diff --git a/Extras/ConvexDecomposition/ConvexBuilder.cpp b/Extras/ConvexDecomposition/ConvexBuilder.cpp index e6f5ee61c..de48d9485 100644 --- a/Extras/ConvexDecomposition/ConvexBuilder.cpp +++ b/Extras/ConvexDecomposition/ConvexBuilder.cpp @@ -8,34 +8,32 @@ #include "fitsphere.h" #include "bestfitobb.h" -unsigned int MAXDEPTH = 8 ; -float CONCAVE_PERCENT = 1.0f ; -float MERGE_PERCENT = 2.0f ; +unsigned int MAXDEPTH = 8; +float CONCAVE_PERCENT = 1.0f; +float MERGE_PERCENT = 2.0f; CHull::CHull(const ConvexDecomposition::ConvexResult &result) { mResult = new ConvexDecomposition::ConvexResult(result); - mVolume = computeMeshVolume( result.mHullVertices, result.mHullTcount, result.mHullIndices ); + mVolume = computeMeshVolume(result.mHullVertices, result.mHullTcount, result.mHullIndices); - mDiagonal = getBoundingRegion( result.mHullVcount, result.mHullVertices, sizeof(float)*3, mMin, mMax ); + mDiagonal = getBoundingRegion(result.mHullVcount, result.mHullVertices, sizeof(float) * 3, mMin, mMax); float dx = mMax[0] - mMin[0]; float dy = mMax[1] - mMin[1]; float dz = mMax[2] - mMin[2]; - dx*=0.1f; // inflate 1/10th on each edge - dy*=0.1f; // inflate 1/10th on each edge - dz*=0.1f; // inflate 1/10th on each edge - - mMin[0]-=dx; - mMin[1]-=dy; - mMin[2]-=dz; - - mMax[0]+=dx; - mMax[1]+=dy; - mMax[2]+=dz; + dx *= 0.1f; // inflate 1/10th on each edge + dy *= 0.1f; // inflate 1/10th on each edge + dz *= 0.1f; // inflate 1/10th on each edge + mMin[0] -= dx; + mMin[1] -= dy; + mMin[2] -= dz; + mMax[0] += dx; + mMax[1] += dy; + mMax[2] += dz; } CHull::~CHull(void) @@ -45,12 +43,9 @@ CHull::~CHull(void) bool CHull::overlap(const CHull &h) const { - return overlapAABB(mMin,mMax, h.mMin, h.mMax ); + return overlapAABB(mMin, mMax, h.mMin, h.mMax); } - - - ConvexBuilder::ConvexBuilder(ConvexDecompInterface *callback) { mCallback = callback; @@ -59,45 +54,45 @@ ConvexBuilder::ConvexBuilder(ConvexDecompInterface *callback) ConvexBuilder::~ConvexBuilder(void) { int i; - for (i=0;ioverlap(*b) ) return 0; // if their AABB's (with a little slop) don't overlap, then return. + if (!a->overlap(*b)) return 0; // if their AABB's (with a little slop) don't overlap, then return. CHull *ret = 0; @@ -140,47 +133,45 @@ CHull * ConvexBuilder::canMerge(CHull *a,CHull *b) UintVector indices; - getMesh( *a->mResult, vc, indices ); - getMesh( *b->mResult, vc, indices ); + getMesh(*a->mResult, vc, indices); + getMesh(*b->mResult, vc, indices); unsigned int vcount = Vl_getVcount(vc); const float *vertices = Vl_getVertices(vc); - unsigned int tcount = indices.size()/3; - + unsigned int tcount = indices.size() / 3; + //don't do anything if hull is empty if (!tcount) { - Vl_releaseVertexLookup (vc); + Vl_releaseVertexLookup(vc); return 0; } ConvexDecomposition::HullResult hresult; ConvexDecomposition::HullLibrary hl; - ConvexDecomposition::HullDesc desc; + ConvexDecomposition::HullDesc desc; desc.SetHullFlag(ConvexDecomposition::QF_TRIANGLES); - desc.mVcount = vcount; - desc.mVertices = vertices; - desc.mVertexStride = sizeof(float)*3; + desc.mVcount = vcount; + desc.mVertices = vertices; + desc.mVertexStride = sizeof(float) * 3; - ConvexDecomposition::HullError hret = hl.CreateConvexHull(desc,hresult); + ConvexDecomposition::HullError hret = hl.CreateConvexHull(desc, hresult); - if ( hret == ConvexDecomposition::QE_OK ) + if (hret == ConvexDecomposition::QE_OK) { + float combineVolume = computeMeshVolume(hresult.mOutputVertices, hresult.mNumFaces, hresult.mIndices); + float sumVolume = a->mVolume + b->mVolume; - float combineVolume = computeMeshVolume( hresult.mOutputVertices, hresult.mNumFaces, hresult.mIndices ); - float sumVolume = a->mVolume + b->mVolume; - - float percent = (sumVolume*100) / combineVolume; - if ( percent >= (100.0f-MERGE_PERCENT) ) + float percent = (sumVolume * 100) / combineVolume; + if (percent >= (100.0f - MERGE_PERCENT)) { ConvexDecomposition::ConvexResult cr(hresult.mNumOutputVertices, hresult.mOutputVertices, hresult.mNumFaces, hresult.mIndices); ret = new CHull(cr); } } - Vl_releaseVertexLookup(vc); return ret; @@ -188,41 +179,36 @@ CHull * ConvexBuilder::canMerge(CHull *a,CHull *b) bool ConvexBuilder::combineHulls(void) { - bool combine = false; - sortChulls(mChulls); // sort the convex hulls, largest volume to least... - - CHullVector output; // the output hulls... + sortChulls(mChulls); // sort the convex hulls, largest volume to least... + CHullVector output; // the output hulls... int i; - for (i=0;imResult; // the high resolution hull... + const ConvexDecomposition::ConvexResult &c = *cr->mResult; // the high resolution hull... ConvexDecomposition::HullResult result; ConvexDecomposition::HullLibrary hl; - ConvexDecomposition::HullDesc hdesc; + ConvexDecomposition::HullDesc hdesc; hdesc.SetHullFlag(ConvexDecomposition::QF_TRIANGLES); - hdesc.mVcount = c.mHullVcount; - hdesc.mVertices = c.mHullVertices; - hdesc.mVertexStride = sizeof(float)*3; - hdesc.mMaxVertices = desc.mMaxVertices; // maximum number of vertices allowed in the output + hdesc.mVcount = c.mHullVcount; + hdesc.mVertices = c.mHullVertices; + hdesc.mVertexStride = sizeof(float) * 3; + hdesc.mMaxVertices = desc.mMaxVertices; // maximum number of vertices allowed in the output - if ( desc.mSkinWidth ) + if (desc.mSkinWidth) { hdesc.mSkinWidth = desc.mSkinWidth; - hdesc.SetHullFlag(ConvexDecomposition::QF_SKIN_WIDTH); // do skin width computation. + hdesc.SetHullFlag(ConvexDecomposition::QF_SKIN_WIDTH); // do skin width computation. } - ConvexDecomposition::HullError ret = hl.CreateConvexHull(hdesc,result); + ConvexDecomposition::HullError ret = hl.CreateConvexHull(hdesc, result); - if ( ret == ConvexDecomposition::QE_OK ) + if (ret == ConvexDecomposition::QE_OK) { ConvexDecomposition::ConvexResult r(result.mNumOutputVertices, result.mOutputVertices, result.mNumFaces, result.mIndices); - r.mHullVolume = computeMeshVolume( result.mOutputVertices, result.mNumFaces, result.mIndices ); // the volume of the hull. + r.mHullVolume = computeMeshVolume(result.mOutputVertices, result.mNumFaces, result.mIndices); // the volume of the hull. // compute the best fit OBB - computeBestFitOBB( result.mNumOutputVertices, result.mOutputVertices, sizeof(float)*3, r.mOBBSides, r.mOBBTransform ); + computeBestFitOBB(result.mNumOutputVertices, result.mOutputVertices, sizeof(float) * 3, r.mOBBSides, r.mOBBTransform); - r.mOBBVolume = r.mOBBSides[0] * r.mOBBSides[1] *r.mOBBSides[2]; // compute the OBB volume. + r.mOBBVolume = r.mOBBSides[0] * r.mOBBSides[1] * r.mOBBSides[2]; // compute the OBB volume. - fm_getTranslation( r.mOBBTransform, r.mOBBCenter ); // get the translation component of the 4x4 matrix. + fm_getTranslation(r.mOBBTransform, r.mOBBCenter); // get the translation component of the 4x4 matrix. - fm_matrixToQuat( r.mOBBTransform, r.mOBBOrientation ); // extract the orientation as a quaternion. - - r.mSphereRadius = computeBoundingSphere( result.mNumOutputVertices, result.mOutputVertices, r.mSphereCenter ); - r.mSphereVolume = fm_sphereVolume( r.mSphereRadius ); + fm_matrixToQuat(r.mOBBTransform, r.mOBBOrientation); // extract the orientation as a quaternion. + r.mSphereRadius = computeBoundingSphere(result.mNumOutputVertices, result.mOutputVertices, r.mSphereCenter); + r.mSphereVolume = fm_sphereVolume(r.mSphereRadius); mCallback->ConvexDecompResult(r); } - hl.ReleaseResult (result); - + hl.ReleaseResult(result); delete cr; } @@ -338,24 +318,23 @@ unsigned int ConvexBuilder::process(const ConvexDecomposition::DecompDesc &desc) return ret; } - -void ConvexBuilder::ConvexDebugTri(const float *p1,const float *p2,const float *p3,unsigned int color) +void ConvexBuilder::ConvexDebugTri(const float *p1, const float *p2, const float *p3, unsigned int color) { - mCallback->ConvexDebugTri(p1,p2,p3,color); + mCallback->ConvexDebugTri(p1, p2, p3, color); } -void ConvexBuilder::ConvexDebugOBB(const float *sides, const float *matrix,unsigned int color) +void ConvexBuilder::ConvexDebugOBB(const float *sides, const float *matrix, unsigned int color) { - mCallback->ConvexDebugOBB(sides,matrix,color); + mCallback->ConvexDebugOBB(sides, matrix, color); } -void ConvexBuilder::ConvexDebugPoint(const float *p,float dist,unsigned int color) +void ConvexBuilder::ConvexDebugPoint(const float *p, float dist, unsigned int color) { - mCallback->ConvexDebugPoint(p,dist,color); + mCallback->ConvexDebugPoint(p, dist, color); } -void ConvexBuilder::ConvexDebugBound(const float *bmin,const float *bmax,unsigned int color) +void ConvexBuilder::ConvexDebugBound(const float *bmin, const float *bmax, unsigned int color) { - mCallback->ConvexDebugBound(bmin,bmax,color); + mCallback->ConvexDebugBound(bmin, bmax, color); } void ConvexBuilder::ConvexDecompResult(ConvexDecomposition::ConvexResult &result) @@ -369,5 +348,3 @@ void ConvexBuilder::sortChulls(CHullVector &hulls) hulls.quickSort(CHullSort()); //hulls.heapSort(CHullSort()); } - - diff --git a/Extras/ConvexDecomposition/ConvexBuilder.h b/Extras/ConvexDecomposition/ConvexBuilder.h index 38eb9d41d..238dfda07 100644 --- a/Extras/ConvexDecomposition/ConvexBuilder.h +++ b/Extras/ConvexDecomposition/ConvexBuilder.h @@ -35,12 +35,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // http://www.amillionpixels.us // - #include "ConvexDecomposition.h" #include "vlookup.h" #include "LinearMath/btAlignedObjectArray.h" - class CHull { public: @@ -50,28 +48,24 @@ public: bool overlap(const CHull &h) const; - float mMin[3]; - float mMax[3]; - float mVolume; - float mDiagonal; // long edge.. - ConvexDecomposition::ConvexResult *mResult; + float mMin[3]; + float mMax[3]; + float mVolume; + float mDiagonal; // long edge.. + ConvexDecomposition::ConvexResult *mResult; }; // Usage: std::sort( list.begin(), list.end(), StringSortRef() ); class CHullSort { public: - - inline bool operator()(const CHull *a,const CHull *b) const + inline bool operator()(const CHull *a, const CHull *b) const { return a->mVolume < b->mVolume; } }; - -typedef btAlignedObjectArray< CHull * > CHullVector; - - +typedef btAlignedObjectArray CHullVector; class ConvexBuilder : public ConvexDecomposition::ConvexDecompInterface { @@ -80,31 +74,30 @@ public: virtual ~ConvexBuilder(void); - bool isDuplicate(unsigned int i1,unsigned int i2,unsigned int i3, - unsigned int ci1,unsigned int ci2,unsigned int ci3); + bool isDuplicate(unsigned int i1, unsigned int i2, unsigned int i3, + unsigned int ci1, unsigned int ci2, unsigned int ci3); - void getMesh(const ConvexDecomposition::ConvexResult &cr,VertexLookup vc,UintVector &indices); + void getMesh(const ConvexDecomposition::ConvexResult &cr, VertexLookup vc, UintVector &indices); - CHull * canMerge(CHull *a,CHull *b); + CHull *canMerge(CHull *a, CHull *b); bool combineHulls(void); unsigned int process(const ConvexDecomposition::DecompDesc &desc); - virtual void ConvexDebugTri(const float *p1,const float *p2,const float *p3,unsigned int color); + virtual void ConvexDebugTri(const float *p1, const float *p2, const float *p3, unsigned int color); - virtual void ConvexDebugOBB(const float *sides, const float *matrix,unsigned int color); - virtual void ConvexDebugPoint(const float *p,float dist,unsigned int color); + virtual void ConvexDebugOBB(const float *sides, const float *matrix, unsigned int color); + virtual void ConvexDebugPoint(const float *p, float dist, unsigned int color); - virtual void ConvexDebugBound(const float *bmin,const float *bmax,unsigned int color); + virtual void ConvexDebugBound(const float *bmin, const float *bmax, unsigned int color); virtual void ConvexDecompResult(ConvexDecomposition::ConvexResult &result); void sortChulls(CHullVector &hulls); - CHullVector mChulls; + CHullVector mChulls; ConvexDecompInterface *mCallback; }; -#endif //CONVEX_BUILDER_H - +#endif //CONVEX_BUILDER_H diff --git a/Extras/ConvexDecomposition/ConvexDecomposition.cpp b/Extras/ConvexDecomposition/ConvexDecomposition.cpp index 572d25f5b..828169213 100644 --- a/Extras/ConvexDecomposition/ConvexDecomposition.cpp +++ b/Extras/ConvexDecomposition/ConvexDecomposition.cpp @@ -5,7 +5,6 @@ #include #include - /*---------------------------------------------------------------------- Copyright (c) 2004 Open Dynamics Framework Group www.physicstools.org @@ -56,320 +55,292 @@ #define SHOW_MESH 0 #define MAKE_MESH 1 - using namespace ConvexDecomposition; - - namespace ConvexDecomposition { - class FaceTri { public: - FaceTri(void) { }; - FaceTri(const float *vertices,unsigned int i1,unsigned int i2,unsigned int i3) - { - mP1.Set( &vertices[i1*3] ); - mP2.Set( &vertices[i2*3] ); - mP3.Set( &vertices[i3*3] ); - } - - Vector3d mP1; - Vector3d mP2; - Vector3d mP3; - Vector3d mNormal; + FaceTri(void){}; + FaceTri(const float *vertices, unsigned int i1, unsigned int i2, unsigned int i3) + { + mP1.Set(&vertices[i1 * 3]); + mP2.Set(&vertices[i2 * 3]); + mP3.Set(&vertices[i3 * 3]); + } + Vector3d mP1; + Vector3d mP2; + Vector3d mP3; + Vector3d mNormal; }; - -void addTri(VertexLookup vl,UintVector &list,const Vector3d &p1,const Vector3d &p2,const Vector3d &p3) +void addTri(VertexLookup vl, UintVector &list, const Vector3d &p1, const Vector3d &p2, const Vector3d &p3) { - unsigned int i1 = Vl_getIndex(vl, p1.Ptr() ); - unsigned int i2 = Vl_getIndex(vl, p2.Ptr() ); - unsigned int i3 = Vl_getIndex(vl, p3.Ptr() ); + unsigned int i1 = Vl_getIndex(vl, p1.Ptr()); + unsigned int i2 = Vl_getIndex(vl, p2.Ptr()); + unsigned int i3 = Vl_getIndex(vl, p3.Ptr()); - // do *not* process degenerate triangles! + // do *not* process degenerate triangles! - if ( i1 != i2 && i1 != i3 && i2 != i3 ) - { - list.push_back(i1); - list.push_back(i2); - list.push_back(i3); - } + if (i1 != i2 && i1 != i3 && i2 != i3) + { + list.push_back(i1); + list.push_back(i2); + list.push_back(i3); + } } - -void calcConvexDecomposition(unsigned int vcount, - const float *vertices, - unsigned int tcount, - const unsigned int *indices, - ConvexDecompInterface *callback, - float masterVolume, - unsigned int depth) +void calcConvexDecomposition(unsigned int vcount, + const float *vertices, + unsigned int tcount, + const unsigned int *indices, + ConvexDecompInterface *callback, + float masterVolume, + unsigned int depth) { + float plane[4]; - float plane[4]; - - bool split = false; - - - if ( depth < MAXDEPTH ) - { + bool split = false; + if (depth < MAXDEPTH) + { float volume; - float c = computeConcavity( vcount, vertices, tcount, indices, callback, plane, volume ); + float c = computeConcavity(vcount, vertices, tcount, indices, callback, plane, volume); - if ( depth == 0 ) - { - masterVolume = volume; - } - - float percent = (c*100.0f)/masterVolume; - - if ( percent > CONCAVE_PERCENT ) // if great than 5% of the total volume is concave, go ahead and keep splitting. + if (depth == 0) { - split = true; - } + masterVolume = volume; + } - } + float percent = (c * 100.0f) / masterVolume; - if ( depth >= MAXDEPTH || !split ) - { + if (percent > CONCAVE_PERCENT) // if great than 5% of the total volume is concave, go ahead and keep splitting. + { + split = true; + } + } + if (depth >= MAXDEPTH || !split) + { #if 1 - HullResult result; - HullLibrary hl; - HullDesc desc; + HullResult result; + HullLibrary hl; + HullDesc desc; - desc.SetHullFlag(QF_TRIANGLES); + desc.SetHullFlag(QF_TRIANGLES); - desc.mVcount = vcount; - desc.mVertices = vertices; - desc.mVertexStride = sizeof(float)*3; + desc.mVcount = vcount; + desc.mVertices = vertices; + desc.mVertexStride = sizeof(float) * 3; - HullError ret = hl.CreateConvexHull(desc,result); - - if ( ret == QE_OK ) - { + HullError ret = hl.CreateConvexHull(desc, result); + if (ret == QE_OK) + { ConvexResult r(result.mNumOutputVertices, result.mOutputVertices, result.mNumFaces, result.mIndices); - callback->ConvexDecompResult(r); - } - + } #else static unsigned int colors[8] = - { - 0xFF0000, - 0x00FF00, - 0x0000FF, - 0xFFFF00, - 0x00FFFF, - 0xFF00FF, - 0xFFFFFF, - 0xFF8040 - }; + { + 0xFF0000, + 0x00FF00, + 0x0000FF, + 0xFFFF00, + 0x00FFFF, + 0xFF00FF, + 0xFFFFFF, + 0xFF8040}; static int count = 0; count++; - if ( count == 8 ) count = 0; + if (count == 8) count = 0; - assert( count >= 0 && count < 8 ); + assert(count >= 0 && count < 8); unsigned int color = colors[count]; - const unsigned int *source = indices; - - for (unsigned int i=0; iConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(), t.mP3.Ptr(), color ); - - } -#endif - - hl.ReleaseResult (result); - return; - - } - - UintVector ifront; - UintVector iback; - - VertexLookup vfront = Vl_createVertexLookup(); - VertexLookup vback = Vl_createVertexLookup(); - - - bool showmesh = false; - #if SHOW_MESH - showmesh = true; - #endif - - if ( 0 ) - { - showmesh = true; - for (float x=-1; x<1; x+=0.10f) - { - for (float y=0; y<1; y+=0.10f) - { - for (float z=-1; z<1; z+=0.04f) - { - float d = x*plane[0] + y*plane[1] + z*plane[2] + plane[3]; - Vector3d p(x,y,z); - if ( d >= 0 ) - callback->ConvexDebugPoint(p.Ptr(), 0.02f, 0x00FF00); - else - callback->ConvexDebugPoint(p.Ptr(), 0.02f, 0xFF0000); - } - } - } - } - - if ( 1 ) - { - // ok..now we are going to 'split' all of the input triangles against this plane! const unsigned int *source = indices; - for (unsigned int i=0; iConvexDebugTri(t.mP1.Ptr(), t.mP2.Ptr(), t.mP3.Ptr(), color); + } +#endif + + hl.ReleaseResult(result); + return; + } + + UintVector ifront; + UintVector iback; + + VertexLookup vfront = Vl_createVertexLookup(); + VertexLookup vback = Vl_createVertexLookup(); + + bool showmesh = false; +#if SHOW_MESH + showmesh = true; +#endif + + if (0) + { + showmesh = true; + for (float x = -1; x < 1; x += 0.10f) + { + for (float y = 0; y < 1; y += 0.10f) + { + for (float z = -1; z < 1; z += 0.04f) + { + float d = x * plane[0] + y * plane[1] + z * plane[2] + plane[3]; + Vector3d p(x, y, z); + if (d >= 0) + callback->ConvexDebugPoint(p.Ptr(), 0.02f, 0x00FF00); + else + callback->ConvexDebugPoint(p.Ptr(), 0.02f, 0xFF0000); + } + } + } + } + + if (1) + { + // ok..now we are going to 'split' all of the input triangles against this plane! + const unsigned int *source = indices; + for (unsigned int i = 0; i < tcount; i++) + { + unsigned int i1 = *source++; + unsigned int i2 = *source++; + unsigned int i3 = *source++; + + FaceTri t(vertices, i1, i2, i3); Vector3d front[4]; Vector3d back[4]; - unsigned int fcount=0; - unsigned int bcount=0; + unsigned int fcount = 0; + unsigned int bcount = 0; PlaneTriResult result; - result = planeTriIntersection(plane,t.mP1.Ptr(),sizeof(Vector3d),0.00001f,front[0].Ptr(),fcount,back[0].Ptr(),bcount ); + result = planeTriIntersection(plane, t.mP1.Ptr(), sizeof(Vector3d), 0.00001f, front[0].Ptr(), fcount, back[0].Ptr(), bcount); - if( fcount > 4 || bcount > 4 ) + if (fcount > 4 || bcount > 4) { - result = planeTriIntersection(plane,t.mP1.Ptr(),sizeof(Vector3d),0.00001f,front[0].Ptr(),fcount,back[0].Ptr(),bcount ); + result = planeTriIntersection(plane, t.mP1.Ptr(), sizeof(Vector3d), 0.00001f, front[0].Ptr(), fcount, back[0].Ptr(), bcount); } - switch ( result ) + switch (result) { case PTR_FRONT: - assert( fcount == 3 ); + assert(fcount == 3); - if ( showmesh ) - callback->ConvexDebugTri( front[0].Ptr(), front[1].Ptr(), front[2].Ptr(), 0x00FF00 ); + if (showmesh) + callback->ConvexDebugTri(front[0].Ptr(), front[1].Ptr(), front[2].Ptr(), 0x00FF00); - #if MAKE_MESH +#if MAKE_MESH - addTri( vfront, ifront, front[0], front[1], front[2] ); + addTri(vfront, ifront, front[0], front[1], front[2]); - - #endif +#endif break; case PTR_BACK: - assert( bcount == 3 ); + assert(bcount == 3); - if ( showmesh ) - callback->ConvexDebugTri( back[0].Ptr(), back[1].Ptr(), back[2].Ptr(), 0xFFFF00 ); + if (showmesh) + callback->ConvexDebugTri(back[0].Ptr(), back[1].Ptr(), back[2].Ptr(), 0xFFFF00); - #if MAKE_MESH +#if MAKE_MESH - addTri( vback, iback, back[0], back[1], back[2] ); + addTri(vback, iback, back[0], back[1], back[2]); - #endif +#endif break; case PTR_SPLIT: - assert( fcount >= 3 && fcount <= 4); - assert( bcount >= 3 && bcount <= 4); + assert(fcount >= 3 && fcount <= 4); + assert(bcount >= 3 && bcount <= 4); - #if MAKE_MESH +#if MAKE_MESH - addTri( vfront, ifront, front[0], front[1], front[2] ); - addTri( vback, iback, back[0], back[1], back[2] ); + addTri(vfront, ifront, front[0], front[1], front[2]); + addTri(vback, iback, back[0], back[1], back[2]); + if (fcount == 4) + { + addTri(vfront, ifront, front[0], front[2], front[3]); + } - if ( fcount == 4 ) - { - addTri( vfront, ifront, front[0], front[2], front[3] ); - } + if (bcount == 4) + { + addTri(vback, iback, back[0], back[2], back[3]); + } - if ( bcount == 4 ) - { - addTri( vback, iback, back[0], back[2], back[3] ); - } +#endif - #endif + if (showmesh) + { + callback->ConvexDebugTri(front[0].Ptr(), front[1].Ptr(), front[2].Ptr(), 0x00D000); + callback->ConvexDebugTri(back[0].Ptr(), back[1].Ptr(), back[2].Ptr(), 0xD0D000); - if ( showmesh ) - { - callback->ConvexDebugTri( front[0].Ptr(), front[1].Ptr(), front[2].Ptr(), 0x00D000 ); - callback->ConvexDebugTri( back[0].Ptr(), back[1].Ptr(), back[2].Ptr(), 0xD0D000 ); - - if ( fcount == 4 ) - { - callback->ConvexDebugTri( front[0].Ptr(), front[2].Ptr(), front[3].Ptr(), 0x00D000 ); - } - if ( bcount == 4 ) - { - callback->ConvexDebugTri( back[0].Ptr(), back[2].Ptr(), back[3].Ptr(), 0xD0D000 ); - } - } + if (fcount == 4) + { + callback->ConvexDebugTri(front[0].Ptr(), front[2].Ptr(), front[3].Ptr(), 0x00D000); + } + if (bcount == 4) + { + callback->ConvexDebugTri(back[0].Ptr(), back[2].Ptr(), back[3].Ptr(), 0xD0D000); + } + } break; } } - // ok... here we recursively call - if ( ifront.size() ) - { - unsigned int vcount = Vl_getVcount(vfront); - const float *vertices = Vl_getVertices(vfront); - unsigned int tcount = ifront.size()/3; + // ok... here we recursively call + if (ifront.size()) + { + unsigned int vcount = Vl_getVcount(vfront); + const float *vertices = Vl_getVertices(vfront); + unsigned int tcount = ifront.size() / 3; - calcConvexDecomposition(vcount, vertices, tcount, &ifront[0], callback, masterVolume, depth+1); + calcConvexDecomposition(vcount, vertices, tcount, &ifront[0], callback, masterVolume, depth + 1); + } - } + ifront.clear(); - ifront.clear(); + Vl_releaseVertexLookup(vfront); - Vl_releaseVertexLookup(vfront); + if (iback.size()) + { + unsigned int vcount = Vl_getVcount(vback); + const float *vertices = Vl_getVertices(vback); + unsigned int tcount = iback.size() / 3; - if ( iback.size() ) - { - unsigned int vcount = Vl_getVcount(vback); - const float *vertices = Vl_getVertices(vback); - unsigned int tcount = iback.size()/3; - - calcConvexDecomposition(vcount, vertices, tcount, &iback[0], callback, masterVolume, depth+1); - - } - - iback.clear(); - Vl_releaseVertexLookup(vback); + calcConvexDecomposition(vcount, vertices, tcount, &iback[0], callback, masterVolume, depth + 1); + } + iback.clear(); + Vl_releaseVertexLookup(vback); } } - - - -} +} // namespace ConvexDecomposition diff --git a/Extras/ConvexDecomposition/ConvexDecomposition.h b/Extras/ConvexDecomposition/ConvexDecomposition.h index 2886c39a4..ad5c1f960 100644 --- a/Extras/ConvexDecomposition/ConvexDecomposition.h +++ b/Extras/ConvexDecomposition/ConvexDecomposition.h @@ -36,185 +36,167 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // http://www.amillionpixels.us // - #ifdef _WIN32 -#include //memcpy +#include //memcpy #endif #include #include #include "LinearMath/btAlignedObjectArray.h" +extern unsigned int MAXDEPTH; +extern float CONCAVE_PERCENT; +extern float MERGE_PERCENT; - -extern unsigned int MAXDEPTH ; -extern float CONCAVE_PERCENT ; -extern float MERGE_PERCENT ; - - -typedef btAlignedObjectArray< unsigned int > UintVector; - - +typedef btAlignedObjectArray UintVector; namespace ConvexDecomposition { - - class ConvexResult +class ConvexResult +{ +public: + ConvexResult(void) { - public: - ConvexResult(void) + mHullVcount = 0; + mHullVertices = 0; + mHullTcount = 0; + mHullIndices = 0; + } + + ConvexResult(unsigned int hvcount, const float *hvertices, unsigned int htcount, const unsigned int *hindices) + { + mHullVcount = hvcount; + if (mHullVcount) + { + mHullVertices = new float[mHullVcount * sizeof(float) * 3]; + memcpy(mHullVertices, hvertices, sizeof(float) * 3 * mHullVcount); + } + else { - mHullVcount = 0; mHullVertices = 0; - mHullTcount = 0; + } + + mHullTcount = htcount; + + if (mHullTcount) + { + mHullIndices = new unsigned int[sizeof(unsigned int) * mHullTcount * 3]; + memcpy(mHullIndices, hindices, sizeof(unsigned int) * mHullTcount * 3); + } + else + { mHullIndices = 0; } + } - ConvexResult(unsigned int hvcount,const float *hvertices,unsigned int htcount,const unsigned int *hindices) - { - mHullVcount = hvcount; - if ( mHullVcount ) - { - mHullVertices = new float[mHullVcount*sizeof(float)*3]; - memcpy(mHullVertices, hvertices, sizeof(float)*3*mHullVcount ); - } - else - { - mHullVertices = 0; - } - - mHullTcount = htcount; - - if ( mHullTcount ) - { - mHullIndices = new unsigned int[sizeof(unsigned int)*mHullTcount*3]; - memcpy(mHullIndices,hindices, sizeof(unsigned int)*mHullTcount*3 ); - } - else - { - mHullIndices = 0; - } - - } - - ConvexResult(const ConvexResult &r) - { - mHullVcount = r.mHullVcount; - if ( mHullVcount ) - { - mHullVertices = new float[mHullVcount*sizeof(float)*3]; - memcpy(mHullVertices, r.mHullVertices, sizeof(float)*3*mHullVcount ); - } - else - { - mHullVertices = 0; - } - mHullTcount = r.mHullTcount; - if ( mHullTcount ) - { - mHullIndices = new unsigned int[sizeof(unsigned int)*mHullTcount*3]; - memcpy(mHullIndices, r.mHullIndices, sizeof(unsigned int)*mHullTcount*3 ); - } - else - { - mHullIndices = 0; - } - } - - ~ConvexResult(void) - { - delete [] mHullVertices; - delete [] mHullIndices; - } - - // the convex hull. - unsigned int mHullVcount; - float * mHullVertices; - unsigned int mHullTcount; - unsigned int *mHullIndices; - - float mHullVolume; // the volume of the convex hull. - - float mOBBSides[3]; // the width, height and breadth of the best fit OBB - float mOBBCenter[3]; // the center of the OBB - float mOBBOrientation[4]; // the quaternion rotation of the OBB. - float mOBBTransform[16]; // the 4x4 transform of the OBB. - float mOBBVolume; // the volume of the OBB - - float mSphereRadius; // radius and center of best fit sphere - float mSphereCenter[3]; - float mSphereVolume; // volume of the best fit sphere - - - - }; - - class ConvexDecompInterface + ConvexResult(const ConvexResult &r) { - public: - virtual ~ConvexDecompInterface() {}; - virtual void ConvexDebugTri(const float *p1,const float *p2,const float *p3,unsigned int color) { }; - virtual void ConvexDebugPoint(const float *p,float dist,unsigned int color) { }; - virtual void ConvexDebugBound(const float *bmin,const float *bmax,unsigned int color) { }; - virtual void ConvexDebugOBB(const float *sides, const float *matrix,unsigned int color) { }; - - virtual void ConvexDecompResult(ConvexResult &result) = 0; - - - - }; - - // just to avoid passing a zillion parameters to the method the - // options are packed into this descriptor. - class DecompDesc - { - public: - DecompDesc(void) + mHullVcount = r.mHullVcount; + if (mHullVcount) { - mVcount = 0; - mVertices = 0; - mTcount = 0; - mIndices = 0; - mDepth = 5; - mCpercent = 5; - mPpercent = 5; - mMaxVertices = 32; - mSkinWidth = 0; - mCallback = 0; + mHullVertices = new float[mHullVcount * sizeof(float) * 3]; + memcpy(mHullVertices, r.mHullVertices, sizeof(float) * 3 * mHullVcount); } + else + { + mHullVertices = 0; + } + mHullTcount = r.mHullTcount; + if (mHullTcount) + { + mHullIndices = new unsigned int[sizeof(unsigned int) * mHullTcount * 3]; + memcpy(mHullIndices, r.mHullIndices, sizeof(unsigned int) * mHullTcount * 3); + } + else + { + mHullIndices = 0; + } + } - // describes the input triangle. - unsigned int mVcount; // the number of vertices in the source mesh. - const float *mVertices; // start of the vertex position array. Assumes a stride of 3 floats. - unsigned int mTcount; // the number of triangles in the source mesh. - unsigned int *mIndices; // the indexed triangle list array (zero index based) + ~ConvexResult(void) + { + delete[] mHullVertices; + delete[] mHullIndices; + } - // options - unsigned int mDepth; // depth to split, a maximum of 10, generally not over 7. - float mCpercent; // the concavity threshold percentage. 0=20 is reasonable. - float mPpercent; // the percentage volume conservation threshold to collapse hulls. 0-30 is reasonable. + // the convex hull. + unsigned int mHullVcount; + float *mHullVertices; + unsigned int mHullTcount; + unsigned int *mHullIndices; - // hull output limits. - unsigned int mMaxVertices; // maximum number of vertices in the output hull. Recommended 32 or less. - float mSkinWidth; // a skin width to apply to the output hulls. + float mHullVolume; // the volume of the convex hull. - ConvexDecompInterface *mCallback; // the interface to receive back the results. + float mOBBSides[3]; // the width, height and breadth of the best fit OBB + float mOBBCenter[3]; // the center of the OBB + float mOBBOrientation[4]; // the quaternion rotation of the OBB. + float mOBBTransform[16]; // the 4x4 transform of the OBB. + float mOBBVolume; // the volume of the OBB - }; + float mSphereRadius; // radius and center of best fit sphere + float mSphereCenter[3]; + float mSphereVolume; // volume of the best fit sphere +}; - // perform approximate convex decomposition on a mesh. - unsigned int performConvexDecomposition(const DecompDesc &desc); // returns the number of hulls produced. +class ConvexDecompInterface +{ +public: + virtual ~ConvexDecompInterface(){}; + virtual void ConvexDebugTri(const float *p1, const float *p2, const float *p3, unsigned int color){}; + virtual void ConvexDebugPoint(const float *p, float dist, unsigned int color){}; + virtual void ConvexDebugBound(const float *bmin, const float *bmax, unsigned int color){}; + virtual void ConvexDebugOBB(const float *sides, const float *matrix, unsigned int color){}; + virtual void ConvexDecompResult(ConvexResult &result) = 0; +}; - void calcConvexDecomposition(unsigned int vcount, - const float *vertices, - unsigned int tcount, - const unsigned int *indices, - ConvexDecompInterface *callback, - float masterVolume, - unsigned int depth); +// just to avoid passing a zillion parameters to the method the +// options are packed into this descriptor. +class DecompDesc +{ +public: + DecompDesc(void) + { + mVcount = 0; + mVertices = 0; + mTcount = 0; + mIndices = 0; + mDepth = 5; + mCpercent = 5; + mPpercent = 5; + mMaxVertices = 32; + mSkinWidth = 0; + mCallback = 0; + } + // describes the input triangle. + unsigned int mVcount; // the number of vertices in the source mesh. + const float *mVertices; // start of the vertex position array. Assumes a stride of 3 floats. + unsigned int mTcount; // the number of triangles in the source mesh. + unsigned int *mIndices; // the indexed triangle list array (zero index based) -} + // options + unsigned int mDepth; // depth to split, a maximum of 10, generally not over 7. + float mCpercent; // the concavity threshold percentage. 0=20 is reasonable. + float mPpercent; // the percentage volume conservation threshold to collapse hulls. 0-30 is reasonable. + // hull output limits. + unsigned int mMaxVertices; // maximum number of vertices in the output hull. Recommended 32 or less. + float mSkinWidth; // a skin width to apply to the output hulls. + + ConvexDecompInterface *mCallback; // the interface to receive back the results. +}; + +// perform approximate convex decomposition on a mesh. +unsigned int performConvexDecomposition(const DecompDesc &desc); // returns the number of hulls produced. + +void calcConvexDecomposition(unsigned int vcount, + const float *vertices, + unsigned int tcount, + const unsigned int *indices, + ConvexDecompInterface *callback, + float masterVolume, + unsigned int depth); + +} // namespace ConvexDecomposition #endif diff --git a/Extras/ConvexDecomposition/bestfit.cpp b/Extras/ConvexDecomposition/bestfit.cpp index e6469f6fb..09024177e 100644 --- a/Extras/ConvexDecomposition/bestfit.cpp +++ b/Extras/ConvexDecomposition/bestfit.cpp @@ -52,369 +52,358 @@ namespace BestFit { - class Vec3 { public: - Vec3(void) { }; - Vec3(float _x,float _y,float _z) { x = _x; y = _y; z = _z; }; + Vec3(void){}; + Vec3(float _x, float _y, float _z) + { + x = _x; + y = _y; + z = _z; + }; + float dot(const Vec3 &v) + { + return x * v.x + y * v.y + z * v.z; // the dot product + } - float dot(const Vec3 &v) - { - return x*v.x + y*v.y + z*v.z; // the dot product - } - - float x; - float y; - float z; + float x; + float y; + float z; }; - class Eigen { public: + void DecrSortEigenStuff(void) + { + Tridiagonal(); //diagonalize the matrix. + QLAlgorithm(); // + DecreasingSort(); + GuaranteeRotation(); + } + void Tridiagonal(void) + { + float fM00 = mElement[0][0]; + float fM01 = mElement[0][1]; + float fM02 = mElement[0][2]; + float fM11 = mElement[1][1]; + float fM12 = mElement[1][2]; + float fM22 = mElement[2][2]; - void DecrSortEigenStuff(void) - { - Tridiagonal(); //diagonalize the matrix. - QLAlgorithm(); // - DecreasingSort(); - GuaranteeRotation(); - } + m_afDiag[0] = fM00; + m_afSubd[2] = 0; + if (fM02 != (float)0.0) + { + float fLength = sqrtf(fM01 * fM01 + fM02 * fM02); + float fInvLength = ((float)1.0) / fLength; + fM01 *= fInvLength; + fM02 *= fInvLength; + float fQ = ((float)2.0) * fM01 * fM12 + fM02 * (fM22 - fM11); + m_afDiag[1] = fM11 + fM02 * fQ; + m_afDiag[2] = fM22 - fM02 * fQ; + m_afSubd[0] = fLength; + m_afSubd[1] = fM12 - fM01 * fQ; + mElement[0][0] = (float)1.0; + mElement[0][1] = (float)0.0; + mElement[0][2] = (float)0.0; + mElement[1][0] = (float)0.0; + mElement[1][1] = fM01; + mElement[1][2] = fM02; + mElement[2][0] = (float)0.0; + mElement[2][1] = fM02; + mElement[2][2] = -fM01; + m_bIsRotation = false; + } + else + { + m_afDiag[1] = fM11; + m_afDiag[2] = fM22; + m_afSubd[0] = fM01; + m_afSubd[1] = fM12; + mElement[0][0] = (float)1.0; + mElement[0][1] = (float)0.0; + mElement[0][2] = (float)0.0; + mElement[1][0] = (float)0.0; + mElement[1][1] = (float)1.0; + mElement[1][2] = (float)0.0; + mElement[2][0] = (float)0.0; + mElement[2][1] = (float)0.0; + mElement[2][2] = (float)1.0; + m_bIsRotation = true; + } + } - void Tridiagonal(void) - { - float fM00 = mElement[0][0]; - float fM01 = mElement[0][1]; - float fM02 = mElement[0][2]; - float fM11 = mElement[1][1]; - float fM12 = mElement[1][2]; - float fM22 = mElement[2][2]; + bool QLAlgorithm(void) + { + const int iMaxIter = 32; - m_afDiag[0] = fM00; - m_afSubd[2] = 0; - if (fM02 != (float)0.0) - { - float fLength = sqrtf(fM01*fM01+fM02*fM02); - float fInvLength = ((float)1.0)/fLength; - fM01 *= fInvLength; - fM02 *= fInvLength; - float fQ = ((float)2.0)*fM01*fM12+fM02*(fM22-fM11); - m_afDiag[1] = fM11+fM02*fQ; - m_afDiag[2] = fM22-fM02*fQ; - m_afSubd[0] = fLength; - m_afSubd[1] = fM12-fM01*fQ; - mElement[0][0] = (float)1.0; - mElement[0][1] = (float)0.0; - mElement[0][2] = (float)0.0; - mElement[1][0] = (float)0.0; - mElement[1][1] = fM01; - mElement[1][2] = fM02; - mElement[2][0] = (float)0.0; - mElement[2][1] = fM02; - mElement[2][2] = -fM01; - m_bIsRotation = false; - } - else - { - m_afDiag[1] = fM11; - m_afDiag[2] = fM22; - m_afSubd[0] = fM01; - m_afSubd[1] = fM12; - mElement[0][0] = (float)1.0; - mElement[0][1] = (float)0.0; - mElement[0][2] = (float)0.0; - mElement[1][0] = (float)0.0; - mElement[1][1] = (float)1.0; - mElement[1][2] = (float)0.0; - mElement[2][0] = (float)0.0; - mElement[2][1] = (float)0.0; - mElement[2][2] = (float)1.0; - m_bIsRotation = true; - } - } + for (int i0 = 0; i0 < 3; i0++) + { + int i1; + for (i1 = 0; i1 < iMaxIter; i1++) + { + int i2; + for (i2 = i0; i2 <= (3 - 2); i2++) + { + float fTmp = fabsf(m_afDiag[i2]) + fabsf(m_afDiag[i2 + 1]); + if (fabsf(m_afSubd[i2]) + fTmp == fTmp) + break; + } + if (i2 == i0) + { + break; + } - bool QLAlgorithm(void) - { - const int iMaxIter = 32; + float fG = (m_afDiag[i0 + 1] - m_afDiag[i0]) / (((float)2.0) * m_afSubd[i0]); + float fR = sqrtf(fG * fG + (float)1.0); + if (fG < (float)0.0) + { + fG = m_afDiag[i2] - m_afDiag[i0] + m_afSubd[i0] / (fG - fR); + } + else + { + fG = m_afDiag[i2] - m_afDiag[i0] + m_afSubd[i0] / (fG + fR); + } + float fSin = (float)1.0, fCos = (float)1.0, fP = (float)0.0; + for (int i3 = i2 - 1; i3 >= i0; i3--) + { + float fF = fSin * m_afSubd[i3]; + float fB = fCos * m_afSubd[i3]; + if (fabsf(fF) >= fabsf(fG)) + { + fCos = fG / fF; + fR = sqrtf(fCos * fCos + (float)1.0); + m_afSubd[i3 + 1] = fF * fR; + fSin = ((float)1.0) / fR; + fCos *= fSin; + } + else + { + fSin = fF / fG; + fR = sqrtf(fSin * fSin + (float)1.0); + m_afSubd[i3 + 1] = fG * fR; + fCos = ((float)1.0) / fR; + fSin *= fCos; + } + fG = m_afDiag[i3 + 1] - fP; + fR = (m_afDiag[i3] - fG) * fSin + ((float)2.0) * fB * fCos; + fP = fSin * fR; + m_afDiag[i3 + 1] = fG + fP; + fG = fCos * fR - fB; + for (int i4 = 0; i4 < 3; i4++) + { + fF = mElement[i4][i3 + 1]; + mElement[i4][i3 + 1] = fSin * mElement[i4][i3] + fCos * fF; + mElement[i4][i3] = fCos * mElement[i4][i3] - fSin * fF; + } + } + m_afDiag[i0] -= fP; + m_afSubd[i0] = fG; + m_afSubd[i2] = (float)0.0; + } + if (i1 == iMaxIter) + { + return false; + } + } + return true; + } - for (int i0 = 0; i0 <3; i0++) - { - int i1; - for (i1 = 0; i1 < iMaxIter; i1++) - { - int i2; - for (i2 = i0; i2 <= (3-2); i2++) - { - float fTmp = fabsf(m_afDiag[i2]) + fabsf(m_afDiag[i2+1]); - if ( fabsf(m_afSubd[i2]) + fTmp == fTmp ) - break; - } - if (i2 == i0) - { - break; - } + void DecreasingSort(void) + { + //sort eigenvalues in decreasing order, e[0] >= ... >= e[iSize-1] + for (int i0 = 0, i1; i0 <= 3 - 2; i0++) + { + // locate maximum eigenvalue + i1 = i0; + float fMax = m_afDiag[i1]; + int i2; + for (i2 = i0 + 1; i2 < 3; i2++) + { + if (m_afDiag[i2] > fMax) + { + i1 = i2; + fMax = m_afDiag[i1]; + } + } - float fG = (m_afDiag[i0+1] - m_afDiag[i0])/(((float)2.0) * m_afSubd[i0]); - float fR = sqrtf(fG*fG+(float)1.0); - if (fG < (float)0.0) - { - fG = m_afDiag[i2]-m_afDiag[i0]+m_afSubd[i0]/(fG-fR); - } - else - { - fG = m_afDiag[i2]-m_afDiag[i0]+m_afSubd[i0]/(fG+fR); - } - float fSin = (float)1.0, fCos = (float)1.0, fP = (float)0.0; - for (int i3 = i2-1; i3 >= i0; i3--) - { - float fF = fSin*m_afSubd[i3]; - float fB = fCos*m_afSubd[i3]; - if (fabsf(fF) >= fabsf(fG)) - { - fCos = fG/fF; - fR = sqrtf(fCos*fCos+(float)1.0); - m_afSubd[i3+1] = fF*fR; - fSin = ((float)1.0)/fR; - fCos *= fSin; - } - else - { - fSin = fF/fG; - fR = sqrtf(fSin*fSin+(float)1.0); - m_afSubd[i3+1] = fG*fR; - fCos = ((float)1.0)/fR; - fSin *= fCos; - } - fG = m_afDiag[i3+1]-fP; - fR = (m_afDiag[i3]-fG)*fSin+((float)2.0)*fB*fCos; - fP = fSin*fR; - m_afDiag[i3+1] = fG+fP; - fG = fCos*fR-fB; - for (int i4 = 0; i4 < 3; i4++) - { - fF = mElement[i4][i3+1]; - mElement[i4][i3+1] = fSin*mElement[i4][i3]+fCos*fF; - mElement[i4][i3] = fCos*mElement[i4][i3]-fSin*fF; - } - } - m_afDiag[i0] -= fP; - m_afSubd[i0] = fG; - m_afSubd[i2] = (float)0.0; - } - if (i1 == iMaxIter) - { - return false; - } - } - return true; - } + if (i1 != i0) + { + // swap eigenvalues + m_afDiag[i1] = m_afDiag[i0]; + m_afDiag[i0] = fMax; + // swap eigenvectors + for (i2 = 0; i2 < 3; i2++) + { + float fTmp = mElement[i2][i0]; + mElement[i2][i0] = mElement[i2][i1]; + mElement[i2][i1] = fTmp; + m_bIsRotation = !m_bIsRotation; + } + } + } + } - void DecreasingSort(void) - { - //sort eigenvalues in decreasing order, e[0] >= ... >= e[iSize-1] - for (int i0 = 0, i1; i0 <= 3-2; i0++) - { - // locate maximum eigenvalue - i1 = i0; - float fMax = m_afDiag[i1]; - int i2; - for (i2 = i0+1; i2 < 3; i2++) - { - if (m_afDiag[i2] > fMax) - { - i1 = i2; - fMax = m_afDiag[i1]; - } - } + void GuaranteeRotation(void) + { + if (!m_bIsRotation) + { + // change sign on the first column + for (int iRow = 0; iRow < 3; iRow++) + { + mElement[iRow][0] = -mElement[iRow][0]; + } + } + } - if (i1 != i0) - { - // swap eigenvalues - m_afDiag[i1] = m_afDiag[i0]; - m_afDiag[i0] = fMax; - // swap eigenvectors - for (i2 = 0; i2 < 3; i2++) - { - float fTmp = mElement[i2][i0]; - mElement[i2][i0] = mElement[i2][i1]; - mElement[i2][i1] = fTmp; - m_bIsRotation = !m_bIsRotation; - } - } - } - } - - - void GuaranteeRotation(void) - { - if (!m_bIsRotation) - { - // change sign on the first column - for (int iRow = 0; iRow <3; iRow++) - { - mElement[iRow][0] = -mElement[iRow][0]; - } - } - } - - float mElement[3][3]; - float m_afDiag[3]; - float m_afSubd[3]; - bool m_bIsRotation; + float mElement[3][3]; + float m_afDiag[3]; + float m_afSubd[3]; + bool m_bIsRotation; }; -} - +} // namespace BestFit using namespace BestFit; - bool getBestFitPlane(unsigned int vcount, - const float *points, - unsigned int vstride, - const float *weights, - unsigned int wstride, - float *plane) + const float *points, + unsigned int vstride, + const float *weights, + unsigned int wstride, + float *plane) { - bool ret = false; + bool ret = false; - Vec3 kOrigin(0,0,0); + Vec3 kOrigin(0, 0, 0); - float wtotal = 0; + float wtotal = 0; - if ( 1 ) - { - const char *source = (const char *) points; - const char *wsource = (const char *) weights; + if (1) + { + const char *source = (const char *)points; + const char *wsource = (const char *)weights; - for (unsigned int i=0; i bmax[0]) bmax[0] = p[0]; + if (p[1] > bmax[1]) bmax[1] = p[1]; + if (p[2] > bmax[2]) bmax[2] = p[2]; + } - if ( p[0] > bmax[0] ) bmax[0] = p[0]; - if ( p[1] > bmax[1] ) bmax[1] = p[1]; - if ( p[2] > bmax[2] ) bmax[2] = p[2]; - - } - - float dx = bmax[0] - bmin[0]; - float dy = bmax[1] - bmin[1]; - float dz = bmax[2] - bmin[2]; - - return sqrtf( dx*dx + dy*dy + dz*dz ); + float dx = bmax[0] - bmin[0]; + float dy = bmax[1] - bmin[1]; + float dz = bmax[2] - bmin[2]; + return sqrtf(dx * dx + dy * dy + dz * dz); } - -bool overlapAABB(const float *bmin1,const float *bmax1,const float *bmin2,const float *bmax2) // return true if the two AABB's overlap. +bool overlapAABB(const float *bmin1, const float *bmax1, const float *bmin2, const float *bmax2) // return true if the two AABB's overlap. { - if ( bmax2[0] < bmin1[0] ) return false; // if the maximum is less than our minimum on any axis - if ( bmax2[1] < bmin1[1] ) return false; - if ( bmax2[2] < bmin1[2] ) return false; + if (bmax2[0] < bmin1[0]) return false; // if the maximum is less than our minimum on any axis + if (bmax2[1] < bmin1[1]) return false; + if (bmax2[2] < bmin1[2]) return false; - if ( bmin2[0] > bmax1[0] ) return false; // if the minimum is greater than our maximum on any axis - if ( bmin2[1] > bmax1[1] ) return false; // if the minimum is greater than our maximum on any axis - if ( bmin2[2] > bmax1[2] ) return false; // if the minimum is greater than our maximum on any axis + if (bmin2[0] > bmax1[0]) return false; // if the minimum is greater than our maximum on any axis + if (bmin2[1] > bmax1[1]) return false; // if the minimum is greater than our maximum on any axis + if (bmin2[2] > bmax1[2]) return false; // if the minimum is greater than our maximum on any axis - - return true; // the extents overlap + return true; // the extents overlap } - - diff --git a/Extras/ConvexDecomposition/bestfit.h b/Extras/ConvexDecomposition/bestfit.h index f2e78e5a6..433f09664 100644 --- a/Extras/ConvexDecomposition/bestfit.h +++ b/Extras/ConvexDecomposition/bestfit.h @@ -36,7 +36,6 @@ // http://www.amillionpixels.us // - // This routine was released in 'snippet' form // by John W. Ratcliff mailto:jratcliff@infiniplex.net // on March 22, 2006. @@ -51,15 +50,14 @@ // computes the best fit plane to a collection of data points. // returns the plane equation as A,B,C,D format. (Ax+By+Cz+D) -bool getBestFitPlane(unsigned int vcount, // number of input data points - const float *points, // starting address of points array. - unsigned int vstride, // stride between input points. - const float *weights, // *optional point weighting values. - unsigned int wstride, // weight stride for each vertex. - float *plane); +bool getBestFitPlane(unsigned int vcount, // number of input data points + const float *points, // starting address of points array. + unsigned int vstride, // stride between input points. + const float *weights, // *optional point weighting values. + unsigned int wstride, // weight stride for each vertex. + float *plane); - -float getBoundingRegion(unsigned int vcount,const float *points,unsigned int pstride,float *bmin,float *bmax); // returns the diagonal distance -bool overlapAABB(const float *bmin1,const float *bmax1,const float *bmin2,const float *bmax2); // return true if the two AABB's overlap. +float getBoundingRegion(unsigned int vcount, const float *points, unsigned int pstride, float *bmin, float *bmax); // returns the diagonal distance +bool overlapAABB(const float *bmin1, const float *bmax1, const float *bmin2, const float *bmax2); // return true if the two AABB's overlap. #endif diff --git a/Extras/ConvexDecomposition/bestfitobb.cpp b/Extras/ConvexDecomposition/bestfitobb.cpp index 2d60fd045..fbbebf3f0 100644 --- a/Extras/ConvexDecomposition/bestfitobb.cpp +++ b/Extras/ConvexDecomposition/bestfitobb.cpp @@ -44,130 +44,123 @@ #include "float_math.h" // computes the OBB for this set of points relative to this transform matrix. -void computeOBB(unsigned int vcount,const float *points,unsigned int pstride,float *sides,const float *matrix) +void computeOBB(unsigned int vcount, const float *points, unsigned int pstride, float *sides, const float *matrix) { - const char *src = (const char *) points; + const char *src = (const char *)points; - float bmin[3] = { 1e9, 1e9, 1e9 }; - float bmax[3] = { -1e9, -1e9, -1e9 }; + float bmin[3] = {1e9, 1e9, 1e9}; + float bmax[3] = {-1e9, -1e9, -1e9}; - for (unsigned int i=0; i bmax[0] ) bmax[0] = t[0]; - if ( t[1] > bmax[1] ) bmax[1] = t[1]; - if ( t[2] > bmax[2] ) bmax[2] = t[2]; + if (t[0] > bmax[0]) bmax[0] = t[0]; + if (t[1] > bmax[1]) bmax[1] = t[1]; + if (t[2] > bmax[2]) bmax[2] = t[2]; - src+=pstride; - } + src += pstride; + } + sides[0] = bmax[0]; + sides[1] = bmax[1]; + sides[2] = bmax[2]; - sides[0] = bmax[0]; - sides[1] = bmax[1]; - sides[2] = bmax[2]; - - if ( fabsf(bmin[0]) > sides[0] ) sides[0] = fabsf(bmin[0]); - if ( fabsf(bmin[1]) > sides[1] ) sides[1] = fabsf(bmin[1]); - if ( fabsf(bmin[2]) > sides[2] ) sides[2] = fabsf(bmin[2]); - - sides[0]*=2.0f; - sides[1]*=2.0f; - sides[2]*=2.0f; + if (fabsf(bmin[0]) > sides[0]) sides[0] = fabsf(bmin[0]); + if (fabsf(bmin[1]) > sides[1]) sides[1] = fabsf(bmin[1]); + if (fabsf(bmin[2]) > sides[2]) sides[2] = fabsf(bmin[2]); + sides[0] *= 2.0f; + sides[1] *= 2.0f; + sides[2] *= 2.0f; } -void computeBestFitOBB(unsigned int vcount,const float *points,unsigned int pstride,float *sides,float *matrix) +void computeBestFitOBB(unsigned int vcount, const float *points, unsigned int pstride, float *sides, float *matrix) { + float bmin[3]; + float bmax[3]; - float bmin[3]; - float bmax[3]; + fm_getAABB(vcount, points, pstride, bmin, bmax); - fm_getAABB(vcount,points,pstride,bmin,bmax); + float center[3]; - float center[3]; + center[0] = (bmax[0] - bmin[0]) * 0.5f + bmin[0]; + center[1] = (bmax[1] - bmin[1]) * 0.5f + bmin[1]; + center[2] = (bmax[2] - bmin[2]) * 0.5f + bmin[2]; - center[0] = (bmax[0]-bmin[0])*0.5f + bmin[0]; - center[1] = (bmax[1]-bmin[1])*0.5f + bmin[1]; - center[2] = (bmax[2]-bmin[2])*0.5f + bmin[2]; + float ax = 0; + float ay = 0; + float az = 0; - float ax = 0; - float ay = 0; - float az = 0; + float sweep = 45.0f; // 180 degree sweep on all three axes. + float steps = 8.0f; // 16 steps on each axis. - float sweep = 45.0f; // 180 degree sweep on all three axes. - float steps = 8.0f; // 16 steps on each axis. + float bestVolume = 1e9; + float angle[3] = {0.f, 0.f, 0.f}; - float bestVolume = 1e9; - float angle[3]={0.f,0.f,0.f}; + while (sweep >= 1) + { + bool found = false; - while ( sweep >= 1 ) - { + float stepsize = sweep / steps; - bool found = false; + for (float x = ax - sweep; x <= ax + sweep; x += stepsize) + { + for (float y = ay - sweep; y <= ay + sweep; y += stepsize) + { + for (float z = az - sweep; z <= az + sweep; z += stepsize) + { + float pmatrix[16]; - float stepsize = sweep / steps; + fm_eulerMatrix(x * FM_DEG_TO_RAD, y * FM_DEG_TO_RAD, z * FM_DEG_TO_RAD, pmatrix); - for (float x=ax-sweep; x<=ax+sweep; x+=stepsize) - { - for (float y=ay-sweep; y<=ay+sweep; y+=stepsize) - { - for (float z=az-sweep; z<=az+sweep; z+=stepsize) - { - float pmatrix[16]; + pmatrix[3 * 4 + 0] = center[0]; + pmatrix[3 * 4 + 1] = center[1]; + pmatrix[3 * 4 + 2] = center[2]; - fm_eulerMatrix( x*FM_DEG_TO_RAD, y*FM_DEG_TO_RAD, z*FM_DEG_TO_RAD, pmatrix ); + float psides[3]; - pmatrix[3*4+0] = center[0]; - pmatrix[3*4+1] = center[1]; - pmatrix[3*4+2] = center[2]; + computeOBB(vcount, points, pstride, psides, pmatrix); - float psides[3]; + float volume = psides[0] * psides[1] * psides[2]; // the volume of the cube - computeOBB( vcount, points, pstride, psides, pmatrix ); + if (volume <= bestVolume) + { + bestVolume = volume; - float volume = psides[0]*psides[1]*psides[2]; // the volume of the cube + sides[0] = psides[0]; + sides[1] = psides[1]; + sides[2] = psides[2]; - if ( volume <= bestVolume ) - { - bestVolume = volume; + angle[0] = ax; + angle[1] = ay; + angle[2] = az; - sides[0] = psides[0]; - sides[1] = psides[1]; - sides[2] = psides[2]; + memcpy(matrix, pmatrix, sizeof(float) * 16); + found = true; // yes, we found an improvement. + } + } + } + } - angle[0] = ax; - angle[1] = ay; - angle[2] = az; - - memcpy(matrix,pmatrix,sizeof(float)*16); - found = true; // yes, we found an improvement. - } - } - } - } - - if ( found ) - { - - ax = angle[0]; - ay = angle[1]; - az = angle[2]; - - sweep*=0.5f; // sweep 1/2 the distance as the last time. - } - else - { - break; // no improvement, so just - } - - } + if (found) + { + ax = angle[0]; + ay = angle[1]; + az = angle[2]; + sweep *= 0.5f; // sweep 1/2 the distance as the last time. + } + else + { + break; // no improvement, so just + } + } } diff --git a/Extras/ConvexDecomposition/bestfitobb.h b/Extras/ConvexDecomposition/bestfitobb.h index 3141f5874..4536c1cdd 100644 --- a/Extras/ConvexDecomposition/bestfitobb.h +++ b/Extras/ConvexDecomposition/bestfitobb.h @@ -36,8 +36,6 @@ // http://www.amillionpixels.us // - - -void computeBestFitOBB(unsigned int vcount,const float *points,unsigned int pstride,float *sides,float *matrix); +void computeBestFitOBB(unsigned int vcount, const float *points, unsigned int pstride, float *sides, float *matrix); #endif diff --git a/Extras/ConvexDecomposition/cd_hull.cpp b/Extras/ConvexDecomposition/cd_hull.cpp index 0fc8b51e0..f97514e8e 100644 --- a/Extras/ConvexDecomposition/cd_hull.cpp +++ b/Extras/ConvexDecomposition/cd_hull.cpp @@ -84,455 +84,530 @@ using namespace ConvexDecomposition; #define DEG2RAD (PI / 180.0f) #define RAD2DEG (180.0f / PI) #define SQRT_OF_2 (1.4142135f) -#define OFFSET(Class,Member) (((char*) (&(((Class*)NULL)-> Member )))- ((char*)NULL)) +#define OFFSET(Class, Member) (((char *)(&(((Class *)NULL)->Member))) - ((char *)NULL)) namespace ConvexDecomposition { - - -int argmin(float a[],int n); -float sqr(float a); -float clampf(float a) ; -float Round(float a,float precision); -float Interpolate(const float &f0,const float &f1,float alpha) ; +int argmin(float a[], int n); +float sqr(float a); +float clampf(float a); +float Round(float a, float precision); +float Interpolate(const float &f0, const float &f1, float alpha); template -void Swap(T &a,T &b) +void Swap(T &a, T &b) { T tmp = a; - a=b; - b=tmp; -} - - - -template -T Max(const T &a,const T &b) -{ - return (a>b)?a:b; + a = b; + b = tmp; } template -T Min(const T &a,const T &b) +T Max(const T &a, const T &b) { - return (a b) ? a : b; +} + +template +T Min(const T &a, const T &b) +{ + return (a < b) ? a : b; } //---------------------------------- -class int3 +class int3 { public: - int x,y,z; + int x, y, z; int3(){}; - int3(int _x,int _y, int _z){x=_x;y=_y;z=_z;} - const int& operator[](int i) const {return (&x)[i];} - int& operator[](int i) {return (&x)[i];} + int3(int _x, int _y, int _z) + { + x = _x; + y = _y; + z = _z; + } + const int &operator[](int i) const { return (&x)[i]; } + int &operator[](int i) { return (&x)[i]; } }; - //-------- 2D -------- class float2 { public: - float x,y; - float2(){x=0;y=0;}; - float2(float _x,float _y){x=_x;y=_y;} - float& operator[](int i) {assert(i>=0&&i<2);return ((float*)this)[i];} - const float& operator[](int i) const {assert(i>=0&&i<2);return ((float*)this)[i];} + float x, y; + float2() + { + x = 0; + y = 0; + }; + float2(float _x, float _y) + { + x = _x; + y = _y; + } + float &operator[](int i) + { + assert(i >= 0 && i < 2); + return ((float *)this)[i]; + } + const float &operator[](int i) const + { + assert(i >= 0 && i < 2); + return ((float *)this)[i]; + } }; -inline float2 operator-( const float2& a, const float2& b ){return float2(a.x-b.x,a.y-b.y);} -inline float2 operator+( const float2& a, const float2& b ){return float2(a.x+b.x,a.y+b.y);} +inline float2 operator-(const float2 &a, const float2 &b) { return float2(a.x - b.x, a.y - b.y); } +inline float2 operator+(const float2 &a, const float2 &b) { return float2(a.x + b.x, a.y + b.y); } //--------- 3D --------- -class float3 // 3D +class float3 // 3D { - public: - float x,y,z; - float3(){x=0;y=0;z=0;}; - float3(float _x,float _y,float _z){x=_x;y=_y;z=_z;}; +public: + float x, y, z; + float3() + { + x = 0; + y = 0; + z = 0; + }; + float3(float _x, float _y, float _z) + { + x = _x; + y = _y; + z = _z; + }; //operator float *() { return &x;}; - float& operator[](int i) {assert(i>=0&&i<3);return ((float*)this)[i];} - const float& operator[](int i) const {assert(i>=0&&i<3);return ((float*)this)[i];} -# ifdef PLUGIN_3DSMAX - float3(const Point3 &p):x(p.x),y(p.y),z(p.z){} - operator Point3(){return *((Point3*)this);} -# endif + float &operator[](int i) + { + assert(i >= 0 && i < 3); + return ((float *)this)[i]; + } + const float &operator[](int i) const + { + assert(i >= 0 && i < 3); + return ((float *)this)[i]; + } +#ifdef PLUGIN_3DSMAX + float3(const Point3 &p) : x(p.x), y(p.y), z(p.z) + { + } + operator Point3() { return *((Point3 *)this); } +#endif }; +float3 &operator+=(float3 &a, const float3 &b); +float3 &operator-=(float3 &a, const float3 &b); +float3 &operator*=(float3 &v, const float s); +float3 &operator/=(float3 &v, const float s); -float3& operator+=( float3 &a, const float3& b ); -float3& operator-=( float3 &a ,const float3& b ); -float3& operator*=( float3 &v ,const float s ); -float3& operator/=( float3 &v, const float s ); - -float magnitude( const float3& v ); -float3 normalize( const float3& v ); +float magnitude(const float3 &v); +float3 normalize(const float3 &v); float3 safenormalize(const float3 &v); float3 vabs(const float3 &v); -float3 operator+( const float3& a, const float3& b ); -float3 operator-( const float3& a, const float3& b ); -float3 operator-( const float3& v ); -float3 operator*( const float3& v, const float s ); -float3 operator*( const float s, const float3& v ); -float3 operator/( const float3& v, const float s ); -inline int operator==( const float3 &a, const float3 &b ) { return (a.x==b.x && a.y==b.y && a.z==b.z); } -inline int operator!=( const float3 &a, const float3 &b ) { return (a.x!=b.x || a.y!=b.y || a.z!=b.z); } +float3 operator+(const float3 &a, const float3 &b); +float3 operator-(const float3 &a, const float3 &b); +float3 operator-(const float3 &v); +float3 operator*(const float3 &v, const float s); +float3 operator*(const float s, const float3 &v); +float3 operator/(const float3 &v, const float s); +inline int operator==(const float3 &a, const float3 &b) { return (a.x == b.x && a.y == b.y && a.z == b.z); } +inline int operator!=(const float3 &a, const float3 &b) { return (a.x != b.x || a.y != b.y || a.z != b.z); } // due to ambiguity and inconsistent standards ther are no overloaded operators for mult such as va*vb. -float dot( const float3& a, const float3& b ); -float3 cmul( const float3 &a, const float3 &b); -float3 cross( const float3& a, const float3& b ); -float3 Interpolate(const float3 &v0,const float3 &v1,float alpha); -float3 Round(const float3& a,float precision); -float3 VectorMax(const float3 &a, const float3 &b); -float3 VectorMin(const float3 &a, const float3 &b); - - +float dot(const float3 &a, const float3 &b); +float3 cmul(const float3 &a, const float3 &b); +float3 cross(const float3 &a, const float3 &b); +float3 Interpolate(const float3 &v0, const float3 &v1, float alpha); +float3 Round(const float3 &a, float precision); +float3 VectorMax(const float3 &a, const float3 &b); +float3 VectorMin(const float3 &a, const float3 &b); class float3x3 { - public: - float3 x,y,z; // the 3 rows of the Matrix - float3x3(){} - float3x3(float xx,float xy,float xz,float yx,float yy,float yz,float zx,float zy,float zz):x(xx,xy,xz),y(yx,yy,yz),z(zx,zy,zz){} - float3x3(float3 _x,float3 _y,float3 _z):x(_x),y(_y),z(_z){} - float3& operator[](int i) {assert(i>=0&&i<3);return (&x)[i];} - const float3& operator[](int i) const {assert(i>=0&&i<3);return (&x)[i];} - float& operator()(int r, int c) {assert(r>=0&&r<3&&c>=0&&c<3);return ((&x)[r])[c];} - const float& operator()(int r, int c) const {assert(r>=0&&r<3&&c>=0&&c<3);return ((&x)[r])[c];} -}; -float3x3 Transpose( const float3x3& m ); -float3 operator*( const float3& v , const float3x3& m ); -float3 operator*( const float3x3& m , const float3& v ); -float3x3 operator*( const float3x3& m , const float& s ); -float3x3 operator*( const float3x3& ma, const float3x3& mb ); -float3x3 operator/( const float3x3& a, const float& s ) ; -float3x3 operator+( const float3x3& a, const float3x3& b ); -float3x3 operator-( const float3x3& a, const float3x3& b ); -float3x3 &operator+=( float3x3& a, const float3x3& b ); -float3x3 &operator-=( float3x3& a, const float3x3& b ); -float3x3 &operator*=( float3x3& a, const float& s ); -float Determinant(const float3x3& m ); -float3x3 Inverse(const float3x3& a); // its just 3x3 so we simply do that cofactor method - +public: + float3 x, y, z; // the 3 rows of the Matrix + float3x3() {} + float3x3(float xx, float xy, float xz, float yx, float yy, float yz, float zx, float zy, float zz) : x(xx, xy, xz), y(yx, yy, yz), z(zx, zy, zz) {} + float3x3(float3 _x, float3 _y, float3 _z) : x(_x), y(_y), z(_z) {} + float3 &operator[](int i) + { + assert(i >= 0 && i < 3); + return (&x)[i]; + } + const float3 &operator[](int i) const + { + assert(i >= 0 && i < 3); + return (&x)[i]; + } + float &operator()(int r, int c) + { + assert(r >= 0 && r < 3 && c >= 0 && c < 3); + return ((&x)[r])[c]; + } + const float &operator()(int r, int c) const + { + assert(r >= 0 && r < 3 && c >= 0 && c < 3); + return ((&x)[r])[c]; + } +}; +float3x3 Transpose(const float3x3 &m); +float3 operator*(const float3 &v, const float3x3 &m); +float3 operator*(const float3x3 &m, const float3 &v); +float3x3 operator*(const float3x3 &m, const float &s); +float3x3 operator*(const float3x3 &ma, const float3x3 &mb); +float3x3 operator/(const float3x3 &a, const float &s); +float3x3 operator+(const float3x3 &a, const float3x3 &b); +float3x3 operator-(const float3x3 &a, const float3x3 &b); +float3x3 &operator+=(float3x3 &a, const float3x3 &b); +float3x3 &operator-=(float3x3 &a, const float3x3 &b); +float3x3 &operator*=(float3x3 &a, const float &s); +float Determinant(const float3x3 &m); +float3x3 Inverse(const float3x3 &a); // its just 3x3 so we simply do that cofactor method //-------- 4D Math -------- class float4 { public: - float x,y,z,w; - float4(){x=0;y=0;z=0;w=0;}; - float4(float _x,float _y,float _z,float _w){x=_x;y=_y;z=_z;w=_w;} - float4(const float3 &v,float _w){x=v.x;y=v.y;z=v.z;w=_w;} + float x, y, z, w; + float4() + { + x = 0; + y = 0; + z = 0; + w = 0; + }; + float4(float _x, float _y, float _z, float _w) + { + x = _x; + y = _y; + z = _z; + w = _w; + } + float4(const float3 &v, float _w) + { + x = v.x; + y = v.y; + z = v.z; + w = _w; + } //operator float *() { return &x;}; - float& operator[](int i) {assert(i>=0&&i<4);return ((float*)this)[i];} - const float& operator[](int i) const {assert(i>=0&&i<4);return ((float*)this)[i];} - const float3& xyz() const { return *((float3*)this);} - float3& xyz() { return *((float3*)this);} + float &operator[](int i) + { + assert(i >= 0 && i < 4); + return ((float *)this)[i]; + } + const float &operator[](int i) const + { + assert(i >= 0 && i < 4); + return ((float *)this)[i]; + } + const float3 &xyz() const { return *((float3 *)this); } + float3 &xyz() { return *((float3 *)this); } }; - struct D3DXMATRIX; class float4x4 { - public: - float4 x,y,z,w; // the 4 rows - float4x4(){} - float4x4(const float4 &_x, const float4 &_y, const float4 &_z, const float4 &_w):x(_x),y(_y),z(_z),w(_w){} +public: + float4 x, y, z, w; // the 4 rows + float4x4() {} + float4x4(const float4 &_x, const float4 &_y, const float4 &_z, const float4 &_w) : x(_x), y(_y), z(_z), w(_w) {} float4x4(float m00, float m01, float m02, float m03, - float m10, float m11, float m12, float m13, - float m20, float m21, float m22, float m23, - float m30, float m31, float m32, float m33 ) - :x(m00,m01,m02,m03),y(m10,m11,m12,m13),z(m20,m21,m22,m23),w(m30,m31,m32,m33){} - float& operator()(int r, int c) {assert(r>=0&&r<4&&c>=0&&c<4);return ((&x)[r])[c];} - const float& operator()(int r, int c) const {assert(r>=0&&r<4&&c>=0&&c<4);return ((&x)[r])[c];} - operator float* () {return &x.x;} - operator const float* () const {return &x.x;} - operator struct D3DXMATRIX* () { return (struct D3DXMATRIX*) this;} - operator const struct D3DXMATRIX* () const { return (struct D3DXMATRIX*) this;} + float m10, float m11, float m12, float m13, + float m20, float m21, float m22, float m23, + float m30, float m31, float m32, float m33) + : x(m00, m01, m02, m03), y(m10, m11, m12, m13), z(m20, m21, m22, m23), w(m30, m31, m32, m33) {} + float &operator()(int r, int c) + { + assert(r >= 0 && r < 4 && c >= 0 && c < 4); + return ((&x)[r])[c]; + } + const float &operator()(int r, int c) const + { + assert(r >= 0 && r < 4 && c >= 0 && c < 4); + return ((&x)[r])[c]; + } + operator float *() { return &x.x; } + operator const float *() const { return &x.x; } + operator struct D3DXMATRIX *() { return (struct D3DXMATRIX *)this; } + operator const struct D3DXMATRIX *() const { return (struct D3DXMATRIX *)this; } }; - -int operator==( const float4 &a, const float4 &b ); -float4 Homogenize(const float3 &v3,const float &w=1.0f); // Turns a 3D float3 4D vector4 by appending w -float4 cmul( const float4 &a, const float4 &b); -float4 operator*( const float4 &v, float s); -float4 operator*( float s, const float4 &v); -float4 operator+( const float4 &a, const float4 &b); -float4 operator-( const float4 &a, const float4 &b); -float4x4 operator*( const float4x4& a, const float4x4& b ); -float4 operator*( const float4& v, const float4x4& m ); +int operator==(const float4 &a, const float4 &b); +float4 Homogenize(const float3 &v3, const float &w = 1.0f); // Turns a 3D float3 4D vector4 by appending w +float4 cmul(const float4 &a, const float4 &b); +float4 operator*(const float4 &v, float s); +float4 operator*(float s, const float4 &v); +float4 operator+(const float4 &a, const float4 &b); +float4 operator-(const float4 &a, const float4 &b); +float4x4 operator*(const float4x4 &a, const float4x4 &b); +float4 operator*(const float4 &v, const float4x4 &m); float4x4 Inverse(const float4x4 &m); float4x4 MatrixRigidInverse(const float4x4 &m); float4x4 MatrixTranspose(const float4x4 &m); -float4x4 MatrixPerspectiveFov(float fovy, float Aspect, float zn, float zf ); +float4x4 MatrixPerspectiveFov(float fovy, float Aspect, float zn, float zf); float4x4 MatrixTranslation(const float3 &t); float4x4 MatrixRotationZ(const float angle_radians); -float4x4 MatrixLookAt(const float3& eye, const float3& at, const float3& up); -int operator==( const float4x4 &a, const float4x4 &b ); - +float4x4 MatrixLookAt(const float3 &eye, const float3 &at, const float3 &up); +int operator==(const float4x4 &a, const float4x4 &b); //-------- Quaternion ------------ -class Quaternion :public float4 +class Quaternion : public float4 { - public: - Quaternion() { x = y = z = 0.0f; w = 1.0f; } - Quaternion( float3 v, float t ) { v = normalize(v); w = cosf(t/2.0f); v = v*sinf(t/2.0f); x = v.x; y = v.y; z = v.z; } - Quaternion(float _x, float _y, float _z, float _w){x=_x;y=_y;z=_z;w=_w;} - float angle() const { return acosf(w)*2.0f; } - float3 axis() const { float3 a(x,y,z); if(fabsf(angle())<0.0000001f) return float3(1,0,0); return a*(1/sinf(angle()/2.0f)); } - float3 xdir() const { return float3( 1-2*(y*y+z*z), 2*(x*y+w*z), 2*(x*z-w*y) ); } - float3 ydir() const { return float3( 2*(x*y-w*z),1-2*(x*x+z*z), 2*(y*z+w*x) ); } - float3 zdir() const { return float3( 2*(x*z+w*y), 2*(y*z-w*x),1-2*(x*x+y*y) ); } - float3x3 getmatrix() const { return float3x3( xdir(), ydir(), zdir() ); } +public: + Quaternion() + { + x = y = z = 0.0f; + w = 1.0f; + } + Quaternion(float3 v, float t) + { + v = normalize(v); + w = cosf(t / 2.0f); + v = v * sinf(t / 2.0f); + x = v.x; + y = v.y; + z = v.z; + } + Quaternion(float _x, float _y, float _z, float _w) + { + x = _x; + y = _y; + z = _z; + w = _w; + } + float angle() const { return acosf(w) * 2.0f; } + float3 axis() const + { + float3 a(x, y, z); + if (fabsf(angle()) < 0.0000001f) return float3(1, 0, 0); + return a * (1 / sinf(angle() / 2.0f)); + } + float3 xdir() const { return float3(1 - 2 * (y * y + z * z), 2 * (x * y + w * z), 2 * (x * z - w * y)); } + float3 ydir() const { return float3(2 * (x * y - w * z), 1 - 2 * (x * x + z * z), 2 * (y * z + w * x)); } + float3 zdir() const { return float3(2 * (x * z + w * y), 2 * (y * z - w * x), 1 - 2 * (x * x + y * y)); } + float3x3 getmatrix() const { return float3x3(xdir(), ydir(), zdir()); } operator float3x3() { return getmatrix(); } void Normalize(); }; -Quaternion& operator*=(Quaternion& a, float s ); -Quaternion operator*( const Quaternion& a, float s ); -Quaternion operator*( const Quaternion& a, const Quaternion& b); -Quaternion operator+( const Quaternion& a, const Quaternion& b ); -Quaternion normalize( Quaternion a ); -float dot( const Quaternion &a, const Quaternion &b ); -float3 operator*( const Quaternion& q, const float3& v ); -float3 operator*( const float3& v, const Quaternion& q ); -Quaternion slerp( Quaternion a, const Quaternion& b, float interp ); -Quaternion Interpolate(const Quaternion &q0,const Quaternion &q1,float alpha); -Quaternion RotationArc(float3 v0, float3 v1 ); // returns quat q where q*v0=v1 -Quaternion Inverse(const Quaternion &q); -float4x4 MatrixFromQuatVec(const Quaternion &q, const float3 &v); - +Quaternion &operator*=(Quaternion &a, float s); +Quaternion operator*(const Quaternion &a, float s); +Quaternion operator*(const Quaternion &a, const Quaternion &b); +Quaternion operator+(const Quaternion &a, const Quaternion &b); +Quaternion normalize(Quaternion a); +float dot(const Quaternion &a, const Quaternion &b); +float3 operator*(const Quaternion &q, const float3 &v); +float3 operator*(const float3 &v, const Quaternion &q); +Quaternion slerp(Quaternion a, const Quaternion &b, float interp); +Quaternion Interpolate(const Quaternion &q0, const Quaternion &q1, float alpha); +Quaternion RotationArc(float3 v0, float3 v1); // returns quat q where q*v0=v1 +Quaternion Inverse(const Quaternion &q); +float4x4 MatrixFromQuatVec(const Quaternion &q, const float3 &v); //------ Euler Angle ----- -Quaternion YawPitchRoll( float yaw, float pitch, float roll ); -float Yaw( const Quaternion& q ); -float Pitch( const Quaternion& q ); -float Roll( Quaternion q ); -float Yaw( const float3& v ); -float Pitch( const float3& v ); - +Quaternion YawPitchRoll(float yaw, float pitch, float roll); +float Yaw(const Quaternion &q); +float Pitch(const Quaternion &q); +float Roll(Quaternion q); +float Yaw(const float3 &v); +float Pitch(const float3 &v); //------- Plane ---------- class Plane { - public: - float3 normal; - float dist; // distance below origin - the D from plane equasion Ax+By+Cz+D=0 - Plane(const float3 &n,float d):normal(n),dist(d){} - Plane():normal(),dist(0){} - void Transform(const float3 &position, const Quaternion &orientation); +public: + float3 normal; + float dist; // distance below origin - the D from plane equasion Ax+By+Cz+D=0 + Plane(const float3 &n, float d) : normal(n), dist(d) {} + Plane() : normal(), dist(0) {} + void Transform(const float3 &position, const Quaternion &orientation); }; -inline Plane PlaneFlip(const Plane &plane){return Plane(-plane.normal,-plane.dist);} -inline int operator==( const Plane &a, const Plane &b ) { return (a.normal==b.normal && a.dist==b.dist); } -inline int coplanar( const Plane &a, const Plane &b ) { return (a==b || a==PlaneFlip(b)); } - +inline Plane PlaneFlip(const Plane &plane) { return Plane(-plane.normal, -plane.dist); } +inline int operator==(const Plane &a, const Plane &b) { return (a.normal == b.normal && a.dist == b.dist); } +inline int coplanar(const Plane &a, const Plane &b) { return (a == b || a == PlaneFlip(b)); } //--------- Utility Functions ------ -float3 PlaneLineIntersection(const Plane &plane, const float3 &p0, const float3 &p1); -float3 PlaneProject(const Plane &plane, const float3 &point); -float3 LineProject(const float3 &p0, const float3 &p1, const float3 &a); // projects a onto infinite line p0p1 -float LineProjectTime(const float3 &p0, const float3 &p1, const float3 &a); -float3 ThreePlaneIntersection(const Plane &p0,const Plane &p1, const Plane &p2); -int PolyHit(const float3 *vert,const int n,const float3 &v0, const float3 &v1, float3 *impact=NULL, float3 *normal=NULL); -int BoxInside(const float3 &p,const float3 &bmin, const float3 &bmax) ; -int BoxIntersect(const float3 &v0, const float3 &v1, const float3 &bmin, const float3 &bmax, float3 *impact); -float DistanceBetweenLines(const float3 &ustart, const float3 &udir, const float3 &vstart, const float3 &vdir, float3 *upoint=NULL, float3 *vpoint=NULL); -float3 TriNormal(const float3 &v0, const float3 &v1, const float3 &v2); -float3 NormalOf(const float3 *vert, const int n); +float3 PlaneLineIntersection(const Plane &plane, const float3 &p0, const float3 &p1); +float3 PlaneProject(const Plane &plane, const float3 &point); +float3 LineProject(const float3 &p0, const float3 &p1, const float3 &a); // projects a onto infinite line p0p1 +float LineProjectTime(const float3 &p0, const float3 &p1, const float3 &a); +float3 ThreePlaneIntersection(const Plane &p0, const Plane &p1, const Plane &p2); +int PolyHit(const float3 *vert, const int n, const float3 &v0, const float3 &v1, float3 *impact = NULL, float3 *normal = NULL); +int BoxInside(const float3 &p, const float3 &bmin, const float3 &bmax); +int BoxIntersect(const float3 &v0, const float3 &v1, const float3 &bmin, const float3 &bmax, float3 *impact); +float DistanceBetweenLines(const float3 &ustart, const float3 &udir, const float3 &vstart, const float3 &vdir, float3 *upoint = NULL, float3 *vpoint = NULL); +float3 TriNormal(const float3 &v0, const float3 &v1, const float3 &v2); +float3 NormalOf(const float3 *vert, const int n); Quaternion VirtualTrackBall(const float3 &cop, const float3 &cor, const float3 &dir0, const float3 &dir1); +float sqr(float a) { return a * a; } +float clampf(float a) { return Min(1.0f, Max(0.0f, a)); } -float sqr(float a) {return a*a;} -float clampf(float a) {return Min(1.0f,Max(0.0f,a));} - - -float Round(float a,float precision) +float Round(float a, float precision) { - return floorf(0.5f+a/precision)*precision; + return floorf(0.5f + a / precision) * precision; } - -float Interpolate(const float &f0,const float &f1,float alpha) +float Interpolate(const float &f0, const float &f1, float alpha) { - return f0*(1-alpha) + f1*alpha; + return f0 * (1 - alpha) + f1 * alpha; } - -int argmin(float a[],int n) +int argmin(float a[], int n) { - int r=0; - for(int i=1;i=1.0) { + float d = dot(a, b); + if (d >= 1.0) + { return a; } float theta = acosf(d); - if(theta==0.0f) { return(a);} - return a*(sinf(theta-interp*theta)/sinf(theta)) + b*(sinf(interp*theta)/sinf(theta)); + if (theta == 0.0f) + { + return (a); + } + return a * (sinf(theta - interp * theta) / sinf(theta)) + b * (sinf(interp * theta) / sinf(theta)); } - -Quaternion Interpolate(const Quaternion &q0,const Quaternion &q1,float alpha) { - return slerp(q0,q1,alpha); -} - - -Quaternion YawPitchRoll( float yaw, float pitch, float roll ) +Quaternion Interpolate(const Quaternion &q0, const Quaternion &q1, float alpha) { - roll *= DEG2RAD; - yaw *= DEG2RAD; + return slerp(q0, q1, alpha); +} + +Quaternion YawPitchRoll(float yaw, float pitch, float roll) +{ + roll *= DEG2RAD; + yaw *= DEG2RAD; pitch *= DEG2RAD; - return Quaternion(float3(0.0f,0.0f,1.0f),yaw)*Quaternion(float3(1.0f,0.0f,0.0f),pitch)*Quaternion(float3(0.0f,1.0f,0.0f),roll); + return Quaternion(float3(0.0f, 0.0f, 1.0f), yaw) * Quaternion(float3(1.0f, 0.0f, 0.0f), pitch) * Quaternion(float3(0.0f, 1.0f, 0.0f), roll); } -float Yaw( const Quaternion& q ) +float Yaw(const Quaternion &q) { float3 v; - v=q.ydir(); - return (v.y==0.0&&v.x==0.0) ? 0.0f: atan2f(-v.x,v.y)*RAD2DEG; + v = q.ydir(); + return (v.y == 0.0 && v.x == 0.0) ? 0.0f : atan2f(-v.x, v.y) * RAD2DEG; } -float Pitch( const Quaternion& q ) +float Pitch(const Quaternion &q) { float3 v; - v=q.ydir(); - return atan2f(v.z,sqrtf(sqr(v.x)+sqr(v.y)))*RAD2DEG; + v = q.ydir(); + return atan2f(v.z, sqrtf(sqr(v.x) + sqr(v.y))) * RAD2DEG; } -float Roll( Quaternion q ) +float Roll(Quaternion q) { - q = Quaternion(float3(0.0f,0.0f,1.0f),-Yaw(q)*DEG2RAD) *q; - q = Quaternion(float3(1.0f,0.0f,0.0f),-Pitch(q)*DEG2RAD) *q; - return atan2f(-q.xdir().z,q.xdir().x)*RAD2DEG; + q = Quaternion(float3(0.0f, 0.0f, 1.0f), -Yaw(q) * DEG2RAD) * q; + q = Quaternion(float3(1.0f, 0.0f, 0.0f), -Pitch(q) * DEG2RAD) * q; + return atan2f(-q.xdir().z, q.xdir().x) * RAD2DEG; } -float Yaw( const float3& v ) +float Yaw(const float3 &v) { - return (v.y==0.0&&v.x==0.0) ? 0.0f: atan2f(-v.x,v.y)*RAD2DEG; + return (v.y == 0.0 && v.x == 0.0) ? 0.0f : atan2f(-v.x, v.y) * RAD2DEG; } -float Pitch( const float3& v ) +float Pitch(const float3 &v) { - return atan2f(v.z,sqrtf(sqr(v.x)+sqr(v.y)))*RAD2DEG; + return atan2f(v.z, sqrtf(sqr(v.x) + sqr(v.y))) * RAD2DEG; } - //------------- Plane -------------- - -void Plane::Transform(const float3 &position, const Quaternion &orientation) { - // Transforms the plane to the space defined by the +void Plane::Transform(const float3 &position, const Quaternion &orientation) +{ + // Transforms the plane to the space defined by the // given position/orientation. float3 newnormal; float3 origin; - newnormal = Inverse(orientation)*normal; - origin = Inverse(orientation)*(-normal*dist - position); + newnormal = Inverse(orientation) * normal; + origin = Inverse(orientation) * (-normal * dist - position); normal = newnormal; dist = -dot(newnormal, origin); } - - - //--------- utility functions ------------- // RotationArc() // Given two vectors v0 and v1 this function // returns quaternion q where q*v0==v1. // Routine taken from game programming gems. -Quaternion RotationArc(float3 v0,float3 v1){ +Quaternion RotationArc(float3 v0, float3 v1) +{ Quaternion q; v0 = normalize(v0); // Comment these two lines out if you know its not needed. v1 = normalize(v1); // If vector is already unit length then why do it again? - float3 c = cross(v0,v1); - float d = dot(v0,v1); - if(d<=-1.0f) { return Quaternion(1,0,0,0);} // 180 about x axis - float s = sqrtf((1+d)*2); + float3 c = cross(v0, v1); + float d = dot(v0, v1); + if (d <= -1.0f) + { + return Quaternion(1, 0, 0, 0); + } // 180 about x axis + float s = sqrtf((1 + d) * 2); q.x = c.x / s; q.y = c.y / s; q.z = c.z / s; - q.w = s /2.0f; + q.w = s / 2.0f; return q; } - -float4x4 MatrixFromQuatVec(const Quaternion &q, const float3 &v) +float4x4 MatrixFromQuatVec(const Quaternion &q, const float3 &v) { - // builds a 4x4 transformation matrix based on orientation q and translation v - float qx2 = q.x*q.x; - float qy2 = q.y*q.y; - float qz2 = q.z*q.z; + // builds a 4x4 transformation matrix based on orientation q and translation v + float qx2 = q.x * q.x; + float qy2 = q.y * q.y; + float qz2 = q.z * q.z; - float qxqy = q.x*q.y; - float qxqz = q.x*q.z; - float qxqw = q.x*q.w; - float qyqz = q.y*q.z; - float qyqw = q.y*q.w; - float qzqw = q.z*q.w; + float qxqy = q.x * q.y; + float qxqz = q.x * q.z; + float qxqw = q.x * q.w; + float qyqz = q.y * q.z; + float qyqw = q.y * q.w; + float qzqw = q.z * q.w; return float4x4( - 1-2*(qy2+qz2), - 2*(qxqy+qzqw), - 2*(qxqz-qyqw), - 0 , - 2*(qxqy-qzqw), - 1-2*(qx2+qz2), - 2*(qyqz+qxqw), - 0 , - 2*(qxqz+qyqw), - 2*(qyqz-qxqw), - 1-2*(qx2+qy2), - 0 , - v.x , - v.y , - v.z , - 1.0f ); + 1 - 2 * (qy2 + qz2), + 2 * (qxqy + qzqw), + 2 * (qxqz - qyqw), + 0, + 2 * (qxqy - qzqw), + 1 - 2 * (qx2 + qz2), + 2 * (qyqz + qxqw), + 0, + 2 * (qxqz + qyqw), + 2 * (qyqz - qxqw), + 1 - 2 * (qx2 + qy2), + 0, + v.x, + v.y, + v.z, + 1.0f); } - float3 PlaneLineIntersection(const Plane &plane, const float3 &p0, const float3 &p1) { // returns the point where the line p0-p1 intersects the plane n&d - float3 dif; - dif = p1-p0; - float dn= dot(plane.normal,dif); - float t = -(plane.dist+dot(plane.normal,p0) )/dn; - return p0 + (dif*t); + float3 dif; + dif = p1 - p0; + float dn = dot(plane.normal, dif); + float t = -(plane.dist + dot(plane.normal, p0)) / dn; + return p0 + (dif * t); } float3 PlaneProject(const Plane &plane, const float3 &point) { - return point - plane.normal * (dot(point,plane.normal)+plane.dist); + return point - plane.normal * (dot(point, plane.normal) + plane.dist); } float3 LineProject(const float3 &p0, const float3 &p1, const float3 &a) { float3 w; - w = p1-p0; - float t= dot(w,(a-p0)) / (sqr(w.x)+sqr(w.y)+sqr(w.z)); - return p0+ w*t; + w = p1 - p0; + float t = dot(w, (a - p0)) / (sqr(w.x) + sqr(w.y) + sqr(w.z)); + return p0 + w * t; } - float LineProjectTime(const float3 &p0, const float3 &p1, const float3 &a) { float3 w; - w = p1-p0; - float t= dot(w,(a-p0)) / (sqr(w.x)+sqr(w.y)+sqr(w.z)); + w = p1 - p0; + float t = dot(w, (a - p0)) / (sqr(w.x) + sqr(w.y) + sqr(w.z)); return t; } - - float3 TriNormal(const float3 &v0, const float3 &v1, const float3 &v2) { // return the normal of the triangle // inscribed by v0, v1, and v2 - float3 cp=cross(v1-v0,v2-v1); - float m=magnitude(cp); - if(m==0) return float3(1,0,0); - return cp*(1.0f/m); + float3 cp = cross(v1 - v0, v2 - v1); + float m = magnitude(cp); + if (m == 0) return float3(1, 0, 0); + return cp * (1.0f / m); } - - -int BoxInside(const float3 &p, const float3 &bmin, const float3 &bmax) +int BoxInside(const float3 &p, const float3 &bmin, const float3 &bmax) { - return (p.x >= bmin.x && p.x <=bmax.x && - p.y >= bmin.y && p.y <=bmax.y && - p.z >= bmin.z && p.z <=bmax.z ); + return (p.x >= bmin.x && p.x <= bmax.x && + p.y >= bmin.y && p.y <= bmax.y && + p.z >= bmin.z && p.z <= bmax.z); } - -int BoxIntersect(const float3 &v0, const float3 &v1, const float3 &bmin, const float3 &bmax,float3 *impact) +int BoxIntersect(const float3 &v0, const float3 &v1, const float3 &bmin, const float3 &bmax, float3 *impact) { - if(BoxInside(v0,bmin,bmax)) - { - *impact=v0; - return 1; - } - if(v0.x<=bmin.x && v1.x>=bmin.x) - { - float a = (bmin.x-v0.x)/(v1.x-v0.x); + if (BoxInside(v0, bmin, bmax)) + { + *impact = v0; + return 1; + } + if (v0.x <= bmin.x && v1.x >= bmin.x) + { + float a = (bmin.x - v0.x) / (v1.x - v0.x); //v.x = bmin.x; - float vy = (1-a) *v0.y + a*v1.y; - float vz = (1-a) *v0.z + a*v1.z; - if(vy>=bmin.y && vy<=bmax.y && vz>=bmin.z && vz<=bmax.z) - { + float vy = (1 - a) * v0.y + a * v1.y; + float vz = (1 - a) * v0.z + a * v1.z; + if (vy >= bmin.y && vy <= bmax.y && vz >= bmin.z && vz <= bmax.z) + { impact->x = bmin.x; impact->y = vy; impact->z = vz; return 1; } } - else if(v0.x >= bmax.x && v1.x <= bmax.x) - { - float a = (bmax.x-v0.x)/(v1.x-v0.x); + else if (v0.x >= bmax.x && v1.x <= bmax.x) + { + float a = (bmax.x - v0.x) / (v1.x - v0.x); //v.x = bmax.x; - float vy = (1-a) *v0.y + a*v1.y; - float vz = (1-a) *v0.z + a*v1.z; - if(vy>=bmin.y && vy<=bmax.y && vz>=bmin.z && vz<=bmax.z) - { + float vy = (1 - a) * v0.y + a * v1.y; + float vz = (1 - a) * v0.z + a * v1.z; + if (vy >= bmin.y && vy <= bmax.y && vz >= bmin.z && vz <= bmax.z) + { impact->x = bmax.x; impact->y = vy; impact->z = vz; return 1; } } - if(v0.y<=bmin.y && v1.y>=bmin.y) - { - float a = (bmin.y-v0.y)/(v1.y-v0.y); - float vx = (1-a) *v0.x + a*v1.x; + if (v0.y <= bmin.y && v1.y >= bmin.y) + { + float a = (bmin.y - v0.y) / (v1.y - v0.y); + float vx = (1 - a) * v0.x + a * v1.x; //v.y = bmin.y; - float vz = (1-a) *v0.z + a*v1.z; - if(vx>=bmin.x && vx<=bmax.x && vz>=bmin.z && vz<=bmax.z) - { + float vz = (1 - a) * v0.z + a * v1.z; + if (vx >= bmin.x && vx <= bmax.x && vz >= bmin.z && vz <= bmax.z) + { impact->x = vx; impact->y = bmin.y; impact->z = vz; return 1; } } - else if(v0.y >= bmax.y && v1.y <= bmax.y) - { - float a = (bmax.y-v0.y)/(v1.y-v0.y); - float vx = (1-a) *v0.x + a*v1.x; + else if (v0.y >= bmax.y && v1.y <= bmax.y) + { + float a = (bmax.y - v0.y) / (v1.y - v0.y); + float vx = (1 - a) * v0.x + a * v1.x; // vy = bmax.y; - float vz = (1-a) *v0.z + a*v1.z; - if(vx>=bmin.x && vx<=bmax.x && vz>=bmin.z && vz<=bmax.z) - { + float vz = (1 - a) * v0.z + a * v1.z; + if (vx >= bmin.x && vx <= bmax.x && vz >= bmin.z && vz <= bmax.z) + { impact->x = vx; impact->y = bmax.y; impact->z = vz; return 1; } } - if(v0.z<=bmin.z && v1.z>=bmin.z) - { - float a = (bmin.z-v0.z)/(v1.z-v0.z); - float vx = (1-a) *v0.x + a*v1.x; - float vy = (1-a) *v0.y + a*v1.y; + if (v0.z <= bmin.z && v1.z >= bmin.z) + { + float a = (bmin.z - v0.z) / (v1.z - v0.z); + float vx = (1 - a) * v0.x + a * v1.x; + float vy = (1 - a) * v0.y + a * v1.y; // v.z = bmin.z; - if(vy>=bmin.y && vy<=bmax.y && vx>=bmin.x && vx<=bmax.x) - { + if (vy >= bmin.y && vy <= bmax.y && vx >= bmin.x && vx <= bmax.x) + { impact->x = vx; impact->y = vy; impact->z = bmin.z; return 1; } } - else if(v0.z >= bmax.z && v1.z <= bmax.z) - { - float a = (bmax.z-v0.z)/(v1.z-v0.z); - float vx = (1-a) *v0.x + a*v1.x; - float vy = (1-a) *v0.y + a*v1.y; + else if (v0.z >= bmax.z && v1.z <= bmax.z) + { + float a = (bmax.z - v0.z) / (v1.z - v0.z); + float vx = (1 - a) * v0.x + a * v1.x; + float vy = (1 - a) * v0.y + a * v1.y; // v.z = bmax.z; - if(vy>=bmin.y && vy<=bmax.y && vx>=bmin.x && vx<=bmax.x) - { + if (vy >= bmin.y && vy <= bmax.y && vx >= bmin.x && vx <= bmax.x) + { impact->x = vx; impact->y = vy; impact->z = bmax.z; @@ -1245,126 +1289,128 @@ int BoxIntersect(const float3 &v0, const float3 &v1, const float3 &bmin, const f return 0; } - float DistanceBetweenLines(const float3 &ustart, const float3 &udir, const float3 &vstart, const float3 &vdir, float3 *upoint, float3 *vpoint) { float3 cp; - cp = normalize(cross(udir,vdir)); + cp = normalize(cross(udir, vdir)); - float distu = -dot(cp,ustart); - float distv = -dot(cp,vstart); - float dist = (float)fabs(distu-distv); - if(upoint) - { + float distu = -dot(cp, ustart); + float distv = -dot(cp, vstart); + float dist = (float)fabs(distu - distv); + if (upoint) + { Plane plane; - plane.normal = normalize(cross(vdir,cp)); - plane.dist = -dot(plane.normal,vstart); - *upoint = PlaneLineIntersection(plane,ustart,ustart+udir); + plane.normal = normalize(cross(vdir, cp)); + plane.dist = -dot(plane.normal, vstart); + *upoint = PlaneLineIntersection(plane, ustart, ustart + udir); } - if(vpoint) - { + if (vpoint) + { Plane plane; - plane.normal = normalize(cross(udir,cp)); - plane.dist = -dot(plane.normal,ustart); - *vpoint = PlaneLineIntersection(plane,vstart,vstart+vdir); + plane.normal = normalize(cross(udir, cp)); + plane.dist = -dot(plane.normal, ustart); + *vpoint = PlaneLineIntersection(plane, vstart, vstart + vdir); } return dist; } - -Quaternion VirtualTrackBall(const float3 &cop, const float3 &cor, const float3 &dir1, const float3 &dir2) +Quaternion VirtualTrackBall(const float3 &cop, const float3 &cor, const float3 &dir1, const float3 &dir2) { // routine taken from game programming gems. // Implement track ball functionality to spin stuf on the screen // cop center of projection // cor center of rotation - // dir1 old mouse direction + // dir1 old mouse direction // dir2 new mouse direction // pretend there is a sphere around cor. Then find the points // where dir1 and dir2 intersect that sphere. Find the // rotation that takes the first point to the second. float m; - // compute plane + // compute plane float3 nrml = cor - cop; - float fudgefactor = 1.0f/(magnitude(nrml) * 0.25f); // since trackball proportional to distance from cop + float fudgefactor = 1.0f / (magnitude(nrml) * 0.25f); // since trackball proportional to distance from cop nrml = normalize(nrml); - float dist = -dot(nrml,cor); - float3 u= PlaneLineIntersection(Plane(nrml,dist),cop,cop+dir1); - u=u-cor; - u=u*fudgefactor; - m= magnitude(u); - if(m>1) - { - u/=m; - } - else - { - u=u - (nrml * sqrtf(1-m*m)); + float dist = -dot(nrml, cor); + float3 u = PlaneLineIntersection(Plane(nrml, dist), cop, cop + dir1); + u = u - cor; + u = u * fudgefactor; + m = magnitude(u); + if (m > 1) + { + u /= m; } - float3 v= PlaneLineIntersection(Plane(nrml,dist),cop,cop+dir2); - v=v-cor; - v=v*fudgefactor; - m= magnitude(v); - if(m>1) - { - v/=m; - } - else - { - v=v - (nrml * sqrtf(1-m*m)); + else + { + u = u - (nrml * sqrtf(1 - m * m)); } - return RotationArc(u,v); + float3 v = PlaneLineIntersection(Plane(nrml, dist), cop, cop + dir2); + v = v - cor; + v = v * fudgefactor; + m = magnitude(v); + if (m > 1) + { + v /= m; + } + else + { + v = v - (nrml * sqrtf(1 - m * m)); + } + return RotationArc(u, v); } - -int countpolyhit=0; +int countpolyhit = 0; int PolyHit(const float3 *vert, const int n, const float3 &v0, const float3 &v1, float3 *impact, float3 *normal) { countpolyhit++; int i; - float3 nrml(0,0,0); - for(i=0;i0) - { - return 0; - } + if (m == 0.0) + { + return 0; + } + nrml = nrml * (1.0f / m); + float dist = -dot(nrml, vert[0]); + float d0, d1; + if ((d0 = dot(v0, nrml) + dist) < 0 || (d1 = dot(v1, nrml) + dist) > 0) + { + return 0; + } - float3 the_point; + float3 the_point; // By using the cached plane distances d0 and d1 // we can optimize the following: // the_point = planelineintersection(nrml,dist,v0,v1); - float a = d0/(d0-d1); - the_point = v0*(1-a) + v1*a; + float a = d0 / (d0 - d1); + the_point = v0 * (1 - a) + v1 * a; - - int inside=1; - for(int j=0;inside && j= 0.0); + int inside = 1; + for (int j = 0; inside && j < n; j++) + { + // let inside = 0 if outside + float3 pp1, pp2, side; + pp1 = vert[j]; + pp2 = vert[(j + 1) % n]; + side = cross((pp2 - pp1), (the_point - pp1)); + inside = (dot(nrml, side) >= 0.0); } - if(inside) + if (inside) + { + if (normal) { - if(normal){*normal=nrml;} - if(impact){*impact=the_point;} + *normal = nrml; + } + if (impact) + { + *impact = the_point; + } } return inside; } @@ -1375,215 +1421,245 @@ int PolyHit(const float3 *vert, const int n, const float3 &v0, const float3 &v1, //************************************************************************** //************************************************************************** -template class ArrayRet; -template class Array { - public: - Array(int s=0); - Array(Array &array); - Array(ArrayRet &array); - ~Array(); - void allocate(int s); - void SetSize(int s); - void Pack(); - Type& Add(Type); - void AddUnique(Type); - int Contains(Type); - void Insert(Type,int); - int IndexOf(Type); - void Remove(Type); - void DelIndex(int i); - Type * element; - int count; - int array_size; - const Type &operator[](int i) const { assert(i>=0 && i=0 && i +class ArrayRet; +template +class Array +{ +public: + Array(int s = 0); + Array(Array &array); + Array(ArrayRet &array); + ~Array(); + void allocate(int s); + void SetSize(int s); + void Pack(); + Type &Add(Type); + void AddUnique(Type); + int Contains(Type); + void Insert(Type, int); + int IndexOf(Type); + void Remove(Type); + void DelIndex(int i); + Type *element; + int count; + int array_size; + const Type &operator[](int i) const + { + assert(i >= 0 && i < count); + return element[i]; + } + Type &operator[](int i) + { + assert(i >= 0 && i < count); + return element[i]; + } + Type &Pop() + { + assert(count); + count--; + return element[count]; + } Array &operator=(Array &array); Array &operator=(ArrayRet &array); // operator ArrayRet &() { return *(ArrayRet *)this;} // this worked but i suspect could be dangerous }; -template class ArrayRet:public Array +template +class ArrayRet : public Array { }; -template Array::Array(int s) +template +Array::Array(int s) { - count=0; + count = 0; array_size = 0; element = NULL; - if(s) + if (s) { allocate(s); } } - -template Array::Array(Array &array) +template +Array::Array(Array &array) { - count=0; + count = 0; array_size = 0; element = NULL; - for(int i=0;i Array::Array(ArrayRet &array) +template +Array::Array(ArrayRet &array) { *this = array; } -template Array &Array::operator=(ArrayRet &array) +template +Array &Array::operator=(ArrayRet &array) { - count=array.count; + count = array.count; array_size = array.array_size; element = array.element; - array.element=NULL; - array.count=0; - array.array_size=0; + array.element = NULL; + array.count = 0; + array.array_size = 0; return *this; } - -template Array &Array::operator=(Array &array) +template +Array &Array::operator=(Array &array) { - count=0; - for(int i=0;i Array::~Array() +template +Array::~Array() { if (element != NULL) { - free(element); + free(element); } - count=0;array_size=0;element=NULL; + count = 0; + array_size = 0; + element = NULL; } -template void Array::allocate(int s) +template +void Array::allocate(int s) { - assert(s>0); - assert(s>=count); + assert(s > 0); + assert(s >= count); Type *old = element; - array_size =s; - element = (Type *) malloc( sizeof(Type)*array_size); + array_size = s; + element = (Type *)malloc(sizeof(Type) * array_size); assert(element); - for(int i=0;i void Array::SetSize(int s) +template +void Array::SetSize(int s) { - if(s==0) + if (s == 0) { - if(element) + if (element) { free(element); element = NULL; } - array_size = s; + array_size = s; } else { allocate(s); } - count=s; + count = s; } -template void Array::Pack() +template +void Array::Pack() { allocate(count); } -template Type& Array::Add(Type t) +template +Type &Array::Add(Type t) { - assert(count<=array_size); - if(count==array_size) + assert(count <= array_size); + if (count == array_size) { - allocate((array_size)?array_size *2:16); + allocate((array_size) ? array_size * 2 : 16); } element[count++] = t; - return element[count-1]; + return element[count - 1]; } -template int Array::Contains(Type t) +template +int Array::Contains(Type t) { int i; - int found=0; - for(i=0;i void Array::AddUnique(Type t) +template +void Array::AddUnique(Type t) { - if(!Contains(t)) Add(t); + if (!Contains(t)) Add(t); } - -template void Array::DelIndex(int i) +template +void Array::DelIndex(int i) { - assert(i void Array::Remove(Type t) +template +void Array::Remove(Type t) { int i; - for(i=0;i void Array::Insert(Type t,int k) +template +void Array::Insert(Type t, int k) { - int i=count; - Add(t); // to allocate space - while(i>k) + int i = count; + Add(t); // to allocate space + while (i > k) { - element[i]=element[i-1]; + element[i] = element[i - 1]; i--; } - assert(i==k); - element[k]=t; + assert(i == k); + element[k] = t; } - -template int Array::IndexOf(Type t) +template +int Array::IndexOf(Type t) { int i; - for(i=0;i int Array::IndexOf(Type t) return -1; } - - //********************************************************************* //********************************************************************* //******** Hull header @@ -1603,85 +1677,83 @@ template int Array::IndexOf(Type t) class PHullResult { public: - PHullResult(void) { mVcount = 0; mIndexCount = 0; mFaceCount = 0; mVertices = 0; - mIndices = 0; + mIndices = 0; } unsigned int mVcount; unsigned int mIndexCount; unsigned int mFaceCount; - float *mVertices; + float *mVertices; unsigned int *mIndices; }; - #define REAL3 float3 -#define REAL float +#define REAL float -#define COPLANAR (0) -#define UNDER (1) -#define OVER (2) -#define SPLIT (OVER|UNDER) +#define COPLANAR (0) +#define UNDER (1) +#define OVER (2) +#define SPLIT (OVER | UNDER) #define PAPERWIDTH (0.001f) float planetestepsilon = PAPERWIDTH; - -class ConvexH +class ConvexH { - public: +public: class HalfEdge { - public: + public: short ea; // the other half of the edge (index into edges list) unsigned char v; // the vertex at the start of this edge (index into vertices list) unsigned char p; // the facet on which this edge lies (index into facets list) - HalfEdge(){} - HalfEdge(short _ea,unsigned char _v, unsigned char _p):ea(_ea),v(_v),p(_p){} + HalfEdge() {} + HalfEdge(short _ea, unsigned char _v, unsigned char _p) : ea(_ea), v(_v), p(_p) {} }; Array vertices; Array edges; - Array facets; - ConvexH(int vertices_size,int edges_size,int facets_size); + Array facets; + ConvexH(int vertices_size, int edges_size, int facets_size); }; typedef ConvexH::HalfEdge HalfEdge; -ConvexH::ConvexH(int vertices_size,int edges_size,int facets_size) - :vertices(vertices_size) - ,edges(edges_size) - ,facets(facets_size) +ConvexH::ConvexH(int vertices_size, int edges_size, int facets_size) + : vertices(vertices_size), edges(edges_size), facets(facets_size) { - vertices.count=vertices_size; - edges.count = edges_size; - facets.count = facets_size; + vertices.count = vertices_size; + edges.count = edges_size; + facets.count = facets_size; } -ConvexH *ConvexHDup(ConvexH *src) { - ConvexH *dst = new ConvexH(src->vertices.count,src->edges.count,src->facets.count); - memcpy(dst->vertices.element,src->vertices.element,sizeof(float3)*src->vertices.count); - memcpy(dst->edges.element,src->edges.element,sizeof(HalfEdge)*src->edges.count); - memcpy(dst->facets.element,src->facets.element,sizeof(Plane)*src->facets.count); +ConvexH *ConvexHDup(ConvexH *src) +{ + ConvexH *dst = new ConvexH(src->vertices.count, src->edges.count, src->facets.count); + memcpy(dst->vertices.element, src->vertices.element, sizeof(float3) * src->vertices.count); + memcpy(dst->edges.element, src->edges.element, sizeof(HalfEdge) * src->edges.count); + memcpy(dst->facets.element, src->facets.element, sizeof(Plane) * src->facets.count); return dst; } - -int PlaneTest(const Plane &p, const REAL3 &v) { - REAL a = dot(v,p.normal)+p.dist; - int flag = (a>planetestepsilon)?OVER:((a<-planetestepsilon)?UNDER:COPLANAR); +int PlaneTest(const Plane &p, const REAL3 &v) +{ + REAL a = dot(v, p.normal) + p.dist; + int flag = (a > planetestepsilon) ? OVER : ((a < -planetestepsilon) ? UNDER : COPLANAR); return flag; } -int SplitTest(ConvexH &convex,const Plane &plane) { - int flag=0; - for(int i=0;i= convex.edges.count || convex.edges[inext].p != convex.edges[i].p) { + int inext = i + 1; + if (inext >= convex.edges.count || convex.edges[inext].p != convex.edges[i].p) + { inext = estart; } assert(convex.edges[inext].p == convex.edges[i].p); int nb = convex.edges[i].ea; - assert(nb!=255); - if(nb==255 || nb==-1) return 0; - assert(nb!=-1); - assert(i== convex.edges[nb].ea); + assert(nb != 255); + if (nb == 255 || nb == -1) return 0; + assert(nb != -1); + assert(i == convex.edges[nb].ea); } - for(i=0;i= convex.edges.count || convex.edges[i1].p != convex.edges[i].p) { + int i1 = i + 1; + if (i1 >= convex.edges.count || convex.edges[i1].p != convex.edges[i].p) + { i1 = estart; } - int i2 = i1+1; - if(i2>= convex.edges.count || convex.edges[i2].p != convex.edges[i].p) { + int i2 = i1 + 1; + if (i2 >= convex.edges.count || convex.edges[i2].p != convex.edges[i].p) + { i2 = estart; } - if(i==i2) continue; // i sliced tangent to an edge and created 2 meaningless edges - REAL3 localnormal = TriNormal(convex.vertices[convex.edges[i ].v], - convex.vertices[convex.edges[i1].v], - convex.vertices[convex.edges[i2].v]); - assert(dot(localnormal,convex.facets[convex.edges[i].p].normal)>0); - if(dot(localnormal,convex.facets[convex.edges[i].p].normal)<=0)return 0; + if (i == i2) continue; // i sliced tangent to an edge and created 2 meaningless edges + REAL3 localnormal = TriNormal(convex.vertices[convex.edges[i].v], + convex.vertices[convex.edges[i1].v], + convex.vertices[convex.edges[i2].v]); + assert(dot(localnormal, convex.facets[convex.edges[i].p].normal) > 0); + if (dot(localnormal, convex.facets[convex.edges[i].p].normal) <= 0) return 0; } return 1; } // back to back quads -ConvexH *test_btbq() { - ConvexH *convex = new ConvexH(4,8,2); - convex->vertices[0] = REAL3(0,0,0); - convex->vertices[1] = REAL3(1,0,0); - convex->vertices[2] = REAL3(1,1,0); - convex->vertices[3] = REAL3(0,1,0); - convex->facets[0] = Plane(REAL3(0,0,1),0); - convex->facets[1] = Plane(REAL3(0,0,-1),0); - convex->edges[0] = HalfEdge(7,0,0); - convex->edges[1] = HalfEdge(6,1,0); - convex->edges[2] = HalfEdge(5,2,0); - convex->edges[3] = HalfEdge(4,3,0); +ConvexH *test_btbq() +{ + ConvexH *convex = new ConvexH(4, 8, 2); + convex->vertices[0] = REAL3(0, 0, 0); + convex->vertices[1] = REAL3(1, 0, 0); + convex->vertices[2] = REAL3(1, 1, 0); + convex->vertices[3] = REAL3(0, 1, 0); + convex->facets[0] = Plane(REAL3(0, 0, 1), 0); + convex->facets[1] = Plane(REAL3(0, 0, -1), 0); + convex->edges[0] = HalfEdge(7, 0, 0); + convex->edges[1] = HalfEdge(6, 1, 0); + convex->edges[2] = HalfEdge(5, 2, 0); + convex->edges[3] = HalfEdge(4, 3, 0); - convex->edges[4] = HalfEdge(3,0,1); - convex->edges[5] = HalfEdge(2,3,1); - convex->edges[6] = HalfEdge(1,2,1); - convex->edges[7] = HalfEdge(0,1,1); + convex->edges[4] = HalfEdge(3, 0, 1); + convex->edges[5] = HalfEdge(2, 3, 1); + convex->edges[6] = HalfEdge(1, 2, 1); + convex->edges[7] = HalfEdge(0, 1, 1); AssertIntact(*convex); return convex; } -ConvexH *test_cube() { - ConvexH *convex = new ConvexH(8,24,6); - convex->vertices[0] = REAL3(0,0,0); - convex->vertices[1] = REAL3(0,0,1); - convex->vertices[2] = REAL3(0,1,0); - convex->vertices[3] = REAL3(0,1,1); - convex->vertices[4] = REAL3(1,0,0); - convex->vertices[5] = REAL3(1,0,1); - convex->vertices[6] = REAL3(1,1,0); - convex->vertices[7] = REAL3(1,1,1); +ConvexH *test_cube() +{ + ConvexH *convex = new ConvexH(8, 24, 6); + convex->vertices[0] = REAL3(0, 0, 0); + convex->vertices[1] = REAL3(0, 0, 1); + convex->vertices[2] = REAL3(0, 1, 0); + convex->vertices[3] = REAL3(0, 1, 1); + convex->vertices[4] = REAL3(1, 0, 0); + convex->vertices[5] = REAL3(1, 0, 1); + convex->vertices[6] = REAL3(1, 1, 0); + convex->vertices[7] = REAL3(1, 1, 1); - convex->facets[0] = Plane(REAL3(-1,0,0),0); - convex->facets[1] = Plane(REAL3(1,0,0),-1); - convex->facets[2] = Plane(REAL3(0,-1,0),0); - convex->facets[3] = Plane(REAL3(0,1,0),-1); - convex->facets[4] = Plane(REAL3(0,0,-1),0); - convex->facets[5] = Plane(REAL3(0,0,1),-1); + convex->facets[0] = Plane(REAL3(-1, 0, 0), 0); + convex->facets[1] = Plane(REAL3(1, 0, 0), -1); + convex->facets[2] = Plane(REAL3(0, -1, 0), 0); + convex->facets[3] = Plane(REAL3(0, 1, 0), -1); + convex->facets[4] = Plane(REAL3(0, 0, -1), 0); + convex->facets[5] = Plane(REAL3(0, 0, 1), -1); - convex->edges[0 ] = HalfEdge(11,0,0); - convex->edges[1 ] = HalfEdge(23,1,0); - convex->edges[2 ] = HalfEdge(15,3,0); - convex->edges[3 ] = HalfEdge(16,2,0); + convex->edges[0] = HalfEdge(11, 0, 0); + convex->edges[1] = HalfEdge(23, 1, 0); + convex->edges[2] = HalfEdge(15, 3, 0); + convex->edges[3] = HalfEdge(16, 2, 0); - convex->edges[4 ] = HalfEdge(13,6,1); - convex->edges[5 ] = HalfEdge(21,7,1); - convex->edges[6 ] = HalfEdge( 9,5,1); - convex->edges[7 ] = HalfEdge(18,4,1); + convex->edges[4] = HalfEdge(13, 6, 1); + convex->edges[5] = HalfEdge(21, 7, 1); + convex->edges[6] = HalfEdge(9, 5, 1); + convex->edges[7] = HalfEdge(18, 4, 1); - convex->edges[8 ] = HalfEdge(19,0,2); - convex->edges[9 ] = HalfEdge( 6,4,2); - convex->edges[10] = HalfEdge(20,5,2); - convex->edges[11] = HalfEdge( 0,1,2); + convex->edges[8] = HalfEdge(19, 0, 2); + convex->edges[9] = HalfEdge(6, 4, 2); + convex->edges[10] = HalfEdge(20, 5, 2); + convex->edges[11] = HalfEdge(0, 1, 2); - convex->edges[12] = HalfEdge(22,3,3); - convex->edges[13] = HalfEdge( 4,7,3); - convex->edges[14] = HalfEdge(17,6,3); - convex->edges[15] = HalfEdge( 2,2,3); + convex->edges[12] = HalfEdge(22, 3, 3); + convex->edges[13] = HalfEdge(4, 7, 3); + convex->edges[14] = HalfEdge(17, 6, 3); + convex->edges[15] = HalfEdge(2, 2, 3); - convex->edges[16] = HalfEdge( 3,0,4); - convex->edges[17] = HalfEdge(14,2,4); - convex->edges[18] = HalfEdge( 7,6,4); - convex->edges[19] = HalfEdge( 8,4,4); - - convex->edges[20] = HalfEdge(10,1,5); - convex->edges[21] = HalfEdge( 5,5,5); - convex->edges[22] = HalfEdge(12,7,5); - convex->edges[23] = HalfEdge( 1,3,5); + convex->edges[16] = HalfEdge(3, 0, 4); + convex->edges[17] = HalfEdge(14, 2, 4); + convex->edges[18] = HalfEdge(7, 6, 4); + convex->edges[19] = HalfEdge(8, 4, 4); + + convex->edges[20] = HalfEdge(10, 1, 5); + convex->edges[21] = HalfEdge(5, 5, 5); + convex->edges[22] = HalfEdge(12, 7, 5); + convex->edges[23] = HalfEdge(1, 3, 5); - return convex; } -ConvexH *ConvexHMakeCube(const REAL3 &bmin, const REAL3 &bmax) { +ConvexH *ConvexHMakeCube(const REAL3 &bmin, const REAL3 &bmax) +{ ConvexH *convex = test_cube(); - convex->vertices[0] = REAL3(bmin.x,bmin.y,bmin.z); - convex->vertices[1] = REAL3(bmin.x,bmin.y,bmax.z); - convex->vertices[2] = REAL3(bmin.x,bmax.y,bmin.z); - convex->vertices[3] = REAL3(bmin.x,bmax.y,bmax.z); - convex->vertices[4] = REAL3(bmax.x,bmin.y,bmin.z); - convex->vertices[5] = REAL3(bmax.x,bmin.y,bmax.z); - convex->vertices[6] = REAL3(bmax.x,bmax.y,bmin.z); - convex->vertices[7] = REAL3(bmax.x,bmax.y,bmax.z); + convex->vertices[0] = REAL3(bmin.x, bmin.y, bmin.z); + convex->vertices[1] = REAL3(bmin.x, bmin.y, bmax.z); + convex->vertices[2] = REAL3(bmin.x, bmax.y, bmin.z); + convex->vertices[3] = REAL3(bmin.x, bmax.y, bmax.z); + convex->vertices[4] = REAL3(bmax.x, bmin.y, bmin.z); + convex->vertices[5] = REAL3(bmax.x, bmin.y, bmax.z); + convex->vertices[6] = REAL3(bmax.x, bmax.y, bmin.z); + convex->vertices[7] = REAL3(bmax.x, bmax.y, bmax.z); - convex->facets[0] = Plane(REAL3(-1,0,0), bmin.x); - convex->facets[1] = Plane(REAL3(1,0,0), -bmax.x); - convex->facets[2] = Plane(REAL3(0,-1,0), bmin.y); - convex->facets[3] = Plane(REAL3(0,1,0), -bmax.y); - convex->facets[4] = Plane(REAL3(0,0,-1), bmin.z); - convex->facets[5] = Plane(REAL3(0,0,1), -bmax.z); + convex->facets[0] = Plane(REAL3(-1, 0, 0), bmin.x); + convex->facets[1] = Plane(REAL3(1, 0, 0), -bmax.x); + convex->facets[2] = Plane(REAL3(0, -1, 0), bmin.y); + convex->facets[3] = Plane(REAL3(0, 1, 0), -bmax.y); + convex->facets[4] = Plane(REAL3(0, 0, -1), bmin.z); + convex->facets[5] = Plane(REAL3(0, 0, 1), -bmax.z); return convex; } -ConvexH *ConvexHCrop(ConvexH &convex,const Plane &slice) +ConvexH *ConvexHCrop(ConvexH &convex, const Plane &slice) { int i; - int vertcountunder=0; - int vertcountover =0; + int vertcountunder = 0; + int vertcountover = 0; Array vertscoplanar; // existing vertex members of convex that are coplanar - vertscoplanar.count=0; + vertscoplanar.count = 0; Array edgesplit; // existing edges that members of convex that cross the splitplane - edgesplit.count=0; + edgesplit.count = 0; - assert(convex.edges.count<480); + assert(convex.edges.count < 480); - EdgeFlag edgeflag[512]; - VertFlag vertflag[256]; + EdgeFlag edgeflag[512]; + VertFlag vertflag[256]; PlaneFlag planeflag[128]; - HalfEdge tmpunderedges[512]; - Plane tmpunderplanes[128]; + HalfEdge tmpunderedges[512]; + Plane tmpunderplanes[128]; Coplanar coplanaredges[512]; - int coplanaredges_num=0; + int coplanaredges_num = 0; Array createdverts; // do the side-of-plane tests - for(i=0;i= convex.edges.count || convex.edges[e1].p!=currentplane) { + do + { + if (e1 >= convex.edges.count || convex.edges[e1].p != currentplane) + { enextface = e1; - e1=estart; + e1 = estart; } HalfEdge &edge0 = convex.edges[e0]; HalfEdge &edge1 = convex.edges[e1]; HalfEdge &edgea = convex.edges[edge0.ea]; - planeside |= vertflag[edge0.v].planetest; //if((vertflag[edge0.v].planetest & vertflag[edge1.v].planetest) == COPLANAR) { // assert(ecop==-1); // ecop=e; //} - - if(vertflag[edge0.v].planetest == OVER && vertflag[edge1.v].planetest == OVER){ + if (vertflag[edge0.v].planetest == OVER && vertflag[edge1.v].planetest == OVER) + { // both endpoints over plane - edgeflag[e0].undermap = -1; + edgeflag[e0].undermap = -1; } - else if((vertflag[edge0.v].planetest | vertflag[edge1.v].planetest) == UNDER) { + else if ((vertflag[edge0.v].planetest | vertflag[edge1.v].planetest) == UNDER) + { // at least one endpoint under, the other coplanar or under - + edgeflag[e0].undermap = under_edge_count; tmpunderedges[under_edge_count].v = vertflag[edge0.v].undermap; tmpunderedges[under_edge_count].p = underplanescount; - if(edge0.ea < e0) { + if (edge0.ea < e0) + { // connect the neighbors - assert(edgeflag[edge0.ea].undermap !=-1); + assert(edgeflag[edge0.ea].undermap != -1); tmpunderedges[under_edge_count].ea = edgeflag[edge0.ea].undermap; tmpunderedges[edgeflag[edge0.ea].undermap].ea = under_edge_count; } under_edge_count++; } - else if((vertflag[edge0.v].planetest | vertflag[edge1.v].planetest) == COPLANAR) { - // both endpoints coplanar + else if ((vertflag[edge0.v].planetest | vertflag[edge1.v].planetest) == COPLANAR) + { + // both endpoints coplanar // must check a 3rd point to see if UNDER - int e2 = e1+1; - if(e2>=convex.edges.count || convex.edges[e2].p!=currentplane) { + int e2 = e1 + 1; + if (e2 >= convex.edges.count || convex.edges[e2].p != currentplane) + { e2 = estart; } - assert(convex.edges[e2].p==currentplane); + assert(convex.edges[e2].p == currentplane); HalfEdge &edge2 = convex.edges[e2]; - if(vertflag[edge2.v].planetest==UNDER) { - + if (vertflag[edge2.v].planetest == UNDER) + { edgeflag[e0].undermap = under_edge_count; tmpunderedges[under_edge_count].v = vertflag[edge0.v].undermap; tmpunderedges[under_edge_count].p = underplanescount; @@ -1954,36 +2046,40 @@ ConvexH *ConvexHCrop(ConvexH &convex,const Plane &slice) // make sure this edge is added to the "coplanar" list coplanaredge = under_edge_count; vout = vertflag[edge0.v].undermap; - vin = vertflag[edge1.v].undermap; + vin = vertflag[edge1.v].undermap; under_edge_count++; } - else { + else + { edgeflag[e0].undermap = -1; } } - else if(vertflag[edge0.v].planetest == UNDER && vertflag[edge1.v].planetest == OVER) { - // first is under 2nd is over - + else if (vertflag[edge0.v].planetest == UNDER && vertflag[edge1.v].planetest == OVER) + { + // first is under 2nd is over + edgeflag[e0].undermap = under_edge_count; tmpunderedges[under_edge_count].v = vertflag[edge0.v].undermap; tmpunderedges[under_edge_count].p = underplanescount; - if(edge0.ea < e0) { - assert(edgeflag[edge0.ea].undermap !=-1); + if (edge0.ea < e0) + { + assert(edgeflag[edge0.ea].undermap != -1); // connect the neighbors tmpunderedges[under_edge_count].ea = edgeflag[edge0.ea].undermap; tmpunderedges[edgeflag[edge0.ea].undermap].ea = under_edge_count; vout = tmpunderedges[edgeflag[edge0.ea].undermap].v; } - else { + else + { Plane &p0 = convex.facets[edge0.p]; Plane &pa = convex.facets[edgea.p]; - createdverts.Add(ThreePlaneIntersection(p0,pa,slice)); + createdverts.Add(ThreePlaneIntersection(p0, pa, slice)); //createdverts.Add(PlaneProject(slice,PlaneLineIntersection(slice,convex.vertices[edge0.v],convex.vertices[edgea.v]))); //createdverts.Add(PlaneLineIntersection(slice,convex.vertices[edge0.v],convex.vertices[edgea.v])); vout = vertcountunder++; } under_edge_count++; - /// hmmm something to think about: i might be able to output this edge regarless of + /// hmmm something to think about: i might be able to output this edge regarless of // wheter or not we know v-in yet. ok i;ll try this now: tmpunderedges[under_edge_count].v = vout; tmpunderedges[under_edge_count].p = underplanescount; @@ -1991,56 +2087,62 @@ ConvexH *ConvexHCrop(ConvexH &convex,const Plane &slice) coplanaredge = under_edge_count; under_edge_count++; - if(vin!=-1) { + if (vin != -1) + { // we previously processed an edge where we came under // now we know about vout as well // ADD THIS EDGE TO THE LIST OF EDGES THAT NEED NEIGHBOR ON PARTITION PLANE!! } - } - else if(vertflag[edge0.v].planetest == COPLANAR && vertflag[edge1.v].planetest == OVER) { - // first is coplanar 2nd is over - + else if (vertflag[edge0.v].planetest == COPLANAR && vertflag[edge1.v].planetest == OVER) + { + // first is coplanar 2nd is over + edgeflag[e0].undermap = -1; vout = vertflag[edge0.v].undermap; // I hate this but i have to make sure part of this face is UNDER before ouputting this vert - int k=estart; + int k = estart; assert(edge0.p == currentplane); - while(!(planeside&UNDER) && k= vertcountunderold); // for debugging only + assert(vin >= vertcountunderold); // for debugging only } - if(vout!=-1) { + if (vout != -1) + { // we previously processed an edge where we went over // now we know vin too // ADD THIS EDGE TO THE LIST OF EDGES THAT NEED NEIGHBOR ON PARTITION PLANE!! @@ -2049,8 +2151,9 @@ ConvexH *ConvexHCrop(ConvexH &convex,const Plane &slice) tmpunderedges[under_edge_count].v = vin; tmpunderedges[under_edge_count].p = underplanescount; edgeflag[e0].undermap = under_edge_count; - if(e0>edge0.ea) { - assert(edgeflag[edge0.ea].undermap !=-1); + if (e0 > edge0.ea) + { + assert(edgeflag[edge0.ea].undermap != -1); // connect the neighbors tmpunderedges[under_edge_count].ea = edgeflag[edge0.ea].undermap; tmpunderedges[edgeflag[edge0.ea].undermap].ea = under_edge_count; @@ -2058,41 +2161,45 @@ ConvexH *ConvexHCrop(ConvexH &convex,const Plane &slice) assert(edgeflag[e0].undermap == under_edge_count); under_edge_count++; } - else if(vertflag[edge0.v].planetest == OVER && vertflag[edge1.v].planetest == COPLANAR) { - // first is over next is coplanar - + else if (vertflag[edge0.v].planetest == OVER && vertflag[edge1.v].planetest == COPLANAR) + { + // first is over next is coplanar + edgeflag[e0].undermap = -1; vin = vertflag[edge1.v].undermap; - assert(vin!=-1); - if(vout!=-1) { + assert(vin != -1); + if (vout != -1) + { // we previously processed an edge where we came under // now we know both endpoints // ADD THIS EDGE TO THE LIST OF EDGES THAT NEED NEIGHBOR ON PARTITION PLANE!! } - } - else { + else + { assert(0); } - - e0=e1; - e1++; // do the modulo at the beginning of the loop + e0 = e1; + e1++; // do the modulo at the beginning of the loop - } while(e0!=estart) ; + } while (e0 != estart); e0 = enextface; - if(planeside&UNDER) { + if (planeside & UNDER) + { planeflag[currentplane].undermap = underplanescount; tmpunderplanes[underplanescount] = convex.facets[currentplane]; underplanescount++; } - else { + else + { planeflag[currentplane].undermap = 0; } - if(vout>=0 && (planeside&UNDER)) { - assert(vin>=0); - assert(coplanaredge>=0); - assert(coplanaredge!=511); + if (vout >= 0 && (planeside & UNDER)) + { + assert(vin >= 0); + assert(coplanaredge >= 0); + assert(coplanaredge != 511); coplanaredges[coplanaredges_num].ea = coplanaredge; coplanaredges[coplanaredges_num].v0 = vin; coplanaredges[coplanaredges_num].v1 = vout; @@ -2101,232 +2208,234 @@ ConvexH *ConvexHCrop(ConvexH &convex,const Plane &slice) } // add the new plane to the mix: - if(coplanaredges_num>0) { - tmpunderplanes[underplanescount++]=slice; + if (coplanaredges_num > 0) + { + tmpunderplanes[underplanescount++] = slice; } - for(i=0;i=coplanaredges_num) + if (j >= coplanaredges_num) { - assert(jvertices.count;j++) + REAL d = 0; + for (int j = 0; j < convex->vertices.count; j++) { - d = Max(d,dot(convex->vertices[j],planes[i].normal)+planes[i].dist); + d = Max(d, dot(convex->vertices[j], planes[i].normal) + planes[i].dist); } - if(i==0 || d>md) + if (i == 0 || d > md) { - p=i; - md=d; + p = i; + md = d; } } - return (md>epsilon)?p:-1; + return (md > epsilon) ? p : -1; } -template -inline int maxdir(const T *p,int count,const T &dir) +template +inline int maxdir(const T *p, int count, const T &dir) { assert(count); - int m=0; + int m = 0; float currDotm = dot(p[0], dir); - for(int i=1;i currDotm) + const float currDoti = dot(p[i], dir); + if (currDoti > currDotm) { currDotm = currDoti; - m=i; + m = i; } } return m; } - -template -int maxdirfiltered(const T *p,int count,const T &dir,Array &allow) +template +int maxdirfiltered(const T *p, int count, const T &dir, Array &allow) { assert(count); - int m=-1; + int m = -1; float currDotm = dot(p[0], dir); - for(int i=0;icurrDotm) + if (currDoti > currDotm) { currDotm = currDoti; - m=i; + m = i; } } } } - assert(m!=-1); + assert(m != -1); return m; -} +} float3 orth(const float3 &v) { - float3 a=cross(v,float3(0,0,1)); - float3 b=cross(v,float3(0,1,0)); - return normalize((magnitude(a)>magnitude(b))?a:b); + float3 a = cross(v, float3(0, 0, 1)); + float3 b = cross(v, float3(0, 1, 0)); + return normalize((magnitude(a) > magnitude(b)) ? a : b); } - -template -int maxdirsterid(const T *p,int count,const T &dir,Array &allow) +template +int maxdirsterid(const T *p, int count, const T &dir, Array &allow) { - int m=-1; - while(m==-1) + int m = -1; + while (m == -1) { - m = maxdirfiltered(p,count,dir,allow); - if(allow[m]==3) return m; + m = maxdirfiltered(p, count, dir, allow); + if (allow[m] == 3) return m; T u = orth(dir); - T v = cross(u,dir); - int ma=-1; - for(float x = 0.0f ; x<= 360.0f ; x+= 45.0f) + T v = cross(u, dir); + int ma = -1; + for (float x = 0.0f; x <= 360.0f; x += 45.0f) { - float s = sinf(DEG2RAD*(x)); - float c = cosf(DEG2RAD*(x)); - int mb = maxdirfiltered(p,count,dir+(u*s+v*c)*0.025f,allow); - if(ma==m && mb==m) + float s = sinf(DEG2RAD * (x)); + float c = cosf(DEG2RAD * (x)); + int mb = maxdirfiltered(p, count, dir + (u * s + v * c) * 0.025f, allow); + if (ma == m && mb == m) { - allow[m]=3; + allow[m] = 3; return m; } - if(ma!=-1 && ma!=mb) // Yuck - this is really ugly + if (ma != -1 && ma != mb) // Yuck - this is really ugly { int mc = ma; - for(float xx = x-40.0f ; xx <= x ; xx+= 5.0f) + for (float xx = x - 40.0f; xx <= x; xx += 5.0f) { - float s = sinf(DEG2RAD*(xx)); - float c = cosf(DEG2RAD*(xx)); - int md = maxdirfiltered(p,count,dir+(u*s+v*c)*0.025f,allow); - if(mc==m && md==m) + float s = sinf(DEG2RAD * (xx)); + float c = cosf(DEG2RAD * (xx)); + int md = maxdirfiltered(p, count, dir + (u * s + v * c) * 0.025f, allow); + if (mc == m && md == m) { - allow[m]=3; + allow[m] = 3; return m; } - mc=md; + mc = md; } } - ma=mb; + ma = mb; } - allow[m]=0; - m=-1; + allow[m] = 0; + m = -1; } assert(0); return m; -} +} - - - -int operator ==(const int3 &a,const int3 &b) +int operator==(const int3 &a, const int3 &b) { - for(int i=0;i<3;i++) + for (int i = 0; i < 3; i++) { - if(a[i]!=b[i]) return 0; + if (a[i] != b[i]) return 0; } return 1; } -int3 roll3(int3 a) +int3 roll3(int3 a) { - int tmp=a[0]; - a[0]=a[1]; - a[1]=a[2]; - a[2]=tmp; + int tmp = a[0]; + a[0] = a[1]; + a[1] = a[2]; + a[2] = tmp; return a; } -int isa(const int3 &a,const int3 &b) +int isa(const int3 &a, const int3 &b) { - return ( a==b || roll3(a)==b || a==roll3(b) ); + return (a == b || roll3(a) == b || a == roll3(b)); } -int b2b(const int3 &a,const int3 &b) +int b2b(const int3 &a, const int3 &b) { - return isa(a,int3(b[2],b[1],b[0])); + return isa(a, int3(b[2], b[1], b[0])); } -int above(float3* vertices,const int3& t, const float3 &p, float epsilon) +int above(float3 *vertices, const int3 &t, const float3 &p, float epsilon) { - float3 n=TriNormal(vertices[t[0]],vertices[t[1]],vertices[t[2]]); - return (dot(n,p-vertices[t[0]]) > epsilon); // EPSILON??? + float3 n = TriNormal(vertices[t[0]], vertices[t[1]], vertices[t[2]]); + return (dot(n, p - vertices[t[0]]) > epsilon); // EPSILON??? } -int hasedge(const int3 &t, int a,int b) +int hasedge(const int3 &t, int a, int b) { - for(int i=0;i<3;i++) + for (int i = 0; i < 3; i++) { - int i1= (i+1)%3; - if(t[i]==a && t[i1]==b) return 1; + int i1 = (i + 1) % 3; + if (t[i] == a && t[i1] == b) return 1; } return 0; } int hasvert(const int3 &t, int v) { - return (t[0]==v || t[1]==v || t[2]==v) ; + return (t[0] == v || t[1] == v || t[2] == v); } -int shareedge(const int3 &a,const int3 &b) +int shareedge(const int3 &a, const int3 &b) { int i; - for(i=0;i<3;i++) + for (i = 0; i < 3; i++) { - int i1= (i+1)%3; - if(hasedge(a,b[i1],b[i])) return 1; + int i1 = (i + 1) % 3; + if (hasedge(a, b[i1], b[i])) return 1; } return 0; } @@ -2342,442 +2451,467 @@ public: int id; int vmax; float rise; - Array* tris; - btHullTriangle(int a,int b,int c, Array* pTris):int3(a,b,c),n(-1,-1,-1) + Array *tris; + btHullTriangle(int a, int b, int c, Array *pTris) : int3(a, b, c), n(-1, -1, -1) { tris = pTris; id = tris->count; tris->Add(this); - vmax=-1; + vmax = -1; rise = 0.0f; } ~btHullTriangle() { - assert((*tris)[id]==this); - (*tris)[id]=NULL; + assert((*tris)[id] == this); + (*tris)[id] = NULL; } - int &neib(int a,int b); + int &neib(int a, int b); }; - -int &btHullTriangle::neib(int a,int b) +int &btHullTriangle::neib(int a, int b) { - static int er=-1; + static int er = -1; int i; - for(i=0;i<3;i++) + for (i = 0; i < 3; i++) { - int i1=(i+1)%3; - int i2=(i+2)%3; - if((*this)[i]==a && (*this)[i1]==b) return n[i2]; - if((*this)[i]==b && (*this)[i1]==a) return n[i2]; + int i1 = (i + 1) % 3; + int i2 = (i + 2) % 3; + if ((*this)[i] == a && (*this)[i1] == b) return n[i2]; + if ((*this)[i] == b && (*this)[i1] == a) return n[i2]; } assert(0); return er; } -void b2bfix(btHullTriangle* s,btHullTriangle*t, Array& tris) +void b2bfix(btHullTriangle *s, btHullTriangle *t, Array &tris) { int i; - for(i=0;i<3;i++) + for (i = 0; i < 3; i++) { - int i1=(i+1)%3; - int i2=(i+2)%3; + int i1 = (i + 1) % 3; + int i2 = (i + 2) % 3; int a = (*s)[i1]; int b = (*s)[i2]; - assert(tris[s->neib(a,b)]->neib(b,a) == s->id); - assert(tris[t->neib(a,b)]->neib(b,a) == t->id); - tris[s->neib(a,b)]->neib(b,a) = t->neib(b,a); - tris[t->neib(b,a)]->neib(a,b) = s->neib(a,b); + assert(tris[s->neib(a, b)]->neib(b, a) == s->id); + assert(tris[t->neib(a, b)]->neib(b, a) == t->id); + tris[s->neib(a, b)]->neib(b, a) = t->neib(b, a); + tris[t->neib(b, a)]->neib(a, b) = s->neib(a, b); } } -void removeb2b(btHullTriangle* s,btHullTriangle*t, Array& tris) +void removeb2b(btHullTriangle *s, btHullTriangle *t, Array &tris) { - b2bfix(s,t, tris); + b2bfix(s, t, tris); delete s; delete t; } -void checkit(btHullTriangle *t, Array& tris) +void checkit(btHullTriangle *t, Array &tris) { int i; - assert(tris[t->id]==t); - for(i=0;i<3;i++) + assert(tris[t->id] == t); + for (i = 0; i < 3; i++) { - int i1=(i+1)%3; - int i2=(i+2)%3; + int i1 = (i + 1) % 3; + int i2 = (i + 2) % 3; int a = (*t)[i1]; int b = (*t)[i2]; - assert(a!=b); - assert( tris[t->n[i]]->neib(b,a) == t->id); + assert(a != b); + assert(tris[t->n[i]]->neib(b, a) == t->id); } } -void extrude(btHullTriangle *t0,int v, Array& tris) +void extrude(btHullTriangle *t0, int v, Array &tris) { - int3 t= *t0; + int3 t = *t0; int n = tris.count; - btHullTriangle* ta = new btHullTriangle(v,t[1],t[2], &tris); - ta->n = int3(t0->n[0],n+1,n+2); - tris[t0->n[0]]->neib(t[1],t[2]) = n+0; - btHullTriangle* tb = new btHullTriangle(v,t[2],t[0], &tris); - tb->n = int3(t0->n[1],n+2,n+0); - tris[t0->n[1]]->neib(t[2],t[0]) = n+1; - btHullTriangle* tc = new btHullTriangle(v,t[0],t[1], &tris); - tc->n = int3(t0->n[2],n+0,n+1); - tris[t0->n[2]]->neib(t[0],t[1]) = n+2; + btHullTriangle *ta = new btHullTriangle(v, t[1], t[2], &tris); + ta->n = int3(t0->n[0], n + 1, n + 2); + tris[t0->n[0]]->neib(t[1], t[2]) = n + 0; + btHullTriangle *tb = new btHullTriangle(v, t[2], t[0], &tris); + tb->n = int3(t0->n[1], n + 2, n + 0); + tris[t0->n[1]]->neib(t[2], t[0]) = n + 1; + btHullTriangle *tc = new btHullTriangle(v, t[0], t[1], &tris); + tc->n = int3(t0->n[2], n + 0, n + 1); + tris[t0->n[2]]->neib(t[0], t[1]) = n + 2; checkit(ta, tris); checkit(tb, tris); checkit(tc, tris); - if(hasvert(*tris[ta->n[0]],v)) removeb2b(ta,tris[ta->n[0]], tris); - if(hasvert(*tris[tb->n[0]],v)) removeb2b(tb,tris[tb->n[0]], tris); - if(hasvert(*tris[tc->n[0]],v)) removeb2b(tc,tris[tc->n[0]], tris); + if (hasvert(*tris[ta->n[0]], v)) removeb2b(ta, tris[ta->n[0]], tris); + if (hasvert(*tris[tb->n[0]], v)) removeb2b(tb, tris[tb->n[0]], tris); + if (hasvert(*tris[tc->n[0]], v)) removeb2b(tc, tris[tc->n[0]], tris); delete t0; - } -btHullTriangle *extrudable(float epsilon, Array& tris) +btHullTriangle *extrudable(float epsilon, Array &tris) { int i; - btHullTriangle *t=NULL; - for(i=0;iriserise)) + if (!t || (tris[i] && t->rise < tris[i]->rise)) { t = tris[i]; } } - return (t->rise >epsilon)?t:NULL ; + return (t->rise > epsilon) ? t : NULL; } class int4 { public: - int x,y,z,w; + int x, y, z, w; int4(){}; - int4(int _x,int _y, int _z,int _w){x=_x;y=_y;z=_z;w=_w;} - const int& operator[](int i) const {return (&x)[i];} - int& operator[](int i) {return (&x)[i];} + int4(int _x, int _y, int _z, int _w) + { + x = _x; + y = _y; + z = _z; + w = _w; + } + const int &operator[](int i) const { return (&x)[i]; } + int &operator[](int i) { return (&x)[i]; } }; - - -int4 FindSimplex(float3 *verts,int verts_count,Array &allow) +int4 FindSimplex(float3 *verts, int verts_count, Array &allow) { float3 basis[3]; - basis[0] = float3( 0.01f, 0.02f, 1.0f ); - int p0 = maxdirsterid(verts,verts_count, basis[0],allow); - int p1 = maxdirsterid(verts,verts_count,-basis[0],allow); - basis[0] = verts[p0]-verts[p1]; - if(p0==p1 || basis[0]==float3(0,0,0)) - return int4(-1,-1,-1,-1); - basis[1] = cross(float3( 1, 0.02f, 0),basis[0]); - basis[2] = cross(float3(-0.02f, 1, 0),basis[0]); - basis[1] = normalize( (magnitude(basis[1])>magnitude(basis[2])) ? basis[1]:basis[2]); - int p2 = maxdirsterid(verts,verts_count,basis[1],allow); - if(p2 == p0 || p2 == p1) + basis[0] = float3(0.01f, 0.02f, 1.0f); + int p0 = maxdirsterid(verts, verts_count, basis[0], allow); + int p1 = maxdirsterid(verts, verts_count, -basis[0], allow); + basis[0] = verts[p0] - verts[p1]; + if (p0 == p1 || basis[0] == float3(0, 0, 0)) + return int4(-1, -1, -1, -1); + basis[1] = cross(float3(1, 0.02f, 0), basis[0]); + basis[2] = cross(float3(-0.02f, 1, 0), basis[0]); + basis[1] = normalize((magnitude(basis[1]) > magnitude(basis[2])) ? basis[1] : basis[2]); + int p2 = maxdirsterid(verts, verts_count, basis[1], allow); + if (p2 == p0 || p2 == p1) { - p2 = maxdirsterid(verts,verts_count,-basis[1],allow); + p2 = maxdirsterid(verts, verts_count, -basis[1], allow); } - if(p2 == p0 || p2 == p1) - return int4(-1,-1,-1,-1); + if (p2 == p0 || p2 == p1) + return int4(-1, -1, -1, -1); basis[1] = verts[p2] - verts[p0]; - basis[2] = normalize(cross(basis[1],basis[0])); - int p3 = maxdirsterid(verts,verts_count,basis[2],allow); - if(p3==p0||p3==p1||p3==p2) p3 = maxdirsterid(verts,verts_count,-basis[2],allow); - if(p3==p0||p3==p1||p3==p2) - return int4(-1,-1,-1,-1); - assert(!(p0==p1||p0==p2||p0==p3||p1==p2||p1==p3||p2==p3)); - if(dot(verts[p3]-verts[p0],cross(verts[p1]-verts[p0],verts[p2]-verts[p0])) <0) {Swap(p2,p3);} - return int4(p0,p1,p2,p3); + basis[2] = normalize(cross(basis[1], basis[0])); + int p3 = maxdirsterid(verts, verts_count, basis[2], allow); + if (p3 == p0 || p3 == p1 || p3 == p2) p3 = maxdirsterid(verts, verts_count, -basis[2], allow); + if (p3 == p0 || p3 == p1 || p3 == p2) + return int4(-1, -1, -1, -1); + assert(!(p0 == p1 || p0 == p2 || p0 == p3 || p1 == p2 || p1 == p3 || p2 == p3)); + if (dot(verts[p3] - verts[p0], cross(verts[p1] - verts[p0], verts[p2] - verts[p0])) < 0) + { + Swap(p2, p3); + } + return int4(p0, p1, p2, p3); } -int calchullgen(float3 *verts,int verts_count, int vlimit,Array& tris) +int calchullgen(float3 *verts, int verts_count, int vlimit, Array &tris) { - if(verts_count <4) return 0; - if(vlimit==0) vlimit=1000000000; + if (verts_count < 4) return 0; + if (vlimit == 0) vlimit = 1000000000; int j; - float3 bmin(*verts),bmax(*verts); + float3 bmin(*verts), bmax(*verts); Array isextreme(verts_count); Array allow(verts_count); - for(j=0;jn = int3(2, 3, 1); + btHullTriangle *t1 = new btHullTriangle(p[3], p[2], p[0], &tris); + t1->n = int3(3, 2, 0); + btHullTriangle *t2 = new btHullTriangle(p[0], p[1], p[3], &tris); + t2->n = int3(0, 1, 3); + btHullTriangle *t3 = new btHullTriangle(p[1], p[0], p[2], &tris); + t3->n = int3(1, 0, 2); + isextreme[p[0]] = isextreme[p[1]] = isextreme[p[2]] = isextreme[p[3]] = 1; + checkit(t0, tris); + checkit(t1, tris); + checkit(t2, tris); + checkit(t3, tris); - - - float3 center = (verts[p[0]]+verts[p[1]]+verts[p[2]]+verts[p[3]]) /4.0f; // a valid interior point - btHullTriangle *t0 = new btHullTriangle(p[2],p[3],p[1], &tris); t0->n=int3(2,3,1); - btHullTriangle *t1 = new btHullTriangle(p[3],p[2],p[0], &tris); t1->n=int3(3,2,0); - btHullTriangle *t2 = new btHullTriangle(p[0],p[1],p[3], &tris); t2->n=int3(0,1,3); - btHullTriangle *t3 = new btHullTriangle(p[1],p[0],p[2], &tris); t3->n=int3(1,0,2); - isextreme[p[0]]=isextreme[p[1]]=isextreme[p[2]]=isextreme[p[3]]=1; - checkit(t0, tris);checkit(t1, tris);checkit(t2, tris);checkit(t3, tris); - - for(j=0;jvmax<0); - float3 n=TriNormal(verts[(*t)[0]],verts[(*t)[1]],verts[(*t)[2]]); - t->vmax = maxdirsterid(verts,verts_count,n,allow); - t->rise = dot(n,verts[t->vmax]-verts[(*t)[0]]); + assert(t->vmax < 0); + float3 n = TriNormal(verts[(*t)[0]], verts[(*t)[1]], verts[(*t)[2]]); + t->vmax = maxdirsterid(verts, verts_count, n, allow); + t->rise = dot(n, verts[t->vmax] - verts[(*t)[0]]); } btHullTriangle *te; - vlimit-=4; - while(vlimit >0 && (te=extrudable(epsilon, tris))) + vlimit -= 4; + while (vlimit > 0 && (te = extrudable(epsilon, tris))) { - // int3 ti=*te; - int v=te->vmax; + // int3 ti=*te; + int v = te->vmax; assert(!isextreme[v]); // wtf we've already done this vertex - isextreme[v]=1; + isextreme[v] = 1; //if(v==p0 || v==p1 || v==p2 || v==p3) continue; // done these already - j=tris.count; - while(j--) { - if(!tris[j]) continue; - int3 t=*tris[j]; - if(above(verts,t,verts[v],0.01f*epsilon)) + j = tris.count; + while (j--) + { + if (!tris[j]) continue; + int3 t = *tris[j]; + if (above(verts, t, verts[v], 0.01f * epsilon)) { - extrude(tris[j],v, tris); + extrude(tris[j], v, tris); } } // now check for those degenerate cases where we have a flipped triangle or a really skinny triangle - j=tris.count; - while(j--) + j = tris.count; + while (j--) { - if(!tris[j]) continue; - if(!hasvert(*tris[j],v)) break; - int3 nt=*tris[j]; - if(above(verts,nt,center,0.01f*epsilon) || magnitude(cross(verts[nt[1]]-verts[nt[0]],verts[nt[2]]-verts[nt[1]]))< epsilon*epsilon*0.1f ) + if (!tris[j]) continue; + if (!hasvert(*tris[j], v)) break; + int3 nt = *tris[j]; + if (above(verts, nt, center, 0.01f * epsilon) || magnitude(cross(verts[nt[1]] - verts[nt[0]], verts[nt[2]] - verts[nt[1]])) < epsilon * epsilon * 0.1f) { btHullTriangle *nb = tris[tris[j]->n[0]]; - assert(nb);assert(!hasvert(*nb,v));assert(nb->idid < j); + extrude(nb, v, tris); + j = tris.count; } - } - j=tris.count; - while(j--) + } + j = tris.count; + while (j--) { - btHullTriangle *t=tris[j]; - if(!t) continue; - if(t->vmax>=0) break; - float3 n=TriNormal(verts[(*t)[0]],verts[(*t)[1]],verts[(*t)[2]]); - t->vmax = maxdirsterid(verts,verts_count,n,allow); - if(isextreme[t->vmax]) + btHullTriangle *t = tris[j]; + if (!t) continue; + if (t->vmax >= 0) break; + float3 n = TriNormal(verts[(*t)[0]], verts[(*t)[1]], verts[(*t)[2]]); + t->vmax = maxdirsterid(verts, verts_count, n, allow); + if (isextreme[t->vmax]) { - t->vmax=-1; // already done that vertex - algorithm needs to be able to terminate. + t->vmax = -1; // already done that vertex - algorithm needs to be able to terminate. } else { - t->rise = dot(n,verts[t->vmax]-verts[(*t)[0]]); + t->rise = dot(n, verts[t->vmax] - verts[(*t)[0]]); } } - vlimit --; + vlimit--; } return 1; } -int calchull(float3 *verts,int verts_count, int *&tris_out, int &tris_count,int vlimit, Array& tris) +int calchull(float3 *verts, int verts_count, int *&tris_out, int &tris_count, int vlimit, Array &tris) { - int rc=calchullgen(verts,verts_count, vlimit, tris) ; - if(!rc) return 0; + int rc = calchullgen(verts, verts_count, vlimit, tris); + if (!rc) return 0; Array ts; - for(int i=0;i &planes,float bevangle, Array& tris) -{ - int i,j; - planes.count=0; - int rc = calchullgen(verts,verts_count,vlimit, tris); - if(!rc) return 0; - for(i=0;in[j]id) continue; - btHullTriangle *s = tris[t->n[j]]; - REAL3 snormal = TriNormal(verts[(*s)[0]],verts[(*s)[1]],verts[(*s)[2]]); - if(dot(snormal,p.normal)>=cos(bevangle*DEG2RAD)) continue; - REAL3 n = normalize(snormal+p.normal); - planes.Add(Plane(n,-dot(n,verts[maxdir(verts,verts_count,n)]))); + for (int j = 0; j < 3; j++) ts.Add((*tris[i])[j]); + delete tris[i]; } - } - - for(i=0;i &planes, float bevangle, Array &tris) { - int i,j; - if(verts_count <4) return 0; - maxplanes = Min(maxplanes,planes_count); - float3 bmin(verts[0]),bmax(verts[0]); - for(i=0;in[j] < t->id) continue; + btHullTriangle *s = tris[t->n[j]]; + REAL3 snormal = TriNormal(verts[(*s)[0]], verts[(*s)[1]], verts[(*s)[2]]); + if (dot(snormal, p.normal) >= cos(bevangle * DEG2RAD)) continue; + REAL3 n = normalize(snormal + p.normal); + planes.Add(Plane(n, -dot(n, verts[maxdir(verts, verts_count, n)]))); + } + } + + for (i = 0; i < tris.count; i++) + if (tris[i]) + { + delete tris[i]; // delete tris[i]; + } + tris.count = 0; + return 1; +} + +int overhull(Plane *planes, int planes_count, float3 *verts, int verts_count, int maxplanes, + float3 *&verts_out, int &verts_count_out, int *&faces_out, int &faces_count_out, float inflate) +{ + int i, j; + if (verts_count < 4) return 0; + maxplanes = Min(maxplanes, planes_count); + float3 bmin(verts[0]), bmax(verts[0]); + for (i = 0; i < verts_count; i++) { - bmin = VectorMin(bmin,verts[i]); - bmax = VectorMax(bmax,verts[i]); + bmin = VectorMin(bmin, verts[i]); + bmax = VectorMax(bmax, verts[i]); } -// float diameter = magnitude(bmax-bmin); -// inflate *=diameter; // RELATIVE INFLATION - bmin -= float3(inflate,inflate,inflate); - bmax += float3(inflate,inflate,inflate); - for(i=0;i=0) + while (maxplanes-- && (k = candidateplane(planes, planes_count, c, epsilon)) >= 0) { ConvexH *tmp = c; - c = ConvexHCrop(*tmp,planes[k]); - if(c==NULL) {c=tmp; break;} // might want to debug this case better!!! - if(!AssertIntact(*c)) {c=tmp; break;} // might want to debug this case better too!!! + c = ConvexHCrop(*tmp, planes[k]); + if (c == NULL) + { + c = tmp; + break; + } // might want to debug this case better!!! + if (!AssertIntact(*c)) + { + c = tmp; + break; + } // might want to debug this case better too!!! delete tmp; } assert(AssertIntact(*c)); //return c; - faces_out = (int*)malloc(sizeof(int)*(1+c->facets.count+c->edges.count)); // new int[1+c->facets.count+c->edges.count]; - faces_count_out=0; - i=0; - faces_out[faces_count_out++]=-1; - k=0; - while(iedges.count) + faces_out = (int *)malloc(sizeof(int) * (1 + c->facets.count + c->edges.count)); // new int[1+c->facets.count+c->edges.count]; + faces_count_out = 0; + i = 0; + faces_out[faces_count_out++] = -1; + k = 0; + while (i < c->edges.count) { - j=1; - while(j+iedges.count && c->edges[i].p==c->edges[i+j].p) { j++; } - faces_out[faces_count_out++]=j; - while(j--) + j = 1; + while (j + i < c->edges.count && c->edges[i].p == c->edges[i + j].p) + { + j++; + } + faces_out[faces_count_out++] = j; + while (j--) { faces_out[faces_count_out++] = c->edges[i].v; i++; } k++; } - faces_out[0]=k; // number of faces. - assert(k==c->facets.count); - assert(faces_count_out == 1+c->facets.count+c->edges.count); - verts_out = c->vertices.element; // new float3[c->vertices.count]; + faces_out[0] = k; // number of faces. + assert(k == c->facets.count); + assert(faces_count_out == 1 + c->facets.count + c->edges.count); + verts_out = c->vertices.element; // new float3[c->vertices.count]; verts_count_out = c->vertices.count; - for(i=0;ivertices.count;i++) + for (i = 0; i < c->vertices.count; i++) { verts_out[i] = float3(c->vertices[i]); } - c->vertices.count=c->vertices.array_size=0; c->vertices.element=NULL; + c->vertices.count = c->vertices.array_size = 0; + c->vertices.element = NULL; delete c; return 1; } -int overhullv(float3 *verts, int verts_count,int maxplanes, - float3 *&verts_out, int &verts_count_out, int *&faces_out, int &faces_count_out ,float inflate,float bevangle,int vlimit, Array& tris) +int overhullv(float3 *verts, int verts_count, int maxplanes, + float3 *&verts_out, int &verts_count_out, int *&faces_out, int &faces_count_out, float inflate, float bevangle, int vlimit, Array &tris) { - if(!verts_count) return 0; - extern int calchullpbev(float3 *verts,int verts_count,int vlimit, Array &planes,float bevangle, Array& tris) ; + if (!verts_count) return 0; + extern int calchullpbev(float3 * verts, int verts_count, int vlimit, Array &planes, float bevangle, Array &tris); Array planes; - int rc=calchullpbev(verts,verts_count,vlimit,planes,bevangle, tris) ; - if(!rc) return 0; - return overhull(planes.element,planes.count,verts,verts_count,maxplanes,verts_out,verts_count_out,faces_out,faces_count_out,inflate); + int rc = calchullpbev(verts, verts_count, vlimit, planes, bevangle, tris); + if (!rc) return 0; + return overhull(planes.element, planes.count, verts, verts_count, maxplanes, verts_out, verts_count_out, faces_out, faces_count_out, inflate); } - -bool ComputeHull(unsigned int vcount,const float *vertices,PHullResult &result,unsigned int vlimit,float inflate, Array& arrtris) +bool ComputeHull(unsigned int vcount, const float *vertices, PHullResult &result, unsigned int vlimit, float inflate, Array &arrtris) { - int index_count; int *faces; float3 *verts_out; - int verts_count_out; + int verts_count_out; - if(inflate==0.0f) + if (inflate == 0.0f) { - int *tris_out; - int tris_count; - int ret = calchull( (float3 *) vertices, (int) vcount, tris_out, tris_count, vlimit, arrtris ); - if(!ret) return false; - result.mIndexCount = (unsigned int) (tris_count*3); - result.mFaceCount = (unsigned int) tris_count; - result.mVertices = (float*) vertices; - result.mVcount = (unsigned int) vcount; - result.mIndices = (unsigned int *) tris_out; + int *tris_out; + int tris_count; + int ret = calchull((float3 *)vertices, (int)vcount, tris_out, tris_count, vlimit, arrtris); + if (!ret) return false; + result.mIndexCount = (unsigned int)(tris_count * 3); + result.mFaceCount = (unsigned int)tris_count; + result.mVertices = (float *)vertices; + result.mVcount = (unsigned int)vcount; + result.mIndices = (unsigned int *)tris_out; return true; } - int ret = overhullv((float3*)vertices,vcount,35,verts_out,verts_count_out,faces,index_count,inflate,120.0f,vlimit, arrtris); - if(!ret) return false; + int ret = overhullv((float3 *)vertices, vcount, 35, verts_out, verts_count_out, faces, index_count, inflate, 120.0f, vlimit, arrtris); + if (!ret) return false; Array tris; - int n=faces[0]; - int k=1; - for(int i=0;i tris; - ok = ComputeHull(ovcount,vsource,hr,desc.mMaxVertices,skinwidth, tris); + Array tris; + ok = ComputeHull(ovcount, vsource, hr, desc.mMaxVertices, skinwidth, tris); - if ( ok ) + if (ok) { - // re-index triangle mesh so it refers to only used vertices, rebuild a new vertex table. - float *vscratch = (float *) malloc( sizeof(float)*hr.mVcount*3); - BringOutYourDead(hr.mVertices,hr.mVcount, vscratch, ovcount, hr.mIndices, hr.mIndexCount ); + float *vscratch = (float *)malloc(sizeof(float) * hr.mVcount * 3); + BringOutYourDead(hr.mVertices, hr.mVcount, vscratch, ovcount, hr.mIndices, hr.mIndexCount); ret = QE_OK; - if ( desc.HasHullFlag(QF_TRIANGLES) ) // if he wants the results as triangle! + if (desc.HasHullFlag(QF_TRIANGLES)) // if he wants the results as triangle! { - result.mPolygons = false; + result.mPolygons = false; result.mNumOutputVertices = ovcount; - result.mOutputVertices = (float *)malloc( sizeof(float)*ovcount*3); - result.mNumFaces = hr.mFaceCount; - result.mNumIndices = hr.mIndexCount; + result.mOutputVertices = (float *)malloc(sizeof(float) * ovcount * 3); + result.mNumFaces = hr.mFaceCount; + result.mNumIndices = hr.mIndexCount; - result.mIndices = (unsigned int *) malloc( sizeof(unsigned int)*hr.mIndexCount); + result.mIndices = (unsigned int *)malloc(sizeof(unsigned int) * hr.mIndexCount); - memcpy(result.mOutputVertices, vscratch, sizeof(float)*3*ovcount ); + memcpy(result.mOutputVertices, vscratch, sizeof(float) * 3 * ovcount); - if ( desc.HasHullFlag(QF_REVERSE_ORDER) ) + if (desc.HasHullFlag(QF_REVERSE_ORDER)) { - const unsigned int *source = hr.mIndices; - unsigned int *dest = result.mIndices; + unsigned int *dest = result.mIndices; - for (unsigned int i=0; i bmax[j] ) bmax[j] = p[j]; + if (p[j] < bmin[j]) bmin[j] = p[j]; + if (p[j] > bmax[j]) bmax[j] = p[j]; } } } @@ -3017,28 +3135,27 @@ bool HullLibrary::CleanupVertices(unsigned int svcount, float center[3]; - center[0] = dx*0.5f + bmin[0]; - center[1] = dy*0.5f + bmin[1]; - center[2] = dz*0.5f + bmin[2]; + center[0] = dx * 0.5f + bmin[0]; + center[1] = dy * 0.5f + bmin[1]; + center[2] = dz * 0.5f + bmin[2]; - if ( dx < EPSILON || dy < EPSILON || dz < EPSILON || svcount < 3 ) + if (dx < EPSILON || dy < EPSILON || dz < EPSILON || svcount < 3) { - float len = FLT_MAX; - if ( dx > EPSILON && dx < len ) len = dx; - if ( dy > EPSILON && dy < len ) len = dy; - if ( dz > EPSILON && dz < len ) len = dz; + if (dx > EPSILON && dx < len) len = dx; + if (dy > EPSILON && dy < len) len = dy; + if (dz > EPSILON && dz < len) len = dz; - if ( len == FLT_MAX ) + if (len == FLT_MAX) { - dx = dy = dz = 0.01f; // one centimeter + dx = dy = dz = 0.01f; // one centimeter } else { - if ( dx < EPSILON ) dx = len * 0.05f; // 1/5th the shortest non-zero edge. - if ( dy < EPSILON ) dy = len * 0.05f; - if ( dz < EPSILON ) dz = len * 0.05f; + if (dx < EPSILON) dx = len * 0.05f; // 1/5th the shortest non-zero edge. + if (dy < EPSILON) dy = len * 0.05f; + if (dz < EPSILON) dz = len * 0.05f; } float x1 = center[0] - dx; @@ -3050,22 +3167,20 @@ bool HullLibrary::CleanupVertices(unsigned int svcount, float z1 = center[2] - dz; float z2 = center[2] + dz; - addPoint(vcount,vertices,x1,y1,z1); - addPoint(vcount,vertices,x2,y1,z1); - addPoint(vcount,vertices,x2,y2,z1); - addPoint(vcount,vertices,x1,y2,z1); - addPoint(vcount,vertices,x1,y1,z2); - addPoint(vcount,vertices,x2,y1,z2); - addPoint(vcount,vertices,x2,y2,z2); - addPoint(vcount,vertices,x1,y2,z2); - - return true; // return cube - + addPoint(vcount, vertices, x1, y1, z1); + addPoint(vcount, vertices, x2, y1, z1); + addPoint(vcount, vertices, x2, y2, z1); + addPoint(vcount, vertices, x1, y2, z1); + addPoint(vcount, vertices, x1, y1, z2); + addPoint(vcount, vertices, x2, y1, z2); + addPoint(vcount, vertices, x2, y2, z2); + addPoint(vcount, vertices, x1, y2, z2); + return true; // return cube } else { - if ( scale ) + if (scale) { scale[0] = dx; scale[1] = dy; @@ -3075,61 +3190,56 @@ bool HullLibrary::CleanupVertices(unsigned int svcount, recip[1] = 1 / dy; recip[2] = 1 / dz; - center[0]*=recip[0]; - center[1]*=recip[1]; - center[2]*=recip[2]; - + center[0] *= recip[0]; + center[1] *= recip[1]; + center[2] *= recip[2]; } - } + vtx = (const char *)svertices; - - vtx = (const char *) svertices; - - for (unsigned int i=0; i dist2 ) + if (dist1 > dist2) { v[0] = px; v[1] = py; @@ -3140,9 +3250,9 @@ bool HullLibrary::CleanupVertices(unsigned int svcount, } } - if ( j == vcount ) + if (j == vcount) { - float *dest = &vertices[vcount*3]; + float *dest = &vertices[vcount * 3]; dest[0] = px; dest[1] = py; dest[2] = pz; @@ -3152,18 +3262,18 @@ bool HullLibrary::CleanupVertices(unsigned int svcount, } // ok..now make sure we didn't prune so many vertices it is now invalid. - if ( 1 ) + if (1) { - float bmin[3] = { FLT_MAX, FLT_MAX, FLT_MAX }; - float bmax[3] = { -FLT_MAX, -FLT_MAX, -FLT_MAX }; + float bmin[3] = {FLT_MAX, FLT_MAX, FLT_MAX}; + float bmax[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}; - for (unsigned int i=0; i bmax[j] ) bmax[j] = p[j]; + if (p[j] < bmin[j]) bmin[j] = p[j]; + if (p[j] > bmax[j]) bmax[j] = p[j]; } } @@ -3171,27 +3281,27 @@ bool HullLibrary::CleanupVertices(unsigned int svcount, float dy = bmax[1] - bmin[1]; float dz = bmax[2] - bmin[2]; - if ( dx < EPSILON || dy < EPSILON || dz < EPSILON || vcount < 3) + if (dx < EPSILON || dy < EPSILON || dz < EPSILON || vcount < 3) { - float cx = dx*0.5f + bmin[0]; - float cy = dy*0.5f + bmin[1]; - float cz = dz*0.5f + bmin[2]; + float cx = dx * 0.5f + bmin[0]; + float cy = dy * 0.5f + bmin[1]; + float cz = dz * 0.5f + bmin[2]; float len = FLT_MAX; - if ( dx >= EPSILON && dx < len ) len = dx; - if ( dy >= EPSILON && dy < len ) len = dy; - if ( dz >= EPSILON && dz < len ) len = dz; + if (dx >= EPSILON && dx < len) len = dx; + if (dy >= EPSILON && dy < len) len = dy; + if (dz >= EPSILON && dz < len) len = dz; - if ( len == FLT_MAX ) + if (len == FLT_MAX) { - dx = dy = dz = 0.01f; // one centimeter + dx = dy = dz = 0.01f; // one centimeter } else { - if ( dx < EPSILON ) dx = len * 0.05f; // 1/5th the shortest non-zero edge. - if ( dy < EPSILON ) dy = len * 0.05f; - if ( dz < EPSILON ) dz = len * 0.05f; + if (dx < EPSILON) dx = len * 0.05f; // 1/5th the shortest non-zero edge. + if (dy < EPSILON) dy = len * 0.05f; + if (dz < EPSILON) dz = len * 0.05f; } float x1 = cx - dx; @@ -3203,16 +3313,16 @@ bool HullLibrary::CleanupVertices(unsigned int svcount, float z1 = cz - dz; float z2 = cz + dz; - vcount = 0; // add box + vcount = 0; // add box - addPoint(vcount,vertices,x1,y1,z1); - addPoint(vcount,vertices,x2,y1,z1); - addPoint(vcount,vertices,x2,y2,z1); - addPoint(vcount,vertices,x1,y2,z1); - addPoint(vcount,vertices,x1,y1,z2); - addPoint(vcount,vertices,x2,y1,z2); - addPoint(vcount,vertices,x2,y2,z2); - addPoint(vcount,vertices,x1,y2,z2); + addPoint(vcount, vertices, x1, y1, z1); + addPoint(vcount, vertices, x2, y1, z1); + addPoint(vcount, vertices, x2, y2, z1); + addPoint(vcount, vertices, x1, y2, z1); + addPoint(vcount, vertices, x1, y1, z2); + addPoint(vcount, vertices, x2, y1, z2); + addPoint(vcount, vertices, x2, y2, z2); + addPoint(vcount, vertices, x1, y2, z2); return true; } @@ -3221,41 +3331,40 @@ bool HullLibrary::CleanupVertices(unsigned int svcount, return true; } -void HullLibrary::BringOutYourDead(const float *verts,unsigned int vcount, float *overts,unsigned int &ocount,unsigned int *indices,unsigned indexcount) +void HullLibrary::BringOutYourDead(const float *verts, unsigned int vcount, float *overts, unsigned int &ocount, unsigned int *indices, unsigned indexcount) { - unsigned int *used = (unsigned int *)malloc(sizeof(unsigned int)*vcount); - memset(used,0,sizeof(unsigned int)*vcount); + unsigned int *used = (unsigned int *)malloc(sizeof(unsigned int) * vcount); + memset(used, 0, sizeof(unsigned int) * vcount); ocount = 0; - for (unsigned int i=0; i= 0 && v < vcount ); + assert(v >= 0 && v < vcount); - if ( used[v] ) // if already remapped + if (used[v]) // if already remapped { - indices[i] = used[v]-1; // index to new array + indices[i] = used[v] - 1; // index to new array } else { + indices[i] = ocount; // new index mapping - indices[i] = ocount; // new index mapping + overts[ocount * 3 + 0] = verts[v * 3 + 0]; // copy old vert to new vert array + overts[ocount * 3 + 1] = verts[v * 3 + 1]; + overts[ocount * 3 + 2] = verts[v * 3 + 2]; - overts[ocount*3+0] = verts[v*3+0]; // copy old vert to new vert array - overts[ocount*3+1] = verts[v*3+1]; - overts[ocount*3+2] = verts[v*3+2]; + ocount++; // increment output vert count - ocount++; // increment output vert count + assert(ocount >= 0 && ocount <= vcount); - assert( ocount >=0 && ocount <= vcount ); - - used[v] = ocount; // assign new index remapping + used[v] = ocount; // assign new index remapping } } free(used); } -} +} // namespace ConvexDecomposition diff --git a/Extras/ConvexDecomposition/cd_hull.h b/Extras/ConvexDecomposition/cd_hull.h index 420e241b2..212815f86 100644 --- a/Extras/ConvexDecomposition/cd_hull.h +++ b/Extras/ConvexDecomposition/cd_hull.h @@ -31,7 +31,6 @@ namespace ConvexDecomposition { - class HullResult { public: @@ -44,110 +43,106 @@ public: mNumIndices = 0; mIndices = 0; } - bool mPolygons; // true if indices represents polygons, false indices are triangles - unsigned int mNumOutputVertices; // number of vertices in the output hull - float *mOutputVertices; // array of vertices, 3 floats each x,y,z - unsigned int mNumFaces; // the number of faces produced - unsigned int mNumIndices; // the total number of indices - unsigned int *mIndices; // pointer to indices. + bool mPolygons; // true if indices represents polygons, false indices are triangles + unsigned int mNumOutputVertices; // number of vertices in the output hull + float *mOutputVertices; // array of vertices, 3 floats each x,y,z + unsigned int mNumFaces; // the number of faces produced + unsigned int mNumIndices; // the total number of indices + unsigned int *mIndices; // pointer to indices. -// If triangles, then indices are array indexes into the vertex list. -// If polygons, indices are in the form (number of points in face) (p1, p2, p3, ..) etc.. + // If triangles, then indices are array indexes into the vertex list. + // If polygons, indices are in the form (number of points in face) (p1, p2, p3, ..) etc.. }; enum HullFlag { - QF_TRIANGLES = (1<<0), // report results as triangles, not polygons. - QF_REVERSE_ORDER = (1<<1), // reverse order of the triangle indices. - QF_SKIN_WIDTH = (1<<2), // extrude hull based on this skin width - QF_DEFAULT = 0 + QF_TRIANGLES = (1 << 0), // report results as triangles, not polygons. + QF_REVERSE_ORDER = (1 << 1), // reverse order of the triangle indices. + QF_SKIN_WIDTH = (1 << 2), // extrude hull based on this skin width + QF_DEFAULT = 0 }; - class HullDesc { public: HullDesc(void) { - mFlags = QF_DEFAULT; - mVcount = 0; - mVertices = 0; - mVertexStride = sizeof(float)*3; - mNormalEpsilon = 0.001f; - mMaxVertices = 4096; // maximum number of points to be considered for a convex hull. - mMaxFaces = 4096; - mSkinWidth = 0.01f; // default is one centimeter + mFlags = QF_DEFAULT; + mVcount = 0; + mVertices = 0; + mVertexStride = sizeof(float) * 3; + mNormalEpsilon = 0.001f; + mMaxVertices = 4096; // maximum number of points to be considered for a convex hull. + mMaxFaces = 4096; + mSkinWidth = 0.01f; // default is one centimeter }; HullDesc(HullFlag flag, - unsigned int vcount, - const float *vertices, - unsigned int stride) + unsigned int vcount, + const float *vertices, + unsigned int stride) { - mFlags = flag; - mVcount = vcount; - mVertices = vertices; - mVertexStride = stride; - mNormalEpsilon = 0.001f; - mMaxVertices = 4096; - mSkinWidth = 0.01f; // default is one centimeter + mFlags = flag; + mVcount = vcount; + mVertices = vertices; + mVertexStride = stride; + mNormalEpsilon = 0.001f; + mMaxVertices = 4096; + mSkinWidth = 0.01f; // default is one centimeter } bool HasHullFlag(HullFlag flag) const { - if ( mFlags & flag ) return true; + if (mFlags & flag) return true; return false; } void SetHullFlag(HullFlag flag) { - mFlags|=flag; + mFlags |= flag; } void ClearHullFlag(HullFlag flag) { - mFlags&=~flag; + mFlags &= ~flag; } - unsigned int mFlags; // flags to use when generating the convex hull. - unsigned int mVcount; // number of vertices in the input point cloud - const float *mVertices; // the array of vertices. - unsigned int mVertexStride; // the stride of each vertex, in bytes. - float mNormalEpsilon; // the epsilon for removing duplicates. This is a normalized value, if normalized bit is on. - float mSkinWidth; - unsigned int mMaxVertices; // maximum number of vertices to be considered for the hull! - unsigned int mMaxFaces; + unsigned int mFlags; // flags to use when generating the convex hull. + unsigned int mVcount; // number of vertices in the input point cloud + const float *mVertices; // the array of vertices. + unsigned int mVertexStride; // the stride of each vertex, in bytes. + float mNormalEpsilon; // the epsilon for removing duplicates. This is a normalized value, if normalized bit is on. + float mSkinWidth; + unsigned int mMaxVertices; // maximum number of vertices to be considered for the hull! + unsigned int mMaxFaces; }; enum HullError { - QE_OK, // success! - QE_FAIL // failed. + QE_OK, // success! + QE_FAIL // failed. }; class HullLibrary { public: + HullError CreateConvexHull(const HullDesc &desc, // describes the input request + HullResult &result); // contains the resulst - HullError CreateConvexHull(const HullDesc &desc, // describes the input request - HullResult &result); // contains the resulst - - HullError ReleaseResult(HullResult &result); // release memory allocated for this result, we are done with it. + HullError ReleaseResult(HullResult &result); // release memory allocated for this result, we are done with it. private: + void BringOutYourDead(const float *verts, unsigned int vcount, float *overts, unsigned int &ocount, unsigned int *indices, unsigned indexcount); - void BringOutYourDead(const float *verts,unsigned int vcount, float *overts,unsigned int &ocount,unsigned int *indices,unsigned indexcount); - - bool CleanupVertices(unsigned int svcount, - const float *svertices, - unsigned int stride, - unsigned int &vcount, // output number of vertices - float *vertices, // location to store the results. - float normalepsilon, - float *scale); + bool CleanupVertices(unsigned int svcount, + const float *svertices, + unsigned int stride, + unsigned int &vcount, // output number of vertices + float *vertices, // location to store the results. + float normalepsilon, + float *scale); }; -} +} // namespace ConvexDecomposition #endif - diff --git a/Extras/ConvexDecomposition/cd_vector.h b/Extras/ConvexDecomposition/cd_vector.h index bd1eff25b..6d46b2f3e 100644 --- a/Extras/ConvexDecomposition/cd_vector.h +++ b/Extras/ConvexDecomposition/cd_vector.h @@ -36,8 +36,7 @@ // http://www.amillionpixels.us // - -#pragma warning(disable:4786) +#pragma warning(disable : 4786) #include #include @@ -45,24 +44,22 @@ namespace ConvexDecomposition { - - const float DEG_TO_RAD = ((2.0f * 3.14152654f) / 360.0f); const float RAD_TO_DEG = (360.0f / (2.0f * 3.141592654f)); class Vector3d { public: - Vector3d(void) { }; // null constructor, does not inialize point. + Vector3d(void){}; // null constructor, does not inialize point. - Vector3d(const Vector3d &a) // constructor copies existing vector. + Vector3d(const Vector3d &a) // constructor copies existing vector. { x = a.x; y = a.y; z = a.z; }; - Vector3d(float a,float b,float c) // construct with initial point. + Vector3d(float a, float b, float c) // construct with initial point. { x = a; y = b; @@ -85,69 +82,102 @@ public: bool operator==(const Vector3d &a) const { - return( a.x == x && a.y == y && a.z == z ); + return (a.x == x && a.y == y && a.z == z); }; bool operator!=(const Vector3d &a) const { - return( a.x != x || a.y != y || a.z != z ); + return (a.x != x || a.y != y || a.z != z); }; -// Operators - Vector3d& operator = (const Vector3d& A) // ASSIGNMENT (=) - { x=A.x; y=A.y; z=A.z; - return(*this); }; + // Operators + Vector3d &operator=(const Vector3d &A) // ASSIGNMENT (=) + { + x = A.x; + y = A.y; + z = A.z; + return (*this); + }; - Vector3d operator + (const Vector3d& A) const // ADDITION (+) - { Vector3d Sum(x+A.x, y+A.y, z+A.z); - return(Sum); }; + Vector3d operator+(const Vector3d &A) const // ADDITION (+) + { + Vector3d Sum(x + A.x, y + A.y, z + A.z); + return (Sum); + }; - Vector3d operator - (const Vector3d& A) const // SUBTRACTION (-) - { Vector3d Diff(x-A.x, y-A.y, z-A.z); - return(Diff); }; + Vector3d operator-(const Vector3d &A) const // SUBTRACTION (-) + { + Vector3d Diff(x - A.x, y - A.y, z - A.z); + return (Diff); + }; - Vector3d operator * (const float s) const // MULTIPLY BY SCALAR (*) - { Vector3d Scaled(x*s, y*s, z*s); - return(Scaled); }; + Vector3d operator*(const float s) const // MULTIPLY BY SCALAR (*) + { + Vector3d Scaled(x * s, y * s, z * s); + return (Scaled); + }; + Vector3d operator+(const float s) const // ADD CONSTANT TO ALL 3 COMPONENTS (*) + { + Vector3d Scaled(x + s, y + s, z + s); + return (Scaled); + }; - Vector3d operator + (const float s) const // ADD CONSTANT TO ALL 3 COMPONENTS (*) - { Vector3d Scaled(x+s, y+s, z+s); - return(Scaled); }; + Vector3d operator/(const float s) const // DIVIDE BY SCALAR (/) + { + float r = 1.0f / s; + Vector3d Scaled(x * r, y * r, z * r); + return (Scaled); + }; + void operator/=(float A) // ACCUMULATED VECTOR ADDITION (/=) + { + x /= A; + y /= A; + z /= A; + }; + void operator+=(const Vector3d A) // ACCUMULATED VECTOR ADDITION (+=) + { + x += A.x; + y += A.y; + z += A.z; + }; + void operator-=(const Vector3d A) // ACCUMULATED VECTOR SUBTRACTION (+=) + { + x -= A.x; + y -= A.y; + z -= A.z; + }; + void operator*=(const float s) // ACCUMULATED SCALAR MULTIPLICATION (*=) (bpc 4/24/2000) + { + x *= s; + y *= s; + z *= s; + } + void operator+=(const float A) // ACCUMULATED VECTOR ADDITION (+=) + { + x += A; + y += A; + z += A; + }; - Vector3d operator / (const float s) const // DIVIDE BY SCALAR (/) - { - float r = 1.0f / s; - Vector3d Scaled(x*r, y*r, z*r); - return(Scaled); - }; + Vector3d operator-(void) const // NEGATION (-) + { + Vector3d Negated(-x, -y, -z); + return (Negated); + }; - void operator /= (float A) // ACCUMULATED VECTOR ADDITION (/=) - { x/=A; y/=A; z/=A; }; - - void operator += (const Vector3d A) // ACCUMULATED VECTOR ADDITION (+=) - { x+=A.x; y+=A.y; z+=A.z; }; - void operator -= (const Vector3d A) // ACCUMULATED VECTOR SUBTRACTION (+=) - { x-=A.x; y-=A.y; z-=A.z; }; - void operator *= (const float s) // ACCUMULATED SCALAR MULTIPLICATION (*=) (bpc 4/24/2000) - {x*=s; y*=s; z*=s;} - - void operator += (const float A) // ACCUMULATED VECTOR ADDITION (+=) - { x+=A; y+=A; z+=A; }; - - - Vector3d operator - (void) const // NEGATION (-) - { Vector3d Negated(-x, -y, -z); - return(Negated); }; - - float operator [] (const int i) const // ALLOWS VECTOR ACCESS AS AN ARRAY. - { return( (i==0)?x:((i==1)?y:z) ); }; - float & operator [] (const int i) - { return( (i==0)?x:((i==1)?y:z) ); }; -// + float operator[](const int i) const // ALLOWS VECTOR ACCESS AS AN ARRAY. + { + return ((i == 0) ? x : ((i == 1) ? y : z)); + }; + float &operator[](const int i) + { + return ((i == 0) ? x : ((i == 1) ? y : z)); + }; + // // accessor methods. float GetX(void) const { return x; }; @@ -158,27 +188,26 @@ public: float Y(void) const { return y; }; float Z(void) const { return z; }; - void SetX(float t) { x = t; }; - void SetY(float t) { y = t; }; - void SetZ(float t) { z = t; }; + void SetX(float t) { x = t; }; + void SetY(float t) { y = t; }; + void SetZ(float t) { z = t; }; - bool IsSame(const Vector3d &v,float epsilon) const + bool IsSame(const Vector3d &v, float epsilon) const { - float dx = fabsf( x - v.x ); - if ( dx > epsilon ) return false; - float dy = fabsf( y - v.y ); - if ( dy > epsilon ) return false; - float dz = fabsf( z - v.z ); - if ( dz > epsilon ) return false; + float dx = fabsf(x - v.x); + if (dx > epsilon) return false; + float dy = fabsf(y - v.y); + if (dy > epsilon) return false; + float dz = fabsf(z - v.z); + if (dz > epsilon) return false; return true; } - float ComputeNormal(const Vector3d &A, - const Vector3d &B, - const Vector3d &C) + const Vector3d &B, + const Vector3d &C) { - float vx,vy,vz,wx,wy,wz,vw_x,vw_y,vw_z,mag; + float vx, vy, vz, wx, wy, wz, vw_x, vw_y, vw_z, mag; vx = (B.x - C.x); vy = (B.y - C.y); @@ -194,13 +223,13 @@ public: mag = sqrtf((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z)); - if ( mag < 0.000001f ) + if (mag < 0.000001f) { mag = 0; } else { - mag = 1.0f/mag; + mag = 1.0f / mag; } x = vw_x * mag; @@ -210,12 +239,11 @@ public: return mag; } - - void ScaleSumScale(float c0,float c1,const Vector3d &pos) + void ScaleSumScale(float c0, float c1, const Vector3d &pos) { - x = (x*c0) + (pos.x*c1); - y = (y*c0) + (pos.y*c1); - z = (z*c0) + (pos.z*c1); + x = (x * c0) + (pos.x * c1); + y = (y * c0) + (pos.y * c1); + z = (z * c0) + (pos.z * c1); } void SwapYZ(void) @@ -234,20 +262,19 @@ public: void Set(const int *p) { - x = (float) p[0]; - y = (float) p[1]; - z = (float) p[2]; + x = (float)p[0]; + y = (float)p[1]; + z = (float)p[2]; } void Set(const float *p) { - x = (float) p[0]; - y = (float) p[1]; - z = (float) p[2]; + x = (float)p[0]; + y = (float)p[1]; + z = (float)p[2]; } - - void Set(float a,float b,float c) + void Set(float a, float b, float c) { x = a; y = b; @@ -259,11 +286,10 @@ public: x = y = z = 0; }; - const float* Ptr() const { return &x; } - float* Ptr() { return &x; } + const float *Ptr() const { return &x; } + float *Ptr() { return &x; } - -// return -(*this). + // return -(*this). Vector3d negative(void) const { Vector3d result; @@ -288,7 +314,7 @@ public: return float(sqrtf(x * x + y * y + z * z)); }; - void Lerp(const Vector3d& from,const Vector3d& to,float slerp) + void Lerp(const Vector3d &from, const Vector3d &to, float slerp) { x = ((to.x - from.x) * slerp) + from.x; y = ((to.y - from.y) * slerp) + from.y; @@ -300,30 +326,30 @@ public: // Reason for existance is so that when a bullet collides with a wall, for // example, you can generate a graphic effect slightly *before* it hit the // wall so that the effect doesn't sort into the wall itself. - void Interpolate(const Vector3d &from,const Vector3d &to,float offset) + void Interpolate(const Vector3d &from, const Vector3d &to, float offset) { - x = to.x-from.x; - y = to.y-from.y; - z = to.z-from.z; - float d = sqrtf( x*x + y*y + z*z ); + x = to.x - from.x; + y = to.y - from.y; + z = to.z - from.z; + float d = sqrtf(x * x + y * y + z * z); float recip = 1.0f / d; - x*=recip; - y*=recip; - z*=recip; // normalize vector - d+=offset; // shift along ray - x = x*d + from.x; - y = y*d + from.y; - z = z*d + from.z; + x *= recip; + y *= recip; + z *= recip; // normalize vector + d += offset; // shift along ray + x = x * d + from.x; + y = y * d + from.y; + z = z * d + from.z; }; bool BinaryEqual(const Vector3d &p) const { - const int *source = (const int *) &x; - const int *dest = (const int *) &p.x; + const int *source = (const int *)&x; + const int *dest = (const int *)&p.x; - if ( source[0] == dest[0] && - source[1] == dest[1] && - source[2] == dest[2] ) return true; + if (source[0] == dest[0] && + source[1] == dest[1] && + source[2] == dest[2]) return true; return false; }; @@ -335,10 +361,8 @@ public: } */ - - -/** Computes the reflection vector between two vectors.*/ - void Reflection(const Vector3d &a,const Vector3d &b)// compute reflection vector. + /** Computes the reflection vector between two vectors.*/ + void Reflection(const Vector3d &a, const Vector3d &b) // compute reflection vector. { Vector3d c; Vector3d d; @@ -354,24 +378,23 @@ public: z = -d.z; }; - void AngleAxis(float angle,const Vector3d& axis) + void AngleAxis(float angle, const Vector3d &axis) { - x = axis.x*angle; - y = axis.y*angle; - z = axis.z*angle; + x = axis.x * angle; + y = axis.y * angle; + z = axis.z * angle; }; - float Length(void) const // length of vector. + float Length(void) const // length of vector. { - return float(sqrt( x*x + y*y + z*z )); + return float(sqrt(x * x + y * y + z * z)); }; - float ComputePlane(const Vector3d &A, - const Vector3d &B, - const Vector3d &C) + const Vector3d &B, + const Vector3d &C) { - float vx,vy,vz,wx,wy,wz,vw_x,vw_y,vw_z,mag; + float vx, vy, vz, wx, wy, wz, vw_x, vw_y, vw_z, mag; vx = (B.x - C.x); vy = (B.y - C.y); @@ -387,68 +410,64 @@ public: mag = sqrtf((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z)); - if ( mag < 0.000001f ) + if (mag < 0.000001f) { mag = 0; } else { - mag = 1.0f/mag; + mag = 1.0f / mag; } x = vw_x * mag; y = vw_y * mag; z = vw_z * mag; - - float D = 0.0f - ((x*A.x)+(y*A.y)+(z*A.z)); + float D = 0.0f - ((x * A.x) + (y * A.y) + (z * A.z)); return D; } - - float FastLength(void) const // length of vector. + float FastLength(void) const // length of vector. { - return float(sqrtf( x*x + y*y + z*z )); - }; - - - float FasterLength(void) const // length of vector. - { - return float(sqrtf( x*x + y*y + z*z )); + return float(sqrtf(x * x + y * y + z * z)); }; - float Length2(void) const // squared distance, prior to square root. + float FasterLength(void) const // length of vector. { - float l2 = x*x+y*y+z*z; + return float(sqrtf(x * x + y * y + z * z)); + }; + + float Length2(void) const // squared distance, prior to square root. + { + float l2 = x * x + y * y + z * z; return l2; }; - float Distance(const Vector3d &a) const // distance between two points. + float Distance(const Vector3d &a) const // distance between two points. { - Vector3d d(a.x-x,a.y-y,a.z-z); + Vector3d d(a.x - x, a.y - y, a.z - z); return d.Length(); } - float FastDistance(const Vector3d &a) const // distance between two points. + float FastDistance(const Vector3d &a) const // distance between two points. { - Vector3d d(a.x-x,a.y-y,a.z-z); + Vector3d d(a.x - x, a.y - y, a.z - z); return d.FastLength(); } - - float FasterDistance(const Vector3d &a) const // distance between two points. + + float FasterDistance(const Vector3d &a) const // distance between two points. { - Vector3d d(a.x-x,a.y-y,a.z-z); + Vector3d d(a.x - x, a.y - y, a.z - z); return d.FasterLength(); } - float DistanceXY(const Vector3d &a) const { - float dx = a.x - x; - float dy = a.y - y; - float dist = dx*dx + dy*dy; - return dist; + float dx = a.x - x; + float dy = a.y - y; + float dist = dx * dx + dy * dy; + return dist; } float Distance2(const Vector3d &a) const // squared distance. @@ -456,26 +475,26 @@ public: float dx = a.x - x; float dy = a.y - y; float dz = a.z - z; - return dx*dx + dy*dy + dz*dz; + return dx * dx + dy * dy + dz * dz; }; float Partial(const Vector3d &p) const { - return (x*p.y) - (p.x*y); + return (x * p.y) - (p.x * y); } - float Area(const Vector3d &p1,const Vector3d &p2) const + float Area(const Vector3d &p1, const Vector3d &p2) const { float A = Partial(p1); - A+= p1.Partial(p2); - A+= p2.Partial(*this); - return A*0.5f; + A += p1.Partial(p2); + A += p2.Partial(*this); + return A * 0.5f; } - inline float Normalize(void) // normalize to a unit vector, returns distance. + inline float Normalize(void) // normalize to a unit vector, returns distance. { - float d = sqrtf( static_cast< float >( x*x + y*y + z*z ) ); - if ( d > 0 ) + float d = sqrtf(static_cast(x * x + y * y + z * z)); + if (d > 0) { float r = 1.0f / d; x *= r; @@ -489,10 +508,10 @@ public: return d; }; - inline float FastNormalize(void) // normalize to a unit vector, returns distance. + inline float FastNormalize(void) // normalize to a unit vector, returns distance. { - float d = sqrt( static_cast< float >( x*x + y*y + z*z ) ); - if ( d > 0 ) + float d = sqrt(static_cast(x * x + y * y + z * z)); + if (d > 0) { float r = 1.0f / d; x *= r; @@ -506,10 +525,10 @@ public: return d; }; - inline float FasterNormalize(void) // normalize to a unit vector, returns distance. + inline float FasterNormalize(void) // normalize to a unit vector, returns distance. { - float d = sqrtf( static_cast< float >( x*x + y*y + z*z ) ); - if ( d > 0 ) + float d = sqrtf(static_cast(x * x + y * y + z * z)); + if (d > 0) { float r = 1.0f / d; x *= r; @@ -523,27 +542,23 @@ public: return d; }; - - - - float Dot(const Vector3d &a) const // computes dot product. + float Dot(const Vector3d &a) const // computes dot product. { - return (x * a.x + y * a.y + z * a.z ); + return (x * a.x + y * a.y + z * a.z); }; - - Vector3d Cross( const Vector3d& other ) const + Vector3d Cross(const Vector3d &other) const { - Vector3d result( y*other.z - z*other.y, z*other.x - x*other.z, x*other.y - y*other.x ); + Vector3d result(y * other.z - z * other.y, z * other.x - x * other.z, x * other.y - y * other.x); return result; } - void Cross(const Vector3d &a,const Vector3d &b) // cross two vectors result in this one. + void Cross(const Vector3d &a, const Vector3d &b) // cross two vectors result in this one. { - x = a.y*b.z - a.z*b.y; - y = a.z*b.x - a.x*b.z; - z = a.x*b.y - a.y*b.x; + x = a.y * b.z - a.z * b.y; + y = a.z * b.x - a.x * b.z; + z = a.x * b.y - a.y * b.x; }; /******************************************/ @@ -552,27 +567,27 @@ public: // Edge from a to b is already in face // Edge from b to c is being considered for addition to face /******************************************/ - bool Concave(const Vector3d& a,const Vector3d& b) + bool Concave(const Vector3d &a, const Vector3d &b) { - float vx,vy,vz,wx,wy,wz,vw_x,vw_y,vw_z,mag,nx,ny,nz,mag_a,mag_b; + float vx, vy, vz, wx, wy, wz, vw_x, vw_y, vw_z, mag, nx, ny, nz, mag_a, mag_b; wx = b.x - a.x; wy = b.y - a.y; wz = b.z - a.z; - mag_a = (float) sqrtf((wx * wx) + (wy * wy) + (wz * wz)); + mag_a = (float)sqrtf((wx * wx) + (wy * wy) + (wz * wz)); vx = x - b.x; vy = y - b.y; vz = z - b.z; - mag_b = (float) sqrtf((vx * vx) + (vy * vy) + (vz * vz)); + mag_b = (float)sqrtf((vx * vx) + (vy * vy) + (vz * vz)); vw_x = (vy * wz) - (vz * wy); vw_y = (vz * wx) - (vx * wz); vw_z = (vx * wy) - (vy * wx); - mag = (float) sqrtf((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z)); + mag = (float)sqrtf((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z)); // Check magnitude of cross product, which is a sine function // i.e., mag (a x b) = mag (a) * mag (b) * sin (theta); @@ -582,7 +597,7 @@ public: // face consolidation to get stuck on particular face. Most meshes // convert properly with a value of 0.0 - if (mag/(mag_a*mag_b) <= 0.0f ) return true; + if (mag / (mag_a * mag_b) <= 0.0f) return true; mag = 1.0f / mag; @@ -595,33 +610,33 @@ public: // are coplanar), negative number if edges are concave (-1.0 if // two tris are coplanar.) - mag = ( x * nx) + ( y * ny) + ( z * nz); + mag = (x * nx) + (y * ny) + (z * nz); - if (mag > 0.0f ) return false; + if (mag > 0.0f) return false; - return(true); + return (true); }; - bool PointTestXY(const Vector3d &i,const Vector3d &j) const + bool PointTestXY(const Vector3d &i, const Vector3d &j) const { - if (((( i.y <= y ) && ( y < j.y )) || - (( j.y <= y ) && ( y < i.y ))) && - ( x < (j.x - i.x) * (y - i.y) / (j.y - i.y) + i.x)) return true; + if ((((i.y <= y) && (y < j.y)) || + ((j.y <= y) && (y < i.y))) && + (x < (j.x - i.x) * (y - i.y) / (j.y - i.y) + i.x)) return true; return false; } // test to see if this point is inside the triangle specified by // these three points on the X/Y plane. bool PointInTriXY(const Vector3d &p1, - const Vector3d &p2, - const Vector3d &p3) const + const Vector3d &p2, + const Vector3d &p3) const { - float ax = p3.x - p2.x; - float ay = p3.y - p2.y; - float bx = p1.x - p3.x; - float by = p1.y - p3.y; - float cx = p2.x - p1.x; - float cy = p2.y - p1.y; + float ax = p3.x - p2.x; + float ay = p3.y - p2.y; + float bx = p1.x - p3.x; + float by = p1.y - p3.y; + float cx = p2.x - p1.x; + float cy = p2.y - p1.y; float apx = x - p1.x; float apy = y - p1.y; float bpx = x - p2.x; @@ -629,9 +644,9 @@ public: float cpx = x - p3.x; float cpy = y - p3.y; - float aCROSSbp = ax*bpy - ay*bpx; - float cCROSSap = cx*apy - cy*apx; - float bCROSScp = bx*cpy - by*cpx; + float aCROSSbp = ax * bpy - ay * bpx; + float cCROSSap = cx * apy - cy * apx; + float bCROSScp = bx * cpy - by * cpx; return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f)); }; @@ -639,15 +654,15 @@ public: // test to see if this point is inside the triangle specified by // these three points on the X/Y plane. bool PointInTriYZ(const Vector3d &p1, - const Vector3d &p2, - const Vector3d &p3) const + const Vector3d &p2, + const Vector3d &p3) const { - float ay = p3.y - p2.y; - float az = p3.z - p2.z; - float by = p1.y - p3.y; - float bz = p1.z - p3.z; - float cy = p2.y - p1.y; - float cz = p2.z - p1.z; + float ay = p3.y - p2.y; + float az = p3.z - p2.z; + float by = p1.y - p3.y; + float bz = p1.z - p3.z; + float cy = p2.y - p1.y; + float cz = p2.z - p1.z; float apy = y - p1.y; float apz = z - p1.z; float bpy = y - p2.y; @@ -655,26 +670,25 @@ public: float cpy = y - p3.y; float cpz = z - p3.z; - float aCROSSbp = ay*bpz - az*bpy; - float cCROSSap = cy*apz - cz*apy; - float bCROSScp = by*cpz - bz*cpy; + float aCROSSbp = ay * bpz - az * bpy; + float cCROSSap = cy * apz - cz * apy; + float bCROSScp = by * cpz - bz * cpy; return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f)); }; - // test to see if this point is inside the triangle specified by // these three points on the X/Y plane. bool PointInTriXZ(const Vector3d &p1, - const Vector3d &p2, - const Vector3d &p3) const + const Vector3d &p2, + const Vector3d &p3) const { - float az = p3.z - p2.z; - float ax = p3.x - p2.x; - float bz = p1.z - p3.z; - float bx = p1.x - p3.x; - float cz = p2.z - p1.z; - float cx = p2.x - p1.x; + float az = p3.z - p2.z; + float ax = p3.x - p2.x; + float bz = p1.z - p3.z; + float bx = p1.x - p3.x; + float cz = p2.z - p1.z; + float cx = p2.x - p1.x; float apz = z - p1.z; float apx = x - p1.x; float bpz = z - p2.z; @@ -682,9 +696,9 @@ public: float cpz = z - p3.z; float cpx = x - p3.x; - float aCROSSbp = az*bpx - ax*bpz; - float cCROSSap = cz*apx - cx*apz; - float bCROSScp = bz*cpx - bx*cpz; + float aCROSSbp = az * bpx - ax * bpz; + float cCROSSap = cz * apx - cx * apz; + float bCROSScp = bz * cpx - bx * cpz; return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f)); }; @@ -692,91 +706,91 @@ public: // Given a point and a line (defined by two points), compute the closest point // in the line. (The line is treated as infinitely long.) void NearestPointInLine(const Vector3d &point, - const Vector3d &line0, - const Vector3d &line1) + const Vector3d &line0, + const Vector3d &line1) { Vector3d &nearestPoint = *this; - Vector3d lineDelta = line1 - line0; + Vector3d lineDelta = line1 - line0; // Handle degenerate lines - if ( lineDelta == Vector3d(0, 0, 0) ) + if (lineDelta == Vector3d(0, 0, 0)) { nearestPoint = line0; } else { - float delta = (point-line0).Dot(lineDelta) / (lineDelta).Dot(lineDelta); - nearestPoint = line0 + lineDelta*delta; + float delta = (point - line0).Dot(lineDelta) / (lineDelta).Dot(lineDelta); + nearestPoint = line0 + lineDelta * delta; } } // Given a point and a line segment (defined by two points), compute the closest point // in the line. Cap the point at the endpoints of the line segment. void NearestPointInLineSegment(const Vector3d &point, - const Vector3d &line0, - const Vector3d &line1) + const Vector3d &line0, + const Vector3d &line1) { Vector3d &nearestPoint = *this; - Vector3d lineDelta = line1 - line0; + Vector3d lineDelta = line1 - line0; // Handle degenerate lines - if ( lineDelta == Vector3d(0, 0, 0) ) + if (lineDelta == Vector3d(0, 0, 0)) { nearestPoint = line0; } else { - float delta = (point-line0).Dot(lineDelta) / (lineDelta).Dot(lineDelta); + float delta = (point - line0).Dot(lineDelta) / (lineDelta).Dot(lineDelta); // Clamp the point to conform to the segment's endpoints - if ( delta < 0 ) + if (delta < 0) delta = 0; - else if ( delta > 1 ) + else if (delta > 1) delta = 1; - nearestPoint = line0 + lineDelta*delta; + nearestPoint = line0 + lineDelta * delta; } } // Given a point and a plane (defined by three points), compute the closest point // in the plane. (The plane is unbounded.) void NearestPointInPlane(const Vector3d &point, - const Vector3d &triangle0, - const Vector3d &triangle1, - const Vector3d &triangle2) + const Vector3d &triangle0, + const Vector3d &triangle1, + const Vector3d &triangle2) { Vector3d &nearestPoint = *this; - Vector3d lineDelta0 = triangle1 - triangle0; - Vector3d lineDelta1 = triangle2 - triangle0; - Vector3d pointDelta = point - triangle0; + Vector3d lineDelta0 = triangle1 - triangle0; + Vector3d lineDelta1 = triangle2 - triangle0; + Vector3d pointDelta = point - triangle0; Vector3d normal; // Get the normal of the polygon (doesn't have to be a unit vector) normal.Cross(lineDelta0, lineDelta1); float delta = normal.Dot(pointDelta) / normal.Dot(normal); - nearestPoint = point - normal*delta; + nearestPoint = point - normal * delta; } // Given a point and a plane (defined by a coplanar point and a normal), compute the closest point // in the plane. (The plane is unbounded.) void NearestPointInPlane(const Vector3d &point, - const Vector3d &planePoint, - const Vector3d &planeNormal) + const Vector3d &planePoint, + const Vector3d &planeNormal) { Vector3d &nearestPoint = *this; - Vector3d pointDelta = point - planePoint; + Vector3d pointDelta = point - planePoint; float delta = planeNormal.Dot(pointDelta) / planeNormal.Dot(planeNormal); - nearestPoint = point - planeNormal*delta; + nearestPoint = point - planeNormal * delta; } // Given a point and a triangle (defined by three points), compute the closest point // in the triangle. Clamp the point so it's confined to the area of the triangle. void NearestPointInTriangle(const Vector3d &point, - const Vector3d &triangle0, - const Vector3d &triangle1, - const Vector3d &triangle2) + const Vector3d &triangle0, + const Vector3d &triangle1, + const Vector3d &triangle2) { static const Vector3d zeroVector(0, 0, 0); @@ -786,11 +800,11 @@ public: Vector3d lineDelta1 = triangle2 - triangle0; // Handle degenerate triangles - if ( (lineDelta0 == zeroVector) || (lineDelta1 == zeroVector) ) + if ((lineDelta0 == zeroVector) || (lineDelta1 == zeroVector)) { nearestPoint.NearestPointInLineSegment(point, triangle1, triangle2); } - else if ( lineDelta0 == lineDelta1 ) + else if (lineDelta0 == lineDelta1) { nearestPoint.NearestPointInLineSegment(point, triangle0, triangle1); } @@ -803,52 +817,52 @@ public: axis[2].NearestPointInLine(triangle2, triangle0, triangle1); float axisDot[3]; - axisDot[0] = (triangle0-axis[0]).Dot(point-axis[0]); - axisDot[1] = (triangle1-axis[1]).Dot(point-axis[1]); - axisDot[2] = (triangle2-axis[2]).Dot(point-axis[2]); + axisDot[0] = (triangle0 - axis[0]).Dot(point - axis[0]); + axisDot[1] = (triangle1 - axis[1]).Dot(point - axis[1]); + axisDot[2] = (triangle2 - axis[2]).Dot(point - axis[2]); - bool bForce = true; - float bestMagnitude2 = 0; - float closeMagnitude2; + bool bForce = true; + float bestMagnitude2 = 0; + float closeMagnitude2; Vector3d closePoint; - if ( axisDot[0] < 0 ) + if (axisDot[0] < 0) { closePoint.NearestPointInLineSegment(point, triangle1, triangle2); closeMagnitude2 = point.Distance2(closePoint); - if ( bForce || (bestMagnitude2 > closeMagnitude2) ) + if (bForce || (bestMagnitude2 > closeMagnitude2)) { - bForce = false; + bForce = false; bestMagnitude2 = closeMagnitude2; - nearestPoint = closePoint; + nearestPoint = closePoint; } } - if ( axisDot[1] < 0 ) + if (axisDot[1] < 0) { closePoint.NearestPointInLineSegment(point, triangle0, triangle2); closeMagnitude2 = point.Distance2(closePoint); - if ( bForce || (bestMagnitude2 > closeMagnitude2) ) + if (bForce || (bestMagnitude2 > closeMagnitude2)) { - bForce = false; + bForce = false; bestMagnitude2 = closeMagnitude2; - nearestPoint = closePoint; + nearestPoint = closePoint; } } - if ( axisDot[2] < 0 ) + if (axisDot[2] < 0) { closePoint.NearestPointInLineSegment(point, triangle0, triangle1); closeMagnitude2 = point.Distance2(closePoint); - if ( bForce || (bestMagnitude2 > closeMagnitude2) ) + if (bForce || (bestMagnitude2 > closeMagnitude2)) { - bForce = false; + bForce = false; bestMagnitude2 = closeMagnitude2; - nearestPoint = closePoint; + nearestPoint = closePoint; } } // If bForce is true at this point, it means the nearest point lies // inside the triangle; use the nearest-point-on-a-plane equation - if ( bForce ) + if (bForce) { Vector3d normal; @@ -858,26 +872,24 @@ public: Vector3d pointDelta = point - triangle0; float delta = normal.Dot(pointDelta) / normal.Dot(normal); - nearestPoint = point - normal*delta; + nearestPoint = point - normal * delta; } } } - -//private: + //private: float x; float y; float z; }; - class Vector2d { public: - Vector2d(void) { }; // null constructor, does not inialize point. + Vector2d(void){}; // null constructor, does not inialize point. - Vector2d(const Vector2d &a) // constructor copies existing vector. + Vector2d(const Vector2d &a) // constructor copies existing vector. { x = a.x; y = a.y; @@ -889,86 +901,85 @@ public: y = t[1]; }; - - Vector2d(float a,float b) // construct with initial point. + Vector2d(float a, float b) // construct with initial point. { x = a; y = b; }; - const float* Ptr() const { return &x; } - float* Ptr() { return &x; } + const float *Ptr() const { return &x; } + float *Ptr() { return &x; } - Vector2d & operator+=(const Vector2d &a) // += operator. + Vector2d &operator+=(const Vector2d &a) // += operator. { - x+=a.x; - y+=a.y; + x += a.x; + y += a.y; return *this; }; - Vector2d & operator-=(const Vector2d &a) + Vector2d &operator-=(const Vector2d &a) { - x-=a.x; - y-=a.y; + x -= a.x; + y -= a.y; return *this; }; - Vector2d & operator*=(const Vector2d &a) + Vector2d &operator*=(const Vector2d &a) { - x*=a.x; - y*=a.y; + x *= a.x; + y *= a.y; return *this; }; - Vector2d & operator/=(const Vector2d &a) + Vector2d &operator/=(const Vector2d &a) { - x/=a.x; - y/=a.y; + x /= a.x; + y /= a.y; return *this; }; bool operator==(const Vector2d &a) const { - if ( a.x == x && a.y == y ) return true; + if (a.x == x && a.y == y) return true; return false; }; bool operator!=(const Vector2d &a) const { - if ( a.x != x || a.y != y ) return true; + if (a.x != x || a.y != y) return true; return false; }; Vector2d operator+(Vector2d a) const { - a.x+=x; - a.y+=y; + a.x += x; + a.y += y; return a; }; Vector2d operator-(Vector2d a) const { - a.x = x-a.x; - a.y = y-a.y; + a.x = x - a.x; + a.y = y - a.y; return a; }; - Vector2d operator - (void) const + Vector2d operator-(void) const { return negative(); }; Vector2d operator*(Vector2d a) const { - a.x*=x; - a.y*=y; + a.x *= x; + a.y *= y; return a; }; Vector2d operator*(float c) const { Vector2d a; - + a.x = x * c; a.y = y * c; @@ -977,24 +988,23 @@ public: Vector2d operator/(Vector2d a) const { - a.x = x/a.x; - a.y = y/a.y; + a.x = x / a.x; + a.y = y / a.y; return a; }; - - float Dot(const Vector2d &a) const // computes dot product. + float Dot(const Vector2d &a) const // computes dot product. { - return (x * a.x + y * a.y ); + return (x * a.x + y * a.y); }; float GetX(void) const { return x; }; float GetY(void) const { return y; }; - void SetX(float t) { x = t; }; - void SetY(float t) { y = t; }; + void SetX(float t) { x = t; }; + void SetY(float t) { y = t; }; - void Set(float a,float b) + void Set(float a, float b) { x = a; y = b; @@ -1015,93 +1025,92 @@ public: float magnitude(void) const { - return (float) sqrtf(x * x + y * y ); + return (float)sqrtf(x * x + y * y); } float fastmagnitude(void) const { - return (float) sqrtf(x * x + y * y ); + return (float)sqrtf(x * x + y * y); } - + float fastermagnitude(void) const { - return (float) sqrtf( x * x + y * y ); + return (float)sqrtf(x * x + y * y); } - void Reflection(Vector2d &a,Vector2d &b); // compute reflection vector. + void Reflection(Vector2d &a, Vector2d &b); // compute reflection vector. - float Length(void) const // length of vector. + float Length(void) const // length of vector. { - return float(sqrtf( x*x + y*y )); + return float(sqrtf(x * x + y * y)); }; - float FastLength(void) const // length of vector. + float FastLength(void) const // length of vector. { - return float(sqrtf( x*x + y*y )); + return float(sqrtf(x * x + y * y)); }; - float FasterLength(void) const // length of vector. + float FasterLength(void) const // length of vector. { - return float(sqrtf( x*x + y*y )); + return float(sqrtf(x * x + y * y)); }; - float Length2(void) // squared distance, prior to square root. + float Length2(void) // squared distance, prior to square root. { - return x*x+y*y; + return x * x + y * y; } - float Distance(const Vector2d &a) const // distance between two points. + float Distance(const Vector2d &a) const // distance between two points. { float dx = a.x - x; float dy = a.y - y; - float d = dx*dx+dy*dy; + float d = dx * dx + dy * dy; return sqrtf(d); }; - float FastDistance(const Vector2d &a) const // distance between two points. + float FastDistance(const Vector2d &a) const // distance between two points. { float dx = a.x - x; float dy = a.y - y; - float d = dx*dx+dy*dy; + float d = dx * dx + dy * dy; return sqrtf(d); }; - float FasterDistance(const Vector2d &a) const // distance between two points. + float FasterDistance(const Vector2d &a) const // distance between two points. { float dx = a.x - x; float dy = a.y - y; - float d = dx*dx+dy*dy; + float d = dx * dx + dy * dy; return sqrtf(d); }; - float Distance2(Vector2d &a) // squared distance. + float Distance2(Vector2d &a) // squared distance. { float dx = a.x - x; float dy = a.y - y; - return dx*dx + dy *dy; + return dx * dx + dy * dy; }; - void Lerp(const Vector2d& from,const Vector2d& to,float slerp) + void Lerp(const Vector2d &from, const Vector2d &to, float slerp) { - x = ((to.x - from.x)*slerp) + from.x; - y = ((to.y - from.y)*slerp) + from.y; + x = ((to.x - from.x) * slerp) + from.x; + y = ((to.y - from.y) * slerp) + from.y; }; - - void Cross(const Vector2d &a,const Vector2d &b) // cross two vectors result in this one. + void Cross(const Vector2d &a, const Vector2d &b) // cross two vectors result in this one. { - x = a.y*b.x - a.x*b.y; - y = a.x*b.x - a.x*b.x; + x = a.y * b.x - a.x * b.y; + y = a.x * b.x - a.x * b.x; }; - float Normalize(void) // normalize to a unit vector, returns distance. + float Normalize(void) // normalize to a unit vector, returns distance. { float l = Length(); - if ( l != 0 ) + if (l != 0) { - l = float( 1 ) / l; - x*=l; - y*=l; + l = float(1) / l; + x *= l; + y *= l; } else { @@ -1110,14 +1119,14 @@ public: return l; }; - float FastNormalize(void) // normalize to a unit vector, returns distance. + float FastNormalize(void) // normalize to a unit vector, returns distance. { float l = FastLength(); - if ( l != 0 ) + if (l != 0) { - l = float( 1 ) / l; - x*=l; - y*=l; + l = float(1) / l; + x *= l; + y *= l; } else { @@ -1126,14 +1135,14 @@ public: return l; }; - float FasterNormalize(void) // normalize to a unit vector, returns distance. + float FasterNormalize(void) // normalize to a unit vector, returns distance. { float l = FasterLength(); - if ( l != 0 ) + if (l != 0) { - l = float( 1 ) / l; - x*=l; - y*=l; + l = float(1) / l; + x *= l; + y *= l; } else { @@ -1142,7 +1151,6 @@ public: return l; }; - float x; float y; }; @@ -1150,36 +1158,35 @@ public: class Line { public: - Line(const Vector3d &from,const Vector3d &to) + Line(const Vector3d &from, const Vector3d &to) { mP1 = from; mP2 = to; }; // JWR Test for the intersection of two lines. - bool Intersect(const Line& src,Vector3d §); + bool Intersect(const Line &src, Vector3d §); + private: Vector3d mP1; Vector3d mP2; - }; +typedef std::vector Vector3dVector; +typedef std::vector Vector2dVector; -typedef std::vector< Vector3d > Vector3dVector; -typedef std::vector< Vector2d > Vector2dVector; - -inline Vector3d operator * (float s, const Vector3d &v ) -{ - Vector3d Scaled(v.x*s, v.y*s, v.z*s); - return(Scaled); +inline Vector3d operator*(float s, const Vector3d &v) +{ + Vector3d Scaled(v.x * s, v.y * s, v.z * s); + return (Scaled); } -inline Vector2d operator * (float s, const Vector2d &v ) - { - Vector2d Scaled(v.x*s, v.y*s); - return(Scaled); - } - +inline Vector2d operator*(float s, const Vector2d &v) +{ + Vector2d Scaled(v.x * s, v.y * s); + return (Scaled); } +} // namespace ConvexDecomposition + #endif diff --git a/Extras/ConvexDecomposition/cd_wavefront.cpp b/Extras/ConvexDecomposition/cd_wavefront.cpp index 54e8bdf68..1c722b4d3 100644 --- a/Extras/ConvexDecomposition/cd_wavefront.cpp +++ b/Extras/ConvexDecomposition/cd_wavefront.cpp @@ -41,7 +41,6 @@ #include "cd_wavefront.h" - using namespace ConvexDecomposition; /*---------------------------------------------------------------------- @@ -75,9 +74,8 @@ using namespace ConvexDecomposition; namespace ConvexDecomposition { - -typedef std::vector< int > IntVector; -typedef std::vector< float > FloatVector; +typedef std::vector IntVector; +typedef std::vector FloatVector; #if defined(__APPLE__) || defined(__CELLOS_LV2__) #define stricmp(a, b) strcasecmp((a), (b)) @@ -89,17 +87,17 @@ typedef std::vector< float > FloatVector; class InPlaceParserInterface { public: - virtual ~InPlaceParserInterface () {} ; + virtual ~InPlaceParserInterface(){}; - virtual int ParseLine(int lineno,int argc,const char **argv) =0; // return TRUE to continue parsing, return FALSE to abort parsing process + virtual int ParseLine(int lineno, int argc, const char **argv) = 0; // return TRUE to continue parsing, return FALSE to abort parsing process }; enum SeparatorType { - ST_DATA, // is data - ST_HARD, // is a hard separator - ST_SOFT, // is a soft separator - ST_EOS // is a comment symbol, and everything past this character should be ignored + ST_DATA, // is data + ST_HARD, // is a hard separator + ST_SOFT, // is a soft separator + ST_EOS // is a comment symbol, and everything past this character should be ignored }; class InPlaceParser @@ -110,10 +108,10 @@ public: Init(); } - InPlaceParser(char *data,int len) + InPlaceParser(char *data, int len) { Init(); - SetSourceData(data,len); + SetSourceData(data, len); } InPlaceParser(const char *fname) @@ -128,48 +126,47 @@ public: { mQuoteChar = 34; mData = 0; - mLen = 0; + mLen = 0; mMyAlloc = false; - for (int i=0; i<256; i++) + for (int i = 0; i < 256; i++) { mHard[i] = ST_DATA; - mHardString[i*2] = i; - mHardString[i*2+1] = 0; + mHardString[i * 2] = i; + mHardString[i * 2 + 1] = 0; } - mHard[0] = ST_EOS; + mHard[0] = ST_EOS; mHard[32] = ST_SOFT; - mHard[9] = ST_SOFT; + mHard[9] = ST_SOFT; mHard[13] = ST_SOFT; mHard[10] = ST_SOFT; } - void SetFile(const char *fname); // use this file as source data to parse. + void SetFile(const char *fname); // use this file as source data to parse. - void SetSourceData(char *data,int len) + void SetSourceData(char *data, int len) { mData = data; - mLen = len; + mLen = len; mMyAlloc = false; }; - int Parse(InPlaceParserInterface *callback); // returns true if entire file was parsed, false if it aborted for some reason + int Parse(InPlaceParserInterface *callback); // returns true if entire file was parsed, false if it aborted for some reason - int ProcessLine(int lineno,char *line,InPlaceParserInterface *callback); + int ProcessLine(int lineno, char *line, InPlaceParserInterface *callback); - const char ** GetArglist(char *source,int &count); // convert source string into an arg list, this is a destructive parse. + const char **GetArglist(char *source, int &count); // convert source string into an arg list, this is a destructive parse. - void SetHardSeparator(char c) // add a hard separator + void SetHardSeparator(char c) // add a hard separator { mHard[(int)c] = ST_HARD; } - void SetHard(char c) // add a hard separator + void SetHard(char c) // add a hard separator { mHard[(int)c] = ST_HARD; } - - void SetCommentSymbol(char c) // comment character, treated as 'end of string' + void SetCommentSymbol(char c) // comment character, treated as 'end of string' { mHard[(int)c] = ST_EOS; } @@ -179,12 +176,11 @@ public: mHard[(int)c] = ST_DATA; } - - void DefaultSymbols(void); // set up default symbols for hard seperator and comment symbol of the '#' character. + void DefaultSymbols(void); // set up default symbols for hard seperator and comment symbol of the '#' character. bool EOS(char c) { - if ( mHard[(int)c] == ST_EOS ) + if (mHard[(int)c] == ST_EOS) { return true; } @@ -197,20 +193,18 @@ public: } private: + inline char *AddHard(int &argc, const char **argv, char *foo); + inline bool IsHard(char c); + inline char *SkipSpaces(char *foo); + inline bool IsWhiteSpace(char c); + inline bool IsNonSeparator(char c); // non seperator,neither hard nor soft - - inline char * AddHard(int &argc,const char **argv,char *foo); - inline bool IsHard(char c); - inline char * SkipSpaces(char *foo); - inline bool IsWhiteSpace(char c); - inline bool IsNonSeparator(char c); // non seperator,neither hard nor soft - - bool mMyAlloc; // whether or not *I* allocated the buffer and am responsible for deleting it. - char *mData; // ascii data to parse. - int mLen; // length of data - SeparatorType mHard[256]; - char mHardString[256*2]; - char mQuoteChar; + bool mMyAlloc; // whether or not *I* allocated the buffer and am responsible for deleting it. + char *mData; // ascii data to parse. + int mLen; // length of data + SeparatorType mHard[256]; + char mHardString[256 * 2]; + char mQuoteChar; }; /*******************************************************************/ @@ -218,33 +212,32 @@ private: /*******************************************************************/ void InPlaceParser::SetFile(const char *fname) { - if ( mMyAlloc ) + if (mMyAlloc) { free(mData); } mData = 0; - mLen = 0; + mLen = 0; mMyAlloc = false; - - FILE *fph = fopen(fname,"rb"); - if ( fph ) + FILE *fph = fopen(fname, "rb"); + if (fph) { - fseek(fph,0L,SEEK_END); + fseek(fph, 0L, SEEK_END); mLen = ftell(fph); - fseek(fph,0L,SEEK_SET); - if ( mLen ) + fseek(fph, 0L, SEEK_SET); + if (mLen) { - mData = (char *) malloc(sizeof(char)*(mLen+1)); + mData = (char *)malloc(sizeof(char) * (mLen + 1)); int ok = fread(mData, mLen, 1, fph); - if ( !ok ) + if (!ok) { free(mData); mData = 0; } else { - mData[mLen] = 0; // zero byte terminate end of file marker. + mData[mLen] = 0; // zero byte terminate end of file marker. mMyAlloc = true; } } @@ -254,7 +247,7 @@ void InPlaceParser::SetFile(const char *fname) InPlaceParser::~InPlaceParser(void) { - if ( mMyAlloc ) + if (mMyAlloc) { free(mData); } @@ -267,12 +260,12 @@ bool InPlaceParser::IsHard(char c) return mHard[(int)c] == ST_HARD; } -char * InPlaceParser::AddHard(int &argc,const char **argv,char *foo) +char *InPlaceParser::AddHard(int &argc, const char **argv, char *foo) { - while ( IsHard(*foo) ) + while (IsHard(*foo)) { - const char *hard = &mHardString[*foo*2]; - if ( argc < MAXARGS ) + const char *hard = &mHardString[*foo * 2]; + if (argc < MAXARGS) { argv[argc++] = hard; } @@ -281,25 +274,24 @@ char * InPlaceParser::AddHard(int &argc,const char **argv,char *foo) return foo; } -bool InPlaceParser::IsWhiteSpace(char c) +bool InPlaceParser::IsWhiteSpace(char c) { return mHard[(int)c] == ST_SOFT; } -char * InPlaceParser::SkipSpaces(char *foo) +char *InPlaceParser::SkipSpaces(char *foo) { - while ( !EOS(*foo) && IsWhiteSpace(*foo) ) foo++; + while (!EOS(*foo) && IsWhiteSpace(*foo)) foo++; return foo; } bool InPlaceParser::IsNonSeparator(char c) { - if ( !IsHard(c) && !IsWhiteSpace(c) && c != 0 ) return true; + if (!IsHard(c) && !IsWhiteSpace(c) && c != 0) return true; return false; } - -int InPlaceParser::ProcessLine(int lineno,char *line,InPlaceParserInterface *callback) +int InPlaceParser::ProcessLine(int lineno, char *line, InPlaceParserInterface *callback) { int ret = 0; @@ -308,66 +300,64 @@ int InPlaceParser::ProcessLine(int lineno,char *line,InPlaceParserInterface *cal char *foo = line; - while ( !EOS(*foo) && argc < MAXARGS ) + while (!EOS(*foo) && argc < MAXARGS) { + foo = SkipSpaces(foo); // skip any leading spaces - foo = SkipSpaces(foo); // skip any leading spaces + if (EOS(*foo)) break; - if ( EOS(*foo) ) break; - - if ( *foo == mQuoteChar ) // if it is an open quote + if (*foo == mQuoteChar) // if it is an open quote { foo++; - if ( argc < MAXARGS ) + if (argc < MAXARGS) { argv[argc++] = foo; } - while ( !EOS(*foo) && *foo != mQuoteChar ) foo++; - if ( !EOS(*foo) ) + while (!EOS(*foo) && *foo != mQuoteChar) foo++; + if (!EOS(*foo)) { - *foo = 0; // replace close quote with zero byte EOS + *foo = 0; // replace close quote with zero byte EOS foo++; } } else { + foo = AddHard(argc, argv, foo); // add any hard separators, skip any spaces - foo = AddHard(argc,argv,foo); // add any hard separators, skip any spaces - - if ( IsNonSeparator(*foo) ) // add non-hard argument. + if (IsNonSeparator(*foo)) // add non-hard argument. { - bool quote = false; - if ( *foo == mQuoteChar ) + bool quote = false; + if (*foo == mQuoteChar) { foo++; quote = true; } - if ( argc < MAXARGS ) + if (argc < MAXARGS) { argv[argc++] = foo; } - if ( quote ) + if (quote) { - while (*foo && *foo != mQuoteChar ) foo++; - if ( *foo ) *foo = 32; + while (*foo && *foo != mQuoteChar) foo++; + if (*foo) *foo = 32; } // continue..until we hit an eos .. - while ( !EOS(*foo) ) // until we hit EOS + while (!EOS(*foo)) // until we hit EOS { - if ( IsWhiteSpace(*foo) ) // if we hit a space, stomp a zero byte, and exit + if (IsWhiteSpace(*foo)) // if we hit a space, stomp a zero byte, and exit { *foo = 0; foo++; break; } - else if ( IsHard(*foo) ) // if we hit a hard separator, stomp a zero byte and store the hard separator argument + else if (IsHard(*foo)) // if we hit a hard separator, stomp a zero byte and store the hard separator argument { - const char *hard = &mHardString[*foo*2]; + const char *hard = &mHardString[*foo * 2]; *foo = 0; - if ( argc < MAXARGS ) + if (argc < MAXARGS) { argv[argc++] = hard; } @@ -375,47 +365,46 @@ int InPlaceParser::ProcessLine(int lineno,char *line,InPlaceParserInterface *cal break; } foo++; - } // end of while loop... + } // end of while loop... } } } - if ( argc ) + if (argc) { - ret = callback->ParseLine(lineno, argc, argv ); + ret = callback->ParseLine(lineno, argc, argv); } return ret; } -int InPlaceParser::Parse(InPlaceParserInterface *callback) // returns true if entire file was parsed, false if it aborted for some reason +int InPlaceParser::Parse(InPlaceParserInterface *callback) // returns true if entire file was parsed, false if it aborted for some reason { - assert( callback ); - if ( !mData ) return 0; + assert(callback); + if (!mData) return 0; int ret = 0; int lineno = 0; - char *foo = mData; + char *foo = mData; char *begin = foo; - - while ( *foo ) + while (*foo) { - if ( *foo == 10 || *foo == 13 ) + if (*foo == 10 || *foo == 13) { lineno++; *foo = 0; - if ( *begin ) // if there is any data to parse at all... + if (*begin) // if there is any data to parse at all... { - int v = ProcessLine(lineno,begin,callback); - if ( v ) ret = v; + int v = ProcessLine(lineno, begin, callback); + if (v) ret = v; } foo++; - if ( *foo == 10 ) foo++; // skip line feed, if it is in the carraige-return line-feed format... + if (*foo == 10) foo++; // skip line feed, if it is in the carraige-return line-feed format... begin = foo; } else @@ -424,14 +413,13 @@ int InPlaceParser::Parse(InPlaceParserInterface *callback) // returns true if e } } - lineno++; // lasst line. + lineno++; // lasst line. - int v = ProcessLine(lineno,begin,callback); - if ( v ) ret = v; + int v = ProcessLine(lineno, begin, callback); + if (v) ret = v; return ret; } - void InPlaceParser::DefaultSymbols(void) { SetHardSeparator(','); @@ -445,8 +433,7 @@ void InPlaceParser::DefaultSymbols(void) SetCommentSymbol('#'); } - -const char ** InPlaceParser::GetArglist(char *line,int &count) // convert source string into an arg list, this is a destructive parse. +const char **InPlaceParser::GetArglist(char *line, int &count) // convert source string into an arg list, this is a destructive parse. { const char **ret = 0; @@ -455,66 +442,64 @@ const char ** InPlaceParser::GetArglist(char *line,int &count) // convert source char *foo = line; - while ( !EOS(*foo) && argc < MAXARGS ) + while (!EOS(*foo) && argc < MAXARGS) { + foo = SkipSpaces(foo); // skip any leading spaces - foo = SkipSpaces(foo); // skip any leading spaces + if (EOS(*foo)) break; - if ( EOS(*foo) ) break; - - if ( *foo == mQuoteChar ) // if it is an open quote + if (*foo == mQuoteChar) // if it is an open quote { foo++; - if ( argc < MAXARGS ) + if (argc < MAXARGS) { argv[argc++] = foo; } - while ( !EOS(*foo) && *foo != mQuoteChar ) foo++; - if ( !EOS(*foo) ) + while (!EOS(*foo) && *foo != mQuoteChar) foo++; + if (!EOS(*foo)) { - *foo = 0; // replace close quote with zero byte EOS + *foo = 0; // replace close quote with zero byte EOS foo++; } } else { + foo = AddHard(argc, argv, foo); // add any hard separators, skip any spaces - foo = AddHard(argc,argv,foo); // add any hard separators, skip any spaces - - if ( IsNonSeparator(*foo) ) // add non-hard argument. + if (IsNonSeparator(*foo)) // add non-hard argument. { - bool quote = false; - if ( *foo == mQuoteChar ) + bool quote = false; + if (*foo == mQuoteChar) { foo++; quote = true; } - if ( argc < MAXARGS ) + if (argc < MAXARGS) { argv[argc++] = foo; } - if ( quote ) + if (quote) { - while (*foo && *foo != mQuoteChar ) foo++; - if ( *foo ) *foo = 32; + while (*foo && *foo != mQuoteChar) foo++; + if (*foo) *foo = 32; } // continue..until we hit an eos .. - while ( !EOS(*foo) ) // until we hit EOS + while (!EOS(*foo)) // until we hit EOS { - if ( IsWhiteSpace(*foo) ) // if we hit a space, stomp a zero byte, and exit + if (IsWhiteSpace(*foo)) // if we hit a space, stomp a zero byte, and exit { *foo = 0; foo++; break; } - else if ( IsHard(*foo) ) // if we hit a hard separator, stomp a zero byte and store the hard separator argument + else if (IsHard(*foo)) // if we hit a hard separator, stomp a zero byte and store the hard separator argument { - const char *hard = &mHardString[*foo*2]; + const char *hard = &mHardString[*foo * 2]; *foo = 0; - if ( argc < MAXARGS ) + if (argc < MAXARGS) { argv[argc++] = hard; } @@ -522,13 +507,13 @@ const char ** InPlaceParser::GetArglist(char *line,int &count) // convert source break; } foo++; - } // end of while loop... + } // end of while loop... } } } count = argc; - if ( argc ) + if (argc) { ret = argv; } @@ -543,186 +528,176 @@ const char ** InPlaceParser::GetArglist(char *line,int &count) // convert source class GeometryVertex { public: - float mPos[3]; - float mNormal[3]; - float mTexel[2]; + float mPos[3]; + float mNormal[3]; + float mTexel[2]; }; - class GeometryInterface { public: + virtual void NodeTriangle(const GeometryVertex *v1, const GeometryVertex *v2, const GeometryVertex *v3) {} - virtual void NodeTriangle(const GeometryVertex *v1,const GeometryVertex *v2,const GeometryVertex *v3) {} - - virtual ~GeometryInterface () {} + virtual ~GeometryInterface() {} }; - /*******************************************************************/ /******************** Obj.h ********************************/ /*******************************************************************/ - class OBJ : public InPlaceParserInterface { public: - int LoadMesh(const char *fname,GeometryInterface *callback); - int ParseLine(int lineno,int argc,const char **argv); // return TRUE to continue parsing, return FALSE to abort parsing process + int LoadMesh(const char *fname, GeometryInterface *callback); + int ParseLine(int lineno, int argc, const char **argv); // return TRUE to continue parsing, return FALSE to abort parsing process private: + void getVertex(GeometryVertex &v, const char *face) const; - void getVertex(GeometryVertex &v,const char *face) const; + FloatVector mVerts; + FloatVector mTexels; + FloatVector mNormals; - FloatVector mVerts; - FloatVector mTexels; - FloatVector mNormals; - - GeometryInterface *mCallback; + GeometryInterface *mCallback; }; - /*******************************************************************/ /******************** Obj.cpp ********************************/ /*******************************************************************/ -int OBJ::LoadMesh(const char *fname,GeometryInterface *iface) +int OBJ::LoadMesh(const char *fname, GeometryInterface *iface) { - int ret = 0; + int ret = 0; - mVerts.clear(); - mTexels.clear(); - mNormals.clear(); + mVerts.clear(); + mTexels.clear(); + mNormals.clear(); - mCallback = iface; + mCallback = iface; - InPlaceParser ipp(fname); + InPlaceParser ipp(fname); - ipp.Parse(this); + ipp.Parse(this); - - return ret; + return ret; } //static const char * GetArg(const char **argv,int i,int argc) //{ - // const char * ret = 0; - // if ( i < argc ) ret = argv[i]; - // return ret; +// const char * ret = 0; +// if ( i < argc ) ret = argv[i]; +// return ret; //} -void OBJ::getVertex(GeometryVertex &v,const char *face) const +void OBJ::getVertex(GeometryVertex &v, const char *face) const { - v.mPos[0] = 0; - v.mPos[1] = 0; - v.mPos[2] = 0; + v.mPos[0] = 0; + v.mPos[1] = 0; + v.mPos[2] = 0; - v.mTexel[0] = 0; - v.mTexel[1] = 0; + v.mTexel[0] = 0; + v.mTexel[1] = 0; - v.mNormal[0] = 0; - v.mNormal[1] = 1; - v.mNormal[2] = 0; + v.mNormal[0] = 0; + v.mNormal[1] = 1; + v.mNormal[2] = 0; - int index = atoi( face )-1; + int index = atoi(face) - 1; - const char *texel = strstr(face,"/"); + const char *texel = strstr(face, "/"); - if ( texel ) - { - int tindex = atoi( texel+1) - 1; + if (texel) + { + int tindex = atoi(texel + 1) - 1; - if ( tindex >=0 && tindex < (int)(mTexels.size()/2) ) - { - const float *t = &mTexels[tindex*2]; + if (tindex >= 0 && tindex < (int)(mTexels.size() / 2)) + { + const float *t = &mTexels[tindex * 2]; - v.mTexel[0] = t[0]; - v.mTexel[1] = t[1]; + v.mTexel[0] = t[0]; + v.mTexel[1] = t[1]; + } - } + const char *normal = strstr(texel + 1, "/"); + if (normal) + { + int nindex = atoi(normal + 1) - 1; - const char *normal = strstr(texel+1,"/"); - if ( normal ) - { - int nindex = atoi( normal+1 ) - 1; + if (nindex >= 0 && nindex < (int)(mNormals.size() / 3)) + { + const float *n = &mNormals[nindex * 3]; - if (nindex >= 0 && nindex < (int)(mNormals.size()/3) ) - { - const float *n = &mNormals[nindex*3]; + v.mNormal[0] = n[0]; + v.mNormal[1] = n[1]; + v.mNormal[2] = n[2]; + } + } + } - v.mNormal[0] = n[0]; - v.mNormal[1] = n[1]; - v.mNormal[2] = n[2]; - } - } - } - - if ( index >= 0 && index < (int)(mVerts.size()/3) ) - { - - const float *p = &mVerts[index*3]; - - v.mPos[0] = p[0]; - v.mPos[1] = p[1]; - v.mPos[2] = p[2]; - } + if (index >= 0 && index < (int)(mVerts.size() / 3)) + { + const float *p = &mVerts[index * 3]; + v.mPos[0] = p[0]; + v.mPos[1] = p[1]; + v.mPos[2] = p[2]; + } } -int OBJ::ParseLine(int lineno,int argc,const char **argv) // return TRUE to continue parsing, return FALSE to abort parsing process +int OBJ::ParseLine(int lineno, int argc, const char **argv) // return TRUE to continue parsing, return FALSE to abort parsing process { - int ret = 0; + int ret = 0; - if ( argc >= 1 ) - { - const char *foo = argv[0]; - if ( *foo != '#' ) - { - if ( strcmp(argv[0],"v") == 0 && argc == 4 ) + if (argc >= 1) + { + const char *foo = argv[0]; + if (*foo != '#') + { + if (strcmp(argv[0], "v") == 0 && argc == 4) - //if ( stricmp(argv[0],"v") == 0 && argc == 4 ) - { - float vx = (float) atof( argv[1] ); - float vy = (float) atof( argv[2] ); - float vz = (float) atof( argv[3] ); - mVerts.push_back(vx); - mVerts.push_back(vy); - mVerts.push_back(vz); - } - else if ( strcmp(argv[0],"vt") == 0 && argc == 3 ) + //if ( stricmp(argv[0],"v") == 0 && argc == 4 ) + { + float vx = (float)atof(argv[1]); + float vy = (float)atof(argv[2]); + float vz = (float)atof(argv[3]); + mVerts.push_back(vx); + mVerts.push_back(vy); + mVerts.push_back(vz); + } + else if (strcmp(argv[0], "vt") == 0 && argc == 3) - // else if ( stricmp(argv[0],"vt") == 0 && argc == 3 ) - { - float tx = (float) atof( argv[1] ); - float ty = (float) atof( argv[2] ); - mTexels.push_back(tx); - mTexels.push_back(ty); - } - // else if ( stricmp(argv[0],"vn") == 0 && argc == 4 ) + // else if ( stricmp(argv[0],"vt") == 0 && argc == 3 ) + { + float tx = (float)atof(argv[1]); + float ty = (float)atof(argv[2]); + mTexels.push_back(tx); + mTexels.push_back(ty); + } + // else if ( stricmp(argv[0],"vn") == 0 && argc == 4 ) - else if ( strcmp(argv[0],"vn") == 0 && argc == 4 ) - { - float normalx = (float) atof(argv[1]); - float normaly = (float) atof(argv[2]); - float normalz = (float) atof(argv[3]); - mNormals.push_back(normalx); - mNormals.push_back(normaly); - mNormals.push_back(normalz); - } -// else if ( stricmp(argv[0],"f") == 0 && argc >= 4 ) + else if (strcmp(argv[0], "vn") == 0 && argc == 4) + { + float normalx = (float)atof(argv[1]); + float normaly = (float)atof(argv[2]); + float normalz = (float)atof(argv[3]); + mNormals.push_back(normalx); + mNormals.push_back(normaly); + mNormals.push_back(normalz); + } + // else if ( stricmp(argv[0],"f") == 0 && argc >= 4 ) - else if ( strcmp(argv[0],"f") == 0 && argc >= 4 ) - { - GeometryVertex v[32]; + else if (strcmp(argv[0], "f") == 0 && argc >= 4) + { + GeometryVertex v[32]; - int vcount = argc-1; + int vcount = argc - 1; - for (int i=1; i p1( v[0].mPos ); @@ -742,119 +717,108 @@ int OBJ::ParseLine(int lineno,int argc,const char **argv) // return TRUE to con } #endif - mCallback->NodeTriangle(&v[0],&v[1],&v[2]); + mCallback->NodeTriangle(&v[0], &v[1], &v[2]); - if ( vcount >=3 ) // do the fan - { - for (int i=2; i<(vcount-1); i++) - { - mCallback->NodeTriangle(&v[0],&v[i],&v[i+1]); - } - } - - } - } - } - - return ret; -} - - - - -class BuildMesh : public GeometryInterface -{ -public: - - int getIndex(const float *p) - { - - int vcount = mVertices.size()/3; - - if(vcount>0) - { - //New MS STL library checks indices in debug build, so zero causes an assert if it is empty. - const float *v = &mVertices[0]; - - for (int i=0; i= 3) // do the fan + { + for (int i = 2; i < (vcount - 1); i++) + { + mCallback->NodeTriangle(&v[0], &v[i], &v[i + 1]); + } + } } } - - mVertices.push_back( p[0] ); - mVertices.push_back( p[1] ); - mVertices.push_back( p[2] ); - - return vcount; } - virtual void NodeTriangle(const GeometryVertex *v1,const GeometryVertex *v2,const GeometryVertex *v3) - { - mIndices.push_back( getIndex(v1->mPos) ); - mIndices.push_back( getIndex(v2->mPos) ); - mIndices.push_back( getIndex(v3->mPos) ); - } - - const FloatVector& GetVertices(void) const { return mVertices; }; - const IntVector& GetIndices(void) const { return mIndices; }; - -private: - FloatVector mVertices; - IntVector mIndices; -}; - - -WavefrontObj::WavefrontObj(void) -{ - mVertexCount = 0; - mTriCount = 0; - mIndices = 0; - mVertices = 0; -} - -WavefrontObj::~WavefrontObj(void) -{ - delete [] mIndices; - delete [] mVertices; -} - -unsigned int WavefrontObj::loadObj(const char *fname) // load a wavefront obj returns number of triangles that were loaded. Data is persists until the class is destructed. -{ - - unsigned int ret = 0; - - delete [] mVertices; - mVertices = 0; - delete [] mIndices; - mIndices = 0; - mVertexCount = 0; - mTriCount = 0; - - - BuildMesh bm; - - OBJ obj; - - obj.LoadMesh(fname,&bm); - - - const FloatVector &vlist = bm.GetVertices(); - const IntVector &indices = bm.GetIndices(); - if ( vlist.size() ) - { - mVertexCount = vlist.size()/3; - mVertices = new float[mVertexCount*3]; - memcpy( mVertices, &vlist[0], sizeof(float)*mVertexCount*3 ); - mTriCount = indices.size()/3; - mIndices = new int[mTriCount*3*sizeof(int)]; - memcpy(mIndices, &indices[0], sizeof(int)*mTriCount*3); - ret = mTriCount; - } - - return ret; } +class BuildMesh : public GeometryInterface +{ +public: + int getIndex(const float *p) + { + int vcount = mVertices.size() / 3; + + if (vcount > 0) + { + //New MS STL library checks indices in debug build, so zero causes an assert if it is empty. + const float *v = &mVertices[0]; + + for (int i = 0; i < vcount; i++) + { + if (v[0] == p[0] && v[1] == p[1] && v[2] == p[2]) return i; + v += 3; + } + } + + mVertices.push_back(p[0]); + mVertices.push_back(p[1]); + mVertices.push_back(p[2]); + + return vcount; + } + + virtual void NodeTriangle(const GeometryVertex *v1, const GeometryVertex *v2, const GeometryVertex *v3) + { + mIndices.push_back(getIndex(v1->mPos)); + mIndices.push_back(getIndex(v2->mPos)); + mIndices.push_back(getIndex(v3->mPos)); + } + + const FloatVector &GetVertices(void) const { return mVertices; }; + const IntVector &GetIndices(void) const { return mIndices; }; + +private: + FloatVector mVertices; + IntVector mIndices; +}; + +WavefrontObj::WavefrontObj(void) +{ + mVertexCount = 0; + mTriCount = 0; + mIndices = 0; + mVertices = 0; } + +WavefrontObj::~WavefrontObj(void) +{ + delete[] mIndices; + delete[] mVertices; +} + +unsigned int WavefrontObj::loadObj(const char *fname) // load a wavefront obj returns number of triangles that were loaded. Data is persists until the class is destructed. +{ + unsigned int ret = 0; + + delete[] mVertices; + mVertices = 0; + delete[] mIndices; + mIndices = 0; + mVertexCount = 0; + mTriCount = 0; + + BuildMesh bm; + + OBJ obj; + + obj.LoadMesh(fname, &bm); + + const FloatVector &vlist = bm.GetVertices(); + const IntVector &indices = bm.GetIndices(); + if (vlist.size()) + { + mVertexCount = vlist.size() / 3; + mVertices = new float[mVertexCount * 3]; + memcpy(mVertices, &vlist[0], sizeof(float) * mVertexCount * 3); + mTriCount = indices.size() / 3; + mIndices = new int[mTriCount * 3 * sizeof(int)]; + memcpy(mIndices, &indices[0], sizeof(int) * mTriCount * 3); + ret = mTriCount; + } + + return ret; +} + +} // namespace ConvexDecomposition diff --git a/Extras/ConvexDecomposition/cd_wavefront.h b/Extras/ConvexDecomposition/cd_wavefront.h index ba5f90bd5..e50a5853a 100644 --- a/Extras/ConvexDecomposition/cd_wavefront.h +++ b/Extras/ConvexDecomposition/cd_wavefront.h @@ -1,9 +1,7 @@ #ifndef CD_WAVEFRONT_OBJ_H - #define CD_WAVEFRONT_OBJ_H - /*---------------------------------------------------------------------- Copyright (c) 2004 Open Dynamics Framework Group www.physicstools.org @@ -38,25 +36,22 @@ // http://www.amillionpixels.us // - namespace ConvexDecomposition { - class WavefrontObj { public: + WavefrontObj(void); + ~WavefrontObj(void); - WavefrontObj(void); - ~WavefrontObj(void); + unsigned int loadObj(const char *fname); // load a wavefront obj returns number of triangles that were loaded. Data is persists until the class is destructed. - unsigned int loadObj(const char *fname); // load a wavefront obj returns number of triangles that were loaded. Data is persists until the class is destructed. - - int mVertexCount; - int mTriCount; - int *mIndices; - float *mVertices; + int mVertexCount; + int mTriCount; + int *mIndices; + float *mVertices; }; -} +} // namespace ConvexDecomposition #endif diff --git a/Extras/ConvexDecomposition/concavity.cpp b/Extras/ConvexDecomposition/concavity.cpp index 5827da293..023181a44 100644 --- a/Extras/ConvexDecomposition/concavity.cpp +++ b/Extras/ConvexDecomposition/concavity.cpp @@ -49,165 +49,156 @@ #include "splitplane.h" #include "ConvexDecomposition.h" - #define WSCALE 4 #define CONCAVE_THRESH 0.05f namespace ConvexDecomposition { - unsigned int getDebugColor(void) { static unsigned int colors[8] = - { - 0xFF0000, - 0x00FF00, - 0x0000FF, - 0xFFFF00, - 0x00FFFF, - 0xFF00FF, - 0xFFFFFF, - 0xFF8040 - }; + { + 0xFF0000, + 0x00FF00, + 0x0000FF, + 0xFFFF00, + 0x00FFFF, + 0xFF00FF, + 0xFFFFFF, + 0xFF8040}; static int count = 0; count++; - if ( count == 8 ) count = 0; + if (count == 8) count = 0; - assert( count >= 0 && count < 8 ); + assert(count >= 0 && count < 8); unsigned int color = colors[count]; - return color; - + return color; } class Wpoint { public: - Wpoint(const Vector3d &p,float w) - { - mPoint = p; - mWeight = w; - } + Wpoint(const Vector3d &p, float w) + { + mPoint = p; + mWeight = w; + } - Vector3d mPoint; - float mWeight; + Vector3d mPoint; + float mWeight; }; -typedef std::vector< Wpoint > WpointVector; +typedef std::vector WpointVector; - -static inline float DistToPt(const float *p,const float *plane) +static inline float DistToPt(const float *p, const float *plane) { float x = p[0]; float y = p[1]; float z = p[2]; - float d = x*plane[0] + y*plane[1] + z*plane[2] + plane[3]; + float d = x * plane[0] + y * plane[1] + z * plane[2] + plane[3]; return d; } - -static void intersect(const float *p1,const float *p2,float *split,const float *plane) +static void intersect(const float *p1, const float *p2, float *split, const float *plane) { + float dp1 = DistToPt(p1, plane); - float dp1 = DistToPt(p1,plane); + float dir[3]; - float dir[3]; + dir[0] = p2[0] - p1[0]; + dir[1] = p2[1] - p1[1]; + dir[2] = p2[2] - p1[2]; - dir[0] = p2[0] - p1[0]; - dir[1] = p2[1] - p1[1]; - dir[2] = p2[2] - p1[2]; + float dot1 = dir[0] * plane[0] + dir[1] * plane[1] + dir[2] * plane[2]; + float dot2 = dp1 - plane[3]; - float dot1 = dir[0]*plane[0] + dir[1]*plane[1] + dir[2]*plane[2]; - float dot2 = dp1 - plane[3]; + float t = -(plane[3] + dot2) / dot1; - float t = -(plane[3] + dot2 ) / dot1; - - split[0] = (dir[0]*t)+p1[0]; - split[1] = (dir[1]*t)+p1[1]; - split[2] = (dir[2]*t)+p1[2]; + split[0] = (dir[0] * t) + p1[0]; + split[1] = (dir[1] * t) + p1[1]; + split[2] = (dir[2] * t) + p1[2]; } - class CTri { public: - CTri(void) { }; + CTri(void){}; - CTri(const float *p1,const float *p2,const float *p3,unsigned int i1,unsigned int i2,unsigned int i3) - { - mProcessed = 0; - mI1 = i1; - mI2 = i2; - mI3 = i3; + CTri(const float *p1, const float *p2, const float *p3, unsigned int i1, unsigned int i2, unsigned int i3) + { + mProcessed = 0; + mI1 = i1; + mI2 = i2; + mI3 = i3; - mP1.Set(p1); - mP2.Set(p2); - mP3.Set(p3); + mP1.Set(p1); + mP2.Set(p2); + mP3.Set(p3); - mPlaneD = mNormal.ComputePlane(mP1,mP2,mP3); + mPlaneD = mNormal.ComputePlane(mP1, mP2, mP3); } - float Facing(const CTri &t) - { + float Facing(const CTri &t) + { float d = mNormal.Dot(t.mNormal); return d; - } + } - // clip this line segment against this triangle. - bool clip(const Vector3d &start,Vector3d &end) const - { - Vector3d sect; - - bool hit = lineIntersectsTriangle(start.Ptr(), end.Ptr(), mP1.Ptr(), mP2.Ptr(), mP3.Ptr(), sect.Ptr() ); - - if ( hit ) - { - end = sect; - } - return hit; - } - - bool Concave(const Vector3d &p,float &distance,Vector3d &n) const + // clip this line segment against this triangle. + bool clip(const Vector3d &start, Vector3d &end) const { - n.NearestPointInTriangle(p,mP1,mP2,mP3); + Vector3d sect; + + bool hit = lineIntersectsTriangle(start.Ptr(), end.Ptr(), mP1.Ptr(), mP2.Ptr(), mP3.Ptr(), sect.Ptr()); + + if (hit) + { + end = sect; + } + return hit; + } + + bool Concave(const Vector3d &p, float &distance, Vector3d &n) const + { + n.NearestPointInTriangle(p, mP1, mP2, mP3); distance = p.Distance(n); return true; } - void addTri(unsigned int *indices,unsigned int i1,unsigned int i2,unsigned int i3,unsigned int &tcount) const + void addTri(unsigned int *indices, unsigned int i1, unsigned int i2, unsigned int i3, unsigned int &tcount) const { - indices[tcount*3+0] = i1; - indices[tcount*3+1] = i2; - indices[tcount*3+2] = i3; + indices[tcount * 3 + 0] = i1; + indices[tcount * 3 + 1] = i2; + indices[tcount * 3 + 2] = i3; tcount++; } float getVolume(ConvexDecompInterface *callback) const { - unsigned int indices[8*3]; + unsigned int indices[8 * 3]; + unsigned int tcount = 0; - unsigned int tcount = 0; + addTri(indices, 0, 1, 2, tcount); + addTri(indices, 3, 4, 5, tcount); - addTri(indices,0,1,2,tcount); - addTri(indices,3,4,5,tcount); + addTri(indices, 0, 3, 4, tcount); + addTri(indices, 0, 4, 1, tcount); - addTri(indices,0,3,4,tcount); - addTri(indices,0,4,1,tcount); + addTri(indices, 1, 4, 5, tcount); + addTri(indices, 1, 5, 2, tcount); - addTri(indices,1,4,5,tcount); - addTri(indices,1,5,2,tcount); + addTri(indices, 0, 3, 5, tcount); + addTri(indices, 0, 5, 2, tcount); - addTri(indices,0,3,5,tcount); - addTri(indices,0,5,2,tcount); + const float *vertices = mP1.Ptr(); - const float *vertices = mP1.Ptr(); - - if ( callback ) + if (callback) { unsigned int color = getDebugColor(); @@ -228,139 +219,134 @@ public: callback->ConvexDebugTri(mP3.Ptr(), d3.Ptr(), d3.Ptr(),0x00FF00); #else - for (unsigned int i=0; iConvexDebugTri(p1,p2,p3,color); + const float *p1 = &vertices[i1 * 3]; + const float *p2 = &vertices[i2 * 3]; + const float *p3 = &vertices[i3 * 3]; + callback->ConvexDebugTri(p1, p2, p3, color); } #endif } - float v = computeMeshVolume(mP1.Ptr(), tcount, indices ); + float v = computeMeshVolume(mP1.Ptr(), tcount, indices); return v; - } - float raySect(const Vector3d &p,const Vector3d &dir,Vector3d §) const + float raySect(const Vector3d &p, const Vector3d &dir, Vector3d §) const { float plane[4]; - plane[0] = mNormal.x; - plane[1] = mNormal.y; - plane[2] = mNormal.z; - plane[3] = mPlaneD; + plane[0] = mNormal.x; + plane[1] = mNormal.y; + plane[2] = mNormal.z; + plane[3] = mPlaneD; - Vector3d dest = p+dir*100000; + Vector3d dest = p + dir * 100000; - intersect( p.Ptr(), dest.Ptr(), sect.Ptr(), plane ); - - return sect.Distance(p); // return the intersection distance. + intersect(p.Ptr(), dest.Ptr(), sect.Ptr(), plane); + return sect.Distance(p); // return the intersection distance. } - float planeDistance(const Vector3d &p) const - { + float planeDistance(const Vector3d &p) const + { float plane[4]; - plane[0] = mNormal.x; - plane[1] = mNormal.y; - plane[2] = mNormal.z; - plane[3] = mPlaneD; + plane[0] = mNormal.x; + plane[1] = mNormal.y; + plane[2] = mNormal.z; + plane[3] = mPlaneD; - return DistToPt( p.Ptr(), plane ); - - } + return DistToPt(p.Ptr(), plane); + } bool samePlane(const CTri &t) const { const float THRESH = 0.001f; - float dd = fabsf( t.mPlaneD - mPlaneD ); - if ( dd > THRESH ) return false; - dd = fabsf( t.mNormal.x - mNormal.x ); - if ( dd > THRESH ) return false; - dd = fabsf( t.mNormal.y - mNormal.y ); - if ( dd > THRESH ) return false; - dd = fabsf( t.mNormal.z - mNormal.z ); - if ( dd > THRESH ) return false; - return true; + float dd = fabsf(t.mPlaneD - mPlaneD); + if (dd > THRESH) return false; + dd = fabsf(t.mNormal.x - mNormal.x); + if (dd > THRESH) return false; + dd = fabsf(t.mNormal.y - mNormal.y); + if (dd > THRESH) return false; + dd = fabsf(t.mNormal.z - mNormal.z); + if (dd > THRESH) return false; + return true; } bool hasIndex(unsigned int i) const { - if ( i == mI1 || i == mI2 || i == mI3 ) return true; + if (i == mI1 || i == mI2 || i == mI3) return true; return false; } - bool sharesEdge(const CTri &t) const - { - bool ret = false; - unsigned int count = 0; + bool sharesEdge(const CTri &t) const + { + bool ret = false; + unsigned int count = 0; - if ( t.hasIndex(mI1) ) count++; - if ( t.hasIndex(mI2) ) count++; - if ( t.hasIndex(mI3) ) count++; + if (t.hasIndex(mI1)) count++; + if (t.hasIndex(mI2)) count++; + if (t.hasIndex(mI3)) count++; - if ( count >= 2 ) ret = true; + if (count >= 2) ret = true; - return ret; - } + return ret; + } - void debug(unsigned int color,ConvexDecompInterface *callback) - { - callback->ConvexDebugTri( mP1.Ptr(), mP2.Ptr(), mP3.Ptr(), color ); - callback->ConvexDebugTri( mP1.Ptr(), mP1.Ptr(), mNear1.Ptr(), 0xFF0000 ); - callback->ConvexDebugTri( mP2.Ptr(), mP2.Ptr(), mNear2.Ptr(), 0xFF0000 ); - callback->ConvexDebugTri( mP2.Ptr(), mP3.Ptr(), mNear3.Ptr(), 0xFF0000 ); - callback->ConvexDebugPoint( mNear1.Ptr(), 0.01f, 0xFF0000 ); - callback->ConvexDebugPoint( mNear2.Ptr(), 0.01f, 0xFF0000 ); - callback->ConvexDebugPoint( mNear3.Ptr(), 0.01f, 0xFF0000 ); - } + void debug(unsigned int color, ConvexDecompInterface *callback) + { + callback->ConvexDebugTri(mP1.Ptr(), mP2.Ptr(), mP3.Ptr(), color); + callback->ConvexDebugTri(mP1.Ptr(), mP1.Ptr(), mNear1.Ptr(), 0xFF0000); + callback->ConvexDebugTri(mP2.Ptr(), mP2.Ptr(), mNear2.Ptr(), 0xFF0000); + callback->ConvexDebugTri(mP2.Ptr(), mP3.Ptr(), mNear3.Ptr(), 0xFF0000); + callback->ConvexDebugPoint(mNear1.Ptr(), 0.01f, 0xFF0000); + callback->ConvexDebugPoint(mNear2.Ptr(), 0.01f, 0xFF0000); + callback->ConvexDebugPoint(mNear3.Ptr(), 0.01f, 0xFF0000); + } - float area(void) - { - float a = mConcavity*mP1.Area(mP2,mP3); - return a; - } + float area(void) + { + float a = mConcavity * mP1.Area(mP2, mP3); + return a; + } - void addWeighted(WpointVector &list,ConvexDecompInterface *callback) - { - - Wpoint p1(mP1,mC1); - Wpoint p2(mP2,mC2); - Wpoint p3(mP3,mC3); + void addWeighted(WpointVector &list, ConvexDecompInterface *callback) + { + Wpoint p1(mP1, mC1); + Wpoint p2(mP2, mC2); + Wpoint p3(mP3, mC3); Vector3d d1 = mNear1 - mP1; Vector3d d2 = mNear2 - mP2; Vector3d d3 = mNear3 - mP3; - d1*=WSCALE; - d2*=WSCALE; - d3*=WSCALE; + d1 *= WSCALE; + d2 *= WSCALE; + d3 *= WSCALE; d1 = d1 + mP1; d2 = d2 + mP2; - d3 = d3 + mP3; + d3 = d3 + mP3; - Wpoint p4(d1,mC1); - Wpoint p5(d2,mC2); - Wpoint p6(d3,mC3); + Wpoint p4(d1, mC1); + Wpoint p5(d2, mC2); + Wpoint p6(d3, mC3); - list.push_back(p1); - list.push_back(p2); - list.push_back(p3); + list.push_back(p1); + list.push_back(p2); + list.push_back(p3); - list.push_back(p4); - list.push_back(p5); - list.push_back(p6); + list.push_back(p4); + list.push_back(p5); + list.push_back(p6); #if 0 callback->ConvexDebugPoint(mP1.Ptr(),0.01f,0x00FF00); @@ -387,39 +373,35 @@ public: callback->ConvexDebugPoint( np3.Ptr(), 0.01F, 0XFF00FF ); #endif + } - - - } - - Vector3d mP1; - Vector3d mP2; - Vector3d mP3; - Vector3d mNear1; - Vector3d mNear2; - Vector3d mNear3; - Vector3d mNormal; - float mPlaneD; - float mConcavity; - float mC1; - float mC2; - float mC3; - unsigned int mI1; - unsigned int mI2; - unsigned int mI3; - int mProcessed; // already been added... + Vector3d mP1; + Vector3d mP2; + Vector3d mP3; + Vector3d mNear1; + Vector3d mNear2; + Vector3d mNear3; + Vector3d mNormal; + float mPlaneD; + float mConcavity; + float mC1; + float mC2; + float mC3; + unsigned int mI1; + unsigned int mI2; + unsigned int mI3; + int mProcessed; // already been added... }; -typedef std::vector< CTri > CTriVector; +typedef std::vector CTriVector; -bool featureMatch(CTri &m,const CTriVector &tris,ConvexDecompInterface *callback,const CTriVector &input_mesh) +bool featureMatch(CTri &m, const CTriVector &tris, ConvexDecompInterface *callback, const CTriVector &input_mesh) { + bool ret = false; - bool ret = false; + float neardot = 0.707f; - float neardot = 0.707f; - - m.mConcavity = 0; + m.mConcavity = 0; //gLog->Display("*********** FEATURE MATCH *************\r\n"); //gLog->Display("Plane: %0.4f,%0.4f,%0.4f %0.4f\r\n", m.mNormal.x, m.mNormal.y, m.mNormal.z, m.mPlaneD ); @@ -429,87 +411,81 @@ bool featureMatch(CTri &m,const CTriVector &tris,ConvexDecompInterface *callback CTri nearest; - - for (i=tris.begin(); i!=tris.end(); ++i) + for (i = tris.begin(); i != tris.end(); ++i) { const CTri &t = (*i); + //gLog->Display(" HullPlane: %0.4f,%0.4f,%0.4f %0.4f\r\n", t.mNormal.x, t.mNormal.y, t.mNormal.z, t.mPlaneD ); - //gLog->Display(" HullPlane: %0.4f,%0.4f,%0.4f %0.4f\r\n", t.mNormal.x, t.mNormal.y, t.mNormal.z, t.mPlaneD ); - - if ( t.samePlane(m) ) + if (t.samePlane(m)) { //gLog->Display("*** PLANE MATCH!!!\r\n"); ret = false; break; } - float dot = t.mNormal.Dot(m.mNormal); + float dot = t.mNormal.Dot(m.mNormal); - if ( dot > neardot ) - { + if (dot > neardot) + { + float d1 = t.planeDistance(m.mP1); + float d2 = t.planeDistance(m.mP2); + float d3 = t.planeDistance(m.mP3); - float d1 = t.planeDistance( m.mP1 ); - float d2 = t.planeDistance( m.mP2 ); - float d3 = t.planeDistance( m.mP3 ); + if (d1 > 0.001f || d2 > 0.001f || d3 > 0.001f) // can't be near coplaner! + { + neardot = dot; - if ( d1 > 0.001f || d2 > 0.001f || d3 > 0.001f ) // can't be near coplaner! - { + Vector3d n1, n2, n3; - neardot = dot; - - Vector3d n1,n2,n3; - - t.raySect( m.mP1, m.mNormal, m.mNear1 ); - t.raySect( m.mP2, m.mNormal, m.mNear2 ); - t.raySect( m.mP3, m.mNormal, m.mNear3 ); + t.raySect(m.mP1, m.mNormal, m.mNear1); + t.raySect(m.mP2, m.mNormal, m.mNear2); + t.raySect(m.mP3, m.mNormal, m.mNear3); nearest = t; - ret = true; - } - - } + ret = true; + } + } } - if ( ret ) + if (ret) { - if ( 0 ) - { - CTriVector::const_iterator i; - for (i=input_mesh.begin(); i!=input_mesh.end(); ++i) - { - const CTri &c = (*i); - if ( c.mI1 != m.mI1 && c.mI2 != m.mI2 && c.mI3 != m.mI3 ) - { - c.clip( m.mP1, m.mNear1 ); - c.clip( m.mP2, m.mNear2 ); - c.clip( m.mP3, m.mNear3 ); - } - } - } + if (0) + { + CTriVector::const_iterator i; + for (i = input_mesh.begin(); i != input_mesh.end(); ++i) + { + const CTri &c = (*i); + if (c.mI1 != m.mI1 && c.mI2 != m.mI2 && c.mI3 != m.mI3) + { + c.clip(m.mP1, m.mNear1); + c.clip(m.mP2, m.mNear2); + c.clip(m.mP3, m.mNear3); + } + } + } - //gLog->Display("*********************************************\r\n"); - //gLog->Display(" HullPlaneNearest: %0.4f,%0.4f,%0.4f %0.4f\r\n", nearest.mNormal.x, nearest.mNormal.y, nearest.mNormal.z, nearest.mPlaneD ); + //gLog->Display("*********************************************\r\n"); + //gLog->Display(" HullPlaneNearest: %0.4f,%0.4f,%0.4f %0.4f\r\n", nearest.mNormal.x, nearest.mNormal.y, nearest.mNormal.z, nearest.mPlaneD ); - m.mC1 = m.mP1.Distance( m.mNear1 ); - m.mC2 = m.mP2.Distance( m.mNear2 ); - m.mC3 = m.mP3.Distance( m.mNear3 ); + m.mC1 = m.mP1.Distance(m.mNear1); + m.mC2 = m.mP2.Distance(m.mNear2); + m.mC3 = m.mP3.Distance(m.mNear3); m.mConcavity = m.mC1; - if ( m.mC2 > m.mConcavity ) m.mConcavity = m.mC2; - if ( m.mC3 > m.mConcavity ) m.mConcavity = m.mC3; + if (m.mC2 > m.mConcavity) m.mConcavity = m.mC2; + if (m.mC3 > m.mConcavity) m.mConcavity = m.mC3; - #if 0 +#if 0 callback->ConvexDebugTri( m.mP1.Ptr(), m.mP2.Ptr(), m.mP3.Ptr(), 0x00FF00 ); callback->ConvexDebugTri( m.mNear1.Ptr(), m.mNear2.Ptr(), m.mNear3.Ptr(), 0xFF0000 ); callback->ConvexDebugTri( m.mP1.Ptr(), m.mP1.Ptr(), m.mNear1.Ptr(), 0xFFFF00 ); callback->ConvexDebugTri( m.mP2.Ptr(), m.mP2.Ptr(), m.mNear2.Ptr(), 0xFFFF00 ); callback->ConvexDebugTri( m.mP3.Ptr(), m.mP3.Ptr(), m.mNear3.Ptr(), 0xFFFF00 ); - #endif - +#endif } else { @@ -520,83 +496,78 @@ bool featureMatch(CTri &m,const CTriVector &tris,ConvexDecompInterface *callback return ret; } -bool isFeatureTri(CTri &t,CTriVector &flist,float fc,ConvexDecompInterface *callback,unsigned int color) +bool isFeatureTri(CTri &t, CTriVector &flist, float fc, ConvexDecompInterface *callback, unsigned int color) { - bool ret = false; + bool ret = false; - if ( t.mProcessed == 0 ) // if not already processed - { + if (t.mProcessed == 0) // if not already processed + { + float c = t.mConcavity / fc; // must be within 80% of the concavity of the parent. - float c = t.mConcavity / fc; // must be within 80% of the concavity of the parent. - - if ( c > 0.85f ) - { - // see if this triangle is a 'feature' triangle. Meaning it shares an - // edge with any existing feature triangle and is within roughly the same - // concavity of the parent. - if ( flist.size() ) + if (c > 0.85f) + { + // see if this triangle is a 'feature' triangle. Meaning it shares an + // edge with any existing feature triangle and is within roughly the same + // concavity of the parent. + if (flist.size()) { - CTriVector::iterator i; - for (i=flist.begin(); i!=flist.end(); ++i) - { - CTri &ftri = (*i); - if ( ftri.sharesEdge(t) ) - { - t.mProcessed = 2; // it is now part of a feature. - flist.push_back(t); // add it to the feature list. -// callback->ConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(),t.mP3.Ptr(), color ); - ret = true; - break; - } + CTriVector::iterator i; + for (i = flist.begin(); i != flist.end(); ++i) + { + CTri &ftri = (*i); + if (ftri.sharesEdge(t)) + { + t.mProcessed = 2; // it is now part of a feature. + flist.push_back(t); // add it to the feature list. + // callback->ConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(),t.mP3.Ptr(), color ); + ret = true; + break; + } } } else { t.mProcessed = 2; - flist.push_back(t); // add it to the feature list. -// callback->ConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(),t.mP3.Ptr(), color ); + flist.push_back(t); // add it to the feature list. + // callback->ConvexDebugTri( t.mP1.Ptr(), t.mP2.Ptr(),t.mP3.Ptr(), color ); ret = true; } - } - else - { - t.mProcessed = 1; // eliminated for this feature, but might be valid for the next one.. - } - - } - return ret; + } + else + { + t.mProcessed = 1; // eliminated for this feature, but might be valid for the next one.. + } + } + return ret; } float computeConcavity(unsigned int vcount, - const float *vertices, - unsigned int tcount, - const unsigned int *indices, - ConvexDecompInterface *callback, - float *plane, // plane equation to split on - float &volume) + const float *vertices, + unsigned int tcount, + const unsigned int *indices, + ConvexDecompInterface *callback, + float *plane, // plane equation to split on + float &volume) { - - float cret = 0; volume = 1; - HullResult result; - HullLibrary hl; - HullDesc desc; + HullResult result; + HullLibrary hl; + HullDesc desc; desc.mMaxFaces = 256; desc.mMaxVertices = 256; desc.SetHullFlag(QF_TRIANGLES); + desc.mVcount = vcount; + desc.mVertices = vertices; + desc.mVertexStride = sizeof(float) * 3; - desc.mVcount = vcount; - desc.mVertices = vertices; - desc.mVertexStride = sizeof(float)*3; + HullError ret = hl.CreateConvexHull(desc, result); - HullError ret = hl.CreateConvexHull(desc,result); - - if ( ret == QE_OK ) - { + if (ret == QE_OK) + { #if 0 float bmin[3]; float bmax[3]; @@ -612,7 +583,7 @@ float computeConcavity(unsigned int vcount, center.z = bmin[2] + dz*0.5f; #endif - volume = computeMeshVolume2( result.mOutputVertices, result.mNumFaces, result.mIndices ); + volume = computeMeshVolume2(result.mOutputVertices, result.mNumFaces, result.mIndices); #if 1 // ok..now..for each triangle on the original mesh.. @@ -621,87 +592,81 @@ float computeConcavity(unsigned int vcount, CTriVector tris; - for (unsigned int i=0; iConvexDebugTri(p1,p2,p3,0xFFFFFF); + // callback->ConvexDebugTri(p1,p2,p3,0xFFFFFF); - CTri t(p1,p2,p3,i1,i2,i3); // + CTri t(p1, p2, p3, i1, i2, i3); // tris.push_back(t); } - // we have not pre-computed the plane equation for each triangle in the convex hull.. + // we have not pre-computed the plane equation for each triangle in the convex hull.. float totalVolume = 0; - CTriVector ftris; // 'feature' triangles. + CTriVector ftris; // 'feature' triangles. const unsigned int *src = indices; + float maxc = 0; - float maxc=0; - - - if ( 1 ) + if (1) { - CTriVector input_mesh; - if ( 1 ) - { - const unsigned int *src = indices; - for (unsigned int i=0; i CONCAVE_THRESH ) + const unsigned int *src = indices; + for (unsigned int i = 0; i < tcount; i++) { + unsigned int i1 = *src++; + unsigned int i2 = *src++; + unsigned int i3 = *src++; - if ( t.mConcavity > maxc ) - { - maxc = t.mConcavity; - maxctri = t; - } + const float *p1 = &vertices[i1 * 3]; + const float *p2 = &vertices[i2 * 3]; + const float *p3 = &vertices[i3 * 3]; - float v = t.getVolume(0); - totalVolume+=v; - ftris.push_back(t); - } + CTri t(p1, p2, p3, i1, i2, i3); + input_mesh.push_back(t); + } + } + CTri maxctri; + + for (unsigned int i = 0; i < tcount; i++) + { + unsigned int i1 = *src++; + unsigned int i2 = *src++; + unsigned int i3 = *src++; + + const float *p1 = &vertices[i1 * 3]; + const float *p2 = &vertices[i2 * 3]; + const float *p3 = &vertices[i3 * 3]; + + CTri t(p1, p2, p3, i1, i2, i3); + + featureMatch(t, tris, callback, input_mesh); + + if (t.mConcavity > CONCAVE_THRESH) + { + if (t.mConcavity > maxc) + { + maxc = t.mConcavity; + maxctri = t; + } + + float v = t.getVolume(0); + totalVolume += v; + ftris.push_back(t); + } } } @@ -786,12 +751,11 @@ float computeConcavity(unsigned int vcount, cret = totalVolume; - hl.ReleaseResult(result); - } + hl.ReleaseResult(result); + } #endif return cret; } - -} +} // namespace ConvexDecomposition diff --git a/Extras/ConvexDecomposition/concavity.h b/Extras/ConvexDecomposition/concavity.h index 012f8a310..be5e7580e 100644 --- a/Extras/ConvexDecomposition/concavity.h +++ b/Extras/ConvexDecomposition/concavity.h @@ -36,25 +36,20 @@ // http://www.amillionpixels.us // - - namespace ConvexDecomposition { - class ConvexDecompInterface; // compute's how 'concave' this object is and returns the total volume of the // convex hull as well as the volume of the 'concavity' which was found. float computeConcavity(unsigned int vcount, - const float *vertices, - unsigned int tcount, - const unsigned int *indices, - ConvexDecompInterface *callback, - float *plane, - float &volume); - - -} + const float *vertices, + unsigned int tcount, + const unsigned int *indices, + ConvexDecompInterface *callback, + float *plane, + float &volume); +} // namespace ConvexDecomposition #endif diff --git a/Extras/ConvexDecomposition/fitsphere.cpp b/Extras/ConvexDecomposition/fitsphere.cpp index 53e6e6d76..a88ebfb7d 100644 --- a/Extras/ConvexDecomposition/fitsphere.cpp +++ b/Extras/ConvexDecomposition/fitsphere.cpp @@ -6,7 +6,6 @@ #include "fitsphere.h" - /*---------------------------------------------------------------------- Copyright (c) 2004 Open Dynamics Framework Group www.physicstools.org @@ -53,27 +52,26 @@ from "Graphics Gems", Academic Press, 1990 /* The abs() of all coordinates must be < BIGNUMBER */ /* Code written by Jack Ritter and Lyle Rains. */ -#define BIGNUMBER 100000000.0 /* hundred million */ +#define BIGNUMBER 100000000.0 /* hundred million */ -static inline void Set(float *n,float x,float y,float z) +static inline void Set(float *n, float x, float y, float z) { n[0] = x; n[1] = y; n[2] = z; } -static inline void Copy(float *dest,const float *source) +static inline void Copy(float *dest, const float *source) { dest[0] = source[0]; dest[1] = source[1]; dest[2] = source[2]; } -float computeBoundingSphere(unsigned int vcount,const float *points,float *center) +float computeBoundingSphere(unsigned int vcount, const float *points, float *center) { - - float mRadius; - float mRadius2; + float mRadius; + float mRadius2; float xmin[3]; float xmax[3]; @@ -84,119 +82,116 @@ float computeBoundingSphere(unsigned int vcount,const float *points,float *cente float dia1[3]; float dia2[3]; - /* FIRST PASS: find 6 minima/maxima points */ - Set(xmin,BIGNUMBER,BIGNUMBER,BIGNUMBER); - Set(xmax,-BIGNUMBER,-BIGNUMBER,-BIGNUMBER); - Set(ymin,BIGNUMBER,BIGNUMBER,BIGNUMBER); - Set(ymax,-BIGNUMBER,-BIGNUMBER,-BIGNUMBER); - Set(zmin,BIGNUMBER,BIGNUMBER,BIGNUMBER); - Set(zmax,-BIGNUMBER,-BIGNUMBER,-BIGNUMBER); + /* FIRST PASS: find 6 minima/maxima points */ + Set(xmin, BIGNUMBER, BIGNUMBER, BIGNUMBER); + Set(xmax, -BIGNUMBER, -BIGNUMBER, -BIGNUMBER); + Set(ymin, BIGNUMBER, BIGNUMBER, BIGNUMBER); + Set(ymax, -BIGNUMBER, -BIGNUMBER, -BIGNUMBER); + Set(zmin, BIGNUMBER, BIGNUMBER, BIGNUMBER); + Set(zmax, -BIGNUMBER, -BIGNUMBER, -BIGNUMBER); - for (unsigned i=0; ixmax[0]) - Copy(xmax,caller_p); - if (caller_p[1]ymax[1]) - Copy(ymax,caller_p); - if (caller_p[2]zmax[2]) - Copy(zmax,caller_p); + if (caller_p[0] < xmin[0]) + Copy(xmin, caller_p); /* New xminimum point */ + if (caller_p[0] > xmax[0]) + Copy(xmax, caller_p); + if (caller_p[1] < ymin[1]) + Copy(ymin, caller_p); + if (caller_p[1] > ymax[1]) + Copy(ymax, caller_p); + if (caller_p[2] < zmin[2]) + Copy(zmin, caller_p); + if (caller_p[2] > zmax[2]) + Copy(zmax, caller_p); } - /* Set xspan = distance between the 2 points xmin & xmax (squared) */ - float dx = xmax[0] - xmin[0]; - float dy = xmax[1] - xmin[1]; - float dz = xmax[2] - xmin[2]; - float xspan = dx*dx + dy*dy + dz*dz; + /* Set xspan = distance between the 2 points xmin & xmax (squared) */ + float dx = xmax[0] - xmin[0]; + float dy = xmax[1] - xmin[1]; + float dz = xmax[2] - xmin[2]; + float xspan = dx * dx + dy * dy + dz * dz; - /* Same for y & z spans */ - dx = ymax[0] - ymin[0]; - dy = ymax[1] - ymin[1]; - dz = ymax[2] - ymin[2]; - float yspan = dx*dx + dy*dy + dz*dz; + /* Same for y & z spans */ + dx = ymax[0] - ymin[0]; + dy = ymax[1] - ymin[1]; + dz = ymax[2] - ymin[2]; + float yspan = dx * dx + dy * dy + dz * dz; - dx = zmax[0] - zmin[0]; - dy = zmax[1] - zmin[1]; - dz = zmax[2] - zmin[2]; - float zspan = dx*dx + dy*dy + dz*dz; + dx = zmax[0] - zmin[0]; + dy = zmax[1] - zmin[1]; + dz = zmax[2] - zmin[2]; + float zspan = dx * dx + dy * dy + dz * dz; - /* Set points dia1 & dia2 to the maximally separated pair */ - Copy(dia1,xmin); - Copy(dia2,xmax); /* assume xspan biggest */ - float maxspan = xspan; + /* Set points dia1 & dia2 to the maximally separated pair */ + Copy(dia1, xmin); + Copy(dia2, xmax); /* assume xspan biggest */ + float maxspan = xspan; - if (yspan>maxspan) + if (yspan > maxspan) { - maxspan = yspan; - Copy(dia1,ymin); - Copy(dia2,ymax); + maxspan = yspan; + Copy(dia1, ymin); + Copy(dia2, ymax); } - if (zspan>maxspan) + if (zspan > maxspan) { - Copy(dia1,zmin); - Copy(dia2,zmax); + Copy(dia1, zmin); + Copy(dia2, zmax); } + /* dia1,dia2 is a diameter of initial sphere */ + /* calc initial center */ + center[0] = (dia1[0] + dia2[0]) * 0.5f; + center[1] = (dia1[1] + dia2[1]) * 0.5f; + center[2] = (dia1[2] + dia2[2]) * 0.5f; - /* dia1,dia2 is a diameter of initial sphere */ - /* calc initial center */ - center[0] = (dia1[0]+dia2[0])*0.5f; - center[1] = (dia1[1]+dia2[1])*0.5f; - center[2] = (dia1[2]+dia2[2])*0.5f; + /* calculate initial radius**2 and radius */ - /* calculate initial radius**2 and radius */ + dx = dia2[0] - center[0]; /* x component of radius vector */ + dy = dia2[1] - center[1]; /* y component of radius vector */ + dz = dia2[2] - center[2]; /* z component of radius vector */ - dx = dia2[0]-center[0]; /* x component of radius vector */ - dy = dia2[1]-center[1]; /* y component of radius vector */ - dz = dia2[2]-center[2]; /* z component of radius vector */ + mRadius2 = dx * dx + dy * dy + dz * dz; + mRadius = float(sqrt(mRadius2)); - mRadius2 = dx*dx + dy*dy + dz*dz; - mRadius = float(sqrt(mRadius2)); + /* SECOND PASS: increment current sphere */ - /* SECOND PASS: increment current sphere */ - - if ( 1 ) + if (1) { - for (unsigned i=0; i mRadius2) /* do r**2 test first */ - { /* this point is outside of current sphere */ - float old_to_p = float(sqrt(old_to_p_sq)); + if (old_to_p_sq > mRadius2) /* do r**2 test first */ + { /* this point is outside of current sphere */ + float old_to_p = float(sqrt(old_to_p_sq)); /* calc radius of new sphere */ - mRadius = (mRadius + old_to_p) * 0.5f; - mRadius2 = mRadius*mRadius; /* for next r**2 compare */ - float old_to_new = old_to_p - mRadius; + mRadius = (mRadius + old_to_p) * 0.5f; + mRadius2 = mRadius * mRadius; /* for next r**2 compare */ + float old_to_new = old_to_p - mRadius; - /* calc center of new sphere */ + /* calc center of new sphere */ - float recip = 1.0f /old_to_p; + float recip = 1.0f / old_to_p; - float cx = (mRadius*center[0] + old_to_new*caller_p[0]) * recip; - float cy = (mRadius*center[1] + old_to_new*caller_p[1]) * recip; - float cz = (mRadius*center[2] + old_to_new*caller_p[2]) * recip; + float cx = (mRadius * center[0] + old_to_new * caller_p[0]) * recip; + float cy = (mRadius * center[1] + old_to_new * caller_p[1]) * recip; + float cz = (mRadius * center[2] + old_to_new * caller_p[2]) * recip; - Set(center,cx,cy,cz); + Set(center, cx, cy, cz); } } } - return mRadius; + return mRadius; } - - diff --git a/Extras/ConvexDecomposition/fitsphere.h b/Extras/ConvexDecomposition/fitsphere.h index cd4a565c5..41d20dbd9 100644 --- a/Extras/ConvexDecomposition/fitsphere.h +++ b/Extras/ConvexDecomposition/fitsphere.h @@ -36,8 +36,6 @@ // http://www.amillionpixels.us // - - -float computeBoundingSphere(unsigned int vcount,const float *points,float *center); +float computeBoundingSphere(unsigned int vcount, const float *points, float *center); #endif diff --git a/Extras/ConvexDecomposition/float_math.cpp b/Extras/ConvexDecomposition/float_math.cpp index 38c699b59..bf16e7f00 100644 --- a/Extras/ConvexDecomposition/float_math.cpp +++ b/Extras/ConvexDecomposition/float_math.cpp @@ -6,7 +6,6 @@ #include #include - /*---------------------------------------------------------------------- Copyright (c) 2004 Open Dynamics Framework Group www.physicstools.org @@ -41,58 +40,53 @@ // http://www.amillionpixels.us // -void fm_inverseRT(const float *matrix,const float *pos,float *t) // inverse rotate translate the point. +void fm_inverseRT(const float *matrix, const float *pos, float *t) // inverse rotate translate the point. { - - float _x = pos[0] - matrix[3*4+0]; - float _y = pos[1] - matrix[3*4+1]; - float _z = pos[2] - matrix[3*4+2]; + float _x = pos[0] - matrix[3 * 4 + 0]; + float _y = pos[1] - matrix[3 * 4 + 1]; + float _z = pos[2] - matrix[3 * 4 + 2]; // Multiply inverse-translated source vector by inverted rotation transform - t[0] = (matrix[0*4+0] * _x) + (matrix[0*4+1] * _y) + (matrix[0*4+2] * _z); - t[1] = (matrix[1*4+0] * _x) + (matrix[1*4+1] * _y) + (matrix[1*4+2] * _z); - t[2] = (matrix[2*4+0] * _x) + (matrix[2*4+1] * _y) + (matrix[2*4+2] * _z); - + t[0] = (matrix[0 * 4 + 0] * _x) + (matrix[0 * 4 + 1] * _y) + (matrix[0 * 4 + 2] * _z); + t[1] = (matrix[1 * 4 + 0] * _x) + (matrix[1 * 4 + 1] * _y) + (matrix[1 * 4 + 2] * _z); + t[2] = (matrix[2 * 4 + 0] * _x) + (matrix[2 * 4 + 1] * _y) + (matrix[2 * 4 + 2] * _z); } - -void fm_identity(float *matrix) // set 4x4 matrix to identity. +void fm_identity(float *matrix) // set 4x4 matrix to identity. { - matrix[0*4+0] = 1; - matrix[1*4+1] = 1; - matrix[2*4+2] = 1; - matrix[3*4+3] = 1; + matrix[0 * 4 + 0] = 1; + matrix[1 * 4 + 1] = 1; + matrix[2 * 4 + 2] = 1; + matrix[3 * 4 + 3] = 1; - matrix[1*4+0] = 0; - matrix[2*4+0] = 0; - matrix[3*4+0] = 0; + matrix[1 * 4 + 0] = 0; + matrix[2 * 4 + 0] = 0; + matrix[3 * 4 + 0] = 0; - matrix[0*4+1] = 0; - matrix[2*4+1] = 0; - matrix[3*4+1] = 0; + matrix[0 * 4 + 1] = 0; + matrix[2 * 4 + 1] = 0; + matrix[3 * 4 + 1] = 0; - matrix[0*4+2] = 0; - matrix[1*4+2] = 0; - matrix[3*4+2] = 0; - - matrix[0*4+3] = 0; - matrix[1*4+3] = 0; - matrix[2*4+3] = 0; + matrix[0 * 4 + 2] = 0; + matrix[1 * 4 + 2] = 0; + matrix[3 * 4 + 2] = 0; + matrix[0 * 4 + 3] = 0; + matrix[1 * 4 + 3] = 0; + matrix[2 * 4 + 3] = 0; } -void fm_eulerMatrix(float ax,float ay,float az,float *matrix) // convert euler (in radians) to a dest 4x4 matrix (translation set to zero) +void fm_eulerMatrix(float ax, float ay, float az, float *matrix) // convert euler (in radians) to a dest 4x4 matrix (translation set to zero) { - float quat[4]; - fm_eulerToQuat(ax,ay,az,quat); - fm_quatToMatrix(quat,matrix); + float quat[4]; + fm_eulerToQuat(ax, ay, az, quat); + fm_quatToMatrix(quat, matrix); } -void fm_getAABB(unsigned int vcount,const float *points,unsigned int pstride,float *bmin,float *bmax) +void fm_getAABB(unsigned int vcount, const float *points, unsigned int pstride, float *bmin, float *bmax) { - - const unsigned char *source = (const unsigned char *) points; + const unsigned char *source = (const unsigned char *)points; bmin[0] = points[0]; bmin[1] = points[1]; @@ -102,29 +96,26 @@ void fm_getAABB(unsigned int vcount,const float *points,unsigned int pstride,flo bmax[1] = points[1]; bmax[2] = points[2]; + for (unsigned int i = 1; i < vcount; i++) + { + source += pstride; + const float *p = (const float *)source; - for (unsigned int i=1; i bmax[0] ) bmax[0] = p[0]; - if ( p[1] > bmax[1] ) bmax[1] = p[1]; - if ( p[2] > bmax[2] ) bmax[2] = p[2]; - - } + if (p[0] > bmax[0]) bmax[0] = p[0]; + if (p[1] > bmax[1]) bmax[1] = p[1]; + if (p[2] > bmax[2]) bmax[2] = p[2]; + } } - -void fm_eulerToQuat(float roll,float pitch,float yaw,float *quat) // convert euler angles to quaternion. +void fm_eulerToQuat(float roll, float pitch, float yaw, float *quat) // convert euler angles to quaternion. { - roll *= 0.5f; + roll *= 0.5f; pitch *= 0.5f; - yaw *= 0.5f; + yaw *= 0.5f; float cr = cosf(roll); float cp = cosf(pitch); @@ -139,119 +130,109 @@ void fm_eulerToQuat(float roll,float pitch,float yaw,float *quat) // convert eul float spcy = sp * cy; float cpsy = cp * sy; - quat[0] = ( sr * cpcy - cr * spsy); - quat[1] = ( cr * spcy + sr * cpsy); - quat[2] = ( cr * cpsy - sr * spcy); - quat[3] = cr * cpcy + sr * spsy; + quat[0] = (sr * cpcy - cr * spsy); + quat[1] = (cr * spcy + sr * cpsy); + quat[2] = (cr * cpsy - sr * spcy); + quat[3] = cr * cpcy + sr * spsy; } -void fm_quatToMatrix(const float *quat,float *matrix) // convert quaterinion rotation to matrix, zeros out the translation component. +void fm_quatToMatrix(const float *quat, float *matrix) // convert quaterinion rotation to matrix, zeros out the translation component. { + float xx = quat[0] * quat[0]; + float yy = quat[1] * quat[1]; + float zz = quat[2] * quat[2]; + float xy = quat[0] * quat[1]; + float xz = quat[0] * quat[2]; + float yz = quat[1] * quat[2]; + float wx = quat[3] * quat[0]; + float wy = quat[3] * quat[1]; + float wz = quat[3] * quat[2]; - float xx = quat[0]*quat[0]; - float yy = quat[1]*quat[1]; - float zz = quat[2]*quat[2]; - float xy = quat[0]*quat[1]; - float xz = quat[0]*quat[2]; - float yz = quat[1]*quat[2]; - float wx = quat[3]*quat[0]; - float wy = quat[3]*quat[1]; - float wz = quat[3]*quat[2]; + matrix[0 * 4 + 0] = 1 - 2 * (yy + zz); + matrix[1 * 4 + 0] = 2 * (xy - wz); + matrix[2 * 4 + 0] = 2 * (xz + wy); - matrix[0*4+0] = 1 - 2 * ( yy + zz ); - matrix[1*4+0] = 2 * ( xy - wz ); - matrix[2*4+0] = 2 * ( xz + wy ); + matrix[0 * 4 + 1] = 2 * (xy + wz); + matrix[1 * 4 + 1] = 1 - 2 * (xx + zz); + matrix[2 * 4 + 1] = 2 * (yz - wx); - matrix[0*4+1] = 2 * ( xy + wz ); - matrix[1*4+1] = 1 - 2 * ( xx + zz ); - matrix[2*4+1] = 2 * ( yz - wx ); - - matrix[0*4+2] = 2 * ( xz - wy ); - matrix[1*4+2] = 2 * ( yz + wx ); - matrix[2*4+2] = 1 - 2 * ( xx + yy ); - - matrix[3*4+0] = matrix[3*4+1] = matrix[3*4+2] = 0.0f; - matrix[0*4+3] = matrix[1*4+3] = matrix[2*4+3] = 0.0f; - matrix[3*4+3] = 1.0f; + matrix[0 * 4 + 2] = 2 * (xz - wy); + matrix[1 * 4 + 2] = 2 * (yz + wx); + matrix[2 * 4 + 2] = 1 - 2 * (xx + yy); + matrix[3 * 4 + 0] = matrix[3 * 4 + 1] = matrix[3 * 4 + 2] = 0.0f; + matrix[0 * 4 + 3] = matrix[1 * 4 + 3] = matrix[2 * 4 + 3] = 0.0f; + matrix[3 * 4 + 3] = 1.0f; } - -void fm_quatRotate(const float *quat,const float *v,float *r) // rotate a vector directly by a quaternion. +void fm_quatRotate(const float *quat, const float *v, float *r) // rotate a vector directly by a quaternion. { - float left[4]; + float left[4]; - left[0] = quat[3]*v[0] + quat[1]*v[2] - v[1]*quat[2]; - left[1] = quat[3]*v[1] + quat[2]*v[0] - v[2]*quat[0]; - left[2] = quat[3]*v[2] + quat[0]*v[1] - v[0]*quat[1]; - left[3] = - quat[0]*v[0] - quat[1]*v[1] - quat[2]*v[2]; - - r[0] = (left[3]*-quat[0]) + (quat[3]*left[0]) + (left[1]*-quat[2]) - (-quat[1]*left[2]); - r[1] = (left[3]*-quat[1]) + (quat[3]*left[1]) + (left[2]*-quat[0]) - (-quat[2]*left[0]); - r[2] = (left[3]*-quat[2]) + (quat[3]*left[2]) + (left[0]*-quat[1]) - (-quat[0]*left[1]); + left[0] = quat[3] * v[0] + quat[1] * v[2] - v[1] * quat[2]; + left[1] = quat[3] * v[1] + quat[2] * v[0] - v[2] * quat[0]; + left[2] = quat[3] * v[2] + quat[0] * v[1] - v[0] * quat[1]; + left[3] = -quat[0] * v[0] - quat[1] * v[1] - quat[2] * v[2]; + r[0] = (left[3] * -quat[0]) + (quat[3] * left[0]) + (left[1] * -quat[2]) - (-quat[1] * left[2]); + r[1] = (left[3] * -quat[1]) + (quat[3] * left[1]) + (left[2] * -quat[0]) - (-quat[2] * left[0]); + r[2] = (left[3] * -quat[2]) + (quat[3] * left[2]) + (left[0] * -quat[1]) - (-quat[0] * left[1]); } - -void fm_getTranslation(const float *matrix,float *t) +void fm_getTranslation(const float *matrix, float *t) { - t[0] = matrix[3*4+0]; - t[1] = matrix[3*4+1]; - t[2] = matrix[3*4+2]; + t[0] = matrix[3 * 4 + 0]; + t[1] = matrix[3 * 4 + 1]; + t[2] = matrix[3 * 4 + 2]; } -void fm_matrixToQuat(const float *matrix,float *quat) // convert the 3x3 portion of a 4x4 matrix into a quaterion as x,y,z,w +void fm_matrixToQuat(const float *matrix, float *quat) // convert the 3x3 portion of a 4x4 matrix into a quaterion as x,y,z,w { - - float tr = matrix[0*4+0] + matrix[1*4+1] + matrix[2*4+2]; + float tr = matrix[0 * 4 + 0] + matrix[1 * 4 + 1] + matrix[2 * 4 + 2]; // check the diagonal - if (tr > 0.0f ) + if (tr > 0.0f) { - float s = (float) sqrt ( (double) (tr + 1.0f) ); + float s = (float)sqrt((double)(tr + 1.0f)); quat[3] = s * 0.5f; s = 0.5f / s; - quat[0] = (matrix[1*4+2] - matrix[2*4+1]) * s; - quat[1] = (matrix[2*4+0] - matrix[0*4+2]) * s; - quat[2] = (matrix[0*4+1] - matrix[1*4+0]) * s; - + quat[0] = (matrix[1 * 4 + 2] - matrix[2 * 4 + 1]) * s; + quat[1] = (matrix[2 * 4 + 0] - matrix[0 * 4 + 2]) * s; + quat[2] = (matrix[0 * 4 + 1] - matrix[1 * 4 + 0]) * s; } else { // diagonal is negative int nxt[3] = {1, 2, 0}; - float qa[4]; + float qa[4]; int i = 0; - if (matrix[1*4+1] > matrix[0*4+0]) i = 1; - if (matrix[2*4+2] > matrix[i*4+i]) i = 2; + if (matrix[1 * 4 + 1] > matrix[0 * 4 + 0]) i = 1; + if (matrix[2 * 4 + 2] > matrix[i * 4 + i]) i = 2; int j = nxt[i]; int k = nxt[j]; - float s = sqrtf ( ((matrix[i*4+i] - (matrix[j*4+j] + matrix[k*4+k])) + 1.0f) ); + float s = sqrtf(((matrix[i * 4 + i] - (matrix[j * 4 + j] + matrix[k * 4 + k])) + 1.0f)); qa[i] = s * 0.5f; - if (s != 0.0f ) s = 0.5f / s; + if (s != 0.0f) s = 0.5f / s; - qa[3] = (matrix[j*4+k] - matrix[k*4+j]) * s; - qa[j] = (matrix[i*4+j] + matrix[j*4+i]) * s; - qa[k] = (matrix[i*4+k] + matrix[k*4+i]) * s; + qa[3] = (matrix[j * 4 + k] - matrix[k * 4 + j]) * s; + qa[j] = (matrix[i * 4 + j] + matrix[j * 4 + i]) * s; + qa[k] = (matrix[i * 4 + k] + matrix[k * 4 + i]) * s; quat[0] = qa[0]; quat[1] = qa[1]; quat[2] = qa[2]; quat[3] = qa[3]; } - - } - -float fm_sphereVolume(float radius) // return's the volume of a sphere of this radius (4/3 PI * R cubed ) +float fm_sphereVolume(float radius) // return's the volume of a sphere of this radius (4/3 PI * R cubed ) { - return (4.0f / 3.0f ) * FM_PI * radius * radius * radius; + return (4.0f / 3.0f) * FM_PI * radius * radius * radius; } diff --git a/Extras/ConvexDecomposition/float_math.h b/Extras/ConvexDecomposition/float_math.h index d6046d3b0..b23280011 100644 --- a/Extras/ConvexDecomposition/float_math.h +++ b/Extras/ConvexDecomposition/float_math.h @@ -3,12 +3,12 @@ #define FLOAT_MATH_H #ifdef _WIN32 - #pragma warning(disable : 4324) // disable padding warning - #pragma warning(disable : 4244) // disable padding warning - #pragma warning(disable : 4267) // possible loss of data - #pragma warning(disable:4530) // Disable the exception disable but used in MSCV Stl warning. - #pragma warning(disable:4996) //Turn off warnings about deprecated C routines - #pragma warning(disable:4786) // Disable the "debug name too long" warning +#pragma warning(disable : 4324) // disable padding warning +#pragma warning(disable : 4244) // disable padding warning +#pragma warning(disable : 4267) // possible loss of data +#pragma warning(disable : 4530) // Disable the exception disable but used in MSCV Stl warning. +#pragma warning(disable : 4996) //Turn off warnings about deprecated C routines +#pragma warning(disable : 4786) // Disable the "debug name too long" warning #endif /*---------------------------------------------------------------------- @@ -45,7 +45,6 @@ // http://www.amillionpixels.us // - // a set of routines that last you do common 3d math // operations without any vector, matrix, or quaternion // classes or templates. @@ -58,15 +57,15 @@ const float FM_PI = 3.141592654f; const float FM_DEG_TO_RAD = ((2.0f * FM_PI) / 360.0f); const float FM_RAD_TO_DEG = (360.0f / (2.0f * FM_PI)); -void fm_identity(float *matrix); // set 4x4 matrix to identity. -void fm_inverseRT(const float *matrix,const float *pos,float *t); // inverse rotate translate the point. -void fm_eulerMatrix(float ax,float ay,float az,float *matrix); // convert euler (in radians) to a dest 4x4 matrix (translation set to zero) -void fm_getAABB(unsigned int vcount,const float *points,unsigned int pstride,float *bmin,float *bmax); -void fm_eulerToQuat(float roll,float pitch,float yaw,float *quat); // convert euler angles to quaternion. -void fm_quatToMatrix(const float *quat,float *matrix); // convert quaterinion rotation to matrix, translation set to zero. -void fm_quatRotate(const float *quat,const float *v,float *r); // rotate a vector directly by a quaternion. -void fm_getTranslation(const float *matrix,float *t); -void fm_matrixToQuat(const float *matrix,float *quat); // convert the 3x3 portion of a 4x4 matrix into a quaterion as x,y,z,w -float fm_sphereVolume(float radius); // return's the volume of a sphere of this radius (4/3 PI * R cubed ) +void fm_identity(float *matrix); // set 4x4 matrix to identity. +void fm_inverseRT(const float *matrix, const float *pos, float *t); // inverse rotate translate the point. +void fm_eulerMatrix(float ax, float ay, float az, float *matrix); // convert euler (in radians) to a dest 4x4 matrix (translation set to zero) +void fm_getAABB(unsigned int vcount, const float *points, unsigned int pstride, float *bmin, float *bmax); +void fm_eulerToQuat(float roll, float pitch, float yaw, float *quat); // convert euler angles to quaternion. +void fm_quatToMatrix(const float *quat, float *matrix); // convert quaterinion rotation to matrix, translation set to zero. +void fm_quatRotate(const float *quat, const float *v, float *r); // rotate a vector directly by a quaternion. +void fm_getTranslation(const float *matrix, float *t); +void fm_matrixToQuat(const float *matrix, float *quat); // convert the 3x3 portion of a 4x4 matrix into a quaterion as x,y,z,w +float fm_sphereVolume(float radius); // return's the volume of a sphere of this radius (4/3 PI * R cubed ) #endif diff --git a/Extras/ConvexDecomposition/meshvolume.cpp b/Extras/ConvexDecomposition/meshvolume.cpp index b9dfa174d..c7427d571 100644 --- a/Extras/ConvexDecomposition/meshvolume.cpp +++ b/Extras/ConvexDecomposition/meshvolume.cpp @@ -35,94 +35,90 @@ // http://www.amillionpixels.us // -inline float det(const float *p1,const float *p2,const float *p3) +inline float det(const float *p1, const float *p2, const float *p3) { - return p1[0]*p2[1]*p3[2] + p2[0]*p3[1]*p1[2] + p3[0]*p1[1]*p2[2] -p1[0]*p3[1]*p2[2] - p2[0]*p1[1]*p3[2] - p3[0]*p2[1]*p1[2]; + return p1[0] * p2[1] * p3[2] + p2[0] * p3[1] * p1[2] + p3[0] * p1[1] * p2[2] - p1[0] * p3[1] * p2[2] - p2[0] * p1[1] * p3[2] - p3[0] * p2[1] * p1[2]; } -float computeMeshVolume(const float *vertices,unsigned int tcount,const unsigned int *indices) +float computeMeshVolume(const float *vertices, unsigned int tcount, const unsigned int *indices) { float volume = 0; - for (unsigned int i=0; i 0) + return PTR_FRONT; // it is 'in front' within the provided epsilon value. - if ( (d+epsilon) > 0 ) - return PTR_FRONT; // it is 'in front' within the provided epsilon value. - - return PTR_BACK; + return PTR_BACK; } -static void add(const float *p,float *dest,unsigned int tstride,unsigned int &pcount) +static void add(const float *p, float *dest, unsigned int tstride, unsigned int &pcount) { - char *d = (char *) dest; - d = d + pcount*tstride; - dest = (float *) d; - dest[0] = p[0]; - dest[1] = p[1]; - dest[2] = p[2]; - pcount++; - assert( pcount <= 4 ); + char *d = (char *)dest; + d = d + pcount * tstride; + dest = (float *)d; + dest[0] = p[0]; + dest[1] = p[1]; + dest[2] = p[2]; + pcount++; + assert(pcount <= 4); } - // assumes that the points are on opposite sides of the plane! -static void intersect(const float *p1,const float *p2,float *split,const float *plane) +static void intersect(const float *p1, const float *p2, float *split, const float *plane) { + float dp1 = DistToPt(p1, plane); - float dp1 = DistToPt(p1,plane); + float dir[3]; - float dir[3]; + dir[0] = p2[0] - p1[0]; + dir[1] = p2[1] - p1[1]; + dir[2] = p2[2] - p1[2]; - dir[0] = p2[0] - p1[0]; - dir[1] = p2[1] - p1[1]; - dir[2] = p2[2] - p1[2]; + float dot1 = dir[0] * plane[0] + dir[1] * plane[1] + dir[2] * plane[2]; + float dot2 = dp1 - plane[3]; - float dot1 = dir[0]*plane[0] + dir[1]*plane[1] + dir[2]*plane[2]; - float dot2 = dp1 - plane[3]; - - float t = -(plane[3] + dot2 ) / dot1; - - split[0] = (dir[0]*t)+p1[0]; - split[1] = (dir[1]*t)+p1[1]; - split[2] = (dir[2]*t)+p1[2]; + float t = -(plane[3] + dot2) / dot1; + split[0] = (dir[0] * t) + p1[0]; + split[1] = (dir[1] * t) + p1[1]; + split[2] = (dir[2] * t) + p1[2]; } -PlaneTriResult planeTriIntersection(const float *plane, // the plane equation in Ax+By+Cz+D format - const float *triangle, // the source triangle. - unsigned int tstride, // stride in bytes of the input and output triangles - float epsilon, // the co-planer epsilon value. - float *front, // the triangle in front of the - unsigned int &fcount, // number of vertices in the 'front' triangle - float *back, // the triangle in back of the plane - unsigned int &bcount) // the number of vertices in the 'back' triangle. +PlaneTriResult planeTriIntersection(const float *plane, // the plane equation in Ax+By+Cz+D format + const float *triangle, // the source triangle. + unsigned int tstride, // stride in bytes of the input and output triangles + float epsilon, // the co-planer epsilon value. + float *front, // the triangle in front of the + unsigned int &fcount, // number of vertices in the 'front' triangle + float *back, // the triangle in back of the plane + unsigned int &bcount) // the number of vertices in the 'back' triangle. { - fcount = 0; - bcount = 0; + fcount = 0; + bcount = 0; - const char *tsource = (const char *) triangle; + const char *tsource = (const char *)triangle; - // get the three vertices of the triangle. - const float *p1 = (const float *) (tsource); - const float *p2 = (const float *) (tsource+tstride); - const float *p3 = (const float *) (tsource+tstride*2); + // get the three vertices of the triangle. + const float *p1 = (const float *)(tsource); + const float *p2 = (const float *)(tsource + tstride); + const float *p3 = (const float *)(tsource + tstride * 2); + PlaneTriResult r1 = getSidePlane(p1, plane, epsilon); // compute the side of the plane each vertex is on + PlaneTriResult r2 = getSidePlane(p2, plane, epsilon); + PlaneTriResult r3 = getSidePlane(p3, plane, epsilon); - PlaneTriResult r1 = getSidePlane(p1,plane,epsilon); // compute the side of the plane each vertex is on - PlaneTriResult r2 = getSidePlane(p2,plane,epsilon); - PlaneTriResult r3 = getSidePlane(p3,plane,epsilon); + if (r1 == r2 && r1 == r3) // if all three vertices are on the same side of the plane. + { + if (r1 == PTR_FRONT) // if all three are in front of the plane, then copy to the 'front' output triangle. + { + add(p1, front, tstride, fcount); + add(p2, front, tstride, fcount); + add(p3, front, tstride, fcount); + } + else + { + add(p1, back, tstride, bcount); // if all three are in 'abck' then copy to the 'back' output triangle. + add(p2, back, tstride, bcount); + add(p3, back, tstride, bcount); + } + return r1; // if all three points are on the same side of the plane return result + } - if ( r1 == r2 && r1 == r3 ) // if all three vertices are on the same side of the plane. - { - if ( r1 == PTR_FRONT ) // if all three are in front of the plane, then copy to the 'front' output triangle. - { - add(p1,front,tstride,fcount); - add(p2,front,tstride,fcount); - add(p3,front,tstride,fcount); - } - else - { - add(p1,back,tstride,bcount); // if all three are in 'abck' then copy to the 'back' output triangle. - add(p2,back,tstride,bcount); - add(p3,back,tstride,bcount); - } - return r1; // if all three points are on the same side of the plane return result - } + // ok.. we need to split the triangle at the plane. - // ok.. we need to split the triangle at the plane. + // First test ray segment P1 to P2 + if (r1 == r2) // if these are both on the same side... + { + if (r1 == PTR_FRONT) + { + add(p1, front, tstride, fcount); + add(p2, front, tstride, fcount); + } + else + { + add(p1, back, tstride, bcount); + add(p2, back, tstride, bcount); + } + } + else + { + float split[3]; // split the point + intersect(p1, p2, split, plane); - // First test ray segment P1 to P2 - if ( r1 == r2 ) // if these are both on the same side... - { - if ( r1 == PTR_FRONT ) - { - add( p1, front, tstride, fcount ); - add( p2, front, tstride, fcount ); - } - else - { - add( p1, back, tstride, bcount ); - add( p2, back, tstride, bcount ); - } - } - else - { - float split[3]; // split the point - intersect(p1,p2,split,plane); + if (r1 == PTR_FRONT) + { + add(p1, front, tstride, fcount); + add(split, front, tstride, fcount); - if ( r1 == PTR_FRONT ) - { + add(split, back, tstride, bcount); + add(p2, back, tstride, bcount); + } + else + { + add(p1, back, tstride, bcount); + add(split, back, tstride, bcount); - add(p1, front, tstride, fcount ); - add(split, front, tstride, fcount ); + add(split, front, tstride, fcount); + add(p2, front, tstride, fcount); + } + } - add(split, back, tstride, bcount ); - add(p2, back, tstride, bcount ); + // Next test ray segment P2 to P3 + if (r2 == r3) // if these are both on the same side... + { + if (r3 == PTR_FRONT) + { + add(p3, front, tstride, fcount); + } + else + { + add(p3, back, tstride, bcount); + } + } + else + { + float split[3]; // split the point + intersect(p2, p3, split, plane); - } - else - { - add(p1, back, tstride, bcount ); - add(split, back, tstride, bcount ); + if (r3 == PTR_FRONT) + { + add(split, front, tstride, fcount); + add(split, back, tstride, bcount); - add(split, front, tstride, fcount ); - add(p2, front, tstride, fcount ); - } + add(p3, front, tstride, fcount); + } + else + { + add(split, front, tstride, fcount); + add(split, back, tstride, bcount); - } + add(p3, back, tstride, bcount); + } + } - // Next test ray segment P2 to P3 - if ( r2 == r3 ) // if these are both on the same side... - { - if ( r3 == PTR_FRONT ) - { - add( p3, front, tstride, fcount ); - } - else - { - add( p3, back, tstride, bcount ); - } - } - else - { - float split[3]; // split the point - intersect(p2,p3,split,plane); + // Next test ray segment P3 to P1 + if (r3 != r1) // if these are both on the same side... + { + float split[3]; // split the point - if ( r3 == PTR_FRONT ) - { - add(split, front, tstride, fcount ); - add(split, back, tstride, bcount ); + intersect(p3, p1, split, plane); - add(p3, front, tstride, fcount ); - } - else - { - add(split, front, tstride, fcount ); - add(split, back, tstride, bcount ); + if (r1 == PTR_FRONT) + { + add(split, front, tstride, fcount); + add(split, back, tstride, bcount); + } + else + { + add(split, front, tstride, fcount); + add(split, back, tstride, bcount); + } + } - add(p3, back, tstride, bcount ); - } - } - - // Next test ray segment P3 to P1 - if ( r3 != r1 ) // if these are both on the same side... - { - float split[3]; // split the point - - intersect(p3,p1,split,plane); - - if ( r1 == PTR_FRONT ) - { - add(split, front, tstride, fcount ); - add(split, back, tstride, bcount ); - } - else - { - add(split, front, tstride, fcount ); - add(split, back, tstride, bcount ); - } - } - - - - return PTR_SPLIT; + return PTR_SPLIT; } diff --git a/Extras/ConvexDecomposition/planetri.h b/Extras/ConvexDecomposition/planetri.h index 780ac854a..1ae2ab21a 100644 --- a/Extras/ConvexDecomposition/planetri.h +++ b/Extras/ConvexDecomposition/planetri.h @@ -36,23 +36,20 @@ // http://www.amillionpixels.us // - - enum PlaneTriResult { - PTR_FRONT, - PTR_BACK, - PTR_SPLIT + PTR_FRONT, + PTR_BACK, + PTR_SPLIT }; -PlaneTriResult planeTriIntersection(const float *plane, // the plane equation in Ax+By+Cz+D format - const float *triangle, // the source position triangle. - unsigned int tstride, // stride in bytes between vertices of the triangle. - float epsilon, // the co-planer epsilon value. - float *front, // the triangle in front of the - unsigned int &fcount, // number of vertices in the 'front' triangle. - float *back, // the triangle in back of the plane - unsigned int &bcount); // the number of vertices in the 'back' triangle. - +PlaneTriResult planeTriIntersection(const float *plane, // the plane equation in Ax+By+Cz+D format + const float *triangle, // the source position triangle. + unsigned int tstride, // stride in bytes between vertices of the triangle. + float epsilon, // the co-planer epsilon value. + float *front, // the triangle in front of the + unsigned int &fcount, // number of vertices in the 'front' triangle. + float *back, // the triangle in back of the plane + unsigned int &bcount); // the number of vertices in the 'back' triangle. #endif diff --git a/Extras/ConvexDecomposition/raytri.cpp b/Extras/ConvexDecomposition/raytri.cpp index 83b076a20..25f9cd332 100644 --- a/Extras/ConvexDecomposition/raytri.cpp +++ b/Extras/ConvexDecomposition/raytri.cpp @@ -41,88 +41,82 @@ // http://www.amillionpixels.us // - /* a = b - c */ -#define vector(a,b,c) \ - (a)[0] = (b)[0] - (c)[0]; \ - (a)[1] = (b)[1] - (c)[1]; \ +#define vector(a, b, c) \ + (a)[0] = (b)[0] - (c)[0]; \ + (a)[1] = (b)[1] - (c)[1]; \ (a)[2] = (b)[2] - (c)[2]; +#define innerProduct(v, q) \ + ((v)[0] * (q)[0] + \ + (v)[1] * (q)[1] + \ + (v)[2] * (q)[2]) - -#define innerProduct(v,q) \ - ((v)[0] * (q)[0] + \ - (v)[1] * (q)[1] + \ - (v)[2] * (q)[2]) - -#define crossProduct(a,b,c) \ +#define crossProduct(a, b, c) \ (a)[0] = (b)[1] * (c)[2] - (c)[1] * (b)[2]; \ (a)[1] = (b)[2] * (c)[0] - (c)[2] * (b)[0]; \ (a)[2] = (b)[0] * (c)[1] - (c)[0] * (b)[1]; -bool rayIntersectsTriangle(const float *p,const float *d,const float *v0,const float *v1,const float *v2,float &t) +bool rayIntersectsTriangle(const float *p, const float *d, const float *v0, const float *v1, const float *v2, float &t) { + float e1[3], e2[3], h[3], s[3], q[3]; + float a, f, u, v; - float e1[3],e2[3],h[3],s[3],q[3]; - float a,f,u,v; - - vector(e1,v1,v0); - vector(e2,v2,v0); - crossProduct(h,d,e2); - a = innerProduct(e1,h); + vector(e1, v1, v0); + vector(e2, v2, v0); + crossProduct(h, d, e2); + a = innerProduct(e1, h); if (a > -0.00001 && a < 0.00001) - return(false); + return (false); - f = 1/a; - vector(s,p,v0); - u = f * (innerProduct(s,h)); + f = 1 / a; + vector(s, p, v0); + u = f * (innerProduct(s, h)); if (u < 0.0 || u > 1.0) - return(false); + return (false); - crossProduct(q,s,e1); - v = f * innerProduct(d,q); + crossProduct(q, s, e1); + v = f * innerProduct(d, q); if (v < 0.0 || u + v > 1.0) - return(false); + return (false); // at this stage we can compute t to find out where // the intersection point is on the line - t = f * innerProduct(e2,q); - if (t > 0) // ray intersection - return(true); - else // this means that there is a line intersection - // but not a ray intersection - return (false); + t = f * innerProduct(e2, q); + if (t > 0) // ray intersection + return (true); + else // this means that there is a line intersection + // but not a ray intersection + return (false); } - -bool lineIntersectsTriangle(const float *rayStart,const float *rayEnd,const float *p1,const float *p2,const float *p3,float *sect) +bool lineIntersectsTriangle(const float *rayStart, const float *rayEnd, const float *p1, const float *p2, const float *p3, float *sect) { float dir[3]; - dir[0] = rayEnd[0] - rayStart[0]; - dir[1] = rayEnd[1] - rayStart[1]; - dir[2] = rayEnd[2] - rayStart[2]; + dir[0] = rayEnd[0] - rayStart[0]; + dir[1] = rayEnd[1] - rayStart[1]; + dir[2] = rayEnd[2] - rayStart[2]; - float d = sqrtf(dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2]); - float r = 1.0f / d; + float d = sqrtf(dir[0] * dir[0] + dir[1] * dir[1] + dir[2] * dir[2]); + float r = 1.0f / d; - dir[0]*=r; - dir[1]*=r; - dir[2]*=r; + dir[0] *= r; + dir[1] *= r; + dir[2] *= r; + float t; - float t; + bool ret = rayIntersectsTriangle(rayStart, dir, p1, p2, p3, t); - bool ret = rayIntersectsTriangle(rayStart, dir, p1, p2, p3, t ); - - if ( ret ) + if (ret) { - if ( t > d ) + if (t > d) { - sect[0] = rayStart[0] + dir[0]*t; - sect[1] = rayStart[1] + dir[1]*t; - sect[2] = rayStart[2] + dir[2]*t; + sect[0] = rayStart[0] + dir[0] * t; + sect[1] = rayStart[1] + dir[1] * t; + sect[2] = rayStart[2] + dir[2] * t; } else { @@ -130,5 +124,5 @@ bool lineIntersectsTriangle(const float *rayStart,const float *rayEnd,const floa } } - return ret; + return ret; } diff --git a/Extras/ConvexDecomposition/raytri.h b/Extras/ConvexDecomposition/raytri.h index 76370c6d7..19932f8c4 100644 --- a/Extras/ConvexDecomposition/raytri.h +++ b/Extras/ConvexDecomposition/raytri.h @@ -36,10 +36,8 @@ // http://www.amillionpixels.us // - - // returns true if the ray intersects the triangle. -bool lineIntersectsTriangle(const float *rayStart,const float *rayEnd,const float *p1,const float *p2,const float *p3,float *sect); -bool rayIntersectsTriangle(const float *p,const float *d,const float *v0,const float *v1,const float *v2,float &t); +bool lineIntersectsTriangle(const float *rayStart, const float *rayEnd, const float *p1, const float *p2, const float *p3, float *sect); +bool rayIntersectsTriangle(const float *p, const float *d, const float *v0, const float *v1, const float *v2, float &t); #endif diff --git a/Extras/ConvexDecomposition/splitplane.cpp b/Extras/ConvexDecomposition/splitplane.cpp index 2ae408e60..22bfdd9ce 100644 --- a/Extras/ConvexDecomposition/splitplane.cpp +++ b/Extras/ConvexDecomposition/splitplane.cpp @@ -6,7 +6,6 @@ #include #include - /*---------------------------------------------------------------------- Copyright (c) 2004 Open Dynamics Framework Group www.physicstools.org @@ -53,10 +52,8 @@ namespace ConvexDecomposition { - -static void computePlane(const float *A,const float *B,const float *C,float *plane) +static void computePlane(const float *A, const float *B, const float *C, float *plane) { - float vx = (B[0] - C[0]); float vy = (B[1] - C[1]); float vz = (B[2] - C[2]); @@ -71,108 +68,104 @@ static void computePlane(const float *A,const float *B,const float *C,float *pla float mag = sqrtf((vw_x * vw_x) + (vw_y * vw_y) + (vw_z * vw_z)); - if ( mag < 0.000001f ) + if (mag < 0.000001f) { mag = 0; } else { - mag = 1.0f/mag; + mag = 1.0f / mag; } float x = vw_x * mag; float y = vw_y * mag; float z = vw_z * mag; + float D = 0.0f - ((x * A[0]) + (y * A[1]) + (z * A[2])); - float D = 0.0f - ((x*A[0])+(y*A[1])+(z*A[2])); - - plane[0] = x; - plane[1] = y; - plane[2] = z; - plane[3] = D; - + plane[0] = x; + plane[1] = y; + plane[2] = z; + plane[3] = D; } class Rect3d { public: - Rect3d(void) { }; + Rect3d(void){}; - Rect3d(const float *bmin,const float *bmax) - { + Rect3d(const float *bmin, const float *bmax) + { + mMin[0] = bmin[0]; + mMin[1] = bmin[1]; + mMin[2] = bmin[2]; - mMin[0] = bmin[0]; - mMin[1] = bmin[1]; - mMin[2] = bmin[2]; + mMax[0] = bmax[0]; + mMax[1] = bmax[1]; + mMax[2] = bmax[2]; + } - mMax[0] = bmax[0]; - mMax[1] = bmax[1]; - mMax[2] = bmax[2]; + void SetMin(const float *bmin) + { + mMin[0] = bmin[0]; + mMin[1] = bmin[1]; + mMin[2] = bmin[2]; + } - } + void SetMax(const float *bmax) + { + mMax[0] = bmax[0]; + mMax[1] = bmax[1]; + mMax[2] = bmax[2]; + } - void SetMin(const float *bmin) - { - mMin[0] = bmin[0]; - mMin[1] = bmin[1]; - mMin[2] = bmin[2]; - } - - void SetMax(const float *bmax) - { - mMax[0] = bmax[0]; - mMax[1] = bmax[1]; - mMax[2] = bmax[2]; - } - - void SetMin(float x,float y,float z) + void SetMin(float x, float y, float z) { mMin[0] = x; mMin[1] = y; mMin[2] = z; } - void SetMax(float x,float y,float z) + void SetMax(float x, float y, float z) { mMax[0] = x; mMax[1] = y; mMax[2] = z; } - float mMin[3]; - float mMax[3]; + float mMin[3]; + float mMax[3]; }; void splitRect(unsigned int axis, - const Rect3d &source, - Rect3d &b1, - Rect3d &b2, - const float *midpoint) + const Rect3d &source, + Rect3d &b1, + Rect3d &b2, + const float *midpoint) { - switch ( axis ) + switch (axis) { case 0: b1.SetMin(source.mMin); - b1.SetMax( midpoint[0], source.mMax[1], source.mMax[2] ); + b1.SetMax(midpoint[0], source.mMax[1], source.mMax[2]); - b2.SetMin( midpoint[0], source.mMin[1], source.mMin[2] ); + b2.SetMin(midpoint[0], source.mMin[1], source.mMin[2]); b2.SetMax(source.mMax); break; case 1: b1.SetMin(source.mMin); - b1.SetMax( source.mMax[0], midpoint[1], source.mMax[2] ); + b1.SetMax(source.mMax[0], midpoint[1], source.mMax[2]); - b2.SetMin( source.mMin[0], midpoint[1], source.mMin[2] ); + b2.SetMin(source.mMin[0], midpoint[1], source.mMin[2]); b2.SetMax(source.mMax); break; case 2: b1.SetMin(source.mMin); - b1.SetMax( source.mMax[0], source.mMax[1], midpoint[2] ); + b1.SetMax(source.mMax[0], source.mMax[1], midpoint[2]); - b2.SetMin( source.mMin[0], source.mMin[1], midpoint[2] ); + b2.SetMin(source.mMin[0], source.mMin[1], midpoint[2]); b2.SetMax(source.mMax); break; @@ -180,127 +173,122 @@ void splitRect(unsigned int axis, } bool computeSplitPlane(unsigned int vcount, - const float *vertices, - unsigned int tcount, - const unsigned int *indices, - ConvexDecompInterface *callback, - float *plane) + const float *vertices, + unsigned int tcount, + const unsigned int *indices, + ConvexDecompInterface *callback, + float *plane) { - float bmin[3] = { 1e9, 1e9, 1e9 }; - float bmax[3] = { -1e9, -1e9, -1e9 }; + float bmin[3] = {1e9, 1e9, 1e9}; + float bmax[3] = {-1e9, -1e9, -1e9}; - for (unsigned int i=0; i bmax[0] ) bmax[0] = p[0]; - if ( p[1] > bmax[1] ) bmax[1] = p[1]; - if ( p[2] > bmax[2] ) bmax[2] = p[2]; - - } - - float dx = bmax[0] - bmin[0]; - float dy = bmax[1] - bmin[1]; - float dz = bmax[2] - bmin[2]; + if (p[0] > bmax[0]) bmax[0] = p[0]; + if (p[1] > bmax[1]) bmax[1] = p[1]; + if (p[2] > bmax[2]) bmax[2] = p[2]; + } + float dx = bmax[0] - bmin[0]; + float dy = bmax[1] - bmin[1]; + float dz = bmax[2] - bmin[2]; float laxis = dx; unsigned int axis = 0; - if ( dy > dx ) + if (dy > dx) { axis = 1; laxis = dy; } - if ( dz > dx && dz > dy ) + if (dz > dx && dz > dy) { axis = 2; laxis = dz; } - float p1[3]; - float p2[3]; - float p3[3]; + float p1[3]; + float p2[3]; + float p3[3]; - p3[0] = p2[0] = p1[0] = bmin[0] + dx*0.5f; - p3[1] = p2[1] = p1[1] = bmin[1] + dy*0.5f; - p3[2] = p2[2] = p1[2] = bmin[2] + dz*0.5f; + p3[0] = p2[0] = p1[0] = bmin[0] + dx * 0.5f; + p3[1] = p2[1] = p1[1] = bmin[1] + dy * 0.5f; + p3[2] = p2[2] = p1[2] = bmin[2] + dz * 0.5f; - Rect3d b(bmin,bmax); + Rect3d b(bmin, bmax); - Rect3d b1,b2; + Rect3d b1, b2; - splitRect(axis,b,b1,b2,p1); + splitRect(axis, b, b1, b2, p1); + // callback->ConvexDebugBound(b1.mMin,b1.mMax,0x00FF00); + // callback->ConvexDebugBound(b2.mMin,b2.mMax,0xFFFF00); -// callback->ConvexDebugBound(b1.mMin,b1.mMax,0x00FF00); -// callback->ConvexDebugBound(b2.mMin,b2.mMax,0xFFFF00); + switch (axis) + { + case 0: + p2[1] = bmin[1]; + p2[2] = bmin[2]; - switch ( axis ) - { - case 0: - p2[1] = bmin[1]; - p2[2] = bmin[2]; + if (dz > dy) + { + p3[1] = bmax[1]; + p3[2] = bmin[2]; + } + else + { + p3[1] = bmin[1]; + p3[2] = bmax[2]; + } - if ( dz > dy ) - { - p3[1] = bmax[1]; - p3[2] = bmin[2]; - } - else - { - p3[1] = bmin[1]; - p3[2] = bmax[2]; - } + break; + case 1: + p2[0] = bmin[0]; + p2[2] = bmin[2]; - break; - case 1: - p2[0] = bmin[0]; - p2[2] = bmin[2]; + if (dx > dz) + { + p3[0] = bmax[0]; + p3[2] = bmin[2]; + } + else + { + p3[0] = bmin[0]; + p3[2] = bmax[2]; + } - if ( dx > dz ) - { - p3[0] = bmax[0]; - p3[2] = bmin[2]; - } - else - { - p3[0] = bmin[0]; - p3[2] = bmax[2]; - } + break; + case 2: + p2[0] = bmin[0]; + p2[1] = bmin[1]; - break; - case 2: - p2[0] = bmin[0]; - p2[1] = bmin[1]; + if (dx > dy) + { + p3[0] = bmax[0]; + p3[1] = bmin[1]; + } + else + { + p3[0] = bmin[0]; + p3[1] = bmax[1]; + } - if ( dx > dy ) - { - p3[0] = bmax[0]; - p3[1] = bmin[1]; - } - else - { - p3[0] = bmin[0]; - p3[1] = bmax[1]; - } + break; + } - break; - } + // callback->ConvexDebugTri(p1,p2,p3,0xFF0000); -// callback->ConvexDebugTri(p1,p2,p3,0xFF0000); - - computePlane(p1,p2,p3,plane); - - return true; + computePlane(p1, p2, p3, plane); + return true; } - -} +} // namespace ConvexDecomposition diff --git a/Extras/ConvexDecomposition/splitplane.h b/Extras/ConvexDecomposition/splitplane.h index 26fe2e33e..12bc06a39 100644 --- a/Extras/ConvexDecomposition/splitplane.h +++ b/Extras/ConvexDecomposition/splitplane.h @@ -39,21 +39,17 @@ // http://www.amillionpixels.us // - - namespace ConvexDecomposition { - class ConvexDecompInterface; bool computeSplitPlane(unsigned int vcount, - const float *vertices, - unsigned int tcount, - const unsigned int *indices, - ConvexDecompInterface *callback, - float *plane); + const float *vertices, + unsigned int tcount, + const unsigned int *indices, + ConvexDecompInterface *callback, + float *plane); - -} +} // namespace ConvexDecomposition #endif diff --git a/Extras/ConvexDecomposition/vlookup.cpp b/Extras/ConvexDecomposition/vlookup.cpp index 3b9e928ca..ee181342e 100644 --- a/Extras/ConvexDecomposition/vlookup.cpp +++ b/Extras/ConvexDecomposition/vlookup.cpp @@ -4,13 +4,12 @@ #include #include -#pragma warning(disable:4786) +#pragma warning(disable : 4786) #include #include #include - /*---------------------------------------------------------------------- Copyright (c) 2004 Open Dynamics Framework Group www.physicstools.org @@ -107,55 +106,50 @@ // You could easily modify this code to support other vertex // formats with any number of interpolants. - - - #include "vlookup.h" namespace Vlookup { - class VertexPosition { public: - VertexPosition(void) { }; - VertexPosition(const float *p) - { - mPos[0] = p[0]; - mPos[1] = p[1]; - mPos[2] = p[2]; - }; - - void Set(int index,const float *pos) + VertexPosition(void){}; + VertexPosition(const float *p) { - const float * p = &pos[index*3]; - - mPos[0] = p[0]; - mPos[1] = p[1]; - mPos[2] = p[2]; - + mPos[0] = p[0]; + mPos[1] = p[1]; + mPos[2] = p[2]; }; - float GetX(void) const { return mPos[0]; }; - float GetY(void) const { return mPos[1]; }; - float GetZ(void) const { return mPos[2]; }; + void Set(int index, const float *pos) + { + const float *p = &pos[index * 3]; + + mPos[0] = p[0]; + mPos[1] = p[1]; + mPos[2] = p[2]; + }; + + float GetX(void) const { return mPos[0]; }; + float GetY(void) const { return mPos[1]; }; + float GetZ(void) const { return mPos[2]; }; float mPos[3]; }; -typedef std::vector< VertexPosition > VertexVector; +typedef std::vector VertexVector; struct Tracker { - VertexPosition mFind; // vertice to locate. - VertexVector *mList; + VertexPosition mFind; // vertice to locate. + VertexVector *mList; Tracker() { mList = 0; } - void SetSearch(const VertexPosition& match,VertexVector *list) + void SetSearch(const VertexPosition &match, VertexVector *list) { mFind = match; mList = list; @@ -165,9 +159,9 @@ struct Tracker struct VertexID { int mID; - Tracker* mTracker; + Tracker *mTracker; - VertexID(int ID, Tracker* Tracker) + VertexID(int ID, Tracker *Tracker) { mID = ID; mTracker = Tracker; @@ -177,46 +171,45 @@ struct VertexID class VertexLess { public: - - bool operator()(VertexID v1,VertexID v2) const; + bool operator()(VertexID v1, VertexID v2) const; private: - const VertexPosition& Get(VertexID index) const + const VertexPosition &Get(VertexID index) const { - if ( index.mID == -1 ) return index.mTracker->mFind; + if (index.mID == -1) return index.mTracker->mFind; VertexVector &vlist = *index.mTracker->mList; return vlist[index.mID]; } }; -template class VertexPool +template +class VertexPool { public: - typedef std::set VertexSet; - typedef std::vector< Type > VertexVector; + typedef std::set VertexSet; + typedef std::vector VertexVector; - int getVertex(const Type& vtx) + int getVertex(const Type &vtx) { - mTracker.SetSearch(vtx,&mVtxs); + mTracker.SetSearch(vtx, &mVtxs); VertexSet::iterator found; - found = mVertSet.find( VertexID(-1,&mTracker) ); - if ( found != mVertSet.end() ) + found = mVertSet.find(VertexID(-1, &mTracker)); + if (found != mVertSet.end()) { return found->mID; } int idx = (int)mVtxs.size(); - mVtxs.push_back( vtx ); - mVertSet.insert( VertexID(idx,&mTracker) ); + mVtxs.push_back(vtx); + mVertSet.insert(VertexID(idx, &mTracker)); return idx; }; - - const float * GetPos(int idx) const + const float *GetPos(int idx) const { return mVtxs[idx].mPos; } - const Type& Get(int idx) const + const Type &Get(int idx) const { return mVtxs[idx]; }; @@ -233,9 +226,9 @@ public: mVtxs.reserve(reservesize); }; - const VertexVector& GetVertexList(void) const { return mVtxs; }; + const VertexVector &GetVertexList(void) const { return mVtxs; }; - void Set(const Type& vtx) + void Set(const Type &vtx) { mVtxs.push_back(vtx); } @@ -245,82 +238,74 @@ public: return mVtxs.size(); }; - - Type * getBuffer(void) + Type *getBuffer(void) { return &mVtxs[0]; }; private: - VertexSet mVertSet; // ordered list. - VertexVector mVtxs; // set of vertices. - Tracker mTracker; + VertexSet mVertSet; // ordered list. + VertexVector mVtxs; // set of vertices. + Tracker mTracker; }; - -bool VertexLess::operator()(VertexID v1,VertexID v2) const +bool VertexLess::operator()(VertexID v1, VertexID v2) const { + const VertexPosition &a = Get(v1); + const VertexPosition &b = Get(v2); - const VertexPosition& a = Get(v1); - const VertexPosition& b = Get(v2); + int ixA = (int)(a.GetX() * 10000.0f); + int ixB = (int)(b.GetX() * 10000.0f); - int ixA = (int) (a.GetX()*10000.0f); - int ixB = (int) (b.GetX()*10000.0f); + if (ixA < ixB) return true; + if (ixA > ixB) return false; - if ( ixA < ixB ) return true; - if ( ixA > ixB ) return false; + int iyA = (int)(a.GetY() * 10000.0f); + int iyB = (int)(b.GetY() * 10000.0f); - int iyA = (int) (a.GetY()*10000.0f); - int iyB = (int) (b.GetY()*10000.0f); + if (iyA < iyB) return true; + if (iyA > iyB) return false; - if ( iyA < iyB ) return true; - if ( iyA > iyB ) return false; - - int izA = (int) (a.GetZ()*10000.0f); - int izB = (int) (b.GetZ()*10000.0f); - - if ( izA < izB ) return true; - if ( izA > izB ) return false; + int izA = (int)(a.GetZ() * 10000.0f); + int izB = (int)(b.GetZ() * 10000.0f); + if (izA < izB) return true; + if (izA > izB) return false; return false; } - - - -} +} // namespace Vlookup using namespace Vlookup; VertexLookup Vl_createVertexLookup(void) { - VertexLookup ret = new VertexPool< VertexPosition >; - return ret; + VertexLookup ret = new VertexPool; + return ret; } -void Vl_releaseVertexLookup(VertexLookup vlook) +void Vl_releaseVertexLookup(VertexLookup vlook) { - VertexPool< VertexPosition > *vp = (VertexPool< VertexPosition > *) vlook; - delete vp; + VertexPool *vp = (VertexPool *)vlook; + delete vp; } -unsigned int Vl_getIndex(VertexLookup vlook,const float *pos) // get index. +unsigned int Vl_getIndex(VertexLookup vlook, const float *pos) // get index. { - VertexPool< VertexPosition > *vp = (VertexPool< VertexPosition > *) vlook; - VertexPosition p(pos); - return vp->getVertex(p); + VertexPool *vp = (VertexPool *)vlook; + VertexPosition p(pos); + return vp->getVertex(p); } -const float * Vl_getVertices(VertexLookup vlook) +const float *Vl_getVertices(VertexLookup vlook) { - VertexPool< VertexPosition > *vp = (VertexPool< VertexPosition > *) vlook; - return vp->GetPos(0); + VertexPool *vp = (VertexPool *)vlook; + return vp->GetPos(0); } - -unsigned int Vl_getVcount(VertexLookup vlook) +unsigned int Vl_getVcount(VertexLookup vlook) { - VertexPool< VertexPosition > *vp = (VertexPool< VertexPosition > *) vlook; - return vp->GetVertexCount(); + VertexPool *vp = (VertexPool *)vlook; + return vp->GetVertexCount(); } diff --git a/Extras/ConvexDecomposition/vlookup.h b/Extras/ConvexDecomposition/vlookup.h index 1a6e0a9e2..8120def43 100644 --- a/Extras/ConvexDecomposition/vlookup.h +++ b/Extras/ConvexDecomposition/vlookup.h @@ -2,7 +2,6 @@ #define VLOOKUP_H - /*---------------------------------------------------------------------- Copyright (c) 2004 Open Dynamics Framework Group www.physicstools.org @@ -37,7 +36,6 @@ // http://www.amillionpixels.us // - // CodeSnippet provided by John W. Ratcliff // on March 23, 2006. // @@ -105,15 +103,13 @@ // Uses an STL set to create an index table for a bunch of vertex positions // used typically to re-index a collection of raw triangle data. +typedef void *VertexLookup; -typedef void * VertexLookup; - -VertexLookup Vl_createVertexLookup(void); -void Vl_releaseVertexLookup(VertexLookup vlook); - -unsigned int Vl_getIndex(VertexLookup vlook,const float *pos); // get index. -const float * Vl_getVertices(VertexLookup vlook); -unsigned int Vl_getVcount(VertexLookup vlook); +VertexLookup Vl_createVertexLookup(void); +void Vl_releaseVertexLookup(VertexLookup vlook); +unsigned int Vl_getIndex(VertexLookup vlook, const float *pos); // get index. +const float *Vl_getVertices(VertexLookup vlook); +unsigned int Vl_getVcount(VertexLookup vlook); #endif diff --git a/Extras/GIMPACTUtils/btGImpactConvexDecompositionShape.cpp b/Extras/GIMPACTUtils/btGImpactConvexDecompositionShape.cpp index fc1ce33e2..755021483 100644 --- a/Extras/GIMPACTUtils/btGImpactConvexDecompositionShape.cpp +++ b/Extras/GIMPACTUtils/btGImpactConvexDecompositionShape.cpp @@ -26,17 +26,16 @@ subject to the following restrictions: class GIM_ConvexDecomposition : public ConvexDecomposition::ConvexDecompInterface { protected: - btGImpactConvexDecompositionShape * m_compoundShape; + btGImpactConvexDecompositionShape* m_compoundShape; btAlignedObjectArray m_convexShapes; - public: - int mBaseCount; - int mHullCount; + int mBaseCount; + int mHullCount; bool m_transformSubShapes; - GIM_ConvexDecomposition(btGImpactConvexDecompositionShape * compoundShape,bool transformSubShapes) + GIM_ConvexDecomposition(btGImpactConvexDecompositionShape* compoundShape, bool transformSubShapes) { mBaseCount = 0; mHullCount = 0; @@ -47,43 +46,39 @@ public: virtual ~GIM_ConvexDecomposition() { int i; - for (i=0;i vertices; - if(m_transformSubShapes) + if (m_transformSubShapes) { - //const unsigned int *src = result.mHullIndices; - for (unsigned int i=0; isetMargin(m_compoundShape->getMargin()); - if(m_transformSubShapes) + if (m_transformSubShapes) { btTransform trans; trans.setIdentity(); @@ -104,7 +99,7 @@ public: // add convex shape - m_compoundShape->addChildShape(trans,convexShape); + m_compoundShape->addChildShape(trans, convexShape); } else { @@ -114,7 +109,7 @@ public: // add convex shape - m_compoundShape->addChildShape(trans,convexShape); + m_compoundShape->addChildShape(trans, convexShape); //m_compoundShape->addChildShape(convexShape); } @@ -122,35 +117,32 @@ public: void processDecomposition(int part) { - btGImpactMeshShapePart::TrimeshPrimitiveManager * trimeshInterface = - m_compoundShape->getTrimeshInterface(part); - + btGImpactMeshShapePart::TrimeshPrimitiveManager* trimeshInterface = + m_compoundShape->getTrimeshInterface(part); trimeshInterface->lock(); //collect vertices btAlignedObjectArray vertices; - vertices.reserve(trimeshInterface->get_vertex_count()*3); + vertices.reserve(trimeshInterface->get_vertex_count() * 3); - for(int vi = 0;viget_vertex_count();vi++) + for (int vi = 0; vi < trimeshInterface->get_vertex_count(); vi++) { btVector3 vec; - trimeshInterface->get_vertex(vi,vec); + trimeshInterface->get_vertex(vi, vec); vertices.push_back(vec[0]); vertices.push_back(vec[1]); vertices.push_back(vec[2]); } - //collect indices btAlignedObjectArray indices; - indices.reserve(trimeshInterface->get_primitive_count()*3); + indices.reserve(trimeshInterface->get_primitive_count() * 3); - - for(int i = 0;iget_primitive_count();i++) + for (int i = 0; i < trimeshInterface->get_primitive_count(); i++) { - unsigned int i0, i1,i2; - trimeshInterface->get_indices(i,i0,i1,i2); + unsigned int i0, i1, i2; + trimeshInterface->get_indices(i, i0, i1, i2); indices.push_back(i0); indices.push_back(i1); indices.push_back(i2); @@ -158,25 +150,22 @@ public: trimeshInterface->unlock(); - - unsigned int depth = 5; - float cpercent = 5; - float ppercent = 15; - unsigned int maxv = 16; - float skinWidth = 0.0f; - + float cpercent = 5; + float ppercent = 15; + unsigned int maxv = 16; + float skinWidth = 0.0f; ConvexDecomposition::DecompDesc desc; - desc.mVcount = trimeshInterface->get_vertex_count(); - desc.mVertices = &vertices[0]; - desc.mTcount = trimeshInterface->get_primitive_count(); - desc.mIndices = &indices[0]; - desc.mDepth = depth; - desc.mCpercent = cpercent; - desc.mPpercent = ppercent; - desc.mMaxVertices = maxv; - desc.mSkinWidth = skinWidth; + desc.mVcount = trimeshInterface->get_vertex_count(); + desc.mVertices = &vertices[0]; + desc.mTcount = trimeshInterface->get_primitive_count(); + desc.mIndices = &indices[0]; + desc.mDepth = depth; + desc.mCpercent = cpercent; + desc.mPpercent = ppercent; + desc.mMaxVertices = maxv; + desc.mSkinWidth = skinWidth; desc.mCallback = this; //convexDecomposition.performConvexDecomposition(desc); @@ -184,21 +173,14 @@ public: ConvexBuilder cb(desc.mCallback); cb.process(desc); } - - - - }; - - void btGImpactConvexDecompositionShape::buildConvexDecomposition(bool transformSubShapes) { - - m_decomposition = new GIM_ConvexDecomposition(this,transformSubShapes); + m_decomposition = new GIM_ConvexDecomposition(this, transformSubShapes); int part_count = m_trimeshInterfaces.size(); - for (int i = 0;iprocessDecomposition(i); } @@ -210,31 +192,27 @@ btGImpactConvexDecompositionShape::~btGImpactConvexDecompositionShape() { delete m_decomposition; } -void btGImpactConvexDecompositionShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const +void btGImpactConvexDecompositionShape::processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const { - int part_count = m_trimeshInterfaces.size(); - for (int part = 0;part(ptr); + btGImpactMeshShapePart::TrimeshPrimitiveManager* trimeshInterface = + static_cast(ptr); trimeshInterface->lock(); btPrimitiveTriangle triangle; - int i = trimeshInterface->get_primitive_count(); - while(i--) + while (i--) { - trimeshInterface->get_primitive_triangle(i,triangle); - callback->processTriangle(triangle.m_vertices,part,i); + trimeshInterface->get_primitive_triangle(i, triangle); + callback->processTriangle(triangle.m_vertices, part, i); } trimeshInterface->unlock(); } - - } diff --git a/Extras/GIMPACTUtils/btGImpactConvexDecompositionShape.h b/Extras/GIMPACTUtils/btGImpactConvexDecompositionShape.h index 4710861f3..47a327065 100644 --- a/Extras/GIMPACTUtils/btGImpactConvexDecompositionShape.h +++ b/Extras/GIMPACTUtils/btGImpactConvexDecompositionShape.h @@ -24,32 +24,28 @@ subject to the following restrictions: #ifndef GIMPACT_CONVEX_DECOMPOSITION_SHAPE_H #define GIMPACT_CONVEX_DECOMPOSITION_SHAPE_H - -#include "BulletCollision/Gimpact/btGImpactShape.h" // box tree class - - +#include "BulletCollision/Gimpact/btGImpactShape.h" // box tree class //! This class creates a decomposition from a trimesh. /*! */ -class btGImpactConvexDecompositionShape : public btGImpactCompoundShape +class btGImpactConvexDecompositionShape : public btGImpactCompoundShape { protected: btAlignedObjectArray m_trimeshInterfaces; - class GIM_ConvexDecomposition* m_decomposition; + class GIM_ConvexDecomposition* m_decomposition; void buildConvexDecomposition(bool transformSubShapes); + public: - btGImpactConvexDecompositionShape( - btStridingMeshInterface * meshInterface, - const btVector3 & mesh_scale, - btScalar margin = btScalar(0.01),bool children_has_transform = true) - :btGImpactCompoundShape(children_has_transform) + btStridingMeshInterface* meshInterface, + const btVector3& mesh_scale, + btScalar margin = btScalar(0.01), bool children_has_transform = true) + : btGImpactCompoundShape(children_has_transform) { - m_collisionMargin = margin; btGImpactMeshShapePart::TrimeshPrimitiveManager triInterface; @@ -59,7 +55,7 @@ public: //add parts int part_count = meshInterface->getNumSubParts(); - for (int i=0;i< part_count;i++ ) + for (int i = 0; i < part_count; i++) { triInterface.m_part = i; m_trimeshInterfaces.push_back(triInterface); @@ -72,16 +68,12 @@ public: virtual ~btGImpactConvexDecompositionShape(); - SIMD_FORCE_INLINE btGImpactMeshShapePart::TrimeshPrimitiveManager * getTrimeshInterface(int part) + SIMD_FORCE_INLINE btGImpactMeshShapePart::TrimeshPrimitiveManager* getTrimeshInterface(int part) { return &m_trimeshInterfaces[part]; } - virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; - + virtual void processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const; }; - - - -#endif //GIMPACT_MESH_SHAPE_H +#endif //GIMPACT_MESH_SHAPE_H diff --git a/Extras/HACD/hacdCircularList.h b/Extras/HACD/hacdCircularList.h index a13394cd6..d09237ae2 100644 --- a/Extras/HACD/hacdCircularList.h +++ b/Extras/HACD/hacdCircularList.h @@ -15,66 +15,72 @@ #pragma once #ifndef HACD_CIRCULAR_LIST_H #define HACD_CIRCULAR_LIST_H -#include +#include #include "hacdVersion.h" namespace HACD { - //! CircularListElement class. - template < typename T > class CircularListElement - { - public: - T & GetData() { return m_data; } - const T & GetData() const { return m_data; } - CircularListElement * & GetNext() { return m_next; } - CircularListElement * & GetPrev() { return m_prev; } - const CircularListElement * & GetNext() const { return m_next; } - const CircularListElement * & GetPrev() const { return m_prev; } - //! Constructor - CircularListElement(const T & data) {m_data = data;} - CircularListElement(void){} - //! Destructor - ~CircularListElement(void){} - private: - T m_data; - CircularListElement * m_next; - CircularListElement * m_prev; +//! CircularListElement class. +template +class CircularListElement +{ +public: + T& GetData() { return m_data; } + const T& GetData() const { return m_data; } + CircularListElement*& GetNext() { return m_next; } + CircularListElement*& GetPrev() { return m_prev; } + const CircularListElement*& GetNext() const { return m_next; } + const CircularListElement*& GetPrev() const { return m_prev; } + //! Constructor + CircularListElement(const T& data) { m_data = data; } + CircularListElement(void) {} + //! Destructor + ~CircularListElement(void) {} - CircularListElement(const CircularListElement & rhs); - }; - - - //! CircularList class. - template < typename T > class CircularList +private: + T m_data; + CircularListElement* m_next; + CircularListElement* m_prev; + + CircularListElement(const CircularListElement& rhs); +}; + +//! CircularList class. +template +class CircularList +{ +public: + CircularListElement*& GetHead() { return m_head; } + const CircularListElement* GetHead() const { return m_head; } + bool IsEmpty() const { return (m_size == 0); } + size_t GetSize() const { return m_size; } + const T& GetData() const { return m_head->GetData(); } + T& GetData() { return m_head->GetData(); } + bool Delete(); + bool Delete(CircularListElement* element); + CircularListElement* Add(const T* data = 0); + CircularListElement* Add(const T& data); + bool Next(); + bool Prev(); + void Clear() { - public: - CircularListElement * & GetHead() { return m_head;} - const CircularListElement * GetHead() const { return m_head;} - bool IsEmpty() const { return (m_size == 0);} - size_t GetSize() const { return m_size; } - const T & GetData() const { return m_head->GetData(); } - T & GetData() { return m_head->GetData();} - bool Delete() ; - bool Delete(CircularListElement * element); - CircularListElement * Add(const T * data = 0); - CircularListElement * Add(const T & data); - bool Next(); - bool Prev(); - void Clear() { while(Delete());}; - const CircularList& operator=(const CircularList& rhs); - //! Constructor - CircularList() - { - m_head = 0; - m_size = 0; - } - CircularList(const CircularList& rhs); - //! Destructor - virtual ~CircularList(void) {Clear();}; - private: - CircularListElement * m_head; //!< a pointer to the head of the circular list - size_t m_size; //!< number of element in the circular list - + while (Delete()) + ; }; -} + const CircularList& operator=(const CircularList& rhs); + //! Constructor + CircularList() + { + m_head = 0; + m_size = 0; + } + CircularList(const CircularList& rhs); + //! Destructor + virtual ~CircularList(void) { Clear(); }; + +private: + CircularListElement* m_head; //!< a pointer to the head of the circular list + size_t m_size; //!< number of element in the circular list +}; +} // namespace HACD #include "hacdCircularList.inl" #endif diff --git a/Extras/HACD/hacdGraph.cpp b/Extras/HACD/hacdGraph.cpp index 4204f2d67..486dc30ee 100644 --- a/Extras/HACD/hacdGraph.cpp +++ b/Extras/HACD/hacdGraph.cpp @@ -14,279 +14,277 @@ */ #include "hacdGraph.h" namespace HACD -{ - - GraphEdge::GraphEdge() - { - m_convexHull = 0; - m_v1 = -1; - m_v2 = -1; - m_name = -1; - m_error = 0; - m_surf = 0; - m_perimeter = 0; - m_concavity = 0; - m_volume = 0; - m_deleted = false; - } - - GraphVertex::GraphVertex() - { - m_convexHull = 0; - m_name = -1; - m_cc = -1; - m_error = 0; - m_surf = 0; - m_perimeter = 0; - m_concavity = 0; - m_volume = 0; - m_deleted = false; - } - - bool GraphVertex::DeleteEdge(long name) - { - std::set::iterator it = m_edges.find(name); - if (it != m_edges.end() ) - { - m_edges.erase(it); - return true; - } - return false; - } - - Graph::Graph() - { - m_nV = 0; - m_nE = 0; - m_nCCs = 0; - } - - Graph::~Graph() - { - } - - void Graph::Allocate(size_t nV, size_t nE) - { - m_nV = nV; - m_edges.reserve(nE); - m_vertices.resize(nV); - for(size_t i = 0; i < nV; i++) - { - m_vertices[i].m_name = static_cast(i); - } - } - - long Graph::AddVertex() - { - size_t name = m_vertices.size(); - m_vertices.resize(name+1); - m_vertices[name].m_name = static_cast(name); - m_nV++; - return static_cast(name); - } - - long Graph::AddEdge(long v1, long v2) - { - size_t name = m_edges.size(); - m_edges.push_back(GraphEdge()); - m_edges[name].m_name = static_cast(name); - m_edges[name].m_v1 = v1; - m_edges[name].m_v2 = v2; - m_vertices[v1].AddEdge(static_cast(name)); - m_vertices[v2].AddEdge(static_cast(name)); - m_nE++; - return static_cast(name); - } - - bool Graph::DeleteEdge(long name) - { - if (name < static_cast(m_edges.size())) - { - long v1 = m_edges[name].m_v1; - long v2 = m_edges[name].m_v2; - m_edges[name].m_deleted = true; - m_vertices[v1].DeleteEdge(name); - m_vertices[v2].DeleteEdge(name); - delete m_edges[name].m_convexHull; - m_edges[name].m_distPoints.clear(); - m_edges[name].m_boudaryEdges.clear(); - m_edges[name].m_convexHull = 0; - m_nE--; - return true; - } - return false; - } - bool Graph::DeleteVertex(long name) - { - if (name < static_cast(m_vertices.size())) - { - m_vertices[name].m_deleted = true; - m_vertices[name].m_edges.clear(); - m_vertices[name].m_ancestors = std::vector(); - delete m_vertices[name].m_convexHull; - m_vertices[name].m_distPoints.clear(); - m_vertices[name].m_boudaryEdges.clear(); - m_vertices[name].m_convexHull = 0; - m_nV--; - return true; - } - return false; - } - bool Graph::EdgeCollapse(long v1, long v2) - { - long edgeToDelete = GetEdgeID(v1, v2); - if (edgeToDelete >= 0) - { - // delete the edge (v1, v2) - DeleteEdge(edgeToDelete); - // add v2 to v1 ancestors - m_vertices[v1].m_ancestors.push_back(v2); - // add v2's ancestors to v1's ancestors - m_vertices[v1].m_ancestors.insert(m_vertices[v1].m_ancestors.begin(), - m_vertices[v2].m_ancestors.begin(), - m_vertices[v2].m_ancestors.end()); - // update adjacency information - std::set & v1Edges = m_vertices[v1].m_edges; - std::set::const_iterator ed(m_vertices[v2].m_edges.begin()); - std::set::const_iterator itEnd(m_vertices[v2].m_edges.end()); - long b = -1; - for(; ed != itEnd; ++ed) - { - if (m_edges[*ed].m_v1 == v2) - { - b = m_edges[*ed].m_v2; - } - else - { - b = m_edges[*ed].m_v1; - } - if (GetEdgeID(v1, b) >= 0) - { - m_edges[*ed].m_deleted = true; - m_vertices[b].DeleteEdge(*ed); - m_nE--; - } - else - { - m_edges[*ed].m_v1 = v1; - m_edges[*ed].m_v2 = b; - v1Edges.insert(*ed); - } - } - // delete the vertex v2 - DeleteVertex(v2); - return true; - } - return false; - } - - long Graph::GetEdgeID(long v1, long v2) const - { - if (v1 < static_cast(m_vertices.size()) && !m_vertices[v1].m_deleted) - { - std::set::const_iterator ed(m_vertices[v1].m_edges.begin()); - std::set::const_iterator itEnd(m_vertices[v1].m_edges.end()); - for(; ed != itEnd; ++ed) - { - if ( (m_edges[*ed].m_v1 == v2) || - (m_edges[*ed].m_v2 == v2) ) - { - return m_edges[*ed].m_name; - } - } - } - return -1; - } - - void Graph::Print() const - { - std::cout << "-----------------------------" << std::endl; - std::cout << "vertices (" << m_nV << ")" << std::endl; - for (size_t v = 0; v < m_vertices.size(); ++v) - { - const GraphVertex & currentVertex = m_vertices[v]; - if (!m_vertices[v].m_deleted) - { - - std::cout << currentVertex.m_name << "\t"; - std::set::const_iterator ed(currentVertex.m_edges.begin()); - std::set::const_iterator itEnd(currentVertex.m_edges.end()); - for(; ed != itEnd; ++ed) - { - std::cout << "(" << m_edges[*ed].m_v1 << "," << m_edges[*ed].m_v2 << ") "; - } - std::cout << std::endl; - } - } - - std::cout << "vertices (" << m_nE << ")" << std::endl; - for (size_t e = 0; e < m_edges.size(); ++e) - { - const GraphEdge & currentEdge = m_edges[e]; - if (!m_edges[e].m_deleted) - { - std::cout << currentEdge.m_name << "\t(" - << m_edges[e].m_v1 << "," - << m_edges[e].m_v2 << ") "<< std::endl; - } - } - } - void Graph::Clear() - { - m_vertices.clear(); - m_edges.clear(); - m_nV = 0; - m_nE = 0; - } - - long Graph::ExtractCCs() - { - // all CCs to -1 - for (size_t v = 0; v < m_vertices.size(); ++v) - { - if (!m_vertices[v].m_deleted) - { - m_vertices[v].m_cc = -1; - } - } - - // we get the CCs - m_nCCs = 0; - long v2 = -1; - std::vector temp; - for (size_t v = 0; v < m_vertices.size(); ++v) - { - if (!m_vertices[v].m_deleted && m_vertices[v].m_cc == -1) - { - m_vertices[v].m_cc = static_cast(m_nCCs); - temp.clear(); - temp.push_back(m_vertices[v].m_name); - while (temp.size()) - { - long vertex = temp[temp.size()-1]; - temp.pop_back(); - std::set::const_iterator ed(m_vertices[vertex].m_edges.begin()); - std::set::const_iterator itEnd(m_vertices[vertex].m_edges.end()); - for(; ed != itEnd; ++ed) - { - if (m_edges[*ed].m_v1 == vertex) - { - v2 = m_edges[*ed].m_v2; - } - else - { - v2 = m_edges[*ed].m_v1; - } - if ( !m_vertices[v2].m_deleted && m_vertices[v2].m_cc == -1) - { - m_vertices[v2].m_cc = static_cast(m_nCCs); - temp.push_back(v2); - } - } - } - m_nCCs++; - } - } - return static_cast(m_nCCs); - } +{ +GraphEdge::GraphEdge() +{ + m_convexHull = 0; + m_v1 = -1; + m_v2 = -1; + m_name = -1; + m_error = 0; + m_surf = 0; + m_perimeter = 0; + m_concavity = 0; + m_volume = 0; + m_deleted = false; } + +GraphVertex::GraphVertex() +{ + m_convexHull = 0; + m_name = -1; + m_cc = -1; + m_error = 0; + m_surf = 0; + m_perimeter = 0; + m_concavity = 0; + m_volume = 0; + m_deleted = false; +} + +bool GraphVertex::DeleteEdge(long name) +{ + std::set::iterator it = m_edges.find(name); + if (it != m_edges.end()) + { + m_edges.erase(it); + return true; + } + return false; +} + +Graph::Graph() +{ + m_nV = 0; + m_nE = 0; + m_nCCs = 0; +} + +Graph::~Graph() +{ +} + +void Graph::Allocate(size_t nV, size_t nE) +{ + m_nV = nV; + m_edges.reserve(nE); + m_vertices.resize(nV); + for (size_t i = 0; i < nV; i++) + { + m_vertices[i].m_name = static_cast(i); + } +} + +long Graph::AddVertex() +{ + size_t name = m_vertices.size(); + m_vertices.resize(name + 1); + m_vertices[name].m_name = static_cast(name); + m_nV++; + return static_cast(name); +} + +long Graph::AddEdge(long v1, long v2) +{ + size_t name = m_edges.size(); + m_edges.push_back(GraphEdge()); + m_edges[name].m_name = static_cast(name); + m_edges[name].m_v1 = v1; + m_edges[name].m_v2 = v2; + m_vertices[v1].AddEdge(static_cast(name)); + m_vertices[v2].AddEdge(static_cast(name)); + m_nE++; + return static_cast(name); +} + +bool Graph::DeleteEdge(long name) +{ + if (name < static_cast(m_edges.size())) + { + long v1 = m_edges[name].m_v1; + long v2 = m_edges[name].m_v2; + m_edges[name].m_deleted = true; + m_vertices[v1].DeleteEdge(name); + m_vertices[v2].DeleteEdge(name); + delete m_edges[name].m_convexHull; + m_edges[name].m_distPoints.clear(); + m_edges[name].m_boudaryEdges.clear(); + m_edges[name].m_convexHull = 0; + m_nE--; + return true; + } + return false; +} +bool Graph::DeleteVertex(long name) +{ + if (name < static_cast(m_vertices.size())) + { + m_vertices[name].m_deleted = true; + m_vertices[name].m_edges.clear(); + m_vertices[name].m_ancestors = std::vector(); + delete m_vertices[name].m_convexHull; + m_vertices[name].m_distPoints.clear(); + m_vertices[name].m_boudaryEdges.clear(); + m_vertices[name].m_convexHull = 0; + m_nV--; + return true; + } + return false; +} +bool Graph::EdgeCollapse(long v1, long v2) +{ + long edgeToDelete = GetEdgeID(v1, v2); + if (edgeToDelete >= 0) + { + // delete the edge (v1, v2) + DeleteEdge(edgeToDelete); + // add v2 to v1 ancestors + m_vertices[v1].m_ancestors.push_back(v2); + // add v2's ancestors to v1's ancestors + m_vertices[v1].m_ancestors.insert(m_vertices[v1].m_ancestors.begin(), + m_vertices[v2].m_ancestors.begin(), + m_vertices[v2].m_ancestors.end()); + // update adjacency information + std::set& v1Edges = m_vertices[v1].m_edges; + std::set::const_iterator ed(m_vertices[v2].m_edges.begin()); + std::set::const_iterator itEnd(m_vertices[v2].m_edges.end()); + long b = -1; + for (; ed != itEnd; ++ed) + { + if (m_edges[*ed].m_v1 == v2) + { + b = m_edges[*ed].m_v2; + } + else + { + b = m_edges[*ed].m_v1; + } + if (GetEdgeID(v1, b) >= 0) + { + m_edges[*ed].m_deleted = true; + m_vertices[b].DeleteEdge(*ed); + m_nE--; + } + else + { + m_edges[*ed].m_v1 = v1; + m_edges[*ed].m_v2 = b; + v1Edges.insert(*ed); + } + } + // delete the vertex v2 + DeleteVertex(v2); + return true; + } + return false; +} + +long Graph::GetEdgeID(long v1, long v2) const +{ + if (v1 < static_cast(m_vertices.size()) && !m_vertices[v1].m_deleted) + { + std::set::const_iterator ed(m_vertices[v1].m_edges.begin()); + std::set::const_iterator itEnd(m_vertices[v1].m_edges.end()); + for (; ed != itEnd; ++ed) + { + if ((m_edges[*ed].m_v1 == v2) || + (m_edges[*ed].m_v2 == v2)) + { + return m_edges[*ed].m_name; + } + } + } + return -1; +} + +void Graph::Print() const +{ + std::cout << "-----------------------------" << std::endl; + std::cout << "vertices (" << m_nV << ")" << std::endl; + for (size_t v = 0; v < m_vertices.size(); ++v) + { + const GraphVertex& currentVertex = m_vertices[v]; + if (!m_vertices[v].m_deleted) + { + std::cout << currentVertex.m_name << "\t"; + std::set::const_iterator ed(currentVertex.m_edges.begin()); + std::set::const_iterator itEnd(currentVertex.m_edges.end()); + for (; ed != itEnd; ++ed) + { + std::cout << "(" << m_edges[*ed].m_v1 << "," << m_edges[*ed].m_v2 << ") "; + } + std::cout << std::endl; + } + } + + std::cout << "vertices (" << m_nE << ")" << std::endl; + for (size_t e = 0; e < m_edges.size(); ++e) + { + const GraphEdge& currentEdge = m_edges[e]; + if (!m_edges[e].m_deleted) + { + std::cout << currentEdge.m_name << "\t(" + << m_edges[e].m_v1 << "," + << m_edges[e].m_v2 << ") " << std::endl; + } + } +} +void Graph::Clear() +{ + m_vertices.clear(); + m_edges.clear(); + m_nV = 0; + m_nE = 0; +} + +long Graph::ExtractCCs() +{ + // all CCs to -1 + for (size_t v = 0; v < m_vertices.size(); ++v) + { + if (!m_vertices[v].m_deleted) + { + m_vertices[v].m_cc = -1; + } + } + + // we get the CCs + m_nCCs = 0; + long v2 = -1; + std::vector temp; + for (size_t v = 0; v < m_vertices.size(); ++v) + { + if (!m_vertices[v].m_deleted && m_vertices[v].m_cc == -1) + { + m_vertices[v].m_cc = static_cast(m_nCCs); + temp.clear(); + temp.push_back(m_vertices[v].m_name); + while (temp.size()) + { + long vertex = temp[temp.size() - 1]; + temp.pop_back(); + std::set::const_iterator ed(m_vertices[vertex].m_edges.begin()); + std::set::const_iterator itEnd(m_vertices[vertex].m_edges.end()); + for (; ed != itEnd; ++ed) + { + if (m_edges[*ed].m_v1 == vertex) + { + v2 = m_edges[*ed].m_v2; + } + else + { + v2 = m_edges[*ed].m_v1; + } + if (!m_vertices[v2].m_deleted && m_vertices[v2].m_cc == -1) + { + m_vertices[v2].m_cc = static_cast(m_nCCs); + temp.push_back(v2); + } + } + } + m_nCCs++; + } + } + return static_cast(m_nCCs); +} +} // namespace HACD diff --git a/Extras/HACD/hacdGraph.h b/Extras/HACD/hacdGraph.h index 9b64aac60..7df9dd51f 100644 --- a/Extras/HACD/hacdGraph.h +++ b/Extras/HACD/hacdGraph.h @@ -24,97 +24,96 @@ namespace HACD { - class GraphVertex; - class GraphEdge; - class Graph; - class HACD; - - class GraphVertex - { - public: - bool AddEdge(long name) - { - m_edges.insert(name); - return true; - } - bool DeleteEdge(long name); - GraphVertex(); - ~GraphVertex(){ delete m_convexHull;}; - private: - long m_name; - long m_cc; - std::set m_edges; - bool m_deleted; - std::vector m_ancestors; - std::map m_distPoints; +class GraphVertex; +class GraphEdge; +class Graph; +class HACD; - Real m_error; - double m_surf; - double m_volume; - double m_perimeter; - double m_concavity; - ICHull * m_convexHull; - std::set m_boudaryEdges; - +class GraphVertex +{ +public: + bool AddEdge(long name) + { + m_edges.insert(name); + return true; + } + bool DeleteEdge(long name); + GraphVertex(); + ~GraphVertex() { delete m_convexHull; }; - friend class GraphEdge; - friend class Graph; - friend class HACD; - }; - - class GraphEdge - { - public: - GraphEdge(); - ~GraphEdge(){delete m_convexHull;}; - private: - long m_name; - long m_v1; - long m_v2; - std::map m_distPoints; - Real m_error; - double m_surf; - double m_volume; - double m_perimeter; - double m_concavity; - ICHull * m_convexHull; - std::set m_boudaryEdges; - bool m_deleted; - +private: + long m_name; + long m_cc; + std::set m_edges; + bool m_deleted; + std::vector m_ancestors; + std::map m_distPoints; - - friend class GraphVertex; - friend class Graph; - friend class HACD; - }; - - class Graph - { - public: - size_t GetNEdges() const { return m_nE;} - size_t GetNVertices() const { return m_nV;} - bool EdgeCollapse(long v1, long v2); - long AddVertex(); - long AddEdge(long v1, long v2); - bool DeleteEdge(long name); - bool DeleteVertex(long name); - long GetEdgeID(long v1, long v2) const; - void Clear(); - void Print() const; - long ExtractCCs(); - - Graph(); - virtual ~Graph(); - void Allocate(size_t nV, size_t nE); + Real m_error; + double m_surf; + double m_volume; + double m_perimeter; + double m_concavity; + ICHull* m_convexHull; + std::set m_boudaryEdges; - private: - size_t m_nCCs; - size_t m_nV; - size_t m_nE; - std::vector m_edges; - std::vector m_vertices; + friend class GraphEdge; + friend class Graph; + friend class HACD; +}; - friend class HACD; - }; -} +class GraphEdge +{ +public: + GraphEdge(); + ~GraphEdge() { delete m_convexHull; }; + +private: + long m_name; + long m_v1; + long m_v2; + std::map m_distPoints; + Real m_error; + double m_surf; + double m_volume; + double m_perimeter; + double m_concavity; + ICHull* m_convexHull; + std::set m_boudaryEdges; + bool m_deleted; + + friend class GraphVertex; + friend class Graph; + friend class HACD; +}; + +class Graph +{ +public: + size_t GetNEdges() const { return m_nE; } + size_t GetNVertices() const { return m_nV; } + bool EdgeCollapse(long v1, long v2); + long AddVertex(); + long AddEdge(long v1, long v2); + bool DeleteEdge(long name); + bool DeleteVertex(long name); + long GetEdgeID(long v1, long v2) const; + void Clear(); + void Print() const; + long ExtractCCs(); + + Graph(); + virtual ~Graph(); + void Allocate(size_t nV, size_t nE); + +private: + size_t m_nCCs; + size_t m_nV; + size_t m_nE; + std::vector m_edges; + std::vector m_vertices; + + friend class HACD; +}; +} // namespace HACD #endif diff --git a/Extras/HACD/hacdHACD.cpp b/Extras/HACD/hacdHACD.cpp index 5c2edf217..d9347e0c2 100644 --- a/Extras/HACD/hacdHACD.cpp +++ b/Extras/HACD/hacdHACD.cpp @@ -14,7 +14,7 @@ */ #ifndef _CRT_SECURE_NO_WARNINGS #define _CRT_SECURE_NO_WARNINGS -#endif //_CRT_SECURE_NO_WARNINGS +#endif //_CRT_SECURE_NO_WARNINGS #include #include "hacdGraph.h" @@ -26,826 +26,826 @@ #include #include "assert.h" -bool gCancelRequest=false; +bool gCancelRequest = false; namespace HACD -{ - double HACD::Concavity(ICHull & ch, std::map & distPoints) - { - double concavity = 0.0; - double distance = 0.0; - std::map::iterator itDP(distPoints.begin()); - std::map::iterator itDPEnd(distPoints.end()); - for(; itDP != itDPEnd; ++itDP) +{ +double HACD::Concavity(ICHull& ch, std::map& distPoints) +{ + double concavity = 0.0; + double distance = 0.0; + std::map::iterator itDP(distPoints.begin()); + std::map::iterator itDPEnd(distPoints.end()); + for (; itDP != itDPEnd; ++itDP) + { + if (!(itDP->second).m_computed) { - if (!(itDP->second).m_computed) - { - if (itDP->first >= 0) - { - distance = ch.ComputeDistance(itDP->first, m_points[itDP->first], m_normals[itDP->first], (itDP->second).m_computed, true); - } - else - { - distance = ch.ComputeDistance(itDP->first, m_facePoints[-itDP->first-1], m_faceNormals[-itDP->first-1], (itDP->second).m_computed, true); - } - } - else - { - distance = (itDP->second).m_dist; - } - if (concavity < distance) + if (itDP->first >= 0) { - concavity = distance; + distance = ch.ComputeDistance(itDP->first, m_points[itDP->first], m_normals[itDP->first], (itDP->second).m_computed, true); + } + else + { + distance = ch.ComputeDistance(itDP->first, m_facePoints[-itDP->first - 1], m_faceNormals[-itDP->first - 1], (itDP->second).m_computed, true); } } - return concavity; - } - - void HACD::CreateGraph() - { - // vertex to triangle adjacency information - std::vector< std::set > vertexToTriangles; - vertexToTriangles.resize(m_nPoints); - for(size_t t = 0; t < m_nTriangles; ++t) + else { - vertexToTriangles[m_triangles[t].X()].insert(static_cast(t)); - vertexToTriangles[m_triangles[t].Y()].insert(static_cast(t)); - vertexToTriangles[m_triangles[t].Z()].insert(static_cast(t)); + distance = (itDP->second).m_dist; } - - m_graph.Clear(); - m_graph.Allocate(m_nTriangles, 5 * m_nTriangles); - unsigned long long tr1[3]; - unsigned long long tr2[3]; - long i1, j1, k1, i2, j2, k2; - long t1, t2; - for (size_t v = 0; v < m_nPoints; v++) + if (concavity < distance) { - std::set::const_iterator it1(vertexToTriangles[v].begin()), itEnd(vertexToTriangles[v].end()); - for(; it1 != itEnd; ++it1) + concavity = distance; + } + } + return concavity; +} + +void HACD::CreateGraph() +{ + // vertex to triangle adjacency information + std::vector > vertexToTriangles; + vertexToTriangles.resize(m_nPoints); + for (size_t t = 0; t < m_nTriangles; ++t) + { + vertexToTriangles[m_triangles[t].X()].insert(static_cast(t)); + vertexToTriangles[m_triangles[t].Y()].insert(static_cast(t)); + vertexToTriangles[m_triangles[t].Z()].insert(static_cast(t)); + } + + m_graph.Clear(); + m_graph.Allocate(m_nTriangles, 5 * m_nTriangles); + unsigned long long tr1[3]; + unsigned long long tr2[3]; + long i1, j1, k1, i2, j2, k2; + long t1, t2; + for (size_t v = 0; v < m_nPoints; v++) + { + std::set::const_iterator it1(vertexToTriangles[v].begin()), itEnd(vertexToTriangles[v].end()); + for (; it1 != itEnd; ++it1) + { + t1 = *it1; + i1 = m_triangles[t1].X(); + j1 = m_triangles[t1].Y(); + k1 = m_triangles[t1].Z(); + tr1[0] = GetEdgeIndex(i1, j1); + tr1[1] = GetEdgeIndex(j1, k1); + tr1[2] = GetEdgeIndex(k1, i1); + std::set::const_iterator it2(it1); + for (++it2; it2 != itEnd; ++it2) { - t1 = *it1; - i1 = m_triangles[t1].X(); - j1 = m_triangles[t1].Y(); - k1 = m_triangles[t1].Z(); - tr1[0] = GetEdgeIndex(i1, j1); - tr1[1] = GetEdgeIndex(j1, k1); - tr1[2] = GetEdgeIndex(k1, i1); - std::set::const_iterator it2(it1); - for(++it2; it2 != itEnd; ++it2) + t2 = *it2; + i2 = m_triangles[t2].X(); + j2 = m_triangles[t2].Y(); + k2 = m_triangles[t2].Z(); + tr2[0] = GetEdgeIndex(i2, j2); + tr2[1] = GetEdgeIndex(j2, k2); + tr2[2] = GetEdgeIndex(k2, i2); + int shared = 0; + for (int i = 0; i < 3; ++i) { - t2 = *it2; - i2 = m_triangles[t2].X(); - j2 = m_triangles[t2].Y(); - k2 = m_triangles[t2].Z(); - tr2[0] = GetEdgeIndex(i2, j2); - tr2[1] = GetEdgeIndex(j2, k2); - tr2[2] = GetEdgeIndex(k2, i2); - int shared = 0; - for(int i = 0; i < 3; ++i) + for (int j = 0; j < 3; ++j) { - for(int j = 0; j < 3; ++j) + if (tr1[i] == tr2[j]) { - if (tr1[i] == tr2[j]) + shared++; + } + } + } + if (shared == 1) // two triangles are connected if they share exactly one edge + { + m_graph.AddEdge(t1, t2); + } + } + } + } + if (m_ccConnectDist >= 0.0) + { + m_graph.ExtractCCs(); + if (m_graph.m_nCCs > 1) + { + std::vector > cc2V; + cc2V.resize(m_graph.m_nCCs); + long cc; + for (size_t t = 0; t < m_nTriangles; ++t) + { + cc = m_graph.m_vertices[t].m_cc; + cc2V[cc].insert(m_triangles[t].X()); + cc2V[cc].insert(m_triangles[t].Y()); + cc2V[cc].insert(m_triangles[t].Z()); + } + + for (size_t cc1 = 0; cc1 < m_graph.m_nCCs; ++cc1) + { + for (size_t cc2 = cc1 + 1; cc2 < m_graph.m_nCCs; ++cc2) + { + std::set::const_iterator itV1(cc2V[cc1].begin()), itVEnd1(cc2V[cc1].end()); + for (; itV1 != itVEnd1; ++itV1) + { + double distC1C2 = std::numeric_limits::max(); + double dist; + t1 = -1; + t2 = -1; + std::set::const_iterator itV2(cc2V[cc2].begin()), itVEnd2(cc2V[cc2].end()); + for (; itV2 != itVEnd2; ++itV2) + { + dist = (m_points[*itV1] - m_points[*itV2]).GetNorm(); + if (dist < distC1C2) { - shared++; + distC1C2 = dist; + t1 = *vertexToTriangles[*itV1].begin(); + + std::set::const_iterator it2(vertexToTriangles[*itV2].begin()), + it2End(vertexToTriangles[*itV2].end()); + t2 = -1; + for (; it2 != it2End; ++it2) + { + if (*it2 != t1) + { + t2 = *it2; + break; + } + } + } + } + if (distC1C2 <= m_ccConnectDist && t1 > 0 && t2 > 0) + { + m_graph.AddEdge(t1, t2); + } + } + } + } + } + } +} +void HACD::InitializeDualGraph() +{ + long i, j, k; + Vec3 u, v, w, normal; + delete[] m_normals; + m_normals = new Vec3[m_nPoints]; + if (m_addFacesPoints) + { + delete[] m_facePoints; + delete[] m_faceNormals; + m_facePoints = new Vec3[m_nTriangles]; + m_faceNormals = new Vec3[m_nTriangles]; + } + memset(m_normals, 0, sizeof(Vec3) * m_nPoints); + for (unsigned long f = 0; f < m_nTriangles; f++) + { + if (m_callBack) (*m_callBack)("+ InitializeDualGraph\n", f, m_nTriangles, 0); + + if (gCancelRequest) + return; + + i = m_triangles[f].X(); + j = m_triangles[f].Y(); + k = m_triangles[f].Z(); + + m_graph.m_vertices[f].m_distPoints[i].m_distOnly = false; + m_graph.m_vertices[f].m_distPoints[j].m_distOnly = false; + m_graph.m_vertices[f].m_distPoints[k].m_distOnly = false; + + ICHull* ch = new ICHull; + m_graph.m_vertices[f].m_convexHull = ch; + ch->AddPoint(m_points[i], i); + ch->AddPoint(m_points[j], j); + ch->AddPoint(m_points[k], k); + ch->SetDistPoints(&m_graph.m_vertices[f].m_distPoints); + + u = m_points[j] - m_points[i]; + v = m_points[k] - m_points[i]; + w = m_points[k] - m_points[j]; + normal = u ^ v; + + m_normals[i] += normal; + m_normals[j] += normal; + m_normals[k] += normal; + + m_graph.m_vertices[f].m_surf = normal.GetNorm(); + m_graph.m_vertices[f].m_perimeter = u.GetNorm() + v.GetNorm() + w.GetNorm(); + + normal.Normalize(); + + m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(i, j)); + m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(j, k)); + m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(k, i)); + if (m_addFacesPoints) + { + m_faceNormals[f] = normal; + m_facePoints[f] = (m_points[i] + m_points[j] + m_points[k]) / 3.0; + m_graph.m_vertices[f].m_distPoints[-static_cast(f) - 1].m_distOnly = true; + } + if (m_addExtraDistPoints) + { // we need a kd-tree structure to accelerate this part! + long i1, j1, k1; + Vec3 u1, v1, normal1; + normal = -normal; + double distance = 0.0; + double distMin = 0.0; + size_t faceIndex = m_nTriangles; + Vec3 seedPoint((m_points[i] + m_points[j] + m_points[k]) / 3.0); + long nhit = 0; + for (size_t f1 = 0; f1 < m_nTriangles; f1++) + { + i1 = m_triangles[f1].X(); + j1 = m_triangles[f1].Y(); + k1 = m_triangles[f1].Z(); + u1 = m_points[j1] - m_points[i1]; + v1 = m_points[k1] - m_points[i1]; + normal1 = (u1 ^ v1); + if (normal * normal1 > 0.0) + { + nhit = IntersectRayTriangle(Vec3(seedPoint.X(), seedPoint.Y(), seedPoint.Z()), + Vec3(normal.X(), normal.Y(), normal.Z()), + Vec3(m_points[i1].X(), m_points[i1].Y(), m_points[i1].Z()), + Vec3(m_points[j1].X(), m_points[j1].Y(), m_points[j1].Z()), + Vec3(m_points[k1].X(), m_points[k1].Y(), m_points[k1].Z()), + distance); + if ((nhit == 1) && ((distMin > distance) || (faceIndex == m_nTriangles))) + { + distMin = distance; + faceIndex = f1; + } + } + } + if (faceIndex < m_nTriangles) + { + i1 = m_triangles[faceIndex].X(); + j1 = m_triangles[faceIndex].Y(); + k1 = m_triangles[faceIndex].Z(); + m_graph.m_vertices[f].m_distPoints[i1].m_distOnly = true; + m_graph.m_vertices[f].m_distPoints[j1].m_distOnly = true; + m_graph.m_vertices[f].m_distPoints[k1].m_distOnly = true; + if (m_addFacesPoints) + { + m_graph.m_vertices[f].m_distPoints[-static_cast(faceIndex) - 1].m_distOnly = true; + } + } + } + } + for (size_t v = 0; v < m_nPoints; v++) + { + m_normals[v].Normalize(); + } +} + +void HACD::NormalizeData() +{ + if (m_nPoints == 0) + { + return; + } + m_barycenter = m_points[0]; + Vec3 min = m_points[0]; + Vec3 max = m_points[0]; + Real x, y, z; + for (size_t v = 1; v < m_nPoints; v++) + { + m_barycenter += m_points[v]; + x = m_points[v].X(); + y = m_points[v].Y(); + z = m_points[v].Z(); + if (x < min.X()) + min.X() = x; + else if (x > max.X()) + max.X() = x; + if (y < min.Y()) + min.Y() = y; + else if (y > max.Y()) + max.Y() = y; + if (z < min.Z()) + min.Z() = z; + else if (z > max.Z()) + max.Z() = z; + } + m_barycenter /= static_cast(m_nPoints); + m_diag = (max - min).GetNorm(); + const Real invDiag = static_cast(2.0 * m_scale / m_diag); + if (m_diag != 0.0) + { + for (size_t v = 0; v < m_nPoints; v++) + { + m_points[v] = (m_points[v] - m_barycenter) * invDiag; + } + } +} +void HACD::DenormalizeData() +{ + if (m_nPoints == 0) + { + return; + } + if (m_diag != 0.0) + { + const Real diag = static_cast(m_diag / (2.0 * m_scale)); + for (size_t v = 0; v < m_nPoints; v++) + { + m_points[v] = m_points[v] * diag + m_barycenter; + } + } +} +HACD::HACD(void) +{ + m_convexHulls = 0; + m_triangles = 0; + m_points = 0; + m_normals = 0; + m_nTriangles = 0; + m_nPoints = 0; + m_nClusters = 0; + m_concavity = 0.0; + m_diag = 1.0; + m_barycenter = Vec3(0.0, 0.0, 0.0); + m_alpha = 0.1; + m_beta = 0.1; + m_nVerticesPerCH = 30; + m_callBack = 0; + m_addExtraDistPoints = false; + m_addNeighboursDistPoints = false; + m_scale = 1000.0; + m_partition = 0; + m_nMinClusters = 3; + m_facePoints = 0; + m_faceNormals = 0; + m_ccConnectDist = 30; +} +HACD::~HACD(void) +{ + delete[] m_normals; + delete[] m_convexHulls; + delete[] m_partition; + delete[] m_facePoints; + delete[] m_faceNormals; +} +int iteration = 0; +void HACD::ComputeEdgeCost(size_t e) +{ + GraphEdge& gE = m_graph.m_edges[e]; + long v1 = gE.m_v1; + long v2 = gE.m_v2; + + if (m_graph.m_vertices[v2].m_distPoints.size() > m_graph.m_vertices[v1].m_distPoints.size()) + { + gE.m_v1 = v2; + gE.m_v2 = v1; + //std::swap(v1, v2); + std::swap(v1, v2); + } + GraphVertex& gV1 = m_graph.m_vertices[v1]; + GraphVertex& gV2 = m_graph.m_vertices[v2]; + + // delete old convex-hull + delete gE.m_convexHull; + // create the edge's convex-hull + ICHull* ch = new ICHull; + gE.m_convexHull = ch; + (*ch) = (*gV1.m_convexHull); + + // update distPoints + gE.m_distPoints = gV1.m_distPoints; + std::map::iterator itDP(gV2.m_distPoints.begin()); + std::map::iterator itDPEnd(gV2.m_distPoints.end()); + std::map::iterator itDP1; + + for (; itDP != itDPEnd; ++itDP) + { + itDP1 = gE.m_distPoints.find(itDP->first); + if (itDP1 == gE.m_distPoints.end()) + { + gE.m_distPoints[itDP->first].m_distOnly = (itDP->second).m_distOnly; + if (!(itDP->second).m_distOnly) + { + ch->AddPoint(m_points[itDP->first], itDP->first); + } + } + else + { + if ((itDP1->second).m_distOnly && !(itDP->second).m_distOnly) + { + gE.m_distPoints[itDP->first].m_distOnly = false; + ch->AddPoint(m_points[itDP->first], itDP->first); + } + } + } + + ch->SetDistPoints(&gE.m_distPoints); + // create the convex-hull + while (ch->Process() == ICHullErrorInconsistent) // if we face problems when constructing the visual-hull. really ugly!!!! + { + // if (m_callBack) (*m_callBack)("\t Problem with convex-hull construction [HACD::ComputeEdgeCost]\n", 0.0, 0.0, 0); + ch = new ICHull; + CircularList& verticesCH = (gE.m_convexHull)->GetMesh().m_vertices; + size_t nV = verticesCH.GetSize(); + long ptIndex = 0; + verticesCH.Next(); + for (size_t v = 1; v < nV; ++v) + { + ptIndex = verticesCH.GetHead()->GetData().m_name; + if (ptIndex != ICHull::sc_dummyIndex /* && ptIndex < m_nPoints*/) + ch->AddPoint(m_points[ptIndex], ptIndex); + verticesCH.Next(); + } + delete gE.m_convexHull; + gE.m_convexHull = ch; + } + double volume = 0.0; + double concavity = 0.0; + if (ch->IsFlat()) + { + bool insideHull; + std::map::iterator itDP(gE.m_distPoints.begin()); + std::map::iterator itDPEnd(gE.m_distPoints.end()); + for (; itDP != itDPEnd; ++itDP) + { + if (itDP->first >= 0) + { + concavity = std::max(concavity, ch->ComputeDistance(itDP->first, m_points[itDP->first], m_normals[itDP->first], insideHull, false)); + } + } + } + else + { + if (m_addNeighboursDistPoints) + { // add distance points from adjacent clusters + std::set eEdges; + std::set_union(gV1.m_edges.begin(), + gV1.m_edges.end(), + gV2.m_edges.begin(), + gV2.m_edges.end(), + std::inserter(eEdges, eEdges.begin())); + + std::set::const_iterator ed(eEdges.begin()); + std::set::const_iterator itEnd(eEdges.end()); + long a, b, c; + for (; ed != itEnd; ++ed) + { + a = m_graph.m_edges[*ed].m_v1; + b = m_graph.m_edges[*ed].m_v2; + if (a != v2 && a != v1) + { + c = a; + } + else if (b != v2 && b != v1) + { + c = b; + } + else + { + c = -1; + } + if (c > 0) + { + GraphVertex& gVC = m_graph.m_vertices[c]; + std::map::iterator itDP(gVC.m_distPoints.begin()); + std::map::iterator itDPEnd(gVC.m_distPoints.end()); + std::map::iterator itDP1; + for (; itDP != itDPEnd; ++itDP) + { + itDP1 = gE.m_distPoints.find(itDP->first); + if (itDP1 == gE.m_distPoints.end()) + { + if (itDP->first >= 0 && itDP1 == gE.m_distPoints.end() && ch->IsInside(m_points[itDP->first])) + { + gE.m_distPoints[itDP->first].m_distOnly = true; + } + else if (itDP->first < 0 && ch->IsInside(m_facePoints[-itDP->first - 1])) + { + gE.m_distPoints[itDP->first].m_distOnly = true; } } } - if (shared == 1) // two triangles are connected if they share exactly one edge - { - m_graph.AddEdge(t1, t2); - } } } - } - if (m_ccConnectDist >= 0.0) - { - m_graph.ExtractCCs(); - if (m_graph.m_nCCs > 1) - { - std::vector< std::set > cc2V; - cc2V.resize(m_graph.m_nCCs); - long cc; - for(size_t t = 0; t < m_nTriangles; ++t) - { - cc = m_graph.m_vertices[t].m_cc; - cc2V[cc].insert(m_triangles[t].X()); - cc2V[cc].insert(m_triangles[t].Y()); - cc2V[cc].insert(m_triangles[t].Z()); - } - - for(size_t cc1 = 0; cc1 < m_graph.m_nCCs; ++cc1) - { - for(size_t cc2 = cc1+1; cc2 < m_graph.m_nCCs; ++cc2) - { - std::set::const_iterator itV1(cc2V[cc1].begin()), itVEnd1(cc2V[cc1].end()); - for(; itV1 != itVEnd1; ++itV1) - { - double distC1C2 = std::numeric_limits::max(); - double dist; - t1 = -1; - t2 = -1; - std::set::const_iterator itV2(cc2V[cc2].begin()), itVEnd2(cc2V[cc2].end()); - for(; itV2 != itVEnd2; ++itV2) - { - dist = (m_points[*itV1] - m_points[*itV2]).GetNorm(); - if (dist < distC1C2) - { - distC1C2 = dist; - t1 = *vertexToTriangles[*itV1].begin(); - - std::set::const_iterator it2(vertexToTriangles[*itV2].begin()), - it2End(vertexToTriangles[*itV2].end()); - t2 = -1; - for(; it2 != it2End; ++it2) - { - if (*it2 != t1) - { - t2 = *it2; - break; - } - } - } - } - if (distC1C2 <= m_ccConnectDist && t1 > 0 && t2 > 0) - { - - m_graph.AddEdge(t1, t2); - } - } - } - } - } - } - } - void HACD::InitializeDualGraph() - { - long i, j, k; - Vec3 u, v, w, normal; - delete [] m_normals; - m_normals = new Vec3[m_nPoints]; - if (m_addFacesPoints) - { - delete [] m_facePoints; - delete [] m_faceNormals; - m_facePoints = new Vec3[m_nTriangles]; - m_faceNormals = new Vec3[m_nTriangles]; - } - memset(m_normals, 0, sizeof(Vec3) * m_nPoints); - for(unsigned long f = 0; f < m_nTriangles; f++) - { - if (m_callBack) (*m_callBack)("+ InitializeDualGraph\n", f, m_nTriangles, 0); - - if (gCancelRequest) - return; - - i = m_triangles[f].X(); - j = m_triangles[f].Y(); - k = m_triangles[f].Z(); - - m_graph.m_vertices[f].m_distPoints[i].m_distOnly = false; - m_graph.m_vertices[f].m_distPoints[j].m_distOnly = false; - m_graph.m_vertices[f].m_distPoints[k].m_distOnly = false; - - ICHull * ch = new ICHull; - m_graph.m_vertices[f].m_convexHull = ch; - ch->AddPoint(m_points[i], i); - ch->AddPoint(m_points[j], j); - ch->AddPoint(m_points[k], k); - ch->SetDistPoints(&m_graph.m_vertices[f].m_distPoints); - - u = m_points[j] - m_points[i]; - v = m_points[k] - m_points[i]; - w = m_points[k] - m_points[j]; - normal = u ^ v; - - m_normals[i] += normal; - m_normals[j] += normal; - m_normals[k] += normal; - - m_graph.m_vertices[f].m_surf = normal.GetNorm(); - m_graph.m_vertices[f].m_perimeter = u.GetNorm() + v.GetNorm() + w.GetNorm(); - - normal.Normalize(); - - m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(i,j)); - m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(j,k)); - m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(k,i)); - if(m_addFacesPoints) - { - m_faceNormals[f] = normal; - m_facePoints[f] = (m_points[i] + m_points[j] + m_points[k]) / 3.0; - m_graph.m_vertices[f].m_distPoints[-static_cast(f)-1].m_distOnly = true; - } - if (m_addExtraDistPoints) - {// we need a kd-tree structure to accelerate this part! - long i1, j1, k1; - Vec3 u1, v1, normal1; - normal = -normal; - double distance = 0.0; - double distMin = 0.0; - size_t faceIndex = m_nTriangles; - Vec3 seedPoint((m_points[i] + m_points[j] + m_points[k]) / 3.0); - long nhit = 0; - for(size_t f1 = 0; f1 < m_nTriangles; f1++) - { - i1 = m_triangles[f1].X(); - j1 = m_triangles[f1].Y(); - k1 = m_triangles[f1].Z(); - u1 = m_points[j1] - m_points[i1]; - v1 = m_points[k1] - m_points[i1]; - normal1 = (u1 ^ v1); - if (normal * normal1 > 0.0) - { - nhit = IntersectRayTriangle(Vec3(seedPoint.X(), seedPoint.Y(), seedPoint.Z()), - Vec3(normal.X(), normal.Y(), normal.Z()), - Vec3(m_points[i1].X(), m_points[i1].Y(), m_points[i1].Z()), - Vec3(m_points[j1].X(), m_points[j1].Y(), m_points[j1].Z()), - Vec3(m_points[k1].X(), m_points[k1].Y(), m_points[k1].Z()), - distance); - if ((nhit==1) && ((distMin > distance) || (faceIndex == m_nTriangles))) - { - distMin = distance; - faceIndex = f1; - } - - } - } - if (faceIndex < m_nTriangles ) - { - i1 = m_triangles[faceIndex].X(); - j1 = m_triangles[faceIndex].Y(); - k1 = m_triangles[faceIndex].Z(); - m_graph.m_vertices[f].m_distPoints[i1].m_distOnly = true; - m_graph.m_vertices[f].m_distPoints[j1].m_distOnly = true; - m_graph.m_vertices[f].m_distPoints[k1].m_distOnly = true; - if (m_addFacesPoints) - { - m_graph.m_vertices[f].m_distPoints[-static_cast(faceIndex)-1].m_distOnly = true; - } - } - } - } - for (size_t v = 0; v < m_nPoints; v++) - { - m_normals[v].Normalize(); } - } - - void HACD::NormalizeData() - { - if (m_nPoints == 0) - { - return; - } - m_barycenter = m_points[0]; - Vec3 min = m_points[0]; - Vec3 max = m_points[0]; - Real x, y, z; - for (size_t v = 1; v < m_nPoints ; v++) - { - m_barycenter += m_points[v]; - x = m_points[v].X(); - y = m_points[v].Y(); - z = m_points[v].Z(); - if ( x < min.X()) min.X() = x; - else if ( x > max.X()) max.X() = x; - if ( y < min.Y()) min.Y() = y; - else if ( y > max.Y()) max.Y() = y; - if ( z < min.Z()) min.Z() = z; - else if ( z > max.Z()) max.Z() = z; - } - m_barycenter /= static_cast(m_nPoints); - m_diag = (max-min).GetNorm(); - const Real invDiag = static_cast(2.0 * m_scale / m_diag); - if (m_diag != 0.0) - { - for (size_t v = 0; v < m_nPoints ; v++) - { - m_points[v] = (m_points[v] - m_barycenter) * invDiag; - } - } - } - void HACD::DenormalizeData() - { - if (m_nPoints == 0) - { - return; - } - if (m_diag != 0.0) - { - const Real diag = static_cast(m_diag / (2.0 * m_scale)); - for (size_t v = 0; v < m_nPoints ; v++) - { - m_points[v] = m_points[v] * diag + m_barycenter; - } - } - } - HACD::HACD(void) - { - m_convexHulls = 0; - m_triangles = 0; - m_points = 0; - m_normals = 0; - m_nTriangles = 0; - m_nPoints = 0; - m_nClusters = 0; - m_concavity = 0.0; - m_diag = 1.0; - m_barycenter = Vec3(0.0, 0.0,0.0); - m_alpha = 0.1; - m_beta = 0.1; - m_nVerticesPerCH = 30; - m_callBack = 0; - m_addExtraDistPoints = false; - m_addNeighboursDistPoints = false; - m_scale = 1000.0; - m_partition = 0; - m_nMinClusters = 3; - m_facePoints = 0; - m_faceNormals = 0; - m_ccConnectDist = 30; - } - HACD::~HACD(void) - { - delete [] m_normals; - delete [] m_convexHulls; - delete [] m_partition; - delete [] m_facePoints; - delete [] m_faceNormals; + concavity = Concavity(*ch, gE.m_distPoints); } - int iteration = 0; - void HACD::ComputeEdgeCost(size_t e) - { - GraphEdge & gE = m_graph.m_edges[e]; - long v1 = gE.m_v1; - long v2 = gE.m_v2; - if (m_graph.m_vertices[v2].m_distPoints.size()>m_graph.m_vertices[v1].m_distPoints.size()) - { - gE.m_v1 = v2; - gE.m_v2 = v1; - //std::swap(v1, v2); - std::swap(v1, v2); - } - GraphVertex & gV1 = m_graph.m_vertices[v1]; - GraphVertex & gV2 = m_graph.m_vertices[v2]; - - // delete old convex-hull - delete gE.m_convexHull; - // create the edge's convex-hull - ICHull * ch = new ICHull; - gE.m_convexHull = ch; - (*ch) = (*gV1.m_convexHull); - - // update distPoints - gE.m_distPoints = gV1.m_distPoints; - std::map::iterator itDP(gV2.m_distPoints.begin()); - std::map::iterator itDPEnd(gV2.m_distPoints.end()); - std::map::iterator itDP1; - - for(; itDP != itDPEnd; ++itDP) - { - itDP1 = gE.m_distPoints.find(itDP->first); - if (itDP1 == gE.m_distPoints.end()) - { - gE.m_distPoints[itDP->first].m_distOnly = (itDP->second).m_distOnly; - if ( !(itDP->second).m_distOnly ) - { - ch->AddPoint(m_points[itDP->first], itDP->first); - } - } - else - { - if ( (itDP1->second).m_distOnly && !(itDP->second).m_distOnly) - { - gE.m_distPoints[itDP->first].m_distOnly = false; - ch->AddPoint(m_points[itDP->first], itDP->first); - } - } - } - - ch->SetDistPoints(&gE.m_distPoints); - // create the convex-hull - while (ch->Process() == ICHullErrorInconsistent) // if we face problems when constructing the visual-hull. really ugly!!!! - { -// if (m_callBack) (*m_callBack)("\t Problem with convex-hull construction [HACD::ComputeEdgeCost]\n", 0.0, 0.0, 0); - ch = new ICHull; - CircularList & verticesCH = (gE.m_convexHull)->GetMesh().m_vertices; - size_t nV = verticesCH.GetSize(); - long ptIndex = 0; - verticesCH.Next(); - for(size_t v = 1; v < nV; ++v) - { - ptIndex = verticesCH.GetHead()->GetData().m_name; - if (ptIndex != ICHull::sc_dummyIndex/* && ptIndex < m_nPoints*/) - ch->AddPoint(m_points[ptIndex], ptIndex); - verticesCH.Next(); - } - delete gE.m_convexHull; - gE.m_convexHull = ch; - } - double volume = 0.0; - double concavity = 0.0; - if (ch->IsFlat()) - { - bool insideHull; - std::map::iterator itDP(gE.m_distPoints.begin()); - std::map::iterator itDPEnd(gE.m_distPoints.end()); - for(; itDP != itDPEnd; ++itDP) - { - if (itDP->first >= 0) - { - concavity = std::max(concavity, ch->ComputeDistance(itDP->first, m_points[itDP->first], m_normals[itDP->first], insideHull, false)); - } - } - } - else - { - if (m_addNeighboursDistPoints) - { // add distance points from adjacent clusters - std::set eEdges; - std::set_union(gV1.m_edges.begin(), - gV1.m_edges.end(), - gV2.m_edges.begin(), - gV2.m_edges.end(), - std::inserter( eEdges, eEdges.begin() ) ); - - std::set::const_iterator ed(eEdges.begin()); - std::set::const_iterator itEnd(eEdges.end()); - long a, b, c; - for(; ed != itEnd; ++ed) - { - a = m_graph.m_edges[*ed].m_v1; - b = m_graph.m_edges[*ed].m_v2; - if ( a != v2 && a != v1) - { - c = a; - } - else if ( b != v2 && b != v1) - { - c = b; - } - else - { - c = -1; - } - if ( c > 0) - { - GraphVertex & gVC = m_graph.m_vertices[c]; - std::map::iterator itDP(gVC.m_distPoints.begin()); - std::map::iterator itDPEnd(gVC.m_distPoints.end()); - std::map::iterator itDP1; - for(; itDP != itDPEnd; ++itDP) - { - itDP1 = gE.m_distPoints.find(itDP->first); - if (itDP1 == gE.m_distPoints.end()) - { - if (itDP->first >= 0 && itDP1 == gE.m_distPoints.end() && ch->IsInside(m_points[itDP->first])) - { - gE.m_distPoints[itDP->first].m_distOnly = true; - } - else if (itDP->first < 0 && ch->IsInside(m_facePoints[-itDP->first-1])) - { - gE.m_distPoints[itDP->first].m_distOnly = true; - } - } - } - } - } - } - concavity = Concavity(*ch, gE.m_distPoints); - } - - // compute boudary edges - double perimeter = 0.0; - double surf = 1.0; - if (m_alpha > 0.0) - { - gE.m_boudaryEdges.clear(); - std::set_symmetric_difference (gV1.m_boudaryEdges.begin(), - gV1.m_boudaryEdges.end(), - gV2.m_boudaryEdges.begin(), - gV2.m_boudaryEdges.end(), - std::inserter( gE.m_boudaryEdges, - gE.m_boudaryEdges.begin() ) ); - - std::set::const_iterator itBE(gE.m_boudaryEdges.begin()); - std::set::const_iterator itBEEnd(gE.m_boudaryEdges.end()); - for(; itBE != itBEEnd; ++itBE) - { - perimeter += (m_points[static_cast((*itBE) >> 32)] - - m_points[static_cast((*itBE) & 0xFFFFFFFFULL)]).GetNorm(); - } - surf = gV1.m_surf + gV2.m_surf; - } - double ratio = perimeter * perimeter / (4.0 * sc_pi * surf); - gE.m_volume = (m_beta == 0.0)?0.0:ch->ComputeVolume()/pow(m_scale, 3.0); // cluster's volume - gE.m_surf = surf; // cluster's area - gE.m_perimeter = perimeter; // cluster's perimeter - gE.m_concavity = concavity; // cluster's concavity - gE.m_error = static_cast(concavity + m_alpha * ratio + m_beta * volume); // cluster's priority - } - bool HACD::InitializePriorityQueue() - { - m_pqueue.reserve(m_graph.m_nE + 100); - for (size_t e=0; e < m_graph.m_nE; ++e) - { - ComputeEdgeCost(static_cast(e)); - m_pqueue.push(GraphEdgePriorityQueue(static_cast(e), m_graph.m_edges[e].m_error)); - } - return true; - } - void HACD::Simplify() + // compute boudary edges + double perimeter = 0.0; + double surf = 1.0; + if (m_alpha > 0.0) { - long v1 = -1; - long v2 = -1; - double progressOld = -1.0; - double progress = 0.0; - double globalConcavity = 0.0; - char msg[1024]; - double ptgStep = 1.0; - while ( (globalConcavity < m_concavity) && - (m_graph.GetNVertices() > m_nMinClusters) && - (m_graph.GetNEdges() > 0)) + gE.m_boudaryEdges.clear(); + std::set_symmetric_difference(gV1.m_boudaryEdges.begin(), + gV1.m_boudaryEdges.end(), + gV2.m_boudaryEdges.begin(), + gV2.m_boudaryEdges.end(), + std::inserter(gE.m_boudaryEdges, + gE.m_boudaryEdges.begin())); + + std::set::const_iterator itBE(gE.m_boudaryEdges.begin()); + std::set::const_iterator itBEEnd(gE.m_boudaryEdges.end()); + for (; itBE != itBEEnd; ++itBE) { - progress = 100.0-m_graph.GetNVertices() * 100.0 / m_nTriangles; - if (fabs(progress-progressOld) > ptgStep && m_callBack) - { - sprintf(msg, "%3.2f %% V = %lu \t C = %f \t \t \r", progress, static_cast(m_graph.GetNVertices()), globalConcavity); - (*m_callBack)(msg, progress, globalConcavity, m_graph.GetNVertices()); - progressOld = progress; - if (progress > 99.0) - { - ptgStep = 0.01; - } - else if (progress > 90.0) - { - ptgStep = 0.1; - } - } - - GraphEdgePriorityQueue currentEdge(0,0.0); - bool done = false; - do - { - done = false; - if (m_pqueue.size() == 0) - { - done = true; - break; - } - currentEdge = m_pqueue.top(); - m_pqueue.pop(); - } - while ( m_graph.m_edges[currentEdge.m_name].m_deleted || - m_graph.m_edges[currentEdge.m_name].m_error != currentEdge.m_priority); - - - if (m_graph.m_edges[currentEdge.m_name].m_concavity < m_concavity && !done) - { - globalConcavity = std::max(globalConcavity ,m_graph.m_edges[currentEdge.m_name].m_concavity); - v1 = m_graph.m_edges[currentEdge.m_name].m_v1; - v2 = m_graph.m_edges[currentEdge.m_name].m_v2; - // update vertex info - m_graph.m_vertices[v1].m_error = m_graph.m_edges[currentEdge.m_name].m_error; - m_graph.m_vertices[v1].m_surf = m_graph.m_edges[currentEdge.m_name].m_surf; - m_graph.m_vertices[v1].m_volume = m_graph.m_edges[currentEdge.m_name].m_volume; - m_graph.m_vertices[v1].m_concavity = m_graph.m_edges[currentEdge.m_name].m_concavity; - m_graph.m_vertices[v1].m_perimeter = m_graph.m_edges[currentEdge.m_name].m_perimeter; - m_graph.m_vertices[v1].m_distPoints = m_graph.m_edges[currentEdge.m_name].m_distPoints; - (*m_graph.m_vertices[v1].m_convexHull) = (*m_graph.m_edges[currentEdge.m_name].m_convexHull); - (m_graph.m_vertices[v1].m_convexHull)->SetDistPoints(&(m_graph.m_vertices[v1].m_distPoints)); - m_graph.m_vertices[v1].m_boudaryEdges = m_graph.m_edges[currentEdge.m_name].m_boudaryEdges; - - // We apply the optimal ecol -// std::cout << "v1 " << v1 << " v2 " << v2 << std::endl; - m_graph.EdgeCollapse(v1, v2); - // recompute the adjacent edges costs - std::set::const_iterator itE(m_graph.m_vertices[v1].m_edges.begin()), - itEEnd(m_graph.m_vertices[v1].m_edges.end()); - for(; itE != itEEnd; ++itE) - { - size_t e = *itE; - ComputeEdgeCost(static_cast(e)); - m_pqueue.push(GraphEdgePriorityQueue(static_cast(e), m_graph.m_edges[e].m_error)); - } - } - else - { - break; - } - } - while (!m_pqueue.empty()) + perimeter += (m_points[static_cast((*itBE) >> 32)] - + m_points[static_cast((*itBE) & 0xFFFFFFFFULL)]) + .GetNorm(); + } + surf = gV1.m_surf + gV2.m_surf; + } + double ratio = perimeter * perimeter / (4.0 * sc_pi * surf); + gE.m_volume = (m_beta == 0.0) ? 0.0 : ch->ComputeVolume() / pow(m_scale, 3.0); // cluster's volume + gE.m_surf = surf; // cluster's area + gE.m_perimeter = perimeter; // cluster's perimeter + gE.m_concavity = concavity; // cluster's concavity + gE.m_error = static_cast(concavity + m_alpha * ratio + m_beta * volume); // cluster's priority +} +bool HACD::InitializePriorityQueue() +{ + m_pqueue.reserve(m_graph.m_nE + 100); + for (size_t e = 0; e < m_graph.m_nE; ++e) + { + ComputeEdgeCost(static_cast(e)); + m_pqueue.push(GraphEdgePriorityQueue(static_cast(e), m_graph.m_edges[e].m_error)); + } + return true; +} +void HACD::Simplify() +{ + long v1 = -1; + long v2 = -1; + double progressOld = -1.0; + double progress = 0.0; + double globalConcavity = 0.0; + char msg[1024]; + double ptgStep = 1.0; + while ((globalConcavity < m_concavity) && + (m_graph.GetNVertices() > m_nMinClusters) && + (m_graph.GetNEdges() > 0)) + { + progress = 100.0 - m_graph.GetNVertices() * 100.0 / m_nTriangles; + if (fabs(progress - progressOld) > ptgStep && m_callBack) { + sprintf(msg, "%3.2f %% V = %lu \t C = %f \t \t \r", progress, static_cast(m_graph.GetNVertices()), globalConcavity); + (*m_callBack)(msg, progress, globalConcavity, m_graph.GetNVertices()); + progressOld = progress; + if (progress > 99.0) + { + ptgStep = 0.01; + } + else if (progress > 90.0) + { + ptgStep = 0.1; + } + } + + GraphEdgePriorityQueue currentEdge(0, 0.0); + bool done = false; + do + { + done = false; + if (m_pqueue.size() == 0) + { + done = true; + break; + } + currentEdge = m_pqueue.top(); m_pqueue.pop(); - } - - m_cVertices.clear(); - m_nClusters = m_graph.GetNVertices(); - m_cVertices.reserve(m_nClusters); - for (size_t p=0, v = 0; v != m_graph.m_vertices.size(); ++v) + } while (m_graph.m_edges[currentEdge.m_name].m_deleted || + m_graph.m_edges[currentEdge.m_name].m_error != currentEdge.m_priority); + + if (m_graph.m_edges[currentEdge.m_name].m_concavity < m_concavity && !done) { - if (!m_graph.m_vertices[v].m_deleted) + globalConcavity = std::max(globalConcavity, m_graph.m_edges[currentEdge.m_name].m_concavity); + v1 = m_graph.m_edges[currentEdge.m_name].m_v1; + v2 = m_graph.m_edges[currentEdge.m_name].m_v2; + // update vertex info + m_graph.m_vertices[v1].m_error = m_graph.m_edges[currentEdge.m_name].m_error; + m_graph.m_vertices[v1].m_surf = m_graph.m_edges[currentEdge.m_name].m_surf; + m_graph.m_vertices[v1].m_volume = m_graph.m_edges[currentEdge.m_name].m_volume; + m_graph.m_vertices[v1].m_concavity = m_graph.m_edges[currentEdge.m_name].m_concavity; + m_graph.m_vertices[v1].m_perimeter = m_graph.m_edges[currentEdge.m_name].m_perimeter; + m_graph.m_vertices[v1].m_distPoints = m_graph.m_edges[currentEdge.m_name].m_distPoints; + (*m_graph.m_vertices[v1].m_convexHull) = (*m_graph.m_edges[currentEdge.m_name].m_convexHull); + (m_graph.m_vertices[v1].m_convexHull)->SetDistPoints(&(m_graph.m_vertices[v1].m_distPoints)); + m_graph.m_vertices[v1].m_boudaryEdges = m_graph.m_edges[currentEdge.m_name].m_boudaryEdges; + + // We apply the optimal ecol + // std::cout << "v1 " << v1 << " v2 " << v2 << std::endl; + m_graph.EdgeCollapse(v1, v2); + // recompute the adjacent edges costs + std::set::const_iterator itE(m_graph.m_vertices[v1].m_edges.begin()), + itEEnd(m_graph.m_vertices[v1].m_edges.end()); + for (; itE != itEEnd; ++itE) { - if (m_callBack) - { - char msg[1024]; - sprintf(msg, "\t CH \t %lu \t %lf \t %lf\n", static_cast(p), m_graph.m_vertices[v].m_concavity, m_graph.m_vertices[v].m_error); - (*m_callBack)(msg, 0.0, 0.0, m_nClusters); - p++; - } - m_cVertices.push_back(static_cast(v)); + size_t e = *itE; + ComputeEdgeCost(static_cast(e)); + m_pqueue.push(GraphEdgePriorityQueue(static_cast(e), m_graph.m_edges[e].m_error)); } } - if (m_callBack) - { - sprintf(msg, "# clusters = %lu \t C = %f\n", static_cast(m_nClusters), globalConcavity); - (*m_callBack)(msg, progress, globalConcavity, m_graph.GetNVertices()); - } - + else + { + break; + } + } + while (!m_pqueue.empty()) + { + m_pqueue.pop(); } - - bool HACD::Compute(bool fullCH, bool exportDistPoints) - { - gCancelRequest = false; - if ( !m_points || !m_triangles || !m_nPoints || !m_nTriangles) + m_cVertices.clear(); + m_nClusters = m_graph.GetNVertices(); + m_cVertices.reserve(m_nClusters); + for (size_t p = 0, v = 0; v != m_graph.m_vertices.size(); ++v) + { + if (!m_graph.m_vertices[v].m_deleted) { - return false; - } - size_t nV = m_nTriangles; - if (m_callBack) - { - std::ostringstream msg; - msg << "+ Mesh" << std::endl; - msg << "\t # vertices \t" << m_nPoints << std::endl; - msg << "\t # triangles \t" << m_nTriangles << std::endl; - msg << "+ Parameters" << std::endl; - msg << "\t min # of clusters \t" << m_nMinClusters << std::endl; - msg << "\t max concavity \t" << m_concavity << std::endl; - msg << "\t compacity weigth \t" << m_alpha << std::endl; - msg << "\t volume weigth \t" << m_beta << std::endl; - msg << "\t # vertices per convex-hull \t" << m_nVerticesPerCH << std::endl; - msg << "\t scale \t" << m_scale << std::endl; - msg << "\t add extra distance points \t" << m_addExtraDistPoints << std::endl; - msg << "\t add neighbours distance points \t" << m_addNeighboursDistPoints << std::endl; - msg << "\t add face distance points \t" << m_addFacesPoints << std::endl; - msg << "\t produce full convex-hulls \t" << fullCH << std::endl; - msg << "\t max. distance to connect CCs \t" << m_ccConnectDist << std::endl; - (*m_callBack)(msg.str().c_str(), 0.0, 0.0, nV); - } - if (m_callBack) (*m_callBack)("+ Normalizing Data\n", 0.0, 0.0, nV); - NormalizeData(); - if (m_callBack) (*m_callBack)("+ Creating Graph\n", 0.0, 0.0, nV); - CreateGraph(); - // Compute the surfaces and perimeters of all the faces - if (m_callBack) (*m_callBack)("+ Initializing Dual Graph\n", 0.0, 0.0, nV); - if (gCancelRequest) - return false; - - InitializeDualGraph(); - if (m_callBack) (*m_callBack)("+ Initializing Priority Queue\n", 0.0, 0.0, nV); - if (gCancelRequest) - return false; - - InitializePriorityQueue(); - // we simplify the graph - if (m_callBack) (*m_callBack)("+ Simplification ...\n", 0.0, 0.0, m_nTriangles); - Simplify(); - if (m_callBack) (*m_callBack)("+ Denormalizing Data\n", 0.0, 0.0, m_nClusters); - DenormalizeData(); - if (m_callBack) (*m_callBack)("+ Computing final convex-hulls\n", 0.0, 0.0, m_nClusters); - delete [] m_convexHulls; - m_convexHulls = new ICHull[m_nClusters]; - delete [] m_partition; - m_partition = new long [m_nTriangles]; - for (size_t p = 0; p != m_cVertices.size(); ++p) - { - size_t v = m_cVertices[p]; - m_partition[v] = static_cast(p); - for(size_t a = 0; a < m_graph.m_vertices[v].m_ancestors.size(); a++) + if (m_callBack) { - m_partition[m_graph.m_vertices[v].m_ancestors[a]] = static_cast(p); + char msg[1024]; + sprintf(msg, "\t CH \t %lu \t %lf \t %lf\n", static_cast(p), m_graph.m_vertices[v].m_concavity, m_graph.m_vertices[v].m_error); + (*m_callBack)(msg, 0.0, 0.0, m_nClusters); + p++; } - // compute the convex-hull - const std::map & pointsCH = m_graph.m_vertices[v].m_distPoints; - std::map::const_iterator itCH(pointsCH.begin()); - std::map::const_iterator itCHEnd(pointsCH.end()); - for(; itCH != itCHEnd; ++itCH) - { - if (!(itCH->second).m_distOnly) - { - m_convexHulls[p].AddPoint(m_points[itCH->first], itCH->first); - } - } - m_convexHulls[p].SetDistPoints(&m_graph.m_vertices[v].m_distPoints); - if (fullCH) - { - m_convexHulls[p].Process(); - } - else - { - m_convexHulls[p].Process(static_cast(m_nVerticesPerCH)); - } - if (exportDistPoints) - { - itCH = pointsCH.begin(); - for(; itCH != itCHEnd; ++itCH) - { - if ((itCH->second).m_distOnly) - { - if (itCH->first >= 0) - { - m_convexHulls[p].AddPoint(m_points[itCH->first], itCH->first); - } - else - { - m_convexHulls[p].AddPoint(m_facePoints[-itCH->first-1], itCH->first); - } - } - } - } - } - return true; - } - - size_t HACD::GetNTrianglesCH(size_t numCH) const - { - if (numCH >= m_nClusters) - { - return 0; - } - return m_convexHulls[numCH].GetMesh().GetNTriangles(); - } - size_t HACD::GetNPointsCH(size_t numCH) const - { - if (numCH >= m_nClusters) - { - return 0; - } - return m_convexHulls[numCH].GetMesh().GetNVertices(); - } - - bool HACD::GetCH(size_t numCH, Vec3 * const points, Vec3 * const triangles) - { - if (numCH >= m_nClusters) - { - return false; - } - m_convexHulls[numCH].GetMesh().GetIFS(points, triangles); - return true; - } - - bool HACD::Save(const char * fileName, bool uniColor, long numCluster) const - { - std::ofstream fout(fileName); - if (fout.is_open()) - { - if (m_callBack) - { - char msg[1024]; - sprintf(msg, "Saving %s\n", fileName); - (*m_callBack)(msg, 0.0, 0.0, m_graph.GetNVertices()); - } - Material mat; - if (numCluster < 0) - { - for (size_t p = 0; p != m_nClusters; ++p) - { - if (!uniColor) - { - mat.m_diffuseColor.X() = mat.m_diffuseColor.Y() = mat.m_diffuseColor.Z() = 0.0; - while (mat.m_diffuseColor.X() == mat.m_diffuseColor.Y() || - mat.m_diffuseColor.Z() == mat.m_diffuseColor.Y() || - mat.m_diffuseColor.Z() == mat.m_diffuseColor.X() ) - { - mat.m_diffuseColor.X() = (rand()%100) / 100.0; - mat.m_diffuseColor.Y() = (rand()%100) / 100.0; - mat.m_diffuseColor.Z() = (rand()%100) / 100.0; - } - } - m_convexHulls[p].GetMesh().SaveVRML2(fout, mat); - } - } - else if (numCluster < static_cast(m_cVertices.size())) - { - m_convexHulls[numCluster].GetMesh().SaveVRML2(fout, mat); - } - fout.close(); - return true; - } - else - { - if (m_callBack) - { - char msg[1024]; - sprintf(msg, "Error saving %s\n", fileName); - (*m_callBack)(msg, 0.0, 0.0, m_graph.GetNVertices()); - } - return false; - } - } + m_cVertices.push_back(static_cast(v)); + } + } + if (m_callBack) + { + sprintf(msg, "# clusters = %lu \t C = %f\n", static_cast(m_nClusters), globalConcavity); + (*m_callBack)(msg, progress, globalConcavity, m_graph.GetNVertices()); + } } +bool HACD::Compute(bool fullCH, bool exportDistPoints) +{ + gCancelRequest = false; + if (!m_points || !m_triangles || !m_nPoints || !m_nTriangles) + { + return false; + } + size_t nV = m_nTriangles; + if (m_callBack) + { + std::ostringstream msg; + msg << "+ Mesh" << std::endl; + msg << "\t # vertices \t" << m_nPoints << std::endl; + msg << "\t # triangles \t" << m_nTriangles << std::endl; + msg << "+ Parameters" << std::endl; + msg << "\t min # of clusters \t" << m_nMinClusters << std::endl; + msg << "\t max concavity \t" << m_concavity << std::endl; + msg << "\t compacity weigth \t" << m_alpha << std::endl; + msg << "\t volume weigth \t" << m_beta << std::endl; + msg << "\t # vertices per convex-hull \t" << m_nVerticesPerCH << std::endl; + msg << "\t scale \t" << m_scale << std::endl; + msg << "\t add extra distance points \t" << m_addExtraDistPoints << std::endl; + msg << "\t add neighbours distance points \t" << m_addNeighboursDistPoints << std::endl; + msg << "\t add face distance points \t" << m_addFacesPoints << std::endl; + msg << "\t produce full convex-hulls \t" << fullCH << std::endl; + msg << "\t max. distance to connect CCs \t" << m_ccConnectDist << std::endl; + (*m_callBack)(msg.str().c_str(), 0.0, 0.0, nV); + } + if (m_callBack) (*m_callBack)("+ Normalizing Data\n", 0.0, 0.0, nV); + NormalizeData(); + if (m_callBack) (*m_callBack)("+ Creating Graph\n", 0.0, 0.0, nV); + CreateGraph(); + // Compute the surfaces and perimeters of all the faces + if (m_callBack) (*m_callBack)("+ Initializing Dual Graph\n", 0.0, 0.0, nV); + if (gCancelRequest) + return false; + + InitializeDualGraph(); + if (m_callBack) (*m_callBack)("+ Initializing Priority Queue\n", 0.0, 0.0, nV); + if (gCancelRequest) + return false; + + InitializePriorityQueue(); + // we simplify the graph + if (m_callBack) (*m_callBack)("+ Simplification ...\n", 0.0, 0.0, m_nTriangles); + Simplify(); + if (m_callBack) (*m_callBack)("+ Denormalizing Data\n", 0.0, 0.0, m_nClusters); + DenormalizeData(); + if (m_callBack) (*m_callBack)("+ Computing final convex-hulls\n", 0.0, 0.0, m_nClusters); + delete[] m_convexHulls; + m_convexHulls = new ICHull[m_nClusters]; + delete[] m_partition; + m_partition = new long[m_nTriangles]; + for (size_t p = 0; p != m_cVertices.size(); ++p) + { + size_t v = m_cVertices[p]; + m_partition[v] = static_cast(p); + for (size_t a = 0; a < m_graph.m_vertices[v].m_ancestors.size(); a++) + { + m_partition[m_graph.m_vertices[v].m_ancestors[a]] = static_cast(p); + } + // compute the convex-hull + const std::map& pointsCH = m_graph.m_vertices[v].m_distPoints; + std::map::const_iterator itCH(pointsCH.begin()); + std::map::const_iterator itCHEnd(pointsCH.end()); + for (; itCH != itCHEnd; ++itCH) + { + if (!(itCH->second).m_distOnly) + { + m_convexHulls[p].AddPoint(m_points[itCH->first], itCH->first); + } + } + m_convexHulls[p].SetDistPoints(&m_graph.m_vertices[v].m_distPoints); + if (fullCH) + { + m_convexHulls[p].Process(); + } + else + { + m_convexHulls[p].Process(static_cast(m_nVerticesPerCH)); + } + if (exportDistPoints) + { + itCH = pointsCH.begin(); + for (; itCH != itCHEnd; ++itCH) + { + if ((itCH->second).m_distOnly) + { + if (itCH->first >= 0) + { + m_convexHulls[p].AddPoint(m_points[itCH->first], itCH->first); + } + else + { + m_convexHulls[p].AddPoint(m_facePoints[-itCH->first - 1], itCH->first); + } + } + } + } + } + return true; +} + +size_t HACD::GetNTrianglesCH(size_t numCH) const +{ + if (numCH >= m_nClusters) + { + return 0; + } + return m_convexHulls[numCH].GetMesh().GetNTriangles(); +} +size_t HACD::GetNPointsCH(size_t numCH) const +{ + if (numCH >= m_nClusters) + { + return 0; + } + return m_convexHulls[numCH].GetMesh().GetNVertices(); +} + +bool HACD::GetCH(size_t numCH, Vec3* const points, Vec3* const triangles) +{ + if (numCH >= m_nClusters) + { + return false; + } + m_convexHulls[numCH].GetMesh().GetIFS(points, triangles); + return true; +} + +bool HACD::Save(const char* fileName, bool uniColor, long numCluster) const +{ + std::ofstream fout(fileName); + if (fout.is_open()) + { + if (m_callBack) + { + char msg[1024]; + sprintf(msg, "Saving %s\n", fileName); + (*m_callBack)(msg, 0.0, 0.0, m_graph.GetNVertices()); + } + Material mat; + if (numCluster < 0) + { + for (size_t p = 0; p != m_nClusters; ++p) + { + if (!uniColor) + { + mat.m_diffuseColor.X() = mat.m_diffuseColor.Y() = mat.m_diffuseColor.Z() = 0.0; + while (mat.m_diffuseColor.X() == mat.m_diffuseColor.Y() || + mat.m_diffuseColor.Z() == mat.m_diffuseColor.Y() || + mat.m_diffuseColor.Z() == mat.m_diffuseColor.X()) + { + mat.m_diffuseColor.X() = (rand() % 100) / 100.0; + mat.m_diffuseColor.Y() = (rand() % 100) / 100.0; + mat.m_diffuseColor.Z() = (rand() % 100) / 100.0; + } + } + m_convexHulls[p].GetMesh().SaveVRML2(fout, mat); + } + } + else if (numCluster < static_cast(m_cVertices.size())) + { + m_convexHulls[numCluster].GetMesh().SaveVRML2(fout, mat); + } + fout.close(); + return true; + } + else + { + if (m_callBack) + { + char msg[1024]; + sprintf(msg, "Error saving %s\n", fileName); + (*m_callBack)(msg, 0.0, 0.0, m_graph.GetNVertices()); + } + return false; + } +} +} // namespace HACD diff --git a/Extras/HACD/hacdHACD.h b/Extras/HACD/hacdHACD.h index 0b2415ba6..efb0fe85e 100644 --- a/Extras/HACD/hacdHACD.h +++ b/Extras/HACD/hacdHACD.h @@ -26,257 +26,260 @@ namespace HACD { - const double sc_pi = 3.14159265; - class HACD; +const double sc_pi = 3.14159265; +class HACD; - // just to be able to set the capcity of the container - - template, class _Pr = std::less > - class reservable_priority_queue: public std::priority_queue<_Ty, _Container, _Pr> +// just to be able to set the capcity of the container + +template , class _Pr = std::less > +class reservable_priority_queue : public std::priority_queue<_Ty, _Container, _Pr> +{ + typedef typename std::priority_queue<_Ty, _Container, _Pr>::size_type size_type; + +public: + reservable_priority_queue(size_type capacity = 0) { reserve(capacity); }; + void reserve(size_type capacity) { this->c.reserve(capacity); } + size_type capacity() const { return this->c.capacity(); } +}; + +//! priority queque element +class GraphEdgePriorityQueue +{ +public: + //! Constructor + //! @param name edge's id + //! @param priority edge's priority + GraphEdgePriorityQueue(long name, Real priority) { - typedef typename std::priority_queue<_Ty, _Container, _Pr>::size_type size_type; - public: - reservable_priority_queue(size_type capacity = 0) { reserve(capacity); }; - void reserve(size_type capacity) { this->c.reserve(capacity); } - size_type capacity() const { return this->c.capacity(); } - }; - - //! priority queque element - class GraphEdgePriorityQueue - { - public: - //! Constructor - //! @param name edge's id - //! @param priority edge's priority - GraphEdgePriorityQueue(long name, Real priority) - { - m_name = name; - m_priority = priority; - } - //! Destructor - ~GraphEdgePriorityQueue(void){} - private: - long m_name; //!< edge name - Real m_priority; //!< priority - //! Operator < for GraphEdgePQ - friend bool operator<(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs); - //! Operator > for GraphEdgePQ - friend bool operator>(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs); - friend class HACD; - }; - inline bool operator<(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs) - { - return lhs.m_priority(const GraphEdgePriorityQueue & lhs, const GraphEdgePriorityQueue & rhs) - { - return lhs.m_priority>rhs.m_priority; - } - typedef bool (*CallBackFunction)(const char *, double, double, size_t); + m_name = name; + m_priority = priority; + } + //! Destructor + ~GraphEdgePriorityQueue(void) {} - //! Provides an implementation of the Hierarchical Approximate Convex Decomposition (HACD) technique described in "A Simple and Efficient Approach for 3D Mesh Approximate Convex Decomposition" Game Programming Gems 8 - Chapter 2.8, p.202. A short version of the chapter was published in ICIP09 and is available at ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf - class HACD - { - public: - - //! Gives the triangles partitionas an array of size m_nTriangles where the i-th element specifies the cluster to which belong the i-th triangle - //! @return triangles partition - const long * GetPartition() const { return m_partition;} - //! Sets the scale factor - //! @param scale scale factor - void SetScaleFactor(double scale) { m_scale = scale;} - //! Gives the scale factor - //! @return scale factor - double GetScaleFactor() const { return m_scale;} - //! Sets the call-back function - //! @param callBack pointer to the call-back function - void SetCallBack(CallBackFunction callBack) { m_callBack = callBack;} - //! Gives the call-back function - //! @return pointer to the call-back function - CallBackFunction GetCallBack() const { return m_callBack;} - - //! Specifies whether faces points should be added when computing the concavity - //! @param addFacesPoints true = faces points should be added - void SetAddFacesPoints(bool addFacesPoints) { m_addFacesPoints = addFacesPoints;} - //! Specifies wheter faces points should be added when computing the concavity - //! @return true = faces points should be added - bool GetAddFacesPoints() const { return m_addFacesPoints;} - //! Specifies whether extra points should be added when computing the concavity - //! @param addExteraDistPoints true = extra points should be added - void SetAddExtraDistPoints(bool addExtraDistPoints) { m_addExtraDistPoints = addExtraDistPoints;} - //! Specifies wheter extra points should be added when computing the concavity - //! @return true = extra points should be added - bool GetAddExtraDistPoints() const { return m_addExtraDistPoints;} - //! Specifies whether extra points should be added when computing the concavity - //! @param addExteraDistPoints true = extra points should be added - void SetAddNeighboursDistPoints(bool addNeighboursDistPoints) { m_addNeighboursDistPoints = addNeighboursDistPoints;} - //! Specifies wheter extra points should be added when computing the concavity - //! @return true = extra points should be added - bool GetAddNeighboursDistPoints() const { return m_addNeighboursDistPoints;} - //! Sets the points of the input mesh (Remark: the input points will be scaled and shifted. Use DenormalizeData() to invert those operations) - //! @param points pointer to the input points - void SetPoints(Vec3 * points) { m_points = points;} - //! Gives the points of the input mesh (Remark: the input points will be scaled and shifted. Use DenormalizeData() to invert those operations) - //! @return pointer to the input points - const Vec3 * GetPoints() const { return m_points;} - //! Sets the triangles of the input mesh. - //! @param triangles points pointer to the input points - void SetTriangles(Vec3 * triangles) { m_triangles = triangles;} - //! Gives the triangles in the input mesh - //! @return pointer to the input triangles - const Vec3 * GetTriangles() const { return m_triangles;} - //! Sets the number of points in the input mesh. - //! @param nPoints number of points the input mesh - void SetNPoints(size_t nPoints) { m_nPoints = nPoints;} - //! Gives the number of points in the input mesh. - //! @return number of points the input mesh - size_t GetNPoints() const { return m_nPoints;} - //! Sets the number of triangles in the input mesh. - //! @param nTriangles number of triangles in the input mesh - void SetNTriangles(size_t nTriangles) { m_nTriangles = nTriangles;} - //! Gives the number of triangles in the input mesh. - //! @return number of triangles the input mesh - size_t GetNTriangles() const { return m_nTriangles;} - //! Sets the minimum number of clusters to be generated. - //! @param nClusters minimum number of clusters - void SetNClusters(size_t nClusters) { m_nMinClusters = nClusters;} - //! Gives the number of generated clusters. - //! @return number of generated clusters - size_t GetNClusters() const { return m_nClusters;} - //! Sets the maximum allowed concavity. - //! @param concavity maximum concavity - void SetConcavity(double concavity) { m_concavity = concavity;} - //! Gives the maximum allowed concavity. - //! @return maximum concavity - double GetConcavity() const { return m_concavity;} - //! Sets the maximum allowed distance to get CCs connected. - //! @param concavity maximum distance to get CCs connected - void SetConnectDist(double ccConnectDist) { m_ccConnectDist = ccConnectDist;} - //! Gives the maximum allowed distance to get CCs connected. - //! @return maximum distance to get CCs connected - double GetConnectDist() const { return m_ccConnectDist;} - //! Sets the volume weight. - //! @param beta volume weight - void SetVolumeWeight(double beta) { m_beta = beta;} - //! Gives the volume weight. - //! @return volume weight - double GetVolumeWeight() const { return m_beta;} - //! Sets the compacity weight (i.e. parameter alpha in ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf). - //! @param alpha compacity weight - void SetCompacityWeight(double alpha) { m_alpha = alpha;} - //! Gives the compacity weight (i.e. parameter alpha in ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf). - //! @return compacity weight - double GetCompacityWeight() const { return m_alpha;} - //! Sets the maximum number of vertices for each generated convex-hull. - //! @param nVerticesPerCH maximum # vertices per CH - void SetNVerticesPerCH(size_t nVerticesPerCH) { m_nVerticesPerCH = nVerticesPerCH;} - //! Gives the maximum number of vertices for each generated convex-hull. - //! @return maximum # vertices per CH - size_t GetNVerticesPerCH() const { return m_nVerticesPerCH;} - //! Gives the number of vertices for the cluster number numCH. - //! @return number of vertices - size_t GetNPointsCH(size_t numCH) const; - //! Gives the number of triangles for the cluster number numCH. - //! @param numCH cluster's number - //! @return number of triangles - size_t GetNTrianglesCH(size_t numCH) const; - //! Gives the vertices and the triangles of the cluster number numCH. - //! @param numCH cluster's number - //! @param points pointer to the vector of points to be filled - //! @param triangles pointer to the vector of triangles to be filled - //! @return true if sucess - bool GetCH(size_t numCH, Vec3 * const points, Vec3 * const triangles); - //! Computes the HACD decomposition. - //! @param fullCH specifies whether to generate convex-hulls with a full or limited (i.e. < m_nVerticesPerCH) number of vertices - //! @param exportDistPoints specifies wheter distance points should ne exported or not (used only for debugging). - //! @return true if sucess - bool Compute(bool fullCH=false, bool exportDistPoints=false); - //! Saves the generated convex-hulls in a VRML 2.0 file. - //! @param fileName the output file name - //! @param uniColor specifies whether the different convex-hulls should have the same color or not - //! @param numCluster specifies the cluster to be saved, if numCluster < 0 export all clusters - //! @return true if sucess - bool Save(const char * fileName, bool uniColor, long numCluster=-1) const; - //! Shifts and scales to the data to have all the coordinates between 0.0 and 1000.0. - void NormalizeData(); - //! Inverse the operations applied by NormalizeData(). - void DenormalizeData(); - //! Constructor. - HACD(void); - //! Destructor. - ~HACD(void); - - private: - //! Gives the edge index. - //! @param a first vertex id - //! @param b second vertex id - //! @return edge's index - static unsigned long long GetEdgeIndex(unsigned long long a, unsigned long long b) - { - if (a > b) return (a << 32) + b; - else return (b << 32) + a; - } - //! Computes the concavity of a cluster. - //! @param ch the cluster's convex-hull - //! @param distPoints the cluster's points - //! @return cluster's concavity - double Concavity(ICHull & ch, std::map & distPoints); - //! Computes the perimeter of a cluster. - //! @param triIndices the cluster's triangles - //! @param distPoints the cluster's points - //! @return cluster's perimeter - double ComputePerimeter(const std::vector & triIndices) const; - //! Creates the Graph by associating to each mesh triangle a vertex in the graph and to each couple of adjacent triangles an edge in the graph. - void CreateGraph(); - //! Initializes the graph costs and computes the vertices normals - void InitializeDualGraph(); - //! Computes the cost of an edge - //! @param e edge's id - void ComputeEdgeCost(size_t e); - //! Initializes the priority queue - //! @param fast specifies whether fast mode is used - //! @return true if success - bool InitializePriorityQueue(); - //! Cleans the intersection between convex-hulls - void CleanClusters(); - //! Computes convex-hulls from partition information - //! @param fullCH specifies whether to generate convex-hulls with a full or limited (i.e. < m_nVerticesPerCH) number of vertices - void ComputeConvexHulls(bool fullCH); - //! Simplifies the graph - //! @param fast specifies whether fast mode is used - void Simplify(); - - private: - double m_scale; //>! scale factor used for NormalizeData() and DenormalizeData() - Vec3 * m_triangles; //>! pointer the triangles array - Vec3 * m_points; //>! pointer the points array - Vec3 * m_facePoints; //>! pointer to the faces points array - Vec3 * m_faceNormals; //>! pointer to the faces normals array - Vec3 * m_normals; //>! pointer the normals array - size_t m_nTriangles; //>! number of triangles in the original mesh - size_t m_nPoints; //>! number of vertices in the original mesh - size_t m_nClusters; //>! number of clusters - size_t m_nMinClusters; //>! minimum number of clusters - double m_ccConnectDist; //>! maximum allowed distance to connect CCs - double m_concavity; //>! maximum concavity - double m_alpha; //>! compacity weigth - double m_beta; //>! volume weigth - double m_diag; //>! length of the BB diagonal - Vec3 m_barycenter; //>! barycenter of the mesh - std::vector< long > m_cVertices; //>! array of vertices each belonging to a different cluster - ICHull * m_convexHulls; //>! convex-hulls associated with the final HACD clusters - Graph m_graph; //>! simplification graph - size_t m_nVerticesPerCH; //>! maximum number of vertices per convex-hull - reservable_priority_queue, - std::greater::value_type> > m_pqueue; //!> priority queue - HACD(const HACD & rhs); - CallBackFunction m_callBack; //>! call-back function - long * m_partition; //>! array of size m_nTriangles where the i-th element specifies the cluster to which belong the i-th triangle - bool m_addFacesPoints; //>! specifies whether to add faces points or not - bool m_addExtraDistPoints; //>! specifies whether to add extra points for concave shapes or not - bool m_addNeighboursDistPoints; //>! specifies whether to add extra points from adjacent clusters or not - - }; +private: + long m_name; //!< edge name + Real m_priority; //!< priority + //! Operator < for GraphEdgePQ + friend bool operator<(const GraphEdgePriorityQueue &lhs, const GraphEdgePriorityQueue &rhs); + //! Operator > for GraphEdgePQ + friend bool operator>(const GraphEdgePriorityQueue &lhs, const GraphEdgePriorityQueue &rhs); + friend class HACD; +}; +inline bool operator<(const GraphEdgePriorityQueue &lhs, const GraphEdgePriorityQueue &rhs) +{ + return lhs.m_priority < rhs.m_priority; } +inline bool operator>(const GraphEdgePriorityQueue &lhs, const GraphEdgePriorityQueue &rhs) +{ + return lhs.m_priority > rhs.m_priority; +} +typedef bool (*CallBackFunction)(const char *, double, double, size_t); + +//! Provides an implementation of the Hierarchical Approximate Convex Decomposition (HACD) technique described in "A Simple and Efficient Approach for 3D Mesh Approximate Convex Decomposition" Game Programming Gems 8 - Chapter 2.8, p.202. A short version of the chapter was published in ICIP09 and is available at ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf +class HACD +{ +public: + //! Gives the triangles partitionas an array of size m_nTriangles where the i-th element specifies the cluster to which belong the i-th triangle + //! @return triangles partition + const long *GetPartition() const { return m_partition; } + //! Sets the scale factor + //! @param scale scale factor + void SetScaleFactor(double scale) { m_scale = scale; } + //! Gives the scale factor + //! @return scale factor + double GetScaleFactor() const { return m_scale; } + //! Sets the call-back function + //! @param callBack pointer to the call-back function + void SetCallBack(CallBackFunction callBack) { m_callBack = callBack; } + //! Gives the call-back function + //! @return pointer to the call-back function + CallBackFunction GetCallBack() const { return m_callBack; } + + //! Specifies whether faces points should be added when computing the concavity + //! @param addFacesPoints true = faces points should be added + void SetAddFacesPoints(bool addFacesPoints) { m_addFacesPoints = addFacesPoints; } + //! Specifies wheter faces points should be added when computing the concavity + //! @return true = faces points should be added + bool GetAddFacesPoints() const { return m_addFacesPoints; } + //! Specifies whether extra points should be added when computing the concavity + //! @param addExteraDistPoints true = extra points should be added + void SetAddExtraDistPoints(bool addExtraDistPoints) { m_addExtraDistPoints = addExtraDistPoints; } + //! Specifies wheter extra points should be added when computing the concavity + //! @return true = extra points should be added + bool GetAddExtraDistPoints() const { return m_addExtraDistPoints; } + //! Specifies whether extra points should be added when computing the concavity + //! @param addExteraDistPoints true = extra points should be added + void SetAddNeighboursDistPoints(bool addNeighboursDistPoints) { m_addNeighboursDistPoints = addNeighboursDistPoints; } + //! Specifies wheter extra points should be added when computing the concavity + //! @return true = extra points should be added + bool GetAddNeighboursDistPoints() const { return m_addNeighboursDistPoints; } + //! Sets the points of the input mesh (Remark: the input points will be scaled and shifted. Use DenormalizeData() to invert those operations) + //! @param points pointer to the input points + void SetPoints(Vec3 *points) { m_points = points; } + //! Gives the points of the input mesh (Remark: the input points will be scaled and shifted. Use DenormalizeData() to invert those operations) + //! @return pointer to the input points + const Vec3 *GetPoints() const { return m_points; } + //! Sets the triangles of the input mesh. + //! @param triangles points pointer to the input points + void SetTriangles(Vec3 *triangles) { m_triangles = triangles; } + //! Gives the triangles in the input mesh + //! @return pointer to the input triangles + const Vec3 *GetTriangles() const { return m_triangles; } + //! Sets the number of points in the input mesh. + //! @param nPoints number of points the input mesh + void SetNPoints(size_t nPoints) { m_nPoints = nPoints; } + //! Gives the number of points in the input mesh. + //! @return number of points the input mesh + size_t GetNPoints() const { return m_nPoints; } + //! Sets the number of triangles in the input mesh. + //! @param nTriangles number of triangles in the input mesh + void SetNTriangles(size_t nTriangles) { m_nTriangles = nTriangles; } + //! Gives the number of triangles in the input mesh. + //! @return number of triangles the input mesh + size_t GetNTriangles() const { return m_nTriangles; } + //! Sets the minimum number of clusters to be generated. + //! @param nClusters minimum number of clusters + void SetNClusters(size_t nClusters) { m_nMinClusters = nClusters; } + //! Gives the number of generated clusters. + //! @return number of generated clusters + size_t GetNClusters() const { return m_nClusters; } + //! Sets the maximum allowed concavity. + //! @param concavity maximum concavity + void SetConcavity(double concavity) { m_concavity = concavity; } + //! Gives the maximum allowed concavity. + //! @return maximum concavity + double GetConcavity() const { return m_concavity; } + //! Sets the maximum allowed distance to get CCs connected. + //! @param concavity maximum distance to get CCs connected + void SetConnectDist(double ccConnectDist) { m_ccConnectDist = ccConnectDist; } + //! Gives the maximum allowed distance to get CCs connected. + //! @return maximum distance to get CCs connected + double GetConnectDist() const { return m_ccConnectDist; } + //! Sets the volume weight. + //! @param beta volume weight + void SetVolumeWeight(double beta) { m_beta = beta; } + //! Gives the volume weight. + //! @return volume weight + double GetVolumeWeight() const { return m_beta; } + //! Sets the compacity weight (i.e. parameter alpha in ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf). + //! @param alpha compacity weight + void SetCompacityWeight(double alpha) { m_alpha = alpha; } + //! Gives the compacity weight (i.e. parameter alpha in ftp://ftp.elet.polimi.it/users/Stefano.Tubaro/ICIP_USB_Proceedings_v2/pdfs/0003501.pdf). + //! @return compacity weight + double GetCompacityWeight() const { return m_alpha; } + //! Sets the maximum number of vertices for each generated convex-hull. + //! @param nVerticesPerCH maximum # vertices per CH + void SetNVerticesPerCH(size_t nVerticesPerCH) { m_nVerticesPerCH = nVerticesPerCH; } + //! Gives the maximum number of vertices for each generated convex-hull. + //! @return maximum # vertices per CH + size_t GetNVerticesPerCH() const { return m_nVerticesPerCH; } + //! Gives the number of vertices for the cluster number numCH. + //! @return number of vertices + size_t GetNPointsCH(size_t numCH) const; + //! Gives the number of triangles for the cluster number numCH. + //! @param numCH cluster's number + //! @return number of triangles + size_t GetNTrianglesCH(size_t numCH) const; + //! Gives the vertices and the triangles of the cluster number numCH. + //! @param numCH cluster's number + //! @param points pointer to the vector of points to be filled + //! @param triangles pointer to the vector of triangles to be filled + //! @return true if sucess + bool GetCH(size_t numCH, Vec3 *const points, Vec3 *const triangles); + //! Computes the HACD decomposition. + //! @param fullCH specifies whether to generate convex-hulls with a full or limited (i.e. < m_nVerticesPerCH) number of vertices + //! @param exportDistPoints specifies wheter distance points should ne exported or not (used only for debugging). + //! @return true if sucess + bool Compute(bool fullCH = false, bool exportDistPoints = false); + //! Saves the generated convex-hulls in a VRML 2.0 file. + //! @param fileName the output file name + //! @param uniColor specifies whether the different convex-hulls should have the same color or not + //! @param numCluster specifies the cluster to be saved, if numCluster < 0 export all clusters + //! @return true if sucess + bool Save(const char *fileName, bool uniColor, long numCluster = -1) const; + //! Shifts and scales to the data to have all the coordinates between 0.0 and 1000.0. + void NormalizeData(); + //! Inverse the operations applied by NormalizeData(). + void DenormalizeData(); + //! Constructor. + HACD(void); + //! Destructor. + ~HACD(void); + +private: + //! Gives the edge index. + //! @param a first vertex id + //! @param b second vertex id + //! @return edge's index + static unsigned long long GetEdgeIndex(unsigned long long a, unsigned long long b) + { + if (a > b) + return (a << 32) + b; + else + return (b << 32) + a; + } + //! Computes the concavity of a cluster. + //! @param ch the cluster's convex-hull + //! @param distPoints the cluster's points + //! @return cluster's concavity + double Concavity(ICHull &ch, std::map &distPoints); + //! Computes the perimeter of a cluster. + //! @param triIndices the cluster's triangles + //! @param distPoints the cluster's points + //! @return cluster's perimeter + double ComputePerimeter(const std::vector &triIndices) const; + //! Creates the Graph by associating to each mesh triangle a vertex in the graph and to each couple of adjacent triangles an edge in the graph. + void CreateGraph(); + //! Initializes the graph costs and computes the vertices normals + void InitializeDualGraph(); + //! Computes the cost of an edge + //! @param e edge's id + void ComputeEdgeCost(size_t e); + //! Initializes the priority queue + //! @param fast specifies whether fast mode is used + //! @return true if success + bool InitializePriorityQueue(); + //! Cleans the intersection between convex-hulls + void CleanClusters(); + //! Computes convex-hulls from partition information + //! @param fullCH specifies whether to generate convex-hulls with a full or limited (i.e. < m_nVerticesPerCH) number of vertices + void ComputeConvexHulls(bool fullCH); + //! Simplifies the graph + //! @param fast specifies whether fast mode is used + void Simplify(); + +private: + double m_scale; //>! scale factor used for NormalizeData() and DenormalizeData() + Vec3 *m_triangles; //>! pointer the triangles array + Vec3 *m_points; //>! pointer the points array + Vec3 *m_facePoints; //>! pointer to the faces points array + Vec3 *m_faceNormals; //>! pointer to the faces normals array + Vec3 *m_normals; //>! pointer the normals array + size_t m_nTriangles; //>! number of triangles in the original mesh + size_t m_nPoints; //>! number of vertices in the original mesh + size_t m_nClusters; //>! number of clusters + size_t m_nMinClusters; //>! minimum number of clusters + double m_ccConnectDist; //>! maximum allowed distance to connect CCs + double m_concavity; //>! maximum concavity + double m_alpha; //>! compacity weigth + double m_beta; //>! volume weigth + double m_diag; //>! length of the BB diagonal + Vec3 m_barycenter; //>! barycenter of the mesh + std::vector m_cVertices; //>! array of vertices each belonging to a different cluster + ICHull *m_convexHulls; //>! convex-hulls associated with the final HACD clusters + Graph m_graph; //>! simplification graph + size_t m_nVerticesPerCH; //>! maximum number of vertices per convex-hull + reservable_priority_queue, + std::greater::value_type> > + m_pqueue; //!> priority queue + HACD(const HACD &rhs); + CallBackFunction m_callBack; //>! call-back function + long *m_partition; //>! array of size m_nTriangles where the i-th element specifies the cluster to which belong the i-th triangle + bool m_addFacesPoints; //>! specifies whether to add faces points or not + bool m_addExtraDistPoints; //>! specifies whether to add extra points for concave shapes or not + bool m_addNeighboursDistPoints; //>! specifies whether to add extra points from adjacent clusters or not +}; +} // namespace HACD #endif diff --git a/Extras/HACD/hacdICHull.cpp b/Extras/HACD/hacdICHull.cpp index de2c7da92..16796296e 100644 --- a/Extras/HACD/hacdICHull.cpp +++ b/Extras/HACD/hacdICHull.cpp @@ -17,1003 +17,1004 @@ #include namespace HACD -{ - const long ICHull::sc_dummyIndex = std::numeric_limits::max(); - ICHull::ICHull(void) - { - m_distPoints = 0; - m_isFlat = false; - m_dummyVertex = 0; - } - bool ICHull::AddPoints(const Vec3 * points, size_t nPoints) +{ +const long ICHull::sc_dummyIndex = std::numeric_limits::max(); +ICHull::ICHull(void) +{ + m_distPoints = 0; + m_isFlat = false; + m_dummyVertex = 0; +} +bool ICHull::AddPoints(const Vec3 *points, size_t nPoints) +{ + if (!points) { - if (!points) - { - return false; - } - CircularListElement * vertex = NULL; - for (size_t i = 0; i < nPoints; i++) - { - vertex = m_mesh.AddVertex(); - vertex->GetData().m_pos.X() = points[i].X(); - vertex->GetData().m_pos.Y() = points[i].Y(); - vertex->GetData().m_pos.Z() = points[i].Z(); - vertex->GetData().m_name = static_cast(i); - } - return true; - } - bool ICHull::AddPoints(std::vector< Vec3 > points) - { - CircularListElement * vertex = NULL; - for (size_t i = 0; i < points.size(); i++) - { - vertex = m_mesh.AddVertex(); - vertex->GetData().m_pos.X() = points[i].X(); - vertex->GetData().m_pos.Y() = points[i].Y(); - vertex->GetData().m_pos.Z() = points[i].Z(); - } - return true; - } - - bool ICHull::AddPoint(const Vec3 & point, long id) - { - if (AddPoints(&point, 1)) - { - m_mesh.m_vertices.GetData().m_name = id; - return true; - } return false; } - - ICHullError ICHull::Process() + CircularListElement *vertex = NULL; + for (size_t i = 0; i < nPoints; i++) { - unsigned long addedPoints = 0; - if (m_mesh.GetNVertices() < 3) - { - return ICHullErrorNotEnoughPoints; - } - if (m_mesh.GetNVertices() == 3) - { - m_isFlat = true; - CircularListElement * t1 = m_mesh.AddTriangle(); - CircularListElement * t2 = m_mesh.AddTriangle(); - CircularListElement * v0 = m_mesh.m_vertices.GetHead(); - CircularListElement * v1 = v0->GetNext(); - CircularListElement * v2 = v1->GetNext(); - // Compute the normal to the plane - Vec3 p0 = v0->GetData().m_pos; - Vec3 p1 = v1->GetData().m_pos; - Vec3 p2 = v2->GetData().m_pos; - m_normal = (p1-p0) ^ (p2-p0); - m_normal.Normalize(); - t1->GetData().m_vertices[0] = v0; - t1->GetData().m_vertices[1] = v1; - t1->GetData().m_vertices[2] = v2; - t2->GetData().m_vertices[0] = v1; - t2->GetData().m_vertices[1] = v2; - t2->GetData().m_vertices[2] = v2; - return ICHullErrorOK; - } - if (m_isFlat) - { - m_mesh.m_edges.Clear(); - m_mesh.m_triangles.Clear(); - m_isFlat = false; - } - if (m_mesh.GetNTriangles() == 0) // we have to create the first polyhedron - { - ICHullError res = DoubleTriangle(); - if (res != ICHullErrorOK) - { - return res; - } - else - { - addedPoints += 3; - } - } - CircularList & vertices = m_mesh.GetVertices(); - // go to the first added and not processed vertex - while (!(vertices.GetHead()->GetPrev()->GetData().m_tag)) - { - vertices.Prev(); - } - while (!vertices.GetData().m_tag) // not processed - { - vertices.GetData().m_tag = true; - if (ProcessPoint()) - { - addedPoints++; - CleanUp(addedPoints); - vertices.Next(); - if (!GetMesh().CheckConsistancy()) - { - return ICHullErrorInconsistent; - } - } - } - if (m_isFlat) - { - std::vector< CircularListElement * > trianglesToDuplicate; - size_t nT = m_mesh.GetNTriangles(); - for(size_t f = 0; f < nT; f++) - { - TMMTriangle & currentTriangle = m_mesh.m_triangles.GetHead()->GetData(); - if( currentTriangle.m_vertices[0]->GetData().m_name == sc_dummyIndex || - currentTriangle.m_vertices[1]->GetData().m_name == sc_dummyIndex || - currentTriangle.m_vertices[2]->GetData().m_name == sc_dummyIndex ) - { - m_trianglesToDelete.push_back(m_mesh.m_triangles.GetHead()); - for(int k = 0; k < 3; k++) - { - for(int h = 0; h < 2; h++) - { - if (currentTriangle.m_edges[k]->GetData().m_triangles[h] == m_mesh.m_triangles.GetHead()) - { - currentTriangle.m_edges[k]->GetData().m_triangles[h] = 0; - break; - } - } - } - } - else - { - trianglesToDuplicate.push_back(m_mesh.m_triangles.GetHead()); - } - m_mesh.m_triangles.Next(); - } - size_t nE = m_mesh.GetNEdges(); - for(size_t e = 0; e < nE; e++) - { - TMMEdge & currentEdge = m_mesh.m_edges.GetHead()->GetData(); - if( currentEdge.m_triangles[0] == 0 && currentEdge.m_triangles[1] == 0) - { - m_edgesToDelete.push_back(m_mesh.m_edges.GetHead()); - } - m_mesh.m_edges.Next(); - } - m_mesh.m_vertices.Delete(m_dummyVertex); - m_dummyVertex = 0; - size_t nV = m_mesh.GetNVertices(); - CircularList & vertices = m_mesh.GetVertices(); - for(size_t v = 0; v < nV; ++v) - { - vertices.GetData().m_tag = false; - vertices.Next(); - } - CleanEdges(); - CleanTriangles(); - CircularListElement * newTriangle; - for(size_t t = 0; t < trianglesToDuplicate.size(); t++) - { - newTriangle = m_mesh.AddTriangle(); - newTriangle->GetData().m_vertices[0] = trianglesToDuplicate[t]->GetData().m_vertices[1]; - newTriangle->GetData().m_vertices[1] = trianglesToDuplicate[t]->GetData().m_vertices[0]; - newTriangle->GetData().m_vertices[2] = trianglesToDuplicate[t]->GetData().m_vertices[2]; - } - } - return ICHullErrorOK; + vertex = m_mesh.AddVertex(); + vertex->GetData().m_pos.X() = points[i].X(); + vertex->GetData().m_pos.Y() = points[i].Y(); + vertex->GetData().m_pos.Z() = points[i].Z(); + vertex->GetData().m_name = static_cast(i); } - ICHullError ICHull::Process(unsigned long nPointsCH) + return true; +} +bool ICHull::AddPoints(std::vector > points) +{ + CircularListElement *vertex = NULL; + for (size_t i = 0; i < points.size(); i++) { - unsigned long addedPoints = 0; - if (nPointsCH < 3 || m_mesh.GetNVertices() < 3) - { - return ICHullErrorNotEnoughPoints; - } - if (m_mesh.GetNVertices() == 3) - { - m_isFlat = true; - CircularListElement * t1 = m_mesh.AddTriangle(); - CircularListElement * t2 = m_mesh.AddTriangle(); - CircularListElement * v0 = m_mesh.m_vertices.GetHead(); - CircularListElement * v1 = v0->GetNext(); - CircularListElement * v2 = v1->GetNext(); - // Compute the normal to the plane - Vec3 p0 = v0->GetData().m_pos; - Vec3 p1 = v1->GetData().m_pos; - Vec3 p2 = v2->GetData().m_pos; - m_normal = (p1-p0) ^ (p2-p0); - m_normal.Normalize(); - t1->GetData().m_vertices[0] = v0; - t1->GetData().m_vertices[1] = v1; - t1->GetData().m_vertices[2] = v2; - t2->GetData().m_vertices[0] = v1; - t2->GetData().m_vertices[1] = v0; - t2->GetData().m_vertices[2] = v2; - return ICHullErrorOK; - } - - if (m_isFlat) - { - m_mesh.m_triangles.Clear(); - m_mesh.m_edges.Clear(); - m_isFlat = false; - } - - if (m_mesh.GetNTriangles() == 0) // we have to create the first polyhedron - { - ICHullError res = DoubleTriangle(); - if (res != ICHullErrorOK) - { - return res; - } - else - { - addedPoints += 3; - } - } - CircularList & vertices = m_mesh.GetVertices(); - while (!vertices.GetData().m_tag && addedPoints < nPointsCH) // not processed - { - if (!FindMaxVolumePoint()) - { - break; - } - vertices.GetData().m_tag = true; - if (ProcessPoint()) - { - addedPoints++; - CleanUp(addedPoints); - if (!GetMesh().CheckConsistancy()) - { - return ICHullErrorInconsistent; - } - vertices.Next(); - } - } - // delete remaining points - while (!vertices.GetData().m_tag) - { - if (vertices.GetHead() == m_dummyVertex) - m_dummyVertex = 0; - vertices.Delete(); - } - if (m_isFlat) - { - std::vector< CircularListElement * > trianglesToDuplicate; - size_t nT = m_mesh.GetNTriangles(); - for(size_t f = 0; f < nT; f++) - { - TMMTriangle & currentTriangle = m_mesh.m_triangles.GetHead()->GetData(); - if( currentTriangle.m_vertices[0]->GetData().m_name == sc_dummyIndex || - currentTriangle.m_vertices[1]->GetData().m_name == sc_dummyIndex || - currentTriangle.m_vertices[2]->GetData().m_name == sc_dummyIndex ) - { - m_trianglesToDelete.push_back(m_mesh.m_triangles.GetHead()); - for(int k = 0; k < 3; k++) - { - for(int h = 0; h < 2; h++) - { - if (currentTriangle.m_edges[k]->GetData().m_triangles[h] == m_mesh.m_triangles.GetHead()) - { - currentTriangle.m_edges[k]->GetData().m_triangles[h] = 0; - break; - } - } - } - } - else - { - trianglesToDuplicate.push_back(m_mesh.m_triangles.GetHead()); - } - m_mesh.m_triangles.Next(); - } - size_t nE = m_mesh.GetNEdges(); - for(size_t e = 0; e < nE; e++) - { - TMMEdge & currentEdge = m_mesh.m_edges.GetHead()->GetData(); - if( currentEdge.m_triangles[0] == 0 && currentEdge.m_triangles[1] == 0) - { - m_edgesToDelete.push_back(m_mesh.m_edges.GetHead()); - } - m_mesh.m_edges.Next(); - } - m_mesh.m_vertices.Delete(m_dummyVertex); - m_dummyVertex = 0; - size_t nV = m_mesh.GetNVertices(); - CircularList & vertices = m_mesh.GetVertices(); - for(size_t v = 0; v < nV; ++v) - { - vertices.GetData().m_tag = false; - vertices.Next(); - } - CleanEdges(); - CleanTriangles(); - CircularListElement * newTriangle; - for(size_t t = 0; t < trianglesToDuplicate.size(); t++) - { - newTriangle = m_mesh.AddTriangle(); - newTriangle->GetData().m_vertices[0] = trianglesToDuplicate[t]->GetData().m_vertices[1]; - newTriangle->GetData().m_vertices[1] = trianglesToDuplicate[t]->GetData().m_vertices[0]; - newTriangle->GetData().m_vertices[2] = trianglesToDuplicate[t]->GetData().m_vertices[2]; - } - } - return ICHullErrorOK; + vertex = m_mesh.AddVertex(); + vertex->GetData().m_pos.X() = points[i].X(); + vertex->GetData().m_pos.Y() = points[i].Y(); + vertex->GetData().m_pos.Z() = points[i].Z(); } - bool ICHull::FindMaxVolumePoint() - { - CircularList & vertices = m_mesh.GetVertices(); - CircularListElement * vMaxVolume = 0; - CircularListElement * vHeadPrev = vertices.GetHead()->GetPrev(); - - double maxVolume = 0.0; - double volume = 0.0; - - while (!vertices.GetData().m_tag) // not processed - { - if (ComputePointVolume(volume, false)) - { - if ( maxVolume < volume) - { - maxVolume = volume; - vMaxVolume = vertices.GetHead(); - } - vertices.Next(); - } - } - CircularListElement * vHead = vHeadPrev->GetNext(); - vertices.GetHead() = vHead; - - if (!vMaxVolume) - { - return false; - } - - if (vMaxVolume != vHead) - { - Vec3 pos = vHead->GetData().m_pos; - long id = vHead->GetData().m_name; - vHead->GetData().m_pos = vMaxVolume->GetData().m_pos; - vHead->GetData().m_name = vMaxVolume->GetData().m_name; - vMaxVolume->GetData().m_pos = pos; - vHead->GetData().m_name = id; - } - - - return true; - } - ICHullError ICHull::DoubleTriangle() - { - // find three non colinear points - m_isFlat = false; - CircularList & vertices = m_mesh.GetVertices(); - CircularListElement * v0 = vertices.GetHead(); - while( Colinear(v0->GetData().m_pos, - v0->GetNext()->GetData().m_pos, - v0->GetNext()->GetNext()->GetData().m_pos)) - { - if ( (v0 = v0->GetNext()) == vertices.GetHead()) - { - return ICHullErrorCoplanarPoints; - } - } - CircularListElement * v1 = v0->GetNext(); - CircularListElement * v2 = v1->GetNext(); - // mark points as processed - v0->GetData().m_tag = v1->GetData().m_tag = v2->GetData().m_tag = true; - - // create two triangles - CircularListElement * f0 = MakeFace(v0, v1, v2, 0); - MakeFace(v2, v1, v0, f0); + return true; +} - // find a fourth non-coplanar point to form tetrahedron - CircularListElement * v3 = v2->GetNext(); - vertices.GetHead() = v3; - - double vol = Volume(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos); - while (vol == 0.0 && !v3->GetNext()->GetData().m_tag) - { - v3 = v3->GetNext(); - vol = Volume(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos); - } - if (vol == 0.0) - { - // compute the barycenter - Vec3 bary(0.0,0.0,0.0); - CircularListElement * vBary = v0; - do - { - bary += vBary->GetData().m_pos; - } - while ( (vBary = vBary->GetNext()) != v0); - bary /= static_cast(vertices.GetSize()); - - // Compute the normal to the plane - Vec3 p0 = v0->GetData().m_pos; - Vec3 p1 = v1->GetData().m_pos; - Vec3 p2 = v2->GetData().m_pos; - m_normal = (p1-p0) ^ (p2-p0); - m_normal.Normalize(); - // add dummy vertex placed at (bary + normal) - vertices.GetHead() = v2; - Vec3 newPt = bary + m_normal; - AddPoint(newPt, sc_dummyIndex); - m_dummyVertex = vertices.GetHead(); - m_isFlat = true; - v3 = v2->GetNext(); - vol = Volume(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos); - return ICHullErrorOK; - } - else if (v3 != vertices.GetHead()) - { - TMMVertex temp; - temp.m_name = v3->GetData().m_name; - temp.m_pos = v3->GetData().m_pos; - v3->GetData().m_name = vertices.GetHead()->GetData().m_name; - v3->GetData().m_pos = vertices.GetHead()->GetData().m_pos; - vertices.GetHead()->GetData().m_name = temp.m_name; - vertices.GetHead()->GetData().m_pos = temp.m_pos; - } - return ICHullErrorOK; - } - CircularListElement * ICHull::MakeFace(CircularListElement * v0, - CircularListElement * v1, - CircularListElement * v2, - CircularListElement * fold) - { - CircularListElement * e0; - CircularListElement * e1; - CircularListElement * e2; - long index = 0; - if (!fold) // if first face to be created - { - e0 = m_mesh.AddEdge(); // create the three edges - e1 = m_mesh.AddEdge(); - e2 = m_mesh.AddEdge(); - } - else // otherwise re-use existing edges (in reverse order) - { - e0 = fold->GetData().m_edges[2]; - e1 = fold->GetData().m_edges[1]; - e2 = fold->GetData().m_edges[0]; - index = 1; - } - e0->GetData().m_vertices[0] = v0; e0->GetData().m_vertices[1] = v1; - e1->GetData().m_vertices[0] = v1; e1->GetData().m_vertices[1] = v2; - e2->GetData().m_vertices[0] = v2; e2->GetData().m_vertices[1] = v0; - // create the new face - CircularListElement * f = m_mesh.AddTriangle(); - f->GetData().m_edges[0] = e0; f->GetData().m_edges[1] = e1; f->GetData().m_edges[2] = e2; - f->GetData().m_vertices[0] = v0; f->GetData().m_vertices[1] = v1; f->GetData().m_vertices[2] = v2; - // link edges to face f - e0->GetData().m_triangles[index] = e1->GetData().m_triangles[index] = e2->GetData().m_triangles[index] = f; - return f; - } - CircularListElement * ICHull::MakeConeFace(CircularListElement * e, CircularListElement * p) +bool ICHull::AddPoint(const Vec3 &point, long id) +{ + if (AddPoints(&point, 1)) { - // create two new edges if they don't already exist - CircularListElement * newEdges[2]; - for(int i = 0; i < 2; ++i) - { - if ( !( newEdges[i] = e->GetData().m_vertices[i]->GetData().m_duplicate ) ) - { // if the edge doesn't exits add it and mark the vertex as duplicated - newEdges[i] = m_mesh.AddEdge(); - newEdges[i]->GetData().m_vertices[0] = e->GetData().m_vertices[i]; - newEdges[i]->GetData().m_vertices[1] = p; - e->GetData().m_vertices[i]->GetData().m_duplicate = newEdges[i]; - } - } - // make the new face - CircularListElement * newFace = m_mesh.AddTriangle(); - newFace->GetData().m_edges[0] = e; - newFace->GetData().m_edges[1] = newEdges[0]; - newFace->GetData().m_edges[2] = newEdges[1]; - MakeCCW(newFace, e, p); - for(int i=0; i < 2; ++i) - { - for(int j=0; j < 2; ++j) - { - if ( ! newEdges[i]->GetData().m_triangles[j] ) - { - newEdges[i]->GetData().m_triangles[j] = newFace; - break; - } - } - } - return newFace; - } - bool ICHull::ComputePointVolume(double &totalVolume, bool markVisibleFaces) - { - // mark visible faces - CircularListElement * fHead = m_mesh.GetTriangles().GetHead(); - CircularListElement * f = fHead; - CircularList & vertices = m_mesh.GetVertices(); - CircularListElement * vertex0 = vertices.GetHead(); - bool visible = false; - Vec3 pos0 = Vec3(vertex0->GetData().m_pos.X(), - vertex0->GetData().m_pos.Y(), - vertex0->GetData().m_pos.Z()); - double vol = 0.0; - totalVolume = 0.0; - Vec3 ver0, ver1, ver2; - do - { - ver0.X() = f->GetData().m_vertices[0]->GetData().m_pos.X(); - ver0.Y() = f->GetData().m_vertices[0]->GetData().m_pos.Y(); - ver0.Z() = f->GetData().m_vertices[0]->GetData().m_pos.Z(); - ver1.X() = f->GetData().m_vertices[1]->GetData().m_pos.X(); - ver1.Y() = f->GetData().m_vertices[1]->GetData().m_pos.Y(); - ver1.Z() = f->GetData().m_vertices[1]->GetData().m_pos.Z(); - ver2.X() = f->GetData().m_vertices[2]->GetData().m_pos.X(); - ver2.Y() = f->GetData().m_vertices[2]->GetData().m_pos.Y(); - ver2.Z() = f->GetData().m_vertices[2]->GetData().m_pos.Z(); - vol = Volume(ver0, ver1, ver2, pos0); - if ( vol < 0.0 ) - { - vol = fabs(vol); - totalVolume += vol; - if (markVisibleFaces) - { - f->GetData().m_visible = true; - m_trianglesToDelete.push_back(f); - } - visible = true; - } - f = f->GetNext(); - } - while (f != fHead); - - if (m_trianglesToDelete.size() == m_mesh.m_triangles.GetSize()) - { - for(size_t i = 0; i < m_trianglesToDelete.size(); i++) - { - m_trianglesToDelete[i]->GetData().m_visible = false; - } - visible = false; - } - // if no faces visible from p then p is inside the hull - if (!visible && markVisibleFaces) - { - if (vertices.GetHead() == m_dummyVertex) - m_dummyVertex = 0; - vertices.Delete(); - m_trianglesToDelete.clear(); - return false; - } - return true; - } - bool ICHull::ProcessPoint() - { - double totalVolume = 0.0; - if (!ComputePointVolume(totalVolume, true)) - { - return false; - } - // Mark edges in interior of visible region for deletion. - // Create a new face based on each border edge - CircularListElement * v0 = m_mesh.GetVertices().GetHead(); - CircularListElement * eHead = m_mesh.GetEdges().GetHead(); - CircularListElement * e = eHead; - CircularListElement * tmp = 0; - long nvisible = 0; - m_edgesToDelete.clear(); - m_edgesToUpdate.clear(); - do - { - tmp = e->GetNext(); - nvisible = 0; - for(int k = 0; k < 2; k++) - { - if ( e->GetData().m_triangles[k]->GetData().m_visible ) - { - nvisible++; - } - } - if ( nvisible == 2) - { - m_edgesToDelete.push_back(e); - } - else if ( nvisible == 1) - { - e->GetData().m_newFace = MakeConeFace(e, v0); - m_edgesToUpdate.push_back(e); - } - e = tmp; - } - while (e != eHead); + m_mesh.m_vertices.GetData().m_name = id; return true; } - bool ICHull::MakeCCW(CircularListElement * f, - CircularListElement * e, - CircularListElement * v) - { - // the visible face adjacent to e - CircularListElement * fv; - if (e->GetData().m_triangles[0]->GetData().m_visible) - { - fv = e->GetData().m_triangles[0]; - } - else - { - fv = e->GetData().m_triangles[1]; - } - - // set vertex[0] and vertex[1] to have the same orientation as the corresponding vertices of fv. - long i; // index of e->m_vertices[0] in fv - CircularListElement * v0 = e->GetData().m_vertices[0]; - CircularListElement * v1 = e->GetData().m_vertices[1]; - for(i = 0; fv->GetData().m_vertices[i] != v0; i++); - - if ( fv->GetData().m_vertices[(i+1) % 3] != e->GetData().m_vertices[1] ) - { - f->GetData().m_vertices[0] = v1; - f->GetData().m_vertices[1] = v0; - } - else - { - f->GetData().m_vertices[0] = v0; - f->GetData().m_vertices[1] = v1; - // swap edges - CircularListElement * tmp = f->GetData().m_edges[0]; - f->GetData().m_edges[0] = f->GetData().m_edges[1]; - f->GetData().m_edges[1] = tmp; - } - f->GetData().m_vertices[2] = v; - return true; - } - bool ICHull::CleanUp(unsigned long & addedPoints) - { - bool r0 = CleanEdges(); - bool r1 = CleanTriangles(); - bool r2 = CleanVertices(addedPoints); - return r0 && r1 && r2; - } - bool ICHull::CleanEdges() - { - // integrate the new faces into the data structure - CircularListElement * e; - const std::vector *>::iterator itEndUpdate = m_edgesToUpdate.end(); - for(std::vector *>::iterator it = m_edgesToUpdate.begin(); it != itEndUpdate; ++it) - { - e = *it; - if ( e->GetData().m_newFace ) - { - if ( e->GetData().m_triangles[0]->GetData().m_visible) - { - e->GetData().m_triangles[0] = e->GetData().m_newFace; - } - else - { - e->GetData().m_triangles[1] = e->GetData().m_newFace; - } - e->GetData().m_newFace = 0; - } - } - // delete edges maked for deletion - CircularList & edges = m_mesh.GetEdges(); - const std::vector *>::iterator itEndDelete = m_edgesToDelete.end(); - for(std::vector *>::iterator it = m_edgesToDelete.begin(); it != itEndDelete; ++it) - { - edges.Delete(*it); - } - m_edgesToDelete.clear(); - m_edgesToUpdate.clear(); - return true; - } - bool ICHull::CleanTriangles() - { - CircularList & triangles = m_mesh.GetTriangles(); - const std::vector *>::iterator itEndDelete = m_trianglesToDelete.end(); - for(std::vector *>::iterator it = m_trianglesToDelete.begin(); it != itEndDelete; ++it) - { - if (m_distPoints) + return false; +} + +ICHullError ICHull::Process() +{ + unsigned long addedPoints = 0; + if (m_mesh.GetNVertices() < 3) + { + return ICHullErrorNotEnoughPoints; + } + if (m_mesh.GetNVertices() == 3) + { + m_isFlat = true; + CircularListElement *t1 = m_mesh.AddTriangle(); + CircularListElement *t2 = m_mesh.AddTriangle(); + CircularListElement *v0 = m_mesh.m_vertices.GetHead(); + CircularListElement *v1 = v0->GetNext(); + CircularListElement *v2 = v1->GetNext(); + // Compute the normal to the plane + Vec3 p0 = v0->GetData().m_pos; + Vec3 p1 = v1->GetData().m_pos; + Vec3 p2 = v2->GetData().m_pos; + m_normal = (p1 - p0) ^ (p2 - p0); + m_normal.Normalize(); + t1->GetData().m_vertices[0] = v0; + t1->GetData().m_vertices[1] = v1; + t1->GetData().m_vertices[2] = v2; + t2->GetData().m_vertices[0] = v1; + t2->GetData().m_vertices[1] = v2; + t2->GetData().m_vertices[2] = v2; + return ICHullErrorOK; + } + if (m_isFlat) + { + m_mesh.m_edges.Clear(); + m_mesh.m_triangles.Clear(); + m_isFlat = false; + } + if (m_mesh.GetNTriangles() == 0) // we have to create the first polyhedron + { + ICHullError res = DoubleTriangle(); + if (res != ICHullErrorOK) + { + return res; + } + else + { + addedPoints += 3; + } + } + CircularList &vertices = m_mesh.GetVertices(); + // go to the first added and not processed vertex + while (!(vertices.GetHead()->GetPrev()->GetData().m_tag)) + { + vertices.Prev(); + } + while (!vertices.GetData().m_tag) // not processed + { + vertices.GetData().m_tag = true; + if (ProcessPoint()) + { + addedPoints++; + CleanUp(addedPoints); + vertices.Next(); + if (!GetMesh().CheckConsistancy()) { - if (m_isFlat) + return ICHullErrorInconsistent; + } + } + } + if (m_isFlat) + { + std::vector *> trianglesToDuplicate; + size_t nT = m_mesh.GetNTriangles(); + for (size_t f = 0; f < nT; f++) + { + TMMTriangle ¤tTriangle = m_mesh.m_triangles.GetHead()->GetData(); + if (currentTriangle.m_vertices[0]->GetData().m_name == sc_dummyIndex || + currentTriangle.m_vertices[1]->GetData().m_name == sc_dummyIndex || + currentTriangle.m_vertices[2]->GetData().m_name == sc_dummyIndex) + { + m_trianglesToDelete.push_back(m_mesh.m_triangles.GetHead()); + for (int k = 0; k < 3; k++) { - // to be updated - } - else - { - std::set::const_iterator itPEnd((*it)->GetData().m_incidentPoints.end()); - std::set::const_iterator itP((*it)->GetData().m_incidentPoints.begin()); - std::map::iterator itPoint; - for(; itP != itPEnd; ++itP) + for (int h = 0; h < 2; h++) { - itPoint = m_distPoints->find(*itP); - if (itPoint != m_distPoints->end()) + if (currentTriangle.m_edges[k]->GetData().m_triangles[h] == m_mesh.m_triangles.GetHead()) { - itPoint->second.m_computed = false; + currentTriangle.m_edges[k]->GetData().m_triangles[h] = 0; + break; } } } } - triangles.Delete(*it); - } - m_trianglesToDelete.clear(); - return true; - } - bool ICHull::CleanVertices(unsigned long & addedPoints) - { - // mark all vertices incident to some undeleted edge as on the hull - CircularList & edges = m_mesh.GetEdges(); - CircularListElement * e = edges.GetHead(); - size_t nE = edges.GetSize(); - for(size_t i = 0; i < nE; i++) - { - e->GetData().m_vertices[0]->GetData().m_onHull = true; - e->GetData().m_vertices[1]->GetData().m_onHull = true; - e = e->GetNext(); - } - // delete all the vertices that have been processed but are not on the hull - CircularList & vertices = m_mesh.GetVertices(); - CircularListElement * vHead = vertices.GetHead(); - CircularListElement * v = vHead; - v = v->GetPrev(); - do - { - if (v->GetData().m_tag && !v->GetData().m_onHull) - { - CircularListElement * tmp = v->GetPrev(); - if (tmp == m_dummyVertex) - m_dummyVertex = 0; - vertices.Delete(v); - v = tmp; - addedPoints--; - } - else - { - v->GetData().m_duplicate = 0; - v->GetData().m_onHull = false; - v = v->GetPrev(); - } - } - while (v->GetData().m_tag && v != vHead); - return true; - } - void ICHull::Clear() - { - m_mesh.Clear(); - m_edgesToDelete = std::vector *>(); - m_edgesToUpdate = std::vector *>(); - m_trianglesToDelete= std::vector *>(); + else + { + trianglesToDuplicate.push_back(m_mesh.m_triangles.GetHead()); + } + m_mesh.m_triangles.Next(); + } + size_t nE = m_mesh.GetNEdges(); + for (size_t e = 0; e < nE; e++) + { + TMMEdge ¤tEdge = m_mesh.m_edges.GetHead()->GetData(); + if (currentEdge.m_triangles[0] == 0 && currentEdge.m_triangles[1] == 0) + { + m_edgesToDelete.push_back(m_mesh.m_edges.GetHead()); + } + m_mesh.m_edges.Next(); + } + m_mesh.m_vertices.Delete(m_dummyVertex); + m_dummyVertex = 0; + size_t nV = m_mesh.GetNVertices(); + CircularList &vertices = m_mesh.GetVertices(); + for (size_t v = 0; v < nV; ++v) + { + vertices.GetData().m_tag = false; + vertices.Next(); + } + CleanEdges(); + CleanTriangles(); + CircularListElement *newTriangle; + for (size_t t = 0; t < trianglesToDuplicate.size(); t++) + { + newTriangle = m_mesh.AddTriangle(); + newTriangle->GetData().m_vertices[0] = trianglesToDuplicate[t]->GetData().m_vertices[1]; + newTriangle->GetData().m_vertices[1] = trianglesToDuplicate[t]->GetData().m_vertices[0]; + newTriangle->GetData().m_vertices[2] = trianglesToDuplicate[t]->GetData().m_vertices[2]; + } + } + return ICHullErrorOK; +} +ICHullError ICHull::Process(unsigned long nPointsCH) +{ + unsigned long addedPoints = 0; + if (nPointsCH < 3 || m_mesh.GetNVertices() < 3) + { + return ICHullErrorNotEnoughPoints; + } + if (m_mesh.GetNVertices() == 3) + { + m_isFlat = true; + CircularListElement *t1 = m_mesh.AddTriangle(); + CircularListElement *t2 = m_mesh.AddTriangle(); + CircularListElement *v0 = m_mesh.m_vertices.GetHead(); + CircularListElement *v1 = v0->GetNext(); + CircularListElement *v2 = v1->GetNext(); + // Compute the normal to the plane + Vec3 p0 = v0->GetData().m_pos; + Vec3 p1 = v1->GetData().m_pos; + Vec3 p2 = v2->GetData().m_pos; + m_normal = (p1 - p0) ^ (p2 - p0); + m_normal.Normalize(); + t1->GetData().m_vertices[0] = v0; + t1->GetData().m_vertices[1] = v1; + t1->GetData().m_vertices[2] = v2; + t2->GetData().m_vertices[0] = v1; + t2->GetData().m_vertices[1] = v0; + t2->GetData().m_vertices[2] = v2; + return ICHullErrorOK; + } + + if (m_isFlat) + { + m_mesh.m_triangles.Clear(); + m_mesh.m_edges.Clear(); m_isFlat = false; } - const ICHull & ICHull::operator=(ICHull & rhs) - { - if (&rhs != this) - { - m_mesh.Copy(rhs.m_mesh); - m_edgesToDelete = rhs.m_edgesToDelete; - m_edgesToUpdate = rhs.m_edgesToUpdate; - m_trianglesToDelete = rhs.m_trianglesToDelete; - m_isFlat = rhs.m_isFlat; - } - return (*this); - } - double ICHull::ComputeVolume() - { - size_t nV = m_mesh.m_vertices.GetSize(); - if (nV == 0 || m_isFlat) + + if (m_mesh.GetNTriangles() == 0) // we have to create the first polyhedron + { + ICHullError res = DoubleTriangle(); + if (res != ICHullErrorOK) { - return 0.0; - } - Vec3 bary(0.0, 0.0, 0.0); - for(size_t v = 0; v < nV; v++) - { - bary.X() += m_mesh.m_vertices.GetHead()->GetData().m_pos.X(); - bary.Y() += m_mesh.m_vertices.GetHead()->GetData().m_pos.Y(); - bary.Z() += m_mesh.m_vertices.GetHead()->GetData().m_pos.Z(); - m_mesh.m_vertices.Next(); - } - bary /= static_cast(nV); - - size_t nT = m_mesh.m_triangles.GetSize(); - Vec3 ver0, ver1, ver2; - double totalVolume = 0.0; - for(size_t t = 0; t < nT; t++) - { - ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X(); - ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y(); - ver0.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Z(); - ver1.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.X(); - ver1.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Y(); - ver1.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Z(); - ver2.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.X(); - ver2.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Y(); - ver2.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Z(); - totalVolume += Volume(ver0, ver1, ver2, bary); - m_mesh.m_triangles.Next(); - } - return totalVolume; - } - bool ICHull::IsInside(const Vec3 & pt0) - { - const Vec3 pt(pt0.X(), pt0.Y(), pt0.Z()); - if (m_isFlat) - { - size_t nT = m_mesh.m_triangles.GetSize(); - Vec3 ver0, ver1, ver2, a, b, c; - double u,v; - for(size_t t = 0; t < nT; t++) - { - ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X(); - ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y(); - ver0.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Z(); - ver1.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.X(); - ver1.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Y(); - ver1.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Z(); - ver2.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.X(); - ver2.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Y(); - ver2.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Z(); - a = ver1 - ver0; - b = ver2 - ver0; - c = pt - ver0; - u = c * a; - v = c * b; - if ( u >= 0.0 && u <= 1.0 && v >= 0.0 && u+v <= 1.0) - { - return true; - } - m_mesh.m_triangles.Next(); - } - return false; + return res; } else { - size_t nT = m_mesh.m_triangles.GetSize(); - Vec3 ver0, ver1, ver2; - for(size_t t = 0; t < nT; t++) - { - ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X(); - ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y(); - ver0.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Z(); - ver1.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.X(); - ver1.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Y(); - ver1.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Z(); - ver2.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.X(); - ver2.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Y(); - ver2.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Z(); - if (Volume(ver0, ver1, ver2, pt) < 0.0) - { - return false; - } - m_mesh.m_triangles.Next(); - } - return true; + addedPoints += 3; } - } - double ICHull::ComputeDistance(long name, const Vec3 & pt, const Vec3 & normal, bool & insideHull, bool updateIncidentPoints) + } + CircularList &vertices = m_mesh.GetVertices(); + while (!vertices.GetData().m_tag && addedPoints < nPointsCH) // not processed { - Vec3 ptNormal(static_cast(normal.X()), - static_cast(normal.Y()), - static_cast(normal.Z())); - Vec3 p0( static_cast(pt.X()), - static_cast(pt.Y()), - static_cast(pt.Z())); - - if (m_isFlat) + if (!FindMaxVolumePoint()) { - double distance = 0.0; - Vec3 chNormal(static_cast(m_normal.X()), - static_cast(m_normal.Y()), - static_cast(m_normal.Z())); - ptNormal -= (ptNormal * chNormal) * chNormal; - if (ptNormal.GetNorm() > 0.0) + break; + } + vertices.GetData().m_tag = true; + if (ProcessPoint()) + { + addedPoints++; + CleanUp(addedPoints); + if (!GetMesh().CheckConsistancy()) { - ptNormal.Normalize(); - long nameVE1; - long nameVE2; - Vec3 pa, pb, d0, d1, d2, d3; - Vec3 p1 = p0 + ptNormal; - Vec3 p2, p3; - double mua, mub, s; - const double EPS = 0.00000000001; - size_t nE = m_mesh.GetNEdges(); - for(size_t e = 0; e < nE; e++) + return ICHullErrorInconsistent; + } + vertices.Next(); + } + } + // delete remaining points + while (!vertices.GetData().m_tag) + { + if (vertices.GetHead() == m_dummyVertex) + m_dummyVertex = 0; + vertices.Delete(); + } + if (m_isFlat) + { + std::vector *> trianglesToDuplicate; + size_t nT = m_mesh.GetNTriangles(); + for (size_t f = 0; f < nT; f++) + { + TMMTriangle ¤tTriangle = m_mesh.m_triangles.GetHead()->GetData(); + if (currentTriangle.m_vertices[0]->GetData().m_name == sc_dummyIndex || + currentTriangle.m_vertices[1]->GetData().m_name == sc_dummyIndex || + currentTriangle.m_vertices[2]->GetData().m_name == sc_dummyIndex) + { + m_trianglesToDelete.push_back(m_mesh.m_triangles.GetHead()); + for (int k = 0; k < 3; k++) { - TMMEdge & currentEdge = m_mesh.m_edges.GetHead()->GetData(); - nameVE1 = currentEdge.m_vertices[0]->GetData().m_name; - nameVE2 = currentEdge.m_vertices[1]->GetData().m_name; - if (currentEdge.m_triangles[0] == 0 || currentEdge.m_triangles[1] == 0) - { - if ( nameVE1==name || nameVE2==name ) - { - return 0.0; - } - /* + for (int h = 0; h < 2; h++) + { + if (currentTriangle.m_edges[k]->GetData().m_triangles[h] == m_mesh.m_triangles.GetHead()) + { + currentTriangle.m_edges[k]->GetData().m_triangles[h] = 0; + break; + } + } + } + } + else + { + trianglesToDuplicate.push_back(m_mesh.m_triangles.GetHead()); + } + m_mesh.m_triangles.Next(); + } + size_t nE = m_mesh.GetNEdges(); + for (size_t e = 0; e < nE; e++) + { + TMMEdge ¤tEdge = m_mesh.m_edges.GetHead()->GetData(); + if (currentEdge.m_triangles[0] == 0 && currentEdge.m_triangles[1] == 0) + { + m_edgesToDelete.push_back(m_mesh.m_edges.GetHead()); + } + m_mesh.m_edges.Next(); + } + m_mesh.m_vertices.Delete(m_dummyVertex); + m_dummyVertex = 0; + size_t nV = m_mesh.GetNVertices(); + CircularList &vertices = m_mesh.GetVertices(); + for (size_t v = 0; v < nV; ++v) + { + vertices.GetData().m_tag = false; + vertices.Next(); + } + CleanEdges(); + CleanTriangles(); + CircularListElement *newTriangle; + for (size_t t = 0; t < trianglesToDuplicate.size(); t++) + { + newTriangle = m_mesh.AddTriangle(); + newTriangle->GetData().m_vertices[0] = trianglesToDuplicate[t]->GetData().m_vertices[1]; + newTriangle->GetData().m_vertices[1] = trianglesToDuplicate[t]->GetData().m_vertices[0]; + newTriangle->GetData().m_vertices[2] = trianglesToDuplicate[t]->GetData().m_vertices[2]; + } + } + return ICHullErrorOK; +} +bool ICHull::FindMaxVolumePoint() +{ + CircularList &vertices = m_mesh.GetVertices(); + CircularListElement *vMaxVolume = 0; + CircularListElement *vHeadPrev = vertices.GetHead()->GetPrev(); + + double maxVolume = 0.0; + double volume = 0.0; + + while (!vertices.GetData().m_tag) // not processed + { + if (ComputePointVolume(volume, false)) + { + if (maxVolume < volume) + { + maxVolume = volume; + vMaxVolume = vertices.GetHead(); + } + vertices.Next(); + } + } + CircularListElement *vHead = vHeadPrev->GetNext(); + vertices.GetHead() = vHead; + + if (!vMaxVolume) + { + return false; + } + + if (vMaxVolume != vHead) + { + Vec3 pos = vHead->GetData().m_pos; + long id = vHead->GetData().m_name; + vHead->GetData().m_pos = vMaxVolume->GetData().m_pos; + vHead->GetData().m_name = vMaxVolume->GetData().m_name; + vMaxVolume->GetData().m_pos = pos; + vHead->GetData().m_name = id; + } + + return true; +} +ICHullError ICHull::DoubleTriangle() +{ + // find three non colinear points + m_isFlat = false; + CircularList &vertices = m_mesh.GetVertices(); + CircularListElement *v0 = vertices.GetHead(); + while (Colinear(v0->GetData().m_pos, + v0->GetNext()->GetData().m_pos, + v0->GetNext()->GetNext()->GetData().m_pos)) + { + if ((v0 = v0->GetNext()) == vertices.GetHead()) + { + return ICHullErrorCoplanarPoints; + } + } + CircularListElement *v1 = v0->GetNext(); + CircularListElement *v2 = v1->GetNext(); + // mark points as processed + v0->GetData().m_tag = v1->GetData().m_tag = v2->GetData().m_tag = true; + + // create two triangles + CircularListElement *f0 = MakeFace(v0, v1, v2, 0); + MakeFace(v2, v1, v0, f0); + + // find a fourth non-coplanar point to form tetrahedron + CircularListElement *v3 = v2->GetNext(); + vertices.GetHead() = v3; + + double vol = Volume(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos); + while (vol == 0.0 && !v3->GetNext()->GetData().m_tag) + { + v3 = v3->GetNext(); + vol = Volume(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos); + } + if (vol == 0.0) + { + // compute the barycenter + Vec3 bary(0.0, 0.0, 0.0); + CircularListElement *vBary = v0; + do + { + bary += vBary->GetData().m_pos; + } while ((vBary = vBary->GetNext()) != v0); + bary /= static_cast(vertices.GetSize()); + + // Compute the normal to the plane + Vec3 p0 = v0->GetData().m_pos; + Vec3 p1 = v1->GetData().m_pos; + Vec3 p2 = v2->GetData().m_pos; + m_normal = (p1 - p0) ^ (p2 - p0); + m_normal.Normalize(); + // add dummy vertex placed at (bary + normal) + vertices.GetHead() = v2; + Vec3 newPt = bary + m_normal; + AddPoint(newPt, sc_dummyIndex); + m_dummyVertex = vertices.GetHead(); + m_isFlat = true; + v3 = v2->GetNext(); + vol = Volume(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos); + return ICHullErrorOK; + } + else if (v3 != vertices.GetHead()) + { + TMMVertex temp; + temp.m_name = v3->GetData().m_name; + temp.m_pos = v3->GetData().m_pos; + v3->GetData().m_name = vertices.GetHead()->GetData().m_name; + v3->GetData().m_pos = vertices.GetHead()->GetData().m_pos; + vertices.GetHead()->GetData().m_name = temp.m_name; + vertices.GetHead()->GetData().m_pos = temp.m_pos; + } + return ICHullErrorOK; +} +CircularListElement *ICHull::MakeFace(CircularListElement *v0, + CircularListElement *v1, + CircularListElement *v2, + CircularListElement *fold) +{ + CircularListElement *e0; + CircularListElement *e1; + CircularListElement *e2; + long index = 0; + if (!fold) // if first face to be created + { + e0 = m_mesh.AddEdge(); // create the three edges + e1 = m_mesh.AddEdge(); + e2 = m_mesh.AddEdge(); + } + else // otherwise re-use existing edges (in reverse order) + { + e0 = fold->GetData().m_edges[2]; + e1 = fold->GetData().m_edges[1]; + e2 = fold->GetData().m_edges[0]; + index = 1; + } + e0->GetData().m_vertices[0] = v0; + e0->GetData().m_vertices[1] = v1; + e1->GetData().m_vertices[0] = v1; + e1->GetData().m_vertices[1] = v2; + e2->GetData().m_vertices[0] = v2; + e2->GetData().m_vertices[1] = v0; + // create the new face + CircularListElement *f = m_mesh.AddTriangle(); + f->GetData().m_edges[0] = e0; + f->GetData().m_edges[1] = e1; + f->GetData().m_edges[2] = e2; + f->GetData().m_vertices[0] = v0; + f->GetData().m_vertices[1] = v1; + f->GetData().m_vertices[2] = v2; + // link edges to face f + e0->GetData().m_triangles[index] = e1->GetData().m_triangles[index] = e2->GetData().m_triangles[index] = f; + return f; +} +CircularListElement *ICHull::MakeConeFace(CircularListElement *e, CircularListElement *p) +{ + // create two new edges if they don't already exist + CircularListElement *newEdges[2]; + for (int i = 0; i < 2; ++i) + { + if (!(newEdges[i] = e->GetData().m_vertices[i]->GetData().m_duplicate)) + { // if the edge doesn't exits add it and mark the vertex as duplicated + newEdges[i] = m_mesh.AddEdge(); + newEdges[i]->GetData().m_vertices[0] = e->GetData().m_vertices[i]; + newEdges[i]->GetData().m_vertices[1] = p; + e->GetData().m_vertices[i]->GetData().m_duplicate = newEdges[i]; + } + } + // make the new face + CircularListElement *newFace = m_mesh.AddTriangle(); + newFace->GetData().m_edges[0] = e; + newFace->GetData().m_edges[1] = newEdges[0]; + newFace->GetData().m_edges[2] = newEdges[1]; + MakeCCW(newFace, e, p); + for (int i = 0; i < 2; ++i) + { + for (int j = 0; j < 2; ++j) + { + if (!newEdges[i]->GetData().m_triangles[j]) + { + newEdges[i]->GetData().m_triangles[j] = newFace; + break; + } + } + } + return newFace; +} +bool ICHull::ComputePointVolume(double &totalVolume, bool markVisibleFaces) +{ + // mark visible faces + CircularListElement *fHead = m_mesh.GetTriangles().GetHead(); + CircularListElement *f = fHead; + CircularList &vertices = m_mesh.GetVertices(); + CircularListElement *vertex0 = vertices.GetHead(); + bool visible = false; + Vec3 pos0 = Vec3(vertex0->GetData().m_pos.X(), + vertex0->GetData().m_pos.Y(), + vertex0->GetData().m_pos.Z()); + double vol = 0.0; + totalVolume = 0.0; + Vec3 ver0, ver1, ver2; + do + { + ver0.X() = f->GetData().m_vertices[0]->GetData().m_pos.X(); + ver0.Y() = f->GetData().m_vertices[0]->GetData().m_pos.Y(); + ver0.Z() = f->GetData().m_vertices[0]->GetData().m_pos.Z(); + ver1.X() = f->GetData().m_vertices[1]->GetData().m_pos.X(); + ver1.Y() = f->GetData().m_vertices[1]->GetData().m_pos.Y(); + ver1.Z() = f->GetData().m_vertices[1]->GetData().m_pos.Z(); + ver2.X() = f->GetData().m_vertices[2]->GetData().m_pos.X(); + ver2.Y() = f->GetData().m_vertices[2]->GetData().m_pos.Y(); + ver2.Z() = f->GetData().m_vertices[2]->GetData().m_pos.Z(); + vol = Volume(ver0, ver1, ver2, pos0); + if (vol < 0.0) + { + vol = fabs(vol); + totalVolume += vol; + if (markVisibleFaces) + { + f->GetData().m_visible = true; + m_trianglesToDelete.push_back(f); + } + visible = true; + } + f = f->GetNext(); + } while (f != fHead); + + if (m_trianglesToDelete.size() == m_mesh.m_triangles.GetSize()) + { + for (size_t i = 0; i < m_trianglesToDelete.size(); i++) + { + m_trianglesToDelete[i]->GetData().m_visible = false; + } + visible = false; + } + // if no faces visible from p then p is inside the hull + if (!visible && markVisibleFaces) + { + if (vertices.GetHead() == m_dummyVertex) + m_dummyVertex = 0; + vertices.Delete(); + m_trianglesToDelete.clear(); + return false; + } + return true; +} +bool ICHull::ProcessPoint() +{ + double totalVolume = 0.0; + if (!ComputePointVolume(totalVolume, true)) + { + return false; + } + // Mark edges in interior of visible region for deletion. + // Create a new face based on each border edge + CircularListElement *v0 = m_mesh.GetVertices().GetHead(); + CircularListElement *eHead = m_mesh.GetEdges().GetHead(); + CircularListElement *e = eHead; + CircularListElement *tmp = 0; + long nvisible = 0; + m_edgesToDelete.clear(); + m_edgesToUpdate.clear(); + do + { + tmp = e->GetNext(); + nvisible = 0; + for (int k = 0; k < 2; k++) + { + if (e->GetData().m_triangles[k]->GetData().m_visible) + { + nvisible++; + } + } + if (nvisible == 2) + { + m_edgesToDelete.push_back(e); + } + else if (nvisible == 1) + { + e->GetData().m_newFace = MakeConeFace(e, v0); + m_edgesToUpdate.push_back(e); + } + e = tmp; + } while (e != eHead); + return true; +} +bool ICHull::MakeCCW(CircularListElement *f, + CircularListElement *e, + CircularListElement *v) +{ + // the visible face adjacent to e + CircularListElement *fv; + if (e->GetData().m_triangles[0]->GetData().m_visible) + { + fv = e->GetData().m_triangles[0]; + } + else + { + fv = e->GetData().m_triangles[1]; + } + + // set vertex[0] and vertex[1] to have the same orientation as the corresponding vertices of fv. + long i; // index of e->m_vertices[0] in fv + CircularListElement *v0 = e->GetData().m_vertices[0]; + CircularListElement *v1 = e->GetData().m_vertices[1]; + for (i = 0; fv->GetData().m_vertices[i] != v0; i++) + ; + + if (fv->GetData().m_vertices[(i + 1) % 3] != e->GetData().m_vertices[1]) + { + f->GetData().m_vertices[0] = v1; + f->GetData().m_vertices[1] = v0; + } + else + { + f->GetData().m_vertices[0] = v0; + f->GetData().m_vertices[1] = v1; + // swap edges + CircularListElement *tmp = f->GetData().m_edges[0]; + f->GetData().m_edges[0] = f->GetData().m_edges[1]; + f->GetData().m_edges[1] = tmp; + } + f->GetData().m_vertices[2] = v; + return true; +} +bool ICHull::CleanUp(unsigned long &addedPoints) +{ + bool r0 = CleanEdges(); + bool r1 = CleanTriangles(); + bool r2 = CleanVertices(addedPoints); + return r0 && r1 && r2; +} +bool ICHull::CleanEdges() +{ + // integrate the new faces into the data structure + CircularListElement *e; + const std::vector *>::iterator itEndUpdate = m_edgesToUpdate.end(); + for (std::vector *>::iterator it = m_edgesToUpdate.begin(); it != itEndUpdate; ++it) + { + e = *it; + if (e->GetData().m_newFace) + { + if (e->GetData().m_triangles[0]->GetData().m_visible) + { + e->GetData().m_triangles[0] = e->GetData().m_newFace; + } + else + { + e->GetData().m_triangles[1] = e->GetData().m_newFace; + } + e->GetData().m_newFace = 0; + } + } + // delete edges maked for deletion + CircularList &edges = m_mesh.GetEdges(); + const std::vector *>::iterator itEndDelete = m_edgesToDelete.end(); + for (std::vector *>::iterator it = m_edgesToDelete.begin(); it != itEndDelete; ++it) + { + edges.Delete(*it); + } + m_edgesToDelete.clear(); + m_edgesToUpdate.clear(); + return true; +} +bool ICHull::CleanTriangles() +{ + CircularList &triangles = m_mesh.GetTriangles(); + const std::vector *>::iterator itEndDelete = m_trianglesToDelete.end(); + for (std::vector *>::iterator it = m_trianglesToDelete.begin(); it != itEndDelete; ++it) + { + if (m_distPoints) + { + if (m_isFlat) + { + // to be updated + } + else + { + std::set::const_iterator itPEnd((*it)->GetData().m_incidentPoints.end()); + std::set::const_iterator itP((*it)->GetData().m_incidentPoints.begin()); + std::map::iterator itPoint; + for (; itP != itPEnd; ++itP) + { + itPoint = m_distPoints->find(*itP); + if (itPoint != m_distPoints->end()) + { + itPoint->second.m_computed = false; + } + } + } + } + triangles.Delete(*it); + } + m_trianglesToDelete.clear(); + return true; +} +bool ICHull::CleanVertices(unsigned long &addedPoints) +{ + // mark all vertices incident to some undeleted edge as on the hull + CircularList &edges = m_mesh.GetEdges(); + CircularListElement *e = edges.GetHead(); + size_t nE = edges.GetSize(); + for (size_t i = 0; i < nE; i++) + { + e->GetData().m_vertices[0]->GetData().m_onHull = true; + e->GetData().m_vertices[1]->GetData().m_onHull = true; + e = e->GetNext(); + } + // delete all the vertices that have been processed but are not on the hull + CircularList &vertices = m_mesh.GetVertices(); + CircularListElement *vHead = vertices.GetHead(); + CircularListElement *v = vHead; + v = v->GetPrev(); + do + { + if (v->GetData().m_tag && !v->GetData().m_onHull) + { + CircularListElement *tmp = v->GetPrev(); + if (tmp == m_dummyVertex) + m_dummyVertex = 0; + vertices.Delete(v); + v = tmp; + addedPoints--; + } + else + { + v->GetData().m_duplicate = 0; + v->GetData().m_onHull = false; + v = v->GetPrev(); + } + } while (v->GetData().m_tag && v != vHead); + return true; +} +void ICHull::Clear() +{ + m_mesh.Clear(); + m_edgesToDelete = std::vector *>(); + m_edgesToUpdate = std::vector *>(); + m_trianglesToDelete = std::vector *>(); + m_isFlat = false; +} +const ICHull &ICHull::operator=(ICHull &rhs) +{ + if (&rhs != this) + { + m_mesh.Copy(rhs.m_mesh); + m_edgesToDelete = rhs.m_edgesToDelete; + m_edgesToUpdate = rhs.m_edgesToUpdate; + m_trianglesToDelete = rhs.m_trianglesToDelete; + m_isFlat = rhs.m_isFlat; + } + return (*this); +} +double ICHull::ComputeVolume() +{ + size_t nV = m_mesh.m_vertices.GetSize(); + if (nV == 0 || m_isFlat) + { + return 0.0; + } + Vec3 bary(0.0, 0.0, 0.0); + for (size_t v = 0; v < nV; v++) + { + bary.X() += m_mesh.m_vertices.GetHead()->GetData().m_pos.X(); + bary.Y() += m_mesh.m_vertices.GetHead()->GetData().m_pos.Y(); + bary.Z() += m_mesh.m_vertices.GetHead()->GetData().m_pos.Z(); + m_mesh.m_vertices.Next(); + } + bary /= static_cast(nV); + + size_t nT = m_mesh.m_triangles.GetSize(); + Vec3 ver0, ver1, ver2; + double totalVolume = 0.0; + for (size_t t = 0; t < nT; t++) + { + ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X(); + ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y(); + ver0.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Z(); + ver1.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.X(); + ver1.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Y(); + ver1.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Z(); + ver2.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.X(); + ver2.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Y(); + ver2.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Z(); + totalVolume += Volume(ver0, ver1, ver2, bary); + m_mesh.m_triangles.Next(); + } + return totalVolume; +} +bool ICHull::IsInside(const Vec3 &pt0) +{ + const Vec3 pt(pt0.X(), pt0.Y(), pt0.Z()); + if (m_isFlat) + { + size_t nT = m_mesh.m_triangles.GetSize(); + Vec3 ver0, ver1, ver2, a, b, c; + double u, v; + for (size_t t = 0; t < nT; t++) + { + ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X(); + ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y(); + ver0.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Z(); + ver1.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.X(); + ver1.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Y(); + ver1.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Z(); + ver2.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.X(); + ver2.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Y(); + ver2.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Z(); + a = ver1 - ver0; + b = ver2 - ver0; + c = pt - ver0; + u = c * a; + v = c * b; + if (u >= 0.0 && u <= 1.0 && v >= 0.0 && u + v <= 1.0) + { + return true; + } + m_mesh.m_triangles.Next(); + } + return false; + } + else + { + size_t nT = m_mesh.m_triangles.GetSize(); + Vec3 ver0, ver1, ver2; + for (size_t t = 0; t < nT; t++) + { + ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X(); + ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y(); + ver0.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Z(); + ver1.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.X(); + ver1.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Y(); + ver1.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Z(); + ver2.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.X(); + ver2.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Y(); + ver2.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Z(); + if (Volume(ver0, ver1, ver2, pt) < 0.0) + { + return false; + } + m_mesh.m_triangles.Next(); + } + return true; + } +} +double ICHull::ComputeDistance(long name, const Vec3 &pt, const Vec3 &normal, bool &insideHull, bool updateIncidentPoints) +{ + Vec3 ptNormal(static_cast(normal.X()), + static_cast(normal.Y()), + static_cast(normal.Z())); + Vec3 p0(static_cast(pt.X()), + static_cast(pt.Y()), + static_cast(pt.Z())); + + if (m_isFlat) + { + double distance = 0.0; + Vec3 chNormal(static_cast(m_normal.X()), + static_cast(m_normal.Y()), + static_cast(m_normal.Z())); + ptNormal -= (ptNormal * chNormal) * chNormal; + if (ptNormal.GetNorm() > 0.0) + { + ptNormal.Normalize(); + long nameVE1; + long nameVE2; + Vec3 pa, pb, d0, d1, d2, d3; + Vec3 p1 = p0 + ptNormal; + Vec3 p2, p3; + double mua, mub, s; + const double EPS = 0.00000000001; + size_t nE = m_mesh.GetNEdges(); + for (size_t e = 0; e < nE; e++) + { + TMMEdge ¤tEdge = m_mesh.m_edges.GetHead()->GetData(); + nameVE1 = currentEdge.m_vertices[0]->GetData().m_name; + nameVE2 = currentEdge.m_vertices[1]->GetData().m_name; + if (currentEdge.m_triangles[0] == 0 || currentEdge.m_triangles[1] == 0) + { + if (nameVE1 == name || nameVE2 == name) + { + return 0.0; + } + /* if (debug) std::cout << "V" << name << " E " << nameVE1 << " " << nameVE2 << std::endl; */ - p2.X() = currentEdge.m_vertices[0]->GetData().m_pos.X(); - p2.Y() = currentEdge.m_vertices[0]->GetData().m_pos.Y(); - p2.Z() = currentEdge.m_vertices[0]->GetData().m_pos.Z(); - p3.X() = currentEdge.m_vertices[1]->GetData().m_pos.X(); - p3.Y() = currentEdge.m_vertices[1]->GetData().m_pos.Y(); - p3.Z() = currentEdge.m_vertices[1]->GetData().m_pos.Z(); - d0 = p3 - p2; - if (d0.GetNorm() > 0.0) - { - if (IntersectLineLine(p0, p1, p2, p3, pa, pb, mua, mub)) - { - d1 = pa - p2; - d2 = pa - pb; - d3 = pa - p0; - mua = d1.GetNorm()/d0.GetNorm(); - mub = d1*d0; - s = d3*ptNormal; - if (d2.GetNorm() < EPS && mua <= 1.0 && mub>=0.0 && s>0.0) - { - distance = std::max(distance, d3.GetNorm()); - } - } - } - } - m_mesh.m_edges.Next(); + p2.X() = currentEdge.m_vertices[0]->GetData().m_pos.X(); + p2.Y() = currentEdge.m_vertices[0]->GetData().m_pos.Y(); + p2.Z() = currentEdge.m_vertices[0]->GetData().m_pos.Z(); + p3.X() = currentEdge.m_vertices[1]->GetData().m_pos.X(); + p3.Y() = currentEdge.m_vertices[1]->GetData().m_pos.Y(); + p3.Z() = currentEdge.m_vertices[1]->GetData().m_pos.Z(); + d0 = p3 - p2; + if (d0.GetNorm() > 0.0) + { + if (IntersectLineLine(p0, p1, p2, p3, pa, pb, mua, mub)) + { + d1 = pa - p2; + d2 = pa - pb; + d3 = pa - p0; + mua = d1.GetNorm() / d0.GetNorm(); + mub = d1 * d0; + s = d3 * ptNormal; + if (d2.GetNorm() < EPS && mua <= 1.0 && mub >= 0.0 && s > 0.0) + { + distance = std::max(distance, d3.GetNorm()); + } + } + } } + m_mesh.m_edges.Next(); } - return distance; } - else - { - Vec3 ptNormal(static_cast(normal.X()), - static_cast(normal.Y()), - static_cast(normal.Z())); + return distance; + } + else + { + Vec3 ptNormal(static_cast(normal.X()), + static_cast(normal.Y()), + static_cast(normal.Z())); - Vec3 impact; - long nhit; - double dist; - double distance = 0.0; - size_t nT = m_mesh.GetNTriangles(); - insideHull = false; - CircularListElement * face = 0; - Vec3 ver0, ver1, ver2; - for(size_t f = 0; f < nT; f++) - { - TMMTriangle & currentTriangle = m_mesh.m_triangles.GetHead()->GetData(); - /* + Vec3 impact; + long nhit; + double dist; + double distance = 0.0; + size_t nT = m_mesh.GetNTriangles(); + insideHull = false; + CircularListElement *face = 0; + Vec3 ver0, ver1, ver2; + for (size_t f = 0; f < nT; f++) + { + TMMTriangle ¤tTriangle = m_mesh.m_triangles.GetHead()->GetData(); + /* if (debug) std::cout << "T " << currentTriangle.m_vertices[0]->GetData().m_name << " " << currentTriangle.m_vertices[1]->GetData().m_name << " " << currentTriangle.m_vertices[2]->GetData().m_name << std::endl; */ - if (currentTriangle.m_vertices[0]->GetData().m_name == name || - currentTriangle.m_vertices[1]->GetData().m_name == name || - currentTriangle.m_vertices[2]->GetData().m_name == name) - { - nhit = 1; - dist = 0.0; - } - else - { - ver0.X() = currentTriangle.m_vertices[0]->GetData().m_pos.X(); - ver0.Y() = currentTriangle.m_vertices[0]->GetData().m_pos.Y(); - ver0.Z() = currentTriangle.m_vertices[0]->GetData().m_pos.Z(); - ver1.X() = currentTriangle.m_vertices[1]->GetData().m_pos.X(); - ver1.Y() = currentTriangle.m_vertices[1]->GetData().m_pos.Y(); - ver1.Z() = currentTriangle.m_vertices[1]->GetData().m_pos.Z(); - ver2.X() = currentTriangle.m_vertices[2]->GetData().m_pos.X(); - ver2.Y() = currentTriangle.m_vertices[2]->GetData().m_pos.Y(); - ver2.Z() = currentTriangle.m_vertices[2]->GetData().m_pos.Z(); - nhit = IntersectRayTriangle(p0, ptNormal, ver0, ver1, ver2, dist); - } + if (currentTriangle.m_vertices[0]->GetData().m_name == name || + currentTriangle.m_vertices[1]->GetData().m_name == name || + currentTriangle.m_vertices[2]->GetData().m_name == name) + { + nhit = 1; + dist = 0.0; + } + else + { + ver0.X() = currentTriangle.m_vertices[0]->GetData().m_pos.X(); + ver0.Y() = currentTriangle.m_vertices[0]->GetData().m_pos.Y(); + ver0.Z() = currentTriangle.m_vertices[0]->GetData().m_pos.Z(); + ver1.X() = currentTriangle.m_vertices[1]->GetData().m_pos.X(); + ver1.Y() = currentTriangle.m_vertices[1]->GetData().m_pos.Y(); + ver1.Z() = currentTriangle.m_vertices[1]->GetData().m_pos.Z(); + ver2.X() = currentTriangle.m_vertices[2]->GetData().m_pos.X(); + ver2.Y() = currentTriangle.m_vertices[2]->GetData().m_pos.Y(); + ver2.Z() = currentTriangle.m_vertices[2]->GetData().m_pos.Z(); + nhit = IntersectRayTriangle(p0, ptNormal, ver0, ver1, ver2, dist); + } - if (nhit == 1 && distance <= dist) - { - distance = dist; - insideHull = true; - face = m_mesh.m_triangles.GetHead(); -/* + if (nhit == 1 && distance <= dist) + { + distance = dist; + insideHull = true; + face = m_mesh.m_triangles.GetHead(); + /* std::cout << name << " -> T " << currentTriangle.m_vertices[0]->GetData().m_name << " " << currentTriangle.m_vertices[1]->GetData().m_name << " " << currentTriangle.m_vertices[2]->GetData().m_name << " Dist " << dist << " P " << currentTriangle.m_normal * normal << std::endl; */ - if (dist > 0.1) - { - break; - } + if (dist > 0.1) + { + break; } - m_mesh.m_triangles.Next(); } - if (updateIncidentPoints && face && m_distPoints) - { - (*m_distPoints)[name].m_dist = static_cast(distance); - face->GetData().m_incidentPoints.insert(name); - } - return distance; + m_mesh.m_triangles.Next(); } + if (updateIncidentPoints && face && m_distPoints) + { + (*m_distPoints)[name].m_dist = static_cast(distance); + face->GetData().m_incidentPoints.insert(name); + } + return distance; } } - - +} // namespace HACD diff --git a/Extras/HACD/hacdICHull.h b/Extras/HACD/hacdICHull.h index 548f992bd..c7d83956f 100644 --- a/Extras/HACD/hacdICHull.h +++ b/Extras/HACD/hacdICHull.h @@ -22,99 +22,99 @@ #include namespace HACD { - class DPoint; - class HACD; - //! Incremental Convex Hull algorithm (cf. http://maven.smith.edu/~orourke/books/ftp.html ). - enum ICHullError - { - ICHullErrorOK = 0, - ICHullErrorCoplanarPoints, - ICHullErrorNoVolume, - ICHullErrorInconsistent, - ICHullErrorNotEnoughPoints - }; - class ICHull - { - public: - //! - bool IsFlat() { return m_isFlat;} - //! - std::map * GetDistPoints() const { return m_distPoints;} - //! - void SetDistPoints(std::map * distPoints) { m_distPoints = distPoints;} - //! Returns the computed mesh - TMMesh & GetMesh() { return m_mesh;} - //! Add one point to the convex-hull - bool AddPoint(const Vec3 & point) {return AddPoints(&point, 1);} - //! Add one point to the convex-hull - bool AddPoint(const Vec3 & point, long id); - //! Add points to the convex-hull - bool AddPoints(const Vec3 * points, size_t nPoints); - bool AddPoints(std::vector< Vec3 > points); - //! - ICHullError Process(); - //! - ICHullError Process(unsigned long nPointsCH); - //! - double ComputeVolume(); - //! - bool IsInside(const Vec3 & pt0); - //! - double ComputeDistance(long name, const Vec3 & pt, const Vec3 & normal, bool & insideHull, bool updateIncidentPoints); - //! - const ICHull & operator=(ICHull & rhs); +class DPoint; +class HACD; +//! Incremental Convex Hull algorithm (cf. http://maven.smith.edu/~orourke/books/ftp.html ). +enum ICHullError +{ + ICHullErrorOK = 0, + ICHullErrorCoplanarPoints, + ICHullErrorNoVolume, + ICHullErrorInconsistent, + ICHullErrorNotEnoughPoints +}; +class ICHull +{ +public: + //! + bool IsFlat() { return m_isFlat; } + //! + std::map *GetDistPoints() const { return m_distPoints; } + //! + void SetDistPoints(std::map *distPoints) { m_distPoints = distPoints; } + //! Returns the computed mesh + TMMesh &GetMesh() { return m_mesh; } + //! Add one point to the convex-hull + bool AddPoint(const Vec3 &point) { return AddPoints(&point, 1); } + //! Add one point to the convex-hull + bool AddPoint(const Vec3 &point, long id); + //! Add points to the convex-hull + bool AddPoints(const Vec3 *points, size_t nPoints); + bool AddPoints(std::vector > points); + //! + ICHullError Process(); + //! + ICHullError Process(unsigned long nPointsCH); + //! + double ComputeVolume(); + //! + bool IsInside(const Vec3 &pt0); + //! + double ComputeDistance(long name, const Vec3 &pt, const Vec3 &normal, bool &insideHull, bool updateIncidentPoints); + //! + const ICHull &operator=(ICHull &rhs); - //! Constructor - ICHull(void); - //! Destructor - virtual ~ICHull(void) {}; + //! Constructor + ICHull(void); + //! Destructor + virtual ~ICHull(void){}; - private: - //! DoubleTriangle builds the initial double triangle. It first finds 3 noncollinear points and makes two faces out of them, in opposite order. It then finds a fourth point that is not coplanar with that face. The vertices are stored in the face structure in counterclockwise order so that the volume between the face and the point is negative. Lastly, the 3 newfaces to the fourth point are constructed and the data structures are cleaned up. - ICHullError DoubleTriangle(); - //! MakeFace creates a new face structure from three vertices (in ccw order). It returns a pointer to the face. - CircularListElement * MakeFace(CircularListElement * v0, - CircularListElement * v1, - CircularListElement * v2, - CircularListElement * fold); - //! - CircularListElement * MakeConeFace(CircularListElement * e, CircularListElement * v); - //! - bool ProcessPoint(); - //! - bool ComputePointVolume(double &totalVolume, bool markVisibleFaces); - //! - bool FindMaxVolumePoint(); - //! - bool CleanEdges(); - //! - bool CleanVertices(unsigned long & addedPoints); - //! - bool CleanTriangles(); - //! - bool CleanUp(unsigned long & addedPoints); - //! - bool MakeCCW(CircularListElement * f, - CircularListElement * e, - CircularListElement * v); - void Clear(); - private: - static const long sc_dummyIndex; - static const double sc_distMin; - TMMesh m_mesh; - std::vector *> m_edgesToDelete; - std::vector *> m_edgesToUpdate; - std::vector *> m_trianglesToDelete; - std::map * m_distPoints; - CircularListElement * m_dummyVertex; - Vec3 m_normal; - bool m_isFlat; - - - ICHull(const ICHull & rhs); - - friend class HACD; - }; +private: + //! DoubleTriangle builds the initial double triangle. It first finds 3 noncollinear points and makes two faces out of them, in opposite order. It then finds a fourth point that is not coplanar with that face. The vertices are stored in the face structure in counterclockwise order so that the volume between the face and the point is negative. Lastly, the 3 newfaces to the fourth point are constructed and the data structures are cleaned up. + ICHullError DoubleTriangle(); + //! MakeFace creates a new face structure from three vertices (in ccw order). It returns a pointer to the face. + CircularListElement *MakeFace(CircularListElement *v0, + CircularListElement *v1, + CircularListElement *v2, + CircularListElement *fold); + //! + CircularListElement *MakeConeFace(CircularListElement *e, CircularListElement *v); + //! + bool ProcessPoint(); + //! + bool ComputePointVolume(double &totalVolume, bool markVisibleFaces); + //! + bool FindMaxVolumePoint(); + //! + bool CleanEdges(); + //! + bool CleanVertices(unsigned long &addedPoints); + //! + bool CleanTriangles(); + //! + bool CleanUp(unsigned long &addedPoints); + //! + bool MakeCCW(CircularListElement *f, + CircularListElement *e, + CircularListElement *v); + void Clear(); -} +private: + static const long sc_dummyIndex; + static const double sc_distMin; + TMMesh m_mesh; + std::vector *> m_edgesToDelete; + std::vector *> m_edgesToUpdate; + std::vector *> m_trianglesToDelete; + std::map *m_distPoints; + CircularListElement *m_dummyVertex; + Vec3 m_normal; + bool m_isFlat; + + ICHull(const ICHull &rhs); + + friend class HACD; +}; + +} // namespace HACD #endif diff --git a/Extras/HACD/hacdManifoldMesh.cpp b/Extras/HACD/hacdManifoldMesh.cpp index 22a3576e4..3aa90260b 100644 --- a/Extras/HACD/hacdManifoldMesh.cpp +++ b/Extras/HACD/hacdManifoldMesh.cpp @@ -15,563 +15,568 @@ #include "hacdManifoldMesh.h" using namespace std; - namespace HACD -{ - Material::Material(void) - { - m_diffuseColor.X() = 0.5; - m_diffuseColor.Y() = 0.5; - m_diffuseColor.Z() = 0.5; - m_specularColor.X() = 0.5; - m_specularColor.Y() = 0.5; - m_specularColor.Z() = 0.5; - m_ambientIntensity = 0.4; - m_emissiveColor.X() = 0.0; - m_emissiveColor.Y() = 0.0; - m_emissiveColor.Z() = 0.0; - m_shininess = 0.4; - m_transparency = 0.0; - } - - TMMVertex::TMMVertex(void) +{ +Material::Material(void) +{ + m_diffuseColor.X() = 0.5; + m_diffuseColor.Y() = 0.5; + m_diffuseColor.Z() = 0.5; + m_specularColor.X() = 0.5; + m_specularColor.Y() = 0.5; + m_specularColor.Z() = 0.5; + m_ambientIntensity = 0.4; + m_emissiveColor.X() = 0.0; + m_emissiveColor.Y() = 0.0; + m_emissiveColor.Z() = 0.0; + m_shininess = 0.4; + m_transparency = 0.0; +} + +TMMVertex::TMMVertex(void) +{ + m_name = 0; + m_id = 0; + m_duplicate = 0; + m_onHull = false; + m_tag = false; +} +TMMVertex::~TMMVertex(void) +{ +} +TMMEdge::TMMEdge(void) +{ + m_id = 0; + m_triangles[0] = m_triangles[1] = m_newFace = 0; + m_vertices[0] = m_vertices[1] = 0; +} +TMMEdge::~TMMEdge(void) +{ +} +TMMTriangle::TMMTriangle(void) +{ + m_id = 0; + for (int i = 0; i < 3; i++) { - m_name = 0; - m_id = 0; - m_duplicate = 0; - m_onHull = false; - m_tag = false; + m_edges[i] = 0; + m_vertices[0] = 0; } - TMMVertex::~TMMVertex(void) - { - } - TMMEdge::TMMEdge(void) - { - m_id = 0; - m_triangles[0] = m_triangles[1] = m_newFace = 0; - m_vertices[0] = m_vertices[1] = 0; - } - TMMEdge::~TMMEdge(void) - { - } - TMMTriangle::TMMTriangle(void) - { - m_id = 0; - for(int i = 0; i < 3; i++) - { - m_edges[i] = 0; - m_vertices[0] = 0; - } - m_visible = false; - } - TMMTriangle::~TMMTriangle(void) - { - } - TMMesh::TMMesh(void) - { - m_barycenter = Vec3(0,0,0); - m_diag = 1; - } - TMMesh::~TMMesh(void) + m_visible = false; +} +TMMTriangle::~TMMTriangle(void) +{ +} +TMMesh::TMMesh(void) +{ + m_barycenter = Vec3(0, 0, 0); + m_diag = 1; +} +TMMesh::~TMMesh(void) +{ +} + +void TMMesh::Print() +{ + size_t nV = m_vertices.GetSize(); + std::cout << "-----------------------------" << std::endl; + std::cout << "vertices (" << nV << ")" << std::endl; + for (size_t v = 0; v < nV; v++) { + const TMMVertex ¤tVertex = m_vertices.GetData(); + std::cout << currentVertex.m_id << ", " + << currentVertex.m_pos.X() << ", " + << currentVertex.m_pos.Y() << ", " + << currentVertex.m_pos.Z() << std::endl; + m_vertices.Next(); } - void TMMesh::Print() + size_t nE = m_edges.GetSize(); + std::cout << "edges (" << nE << ")" << std::endl; + for (size_t e = 0; e < nE; e++) + { + const TMMEdge ¤tEdge = m_edges.GetData(); + const CircularListElement *v0 = currentEdge.m_vertices[0]; + const CircularListElement *v1 = currentEdge.m_vertices[1]; + const CircularListElement *f0 = currentEdge.m_triangles[0]; + const CircularListElement *f1 = currentEdge.m_triangles[1]; + + std::cout << "-> (" << v0->GetData().m_name << ", " << v1->GetData().m_name << ")" << std::endl; + std::cout << "-> F0 (" << f0->GetData().m_vertices[0]->GetData().m_name << ", " + << f0->GetData().m_vertices[1]->GetData().m_name << ", " + << f0->GetData().m_vertices[2]->GetData().m_name << ")" << std::endl; + std::cout << "-> F1 (" << f1->GetData().m_vertices[0]->GetData().m_name << ", " + << f1->GetData().m_vertices[1]->GetData().m_name << ", " + << f1->GetData().m_vertices[2]->GetData().m_name << ")" << std::endl; + m_edges.Next(); + } + size_t nT = m_triangles.GetSize(); + std::cout << "triangles (" << nT << ")" << std::endl; + for (size_t t = 0; t < nT; t++) + { + const TMMTriangle ¤tTriangle = m_triangles.GetData(); + const CircularListElement *v0 = currentTriangle.m_vertices[0]; + const CircularListElement *v1 = currentTriangle.m_vertices[1]; + const CircularListElement *v2 = currentTriangle.m_vertices[2]; + const CircularListElement *e0 = currentTriangle.m_edges[0]; + const CircularListElement *e1 = currentTriangle.m_edges[1]; + const CircularListElement *e2 = currentTriangle.m_edges[2]; + + std::cout << "-> (" << v0->GetData().m_name << ", " << v1->GetData().m_name << ", " << v2->GetData().m_name << ")" << std::endl; + + std::cout << "-> E0 (" << e0->GetData().m_vertices[0]->GetData().m_name << ", " + << e0->GetData().m_vertices[1]->GetData().m_name << ")" << std::endl; + std::cout << "-> E1 (" << e1->GetData().m_vertices[0]->GetData().m_name << ", " + << e1->GetData().m_vertices[1]->GetData().m_name << ")" << std::endl; + std::cout << "-> E2 (" << e2->GetData().m_vertices[0]->GetData().m_name << ", " + << e2->GetData().m_vertices[1]->GetData().m_name << ")" << std::endl; + m_triangles.Next(); + } +} +bool TMMesh::Save(const char *fileName) +{ + std::ofstream fout(fileName); + std::cout << "Saving " << fileName << std::endl; + if (SaveVRML2(fout)) + { + fout.close(); + return true; + } + return false; +} +bool TMMesh::SaveVRML2(std::ofstream &fout) +{ + return SaveVRML2(fout, Material()); +} +bool TMMesh::SaveVRML2(std::ofstream &fout, const Material &material) +{ + if (fout.is_open()) { size_t nV = m_vertices.GetSize(); - std::cout << "-----------------------------" << std::endl; - std::cout << "vertices (" << nV << ")" << std::endl; - for(size_t v = 0; v < nV; v++) - { - const TMMVertex & currentVertex = m_vertices.GetData(); - std::cout << currentVertex.m_id << ", " - << currentVertex.m_pos.X() << ", " - << currentVertex.m_pos.Y() << ", " - << currentVertex.m_pos.Z() << std::endl; - m_vertices.Next(); - } - - - size_t nE = m_edges.GetSize(); - std::cout << "edges (" << nE << ")" << std::endl; - for(size_t e = 0; e < nE; e++) - { - const TMMEdge & currentEdge = m_edges.GetData(); - const CircularListElement * v0 = currentEdge.m_vertices[0]; - const CircularListElement * v1 = currentEdge.m_vertices[1]; - const CircularListElement * f0 = currentEdge.m_triangles[0]; - const CircularListElement * f1 = currentEdge.m_triangles[1]; - - std::cout << "-> (" << v0->GetData().m_name << ", " << v1->GetData().m_name << ")" << std::endl; - std::cout << "-> F0 (" << f0->GetData().m_vertices[0]->GetData().m_name << ", " - << f0->GetData().m_vertices[1]->GetData().m_name << ", " - << f0->GetData().m_vertices[2]->GetData().m_name <<")" << std::endl; - std::cout << "-> F1 (" << f1->GetData().m_vertices[0]->GetData().m_name << ", " - << f1->GetData().m_vertices[1]->GetData().m_name << ", " - << f1->GetData().m_vertices[2]->GetData().m_name << ")" << std::endl; - m_edges.Next(); - } size_t nT = m_triangles.GetSize(); - std::cout << "triangles (" << nT << ")" << std::endl; - for(size_t t = 0; t < nT; t++) + fout << "#VRML V2.0 utf8" << std::endl; + fout << "" << std::endl; + fout << "# Vertices: " << nV << std::endl; + fout << "# Triangles: " << nT << std::endl; + fout << "" << std::endl; + fout << "Group {" << std::endl; + fout << " children [" << std::endl; + fout << " Shape {" << std::endl; + fout << " appearance Appearance {" << std::endl; + fout << " material Material {" << std::endl; + fout << " diffuseColor " << material.m_diffuseColor.X() << " " + << material.m_diffuseColor.Y() << " " + << material.m_diffuseColor.Z() << std::endl; + fout << " ambientIntensity " << material.m_ambientIntensity << std::endl; + fout << " specularColor " << material.m_specularColor.X() << " " + << material.m_specularColor.Y() << " " + << material.m_specularColor.Z() << std::endl; + fout << " emissiveColor " << material.m_emissiveColor.X() << " " + << material.m_emissiveColor.Y() << " " + << material.m_emissiveColor.Z() << std::endl; + fout << " shininess " << material.m_shininess << std::endl; + fout << " transparency " << material.m_transparency << std::endl; + fout << " }" << std::endl; + fout << " }" << std::endl; + fout << " geometry IndexedFaceSet {" << std::endl; + fout << " ccw TRUE" << std::endl; + fout << " solid TRUE" << std::endl; + fout << " convex TRUE" << std::endl; + if (GetNVertices() > 0) { - const TMMTriangle & currentTriangle = m_triangles.GetData(); - const CircularListElement * v0 = currentTriangle.m_vertices[0]; - const CircularListElement * v1 = currentTriangle.m_vertices[1]; - const CircularListElement * v2 = currentTriangle.m_vertices[2]; - const CircularListElement * e0 = currentTriangle.m_edges[0]; - const CircularListElement * e1 = currentTriangle.m_edges[1]; - const CircularListElement * e2 = currentTriangle.m_edges[2]; - - std::cout << "-> (" << v0->GetData().m_name << ", " << v1->GetData().m_name << ", "<< v2->GetData().m_name << ")" << std::endl; - - std::cout << "-> E0 (" << e0->GetData().m_vertices[0]->GetData().m_name << ", " - << e0->GetData().m_vertices[1]->GetData().m_name << ")" << std::endl; - std::cout << "-> E1 (" << e1->GetData().m_vertices[0]->GetData().m_name << ", " - << e1->GetData().m_vertices[1]->GetData().m_name << ")" << std::endl; - std::cout << "-> E2 (" << e2->GetData().m_vertices[0]->GetData().m_name << ", " - << e2->GetData().m_vertices[1]->GetData().m_name << ")" << std::endl; - m_triangles.Next(); - } - } - bool TMMesh::Save(const char *fileName) - { - std::ofstream fout(fileName); - std::cout << "Saving " << fileName << std::endl; - if (SaveVRML2(fout)) - { - fout.close(); - return true; + fout << " coord DEF co Coordinate {" << std::endl; + fout << " point [" << std::endl; + for (size_t v = 0; v < nV; v++) + { + TMMVertex ¤tVertex = m_vertices.GetData(); + fout << " " << currentVertex.m_pos.X() << " " + << currentVertex.m_pos.Y() << " " + << currentVertex.m_pos.Z() << "," << std::endl; + currentVertex.m_id = v; + m_vertices.Next(); + } + fout << " ]" << std::endl; + fout << " }" << std::endl; } - return false; - } - bool TMMesh::SaveVRML2(std::ofstream &fout) - { - return SaveVRML2(fout, Material()); - } - bool TMMesh::SaveVRML2(std::ofstream &fout, const Material & material) - { - if (fout.is_open()) - { - size_t nV = m_vertices.GetSize(); - size_t nT = m_triangles.GetSize(); - fout <<"#VRML V2.0 utf8" << std::endl; - fout <<"" << std::endl; - fout <<"# Vertices: " << nV << std::endl; - fout <<"# Triangles: " << nT << std::endl; - fout <<"" << std::endl; - fout <<"Group {" << std::endl; - fout <<" children [" << std::endl; - fout <<" Shape {" << std::endl; - fout <<" appearance Appearance {" << std::endl; - fout <<" material Material {" << std::endl; - fout <<" diffuseColor " << material.m_diffuseColor.X() << " " - << material.m_diffuseColor.Y() << " " - << material.m_diffuseColor.Z() << std::endl; - fout <<" ambientIntensity " << material.m_ambientIntensity << std::endl; - fout <<" specularColor " << material.m_specularColor.X() << " " - << material.m_specularColor.Y() << " " - << material.m_specularColor.Z() << std::endl; - fout <<" emissiveColor " << material.m_emissiveColor.X() << " " - << material.m_emissiveColor.Y() << " " - << material.m_emissiveColor.Z() << std::endl; - fout <<" shininess " << material.m_shininess << std::endl; - fout <<" transparency " << material.m_transparency << std::endl; - fout <<" }" << std::endl; - fout <<" }" << std::endl; - fout <<" geometry IndexedFaceSet {" << std::endl; - fout <<" ccw TRUE" << std::endl; - fout <<" solid TRUE" << std::endl; - fout <<" convex TRUE" << std::endl; - if (GetNVertices() > 0) { - fout <<" coord DEF co Coordinate {" << std::endl; - fout <<" point [" << std::endl; - for(size_t v = 0; v < nV; v++) - { - TMMVertex & currentVertex = m_vertices.GetData(); - fout <<" " << currentVertex.m_pos.X() << " " - << currentVertex.m_pos.Y() << " " - << currentVertex.m_pos.Z() << "," << std::endl; - currentVertex.m_id = v; - m_vertices.Next(); - } - fout <<" ]" << std::endl; - fout <<" }" << std::endl; - } - if (GetNTriangles() > 0) { - fout <<" coordIndex [ " << std::endl; - for(size_t f = 0; f < nT; f++) - { - TMMTriangle & currentTriangle = m_triangles.GetData(); - fout <<" " << currentTriangle.m_vertices[0]->GetData().m_id << ", " - << currentTriangle.m_vertices[1]->GetData().m_id << ", " - << currentTriangle.m_vertices[2]->GetData().m_id << ", -1," << std::endl; - m_triangles.Next(); - } - fout <<" ]" << std::endl; - } - fout <<" }" << std::endl; - fout <<" }" << std::endl; - fout <<" ]" << std::endl; - fout <<"}" << std::endl; - } - return true; - } - void TMMesh::GetIFS(Vec3 * const points, Vec3 * const triangles) - { - size_t nV = m_vertices.GetSize(); - size_t nT = m_triangles.GetSize(); + if (GetNTriangles() > 0) + { + fout << " coordIndex [ " << std::endl; + for (size_t f = 0; f < nT; f++) + { + TMMTriangle ¤tTriangle = m_triangles.GetData(); + fout << " " << currentTriangle.m_vertices[0]->GetData().m_id << ", " + << currentTriangle.m_vertices[1]->GetData().m_id << ", " + << currentTriangle.m_vertices[2]->GetData().m_id << ", -1," << std::endl; + m_triangles.Next(); + } + fout << " ]" << std::endl; + } + fout << " }" << std::endl; + fout << " }" << std::endl; + fout << " ]" << std::endl; + fout << "}" << std::endl; + } + return true; +} +void TMMesh::GetIFS(Vec3 *const points, Vec3 *const triangles) +{ + size_t nV = m_vertices.GetSize(); + size_t nT = m_triangles.GetSize(); - for(size_t v = 0; v < nV; v++) - { - points[v] = m_vertices.GetData().m_pos; - m_vertices.GetData().m_id = v; - m_vertices.Next(); - } - for(size_t f = 0; f < nT; f++) - { - TMMTriangle & currentTriangle = m_triangles.GetData(); - triangles[f].X() = static_cast(currentTriangle.m_vertices[0]->GetData().m_id); - triangles[f].Y() = static_cast(currentTriangle.m_vertices[1]->GetData().m_id); - triangles[f].Z() = static_cast(currentTriangle.m_vertices[2]->GetData().m_id); - m_triangles.Next(); - } - } - void TMMesh::Clear() - { - m_vertices.Clear(); - m_edges.Clear(); - m_triangles.Clear(); - } - void TMMesh::Copy(TMMesh & mesh) - { - Clear(); - // updating the id's - size_t nV = mesh.m_vertices.GetSize(); - size_t nE = mesh. m_edges.GetSize(); - size_t nT = mesh.m_triangles.GetSize(); - for(size_t v = 0; v < nV; v++) - { - mesh.m_vertices.GetData().m_id = v; - mesh.m_vertices.Next(); - } - for(size_t e = 0; e < nE; e++) - { - mesh.m_edges.GetData().m_id = e; - mesh.m_edges.Next(); - - } - for(size_t f = 0; f < nT; f++) - { - mesh.m_triangles.GetData().m_id = f; - mesh.m_triangles.Next(); - } - // copying data - m_vertices = mesh.m_vertices; - m_edges = mesh.m_edges; - m_triangles = mesh.m_triangles; - - // generating mapping - CircularListElement ** vertexMap = new CircularListElement * [nV]; - CircularListElement ** edgeMap = new CircularListElement * [nE]; - CircularListElement ** triangleMap = new CircularListElement * [nT]; - for(size_t v = 0; v < nV; v++) - { - vertexMap[v] = m_vertices.GetHead(); - m_vertices.Next(); - } - for(size_t e = 0; e < nE; e++) - { - edgeMap[e] = m_edges.GetHead(); - m_edges.Next(); - } - for(size_t f = 0; f < nT; f++) - { - triangleMap[f] = m_triangles.GetHead(); - m_triangles.Next(); - } - - // updating pointers - for(size_t v = 0; v < nV; v++) - { - if (vertexMap[v]->GetData().m_duplicate) - { - vertexMap[v]->GetData().m_duplicate = edgeMap[vertexMap[v]->GetData().m_duplicate->GetData().m_id]; - } - } - for(size_t e = 0; e < nE; e++) - { - if (edgeMap[e]->GetData().m_newFace) - { - edgeMap[e]->GetData().m_newFace = triangleMap[edgeMap[e]->GetData().m_newFace->GetData().m_id]; - } - if (nT > 0) - { - for(int f = 0; f < 2; f++) - { - if (edgeMap[e]->GetData().m_triangles[f]) - { - edgeMap[e]->GetData().m_triangles[f] = triangleMap[edgeMap[e]->GetData().m_triangles[f]->GetData().m_id]; - } - } - } - for(int v = 0; v < 2; v++) - { - if (edgeMap[e]->GetData().m_vertices[v]) - { - edgeMap[e]->GetData().m_vertices[v] = vertexMap[edgeMap[e]->GetData().m_vertices[v]->GetData().m_id]; - } - } - } - for(size_t f = 0; f < nT; f++) - { - if (nE > 0) - { - for(int e = 0; e < 3; e++) - { - if (triangleMap[f]->GetData().m_edges[e]) - { - triangleMap[f]->GetData().m_edges[e] = edgeMap[triangleMap[f]->GetData().m_edges[e]->GetData().m_id]; - } - } - } - for(int v = 0; v < 3; v++) - { - if (triangleMap[f]->GetData().m_vertices[v]) - { - triangleMap[f]->GetData().m_vertices[v] = vertexMap[triangleMap[f]->GetData().m_vertices[v]->GetData().m_id]; - } - } - } - delete [] vertexMap; - delete [] edgeMap; - delete [] triangleMap; - - } - long IntersectRayTriangle(const Vec3 & P0, const Vec3 & dir, - const Vec3 & V0, const Vec3 & V1, - const Vec3 & V2, double &t) + for (size_t v = 0; v < nV; v++) { - Vec3 edge1, edge2, edge3; - double det, invDet; - edge1 = V1 - V2; - edge2 = V2 - V0; - Vec3 pvec = dir ^ edge2; - det = edge1 * pvec; - if (det == 0.0) - return 0; - invDet = 1.0/det; - Vec3 tvec = P0 - V0; - Vec3 qvec = tvec ^ edge1; - t = (edge2 * qvec) * invDet; - if (t < 0.0) - { - return 0; - } - edge3 = V0 - V1; - Vec3 I(P0 + t * dir); - Vec3 s0 = (I-V0) ^ edge3; - Vec3 s1 = (I-V1) ^ edge1; - Vec3 s2 = (I-V2) ^ edge2; - if (s0*s1 > -1e-9 && s2*s1 > -1e-9) + points[v] = m_vertices.GetData().m_pos; + m_vertices.GetData().m_id = v; + m_vertices.Next(); + } + for (size_t f = 0; f < nT; f++) + { + TMMTriangle ¤tTriangle = m_triangles.GetData(); + triangles[f].X() = static_cast(currentTriangle.m_vertices[0]->GetData().m_id); + triangles[f].Y() = static_cast(currentTriangle.m_vertices[1]->GetData().m_id); + triangles[f].Z() = static_cast(currentTriangle.m_vertices[2]->GetData().m_id); + m_triangles.Next(); + } +} +void TMMesh::Clear() +{ + m_vertices.Clear(); + m_edges.Clear(); + m_triangles.Clear(); +} +void TMMesh::Copy(TMMesh &mesh) +{ + Clear(); + // updating the id's + size_t nV = mesh.m_vertices.GetSize(); + size_t nE = mesh.m_edges.GetSize(); + size_t nT = mesh.m_triangles.GetSize(); + for (size_t v = 0; v < nV; v++) + { + mesh.m_vertices.GetData().m_id = v; + mesh.m_vertices.Next(); + } + for (size_t e = 0; e < nE; e++) + { + mesh.m_edges.GetData().m_id = e; + mesh.m_edges.Next(); + } + for (size_t f = 0; f < nT; f++) + { + mesh.m_triangles.GetData().m_id = f; + mesh.m_triangles.Next(); + } + // copying data + m_vertices = mesh.m_vertices; + m_edges = mesh.m_edges; + m_triangles = mesh.m_triangles; + + // generating mapping + CircularListElement **vertexMap = new CircularListElement *[nV]; + CircularListElement **edgeMap = new CircularListElement *[nE]; + CircularListElement **triangleMap = new CircularListElement *[nT]; + for (size_t v = 0; v < nV; v++) + { + vertexMap[v] = m_vertices.GetHead(); + m_vertices.Next(); + } + for (size_t e = 0; e < nE; e++) + { + edgeMap[e] = m_edges.GetHead(); + m_edges.Next(); + } + for (size_t f = 0; f < nT; f++) + { + triangleMap[f] = m_triangles.GetHead(); + m_triangles.Next(); + } + + // updating pointers + for (size_t v = 0; v < nV; v++) + { + if (vertexMap[v]->GetData().m_duplicate) { - return 1; + vertexMap[v]->GetData().m_duplicate = edgeMap[vertexMap[v]->GetData().m_duplicate->GetData().m_id]; } + } + for (size_t e = 0; e < nE; e++) + { + if (edgeMap[e]->GetData().m_newFace) + { + edgeMap[e]->GetData().m_newFace = triangleMap[edgeMap[e]->GetData().m_newFace->GetData().m_id]; + } + if (nT > 0) + { + for (int f = 0; f < 2; f++) + { + if (edgeMap[e]->GetData().m_triangles[f]) + { + edgeMap[e]->GetData().m_triangles[f] = triangleMap[edgeMap[e]->GetData().m_triangles[f]->GetData().m_id]; + } + } + } + for (int v = 0; v < 2; v++) + { + if (edgeMap[e]->GetData().m_vertices[v]) + { + edgeMap[e]->GetData().m_vertices[v] = vertexMap[edgeMap[e]->GetData().m_vertices[v]->GetData().m_id]; + } + } + } + for (size_t f = 0; f < nT; f++) + { + if (nE > 0) + { + for (int e = 0; e < 3; e++) + { + if (triangleMap[f]->GetData().m_edges[e]) + { + triangleMap[f]->GetData().m_edges[e] = edgeMap[triangleMap[f]->GetData().m_edges[e]->GetData().m_id]; + } + } + } + for (int v = 0; v < 3; v++) + { + if (triangleMap[f]->GetData().m_vertices[v]) + { + triangleMap[f]->GetData().m_vertices[v] = vertexMap[triangleMap[f]->GetData().m_vertices[v]->GetData().m_id]; + } + } + } + delete[] vertexMap; + delete[] edgeMap; + delete[] triangleMap; +} +long IntersectRayTriangle(const Vec3 &P0, const Vec3 &dir, + const Vec3 &V0, const Vec3 &V1, + const Vec3 &V2, double &t) +{ + Vec3 edge1, edge2, edge3; + double det, invDet; + edge1 = V1 - V2; + edge2 = V2 - V0; + Vec3 pvec = dir ^ edge2; + det = edge1 * pvec; + if (det == 0.0) + return 0; + invDet = 1.0 / det; + Vec3 tvec = P0 - V0; + Vec3 qvec = tvec ^ edge1; + t = (edge2 * qvec) * invDet; + if (t < 0.0) + { return 0; } - - bool IntersectLineLine(const Vec3 & p1, const Vec3 & p2, - const Vec3 & p3, const Vec3 & p4, - Vec3 & pa, Vec3 & pb, - double & mua, double & mub) - { - Vec3 p13,p43,p21; - double d1343,d4321,d1321,d4343,d2121; - double numer,denom; - - p13.X() = p1.X() - p3.X(); - p13.Y() = p1.Y() - p3.Y(); - p13.Z() = p1.Z() - p3.Z(); - p43.X() = p4.X() - p3.X(); - p43.Y() = p4.Y() - p3.Y(); - p43.Z() = p4.Z() - p3.Z(); - if (p43.X()==0.0 && p43.Y()==0.0 && p43.Z()==0.0) - return false; - p21.X() = p2.X() - p1.X(); - p21.Y() = p2.Y() - p1.Y(); - p21.Z() = p2.Z() - p1.Z(); - if (p21.X()==0.0 && p21.Y()==0.0 && p21.Z()==0.0) - return false; - - d1343 = p13.X() * p43.X() + p13.Y() * p43.Y() + p13.Z() * p43.Z(); - d4321 = p43.X() * p21.X() + p43.Y() * p21.Y() + p43.Z() * p21.Z(); - d1321 = p13.X() * p21.X() + p13.Y() * p21.Y() + p13.Z() * p21.Z(); - d4343 = p43.X() * p43.X() + p43.Y() * p43.Y() + p43.Z() * p43.Z(); - d2121 = p21.X() * p21.X() + p21.Y() * p21.Y() + p21.Z() * p21.Z(); - - denom = d2121 * d4343 - d4321 * d4321; - if (denom==0.0) - return false; - numer = d1343 * d4321 - d1321 * d4343; - - mua = numer / denom; - mub = (d1343 + d4321 * (mua)) / d4343; - - pa.X() = p1.X() + mua * p21.X(); - pa.Y() = p1.Y() + mua * p21.Y(); - pa.Z() = p1.Z() + mua * p21.Z(); - pb.X() = p3.X() + mub * p43.X(); - pb.Y() = p3.Y() + mub * p43.Y(); - pb.Z() = p3.Z() + mub * p43.Z(); - - return true; - } - - long IntersectRayTriangle2(const Vec3 & P0, const Vec3 & dir, - const Vec3 & V0, const Vec3 & V1, - const Vec3 & V2, double &r) + edge3 = V0 - V1; + Vec3 I(P0 + t * dir); + Vec3 s0 = (I - V0) ^ edge3; + Vec3 s1 = (I - V1) ^ edge1; + Vec3 s2 = (I - V2) ^ edge2; + if (s0 * s1 > -1e-9 && s2 * s1 > -1e-9) { - Vec3 u, v, n; // triangle vectors - Vec3 w0, w; // ray vectors - double a, b; // params to calc ray-plane intersect - - // get triangle edge vectors and plane normal - u = V1 - V0; - v = V2 - V0; - n = u ^ v; // cross product - if (n.GetNorm() == 0.0) // triangle is degenerate - return -1; // do not deal with this case - - w0 = P0 - V0; - a = - n * w0; - b = n * dir; - if (fabs(b) <= 0.0) { // ray is parallel to triangle plane - if (a == 0.0) // ray lies in triangle plane - return 2; - else return 0; // ray disjoint from plane - } - - // get intersect point of ray with triangle plane - r = a / b; - if (r < 0.0) // ray goes away from triangle - return 0; // => no intersect - // for a segment, also test if (r > 1.0) => no intersect - - Vec3 I = P0 + r * dir; // intersect point of ray and plane - - // is I inside T? - double uu, uv, vv, wu, wv, D; - uu = u * u; - uv = u * v; - vv = v * v; - w = I - V0; - wu = w * u; - wv = w * v; - D = uv * uv - uu * vv; - - // get and test parametric coords - double s, t; - s = (uv * wv - vv * wu) / D; - if (s < 0.0 || s > 1.0) // I is outside T - return 0; - t = (uv * wu - uu * wv) / D; - if (t < 0.0 || (s + t) > 1.0) // I is outside T - return 0; - return 1; // I is in T + return 1; } - - - bool TMMesh::CheckConsistancy() - { - size_t nE = m_edges.GetSize(); - size_t nT = m_triangles.GetSize(); - for(size_t e = 0; e < nE; e++) - { - for(int f = 0; f < 2; f++) - { - if (!m_edges.GetHead()->GetData().m_triangles[f]) - { - return false; - } - } - m_edges.Next(); - } + return 0; +} - for(size_t f = 0; f < nT; f++) - { - for(int e = 0; e < 3; e++) - { - int found = 0; - for(int k = 0; k < 2; k++) - { - if (m_triangles.GetHead()->GetData().m_edges[e]->GetData().m_triangles[k] == m_triangles.GetHead()) - { - found++; - } - } - if (found != 1) - { - return false; - } - } - m_triangles.Next(); - } +bool IntersectLineLine(const Vec3 &p1, const Vec3 &p2, + const Vec3 &p3, const Vec3 &p4, + Vec3 &pa, Vec3 &pb, + double &mua, double &mub) +{ + Vec3 p13, p43, p21; + double d1343, d4321, d1321, d4343, d2121; + double numer, denom; - return true; - } - bool TMMesh::Normalize() - { - size_t nV = m_vertices.GetSize(); - if (nV == 0) - { - return false; - } - m_barycenter = m_vertices.GetHead()->GetData().m_pos; - Vec3 min = m_barycenter; - Vec3 max = m_barycenter; - Real x, y, z; - for(size_t v = 1; v < nV; v++) - { - m_barycenter += m_vertices.GetHead()->GetData().m_pos; - x = m_vertices.GetHead()->GetData().m_pos.X(); - y = m_vertices.GetHead()->GetData().m_pos.Y(); - z = m_vertices.GetHead()->GetData().m_pos.Z(); - if ( x < min.X()) min.X() = x; - else if ( x > max.X()) max.X() = x; - if ( y < min.Y()) min.Y() = y; - else if ( y > max.Y()) max.Y() = y; - if ( z < min.Z()) min.Z() = z; - else if ( z > max.Z()) max.Z() = z; - m_vertices.Next(); - } - m_barycenter /= static_cast(nV); - m_diag = static_cast(0.001 * (max-min).GetNorm()); - const Real invDiag = static_cast(1.0 / m_diag); - if (m_diag != 0.0) - { - for(size_t v = 0; v < nV; v++) - { - m_vertices.GetHead()->GetData().m_pos = (m_vertices.GetHead()->GetData().m_pos - m_barycenter) * invDiag; - m_vertices.Next(); - } - } - return true; + p13.X() = p1.X() - p3.X(); + p13.Y() = p1.Y() - p3.Y(); + p13.Z() = p1.Z() - p3.Z(); + p43.X() = p4.X() - p3.X(); + p43.Y() = p4.Y() - p3.Y(); + p43.Z() = p4.Z() - p3.Z(); + if (p43.X() == 0.0 && p43.Y() == 0.0 && p43.Z() == 0.0) + return false; + p21.X() = p2.X() - p1.X(); + p21.Y() = p2.Y() - p1.Y(); + p21.Z() = p2.Z() - p1.Z(); + if (p21.X() == 0.0 && p21.Y() == 0.0 && p21.Z() == 0.0) + return false; + + d1343 = p13.X() * p43.X() + p13.Y() * p43.Y() + p13.Z() * p43.Z(); + d4321 = p43.X() * p21.X() + p43.Y() * p21.Y() + p43.Z() * p21.Z(); + d1321 = p13.X() * p21.X() + p13.Y() * p21.Y() + p13.Z() * p21.Z(); + d4343 = p43.X() * p43.X() + p43.Y() * p43.Y() + p43.Z() * p43.Z(); + d2121 = p21.X() * p21.X() + p21.Y() * p21.Y() + p21.Z() * p21.Z(); + + denom = d2121 * d4343 - d4321 * d4321; + if (denom == 0.0) + return false; + numer = d1343 * d4321 - d1321 * d4343; + + mua = numer / denom; + mub = (d1343 + d4321 * (mua)) / d4343; + + pa.X() = p1.X() + mua * p21.X(); + pa.Y() = p1.Y() + mua * p21.Y(); + pa.Z() = p1.Z() + mua * p21.Z(); + pb.X() = p3.X() + mub * p43.X(); + pb.Y() = p3.Y() + mub * p43.Y(); + pb.Z() = p3.Z() + mub * p43.Z(); + + return true; +} + +long IntersectRayTriangle2(const Vec3 &P0, const Vec3 &dir, + const Vec3 &V0, const Vec3 &V1, + const Vec3 &V2, double &r) +{ + Vec3 u, v, n; // triangle vectors + Vec3 w0, w; // ray vectors + double a, b; // params to calc ray-plane intersect + + // get triangle edge vectors and plane normal + u = V1 - V0; + v = V2 - V0; + n = u ^ v; // cross product + if (n.GetNorm() == 0.0) // triangle is degenerate + return -1; // do not deal with this case + + w0 = P0 - V0; + a = -n * w0; + b = n * dir; + if (fabs(b) <= 0.0) + { // ray is parallel to triangle plane + if (a == 0.0) // ray lies in triangle plane + return 2; + else + return 0; // ray disjoint from plane } - bool TMMesh::Denormalize() + + // get intersect point of ray with triangle plane + r = a / b; + if (r < 0.0) // ray goes away from triangle + return 0; // => no intersect + // for a segment, also test if (r > 1.0) => no intersect + + Vec3 I = P0 + r * dir; // intersect point of ray and plane + + // is I inside T? + double uu, uv, vv, wu, wv, D; + uu = u * u; + uv = u * v; + vv = v * v; + w = I - V0; + wu = w * u; + wv = w * v; + D = uv * uv - uu * vv; + + // get and test parametric coords + double s, t; + s = (uv * wv - vv * wu) / D; + if (s < 0.0 || s > 1.0) // I is outside T + return 0; + t = (uv * wu - uu * wv) / D; + if (t < 0.0 || (s + t) > 1.0) // I is outside T + return 0; + return 1; // I is in T +} + +bool TMMesh::CheckConsistancy() +{ + size_t nE = m_edges.GetSize(); + size_t nT = m_triangles.GetSize(); + for (size_t e = 0; e < nE; e++) { - size_t nV = m_vertices.GetSize(); - if (nV == 0) + for (int f = 0; f < 2; f++) { - return false; - } - if (m_diag != 0.0) - { - for(size_t v = 0; v < nV; v++) - { - m_vertices.GetHead()->GetData().m_pos = m_vertices.GetHead()->GetData().m_pos * m_diag + m_barycenter; - m_vertices.Next(); + if (!m_edges.GetHead()->GetData().m_triangles[f]) + { + return false; } } - return false; - } + m_edges.Next(); + } + + for (size_t f = 0; f < nT; f++) + { + for (int e = 0; e < 3; e++) + { + int found = 0; + for (int k = 0; k < 2; k++) + { + if (m_triangles.GetHead()->GetData().m_edges[e]->GetData().m_triangles[k] == m_triangles.GetHead()) + { + found++; + } + } + if (found != 1) + { + return false; + } + } + m_triangles.Next(); + } + + return true; } +bool TMMesh::Normalize() +{ + size_t nV = m_vertices.GetSize(); + if (nV == 0) + { + return false; + } + m_barycenter = m_vertices.GetHead()->GetData().m_pos; + Vec3 min = m_barycenter; + Vec3 max = m_barycenter; + Real x, y, z; + for (size_t v = 1; v < nV; v++) + { + m_barycenter += m_vertices.GetHead()->GetData().m_pos; + x = m_vertices.GetHead()->GetData().m_pos.X(); + y = m_vertices.GetHead()->GetData().m_pos.Y(); + z = m_vertices.GetHead()->GetData().m_pos.Z(); + if (x < min.X()) + min.X() = x; + else if (x > max.X()) + max.X() = x; + if (y < min.Y()) + min.Y() = y; + else if (y > max.Y()) + max.Y() = y; + if (z < min.Z()) + min.Z() = z; + else if (z > max.Z()) + max.Z() = z; + m_vertices.Next(); + } + m_barycenter /= static_cast(nV); + m_diag = static_cast(0.001 * (max - min).GetNorm()); + const Real invDiag = static_cast(1.0 / m_diag); + if (m_diag != 0.0) + { + for (size_t v = 0; v < nV; v++) + { + m_vertices.GetHead()->GetData().m_pos = (m_vertices.GetHead()->GetData().m_pos - m_barycenter) * invDiag; + m_vertices.Next(); + } + } + return true; +} +bool TMMesh::Denormalize() +{ + size_t nV = m_vertices.GetSize(); + if (nV == 0) + { + return false; + } + if (m_diag != 0.0) + { + for (size_t v = 0; v < nV; v++) + { + m_vertices.GetHead()->GetData().m_pos = m_vertices.GetHead()->GetData().m_pos * m_diag + m_barycenter; + m_vertices.Next(); + } + } + return false; +} +} // namespace HACD diff --git a/Extras/HACD/hacdManifoldMesh.h b/Extras/HACD/hacdManifoldMesh.h index 318ecbab6..1d2291870 100644 --- a/Extras/HACD/hacdManifoldMesh.h +++ b/Extras/HACD/hacdManifoldMesh.h @@ -38,213 +38,214 @@ All rights reserved. #include namespace HACD { - class TMMTriangle; - class TMMEdge; - class TMMesh; - class ICHull; - class HACD; +class TMMTriangle; +class TMMEdge; +class TMMesh; +class ICHull; +class HACD; - class DPoint - { - public: - DPoint(Real dist=0, bool computed=false, bool distOnly=false) - :m_dist(dist), - m_computed(computed), - m_distOnly(distOnly){}; - ~DPoint(){}; - private: - Real m_dist; - bool m_computed; - bool m_distOnly; - friend class TMMTriangle; - friend class TMMesh; - friend class GraphVertex; - friend class GraphEdge; - friend class Graph; - friend class ICHull; - friend class HACD; - }; +class DPoint +{ +public: + DPoint(Real dist = 0, bool computed = false, bool distOnly = false) + : m_dist(dist), + m_computed(computed), + m_distOnly(distOnly){}; + ~DPoint(){}; - //! Vertex data structure used in a triangular manifold mesh (TMM). - class TMMVertex - { - public: - TMMVertex(void); - ~TMMVertex(void); - - private: - Vec3 m_pos; - long m_name; - size_t m_id; - CircularListElement * m_duplicate; // pointer to incident cone edge (or NULL) - bool m_onHull; - bool m_tag; - TMMVertex(const TMMVertex & rhs); - - friend class HACD; - friend class ICHull; - friend class TMMesh; - friend class TMMTriangle; - friend class TMMEdge; - }; +private: + Real m_dist; + bool m_computed; + bool m_distOnly; + friend class TMMTriangle; + friend class TMMesh; + friend class GraphVertex; + friend class GraphEdge; + friend class Graph; + friend class ICHull; + friend class HACD; +}; - //! Edge data structure used in a triangular manifold mesh (TMM). - class TMMEdge - { - public: - TMMEdge(void); - ~TMMEdge(void); - private: - size_t m_id; - CircularListElement * m_triangles[2]; - CircularListElement * m_vertices[2]; - CircularListElement * m_newFace; +//! Vertex data structure used in a triangular manifold mesh (TMM). +class TMMVertex +{ +public: + TMMVertex(void); + ~TMMVertex(void); +private: + Vec3 m_pos; + long m_name; + size_t m_id; + CircularListElement *m_duplicate; // pointer to incident cone edge (or NULL) + bool m_onHull; + bool m_tag; + TMMVertex(const TMMVertex &rhs); - TMMEdge(const TMMEdge & rhs); - - friend class HACD; - friend class ICHull; - friend class TMMTriangle; - friend class TMMVertex; - friend class TMMesh; - }; + friend class HACD; + friend class ICHull; + friend class TMMesh; + friend class TMMTriangle; + friend class TMMEdge; +}; - //! Triangle data structure used in a triangular manifold mesh (TMM). - class TMMTriangle - { - public: - TMMTriangle(void); - ~TMMTriangle(void); - private: - size_t m_id; - CircularListElement * m_edges[3]; - CircularListElement * m_vertices[3]; - std::set m_incidentPoints; - bool m_visible; - - TMMTriangle(const TMMTriangle & rhs); - - friend class HACD; - friend class ICHull; - friend class TMMesh; - friend class TMMVertex; - friend class TMMEdge; - }; - - class Material - { - public: - Material(void); - ~Material(void){} -// private: - Vec3 m_diffuseColor; - double m_ambientIntensity; - Vec3 m_specularColor; - Vec3 m_emissiveColor; - double m_shininess; - double m_transparency; - - friend class TMMesh; - friend class HACD; - }; +//! Edge data structure used in a triangular manifold mesh (TMM). +class TMMEdge +{ +public: + TMMEdge(void); + ~TMMEdge(void); - //! triangular manifold mesh data structure. - class TMMesh - { - public: +private: + size_t m_id; + CircularListElement *m_triangles[2]; + CircularListElement *m_vertices[2]; + CircularListElement *m_newFace; - //! Returns the number of vertices> - inline size_t GetNVertices() const { return m_vertices.GetSize();} - //! Returns the number of edges - inline size_t GetNEdges() const { return m_edges.GetSize();} - //! Returns the number of triangles - inline size_t GetNTriangles() const { return m_triangles.GetSize();} - //! Returns the vertices circular list - inline const CircularList & GetVertices() const { return m_vertices;} - //! Returns the edges circular list - inline const CircularList & GetEdges() const { return m_edges;} - //! Returns the triangles circular list - inline const CircularList & GetTriangles() const { return m_triangles;} - //! Returns the vertices circular list - inline CircularList & GetVertices() { return m_vertices;} - //! Returns the edges circular list - inline CircularList & GetEdges() { return m_edges;} - //! Returns the triangles circular list - inline CircularList & GetTriangles() { return m_triangles;} - //! Add vertex to the mesh - CircularListElement * AddVertex() {return m_vertices.Add();} - //! Add vertex to the mesh - CircularListElement * AddEdge() {return m_edges.Add();} - //! Add vertex to the mesh - CircularListElement * AddTriangle() {return m_triangles.Add();} - //! Print mesh information - void Print(); - //! - void GetIFS(Vec3 * const points, Vec3 * const triangles); - //! Save mesh - bool Save(const char *fileName); - //! Save mesh to VRML 2.0 format - bool SaveVRML2(std::ofstream &fout); - //! Save mesh to VRML 2.0 format - bool SaveVRML2(std::ofstream &fout, const Material & material); - //! - void Clear(); - //! - void Copy(TMMesh & mesh); - //! - bool CheckConsistancy(); - //! - bool Normalize(); - //! - bool Denormalize(); - //! Constructor - TMMesh(void); - //! Destructor - virtual ~TMMesh(void); + TMMEdge(const TMMEdge &rhs); - private: - CircularList m_vertices; - CircularList m_edges; - CircularList m_triangles; - Real m_diag; //>! length of the BB diagonal - Vec3 m_barycenter; //>! barycenter of the mesh + friend class HACD; + friend class ICHull; + friend class TMMTriangle; + friend class TMMVertex; + friend class TMMesh; +}; - // not defined - TMMesh(const TMMesh & rhs); - friend class ICHull; - friend class HACD; - }; - //! IntersectRayTriangle(): intersect a ray with a 3D triangle - //! Input: a ray R, and a triangle T - //! Output: *I = intersection point (when it exists) - //! 0 = disjoint (no intersect) - //! 1 = intersect in unique point I1 - long IntersectRayTriangle( const Vec3 & P0, const Vec3 & dir, - const Vec3 & V0, const Vec3 & V1, - const Vec3 & V2, double &t); +//! Triangle data structure used in a triangular manifold mesh (TMM). +class TMMTriangle +{ +public: + TMMTriangle(void); + ~TMMTriangle(void); - // intersect_RayTriangle(): intersect a ray with a 3D triangle - // Input: a ray R, and a triangle T - // Output: *I = intersection point (when it exists) - // Return: -1 = triangle is degenerate (a segment or point) - // 0 = disjoint (no intersect) - // 1 = intersect in unique point I1 - // 2 = are in the same plane - long IntersectRayTriangle2(const Vec3 & P0, const Vec3 & dir, - const Vec3 & V0, const Vec3 & V1, - const Vec3 & V2, double &r); +private: + size_t m_id; + CircularListElement *m_edges[3]; + CircularListElement *m_vertices[3]; + std::set m_incidentPoints; + bool m_visible; - /* + TMMTriangle(const TMMTriangle &rhs); + + friend class HACD; + friend class ICHull; + friend class TMMesh; + friend class TMMVertex; + friend class TMMEdge; +}; + +class Material +{ +public: + Material(void); + ~Material(void) {} + // private: + Vec3 m_diffuseColor; + double m_ambientIntensity; + Vec3 m_specularColor; + Vec3 m_emissiveColor; + double m_shininess; + double m_transparency; + + friend class TMMesh; + friend class HACD; +}; + +//! triangular manifold mesh data structure. +class TMMesh +{ +public: + //! Returns the number of vertices> + inline size_t GetNVertices() const { return m_vertices.GetSize(); } + //! Returns the number of edges + inline size_t GetNEdges() const { return m_edges.GetSize(); } + //! Returns the number of triangles + inline size_t GetNTriangles() const { return m_triangles.GetSize(); } + //! Returns the vertices circular list + inline const CircularList &GetVertices() const { return m_vertices; } + //! Returns the edges circular list + inline const CircularList &GetEdges() const { return m_edges; } + //! Returns the triangles circular list + inline const CircularList &GetTriangles() const { return m_triangles; } + //! Returns the vertices circular list + inline CircularList &GetVertices() { return m_vertices; } + //! Returns the edges circular list + inline CircularList &GetEdges() { return m_edges; } + //! Returns the triangles circular list + inline CircularList &GetTriangles() { return m_triangles; } + //! Add vertex to the mesh + CircularListElement *AddVertex() { return m_vertices.Add(); } + //! Add vertex to the mesh + CircularListElement *AddEdge() { return m_edges.Add(); } + //! Add vertex to the mesh + CircularListElement *AddTriangle() { return m_triangles.Add(); } + //! Print mesh information + void Print(); + //! + void GetIFS(Vec3 *const points, Vec3 *const triangles); + //! Save mesh + bool Save(const char *fileName); + //! Save mesh to VRML 2.0 format + bool SaveVRML2(std::ofstream &fout); + //! Save mesh to VRML 2.0 format + bool SaveVRML2(std::ofstream &fout, const Material &material); + //! + void Clear(); + //! + void Copy(TMMesh &mesh); + //! + bool CheckConsistancy(); + //! + bool Normalize(); + //! + bool Denormalize(); + //! Constructor + TMMesh(void); + //! Destructor + virtual ~TMMesh(void); + +private: + CircularList m_vertices; + CircularList m_edges; + CircularList m_triangles; + Real m_diag; //>! length of the BB diagonal + Vec3 m_barycenter; //>! barycenter of the mesh + + // not defined + TMMesh(const TMMesh &rhs); + friend class ICHull; + friend class HACD; +}; +//! IntersectRayTriangle(): intersect a ray with a 3D triangle +//! Input: a ray R, and a triangle T +//! Output: *I = intersection point (when it exists) +//! 0 = disjoint (no intersect) +//! 1 = intersect in unique point I1 +long IntersectRayTriangle(const Vec3 &P0, const Vec3 &dir, + const Vec3 &V0, const Vec3 &V1, + const Vec3 &V2, double &t); + +// intersect_RayTriangle(): intersect a ray with a 3D triangle +// Input: a ray R, and a triangle T +// Output: *I = intersection point (when it exists) +// Return: -1 = triangle is degenerate (a segment or point) +// 0 = disjoint (no intersect) +// 1 = intersect in unique point I1 +// 2 = are in the same plane +long IntersectRayTriangle2(const Vec3 &P0, const Vec3 &dir, + const Vec3 &V0, const Vec3 &V1, + const Vec3 &V2, double &r); + +/* Calculate the line segment PaPb that is the shortest route between two lines P1P2 and P3P4. Calculate also the values of mua and mub where Pa = P1 + mua (P2 - P1) Pb = P3 + mub (P4 - P3) Return FALSE if no solution exists. */ - bool IntersectLineLine(const Vec3 & p1, const Vec3 & p2, - const Vec3 & p3, const Vec3 & p4, - Vec3 & pa, Vec3 & pb, - double & mua, double &mub); -} +bool IntersectLineLine(const Vec3 &p1, const Vec3 &p2, + const Vec3 &p3, const Vec3 &p4, + Vec3 &pa, Vec3 &pb, + double &mua, double &mub); +} // namespace HACD #endif diff --git a/Extras/HACD/hacdVector.h b/Extras/HACD/hacdVector.h index bb0858ba5..778e04a39 100644 --- a/Extras/HACD/hacdVector.h +++ b/Extras/HACD/hacdVector.h @@ -15,53 +15,54 @@ #pragma once #ifndef HACD_VECTOR_H #define HACD_VECTOR_H -#include -#include +#include +#include #include "hacdVersion.h" namespace HACD { - typedef double Real; - //! Vector dim 3. - template < typename T > class Vec3 - { - public: - T & X(); - T & Y(); - T & Z(); - const T & X() const; - const T & Y() const; - const T & Z() const; - void Normalize(); - T GetNorm() const; - void operator= (const Vec3 & rhs); - void operator+=(const Vec3 & rhs); - void operator-=(const Vec3 & rhs); - void operator-=(T a); - void operator+=(T a); - void operator/=(T a); - void operator*=(T a); - Vec3 operator^ (const Vec3 & rhs) const; - T operator* (const Vec3 & rhs) const; - Vec3 operator+ (const Vec3 & rhs) const; - Vec3 operator- (const Vec3 & rhs) const; - Vec3 operator- () const; - Vec3 operator* (T rhs) const; - Vec3 operator/ (T rhs) const; - Vec3(); - Vec3(T a); - Vec3(T x, T y, T z); - Vec3(const Vec3 & rhs); - /*virtual*/ ~Vec3(void); +typedef double Real; +//! Vector dim 3. +template +class Vec3 +{ +public: + T& X(); + T& Y(); + T& Z(); + const T& X() const; + const T& Y() const; + const T& Z() const; + void Normalize(); + T GetNorm() const; + void operator=(const Vec3& rhs); + void operator+=(const Vec3& rhs); + void operator-=(const Vec3& rhs); + void operator-=(T a); + void operator+=(T a); + void operator/=(T a); + void operator*=(T a); + Vec3 operator^(const Vec3& rhs) const; + T operator*(const Vec3& rhs) const; + Vec3 operator+(const Vec3& rhs) const; + Vec3 operator-(const Vec3& rhs) const; + Vec3 operator-() const; + Vec3 operator*(T rhs) const; + Vec3 operator/(T rhs) const; + Vec3(); + Vec3(T a); + Vec3(T x, T y, T z); + Vec3(const Vec3& rhs); + /*virtual*/ ~Vec3(void); - private: - T m_data[3]; - }; - template - bool Colinear(const Vec3 & a, const Vec3 & b, const Vec3 & c); - template - const T Volume(const Vec3 & a, const Vec3 & b, const Vec3 & c, const Vec3 & d); - -} -#include "hacdVector.inl" // template implementation +private: + T m_data[3]; +}; +template +bool Colinear(const Vec3& a, const Vec3& b, const Vec3& c); +template +const T Volume(const Vec3& a, const Vec3& b, const Vec3& c, const Vec3& d); + +} // namespace HACD +#include "hacdVector.inl" // template implementation #endif diff --git a/Extras/InverseDynamics/BulletInverseDynamicsUtilsCommon.h b/Extras/InverseDynamics/BulletInverseDynamicsUtilsCommon.h index 25e77cda6..87a0897fd 100644 --- a/Extras/InverseDynamics/BulletInverseDynamicsUtilsCommon.h +++ b/Extras/InverseDynamics/BulletInverseDynamicsUtilsCommon.h @@ -12,6 +12,4 @@ #include "MultiBodyNameMap.hpp" #include "User2InternalIndex.hpp" -#endif//BULLET_INVERSE_DYNAMICS_UTILS_COMMON_H - - +#endif //BULLET_INVERSE_DYNAMICS_UTILS_COMMON_H diff --git a/Extras/InverseDynamics/CloneTreeCreator.cpp b/Extras/InverseDynamics/CloneTreeCreator.cpp index d267282a4..4f56f3c66 100644 --- a/Extras/InverseDynamics/CloneTreeCreator.cpp +++ b/Extras/InverseDynamics/CloneTreeCreator.cpp @@ -2,48 +2,58 @@ #include -namespace btInverseDynamics { -#define CHECK_NULLPTR() \ - do { \ - if (m_reference == 0x0) { \ - bt_id_error_message("m_reference == 0x0\n"); \ - return -1; \ - } \ - } while (0) +namespace btInverseDynamics +{ +#define CHECK_NULLPTR() \ + do \ + { \ + if (m_reference == 0x0) \ + { \ + bt_id_error_message("m_reference == 0x0\n"); \ + return -1; \ + } \ + } while (0) -#define TRY(x) \ - do { \ - if (x == -1) { \ - bt_id_error_message("error calling " #x "\n"); \ - return -1; \ - } \ - } while (0) -CloneTreeCreator::CloneTreeCreator(const MultiBodyTree* reference) { m_reference = reference; } +#define TRY(x) \ + do \ + { \ + if (x == -1) \ + { \ + bt_id_error_message("error calling " #x "\n"); \ + return -1; \ + } \ + } while (0) +CloneTreeCreator::CloneTreeCreator(const MultiBodyTree* reference) +{ + m_reference = reference; +} CloneTreeCreator::~CloneTreeCreator() {} -int CloneTreeCreator::getNumBodies(int* num_bodies) const { - CHECK_NULLPTR(); - *num_bodies = m_reference->numBodies(); - return 0; +int CloneTreeCreator::getNumBodies(int* num_bodies) const +{ + CHECK_NULLPTR(); + *num_bodies = m_reference->numBodies(); + return 0; } int CloneTreeCreator::getBody(const int body_index, int* parent_index, JointType* joint_type, - vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, - vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com, - mat33* body_I_body, int* user_int, void** user_ptr) const { - CHECK_NULLPTR(); - TRY(m_reference->getParentIndex(body_index, parent_index)); - TRY(m_reference->getJointType(body_index, joint_type)); - TRY(m_reference->getParentRParentBodyRef(body_index, parent_r_parent_body_ref)); - TRY(m_reference->getBodyTParentRef(body_index, body_T_parent_ref)); - TRY(m_reference->getBodyAxisOfMotion(body_index, body_axis_of_motion)); - TRY(m_reference->getBodyMass(body_index, mass)); - TRY(m_reference->getBodyFirstMassMoment(body_index, body_r_body_com)); - TRY(m_reference->getBodySecondMassMoment(body_index, body_I_body)); - TRY(m_reference->getUserInt(body_index, user_int)); - TRY(m_reference->getUserPtr(body_index, user_ptr)); + vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, + vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com, + mat33* body_I_body, int* user_int, void** user_ptr) const +{ + CHECK_NULLPTR(); + TRY(m_reference->getParentIndex(body_index, parent_index)); + TRY(m_reference->getJointType(body_index, joint_type)); + TRY(m_reference->getParentRParentBodyRef(body_index, parent_r_parent_body_ref)); + TRY(m_reference->getBodyTParentRef(body_index, body_T_parent_ref)); + TRY(m_reference->getBodyAxisOfMotion(body_index, body_axis_of_motion)); + TRY(m_reference->getBodyMass(body_index, mass)); + TRY(m_reference->getBodyFirstMassMoment(body_index, body_r_body_com)); + TRY(m_reference->getBodySecondMassMoment(body_index, body_I_body)); + TRY(m_reference->getUserInt(body_index, user_int)); + TRY(m_reference->getUserPtr(body_index, user_ptr)); - return 0; -} + return 0; } +} // namespace btInverseDynamics diff --git a/Extras/InverseDynamics/CloneTreeCreator.hpp b/Extras/InverseDynamics/CloneTreeCreator.hpp index cb96d56b4..c40cce351 100644 --- a/Extras/InverseDynamics/CloneTreeCreator.hpp +++ b/Extras/InverseDynamics/CloneTreeCreator.hpp @@ -4,24 +4,26 @@ #include "BulletInverseDynamics/IDConfig.hpp" #include "MultiBodyTreeCreator.hpp" -namespace btInverseDynamics { +namespace btInverseDynamics +{ /// Generate an identical multibody tree from a reference system. -class CloneTreeCreator : public MultiBodyTreeCreator { +class CloneTreeCreator : public MultiBodyTreeCreator +{ public: - /// ctor - /// @param reference the MultiBodyTree to clone - CloneTreeCreator(const MultiBodyTree*reference); - ~CloneTreeCreator(); - ///\copydoc MultiBodyTreeCreator::getNumBodies - int getNumBodies(int* num_bodies) const; - ///\copydoc MultiBodyTreeCreator::getBody - int getBody(const int body_index, int* parent_index, JointType* joint_type, - vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, vec3* body_axis_of_motion, - idScalar* mass, vec3* body_r_body_com, mat33* body_I_body, int* user_int, - void** user_ptr) const; + /// ctor + /// @param reference the MultiBodyTree to clone + CloneTreeCreator(const MultiBodyTree* reference); + ~CloneTreeCreator(); + ///\copydoc MultiBodyTreeCreator::getNumBodies + int getNumBodies(int* num_bodies) const; + ///\copydoc MultiBodyTreeCreator::getBody + int getBody(const int body_index, int* parent_index, JointType* joint_type, + vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, vec3* body_axis_of_motion, + idScalar* mass, vec3* body_r_body_com, mat33* body_I_body, int* user_int, + void** user_ptr) const; private: - const MultiBodyTree *m_reference; + const MultiBodyTree* m_reference; }; -} +} // namespace btInverseDynamics #endif // CLONETREE_CREATOR_HPP_ diff --git a/Extras/InverseDynamics/CoilCreator.cpp b/Extras/InverseDynamics/CoilCreator.cpp index ce37a9922..627e3cc56 100644 --- a/Extras/InverseDynamics/CoilCreator.cpp +++ b/Extras/InverseDynamics/CoilCreator.cpp @@ -2,66 +2,72 @@ #include "CoilCreator.hpp" -namespace btInverseDynamics { -CoilCreator::CoilCreator(int n) : m_num_bodies(n), m_parent(n) { - for (int i = 0; i < m_num_bodies; i++) { - m_parent[i] = i - 1; - } +namespace btInverseDynamics +{ +CoilCreator::CoilCreator(int n) : m_num_bodies(n), m_parent(n) +{ + for (int i = 0; i < m_num_bodies; i++) + { + m_parent[i] = i - 1; + } - // DH parameters (that's what's in the paper ...) - const idScalar theta_DH = 0; - const idScalar d_DH = 0.0; - const idScalar a_DH = 1.0 / m_num_bodies; - const idScalar alpha_DH = 5.0 * BT_ID_PI / m_num_bodies; - getVecMatFromDH(theta_DH, d_DH, a_DH, alpha_DH, &m_parent_r_parent_body_ref, - &m_body_T_parent_ref); - // always z-axis - m_body_axis_of_motion(0) = 0.0; - m_body_axis_of_motion(1) = 0.0; - m_body_axis_of_motion(2) = 1.0; + // DH parameters (that's what's in the paper ...) + const idScalar theta_DH = 0; + const idScalar d_DH = 0.0; + const idScalar a_DH = 1.0 / m_num_bodies; + const idScalar alpha_DH = 5.0 * BT_ID_PI / m_num_bodies; + getVecMatFromDH(theta_DH, d_DH, a_DH, alpha_DH, &m_parent_r_parent_body_ref, + &m_body_T_parent_ref); + // always z-axis + m_body_axis_of_motion(0) = 0.0; + m_body_axis_of_motion(1) = 0.0; + m_body_axis_of_motion(2) = 1.0; - m_mass = 1.0 / m_num_bodies; - m_body_r_body_com(0) = 1.0 / (2.0 * m_num_bodies); - m_body_r_body_com(1) = 0.0; - m_body_r_body_com(2) = 0.0; + m_mass = 1.0 / m_num_bodies; + m_body_r_body_com(0) = 1.0 / (2.0 * m_num_bodies); + m_body_r_body_com(1) = 0.0; + m_body_r_body_com(2) = 0.0; - m_body_I_body(0, 0) = 1e-4 / (2.0 * m_num_bodies); - m_body_I_body(0, 1) = 0.0; - m_body_I_body(0, 2) = 0.0; - m_body_I_body(1, 0) = 0.0; - m_body_I_body(1, 1) = (3e-4 + 4.0 / BT_ID_POW(m_num_bodies, 2)) / (12.0 * m_num_bodies); - m_body_I_body(1, 2) = 0.0; - m_body_I_body(2, 0) = 0.0; - m_body_I_body(2, 1) = 0.0; - m_body_I_body(2, 2) = m_body_I_body(1, 1); + m_body_I_body(0, 0) = 1e-4 / (2.0 * m_num_bodies); + m_body_I_body(0, 1) = 0.0; + m_body_I_body(0, 2) = 0.0; + m_body_I_body(1, 0) = 0.0; + m_body_I_body(1, 1) = (3e-4 + 4.0 / BT_ID_POW(m_num_bodies, 2)) / (12.0 * m_num_bodies); + m_body_I_body(1, 2) = 0.0; + m_body_I_body(2, 0) = 0.0; + m_body_I_body(2, 1) = 0.0; + m_body_I_body(2, 2) = m_body_I_body(1, 1); } CoilCreator::~CoilCreator() {} -int CoilCreator::getNumBodies(int* num_bodies) const { - *num_bodies = m_num_bodies; - return 0; +int CoilCreator::getNumBodies(int* num_bodies) const +{ + *num_bodies = m_num_bodies; + return 0; } int CoilCreator::getBody(int body_index, int* parent_index, JointType* joint_type, - vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, - vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com, - mat33* body_I_body, int* user_int, void** user_ptr) const { - if (body_index < 0 || body_index >= m_num_bodies) { - bt_id_error_message("invalid body index %d\n", body_index); - return -1; - } - *parent_index = m_parent[body_index]; - *joint_type = REVOLUTE; - *parent_r_parent_body_ref = m_parent_r_parent_body_ref; - *body_T_parent_ref = m_body_T_parent_ref; - *body_axis_of_motion = m_body_axis_of_motion; - *mass = m_mass; - *body_r_body_com = m_body_r_body_com; - *body_I_body = m_body_I_body; + vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, + vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com, + mat33* body_I_body, int* user_int, void** user_ptr) const +{ + if (body_index < 0 || body_index >= m_num_bodies) + { + bt_id_error_message("invalid body index %d\n", body_index); + return -1; + } + *parent_index = m_parent[body_index]; + *joint_type = REVOLUTE; + *parent_r_parent_body_ref = m_parent_r_parent_body_ref; + *body_T_parent_ref = m_body_T_parent_ref; + *body_axis_of_motion = m_body_axis_of_motion; + *mass = m_mass; + *body_r_body_com = m_body_r_body_com; + *body_I_body = m_body_I_body; - *user_int = 0; - *user_ptr = 0; - return 0; -} + *user_int = 0; + *user_ptr = 0; + return 0; } +} // namespace btInverseDynamics diff --git a/Extras/InverseDynamics/CoilCreator.hpp b/Extras/InverseDynamics/CoilCreator.hpp index a57ee3595..886214a7b 100644 --- a/Extras/InverseDynamics/CoilCreator.hpp +++ b/Extras/InverseDynamics/CoilCreator.hpp @@ -3,38 +3,39 @@ #include "MultiBodyTreeCreator.hpp" -namespace btInverseDynamics { - +namespace btInverseDynamics +{ /// Creator class for building a "coil" system as intruduced as benchmark example in /// Featherstone (1999), "A Divide-and-Conquer Articulated-Body Algorithm for Parallel O(log(n)) /// Calculation of Rigid-Body Dynamics. Part 2: Trees, Loops, and Accuracy.", The International /// Journal of Robotics Research 18 (9): 876–892. doi : 10.1177 / 02783649922066628. /// /// This is a serial chain, with an initial configuration resembling a coil. -class CoilCreator : public MultiBodyTreeCreator { +class CoilCreator : public MultiBodyTreeCreator +{ public: - /// ctor. - /// @param n the number of bodies in the system - CoilCreator(int n); - /// dtor - ~CoilCreator(); - // \copydoc MultiBodyTreeCreator::getNumBodies - int getNumBodies(int* num_bodies) const; - // \copydoc MultiBodyTreeCreator::getBody - int getBody(const int body_index, int* parent_index, JointType* joint_type, - vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, vec3* body_axis_of_motion, - idScalar* mass, vec3* body_r_body_com, mat33* body_I_body, int* user_int, - void** user_ptr) const; + /// ctor. + /// @param n the number of bodies in the system + CoilCreator(int n); + /// dtor + ~CoilCreator(); + // \copydoc MultiBodyTreeCreator::getNumBodies + int getNumBodies(int* num_bodies) const; + // \copydoc MultiBodyTreeCreator::getBody + int getBody(const int body_index, int* parent_index, JointType* joint_type, + vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, vec3* body_axis_of_motion, + idScalar* mass, vec3* body_r_body_com, mat33* body_I_body, int* user_int, + void** user_ptr) const; private: - int m_num_bodies; - std::vector m_parent; - vec3 m_parent_r_parent_body_ref; - mat33 m_body_T_parent_ref; - vec3 m_body_axis_of_motion; - idScalar m_mass; - vec3 m_body_r_body_com; - mat33 m_body_I_body; + int m_num_bodies; + std::vector m_parent; + vec3 m_parent_r_parent_body_ref; + mat33 m_body_T_parent_ref; + vec3 m_body_axis_of_motion; + idScalar m_mass; + vec3 m_body_r_body_com; + mat33 m_body_I_body; }; -} +} // namespace btInverseDynamics #endif diff --git a/Extras/InverseDynamics/DillCreator.cpp b/Extras/InverseDynamics/DillCreator.cpp index 17f30dcd5..01ecba314 100644 --- a/Extras/InverseDynamics/DillCreator.cpp +++ b/Extras/InverseDynamics/DillCreator.cpp @@ -1,124 +1,136 @@ #include "DillCreator.hpp" #include -namespace btInverseDynamics { - +namespace btInverseDynamics +{ DillCreator::DillCreator(int level) - : m_level(level), - m_num_bodies(BT_ID_POW(2, level)) - { - m_parent.resize(m_num_bodies); - m_parent_r_parent_body_ref.resize(m_num_bodies); - m_body_T_parent_ref.resize(m_num_bodies); - m_body_axis_of_motion.resize(m_num_bodies); - m_mass.resize(m_num_bodies); - m_body_r_body_com.resize(m_num_bodies); - m_body_I_body.resize(m_num_bodies); + : m_level(level), + m_num_bodies(BT_ID_POW(2, level)) +{ + m_parent.resize(m_num_bodies); + m_parent_r_parent_body_ref.resize(m_num_bodies); + m_body_T_parent_ref.resize(m_num_bodies); + m_body_axis_of_motion.resize(m_num_bodies); + m_mass.resize(m_num_bodies); + m_body_r_body_com.resize(m_num_bodies); + m_body_I_body.resize(m_num_bodies); - // generate names (for debugging) - for (int i = 0; i < m_num_bodies; i++) { - m_parent[i] = i - 1; + // generate names (for debugging) + for (int i = 0; i < m_num_bodies; i++) + { + m_parent[i] = i - 1; - // all z-axis (DH convention) - m_body_axis_of_motion[i](0) = 0.0; - m_body_axis_of_motion[i](1) = 0.0; - m_body_axis_of_motion[i](2) = 1.0; - } + // all z-axis (DH convention) + m_body_axis_of_motion[i](0) = 0.0; + m_body_axis_of_motion[i](1) = 0.0; + m_body_axis_of_motion[i](2) = 1.0; + } - // recursively build data structures - m_current_body = 0; - const int parent = -1; - const idScalar d_DH = 0.0; - const idScalar a_DH = 0.0; - const idScalar alpha_DH = 0.0; + // recursively build data structures + m_current_body = 0; + const int parent = -1; + const idScalar d_DH = 0.0; + const idScalar a_DH = 0.0; + const idScalar alpha_DH = 0.0; - if (-1 == recurseDill(m_level, parent, d_DH, a_DH, alpha_DH)) { - bt_id_error_message("recurseDill failed\n"); - abort(); - } + if (-1 == recurseDill(m_level, parent, d_DH, a_DH, alpha_DH)) + { + bt_id_error_message("recurseDill failed\n"); + abort(); + } } DillCreator::~DillCreator() {} -int DillCreator::getNumBodies(int* num_bodies) const { - *num_bodies = m_num_bodies; - return 0; +int DillCreator::getNumBodies(int* num_bodies) const +{ + *num_bodies = m_num_bodies; + return 0; } int DillCreator::getBody(const int body_index, int* parent_index, JointType* joint_type, - vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, - vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com, - mat33* body_I_body, int* user_int, void** user_ptr) const { - if (body_index < 0 || body_index >= m_num_bodies) { - bt_id_error_message("invalid body index %d\n", body_index); - return -1; - } - *parent_index = m_parent[body_index]; - *joint_type = REVOLUTE; - *parent_r_parent_body_ref = m_parent_r_parent_body_ref[body_index]; - *body_T_parent_ref = m_body_T_parent_ref[body_index]; - *body_axis_of_motion = m_body_axis_of_motion[body_index]; - *mass = m_mass[body_index]; - *body_r_body_com = m_body_r_body_com[body_index]; - *body_I_body = m_body_I_body[body_index]; + vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, + vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com, + mat33* body_I_body, int* user_int, void** user_ptr) const +{ + if (body_index < 0 || body_index >= m_num_bodies) + { + bt_id_error_message("invalid body index %d\n", body_index); + return -1; + } + *parent_index = m_parent[body_index]; + *joint_type = REVOLUTE; + *parent_r_parent_body_ref = m_parent_r_parent_body_ref[body_index]; + *body_T_parent_ref = m_body_T_parent_ref[body_index]; + *body_axis_of_motion = m_body_axis_of_motion[body_index]; + *mass = m_mass[body_index]; + *body_r_body_com = m_body_r_body_com[body_index]; + *body_I_body = m_body_I_body[body_index]; - *user_int = 0; - *user_ptr = 0; - return 0; + *user_int = 0; + *user_ptr = 0; + return 0; } int DillCreator::recurseDill(const int level, const int parent, const idScalar d_DH_in, - const idScalar a_DH_in, const idScalar alpha_DH_in) { - if (level < 0) { - bt_id_error_message("invalid level parameter (%d)\n", level); - return -1; - } + const idScalar a_DH_in, const idScalar alpha_DH_in) +{ + if (level < 0) + { + bt_id_error_message("invalid level parameter (%d)\n", level); + return -1; + } - if (m_current_body >= m_num_bodies || m_current_body < 0) { - bt_id_error_message("invalid body parameter (%d, num_bodies: %d)\n", m_current_body, - m_num_bodies); - return -1; - } + if (m_current_body >= m_num_bodies || m_current_body < 0) + { + bt_id_error_message("invalid body parameter (%d, num_bodies: %d)\n", m_current_body, + m_num_bodies); + return -1; + } - idScalar size = BT_ID_MAX(level, 1); - const int body = m_current_body; - // length = 0.1 * size; - // with = 2 * 0.01 * size; + idScalar size = BT_ID_MAX(level, 1); + const int body = m_current_body; + // length = 0.1 * size; + // with = 2 * 0.01 * size; - /// these parameters are from the paper ... - /// TODO: add proper citation - m_parent[body] = parent; - m_mass[body] = 0.1 * BT_ID_POW(size, 3); - m_body_r_body_com[body](0) = 0.05 * size; - m_body_r_body_com[body](1) = 0; - m_body_r_body_com[body](2) = 0; - // initialization - for (int i = 0; i < 3; i++) { - m_parent_r_parent_body_ref[body](i) = 0; - for (int j = 0; j < 3; j++) { - m_body_I_body[body](i, j) = 0.0; - m_body_T_parent_ref[body](i, j) = 0.0; - } - } - const idScalar size_5 = pow(size, 5); - m_body_I_body[body](0, 0) = size_5 / 0.2e6; - m_body_I_body[body](1, 1) = size_5 * 403 / 1.2e6; - m_body_I_body[body](2, 2) = m_body_I_body[body](1, 1); + /// these parameters are from the paper ... + /// TODO: add proper citation + m_parent[body] = parent; + m_mass[body] = 0.1 * BT_ID_POW(size, 3); + m_body_r_body_com[body](0) = 0.05 * size; + m_body_r_body_com[body](1) = 0; + m_body_r_body_com[body](2) = 0; + // initialization + for (int i = 0; i < 3; i++) + { + m_parent_r_parent_body_ref[body](i) = 0; + for (int j = 0; j < 3; j++) + { + m_body_I_body[body](i, j) = 0.0; + m_body_T_parent_ref[body](i, j) = 0.0; + } + } + const idScalar size_5 = pow(size, 5); + m_body_I_body[body](0, 0) = size_5 / 0.2e6; + m_body_I_body[body](1, 1) = size_5 * 403 / 1.2e6; + m_body_I_body[body](2, 2) = m_body_I_body[body](1, 1); - getVecMatFromDH(0, 0, a_DH_in, alpha_DH_in, &m_parent_r_parent_body_ref[body], - &m_body_T_parent_ref[body]); + getVecMatFromDH(0, 0, a_DH_in, alpha_DH_in, &m_parent_r_parent_body_ref[body], + &m_body_T_parent_ref[body]); - // attach "level" Dill systems of levels 1...level - for (int i = 1; i <= level; i++) { - idScalar d_DH = 0.01 * size; - if (i == level) { - d_DH = 0.0; - } - const idScalar a_DH = i * 0.1; - const idScalar alpha_DH = i * BT_ID_PI / 3.0; - m_current_body++; - recurseDill(i - 1, body, d_DH, a_DH, alpha_DH); - } + // attach "level" Dill systems of levels 1...level + for (int i = 1; i <= level; i++) + { + idScalar d_DH = 0.01 * size; + if (i == level) + { + d_DH = 0.0; + } + const idScalar a_DH = i * 0.1; + const idScalar alpha_DH = i * BT_ID_PI / 3.0; + m_current_body++; + recurseDill(i - 1, body, d_DH, a_DH, alpha_DH); + } - return 0; // ok! -} + return 0; // ok! } +} // namespace btInverseDynamics diff --git a/Extras/InverseDynamics/DillCreator.hpp b/Extras/InverseDynamics/DillCreator.hpp index fbe0e8e22..854e76964 100644 --- a/Extras/InverseDynamics/DillCreator.hpp +++ b/Extras/InverseDynamics/DillCreator.hpp @@ -3,45 +3,45 @@ #include "MultiBodyTreeCreator.hpp" -namespace btInverseDynamics { - - +namespace btInverseDynamics +{ /// Creator class for building a "Dill" system as intruduced as benchmark example in /// Featherstone (1999), "A Divide-and-Conquer Articulated-Body Algorithm for Parallel O(log(n)) /// Calculation of Rigid-Body Dynamics. Part 2: Trees, Loops, and Accuracy.", The International /// Journal of Robotics Research 18 (9): 876–892. doi : 10.1177 / 02783649922066628. /// /// This is a self-similar branched tree, somewhat resembling a dill plant -class DillCreator : public MultiBodyTreeCreator { +class DillCreator : public MultiBodyTreeCreator +{ public: - /// ctor - /// @param levels the number of dill levels - DillCreator(int levels); - /// dtor - ~DillCreator(); - ///\copydoc MultiBodyTreeCreator::getNumBodies - int getNumBodies(int* num_bodies) const; - ///\copydoc MultiBodyTreeCreator::getBody - int getBody(const int body_index, int* parent_index, JointType* joint_type, - vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, vec3* body_axis_of_motion, - idScalar* mass, vec3* body_r_body_com, mat33* body_I_body, int* user_int, - void** user_ptr) const; + /// ctor + /// @param levels the number of dill levels + DillCreator(int levels); + /// dtor + ~DillCreator(); + ///\copydoc MultiBodyTreeCreator::getNumBodies + int getNumBodies(int* num_bodies) const; + ///\copydoc MultiBodyTreeCreator::getBody + int getBody(const int body_index, int* parent_index, JointType* joint_type, + vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, vec3* body_axis_of_motion, + idScalar* mass, vec3* body_r_body_com, mat33* body_I_body, int* user_int, + void** user_ptr) const; private: - /// recursively generate dill bodies. - /// TODO better documentation - int recurseDill(const int levels, const int parent, const idScalar d_DH_in, - const idScalar a_DH_in, const idScalar alpha_DH_in); - int m_level; - int m_num_bodies; - idArray::type m_parent; - idArray::type m_parent_r_parent_body_ref; - idArray::type m_body_T_parent_ref; - idArray::type m_body_axis_of_motion; - idArray::type m_mass; - idArray::type m_body_r_body_com; - idArray::type m_body_I_body; - int m_current_body; + /// recursively generate dill bodies. + /// TODO better documentation + int recurseDill(const int levels, const int parent, const idScalar d_DH_in, + const idScalar a_DH_in, const idScalar alpha_DH_in); + int m_level; + int m_num_bodies; + idArray::type m_parent; + idArray::type m_parent_r_parent_body_ref; + idArray::type m_body_T_parent_ref; + idArray::type m_body_axis_of_motion; + idArray::type m_mass; + idArray::type m_body_r_body_com; + idArray::type m_body_I_body; + int m_current_body; }; -} +} // namespace btInverseDynamics #endif diff --git a/Extras/InverseDynamics/IDRandomUtil.cpp b/Extras/InverseDynamics/IDRandomUtil.cpp index fff352490..30411e5a8 100644 --- a/Extras/InverseDynamics/IDRandomUtil.cpp +++ b/Extras/InverseDynamics/IDRandomUtil.cpp @@ -6,9 +6,8 @@ #include "BulletInverseDynamics/IDMath.hpp" #include "IDRandomUtil.hpp" - -namespace btInverseDynamics { - +namespace btInverseDynamics +{ // constants for random mass and inertia generation // these are arbitrary positive values. static const float mass_min = 0.001; @@ -19,53 +18,59 @@ void randomInit(unsigned seed) { srand(seed); } int randomInt(int low, int high) { return rand() % (high + 1 - low) + low; } -float randomFloat(float low, float high) { - return low + static_cast(rand()) / RAND_MAX * (high - low); +float randomFloat(float low, float high) +{ + return low + static_cast(rand()) / RAND_MAX * (high - low); } float randomMass() { return randomFloat(mass_min, mass_max); } -vec3 randomInertiaPrincipal() { - vec3 inertia; - do { - inertia(0) = randomFloat(mass_min, mass_max); - inertia(1) = randomFloat(mass_min, mass_max); - inertia(2) = randomFloat(mass_min, mass_max); - } while (inertia(0) + inertia(1) < inertia(2) || inertia(0) + inertia(2) < inertia(1) || - inertia(1) + inertia(2) < inertia(0)); - return inertia; +vec3 randomInertiaPrincipal() +{ + vec3 inertia; + do + { + inertia(0) = randomFloat(mass_min, mass_max); + inertia(1) = randomFloat(mass_min, mass_max); + inertia(2) = randomFloat(mass_min, mass_max); + } while (inertia(0) + inertia(1) < inertia(2) || inertia(0) + inertia(2) < inertia(1) || + inertia(1) + inertia(2) < inertia(0)); + return inertia; } -mat33 randomInertiaMatrix() { - // generate random valid inertia matrix by first getting valid components - // along major axes and then rotating by random amount - vec3 principal = randomInertiaPrincipal(); - mat33 rot(transformX(randomFloat(-BT_ID_PI, BT_ID_PI)) * transformY(randomFloat(-BT_ID_PI, BT_ID_PI)) * - transformZ(randomFloat(-BT_ID_PI, BT_ID_PI))); - mat33 inertia; - inertia(0, 0) = principal(0); - inertia(0, 1) = 0; - inertia(0, 2) = 0; - inertia(1, 0) = 0; - inertia(1, 1) = principal(1); - inertia(1, 2) = 0; - inertia(2, 0) = 0; - inertia(2, 1) = 0; - inertia(2, 2) = principal(2); - return rot * inertia * rot.transpose(); +mat33 randomInertiaMatrix() +{ + // generate random valid inertia matrix by first getting valid components + // along major axes and then rotating by random amount + vec3 principal = randomInertiaPrincipal(); + mat33 rot(transformX(randomFloat(-BT_ID_PI, BT_ID_PI)) * transformY(randomFloat(-BT_ID_PI, BT_ID_PI)) * + transformZ(randomFloat(-BT_ID_PI, BT_ID_PI))); + mat33 inertia; + inertia(0, 0) = principal(0); + inertia(0, 1) = 0; + inertia(0, 2) = 0; + inertia(1, 0) = 0; + inertia(1, 1) = principal(1); + inertia(1, 2) = 0; + inertia(2, 0) = 0; + inertia(2, 1) = 0; + inertia(2, 2) = principal(2); + return rot * inertia * rot.transpose(); } -vec3 randomAxis() { - vec3 axis; - idScalar length; - do { - axis(0) = randomFloat(-1.0, 1.0); - axis(1) = randomFloat(-1.0, 1.0); - axis(2) = randomFloat(-1.0, 1.0); +vec3 randomAxis() +{ + vec3 axis; + idScalar length; + do + { + axis(0) = randomFloat(-1.0, 1.0); + axis(1) = randomFloat(-1.0, 1.0); + axis(2) = randomFloat(-1.0, 1.0); - length = BT_ID_SQRT(BT_ID_POW(axis(0), 2) + BT_ID_POW(axis(1), 2) + BT_ID_POW(axis(2), 2)); - } while (length < 0.01); + length = BT_ID_SQRT(BT_ID_POW(axis(0), 2) + BT_ID_POW(axis(1), 2) + BT_ID_POW(axis(2), 2)); + } while (length < 0.01); - return axis / length; -} + return axis / length; } +} // namespace btInverseDynamics diff --git a/Extras/InverseDynamics/IDRandomUtil.hpp b/Extras/InverseDynamics/IDRandomUtil.hpp index 72a97fa2b..405e6472c 100644 --- a/Extras/InverseDynamics/IDRandomUtil.hpp +++ b/Extras/InverseDynamics/IDRandomUtil.hpp @@ -1,7 +1,8 @@ #ifndef ID_RANDOM_UTIL_HPP_ #define ID_RANDOM_UTIL_HPP_ #include "BulletInverseDynamics/IDConfig.hpp" -namespace btInverseDynamics { +namespace btInverseDynamics +{ /// seed random number generator using time() void randomInit(); /// seed random number generator with identical value to get repeatable results @@ -32,5 +33,5 @@ vec3 randomInertiaPrincipal(); mat33 randomInertiaMatrix(); /// generate a random unit vector vec3 randomAxis(); -} +} // namespace btInverseDynamics #endif diff --git a/Extras/InverseDynamics/MultiBodyNameMap.cpp b/Extras/InverseDynamics/MultiBodyNameMap.cpp index 81d33f285..75b5acc91 100644 --- a/Extras/InverseDynamics/MultiBodyNameMap.cpp +++ b/Extras/InverseDynamics/MultiBodyNameMap.cpp @@ -1,78 +1,92 @@ #include "MultiBodyNameMap.hpp" -namespace btInverseDynamics { - +namespace btInverseDynamics +{ MultiBodyNameMap::MultiBodyNameMap() {} -int MultiBodyNameMap::addBody(const int index, const std::string& name) { - if (m_index_to_body_name.count(index) > 0) { - bt_id_error_message("trying to add index %d again\n", index); - return -1; - } - if (m_body_name_to_index.count(name) > 0) { - bt_id_error_message("trying to add name %s again\n", name.c_str()); - return -1; - } +int MultiBodyNameMap::addBody(const int index, const std::string& name) +{ + if (m_index_to_body_name.count(index) > 0) + { + bt_id_error_message("trying to add index %d again\n", index); + return -1; + } + if (m_body_name_to_index.count(name) > 0) + { + bt_id_error_message("trying to add name %s again\n", name.c_str()); + return -1; + } - m_index_to_body_name[index] = name; - m_body_name_to_index[name] = index; + m_index_to_body_name[index] = name; + m_body_name_to_index[name] = index; - return 0; + return 0; } -int MultiBodyNameMap::addJoint(const int index, const std::string& name) { - if (m_index_to_joint_name.count(index) > 0) { - bt_id_error_message("trying to add index %d again\n", index); - return -1; - } - if (m_joint_name_to_index.count(name) > 0) { - bt_id_error_message("trying to add name %s again\n", name.c_str()); - return -1; - } +int MultiBodyNameMap::addJoint(const int index, const std::string& name) +{ + if (m_index_to_joint_name.count(index) > 0) + { + bt_id_error_message("trying to add index %d again\n", index); + return -1; + } + if (m_joint_name_to_index.count(name) > 0) + { + bt_id_error_message("trying to add name %s again\n", name.c_str()); + return -1; + } - m_index_to_joint_name[index] = name; - m_joint_name_to_index[name] = index; + m_index_to_joint_name[index] = name; + m_joint_name_to_index[name] = index; - return 0; + return 0; } -int MultiBodyNameMap::getBodyName(const int index, std::string* name) const { - std::map::const_iterator it = m_index_to_body_name.find(index); - if (it == m_index_to_body_name.end()) { - bt_id_error_message("index %d not known\n", index); - return -1; - } - *name = it->second; - return 0; +int MultiBodyNameMap::getBodyName(const int index, std::string* name) const +{ + std::map::const_iterator it = m_index_to_body_name.find(index); + if (it == m_index_to_body_name.end()) + { + bt_id_error_message("index %d not known\n", index); + return -1; + } + *name = it->second; + return 0; } -int MultiBodyNameMap::getJointName(const int index, std::string* name) const { - std::map::const_iterator it = m_index_to_joint_name.find(index); - if (it == m_index_to_joint_name.end()) { - bt_id_error_message("index %d not known\n", index); - return -1; - } - *name = it->second; - return 0; +int MultiBodyNameMap::getJointName(const int index, std::string* name) const +{ + std::map::const_iterator it = m_index_to_joint_name.find(index); + if (it == m_index_to_joint_name.end()) + { + bt_id_error_message("index %d not known\n", index); + return -1; + } + *name = it->second; + return 0; } -int MultiBodyNameMap::getBodyIndex(const std::string& name, int* index) const { - std::map::const_iterator it = m_body_name_to_index.find(name); - if (it == m_body_name_to_index.end()) { - bt_id_error_message("name %s not known\n", name.c_str()); - return -1; - } - *index = it->second; - return 0; +int MultiBodyNameMap::getBodyIndex(const std::string& name, int* index) const +{ + std::map::const_iterator it = m_body_name_to_index.find(name); + if (it == m_body_name_to_index.end()) + { + bt_id_error_message("name %s not known\n", name.c_str()); + return -1; + } + *index = it->second; + return 0; } -int MultiBodyNameMap::getJointIndex(const std::string& name, int* index) const { - std::map::const_iterator it = m_joint_name_to_index.find(name); - if (it == m_joint_name_to_index.end()) { - bt_id_error_message("name %s not known\n", name.c_str()); - return -1; - } - *index = it->second; - return 0; -} +int MultiBodyNameMap::getJointIndex(const std::string& name, int* index) const +{ + std::map::const_iterator it = m_joint_name_to_index.find(name); + if (it == m_joint_name_to_index.end()) + { + bt_id_error_message("name %s not known\n", name.c_str()); + return -1; + } + *index = it->second; + return 0; } +} // namespace btInverseDynamics diff --git a/Extras/InverseDynamics/MultiBodyNameMap.hpp b/Extras/InverseDynamics/MultiBodyNameMap.hpp index a5e024ce0..e09415454 100644 --- a/Extras/InverseDynamics/MultiBodyNameMap.hpp +++ b/Extras/InverseDynamics/MultiBodyNameMap.hpp @@ -5,50 +5,51 @@ #include #include -namespace btInverseDynamics { - +namespace btInverseDynamics +{ /// \brief The MultiBodyNameMap class /// Utility class that stores a maps from body/joint indices to/from body and joint names -class MultiBodyNameMap { +class MultiBodyNameMap +{ public: - MultiBodyNameMap(); - /// add a body to the map - /// @param index of the body - /// @param name name of the body - /// @return 0 on success, -1 on failure - int addBody(const int index, const std::string& name); - /// add a joint to the map - /// @param index of the joint - /// @param name name of the joint - /// @return 0 on success, -1 on failure - int addJoint(const int index, const std::string& name); - /// get body name from index - /// @param index of the body - /// @param body_name name of the body - /// @return 0 on success, -1 on failure - int getBodyName(const int index, std::string* name) const; - /// get joint name from index - /// @param index of the joint - /// @param joint_name name of the joint - /// @return 0 on success, -1 on failure - int getJointName(const int index, std::string* name) const; - /// get body index from name - /// @param index of the body - /// @param name name of the body - /// @return 0 on success, -1 on failure - int getBodyIndex(const std::string& name, int* index) const; - /// get joint index from name - /// @param index of the joint - /// @param name name of the joint - /// @return 0 on success, -1 on failure - int getJointIndex(const std::string& name, int* index) const; + MultiBodyNameMap(); + /// add a body to the map + /// @param index of the body + /// @param name name of the body + /// @return 0 on success, -1 on failure + int addBody(const int index, const std::string& name); + /// add a joint to the map + /// @param index of the joint + /// @param name name of the joint + /// @return 0 on success, -1 on failure + int addJoint(const int index, const std::string& name); + /// get body name from index + /// @param index of the body + /// @param body_name name of the body + /// @return 0 on success, -1 on failure + int getBodyName(const int index, std::string* name) const; + /// get joint name from index + /// @param index of the joint + /// @param joint_name name of the joint + /// @return 0 on success, -1 on failure + int getJointName(const int index, std::string* name) const; + /// get body index from name + /// @param index of the body + /// @param name name of the body + /// @return 0 on success, -1 on failure + int getBodyIndex(const std::string& name, int* index) const; + /// get joint index from name + /// @param index of the joint + /// @param name name of the joint + /// @return 0 on success, -1 on failure + int getJointIndex(const std::string& name, int* index) const; private: - std::map m_index_to_joint_name; - std::map m_index_to_body_name; + std::map m_index_to_joint_name; + std::map m_index_to_body_name; - std::map m_joint_name_to_index; - std::map m_body_name_to_index; + std::map m_joint_name_to_index; + std::map m_body_name_to_index; }; -} +} // namespace btInverseDynamics #endif // MULTIBODYNAMEMAP_HPP_ diff --git a/Extras/InverseDynamics/MultiBodyTreeCreator.cpp b/Extras/InverseDynamics/MultiBodyTreeCreator.cpp index 0972f4396..a390aae03 100644 --- a/Extras/InverseDynamics/MultiBodyTreeCreator.cpp +++ b/Extras/InverseDynamics/MultiBodyTreeCreator.cpp @@ -1,64 +1,71 @@ #include "MultiBodyTreeCreator.hpp" -namespace btInverseDynamics { +namespace btInverseDynamics +{ +MultiBodyTree* CreateMultiBodyTree(const MultiBodyTreeCreator& creator) +{ + int num_bodies; + int parent_index; + JointType joint_type; + vec3 body_r_parent_body_ref; + mat33 body_R_parent_ref; + vec3 body_axis_of_motion; + idScalar mass; + vec3 body_r_body_com; + mat33 body_I_body; + int user_int; + void* user_ptr; -MultiBodyTree* CreateMultiBodyTree(const MultiBodyTreeCreator& creator) { - int num_bodies; - int parent_index; - JointType joint_type; - vec3 body_r_parent_body_ref; - mat33 body_R_parent_ref; - vec3 body_axis_of_motion; - idScalar mass; - vec3 body_r_body_com; - mat33 body_I_body; - int user_int; - void* user_ptr; + MultiBodyTree* tree = new MultiBodyTree(); + if (0x0 == tree) + { + bt_id_error_message("cannot allocate tree\n"); + return 0x0; + } - MultiBodyTree* tree = new MultiBodyTree(); - if (0x0 == tree) { - bt_id_error_message("cannot allocate tree\n"); - return 0x0; - } + // TODO: move to some policy argument + tree->setAcceptInvalidMassParameters(false); - // TODO: move to some policy argument - tree->setAcceptInvalidMassParameters(false); + // get number of bodies in the system + if (-1 == creator.getNumBodies(&num_bodies)) + { + bt_id_error_message("getting body indices\n"); + delete tree; + return 0x0; + } - // get number of bodies in the system - if (-1 == creator.getNumBodies(&num_bodies)) { - bt_id_error_message("getting body indices\n"); - delete tree; - return 0x0; - } + // get data for all bodies + for (int index = 0; index < num_bodies; index++) + { + // get body parameters from user callbacks + if (-1 == + creator.getBody(index, &parent_index, &joint_type, &body_r_parent_body_ref, + &body_R_parent_ref, &body_axis_of_motion, &mass, &body_r_body_com, + &body_I_body, &user_int, &user_ptr)) + { + bt_id_error_message("getting data for body %d\n", index); + delete tree; + return 0x0; + } + // add body to system + if (-1 == + tree->addBody(index, parent_index, joint_type, body_r_parent_body_ref, + body_R_parent_ref, body_axis_of_motion, mass, body_r_body_com, + body_I_body, user_int, user_ptr)) + { + bt_id_error_message("adding body %d\n", index); + delete tree; + return 0x0; + } + } + // finalize initialization + if (-1 == tree->finalize()) + { + bt_id_error_message("building system\n"); + delete tree; + return 0x0; + } - // get data for all bodies - for (int index = 0; index < num_bodies; index++) { - // get body parameters from user callbacks - if (-1 == - creator.getBody(index, &parent_index, &joint_type, &body_r_parent_body_ref, - &body_R_parent_ref, &body_axis_of_motion, &mass, &body_r_body_com, - &body_I_body, &user_int, &user_ptr)) { - bt_id_error_message("getting data for body %d\n", index); - delete tree; - return 0x0; - } - // add body to system - if (-1 == - tree->addBody(index, parent_index, joint_type, body_r_parent_body_ref, - body_R_parent_ref, body_axis_of_motion, mass, body_r_body_com, - body_I_body, user_int, user_ptr)) { - bt_id_error_message("adding body %d\n", index); - delete tree; - return 0x0; - } - } - // finalize initialization - if (-1 == tree->finalize()) { - bt_id_error_message("building system\n"); - delete tree; - return 0x0; - } - - return tree; -} + return tree; } +} // namespace btInverseDynamics diff --git a/Extras/InverseDynamics/MultiBodyTreeCreator.hpp b/Extras/InverseDynamics/MultiBodyTreeCreator.hpp index bbf552eb6..2d15b0923 100644 --- a/Extras/InverseDynamics/MultiBodyTreeCreator.hpp +++ b/Extras/InverseDynamics/MultiBodyTreeCreator.hpp @@ -8,28 +8,30 @@ #include "BulletInverseDynamics/MultiBodyTree.hpp" #include "MultiBodyNameMap.hpp" -namespace btInverseDynamics { +namespace btInverseDynamics +{ /// Interface class for initializing a MultiBodyTree instance. /// Data to be provided is modeled on the URDF specification. /// The user can derive from this class in order to programmatically /// initialize a system. -class MultiBodyTreeCreator { +class MultiBodyTreeCreator +{ public: - /// the dtor - virtual ~MultiBodyTreeCreator() {} - /// Get the number of bodies in the system - /// @param num_bodies write number of bodies here - /// @return 0 on success, -1 on error - virtual int getNumBodies(int* num_bodies) const = 0; - /// Interface for accessing link mass properties. - /// For detailed description of data, @sa MultiBodyTree::addBody - /// \copydoc MultiBodyTree::addBody - virtual int getBody(const int body_index, int* parent_index, JointType* joint_type, - vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, - vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com, - mat33* body_I_body, int* user_int, void** user_ptr) const = 0; - /// @return a pointer to a name mapping utility class, or 0x0 if not available - virtual const MultiBodyNameMap* getNameMap() const {return 0x0;} + /// the dtor + virtual ~MultiBodyTreeCreator() {} + /// Get the number of bodies in the system + /// @param num_bodies write number of bodies here + /// @return 0 on success, -1 on error + virtual int getNumBodies(int* num_bodies) const = 0; + /// Interface for accessing link mass properties. + /// For detailed description of data, @sa MultiBodyTree::addBody + /// \copydoc MultiBodyTree::addBody + virtual int getBody(const int body_index, int* parent_index, JointType* joint_type, + vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, + vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com, + mat33* body_I_body, int* user_int, void** user_ptr) const = 0; + /// @return a pointer to a name mapping utility class, or 0x0 if not available + virtual const MultiBodyNameMap* getNameMap() const { return 0x0; } }; /// Create a multibody object. @@ -38,7 +40,7 @@ public: /// @return A pointer to an allocated multibodytree instance, or /// 0x0 if an error occured. MultiBodyTree* CreateMultiBodyTree(const MultiBodyTreeCreator& creator); -} +} // namespace btInverseDynamics // does urdf have gravity direction ?? diff --git a/Extras/InverseDynamics/MultiBodyTreeDebugGraph.cpp b/Extras/InverseDynamics/MultiBodyTreeDebugGraph.cpp index aac58e4b3..4609472e0 100644 --- a/Extras/InverseDynamics/MultiBodyTreeDebugGraph.cpp +++ b/Extras/InverseDynamics/MultiBodyTreeDebugGraph.cpp @@ -2,63 +2,76 @@ #include -namespace btInverseDynamics { - +namespace btInverseDynamics +{ int writeGraphvizDotFile(const MultiBodyTree* tree, const MultiBodyNameMap* map, - const char* filename) { - if (0x0 == tree) { - bt_id_error_message("tree pointer is null\n"); - return -1; - } - if (0x0 == filename) { - bt_id_error_message("filename is null\n"); - return -1; - } + const char* filename) +{ + if (0x0 == tree) + { + bt_id_error_message("tree pointer is null\n"); + return -1; + } + if (0x0 == filename) + { + bt_id_error_message("filename is null\n"); + return -1; + } - FILE* fp = fopen(filename, "w"); - if (NULL == fp) { - bt_id_error_message("cannot open file %s for writing\n", filename); - return -1; - } - fprintf(fp, "// to generate postscript file, run dot -Tps %s -o %s.ps\n" - "// details see graphviz documentation at http://graphviz.org\n" - "digraph tree {\n", - filename, filename); + FILE* fp = fopen(filename, "w"); + if (NULL == fp) + { + bt_id_error_message("cannot open file %s for writing\n", filename); + return -1; + } + fprintf(fp, + "// to generate postscript file, run dot -Tps %s -o %s.ps\n" + "// details see graphviz documentation at http://graphviz.org\n" + "digraph tree {\n", + filename, filename); - for (int body = 0; body < tree->numBodies(); body++) { - std::string name; - if (0x0 != map) { - if (-1 == map->getBodyName(body, &name)) { - bt_id_error_message("can't get name of body %d\n", body); - return -1; - } - fprintf(fp, " %d [label=\"%d/%s\"];\n", body, body, name.c_str()); - } - } - for (int body = 0; body < tree->numBodies(); body++) { - int parent; - const char* joint_type; - int qi; - if (-1 == tree->getParentIndex(body, &parent)) { - bt_id_error_message("indexing error\n"); - return -1; - } - if (-1 == tree->getJointTypeStr(body, &joint_type)) { - bt_id_error_message("indexing error\n"); - return -1; - } - if (-1 == tree->getDoFOffset(body, &qi)) { - bt_id_error_message("indexing error\n"); - return -1; - } - if (-1 != parent) { - fprintf(fp, " %d -> %d [label= \"type:%s, q=%d\"];\n", parent, body, - joint_type, qi); - } - } + for (int body = 0; body < tree->numBodies(); body++) + { + std::string name; + if (0x0 != map) + { + if (-1 == map->getBodyName(body, &name)) + { + bt_id_error_message("can't get name of body %d\n", body); + return -1; + } + fprintf(fp, " %d [label=\"%d/%s\"];\n", body, body, name.c_str()); + } + } + for (int body = 0; body < tree->numBodies(); body++) + { + int parent; + const char* joint_type; + int qi; + if (-1 == tree->getParentIndex(body, &parent)) + { + bt_id_error_message("indexing error\n"); + return -1; + } + if (-1 == tree->getJointTypeStr(body, &joint_type)) + { + bt_id_error_message("indexing error\n"); + return -1; + } + if (-1 == tree->getDoFOffset(body, &qi)) + { + bt_id_error_message("indexing error\n"); + return -1; + } + if (-1 != parent) + { + fprintf(fp, " %d -> %d [label= \"type:%s, q=%d\"];\n", parent, body, + joint_type, qi); + } + } - fprintf(fp, "}\n"); - fclose(fp); - return 0; -} + fprintf(fp, "}\n"); + fclose(fp); + return 0; } +} // namespace btInverseDynamics diff --git a/Extras/InverseDynamics/MultiBodyTreeDebugGraph.hpp b/Extras/InverseDynamics/MultiBodyTreeDebugGraph.hpp index f249d0952..fd2309be7 100644 --- a/Extras/InverseDynamics/MultiBodyTreeDebugGraph.hpp +++ b/Extras/InverseDynamics/MultiBodyTreeDebugGraph.hpp @@ -4,14 +4,15 @@ #include "BulletInverseDynamics/MultiBodyTree.hpp" #include "MultiBodyNameMap.hpp" -namespace btInverseDynamics { +namespace btInverseDynamics +{ /// generate a dot-file of the multibody tree for generating a graph using graphviz' dot tool /// @param tree the multibody tree /// @param map to add names of links (if 0x0, no names will be added) /// @param filename name for the output file /// @return 0 on success, -1 on error int writeGraphvizDotFile(const MultiBodyTree* tree, const MultiBodyNameMap* map, - const char* filename); -} + const char* filename); +} // namespace btInverseDynamics #endif // MULTIBODYTREEDEBUGGRAPH_HPP diff --git a/Extras/InverseDynamics/RandomTreeCreator.cpp b/Extras/InverseDynamics/RandomTreeCreator.cpp index a531037a2..4717e3189 100644 --- a/Extras/InverseDynamics/RandomTreeCreator.cpp +++ b/Extras/InverseDynamics/RandomTreeCreator.cpp @@ -4,78 +4,88 @@ #include "IDRandomUtil.hpp" -namespace btInverseDynamics { - -RandomTreeCreator::RandomTreeCreator(const int max_bodies, bool random_seed) { - // seed generator - if(random_seed) { - randomInit(); // seeds with time() - } else { - randomInit(1); // seeds with 1 - } - m_num_bodies = randomInt(1, max_bodies); +namespace btInverseDynamics +{ +RandomTreeCreator::RandomTreeCreator(const int max_bodies, bool random_seed) +{ + // seed generator + if (random_seed) + { + randomInit(); // seeds with time() + } + else + { + randomInit(1); // seeds with 1 + } + m_num_bodies = randomInt(1, max_bodies); } RandomTreeCreator::~RandomTreeCreator() {} -int RandomTreeCreator::getNumBodies(int* num_bodies) const { - *num_bodies = m_num_bodies; - return 0; +int RandomTreeCreator::getNumBodies(int* num_bodies) const +{ + *num_bodies = m_num_bodies; + return 0; } int RandomTreeCreator::getBody(const int body_index, int* parent_index, JointType* joint_type, - vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, - vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com, - mat33* body_I_body, int* user_int, void** user_ptr) const { - if(0 == body_index) { //root body - *parent_index = -1; - } else { - *parent_index = randomInt(0, body_index - 1); - } + vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, + vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com, + mat33* body_I_body, int* user_int, void** user_ptr) const +{ + if (0 == body_index) + { //root body + *parent_index = -1; + } + else + { + *parent_index = randomInt(0, body_index - 1); + } - switch (randomInt(0, 3)) { - case 0: - *joint_type = FIXED; - break; - case 1: - *joint_type = REVOLUTE; - break; - case 2: - *joint_type = PRISMATIC; - break; - case 3: - *joint_type = FLOATING; - break; - default: - bt_id_error_message("randomInt() result out of range\n"); - return -1; - } + switch (randomInt(0, 3)) + { + case 0: + *joint_type = FIXED; + break; + case 1: + *joint_type = REVOLUTE; + break; + case 2: + *joint_type = PRISMATIC; + break; + case 3: + *joint_type = FLOATING; + break; + default: + bt_id_error_message("randomInt() result out of range\n"); + return -1; + } - (*parent_r_parent_body_ref)(0) = randomFloat(-1.0, 1.0); - (*parent_r_parent_body_ref)(1) = randomFloat(-1.0, 1.0); - (*parent_r_parent_body_ref)(2) = randomFloat(-1.0, 1.0); + (*parent_r_parent_body_ref)(0) = randomFloat(-1.0, 1.0); + (*parent_r_parent_body_ref)(1) = randomFloat(-1.0, 1.0); + (*parent_r_parent_body_ref)(2) = randomFloat(-1.0, 1.0); - bodyTParentFromAxisAngle(randomAxis(), randomFloat(-BT_ID_PI, BT_ID_PI), body_T_parent_ref); + bodyTParentFromAxisAngle(randomAxis(), randomFloat(-BT_ID_PI, BT_ID_PI), body_T_parent_ref); - *body_axis_of_motion = randomAxis(); - *mass = randomMass(); - (*body_r_body_com)(0) = randomFloat(-1.0, 1.0); - (*body_r_body_com)(1) = randomFloat(-1.0, 1.0); - (*body_r_body_com)(2) = randomFloat(-1.0, 1.0); - const double a = randomFloat(-BT_ID_PI, BT_ID_PI); - const double b = randomFloat(-BT_ID_PI, BT_ID_PI); - const double c = randomFloat(-BT_ID_PI, BT_ID_PI); - vec3 ii = randomInertiaPrincipal(); - mat33 ii_diag; - setZero(ii_diag); - ii_diag(0,0)=ii(0); - ii_diag(1,1)=ii(1); - ii_diag(2,2)=ii(2); - *body_I_body = transformX(a) * transformY(b) * transformZ(c) * ii_diag * - transformZ(-c) * transformY(-b) * transformX(-a); - *user_int = 0; - *user_ptr = 0; + *body_axis_of_motion = randomAxis(); + *mass = randomMass(); + (*body_r_body_com)(0) = randomFloat(-1.0, 1.0); + (*body_r_body_com)(1) = randomFloat(-1.0, 1.0); + (*body_r_body_com)(2) = randomFloat(-1.0, 1.0); + const double a = randomFloat(-BT_ID_PI, BT_ID_PI); + const double b = randomFloat(-BT_ID_PI, BT_ID_PI); + const double c = randomFloat(-BT_ID_PI, BT_ID_PI); + vec3 ii = randomInertiaPrincipal(); + mat33 ii_diag; + setZero(ii_diag); + ii_diag(0, 0) = ii(0); + ii_diag(1, 1) = ii(1); + ii_diag(2, 2) = ii(2); + *body_I_body = transformX(a) * transformY(b) * transformZ(c) * ii_diag * + transformZ(-c) * transformY(-b) * transformX(-a); + *user_int = 0; + *user_ptr = 0; - return 0; -} + return 0; } +} // namespace btInverseDynamics diff --git a/Extras/InverseDynamics/RandomTreeCreator.hpp b/Extras/InverseDynamics/RandomTreeCreator.hpp index bbadb997d..71b39dd00 100644 --- a/Extras/InverseDynamics/RandomTreeCreator.hpp +++ b/Extras/InverseDynamics/RandomTreeCreator.hpp @@ -4,28 +4,30 @@ #include "BulletInverseDynamics/IDConfig.hpp" #include "MultiBodyTreeCreator.hpp" -namespace btInverseDynamics { +namespace btInverseDynamics +{ /// Generate a random MultiBodyTree with fixed or floating base and fixed, prismatic or revolute /// joints /// Uses a pseudo random number generator seeded from a random device. -class RandomTreeCreator : public MultiBodyTreeCreator { +class RandomTreeCreator : public MultiBodyTreeCreator +{ public: - /// ctor - /// @param max_bodies maximum number of bodies - /// @param gravity gravitational acceleration - /// @param use_seed if true, seed random number generator - RandomTreeCreator(const int max_bodies, bool use_seed=false); - ~RandomTreeCreator(); - ///\copydoc MultiBodyTreeCreator::getNumBodies - int getNumBodies(int* num_bodies) const; - ///\copydoc MultiBodyTreeCreator::getBody - int getBody(const int body_index, int* parent_index, JointType* joint_type, - vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, vec3* body_axis_of_motion, - idScalar* mass, vec3* body_r_body_com, mat33* body_I_body, int* user_int, - void** user_ptr) const; + /// ctor + /// @param max_bodies maximum number of bodies + /// @param gravity gravitational acceleration + /// @param use_seed if true, seed random number generator + RandomTreeCreator(const int max_bodies, bool use_seed = false); + ~RandomTreeCreator(); + ///\copydoc MultiBodyTreeCreator::getNumBodies + int getNumBodies(int* num_bodies) const; + ///\copydoc MultiBodyTreeCreator::getBody + int getBody(const int body_index, int* parent_index, JointType* joint_type, + vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, vec3* body_axis_of_motion, + idScalar* mass, vec3* body_r_body_com, mat33* body_I_body, int* user_int, + void** user_ptr) const; private: - int m_num_bodies; + int m_num_bodies; }; -} +} // namespace btInverseDynamics #endif // RANDOMTREE_CREATOR_HPP_ diff --git a/Extras/InverseDynamics/SimpleTreeCreator.cpp b/Extras/InverseDynamics/SimpleTreeCreator.cpp index e2b308ebe..bffdd3f6e 100644 --- a/Extras/InverseDynamics/SimpleTreeCreator.cpp +++ b/Extras/InverseDynamics/SimpleTreeCreator.cpp @@ -2,68 +2,76 @@ #include -namespace btInverseDynamics { +namespace btInverseDynamics +{ /// minimal "tree" (chain) -SimpleTreeCreator::SimpleTreeCreator(int dim) : m_num_bodies(dim) { - m_mass = 1.0; - m_body_T_parent_ref(0, 0) = 1; - m_body_T_parent_ref(0, 1) = 0; - m_body_T_parent_ref(0, 2) = 0; - m_body_T_parent_ref(1, 0) = 0; - m_body_T_parent_ref(1, 1) = 1; - m_body_T_parent_ref(1, 2) = 0; - m_body_T_parent_ref(2, 0) = 0; - m_body_T_parent_ref(2, 1) = 0; - m_body_T_parent_ref(2, 2) = 1; +SimpleTreeCreator::SimpleTreeCreator(int dim) : m_num_bodies(dim) +{ + m_mass = 1.0; + m_body_T_parent_ref(0, 0) = 1; + m_body_T_parent_ref(0, 1) = 0; + m_body_T_parent_ref(0, 2) = 0; + m_body_T_parent_ref(1, 0) = 0; + m_body_T_parent_ref(1, 1) = 1; + m_body_T_parent_ref(1, 2) = 0; + m_body_T_parent_ref(2, 0) = 0; + m_body_T_parent_ref(2, 1) = 0; + m_body_T_parent_ref(2, 2) = 1; - m_parent_r_parent_body_ref(0) = 1.0; - m_parent_r_parent_body_ref(1) = 0.0; - m_parent_r_parent_body_ref(2) = 0.0; + m_parent_r_parent_body_ref(0) = 1.0; + m_parent_r_parent_body_ref(1) = 0.0; + m_parent_r_parent_body_ref(2) = 0.0; - m_body_r_body_com(0) = 0.5; - m_body_r_body_com(1) = 0.0; - m_body_r_body_com(2) = 0.0; + m_body_r_body_com(0) = 0.5; + m_body_r_body_com(1) = 0.0; + m_body_r_body_com(2) = 0.0; - m_body_I_body(0, 0) = 1; - m_body_I_body(0, 1) = 0; - m_body_I_body(0, 2) = 0; - m_body_I_body(1, 0) = 0; - m_body_I_body(1, 1) = 1; - m_body_I_body(1, 2) = 0; - m_body_I_body(2, 0) = 0; - m_body_I_body(2, 1) = 0; - m_body_I_body(2, 2) = 1; + m_body_I_body(0, 0) = 1; + m_body_I_body(0, 1) = 0; + m_body_I_body(0, 2) = 0; + m_body_I_body(1, 0) = 0; + m_body_I_body(1, 1) = 1; + m_body_I_body(1, 2) = 0; + m_body_I_body(2, 0) = 0; + m_body_I_body(2, 1) = 0; + m_body_I_body(2, 2) = 1; - m_axis(0) = 0; - m_axis(1) = 0; - m_axis(2) = 1; + m_axis(0) = 0; + m_axis(1) = 0; + m_axis(2) = 1; } -int SimpleTreeCreator::getNumBodies(int* num_bodies) const { - *num_bodies = m_num_bodies; - return 0; +int SimpleTreeCreator::getNumBodies(int* num_bodies) const +{ + *num_bodies = m_num_bodies; + return 0; } int SimpleTreeCreator::getBody(const int body_index, int* parent_index, JointType* joint_type, - vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, - vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com, - mat33* body_I_body, int* user_int, void** user_ptr) const { - *parent_index = body_index - 1; - if (body_index % 2) { - *joint_type = PRISMATIC; - } else { - *joint_type = REVOLUTE; - } - *parent_r_parent_body_ref = m_parent_r_parent_body_ref; - if (0 == body_index) { - (*parent_r_parent_body_ref)(2) = 1.0; - } - *body_T_parent_ref = m_body_T_parent_ref; - *body_axis_of_motion = m_axis; - *mass = m_mass; - *body_r_body_com = m_body_r_body_com; - *body_I_body = m_body_I_body; - *user_int = 0; - *user_ptr = 0; - return 0; -} + vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, + vec3* body_axis_of_motion, idScalar* mass, vec3* body_r_body_com, + mat33* body_I_body, int* user_int, void** user_ptr) const +{ + *parent_index = body_index - 1; + if (body_index % 2) + { + *joint_type = PRISMATIC; + } + else + { + *joint_type = REVOLUTE; + } + *parent_r_parent_body_ref = m_parent_r_parent_body_ref; + if (0 == body_index) + { + (*parent_r_parent_body_ref)(2) = 1.0; + } + *body_T_parent_ref = m_body_T_parent_ref; + *body_axis_of_motion = m_axis; + *mass = m_mass; + *body_r_body_com = m_body_r_body_com; + *body_I_body = m_body_I_body; + *user_int = 0; + *user_ptr = 0; + return 0; } +} // namespace btInverseDynamics diff --git a/Extras/InverseDynamics/SimpleTreeCreator.hpp b/Extras/InverseDynamics/SimpleTreeCreator.hpp index f336eae72..00e83c3cd 100644 --- a/Extras/InverseDynamics/SimpleTreeCreator.hpp +++ b/Extras/InverseDynamics/SimpleTreeCreator.hpp @@ -3,32 +3,33 @@ #include "MultiBodyTreeCreator.hpp" -namespace btInverseDynamics { - +namespace btInverseDynamics +{ /// minimal "tree" (chain) -class SimpleTreeCreator : public MultiBodyTreeCreator { +class SimpleTreeCreator : public MultiBodyTreeCreator +{ public: - /// ctor - /// @param dim number of bodies - SimpleTreeCreator(int dim); - // dtor - ~SimpleTreeCreator() {} - ///\copydoc MultiBodyTreeCreator::getNumBodies - int getNumBodies(int* num_bodies) const; - ///\copydoc MultiBodyTreeCreator::getBody - int getBody(const int body_index, int* parent_index, JointType* joint_type, - vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, vec3* body_axis_of_motion, - idScalar* mass, vec3* body_r_body_com, mat33* body_I_body, int* user_int, - void** user_ptr) const; + /// ctor + /// @param dim number of bodies + SimpleTreeCreator(int dim); + // dtor + ~SimpleTreeCreator() {} + ///\copydoc MultiBodyTreeCreator::getNumBodies + int getNumBodies(int* num_bodies) const; + ///\copydoc MultiBodyTreeCreator::getBody + int getBody(const int body_index, int* parent_index, JointType* joint_type, + vec3* parent_r_parent_body_ref, mat33* body_T_parent_ref, vec3* body_axis_of_motion, + idScalar* mass, vec3* body_r_body_com, mat33* body_I_body, int* user_int, + void** user_ptr) const; private: - int m_num_bodies; - idScalar m_mass; - mat33 m_body_T_parent_ref; - vec3 m_parent_r_parent_body_ref; - vec3 m_body_r_body_com; - mat33 m_body_I_body; - vec3 m_axis; + int m_num_bodies; + idScalar m_mass; + mat33 m_body_T_parent_ref; + vec3 m_parent_r_parent_body_ref; + vec3 m_body_r_body_com; + mat33 m_body_I_body; + vec3 m_axis; }; -} +} // namespace btInverseDynamics #endif // SIMPLETREECREATOR_HPP_ diff --git a/Extras/InverseDynamics/User2InternalIndex.cpp b/Extras/InverseDynamics/User2InternalIndex.cpp index 76874bf70..2d8b096e4 100644 --- a/Extras/InverseDynamics/User2InternalIndex.cpp +++ b/Extras/InverseDynamics/User2InternalIndex.cpp @@ -1,99 +1,121 @@ #include "User2InternalIndex.hpp" -namespace btInverseDynamics { +namespace btInverseDynamics +{ User2InternalIndex::User2InternalIndex() : m_map_built(false) {} -void User2InternalIndex::addBody(const int body, const int parent) { - m_user_parent_index_map[body] = parent; +void User2InternalIndex::addBody(const int body, const int parent) +{ + m_user_parent_index_map[body] = parent; } -int User2InternalIndex::findRoot(int index) { - if (0 == m_user_parent_index_map.count(index)) { - return index; - } - return findRoot(m_user_parent_index_map[index]); +int User2InternalIndex::findRoot(int index) +{ + if (0 == m_user_parent_index_map.count(index)) + { + return index; + } + return findRoot(m_user_parent_index_map[index]); } // modelled after URDF2Bullet.cpp:void ComputeParentIndices(const // URDFImporterInterface& u2b, URDF2BulletCachedData& cache, int urdfLinkIndex, // int urdfParentIndex) -void User2InternalIndex::recurseIndexSets(const int user_body_index) { - m_user_to_internal[user_body_index] = m_current_index; - m_current_index++; - for (size_t i = 0; i < m_user_child_indices[user_body_index].size(); i++) { - recurseIndexSets(m_user_child_indices[user_body_index][i]); - } +void User2InternalIndex::recurseIndexSets(const int user_body_index) +{ + m_user_to_internal[user_body_index] = m_current_index; + m_current_index++; + for (size_t i = 0; i < m_user_child_indices[user_body_index].size(); i++) + { + recurseIndexSets(m_user_child_indices[user_body_index][i]); + } } -int User2InternalIndex::buildMapping() { - // find root index - int user_root_index = -1; - for (std::map::iterator it = m_user_parent_index_map.begin(); - it != m_user_parent_index_map.end(); it++) { - int current_root_index = findRoot(it->second); - if (it == m_user_parent_index_map.begin()) { - user_root_index = current_root_index; - } else { - if (user_root_index != current_root_index) { - bt_id_error_message("multiple roots (at least) %d and %d\n", user_root_index, - current_root_index); - return -1; - } - } - } +int User2InternalIndex::buildMapping() +{ + // find root index + int user_root_index = -1; + for (std::map::iterator it = m_user_parent_index_map.begin(); + it != m_user_parent_index_map.end(); it++) + { + int current_root_index = findRoot(it->second); + if (it == m_user_parent_index_map.begin()) + { + user_root_index = current_root_index; + } + else + { + if (user_root_index != current_root_index) + { + bt_id_error_message("multiple roots (at least) %d and %d\n", user_root_index, + current_root_index); + return -1; + } + } + } - // build child index map - for (std::map::iterator it = m_user_parent_index_map.begin(); - it != m_user_parent_index_map.end(); it++) { - m_user_child_indices[it->second].push_back(it->first); - } + // build child index map + for (std::map::iterator it = m_user_parent_index_map.begin(); + it != m_user_parent_index_map.end(); it++) + { + m_user_child_indices[it->second].push_back(it->first); + } - m_current_index = -1; - // build internal index set - m_user_to_internal[user_root_index] = -1; // add map for root link - recurseIndexSets(user_root_index); + m_current_index = -1; + // build internal index set + m_user_to_internal[user_root_index] = -1; // add map for root link + recurseIndexSets(user_root_index); - // reverse mapping - for (std::map::iterator it = m_user_to_internal.begin(); - it != m_user_to_internal.end(); it++) { - m_internal_to_user[it->second] = it->first; - } + // reverse mapping + for (std::map::iterator it = m_user_to_internal.begin(); + it != m_user_to_internal.end(); it++) + { + m_internal_to_user[it->second] = it->first; + } - m_map_built = true; - return 0; + m_map_built = true; + return 0; } -int User2InternalIndex::user2internal(const int user, int *internal) const { +int User2InternalIndex::user2internal(const int user, int *internal) const +{ + if (!m_map_built) + { + return -1; + } - if (!m_map_built) { - return -1; - } - - std::map::const_iterator it; - it = m_user_to_internal.find(user); - if (it != m_user_to_internal.end()) { - *internal = it->second; - return 0; - } else { - bt_id_error_message("no user index %d\n", user); - return -1; - } + std::map::const_iterator it; + it = m_user_to_internal.find(user); + if (it != m_user_to_internal.end()) + { + *internal = it->second; + return 0; + } + else + { + bt_id_error_message("no user index %d\n", user); + return -1; + } } -int User2InternalIndex::internal2user(const int internal, int *user) const { +int User2InternalIndex::internal2user(const int internal, int *user) const +{ + if (!m_map_built) + { + return -1; + } - if (!m_map_built) { - return -1; - } - - std::map::const_iterator it; - it = m_internal_to_user.find(internal); - if (it != m_internal_to_user.end()) { - *user = it->second; - return 0; - } else { - bt_id_error_message("no internal index %d\n", internal); - return -1; - } -} + std::map::const_iterator it; + it = m_internal_to_user.find(internal); + if (it != m_internal_to_user.end()) + { + *user = it->second; + return 0; + } + else + { + bt_id_error_message("no internal index %d\n", internal); + return -1; + } } +} // namespace btInverseDynamics diff --git a/Extras/InverseDynamics/User2InternalIndex.hpp b/Extras/InverseDynamics/User2InternalIndex.hpp index 06c7ef2aa..1ab519444 100644 --- a/Extras/InverseDynamics/User2InternalIndex.hpp +++ b/Extras/InverseDynamics/User2InternalIndex.hpp @@ -5,42 +5,43 @@ #include "BulletInverseDynamics/IDConfig.hpp" -namespace btInverseDynamics { - +namespace btInverseDynamics +{ /// Convert arbitrary indexing scheme to internal indexing /// used for MultiBodyTree -class User2InternalIndex { +class User2InternalIndex +{ public: - /// Ctor - User2InternalIndex(); - /// add body to index maps - /// @param body index of body to add (external) - /// @param parent index of parent body (external) - void addBody(const int body, const int parent); - /// build mapping from external to internal indexing - /// @return 0 on success, -1 on failure - int buildMapping(); - /// get internal index from external index - /// @param user external (user) index - /// @param internal pointer for storage of corresponding internal index - /// @return 0 on success, -1 on failure - int user2internal(const int user, int *internal) const; - /// get internal index from external index - /// @param user external (user) index - /// @param internal pointer for storage of corresponding internal index - /// @return 0 on success, -1 on failure - int internal2user(const int internal, int *user) const; + /// Ctor + User2InternalIndex(); + /// add body to index maps + /// @param body index of body to add (external) + /// @param parent index of parent body (external) + void addBody(const int body, const int parent); + /// build mapping from external to internal indexing + /// @return 0 on success, -1 on failure + int buildMapping(); + /// get internal index from external index + /// @param user external (user) index + /// @param internal pointer for storage of corresponding internal index + /// @return 0 on success, -1 on failure + int user2internal(const int user, int *internal) const; + /// get internal index from external index + /// @param user external (user) index + /// @param internal pointer for storage of corresponding internal index + /// @return 0 on success, -1 on failure + int internal2user(const int internal, int *user) const; private: - int findRoot(int index); - void recurseIndexSets(const int user_body_index); - bool m_map_built; - std::map m_user_parent_index_map; - std::map m_user_to_internal; - std::map m_internal_to_user; - std::map > m_user_child_indices; - int m_current_index; + int findRoot(int index); + void recurseIndexSets(const int user_body_index); + bool m_map_built; + std::map m_user_parent_index_map; + std::map m_user_to_internal; + std::map m_internal_to_user; + std::map > m_user_child_indices; + int m_current_index; }; -} +} // namespace btInverseDynamics #endif // USER2INTERNALINDEX_HPP diff --git a/Extras/InverseDynamics/btMultiBodyFromURDF.hpp b/Extras/InverseDynamics/btMultiBodyFromURDF.hpp index 444a7134e..5eab2b4f9 100644 --- a/Extras/InverseDynamics/btMultiBodyFromURDF.hpp +++ b/Extras/InverseDynamics/btMultiBodyFromURDF.hpp @@ -14,78 +14,84 @@ /// Create a btMultiBody model from URDF. /// This is adapted from Bullet URDF loader example -class MyBtMultiBodyFromURDF { +class MyBtMultiBodyFromURDF +{ public: - /// ctor - /// @param gravity gravitational acceleration (in world frame) - /// @param base_fixed if true, the root body is treated as fixed, - /// if false, it is treated as floating - MyBtMultiBodyFromURDF(const btVector3 &gravity, const bool base_fixed) - : m_gravity(gravity), m_base_fixed(base_fixed) { - m_broadphase = 0x0; - m_dispatcher = 0x0; - m_solver = 0x0; - m_collisionConfiguration = 0x0; - m_dynamicsWorld = 0x0; - m_multibody = 0x0; - } - /// dtor - ~MyBtMultiBodyFromURDF() { - delete m_dynamicsWorld; - delete m_solver; - delete m_broadphase; - delete m_dispatcher; - delete m_collisionConfiguration; - delete m_multibody; - } - /// @param name path to urdf file - void setFileName(const std::string name) { m_filename = name; } - /// load urdf file and build btMultiBody model - void init() { - this->createEmptyDynamicsWorld(); - m_dynamicsWorld->setGravity(m_gravity); - BulletURDFImporter urdf_importer(&m_nogfx,0,1,0); - URDFImporterInterface &u2b(urdf_importer); - bool loadOk = u2b.loadURDF(m_filename.c_str(), m_base_fixed); + /// ctor + /// @param gravity gravitational acceleration (in world frame) + /// @param base_fixed if true, the root body is treated as fixed, + /// if false, it is treated as floating + MyBtMultiBodyFromURDF(const btVector3 &gravity, const bool base_fixed) + : m_gravity(gravity), m_base_fixed(base_fixed) + { + m_broadphase = 0x0; + m_dispatcher = 0x0; + m_solver = 0x0; + m_collisionConfiguration = 0x0; + m_dynamicsWorld = 0x0; + m_multibody = 0x0; + } + /// dtor + ~MyBtMultiBodyFromURDF() + { + delete m_dynamicsWorld; + delete m_solver; + delete m_broadphase; + delete m_dispatcher; + delete m_collisionConfiguration; + delete m_multibody; + } + /// @param name path to urdf file + void setFileName(const std::string name) { m_filename = name; } + /// load urdf file and build btMultiBody model + void init() + { + this->createEmptyDynamicsWorld(); + m_dynamicsWorld->setGravity(m_gravity); + BulletURDFImporter urdf_importer(&m_nogfx, 0, 1, 0); + URDFImporterInterface &u2b(urdf_importer); + bool loadOk = u2b.loadURDF(m_filename.c_str(), m_base_fixed); - if (loadOk) { - btTransform identityTrans; - identityTrans.setIdentity(); - MyMultiBodyCreator creation(&m_nogfx); - const bool use_multibody = true; - ConvertURDF2Bullet(u2b, creation, identityTrans, m_dynamicsWorld, use_multibody, - u2b.getPathPrefix()); - m_multibody = creation.getBulletMultiBody(); - m_dynamicsWorld->stepSimulation(1. / 240., 0); - } - } - /// @return pointer to the btMultiBody model - btMultiBody *getBtMultiBody() { return m_multibody; } + if (loadOk) + { + btTransform identityTrans; + identityTrans.setIdentity(); + MyMultiBodyCreator creation(&m_nogfx); + const bool use_multibody = true; + ConvertURDF2Bullet(u2b, creation, identityTrans, m_dynamicsWorld, use_multibody, + u2b.getPathPrefix()); + m_multibody = creation.getBulletMultiBody(); + m_dynamicsWorld->stepSimulation(1. / 240., 0); + } + } + /// @return pointer to the btMultiBody model + btMultiBody *getBtMultiBody() { return m_multibody; } private: - // internal utility function - void createEmptyDynamicsWorld() { - m_collisionConfiguration = new btDefaultCollisionConfiguration(); + // internal utility function + void createEmptyDynamicsWorld() + { + m_collisionConfiguration = new btDefaultCollisionConfiguration(); - /// use the default collision dispatcher. For parallel processing you can use a diffent - /// dispatcher (see Extras/BulletMultiThreaded) - m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); - m_broadphase = new btDbvtBroadphase(); - m_solver = new btMultiBodyConstraintSolver; - m_dynamicsWorld = new btMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, m_solver, - m_collisionConfiguration); - m_dynamicsWorld->setGravity(m_gravity); - } + /// use the default collision dispatcher. For parallel processing you can use a diffent + /// dispatcher (see Extras/BulletMultiThreaded) + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + m_broadphase = new btDbvtBroadphase(); + m_solver = new btMultiBodyConstraintSolver; + m_dynamicsWorld = new btMultiBodyDynamicsWorld(m_dispatcher, m_broadphase, m_solver, + m_collisionConfiguration); + m_dynamicsWorld->setGravity(m_gravity); + } - btBroadphaseInterface *m_broadphase; - btCollisionDispatcher *m_dispatcher; - btMultiBodyConstraintSolver *m_solver; - btDefaultCollisionConfiguration *m_collisionConfiguration; - btMultiBodyDynamicsWorld *m_dynamicsWorld; - std::string m_filename; - DummyGUIHelper m_nogfx; - btMultiBody *m_multibody; - const btVector3 m_gravity; - const bool m_base_fixed; + btBroadphaseInterface *m_broadphase; + btCollisionDispatcher *m_dispatcher; + btMultiBodyConstraintSolver *m_solver; + btDefaultCollisionConfiguration *m_collisionConfiguration; + btMultiBodyDynamicsWorld *m_dynamicsWorld; + std::string m_filename; + DummyGUIHelper m_nogfx; + btMultiBody *m_multibody; + const btVector3 m_gravity; + const bool m_base_fixed; }; #endif // BTMULTIBODYFROMURDF_HPP diff --git a/Extras/InverseDynamics/btMultiBodyTreeCreator.cpp b/Extras/InverseDynamics/btMultiBodyTreeCreator.cpp index 1b32df617..d70e28220 100644 --- a/Extras/InverseDynamics/btMultiBodyTreeCreator.cpp +++ b/Extras/InverseDynamics/btMultiBodyTreeCreator.cpp @@ -1,272 +1,299 @@ #include "btMultiBodyTreeCreator.hpp" -namespace btInverseDynamics { - +namespace btInverseDynamics +{ btMultiBodyTreeCreator::btMultiBodyTreeCreator() : m_initialized(false) {} -int btMultiBodyTreeCreator::createFromBtMultiBody(const btMultiBody *btmb, const bool verbose) { - if (0x0 == btmb) { - bt_id_error_message("cannot create MultiBodyTree from null pointer\n"); - return -1; - } +int btMultiBodyTreeCreator::createFromBtMultiBody(const btMultiBody *btmb, const bool verbose) +{ + if (0x0 == btmb) + { + bt_id_error_message("cannot create MultiBodyTree from null pointer\n"); + return -1; + } - // in case this is a second call, discard old data - m_data.clear(); - m_initialized = false; + // in case this is a second call, discard old data + m_data.clear(); + m_initialized = false; - // btMultiBody treats base link separately - m_data.resize(1 + btmb->getNumLinks()); + // btMultiBody treats base link separately + m_data.resize(1 + btmb->getNumLinks()); - // add base link data - { - LinkData &link = m_data[0]; + // add base link data + { + LinkData &link = m_data[0]; - link.parent_index = -1; - if (btmb->hasFixedBase()) { - link.joint_type = FIXED; - } else { - link.joint_type = FLOATING; - } - btTransform transform=(btmb->getBaseWorldTransform()); + link.parent_index = -1; + if (btmb->hasFixedBase()) + { + link.joint_type = FIXED; + } + else + { + link.joint_type = FLOATING; + } + btTransform transform = (btmb->getBaseWorldTransform()); //compute inverse dynamics in body-fixed frame transform.setIdentity(); - link.parent_r_parent_body_ref(0) = transform.getOrigin()[0]; - link.parent_r_parent_body_ref(1) = transform.getOrigin()[1]; - link.parent_r_parent_body_ref(2) = transform.getOrigin()[2]; + link.parent_r_parent_body_ref(0) = transform.getOrigin()[0]; + link.parent_r_parent_body_ref(1) = transform.getOrigin()[1]; + link.parent_r_parent_body_ref(2) = transform.getOrigin()[2]; - link.body_T_parent_ref(0, 0) = transform.getBasis()[0][0]; - link.body_T_parent_ref(0, 1) = transform.getBasis()[0][1]; - link.body_T_parent_ref(0, 2) = transform.getBasis()[0][2]; + link.body_T_parent_ref(0, 0) = transform.getBasis()[0][0]; + link.body_T_parent_ref(0, 1) = transform.getBasis()[0][1]; + link.body_T_parent_ref(0, 2) = transform.getBasis()[0][2]; - link.body_T_parent_ref(1, 0) = transform.getBasis()[1][0]; - link.body_T_parent_ref(1, 1) = transform.getBasis()[1][1]; - link.body_T_parent_ref(1, 2) = transform.getBasis()[1][2]; + link.body_T_parent_ref(1, 0) = transform.getBasis()[1][0]; + link.body_T_parent_ref(1, 1) = transform.getBasis()[1][1]; + link.body_T_parent_ref(1, 2) = transform.getBasis()[1][2]; - link.body_T_parent_ref(2, 0) = transform.getBasis()[2][0]; - link.body_T_parent_ref(2, 1) = transform.getBasis()[2][1]; - link.body_T_parent_ref(2, 2) = transform.getBasis()[2][2]; + link.body_T_parent_ref(2, 0) = transform.getBasis()[2][0]; + link.body_T_parent_ref(2, 1) = transform.getBasis()[2][1]; + link.body_T_parent_ref(2, 2) = transform.getBasis()[2][2]; - // random unit vector. value not used for fixed or floating joints. - link.body_axis_of_motion(0) = 0; - link.body_axis_of_motion(1) = 0; - link.body_axis_of_motion(2) = 1; + // random unit vector. value not used for fixed or floating joints. + link.body_axis_of_motion(0) = 0; + link.body_axis_of_motion(1) = 0; + link.body_axis_of_motion(2) = 1; - link.mass = btmb->getBaseMass(); - // link frame in the center of mass - link.body_r_body_com(0) = 0; - link.body_r_body_com(1) = 0; - link.body_r_body_com(2) = 0; - // BulletDynamics uses body-fixed frame in the cog, aligned with principal axes - link.body_I_body(0, 0) = btmb->getBaseInertia()[0]; - link.body_I_body(0, 1) = 0.0; - link.body_I_body(0, 2) = 0.0; - link.body_I_body(1, 0) = 0.0; - link.body_I_body(1, 1) = btmb->getBaseInertia()[1]; - link.body_I_body(1, 2) = 0.0; - link.body_I_body(2, 0) = 0.0; - link.body_I_body(2, 1) = 0.0; - link.body_I_body(2, 2) = btmb->getBaseInertia()[2]; - // shift reference point to link origin (in joint axis) - mat33 tilde_r_com = tildeOperator(link.body_r_body_com); - link.body_I_body = link.body_I_body - link.mass * tilde_r_com * tilde_r_com; - if (verbose) { - id_printf("base: mass= %f, bt_inertia= [%f %f %f]\n" - "Io= [%f %f %f;\n" - " %f %f %f;\n" - " %f %f %f]\n", - link.mass, btmb->getBaseInertia()[0], btmb->getBaseInertia()[1], - btmb->getBaseInertia()[2], link.body_I_body(0, 0), link.body_I_body(0, 1), - link.body_I_body(0, 2), link.body_I_body(1, 0), link.body_I_body(1, 1), - link.body_I_body(1, 2), link.body_I_body(2, 0), link.body_I_body(2, 1), - link.body_I_body(2, 2)); - } - } + link.mass = btmb->getBaseMass(); + // link frame in the center of mass + link.body_r_body_com(0) = 0; + link.body_r_body_com(1) = 0; + link.body_r_body_com(2) = 0; + // BulletDynamics uses body-fixed frame in the cog, aligned with principal axes + link.body_I_body(0, 0) = btmb->getBaseInertia()[0]; + link.body_I_body(0, 1) = 0.0; + link.body_I_body(0, 2) = 0.0; + link.body_I_body(1, 0) = 0.0; + link.body_I_body(1, 1) = btmb->getBaseInertia()[1]; + link.body_I_body(1, 2) = 0.0; + link.body_I_body(2, 0) = 0.0; + link.body_I_body(2, 1) = 0.0; + link.body_I_body(2, 2) = btmb->getBaseInertia()[2]; + // shift reference point to link origin (in joint axis) + mat33 tilde_r_com = tildeOperator(link.body_r_body_com); + link.body_I_body = link.body_I_body - link.mass * tilde_r_com * tilde_r_com; + if (verbose) + { + id_printf( + "base: mass= %f, bt_inertia= [%f %f %f]\n" + "Io= [%f %f %f;\n" + " %f %f %f;\n" + " %f %f %f]\n", + link.mass, btmb->getBaseInertia()[0], btmb->getBaseInertia()[1], + btmb->getBaseInertia()[2], link.body_I_body(0, 0), link.body_I_body(0, 1), + link.body_I_body(0, 2), link.body_I_body(1, 0), link.body_I_body(1, 1), + link.body_I_body(1, 2), link.body_I_body(2, 0), link.body_I_body(2, 1), + link.body_I_body(2, 2)); + } + } - for (int bt_index = 0; bt_index < btmb->getNumLinks(); bt_index++) { - if (verbose) { - id_printf("bt->id: converting link %d\n", bt_index); - } - const btMultibodyLink &bt_link = btmb->getLink(bt_index); - LinkData &link = m_data[bt_index + 1]; + for (int bt_index = 0; bt_index < btmb->getNumLinks(); bt_index++) + { + if (verbose) + { + id_printf("bt->id: converting link %d\n", bt_index); + } + const btMultibodyLink &bt_link = btmb->getLink(bt_index); + LinkData &link = m_data[bt_index + 1]; - link.parent_index = bt_link.m_parent + 1; + link.parent_index = bt_link.m_parent + 1; - link.mass = bt_link.m_mass; - if (verbose) { - id_printf("mass= %f\n", link.mass); - } - // from this body's pivot to this body's com in this body's frame - link.body_r_body_com[0] = bt_link.m_dVector[0]; - link.body_r_body_com[1] = bt_link.m_dVector[1]; - link.body_r_body_com[2] = bt_link.m_dVector[2]; - if (verbose) { - id_printf("com= %f %f %f\n", link.body_r_body_com[0], link.body_r_body_com[1], - link.body_r_body_com[2]); - } - // BulletDynamics uses a body-fixed frame in the CoM, aligned with principal axes - link.body_I_body(0, 0) = bt_link.m_inertiaLocal[0]; - link.body_I_body(0, 1) = 0.0; - link.body_I_body(0, 2) = 0.0; - link.body_I_body(1, 0) = 0.0; - link.body_I_body(1, 1) = bt_link.m_inertiaLocal[1]; - link.body_I_body(1, 2) = 0.0; - link.body_I_body(2, 0) = 0.0; - link.body_I_body(2, 1) = 0.0; - link.body_I_body(2, 2) = bt_link.m_inertiaLocal[2]; - // shift reference point to link origin (in joint axis) - mat33 tilde_r_com = tildeOperator(link.body_r_body_com); - link.body_I_body = link.body_I_body - link.mass * tilde_r_com * tilde_r_com; + link.mass = bt_link.m_mass; + if (verbose) + { + id_printf("mass= %f\n", link.mass); + } + // from this body's pivot to this body's com in this body's frame + link.body_r_body_com[0] = bt_link.m_dVector[0]; + link.body_r_body_com[1] = bt_link.m_dVector[1]; + link.body_r_body_com[2] = bt_link.m_dVector[2]; + if (verbose) + { + id_printf("com= %f %f %f\n", link.body_r_body_com[0], link.body_r_body_com[1], + link.body_r_body_com[2]); + } + // BulletDynamics uses a body-fixed frame in the CoM, aligned with principal axes + link.body_I_body(0, 0) = bt_link.m_inertiaLocal[0]; + link.body_I_body(0, 1) = 0.0; + link.body_I_body(0, 2) = 0.0; + link.body_I_body(1, 0) = 0.0; + link.body_I_body(1, 1) = bt_link.m_inertiaLocal[1]; + link.body_I_body(1, 2) = 0.0; + link.body_I_body(2, 0) = 0.0; + link.body_I_body(2, 1) = 0.0; + link.body_I_body(2, 2) = bt_link.m_inertiaLocal[2]; + // shift reference point to link origin (in joint axis) + mat33 tilde_r_com = tildeOperator(link.body_r_body_com); + link.body_I_body = link.body_I_body - link.mass * tilde_r_com * tilde_r_com; - if (verbose) { - id_printf("link %d: mass= %f, bt_inertia= [%f %f %f]\n" - "Io= [%f %f %f;\n" - " %f %f %f;\n" - " %f %f %f]\n", - bt_index, link.mass, bt_link.m_inertiaLocal[0], bt_link.m_inertiaLocal[1], - bt_link.m_inertiaLocal[2], link.body_I_body(0, 0), link.body_I_body(0, 1), - link.body_I_body(0, 2), link.body_I_body(1, 0), link.body_I_body(1, 1), - link.body_I_body(1, 2), link.body_I_body(2, 0), link.body_I_body(2, 1), - link.body_I_body(2, 2)); - } - // transform for vectors written in parent frame to this link's body-fixed frame - btMatrix3x3 basis = btTransform(bt_link.m_zeroRotParentToThis).getBasis(); - link.body_T_parent_ref(0, 0) = basis[0][0]; - link.body_T_parent_ref(0, 1) = basis[0][1]; - link.body_T_parent_ref(0, 2) = basis[0][2]; - link.body_T_parent_ref(1, 0) = basis[1][0]; - link.body_T_parent_ref(1, 1) = basis[1][1]; - link.body_T_parent_ref(1, 2) = basis[1][2]; - link.body_T_parent_ref(2, 0) = basis[2][0]; - link.body_T_parent_ref(2, 1) = basis[2][1]; - link.body_T_parent_ref(2, 2) = basis[2][2]; - if (verbose) { - id_printf("body_T_parent_ref= %f %f %f\n" - " %f %f %f\n" - " %f %f %f\n", - basis[0][0], basis[0][1], basis[0][2], basis[1][0], basis[1][1], basis[1][2], - basis[2][0], basis[2][1], basis[2][2]); - } - switch (bt_link.m_jointType) { - case btMultibodyLink::eRevolute: - link.joint_type = REVOLUTE; - if (verbose) { - id_printf("type= revolute\n"); - } - link.body_axis_of_motion(0) = bt_link.m_axes[0].m_topVec[0]; - link.body_axis_of_motion(1) = bt_link.m_axes[0].m_topVec[1]; - link.body_axis_of_motion(2) = bt_link.m_axes[0].m_topVec[2]; + if (verbose) + { + id_printf( + "link %d: mass= %f, bt_inertia= [%f %f %f]\n" + "Io= [%f %f %f;\n" + " %f %f %f;\n" + " %f %f %f]\n", + bt_index, link.mass, bt_link.m_inertiaLocal[0], bt_link.m_inertiaLocal[1], + bt_link.m_inertiaLocal[2], link.body_I_body(0, 0), link.body_I_body(0, 1), + link.body_I_body(0, 2), link.body_I_body(1, 0), link.body_I_body(1, 1), + link.body_I_body(1, 2), link.body_I_body(2, 0), link.body_I_body(2, 1), + link.body_I_body(2, 2)); + } + // transform for vectors written in parent frame to this link's body-fixed frame + btMatrix3x3 basis = btTransform(bt_link.m_zeroRotParentToThis).getBasis(); + link.body_T_parent_ref(0, 0) = basis[0][0]; + link.body_T_parent_ref(0, 1) = basis[0][1]; + link.body_T_parent_ref(0, 2) = basis[0][2]; + link.body_T_parent_ref(1, 0) = basis[1][0]; + link.body_T_parent_ref(1, 1) = basis[1][1]; + link.body_T_parent_ref(1, 2) = basis[1][2]; + link.body_T_parent_ref(2, 0) = basis[2][0]; + link.body_T_parent_ref(2, 1) = basis[2][1]; + link.body_T_parent_ref(2, 2) = basis[2][2]; + if (verbose) + { + id_printf( + "body_T_parent_ref= %f %f %f\n" + " %f %f %f\n" + " %f %f %f\n", + basis[0][0], basis[0][1], basis[0][2], basis[1][0], basis[1][1], basis[1][2], + basis[2][0], basis[2][1], basis[2][2]); + } + switch (bt_link.m_jointType) + { + case btMultibodyLink::eRevolute: + link.joint_type = REVOLUTE; + if (verbose) + { + id_printf("type= revolute\n"); + } + link.body_axis_of_motion(0) = bt_link.m_axes[0].m_topVec[0]; + link.body_axis_of_motion(1) = bt_link.m_axes[0].m_topVec[1]; + link.body_axis_of_motion(2) = bt_link.m_axes[0].m_topVec[2]; - // for revolute joints, m_eVector = parentComToThisPivotOffset - // m_dVector = thisPivotToThisComOffset - // from parent com to pivot, in parent frame - link.parent_r_parent_body_ref(0) = bt_link.m_eVector[0]; - link.parent_r_parent_body_ref(1) = bt_link.m_eVector[1]; - link.parent_r_parent_body_ref(2) = bt_link.m_eVector[2]; - break; - case btMultibodyLink::ePrismatic: - link.joint_type = PRISMATIC; - if (verbose) { - id_printf("type= prismatic\n"); - } - link.body_axis_of_motion(0) = bt_link.m_axes[0].m_bottomVec[0]; - link.body_axis_of_motion(1) = bt_link.m_axes[0].m_bottomVec[1]; - link.body_axis_of_motion(2) = bt_link.m_axes[0].m_bottomVec[2]; + // for revolute joints, m_eVector = parentComToThisPivotOffset + // m_dVector = thisPivotToThisComOffset + // from parent com to pivot, in parent frame + link.parent_r_parent_body_ref(0) = bt_link.m_eVector[0]; + link.parent_r_parent_body_ref(1) = bt_link.m_eVector[1]; + link.parent_r_parent_body_ref(2) = bt_link.m_eVector[2]; + break; + case btMultibodyLink::ePrismatic: + link.joint_type = PRISMATIC; + if (verbose) + { + id_printf("type= prismatic\n"); + } + link.body_axis_of_motion(0) = bt_link.m_axes[0].m_bottomVec[0]; + link.body_axis_of_motion(1) = bt_link.m_axes[0].m_bottomVec[1]; + link.body_axis_of_motion(2) = bt_link.m_axes[0].m_bottomVec[2]; - // for prismatic joints, eVector - // according to documentation : - // parentComToThisComOffset - // but seems to be: from parent's com to parent's - // pivot ?? - // m_dVector = thisPivotToThisComOffset - link.parent_r_parent_body_ref(0) = bt_link.m_eVector[0]; - link.parent_r_parent_body_ref(1) = bt_link.m_eVector[1]; - link.parent_r_parent_body_ref(2) = bt_link.m_eVector[2]; - break; - case btMultibodyLink::eSpherical: - bt_id_error_message("spherical joints not implemented\n"); - return -1; - case btMultibodyLink::ePlanar: - bt_id_error_message("planar joints not implemented\n"); - return -1; - case btMultibodyLink::eFixed: - link.joint_type = FIXED; - // random unit vector - link.body_axis_of_motion(0) = 0; - link.body_axis_of_motion(1) = 0; - link.body_axis_of_motion(2) = 1; + // for prismatic joints, eVector + // according to documentation : + // parentComToThisComOffset + // but seems to be: from parent's com to parent's + // pivot ?? + // m_dVector = thisPivotToThisComOffset + link.parent_r_parent_body_ref(0) = bt_link.m_eVector[0]; + link.parent_r_parent_body_ref(1) = bt_link.m_eVector[1]; + link.parent_r_parent_body_ref(2) = bt_link.m_eVector[2]; + break; + case btMultibodyLink::eSpherical: + bt_id_error_message("spherical joints not implemented\n"); + return -1; + case btMultibodyLink::ePlanar: + bt_id_error_message("planar joints not implemented\n"); + return -1; + case btMultibodyLink::eFixed: + link.joint_type = FIXED; + // random unit vector + link.body_axis_of_motion(0) = 0; + link.body_axis_of_motion(1) = 0; + link.body_axis_of_motion(2) = 1; - // for fixed joints, m_dVector = thisPivotToThisComOffset; - // m_eVector = parentComToThisPivotOffset; - link.parent_r_parent_body_ref(0) = bt_link.m_eVector[0]; - link.parent_r_parent_body_ref(1) = bt_link.m_eVector[1]; - link.parent_r_parent_body_ref(2) = bt_link.m_eVector[2]; - break; - default: - bt_id_error_message("unknown btMultiBody::eFeatherstoneJointType %d\n", - bt_link.m_jointType); - return -1; - } - if (link.parent_index > 0) { // parent body isn't the root - const btMultibodyLink &bt_parent_link = btmb->getLink(link.parent_index - 1); - // from parent pivot to parent com, in parent frame - link.parent_r_parent_body_ref(0) += bt_parent_link.m_dVector[0]; - link.parent_r_parent_body_ref(1) += bt_parent_link.m_dVector[1]; - link.parent_r_parent_body_ref(2) += bt_parent_link.m_dVector[2]; - } else { - // parent is root body. btMultiBody only knows 6-DoF or 0-DoF root bodies, - // whose link frame is in the CoM (ie, no notion of a pivot point) - } + // for fixed joints, m_dVector = thisPivotToThisComOffset; + // m_eVector = parentComToThisPivotOffset; + link.parent_r_parent_body_ref(0) = bt_link.m_eVector[0]; + link.parent_r_parent_body_ref(1) = bt_link.m_eVector[1]; + link.parent_r_parent_body_ref(2) = bt_link.m_eVector[2]; + break; + default: + bt_id_error_message("unknown btMultiBody::eFeatherstoneJointType %d\n", + bt_link.m_jointType); + return -1; + } + if (link.parent_index > 0) + { // parent body isn't the root + const btMultibodyLink &bt_parent_link = btmb->getLink(link.parent_index - 1); + // from parent pivot to parent com, in parent frame + link.parent_r_parent_body_ref(0) += bt_parent_link.m_dVector[0]; + link.parent_r_parent_body_ref(1) += bt_parent_link.m_dVector[1]; + link.parent_r_parent_body_ref(2) += bt_parent_link.m_dVector[2]; + } + else + { + // parent is root body. btMultiBody only knows 6-DoF or 0-DoF root bodies, + // whose link frame is in the CoM (ie, no notion of a pivot point) + } - if (verbose) { - id_printf("parent_r_parent_body_ref= %f %f %f\n", link.parent_r_parent_body_ref[0], - link.parent_r_parent_body_ref[1], link.parent_r_parent_body_ref[2]); - } - } + if (verbose) + { + id_printf("parent_r_parent_body_ref= %f %f %f\n", link.parent_r_parent_body_ref[0], + link.parent_r_parent_body_ref[1], link.parent_r_parent_body_ref[2]); + } + } - m_initialized = true; + m_initialized = true; - return 0; + return 0; } -int btMultiBodyTreeCreator::getNumBodies(int *num_bodies) const { - if (false == m_initialized) { - bt_id_error_message("btMultiBody not converted yet\n"); - return -1; - } +int btMultiBodyTreeCreator::getNumBodies(int *num_bodies) const +{ + if (false == m_initialized) + { + bt_id_error_message("btMultiBody not converted yet\n"); + return -1; + } - *num_bodies = static_cast(m_data.size()); - return 0; + *num_bodies = static_cast(m_data.size()); + return 0; } int btMultiBodyTreeCreator::getBody(const int body_index, int *parent_index, JointType *joint_type, - vec3 *parent_r_parent_body_ref, mat33 *body_T_parent_ref, - vec3 *body_axis_of_motion, idScalar *mass, - vec3 *body_r_body_com, mat33 *body_I_body, int *user_int, - void **user_ptr) const { - if (false == m_initialized) { - bt_id_error_message("MultiBodyTree not created yet\n"); - return -1; - } + vec3 *parent_r_parent_body_ref, mat33 *body_T_parent_ref, + vec3 *body_axis_of_motion, idScalar *mass, + vec3 *body_r_body_com, mat33 *body_I_body, int *user_int, + void **user_ptr) const +{ + if (false == m_initialized) + { + bt_id_error_message("MultiBodyTree not created yet\n"); + return -1; + } - if (body_index < 0 || body_index >= static_cast(m_data.size())) { - bt_id_error_message("index out of range (got %d but only %zu bodies)\n", body_index, - m_data.size()); - return -1; - } + if (body_index < 0 || body_index >= static_cast(m_data.size())) + { + bt_id_error_message("index out of range (got %d but only %zu bodies)\n", body_index, + m_data.size()); + return -1; + } - *parent_index = m_data[body_index].parent_index; - *joint_type = m_data[body_index].joint_type; - *parent_r_parent_body_ref = m_data[body_index].parent_r_parent_body_ref; - *body_T_parent_ref = m_data[body_index].body_T_parent_ref; - *body_axis_of_motion = m_data[body_index].body_axis_of_motion; - *mass = m_data[body_index].mass; - *body_r_body_com = m_data[body_index].body_r_body_com; - *body_I_body = m_data[body_index].body_I_body; + *parent_index = m_data[body_index].parent_index; + *joint_type = m_data[body_index].joint_type; + *parent_r_parent_body_ref = m_data[body_index].parent_r_parent_body_ref; + *body_T_parent_ref = m_data[body_index].body_T_parent_ref; + *body_axis_of_motion = m_data[body_index].body_axis_of_motion; + *mass = m_data[body_index].mass; + *body_r_body_com = m_data[body_index].body_r_body_com; + *body_I_body = m_data[body_index].body_I_body; - *user_int = -1; - *user_ptr = 0x0; + *user_int = -1; + *user_ptr = 0x0; - return 0; -} + return 0; } +} // namespace btInverseDynamics diff --git a/Extras/InverseDynamics/btMultiBodyTreeCreator.hpp b/Extras/InverseDynamics/btMultiBodyTreeCreator.hpp index dbc82ab3f..818c04e67 100644 --- a/Extras/InverseDynamics/btMultiBodyTreeCreator.hpp +++ b/Extras/InverseDynamics/btMultiBodyTreeCreator.hpp @@ -7,44 +7,46 @@ #include "MultiBodyTreeCreator.hpp" #include "BulletDynamics/Featherstone/btMultiBody.h" -namespace btInverseDynamics { - +namespace btInverseDynamics +{ /// MultiBodyTreeCreator implementation for converting /// a btMultiBody forward dynamics model into a MultiBodyTree inverse dynamics model -class btMultiBodyTreeCreator : public MultiBodyTreeCreator { +class btMultiBodyTreeCreator : public MultiBodyTreeCreator +{ public: - /// ctor - btMultiBodyTreeCreator(); - /// dtor - ~btMultiBodyTreeCreator() {} - /// extract model data from a btMultiBody - /// @param btmb pointer to btMultiBody to convert - /// @param verbose if true, some information is printed - /// @return -1 on error, 0 on success - int createFromBtMultiBody(const btMultiBody *btmb, const bool verbose = false); - /// \copydoc MultiBodyTreeCreator::getNumBodies - int getNumBodies(int *num_bodies) const; - ///\copydoc MultiBodyTreeCreator::getBody + /// ctor + btMultiBodyTreeCreator(); + /// dtor + ~btMultiBodyTreeCreator() {} + /// extract model data from a btMultiBody + /// @param btmb pointer to btMultiBody to convert + /// @param verbose if true, some information is printed + /// @return -1 on error, 0 on success + int createFromBtMultiBody(const btMultiBody *btmb, const bool verbose = false); + /// \copydoc MultiBodyTreeCreator::getNumBodies + int getNumBodies(int *num_bodies) const; + ///\copydoc MultiBodyTreeCreator::getBody int getBody(const int body_index, int *parent_index, JointType *joint_type, - vec3 *parent_r_parent_body_ref, mat33 *body_T_parent_ref, - vec3 *body_axis_of_motion, idScalar *mass, vec3 *body_r_body_com, - mat33 *body_I_body, int *user_int, void **user_ptr) const; + vec3 *parent_r_parent_body_ref, mat33 *body_T_parent_ref, + vec3 *body_axis_of_motion, idScalar *mass, vec3 *body_r_body_com, + mat33 *body_I_body, int *user_int, void **user_ptr) const; private: - // internal struct holding data extracted from btMultiBody - struct LinkData { - int parent_index; - JointType joint_type; - vec3 parent_r_parent_body_ref; - mat33 body_T_parent_ref; - vec3 body_axis_of_motion; - idScalar mass; - vec3 body_r_body_com; - mat33 body_I_body; - }; - idArray::type m_data; - bool m_initialized; + // internal struct holding data extracted from btMultiBody + struct LinkData + { + int parent_index; + JointType joint_type; + vec3 parent_r_parent_body_ref; + mat33 body_T_parent_ref; + vec3 body_axis_of_motion; + idScalar mass; + vec3 body_r_body_com; + mat33 body_I_body; + }; + idArray::type m_data; + bool m_initialized; }; -} +} // namespace btInverseDynamics #endif // BTMULTIBODYTREECREATOR_HPP_ diff --git a/Extras/InverseDynamics/invdyn_bullet_comparison.cpp b/Extras/InverseDynamics/invdyn_bullet_comparison.cpp index 4187e134b..ffa2a8e07 100644 --- a/Extras/InverseDynamics/invdyn_bullet_comparison.cpp +++ b/Extras/InverseDynamics/invdyn_bullet_comparison.cpp @@ -8,300 +8,354 @@ #include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" #include "BulletDynamics/Featherstone/btMultiBodyPoint2Point.h" -namespace btInverseDynamics { +namespace btInverseDynamics +{ int compareInverseAndForwardDynamics(vecx &q, vecx &u, vecx &dot_u, btVector3 &gravity, bool verbose, - btMultiBody *btmb, MultiBodyTree *id_tree, double *pos_error, - double *acc_error) { + btMultiBody *btmb, MultiBodyTree *id_tree, double *pos_error, + double *acc_error) +{ // call function and return -1 if it does, printing an bt_id_error_message -#define RETURN_ON_FAILURE(x) \ - do { \ - if (-1 == x) { \ - bt_id_error_message("calling " #x "\n"); \ - return -1; \ - } \ - } while (0) +#define RETURN_ON_FAILURE(x) \ + do \ + { \ + if (-1 == x) \ + { \ + bt_id_error_message("calling " #x "\n"); \ + return -1; \ + } \ + } while (0) - if (verbose) { - printf("\n ===================================== \n"); - } - vecx joint_forces(q.size()); + if (verbose) + { + printf("\n ===================================== \n"); + } + vecx joint_forces(q.size()); - // set positions and velocities for btMultiBody - // base link - mat33 world_T_base; - vec3 world_pos_base; - btTransform base_transform; - vec3 base_velocity; - vec3 base_angular_velocity; + // set positions and velocities for btMultiBody + // base link + mat33 world_T_base; + vec3 world_pos_base; + btTransform base_transform; + vec3 base_velocity; + vec3 base_angular_velocity; - RETURN_ON_FAILURE(id_tree->setGravityInWorldFrame(gravity)); - RETURN_ON_FAILURE(id_tree->getBodyOrigin(0, &world_pos_base)); - RETURN_ON_FAILURE(id_tree->getBodyTransform(0, &world_T_base)); - RETURN_ON_FAILURE(id_tree->getBodyAngularVelocity(0, &base_angular_velocity)); - RETURN_ON_FAILURE(id_tree->getBodyLinearVelocityCoM(0, &base_velocity)); + RETURN_ON_FAILURE(id_tree->setGravityInWorldFrame(gravity)); + RETURN_ON_FAILURE(id_tree->getBodyOrigin(0, &world_pos_base)); + RETURN_ON_FAILURE(id_tree->getBodyTransform(0, &world_T_base)); + RETURN_ON_FAILURE(id_tree->getBodyAngularVelocity(0, &base_angular_velocity)); + RETURN_ON_FAILURE(id_tree->getBodyLinearVelocityCoM(0, &base_velocity)); - base_transform.setBasis(world_T_base); - base_transform.setOrigin(world_pos_base); - btmb->setBaseWorldTransform(base_transform); - btmb->setBaseOmega(base_angular_velocity); - btmb->setBaseVel(base_velocity); - btmb->setLinearDamping(0); - btmb->setAngularDamping(0); + base_transform.setBasis(world_T_base); + base_transform.setOrigin(world_pos_base); + btmb->setBaseWorldTransform(base_transform); + btmb->setBaseOmega(base_angular_velocity); + btmb->setBaseVel(base_velocity); + btmb->setLinearDamping(0); + btmb->setAngularDamping(0); - // remaining links - int q_index; - if (btmb->hasFixedBase()) { - q_index = 0; - } else { - q_index = 6; - } - if (verbose) { - printf("bt:num_links= %d, num_dofs= %d\n", btmb->getNumLinks(), btmb->getNumDofs()); - } - for (int l = 0; l < btmb->getNumLinks(); l++) { - const btMultibodyLink &link = btmb->getLink(l); - if (verbose) { - printf("link %d, pos_var_count= %d, dof_count= %d\n", l, link.m_posVarCount, - link.m_dofCount); - } - if (link.m_posVarCount == 1) { - btmb->setJointPosMultiDof(l, &q(q_index)); - btmb->setJointVelMultiDof(l, &u(q_index)); - if (verbose) { - printf("set q[%d]= %f, u[%d]= %f\n", q_index, q(q_index), q_index, u(q_index)); - } - q_index++; - } - } - // sanity check - if (q_index != q.size()) { - bt_id_error_message("error in number of dofs for btMultibody and MultiBodyTree\n"); - return -1; - } + // remaining links + int q_index; + if (btmb->hasFixedBase()) + { + q_index = 0; + } + else + { + q_index = 6; + } + if (verbose) + { + printf("bt:num_links= %d, num_dofs= %d\n", btmb->getNumLinks(), btmb->getNumDofs()); + } + for (int l = 0; l < btmb->getNumLinks(); l++) + { + const btMultibodyLink &link = btmb->getLink(l); + if (verbose) + { + printf("link %d, pos_var_count= %d, dof_count= %d\n", l, link.m_posVarCount, + link.m_dofCount); + } + if (link.m_posVarCount == 1) + { + btmb->setJointPosMultiDof(l, &q(q_index)); + btmb->setJointVelMultiDof(l, &u(q_index)); + if (verbose) + { + printf("set q[%d]= %f, u[%d]= %f\n", q_index, q(q_index), q_index, u(q_index)); + } + q_index++; + } + } + // sanity check + if (q_index != q.size()) + { + bt_id_error_message("error in number of dofs for btMultibody and MultiBodyTree\n"); + return -1; + } - // run inverse dynamics to determine joint_forces for given q, u, dot_u - if (-1 == id_tree->calculateInverseDynamics(q, u, dot_u, &joint_forces)) { - bt_id_error_message("calculating inverse dynamics\n"); - return -1; - } + // run inverse dynamics to determine joint_forces for given q, u, dot_u + if (-1 == id_tree->calculateInverseDynamics(q, u, dot_u, &joint_forces)) + { + bt_id_error_message("calculating inverse dynamics\n"); + return -1; + } - // set up bullet forward dynamics model - btScalar dt = 0; - btAlignedObjectArray scratch_r; - btAlignedObjectArray scratch_v; - btAlignedObjectArray scratch_m; - // this triggers switch between using either appliedConstraintForce or appliedForce - bool isConstraintPass = false; - // apply gravity forces for btMultiBody model. Must be done manually. - btmb->addBaseForce(btmb->getBaseMass() * gravity); + // set up bullet forward dynamics model + btScalar dt = 0; + btAlignedObjectArray scratch_r; + btAlignedObjectArray scratch_v; + btAlignedObjectArray scratch_m; + // this triggers switch between using either appliedConstraintForce or appliedForce + bool isConstraintPass = false; + // apply gravity forces for btMultiBody model. Must be done manually. + btmb->addBaseForce(btmb->getBaseMass() * gravity); - for (int link = 0; link < btmb->getNumLinks(); link++) { - btmb->addLinkForce(link, gravity * btmb->getLinkMass(link)); - if (verbose) { - printf("link %d, applying gravity %f %f %f\n", link, - gravity[0] * btmb->getLinkMass(link), gravity[1] * btmb->getLinkMass(link), - gravity[2] * btmb->getLinkMass(link)); - } - } + for (int link = 0; link < btmb->getNumLinks(); link++) + { + btmb->addLinkForce(link, gravity * btmb->getLinkMass(link)); + if (verbose) + { + printf("link %d, applying gravity %f %f %f\n", link, + gravity[0] * btmb->getLinkMass(link), gravity[1] * btmb->getLinkMass(link), + gravity[2] * btmb->getLinkMass(link)); + } + } - // apply generalized forces - if (btmb->hasFixedBase()) { - q_index = 0; - } else { - vec3 base_force; - base_force(0) = joint_forces(3); - base_force(1) = joint_forces(4); - base_force(2) = joint_forces(5); + // apply generalized forces + if (btmb->hasFixedBase()) + { + q_index = 0; + } + else + { + vec3 base_force; + base_force(0) = joint_forces(3); + base_force(1) = joint_forces(4); + base_force(2) = joint_forces(5); - vec3 base_moment; - base_moment(0) = joint_forces(0); - base_moment(1) = joint_forces(1); - base_moment(2) = joint_forces(2); + vec3 base_moment; + base_moment(0) = joint_forces(0); + base_moment(1) = joint_forces(1); + base_moment(2) = joint_forces(2); - btmb->addBaseForce(world_T_base * base_force); - btmb->addBaseTorque(world_T_base * base_moment); - if (verbose) { - printf("base force from id: %f %f %f\n", joint_forces(3), joint_forces(4), - joint_forces(5)); - printf("base moment from id: %f %f %f\n", joint_forces(0), joint_forces(1), - joint_forces(2)); - } - q_index = 6; - } + btmb->addBaseForce(world_T_base * base_force); + btmb->addBaseTorque(world_T_base * base_moment); + if (verbose) + { + printf("base force from id: %f %f %f\n", joint_forces(3), joint_forces(4), + joint_forces(5)); + printf("base moment from id: %f %f %f\n", joint_forces(0), joint_forces(1), + joint_forces(2)); + } + q_index = 6; + } - for (int l = 0; l < btmb->getNumLinks(); l++) { - const btMultibodyLink &link = btmb->getLink(l); - if (link.m_posVarCount == 1) { - if (verbose) { - printf("id:joint_force[%d]= %f, applied to link %d\n", q_index, - joint_forces(q_index), l); - } - btmb->addJointTorque(l, joint_forces(q_index)); - q_index++; - } - } + for (int l = 0; l < btmb->getNumLinks(); l++) + { + const btMultibodyLink &link = btmb->getLink(l); + if (link.m_posVarCount == 1) + { + if (verbose) + { + printf("id:joint_force[%d]= %f, applied to link %d\n", q_index, + joint_forces(q_index), l); + } + btmb->addJointTorque(l, joint_forces(q_index)); + q_index++; + } + } - // sanity check - if (q_index != q.size()) { - bt_id_error_message("error in number of dofs for btMultibody and MultiBodyTree\n"); - return -1; - } + // sanity check + if (q_index != q.size()) + { + bt_id_error_message("error in number of dofs for btMultibody and MultiBodyTree\n"); + return -1; + } - // run forward kinematics & forward dynamics - btAlignedObjectArray world_to_local; - btAlignedObjectArray local_origin; - btmb->forwardKinematics(world_to_local, local_origin); - btmb->computeAccelerationsArticulatedBodyAlgorithmMultiDof(dt, scratch_r, scratch_v, scratch_m, isConstraintPass); + // run forward kinematics & forward dynamics + btAlignedObjectArray world_to_local; + btAlignedObjectArray local_origin; + btmb->forwardKinematics(world_to_local, local_origin); + btmb->computeAccelerationsArticulatedBodyAlgorithmMultiDof(dt, scratch_r, scratch_v, scratch_m, isConstraintPass); - // read generalized accelerations back from btMultiBody - // the mapping from scratch variables to accelerations is taken from the implementation - // of stepVelocitiesMultiDof - btScalar *base_accel = &scratch_r[btmb->getNumDofs()]; - btScalar *joint_accel = base_accel + 6; - *acc_error = 0; - int dot_u_offset = 0; - if (btmb->hasFixedBase()) { - dot_u_offset = 0; - } else { - dot_u_offset = 6; - } + // read generalized accelerations back from btMultiBody + // the mapping from scratch variables to accelerations is taken from the implementation + // of stepVelocitiesMultiDof + btScalar *base_accel = &scratch_r[btmb->getNumDofs()]; + btScalar *joint_accel = base_accel + 6; + *acc_error = 0; + int dot_u_offset = 0; + if (btmb->hasFixedBase()) + { + dot_u_offset = 0; + } + else + { + dot_u_offset = 6; + } - if (true == btmb->hasFixedBase()) { - for (int i = 0; i < btmb->getNumDofs(); i++) { - if (verbose) { - printf("bt:ddot_q[%d]= %f, id:ddot_q= %e, diff= %e\n", i, joint_accel[i], - dot_u(i + dot_u_offset), joint_accel[i] - dot_u(i)); - } - *acc_error += BT_ID_POW(joint_accel[i] - dot_u(i + dot_u_offset), 2); - } - } else { - vec3 base_dot_omega; - vec3 world_dot_omega; - world_dot_omega(0) = base_accel[0]; - world_dot_omega(1) = base_accel[1]; - world_dot_omega(2) = base_accel[2]; - base_dot_omega = world_T_base.transpose() * world_dot_omega; + if (true == btmb->hasFixedBase()) + { + for (int i = 0; i < btmb->getNumDofs(); i++) + { + if (verbose) + { + printf("bt:ddot_q[%d]= %f, id:ddot_q= %e, diff= %e\n", i, joint_accel[i], + dot_u(i + dot_u_offset), joint_accel[i] - dot_u(i)); + } + *acc_error += BT_ID_POW(joint_accel[i] - dot_u(i + dot_u_offset), 2); + } + } + else + { + vec3 base_dot_omega; + vec3 world_dot_omega; + world_dot_omega(0) = base_accel[0]; + world_dot_omega(1) = base_accel[1]; + world_dot_omega(2) = base_accel[2]; + base_dot_omega = world_T_base.transpose() * world_dot_omega; - // com happens to coincide with link origin here. If that changes, we need to calculate - // ddot_com - vec3 base_ddot_com; - vec3 world_ddot_com; - world_ddot_com(0) = base_accel[3]; - world_ddot_com(1) = base_accel[4]; - world_ddot_com(2) = base_accel[5]; - base_ddot_com = world_T_base.transpose()*world_ddot_com; + // com happens to coincide with link origin here. If that changes, we need to calculate + // ddot_com + vec3 base_ddot_com; + vec3 world_ddot_com; + world_ddot_com(0) = base_accel[3]; + world_ddot_com(1) = base_accel[4]; + world_ddot_com(2) = base_accel[5]; + base_ddot_com = world_T_base.transpose() * world_ddot_com; - for (int i = 0; i < 3; i++) { - if (verbose) { - printf("bt::base_dot_omega(%d)= %e dot_u[%d]= %e, diff= %e\n", i, base_dot_omega(i), - i, dot_u[i], base_dot_omega(i) - dot_u[i]); - } - *acc_error += BT_ID_POW(base_dot_omega(i) - dot_u(i), 2); - } - for (int i = 0; i < 3; i++) { - if (verbose) { - printf("bt::base_ddot_com(%d)= %e dot_u[%d]= %e, diff= %e\n", i, base_ddot_com(i), - i, dot_u[i + 3], base_ddot_com(i) - dot_u[i + 3]); - } - *acc_error += BT_ID_POW(base_ddot_com(i) - dot_u(i + 3), 2); - } + for (int i = 0; i < 3; i++) + { + if (verbose) + { + printf("bt::base_dot_omega(%d)= %e dot_u[%d]= %e, diff= %e\n", i, base_dot_omega(i), + i, dot_u[i], base_dot_omega(i) - dot_u[i]); + } + *acc_error += BT_ID_POW(base_dot_omega(i) - dot_u(i), 2); + } + for (int i = 0; i < 3; i++) + { + if (verbose) + { + printf("bt::base_ddot_com(%d)= %e dot_u[%d]= %e, diff= %e\n", i, base_ddot_com(i), + i, dot_u[i + 3], base_ddot_com(i) - dot_u[i + 3]); + } + *acc_error += BT_ID_POW(base_ddot_com(i) - dot_u(i + 3), 2); + } - for (int i = 0; i < btmb->getNumDofs(); i++) { - if (verbose) { - printf("bt:ddot_q[%d]= %f, id:ddot_q= %e, diff= %e\n", i, joint_accel[i], - dot_u(i + 6), joint_accel[i] - dot_u(i + 6)); - } - *acc_error += BT_ID_POW(joint_accel[i] - dot_u(i + 6), 2); - } - } - *acc_error = std::sqrt(*acc_error); - if (verbose) { - printf("======dynamics-err: %e\n", *acc_error); - } - *pos_error = 0.0; + for (int i = 0; i < btmb->getNumDofs(); i++) + { + if (verbose) + { + printf("bt:ddot_q[%d]= %f, id:ddot_q= %e, diff= %e\n", i, joint_accel[i], + dot_u(i + 6), joint_accel[i] - dot_u(i + 6)); + } + *acc_error += BT_ID_POW(joint_accel[i] - dot_u(i + 6), 2); + } + } + *acc_error = std::sqrt(*acc_error); + if (verbose) + { + printf("======dynamics-err: %e\n", *acc_error); + } + *pos_error = 0.0; - { - mat33 world_T_body; - if (-1 == id_tree->getBodyTransform(0, &world_T_body)) { - bt_id_error_message("getting transform for body %d\n", 0); - return -1; - } - vec3 world_com; - if (-1 == id_tree->getBodyCoM(0, &world_com)) { - bt_id_error_message("getting com for body %d\n", 0); - return -1; - } - if (verbose) { - printf("id:com: %f %f %f\n", world_com(0), world_com(1), world_com(2)); + { + mat33 world_T_body; + if (-1 == id_tree->getBodyTransform(0, &world_T_body)) + { + bt_id_error_message("getting transform for body %d\n", 0); + return -1; + } + vec3 world_com; + if (-1 == id_tree->getBodyCoM(0, &world_com)) + { + bt_id_error_message("getting com for body %d\n", 0); + return -1; + } + if (verbose) + { + printf("id:com: %f %f %f\n", world_com(0), world_com(1), world_com(2)); - printf("id:transform: %f %f %f\n" - " %f %f %f\n" - " %f %f %f\n", - world_T_body(0, 0), world_T_body(0, 1), world_T_body(0, 2), world_T_body(1, 0), - world_T_body(1, 1), world_T_body(1, 2), world_T_body(2, 0), world_T_body(2, 1), - world_T_body(2, 2)); - } - } + printf( + "id:transform: %f %f %f\n" + " %f %f %f\n" + " %f %f %f\n", + world_T_body(0, 0), world_T_body(0, 1), world_T_body(0, 2), world_T_body(1, 0), + world_T_body(1, 1), world_T_body(1, 2), world_T_body(2, 0), world_T_body(2, 1), + world_T_body(2, 2)); + } + } - for (int l = 0; l < btmb->getNumLinks(); l++) { - const btMultibodyLink &bt_link = btmb->getLink(l); + for (int l = 0; l < btmb->getNumLinks(); l++) + { + const btMultibodyLink &bt_link = btmb->getLink(l); - vec3 bt_origin = bt_link.m_cachedWorldTransform.getOrigin(); - mat33 bt_basis = bt_link.m_cachedWorldTransform.getBasis(); - if (verbose) { - printf("------------- link %d\n", l + 1); - printf("bt:com: %f %f %f\n", bt_origin(0), bt_origin(1), bt_origin(2)); - printf("bt:transform: %f %f %f\n" - " %f %f %f\n" - " %f %f %f\n", - bt_basis(0, 0), bt_basis(0, 1), bt_basis(0, 2), bt_basis(1, 0), bt_basis(1, 1), - bt_basis(1, 2), bt_basis(2, 0), bt_basis(2, 1), bt_basis(2, 2)); - } - mat33 id_world_T_body; - vec3 id_world_com; + vec3 bt_origin = bt_link.m_cachedWorldTransform.getOrigin(); + mat33 bt_basis = bt_link.m_cachedWorldTransform.getBasis(); + if (verbose) + { + printf("------------- link %d\n", l + 1); + printf("bt:com: %f %f %f\n", bt_origin(0), bt_origin(1), bt_origin(2)); + printf( + "bt:transform: %f %f %f\n" + " %f %f %f\n" + " %f %f %f\n", + bt_basis(0, 0), bt_basis(0, 1), bt_basis(0, 2), bt_basis(1, 0), bt_basis(1, 1), + bt_basis(1, 2), bt_basis(2, 0), bt_basis(2, 1), bt_basis(2, 2)); + } + mat33 id_world_T_body; + vec3 id_world_com; - if (-1 == id_tree->getBodyTransform(l + 1, &id_world_T_body)) { - bt_id_error_message("getting transform for body %d\n", l); - return -1; - } - if (-1 == id_tree->getBodyCoM(l + 1, &id_world_com)) { - bt_id_error_message("getting com for body %d\n", l); - return -1; - } - if (verbose) { - printf("id:com: %f %f %f\n", id_world_com(0), id_world_com(1), id_world_com(2)); + if (-1 == id_tree->getBodyTransform(l + 1, &id_world_T_body)) + { + bt_id_error_message("getting transform for body %d\n", l); + return -1; + } + if (-1 == id_tree->getBodyCoM(l + 1, &id_world_com)) + { + bt_id_error_message("getting com for body %d\n", l); + return -1; + } + if (verbose) + { + printf("id:com: %f %f %f\n", id_world_com(0), id_world_com(1), id_world_com(2)); - printf("id:transform: %f %f %f\n" - " %f %f %f\n" - " %f %f %f\n", - id_world_T_body(0, 0), id_world_T_body(0, 1), id_world_T_body(0, 2), - id_world_T_body(1, 0), id_world_T_body(1, 1), id_world_T_body(1, 2), - id_world_T_body(2, 0), id_world_T_body(2, 1), id_world_T_body(2, 2)); - } - vec3 diff_com = bt_origin - id_world_com; - mat33 diff_basis = bt_basis - id_world_T_body; - if (verbose) { - printf("diff-com: %e %e %e\n", diff_com(0), diff_com(1), diff_com(2)); + printf( + "id:transform: %f %f %f\n" + " %f %f %f\n" + " %f %f %f\n", + id_world_T_body(0, 0), id_world_T_body(0, 1), id_world_T_body(0, 2), + id_world_T_body(1, 0), id_world_T_body(1, 1), id_world_T_body(1, 2), + id_world_T_body(2, 0), id_world_T_body(2, 1), id_world_T_body(2, 2)); + } + vec3 diff_com = bt_origin - id_world_com; + mat33 diff_basis = bt_basis - id_world_T_body; + if (verbose) + { + printf("diff-com: %e %e %e\n", diff_com(0), diff_com(1), diff_com(2)); - printf("diff-transform: %e %e %e %e %e %e %e %e %e\n", diff_basis(0, 0), - diff_basis(0, 1), diff_basis(0, 2), diff_basis(1, 0), diff_basis(1, 1), - diff_basis(1, 2), diff_basis(2, 0), diff_basis(2, 1), diff_basis(2, 2)); - } - double total_pos_err = - BT_ID_SQRT(BT_ID_POW(diff_com(0), 2) + BT_ID_POW(diff_com(1), 2) + - BT_ID_POW(diff_com(2), 2) + BT_ID_POW(diff_basis(0, 0), 2) + - BT_ID_POW(diff_basis(0, 1), 2) + BT_ID_POW(diff_basis(0, 2), 2) + - BT_ID_POW(diff_basis(1, 0), 2) + BT_ID_POW(diff_basis(1, 1), 2) + - BT_ID_POW(diff_basis(1, 2), 2) + BT_ID_POW(diff_basis(2, 0), 2) + - BT_ID_POW(diff_basis(2, 1), 2) + BT_ID_POW(diff_basis(2, 2), 2)); - if (verbose) { - printf("======kin-pos-err: %e\n", total_pos_err); - } - if (total_pos_err > *pos_error) { - *pos_error = total_pos_err; - } - } + printf("diff-transform: %e %e %e %e %e %e %e %e %e\n", diff_basis(0, 0), + diff_basis(0, 1), diff_basis(0, 2), diff_basis(1, 0), diff_basis(1, 1), + diff_basis(1, 2), diff_basis(2, 0), diff_basis(2, 1), diff_basis(2, 2)); + } + double total_pos_err = + BT_ID_SQRT(BT_ID_POW(diff_com(0), 2) + BT_ID_POW(diff_com(1), 2) + + BT_ID_POW(diff_com(2), 2) + BT_ID_POW(diff_basis(0, 0), 2) + + BT_ID_POW(diff_basis(0, 1), 2) + BT_ID_POW(diff_basis(0, 2), 2) + + BT_ID_POW(diff_basis(1, 0), 2) + BT_ID_POW(diff_basis(1, 1), 2) + + BT_ID_POW(diff_basis(1, 2), 2) + BT_ID_POW(diff_basis(2, 0), 2) + + BT_ID_POW(diff_basis(2, 1), 2) + BT_ID_POW(diff_basis(2, 2), 2)); + if (verbose) + { + printf("======kin-pos-err: %e\n", total_pos_err); + } + if (total_pos_err > *pos_error) + { + *pos_error = total_pos_err; + } + } - return 0; -} + return 0; } +} // namespace btInverseDynamics diff --git a/Extras/InverseDynamics/invdyn_bullet_comparison.hpp b/Extras/InverseDynamics/invdyn_bullet_comparison.hpp index 1a6b7d4d5..c33353300 100644 --- a/Extras/InverseDynamics/invdyn_bullet_comparison.hpp +++ b/Extras/InverseDynamics/invdyn_bullet_comparison.hpp @@ -6,7 +6,8 @@ class btMultiBody; class btVector3; -namespace btInverseDynamics { +namespace btInverseDynamics +{ class MultiBodyTree; /// this function compares the forward dynamics computations implemented in btMultiBody to @@ -29,7 +30,7 @@ class MultiBodyTree; /// computed in step 3 relative to dot_u /// @return -1 on error, 0 on success int compareInverseAndForwardDynamics(vecx &q, vecx &u, vecx &dot_u, btVector3 &gravity, bool verbose, - btMultiBody *btmb, MultiBodyTree *id_tree, double *pos_error, - double *acc_error); -} + btMultiBody *btmb, MultiBodyTree *id_tree, double *pos_error, + double *acc_error); +} // namespace btInverseDynamics #endif // INVDYN_BULLET_COMPARISON_HPP diff --git a/Extras/Serialize/BlenderSerialize/bBlenderFile.cpp b/Extras/Serialize/BlenderSerialize/bBlenderFile.cpp index 9405fe14f..b1ee794f0 100644 --- a/Extras/Serialize/BlenderSerialize/bBlenderFile.cpp +++ b/Extras/Serialize/BlenderSerialize/bBlenderFile.cpp @@ -27,32 +27,27 @@ extern int DNAlen; extern unsigned char DNAstr64[]; extern int DNAlen64; - using namespace bParse; -bBlenderFile::bBlenderFile(const char* fileName) -:bFile(fileName, "BLENDER") +bBlenderFile::bBlenderFile(const char *fileName) + : bFile(fileName, "BLENDER") { - mMain= new bMain(this, fileName, mVersion); + mMain = new bMain(this, fileName, mVersion); } - - bBlenderFile::bBlenderFile(char *memoryBuffer, int len) -:bFile(memoryBuffer,len, "BLENDER"), -mMain(0) + : bFile(memoryBuffer, len, "BLENDER"), + mMain(0) { - mMain= new bMain(this, "memoryBuf", mVersion); + mMain = new bMain(this, "memoryBuf", mVersion); } - bBlenderFile::~bBlenderFile() { delete mMain; } - -bMain* bBlenderFile::getMain() +bMain *bBlenderFile::getMain() { return mMain; } @@ -60,20 +55,17 @@ bMain* bBlenderFile::getMain() // ----------------------------------------------------- // void bBlenderFile::parseData() { -// printf ("Building datablocks\n"); -// printf ("Chunk size = %d\n",CHUNK_HEADER_LEN); -// printf ("File chunk size = %d\n", ChunkUtils::getOffset(mFlags)); + // printf ("Building datablocks\n"); + // printf ("Chunk size = %d\n",CHUNK_HEADER_LEN); + // printf ("File chunk size = %d\n", ChunkUtils::getOffset(mFlags)); - const bool swap = (mFlags&FD_ENDIAN_SWAP)!=0; - + const bool swap = (mFlags & FD_ENDIAN_SWAP) != 0; - - char *dataPtr = mFileBuffer+mDataStart; + char *dataPtr = mFileBuffer + mDataStart; bChunkInd dataChunk; dataChunk.code = 0; - //dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags); int seek = getNextBlock(&dataChunk, dataPtr, mFlags); //dataPtr += ChunkUtils::getOffset(mFlags); @@ -81,55 +73,46 @@ void bBlenderFile::parseData() while (dataChunk.code != DNA1) { - - - - // one behind if (dataChunk.code == SDNA) break; //if (dataChunk.code == DNA1) break; // same as (BHEAD+DATA dependency) - dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags); + dataPtrHead = dataPtr + ChunkUtils::getOffset(mFlags); char *id = readStruct(dataPtrHead, dataChunk); // lookup maps if (id) { - m_chunkPtrPtrMap.insert(dataChunk.oldPtr, dataChunk); - mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)id); + m_chunkPtrPtrMap.insert(dataChunk.oldPtr, dataChunk); + mLibPointers.insert(dataChunk.oldPtr, (bStructHandle *)id); m_chunks.push_back(dataChunk); // block it bListBasePtr *listID = mMain->getListBasePtr(dataChunk.code); if (listID) - listID->push_back((bStructHandle*)id); + listID->push_back((bStructHandle *)id); } if (dataChunk.code == GLOB) { - m_glob = (bStructHandle*) id; + m_glob = (bStructHandle *)id; } // next please! dataPtr += seek; - seek = getNextBlock(&dataChunk, dataPtr, mFlags); + seek = getNextBlock(&dataChunk, dataPtr, mFlags); if (seek < 0) break; } - } -void bBlenderFile::addDataBlock(char* dataBlock) +void bBlenderFile::addDataBlock(char *dataBlock) { mMain->addDatablock(dataBlock); } - - - - // 32 && 64 bit versions extern unsigned char DNAstr[]; extern int DNAlen; @@ -137,88 +120,87 @@ extern int DNAlen; //unsigned char DNAstr[]={0}; //int DNAlen=0; - extern unsigned char DNAstr64[]; extern int DNAlen64; - -void bBlenderFile::writeDNA(FILE* fp) +void bBlenderFile::writeDNA(FILE *fp) { - bChunkInd dataChunk; dataChunk.code = DNA1; dataChunk.dna_nr = 0; dataChunk.nr = 1; - + if (VOID_IS_8) { dataChunk.len = DNAlen64; dataChunk.oldPtr = DNAstr64; - fwrite(&dataChunk,sizeof(bChunkInd),1,fp); - fwrite(DNAstr64, DNAlen64,1,fp); + fwrite(&dataChunk, sizeof(bChunkInd), 1, fp); + fwrite(DNAstr64, DNAlen64, 1, fp); } else { dataChunk.len = DNAlen; dataChunk.oldPtr = DNAstr; - fwrite(&dataChunk,sizeof(bChunkInd),1,fp); - fwrite(DNAstr, DNAlen,1,fp); + fwrite(&dataChunk, sizeof(bChunkInd), 1, fp); + fwrite(DNAstr, DNAlen, 1, fp); } } -void bBlenderFile::parse(int verboseMode) +void bBlenderFile::parse(int verboseMode) { if (VOID_IS_8) { - parseInternal(verboseMode,(char*)DNAstr64,DNAlen64); + parseInternal(verboseMode, (char *)DNAstr64, DNAlen64); } else { - parseInternal(verboseMode,(char*)DNAstr,DNAlen); + parseInternal(verboseMode, (char *)DNAstr, DNAlen); } } // experimental -int bBlenderFile::write(const char* fileName, bool fixupPointers) +int bBlenderFile::write(const char *fileName, bool fixupPointers) { FILE *fp = fopen(fileName, "wb"); if (fp) { - char header[SIZEOFBLENDERHEADER] ; + char header[SIZEOFBLENDERHEADER]; memcpy(header, m_headerString, 7); - int endian= 1; - endian= ((char*)&endian)[0]; + int endian = 1; + endian = ((char *)&endian)[0]; if (endian) { header[7] = '_'; - } else + } + else { header[7] = '-'; } if (VOID_IS_8) { - header[8]='V'; - } else + header[8] = 'V'; + } + else { - header[8]='v'; + header[8] = 'v'; } header[9] = '2'; header[10] = '4'; header[11] = '9'; - - fwrite(header,SIZEOFBLENDERHEADER,1,fp); + + fwrite(header, SIZEOFBLENDERHEADER, 1, fp); writeChunks(fp, fixupPointers); writeDNA(fp); fclose(fp); - - } else + } + else { - printf("Error: cannot open file %s for writing\n",fileName); + printf("Error: cannot open file %s for writing\n", fileName); return 0; } return 1; diff --git a/Extras/Serialize/BlenderSerialize/bBlenderFile.h b/Extras/Serialize/BlenderSerialize/bBlenderFile.h index 3c163b9e1..8c0ba2d40 100644 --- a/Extras/Serialize/BlenderSerialize/bBlenderFile.h +++ b/Extras/Serialize/BlenderSerialize/bBlenderFile.h @@ -16,48 +16,43 @@ subject to the following restrictions: #ifndef B_BLENDER_FILE_H #define B_BLENDER_FILE_H - #include "bFile.h" -namespace bParse { +namespace bParse +{ +// ----------------------------------------------------- // +class bBlenderFile : public bFile +{ +protected: + bMain* mMain; - // ----------------------------------------------------- // - class bBlenderFile : public bFile + bStructHandle* m_glob; + +public: + bBlenderFile(const char* fileName); + + bBlenderFile(char* memoryBuffer, int len); + + virtual ~bBlenderFile(); + + bMain* getMain(); + + virtual void addDataBlock(char* dataBlock); + + bStructHandle* getFileGlobal() { + return m_glob; + } - protected: - bMain* mMain; + // experimental + virtual int write(const char* fileName, bool fixupPointers = false); - bStructHandle* m_glob; + virtual void parse(int verboseMode); - - public: + virtual void parseData(); - bBlenderFile(const char* fileName); - - bBlenderFile(char *memoryBuffer, int len); - - virtual ~bBlenderFile(); - - bMain* getMain(); - - virtual void addDataBlock(char* dataBlock); - - bStructHandle* getFileGlobal() - { - return m_glob; - } - - // experimental - virtual int write(const char* fileName, bool fixupPointers = false); - - virtual void parse(int verboseMode); - - virtual void parseData(); - - virtual void writeDNA(FILE* fp); - - }; + virtual void writeDNA(FILE* fp); }; +}; // namespace bParse -#endif //B_BLENDER_FILE_H +#endif //B_BLENDER_FILE_H diff --git a/Extras/Serialize/BlenderSerialize/bMain.cpp b/Extras/Serialize/BlenderSerialize/bMain.cpp index fa672fbb8..5474767fe 100644 --- a/Extras/Serialize/BlenderSerialize/bMain.cpp +++ b/Extras/Serialize/BlenderSerialize/bMain.cpp @@ -21,51 +21,49 @@ subject to the following restrictions: using namespace bParse; - // ----------------------------------------------------- // bMain::bMain(bBlenderFile *filePtr, const char *baseName, int fileVersion) - : mFP(filePtr), - mVersion(fileVersion), - mName(baseName) + : mFP(filePtr), + mVersion(fileVersion), + mName(baseName) { - mData.insert(ID_SCE,bListBasePtr()); - mData.insert(ID_LI,bListBasePtr()); - mData.insert(ID_OB,bListBasePtr()); - mData.insert(ID_ME,bListBasePtr()); - mData.insert(ID_CU,bListBasePtr()); - mData.insert(ID_MB,bListBasePtr()); - mData.insert(ID_MA,bListBasePtr()); - mData.insert(ID_TE,bListBasePtr()); - mData.insert(ID_IM,bListBasePtr()); - mData.insert(ID_WV,bListBasePtr()); - mData.insert(ID_LT,bListBasePtr()); - mData.insert(ID_LA,bListBasePtr()); - mData.insert(ID_CA,bListBasePtr()); - mData.insert(ID_IP,bListBasePtr()); - mData.insert(ID_KE,bListBasePtr()); - mData.insert(ID_WO,bListBasePtr()); - mData.insert(ID_SCR,bListBasePtr()); - mData.insert(ID_VF,bListBasePtr()); - mData.insert(ID_TXT,bListBasePtr()); - mData.insert(ID_SO,bListBasePtr()); - mData.insert(ID_GR,bListBasePtr()); - mData.insert(ID_AR,bListBasePtr()); - mData.insert(ID_AC,bListBasePtr()); - mData.insert(ID_NT,bListBasePtr()); - mData.insert(ID_BR,bListBasePtr()); + mData.insert(ID_SCE, bListBasePtr()); + mData.insert(ID_LI, bListBasePtr()); + mData.insert(ID_OB, bListBasePtr()); + mData.insert(ID_ME, bListBasePtr()); + mData.insert(ID_CU, bListBasePtr()); + mData.insert(ID_MB, bListBasePtr()); + mData.insert(ID_MA, bListBasePtr()); + mData.insert(ID_TE, bListBasePtr()); + mData.insert(ID_IM, bListBasePtr()); + mData.insert(ID_WV, bListBasePtr()); + mData.insert(ID_LT, bListBasePtr()); + mData.insert(ID_LA, bListBasePtr()); + mData.insert(ID_CA, bListBasePtr()); + mData.insert(ID_IP, bListBasePtr()); + mData.insert(ID_KE, bListBasePtr()); + mData.insert(ID_WO, bListBasePtr()); + mData.insert(ID_SCR, bListBasePtr()); + mData.insert(ID_VF, bListBasePtr()); + mData.insert(ID_TXT, bListBasePtr()); + mData.insert(ID_SO, bListBasePtr()); + mData.insert(ID_GR, bListBasePtr()); + mData.insert(ID_AR, bListBasePtr()); + mData.insert(ID_AC, bListBasePtr()); + mData.insert(ID_NT, bListBasePtr()); + mData.insert(ID_BR, bListBasePtr()); mData.insert(ID_SCRIPT, bListBasePtr()); } - // ----------------------------------------------------- // bMain::~bMain() { // allocated data blocks! int sz = mPool.size(); - for (int i=0;ifirst) return; @@ -121,18 +114,18 @@ void bMain::linkList(void *listBasePtr) } void *prev = 0; - Link *l = (Link*)base->first; + Link *l = (Link *)base->first; while (l) { l->next = mFP->findLibPointer(l->next); l->prev = l->next; prev = l->next; - l = (Link*)l->next; + l = (Link *)l->next; } } // ------------------------------------------------------------// -bListBasePtr* bMain::getListBasePtr(int listBaseCode) +bListBasePtr *bMain::getListBasePtr(int listBaseCode) { bListBasePtr *ptr = _findCode(listBaseCode); if (!ptr) @@ -143,12 +136,10 @@ bListBasePtr* bMain::getListBasePtr(int listBaseCode) // ------------------------------------------------------------// bListBasePtr *bMain::_findCode(int code) { - - bListBasePtr* lbPtr = mData.find(code); + bListBasePtr *lbPtr = mData.find(code); return lbPtr; } - // ------------------------------------------------------------// bListBasePtr *bMain::getScene() { @@ -193,8 +184,6 @@ bListBasePtr *bMain::getCurve() return ptr; } - - // ------------------------------------------------------------// bListBasePtr *bMain::getMball() { @@ -222,7 +211,6 @@ bListBasePtr *bMain::getTex() return ptr; } - // ------------------------------------------------------------// bListBasePtr *bMain::getImage() { @@ -295,7 +283,6 @@ bListBasePtr *bMain::getWorld() return ptr; } - // ------------------------------------------------------------// bListBasePtr *bMain::getScreen() { @@ -368,7 +355,6 @@ bListBasePtr *bMain::getAction() return ptr; } - // ------------------------------------------------------------// bListBasePtr *bMain::getNodetree() { @@ -387,6 +373,4 @@ bListBasePtr *bMain::getBrush() return ptr; } - - //eof diff --git a/Extras/Serialize/BlenderSerialize/bMain.h b/Extras/Serialize/BlenderSerialize/bMain.h index f8e9afc5b..c52c92745 100644 --- a/Extras/Serialize/BlenderSerialize/bMain.h +++ b/Extras/Serialize/BlenderSerialize/bMain.h @@ -20,91 +20,77 @@ subject to the following restrictions: #include "bChunk.h" #include "LinearMath/btHashMap.h" +namespace bParse +{ +class bDNA; + +class bBlenderFile; +}; // namespace bParse namespace bParse { - class bDNA; +// ----------------------------------------------------- // - class bBlenderFile; -}; +typedef btHashMap bMainDataMap; - - -namespace bParse { - - - // ----------------------------------------------------- // - - typedef btHashMap bMainDataMap; - - - - // ----------------------------------------------------- // - class bMain - { +// ----------------------------------------------------- // +class bMain +{ //private: - public: - bBlenderFile* mFP; - bListBasePtr mPool; +public: + bBlenderFile *mFP; + bListBasePtr mPool; - int mVersion; - const char* mName; + int mVersion; + const char *mName; - bMainDataMap mData; + bMainDataMap mData; - + bListBasePtr *_findCode(int code); +public: + bMain(bBlenderFile *filePtr, const char *baseName, int fileVersion); + ~bMain(); - bListBasePtr *_findCode(int code); + int getVersion(); + const char *getName(); - public: - bMain(bBlenderFile *filePtr, const char *baseName, int fileVersion); - ~bMain(); + bListBasePtr *getListBasePtr(int listBaseCode); - int getVersion(); - const char *getName(); + bListBasePtr *getScene(); + bListBasePtr *getLibrary(); + bListBasePtr *getObject(); + bListBasePtr *getMesh(); + bListBasePtr *getCurve(); + bListBasePtr *getMball(); + bListBasePtr *getMat(); + bListBasePtr *getTex(); + bListBasePtr *getImage(); + bListBasePtr *getWave(); + bListBasePtr *getLatt(); + bListBasePtr *getLamp(); + bListBasePtr *getCamera(); + bListBasePtr *getIpo(); + bListBasePtr *getKey(); + bListBasePtr *getWorld(); + bListBasePtr *getScreen(); + bListBasePtr *getScript(); + bListBasePtr *getVfont(); + bListBasePtr *getText(); + bListBasePtr *getSound(); + bListBasePtr *getGroup(); + bListBasePtr *getArmature(); + bListBasePtr *getAction(); + bListBasePtr *getNodetree(); + bListBasePtr *getBrush(); - bListBasePtr *getListBasePtr(int listBaseCode); + // tracking allocated memory + void addDatablock(void *allocated); + // -- - bListBasePtr *getScene(); - bListBasePtr *getLibrary(); - bListBasePtr *getObject(); - bListBasePtr *getMesh(); - bListBasePtr *getCurve(); - bListBasePtr *getMball(); - bListBasePtr *getMat(); - bListBasePtr *getTex(); - bListBasePtr *getImage(); - bListBasePtr *getWave(); - bListBasePtr *getLatt(); - bListBasePtr *getLamp(); - bListBasePtr *getCamera(); - bListBasePtr *getIpo(); - bListBasePtr *getKey(); - bListBasePtr *getWorld(); - bListBasePtr *getScreen(); - bListBasePtr *getScript(); - bListBasePtr *getVfont(); - bListBasePtr *getText(); - bListBasePtr *getSound(); - bListBasePtr *getGroup(); - bListBasePtr *getArmature(); - bListBasePtr *getAction(); - bListBasePtr *getNodetree(); - bListBasePtr *getBrush(); + void linkList(void *listBasePtr); +}; +} // namespace bParse - - - // tracking allocated memory - void addDatablock(void *allocated); - - - // -- - - void linkList(void *listBasePtr); - }; -} - - -#endif//__BMAIN_H__ +#endif //__BMAIN_H__ diff --git a/Extras/Serialize/BlenderSerialize/dna249-64bit.cpp b/Extras/Serialize/BlenderSerialize/dna249-64bit.cpp index 7c56c2c47..e44d0d260 100644 --- a/Extras/Serialize/BlenderSerialize/dna249-64bit.cpp +++ b/Extras/Serialize/BlenderSerialize/dna249-64bit.cpp @@ -12,1400 +12,1399 @@ subject to the following restrictions: 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ -unsigned char DNAstr64[]= { -83,68,78,65,78,65,77,69,119,9,0,0,42,110,101,120,116,0,42,112,114,101,118,0,42,100,97,116,97,0,42,102,105, -114,115,116,0,42,108,97,115,116,0,120,0,121,0,122,0,119,0,120,109,105,110,0,120,109,97,120,0,121,109,105,110, -0,121,109,97,120,0,42,112,111,105,110,116,101,114,0,103,114,111,117,112,0,118,97,108,0,118,97,108,50,0,110,97, -109,101,91,51,50,93,0,116,121,112,101,0,115,117,98,116,121,112,101,0,102,108,97,103,0,115,97,118,101,100,0,100, -97,116,97,0,108,101,110,0,116,111,116,97,108,108,101,110,0,42,110,101,119,105,100,0,42,108,105,98,0,110,97,109, -101,91,50,52,93,0,117,115,0,105,99,111,110,95,105,100,0,42,112,114,111,112,101,114,116,105,101,115,0,105,100,0, -42,105,100,98,108,111,99,107,0,42,102,105,108,101,100,97,116,97,0,110,97,109,101,91,50,52,48,93,0,102,105,108, -101,110,97,109,101,91,50,52,48,93,0,116,111,116,0,112,97,100,0,42,112,97,114,101,110,116,0,119,91,50,93,0, -104,91,50,93,0,99,104,97,110,103,101,100,91,50,93,0,112,97,100,48,0,112,97,100,49,0,42,114,101,99,116,91, -50,93,0,42,111,98,0,98,108,111,99,107,116,121,112,101,0,97,100,114,99,111,100,101,0,110,97,109,101,91,49,50, -56,93,0,42,98,112,0,42,98,101,122,116,0,109,97,120,114,99,116,0,116,111,116,114,99,116,0,118,97,114,116,121, -112,101,0,116,111,116,118,101,114,116,0,105,112,111,0,101,120,116,114,97,112,0,114,116,0,98,105,116,109,97,115,107, -0,115,108,105,100,101,95,109,105,110,0,115,108,105,100,101,95,109,97,120,0,99,117,114,118,97,108,0,42,100,114,105, -118,101,114,0,99,117,114,118,101,0,99,117,114,0,115,104,111,119,107,101,121,0,109,117,116,101,105,112,111,0,112,111, -115,0,114,101,108,97,116,105,118,101,0,116,111,116,101,108,101,109,0,112,97,100,50,0,42,119,101,105,103,104,116,115, -0,118,103,114,111,117,112,91,51,50,93,0,115,108,105,100,101,114,109,105,110,0,115,108,105,100,101,114,109,97,120,0, -42,114,101,102,107,101,121,0,101,108,101,109,115,116,114,91,51,50,93,0,101,108,101,109,115,105,122,101,0,98,108,111, -99,107,0,42,105,112,111,0,42,102,114,111,109,0,116,111,116,107,101,121,0,115,108,117,114,112,104,0,42,42,115,99, -114,105,112,116,115,0,42,102,108,97,103,0,97,99,116,115,99,114,105,112,116,0,116,111,116,115,99,114,105,112,116,0, -42,108,105,110,101,0,42,102,111,114,109,97,116,0,98,108,101,110,0,108,105,110,101,110,111,0,115,116,97,114,116,0, -101,110,100,0,102,108,97,103,115,0,99,111,108,111,114,91,52,93,0,112,97,100,91,52,93,0,42,110,97,109,101,0, -110,108,105,110,101,115,0,108,105,110,101,115,0,42,99,117,114,108,0,42,115,101,108,108,0,99,117,114,99,0,115,101, -108,99,0,109,97,114,107,101,114,115,0,42,117,110,100,111,95,98,117,102,0,117,110,100,111,95,112,111,115,0,117,110, -100,111,95,108,101,110,0,42,99,111,109,112,105,108,101,100,0,109,116,105,109,101,0,115,105,122,101,0,115,101,101,107, -0,112,97,115,115,101,112,97,114,116,97,108,112,104,97,0,97,110,103,108,101,0,99,108,105,112,115,116,97,0,99,108, -105,112,101,110,100,0,108,101,110,115,0,111,114,116,104,111,95,115,99,97,108,101,0,100,114,97,119,115,105,122,101,0, -115,104,105,102,116,120,0,115,104,105,102,116,121,0,89,70,95,100,111,102,100,105,115,116,0,89,70,95,97,112,101,114, -116,117,114,101,0,89,70,95,98,107,104,116,121,112,101,0,89,70,95,98,107,104,98,105,97,115,0,89,70,95,98,107, -104,114,111,116,0,115,99,114,105,112,116,108,105,110,107,0,42,100,111,102,95,111,98,0,102,114,97,109,101,110,114,0, -102,114,97,109,101,115,0,111,102,102,115,101,116,0,115,102,114,97,0,102,105,101,95,105,109,97,0,99,121,99,108,0, -111,107,0,109,117,108,116,105,95,105,110,100,101,120,0,108,97,121,101,114,0,112,97,115,115,0,109,101,110,117,110,114, -0,105,98,117,102,115,0,42,103,112,117,116,101,120,116,117,114,101,0,42,97,110,105,109,0,42,114,114,0,115,111,117, -114,99,101,0,108,97,115,116,102,114,97,109,101,0,116,112,97,103,101,102,108,97,103,0,116,111,116,98,105,110,100,0, -120,114,101,112,0,121,114,101,112,0,116,119,115,116,97,0,116,119,101,110,100,0,98,105,110,100,99,111,100,101,0,42, -114,101,112,98,105,110,100,0,42,112,97,99,107,101,100,102,105,108,101,0,42,112,114,101,118,105,101,119,0,108,97,115, -116,117,112,100,97,116,101,0,108,97,115,116,117,115,101,100,0,97,110,105,109,115,112,101,101,100,0,103,101,110,95,120, -0,103,101,110,95,121,0,103,101,110,95,116,121,112,101,0,97,115,112,120,0,97,115,112,121,0,42,118,110,111,100,101, -0,116,101,120,99,111,0,109,97,112,116,111,0,109,97,112,116,111,110,101,103,0,98,108,101,110,100,116,121,112,101,0, -42,111,98,106,101,99,116,0,42,116,101,120,0,117,118,110,97,109,101,91,51,50,93,0,112,114,111,106,120,0,112,114, -111,106,121,0,112,114,111,106,122,0,109,97,112,112,105,110,103,0,111,102,115,91,51,93,0,115,105,122,101,91,51,93, -0,116,101,120,102,108,97,103,0,99,111,108,111,114,109,111,100,101,108,0,112,109,97,112,116,111,0,112,109,97,112,116, -111,110,101,103,0,110,111,114,109,97,112,115,112,97,99,101,0,119,104,105,99,104,95,111,117,116,112,117,116,0,112,97, -100,91,50,93,0,114,0,103,0,98,0,107,0,100,101,102,95,118,97,114,0,99,111,108,102,97,99,0,110,111,114,102, -97,99,0,118,97,114,102,97,99,0,100,105,115,112,102,97,99,0,119,97,114,112,102,97,99,0,110,97,109,101,91,49, -54,48,93,0,42,104,97,110,100,108,101,0,42,112,110,97,109,101,0,42,115,116,110,97,109,101,115,0,115,116,121,112, -101,115,0,118,97,114,115,0,42,118,97,114,115,116,114,0,42,114,101,115,117,108,116,0,42,99,102,114,97,0,100,97, -116,97,91,51,50,93,0,40,42,100,111,105,116,41,40,41,0,40,42,105,110,115,116,97,110,99,101,95,105,110,105,116, -41,40,41,0,40,42,99,97,108,108,98,97,99,107,41,40,41,0,118,101,114,115,105,111,110,0,97,0,105,112,111,116, -121,112,101,0,42,105,109,97,0,42,99,117,98,101,91,54,93,0,105,109,97,116,91,52,93,91,52,93,0,111,98,105, -109,97,116,91,51,93,91,51,93,0,115,116,121,112,101,0,118,105,101,119,115,99,97,108,101,0,110,111,116,108,97,121, -0,99,117,98,101,114,101,115,0,100,101,112,116,104,0,114,101,99,97,108,99,0,108,97,115,116,115,105,122,101,0,110, -111,105,115,101,115,105,122,101,0,116,117,114,98,117,108,0,98,114,105,103,104,116,0,99,111,110,116,114,97,115,116,0, -114,102,97,99,0,103,102,97,99,0,98,102,97,99,0,102,105,108,116,101,114,115,105,122,101,0,109,103,95,72,0,109, -103,95,108,97,99,117,110,97,114,105,116,121,0,109,103,95,111,99,116,97,118,101,115,0,109,103,95,111,102,102,115,101, -116,0,109,103,95,103,97,105,110,0,100,105,115,116,95,97,109,111,117,110,116,0,110,115,95,111,117,116,115,99,97,108, -101,0,118,110,95,119,49,0,118,110,95,119,50,0,118,110,95,119,51,0,118,110,95,119,52,0,118,110,95,109,101,120, -112,0,118,110,95,100,105,115,116,109,0,118,110,95,99,111,108,116,121,112,101,0,110,111,105,115,101,100,101,112,116,104, -0,110,111,105,115,101,116,121,112,101,0,110,111,105,115,101,98,97,115,105,115,0,110,111,105,115,101,98,97,115,105,115, -50,0,105,109,97,102,108,97,103,0,99,114,111,112,120,109,105,110,0,99,114,111,112,121,109,105,110,0,99,114,111,112, -120,109,97,120,0,99,114,111,112,121,109,97,120,0,120,114,101,112,101,97,116,0,121,114,101,112,101,97,116,0,101,120, -116,101,110,100,0,99,104,101,99,107,101,114,100,105,115,116,0,110,97,98,108,97,0,105,117,115,101,114,0,42,110,111, -100,101,116,114,101,101,0,42,112,108,117,103,105,110,0,42,99,111,98,97,0,42,101,110,118,0,117,115,101,95,110,111, -100,101,115,0,112,97,100,91,55,93,0,108,111,99,91,51,93,0,114,111,116,91,51,93,0,109,97,116,91,52,93,91, -52,93,0,109,105,110,91,51,93,0,109,97,120,91,51,93,0,112,97,100,51,0,109,111,100,101,0,116,111,116,101,120, -0,115,104,100,119,114,0,115,104,100,119,103,0,115,104,100,119,98,0,115,104,100,119,112,97,100,0,101,110,101,114,103, -121,0,100,105,115,116,0,115,112,111,116,115,105,122,101,0,115,112,111,116,98,108,101,110,100,0,104,97,105,110,116,0, -97,116,116,49,0,97,116,116,50,0,42,99,117,114,102,97,108,108,111,102,102,0,102,97,108,108,111,102,102,95,116,121, -112,101,0,115,104,97,100,115,112,111,116,115,105,122,101,0,98,105,97,115,0,115,111,102,116,0,98,117,102,115,105,122, -101,0,115,97,109,112,0,98,117,102,102,101,114,115,0,102,105,108,116,101,114,116,121,112,101,0,98,117,102,102,108,97, -103,0,98,117,102,116,121,112,101,0,114,97,121,95,115,97,109,112,0,114,97,121,95,115,97,109,112,121,0,114,97,121, -95,115,97,109,112,122,0,114,97,121,95,115,97,109,112,95,116,121,112,101,0,97,114,101,97,95,115,104,97,112,101,0, -97,114,101,97,95,115,105,122,101,0,97,114,101,97,95,115,105,122,101,121,0,97,114,101,97,95,115,105,122,101,122,0, -97,100,97,112,116,95,116,104,114,101,115,104,0,114,97,121,95,115,97,109,112,95,109,101,116,104,111,100,0,116,101,120, -97,99,116,0,115,104,97,100,104,97,108,111,115,116,101,112,0,115,117,110,95,101,102,102,101,99,116,95,116,121,112,101, -0,115,107,121,98,108,101,110,100,116,121,112,101,0,104,111,114,105,122,111,110,95,98,114,105,103,104,116,110,101,115,115, -0,115,112,114,101,97,100,0,115,117,110,95,98,114,105,103,104,116,110,101,115,115,0,115,117,110,95,115,105,122,101,0, -98,97,99,107,115,99,97,116,116,101,114,101,100,95,108,105,103,104,116,0,115,117,110,95,105,110,116,101,110,115,105,116, -121,0,97,116,109,95,116,117,114,98,105,100,105,116,121,0,97,116,109,95,105,110,115,99,97,116,116,101,114,105,110,103, -95,102,97,99,116,111,114,0,97,116,109,95,101,120,116,105,110,99,116,105,111,110,95,102,97,99,116,111,114,0,97,116, -109,95,100,105,115,116,97,110,99,101,95,102,97,99,116,111,114,0,115,107,121,98,108,101,110,100,102,97,99,0,115,107, -121,95,101,120,112,111,115,117,114,101,0,115,107,121,95,99,111,108,111,114,115,112,97,99,101,0,112,97,100,52,0,89, -70,95,110,117,109,112,104,111,116,111,110,115,0,89,70,95,110,117,109,115,101,97,114,99,104,0,89,70,95,112,104,100, -101,112,116,104,0,89,70,95,117,115,101,113,109,99,0,89,70,95,98,117,102,115,105,122,101,0,89,70,95,112,97,100, -0,89,70,95,99,97,117,115,116,105,99,98,108,117,114,0,89,70,95,108,116,114,97,100,105,117,115,0,89,70,95,103, -108,111,119,105,110,116,0,89,70,95,103,108,111,119,111,102,115,0,89,70,95,103,108,111,119,116,121,112,101,0,89,70, -95,112,97,100,50,0,42,109,116,101,120,91,49,56,93,0,115,112,101,99,114,0,115,112,101,99,103,0,115,112,101,99, -98,0,109,105,114,114,0,109,105,114,103,0,109,105,114,98,0,97,109,98,114,0,97,109,98,98,0,97,109,98,103,0, -97,109,98,0,101,109,105,116,0,97,110,103,0,115,112,101,99,116,114,97,0,114,97,121,95,109,105,114,114,111,114,0, -97,108,112,104,97,0,114,101,102,0,115,112,101,99,0,122,111,102,102,115,0,97,100,100,0,116,114,97,110,115,108,117, -99,101,110,99,121,0,102,114,101,115,110,101,108,95,109,105,114,0,102,114,101,115,110,101,108,95,109,105,114,95,105,0, -102,114,101,115,110,101,108,95,116,114,97,0,102,114,101,115,110,101,108,95,116,114,97,95,105,0,102,105,108,116,101,114, -0,116,120,95,108,105,109,105,116,0,116,120,95,102,97,108,108,111,102,102,0,114,97,121,95,100,101,112,116,104,0,114, -97,121,95,100,101,112,116,104,95,116,114,97,0,104,97,114,0,115,101,101,100,49,0,115,101,101,100,50,0,103,108,111, -115,115,95,109,105,114,0,103,108,111,115,115,95,116,114,97,0,115,97,109,112,95,103,108,111,115,115,95,109,105,114,0, -115,97,109,112,95,103,108,111,115,115,95,116,114,97,0,97,100,97,112,116,95,116,104,114,101,115,104,95,109,105,114,0, -97,100,97,112,116,95,116,104,114,101,115,104,95,116,114,97,0,97,110,105,115,111,95,103,108,111,115,115,95,109,105,114, -0,100,105,115,116,95,109,105,114,0,102,97,100,101,116,111,95,109,105,114,0,115,104,97,100,101,95,102,108,97,103,0, -109,111,100,101,95,108,0,102,108,97,114,101,99,0,115,116,97,114,99,0,108,105,110,101,99,0,114,105,110,103,99,0, -104,97,115,105,122,101,0,102,108,97,114,101,115,105,122,101,0,115,117,98,115,105,122,101,0,102,108,97,114,101,98,111, -111,115,116,0,115,116,114,97,110,100,95,115,116,97,0,115,116,114,97,110,100,95,101,110,100,0,115,116,114,97,110,100, -95,101,97,115,101,0,115,116,114,97,110,100,95,115,117,114,102,110,111,114,0,115,116,114,97,110,100,95,109,105,110,0, -115,116,114,97,110,100,95,119,105,100,116,104,102,97,100,101,0,115,116,114,97,110,100,95,117,118,110,97,109,101,91,51, -50,93,0,115,98,105,97,115,0,108,98,105,97,115,0,115,104,97,100,95,97,108,112,104,97,0,115,101,112,116,101,120, -0,114,103,98,115,101,108,0,112,114,95,116,121,112,101,0,112,114,95,98,97,99,107,0,112,114,95,108,97,109,112,0, -109,108,95,102,108,97,103,0,100,105,102,102,95,115,104,97,100,101,114,0,115,112,101,99,95,115,104,97,100,101,114,0, -114,111,117,103,104,110,101,115,115,0,114,101,102,114,97,99,0,112,97,114,97,109,91,52,93,0,114,109,115,0,100,97, -114,107,110,101,115,115,0,42,114,97,109,112,95,99,111,108,0,42,114,97,109,112,95,115,112,101,99,0,114,97,109,112, -105,110,95,99,111,108,0,114,97,109,112,105,110,95,115,112,101,99,0,114,97,109,112,98,108,101,110,100,95,99,111,108, -0,114,97,109,112,98,108,101,110,100,95,115,112,101,99,0,114,97,109,112,95,115,104,111,119,0,114,97,109,112,102,97, -99,95,99,111,108,0,114,97,109,112,102,97,99,95,115,112,101,99,0,42,103,114,111,117,112,0,102,114,105,99,116,105, -111,110,0,102,104,0,114,101,102,108,101,99,116,0,102,104,100,105,115,116,0,120,121,102,114,105,99,116,0,100,121,110, -97,109,111,100,101,0,115,115,115,95,114,97,100,105,117,115,91,51,93,0,115,115,115,95,99,111,108,91,51,93,0,115, -115,115,95,101,114,114,111,114,0,115,115,115,95,115,99,97,108,101,0,115,115,115,95,105,111,114,0,115,115,115,95,99, -111,108,102,97,99,0,115,115,115,95,116,101,120,102,97,99,0,115,115,115,95,102,114,111,110,116,0,115,115,115,95,98, -97,99,107,0,115,115,115,95,102,108,97,103,0,115,115,115,95,112,114,101,115,101,116,0,89,70,95,97,114,0,89,70, -95,97,103,0,89,70,95,97,98,0,89,70,95,100,115,99,97,108,101,0,89,70,95,100,112,119,114,0,89,70,95,100, -115,109,112,0,89,70,95,112,114,101,115,101,116,0,89,70,95,100,106,105,116,0,103,112,117,109,97,116,101,114,105,97, -108,0,110,97,109,101,91,50,53,54,93,0,115,99,97,108,101,0,42,98,98,0,105,49,0,106,49,0,107,49,0,105, -50,0,106,50,0,107,50,0,115,101,108,99,111,108,49,0,115,101,108,99,111,108,50,0,113,117,97,116,91,52,93,0, -101,120,112,120,0,101,120,112,121,0,101,120,112,122,0,114,97,100,0,114,97,100,50,0,115,0,42,109,97,116,0,42, -105,109,97,116,0,101,108,101,109,115,0,100,105,115,112,0,42,42,109,97,116,0,116,111,116,99,111,108,0,119,105,114, -101,115,105,122,101,0,114,101,110,100,101,114,115,105,122,101,0,116,104,114,101,115,104,0,118,101,99,91,51,93,91,51, -93,0,97,108,102,97,0,119,101,105,103,104,116,0,114,97,100,105,117,115,0,104,49,0,104,50,0,102,49,0,102,50, -0,102,51,0,104,105,100,101,0,118,101,99,91,52,93,0,109,97,116,95,110,114,0,112,110,116,115,117,0,112,110,116, -115,118,0,114,101,115,111,108,117,0,114,101,115,111,108,118,0,111,114,100,101,114,117,0,111,114,100,101,114,118,0,102, -108,97,103,117,0,102,108,97,103,118,0,42,107,110,111,116,115,117,0,42,107,110,111,116,115,118,0,116,105,108,116,95, -105,110,116,101,114,112,0,114,97,100,105,117,115,95,105,110,116,101,114,112,0,99,104,97,114,105,100,120,0,107,101,114, -110,0,104,0,110,117,114,98,0,42,98,101,118,111,98,106,0,42,116,97,112,101,114,111,98,106,0,42,116,101,120,116, -111,110,99,117,114,118,101,0,42,112,97,116,104,0,42,107,101,121,0,98,101,118,0,112,97,116,104,108,101,110,0,98, -101,118,114,101,115,111,108,0,119,105,100,116,104,0,101,120,116,49,0,101,120,116,50,0,114,101,115,111,108,117,95,114, -101,110,0,114,101,115,111,108,118,95,114,101,110,0,115,112,97,99,101,109,111,100,101,0,115,112,97,99,105,110,103,0, -108,105,110,101,100,105,115,116,0,115,104,101,97,114,0,102,115,105,122,101,0,119,111,114,100,115,112,97,99,101,0,117, -108,112,111,115,0,117,108,104,101,105,103,104,116,0,120,111,102,0,121,111,102,0,108,105,110,101,119,105,100,116,104,0, -42,115,116,114,0,102,97,109,105,108,121,91,50,52,93,0,42,118,102,111,110,116,0,42,118,102,111,110,116,98,0,42, -118,102,111,110,116,105,0,42,118,102,111,110,116,98,105,0,115,101,112,99,104,97,114,0,116,111,116,98,111,120,0,97, -99,116,98,111,120,0,42,116,98,0,115,101,108,115,116,97,114,116,0,115,101,108,101,110,100,0,42,115,116,114,105,110, -102,111,0,99,117,114,105,110,102,111,0,101,102,102,101,99,116,0,42,109,102,97,99,101,0,42,109,116,102,97,99,101, -0,42,116,102,97,99,101,0,42,109,118,101,114,116,0,42,109,101,100,103,101,0,42,100,118,101,114,116,0,42,109,99, -111,108,0,42,109,115,116,105,99,107,121,0,42,116,101,120,99,111,109,101,115,104,0,42,109,115,101,108,101,99,116,0, -118,100,97,116,97,0,101,100,97,116,97,0,102,100,97,116,97,0,116,111,116,101,100,103,101,0,116,111,116,102,97,99, -101,0,116,111,116,115,101,108,101,99,116,0,97,99,116,95,102,97,99,101,0,99,117,98,101,109,97,112,115,105,122,101, -0,115,109,111,111,116,104,114,101,115,104,0,115,117,98,100,105,118,0,115,117,98,100,105,118,114,0,115,117,98,115,117, -114,102,116,121,112,101,0,42,109,114,0,42,112,118,0,42,116,112,97,103,101,0,117,118,91,52,93,91,50,93,0,99, -111,108,91,52,93,0,116,114,97,110,115,112,0,116,105,108,101,0,117,110,119,114,97,112,0,118,49,0,118,50,0,118, -51,0,118,52,0,101,100,99,111,100,101,0,99,114,101,97,115,101,0,98,119,101,105,103,104,116,0,100,101,102,95,110, -114,0,42,100,119,0,116,111,116,119,101,105,103,104,116,0,99,111,91,51,93,0,110,111,91,51,93,0,112,97,100,91, -51,93,0,117,118,91,50,93,0,99,111,91,50,93,0,105,110,100,101,120,0,102,0,105,0,115,91,50,53,54,93,0, -118,91,52,93,0,109,105,100,0,118,91,50,93,0,42,102,97,99,101,115,0,42,99,111,108,102,97,99,101,115,0,42, -101,100,103,101,115,0,42,101,100,103,101,95,98,111,117,110,100,97,114,121,95,115,116,97,116,101,115,0,42,118,101,114, -116,95,101,100,103,101,95,109,97,112,0,42,118,101,114,116,95,102,97,99,101,95,109,97,112,0,42,109,97,112,95,109, -101,109,0,42,118,101,114,116,115,0,108,101,118,101,108,115,0,108,101,118,101,108,95,99,111,117,110,116,0,99,117,114, -114,101,110,116,0,110,101,119,108,118,108,0,101,100,103,101,108,118,108,0,112,105,110,108,118,108,0,114,101,110,100,101, -114,108,118,108,0,117,115,101,95,99,111,108,0,42,101,100,103,101,95,102,108,97,103,115,0,42,101,100,103,101,95,99, -114,101,97,115,101,115,0,42,118,101,114,116,95,109,97,112,0,42,101,100,103,101,95,109,97,112,0,42,111,108,100,95, -102,97,99,101,115,0,42,111,108,100,95,101,100,103,101,115,0,42,101,114,114,111,114,0,109,111,100,105,102,105,101,114, -0,115,117,98,100,105,118,84,121,112,101,0,114,101,110,100,101,114,76,101,118,101,108,115,0,42,101,109,67,97,99,104, -101,0,42,109,67,97,99,104,101,0,100,101,102,97,120,105,115,0,112,97,100,91,54,93,0,108,101,110,103,116,104,0, -114,97,110,100,111,109,105,122,101,0,115,101,101,100,0,42,111,98,95,97,114,109,0,42,115,116,97,114,116,95,99,97, -112,0,42,101,110,100,95,99,97,112,0,42,99,117,114,118,101,95,111,98,0,42,111,102,102,115,101,116,95,111,98,0, -111,102,102,115,101,116,91,51,93,0,115,99,97,108,101,91,51,93,0,109,101,114,103,101,95,100,105,115,116,0,102,105, -116,95,116,121,112,101,0,111,102,102,115,101,116,95,116,121,112,101,0,99,111,117,110,116,0,97,120,105,115,0,116,111, -108,101,114,97,110,99,101,0,42,109,105,114,114,111,114,95,111,98,0,115,112,108,105,116,95,97,110,103,108,101,0,118, -97,108,117,101,0,114,101,115,0,118,97,108,95,102,108,97,103,115,0,108,105,109,95,102,108,97,103,115,0,101,95,102, -108,97,103,115,0,98,101,118,101,108,95,97,110,103,108,101,0,100,101,102,103,114,112,95,110,97,109,101,91,51,50,93, -0,42,116,101,120,116,117,114,101,0,115,116,114,101,110,103,116,104,0,100,105,114,101,99,116,105,111,110,0,109,105,100, -108,101,118,101,108,0,116,101,120,109,97,112,112,105,110,103,0,42,109,97,112,95,111,98,106,101,99,116,0,117,118,108, -97,121,101,114,95,110,97,109,101,91,51,50,93,0,117,118,108,97,121,101,114,95,116,109,112,0,42,112,114,111,106,101, -99,116,111,114,115,91,49,48,93,0,42,105,109,97,103,101,0,110,117,109,95,112,114,111,106,101,99,116,111,114,115,0, -97,115,112,101,99,116,120,0,97,115,112,101,99,116,121,0,112,101,114,99,101,110,116,0,102,97,99,101,67,111,117,110, -116,0,102,97,99,0,114,101,112,101,97,116,0,42,111,98,106,101,99,116,99,101,110,116,101,114,0,115,116,97,114,116, -120,0,115,116,97,114,116,121,0,104,101,105,103,104,116,0,110,97,114,114,111,119,0,115,112,101,101,100,0,100,97,109, -112,0,102,97,108,108,111,102,102,0,116,105,109,101,111,102,102,115,0,108,105,102,101,116,105,109,101,0,100,101,102,111, -114,109,102,108,97,103,0,109,117,108,116,105,0,42,112,114,101,118,67,111,115,0,112,97,114,101,110,116,105,110,118,91, -52,93,91,52,93,0,99,101,110,116,91,51,93,0,42,105,110,100,101,120,97,114,0,116,111,116,105,110,100,101,120,0, -102,111,114,99,101,0,42,99,108,111,116,104,79,98,106,101,99,116,0,42,115,105,109,95,112,97,114,109,115,0,42,99, -111,108,108,95,112,97,114,109,115,0,42,112,111,105,110,116,95,99,97,99,104,101,0,42,120,0,42,120,110,101,119,0, -42,120,111,108,100,0,42,99,117,114,114,101,110,116,95,120,110,101,119,0,42,99,117,114,114,101,110,116,95,120,0,42, -99,117,114,114,101,110,116,95,118,0,42,109,102,97,99,101,115,0,110,117,109,118,101,114,116,115,0,110,117,109,102,97, -99,101,115,0,97,98,115,111,114,112,116,105,111,110,0,116,105,109,101,0,42,98,118,104,116,114,101,101,0,42,100,109, -0,111,112,101,114,97,116,105,111,110,0,118,101,114,116,101,120,0,116,111,116,105,110,102,108,117,101,110,99,101,0,103, -114,105,100,115,105,122,101,0,110,101,101,100,98,105,110,100,0,42,98,105,110,100,119,101,105,103,104,116,115,0,42,98, -105,110,100,99,111,115,0,116,111,116,99,97,103,101,118,101,114,116,0,42,100,121,110,103,114,105,100,0,42,100,121,110, -105,110,102,108,117,101,110,99,101,115,0,42,100,121,110,118,101,114,116,115,0,42,112,97,100,50,0,100,121,110,103,114, -105,100,115,105,122,101,0,100,121,110,99,101,108,108,109,105,110,91,51,93,0,100,121,110,99,101,108,108,119,105,100,116, -104,0,98,105,110,100,109,97,116,91,52,93,91,52,93,0,42,112,115,121,115,0,116,111,116,100,109,118,101,114,116,0, -116,111,116,100,109,101,100,103,101,0,116,111,116,100,109,102,97,99,101,0,112,115,121,115,0,114,116,91,50,93,0,42, -102,97,99,101,112,97,0,118,103,114,111,117,112,0,112,114,111,116,101,99,116,0,42,102,115,115,0,42,116,97,114,103, -101,116,0,42,97,117,120,84,97,114,103,101,116,0,118,103,114,111,117,112,95,110,97,109,101,91,51,50,93,0,107,101, -101,112,68,105,115,116,0,115,104,114,105,110,107,84,121,112,101,0,115,104,114,105,110,107,79,112,116,115,0,112,114,111, -106,65,120,105,115,0,115,117,98,115,117,114,102,76,101,118,101,108,115,0,42,111,114,105,103,105,110,0,102,97,99,116, -111,114,0,108,105,109,105,116,91,50,93,0,111,114,105,103,105,110,79,112,116,115,0,112,110,116,115,119,0,111,112,110, -116,115,117,0,111,112,110,116,115,118,0,111,112,110,116,115,119,0,116,121,112,101,117,0,116,121,112,101,118,0,116,121, -112,101,119,0,102,117,0,102,118,0,102,119,0,100,117,0,100,118,0,100,119,0,42,100,101,102,0,118,101,99,91,56, -93,91,51,93,0,112,97,114,116,121,112,101,0,112,97,114,49,0,112,97,114,50,0,112,97,114,51,0,112,97,114,115, -117,98,115,116,114,91,51,50,93,0,42,116,114,97,99,107,0,42,112,114,111,120,121,0,42,112,114,111,120,121,95,103, -114,111,117,112,0,42,112,114,111,120,121,95,102,114,111,109,0,42,97,99,116,105,111,110,0,42,112,111,115,101,108,105, -98,0,42,112,111,115,101,0,99,111,110,115,116,114,97,105,110,116,67,104,97,110,110,101,108,115,0,100,101,102,98,97, -115,101,0,109,111,100,105,102,105,101,114,115,0,100,108,111,99,91,51,93,0,111,114,105,103,91,51,93,0,100,115,105, -122,101,91,51,93,0,100,114,111,116,91,51,93,0,111,98,109,97,116,91,52,93,91,52,93,0,99,111,110,115,116,105, -110,118,91,52,93,91,52,93,0,108,97,121,0,99,111,108,98,105,116,115,0,116,114,97,110,115,102,108,97,103,0,105, -112,111,102,108,97,103,0,116,114,97,99,107,102,108,97,103,0,117,112,102,108,97,103,0,110,108,97,102,108,97,103,0, -112,114,111,116,101,99,116,102,108,97,103,0,105,112,111,119,105,110,0,115,99,97,102,108,97,103,0,115,99,97,118,105, -115,102,108,97,103,0,98,111,117,110,100,116,121,112,101,0,100,117,112,111,110,0,100,117,112,111,102,102,0,100,117,112, -115,116,97,0,100,117,112,101,110,100,0,115,102,0,99,116,105,109,101,0,109,97,115,115,0,100,97,109,112,105,110,103, -0,105,110,101,114,116,105,97,0,102,111,114,109,102,97,99,116,111,114,0,114,100,97,109,112,105,110,103,0,115,105,122, -101,102,97,99,0,109,97,114,103,105,110,0,109,97,120,95,118,101,108,0,109,105,110,95,118,101,108,0,109,95,99,111, -110,116,97,99,116,80,114,111,99,101,115,115,105,110,103,84,104,114,101,115,104,111,108,100,0,100,116,0,100,116,120,0, -97,99,116,99,111,108,0,101,109,112,116,121,95,100,114,97,119,116,121,112,101,0,112,97,100,49,91,51,93,0,101,109, -112,116,121,95,100,114,97,119,115,105,122,101,0,100,117,112,102,97,99,101,115,99,97,0,112,114,111,112,0,115,101,110, -115,111,114,115,0,99,111,110,116,114,111,108,108,101,114,115,0,97,99,116,117,97,116,111,114,115,0,98,98,115,105,122, -101,91,51,93,0,97,99,116,100,101,102,0,103,97,109,101,102,108,97,103,0,103,97,109,101,102,108,97,103,50,0,42, -98,115,111,102,116,0,115,111,102,116,102,108,97,103,0,97,110,105,115,111,116,114,111,112,105,99,70,114,105,99,116,105, -111,110,91,51,93,0,99,111,110,115,116,114,97,105,110,116,115,0,110,108,97,115,116,114,105,112,115,0,104,111,111,107, -115,0,112,97,114,116,105,99,108,101,115,121,115,116,101,109,0,42,112,100,0,42,115,111,102,116,0,42,100,117,112,95, -103,114,111,117,112,0,102,108,117,105,100,115,105,109,70,108,97,103,0,114,101,115,116,114,105,99,116,102,108,97,103,0, -115,104,97,112,101,110,114,0,115,104,97,112,101,102,108,97,103,0,114,101,99,97,108,99,111,0,98,111,100,121,95,116, -121,112,101,0,42,102,108,117,105,100,115,105,109,83,101,116,116,105,110,103,115,0,42,100,101,114,105,118,101,100,68,101, -102,111,114,109,0,42,100,101,114,105,118,101,100,70,105,110,97,108,0,108,97,115,116,68,97,116,97,77,97,115,107,0, -115,116,97,116,101,0,105,110,105,116,95,115,116,97,116,101,0,103,112,117,108,97,109,112,0,99,117,114,105,110,100,101, -120,0,97,99,116,105,118,101,0,100,101,102,108,101,99,116,0,102,111,114,99,101,102,105,101,108,100,0,112,100,101,102, -95,100,97,109,112,0,112,100,101,102,95,114,100,97,109,112,0,112,100,101,102,95,112,101,114,109,0,112,100,101,102,95, -102,114,105,99,116,0,112,100,101,102,95,114,102,114,105,99,116,0,102,95,115,116,114,101,110,103,116,104,0,102,95,112, -111,119,101,114,0,102,95,100,105,115,116,0,102,95,100,97,109,112,0,109,97,120,100,105,115,116,0,109,105,110,100,105, -115,116,0,109,97,120,114,97,100,0,109,105,110,114,97,100,0,102,95,112,111,119,101,114,95,114,0,112,100,101,102,95, -115,98,100,97,109,112,0,112,100,101,102,95,115,98,105,102,116,0,112,100,101,102,95,115,98,111,102,116,0,99,108,117, -109,112,95,102,97,99,0,99,108,117,109,112,95,112,111,119,0,107,105,110,107,95,102,114,101,113,0,107,105,110,107,95, -115,104,97,112,101,0,107,105,110,107,95,97,109,112,0,102,114,101,101,95,101,110,100,0,116,101,120,95,110,97,98,108, -97,0,116,101,120,95,109,111,100,101,0,107,105,110,107,0,107,105,110,107,95,97,120,105,115,0,114,116,50,0,42,114, -110,103,0,102,95,110,111,105,115,101,0,115,105,109,102,114,97,109,101,0,115,116,97,114,116,102,114,97,109,101,0,101, -110,100,102,114,97,109,101,0,101,100,105,116,102,114,97,109,101,0,108,105,110,83,116,105,102,102,0,97,110,103,83,116, -105,102,102,0,118,111,108,117,109,101,0,118,105,116,101,114,97,116,105,111,110,115,0,112,105,116,101,114,97,116,105,111, -110,115,0,100,105,116,101,114,97,116,105,111,110,115,0,99,105,116,101,114,97,116,105,111,110,115,0,107,83,82,72,82, -95,67,76,0,107,83,75,72,82,95,67,76,0,107,83,83,72,82,95,67,76,0,107,83,82,95,83,80,76,84,95,67, -76,0,107,83,75,95,83,80,76,84,95,67,76,0,107,83,83,95,83,80,76,84,95,67,76,0,107,86,67,70,0,107, -68,80,0,107,68,71,0,107,76,70,0,107,80,82,0,107,86,67,0,107,68,70,0,107,77,84,0,107,67,72,82,0, -107,75,72,82,0,107,83,72,82,0,107,65,72,82,0,99,111,108,108,105,115,105,111,110,102,108,97,103,115,0,110,117, -109,99,108,117,115,116,101,114,105,116,101,114,97,116,105,111,110,115,0,119,101,108,100,105,110,103,0,42,112,97,114,116, -105,99,108,101,115,0,116,111,116,112,111,105,110,116,0,116,111,116,115,112,114,105,110,103,0,42,98,112,111,105,110,116, -0,42,98,115,112,114,105,110,103,0,109,115,103,95,108,111,99,107,0,109,115,103,95,118,97,108,117,101,0,110,111,100, -101,109,97,115,115,0,110,97,109,101,100,86,71,95,77,97,115,115,91,51,50,93,0,103,114,97,118,0,109,101,100,105, -97,102,114,105,99,116,0,114,107,108,105,109,105,116,0,112,104,121,115,105,99,115,95,115,112,101,101,100,0,103,111,97, -108,115,112,114,105,110,103,0,103,111,97,108,102,114,105,99,116,0,109,105,110,103,111,97,108,0,109,97,120,103,111,97, -108,0,100,101,102,103,111,97,108,0,118,101,114,116,103,114,111,117,112,0,110,97,109,101,100,86,71,95,83,111,102,116, -103,111,97,108,91,51,50,93,0,102,117,122,122,121,110,101,115,115,0,105,110,115,112,114,105,110,103,0,105,110,102,114, -105,99,116,0,110,97,109,101,100,86,71,95,83,112,114,105,110,103,95,75,91,51,50,93,0,101,102,114,97,0,105,110, -116,101,114,118,97,108,0,108,111,99,97,108,0,115,111,108,118,101,114,102,108,97,103,115,0,42,42,107,101,121,115,0, -116,111,116,112,111,105,110,116,107,101,121,0,115,101,99,111,110,100,115,112,114,105,110,103,0,99,111,108,98,97,108,108, -0,98,97,108,108,100,97,109,112,0,98,97,108,108,115,116,105,102,102,0,115,98,99,95,109,111,100,101,0,97,101,114, -111,101,100,103,101,0,109,105,110,108,111,111,112,115,0,109,97,120,108,111,111,112,115,0,99,104,111,107,101,0,115,111, -108,118,101,114,95,73,68,0,112,108,97,115,116,105,99,0,115,112,114,105,110,103,112,114,101,108,111,97,100,0,42,115, -99,114,97,116,99,104,0,115,104,101,97,114,115,116,105,102,102,0,105,110,112,117,115,104,0,42,112,111,105,110,116,99, -97,99,104,101,0,115,104,111,119,95,97,100,118,97,110,99,101,100,111,112,116,105,111,110,115,0,114,101,115,111,108,117, -116,105,111,110,120,121,122,0,112,114,101,118,105,101,119,114,101,115,120,121,122,0,114,101,97,108,115,105,122,101,0,103, -117,105,68,105,115,112,108,97,121,77,111,100,101,0,114,101,110,100,101,114,68,105,115,112,108,97,121,77,111,100,101,0, -118,105,115,99,111,115,105,116,121,86,97,108,117,101,0,118,105,115,99,111,115,105,116,121,77,111,100,101,0,118,105,115, -99,111,115,105,116,121,69,120,112,111,110,101,110,116,0,103,114,97,118,120,0,103,114,97,118,121,0,103,114,97,118,122, -0,97,110,105,109,83,116,97,114,116,0,97,110,105,109,69,110,100,0,103,115,116,97,114,0,109,97,120,82,101,102,105, -110,101,0,105,110,105,86,101,108,120,0,105,110,105,86,101,108,121,0,105,110,105,86,101,108,122,0,42,111,114,103,77, -101,115,104,0,42,109,101,115,104,83,117,114,102,97,99,101,0,42,109,101,115,104,66,66,0,115,117,114,102,100,97,116, -97,80,97,116,104,91,50,52,48,93,0,98,98,83,116,97,114,116,91,51,93,0,98,98,83,105,122,101,91,51,93,0, -116,121,112,101,70,108,97,103,115,0,100,111,109,97,105,110,78,111,118,101,99,103,101,110,0,118,111,108,117,109,101,73, -110,105,116,84,121,112,101,0,112,97,114,116,83,108,105,112,86,97,108,117,101,0,103,101,110,101,114,97,116,101,84,114, -97,99,101,114,115,0,103,101,110,101,114,97,116,101,80,97,114,116,105,99,108,101,115,0,115,117,114,102,97,99,101,83, -109,111,111,116,104,105,110,103,0,115,117,114,102,97,99,101,83,117,98,100,105,118,115,0,112,97,114,116,105,99,108,101, -73,110,102,83,105,122,101,0,112,97,114,116,105,99,108,101,73,110,102,65,108,112,104,97,0,102,97,114,70,105,101,108, -100,83,105,122,101,0,42,109,101,115,104,83,117,114,102,78,111,114,109,97,108,115,0,99,112,115,84,105,109,101,83,116, -97,114,116,0,99,112,115,84,105,109,101,69,110,100,0,99,112,115,81,117,97,108,105,116,121,0,97,116,116,114,97,99, -116,102,111,114,99,101,83,116,114,101,110,103,116,104,0,97,116,116,114,97,99,116,102,111,114,99,101,82,97,100,105,117, -115,0,118,101,108,111,99,105,116,121,102,111,114,99,101,83,116,114,101,110,103,116,104,0,118,101,108,111,99,105,116,121, -102,111,114,99,101,82,97,100,105,117,115,0,108,97,115,116,103,111,111,100,102,114,97,109,101,0,109,105,115,116,121,112, -101,0,104,111,114,114,0,104,111,114,103,0,104,111,114,98,0,104,111,114,107,0,122,101,110,114,0,122,101,110,103,0, -122,101,110,98,0,122,101,110,107,0,97,109,98,107,0,102,97,115,116,99,111,108,0,101,120,112,111,115,117,114,101,0, -101,120,112,0,114,97,110,103,101,0,108,105,110,102,97,99,0,108,111,103,102,97,99,0,103,114,97,118,105,116,121,0, -97,99,116,105,118,105,116,121,66,111,120,82,97,100,105,117,115,0,115,107,121,116,121,112,101,0,111,99,99,108,117,115, -105,111,110,82,101,115,0,112,104,121,115,105,99,115,69,110,103,105,110,101,0,116,105,99,114,97,116,101,0,109,97,120, -108,111,103,105,99,115,116,101,112,0,112,104,121,115,117,98,115,116,101,112,0,109,97,120,112,104,121,115,116,101,112,0, -109,105,115,105,0,109,105,115,116,115,116,97,0,109,105,115,116,100,105,115,116,0,109,105,115,116,104,105,0,115,116,97, -114,114,0,115,116,97,114,103,0,115,116,97,114,98,0,115,116,97,114,107,0,115,116,97,114,115,105,122,101,0,115,116, -97,114,109,105,110,100,105,115,116,0,115,116,97,114,100,105,115,116,0,115,116,97,114,99,111,108,110,111,105,115,101,0, -100,111,102,115,116,97,0,100,111,102,101,110,100,0,100,111,102,109,105,110,0,100,111,102,109,97,120,0,97,111,100,105, -115,116,0,97,111,100,105,115,116,102,97,99,0,97,111,101,110,101,114,103,121,0,97,111,98,105,97,115,0,97,111,109, -111,100,101,0,97,111,115,97,109,112,0,97,111,109,105,120,0,97,111,99,111,108,111,114,0,97,111,95,97,100,97,112, -116,95,116,104,114,101,115,104,0,97,111,95,97,100,97,112,116,95,115,112,101,101,100,95,102,97,99,0,97,111,95,97, -112,112,114,111,120,95,101,114,114,111,114,0,97,111,95,97,112,112,114,111,120,95,99,111,114,114,101,99,116,105,111,110, -0,97,111,95,115,97,109,112,95,109,101,116,104,111,100,0,97,111,95,103,97,116,104,101,114,95,109,101,116,104,111,100, -0,97,111,95,97,112,112,114,111,120,95,112,97,115,115,101,115,0,42,97,111,115,112,104,101,114,101,0,42,97,111,116, -97,98,108,101,115,0,104,101,109,105,114,101,115,0,109,97,120,105,116,101,114,0,100,114,97,119,116,121,112,101,0,115, -117,98,115,104,111,111,116,112,0,115,117,98,115,104,111,111,116,101,0,110,111,100,101,108,105,109,0,109,97,120,115,117, -98,108,97,109,112,0,112,97,109,97,0,112,97,109,105,0,101,108,109,97,0,101,108,109,105,0,109,97,120,110,111,100, -101,0,99,111,110,118,101,114,103,101,110,99,101,0,114,97,100,102,97,99,0,103,97,109,109,97,0,115,101,108,99,111, -108,0,115,120,0,115,121,0,42,108,112,70,111,114,109,97,116,0,42,108,112,80,97,114,109,115,0,99,98,70,111,114, -109,97,116,0,99,98,80,97,114,109,115,0,102,99,99,84,121,112,101,0,102,99,99,72,97,110,100,108,101,114,0,100, -119,75,101,121,70,114,97,109,101,69,118,101,114,121,0,100,119,81,117,97,108,105,116,121,0,100,119,66,121,116,101,115, -80,101,114,83,101,99,111,110,100,0,100,119,70,108,97,103,115,0,100,119,73,110,116,101,114,108,101,97,118,101,69,118, -101,114,121,0,97,118,105,99,111,100,101,99,110,97,109,101,91,49,50,56,93,0,42,99,100,80,97,114,109,115,0,42, -112,97,100,0,99,100,83,105,122,101,0,113,116,99,111,100,101,99,110,97,109,101,91,49,50,56,93,0,99,111,100,101, -99,0,97,117,100,105,111,95,99,111,100,101,99,0,118,105,100,101,111,95,98,105,116,114,97,116,101,0,97,117,100,105, -111,95,98,105,116,114,97,116,101,0,103,111,112,95,115,105,122,101,0,114,99,95,109,105,110,95,114,97,116,101,0,114, -99,95,109,97,120,95,114,97,116,101,0,114,99,95,98,117,102,102,101,114,95,115,105,122,101,0,109,117,120,95,112,97, -99,107,101,116,95,115,105,122,101,0,109,117,120,95,114,97,116,101,0,109,105,120,114,97,116,101,0,109,97,105,110,0, -42,109,97,116,95,111,118,101,114,114,105,100,101,0,42,108,105,103,104,116,95,111,118,101,114,114,105,100,101,0,108,97, -121,95,122,109,97,115,107,0,108,97,121,102,108,97,103,0,112,97,115,115,102,108,97,103,0,112,97,115,115,95,120,111, -114,0,42,97,118,105,99,111,100,101,99,100,97,116,97,0,42,113,116,99,111,100,101,99,100,97,116,97,0,102,102,99, -111,100,101,99,100,97,116,97,0,99,102,114,97,0,112,115,102,114,97,0,112,101,102,114,97,0,105,109,97,103,101,115, -0,102,114,97,109,97,112,116,111,0,116,104,114,101,97,100,115,0,102,114,97,109,101,108,101,110,0,98,108,117,114,102, -97,99,0,101,100,103,101,82,0,101,100,103,101,71,0,101,100,103,101,66,0,102,117,108,108,115,99,114,101,101,110,0, -120,112,108,97,121,0,121,112,108,97,121,0,102,114,101,113,112,108,97,121,0,97,116,116,114,105,98,0,114,116,49,0, -115,116,101,114,101,111,109,111,100,101,0,100,105,109,101,110,115,105,111,110,115,112,114,101,115,101,116,0,109,97,120,105, -109,115,105,122,101,0,120,115,99,104,0,121,115,99,104,0,120,112,97,114,116,115,0,121,112,97,114,116,115,0,119,105, -110,112,111,115,0,112,108,97,110,101,115,0,105,109,116,121,112,101,0,115,117,98,105,109,116,121,112,101,0,113,117,97, -108,105,116,121,0,114,112,97,100,0,114,112,97,100,49,0,114,112,97,100,50,0,115,99,101,109,111,100,101,0,114,101, -110,100,101,114,101,114,0,111,99,114,101,115,0,97,108,112,104,97,109,111,100,101,0,111,115,97,0,102,114,115,95,115, -101,99,0,101,100,103,101,105,110,116,0,115,97,102,101,116,121,0,98,111,114,100,101,114,0,100,105,115,112,114,101,99, -116,0,108,97,121,101,114,115,0,97,99,116,108,97,121,0,120,97,115,112,0,121,97,115,112,0,102,114,115,95,115,101, -99,95,98,97,115,101,0,103,97,117,115,115,0,112,111,115,116,109,117,108,0,112,111,115,116,103,97,109,109,97,0,112, -111,115,116,104,117,101,0,112,111,115,116,115,97,116,0,100,105,116,104,101,114,95,105,110,116,101,110,115,105,116,121,0, -98,97,107,101,95,111,115,97,0,98,97,107,101,95,102,105,108,116,101,114,0,98,97,107,101,95,109,111,100,101,0,98, -97,107,101,95,102,108,97,103,0,98,97,107,101,95,110,111,114,109,97,108,95,115,112,97,99,101,0,98,97,107,101,95, -113,117,97,100,95,115,112,108,105,116,0,98,97,107,101,95,109,97,120,100,105,115,116,0,98,97,107,101,95,98,105,97, -115,100,105,115,116,0,98,97,107,101,95,112,97,100,0,71,73,113,117,97,108,105,116,121,0,71,73,99,97,99,104,101, -0,71,73,109,101,116,104,111,100,0,71,73,112,104,111,116,111,110,115,0,71,73,100,105,114,101,99,116,0,89,70,95, -65,65,0,89,70,101,120,112,111,114,116,120,109,108,0,89,70,95,110,111,98,117,109,112,0,89,70,95,99,108,97,109, -112,114,103,98,0,121,102,112,97,100,49,0,71,73,100,101,112,116,104,0,71,73,99,97,117,115,100,101,112,116,104,0, -71,73,112,105,120,101,108,115,112,101,114,115,97,109,112,108,101,0,71,73,112,104,111,116,111,110,99,111,117,110,116,0, -71,73,109,105,120,112,104,111,116,111,110,115,0,71,73,112,104,111,116,111,110,114,97,100,105,117,115,0,89,70,95,114, -97,121,100,101,112,116,104,0,89,70,95,65,65,112,97,115,115,101,115,0,89,70,95,65,65,115,97,109,112,108,101,115, -0,121,102,112,97,100,50,0,71,73,115,104,97,100,111,119,113,117,97,108,105,116,121,0,71,73,114,101,102,105,110,101, -109,101,110,116,0,71,73,112,111,119,101,114,0,71,73,105,110,100,105,114,112,111,119,101,114,0,89,70,95,103,97,109, -109,97,0,89,70,95,101,120,112,111,115,117,114,101,0,89,70,95,114,97,121,98,105,97,115,0,89,70,95,65,65,112, -105,120,101,108,115,105,122,101,0,89,70,95,65,65,116,104,114,101,115,104,111,108,100,0,98,97,99,107,98,117,102,91, -49,54,48,93,0,112,105,99,91,49,54,48,93,0,115,116,97,109,112,0,115,116,97,109,112,95,102,111,110,116,95,105, -100,0,115,116,97,109,112,95,117,100,97,116,97,91,49,54,48,93,0,102,103,95,115,116,97,109,112,91,52,93,0,98, -103,95,115,116,97,109,112,91,52,93,0,115,105,109,112,108,105,102,121,95,115,117,98,115,117,114,102,0,115,105,109,112, -108,105,102,121,95,115,104,97,100,111,119,115,97,109,112,108,101,115,0,115,105,109,112,108,105,102,121,95,112,97,114,116, -105,99,108,101,115,0,115,105,109,112,108,105,102,121,95,97,111,115,115,115,0,99,105,110,101,111,110,119,104,105,116,101, -0,99,105,110,101,111,110,98,108,97,99,107,0,99,105,110,101,111,110,103,97,109,109,97,0,106,112,50,95,112,114,101, -115,101,116,0,106,112,50,95,100,101,112,116,104,0,114,112,97,100,51,0,100,111,109,101,114,101,115,0,100,111,109,101, -109,111,100,101,0,100,111,109,101,97,110,103,108,101,0,100,111,109,101,116,105,108,116,0,100,111,109,101,114,101,115,98, -117,102,0,42,100,111,109,101,116,101,120,116,0,112,97,114,116,105,99,108,101,95,112,101,114,99,0,115,117,98,115,117, -114,102,95,109,97,120,0,115,104,97,100,98,117,102,115,97,109,112,108,101,95,109,97,120,0,97,111,95,101,114,114,111, -114,0,99,111,108,91,51,93,0,102,114,97,109,101,0,110,97,109,101,91,54,52,93,0,42,98,114,117,115,104,0,116, -111,111,108,0,115,101,97,109,95,98,108,101,101,100,0,110,111,114,109,97,108,95,97,110,103,108,101,0,115,116,101,112, -0,105,110,118,101,114,116,0,116,111,116,114,101,107,101,121,0,116,111,116,97,100,100,107,101,121,0,98,114,117,115,104, -116,121,112,101,0,98,114,117,115,104,91,55,93,0,101,109,105,116,116,101,114,100,105,115,116,0,100,114,97,119,95,116, -105,109,101,100,0,110,97,109,101,91,51,54,93,0,109,97,116,91,51,93,91,51,93,0,99,111,114,110,101,114,116,121, -112,101,0,101,100,105,116,98,117,116,102,108,97,103,0,106,111,105,110,116,114,105,108,105,109,105,116,0,100,101,103,114, -0,116,117,114,110,0,101,120,116,114,95,111,102,102,115,0,100,111,117,98,108,105,109,105,116,0,115,101,103,109,101,110, -116,115,0,114,105,110,103,115,0,118,101,114,116,105,99,101,115,0,117,110,119,114,97,112,112,101,114,0,117,118,99,97, -108,99,95,114,97,100,105,117,115,0,117,118,99,97,108,99,95,99,117,98,101,115,105,122,101,0,117,118,99,97,108,99, -95,109,97,114,103,105,110,0,117,118,99,97,108,99,95,109,97,112,100,105,114,0,117,118,99,97,108,99,95,109,97,112, -97,108,105,103,110,0,117,118,99,97,108,99,95,102,108,97,103,0,97,117,116,111,105,107,95,99,104,97,105,110,108,101, -110,0,105,109,97,112,97,105,110,116,0,112,97,114,116,105,99,108,101,0,115,101,108,101,99,116,95,116,104,114,101,115, -104,0,99,108,101,97,110,95,116,104,114,101,115,104,0,114,101,116,111,112,111,95,109,111,100,101,0,114,101,116,111,112, -111,95,112,97,105,110,116,95,116,111,111,108,0,108,105,110,101,95,100,105,118,0,101,108,108,105,112,115,101,95,100,105, -118,0,114,101,116,111,112,111,95,104,111,116,115,112,111,116,0,109,117,108,116,105,114,101,115,95,115,117,98,100,105,118, -95,116,121,112,101,0,115,107,103,101,110,95,114,101,115,111,108,117,116,105,111,110,0,115,107,103,101,110,95,116,104,114, -101,115,104,111,108,100,95,105,110,116,101,114,110,97,108,0,115,107,103,101,110,95,116,104,114,101,115,104,111,108,100,95, -101,120,116,101,114,110,97,108,0,115,107,103,101,110,95,108,101,110,103,116,104,95,114,97,116,105,111,0,115,107,103,101, -110,95,108,101,110,103,116,104,95,108,105,109,105,116,0,115,107,103,101,110,95,97,110,103,108,101,95,108,105,109,105,116, -0,115,107,103,101,110,95,99,111,114,114,101,108,97,116,105,111,110,95,108,105,109,105,116,0,115,107,103,101,110,95,115, -121,109,109,101,116,114,121,95,108,105,109,105,116,0,115,107,103,101,110,95,114,101,116,97,114,103,101,116,95,97,110,103, -108,101,95,119,101,105,103,104,116,0,115,107,103,101,110,95,114,101,116,97,114,103,101,116,95,108,101,110,103,116,104,95, -119,101,105,103,104,116,0,115,107,103,101,110,95,114,101,116,97,114,103,101,116,95,100,105,115,116,97,110,99,101,95,119, -101,105,103,104,116,0,115,107,103,101,110,95,111,112,116,105,111,110,115,0,115,107,103,101,110,95,112,111,115,116,112,114, -111,0,115,107,103,101,110,95,112,111,115,116,112,114,111,95,112,97,115,115,101,115,0,115,107,103,101,110,95,115,117,98, -100,105,118,105,115,105,111,110,115,91,51,93,0,115,107,103,101,110,95,109,117,108,116,105,95,108,101,118,101,108,0,42, -115,107,103,101,110,95,116,101,109,112,108,97,116,101,0,98,111,110,101,95,115,107,101,116,99,104,105,110,103,0,98,111, -110,101,95,115,107,101,116,99,104,105,110,103,95,99,111,110,118,101,114,116,0,115,107,103,101,110,95,115,117,98,100,105, -118,105,115,105,111,110,95,110,117,109,98,101,114,0,115,107,103,101,110,95,114,101,116,97,114,103,101,116,95,111,112,116, -105,111,110,115,0,115,107,103,101,110,95,114,101,116,97,114,103,101,116,95,114,111,108,108,0,115,107,103,101,110,95,115, -105,100,101,95,115,116,114,105,110,103,91,56,93,0,115,107,103,101,110,95,110,117,109,95,115,116,114,105,110,103,91,56, -93,0,101,100,103,101,95,109,111,100,101,0,112,97,100,51,91,50,93,0,100,105,114,0,118,105,101,119,0,42,115,101, -115,115,105,111,110,0,42,99,117,109,97,112,0,100,114,97,119,98,114,117,115,104,0,115,109,111,111,116,104,98,114,117, -115,104,0,112,105,110,99,104,98,114,117,115,104,0,105,110,102,108,97,116,101,98,114,117,115,104,0,103,114,97,98,98, -114,117,115,104,0,108,97,121,101,114,98,114,117,115,104,0,102,108,97,116,116,101,110,98,114,117,115,104,0,112,105,118, -111,116,91,51,93,0,98,114,117,115,104,95,116,121,112,101,0,116,101,120,110,114,0,116,101,120,114,101,112,116,0,116, -101,120,102,97,100,101,0,116,101,120,115,101,112,0,97,118,101,114,97,103,105,110,103,0,116,97,98,108,101,116,95,115, -105,122,101,0,116,97,98,108,101,116,95,115,116,114,101,110,103,116,104,0,115,121,109,109,0,114,97,107,101,0,97,120, -105,115,108,111,99,107,0,42,99,97,109,101,114,97,0,42,119,111,114,108,100,0,42,115,101,116,0,98,97,115,101,0, -42,98,97,115,97,99,116,0,99,117,114,115,111,114,91,51,93,0,116,119,99,101,110,116,91,51,93,0,116,119,109,105, -110,91,51,93,0,116,119,109,97,120,91,51,93,0,101,100,105,116,98,117,116,115,105,122,101,0,115,101,108,101,99,116, -109,111,100,101,0,112,114,111,112,111,114,116,105,111,110,97,108,0,112,114,111,112,95,109,111,100,101,0,97,117,116,111, -109,101,114,103,101,0,112,97,100,53,0,112,97,100,54,0,97,117,116,111,107,101,121,95,109,111,100,101,0,42,101,100, -0,42,114,97,100,105,111,0,102,114,97,109,105,110,103,0,42,116,111,111,108,115,101,116,116,105,110,103,115,0,97,117, -100,105,111,0,116,114,97,110,115,102,111,114,109,95,115,112,97,99,101,115,0,106,117,109,112,102,114,97,109,101,0,115, -110,97,112,95,109,111,100,101,0,115,110,97,112,95,102,108,97,103,0,115,110,97,112,95,116,97,114,103,101,116,0,42, -116,104,101,68,97,103,0,100,97,103,105,115,118,97,108,105,100,0,100,97,103,102,108,97,103,115,0,115,99,117,108,112, -116,100,97,116,97,0,102,114,97,109,101,95,115,116,101,112,0,122,111,111,109,0,98,108,101,110,100,0,120,105,109,0, -121,105,109,0,115,112,97,99,101,116,121,112,101,0,98,108,111,99,107,115,99,97,108,101,0,42,97,114,101,97,0,98, -108,111,99,107,104,97,110,100,108,101,114,91,56,93,0,118,105,101,119,109,97,116,91,52,93,91,52,93,0,118,105,101, -119,105,110,118,91,52,93,91,52,93,0,112,101,114,115,109,97,116,91,52,93,91,52,93,0,112,101,114,115,105,110,118, -91,52,93,91,52,93,0,119,105,110,109,97,116,49,91,52,93,91,52,93,0,118,105,101,119,109,97,116,49,91,52,93, -91,52,93,0,118,105,101,119,113,117,97,116,91,52,93,0,122,102,97,99,0,108,97,121,95,117,115,101,100,0,112,101, -114,115,112,0,42,111,98,95,99,101,110,116,114,101,0,42,98,103,112,105,99,0,42,108,111,99,97,108,118,100,0,42, -114,105,0,42,114,101,116,111,112,111,95,118,105,101,119,95,100,97,116,97,0,42,100,101,112,116,104,115,0,111,98,95, -99,101,110,116,114,101,95,98,111,110,101,91,51,50,93,0,108,111,99,97,108,118,105,101,119,0,108,97,121,97,99,116, -0,115,99,101,110,101,108,111,99,107,0,97,114,111,117,110,100,0,99,97,109,122,111,111,109,0,112,105,118,111,116,95, -108,97,115,116,0,103,114,105,100,0,103,114,105,100,118,105,101,119,0,112,105,120,115,105,122,101,0,110,101,97,114,0, -102,97,114,0,99,97,109,100,120,0,99,97,109,100,121,0,103,114,105,100,108,105,110,101,115,0,118,105,101,119,98,117, -116,0,103,114,105,100,102,108,97,103,0,109,111,100,101,115,101,108,101,99,116,0,116,119,116,121,112,101,0,116,119,109, -111,100,101,0,116,119,102,108,97,103,0,116,119,100,114,97,119,102,108,97,103,0,116,119,109,97,116,91,52,93,91,52, -93,0,99,108,105,112,91,52,93,91,52,93,0,42,99,108,105,112,98,98,0,97,102,116,101,114,100,114,97,119,0,122, -98,117,102,0,120,114,97,121,0,102,108,97,103,50,0,103,114,105,100,115,117,98,100,105,118,0,107,101,121,102,108,97, -103,115,0,110,100,111,102,109,111,100,101,0,110,100,111,102,102,105,108,116,101,114,0,42,112,114,111,112,101,114,116,105, -101,115,95,115,116,111,114,97,103,101,0,42,103,112,100,0,108,118,105,101,119,113,117,97,116,91,52,93,0,108,112,101, -114,115,112,0,108,118,105,101,119,0,118,101,114,116,0,104,111,114,0,109,97,115,107,0,109,105,110,91,50,93,0,109, -97,120,91,50,93,0,109,105,110,122,111,111,109,0,109,97,120,122,111,111,109,0,115,99,114,111,108,108,0,107,101,101, -112,116,111,116,0,107,101,101,112,97,115,112,101,99,116,0,107,101,101,112,122,111,111,109,0,111,108,100,119,105,110,120, -0,111,108,100,119,105,110,121,0,99,117,114,115,111,114,91,50,93,0,114,111,119,98,117,116,0,118,50,100,0,42,101, -100,105,116,105,112,111,0,105,112,111,107,101,121,0,97,99,116,110,97,109,101,91,51,50,93,0,99,111,110,115,116,110, -97,109,101,91,51,50,93,0,98,111,110,101,110,97,109,101,91,51,50,93,0,116,111,116,105,112,111,0,112,105,110,0, -98,117,116,111,102,115,0,99,104,97,110,110,101,108,0,108,111,99,107,0,109,101,100,105,97,110,91,51,93,0,99,117, -114,115,101,110,115,0,99,117,114,97,99,116,0,97,108,105,103,110,0,116,97,98,111,0,109,97,105,110,98,0,109,97, -105,110,98,111,0,42,108,111,99,107,112,111,105,110,0,116,101,120,102,114,111,109,0,115,104,111,119,103,114,111,117,112, -0,109,111,100,101,108,116,121,112,101,0,115,99,114,105,112,116,98,108,111,99,107,0,114,101,95,97,108,105,103,110,0, -111,108,100,107,101,121,112,114,101,115,115,0,116,97,98,91,55,93,0,114,101,110,100,101,114,95,115,105,122,101,0,99, -104,97,110,115,104,111,119,110,0,122,101,98,114,97,0,42,102,105,108,101,108,105,115,116,0,116,111,116,102,105,108,101, -0,116,105,116,108,101,91,50,52,93,0,100,105,114,91,50,52,48,93,0,102,105,108,101,91,56,48,93,0,111,102,115, -0,115,111,114,116,0,109,97,120,110,97,109,101,108,101,110,0,99,111,108,108,117,109,115,0,102,95,102,112,0,102,112, -95,115,116,114,91,56,93,0,42,108,105,98,102,105,108,101,100,97,116,97,0,114,101,116,118,97,108,0,109,101,110,117, -0,97,99,116,0,40,42,114,101,116,117,114,110,102,117,110,99,41,40,41,0,40,42,114,101,116,117,114,110,102,117,110, -99,95,101,118,101,110,116,41,40,41,0,40,42,114,101,116,117,114,110,102,117,110,99,95,97,114,103,115,41,40,41,0, -42,97,114,103,49,0,42,97,114,103,50,0,42,109,101,110,117,112,0,42,112,117,112,109,101,110,117,0,111,111,112,115, -0,118,105,115,105,102,108,97,103,0,116,114,101,101,0,42,116,114,101,101,115,116,111,114,101,0,115,101,97,114,99,104, -95,115,116,114,105,110,103,91,51,50,93,0,115,101,97,114,99,104,95,116,115,101,0,115,101,97,114,99,104,95,102,108, -97,103,115,0,100,111,95,0,111,117,116,108,105,110,101,118,105,115,0,115,116,111,114,101,102,108,97,103,0,100,101,112, -115,95,102,108,97,103,115,0,105,109,97,110,114,0,99,117,114,116,105,108,101,0,105,109,116,121,112,101,110,114,0,100, -116,95,117,118,0,115,116,105,99,107,121,0,100,116,95,117,118,115,116,114,101,116,99,104,0,112,97,100,91,53,93,0, -99,101,110,116,120,0,99,101,110,116,121,0,97,117,116,111,115,110,97,112,0,42,116,101,120,116,0,116,111,112,0,118, -105,101,119,108,105,110,101,115,0,102,111,110,116,95,105,100,0,108,104,101,105,103,104,116,0,108,101,102,116,0,115,104, -111,119,108,105,110,101,110,114,115,0,116,97,98,110,117,109,98,101,114,0,99,117,114,114,116,97,98,95,115,101,116,0, -115,104,111,119,115,121,110,116,97,120,0,111,118,101,114,119,114,105,116,101,0,112,105,120,95,112,101,114,95,108,105,110, -101,0,116,120,116,115,99,114,111,108,108,0,116,120,116,98,97,114,0,119,111,114,100,119,114,97,112,0,100,111,112,108, -117,103,105,110,115,0,42,112,121,95,100,114,97,119,0,42,112,121,95,101,118,101,110,116,0,42,112,121,95,98,117,116, -116,111,110,0,42,112,121,95,98,114,111,119,115,101,114,99,97,108,108,98,97,99,107,0,42,112,121,95,103,108,111,98, -97,108,100,105,99,116,0,108,97,115,116,115,112,97,99,101,0,115,99,114,105,112,116,110,97,109,101,91,50,53,54,93, -0,115,99,114,105,112,116,97,114,103,91,50,53,54,93,0,42,115,99,114,105,112,116,0,42,98,117,116,95,114,101,102, -115,0,114,101,100,114,97,119,115,0,42,105,100,0,97,115,112,101,99,116,0,42,99,117,114,102,111,110,116,0,42,101, -100,105,116,116,114,101,101,0,116,114,101,101,116,121,112,101,0,42,102,105,108,101,115,0,97,99,116,105,118,101,95,102, -105,108,101,0,110,117,109,116,105,108,101,115,120,0,110,117,109,116,105,108,101,115,121,0,115,101,108,115,116,97,116,101, -0,118,105,101,119,114,101,99,116,0,98,111,111,107,109,97,114,107,114,101,99,116,0,115,99,114,111,108,108,112,111,115, -0,115,99,114,111,108,108,104,101,105,103,104,116,0,115,99,114,111,108,108,97,114,101,97,0,97,99,116,105,118,101,95, -98,111,111,107,109,97,114,107,0,112,114,118,95,119,0,112,114,118,95,104,0,42,105,109,103,0,111,117,116,108,105,110, -101,91,52,93,0,110,101,117,116,114,97,108,91,52,93,0,97,99,116,105,111,110,91,52,93,0,115,101,116,116,105,110, -103,91,52,93,0,115,101,116,116,105,110,103,49,91,52,93,0,115,101,116,116,105,110,103,50,91,52,93,0,110,117,109, -91,52,93,0,116,101,120,116,102,105,101,108,100,91,52,93,0,116,101,120,116,102,105,101,108,100,95,104,105,91,52,93, -0,112,111,112,117,112,91,52,93,0,116,101,120,116,91,52,93,0,116,101,120,116,95,104,105,91,52,93,0,109,101,110, -117,95,98,97,99,107,91,52,93,0,109,101,110,117,95,105,116,101,109,91,52,93,0,109,101,110,117,95,104,105,108,105, -116,101,91,52,93,0,109,101,110,117,95,116,101,120,116,91,52,93,0,109,101,110,117,95,116,101,120,116,95,104,105,91, -52,93,0,98,117,116,95,100,114,97,119,116,121,112,101,0,105,99,111,110,102,105,108,101,91,56,48,93,0,98,97,99, -107,91,52,93,0,104,101,97,100,101,114,91,52,93,0,112,97,110,101,108,91,52,93,0,115,104,97,100,101,49,91,52, -93,0,115,104,97,100,101,50,91,52,93,0,104,105,108,105,116,101,91,52,93,0,103,114,105,100,91,52,93,0,119,105, -114,101,91,52,93,0,115,101,108,101,99,116,91,52,93,0,108,97,109,112,91,52,93,0,97,99,116,105,118,101,91,52, -93,0,103,114,111,117,112,91,52,93,0,103,114,111,117,112,95,97,99,116,105,118,101,91,52,93,0,116,114,97,110,115, -102,111,114,109,91,52,93,0,118,101,114,116,101,120,91,52,93,0,118,101,114,116,101,120,95,115,101,108,101,99,116,91, -52,93,0,101,100,103,101,91,52,93,0,101,100,103,101,95,115,101,108,101,99,116,91,52,93,0,101,100,103,101,95,115, -101,97,109,91,52,93,0,101,100,103,101,95,115,104,97,114,112,91,52,93,0,101,100,103,101,95,102,97,99,101,115,101, -108,91,52,93,0,102,97,99,101,91,52,93,0,102,97,99,101,95,115,101,108,101,99,116,91,52,93,0,102,97,99,101, -95,100,111,116,91,52,93,0,110,111,114,109,97,108,91,52,93,0,98,111,110,101,95,115,111,108,105,100,91,52,93,0, -98,111,110,101,95,112,111,115,101,91,52,93,0,115,116,114,105,112,91,52,93,0,115,116,114,105,112,95,115,101,108,101, -99,116,91,52,93,0,99,102,114,97,109,101,91,52,93,0,118,101,114,116,101,120,95,115,105,122,101,0,102,97,99,101, -100,111,116,95,115,105,122,101,0,98,112,97,100,91,50,93,0,115,121,110,116,97,120,108,91,52,93,0,115,121,110,116, -97,120,110,91,52,93,0,115,121,110,116,97,120,98,91,52,93,0,115,121,110,116,97,120,118,91,52,93,0,115,121,110, -116,97,120,99,91,52,93,0,109,111,118,105,101,91,52,93,0,105,109,97,103,101,91,52,93,0,115,99,101,110,101,91, -52,93,0,97,117,100,105,111,91,52,93,0,101,102,102,101,99,116,91,52,93,0,112,108,117,103,105,110,91,52,93,0, -116,114,97,110,115,105,116,105,111,110,91,52,93,0,109,101,116,97,91,52,93,0,101,100,105,116,109,101,115,104,95,97, -99,116,105,118,101,91,52,93,0,104,97,110,100,108,101,95,118,101,114,116,101,120,91,52,93,0,104,97,110,100,108,101, -95,118,101,114,116,101,120,95,115,101,108,101,99,116,91,52,93,0,104,97,110,100,108,101,95,118,101,114,116,101,120,95, -115,105,122,101,0,104,112,97,100,91,55,93,0,115,111,108,105,100,91,52,93,0,116,117,105,0,116,98,117,116,115,0, -116,118,51,100,0,116,102,105,108,101,0,116,105,112,111,0,116,105,110,102,111,0,116,115,110,100,0,116,97,99,116,0, -116,110,108,97,0,116,115,101,113,0,116,105,109,97,0,116,105,109,97,115,101,108,0,116,101,120,116,0,116,111,111,112, -115,0,116,116,105,109,101,0,116,110,111,100,101,0,116,97,114,109,91,50,48,93,0,98,112,97,100,91,52,93,0,98, -112,97,100,49,91,52,93,0,115,112,101,99,91,52,93,0,100,117,112,102,108,97,103,0,115,97,118,101,116,105,109,101, -0,116,101,109,112,100,105,114,91,49,54,48,93,0,102,111,110,116,100,105,114,91,49,54,48,93,0,114,101,110,100,101, -114,100,105,114,91,49,54,48,93,0,116,101,120,116,117,100,105,114,91,49,54,48,93,0,112,108,117,103,116,101,120,100, -105,114,91,49,54,48,93,0,112,108,117,103,115,101,113,100,105,114,91,49,54,48,93,0,112,121,116,104,111,110,100,105, -114,91,49,54,48,93,0,115,111,117,110,100,100,105,114,91,49,54,48,93,0,121,102,101,120,112,111,114,116,100,105,114, -91,49,54,48,93,0,118,101,114,115,105,111,110,115,0,118,114,109,108,102,108,97,103,0,103,97,109,101,102,108,97,103, -115,0,119,104,101,101,108,108,105,110,101,115,99,114,111,108,108,0,117,105,102,108,97,103,0,108,97,110,103,117,97,103, -101,0,117,115,101,114,112,114,101,102,0,118,105,101,119,122,111,111,109,0,99,111,110,115,111,108,101,95,98,117,102,102, -101,114,0,99,111,110,115,111,108,101,95,111,117,116,0,109,105,120,98,117,102,115,105,122,101,0,102,111,110,116,115,105, -122,101,0,101,110,99,111,100,105,110,103,0,116,114,97,110,115,111,112,116,115,0,109,101,110,117,116,104,114,101,115,104, -111,108,100,49,0,109,101,110,117,116,104,114,101,115,104,111,108,100,50,0,102,111,110,116,110,97,109,101,91,50,53,54, -93,0,116,104,101,109,101,115,0,117,110,100,111,115,116,101,112,115,0,117,110,100,111,109,101,109,111,114,121,0,103,112, -95,109,97,110,104,97,116,116,101,110,100,105,115,116,0,103,112,95,101,117,99,108,105,100,101,97,110,100,105,115,116,0, -103,112,95,101,114,97,115,101,114,0,103,112,95,115,101,116,116,105,110,103,115,0,116,98,95,108,101,102,116,109,111,117, -115,101,0,116,98,95,114,105,103,104,116,109,111,117,115,101,0,108,105,103,104,116,91,51,93,0,116,119,95,104,111,116, -115,112,111,116,0,116,119,95,102,108,97,103,0,116,119,95,104,97,110,100,108,101,115,105,122,101,0,116,119,95,115,105, -122,101,0,116,101,120,116,105,109,101,111,117,116,0,116,101,120,99,111,108,108,101,99,116,114,97,116,101,0,109,101,109, -99,97,99,104,101,108,105,109,105,116,0,112,114,101,102,101,116,99,104,102,114,97,109,101,115,0,102,114,97,109,101,115, -101,114,118,101,114,112,111,114,116,0,112,97,100,95,114,111,116,95,97,110,103,108,101,0,111,98,99,101,110,116,101,114, -95,100,105,97,0,114,118,105,115,105,122,101,0,114,118,105,98,114,105,103,104,116,0,114,101,99,101,110,116,95,102,105, -108,101,115,0,115,109,111,111,116,104,95,118,105,101,119,116,120,0,103,108,114,101,115,108,105,109,105,116,0,110,100,111, -102,95,112,97,110,0,110,100,111,102,95,114,111,116,97,116,101,0,99,117,114,115,115,105,122,101,0,112,97,100,91,56, -93,0,118,101,114,115,101,109,97,115,116,101,114,91,49,54,48,93,0,118,101,114,115,101,117,115,101,114,91,49,54,48, -93,0,103,108,97,108,112,104,97,99,108,105,112,0,97,117,116,111,107,101,121,95,102,108,97,103,0,99,111,98,97,95, -119,101,105,103,104,116,0,118,101,114,116,98,97,115,101,0,101,100,103,101,98,97,115,101,0,97,114,101,97,98,97,115, -101,0,42,115,99,101,110,101,0,101,110,100,120,0,101,110,100,121,0,115,105,122,101,120,0,115,105,122,101,121,0,115, -99,101,110,101,110,114,0,115,99,114,101,101,110,110,114,0,102,117,108,108,0,109,97,105,110,119,105,110,0,119,105,110, -97,107,116,0,104,97,110,100,108,101,114,91,56,93,0,42,110,101,119,118,0,118,101,99,0,42,118,49,0,42,118,50, -0,112,97,110,101,108,110,97,109,101,91,54,52,93,0,116,97,98,110,97,109,101,91,54,52,93,0,100,114,97,119,110, -97,109,101,91,54,52,93,0,111,102,115,120,0,111,102,115,121,0,99,111,110,116,114,111,108,0,115,110,97,112,0,111, -108,100,95,111,102,115,120,0,111,108,100,95,111,102,115,121,0,115,111,114,116,99,111,117,110,116,101,114,0,42,112,97, -110,101,108,116,97,98,0,42,118,51,0,42,118,52,0,42,102,117,108,108,0,119,105,110,109,97,116,91,52,93,91,52, -93,0,104,101,97,100,114,99,116,0,119,105,110,114,99,116,0,104,101,97,100,119,105,110,0,119,105,110,0,104,101,97, -100,101,114,116,121,112,101,0,98,117,116,115,112,97,99,101,116,121,112,101,0,119,105,110,120,0,119,105,110,121,0,104, -101,97,100,95,115,119,97,112,0,104,101,97,100,95,101,113,117,97,108,0,119,105,110,95,115,119,97,112,0,119,105,110, -95,101,113,117,97,108,0,104,101,97,100,98,117,116,108,101,110,0,104,101,97,100,98,117,116,111,102,115,0,99,117,114, -115,111,114,0,115,112,97,99,101,100,97,116,97,0,117,105,98,108,111,99,107,115,0,112,97,110,101,108,115,0,115,117, -98,118,115,116,114,91,52,93,0,115,117,98,118,101,114,115,105,111,110,0,112,97,100,115,0,109,105,110,118,101,114,115, -105,111,110,0,109,105,110,115,117,98,118,101,114,115,105,111,110,0,100,105,115,112,108,97,121,109,111,100,101,0,42,99, -117,114,115,99,114,101,101,110,0,42,99,117,114,115,99,101,110,101,0,102,105,108,101,102,108,97,103,115,0,103,108,111, -98,97,108,102,0,110,97,109,101,91,56,48,93,0,42,105,98,117,102,0,42,105,98,117,102,95,99,111,109,112,0,42, -115,101,49,0,42,115,101,50,0,42,115,101,51,0,110,114,0,98,111,116,116,111,109,0,114,105,103,104,116,0,120,111, -102,115,0,121,111,102,115,0,108,105,102,116,91,51,93,0,103,97,109,109,97,91,51,93,0,103,97,105,110,91,51,93, -0,115,97,116,117,114,97,116,105,111,110,0,42,103,117,105,0,100,105,114,91,49,54,48,93,0,100,111,110,101,0,115, -116,97,114,116,115,116,105,108,108,0,101,110,100,115,116,105,108,108,0,42,115,116,114,105,112,100,97,116,97,0,111,114, -120,0,111,114,121,0,42,99,114,111,112,0,42,116,114,97,110,115,102,111,114,109,0,42,99,111,108,111,114,95,98,97, -108,97,110,99,101,0,42,116,115,116,114,105,112,100,97,116,97,0,42,116,115,116,114,105,112,100,97,116,97,95,115,116, -97,114,116,115,116,105,108,108,0,42,116,115,116,114,105,112,100,97,116,97,95,101,110,100,115,116,105,108,108,0,42,105, -98,117,102,95,115,116,97,114,116,115,116,105,108,108,0,42,105,98,117,102,95,101,110,100,115,116,105,108,108,0,42,105, -110,115,116,97,110,99,101,95,112,114,105,118,97,116,101,95,100,97,116,97,0,42,42,99,117,114,114,101,110,116,95,112, -114,105,118,97,116,101,95,100,97,116,97,0,42,116,109,112,0,115,116,97,114,116,111,102,115,0,101,110,100,111,102,115, -0,109,97,99,104,105,110,101,0,115,116,97,114,116,100,105,115,112,0,101,110,100,100,105,115,112,0,109,117,108,0,104, -97,110,100,115,105,122,101,0,97,110,105,109,95,112,114,101,115,101,101,107,0,42,115,116,114,105,112,0,102,97,99,102, -48,0,102,97,99,102,49,0,42,115,101,113,49,0,42,115,101,113,50,0,42,115,101,113,51,0,115,101,113,98,97,115, -101,0,42,115,111,117,110,100,0,42,104,100,97,117,100,105,111,0,108,101,118,101,108,0,112,97,110,0,115,116,114,111, -98,101,0,42,101,102,102,101,99,116,100,97,116,97,0,97,110,105,109,95,115,116,97,114,116,111,102,115,0,97,110,105, -109,95,101,110,100,111,102,115,0,98,108,101,110,100,95,109,111,100,101,0,98,108,101,110,100,95,111,112,97,99,105,116, -121,0,42,111,108,100,98,97,115,101,112,0,42,112,97,114,115,101,113,0,42,115,101,113,98,97,115,101,112,0,109,101, -116,97,115,116,97,99,107,0,101,100,103,101,87,105,100,116,104,0,102,111,114,119,97,114,100,0,119,105,112,101,116,121, -112,101,0,102,77,105,110,105,0,102,67,108,97,109,112,0,102,66,111,111,115,116,0,100,68,105,115,116,0,100,81,117, -97,108,105,116,121,0,98,78,111,67,111,109,112,0,83,99,97,108,101,120,73,110,105,0,83,99,97,108,101,121,73,110, -105,0,83,99,97,108,101,120,70,105,110,0,83,99,97,108,101,121,70,105,110,0,120,73,110,105,0,120,70,105,110,0, -121,73,110,105,0,121,70,105,110,0,114,111,116,73,110,105,0,114,111,116,70,105,110,0,105,110,116,101,114,112,111,108, -97,116,105,111,110,0,42,102,114,97,109,101,77,97,112,0,103,108,111,98,97,108,83,112,101,101,100,0,108,97,115,116, -86,97,108,105,100,70,114,97,109,101,0,98,108,101,110,100,70,114,97,109,101,115,0,98,117,116,116,121,112,101,0,117, -115,101,114,106,105,116,0,115,116,97,0,116,111,116,112,97,114,116,0,110,111,114,109,102,97,99,0,111,98,102,97,99, -0,114,97,110,100,102,97,99,0,116,101,120,102,97,99,0,114,97,110,100,108,105,102,101,0,102,111,114,99,101,91,51, -93,0,118,101,99,116,115,105,122,101,0,109,97,120,108,101,110,0,100,101,102,118,101,99,91,51,93,0,109,117,108,116, -91,52,93,0,108,105,102,101,91,52,93,0,99,104,105,108,100,91,52,93,0,109,97,116,91,52,93,0,116,101,120,109, -97,112,0,99,117,114,109,117,108,116,0,115,116,97,116,105,99,115,116,101,112,0,111,109,97,116,0,116,105,109,101,116, -101,120,0,115,112,101,101,100,116,101,120,0,102,108,97,103,50,110,101,103,0,118,101,114,116,103,114,111,117,112,95,118, -0,118,103,114,111,117,112,110,97,109,101,91,51,50,93,0,118,103,114,111,117,112,110,97,109,101,95,118,91,51,50,93, -0,42,107,101,121,115,0,109,105,110,102,97,99,0,117,115,101,100,0,117,115,101,100,101,108,101,109,0,100,120,0,100, -121,0,108,105,110,107,0,111,116,121,112,101,0,111,108,100,0,42,112,111,105,110,0,42,111,108,100,112,111,105,110,0, -114,101,115,101,116,100,105,115,116,0,108,97,115,116,118,97,108,0,42,109,97,0,107,101,121,0,113,117,97,108,0,113, -117,97,108,50,0,116,97,114,103,101,116,78,97,109,101,91,51,50,93,0,116,111,103,103,108,101,78,97,109,101,91,51, -50,93,0,118,97,108,117,101,91,51,50,93,0,109,97,120,118,97,108,117,101,91,51,50,93,0,100,101,108,97,121,0, -100,117,114,97,116,105,111,110,0,109,97,116,101,114,105,97,108,78,97,109,101,91,51,50,93,0,100,97,109,112,116,105, -109,101,114,0,112,114,111,112,110,97,109,101,91,51,50,93,0,109,97,116,110,97,109,101,91,51,50,93,0,97,120,105, -115,102,108,97,103,0,42,102,114,111,109,79,98,106,101,99,116,0,115,117,98,106,101,99,116,91,51,50,93,0,98,111, -100,121,91,51,50,93,0,112,117,108,115,101,0,102,114,101,113,0,116,111,116,108,105,110,107,115,0,42,42,108,105,110, -107,115,0,116,97,112,0,106,111,121,105,110,100,101,120,0,97,120,105,115,95,115,105,110,103,108,101,0,97,120,105,115, -102,0,98,117,116,116,111,110,0,104,97,116,0,104,97,116,102,0,112,114,101,99,105,115,105,111,110,0,115,116,114,91, -49,50,56,93,0,109,111,100,117,108,101,91,54,52,93,0,42,109,121,110,101,119,0,105,110,112,117,116,115,0,116,111, -116,115,108,105,110,107,115,0,42,42,115,108,105,110,107,115,0,118,97,108,111,0,115,116,97,116,101,95,109,97,115,107, -0,42,97,99,116,0,102,114,97,109,101,80,114,111,112,91,51,50,93,0,98,108,101,110,100,105,110,0,112,114,105,111, -114,105,116,121,0,101,110,100,95,114,101,115,101,116,0,115,116,114,105,100,101,97,120,105,115,0,115,116,114,105,100,101, -108,101,110,103,116,104,0,115,110,100,110,114,0,112,97,100,49,91,50,93,0,109,97,107,101,99,111,112,121,0,99,111, -112,121,109,97,100,101,0,112,97,100,50,91,49,93,0,116,114,97,99,107,0,42,109,101,0,108,105,110,86,101,108,111, -99,105,116,121,91,51,93,0,97,110,103,86,101,108,111,99,105,116,121,91,51,93,0,108,111,99,97,108,102,108,97,103, -0,100,121,110,95,111,112,101,114,97,116,105,111,110,0,102,111,114,99,101,108,111,99,91,51,93,0,102,111,114,99,101, -114,111,116,91,51,93,0,108,105,110,101,97,114,118,101,108,111,99,105,116,121,91,51,93,0,97,110,103,117,108,97,114, -118,101,108,111,99,105,116,121,91,51,93,0,42,114,101,102,101,114,101,110,99,101,0,98,117,116,115,116,97,0,98,117, -116,101,110,100,0,109,105,110,0,109,97,120,0,118,105,115,105,102,97,99,0,114,111,116,100,97,109,112,0,109,105,110, -108,111,99,91,51,93,0,109,97,120,108,111,99,91,51,93,0,109,105,110,114,111,116,91,51,93,0,109,97,120,114,111, -116,91,51,93,0,109,97,116,112,114,111,112,91,51,50,93,0,100,105,115,116,114,105,98,117,116,105,111,110,0,105,110, -116,95,97,114,103,95,49,0,105,110,116,95,97,114,103,95,50,0,102,108,111,97,116,95,97,114,103,95,49,0,102,108, -111,97,116,95,97,114,103,95,50,0,116,111,80,114,111,112,78,97,109,101,91,51,50,93,0,42,116,111,79,98,106,101, -99,116,0,98,111,100,121,84,121,112,101,0,102,105,108,101,110,97,109,101,91,54,52,93,0,108,111,97,100,97,110,105, -110,97,109,101,91,54,52,93,0,105,110,116,95,97,114,103,0,102,108,111,97,116,95,97,114,103,0,103,111,0,97,99, -99,101,108,108,101,114,97,116,105,111,110,0,109,97,120,115,112,101,101,100,0,109,97,120,114,111,116,115,112,101,101,100, -0,109,97,120,116,105,108,116,115,112,101,101,100,0,116,105,108,116,100,97,109,112,0,115,112,101,101,100,100,97,109,112, -0,42,115,97,109,112,108,101,0,42,115,116,114,101,97,109,0,42,110,101,119,112,97,99,107,101,100,102,105,108,101,0, -42,115,110,100,95,115,111,117,110,100,0,112,97,110,110,105,110,103,0,97,116,116,101,110,117,97,116,105,111,110,0,112, -105,116,99,104,0,109,105,110,95,103,97,105,110,0,109,97,120,95,103,97,105,110,0,100,105,115,116,97,110,99,101,0, -115,116,114,101,97,109,108,101,110,0,99,104,97,110,110,101,108,115,0,104,105,103,104,112,114,105,111,0,112,97,100,91, -49,48,93,0,103,97,105,110,0,100,111,112,112,108,101,114,102,97,99,116,111,114,0,100,111,112,112,108,101,114,118,101, -108,111,99,105,116,121,0,110,117,109,115,111,117,110,100,115,98,108,101,110,100,101,114,0,110,117,109,115,111,117,110,100, -115,103,97,109,101,101,110,103,105,110,101,0,42,108,97,109,112,114,101,110,0,103,111,98,106,101,99,116,0,100,117,112, -108,105,95,111,102,115,91,51,93,0,99,104,105,108,100,98,97,115,101,0,114,111,108,108,0,104,101,97,100,91,51,93, -0,116,97,105,108,91,51,93,0,98,111,110,101,95,109,97,116,91,51,93,91,51,93,0,97,114,109,95,104,101,97,100, -91,51,93,0,97,114,109,95,116,97,105,108,91,51,93,0,97,114,109,95,109,97,116,91,52,93,91,52,93,0,120,119, -105,100,116,104,0,122,119,105,100,116,104,0,101,97,115,101,49,0,101,97,115,101,50,0,114,97,100,95,104,101,97,100, -0,114,97,100,95,116,97,105,108,0,98,111,110,101,98,97,115,101,0,99,104,97,105,110,98,97,115,101,0,112,97,116, -104,102,108,97,103,0,108,97,121,101,114,95,112,114,111,116,101,99,116,101,100,0,103,104,111,115,116,101,112,0,103,104, -111,115,116,115,105,122,101,0,103,104,111,115,116,116,121,112,101,0,112,97,116,104,115,105,122,101,0,103,104,111,115,116, -115,102,0,103,104,111,115,116,101,102,0,112,97,116,104,115,102,0,112,97,116,104,101,102,0,112,97,116,104,98,99,0, -112,97,116,104,97,99,0,99,111,110,115,116,102,108,97,103,0,105,107,102,108,97,103,0,115,101,108,101,99,116,102,108, -97,103,0,97,103,114,112,95,105,110,100,101,120,0,42,98,111,110,101,0,42,99,104,105,108,100,0,105,107,116,114,101, -101,0,42,98,95,98,111,110,101,95,109,97,116,115,0,42,100,117,97,108,95,113,117,97,116,0,42,98,95,98,111,110, -101,95,100,117,97,108,95,113,117,97,116,115,0,99,104,97,110,95,109,97,116,91,52,93,91,52,93,0,112,111,115,101, -95,109,97,116,91,52,93,91,52,93,0,112,111,115,101,95,104,101,97,100,91,51,93,0,112,111,115,101,95,116,97,105, -108,91,51,93,0,108,105,109,105,116,109,105,110,91,51,93,0,108,105,109,105,116,109,97,120,91,51,93,0,115,116,105, -102,102,110,101,115,115,91,51,93,0,105,107,115,116,114,101,116,99,104,0,42,99,117,115,116,111,109,0,99,104,97,110, -98,97,115,101,0,112,114,111,120,121,95,108,97,121,101,114,0,115,116,114,105,100,101,95,111,102,102,115,101,116,91,51, -93,0,99,121,99,108,105,99,95,111,102,102,115,101,116,91,51,93,0,97,103,114,111,117,112,115,0,97,99,116,105,118, -101,95,103,114,111,117,112,0,99,117,115,116,111,109,67,111,108,0,99,115,0,42,103,114,112,0,114,101,115,101,114,118, -101,100,49,0,103,114,111,117,112,115,0,97,99,116,105,118,101,95,109,97,114,107,101,114,0,97,99,116,110,114,0,97, -99,116,119,105,100,116,104,0,116,105,109,101,115,108,105,100,101,0,110,97,109,101,91,51,48,93,0,111,119,110,115,112, -97,99,101,0,116,97,114,115,112,97,99,101,0,101,110,102,111,114,99,101,0,104,101,97,100,116,97,105,108,0,42,116, -97,114,0,115,117,98,116,97,114,103,101,116,91,51,50,93,0,109,97,116,114,105,120,91,52,93,91,52,93,0,115,112, -97,99,101,0,42,112,114,111,112,0,116,97,114,110,117,109,0,116,97,114,103,101,116,115,0,105,116,101,114,97,116,105, -111,110,115,0,114,111,111,116,98,111,110,101,0,109,97,120,95,114,111,111,116,98,111,110,101,0,42,112,111,108,101,116, -97,114,0,112,111,108,101,115,117,98,116,97,114,103,101,116,91,51,50,93,0,112,111,108,101,97,110,103,108,101,0,111, -114,105,101,110,116,119,101,105,103,104,116,0,103,114,97,98,116,97,114,103,101,116,91,51,93,0,114,101,115,101,114,118, -101,100,50,0,109,105,110,109,97,120,102,108,97,103,0,115,116,117,99,107,0,99,97,99,104,101,91,51,93,0,108,111, -99,107,102,108,97,103,0,102,111,108,108,111,119,102,108,97,103,0,118,111,108,109,111,100,101,0,112,108,97,110,101,0, -111,114,103,108,101,110,103,116,104,0,98,117,108,103,101,0,112,105,118,88,0,112,105,118,89,0,112,105,118,90,0,97, -120,88,0,97,120,89,0,97,120,90,0,109,105,110,76,105,109,105,116,91,54,93,0,109,97,120,76,105,109,105,116,91, -54,93,0,101,120,116,114,97,70,122,0,105,110,118,109,97,116,91,52,93,91,52,93,0,102,114,111,109,0,116,111,0, -109,97,112,91,51,93,0,101,120,112,111,0,102,114,111,109,95,109,105,110,91,51,93,0,102,114,111,109,95,109,97,120, -91,51,93,0,116,111,95,109,105,110,91,51,93,0,116,111,95,109,97,120,91,51,93,0,122,109,105,110,0,122,109,97, -120,0,112,97,100,91,57,93,0,99,104,97,110,110,101,108,91,51,50,93,0,110,111,95,114,111,116,95,97,120,105,115, -0,115,116,114,105,100,101,95,97,120,105,115,0,99,117,114,109,111,100,0,97,99,116,115,116,97,114,116,0,97,99,116, -101,110,100,0,97,99,116,111,102,102,115,0,115,116,114,105,100,101,108,101,110,0,98,108,101,110,100,111,117,116,0,115, -116,114,105,100,101,99,104,97,110,110,101,108,91,51,50,93,0,111,102,102,115,95,98,111,110,101,91,51,50,93,0,104, -97,115,105,110,112,117,116,0,104,97,115,111,117,116,112,117,116,0,100,97,116,97,116,121,112,101,0,115,111,99,107,101, -116,116,121,112,101,0,42,110,101,119,95,115,111,99,107,0,110,115,0,108,105,109,105,116,0,115,116,97,99,107,95,105, -110,100,101,120,0,105,110,116,101,114,110,0,115,116,97,99,107,95,105,110,100,101,120,95,101,120,116,0,108,111,99,120, -0,108,111,99,121,0,111,119,110,95,105,110,100,101,120,0,116,111,95,105,110,100,101,120,0,42,116,111,115,111,99,107, -0,42,108,105,110,107,0,42,110,101,119,95,110,111,100,101,0,117,115,101,114,110,97,109,101,91,51,50,93,0,108,97, -115,116,121,0,111,117,116,112,117,116,115,0,42,115,116,111,114,97,103,101,0,109,105,110,105,119,105,100,116,104,0,99, -117,115,116,111,109,49,0,99,117,115,116,111,109,50,0,99,117,115,116,111,109,51,0,99,117,115,116,111,109,52,0,110, -101,101,100,95,101,120,101,99,0,101,120,101,99,0,116,111,116,114,0,98,117,116,114,0,112,114,118,114,0,42,116,121, -112,101,105,110,102,111,0,42,102,114,111,109,110,111,100,101,0,42,116,111,110,111,100,101,0,42,102,114,111,109,115,111, -99,107,0,110,111,100,101,115,0,108,105,110,107,115,0,42,115,116,97,99,107,0,42,116,104,114,101,97,100,115,116,97, -99,107,0,105,110,105,116,0,115,116,97,99,107,115,105,122,101,0,99,117,114,95,105,110,100,101,120,0,97,108,108,116, -121,112,101,115,0,42,111,119,110,116,121,112,101,0,42,115,101,108,105,110,0,42,115,101,108,111,117,116,0,40,42,116, -105,109,101,99,117,114,115,111,114,41,40,41,0,40,42,115,116,97,116,115,95,100,114,97,119,41,40,41,0,40,42,116, -101,115,116,95,98,114,101,97,107,41,40,41,0,99,121,99,108,105,99,0,109,111,118,105,101,0,115,97,109,112,108,101, -115,0,109,105,110,115,112,101,101,100,0,112,101,114,99,101,110,116,120,0,112,101,114,99,101,110,116,121,0,98,111,107, -101,104,0,99,117,114,118,101,100,0,105,109,97,103,101,95,105,110,95,119,105,100,116,104,0,105,109,97,103,101,95,105, -110,95,104,101,105,103,104,116,0,99,101,110,116,101,114,95,120,0,99,101,110,116,101,114,95,121,0,115,112,105,110,0, -105,116,101,114,0,119,114,97,112,0,115,105,103,109,97,95,99,111,108,111,114,0,115,105,103,109,97,95,115,112,97,99, -101,0,104,117,101,0,115,97,116,0,116,49,0,116,50,0,116,51,0,102,115,116,114,101,110,103,116,104,0,102,97,108, -112,104,97,0,107,101,121,91,52,93,0,120,49,0,120,50,0,121,49,0,121,50,0,99,111,108,110,97,109,101,91,51, -50,93,0,98,107,116,121,112,101,0,114,111,116,97,116,105,111,110,0,112,114,101,118,105,101,119,0,103,97,109,99,111, -0,110,111,95,122,98,117,102,0,102,115,116,111,112,0,109,97,120,98,108,117,114,0,98,116,104,114,101,115,104,0,42, -100,105,99,116,0,42,110,111,100,101,0,97,110,103,108,101,95,111,102,115,0,99,111,108,109,111,100,0,109,105,120,0, -116,104,114,101,115,104,111,108,100,0,102,97,100,101,0,109,0,99,0,106,105,116,0,112,114,111,106,0,102,105,116,0, -115,104,111,114,116,121,0,109,105,110,116,97,98,108,101,0,109,97,120,116,97,98,108,101,0,101,120,116,95,105,110,91, -50,93,0,101,120,116,95,111,117,116,91,50,93,0,42,99,117,114,118,101,0,42,116,97,98,108,101,0,42,112,114,101, -109,117,108,116,97,98,108,101,0,99,117,114,114,0,99,108,105,112,114,0,99,109,91,52,93,0,98,108,97,99,107,91, -51,93,0,119,104,105,116,101,91,51,93,0,98,119,109,117,108,91,51,93,0,115,97,109,112,108,101,91,51,93,0,111, -102,102,115,101,116,91,50,93,0,105,110,110,101,114,114,97,100,105,117,115,0,114,97,116,101,0,114,103,98,91,51,93, -0,99,108,111,110,101,0,97,99,116,105,118,101,95,114,110,100,0,97,99,116,105,118,101,95,99,108,111,110,101,0,97, -99,116,105,118,101,95,109,97,115,107,0,42,108,97,121,101,114,115,0,116,111,116,108,97,121,101,114,0,109,97,120,108, -97,121,101,114,0,116,111,116,115,105,122,101,0,42,112,111,111,108,0,101,100,105,116,102,108,97,103,0,118,101,108,91, -51,93,0,114,111,116,91,52,93,0,97,118,101,91,51,93,0,110,117,109,0,112,97,114,101,110,116,0,112,97,91,52, -93,0,119,91,52,93,0,102,117,118,91,52,93,0,102,111,102,102,115,101,116,0,114,97,110,100,91,51,93,0,42,115, -116,105,99,107,95,111,98,0,112,114,101,118,95,115,116,97,116,101,0,42,104,97,105,114,0,105,95,114,111,116,91,52, -93,0,114,95,114,111,116,91,52,93,0,114,95,97,118,101,91,51,93,0,114,95,118,101,91,51,93,0,100,105,101,116, -105,109,101,0,98,97,110,107,0,115,105,122,101,109,117,108,0,110,117,109,95,100,109,99,97,99,104,101,0,98,112,105, -0,97,108,105,118,101,0,108,111,111,112,0,100,105,115,116,114,0,112,104,121,115,116,121,112,101,0,114,111,116,109,111, -100,101,0,97,118,101,109,111,100,101,0,114,101,97,99,116,101,118,101,110,116,0,100,114,97,119,0,100,114,97,119,95, -97,115,0,100,114,97,119,95,115,105,122,101,0,99,104,105,108,100,116,121,112,101,0,100,114,97,119,95,115,116,101,112, -0,114,101,110,95,115,116,101,112,0,104,97,105,114,95,115,116,101,112,0,107,101,121,115,95,115,116,101,112,0,97,100, -97,112,116,95,97,110,103,108,101,0,97,100,97,112,116,95,112,105,120,0,114,111,116,102,114,111,109,0,105,110,116,101, -103,114,97,116,111,114,0,110,98,101,116,119,101,101,110,0,98,111,105,100,110,101,105,103,104,98,111,117,114,115,0,98, -98,95,97,108,105,103,110,0,98,98,95,117,118,95,115,112,108,105,116,0,98,98,95,97,110,105,109,0,98,98,95,115, -112,108,105,116,95,111,102,102,115,101,116,0,98,98,95,116,105,108,116,0,98,98,95,114,97,110,100,95,116,105,108,116, -0,98,98,95,111,102,102,115,101,116,91,50,93,0,115,105,109,112,108,105,102,121,95,102,108,97,103,0,115,105,109,112, -108,105,102,121,95,114,101,102,115,105,122,101,0,115,105,109,112,108,105,102,121,95,114,97,116,101,0,115,105,109,112,108, -105,102,121,95,116,114,97,110,115,105,116,105,111,110,0,115,105,109,112,108,105,102,121,95,118,105,101,119,112,111,114,116, -0,116,105,109,101,116,119,101,97,107,0,106,105,116,102,97,99,0,107,101,121,101,100,95,116,105,109,101,0,101,102,102, -95,104,97,105,114,0,103,114,105,100,95,114,101,115,0,112,97,114,116,102,97,99,0,116,97,110,102,97,99,0,116,97, -110,112,104,97,115,101,0,114,101,97,99,116,102,97,99,0,97,118,101,102,97,99,0,112,104,97,115,101,102,97,99,0, -114,97,110,100,114,111,116,102,97,99,0,114,97,110,100,112,104,97,115,101,102,97,99,0,114,97,110,100,115,105,122,101, -0,114,101,97,99,116,115,104,97,112,101,0,97,99,99,91,51,93,0,100,114,97,103,102,97,99,0,98,114,111,119,110, -102,97,99,0,100,97,109,112,102,97,99,0,97,98,115,108,101,110,103,116,104,0,114,97,110,100,108,101,110,103,116,104, -0,99,104,105,108,100,95,110,98,114,0,114,101,110,95,99,104,105,108,100,95,110,98,114,0,112,97,114,101,110,116,115, -0,99,104,105,108,100,115,105,122,101,0,99,104,105,108,100,114,97,110,100,115,105,122,101,0,99,104,105,108,100,114,97, -100,0,99,104,105,108,100,102,108,97,116,0,99,104,105,108,100,115,112,114,101,97,100,0,99,108,117,109,112,102,97,99, -0,99,108,117,109,112,112,111,119,0,114,111,117,103,104,49,0,114,111,117,103,104,49,95,115,105,122,101,0,114,111,117, -103,104,50,0,114,111,117,103,104,50,95,115,105,122,101,0,114,111,117,103,104,50,95,116,104,114,101,115,0,114,111,117, -103,104,95,101,110,100,0,114,111,117,103,104,95,101,110,100,95,115,104,97,112,101,0,98,114,97,110,99,104,95,116,104, -114,101,115,0,100,114,97,119,95,108,105,110,101,91,50,93,0,109,97,120,95,108,97,116,95,97,99,99,0,109,97,120, -95,116,97,110,95,97,99,99,0,97,118,101,114,97,103,101,95,118,101,108,0,98,97,110,107,105,110,103,0,109,97,120, -95,98,97,110,107,0,103,114,111,117,110,100,122,0,98,111,105,100,102,97,99,91,56,93,0,98,111,105,100,114,117,108, -101,91,56,93,0,42,101,102,102,95,103,114,111,117,112,0,42,100,117,112,95,111,98,0,42,98,98,95,111,98,0,42, -112,100,50,0,42,112,97,114,116,0,42,101,100,105,116,0,42,42,112,97,116,104,99,97,99,104,101,0,42,42,99,104, -105,108,100,99,97,99,104,101,0,112,97,116,104,99,97,99,104,101,98,117,102,115,0,99,104,105,108,100,99,97,99,104, -101,98,117,102,115,0,42,116,97,114,103,101,116,95,111,98,0,42,107,101,121,101,100,95,111,98,0,42,108,97,116,116, -105,99,101,0,101,102,102,101,99,116,111,114,115,0,114,101,97,99,116,101,118,101,110,116,115,0,116,111,116,99,104,105, -108,100,0,116,111,116,99,97,99,104,101,100,0,116,111,116,99,104,105,108,100,99,97,99,104,101,0,116,97,114,103,101, -116,95,112,115,121,115,0,107,101,121,101,100,95,112,115,121,115,0,116,111,116,107,101,121,101,100,0,98,97,107,101,115, -112,97,99,101,0,98,98,95,117,118,110,97,109,101,91,51,93,91,51,50,93,0,118,103,114,111,117,112,91,49,50,93, -0,118,103,95,110,101,103,0,114,116,51,0,42,114,101,110,100,101,114,100,97,116,97,0,42,99,97,99,104,101,0,67, -100,105,115,0,67,118,105,0,91,51,93,0,115,116,114,117,99,116,117,114,97,108,0,98,101,110,100,105,110,103,0,109, -97,120,95,98,101,110,100,0,109,97,120,95,115,116,114,117,99,116,0,109,97,120,95,115,104,101,97,114,0,97,118,103, -95,115,112,114,105,110,103,95,108,101,110,0,116,105,109,101,115,99,97,108,101,0,101,102,102,95,102,111,114,99,101,95, -115,99,97,108,101,0,101,102,102,95,119,105,110,100,95,115,99,97,108,101,0,115,105,109,95,116,105,109,101,95,111,108, -100,0,115,116,101,112,115,80,101,114,70,114,97,109,101,0,112,114,101,114,111,108,108,0,109,97,120,115,112,114,105,110, -103,108,101,110,0,115,111,108,118,101,114,95,116,121,112,101,0,118,103,114,111,117,112,95,98,101,110,100,0,118,103,114, -111,117,112,95,109,97,115,115,0,118,103,114,111,117,112,95,115,116,114,117,99,116,0,112,114,101,115,101,116,115,0,42, -99,111,108,108,105,115,105,111,110,95,108,105,115,116,0,101,112,115,105,108,111,110,0,115,101,108,102,95,102,114,105,99, -116,105,111,110,0,115,101,108,102,101,112,115,105,108,111,110,0,115,101,108,102,95,108,111,111,112,95,99,111,117,110,116, -0,108,111,111,112,95,99,111,117,110,116,0,112,114,101,115,115,117,114,101,0,42,112,111,105,110,116,115,0,116,111,116, -112,111,105,110,116,115,0,116,104,105,99,107,110,101,115,115,0,115,116,114,111,107,101,115,0,102,114,97,109,101,110,117, -109,0,42,97,99,116,102,114,97,109,101,0,103,115,116,101,112,0,105,110,102,111,91,49,50,56,93,0,115,98,117,102, -102,101,114,95,115,105,122,101,0,115,98,117,102,102,101,114,95,115,102,108,97,103,0,42,115,98,117,102,102,101,114,0, -0,0,0,84,89,80,69,100,1,0,0,99,104,97,114,0,117,99,104,97,114,0,115,104,111,114,116,0,117,115,104,111, -114,116,0,105,110,116,0,108,111,110,103,0,117,108,111,110,103,0,102,108,111,97,116,0,100,111,117,98,108,101,0,118, -111,105,100,0,76,105,110,107,0,76,105,110,107,68,97,116,97,0,76,105,115,116,66,97,115,101,0,118,101,99,50,115, -0,118,101,99,50,105,0,118,101,99,50,102,0,118,101,99,50,100,0,118,101,99,51,105,0,118,101,99,51,102,0,118, -101,99,51,100,0,118,101,99,52,105,0,118,101,99,52,102,0,118,101,99,52,100,0,114,99,116,105,0,114,99,116,102, -0,73,68,80,114,111,112,101,114,116,121,68,97,116,97,0,73,68,80,114,111,112,101,114,116,121,0,73,68,0,76,105, -98,114,97,114,121,0,70,105,108,101,68,97,116,97,0,80,114,101,118,105,101,119,73,109,97,103,101,0,73,112,111,68, -114,105,118,101,114,0,79,98,106,101,99,116,0,73,112,111,67,117,114,118,101,0,66,80,111,105,110,116,0,66,101,122, -84,114,105,112,108,101,0,73,112,111,0,75,101,121,66,108,111,99,107,0,75,101,121,0,83,99,114,105,112,116,76,105, -110,107,0,84,101,120,116,76,105,110,101,0,84,101,120,116,77,97,114,107,101,114,0,84,101,120,116,0,80,97,99,107, -101,100,70,105,108,101,0,67,97,109,101,114,97,0,73,109,97,103,101,85,115,101,114,0,73,109,97,103,101,0,71,80, -85,84,101,120,116,117,114,101,0,97,110,105,109,0,82,101,110,100,101,114,82,101,115,117,108,116,0,77,84,101,120,0, -84,101,120,0,80,108,117,103,105,110,84,101,120,0,67,66,68,97,116,97,0,67,111,108,111,114,66,97,110,100,0,69, -110,118,77,97,112,0,73,109,66,117,102,0,98,78,111,100,101,84,114,101,101,0,84,101,120,77,97,112,112,105,110,103, -0,76,97,109,112,0,67,117,114,118,101,77,97,112,112,105,110,103,0,87,97,118,101,0,77,97,116,101,114,105,97,108, -0,71,114,111,117,112,0,86,70,111,110,116,0,86,70,111,110,116,68,97,116,97,0,77,101,116,97,69,108,101,109,0, -66,111,117,110,100,66,111,120,0,77,101,116,97,66,97,108,108,0,78,117,114,98,0,67,104,97,114,73,110,102,111,0, -84,101,120,116,66,111,120,0,67,117,114,118,101,0,80,97,116,104,0,77,101,115,104,0,77,70,97,99,101,0,77,84, -70,97,99,101,0,84,70,97,99,101,0,77,86,101,114,116,0,77,69,100,103,101,0,77,68,101,102,111,114,109,86,101, -114,116,0,77,67,111,108,0,77,83,116,105,99,107,121,0,77,83,101,108,101,99,116,0,67,117,115,116,111,109,68,97, -116,97,0,77,117,108,116,105,114,101,115,0,80,97,114,116,105,97,108,86,105,115,105,98,105,108,105,116,121,0,77,68, -101,102,111,114,109,87,101,105,103,104,116,0,77,84,101,120,80,111,108,121,0,77,76,111,111,112,85,86,0,77,76,111, -111,112,67,111,108,0,77,70,108,111,97,116,80,114,111,112,101,114,116,121,0,77,73,110,116,80,114,111,112,101,114,116, -121,0,77,83,116,114,105,110,103,80,114,111,112,101,114,116,121,0,79,114,105,103,83,112,97,99,101,70,97,99,101,0, -77,117,108,116,105,114,101,115,67,111,108,0,77,117,108,116,105,114,101,115,67,111,108,70,97,99,101,0,77,117,108,116, -105,114,101,115,70,97,99,101,0,77,117,108,116,105,114,101,115,69,100,103,101,0,77,117,108,116,105,114,101,115,76,101, -118,101,108,0,77,117,108,116,105,114,101,115,77,97,112,78,111,100,101,0,77,111,100,105,102,105,101,114,68,97,116,97, -0,83,117,98,115,117,114,102,77,111,100,105,102,105,101,114,68,97,116,97,0,76,97,116,116,105,99,101,77,111,100,105, -102,105,101,114,68,97,116,97,0,67,117,114,118,101,77,111,100,105,102,105,101,114,68,97,116,97,0,66,117,105,108,100, -77,111,100,105,102,105,101,114,68,97,116,97,0,77,97,115,107,77,111,100,105,102,105,101,114,68,97,116,97,0,65,114, -114,97,121,77,111,100,105,102,105,101,114,68,97,116,97,0,77,105,114,114,111,114,77,111,100,105,102,105,101,114,68,97, -116,97,0,69,100,103,101,83,112,108,105,116,77,111,100,105,102,105,101,114,68,97,116,97,0,66,101,118,101,108,77,111, -100,105,102,105,101,114,68,97,116,97,0,66,77,101,115,104,77,111,100,105,102,105,101,114,68,97,116,97,0,68,105,115, -112,108,97,99,101,77,111,100,105,102,105,101,114,68,97,116,97,0,85,86,80,114,111,106,101,99,116,77,111,100,105,102, -105,101,114,68,97,116,97,0,68,101,99,105,109,97,116,101,77,111,100,105,102,105,101,114,68,97,116,97,0,83,109,111, -111,116,104,77,111,100,105,102,105,101,114,68,97,116,97,0,67,97,115,116,77,111,100,105,102,105,101,114,68,97,116,97, -0,87,97,118,101,77,111,100,105,102,105,101,114,68,97,116,97,0,65,114,109,97,116,117,114,101,77,111,100,105,102,105, -101,114,68,97,116,97,0,72,111,111,107,77,111,100,105,102,105,101,114,68,97,116,97,0,83,111,102,116,98,111,100,121, -77,111,100,105,102,105,101,114,68,97,116,97,0,67,108,111,116,104,77,111,100,105,102,105,101,114,68,97,116,97,0,67, -108,111,116,104,0,67,108,111,116,104,83,105,109,83,101,116,116,105,110,103,115,0,67,108,111,116,104,67,111,108,108,83, -101,116,116,105,110,103,115,0,80,111,105,110,116,67,97,99,104,101,0,67,111,108,108,105,115,105,111,110,77,111,100,105, -102,105,101,114,68,97,116,97,0,66,86,72,84,114,101,101,0,83,117,114,102,97,99,101,77,111,100,105,102,105,101,114, -68,97,116,97,0,68,101,114,105,118,101,100,77,101,115,104,0,66,86,72,84,114,101,101,70,114,111,109,77,101,115,104, -0,66,111,111,108,101,97,110,77,111,100,105,102,105,101,114,68,97,116,97,0,77,68,101,102,73,110,102,108,117,101,110, -99,101,0,77,68,101,102,67,101,108,108,0,77,101,115,104,68,101,102,111,114,109,77,111,100,105,102,105,101,114,68,97, -116,97,0,80,97,114,116,105,99,108,101,83,121,115,116,101,109,77,111,100,105,102,105,101,114,68,97,116,97,0,80,97, -114,116,105,99,108,101,83,121,115,116,101,109,0,80,97,114,116,105,99,108,101,73,110,115,116,97,110,99,101,77,111,100, -105,102,105,101,114,68,97,116,97,0,69,120,112,108,111,100,101,77,111,100,105,102,105,101,114,68,97,116,97,0,70,108, -117,105,100,115,105,109,77,111,100,105,102,105,101,114,68,97,116,97,0,70,108,117,105,100,115,105,109,83,101,116,116,105, -110,103,115,0,83,104,114,105,110,107,119,114,97,112,77,111,100,105,102,105,101,114,68,97,116,97,0,83,105,109,112,108, -101,68,101,102,111,114,109,77,111,100,105,102,105,101,114,68,97,116,97,0,76,97,116,116,105,99,101,0,98,68,101,102, -111,114,109,71,114,111,117,112,0,98,65,99,116,105,111,110,0,98,80,111,115,101,0,66,117,108,108,101,116,83,111,102, -116,66,111,100,121,0,80,97,114,116,68,101,102,108,101,99,116,0,83,111,102,116,66,111,100,121,0,79,98,72,111,111, -107,0,82,78,71,0,83,66,86,101,114,116,101,120,0,66,111,100,121,80,111,105,110,116,0,66,111,100,121,83,112,114, -105,110,103,0,83,66,83,99,114,97,116,99,104,0,87,111,114,108,100,0,82,97,100,105,111,0,66,97,115,101,0,65, -118,105,67,111,100,101,99,68,97,116,97,0,81,117,105,99,107,116,105,109,101,67,111,100,101,99,68,97,116,97,0,70, -70,77,112,101,103,67,111,100,101,99,68,97,116,97,0,65,117,100,105,111,68,97,116,97,0,83,99,101,110,101,82,101, -110,100,101,114,76,97,121,101,114,0,82,101,110,100,101,114,68,97,116,97,0,82,101,110,100,101,114,80,114,111,102,105, -108,101,0,71,97,109,101,70,114,97,109,105,110,103,0,84,105,109,101,77,97,114,107,101,114,0,73,109,97,103,101,80, -97,105,110,116,83,101,116,116,105,110,103,115,0,66,114,117,115,104,0,80,97,114,116,105,99,108,101,66,114,117,115,104, -68,97,116,97,0,80,97,114,116,105,99,108,101,69,100,105,116,83,101,116,116,105,110,103,115,0,84,114,97,110,115,102, -111,114,109,79,114,105,101,110,116,97,116,105,111,110,0,84,111,111,108,83,101,116,116,105,110,103,115,0,66,114,117,115, -104,68,97,116,97,0,83,99,117,108,112,116,68,97,116,97,0,83,99,117,108,112,116,83,101,115,115,105,111,110,0,83, -99,101,110,101,0,68,97,103,70,111,114,101,115,116,0,66,71,112,105,99,0,86,105,101,119,51,68,0,83,112,97,99, -101,76,105,110,107,0,83,99,114,65,114,101,97,0,82,101,110,100,101,114,73,110,102,111,0,82,101,116,111,112,111,86, -105,101,119,68,97,116,97,0,86,105,101,119,68,101,112,116,104,115,0,98,71,80,100,97,116,97,0,86,105,101,119,50, -68,0,83,112,97,99,101,73,110,102,111,0,83,112,97,99,101,73,112,111,0,83,112,97,99,101,66,117,116,115,0,83, -112,97,99,101,83,101,113,0,83,112,97,99,101,70,105,108,101,0,100,105,114,101,110,116,114,121,0,66,108,101,110,100, -72,97,110,100,108,101,0,83,112,97,99,101,79,111,112,115,0,84,114,101,101,83,116,111,114,101,0,84,114,101,101,83, -116,111,114,101,69,108,101,109,0,83,112,97,99,101,73,109,97,103,101,0,83,112,97,99,101,78,108,97,0,83,112,97, -99,101,84,101,120,116,0,83,99,114,105,112,116,0,83,112,97,99,101,83,99,114,105,112,116,0,83,112,97,99,101,84, -105,109,101,0,83,112,97,99,101,78,111,100,101,0,83,112,97,99,101,73,109,97,83,101,108,0,70,105,108,101,76,105, -115,116,0,84,104,101,109,101,85,73,0,84,104,101,109,101,83,112,97,99,101,0,84,104,101,109,101,87,105,114,101,67, -111,108,111,114,0,98,84,104,101,109,101,0,83,111,108,105,100,76,105,103,104,116,0,85,115,101,114,68,101,102,0,98, -83,99,114,101,101,110,0,83,99,114,86,101,114,116,0,83,99,114,69,100,103,101,0,80,97,110,101,108,0,70,105,108, -101,71,108,111,98,97,108,0,83,116,114,105,112,69,108,101,109,0,84,83,116,114,105,112,69,108,101,109,0,83,116,114, -105,112,67,114,111,112,0,83,116,114,105,112,84,114,97,110,115,102,111,114,109,0,83,116,114,105,112,67,111,108,111,114, -66,97,108,97,110,99,101,0,83,116,114,105,112,67,111,108,111,114,66,97,108,97,110,99,101,71,85,73,72,101,108,112, -101,114,0,83,116,114,105,112,80,114,111,120,121,0,83,116,114,105,112,0,80,108,117,103,105,110,83,101,113,0,83,101, -113,117,101,110,99,101,0,98,83,111,117,110,100,0,104,100,97,117,100,105,111,0,77,101,116,97,83,116,97,99,107,0, -69,100,105,116,105,110,103,0,87,105,112,101,86,97,114,115,0,71,108,111,119,86,97,114,115,0,84,114,97,110,115,102, -111,114,109,86,97,114,115,0,83,111,108,105,100,67,111,108,111,114,86,97,114,115,0,83,112,101,101,100,67,111,110,116, -114,111,108,86,97,114,115,0,69,102,102,101,99,116,0,66,117,105,108,100,69,102,102,0,80,97,114,116,69,102,102,0, -80,97,114,116,105,99,108,101,0,87,97,118,101,69,102,102,0,79,111,112,115,0,98,80,114,111,112,101,114,116,121,0, -98,78,101,97,114,83,101,110,115,111,114,0,98,77,111,117,115,101,83,101,110,115,111,114,0,98,84,111,117,99,104,83, -101,110,115,111,114,0,98,75,101,121,98,111,97,114,100,83,101,110,115,111,114,0,98,80,114,111,112,101,114,116,121,83, -101,110,115,111,114,0,98,65,99,116,117,97,116,111,114,83,101,110,115,111,114,0,98,68,101,108,97,121,83,101,110,115, -111,114,0,98,67,111,108,108,105,115,105,111,110,83,101,110,115,111,114,0,98,82,97,100,97,114,83,101,110,115,111,114, -0,98,82,97,110,100,111,109,83,101,110,115,111,114,0,98,82,97,121,83,101,110,115,111,114,0,98,77,101,115,115,97, -103,101,83,101,110,115,111,114,0,98,83,101,110,115,111,114,0,98,67,111,110,116,114,111,108,108,101,114,0,98,74,111, -121,115,116,105,99,107,83,101,110,115,111,114,0,98,69,120,112,114,101,115,115,105,111,110,67,111,110,116,0,98,80,121, -116,104,111,110,67,111,110,116,0,98,65,99,116,117,97,116,111,114,0,98,65,100,100,79,98,106,101,99,116,65,99,116, -117,97,116,111,114,0,98,65,99,116,105,111,110,65,99,116,117,97,116,111,114,0,98,83,111,117,110,100,65,99,116,117, -97,116,111,114,0,98,67,68,65,99,116,117,97,116,111,114,0,98,69,100,105,116,79,98,106,101,99,116,65,99,116,117, -97,116,111,114,0,98,83,99,101,110,101,65,99,116,117,97,116,111,114,0,98,80,114,111,112,101,114,116,121,65,99,116, -117,97,116,111,114,0,98,79,98,106,101,99,116,65,99,116,117,97,116,111,114,0,98,73,112,111,65,99,116,117,97,116, -111,114,0,98,67,97,109,101,114,97,65,99,116,117,97,116,111,114,0,98,67,111,110,115,116,114,97,105,110,116,65,99, -116,117,97,116,111,114,0,98,71,114,111,117,112,65,99,116,117,97,116,111,114,0,98,82,97,110,100,111,109,65,99,116, -117,97,116,111,114,0,98,77,101,115,115,97,103,101,65,99,116,117,97,116,111,114,0,98,71,97,109,101,65,99,116,117, -97,116,111,114,0,98,86,105,115,105,98,105,108,105,116,121,65,99,116,117,97,116,111,114,0,98,84,119,111,68,70,105, -108,116,101,114,65,99,116,117,97,116,111,114,0,98,80,97,114,101,110,116,65,99,116,117,97,116,111,114,0,98,83,116, -97,116,101,65,99,116,117,97,116,111,114,0,70,114,101,101,67,97,109,101,114,97,0,98,83,97,109,112,108,101,0,98, -83,111,117,110,100,76,105,115,116,101,110,101,114,0,83,112,97,99,101,83,111,117,110,100,0,71,114,111,117,112,79,98, -106,101,99,116,0,66,111,110,101,0,98,65,114,109,97,116,117,114,101,0,98,80,111,115,101,67,104,97,110,110,101,108, -0,98,65,99,116,105,111,110,71,114,111,117,112,0,98,65,99,116,105,111,110,67,104,97,110,110,101,108,0,83,112,97, -99,101,65,99,116,105,111,110,0,98,67,111,110,115,116,114,97,105,110,116,67,104,97,110,110,101,108,0,98,67,111,110, -115,116,114,97,105,110,116,0,98,67,111,110,115,116,114,97,105,110,116,84,97,114,103,101,116,0,98,80,121,116,104,111, -110,67,111,110,115,116,114,97,105,110,116,0,98,75,105,110,101,109,97,116,105,99,67,111,110,115,116,114,97,105,110,116, -0,98,84,114,97,99,107,84,111,67,111,110,115,116,114,97,105,110,116,0,98,82,111,116,97,116,101,76,105,107,101,67, -111,110,115,116,114,97,105,110,116,0,98,76,111,99,97,116,101,76,105,107,101,67,111,110,115,116,114,97,105,110,116,0, -98,77,105,110,77,97,120,67,111,110,115,116,114,97,105,110,116,0,98,83,105,122,101,76,105,107,101,67,111,110,115,116, -114,97,105,110,116,0,98,65,99,116,105,111,110,67,111,110,115,116,114,97,105,110,116,0,98,76,111,99,107,84,114,97, -99,107,67,111,110,115,116,114,97,105,110,116,0,98,70,111,108,108,111,119,80,97,116,104,67,111,110,115,116,114,97,105, -110,116,0,98,83,116,114,101,116,99,104,84,111,67,111,110,115,116,114,97,105,110,116,0,98,82,105,103,105,100,66,111, -100,121,74,111,105,110,116,67,111,110,115,116,114,97,105,110,116,0,98,67,108,97,109,112,84,111,67,111,110,115,116,114, -97,105,110,116,0,98,67,104,105,108,100,79,102,67,111,110,115,116,114,97,105,110,116,0,98,84,114,97,110,115,102,111, -114,109,67,111,110,115,116,114,97,105,110,116,0,98,76,111,99,76,105,109,105,116,67,111,110,115,116,114,97,105,110,116, -0,98,82,111,116,76,105,109,105,116,67,111,110,115,116,114,97,105,110,116,0,98,83,105,122,101,76,105,109,105,116,67, -111,110,115,116,114,97,105,110,116,0,98,68,105,115,116,76,105,109,105,116,67,111,110,115,116,114,97,105,110,116,0,98, -83,104,114,105,110,107,119,114,97,112,67,111,110,115,116,114,97,105,110,116,0,98,65,99,116,105,111,110,77,111,100,105, -102,105,101,114,0,98,65,99,116,105,111,110,83,116,114,105,112,0,98,78,111,100,101,83,116,97,99,107,0,98,78,111, -100,101,83,111,99,107,101,116,0,98,78,111,100,101,76,105,110,107,0,98,78,111,100,101,0,98,78,111,100,101,80,114, -101,118,105,101,119,0,98,78,111,100,101,84,121,112,101,0,78,111,100,101,73,109,97,103,101,65,110,105,109,0,78,111, -100,101,66,108,117,114,68,97,116,97,0,78,111,100,101,68,66,108,117,114,68,97,116,97,0,78,111,100,101,66,105,108, -97,116,101,114,97,108,66,108,117,114,68,97,116,97,0,78,111,100,101,72,117,101,83,97,116,0,78,111,100,101,73,109, -97,103,101,70,105,108,101,0,78,111,100,101,67,104,114,111,109,97,0,78,111,100,101,84,119,111,88,89,115,0,78,111, -100,101,84,119,111,70,108,111,97,116,115,0,78,111,100,101,71,101,111,109,101,116,114,121,0,78,111,100,101,86,101,114, -116,101,120,67,111,108,0,78,111,100,101,68,101,102,111,99,117,115,0,78,111,100,101,83,99,114,105,112,116,68,105,99, -116,0,78,111,100,101,71,108,97,114,101,0,78,111,100,101,84,111,110,101,109,97,112,0,78,111,100,101,76,101,110,115, -68,105,115,116,0,84,101,120,78,111,100,101,79,117,116,112,117,116,0,67,117,114,118,101,77,97,112,80,111,105,110,116, -0,67,117,114,118,101,77,97,112,0,66,114,117,115,104,67,108,111,110,101,0,67,117,115,116,111,109,68,97,116,97,76, -97,121,101,114,0,72,97,105,114,75,101,121,0,80,97,114,116,105,99,108,101,75,101,121,0,67,104,105,108,100,80,97, -114,116,105,99,108,101,0,80,97,114,116,105,99,108,101,68,97,116,97,0,80,97,114,116,105,99,108,101,83,101,116,116, -105,110,103,115,0,80,97,114,116,105,99,108,101,69,100,105,116,0,80,97,114,116,105,99,108,101,67,97,99,104,101,75, -101,121,0,76,105,110,107,78,111,100,101,0,98,71,80,68,115,112,111,105,110,116,0,98,71,80,68,115,116,114,111,107, -101,0,98,71,80,68,102,114,97,109,101,0,98,71,80,68,108,97,121,101,114,0,0,84,76,69,78,1,0,1,0,2, -0,2,0,4,0,4,0,4,0,4,0,8,0,0,0,16,0,24,0,16,0,4,0,8,0,8,0,16,0,12,0,12, -0,24,0,16,0,16,0,32,0,16,0,16,0,32,0,96,0,72,0,72,2,0,0,40,0,-112,0,48,4,112,0,36, -0,56,0,112,0,-128,0,-96,0,24,0,40,0,48,0,-80,0,24,0,-88,0,32,0,-72,1,0,0,0,0,0,0,-112, -0,64,1,120,1,24,0,8,3,-56,0,0,0,-56,0,-120,0,-16,1,56,1,80,0,-16,2,104,0,96,1,0,0,-128, -0,104,0,-72,0,80,0,8,0,16,0,-96,1,0,0,-112,1,20,0,48,0,64,0,24,0,12,0,16,0,4,0,8, -0,8,0,32,0,112,0,48,0,8,0,16,0,8,0,8,0,4,0,4,0,0,1,32,0,16,0,64,0,24,0,12, -0,96,0,0,0,64,0,88,0,104,0,112,0,80,0,112,0,-112,0,80,0,72,0,120,0,72,0,-88,0,-48,0,72, -0,104,0,120,0,-48,0,120,0,-56,0,64,0,96,0,0,0,-120,0,32,0,20,0,-112,0,0,0,80,0,0,0,0, -0,80,0,8,0,8,0,0,1,96,0,-104,1,80,0,80,0,80,0,-72,1,-128,0,120,0,-104,0,48,0,-128,0,72, -0,120,0,-120,0,16,1,-32,0,0,0,16,0,0,0,0,0,0,0,-32,1,40,0,40,0,-72,0,-104,0,56,0,16, -0,88,0,-24,3,64,0,16,0,88,0,16,0,24,1,8,0,72,0,88,0,-16,0,8,0,-8,0,0,0,64,6,0, -0,64,0,88,3,48,0,8,1,0,0,0,0,0,0,32,0,-120,0,48,0,120,1,-16,0,-40,0,-8,1,0,0,0, -0,48,1,16,0,16,0,32,1,-64,0,-112,0,120,2,56,0,-80,0,0,1,-72,2,0,0,-104,0,-48,0,16,0,64, -14,56,0,40,12,-88,0,32,0,40,0,-16,0,40,0,80,0,48,0,16,0,8,0,64,0,0,0,0,1,32,1,-56, -1,8,1,72,1,0,0,32,0,48,0,12,0,24,0,48,0,16,0,32,0,24,0,32,0,72,1,0,0,64,0,64, -0,80,0,48,0,8,0,48,0,72,0,104,0,40,0,8,0,72,0,44,0,40,0,108,0,72,0,96,0,104,0,60, -0,-128,0,80,0,80,0,16,0,96,0,32,0,20,0,88,0,24,0,80,0,112,0,84,0,32,0,96,0,64,0,56, -0,112,0,-116,0,4,0,24,0,16,0,8,0,40,0,0,0,88,0,-64,0,40,0,24,1,-104,0,-48,1,88,0,88, -0,-48,0,56,0,80,0,-128,0,80,0,112,0,56,0,48,0,48,0,72,0,48,0,72,0,48,0,24,0,56,0,104, -0,16,0,112,0,96,0,28,0,28,0,28,0,56,0,24,0,72,0,-88,0,40,0,-112,0,48,0,-8,0,0,0,0, -0,16,0,40,0,28,0,12,0,12,0,16,1,40,0,8,0,8,0,64,0,32,0,24,0,16,0,24,0,32,0,8, -0,32,0,12,0,56,0,24,0,72,0,24,0,56,0,72,0,8,1,16,2,0,0,0,0,0,0,16,0,32,0,40, -0,-64,0,83,84,82,67,57,1,0,0,10,0,2,0,10,0,0,0,10,0,1,0,11,0,3,0,11,0,0,0,11, -0,1,0,9,0,2,0,12,0,2,0,9,0,3,0,9,0,4,0,13,0,2,0,2,0,5,0,2,0,6,0,14, -0,2,0,4,0,5,0,4,0,6,0,15,0,2,0,7,0,5,0,7,0,6,0,16,0,2,0,8,0,5,0,8, -0,6,0,17,0,3,0,4,0,5,0,4,0,6,0,4,0,7,0,18,0,3,0,7,0,5,0,7,0,6,0,7, -0,7,0,19,0,3,0,8,0,5,0,8,0,6,0,8,0,7,0,20,0,4,0,4,0,5,0,4,0,6,0,4, -0,7,0,4,0,8,0,21,0,4,0,7,0,5,0,7,0,6,0,7,0,7,0,7,0,8,0,22,0,4,0,8, -0,5,0,8,0,6,0,8,0,7,0,8,0,8,0,23,0,4,0,4,0,9,0,4,0,10,0,4,0,11,0,4, -0,12,0,24,0,4,0,7,0,9,0,7,0,10,0,7,0,11,0,7,0,12,0,25,0,4,0,9,0,13,0,12, -0,14,0,4,0,15,0,4,0,16,0,26,0,10,0,26,0,0,0,26,0,1,0,0,0,17,0,0,0,18,0,0, -0,19,0,2,0,20,0,4,0,21,0,25,0,22,0,4,0,23,0,4,0,24,0,27,0,9,0,9,0,0,0,9, -0,1,0,27,0,25,0,28,0,26,0,0,0,27,0,2,0,28,0,2,0,20,0,4,0,29,0,26,0,30,0,28, -0,8,0,27,0,31,0,27,0,32,0,29,0,33,0,0,0,34,0,0,0,35,0,4,0,36,0,4,0,37,0,28, -0,38,0,30,0,6,0,4,0,39,0,4,0,40,0,2,0,41,0,2,0,42,0,2,0,43,0,4,0,44,0,31, -0,6,0,32,0,45,0,2,0,46,0,2,0,47,0,2,0,18,0,2,0,20,0,0,0,48,0,33,0,21,0,33, -0,0,0,33,0,1,0,34,0,49,0,35,0,50,0,24,0,51,0,24,0,52,0,2,0,46,0,2,0,47,0,2, -0,53,0,2,0,54,0,2,0,55,0,2,0,56,0,2,0,20,0,2,0,57,0,7,0,11,0,7,0,12,0,4, -0,58,0,7,0,59,0,7,0,60,0,7,0,61,0,31,0,62,0,36,0,7,0,27,0,31,0,12,0,63,0,24, -0,64,0,2,0,46,0,2,0,65,0,2,0,66,0,2,0,37,0,37,0,16,0,37,0,0,0,37,0,1,0,7, -0,67,0,7,0,61,0,2,0,18,0,2,0,47,0,2,0,68,0,2,0,20,0,4,0,69,0,4,0,70,0,9, -0,2,0,7,0,71,0,0,0,17,0,0,0,72,0,7,0,73,0,7,0,74,0,38,0,12,0,27,0,31,0,37, -0,75,0,0,0,76,0,4,0,77,0,7,0,61,0,12,0,78,0,36,0,79,0,27,0,80,0,2,0,18,0,2, -0,81,0,2,0,82,0,2,0,20,0,39,0,5,0,27,0,83,0,2,0,84,0,2,0,85,0,2,0,86,0,4, -0,37,0,40,0,6,0,40,0,0,0,40,0,1,0,0,0,87,0,0,0,88,0,4,0,23,0,4,0,89,0,41, -0,10,0,41,0,0,0,41,0,1,0,4,0,90,0,4,0,91,0,4,0,92,0,4,0,43,0,4,0,14,0,4, -0,93,0,0,0,94,0,0,0,95,0,42,0,15,0,27,0,31,0,0,0,96,0,4,0,93,0,4,0,97,0,12, -0,98,0,40,0,99,0,40,0,100,0,4,0,101,0,4,0,102,0,12,0,103,0,0,0,104,0,4,0,105,0,4, -0,106,0,9,0,107,0,8,0,108,0,43,0,5,0,4,0,109,0,4,0,110,0,4,0,93,0,4,0,37,0,9, -0,2,0,44,0,20,0,27,0,31,0,2,0,18,0,2,0,20,0,7,0,111,0,7,0,112,0,7,0,113,0,7, -0,114,0,7,0,115,0,7,0,116,0,7,0,117,0,7,0,118,0,7,0,119,0,7,0,120,0,7,0,121,0,2, -0,122,0,2,0,123,0,7,0,124,0,36,0,79,0,39,0,125,0,32,0,126,0,45,0,12,0,4,0,127,0,4, -0,-128,0,4,0,-127,0,4,0,-126,0,2,0,-125,0,2,0,-124,0,2,0,20,0,2,0,-123,0,2,0,-122,0,2, -0,-121,0,2,0,-120,0,2,0,-119,0,46,0,32,0,27,0,31,0,0,0,34,0,12,0,-118,0,47,0,-117,0,48, -0,-116,0,49,0,-115,0,2,0,-123,0,2,0,20,0,2,0,-114,0,2,0,18,0,2,0,37,0,2,0,43,0,4, -0,-113,0,2,0,-112,0,2,0,-111,0,2,0,-110,0,2,0,-109,0,2,0,-108,0,2,0,-107,0,4,0,-106,0,4, -0,-105,0,43,0,-104,0,30,0,-103,0,7,0,-102,0,4,0,-101,0,2,0,-100,0,2,0,-99,0,2,0,-98,0,2, -0,-97,0,7,0,-96,0,7,0,-95,0,9,0,-94,0,50,0,31,0,2,0,-93,0,2,0,-92,0,2,0,-91,0,2, -0,-90,0,32,0,-89,0,51,0,-88,0,0,0,-87,0,0,0,-86,0,0,0,-85,0,0,0,-84,0,0,0,-83,0,7, -0,-82,0,7,0,-81,0,2,0,-80,0,2,0,-79,0,2,0,-78,0,2,0,-77,0,2,0,-76,0,2,0,-75,0,2, -0,-74,0,7,0,-73,0,7,0,-72,0,7,0,-71,0,7,0,-70,0,7,0,-69,0,7,0,57,0,7,0,-68,0,7, -0,-67,0,7,0,-66,0,7,0,-65,0,7,0,-64,0,52,0,15,0,0,0,-63,0,9,0,-62,0,0,0,-61,0,0, -0,-60,0,4,0,-59,0,4,0,-58,0,9,0,-57,0,7,0,-56,0,7,0,-55,0,7,0,-54,0,4,0,-53,0,9, -0,-52,0,9,0,-51,0,4,0,-50,0,4,0,37,0,53,0,6,0,7,0,-73,0,7,0,-72,0,7,0,-71,0,7, -0,-49,0,7,0,67,0,4,0,64,0,54,0,5,0,2,0,20,0,2,0,36,0,2,0,64,0,2,0,-48,0,53, -0,-54,0,55,0,17,0,32,0,-89,0,46,0,-47,0,56,0,-46,0,7,0,-45,0,7,0,-44,0,2,0,18,0,2, -0,-43,0,7,0,113,0,7,0,114,0,7,0,-42,0,4,0,-41,0,2,0,-40,0,2,0,-39,0,4,0,-123,0,4, -0,-113,0,2,0,-38,0,2,0,-37,0,51,0,56,0,27,0,31,0,7,0,-36,0,7,0,-35,0,7,0,-34,0,7, -0,-33,0,7,0,-32,0,7,0,-31,0,7,0,-30,0,7,0,-29,0,7,0,-28,0,7,0,-27,0,7,0,-26,0,7, -0,-25,0,7,0,-24,0,7,0,-23,0,7,0,-22,0,7,0,-21,0,7,0,-20,0,7,0,-19,0,7,0,-18,0,7, -0,-17,0,2,0,-16,0,2,0,-15,0,2,0,-14,0,2,0,-13,0,2,0,-12,0,2,0,-11,0,2,0,-10,0,2, -0,20,0,2,0,18,0,2,0,-43,0,7,0,-9,0,7,0,-8,0,7,0,-7,0,7,0,-6,0,2,0,-5,0,2, -0,-4,0,2,0,-3,0,2,0,-125,0,4,0,23,0,4,0,-128,0,4,0,-127,0,4,0,-126,0,7,0,-2,0,7, -0,-1,0,7,0,-67,0,45,0,0,1,57,0,1,1,36,0,79,0,46,0,-47,0,52,0,2,1,54,0,3,1,55, -0,4,1,30,0,-103,0,0,0,5,1,0,0,6,1,58,0,8,0,7,0,7,1,7,0,8,1,7,0,-81,0,4, -0,20,0,7,0,9,1,7,0,10,1,7,0,11,1,32,0,45,0,59,0,80,0,27,0,31,0,2,0,18,0,2, -0,12,1,4,0,13,1,2,0,-79,0,2,0,14,1,7,0,-73,0,7,0,-72,0,7,0,-71,0,7,0,-70,0,7, -0,15,1,7,0,16,1,7,0,17,1,7,0,18,1,7,0,19,1,7,0,20,1,7,0,21,1,7,0,22,1,7, -0,23,1,7,0,24,1,7,0,25,1,60,0,26,1,2,0,27,1,2,0,70,0,7,0,113,0,7,0,114,0,7, -0,28,1,7,0,29,1,7,0,30,1,2,0,31,1,2,0,32,1,2,0,33,1,2,0,34,1,0,0,35,1,0, -0,36,1,2,0,37,1,2,0,38,1,2,0,39,1,2,0,40,1,2,0,41,1,7,0,42,1,7,0,43,1,7, -0,44,1,7,0,45,1,2,0,46,1,2,0,43,0,2,0,47,1,2,0,48,1,2,0,49,1,2,0,50,1,7, -0,51,1,7,0,52,1,7,0,53,1,7,0,54,1,7,0,55,1,7,0,56,1,7,0,57,1,7,0,58,1,7, -0,59,1,7,0,60,1,7,0,61,1,7,0,62,1,2,0,63,1,2,0,64,1,4,0,65,1,4,0,66,1,2, -0,67,1,2,0,68,1,2,0,69,1,2,0,70,1,7,0,71,1,7,0,72,1,7,0,73,1,7,0,74,1,2, -0,75,1,2,0,76,1,50,0,77,1,36,0,79,0,30,0,-103,0,39,0,125,0,61,0,2,0,27,0,31,0,36, -0,79,0,62,0,-127,0,27,0,31,0,2,0,-79,0,2,0,20,0,7,0,-73,0,7,0,-72,0,7,0,-71,0,7, -0,78,1,7,0,79,1,7,0,80,1,7,0,81,1,7,0,82,1,7,0,83,1,7,0,84,1,7,0,85,1,7, -0,86,1,7,0,87,1,7,0,88,1,7,0,89,1,7,0,90,1,7,0,91,1,7,0,92,1,7,0,93,1,7, -0,94,1,7,0,95,1,7,0,96,1,7,0,97,1,7,0,98,1,7,0,99,1,7,0,100,1,7,0,101,1,7, -0,102,1,7,0,103,1,7,0,104,1,2,0,105,1,2,0,106,1,2,0,107,1,0,0,108,1,0,0,109,1,7, -0,110,1,7,0,111,1,2,0,112,1,2,0,113,1,7,0,114,1,7,0,115,1,7,0,116,1,7,0,117,1,2, -0,118,1,2,0,119,1,4,0,13,1,4,0,120,1,2,0,121,1,2,0,122,1,2,0,123,1,2,0,124,1,7, -0,125,1,7,0,126,1,7,0,127,1,7,0,-128,1,7,0,-127,1,7,0,-126,1,7,0,-125,1,7,0,-124,1,7, -0,-123,1,7,0,-122,1,0,0,-121,1,7,0,-120,1,7,0,-119,1,7,0,-118,1,4,0,-117,1,0,0,-116,1,0, -0,47,1,0,0,-115,1,0,0,5,1,2,0,-114,1,2,0,-113,1,2,0,64,1,2,0,-112,1,2,0,-111,1,2, -0,-110,1,7,0,-109,1,7,0,-108,1,7,0,-107,1,7,0,-106,1,7,0,-105,1,2,0,-93,0,2,0,-92,0,54, -0,-104,1,54,0,-103,1,0,0,-102,1,0,0,-101,1,0,0,-100,1,0,0,-99,1,2,0,-98,1,2,0,12,1,7, -0,-97,1,7,0,-96,1,50,0,77,1,57,0,1,1,36,0,79,0,63,0,-95,1,30,0,-103,0,7,0,-94,1,7, -0,-93,1,7,0,-92,1,7,0,-91,1,7,0,-90,1,2,0,-89,1,2,0,70,0,7,0,-88,1,7,0,-87,1,7, -0,-86,1,7,0,-85,1,7,0,-84,1,7,0,-83,1,7,0,-82,1,7,0,-81,1,7,0,-80,1,2,0,-79,1,2, -0,-78,1,7,0,-77,1,7,0,-76,1,7,0,-75,1,7,0,-74,1,7,0,-73,1,4,0,-72,1,4,0,-71,1,4, -0,-70,1,39,0,125,0,12,0,-69,1,64,0,6,0,27,0,31,0,0,0,-68,1,7,0,-67,1,7,0,37,0,65, -0,2,0,43,0,-104,0,66,0,26,0,66,0,0,0,66,0,1,0,67,0,-66,1,4,0,-65,1,4,0,-64,1,4, -0,-63,1,4,0,-62,1,4,0,-61,1,4,0,-60,1,2,0,18,0,2,0,20,0,2,0,-59,1,2,0,-58,1,7, -0,5,0,7,0,6,0,7,0,7,0,7,0,-57,1,7,0,-56,1,7,0,-55,1,7,0,-54,1,7,0,-53,1,7, -0,-52,1,7,0,-51,1,7,0,23,0,7,0,-50,1,7,0,-49,1,68,0,15,0,27,0,31,0,67,0,-66,1,12, -0,-48,1,12,0,-47,1,36,0,79,0,62,0,-46,1,2,0,20,0,2,0,-45,1,4,0,-80,0,7,0,7,1,7, -0,-81,0,7,0,8,1,7,0,-44,1,7,0,-43,1,7,0,-42,1,35,0,10,0,7,0,-41,1,7,0,-40,1,7, -0,-39,1,7,0,-38,1,2,0,-37,1,2,0,-36,1,0,0,-35,1,0,0,-34,1,0,0,-33,1,0,0,-32,1,34, -0,7,0,7,0,-31,1,7,0,-40,1,7,0,-39,1,2,0,-35,1,2,0,-32,1,7,0,-38,1,7,0,37,0,69, -0,21,0,69,0,0,0,69,0,1,0,2,0,18,0,2,0,-30,1,2,0,-32,1,2,0,20,0,2,0,-29,1,2, -0,-28,1,2,0,-27,1,2,0,-26,1,2,0,-25,1,2,0,-24,1,2,0,-23,1,2,0,-22,1,7,0,-21,1,7, -0,-20,1,34,0,49,0,35,0,50,0,2,0,-19,1,2,0,-18,1,4,0,-17,1,70,0,5,0,2,0,-16,1,2, -0,-30,1,0,0,20,0,0,0,37,0,2,0,70,0,71,0,4,0,7,0,5,0,7,0,6,0,7,0,8,0,7, -0,-15,1,72,0,57,0,27,0,31,0,67,0,-66,1,12,0,-14,1,12,0,-47,1,32,0,-13,1,32,0,-12,1,32, -0,-11,1,36,0,79,0,73,0,-10,1,38,0,-9,1,62,0,-46,1,12,0,-8,1,7,0,7,1,7,0,-81,0,7, -0,8,1,4,0,-80,0,2,0,-7,1,2,0,-45,1,2,0,20,0,2,0,-6,1,7,0,-5,1,7,0,-4,1,7, -0,-3,1,2,0,-27,1,2,0,-26,1,2,0,-2,1,2,0,-1,1,4,0,70,0,2,0,23,0,2,0,98,0,2, -0,67,0,2,0,0,2,7,0,1,2,7,0,2,2,7,0,3,2,7,0,4,2,7,0,5,2,7,0,6,2,7, -0,7,2,7,0,8,2,7,0,9,2,7,0,10,2,0,0,11,2,0,0,12,2,64,0,13,2,64,0,14,2,64, -0,15,2,64,0,16,2,4,0,17,2,4,0,18,2,4,0,19,2,4,0,37,0,71,0,20,2,4,0,21,2,4, -0,22,2,70,0,23,2,70,0,24,2,74,0,39,0,27,0,31,0,67,0,-66,1,12,0,25,2,36,0,79,0,38, -0,-9,1,62,0,-46,1,75,0,26,2,76,0,27,2,77,0,28,2,78,0,29,2,79,0,30,2,80,0,31,2,81, -0,32,2,82,0,33,2,74,0,34,2,83,0,35,2,84,0,36,2,84,0,37,2,84,0,38,2,4,0,54,0,4, -0,39,2,4,0,40,2,4,0,41,2,4,0,42,2,4,0,-80,0,7,0,7,1,7,0,-81,0,7,0,8,1,7, -0,43,2,7,0,37,0,2,0,44,2,2,0,20,0,2,0,45,2,2,0,46,2,2,0,-45,1,2,0,47,2,85, -0,48,2,86,0,49,2,9,0,-94,0,77,0,8,0,9,0,50,2,7,0,51,2,4,0,52,2,0,0,20,0,0, -0,53,2,2,0,13,1,2,0,54,2,2,0,55,2,75,0,8,0,4,0,56,2,4,0,57,2,4,0,58,2,4, -0,59,2,0,0,37,0,0,0,-30,1,0,0,60,2,0,0,20,0,79,0,5,0,4,0,56,2,4,0,57,2,0, -0,61,2,0,0,62,2,2,0,20,0,87,0,2,0,4,0,63,2,7,0,-39,1,80,0,3,0,87,0,64,2,4, -0,65,2,4,0,20,0,78,0,6,0,7,0,66,2,2,0,67,2,0,0,20,0,0,0,-30,1,0,0,62,2,0, -0,68,2,81,0,4,0,0,0,-49,0,0,0,-73,0,0,0,-72,0,0,0,-71,0,88,0,6,0,46,0,50,2,0, -0,20,0,0,0,53,2,2,0,13,1,2,0,54,2,2,0,55,2,89,0,1,0,7,0,69,2,90,0,5,0,0, -0,-49,0,0,0,-73,0,0,0,-72,0,0,0,-71,0,4,0,37,0,82,0,1,0,7,0,70,2,83,0,2,0,4, -0,71,2,4,0,18,0,76,0,7,0,7,0,51,2,46,0,50,2,0,0,20,0,0,0,53,2,2,0,13,1,2, -0,54,2,2,0,55,2,91,0,1,0,7,0,72,2,92,0,1,0,4,0,73,2,93,0,1,0,0,0,74,2,94, -0,1,0,7,0,51,2,95,0,4,0,7,0,-49,0,7,0,-73,0,7,0,-72,0,7,0,-71,0,96,0,1,0,95, -0,52,2,97,0,5,0,4,0,75,2,4,0,76,2,0,0,20,0,0,0,-30,1,0,0,-74,0,98,0,2,0,4, -0,77,2,4,0,76,2,99,0,14,0,99,0,0,0,99,0,1,0,97,0,78,2,96,0,79,2,98,0,80,2,0, -0,81,2,12,0,82,2,12,0,83,2,100,0,84,2,4,0,54,0,4,0,40,2,4,0,39,2,4,0,37,0,78, -0,85,2,85,0,14,0,12,0,86,2,78,0,85,2,0,0,87,2,0,0,88,2,0,0,89,2,0,0,90,2,0, -0,91,2,0,0,92,2,0,0,93,2,0,0,20,0,84,0,36,2,84,0,38,2,2,0,94,2,0,0,95,2,86, -0,8,0,4,0,96,2,4,0,97,2,75,0,98,2,79,0,99,2,4,0,40,2,4,0,39,2,4,0,54,0,4, -0,37,0,101,0,6,0,101,0,0,0,101,0,1,0,4,0,18,0,4,0,13,1,0,0,17,0,0,0,100,2,102, -0,7,0,101,0,101,2,2,0,102,2,2,0,86,2,2,0,103,2,2,0,93,0,9,0,104,2,9,0,105,2,103, -0,3,0,101,0,101,2,32,0,-89,0,0,0,17,0,104,0,5,0,101,0,101,2,32,0,-89,0,0,0,17,0,2, -0,106,2,0,0,107,2,105,0,5,0,101,0,101,2,7,0,91,0,7,0,108,2,4,0,109,2,4,0,110,2,106, -0,5,0,101,0,101,2,32,0,111,2,0,0,72,0,4,0,13,1,4,0,20,0,107,0,13,0,101,0,101,2,32, -0,112,2,32,0,113,2,32,0,114,2,32,0,115,2,7,0,116,2,7,0,117,2,7,0,108,2,7,0,118,2,4, -0,119,2,4,0,120,2,4,0,93,0,4,0,121,2,108,0,5,0,101,0,101,2,2,0,122,2,2,0,20,0,7, -0,123,2,32,0,124,2,109,0,3,0,101,0,101,2,7,0,125,2,4,0,93,0,110,0,10,0,101,0,101,2,7, -0,126,2,4,0,127,2,4,0,37,0,2,0,93,0,2,0,-128,2,2,0,-127,2,2,0,-126,2,7,0,-125,2,0, -0,-124,2,111,0,3,0,101,0,101,2,7,0,37,0,4,0,18,0,112,0,11,0,101,0,101,2,51,0,-123,2,7, -0,-122,2,4,0,-121,2,0,0,-124,2,7,0,-120,2,4,0,-119,2,32,0,-118,2,0,0,-117,2,4,0,-116,2,4, -0,37,0,113,0,10,0,101,0,101,2,32,0,-115,2,46,0,-114,2,4,0,93,0,4,0,-113,2,7,0,-112,2,7, -0,-111,2,0,0,-117,2,4,0,-116,2,4,0,37,0,114,0,3,0,101,0,101,2,7,0,-110,2,4,0,-109,2,115, -0,5,0,101,0,101,2,7,0,-108,2,0,0,-124,2,2,0,20,0,2,0,-107,2,116,0,8,0,101,0,101,2,32, -0,-89,0,7,0,-108,2,7,0,-38,1,7,0,109,0,0,0,-124,2,2,0,20,0,2,0,18,0,117,0,21,0,101, -0,101,2,32,0,-106,2,0,0,-124,2,51,0,-123,2,32,0,-118,2,2,0,20,0,2,0,37,0,7,0,-105,2,7, -0,-104,2,7,0,-103,2,7,0,-5,1,7,0,-102,2,7,0,-101,2,7,0,-100,2,7,0,-99,2,4,0,-119,2,4, -0,-116,2,0,0,-117,2,7,0,-98,2,7,0,-97,2,7,0,43,0,118,0,7,0,101,0,101,2,2,0,-96,2,2, -0,-95,2,4,0,70,0,32,0,-89,0,7,0,-94,2,0,0,-124,2,119,0,9,0,101,0,101,2,32,0,-89,0,7, -0,-93,2,7,0,-92,2,7,0,-99,2,4,0,-91,2,4,0,-90,2,7,0,-89,2,0,0,17,0,120,0,1,0,101, -0,101,2,121,0,5,0,101,0,101,2,122,0,-88,2,123,0,-87,2,124,0,-86,2,125,0,-85,2,126,0,14,0,101, -0,101,2,78,0,-84,2,78,0,-83,2,78,0,-82,2,78,0,-81,2,78,0,-80,2,78,0,-79,2,75,0,-78,2,4, -0,-77,2,4,0,-76,2,2,0,-75,2,2,0,37,0,7,0,-74,2,127,0,-73,2,-128,0,3,0,101,0,101,2,-127, -0,-72,2,-126,0,-73,2,-125,0,4,0,101,0,101,2,32,0,-89,0,4,0,-71,2,4,0,37,0,-124,0,2,0,4, -0,-70,2,7,0,-39,1,-123,0,2,0,4,0,-127,0,4,0,-69,2,-122,0,20,0,101,0,101,2,32,0,-89,0,0, -0,-124,2,2,0,-68,2,2,0,-67,2,2,0,20,0,2,0,37,0,7,0,-66,2,7,0,-65,2,4,0,54,0,4, -0,-64,2,-123,0,-63,2,-124,0,-62,2,4,0,-61,2,4,0,-60,2,4,0,-59,2,4,0,-69,2,7,0,-58,2,7, -0,-57,2,7,0,-56,2,-121,0,8,0,101,0,101,2,-120,0,-55,2,-127,0,-72,2,4,0,-54,2,4,0,-53,2,4, -0,-52,2,2,0,20,0,2,0,57,0,-119,0,5,0,101,0,101,2,32,0,45,0,2,0,-51,2,2,0,20,0,2, -0,-50,2,-118,0,5,0,101,0,101,2,4,0,-49,2,2,0,20,0,2,0,-48,2,7,0,-47,2,-117,0,3,0,101, -0,101,2,-116,0,-46,2,125,0,-85,2,-115,0,10,0,101,0,101,2,32,0,-45,2,32,0,-44,2,0,0,-43,2,7, -0,-42,2,2,0,-41,2,2,0,-40,2,0,0,-39,2,0,0,-38,2,0,0,107,2,-114,0,9,0,101,0,101,2,32, -0,-37,2,0,0,-43,2,7,0,-36,2,7,0,-35,2,0,0,13,1,0,0,122,2,0,0,-34,2,0,0,37,0,-113, -0,24,0,27,0,31,0,2,0,-29,1,2,0,-28,1,2,0,-33,2,2,0,20,0,2,0,-32,2,2,0,-31,2,2, -0,-30,2,2,0,70,0,0,0,-29,2,0,0,-28,2,0,0,-27,2,0,0,18,0,4,0,37,0,7,0,-26,2,7, -0,-25,2,7,0,-24,2,7,0,-23,2,7,0,-22,2,7,0,-21,2,34,0,-20,2,36,0,79,0,38,0,-9,1,80, -0,31,2,-112,0,3,0,-112,0,0,0,-112,0,1,0,0,0,17,0,67,0,3,0,7,0,-19,2,4,0,20,0,4, -0,37,0,32,0,111,0,27,0,31,0,2,0,18,0,2,0,-18,2,4,0,-17,2,4,0,-16,2,4,0,-15,2,0, -0,-14,2,32,0,38,0,32,0,-13,2,32,0,-12,2,32,0,-11,2,32,0,-10,2,36,0,79,0,73,0,-10,1,67, -0,-66,1,-111,0,-9,2,-111,0,-8,2,-110,0,-7,2,9,0,2,0,12,0,-6,2,12,0,25,2,12,0,-47,1,12, -0,-5,2,12,0,-4,2,62,0,-46,1,7,0,7,1,7,0,-3,2,7,0,-2,2,7,0,-81,0,7,0,-1,2,7, -0,8,1,7,0,0,3,7,0,1,3,7,0,-93,2,7,0,2,3,7,0,-45,0,4,0,3,3,2,0,20,0,2, -0,4,3,2,0,5,3,2,0,6,3,2,0,7,3,2,0,8,3,2,0,9,3,2,0,10,3,2,0,11,3,2, -0,12,3,2,0,13,3,2,0,14,3,4,0,15,3,4,0,16,3,4,0,17,3,4,0,18,3,7,0,19,3,7, -0,20,3,7,0,21,3,7,0,22,3,7,0,23,3,7,0,24,3,7,0,25,3,7,0,26,3,7,0,27,3,7, -0,28,3,7,0,29,3,7,0,30,3,0,0,31,3,0,0,32,3,0,0,-45,1,0,0,33,3,0,0,34,3,0, -0,35,3,7,0,36,3,7,0,37,3,39,0,125,0,12,0,38,3,12,0,39,3,12,0,40,3,12,0,41,3,7, -0,42,3,2,0,71,2,2,0,43,3,7,0,52,2,4,0,44,3,4,0,45,3,-109,0,46,3,2,0,47,3,2, -0,-38,0,7,0,48,3,12,0,49,3,12,0,50,3,12,0,51,3,12,0,52,3,-108,0,53,3,-107,0,54,3,63, -0,55,3,2,0,56,3,2,0,57,3,2,0,58,3,2,0,59,3,7,0,44,2,2,0,60,3,2,0,61,3,-116, -0,62,3,-127,0,63,3,-127,0,64,3,4,0,65,3,4,0,66,3,4,0,67,3,4,0,70,0,9,0,-94,0,12, -0,68,3,-106,0,14,0,-106,0,0,0,-106,0,1,0,32,0,38,0,7,0,-93,2,7,0,9,1,7,0,-92,2,7, -0,-99,2,0,0,17,0,4,0,-91,2,4,0,-90,2,4,0,69,3,2,0,18,0,2,0,70,3,7,0,-89,2,-108, -0,36,0,2,0,71,3,2,0,72,3,2,0,20,0,2,0,-99,2,7,0,73,3,7,0,74,3,7,0,75,3,7, -0,76,3,7,0,77,3,7,0,78,3,7,0,79,3,7,0,80,3,7,0,81,3,7,0,82,3,7,0,83,3,7, -0,84,3,7,0,85,3,7,0,86,3,7,0,87,3,7,0,88,3,7,0,89,3,7,0,90,3,7,0,91,3,7, -0,92,3,7,0,93,3,7,0,94,3,7,0,95,3,7,0,96,3,2,0,97,3,2,0,98,3,2,0,99,3,2, -0,100,3,51,0,-88,0,-105,0,101,3,7,0,102,3,4,0,110,2,125,0,5,0,4,0,20,0,4,0,103,3,4, -0,104,3,4,0,105,3,4,0,106,3,-104,0,1,0,7,0,-31,1,-109,0,30,0,4,0,20,0,7,0,107,3,7, -0,108,3,7,0,109,3,4,0,110,3,4,0,111,3,4,0,112,3,4,0,113,3,7,0,114,3,7,0,115,3,7, -0,116,3,7,0,117,3,7,0,118,3,7,0,119,3,7,0,120,3,7,0,121,3,7,0,122,3,7,0,123,3,7, -0,124,3,7,0,125,3,7,0,126,3,7,0,127,3,7,0,-128,3,7,0,-127,3,7,0,-126,3,7,0,-125,3,4, -0,-124,3,4,0,-123,3,7,0,-122,3,7,0,27,3,-107,0,49,0,-120,0,-121,3,4,0,-120,3,4,0,-119,3,-103, -0,-118,3,-102,0,-117,3,0,0,37,0,0,0,-116,3,2,0,-115,3,7,0,-114,3,0,0,-113,3,7,0,-112,3,7, -0,-111,3,7,0,-110,3,7,0,-109,3,7,0,-108,3,7,0,-107,3,7,0,-106,3,7,0,-105,3,7,0,-104,3,2, -0,-103,3,0,0,-102,3,2,0,-101,3,7,0,-100,3,7,0,-99,3,0,0,-98,3,4,0,-126,0,4,0,-97,3,4, -0,-96,3,2,0,-95,3,2,0,-94,3,-104,0,-93,3,4,0,-92,3,4,0,81,0,7,0,-91,3,7,0,-90,3,7, -0,-89,3,7,0,-88,3,2,0,-87,3,2,0,-86,3,2,0,-85,3,2,0,-84,3,2,0,-83,3,2,0,-82,3,2, -0,-81,3,2,0,-80,3,-101,0,-79,3,7,0,-78,3,7,0,-77,3,125,0,-76,3,-116,0,48,0,2,0,18,0,2, -0,-75,3,2,0,-74,3,2,0,-73,3,7,0,-72,3,2,0,-71,3,2,0,-70,3,7,0,-69,3,2,0,-68,3,2, -0,-67,3,7,0,-66,3,7,0,-65,3,7,0,-64,3,7,0,-63,3,7,0,-62,3,7,0,-61,3,4,0,-60,3,7, -0,-59,3,7,0,-58,3,7,0,-57,3,74,0,-56,3,74,0,-55,3,74,0,-54,3,0,0,-53,3,7,0,-52,3,7, -0,-51,3,36,0,79,0,2,0,-50,3,0,0,-49,3,0,0,-48,3,7,0,-47,3,4,0,-46,3,7,0,-45,3,7, -0,-44,3,4,0,-43,3,4,0,20,0,7,0,-42,3,7,0,-41,3,7,0,-40,3,78,0,-39,3,7,0,-38,3,7, -0,-37,3,7,0,-36,3,7,0,-35,3,7,0,-34,3,7,0,-33,3,7,0,-32,3,4,0,-31,3,-100,0,71,0,27, -0,31,0,2,0,-79,0,2,0,14,1,2,0,47,1,2,0,-30,3,7,0,-29,3,7,0,-28,3,7,0,-27,3,7, -0,-26,3,7,0,-25,3,7,0,-24,3,7,0,-23,3,7,0,-22,3,7,0,84,1,7,0,86,1,7,0,85,1,7, -0,-21,3,4,0,-20,3,7,0,-19,3,7,0,-18,3,7,0,-17,3,7,0,-16,3,7,0,-15,3,7,0,-14,3,7, -0,-13,3,2,0,-12,3,2,0,13,1,2,0,-11,3,2,0,-10,3,2,0,-9,3,2,0,-8,3,2,0,-7,3,2, -0,-6,3,7,0,-5,3,7,0,-4,3,7,0,-3,3,7,0,-2,3,7,0,-1,3,7,0,0,4,7,0,1,4,7, -0,2,4,7,0,3,4,7,0,4,4,7,0,5,4,7,0,6,4,2,0,7,4,2,0,8,4,2,0,9,4,2, -0,10,4,7,0,11,4,7,0,12,4,7,0,13,4,7,0,14,4,2,0,15,4,2,0,16,4,2,0,17,4,2, -0,18,4,7,0,19,4,7,0,20,4,7,0,21,4,7,0,22,4,2,0,23,4,2,0,24,4,2,0,25,4,2, -0,43,0,7,0,26,4,7,0,27,4,36,0,79,0,50,0,77,1,30,0,-103,0,39,0,125,0,-99,0,16,0,2, -0,28,4,2,0,29,4,2,0,30,4,2,0,20,0,2,0,31,4,2,0,32,4,2,0,33,4,2,0,34,4,2, -0,35,4,2,0,36,4,2,0,37,4,2,0,38,4,4,0,39,4,7,0,40,4,7,0,41,4,7,0,42,4,-98, -0,8,0,-98,0,0,0,-98,0,1,0,4,0,3,3,4,0,43,4,4,0,20,0,2,0,44,4,2,0,45,4,32, -0,-89,0,-97,0,13,0,9,0,46,4,9,0,47,4,4,0,48,4,4,0,49,4,4,0,50,4,4,0,51,4,4, -0,52,4,4,0,53,4,4,0,54,4,4,0,55,4,4,0,56,4,4,0,37,0,0,0,57,4,-96,0,5,0,9, -0,58,4,9,0,59,4,4,0,60,4,4,0,70,0,0,0,61,4,-95,0,13,0,4,0,18,0,4,0,62,4,4, -0,63,4,4,0,64,4,4,0,65,4,4,0,66,4,4,0,93,0,4,0,67,4,4,0,68,4,4,0,69,4,4, -0,70,4,4,0,71,4,26,0,30,0,-94,0,4,0,4,0,72,4,7,0,73,4,2,0,20,0,2,0,68,2,-93, -0,11,0,-93,0,0,0,-93,0,1,0,0,0,17,0,62,0,74,4,63,0,75,4,4,0,3,3,4,0,76,4,4, -0,77,4,4,0,37,0,4,0,78,4,4,0,79,4,-92,0,-126,0,-97,0,80,4,-96,0,81,4,-95,0,82,4,4, -0,83,4,4,0,-126,0,4,0,-97,3,4,0,84,4,4,0,85,4,4,0,86,4,4,0,87,4,2,0,20,0,2, -0,88,4,7,0,20,3,7,0,89,4,7,0,90,4,7,0,91,4,7,0,92,4,7,0,93,4,2,0,94,4,2, -0,95,4,2,0,96,4,2,0,97,4,2,0,-39,0,2,0,98,4,2,0,99,4,2,0,100,3,2,0,100,4,2, -0,101,4,2,0,34,1,2,0,109,0,2,0,102,4,2,0,103,4,2,0,104,4,2,0,105,4,2,0,106,4,2, -0,107,4,2,0,108,4,2,0,109,4,2,0,110,4,2,0,35,1,2,0,111,4,2,0,112,4,2,0,113,4,2, -0,114,4,4,0,115,4,4,0,13,1,2,0,116,4,2,0,117,4,2,0,118,4,2,0,119,4,2,0,120,4,2, -0,121,4,24,0,122,4,24,0,123,4,23,0,124,4,12,0,125,4,2,0,126,4,2,0,37,0,7,0,127,4,7, -0,-128,4,7,0,-127,4,7,0,-126,4,7,0,-125,4,7,0,-124,4,7,0,-123,4,7,0,-122,4,7,0,-121,4,2, -0,-120,4,2,0,-119,4,2,0,-118,4,2,0,-117,4,2,0,-116,4,2,0,-115,4,7,0,-114,4,7,0,-113,4,7, -0,-112,4,2,0,-111,4,2,0,-110,4,2,0,-109,4,2,0,-108,4,2,0,-107,4,2,0,-106,4,2,0,-105,4,2, -0,-104,4,2,0,-103,4,2,0,-102,4,4,0,-101,4,4,0,-100,4,4,0,-99,4,4,0,-98,4,4,0,-97,4,7, -0,-96,4,4,0,-95,4,4,0,-94,4,4,0,-93,4,4,0,-92,4,7,0,-91,4,7,0,-90,4,7,0,-89,4,7, -0,-88,4,7,0,-87,4,7,0,-86,4,7,0,-85,4,7,0,-84,4,7,0,-83,4,0,0,-82,4,0,0,-81,4,4, -0,-80,4,2,0,-79,4,2,0,12,1,0,0,-78,4,7,0,-77,4,7,0,-76,4,4,0,-75,4,4,0,-74,4,7, -0,-73,4,7,0,-72,4,2,0,-71,4,2,0,-70,4,7,0,-69,4,2,0,-68,4,2,0,-67,4,4,0,-66,4,2, -0,-65,4,2,0,-64,4,2,0,-63,4,2,0,-62,4,7,0,-61,4,7,0,70,0,42,0,-60,4,-91,0,9,0,-91, -0,0,0,-91,0,1,0,0,0,17,0,2,0,-59,4,2,0,-58,4,2,0,-57,4,2,0,43,0,7,0,-56,4,7, -0,70,0,-90,0,5,0,7,0,-55,4,0,0,18,0,0,0,43,0,0,0,70,0,0,0,12,1,-89,0,5,0,-89, -0,0,0,-89,0,1,0,4,0,-54,4,0,0,-53,4,4,0,20,0,-88,0,5,0,-87,0,-52,4,2,0,20,0,2, -0,-51,4,2,0,-50,4,2,0,-49,4,-86,0,4,0,2,0,109,0,2,0,-122,2,2,0,-48,4,2,0,-47,4,-85, -0,7,0,2,0,20,0,2,0,-46,4,2,0,-45,4,2,0,-44,4,-86,0,-43,4,7,0,-42,4,4,0,-41,4,-84, -0,4,0,-84,0,0,0,-84,0,1,0,0,0,-40,4,7,0,-39,4,-83,0,56,0,2,0,-38,4,2,0,-37,4,7, -0,-36,4,7,0,-35,4,2,0,-48,4,2,0,-34,4,7,0,-33,4,7,0,-32,4,2,0,-31,4,2,0,-30,4,2, -0,-29,4,2,0,-28,4,7,0,-27,4,7,0,-26,4,7,0,-25,4,7,0,37,0,2,0,-24,4,2,0,-23,4,2, -0,-22,4,2,0,-21,4,-88,0,-20,4,-85,0,-19,4,7,0,-18,4,7,0,-17,4,0,0,-16,4,0,0,-15,4,0, -0,-14,4,0,0,-13,4,0,0,-12,4,0,0,-11,4,2,0,-10,4,7,0,-9,4,7,0,-8,4,7,0,-7,4,7, -0,-6,4,7,0,-5,4,7,0,-4,4,7,0,-3,4,7,0,-2,4,7,0,-1,4,7,0,0,5,2,0,1,5,0, -0,2,5,0,0,3,5,0,0,4,5,0,0,5,5,32,0,6,5,0,0,7,5,0,0,8,5,0,0,9,5,0, -0,10,5,0,0,11,5,0,0,12,5,0,0,13,5,0,0,14,5,0,0,15,5,-82,0,6,0,2,0,109,0,0, -0,-122,2,0,0,16,5,0,0,17,5,0,0,20,0,0,0,-74,0,-81,0,26,0,-80,0,18,5,50,0,77,1,60, -0,19,5,-82,0,20,5,-82,0,21,5,-82,0,22,5,-82,0,23,5,-82,0,24,5,-82,0,25,5,-82,0,26,5,7, -0,27,5,2,0,28,5,2,0,47,1,2,0,29,5,2,0,1,2,0,0,30,5,0,0,31,5,0,0,32,5,0, -0,33,5,0,0,93,0,0,0,34,5,0,0,35,5,0,0,36,5,0,0,37,5,0,0,38,5,0,0,-74,0,-79, -0,43,0,27,0,31,0,32,0,39,5,-100,0,40,5,-79,0,41,5,46,0,-47,0,12,0,42,5,-98,0,43,5,7, -0,44,5,7,0,45,5,7,0,46,5,7,0,47,5,4,0,3,3,7,0,48,5,2,0,49,5,2,0,50,5,2, -0,51,5,2,0,52,5,2,0,53,5,2,0,54,5,2,0,55,5,2,0,5,1,57,0,1,1,9,0,56,5,-99, -0,57,5,-90,0,58,5,-83,0,59,5,-92,0,-73,0,-94,0,60,5,39,0,125,0,12,0,103,0,12,0,61,5,2, -0,62,5,2,0,63,5,2,0,64,5,2,0,65,5,-78,0,66,5,2,0,67,5,2,0,68,5,2,0,64,1,2, -0,-38,0,-81,0,69,5,4,0,70,5,4,0,37,0,-77,0,9,0,46,0,-47,0,45,0,0,1,7,0,8,2,7, -0,9,2,7,0,109,0,7,0,71,5,7,0,72,5,2,0,73,5,2,0,74,5,-76,0,75,0,-75,0,0,0,-75, -0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,7,0,79,5,7,0,80,5,7,0,81,5,7, -0,82,5,7,0,83,5,7,0,84,5,7,0,85,5,7,0,20,1,7,0,86,5,4,0,87,5,2,0,88,5,2, -0,17,5,32,0,39,5,32,0,89,5,-77,0,90,5,-76,0,91,5,-73,0,92,5,-72,0,93,5,-71,0,94,5,0, -0,95,5,2,0,30,4,2,0,96,5,4,0,3,3,4,0,97,5,2,0,98,5,2,0,99,5,2,0,100,5,0, -0,101,5,0,0,43,0,7,0,115,0,7,0,102,5,7,0,103,5,7,0,104,5,7,0,105,5,7,0,106,5,7, -0,107,5,7,0,108,5,7,0,-82,0,7,0,44,5,2,0,109,5,2,0,110,5,2,0,111,5,2,0,112,5,2, -0,-119,0,2,0,29,5,2,0,113,5,2,0,114,5,2,0,115,5,2,0,116,5,7,0,117,5,7,0,118,5,67, -0,119,5,12,0,120,5,2,0,121,5,2,0,53,2,2,0,122,5,2,0,20,0,2,0,123,5,2,0,124,5,2, -0,125,5,0,0,126,5,0,0,127,5,9,0,-128,5,-70,0,-127,5,7,0,-126,5,2,0,-125,5,2,0,-124,5,2, -0,53,5,2,0,54,5,-69,0,19,0,24,0,36,0,24,0,64,0,23,0,-123,5,23,0,-122,5,23,0,-121,5,7, -0,-120,5,7,0,-119,5,7,0,-118,5,7,0,-117,5,2,0,-116,5,2,0,-115,5,2,0,-114,5,2,0,-113,5,2, -0,-112,5,2,0,-111,5,4,0,20,0,7,0,-110,5,2,0,99,5,0,0,107,2,-75,0,6,0,-75,0,0,0,-75, -0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-68,0,6,0,-75,0,0,0,-75,0,1,0,4, -0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-67,0,27,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7, -0,76,5,-74,0,77,5,2,0,78,5,4,0,-109,5,4,0,70,0,-69,0,-108,5,9,0,-107,5,12,0,-106,5,36, -0,79,0,27,0,80,0,0,0,-105,5,0,0,-104,5,0,0,-103,5,2,0,-102,5,2,0,-101,5,2,0,-100,5,2, -0,-99,5,2,0,65,0,2,0,46,0,2,0,-119,0,2,0,-98,5,4,0,20,0,7,0,-97,5,24,0,36,0,-66, -0,29,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,-73,0,92,5,2,0,78,5,2, -0,-96,5,2,0,-95,5,2,0,-94,5,2,0,-93,5,-69,0,-108,5,2,0,-92,5,2,0,-119,0,2,0,-101,5,2, -0,-91,5,9,0,-90,5,2,0,29,5,0,0,-89,5,0,0,-88,5,2,0,-87,5,2,0,-86,5,2,0,12,3,2, -0,-85,5,2,0,-84,5,0,0,37,0,0,0,20,0,0,0,47,1,0,0,-83,5,-65,0,16,0,-75,0,0,0,-75, -0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-69,0,-108,5,7,0,8,2,7,0,9,2,2, -0,-92,5,2,0,-82,5,2,0,-81,5,2,0,-80,5,4,0,20,0,7,0,71,5,-70,0,-127,5,-64,0,33,0,-75, -0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-63,0,-79,5,4,0,-78,5,0, -0,-77,5,0,0,-76,5,0,0,-75,5,2,0,18,0,2,0,-74,5,2,0,20,0,2,0,-73,5,2,0,-72,5,2, -0,-71,5,2,0,-70,5,2,0,43,0,4,0,70,0,0,0,-69,5,-62,0,-68,5,2,0,-67,5,2,0,-66,5,2, -0,-65,5,2,0,-48,0,9,0,-64,5,9,0,-63,5,9,0,-62,5,9,0,-61,5,9,0,-60,5,2,0,-59,5,0, -0,-58,5,-61,0,23,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-69, -0,-108,5,12,0,-57,5,2,0,-101,5,2,0,-56,5,2,0,20,0,2,0,57,0,9,0,-90,5,12,0,-55,5,-60, -0,-54,5,0,0,-53,5,-59,0,-52,5,4,0,-51,5,4,0,-50,5,2,0,18,0,2,0,-49,5,2,0,-48,5,2, -0,-47,5,-58,0,29,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-69, -0,-108,5,46,0,-114,2,45,0,0,1,60,0,19,5,2,0,13,1,2,0,-119,0,2,0,-46,5,2,0,-45,5,4, -0,20,0,2,0,49,5,2,0,-44,5,2,0,-98,5,2,0,-101,5,7,0,71,5,0,0,-43,5,0,0,-42,5,0, -0,-41,5,0,0,-40,5,7,0,8,2,7,0,9,2,7,0,-39,5,7,0,-38,5,-70,0,-127,5,-57,0,11,0,-75, -0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,2,0,-119,0,2,0,-98,5,2, -0,-37,5,2,0,20,0,-69,0,-108,5,-56,0,24,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74, -0,77,5,2,0,78,5,42,0,-36,5,4,0,-35,5,4,0,-34,5,2,0,93,0,2,0,-119,0,4,0,-33,5,4, -0,-32,5,4,0,-31,5,4,0,-30,5,4,0,-29,5,4,0,-28,5,4,0,-27,5,4,0,-26,5,7,0,-25,5,23, -0,-24,5,23,0,-23,5,4,0,-22,5,4,0,-21,5,-55,0,10,0,27,0,31,0,9,0,-20,5,9,0,-19,5,9, -0,-18,5,9,0,-17,5,9,0,-16,5,4,0,93,0,4,0,-15,5,0,0,-14,5,0,0,-13,5,-54,0,10,0,-75, -0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,-55,0,-12,5,2,0,93,0,2,0,-119,0,4, -0,43,0,9,0,-11,5,-53,0,8,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,-69, -0,-108,5,4,0,20,0,4,0,-10,5,-52,0,21,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74, -0,77,5,2,0,78,5,-69,0,-108,5,27,0,-9,5,27,0,80,0,2,0,20,0,2,0,-119,0,7,0,-8,5,9, -0,-7,5,7,0,8,2,7,0,9,2,57,0,1,1,57,0,-6,5,4,0,-5,5,2,0,-89,5,2,0,37,0,-70, -0,-127,5,-51,0,42,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-69, -0,-108,5,-50,0,-4,5,0,0,-77,5,0,0,-76,5,0,0,-75,5,2,0,18,0,2,0,-66,5,2,0,20,0,2, -0,-73,5,9,0,-7,5,4,0,-3,5,4,0,-2,5,4,0,-1,5,4,0,0,6,23,0,1,6,23,0,2,6,7, -0,3,6,7,0,4,6,7,0,5,6,7,0,-8,5,2,0,-67,5,2,0,-48,0,2,0,102,1,2,0,6,6,2, -0,37,0,2,0,43,0,2,0,7,6,2,0,8,6,9,0,-64,5,9,0,-63,5,9,0,-62,5,9,0,-61,5,9, -0,-60,5,2,0,-59,5,0,0,-58,5,56,0,9,6,-49,0,20,0,0,0,10,6,0,0,11,6,0,0,12,6,0, -0,13,6,0,0,14,6,0,0,15,6,0,0,16,6,0,0,17,6,0,0,18,6,0,0,19,6,0,0,20,6,0, -0,21,6,0,0,22,6,0,0,23,6,0,0,24,6,0,0,25,6,0,0,26,6,0,0,27,6,0,0,68,2,0, -0,28,6,-48,0,54,0,0,0,29,6,0,0,20,6,0,0,21,6,0,0,30,6,0,0,31,6,0,0,32,6,0, -0,33,6,0,0,34,6,0,0,35,6,0,0,36,6,0,0,37,6,0,0,38,6,0,0,39,6,0,0,40,6,0, -0,41,6,0,0,42,6,0,0,43,6,0,0,44,6,0,0,45,6,0,0,46,6,0,0,47,6,0,0,48,6,0, -0,49,6,0,0,50,6,0,0,51,6,0,0,52,6,0,0,53,6,0,0,54,6,0,0,55,6,0,0,56,6,0, -0,57,6,0,0,58,6,0,0,95,0,0,0,59,6,0,0,60,6,0,0,61,6,0,0,62,6,0,0,63,6,0, -0,64,6,0,0,65,6,0,0,66,6,0,0,67,6,0,0,68,6,0,0,69,6,0,0,70,6,0,0,71,6,0, -0,72,6,0,0,73,6,0,0,74,6,0,0,75,6,0,0,76,6,0,0,77,6,0,0,78,6,0,0,79,6,-47, -0,5,0,0,0,80,6,0,0,37,6,0,0,39,6,2,0,20,0,2,0,37,0,-46,0,22,0,-46,0,0,0,-46, -0,1,0,0,0,17,0,-49,0,81,6,-48,0,82,6,-48,0,83,6,-48,0,84,6,-48,0,85,6,-48,0,86,6,-48, -0,87,6,-48,0,88,6,-48,0,89,6,-48,0,90,6,-48,0,91,6,-48,0,92,6,-48,0,93,6,-48,0,94,6,-48, -0,95,6,-48,0,96,6,-47,0,97,6,0,0,98,6,0,0,99,6,-45,0,5,0,4,0,20,0,4,0,37,0,7, -0,52,2,7,0,100,6,7,0,-31,1,-44,0,66,0,4,0,20,0,4,0,101,6,4,0,102,6,0,0,103,6,0, -0,104,6,0,0,105,6,0,0,106,6,0,0,107,6,0,0,108,6,0,0,109,6,0,0,110,6,0,0,111,6,2, -0,112,6,2,0,113,6,4,0,114,6,4,0,115,6,4,0,116,6,4,0,117,6,2,0,118,6,2,0,119,6,2, -0,120,6,2,0,121,6,4,0,122,6,4,0,123,6,2,0,124,6,2,0,125,6,2,0,126,6,2,0,127,6,0, -0,-128,6,12,0,-127,6,2,0,-126,6,2,0,-125,6,2,0,-124,6,2,0,-123,6,2,0,-122,6,2,0,-121,6,2, -0,-120,6,2,0,-119,6,-45,0,-118,6,2,0,-117,6,2,0,-116,6,2,0,-115,6,2,0,-114,6,4,0,-113,6,4, -0,-112,6,4,0,-111,6,4,0,-110,6,2,0,-109,6,2,0,-108,6,2,0,-107,6,2,0,-106,6,2,0,-105,6,2, -0,-104,6,2,0,-103,6,2,0,-102,6,2,0,-101,6,2,0,-100,6,2,0,-99,6,2,0,37,0,0,0,-98,6,0, -0,-97,6,0,0,-96,6,7,0,-95,6,2,0,55,5,2,0,-94,6,54,0,-93,6,-43,0,18,0,27,0,31,0,12, -0,-92,6,12,0,-91,6,12,0,-90,6,-79,0,-89,6,2,0,-105,2,2,0,-88,6,2,0,-104,2,2,0,-87,6,2, -0,-86,6,2,0,-85,6,2,0,-84,6,2,0,-83,6,2,0,-82,6,2,0,37,0,2,0,-81,6,2,0,-80,6,2, -0,-79,6,-42,0,5,0,-42,0,0,0,-42,0,1,0,-42,0,-78,6,13,0,-77,6,4,0,20,0,-41,0,7,0,-41, -0,0,0,-41,0,1,0,-42,0,-76,6,-42,0,-75,6,2,0,123,4,2,0,20,0,4,0,37,0,-40,0,17,0,-40, -0,0,0,-40,0,1,0,0,0,-74,6,0,0,-73,6,0,0,-72,6,2,0,-71,6,2,0,-70,6,2,0,-86,6,2, -0,-85,6,2,0,20,0,2,0,70,3,2,0,-69,6,2,0,-68,6,2,0,-67,6,2,0,-66,6,4,0,-65,6,-40, -0,-64,6,-74,0,30,0,-74,0,0,0,-74,0,1,0,-42,0,-76,6,-42,0,-75,6,-42,0,-63,6,-42,0,-62,6,-43, -0,-61,6,7,0,-60,6,23,0,52,0,23,0,-59,6,23,0,-58,6,2,0,-57,6,2,0,-56,6,2,0,-55,6,0, -0,75,5,0,0,-54,6,2,0,-53,6,2,0,-52,6,0,0,-51,6,0,0,-50,6,0,0,-49,6,0,0,-48,6,2, -0,-47,6,2,0,-46,6,2,0,-45,6,2,0,20,0,39,0,125,0,12,0,-44,6,12,0,-43,6,12,0,-42,6,-39, -0,11,0,0,0,-41,6,2,0,-40,6,2,0,-39,6,2,0,-38,6,2,0,-37,6,2,0,-36,6,2,0,107,4,9, -0,-35,6,9,0,-34,6,4,0,-33,6,4,0,-32,6,-38,0,1,0,0,0,-31,6,-37,0,8,0,56,0,-30,6,56, -0,-29,6,-37,0,-28,6,-37,0,-27,6,-37,0,-26,6,2,0,-123,0,2,0,20,0,4,0,-25,6,-36,0,4,0,4, -0,-35,5,4,0,-24,6,4,0,-31,5,4,0,-23,6,-35,0,2,0,4,0,-22,6,4,0,-21,6,-34,0,9,0,7, -0,-20,6,7,0,-19,6,7,0,-18,6,4,0,20,0,4,0,13,1,7,0,-19,3,7,0,-17,6,4,0,37,0,-33, -0,-16,6,-32,0,6,0,0,0,-15,6,0,0,-75,5,48,0,-116,0,2,0,109,0,2,0,111,4,4,0,37,0,-31, -0,21,0,-31,0,0,0,-31,0,1,0,4,0,57,0,4,0,23,0,4,0,28,0,4,0,-14,6,4,0,-13,6,4, -0,-12,6,-38,0,-11,6,0,0,-15,6,4,0,-10,6,4,0,-9,6,-32,0,-12,2,-36,0,-8,6,-35,0,-7,6,-34, -0,-6,6,-37,0,-5,6,-37,0,-4,6,-37,0,-3,6,56,0,-2,6,56,0,-1,6,-30,0,12,0,0,0,-68,1,9, -0,-62,0,0,0,-61,0,4,0,-58,0,4,0,-50,0,9,0,-57,0,7,0,-55,0,7,0,-54,0,9,0,0,7,9, -0,1,7,9,0,-53,0,9,0,-51,0,-29,0,43,0,-29,0,0,0,-29,0,1,0,9,0,2,7,9,0,26,0,0, -0,27,0,4,0,20,0,4,0,18,0,4,0,23,0,4,0,91,0,4,0,3,7,4,0,4,7,4,0,-13,6,4, -0,-12,6,4,0,5,7,4,0,-39,0,4,0,6,7,4,0,7,7,7,0,8,7,7,0,9,7,4,0,-126,0,4, -0,10,7,-31,0,11,7,36,0,79,0,-79,0,-89,6,48,0,-116,0,7,0,12,7,7,0,13,7,-30,0,2,1,-29, -0,14,7,-29,0,15,7,-29,0,16,7,12,0,17,7,-28,0,18,7,-27,0,19,7,7,0,20,7,7,0,21,7,4, -0,-84,6,7,0,22,7,9,0,23,7,4,0,24,7,4,0,25,7,4,0,26,7,7,0,27,7,-26,0,4,0,-26, -0,0,0,-26,0,1,0,12,0,28,7,-29,0,29,7,-25,0,6,0,12,0,30,7,12,0,17,7,12,0,31,7,2, -0,20,0,2,0,37,0,4,0,57,0,-24,0,4,0,7,0,32,7,7,0,112,0,2,0,33,7,2,0,34,7,-23, -0,6,0,7,0,35,7,7,0,36,7,7,0,37,7,7,0,38,7,4,0,39,7,4,0,40,7,-22,0,12,0,7, -0,41,7,7,0,42,7,7,0,43,7,7,0,44,7,7,0,45,7,7,0,46,7,7,0,47,7,7,0,48,7,7, -0,49,7,7,0,50,7,4,0,-110,2,4,0,51,7,-21,0,2,0,7,0,-55,4,7,0,37,0,-20,0,7,0,7, -0,52,7,7,0,53,7,4,0,93,0,4,0,108,2,4,0,54,7,4,0,55,7,4,0,37,0,-19,0,6,0,-19, -0,0,0,-19,0,1,0,2,0,18,0,2,0,20,0,2,0,56,7,2,0,57,0,-18,0,8,0,-18,0,0,0,-18, -0,1,0,2,0,18,0,2,0,20,0,2,0,56,7,2,0,57,0,7,0,23,0,7,0,-126,0,-17,0,45,0,-17, -0,0,0,-17,0,1,0,2,0,18,0,2,0,20,0,2,0,56,7,2,0,-43,0,2,0,-103,3,2,0,57,7,7, -0,58,7,7,0,92,0,7,0,-97,2,4,0,59,7,4,0,81,0,4,0,110,2,7,0,60,7,7,0,61,7,7, -0,62,7,7,0,63,7,7,0,64,7,7,0,65,7,7,0,-100,2,7,0,-1,0,7,0,66,7,7,0,67,7,7, -0,37,0,7,0,68,7,7,0,69,7,7,0,70,7,2,0,71,7,2,0,72,7,2,0,73,7,2,0,74,7,2, -0,75,7,2,0,76,7,2,0,77,7,2,0,78,7,2,0,123,5,2,0,79,7,2,0,-47,1,2,0,80,7,0, -0,81,7,0,0,82,7,7,0,-45,0,-16,0,83,7,63,0,-95,1,-15,0,16,0,-15,0,0,0,-15,0,1,0,2, -0,18,0,2,0,20,0,2,0,56,7,2,0,-43,0,7,0,-105,2,7,0,-104,2,7,0,-103,2,7,0,-5,1,7, -0,-102,2,7,0,-101,2,7,0,84,7,7,0,-100,2,7,0,-98,2,7,0,-97,2,-59,0,5,0,2,0,18,0,2, -0,-25,6,2,0,20,0,2,0,85,7,27,0,-9,5,-60,0,3,0,4,0,69,0,4,0,86,7,-59,0,2,0,-14, -0,12,0,-14,0,0,0,-14,0,1,0,2,0,18,0,2,0,20,0,2,0,31,3,2,0,-32,1,7,0,5,0,7, -0,6,0,7,0,87,7,7,0,88,7,27,0,-9,5,12,0,89,7,-13,0,11,0,-13,0,0,0,-13,0,1,0,0, -0,17,0,2,0,18,0,2,0,90,7,4,0,22,0,4,0,91,7,2,0,20,0,2,0,37,0,9,0,92,7,9, -0,93,7,-12,0,5,0,0,0,17,0,7,0,20,1,7,0,94,7,4,0,95,7,4,0,37,0,-11,0,4,0,2, -0,18,0,2,0,20,0,2,0,43,0,2,0,70,0,-10,0,4,0,0,0,17,0,62,0,96,7,7,0,20,1,7, -0,37,0,-9,0,6,0,2,0,97,7,2,0,98,7,2,0,18,0,2,0,99,7,0,0,100,7,0,0,101,7,-8, -0,5,0,4,0,18,0,4,0,37,0,0,0,17,0,0,0,102,7,0,0,103,7,-7,0,3,0,4,0,18,0,4, -0,37,0,0,0,17,0,-6,0,4,0,2,0,104,7,2,0,105,7,2,0,20,0,2,0,37,0,-5,0,6,0,0, -0,17,0,0,0,106,7,2,0,107,7,2,0,-100,2,2,0,13,1,2,0,70,0,-4,0,5,0,0,0,17,0,7, -0,112,0,7,0,-17,3,2,0,20,0,2,0,122,2,-3,0,3,0,0,0,17,0,4,0,110,2,4,0,104,7,-2, -0,7,0,0,0,17,0,7,0,-17,3,0,0,108,7,0,0,109,7,2,0,13,1,2,0,43,0,4,0,110,7,-1, -0,3,0,32,0,111,7,0,0,112,7,0,0,113,7,0,1,18,0,0,1,0,0,0,1,1,0,2,0,18,0,2, -0,90,7,2,0,20,0,2,0,114,7,2,0,115,7,2,0,116,7,2,0,43,0,2,0,70,0,0,0,17,0,9, -0,2,0,1,1,117,7,32,0,45,0,2,0,-47,4,2,0,20,7,2,0,118,7,2,0,37,0,2,1,11,0,0, -0,17,0,0,0,18,0,0,0,119,7,2,0,20,0,2,0,122,2,2,0,120,7,4,0,121,7,4,0,122,7,4, -0,123,7,4,0,124,7,4,0,125,7,3,1,1,0,0,0,126,7,4,1,4,0,42,0,-36,5,0,0,127,7,4, -0,13,1,4,0,20,0,1,1,18,0,1,1,0,0,1,1,1,0,1,1,-128,7,2,0,18,0,2,0,20,0,2, -0,-127,7,2,0,116,7,2,0,90,7,2,0,-126,7,2,0,70,0,2,0,12,1,0,0,17,0,9,0,2,0,5, -1,117,7,0,1,-125,7,2,0,15,0,2,0,-124,7,4,0,-123,7,6,1,3,0,4,0,-74,2,4,0,37,0,32, -0,45,0,7,1,12,0,-111,0,-122,7,2,0,18,0,2,0,20,0,4,0,58,7,4,0,92,0,0,0,17,0,0, -0,-121,7,2,0,-120,7,2,0,-119,7,2,0,-118,7,2,0,-117,7,7,0,-116,7,8,1,10,0,2,0,20,0,2, -0,-115,7,4,0,58,7,4,0,92,0,2,0,-114,7,-28,0,18,7,2,0,18,0,2,0,-113,7,2,0,-112,7,2, -0,-111,7,9,1,7,0,2,0,20,0,2,0,-115,7,4,0,58,7,4,0,92,0,2,0,18,0,2,0,-110,7,7, -0,109,3,10,1,11,0,4,0,-74,2,2,0,18,0,2,0,20,0,32,0,45,0,74,0,-109,7,0,0,17,0,7, -0,-108,7,7,0,-107,7,7,0,21,3,2,0,-106,7,2,0,-105,7,11,1,5,0,2,0,18,0,2,0,20,0,4, -0,37,0,-79,0,-89,6,32,0,39,5,12,1,5,0,4,0,20,0,4,0,18,0,0,0,17,0,0,0,102,7,32, -0,45,0,13,1,13,0,2,0,20,0,2,0,18,0,2,0,90,7,2,0,22,3,7,0,-104,7,7,0,-103,7,7, -0,7,1,7,0,8,1,7,0,-3,2,7,0,0,3,7,0,-102,7,7,0,-101,7,32,0,-100,7,14,1,10,0,2, -0,20,0,2,0,18,0,4,0,58,7,4,0,92,0,0,0,17,0,0,0,-121,7,2,0,43,0,2,0,64,0,2, -0,-99,7,2,0,-98,7,15,1,8,0,32,0,45,0,7,0,-103,2,7,0,-97,7,7,0,-96,7,7,0,-108,2,2, -0,20,0,2,0,122,2,7,0,-95,7,16,1,12,0,2,0,18,0,2,0,13,1,2,0,20,0,2,0,-100,2,2, -0,-74,2,2,0,-94,7,4,0,37,0,7,0,-93,7,7,0,-92,7,7,0,-91,7,7,0,-90,7,0,0,-89,7,17, -1,10,0,2,0,20,0,2,0,18,0,4,0,58,7,4,0,92,0,0,0,17,0,2,0,68,2,2,0,64,0,2, -0,-99,7,2,0,-98,7,63,0,-95,1,18,1,7,0,4,0,110,2,4,0,-88,7,4,0,-87,7,4,0,-86,7,7, -0,-85,7,7,0,-84,7,0,0,108,7,19,1,7,0,0,0,-83,7,32,0,-82,7,0,0,112,7,2,0,-81,7,2, -0,43,0,4,0,70,0,0,0,113,7,20,1,6,0,2,0,20,0,2,0,18,0,4,0,58,7,4,0,92,0,0, -0,-80,7,0,0,-79,7,21,1,1,0,4,0,20,0,22,1,6,0,0,0,95,0,2,0,18,0,2,0,20,0,4, -0,-78,7,7,0,-77,7,42,0,-36,5,23,1,4,0,0,0,-74,0,2,0,20,0,4,0,18,0,32,0,45,0,24, -1,2,0,4,0,18,0,4,0,-121,5,5,1,10,0,5,1,0,0,5,1,1,0,5,1,-128,7,2,0,18,0,2, -0,20,0,2,0,90,7,2,0,-76,7,0,0,17,0,9,0,2,0,32,0,45,0,25,1,10,0,7,0,21,3,7, -0,-75,7,7,0,-74,7,7,0,-73,7,7,0,-72,7,4,0,20,0,7,0,-94,7,7,0,-71,7,7,0,-70,7,7, -0,37,0,-28,0,20,0,27,0,31,0,0,0,-63,0,26,1,-69,7,9,0,-68,7,43,0,-104,0,43,0,-67,7,9, -0,-66,7,36,0,79,0,7,0,109,3,7,0,-65,7,7,0,-64,7,7,0,-63,7,7,0,-62,7,7,0,-61,7,7, -0,-60,7,4,0,93,0,4,0,-59,7,0,0,-58,7,0,0,-57,7,0,0,-56,7,27,1,6,0,27,0,31,0,7, -0,-55,7,7,0,-54,7,7,0,-53,7,2,0,-52,7,2,0,-51,7,28,1,14,0,-75,0,0,0,-75,0,1,0,4, -0,75,5,7,0,76,5,-74,0,77,5,-69,0,-108,5,-28,0,18,7,2,0,13,1,2,0,-115,7,2,0,8,2,2, -0,9,2,2,0,20,0,2,0,-98,5,4,0,70,0,29,1,6,0,29,1,0,0,29,1,1,0,32,0,45,0,9, -0,-50,7,4,0,-38,0,4,0,37,0,63,0,4,0,27,0,31,0,12,0,-49,7,4,0,-121,0,7,0,-48,7,30, -1,25,0,30,1,0,0,30,1,1,0,30,1,38,0,12,0,-47,7,0,0,17,0,7,0,-46,7,7,0,-45,7,7, -0,-44,7,7,0,-43,7,4,0,20,0,7,0,-42,7,7,0,-41,7,7,0,-40,7,7,0,20,1,7,0,-39,1,7, -0,-39,7,7,0,108,2,7,0,-38,7,7,0,-37,7,7,0,-36,7,7,0,-35,7,7,0,-34,7,7,0,-81,0,2, -0,-121,0,2,0,-31,4,31,1,19,0,27,0,31,0,12,0,-33,7,12,0,-32,7,4,0,20,0,4,0,30,4,2, -0,-96,2,2,0,-31,7,2,0,-121,0,2,0,-30,7,2,0,-29,7,2,0,-28,7,2,0,-27,7,2,0,-26,7,4, -0,-25,7,4,0,-24,7,4,0,-23,7,4,0,-22,7,4,0,-21,7,4,0,-20,7,32,1,34,0,32,1,0,0,32, -1,1,0,12,0,49,3,0,0,17,0,2,0,20,0,2,0,-19,7,2,0,-18,7,2,0,-17,7,2,0,10,3,2, -0,-16,7,4,0,-7,1,4,0,-23,7,4,0,-22,7,30,1,-15,7,32,1,38,0,32,1,-14,7,12,0,-13,7,9, -0,-12,7,9,0,-11,7,9,0,-10,7,7,0,7,1,7,0,-81,0,7,0,-57,1,7,0,-9,7,7,0,-8,7,7, -0,2,3,7,0,-7,7,7,0,-6,7,7,0,-5,7,7,0,-4,7,7,0,-3,7,7,0,-2,7,7,0,-10,1,32, -0,-1,7,-110,0,9,0,12,0,0,8,2,0,20,0,2,0,1,8,7,0,20,3,7,0,2,8,7,0,3,8,12, -0,4,8,4,0,5,8,4,0,37,0,33,1,7,0,33,1,0,0,33,1,1,0,12,0,-58,7,4,0,20,0,4, -0,6,8,0,0,17,0,-47,0,7,8,34,1,8,0,34,1,0,0,34,1,1,0,33,1,8,8,36,0,79,0,12, -0,-6,2,4,0,20,0,0,0,17,0,4,0,9,8,-111,0,6,0,27,0,31,0,12,0,0,8,12,0,10,8,12, -0,103,0,4,0,11,8,4,0,37,0,35,1,16,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74, -0,77,5,2,0,78,5,-69,0,-108,5,-111,0,-9,2,0,0,13,1,0,0,-37,5,2,0,20,0,2,0,12,8,2, -0,-101,5,2,0,-98,5,2,0,13,8,7,0,14,8,36,1,5,0,36,1,0,0,36,1,1,0,36,0,79,0,2, -0,20,0,0,0,15,8,37,1,12,0,37,1,0,0,37,1,1,0,9,0,2,0,2,0,18,0,2,0,20,0,0, -0,16,8,0,0,17,8,0,0,15,8,7,0,18,8,7,0,19,8,4,0,37,0,36,0,79,0,38,1,9,0,38, -1,0,0,38,1,1,0,32,0,20,8,0,0,21,8,7,0,22,8,2,0,23,8,2,0,20,0,2,0,18,0,2, -0,37,0,39,1,7,0,42,0,-36,5,26,0,24,8,4,0,20,0,4,0,25,8,12,0,26,8,32,0,20,8,0, -0,21,8,40,1,12,0,32,0,20,8,2,0,27,8,2,0,20,0,2,0,28,8,2,0,29,8,0,0,21,8,32, -0,30,8,0,0,31,8,7,0,32,8,7,0,-39,1,7,0,33,8,7,0,34,8,41,1,6,0,32,0,20,8,4, -0,9,8,4,0,35,8,4,0,93,0,4,0,37,0,0,0,21,8,42,1,4,0,32,0,20,8,4,0,20,0,4, -0,9,8,0,0,21,8,43,1,4,0,32,0,20,8,4,0,20,0,4,0,9,8,0,0,21,8,44,1,10,0,32, -0,20,8,4,0,36,8,7,0,-127,0,4,0,20,0,2,0,-42,5,2,0,37,8,2,0,43,0,2,0,70,0,7, -0,38,8,0,0,21,8,45,1,4,0,32,0,20,8,4,0,20,0,4,0,9,8,0,0,21,8,46,1,10,0,32, -0,20,8,2,0,18,0,2,0,-95,3,4,0,91,0,4,0,92,0,7,0,-97,7,7,0,-96,7,4,0,37,0,-111, -0,-122,7,0,0,21,8,47,1,4,0,32,0,20,8,4,0,7,3,4,0,39,8,0,0,21,8,48,1,5,0,32, -0,20,8,7,0,-127,0,4,0,40,8,4,0,7,3,4,0,8,3,49,1,6,0,32,0,20,8,4,0,41,8,4, -0,42,8,7,0,43,8,7,0,44,8,0,0,21,8,50,1,16,0,32,0,20,8,32,0,-14,7,4,0,18,0,7, -0,45,8,7,0,46,8,7,0,47,8,7,0,48,8,7,0,49,8,7,0,50,8,7,0,51,8,7,0,52,8,7, -0,53,8,2,0,20,0,2,0,37,0,2,0,43,0,2,0,70,0,51,1,3,0,32,0,20,8,4,0,20,0,4, -0,123,5,52,1,5,0,32,0,20,8,4,0,20,0,4,0,37,0,7,0,54,8,0,0,21,8,53,1,10,0,32, -0,20,8,0,0,21,8,2,0,55,8,2,0,56,8,0,0,57,8,0,0,58,8,7,0,59,8,7,0,60,8,7, -0,61,8,7,0,62,8,54,1,8,0,7,0,9,0,7,0,10,0,7,0,11,0,7,0,12,0,7,0,63,8,7, -0,64,8,2,0,20,0,2,0,123,5,55,1,8,0,7,0,9,0,7,0,10,0,7,0,11,0,7,0,12,0,7, -0,63,8,7,0,64,8,2,0,20,0,2,0,123,5,56,1,8,0,7,0,9,0,7,0,10,0,7,0,11,0,7, -0,12,0,7,0,63,8,7,0,64,8,2,0,20,0,2,0,123,5,57,1,7,0,32,0,20,8,0,0,21,8,7, -0,20,1,7,0,30,1,2,0,20,0,2,0,13,1,4,0,37,0,58,1,5,0,32,0,-45,2,7,0,20,1,2, -0,-41,2,0,0,-39,2,0,0,65,8,59,1,10,0,59,1,0,0,59,1,1,0,2,0,18,0,2,0,20,0,0, -0,66,8,7,0,-36,0,7,0,-35,0,2,0,-58,7,2,0,67,8,32,0,45,0,60,1,22,0,60,1,0,0,60, -1,1,0,2,0,20,0,2,0,13,1,2,0,68,8,2,0,69,8,36,0,79,0,-111,0,-122,7,32,0,-89,0,7, -0,91,0,7,0,92,0,7,0,70,8,7,0,71,8,7,0,72,8,7,0,73,8,7,0,-107,2,7,0,-67,1,7, -0,-120,7,7,0,74,8,0,0,75,8,0,0,76,8,12,0,-4,2,61,1,8,0,7,0,-31,1,7,0,-97,7,7, -0,-96,7,9,0,2,0,2,0,77,8,2,0,78,8,2,0,79,8,2,0,80,8,62,1,18,0,62,1,0,0,62, -1,1,0,62,1,81,8,0,0,17,0,61,1,82,8,2,0,18,0,2,0,20,0,2,0,83,8,2,0,84,8,2, -0,85,8,2,0,86,8,4,0,43,0,7,0,87,8,7,0,88,8,4,0,89,8,4,0,90,8,62,1,91,8,63, -1,92,8,64,1,32,0,64,1,0,0,64,1,1,0,64,1,93,8,0,0,17,0,0,0,94,8,2,0,18,0,2, -0,20,0,2,0,-14,6,2,0,20,7,2,0,95,8,2,0,-119,0,2,0,84,8,2,0,-25,6,12,0,-127,7,12, -0,96,8,27,0,-9,5,9,0,97,8,7,0,87,8,7,0,88,8,7,0,-5,1,7,0,98,8,2,0,99,8,2, -0,100,8,7,0,101,8,7,0,102,8,2,0,103,8,2,0,104,8,24,0,105,8,24,0,106,8,24,0,107,8,65, -1,-103,0,66,1,108,8,63,1,6,0,63,1,0,0,63,1,1,0,64,1,109,8,64,1,110,8,62,1,111,8,62, -1,91,8,57,0,16,0,27,0,31,0,12,0,112,8,12,0,113,8,61,1,114,8,12,0,115,8,4,0,18,0,4, -0,116,8,4,0,117,8,4,0,118,8,12,0,119,8,66,1,120,8,62,1,121,8,62,1,122,8,9,0,123,8,9, -0,124,8,4,0,125,8,67,1,6,0,4,0,-128,0,4,0,-126,0,4,0,-25,6,0,0,126,8,0,0,127,8,2, -0,37,0,68,1,16,0,2,0,-86,6,2,0,-85,6,2,0,-128,8,2,0,-74,7,2,0,-127,8,2,0,68,0,7, -0,-108,2,7,0,-126,8,7,0,-125,8,2,0,34,1,0,0,-124,8,0,0,42,4,2,0,-123,8,2,0,37,0,4, -0,-122,8,4,0,-121,8,69,1,9,0,7,0,-120,8,7,0,-119,8,7,0,-60,7,7,0,112,0,7,0,-118,8,7, -0,71,5,2,0,-117,8,0,0,-116,8,0,0,37,0,70,1,4,0,7,0,-115,8,7,0,-114,8,2,0,-117,8,2, -0,37,0,71,1,3,0,7,0,-113,8,7,0,-112,8,7,0,15,0,72,1,7,0,0,0,-68,1,2,0,109,4,2, -0,110,4,2,0,111,4,2,0,62,4,4,0,-126,0,4,0,-97,3,73,1,7,0,7,0,-111,8,7,0,-110,8,7, -0,-109,8,7,0,4,2,7,0,-108,8,7,0,-107,8,7,0,-106,8,74,1,4,0,2,0,-105,8,2,0,-104,8,2, -0,-103,8,2,0,-102,8,75,1,2,0,7,0,5,0,7,0,6,0,76,1,2,0,0,0,-87,0,0,0,-101,8,77, -1,1,0,0,0,17,0,78,1,10,0,0,0,-100,8,0,0,-99,8,0,0,-98,8,0,0,-97,8,2,0,-128,8,2, -0,-96,8,7,0,-95,8,7,0,-94,8,7,0,-93,8,7,0,-67,1,79,1,2,0,9,0,-92,8,9,0,-91,8,80, -1,11,0,0,0,111,4,0,0,18,0,0,0,-117,8,0,0,112,0,0,0,-90,8,0,0,109,0,0,0,-74,0,7, -0,-89,8,7,0,-88,8,7,0,-87,8,7,0,-86,8,81,1,8,0,7,0,97,7,7,0,-127,0,7,0,42,4,7, -0,72,2,7,0,-85,8,7,0,-49,0,7,0,-84,8,4,0,18,0,82,1,4,0,2,0,-83,8,2,0,-82,8,2, -0,-81,8,2,0,37,0,83,1,1,0,0,0,17,0,84,1,4,0,7,0,5,0,7,0,6,0,2,0,20,0,2, -0,-80,8,85,1,10,0,2,0,-120,3,2,0,20,0,7,0,-17,3,7,0,-79,8,7,0,-78,8,7,0,-77,8,7, -0,-76,8,84,1,-75,8,84,1,-74,8,84,1,-73,8,60,0,9,0,4,0,20,0,4,0,64,0,24,0,-72,8,24, -0,-71,8,85,1,-70,8,7,0,-69,8,7,0,-68,8,7,0,-67,8,7,0,-66,8,86,1,4,0,46,0,-114,2,7, -0,-65,8,7,0,92,1,7,0,37,0,-87,0,13,0,27,0,31,0,2,0,20,0,2,0,72,5,4,0,109,0,7, -0,-64,8,7,0,1,2,7,0,-63,8,7,0,-62,8,7,0,92,1,2,0,47,1,2,0,37,0,50,0,77,1,86, -1,-61,8,87,1,10,0,4,0,18,0,4,0,-127,0,4,0,20,0,4,0,70,3,4,0,-60,8,4,0,-59,8,4, -0,-58,8,0,0,95,0,0,0,17,0,9,0,2,0,84,0,6,0,87,1,-57,8,4,0,-56,8,4,0,-55,8,4, -0,-54,8,4,0,37,0,9,0,-53,8,88,1,5,0,7,0,66,2,7,0,-74,2,7,0,-39,1,2,0,-52,8,2, -0,37,0,89,1,5,0,7,0,66,2,7,0,-51,8,7,0,-50,8,7,0,-49,8,7,0,-74,2,90,1,7,0,4, -0,-48,8,4,0,-47,8,4,0,-46,8,7,0,-45,8,7,0,-44,8,7,0,-43,8,7,0,-42,8,91,1,26,0,32, -0,-41,8,89,1,66,3,89,1,-40,8,88,1,-39,8,89,1,83,7,7,0,-38,8,7,0,-37,8,7,0,-36,8,7, -0,-35,8,7,0,-44,8,7,0,-43,8,7,0,-74,2,7,0,-97,2,7,0,-34,8,7,0,-33,8,7,0,109,0,7, -0,-32,8,4,0,-48,8,4,0,-31,8,4,0,37,0,4,0,81,0,4,0,-30,8,2,0,20,0,2,0,-29,8,2, -0,-28,8,2,0,100,3,92,1,112,0,27,0,31,0,4,0,20,0,2,0,18,0,2,0,55,8,2,0,-27,8,2, -0,-26,8,2,0,-25,8,2,0,-24,8,2,0,-23,8,2,0,-22,8,2,0,-21,8,2,0,-20,8,2,0,-19,8,2, -0,-18,8,2,0,-17,8,2,0,-16,8,2,0,-15,8,2,0,-14,8,2,0,-13,8,2,0,-47,1,2,0,76,7,2, -0,51,7,2,0,-12,8,2,0,-11,8,2,0,98,3,2,0,99,3,2,0,-10,8,2,0,-9,8,2,0,-8,8,2, -0,-7,8,2,0,-6,8,2,0,-5,8,7,0,-4,8,7,0,-3,8,7,0,-2,8,2,0,-1,8,2,0,0,9,7, -0,1,9,7,0,2,9,7,0,3,9,7,0,58,7,7,0,92,0,7,0,-97,2,7,0,64,7,7,0,4,9,7, -0,5,9,7,0,6,9,7,0,7,9,7,0,57,0,4,0,59,7,4,0,57,7,4,0,8,9,7,0,60,7,7, -0,61,7,7,0,62,7,7,0,9,9,7,0,10,9,7,0,11,9,7,0,12,9,7,0,13,9,7,0,14,9,7, -0,15,9,7,0,16,9,7,0,21,3,7,0,109,0,7,0,17,9,7,0,18,9,7,0,19,9,7,0,20,9,7, -0,21,9,7,0,22,9,7,0,108,2,7,0,23,9,7,0,24,9,4,0,25,9,4,0,26,9,7,0,27,9,7, -0,28,9,7,0,29,9,7,0,30,9,7,0,31,9,7,0,32,9,7,0,33,9,7,0,34,9,7,0,94,3,7, -0,92,3,7,0,93,3,7,0,35,9,7,0,36,9,7,0,37,9,7,0,38,9,7,0,39,9,7,0,40,9,7, -0,41,9,7,0,42,9,7,0,43,9,7,0,28,3,7,0,44,9,7,0,45,9,7,0,46,9,7,0,47,9,7, -0,48,9,7,0,49,9,7,0,50,9,0,0,51,9,63,0,55,3,63,0,52,9,32,0,53,9,32,0,54,9,36, -0,79,0,-108,0,53,3,-108,0,55,9,-120,0,37,0,-120,0,0,0,-120,0,1,0,92,1,56,9,91,1,-121,3,90, -1,-14,7,93,1,57,9,94,1,58,9,94,1,59,9,12,0,60,9,12,0,61,9,-107,0,54,3,32,0,62,9,32, -0,63,9,32,0,64,9,12,0,65,9,12,0,66,9,7,0,-45,0,7,0,83,4,4,0,110,2,4,0,20,0,4, -0,59,7,4,0,67,9,4,0,68,9,4,0,69,9,4,0,57,0,2,0,-38,0,2,0,70,9,2,0,71,9,2, -0,72,9,2,0,47,3,2,0,73,9,0,0,74,9,2,0,75,9,2,0,76,9,2,0,77,9,9,0,78,9,125, -0,-76,3,123,0,34,0,95,1,79,9,7,0,-106,3,7,0,80,9,7,0,81,9,7,0,-14,3,7,0,82,9,7, -0,31,3,7,0,21,3,7,0,83,9,7,0,3,2,7,0,84,9,7,0,85,9,7,0,86,9,7,0,87,9,7, -0,88,9,7,0,89,9,7,0,-105,3,7,0,90,9,7,0,91,9,7,0,92,9,7,0,-104,3,7,0,-108,3,7, -0,-107,3,4,0,93,9,4,0,93,0,4,0,94,9,4,0,95,9,2,0,96,9,2,0,97,9,2,0,98,9,2, -0,99,9,2,0,100,9,2,0,37,0,4,0,70,0,124,0,8,0,95,1,101,9,7,0,102,9,7,0,103,9,7, -0,-94,1,7,0,104,9,4,0,93,0,2,0,105,9,2,0,106,9,96,1,4,0,7,0,5,0,7,0,6,0,7, -0,7,0,7,0,107,9,97,1,6,0,97,1,0,0,97,1,1,0,96,1,108,9,4,0,109,9,2,0,110,9,2, -0,20,0,98,1,5,0,98,1,0,0,98,1,1,0,12,0,111,9,4,0,112,9,4,0,20,0,99,1,9,0,99, -1,0,0,99,1,1,0,12,0,-128,0,98,1,113,9,4,0,20,0,2,0,110,9,2,0,114,9,7,0,94,0,0, -0,115,9,-70,0,5,0,12,0,125,4,4,0,20,0,2,0,116,9,2,0,117,9,9,0,118,9,69,78,68,66,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -}; -int DNAlen64= sizeof(DNAstr64); +unsigned char DNAstr64[] = { + 83, 68, 78, 65, 78, 65, 77, 69, 119, 9, 0, 0, 42, 110, 101, 120, 116, 0, 42, 112, 114, 101, 118, 0, 42, 100, 97, 116, 97, 0, 42, 102, 105, + 114, 115, 116, 0, 42, 108, 97, 115, 116, 0, 120, 0, 121, 0, 122, 0, 119, 0, 120, 109, 105, 110, 0, 120, 109, 97, 120, 0, 121, 109, 105, 110, + 0, 121, 109, 97, 120, 0, 42, 112, 111, 105, 110, 116, 101, 114, 0, 103, 114, 111, 117, 112, 0, 118, 97, 108, 0, 118, 97, 108, 50, 0, 110, 97, + 109, 101, 91, 51, 50, 93, 0, 116, 121, 112, 101, 0, 115, 117, 98, 116, 121, 112, 101, 0, 102, 108, 97, 103, 0, 115, 97, 118, 101, 100, 0, 100, + 97, 116, 97, 0, 108, 101, 110, 0, 116, 111, 116, 97, 108, 108, 101, 110, 0, 42, 110, 101, 119, 105, 100, 0, 42, 108, 105, 98, 0, 110, 97, 109, + 101, 91, 50, 52, 93, 0, 117, 115, 0, 105, 99, 111, 110, 95, 105, 100, 0, 42, 112, 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 105, 100, 0, + 42, 105, 100, 98, 108, 111, 99, 107, 0, 42, 102, 105, 108, 101, 100, 97, 116, 97, 0, 110, 97, 109, 101, 91, 50, 52, 48, 93, 0, 102, 105, 108, + 101, 110, 97, 109, 101, 91, 50, 52, 48, 93, 0, 116, 111, 116, 0, 112, 97, 100, 0, 42, 112, 97, 114, 101, 110, 116, 0, 119, 91, 50, 93, 0, + 104, 91, 50, 93, 0, 99, 104, 97, 110, 103, 101, 100, 91, 50, 93, 0, 112, 97, 100, 48, 0, 112, 97, 100, 49, 0, 42, 114, 101, 99, 116, 91, + 50, 93, 0, 42, 111, 98, 0, 98, 108, 111, 99, 107, 116, 121, 112, 101, 0, 97, 100, 114, 99, 111, 100, 101, 0, 110, 97, 109, 101, 91, 49, 50, + 56, 93, 0, 42, 98, 112, 0, 42, 98, 101, 122, 116, 0, 109, 97, 120, 114, 99, 116, 0, 116, 111, 116, 114, 99, 116, 0, 118, 97, 114, 116, 121, + 112, 101, 0, 116, 111, 116, 118, 101, 114, 116, 0, 105, 112, 111, 0, 101, 120, 116, 114, 97, 112, 0, 114, 116, 0, 98, 105, 116, 109, 97, 115, 107, + 0, 115, 108, 105, 100, 101, 95, 109, 105, 110, 0, 115, 108, 105, 100, 101, 95, 109, 97, 120, 0, 99, 117, 114, 118, 97, 108, 0, 42, 100, 114, 105, + 118, 101, 114, 0, 99, 117, 114, 118, 101, 0, 99, 117, 114, 0, 115, 104, 111, 119, 107, 101, 121, 0, 109, 117, 116, 101, 105, 112, 111, 0, 112, 111, + 115, 0, 114, 101, 108, 97, 116, 105, 118, 101, 0, 116, 111, 116, 101, 108, 101, 109, 0, 112, 97, 100, 50, 0, 42, 119, 101, 105, 103, 104, 116, 115, + 0, 118, 103, 114, 111, 117, 112, 91, 51, 50, 93, 0, 115, 108, 105, 100, 101, 114, 109, 105, 110, 0, 115, 108, 105, 100, 101, 114, 109, 97, 120, 0, + 42, 114, 101, 102, 107, 101, 121, 0, 101, 108, 101, 109, 115, 116, 114, 91, 51, 50, 93, 0, 101, 108, 101, 109, 115, 105, 122, 101, 0, 98, 108, 111, + 99, 107, 0, 42, 105, 112, 111, 0, 42, 102, 114, 111, 109, 0, 116, 111, 116, 107, 101, 121, 0, 115, 108, 117, 114, 112, 104, 0, 42, 42, 115, 99, + 114, 105, 112, 116, 115, 0, 42, 102, 108, 97, 103, 0, 97, 99, 116, 115, 99, 114, 105, 112, 116, 0, 116, 111, 116, 115, 99, 114, 105, 112, 116, 0, + 42, 108, 105, 110, 101, 0, 42, 102, 111, 114, 109, 97, 116, 0, 98, 108, 101, 110, 0, 108, 105, 110, 101, 110, 111, 0, 115, 116, 97, 114, 116, 0, + 101, 110, 100, 0, 102, 108, 97, 103, 115, 0, 99, 111, 108, 111, 114, 91, 52, 93, 0, 112, 97, 100, 91, 52, 93, 0, 42, 110, 97, 109, 101, 0, + 110, 108, 105, 110, 101, 115, 0, 108, 105, 110, 101, 115, 0, 42, 99, 117, 114, 108, 0, 42, 115, 101, 108, 108, 0, 99, 117, 114, 99, 0, 115, 101, + 108, 99, 0, 109, 97, 114, 107, 101, 114, 115, 0, 42, 117, 110, 100, 111, 95, 98, 117, 102, 0, 117, 110, 100, 111, 95, 112, 111, 115, 0, 117, 110, + 100, 111, 95, 108, 101, 110, 0, 42, 99, 111, 109, 112, 105, 108, 101, 100, 0, 109, 116, 105, 109, 101, 0, 115, 105, 122, 101, 0, 115, 101, 101, 107, + 0, 112, 97, 115, 115, 101, 112, 97, 114, 116, 97, 108, 112, 104, 97, 0, 97, 110, 103, 108, 101, 0, 99, 108, 105, 112, 115, 116, 97, 0, 99, 108, + 105, 112, 101, 110, 100, 0, 108, 101, 110, 115, 0, 111, 114, 116, 104, 111, 95, 115, 99, 97, 108, 101, 0, 100, 114, 97, 119, 115, 105, 122, 101, 0, + 115, 104, 105, 102, 116, 120, 0, 115, 104, 105, 102, 116, 121, 0, 89, 70, 95, 100, 111, 102, 100, 105, 115, 116, 0, 89, 70, 95, 97, 112, 101, 114, + 116, 117, 114, 101, 0, 89, 70, 95, 98, 107, 104, 116, 121, 112, 101, 0, 89, 70, 95, 98, 107, 104, 98, 105, 97, 115, 0, 89, 70, 95, 98, 107, + 104, 114, 111, 116, 0, 115, 99, 114, 105, 112, 116, 108, 105, 110, 107, 0, 42, 100, 111, 102, 95, 111, 98, 0, 102, 114, 97, 109, 101, 110, 114, 0, + 102, 114, 97, 109, 101, 115, 0, 111, 102, 102, 115, 101, 116, 0, 115, 102, 114, 97, 0, 102, 105, 101, 95, 105, 109, 97, 0, 99, 121, 99, 108, 0, + 111, 107, 0, 109, 117, 108, 116, 105, 95, 105, 110, 100, 101, 120, 0, 108, 97, 121, 101, 114, 0, 112, 97, 115, 115, 0, 109, 101, 110, 117, 110, 114, + 0, 105, 98, 117, 102, 115, 0, 42, 103, 112, 117, 116, 101, 120, 116, 117, 114, 101, 0, 42, 97, 110, 105, 109, 0, 42, 114, 114, 0, 115, 111, 117, + 114, 99, 101, 0, 108, 97, 115, 116, 102, 114, 97, 109, 101, 0, 116, 112, 97, 103, 101, 102, 108, 97, 103, 0, 116, 111, 116, 98, 105, 110, 100, 0, + 120, 114, 101, 112, 0, 121, 114, 101, 112, 0, 116, 119, 115, 116, 97, 0, 116, 119, 101, 110, 100, 0, 98, 105, 110, 100, 99, 111, 100, 101, 0, 42, + 114, 101, 112, 98, 105, 110, 100, 0, 42, 112, 97, 99, 107, 101, 100, 102, 105, 108, 101, 0, 42, 112, 114, 101, 118, 105, 101, 119, 0, 108, 97, 115, + 116, 117, 112, 100, 97, 116, 101, 0, 108, 97, 115, 116, 117, 115, 101, 100, 0, 97, 110, 105, 109, 115, 112, 101, 101, 100, 0, 103, 101, 110, 95, 120, + 0, 103, 101, 110, 95, 121, 0, 103, 101, 110, 95, 116, 121, 112, 101, 0, 97, 115, 112, 120, 0, 97, 115, 112, 121, 0, 42, 118, 110, 111, 100, 101, + 0, 116, 101, 120, 99, 111, 0, 109, 97, 112, 116, 111, 0, 109, 97, 112, 116, 111, 110, 101, 103, 0, 98, 108, 101, 110, 100, 116, 121, 112, 101, 0, + 42, 111, 98, 106, 101, 99, 116, 0, 42, 116, 101, 120, 0, 117, 118, 110, 97, 109, 101, 91, 51, 50, 93, 0, 112, 114, 111, 106, 120, 0, 112, 114, + 111, 106, 121, 0, 112, 114, 111, 106, 122, 0, 109, 97, 112, 112, 105, 110, 103, 0, 111, 102, 115, 91, 51, 93, 0, 115, 105, 122, 101, 91, 51, 93, + 0, 116, 101, 120, 102, 108, 97, 103, 0, 99, 111, 108, 111, 114, 109, 111, 100, 101, 108, 0, 112, 109, 97, 112, 116, 111, 0, 112, 109, 97, 112, 116, + 111, 110, 101, 103, 0, 110, 111, 114, 109, 97, 112, 115, 112, 97, 99, 101, 0, 119, 104, 105, 99, 104, 95, 111, 117, 116, 112, 117, 116, 0, 112, 97, + 100, 91, 50, 93, 0, 114, 0, 103, 0, 98, 0, 107, 0, 100, 101, 102, 95, 118, 97, 114, 0, 99, 111, 108, 102, 97, 99, 0, 110, 111, 114, 102, + 97, 99, 0, 118, 97, 114, 102, 97, 99, 0, 100, 105, 115, 112, 102, 97, 99, 0, 119, 97, 114, 112, 102, 97, 99, 0, 110, 97, 109, 101, 91, 49, + 54, 48, 93, 0, 42, 104, 97, 110, 100, 108, 101, 0, 42, 112, 110, 97, 109, 101, 0, 42, 115, 116, 110, 97, 109, 101, 115, 0, 115, 116, 121, 112, + 101, 115, 0, 118, 97, 114, 115, 0, 42, 118, 97, 114, 115, 116, 114, 0, 42, 114, 101, 115, 117, 108, 116, 0, 42, 99, 102, 114, 97, 0, 100, 97, + 116, 97, 91, 51, 50, 93, 0, 40, 42, 100, 111, 105, 116, 41, 40, 41, 0, 40, 42, 105, 110, 115, 116, 97, 110, 99, 101, 95, 105, 110, 105, 116, + 41, 40, 41, 0, 40, 42, 99, 97, 108, 108, 98, 97, 99, 107, 41, 40, 41, 0, 118, 101, 114, 115, 105, 111, 110, 0, 97, 0, 105, 112, 111, 116, + 121, 112, 101, 0, 42, 105, 109, 97, 0, 42, 99, 117, 98, 101, 91, 54, 93, 0, 105, 109, 97, 116, 91, 52, 93, 91, 52, 93, 0, 111, 98, 105, + 109, 97, 116, 91, 51, 93, 91, 51, 93, 0, 115, 116, 121, 112, 101, 0, 118, 105, 101, 119, 115, 99, 97, 108, 101, 0, 110, 111, 116, 108, 97, 121, + 0, 99, 117, 98, 101, 114, 101, 115, 0, 100, 101, 112, 116, 104, 0, 114, 101, 99, 97, 108, 99, 0, 108, 97, 115, 116, 115, 105, 122, 101, 0, 110, + 111, 105, 115, 101, 115, 105, 122, 101, 0, 116, 117, 114, 98, 117, 108, 0, 98, 114, 105, 103, 104, 116, 0, 99, 111, 110, 116, 114, 97, 115, 116, 0, + 114, 102, 97, 99, 0, 103, 102, 97, 99, 0, 98, 102, 97, 99, 0, 102, 105, 108, 116, 101, 114, 115, 105, 122, 101, 0, 109, 103, 95, 72, 0, 109, + 103, 95, 108, 97, 99, 117, 110, 97, 114, 105, 116, 121, 0, 109, 103, 95, 111, 99, 116, 97, 118, 101, 115, 0, 109, 103, 95, 111, 102, 102, 115, 101, + 116, 0, 109, 103, 95, 103, 97, 105, 110, 0, 100, 105, 115, 116, 95, 97, 109, 111, 117, 110, 116, 0, 110, 115, 95, 111, 117, 116, 115, 99, 97, 108, + 101, 0, 118, 110, 95, 119, 49, 0, 118, 110, 95, 119, 50, 0, 118, 110, 95, 119, 51, 0, 118, 110, 95, 119, 52, 0, 118, 110, 95, 109, 101, 120, + 112, 0, 118, 110, 95, 100, 105, 115, 116, 109, 0, 118, 110, 95, 99, 111, 108, 116, 121, 112, 101, 0, 110, 111, 105, 115, 101, 100, 101, 112, 116, 104, + 0, 110, 111, 105, 115, 101, 116, 121, 112, 101, 0, 110, 111, 105, 115, 101, 98, 97, 115, 105, 115, 0, 110, 111, 105, 115, 101, 98, 97, 115, 105, 115, + 50, 0, 105, 109, 97, 102, 108, 97, 103, 0, 99, 114, 111, 112, 120, 109, 105, 110, 0, 99, 114, 111, 112, 121, 109, 105, 110, 0, 99, 114, 111, 112, + 120, 109, 97, 120, 0, 99, 114, 111, 112, 121, 109, 97, 120, 0, 120, 114, 101, 112, 101, 97, 116, 0, 121, 114, 101, 112, 101, 97, 116, 0, 101, 120, + 116, 101, 110, 100, 0, 99, 104, 101, 99, 107, 101, 114, 100, 105, 115, 116, 0, 110, 97, 98, 108, 97, 0, 105, 117, 115, 101, 114, 0, 42, 110, 111, + 100, 101, 116, 114, 101, 101, 0, 42, 112, 108, 117, 103, 105, 110, 0, 42, 99, 111, 98, 97, 0, 42, 101, 110, 118, 0, 117, 115, 101, 95, 110, 111, + 100, 101, 115, 0, 112, 97, 100, 91, 55, 93, 0, 108, 111, 99, 91, 51, 93, 0, 114, 111, 116, 91, 51, 93, 0, 109, 97, 116, 91, 52, 93, 91, + 52, 93, 0, 109, 105, 110, 91, 51, 93, 0, 109, 97, 120, 91, 51, 93, 0, 112, 97, 100, 51, 0, 109, 111, 100, 101, 0, 116, 111, 116, 101, 120, + 0, 115, 104, 100, 119, 114, 0, 115, 104, 100, 119, 103, 0, 115, 104, 100, 119, 98, 0, 115, 104, 100, 119, 112, 97, 100, 0, 101, 110, 101, 114, 103, + 121, 0, 100, 105, 115, 116, 0, 115, 112, 111, 116, 115, 105, 122, 101, 0, 115, 112, 111, 116, 98, 108, 101, 110, 100, 0, 104, 97, 105, 110, 116, 0, + 97, 116, 116, 49, 0, 97, 116, 116, 50, 0, 42, 99, 117, 114, 102, 97, 108, 108, 111, 102, 102, 0, 102, 97, 108, 108, 111, 102, 102, 95, 116, 121, + 112, 101, 0, 115, 104, 97, 100, 115, 112, 111, 116, 115, 105, 122, 101, 0, 98, 105, 97, 115, 0, 115, 111, 102, 116, 0, 98, 117, 102, 115, 105, 122, + 101, 0, 115, 97, 109, 112, 0, 98, 117, 102, 102, 101, 114, 115, 0, 102, 105, 108, 116, 101, 114, 116, 121, 112, 101, 0, 98, 117, 102, 102, 108, 97, + 103, 0, 98, 117, 102, 116, 121, 112, 101, 0, 114, 97, 121, 95, 115, 97, 109, 112, 0, 114, 97, 121, 95, 115, 97, 109, 112, 121, 0, 114, 97, 121, + 95, 115, 97, 109, 112, 122, 0, 114, 97, 121, 95, 115, 97, 109, 112, 95, 116, 121, 112, 101, 0, 97, 114, 101, 97, 95, 115, 104, 97, 112, 101, 0, + 97, 114, 101, 97, 95, 115, 105, 122, 101, 0, 97, 114, 101, 97, 95, 115, 105, 122, 101, 121, 0, 97, 114, 101, 97, 95, 115, 105, 122, 101, 122, 0, + 97, 100, 97, 112, 116, 95, 116, 104, 114, 101, 115, 104, 0, 114, 97, 121, 95, 115, 97, 109, 112, 95, 109, 101, 116, 104, 111, 100, 0, 116, 101, 120, + 97, 99, 116, 0, 115, 104, 97, 100, 104, 97, 108, 111, 115, 116, 101, 112, 0, 115, 117, 110, 95, 101, 102, 102, 101, 99, 116, 95, 116, 121, 112, 101, + 0, 115, 107, 121, 98, 108, 101, 110, 100, 116, 121, 112, 101, 0, 104, 111, 114, 105, 122, 111, 110, 95, 98, 114, 105, 103, 104, 116, 110, 101, 115, 115, + 0, 115, 112, 114, 101, 97, 100, 0, 115, 117, 110, 95, 98, 114, 105, 103, 104, 116, 110, 101, 115, 115, 0, 115, 117, 110, 95, 115, 105, 122, 101, 0, + 98, 97, 99, 107, 115, 99, 97, 116, 116, 101, 114, 101, 100, 95, 108, 105, 103, 104, 116, 0, 115, 117, 110, 95, 105, 110, 116, 101, 110, 115, 105, 116, + 121, 0, 97, 116, 109, 95, 116, 117, 114, 98, 105, 100, 105, 116, 121, 0, 97, 116, 109, 95, 105, 110, 115, 99, 97, 116, 116, 101, 114, 105, 110, 103, + 95, 102, 97, 99, 116, 111, 114, 0, 97, 116, 109, 95, 101, 120, 116, 105, 110, 99, 116, 105, 111, 110, 95, 102, 97, 99, 116, 111, 114, 0, 97, 116, + 109, 95, 100, 105, 115, 116, 97, 110, 99, 101, 95, 102, 97, 99, 116, 111, 114, 0, 115, 107, 121, 98, 108, 101, 110, 100, 102, 97, 99, 0, 115, 107, + 121, 95, 101, 120, 112, 111, 115, 117, 114, 101, 0, 115, 107, 121, 95, 99, 111, 108, 111, 114, 115, 112, 97, 99, 101, 0, 112, 97, 100, 52, 0, 89, + 70, 95, 110, 117, 109, 112, 104, 111, 116, 111, 110, 115, 0, 89, 70, 95, 110, 117, 109, 115, 101, 97, 114, 99, 104, 0, 89, 70, 95, 112, 104, 100, + 101, 112, 116, 104, 0, 89, 70, 95, 117, 115, 101, 113, 109, 99, 0, 89, 70, 95, 98, 117, 102, 115, 105, 122, 101, 0, 89, 70, 95, 112, 97, 100, + 0, 89, 70, 95, 99, 97, 117, 115, 116, 105, 99, 98, 108, 117, 114, 0, 89, 70, 95, 108, 116, 114, 97, 100, 105, 117, 115, 0, 89, 70, 95, 103, + 108, 111, 119, 105, 110, 116, 0, 89, 70, 95, 103, 108, 111, 119, 111, 102, 115, 0, 89, 70, 95, 103, 108, 111, 119, 116, 121, 112, 101, 0, 89, 70, + 95, 112, 97, 100, 50, 0, 42, 109, 116, 101, 120, 91, 49, 56, 93, 0, 115, 112, 101, 99, 114, 0, 115, 112, 101, 99, 103, 0, 115, 112, 101, 99, + 98, 0, 109, 105, 114, 114, 0, 109, 105, 114, 103, 0, 109, 105, 114, 98, 0, 97, 109, 98, 114, 0, 97, 109, 98, 98, 0, 97, 109, 98, 103, 0, + 97, 109, 98, 0, 101, 109, 105, 116, 0, 97, 110, 103, 0, 115, 112, 101, 99, 116, 114, 97, 0, 114, 97, 121, 95, 109, 105, 114, 114, 111, 114, 0, + 97, 108, 112, 104, 97, 0, 114, 101, 102, 0, 115, 112, 101, 99, 0, 122, 111, 102, 102, 115, 0, 97, 100, 100, 0, 116, 114, 97, 110, 115, 108, 117, + 99, 101, 110, 99, 121, 0, 102, 114, 101, 115, 110, 101, 108, 95, 109, 105, 114, 0, 102, 114, 101, 115, 110, 101, 108, 95, 109, 105, 114, 95, 105, 0, + 102, 114, 101, 115, 110, 101, 108, 95, 116, 114, 97, 0, 102, 114, 101, 115, 110, 101, 108, 95, 116, 114, 97, 95, 105, 0, 102, 105, 108, 116, 101, 114, + 0, 116, 120, 95, 108, 105, 109, 105, 116, 0, 116, 120, 95, 102, 97, 108, 108, 111, 102, 102, 0, 114, 97, 121, 95, 100, 101, 112, 116, 104, 0, 114, + 97, 121, 95, 100, 101, 112, 116, 104, 95, 116, 114, 97, 0, 104, 97, 114, 0, 115, 101, 101, 100, 49, 0, 115, 101, 101, 100, 50, 0, 103, 108, 111, + 115, 115, 95, 109, 105, 114, 0, 103, 108, 111, 115, 115, 95, 116, 114, 97, 0, 115, 97, 109, 112, 95, 103, 108, 111, 115, 115, 95, 109, 105, 114, 0, + 115, 97, 109, 112, 95, 103, 108, 111, 115, 115, 95, 116, 114, 97, 0, 97, 100, 97, 112, 116, 95, 116, 104, 114, 101, 115, 104, 95, 109, 105, 114, 0, + 97, 100, 97, 112, 116, 95, 116, 104, 114, 101, 115, 104, 95, 116, 114, 97, 0, 97, 110, 105, 115, 111, 95, 103, 108, 111, 115, 115, 95, 109, 105, 114, + 0, 100, 105, 115, 116, 95, 109, 105, 114, 0, 102, 97, 100, 101, 116, 111, 95, 109, 105, 114, 0, 115, 104, 97, 100, 101, 95, 102, 108, 97, 103, 0, + 109, 111, 100, 101, 95, 108, 0, 102, 108, 97, 114, 101, 99, 0, 115, 116, 97, 114, 99, 0, 108, 105, 110, 101, 99, 0, 114, 105, 110, 103, 99, 0, + 104, 97, 115, 105, 122, 101, 0, 102, 108, 97, 114, 101, 115, 105, 122, 101, 0, 115, 117, 98, 115, 105, 122, 101, 0, 102, 108, 97, 114, 101, 98, 111, + 111, 115, 116, 0, 115, 116, 114, 97, 110, 100, 95, 115, 116, 97, 0, 115, 116, 114, 97, 110, 100, 95, 101, 110, 100, 0, 115, 116, 114, 97, 110, 100, + 95, 101, 97, 115, 101, 0, 115, 116, 114, 97, 110, 100, 95, 115, 117, 114, 102, 110, 111, 114, 0, 115, 116, 114, 97, 110, 100, 95, 109, 105, 110, 0, + 115, 116, 114, 97, 110, 100, 95, 119, 105, 100, 116, 104, 102, 97, 100, 101, 0, 115, 116, 114, 97, 110, 100, 95, 117, 118, 110, 97, 109, 101, 91, 51, + 50, 93, 0, 115, 98, 105, 97, 115, 0, 108, 98, 105, 97, 115, 0, 115, 104, 97, 100, 95, 97, 108, 112, 104, 97, 0, 115, 101, 112, 116, 101, 120, + 0, 114, 103, 98, 115, 101, 108, 0, 112, 114, 95, 116, 121, 112, 101, 0, 112, 114, 95, 98, 97, 99, 107, 0, 112, 114, 95, 108, 97, 109, 112, 0, + 109, 108, 95, 102, 108, 97, 103, 0, 100, 105, 102, 102, 95, 115, 104, 97, 100, 101, 114, 0, 115, 112, 101, 99, 95, 115, 104, 97, 100, 101, 114, 0, + 114, 111, 117, 103, 104, 110, 101, 115, 115, 0, 114, 101, 102, 114, 97, 99, 0, 112, 97, 114, 97, 109, 91, 52, 93, 0, 114, 109, 115, 0, 100, 97, + 114, 107, 110, 101, 115, 115, 0, 42, 114, 97, 109, 112, 95, 99, 111, 108, 0, 42, 114, 97, 109, 112, 95, 115, 112, 101, 99, 0, 114, 97, 109, 112, + 105, 110, 95, 99, 111, 108, 0, 114, 97, 109, 112, 105, 110, 95, 115, 112, 101, 99, 0, 114, 97, 109, 112, 98, 108, 101, 110, 100, 95, 99, 111, 108, + 0, 114, 97, 109, 112, 98, 108, 101, 110, 100, 95, 115, 112, 101, 99, 0, 114, 97, 109, 112, 95, 115, 104, 111, 119, 0, 114, 97, 109, 112, 102, 97, + 99, 95, 99, 111, 108, 0, 114, 97, 109, 112, 102, 97, 99, 95, 115, 112, 101, 99, 0, 42, 103, 114, 111, 117, 112, 0, 102, 114, 105, 99, 116, 105, + 111, 110, 0, 102, 104, 0, 114, 101, 102, 108, 101, 99, 116, 0, 102, 104, 100, 105, 115, 116, 0, 120, 121, 102, 114, 105, 99, 116, 0, 100, 121, 110, + 97, 109, 111, 100, 101, 0, 115, 115, 115, 95, 114, 97, 100, 105, 117, 115, 91, 51, 93, 0, 115, 115, 115, 95, 99, 111, 108, 91, 51, 93, 0, 115, + 115, 115, 95, 101, 114, 114, 111, 114, 0, 115, 115, 115, 95, 115, 99, 97, 108, 101, 0, 115, 115, 115, 95, 105, 111, 114, 0, 115, 115, 115, 95, 99, + 111, 108, 102, 97, 99, 0, 115, 115, 115, 95, 116, 101, 120, 102, 97, 99, 0, 115, 115, 115, 95, 102, 114, 111, 110, 116, 0, 115, 115, 115, 95, 98, + 97, 99, 107, 0, 115, 115, 115, 95, 102, 108, 97, 103, 0, 115, 115, 115, 95, 112, 114, 101, 115, 101, 116, 0, 89, 70, 95, 97, 114, 0, 89, 70, + 95, 97, 103, 0, 89, 70, 95, 97, 98, 0, 89, 70, 95, 100, 115, 99, 97, 108, 101, 0, 89, 70, 95, 100, 112, 119, 114, 0, 89, 70, 95, 100, + 115, 109, 112, 0, 89, 70, 95, 112, 114, 101, 115, 101, 116, 0, 89, 70, 95, 100, 106, 105, 116, 0, 103, 112, 117, 109, 97, 116, 101, 114, 105, 97, + 108, 0, 110, 97, 109, 101, 91, 50, 53, 54, 93, 0, 115, 99, 97, 108, 101, 0, 42, 98, 98, 0, 105, 49, 0, 106, 49, 0, 107, 49, 0, 105, + 50, 0, 106, 50, 0, 107, 50, 0, 115, 101, 108, 99, 111, 108, 49, 0, 115, 101, 108, 99, 111, 108, 50, 0, 113, 117, 97, 116, 91, 52, 93, 0, + 101, 120, 112, 120, 0, 101, 120, 112, 121, 0, 101, 120, 112, 122, 0, 114, 97, 100, 0, 114, 97, 100, 50, 0, 115, 0, 42, 109, 97, 116, 0, 42, + 105, 109, 97, 116, 0, 101, 108, 101, 109, 115, 0, 100, 105, 115, 112, 0, 42, 42, 109, 97, 116, 0, 116, 111, 116, 99, 111, 108, 0, 119, 105, 114, + 101, 115, 105, 122, 101, 0, 114, 101, 110, 100, 101, 114, 115, 105, 122, 101, 0, 116, 104, 114, 101, 115, 104, 0, 118, 101, 99, 91, 51, 93, 91, 51, + 93, 0, 97, 108, 102, 97, 0, 119, 101, 105, 103, 104, 116, 0, 114, 97, 100, 105, 117, 115, 0, 104, 49, 0, 104, 50, 0, 102, 49, 0, 102, 50, + 0, 102, 51, 0, 104, 105, 100, 101, 0, 118, 101, 99, 91, 52, 93, 0, 109, 97, 116, 95, 110, 114, 0, 112, 110, 116, 115, 117, 0, 112, 110, 116, + 115, 118, 0, 114, 101, 115, 111, 108, 117, 0, 114, 101, 115, 111, 108, 118, 0, 111, 114, 100, 101, 114, 117, 0, 111, 114, 100, 101, 114, 118, 0, 102, + 108, 97, 103, 117, 0, 102, 108, 97, 103, 118, 0, 42, 107, 110, 111, 116, 115, 117, 0, 42, 107, 110, 111, 116, 115, 118, 0, 116, 105, 108, 116, 95, + 105, 110, 116, 101, 114, 112, 0, 114, 97, 100, 105, 117, 115, 95, 105, 110, 116, 101, 114, 112, 0, 99, 104, 97, 114, 105, 100, 120, 0, 107, 101, 114, + 110, 0, 104, 0, 110, 117, 114, 98, 0, 42, 98, 101, 118, 111, 98, 106, 0, 42, 116, 97, 112, 101, 114, 111, 98, 106, 0, 42, 116, 101, 120, 116, + 111, 110, 99, 117, 114, 118, 101, 0, 42, 112, 97, 116, 104, 0, 42, 107, 101, 121, 0, 98, 101, 118, 0, 112, 97, 116, 104, 108, 101, 110, 0, 98, + 101, 118, 114, 101, 115, 111, 108, 0, 119, 105, 100, 116, 104, 0, 101, 120, 116, 49, 0, 101, 120, 116, 50, 0, 114, 101, 115, 111, 108, 117, 95, 114, + 101, 110, 0, 114, 101, 115, 111, 108, 118, 95, 114, 101, 110, 0, 115, 112, 97, 99, 101, 109, 111, 100, 101, 0, 115, 112, 97, 99, 105, 110, 103, 0, + 108, 105, 110, 101, 100, 105, 115, 116, 0, 115, 104, 101, 97, 114, 0, 102, 115, 105, 122, 101, 0, 119, 111, 114, 100, 115, 112, 97, 99, 101, 0, 117, + 108, 112, 111, 115, 0, 117, 108, 104, 101, 105, 103, 104, 116, 0, 120, 111, 102, 0, 121, 111, 102, 0, 108, 105, 110, 101, 119, 105, 100, 116, 104, 0, + 42, 115, 116, 114, 0, 102, 97, 109, 105, 108, 121, 91, 50, 52, 93, 0, 42, 118, 102, 111, 110, 116, 0, 42, 118, 102, 111, 110, 116, 98, 0, 42, + 118, 102, 111, 110, 116, 105, 0, 42, 118, 102, 111, 110, 116, 98, 105, 0, 115, 101, 112, 99, 104, 97, 114, 0, 116, 111, 116, 98, 111, 120, 0, 97, + 99, 116, 98, 111, 120, 0, 42, 116, 98, 0, 115, 101, 108, 115, 116, 97, 114, 116, 0, 115, 101, 108, 101, 110, 100, 0, 42, 115, 116, 114, 105, 110, + 102, 111, 0, 99, 117, 114, 105, 110, 102, 111, 0, 101, 102, 102, 101, 99, 116, 0, 42, 109, 102, 97, 99, 101, 0, 42, 109, 116, 102, 97, 99, 101, + 0, 42, 116, 102, 97, 99, 101, 0, 42, 109, 118, 101, 114, 116, 0, 42, 109, 101, 100, 103, 101, 0, 42, 100, 118, 101, 114, 116, 0, 42, 109, 99, + 111, 108, 0, 42, 109, 115, 116, 105, 99, 107, 121, 0, 42, 116, 101, 120, 99, 111, 109, 101, 115, 104, 0, 42, 109, 115, 101, 108, 101, 99, 116, 0, + 118, 100, 97, 116, 97, 0, 101, 100, 97, 116, 97, 0, 102, 100, 97, 116, 97, 0, 116, 111, 116, 101, 100, 103, 101, 0, 116, 111, 116, 102, 97, 99, + 101, 0, 116, 111, 116, 115, 101, 108, 101, 99, 116, 0, 97, 99, 116, 95, 102, 97, 99, 101, 0, 99, 117, 98, 101, 109, 97, 112, 115, 105, 122, 101, + 0, 115, 109, 111, 111, 116, 104, 114, 101, 115, 104, 0, 115, 117, 98, 100, 105, 118, 0, 115, 117, 98, 100, 105, 118, 114, 0, 115, 117, 98, 115, 117, + 114, 102, 116, 121, 112, 101, 0, 42, 109, 114, 0, 42, 112, 118, 0, 42, 116, 112, 97, 103, 101, 0, 117, 118, 91, 52, 93, 91, 50, 93, 0, 99, + 111, 108, 91, 52, 93, 0, 116, 114, 97, 110, 115, 112, 0, 116, 105, 108, 101, 0, 117, 110, 119, 114, 97, 112, 0, 118, 49, 0, 118, 50, 0, 118, + 51, 0, 118, 52, 0, 101, 100, 99, 111, 100, 101, 0, 99, 114, 101, 97, 115, 101, 0, 98, 119, 101, 105, 103, 104, 116, 0, 100, 101, 102, 95, 110, + 114, 0, 42, 100, 119, 0, 116, 111, 116, 119, 101, 105, 103, 104, 116, 0, 99, 111, 91, 51, 93, 0, 110, 111, 91, 51, 93, 0, 112, 97, 100, 91, + 51, 93, 0, 117, 118, 91, 50, 93, 0, 99, 111, 91, 50, 93, 0, 105, 110, 100, 101, 120, 0, 102, 0, 105, 0, 115, 91, 50, 53, 54, 93, 0, + 118, 91, 52, 93, 0, 109, 105, 100, 0, 118, 91, 50, 93, 0, 42, 102, 97, 99, 101, 115, 0, 42, 99, 111, 108, 102, 97, 99, 101, 115, 0, 42, + 101, 100, 103, 101, 115, 0, 42, 101, 100, 103, 101, 95, 98, 111, 117, 110, 100, 97, 114, 121, 95, 115, 116, 97, 116, 101, 115, 0, 42, 118, 101, 114, + 116, 95, 101, 100, 103, 101, 95, 109, 97, 112, 0, 42, 118, 101, 114, 116, 95, 102, 97, 99, 101, 95, 109, 97, 112, 0, 42, 109, 97, 112, 95, 109, + 101, 109, 0, 42, 118, 101, 114, 116, 115, 0, 108, 101, 118, 101, 108, 115, 0, 108, 101, 118, 101, 108, 95, 99, 111, 117, 110, 116, 0, 99, 117, 114, + 114, 101, 110, 116, 0, 110, 101, 119, 108, 118, 108, 0, 101, 100, 103, 101, 108, 118, 108, 0, 112, 105, 110, 108, 118, 108, 0, 114, 101, 110, 100, 101, + 114, 108, 118, 108, 0, 117, 115, 101, 95, 99, 111, 108, 0, 42, 101, 100, 103, 101, 95, 102, 108, 97, 103, 115, 0, 42, 101, 100, 103, 101, 95, 99, + 114, 101, 97, 115, 101, 115, 0, 42, 118, 101, 114, 116, 95, 109, 97, 112, 0, 42, 101, 100, 103, 101, 95, 109, 97, 112, 0, 42, 111, 108, 100, 95, + 102, 97, 99, 101, 115, 0, 42, 111, 108, 100, 95, 101, 100, 103, 101, 115, 0, 42, 101, 114, 114, 111, 114, 0, 109, 111, 100, 105, 102, 105, 101, 114, + 0, 115, 117, 98, 100, 105, 118, 84, 121, 112, 101, 0, 114, 101, 110, 100, 101, 114, 76, 101, 118, 101, 108, 115, 0, 42, 101, 109, 67, 97, 99, 104, + 101, 0, 42, 109, 67, 97, 99, 104, 101, 0, 100, 101, 102, 97, 120, 105, 115, 0, 112, 97, 100, 91, 54, 93, 0, 108, 101, 110, 103, 116, 104, 0, + 114, 97, 110, 100, 111, 109, 105, 122, 101, 0, 115, 101, 101, 100, 0, 42, 111, 98, 95, 97, 114, 109, 0, 42, 115, 116, 97, 114, 116, 95, 99, 97, + 112, 0, 42, 101, 110, 100, 95, 99, 97, 112, 0, 42, 99, 117, 114, 118, 101, 95, 111, 98, 0, 42, 111, 102, 102, 115, 101, 116, 95, 111, 98, 0, + 111, 102, 102, 115, 101, 116, 91, 51, 93, 0, 115, 99, 97, 108, 101, 91, 51, 93, 0, 109, 101, 114, 103, 101, 95, 100, 105, 115, 116, 0, 102, 105, + 116, 95, 116, 121, 112, 101, 0, 111, 102, 102, 115, 101, 116, 95, 116, 121, 112, 101, 0, 99, 111, 117, 110, 116, 0, 97, 120, 105, 115, 0, 116, 111, + 108, 101, 114, 97, 110, 99, 101, 0, 42, 109, 105, 114, 114, 111, 114, 95, 111, 98, 0, 115, 112, 108, 105, 116, 95, 97, 110, 103, 108, 101, 0, 118, + 97, 108, 117, 101, 0, 114, 101, 115, 0, 118, 97, 108, 95, 102, 108, 97, 103, 115, 0, 108, 105, 109, 95, 102, 108, 97, 103, 115, 0, 101, 95, 102, + 108, 97, 103, 115, 0, 98, 101, 118, 101, 108, 95, 97, 110, 103, 108, 101, 0, 100, 101, 102, 103, 114, 112, 95, 110, 97, 109, 101, 91, 51, 50, 93, + 0, 42, 116, 101, 120, 116, 117, 114, 101, 0, 115, 116, 114, 101, 110, 103, 116, 104, 0, 100, 105, 114, 101, 99, 116, 105, 111, 110, 0, 109, 105, 100, + 108, 101, 118, 101, 108, 0, 116, 101, 120, 109, 97, 112, 112, 105, 110, 103, 0, 42, 109, 97, 112, 95, 111, 98, 106, 101, 99, 116, 0, 117, 118, 108, + 97, 121, 101, 114, 95, 110, 97, 109, 101, 91, 51, 50, 93, 0, 117, 118, 108, 97, 121, 101, 114, 95, 116, 109, 112, 0, 42, 112, 114, 111, 106, 101, + 99, 116, 111, 114, 115, 91, 49, 48, 93, 0, 42, 105, 109, 97, 103, 101, 0, 110, 117, 109, 95, 112, 114, 111, 106, 101, 99, 116, 111, 114, 115, 0, + 97, 115, 112, 101, 99, 116, 120, 0, 97, 115, 112, 101, 99, 116, 121, 0, 112, 101, 114, 99, 101, 110, 116, 0, 102, 97, 99, 101, 67, 111, 117, 110, + 116, 0, 102, 97, 99, 0, 114, 101, 112, 101, 97, 116, 0, 42, 111, 98, 106, 101, 99, 116, 99, 101, 110, 116, 101, 114, 0, 115, 116, 97, 114, 116, + 120, 0, 115, 116, 97, 114, 116, 121, 0, 104, 101, 105, 103, 104, 116, 0, 110, 97, 114, 114, 111, 119, 0, 115, 112, 101, 101, 100, 0, 100, 97, 109, + 112, 0, 102, 97, 108, 108, 111, 102, 102, 0, 116, 105, 109, 101, 111, 102, 102, 115, 0, 108, 105, 102, 101, 116, 105, 109, 101, 0, 100, 101, 102, 111, + 114, 109, 102, 108, 97, 103, 0, 109, 117, 108, 116, 105, 0, 42, 112, 114, 101, 118, 67, 111, 115, 0, 112, 97, 114, 101, 110, 116, 105, 110, 118, 91, + 52, 93, 91, 52, 93, 0, 99, 101, 110, 116, 91, 51, 93, 0, 42, 105, 110, 100, 101, 120, 97, 114, 0, 116, 111, 116, 105, 110, 100, 101, 120, 0, + 102, 111, 114, 99, 101, 0, 42, 99, 108, 111, 116, 104, 79, 98, 106, 101, 99, 116, 0, 42, 115, 105, 109, 95, 112, 97, 114, 109, 115, 0, 42, 99, + 111, 108, 108, 95, 112, 97, 114, 109, 115, 0, 42, 112, 111, 105, 110, 116, 95, 99, 97, 99, 104, 101, 0, 42, 120, 0, 42, 120, 110, 101, 119, 0, + 42, 120, 111, 108, 100, 0, 42, 99, 117, 114, 114, 101, 110, 116, 95, 120, 110, 101, 119, 0, 42, 99, 117, 114, 114, 101, 110, 116, 95, 120, 0, 42, + 99, 117, 114, 114, 101, 110, 116, 95, 118, 0, 42, 109, 102, 97, 99, 101, 115, 0, 110, 117, 109, 118, 101, 114, 116, 115, 0, 110, 117, 109, 102, 97, + 99, 101, 115, 0, 97, 98, 115, 111, 114, 112, 116, 105, 111, 110, 0, 116, 105, 109, 101, 0, 42, 98, 118, 104, 116, 114, 101, 101, 0, 42, 100, 109, + 0, 111, 112, 101, 114, 97, 116, 105, 111, 110, 0, 118, 101, 114, 116, 101, 120, 0, 116, 111, 116, 105, 110, 102, 108, 117, 101, 110, 99, 101, 0, 103, + 114, 105, 100, 115, 105, 122, 101, 0, 110, 101, 101, 100, 98, 105, 110, 100, 0, 42, 98, 105, 110, 100, 119, 101, 105, 103, 104, 116, 115, 0, 42, 98, + 105, 110, 100, 99, 111, 115, 0, 116, 111, 116, 99, 97, 103, 101, 118, 101, 114, 116, 0, 42, 100, 121, 110, 103, 114, 105, 100, 0, 42, 100, 121, 110, + 105, 110, 102, 108, 117, 101, 110, 99, 101, 115, 0, 42, 100, 121, 110, 118, 101, 114, 116, 115, 0, 42, 112, 97, 100, 50, 0, 100, 121, 110, 103, 114, + 105, 100, 115, 105, 122, 101, 0, 100, 121, 110, 99, 101, 108, 108, 109, 105, 110, 91, 51, 93, 0, 100, 121, 110, 99, 101, 108, 108, 119, 105, 100, 116, + 104, 0, 98, 105, 110, 100, 109, 97, 116, 91, 52, 93, 91, 52, 93, 0, 42, 112, 115, 121, 115, 0, 116, 111, 116, 100, 109, 118, 101, 114, 116, 0, + 116, 111, 116, 100, 109, 101, 100, 103, 101, 0, 116, 111, 116, 100, 109, 102, 97, 99, 101, 0, 112, 115, 121, 115, 0, 114, 116, 91, 50, 93, 0, 42, + 102, 97, 99, 101, 112, 97, 0, 118, 103, 114, 111, 117, 112, 0, 112, 114, 111, 116, 101, 99, 116, 0, 42, 102, 115, 115, 0, 42, 116, 97, 114, 103, + 101, 116, 0, 42, 97, 117, 120, 84, 97, 114, 103, 101, 116, 0, 118, 103, 114, 111, 117, 112, 95, 110, 97, 109, 101, 91, 51, 50, 93, 0, 107, 101, + 101, 112, 68, 105, 115, 116, 0, 115, 104, 114, 105, 110, 107, 84, 121, 112, 101, 0, 115, 104, 114, 105, 110, 107, 79, 112, 116, 115, 0, 112, 114, 111, + 106, 65, 120, 105, 115, 0, 115, 117, 98, 115, 117, 114, 102, 76, 101, 118, 101, 108, 115, 0, 42, 111, 114, 105, 103, 105, 110, 0, 102, 97, 99, 116, + 111, 114, 0, 108, 105, 109, 105, 116, 91, 50, 93, 0, 111, 114, 105, 103, 105, 110, 79, 112, 116, 115, 0, 112, 110, 116, 115, 119, 0, 111, 112, 110, + 116, 115, 117, 0, 111, 112, 110, 116, 115, 118, 0, 111, 112, 110, 116, 115, 119, 0, 116, 121, 112, 101, 117, 0, 116, 121, 112, 101, 118, 0, 116, 121, + 112, 101, 119, 0, 102, 117, 0, 102, 118, 0, 102, 119, 0, 100, 117, 0, 100, 118, 0, 100, 119, 0, 42, 100, 101, 102, 0, 118, 101, 99, 91, 56, + 93, 91, 51, 93, 0, 112, 97, 114, 116, 121, 112, 101, 0, 112, 97, 114, 49, 0, 112, 97, 114, 50, 0, 112, 97, 114, 51, 0, 112, 97, 114, 115, + 117, 98, 115, 116, 114, 91, 51, 50, 93, 0, 42, 116, 114, 97, 99, 107, 0, 42, 112, 114, 111, 120, 121, 0, 42, 112, 114, 111, 120, 121, 95, 103, + 114, 111, 117, 112, 0, 42, 112, 114, 111, 120, 121, 95, 102, 114, 111, 109, 0, 42, 97, 99, 116, 105, 111, 110, 0, 42, 112, 111, 115, 101, 108, 105, + 98, 0, 42, 112, 111, 115, 101, 0, 99, 111, 110, 115, 116, 114, 97, 105, 110, 116, 67, 104, 97, 110, 110, 101, 108, 115, 0, 100, 101, 102, 98, 97, + 115, 101, 0, 109, 111, 100, 105, 102, 105, 101, 114, 115, 0, 100, 108, 111, 99, 91, 51, 93, 0, 111, 114, 105, 103, 91, 51, 93, 0, 100, 115, 105, + 122, 101, 91, 51, 93, 0, 100, 114, 111, 116, 91, 51, 93, 0, 111, 98, 109, 97, 116, 91, 52, 93, 91, 52, 93, 0, 99, 111, 110, 115, 116, 105, + 110, 118, 91, 52, 93, 91, 52, 93, 0, 108, 97, 121, 0, 99, 111, 108, 98, 105, 116, 115, 0, 116, 114, 97, 110, 115, 102, 108, 97, 103, 0, 105, + 112, 111, 102, 108, 97, 103, 0, 116, 114, 97, 99, 107, 102, 108, 97, 103, 0, 117, 112, 102, 108, 97, 103, 0, 110, 108, 97, 102, 108, 97, 103, 0, + 112, 114, 111, 116, 101, 99, 116, 102, 108, 97, 103, 0, 105, 112, 111, 119, 105, 110, 0, 115, 99, 97, 102, 108, 97, 103, 0, 115, 99, 97, 118, 105, + 115, 102, 108, 97, 103, 0, 98, 111, 117, 110, 100, 116, 121, 112, 101, 0, 100, 117, 112, 111, 110, 0, 100, 117, 112, 111, 102, 102, 0, 100, 117, 112, + 115, 116, 97, 0, 100, 117, 112, 101, 110, 100, 0, 115, 102, 0, 99, 116, 105, 109, 101, 0, 109, 97, 115, 115, 0, 100, 97, 109, 112, 105, 110, 103, + 0, 105, 110, 101, 114, 116, 105, 97, 0, 102, 111, 114, 109, 102, 97, 99, 116, 111, 114, 0, 114, 100, 97, 109, 112, 105, 110, 103, 0, 115, 105, 122, + 101, 102, 97, 99, 0, 109, 97, 114, 103, 105, 110, 0, 109, 97, 120, 95, 118, 101, 108, 0, 109, 105, 110, 95, 118, 101, 108, 0, 109, 95, 99, 111, + 110, 116, 97, 99, 116, 80, 114, 111, 99, 101, 115, 115, 105, 110, 103, 84, 104, 114, 101, 115, 104, 111, 108, 100, 0, 100, 116, 0, 100, 116, 120, 0, + 97, 99, 116, 99, 111, 108, 0, 101, 109, 112, 116, 121, 95, 100, 114, 97, 119, 116, 121, 112, 101, 0, 112, 97, 100, 49, 91, 51, 93, 0, 101, 109, + 112, 116, 121, 95, 100, 114, 97, 119, 115, 105, 122, 101, 0, 100, 117, 112, 102, 97, 99, 101, 115, 99, 97, 0, 112, 114, 111, 112, 0, 115, 101, 110, + 115, 111, 114, 115, 0, 99, 111, 110, 116, 114, 111, 108, 108, 101, 114, 115, 0, 97, 99, 116, 117, 97, 116, 111, 114, 115, 0, 98, 98, 115, 105, 122, + 101, 91, 51, 93, 0, 97, 99, 116, 100, 101, 102, 0, 103, 97, 109, 101, 102, 108, 97, 103, 0, 103, 97, 109, 101, 102, 108, 97, 103, 50, 0, 42, + 98, 115, 111, 102, 116, 0, 115, 111, 102, 116, 102, 108, 97, 103, 0, 97, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 70, 114, 105, 99, 116, 105, + 111, 110, 91, 51, 93, 0, 99, 111, 110, 115, 116, 114, 97, 105, 110, 116, 115, 0, 110, 108, 97, 115, 116, 114, 105, 112, 115, 0, 104, 111, 111, 107, + 115, 0, 112, 97, 114, 116, 105, 99, 108, 101, 115, 121, 115, 116, 101, 109, 0, 42, 112, 100, 0, 42, 115, 111, 102, 116, 0, 42, 100, 117, 112, 95, + 103, 114, 111, 117, 112, 0, 102, 108, 117, 105, 100, 115, 105, 109, 70, 108, 97, 103, 0, 114, 101, 115, 116, 114, 105, 99, 116, 102, 108, 97, 103, 0, + 115, 104, 97, 112, 101, 110, 114, 0, 115, 104, 97, 112, 101, 102, 108, 97, 103, 0, 114, 101, 99, 97, 108, 99, 111, 0, 98, 111, 100, 121, 95, 116, + 121, 112, 101, 0, 42, 102, 108, 117, 105, 100, 115, 105, 109, 83, 101, 116, 116, 105, 110, 103, 115, 0, 42, 100, 101, 114, 105, 118, 101, 100, 68, 101, + 102, 111, 114, 109, 0, 42, 100, 101, 114, 105, 118, 101, 100, 70, 105, 110, 97, 108, 0, 108, 97, 115, 116, 68, 97, 116, 97, 77, 97, 115, 107, 0, + 115, 116, 97, 116, 101, 0, 105, 110, 105, 116, 95, 115, 116, 97, 116, 101, 0, 103, 112, 117, 108, 97, 109, 112, 0, 99, 117, 114, 105, 110, 100, 101, + 120, 0, 97, 99, 116, 105, 118, 101, 0, 100, 101, 102, 108, 101, 99, 116, 0, 102, 111, 114, 99, 101, 102, 105, 101, 108, 100, 0, 112, 100, 101, 102, + 95, 100, 97, 109, 112, 0, 112, 100, 101, 102, 95, 114, 100, 97, 109, 112, 0, 112, 100, 101, 102, 95, 112, 101, 114, 109, 0, 112, 100, 101, 102, 95, + 102, 114, 105, 99, 116, 0, 112, 100, 101, 102, 95, 114, 102, 114, 105, 99, 116, 0, 102, 95, 115, 116, 114, 101, 110, 103, 116, 104, 0, 102, 95, 112, + 111, 119, 101, 114, 0, 102, 95, 100, 105, 115, 116, 0, 102, 95, 100, 97, 109, 112, 0, 109, 97, 120, 100, 105, 115, 116, 0, 109, 105, 110, 100, 105, + 115, 116, 0, 109, 97, 120, 114, 97, 100, 0, 109, 105, 110, 114, 97, 100, 0, 102, 95, 112, 111, 119, 101, 114, 95, 114, 0, 112, 100, 101, 102, 95, + 115, 98, 100, 97, 109, 112, 0, 112, 100, 101, 102, 95, 115, 98, 105, 102, 116, 0, 112, 100, 101, 102, 95, 115, 98, 111, 102, 116, 0, 99, 108, 117, + 109, 112, 95, 102, 97, 99, 0, 99, 108, 117, 109, 112, 95, 112, 111, 119, 0, 107, 105, 110, 107, 95, 102, 114, 101, 113, 0, 107, 105, 110, 107, 95, + 115, 104, 97, 112, 101, 0, 107, 105, 110, 107, 95, 97, 109, 112, 0, 102, 114, 101, 101, 95, 101, 110, 100, 0, 116, 101, 120, 95, 110, 97, 98, 108, + 97, 0, 116, 101, 120, 95, 109, 111, 100, 101, 0, 107, 105, 110, 107, 0, 107, 105, 110, 107, 95, 97, 120, 105, 115, 0, 114, 116, 50, 0, 42, 114, + 110, 103, 0, 102, 95, 110, 111, 105, 115, 101, 0, 115, 105, 109, 102, 114, 97, 109, 101, 0, 115, 116, 97, 114, 116, 102, 114, 97, 109, 101, 0, 101, + 110, 100, 102, 114, 97, 109, 101, 0, 101, 100, 105, 116, 102, 114, 97, 109, 101, 0, 108, 105, 110, 83, 116, 105, 102, 102, 0, 97, 110, 103, 83, 116, + 105, 102, 102, 0, 118, 111, 108, 117, 109, 101, 0, 118, 105, 116, 101, 114, 97, 116, 105, 111, 110, 115, 0, 112, 105, 116, 101, 114, 97, 116, 105, 111, + 110, 115, 0, 100, 105, 116, 101, 114, 97, 116, 105, 111, 110, 115, 0, 99, 105, 116, 101, 114, 97, 116, 105, 111, 110, 115, 0, 107, 83, 82, 72, 82, + 95, 67, 76, 0, 107, 83, 75, 72, 82, 95, 67, 76, 0, 107, 83, 83, 72, 82, 95, 67, 76, 0, 107, 83, 82, 95, 83, 80, 76, 84, 95, 67, + 76, 0, 107, 83, 75, 95, 83, 80, 76, 84, 95, 67, 76, 0, 107, 83, 83, 95, 83, 80, 76, 84, 95, 67, 76, 0, 107, 86, 67, 70, 0, 107, + 68, 80, 0, 107, 68, 71, 0, 107, 76, 70, 0, 107, 80, 82, 0, 107, 86, 67, 0, 107, 68, 70, 0, 107, 77, 84, 0, 107, 67, 72, 82, 0, + 107, 75, 72, 82, 0, 107, 83, 72, 82, 0, 107, 65, 72, 82, 0, 99, 111, 108, 108, 105, 115, 105, 111, 110, 102, 108, 97, 103, 115, 0, 110, 117, + 109, 99, 108, 117, 115, 116, 101, 114, 105, 116, 101, 114, 97, 116, 105, 111, 110, 115, 0, 119, 101, 108, 100, 105, 110, 103, 0, 42, 112, 97, 114, 116, + 105, 99, 108, 101, 115, 0, 116, 111, 116, 112, 111, 105, 110, 116, 0, 116, 111, 116, 115, 112, 114, 105, 110, 103, 0, 42, 98, 112, 111, 105, 110, 116, + 0, 42, 98, 115, 112, 114, 105, 110, 103, 0, 109, 115, 103, 95, 108, 111, 99, 107, 0, 109, 115, 103, 95, 118, 97, 108, 117, 101, 0, 110, 111, 100, + 101, 109, 97, 115, 115, 0, 110, 97, 109, 101, 100, 86, 71, 95, 77, 97, 115, 115, 91, 51, 50, 93, 0, 103, 114, 97, 118, 0, 109, 101, 100, 105, + 97, 102, 114, 105, 99, 116, 0, 114, 107, 108, 105, 109, 105, 116, 0, 112, 104, 121, 115, 105, 99, 115, 95, 115, 112, 101, 101, 100, 0, 103, 111, 97, + 108, 115, 112, 114, 105, 110, 103, 0, 103, 111, 97, 108, 102, 114, 105, 99, 116, 0, 109, 105, 110, 103, 111, 97, 108, 0, 109, 97, 120, 103, 111, 97, + 108, 0, 100, 101, 102, 103, 111, 97, 108, 0, 118, 101, 114, 116, 103, 114, 111, 117, 112, 0, 110, 97, 109, 101, 100, 86, 71, 95, 83, 111, 102, 116, + 103, 111, 97, 108, 91, 51, 50, 93, 0, 102, 117, 122, 122, 121, 110, 101, 115, 115, 0, 105, 110, 115, 112, 114, 105, 110, 103, 0, 105, 110, 102, 114, + 105, 99, 116, 0, 110, 97, 109, 101, 100, 86, 71, 95, 83, 112, 114, 105, 110, 103, 95, 75, 91, 51, 50, 93, 0, 101, 102, 114, 97, 0, 105, 110, + 116, 101, 114, 118, 97, 108, 0, 108, 111, 99, 97, 108, 0, 115, 111, 108, 118, 101, 114, 102, 108, 97, 103, 115, 0, 42, 42, 107, 101, 121, 115, 0, + 116, 111, 116, 112, 111, 105, 110, 116, 107, 101, 121, 0, 115, 101, 99, 111, 110, 100, 115, 112, 114, 105, 110, 103, 0, 99, 111, 108, 98, 97, 108, 108, + 0, 98, 97, 108, 108, 100, 97, 109, 112, 0, 98, 97, 108, 108, 115, 116, 105, 102, 102, 0, 115, 98, 99, 95, 109, 111, 100, 101, 0, 97, 101, 114, + 111, 101, 100, 103, 101, 0, 109, 105, 110, 108, 111, 111, 112, 115, 0, 109, 97, 120, 108, 111, 111, 112, 115, 0, 99, 104, 111, 107, 101, 0, 115, 111, + 108, 118, 101, 114, 95, 73, 68, 0, 112, 108, 97, 115, 116, 105, 99, 0, 115, 112, 114, 105, 110, 103, 112, 114, 101, 108, 111, 97, 100, 0, 42, 115, + 99, 114, 97, 116, 99, 104, 0, 115, 104, 101, 97, 114, 115, 116, 105, 102, 102, 0, 105, 110, 112, 117, 115, 104, 0, 42, 112, 111, 105, 110, 116, 99, + 97, 99, 104, 101, 0, 115, 104, 111, 119, 95, 97, 100, 118, 97, 110, 99, 101, 100, 111, 112, 116, 105, 111, 110, 115, 0, 114, 101, 115, 111, 108, 117, + 116, 105, 111, 110, 120, 121, 122, 0, 112, 114, 101, 118, 105, 101, 119, 114, 101, 115, 120, 121, 122, 0, 114, 101, 97, 108, 115, 105, 122, 101, 0, 103, + 117, 105, 68, 105, 115, 112, 108, 97, 121, 77, 111, 100, 101, 0, 114, 101, 110, 100, 101, 114, 68, 105, 115, 112, 108, 97, 121, 77, 111, 100, 101, 0, + 118, 105, 115, 99, 111, 115, 105, 116, 121, 86, 97, 108, 117, 101, 0, 118, 105, 115, 99, 111, 115, 105, 116, 121, 77, 111, 100, 101, 0, 118, 105, 115, + 99, 111, 115, 105, 116, 121, 69, 120, 112, 111, 110, 101, 110, 116, 0, 103, 114, 97, 118, 120, 0, 103, 114, 97, 118, 121, 0, 103, 114, 97, 118, 122, + 0, 97, 110, 105, 109, 83, 116, 97, 114, 116, 0, 97, 110, 105, 109, 69, 110, 100, 0, 103, 115, 116, 97, 114, 0, 109, 97, 120, 82, 101, 102, 105, + 110, 101, 0, 105, 110, 105, 86, 101, 108, 120, 0, 105, 110, 105, 86, 101, 108, 121, 0, 105, 110, 105, 86, 101, 108, 122, 0, 42, 111, 114, 103, 77, + 101, 115, 104, 0, 42, 109, 101, 115, 104, 83, 117, 114, 102, 97, 99, 101, 0, 42, 109, 101, 115, 104, 66, 66, 0, 115, 117, 114, 102, 100, 97, 116, + 97, 80, 97, 116, 104, 91, 50, 52, 48, 93, 0, 98, 98, 83, 116, 97, 114, 116, 91, 51, 93, 0, 98, 98, 83, 105, 122, 101, 91, 51, 93, 0, + 116, 121, 112, 101, 70, 108, 97, 103, 115, 0, 100, 111, 109, 97, 105, 110, 78, 111, 118, 101, 99, 103, 101, 110, 0, 118, 111, 108, 117, 109, 101, 73, + 110, 105, 116, 84, 121, 112, 101, 0, 112, 97, 114, 116, 83, 108, 105, 112, 86, 97, 108, 117, 101, 0, 103, 101, 110, 101, 114, 97, 116, 101, 84, 114, + 97, 99, 101, 114, 115, 0, 103, 101, 110, 101, 114, 97, 116, 101, 80, 97, 114, 116, 105, 99, 108, 101, 115, 0, 115, 117, 114, 102, 97, 99, 101, 83, + 109, 111, 111, 116, 104, 105, 110, 103, 0, 115, 117, 114, 102, 97, 99, 101, 83, 117, 98, 100, 105, 118, 115, 0, 112, 97, 114, 116, 105, 99, 108, 101, + 73, 110, 102, 83, 105, 122, 101, 0, 112, 97, 114, 116, 105, 99, 108, 101, 73, 110, 102, 65, 108, 112, 104, 97, 0, 102, 97, 114, 70, 105, 101, 108, + 100, 83, 105, 122, 101, 0, 42, 109, 101, 115, 104, 83, 117, 114, 102, 78, 111, 114, 109, 97, 108, 115, 0, 99, 112, 115, 84, 105, 109, 101, 83, 116, + 97, 114, 116, 0, 99, 112, 115, 84, 105, 109, 101, 69, 110, 100, 0, 99, 112, 115, 81, 117, 97, 108, 105, 116, 121, 0, 97, 116, 116, 114, 97, 99, + 116, 102, 111, 114, 99, 101, 83, 116, 114, 101, 110, 103, 116, 104, 0, 97, 116, 116, 114, 97, 99, 116, 102, 111, 114, 99, 101, 82, 97, 100, 105, 117, + 115, 0, 118, 101, 108, 111, 99, 105, 116, 121, 102, 111, 114, 99, 101, 83, 116, 114, 101, 110, 103, 116, 104, 0, 118, 101, 108, 111, 99, 105, 116, 121, + 102, 111, 114, 99, 101, 82, 97, 100, 105, 117, 115, 0, 108, 97, 115, 116, 103, 111, 111, 100, 102, 114, 97, 109, 101, 0, 109, 105, 115, 116, 121, 112, + 101, 0, 104, 111, 114, 114, 0, 104, 111, 114, 103, 0, 104, 111, 114, 98, 0, 104, 111, 114, 107, 0, 122, 101, 110, 114, 0, 122, 101, 110, 103, 0, + 122, 101, 110, 98, 0, 122, 101, 110, 107, 0, 97, 109, 98, 107, 0, 102, 97, 115, 116, 99, 111, 108, 0, 101, 120, 112, 111, 115, 117, 114, 101, 0, + 101, 120, 112, 0, 114, 97, 110, 103, 101, 0, 108, 105, 110, 102, 97, 99, 0, 108, 111, 103, 102, 97, 99, 0, 103, 114, 97, 118, 105, 116, 121, 0, + 97, 99, 116, 105, 118, 105, 116, 121, 66, 111, 120, 82, 97, 100, 105, 117, 115, 0, 115, 107, 121, 116, 121, 112, 101, 0, 111, 99, 99, 108, 117, 115, + 105, 111, 110, 82, 101, 115, 0, 112, 104, 121, 115, 105, 99, 115, 69, 110, 103, 105, 110, 101, 0, 116, 105, 99, 114, 97, 116, 101, 0, 109, 97, 120, + 108, 111, 103, 105, 99, 115, 116, 101, 112, 0, 112, 104, 121, 115, 117, 98, 115, 116, 101, 112, 0, 109, 97, 120, 112, 104, 121, 115, 116, 101, 112, 0, + 109, 105, 115, 105, 0, 109, 105, 115, 116, 115, 116, 97, 0, 109, 105, 115, 116, 100, 105, 115, 116, 0, 109, 105, 115, 116, 104, 105, 0, 115, 116, 97, + 114, 114, 0, 115, 116, 97, 114, 103, 0, 115, 116, 97, 114, 98, 0, 115, 116, 97, 114, 107, 0, 115, 116, 97, 114, 115, 105, 122, 101, 0, 115, 116, + 97, 114, 109, 105, 110, 100, 105, 115, 116, 0, 115, 116, 97, 114, 100, 105, 115, 116, 0, 115, 116, 97, 114, 99, 111, 108, 110, 111, 105, 115, 101, 0, + 100, 111, 102, 115, 116, 97, 0, 100, 111, 102, 101, 110, 100, 0, 100, 111, 102, 109, 105, 110, 0, 100, 111, 102, 109, 97, 120, 0, 97, 111, 100, 105, + 115, 116, 0, 97, 111, 100, 105, 115, 116, 102, 97, 99, 0, 97, 111, 101, 110, 101, 114, 103, 121, 0, 97, 111, 98, 105, 97, 115, 0, 97, 111, 109, + 111, 100, 101, 0, 97, 111, 115, 97, 109, 112, 0, 97, 111, 109, 105, 120, 0, 97, 111, 99, 111, 108, 111, 114, 0, 97, 111, 95, 97, 100, 97, 112, + 116, 95, 116, 104, 114, 101, 115, 104, 0, 97, 111, 95, 97, 100, 97, 112, 116, 95, 115, 112, 101, 101, 100, 95, 102, 97, 99, 0, 97, 111, 95, 97, + 112, 112, 114, 111, 120, 95, 101, 114, 114, 111, 114, 0, 97, 111, 95, 97, 112, 112, 114, 111, 120, 95, 99, 111, 114, 114, 101, 99, 116, 105, 111, 110, + 0, 97, 111, 95, 115, 97, 109, 112, 95, 109, 101, 116, 104, 111, 100, 0, 97, 111, 95, 103, 97, 116, 104, 101, 114, 95, 109, 101, 116, 104, 111, 100, + 0, 97, 111, 95, 97, 112, 112, 114, 111, 120, 95, 112, 97, 115, 115, 101, 115, 0, 42, 97, 111, 115, 112, 104, 101, 114, 101, 0, 42, 97, 111, 116, + 97, 98, 108, 101, 115, 0, 104, 101, 109, 105, 114, 101, 115, 0, 109, 97, 120, 105, 116, 101, 114, 0, 100, 114, 97, 119, 116, 121, 112, 101, 0, 115, + 117, 98, 115, 104, 111, 111, 116, 112, 0, 115, 117, 98, 115, 104, 111, 111, 116, 101, 0, 110, 111, 100, 101, 108, 105, 109, 0, 109, 97, 120, 115, 117, + 98, 108, 97, 109, 112, 0, 112, 97, 109, 97, 0, 112, 97, 109, 105, 0, 101, 108, 109, 97, 0, 101, 108, 109, 105, 0, 109, 97, 120, 110, 111, 100, + 101, 0, 99, 111, 110, 118, 101, 114, 103, 101, 110, 99, 101, 0, 114, 97, 100, 102, 97, 99, 0, 103, 97, 109, 109, 97, 0, 115, 101, 108, 99, 111, + 108, 0, 115, 120, 0, 115, 121, 0, 42, 108, 112, 70, 111, 114, 109, 97, 116, 0, 42, 108, 112, 80, 97, 114, 109, 115, 0, 99, 98, 70, 111, 114, + 109, 97, 116, 0, 99, 98, 80, 97, 114, 109, 115, 0, 102, 99, 99, 84, 121, 112, 101, 0, 102, 99, 99, 72, 97, 110, 100, 108, 101, 114, 0, 100, + 119, 75, 101, 121, 70, 114, 97, 109, 101, 69, 118, 101, 114, 121, 0, 100, 119, 81, 117, 97, 108, 105, 116, 121, 0, 100, 119, 66, 121, 116, 101, 115, + 80, 101, 114, 83, 101, 99, 111, 110, 100, 0, 100, 119, 70, 108, 97, 103, 115, 0, 100, 119, 73, 110, 116, 101, 114, 108, 101, 97, 118, 101, 69, 118, + 101, 114, 121, 0, 97, 118, 105, 99, 111, 100, 101, 99, 110, 97, 109, 101, 91, 49, 50, 56, 93, 0, 42, 99, 100, 80, 97, 114, 109, 115, 0, 42, + 112, 97, 100, 0, 99, 100, 83, 105, 122, 101, 0, 113, 116, 99, 111, 100, 101, 99, 110, 97, 109, 101, 91, 49, 50, 56, 93, 0, 99, 111, 100, 101, + 99, 0, 97, 117, 100, 105, 111, 95, 99, 111, 100, 101, 99, 0, 118, 105, 100, 101, 111, 95, 98, 105, 116, 114, 97, 116, 101, 0, 97, 117, 100, 105, + 111, 95, 98, 105, 116, 114, 97, 116, 101, 0, 103, 111, 112, 95, 115, 105, 122, 101, 0, 114, 99, 95, 109, 105, 110, 95, 114, 97, 116, 101, 0, 114, + 99, 95, 109, 97, 120, 95, 114, 97, 116, 101, 0, 114, 99, 95, 98, 117, 102, 102, 101, 114, 95, 115, 105, 122, 101, 0, 109, 117, 120, 95, 112, 97, + 99, 107, 101, 116, 95, 115, 105, 122, 101, 0, 109, 117, 120, 95, 114, 97, 116, 101, 0, 109, 105, 120, 114, 97, 116, 101, 0, 109, 97, 105, 110, 0, + 42, 109, 97, 116, 95, 111, 118, 101, 114, 114, 105, 100, 101, 0, 42, 108, 105, 103, 104, 116, 95, 111, 118, 101, 114, 114, 105, 100, 101, 0, 108, 97, + 121, 95, 122, 109, 97, 115, 107, 0, 108, 97, 121, 102, 108, 97, 103, 0, 112, 97, 115, 115, 102, 108, 97, 103, 0, 112, 97, 115, 115, 95, 120, 111, + 114, 0, 42, 97, 118, 105, 99, 111, 100, 101, 99, 100, 97, 116, 97, 0, 42, 113, 116, 99, 111, 100, 101, 99, 100, 97, 116, 97, 0, 102, 102, 99, + 111, 100, 101, 99, 100, 97, 116, 97, 0, 99, 102, 114, 97, 0, 112, 115, 102, 114, 97, 0, 112, 101, 102, 114, 97, 0, 105, 109, 97, 103, 101, 115, + 0, 102, 114, 97, 109, 97, 112, 116, 111, 0, 116, 104, 114, 101, 97, 100, 115, 0, 102, 114, 97, 109, 101, 108, 101, 110, 0, 98, 108, 117, 114, 102, + 97, 99, 0, 101, 100, 103, 101, 82, 0, 101, 100, 103, 101, 71, 0, 101, 100, 103, 101, 66, 0, 102, 117, 108, 108, 115, 99, 114, 101, 101, 110, 0, + 120, 112, 108, 97, 121, 0, 121, 112, 108, 97, 121, 0, 102, 114, 101, 113, 112, 108, 97, 121, 0, 97, 116, 116, 114, 105, 98, 0, 114, 116, 49, 0, + 115, 116, 101, 114, 101, 111, 109, 111, 100, 101, 0, 100, 105, 109, 101, 110, 115, 105, 111, 110, 115, 112, 114, 101, 115, 101, 116, 0, 109, 97, 120, 105, + 109, 115, 105, 122, 101, 0, 120, 115, 99, 104, 0, 121, 115, 99, 104, 0, 120, 112, 97, 114, 116, 115, 0, 121, 112, 97, 114, 116, 115, 0, 119, 105, + 110, 112, 111, 115, 0, 112, 108, 97, 110, 101, 115, 0, 105, 109, 116, 121, 112, 101, 0, 115, 117, 98, 105, 109, 116, 121, 112, 101, 0, 113, 117, 97, + 108, 105, 116, 121, 0, 114, 112, 97, 100, 0, 114, 112, 97, 100, 49, 0, 114, 112, 97, 100, 50, 0, 115, 99, 101, 109, 111, 100, 101, 0, 114, 101, + 110, 100, 101, 114, 101, 114, 0, 111, 99, 114, 101, 115, 0, 97, 108, 112, 104, 97, 109, 111, 100, 101, 0, 111, 115, 97, 0, 102, 114, 115, 95, 115, + 101, 99, 0, 101, 100, 103, 101, 105, 110, 116, 0, 115, 97, 102, 101, 116, 121, 0, 98, 111, 114, 100, 101, 114, 0, 100, 105, 115, 112, 114, 101, 99, + 116, 0, 108, 97, 121, 101, 114, 115, 0, 97, 99, 116, 108, 97, 121, 0, 120, 97, 115, 112, 0, 121, 97, 115, 112, 0, 102, 114, 115, 95, 115, 101, + 99, 95, 98, 97, 115, 101, 0, 103, 97, 117, 115, 115, 0, 112, 111, 115, 116, 109, 117, 108, 0, 112, 111, 115, 116, 103, 97, 109, 109, 97, 0, 112, + 111, 115, 116, 104, 117, 101, 0, 112, 111, 115, 116, 115, 97, 116, 0, 100, 105, 116, 104, 101, 114, 95, 105, 110, 116, 101, 110, 115, 105, 116, 121, 0, + 98, 97, 107, 101, 95, 111, 115, 97, 0, 98, 97, 107, 101, 95, 102, 105, 108, 116, 101, 114, 0, 98, 97, 107, 101, 95, 109, 111, 100, 101, 0, 98, + 97, 107, 101, 95, 102, 108, 97, 103, 0, 98, 97, 107, 101, 95, 110, 111, 114, 109, 97, 108, 95, 115, 112, 97, 99, 101, 0, 98, 97, 107, 101, 95, + 113, 117, 97, 100, 95, 115, 112, 108, 105, 116, 0, 98, 97, 107, 101, 95, 109, 97, 120, 100, 105, 115, 116, 0, 98, 97, 107, 101, 95, 98, 105, 97, + 115, 100, 105, 115, 116, 0, 98, 97, 107, 101, 95, 112, 97, 100, 0, 71, 73, 113, 117, 97, 108, 105, 116, 121, 0, 71, 73, 99, 97, 99, 104, 101, + 0, 71, 73, 109, 101, 116, 104, 111, 100, 0, 71, 73, 112, 104, 111, 116, 111, 110, 115, 0, 71, 73, 100, 105, 114, 101, 99, 116, 0, 89, 70, 95, + 65, 65, 0, 89, 70, 101, 120, 112, 111, 114, 116, 120, 109, 108, 0, 89, 70, 95, 110, 111, 98, 117, 109, 112, 0, 89, 70, 95, 99, 108, 97, 109, + 112, 114, 103, 98, 0, 121, 102, 112, 97, 100, 49, 0, 71, 73, 100, 101, 112, 116, 104, 0, 71, 73, 99, 97, 117, 115, 100, 101, 112, 116, 104, 0, + 71, 73, 112, 105, 120, 101, 108, 115, 112, 101, 114, 115, 97, 109, 112, 108, 101, 0, 71, 73, 112, 104, 111, 116, 111, 110, 99, 111, 117, 110, 116, 0, + 71, 73, 109, 105, 120, 112, 104, 111, 116, 111, 110, 115, 0, 71, 73, 112, 104, 111, 116, 111, 110, 114, 97, 100, 105, 117, 115, 0, 89, 70, 95, 114, + 97, 121, 100, 101, 112, 116, 104, 0, 89, 70, 95, 65, 65, 112, 97, 115, 115, 101, 115, 0, 89, 70, 95, 65, 65, 115, 97, 109, 112, 108, 101, 115, + 0, 121, 102, 112, 97, 100, 50, 0, 71, 73, 115, 104, 97, 100, 111, 119, 113, 117, 97, 108, 105, 116, 121, 0, 71, 73, 114, 101, 102, 105, 110, 101, + 109, 101, 110, 116, 0, 71, 73, 112, 111, 119, 101, 114, 0, 71, 73, 105, 110, 100, 105, 114, 112, 111, 119, 101, 114, 0, 89, 70, 95, 103, 97, 109, + 109, 97, 0, 89, 70, 95, 101, 120, 112, 111, 115, 117, 114, 101, 0, 89, 70, 95, 114, 97, 121, 98, 105, 97, 115, 0, 89, 70, 95, 65, 65, 112, + 105, 120, 101, 108, 115, 105, 122, 101, 0, 89, 70, 95, 65, 65, 116, 104, 114, 101, 115, 104, 111, 108, 100, 0, 98, 97, 99, 107, 98, 117, 102, 91, + 49, 54, 48, 93, 0, 112, 105, 99, 91, 49, 54, 48, 93, 0, 115, 116, 97, 109, 112, 0, 115, 116, 97, 109, 112, 95, 102, 111, 110, 116, 95, 105, + 100, 0, 115, 116, 97, 109, 112, 95, 117, 100, 97, 116, 97, 91, 49, 54, 48, 93, 0, 102, 103, 95, 115, 116, 97, 109, 112, 91, 52, 93, 0, 98, + 103, 95, 115, 116, 97, 109, 112, 91, 52, 93, 0, 115, 105, 109, 112, 108, 105, 102, 121, 95, 115, 117, 98, 115, 117, 114, 102, 0, 115, 105, 109, 112, + 108, 105, 102, 121, 95, 115, 104, 97, 100, 111, 119, 115, 97, 109, 112, 108, 101, 115, 0, 115, 105, 109, 112, 108, 105, 102, 121, 95, 112, 97, 114, 116, + 105, 99, 108, 101, 115, 0, 115, 105, 109, 112, 108, 105, 102, 121, 95, 97, 111, 115, 115, 115, 0, 99, 105, 110, 101, 111, 110, 119, 104, 105, 116, 101, + 0, 99, 105, 110, 101, 111, 110, 98, 108, 97, 99, 107, 0, 99, 105, 110, 101, 111, 110, 103, 97, 109, 109, 97, 0, 106, 112, 50, 95, 112, 114, 101, + 115, 101, 116, 0, 106, 112, 50, 95, 100, 101, 112, 116, 104, 0, 114, 112, 97, 100, 51, 0, 100, 111, 109, 101, 114, 101, 115, 0, 100, 111, 109, 101, + 109, 111, 100, 101, 0, 100, 111, 109, 101, 97, 110, 103, 108, 101, 0, 100, 111, 109, 101, 116, 105, 108, 116, 0, 100, 111, 109, 101, 114, 101, 115, 98, + 117, 102, 0, 42, 100, 111, 109, 101, 116, 101, 120, 116, 0, 112, 97, 114, 116, 105, 99, 108, 101, 95, 112, 101, 114, 99, 0, 115, 117, 98, 115, 117, + 114, 102, 95, 109, 97, 120, 0, 115, 104, 97, 100, 98, 117, 102, 115, 97, 109, 112, 108, 101, 95, 109, 97, 120, 0, 97, 111, 95, 101, 114, 114, 111, + 114, 0, 99, 111, 108, 91, 51, 93, 0, 102, 114, 97, 109, 101, 0, 110, 97, 109, 101, 91, 54, 52, 93, 0, 42, 98, 114, 117, 115, 104, 0, 116, + 111, 111, 108, 0, 115, 101, 97, 109, 95, 98, 108, 101, 101, 100, 0, 110, 111, 114, 109, 97, 108, 95, 97, 110, 103, 108, 101, 0, 115, 116, 101, 112, + 0, 105, 110, 118, 101, 114, 116, 0, 116, 111, 116, 114, 101, 107, 101, 121, 0, 116, 111, 116, 97, 100, 100, 107, 101, 121, 0, 98, 114, 117, 115, 104, + 116, 121, 112, 101, 0, 98, 114, 117, 115, 104, 91, 55, 93, 0, 101, 109, 105, 116, 116, 101, 114, 100, 105, 115, 116, 0, 100, 114, 97, 119, 95, 116, + 105, 109, 101, 100, 0, 110, 97, 109, 101, 91, 51, 54, 93, 0, 109, 97, 116, 91, 51, 93, 91, 51, 93, 0, 99, 111, 114, 110, 101, 114, 116, 121, + 112, 101, 0, 101, 100, 105, 116, 98, 117, 116, 102, 108, 97, 103, 0, 106, 111, 105, 110, 116, 114, 105, 108, 105, 109, 105, 116, 0, 100, 101, 103, 114, + 0, 116, 117, 114, 110, 0, 101, 120, 116, 114, 95, 111, 102, 102, 115, 0, 100, 111, 117, 98, 108, 105, 109, 105, 116, 0, 115, 101, 103, 109, 101, 110, + 116, 115, 0, 114, 105, 110, 103, 115, 0, 118, 101, 114, 116, 105, 99, 101, 115, 0, 117, 110, 119, 114, 97, 112, 112, 101, 114, 0, 117, 118, 99, 97, + 108, 99, 95, 114, 97, 100, 105, 117, 115, 0, 117, 118, 99, 97, 108, 99, 95, 99, 117, 98, 101, 115, 105, 122, 101, 0, 117, 118, 99, 97, 108, 99, + 95, 109, 97, 114, 103, 105, 110, 0, 117, 118, 99, 97, 108, 99, 95, 109, 97, 112, 100, 105, 114, 0, 117, 118, 99, 97, 108, 99, 95, 109, 97, 112, + 97, 108, 105, 103, 110, 0, 117, 118, 99, 97, 108, 99, 95, 102, 108, 97, 103, 0, 97, 117, 116, 111, 105, 107, 95, 99, 104, 97, 105, 110, 108, 101, + 110, 0, 105, 109, 97, 112, 97, 105, 110, 116, 0, 112, 97, 114, 116, 105, 99, 108, 101, 0, 115, 101, 108, 101, 99, 116, 95, 116, 104, 114, 101, 115, + 104, 0, 99, 108, 101, 97, 110, 95, 116, 104, 114, 101, 115, 104, 0, 114, 101, 116, 111, 112, 111, 95, 109, 111, 100, 101, 0, 114, 101, 116, 111, 112, + 111, 95, 112, 97, 105, 110, 116, 95, 116, 111, 111, 108, 0, 108, 105, 110, 101, 95, 100, 105, 118, 0, 101, 108, 108, 105, 112, 115, 101, 95, 100, 105, + 118, 0, 114, 101, 116, 111, 112, 111, 95, 104, 111, 116, 115, 112, 111, 116, 0, 109, 117, 108, 116, 105, 114, 101, 115, 95, 115, 117, 98, 100, 105, 118, + 95, 116, 121, 112, 101, 0, 115, 107, 103, 101, 110, 95, 114, 101, 115, 111, 108, 117, 116, 105, 111, 110, 0, 115, 107, 103, 101, 110, 95, 116, 104, 114, + 101, 115, 104, 111, 108, 100, 95, 105, 110, 116, 101, 114, 110, 97, 108, 0, 115, 107, 103, 101, 110, 95, 116, 104, 114, 101, 115, 104, 111, 108, 100, 95, + 101, 120, 116, 101, 114, 110, 97, 108, 0, 115, 107, 103, 101, 110, 95, 108, 101, 110, 103, 116, 104, 95, 114, 97, 116, 105, 111, 0, 115, 107, 103, 101, + 110, 95, 108, 101, 110, 103, 116, 104, 95, 108, 105, 109, 105, 116, 0, 115, 107, 103, 101, 110, 95, 97, 110, 103, 108, 101, 95, 108, 105, 109, 105, 116, + 0, 115, 107, 103, 101, 110, 95, 99, 111, 114, 114, 101, 108, 97, 116, 105, 111, 110, 95, 108, 105, 109, 105, 116, 0, 115, 107, 103, 101, 110, 95, 115, + 121, 109, 109, 101, 116, 114, 121, 95, 108, 105, 109, 105, 116, 0, 115, 107, 103, 101, 110, 95, 114, 101, 116, 97, 114, 103, 101, 116, 95, 97, 110, 103, + 108, 101, 95, 119, 101, 105, 103, 104, 116, 0, 115, 107, 103, 101, 110, 95, 114, 101, 116, 97, 114, 103, 101, 116, 95, 108, 101, 110, 103, 116, 104, 95, + 119, 101, 105, 103, 104, 116, 0, 115, 107, 103, 101, 110, 95, 114, 101, 116, 97, 114, 103, 101, 116, 95, 100, 105, 115, 116, 97, 110, 99, 101, 95, 119, + 101, 105, 103, 104, 116, 0, 115, 107, 103, 101, 110, 95, 111, 112, 116, 105, 111, 110, 115, 0, 115, 107, 103, 101, 110, 95, 112, 111, 115, 116, 112, 114, + 111, 0, 115, 107, 103, 101, 110, 95, 112, 111, 115, 116, 112, 114, 111, 95, 112, 97, 115, 115, 101, 115, 0, 115, 107, 103, 101, 110, 95, 115, 117, 98, + 100, 105, 118, 105, 115, 105, 111, 110, 115, 91, 51, 93, 0, 115, 107, 103, 101, 110, 95, 109, 117, 108, 116, 105, 95, 108, 101, 118, 101, 108, 0, 42, + 115, 107, 103, 101, 110, 95, 116, 101, 109, 112, 108, 97, 116, 101, 0, 98, 111, 110, 101, 95, 115, 107, 101, 116, 99, 104, 105, 110, 103, 0, 98, 111, + 110, 101, 95, 115, 107, 101, 116, 99, 104, 105, 110, 103, 95, 99, 111, 110, 118, 101, 114, 116, 0, 115, 107, 103, 101, 110, 95, 115, 117, 98, 100, 105, + 118, 105, 115, 105, 111, 110, 95, 110, 117, 109, 98, 101, 114, 0, 115, 107, 103, 101, 110, 95, 114, 101, 116, 97, 114, 103, 101, 116, 95, 111, 112, 116, + 105, 111, 110, 115, 0, 115, 107, 103, 101, 110, 95, 114, 101, 116, 97, 114, 103, 101, 116, 95, 114, 111, 108, 108, 0, 115, 107, 103, 101, 110, 95, 115, + 105, 100, 101, 95, 115, 116, 114, 105, 110, 103, 91, 56, 93, 0, 115, 107, 103, 101, 110, 95, 110, 117, 109, 95, 115, 116, 114, 105, 110, 103, 91, 56, + 93, 0, 101, 100, 103, 101, 95, 109, 111, 100, 101, 0, 112, 97, 100, 51, 91, 50, 93, 0, 100, 105, 114, 0, 118, 105, 101, 119, 0, 42, 115, 101, + 115, 115, 105, 111, 110, 0, 42, 99, 117, 109, 97, 112, 0, 100, 114, 97, 119, 98, 114, 117, 115, 104, 0, 115, 109, 111, 111, 116, 104, 98, 114, 117, + 115, 104, 0, 112, 105, 110, 99, 104, 98, 114, 117, 115, 104, 0, 105, 110, 102, 108, 97, 116, 101, 98, 114, 117, 115, 104, 0, 103, 114, 97, 98, 98, + 114, 117, 115, 104, 0, 108, 97, 121, 101, 114, 98, 114, 117, 115, 104, 0, 102, 108, 97, 116, 116, 101, 110, 98, 114, 117, 115, 104, 0, 112, 105, 118, + 111, 116, 91, 51, 93, 0, 98, 114, 117, 115, 104, 95, 116, 121, 112, 101, 0, 116, 101, 120, 110, 114, 0, 116, 101, 120, 114, 101, 112, 116, 0, 116, + 101, 120, 102, 97, 100, 101, 0, 116, 101, 120, 115, 101, 112, 0, 97, 118, 101, 114, 97, 103, 105, 110, 103, 0, 116, 97, 98, 108, 101, 116, 95, 115, + 105, 122, 101, 0, 116, 97, 98, 108, 101, 116, 95, 115, 116, 114, 101, 110, 103, 116, 104, 0, 115, 121, 109, 109, 0, 114, 97, 107, 101, 0, 97, 120, + 105, 115, 108, 111, 99, 107, 0, 42, 99, 97, 109, 101, 114, 97, 0, 42, 119, 111, 114, 108, 100, 0, 42, 115, 101, 116, 0, 98, 97, 115, 101, 0, + 42, 98, 97, 115, 97, 99, 116, 0, 99, 117, 114, 115, 111, 114, 91, 51, 93, 0, 116, 119, 99, 101, 110, 116, 91, 51, 93, 0, 116, 119, 109, 105, + 110, 91, 51, 93, 0, 116, 119, 109, 97, 120, 91, 51, 93, 0, 101, 100, 105, 116, 98, 117, 116, 115, 105, 122, 101, 0, 115, 101, 108, 101, 99, 116, + 109, 111, 100, 101, 0, 112, 114, 111, 112, 111, 114, 116, 105, 111, 110, 97, 108, 0, 112, 114, 111, 112, 95, 109, 111, 100, 101, 0, 97, 117, 116, 111, + 109, 101, 114, 103, 101, 0, 112, 97, 100, 53, 0, 112, 97, 100, 54, 0, 97, 117, 116, 111, 107, 101, 121, 95, 109, 111, 100, 101, 0, 42, 101, 100, + 0, 42, 114, 97, 100, 105, 111, 0, 102, 114, 97, 109, 105, 110, 103, 0, 42, 116, 111, 111, 108, 115, 101, 116, 116, 105, 110, 103, 115, 0, 97, 117, + 100, 105, 111, 0, 116, 114, 97, 110, 115, 102, 111, 114, 109, 95, 115, 112, 97, 99, 101, 115, 0, 106, 117, 109, 112, 102, 114, 97, 109, 101, 0, 115, + 110, 97, 112, 95, 109, 111, 100, 101, 0, 115, 110, 97, 112, 95, 102, 108, 97, 103, 0, 115, 110, 97, 112, 95, 116, 97, 114, 103, 101, 116, 0, 42, + 116, 104, 101, 68, 97, 103, 0, 100, 97, 103, 105, 115, 118, 97, 108, 105, 100, 0, 100, 97, 103, 102, 108, 97, 103, 115, 0, 115, 99, 117, 108, 112, + 116, 100, 97, 116, 97, 0, 102, 114, 97, 109, 101, 95, 115, 116, 101, 112, 0, 122, 111, 111, 109, 0, 98, 108, 101, 110, 100, 0, 120, 105, 109, 0, + 121, 105, 109, 0, 115, 112, 97, 99, 101, 116, 121, 112, 101, 0, 98, 108, 111, 99, 107, 115, 99, 97, 108, 101, 0, 42, 97, 114, 101, 97, 0, 98, + 108, 111, 99, 107, 104, 97, 110, 100, 108, 101, 114, 91, 56, 93, 0, 118, 105, 101, 119, 109, 97, 116, 91, 52, 93, 91, 52, 93, 0, 118, 105, 101, + 119, 105, 110, 118, 91, 52, 93, 91, 52, 93, 0, 112, 101, 114, 115, 109, 97, 116, 91, 52, 93, 91, 52, 93, 0, 112, 101, 114, 115, 105, 110, 118, + 91, 52, 93, 91, 52, 93, 0, 119, 105, 110, 109, 97, 116, 49, 91, 52, 93, 91, 52, 93, 0, 118, 105, 101, 119, 109, 97, 116, 49, 91, 52, 93, + 91, 52, 93, 0, 118, 105, 101, 119, 113, 117, 97, 116, 91, 52, 93, 0, 122, 102, 97, 99, 0, 108, 97, 121, 95, 117, 115, 101, 100, 0, 112, 101, + 114, 115, 112, 0, 42, 111, 98, 95, 99, 101, 110, 116, 114, 101, 0, 42, 98, 103, 112, 105, 99, 0, 42, 108, 111, 99, 97, 108, 118, 100, 0, 42, + 114, 105, 0, 42, 114, 101, 116, 111, 112, 111, 95, 118, 105, 101, 119, 95, 100, 97, 116, 97, 0, 42, 100, 101, 112, 116, 104, 115, 0, 111, 98, 95, + 99, 101, 110, 116, 114, 101, 95, 98, 111, 110, 101, 91, 51, 50, 93, 0, 108, 111, 99, 97, 108, 118, 105, 101, 119, 0, 108, 97, 121, 97, 99, 116, + 0, 115, 99, 101, 110, 101, 108, 111, 99, 107, 0, 97, 114, 111, 117, 110, 100, 0, 99, 97, 109, 122, 111, 111, 109, 0, 112, 105, 118, 111, 116, 95, + 108, 97, 115, 116, 0, 103, 114, 105, 100, 0, 103, 114, 105, 100, 118, 105, 101, 119, 0, 112, 105, 120, 115, 105, 122, 101, 0, 110, 101, 97, 114, 0, + 102, 97, 114, 0, 99, 97, 109, 100, 120, 0, 99, 97, 109, 100, 121, 0, 103, 114, 105, 100, 108, 105, 110, 101, 115, 0, 118, 105, 101, 119, 98, 117, + 116, 0, 103, 114, 105, 100, 102, 108, 97, 103, 0, 109, 111, 100, 101, 115, 101, 108, 101, 99, 116, 0, 116, 119, 116, 121, 112, 101, 0, 116, 119, 109, + 111, 100, 101, 0, 116, 119, 102, 108, 97, 103, 0, 116, 119, 100, 114, 97, 119, 102, 108, 97, 103, 0, 116, 119, 109, 97, 116, 91, 52, 93, 91, 52, + 93, 0, 99, 108, 105, 112, 91, 52, 93, 91, 52, 93, 0, 42, 99, 108, 105, 112, 98, 98, 0, 97, 102, 116, 101, 114, 100, 114, 97, 119, 0, 122, + 98, 117, 102, 0, 120, 114, 97, 121, 0, 102, 108, 97, 103, 50, 0, 103, 114, 105, 100, 115, 117, 98, 100, 105, 118, 0, 107, 101, 121, 102, 108, 97, + 103, 115, 0, 110, 100, 111, 102, 109, 111, 100, 101, 0, 110, 100, 111, 102, 102, 105, 108, 116, 101, 114, 0, 42, 112, 114, 111, 112, 101, 114, 116, 105, + 101, 115, 95, 115, 116, 111, 114, 97, 103, 101, 0, 42, 103, 112, 100, 0, 108, 118, 105, 101, 119, 113, 117, 97, 116, 91, 52, 93, 0, 108, 112, 101, + 114, 115, 112, 0, 108, 118, 105, 101, 119, 0, 118, 101, 114, 116, 0, 104, 111, 114, 0, 109, 97, 115, 107, 0, 109, 105, 110, 91, 50, 93, 0, 109, + 97, 120, 91, 50, 93, 0, 109, 105, 110, 122, 111, 111, 109, 0, 109, 97, 120, 122, 111, 111, 109, 0, 115, 99, 114, 111, 108, 108, 0, 107, 101, 101, + 112, 116, 111, 116, 0, 107, 101, 101, 112, 97, 115, 112, 101, 99, 116, 0, 107, 101, 101, 112, 122, 111, 111, 109, 0, 111, 108, 100, 119, 105, 110, 120, + 0, 111, 108, 100, 119, 105, 110, 121, 0, 99, 117, 114, 115, 111, 114, 91, 50, 93, 0, 114, 111, 119, 98, 117, 116, 0, 118, 50, 100, 0, 42, 101, + 100, 105, 116, 105, 112, 111, 0, 105, 112, 111, 107, 101, 121, 0, 97, 99, 116, 110, 97, 109, 101, 91, 51, 50, 93, 0, 99, 111, 110, 115, 116, 110, + 97, 109, 101, 91, 51, 50, 93, 0, 98, 111, 110, 101, 110, 97, 109, 101, 91, 51, 50, 93, 0, 116, 111, 116, 105, 112, 111, 0, 112, 105, 110, 0, + 98, 117, 116, 111, 102, 115, 0, 99, 104, 97, 110, 110, 101, 108, 0, 108, 111, 99, 107, 0, 109, 101, 100, 105, 97, 110, 91, 51, 93, 0, 99, 117, + 114, 115, 101, 110, 115, 0, 99, 117, 114, 97, 99, 116, 0, 97, 108, 105, 103, 110, 0, 116, 97, 98, 111, 0, 109, 97, 105, 110, 98, 0, 109, 97, + 105, 110, 98, 111, 0, 42, 108, 111, 99, 107, 112, 111, 105, 110, 0, 116, 101, 120, 102, 114, 111, 109, 0, 115, 104, 111, 119, 103, 114, 111, 117, 112, + 0, 109, 111, 100, 101, 108, 116, 121, 112, 101, 0, 115, 99, 114, 105, 112, 116, 98, 108, 111, 99, 107, 0, 114, 101, 95, 97, 108, 105, 103, 110, 0, + 111, 108, 100, 107, 101, 121, 112, 114, 101, 115, 115, 0, 116, 97, 98, 91, 55, 93, 0, 114, 101, 110, 100, 101, 114, 95, 115, 105, 122, 101, 0, 99, + 104, 97, 110, 115, 104, 111, 119, 110, 0, 122, 101, 98, 114, 97, 0, 42, 102, 105, 108, 101, 108, 105, 115, 116, 0, 116, 111, 116, 102, 105, 108, 101, + 0, 116, 105, 116, 108, 101, 91, 50, 52, 93, 0, 100, 105, 114, 91, 50, 52, 48, 93, 0, 102, 105, 108, 101, 91, 56, 48, 93, 0, 111, 102, 115, + 0, 115, 111, 114, 116, 0, 109, 97, 120, 110, 97, 109, 101, 108, 101, 110, 0, 99, 111, 108, 108, 117, 109, 115, 0, 102, 95, 102, 112, 0, 102, 112, + 95, 115, 116, 114, 91, 56, 93, 0, 42, 108, 105, 98, 102, 105, 108, 101, 100, 97, 116, 97, 0, 114, 101, 116, 118, 97, 108, 0, 109, 101, 110, 117, + 0, 97, 99, 116, 0, 40, 42, 114, 101, 116, 117, 114, 110, 102, 117, 110, 99, 41, 40, 41, 0, 40, 42, 114, 101, 116, 117, 114, 110, 102, 117, 110, + 99, 95, 101, 118, 101, 110, 116, 41, 40, 41, 0, 40, 42, 114, 101, 116, 117, 114, 110, 102, 117, 110, 99, 95, 97, 114, 103, 115, 41, 40, 41, 0, + 42, 97, 114, 103, 49, 0, 42, 97, 114, 103, 50, 0, 42, 109, 101, 110, 117, 112, 0, 42, 112, 117, 112, 109, 101, 110, 117, 0, 111, 111, 112, 115, + 0, 118, 105, 115, 105, 102, 108, 97, 103, 0, 116, 114, 101, 101, 0, 42, 116, 114, 101, 101, 115, 116, 111, 114, 101, 0, 115, 101, 97, 114, 99, 104, + 95, 115, 116, 114, 105, 110, 103, 91, 51, 50, 93, 0, 115, 101, 97, 114, 99, 104, 95, 116, 115, 101, 0, 115, 101, 97, 114, 99, 104, 95, 102, 108, + 97, 103, 115, 0, 100, 111, 95, 0, 111, 117, 116, 108, 105, 110, 101, 118, 105, 115, 0, 115, 116, 111, 114, 101, 102, 108, 97, 103, 0, 100, 101, 112, + 115, 95, 102, 108, 97, 103, 115, 0, 105, 109, 97, 110, 114, 0, 99, 117, 114, 116, 105, 108, 101, 0, 105, 109, 116, 121, 112, 101, 110, 114, 0, 100, + 116, 95, 117, 118, 0, 115, 116, 105, 99, 107, 121, 0, 100, 116, 95, 117, 118, 115, 116, 114, 101, 116, 99, 104, 0, 112, 97, 100, 91, 53, 93, 0, + 99, 101, 110, 116, 120, 0, 99, 101, 110, 116, 121, 0, 97, 117, 116, 111, 115, 110, 97, 112, 0, 42, 116, 101, 120, 116, 0, 116, 111, 112, 0, 118, + 105, 101, 119, 108, 105, 110, 101, 115, 0, 102, 111, 110, 116, 95, 105, 100, 0, 108, 104, 101, 105, 103, 104, 116, 0, 108, 101, 102, 116, 0, 115, 104, + 111, 119, 108, 105, 110, 101, 110, 114, 115, 0, 116, 97, 98, 110, 117, 109, 98, 101, 114, 0, 99, 117, 114, 114, 116, 97, 98, 95, 115, 101, 116, 0, + 115, 104, 111, 119, 115, 121, 110, 116, 97, 120, 0, 111, 118, 101, 114, 119, 114, 105, 116, 101, 0, 112, 105, 120, 95, 112, 101, 114, 95, 108, 105, 110, + 101, 0, 116, 120, 116, 115, 99, 114, 111, 108, 108, 0, 116, 120, 116, 98, 97, 114, 0, 119, 111, 114, 100, 119, 114, 97, 112, 0, 100, 111, 112, 108, + 117, 103, 105, 110, 115, 0, 42, 112, 121, 95, 100, 114, 97, 119, 0, 42, 112, 121, 95, 101, 118, 101, 110, 116, 0, 42, 112, 121, 95, 98, 117, 116, + 116, 111, 110, 0, 42, 112, 121, 95, 98, 114, 111, 119, 115, 101, 114, 99, 97, 108, 108, 98, 97, 99, 107, 0, 42, 112, 121, 95, 103, 108, 111, 98, + 97, 108, 100, 105, 99, 116, 0, 108, 97, 115, 116, 115, 112, 97, 99, 101, 0, 115, 99, 114, 105, 112, 116, 110, 97, 109, 101, 91, 50, 53, 54, 93, + 0, 115, 99, 114, 105, 112, 116, 97, 114, 103, 91, 50, 53, 54, 93, 0, 42, 115, 99, 114, 105, 112, 116, 0, 42, 98, 117, 116, 95, 114, 101, 102, + 115, 0, 114, 101, 100, 114, 97, 119, 115, 0, 42, 105, 100, 0, 97, 115, 112, 101, 99, 116, 0, 42, 99, 117, 114, 102, 111, 110, 116, 0, 42, 101, + 100, 105, 116, 116, 114, 101, 101, 0, 116, 114, 101, 101, 116, 121, 112, 101, 0, 42, 102, 105, 108, 101, 115, 0, 97, 99, 116, 105, 118, 101, 95, 102, + 105, 108, 101, 0, 110, 117, 109, 116, 105, 108, 101, 115, 120, 0, 110, 117, 109, 116, 105, 108, 101, 115, 121, 0, 115, 101, 108, 115, 116, 97, 116, 101, + 0, 118, 105, 101, 119, 114, 101, 99, 116, 0, 98, 111, 111, 107, 109, 97, 114, 107, 114, 101, 99, 116, 0, 115, 99, 114, 111, 108, 108, 112, 111, 115, + 0, 115, 99, 114, 111, 108, 108, 104, 101, 105, 103, 104, 116, 0, 115, 99, 114, 111, 108, 108, 97, 114, 101, 97, 0, 97, 99, 116, 105, 118, 101, 95, + 98, 111, 111, 107, 109, 97, 114, 107, 0, 112, 114, 118, 95, 119, 0, 112, 114, 118, 95, 104, 0, 42, 105, 109, 103, 0, 111, 117, 116, 108, 105, 110, + 101, 91, 52, 93, 0, 110, 101, 117, 116, 114, 97, 108, 91, 52, 93, 0, 97, 99, 116, 105, 111, 110, 91, 52, 93, 0, 115, 101, 116, 116, 105, 110, + 103, 91, 52, 93, 0, 115, 101, 116, 116, 105, 110, 103, 49, 91, 52, 93, 0, 115, 101, 116, 116, 105, 110, 103, 50, 91, 52, 93, 0, 110, 117, 109, + 91, 52, 93, 0, 116, 101, 120, 116, 102, 105, 101, 108, 100, 91, 52, 93, 0, 116, 101, 120, 116, 102, 105, 101, 108, 100, 95, 104, 105, 91, 52, 93, + 0, 112, 111, 112, 117, 112, 91, 52, 93, 0, 116, 101, 120, 116, 91, 52, 93, 0, 116, 101, 120, 116, 95, 104, 105, 91, 52, 93, 0, 109, 101, 110, + 117, 95, 98, 97, 99, 107, 91, 52, 93, 0, 109, 101, 110, 117, 95, 105, 116, 101, 109, 91, 52, 93, 0, 109, 101, 110, 117, 95, 104, 105, 108, 105, + 116, 101, 91, 52, 93, 0, 109, 101, 110, 117, 95, 116, 101, 120, 116, 91, 52, 93, 0, 109, 101, 110, 117, 95, 116, 101, 120, 116, 95, 104, 105, 91, + 52, 93, 0, 98, 117, 116, 95, 100, 114, 97, 119, 116, 121, 112, 101, 0, 105, 99, 111, 110, 102, 105, 108, 101, 91, 56, 48, 93, 0, 98, 97, 99, + 107, 91, 52, 93, 0, 104, 101, 97, 100, 101, 114, 91, 52, 93, 0, 112, 97, 110, 101, 108, 91, 52, 93, 0, 115, 104, 97, 100, 101, 49, 91, 52, + 93, 0, 115, 104, 97, 100, 101, 50, 91, 52, 93, 0, 104, 105, 108, 105, 116, 101, 91, 52, 93, 0, 103, 114, 105, 100, 91, 52, 93, 0, 119, 105, + 114, 101, 91, 52, 93, 0, 115, 101, 108, 101, 99, 116, 91, 52, 93, 0, 108, 97, 109, 112, 91, 52, 93, 0, 97, 99, 116, 105, 118, 101, 91, 52, + 93, 0, 103, 114, 111, 117, 112, 91, 52, 93, 0, 103, 114, 111, 117, 112, 95, 97, 99, 116, 105, 118, 101, 91, 52, 93, 0, 116, 114, 97, 110, 115, + 102, 111, 114, 109, 91, 52, 93, 0, 118, 101, 114, 116, 101, 120, 91, 52, 93, 0, 118, 101, 114, 116, 101, 120, 95, 115, 101, 108, 101, 99, 116, 91, + 52, 93, 0, 101, 100, 103, 101, 91, 52, 93, 0, 101, 100, 103, 101, 95, 115, 101, 108, 101, 99, 116, 91, 52, 93, 0, 101, 100, 103, 101, 95, 115, + 101, 97, 109, 91, 52, 93, 0, 101, 100, 103, 101, 95, 115, 104, 97, 114, 112, 91, 52, 93, 0, 101, 100, 103, 101, 95, 102, 97, 99, 101, 115, 101, + 108, 91, 52, 93, 0, 102, 97, 99, 101, 91, 52, 93, 0, 102, 97, 99, 101, 95, 115, 101, 108, 101, 99, 116, 91, 52, 93, 0, 102, 97, 99, 101, + 95, 100, 111, 116, 91, 52, 93, 0, 110, 111, 114, 109, 97, 108, 91, 52, 93, 0, 98, 111, 110, 101, 95, 115, 111, 108, 105, 100, 91, 52, 93, 0, + 98, 111, 110, 101, 95, 112, 111, 115, 101, 91, 52, 93, 0, 115, 116, 114, 105, 112, 91, 52, 93, 0, 115, 116, 114, 105, 112, 95, 115, 101, 108, 101, + 99, 116, 91, 52, 93, 0, 99, 102, 114, 97, 109, 101, 91, 52, 93, 0, 118, 101, 114, 116, 101, 120, 95, 115, 105, 122, 101, 0, 102, 97, 99, 101, + 100, 111, 116, 95, 115, 105, 122, 101, 0, 98, 112, 97, 100, 91, 50, 93, 0, 115, 121, 110, 116, 97, 120, 108, 91, 52, 93, 0, 115, 121, 110, 116, + 97, 120, 110, 91, 52, 93, 0, 115, 121, 110, 116, 97, 120, 98, 91, 52, 93, 0, 115, 121, 110, 116, 97, 120, 118, 91, 52, 93, 0, 115, 121, 110, + 116, 97, 120, 99, 91, 52, 93, 0, 109, 111, 118, 105, 101, 91, 52, 93, 0, 105, 109, 97, 103, 101, 91, 52, 93, 0, 115, 99, 101, 110, 101, 91, + 52, 93, 0, 97, 117, 100, 105, 111, 91, 52, 93, 0, 101, 102, 102, 101, 99, 116, 91, 52, 93, 0, 112, 108, 117, 103, 105, 110, 91, 52, 93, 0, + 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 91, 52, 93, 0, 109, 101, 116, 97, 91, 52, 93, 0, 101, 100, 105, 116, 109, 101, 115, 104, 95, 97, + 99, 116, 105, 118, 101, 91, 52, 93, 0, 104, 97, 110, 100, 108, 101, 95, 118, 101, 114, 116, 101, 120, 91, 52, 93, 0, 104, 97, 110, 100, 108, 101, + 95, 118, 101, 114, 116, 101, 120, 95, 115, 101, 108, 101, 99, 116, 91, 52, 93, 0, 104, 97, 110, 100, 108, 101, 95, 118, 101, 114, 116, 101, 120, 95, + 115, 105, 122, 101, 0, 104, 112, 97, 100, 91, 55, 93, 0, 115, 111, 108, 105, 100, 91, 52, 93, 0, 116, 117, 105, 0, 116, 98, 117, 116, 115, 0, + 116, 118, 51, 100, 0, 116, 102, 105, 108, 101, 0, 116, 105, 112, 111, 0, 116, 105, 110, 102, 111, 0, 116, 115, 110, 100, 0, 116, 97, 99, 116, 0, + 116, 110, 108, 97, 0, 116, 115, 101, 113, 0, 116, 105, 109, 97, 0, 116, 105, 109, 97, 115, 101, 108, 0, 116, 101, 120, 116, 0, 116, 111, 111, 112, + 115, 0, 116, 116, 105, 109, 101, 0, 116, 110, 111, 100, 101, 0, 116, 97, 114, 109, 91, 50, 48, 93, 0, 98, 112, 97, 100, 91, 52, 93, 0, 98, + 112, 97, 100, 49, 91, 52, 93, 0, 115, 112, 101, 99, 91, 52, 93, 0, 100, 117, 112, 102, 108, 97, 103, 0, 115, 97, 118, 101, 116, 105, 109, 101, + 0, 116, 101, 109, 112, 100, 105, 114, 91, 49, 54, 48, 93, 0, 102, 111, 110, 116, 100, 105, 114, 91, 49, 54, 48, 93, 0, 114, 101, 110, 100, 101, + 114, 100, 105, 114, 91, 49, 54, 48, 93, 0, 116, 101, 120, 116, 117, 100, 105, 114, 91, 49, 54, 48, 93, 0, 112, 108, 117, 103, 116, 101, 120, 100, + 105, 114, 91, 49, 54, 48, 93, 0, 112, 108, 117, 103, 115, 101, 113, 100, 105, 114, 91, 49, 54, 48, 93, 0, 112, 121, 116, 104, 111, 110, 100, 105, + 114, 91, 49, 54, 48, 93, 0, 115, 111, 117, 110, 100, 100, 105, 114, 91, 49, 54, 48, 93, 0, 121, 102, 101, 120, 112, 111, 114, 116, 100, 105, 114, + 91, 49, 54, 48, 93, 0, 118, 101, 114, 115, 105, 111, 110, 115, 0, 118, 114, 109, 108, 102, 108, 97, 103, 0, 103, 97, 109, 101, 102, 108, 97, 103, + 115, 0, 119, 104, 101, 101, 108, 108, 105, 110, 101, 115, 99, 114, 111, 108, 108, 0, 117, 105, 102, 108, 97, 103, 0, 108, 97, 110, 103, 117, 97, 103, + 101, 0, 117, 115, 101, 114, 112, 114, 101, 102, 0, 118, 105, 101, 119, 122, 111, 111, 109, 0, 99, 111, 110, 115, 111, 108, 101, 95, 98, 117, 102, 102, + 101, 114, 0, 99, 111, 110, 115, 111, 108, 101, 95, 111, 117, 116, 0, 109, 105, 120, 98, 117, 102, 115, 105, 122, 101, 0, 102, 111, 110, 116, 115, 105, + 122, 101, 0, 101, 110, 99, 111, 100, 105, 110, 103, 0, 116, 114, 97, 110, 115, 111, 112, 116, 115, 0, 109, 101, 110, 117, 116, 104, 114, 101, 115, 104, + 111, 108, 100, 49, 0, 109, 101, 110, 117, 116, 104, 114, 101, 115, 104, 111, 108, 100, 50, 0, 102, 111, 110, 116, 110, 97, 109, 101, 91, 50, 53, 54, + 93, 0, 116, 104, 101, 109, 101, 115, 0, 117, 110, 100, 111, 115, 116, 101, 112, 115, 0, 117, 110, 100, 111, 109, 101, 109, 111, 114, 121, 0, 103, 112, + 95, 109, 97, 110, 104, 97, 116, 116, 101, 110, 100, 105, 115, 116, 0, 103, 112, 95, 101, 117, 99, 108, 105, 100, 101, 97, 110, 100, 105, 115, 116, 0, + 103, 112, 95, 101, 114, 97, 115, 101, 114, 0, 103, 112, 95, 115, 101, 116, 116, 105, 110, 103, 115, 0, 116, 98, 95, 108, 101, 102, 116, 109, 111, 117, + 115, 101, 0, 116, 98, 95, 114, 105, 103, 104, 116, 109, 111, 117, 115, 101, 0, 108, 105, 103, 104, 116, 91, 51, 93, 0, 116, 119, 95, 104, 111, 116, + 115, 112, 111, 116, 0, 116, 119, 95, 102, 108, 97, 103, 0, 116, 119, 95, 104, 97, 110, 100, 108, 101, 115, 105, 122, 101, 0, 116, 119, 95, 115, 105, + 122, 101, 0, 116, 101, 120, 116, 105, 109, 101, 111, 117, 116, 0, 116, 101, 120, 99, 111, 108, 108, 101, 99, 116, 114, 97, 116, 101, 0, 109, 101, 109, + 99, 97, 99, 104, 101, 108, 105, 109, 105, 116, 0, 112, 114, 101, 102, 101, 116, 99, 104, 102, 114, 97, 109, 101, 115, 0, 102, 114, 97, 109, 101, 115, + 101, 114, 118, 101, 114, 112, 111, 114, 116, 0, 112, 97, 100, 95, 114, 111, 116, 95, 97, 110, 103, 108, 101, 0, 111, 98, 99, 101, 110, 116, 101, 114, + 95, 100, 105, 97, 0, 114, 118, 105, 115, 105, 122, 101, 0, 114, 118, 105, 98, 114, 105, 103, 104, 116, 0, 114, 101, 99, 101, 110, 116, 95, 102, 105, + 108, 101, 115, 0, 115, 109, 111, 111, 116, 104, 95, 118, 105, 101, 119, 116, 120, 0, 103, 108, 114, 101, 115, 108, 105, 109, 105, 116, 0, 110, 100, 111, + 102, 95, 112, 97, 110, 0, 110, 100, 111, 102, 95, 114, 111, 116, 97, 116, 101, 0, 99, 117, 114, 115, 115, 105, 122, 101, 0, 112, 97, 100, 91, 56, + 93, 0, 118, 101, 114, 115, 101, 109, 97, 115, 116, 101, 114, 91, 49, 54, 48, 93, 0, 118, 101, 114, 115, 101, 117, 115, 101, 114, 91, 49, 54, 48, + 93, 0, 103, 108, 97, 108, 112, 104, 97, 99, 108, 105, 112, 0, 97, 117, 116, 111, 107, 101, 121, 95, 102, 108, 97, 103, 0, 99, 111, 98, 97, 95, + 119, 101, 105, 103, 104, 116, 0, 118, 101, 114, 116, 98, 97, 115, 101, 0, 101, 100, 103, 101, 98, 97, 115, 101, 0, 97, 114, 101, 97, 98, 97, 115, + 101, 0, 42, 115, 99, 101, 110, 101, 0, 101, 110, 100, 120, 0, 101, 110, 100, 121, 0, 115, 105, 122, 101, 120, 0, 115, 105, 122, 101, 121, 0, 115, + 99, 101, 110, 101, 110, 114, 0, 115, 99, 114, 101, 101, 110, 110, 114, 0, 102, 117, 108, 108, 0, 109, 97, 105, 110, 119, 105, 110, 0, 119, 105, 110, + 97, 107, 116, 0, 104, 97, 110, 100, 108, 101, 114, 91, 56, 93, 0, 42, 110, 101, 119, 118, 0, 118, 101, 99, 0, 42, 118, 49, 0, 42, 118, 50, + 0, 112, 97, 110, 101, 108, 110, 97, 109, 101, 91, 54, 52, 93, 0, 116, 97, 98, 110, 97, 109, 101, 91, 54, 52, 93, 0, 100, 114, 97, 119, 110, + 97, 109, 101, 91, 54, 52, 93, 0, 111, 102, 115, 120, 0, 111, 102, 115, 121, 0, 99, 111, 110, 116, 114, 111, 108, 0, 115, 110, 97, 112, 0, 111, + 108, 100, 95, 111, 102, 115, 120, 0, 111, 108, 100, 95, 111, 102, 115, 121, 0, 115, 111, 114, 116, 99, 111, 117, 110, 116, 101, 114, 0, 42, 112, 97, + 110, 101, 108, 116, 97, 98, 0, 42, 118, 51, 0, 42, 118, 52, 0, 42, 102, 117, 108, 108, 0, 119, 105, 110, 109, 97, 116, 91, 52, 93, 91, 52, + 93, 0, 104, 101, 97, 100, 114, 99, 116, 0, 119, 105, 110, 114, 99, 116, 0, 104, 101, 97, 100, 119, 105, 110, 0, 119, 105, 110, 0, 104, 101, 97, + 100, 101, 114, 116, 121, 112, 101, 0, 98, 117, 116, 115, 112, 97, 99, 101, 116, 121, 112, 101, 0, 119, 105, 110, 120, 0, 119, 105, 110, 121, 0, 104, + 101, 97, 100, 95, 115, 119, 97, 112, 0, 104, 101, 97, 100, 95, 101, 113, 117, 97, 108, 0, 119, 105, 110, 95, 115, 119, 97, 112, 0, 119, 105, 110, + 95, 101, 113, 117, 97, 108, 0, 104, 101, 97, 100, 98, 117, 116, 108, 101, 110, 0, 104, 101, 97, 100, 98, 117, 116, 111, 102, 115, 0, 99, 117, 114, + 115, 111, 114, 0, 115, 112, 97, 99, 101, 100, 97, 116, 97, 0, 117, 105, 98, 108, 111, 99, 107, 115, 0, 112, 97, 110, 101, 108, 115, 0, 115, 117, + 98, 118, 115, 116, 114, 91, 52, 93, 0, 115, 117, 98, 118, 101, 114, 115, 105, 111, 110, 0, 112, 97, 100, 115, 0, 109, 105, 110, 118, 101, 114, 115, + 105, 111, 110, 0, 109, 105, 110, 115, 117, 98, 118, 101, 114, 115, 105, 111, 110, 0, 100, 105, 115, 112, 108, 97, 121, 109, 111, 100, 101, 0, 42, 99, + 117, 114, 115, 99, 114, 101, 101, 110, 0, 42, 99, 117, 114, 115, 99, 101, 110, 101, 0, 102, 105, 108, 101, 102, 108, 97, 103, 115, 0, 103, 108, 111, + 98, 97, 108, 102, 0, 110, 97, 109, 101, 91, 56, 48, 93, 0, 42, 105, 98, 117, 102, 0, 42, 105, 98, 117, 102, 95, 99, 111, 109, 112, 0, 42, + 115, 101, 49, 0, 42, 115, 101, 50, 0, 42, 115, 101, 51, 0, 110, 114, 0, 98, 111, 116, 116, 111, 109, 0, 114, 105, 103, 104, 116, 0, 120, 111, + 102, 115, 0, 121, 111, 102, 115, 0, 108, 105, 102, 116, 91, 51, 93, 0, 103, 97, 109, 109, 97, 91, 51, 93, 0, 103, 97, 105, 110, 91, 51, 93, + 0, 115, 97, 116, 117, 114, 97, 116, 105, 111, 110, 0, 42, 103, 117, 105, 0, 100, 105, 114, 91, 49, 54, 48, 93, 0, 100, 111, 110, 101, 0, 115, + 116, 97, 114, 116, 115, 116, 105, 108, 108, 0, 101, 110, 100, 115, 116, 105, 108, 108, 0, 42, 115, 116, 114, 105, 112, 100, 97, 116, 97, 0, 111, 114, + 120, 0, 111, 114, 121, 0, 42, 99, 114, 111, 112, 0, 42, 116, 114, 97, 110, 115, 102, 111, 114, 109, 0, 42, 99, 111, 108, 111, 114, 95, 98, 97, + 108, 97, 110, 99, 101, 0, 42, 116, 115, 116, 114, 105, 112, 100, 97, 116, 97, 0, 42, 116, 115, 116, 114, 105, 112, 100, 97, 116, 97, 95, 115, 116, + 97, 114, 116, 115, 116, 105, 108, 108, 0, 42, 116, 115, 116, 114, 105, 112, 100, 97, 116, 97, 95, 101, 110, 100, 115, 116, 105, 108, 108, 0, 42, 105, + 98, 117, 102, 95, 115, 116, 97, 114, 116, 115, 116, 105, 108, 108, 0, 42, 105, 98, 117, 102, 95, 101, 110, 100, 115, 116, 105, 108, 108, 0, 42, 105, + 110, 115, 116, 97, 110, 99, 101, 95, 112, 114, 105, 118, 97, 116, 101, 95, 100, 97, 116, 97, 0, 42, 42, 99, 117, 114, 114, 101, 110, 116, 95, 112, + 114, 105, 118, 97, 116, 101, 95, 100, 97, 116, 97, 0, 42, 116, 109, 112, 0, 115, 116, 97, 114, 116, 111, 102, 115, 0, 101, 110, 100, 111, 102, 115, + 0, 109, 97, 99, 104, 105, 110, 101, 0, 115, 116, 97, 114, 116, 100, 105, 115, 112, 0, 101, 110, 100, 100, 105, 115, 112, 0, 109, 117, 108, 0, 104, + 97, 110, 100, 115, 105, 122, 101, 0, 97, 110, 105, 109, 95, 112, 114, 101, 115, 101, 101, 107, 0, 42, 115, 116, 114, 105, 112, 0, 102, 97, 99, 102, + 48, 0, 102, 97, 99, 102, 49, 0, 42, 115, 101, 113, 49, 0, 42, 115, 101, 113, 50, 0, 42, 115, 101, 113, 51, 0, 115, 101, 113, 98, 97, 115, + 101, 0, 42, 115, 111, 117, 110, 100, 0, 42, 104, 100, 97, 117, 100, 105, 111, 0, 108, 101, 118, 101, 108, 0, 112, 97, 110, 0, 115, 116, 114, 111, + 98, 101, 0, 42, 101, 102, 102, 101, 99, 116, 100, 97, 116, 97, 0, 97, 110, 105, 109, 95, 115, 116, 97, 114, 116, 111, 102, 115, 0, 97, 110, 105, + 109, 95, 101, 110, 100, 111, 102, 115, 0, 98, 108, 101, 110, 100, 95, 109, 111, 100, 101, 0, 98, 108, 101, 110, 100, 95, 111, 112, 97, 99, 105, 116, + 121, 0, 42, 111, 108, 100, 98, 97, 115, 101, 112, 0, 42, 112, 97, 114, 115, 101, 113, 0, 42, 115, 101, 113, 98, 97, 115, 101, 112, 0, 109, 101, + 116, 97, 115, 116, 97, 99, 107, 0, 101, 100, 103, 101, 87, 105, 100, 116, 104, 0, 102, 111, 114, 119, 97, 114, 100, 0, 119, 105, 112, 101, 116, 121, + 112, 101, 0, 102, 77, 105, 110, 105, 0, 102, 67, 108, 97, 109, 112, 0, 102, 66, 111, 111, 115, 116, 0, 100, 68, 105, 115, 116, 0, 100, 81, 117, + 97, 108, 105, 116, 121, 0, 98, 78, 111, 67, 111, 109, 112, 0, 83, 99, 97, 108, 101, 120, 73, 110, 105, 0, 83, 99, 97, 108, 101, 121, 73, 110, + 105, 0, 83, 99, 97, 108, 101, 120, 70, 105, 110, 0, 83, 99, 97, 108, 101, 121, 70, 105, 110, 0, 120, 73, 110, 105, 0, 120, 70, 105, 110, 0, + 121, 73, 110, 105, 0, 121, 70, 105, 110, 0, 114, 111, 116, 73, 110, 105, 0, 114, 111, 116, 70, 105, 110, 0, 105, 110, 116, 101, 114, 112, 111, 108, + 97, 116, 105, 111, 110, 0, 42, 102, 114, 97, 109, 101, 77, 97, 112, 0, 103, 108, 111, 98, 97, 108, 83, 112, 101, 101, 100, 0, 108, 97, 115, 116, + 86, 97, 108, 105, 100, 70, 114, 97, 109, 101, 0, 98, 108, 101, 110, 100, 70, 114, 97, 109, 101, 115, 0, 98, 117, 116, 116, 121, 112, 101, 0, 117, + 115, 101, 114, 106, 105, 116, 0, 115, 116, 97, 0, 116, 111, 116, 112, 97, 114, 116, 0, 110, 111, 114, 109, 102, 97, 99, 0, 111, 98, 102, 97, 99, + 0, 114, 97, 110, 100, 102, 97, 99, 0, 116, 101, 120, 102, 97, 99, 0, 114, 97, 110, 100, 108, 105, 102, 101, 0, 102, 111, 114, 99, 101, 91, 51, + 93, 0, 118, 101, 99, 116, 115, 105, 122, 101, 0, 109, 97, 120, 108, 101, 110, 0, 100, 101, 102, 118, 101, 99, 91, 51, 93, 0, 109, 117, 108, 116, + 91, 52, 93, 0, 108, 105, 102, 101, 91, 52, 93, 0, 99, 104, 105, 108, 100, 91, 52, 93, 0, 109, 97, 116, 91, 52, 93, 0, 116, 101, 120, 109, + 97, 112, 0, 99, 117, 114, 109, 117, 108, 116, 0, 115, 116, 97, 116, 105, 99, 115, 116, 101, 112, 0, 111, 109, 97, 116, 0, 116, 105, 109, 101, 116, + 101, 120, 0, 115, 112, 101, 101, 100, 116, 101, 120, 0, 102, 108, 97, 103, 50, 110, 101, 103, 0, 118, 101, 114, 116, 103, 114, 111, 117, 112, 95, 118, + 0, 118, 103, 114, 111, 117, 112, 110, 97, 109, 101, 91, 51, 50, 93, 0, 118, 103, 114, 111, 117, 112, 110, 97, 109, 101, 95, 118, 91, 51, 50, 93, + 0, 42, 107, 101, 121, 115, 0, 109, 105, 110, 102, 97, 99, 0, 117, 115, 101, 100, 0, 117, 115, 101, 100, 101, 108, 101, 109, 0, 100, 120, 0, 100, + 121, 0, 108, 105, 110, 107, 0, 111, 116, 121, 112, 101, 0, 111, 108, 100, 0, 42, 112, 111, 105, 110, 0, 42, 111, 108, 100, 112, 111, 105, 110, 0, + 114, 101, 115, 101, 116, 100, 105, 115, 116, 0, 108, 97, 115, 116, 118, 97, 108, 0, 42, 109, 97, 0, 107, 101, 121, 0, 113, 117, 97, 108, 0, 113, + 117, 97, 108, 50, 0, 116, 97, 114, 103, 101, 116, 78, 97, 109, 101, 91, 51, 50, 93, 0, 116, 111, 103, 103, 108, 101, 78, 97, 109, 101, 91, 51, + 50, 93, 0, 118, 97, 108, 117, 101, 91, 51, 50, 93, 0, 109, 97, 120, 118, 97, 108, 117, 101, 91, 51, 50, 93, 0, 100, 101, 108, 97, 121, 0, + 100, 117, 114, 97, 116, 105, 111, 110, 0, 109, 97, 116, 101, 114, 105, 97, 108, 78, 97, 109, 101, 91, 51, 50, 93, 0, 100, 97, 109, 112, 116, 105, + 109, 101, 114, 0, 112, 114, 111, 112, 110, 97, 109, 101, 91, 51, 50, 93, 0, 109, 97, 116, 110, 97, 109, 101, 91, 51, 50, 93, 0, 97, 120, 105, + 115, 102, 108, 97, 103, 0, 42, 102, 114, 111, 109, 79, 98, 106, 101, 99, 116, 0, 115, 117, 98, 106, 101, 99, 116, 91, 51, 50, 93, 0, 98, 111, + 100, 121, 91, 51, 50, 93, 0, 112, 117, 108, 115, 101, 0, 102, 114, 101, 113, 0, 116, 111, 116, 108, 105, 110, 107, 115, 0, 42, 42, 108, 105, 110, + 107, 115, 0, 116, 97, 112, 0, 106, 111, 121, 105, 110, 100, 101, 120, 0, 97, 120, 105, 115, 95, 115, 105, 110, 103, 108, 101, 0, 97, 120, 105, 115, + 102, 0, 98, 117, 116, 116, 111, 110, 0, 104, 97, 116, 0, 104, 97, 116, 102, 0, 112, 114, 101, 99, 105, 115, 105, 111, 110, 0, 115, 116, 114, 91, + 49, 50, 56, 93, 0, 109, 111, 100, 117, 108, 101, 91, 54, 52, 93, 0, 42, 109, 121, 110, 101, 119, 0, 105, 110, 112, 117, 116, 115, 0, 116, 111, + 116, 115, 108, 105, 110, 107, 115, 0, 42, 42, 115, 108, 105, 110, 107, 115, 0, 118, 97, 108, 111, 0, 115, 116, 97, 116, 101, 95, 109, 97, 115, 107, + 0, 42, 97, 99, 116, 0, 102, 114, 97, 109, 101, 80, 114, 111, 112, 91, 51, 50, 93, 0, 98, 108, 101, 110, 100, 105, 110, 0, 112, 114, 105, 111, + 114, 105, 116, 121, 0, 101, 110, 100, 95, 114, 101, 115, 101, 116, 0, 115, 116, 114, 105, 100, 101, 97, 120, 105, 115, 0, 115, 116, 114, 105, 100, 101, + 108, 101, 110, 103, 116, 104, 0, 115, 110, 100, 110, 114, 0, 112, 97, 100, 49, 91, 50, 93, 0, 109, 97, 107, 101, 99, 111, 112, 121, 0, 99, 111, + 112, 121, 109, 97, 100, 101, 0, 112, 97, 100, 50, 91, 49, 93, 0, 116, 114, 97, 99, 107, 0, 42, 109, 101, 0, 108, 105, 110, 86, 101, 108, 111, + 99, 105, 116, 121, 91, 51, 93, 0, 97, 110, 103, 86, 101, 108, 111, 99, 105, 116, 121, 91, 51, 93, 0, 108, 111, 99, 97, 108, 102, 108, 97, 103, + 0, 100, 121, 110, 95, 111, 112, 101, 114, 97, 116, 105, 111, 110, 0, 102, 111, 114, 99, 101, 108, 111, 99, 91, 51, 93, 0, 102, 111, 114, 99, 101, + 114, 111, 116, 91, 51, 93, 0, 108, 105, 110, 101, 97, 114, 118, 101, 108, 111, 99, 105, 116, 121, 91, 51, 93, 0, 97, 110, 103, 117, 108, 97, 114, + 118, 101, 108, 111, 99, 105, 116, 121, 91, 51, 93, 0, 42, 114, 101, 102, 101, 114, 101, 110, 99, 101, 0, 98, 117, 116, 115, 116, 97, 0, 98, 117, + 116, 101, 110, 100, 0, 109, 105, 110, 0, 109, 97, 120, 0, 118, 105, 115, 105, 102, 97, 99, 0, 114, 111, 116, 100, 97, 109, 112, 0, 109, 105, 110, + 108, 111, 99, 91, 51, 93, 0, 109, 97, 120, 108, 111, 99, 91, 51, 93, 0, 109, 105, 110, 114, 111, 116, 91, 51, 93, 0, 109, 97, 120, 114, 111, + 116, 91, 51, 93, 0, 109, 97, 116, 112, 114, 111, 112, 91, 51, 50, 93, 0, 100, 105, 115, 116, 114, 105, 98, 117, 116, 105, 111, 110, 0, 105, 110, + 116, 95, 97, 114, 103, 95, 49, 0, 105, 110, 116, 95, 97, 114, 103, 95, 50, 0, 102, 108, 111, 97, 116, 95, 97, 114, 103, 95, 49, 0, 102, 108, + 111, 97, 116, 95, 97, 114, 103, 95, 50, 0, 116, 111, 80, 114, 111, 112, 78, 97, 109, 101, 91, 51, 50, 93, 0, 42, 116, 111, 79, 98, 106, 101, + 99, 116, 0, 98, 111, 100, 121, 84, 121, 112, 101, 0, 102, 105, 108, 101, 110, 97, 109, 101, 91, 54, 52, 93, 0, 108, 111, 97, 100, 97, 110, 105, + 110, 97, 109, 101, 91, 54, 52, 93, 0, 105, 110, 116, 95, 97, 114, 103, 0, 102, 108, 111, 97, 116, 95, 97, 114, 103, 0, 103, 111, 0, 97, 99, + 99, 101, 108, 108, 101, 114, 97, 116, 105, 111, 110, 0, 109, 97, 120, 115, 112, 101, 101, 100, 0, 109, 97, 120, 114, 111, 116, 115, 112, 101, 101, 100, + 0, 109, 97, 120, 116, 105, 108, 116, 115, 112, 101, 101, 100, 0, 116, 105, 108, 116, 100, 97, 109, 112, 0, 115, 112, 101, 101, 100, 100, 97, 109, 112, + 0, 42, 115, 97, 109, 112, 108, 101, 0, 42, 115, 116, 114, 101, 97, 109, 0, 42, 110, 101, 119, 112, 97, 99, 107, 101, 100, 102, 105, 108, 101, 0, + 42, 115, 110, 100, 95, 115, 111, 117, 110, 100, 0, 112, 97, 110, 110, 105, 110, 103, 0, 97, 116, 116, 101, 110, 117, 97, 116, 105, 111, 110, 0, 112, + 105, 116, 99, 104, 0, 109, 105, 110, 95, 103, 97, 105, 110, 0, 109, 97, 120, 95, 103, 97, 105, 110, 0, 100, 105, 115, 116, 97, 110, 99, 101, 0, + 115, 116, 114, 101, 97, 109, 108, 101, 110, 0, 99, 104, 97, 110, 110, 101, 108, 115, 0, 104, 105, 103, 104, 112, 114, 105, 111, 0, 112, 97, 100, 91, + 49, 48, 93, 0, 103, 97, 105, 110, 0, 100, 111, 112, 112, 108, 101, 114, 102, 97, 99, 116, 111, 114, 0, 100, 111, 112, 112, 108, 101, 114, 118, 101, + 108, 111, 99, 105, 116, 121, 0, 110, 117, 109, 115, 111, 117, 110, 100, 115, 98, 108, 101, 110, 100, 101, 114, 0, 110, 117, 109, 115, 111, 117, 110, 100, + 115, 103, 97, 109, 101, 101, 110, 103, 105, 110, 101, 0, 42, 108, 97, 109, 112, 114, 101, 110, 0, 103, 111, 98, 106, 101, 99, 116, 0, 100, 117, 112, + 108, 105, 95, 111, 102, 115, 91, 51, 93, 0, 99, 104, 105, 108, 100, 98, 97, 115, 101, 0, 114, 111, 108, 108, 0, 104, 101, 97, 100, 91, 51, 93, + 0, 116, 97, 105, 108, 91, 51, 93, 0, 98, 111, 110, 101, 95, 109, 97, 116, 91, 51, 93, 91, 51, 93, 0, 97, 114, 109, 95, 104, 101, 97, 100, + 91, 51, 93, 0, 97, 114, 109, 95, 116, 97, 105, 108, 91, 51, 93, 0, 97, 114, 109, 95, 109, 97, 116, 91, 52, 93, 91, 52, 93, 0, 120, 119, + 105, 100, 116, 104, 0, 122, 119, 105, 100, 116, 104, 0, 101, 97, 115, 101, 49, 0, 101, 97, 115, 101, 50, 0, 114, 97, 100, 95, 104, 101, 97, 100, + 0, 114, 97, 100, 95, 116, 97, 105, 108, 0, 98, 111, 110, 101, 98, 97, 115, 101, 0, 99, 104, 97, 105, 110, 98, 97, 115, 101, 0, 112, 97, 116, + 104, 102, 108, 97, 103, 0, 108, 97, 121, 101, 114, 95, 112, 114, 111, 116, 101, 99, 116, 101, 100, 0, 103, 104, 111, 115, 116, 101, 112, 0, 103, 104, + 111, 115, 116, 115, 105, 122, 101, 0, 103, 104, 111, 115, 116, 116, 121, 112, 101, 0, 112, 97, 116, 104, 115, 105, 122, 101, 0, 103, 104, 111, 115, 116, + 115, 102, 0, 103, 104, 111, 115, 116, 101, 102, 0, 112, 97, 116, 104, 115, 102, 0, 112, 97, 116, 104, 101, 102, 0, 112, 97, 116, 104, 98, 99, 0, + 112, 97, 116, 104, 97, 99, 0, 99, 111, 110, 115, 116, 102, 108, 97, 103, 0, 105, 107, 102, 108, 97, 103, 0, 115, 101, 108, 101, 99, 116, 102, 108, + 97, 103, 0, 97, 103, 114, 112, 95, 105, 110, 100, 101, 120, 0, 42, 98, 111, 110, 101, 0, 42, 99, 104, 105, 108, 100, 0, 105, 107, 116, 114, 101, + 101, 0, 42, 98, 95, 98, 111, 110, 101, 95, 109, 97, 116, 115, 0, 42, 100, 117, 97, 108, 95, 113, 117, 97, 116, 0, 42, 98, 95, 98, 111, 110, + 101, 95, 100, 117, 97, 108, 95, 113, 117, 97, 116, 115, 0, 99, 104, 97, 110, 95, 109, 97, 116, 91, 52, 93, 91, 52, 93, 0, 112, 111, 115, 101, + 95, 109, 97, 116, 91, 52, 93, 91, 52, 93, 0, 112, 111, 115, 101, 95, 104, 101, 97, 100, 91, 51, 93, 0, 112, 111, 115, 101, 95, 116, 97, 105, + 108, 91, 51, 93, 0, 108, 105, 109, 105, 116, 109, 105, 110, 91, 51, 93, 0, 108, 105, 109, 105, 116, 109, 97, 120, 91, 51, 93, 0, 115, 116, 105, + 102, 102, 110, 101, 115, 115, 91, 51, 93, 0, 105, 107, 115, 116, 114, 101, 116, 99, 104, 0, 42, 99, 117, 115, 116, 111, 109, 0, 99, 104, 97, 110, + 98, 97, 115, 101, 0, 112, 114, 111, 120, 121, 95, 108, 97, 121, 101, 114, 0, 115, 116, 114, 105, 100, 101, 95, 111, 102, 102, 115, 101, 116, 91, 51, + 93, 0, 99, 121, 99, 108, 105, 99, 95, 111, 102, 102, 115, 101, 116, 91, 51, 93, 0, 97, 103, 114, 111, 117, 112, 115, 0, 97, 99, 116, 105, 118, + 101, 95, 103, 114, 111, 117, 112, 0, 99, 117, 115, 116, 111, 109, 67, 111, 108, 0, 99, 115, 0, 42, 103, 114, 112, 0, 114, 101, 115, 101, 114, 118, + 101, 100, 49, 0, 103, 114, 111, 117, 112, 115, 0, 97, 99, 116, 105, 118, 101, 95, 109, 97, 114, 107, 101, 114, 0, 97, 99, 116, 110, 114, 0, 97, + 99, 116, 119, 105, 100, 116, 104, 0, 116, 105, 109, 101, 115, 108, 105, 100, 101, 0, 110, 97, 109, 101, 91, 51, 48, 93, 0, 111, 119, 110, 115, 112, + 97, 99, 101, 0, 116, 97, 114, 115, 112, 97, 99, 101, 0, 101, 110, 102, 111, 114, 99, 101, 0, 104, 101, 97, 100, 116, 97, 105, 108, 0, 42, 116, + 97, 114, 0, 115, 117, 98, 116, 97, 114, 103, 101, 116, 91, 51, 50, 93, 0, 109, 97, 116, 114, 105, 120, 91, 52, 93, 91, 52, 93, 0, 115, 112, + 97, 99, 101, 0, 42, 112, 114, 111, 112, 0, 116, 97, 114, 110, 117, 109, 0, 116, 97, 114, 103, 101, 116, 115, 0, 105, 116, 101, 114, 97, 116, 105, + 111, 110, 115, 0, 114, 111, 111, 116, 98, 111, 110, 101, 0, 109, 97, 120, 95, 114, 111, 111, 116, 98, 111, 110, 101, 0, 42, 112, 111, 108, 101, 116, + 97, 114, 0, 112, 111, 108, 101, 115, 117, 98, 116, 97, 114, 103, 101, 116, 91, 51, 50, 93, 0, 112, 111, 108, 101, 97, 110, 103, 108, 101, 0, 111, + 114, 105, 101, 110, 116, 119, 101, 105, 103, 104, 116, 0, 103, 114, 97, 98, 116, 97, 114, 103, 101, 116, 91, 51, 93, 0, 114, 101, 115, 101, 114, 118, + 101, 100, 50, 0, 109, 105, 110, 109, 97, 120, 102, 108, 97, 103, 0, 115, 116, 117, 99, 107, 0, 99, 97, 99, 104, 101, 91, 51, 93, 0, 108, 111, + 99, 107, 102, 108, 97, 103, 0, 102, 111, 108, 108, 111, 119, 102, 108, 97, 103, 0, 118, 111, 108, 109, 111, 100, 101, 0, 112, 108, 97, 110, 101, 0, + 111, 114, 103, 108, 101, 110, 103, 116, 104, 0, 98, 117, 108, 103, 101, 0, 112, 105, 118, 88, 0, 112, 105, 118, 89, 0, 112, 105, 118, 90, 0, 97, + 120, 88, 0, 97, 120, 89, 0, 97, 120, 90, 0, 109, 105, 110, 76, 105, 109, 105, 116, 91, 54, 93, 0, 109, 97, 120, 76, 105, 109, 105, 116, 91, + 54, 93, 0, 101, 120, 116, 114, 97, 70, 122, 0, 105, 110, 118, 109, 97, 116, 91, 52, 93, 91, 52, 93, 0, 102, 114, 111, 109, 0, 116, 111, 0, + 109, 97, 112, 91, 51, 93, 0, 101, 120, 112, 111, 0, 102, 114, 111, 109, 95, 109, 105, 110, 91, 51, 93, 0, 102, 114, 111, 109, 95, 109, 97, 120, + 91, 51, 93, 0, 116, 111, 95, 109, 105, 110, 91, 51, 93, 0, 116, 111, 95, 109, 97, 120, 91, 51, 93, 0, 122, 109, 105, 110, 0, 122, 109, 97, + 120, 0, 112, 97, 100, 91, 57, 93, 0, 99, 104, 97, 110, 110, 101, 108, 91, 51, 50, 93, 0, 110, 111, 95, 114, 111, 116, 95, 97, 120, 105, 115, + 0, 115, 116, 114, 105, 100, 101, 95, 97, 120, 105, 115, 0, 99, 117, 114, 109, 111, 100, 0, 97, 99, 116, 115, 116, 97, 114, 116, 0, 97, 99, 116, + 101, 110, 100, 0, 97, 99, 116, 111, 102, 102, 115, 0, 115, 116, 114, 105, 100, 101, 108, 101, 110, 0, 98, 108, 101, 110, 100, 111, 117, 116, 0, 115, + 116, 114, 105, 100, 101, 99, 104, 97, 110, 110, 101, 108, 91, 51, 50, 93, 0, 111, 102, 102, 115, 95, 98, 111, 110, 101, 91, 51, 50, 93, 0, 104, + 97, 115, 105, 110, 112, 117, 116, 0, 104, 97, 115, 111, 117, 116, 112, 117, 116, 0, 100, 97, 116, 97, 116, 121, 112, 101, 0, 115, 111, 99, 107, 101, + 116, 116, 121, 112, 101, 0, 42, 110, 101, 119, 95, 115, 111, 99, 107, 0, 110, 115, 0, 108, 105, 109, 105, 116, 0, 115, 116, 97, 99, 107, 95, 105, + 110, 100, 101, 120, 0, 105, 110, 116, 101, 114, 110, 0, 115, 116, 97, 99, 107, 95, 105, 110, 100, 101, 120, 95, 101, 120, 116, 0, 108, 111, 99, 120, + 0, 108, 111, 99, 121, 0, 111, 119, 110, 95, 105, 110, 100, 101, 120, 0, 116, 111, 95, 105, 110, 100, 101, 120, 0, 42, 116, 111, 115, 111, 99, 107, + 0, 42, 108, 105, 110, 107, 0, 42, 110, 101, 119, 95, 110, 111, 100, 101, 0, 117, 115, 101, 114, 110, 97, 109, 101, 91, 51, 50, 93, 0, 108, 97, + 115, 116, 121, 0, 111, 117, 116, 112, 117, 116, 115, 0, 42, 115, 116, 111, 114, 97, 103, 101, 0, 109, 105, 110, 105, 119, 105, 100, 116, 104, 0, 99, + 117, 115, 116, 111, 109, 49, 0, 99, 117, 115, 116, 111, 109, 50, 0, 99, 117, 115, 116, 111, 109, 51, 0, 99, 117, 115, 116, 111, 109, 52, 0, 110, + 101, 101, 100, 95, 101, 120, 101, 99, 0, 101, 120, 101, 99, 0, 116, 111, 116, 114, 0, 98, 117, 116, 114, 0, 112, 114, 118, 114, 0, 42, 116, 121, + 112, 101, 105, 110, 102, 111, 0, 42, 102, 114, 111, 109, 110, 111, 100, 101, 0, 42, 116, 111, 110, 111, 100, 101, 0, 42, 102, 114, 111, 109, 115, 111, + 99, 107, 0, 110, 111, 100, 101, 115, 0, 108, 105, 110, 107, 115, 0, 42, 115, 116, 97, 99, 107, 0, 42, 116, 104, 114, 101, 97, 100, 115, 116, 97, + 99, 107, 0, 105, 110, 105, 116, 0, 115, 116, 97, 99, 107, 115, 105, 122, 101, 0, 99, 117, 114, 95, 105, 110, 100, 101, 120, 0, 97, 108, 108, 116, + 121, 112, 101, 115, 0, 42, 111, 119, 110, 116, 121, 112, 101, 0, 42, 115, 101, 108, 105, 110, 0, 42, 115, 101, 108, 111, 117, 116, 0, 40, 42, 116, + 105, 109, 101, 99, 117, 114, 115, 111, 114, 41, 40, 41, 0, 40, 42, 115, 116, 97, 116, 115, 95, 100, 114, 97, 119, 41, 40, 41, 0, 40, 42, 116, + 101, 115, 116, 95, 98, 114, 101, 97, 107, 41, 40, 41, 0, 99, 121, 99, 108, 105, 99, 0, 109, 111, 118, 105, 101, 0, 115, 97, 109, 112, 108, 101, + 115, 0, 109, 105, 110, 115, 112, 101, 101, 100, 0, 112, 101, 114, 99, 101, 110, 116, 120, 0, 112, 101, 114, 99, 101, 110, 116, 121, 0, 98, 111, 107, + 101, 104, 0, 99, 117, 114, 118, 101, 100, 0, 105, 109, 97, 103, 101, 95, 105, 110, 95, 119, 105, 100, 116, 104, 0, 105, 109, 97, 103, 101, 95, 105, + 110, 95, 104, 101, 105, 103, 104, 116, 0, 99, 101, 110, 116, 101, 114, 95, 120, 0, 99, 101, 110, 116, 101, 114, 95, 121, 0, 115, 112, 105, 110, 0, + 105, 116, 101, 114, 0, 119, 114, 97, 112, 0, 115, 105, 103, 109, 97, 95, 99, 111, 108, 111, 114, 0, 115, 105, 103, 109, 97, 95, 115, 112, 97, 99, + 101, 0, 104, 117, 101, 0, 115, 97, 116, 0, 116, 49, 0, 116, 50, 0, 116, 51, 0, 102, 115, 116, 114, 101, 110, 103, 116, 104, 0, 102, 97, 108, + 112, 104, 97, 0, 107, 101, 121, 91, 52, 93, 0, 120, 49, 0, 120, 50, 0, 121, 49, 0, 121, 50, 0, 99, 111, 108, 110, 97, 109, 101, 91, 51, + 50, 93, 0, 98, 107, 116, 121, 112, 101, 0, 114, 111, 116, 97, 116, 105, 111, 110, 0, 112, 114, 101, 118, 105, 101, 119, 0, 103, 97, 109, 99, 111, + 0, 110, 111, 95, 122, 98, 117, 102, 0, 102, 115, 116, 111, 112, 0, 109, 97, 120, 98, 108, 117, 114, 0, 98, 116, 104, 114, 101, 115, 104, 0, 42, + 100, 105, 99, 116, 0, 42, 110, 111, 100, 101, 0, 97, 110, 103, 108, 101, 95, 111, 102, 115, 0, 99, 111, 108, 109, 111, 100, 0, 109, 105, 120, 0, + 116, 104, 114, 101, 115, 104, 111, 108, 100, 0, 102, 97, 100, 101, 0, 109, 0, 99, 0, 106, 105, 116, 0, 112, 114, 111, 106, 0, 102, 105, 116, 0, + 115, 104, 111, 114, 116, 121, 0, 109, 105, 110, 116, 97, 98, 108, 101, 0, 109, 97, 120, 116, 97, 98, 108, 101, 0, 101, 120, 116, 95, 105, 110, 91, + 50, 93, 0, 101, 120, 116, 95, 111, 117, 116, 91, 50, 93, 0, 42, 99, 117, 114, 118, 101, 0, 42, 116, 97, 98, 108, 101, 0, 42, 112, 114, 101, + 109, 117, 108, 116, 97, 98, 108, 101, 0, 99, 117, 114, 114, 0, 99, 108, 105, 112, 114, 0, 99, 109, 91, 52, 93, 0, 98, 108, 97, 99, 107, 91, + 51, 93, 0, 119, 104, 105, 116, 101, 91, 51, 93, 0, 98, 119, 109, 117, 108, 91, 51, 93, 0, 115, 97, 109, 112, 108, 101, 91, 51, 93, 0, 111, + 102, 102, 115, 101, 116, 91, 50, 93, 0, 105, 110, 110, 101, 114, 114, 97, 100, 105, 117, 115, 0, 114, 97, 116, 101, 0, 114, 103, 98, 91, 51, 93, + 0, 99, 108, 111, 110, 101, 0, 97, 99, 116, 105, 118, 101, 95, 114, 110, 100, 0, 97, 99, 116, 105, 118, 101, 95, 99, 108, 111, 110, 101, 0, 97, + 99, 116, 105, 118, 101, 95, 109, 97, 115, 107, 0, 42, 108, 97, 121, 101, 114, 115, 0, 116, 111, 116, 108, 97, 121, 101, 114, 0, 109, 97, 120, 108, + 97, 121, 101, 114, 0, 116, 111, 116, 115, 105, 122, 101, 0, 42, 112, 111, 111, 108, 0, 101, 100, 105, 116, 102, 108, 97, 103, 0, 118, 101, 108, 91, + 51, 93, 0, 114, 111, 116, 91, 52, 93, 0, 97, 118, 101, 91, 51, 93, 0, 110, 117, 109, 0, 112, 97, 114, 101, 110, 116, 0, 112, 97, 91, 52, + 93, 0, 119, 91, 52, 93, 0, 102, 117, 118, 91, 52, 93, 0, 102, 111, 102, 102, 115, 101, 116, 0, 114, 97, 110, 100, 91, 51, 93, 0, 42, 115, + 116, 105, 99, 107, 95, 111, 98, 0, 112, 114, 101, 118, 95, 115, 116, 97, 116, 101, 0, 42, 104, 97, 105, 114, 0, 105, 95, 114, 111, 116, 91, 52, + 93, 0, 114, 95, 114, 111, 116, 91, 52, 93, 0, 114, 95, 97, 118, 101, 91, 51, 93, 0, 114, 95, 118, 101, 91, 51, 93, 0, 100, 105, 101, 116, + 105, 109, 101, 0, 98, 97, 110, 107, 0, 115, 105, 122, 101, 109, 117, 108, 0, 110, 117, 109, 95, 100, 109, 99, 97, 99, 104, 101, 0, 98, 112, 105, + 0, 97, 108, 105, 118, 101, 0, 108, 111, 111, 112, 0, 100, 105, 115, 116, 114, 0, 112, 104, 121, 115, 116, 121, 112, 101, 0, 114, 111, 116, 109, 111, + 100, 101, 0, 97, 118, 101, 109, 111, 100, 101, 0, 114, 101, 97, 99, 116, 101, 118, 101, 110, 116, 0, 100, 114, 97, 119, 0, 100, 114, 97, 119, 95, + 97, 115, 0, 100, 114, 97, 119, 95, 115, 105, 122, 101, 0, 99, 104, 105, 108, 100, 116, 121, 112, 101, 0, 100, 114, 97, 119, 95, 115, 116, 101, 112, + 0, 114, 101, 110, 95, 115, 116, 101, 112, 0, 104, 97, 105, 114, 95, 115, 116, 101, 112, 0, 107, 101, 121, 115, 95, 115, 116, 101, 112, 0, 97, 100, + 97, 112, 116, 95, 97, 110, 103, 108, 101, 0, 97, 100, 97, 112, 116, 95, 112, 105, 120, 0, 114, 111, 116, 102, 114, 111, 109, 0, 105, 110, 116, 101, + 103, 114, 97, 116, 111, 114, 0, 110, 98, 101, 116, 119, 101, 101, 110, 0, 98, 111, 105, 100, 110, 101, 105, 103, 104, 98, 111, 117, 114, 115, 0, 98, + 98, 95, 97, 108, 105, 103, 110, 0, 98, 98, 95, 117, 118, 95, 115, 112, 108, 105, 116, 0, 98, 98, 95, 97, 110, 105, 109, 0, 98, 98, 95, 115, + 112, 108, 105, 116, 95, 111, 102, 102, 115, 101, 116, 0, 98, 98, 95, 116, 105, 108, 116, 0, 98, 98, 95, 114, 97, 110, 100, 95, 116, 105, 108, 116, + 0, 98, 98, 95, 111, 102, 102, 115, 101, 116, 91, 50, 93, 0, 115, 105, 109, 112, 108, 105, 102, 121, 95, 102, 108, 97, 103, 0, 115, 105, 109, 112, + 108, 105, 102, 121, 95, 114, 101, 102, 115, 105, 122, 101, 0, 115, 105, 109, 112, 108, 105, 102, 121, 95, 114, 97, 116, 101, 0, 115, 105, 109, 112, 108, + 105, 102, 121, 95, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 115, 105, 109, 112, 108, 105, 102, 121, 95, 118, 105, 101, 119, 112, 111, 114, 116, + 0, 116, 105, 109, 101, 116, 119, 101, 97, 107, 0, 106, 105, 116, 102, 97, 99, 0, 107, 101, 121, 101, 100, 95, 116, 105, 109, 101, 0, 101, 102, 102, + 95, 104, 97, 105, 114, 0, 103, 114, 105, 100, 95, 114, 101, 115, 0, 112, 97, 114, 116, 102, 97, 99, 0, 116, 97, 110, 102, 97, 99, 0, 116, 97, + 110, 112, 104, 97, 115, 101, 0, 114, 101, 97, 99, 116, 102, 97, 99, 0, 97, 118, 101, 102, 97, 99, 0, 112, 104, 97, 115, 101, 102, 97, 99, 0, + 114, 97, 110, 100, 114, 111, 116, 102, 97, 99, 0, 114, 97, 110, 100, 112, 104, 97, 115, 101, 102, 97, 99, 0, 114, 97, 110, 100, 115, 105, 122, 101, + 0, 114, 101, 97, 99, 116, 115, 104, 97, 112, 101, 0, 97, 99, 99, 91, 51, 93, 0, 100, 114, 97, 103, 102, 97, 99, 0, 98, 114, 111, 119, 110, + 102, 97, 99, 0, 100, 97, 109, 112, 102, 97, 99, 0, 97, 98, 115, 108, 101, 110, 103, 116, 104, 0, 114, 97, 110, 100, 108, 101, 110, 103, 116, 104, + 0, 99, 104, 105, 108, 100, 95, 110, 98, 114, 0, 114, 101, 110, 95, 99, 104, 105, 108, 100, 95, 110, 98, 114, 0, 112, 97, 114, 101, 110, 116, 115, + 0, 99, 104, 105, 108, 100, 115, 105, 122, 101, 0, 99, 104, 105, 108, 100, 114, 97, 110, 100, 115, 105, 122, 101, 0, 99, 104, 105, 108, 100, 114, 97, + 100, 0, 99, 104, 105, 108, 100, 102, 108, 97, 116, 0, 99, 104, 105, 108, 100, 115, 112, 114, 101, 97, 100, 0, 99, 108, 117, 109, 112, 102, 97, 99, + 0, 99, 108, 117, 109, 112, 112, 111, 119, 0, 114, 111, 117, 103, 104, 49, 0, 114, 111, 117, 103, 104, 49, 95, 115, 105, 122, 101, 0, 114, 111, 117, + 103, 104, 50, 0, 114, 111, 117, 103, 104, 50, 95, 115, 105, 122, 101, 0, 114, 111, 117, 103, 104, 50, 95, 116, 104, 114, 101, 115, 0, 114, 111, 117, + 103, 104, 95, 101, 110, 100, 0, 114, 111, 117, 103, 104, 95, 101, 110, 100, 95, 115, 104, 97, 112, 101, 0, 98, 114, 97, 110, 99, 104, 95, 116, 104, + 114, 101, 115, 0, 100, 114, 97, 119, 95, 108, 105, 110, 101, 91, 50, 93, 0, 109, 97, 120, 95, 108, 97, 116, 95, 97, 99, 99, 0, 109, 97, 120, + 95, 116, 97, 110, 95, 97, 99, 99, 0, 97, 118, 101, 114, 97, 103, 101, 95, 118, 101, 108, 0, 98, 97, 110, 107, 105, 110, 103, 0, 109, 97, 120, + 95, 98, 97, 110, 107, 0, 103, 114, 111, 117, 110, 100, 122, 0, 98, 111, 105, 100, 102, 97, 99, 91, 56, 93, 0, 98, 111, 105, 100, 114, 117, 108, + 101, 91, 56, 93, 0, 42, 101, 102, 102, 95, 103, 114, 111, 117, 112, 0, 42, 100, 117, 112, 95, 111, 98, 0, 42, 98, 98, 95, 111, 98, 0, 42, + 112, 100, 50, 0, 42, 112, 97, 114, 116, 0, 42, 101, 100, 105, 116, 0, 42, 42, 112, 97, 116, 104, 99, 97, 99, 104, 101, 0, 42, 42, 99, 104, + 105, 108, 100, 99, 97, 99, 104, 101, 0, 112, 97, 116, 104, 99, 97, 99, 104, 101, 98, 117, 102, 115, 0, 99, 104, 105, 108, 100, 99, 97, 99, 104, + 101, 98, 117, 102, 115, 0, 42, 116, 97, 114, 103, 101, 116, 95, 111, 98, 0, 42, 107, 101, 121, 101, 100, 95, 111, 98, 0, 42, 108, 97, 116, 116, + 105, 99, 101, 0, 101, 102, 102, 101, 99, 116, 111, 114, 115, 0, 114, 101, 97, 99, 116, 101, 118, 101, 110, 116, 115, 0, 116, 111, 116, 99, 104, 105, + 108, 100, 0, 116, 111, 116, 99, 97, 99, 104, 101, 100, 0, 116, 111, 116, 99, 104, 105, 108, 100, 99, 97, 99, 104, 101, 0, 116, 97, 114, 103, 101, + 116, 95, 112, 115, 121, 115, 0, 107, 101, 121, 101, 100, 95, 112, 115, 121, 115, 0, 116, 111, 116, 107, 101, 121, 101, 100, 0, 98, 97, 107, 101, 115, + 112, 97, 99, 101, 0, 98, 98, 95, 117, 118, 110, 97, 109, 101, 91, 51, 93, 91, 51, 50, 93, 0, 118, 103, 114, 111, 117, 112, 91, 49, 50, 93, + 0, 118, 103, 95, 110, 101, 103, 0, 114, 116, 51, 0, 42, 114, 101, 110, 100, 101, 114, 100, 97, 116, 97, 0, 42, 99, 97, 99, 104, 101, 0, 67, + 100, 105, 115, 0, 67, 118, 105, 0, 91, 51, 93, 0, 115, 116, 114, 117, 99, 116, 117, 114, 97, 108, 0, 98, 101, 110, 100, 105, 110, 103, 0, 109, + 97, 120, 95, 98, 101, 110, 100, 0, 109, 97, 120, 95, 115, 116, 114, 117, 99, 116, 0, 109, 97, 120, 95, 115, 104, 101, 97, 114, 0, 97, 118, 103, + 95, 115, 112, 114, 105, 110, 103, 95, 108, 101, 110, 0, 116, 105, 109, 101, 115, 99, 97, 108, 101, 0, 101, 102, 102, 95, 102, 111, 114, 99, 101, 95, + 115, 99, 97, 108, 101, 0, 101, 102, 102, 95, 119, 105, 110, 100, 95, 115, 99, 97, 108, 101, 0, 115, 105, 109, 95, 116, 105, 109, 101, 95, 111, 108, + 100, 0, 115, 116, 101, 112, 115, 80, 101, 114, 70, 114, 97, 109, 101, 0, 112, 114, 101, 114, 111, 108, 108, 0, 109, 97, 120, 115, 112, 114, 105, 110, + 103, 108, 101, 110, 0, 115, 111, 108, 118, 101, 114, 95, 116, 121, 112, 101, 0, 118, 103, 114, 111, 117, 112, 95, 98, 101, 110, 100, 0, 118, 103, 114, + 111, 117, 112, 95, 109, 97, 115, 115, 0, 118, 103, 114, 111, 117, 112, 95, 115, 116, 114, 117, 99, 116, 0, 112, 114, 101, 115, 101, 116, 115, 0, 42, + 99, 111, 108, 108, 105, 115, 105, 111, 110, 95, 108, 105, 115, 116, 0, 101, 112, 115, 105, 108, 111, 110, 0, 115, 101, 108, 102, 95, 102, 114, 105, 99, + 116, 105, 111, 110, 0, 115, 101, 108, 102, 101, 112, 115, 105, 108, 111, 110, 0, 115, 101, 108, 102, 95, 108, 111, 111, 112, 95, 99, 111, 117, 110, 116, + 0, 108, 111, 111, 112, 95, 99, 111, 117, 110, 116, 0, 112, 114, 101, 115, 115, 117, 114, 101, 0, 42, 112, 111, 105, 110, 116, 115, 0, 116, 111, 116, + 112, 111, 105, 110, 116, 115, 0, 116, 104, 105, 99, 107, 110, 101, 115, 115, 0, 115, 116, 114, 111, 107, 101, 115, 0, 102, 114, 97, 109, 101, 110, 117, + 109, 0, 42, 97, 99, 116, 102, 114, 97, 109, 101, 0, 103, 115, 116, 101, 112, 0, 105, 110, 102, 111, 91, 49, 50, 56, 93, 0, 115, 98, 117, 102, + 102, 101, 114, 95, 115, 105, 122, 101, 0, 115, 98, 117, 102, 102, 101, 114, 95, 115, 102, 108, 97, 103, 0, 42, 115, 98, 117, 102, 102, 101, 114, 0, + 0, 0, 0, 84, 89, 80, 69, 100, 1, 0, 0, 99, 104, 97, 114, 0, 117, 99, 104, 97, 114, 0, 115, 104, 111, 114, 116, 0, 117, 115, 104, 111, + 114, 116, 0, 105, 110, 116, 0, 108, 111, 110, 103, 0, 117, 108, 111, 110, 103, 0, 102, 108, 111, 97, 116, 0, 100, 111, 117, 98, 108, 101, 0, 118, + 111, 105, 100, 0, 76, 105, 110, 107, 0, 76, 105, 110, 107, 68, 97, 116, 97, 0, 76, 105, 115, 116, 66, 97, 115, 101, 0, 118, 101, 99, 50, 115, + 0, 118, 101, 99, 50, 105, 0, 118, 101, 99, 50, 102, 0, 118, 101, 99, 50, 100, 0, 118, 101, 99, 51, 105, 0, 118, 101, 99, 51, 102, 0, 118, + 101, 99, 51, 100, 0, 118, 101, 99, 52, 105, 0, 118, 101, 99, 52, 102, 0, 118, 101, 99, 52, 100, 0, 114, 99, 116, 105, 0, 114, 99, 116, 102, + 0, 73, 68, 80, 114, 111, 112, 101, 114, 116, 121, 68, 97, 116, 97, 0, 73, 68, 80, 114, 111, 112, 101, 114, 116, 121, 0, 73, 68, 0, 76, 105, + 98, 114, 97, 114, 121, 0, 70, 105, 108, 101, 68, 97, 116, 97, 0, 80, 114, 101, 118, 105, 101, 119, 73, 109, 97, 103, 101, 0, 73, 112, 111, 68, + 114, 105, 118, 101, 114, 0, 79, 98, 106, 101, 99, 116, 0, 73, 112, 111, 67, 117, 114, 118, 101, 0, 66, 80, 111, 105, 110, 116, 0, 66, 101, 122, + 84, 114, 105, 112, 108, 101, 0, 73, 112, 111, 0, 75, 101, 121, 66, 108, 111, 99, 107, 0, 75, 101, 121, 0, 83, 99, 114, 105, 112, 116, 76, 105, + 110, 107, 0, 84, 101, 120, 116, 76, 105, 110, 101, 0, 84, 101, 120, 116, 77, 97, 114, 107, 101, 114, 0, 84, 101, 120, 116, 0, 80, 97, 99, 107, + 101, 100, 70, 105, 108, 101, 0, 67, 97, 109, 101, 114, 97, 0, 73, 109, 97, 103, 101, 85, 115, 101, 114, 0, 73, 109, 97, 103, 101, 0, 71, 80, + 85, 84, 101, 120, 116, 117, 114, 101, 0, 97, 110, 105, 109, 0, 82, 101, 110, 100, 101, 114, 82, 101, 115, 117, 108, 116, 0, 77, 84, 101, 120, 0, + 84, 101, 120, 0, 80, 108, 117, 103, 105, 110, 84, 101, 120, 0, 67, 66, 68, 97, 116, 97, 0, 67, 111, 108, 111, 114, 66, 97, 110, 100, 0, 69, + 110, 118, 77, 97, 112, 0, 73, 109, 66, 117, 102, 0, 98, 78, 111, 100, 101, 84, 114, 101, 101, 0, 84, 101, 120, 77, 97, 112, 112, 105, 110, 103, + 0, 76, 97, 109, 112, 0, 67, 117, 114, 118, 101, 77, 97, 112, 112, 105, 110, 103, 0, 87, 97, 118, 101, 0, 77, 97, 116, 101, 114, 105, 97, 108, + 0, 71, 114, 111, 117, 112, 0, 86, 70, 111, 110, 116, 0, 86, 70, 111, 110, 116, 68, 97, 116, 97, 0, 77, 101, 116, 97, 69, 108, 101, 109, 0, + 66, 111, 117, 110, 100, 66, 111, 120, 0, 77, 101, 116, 97, 66, 97, 108, 108, 0, 78, 117, 114, 98, 0, 67, 104, 97, 114, 73, 110, 102, 111, 0, + 84, 101, 120, 116, 66, 111, 120, 0, 67, 117, 114, 118, 101, 0, 80, 97, 116, 104, 0, 77, 101, 115, 104, 0, 77, 70, 97, 99, 101, 0, 77, 84, + 70, 97, 99, 101, 0, 84, 70, 97, 99, 101, 0, 77, 86, 101, 114, 116, 0, 77, 69, 100, 103, 101, 0, 77, 68, 101, 102, 111, 114, 109, 86, 101, + 114, 116, 0, 77, 67, 111, 108, 0, 77, 83, 116, 105, 99, 107, 121, 0, 77, 83, 101, 108, 101, 99, 116, 0, 67, 117, 115, 116, 111, 109, 68, 97, + 116, 97, 0, 77, 117, 108, 116, 105, 114, 101, 115, 0, 80, 97, 114, 116, 105, 97, 108, 86, 105, 115, 105, 98, 105, 108, 105, 116, 121, 0, 77, 68, + 101, 102, 111, 114, 109, 87, 101, 105, 103, 104, 116, 0, 77, 84, 101, 120, 80, 111, 108, 121, 0, 77, 76, 111, 111, 112, 85, 86, 0, 77, 76, 111, + 111, 112, 67, 111, 108, 0, 77, 70, 108, 111, 97, 116, 80, 114, 111, 112, 101, 114, 116, 121, 0, 77, 73, 110, 116, 80, 114, 111, 112, 101, 114, 116, + 121, 0, 77, 83, 116, 114, 105, 110, 103, 80, 114, 111, 112, 101, 114, 116, 121, 0, 79, 114, 105, 103, 83, 112, 97, 99, 101, 70, 97, 99, 101, 0, + 77, 117, 108, 116, 105, 114, 101, 115, 67, 111, 108, 0, 77, 117, 108, 116, 105, 114, 101, 115, 67, 111, 108, 70, 97, 99, 101, 0, 77, 117, 108, 116, + 105, 114, 101, 115, 70, 97, 99, 101, 0, 77, 117, 108, 116, 105, 114, 101, 115, 69, 100, 103, 101, 0, 77, 117, 108, 116, 105, 114, 101, 115, 76, 101, + 118, 101, 108, 0, 77, 117, 108, 116, 105, 114, 101, 115, 77, 97, 112, 78, 111, 100, 101, 0, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, + 0, 83, 117, 98, 115, 117, 114, 102, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 76, 97, 116, 116, 105, 99, 101, 77, 111, 100, 105, + 102, 105, 101, 114, 68, 97, 116, 97, 0, 67, 117, 114, 118, 101, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 66, 117, 105, 108, 100, + 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 77, 97, 115, 107, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 65, 114, + 114, 97, 121, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 77, 105, 114, 114, 111, 114, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, + 116, 97, 0, 69, 100, 103, 101, 83, 112, 108, 105, 116, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 66, 101, 118, 101, 108, 77, 111, + 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 66, 77, 101, 115, 104, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 68, 105, 115, + 112, 108, 97, 99, 101, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 85, 86, 80, 114, 111, 106, 101, 99, 116, 77, 111, 100, 105, 102, + 105, 101, 114, 68, 97, 116, 97, 0, 68, 101, 99, 105, 109, 97, 116, 101, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 83, 109, 111, + 111, 116, 104, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 67, 97, 115, 116, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, + 0, 87, 97, 118, 101, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 65, 114, 109, 97, 116, 117, 114, 101, 77, 111, 100, 105, 102, 105, + 101, 114, 68, 97, 116, 97, 0, 72, 111, 111, 107, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 83, 111, 102, 116, 98, 111, 100, 121, + 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 67, 108, 111, 116, 104, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 67, + 108, 111, 116, 104, 0, 67, 108, 111, 116, 104, 83, 105, 109, 83, 101, 116, 116, 105, 110, 103, 115, 0, 67, 108, 111, 116, 104, 67, 111, 108, 108, 83, + 101, 116, 116, 105, 110, 103, 115, 0, 80, 111, 105, 110, 116, 67, 97, 99, 104, 101, 0, 67, 111, 108, 108, 105, 115, 105, 111, 110, 77, 111, 100, 105, + 102, 105, 101, 114, 68, 97, 116, 97, 0, 66, 86, 72, 84, 114, 101, 101, 0, 83, 117, 114, 102, 97, 99, 101, 77, 111, 100, 105, 102, 105, 101, 114, + 68, 97, 116, 97, 0, 68, 101, 114, 105, 118, 101, 100, 77, 101, 115, 104, 0, 66, 86, 72, 84, 114, 101, 101, 70, 114, 111, 109, 77, 101, 115, 104, + 0, 66, 111, 111, 108, 101, 97, 110, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 77, 68, 101, 102, 73, 110, 102, 108, 117, 101, 110, + 99, 101, 0, 77, 68, 101, 102, 67, 101, 108, 108, 0, 77, 101, 115, 104, 68, 101, 102, 111, 114, 109, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, + 116, 97, 0, 80, 97, 114, 116, 105, 99, 108, 101, 83, 121, 115, 116, 101, 109, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 80, 97, + 114, 116, 105, 99, 108, 101, 83, 121, 115, 116, 101, 109, 0, 80, 97, 114, 116, 105, 99, 108, 101, 73, 110, 115, 116, 97, 110, 99, 101, 77, 111, 100, + 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 69, 120, 112, 108, 111, 100, 101, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 70, 108, + 117, 105, 100, 115, 105, 109, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 70, 108, 117, 105, 100, 115, 105, 109, 83, 101, 116, 116, 105, + 110, 103, 115, 0, 83, 104, 114, 105, 110, 107, 119, 114, 97, 112, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 83, 105, 109, 112, 108, + 101, 68, 101, 102, 111, 114, 109, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 76, 97, 116, 116, 105, 99, 101, 0, 98, 68, 101, 102, + 111, 114, 109, 71, 114, 111, 117, 112, 0, 98, 65, 99, 116, 105, 111, 110, 0, 98, 80, 111, 115, 101, 0, 66, 117, 108, 108, 101, 116, 83, 111, 102, + 116, 66, 111, 100, 121, 0, 80, 97, 114, 116, 68, 101, 102, 108, 101, 99, 116, 0, 83, 111, 102, 116, 66, 111, 100, 121, 0, 79, 98, 72, 111, 111, + 107, 0, 82, 78, 71, 0, 83, 66, 86, 101, 114, 116, 101, 120, 0, 66, 111, 100, 121, 80, 111, 105, 110, 116, 0, 66, 111, 100, 121, 83, 112, 114, + 105, 110, 103, 0, 83, 66, 83, 99, 114, 97, 116, 99, 104, 0, 87, 111, 114, 108, 100, 0, 82, 97, 100, 105, 111, 0, 66, 97, 115, 101, 0, 65, + 118, 105, 67, 111, 100, 101, 99, 68, 97, 116, 97, 0, 81, 117, 105, 99, 107, 116, 105, 109, 101, 67, 111, 100, 101, 99, 68, 97, 116, 97, 0, 70, + 70, 77, 112, 101, 103, 67, 111, 100, 101, 99, 68, 97, 116, 97, 0, 65, 117, 100, 105, 111, 68, 97, 116, 97, 0, 83, 99, 101, 110, 101, 82, 101, + 110, 100, 101, 114, 76, 97, 121, 101, 114, 0, 82, 101, 110, 100, 101, 114, 68, 97, 116, 97, 0, 82, 101, 110, 100, 101, 114, 80, 114, 111, 102, 105, + 108, 101, 0, 71, 97, 109, 101, 70, 114, 97, 109, 105, 110, 103, 0, 84, 105, 109, 101, 77, 97, 114, 107, 101, 114, 0, 73, 109, 97, 103, 101, 80, + 97, 105, 110, 116, 83, 101, 116, 116, 105, 110, 103, 115, 0, 66, 114, 117, 115, 104, 0, 80, 97, 114, 116, 105, 99, 108, 101, 66, 114, 117, 115, 104, + 68, 97, 116, 97, 0, 80, 97, 114, 116, 105, 99, 108, 101, 69, 100, 105, 116, 83, 101, 116, 116, 105, 110, 103, 115, 0, 84, 114, 97, 110, 115, 102, + 111, 114, 109, 79, 114, 105, 101, 110, 116, 97, 116, 105, 111, 110, 0, 84, 111, 111, 108, 83, 101, 116, 116, 105, 110, 103, 115, 0, 66, 114, 117, 115, + 104, 68, 97, 116, 97, 0, 83, 99, 117, 108, 112, 116, 68, 97, 116, 97, 0, 83, 99, 117, 108, 112, 116, 83, 101, 115, 115, 105, 111, 110, 0, 83, + 99, 101, 110, 101, 0, 68, 97, 103, 70, 111, 114, 101, 115, 116, 0, 66, 71, 112, 105, 99, 0, 86, 105, 101, 119, 51, 68, 0, 83, 112, 97, 99, + 101, 76, 105, 110, 107, 0, 83, 99, 114, 65, 114, 101, 97, 0, 82, 101, 110, 100, 101, 114, 73, 110, 102, 111, 0, 82, 101, 116, 111, 112, 111, 86, + 105, 101, 119, 68, 97, 116, 97, 0, 86, 105, 101, 119, 68, 101, 112, 116, 104, 115, 0, 98, 71, 80, 100, 97, 116, 97, 0, 86, 105, 101, 119, 50, + 68, 0, 83, 112, 97, 99, 101, 73, 110, 102, 111, 0, 83, 112, 97, 99, 101, 73, 112, 111, 0, 83, 112, 97, 99, 101, 66, 117, 116, 115, 0, 83, + 112, 97, 99, 101, 83, 101, 113, 0, 83, 112, 97, 99, 101, 70, 105, 108, 101, 0, 100, 105, 114, 101, 110, 116, 114, 121, 0, 66, 108, 101, 110, 100, + 72, 97, 110, 100, 108, 101, 0, 83, 112, 97, 99, 101, 79, 111, 112, 115, 0, 84, 114, 101, 101, 83, 116, 111, 114, 101, 0, 84, 114, 101, 101, 83, + 116, 111, 114, 101, 69, 108, 101, 109, 0, 83, 112, 97, 99, 101, 73, 109, 97, 103, 101, 0, 83, 112, 97, 99, 101, 78, 108, 97, 0, 83, 112, 97, + 99, 101, 84, 101, 120, 116, 0, 83, 99, 114, 105, 112, 116, 0, 83, 112, 97, 99, 101, 83, 99, 114, 105, 112, 116, 0, 83, 112, 97, 99, 101, 84, + 105, 109, 101, 0, 83, 112, 97, 99, 101, 78, 111, 100, 101, 0, 83, 112, 97, 99, 101, 73, 109, 97, 83, 101, 108, 0, 70, 105, 108, 101, 76, 105, + 115, 116, 0, 84, 104, 101, 109, 101, 85, 73, 0, 84, 104, 101, 109, 101, 83, 112, 97, 99, 101, 0, 84, 104, 101, 109, 101, 87, 105, 114, 101, 67, + 111, 108, 111, 114, 0, 98, 84, 104, 101, 109, 101, 0, 83, 111, 108, 105, 100, 76, 105, 103, 104, 116, 0, 85, 115, 101, 114, 68, 101, 102, 0, 98, + 83, 99, 114, 101, 101, 110, 0, 83, 99, 114, 86, 101, 114, 116, 0, 83, 99, 114, 69, 100, 103, 101, 0, 80, 97, 110, 101, 108, 0, 70, 105, 108, + 101, 71, 108, 111, 98, 97, 108, 0, 83, 116, 114, 105, 112, 69, 108, 101, 109, 0, 84, 83, 116, 114, 105, 112, 69, 108, 101, 109, 0, 83, 116, 114, + 105, 112, 67, 114, 111, 112, 0, 83, 116, 114, 105, 112, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 83, 116, 114, 105, 112, 67, 111, 108, 111, 114, + 66, 97, 108, 97, 110, 99, 101, 0, 83, 116, 114, 105, 112, 67, 111, 108, 111, 114, 66, 97, 108, 97, 110, 99, 101, 71, 85, 73, 72, 101, 108, 112, + 101, 114, 0, 83, 116, 114, 105, 112, 80, 114, 111, 120, 121, 0, 83, 116, 114, 105, 112, 0, 80, 108, 117, 103, 105, 110, 83, 101, 113, 0, 83, 101, + 113, 117, 101, 110, 99, 101, 0, 98, 83, 111, 117, 110, 100, 0, 104, 100, 97, 117, 100, 105, 111, 0, 77, 101, 116, 97, 83, 116, 97, 99, 107, 0, + 69, 100, 105, 116, 105, 110, 103, 0, 87, 105, 112, 101, 86, 97, 114, 115, 0, 71, 108, 111, 119, 86, 97, 114, 115, 0, 84, 114, 97, 110, 115, 102, + 111, 114, 109, 86, 97, 114, 115, 0, 83, 111, 108, 105, 100, 67, 111, 108, 111, 114, 86, 97, 114, 115, 0, 83, 112, 101, 101, 100, 67, 111, 110, 116, + 114, 111, 108, 86, 97, 114, 115, 0, 69, 102, 102, 101, 99, 116, 0, 66, 117, 105, 108, 100, 69, 102, 102, 0, 80, 97, 114, 116, 69, 102, 102, 0, + 80, 97, 114, 116, 105, 99, 108, 101, 0, 87, 97, 118, 101, 69, 102, 102, 0, 79, 111, 112, 115, 0, 98, 80, 114, 111, 112, 101, 114, 116, 121, 0, + 98, 78, 101, 97, 114, 83, 101, 110, 115, 111, 114, 0, 98, 77, 111, 117, 115, 101, 83, 101, 110, 115, 111, 114, 0, 98, 84, 111, 117, 99, 104, 83, + 101, 110, 115, 111, 114, 0, 98, 75, 101, 121, 98, 111, 97, 114, 100, 83, 101, 110, 115, 111, 114, 0, 98, 80, 114, 111, 112, 101, 114, 116, 121, 83, + 101, 110, 115, 111, 114, 0, 98, 65, 99, 116, 117, 97, 116, 111, 114, 83, 101, 110, 115, 111, 114, 0, 98, 68, 101, 108, 97, 121, 83, 101, 110, 115, + 111, 114, 0, 98, 67, 111, 108, 108, 105, 115, 105, 111, 110, 83, 101, 110, 115, 111, 114, 0, 98, 82, 97, 100, 97, 114, 83, 101, 110, 115, 111, 114, + 0, 98, 82, 97, 110, 100, 111, 109, 83, 101, 110, 115, 111, 114, 0, 98, 82, 97, 121, 83, 101, 110, 115, 111, 114, 0, 98, 77, 101, 115, 115, 97, + 103, 101, 83, 101, 110, 115, 111, 114, 0, 98, 83, 101, 110, 115, 111, 114, 0, 98, 67, 111, 110, 116, 114, 111, 108, 108, 101, 114, 0, 98, 74, 111, + 121, 115, 116, 105, 99, 107, 83, 101, 110, 115, 111, 114, 0, 98, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 67, 111, 110, 116, 0, 98, 80, 121, + 116, 104, 111, 110, 67, 111, 110, 116, 0, 98, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 65, 100, 100, 79, 98, 106, 101, 99, 116, 65, 99, 116, + 117, 97, 116, 111, 114, 0, 98, 65, 99, 116, 105, 111, 110, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 83, 111, 117, 110, 100, 65, 99, 116, 117, + 97, 116, 111, 114, 0, 98, 67, 68, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 69, 100, 105, 116, 79, 98, 106, 101, 99, 116, 65, 99, 116, 117, + 97, 116, 111, 114, 0, 98, 83, 99, 101, 110, 101, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 80, 114, 111, 112, 101, 114, 116, 121, 65, 99, 116, + 117, 97, 116, 111, 114, 0, 98, 79, 98, 106, 101, 99, 116, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 73, 112, 111, 65, 99, 116, 117, 97, 116, + 111, 114, 0, 98, 67, 97, 109, 101, 114, 97, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 65, 99, + 116, 117, 97, 116, 111, 114, 0, 98, 71, 114, 111, 117, 112, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 82, 97, 110, 100, 111, 109, 65, 99, 116, + 117, 97, 116, 111, 114, 0, 98, 77, 101, 115, 115, 97, 103, 101, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 71, 97, 109, 101, 65, 99, 116, 117, + 97, 116, 111, 114, 0, 98, 86, 105, 115, 105, 98, 105, 108, 105, 116, 121, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 84, 119, 111, 68, 70, 105, + 108, 116, 101, 114, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 80, 97, 114, 101, 110, 116, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 83, 116, + 97, 116, 101, 65, 99, 116, 117, 97, 116, 111, 114, 0, 70, 114, 101, 101, 67, 97, 109, 101, 114, 97, 0, 98, 83, 97, 109, 112, 108, 101, 0, 98, + 83, 111, 117, 110, 100, 76, 105, 115, 116, 101, 110, 101, 114, 0, 83, 112, 97, 99, 101, 83, 111, 117, 110, 100, 0, 71, 114, 111, 117, 112, 79, 98, + 106, 101, 99, 116, 0, 66, 111, 110, 101, 0, 98, 65, 114, 109, 97, 116, 117, 114, 101, 0, 98, 80, 111, 115, 101, 67, 104, 97, 110, 110, 101, 108, + 0, 98, 65, 99, 116, 105, 111, 110, 71, 114, 111, 117, 112, 0, 98, 65, 99, 116, 105, 111, 110, 67, 104, 97, 110, 110, 101, 108, 0, 83, 112, 97, + 99, 101, 65, 99, 116, 105, 111, 110, 0, 98, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 67, 104, 97, 110, 110, 101, 108, 0, 98, 67, 111, 110, + 115, 116, 114, 97, 105, 110, 116, 0, 98, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 84, 97, 114, 103, 101, 116, 0, 98, 80, 121, 116, 104, 111, + 110, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 75, 105, 110, 101, 109, 97, 116, 105, 99, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, + 0, 98, 84, 114, 97, 99, 107, 84, 111, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 82, 111, 116, 97, 116, 101, 76, 105, 107, 101, 67, + 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 76, 111, 99, 97, 116, 101, 76, 105, 107, 101, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, + 98, 77, 105, 110, 77, 97, 120, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 83, 105, 122, 101, 76, 105, 107, 101, 67, 111, 110, 115, 116, + 114, 97, 105, 110, 116, 0, 98, 65, 99, 116, 105, 111, 110, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 76, 111, 99, 107, 84, 114, 97, + 99, 107, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 70, 111, 108, 108, 111, 119, 80, 97, 116, 104, 67, 111, 110, 115, 116, 114, 97, 105, + 110, 116, 0, 98, 83, 116, 114, 101, 116, 99, 104, 84, 111, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 82, 105, 103, 105, 100, 66, 111, + 100, 121, 74, 111, 105, 110, 116, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 67, 108, 97, 109, 112, 84, 111, 67, 111, 110, 115, 116, 114, + 97, 105, 110, 116, 0, 98, 67, 104, 105, 108, 100, 79, 102, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 84, 114, 97, 110, 115, 102, 111, + 114, 109, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 76, 111, 99, 76, 105, 109, 105, 116, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, + 0, 98, 82, 111, 116, 76, 105, 109, 105, 116, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 83, 105, 122, 101, 76, 105, 109, 105, 116, 67, + 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 68, 105, 115, 116, 76, 105, 109, 105, 116, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, + 83, 104, 114, 105, 110, 107, 119, 114, 97, 112, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 65, 99, 116, 105, 111, 110, 77, 111, 100, 105, + 102, 105, 101, 114, 0, 98, 65, 99, 116, 105, 111, 110, 83, 116, 114, 105, 112, 0, 98, 78, 111, 100, 101, 83, 116, 97, 99, 107, 0, 98, 78, 111, + 100, 101, 83, 111, 99, 107, 101, 116, 0, 98, 78, 111, 100, 101, 76, 105, 110, 107, 0, 98, 78, 111, 100, 101, 0, 98, 78, 111, 100, 101, 80, 114, + 101, 118, 105, 101, 119, 0, 98, 78, 111, 100, 101, 84, 121, 112, 101, 0, 78, 111, 100, 101, 73, 109, 97, 103, 101, 65, 110, 105, 109, 0, 78, 111, + 100, 101, 66, 108, 117, 114, 68, 97, 116, 97, 0, 78, 111, 100, 101, 68, 66, 108, 117, 114, 68, 97, 116, 97, 0, 78, 111, 100, 101, 66, 105, 108, + 97, 116, 101, 114, 97, 108, 66, 108, 117, 114, 68, 97, 116, 97, 0, 78, 111, 100, 101, 72, 117, 101, 83, 97, 116, 0, 78, 111, 100, 101, 73, 109, + 97, 103, 101, 70, 105, 108, 101, 0, 78, 111, 100, 101, 67, 104, 114, 111, 109, 97, 0, 78, 111, 100, 101, 84, 119, 111, 88, 89, 115, 0, 78, 111, + 100, 101, 84, 119, 111, 70, 108, 111, 97, 116, 115, 0, 78, 111, 100, 101, 71, 101, 111, 109, 101, 116, 114, 121, 0, 78, 111, 100, 101, 86, 101, 114, + 116, 101, 120, 67, 111, 108, 0, 78, 111, 100, 101, 68, 101, 102, 111, 99, 117, 115, 0, 78, 111, 100, 101, 83, 99, 114, 105, 112, 116, 68, 105, 99, + 116, 0, 78, 111, 100, 101, 71, 108, 97, 114, 101, 0, 78, 111, 100, 101, 84, 111, 110, 101, 109, 97, 112, 0, 78, 111, 100, 101, 76, 101, 110, 115, + 68, 105, 115, 116, 0, 84, 101, 120, 78, 111, 100, 101, 79, 117, 116, 112, 117, 116, 0, 67, 117, 114, 118, 101, 77, 97, 112, 80, 111, 105, 110, 116, + 0, 67, 117, 114, 118, 101, 77, 97, 112, 0, 66, 114, 117, 115, 104, 67, 108, 111, 110, 101, 0, 67, 117, 115, 116, 111, 109, 68, 97, 116, 97, 76, + 97, 121, 101, 114, 0, 72, 97, 105, 114, 75, 101, 121, 0, 80, 97, 114, 116, 105, 99, 108, 101, 75, 101, 121, 0, 67, 104, 105, 108, 100, 80, 97, + 114, 116, 105, 99, 108, 101, 0, 80, 97, 114, 116, 105, 99, 108, 101, 68, 97, 116, 97, 0, 80, 97, 114, 116, 105, 99, 108, 101, 83, 101, 116, 116, + 105, 110, 103, 115, 0, 80, 97, 114, 116, 105, 99, 108, 101, 69, 100, 105, 116, 0, 80, 97, 114, 116, 105, 99, 108, 101, 67, 97, 99, 104, 101, 75, + 101, 121, 0, 76, 105, 110, 107, 78, 111, 100, 101, 0, 98, 71, 80, 68, 115, 112, 111, 105, 110, 116, 0, 98, 71, 80, 68, 115, 116, 114, 111, 107, + 101, 0, 98, 71, 80, 68, 102, 114, 97, 109, 101, 0, 98, 71, 80, 68, 108, 97, 121, 101, 114, 0, 0, 84, 76, 69, 78, 1, 0, 1, 0, 2, + 0, 2, 0, 4, 0, 4, 0, 4, 0, 4, 0, 8, 0, 0, 0, 16, 0, 24, 0, 16, 0, 4, 0, 8, 0, 8, 0, 16, 0, 12, 0, 12, + 0, 24, 0, 16, 0, 16, 0, 32, 0, 16, 0, 16, 0, 32, 0, 96, 0, 72, 0, 72, 2, 0, 0, 40, 0, -112, 0, 48, 4, 112, 0, 36, + 0, 56, 0, 112, 0, -128, 0, -96, 0, 24, 0, 40, 0, 48, 0, -80, 0, 24, 0, -88, 0, 32, 0, -72, 1, 0, 0, 0, 0, 0, 0, -112, + 0, 64, 1, 120, 1, 24, 0, 8, 3, -56, 0, 0, 0, -56, 0, -120, 0, -16, 1, 56, 1, 80, 0, -16, 2, 104, 0, 96, 1, 0, 0, -128, + 0, 104, 0, -72, 0, 80, 0, 8, 0, 16, 0, -96, 1, 0, 0, -112, 1, 20, 0, 48, 0, 64, 0, 24, 0, 12, 0, 16, 0, 4, 0, 8, + 0, 8, 0, 32, 0, 112, 0, 48, 0, 8, 0, 16, 0, 8, 0, 8, 0, 4, 0, 4, 0, 0, 1, 32, 0, 16, 0, 64, 0, 24, 0, 12, + 0, 96, 0, 0, 0, 64, 0, 88, 0, 104, 0, 112, 0, 80, 0, 112, 0, -112, 0, 80, 0, 72, 0, 120, 0, 72, 0, -88, 0, -48, 0, 72, + 0, 104, 0, 120, 0, -48, 0, 120, 0, -56, 0, 64, 0, 96, 0, 0, 0, -120, 0, 32, 0, 20, 0, -112, 0, 0, 0, 80, 0, 0, 0, 0, + 0, 80, 0, 8, 0, 8, 0, 0, 1, 96, 0, -104, 1, 80, 0, 80, 0, 80, 0, -72, 1, -128, 0, 120, 0, -104, 0, 48, 0, -128, 0, 72, + 0, 120, 0, -120, 0, 16, 1, -32, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, -32, 1, 40, 0, 40, 0, -72, 0, -104, 0, 56, 0, 16, + 0, 88, 0, -24, 3, 64, 0, 16, 0, 88, 0, 16, 0, 24, 1, 8, 0, 72, 0, 88, 0, -16, 0, 8, 0, -8, 0, 0, 0, 64, 6, 0, + 0, 64, 0, 88, 3, 48, 0, 8, 1, 0, 0, 0, 0, 0, 0, 32, 0, -120, 0, 48, 0, 120, 1, -16, 0, -40, 0, -8, 1, 0, 0, 0, + 0, 48, 1, 16, 0, 16, 0, 32, 1, -64, 0, -112, 0, 120, 2, 56, 0, -80, 0, 0, 1, -72, 2, 0, 0, -104, 0, -48, 0, 16, 0, 64, + 14, 56, 0, 40, 12, -88, 0, 32, 0, 40, 0, -16, 0, 40, 0, 80, 0, 48, 0, 16, 0, 8, 0, 64, 0, 0, 0, 0, 1, 32, 1, -56, + 1, 8, 1, 72, 1, 0, 0, 32, 0, 48, 0, 12, 0, 24, 0, 48, 0, 16, 0, 32, 0, 24, 0, 32, 0, 72, 1, 0, 0, 64, 0, 64, + 0, 80, 0, 48, 0, 8, 0, 48, 0, 72, 0, 104, 0, 40, 0, 8, 0, 72, 0, 44, 0, 40, 0, 108, 0, 72, 0, 96, 0, 104, 0, 60, + 0, -128, 0, 80, 0, 80, 0, 16, 0, 96, 0, 32, 0, 20, 0, 88, 0, 24, 0, 80, 0, 112, 0, 84, 0, 32, 0, 96, 0, 64, 0, 56, + 0, 112, 0, -116, 0, 4, 0, 24, 0, 16, 0, 8, 0, 40, 0, 0, 0, 88, 0, -64, 0, 40, 0, 24, 1, -104, 0, -48, 1, 88, 0, 88, + 0, -48, 0, 56, 0, 80, 0, -128, 0, 80, 0, 112, 0, 56, 0, 48, 0, 48, 0, 72, 0, 48, 0, 72, 0, 48, 0, 24, 0, 56, 0, 104, + 0, 16, 0, 112, 0, 96, 0, 28, 0, 28, 0, 28, 0, 56, 0, 24, 0, 72, 0, -88, 0, 40, 0, -112, 0, 48, 0, -8, 0, 0, 0, 0, + 0, 16, 0, 40, 0, 28, 0, 12, 0, 12, 0, 16, 1, 40, 0, 8, 0, 8, 0, 64, 0, 32, 0, 24, 0, 16, 0, 24, 0, 32, 0, 8, + 0, 32, 0, 12, 0, 56, 0, 24, 0, 72, 0, 24, 0, 56, 0, 72, 0, 8, 1, 16, 2, 0, 0, 0, 0, 0, 0, 16, 0, 32, 0, 40, + 0, -64, 0, 83, 84, 82, 67, 57, 1, 0, 0, 10, 0, 2, 0, 10, 0, 0, 0, 10, 0, 1, 0, 11, 0, 3, 0, 11, 0, 0, 0, 11, + 0, 1, 0, 9, 0, 2, 0, 12, 0, 2, 0, 9, 0, 3, 0, 9, 0, 4, 0, 13, 0, 2, 0, 2, 0, 5, 0, 2, 0, 6, 0, 14, + 0, 2, 0, 4, 0, 5, 0, 4, 0, 6, 0, 15, 0, 2, 0, 7, 0, 5, 0, 7, 0, 6, 0, 16, 0, 2, 0, 8, 0, 5, 0, 8, + 0, 6, 0, 17, 0, 3, 0, 4, 0, 5, 0, 4, 0, 6, 0, 4, 0, 7, 0, 18, 0, 3, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, + 0, 7, 0, 19, 0, 3, 0, 8, 0, 5, 0, 8, 0, 6, 0, 8, 0, 7, 0, 20, 0, 4, 0, 4, 0, 5, 0, 4, 0, 6, 0, 4, + 0, 7, 0, 4, 0, 8, 0, 21, 0, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 7, 0, 8, 0, 22, 0, 4, 0, 8, + 0, 5, 0, 8, 0, 6, 0, 8, 0, 7, 0, 8, 0, 8, 0, 23, 0, 4, 0, 4, 0, 9, 0, 4, 0, 10, 0, 4, 0, 11, 0, 4, + 0, 12, 0, 24, 0, 4, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0, 25, 0, 4, 0, 9, 0, 13, 0, 12, + 0, 14, 0, 4, 0, 15, 0, 4, 0, 16, 0, 26, 0, 10, 0, 26, 0, 0, 0, 26, 0, 1, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, + 0, 19, 0, 2, 0, 20, 0, 4, 0, 21, 0, 25, 0, 22, 0, 4, 0, 23, 0, 4, 0, 24, 0, 27, 0, 9, 0, 9, 0, 0, 0, 9, + 0, 1, 0, 27, 0, 25, 0, 28, 0, 26, 0, 0, 0, 27, 0, 2, 0, 28, 0, 2, 0, 20, 0, 4, 0, 29, 0, 26, 0, 30, 0, 28, + 0, 8, 0, 27, 0, 31, 0, 27, 0, 32, 0, 29, 0, 33, 0, 0, 0, 34, 0, 0, 0, 35, 0, 4, 0, 36, 0, 4, 0, 37, 0, 28, + 0, 38, 0, 30, 0, 6, 0, 4, 0, 39, 0, 4, 0, 40, 0, 2, 0, 41, 0, 2, 0, 42, 0, 2, 0, 43, 0, 4, 0, 44, 0, 31, + 0, 6, 0, 32, 0, 45, 0, 2, 0, 46, 0, 2, 0, 47, 0, 2, 0, 18, 0, 2, 0, 20, 0, 0, 0, 48, 0, 33, 0, 21, 0, 33, + 0, 0, 0, 33, 0, 1, 0, 34, 0, 49, 0, 35, 0, 50, 0, 24, 0, 51, 0, 24, 0, 52, 0, 2, 0, 46, 0, 2, 0, 47, 0, 2, + 0, 53, 0, 2, 0, 54, 0, 2, 0, 55, 0, 2, 0, 56, 0, 2, 0, 20, 0, 2, 0, 57, 0, 7, 0, 11, 0, 7, 0, 12, 0, 4, + 0, 58, 0, 7, 0, 59, 0, 7, 0, 60, 0, 7, 0, 61, 0, 31, 0, 62, 0, 36, 0, 7, 0, 27, 0, 31, 0, 12, 0, 63, 0, 24, + 0, 64, 0, 2, 0, 46, 0, 2, 0, 65, 0, 2, 0, 66, 0, 2, 0, 37, 0, 37, 0, 16, 0, 37, 0, 0, 0, 37, 0, 1, 0, 7, + 0, 67, 0, 7, 0, 61, 0, 2, 0, 18, 0, 2, 0, 47, 0, 2, 0, 68, 0, 2, 0, 20, 0, 4, 0, 69, 0, 4, 0, 70, 0, 9, + 0, 2, 0, 7, 0, 71, 0, 0, 0, 17, 0, 0, 0, 72, 0, 7, 0, 73, 0, 7, 0, 74, 0, 38, 0, 12, 0, 27, 0, 31, 0, 37, + 0, 75, 0, 0, 0, 76, 0, 4, 0, 77, 0, 7, 0, 61, 0, 12, 0, 78, 0, 36, 0, 79, 0, 27, 0, 80, 0, 2, 0, 18, 0, 2, + 0, 81, 0, 2, 0, 82, 0, 2, 0, 20, 0, 39, 0, 5, 0, 27, 0, 83, 0, 2, 0, 84, 0, 2, 0, 85, 0, 2, 0, 86, 0, 4, + 0, 37, 0, 40, 0, 6, 0, 40, 0, 0, 0, 40, 0, 1, 0, 0, 0, 87, 0, 0, 0, 88, 0, 4, 0, 23, 0, 4, 0, 89, 0, 41, + 0, 10, 0, 41, 0, 0, 0, 41, 0, 1, 0, 4, 0, 90, 0, 4, 0, 91, 0, 4, 0, 92, 0, 4, 0, 43, 0, 4, 0, 14, 0, 4, + 0, 93, 0, 0, 0, 94, 0, 0, 0, 95, 0, 42, 0, 15, 0, 27, 0, 31, 0, 0, 0, 96, 0, 4, 0, 93, 0, 4, 0, 97, 0, 12, + 0, 98, 0, 40, 0, 99, 0, 40, 0, 100, 0, 4, 0, 101, 0, 4, 0, 102, 0, 12, 0, 103, 0, 0, 0, 104, 0, 4, 0, 105, 0, 4, + 0, 106, 0, 9, 0, 107, 0, 8, 0, 108, 0, 43, 0, 5, 0, 4, 0, 109, 0, 4, 0, 110, 0, 4, 0, 93, 0, 4, 0, 37, 0, 9, + 0, 2, 0, 44, 0, 20, 0, 27, 0, 31, 0, 2, 0, 18, 0, 2, 0, 20, 0, 7, 0, 111, 0, 7, 0, 112, 0, 7, 0, 113, 0, 7, + 0, 114, 0, 7, 0, 115, 0, 7, 0, 116, 0, 7, 0, 117, 0, 7, 0, 118, 0, 7, 0, 119, 0, 7, 0, 120, 0, 7, 0, 121, 0, 2, + 0, 122, 0, 2, 0, 123, 0, 7, 0, 124, 0, 36, 0, 79, 0, 39, 0, 125, 0, 32, 0, 126, 0, 45, 0, 12, 0, 4, 0, 127, 0, 4, + 0, -128, 0, 4, 0, -127, 0, 4, 0, -126, 0, 2, 0, -125, 0, 2, 0, -124, 0, 2, 0, 20, 0, 2, 0, -123, 0, 2, 0, -122, 0, 2, + 0, -121, 0, 2, 0, -120, 0, 2, 0, -119, 0, 46, 0, 32, 0, 27, 0, 31, 0, 0, 0, 34, 0, 12, 0, -118, 0, 47, 0, -117, 0, 48, + 0, -116, 0, 49, 0, -115, 0, 2, 0, -123, 0, 2, 0, 20, 0, 2, 0, -114, 0, 2, 0, 18, 0, 2, 0, 37, 0, 2, 0, 43, 0, 4, + 0, -113, 0, 2, 0, -112, 0, 2, 0, -111, 0, 2, 0, -110, 0, 2, 0, -109, 0, 2, 0, -108, 0, 2, 0, -107, 0, 4, 0, -106, 0, 4, + 0, -105, 0, 43, 0, -104, 0, 30, 0, -103, 0, 7, 0, -102, 0, 4, 0, -101, 0, 2, 0, -100, 0, 2, 0, -99, 0, 2, 0, -98, 0, 2, + 0, -97, 0, 7, 0, -96, 0, 7, 0, -95, 0, 9, 0, -94, 0, 50, 0, 31, 0, 2, 0, -93, 0, 2, 0, -92, 0, 2, 0, -91, 0, 2, + 0, -90, 0, 32, 0, -89, 0, 51, 0, -88, 0, 0, 0, -87, 0, 0, 0, -86, 0, 0, 0, -85, 0, 0, 0, -84, 0, 0, 0, -83, 0, 7, + 0, -82, 0, 7, 0, -81, 0, 2, 0, -80, 0, 2, 0, -79, 0, 2, 0, -78, 0, 2, 0, -77, 0, 2, 0, -76, 0, 2, 0, -75, 0, 2, + 0, -74, 0, 7, 0, -73, 0, 7, 0, -72, 0, 7, 0, -71, 0, 7, 0, -70, 0, 7, 0, -69, 0, 7, 0, 57, 0, 7, 0, -68, 0, 7, + 0, -67, 0, 7, 0, -66, 0, 7, 0, -65, 0, 7, 0, -64, 0, 52, 0, 15, 0, 0, 0, -63, 0, 9, 0, -62, 0, 0, 0, -61, 0, 0, + 0, -60, 0, 4, 0, -59, 0, 4, 0, -58, 0, 9, 0, -57, 0, 7, 0, -56, 0, 7, 0, -55, 0, 7, 0, -54, 0, 4, 0, -53, 0, 9, + 0, -52, 0, 9, 0, -51, 0, 4, 0, -50, 0, 4, 0, 37, 0, 53, 0, 6, 0, 7, 0, -73, 0, 7, 0, -72, 0, 7, 0, -71, 0, 7, + 0, -49, 0, 7, 0, 67, 0, 4, 0, 64, 0, 54, 0, 5, 0, 2, 0, 20, 0, 2, 0, 36, 0, 2, 0, 64, 0, 2, 0, -48, 0, 53, + 0, -54, 0, 55, 0, 17, 0, 32, 0, -89, 0, 46, 0, -47, 0, 56, 0, -46, 0, 7, 0, -45, 0, 7, 0, -44, 0, 2, 0, 18, 0, 2, + 0, -43, 0, 7, 0, 113, 0, 7, 0, 114, 0, 7, 0, -42, 0, 4, 0, -41, 0, 2, 0, -40, 0, 2, 0, -39, 0, 4, 0, -123, 0, 4, + 0, -113, 0, 2, 0, -38, 0, 2, 0, -37, 0, 51, 0, 56, 0, 27, 0, 31, 0, 7, 0, -36, 0, 7, 0, -35, 0, 7, 0, -34, 0, 7, + 0, -33, 0, 7, 0, -32, 0, 7, 0, -31, 0, 7, 0, -30, 0, 7, 0, -29, 0, 7, 0, -28, 0, 7, 0, -27, 0, 7, 0, -26, 0, 7, + 0, -25, 0, 7, 0, -24, 0, 7, 0, -23, 0, 7, 0, -22, 0, 7, 0, -21, 0, 7, 0, -20, 0, 7, 0, -19, 0, 7, 0, -18, 0, 7, + 0, -17, 0, 2, 0, -16, 0, 2, 0, -15, 0, 2, 0, -14, 0, 2, 0, -13, 0, 2, 0, -12, 0, 2, 0, -11, 0, 2, 0, -10, 0, 2, + 0, 20, 0, 2, 0, 18, 0, 2, 0, -43, 0, 7, 0, -9, 0, 7, 0, -8, 0, 7, 0, -7, 0, 7, 0, -6, 0, 2, 0, -5, 0, 2, + 0, -4, 0, 2, 0, -3, 0, 2, 0, -125, 0, 4, 0, 23, 0, 4, 0, -128, 0, 4, 0, -127, 0, 4, 0, -126, 0, 7, 0, -2, 0, 7, + 0, -1, 0, 7, 0, -67, 0, 45, 0, 0, 1, 57, 0, 1, 1, 36, 0, 79, 0, 46, 0, -47, 0, 52, 0, 2, 1, 54, 0, 3, 1, 55, + 0, 4, 1, 30, 0, -103, 0, 0, 0, 5, 1, 0, 0, 6, 1, 58, 0, 8, 0, 7, 0, 7, 1, 7, 0, 8, 1, 7, 0, -81, 0, 4, + 0, 20, 0, 7, 0, 9, 1, 7, 0, 10, 1, 7, 0, 11, 1, 32, 0, 45, 0, 59, 0, 80, 0, 27, 0, 31, 0, 2, 0, 18, 0, 2, + 0, 12, 1, 4, 0, 13, 1, 2, 0, -79, 0, 2, 0, 14, 1, 7, 0, -73, 0, 7, 0, -72, 0, 7, 0, -71, 0, 7, 0, -70, 0, 7, + 0, 15, 1, 7, 0, 16, 1, 7, 0, 17, 1, 7, 0, 18, 1, 7, 0, 19, 1, 7, 0, 20, 1, 7, 0, 21, 1, 7, 0, 22, 1, 7, + 0, 23, 1, 7, 0, 24, 1, 7, 0, 25, 1, 60, 0, 26, 1, 2, 0, 27, 1, 2, 0, 70, 0, 7, 0, 113, 0, 7, 0, 114, 0, 7, + 0, 28, 1, 7, 0, 29, 1, 7, 0, 30, 1, 2, 0, 31, 1, 2, 0, 32, 1, 2, 0, 33, 1, 2, 0, 34, 1, 0, 0, 35, 1, 0, + 0, 36, 1, 2, 0, 37, 1, 2, 0, 38, 1, 2, 0, 39, 1, 2, 0, 40, 1, 2, 0, 41, 1, 7, 0, 42, 1, 7, 0, 43, 1, 7, + 0, 44, 1, 7, 0, 45, 1, 2, 0, 46, 1, 2, 0, 43, 0, 2, 0, 47, 1, 2, 0, 48, 1, 2, 0, 49, 1, 2, 0, 50, 1, 7, + 0, 51, 1, 7, 0, 52, 1, 7, 0, 53, 1, 7, 0, 54, 1, 7, 0, 55, 1, 7, 0, 56, 1, 7, 0, 57, 1, 7, 0, 58, 1, 7, + 0, 59, 1, 7, 0, 60, 1, 7, 0, 61, 1, 7, 0, 62, 1, 2, 0, 63, 1, 2, 0, 64, 1, 4, 0, 65, 1, 4, 0, 66, 1, 2, + 0, 67, 1, 2, 0, 68, 1, 2, 0, 69, 1, 2, 0, 70, 1, 7, 0, 71, 1, 7, 0, 72, 1, 7, 0, 73, 1, 7, 0, 74, 1, 2, + 0, 75, 1, 2, 0, 76, 1, 50, 0, 77, 1, 36, 0, 79, 0, 30, 0, -103, 0, 39, 0, 125, 0, 61, 0, 2, 0, 27, 0, 31, 0, 36, + 0, 79, 0, 62, 0, -127, 0, 27, 0, 31, 0, 2, 0, -79, 0, 2, 0, 20, 0, 7, 0, -73, 0, 7, 0, -72, 0, 7, 0, -71, 0, 7, + 0, 78, 1, 7, 0, 79, 1, 7, 0, 80, 1, 7, 0, 81, 1, 7, 0, 82, 1, 7, 0, 83, 1, 7, 0, 84, 1, 7, 0, 85, 1, 7, + 0, 86, 1, 7, 0, 87, 1, 7, 0, 88, 1, 7, 0, 89, 1, 7, 0, 90, 1, 7, 0, 91, 1, 7, 0, 92, 1, 7, 0, 93, 1, 7, + 0, 94, 1, 7, 0, 95, 1, 7, 0, 96, 1, 7, 0, 97, 1, 7, 0, 98, 1, 7, 0, 99, 1, 7, 0, 100, 1, 7, 0, 101, 1, 7, + 0, 102, 1, 7, 0, 103, 1, 7, 0, 104, 1, 2, 0, 105, 1, 2, 0, 106, 1, 2, 0, 107, 1, 0, 0, 108, 1, 0, 0, 109, 1, 7, + 0, 110, 1, 7, 0, 111, 1, 2, 0, 112, 1, 2, 0, 113, 1, 7, 0, 114, 1, 7, 0, 115, 1, 7, 0, 116, 1, 7, 0, 117, 1, 2, + 0, 118, 1, 2, 0, 119, 1, 4, 0, 13, 1, 4, 0, 120, 1, 2, 0, 121, 1, 2, 0, 122, 1, 2, 0, 123, 1, 2, 0, 124, 1, 7, + 0, 125, 1, 7, 0, 126, 1, 7, 0, 127, 1, 7, 0, -128, 1, 7, 0, -127, 1, 7, 0, -126, 1, 7, 0, -125, 1, 7, 0, -124, 1, 7, + 0, -123, 1, 7, 0, -122, 1, 0, 0, -121, 1, 7, 0, -120, 1, 7, 0, -119, 1, 7, 0, -118, 1, 4, 0, -117, 1, 0, 0, -116, 1, 0, + 0, 47, 1, 0, 0, -115, 1, 0, 0, 5, 1, 2, 0, -114, 1, 2, 0, -113, 1, 2, 0, 64, 1, 2, 0, -112, 1, 2, 0, -111, 1, 2, + 0, -110, 1, 7, 0, -109, 1, 7, 0, -108, 1, 7, 0, -107, 1, 7, 0, -106, 1, 7, 0, -105, 1, 2, 0, -93, 0, 2, 0, -92, 0, 54, + 0, -104, 1, 54, 0, -103, 1, 0, 0, -102, 1, 0, 0, -101, 1, 0, 0, -100, 1, 0, 0, -99, 1, 2, 0, -98, 1, 2, 0, 12, 1, 7, + 0, -97, 1, 7, 0, -96, 1, 50, 0, 77, 1, 57, 0, 1, 1, 36, 0, 79, 0, 63, 0, -95, 1, 30, 0, -103, 0, 7, 0, -94, 1, 7, + 0, -93, 1, 7, 0, -92, 1, 7, 0, -91, 1, 7, 0, -90, 1, 2, 0, -89, 1, 2, 0, 70, 0, 7, 0, -88, 1, 7, 0, -87, 1, 7, + 0, -86, 1, 7, 0, -85, 1, 7, 0, -84, 1, 7, 0, -83, 1, 7, 0, -82, 1, 7, 0, -81, 1, 7, 0, -80, 1, 2, 0, -79, 1, 2, + 0, -78, 1, 7, 0, -77, 1, 7, 0, -76, 1, 7, 0, -75, 1, 7, 0, -74, 1, 7, 0, -73, 1, 4, 0, -72, 1, 4, 0, -71, 1, 4, + 0, -70, 1, 39, 0, 125, 0, 12, 0, -69, 1, 64, 0, 6, 0, 27, 0, 31, 0, 0, 0, -68, 1, 7, 0, -67, 1, 7, 0, 37, 0, 65, + 0, 2, 0, 43, 0, -104, 0, 66, 0, 26, 0, 66, 0, 0, 0, 66, 0, 1, 0, 67, 0, -66, 1, 4, 0, -65, 1, 4, 0, -64, 1, 4, + 0, -63, 1, 4, 0, -62, 1, 4, 0, -61, 1, 4, 0, -60, 1, 2, 0, 18, 0, 2, 0, 20, 0, 2, 0, -59, 1, 2, 0, -58, 1, 7, + 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 7, 0, -57, 1, 7, 0, -56, 1, 7, 0, -55, 1, 7, 0, -54, 1, 7, 0, -53, 1, 7, + 0, -52, 1, 7, 0, -51, 1, 7, 0, 23, 0, 7, 0, -50, 1, 7, 0, -49, 1, 68, 0, 15, 0, 27, 0, 31, 0, 67, 0, -66, 1, 12, + 0, -48, 1, 12, 0, -47, 1, 36, 0, 79, 0, 62, 0, -46, 1, 2, 0, 20, 0, 2, 0, -45, 1, 4, 0, -80, 0, 7, 0, 7, 1, 7, + 0, -81, 0, 7, 0, 8, 1, 7, 0, -44, 1, 7, 0, -43, 1, 7, 0, -42, 1, 35, 0, 10, 0, 7, 0, -41, 1, 7, 0, -40, 1, 7, + 0, -39, 1, 7, 0, -38, 1, 2, 0, -37, 1, 2, 0, -36, 1, 0, 0, -35, 1, 0, 0, -34, 1, 0, 0, -33, 1, 0, 0, -32, 1, 34, + 0, 7, 0, 7, 0, -31, 1, 7, 0, -40, 1, 7, 0, -39, 1, 2, 0, -35, 1, 2, 0, -32, 1, 7, 0, -38, 1, 7, 0, 37, 0, 69, + 0, 21, 0, 69, 0, 0, 0, 69, 0, 1, 0, 2, 0, 18, 0, 2, 0, -30, 1, 2, 0, -32, 1, 2, 0, 20, 0, 2, 0, -29, 1, 2, + 0, -28, 1, 2, 0, -27, 1, 2, 0, -26, 1, 2, 0, -25, 1, 2, 0, -24, 1, 2, 0, -23, 1, 2, 0, -22, 1, 7, 0, -21, 1, 7, + 0, -20, 1, 34, 0, 49, 0, 35, 0, 50, 0, 2, 0, -19, 1, 2, 0, -18, 1, 4, 0, -17, 1, 70, 0, 5, 0, 2, 0, -16, 1, 2, + 0, -30, 1, 0, 0, 20, 0, 0, 0, 37, 0, 2, 0, 70, 0, 71, 0, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 8, 0, 7, + 0, -15, 1, 72, 0, 57, 0, 27, 0, 31, 0, 67, 0, -66, 1, 12, 0, -14, 1, 12, 0, -47, 1, 32, 0, -13, 1, 32, 0, -12, 1, 32, + 0, -11, 1, 36, 0, 79, 0, 73, 0, -10, 1, 38, 0, -9, 1, 62, 0, -46, 1, 12, 0, -8, 1, 7, 0, 7, 1, 7, 0, -81, 0, 7, + 0, 8, 1, 4, 0, -80, 0, 2, 0, -7, 1, 2, 0, -45, 1, 2, 0, 20, 0, 2, 0, -6, 1, 7, 0, -5, 1, 7, 0, -4, 1, 7, + 0, -3, 1, 2, 0, -27, 1, 2, 0, -26, 1, 2, 0, -2, 1, 2, 0, -1, 1, 4, 0, 70, 0, 2, 0, 23, 0, 2, 0, 98, 0, 2, + 0, 67, 0, 2, 0, 0, 2, 7, 0, 1, 2, 7, 0, 2, 2, 7, 0, 3, 2, 7, 0, 4, 2, 7, 0, 5, 2, 7, 0, 6, 2, 7, + 0, 7, 2, 7, 0, 8, 2, 7, 0, 9, 2, 7, 0, 10, 2, 0, 0, 11, 2, 0, 0, 12, 2, 64, 0, 13, 2, 64, 0, 14, 2, 64, + 0, 15, 2, 64, 0, 16, 2, 4, 0, 17, 2, 4, 0, 18, 2, 4, 0, 19, 2, 4, 0, 37, 0, 71, 0, 20, 2, 4, 0, 21, 2, 4, + 0, 22, 2, 70, 0, 23, 2, 70, 0, 24, 2, 74, 0, 39, 0, 27, 0, 31, 0, 67, 0, -66, 1, 12, 0, 25, 2, 36, 0, 79, 0, 38, + 0, -9, 1, 62, 0, -46, 1, 75, 0, 26, 2, 76, 0, 27, 2, 77, 0, 28, 2, 78, 0, 29, 2, 79, 0, 30, 2, 80, 0, 31, 2, 81, + 0, 32, 2, 82, 0, 33, 2, 74, 0, 34, 2, 83, 0, 35, 2, 84, 0, 36, 2, 84, 0, 37, 2, 84, 0, 38, 2, 4, 0, 54, 0, 4, + 0, 39, 2, 4, 0, 40, 2, 4, 0, 41, 2, 4, 0, 42, 2, 4, 0, -80, 0, 7, 0, 7, 1, 7, 0, -81, 0, 7, 0, 8, 1, 7, + 0, 43, 2, 7, 0, 37, 0, 2, 0, 44, 2, 2, 0, 20, 0, 2, 0, 45, 2, 2, 0, 46, 2, 2, 0, -45, 1, 2, 0, 47, 2, 85, + 0, 48, 2, 86, 0, 49, 2, 9, 0, -94, 0, 77, 0, 8, 0, 9, 0, 50, 2, 7, 0, 51, 2, 4, 0, 52, 2, 0, 0, 20, 0, 0, + 0, 53, 2, 2, 0, 13, 1, 2, 0, 54, 2, 2, 0, 55, 2, 75, 0, 8, 0, 4, 0, 56, 2, 4, 0, 57, 2, 4, 0, 58, 2, 4, + 0, 59, 2, 0, 0, 37, 0, 0, 0, -30, 1, 0, 0, 60, 2, 0, 0, 20, 0, 79, 0, 5, 0, 4, 0, 56, 2, 4, 0, 57, 2, 0, + 0, 61, 2, 0, 0, 62, 2, 2, 0, 20, 0, 87, 0, 2, 0, 4, 0, 63, 2, 7, 0, -39, 1, 80, 0, 3, 0, 87, 0, 64, 2, 4, + 0, 65, 2, 4, 0, 20, 0, 78, 0, 6, 0, 7, 0, 66, 2, 2, 0, 67, 2, 0, 0, 20, 0, 0, 0, -30, 1, 0, 0, 62, 2, 0, + 0, 68, 2, 81, 0, 4, 0, 0, 0, -49, 0, 0, 0, -73, 0, 0, 0, -72, 0, 0, 0, -71, 0, 88, 0, 6, 0, 46, 0, 50, 2, 0, + 0, 20, 0, 0, 0, 53, 2, 2, 0, 13, 1, 2, 0, 54, 2, 2, 0, 55, 2, 89, 0, 1, 0, 7, 0, 69, 2, 90, 0, 5, 0, 0, + 0, -49, 0, 0, 0, -73, 0, 0, 0, -72, 0, 0, 0, -71, 0, 4, 0, 37, 0, 82, 0, 1, 0, 7, 0, 70, 2, 83, 0, 2, 0, 4, + 0, 71, 2, 4, 0, 18, 0, 76, 0, 7, 0, 7, 0, 51, 2, 46, 0, 50, 2, 0, 0, 20, 0, 0, 0, 53, 2, 2, 0, 13, 1, 2, + 0, 54, 2, 2, 0, 55, 2, 91, 0, 1, 0, 7, 0, 72, 2, 92, 0, 1, 0, 4, 0, 73, 2, 93, 0, 1, 0, 0, 0, 74, 2, 94, + 0, 1, 0, 7, 0, 51, 2, 95, 0, 4, 0, 7, 0, -49, 0, 7, 0, -73, 0, 7, 0, -72, 0, 7, 0, -71, 0, 96, 0, 1, 0, 95, + 0, 52, 2, 97, 0, 5, 0, 4, 0, 75, 2, 4, 0, 76, 2, 0, 0, 20, 0, 0, 0, -30, 1, 0, 0, -74, 0, 98, 0, 2, 0, 4, + 0, 77, 2, 4, 0, 76, 2, 99, 0, 14, 0, 99, 0, 0, 0, 99, 0, 1, 0, 97, 0, 78, 2, 96, 0, 79, 2, 98, 0, 80, 2, 0, + 0, 81, 2, 12, 0, 82, 2, 12, 0, 83, 2, 100, 0, 84, 2, 4, 0, 54, 0, 4, 0, 40, 2, 4, 0, 39, 2, 4, 0, 37, 0, 78, + 0, 85, 2, 85, 0, 14, 0, 12, 0, 86, 2, 78, 0, 85, 2, 0, 0, 87, 2, 0, 0, 88, 2, 0, 0, 89, 2, 0, 0, 90, 2, 0, + 0, 91, 2, 0, 0, 92, 2, 0, 0, 93, 2, 0, 0, 20, 0, 84, 0, 36, 2, 84, 0, 38, 2, 2, 0, 94, 2, 0, 0, 95, 2, 86, + 0, 8, 0, 4, 0, 96, 2, 4, 0, 97, 2, 75, 0, 98, 2, 79, 0, 99, 2, 4, 0, 40, 2, 4, 0, 39, 2, 4, 0, 54, 0, 4, + 0, 37, 0, 101, 0, 6, 0, 101, 0, 0, 0, 101, 0, 1, 0, 4, 0, 18, 0, 4, 0, 13, 1, 0, 0, 17, 0, 0, 0, 100, 2, 102, + 0, 7, 0, 101, 0, 101, 2, 2, 0, 102, 2, 2, 0, 86, 2, 2, 0, 103, 2, 2, 0, 93, 0, 9, 0, 104, 2, 9, 0, 105, 2, 103, + 0, 3, 0, 101, 0, 101, 2, 32, 0, -89, 0, 0, 0, 17, 0, 104, 0, 5, 0, 101, 0, 101, 2, 32, 0, -89, 0, 0, 0, 17, 0, 2, + 0, 106, 2, 0, 0, 107, 2, 105, 0, 5, 0, 101, 0, 101, 2, 7, 0, 91, 0, 7, 0, 108, 2, 4, 0, 109, 2, 4, 0, 110, 2, 106, + 0, 5, 0, 101, 0, 101, 2, 32, 0, 111, 2, 0, 0, 72, 0, 4, 0, 13, 1, 4, 0, 20, 0, 107, 0, 13, 0, 101, 0, 101, 2, 32, + 0, 112, 2, 32, 0, 113, 2, 32, 0, 114, 2, 32, 0, 115, 2, 7, 0, 116, 2, 7, 0, 117, 2, 7, 0, 108, 2, 7, 0, 118, 2, 4, + 0, 119, 2, 4, 0, 120, 2, 4, 0, 93, 0, 4, 0, 121, 2, 108, 0, 5, 0, 101, 0, 101, 2, 2, 0, 122, 2, 2, 0, 20, 0, 7, + 0, 123, 2, 32, 0, 124, 2, 109, 0, 3, 0, 101, 0, 101, 2, 7, 0, 125, 2, 4, 0, 93, 0, 110, 0, 10, 0, 101, 0, 101, 2, 7, + 0, 126, 2, 4, 0, 127, 2, 4, 0, 37, 0, 2, 0, 93, 0, 2, 0, -128, 2, 2, 0, -127, 2, 2, 0, -126, 2, 7, 0, -125, 2, 0, + 0, -124, 2, 111, 0, 3, 0, 101, 0, 101, 2, 7, 0, 37, 0, 4, 0, 18, 0, 112, 0, 11, 0, 101, 0, 101, 2, 51, 0, -123, 2, 7, + 0, -122, 2, 4, 0, -121, 2, 0, 0, -124, 2, 7, 0, -120, 2, 4, 0, -119, 2, 32, 0, -118, 2, 0, 0, -117, 2, 4, 0, -116, 2, 4, + 0, 37, 0, 113, 0, 10, 0, 101, 0, 101, 2, 32, 0, -115, 2, 46, 0, -114, 2, 4, 0, 93, 0, 4, 0, -113, 2, 7, 0, -112, 2, 7, + 0, -111, 2, 0, 0, -117, 2, 4, 0, -116, 2, 4, 0, 37, 0, 114, 0, 3, 0, 101, 0, 101, 2, 7, 0, -110, 2, 4, 0, -109, 2, 115, + 0, 5, 0, 101, 0, 101, 2, 7, 0, -108, 2, 0, 0, -124, 2, 2, 0, 20, 0, 2, 0, -107, 2, 116, 0, 8, 0, 101, 0, 101, 2, 32, + 0, -89, 0, 7, 0, -108, 2, 7, 0, -38, 1, 7, 0, 109, 0, 0, 0, -124, 2, 2, 0, 20, 0, 2, 0, 18, 0, 117, 0, 21, 0, 101, + 0, 101, 2, 32, 0, -106, 2, 0, 0, -124, 2, 51, 0, -123, 2, 32, 0, -118, 2, 2, 0, 20, 0, 2, 0, 37, 0, 7, 0, -105, 2, 7, + 0, -104, 2, 7, 0, -103, 2, 7, 0, -5, 1, 7, 0, -102, 2, 7, 0, -101, 2, 7, 0, -100, 2, 7, 0, -99, 2, 4, 0, -119, 2, 4, + 0, -116, 2, 0, 0, -117, 2, 7, 0, -98, 2, 7, 0, -97, 2, 7, 0, 43, 0, 118, 0, 7, 0, 101, 0, 101, 2, 2, 0, -96, 2, 2, + 0, -95, 2, 4, 0, 70, 0, 32, 0, -89, 0, 7, 0, -94, 2, 0, 0, -124, 2, 119, 0, 9, 0, 101, 0, 101, 2, 32, 0, -89, 0, 7, + 0, -93, 2, 7, 0, -92, 2, 7, 0, -99, 2, 4, 0, -91, 2, 4, 0, -90, 2, 7, 0, -89, 2, 0, 0, 17, 0, 120, 0, 1, 0, 101, + 0, 101, 2, 121, 0, 5, 0, 101, 0, 101, 2, 122, 0, -88, 2, 123, 0, -87, 2, 124, 0, -86, 2, 125, 0, -85, 2, 126, 0, 14, 0, 101, + 0, 101, 2, 78, 0, -84, 2, 78, 0, -83, 2, 78, 0, -82, 2, 78, 0, -81, 2, 78, 0, -80, 2, 78, 0, -79, 2, 75, 0, -78, 2, 4, + 0, -77, 2, 4, 0, -76, 2, 2, 0, -75, 2, 2, 0, 37, 0, 7, 0, -74, 2, 127, 0, -73, 2, -128, 0, 3, 0, 101, 0, 101, 2, -127, + 0, -72, 2, -126, 0, -73, 2, -125, 0, 4, 0, 101, 0, 101, 2, 32, 0, -89, 0, 4, 0, -71, 2, 4, 0, 37, 0, -124, 0, 2, 0, 4, + 0, -70, 2, 7, 0, -39, 1, -123, 0, 2, 0, 4, 0, -127, 0, 4, 0, -69, 2, -122, 0, 20, 0, 101, 0, 101, 2, 32, 0, -89, 0, 0, + 0, -124, 2, 2, 0, -68, 2, 2, 0, -67, 2, 2, 0, 20, 0, 2, 0, 37, 0, 7, 0, -66, 2, 7, 0, -65, 2, 4, 0, 54, 0, 4, + 0, -64, 2, -123, 0, -63, 2, -124, 0, -62, 2, 4, 0, -61, 2, 4, 0, -60, 2, 4, 0, -59, 2, 4, 0, -69, 2, 7, 0, -58, 2, 7, + 0, -57, 2, 7, 0, -56, 2, -121, 0, 8, 0, 101, 0, 101, 2, -120, 0, -55, 2, -127, 0, -72, 2, 4, 0, -54, 2, 4, 0, -53, 2, 4, + 0, -52, 2, 2, 0, 20, 0, 2, 0, 57, 0, -119, 0, 5, 0, 101, 0, 101, 2, 32, 0, 45, 0, 2, 0, -51, 2, 2, 0, 20, 0, 2, + 0, -50, 2, -118, 0, 5, 0, 101, 0, 101, 2, 4, 0, -49, 2, 2, 0, 20, 0, 2, 0, -48, 2, 7, 0, -47, 2, -117, 0, 3, 0, 101, + 0, 101, 2, -116, 0, -46, 2, 125, 0, -85, 2, -115, 0, 10, 0, 101, 0, 101, 2, 32, 0, -45, 2, 32, 0, -44, 2, 0, 0, -43, 2, 7, + 0, -42, 2, 2, 0, -41, 2, 2, 0, -40, 2, 0, 0, -39, 2, 0, 0, -38, 2, 0, 0, 107, 2, -114, 0, 9, 0, 101, 0, 101, 2, 32, + 0, -37, 2, 0, 0, -43, 2, 7, 0, -36, 2, 7, 0, -35, 2, 0, 0, 13, 1, 0, 0, 122, 2, 0, 0, -34, 2, 0, 0, 37, 0, -113, + 0, 24, 0, 27, 0, 31, 0, 2, 0, -29, 1, 2, 0, -28, 1, 2, 0, -33, 2, 2, 0, 20, 0, 2, 0, -32, 2, 2, 0, -31, 2, 2, + 0, -30, 2, 2, 0, 70, 0, 0, 0, -29, 2, 0, 0, -28, 2, 0, 0, -27, 2, 0, 0, 18, 0, 4, 0, 37, 0, 7, 0, -26, 2, 7, + 0, -25, 2, 7, 0, -24, 2, 7, 0, -23, 2, 7, 0, -22, 2, 7, 0, -21, 2, 34, 0, -20, 2, 36, 0, 79, 0, 38, 0, -9, 1, 80, + 0, 31, 2, -112, 0, 3, 0, -112, 0, 0, 0, -112, 0, 1, 0, 0, 0, 17, 0, 67, 0, 3, 0, 7, 0, -19, 2, 4, 0, 20, 0, 4, + 0, 37, 0, 32, 0, 111, 0, 27, 0, 31, 0, 2, 0, 18, 0, 2, 0, -18, 2, 4, 0, -17, 2, 4, 0, -16, 2, 4, 0, -15, 2, 0, + 0, -14, 2, 32, 0, 38, 0, 32, 0, -13, 2, 32, 0, -12, 2, 32, 0, -11, 2, 32, 0, -10, 2, 36, 0, 79, 0, 73, 0, -10, 1, 67, + 0, -66, 1, -111, 0, -9, 2, -111, 0, -8, 2, -110, 0, -7, 2, 9, 0, 2, 0, 12, 0, -6, 2, 12, 0, 25, 2, 12, 0, -47, 1, 12, + 0, -5, 2, 12, 0, -4, 2, 62, 0, -46, 1, 7, 0, 7, 1, 7, 0, -3, 2, 7, 0, -2, 2, 7, 0, -81, 0, 7, 0, -1, 2, 7, + 0, 8, 1, 7, 0, 0, 3, 7, 0, 1, 3, 7, 0, -93, 2, 7, 0, 2, 3, 7, 0, -45, 0, 4, 0, 3, 3, 2, 0, 20, 0, 2, + 0, 4, 3, 2, 0, 5, 3, 2, 0, 6, 3, 2, 0, 7, 3, 2, 0, 8, 3, 2, 0, 9, 3, 2, 0, 10, 3, 2, 0, 11, 3, 2, + 0, 12, 3, 2, 0, 13, 3, 2, 0, 14, 3, 4, 0, 15, 3, 4, 0, 16, 3, 4, 0, 17, 3, 4, 0, 18, 3, 7, 0, 19, 3, 7, + 0, 20, 3, 7, 0, 21, 3, 7, 0, 22, 3, 7, 0, 23, 3, 7, 0, 24, 3, 7, 0, 25, 3, 7, 0, 26, 3, 7, 0, 27, 3, 7, + 0, 28, 3, 7, 0, 29, 3, 7, 0, 30, 3, 0, 0, 31, 3, 0, 0, 32, 3, 0, 0, -45, 1, 0, 0, 33, 3, 0, 0, 34, 3, 0, + 0, 35, 3, 7, 0, 36, 3, 7, 0, 37, 3, 39, 0, 125, 0, 12, 0, 38, 3, 12, 0, 39, 3, 12, 0, 40, 3, 12, 0, 41, 3, 7, + 0, 42, 3, 2, 0, 71, 2, 2, 0, 43, 3, 7, 0, 52, 2, 4, 0, 44, 3, 4, 0, 45, 3, -109, 0, 46, 3, 2, 0, 47, 3, 2, + 0, -38, 0, 7, 0, 48, 3, 12, 0, 49, 3, 12, 0, 50, 3, 12, 0, 51, 3, 12, 0, 52, 3, -108, 0, 53, 3, -107, 0, 54, 3, 63, + 0, 55, 3, 2, 0, 56, 3, 2, 0, 57, 3, 2, 0, 58, 3, 2, 0, 59, 3, 7, 0, 44, 2, 2, 0, 60, 3, 2, 0, 61, 3, -116, + 0, 62, 3, -127, 0, 63, 3, -127, 0, 64, 3, 4, 0, 65, 3, 4, 0, 66, 3, 4, 0, 67, 3, 4, 0, 70, 0, 9, 0, -94, 0, 12, + 0, 68, 3, -106, 0, 14, 0, -106, 0, 0, 0, -106, 0, 1, 0, 32, 0, 38, 0, 7, 0, -93, 2, 7, 0, 9, 1, 7, 0, -92, 2, 7, + 0, -99, 2, 0, 0, 17, 0, 4, 0, -91, 2, 4, 0, -90, 2, 4, 0, 69, 3, 2, 0, 18, 0, 2, 0, 70, 3, 7, 0, -89, 2, -108, + 0, 36, 0, 2, 0, 71, 3, 2, 0, 72, 3, 2, 0, 20, 0, 2, 0, -99, 2, 7, 0, 73, 3, 7, 0, 74, 3, 7, 0, 75, 3, 7, + 0, 76, 3, 7, 0, 77, 3, 7, 0, 78, 3, 7, 0, 79, 3, 7, 0, 80, 3, 7, 0, 81, 3, 7, 0, 82, 3, 7, 0, 83, 3, 7, + 0, 84, 3, 7, 0, 85, 3, 7, 0, 86, 3, 7, 0, 87, 3, 7, 0, 88, 3, 7, 0, 89, 3, 7, 0, 90, 3, 7, 0, 91, 3, 7, + 0, 92, 3, 7, 0, 93, 3, 7, 0, 94, 3, 7, 0, 95, 3, 7, 0, 96, 3, 2, 0, 97, 3, 2, 0, 98, 3, 2, 0, 99, 3, 2, + 0, 100, 3, 51, 0, -88, 0, -105, 0, 101, 3, 7, 0, 102, 3, 4, 0, 110, 2, 125, 0, 5, 0, 4, 0, 20, 0, 4, 0, 103, 3, 4, + 0, 104, 3, 4, 0, 105, 3, 4, 0, 106, 3, -104, 0, 1, 0, 7, 0, -31, 1, -109, 0, 30, 0, 4, 0, 20, 0, 7, 0, 107, 3, 7, + 0, 108, 3, 7, 0, 109, 3, 4, 0, 110, 3, 4, 0, 111, 3, 4, 0, 112, 3, 4, 0, 113, 3, 7, 0, 114, 3, 7, 0, 115, 3, 7, + 0, 116, 3, 7, 0, 117, 3, 7, 0, 118, 3, 7, 0, 119, 3, 7, 0, 120, 3, 7, 0, 121, 3, 7, 0, 122, 3, 7, 0, 123, 3, 7, + 0, 124, 3, 7, 0, 125, 3, 7, 0, 126, 3, 7, 0, 127, 3, 7, 0, -128, 3, 7, 0, -127, 3, 7, 0, -126, 3, 7, 0, -125, 3, 4, + 0, -124, 3, 4, 0, -123, 3, 7, 0, -122, 3, 7, 0, 27, 3, -107, 0, 49, 0, -120, 0, -121, 3, 4, 0, -120, 3, 4, 0, -119, 3, -103, + 0, -118, 3, -102, 0, -117, 3, 0, 0, 37, 0, 0, 0, -116, 3, 2, 0, -115, 3, 7, 0, -114, 3, 0, 0, -113, 3, 7, 0, -112, 3, 7, + 0, -111, 3, 7, 0, -110, 3, 7, 0, -109, 3, 7, 0, -108, 3, 7, 0, -107, 3, 7, 0, -106, 3, 7, 0, -105, 3, 7, 0, -104, 3, 2, + 0, -103, 3, 0, 0, -102, 3, 2, 0, -101, 3, 7, 0, -100, 3, 7, 0, -99, 3, 0, 0, -98, 3, 4, 0, -126, 0, 4, 0, -97, 3, 4, + 0, -96, 3, 2, 0, -95, 3, 2, 0, -94, 3, -104, 0, -93, 3, 4, 0, -92, 3, 4, 0, 81, 0, 7, 0, -91, 3, 7, 0, -90, 3, 7, + 0, -89, 3, 7, 0, -88, 3, 2, 0, -87, 3, 2, 0, -86, 3, 2, 0, -85, 3, 2, 0, -84, 3, 2, 0, -83, 3, 2, 0, -82, 3, 2, + 0, -81, 3, 2, 0, -80, 3, -101, 0, -79, 3, 7, 0, -78, 3, 7, 0, -77, 3, 125, 0, -76, 3, -116, 0, 48, 0, 2, 0, 18, 0, 2, + 0, -75, 3, 2, 0, -74, 3, 2, 0, -73, 3, 7, 0, -72, 3, 2, 0, -71, 3, 2, 0, -70, 3, 7, 0, -69, 3, 2, 0, -68, 3, 2, + 0, -67, 3, 7, 0, -66, 3, 7, 0, -65, 3, 7, 0, -64, 3, 7, 0, -63, 3, 7, 0, -62, 3, 7, 0, -61, 3, 4, 0, -60, 3, 7, + 0, -59, 3, 7, 0, -58, 3, 7, 0, -57, 3, 74, 0, -56, 3, 74, 0, -55, 3, 74, 0, -54, 3, 0, 0, -53, 3, 7, 0, -52, 3, 7, + 0, -51, 3, 36, 0, 79, 0, 2, 0, -50, 3, 0, 0, -49, 3, 0, 0, -48, 3, 7, 0, -47, 3, 4, 0, -46, 3, 7, 0, -45, 3, 7, + 0, -44, 3, 4, 0, -43, 3, 4, 0, 20, 0, 7, 0, -42, 3, 7, 0, -41, 3, 7, 0, -40, 3, 78, 0, -39, 3, 7, 0, -38, 3, 7, + 0, -37, 3, 7, 0, -36, 3, 7, 0, -35, 3, 7, 0, -34, 3, 7, 0, -33, 3, 7, 0, -32, 3, 4, 0, -31, 3, -100, 0, 71, 0, 27, + 0, 31, 0, 2, 0, -79, 0, 2, 0, 14, 1, 2, 0, 47, 1, 2, 0, -30, 3, 7, 0, -29, 3, 7, 0, -28, 3, 7, 0, -27, 3, 7, + 0, -26, 3, 7, 0, -25, 3, 7, 0, -24, 3, 7, 0, -23, 3, 7, 0, -22, 3, 7, 0, 84, 1, 7, 0, 86, 1, 7, 0, 85, 1, 7, + 0, -21, 3, 4, 0, -20, 3, 7, 0, -19, 3, 7, 0, -18, 3, 7, 0, -17, 3, 7, 0, -16, 3, 7, 0, -15, 3, 7, 0, -14, 3, 7, + 0, -13, 3, 2, 0, -12, 3, 2, 0, 13, 1, 2, 0, -11, 3, 2, 0, -10, 3, 2, 0, -9, 3, 2, 0, -8, 3, 2, 0, -7, 3, 2, + 0, -6, 3, 7, 0, -5, 3, 7, 0, -4, 3, 7, 0, -3, 3, 7, 0, -2, 3, 7, 0, -1, 3, 7, 0, 0, 4, 7, 0, 1, 4, 7, + 0, 2, 4, 7, 0, 3, 4, 7, 0, 4, 4, 7, 0, 5, 4, 7, 0, 6, 4, 2, 0, 7, 4, 2, 0, 8, 4, 2, 0, 9, 4, 2, + 0, 10, 4, 7, 0, 11, 4, 7, 0, 12, 4, 7, 0, 13, 4, 7, 0, 14, 4, 2, 0, 15, 4, 2, 0, 16, 4, 2, 0, 17, 4, 2, + 0, 18, 4, 7, 0, 19, 4, 7, 0, 20, 4, 7, 0, 21, 4, 7, 0, 22, 4, 2, 0, 23, 4, 2, 0, 24, 4, 2, 0, 25, 4, 2, + 0, 43, 0, 7, 0, 26, 4, 7, 0, 27, 4, 36, 0, 79, 0, 50, 0, 77, 1, 30, 0, -103, 0, 39, 0, 125, 0, -99, 0, 16, 0, 2, + 0, 28, 4, 2, 0, 29, 4, 2, 0, 30, 4, 2, 0, 20, 0, 2, 0, 31, 4, 2, 0, 32, 4, 2, 0, 33, 4, 2, 0, 34, 4, 2, + 0, 35, 4, 2, 0, 36, 4, 2, 0, 37, 4, 2, 0, 38, 4, 4, 0, 39, 4, 7, 0, 40, 4, 7, 0, 41, 4, 7, 0, 42, 4, -98, + 0, 8, 0, -98, 0, 0, 0, -98, 0, 1, 0, 4, 0, 3, 3, 4, 0, 43, 4, 4, 0, 20, 0, 2, 0, 44, 4, 2, 0, 45, 4, 32, + 0, -89, 0, -97, 0, 13, 0, 9, 0, 46, 4, 9, 0, 47, 4, 4, 0, 48, 4, 4, 0, 49, 4, 4, 0, 50, 4, 4, 0, 51, 4, 4, + 0, 52, 4, 4, 0, 53, 4, 4, 0, 54, 4, 4, 0, 55, 4, 4, 0, 56, 4, 4, 0, 37, 0, 0, 0, 57, 4, -96, 0, 5, 0, 9, + 0, 58, 4, 9, 0, 59, 4, 4, 0, 60, 4, 4, 0, 70, 0, 0, 0, 61, 4, -95, 0, 13, 0, 4, 0, 18, 0, 4, 0, 62, 4, 4, + 0, 63, 4, 4, 0, 64, 4, 4, 0, 65, 4, 4, 0, 66, 4, 4, 0, 93, 0, 4, 0, 67, 4, 4, 0, 68, 4, 4, 0, 69, 4, 4, + 0, 70, 4, 4, 0, 71, 4, 26, 0, 30, 0, -94, 0, 4, 0, 4, 0, 72, 4, 7, 0, 73, 4, 2, 0, 20, 0, 2, 0, 68, 2, -93, + 0, 11, 0, -93, 0, 0, 0, -93, 0, 1, 0, 0, 0, 17, 0, 62, 0, 74, 4, 63, 0, 75, 4, 4, 0, 3, 3, 4, 0, 76, 4, 4, + 0, 77, 4, 4, 0, 37, 0, 4, 0, 78, 4, 4, 0, 79, 4, -92, 0, -126, 0, -97, 0, 80, 4, -96, 0, 81, 4, -95, 0, 82, 4, 4, + 0, 83, 4, 4, 0, -126, 0, 4, 0, -97, 3, 4, 0, 84, 4, 4, 0, 85, 4, 4, 0, 86, 4, 4, 0, 87, 4, 2, 0, 20, 0, 2, + 0, 88, 4, 7, 0, 20, 3, 7, 0, 89, 4, 7, 0, 90, 4, 7, 0, 91, 4, 7, 0, 92, 4, 7, 0, 93, 4, 2, 0, 94, 4, 2, + 0, 95, 4, 2, 0, 96, 4, 2, 0, 97, 4, 2, 0, -39, 0, 2, 0, 98, 4, 2, 0, 99, 4, 2, 0, 100, 3, 2, 0, 100, 4, 2, + 0, 101, 4, 2, 0, 34, 1, 2, 0, 109, 0, 2, 0, 102, 4, 2, 0, 103, 4, 2, 0, 104, 4, 2, 0, 105, 4, 2, 0, 106, 4, 2, + 0, 107, 4, 2, 0, 108, 4, 2, 0, 109, 4, 2, 0, 110, 4, 2, 0, 35, 1, 2, 0, 111, 4, 2, 0, 112, 4, 2, 0, 113, 4, 2, + 0, 114, 4, 4, 0, 115, 4, 4, 0, 13, 1, 2, 0, 116, 4, 2, 0, 117, 4, 2, 0, 118, 4, 2, 0, 119, 4, 2, 0, 120, 4, 2, + 0, 121, 4, 24, 0, 122, 4, 24, 0, 123, 4, 23, 0, 124, 4, 12, 0, 125, 4, 2, 0, 126, 4, 2, 0, 37, 0, 7, 0, 127, 4, 7, + 0, -128, 4, 7, 0, -127, 4, 7, 0, -126, 4, 7, 0, -125, 4, 7, 0, -124, 4, 7, 0, -123, 4, 7, 0, -122, 4, 7, 0, -121, 4, 2, + 0, -120, 4, 2, 0, -119, 4, 2, 0, -118, 4, 2, 0, -117, 4, 2, 0, -116, 4, 2, 0, -115, 4, 7, 0, -114, 4, 7, 0, -113, 4, 7, + 0, -112, 4, 2, 0, -111, 4, 2, 0, -110, 4, 2, 0, -109, 4, 2, 0, -108, 4, 2, 0, -107, 4, 2, 0, -106, 4, 2, 0, -105, 4, 2, + 0, -104, 4, 2, 0, -103, 4, 2, 0, -102, 4, 4, 0, -101, 4, 4, 0, -100, 4, 4, 0, -99, 4, 4, 0, -98, 4, 4, 0, -97, 4, 7, + 0, -96, 4, 4, 0, -95, 4, 4, 0, -94, 4, 4, 0, -93, 4, 4, 0, -92, 4, 7, 0, -91, 4, 7, 0, -90, 4, 7, 0, -89, 4, 7, + 0, -88, 4, 7, 0, -87, 4, 7, 0, -86, 4, 7, 0, -85, 4, 7, 0, -84, 4, 7, 0, -83, 4, 0, 0, -82, 4, 0, 0, -81, 4, 4, + 0, -80, 4, 2, 0, -79, 4, 2, 0, 12, 1, 0, 0, -78, 4, 7, 0, -77, 4, 7, 0, -76, 4, 4, 0, -75, 4, 4, 0, -74, 4, 7, + 0, -73, 4, 7, 0, -72, 4, 2, 0, -71, 4, 2, 0, -70, 4, 7, 0, -69, 4, 2, 0, -68, 4, 2, 0, -67, 4, 4, 0, -66, 4, 2, + 0, -65, 4, 2, 0, -64, 4, 2, 0, -63, 4, 2, 0, -62, 4, 7, 0, -61, 4, 7, 0, 70, 0, 42, 0, -60, 4, -91, 0, 9, 0, -91, + 0, 0, 0, -91, 0, 1, 0, 0, 0, 17, 0, 2, 0, -59, 4, 2, 0, -58, 4, 2, 0, -57, 4, 2, 0, 43, 0, 7, 0, -56, 4, 7, + 0, 70, 0, -90, 0, 5, 0, 7, 0, -55, 4, 0, 0, 18, 0, 0, 0, 43, 0, 0, 0, 70, 0, 0, 0, 12, 1, -89, 0, 5, 0, -89, + 0, 0, 0, -89, 0, 1, 0, 4, 0, -54, 4, 0, 0, -53, 4, 4, 0, 20, 0, -88, 0, 5, 0, -87, 0, -52, 4, 2, 0, 20, 0, 2, + 0, -51, 4, 2, 0, -50, 4, 2, 0, -49, 4, -86, 0, 4, 0, 2, 0, 109, 0, 2, 0, -122, 2, 2, 0, -48, 4, 2, 0, -47, 4, -85, + 0, 7, 0, 2, 0, 20, 0, 2, 0, -46, 4, 2, 0, -45, 4, 2, 0, -44, 4, -86, 0, -43, 4, 7, 0, -42, 4, 4, 0, -41, 4, -84, + 0, 4, 0, -84, 0, 0, 0, -84, 0, 1, 0, 0, 0, -40, 4, 7, 0, -39, 4, -83, 0, 56, 0, 2, 0, -38, 4, 2, 0, -37, 4, 7, + 0, -36, 4, 7, 0, -35, 4, 2, 0, -48, 4, 2, 0, -34, 4, 7, 0, -33, 4, 7, 0, -32, 4, 2, 0, -31, 4, 2, 0, -30, 4, 2, + 0, -29, 4, 2, 0, -28, 4, 7, 0, -27, 4, 7, 0, -26, 4, 7, 0, -25, 4, 7, 0, 37, 0, 2, 0, -24, 4, 2, 0, -23, 4, 2, + 0, -22, 4, 2, 0, -21, 4, -88, 0, -20, 4, -85, 0, -19, 4, 7, 0, -18, 4, 7, 0, -17, 4, 0, 0, -16, 4, 0, 0, -15, 4, 0, + 0, -14, 4, 0, 0, -13, 4, 0, 0, -12, 4, 0, 0, -11, 4, 2, 0, -10, 4, 7, 0, -9, 4, 7, 0, -8, 4, 7, 0, -7, 4, 7, + 0, -6, 4, 7, 0, -5, 4, 7, 0, -4, 4, 7, 0, -3, 4, 7, 0, -2, 4, 7, 0, -1, 4, 7, 0, 0, 5, 2, 0, 1, 5, 0, + 0, 2, 5, 0, 0, 3, 5, 0, 0, 4, 5, 0, 0, 5, 5, 32, 0, 6, 5, 0, 0, 7, 5, 0, 0, 8, 5, 0, 0, 9, 5, 0, + 0, 10, 5, 0, 0, 11, 5, 0, 0, 12, 5, 0, 0, 13, 5, 0, 0, 14, 5, 0, 0, 15, 5, -82, 0, 6, 0, 2, 0, 109, 0, 0, + 0, -122, 2, 0, 0, 16, 5, 0, 0, 17, 5, 0, 0, 20, 0, 0, 0, -74, 0, -81, 0, 26, 0, -80, 0, 18, 5, 50, 0, 77, 1, 60, + 0, 19, 5, -82, 0, 20, 5, -82, 0, 21, 5, -82, 0, 22, 5, -82, 0, 23, 5, -82, 0, 24, 5, -82, 0, 25, 5, -82, 0, 26, 5, 7, + 0, 27, 5, 2, 0, 28, 5, 2, 0, 47, 1, 2, 0, 29, 5, 2, 0, 1, 2, 0, 0, 30, 5, 0, 0, 31, 5, 0, 0, 32, 5, 0, + 0, 33, 5, 0, 0, 93, 0, 0, 0, 34, 5, 0, 0, 35, 5, 0, 0, 36, 5, 0, 0, 37, 5, 0, 0, 38, 5, 0, 0, -74, 0, -79, + 0, 43, 0, 27, 0, 31, 0, 32, 0, 39, 5, -100, 0, 40, 5, -79, 0, 41, 5, 46, 0, -47, 0, 12, 0, 42, 5, -98, 0, 43, 5, 7, + 0, 44, 5, 7, 0, 45, 5, 7, 0, 46, 5, 7, 0, 47, 5, 4, 0, 3, 3, 7, 0, 48, 5, 2, 0, 49, 5, 2, 0, 50, 5, 2, + 0, 51, 5, 2, 0, 52, 5, 2, 0, 53, 5, 2, 0, 54, 5, 2, 0, 55, 5, 2, 0, 5, 1, 57, 0, 1, 1, 9, 0, 56, 5, -99, + 0, 57, 5, -90, 0, 58, 5, -83, 0, 59, 5, -92, 0, -73, 0, -94, 0, 60, 5, 39, 0, 125, 0, 12, 0, 103, 0, 12, 0, 61, 5, 2, + 0, 62, 5, 2, 0, 63, 5, 2, 0, 64, 5, 2, 0, 65, 5, -78, 0, 66, 5, 2, 0, 67, 5, 2, 0, 68, 5, 2, 0, 64, 1, 2, + 0, -38, 0, -81, 0, 69, 5, 4, 0, 70, 5, 4, 0, 37, 0, -77, 0, 9, 0, 46, 0, -47, 0, 45, 0, 0, 1, 7, 0, 8, 2, 7, + 0, 9, 2, 7, 0, 109, 0, 7, 0, 71, 5, 7, 0, 72, 5, 2, 0, 73, 5, 2, 0, 74, 5, -76, 0, 75, 0, -75, 0, 0, 0, -75, + 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, 2, 0, 78, 5, 7, 0, 79, 5, 7, 0, 80, 5, 7, 0, 81, 5, 7, + 0, 82, 5, 7, 0, 83, 5, 7, 0, 84, 5, 7, 0, 85, 5, 7, 0, 20, 1, 7, 0, 86, 5, 4, 0, 87, 5, 2, 0, 88, 5, 2, + 0, 17, 5, 32, 0, 39, 5, 32, 0, 89, 5, -77, 0, 90, 5, -76, 0, 91, 5, -73, 0, 92, 5, -72, 0, 93, 5, -71, 0, 94, 5, 0, + 0, 95, 5, 2, 0, 30, 4, 2, 0, 96, 5, 4, 0, 3, 3, 4, 0, 97, 5, 2, 0, 98, 5, 2, 0, 99, 5, 2, 0, 100, 5, 0, + 0, 101, 5, 0, 0, 43, 0, 7, 0, 115, 0, 7, 0, 102, 5, 7, 0, 103, 5, 7, 0, 104, 5, 7, 0, 105, 5, 7, 0, 106, 5, 7, + 0, 107, 5, 7, 0, 108, 5, 7, 0, -82, 0, 7, 0, 44, 5, 2, 0, 109, 5, 2, 0, 110, 5, 2, 0, 111, 5, 2, 0, 112, 5, 2, + 0, -119, 0, 2, 0, 29, 5, 2, 0, 113, 5, 2, 0, 114, 5, 2, 0, 115, 5, 2, 0, 116, 5, 7, 0, 117, 5, 7, 0, 118, 5, 67, + 0, 119, 5, 12, 0, 120, 5, 2, 0, 121, 5, 2, 0, 53, 2, 2, 0, 122, 5, 2, 0, 20, 0, 2, 0, 123, 5, 2, 0, 124, 5, 2, + 0, 125, 5, 0, 0, 126, 5, 0, 0, 127, 5, 9, 0, -128, 5, -70, 0, -127, 5, 7, 0, -126, 5, 2, 0, -125, 5, 2, 0, -124, 5, 2, + 0, 53, 5, 2, 0, 54, 5, -69, 0, 19, 0, 24, 0, 36, 0, 24, 0, 64, 0, 23, 0, -123, 5, 23, 0, -122, 5, 23, 0, -121, 5, 7, + 0, -120, 5, 7, 0, -119, 5, 7, 0, -118, 5, 7, 0, -117, 5, 2, 0, -116, 5, 2, 0, -115, 5, 2, 0, -114, 5, 2, 0, -113, 5, 2, + 0, -112, 5, 2, 0, -111, 5, 4, 0, 20, 0, 7, 0, -110, 5, 2, 0, 99, 5, 0, 0, 107, 2, -75, 0, 6, 0, -75, 0, 0, 0, -75, + 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, 2, 0, 78, 5, -68, 0, 6, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, + 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, 2, 0, 78, 5, -67, 0, 27, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, + 0, 76, 5, -74, 0, 77, 5, 2, 0, 78, 5, 4, 0, -109, 5, 4, 0, 70, 0, -69, 0, -108, 5, 9, 0, -107, 5, 12, 0, -106, 5, 36, + 0, 79, 0, 27, 0, 80, 0, 0, 0, -105, 5, 0, 0, -104, 5, 0, 0, -103, 5, 2, 0, -102, 5, 2, 0, -101, 5, 2, 0, -100, 5, 2, + 0, -99, 5, 2, 0, 65, 0, 2, 0, 46, 0, 2, 0, -119, 0, 2, 0, -98, 5, 4, 0, 20, 0, 7, 0, -97, 5, 24, 0, 36, 0, -66, + 0, 29, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, -73, 0, 92, 5, 2, 0, 78, 5, 2, + 0, -96, 5, 2, 0, -95, 5, 2, 0, -94, 5, 2, 0, -93, 5, -69, 0, -108, 5, 2, 0, -92, 5, 2, 0, -119, 0, 2, 0, -101, 5, 2, + 0, -91, 5, 9, 0, -90, 5, 2, 0, 29, 5, 0, 0, -89, 5, 0, 0, -88, 5, 2, 0, -87, 5, 2, 0, -86, 5, 2, 0, 12, 3, 2, + 0, -85, 5, 2, 0, -84, 5, 0, 0, 37, 0, 0, 0, 20, 0, 0, 0, 47, 1, 0, 0, -83, 5, -65, 0, 16, 0, -75, 0, 0, 0, -75, + 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, 2, 0, 78, 5, -69, 0, -108, 5, 7, 0, 8, 2, 7, 0, 9, 2, 2, + 0, -92, 5, 2, 0, -82, 5, 2, 0, -81, 5, 2, 0, -80, 5, 4, 0, 20, 0, 7, 0, 71, 5, -70, 0, -127, 5, -64, 0, 33, 0, -75, + 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, 2, 0, 78, 5, -63, 0, -79, 5, 4, 0, -78, 5, 0, + 0, -77, 5, 0, 0, -76, 5, 0, 0, -75, 5, 2, 0, 18, 0, 2, 0, -74, 5, 2, 0, 20, 0, 2, 0, -73, 5, 2, 0, -72, 5, 2, + 0, -71, 5, 2, 0, -70, 5, 2, 0, 43, 0, 4, 0, 70, 0, 0, 0, -69, 5, -62, 0, -68, 5, 2, 0, -67, 5, 2, 0, -66, 5, 2, + 0, -65, 5, 2, 0, -48, 0, 9, 0, -64, 5, 9, 0, -63, 5, 9, 0, -62, 5, 9, 0, -61, 5, 9, 0, -60, 5, 2, 0, -59, 5, 0, + 0, -58, 5, -61, 0, 23, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, 2, 0, 78, 5, -69, + 0, -108, 5, 12, 0, -57, 5, 2, 0, -101, 5, 2, 0, -56, 5, 2, 0, 20, 0, 2, 0, 57, 0, 9, 0, -90, 5, 12, 0, -55, 5, -60, + 0, -54, 5, 0, 0, -53, 5, -59, 0, -52, 5, 4, 0, -51, 5, 4, 0, -50, 5, 2, 0, 18, 0, 2, 0, -49, 5, 2, 0, -48, 5, 2, + 0, -47, 5, -58, 0, 29, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, 2, 0, 78, 5, -69, + 0, -108, 5, 46, 0, -114, 2, 45, 0, 0, 1, 60, 0, 19, 5, 2, 0, 13, 1, 2, 0, -119, 0, 2, 0, -46, 5, 2, 0, -45, 5, 4, + 0, 20, 0, 2, 0, 49, 5, 2, 0, -44, 5, 2, 0, -98, 5, 2, 0, -101, 5, 7, 0, 71, 5, 0, 0, -43, 5, 0, 0, -42, 5, 0, + 0, -41, 5, 0, 0, -40, 5, 7, 0, 8, 2, 7, 0, 9, 2, 7, 0, -39, 5, 7, 0, -38, 5, -70, 0, -127, 5, -57, 0, 11, 0, -75, + 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, 2, 0, 78, 5, 2, 0, -119, 0, 2, 0, -98, 5, 2, + 0, -37, 5, 2, 0, 20, 0, -69, 0, -108, 5, -56, 0, 24, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, + 0, 77, 5, 2, 0, 78, 5, 42, 0, -36, 5, 4, 0, -35, 5, 4, 0, -34, 5, 2, 0, 93, 0, 2, 0, -119, 0, 4, 0, -33, 5, 4, + 0, -32, 5, 4, 0, -31, 5, 4, 0, -30, 5, 4, 0, -29, 5, 4, 0, -28, 5, 4, 0, -27, 5, 4, 0, -26, 5, 7, 0, -25, 5, 23, + 0, -24, 5, 23, 0, -23, 5, 4, 0, -22, 5, 4, 0, -21, 5, -55, 0, 10, 0, 27, 0, 31, 0, 9, 0, -20, 5, 9, 0, -19, 5, 9, + 0, -18, 5, 9, 0, -17, 5, 9, 0, -16, 5, 4, 0, 93, 0, 4, 0, -15, 5, 0, 0, -14, 5, 0, 0, -13, 5, -54, 0, 10, 0, -75, + 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, -55, 0, -12, 5, 2, 0, 93, 0, 2, 0, -119, 0, 4, + 0, 43, 0, 9, 0, -11, 5, -53, 0, 8, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, -69, + 0, -108, 5, 4, 0, 20, 0, 4, 0, -10, 5, -52, 0, 21, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, + 0, 77, 5, 2, 0, 78, 5, -69, 0, -108, 5, 27, 0, -9, 5, 27, 0, 80, 0, 2, 0, 20, 0, 2, 0, -119, 0, 7, 0, -8, 5, 9, + 0, -7, 5, 7, 0, 8, 2, 7, 0, 9, 2, 57, 0, 1, 1, 57, 0, -6, 5, 4, 0, -5, 5, 2, 0, -89, 5, 2, 0, 37, 0, -70, + 0, -127, 5, -51, 0, 42, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, 2, 0, 78, 5, -69, + 0, -108, 5, -50, 0, -4, 5, 0, 0, -77, 5, 0, 0, -76, 5, 0, 0, -75, 5, 2, 0, 18, 0, 2, 0, -66, 5, 2, 0, 20, 0, 2, + 0, -73, 5, 9, 0, -7, 5, 4, 0, -3, 5, 4, 0, -2, 5, 4, 0, -1, 5, 4, 0, 0, 6, 23, 0, 1, 6, 23, 0, 2, 6, 7, + 0, 3, 6, 7, 0, 4, 6, 7, 0, 5, 6, 7, 0, -8, 5, 2, 0, -67, 5, 2, 0, -48, 0, 2, 0, 102, 1, 2, 0, 6, 6, 2, + 0, 37, 0, 2, 0, 43, 0, 2, 0, 7, 6, 2, 0, 8, 6, 9, 0, -64, 5, 9, 0, -63, 5, 9, 0, -62, 5, 9, 0, -61, 5, 9, + 0, -60, 5, 2, 0, -59, 5, 0, 0, -58, 5, 56, 0, 9, 6, -49, 0, 20, 0, 0, 0, 10, 6, 0, 0, 11, 6, 0, 0, 12, 6, 0, + 0, 13, 6, 0, 0, 14, 6, 0, 0, 15, 6, 0, 0, 16, 6, 0, 0, 17, 6, 0, 0, 18, 6, 0, 0, 19, 6, 0, 0, 20, 6, 0, + 0, 21, 6, 0, 0, 22, 6, 0, 0, 23, 6, 0, 0, 24, 6, 0, 0, 25, 6, 0, 0, 26, 6, 0, 0, 27, 6, 0, 0, 68, 2, 0, + 0, 28, 6, -48, 0, 54, 0, 0, 0, 29, 6, 0, 0, 20, 6, 0, 0, 21, 6, 0, 0, 30, 6, 0, 0, 31, 6, 0, 0, 32, 6, 0, + 0, 33, 6, 0, 0, 34, 6, 0, 0, 35, 6, 0, 0, 36, 6, 0, 0, 37, 6, 0, 0, 38, 6, 0, 0, 39, 6, 0, 0, 40, 6, 0, + 0, 41, 6, 0, 0, 42, 6, 0, 0, 43, 6, 0, 0, 44, 6, 0, 0, 45, 6, 0, 0, 46, 6, 0, 0, 47, 6, 0, 0, 48, 6, 0, + 0, 49, 6, 0, 0, 50, 6, 0, 0, 51, 6, 0, 0, 52, 6, 0, 0, 53, 6, 0, 0, 54, 6, 0, 0, 55, 6, 0, 0, 56, 6, 0, + 0, 57, 6, 0, 0, 58, 6, 0, 0, 95, 0, 0, 0, 59, 6, 0, 0, 60, 6, 0, 0, 61, 6, 0, 0, 62, 6, 0, 0, 63, 6, 0, + 0, 64, 6, 0, 0, 65, 6, 0, 0, 66, 6, 0, 0, 67, 6, 0, 0, 68, 6, 0, 0, 69, 6, 0, 0, 70, 6, 0, 0, 71, 6, 0, + 0, 72, 6, 0, 0, 73, 6, 0, 0, 74, 6, 0, 0, 75, 6, 0, 0, 76, 6, 0, 0, 77, 6, 0, 0, 78, 6, 0, 0, 79, 6, -47, + 0, 5, 0, 0, 0, 80, 6, 0, 0, 37, 6, 0, 0, 39, 6, 2, 0, 20, 0, 2, 0, 37, 0, -46, 0, 22, 0, -46, 0, 0, 0, -46, + 0, 1, 0, 0, 0, 17, 0, -49, 0, 81, 6, -48, 0, 82, 6, -48, 0, 83, 6, -48, 0, 84, 6, -48, 0, 85, 6, -48, 0, 86, 6, -48, + 0, 87, 6, -48, 0, 88, 6, -48, 0, 89, 6, -48, 0, 90, 6, -48, 0, 91, 6, -48, 0, 92, 6, -48, 0, 93, 6, -48, 0, 94, 6, -48, + 0, 95, 6, -48, 0, 96, 6, -47, 0, 97, 6, 0, 0, 98, 6, 0, 0, 99, 6, -45, 0, 5, 0, 4, 0, 20, 0, 4, 0, 37, 0, 7, + 0, 52, 2, 7, 0, 100, 6, 7, 0, -31, 1, -44, 0, 66, 0, 4, 0, 20, 0, 4, 0, 101, 6, 4, 0, 102, 6, 0, 0, 103, 6, 0, + 0, 104, 6, 0, 0, 105, 6, 0, 0, 106, 6, 0, 0, 107, 6, 0, 0, 108, 6, 0, 0, 109, 6, 0, 0, 110, 6, 0, 0, 111, 6, 2, + 0, 112, 6, 2, 0, 113, 6, 4, 0, 114, 6, 4, 0, 115, 6, 4, 0, 116, 6, 4, 0, 117, 6, 2, 0, 118, 6, 2, 0, 119, 6, 2, + 0, 120, 6, 2, 0, 121, 6, 4, 0, 122, 6, 4, 0, 123, 6, 2, 0, 124, 6, 2, 0, 125, 6, 2, 0, 126, 6, 2, 0, 127, 6, 0, + 0, -128, 6, 12, 0, -127, 6, 2, 0, -126, 6, 2, 0, -125, 6, 2, 0, -124, 6, 2, 0, -123, 6, 2, 0, -122, 6, 2, 0, -121, 6, 2, + 0, -120, 6, 2, 0, -119, 6, -45, 0, -118, 6, 2, 0, -117, 6, 2, 0, -116, 6, 2, 0, -115, 6, 2, 0, -114, 6, 4, 0, -113, 6, 4, + 0, -112, 6, 4, 0, -111, 6, 4, 0, -110, 6, 2, 0, -109, 6, 2, 0, -108, 6, 2, 0, -107, 6, 2, 0, -106, 6, 2, 0, -105, 6, 2, + 0, -104, 6, 2, 0, -103, 6, 2, 0, -102, 6, 2, 0, -101, 6, 2, 0, -100, 6, 2, 0, -99, 6, 2, 0, 37, 0, 0, 0, -98, 6, 0, + 0, -97, 6, 0, 0, -96, 6, 7, 0, -95, 6, 2, 0, 55, 5, 2, 0, -94, 6, 54, 0, -93, 6, -43, 0, 18, 0, 27, 0, 31, 0, 12, + 0, -92, 6, 12, 0, -91, 6, 12, 0, -90, 6, -79, 0, -89, 6, 2, 0, -105, 2, 2, 0, -88, 6, 2, 0, -104, 2, 2, 0, -87, 6, 2, + 0, -86, 6, 2, 0, -85, 6, 2, 0, -84, 6, 2, 0, -83, 6, 2, 0, -82, 6, 2, 0, 37, 0, 2, 0, -81, 6, 2, 0, -80, 6, 2, + 0, -79, 6, -42, 0, 5, 0, -42, 0, 0, 0, -42, 0, 1, 0, -42, 0, -78, 6, 13, 0, -77, 6, 4, 0, 20, 0, -41, 0, 7, 0, -41, + 0, 0, 0, -41, 0, 1, 0, -42, 0, -76, 6, -42, 0, -75, 6, 2, 0, 123, 4, 2, 0, 20, 0, 4, 0, 37, 0, -40, 0, 17, 0, -40, + 0, 0, 0, -40, 0, 1, 0, 0, 0, -74, 6, 0, 0, -73, 6, 0, 0, -72, 6, 2, 0, -71, 6, 2, 0, -70, 6, 2, 0, -86, 6, 2, + 0, -85, 6, 2, 0, 20, 0, 2, 0, 70, 3, 2, 0, -69, 6, 2, 0, -68, 6, 2, 0, -67, 6, 2, 0, -66, 6, 4, 0, -65, 6, -40, + 0, -64, 6, -74, 0, 30, 0, -74, 0, 0, 0, -74, 0, 1, 0, -42, 0, -76, 6, -42, 0, -75, 6, -42, 0, -63, 6, -42, 0, -62, 6, -43, + 0, -61, 6, 7, 0, -60, 6, 23, 0, 52, 0, 23, 0, -59, 6, 23, 0, -58, 6, 2, 0, -57, 6, 2, 0, -56, 6, 2, 0, -55, 6, 0, + 0, 75, 5, 0, 0, -54, 6, 2, 0, -53, 6, 2, 0, -52, 6, 0, 0, -51, 6, 0, 0, -50, 6, 0, 0, -49, 6, 0, 0, -48, 6, 2, + 0, -47, 6, 2, 0, -46, 6, 2, 0, -45, 6, 2, 0, 20, 0, 39, 0, 125, 0, 12, 0, -44, 6, 12, 0, -43, 6, 12, 0, -42, 6, -39, + 0, 11, 0, 0, 0, -41, 6, 2, 0, -40, 6, 2, 0, -39, 6, 2, 0, -38, 6, 2, 0, -37, 6, 2, 0, -36, 6, 2, 0, 107, 4, 9, + 0, -35, 6, 9, 0, -34, 6, 4, 0, -33, 6, 4, 0, -32, 6, -38, 0, 1, 0, 0, 0, -31, 6, -37, 0, 8, 0, 56, 0, -30, 6, 56, + 0, -29, 6, -37, 0, -28, 6, -37, 0, -27, 6, -37, 0, -26, 6, 2, 0, -123, 0, 2, 0, 20, 0, 4, 0, -25, 6, -36, 0, 4, 0, 4, + 0, -35, 5, 4, 0, -24, 6, 4, 0, -31, 5, 4, 0, -23, 6, -35, 0, 2, 0, 4, 0, -22, 6, 4, 0, -21, 6, -34, 0, 9, 0, 7, + 0, -20, 6, 7, 0, -19, 6, 7, 0, -18, 6, 4, 0, 20, 0, 4, 0, 13, 1, 7, 0, -19, 3, 7, 0, -17, 6, 4, 0, 37, 0, -33, + 0, -16, 6, -32, 0, 6, 0, 0, 0, -15, 6, 0, 0, -75, 5, 48, 0, -116, 0, 2, 0, 109, 0, 2, 0, 111, 4, 4, 0, 37, 0, -31, + 0, 21, 0, -31, 0, 0, 0, -31, 0, 1, 0, 4, 0, 57, 0, 4, 0, 23, 0, 4, 0, 28, 0, 4, 0, -14, 6, 4, 0, -13, 6, 4, + 0, -12, 6, -38, 0, -11, 6, 0, 0, -15, 6, 4, 0, -10, 6, 4, 0, -9, 6, -32, 0, -12, 2, -36, 0, -8, 6, -35, 0, -7, 6, -34, + 0, -6, 6, -37, 0, -5, 6, -37, 0, -4, 6, -37, 0, -3, 6, 56, 0, -2, 6, 56, 0, -1, 6, -30, 0, 12, 0, 0, 0, -68, 1, 9, + 0, -62, 0, 0, 0, -61, 0, 4, 0, -58, 0, 4, 0, -50, 0, 9, 0, -57, 0, 7, 0, -55, 0, 7, 0, -54, 0, 9, 0, 0, 7, 9, + 0, 1, 7, 9, 0, -53, 0, 9, 0, -51, 0, -29, 0, 43, 0, -29, 0, 0, 0, -29, 0, 1, 0, 9, 0, 2, 7, 9, 0, 26, 0, 0, + 0, 27, 0, 4, 0, 20, 0, 4, 0, 18, 0, 4, 0, 23, 0, 4, 0, 91, 0, 4, 0, 3, 7, 4, 0, 4, 7, 4, 0, -13, 6, 4, + 0, -12, 6, 4, 0, 5, 7, 4, 0, -39, 0, 4, 0, 6, 7, 4, 0, 7, 7, 7, 0, 8, 7, 7, 0, 9, 7, 4, 0, -126, 0, 4, + 0, 10, 7, -31, 0, 11, 7, 36, 0, 79, 0, -79, 0, -89, 6, 48, 0, -116, 0, 7, 0, 12, 7, 7, 0, 13, 7, -30, 0, 2, 1, -29, + 0, 14, 7, -29, 0, 15, 7, -29, 0, 16, 7, 12, 0, 17, 7, -28, 0, 18, 7, -27, 0, 19, 7, 7, 0, 20, 7, 7, 0, 21, 7, 4, + 0, -84, 6, 7, 0, 22, 7, 9, 0, 23, 7, 4, 0, 24, 7, 4, 0, 25, 7, 4, 0, 26, 7, 7, 0, 27, 7, -26, 0, 4, 0, -26, + 0, 0, 0, -26, 0, 1, 0, 12, 0, 28, 7, -29, 0, 29, 7, -25, 0, 6, 0, 12, 0, 30, 7, 12, 0, 17, 7, 12, 0, 31, 7, 2, + 0, 20, 0, 2, 0, 37, 0, 4, 0, 57, 0, -24, 0, 4, 0, 7, 0, 32, 7, 7, 0, 112, 0, 2, 0, 33, 7, 2, 0, 34, 7, -23, + 0, 6, 0, 7, 0, 35, 7, 7, 0, 36, 7, 7, 0, 37, 7, 7, 0, 38, 7, 4, 0, 39, 7, 4, 0, 40, 7, -22, 0, 12, 0, 7, + 0, 41, 7, 7, 0, 42, 7, 7, 0, 43, 7, 7, 0, 44, 7, 7, 0, 45, 7, 7, 0, 46, 7, 7, 0, 47, 7, 7, 0, 48, 7, 7, + 0, 49, 7, 7, 0, 50, 7, 4, 0, -110, 2, 4, 0, 51, 7, -21, 0, 2, 0, 7, 0, -55, 4, 7, 0, 37, 0, -20, 0, 7, 0, 7, + 0, 52, 7, 7, 0, 53, 7, 4, 0, 93, 0, 4, 0, 108, 2, 4, 0, 54, 7, 4, 0, 55, 7, 4, 0, 37, 0, -19, 0, 6, 0, -19, + 0, 0, 0, -19, 0, 1, 0, 2, 0, 18, 0, 2, 0, 20, 0, 2, 0, 56, 7, 2, 0, 57, 0, -18, 0, 8, 0, -18, 0, 0, 0, -18, + 0, 1, 0, 2, 0, 18, 0, 2, 0, 20, 0, 2, 0, 56, 7, 2, 0, 57, 0, 7, 0, 23, 0, 7, 0, -126, 0, -17, 0, 45, 0, -17, + 0, 0, 0, -17, 0, 1, 0, 2, 0, 18, 0, 2, 0, 20, 0, 2, 0, 56, 7, 2, 0, -43, 0, 2, 0, -103, 3, 2, 0, 57, 7, 7, + 0, 58, 7, 7, 0, 92, 0, 7, 0, -97, 2, 4, 0, 59, 7, 4, 0, 81, 0, 4, 0, 110, 2, 7, 0, 60, 7, 7, 0, 61, 7, 7, + 0, 62, 7, 7, 0, 63, 7, 7, 0, 64, 7, 7, 0, 65, 7, 7, 0, -100, 2, 7, 0, -1, 0, 7, 0, 66, 7, 7, 0, 67, 7, 7, + 0, 37, 0, 7, 0, 68, 7, 7, 0, 69, 7, 7, 0, 70, 7, 2, 0, 71, 7, 2, 0, 72, 7, 2, 0, 73, 7, 2, 0, 74, 7, 2, + 0, 75, 7, 2, 0, 76, 7, 2, 0, 77, 7, 2, 0, 78, 7, 2, 0, 123, 5, 2, 0, 79, 7, 2, 0, -47, 1, 2, 0, 80, 7, 0, + 0, 81, 7, 0, 0, 82, 7, 7, 0, -45, 0, -16, 0, 83, 7, 63, 0, -95, 1, -15, 0, 16, 0, -15, 0, 0, 0, -15, 0, 1, 0, 2, + 0, 18, 0, 2, 0, 20, 0, 2, 0, 56, 7, 2, 0, -43, 0, 7, 0, -105, 2, 7, 0, -104, 2, 7, 0, -103, 2, 7, 0, -5, 1, 7, + 0, -102, 2, 7, 0, -101, 2, 7, 0, 84, 7, 7, 0, -100, 2, 7, 0, -98, 2, 7, 0, -97, 2, -59, 0, 5, 0, 2, 0, 18, 0, 2, + 0, -25, 6, 2, 0, 20, 0, 2, 0, 85, 7, 27, 0, -9, 5, -60, 0, 3, 0, 4, 0, 69, 0, 4, 0, 86, 7, -59, 0, 2, 0, -14, + 0, 12, 0, -14, 0, 0, 0, -14, 0, 1, 0, 2, 0, 18, 0, 2, 0, 20, 0, 2, 0, 31, 3, 2, 0, -32, 1, 7, 0, 5, 0, 7, + 0, 6, 0, 7, 0, 87, 7, 7, 0, 88, 7, 27, 0, -9, 5, 12, 0, 89, 7, -13, 0, 11, 0, -13, 0, 0, 0, -13, 0, 1, 0, 0, + 0, 17, 0, 2, 0, 18, 0, 2, 0, 90, 7, 4, 0, 22, 0, 4, 0, 91, 7, 2, 0, 20, 0, 2, 0, 37, 0, 9, 0, 92, 7, 9, + 0, 93, 7, -12, 0, 5, 0, 0, 0, 17, 0, 7, 0, 20, 1, 7, 0, 94, 7, 4, 0, 95, 7, 4, 0, 37, 0, -11, 0, 4, 0, 2, + 0, 18, 0, 2, 0, 20, 0, 2, 0, 43, 0, 2, 0, 70, 0, -10, 0, 4, 0, 0, 0, 17, 0, 62, 0, 96, 7, 7, 0, 20, 1, 7, + 0, 37, 0, -9, 0, 6, 0, 2, 0, 97, 7, 2, 0, 98, 7, 2, 0, 18, 0, 2, 0, 99, 7, 0, 0, 100, 7, 0, 0, 101, 7, -8, + 0, 5, 0, 4, 0, 18, 0, 4, 0, 37, 0, 0, 0, 17, 0, 0, 0, 102, 7, 0, 0, 103, 7, -7, 0, 3, 0, 4, 0, 18, 0, 4, + 0, 37, 0, 0, 0, 17, 0, -6, 0, 4, 0, 2, 0, 104, 7, 2, 0, 105, 7, 2, 0, 20, 0, 2, 0, 37, 0, -5, 0, 6, 0, 0, + 0, 17, 0, 0, 0, 106, 7, 2, 0, 107, 7, 2, 0, -100, 2, 2, 0, 13, 1, 2, 0, 70, 0, -4, 0, 5, 0, 0, 0, 17, 0, 7, + 0, 112, 0, 7, 0, -17, 3, 2, 0, 20, 0, 2, 0, 122, 2, -3, 0, 3, 0, 0, 0, 17, 0, 4, 0, 110, 2, 4, 0, 104, 7, -2, + 0, 7, 0, 0, 0, 17, 0, 7, 0, -17, 3, 0, 0, 108, 7, 0, 0, 109, 7, 2, 0, 13, 1, 2, 0, 43, 0, 4, 0, 110, 7, -1, + 0, 3, 0, 32, 0, 111, 7, 0, 0, 112, 7, 0, 0, 113, 7, 0, 1, 18, 0, 0, 1, 0, 0, 0, 1, 1, 0, 2, 0, 18, 0, 2, + 0, 90, 7, 2, 0, 20, 0, 2, 0, 114, 7, 2, 0, 115, 7, 2, 0, 116, 7, 2, 0, 43, 0, 2, 0, 70, 0, 0, 0, 17, 0, 9, + 0, 2, 0, 1, 1, 117, 7, 32, 0, 45, 0, 2, 0, -47, 4, 2, 0, 20, 7, 2, 0, 118, 7, 2, 0, 37, 0, 2, 1, 11, 0, 0, + 0, 17, 0, 0, 0, 18, 0, 0, 0, 119, 7, 2, 0, 20, 0, 2, 0, 122, 2, 2, 0, 120, 7, 4, 0, 121, 7, 4, 0, 122, 7, 4, + 0, 123, 7, 4, 0, 124, 7, 4, 0, 125, 7, 3, 1, 1, 0, 0, 0, 126, 7, 4, 1, 4, 0, 42, 0, -36, 5, 0, 0, 127, 7, 4, + 0, 13, 1, 4, 0, 20, 0, 1, 1, 18, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, -128, 7, 2, 0, 18, 0, 2, 0, 20, 0, 2, + 0, -127, 7, 2, 0, 116, 7, 2, 0, 90, 7, 2, 0, -126, 7, 2, 0, 70, 0, 2, 0, 12, 1, 0, 0, 17, 0, 9, 0, 2, 0, 5, + 1, 117, 7, 0, 1, -125, 7, 2, 0, 15, 0, 2, 0, -124, 7, 4, 0, -123, 7, 6, 1, 3, 0, 4, 0, -74, 2, 4, 0, 37, 0, 32, + 0, 45, 0, 7, 1, 12, 0, -111, 0, -122, 7, 2, 0, 18, 0, 2, 0, 20, 0, 4, 0, 58, 7, 4, 0, 92, 0, 0, 0, 17, 0, 0, + 0, -121, 7, 2, 0, -120, 7, 2, 0, -119, 7, 2, 0, -118, 7, 2, 0, -117, 7, 7, 0, -116, 7, 8, 1, 10, 0, 2, 0, 20, 0, 2, + 0, -115, 7, 4, 0, 58, 7, 4, 0, 92, 0, 2, 0, -114, 7, -28, 0, 18, 7, 2, 0, 18, 0, 2, 0, -113, 7, 2, 0, -112, 7, 2, + 0, -111, 7, 9, 1, 7, 0, 2, 0, 20, 0, 2, 0, -115, 7, 4, 0, 58, 7, 4, 0, 92, 0, 2, 0, 18, 0, 2, 0, -110, 7, 7, + 0, 109, 3, 10, 1, 11, 0, 4, 0, -74, 2, 2, 0, 18, 0, 2, 0, 20, 0, 32, 0, 45, 0, 74, 0, -109, 7, 0, 0, 17, 0, 7, + 0, -108, 7, 7, 0, -107, 7, 7, 0, 21, 3, 2, 0, -106, 7, 2, 0, -105, 7, 11, 1, 5, 0, 2, 0, 18, 0, 2, 0, 20, 0, 4, + 0, 37, 0, -79, 0, -89, 6, 32, 0, 39, 5, 12, 1, 5, 0, 4, 0, 20, 0, 4, 0, 18, 0, 0, 0, 17, 0, 0, 0, 102, 7, 32, + 0, 45, 0, 13, 1, 13, 0, 2, 0, 20, 0, 2, 0, 18, 0, 2, 0, 90, 7, 2, 0, 22, 3, 7, 0, -104, 7, 7, 0, -103, 7, 7, + 0, 7, 1, 7, 0, 8, 1, 7, 0, -3, 2, 7, 0, 0, 3, 7, 0, -102, 7, 7, 0, -101, 7, 32, 0, -100, 7, 14, 1, 10, 0, 2, + 0, 20, 0, 2, 0, 18, 0, 4, 0, 58, 7, 4, 0, 92, 0, 0, 0, 17, 0, 0, 0, -121, 7, 2, 0, 43, 0, 2, 0, 64, 0, 2, + 0, -99, 7, 2, 0, -98, 7, 15, 1, 8, 0, 32, 0, 45, 0, 7, 0, -103, 2, 7, 0, -97, 7, 7, 0, -96, 7, 7, 0, -108, 2, 2, + 0, 20, 0, 2, 0, 122, 2, 7, 0, -95, 7, 16, 1, 12, 0, 2, 0, 18, 0, 2, 0, 13, 1, 2, 0, 20, 0, 2, 0, -100, 2, 2, + 0, -74, 2, 2, 0, -94, 7, 4, 0, 37, 0, 7, 0, -93, 7, 7, 0, -92, 7, 7, 0, -91, 7, 7, 0, -90, 7, 0, 0, -89, 7, 17, + 1, 10, 0, 2, 0, 20, 0, 2, 0, 18, 0, 4, 0, 58, 7, 4, 0, 92, 0, 0, 0, 17, 0, 2, 0, 68, 2, 2, 0, 64, 0, 2, + 0, -99, 7, 2, 0, -98, 7, 63, 0, -95, 1, 18, 1, 7, 0, 4, 0, 110, 2, 4, 0, -88, 7, 4, 0, -87, 7, 4, 0, -86, 7, 7, + 0, -85, 7, 7, 0, -84, 7, 0, 0, 108, 7, 19, 1, 7, 0, 0, 0, -83, 7, 32, 0, -82, 7, 0, 0, 112, 7, 2, 0, -81, 7, 2, + 0, 43, 0, 4, 0, 70, 0, 0, 0, 113, 7, 20, 1, 6, 0, 2, 0, 20, 0, 2, 0, 18, 0, 4, 0, 58, 7, 4, 0, 92, 0, 0, + 0, -80, 7, 0, 0, -79, 7, 21, 1, 1, 0, 4, 0, 20, 0, 22, 1, 6, 0, 0, 0, 95, 0, 2, 0, 18, 0, 2, 0, 20, 0, 4, + 0, -78, 7, 7, 0, -77, 7, 42, 0, -36, 5, 23, 1, 4, 0, 0, 0, -74, 0, 2, 0, 20, 0, 4, 0, 18, 0, 32, 0, 45, 0, 24, + 1, 2, 0, 4, 0, 18, 0, 4, 0, -121, 5, 5, 1, 10, 0, 5, 1, 0, 0, 5, 1, 1, 0, 5, 1, -128, 7, 2, 0, 18, 0, 2, + 0, 20, 0, 2, 0, 90, 7, 2, 0, -76, 7, 0, 0, 17, 0, 9, 0, 2, 0, 32, 0, 45, 0, 25, 1, 10, 0, 7, 0, 21, 3, 7, + 0, -75, 7, 7, 0, -74, 7, 7, 0, -73, 7, 7, 0, -72, 7, 4, 0, 20, 0, 7, 0, -94, 7, 7, 0, -71, 7, 7, 0, -70, 7, 7, + 0, 37, 0, -28, 0, 20, 0, 27, 0, 31, 0, 0, 0, -63, 0, 26, 1, -69, 7, 9, 0, -68, 7, 43, 0, -104, 0, 43, 0, -67, 7, 9, + 0, -66, 7, 36, 0, 79, 0, 7, 0, 109, 3, 7, 0, -65, 7, 7, 0, -64, 7, 7, 0, -63, 7, 7, 0, -62, 7, 7, 0, -61, 7, 7, + 0, -60, 7, 4, 0, 93, 0, 4, 0, -59, 7, 0, 0, -58, 7, 0, 0, -57, 7, 0, 0, -56, 7, 27, 1, 6, 0, 27, 0, 31, 0, 7, + 0, -55, 7, 7, 0, -54, 7, 7, 0, -53, 7, 2, 0, -52, 7, 2, 0, -51, 7, 28, 1, 14, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, + 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, -69, 0, -108, 5, -28, 0, 18, 7, 2, 0, 13, 1, 2, 0, -115, 7, 2, 0, 8, 2, 2, + 0, 9, 2, 2, 0, 20, 0, 2, 0, -98, 5, 4, 0, 70, 0, 29, 1, 6, 0, 29, 1, 0, 0, 29, 1, 1, 0, 32, 0, 45, 0, 9, + 0, -50, 7, 4, 0, -38, 0, 4, 0, 37, 0, 63, 0, 4, 0, 27, 0, 31, 0, 12, 0, -49, 7, 4, 0, -121, 0, 7, 0, -48, 7, 30, + 1, 25, 0, 30, 1, 0, 0, 30, 1, 1, 0, 30, 1, 38, 0, 12, 0, -47, 7, 0, 0, 17, 0, 7, 0, -46, 7, 7, 0, -45, 7, 7, + 0, -44, 7, 7, 0, -43, 7, 4, 0, 20, 0, 7, 0, -42, 7, 7, 0, -41, 7, 7, 0, -40, 7, 7, 0, 20, 1, 7, 0, -39, 1, 7, + 0, -39, 7, 7, 0, 108, 2, 7, 0, -38, 7, 7, 0, -37, 7, 7, 0, -36, 7, 7, 0, -35, 7, 7, 0, -34, 7, 7, 0, -81, 0, 2, + 0, -121, 0, 2, 0, -31, 4, 31, 1, 19, 0, 27, 0, 31, 0, 12, 0, -33, 7, 12, 0, -32, 7, 4, 0, 20, 0, 4, 0, 30, 4, 2, + 0, -96, 2, 2, 0, -31, 7, 2, 0, -121, 0, 2, 0, -30, 7, 2, 0, -29, 7, 2, 0, -28, 7, 2, 0, -27, 7, 2, 0, -26, 7, 4, + 0, -25, 7, 4, 0, -24, 7, 4, 0, -23, 7, 4, 0, -22, 7, 4, 0, -21, 7, 4, 0, -20, 7, 32, 1, 34, 0, 32, 1, 0, 0, 32, + 1, 1, 0, 12, 0, 49, 3, 0, 0, 17, 0, 2, 0, 20, 0, 2, 0, -19, 7, 2, 0, -18, 7, 2, 0, -17, 7, 2, 0, 10, 3, 2, + 0, -16, 7, 4, 0, -7, 1, 4, 0, -23, 7, 4, 0, -22, 7, 30, 1, -15, 7, 32, 1, 38, 0, 32, 1, -14, 7, 12, 0, -13, 7, 9, + 0, -12, 7, 9, 0, -11, 7, 9, 0, -10, 7, 7, 0, 7, 1, 7, 0, -81, 0, 7, 0, -57, 1, 7, 0, -9, 7, 7, 0, -8, 7, 7, + 0, 2, 3, 7, 0, -7, 7, 7, 0, -6, 7, 7, 0, -5, 7, 7, 0, -4, 7, 7, 0, -3, 7, 7, 0, -2, 7, 7, 0, -10, 1, 32, + 0, -1, 7, -110, 0, 9, 0, 12, 0, 0, 8, 2, 0, 20, 0, 2, 0, 1, 8, 7, 0, 20, 3, 7, 0, 2, 8, 7, 0, 3, 8, 12, + 0, 4, 8, 4, 0, 5, 8, 4, 0, 37, 0, 33, 1, 7, 0, 33, 1, 0, 0, 33, 1, 1, 0, 12, 0, -58, 7, 4, 0, 20, 0, 4, + 0, 6, 8, 0, 0, 17, 0, -47, 0, 7, 8, 34, 1, 8, 0, 34, 1, 0, 0, 34, 1, 1, 0, 33, 1, 8, 8, 36, 0, 79, 0, 12, + 0, -6, 2, 4, 0, 20, 0, 0, 0, 17, 0, 4, 0, 9, 8, -111, 0, 6, 0, 27, 0, 31, 0, 12, 0, 0, 8, 12, 0, 10, 8, 12, + 0, 103, 0, 4, 0, 11, 8, 4, 0, 37, 0, 35, 1, 16, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, + 0, 77, 5, 2, 0, 78, 5, -69, 0, -108, 5, -111, 0, -9, 2, 0, 0, 13, 1, 0, 0, -37, 5, 2, 0, 20, 0, 2, 0, 12, 8, 2, + 0, -101, 5, 2, 0, -98, 5, 2, 0, 13, 8, 7, 0, 14, 8, 36, 1, 5, 0, 36, 1, 0, 0, 36, 1, 1, 0, 36, 0, 79, 0, 2, + 0, 20, 0, 0, 0, 15, 8, 37, 1, 12, 0, 37, 1, 0, 0, 37, 1, 1, 0, 9, 0, 2, 0, 2, 0, 18, 0, 2, 0, 20, 0, 0, + 0, 16, 8, 0, 0, 17, 8, 0, 0, 15, 8, 7, 0, 18, 8, 7, 0, 19, 8, 4, 0, 37, 0, 36, 0, 79, 0, 38, 1, 9, 0, 38, + 1, 0, 0, 38, 1, 1, 0, 32, 0, 20, 8, 0, 0, 21, 8, 7, 0, 22, 8, 2, 0, 23, 8, 2, 0, 20, 0, 2, 0, 18, 0, 2, + 0, 37, 0, 39, 1, 7, 0, 42, 0, -36, 5, 26, 0, 24, 8, 4, 0, 20, 0, 4, 0, 25, 8, 12, 0, 26, 8, 32, 0, 20, 8, 0, + 0, 21, 8, 40, 1, 12, 0, 32, 0, 20, 8, 2, 0, 27, 8, 2, 0, 20, 0, 2, 0, 28, 8, 2, 0, 29, 8, 0, 0, 21, 8, 32, + 0, 30, 8, 0, 0, 31, 8, 7, 0, 32, 8, 7, 0, -39, 1, 7, 0, 33, 8, 7, 0, 34, 8, 41, 1, 6, 0, 32, 0, 20, 8, 4, + 0, 9, 8, 4, 0, 35, 8, 4, 0, 93, 0, 4, 0, 37, 0, 0, 0, 21, 8, 42, 1, 4, 0, 32, 0, 20, 8, 4, 0, 20, 0, 4, + 0, 9, 8, 0, 0, 21, 8, 43, 1, 4, 0, 32, 0, 20, 8, 4, 0, 20, 0, 4, 0, 9, 8, 0, 0, 21, 8, 44, 1, 10, 0, 32, + 0, 20, 8, 4, 0, 36, 8, 7, 0, -127, 0, 4, 0, 20, 0, 2, 0, -42, 5, 2, 0, 37, 8, 2, 0, 43, 0, 2, 0, 70, 0, 7, + 0, 38, 8, 0, 0, 21, 8, 45, 1, 4, 0, 32, 0, 20, 8, 4, 0, 20, 0, 4, 0, 9, 8, 0, 0, 21, 8, 46, 1, 10, 0, 32, + 0, 20, 8, 2, 0, 18, 0, 2, 0, -95, 3, 4, 0, 91, 0, 4, 0, 92, 0, 7, 0, -97, 7, 7, 0, -96, 7, 4, 0, 37, 0, -111, + 0, -122, 7, 0, 0, 21, 8, 47, 1, 4, 0, 32, 0, 20, 8, 4, 0, 7, 3, 4, 0, 39, 8, 0, 0, 21, 8, 48, 1, 5, 0, 32, + 0, 20, 8, 7, 0, -127, 0, 4, 0, 40, 8, 4, 0, 7, 3, 4, 0, 8, 3, 49, 1, 6, 0, 32, 0, 20, 8, 4, 0, 41, 8, 4, + 0, 42, 8, 7, 0, 43, 8, 7, 0, 44, 8, 0, 0, 21, 8, 50, 1, 16, 0, 32, 0, 20, 8, 32, 0, -14, 7, 4, 0, 18, 0, 7, + 0, 45, 8, 7, 0, 46, 8, 7, 0, 47, 8, 7, 0, 48, 8, 7, 0, 49, 8, 7, 0, 50, 8, 7, 0, 51, 8, 7, 0, 52, 8, 7, + 0, 53, 8, 2, 0, 20, 0, 2, 0, 37, 0, 2, 0, 43, 0, 2, 0, 70, 0, 51, 1, 3, 0, 32, 0, 20, 8, 4, 0, 20, 0, 4, + 0, 123, 5, 52, 1, 5, 0, 32, 0, 20, 8, 4, 0, 20, 0, 4, 0, 37, 0, 7, 0, 54, 8, 0, 0, 21, 8, 53, 1, 10, 0, 32, + 0, 20, 8, 0, 0, 21, 8, 2, 0, 55, 8, 2, 0, 56, 8, 0, 0, 57, 8, 0, 0, 58, 8, 7, 0, 59, 8, 7, 0, 60, 8, 7, + 0, 61, 8, 7, 0, 62, 8, 54, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0, 7, 0, 63, 8, 7, + 0, 64, 8, 2, 0, 20, 0, 2, 0, 123, 5, 55, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0, 7, + 0, 63, 8, 7, 0, 64, 8, 2, 0, 20, 0, 2, 0, 123, 5, 56, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, + 0, 12, 0, 7, 0, 63, 8, 7, 0, 64, 8, 2, 0, 20, 0, 2, 0, 123, 5, 57, 1, 7, 0, 32, 0, 20, 8, 0, 0, 21, 8, 7, + 0, 20, 1, 7, 0, 30, 1, 2, 0, 20, 0, 2, 0, 13, 1, 4, 0, 37, 0, 58, 1, 5, 0, 32, 0, -45, 2, 7, 0, 20, 1, 2, + 0, -41, 2, 0, 0, -39, 2, 0, 0, 65, 8, 59, 1, 10, 0, 59, 1, 0, 0, 59, 1, 1, 0, 2, 0, 18, 0, 2, 0, 20, 0, 0, + 0, 66, 8, 7, 0, -36, 0, 7, 0, -35, 0, 2, 0, -58, 7, 2, 0, 67, 8, 32, 0, 45, 0, 60, 1, 22, 0, 60, 1, 0, 0, 60, + 1, 1, 0, 2, 0, 20, 0, 2, 0, 13, 1, 2, 0, 68, 8, 2, 0, 69, 8, 36, 0, 79, 0, -111, 0, -122, 7, 32, 0, -89, 0, 7, + 0, 91, 0, 7, 0, 92, 0, 7, 0, 70, 8, 7, 0, 71, 8, 7, 0, 72, 8, 7, 0, 73, 8, 7, 0, -107, 2, 7, 0, -67, 1, 7, + 0, -120, 7, 7, 0, 74, 8, 0, 0, 75, 8, 0, 0, 76, 8, 12, 0, -4, 2, 61, 1, 8, 0, 7, 0, -31, 1, 7, 0, -97, 7, 7, + 0, -96, 7, 9, 0, 2, 0, 2, 0, 77, 8, 2, 0, 78, 8, 2, 0, 79, 8, 2, 0, 80, 8, 62, 1, 18, 0, 62, 1, 0, 0, 62, + 1, 1, 0, 62, 1, 81, 8, 0, 0, 17, 0, 61, 1, 82, 8, 2, 0, 18, 0, 2, 0, 20, 0, 2, 0, 83, 8, 2, 0, 84, 8, 2, + 0, 85, 8, 2, 0, 86, 8, 4, 0, 43, 0, 7, 0, 87, 8, 7, 0, 88, 8, 4, 0, 89, 8, 4, 0, 90, 8, 62, 1, 91, 8, 63, + 1, 92, 8, 64, 1, 32, 0, 64, 1, 0, 0, 64, 1, 1, 0, 64, 1, 93, 8, 0, 0, 17, 0, 0, 0, 94, 8, 2, 0, 18, 0, 2, + 0, 20, 0, 2, 0, -14, 6, 2, 0, 20, 7, 2, 0, 95, 8, 2, 0, -119, 0, 2, 0, 84, 8, 2, 0, -25, 6, 12, 0, -127, 7, 12, + 0, 96, 8, 27, 0, -9, 5, 9, 0, 97, 8, 7, 0, 87, 8, 7, 0, 88, 8, 7, 0, -5, 1, 7, 0, 98, 8, 2, 0, 99, 8, 2, + 0, 100, 8, 7, 0, 101, 8, 7, 0, 102, 8, 2, 0, 103, 8, 2, 0, 104, 8, 24, 0, 105, 8, 24, 0, 106, 8, 24, 0, 107, 8, 65, + 1, -103, 0, 66, 1, 108, 8, 63, 1, 6, 0, 63, 1, 0, 0, 63, 1, 1, 0, 64, 1, 109, 8, 64, 1, 110, 8, 62, 1, 111, 8, 62, + 1, 91, 8, 57, 0, 16, 0, 27, 0, 31, 0, 12, 0, 112, 8, 12, 0, 113, 8, 61, 1, 114, 8, 12, 0, 115, 8, 4, 0, 18, 0, 4, + 0, 116, 8, 4, 0, 117, 8, 4, 0, 118, 8, 12, 0, 119, 8, 66, 1, 120, 8, 62, 1, 121, 8, 62, 1, 122, 8, 9, 0, 123, 8, 9, + 0, 124, 8, 4, 0, 125, 8, 67, 1, 6, 0, 4, 0, -128, 0, 4, 0, -126, 0, 4, 0, -25, 6, 0, 0, 126, 8, 0, 0, 127, 8, 2, + 0, 37, 0, 68, 1, 16, 0, 2, 0, -86, 6, 2, 0, -85, 6, 2, 0, -128, 8, 2, 0, -74, 7, 2, 0, -127, 8, 2, 0, 68, 0, 7, + 0, -108, 2, 7, 0, -126, 8, 7, 0, -125, 8, 2, 0, 34, 1, 0, 0, -124, 8, 0, 0, 42, 4, 2, 0, -123, 8, 2, 0, 37, 0, 4, + 0, -122, 8, 4, 0, -121, 8, 69, 1, 9, 0, 7, 0, -120, 8, 7, 0, -119, 8, 7, 0, -60, 7, 7, 0, 112, 0, 7, 0, -118, 8, 7, + 0, 71, 5, 2, 0, -117, 8, 0, 0, -116, 8, 0, 0, 37, 0, 70, 1, 4, 0, 7, 0, -115, 8, 7, 0, -114, 8, 2, 0, -117, 8, 2, + 0, 37, 0, 71, 1, 3, 0, 7, 0, -113, 8, 7, 0, -112, 8, 7, 0, 15, 0, 72, 1, 7, 0, 0, 0, -68, 1, 2, 0, 109, 4, 2, + 0, 110, 4, 2, 0, 111, 4, 2, 0, 62, 4, 4, 0, -126, 0, 4, 0, -97, 3, 73, 1, 7, 0, 7, 0, -111, 8, 7, 0, -110, 8, 7, + 0, -109, 8, 7, 0, 4, 2, 7, 0, -108, 8, 7, 0, -107, 8, 7, 0, -106, 8, 74, 1, 4, 0, 2, 0, -105, 8, 2, 0, -104, 8, 2, + 0, -103, 8, 2, 0, -102, 8, 75, 1, 2, 0, 7, 0, 5, 0, 7, 0, 6, 0, 76, 1, 2, 0, 0, 0, -87, 0, 0, 0, -101, 8, 77, + 1, 1, 0, 0, 0, 17, 0, 78, 1, 10, 0, 0, 0, -100, 8, 0, 0, -99, 8, 0, 0, -98, 8, 0, 0, -97, 8, 2, 0, -128, 8, 2, + 0, -96, 8, 7, 0, -95, 8, 7, 0, -94, 8, 7, 0, -93, 8, 7, 0, -67, 1, 79, 1, 2, 0, 9, 0, -92, 8, 9, 0, -91, 8, 80, + 1, 11, 0, 0, 0, 111, 4, 0, 0, 18, 0, 0, 0, -117, 8, 0, 0, 112, 0, 0, 0, -90, 8, 0, 0, 109, 0, 0, 0, -74, 0, 7, + 0, -89, 8, 7, 0, -88, 8, 7, 0, -87, 8, 7, 0, -86, 8, 81, 1, 8, 0, 7, 0, 97, 7, 7, 0, -127, 0, 7, 0, 42, 4, 7, + 0, 72, 2, 7, 0, -85, 8, 7, 0, -49, 0, 7, 0, -84, 8, 4, 0, 18, 0, 82, 1, 4, 0, 2, 0, -83, 8, 2, 0, -82, 8, 2, + 0, -81, 8, 2, 0, 37, 0, 83, 1, 1, 0, 0, 0, 17, 0, 84, 1, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 2, 0, 20, 0, 2, + 0, -80, 8, 85, 1, 10, 0, 2, 0, -120, 3, 2, 0, 20, 0, 7, 0, -17, 3, 7, 0, -79, 8, 7, 0, -78, 8, 7, 0, -77, 8, 7, + 0, -76, 8, 84, 1, -75, 8, 84, 1, -74, 8, 84, 1, -73, 8, 60, 0, 9, 0, 4, 0, 20, 0, 4, 0, 64, 0, 24, 0, -72, 8, 24, + 0, -71, 8, 85, 1, -70, 8, 7, 0, -69, 8, 7, 0, -68, 8, 7, 0, -67, 8, 7, 0, -66, 8, 86, 1, 4, 0, 46, 0, -114, 2, 7, + 0, -65, 8, 7, 0, 92, 1, 7, 0, 37, 0, -87, 0, 13, 0, 27, 0, 31, 0, 2, 0, 20, 0, 2, 0, 72, 5, 4, 0, 109, 0, 7, + 0, -64, 8, 7, 0, 1, 2, 7, 0, -63, 8, 7, 0, -62, 8, 7, 0, 92, 1, 2, 0, 47, 1, 2, 0, 37, 0, 50, 0, 77, 1, 86, + 1, -61, 8, 87, 1, 10, 0, 4, 0, 18, 0, 4, 0, -127, 0, 4, 0, 20, 0, 4, 0, 70, 3, 4, 0, -60, 8, 4, 0, -59, 8, 4, + 0, -58, 8, 0, 0, 95, 0, 0, 0, 17, 0, 9, 0, 2, 0, 84, 0, 6, 0, 87, 1, -57, 8, 4, 0, -56, 8, 4, 0, -55, 8, 4, + 0, -54, 8, 4, 0, 37, 0, 9, 0, -53, 8, 88, 1, 5, 0, 7, 0, 66, 2, 7, 0, -74, 2, 7, 0, -39, 1, 2, 0, -52, 8, 2, + 0, 37, 0, 89, 1, 5, 0, 7, 0, 66, 2, 7, 0, -51, 8, 7, 0, -50, 8, 7, 0, -49, 8, 7, 0, -74, 2, 90, 1, 7, 0, 4, + 0, -48, 8, 4, 0, -47, 8, 4, 0, -46, 8, 7, 0, -45, 8, 7, 0, -44, 8, 7, 0, -43, 8, 7, 0, -42, 8, 91, 1, 26, 0, 32, + 0, -41, 8, 89, 1, 66, 3, 89, 1, -40, 8, 88, 1, -39, 8, 89, 1, 83, 7, 7, 0, -38, 8, 7, 0, -37, 8, 7, 0, -36, 8, 7, + 0, -35, 8, 7, 0, -44, 8, 7, 0, -43, 8, 7, 0, -74, 2, 7, 0, -97, 2, 7, 0, -34, 8, 7, 0, -33, 8, 7, 0, 109, 0, 7, + 0, -32, 8, 4, 0, -48, 8, 4, 0, -31, 8, 4, 0, 37, 0, 4, 0, 81, 0, 4, 0, -30, 8, 2, 0, 20, 0, 2, 0, -29, 8, 2, + 0, -28, 8, 2, 0, 100, 3, 92, 1, 112, 0, 27, 0, 31, 0, 4, 0, 20, 0, 2, 0, 18, 0, 2, 0, 55, 8, 2, 0, -27, 8, 2, + 0, -26, 8, 2, 0, -25, 8, 2, 0, -24, 8, 2, 0, -23, 8, 2, 0, -22, 8, 2, 0, -21, 8, 2, 0, -20, 8, 2, 0, -19, 8, 2, + 0, -18, 8, 2, 0, -17, 8, 2, 0, -16, 8, 2, 0, -15, 8, 2, 0, -14, 8, 2, 0, -13, 8, 2, 0, -47, 1, 2, 0, 76, 7, 2, + 0, 51, 7, 2, 0, -12, 8, 2, 0, -11, 8, 2, 0, 98, 3, 2, 0, 99, 3, 2, 0, -10, 8, 2, 0, -9, 8, 2, 0, -8, 8, 2, + 0, -7, 8, 2, 0, -6, 8, 2, 0, -5, 8, 7, 0, -4, 8, 7, 0, -3, 8, 7, 0, -2, 8, 2, 0, -1, 8, 2, 0, 0, 9, 7, + 0, 1, 9, 7, 0, 2, 9, 7, 0, 3, 9, 7, 0, 58, 7, 7, 0, 92, 0, 7, 0, -97, 2, 7, 0, 64, 7, 7, 0, 4, 9, 7, + 0, 5, 9, 7, 0, 6, 9, 7, 0, 7, 9, 7, 0, 57, 0, 4, 0, 59, 7, 4, 0, 57, 7, 4, 0, 8, 9, 7, 0, 60, 7, 7, + 0, 61, 7, 7, 0, 62, 7, 7, 0, 9, 9, 7, 0, 10, 9, 7, 0, 11, 9, 7, 0, 12, 9, 7, 0, 13, 9, 7, 0, 14, 9, 7, + 0, 15, 9, 7, 0, 16, 9, 7, 0, 21, 3, 7, 0, 109, 0, 7, 0, 17, 9, 7, 0, 18, 9, 7, 0, 19, 9, 7, 0, 20, 9, 7, + 0, 21, 9, 7, 0, 22, 9, 7, 0, 108, 2, 7, 0, 23, 9, 7, 0, 24, 9, 4, 0, 25, 9, 4, 0, 26, 9, 7, 0, 27, 9, 7, + 0, 28, 9, 7, 0, 29, 9, 7, 0, 30, 9, 7, 0, 31, 9, 7, 0, 32, 9, 7, 0, 33, 9, 7, 0, 34, 9, 7, 0, 94, 3, 7, + 0, 92, 3, 7, 0, 93, 3, 7, 0, 35, 9, 7, 0, 36, 9, 7, 0, 37, 9, 7, 0, 38, 9, 7, 0, 39, 9, 7, 0, 40, 9, 7, + 0, 41, 9, 7, 0, 42, 9, 7, 0, 43, 9, 7, 0, 28, 3, 7, 0, 44, 9, 7, 0, 45, 9, 7, 0, 46, 9, 7, 0, 47, 9, 7, + 0, 48, 9, 7, 0, 49, 9, 7, 0, 50, 9, 0, 0, 51, 9, 63, 0, 55, 3, 63, 0, 52, 9, 32, 0, 53, 9, 32, 0, 54, 9, 36, + 0, 79, 0, -108, 0, 53, 3, -108, 0, 55, 9, -120, 0, 37, 0, -120, 0, 0, 0, -120, 0, 1, 0, 92, 1, 56, 9, 91, 1, -121, 3, 90, + 1, -14, 7, 93, 1, 57, 9, 94, 1, 58, 9, 94, 1, 59, 9, 12, 0, 60, 9, 12, 0, 61, 9, -107, 0, 54, 3, 32, 0, 62, 9, 32, + 0, 63, 9, 32, 0, 64, 9, 12, 0, 65, 9, 12, 0, 66, 9, 7, 0, -45, 0, 7, 0, 83, 4, 4, 0, 110, 2, 4, 0, 20, 0, 4, + 0, 59, 7, 4, 0, 67, 9, 4, 0, 68, 9, 4, 0, 69, 9, 4, 0, 57, 0, 2, 0, -38, 0, 2, 0, 70, 9, 2, 0, 71, 9, 2, + 0, 72, 9, 2, 0, 47, 3, 2, 0, 73, 9, 0, 0, 74, 9, 2, 0, 75, 9, 2, 0, 76, 9, 2, 0, 77, 9, 9, 0, 78, 9, 125, + 0, -76, 3, 123, 0, 34, 0, 95, 1, 79, 9, 7, 0, -106, 3, 7, 0, 80, 9, 7, 0, 81, 9, 7, 0, -14, 3, 7, 0, 82, 9, 7, + 0, 31, 3, 7, 0, 21, 3, 7, 0, 83, 9, 7, 0, 3, 2, 7, 0, 84, 9, 7, 0, 85, 9, 7, 0, 86, 9, 7, 0, 87, 9, 7, + 0, 88, 9, 7, 0, 89, 9, 7, 0, -105, 3, 7, 0, 90, 9, 7, 0, 91, 9, 7, 0, 92, 9, 7, 0, -104, 3, 7, 0, -108, 3, 7, + 0, -107, 3, 4, 0, 93, 9, 4, 0, 93, 0, 4, 0, 94, 9, 4, 0, 95, 9, 2, 0, 96, 9, 2, 0, 97, 9, 2, 0, 98, 9, 2, + 0, 99, 9, 2, 0, 100, 9, 2, 0, 37, 0, 4, 0, 70, 0, 124, 0, 8, 0, 95, 1, 101, 9, 7, 0, 102, 9, 7, 0, 103, 9, 7, + 0, -94, 1, 7, 0, 104, 9, 4, 0, 93, 0, 2, 0, 105, 9, 2, 0, 106, 9, 96, 1, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, + 0, 7, 0, 7, 0, 107, 9, 97, 1, 6, 0, 97, 1, 0, 0, 97, 1, 1, 0, 96, 1, 108, 9, 4, 0, 109, 9, 2, 0, 110, 9, 2, + 0, 20, 0, 98, 1, 5, 0, 98, 1, 0, 0, 98, 1, 1, 0, 12, 0, 111, 9, 4, 0, 112, 9, 4, 0, 20, 0, 99, 1, 9, 0, 99, + 1, 0, 0, 99, 1, 1, 0, 12, 0, -128, 0, 98, 1, 113, 9, 4, 0, 20, 0, 2, 0, 110, 9, 2, 0, 114, 9, 7, 0, 94, 0, 0, + 0, 115, 9, -70, 0, 5, 0, 12, 0, 125, 4, 4, 0, 20, 0, 2, 0, 116, 9, 2, 0, 117, 9, 9, 0, 118, 9, 69, 78, 68, 66, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +int DNAlen64 = sizeof(DNAstr64); diff --git a/Extras/Serialize/BlenderSerialize/dna249.cpp b/Extras/Serialize/BlenderSerialize/dna249.cpp index 97881b4f7..5584d643a 100644 --- a/Extras/Serialize/BlenderSerialize/dna249.cpp +++ b/Extras/Serialize/BlenderSerialize/dna249.cpp @@ -12,1400 +12,1399 @@ subject to the following restrictions: 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ -unsigned char DNAstr[]= { -83,68,78,65,78,65,77,69,119,9,0,0,42,110,101,120,116,0,42,112,114,101,118,0,42,100,97,116,97,0,42,102,105, -114,115,116,0,42,108,97,115,116,0,120,0,121,0,122,0,119,0,120,109,105,110,0,120,109,97,120,0,121,109,105,110, -0,121,109,97,120,0,42,112,111,105,110,116,101,114,0,103,114,111,117,112,0,118,97,108,0,118,97,108,50,0,110,97, -109,101,91,51,50,93,0,116,121,112,101,0,115,117,98,116,121,112,101,0,102,108,97,103,0,115,97,118,101,100,0,100, -97,116,97,0,108,101,110,0,116,111,116,97,108,108,101,110,0,42,110,101,119,105,100,0,42,108,105,98,0,110,97,109, -101,91,50,52,93,0,117,115,0,105,99,111,110,95,105,100,0,42,112,114,111,112,101,114,116,105,101,115,0,105,100,0, -42,105,100,98,108,111,99,107,0,42,102,105,108,101,100,97,116,97,0,110,97,109,101,91,50,52,48,93,0,102,105,108, -101,110,97,109,101,91,50,52,48,93,0,116,111,116,0,112,97,100,0,42,112,97,114,101,110,116,0,119,91,50,93,0, -104,91,50,93,0,99,104,97,110,103,101,100,91,50,93,0,112,97,100,48,0,112,97,100,49,0,42,114,101,99,116,91, -50,93,0,42,111,98,0,98,108,111,99,107,116,121,112,101,0,97,100,114,99,111,100,101,0,110,97,109,101,91,49,50, -56,93,0,42,98,112,0,42,98,101,122,116,0,109,97,120,114,99,116,0,116,111,116,114,99,116,0,118,97,114,116,121, -112,101,0,116,111,116,118,101,114,116,0,105,112,111,0,101,120,116,114,97,112,0,114,116,0,98,105,116,109,97,115,107, -0,115,108,105,100,101,95,109,105,110,0,115,108,105,100,101,95,109,97,120,0,99,117,114,118,97,108,0,42,100,114,105, -118,101,114,0,99,117,114,118,101,0,99,117,114,0,115,104,111,119,107,101,121,0,109,117,116,101,105,112,111,0,112,111, -115,0,114,101,108,97,116,105,118,101,0,116,111,116,101,108,101,109,0,112,97,100,50,0,42,119,101,105,103,104,116,115, -0,118,103,114,111,117,112,91,51,50,93,0,115,108,105,100,101,114,109,105,110,0,115,108,105,100,101,114,109,97,120,0, -42,114,101,102,107,101,121,0,101,108,101,109,115,116,114,91,51,50,93,0,101,108,101,109,115,105,122,101,0,98,108,111, -99,107,0,42,105,112,111,0,42,102,114,111,109,0,116,111,116,107,101,121,0,115,108,117,114,112,104,0,42,42,115,99, -114,105,112,116,115,0,42,102,108,97,103,0,97,99,116,115,99,114,105,112,116,0,116,111,116,115,99,114,105,112,116,0, -42,108,105,110,101,0,42,102,111,114,109,97,116,0,98,108,101,110,0,108,105,110,101,110,111,0,115,116,97,114,116,0, -101,110,100,0,102,108,97,103,115,0,99,111,108,111,114,91,52,93,0,112,97,100,91,52,93,0,42,110,97,109,101,0, -110,108,105,110,101,115,0,108,105,110,101,115,0,42,99,117,114,108,0,42,115,101,108,108,0,99,117,114,99,0,115,101, -108,99,0,109,97,114,107,101,114,115,0,42,117,110,100,111,95,98,117,102,0,117,110,100,111,95,112,111,115,0,117,110, -100,111,95,108,101,110,0,42,99,111,109,112,105,108,101,100,0,109,116,105,109,101,0,115,105,122,101,0,115,101,101,107, -0,112,97,115,115,101,112,97,114,116,97,108,112,104,97,0,97,110,103,108,101,0,99,108,105,112,115,116,97,0,99,108, -105,112,101,110,100,0,108,101,110,115,0,111,114,116,104,111,95,115,99,97,108,101,0,100,114,97,119,115,105,122,101,0, -115,104,105,102,116,120,0,115,104,105,102,116,121,0,89,70,95,100,111,102,100,105,115,116,0,89,70,95,97,112,101,114, -116,117,114,101,0,89,70,95,98,107,104,116,121,112,101,0,89,70,95,98,107,104,98,105,97,115,0,89,70,95,98,107, -104,114,111,116,0,115,99,114,105,112,116,108,105,110,107,0,42,100,111,102,95,111,98,0,102,114,97,109,101,110,114,0, -102,114,97,109,101,115,0,111,102,102,115,101,116,0,115,102,114,97,0,102,105,101,95,105,109,97,0,99,121,99,108,0, -111,107,0,109,117,108,116,105,95,105,110,100,101,120,0,108,97,121,101,114,0,112,97,115,115,0,109,101,110,117,110,114, -0,105,98,117,102,115,0,42,103,112,117,116,101,120,116,117,114,101,0,42,97,110,105,109,0,42,114,114,0,115,111,117, -114,99,101,0,108,97,115,116,102,114,97,109,101,0,116,112,97,103,101,102,108,97,103,0,116,111,116,98,105,110,100,0, -120,114,101,112,0,121,114,101,112,0,116,119,115,116,97,0,116,119,101,110,100,0,98,105,110,100,99,111,100,101,0,42, -114,101,112,98,105,110,100,0,42,112,97,99,107,101,100,102,105,108,101,0,42,112,114,101,118,105,101,119,0,108,97,115, -116,117,112,100,97,116,101,0,108,97,115,116,117,115,101,100,0,97,110,105,109,115,112,101,101,100,0,103,101,110,95,120, -0,103,101,110,95,121,0,103,101,110,95,116,121,112,101,0,97,115,112,120,0,97,115,112,121,0,42,118,110,111,100,101, -0,116,101,120,99,111,0,109,97,112,116,111,0,109,97,112,116,111,110,101,103,0,98,108,101,110,100,116,121,112,101,0, -42,111,98,106,101,99,116,0,42,116,101,120,0,117,118,110,97,109,101,91,51,50,93,0,112,114,111,106,120,0,112,114, -111,106,121,0,112,114,111,106,122,0,109,97,112,112,105,110,103,0,111,102,115,91,51,93,0,115,105,122,101,91,51,93, -0,116,101,120,102,108,97,103,0,99,111,108,111,114,109,111,100,101,108,0,112,109,97,112,116,111,0,112,109,97,112,116, -111,110,101,103,0,110,111,114,109,97,112,115,112,97,99,101,0,119,104,105,99,104,95,111,117,116,112,117,116,0,112,97, -100,91,50,93,0,114,0,103,0,98,0,107,0,100,101,102,95,118,97,114,0,99,111,108,102,97,99,0,110,111,114,102, -97,99,0,118,97,114,102,97,99,0,100,105,115,112,102,97,99,0,119,97,114,112,102,97,99,0,110,97,109,101,91,49, -54,48,93,0,42,104,97,110,100,108,101,0,42,112,110,97,109,101,0,42,115,116,110,97,109,101,115,0,115,116,121,112, -101,115,0,118,97,114,115,0,42,118,97,114,115,116,114,0,42,114,101,115,117,108,116,0,42,99,102,114,97,0,100,97, -116,97,91,51,50,93,0,40,42,100,111,105,116,41,40,41,0,40,42,105,110,115,116,97,110,99,101,95,105,110,105,116, -41,40,41,0,40,42,99,97,108,108,98,97,99,107,41,40,41,0,118,101,114,115,105,111,110,0,97,0,105,112,111,116, -121,112,101,0,42,105,109,97,0,42,99,117,98,101,91,54,93,0,105,109,97,116,91,52,93,91,52,93,0,111,98,105, -109,97,116,91,51,93,91,51,93,0,115,116,121,112,101,0,118,105,101,119,115,99,97,108,101,0,110,111,116,108,97,121, -0,99,117,98,101,114,101,115,0,100,101,112,116,104,0,114,101,99,97,108,99,0,108,97,115,116,115,105,122,101,0,110, -111,105,115,101,115,105,122,101,0,116,117,114,98,117,108,0,98,114,105,103,104,116,0,99,111,110,116,114,97,115,116,0, -114,102,97,99,0,103,102,97,99,0,98,102,97,99,0,102,105,108,116,101,114,115,105,122,101,0,109,103,95,72,0,109, -103,95,108,97,99,117,110,97,114,105,116,121,0,109,103,95,111,99,116,97,118,101,115,0,109,103,95,111,102,102,115,101, -116,0,109,103,95,103,97,105,110,0,100,105,115,116,95,97,109,111,117,110,116,0,110,115,95,111,117,116,115,99,97,108, -101,0,118,110,95,119,49,0,118,110,95,119,50,0,118,110,95,119,51,0,118,110,95,119,52,0,118,110,95,109,101,120, -112,0,118,110,95,100,105,115,116,109,0,118,110,95,99,111,108,116,121,112,101,0,110,111,105,115,101,100,101,112,116,104, -0,110,111,105,115,101,116,121,112,101,0,110,111,105,115,101,98,97,115,105,115,0,110,111,105,115,101,98,97,115,105,115, -50,0,105,109,97,102,108,97,103,0,99,114,111,112,120,109,105,110,0,99,114,111,112,121,109,105,110,0,99,114,111,112, -120,109,97,120,0,99,114,111,112,121,109,97,120,0,120,114,101,112,101,97,116,0,121,114,101,112,101,97,116,0,101,120, -116,101,110,100,0,99,104,101,99,107,101,114,100,105,115,116,0,110,97,98,108,97,0,105,117,115,101,114,0,42,110,111, -100,101,116,114,101,101,0,42,112,108,117,103,105,110,0,42,99,111,98,97,0,42,101,110,118,0,117,115,101,95,110,111, -100,101,115,0,112,97,100,91,55,93,0,108,111,99,91,51,93,0,114,111,116,91,51,93,0,109,97,116,91,52,93,91, -52,93,0,109,105,110,91,51,93,0,109,97,120,91,51,93,0,112,97,100,51,0,109,111,100,101,0,116,111,116,101,120, -0,115,104,100,119,114,0,115,104,100,119,103,0,115,104,100,119,98,0,115,104,100,119,112,97,100,0,101,110,101,114,103, -121,0,100,105,115,116,0,115,112,111,116,115,105,122,101,0,115,112,111,116,98,108,101,110,100,0,104,97,105,110,116,0, -97,116,116,49,0,97,116,116,50,0,42,99,117,114,102,97,108,108,111,102,102,0,102,97,108,108,111,102,102,95,116,121, -112,101,0,115,104,97,100,115,112,111,116,115,105,122,101,0,98,105,97,115,0,115,111,102,116,0,98,117,102,115,105,122, -101,0,115,97,109,112,0,98,117,102,102,101,114,115,0,102,105,108,116,101,114,116,121,112,101,0,98,117,102,102,108,97, -103,0,98,117,102,116,121,112,101,0,114,97,121,95,115,97,109,112,0,114,97,121,95,115,97,109,112,121,0,114,97,121, -95,115,97,109,112,122,0,114,97,121,95,115,97,109,112,95,116,121,112,101,0,97,114,101,97,95,115,104,97,112,101,0, -97,114,101,97,95,115,105,122,101,0,97,114,101,97,95,115,105,122,101,121,0,97,114,101,97,95,115,105,122,101,122,0, -97,100,97,112,116,95,116,104,114,101,115,104,0,114,97,121,95,115,97,109,112,95,109,101,116,104,111,100,0,116,101,120, -97,99,116,0,115,104,97,100,104,97,108,111,115,116,101,112,0,115,117,110,95,101,102,102,101,99,116,95,116,121,112,101, -0,115,107,121,98,108,101,110,100,116,121,112,101,0,104,111,114,105,122,111,110,95,98,114,105,103,104,116,110,101,115,115, -0,115,112,114,101,97,100,0,115,117,110,95,98,114,105,103,104,116,110,101,115,115,0,115,117,110,95,115,105,122,101,0, -98,97,99,107,115,99,97,116,116,101,114,101,100,95,108,105,103,104,116,0,115,117,110,95,105,110,116,101,110,115,105,116, -121,0,97,116,109,95,116,117,114,98,105,100,105,116,121,0,97,116,109,95,105,110,115,99,97,116,116,101,114,105,110,103, -95,102,97,99,116,111,114,0,97,116,109,95,101,120,116,105,110,99,116,105,111,110,95,102,97,99,116,111,114,0,97,116, -109,95,100,105,115,116,97,110,99,101,95,102,97,99,116,111,114,0,115,107,121,98,108,101,110,100,102,97,99,0,115,107, -121,95,101,120,112,111,115,117,114,101,0,115,107,121,95,99,111,108,111,114,115,112,97,99,101,0,112,97,100,52,0,89, -70,95,110,117,109,112,104,111,116,111,110,115,0,89,70,95,110,117,109,115,101,97,114,99,104,0,89,70,95,112,104,100, -101,112,116,104,0,89,70,95,117,115,101,113,109,99,0,89,70,95,98,117,102,115,105,122,101,0,89,70,95,112,97,100, -0,89,70,95,99,97,117,115,116,105,99,98,108,117,114,0,89,70,95,108,116,114,97,100,105,117,115,0,89,70,95,103, -108,111,119,105,110,116,0,89,70,95,103,108,111,119,111,102,115,0,89,70,95,103,108,111,119,116,121,112,101,0,89,70, -95,112,97,100,50,0,42,109,116,101,120,91,49,56,93,0,115,112,101,99,114,0,115,112,101,99,103,0,115,112,101,99, -98,0,109,105,114,114,0,109,105,114,103,0,109,105,114,98,0,97,109,98,114,0,97,109,98,98,0,97,109,98,103,0, -97,109,98,0,101,109,105,116,0,97,110,103,0,115,112,101,99,116,114,97,0,114,97,121,95,109,105,114,114,111,114,0, -97,108,112,104,97,0,114,101,102,0,115,112,101,99,0,122,111,102,102,115,0,97,100,100,0,116,114,97,110,115,108,117, -99,101,110,99,121,0,102,114,101,115,110,101,108,95,109,105,114,0,102,114,101,115,110,101,108,95,109,105,114,95,105,0, -102,114,101,115,110,101,108,95,116,114,97,0,102,114,101,115,110,101,108,95,116,114,97,95,105,0,102,105,108,116,101,114, -0,116,120,95,108,105,109,105,116,0,116,120,95,102,97,108,108,111,102,102,0,114,97,121,95,100,101,112,116,104,0,114, -97,121,95,100,101,112,116,104,95,116,114,97,0,104,97,114,0,115,101,101,100,49,0,115,101,101,100,50,0,103,108,111, -115,115,95,109,105,114,0,103,108,111,115,115,95,116,114,97,0,115,97,109,112,95,103,108,111,115,115,95,109,105,114,0, -115,97,109,112,95,103,108,111,115,115,95,116,114,97,0,97,100,97,112,116,95,116,104,114,101,115,104,95,109,105,114,0, -97,100,97,112,116,95,116,104,114,101,115,104,95,116,114,97,0,97,110,105,115,111,95,103,108,111,115,115,95,109,105,114, -0,100,105,115,116,95,109,105,114,0,102,97,100,101,116,111,95,109,105,114,0,115,104,97,100,101,95,102,108,97,103,0, -109,111,100,101,95,108,0,102,108,97,114,101,99,0,115,116,97,114,99,0,108,105,110,101,99,0,114,105,110,103,99,0, -104,97,115,105,122,101,0,102,108,97,114,101,115,105,122,101,0,115,117,98,115,105,122,101,0,102,108,97,114,101,98,111, -111,115,116,0,115,116,114,97,110,100,95,115,116,97,0,115,116,114,97,110,100,95,101,110,100,0,115,116,114,97,110,100, -95,101,97,115,101,0,115,116,114,97,110,100,95,115,117,114,102,110,111,114,0,115,116,114,97,110,100,95,109,105,110,0, -115,116,114,97,110,100,95,119,105,100,116,104,102,97,100,101,0,115,116,114,97,110,100,95,117,118,110,97,109,101,91,51, -50,93,0,115,98,105,97,115,0,108,98,105,97,115,0,115,104,97,100,95,97,108,112,104,97,0,115,101,112,116,101,120, -0,114,103,98,115,101,108,0,112,114,95,116,121,112,101,0,112,114,95,98,97,99,107,0,112,114,95,108,97,109,112,0, -109,108,95,102,108,97,103,0,100,105,102,102,95,115,104,97,100,101,114,0,115,112,101,99,95,115,104,97,100,101,114,0, -114,111,117,103,104,110,101,115,115,0,114,101,102,114,97,99,0,112,97,114,97,109,91,52,93,0,114,109,115,0,100,97, -114,107,110,101,115,115,0,42,114,97,109,112,95,99,111,108,0,42,114,97,109,112,95,115,112,101,99,0,114,97,109,112, -105,110,95,99,111,108,0,114,97,109,112,105,110,95,115,112,101,99,0,114,97,109,112,98,108,101,110,100,95,99,111,108, -0,114,97,109,112,98,108,101,110,100,95,115,112,101,99,0,114,97,109,112,95,115,104,111,119,0,114,97,109,112,102,97, -99,95,99,111,108,0,114,97,109,112,102,97,99,95,115,112,101,99,0,42,103,114,111,117,112,0,102,114,105,99,116,105, -111,110,0,102,104,0,114,101,102,108,101,99,116,0,102,104,100,105,115,116,0,120,121,102,114,105,99,116,0,100,121,110, -97,109,111,100,101,0,115,115,115,95,114,97,100,105,117,115,91,51,93,0,115,115,115,95,99,111,108,91,51,93,0,115, -115,115,95,101,114,114,111,114,0,115,115,115,95,115,99,97,108,101,0,115,115,115,95,105,111,114,0,115,115,115,95,99, -111,108,102,97,99,0,115,115,115,95,116,101,120,102,97,99,0,115,115,115,95,102,114,111,110,116,0,115,115,115,95,98, -97,99,107,0,115,115,115,95,102,108,97,103,0,115,115,115,95,112,114,101,115,101,116,0,89,70,95,97,114,0,89,70, -95,97,103,0,89,70,95,97,98,0,89,70,95,100,115,99,97,108,101,0,89,70,95,100,112,119,114,0,89,70,95,100, -115,109,112,0,89,70,95,112,114,101,115,101,116,0,89,70,95,100,106,105,116,0,103,112,117,109,97,116,101,114,105,97, -108,0,110,97,109,101,91,50,53,54,93,0,115,99,97,108,101,0,42,98,98,0,105,49,0,106,49,0,107,49,0,105, -50,0,106,50,0,107,50,0,115,101,108,99,111,108,49,0,115,101,108,99,111,108,50,0,113,117,97,116,91,52,93,0, -101,120,112,120,0,101,120,112,121,0,101,120,112,122,0,114,97,100,0,114,97,100,50,0,115,0,42,109,97,116,0,42, -105,109,97,116,0,101,108,101,109,115,0,100,105,115,112,0,42,42,109,97,116,0,116,111,116,99,111,108,0,119,105,114, -101,115,105,122,101,0,114,101,110,100,101,114,115,105,122,101,0,116,104,114,101,115,104,0,118,101,99,91,51,93,91,51, -93,0,97,108,102,97,0,119,101,105,103,104,116,0,114,97,100,105,117,115,0,104,49,0,104,50,0,102,49,0,102,50, -0,102,51,0,104,105,100,101,0,118,101,99,91,52,93,0,109,97,116,95,110,114,0,112,110,116,115,117,0,112,110,116, -115,118,0,114,101,115,111,108,117,0,114,101,115,111,108,118,0,111,114,100,101,114,117,0,111,114,100,101,114,118,0,102, -108,97,103,117,0,102,108,97,103,118,0,42,107,110,111,116,115,117,0,42,107,110,111,116,115,118,0,116,105,108,116,95, -105,110,116,101,114,112,0,114,97,100,105,117,115,95,105,110,116,101,114,112,0,99,104,97,114,105,100,120,0,107,101,114, -110,0,104,0,110,117,114,98,0,42,98,101,118,111,98,106,0,42,116,97,112,101,114,111,98,106,0,42,116,101,120,116, -111,110,99,117,114,118,101,0,42,112,97,116,104,0,42,107,101,121,0,98,101,118,0,112,97,116,104,108,101,110,0,98, -101,118,114,101,115,111,108,0,119,105,100,116,104,0,101,120,116,49,0,101,120,116,50,0,114,101,115,111,108,117,95,114, -101,110,0,114,101,115,111,108,118,95,114,101,110,0,115,112,97,99,101,109,111,100,101,0,115,112,97,99,105,110,103,0, -108,105,110,101,100,105,115,116,0,115,104,101,97,114,0,102,115,105,122,101,0,119,111,114,100,115,112,97,99,101,0,117, -108,112,111,115,0,117,108,104,101,105,103,104,116,0,120,111,102,0,121,111,102,0,108,105,110,101,119,105,100,116,104,0, -42,115,116,114,0,102,97,109,105,108,121,91,50,52,93,0,42,118,102,111,110,116,0,42,118,102,111,110,116,98,0,42, -118,102,111,110,116,105,0,42,118,102,111,110,116,98,105,0,115,101,112,99,104,97,114,0,116,111,116,98,111,120,0,97, -99,116,98,111,120,0,42,116,98,0,115,101,108,115,116,97,114,116,0,115,101,108,101,110,100,0,42,115,116,114,105,110, -102,111,0,99,117,114,105,110,102,111,0,101,102,102,101,99,116,0,42,109,102,97,99,101,0,42,109,116,102,97,99,101, -0,42,116,102,97,99,101,0,42,109,118,101,114,116,0,42,109,101,100,103,101,0,42,100,118,101,114,116,0,42,109,99, -111,108,0,42,109,115,116,105,99,107,121,0,42,116,101,120,99,111,109,101,115,104,0,42,109,115,101,108,101,99,116,0, -118,100,97,116,97,0,101,100,97,116,97,0,102,100,97,116,97,0,116,111,116,101,100,103,101,0,116,111,116,102,97,99, -101,0,116,111,116,115,101,108,101,99,116,0,97,99,116,95,102,97,99,101,0,99,117,98,101,109,97,112,115,105,122,101, -0,115,109,111,111,116,104,114,101,115,104,0,115,117,98,100,105,118,0,115,117,98,100,105,118,114,0,115,117,98,115,117, -114,102,116,121,112,101,0,42,109,114,0,42,112,118,0,42,116,112,97,103,101,0,117,118,91,52,93,91,50,93,0,99, -111,108,91,52,93,0,116,114,97,110,115,112,0,116,105,108,101,0,117,110,119,114,97,112,0,118,49,0,118,50,0,118, -51,0,118,52,0,101,100,99,111,100,101,0,99,114,101,97,115,101,0,98,119,101,105,103,104,116,0,100,101,102,95,110, -114,0,42,100,119,0,116,111,116,119,101,105,103,104,116,0,99,111,91,51,93,0,110,111,91,51,93,0,112,97,100,91, -51,93,0,117,118,91,50,93,0,99,111,91,50,93,0,105,110,100,101,120,0,102,0,105,0,115,91,50,53,54,93,0, -118,91,52,93,0,109,105,100,0,118,91,50,93,0,42,102,97,99,101,115,0,42,99,111,108,102,97,99,101,115,0,42, -101,100,103,101,115,0,42,101,100,103,101,95,98,111,117,110,100,97,114,121,95,115,116,97,116,101,115,0,42,118,101,114, -116,95,101,100,103,101,95,109,97,112,0,42,118,101,114,116,95,102,97,99,101,95,109,97,112,0,42,109,97,112,95,109, -101,109,0,42,118,101,114,116,115,0,108,101,118,101,108,115,0,108,101,118,101,108,95,99,111,117,110,116,0,99,117,114, -114,101,110,116,0,110,101,119,108,118,108,0,101,100,103,101,108,118,108,0,112,105,110,108,118,108,0,114,101,110,100,101, -114,108,118,108,0,117,115,101,95,99,111,108,0,42,101,100,103,101,95,102,108,97,103,115,0,42,101,100,103,101,95,99, -114,101,97,115,101,115,0,42,118,101,114,116,95,109,97,112,0,42,101,100,103,101,95,109,97,112,0,42,111,108,100,95, -102,97,99,101,115,0,42,111,108,100,95,101,100,103,101,115,0,42,101,114,114,111,114,0,109,111,100,105,102,105,101,114, -0,115,117,98,100,105,118,84,121,112,101,0,114,101,110,100,101,114,76,101,118,101,108,115,0,42,101,109,67,97,99,104, -101,0,42,109,67,97,99,104,101,0,100,101,102,97,120,105,115,0,112,97,100,91,54,93,0,108,101,110,103,116,104,0, -114,97,110,100,111,109,105,122,101,0,115,101,101,100,0,42,111,98,95,97,114,109,0,42,115,116,97,114,116,95,99,97, -112,0,42,101,110,100,95,99,97,112,0,42,99,117,114,118,101,95,111,98,0,42,111,102,102,115,101,116,95,111,98,0, -111,102,102,115,101,116,91,51,93,0,115,99,97,108,101,91,51,93,0,109,101,114,103,101,95,100,105,115,116,0,102,105, -116,95,116,121,112,101,0,111,102,102,115,101,116,95,116,121,112,101,0,99,111,117,110,116,0,97,120,105,115,0,116,111, -108,101,114,97,110,99,101,0,42,109,105,114,114,111,114,95,111,98,0,115,112,108,105,116,95,97,110,103,108,101,0,118, -97,108,117,101,0,114,101,115,0,118,97,108,95,102,108,97,103,115,0,108,105,109,95,102,108,97,103,115,0,101,95,102, -108,97,103,115,0,98,101,118,101,108,95,97,110,103,108,101,0,100,101,102,103,114,112,95,110,97,109,101,91,51,50,93, -0,42,116,101,120,116,117,114,101,0,115,116,114,101,110,103,116,104,0,100,105,114,101,99,116,105,111,110,0,109,105,100, -108,101,118,101,108,0,116,101,120,109,97,112,112,105,110,103,0,42,109,97,112,95,111,98,106,101,99,116,0,117,118,108, -97,121,101,114,95,110,97,109,101,91,51,50,93,0,117,118,108,97,121,101,114,95,116,109,112,0,42,112,114,111,106,101, -99,116,111,114,115,91,49,48,93,0,42,105,109,97,103,101,0,110,117,109,95,112,114,111,106,101,99,116,111,114,115,0, -97,115,112,101,99,116,120,0,97,115,112,101,99,116,121,0,112,101,114,99,101,110,116,0,102,97,99,101,67,111,117,110, -116,0,102,97,99,0,114,101,112,101,97,116,0,42,111,98,106,101,99,116,99,101,110,116,101,114,0,115,116,97,114,116, -120,0,115,116,97,114,116,121,0,104,101,105,103,104,116,0,110,97,114,114,111,119,0,115,112,101,101,100,0,100,97,109, -112,0,102,97,108,108,111,102,102,0,116,105,109,101,111,102,102,115,0,108,105,102,101,116,105,109,101,0,100,101,102,111, -114,109,102,108,97,103,0,109,117,108,116,105,0,42,112,114,101,118,67,111,115,0,112,97,114,101,110,116,105,110,118,91, -52,93,91,52,93,0,99,101,110,116,91,51,93,0,42,105,110,100,101,120,97,114,0,116,111,116,105,110,100,101,120,0, -102,111,114,99,101,0,42,99,108,111,116,104,79,98,106,101,99,116,0,42,115,105,109,95,112,97,114,109,115,0,42,99, -111,108,108,95,112,97,114,109,115,0,42,112,111,105,110,116,95,99,97,99,104,101,0,42,120,0,42,120,110,101,119,0, -42,120,111,108,100,0,42,99,117,114,114,101,110,116,95,120,110,101,119,0,42,99,117,114,114,101,110,116,95,120,0,42, -99,117,114,114,101,110,116,95,118,0,42,109,102,97,99,101,115,0,110,117,109,118,101,114,116,115,0,110,117,109,102,97, -99,101,115,0,97,98,115,111,114,112,116,105,111,110,0,116,105,109,101,0,42,98,118,104,116,114,101,101,0,42,100,109, -0,111,112,101,114,97,116,105,111,110,0,118,101,114,116,101,120,0,116,111,116,105,110,102,108,117,101,110,99,101,0,103, -114,105,100,115,105,122,101,0,110,101,101,100,98,105,110,100,0,42,98,105,110,100,119,101,105,103,104,116,115,0,42,98, -105,110,100,99,111,115,0,116,111,116,99,97,103,101,118,101,114,116,0,42,100,121,110,103,114,105,100,0,42,100,121,110, -105,110,102,108,117,101,110,99,101,115,0,42,100,121,110,118,101,114,116,115,0,42,112,97,100,50,0,100,121,110,103,114, -105,100,115,105,122,101,0,100,121,110,99,101,108,108,109,105,110,91,51,93,0,100,121,110,99,101,108,108,119,105,100,116, -104,0,98,105,110,100,109,97,116,91,52,93,91,52,93,0,42,112,115,121,115,0,116,111,116,100,109,118,101,114,116,0, -116,111,116,100,109,101,100,103,101,0,116,111,116,100,109,102,97,99,101,0,112,115,121,115,0,114,116,91,50,93,0,42, -102,97,99,101,112,97,0,118,103,114,111,117,112,0,112,114,111,116,101,99,116,0,42,102,115,115,0,42,116,97,114,103, -101,116,0,42,97,117,120,84,97,114,103,101,116,0,118,103,114,111,117,112,95,110,97,109,101,91,51,50,93,0,107,101, -101,112,68,105,115,116,0,115,104,114,105,110,107,84,121,112,101,0,115,104,114,105,110,107,79,112,116,115,0,112,114,111, -106,65,120,105,115,0,115,117,98,115,117,114,102,76,101,118,101,108,115,0,42,111,114,105,103,105,110,0,102,97,99,116, -111,114,0,108,105,109,105,116,91,50,93,0,111,114,105,103,105,110,79,112,116,115,0,112,110,116,115,119,0,111,112,110, -116,115,117,0,111,112,110,116,115,118,0,111,112,110,116,115,119,0,116,121,112,101,117,0,116,121,112,101,118,0,116,121, -112,101,119,0,102,117,0,102,118,0,102,119,0,100,117,0,100,118,0,100,119,0,42,100,101,102,0,118,101,99,91,56, -93,91,51,93,0,112,97,114,116,121,112,101,0,112,97,114,49,0,112,97,114,50,0,112,97,114,51,0,112,97,114,115, -117,98,115,116,114,91,51,50,93,0,42,116,114,97,99,107,0,42,112,114,111,120,121,0,42,112,114,111,120,121,95,103, -114,111,117,112,0,42,112,114,111,120,121,95,102,114,111,109,0,42,97,99,116,105,111,110,0,42,112,111,115,101,108,105, -98,0,42,112,111,115,101,0,99,111,110,115,116,114,97,105,110,116,67,104,97,110,110,101,108,115,0,100,101,102,98,97, -115,101,0,109,111,100,105,102,105,101,114,115,0,100,108,111,99,91,51,93,0,111,114,105,103,91,51,93,0,100,115,105, -122,101,91,51,93,0,100,114,111,116,91,51,93,0,111,98,109,97,116,91,52,93,91,52,93,0,99,111,110,115,116,105, -110,118,91,52,93,91,52,93,0,108,97,121,0,99,111,108,98,105,116,115,0,116,114,97,110,115,102,108,97,103,0,105, -112,111,102,108,97,103,0,116,114,97,99,107,102,108,97,103,0,117,112,102,108,97,103,0,110,108,97,102,108,97,103,0, -112,114,111,116,101,99,116,102,108,97,103,0,105,112,111,119,105,110,0,115,99,97,102,108,97,103,0,115,99,97,118,105, -115,102,108,97,103,0,98,111,117,110,100,116,121,112,101,0,100,117,112,111,110,0,100,117,112,111,102,102,0,100,117,112, -115,116,97,0,100,117,112,101,110,100,0,115,102,0,99,116,105,109,101,0,109,97,115,115,0,100,97,109,112,105,110,103, -0,105,110,101,114,116,105,97,0,102,111,114,109,102,97,99,116,111,114,0,114,100,97,109,112,105,110,103,0,115,105,122, -101,102,97,99,0,109,97,114,103,105,110,0,109,97,120,95,118,101,108,0,109,105,110,95,118,101,108,0,109,95,99,111, -110,116,97,99,116,80,114,111,99,101,115,115,105,110,103,84,104,114,101,115,104,111,108,100,0,100,116,0,100,116,120,0, -97,99,116,99,111,108,0,101,109,112,116,121,95,100,114,97,119,116,121,112,101,0,112,97,100,49,91,51,93,0,101,109, -112,116,121,95,100,114,97,119,115,105,122,101,0,100,117,112,102,97,99,101,115,99,97,0,112,114,111,112,0,115,101,110, -115,111,114,115,0,99,111,110,116,114,111,108,108,101,114,115,0,97,99,116,117,97,116,111,114,115,0,98,98,115,105,122, -101,91,51,93,0,97,99,116,100,101,102,0,103,97,109,101,102,108,97,103,0,103,97,109,101,102,108,97,103,50,0,42, -98,115,111,102,116,0,115,111,102,116,102,108,97,103,0,97,110,105,115,111,116,114,111,112,105,99,70,114,105,99,116,105, -111,110,91,51,93,0,99,111,110,115,116,114,97,105,110,116,115,0,110,108,97,115,116,114,105,112,115,0,104,111,111,107, -115,0,112,97,114,116,105,99,108,101,115,121,115,116,101,109,0,42,112,100,0,42,115,111,102,116,0,42,100,117,112,95, -103,114,111,117,112,0,102,108,117,105,100,115,105,109,70,108,97,103,0,114,101,115,116,114,105,99,116,102,108,97,103,0, -115,104,97,112,101,110,114,0,115,104,97,112,101,102,108,97,103,0,114,101,99,97,108,99,111,0,98,111,100,121,95,116, -121,112,101,0,42,102,108,117,105,100,115,105,109,83,101,116,116,105,110,103,115,0,42,100,101,114,105,118,101,100,68,101, -102,111,114,109,0,42,100,101,114,105,118,101,100,70,105,110,97,108,0,108,97,115,116,68,97,116,97,77,97,115,107,0, -115,116,97,116,101,0,105,110,105,116,95,115,116,97,116,101,0,103,112,117,108,97,109,112,0,99,117,114,105,110,100,101, -120,0,97,99,116,105,118,101,0,100,101,102,108,101,99,116,0,102,111,114,99,101,102,105,101,108,100,0,112,100,101,102, -95,100,97,109,112,0,112,100,101,102,95,114,100,97,109,112,0,112,100,101,102,95,112,101,114,109,0,112,100,101,102,95, -102,114,105,99,116,0,112,100,101,102,95,114,102,114,105,99,116,0,102,95,115,116,114,101,110,103,116,104,0,102,95,112, -111,119,101,114,0,102,95,100,105,115,116,0,102,95,100,97,109,112,0,109,97,120,100,105,115,116,0,109,105,110,100,105, -115,116,0,109,97,120,114,97,100,0,109,105,110,114,97,100,0,102,95,112,111,119,101,114,95,114,0,112,100,101,102,95, -115,98,100,97,109,112,0,112,100,101,102,95,115,98,105,102,116,0,112,100,101,102,95,115,98,111,102,116,0,99,108,117, -109,112,95,102,97,99,0,99,108,117,109,112,95,112,111,119,0,107,105,110,107,95,102,114,101,113,0,107,105,110,107,95, -115,104,97,112,101,0,107,105,110,107,95,97,109,112,0,102,114,101,101,95,101,110,100,0,116,101,120,95,110,97,98,108, -97,0,116,101,120,95,109,111,100,101,0,107,105,110,107,0,107,105,110,107,95,97,120,105,115,0,114,116,50,0,42,114, -110,103,0,102,95,110,111,105,115,101,0,115,105,109,102,114,97,109,101,0,115,116,97,114,116,102,114,97,109,101,0,101, -110,100,102,114,97,109,101,0,101,100,105,116,102,114,97,109,101,0,108,105,110,83,116,105,102,102,0,97,110,103,83,116, -105,102,102,0,118,111,108,117,109,101,0,118,105,116,101,114,97,116,105,111,110,115,0,112,105,116,101,114,97,116,105,111, -110,115,0,100,105,116,101,114,97,116,105,111,110,115,0,99,105,116,101,114,97,116,105,111,110,115,0,107,83,82,72,82, -95,67,76,0,107,83,75,72,82,95,67,76,0,107,83,83,72,82,95,67,76,0,107,83,82,95,83,80,76,84,95,67, -76,0,107,83,75,95,83,80,76,84,95,67,76,0,107,83,83,95,83,80,76,84,95,67,76,0,107,86,67,70,0,107, -68,80,0,107,68,71,0,107,76,70,0,107,80,82,0,107,86,67,0,107,68,70,0,107,77,84,0,107,67,72,82,0, -107,75,72,82,0,107,83,72,82,0,107,65,72,82,0,99,111,108,108,105,115,105,111,110,102,108,97,103,115,0,110,117, -109,99,108,117,115,116,101,114,105,116,101,114,97,116,105,111,110,115,0,119,101,108,100,105,110,103,0,42,112,97,114,116, -105,99,108,101,115,0,116,111,116,112,111,105,110,116,0,116,111,116,115,112,114,105,110,103,0,42,98,112,111,105,110,116, -0,42,98,115,112,114,105,110,103,0,109,115,103,95,108,111,99,107,0,109,115,103,95,118,97,108,117,101,0,110,111,100, -101,109,97,115,115,0,110,97,109,101,100,86,71,95,77,97,115,115,91,51,50,93,0,103,114,97,118,0,109,101,100,105, -97,102,114,105,99,116,0,114,107,108,105,109,105,116,0,112,104,121,115,105,99,115,95,115,112,101,101,100,0,103,111,97, -108,115,112,114,105,110,103,0,103,111,97,108,102,114,105,99,116,0,109,105,110,103,111,97,108,0,109,97,120,103,111,97, -108,0,100,101,102,103,111,97,108,0,118,101,114,116,103,114,111,117,112,0,110,97,109,101,100,86,71,95,83,111,102,116, -103,111,97,108,91,51,50,93,0,102,117,122,122,121,110,101,115,115,0,105,110,115,112,114,105,110,103,0,105,110,102,114, -105,99,116,0,110,97,109,101,100,86,71,95,83,112,114,105,110,103,95,75,91,51,50,93,0,101,102,114,97,0,105,110, -116,101,114,118,97,108,0,108,111,99,97,108,0,115,111,108,118,101,114,102,108,97,103,115,0,42,42,107,101,121,115,0, -116,111,116,112,111,105,110,116,107,101,121,0,115,101,99,111,110,100,115,112,114,105,110,103,0,99,111,108,98,97,108,108, -0,98,97,108,108,100,97,109,112,0,98,97,108,108,115,116,105,102,102,0,115,98,99,95,109,111,100,101,0,97,101,114, -111,101,100,103,101,0,109,105,110,108,111,111,112,115,0,109,97,120,108,111,111,112,115,0,99,104,111,107,101,0,115,111, -108,118,101,114,95,73,68,0,112,108,97,115,116,105,99,0,115,112,114,105,110,103,112,114,101,108,111,97,100,0,42,115, -99,114,97,116,99,104,0,115,104,101,97,114,115,116,105,102,102,0,105,110,112,117,115,104,0,42,112,111,105,110,116,99, -97,99,104,101,0,115,104,111,119,95,97,100,118,97,110,99,101,100,111,112,116,105,111,110,115,0,114,101,115,111,108,117, -116,105,111,110,120,121,122,0,112,114,101,118,105,101,119,114,101,115,120,121,122,0,114,101,97,108,115,105,122,101,0,103, -117,105,68,105,115,112,108,97,121,77,111,100,101,0,114,101,110,100,101,114,68,105,115,112,108,97,121,77,111,100,101,0, -118,105,115,99,111,115,105,116,121,86,97,108,117,101,0,118,105,115,99,111,115,105,116,121,77,111,100,101,0,118,105,115, -99,111,115,105,116,121,69,120,112,111,110,101,110,116,0,103,114,97,118,120,0,103,114,97,118,121,0,103,114,97,118,122, -0,97,110,105,109,83,116,97,114,116,0,97,110,105,109,69,110,100,0,103,115,116,97,114,0,109,97,120,82,101,102,105, -110,101,0,105,110,105,86,101,108,120,0,105,110,105,86,101,108,121,0,105,110,105,86,101,108,122,0,42,111,114,103,77, -101,115,104,0,42,109,101,115,104,83,117,114,102,97,99,101,0,42,109,101,115,104,66,66,0,115,117,114,102,100,97,116, -97,80,97,116,104,91,50,52,48,93,0,98,98,83,116,97,114,116,91,51,93,0,98,98,83,105,122,101,91,51,93,0, -116,121,112,101,70,108,97,103,115,0,100,111,109,97,105,110,78,111,118,101,99,103,101,110,0,118,111,108,117,109,101,73, -110,105,116,84,121,112,101,0,112,97,114,116,83,108,105,112,86,97,108,117,101,0,103,101,110,101,114,97,116,101,84,114, -97,99,101,114,115,0,103,101,110,101,114,97,116,101,80,97,114,116,105,99,108,101,115,0,115,117,114,102,97,99,101,83, -109,111,111,116,104,105,110,103,0,115,117,114,102,97,99,101,83,117,98,100,105,118,115,0,112,97,114,116,105,99,108,101, -73,110,102,83,105,122,101,0,112,97,114,116,105,99,108,101,73,110,102,65,108,112,104,97,0,102,97,114,70,105,101,108, -100,83,105,122,101,0,42,109,101,115,104,83,117,114,102,78,111,114,109,97,108,115,0,99,112,115,84,105,109,101,83,116, -97,114,116,0,99,112,115,84,105,109,101,69,110,100,0,99,112,115,81,117,97,108,105,116,121,0,97,116,116,114,97,99, -116,102,111,114,99,101,83,116,114,101,110,103,116,104,0,97,116,116,114,97,99,116,102,111,114,99,101,82,97,100,105,117, -115,0,118,101,108,111,99,105,116,121,102,111,114,99,101,83,116,114,101,110,103,116,104,0,118,101,108,111,99,105,116,121, -102,111,114,99,101,82,97,100,105,117,115,0,108,97,115,116,103,111,111,100,102,114,97,109,101,0,109,105,115,116,121,112, -101,0,104,111,114,114,0,104,111,114,103,0,104,111,114,98,0,104,111,114,107,0,122,101,110,114,0,122,101,110,103,0, -122,101,110,98,0,122,101,110,107,0,97,109,98,107,0,102,97,115,116,99,111,108,0,101,120,112,111,115,117,114,101,0, -101,120,112,0,114,97,110,103,101,0,108,105,110,102,97,99,0,108,111,103,102,97,99,0,103,114,97,118,105,116,121,0, -97,99,116,105,118,105,116,121,66,111,120,82,97,100,105,117,115,0,115,107,121,116,121,112,101,0,111,99,99,108,117,115, -105,111,110,82,101,115,0,112,104,121,115,105,99,115,69,110,103,105,110,101,0,116,105,99,114,97,116,101,0,109,97,120, -108,111,103,105,99,115,116,101,112,0,112,104,121,115,117,98,115,116,101,112,0,109,97,120,112,104,121,115,116,101,112,0, -109,105,115,105,0,109,105,115,116,115,116,97,0,109,105,115,116,100,105,115,116,0,109,105,115,116,104,105,0,115,116,97, -114,114,0,115,116,97,114,103,0,115,116,97,114,98,0,115,116,97,114,107,0,115,116,97,114,115,105,122,101,0,115,116, -97,114,109,105,110,100,105,115,116,0,115,116,97,114,100,105,115,116,0,115,116,97,114,99,111,108,110,111,105,115,101,0, -100,111,102,115,116,97,0,100,111,102,101,110,100,0,100,111,102,109,105,110,0,100,111,102,109,97,120,0,97,111,100,105, -115,116,0,97,111,100,105,115,116,102,97,99,0,97,111,101,110,101,114,103,121,0,97,111,98,105,97,115,0,97,111,109, -111,100,101,0,97,111,115,97,109,112,0,97,111,109,105,120,0,97,111,99,111,108,111,114,0,97,111,95,97,100,97,112, -116,95,116,104,114,101,115,104,0,97,111,95,97,100,97,112,116,95,115,112,101,101,100,95,102,97,99,0,97,111,95,97, -112,112,114,111,120,95,101,114,114,111,114,0,97,111,95,97,112,112,114,111,120,95,99,111,114,114,101,99,116,105,111,110, -0,97,111,95,115,97,109,112,95,109,101,116,104,111,100,0,97,111,95,103,97,116,104,101,114,95,109,101,116,104,111,100, -0,97,111,95,97,112,112,114,111,120,95,112,97,115,115,101,115,0,42,97,111,115,112,104,101,114,101,0,42,97,111,116, -97,98,108,101,115,0,104,101,109,105,114,101,115,0,109,97,120,105,116,101,114,0,100,114,97,119,116,121,112,101,0,115, -117,98,115,104,111,111,116,112,0,115,117,98,115,104,111,111,116,101,0,110,111,100,101,108,105,109,0,109,97,120,115,117, -98,108,97,109,112,0,112,97,109,97,0,112,97,109,105,0,101,108,109,97,0,101,108,109,105,0,109,97,120,110,111,100, -101,0,99,111,110,118,101,114,103,101,110,99,101,0,114,97,100,102,97,99,0,103,97,109,109,97,0,115,101,108,99,111, -108,0,115,120,0,115,121,0,42,108,112,70,111,114,109,97,116,0,42,108,112,80,97,114,109,115,0,99,98,70,111,114, -109,97,116,0,99,98,80,97,114,109,115,0,102,99,99,84,121,112,101,0,102,99,99,72,97,110,100,108,101,114,0,100, -119,75,101,121,70,114,97,109,101,69,118,101,114,121,0,100,119,81,117,97,108,105,116,121,0,100,119,66,121,116,101,115, -80,101,114,83,101,99,111,110,100,0,100,119,70,108,97,103,115,0,100,119,73,110,116,101,114,108,101,97,118,101,69,118, -101,114,121,0,97,118,105,99,111,100,101,99,110,97,109,101,91,49,50,56,93,0,42,99,100,80,97,114,109,115,0,42, -112,97,100,0,99,100,83,105,122,101,0,113,116,99,111,100,101,99,110,97,109,101,91,49,50,56,93,0,99,111,100,101, -99,0,97,117,100,105,111,95,99,111,100,101,99,0,118,105,100,101,111,95,98,105,116,114,97,116,101,0,97,117,100,105, -111,95,98,105,116,114,97,116,101,0,103,111,112,95,115,105,122,101,0,114,99,95,109,105,110,95,114,97,116,101,0,114, -99,95,109,97,120,95,114,97,116,101,0,114,99,95,98,117,102,102,101,114,95,115,105,122,101,0,109,117,120,95,112,97, -99,107,101,116,95,115,105,122,101,0,109,117,120,95,114,97,116,101,0,109,105,120,114,97,116,101,0,109,97,105,110,0, -42,109,97,116,95,111,118,101,114,114,105,100,101,0,42,108,105,103,104,116,95,111,118,101,114,114,105,100,101,0,108,97, -121,95,122,109,97,115,107,0,108,97,121,102,108,97,103,0,112,97,115,115,102,108,97,103,0,112,97,115,115,95,120,111, -114,0,42,97,118,105,99,111,100,101,99,100,97,116,97,0,42,113,116,99,111,100,101,99,100,97,116,97,0,102,102,99, -111,100,101,99,100,97,116,97,0,99,102,114,97,0,112,115,102,114,97,0,112,101,102,114,97,0,105,109,97,103,101,115, -0,102,114,97,109,97,112,116,111,0,116,104,114,101,97,100,115,0,102,114,97,109,101,108,101,110,0,98,108,117,114,102, -97,99,0,101,100,103,101,82,0,101,100,103,101,71,0,101,100,103,101,66,0,102,117,108,108,115,99,114,101,101,110,0, -120,112,108,97,121,0,121,112,108,97,121,0,102,114,101,113,112,108,97,121,0,97,116,116,114,105,98,0,114,116,49,0, -115,116,101,114,101,111,109,111,100,101,0,100,105,109,101,110,115,105,111,110,115,112,114,101,115,101,116,0,109,97,120,105, -109,115,105,122,101,0,120,115,99,104,0,121,115,99,104,0,120,112,97,114,116,115,0,121,112,97,114,116,115,0,119,105, -110,112,111,115,0,112,108,97,110,101,115,0,105,109,116,121,112,101,0,115,117,98,105,109,116,121,112,101,0,113,117,97, -108,105,116,121,0,114,112,97,100,0,114,112,97,100,49,0,114,112,97,100,50,0,115,99,101,109,111,100,101,0,114,101, -110,100,101,114,101,114,0,111,99,114,101,115,0,97,108,112,104,97,109,111,100,101,0,111,115,97,0,102,114,115,95,115, -101,99,0,101,100,103,101,105,110,116,0,115,97,102,101,116,121,0,98,111,114,100,101,114,0,100,105,115,112,114,101,99, -116,0,108,97,121,101,114,115,0,97,99,116,108,97,121,0,120,97,115,112,0,121,97,115,112,0,102,114,115,95,115,101, -99,95,98,97,115,101,0,103,97,117,115,115,0,112,111,115,116,109,117,108,0,112,111,115,116,103,97,109,109,97,0,112, -111,115,116,104,117,101,0,112,111,115,116,115,97,116,0,100,105,116,104,101,114,95,105,110,116,101,110,115,105,116,121,0, -98,97,107,101,95,111,115,97,0,98,97,107,101,95,102,105,108,116,101,114,0,98,97,107,101,95,109,111,100,101,0,98, -97,107,101,95,102,108,97,103,0,98,97,107,101,95,110,111,114,109,97,108,95,115,112,97,99,101,0,98,97,107,101,95, -113,117,97,100,95,115,112,108,105,116,0,98,97,107,101,95,109,97,120,100,105,115,116,0,98,97,107,101,95,98,105,97, -115,100,105,115,116,0,98,97,107,101,95,112,97,100,0,71,73,113,117,97,108,105,116,121,0,71,73,99,97,99,104,101, -0,71,73,109,101,116,104,111,100,0,71,73,112,104,111,116,111,110,115,0,71,73,100,105,114,101,99,116,0,89,70,95, -65,65,0,89,70,101,120,112,111,114,116,120,109,108,0,89,70,95,110,111,98,117,109,112,0,89,70,95,99,108,97,109, -112,114,103,98,0,121,102,112,97,100,49,0,71,73,100,101,112,116,104,0,71,73,99,97,117,115,100,101,112,116,104,0, -71,73,112,105,120,101,108,115,112,101,114,115,97,109,112,108,101,0,71,73,112,104,111,116,111,110,99,111,117,110,116,0, -71,73,109,105,120,112,104,111,116,111,110,115,0,71,73,112,104,111,116,111,110,114,97,100,105,117,115,0,89,70,95,114, -97,121,100,101,112,116,104,0,89,70,95,65,65,112,97,115,115,101,115,0,89,70,95,65,65,115,97,109,112,108,101,115, -0,121,102,112,97,100,50,0,71,73,115,104,97,100,111,119,113,117,97,108,105,116,121,0,71,73,114,101,102,105,110,101, -109,101,110,116,0,71,73,112,111,119,101,114,0,71,73,105,110,100,105,114,112,111,119,101,114,0,89,70,95,103,97,109, -109,97,0,89,70,95,101,120,112,111,115,117,114,101,0,89,70,95,114,97,121,98,105,97,115,0,89,70,95,65,65,112, -105,120,101,108,115,105,122,101,0,89,70,95,65,65,116,104,114,101,115,104,111,108,100,0,98,97,99,107,98,117,102,91, -49,54,48,93,0,112,105,99,91,49,54,48,93,0,115,116,97,109,112,0,115,116,97,109,112,95,102,111,110,116,95,105, -100,0,115,116,97,109,112,95,117,100,97,116,97,91,49,54,48,93,0,102,103,95,115,116,97,109,112,91,52,93,0,98, -103,95,115,116,97,109,112,91,52,93,0,115,105,109,112,108,105,102,121,95,115,117,98,115,117,114,102,0,115,105,109,112, -108,105,102,121,95,115,104,97,100,111,119,115,97,109,112,108,101,115,0,115,105,109,112,108,105,102,121,95,112,97,114,116, -105,99,108,101,115,0,115,105,109,112,108,105,102,121,95,97,111,115,115,115,0,99,105,110,101,111,110,119,104,105,116,101, -0,99,105,110,101,111,110,98,108,97,99,107,0,99,105,110,101,111,110,103,97,109,109,97,0,106,112,50,95,112,114,101, -115,101,116,0,106,112,50,95,100,101,112,116,104,0,114,112,97,100,51,0,100,111,109,101,114,101,115,0,100,111,109,101, -109,111,100,101,0,100,111,109,101,97,110,103,108,101,0,100,111,109,101,116,105,108,116,0,100,111,109,101,114,101,115,98, -117,102,0,42,100,111,109,101,116,101,120,116,0,112,97,114,116,105,99,108,101,95,112,101,114,99,0,115,117,98,115,117, -114,102,95,109,97,120,0,115,104,97,100,98,117,102,115,97,109,112,108,101,95,109,97,120,0,97,111,95,101,114,114,111, -114,0,99,111,108,91,51,93,0,102,114,97,109,101,0,110,97,109,101,91,54,52,93,0,42,98,114,117,115,104,0,116, -111,111,108,0,115,101,97,109,95,98,108,101,101,100,0,110,111,114,109,97,108,95,97,110,103,108,101,0,115,116,101,112, -0,105,110,118,101,114,116,0,116,111,116,114,101,107,101,121,0,116,111,116,97,100,100,107,101,121,0,98,114,117,115,104, -116,121,112,101,0,98,114,117,115,104,91,55,93,0,101,109,105,116,116,101,114,100,105,115,116,0,100,114,97,119,95,116, -105,109,101,100,0,110,97,109,101,91,51,54,93,0,109,97,116,91,51,93,91,51,93,0,99,111,114,110,101,114,116,121, -112,101,0,101,100,105,116,98,117,116,102,108,97,103,0,106,111,105,110,116,114,105,108,105,109,105,116,0,100,101,103,114, -0,116,117,114,110,0,101,120,116,114,95,111,102,102,115,0,100,111,117,98,108,105,109,105,116,0,115,101,103,109,101,110, -116,115,0,114,105,110,103,115,0,118,101,114,116,105,99,101,115,0,117,110,119,114,97,112,112,101,114,0,117,118,99,97, -108,99,95,114,97,100,105,117,115,0,117,118,99,97,108,99,95,99,117,98,101,115,105,122,101,0,117,118,99,97,108,99, -95,109,97,114,103,105,110,0,117,118,99,97,108,99,95,109,97,112,100,105,114,0,117,118,99,97,108,99,95,109,97,112, -97,108,105,103,110,0,117,118,99,97,108,99,95,102,108,97,103,0,97,117,116,111,105,107,95,99,104,97,105,110,108,101, -110,0,105,109,97,112,97,105,110,116,0,112,97,114,116,105,99,108,101,0,115,101,108,101,99,116,95,116,104,114,101,115, -104,0,99,108,101,97,110,95,116,104,114,101,115,104,0,114,101,116,111,112,111,95,109,111,100,101,0,114,101,116,111,112, -111,95,112,97,105,110,116,95,116,111,111,108,0,108,105,110,101,95,100,105,118,0,101,108,108,105,112,115,101,95,100,105, -118,0,114,101,116,111,112,111,95,104,111,116,115,112,111,116,0,109,117,108,116,105,114,101,115,95,115,117,98,100,105,118, -95,116,121,112,101,0,115,107,103,101,110,95,114,101,115,111,108,117,116,105,111,110,0,115,107,103,101,110,95,116,104,114, -101,115,104,111,108,100,95,105,110,116,101,114,110,97,108,0,115,107,103,101,110,95,116,104,114,101,115,104,111,108,100,95, -101,120,116,101,114,110,97,108,0,115,107,103,101,110,95,108,101,110,103,116,104,95,114,97,116,105,111,0,115,107,103,101, -110,95,108,101,110,103,116,104,95,108,105,109,105,116,0,115,107,103,101,110,95,97,110,103,108,101,95,108,105,109,105,116, -0,115,107,103,101,110,95,99,111,114,114,101,108,97,116,105,111,110,95,108,105,109,105,116,0,115,107,103,101,110,95,115, -121,109,109,101,116,114,121,95,108,105,109,105,116,0,115,107,103,101,110,95,114,101,116,97,114,103,101,116,95,97,110,103, -108,101,95,119,101,105,103,104,116,0,115,107,103,101,110,95,114,101,116,97,114,103,101,116,95,108,101,110,103,116,104,95, -119,101,105,103,104,116,0,115,107,103,101,110,95,114,101,116,97,114,103,101,116,95,100,105,115,116,97,110,99,101,95,119, -101,105,103,104,116,0,115,107,103,101,110,95,111,112,116,105,111,110,115,0,115,107,103,101,110,95,112,111,115,116,112,114, -111,0,115,107,103,101,110,95,112,111,115,116,112,114,111,95,112,97,115,115,101,115,0,115,107,103,101,110,95,115,117,98, -100,105,118,105,115,105,111,110,115,91,51,93,0,115,107,103,101,110,95,109,117,108,116,105,95,108,101,118,101,108,0,42, -115,107,103,101,110,95,116,101,109,112,108,97,116,101,0,98,111,110,101,95,115,107,101,116,99,104,105,110,103,0,98,111, -110,101,95,115,107,101,116,99,104,105,110,103,95,99,111,110,118,101,114,116,0,115,107,103,101,110,95,115,117,98,100,105, -118,105,115,105,111,110,95,110,117,109,98,101,114,0,115,107,103,101,110,95,114,101,116,97,114,103,101,116,95,111,112,116, -105,111,110,115,0,115,107,103,101,110,95,114,101,116,97,114,103,101,116,95,114,111,108,108,0,115,107,103,101,110,95,115, -105,100,101,95,115,116,114,105,110,103,91,56,93,0,115,107,103,101,110,95,110,117,109,95,115,116,114,105,110,103,91,56, -93,0,101,100,103,101,95,109,111,100,101,0,112,97,100,51,91,50,93,0,100,105,114,0,118,105,101,119,0,42,115,101, -115,115,105,111,110,0,42,99,117,109,97,112,0,100,114,97,119,98,114,117,115,104,0,115,109,111,111,116,104,98,114,117, -115,104,0,112,105,110,99,104,98,114,117,115,104,0,105,110,102,108,97,116,101,98,114,117,115,104,0,103,114,97,98,98, -114,117,115,104,0,108,97,121,101,114,98,114,117,115,104,0,102,108,97,116,116,101,110,98,114,117,115,104,0,112,105,118, -111,116,91,51,93,0,98,114,117,115,104,95,116,121,112,101,0,116,101,120,110,114,0,116,101,120,114,101,112,116,0,116, -101,120,102,97,100,101,0,116,101,120,115,101,112,0,97,118,101,114,97,103,105,110,103,0,116,97,98,108,101,116,95,115, -105,122,101,0,116,97,98,108,101,116,95,115,116,114,101,110,103,116,104,0,115,121,109,109,0,114,97,107,101,0,97,120, -105,115,108,111,99,107,0,42,99,97,109,101,114,97,0,42,119,111,114,108,100,0,42,115,101,116,0,98,97,115,101,0, -42,98,97,115,97,99,116,0,99,117,114,115,111,114,91,51,93,0,116,119,99,101,110,116,91,51,93,0,116,119,109,105, -110,91,51,93,0,116,119,109,97,120,91,51,93,0,101,100,105,116,98,117,116,115,105,122,101,0,115,101,108,101,99,116, -109,111,100,101,0,112,114,111,112,111,114,116,105,111,110,97,108,0,112,114,111,112,95,109,111,100,101,0,97,117,116,111, -109,101,114,103,101,0,112,97,100,53,0,112,97,100,54,0,97,117,116,111,107,101,121,95,109,111,100,101,0,42,101,100, -0,42,114,97,100,105,111,0,102,114,97,109,105,110,103,0,42,116,111,111,108,115,101,116,116,105,110,103,115,0,97,117, -100,105,111,0,116,114,97,110,115,102,111,114,109,95,115,112,97,99,101,115,0,106,117,109,112,102,114,97,109,101,0,115, -110,97,112,95,109,111,100,101,0,115,110,97,112,95,102,108,97,103,0,115,110,97,112,95,116,97,114,103,101,116,0,42, -116,104,101,68,97,103,0,100,97,103,105,115,118,97,108,105,100,0,100,97,103,102,108,97,103,115,0,115,99,117,108,112, -116,100,97,116,97,0,102,114,97,109,101,95,115,116,101,112,0,122,111,111,109,0,98,108,101,110,100,0,120,105,109,0, -121,105,109,0,115,112,97,99,101,116,121,112,101,0,98,108,111,99,107,115,99,97,108,101,0,42,97,114,101,97,0,98, -108,111,99,107,104,97,110,100,108,101,114,91,56,93,0,118,105,101,119,109,97,116,91,52,93,91,52,93,0,118,105,101, -119,105,110,118,91,52,93,91,52,93,0,112,101,114,115,109,97,116,91,52,93,91,52,93,0,112,101,114,115,105,110,118, -91,52,93,91,52,93,0,119,105,110,109,97,116,49,91,52,93,91,52,93,0,118,105,101,119,109,97,116,49,91,52,93, -91,52,93,0,118,105,101,119,113,117,97,116,91,52,93,0,122,102,97,99,0,108,97,121,95,117,115,101,100,0,112,101, -114,115,112,0,42,111,98,95,99,101,110,116,114,101,0,42,98,103,112,105,99,0,42,108,111,99,97,108,118,100,0,42, -114,105,0,42,114,101,116,111,112,111,95,118,105,101,119,95,100,97,116,97,0,42,100,101,112,116,104,115,0,111,98,95, -99,101,110,116,114,101,95,98,111,110,101,91,51,50,93,0,108,111,99,97,108,118,105,101,119,0,108,97,121,97,99,116, -0,115,99,101,110,101,108,111,99,107,0,97,114,111,117,110,100,0,99,97,109,122,111,111,109,0,112,105,118,111,116,95, -108,97,115,116,0,103,114,105,100,0,103,114,105,100,118,105,101,119,0,112,105,120,115,105,122,101,0,110,101,97,114,0, -102,97,114,0,99,97,109,100,120,0,99,97,109,100,121,0,103,114,105,100,108,105,110,101,115,0,118,105,101,119,98,117, -116,0,103,114,105,100,102,108,97,103,0,109,111,100,101,115,101,108,101,99,116,0,116,119,116,121,112,101,0,116,119,109, -111,100,101,0,116,119,102,108,97,103,0,116,119,100,114,97,119,102,108,97,103,0,116,119,109,97,116,91,52,93,91,52, -93,0,99,108,105,112,91,52,93,91,52,93,0,42,99,108,105,112,98,98,0,97,102,116,101,114,100,114,97,119,0,122, -98,117,102,0,120,114,97,121,0,102,108,97,103,50,0,103,114,105,100,115,117,98,100,105,118,0,107,101,121,102,108,97, -103,115,0,110,100,111,102,109,111,100,101,0,110,100,111,102,102,105,108,116,101,114,0,42,112,114,111,112,101,114,116,105, -101,115,95,115,116,111,114,97,103,101,0,42,103,112,100,0,108,118,105,101,119,113,117,97,116,91,52,93,0,108,112,101, -114,115,112,0,108,118,105,101,119,0,118,101,114,116,0,104,111,114,0,109,97,115,107,0,109,105,110,91,50,93,0,109, -97,120,91,50,93,0,109,105,110,122,111,111,109,0,109,97,120,122,111,111,109,0,115,99,114,111,108,108,0,107,101,101, -112,116,111,116,0,107,101,101,112,97,115,112,101,99,116,0,107,101,101,112,122,111,111,109,0,111,108,100,119,105,110,120, -0,111,108,100,119,105,110,121,0,99,117,114,115,111,114,91,50,93,0,114,111,119,98,117,116,0,118,50,100,0,42,101, -100,105,116,105,112,111,0,105,112,111,107,101,121,0,97,99,116,110,97,109,101,91,51,50,93,0,99,111,110,115,116,110, -97,109,101,91,51,50,93,0,98,111,110,101,110,97,109,101,91,51,50,93,0,116,111,116,105,112,111,0,112,105,110,0, -98,117,116,111,102,115,0,99,104,97,110,110,101,108,0,108,111,99,107,0,109,101,100,105,97,110,91,51,93,0,99,117, -114,115,101,110,115,0,99,117,114,97,99,116,0,97,108,105,103,110,0,116,97,98,111,0,109,97,105,110,98,0,109,97, -105,110,98,111,0,42,108,111,99,107,112,111,105,110,0,116,101,120,102,114,111,109,0,115,104,111,119,103,114,111,117,112, -0,109,111,100,101,108,116,121,112,101,0,115,99,114,105,112,116,98,108,111,99,107,0,114,101,95,97,108,105,103,110,0, -111,108,100,107,101,121,112,114,101,115,115,0,116,97,98,91,55,93,0,114,101,110,100,101,114,95,115,105,122,101,0,99, -104,97,110,115,104,111,119,110,0,122,101,98,114,97,0,42,102,105,108,101,108,105,115,116,0,116,111,116,102,105,108,101, -0,116,105,116,108,101,91,50,52,93,0,100,105,114,91,50,52,48,93,0,102,105,108,101,91,56,48,93,0,111,102,115, -0,115,111,114,116,0,109,97,120,110,97,109,101,108,101,110,0,99,111,108,108,117,109,115,0,102,95,102,112,0,102,112, -95,115,116,114,91,56,93,0,42,108,105,98,102,105,108,101,100,97,116,97,0,114,101,116,118,97,108,0,109,101,110,117, -0,97,99,116,0,40,42,114,101,116,117,114,110,102,117,110,99,41,40,41,0,40,42,114,101,116,117,114,110,102,117,110, -99,95,101,118,101,110,116,41,40,41,0,40,42,114,101,116,117,114,110,102,117,110,99,95,97,114,103,115,41,40,41,0, -42,97,114,103,49,0,42,97,114,103,50,0,42,109,101,110,117,112,0,42,112,117,112,109,101,110,117,0,111,111,112,115, -0,118,105,115,105,102,108,97,103,0,116,114,101,101,0,42,116,114,101,101,115,116,111,114,101,0,115,101,97,114,99,104, -95,115,116,114,105,110,103,91,51,50,93,0,115,101,97,114,99,104,95,116,115,101,0,115,101,97,114,99,104,95,102,108, -97,103,115,0,100,111,95,0,111,117,116,108,105,110,101,118,105,115,0,115,116,111,114,101,102,108,97,103,0,100,101,112, -115,95,102,108,97,103,115,0,105,109,97,110,114,0,99,117,114,116,105,108,101,0,105,109,116,121,112,101,110,114,0,100, -116,95,117,118,0,115,116,105,99,107,121,0,100,116,95,117,118,115,116,114,101,116,99,104,0,112,97,100,91,53,93,0, -99,101,110,116,120,0,99,101,110,116,121,0,97,117,116,111,115,110,97,112,0,42,116,101,120,116,0,116,111,112,0,118, -105,101,119,108,105,110,101,115,0,102,111,110,116,95,105,100,0,108,104,101,105,103,104,116,0,108,101,102,116,0,115,104, -111,119,108,105,110,101,110,114,115,0,116,97,98,110,117,109,98,101,114,0,99,117,114,114,116,97,98,95,115,101,116,0, -115,104,111,119,115,121,110,116,97,120,0,111,118,101,114,119,114,105,116,101,0,112,105,120,95,112,101,114,95,108,105,110, -101,0,116,120,116,115,99,114,111,108,108,0,116,120,116,98,97,114,0,119,111,114,100,119,114,97,112,0,100,111,112,108, -117,103,105,110,115,0,42,112,121,95,100,114,97,119,0,42,112,121,95,101,118,101,110,116,0,42,112,121,95,98,117,116, -116,111,110,0,42,112,121,95,98,114,111,119,115,101,114,99,97,108,108,98,97,99,107,0,42,112,121,95,103,108,111,98, -97,108,100,105,99,116,0,108,97,115,116,115,112,97,99,101,0,115,99,114,105,112,116,110,97,109,101,91,50,53,54,93, -0,115,99,114,105,112,116,97,114,103,91,50,53,54,93,0,42,115,99,114,105,112,116,0,42,98,117,116,95,114,101,102, -115,0,114,101,100,114,97,119,115,0,42,105,100,0,97,115,112,101,99,116,0,42,99,117,114,102,111,110,116,0,42,101, -100,105,116,116,114,101,101,0,116,114,101,101,116,121,112,101,0,42,102,105,108,101,115,0,97,99,116,105,118,101,95,102, -105,108,101,0,110,117,109,116,105,108,101,115,120,0,110,117,109,116,105,108,101,115,121,0,115,101,108,115,116,97,116,101, -0,118,105,101,119,114,101,99,116,0,98,111,111,107,109,97,114,107,114,101,99,116,0,115,99,114,111,108,108,112,111,115, -0,115,99,114,111,108,108,104,101,105,103,104,116,0,115,99,114,111,108,108,97,114,101,97,0,97,99,116,105,118,101,95, -98,111,111,107,109,97,114,107,0,112,114,118,95,119,0,112,114,118,95,104,0,42,105,109,103,0,111,117,116,108,105,110, -101,91,52,93,0,110,101,117,116,114,97,108,91,52,93,0,97,99,116,105,111,110,91,52,93,0,115,101,116,116,105,110, -103,91,52,93,0,115,101,116,116,105,110,103,49,91,52,93,0,115,101,116,116,105,110,103,50,91,52,93,0,110,117,109, -91,52,93,0,116,101,120,116,102,105,101,108,100,91,52,93,0,116,101,120,116,102,105,101,108,100,95,104,105,91,52,93, -0,112,111,112,117,112,91,52,93,0,116,101,120,116,91,52,93,0,116,101,120,116,95,104,105,91,52,93,0,109,101,110, -117,95,98,97,99,107,91,52,93,0,109,101,110,117,95,105,116,101,109,91,52,93,0,109,101,110,117,95,104,105,108,105, -116,101,91,52,93,0,109,101,110,117,95,116,101,120,116,91,52,93,0,109,101,110,117,95,116,101,120,116,95,104,105,91, -52,93,0,98,117,116,95,100,114,97,119,116,121,112,101,0,105,99,111,110,102,105,108,101,91,56,48,93,0,98,97,99, -107,91,52,93,0,104,101,97,100,101,114,91,52,93,0,112,97,110,101,108,91,52,93,0,115,104,97,100,101,49,91,52, -93,0,115,104,97,100,101,50,91,52,93,0,104,105,108,105,116,101,91,52,93,0,103,114,105,100,91,52,93,0,119,105, -114,101,91,52,93,0,115,101,108,101,99,116,91,52,93,0,108,97,109,112,91,52,93,0,97,99,116,105,118,101,91,52, -93,0,103,114,111,117,112,91,52,93,0,103,114,111,117,112,95,97,99,116,105,118,101,91,52,93,0,116,114,97,110,115, -102,111,114,109,91,52,93,0,118,101,114,116,101,120,91,52,93,0,118,101,114,116,101,120,95,115,101,108,101,99,116,91, -52,93,0,101,100,103,101,91,52,93,0,101,100,103,101,95,115,101,108,101,99,116,91,52,93,0,101,100,103,101,95,115, -101,97,109,91,52,93,0,101,100,103,101,95,115,104,97,114,112,91,52,93,0,101,100,103,101,95,102,97,99,101,115,101, -108,91,52,93,0,102,97,99,101,91,52,93,0,102,97,99,101,95,115,101,108,101,99,116,91,52,93,0,102,97,99,101, -95,100,111,116,91,52,93,0,110,111,114,109,97,108,91,52,93,0,98,111,110,101,95,115,111,108,105,100,91,52,93,0, -98,111,110,101,95,112,111,115,101,91,52,93,0,115,116,114,105,112,91,52,93,0,115,116,114,105,112,95,115,101,108,101, -99,116,91,52,93,0,99,102,114,97,109,101,91,52,93,0,118,101,114,116,101,120,95,115,105,122,101,0,102,97,99,101, -100,111,116,95,115,105,122,101,0,98,112,97,100,91,50,93,0,115,121,110,116,97,120,108,91,52,93,0,115,121,110,116, -97,120,110,91,52,93,0,115,121,110,116,97,120,98,91,52,93,0,115,121,110,116,97,120,118,91,52,93,0,115,121,110, -116,97,120,99,91,52,93,0,109,111,118,105,101,91,52,93,0,105,109,97,103,101,91,52,93,0,115,99,101,110,101,91, -52,93,0,97,117,100,105,111,91,52,93,0,101,102,102,101,99,116,91,52,93,0,112,108,117,103,105,110,91,52,93,0, -116,114,97,110,115,105,116,105,111,110,91,52,93,0,109,101,116,97,91,52,93,0,101,100,105,116,109,101,115,104,95,97, -99,116,105,118,101,91,52,93,0,104,97,110,100,108,101,95,118,101,114,116,101,120,91,52,93,0,104,97,110,100,108,101, -95,118,101,114,116,101,120,95,115,101,108,101,99,116,91,52,93,0,104,97,110,100,108,101,95,118,101,114,116,101,120,95, -115,105,122,101,0,104,112,97,100,91,55,93,0,115,111,108,105,100,91,52,93,0,116,117,105,0,116,98,117,116,115,0, -116,118,51,100,0,116,102,105,108,101,0,116,105,112,111,0,116,105,110,102,111,0,116,115,110,100,0,116,97,99,116,0, -116,110,108,97,0,116,115,101,113,0,116,105,109,97,0,116,105,109,97,115,101,108,0,116,101,120,116,0,116,111,111,112, -115,0,116,116,105,109,101,0,116,110,111,100,101,0,116,97,114,109,91,50,48,93,0,98,112,97,100,91,52,93,0,98, -112,97,100,49,91,52,93,0,115,112,101,99,91,52,93,0,100,117,112,102,108,97,103,0,115,97,118,101,116,105,109,101, -0,116,101,109,112,100,105,114,91,49,54,48,93,0,102,111,110,116,100,105,114,91,49,54,48,93,0,114,101,110,100,101, -114,100,105,114,91,49,54,48,93,0,116,101,120,116,117,100,105,114,91,49,54,48,93,0,112,108,117,103,116,101,120,100, -105,114,91,49,54,48,93,0,112,108,117,103,115,101,113,100,105,114,91,49,54,48,93,0,112,121,116,104,111,110,100,105, -114,91,49,54,48,93,0,115,111,117,110,100,100,105,114,91,49,54,48,93,0,121,102,101,120,112,111,114,116,100,105,114, -91,49,54,48,93,0,118,101,114,115,105,111,110,115,0,118,114,109,108,102,108,97,103,0,103,97,109,101,102,108,97,103, -115,0,119,104,101,101,108,108,105,110,101,115,99,114,111,108,108,0,117,105,102,108,97,103,0,108,97,110,103,117,97,103, -101,0,117,115,101,114,112,114,101,102,0,118,105,101,119,122,111,111,109,0,99,111,110,115,111,108,101,95,98,117,102,102, -101,114,0,99,111,110,115,111,108,101,95,111,117,116,0,109,105,120,98,117,102,115,105,122,101,0,102,111,110,116,115,105, -122,101,0,101,110,99,111,100,105,110,103,0,116,114,97,110,115,111,112,116,115,0,109,101,110,117,116,104,114,101,115,104, -111,108,100,49,0,109,101,110,117,116,104,114,101,115,104,111,108,100,50,0,102,111,110,116,110,97,109,101,91,50,53,54, -93,0,116,104,101,109,101,115,0,117,110,100,111,115,116,101,112,115,0,117,110,100,111,109,101,109,111,114,121,0,103,112, -95,109,97,110,104,97,116,116,101,110,100,105,115,116,0,103,112,95,101,117,99,108,105,100,101,97,110,100,105,115,116,0, -103,112,95,101,114,97,115,101,114,0,103,112,95,115,101,116,116,105,110,103,115,0,116,98,95,108,101,102,116,109,111,117, -115,101,0,116,98,95,114,105,103,104,116,109,111,117,115,101,0,108,105,103,104,116,91,51,93,0,116,119,95,104,111,116, -115,112,111,116,0,116,119,95,102,108,97,103,0,116,119,95,104,97,110,100,108,101,115,105,122,101,0,116,119,95,115,105, -122,101,0,116,101,120,116,105,109,101,111,117,116,0,116,101,120,99,111,108,108,101,99,116,114,97,116,101,0,109,101,109, -99,97,99,104,101,108,105,109,105,116,0,112,114,101,102,101,116,99,104,102,114,97,109,101,115,0,102,114,97,109,101,115, -101,114,118,101,114,112,111,114,116,0,112,97,100,95,114,111,116,95,97,110,103,108,101,0,111,98,99,101,110,116,101,114, -95,100,105,97,0,114,118,105,115,105,122,101,0,114,118,105,98,114,105,103,104,116,0,114,101,99,101,110,116,95,102,105, -108,101,115,0,115,109,111,111,116,104,95,118,105,101,119,116,120,0,103,108,114,101,115,108,105,109,105,116,0,110,100,111, -102,95,112,97,110,0,110,100,111,102,95,114,111,116,97,116,101,0,99,117,114,115,115,105,122,101,0,112,97,100,91,56, -93,0,118,101,114,115,101,109,97,115,116,101,114,91,49,54,48,93,0,118,101,114,115,101,117,115,101,114,91,49,54,48, -93,0,103,108,97,108,112,104,97,99,108,105,112,0,97,117,116,111,107,101,121,95,102,108,97,103,0,99,111,98,97,95, -119,101,105,103,104,116,0,118,101,114,116,98,97,115,101,0,101,100,103,101,98,97,115,101,0,97,114,101,97,98,97,115, -101,0,42,115,99,101,110,101,0,101,110,100,120,0,101,110,100,121,0,115,105,122,101,120,0,115,105,122,101,121,0,115, -99,101,110,101,110,114,0,115,99,114,101,101,110,110,114,0,102,117,108,108,0,109,97,105,110,119,105,110,0,119,105,110, -97,107,116,0,104,97,110,100,108,101,114,91,56,93,0,42,110,101,119,118,0,118,101,99,0,42,118,49,0,42,118,50, -0,112,97,110,101,108,110,97,109,101,91,54,52,93,0,116,97,98,110,97,109,101,91,54,52,93,0,100,114,97,119,110, -97,109,101,91,54,52,93,0,111,102,115,120,0,111,102,115,121,0,99,111,110,116,114,111,108,0,115,110,97,112,0,111, -108,100,95,111,102,115,120,0,111,108,100,95,111,102,115,121,0,115,111,114,116,99,111,117,110,116,101,114,0,42,112,97, -110,101,108,116,97,98,0,42,118,51,0,42,118,52,0,42,102,117,108,108,0,119,105,110,109,97,116,91,52,93,91,52, -93,0,104,101,97,100,114,99,116,0,119,105,110,114,99,116,0,104,101,97,100,119,105,110,0,119,105,110,0,104,101,97, -100,101,114,116,121,112,101,0,98,117,116,115,112,97,99,101,116,121,112,101,0,119,105,110,120,0,119,105,110,121,0,104, -101,97,100,95,115,119,97,112,0,104,101,97,100,95,101,113,117,97,108,0,119,105,110,95,115,119,97,112,0,119,105,110, -95,101,113,117,97,108,0,104,101,97,100,98,117,116,108,101,110,0,104,101,97,100,98,117,116,111,102,115,0,99,117,114, -115,111,114,0,115,112,97,99,101,100,97,116,97,0,117,105,98,108,111,99,107,115,0,112,97,110,101,108,115,0,115,117, -98,118,115,116,114,91,52,93,0,115,117,98,118,101,114,115,105,111,110,0,112,97,100,115,0,109,105,110,118,101,114,115, -105,111,110,0,109,105,110,115,117,98,118,101,114,115,105,111,110,0,100,105,115,112,108,97,121,109,111,100,101,0,42,99, -117,114,115,99,114,101,101,110,0,42,99,117,114,115,99,101,110,101,0,102,105,108,101,102,108,97,103,115,0,103,108,111, -98,97,108,102,0,110,97,109,101,91,56,48,93,0,42,105,98,117,102,0,42,105,98,117,102,95,99,111,109,112,0,42, -115,101,49,0,42,115,101,50,0,42,115,101,51,0,110,114,0,98,111,116,116,111,109,0,114,105,103,104,116,0,120,111, -102,115,0,121,111,102,115,0,108,105,102,116,91,51,93,0,103,97,109,109,97,91,51,93,0,103,97,105,110,91,51,93, -0,115,97,116,117,114,97,116,105,111,110,0,42,103,117,105,0,100,105,114,91,49,54,48,93,0,100,111,110,101,0,115, -116,97,114,116,115,116,105,108,108,0,101,110,100,115,116,105,108,108,0,42,115,116,114,105,112,100,97,116,97,0,111,114, -120,0,111,114,121,0,42,99,114,111,112,0,42,116,114,97,110,115,102,111,114,109,0,42,99,111,108,111,114,95,98,97, -108,97,110,99,101,0,42,116,115,116,114,105,112,100,97,116,97,0,42,116,115,116,114,105,112,100,97,116,97,95,115,116, -97,114,116,115,116,105,108,108,0,42,116,115,116,114,105,112,100,97,116,97,95,101,110,100,115,116,105,108,108,0,42,105, -98,117,102,95,115,116,97,114,116,115,116,105,108,108,0,42,105,98,117,102,95,101,110,100,115,116,105,108,108,0,42,105, -110,115,116,97,110,99,101,95,112,114,105,118,97,116,101,95,100,97,116,97,0,42,42,99,117,114,114,101,110,116,95,112, -114,105,118,97,116,101,95,100,97,116,97,0,42,116,109,112,0,115,116,97,114,116,111,102,115,0,101,110,100,111,102,115, -0,109,97,99,104,105,110,101,0,115,116,97,114,116,100,105,115,112,0,101,110,100,100,105,115,112,0,109,117,108,0,104, -97,110,100,115,105,122,101,0,97,110,105,109,95,112,114,101,115,101,101,107,0,42,115,116,114,105,112,0,102,97,99,102, -48,0,102,97,99,102,49,0,42,115,101,113,49,0,42,115,101,113,50,0,42,115,101,113,51,0,115,101,113,98,97,115, -101,0,42,115,111,117,110,100,0,42,104,100,97,117,100,105,111,0,108,101,118,101,108,0,112,97,110,0,115,116,114,111, -98,101,0,42,101,102,102,101,99,116,100,97,116,97,0,97,110,105,109,95,115,116,97,114,116,111,102,115,0,97,110,105, -109,95,101,110,100,111,102,115,0,98,108,101,110,100,95,109,111,100,101,0,98,108,101,110,100,95,111,112,97,99,105,116, -121,0,42,111,108,100,98,97,115,101,112,0,42,112,97,114,115,101,113,0,42,115,101,113,98,97,115,101,112,0,109,101, -116,97,115,116,97,99,107,0,101,100,103,101,87,105,100,116,104,0,102,111,114,119,97,114,100,0,119,105,112,101,116,121, -112,101,0,102,77,105,110,105,0,102,67,108,97,109,112,0,102,66,111,111,115,116,0,100,68,105,115,116,0,100,81,117, -97,108,105,116,121,0,98,78,111,67,111,109,112,0,83,99,97,108,101,120,73,110,105,0,83,99,97,108,101,121,73,110, -105,0,83,99,97,108,101,120,70,105,110,0,83,99,97,108,101,121,70,105,110,0,120,73,110,105,0,120,70,105,110,0, -121,73,110,105,0,121,70,105,110,0,114,111,116,73,110,105,0,114,111,116,70,105,110,0,105,110,116,101,114,112,111,108, -97,116,105,111,110,0,42,102,114,97,109,101,77,97,112,0,103,108,111,98,97,108,83,112,101,101,100,0,108,97,115,116, -86,97,108,105,100,70,114,97,109,101,0,98,108,101,110,100,70,114,97,109,101,115,0,98,117,116,116,121,112,101,0,117, -115,101,114,106,105,116,0,115,116,97,0,116,111,116,112,97,114,116,0,110,111,114,109,102,97,99,0,111,98,102,97,99, -0,114,97,110,100,102,97,99,0,116,101,120,102,97,99,0,114,97,110,100,108,105,102,101,0,102,111,114,99,101,91,51, -93,0,118,101,99,116,115,105,122,101,0,109,97,120,108,101,110,0,100,101,102,118,101,99,91,51,93,0,109,117,108,116, -91,52,93,0,108,105,102,101,91,52,93,0,99,104,105,108,100,91,52,93,0,109,97,116,91,52,93,0,116,101,120,109, -97,112,0,99,117,114,109,117,108,116,0,115,116,97,116,105,99,115,116,101,112,0,111,109,97,116,0,116,105,109,101,116, -101,120,0,115,112,101,101,100,116,101,120,0,102,108,97,103,50,110,101,103,0,118,101,114,116,103,114,111,117,112,95,118, -0,118,103,114,111,117,112,110,97,109,101,91,51,50,93,0,118,103,114,111,117,112,110,97,109,101,95,118,91,51,50,93, -0,42,107,101,121,115,0,109,105,110,102,97,99,0,117,115,101,100,0,117,115,101,100,101,108,101,109,0,100,120,0,100, -121,0,108,105,110,107,0,111,116,121,112,101,0,111,108,100,0,42,112,111,105,110,0,42,111,108,100,112,111,105,110,0, -114,101,115,101,116,100,105,115,116,0,108,97,115,116,118,97,108,0,42,109,97,0,107,101,121,0,113,117,97,108,0,113, -117,97,108,50,0,116,97,114,103,101,116,78,97,109,101,91,51,50,93,0,116,111,103,103,108,101,78,97,109,101,91,51, -50,93,0,118,97,108,117,101,91,51,50,93,0,109,97,120,118,97,108,117,101,91,51,50,93,0,100,101,108,97,121,0, -100,117,114,97,116,105,111,110,0,109,97,116,101,114,105,97,108,78,97,109,101,91,51,50,93,0,100,97,109,112,116,105, -109,101,114,0,112,114,111,112,110,97,109,101,91,51,50,93,0,109,97,116,110,97,109,101,91,51,50,93,0,97,120,105, -115,102,108,97,103,0,42,102,114,111,109,79,98,106,101,99,116,0,115,117,98,106,101,99,116,91,51,50,93,0,98,111, -100,121,91,51,50,93,0,112,117,108,115,101,0,102,114,101,113,0,116,111,116,108,105,110,107,115,0,42,42,108,105,110, -107,115,0,116,97,112,0,106,111,121,105,110,100,101,120,0,97,120,105,115,95,115,105,110,103,108,101,0,97,120,105,115, -102,0,98,117,116,116,111,110,0,104,97,116,0,104,97,116,102,0,112,114,101,99,105,115,105,111,110,0,115,116,114,91, -49,50,56,93,0,109,111,100,117,108,101,91,54,52,93,0,42,109,121,110,101,119,0,105,110,112,117,116,115,0,116,111, -116,115,108,105,110,107,115,0,42,42,115,108,105,110,107,115,0,118,97,108,111,0,115,116,97,116,101,95,109,97,115,107, -0,42,97,99,116,0,102,114,97,109,101,80,114,111,112,91,51,50,93,0,98,108,101,110,100,105,110,0,112,114,105,111, -114,105,116,121,0,101,110,100,95,114,101,115,101,116,0,115,116,114,105,100,101,97,120,105,115,0,115,116,114,105,100,101, -108,101,110,103,116,104,0,115,110,100,110,114,0,112,97,100,49,91,50,93,0,109,97,107,101,99,111,112,121,0,99,111, -112,121,109,97,100,101,0,112,97,100,50,91,49,93,0,116,114,97,99,107,0,42,109,101,0,108,105,110,86,101,108,111, -99,105,116,121,91,51,93,0,97,110,103,86,101,108,111,99,105,116,121,91,51,93,0,108,111,99,97,108,102,108,97,103, -0,100,121,110,95,111,112,101,114,97,116,105,111,110,0,102,111,114,99,101,108,111,99,91,51,93,0,102,111,114,99,101, -114,111,116,91,51,93,0,108,105,110,101,97,114,118,101,108,111,99,105,116,121,91,51,93,0,97,110,103,117,108,97,114, -118,101,108,111,99,105,116,121,91,51,93,0,42,114,101,102,101,114,101,110,99,101,0,98,117,116,115,116,97,0,98,117, -116,101,110,100,0,109,105,110,0,109,97,120,0,118,105,115,105,102,97,99,0,114,111,116,100,97,109,112,0,109,105,110, -108,111,99,91,51,93,0,109,97,120,108,111,99,91,51,93,0,109,105,110,114,111,116,91,51,93,0,109,97,120,114,111, -116,91,51,93,0,109,97,116,112,114,111,112,91,51,50,93,0,100,105,115,116,114,105,98,117,116,105,111,110,0,105,110, -116,95,97,114,103,95,49,0,105,110,116,95,97,114,103,95,50,0,102,108,111,97,116,95,97,114,103,95,49,0,102,108, -111,97,116,95,97,114,103,95,50,0,116,111,80,114,111,112,78,97,109,101,91,51,50,93,0,42,116,111,79,98,106,101, -99,116,0,98,111,100,121,84,121,112,101,0,102,105,108,101,110,97,109,101,91,54,52,93,0,108,111,97,100,97,110,105, -110,97,109,101,91,54,52,93,0,105,110,116,95,97,114,103,0,102,108,111,97,116,95,97,114,103,0,103,111,0,97,99, -99,101,108,108,101,114,97,116,105,111,110,0,109,97,120,115,112,101,101,100,0,109,97,120,114,111,116,115,112,101,101,100, -0,109,97,120,116,105,108,116,115,112,101,101,100,0,116,105,108,116,100,97,109,112,0,115,112,101,101,100,100,97,109,112, -0,42,115,97,109,112,108,101,0,42,115,116,114,101,97,109,0,42,110,101,119,112,97,99,107,101,100,102,105,108,101,0, -42,115,110,100,95,115,111,117,110,100,0,112,97,110,110,105,110,103,0,97,116,116,101,110,117,97,116,105,111,110,0,112, -105,116,99,104,0,109,105,110,95,103,97,105,110,0,109,97,120,95,103,97,105,110,0,100,105,115,116,97,110,99,101,0, -115,116,114,101,97,109,108,101,110,0,99,104,97,110,110,101,108,115,0,104,105,103,104,112,114,105,111,0,112,97,100,91, -49,48,93,0,103,97,105,110,0,100,111,112,112,108,101,114,102,97,99,116,111,114,0,100,111,112,112,108,101,114,118,101, -108,111,99,105,116,121,0,110,117,109,115,111,117,110,100,115,98,108,101,110,100,101,114,0,110,117,109,115,111,117,110,100, -115,103,97,109,101,101,110,103,105,110,101,0,42,108,97,109,112,114,101,110,0,103,111,98,106,101,99,116,0,100,117,112, -108,105,95,111,102,115,91,51,93,0,99,104,105,108,100,98,97,115,101,0,114,111,108,108,0,104,101,97,100,91,51,93, -0,116,97,105,108,91,51,93,0,98,111,110,101,95,109,97,116,91,51,93,91,51,93,0,97,114,109,95,104,101,97,100, -91,51,93,0,97,114,109,95,116,97,105,108,91,51,93,0,97,114,109,95,109,97,116,91,52,93,91,52,93,0,120,119, -105,100,116,104,0,122,119,105,100,116,104,0,101,97,115,101,49,0,101,97,115,101,50,0,114,97,100,95,104,101,97,100, -0,114,97,100,95,116,97,105,108,0,98,111,110,101,98,97,115,101,0,99,104,97,105,110,98,97,115,101,0,112,97,116, -104,102,108,97,103,0,108,97,121,101,114,95,112,114,111,116,101,99,116,101,100,0,103,104,111,115,116,101,112,0,103,104, -111,115,116,115,105,122,101,0,103,104,111,115,116,116,121,112,101,0,112,97,116,104,115,105,122,101,0,103,104,111,115,116, -115,102,0,103,104,111,115,116,101,102,0,112,97,116,104,115,102,0,112,97,116,104,101,102,0,112,97,116,104,98,99,0, -112,97,116,104,97,99,0,99,111,110,115,116,102,108,97,103,0,105,107,102,108,97,103,0,115,101,108,101,99,116,102,108, -97,103,0,97,103,114,112,95,105,110,100,101,120,0,42,98,111,110,101,0,42,99,104,105,108,100,0,105,107,116,114,101, -101,0,42,98,95,98,111,110,101,95,109,97,116,115,0,42,100,117,97,108,95,113,117,97,116,0,42,98,95,98,111,110, -101,95,100,117,97,108,95,113,117,97,116,115,0,99,104,97,110,95,109,97,116,91,52,93,91,52,93,0,112,111,115,101, -95,109,97,116,91,52,93,91,52,93,0,112,111,115,101,95,104,101,97,100,91,51,93,0,112,111,115,101,95,116,97,105, -108,91,51,93,0,108,105,109,105,116,109,105,110,91,51,93,0,108,105,109,105,116,109,97,120,91,51,93,0,115,116,105, -102,102,110,101,115,115,91,51,93,0,105,107,115,116,114,101,116,99,104,0,42,99,117,115,116,111,109,0,99,104,97,110, -98,97,115,101,0,112,114,111,120,121,95,108,97,121,101,114,0,115,116,114,105,100,101,95,111,102,102,115,101,116,91,51, -93,0,99,121,99,108,105,99,95,111,102,102,115,101,116,91,51,93,0,97,103,114,111,117,112,115,0,97,99,116,105,118, -101,95,103,114,111,117,112,0,99,117,115,116,111,109,67,111,108,0,99,115,0,42,103,114,112,0,114,101,115,101,114,118, -101,100,49,0,103,114,111,117,112,115,0,97,99,116,105,118,101,95,109,97,114,107,101,114,0,97,99,116,110,114,0,97, -99,116,119,105,100,116,104,0,116,105,109,101,115,108,105,100,101,0,110,97,109,101,91,51,48,93,0,111,119,110,115,112, -97,99,101,0,116,97,114,115,112,97,99,101,0,101,110,102,111,114,99,101,0,104,101,97,100,116,97,105,108,0,42,116, -97,114,0,115,117,98,116,97,114,103,101,116,91,51,50,93,0,109,97,116,114,105,120,91,52,93,91,52,93,0,115,112, -97,99,101,0,42,112,114,111,112,0,116,97,114,110,117,109,0,116,97,114,103,101,116,115,0,105,116,101,114,97,116,105, -111,110,115,0,114,111,111,116,98,111,110,101,0,109,97,120,95,114,111,111,116,98,111,110,101,0,42,112,111,108,101,116, -97,114,0,112,111,108,101,115,117,98,116,97,114,103,101,116,91,51,50,93,0,112,111,108,101,97,110,103,108,101,0,111, -114,105,101,110,116,119,101,105,103,104,116,0,103,114,97,98,116,97,114,103,101,116,91,51,93,0,114,101,115,101,114,118, -101,100,50,0,109,105,110,109,97,120,102,108,97,103,0,115,116,117,99,107,0,99,97,99,104,101,91,51,93,0,108,111, -99,107,102,108,97,103,0,102,111,108,108,111,119,102,108,97,103,0,118,111,108,109,111,100,101,0,112,108,97,110,101,0, -111,114,103,108,101,110,103,116,104,0,98,117,108,103,101,0,112,105,118,88,0,112,105,118,89,0,112,105,118,90,0,97, -120,88,0,97,120,89,0,97,120,90,0,109,105,110,76,105,109,105,116,91,54,93,0,109,97,120,76,105,109,105,116,91, -54,93,0,101,120,116,114,97,70,122,0,105,110,118,109,97,116,91,52,93,91,52,93,0,102,114,111,109,0,116,111,0, -109,97,112,91,51,93,0,101,120,112,111,0,102,114,111,109,95,109,105,110,91,51,93,0,102,114,111,109,95,109,97,120, -91,51,93,0,116,111,95,109,105,110,91,51,93,0,116,111,95,109,97,120,91,51,93,0,122,109,105,110,0,122,109,97, -120,0,112,97,100,91,57,93,0,99,104,97,110,110,101,108,91,51,50,93,0,110,111,95,114,111,116,95,97,120,105,115, -0,115,116,114,105,100,101,95,97,120,105,115,0,99,117,114,109,111,100,0,97,99,116,115,116,97,114,116,0,97,99,116, -101,110,100,0,97,99,116,111,102,102,115,0,115,116,114,105,100,101,108,101,110,0,98,108,101,110,100,111,117,116,0,115, -116,114,105,100,101,99,104,97,110,110,101,108,91,51,50,93,0,111,102,102,115,95,98,111,110,101,91,51,50,93,0,104, -97,115,105,110,112,117,116,0,104,97,115,111,117,116,112,117,116,0,100,97,116,97,116,121,112,101,0,115,111,99,107,101, -116,116,121,112,101,0,42,110,101,119,95,115,111,99,107,0,110,115,0,108,105,109,105,116,0,115,116,97,99,107,95,105, -110,100,101,120,0,105,110,116,101,114,110,0,115,116,97,99,107,95,105,110,100,101,120,95,101,120,116,0,108,111,99,120, -0,108,111,99,121,0,111,119,110,95,105,110,100,101,120,0,116,111,95,105,110,100,101,120,0,42,116,111,115,111,99,107, -0,42,108,105,110,107,0,42,110,101,119,95,110,111,100,101,0,117,115,101,114,110,97,109,101,91,51,50,93,0,108,97, -115,116,121,0,111,117,116,112,117,116,115,0,42,115,116,111,114,97,103,101,0,109,105,110,105,119,105,100,116,104,0,99, -117,115,116,111,109,49,0,99,117,115,116,111,109,50,0,99,117,115,116,111,109,51,0,99,117,115,116,111,109,52,0,110, -101,101,100,95,101,120,101,99,0,101,120,101,99,0,116,111,116,114,0,98,117,116,114,0,112,114,118,114,0,42,116,121, -112,101,105,110,102,111,0,42,102,114,111,109,110,111,100,101,0,42,116,111,110,111,100,101,0,42,102,114,111,109,115,111, -99,107,0,110,111,100,101,115,0,108,105,110,107,115,0,42,115,116,97,99,107,0,42,116,104,114,101,97,100,115,116,97, -99,107,0,105,110,105,116,0,115,116,97,99,107,115,105,122,101,0,99,117,114,95,105,110,100,101,120,0,97,108,108,116, -121,112,101,115,0,42,111,119,110,116,121,112,101,0,42,115,101,108,105,110,0,42,115,101,108,111,117,116,0,40,42,116, -105,109,101,99,117,114,115,111,114,41,40,41,0,40,42,115,116,97,116,115,95,100,114,97,119,41,40,41,0,40,42,116, -101,115,116,95,98,114,101,97,107,41,40,41,0,99,121,99,108,105,99,0,109,111,118,105,101,0,115,97,109,112,108,101, -115,0,109,105,110,115,112,101,101,100,0,112,101,114,99,101,110,116,120,0,112,101,114,99,101,110,116,121,0,98,111,107, -101,104,0,99,117,114,118,101,100,0,105,109,97,103,101,95,105,110,95,119,105,100,116,104,0,105,109,97,103,101,95,105, -110,95,104,101,105,103,104,116,0,99,101,110,116,101,114,95,120,0,99,101,110,116,101,114,95,121,0,115,112,105,110,0, -105,116,101,114,0,119,114,97,112,0,115,105,103,109,97,95,99,111,108,111,114,0,115,105,103,109,97,95,115,112,97,99, -101,0,104,117,101,0,115,97,116,0,116,49,0,116,50,0,116,51,0,102,115,116,114,101,110,103,116,104,0,102,97,108, -112,104,97,0,107,101,121,91,52,93,0,120,49,0,120,50,0,121,49,0,121,50,0,99,111,108,110,97,109,101,91,51, -50,93,0,98,107,116,121,112,101,0,114,111,116,97,116,105,111,110,0,112,114,101,118,105,101,119,0,103,97,109,99,111, -0,110,111,95,122,98,117,102,0,102,115,116,111,112,0,109,97,120,98,108,117,114,0,98,116,104,114,101,115,104,0,42, -100,105,99,116,0,42,110,111,100,101,0,97,110,103,108,101,95,111,102,115,0,99,111,108,109,111,100,0,109,105,120,0, -116,104,114,101,115,104,111,108,100,0,102,97,100,101,0,109,0,99,0,106,105,116,0,112,114,111,106,0,102,105,116,0, -115,104,111,114,116,121,0,109,105,110,116,97,98,108,101,0,109,97,120,116,97,98,108,101,0,101,120,116,95,105,110,91, -50,93,0,101,120,116,95,111,117,116,91,50,93,0,42,99,117,114,118,101,0,42,116,97,98,108,101,0,42,112,114,101, -109,117,108,116,97,98,108,101,0,99,117,114,114,0,99,108,105,112,114,0,99,109,91,52,93,0,98,108,97,99,107,91, -51,93,0,119,104,105,116,101,91,51,93,0,98,119,109,117,108,91,51,93,0,115,97,109,112,108,101,91,51,93,0,111, -102,102,115,101,116,91,50,93,0,105,110,110,101,114,114,97,100,105,117,115,0,114,97,116,101,0,114,103,98,91,51,93, -0,99,108,111,110,101,0,97,99,116,105,118,101,95,114,110,100,0,97,99,116,105,118,101,95,99,108,111,110,101,0,97, -99,116,105,118,101,95,109,97,115,107,0,42,108,97,121,101,114,115,0,116,111,116,108,97,121,101,114,0,109,97,120,108, -97,121,101,114,0,116,111,116,115,105,122,101,0,42,112,111,111,108,0,101,100,105,116,102,108,97,103,0,118,101,108,91, -51,93,0,114,111,116,91,52,93,0,97,118,101,91,51,93,0,110,117,109,0,112,97,114,101,110,116,0,112,97,91,52, -93,0,119,91,52,93,0,102,117,118,91,52,93,0,102,111,102,102,115,101,116,0,114,97,110,100,91,51,93,0,42,115, -116,105,99,107,95,111,98,0,112,114,101,118,95,115,116,97,116,101,0,42,104,97,105,114,0,105,95,114,111,116,91,52, -93,0,114,95,114,111,116,91,52,93,0,114,95,97,118,101,91,51,93,0,114,95,118,101,91,51,93,0,100,105,101,116, -105,109,101,0,98,97,110,107,0,115,105,122,101,109,117,108,0,110,117,109,95,100,109,99,97,99,104,101,0,98,112,105, -0,97,108,105,118,101,0,108,111,111,112,0,100,105,115,116,114,0,112,104,121,115,116,121,112,101,0,114,111,116,109,111, -100,101,0,97,118,101,109,111,100,101,0,114,101,97,99,116,101,118,101,110,116,0,100,114,97,119,0,100,114,97,119,95, -97,115,0,100,114,97,119,95,115,105,122,101,0,99,104,105,108,100,116,121,112,101,0,100,114,97,119,95,115,116,101,112, -0,114,101,110,95,115,116,101,112,0,104,97,105,114,95,115,116,101,112,0,107,101,121,115,95,115,116,101,112,0,97,100, -97,112,116,95,97,110,103,108,101,0,97,100,97,112,116,95,112,105,120,0,114,111,116,102,114,111,109,0,105,110,116,101, -103,114,97,116,111,114,0,110,98,101,116,119,101,101,110,0,98,111,105,100,110,101,105,103,104,98,111,117,114,115,0,98, -98,95,97,108,105,103,110,0,98,98,95,117,118,95,115,112,108,105,116,0,98,98,95,97,110,105,109,0,98,98,95,115, -112,108,105,116,95,111,102,102,115,101,116,0,98,98,95,116,105,108,116,0,98,98,95,114,97,110,100,95,116,105,108,116, -0,98,98,95,111,102,102,115,101,116,91,50,93,0,115,105,109,112,108,105,102,121,95,102,108,97,103,0,115,105,109,112, -108,105,102,121,95,114,101,102,115,105,122,101,0,115,105,109,112,108,105,102,121,95,114,97,116,101,0,115,105,109,112,108, -105,102,121,95,116,114,97,110,115,105,116,105,111,110,0,115,105,109,112,108,105,102,121,95,118,105,101,119,112,111,114,116, -0,116,105,109,101,116,119,101,97,107,0,106,105,116,102,97,99,0,107,101,121,101,100,95,116,105,109,101,0,101,102,102, -95,104,97,105,114,0,103,114,105,100,95,114,101,115,0,112,97,114,116,102,97,99,0,116,97,110,102,97,99,0,116,97, -110,112,104,97,115,101,0,114,101,97,99,116,102,97,99,0,97,118,101,102,97,99,0,112,104,97,115,101,102,97,99,0, -114,97,110,100,114,111,116,102,97,99,0,114,97,110,100,112,104,97,115,101,102,97,99,0,114,97,110,100,115,105,122,101, -0,114,101,97,99,116,115,104,97,112,101,0,97,99,99,91,51,93,0,100,114,97,103,102,97,99,0,98,114,111,119,110, -102,97,99,0,100,97,109,112,102,97,99,0,97,98,115,108,101,110,103,116,104,0,114,97,110,100,108,101,110,103,116,104, -0,99,104,105,108,100,95,110,98,114,0,114,101,110,95,99,104,105,108,100,95,110,98,114,0,112,97,114,101,110,116,115, -0,99,104,105,108,100,115,105,122,101,0,99,104,105,108,100,114,97,110,100,115,105,122,101,0,99,104,105,108,100,114,97, -100,0,99,104,105,108,100,102,108,97,116,0,99,104,105,108,100,115,112,114,101,97,100,0,99,108,117,109,112,102,97,99, -0,99,108,117,109,112,112,111,119,0,114,111,117,103,104,49,0,114,111,117,103,104,49,95,115,105,122,101,0,114,111,117, -103,104,50,0,114,111,117,103,104,50,95,115,105,122,101,0,114,111,117,103,104,50,95,116,104,114,101,115,0,114,111,117, -103,104,95,101,110,100,0,114,111,117,103,104,95,101,110,100,95,115,104,97,112,101,0,98,114,97,110,99,104,95,116,104, -114,101,115,0,100,114,97,119,95,108,105,110,101,91,50,93,0,109,97,120,95,108,97,116,95,97,99,99,0,109,97,120, -95,116,97,110,95,97,99,99,0,97,118,101,114,97,103,101,95,118,101,108,0,98,97,110,107,105,110,103,0,109,97,120, -95,98,97,110,107,0,103,114,111,117,110,100,122,0,98,111,105,100,102,97,99,91,56,93,0,98,111,105,100,114,117,108, -101,91,56,93,0,42,101,102,102,95,103,114,111,117,112,0,42,100,117,112,95,111,98,0,42,98,98,95,111,98,0,42, -112,100,50,0,42,112,97,114,116,0,42,101,100,105,116,0,42,42,112,97,116,104,99,97,99,104,101,0,42,42,99,104, -105,108,100,99,97,99,104,101,0,112,97,116,104,99,97,99,104,101,98,117,102,115,0,99,104,105,108,100,99,97,99,104, -101,98,117,102,115,0,42,116,97,114,103,101,116,95,111,98,0,42,107,101,121,101,100,95,111,98,0,42,108,97,116,116, -105,99,101,0,101,102,102,101,99,116,111,114,115,0,114,101,97,99,116,101,118,101,110,116,115,0,116,111,116,99,104,105, -108,100,0,116,111,116,99,97,99,104,101,100,0,116,111,116,99,104,105,108,100,99,97,99,104,101,0,116,97,114,103,101, -116,95,112,115,121,115,0,107,101,121,101,100,95,112,115,121,115,0,116,111,116,107,101,121,101,100,0,98,97,107,101,115, -112,97,99,101,0,98,98,95,117,118,110,97,109,101,91,51,93,91,51,50,93,0,118,103,114,111,117,112,91,49,50,93, -0,118,103,95,110,101,103,0,114,116,51,0,42,114,101,110,100,101,114,100,97,116,97,0,42,99,97,99,104,101,0,67, -100,105,115,0,67,118,105,0,91,51,93,0,115,116,114,117,99,116,117,114,97,108,0,98,101,110,100,105,110,103,0,109, -97,120,95,98,101,110,100,0,109,97,120,95,115,116,114,117,99,116,0,109,97,120,95,115,104,101,97,114,0,97,118,103, -95,115,112,114,105,110,103,95,108,101,110,0,116,105,109,101,115,99,97,108,101,0,101,102,102,95,102,111,114,99,101,95, -115,99,97,108,101,0,101,102,102,95,119,105,110,100,95,115,99,97,108,101,0,115,105,109,95,116,105,109,101,95,111,108, -100,0,115,116,101,112,115,80,101,114,70,114,97,109,101,0,112,114,101,114,111,108,108,0,109,97,120,115,112,114,105,110, -103,108,101,110,0,115,111,108,118,101,114,95,116,121,112,101,0,118,103,114,111,117,112,95,98,101,110,100,0,118,103,114, -111,117,112,95,109,97,115,115,0,118,103,114,111,117,112,95,115,116,114,117,99,116,0,112,114,101,115,101,116,115,0,42, -99,111,108,108,105,115,105,111,110,95,108,105,115,116,0,101,112,115,105,108,111,110,0,115,101,108,102,95,102,114,105,99, -116,105,111,110,0,115,101,108,102,101,112,115,105,108,111,110,0,115,101,108,102,95,108,111,111,112,95,99,111,117,110,116, -0,108,111,111,112,95,99,111,117,110,116,0,112,114,101,115,115,117,114,101,0,42,112,111,105,110,116,115,0,116,111,116, -112,111,105,110,116,115,0,116,104,105,99,107,110,101,115,115,0,115,116,114,111,107,101,115,0,102,114,97,109,101,110,117, -109,0,42,97,99,116,102,114,97,109,101,0,103,115,116,101,112,0,105,110,102,111,91,49,50,56,93,0,115,98,117,102, -102,101,114,95,115,105,122,101,0,115,98,117,102,102,101,114,95,115,102,108,97,103,0,42,115,98,117,102,102,101,114,0, -0,0,0,84,89,80,69,100,1,0,0,99,104,97,114,0,117,99,104,97,114,0,115,104,111,114,116,0,117,115,104,111, -114,116,0,105,110,116,0,108,111,110,103,0,117,108,111,110,103,0,102,108,111,97,116,0,100,111,117,98,108,101,0,118, -111,105,100,0,76,105,110,107,0,76,105,110,107,68,97,116,97,0,76,105,115,116,66,97,115,101,0,118,101,99,50,115, -0,118,101,99,50,105,0,118,101,99,50,102,0,118,101,99,50,100,0,118,101,99,51,105,0,118,101,99,51,102,0,118, -101,99,51,100,0,118,101,99,52,105,0,118,101,99,52,102,0,118,101,99,52,100,0,114,99,116,105,0,114,99,116,102, -0,73,68,80,114,111,112,101,114,116,121,68,97,116,97,0,73,68,80,114,111,112,101,114,116,121,0,73,68,0,76,105, -98,114,97,114,121,0,70,105,108,101,68,97,116,97,0,80,114,101,118,105,101,119,73,109,97,103,101,0,73,112,111,68, -114,105,118,101,114,0,79,98,106,101,99,116,0,73,112,111,67,117,114,118,101,0,66,80,111,105,110,116,0,66,101,122, -84,114,105,112,108,101,0,73,112,111,0,75,101,121,66,108,111,99,107,0,75,101,121,0,83,99,114,105,112,116,76,105, -110,107,0,84,101,120,116,76,105,110,101,0,84,101,120,116,77,97,114,107,101,114,0,84,101,120,116,0,80,97,99,107, -101,100,70,105,108,101,0,67,97,109,101,114,97,0,73,109,97,103,101,85,115,101,114,0,73,109,97,103,101,0,71,80, -85,84,101,120,116,117,114,101,0,97,110,105,109,0,82,101,110,100,101,114,82,101,115,117,108,116,0,77,84,101,120,0, -84,101,120,0,80,108,117,103,105,110,84,101,120,0,67,66,68,97,116,97,0,67,111,108,111,114,66,97,110,100,0,69, -110,118,77,97,112,0,73,109,66,117,102,0,98,78,111,100,101,84,114,101,101,0,84,101,120,77,97,112,112,105,110,103, -0,76,97,109,112,0,67,117,114,118,101,77,97,112,112,105,110,103,0,87,97,118,101,0,77,97,116,101,114,105,97,108, -0,71,114,111,117,112,0,86,70,111,110,116,0,86,70,111,110,116,68,97,116,97,0,77,101,116,97,69,108,101,109,0, -66,111,117,110,100,66,111,120,0,77,101,116,97,66,97,108,108,0,78,117,114,98,0,67,104,97,114,73,110,102,111,0, -84,101,120,116,66,111,120,0,67,117,114,118,101,0,80,97,116,104,0,77,101,115,104,0,77,70,97,99,101,0,77,84, -70,97,99,101,0,84,70,97,99,101,0,77,86,101,114,116,0,77,69,100,103,101,0,77,68,101,102,111,114,109,86,101, -114,116,0,77,67,111,108,0,77,83,116,105,99,107,121,0,77,83,101,108,101,99,116,0,67,117,115,116,111,109,68,97, -116,97,0,77,117,108,116,105,114,101,115,0,80,97,114,116,105,97,108,86,105,115,105,98,105,108,105,116,121,0,77,68, -101,102,111,114,109,87,101,105,103,104,116,0,77,84,101,120,80,111,108,121,0,77,76,111,111,112,85,86,0,77,76,111, -111,112,67,111,108,0,77,70,108,111,97,116,80,114,111,112,101,114,116,121,0,77,73,110,116,80,114,111,112,101,114,116, -121,0,77,83,116,114,105,110,103,80,114,111,112,101,114,116,121,0,79,114,105,103,83,112,97,99,101,70,97,99,101,0, -77,117,108,116,105,114,101,115,67,111,108,0,77,117,108,116,105,114,101,115,67,111,108,70,97,99,101,0,77,117,108,116, -105,114,101,115,70,97,99,101,0,77,117,108,116,105,114,101,115,69,100,103,101,0,77,117,108,116,105,114,101,115,76,101, -118,101,108,0,77,117,108,116,105,114,101,115,77,97,112,78,111,100,101,0,77,111,100,105,102,105,101,114,68,97,116,97, -0,83,117,98,115,117,114,102,77,111,100,105,102,105,101,114,68,97,116,97,0,76,97,116,116,105,99,101,77,111,100,105, -102,105,101,114,68,97,116,97,0,67,117,114,118,101,77,111,100,105,102,105,101,114,68,97,116,97,0,66,117,105,108,100, -77,111,100,105,102,105,101,114,68,97,116,97,0,77,97,115,107,77,111,100,105,102,105,101,114,68,97,116,97,0,65,114, -114,97,121,77,111,100,105,102,105,101,114,68,97,116,97,0,77,105,114,114,111,114,77,111,100,105,102,105,101,114,68,97, -116,97,0,69,100,103,101,83,112,108,105,116,77,111,100,105,102,105,101,114,68,97,116,97,0,66,101,118,101,108,77,111, -100,105,102,105,101,114,68,97,116,97,0,66,77,101,115,104,77,111,100,105,102,105,101,114,68,97,116,97,0,68,105,115, -112,108,97,99,101,77,111,100,105,102,105,101,114,68,97,116,97,0,85,86,80,114,111,106,101,99,116,77,111,100,105,102, -105,101,114,68,97,116,97,0,68,101,99,105,109,97,116,101,77,111,100,105,102,105,101,114,68,97,116,97,0,83,109,111, -111,116,104,77,111,100,105,102,105,101,114,68,97,116,97,0,67,97,115,116,77,111,100,105,102,105,101,114,68,97,116,97, -0,87,97,118,101,77,111,100,105,102,105,101,114,68,97,116,97,0,65,114,109,97,116,117,114,101,77,111,100,105,102,105, -101,114,68,97,116,97,0,72,111,111,107,77,111,100,105,102,105,101,114,68,97,116,97,0,83,111,102,116,98,111,100,121, -77,111,100,105,102,105,101,114,68,97,116,97,0,67,108,111,116,104,77,111,100,105,102,105,101,114,68,97,116,97,0,67, -108,111,116,104,0,67,108,111,116,104,83,105,109,83,101,116,116,105,110,103,115,0,67,108,111,116,104,67,111,108,108,83, -101,116,116,105,110,103,115,0,80,111,105,110,116,67,97,99,104,101,0,67,111,108,108,105,115,105,111,110,77,111,100,105, -102,105,101,114,68,97,116,97,0,66,86,72,84,114,101,101,0,83,117,114,102,97,99,101,77,111,100,105,102,105,101,114, -68,97,116,97,0,68,101,114,105,118,101,100,77,101,115,104,0,66,86,72,84,114,101,101,70,114,111,109,77,101,115,104, -0,66,111,111,108,101,97,110,77,111,100,105,102,105,101,114,68,97,116,97,0,77,68,101,102,73,110,102,108,117,101,110, -99,101,0,77,68,101,102,67,101,108,108,0,77,101,115,104,68,101,102,111,114,109,77,111,100,105,102,105,101,114,68,97, -116,97,0,80,97,114,116,105,99,108,101,83,121,115,116,101,109,77,111,100,105,102,105,101,114,68,97,116,97,0,80,97, -114,116,105,99,108,101,83,121,115,116,101,109,0,80,97,114,116,105,99,108,101,73,110,115,116,97,110,99,101,77,111,100, -105,102,105,101,114,68,97,116,97,0,69,120,112,108,111,100,101,77,111,100,105,102,105,101,114,68,97,116,97,0,70,108, -117,105,100,115,105,109,77,111,100,105,102,105,101,114,68,97,116,97,0,70,108,117,105,100,115,105,109,83,101,116,116,105, -110,103,115,0,83,104,114,105,110,107,119,114,97,112,77,111,100,105,102,105,101,114,68,97,116,97,0,83,105,109,112,108, -101,68,101,102,111,114,109,77,111,100,105,102,105,101,114,68,97,116,97,0,76,97,116,116,105,99,101,0,98,68,101,102, -111,114,109,71,114,111,117,112,0,98,65,99,116,105,111,110,0,98,80,111,115,101,0,66,117,108,108,101,116,83,111,102, -116,66,111,100,121,0,80,97,114,116,68,101,102,108,101,99,116,0,83,111,102,116,66,111,100,121,0,79,98,72,111,111, -107,0,82,78,71,0,83,66,86,101,114,116,101,120,0,66,111,100,121,80,111,105,110,116,0,66,111,100,121,83,112,114, -105,110,103,0,83,66,83,99,114,97,116,99,104,0,87,111,114,108,100,0,82,97,100,105,111,0,66,97,115,101,0,65, -118,105,67,111,100,101,99,68,97,116,97,0,81,117,105,99,107,116,105,109,101,67,111,100,101,99,68,97,116,97,0,70, -70,77,112,101,103,67,111,100,101,99,68,97,116,97,0,65,117,100,105,111,68,97,116,97,0,83,99,101,110,101,82,101, -110,100,101,114,76,97,121,101,114,0,82,101,110,100,101,114,68,97,116,97,0,82,101,110,100,101,114,80,114,111,102,105, -108,101,0,71,97,109,101,70,114,97,109,105,110,103,0,84,105,109,101,77,97,114,107,101,114,0,73,109,97,103,101,80, -97,105,110,116,83,101,116,116,105,110,103,115,0,66,114,117,115,104,0,80,97,114,116,105,99,108,101,66,114,117,115,104, -68,97,116,97,0,80,97,114,116,105,99,108,101,69,100,105,116,83,101,116,116,105,110,103,115,0,84,114,97,110,115,102, -111,114,109,79,114,105,101,110,116,97,116,105,111,110,0,84,111,111,108,83,101,116,116,105,110,103,115,0,66,114,117,115, -104,68,97,116,97,0,83,99,117,108,112,116,68,97,116,97,0,83,99,117,108,112,116,83,101,115,115,105,111,110,0,83, -99,101,110,101,0,68,97,103,70,111,114,101,115,116,0,66,71,112,105,99,0,86,105,101,119,51,68,0,83,112,97,99, -101,76,105,110,107,0,83,99,114,65,114,101,97,0,82,101,110,100,101,114,73,110,102,111,0,82,101,116,111,112,111,86, -105,101,119,68,97,116,97,0,86,105,101,119,68,101,112,116,104,115,0,98,71,80,100,97,116,97,0,86,105,101,119,50, -68,0,83,112,97,99,101,73,110,102,111,0,83,112,97,99,101,73,112,111,0,83,112,97,99,101,66,117,116,115,0,83, -112,97,99,101,83,101,113,0,83,112,97,99,101,70,105,108,101,0,100,105,114,101,110,116,114,121,0,66,108,101,110,100, -72,97,110,100,108,101,0,83,112,97,99,101,79,111,112,115,0,84,114,101,101,83,116,111,114,101,0,84,114,101,101,83, -116,111,114,101,69,108,101,109,0,83,112,97,99,101,73,109,97,103,101,0,83,112,97,99,101,78,108,97,0,83,112,97, -99,101,84,101,120,116,0,83,99,114,105,112,116,0,83,112,97,99,101,83,99,114,105,112,116,0,83,112,97,99,101,84, -105,109,101,0,83,112,97,99,101,78,111,100,101,0,83,112,97,99,101,73,109,97,83,101,108,0,70,105,108,101,76,105, -115,116,0,84,104,101,109,101,85,73,0,84,104,101,109,101,83,112,97,99,101,0,84,104,101,109,101,87,105,114,101,67, -111,108,111,114,0,98,84,104,101,109,101,0,83,111,108,105,100,76,105,103,104,116,0,85,115,101,114,68,101,102,0,98, -83,99,114,101,101,110,0,83,99,114,86,101,114,116,0,83,99,114,69,100,103,101,0,80,97,110,101,108,0,70,105,108, -101,71,108,111,98,97,108,0,83,116,114,105,112,69,108,101,109,0,84,83,116,114,105,112,69,108,101,109,0,83,116,114, -105,112,67,114,111,112,0,83,116,114,105,112,84,114,97,110,115,102,111,114,109,0,83,116,114,105,112,67,111,108,111,114, -66,97,108,97,110,99,101,0,83,116,114,105,112,67,111,108,111,114,66,97,108,97,110,99,101,71,85,73,72,101,108,112, -101,114,0,83,116,114,105,112,80,114,111,120,121,0,83,116,114,105,112,0,80,108,117,103,105,110,83,101,113,0,83,101, -113,117,101,110,99,101,0,98,83,111,117,110,100,0,104,100,97,117,100,105,111,0,77,101,116,97,83,116,97,99,107,0, -69,100,105,116,105,110,103,0,87,105,112,101,86,97,114,115,0,71,108,111,119,86,97,114,115,0,84,114,97,110,115,102, -111,114,109,86,97,114,115,0,83,111,108,105,100,67,111,108,111,114,86,97,114,115,0,83,112,101,101,100,67,111,110,116, -114,111,108,86,97,114,115,0,69,102,102,101,99,116,0,66,117,105,108,100,69,102,102,0,80,97,114,116,69,102,102,0, -80,97,114,116,105,99,108,101,0,87,97,118,101,69,102,102,0,79,111,112,115,0,98,80,114,111,112,101,114,116,121,0, -98,78,101,97,114,83,101,110,115,111,114,0,98,77,111,117,115,101,83,101,110,115,111,114,0,98,84,111,117,99,104,83, -101,110,115,111,114,0,98,75,101,121,98,111,97,114,100,83,101,110,115,111,114,0,98,80,114,111,112,101,114,116,121,83, -101,110,115,111,114,0,98,65,99,116,117,97,116,111,114,83,101,110,115,111,114,0,98,68,101,108,97,121,83,101,110,115, -111,114,0,98,67,111,108,108,105,115,105,111,110,83,101,110,115,111,114,0,98,82,97,100,97,114,83,101,110,115,111,114, -0,98,82,97,110,100,111,109,83,101,110,115,111,114,0,98,82,97,121,83,101,110,115,111,114,0,98,77,101,115,115,97, -103,101,83,101,110,115,111,114,0,98,83,101,110,115,111,114,0,98,67,111,110,116,114,111,108,108,101,114,0,98,74,111, -121,115,116,105,99,107,83,101,110,115,111,114,0,98,69,120,112,114,101,115,115,105,111,110,67,111,110,116,0,98,80,121, -116,104,111,110,67,111,110,116,0,98,65,99,116,117,97,116,111,114,0,98,65,100,100,79,98,106,101,99,116,65,99,116, -117,97,116,111,114,0,98,65,99,116,105,111,110,65,99,116,117,97,116,111,114,0,98,83,111,117,110,100,65,99,116,117, -97,116,111,114,0,98,67,68,65,99,116,117,97,116,111,114,0,98,69,100,105,116,79,98,106,101,99,116,65,99,116,117, -97,116,111,114,0,98,83,99,101,110,101,65,99,116,117,97,116,111,114,0,98,80,114,111,112,101,114,116,121,65,99,116, -117,97,116,111,114,0,98,79,98,106,101,99,116,65,99,116,117,97,116,111,114,0,98,73,112,111,65,99,116,117,97,116, -111,114,0,98,67,97,109,101,114,97,65,99,116,117,97,116,111,114,0,98,67,111,110,115,116,114,97,105,110,116,65,99, -116,117,97,116,111,114,0,98,71,114,111,117,112,65,99,116,117,97,116,111,114,0,98,82,97,110,100,111,109,65,99,116, -117,97,116,111,114,0,98,77,101,115,115,97,103,101,65,99,116,117,97,116,111,114,0,98,71,97,109,101,65,99,116,117, -97,116,111,114,0,98,86,105,115,105,98,105,108,105,116,121,65,99,116,117,97,116,111,114,0,98,84,119,111,68,70,105, -108,116,101,114,65,99,116,117,97,116,111,114,0,98,80,97,114,101,110,116,65,99,116,117,97,116,111,114,0,98,83,116, -97,116,101,65,99,116,117,97,116,111,114,0,70,114,101,101,67,97,109,101,114,97,0,98,83,97,109,112,108,101,0,98, -83,111,117,110,100,76,105,115,116,101,110,101,114,0,83,112,97,99,101,83,111,117,110,100,0,71,114,111,117,112,79,98, -106,101,99,116,0,66,111,110,101,0,98,65,114,109,97,116,117,114,101,0,98,80,111,115,101,67,104,97,110,110,101,108, -0,98,65,99,116,105,111,110,71,114,111,117,112,0,98,65,99,116,105,111,110,67,104,97,110,110,101,108,0,83,112,97, -99,101,65,99,116,105,111,110,0,98,67,111,110,115,116,114,97,105,110,116,67,104,97,110,110,101,108,0,98,67,111,110, -115,116,114,97,105,110,116,0,98,67,111,110,115,116,114,97,105,110,116,84,97,114,103,101,116,0,98,80,121,116,104,111, -110,67,111,110,115,116,114,97,105,110,116,0,98,75,105,110,101,109,97,116,105,99,67,111,110,115,116,114,97,105,110,116, -0,98,84,114,97,99,107,84,111,67,111,110,115,116,114,97,105,110,116,0,98,82,111,116,97,116,101,76,105,107,101,67, -111,110,115,116,114,97,105,110,116,0,98,76,111,99,97,116,101,76,105,107,101,67,111,110,115,116,114,97,105,110,116,0, -98,77,105,110,77,97,120,67,111,110,115,116,114,97,105,110,116,0,98,83,105,122,101,76,105,107,101,67,111,110,115,116, -114,97,105,110,116,0,98,65,99,116,105,111,110,67,111,110,115,116,114,97,105,110,116,0,98,76,111,99,107,84,114,97, -99,107,67,111,110,115,116,114,97,105,110,116,0,98,70,111,108,108,111,119,80,97,116,104,67,111,110,115,116,114,97,105, -110,116,0,98,83,116,114,101,116,99,104,84,111,67,111,110,115,116,114,97,105,110,116,0,98,82,105,103,105,100,66,111, -100,121,74,111,105,110,116,67,111,110,115,116,114,97,105,110,116,0,98,67,108,97,109,112,84,111,67,111,110,115,116,114, -97,105,110,116,0,98,67,104,105,108,100,79,102,67,111,110,115,116,114,97,105,110,116,0,98,84,114,97,110,115,102,111, -114,109,67,111,110,115,116,114,97,105,110,116,0,98,76,111,99,76,105,109,105,116,67,111,110,115,116,114,97,105,110,116, -0,98,82,111,116,76,105,109,105,116,67,111,110,115,116,114,97,105,110,116,0,98,83,105,122,101,76,105,109,105,116,67, -111,110,115,116,114,97,105,110,116,0,98,68,105,115,116,76,105,109,105,116,67,111,110,115,116,114,97,105,110,116,0,98, -83,104,114,105,110,107,119,114,97,112,67,111,110,115,116,114,97,105,110,116,0,98,65,99,116,105,111,110,77,111,100,105, -102,105,101,114,0,98,65,99,116,105,111,110,83,116,114,105,112,0,98,78,111,100,101,83,116,97,99,107,0,98,78,111, -100,101,83,111,99,107,101,116,0,98,78,111,100,101,76,105,110,107,0,98,78,111,100,101,0,98,78,111,100,101,80,114, -101,118,105,101,119,0,98,78,111,100,101,84,121,112,101,0,78,111,100,101,73,109,97,103,101,65,110,105,109,0,78,111, -100,101,66,108,117,114,68,97,116,97,0,78,111,100,101,68,66,108,117,114,68,97,116,97,0,78,111,100,101,66,105,108, -97,116,101,114,97,108,66,108,117,114,68,97,116,97,0,78,111,100,101,72,117,101,83,97,116,0,78,111,100,101,73,109, -97,103,101,70,105,108,101,0,78,111,100,101,67,104,114,111,109,97,0,78,111,100,101,84,119,111,88,89,115,0,78,111, -100,101,84,119,111,70,108,111,97,116,115,0,78,111,100,101,71,101,111,109,101,116,114,121,0,78,111,100,101,86,101,114, -116,101,120,67,111,108,0,78,111,100,101,68,101,102,111,99,117,115,0,78,111,100,101,83,99,114,105,112,116,68,105,99, -116,0,78,111,100,101,71,108,97,114,101,0,78,111,100,101,84,111,110,101,109,97,112,0,78,111,100,101,76,101,110,115, -68,105,115,116,0,84,101,120,78,111,100,101,79,117,116,112,117,116,0,67,117,114,118,101,77,97,112,80,111,105,110,116, -0,67,117,114,118,101,77,97,112,0,66,114,117,115,104,67,108,111,110,101,0,67,117,115,116,111,109,68,97,116,97,76, -97,121,101,114,0,72,97,105,114,75,101,121,0,80,97,114,116,105,99,108,101,75,101,121,0,67,104,105,108,100,80,97, -114,116,105,99,108,101,0,80,97,114,116,105,99,108,101,68,97,116,97,0,80,97,114,116,105,99,108,101,83,101,116,116, -105,110,103,115,0,80,97,114,116,105,99,108,101,69,100,105,116,0,80,97,114,116,105,99,108,101,67,97,99,104,101,75, -101,121,0,76,105,110,107,78,111,100,101,0,98,71,80,68,115,112,111,105,110,116,0,98,71,80,68,115,116,114,111,107, -101,0,98,71,80,68,102,114,97,109,101,0,98,71,80,68,108,97,121,101,114,0,0,84,76,69,78,1,0,1,0,2, -0,2,0,4,0,4,0,4,0,4,0,8,0,0,0,8,0,12,0,8,0,4,0,8,0,8,0,16,0,12,0,12, -0,24,0,16,0,16,0,32,0,16,0,16,0,20,0,76,0,52,0,40,2,0,0,32,0,-116,0,80,3,92,0,36, -0,56,0,84,0,112,0,120,0,16,0,24,0,40,0,120,0,20,0,-124,0,32,0,-128,1,0,0,0,0,0,0,-120, -0,16,1,84,1,24,0,8,3,-88,0,0,0,124,0,-124,0,-128,1,8,1,56,0,108,2,76,0,68,1,0,0,108, -0,104,0,-120,0,56,0,8,0,16,0,56,1,0,0,24,1,20,0,44,0,60,0,24,0,12,0,12,0,4,0,8, -0,8,0,24,0,76,0,32,0,8,0,12,0,8,0,8,0,4,0,4,0,0,1,32,0,16,0,64,0,24,0,12, -0,56,0,0,0,52,0,68,0,88,0,96,0,68,0,96,0,116,0,64,0,60,0,108,0,60,0,-108,0,-104,0,60, -0,92,0,104,0,-72,0,100,0,-76,0,52,0,68,0,0,0,-124,0,28,0,20,0,100,0,0,0,60,0,0,0,0, -0,64,0,8,0,8,0,-40,0,76,0,64,1,64,0,64,0,60,0,-92,1,108,0,104,0,116,0,40,0,84,0,56, -0,120,0,-128,0,-8,0,-48,0,0,0,16,0,0,0,0,0,0,0,108,1,40,0,28,0,-80,0,-112,0,52,0,16, -0,72,0,-48,3,56,0,16,0,80,0,12,0,-72,0,8,0,72,0,80,0,-24,0,8,0,-88,0,0,0,124,5,0, -0,60,0,28,3,36,0,-52,0,0,0,0,0,0,0,20,0,-120,0,36,0,88,1,-36,0,-56,0,-56,1,0,0,0, -0,8,1,12,0,12,0,8,1,-76,0,-128,0,80,2,36,0,-92,0,-36,0,-124,2,0,0,-104,0,-48,0,16,0,56, -14,56,0,32,12,120,0,20,0,24,0,-28,0,32,0,80,0,28,0,16,0,8,0,60,0,0,0,-4,0,-16,0,-88, -1,-60,0,28,1,0,0,16,0,28,0,12,0,24,0,48,0,16,0,28,0,16,0,24,0,56,1,0,0,56,0,44, -0,64,0,48,0,8,0,44,0,72,0,104,0,40,0,8,0,72,0,44,0,40,0,108,0,68,0,76,0,80,0,60, -0,-128,0,76,0,60,0,12,0,92,0,28,0,20,0,80,0,16,0,76,0,108,0,84,0,28,0,96,0,60,0,56, -0,108,0,-116,0,4,0,20,0,12,0,8,0,40,0,0,0,68,0,-80,0,24,0,4,1,116,0,-104,1,72,0,64, -0,-64,0,44,0,64,0,116,0,60,0,104,0,52,0,44,0,44,0,68,0,44,0,64,0,44,0,20,0,52,0,96, -0,12,0,108,0,92,0,28,0,28,0,28,0,52,0,20,0,60,0,-116,0,36,0,120,0,24,0,-52,0,0,0,0, -0,16,0,40,0,28,0,12,0,12,0,16,1,40,0,8,0,8,0,64,0,32,0,24,0,8,0,24,0,32,0,8, -0,32,0,12,0,44,0,20,0,68,0,24,0,56,0,72,0,-4,0,-32,1,0,0,0,0,0,0,16,0,20,0,24, -0,-84,0,83,84,82,67,57,1,0,0,10,0,2,0,10,0,0,0,10,0,1,0,11,0,3,0,11,0,0,0,11, -0,1,0,9,0,2,0,12,0,2,0,9,0,3,0,9,0,4,0,13,0,2,0,2,0,5,0,2,0,6,0,14, -0,2,0,4,0,5,0,4,0,6,0,15,0,2,0,7,0,5,0,7,0,6,0,16,0,2,0,8,0,5,0,8, -0,6,0,17,0,3,0,4,0,5,0,4,0,6,0,4,0,7,0,18,0,3,0,7,0,5,0,7,0,6,0,7, -0,7,0,19,0,3,0,8,0,5,0,8,0,6,0,8,0,7,0,20,0,4,0,4,0,5,0,4,0,6,0,4, -0,7,0,4,0,8,0,21,0,4,0,7,0,5,0,7,0,6,0,7,0,7,0,7,0,8,0,22,0,4,0,8, -0,5,0,8,0,6,0,8,0,7,0,8,0,8,0,23,0,4,0,4,0,9,0,4,0,10,0,4,0,11,0,4, -0,12,0,24,0,4,0,7,0,9,0,7,0,10,0,7,0,11,0,7,0,12,0,25,0,4,0,9,0,13,0,12, -0,14,0,4,0,15,0,4,0,16,0,26,0,10,0,26,0,0,0,26,0,1,0,0,0,17,0,0,0,18,0,0, -0,19,0,2,0,20,0,4,0,21,0,25,0,22,0,4,0,23,0,4,0,24,0,27,0,9,0,9,0,0,0,9, -0,1,0,27,0,25,0,28,0,26,0,0,0,27,0,2,0,28,0,2,0,20,0,4,0,29,0,26,0,30,0,28, -0,8,0,27,0,31,0,27,0,32,0,29,0,33,0,0,0,34,0,0,0,35,0,4,0,36,0,4,0,37,0,28, -0,38,0,30,0,6,0,4,0,39,0,4,0,40,0,2,0,41,0,2,0,42,0,2,0,43,0,4,0,44,0,31, -0,6,0,32,0,45,0,2,0,46,0,2,0,47,0,2,0,18,0,2,0,20,0,0,0,48,0,33,0,21,0,33, -0,0,0,33,0,1,0,34,0,49,0,35,0,50,0,24,0,51,0,24,0,52,0,2,0,46,0,2,0,47,0,2, -0,53,0,2,0,54,0,2,0,55,0,2,0,56,0,2,0,20,0,2,0,57,0,7,0,11,0,7,0,12,0,4, -0,58,0,7,0,59,0,7,0,60,0,7,0,61,0,31,0,62,0,36,0,7,0,27,0,31,0,12,0,63,0,24, -0,64,0,2,0,46,0,2,0,65,0,2,0,66,0,2,0,37,0,37,0,16,0,37,0,0,0,37,0,1,0,7, -0,67,0,7,0,61,0,2,0,18,0,2,0,47,0,2,0,68,0,2,0,20,0,4,0,69,0,4,0,70,0,9, -0,2,0,7,0,71,0,0,0,17,0,0,0,72,0,7,0,73,0,7,0,74,0,38,0,12,0,27,0,31,0,37, -0,75,0,0,0,76,0,4,0,77,0,7,0,61,0,12,0,78,0,36,0,79,0,27,0,80,0,2,0,18,0,2, -0,81,0,2,0,82,0,2,0,20,0,39,0,5,0,27,0,83,0,2,0,84,0,2,0,85,0,2,0,86,0,4, -0,37,0,40,0,6,0,40,0,0,0,40,0,1,0,0,0,87,0,0,0,88,0,4,0,23,0,4,0,89,0,41, -0,10,0,41,0,0,0,41,0,1,0,4,0,90,0,4,0,91,0,4,0,92,0,4,0,43,0,4,0,14,0,4, -0,93,0,0,0,94,0,0,0,95,0,42,0,15,0,27,0,31,0,0,0,96,0,4,0,93,0,4,0,97,0,12, -0,98,0,40,0,99,0,40,0,100,0,4,0,101,0,4,0,102,0,12,0,103,0,0,0,104,0,4,0,105,0,4, -0,106,0,9,0,107,0,8,0,108,0,43,0,5,0,4,0,109,0,4,0,110,0,4,0,93,0,4,0,37,0,9, -0,2,0,44,0,20,0,27,0,31,0,2,0,18,0,2,0,20,0,7,0,111,0,7,0,112,0,7,0,113,0,7, -0,114,0,7,0,115,0,7,0,116,0,7,0,117,0,7,0,118,0,7,0,119,0,7,0,120,0,7,0,121,0,2, -0,122,0,2,0,123,0,7,0,124,0,36,0,79,0,39,0,125,0,32,0,126,0,45,0,12,0,4,0,127,0,4, -0,-128,0,4,0,-127,0,4,0,-126,0,2,0,-125,0,2,0,-124,0,2,0,20,0,2,0,-123,0,2,0,-122,0,2, -0,-121,0,2,0,-120,0,2,0,-119,0,46,0,32,0,27,0,31,0,0,0,34,0,12,0,-118,0,47,0,-117,0,48, -0,-116,0,49,0,-115,0,2,0,-123,0,2,0,20,0,2,0,-114,0,2,0,18,0,2,0,37,0,2,0,43,0,4, -0,-113,0,2,0,-112,0,2,0,-111,0,2,0,-110,0,2,0,-109,0,2,0,-108,0,2,0,-107,0,4,0,-106,0,4, -0,-105,0,43,0,-104,0,30,0,-103,0,7,0,-102,0,4,0,-101,0,2,0,-100,0,2,0,-99,0,2,0,-98,0,2, -0,-97,0,7,0,-96,0,7,0,-95,0,9,0,-94,0,50,0,31,0,2,0,-93,0,2,0,-92,0,2,0,-91,0,2, -0,-90,0,32,0,-89,0,51,0,-88,0,0,0,-87,0,0,0,-86,0,0,0,-85,0,0,0,-84,0,0,0,-83,0,7, -0,-82,0,7,0,-81,0,2,0,-80,0,2,0,-79,0,2,0,-78,0,2,0,-77,0,2,0,-76,0,2,0,-75,0,2, -0,-74,0,7,0,-73,0,7,0,-72,0,7,0,-71,0,7,0,-70,0,7,0,-69,0,7,0,57,0,7,0,-68,0,7, -0,-67,0,7,0,-66,0,7,0,-65,0,7,0,-64,0,52,0,15,0,0,0,-63,0,9,0,-62,0,0,0,-61,0,0, -0,-60,0,4,0,-59,0,4,0,-58,0,9,0,-57,0,7,0,-56,0,7,0,-55,0,7,0,-54,0,4,0,-53,0,9, -0,-52,0,9,0,-51,0,4,0,-50,0,4,0,37,0,53,0,6,0,7,0,-73,0,7,0,-72,0,7,0,-71,0,7, -0,-49,0,7,0,67,0,4,0,64,0,54,0,5,0,2,0,20,0,2,0,36,0,2,0,64,0,2,0,-48,0,53, -0,-54,0,55,0,17,0,32,0,-89,0,46,0,-47,0,56,0,-46,0,7,0,-45,0,7,0,-44,0,2,0,18,0,2, -0,-43,0,7,0,113,0,7,0,114,0,7,0,-42,0,4,0,-41,0,2,0,-40,0,2,0,-39,0,4,0,-123,0,4, -0,-113,0,2,0,-38,0,2,0,-37,0,51,0,56,0,27,0,31,0,7,0,-36,0,7,0,-35,0,7,0,-34,0,7, -0,-33,0,7,0,-32,0,7,0,-31,0,7,0,-30,0,7,0,-29,0,7,0,-28,0,7,0,-27,0,7,0,-26,0,7, -0,-25,0,7,0,-24,0,7,0,-23,0,7,0,-22,0,7,0,-21,0,7,0,-20,0,7,0,-19,0,7,0,-18,0,7, -0,-17,0,2,0,-16,0,2,0,-15,0,2,0,-14,0,2,0,-13,0,2,0,-12,0,2,0,-11,0,2,0,-10,0,2, -0,20,0,2,0,18,0,2,0,-43,0,7,0,-9,0,7,0,-8,0,7,0,-7,0,7,0,-6,0,2,0,-5,0,2, -0,-4,0,2,0,-3,0,2,0,-125,0,4,0,23,0,4,0,-128,0,4,0,-127,0,4,0,-126,0,7,0,-2,0,7, -0,-1,0,7,0,-67,0,45,0,0,1,57,0,1,1,36,0,79,0,46,0,-47,0,52,0,2,1,54,0,3,1,55, -0,4,1,30,0,-103,0,0,0,5,1,0,0,6,1,58,0,8,0,7,0,7,1,7,0,8,1,7,0,-81,0,4, -0,20,0,7,0,9,1,7,0,10,1,7,0,11,1,32,0,45,0,59,0,80,0,27,0,31,0,2,0,18,0,2, -0,12,1,4,0,13,1,2,0,-79,0,2,0,14,1,7,0,-73,0,7,0,-72,0,7,0,-71,0,7,0,-70,0,7, -0,15,1,7,0,16,1,7,0,17,1,7,0,18,1,7,0,19,1,7,0,20,1,7,0,21,1,7,0,22,1,7, -0,23,1,7,0,24,1,7,0,25,1,60,0,26,1,2,0,27,1,2,0,70,0,7,0,113,0,7,0,114,0,7, -0,28,1,7,0,29,1,7,0,30,1,2,0,31,1,2,0,32,1,2,0,33,1,2,0,34,1,0,0,35,1,0, -0,36,1,2,0,37,1,2,0,38,1,2,0,39,1,2,0,40,1,2,0,41,1,7,0,42,1,7,0,43,1,7, -0,44,1,7,0,45,1,2,0,46,1,2,0,43,0,2,0,47,1,2,0,48,1,2,0,49,1,2,0,50,1,7, -0,51,1,7,0,52,1,7,0,53,1,7,0,54,1,7,0,55,1,7,0,56,1,7,0,57,1,7,0,58,1,7, -0,59,1,7,0,60,1,7,0,61,1,7,0,62,1,2,0,63,1,2,0,64,1,4,0,65,1,4,0,66,1,2, -0,67,1,2,0,68,1,2,0,69,1,2,0,70,1,7,0,71,1,7,0,72,1,7,0,73,1,7,0,74,1,2, -0,75,1,2,0,76,1,50,0,77,1,36,0,79,0,30,0,-103,0,39,0,125,0,61,0,2,0,27,0,31,0,36, -0,79,0,62,0,-127,0,27,0,31,0,2,0,-79,0,2,0,20,0,7,0,-73,0,7,0,-72,0,7,0,-71,0,7, -0,78,1,7,0,79,1,7,0,80,1,7,0,81,1,7,0,82,1,7,0,83,1,7,0,84,1,7,0,85,1,7, -0,86,1,7,0,87,1,7,0,88,1,7,0,89,1,7,0,90,1,7,0,91,1,7,0,92,1,7,0,93,1,7, -0,94,1,7,0,95,1,7,0,96,1,7,0,97,1,7,0,98,1,7,0,99,1,7,0,100,1,7,0,101,1,7, -0,102,1,7,0,103,1,7,0,104,1,2,0,105,1,2,0,106,1,2,0,107,1,0,0,108,1,0,0,109,1,7, -0,110,1,7,0,111,1,2,0,112,1,2,0,113,1,7,0,114,1,7,0,115,1,7,0,116,1,7,0,117,1,2, -0,118,1,2,0,119,1,4,0,13,1,4,0,120,1,2,0,121,1,2,0,122,1,2,0,123,1,2,0,124,1,7, -0,125,1,7,0,126,1,7,0,127,1,7,0,-128,1,7,0,-127,1,7,0,-126,1,7,0,-125,1,7,0,-124,1,7, -0,-123,1,7,0,-122,1,0,0,-121,1,7,0,-120,1,7,0,-119,1,7,0,-118,1,4,0,-117,1,0,0,-116,1,0, -0,47,1,0,0,-115,1,0,0,5,1,2,0,-114,1,2,0,-113,1,2,0,64,1,2,0,-112,1,2,0,-111,1,2, -0,-110,1,7,0,-109,1,7,0,-108,1,7,0,-107,1,7,0,-106,1,7,0,-105,1,2,0,-93,0,2,0,-92,0,54, -0,-104,1,54,0,-103,1,0,0,-102,1,0,0,-101,1,0,0,-100,1,0,0,-99,1,2,0,-98,1,2,0,12,1,7, -0,-97,1,7,0,-96,1,50,0,77,1,57,0,1,1,36,0,79,0,63,0,-95,1,30,0,-103,0,7,0,-94,1,7, -0,-93,1,7,0,-92,1,7,0,-91,1,7,0,-90,1,2,0,-89,1,2,0,70,0,7,0,-88,1,7,0,-87,1,7, -0,-86,1,7,0,-85,1,7,0,-84,1,7,0,-83,1,7,0,-82,1,7,0,-81,1,7,0,-80,1,2,0,-79,1,2, -0,-78,1,7,0,-77,1,7,0,-76,1,7,0,-75,1,7,0,-74,1,7,0,-73,1,4,0,-72,1,4,0,-71,1,4, -0,-70,1,39,0,125,0,12,0,-69,1,64,0,6,0,27,0,31,0,0,0,-68,1,7,0,-67,1,7,0,37,0,65, -0,2,0,43,0,-104,0,66,0,26,0,66,0,0,0,66,0,1,0,67,0,-66,1,4,0,-65,1,4,0,-64,1,4, -0,-63,1,4,0,-62,1,4,0,-61,1,4,0,-60,1,2,0,18,0,2,0,20,0,2,0,-59,1,2,0,-58,1,7, -0,5,0,7,0,6,0,7,0,7,0,7,0,-57,1,7,0,-56,1,7,0,-55,1,7,0,-54,1,7,0,-53,1,7, -0,-52,1,7,0,-51,1,7,0,23,0,7,0,-50,1,7,0,-49,1,68,0,15,0,27,0,31,0,67,0,-66,1,12, -0,-48,1,12,0,-47,1,36,0,79,0,62,0,-46,1,2,0,20,0,2,0,-45,1,4,0,-80,0,7,0,7,1,7, -0,-81,0,7,0,8,1,7,0,-44,1,7,0,-43,1,7,0,-42,1,35,0,10,0,7,0,-41,1,7,0,-40,1,7, -0,-39,1,7,0,-38,1,2,0,-37,1,2,0,-36,1,0,0,-35,1,0,0,-34,1,0,0,-33,1,0,0,-32,1,34, -0,7,0,7,0,-31,1,7,0,-40,1,7,0,-39,1,2,0,-35,1,2,0,-32,1,7,0,-38,1,7,0,37,0,69, -0,21,0,69,0,0,0,69,0,1,0,2,0,18,0,2,0,-30,1,2,0,-32,1,2,0,20,0,2,0,-29,1,2, -0,-28,1,2,0,-27,1,2,0,-26,1,2,0,-25,1,2,0,-24,1,2,0,-23,1,2,0,-22,1,7,0,-21,1,7, -0,-20,1,34,0,49,0,35,0,50,0,2,0,-19,1,2,0,-18,1,4,0,-17,1,70,0,5,0,2,0,-16,1,2, -0,-30,1,0,0,20,0,0,0,37,0,2,0,70,0,71,0,4,0,7,0,5,0,7,0,6,0,7,0,8,0,7, -0,-15,1,72,0,57,0,27,0,31,0,67,0,-66,1,12,0,-14,1,12,0,-47,1,32,0,-13,1,32,0,-12,1,32, -0,-11,1,36,0,79,0,73,0,-10,1,38,0,-9,1,62,0,-46,1,12,0,-8,1,7,0,7,1,7,0,-81,0,7, -0,8,1,4,0,-80,0,2,0,-7,1,2,0,-45,1,2,0,20,0,2,0,-6,1,7,0,-5,1,7,0,-4,1,7, -0,-3,1,2,0,-27,1,2,0,-26,1,2,0,-2,1,2,0,-1,1,4,0,70,0,2,0,23,0,2,0,98,0,2, -0,67,0,2,0,0,2,7,0,1,2,7,0,2,2,7,0,3,2,7,0,4,2,7,0,5,2,7,0,6,2,7, -0,7,2,7,0,8,2,7,0,9,2,7,0,10,2,0,0,11,2,0,0,12,2,64,0,13,2,64,0,14,2,64, -0,15,2,64,0,16,2,4,0,17,2,4,0,18,2,4,0,19,2,4,0,37,0,71,0,20,2,4,0,21,2,4, -0,22,2,70,0,23,2,70,0,24,2,74,0,39,0,27,0,31,0,67,0,-66,1,12,0,25,2,36,0,79,0,38, -0,-9,1,62,0,-46,1,75,0,26,2,76,0,27,2,77,0,28,2,78,0,29,2,79,0,30,2,80,0,31,2,81, -0,32,2,82,0,33,2,74,0,34,2,83,0,35,2,84,0,36,2,84,0,37,2,84,0,38,2,4,0,54,0,4, -0,39,2,4,0,40,2,4,0,41,2,4,0,42,2,4,0,-80,0,7,0,7,1,7,0,-81,0,7,0,8,1,7, -0,43,2,7,0,37,0,2,0,44,2,2,0,20,0,2,0,45,2,2,0,46,2,2,0,-45,1,2,0,47,2,85, -0,48,2,86,0,49,2,9,0,-94,0,77,0,8,0,9,0,50,2,7,0,51,2,4,0,52,2,0,0,20,0,0, -0,53,2,2,0,13,1,2,0,54,2,2,0,55,2,75,0,8,0,4,0,56,2,4,0,57,2,4,0,58,2,4, -0,59,2,0,0,37,0,0,0,-30,1,0,0,60,2,0,0,20,0,79,0,5,0,4,0,56,2,4,0,57,2,0, -0,61,2,0,0,62,2,2,0,20,0,87,0,2,0,4,0,63,2,7,0,-39,1,80,0,3,0,87,0,64,2,4, -0,65,2,4,0,20,0,78,0,6,0,7,0,66,2,2,0,67,2,0,0,20,0,0,0,-30,1,0,0,62,2,0, -0,68,2,81,0,4,0,0,0,-49,0,0,0,-73,0,0,0,-72,0,0,0,-71,0,88,0,6,0,46,0,50,2,0, -0,20,0,0,0,53,2,2,0,13,1,2,0,54,2,2,0,55,2,89,0,1,0,7,0,69,2,90,0,5,0,0, -0,-49,0,0,0,-73,0,0,0,-72,0,0,0,-71,0,4,0,37,0,82,0,1,0,7,0,70,2,83,0,2,0,4, -0,71,2,4,0,18,0,76,0,7,0,7,0,51,2,46,0,50,2,0,0,20,0,0,0,53,2,2,0,13,1,2, -0,54,2,2,0,55,2,91,0,1,0,7,0,72,2,92,0,1,0,4,0,73,2,93,0,1,0,0,0,74,2,94, -0,1,0,7,0,51,2,95,0,4,0,7,0,-49,0,7,0,-73,0,7,0,-72,0,7,0,-71,0,96,0,1,0,95, -0,52,2,97,0,5,0,4,0,75,2,4,0,76,2,0,0,20,0,0,0,-30,1,0,0,-74,0,98,0,2,0,4, -0,77,2,4,0,76,2,99,0,14,0,99,0,0,0,99,0,1,0,97,0,78,2,96,0,79,2,98,0,80,2,0, -0,81,2,12,0,82,2,12,0,83,2,100,0,84,2,4,0,54,0,4,0,40,2,4,0,39,2,4,0,37,0,78, -0,85,2,85,0,14,0,12,0,86,2,78,0,85,2,0,0,87,2,0,0,88,2,0,0,89,2,0,0,90,2,0, -0,91,2,0,0,92,2,0,0,93,2,0,0,20,0,84,0,36,2,84,0,38,2,2,0,94,2,0,0,95,2,86, -0,8,0,4,0,96,2,4,0,97,2,75,0,98,2,79,0,99,2,4,0,40,2,4,0,39,2,4,0,54,0,4, -0,37,0,101,0,6,0,101,0,0,0,101,0,1,0,4,0,18,0,4,0,13,1,0,0,17,0,0,0,100,2,102, -0,7,0,101,0,101,2,2,0,102,2,2,0,86,2,2,0,103,2,2,0,93,0,9,0,104,2,9,0,105,2,103, -0,3,0,101,0,101,2,32,0,-89,0,0,0,17,0,104,0,5,0,101,0,101,2,32,0,-89,0,0,0,17,0,2, -0,106,2,0,0,107,2,105,0,5,0,101,0,101,2,7,0,91,0,7,0,108,2,4,0,109,2,4,0,110,2,106, -0,5,0,101,0,101,2,32,0,111,2,0,0,72,0,4,0,13,1,4,0,20,0,107,0,13,0,101,0,101,2,32, -0,112,2,32,0,113,2,32,0,114,2,32,0,115,2,7,0,116,2,7,0,117,2,7,0,108,2,7,0,118,2,4, -0,119,2,4,0,120,2,4,0,93,0,4,0,121,2,108,0,5,0,101,0,101,2,2,0,122,2,2,0,20,0,7, -0,123,2,32,0,124,2,109,0,3,0,101,0,101,2,7,0,125,2,4,0,93,0,110,0,10,0,101,0,101,2,7, -0,126,2,4,0,127,2,4,0,37,0,2,0,93,0,2,0,-128,2,2,0,-127,2,2,0,-126,2,7,0,-125,2,0, -0,-124,2,111,0,3,0,101,0,101,2,7,0,37,0,4,0,18,0,112,0,11,0,101,0,101,2,51,0,-123,2,7, -0,-122,2,4,0,-121,2,0,0,-124,2,7,0,-120,2,4,0,-119,2,32,0,-118,2,0,0,-117,2,4,0,-116,2,4, -0,37,0,113,0,10,0,101,0,101,2,32,0,-115,2,46,0,-114,2,4,0,93,0,4,0,-113,2,7,0,-112,2,7, -0,-111,2,0,0,-117,2,4,0,-116,2,4,0,37,0,114,0,3,0,101,0,101,2,7,0,-110,2,4,0,-109,2,115, -0,5,0,101,0,101,2,7,0,-108,2,0,0,-124,2,2,0,20,0,2,0,-107,2,116,0,8,0,101,0,101,2,32, -0,-89,0,7,0,-108,2,7,0,-38,1,7,0,109,0,0,0,-124,2,2,0,20,0,2,0,18,0,117,0,21,0,101, -0,101,2,32,0,-106,2,0,0,-124,2,51,0,-123,2,32,0,-118,2,2,0,20,0,2,0,37,0,7,0,-105,2,7, -0,-104,2,7,0,-103,2,7,0,-5,1,7,0,-102,2,7,0,-101,2,7,0,-100,2,7,0,-99,2,4,0,-119,2,4, -0,-116,2,0,0,-117,2,7,0,-98,2,7,0,-97,2,7,0,43,0,118,0,7,0,101,0,101,2,2,0,-96,2,2, -0,-95,2,4,0,70,0,32,0,-89,0,7,0,-94,2,0,0,-124,2,119,0,9,0,101,0,101,2,32,0,-89,0,7, -0,-93,2,7,0,-92,2,7,0,-99,2,4,0,-91,2,4,0,-90,2,7,0,-89,2,0,0,17,0,120,0,1,0,101, -0,101,2,121,0,5,0,101,0,101,2,122,0,-88,2,123,0,-87,2,124,0,-86,2,125,0,-85,2,126,0,14,0,101, -0,101,2,78,0,-84,2,78,0,-83,2,78,0,-82,2,78,0,-81,2,78,0,-80,2,78,0,-79,2,75,0,-78,2,4, -0,-77,2,4,0,-76,2,2,0,-75,2,2,0,37,0,7,0,-74,2,127,0,-73,2,-128,0,3,0,101,0,101,2,-127, -0,-72,2,-126,0,-73,2,-125,0,4,0,101,0,101,2,32,0,-89,0,4,0,-71,2,4,0,37,0,-124,0,2,0,4, -0,-70,2,7,0,-39,1,-123,0,2,0,4,0,-127,0,4,0,-69,2,-122,0,20,0,101,0,101,2,32,0,-89,0,0, -0,-124,2,2,0,-68,2,2,0,-67,2,2,0,20,0,2,0,37,0,7,0,-66,2,7,0,-65,2,4,0,54,0,4, -0,-64,2,-123,0,-63,2,-124,0,-62,2,4,0,-61,2,4,0,-60,2,4,0,-59,2,4,0,-69,2,7,0,-58,2,7, -0,-57,2,7,0,-56,2,-121,0,8,0,101,0,101,2,-120,0,-55,2,-127,0,-72,2,4,0,-54,2,4,0,-53,2,4, -0,-52,2,2,0,20,0,2,0,57,0,-119,0,5,0,101,0,101,2,32,0,45,0,2,0,-51,2,2,0,20,0,2, -0,-50,2,-118,0,5,0,101,0,101,2,4,0,-49,2,2,0,20,0,2,0,-48,2,7,0,-47,2,-117,0,3,0,101, -0,101,2,-116,0,-46,2,125,0,-85,2,-115,0,10,0,101,0,101,2,32,0,-45,2,32,0,-44,2,0,0,-43,2,7, -0,-42,2,2,0,-41,2,2,0,-40,2,0,0,-39,2,0,0,-38,2,0,0,107,2,-114,0,9,0,101,0,101,2,32, -0,-37,2,0,0,-43,2,7,0,-36,2,7,0,-35,2,0,0,13,1,0,0,122,2,0,0,-34,2,0,0,37,0,-113, -0,24,0,27,0,31,0,2,0,-29,1,2,0,-28,1,2,0,-33,2,2,0,20,0,2,0,-32,2,2,0,-31,2,2, -0,-30,2,2,0,70,0,0,0,-29,2,0,0,-28,2,0,0,-27,2,0,0,18,0,4,0,37,0,7,0,-26,2,7, -0,-25,2,7,0,-24,2,7,0,-23,2,7,0,-22,2,7,0,-21,2,34,0,-20,2,36,0,79,0,38,0,-9,1,80, -0,31,2,-112,0,3,0,-112,0,0,0,-112,0,1,0,0,0,17,0,67,0,3,0,7,0,-19,2,4,0,20,0,4, -0,37,0,32,0,111,0,27,0,31,0,2,0,18,0,2,0,-18,2,4,0,-17,2,4,0,-16,2,4,0,-15,2,0, -0,-14,2,32,0,38,0,32,0,-13,2,32,0,-12,2,32,0,-11,2,32,0,-10,2,36,0,79,0,73,0,-10,1,67, -0,-66,1,-111,0,-9,2,-111,0,-8,2,-110,0,-7,2,9,0,2,0,12,0,-6,2,12,0,25,2,12,0,-47,1,12, -0,-5,2,12,0,-4,2,62,0,-46,1,7,0,7,1,7,0,-3,2,7,0,-2,2,7,0,-81,0,7,0,-1,2,7, -0,8,1,7,0,0,3,7,0,1,3,7,0,-93,2,7,0,2,3,7,0,-45,0,4,0,3,3,2,0,20,0,2, -0,4,3,2,0,5,3,2,0,6,3,2,0,7,3,2,0,8,3,2,0,9,3,2,0,10,3,2,0,11,3,2, -0,12,3,2,0,13,3,2,0,14,3,4,0,15,3,4,0,16,3,4,0,17,3,4,0,18,3,7,0,19,3,7, -0,20,3,7,0,21,3,7,0,22,3,7,0,23,3,7,0,24,3,7,0,25,3,7,0,26,3,7,0,27,3,7, -0,28,3,7,0,29,3,7,0,30,3,0,0,31,3,0,0,32,3,0,0,-45,1,0,0,33,3,0,0,34,3,0, -0,35,3,7,0,36,3,7,0,37,3,39,0,125,0,12,0,38,3,12,0,39,3,12,0,40,3,12,0,41,3,7, -0,42,3,2,0,71,2,2,0,43,3,7,0,52,2,4,0,44,3,4,0,45,3,-109,0,46,3,2,0,47,3,2, -0,-38,0,7,0,48,3,12,0,49,3,12,0,50,3,12,0,51,3,12,0,52,3,-108,0,53,3,-107,0,54,3,63, -0,55,3,2,0,56,3,2,0,57,3,2,0,58,3,2,0,59,3,7,0,44,2,2,0,60,3,2,0,61,3,-116, -0,62,3,-127,0,63,3,-127,0,64,3,4,0,65,3,4,0,66,3,4,0,67,3,4,0,70,0,9,0,-94,0,12, -0,68,3,-106,0,14,0,-106,0,0,0,-106,0,1,0,32,0,38,0,7,0,-93,2,7,0,9,1,7,0,-92,2,7, -0,-99,2,0,0,17,0,4,0,-91,2,4,0,-90,2,4,0,69,3,2,0,18,0,2,0,70,3,7,0,-89,2,-108, -0,36,0,2,0,71,3,2,0,72,3,2,0,20,0,2,0,-99,2,7,0,73,3,7,0,74,3,7,0,75,3,7, -0,76,3,7,0,77,3,7,0,78,3,7,0,79,3,7,0,80,3,7,0,81,3,7,0,82,3,7,0,83,3,7, -0,84,3,7,0,85,3,7,0,86,3,7,0,87,3,7,0,88,3,7,0,89,3,7,0,90,3,7,0,91,3,7, -0,92,3,7,0,93,3,7,0,94,3,7,0,95,3,7,0,96,3,2,0,97,3,2,0,98,3,2,0,99,3,2, -0,100,3,51,0,-88,0,-105,0,101,3,7,0,102,3,4,0,110,2,125,0,5,0,4,0,20,0,4,0,103,3,4, -0,104,3,4,0,105,3,4,0,106,3,-104,0,1,0,7,0,-31,1,-109,0,30,0,4,0,20,0,7,0,107,3,7, -0,108,3,7,0,109,3,4,0,110,3,4,0,111,3,4,0,112,3,4,0,113,3,7,0,114,3,7,0,115,3,7, -0,116,3,7,0,117,3,7,0,118,3,7,0,119,3,7,0,120,3,7,0,121,3,7,0,122,3,7,0,123,3,7, -0,124,3,7,0,125,3,7,0,126,3,7,0,127,3,7,0,-128,3,7,0,-127,3,7,0,-126,3,7,0,-125,3,4, -0,-124,3,4,0,-123,3,7,0,-122,3,7,0,27,3,-107,0,49,0,-120,0,-121,3,4,0,-120,3,4,0,-119,3,-103, -0,-118,3,-102,0,-117,3,0,0,37,0,0,0,-116,3,2,0,-115,3,7,0,-114,3,0,0,-113,3,7,0,-112,3,7, -0,-111,3,7,0,-110,3,7,0,-109,3,7,0,-108,3,7,0,-107,3,7,0,-106,3,7,0,-105,3,7,0,-104,3,2, -0,-103,3,0,0,-102,3,2,0,-101,3,7,0,-100,3,7,0,-99,3,0,0,-98,3,4,0,-126,0,4,0,-97,3,4, -0,-96,3,2,0,-95,3,2,0,-94,3,-104,0,-93,3,4,0,-92,3,4,0,81,0,7,0,-91,3,7,0,-90,3,7, -0,-89,3,7,0,-88,3,2,0,-87,3,2,0,-86,3,2,0,-85,3,2,0,-84,3,2,0,-83,3,2,0,-82,3,2, -0,-81,3,2,0,-80,3,-101,0,-79,3,7,0,-78,3,7,0,-77,3,125,0,-76,3,-116,0,48,0,2,0,18,0,2, -0,-75,3,2,0,-74,3,2,0,-73,3,7,0,-72,3,2,0,-71,3,2,0,-70,3,7,0,-69,3,2,0,-68,3,2, -0,-67,3,7,0,-66,3,7,0,-65,3,7,0,-64,3,7,0,-63,3,7,0,-62,3,7,0,-61,3,4,0,-60,3,7, -0,-59,3,7,0,-58,3,7,0,-57,3,74,0,-56,3,74,0,-55,3,74,0,-54,3,0,0,-53,3,7,0,-52,3,7, -0,-51,3,36,0,79,0,2,0,-50,3,0,0,-49,3,0,0,-48,3,7,0,-47,3,4,0,-46,3,7,0,-45,3,7, -0,-44,3,4,0,-43,3,4,0,20,0,7,0,-42,3,7,0,-41,3,7,0,-40,3,78,0,-39,3,7,0,-38,3,7, -0,-37,3,7,0,-36,3,7,0,-35,3,7,0,-34,3,7,0,-33,3,7,0,-32,3,4,0,-31,3,-100,0,71,0,27, -0,31,0,2,0,-79,0,2,0,14,1,2,0,47,1,2,0,-30,3,7,0,-29,3,7,0,-28,3,7,0,-27,3,7, -0,-26,3,7,0,-25,3,7,0,-24,3,7,0,-23,3,7,0,-22,3,7,0,84,1,7,0,86,1,7,0,85,1,7, -0,-21,3,4,0,-20,3,7,0,-19,3,7,0,-18,3,7,0,-17,3,7,0,-16,3,7,0,-15,3,7,0,-14,3,7, -0,-13,3,2,0,-12,3,2,0,13,1,2,0,-11,3,2,0,-10,3,2,0,-9,3,2,0,-8,3,2,0,-7,3,2, -0,-6,3,7,0,-5,3,7,0,-4,3,7,0,-3,3,7,0,-2,3,7,0,-1,3,7,0,0,4,7,0,1,4,7, -0,2,4,7,0,3,4,7,0,4,4,7,0,5,4,7,0,6,4,2,0,7,4,2,0,8,4,2,0,9,4,2, -0,10,4,7,0,11,4,7,0,12,4,7,0,13,4,7,0,14,4,2,0,15,4,2,0,16,4,2,0,17,4,2, -0,18,4,7,0,19,4,7,0,20,4,7,0,21,4,7,0,22,4,2,0,23,4,2,0,24,4,2,0,25,4,2, -0,43,0,7,0,26,4,7,0,27,4,36,0,79,0,50,0,77,1,30,0,-103,0,39,0,125,0,-99,0,16,0,2, -0,28,4,2,0,29,4,2,0,30,4,2,0,20,0,2,0,31,4,2,0,32,4,2,0,33,4,2,0,34,4,2, -0,35,4,2,0,36,4,2,0,37,4,2,0,38,4,4,0,39,4,7,0,40,4,7,0,41,4,7,0,42,4,-98, -0,8,0,-98,0,0,0,-98,0,1,0,4,0,3,3,4,0,43,4,4,0,20,0,2,0,44,4,2,0,45,4,32, -0,-89,0,-97,0,13,0,9,0,46,4,9,0,47,4,4,0,48,4,4,0,49,4,4,0,50,4,4,0,51,4,4, -0,52,4,4,0,53,4,4,0,54,4,4,0,55,4,4,0,56,4,4,0,37,0,0,0,57,4,-96,0,5,0,9, -0,58,4,9,0,59,4,4,0,60,4,4,0,70,0,0,0,61,4,-95,0,13,0,4,0,18,0,4,0,62,4,4, -0,63,4,4,0,64,4,4,0,65,4,4,0,66,4,4,0,93,0,4,0,67,4,4,0,68,4,4,0,69,4,4, -0,70,4,4,0,71,4,26,0,30,0,-94,0,4,0,4,0,72,4,7,0,73,4,2,0,20,0,2,0,68,2,-93, -0,11,0,-93,0,0,0,-93,0,1,0,0,0,17,0,62,0,74,4,63,0,75,4,4,0,3,3,4,0,76,4,4, -0,77,4,4,0,37,0,4,0,78,4,4,0,79,4,-92,0,-126,0,-97,0,80,4,-96,0,81,4,-95,0,82,4,4, -0,83,4,4,0,-126,0,4,0,-97,3,4,0,84,4,4,0,85,4,4,0,86,4,4,0,87,4,2,0,20,0,2, -0,88,4,7,0,20,3,7,0,89,4,7,0,90,4,7,0,91,4,7,0,92,4,7,0,93,4,2,0,94,4,2, -0,95,4,2,0,96,4,2,0,97,4,2,0,-39,0,2,0,98,4,2,0,99,4,2,0,100,3,2,0,100,4,2, -0,101,4,2,0,34,1,2,0,109,0,2,0,102,4,2,0,103,4,2,0,104,4,2,0,105,4,2,0,106,4,2, -0,107,4,2,0,108,4,2,0,109,4,2,0,110,4,2,0,35,1,2,0,111,4,2,0,112,4,2,0,113,4,2, -0,114,4,4,0,115,4,4,0,13,1,2,0,116,4,2,0,117,4,2,0,118,4,2,0,119,4,2,0,120,4,2, -0,121,4,24,0,122,4,24,0,123,4,23,0,124,4,12,0,125,4,2,0,126,4,2,0,37,0,7,0,127,4,7, -0,-128,4,7,0,-127,4,7,0,-126,4,7,0,-125,4,7,0,-124,4,7,0,-123,4,7,0,-122,4,7,0,-121,4,2, -0,-120,4,2,0,-119,4,2,0,-118,4,2,0,-117,4,2,0,-116,4,2,0,-115,4,7,0,-114,4,7,0,-113,4,7, -0,-112,4,2,0,-111,4,2,0,-110,4,2,0,-109,4,2,0,-108,4,2,0,-107,4,2,0,-106,4,2,0,-105,4,2, -0,-104,4,2,0,-103,4,2,0,-102,4,4,0,-101,4,4,0,-100,4,4,0,-99,4,4,0,-98,4,4,0,-97,4,7, -0,-96,4,4,0,-95,4,4,0,-94,4,4,0,-93,4,4,0,-92,4,7,0,-91,4,7,0,-90,4,7,0,-89,4,7, -0,-88,4,7,0,-87,4,7,0,-86,4,7,0,-85,4,7,0,-84,4,7,0,-83,4,0,0,-82,4,0,0,-81,4,4, -0,-80,4,2,0,-79,4,2,0,12,1,0,0,-78,4,7,0,-77,4,7,0,-76,4,4,0,-75,4,4,0,-74,4,7, -0,-73,4,7,0,-72,4,2,0,-71,4,2,0,-70,4,7,0,-69,4,2,0,-68,4,2,0,-67,4,4,0,-66,4,2, -0,-65,4,2,0,-64,4,2,0,-63,4,2,0,-62,4,7,0,-61,4,7,0,70,0,42,0,-60,4,-91,0,9,0,-91, -0,0,0,-91,0,1,0,0,0,17,0,2,0,-59,4,2,0,-58,4,2,0,-57,4,2,0,43,0,7,0,-56,4,7, -0,70,0,-90,0,5,0,7,0,-55,4,0,0,18,0,0,0,43,0,0,0,70,0,0,0,12,1,-89,0,5,0,-89, -0,0,0,-89,0,1,0,4,0,-54,4,0,0,-53,4,4,0,20,0,-88,0,5,0,-87,0,-52,4,2,0,20,0,2, -0,-51,4,2,0,-50,4,2,0,-49,4,-86,0,4,0,2,0,109,0,2,0,-122,2,2,0,-48,4,2,0,-47,4,-85, -0,7,0,2,0,20,0,2,0,-46,4,2,0,-45,4,2,0,-44,4,-86,0,-43,4,7,0,-42,4,4,0,-41,4,-84, -0,4,0,-84,0,0,0,-84,0,1,0,0,0,-40,4,7,0,-39,4,-83,0,56,0,2,0,-38,4,2,0,-37,4,7, -0,-36,4,7,0,-35,4,2,0,-48,4,2,0,-34,4,7,0,-33,4,7,0,-32,4,2,0,-31,4,2,0,-30,4,2, -0,-29,4,2,0,-28,4,7,0,-27,4,7,0,-26,4,7,0,-25,4,7,0,37,0,2,0,-24,4,2,0,-23,4,2, -0,-22,4,2,0,-21,4,-88,0,-20,4,-85,0,-19,4,7,0,-18,4,7,0,-17,4,0,0,-16,4,0,0,-15,4,0, -0,-14,4,0,0,-13,4,0,0,-12,4,0,0,-11,4,2,0,-10,4,7,0,-9,4,7,0,-8,4,7,0,-7,4,7, -0,-6,4,7,0,-5,4,7,0,-4,4,7,0,-3,4,7,0,-2,4,7,0,-1,4,7,0,0,5,2,0,1,5,0, -0,2,5,0,0,3,5,0,0,4,5,0,0,5,5,32,0,6,5,0,0,7,5,0,0,8,5,0,0,9,5,0, -0,10,5,0,0,11,5,0,0,12,5,0,0,13,5,0,0,14,5,0,0,15,5,-82,0,6,0,2,0,109,0,0, -0,-122,2,0,0,16,5,0,0,17,5,0,0,20,0,0,0,-74,0,-81,0,26,0,-80,0,18,5,50,0,77,1,60, -0,19,5,-82,0,20,5,-82,0,21,5,-82,0,22,5,-82,0,23,5,-82,0,24,5,-82,0,25,5,-82,0,26,5,7, -0,27,5,2,0,28,5,2,0,47,1,2,0,29,5,2,0,1,2,0,0,30,5,0,0,31,5,0,0,32,5,0, -0,33,5,0,0,93,0,0,0,34,5,0,0,35,5,0,0,36,5,0,0,37,5,0,0,38,5,0,0,-74,0,-79, -0,43,0,27,0,31,0,32,0,39,5,-100,0,40,5,-79,0,41,5,46,0,-47,0,12,0,42,5,-98,0,43,5,7, -0,44,5,7,0,45,5,7,0,46,5,7,0,47,5,4,0,3,3,7,0,48,5,2,0,49,5,2,0,50,5,2, -0,51,5,2,0,52,5,2,0,53,5,2,0,54,5,2,0,55,5,2,0,5,1,57,0,1,1,9,0,56,5,-99, -0,57,5,-90,0,58,5,-83,0,59,5,-92,0,-73,0,-94,0,60,5,39,0,125,0,12,0,103,0,12,0,61,5,2, -0,62,5,2,0,63,5,2,0,64,5,2,0,65,5,-78,0,66,5,2,0,67,5,2,0,68,5,2,0,64,1,2, -0,-38,0,-81,0,69,5,4,0,70,5,4,0,37,0,-77,0,9,0,46,0,-47,0,45,0,0,1,7,0,8,2,7, -0,9,2,7,0,109,0,7,0,71,5,7,0,72,5,2,0,73,5,2,0,74,5,-76,0,75,0,-75,0,0,0,-75, -0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,7,0,79,5,7,0,80,5,7,0,81,5,7, -0,82,5,7,0,83,5,7,0,84,5,7,0,85,5,7,0,20,1,7,0,86,5,4,0,87,5,2,0,88,5,2, -0,17,5,32,0,39,5,32,0,89,5,-77,0,90,5,-76,0,91,5,-73,0,92,5,-72,0,93,5,-71,0,94,5,0, -0,95,5,2,0,30,4,2,0,96,5,4,0,3,3,4,0,97,5,2,0,98,5,2,0,99,5,2,0,100,5,0, -0,101,5,0,0,43,0,7,0,115,0,7,0,102,5,7,0,103,5,7,0,104,5,7,0,105,5,7,0,106,5,7, -0,107,5,7,0,108,5,7,0,-82,0,7,0,44,5,2,0,109,5,2,0,110,5,2,0,111,5,2,0,112,5,2, -0,-119,0,2,0,29,5,2,0,113,5,2,0,114,5,2,0,115,5,2,0,116,5,7,0,117,5,7,0,118,5,67, -0,119,5,12,0,120,5,2,0,121,5,2,0,53,2,2,0,122,5,2,0,20,0,2,0,123,5,2,0,124,5,2, -0,125,5,0,0,126,5,0,0,127,5,9,0,-128,5,-70,0,-127,5,7,0,-126,5,2,0,-125,5,2,0,-124,5,2, -0,53,5,2,0,54,5,-69,0,19,0,24,0,36,0,24,0,64,0,23,0,-123,5,23,0,-122,5,23,0,-121,5,7, -0,-120,5,7,0,-119,5,7,0,-118,5,7,0,-117,5,2,0,-116,5,2,0,-115,5,2,0,-114,5,2,0,-113,5,2, -0,-112,5,2,0,-111,5,4,0,20,0,7,0,-110,5,2,0,99,5,0,0,107,2,-75,0,6,0,-75,0,0,0,-75, -0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-68,0,6,0,-75,0,0,0,-75,0,1,0,4, -0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-67,0,27,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7, -0,76,5,-74,0,77,5,2,0,78,5,4,0,-109,5,4,0,70,0,-69,0,-108,5,9,0,-107,5,12,0,-106,5,36, -0,79,0,27,0,80,0,0,0,-105,5,0,0,-104,5,0,0,-103,5,2,0,-102,5,2,0,-101,5,2,0,-100,5,2, -0,-99,5,2,0,65,0,2,0,46,0,2,0,-119,0,2,0,-98,5,4,0,20,0,7,0,-97,5,24,0,36,0,-66, -0,29,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,-73,0,92,5,2,0,78,5,2, -0,-96,5,2,0,-95,5,2,0,-94,5,2,0,-93,5,-69,0,-108,5,2,0,-92,5,2,0,-119,0,2,0,-101,5,2, -0,-91,5,9,0,-90,5,2,0,29,5,0,0,-89,5,0,0,-88,5,2,0,-87,5,2,0,-86,5,2,0,12,3,2, -0,-85,5,2,0,-84,5,0,0,37,0,0,0,20,0,0,0,47,1,0,0,-83,5,-65,0,16,0,-75,0,0,0,-75, -0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-69,0,-108,5,7,0,8,2,7,0,9,2,2, -0,-92,5,2,0,-82,5,2,0,-81,5,2,0,-80,5,4,0,20,0,7,0,71,5,-70,0,-127,5,-64,0,33,0,-75, -0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-63,0,-79,5,4,0,-78,5,0, -0,-77,5,0,0,-76,5,0,0,-75,5,2,0,18,0,2,0,-74,5,2,0,20,0,2,0,-73,5,2,0,-72,5,2, -0,-71,5,2,0,-70,5,2,0,43,0,4,0,70,0,0,0,-69,5,-62,0,-68,5,2,0,-67,5,2,0,-66,5,2, -0,-65,5,2,0,-48,0,9,0,-64,5,9,0,-63,5,9,0,-62,5,9,0,-61,5,9,0,-60,5,2,0,-59,5,0, -0,-58,5,-61,0,23,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-69, -0,-108,5,12,0,-57,5,2,0,-101,5,2,0,-56,5,2,0,20,0,2,0,57,0,9,0,-90,5,12,0,-55,5,-60, -0,-54,5,0,0,-53,5,-59,0,-52,5,4,0,-51,5,4,0,-50,5,2,0,18,0,2,0,-49,5,2,0,-48,5,2, -0,-47,5,-58,0,29,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-69, -0,-108,5,46,0,-114,2,45,0,0,1,60,0,19,5,2,0,13,1,2,0,-119,0,2,0,-46,5,2,0,-45,5,4, -0,20,0,2,0,49,5,2,0,-44,5,2,0,-98,5,2,0,-101,5,7,0,71,5,0,0,-43,5,0,0,-42,5,0, -0,-41,5,0,0,-40,5,7,0,8,2,7,0,9,2,7,0,-39,5,7,0,-38,5,-70,0,-127,5,-57,0,11,0,-75, -0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,2,0,-119,0,2,0,-98,5,2, -0,-37,5,2,0,20,0,-69,0,-108,5,-56,0,24,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74, -0,77,5,2,0,78,5,42,0,-36,5,4,0,-35,5,4,0,-34,5,2,0,93,0,2,0,-119,0,4,0,-33,5,4, -0,-32,5,4,0,-31,5,4,0,-30,5,4,0,-29,5,4,0,-28,5,4,0,-27,5,4,0,-26,5,7,0,-25,5,23, -0,-24,5,23,0,-23,5,4,0,-22,5,4,0,-21,5,-55,0,10,0,27,0,31,0,9,0,-20,5,9,0,-19,5,9, -0,-18,5,9,0,-17,5,9,0,-16,5,4,0,93,0,4,0,-15,5,0,0,-14,5,0,0,-13,5,-54,0,10,0,-75, -0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,-55,0,-12,5,2,0,93,0,2,0,-119,0,4, -0,43,0,9,0,-11,5,-53,0,8,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,-69, -0,-108,5,4,0,20,0,4,0,-10,5,-52,0,21,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74, -0,77,5,2,0,78,5,-69,0,-108,5,27,0,-9,5,27,0,80,0,2,0,20,0,2,0,-119,0,7,0,-8,5,9, -0,-7,5,7,0,8,2,7,0,9,2,57,0,1,1,57,0,-6,5,4,0,-5,5,2,0,-89,5,2,0,37,0,-70, -0,-127,5,-51,0,42,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74,0,77,5,2,0,78,5,-69, -0,-108,5,-50,0,-4,5,0,0,-77,5,0,0,-76,5,0,0,-75,5,2,0,18,0,2,0,-66,5,2,0,20,0,2, -0,-73,5,9,0,-7,5,4,0,-3,5,4,0,-2,5,4,0,-1,5,4,0,0,6,23,0,1,6,23,0,2,6,7, -0,3,6,7,0,4,6,7,0,5,6,7,0,-8,5,2,0,-67,5,2,0,-48,0,2,0,102,1,2,0,6,6,2, -0,37,0,2,0,43,0,2,0,7,6,2,0,8,6,9,0,-64,5,9,0,-63,5,9,0,-62,5,9,0,-61,5,9, -0,-60,5,2,0,-59,5,0,0,-58,5,56,0,9,6,-49,0,20,0,0,0,10,6,0,0,11,6,0,0,12,6,0, -0,13,6,0,0,14,6,0,0,15,6,0,0,16,6,0,0,17,6,0,0,18,6,0,0,19,6,0,0,20,6,0, -0,21,6,0,0,22,6,0,0,23,6,0,0,24,6,0,0,25,6,0,0,26,6,0,0,27,6,0,0,68,2,0, -0,28,6,-48,0,54,0,0,0,29,6,0,0,20,6,0,0,21,6,0,0,30,6,0,0,31,6,0,0,32,6,0, -0,33,6,0,0,34,6,0,0,35,6,0,0,36,6,0,0,37,6,0,0,38,6,0,0,39,6,0,0,40,6,0, -0,41,6,0,0,42,6,0,0,43,6,0,0,44,6,0,0,45,6,0,0,46,6,0,0,47,6,0,0,48,6,0, -0,49,6,0,0,50,6,0,0,51,6,0,0,52,6,0,0,53,6,0,0,54,6,0,0,55,6,0,0,56,6,0, -0,57,6,0,0,58,6,0,0,95,0,0,0,59,6,0,0,60,6,0,0,61,6,0,0,62,6,0,0,63,6,0, -0,64,6,0,0,65,6,0,0,66,6,0,0,67,6,0,0,68,6,0,0,69,6,0,0,70,6,0,0,71,6,0, -0,72,6,0,0,73,6,0,0,74,6,0,0,75,6,0,0,76,6,0,0,77,6,0,0,78,6,0,0,79,6,-47, -0,5,0,0,0,80,6,0,0,37,6,0,0,39,6,2,0,20,0,2,0,37,0,-46,0,22,0,-46,0,0,0,-46, -0,1,0,0,0,17,0,-49,0,81,6,-48,0,82,6,-48,0,83,6,-48,0,84,6,-48,0,85,6,-48,0,86,6,-48, -0,87,6,-48,0,88,6,-48,0,89,6,-48,0,90,6,-48,0,91,6,-48,0,92,6,-48,0,93,6,-48,0,94,6,-48, -0,95,6,-48,0,96,6,-47,0,97,6,0,0,98,6,0,0,99,6,-45,0,5,0,4,0,20,0,4,0,37,0,7, -0,52,2,7,0,100,6,7,0,-31,1,-44,0,66,0,4,0,20,0,4,0,101,6,4,0,102,6,0,0,103,6,0, -0,104,6,0,0,105,6,0,0,106,6,0,0,107,6,0,0,108,6,0,0,109,6,0,0,110,6,0,0,111,6,2, -0,112,6,2,0,113,6,4,0,114,6,4,0,115,6,4,0,116,6,4,0,117,6,2,0,118,6,2,0,119,6,2, -0,120,6,2,0,121,6,4,0,122,6,4,0,123,6,2,0,124,6,2,0,125,6,2,0,126,6,2,0,127,6,0, -0,-128,6,12,0,-127,6,2,0,-126,6,2,0,-125,6,2,0,-124,6,2,0,-123,6,2,0,-122,6,2,0,-121,6,2, -0,-120,6,2,0,-119,6,-45,0,-118,6,2,0,-117,6,2,0,-116,6,2,0,-115,6,2,0,-114,6,4,0,-113,6,4, -0,-112,6,4,0,-111,6,4,0,-110,6,2,0,-109,6,2,0,-108,6,2,0,-107,6,2,0,-106,6,2,0,-105,6,2, -0,-104,6,2,0,-103,6,2,0,-102,6,2,0,-101,6,2,0,-100,6,2,0,-99,6,2,0,37,0,0,0,-98,6,0, -0,-97,6,0,0,-96,6,7,0,-95,6,2,0,55,5,2,0,-94,6,54,0,-93,6,-43,0,18,0,27,0,31,0,12, -0,-92,6,12,0,-91,6,12,0,-90,6,-79,0,-89,6,2,0,-105,2,2,0,-88,6,2,0,-104,2,2,0,-87,6,2, -0,-86,6,2,0,-85,6,2,0,-84,6,2,0,-83,6,2,0,-82,6,2,0,37,0,2,0,-81,6,2,0,-80,6,2, -0,-79,6,-42,0,5,0,-42,0,0,0,-42,0,1,0,-42,0,-78,6,13,0,-77,6,4,0,20,0,-41,0,7,0,-41, -0,0,0,-41,0,1,0,-42,0,-76,6,-42,0,-75,6,2,0,123,4,2,0,20,0,4,0,37,0,-40,0,17,0,-40, -0,0,0,-40,0,1,0,0,0,-74,6,0,0,-73,6,0,0,-72,6,2,0,-71,6,2,0,-70,6,2,0,-86,6,2, -0,-85,6,2,0,20,0,2,0,70,3,2,0,-69,6,2,0,-68,6,2,0,-67,6,2,0,-66,6,4,0,-65,6,-40, -0,-64,6,-74,0,30,0,-74,0,0,0,-74,0,1,0,-42,0,-76,6,-42,0,-75,6,-42,0,-63,6,-42,0,-62,6,-43, -0,-61,6,7,0,-60,6,23,0,52,0,23,0,-59,6,23,0,-58,6,2,0,-57,6,2,0,-56,6,2,0,-55,6,0, -0,75,5,0,0,-54,6,2,0,-53,6,2,0,-52,6,0,0,-51,6,0,0,-50,6,0,0,-49,6,0,0,-48,6,2, -0,-47,6,2,0,-46,6,2,0,-45,6,2,0,20,0,39,0,125,0,12,0,-44,6,12,0,-43,6,12,0,-42,6,-39, -0,11,0,0,0,-41,6,2,0,-40,6,2,0,-39,6,2,0,-38,6,2,0,-37,6,2,0,-36,6,2,0,107,4,9, -0,-35,6,9,0,-34,6,4,0,-33,6,4,0,-32,6,-38,0,1,0,0,0,-31,6,-37,0,8,0,56,0,-30,6,56, -0,-29,6,-37,0,-28,6,-37,0,-27,6,-37,0,-26,6,2,0,-123,0,2,0,20,0,4,0,-25,6,-36,0,4,0,4, -0,-35,5,4,0,-24,6,4,0,-31,5,4,0,-23,6,-35,0,2,0,4,0,-22,6,4,0,-21,6,-34,0,9,0,7, -0,-20,6,7,0,-19,6,7,0,-18,6,4,0,20,0,4,0,13,1,7,0,-19,3,7,0,-17,6,4,0,37,0,-33, -0,-16,6,-32,0,6,0,0,0,-15,6,0,0,-75,5,48,0,-116,0,2,0,109,0,2,0,111,4,4,0,37,0,-31, -0,21,0,-31,0,0,0,-31,0,1,0,4,0,57,0,4,0,23,0,4,0,28,0,4,0,-14,6,4,0,-13,6,4, -0,-12,6,-38,0,-11,6,0,0,-15,6,4,0,-10,6,4,0,-9,6,-32,0,-12,2,-36,0,-8,6,-35,0,-7,6,-34, -0,-6,6,-37,0,-5,6,-37,0,-4,6,-37,0,-3,6,56,0,-2,6,56,0,-1,6,-30,0,12,0,0,0,-68,1,9, -0,-62,0,0,0,-61,0,4,0,-58,0,4,0,-50,0,9,0,-57,0,7,0,-55,0,7,0,-54,0,9,0,0,7,9, -0,1,7,9,0,-53,0,9,0,-51,0,-29,0,43,0,-29,0,0,0,-29,0,1,0,9,0,2,7,9,0,26,0,0, -0,27,0,4,0,20,0,4,0,18,0,4,0,23,0,4,0,91,0,4,0,3,7,4,0,4,7,4,0,-13,6,4, -0,-12,6,4,0,5,7,4,0,-39,0,4,0,6,7,4,0,7,7,7,0,8,7,7,0,9,7,4,0,-126,0,4, -0,10,7,-31,0,11,7,36,0,79,0,-79,0,-89,6,48,0,-116,0,7,0,12,7,7,0,13,7,-30,0,2,1,-29, -0,14,7,-29,0,15,7,-29,0,16,7,12,0,17,7,-28,0,18,7,-27,0,19,7,7,0,20,7,7,0,21,7,4, -0,-84,6,7,0,22,7,9,0,23,7,4,0,24,7,4,0,25,7,4,0,26,7,7,0,27,7,-26,0,4,0,-26, -0,0,0,-26,0,1,0,12,0,28,7,-29,0,29,7,-25,0,6,0,12,0,30,7,12,0,17,7,12,0,31,7,2, -0,20,0,2,0,37,0,4,0,57,0,-24,0,4,0,7,0,32,7,7,0,112,0,2,0,33,7,2,0,34,7,-23, -0,6,0,7,0,35,7,7,0,36,7,7,0,37,7,7,0,38,7,4,0,39,7,4,0,40,7,-22,0,12,0,7, -0,41,7,7,0,42,7,7,0,43,7,7,0,44,7,7,0,45,7,7,0,46,7,7,0,47,7,7,0,48,7,7, -0,49,7,7,0,50,7,4,0,-110,2,4,0,51,7,-21,0,2,0,7,0,-55,4,7,0,37,0,-20,0,7,0,7, -0,52,7,7,0,53,7,4,0,93,0,4,0,108,2,4,0,54,7,4,0,55,7,4,0,37,0,-19,0,6,0,-19, -0,0,0,-19,0,1,0,2,0,18,0,2,0,20,0,2,0,56,7,2,0,57,0,-18,0,8,0,-18,0,0,0,-18, -0,1,0,2,0,18,0,2,0,20,0,2,0,56,7,2,0,57,0,7,0,23,0,7,0,-126,0,-17,0,45,0,-17, -0,0,0,-17,0,1,0,2,0,18,0,2,0,20,0,2,0,56,7,2,0,-43,0,2,0,-103,3,2,0,57,7,7, -0,58,7,7,0,92,0,7,0,-97,2,4,0,59,7,4,0,81,0,4,0,110,2,7,0,60,7,7,0,61,7,7, -0,62,7,7,0,63,7,7,0,64,7,7,0,65,7,7,0,-100,2,7,0,-1,0,7,0,66,7,7,0,67,7,7, -0,37,0,7,0,68,7,7,0,69,7,7,0,70,7,2,0,71,7,2,0,72,7,2,0,73,7,2,0,74,7,2, -0,75,7,2,0,76,7,2,0,77,7,2,0,78,7,2,0,123,5,2,0,79,7,2,0,-47,1,2,0,80,7,0, -0,81,7,0,0,82,7,7,0,-45,0,-16,0,83,7,63,0,-95,1,-15,0,16,0,-15,0,0,0,-15,0,1,0,2, -0,18,0,2,0,20,0,2,0,56,7,2,0,-43,0,7,0,-105,2,7,0,-104,2,7,0,-103,2,7,0,-5,1,7, -0,-102,2,7,0,-101,2,7,0,84,7,7,0,-100,2,7,0,-98,2,7,0,-97,2,-59,0,5,0,2,0,18,0,2, -0,-25,6,2,0,20,0,2,0,85,7,27,0,-9,5,-60,0,3,0,4,0,69,0,4,0,86,7,-59,0,2,0,-14, -0,12,0,-14,0,0,0,-14,0,1,0,2,0,18,0,2,0,20,0,2,0,31,3,2,0,-32,1,7,0,5,0,7, -0,6,0,7,0,87,7,7,0,88,7,27,0,-9,5,12,0,89,7,-13,0,11,0,-13,0,0,0,-13,0,1,0,0, -0,17,0,2,0,18,0,2,0,90,7,4,0,22,0,4,0,91,7,2,0,20,0,2,0,37,0,9,0,92,7,9, -0,93,7,-12,0,5,0,0,0,17,0,7,0,20,1,7,0,94,7,4,0,95,7,4,0,37,0,-11,0,4,0,2, -0,18,0,2,0,20,0,2,0,43,0,2,0,70,0,-10,0,4,0,0,0,17,0,62,0,96,7,7,0,20,1,7, -0,37,0,-9,0,6,0,2,0,97,7,2,0,98,7,2,0,18,0,2,0,99,7,0,0,100,7,0,0,101,7,-8, -0,5,0,4,0,18,0,4,0,37,0,0,0,17,0,0,0,102,7,0,0,103,7,-7,0,3,0,4,0,18,0,4, -0,37,0,0,0,17,0,-6,0,4,0,2,0,104,7,2,0,105,7,2,0,20,0,2,0,37,0,-5,0,6,0,0, -0,17,0,0,0,106,7,2,0,107,7,2,0,-100,2,2,0,13,1,2,0,70,0,-4,0,5,0,0,0,17,0,7, -0,112,0,7,0,-17,3,2,0,20,0,2,0,122,2,-3,0,3,0,0,0,17,0,4,0,110,2,4,0,104,7,-2, -0,7,0,0,0,17,0,7,0,-17,3,0,0,108,7,0,0,109,7,2,0,13,1,2,0,43,0,4,0,110,7,-1, -0,3,0,32,0,111,7,0,0,112,7,0,0,113,7,0,1,18,0,0,1,0,0,0,1,1,0,2,0,18,0,2, -0,90,7,2,0,20,0,2,0,114,7,2,0,115,7,2,0,116,7,2,0,43,0,2,0,70,0,0,0,17,0,9, -0,2,0,1,1,117,7,32,0,45,0,2,0,-47,4,2,0,20,7,2,0,118,7,2,0,37,0,2,1,11,0,0, -0,17,0,0,0,18,0,0,0,119,7,2,0,20,0,2,0,122,2,2,0,120,7,4,0,121,7,4,0,122,7,4, -0,123,7,4,0,124,7,4,0,125,7,3,1,1,0,0,0,126,7,4,1,4,0,42,0,-36,5,0,0,127,7,4, -0,13,1,4,0,20,0,1,1,18,0,1,1,0,0,1,1,1,0,1,1,-128,7,2,0,18,0,2,0,20,0,2, -0,-127,7,2,0,116,7,2,0,90,7,2,0,-126,7,2,0,70,0,2,0,12,1,0,0,17,0,9,0,2,0,5, -1,117,7,0,1,-125,7,2,0,15,0,2,0,-124,7,4,0,-123,7,6,1,3,0,4,0,-74,2,4,0,37,0,32, -0,45,0,7,1,12,0,-111,0,-122,7,2,0,18,0,2,0,20,0,4,0,58,7,4,0,92,0,0,0,17,0,0, -0,-121,7,2,0,-120,7,2,0,-119,7,2,0,-118,7,2,0,-117,7,7,0,-116,7,8,1,10,0,2,0,20,0,2, -0,-115,7,4,0,58,7,4,0,92,0,2,0,-114,7,-28,0,18,7,2,0,18,0,2,0,-113,7,2,0,-112,7,2, -0,-111,7,9,1,7,0,2,0,20,0,2,0,-115,7,4,0,58,7,4,0,92,0,2,0,18,0,2,0,-110,7,7, -0,109,3,10,1,11,0,4,0,-74,2,2,0,18,0,2,0,20,0,32,0,45,0,74,0,-109,7,0,0,17,0,7, -0,-108,7,7,0,-107,7,7,0,21,3,2,0,-106,7,2,0,-105,7,11,1,5,0,2,0,18,0,2,0,20,0,4, -0,37,0,-79,0,-89,6,32,0,39,5,12,1,5,0,4,0,20,0,4,0,18,0,0,0,17,0,0,0,102,7,32, -0,45,0,13,1,13,0,2,0,20,0,2,0,18,0,2,0,90,7,2,0,22,3,7,0,-104,7,7,0,-103,7,7, -0,7,1,7,0,8,1,7,0,-3,2,7,0,0,3,7,0,-102,7,7,0,-101,7,32,0,-100,7,14,1,10,0,2, -0,20,0,2,0,18,0,4,0,58,7,4,0,92,0,0,0,17,0,0,0,-121,7,2,0,43,0,2,0,64,0,2, -0,-99,7,2,0,-98,7,15,1,8,0,32,0,45,0,7,0,-103,2,7,0,-97,7,7,0,-96,7,7,0,-108,2,2, -0,20,0,2,0,122,2,7,0,-95,7,16,1,12,0,2,0,18,0,2,0,13,1,2,0,20,0,2,0,-100,2,2, -0,-74,2,2,0,-94,7,4,0,37,0,7,0,-93,7,7,0,-92,7,7,0,-91,7,7,0,-90,7,0,0,-89,7,17, -1,10,0,2,0,20,0,2,0,18,0,4,0,58,7,4,0,92,0,0,0,17,0,2,0,68,2,2,0,64,0,2, -0,-99,7,2,0,-98,7,63,0,-95,1,18,1,7,0,4,0,110,2,4,0,-88,7,4,0,-87,7,4,0,-86,7,7, -0,-85,7,7,0,-84,7,0,0,108,7,19,1,7,0,0,0,-83,7,32,0,-82,7,0,0,112,7,2,0,-81,7,2, -0,43,0,4,0,70,0,0,0,113,7,20,1,6,0,2,0,20,0,2,0,18,0,4,0,58,7,4,0,92,0,0, -0,-80,7,0,0,-79,7,21,1,1,0,4,0,20,0,22,1,6,0,0,0,95,0,2,0,18,0,2,0,20,0,4, -0,-78,7,7,0,-77,7,42,0,-36,5,23,1,4,0,0,0,-74,0,2,0,20,0,4,0,18,0,32,0,45,0,24, -1,2,0,4,0,18,0,4,0,-121,5,5,1,10,0,5,1,0,0,5,1,1,0,5,1,-128,7,2,0,18,0,2, -0,20,0,2,0,90,7,2,0,-76,7,0,0,17,0,9,0,2,0,32,0,45,0,25,1,10,0,7,0,21,3,7, -0,-75,7,7,0,-74,7,7,0,-73,7,7,0,-72,7,4,0,20,0,7,0,-94,7,7,0,-71,7,7,0,-70,7,7, -0,37,0,-28,0,20,0,27,0,31,0,0,0,-63,0,26,1,-69,7,9,0,-68,7,43,0,-104,0,43,0,-67,7,9, -0,-66,7,36,0,79,0,7,0,109,3,7,0,-65,7,7,0,-64,7,7,0,-63,7,7,0,-62,7,7,0,-61,7,7, -0,-60,7,4,0,93,0,4,0,-59,7,0,0,-58,7,0,0,-57,7,0,0,-56,7,27,1,6,0,27,0,31,0,7, -0,-55,7,7,0,-54,7,7,0,-53,7,2,0,-52,7,2,0,-51,7,28,1,14,0,-75,0,0,0,-75,0,1,0,4, -0,75,5,7,0,76,5,-74,0,77,5,-69,0,-108,5,-28,0,18,7,2,0,13,1,2,0,-115,7,2,0,8,2,2, -0,9,2,2,0,20,0,2,0,-98,5,4,0,70,0,29,1,6,0,29,1,0,0,29,1,1,0,32,0,45,0,9, -0,-50,7,4,0,-38,0,4,0,37,0,63,0,4,0,27,0,31,0,12,0,-49,7,4,0,-121,0,7,0,-48,7,30, -1,25,0,30,1,0,0,30,1,1,0,30,1,38,0,12,0,-47,7,0,0,17,0,7,0,-46,7,7,0,-45,7,7, -0,-44,7,7,0,-43,7,4,0,20,0,7,0,-42,7,7,0,-41,7,7,0,-40,7,7,0,20,1,7,0,-39,1,7, -0,-39,7,7,0,108,2,7,0,-38,7,7,0,-37,7,7,0,-36,7,7,0,-35,7,7,0,-34,7,7,0,-81,0,2, -0,-121,0,2,0,-31,4,31,1,19,0,27,0,31,0,12,0,-33,7,12,0,-32,7,4,0,20,0,4,0,30,4,2, -0,-96,2,2,0,-31,7,2,0,-121,0,2,0,-30,7,2,0,-29,7,2,0,-28,7,2,0,-27,7,2,0,-26,7,4, -0,-25,7,4,0,-24,7,4,0,-23,7,4,0,-22,7,4,0,-21,7,4,0,-20,7,32,1,34,0,32,1,0,0,32, -1,1,0,12,0,49,3,0,0,17,0,2,0,20,0,2,0,-19,7,2,0,-18,7,2,0,-17,7,2,0,10,3,2, -0,-16,7,4,0,-7,1,4,0,-23,7,4,0,-22,7,30,1,-15,7,32,1,38,0,32,1,-14,7,12,0,-13,7,9, -0,-12,7,9,0,-11,7,9,0,-10,7,7,0,7,1,7,0,-81,0,7,0,-57,1,7,0,-9,7,7,0,-8,7,7, -0,2,3,7,0,-7,7,7,0,-6,7,7,0,-5,7,7,0,-4,7,7,0,-3,7,7,0,-2,7,7,0,-10,1,32, -0,-1,7,-110,0,9,0,12,0,0,8,2,0,20,0,2,0,1,8,7,0,20,3,7,0,2,8,7,0,3,8,12, -0,4,8,4,0,5,8,4,0,37,0,33,1,7,0,33,1,0,0,33,1,1,0,12,0,-58,7,4,0,20,0,4, -0,6,8,0,0,17,0,-47,0,7,8,34,1,8,0,34,1,0,0,34,1,1,0,33,1,8,8,36,0,79,0,12, -0,-6,2,4,0,20,0,0,0,17,0,4,0,9,8,-111,0,6,0,27,0,31,0,12,0,0,8,12,0,10,8,12, -0,103,0,4,0,11,8,4,0,37,0,35,1,16,0,-75,0,0,0,-75,0,1,0,4,0,75,5,7,0,76,5,-74, -0,77,5,2,0,78,5,-69,0,-108,5,-111,0,-9,2,0,0,13,1,0,0,-37,5,2,0,20,0,2,0,12,8,2, -0,-101,5,2,0,-98,5,2,0,13,8,7,0,14,8,36,1,5,0,36,1,0,0,36,1,1,0,36,0,79,0,2, -0,20,0,0,0,15,8,37,1,12,0,37,1,0,0,37,1,1,0,9,0,2,0,2,0,18,0,2,0,20,0,0, -0,16,8,0,0,17,8,0,0,15,8,7,0,18,8,7,0,19,8,4,0,37,0,36,0,79,0,38,1,9,0,38, -1,0,0,38,1,1,0,32,0,20,8,0,0,21,8,7,0,22,8,2,0,23,8,2,0,20,0,2,0,18,0,2, -0,37,0,39,1,7,0,42,0,-36,5,26,0,24,8,4,0,20,0,4,0,25,8,12,0,26,8,32,0,20,8,0, -0,21,8,40,1,12,0,32,0,20,8,2,0,27,8,2,0,20,0,2,0,28,8,2,0,29,8,0,0,21,8,32, -0,30,8,0,0,31,8,7,0,32,8,7,0,-39,1,7,0,33,8,7,0,34,8,41,1,6,0,32,0,20,8,4, -0,9,8,4,0,35,8,4,0,93,0,4,0,37,0,0,0,21,8,42,1,4,0,32,0,20,8,4,0,20,0,4, -0,9,8,0,0,21,8,43,1,4,0,32,0,20,8,4,0,20,0,4,0,9,8,0,0,21,8,44,1,10,0,32, -0,20,8,4,0,36,8,7,0,-127,0,4,0,20,0,2,0,-42,5,2,0,37,8,2,0,43,0,2,0,70,0,7, -0,38,8,0,0,21,8,45,1,4,0,32,0,20,8,4,0,20,0,4,0,9,8,0,0,21,8,46,1,10,0,32, -0,20,8,2,0,18,0,2,0,-95,3,4,0,91,0,4,0,92,0,7,0,-97,7,7,0,-96,7,4,0,37,0,-111, -0,-122,7,0,0,21,8,47,1,4,0,32,0,20,8,4,0,7,3,4,0,39,8,0,0,21,8,48,1,5,0,32, -0,20,8,7,0,-127,0,4,0,40,8,4,0,7,3,4,0,8,3,49,1,6,0,32,0,20,8,4,0,41,8,4, -0,42,8,7,0,43,8,7,0,44,8,0,0,21,8,50,1,16,0,32,0,20,8,32,0,-14,7,4,0,18,0,7, -0,45,8,7,0,46,8,7,0,47,8,7,0,48,8,7,0,49,8,7,0,50,8,7,0,51,8,7,0,52,8,7, -0,53,8,2,0,20,0,2,0,37,0,2,0,43,0,2,0,70,0,51,1,3,0,32,0,20,8,4,0,20,0,4, -0,123,5,52,1,5,0,32,0,20,8,4,0,20,0,4,0,37,0,7,0,54,8,0,0,21,8,53,1,10,0,32, -0,20,8,0,0,21,8,2,0,55,8,2,0,56,8,0,0,57,8,0,0,58,8,7,0,59,8,7,0,60,8,7, -0,61,8,7,0,62,8,54,1,8,0,7,0,9,0,7,0,10,0,7,0,11,0,7,0,12,0,7,0,63,8,7, -0,64,8,2,0,20,0,2,0,123,5,55,1,8,0,7,0,9,0,7,0,10,0,7,0,11,0,7,0,12,0,7, -0,63,8,7,0,64,8,2,0,20,0,2,0,123,5,56,1,8,0,7,0,9,0,7,0,10,0,7,0,11,0,7, -0,12,0,7,0,63,8,7,0,64,8,2,0,20,0,2,0,123,5,57,1,7,0,32,0,20,8,0,0,21,8,7, -0,20,1,7,0,30,1,2,0,20,0,2,0,13,1,4,0,37,0,58,1,5,0,32,0,-45,2,7,0,20,1,2, -0,-41,2,0,0,-39,2,0,0,65,8,59,1,10,0,59,1,0,0,59,1,1,0,2,0,18,0,2,0,20,0,0, -0,66,8,7,0,-36,0,7,0,-35,0,2,0,-58,7,2,0,67,8,32,0,45,0,60,1,22,0,60,1,0,0,60, -1,1,0,2,0,20,0,2,0,13,1,2,0,68,8,2,0,69,8,36,0,79,0,-111,0,-122,7,32,0,-89,0,7, -0,91,0,7,0,92,0,7,0,70,8,7,0,71,8,7,0,72,8,7,0,73,8,7,0,-107,2,7,0,-67,1,7, -0,-120,7,7,0,74,8,0,0,75,8,0,0,76,8,12,0,-4,2,61,1,8,0,7,0,-31,1,7,0,-97,7,7, -0,-96,7,9,0,2,0,2,0,77,8,2,0,78,8,2,0,79,8,2,0,80,8,62,1,18,0,62,1,0,0,62, -1,1,0,62,1,81,8,0,0,17,0,61,1,82,8,2,0,18,0,2,0,20,0,2,0,83,8,2,0,84,8,2, -0,85,8,2,0,86,8,4,0,43,0,7,0,87,8,7,0,88,8,4,0,89,8,4,0,90,8,62,1,91,8,63, -1,92,8,64,1,32,0,64,1,0,0,64,1,1,0,64,1,93,8,0,0,17,0,0,0,94,8,2,0,18,0,2, -0,20,0,2,0,-14,6,2,0,20,7,2,0,95,8,2,0,-119,0,2,0,84,8,2,0,-25,6,12,0,-127,7,12, -0,96,8,27,0,-9,5,9,0,97,8,7,0,87,8,7,0,88,8,7,0,-5,1,7,0,98,8,2,0,99,8,2, -0,100,8,7,0,101,8,7,0,102,8,2,0,103,8,2,0,104,8,24,0,105,8,24,0,106,8,24,0,107,8,65, -1,-103,0,66,1,108,8,63,1,6,0,63,1,0,0,63,1,1,0,64,1,109,8,64,1,110,8,62,1,111,8,62, -1,91,8,57,0,16,0,27,0,31,0,12,0,112,8,12,0,113,8,61,1,114,8,12,0,115,8,4,0,18,0,4, -0,116,8,4,0,117,8,4,0,118,8,12,0,119,8,66,1,120,8,62,1,121,8,62,1,122,8,9,0,123,8,9, -0,124,8,4,0,125,8,67,1,6,0,4,0,-128,0,4,0,-126,0,4,0,-25,6,0,0,126,8,0,0,127,8,2, -0,37,0,68,1,16,0,2,0,-86,6,2,0,-85,6,2,0,-128,8,2,0,-74,7,2,0,-127,8,2,0,68,0,7, -0,-108,2,7,0,-126,8,7,0,-125,8,2,0,34,1,0,0,-124,8,0,0,42,4,2,0,-123,8,2,0,37,0,4, -0,-122,8,4,0,-121,8,69,1,9,0,7,0,-120,8,7,0,-119,8,7,0,-60,7,7,0,112,0,7,0,-118,8,7, -0,71,5,2,0,-117,8,0,0,-116,8,0,0,37,0,70,1,4,0,7,0,-115,8,7,0,-114,8,2,0,-117,8,2, -0,37,0,71,1,3,0,7,0,-113,8,7,0,-112,8,7,0,15,0,72,1,7,0,0,0,-68,1,2,0,109,4,2, -0,110,4,2,0,111,4,2,0,62,4,4,0,-126,0,4,0,-97,3,73,1,7,0,7,0,-111,8,7,0,-110,8,7, -0,-109,8,7,0,4,2,7,0,-108,8,7,0,-107,8,7,0,-106,8,74,1,4,0,2,0,-105,8,2,0,-104,8,2, -0,-103,8,2,0,-102,8,75,1,2,0,7,0,5,0,7,0,6,0,76,1,2,0,0,0,-87,0,0,0,-101,8,77, -1,1,0,0,0,17,0,78,1,10,0,0,0,-100,8,0,0,-99,8,0,0,-98,8,0,0,-97,8,2,0,-128,8,2, -0,-96,8,7,0,-95,8,7,0,-94,8,7,0,-93,8,7,0,-67,1,79,1,2,0,9,0,-92,8,9,0,-91,8,80, -1,11,0,0,0,111,4,0,0,18,0,0,0,-117,8,0,0,112,0,0,0,-90,8,0,0,109,0,0,0,-74,0,7, -0,-89,8,7,0,-88,8,7,0,-87,8,7,0,-86,8,81,1,8,0,7,0,97,7,7,0,-127,0,7,0,42,4,7, -0,72,2,7,0,-85,8,7,0,-49,0,7,0,-84,8,4,0,18,0,82,1,4,0,2,0,-83,8,2,0,-82,8,2, -0,-81,8,2,0,37,0,83,1,1,0,0,0,17,0,84,1,4,0,7,0,5,0,7,0,6,0,2,0,20,0,2, -0,-80,8,85,1,10,0,2,0,-120,3,2,0,20,0,7,0,-17,3,7,0,-79,8,7,0,-78,8,7,0,-77,8,7, -0,-76,8,84,1,-75,8,84,1,-74,8,84,1,-73,8,60,0,9,0,4,0,20,0,4,0,64,0,24,0,-72,8,24, -0,-71,8,85,1,-70,8,7,0,-69,8,7,0,-68,8,7,0,-67,8,7,0,-66,8,86,1,4,0,46,0,-114,2,7, -0,-65,8,7,0,92,1,7,0,37,0,-87,0,13,0,27,0,31,0,2,0,20,0,2,0,72,5,4,0,109,0,7, -0,-64,8,7,0,1,2,7,0,-63,8,7,0,-62,8,7,0,92,1,2,0,47,1,2,0,37,0,50,0,77,1,86, -1,-61,8,87,1,10,0,4,0,18,0,4,0,-127,0,4,0,20,0,4,0,70,3,4,0,-60,8,4,0,-59,8,4, -0,-58,8,0,0,95,0,0,0,17,0,9,0,2,0,84,0,6,0,87,1,-57,8,4,0,-56,8,4,0,-55,8,4, -0,-54,8,4,0,37,0,9,0,-53,8,88,1,5,0,7,0,66,2,7,0,-74,2,7,0,-39,1,2,0,-52,8,2, -0,37,0,89,1,5,0,7,0,66,2,7,0,-51,8,7,0,-50,8,7,0,-49,8,7,0,-74,2,90,1,7,0,4, -0,-48,8,4,0,-47,8,4,0,-46,8,7,0,-45,8,7,0,-44,8,7,0,-43,8,7,0,-42,8,91,1,26,0,32, -0,-41,8,89,1,66,3,89,1,-40,8,88,1,-39,8,89,1,83,7,7,0,-38,8,7,0,-37,8,7,0,-36,8,7, -0,-35,8,7,0,-44,8,7,0,-43,8,7,0,-74,2,7,0,-97,2,7,0,-34,8,7,0,-33,8,7,0,109,0,7, -0,-32,8,4,0,-48,8,4,0,-31,8,4,0,37,0,4,0,81,0,4,0,-30,8,2,0,20,0,2,0,-29,8,2, -0,-28,8,2,0,100,3,92,1,112,0,27,0,31,0,4,0,20,0,2,0,18,0,2,0,55,8,2,0,-27,8,2, -0,-26,8,2,0,-25,8,2,0,-24,8,2,0,-23,8,2,0,-22,8,2,0,-21,8,2,0,-20,8,2,0,-19,8,2, -0,-18,8,2,0,-17,8,2,0,-16,8,2,0,-15,8,2,0,-14,8,2,0,-13,8,2,0,-47,1,2,0,76,7,2, -0,51,7,2,0,-12,8,2,0,-11,8,2,0,98,3,2,0,99,3,2,0,-10,8,2,0,-9,8,2,0,-8,8,2, -0,-7,8,2,0,-6,8,2,0,-5,8,7,0,-4,8,7,0,-3,8,7,0,-2,8,2,0,-1,8,2,0,0,9,7, -0,1,9,7,0,2,9,7,0,3,9,7,0,58,7,7,0,92,0,7,0,-97,2,7,0,64,7,7,0,4,9,7, -0,5,9,7,0,6,9,7,0,7,9,7,0,57,0,4,0,59,7,4,0,57,7,4,0,8,9,7,0,60,7,7, -0,61,7,7,0,62,7,7,0,9,9,7,0,10,9,7,0,11,9,7,0,12,9,7,0,13,9,7,0,14,9,7, -0,15,9,7,0,16,9,7,0,21,3,7,0,109,0,7,0,17,9,7,0,18,9,7,0,19,9,7,0,20,9,7, -0,21,9,7,0,22,9,7,0,108,2,7,0,23,9,7,0,24,9,4,0,25,9,4,0,26,9,7,0,27,9,7, -0,28,9,7,0,29,9,7,0,30,9,7,0,31,9,7,0,32,9,7,0,33,9,7,0,34,9,7,0,94,3,7, -0,92,3,7,0,93,3,7,0,35,9,7,0,36,9,7,0,37,9,7,0,38,9,7,0,39,9,7,0,40,9,7, -0,41,9,7,0,42,9,7,0,43,9,7,0,28,3,7,0,44,9,7,0,45,9,7,0,46,9,7,0,47,9,7, -0,48,9,7,0,49,9,7,0,50,9,0,0,51,9,63,0,55,3,63,0,52,9,32,0,53,9,32,0,54,9,36, -0,79,0,-108,0,53,3,-108,0,55,9,-120,0,37,0,-120,0,0,0,-120,0,1,0,92,1,56,9,91,1,-121,3,90, -1,-14,7,93,1,57,9,94,1,58,9,94,1,59,9,12,0,60,9,12,0,61,9,-107,0,54,3,32,0,62,9,32, -0,63,9,32,0,64,9,12,0,65,9,12,0,66,9,7,0,-45,0,7,0,83,4,4,0,110,2,4,0,20,0,4, -0,59,7,4,0,67,9,4,0,68,9,4,0,69,9,4,0,57,0,2,0,-38,0,2,0,70,9,2,0,71,9,2, -0,72,9,2,0,47,3,2,0,73,9,0,0,74,9,2,0,75,9,2,0,76,9,2,0,77,9,9,0,78,9,125, -0,-76,3,123,0,34,0,95,1,79,9,7,0,-106,3,7,0,80,9,7,0,81,9,7,0,-14,3,7,0,82,9,7, -0,31,3,7,0,21,3,7,0,83,9,7,0,3,2,7,0,84,9,7,0,85,9,7,0,86,9,7,0,87,9,7, -0,88,9,7,0,89,9,7,0,-105,3,7,0,90,9,7,0,91,9,7,0,92,9,7,0,-104,3,7,0,-108,3,7, -0,-107,3,4,0,93,9,4,0,93,0,4,0,94,9,4,0,95,9,2,0,96,9,2,0,97,9,2,0,98,9,2, -0,99,9,2,0,100,9,2,0,37,0,4,0,70,0,124,0,8,0,95,1,101,9,7,0,102,9,7,0,103,9,7, -0,-94,1,7,0,104,9,4,0,93,0,2,0,105,9,2,0,106,9,96,1,4,0,7,0,5,0,7,0,6,0,7, -0,7,0,7,0,107,9,97,1,6,0,97,1,0,0,97,1,1,0,96,1,108,9,4,0,109,9,2,0,110,9,2, -0,20,0,98,1,5,0,98,1,0,0,98,1,1,0,12,0,111,9,4,0,112,9,4,0,20,0,99,1,9,0,99, -1,0,0,99,1,1,0,12,0,-128,0,98,1,113,9,4,0,20,0,2,0,110,9,2,0,114,9,7,0,94,0,0, -0,115,9,-70,0,5,0,12,0,125,4,4,0,20,0,2,0,116,9,2,0,117,9,9,0,118,9,69,78,68,66,0, -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -}; -int DNAlen= sizeof(DNAstr); +unsigned char DNAstr[] = { + 83, 68, 78, 65, 78, 65, 77, 69, 119, 9, 0, 0, 42, 110, 101, 120, 116, 0, 42, 112, 114, 101, 118, 0, 42, 100, 97, 116, 97, 0, 42, 102, 105, + 114, 115, 116, 0, 42, 108, 97, 115, 116, 0, 120, 0, 121, 0, 122, 0, 119, 0, 120, 109, 105, 110, 0, 120, 109, 97, 120, 0, 121, 109, 105, 110, + 0, 121, 109, 97, 120, 0, 42, 112, 111, 105, 110, 116, 101, 114, 0, 103, 114, 111, 117, 112, 0, 118, 97, 108, 0, 118, 97, 108, 50, 0, 110, 97, + 109, 101, 91, 51, 50, 93, 0, 116, 121, 112, 101, 0, 115, 117, 98, 116, 121, 112, 101, 0, 102, 108, 97, 103, 0, 115, 97, 118, 101, 100, 0, 100, + 97, 116, 97, 0, 108, 101, 110, 0, 116, 111, 116, 97, 108, 108, 101, 110, 0, 42, 110, 101, 119, 105, 100, 0, 42, 108, 105, 98, 0, 110, 97, 109, + 101, 91, 50, 52, 93, 0, 117, 115, 0, 105, 99, 111, 110, 95, 105, 100, 0, 42, 112, 114, 111, 112, 101, 114, 116, 105, 101, 115, 0, 105, 100, 0, + 42, 105, 100, 98, 108, 111, 99, 107, 0, 42, 102, 105, 108, 101, 100, 97, 116, 97, 0, 110, 97, 109, 101, 91, 50, 52, 48, 93, 0, 102, 105, 108, + 101, 110, 97, 109, 101, 91, 50, 52, 48, 93, 0, 116, 111, 116, 0, 112, 97, 100, 0, 42, 112, 97, 114, 101, 110, 116, 0, 119, 91, 50, 93, 0, + 104, 91, 50, 93, 0, 99, 104, 97, 110, 103, 101, 100, 91, 50, 93, 0, 112, 97, 100, 48, 0, 112, 97, 100, 49, 0, 42, 114, 101, 99, 116, 91, + 50, 93, 0, 42, 111, 98, 0, 98, 108, 111, 99, 107, 116, 121, 112, 101, 0, 97, 100, 114, 99, 111, 100, 101, 0, 110, 97, 109, 101, 91, 49, 50, + 56, 93, 0, 42, 98, 112, 0, 42, 98, 101, 122, 116, 0, 109, 97, 120, 114, 99, 116, 0, 116, 111, 116, 114, 99, 116, 0, 118, 97, 114, 116, 121, + 112, 101, 0, 116, 111, 116, 118, 101, 114, 116, 0, 105, 112, 111, 0, 101, 120, 116, 114, 97, 112, 0, 114, 116, 0, 98, 105, 116, 109, 97, 115, 107, + 0, 115, 108, 105, 100, 101, 95, 109, 105, 110, 0, 115, 108, 105, 100, 101, 95, 109, 97, 120, 0, 99, 117, 114, 118, 97, 108, 0, 42, 100, 114, 105, + 118, 101, 114, 0, 99, 117, 114, 118, 101, 0, 99, 117, 114, 0, 115, 104, 111, 119, 107, 101, 121, 0, 109, 117, 116, 101, 105, 112, 111, 0, 112, 111, + 115, 0, 114, 101, 108, 97, 116, 105, 118, 101, 0, 116, 111, 116, 101, 108, 101, 109, 0, 112, 97, 100, 50, 0, 42, 119, 101, 105, 103, 104, 116, 115, + 0, 118, 103, 114, 111, 117, 112, 91, 51, 50, 93, 0, 115, 108, 105, 100, 101, 114, 109, 105, 110, 0, 115, 108, 105, 100, 101, 114, 109, 97, 120, 0, + 42, 114, 101, 102, 107, 101, 121, 0, 101, 108, 101, 109, 115, 116, 114, 91, 51, 50, 93, 0, 101, 108, 101, 109, 115, 105, 122, 101, 0, 98, 108, 111, + 99, 107, 0, 42, 105, 112, 111, 0, 42, 102, 114, 111, 109, 0, 116, 111, 116, 107, 101, 121, 0, 115, 108, 117, 114, 112, 104, 0, 42, 42, 115, 99, + 114, 105, 112, 116, 115, 0, 42, 102, 108, 97, 103, 0, 97, 99, 116, 115, 99, 114, 105, 112, 116, 0, 116, 111, 116, 115, 99, 114, 105, 112, 116, 0, + 42, 108, 105, 110, 101, 0, 42, 102, 111, 114, 109, 97, 116, 0, 98, 108, 101, 110, 0, 108, 105, 110, 101, 110, 111, 0, 115, 116, 97, 114, 116, 0, + 101, 110, 100, 0, 102, 108, 97, 103, 115, 0, 99, 111, 108, 111, 114, 91, 52, 93, 0, 112, 97, 100, 91, 52, 93, 0, 42, 110, 97, 109, 101, 0, + 110, 108, 105, 110, 101, 115, 0, 108, 105, 110, 101, 115, 0, 42, 99, 117, 114, 108, 0, 42, 115, 101, 108, 108, 0, 99, 117, 114, 99, 0, 115, 101, + 108, 99, 0, 109, 97, 114, 107, 101, 114, 115, 0, 42, 117, 110, 100, 111, 95, 98, 117, 102, 0, 117, 110, 100, 111, 95, 112, 111, 115, 0, 117, 110, + 100, 111, 95, 108, 101, 110, 0, 42, 99, 111, 109, 112, 105, 108, 101, 100, 0, 109, 116, 105, 109, 101, 0, 115, 105, 122, 101, 0, 115, 101, 101, 107, + 0, 112, 97, 115, 115, 101, 112, 97, 114, 116, 97, 108, 112, 104, 97, 0, 97, 110, 103, 108, 101, 0, 99, 108, 105, 112, 115, 116, 97, 0, 99, 108, + 105, 112, 101, 110, 100, 0, 108, 101, 110, 115, 0, 111, 114, 116, 104, 111, 95, 115, 99, 97, 108, 101, 0, 100, 114, 97, 119, 115, 105, 122, 101, 0, + 115, 104, 105, 102, 116, 120, 0, 115, 104, 105, 102, 116, 121, 0, 89, 70, 95, 100, 111, 102, 100, 105, 115, 116, 0, 89, 70, 95, 97, 112, 101, 114, + 116, 117, 114, 101, 0, 89, 70, 95, 98, 107, 104, 116, 121, 112, 101, 0, 89, 70, 95, 98, 107, 104, 98, 105, 97, 115, 0, 89, 70, 95, 98, 107, + 104, 114, 111, 116, 0, 115, 99, 114, 105, 112, 116, 108, 105, 110, 107, 0, 42, 100, 111, 102, 95, 111, 98, 0, 102, 114, 97, 109, 101, 110, 114, 0, + 102, 114, 97, 109, 101, 115, 0, 111, 102, 102, 115, 101, 116, 0, 115, 102, 114, 97, 0, 102, 105, 101, 95, 105, 109, 97, 0, 99, 121, 99, 108, 0, + 111, 107, 0, 109, 117, 108, 116, 105, 95, 105, 110, 100, 101, 120, 0, 108, 97, 121, 101, 114, 0, 112, 97, 115, 115, 0, 109, 101, 110, 117, 110, 114, + 0, 105, 98, 117, 102, 115, 0, 42, 103, 112, 117, 116, 101, 120, 116, 117, 114, 101, 0, 42, 97, 110, 105, 109, 0, 42, 114, 114, 0, 115, 111, 117, + 114, 99, 101, 0, 108, 97, 115, 116, 102, 114, 97, 109, 101, 0, 116, 112, 97, 103, 101, 102, 108, 97, 103, 0, 116, 111, 116, 98, 105, 110, 100, 0, + 120, 114, 101, 112, 0, 121, 114, 101, 112, 0, 116, 119, 115, 116, 97, 0, 116, 119, 101, 110, 100, 0, 98, 105, 110, 100, 99, 111, 100, 101, 0, 42, + 114, 101, 112, 98, 105, 110, 100, 0, 42, 112, 97, 99, 107, 101, 100, 102, 105, 108, 101, 0, 42, 112, 114, 101, 118, 105, 101, 119, 0, 108, 97, 115, + 116, 117, 112, 100, 97, 116, 101, 0, 108, 97, 115, 116, 117, 115, 101, 100, 0, 97, 110, 105, 109, 115, 112, 101, 101, 100, 0, 103, 101, 110, 95, 120, + 0, 103, 101, 110, 95, 121, 0, 103, 101, 110, 95, 116, 121, 112, 101, 0, 97, 115, 112, 120, 0, 97, 115, 112, 121, 0, 42, 118, 110, 111, 100, 101, + 0, 116, 101, 120, 99, 111, 0, 109, 97, 112, 116, 111, 0, 109, 97, 112, 116, 111, 110, 101, 103, 0, 98, 108, 101, 110, 100, 116, 121, 112, 101, 0, + 42, 111, 98, 106, 101, 99, 116, 0, 42, 116, 101, 120, 0, 117, 118, 110, 97, 109, 101, 91, 51, 50, 93, 0, 112, 114, 111, 106, 120, 0, 112, 114, + 111, 106, 121, 0, 112, 114, 111, 106, 122, 0, 109, 97, 112, 112, 105, 110, 103, 0, 111, 102, 115, 91, 51, 93, 0, 115, 105, 122, 101, 91, 51, 93, + 0, 116, 101, 120, 102, 108, 97, 103, 0, 99, 111, 108, 111, 114, 109, 111, 100, 101, 108, 0, 112, 109, 97, 112, 116, 111, 0, 112, 109, 97, 112, 116, + 111, 110, 101, 103, 0, 110, 111, 114, 109, 97, 112, 115, 112, 97, 99, 101, 0, 119, 104, 105, 99, 104, 95, 111, 117, 116, 112, 117, 116, 0, 112, 97, + 100, 91, 50, 93, 0, 114, 0, 103, 0, 98, 0, 107, 0, 100, 101, 102, 95, 118, 97, 114, 0, 99, 111, 108, 102, 97, 99, 0, 110, 111, 114, 102, + 97, 99, 0, 118, 97, 114, 102, 97, 99, 0, 100, 105, 115, 112, 102, 97, 99, 0, 119, 97, 114, 112, 102, 97, 99, 0, 110, 97, 109, 101, 91, 49, + 54, 48, 93, 0, 42, 104, 97, 110, 100, 108, 101, 0, 42, 112, 110, 97, 109, 101, 0, 42, 115, 116, 110, 97, 109, 101, 115, 0, 115, 116, 121, 112, + 101, 115, 0, 118, 97, 114, 115, 0, 42, 118, 97, 114, 115, 116, 114, 0, 42, 114, 101, 115, 117, 108, 116, 0, 42, 99, 102, 114, 97, 0, 100, 97, + 116, 97, 91, 51, 50, 93, 0, 40, 42, 100, 111, 105, 116, 41, 40, 41, 0, 40, 42, 105, 110, 115, 116, 97, 110, 99, 101, 95, 105, 110, 105, 116, + 41, 40, 41, 0, 40, 42, 99, 97, 108, 108, 98, 97, 99, 107, 41, 40, 41, 0, 118, 101, 114, 115, 105, 111, 110, 0, 97, 0, 105, 112, 111, 116, + 121, 112, 101, 0, 42, 105, 109, 97, 0, 42, 99, 117, 98, 101, 91, 54, 93, 0, 105, 109, 97, 116, 91, 52, 93, 91, 52, 93, 0, 111, 98, 105, + 109, 97, 116, 91, 51, 93, 91, 51, 93, 0, 115, 116, 121, 112, 101, 0, 118, 105, 101, 119, 115, 99, 97, 108, 101, 0, 110, 111, 116, 108, 97, 121, + 0, 99, 117, 98, 101, 114, 101, 115, 0, 100, 101, 112, 116, 104, 0, 114, 101, 99, 97, 108, 99, 0, 108, 97, 115, 116, 115, 105, 122, 101, 0, 110, + 111, 105, 115, 101, 115, 105, 122, 101, 0, 116, 117, 114, 98, 117, 108, 0, 98, 114, 105, 103, 104, 116, 0, 99, 111, 110, 116, 114, 97, 115, 116, 0, + 114, 102, 97, 99, 0, 103, 102, 97, 99, 0, 98, 102, 97, 99, 0, 102, 105, 108, 116, 101, 114, 115, 105, 122, 101, 0, 109, 103, 95, 72, 0, 109, + 103, 95, 108, 97, 99, 117, 110, 97, 114, 105, 116, 121, 0, 109, 103, 95, 111, 99, 116, 97, 118, 101, 115, 0, 109, 103, 95, 111, 102, 102, 115, 101, + 116, 0, 109, 103, 95, 103, 97, 105, 110, 0, 100, 105, 115, 116, 95, 97, 109, 111, 117, 110, 116, 0, 110, 115, 95, 111, 117, 116, 115, 99, 97, 108, + 101, 0, 118, 110, 95, 119, 49, 0, 118, 110, 95, 119, 50, 0, 118, 110, 95, 119, 51, 0, 118, 110, 95, 119, 52, 0, 118, 110, 95, 109, 101, 120, + 112, 0, 118, 110, 95, 100, 105, 115, 116, 109, 0, 118, 110, 95, 99, 111, 108, 116, 121, 112, 101, 0, 110, 111, 105, 115, 101, 100, 101, 112, 116, 104, + 0, 110, 111, 105, 115, 101, 116, 121, 112, 101, 0, 110, 111, 105, 115, 101, 98, 97, 115, 105, 115, 0, 110, 111, 105, 115, 101, 98, 97, 115, 105, 115, + 50, 0, 105, 109, 97, 102, 108, 97, 103, 0, 99, 114, 111, 112, 120, 109, 105, 110, 0, 99, 114, 111, 112, 121, 109, 105, 110, 0, 99, 114, 111, 112, + 120, 109, 97, 120, 0, 99, 114, 111, 112, 121, 109, 97, 120, 0, 120, 114, 101, 112, 101, 97, 116, 0, 121, 114, 101, 112, 101, 97, 116, 0, 101, 120, + 116, 101, 110, 100, 0, 99, 104, 101, 99, 107, 101, 114, 100, 105, 115, 116, 0, 110, 97, 98, 108, 97, 0, 105, 117, 115, 101, 114, 0, 42, 110, 111, + 100, 101, 116, 114, 101, 101, 0, 42, 112, 108, 117, 103, 105, 110, 0, 42, 99, 111, 98, 97, 0, 42, 101, 110, 118, 0, 117, 115, 101, 95, 110, 111, + 100, 101, 115, 0, 112, 97, 100, 91, 55, 93, 0, 108, 111, 99, 91, 51, 93, 0, 114, 111, 116, 91, 51, 93, 0, 109, 97, 116, 91, 52, 93, 91, + 52, 93, 0, 109, 105, 110, 91, 51, 93, 0, 109, 97, 120, 91, 51, 93, 0, 112, 97, 100, 51, 0, 109, 111, 100, 101, 0, 116, 111, 116, 101, 120, + 0, 115, 104, 100, 119, 114, 0, 115, 104, 100, 119, 103, 0, 115, 104, 100, 119, 98, 0, 115, 104, 100, 119, 112, 97, 100, 0, 101, 110, 101, 114, 103, + 121, 0, 100, 105, 115, 116, 0, 115, 112, 111, 116, 115, 105, 122, 101, 0, 115, 112, 111, 116, 98, 108, 101, 110, 100, 0, 104, 97, 105, 110, 116, 0, + 97, 116, 116, 49, 0, 97, 116, 116, 50, 0, 42, 99, 117, 114, 102, 97, 108, 108, 111, 102, 102, 0, 102, 97, 108, 108, 111, 102, 102, 95, 116, 121, + 112, 101, 0, 115, 104, 97, 100, 115, 112, 111, 116, 115, 105, 122, 101, 0, 98, 105, 97, 115, 0, 115, 111, 102, 116, 0, 98, 117, 102, 115, 105, 122, + 101, 0, 115, 97, 109, 112, 0, 98, 117, 102, 102, 101, 114, 115, 0, 102, 105, 108, 116, 101, 114, 116, 121, 112, 101, 0, 98, 117, 102, 102, 108, 97, + 103, 0, 98, 117, 102, 116, 121, 112, 101, 0, 114, 97, 121, 95, 115, 97, 109, 112, 0, 114, 97, 121, 95, 115, 97, 109, 112, 121, 0, 114, 97, 121, + 95, 115, 97, 109, 112, 122, 0, 114, 97, 121, 95, 115, 97, 109, 112, 95, 116, 121, 112, 101, 0, 97, 114, 101, 97, 95, 115, 104, 97, 112, 101, 0, + 97, 114, 101, 97, 95, 115, 105, 122, 101, 0, 97, 114, 101, 97, 95, 115, 105, 122, 101, 121, 0, 97, 114, 101, 97, 95, 115, 105, 122, 101, 122, 0, + 97, 100, 97, 112, 116, 95, 116, 104, 114, 101, 115, 104, 0, 114, 97, 121, 95, 115, 97, 109, 112, 95, 109, 101, 116, 104, 111, 100, 0, 116, 101, 120, + 97, 99, 116, 0, 115, 104, 97, 100, 104, 97, 108, 111, 115, 116, 101, 112, 0, 115, 117, 110, 95, 101, 102, 102, 101, 99, 116, 95, 116, 121, 112, 101, + 0, 115, 107, 121, 98, 108, 101, 110, 100, 116, 121, 112, 101, 0, 104, 111, 114, 105, 122, 111, 110, 95, 98, 114, 105, 103, 104, 116, 110, 101, 115, 115, + 0, 115, 112, 114, 101, 97, 100, 0, 115, 117, 110, 95, 98, 114, 105, 103, 104, 116, 110, 101, 115, 115, 0, 115, 117, 110, 95, 115, 105, 122, 101, 0, + 98, 97, 99, 107, 115, 99, 97, 116, 116, 101, 114, 101, 100, 95, 108, 105, 103, 104, 116, 0, 115, 117, 110, 95, 105, 110, 116, 101, 110, 115, 105, 116, + 121, 0, 97, 116, 109, 95, 116, 117, 114, 98, 105, 100, 105, 116, 121, 0, 97, 116, 109, 95, 105, 110, 115, 99, 97, 116, 116, 101, 114, 105, 110, 103, + 95, 102, 97, 99, 116, 111, 114, 0, 97, 116, 109, 95, 101, 120, 116, 105, 110, 99, 116, 105, 111, 110, 95, 102, 97, 99, 116, 111, 114, 0, 97, 116, + 109, 95, 100, 105, 115, 116, 97, 110, 99, 101, 95, 102, 97, 99, 116, 111, 114, 0, 115, 107, 121, 98, 108, 101, 110, 100, 102, 97, 99, 0, 115, 107, + 121, 95, 101, 120, 112, 111, 115, 117, 114, 101, 0, 115, 107, 121, 95, 99, 111, 108, 111, 114, 115, 112, 97, 99, 101, 0, 112, 97, 100, 52, 0, 89, + 70, 95, 110, 117, 109, 112, 104, 111, 116, 111, 110, 115, 0, 89, 70, 95, 110, 117, 109, 115, 101, 97, 114, 99, 104, 0, 89, 70, 95, 112, 104, 100, + 101, 112, 116, 104, 0, 89, 70, 95, 117, 115, 101, 113, 109, 99, 0, 89, 70, 95, 98, 117, 102, 115, 105, 122, 101, 0, 89, 70, 95, 112, 97, 100, + 0, 89, 70, 95, 99, 97, 117, 115, 116, 105, 99, 98, 108, 117, 114, 0, 89, 70, 95, 108, 116, 114, 97, 100, 105, 117, 115, 0, 89, 70, 95, 103, + 108, 111, 119, 105, 110, 116, 0, 89, 70, 95, 103, 108, 111, 119, 111, 102, 115, 0, 89, 70, 95, 103, 108, 111, 119, 116, 121, 112, 101, 0, 89, 70, + 95, 112, 97, 100, 50, 0, 42, 109, 116, 101, 120, 91, 49, 56, 93, 0, 115, 112, 101, 99, 114, 0, 115, 112, 101, 99, 103, 0, 115, 112, 101, 99, + 98, 0, 109, 105, 114, 114, 0, 109, 105, 114, 103, 0, 109, 105, 114, 98, 0, 97, 109, 98, 114, 0, 97, 109, 98, 98, 0, 97, 109, 98, 103, 0, + 97, 109, 98, 0, 101, 109, 105, 116, 0, 97, 110, 103, 0, 115, 112, 101, 99, 116, 114, 97, 0, 114, 97, 121, 95, 109, 105, 114, 114, 111, 114, 0, + 97, 108, 112, 104, 97, 0, 114, 101, 102, 0, 115, 112, 101, 99, 0, 122, 111, 102, 102, 115, 0, 97, 100, 100, 0, 116, 114, 97, 110, 115, 108, 117, + 99, 101, 110, 99, 121, 0, 102, 114, 101, 115, 110, 101, 108, 95, 109, 105, 114, 0, 102, 114, 101, 115, 110, 101, 108, 95, 109, 105, 114, 95, 105, 0, + 102, 114, 101, 115, 110, 101, 108, 95, 116, 114, 97, 0, 102, 114, 101, 115, 110, 101, 108, 95, 116, 114, 97, 95, 105, 0, 102, 105, 108, 116, 101, 114, + 0, 116, 120, 95, 108, 105, 109, 105, 116, 0, 116, 120, 95, 102, 97, 108, 108, 111, 102, 102, 0, 114, 97, 121, 95, 100, 101, 112, 116, 104, 0, 114, + 97, 121, 95, 100, 101, 112, 116, 104, 95, 116, 114, 97, 0, 104, 97, 114, 0, 115, 101, 101, 100, 49, 0, 115, 101, 101, 100, 50, 0, 103, 108, 111, + 115, 115, 95, 109, 105, 114, 0, 103, 108, 111, 115, 115, 95, 116, 114, 97, 0, 115, 97, 109, 112, 95, 103, 108, 111, 115, 115, 95, 109, 105, 114, 0, + 115, 97, 109, 112, 95, 103, 108, 111, 115, 115, 95, 116, 114, 97, 0, 97, 100, 97, 112, 116, 95, 116, 104, 114, 101, 115, 104, 95, 109, 105, 114, 0, + 97, 100, 97, 112, 116, 95, 116, 104, 114, 101, 115, 104, 95, 116, 114, 97, 0, 97, 110, 105, 115, 111, 95, 103, 108, 111, 115, 115, 95, 109, 105, 114, + 0, 100, 105, 115, 116, 95, 109, 105, 114, 0, 102, 97, 100, 101, 116, 111, 95, 109, 105, 114, 0, 115, 104, 97, 100, 101, 95, 102, 108, 97, 103, 0, + 109, 111, 100, 101, 95, 108, 0, 102, 108, 97, 114, 101, 99, 0, 115, 116, 97, 114, 99, 0, 108, 105, 110, 101, 99, 0, 114, 105, 110, 103, 99, 0, + 104, 97, 115, 105, 122, 101, 0, 102, 108, 97, 114, 101, 115, 105, 122, 101, 0, 115, 117, 98, 115, 105, 122, 101, 0, 102, 108, 97, 114, 101, 98, 111, + 111, 115, 116, 0, 115, 116, 114, 97, 110, 100, 95, 115, 116, 97, 0, 115, 116, 114, 97, 110, 100, 95, 101, 110, 100, 0, 115, 116, 114, 97, 110, 100, + 95, 101, 97, 115, 101, 0, 115, 116, 114, 97, 110, 100, 95, 115, 117, 114, 102, 110, 111, 114, 0, 115, 116, 114, 97, 110, 100, 95, 109, 105, 110, 0, + 115, 116, 114, 97, 110, 100, 95, 119, 105, 100, 116, 104, 102, 97, 100, 101, 0, 115, 116, 114, 97, 110, 100, 95, 117, 118, 110, 97, 109, 101, 91, 51, + 50, 93, 0, 115, 98, 105, 97, 115, 0, 108, 98, 105, 97, 115, 0, 115, 104, 97, 100, 95, 97, 108, 112, 104, 97, 0, 115, 101, 112, 116, 101, 120, + 0, 114, 103, 98, 115, 101, 108, 0, 112, 114, 95, 116, 121, 112, 101, 0, 112, 114, 95, 98, 97, 99, 107, 0, 112, 114, 95, 108, 97, 109, 112, 0, + 109, 108, 95, 102, 108, 97, 103, 0, 100, 105, 102, 102, 95, 115, 104, 97, 100, 101, 114, 0, 115, 112, 101, 99, 95, 115, 104, 97, 100, 101, 114, 0, + 114, 111, 117, 103, 104, 110, 101, 115, 115, 0, 114, 101, 102, 114, 97, 99, 0, 112, 97, 114, 97, 109, 91, 52, 93, 0, 114, 109, 115, 0, 100, 97, + 114, 107, 110, 101, 115, 115, 0, 42, 114, 97, 109, 112, 95, 99, 111, 108, 0, 42, 114, 97, 109, 112, 95, 115, 112, 101, 99, 0, 114, 97, 109, 112, + 105, 110, 95, 99, 111, 108, 0, 114, 97, 109, 112, 105, 110, 95, 115, 112, 101, 99, 0, 114, 97, 109, 112, 98, 108, 101, 110, 100, 95, 99, 111, 108, + 0, 114, 97, 109, 112, 98, 108, 101, 110, 100, 95, 115, 112, 101, 99, 0, 114, 97, 109, 112, 95, 115, 104, 111, 119, 0, 114, 97, 109, 112, 102, 97, + 99, 95, 99, 111, 108, 0, 114, 97, 109, 112, 102, 97, 99, 95, 115, 112, 101, 99, 0, 42, 103, 114, 111, 117, 112, 0, 102, 114, 105, 99, 116, 105, + 111, 110, 0, 102, 104, 0, 114, 101, 102, 108, 101, 99, 116, 0, 102, 104, 100, 105, 115, 116, 0, 120, 121, 102, 114, 105, 99, 116, 0, 100, 121, 110, + 97, 109, 111, 100, 101, 0, 115, 115, 115, 95, 114, 97, 100, 105, 117, 115, 91, 51, 93, 0, 115, 115, 115, 95, 99, 111, 108, 91, 51, 93, 0, 115, + 115, 115, 95, 101, 114, 114, 111, 114, 0, 115, 115, 115, 95, 115, 99, 97, 108, 101, 0, 115, 115, 115, 95, 105, 111, 114, 0, 115, 115, 115, 95, 99, + 111, 108, 102, 97, 99, 0, 115, 115, 115, 95, 116, 101, 120, 102, 97, 99, 0, 115, 115, 115, 95, 102, 114, 111, 110, 116, 0, 115, 115, 115, 95, 98, + 97, 99, 107, 0, 115, 115, 115, 95, 102, 108, 97, 103, 0, 115, 115, 115, 95, 112, 114, 101, 115, 101, 116, 0, 89, 70, 95, 97, 114, 0, 89, 70, + 95, 97, 103, 0, 89, 70, 95, 97, 98, 0, 89, 70, 95, 100, 115, 99, 97, 108, 101, 0, 89, 70, 95, 100, 112, 119, 114, 0, 89, 70, 95, 100, + 115, 109, 112, 0, 89, 70, 95, 112, 114, 101, 115, 101, 116, 0, 89, 70, 95, 100, 106, 105, 116, 0, 103, 112, 117, 109, 97, 116, 101, 114, 105, 97, + 108, 0, 110, 97, 109, 101, 91, 50, 53, 54, 93, 0, 115, 99, 97, 108, 101, 0, 42, 98, 98, 0, 105, 49, 0, 106, 49, 0, 107, 49, 0, 105, + 50, 0, 106, 50, 0, 107, 50, 0, 115, 101, 108, 99, 111, 108, 49, 0, 115, 101, 108, 99, 111, 108, 50, 0, 113, 117, 97, 116, 91, 52, 93, 0, + 101, 120, 112, 120, 0, 101, 120, 112, 121, 0, 101, 120, 112, 122, 0, 114, 97, 100, 0, 114, 97, 100, 50, 0, 115, 0, 42, 109, 97, 116, 0, 42, + 105, 109, 97, 116, 0, 101, 108, 101, 109, 115, 0, 100, 105, 115, 112, 0, 42, 42, 109, 97, 116, 0, 116, 111, 116, 99, 111, 108, 0, 119, 105, 114, + 101, 115, 105, 122, 101, 0, 114, 101, 110, 100, 101, 114, 115, 105, 122, 101, 0, 116, 104, 114, 101, 115, 104, 0, 118, 101, 99, 91, 51, 93, 91, 51, + 93, 0, 97, 108, 102, 97, 0, 119, 101, 105, 103, 104, 116, 0, 114, 97, 100, 105, 117, 115, 0, 104, 49, 0, 104, 50, 0, 102, 49, 0, 102, 50, + 0, 102, 51, 0, 104, 105, 100, 101, 0, 118, 101, 99, 91, 52, 93, 0, 109, 97, 116, 95, 110, 114, 0, 112, 110, 116, 115, 117, 0, 112, 110, 116, + 115, 118, 0, 114, 101, 115, 111, 108, 117, 0, 114, 101, 115, 111, 108, 118, 0, 111, 114, 100, 101, 114, 117, 0, 111, 114, 100, 101, 114, 118, 0, 102, + 108, 97, 103, 117, 0, 102, 108, 97, 103, 118, 0, 42, 107, 110, 111, 116, 115, 117, 0, 42, 107, 110, 111, 116, 115, 118, 0, 116, 105, 108, 116, 95, + 105, 110, 116, 101, 114, 112, 0, 114, 97, 100, 105, 117, 115, 95, 105, 110, 116, 101, 114, 112, 0, 99, 104, 97, 114, 105, 100, 120, 0, 107, 101, 114, + 110, 0, 104, 0, 110, 117, 114, 98, 0, 42, 98, 101, 118, 111, 98, 106, 0, 42, 116, 97, 112, 101, 114, 111, 98, 106, 0, 42, 116, 101, 120, 116, + 111, 110, 99, 117, 114, 118, 101, 0, 42, 112, 97, 116, 104, 0, 42, 107, 101, 121, 0, 98, 101, 118, 0, 112, 97, 116, 104, 108, 101, 110, 0, 98, + 101, 118, 114, 101, 115, 111, 108, 0, 119, 105, 100, 116, 104, 0, 101, 120, 116, 49, 0, 101, 120, 116, 50, 0, 114, 101, 115, 111, 108, 117, 95, 114, + 101, 110, 0, 114, 101, 115, 111, 108, 118, 95, 114, 101, 110, 0, 115, 112, 97, 99, 101, 109, 111, 100, 101, 0, 115, 112, 97, 99, 105, 110, 103, 0, + 108, 105, 110, 101, 100, 105, 115, 116, 0, 115, 104, 101, 97, 114, 0, 102, 115, 105, 122, 101, 0, 119, 111, 114, 100, 115, 112, 97, 99, 101, 0, 117, + 108, 112, 111, 115, 0, 117, 108, 104, 101, 105, 103, 104, 116, 0, 120, 111, 102, 0, 121, 111, 102, 0, 108, 105, 110, 101, 119, 105, 100, 116, 104, 0, + 42, 115, 116, 114, 0, 102, 97, 109, 105, 108, 121, 91, 50, 52, 93, 0, 42, 118, 102, 111, 110, 116, 0, 42, 118, 102, 111, 110, 116, 98, 0, 42, + 118, 102, 111, 110, 116, 105, 0, 42, 118, 102, 111, 110, 116, 98, 105, 0, 115, 101, 112, 99, 104, 97, 114, 0, 116, 111, 116, 98, 111, 120, 0, 97, + 99, 116, 98, 111, 120, 0, 42, 116, 98, 0, 115, 101, 108, 115, 116, 97, 114, 116, 0, 115, 101, 108, 101, 110, 100, 0, 42, 115, 116, 114, 105, 110, + 102, 111, 0, 99, 117, 114, 105, 110, 102, 111, 0, 101, 102, 102, 101, 99, 116, 0, 42, 109, 102, 97, 99, 101, 0, 42, 109, 116, 102, 97, 99, 101, + 0, 42, 116, 102, 97, 99, 101, 0, 42, 109, 118, 101, 114, 116, 0, 42, 109, 101, 100, 103, 101, 0, 42, 100, 118, 101, 114, 116, 0, 42, 109, 99, + 111, 108, 0, 42, 109, 115, 116, 105, 99, 107, 121, 0, 42, 116, 101, 120, 99, 111, 109, 101, 115, 104, 0, 42, 109, 115, 101, 108, 101, 99, 116, 0, + 118, 100, 97, 116, 97, 0, 101, 100, 97, 116, 97, 0, 102, 100, 97, 116, 97, 0, 116, 111, 116, 101, 100, 103, 101, 0, 116, 111, 116, 102, 97, 99, + 101, 0, 116, 111, 116, 115, 101, 108, 101, 99, 116, 0, 97, 99, 116, 95, 102, 97, 99, 101, 0, 99, 117, 98, 101, 109, 97, 112, 115, 105, 122, 101, + 0, 115, 109, 111, 111, 116, 104, 114, 101, 115, 104, 0, 115, 117, 98, 100, 105, 118, 0, 115, 117, 98, 100, 105, 118, 114, 0, 115, 117, 98, 115, 117, + 114, 102, 116, 121, 112, 101, 0, 42, 109, 114, 0, 42, 112, 118, 0, 42, 116, 112, 97, 103, 101, 0, 117, 118, 91, 52, 93, 91, 50, 93, 0, 99, + 111, 108, 91, 52, 93, 0, 116, 114, 97, 110, 115, 112, 0, 116, 105, 108, 101, 0, 117, 110, 119, 114, 97, 112, 0, 118, 49, 0, 118, 50, 0, 118, + 51, 0, 118, 52, 0, 101, 100, 99, 111, 100, 101, 0, 99, 114, 101, 97, 115, 101, 0, 98, 119, 101, 105, 103, 104, 116, 0, 100, 101, 102, 95, 110, + 114, 0, 42, 100, 119, 0, 116, 111, 116, 119, 101, 105, 103, 104, 116, 0, 99, 111, 91, 51, 93, 0, 110, 111, 91, 51, 93, 0, 112, 97, 100, 91, + 51, 93, 0, 117, 118, 91, 50, 93, 0, 99, 111, 91, 50, 93, 0, 105, 110, 100, 101, 120, 0, 102, 0, 105, 0, 115, 91, 50, 53, 54, 93, 0, + 118, 91, 52, 93, 0, 109, 105, 100, 0, 118, 91, 50, 93, 0, 42, 102, 97, 99, 101, 115, 0, 42, 99, 111, 108, 102, 97, 99, 101, 115, 0, 42, + 101, 100, 103, 101, 115, 0, 42, 101, 100, 103, 101, 95, 98, 111, 117, 110, 100, 97, 114, 121, 95, 115, 116, 97, 116, 101, 115, 0, 42, 118, 101, 114, + 116, 95, 101, 100, 103, 101, 95, 109, 97, 112, 0, 42, 118, 101, 114, 116, 95, 102, 97, 99, 101, 95, 109, 97, 112, 0, 42, 109, 97, 112, 95, 109, + 101, 109, 0, 42, 118, 101, 114, 116, 115, 0, 108, 101, 118, 101, 108, 115, 0, 108, 101, 118, 101, 108, 95, 99, 111, 117, 110, 116, 0, 99, 117, 114, + 114, 101, 110, 116, 0, 110, 101, 119, 108, 118, 108, 0, 101, 100, 103, 101, 108, 118, 108, 0, 112, 105, 110, 108, 118, 108, 0, 114, 101, 110, 100, 101, + 114, 108, 118, 108, 0, 117, 115, 101, 95, 99, 111, 108, 0, 42, 101, 100, 103, 101, 95, 102, 108, 97, 103, 115, 0, 42, 101, 100, 103, 101, 95, 99, + 114, 101, 97, 115, 101, 115, 0, 42, 118, 101, 114, 116, 95, 109, 97, 112, 0, 42, 101, 100, 103, 101, 95, 109, 97, 112, 0, 42, 111, 108, 100, 95, + 102, 97, 99, 101, 115, 0, 42, 111, 108, 100, 95, 101, 100, 103, 101, 115, 0, 42, 101, 114, 114, 111, 114, 0, 109, 111, 100, 105, 102, 105, 101, 114, + 0, 115, 117, 98, 100, 105, 118, 84, 121, 112, 101, 0, 114, 101, 110, 100, 101, 114, 76, 101, 118, 101, 108, 115, 0, 42, 101, 109, 67, 97, 99, 104, + 101, 0, 42, 109, 67, 97, 99, 104, 101, 0, 100, 101, 102, 97, 120, 105, 115, 0, 112, 97, 100, 91, 54, 93, 0, 108, 101, 110, 103, 116, 104, 0, + 114, 97, 110, 100, 111, 109, 105, 122, 101, 0, 115, 101, 101, 100, 0, 42, 111, 98, 95, 97, 114, 109, 0, 42, 115, 116, 97, 114, 116, 95, 99, 97, + 112, 0, 42, 101, 110, 100, 95, 99, 97, 112, 0, 42, 99, 117, 114, 118, 101, 95, 111, 98, 0, 42, 111, 102, 102, 115, 101, 116, 95, 111, 98, 0, + 111, 102, 102, 115, 101, 116, 91, 51, 93, 0, 115, 99, 97, 108, 101, 91, 51, 93, 0, 109, 101, 114, 103, 101, 95, 100, 105, 115, 116, 0, 102, 105, + 116, 95, 116, 121, 112, 101, 0, 111, 102, 102, 115, 101, 116, 95, 116, 121, 112, 101, 0, 99, 111, 117, 110, 116, 0, 97, 120, 105, 115, 0, 116, 111, + 108, 101, 114, 97, 110, 99, 101, 0, 42, 109, 105, 114, 114, 111, 114, 95, 111, 98, 0, 115, 112, 108, 105, 116, 95, 97, 110, 103, 108, 101, 0, 118, + 97, 108, 117, 101, 0, 114, 101, 115, 0, 118, 97, 108, 95, 102, 108, 97, 103, 115, 0, 108, 105, 109, 95, 102, 108, 97, 103, 115, 0, 101, 95, 102, + 108, 97, 103, 115, 0, 98, 101, 118, 101, 108, 95, 97, 110, 103, 108, 101, 0, 100, 101, 102, 103, 114, 112, 95, 110, 97, 109, 101, 91, 51, 50, 93, + 0, 42, 116, 101, 120, 116, 117, 114, 101, 0, 115, 116, 114, 101, 110, 103, 116, 104, 0, 100, 105, 114, 101, 99, 116, 105, 111, 110, 0, 109, 105, 100, + 108, 101, 118, 101, 108, 0, 116, 101, 120, 109, 97, 112, 112, 105, 110, 103, 0, 42, 109, 97, 112, 95, 111, 98, 106, 101, 99, 116, 0, 117, 118, 108, + 97, 121, 101, 114, 95, 110, 97, 109, 101, 91, 51, 50, 93, 0, 117, 118, 108, 97, 121, 101, 114, 95, 116, 109, 112, 0, 42, 112, 114, 111, 106, 101, + 99, 116, 111, 114, 115, 91, 49, 48, 93, 0, 42, 105, 109, 97, 103, 101, 0, 110, 117, 109, 95, 112, 114, 111, 106, 101, 99, 116, 111, 114, 115, 0, + 97, 115, 112, 101, 99, 116, 120, 0, 97, 115, 112, 101, 99, 116, 121, 0, 112, 101, 114, 99, 101, 110, 116, 0, 102, 97, 99, 101, 67, 111, 117, 110, + 116, 0, 102, 97, 99, 0, 114, 101, 112, 101, 97, 116, 0, 42, 111, 98, 106, 101, 99, 116, 99, 101, 110, 116, 101, 114, 0, 115, 116, 97, 114, 116, + 120, 0, 115, 116, 97, 114, 116, 121, 0, 104, 101, 105, 103, 104, 116, 0, 110, 97, 114, 114, 111, 119, 0, 115, 112, 101, 101, 100, 0, 100, 97, 109, + 112, 0, 102, 97, 108, 108, 111, 102, 102, 0, 116, 105, 109, 101, 111, 102, 102, 115, 0, 108, 105, 102, 101, 116, 105, 109, 101, 0, 100, 101, 102, 111, + 114, 109, 102, 108, 97, 103, 0, 109, 117, 108, 116, 105, 0, 42, 112, 114, 101, 118, 67, 111, 115, 0, 112, 97, 114, 101, 110, 116, 105, 110, 118, 91, + 52, 93, 91, 52, 93, 0, 99, 101, 110, 116, 91, 51, 93, 0, 42, 105, 110, 100, 101, 120, 97, 114, 0, 116, 111, 116, 105, 110, 100, 101, 120, 0, + 102, 111, 114, 99, 101, 0, 42, 99, 108, 111, 116, 104, 79, 98, 106, 101, 99, 116, 0, 42, 115, 105, 109, 95, 112, 97, 114, 109, 115, 0, 42, 99, + 111, 108, 108, 95, 112, 97, 114, 109, 115, 0, 42, 112, 111, 105, 110, 116, 95, 99, 97, 99, 104, 101, 0, 42, 120, 0, 42, 120, 110, 101, 119, 0, + 42, 120, 111, 108, 100, 0, 42, 99, 117, 114, 114, 101, 110, 116, 95, 120, 110, 101, 119, 0, 42, 99, 117, 114, 114, 101, 110, 116, 95, 120, 0, 42, + 99, 117, 114, 114, 101, 110, 116, 95, 118, 0, 42, 109, 102, 97, 99, 101, 115, 0, 110, 117, 109, 118, 101, 114, 116, 115, 0, 110, 117, 109, 102, 97, + 99, 101, 115, 0, 97, 98, 115, 111, 114, 112, 116, 105, 111, 110, 0, 116, 105, 109, 101, 0, 42, 98, 118, 104, 116, 114, 101, 101, 0, 42, 100, 109, + 0, 111, 112, 101, 114, 97, 116, 105, 111, 110, 0, 118, 101, 114, 116, 101, 120, 0, 116, 111, 116, 105, 110, 102, 108, 117, 101, 110, 99, 101, 0, 103, + 114, 105, 100, 115, 105, 122, 101, 0, 110, 101, 101, 100, 98, 105, 110, 100, 0, 42, 98, 105, 110, 100, 119, 101, 105, 103, 104, 116, 115, 0, 42, 98, + 105, 110, 100, 99, 111, 115, 0, 116, 111, 116, 99, 97, 103, 101, 118, 101, 114, 116, 0, 42, 100, 121, 110, 103, 114, 105, 100, 0, 42, 100, 121, 110, + 105, 110, 102, 108, 117, 101, 110, 99, 101, 115, 0, 42, 100, 121, 110, 118, 101, 114, 116, 115, 0, 42, 112, 97, 100, 50, 0, 100, 121, 110, 103, 114, + 105, 100, 115, 105, 122, 101, 0, 100, 121, 110, 99, 101, 108, 108, 109, 105, 110, 91, 51, 93, 0, 100, 121, 110, 99, 101, 108, 108, 119, 105, 100, 116, + 104, 0, 98, 105, 110, 100, 109, 97, 116, 91, 52, 93, 91, 52, 93, 0, 42, 112, 115, 121, 115, 0, 116, 111, 116, 100, 109, 118, 101, 114, 116, 0, + 116, 111, 116, 100, 109, 101, 100, 103, 101, 0, 116, 111, 116, 100, 109, 102, 97, 99, 101, 0, 112, 115, 121, 115, 0, 114, 116, 91, 50, 93, 0, 42, + 102, 97, 99, 101, 112, 97, 0, 118, 103, 114, 111, 117, 112, 0, 112, 114, 111, 116, 101, 99, 116, 0, 42, 102, 115, 115, 0, 42, 116, 97, 114, 103, + 101, 116, 0, 42, 97, 117, 120, 84, 97, 114, 103, 101, 116, 0, 118, 103, 114, 111, 117, 112, 95, 110, 97, 109, 101, 91, 51, 50, 93, 0, 107, 101, + 101, 112, 68, 105, 115, 116, 0, 115, 104, 114, 105, 110, 107, 84, 121, 112, 101, 0, 115, 104, 114, 105, 110, 107, 79, 112, 116, 115, 0, 112, 114, 111, + 106, 65, 120, 105, 115, 0, 115, 117, 98, 115, 117, 114, 102, 76, 101, 118, 101, 108, 115, 0, 42, 111, 114, 105, 103, 105, 110, 0, 102, 97, 99, 116, + 111, 114, 0, 108, 105, 109, 105, 116, 91, 50, 93, 0, 111, 114, 105, 103, 105, 110, 79, 112, 116, 115, 0, 112, 110, 116, 115, 119, 0, 111, 112, 110, + 116, 115, 117, 0, 111, 112, 110, 116, 115, 118, 0, 111, 112, 110, 116, 115, 119, 0, 116, 121, 112, 101, 117, 0, 116, 121, 112, 101, 118, 0, 116, 121, + 112, 101, 119, 0, 102, 117, 0, 102, 118, 0, 102, 119, 0, 100, 117, 0, 100, 118, 0, 100, 119, 0, 42, 100, 101, 102, 0, 118, 101, 99, 91, 56, + 93, 91, 51, 93, 0, 112, 97, 114, 116, 121, 112, 101, 0, 112, 97, 114, 49, 0, 112, 97, 114, 50, 0, 112, 97, 114, 51, 0, 112, 97, 114, 115, + 117, 98, 115, 116, 114, 91, 51, 50, 93, 0, 42, 116, 114, 97, 99, 107, 0, 42, 112, 114, 111, 120, 121, 0, 42, 112, 114, 111, 120, 121, 95, 103, + 114, 111, 117, 112, 0, 42, 112, 114, 111, 120, 121, 95, 102, 114, 111, 109, 0, 42, 97, 99, 116, 105, 111, 110, 0, 42, 112, 111, 115, 101, 108, 105, + 98, 0, 42, 112, 111, 115, 101, 0, 99, 111, 110, 115, 116, 114, 97, 105, 110, 116, 67, 104, 97, 110, 110, 101, 108, 115, 0, 100, 101, 102, 98, 97, + 115, 101, 0, 109, 111, 100, 105, 102, 105, 101, 114, 115, 0, 100, 108, 111, 99, 91, 51, 93, 0, 111, 114, 105, 103, 91, 51, 93, 0, 100, 115, 105, + 122, 101, 91, 51, 93, 0, 100, 114, 111, 116, 91, 51, 93, 0, 111, 98, 109, 97, 116, 91, 52, 93, 91, 52, 93, 0, 99, 111, 110, 115, 116, 105, + 110, 118, 91, 52, 93, 91, 52, 93, 0, 108, 97, 121, 0, 99, 111, 108, 98, 105, 116, 115, 0, 116, 114, 97, 110, 115, 102, 108, 97, 103, 0, 105, + 112, 111, 102, 108, 97, 103, 0, 116, 114, 97, 99, 107, 102, 108, 97, 103, 0, 117, 112, 102, 108, 97, 103, 0, 110, 108, 97, 102, 108, 97, 103, 0, + 112, 114, 111, 116, 101, 99, 116, 102, 108, 97, 103, 0, 105, 112, 111, 119, 105, 110, 0, 115, 99, 97, 102, 108, 97, 103, 0, 115, 99, 97, 118, 105, + 115, 102, 108, 97, 103, 0, 98, 111, 117, 110, 100, 116, 121, 112, 101, 0, 100, 117, 112, 111, 110, 0, 100, 117, 112, 111, 102, 102, 0, 100, 117, 112, + 115, 116, 97, 0, 100, 117, 112, 101, 110, 100, 0, 115, 102, 0, 99, 116, 105, 109, 101, 0, 109, 97, 115, 115, 0, 100, 97, 109, 112, 105, 110, 103, + 0, 105, 110, 101, 114, 116, 105, 97, 0, 102, 111, 114, 109, 102, 97, 99, 116, 111, 114, 0, 114, 100, 97, 109, 112, 105, 110, 103, 0, 115, 105, 122, + 101, 102, 97, 99, 0, 109, 97, 114, 103, 105, 110, 0, 109, 97, 120, 95, 118, 101, 108, 0, 109, 105, 110, 95, 118, 101, 108, 0, 109, 95, 99, 111, + 110, 116, 97, 99, 116, 80, 114, 111, 99, 101, 115, 115, 105, 110, 103, 84, 104, 114, 101, 115, 104, 111, 108, 100, 0, 100, 116, 0, 100, 116, 120, 0, + 97, 99, 116, 99, 111, 108, 0, 101, 109, 112, 116, 121, 95, 100, 114, 97, 119, 116, 121, 112, 101, 0, 112, 97, 100, 49, 91, 51, 93, 0, 101, 109, + 112, 116, 121, 95, 100, 114, 97, 119, 115, 105, 122, 101, 0, 100, 117, 112, 102, 97, 99, 101, 115, 99, 97, 0, 112, 114, 111, 112, 0, 115, 101, 110, + 115, 111, 114, 115, 0, 99, 111, 110, 116, 114, 111, 108, 108, 101, 114, 115, 0, 97, 99, 116, 117, 97, 116, 111, 114, 115, 0, 98, 98, 115, 105, 122, + 101, 91, 51, 93, 0, 97, 99, 116, 100, 101, 102, 0, 103, 97, 109, 101, 102, 108, 97, 103, 0, 103, 97, 109, 101, 102, 108, 97, 103, 50, 0, 42, + 98, 115, 111, 102, 116, 0, 115, 111, 102, 116, 102, 108, 97, 103, 0, 97, 110, 105, 115, 111, 116, 114, 111, 112, 105, 99, 70, 114, 105, 99, 116, 105, + 111, 110, 91, 51, 93, 0, 99, 111, 110, 115, 116, 114, 97, 105, 110, 116, 115, 0, 110, 108, 97, 115, 116, 114, 105, 112, 115, 0, 104, 111, 111, 107, + 115, 0, 112, 97, 114, 116, 105, 99, 108, 101, 115, 121, 115, 116, 101, 109, 0, 42, 112, 100, 0, 42, 115, 111, 102, 116, 0, 42, 100, 117, 112, 95, + 103, 114, 111, 117, 112, 0, 102, 108, 117, 105, 100, 115, 105, 109, 70, 108, 97, 103, 0, 114, 101, 115, 116, 114, 105, 99, 116, 102, 108, 97, 103, 0, + 115, 104, 97, 112, 101, 110, 114, 0, 115, 104, 97, 112, 101, 102, 108, 97, 103, 0, 114, 101, 99, 97, 108, 99, 111, 0, 98, 111, 100, 121, 95, 116, + 121, 112, 101, 0, 42, 102, 108, 117, 105, 100, 115, 105, 109, 83, 101, 116, 116, 105, 110, 103, 115, 0, 42, 100, 101, 114, 105, 118, 101, 100, 68, 101, + 102, 111, 114, 109, 0, 42, 100, 101, 114, 105, 118, 101, 100, 70, 105, 110, 97, 108, 0, 108, 97, 115, 116, 68, 97, 116, 97, 77, 97, 115, 107, 0, + 115, 116, 97, 116, 101, 0, 105, 110, 105, 116, 95, 115, 116, 97, 116, 101, 0, 103, 112, 117, 108, 97, 109, 112, 0, 99, 117, 114, 105, 110, 100, 101, + 120, 0, 97, 99, 116, 105, 118, 101, 0, 100, 101, 102, 108, 101, 99, 116, 0, 102, 111, 114, 99, 101, 102, 105, 101, 108, 100, 0, 112, 100, 101, 102, + 95, 100, 97, 109, 112, 0, 112, 100, 101, 102, 95, 114, 100, 97, 109, 112, 0, 112, 100, 101, 102, 95, 112, 101, 114, 109, 0, 112, 100, 101, 102, 95, + 102, 114, 105, 99, 116, 0, 112, 100, 101, 102, 95, 114, 102, 114, 105, 99, 116, 0, 102, 95, 115, 116, 114, 101, 110, 103, 116, 104, 0, 102, 95, 112, + 111, 119, 101, 114, 0, 102, 95, 100, 105, 115, 116, 0, 102, 95, 100, 97, 109, 112, 0, 109, 97, 120, 100, 105, 115, 116, 0, 109, 105, 110, 100, 105, + 115, 116, 0, 109, 97, 120, 114, 97, 100, 0, 109, 105, 110, 114, 97, 100, 0, 102, 95, 112, 111, 119, 101, 114, 95, 114, 0, 112, 100, 101, 102, 95, + 115, 98, 100, 97, 109, 112, 0, 112, 100, 101, 102, 95, 115, 98, 105, 102, 116, 0, 112, 100, 101, 102, 95, 115, 98, 111, 102, 116, 0, 99, 108, 117, + 109, 112, 95, 102, 97, 99, 0, 99, 108, 117, 109, 112, 95, 112, 111, 119, 0, 107, 105, 110, 107, 95, 102, 114, 101, 113, 0, 107, 105, 110, 107, 95, + 115, 104, 97, 112, 101, 0, 107, 105, 110, 107, 95, 97, 109, 112, 0, 102, 114, 101, 101, 95, 101, 110, 100, 0, 116, 101, 120, 95, 110, 97, 98, 108, + 97, 0, 116, 101, 120, 95, 109, 111, 100, 101, 0, 107, 105, 110, 107, 0, 107, 105, 110, 107, 95, 97, 120, 105, 115, 0, 114, 116, 50, 0, 42, 114, + 110, 103, 0, 102, 95, 110, 111, 105, 115, 101, 0, 115, 105, 109, 102, 114, 97, 109, 101, 0, 115, 116, 97, 114, 116, 102, 114, 97, 109, 101, 0, 101, + 110, 100, 102, 114, 97, 109, 101, 0, 101, 100, 105, 116, 102, 114, 97, 109, 101, 0, 108, 105, 110, 83, 116, 105, 102, 102, 0, 97, 110, 103, 83, 116, + 105, 102, 102, 0, 118, 111, 108, 117, 109, 101, 0, 118, 105, 116, 101, 114, 97, 116, 105, 111, 110, 115, 0, 112, 105, 116, 101, 114, 97, 116, 105, 111, + 110, 115, 0, 100, 105, 116, 101, 114, 97, 116, 105, 111, 110, 115, 0, 99, 105, 116, 101, 114, 97, 116, 105, 111, 110, 115, 0, 107, 83, 82, 72, 82, + 95, 67, 76, 0, 107, 83, 75, 72, 82, 95, 67, 76, 0, 107, 83, 83, 72, 82, 95, 67, 76, 0, 107, 83, 82, 95, 83, 80, 76, 84, 95, 67, + 76, 0, 107, 83, 75, 95, 83, 80, 76, 84, 95, 67, 76, 0, 107, 83, 83, 95, 83, 80, 76, 84, 95, 67, 76, 0, 107, 86, 67, 70, 0, 107, + 68, 80, 0, 107, 68, 71, 0, 107, 76, 70, 0, 107, 80, 82, 0, 107, 86, 67, 0, 107, 68, 70, 0, 107, 77, 84, 0, 107, 67, 72, 82, 0, + 107, 75, 72, 82, 0, 107, 83, 72, 82, 0, 107, 65, 72, 82, 0, 99, 111, 108, 108, 105, 115, 105, 111, 110, 102, 108, 97, 103, 115, 0, 110, 117, + 109, 99, 108, 117, 115, 116, 101, 114, 105, 116, 101, 114, 97, 116, 105, 111, 110, 115, 0, 119, 101, 108, 100, 105, 110, 103, 0, 42, 112, 97, 114, 116, + 105, 99, 108, 101, 115, 0, 116, 111, 116, 112, 111, 105, 110, 116, 0, 116, 111, 116, 115, 112, 114, 105, 110, 103, 0, 42, 98, 112, 111, 105, 110, 116, + 0, 42, 98, 115, 112, 114, 105, 110, 103, 0, 109, 115, 103, 95, 108, 111, 99, 107, 0, 109, 115, 103, 95, 118, 97, 108, 117, 101, 0, 110, 111, 100, + 101, 109, 97, 115, 115, 0, 110, 97, 109, 101, 100, 86, 71, 95, 77, 97, 115, 115, 91, 51, 50, 93, 0, 103, 114, 97, 118, 0, 109, 101, 100, 105, + 97, 102, 114, 105, 99, 116, 0, 114, 107, 108, 105, 109, 105, 116, 0, 112, 104, 121, 115, 105, 99, 115, 95, 115, 112, 101, 101, 100, 0, 103, 111, 97, + 108, 115, 112, 114, 105, 110, 103, 0, 103, 111, 97, 108, 102, 114, 105, 99, 116, 0, 109, 105, 110, 103, 111, 97, 108, 0, 109, 97, 120, 103, 111, 97, + 108, 0, 100, 101, 102, 103, 111, 97, 108, 0, 118, 101, 114, 116, 103, 114, 111, 117, 112, 0, 110, 97, 109, 101, 100, 86, 71, 95, 83, 111, 102, 116, + 103, 111, 97, 108, 91, 51, 50, 93, 0, 102, 117, 122, 122, 121, 110, 101, 115, 115, 0, 105, 110, 115, 112, 114, 105, 110, 103, 0, 105, 110, 102, 114, + 105, 99, 116, 0, 110, 97, 109, 101, 100, 86, 71, 95, 83, 112, 114, 105, 110, 103, 95, 75, 91, 51, 50, 93, 0, 101, 102, 114, 97, 0, 105, 110, + 116, 101, 114, 118, 97, 108, 0, 108, 111, 99, 97, 108, 0, 115, 111, 108, 118, 101, 114, 102, 108, 97, 103, 115, 0, 42, 42, 107, 101, 121, 115, 0, + 116, 111, 116, 112, 111, 105, 110, 116, 107, 101, 121, 0, 115, 101, 99, 111, 110, 100, 115, 112, 114, 105, 110, 103, 0, 99, 111, 108, 98, 97, 108, 108, + 0, 98, 97, 108, 108, 100, 97, 109, 112, 0, 98, 97, 108, 108, 115, 116, 105, 102, 102, 0, 115, 98, 99, 95, 109, 111, 100, 101, 0, 97, 101, 114, + 111, 101, 100, 103, 101, 0, 109, 105, 110, 108, 111, 111, 112, 115, 0, 109, 97, 120, 108, 111, 111, 112, 115, 0, 99, 104, 111, 107, 101, 0, 115, 111, + 108, 118, 101, 114, 95, 73, 68, 0, 112, 108, 97, 115, 116, 105, 99, 0, 115, 112, 114, 105, 110, 103, 112, 114, 101, 108, 111, 97, 100, 0, 42, 115, + 99, 114, 97, 116, 99, 104, 0, 115, 104, 101, 97, 114, 115, 116, 105, 102, 102, 0, 105, 110, 112, 117, 115, 104, 0, 42, 112, 111, 105, 110, 116, 99, + 97, 99, 104, 101, 0, 115, 104, 111, 119, 95, 97, 100, 118, 97, 110, 99, 101, 100, 111, 112, 116, 105, 111, 110, 115, 0, 114, 101, 115, 111, 108, 117, + 116, 105, 111, 110, 120, 121, 122, 0, 112, 114, 101, 118, 105, 101, 119, 114, 101, 115, 120, 121, 122, 0, 114, 101, 97, 108, 115, 105, 122, 101, 0, 103, + 117, 105, 68, 105, 115, 112, 108, 97, 121, 77, 111, 100, 101, 0, 114, 101, 110, 100, 101, 114, 68, 105, 115, 112, 108, 97, 121, 77, 111, 100, 101, 0, + 118, 105, 115, 99, 111, 115, 105, 116, 121, 86, 97, 108, 117, 101, 0, 118, 105, 115, 99, 111, 115, 105, 116, 121, 77, 111, 100, 101, 0, 118, 105, 115, + 99, 111, 115, 105, 116, 121, 69, 120, 112, 111, 110, 101, 110, 116, 0, 103, 114, 97, 118, 120, 0, 103, 114, 97, 118, 121, 0, 103, 114, 97, 118, 122, + 0, 97, 110, 105, 109, 83, 116, 97, 114, 116, 0, 97, 110, 105, 109, 69, 110, 100, 0, 103, 115, 116, 97, 114, 0, 109, 97, 120, 82, 101, 102, 105, + 110, 101, 0, 105, 110, 105, 86, 101, 108, 120, 0, 105, 110, 105, 86, 101, 108, 121, 0, 105, 110, 105, 86, 101, 108, 122, 0, 42, 111, 114, 103, 77, + 101, 115, 104, 0, 42, 109, 101, 115, 104, 83, 117, 114, 102, 97, 99, 101, 0, 42, 109, 101, 115, 104, 66, 66, 0, 115, 117, 114, 102, 100, 97, 116, + 97, 80, 97, 116, 104, 91, 50, 52, 48, 93, 0, 98, 98, 83, 116, 97, 114, 116, 91, 51, 93, 0, 98, 98, 83, 105, 122, 101, 91, 51, 93, 0, + 116, 121, 112, 101, 70, 108, 97, 103, 115, 0, 100, 111, 109, 97, 105, 110, 78, 111, 118, 101, 99, 103, 101, 110, 0, 118, 111, 108, 117, 109, 101, 73, + 110, 105, 116, 84, 121, 112, 101, 0, 112, 97, 114, 116, 83, 108, 105, 112, 86, 97, 108, 117, 101, 0, 103, 101, 110, 101, 114, 97, 116, 101, 84, 114, + 97, 99, 101, 114, 115, 0, 103, 101, 110, 101, 114, 97, 116, 101, 80, 97, 114, 116, 105, 99, 108, 101, 115, 0, 115, 117, 114, 102, 97, 99, 101, 83, + 109, 111, 111, 116, 104, 105, 110, 103, 0, 115, 117, 114, 102, 97, 99, 101, 83, 117, 98, 100, 105, 118, 115, 0, 112, 97, 114, 116, 105, 99, 108, 101, + 73, 110, 102, 83, 105, 122, 101, 0, 112, 97, 114, 116, 105, 99, 108, 101, 73, 110, 102, 65, 108, 112, 104, 97, 0, 102, 97, 114, 70, 105, 101, 108, + 100, 83, 105, 122, 101, 0, 42, 109, 101, 115, 104, 83, 117, 114, 102, 78, 111, 114, 109, 97, 108, 115, 0, 99, 112, 115, 84, 105, 109, 101, 83, 116, + 97, 114, 116, 0, 99, 112, 115, 84, 105, 109, 101, 69, 110, 100, 0, 99, 112, 115, 81, 117, 97, 108, 105, 116, 121, 0, 97, 116, 116, 114, 97, 99, + 116, 102, 111, 114, 99, 101, 83, 116, 114, 101, 110, 103, 116, 104, 0, 97, 116, 116, 114, 97, 99, 116, 102, 111, 114, 99, 101, 82, 97, 100, 105, 117, + 115, 0, 118, 101, 108, 111, 99, 105, 116, 121, 102, 111, 114, 99, 101, 83, 116, 114, 101, 110, 103, 116, 104, 0, 118, 101, 108, 111, 99, 105, 116, 121, + 102, 111, 114, 99, 101, 82, 97, 100, 105, 117, 115, 0, 108, 97, 115, 116, 103, 111, 111, 100, 102, 114, 97, 109, 101, 0, 109, 105, 115, 116, 121, 112, + 101, 0, 104, 111, 114, 114, 0, 104, 111, 114, 103, 0, 104, 111, 114, 98, 0, 104, 111, 114, 107, 0, 122, 101, 110, 114, 0, 122, 101, 110, 103, 0, + 122, 101, 110, 98, 0, 122, 101, 110, 107, 0, 97, 109, 98, 107, 0, 102, 97, 115, 116, 99, 111, 108, 0, 101, 120, 112, 111, 115, 117, 114, 101, 0, + 101, 120, 112, 0, 114, 97, 110, 103, 101, 0, 108, 105, 110, 102, 97, 99, 0, 108, 111, 103, 102, 97, 99, 0, 103, 114, 97, 118, 105, 116, 121, 0, + 97, 99, 116, 105, 118, 105, 116, 121, 66, 111, 120, 82, 97, 100, 105, 117, 115, 0, 115, 107, 121, 116, 121, 112, 101, 0, 111, 99, 99, 108, 117, 115, + 105, 111, 110, 82, 101, 115, 0, 112, 104, 121, 115, 105, 99, 115, 69, 110, 103, 105, 110, 101, 0, 116, 105, 99, 114, 97, 116, 101, 0, 109, 97, 120, + 108, 111, 103, 105, 99, 115, 116, 101, 112, 0, 112, 104, 121, 115, 117, 98, 115, 116, 101, 112, 0, 109, 97, 120, 112, 104, 121, 115, 116, 101, 112, 0, + 109, 105, 115, 105, 0, 109, 105, 115, 116, 115, 116, 97, 0, 109, 105, 115, 116, 100, 105, 115, 116, 0, 109, 105, 115, 116, 104, 105, 0, 115, 116, 97, + 114, 114, 0, 115, 116, 97, 114, 103, 0, 115, 116, 97, 114, 98, 0, 115, 116, 97, 114, 107, 0, 115, 116, 97, 114, 115, 105, 122, 101, 0, 115, 116, + 97, 114, 109, 105, 110, 100, 105, 115, 116, 0, 115, 116, 97, 114, 100, 105, 115, 116, 0, 115, 116, 97, 114, 99, 111, 108, 110, 111, 105, 115, 101, 0, + 100, 111, 102, 115, 116, 97, 0, 100, 111, 102, 101, 110, 100, 0, 100, 111, 102, 109, 105, 110, 0, 100, 111, 102, 109, 97, 120, 0, 97, 111, 100, 105, + 115, 116, 0, 97, 111, 100, 105, 115, 116, 102, 97, 99, 0, 97, 111, 101, 110, 101, 114, 103, 121, 0, 97, 111, 98, 105, 97, 115, 0, 97, 111, 109, + 111, 100, 101, 0, 97, 111, 115, 97, 109, 112, 0, 97, 111, 109, 105, 120, 0, 97, 111, 99, 111, 108, 111, 114, 0, 97, 111, 95, 97, 100, 97, 112, + 116, 95, 116, 104, 114, 101, 115, 104, 0, 97, 111, 95, 97, 100, 97, 112, 116, 95, 115, 112, 101, 101, 100, 95, 102, 97, 99, 0, 97, 111, 95, 97, + 112, 112, 114, 111, 120, 95, 101, 114, 114, 111, 114, 0, 97, 111, 95, 97, 112, 112, 114, 111, 120, 95, 99, 111, 114, 114, 101, 99, 116, 105, 111, 110, + 0, 97, 111, 95, 115, 97, 109, 112, 95, 109, 101, 116, 104, 111, 100, 0, 97, 111, 95, 103, 97, 116, 104, 101, 114, 95, 109, 101, 116, 104, 111, 100, + 0, 97, 111, 95, 97, 112, 112, 114, 111, 120, 95, 112, 97, 115, 115, 101, 115, 0, 42, 97, 111, 115, 112, 104, 101, 114, 101, 0, 42, 97, 111, 116, + 97, 98, 108, 101, 115, 0, 104, 101, 109, 105, 114, 101, 115, 0, 109, 97, 120, 105, 116, 101, 114, 0, 100, 114, 97, 119, 116, 121, 112, 101, 0, 115, + 117, 98, 115, 104, 111, 111, 116, 112, 0, 115, 117, 98, 115, 104, 111, 111, 116, 101, 0, 110, 111, 100, 101, 108, 105, 109, 0, 109, 97, 120, 115, 117, + 98, 108, 97, 109, 112, 0, 112, 97, 109, 97, 0, 112, 97, 109, 105, 0, 101, 108, 109, 97, 0, 101, 108, 109, 105, 0, 109, 97, 120, 110, 111, 100, + 101, 0, 99, 111, 110, 118, 101, 114, 103, 101, 110, 99, 101, 0, 114, 97, 100, 102, 97, 99, 0, 103, 97, 109, 109, 97, 0, 115, 101, 108, 99, 111, + 108, 0, 115, 120, 0, 115, 121, 0, 42, 108, 112, 70, 111, 114, 109, 97, 116, 0, 42, 108, 112, 80, 97, 114, 109, 115, 0, 99, 98, 70, 111, 114, + 109, 97, 116, 0, 99, 98, 80, 97, 114, 109, 115, 0, 102, 99, 99, 84, 121, 112, 101, 0, 102, 99, 99, 72, 97, 110, 100, 108, 101, 114, 0, 100, + 119, 75, 101, 121, 70, 114, 97, 109, 101, 69, 118, 101, 114, 121, 0, 100, 119, 81, 117, 97, 108, 105, 116, 121, 0, 100, 119, 66, 121, 116, 101, 115, + 80, 101, 114, 83, 101, 99, 111, 110, 100, 0, 100, 119, 70, 108, 97, 103, 115, 0, 100, 119, 73, 110, 116, 101, 114, 108, 101, 97, 118, 101, 69, 118, + 101, 114, 121, 0, 97, 118, 105, 99, 111, 100, 101, 99, 110, 97, 109, 101, 91, 49, 50, 56, 93, 0, 42, 99, 100, 80, 97, 114, 109, 115, 0, 42, + 112, 97, 100, 0, 99, 100, 83, 105, 122, 101, 0, 113, 116, 99, 111, 100, 101, 99, 110, 97, 109, 101, 91, 49, 50, 56, 93, 0, 99, 111, 100, 101, + 99, 0, 97, 117, 100, 105, 111, 95, 99, 111, 100, 101, 99, 0, 118, 105, 100, 101, 111, 95, 98, 105, 116, 114, 97, 116, 101, 0, 97, 117, 100, 105, + 111, 95, 98, 105, 116, 114, 97, 116, 101, 0, 103, 111, 112, 95, 115, 105, 122, 101, 0, 114, 99, 95, 109, 105, 110, 95, 114, 97, 116, 101, 0, 114, + 99, 95, 109, 97, 120, 95, 114, 97, 116, 101, 0, 114, 99, 95, 98, 117, 102, 102, 101, 114, 95, 115, 105, 122, 101, 0, 109, 117, 120, 95, 112, 97, + 99, 107, 101, 116, 95, 115, 105, 122, 101, 0, 109, 117, 120, 95, 114, 97, 116, 101, 0, 109, 105, 120, 114, 97, 116, 101, 0, 109, 97, 105, 110, 0, + 42, 109, 97, 116, 95, 111, 118, 101, 114, 114, 105, 100, 101, 0, 42, 108, 105, 103, 104, 116, 95, 111, 118, 101, 114, 114, 105, 100, 101, 0, 108, 97, + 121, 95, 122, 109, 97, 115, 107, 0, 108, 97, 121, 102, 108, 97, 103, 0, 112, 97, 115, 115, 102, 108, 97, 103, 0, 112, 97, 115, 115, 95, 120, 111, + 114, 0, 42, 97, 118, 105, 99, 111, 100, 101, 99, 100, 97, 116, 97, 0, 42, 113, 116, 99, 111, 100, 101, 99, 100, 97, 116, 97, 0, 102, 102, 99, + 111, 100, 101, 99, 100, 97, 116, 97, 0, 99, 102, 114, 97, 0, 112, 115, 102, 114, 97, 0, 112, 101, 102, 114, 97, 0, 105, 109, 97, 103, 101, 115, + 0, 102, 114, 97, 109, 97, 112, 116, 111, 0, 116, 104, 114, 101, 97, 100, 115, 0, 102, 114, 97, 109, 101, 108, 101, 110, 0, 98, 108, 117, 114, 102, + 97, 99, 0, 101, 100, 103, 101, 82, 0, 101, 100, 103, 101, 71, 0, 101, 100, 103, 101, 66, 0, 102, 117, 108, 108, 115, 99, 114, 101, 101, 110, 0, + 120, 112, 108, 97, 121, 0, 121, 112, 108, 97, 121, 0, 102, 114, 101, 113, 112, 108, 97, 121, 0, 97, 116, 116, 114, 105, 98, 0, 114, 116, 49, 0, + 115, 116, 101, 114, 101, 111, 109, 111, 100, 101, 0, 100, 105, 109, 101, 110, 115, 105, 111, 110, 115, 112, 114, 101, 115, 101, 116, 0, 109, 97, 120, 105, + 109, 115, 105, 122, 101, 0, 120, 115, 99, 104, 0, 121, 115, 99, 104, 0, 120, 112, 97, 114, 116, 115, 0, 121, 112, 97, 114, 116, 115, 0, 119, 105, + 110, 112, 111, 115, 0, 112, 108, 97, 110, 101, 115, 0, 105, 109, 116, 121, 112, 101, 0, 115, 117, 98, 105, 109, 116, 121, 112, 101, 0, 113, 117, 97, + 108, 105, 116, 121, 0, 114, 112, 97, 100, 0, 114, 112, 97, 100, 49, 0, 114, 112, 97, 100, 50, 0, 115, 99, 101, 109, 111, 100, 101, 0, 114, 101, + 110, 100, 101, 114, 101, 114, 0, 111, 99, 114, 101, 115, 0, 97, 108, 112, 104, 97, 109, 111, 100, 101, 0, 111, 115, 97, 0, 102, 114, 115, 95, 115, + 101, 99, 0, 101, 100, 103, 101, 105, 110, 116, 0, 115, 97, 102, 101, 116, 121, 0, 98, 111, 114, 100, 101, 114, 0, 100, 105, 115, 112, 114, 101, 99, + 116, 0, 108, 97, 121, 101, 114, 115, 0, 97, 99, 116, 108, 97, 121, 0, 120, 97, 115, 112, 0, 121, 97, 115, 112, 0, 102, 114, 115, 95, 115, 101, + 99, 95, 98, 97, 115, 101, 0, 103, 97, 117, 115, 115, 0, 112, 111, 115, 116, 109, 117, 108, 0, 112, 111, 115, 116, 103, 97, 109, 109, 97, 0, 112, + 111, 115, 116, 104, 117, 101, 0, 112, 111, 115, 116, 115, 97, 116, 0, 100, 105, 116, 104, 101, 114, 95, 105, 110, 116, 101, 110, 115, 105, 116, 121, 0, + 98, 97, 107, 101, 95, 111, 115, 97, 0, 98, 97, 107, 101, 95, 102, 105, 108, 116, 101, 114, 0, 98, 97, 107, 101, 95, 109, 111, 100, 101, 0, 98, + 97, 107, 101, 95, 102, 108, 97, 103, 0, 98, 97, 107, 101, 95, 110, 111, 114, 109, 97, 108, 95, 115, 112, 97, 99, 101, 0, 98, 97, 107, 101, 95, + 113, 117, 97, 100, 95, 115, 112, 108, 105, 116, 0, 98, 97, 107, 101, 95, 109, 97, 120, 100, 105, 115, 116, 0, 98, 97, 107, 101, 95, 98, 105, 97, + 115, 100, 105, 115, 116, 0, 98, 97, 107, 101, 95, 112, 97, 100, 0, 71, 73, 113, 117, 97, 108, 105, 116, 121, 0, 71, 73, 99, 97, 99, 104, 101, + 0, 71, 73, 109, 101, 116, 104, 111, 100, 0, 71, 73, 112, 104, 111, 116, 111, 110, 115, 0, 71, 73, 100, 105, 114, 101, 99, 116, 0, 89, 70, 95, + 65, 65, 0, 89, 70, 101, 120, 112, 111, 114, 116, 120, 109, 108, 0, 89, 70, 95, 110, 111, 98, 117, 109, 112, 0, 89, 70, 95, 99, 108, 97, 109, + 112, 114, 103, 98, 0, 121, 102, 112, 97, 100, 49, 0, 71, 73, 100, 101, 112, 116, 104, 0, 71, 73, 99, 97, 117, 115, 100, 101, 112, 116, 104, 0, + 71, 73, 112, 105, 120, 101, 108, 115, 112, 101, 114, 115, 97, 109, 112, 108, 101, 0, 71, 73, 112, 104, 111, 116, 111, 110, 99, 111, 117, 110, 116, 0, + 71, 73, 109, 105, 120, 112, 104, 111, 116, 111, 110, 115, 0, 71, 73, 112, 104, 111, 116, 111, 110, 114, 97, 100, 105, 117, 115, 0, 89, 70, 95, 114, + 97, 121, 100, 101, 112, 116, 104, 0, 89, 70, 95, 65, 65, 112, 97, 115, 115, 101, 115, 0, 89, 70, 95, 65, 65, 115, 97, 109, 112, 108, 101, 115, + 0, 121, 102, 112, 97, 100, 50, 0, 71, 73, 115, 104, 97, 100, 111, 119, 113, 117, 97, 108, 105, 116, 121, 0, 71, 73, 114, 101, 102, 105, 110, 101, + 109, 101, 110, 116, 0, 71, 73, 112, 111, 119, 101, 114, 0, 71, 73, 105, 110, 100, 105, 114, 112, 111, 119, 101, 114, 0, 89, 70, 95, 103, 97, 109, + 109, 97, 0, 89, 70, 95, 101, 120, 112, 111, 115, 117, 114, 101, 0, 89, 70, 95, 114, 97, 121, 98, 105, 97, 115, 0, 89, 70, 95, 65, 65, 112, + 105, 120, 101, 108, 115, 105, 122, 101, 0, 89, 70, 95, 65, 65, 116, 104, 114, 101, 115, 104, 111, 108, 100, 0, 98, 97, 99, 107, 98, 117, 102, 91, + 49, 54, 48, 93, 0, 112, 105, 99, 91, 49, 54, 48, 93, 0, 115, 116, 97, 109, 112, 0, 115, 116, 97, 109, 112, 95, 102, 111, 110, 116, 95, 105, + 100, 0, 115, 116, 97, 109, 112, 95, 117, 100, 97, 116, 97, 91, 49, 54, 48, 93, 0, 102, 103, 95, 115, 116, 97, 109, 112, 91, 52, 93, 0, 98, + 103, 95, 115, 116, 97, 109, 112, 91, 52, 93, 0, 115, 105, 109, 112, 108, 105, 102, 121, 95, 115, 117, 98, 115, 117, 114, 102, 0, 115, 105, 109, 112, + 108, 105, 102, 121, 95, 115, 104, 97, 100, 111, 119, 115, 97, 109, 112, 108, 101, 115, 0, 115, 105, 109, 112, 108, 105, 102, 121, 95, 112, 97, 114, 116, + 105, 99, 108, 101, 115, 0, 115, 105, 109, 112, 108, 105, 102, 121, 95, 97, 111, 115, 115, 115, 0, 99, 105, 110, 101, 111, 110, 119, 104, 105, 116, 101, + 0, 99, 105, 110, 101, 111, 110, 98, 108, 97, 99, 107, 0, 99, 105, 110, 101, 111, 110, 103, 97, 109, 109, 97, 0, 106, 112, 50, 95, 112, 114, 101, + 115, 101, 116, 0, 106, 112, 50, 95, 100, 101, 112, 116, 104, 0, 114, 112, 97, 100, 51, 0, 100, 111, 109, 101, 114, 101, 115, 0, 100, 111, 109, 101, + 109, 111, 100, 101, 0, 100, 111, 109, 101, 97, 110, 103, 108, 101, 0, 100, 111, 109, 101, 116, 105, 108, 116, 0, 100, 111, 109, 101, 114, 101, 115, 98, + 117, 102, 0, 42, 100, 111, 109, 101, 116, 101, 120, 116, 0, 112, 97, 114, 116, 105, 99, 108, 101, 95, 112, 101, 114, 99, 0, 115, 117, 98, 115, 117, + 114, 102, 95, 109, 97, 120, 0, 115, 104, 97, 100, 98, 117, 102, 115, 97, 109, 112, 108, 101, 95, 109, 97, 120, 0, 97, 111, 95, 101, 114, 114, 111, + 114, 0, 99, 111, 108, 91, 51, 93, 0, 102, 114, 97, 109, 101, 0, 110, 97, 109, 101, 91, 54, 52, 93, 0, 42, 98, 114, 117, 115, 104, 0, 116, + 111, 111, 108, 0, 115, 101, 97, 109, 95, 98, 108, 101, 101, 100, 0, 110, 111, 114, 109, 97, 108, 95, 97, 110, 103, 108, 101, 0, 115, 116, 101, 112, + 0, 105, 110, 118, 101, 114, 116, 0, 116, 111, 116, 114, 101, 107, 101, 121, 0, 116, 111, 116, 97, 100, 100, 107, 101, 121, 0, 98, 114, 117, 115, 104, + 116, 121, 112, 101, 0, 98, 114, 117, 115, 104, 91, 55, 93, 0, 101, 109, 105, 116, 116, 101, 114, 100, 105, 115, 116, 0, 100, 114, 97, 119, 95, 116, + 105, 109, 101, 100, 0, 110, 97, 109, 101, 91, 51, 54, 93, 0, 109, 97, 116, 91, 51, 93, 91, 51, 93, 0, 99, 111, 114, 110, 101, 114, 116, 121, + 112, 101, 0, 101, 100, 105, 116, 98, 117, 116, 102, 108, 97, 103, 0, 106, 111, 105, 110, 116, 114, 105, 108, 105, 109, 105, 116, 0, 100, 101, 103, 114, + 0, 116, 117, 114, 110, 0, 101, 120, 116, 114, 95, 111, 102, 102, 115, 0, 100, 111, 117, 98, 108, 105, 109, 105, 116, 0, 115, 101, 103, 109, 101, 110, + 116, 115, 0, 114, 105, 110, 103, 115, 0, 118, 101, 114, 116, 105, 99, 101, 115, 0, 117, 110, 119, 114, 97, 112, 112, 101, 114, 0, 117, 118, 99, 97, + 108, 99, 95, 114, 97, 100, 105, 117, 115, 0, 117, 118, 99, 97, 108, 99, 95, 99, 117, 98, 101, 115, 105, 122, 101, 0, 117, 118, 99, 97, 108, 99, + 95, 109, 97, 114, 103, 105, 110, 0, 117, 118, 99, 97, 108, 99, 95, 109, 97, 112, 100, 105, 114, 0, 117, 118, 99, 97, 108, 99, 95, 109, 97, 112, + 97, 108, 105, 103, 110, 0, 117, 118, 99, 97, 108, 99, 95, 102, 108, 97, 103, 0, 97, 117, 116, 111, 105, 107, 95, 99, 104, 97, 105, 110, 108, 101, + 110, 0, 105, 109, 97, 112, 97, 105, 110, 116, 0, 112, 97, 114, 116, 105, 99, 108, 101, 0, 115, 101, 108, 101, 99, 116, 95, 116, 104, 114, 101, 115, + 104, 0, 99, 108, 101, 97, 110, 95, 116, 104, 114, 101, 115, 104, 0, 114, 101, 116, 111, 112, 111, 95, 109, 111, 100, 101, 0, 114, 101, 116, 111, 112, + 111, 95, 112, 97, 105, 110, 116, 95, 116, 111, 111, 108, 0, 108, 105, 110, 101, 95, 100, 105, 118, 0, 101, 108, 108, 105, 112, 115, 101, 95, 100, 105, + 118, 0, 114, 101, 116, 111, 112, 111, 95, 104, 111, 116, 115, 112, 111, 116, 0, 109, 117, 108, 116, 105, 114, 101, 115, 95, 115, 117, 98, 100, 105, 118, + 95, 116, 121, 112, 101, 0, 115, 107, 103, 101, 110, 95, 114, 101, 115, 111, 108, 117, 116, 105, 111, 110, 0, 115, 107, 103, 101, 110, 95, 116, 104, 114, + 101, 115, 104, 111, 108, 100, 95, 105, 110, 116, 101, 114, 110, 97, 108, 0, 115, 107, 103, 101, 110, 95, 116, 104, 114, 101, 115, 104, 111, 108, 100, 95, + 101, 120, 116, 101, 114, 110, 97, 108, 0, 115, 107, 103, 101, 110, 95, 108, 101, 110, 103, 116, 104, 95, 114, 97, 116, 105, 111, 0, 115, 107, 103, 101, + 110, 95, 108, 101, 110, 103, 116, 104, 95, 108, 105, 109, 105, 116, 0, 115, 107, 103, 101, 110, 95, 97, 110, 103, 108, 101, 95, 108, 105, 109, 105, 116, + 0, 115, 107, 103, 101, 110, 95, 99, 111, 114, 114, 101, 108, 97, 116, 105, 111, 110, 95, 108, 105, 109, 105, 116, 0, 115, 107, 103, 101, 110, 95, 115, + 121, 109, 109, 101, 116, 114, 121, 95, 108, 105, 109, 105, 116, 0, 115, 107, 103, 101, 110, 95, 114, 101, 116, 97, 114, 103, 101, 116, 95, 97, 110, 103, + 108, 101, 95, 119, 101, 105, 103, 104, 116, 0, 115, 107, 103, 101, 110, 95, 114, 101, 116, 97, 114, 103, 101, 116, 95, 108, 101, 110, 103, 116, 104, 95, + 119, 101, 105, 103, 104, 116, 0, 115, 107, 103, 101, 110, 95, 114, 101, 116, 97, 114, 103, 101, 116, 95, 100, 105, 115, 116, 97, 110, 99, 101, 95, 119, + 101, 105, 103, 104, 116, 0, 115, 107, 103, 101, 110, 95, 111, 112, 116, 105, 111, 110, 115, 0, 115, 107, 103, 101, 110, 95, 112, 111, 115, 116, 112, 114, + 111, 0, 115, 107, 103, 101, 110, 95, 112, 111, 115, 116, 112, 114, 111, 95, 112, 97, 115, 115, 101, 115, 0, 115, 107, 103, 101, 110, 95, 115, 117, 98, + 100, 105, 118, 105, 115, 105, 111, 110, 115, 91, 51, 93, 0, 115, 107, 103, 101, 110, 95, 109, 117, 108, 116, 105, 95, 108, 101, 118, 101, 108, 0, 42, + 115, 107, 103, 101, 110, 95, 116, 101, 109, 112, 108, 97, 116, 101, 0, 98, 111, 110, 101, 95, 115, 107, 101, 116, 99, 104, 105, 110, 103, 0, 98, 111, + 110, 101, 95, 115, 107, 101, 116, 99, 104, 105, 110, 103, 95, 99, 111, 110, 118, 101, 114, 116, 0, 115, 107, 103, 101, 110, 95, 115, 117, 98, 100, 105, + 118, 105, 115, 105, 111, 110, 95, 110, 117, 109, 98, 101, 114, 0, 115, 107, 103, 101, 110, 95, 114, 101, 116, 97, 114, 103, 101, 116, 95, 111, 112, 116, + 105, 111, 110, 115, 0, 115, 107, 103, 101, 110, 95, 114, 101, 116, 97, 114, 103, 101, 116, 95, 114, 111, 108, 108, 0, 115, 107, 103, 101, 110, 95, 115, + 105, 100, 101, 95, 115, 116, 114, 105, 110, 103, 91, 56, 93, 0, 115, 107, 103, 101, 110, 95, 110, 117, 109, 95, 115, 116, 114, 105, 110, 103, 91, 56, + 93, 0, 101, 100, 103, 101, 95, 109, 111, 100, 101, 0, 112, 97, 100, 51, 91, 50, 93, 0, 100, 105, 114, 0, 118, 105, 101, 119, 0, 42, 115, 101, + 115, 115, 105, 111, 110, 0, 42, 99, 117, 109, 97, 112, 0, 100, 114, 97, 119, 98, 114, 117, 115, 104, 0, 115, 109, 111, 111, 116, 104, 98, 114, 117, + 115, 104, 0, 112, 105, 110, 99, 104, 98, 114, 117, 115, 104, 0, 105, 110, 102, 108, 97, 116, 101, 98, 114, 117, 115, 104, 0, 103, 114, 97, 98, 98, + 114, 117, 115, 104, 0, 108, 97, 121, 101, 114, 98, 114, 117, 115, 104, 0, 102, 108, 97, 116, 116, 101, 110, 98, 114, 117, 115, 104, 0, 112, 105, 118, + 111, 116, 91, 51, 93, 0, 98, 114, 117, 115, 104, 95, 116, 121, 112, 101, 0, 116, 101, 120, 110, 114, 0, 116, 101, 120, 114, 101, 112, 116, 0, 116, + 101, 120, 102, 97, 100, 101, 0, 116, 101, 120, 115, 101, 112, 0, 97, 118, 101, 114, 97, 103, 105, 110, 103, 0, 116, 97, 98, 108, 101, 116, 95, 115, + 105, 122, 101, 0, 116, 97, 98, 108, 101, 116, 95, 115, 116, 114, 101, 110, 103, 116, 104, 0, 115, 121, 109, 109, 0, 114, 97, 107, 101, 0, 97, 120, + 105, 115, 108, 111, 99, 107, 0, 42, 99, 97, 109, 101, 114, 97, 0, 42, 119, 111, 114, 108, 100, 0, 42, 115, 101, 116, 0, 98, 97, 115, 101, 0, + 42, 98, 97, 115, 97, 99, 116, 0, 99, 117, 114, 115, 111, 114, 91, 51, 93, 0, 116, 119, 99, 101, 110, 116, 91, 51, 93, 0, 116, 119, 109, 105, + 110, 91, 51, 93, 0, 116, 119, 109, 97, 120, 91, 51, 93, 0, 101, 100, 105, 116, 98, 117, 116, 115, 105, 122, 101, 0, 115, 101, 108, 101, 99, 116, + 109, 111, 100, 101, 0, 112, 114, 111, 112, 111, 114, 116, 105, 111, 110, 97, 108, 0, 112, 114, 111, 112, 95, 109, 111, 100, 101, 0, 97, 117, 116, 111, + 109, 101, 114, 103, 101, 0, 112, 97, 100, 53, 0, 112, 97, 100, 54, 0, 97, 117, 116, 111, 107, 101, 121, 95, 109, 111, 100, 101, 0, 42, 101, 100, + 0, 42, 114, 97, 100, 105, 111, 0, 102, 114, 97, 109, 105, 110, 103, 0, 42, 116, 111, 111, 108, 115, 101, 116, 116, 105, 110, 103, 115, 0, 97, 117, + 100, 105, 111, 0, 116, 114, 97, 110, 115, 102, 111, 114, 109, 95, 115, 112, 97, 99, 101, 115, 0, 106, 117, 109, 112, 102, 114, 97, 109, 101, 0, 115, + 110, 97, 112, 95, 109, 111, 100, 101, 0, 115, 110, 97, 112, 95, 102, 108, 97, 103, 0, 115, 110, 97, 112, 95, 116, 97, 114, 103, 101, 116, 0, 42, + 116, 104, 101, 68, 97, 103, 0, 100, 97, 103, 105, 115, 118, 97, 108, 105, 100, 0, 100, 97, 103, 102, 108, 97, 103, 115, 0, 115, 99, 117, 108, 112, + 116, 100, 97, 116, 97, 0, 102, 114, 97, 109, 101, 95, 115, 116, 101, 112, 0, 122, 111, 111, 109, 0, 98, 108, 101, 110, 100, 0, 120, 105, 109, 0, + 121, 105, 109, 0, 115, 112, 97, 99, 101, 116, 121, 112, 101, 0, 98, 108, 111, 99, 107, 115, 99, 97, 108, 101, 0, 42, 97, 114, 101, 97, 0, 98, + 108, 111, 99, 107, 104, 97, 110, 100, 108, 101, 114, 91, 56, 93, 0, 118, 105, 101, 119, 109, 97, 116, 91, 52, 93, 91, 52, 93, 0, 118, 105, 101, + 119, 105, 110, 118, 91, 52, 93, 91, 52, 93, 0, 112, 101, 114, 115, 109, 97, 116, 91, 52, 93, 91, 52, 93, 0, 112, 101, 114, 115, 105, 110, 118, + 91, 52, 93, 91, 52, 93, 0, 119, 105, 110, 109, 97, 116, 49, 91, 52, 93, 91, 52, 93, 0, 118, 105, 101, 119, 109, 97, 116, 49, 91, 52, 93, + 91, 52, 93, 0, 118, 105, 101, 119, 113, 117, 97, 116, 91, 52, 93, 0, 122, 102, 97, 99, 0, 108, 97, 121, 95, 117, 115, 101, 100, 0, 112, 101, + 114, 115, 112, 0, 42, 111, 98, 95, 99, 101, 110, 116, 114, 101, 0, 42, 98, 103, 112, 105, 99, 0, 42, 108, 111, 99, 97, 108, 118, 100, 0, 42, + 114, 105, 0, 42, 114, 101, 116, 111, 112, 111, 95, 118, 105, 101, 119, 95, 100, 97, 116, 97, 0, 42, 100, 101, 112, 116, 104, 115, 0, 111, 98, 95, + 99, 101, 110, 116, 114, 101, 95, 98, 111, 110, 101, 91, 51, 50, 93, 0, 108, 111, 99, 97, 108, 118, 105, 101, 119, 0, 108, 97, 121, 97, 99, 116, + 0, 115, 99, 101, 110, 101, 108, 111, 99, 107, 0, 97, 114, 111, 117, 110, 100, 0, 99, 97, 109, 122, 111, 111, 109, 0, 112, 105, 118, 111, 116, 95, + 108, 97, 115, 116, 0, 103, 114, 105, 100, 0, 103, 114, 105, 100, 118, 105, 101, 119, 0, 112, 105, 120, 115, 105, 122, 101, 0, 110, 101, 97, 114, 0, + 102, 97, 114, 0, 99, 97, 109, 100, 120, 0, 99, 97, 109, 100, 121, 0, 103, 114, 105, 100, 108, 105, 110, 101, 115, 0, 118, 105, 101, 119, 98, 117, + 116, 0, 103, 114, 105, 100, 102, 108, 97, 103, 0, 109, 111, 100, 101, 115, 101, 108, 101, 99, 116, 0, 116, 119, 116, 121, 112, 101, 0, 116, 119, 109, + 111, 100, 101, 0, 116, 119, 102, 108, 97, 103, 0, 116, 119, 100, 114, 97, 119, 102, 108, 97, 103, 0, 116, 119, 109, 97, 116, 91, 52, 93, 91, 52, + 93, 0, 99, 108, 105, 112, 91, 52, 93, 91, 52, 93, 0, 42, 99, 108, 105, 112, 98, 98, 0, 97, 102, 116, 101, 114, 100, 114, 97, 119, 0, 122, + 98, 117, 102, 0, 120, 114, 97, 121, 0, 102, 108, 97, 103, 50, 0, 103, 114, 105, 100, 115, 117, 98, 100, 105, 118, 0, 107, 101, 121, 102, 108, 97, + 103, 115, 0, 110, 100, 111, 102, 109, 111, 100, 101, 0, 110, 100, 111, 102, 102, 105, 108, 116, 101, 114, 0, 42, 112, 114, 111, 112, 101, 114, 116, 105, + 101, 115, 95, 115, 116, 111, 114, 97, 103, 101, 0, 42, 103, 112, 100, 0, 108, 118, 105, 101, 119, 113, 117, 97, 116, 91, 52, 93, 0, 108, 112, 101, + 114, 115, 112, 0, 108, 118, 105, 101, 119, 0, 118, 101, 114, 116, 0, 104, 111, 114, 0, 109, 97, 115, 107, 0, 109, 105, 110, 91, 50, 93, 0, 109, + 97, 120, 91, 50, 93, 0, 109, 105, 110, 122, 111, 111, 109, 0, 109, 97, 120, 122, 111, 111, 109, 0, 115, 99, 114, 111, 108, 108, 0, 107, 101, 101, + 112, 116, 111, 116, 0, 107, 101, 101, 112, 97, 115, 112, 101, 99, 116, 0, 107, 101, 101, 112, 122, 111, 111, 109, 0, 111, 108, 100, 119, 105, 110, 120, + 0, 111, 108, 100, 119, 105, 110, 121, 0, 99, 117, 114, 115, 111, 114, 91, 50, 93, 0, 114, 111, 119, 98, 117, 116, 0, 118, 50, 100, 0, 42, 101, + 100, 105, 116, 105, 112, 111, 0, 105, 112, 111, 107, 101, 121, 0, 97, 99, 116, 110, 97, 109, 101, 91, 51, 50, 93, 0, 99, 111, 110, 115, 116, 110, + 97, 109, 101, 91, 51, 50, 93, 0, 98, 111, 110, 101, 110, 97, 109, 101, 91, 51, 50, 93, 0, 116, 111, 116, 105, 112, 111, 0, 112, 105, 110, 0, + 98, 117, 116, 111, 102, 115, 0, 99, 104, 97, 110, 110, 101, 108, 0, 108, 111, 99, 107, 0, 109, 101, 100, 105, 97, 110, 91, 51, 93, 0, 99, 117, + 114, 115, 101, 110, 115, 0, 99, 117, 114, 97, 99, 116, 0, 97, 108, 105, 103, 110, 0, 116, 97, 98, 111, 0, 109, 97, 105, 110, 98, 0, 109, 97, + 105, 110, 98, 111, 0, 42, 108, 111, 99, 107, 112, 111, 105, 110, 0, 116, 101, 120, 102, 114, 111, 109, 0, 115, 104, 111, 119, 103, 114, 111, 117, 112, + 0, 109, 111, 100, 101, 108, 116, 121, 112, 101, 0, 115, 99, 114, 105, 112, 116, 98, 108, 111, 99, 107, 0, 114, 101, 95, 97, 108, 105, 103, 110, 0, + 111, 108, 100, 107, 101, 121, 112, 114, 101, 115, 115, 0, 116, 97, 98, 91, 55, 93, 0, 114, 101, 110, 100, 101, 114, 95, 115, 105, 122, 101, 0, 99, + 104, 97, 110, 115, 104, 111, 119, 110, 0, 122, 101, 98, 114, 97, 0, 42, 102, 105, 108, 101, 108, 105, 115, 116, 0, 116, 111, 116, 102, 105, 108, 101, + 0, 116, 105, 116, 108, 101, 91, 50, 52, 93, 0, 100, 105, 114, 91, 50, 52, 48, 93, 0, 102, 105, 108, 101, 91, 56, 48, 93, 0, 111, 102, 115, + 0, 115, 111, 114, 116, 0, 109, 97, 120, 110, 97, 109, 101, 108, 101, 110, 0, 99, 111, 108, 108, 117, 109, 115, 0, 102, 95, 102, 112, 0, 102, 112, + 95, 115, 116, 114, 91, 56, 93, 0, 42, 108, 105, 98, 102, 105, 108, 101, 100, 97, 116, 97, 0, 114, 101, 116, 118, 97, 108, 0, 109, 101, 110, 117, + 0, 97, 99, 116, 0, 40, 42, 114, 101, 116, 117, 114, 110, 102, 117, 110, 99, 41, 40, 41, 0, 40, 42, 114, 101, 116, 117, 114, 110, 102, 117, 110, + 99, 95, 101, 118, 101, 110, 116, 41, 40, 41, 0, 40, 42, 114, 101, 116, 117, 114, 110, 102, 117, 110, 99, 95, 97, 114, 103, 115, 41, 40, 41, 0, + 42, 97, 114, 103, 49, 0, 42, 97, 114, 103, 50, 0, 42, 109, 101, 110, 117, 112, 0, 42, 112, 117, 112, 109, 101, 110, 117, 0, 111, 111, 112, 115, + 0, 118, 105, 115, 105, 102, 108, 97, 103, 0, 116, 114, 101, 101, 0, 42, 116, 114, 101, 101, 115, 116, 111, 114, 101, 0, 115, 101, 97, 114, 99, 104, + 95, 115, 116, 114, 105, 110, 103, 91, 51, 50, 93, 0, 115, 101, 97, 114, 99, 104, 95, 116, 115, 101, 0, 115, 101, 97, 114, 99, 104, 95, 102, 108, + 97, 103, 115, 0, 100, 111, 95, 0, 111, 117, 116, 108, 105, 110, 101, 118, 105, 115, 0, 115, 116, 111, 114, 101, 102, 108, 97, 103, 0, 100, 101, 112, + 115, 95, 102, 108, 97, 103, 115, 0, 105, 109, 97, 110, 114, 0, 99, 117, 114, 116, 105, 108, 101, 0, 105, 109, 116, 121, 112, 101, 110, 114, 0, 100, + 116, 95, 117, 118, 0, 115, 116, 105, 99, 107, 121, 0, 100, 116, 95, 117, 118, 115, 116, 114, 101, 116, 99, 104, 0, 112, 97, 100, 91, 53, 93, 0, + 99, 101, 110, 116, 120, 0, 99, 101, 110, 116, 121, 0, 97, 117, 116, 111, 115, 110, 97, 112, 0, 42, 116, 101, 120, 116, 0, 116, 111, 112, 0, 118, + 105, 101, 119, 108, 105, 110, 101, 115, 0, 102, 111, 110, 116, 95, 105, 100, 0, 108, 104, 101, 105, 103, 104, 116, 0, 108, 101, 102, 116, 0, 115, 104, + 111, 119, 108, 105, 110, 101, 110, 114, 115, 0, 116, 97, 98, 110, 117, 109, 98, 101, 114, 0, 99, 117, 114, 114, 116, 97, 98, 95, 115, 101, 116, 0, + 115, 104, 111, 119, 115, 121, 110, 116, 97, 120, 0, 111, 118, 101, 114, 119, 114, 105, 116, 101, 0, 112, 105, 120, 95, 112, 101, 114, 95, 108, 105, 110, + 101, 0, 116, 120, 116, 115, 99, 114, 111, 108, 108, 0, 116, 120, 116, 98, 97, 114, 0, 119, 111, 114, 100, 119, 114, 97, 112, 0, 100, 111, 112, 108, + 117, 103, 105, 110, 115, 0, 42, 112, 121, 95, 100, 114, 97, 119, 0, 42, 112, 121, 95, 101, 118, 101, 110, 116, 0, 42, 112, 121, 95, 98, 117, 116, + 116, 111, 110, 0, 42, 112, 121, 95, 98, 114, 111, 119, 115, 101, 114, 99, 97, 108, 108, 98, 97, 99, 107, 0, 42, 112, 121, 95, 103, 108, 111, 98, + 97, 108, 100, 105, 99, 116, 0, 108, 97, 115, 116, 115, 112, 97, 99, 101, 0, 115, 99, 114, 105, 112, 116, 110, 97, 109, 101, 91, 50, 53, 54, 93, + 0, 115, 99, 114, 105, 112, 116, 97, 114, 103, 91, 50, 53, 54, 93, 0, 42, 115, 99, 114, 105, 112, 116, 0, 42, 98, 117, 116, 95, 114, 101, 102, + 115, 0, 114, 101, 100, 114, 97, 119, 115, 0, 42, 105, 100, 0, 97, 115, 112, 101, 99, 116, 0, 42, 99, 117, 114, 102, 111, 110, 116, 0, 42, 101, + 100, 105, 116, 116, 114, 101, 101, 0, 116, 114, 101, 101, 116, 121, 112, 101, 0, 42, 102, 105, 108, 101, 115, 0, 97, 99, 116, 105, 118, 101, 95, 102, + 105, 108, 101, 0, 110, 117, 109, 116, 105, 108, 101, 115, 120, 0, 110, 117, 109, 116, 105, 108, 101, 115, 121, 0, 115, 101, 108, 115, 116, 97, 116, 101, + 0, 118, 105, 101, 119, 114, 101, 99, 116, 0, 98, 111, 111, 107, 109, 97, 114, 107, 114, 101, 99, 116, 0, 115, 99, 114, 111, 108, 108, 112, 111, 115, + 0, 115, 99, 114, 111, 108, 108, 104, 101, 105, 103, 104, 116, 0, 115, 99, 114, 111, 108, 108, 97, 114, 101, 97, 0, 97, 99, 116, 105, 118, 101, 95, + 98, 111, 111, 107, 109, 97, 114, 107, 0, 112, 114, 118, 95, 119, 0, 112, 114, 118, 95, 104, 0, 42, 105, 109, 103, 0, 111, 117, 116, 108, 105, 110, + 101, 91, 52, 93, 0, 110, 101, 117, 116, 114, 97, 108, 91, 52, 93, 0, 97, 99, 116, 105, 111, 110, 91, 52, 93, 0, 115, 101, 116, 116, 105, 110, + 103, 91, 52, 93, 0, 115, 101, 116, 116, 105, 110, 103, 49, 91, 52, 93, 0, 115, 101, 116, 116, 105, 110, 103, 50, 91, 52, 93, 0, 110, 117, 109, + 91, 52, 93, 0, 116, 101, 120, 116, 102, 105, 101, 108, 100, 91, 52, 93, 0, 116, 101, 120, 116, 102, 105, 101, 108, 100, 95, 104, 105, 91, 52, 93, + 0, 112, 111, 112, 117, 112, 91, 52, 93, 0, 116, 101, 120, 116, 91, 52, 93, 0, 116, 101, 120, 116, 95, 104, 105, 91, 52, 93, 0, 109, 101, 110, + 117, 95, 98, 97, 99, 107, 91, 52, 93, 0, 109, 101, 110, 117, 95, 105, 116, 101, 109, 91, 52, 93, 0, 109, 101, 110, 117, 95, 104, 105, 108, 105, + 116, 101, 91, 52, 93, 0, 109, 101, 110, 117, 95, 116, 101, 120, 116, 91, 52, 93, 0, 109, 101, 110, 117, 95, 116, 101, 120, 116, 95, 104, 105, 91, + 52, 93, 0, 98, 117, 116, 95, 100, 114, 97, 119, 116, 121, 112, 101, 0, 105, 99, 111, 110, 102, 105, 108, 101, 91, 56, 48, 93, 0, 98, 97, 99, + 107, 91, 52, 93, 0, 104, 101, 97, 100, 101, 114, 91, 52, 93, 0, 112, 97, 110, 101, 108, 91, 52, 93, 0, 115, 104, 97, 100, 101, 49, 91, 52, + 93, 0, 115, 104, 97, 100, 101, 50, 91, 52, 93, 0, 104, 105, 108, 105, 116, 101, 91, 52, 93, 0, 103, 114, 105, 100, 91, 52, 93, 0, 119, 105, + 114, 101, 91, 52, 93, 0, 115, 101, 108, 101, 99, 116, 91, 52, 93, 0, 108, 97, 109, 112, 91, 52, 93, 0, 97, 99, 116, 105, 118, 101, 91, 52, + 93, 0, 103, 114, 111, 117, 112, 91, 52, 93, 0, 103, 114, 111, 117, 112, 95, 97, 99, 116, 105, 118, 101, 91, 52, 93, 0, 116, 114, 97, 110, 115, + 102, 111, 114, 109, 91, 52, 93, 0, 118, 101, 114, 116, 101, 120, 91, 52, 93, 0, 118, 101, 114, 116, 101, 120, 95, 115, 101, 108, 101, 99, 116, 91, + 52, 93, 0, 101, 100, 103, 101, 91, 52, 93, 0, 101, 100, 103, 101, 95, 115, 101, 108, 101, 99, 116, 91, 52, 93, 0, 101, 100, 103, 101, 95, 115, + 101, 97, 109, 91, 52, 93, 0, 101, 100, 103, 101, 95, 115, 104, 97, 114, 112, 91, 52, 93, 0, 101, 100, 103, 101, 95, 102, 97, 99, 101, 115, 101, + 108, 91, 52, 93, 0, 102, 97, 99, 101, 91, 52, 93, 0, 102, 97, 99, 101, 95, 115, 101, 108, 101, 99, 116, 91, 52, 93, 0, 102, 97, 99, 101, + 95, 100, 111, 116, 91, 52, 93, 0, 110, 111, 114, 109, 97, 108, 91, 52, 93, 0, 98, 111, 110, 101, 95, 115, 111, 108, 105, 100, 91, 52, 93, 0, + 98, 111, 110, 101, 95, 112, 111, 115, 101, 91, 52, 93, 0, 115, 116, 114, 105, 112, 91, 52, 93, 0, 115, 116, 114, 105, 112, 95, 115, 101, 108, 101, + 99, 116, 91, 52, 93, 0, 99, 102, 114, 97, 109, 101, 91, 52, 93, 0, 118, 101, 114, 116, 101, 120, 95, 115, 105, 122, 101, 0, 102, 97, 99, 101, + 100, 111, 116, 95, 115, 105, 122, 101, 0, 98, 112, 97, 100, 91, 50, 93, 0, 115, 121, 110, 116, 97, 120, 108, 91, 52, 93, 0, 115, 121, 110, 116, + 97, 120, 110, 91, 52, 93, 0, 115, 121, 110, 116, 97, 120, 98, 91, 52, 93, 0, 115, 121, 110, 116, 97, 120, 118, 91, 52, 93, 0, 115, 121, 110, + 116, 97, 120, 99, 91, 52, 93, 0, 109, 111, 118, 105, 101, 91, 52, 93, 0, 105, 109, 97, 103, 101, 91, 52, 93, 0, 115, 99, 101, 110, 101, 91, + 52, 93, 0, 97, 117, 100, 105, 111, 91, 52, 93, 0, 101, 102, 102, 101, 99, 116, 91, 52, 93, 0, 112, 108, 117, 103, 105, 110, 91, 52, 93, 0, + 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 91, 52, 93, 0, 109, 101, 116, 97, 91, 52, 93, 0, 101, 100, 105, 116, 109, 101, 115, 104, 95, 97, + 99, 116, 105, 118, 101, 91, 52, 93, 0, 104, 97, 110, 100, 108, 101, 95, 118, 101, 114, 116, 101, 120, 91, 52, 93, 0, 104, 97, 110, 100, 108, 101, + 95, 118, 101, 114, 116, 101, 120, 95, 115, 101, 108, 101, 99, 116, 91, 52, 93, 0, 104, 97, 110, 100, 108, 101, 95, 118, 101, 114, 116, 101, 120, 95, + 115, 105, 122, 101, 0, 104, 112, 97, 100, 91, 55, 93, 0, 115, 111, 108, 105, 100, 91, 52, 93, 0, 116, 117, 105, 0, 116, 98, 117, 116, 115, 0, + 116, 118, 51, 100, 0, 116, 102, 105, 108, 101, 0, 116, 105, 112, 111, 0, 116, 105, 110, 102, 111, 0, 116, 115, 110, 100, 0, 116, 97, 99, 116, 0, + 116, 110, 108, 97, 0, 116, 115, 101, 113, 0, 116, 105, 109, 97, 0, 116, 105, 109, 97, 115, 101, 108, 0, 116, 101, 120, 116, 0, 116, 111, 111, 112, + 115, 0, 116, 116, 105, 109, 101, 0, 116, 110, 111, 100, 101, 0, 116, 97, 114, 109, 91, 50, 48, 93, 0, 98, 112, 97, 100, 91, 52, 93, 0, 98, + 112, 97, 100, 49, 91, 52, 93, 0, 115, 112, 101, 99, 91, 52, 93, 0, 100, 117, 112, 102, 108, 97, 103, 0, 115, 97, 118, 101, 116, 105, 109, 101, + 0, 116, 101, 109, 112, 100, 105, 114, 91, 49, 54, 48, 93, 0, 102, 111, 110, 116, 100, 105, 114, 91, 49, 54, 48, 93, 0, 114, 101, 110, 100, 101, + 114, 100, 105, 114, 91, 49, 54, 48, 93, 0, 116, 101, 120, 116, 117, 100, 105, 114, 91, 49, 54, 48, 93, 0, 112, 108, 117, 103, 116, 101, 120, 100, + 105, 114, 91, 49, 54, 48, 93, 0, 112, 108, 117, 103, 115, 101, 113, 100, 105, 114, 91, 49, 54, 48, 93, 0, 112, 121, 116, 104, 111, 110, 100, 105, + 114, 91, 49, 54, 48, 93, 0, 115, 111, 117, 110, 100, 100, 105, 114, 91, 49, 54, 48, 93, 0, 121, 102, 101, 120, 112, 111, 114, 116, 100, 105, 114, + 91, 49, 54, 48, 93, 0, 118, 101, 114, 115, 105, 111, 110, 115, 0, 118, 114, 109, 108, 102, 108, 97, 103, 0, 103, 97, 109, 101, 102, 108, 97, 103, + 115, 0, 119, 104, 101, 101, 108, 108, 105, 110, 101, 115, 99, 114, 111, 108, 108, 0, 117, 105, 102, 108, 97, 103, 0, 108, 97, 110, 103, 117, 97, 103, + 101, 0, 117, 115, 101, 114, 112, 114, 101, 102, 0, 118, 105, 101, 119, 122, 111, 111, 109, 0, 99, 111, 110, 115, 111, 108, 101, 95, 98, 117, 102, 102, + 101, 114, 0, 99, 111, 110, 115, 111, 108, 101, 95, 111, 117, 116, 0, 109, 105, 120, 98, 117, 102, 115, 105, 122, 101, 0, 102, 111, 110, 116, 115, 105, + 122, 101, 0, 101, 110, 99, 111, 100, 105, 110, 103, 0, 116, 114, 97, 110, 115, 111, 112, 116, 115, 0, 109, 101, 110, 117, 116, 104, 114, 101, 115, 104, + 111, 108, 100, 49, 0, 109, 101, 110, 117, 116, 104, 114, 101, 115, 104, 111, 108, 100, 50, 0, 102, 111, 110, 116, 110, 97, 109, 101, 91, 50, 53, 54, + 93, 0, 116, 104, 101, 109, 101, 115, 0, 117, 110, 100, 111, 115, 116, 101, 112, 115, 0, 117, 110, 100, 111, 109, 101, 109, 111, 114, 121, 0, 103, 112, + 95, 109, 97, 110, 104, 97, 116, 116, 101, 110, 100, 105, 115, 116, 0, 103, 112, 95, 101, 117, 99, 108, 105, 100, 101, 97, 110, 100, 105, 115, 116, 0, + 103, 112, 95, 101, 114, 97, 115, 101, 114, 0, 103, 112, 95, 115, 101, 116, 116, 105, 110, 103, 115, 0, 116, 98, 95, 108, 101, 102, 116, 109, 111, 117, + 115, 101, 0, 116, 98, 95, 114, 105, 103, 104, 116, 109, 111, 117, 115, 101, 0, 108, 105, 103, 104, 116, 91, 51, 93, 0, 116, 119, 95, 104, 111, 116, + 115, 112, 111, 116, 0, 116, 119, 95, 102, 108, 97, 103, 0, 116, 119, 95, 104, 97, 110, 100, 108, 101, 115, 105, 122, 101, 0, 116, 119, 95, 115, 105, + 122, 101, 0, 116, 101, 120, 116, 105, 109, 101, 111, 117, 116, 0, 116, 101, 120, 99, 111, 108, 108, 101, 99, 116, 114, 97, 116, 101, 0, 109, 101, 109, + 99, 97, 99, 104, 101, 108, 105, 109, 105, 116, 0, 112, 114, 101, 102, 101, 116, 99, 104, 102, 114, 97, 109, 101, 115, 0, 102, 114, 97, 109, 101, 115, + 101, 114, 118, 101, 114, 112, 111, 114, 116, 0, 112, 97, 100, 95, 114, 111, 116, 95, 97, 110, 103, 108, 101, 0, 111, 98, 99, 101, 110, 116, 101, 114, + 95, 100, 105, 97, 0, 114, 118, 105, 115, 105, 122, 101, 0, 114, 118, 105, 98, 114, 105, 103, 104, 116, 0, 114, 101, 99, 101, 110, 116, 95, 102, 105, + 108, 101, 115, 0, 115, 109, 111, 111, 116, 104, 95, 118, 105, 101, 119, 116, 120, 0, 103, 108, 114, 101, 115, 108, 105, 109, 105, 116, 0, 110, 100, 111, + 102, 95, 112, 97, 110, 0, 110, 100, 111, 102, 95, 114, 111, 116, 97, 116, 101, 0, 99, 117, 114, 115, 115, 105, 122, 101, 0, 112, 97, 100, 91, 56, + 93, 0, 118, 101, 114, 115, 101, 109, 97, 115, 116, 101, 114, 91, 49, 54, 48, 93, 0, 118, 101, 114, 115, 101, 117, 115, 101, 114, 91, 49, 54, 48, + 93, 0, 103, 108, 97, 108, 112, 104, 97, 99, 108, 105, 112, 0, 97, 117, 116, 111, 107, 101, 121, 95, 102, 108, 97, 103, 0, 99, 111, 98, 97, 95, + 119, 101, 105, 103, 104, 116, 0, 118, 101, 114, 116, 98, 97, 115, 101, 0, 101, 100, 103, 101, 98, 97, 115, 101, 0, 97, 114, 101, 97, 98, 97, 115, + 101, 0, 42, 115, 99, 101, 110, 101, 0, 101, 110, 100, 120, 0, 101, 110, 100, 121, 0, 115, 105, 122, 101, 120, 0, 115, 105, 122, 101, 121, 0, 115, + 99, 101, 110, 101, 110, 114, 0, 115, 99, 114, 101, 101, 110, 110, 114, 0, 102, 117, 108, 108, 0, 109, 97, 105, 110, 119, 105, 110, 0, 119, 105, 110, + 97, 107, 116, 0, 104, 97, 110, 100, 108, 101, 114, 91, 56, 93, 0, 42, 110, 101, 119, 118, 0, 118, 101, 99, 0, 42, 118, 49, 0, 42, 118, 50, + 0, 112, 97, 110, 101, 108, 110, 97, 109, 101, 91, 54, 52, 93, 0, 116, 97, 98, 110, 97, 109, 101, 91, 54, 52, 93, 0, 100, 114, 97, 119, 110, + 97, 109, 101, 91, 54, 52, 93, 0, 111, 102, 115, 120, 0, 111, 102, 115, 121, 0, 99, 111, 110, 116, 114, 111, 108, 0, 115, 110, 97, 112, 0, 111, + 108, 100, 95, 111, 102, 115, 120, 0, 111, 108, 100, 95, 111, 102, 115, 121, 0, 115, 111, 114, 116, 99, 111, 117, 110, 116, 101, 114, 0, 42, 112, 97, + 110, 101, 108, 116, 97, 98, 0, 42, 118, 51, 0, 42, 118, 52, 0, 42, 102, 117, 108, 108, 0, 119, 105, 110, 109, 97, 116, 91, 52, 93, 91, 52, + 93, 0, 104, 101, 97, 100, 114, 99, 116, 0, 119, 105, 110, 114, 99, 116, 0, 104, 101, 97, 100, 119, 105, 110, 0, 119, 105, 110, 0, 104, 101, 97, + 100, 101, 114, 116, 121, 112, 101, 0, 98, 117, 116, 115, 112, 97, 99, 101, 116, 121, 112, 101, 0, 119, 105, 110, 120, 0, 119, 105, 110, 121, 0, 104, + 101, 97, 100, 95, 115, 119, 97, 112, 0, 104, 101, 97, 100, 95, 101, 113, 117, 97, 108, 0, 119, 105, 110, 95, 115, 119, 97, 112, 0, 119, 105, 110, + 95, 101, 113, 117, 97, 108, 0, 104, 101, 97, 100, 98, 117, 116, 108, 101, 110, 0, 104, 101, 97, 100, 98, 117, 116, 111, 102, 115, 0, 99, 117, 114, + 115, 111, 114, 0, 115, 112, 97, 99, 101, 100, 97, 116, 97, 0, 117, 105, 98, 108, 111, 99, 107, 115, 0, 112, 97, 110, 101, 108, 115, 0, 115, 117, + 98, 118, 115, 116, 114, 91, 52, 93, 0, 115, 117, 98, 118, 101, 114, 115, 105, 111, 110, 0, 112, 97, 100, 115, 0, 109, 105, 110, 118, 101, 114, 115, + 105, 111, 110, 0, 109, 105, 110, 115, 117, 98, 118, 101, 114, 115, 105, 111, 110, 0, 100, 105, 115, 112, 108, 97, 121, 109, 111, 100, 101, 0, 42, 99, + 117, 114, 115, 99, 114, 101, 101, 110, 0, 42, 99, 117, 114, 115, 99, 101, 110, 101, 0, 102, 105, 108, 101, 102, 108, 97, 103, 115, 0, 103, 108, 111, + 98, 97, 108, 102, 0, 110, 97, 109, 101, 91, 56, 48, 93, 0, 42, 105, 98, 117, 102, 0, 42, 105, 98, 117, 102, 95, 99, 111, 109, 112, 0, 42, + 115, 101, 49, 0, 42, 115, 101, 50, 0, 42, 115, 101, 51, 0, 110, 114, 0, 98, 111, 116, 116, 111, 109, 0, 114, 105, 103, 104, 116, 0, 120, 111, + 102, 115, 0, 121, 111, 102, 115, 0, 108, 105, 102, 116, 91, 51, 93, 0, 103, 97, 109, 109, 97, 91, 51, 93, 0, 103, 97, 105, 110, 91, 51, 93, + 0, 115, 97, 116, 117, 114, 97, 116, 105, 111, 110, 0, 42, 103, 117, 105, 0, 100, 105, 114, 91, 49, 54, 48, 93, 0, 100, 111, 110, 101, 0, 115, + 116, 97, 114, 116, 115, 116, 105, 108, 108, 0, 101, 110, 100, 115, 116, 105, 108, 108, 0, 42, 115, 116, 114, 105, 112, 100, 97, 116, 97, 0, 111, 114, + 120, 0, 111, 114, 121, 0, 42, 99, 114, 111, 112, 0, 42, 116, 114, 97, 110, 115, 102, 111, 114, 109, 0, 42, 99, 111, 108, 111, 114, 95, 98, 97, + 108, 97, 110, 99, 101, 0, 42, 116, 115, 116, 114, 105, 112, 100, 97, 116, 97, 0, 42, 116, 115, 116, 114, 105, 112, 100, 97, 116, 97, 95, 115, 116, + 97, 114, 116, 115, 116, 105, 108, 108, 0, 42, 116, 115, 116, 114, 105, 112, 100, 97, 116, 97, 95, 101, 110, 100, 115, 116, 105, 108, 108, 0, 42, 105, + 98, 117, 102, 95, 115, 116, 97, 114, 116, 115, 116, 105, 108, 108, 0, 42, 105, 98, 117, 102, 95, 101, 110, 100, 115, 116, 105, 108, 108, 0, 42, 105, + 110, 115, 116, 97, 110, 99, 101, 95, 112, 114, 105, 118, 97, 116, 101, 95, 100, 97, 116, 97, 0, 42, 42, 99, 117, 114, 114, 101, 110, 116, 95, 112, + 114, 105, 118, 97, 116, 101, 95, 100, 97, 116, 97, 0, 42, 116, 109, 112, 0, 115, 116, 97, 114, 116, 111, 102, 115, 0, 101, 110, 100, 111, 102, 115, + 0, 109, 97, 99, 104, 105, 110, 101, 0, 115, 116, 97, 114, 116, 100, 105, 115, 112, 0, 101, 110, 100, 100, 105, 115, 112, 0, 109, 117, 108, 0, 104, + 97, 110, 100, 115, 105, 122, 101, 0, 97, 110, 105, 109, 95, 112, 114, 101, 115, 101, 101, 107, 0, 42, 115, 116, 114, 105, 112, 0, 102, 97, 99, 102, + 48, 0, 102, 97, 99, 102, 49, 0, 42, 115, 101, 113, 49, 0, 42, 115, 101, 113, 50, 0, 42, 115, 101, 113, 51, 0, 115, 101, 113, 98, 97, 115, + 101, 0, 42, 115, 111, 117, 110, 100, 0, 42, 104, 100, 97, 117, 100, 105, 111, 0, 108, 101, 118, 101, 108, 0, 112, 97, 110, 0, 115, 116, 114, 111, + 98, 101, 0, 42, 101, 102, 102, 101, 99, 116, 100, 97, 116, 97, 0, 97, 110, 105, 109, 95, 115, 116, 97, 114, 116, 111, 102, 115, 0, 97, 110, 105, + 109, 95, 101, 110, 100, 111, 102, 115, 0, 98, 108, 101, 110, 100, 95, 109, 111, 100, 101, 0, 98, 108, 101, 110, 100, 95, 111, 112, 97, 99, 105, 116, + 121, 0, 42, 111, 108, 100, 98, 97, 115, 101, 112, 0, 42, 112, 97, 114, 115, 101, 113, 0, 42, 115, 101, 113, 98, 97, 115, 101, 112, 0, 109, 101, + 116, 97, 115, 116, 97, 99, 107, 0, 101, 100, 103, 101, 87, 105, 100, 116, 104, 0, 102, 111, 114, 119, 97, 114, 100, 0, 119, 105, 112, 101, 116, 121, + 112, 101, 0, 102, 77, 105, 110, 105, 0, 102, 67, 108, 97, 109, 112, 0, 102, 66, 111, 111, 115, 116, 0, 100, 68, 105, 115, 116, 0, 100, 81, 117, + 97, 108, 105, 116, 121, 0, 98, 78, 111, 67, 111, 109, 112, 0, 83, 99, 97, 108, 101, 120, 73, 110, 105, 0, 83, 99, 97, 108, 101, 121, 73, 110, + 105, 0, 83, 99, 97, 108, 101, 120, 70, 105, 110, 0, 83, 99, 97, 108, 101, 121, 70, 105, 110, 0, 120, 73, 110, 105, 0, 120, 70, 105, 110, 0, + 121, 73, 110, 105, 0, 121, 70, 105, 110, 0, 114, 111, 116, 73, 110, 105, 0, 114, 111, 116, 70, 105, 110, 0, 105, 110, 116, 101, 114, 112, 111, 108, + 97, 116, 105, 111, 110, 0, 42, 102, 114, 97, 109, 101, 77, 97, 112, 0, 103, 108, 111, 98, 97, 108, 83, 112, 101, 101, 100, 0, 108, 97, 115, 116, + 86, 97, 108, 105, 100, 70, 114, 97, 109, 101, 0, 98, 108, 101, 110, 100, 70, 114, 97, 109, 101, 115, 0, 98, 117, 116, 116, 121, 112, 101, 0, 117, + 115, 101, 114, 106, 105, 116, 0, 115, 116, 97, 0, 116, 111, 116, 112, 97, 114, 116, 0, 110, 111, 114, 109, 102, 97, 99, 0, 111, 98, 102, 97, 99, + 0, 114, 97, 110, 100, 102, 97, 99, 0, 116, 101, 120, 102, 97, 99, 0, 114, 97, 110, 100, 108, 105, 102, 101, 0, 102, 111, 114, 99, 101, 91, 51, + 93, 0, 118, 101, 99, 116, 115, 105, 122, 101, 0, 109, 97, 120, 108, 101, 110, 0, 100, 101, 102, 118, 101, 99, 91, 51, 93, 0, 109, 117, 108, 116, + 91, 52, 93, 0, 108, 105, 102, 101, 91, 52, 93, 0, 99, 104, 105, 108, 100, 91, 52, 93, 0, 109, 97, 116, 91, 52, 93, 0, 116, 101, 120, 109, + 97, 112, 0, 99, 117, 114, 109, 117, 108, 116, 0, 115, 116, 97, 116, 105, 99, 115, 116, 101, 112, 0, 111, 109, 97, 116, 0, 116, 105, 109, 101, 116, + 101, 120, 0, 115, 112, 101, 101, 100, 116, 101, 120, 0, 102, 108, 97, 103, 50, 110, 101, 103, 0, 118, 101, 114, 116, 103, 114, 111, 117, 112, 95, 118, + 0, 118, 103, 114, 111, 117, 112, 110, 97, 109, 101, 91, 51, 50, 93, 0, 118, 103, 114, 111, 117, 112, 110, 97, 109, 101, 95, 118, 91, 51, 50, 93, + 0, 42, 107, 101, 121, 115, 0, 109, 105, 110, 102, 97, 99, 0, 117, 115, 101, 100, 0, 117, 115, 101, 100, 101, 108, 101, 109, 0, 100, 120, 0, 100, + 121, 0, 108, 105, 110, 107, 0, 111, 116, 121, 112, 101, 0, 111, 108, 100, 0, 42, 112, 111, 105, 110, 0, 42, 111, 108, 100, 112, 111, 105, 110, 0, + 114, 101, 115, 101, 116, 100, 105, 115, 116, 0, 108, 97, 115, 116, 118, 97, 108, 0, 42, 109, 97, 0, 107, 101, 121, 0, 113, 117, 97, 108, 0, 113, + 117, 97, 108, 50, 0, 116, 97, 114, 103, 101, 116, 78, 97, 109, 101, 91, 51, 50, 93, 0, 116, 111, 103, 103, 108, 101, 78, 97, 109, 101, 91, 51, + 50, 93, 0, 118, 97, 108, 117, 101, 91, 51, 50, 93, 0, 109, 97, 120, 118, 97, 108, 117, 101, 91, 51, 50, 93, 0, 100, 101, 108, 97, 121, 0, + 100, 117, 114, 97, 116, 105, 111, 110, 0, 109, 97, 116, 101, 114, 105, 97, 108, 78, 97, 109, 101, 91, 51, 50, 93, 0, 100, 97, 109, 112, 116, 105, + 109, 101, 114, 0, 112, 114, 111, 112, 110, 97, 109, 101, 91, 51, 50, 93, 0, 109, 97, 116, 110, 97, 109, 101, 91, 51, 50, 93, 0, 97, 120, 105, + 115, 102, 108, 97, 103, 0, 42, 102, 114, 111, 109, 79, 98, 106, 101, 99, 116, 0, 115, 117, 98, 106, 101, 99, 116, 91, 51, 50, 93, 0, 98, 111, + 100, 121, 91, 51, 50, 93, 0, 112, 117, 108, 115, 101, 0, 102, 114, 101, 113, 0, 116, 111, 116, 108, 105, 110, 107, 115, 0, 42, 42, 108, 105, 110, + 107, 115, 0, 116, 97, 112, 0, 106, 111, 121, 105, 110, 100, 101, 120, 0, 97, 120, 105, 115, 95, 115, 105, 110, 103, 108, 101, 0, 97, 120, 105, 115, + 102, 0, 98, 117, 116, 116, 111, 110, 0, 104, 97, 116, 0, 104, 97, 116, 102, 0, 112, 114, 101, 99, 105, 115, 105, 111, 110, 0, 115, 116, 114, 91, + 49, 50, 56, 93, 0, 109, 111, 100, 117, 108, 101, 91, 54, 52, 93, 0, 42, 109, 121, 110, 101, 119, 0, 105, 110, 112, 117, 116, 115, 0, 116, 111, + 116, 115, 108, 105, 110, 107, 115, 0, 42, 42, 115, 108, 105, 110, 107, 115, 0, 118, 97, 108, 111, 0, 115, 116, 97, 116, 101, 95, 109, 97, 115, 107, + 0, 42, 97, 99, 116, 0, 102, 114, 97, 109, 101, 80, 114, 111, 112, 91, 51, 50, 93, 0, 98, 108, 101, 110, 100, 105, 110, 0, 112, 114, 105, 111, + 114, 105, 116, 121, 0, 101, 110, 100, 95, 114, 101, 115, 101, 116, 0, 115, 116, 114, 105, 100, 101, 97, 120, 105, 115, 0, 115, 116, 114, 105, 100, 101, + 108, 101, 110, 103, 116, 104, 0, 115, 110, 100, 110, 114, 0, 112, 97, 100, 49, 91, 50, 93, 0, 109, 97, 107, 101, 99, 111, 112, 121, 0, 99, 111, + 112, 121, 109, 97, 100, 101, 0, 112, 97, 100, 50, 91, 49, 93, 0, 116, 114, 97, 99, 107, 0, 42, 109, 101, 0, 108, 105, 110, 86, 101, 108, 111, + 99, 105, 116, 121, 91, 51, 93, 0, 97, 110, 103, 86, 101, 108, 111, 99, 105, 116, 121, 91, 51, 93, 0, 108, 111, 99, 97, 108, 102, 108, 97, 103, + 0, 100, 121, 110, 95, 111, 112, 101, 114, 97, 116, 105, 111, 110, 0, 102, 111, 114, 99, 101, 108, 111, 99, 91, 51, 93, 0, 102, 111, 114, 99, 101, + 114, 111, 116, 91, 51, 93, 0, 108, 105, 110, 101, 97, 114, 118, 101, 108, 111, 99, 105, 116, 121, 91, 51, 93, 0, 97, 110, 103, 117, 108, 97, 114, + 118, 101, 108, 111, 99, 105, 116, 121, 91, 51, 93, 0, 42, 114, 101, 102, 101, 114, 101, 110, 99, 101, 0, 98, 117, 116, 115, 116, 97, 0, 98, 117, + 116, 101, 110, 100, 0, 109, 105, 110, 0, 109, 97, 120, 0, 118, 105, 115, 105, 102, 97, 99, 0, 114, 111, 116, 100, 97, 109, 112, 0, 109, 105, 110, + 108, 111, 99, 91, 51, 93, 0, 109, 97, 120, 108, 111, 99, 91, 51, 93, 0, 109, 105, 110, 114, 111, 116, 91, 51, 93, 0, 109, 97, 120, 114, 111, + 116, 91, 51, 93, 0, 109, 97, 116, 112, 114, 111, 112, 91, 51, 50, 93, 0, 100, 105, 115, 116, 114, 105, 98, 117, 116, 105, 111, 110, 0, 105, 110, + 116, 95, 97, 114, 103, 95, 49, 0, 105, 110, 116, 95, 97, 114, 103, 95, 50, 0, 102, 108, 111, 97, 116, 95, 97, 114, 103, 95, 49, 0, 102, 108, + 111, 97, 116, 95, 97, 114, 103, 95, 50, 0, 116, 111, 80, 114, 111, 112, 78, 97, 109, 101, 91, 51, 50, 93, 0, 42, 116, 111, 79, 98, 106, 101, + 99, 116, 0, 98, 111, 100, 121, 84, 121, 112, 101, 0, 102, 105, 108, 101, 110, 97, 109, 101, 91, 54, 52, 93, 0, 108, 111, 97, 100, 97, 110, 105, + 110, 97, 109, 101, 91, 54, 52, 93, 0, 105, 110, 116, 95, 97, 114, 103, 0, 102, 108, 111, 97, 116, 95, 97, 114, 103, 0, 103, 111, 0, 97, 99, + 99, 101, 108, 108, 101, 114, 97, 116, 105, 111, 110, 0, 109, 97, 120, 115, 112, 101, 101, 100, 0, 109, 97, 120, 114, 111, 116, 115, 112, 101, 101, 100, + 0, 109, 97, 120, 116, 105, 108, 116, 115, 112, 101, 101, 100, 0, 116, 105, 108, 116, 100, 97, 109, 112, 0, 115, 112, 101, 101, 100, 100, 97, 109, 112, + 0, 42, 115, 97, 109, 112, 108, 101, 0, 42, 115, 116, 114, 101, 97, 109, 0, 42, 110, 101, 119, 112, 97, 99, 107, 101, 100, 102, 105, 108, 101, 0, + 42, 115, 110, 100, 95, 115, 111, 117, 110, 100, 0, 112, 97, 110, 110, 105, 110, 103, 0, 97, 116, 116, 101, 110, 117, 97, 116, 105, 111, 110, 0, 112, + 105, 116, 99, 104, 0, 109, 105, 110, 95, 103, 97, 105, 110, 0, 109, 97, 120, 95, 103, 97, 105, 110, 0, 100, 105, 115, 116, 97, 110, 99, 101, 0, + 115, 116, 114, 101, 97, 109, 108, 101, 110, 0, 99, 104, 97, 110, 110, 101, 108, 115, 0, 104, 105, 103, 104, 112, 114, 105, 111, 0, 112, 97, 100, 91, + 49, 48, 93, 0, 103, 97, 105, 110, 0, 100, 111, 112, 112, 108, 101, 114, 102, 97, 99, 116, 111, 114, 0, 100, 111, 112, 112, 108, 101, 114, 118, 101, + 108, 111, 99, 105, 116, 121, 0, 110, 117, 109, 115, 111, 117, 110, 100, 115, 98, 108, 101, 110, 100, 101, 114, 0, 110, 117, 109, 115, 111, 117, 110, 100, + 115, 103, 97, 109, 101, 101, 110, 103, 105, 110, 101, 0, 42, 108, 97, 109, 112, 114, 101, 110, 0, 103, 111, 98, 106, 101, 99, 116, 0, 100, 117, 112, + 108, 105, 95, 111, 102, 115, 91, 51, 93, 0, 99, 104, 105, 108, 100, 98, 97, 115, 101, 0, 114, 111, 108, 108, 0, 104, 101, 97, 100, 91, 51, 93, + 0, 116, 97, 105, 108, 91, 51, 93, 0, 98, 111, 110, 101, 95, 109, 97, 116, 91, 51, 93, 91, 51, 93, 0, 97, 114, 109, 95, 104, 101, 97, 100, + 91, 51, 93, 0, 97, 114, 109, 95, 116, 97, 105, 108, 91, 51, 93, 0, 97, 114, 109, 95, 109, 97, 116, 91, 52, 93, 91, 52, 93, 0, 120, 119, + 105, 100, 116, 104, 0, 122, 119, 105, 100, 116, 104, 0, 101, 97, 115, 101, 49, 0, 101, 97, 115, 101, 50, 0, 114, 97, 100, 95, 104, 101, 97, 100, + 0, 114, 97, 100, 95, 116, 97, 105, 108, 0, 98, 111, 110, 101, 98, 97, 115, 101, 0, 99, 104, 97, 105, 110, 98, 97, 115, 101, 0, 112, 97, 116, + 104, 102, 108, 97, 103, 0, 108, 97, 121, 101, 114, 95, 112, 114, 111, 116, 101, 99, 116, 101, 100, 0, 103, 104, 111, 115, 116, 101, 112, 0, 103, 104, + 111, 115, 116, 115, 105, 122, 101, 0, 103, 104, 111, 115, 116, 116, 121, 112, 101, 0, 112, 97, 116, 104, 115, 105, 122, 101, 0, 103, 104, 111, 115, 116, + 115, 102, 0, 103, 104, 111, 115, 116, 101, 102, 0, 112, 97, 116, 104, 115, 102, 0, 112, 97, 116, 104, 101, 102, 0, 112, 97, 116, 104, 98, 99, 0, + 112, 97, 116, 104, 97, 99, 0, 99, 111, 110, 115, 116, 102, 108, 97, 103, 0, 105, 107, 102, 108, 97, 103, 0, 115, 101, 108, 101, 99, 116, 102, 108, + 97, 103, 0, 97, 103, 114, 112, 95, 105, 110, 100, 101, 120, 0, 42, 98, 111, 110, 101, 0, 42, 99, 104, 105, 108, 100, 0, 105, 107, 116, 114, 101, + 101, 0, 42, 98, 95, 98, 111, 110, 101, 95, 109, 97, 116, 115, 0, 42, 100, 117, 97, 108, 95, 113, 117, 97, 116, 0, 42, 98, 95, 98, 111, 110, + 101, 95, 100, 117, 97, 108, 95, 113, 117, 97, 116, 115, 0, 99, 104, 97, 110, 95, 109, 97, 116, 91, 52, 93, 91, 52, 93, 0, 112, 111, 115, 101, + 95, 109, 97, 116, 91, 52, 93, 91, 52, 93, 0, 112, 111, 115, 101, 95, 104, 101, 97, 100, 91, 51, 93, 0, 112, 111, 115, 101, 95, 116, 97, 105, + 108, 91, 51, 93, 0, 108, 105, 109, 105, 116, 109, 105, 110, 91, 51, 93, 0, 108, 105, 109, 105, 116, 109, 97, 120, 91, 51, 93, 0, 115, 116, 105, + 102, 102, 110, 101, 115, 115, 91, 51, 93, 0, 105, 107, 115, 116, 114, 101, 116, 99, 104, 0, 42, 99, 117, 115, 116, 111, 109, 0, 99, 104, 97, 110, + 98, 97, 115, 101, 0, 112, 114, 111, 120, 121, 95, 108, 97, 121, 101, 114, 0, 115, 116, 114, 105, 100, 101, 95, 111, 102, 102, 115, 101, 116, 91, 51, + 93, 0, 99, 121, 99, 108, 105, 99, 95, 111, 102, 102, 115, 101, 116, 91, 51, 93, 0, 97, 103, 114, 111, 117, 112, 115, 0, 97, 99, 116, 105, 118, + 101, 95, 103, 114, 111, 117, 112, 0, 99, 117, 115, 116, 111, 109, 67, 111, 108, 0, 99, 115, 0, 42, 103, 114, 112, 0, 114, 101, 115, 101, 114, 118, + 101, 100, 49, 0, 103, 114, 111, 117, 112, 115, 0, 97, 99, 116, 105, 118, 101, 95, 109, 97, 114, 107, 101, 114, 0, 97, 99, 116, 110, 114, 0, 97, + 99, 116, 119, 105, 100, 116, 104, 0, 116, 105, 109, 101, 115, 108, 105, 100, 101, 0, 110, 97, 109, 101, 91, 51, 48, 93, 0, 111, 119, 110, 115, 112, + 97, 99, 101, 0, 116, 97, 114, 115, 112, 97, 99, 101, 0, 101, 110, 102, 111, 114, 99, 101, 0, 104, 101, 97, 100, 116, 97, 105, 108, 0, 42, 116, + 97, 114, 0, 115, 117, 98, 116, 97, 114, 103, 101, 116, 91, 51, 50, 93, 0, 109, 97, 116, 114, 105, 120, 91, 52, 93, 91, 52, 93, 0, 115, 112, + 97, 99, 101, 0, 42, 112, 114, 111, 112, 0, 116, 97, 114, 110, 117, 109, 0, 116, 97, 114, 103, 101, 116, 115, 0, 105, 116, 101, 114, 97, 116, 105, + 111, 110, 115, 0, 114, 111, 111, 116, 98, 111, 110, 101, 0, 109, 97, 120, 95, 114, 111, 111, 116, 98, 111, 110, 101, 0, 42, 112, 111, 108, 101, 116, + 97, 114, 0, 112, 111, 108, 101, 115, 117, 98, 116, 97, 114, 103, 101, 116, 91, 51, 50, 93, 0, 112, 111, 108, 101, 97, 110, 103, 108, 101, 0, 111, + 114, 105, 101, 110, 116, 119, 101, 105, 103, 104, 116, 0, 103, 114, 97, 98, 116, 97, 114, 103, 101, 116, 91, 51, 93, 0, 114, 101, 115, 101, 114, 118, + 101, 100, 50, 0, 109, 105, 110, 109, 97, 120, 102, 108, 97, 103, 0, 115, 116, 117, 99, 107, 0, 99, 97, 99, 104, 101, 91, 51, 93, 0, 108, 111, + 99, 107, 102, 108, 97, 103, 0, 102, 111, 108, 108, 111, 119, 102, 108, 97, 103, 0, 118, 111, 108, 109, 111, 100, 101, 0, 112, 108, 97, 110, 101, 0, + 111, 114, 103, 108, 101, 110, 103, 116, 104, 0, 98, 117, 108, 103, 101, 0, 112, 105, 118, 88, 0, 112, 105, 118, 89, 0, 112, 105, 118, 90, 0, 97, + 120, 88, 0, 97, 120, 89, 0, 97, 120, 90, 0, 109, 105, 110, 76, 105, 109, 105, 116, 91, 54, 93, 0, 109, 97, 120, 76, 105, 109, 105, 116, 91, + 54, 93, 0, 101, 120, 116, 114, 97, 70, 122, 0, 105, 110, 118, 109, 97, 116, 91, 52, 93, 91, 52, 93, 0, 102, 114, 111, 109, 0, 116, 111, 0, + 109, 97, 112, 91, 51, 93, 0, 101, 120, 112, 111, 0, 102, 114, 111, 109, 95, 109, 105, 110, 91, 51, 93, 0, 102, 114, 111, 109, 95, 109, 97, 120, + 91, 51, 93, 0, 116, 111, 95, 109, 105, 110, 91, 51, 93, 0, 116, 111, 95, 109, 97, 120, 91, 51, 93, 0, 122, 109, 105, 110, 0, 122, 109, 97, + 120, 0, 112, 97, 100, 91, 57, 93, 0, 99, 104, 97, 110, 110, 101, 108, 91, 51, 50, 93, 0, 110, 111, 95, 114, 111, 116, 95, 97, 120, 105, 115, + 0, 115, 116, 114, 105, 100, 101, 95, 97, 120, 105, 115, 0, 99, 117, 114, 109, 111, 100, 0, 97, 99, 116, 115, 116, 97, 114, 116, 0, 97, 99, 116, + 101, 110, 100, 0, 97, 99, 116, 111, 102, 102, 115, 0, 115, 116, 114, 105, 100, 101, 108, 101, 110, 0, 98, 108, 101, 110, 100, 111, 117, 116, 0, 115, + 116, 114, 105, 100, 101, 99, 104, 97, 110, 110, 101, 108, 91, 51, 50, 93, 0, 111, 102, 102, 115, 95, 98, 111, 110, 101, 91, 51, 50, 93, 0, 104, + 97, 115, 105, 110, 112, 117, 116, 0, 104, 97, 115, 111, 117, 116, 112, 117, 116, 0, 100, 97, 116, 97, 116, 121, 112, 101, 0, 115, 111, 99, 107, 101, + 116, 116, 121, 112, 101, 0, 42, 110, 101, 119, 95, 115, 111, 99, 107, 0, 110, 115, 0, 108, 105, 109, 105, 116, 0, 115, 116, 97, 99, 107, 95, 105, + 110, 100, 101, 120, 0, 105, 110, 116, 101, 114, 110, 0, 115, 116, 97, 99, 107, 95, 105, 110, 100, 101, 120, 95, 101, 120, 116, 0, 108, 111, 99, 120, + 0, 108, 111, 99, 121, 0, 111, 119, 110, 95, 105, 110, 100, 101, 120, 0, 116, 111, 95, 105, 110, 100, 101, 120, 0, 42, 116, 111, 115, 111, 99, 107, + 0, 42, 108, 105, 110, 107, 0, 42, 110, 101, 119, 95, 110, 111, 100, 101, 0, 117, 115, 101, 114, 110, 97, 109, 101, 91, 51, 50, 93, 0, 108, 97, + 115, 116, 121, 0, 111, 117, 116, 112, 117, 116, 115, 0, 42, 115, 116, 111, 114, 97, 103, 101, 0, 109, 105, 110, 105, 119, 105, 100, 116, 104, 0, 99, + 117, 115, 116, 111, 109, 49, 0, 99, 117, 115, 116, 111, 109, 50, 0, 99, 117, 115, 116, 111, 109, 51, 0, 99, 117, 115, 116, 111, 109, 52, 0, 110, + 101, 101, 100, 95, 101, 120, 101, 99, 0, 101, 120, 101, 99, 0, 116, 111, 116, 114, 0, 98, 117, 116, 114, 0, 112, 114, 118, 114, 0, 42, 116, 121, + 112, 101, 105, 110, 102, 111, 0, 42, 102, 114, 111, 109, 110, 111, 100, 101, 0, 42, 116, 111, 110, 111, 100, 101, 0, 42, 102, 114, 111, 109, 115, 111, + 99, 107, 0, 110, 111, 100, 101, 115, 0, 108, 105, 110, 107, 115, 0, 42, 115, 116, 97, 99, 107, 0, 42, 116, 104, 114, 101, 97, 100, 115, 116, 97, + 99, 107, 0, 105, 110, 105, 116, 0, 115, 116, 97, 99, 107, 115, 105, 122, 101, 0, 99, 117, 114, 95, 105, 110, 100, 101, 120, 0, 97, 108, 108, 116, + 121, 112, 101, 115, 0, 42, 111, 119, 110, 116, 121, 112, 101, 0, 42, 115, 101, 108, 105, 110, 0, 42, 115, 101, 108, 111, 117, 116, 0, 40, 42, 116, + 105, 109, 101, 99, 117, 114, 115, 111, 114, 41, 40, 41, 0, 40, 42, 115, 116, 97, 116, 115, 95, 100, 114, 97, 119, 41, 40, 41, 0, 40, 42, 116, + 101, 115, 116, 95, 98, 114, 101, 97, 107, 41, 40, 41, 0, 99, 121, 99, 108, 105, 99, 0, 109, 111, 118, 105, 101, 0, 115, 97, 109, 112, 108, 101, + 115, 0, 109, 105, 110, 115, 112, 101, 101, 100, 0, 112, 101, 114, 99, 101, 110, 116, 120, 0, 112, 101, 114, 99, 101, 110, 116, 121, 0, 98, 111, 107, + 101, 104, 0, 99, 117, 114, 118, 101, 100, 0, 105, 109, 97, 103, 101, 95, 105, 110, 95, 119, 105, 100, 116, 104, 0, 105, 109, 97, 103, 101, 95, 105, + 110, 95, 104, 101, 105, 103, 104, 116, 0, 99, 101, 110, 116, 101, 114, 95, 120, 0, 99, 101, 110, 116, 101, 114, 95, 121, 0, 115, 112, 105, 110, 0, + 105, 116, 101, 114, 0, 119, 114, 97, 112, 0, 115, 105, 103, 109, 97, 95, 99, 111, 108, 111, 114, 0, 115, 105, 103, 109, 97, 95, 115, 112, 97, 99, + 101, 0, 104, 117, 101, 0, 115, 97, 116, 0, 116, 49, 0, 116, 50, 0, 116, 51, 0, 102, 115, 116, 114, 101, 110, 103, 116, 104, 0, 102, 97, 108, + 112, 104, 97, 0, 107, 101, 121, 91, 52, 93, 0, 120, 49, 0, 120, 50, 0, 121, 49, 0, 121, 50, 0, 99, 111, 108, 110, 97, 109, 101, 91, 51, + 50, 93, 0, 98, 107, 116, 121, 112, 101, 0, 114, 111, 116, 97, 116, 105, 111, 110, 0, 112, 114, 101, 118, 105, 101, 119, 0, 103, 97, 109, 99, 111, + 0, 110, 111, 95, 122, 98, 117, 102, 0, 102, 115, 116, 111, 112, 0, 109, 97, 120, 98, 108, 117, 114, 0, 98, 116, 104, 114, 101, 115, 104, 0, 42, + 100, 105, 99, 116, 0, 42, 110, 111, 100, 101, 0, 97, 110, 103, 108, 101, 95, 111, 102, 115, 0, 99, 111, 108, 109, 111, 100, 0, 109, 105, 120, 0, + 116, 104, 114, 101, 115, 104, 111, 108, 100, 0, 102, 97, 100, 101, 0, 109, 0, 99, 0, 106, 105, 116, 0, 112, 114, 111, 106, 0, 102, 105, 116, 0, + 115, 104, 111, 114, 116, 121, 0, 109, 105, 110, 116, 97, 98, 108, 101, 0, 109, 97, 120, 116, 97, 98, 108, 101, 0, 101, 120, 116, 95, 105, 110, 91, + 50, 93, 0, 101, 120, 116, 95, 111, 117, 116, 91, 50, 93, 0, 42, 99, 117, 114, 118, 101, 0, 42, 116, 97, 98, 108, 101, 0, 42, 112, 114, 101, + 109, 117, 108, 116, 97, 98, 108, 101, 0, 99, 117, 114, 114, 0, 99, 108, 105, 112, 114, 0, 99, 109, 91, 52, 93, 0, 98, 108, 97, 99, 107, 91, + 51, 93, 0, 119, 104, 105, 116, 101, 91, 51, 93, 0, 98, 119, 109, 117, 108, 91, 51, 93, 0, 115, 97, 109, 112, 108, 101, 91, 51, 93, 0, 111, + 102, 102, 115, 101, 116, 91, 50, 93, 0, 105, 110, 110, 101, 114, 114, 97, 100, 105, 117, 115, 0, 114, 97, 116, 101, 0, 114, 103, 98, 91, 51, 93, + 0, 99, 108, 111, 110, 101, 0, 97, 99, 116, 105, 118, 101, 95, 114, 110, 100, 0, 97, 99, 116, 105, 118, 101, 95, 99, 108, 111, 110, 101, 0, 97, + 99, 116, 105, 118, 101, 95, 109, 97, 115, 107, 0, 42, 108, 97, 121, 101, 114, 115, 0, 116, 111, 116, 108, 97, 121, 101, 114, 0, 109, 97, 120, 108, + 97, 121, 101, 114, 0, 116, 111, 116, 115, 105, 122, 101, 0, 42, 112, 111, 111, 108, 0, 101, 100, 105, 116, 102, 108, 97, 103, 0, 118, 101, 108, 91, + 51, 93, 0, 114, 111, 116, 91, 52, 93, 0, 97, 118, 101, 91, 51, 93, 0, 110, 117, 109, 0, 112, 97, 114, 101, 110, 116, 0, 112, 97, 91, 52, + 93, 0, 119, 91, 52, 93, 0, 102, 117, 118, 91, 52, 93, 0, 102, 111, 102, 102, 115, 101, 116, 0, 114, 97, 110, 100, 91, 51, 93, 0, 42, 115, + 116, 105, 99, 107, 95, 111, 98, 0, 112, 114, 101, 118, 95, 115, 116, 97, 116, 101, 0, 42, 104, 97, 105, 114, 0, 105, 95, 114, 111, 116, 91, 52, + 93, 0, 114, 95, 114, 111, 116, 91, 52, 93, 0, 114, 95, 97, 118, 101, 91, 51, 93, 0, 114, 95, 118, 101, 91, 51, 93, 0, 100, 105, 101, 116, + 105, 109, 101, 0, 98, 97, 110, 107, 0, 115, 105, 122, 101, 109, 117, 108, 0, 110, 117, 109, 95, 100, 109, 99, 97, 99, 104, 101, 0, 98, 112, 105, + 0, 97, 108, 105, 118, 101, 0, 108, 111, 111, 112, 0, 100, 105, 115, 116, 114, 0, 112, 104, 121, 115, 116, 121, 112, 101, 0, 114, 111, 116, 109, 111, + 100, 101, 0, 97, 118, 101, 109, 111, 100, 101, 0, 114, 101, 97, 99, 116, 101, 118, 101, 110, 116, 0, 100, 114, 97, 119, 0, 100, 114, 97, 119, 95, + 97, 115, 0, 100, 114, 97, 119, 95, 115, 105, 122, 101, 0, 99, 104, 105, 108, 100, 116, 121, 112, 101, 0, 100, 114, 97, 119, 95, 115, 116, 101, 112, + 0, 114, 101, 110, 95, 115, 116, 101, 112, 0, 104, 97, 105, 114, 95, 115, 116, 101, 112, 0, 107, 101, 121, 115, 95, 115, 116, 101, 112, 0, 97, 100, + 97, 112, 116, 95, 97, 110, 103, 108, 101, 0, 97, 100, 97, 112, 116, 95, 112, 105, 120, 0, 114, 111, 116, 102, 114, 111, 109, 0, 105, 110, 116, 101, + 103, 114, 97, 116, 111, 114, 0, 110, 98, 101, 116, 119, 101, 101, 110, 0, 98, 111, 105, 100, 110, 101, 105, 103, 104, 98, 111, 117, 114, 115, 0, 98, + 98, 95, 97, 108, 105, 103, 110, 0, 98, 98, 95, 117, 118, 95, 115, 112, 108, 105, 116, 0, 98, 98, 95, 97, 110, 105, 109, 0, 98, 98, 95, 115, + 112, 108, 105, 116, 95, 111, 102, 102, 115, 101, 116, 0, 98, 98, 95, 116, 105, 108, 116, 0, 98, 98, 95, 114, 97, 110, 100, 95, 116, 105, 108, 116, + 0, 98, 98, 95, 111, 102, 102, 115, 101, 116, 91, 50, 93, 0, 115, 105, 109, 112, 108, 105, 102, 121, 95, 102, 108, 97, 103, 0, 115, 105, 109, 112, + 108, 105, 102, 121, 95, 114, 101, 102, 115, 105, 122, 101, 0, 115, 105, 109, 112, 108, 105, 102, 121, 95, 114, 97, 116, 101, 0, 115, 105, 109, 112, 108, + 105, 102, 121, 95, 116, 114, 97, 110, 115, 105, 116, 105, 111, 110, 0, 115, 105, 109, 112, 108, 105, 102, 121, 95, 118, 105, 101, 119, 112, 111, 114, 116, + 0, 116, 105, 109, 101, 116, 119, 101, 97, 107, 0, 106, 105, 116, 102, 97, 99, 0, 107, 101, 121, 101, 100, 95, 116, 105, 109, 101, 0, 101, 102, 102, + 95, 104, 97, 105, 114, 0, 103, 114, 105, 100, 95, 114, 101, 115, 0, 112, 97, 114, 116, 102, 97, 99, 0, 116, 97, 110, 102, 97, 99, 0, 116, 97, + 110, 112, 104, 97, 115, 101, 0, 114, 101, 97, 99, 116, 102, 97, 99, 0, 97, 118, 101, 102, 97, 99, 0, 112, 104, 97, 115, 101, 102, 97, 99, 0, + 114, 97, 110, 100, 114, 111, 116, 102, 97, 99, 0, 114, 97, 110, 100, 112, 104, 97, 115, 101, 102, 97, 99, 0, 114, 97, 110, 100, 115, 105, 122, 101, + 0, 114, 101, 97, 99, 116, 115, 104, 97, 112, 101, 0, 97, 99, 99, 91, 51, 93, 0, 100, 114, 97, 103, 102, 97, 99, 0, 98, 114, 111, 119, 110, + 102, 97, 99, 0, 100, 97, 109, 112, 102, 97, 99, 0, 97, 98, 115, 108, 101, 110, 103, 116, 104, 0, 114, 97, 110, 100, 108, 101, 110, 103, 116, 104, + 0, 99, 104, 105, 108, 100, 95, 110, 98, 114, 0, 114, 101, 110, 95, 99, 104, 105, 108, 100, 95, 110, 98, 114, 0, 112, 97, 114, 101, 110, 116, 115, + 0, 99, 104, 105, 108, 100, 115, 105, 122, 101, 0, 99, 104, 105, 108, 100, 114, 97, 110, 100, 115, 105, 122, 101, 0, 99, 104, 105, 108, 100, 114, 97, + 100, 0, 99, 104, 105, 108, 100, 102, 108, 97, 116, 0, 99, 104, 105, 108, 100, 115, 112, 114, 101, 97, 100, 0, 99, 108, 117, 109, 112, 102, 97, 99, + 0, 99, 108, 117, 109, 112, 112, 111, 119, 0, 114, 111, 117, 103, 104, 49, 0, 114, 111, 117, 103, 104, 49, 95, 115, 105, 122, 101, 0, 114, 111, 117, + 103, 104, 50, 0, 114, 111, 117, 103, 104, 50, 95, 115, 105, 122, 101, 0, 114, 111, 117, 103, 104, 50, 95, 116, 104, 114, 101, 115, 0, 114, 111, 117, + 103, 104, 95, 101, 110, 100, 0, 114, 111, 117, 103, 104, 95, 101, 110, 100, 95, 115, 104, 97, 112, 101, 0, 98, 114, 97, 110, 99, 104, 95, 116, 104, + 114, 101, 115, 0, 100, 114, 97, 119, 95, 108, 105, 110, 101, 91, 50, 93, 0, 109, 97, 120, 95, 108, 97, 116, 95, 97, 99, 99, 0, 109, 97, 120, + 95, 116, 97, 110, 95, 97, 99, 99, 0, 97, 118, 101, 114, 97, 103, 101, 95, 118, 101, 108, 0, 98, 97, 110, 107, 105, 110, 103, 0, 109, 97, 120, + 95, 98, 97, 110, 107, 0, 103, 114, 111, 117, 110, 100, 122, 0, 98, 111, 105, 100, 102, 97, 99, 91, 56, 93, 0, 98, 111, 105, 100, 114, 117, 108, + 101, 91, 56, 93, 0, 42, 101, 102, 102, 95, 103, 114, 111, 117, 112, 0, 42, 100, 117, 112, 95, 111, 98, 0, 42, 98, 98, 95, 111, 98, 0, 42, + 112, 100, 50, 0, 42, 112, 97, 114, 116, 0, 42, 101, 100, 105, 116, 0, 42, 42, 112, 97, 116, 104, 99, 97, 99, 104, 101, 0, 42, 42, 99, 104, + 105, 108, 100, 99, 97, 99, 104, 101, 0, 112, 97, 116, 104, 99, 97, 99, 104, 101, 98, 117, 102, 115, 0, 99, 104, 105, 108, 100, 99, 97, 99, 104, + 101, 98, 117, 102, 115, 0, 42, 116, 97, 114, 103, 101, 116, 95, 111, 98, 0, 42, 107, 101, 121, 101, 100, 95, 111, 98, 0, 42, 108, 97, 116, 116, + 105, 99, 101, 0, 101, 102, 102, 101, 99, 116, 111, 114, 115, 0, 114, 101, 97, 99, 116, 101, 118, 101, 110, 116, 115, 0, 116, 111, 116, 99, 104, 105, + 108, 100, 0, 116, 111, 116, 99, 97, 99, 104, 101, 100, 0, 116, 111, 116, 99, 104, 105, 108, 100, 99, 97, 99, 104, 101, 0, 116, 97, 114, 103, 101, + 116, 95, 112, 115, 121, 115, 0, 107, 101, 121, 101, 100, 95, 112, 115, 121, 115, 0, 116, 111, 116, 107, 101, 121, 101, 100, 0, 98, 97, 107, 101, 115, + 112, 97, 99, 101, 0, 98, 98, 95, 117, 118, 110, 97, 109, 101, 91, 51, 93, 91, 51, 50, 93, 0, 118, 103, 114, 111, 117, 112, 91, 49, 50, 93, + 0, 118, 103, 95, 110, 101, 103, 0, 114, 116, 51, 0, 42, 114, 101, 110, 100, 101, 114, 100, 97, 116, 97, 0, 42, 99, 97, 99, 104, 101, 0, 67, + 100, 105, 115, 0, 67, 118, 105, 0, 91, 51, 93, 0, 115, 116, 114, 117, 99, 116, 117, 114, 97, 108, 0, 98, 101, 110, 100, 105, 110, 103, 0, 109, + 97, 120, 95, 98, 101, 110, 100, 0, 109, 97, 120, 95, 115, 116, 114, 117, 99, 116, 0, 109, 97, 120, 95, 115, 104, 101, 97, 114, 0, 97, 118, 103, + 95, 115, 112, 114, 105, 110, 103, 95, 108, 101, 110, 0, 116, 105, 109, 101, 115, 99, 97, 108, 101, 0, 101, 102, 102, 95, 102, 111, 114, 99, 101, 95, + 115, 99, 97, 108, 101, 0, 101, 102, 102, 95, 119, 105, 110, 100, 95, 115, 99, 97, 108, 101, 0, 115, 105, 109, 95, 116, 105, 109, 101, 95, 111, 108, + 100, 0, 115, 116, 101, 112, 115, 80, 101, 114, 70, 114, 97, 109, 101, 0, 112, 114, 101, 114, 111, 108, 108, 0, 109, 97, 120, 115, 112, 114, 105, 110, + 103, 108, 101, 110, 0, 115, 111, 108, 118, 101, 114, 95, 116, 121, 112, 101, 0, 118, 103, 114, 111, 117, 112, 95, 98, 101, 110, 100, 0, 118, 103, 114, + 111, 117, 112, 95, 109, 97, 115, 115, 0, 118, 103, 114, 111, 117, 112, 95, 115, 116, 114, 117, 99, 116, 0, 112, 114, 101, 115, 101, 116, 115, 0, 42, + 99, 111, 108, 108, 105, 115, 105, 111, 110, 95, 108, 105, 115, 116, 0, 101, 112, 115, 105, 108, 111, 110, 0, 115, 101, 108, 102, 95, 102, 114, 105, 99, + 116, 105, 111, 110, 0, 115, 101, 108, 102, 101, 112, 115, 105, 108, 111, 110, 0, 115, 101, 108, 102, 95, 108, 111, 111, 112, 95, 99, 111, 117, 110, 116, + 0, 108, 111, 111, 112, 95, 99, 111, 117, 110, 116, 0, 112, 114, 101, 115, 115, 117, 114, 101, 0, 42, 112, 111, 105, 110, 116, 115, 0, 116, 111, 116, + 112, 111, 105, 110, 116, 115, 0, 116, 104, 105, 99, 107, 110, 101, 115, 115, 0, 115, 116, 114, 111, 107, 101, 115, 0, 102, 114, 97, 109, 101, 110, 117, + 109, 0, 42, 97, 99, 116, 102, 114, 97, 109, 101, 0, 103, 115, 116, 101, 112, 0, 105, 110, 102, 111, 91, 49, 50, 56, 93, 0, 115, 98, 117, 102, + 102, 101, 114, 95, 115, 105, 122, 101, 0, 115, 98, 117, 102, 102, 101, 114, 95, 115, 102, 108, 97, 103, 0, 42, 115, 98, 117, 102, 102, 101, 114, 0, + 0, 0, 0, 84, 89, 80, 69, 100, 1, 0, 0, 99, 104, 97, 114, 0, 117, 99, 104, 97, 114, 0, 115, 104, 111, 114, 116, 0, 117, 115, 104, 111, + 114, 116, 0, 105, 110, 116, 0, 108, 111, 110, 103, 0, 117, 108, 111, 110, 103, 0, 102, 108, 111, 97, 116, 0, 100, 111, 117, 98, 108, 101, 0, 118, + 111, 105, 100, 0, 76, 105, 110, 107, 0, 76, 105, 110, 107, 68, 97, 116, 97, 0, 76, 105, 115, 116, 66, 97, 115, 101, 0, 118, 101, 99, 50, 115, + 0, 118, 101, 99, 50, 105, 0, 118, 101, 99, 50, 102, 0, 118, 101, 99, 50, 100, 0, 118, 101, 99, 51, 105, 0, 118, 101, 99, 51, 102, 0, 118, + 101, 99, 51, 100, 0, 118, 101, 99, 52, 105, 0, 118, 101, 99, 52, 102, 0, 118, 101, 99, 52, 100, 0, 114, 99, 116, 105, 0, 114, 99, 116, 102, + 0, 73, 68, 80, 114, 111, 112, 101, 114, 116, 121, 68, 97, 116, 97, 0, 73, 68, 80, 114, 111, 112, 101, 114, 116, 121, 0, 73, 68, 0, 76, 105, + 98, 114, 97, 114, 121, 0, 70, 105, 108, 101, 68, 97, 116, 97, 0, 80, 114, 101, 118, 105, 101, 119, 73, 109, 97, 103, 101, 0, 73, 112, 111, 68, + 114, 105, 118, 101, 114, 0, 79, 98, 106, 101, 99, 116, 0, 73, 112, 111, 67, 117, 114, 118, 101, 0, 66, 80, 111, 105, 110, 116, 0, 66, 101, 122, + 84, 114, 105, 112, 108, 101, 0, 73, 112, 111, 0, 75, 101, 121, 66, 108, 111, 99, 107, 0, 75, 101, 121, 0, 83, 99, 114, 105, 112, 116, 76, 105, + 110, 107, 0, 84, 101, 120, 116, 76, 105, 110, 101, 0, 84, 101, 120, 116, 77, 97, 114, 107, 101, 114, 0, 84, 101, 120, 116, 0, 80, 97, 99, 107, + 101, 100, 70, 105, 108, 101, 0, 67, 97, 109, 101, 114, 97, 0, 73, 109, 97, 103, 101, 85, 115, 101, 114, 0, 73, 109, 97, 103, 101, 0, 71, 80, + 85, 84, 101, 120, 116, 117, 114, 101, 0, 97, 110, 105, 109, 0, 82, 101, 110, 100, 101, 114, 82, 101, 115, 117, 108, 116, 0, 77, 84, 101, 120, 0, + 84, 101, 120, 0, 80, 108, 117, 103, 105, 110, 84, 101, 120, 0, 67, 66, 68, 97, 116, 97, 0, 67, 111, 108, 111, 114, 66, 97, 110, 100, 0, 69, + 110, 118, 77, 97, 112, 0, 73, 109, 66, 117, 102, 0, 98, 78, 111, 100, 101, 84, 114, 101, 101, 0, 84, 101, 120, 77, 97, 112, 112, 105, 110, 103, + 0, 76, 97, 109, 112, 0, 67, 117, 114, 118, 101, 77, 97, 112, 112, 105, 110, 103, 0, 87, 97, 118, 101, 0, 77, 97, 116, 101, 114, 105, 97, 108, + 0, 71, 114, 111, 117, 112, 0, 86, 70, 111, 110, 116, 0, 86, 70, 111, 110, 116, 68, 97, 116, 97, 0, 77, 101, 116, 97, 69, 108, 101, 109, 0, + 66, 111, 117, 110, 100, 66, 111, 120, 0, 77, 101, 116, 97, 66, 97, 108, 108, 0, 78, 117, 114, 98, 0, 67, 104, 97, 114, 73, 110, 102, 111, 0, + 84, 101, 120, 116, 66, 111, 120, 0, 67, 117, 114, 118, 101, 0, 80, 97, 116, 104, 0, 77, 101, 115, 104, 0, 77, 70, 97, 99, 101, 0, 77, 84, + 70, 97, 99, 101, 0, 84, 70, 97, 99, 101, 0, 77, 86, 101, 114, 116, 0, 77, 69, 100, 103, 101, 0, 77, 68, 101, 102, 111, 114, 109, 86, 101, + 114, 116, 0, 77, 67, 111, 108, 0, 77, 83, 116, 105, 99, 107, 121, 0, 77, 83, 101, 108, 101, 99, 116, 0, 67, 117, 115, 116, 111, 109, 68, 97, + 116, 97, 0, 77, 117, 108, 116, 105, 114, 101, 115, 0, 80, 97, 114, 116, 105, 97, 108, 86, 105, 115, 105, 98, 105, 108, 105, 116, 121, 0, 77, 68, + 101, 102, 111, 114, 109, 87, 101, 105, 103, 104, 116, 0, 77, 84, 101, 120, 80, 111, 108, 121, 0, 77, 76, 111, 111, 112, 85, 86, 0, 77, 76, 111, + 111, 112, 67, 111, 108, 0, 77, 70, 108, 111, 97, 116, 80, 114, 111, 112, 101, 114, 116, 121, 0, 77, 73, 110, 116, 80, 114, 111, 112, 101, 114, 116, + 121, 0, 77, 83, 116, 114, 105, 110, 103, 80, 114, 111, 112, 101, 114, 116, 121, 0, 79, 114, 105, 103, 83, 112, 97, 99, 101, 70, 97, 99, 101, 0, + 77, 117, 108, 116, 105, 114, 101, 115, 67, 111, 108, 0, 77, 117, 108, 116, 105, 114, 101, 115, 67, 111, 108, 70, 97, 99, 101, 0, 77, 117, 108, 116, + 105, 114, 101, 115, 70, 97, 99, 101, 0, 77, 117, 108, 116, 105, 114, 101, 115, 69, 100, 103, 101, 0, 77, 117, 108, 116, 105, 114, 101, 115, 76, 101, + 118, 101, 108, 0, 77, 117, 108, 116, 105, 114, 101, 115, 77, 97, 112, 78, 111, 100, 101, 0, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, + 0, 83, 117, 98, 115, 117, 114, 102, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 76, 97, 116, 116, 105, 99, 101, 77, 111, 100, 105, + 102, 105, 101, 114, 68, 97, 116, 97, 0, 67, 117, 114, 118, 101, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 66, 117, 105, 108, 100, + 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 77, 97, 115, 107, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 65, 114, + 114, 97, 121, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 77, 105, 114, 114, 111, 114, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, + 116, 97, 0, 69, 100, 103, 101, 83, 112, 108, 105, 116, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 66, 101, 118, 101, 108, 77, 111, + 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 66, 77, 101, 115, 104, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 68, 105, 115, + 112, 108, 97, 99, 101, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 85, 86, 80, 114, 111, 106, 101, 99, 116, 77, 111, 100, 105, 102, + 105, 101, 114, 68, 97, 116, 97, 0, 68, 101, 99, 105, 109, 97, 116, 101, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 83, 109, 111, + 111, 116, 104, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 67, 97, 115, 116, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, + 0, 87, 97, 118, 101, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 65, 114, 109, 97, 116, 117, 114, 101, 77, 111, 100, 105, 102, 105, + 101, 114, 68, 97, 116, 97, 0, 72, 111, 111, 107, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 83, 111, 102, 116, 98, 111, 100, 121, + 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 67, 108, 111, 116, 104, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 67, + 108, 111, 116, 104, 0, 67, 108, 111, 116, 104, 83, 105, 109, 83, 101, 116, 116, 105, 110, 103, 115, 0, 67, 108, 111, 116, 104, 67, 111, 108, 108, 83, + 101, 116, 116, 105, 110, 103, 115, 0, 80, 111, 105, 110, 116, 67, 97, 99, 104, 101, 0, 67, 111, 108, 108, 105, 115, 105, 111, 110, 77, 111, 100, 105, + 102, 105, 101, 114, 68, 97, 116, 97, 0, 66, 86, 72, 84, 114, 101, 101, 0, 83, 117, 114, 102, 97, 99, 101, 77, 111, 100, 105, 102, 105, 101, 114, + 68, 97, 116, 97, 0, 68, 101, 114, 105, 118, 101, 100, 77, 101, 115, 104, 0, 66, 86, 72, 84, 114, 101, 101, 70, 114, 111, 109, 77, 101, 115, 104, + 0, 66, 111, 111, 108, 101, 97, 110, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 77, 68, 101, 102, 73, 110, 102, 108, 117, 101, 110, + 99, 101, 0, 77, 68, 101, 102, 67, 101, 108, 108, 0, 77, 101, 115, 104, 68, 101, 102, 111, 114, 109, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, + 116, 97, 0, 80, 97, 114, 116, 105, 99, 108, 101, 83, 121, 115, 116, 101, 109, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 80, 97, + 114, 116, 105, 99, 108, 101, 83, 121, 115, 116, 101, 109, 0, 80, 97, 114, 116, 105, 99, 108, 101, 73, 110, 115, 116, 97, 110, 99, 101, 77, 111, 100, + 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 69, 120, 112, 108, 111, 100, 101, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 70, 108, + 117, 105, 100, 115, 105, 109, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 70, 108, 117, 105, 100, 115, 105, 109, 83, 101, 116, 116, 105, + 110, 103, 115, 0, 83, 104, 114, 105, 110, 107, 119, 114, 97, 112, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 83, 105, 109, 112, 108, + 101, 68, 101, 102, 111, 114, 109, 77, 111, 100, 105, 102, 105, 101, 114, 68, 97, 116, 97, 0, 76, 97, 116, 116, 105, 99, 101, 0, 98, 68, 101, 102, + 111, 114, 109, 71, 114, 111, 117, 112, 0, 98, 65, 99, 116, 105, 111, 110, 0, 98, 80, 111, 115, 101, 0, 66, 117, 108, 108, 101, 116, 83, 111, 102, + 116, 66, 111, 100, 121, 0, 80, 97, 114, 116, 68, 101, 102, 108, 101, 99, 116, 0, 83, 111, 102, 116, 66, 111, 100, 121, 0, 79, 98, 72, 111, 111, + 107, 0, 82, 78, 71, 0, 83, 66, 86, 101, 114, 116, 101, 120, 0, 66, 111, 100, 121, 80, 111, 105, 110, 116, 0, 66, 111, 100, 121, 83, 112, 114, + 105, 110, 103, 0, 83, 66, 83, 99, 114, 97, 116, 99, 104, 0, 87, 111, 114, 108, 100, 0, 82, 97, 100, 105, 111, 0, 66, 97, 115, 101, 0, 65, + 118, 105, 67, 111, 100, 101, 99, 68, 97, 116, 97, 0, 81, 117, 105, 99, 107, 116, 105, 109, 101, 67, 111, 100, 101, 99, 68, 97, 116, 97, 0, 70, + 70, 77, 112, 101, 103, 67, 111, 100, 101, 99, 68, 97, 116, 97, 0, 65, 117, 100, 105, 111, 68, 97, 116, 97, 0, 83, 99, 101, 110, 101, 82, 101, + 110, 100, 101, 114, 76, 97, 121, 101, 114, 0, 82, 101, 110, 100, 101, 114, 68, 97, 116, 97, 0, 82, 101, 110, 100, 101, 114, 80, 114, 111, 102, 105, + 108, 101, 0, 71, 97, 109, 101, 70, 114, 97, 109, 105, 110, 103, 0, 84, 105, 109, 101, 77, 97, 114, 107, 101, 114, 0, 73, 109, 97, 103, 101, 80, + 97, 105, 110, 116, 83, 101, 116, 116, 105, 110, 103, 115, 0, 66, 114, 117, 115, 104, 0, 80, 97, 114, 116, 105, 99, 108, 101, 66, 114, 117, 115, 104, + 68, 97, 116, 97, 0, 80, 97, 114, 116, 105, 99, 108, 101, 69, 100, 105, 116, 83, 101, 116, 116, 105, 110, 103, 115, 0, 84, 114, 97, 110, 115, 102, + 111, 114, 109, 79, 114, 105, 101, 110, 116, 97, 116, 105, 111, 110, 0, 84, 111, 111, 108, 83, 101, 116, 116, 105, 110, 103, 115, 0, 66, 114, 117, 115, + 104, 68, 97, 116, 97, 0, 83, 99, 117, 108, 112, 116, 68, 97, 116, 97, 0, 83, 99, 117, 108, 112, 116, 83, 101, 115, 115, 105, 111, 110, 0, 83, + 99, 101, 110, 101, 0, 68, 97, 103, 70, 111, 114, 101, 115, 116, 0, 66, 71, 112, 105, 99, 0, 86, 105, 101, 119, 51, 68, 0, 83, 112, 97, 99, + 101, 76, 105, 110, 107, 0, 83, 99, 114, 65, 114, 101, 97, 0, 82, 101, 110, 100, 101, 114, 73, 110, 102, 111, 0, 82, 101, 116, 111, 112, 111, 86, + 105, 101, 119, 68, 97, 116, 97, 0, 86, 105, 101, 119, 68, 101, 112, 116, 104, 115, 0, 98, 71, 80, 100, 97, 116, 97, 0, 86, 105, 101, 119, 50, + 68, 0, 83, 112, 97, 99, 101, 73, 110, 102, 111, 0, 83, 112, 97, 99, 101, 73, 112, 111, 0, 83, 112, 97, 99, 101, 66, 117, 116, 115, 0, 83, + 112, 97, 99, 101, 83, 101, 113, 0, 83, 112, 97, 99, 101, 70, 105, 108, 101, 0, 100, 105, 114, 101, 110, 116, 114, 121, 0, 66, 108, 101, 110, 100, + 72, 97, 110, 100, 108, 101, 0, 83, 112, 97, 99, 101, 79, 111, 112, 115, 0, 84, 114, 101, 101, 83, 116, 111, 114, 101, 0, 84, 114, 101, 101, 83, + 116, 111, 114, 101, 69, 108, 101, 109, 0, 83, 112, 97, 99, 101, 73, 109, 97, 103, 101, 0, 83, 112, 97, 99, 101, 78, 108, 97, 0, 83, 112, 97, + 99, 101, 84, 101, 120, 116, 0, 83, 99, 114, 105, 112, 116, 0, 83, 112, 97, 99, 101, 83, 99, 114, 105, 112, 116, 0, 83, 112, 97, 99, 101, 84, + 105, 109, 101, 0, 83, 112, 97, 99, 101, 78, 111, 100, 101, 0, 83, 112, 97, 99, 101, 73, 109, 97, 83, 101, 108, 0, 70, 105, 108, 101, 76, 105, + 115, 116, 0, 84, 104, 101, 109, 101, 85, 73, 0, 84, 104, 101, 109, 101, 83, 112, 97, 99, 101, 0, 84, 104, 101, 109, 101, 87, 105, 114, 101, 67, + 111, 108, 111, 114, 0, 98, 84, 104, 101, 109, 101, 0, 83, 111, 108, 105, 100, 76, 105, 103, 104, 116, 0, 85, 115, 101, 114, 68, 101, 102, 0, 98, + 83, 99, 114, 101, 101, 110, 0, 83, 99, 114, 86, 101, 114, 116, 0, 83, 99, 114, 69, 100, 103, 101, 0, 80, 97, 110, 101, 108, 0, 70, 105, 108, + 101, 71, 108, 111, 98, 97, 108, 0, 83, 116, 114, 105, 112, 69, 108, 101, 109, 0, 84, 83, 116, 114, 105, 112, 69, 108, 101, 109, 0, 83, 116, 114, + 105, 112, 67, 114, 111, 112, 0, 83, 116, 114, 105, 112, 84, 114, 97, 110, 115, 102, 111, 114, 109, 0, 83, 116, 114, 105, 112, 67, 111, 108, 111, 114, + 66, 97, 108, 97, 110, 99, 101, 0, 83, 116, 114, 105, 112, 67, 111, 108, 111, 114, 66, 97, 108, 97, 110, 99, 101, 71, 85, 73, 72, 101, 108, 112, + 101, 114, 0, 83, 116, 114, 105, 112, 80, 114, 111, 120, 121, 0, 83, 116, 114, 105, 112, 0, 80, 108, 117, 103, 105, 110, 83, 101, 113, 0, 83, 101, + 113, 117, 101, 110, 99, 101, 0, 98, 83, 111, 117, 110, 100, 0, 104, 100, 97, 117, 100, 105, 111, 0, 77, 101, 116, 97, 83, 116, 97, 99, 107, 0, + 69, 100, 105, 116, 105, 110, 103, 0, 87, 105, 112, 101, 86, 97, 114, 115, 0, 71, 108, 111, 119, 86, 97, 114, 115, 0, 84, 114, 97, 110, 115, 102, + 111, 114, 109, 86, 97, 114, 115, 0, 83, 111, 108, 105, 100, 67, 111, 108, 111, 114, 86, 97, 114, 115, 0, 83, 112, 101, 101, 100, 67, 111, 110, 116, + 114, 111, 108, 86, 97, 114, 115, 0, 69, 102, 102, 101, 99, 116, 0, 66, 117, 105, 108, 100, 69, 102, 102, 0, 80, 97, 114, 116, 69, 102, 102, 0, + 80, 97, 114, 116, 105, 99, 108, 101, 0, 87, 97, 118, 101, 69, 102, 102, 0, 79, 111, 112, 115, 0, 98, 80, 114, 111, 112, 101, 114, 116, 121, 0, + 98, 78, 101, 97, 114, 83, 101, 110, 115, 111, 114, 0, 98, 77, 111, 117, 115, 101, 83, 101, 110, 115, 111, 114, 0, 98, 84, 111, 117, 99, 104, 83, + 101, 110, 115, 111, 114, 0, 98, 75, 101, 121, 98, 111, 97, 114, 100, 83, 101, 110, 115, 111, 114, 0, 98, 80, 114, 111, 112, 101, 114, 116, 121, 83, + 101, 110, 115, 111, 114, 0, 98, 65, 99, 116, 117, 97, 116, 111, 114, 83, 101, 110, 115, 111, 114, 0, 98, 68, 101, 108, 97, 121, 83, 101, 110, 115, + 111, 114, 0, 98, 67, 111, 108, 108, 105, 115, 105, 111, 110, 83, 101, 110, 115, 111, 114, 0, 98, 82, 97, 100, 97, 114, 83, 101, 110, 115, 111, 114, + 0, 98, 82, 97, 110, 100, 111, 109, 83, 101, 110, 115, 111, 114, 0, 98, 82, 97, 121, 83, 101, 110, 115, 111, 114, 0, 98, 77, 101, 115, 115, 97, + 103, 101, 83, 101, 110, 115, 111, 114, 0, 98, 83, 101, 110, 115, 111, 114, 0, 98, 67, 111, 110, 116, 114, 111, 108, 108, 101, 114, 0, 98, 74, 111, + 121, 115, 116, 105, 99, 107, 83, 101, 110, 115, 111, 114, 0, 98, 69, 120, 112, 114, 101, 115, 115, 105, 111, 110, 67, 111, 110, 116, 0, 98, 80, 121, + 116, 104, 111, 110, 67, 111, 110, 116, 0, 98, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 65, 100, 100, 79, 98, 106, 101, 99, 116, 65, 99, 116, + 117, 97, 116, 111, 114, 0, 98, 65, 99, 116, 105, 111, 110, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 83, 111, 117, 110, 100, 65, 99, 116, 117, + 97, 116, 111, 114, 0, 98, 67, 68, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 69, 100, 105, 116, 79, 98, 106, 101, 99, 116, 65, 99, 116, 117, + 97, 116, 111, 114, 0, 98, 83, 99, 101, 110, 101, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 80, 114, 111, 112, 101, 114, 116, 121, 65, 99, 116, + 117, 97, 116, 111, 114, 0, 98, 79, 98, 106, 101, 99, 116, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 73, 112, 111, 65, 99, 116, 117, 97, 116, + 111, 114, 0, 98, 67, 97, 109, 101, 114, 97, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 65, 99, + 116, 117, 97, 116, 111, 114, 0, 98, 71, 114, 111, 117, 112, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 82, 97, 110, 100, 111, 109, 65, 99, 116, + 117, 97, 116, 111, 114, 0, 98, 77, 101, 115, 115, 97, 103, 101, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 71, 97, 109, 101, 65, 99, 116, 117, + 97, 116, 111, 114, 0, 98, 86, 105, 115, 105, 98, 105, 108, 105, 116, 121, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 84, 119, 111, 68, 70, 105, + 108, 116, 101, 114, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 80, 97, 114, 101, 110, 116, 65, 99, 116, 117, 97, 116, 111, 114, 0, 98, 83, 116, + 97, 116, 101, 65, 99, 116, 117, 97, 116, 111, 114, 0, 70, 114, 101, 101, 67, 97, 109, 101, 114, 97, 0, 98, 83, 97, 109, 112, 108, 101, 0, 98, + 83, 111, 117, 110, 100, 76, 105, 115, 116, 101, 110, 101, 114, 0, 83, 112, 97, 99, 101, 83, 111, 117, 110, 100, 0, 71, 114, 111, 117, 112, 79, 98, + 106, 101, 99, 116, 0, 66, 111, 110, 101, 0, 98, 65, 114, 109, 97, 116, 117, 114, 101, 0, 98, 80, 111, 115, 101, 67, 104, 97, 110, 110, 101, 108, + 0, 98, 65, 99, 116, 105, 111, 110, 71, 114, 111, 117, 112, 0, 98, 65, 99, 116, 105, 111, 110, 67, 104, 97, 110, 110, 101, 108, 0, 83, 112, 97, + 99, 101, 65, 99, 116, 105, 111, 110, 0, 98, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 67, 104, 97, 110, 110, 101, 108, 0, 98, 67, 111, 110, + 115, 116, 114, 97, 105, 110, 116, 0, 98, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 84, 97, 114, 103, 101, 116, 0, 98, 80, 121, 116, 104, 111, + 110, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 75, 105, 110, 101, 109, 97, 116, 105, 99, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, + 0, 98, 84, 114, 97, 99, 107, 84, 111, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 82, 111, 116, 97, 116, 101, 76, 105, 107, 101, 67, + 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 76, 111, 99, 97, 116, 101, 76, 105, 107, 101, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, + 98, 77, 105, 110, 77, 97, 120, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 83, 105, 122, 101, 76, 105, 107, 101, 67, 111, 110, 115, 116, + 114, 97, 105, 110, 116, 0, 98, 65, 99, 116, 105, 111, 110, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 76, 111, 99, 107, 84, 114, 97, + 99, 107, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 70, 111, 108, 108, 111, 119, 80, 97, 116, 104, 67, 111, 110, 115, 116, 114, 97, 105, + 110, 116, 0, 98, 83, 116, 114, 101, 116, 99, 104, 84, 111, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 82, 105, 103, 105, 100, 66, 111, + 100, 121, 74, 111, 105, 110, 116, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 67, 108, 97, 109, 112, 84, 111, 67, 111, 110, 115, 116, 114, + 97, 105, 110, 116, 0, 98, 67, 104, 105, 108, 100, 79, 102, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 84, 114, 97, 110, 115, 102, 111, + 114, 109, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 76, 111, 99, 76, 105, 109, 105, 116, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, + 0, 98, 82, 111, 116, 76, 105, 109, 105, 116, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 83, 105, 122, 101, 76, 105, 109, 105, 116, 67, + 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 68, 105, 115, 116, 76, 105, 109, 105, 116, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, + 83, 104, 114, 105, 110, 107, 119, 114, 97, 112, 67, 111, 110, 115, 116, 114, 97, 105, 110, 116, 0, 98, 65, 99, 116, 105, 111, 110, 77, 111, 100, 105, + 102, 105, 101, 114, 0, 98, 65, 99, 116, 105, 111, 110, 83, 116, 114, 105, 112, 0, 98, 78, 111, 100, 101, 83, 116, 97, 99, 107, 0, 98, 78, 111, + 100, 101, 83, 111, 99, 107, 101, 116, 0, 98, 78, 111, 100, 101, 76, 105, 110, 107, 0, 98, 78, 111, 100, 101, 0, 98, 78, 111, 100, 101, 80, 114, + 101, 118, 105, 101, 119, 0, 98, 78, 111, 100, 101, 84, 121, 112, 101, 0, 78, 111, 100, 101, 73, 109, 97, 103, 101, 65, 110, 105, 109, 0, 78, 111, + 100, 101, 66, 108, 117, 114, 68, 97, 116, 97, 0, 78, 111, 100, 101, 68, 66, 108, 117, 114, 68, 97, 116, 97, 0, 78, 111, 100, 101, 66, 105, 108, + 97, 116, 101, 114, 97, 108, 66, 108, 117, 114, 68, 97, 116, 97, 0, 78, 111, 100, 101, 72, 117, 101, 83, 97, 116, 0, 78, 111, 100, 101, 73, 109, + 97, 103, 101, 70, 105, 108, 101, 0, 78, 111, 100, 101, 67, 104, 114, 111, 109, 97, 0, 78, 111, 100, 101, 84, 119, 111, 88, 89, 115, 0, 78, 111, + 100, 101, 84, 119, 111, 70, 108, 111, 97, 116, 115, 0, 78, 111, 100, 101, 71, 101, 111, 109, 101, 116, 114, 121, 0, 78, 111, 100, 101, 86, 101, 114, + 116, 101, 120, 67, 111, 108, 0, 78, 111, 100, 101, 68, 101, 102, 111, 99, 117, 115, 0, 78, 111, 100, 101, 83, 99, 114, 105, 112, 116, 68, 105, 99, + 116, 0, 78, 111, 100, 101, 71, 108, 97, 114, 101, 0, 78, 111, 100, 101, 84, 111, 110, 101, 109, 97, 112, 0, 78, 111, 100, 101, 76, 101, 110, 115, + 68, 105, 115, 116, 0, 84, 101, 120, 78, 111, 100, 101, 79, 117, 116, 112, 117, 116, 0, 67, 117, 114, 118, 101, 77, 97, 112, 80, 111, 105, 110, 116, + 0, 67, 117, 114, 118, 101, 77, 97, 112, 0, 66, 114, 117, 115, 104, 67, 108, 111, 110, 101, 0, 67, 117, 115, 116, 111, 109, 68, 97, 116, 97, 76, + 97, 121, 101, 114, 0, 72, 97, 105, 114, 75, 101, 121, 0, 80, 97, 114, 116, 105, 99, 108, 101, 75, 101, 121, 0, 67, 104, 105, 108, 100, 80, 97, + 114, 116, 105, 99, 108, 101, 0, 80, 97, 114, 116, 105, 99, 108, 101, 68, 97, 116, 97, 0, 80, 97, 114, 116, 105, 99, 108, 101, 83, 101, 116, 116, + 105, 110, 103, 115, 0, 80, 97, 114, 116, 105, 99, 108, 101, 69, 100, 105, 116, 0, 80, 97, 114, 116, 105, 99, 108, 101, 67, 97, 99, 104, 101, 75, + 101, 121, 0, 76, 105, 110, 107, 78, 111, 100, 101, 0, 98, 71, 80, 68, 115, 112, 111, 105, 110, 116, 0, 98, 71, 80, 68, 115, 116, 114, 111, 107, + 101, 0, 98, 71, 80, 68, 102, 114, 97, 109, 101, 0, 98, 71, 80, 68, 108, 97, 121, 101, 114, 0, 0, 84, 76, 69, 78, 1, 0, 1, 0, 2, + 0, 2, 0, 4, 0, 4, 0, 4, 0, 4, 0, 8, 0, 0, 0, 8, 0, 12, 0, 8, 0, 4, 0, 8, 0, 8, 0, 16, 0, 12, 0, 12, + 0, 24, 0, 16, 0, 16, 0, 32, 0, 16, 0, 16, 0, 20, 0, 76, 0, 52, 0, 40, 2, 0, 0, 32, 0, -116, 0, 80, 3, 92, 0, 36, + 0, 56, 0, 84, 0, 112, 0, 120, 0, 16, 0, 24, 0, 40, 0, 120, 0, 20, 0, -124, 0, 32, 0, -128, 1, 0, 0, 0, 0, 0, 0, -120, + 0, 16, 1, 84, 1, 24, 0, 8, 3, -88, 0, 0, 0, 124, 0, -124, 0, -128, 1, 8, 1, 56, 0, 108, 2, 76, 0, 68, 1, 0, 0, 108, + 0, 104, 0, -120, 0, 56, 0, 8, 0, 16, 0, 56, 1, 0, 0, 24, 1, 20, 0, 44, 0, 60, 0, 24, 0, 12, 0, 12, 0, 4, 0, 8, + 0, 8, 0, 24, 0, 76, 0, 32, 0, 8, 0, 12, 0, 8, 0, 8, 0, 4, 0, 4, 0, 0, 1, 32, 0, 16, 0, 64, 0, 24, 0, 12, + 0, 56, 0, 0, 0, 52, 0, 68, 0, 88, 0, 96, 0, 68, 0, 96, 0, 116, 0, 64, 0, 60, 0, 108, 0, 60, 0, -108, 0, -104, 0, 60, + 0, 92, 0, 104, 0, -72, 0, 100, 0, -76, 0, 52, 0, 68, 0, 0, 0, -124, 0, 28, 0, 20, 0, 100, 0, 0, 0, 60, 0, 0, 0, 0, + 0, 64, 0, 8, 0, 8, 0, -40, 0, 76, 0, 64, 1, 64, 0, 64, 0, 60, 0, -92, 1, 108, 0, 104, 0, 116, 0, 40, 0, 84, 0, 56, + 0, 120, 0, -128, 0, -8, 0, -48, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 108, 1, 40, 0, 28, 0, -80, 0, -112, 0, 52, 0, 16, + 0, 72, 0, -48, 3, 56, 0, 16, 0, 80, 0, 12, 0, -72, 0, 8, 0, 72, 0, 80, 0, -24, 0, 8, 0, -88, 0, 0, 0, 124, 5, 0, + 0, 60, 0, 28, 3, 36, 0, -52, 0, 0, 0, 0, 0, 0, 0, 20, 0, -120, 0, 36, 0, 88, 1, -36, 0, -56, 0, -56, 1, 0, 0, 0, + 0, 8, 1, 12, 0, 12, 0, 8, 1, -76, 0, -128, 0, 80, 2, 36, 0, -92, 0, -36, 0, -124, 2, 0, 0, -104, 0, -48, 0, 16, 0, 56, + 14, 56, 0, 32, 12, 120, 0, 20, 0, 24, 0, -28, 0, 32, 0, 80, 0, 28, 0, 16, 0, 8, 0, 60, 0, 0, 0, -4, 0, -16, 0, -88, + 1, -60, 0, 28, 1, 0, 0, 16, 0, 28, 0, 12, 0, 24, 0, 48, 0, 16, 0, 28, 0, 16, 0, 24, 0, 56, 1, 0, 0, 56, 0, 44, + 0, 64, 0, 48, 0, 8, 0, 44, 0, 72, 0, 104, 0, 40, 0, 8, 0, 72, 0, 44, 0, 40, 0, 108, 0, 68, 0, 76, 0, 80, 0, 60, + 0, -128, 0, 76, 0, 60, 0, 12, 0, 92, 0, 28, 0, 20, 0, 80, 0, 16, 0, 76, 0, 108, 0, 84, 0, 28, 0, 96, 0, 60, 0, 56, + 0, 108, 0, -116, 0, 4, 0, 20, 0, 12, 0, 8, 0, 40, 0, 0, 0, 68, 0, -80, 0, 24, 0, 4, 1, 116, 0, -104, 1, 72, 0, 64, + 0, -64, 0, 44, 0, 64, 0, 116, 0, 60, 0, 104, 0, 52, 0, 44, 0, 44, 0, 68, 0, 44, 0, 64, 0, 44, 0, 20, 0, 52, 0, 96, + 0, 12, 0, 108, 0, 92, 0, 28, 0, 28, 0, 28, 0, 52, 0, 20, 0, 60, 0, -116, 0, 36, 0, 120, 0, 24, 0, -52, 0, 0, 0, 0, + 0, 16, 0, 40, 0, 28, 0, 12, 0, 12, 0, 16, 1, 40, 0, 8, 0, 8, 0, 64, 0, 32, 0, 24, 0, 8, 0, 24, 0, 32, 0, 8, + 0, 32, 0, 12, 0, 44, 0, 20, 0, 68, 0, 24, 0, 56, 0, 72, 0, -4, 0, -32, 1, 0, 0, 0, 0, 0, 0, 16, 0, 20, 0, 24, + 0, -84, 0, 83, 84, 82, 67, 57, 1, 0, 0, 10, 0, 2, 0, 10, 0, 0, 0, 10, 0, 1, 0, 11, 0, 3, 0, 11, 0, 0, 0, 11, + 0, 1, 0, 9, 0, 2, 0, 12, 0, 2, 0, 9, 0, 3, 0, 9, 0, 4, 0, 13, 0, 2, 0, 2, 0, 5, 0, 2, 0, 6, 0, 14, + 0, 2, 0, 4, 0, 5, 0, 4, 0, 6, 0, 15, 0, 2, 0, 7, 0, 5, 0, 7, 0, 6, 0, 16, 0, 2, 0, 8, 0, 5, 0, 8, + 0, 6, 0, 17, 0, 3, 0, 4, 0, 5, 0, 4, 0, 6, 0, 4, 0, 7, 0, 18, 0, 3, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, + 0, 7, 0, 19, 0, 3, 0, 8, 0, 5, 0, 8, 0, 6, 0, 8, 0, 7, 0, 20, 0, 4, 0, 4, 0, 5, 0, 4, 0, 6, 0, 4, + 0, 7, 0, 4, 0, 8, 0, 21, 0, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 7, 0, 8, 0, 22, 0, 4, 0, 8, + 0, 5, 0, 8, 0, 6, 0, 8, 0, 7, 0, 8, 0, 8, 0, 23, 0, 4, 0, 4, 0, 9, 0, 4, 0, 10, 0, 4, 0, 11, 0, 4, + 0, 12, 0, 24, 0, 4, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0, 25, 0, 4, 0, 9, 0, 13, 0, 12, + 0, 14, 0, 4, 0, 15, 0, 4, 0, 16, 0, 26, 0, 10, 0, 26, 0, 0, 0, 26, 0, 1, 0, 0, 0, 17, 0, 0, 0, 18, 0, 0, + 0, 19, 0, 2, 0, 20, 0, 4, 0, 21, 0, 25, 0, 22, 0, 4, 0, 23, 0, 4, 0, 24, 0, 27, 0, 9, 0, 9, 0, 0, 0, 9, + 0, 1, 0, 27, 0, 25, 0, 28, 0, 26, 0, 0, 0, 27, 0, 2, 0, 28, 0, 2, 0, 20, 0, 4, 0, 29, 0, 26, 0, 30, 0, 28, + 0, 8, 0, 27, 0, 31, 0, 27, 0, 32, 0, 29, 0, 33, 0, 0, 0, 34, 0, 0, 0, 35, 0, 4, 0, 36, 0, 4, 0, 37, 0, 28, + 0, 38, 0, 30, 0, 6, 0, 4, 0, 39, 0, 4, 0, 40, 0, 2, 0, 41, 0, 2, 0, 42, 0, 2, 0, 43, 0, 4, 0, 44, 0, 31, + 0, 6, 0, 32, 0, 45, 0, 2, 0, 46, 0, 2, 0, 47, 0, 2, 0, 18, 0, 2, 0, 20, 0, 0, 0, 48, 0, 33, 0, 21, 0, 33, + 0, 0, 0, 33, 0, 1, 0, 34, 0, 49, 0, 35, 0, 50, 0, 24, 0, 51, 0, 24, 0, 52, 0, 2, 0, 46, 0, 2, 0, 47, 0, 2, + 0, 53, 0, 2, 0, 54, 0, 2, 0, 55, 0, 2, 0, 56, 0, 2, 0, 20, 0, 2, 0, 57, 0, 7, 0, 11, 0, 7, 0, 12, 0, 4, + 0, 58, 0, 7, 0, 59, 0, 7, 0, 60, 0, 7, 0, 61, 0, 31, 0, 62, 0, 36, 0, 7, 0, 27, 0, 31, 0, 12, 0, 63, 0, 24, + 0, 64, 0, 2, 0, 46, 0, 2, 0, 65, 0, 2, 0, 66, 0, 2, 0, 37, 0, 37, 0, 16, 0, 37, 0, 0, 0, 37, 0, 1, 0, 7, + 0, 67, 0, 7, 0, 61, 0, 2, 0, 18, 0, 2, 0, 47, 0, 2, 0, 68, 0, 2, 0, 20, 0, 4, 0, 69, 0, 4, 0, 70, 0, 9, + 0, 2, 0, 7, 0, 71, 0, 0, 0, 17, 0, 0, 0, 72, 0, 7, 0, 73, 0, 7, 0, 74, 0, 38, 0, 12, 0, 27, 0, 31, 0, 37, + 0, 75, 0, 0, 0, 76, 0, 4, 0, 77, 0, 7, 0, 61, 0, 12, 0, 78, 0, 36, 0, 79, 0, 27, 0, 80, 0, 2, 0, 18, 0, 2, + 0, 81, 0, 2, 0, 82, 0, 2, 0, 20, 0, 39, 0, 5, 0, 27, 0, 83, 0, 2, 0, 84, 0, 2, 0, 85, 0, 2, 0, 86, 0, 4, + 0, 37, 0, 40, 0, 6, 0, 40, 0, 0, 0, 40, 0, 1, 0, 0, 0, 87, 0, 0, 0, 88, 0, 4, 0, 23, 0, 4, 0, 89, 0, 41, + 0, 10, 0, 41, 0, 0, 0, 41, 0, 1, 0, 4, 0, 90, 0, 4, 0, 91, 0, 4, 0, 92, 0, 4, 0, 43, 0, 4, 0, 14, 0, 4, + 0, 93, 0, 0, 0, 94, 0, 0, 0, 95, 0, 42, 0, 15, 0, 27, 0, 31, 0, 0, 0, 96, 0, 4, 0, 93, 0, 4, 0, 97, 0, 12, + 0, 98, 0, 40, 0, 99, 0, 40, 0, 100, 0, 4, 0, 101, 0, 4, 0, 102, 0, 12, 0, 103, 0, 0, 0, 104, 0, 4, 0, 105, 0, 4, + 0, 106, 0, 9, 0, 107, 0, 8, 0, 108, 0, 43, 0, 5, 0, 4, 0, 109, 0, 4, 0, 110, 0, 4, 0, 93, 0, 4, 0, 37, 0, 9, + 0, 2, 0, 44, 0, 20, 0, 27, 0, 31, 0, 2, 0, 18, 0, 2, 0, 20, 0, 7, 0, 111, 0, 7, 0, 112, 0, 7, 0, 113, 0, 7, + 0, 114, 0, 7, 0, 115, 0, 7, 0, 116, 0, 7, 0, 117, 0, 7, 0, 118, 0, 7, 0, 119, 0, 7, 0, 120, 0, 7, 0, 121, 0, 2, + 0, 122, 0, 2, 0, 123, 0, 7, 0, 124, 0, 36, 0, 79, 0, 39, 0, 125, 0, 32, 0, 126, 0, 45, 0, 12, 0, 4, 0, 127, 0, 4, + 0, -128, 0, 4, 0, -127, 0, 4, 0, -126, 0, 2, 0, -125, 0, 2, 0, -124, 0, 2, 0, 20, 0, 2, 0, -123, 0, 2, 0, -122, 0, 2, + 0, -121, 0, 2, 0, -120, 0, 2, 0, -119, 0, 46, 0, 32, 0, 27, 0, 31, 0, 0, 0, 34, 0, 12, 0, -118, 0, 47, 0, -117, 0, 48, + 0, -116, 0, 49, 0, -115, 0, 2, 0, -123, 0, 2, 0, 20, 0, 2, 0, -114, 0, 2, 0, 18, 0, 2, 0, 37, 0, 2, 0, 43, 0, 4, + 0, -113, 0, 2, 0, -112, 0, 2, 0, -111, 0, 2, 0, -110, 0, 2, 0, -109, 0, 2, 0, -108, 0, 2, 0, -107, 0, 4, 0, -106, 0, 4, + 0, -105, 0, 43, 0, -104, 0, 30, 0, -103, 0, 7, 0, -102, 0, 4, 0, -101, 0, 2, 0, -100, 0, 2, 0, -99, 0, 2, 0, -98, 0, 2, + 0, -97, 0, 7, 0, -96, 0, 7, 0, -95, 0, 9, 0, -94, 0, 50, 0, 31, 0, 2, 0, -93, 0, 2, 0, -92, 0, 2, 0, -91, 0, 2, + 0, -90, 0, 32, 0, -89, 0, 51, 0, -88, 0, 0, 0, -87, 0, 0, 0, -86, 0, 0, 0, -85, 0, 0, 0, -84, 0, 0, 0, -83, 0, 7, + 0, -82, 0, 7, 0, -81, 0, 2, 0, -80, 0, 2, 0, -79, 0, 2, 0, -78, 0, 2, 0, -77, 0, 2, 0, -76, 0, 2, 0, -75, 0, 2, + 0, -74, 0, 7, 0, -73, 0, 7, 0, -72, 0, 7, 0, -71, 0, 7, 0, -70, 0, 7, 0, -69, 0, 7, 0, 57, 0, 7, 0, -68, 0, 7, + 0, -67, 0, 7, 0, -66, 0, 7, 0, -65, 0, 7, 0, -64, 0, 52, 0, 15, 0, 0, 0, -63, 0, 9, 0, -62, 0, 0, 0, -61, 0, 0, + 0, -60, 0, 4, 0, -59, 0, 4, 0, -58, 0, 9, 0, -57, 0, 7, 0, -56, 0, 7, 0, -55, 0, 7, 0, -54, 0, 4, 0, -53, 0, 9, + 0, -52, 0, 9, 0, -51, 0, 4, 0, -50, 0, 4, 0, 37, 0, 53, 0, 6, 0, 7, 0, -73, 0, 7, 0, -72, 0, 7, 0, -71, 0, 7, + 0, -49, 0, 7, 0, 67, 0, 4, 0, 64, 0, 54, 0, 5, 0, 2, 0, 20, 0, 2, 0, 36, 0, 2, 0, 64, 0, 2, 0, -48, 0, 53, + 0, -54, 0, 55, 0, 17, 0, 32, 0, -89, 0, 46, 0, -47, 0, 56, 0, -46, 0, 7, 0, -45, 0, 7, 0, -44, 0, 2, 0, 18, 0, 2, + 0, -43, 0, 7, 0, 113, 0, 7, 0, 114, 0, 7, 0, -42, 0, 4, 0, -41, 0, 2, 0, -40, 0, 2, 0, -39, 0, 4, 0, -123, 0, 4, + 0, -113, 0, 2, 0, -38, 0, 2, 0, -37, 0, 51, 0, 56, 0, 27, 0, 31, 0, 7, 0, -36, 0, 7, 0, -35, 0, 7, 0, -34, 0, 7, + 0, -33, 0, 7, 0, -32, 0, 7, 0, -31, 0, 7, 0, -30, 0, 7, 0, -29, 0, 7, 0, -28, 0, 7, 0, -27, 0, 7, 0, -26, 0, 7, + 0, -25, 0, 7, 0, -24, 0, 7, 0, -23, 0, 7, 0, -22, 0, 7, 0, -21, 0, 7, 0, -20, 0, 7, 0, -19, 0, 7, 0, -18, 0, 7, + 0, -17, 0, 2, 0, -16, 0, 2, 0, -15, 0, 2, 0, -14, 0, 2, 0, -13, 0, 2, 0, -12, 0, 2, 0, -11, 0, 2, 0, -10, 0, 2, + 0, 20, 0, 2, 0, 18, 0, 2, 0, -43, 0, 7, 0, -9, 0, 7, 0, -8, 0, 7, 0, -7, 0, 7, 0, -6, 0, 2, 0, -5, 0, 2, + 0, -4, 0, 2, 0, -3, 0, 2, 0, -125, 0, 4, 0, 23, 0, 4, 0, -128, 0, 4, 0, -127, 0, 4, 0, -126, 0, 7, 0, -2, 0, 7, + 0, -1, 0, 7, 0, -67, 0, 45, 0, 0, 1, 57, 0, 1, 1, 36, 0, 79, 0, 46, 0, -47, 0, 52, 0, 2, 1, 54, 0, 3, 1, 55, + 0, 4, 1, 30, 0, -103, 0, 0, 0, 5, 1, 0, 0, 6, 1, 58, 0, 8, 0, 7, 0, 7, 1, 7, 0, 8, 1, 7, 0, -81, 0, 4, + 0, 20, 0, 7, 0, 9, 1, 7, 0, 10, 1, 7, 0, 11, 1, 32, 0, 45, 0, 59, 0, 80, 0, 27, 0, 31, 0, 2, 0, 18, 0, 2, + 0, 12, 1, 4, 0, 13, 1, 2, 0, -79, 0, 2, 0, 14, 1, 7, 0, -73, 0, 7, 0, -72, 0, 7, 0, -71, 0, 7, 0, -70, 0, 7, + 0, 15, 1, 7, 0, 16, 1, 7, 0, 17, 1, 7, 0, 18, 1, 7, 0, 19, 1, 7, 0, 20, 1, 7, 0, 21, 1, 7, 0, 22, 1, 7, + 0, 23, 1, 7, 0, 24, 1, 7, 0, 25, 1, 60, 0, 26, 1, 2, 0, 27, 1, 2, 0, 70, 0, 7, 0, 113, 0, 7, 0, 114, 0, 7, + 0, 28, 1, 7, 0, 29, 1, 7, 0, 30, 1, 2, 0, 31, 1, 2, 0, 32, 1, 2, 0, 33, 1, 2, 0, 34, 1, 0, 0, 35, 1, 0, + 0, 36, 1, 2, 0, 37, 1, 2, 0, 38, 1, 2, 0, 39, 1, 2, 0, 40, 1, 2, 0, 41, 1, 7, 0, 42, 1, 7, 0, 43, 1, 7, + 0, 44, 1, 7, 0, 45, 1, 2, 0, 46, 1, 2, 0, 43, 0, 2, 0, 47, 1, 2, 0, 48, 1, 2, 0, 49, 1, 2, 0, 50, 1, 7, + 0, 51, 1, 7, 0, 52, 1, 7, 0, 53, 1, 7, 0, 54, 1, 7, 0, 55, 1, 7, 0, 56, 1, 7, 0, 57, 1, 7, 0, 58, 1, 7, + 0, 59, 1, 7, 0, 60, 1, 7, 0, 61, 1, 7, 0, 62, 1, 2, 0, 63, 1, 2, 0, 64, 1, 4, 0, 65, 1, 4, 0, 66, 1, 2, + 0, 67, 1, 2, 0, 68, 1, 2, 0, 69, 1, 2, 0, 70, 1, 7, 0, 71, 1, 7, 0, 72, 1, 7, 0, 73, 1, 7, 0, 74, 1, 2, + 0, 75, 1, 2, 0, 76, 1, 50, 0, 77, 1, 36, 0, 79, 0, 30, 0, -103, 0, 39, 0, 125, 0, 61, 0, 2, 0, 27, 0, 31, 0, 36, + 0, 79, 0, 62, 0, -127, 0, 27, 0, 31, 0, 2, 0, -79, 0, 2, 0, 20, 0, 7, 0, -73, 0, 7, 0, -72, 0, 7, 0, -71, 0, 7, + 0, 78, 1, 7, 0, 79, 1, 7, 0, 80, 1, 7, 0, 81, 1, 7, 0, 82, 1, 7, 0, 83, 1, 7, 0, 84, 1, 7, 0, 85, 1, 7, + 0, 86, 1, 7, 0, 87, 1, 7, 0, 88, 1, 7, 0, 89, 1, 7, 0, 90, 1, 7, 0, 91, 1, 7, 0, 92, 1, 7, 0, 93, 1, 7, + 0, 94, 1, 7, 0, 95, 1, 7, 0, 96, 1, 7, 0, 97, 1, 7, 0, 98, 1, 7, 0, 99, 1, 7, 0, 100, 1, 7, 0, 101, 1, 7, + 0, 102, 1, 7, 0, 103, 1, 7, 0, 104, 1, 2, 0, 105, 1, 2, 0, 106, 1, 2, 0, 107, 1, 0, 0, 108, 1, 0, 0, 109, 1, 7, + 0, 110, 1, 7, 0, 111, 1, 2, 0, 112, 1, 2, 0, 113, 1, 7, 0, 114, 1, 7, 0, 115, 1, 7, 0, 116, 1, 7, 0, 117, 1, 2, + 0, 118, 1, 2, 0, 119, 1, 4, 0, 13, 1, 4, 0, 120, 1, 2, 0, 121, 1, 2, 0, 122, 1, 2, 0, 123, 1, 2, 0, 124, 1, 7, + 0, 125, 1, 7, 0, 126, 1, 7, 0, 127, 1, 7, 0, -128, 1, 7, 0, -127, 1, 7, 0, -126, 1, 7, 0, -125, 1, 7, 0, -124, 1, 7, + 0, -123, 1, 7, 0, -122, 1, 0, 0, -121, 1, 7, 0, -120, 1, 7, 0, -119, 1, 7, 0, -118, 1, 4, 0, -117, 1, 0, 0, -116, 1, 0, + 0, 47, 1, 0, 0, -115, 1, 0, 0, 5, 1, 2, 0, -114, 1, 2, 0, -113, 1, 2, 0, 64, 1, 2, 0, -112, 1, 2, 0, -111, 1, 2, + 0, -110, 1, 7, 0, -109, 1, 7, 0, -108, 1, 7, 0, -107, 1, 7, 0, -106, 1, 7, 0, -105, 1, 2, 0, -93, 0, 2, 0, -92, 0, 54, + 0, -104, 1, 54, 0, -103, 1, 0, 0, -102, 1, 0, 0, -101, 1, 0, 0, -100, 1, 0, 0, -99, 1, 2, 0, -98, 1, 2, 0, 12, 1, 7, + 0, -97, 1, 7, 0, -96, 1, 50, 0, 77, 1, 57, 0, 1, 1, 36, 0, 79, 0, 63, 0, -95, 1, 30, 0, -103, 0, 7, 0, -94, 1, 7, + 0, -93, 1, 7, 0, -92, 1, 7, 0, -91, 1, 7, 0, -90, 1, 2, 0, -89, 1, 2, 0, 70, 0, 7, 0, -88, 1, 7, 0, -87, 1, 7, + 0, -86, 1, 7, 0, -85, 1, 7, 0, -84, 1, 7, 0, -83, 1, 7, 0, -82, 1, 7, 0, -81, 1, 7, 0, -80, 1, 2, 0, -79, 1, 2, + 0, -78, 1, 7, 0, -77, 1, 7, 0, -76, 1, 7, 0, -75, 1, 7, 0, -74, 1, 7, 0, -73, 1, 4, 0, -72, 1, 4, 0, -71, 1, 4, + 0, -70, 1, 39, 0, 125, 0, 12, 0, -69, 1, 64, 0, 6, 0, 27, 0, 31, 0, 0, 0, -68, 1, 7, 0, -67, 1, 7, 0, 37, 0, 65, + 0, 2, 0, 43, 0, -104, 0, 66, 0, 26, 0, 66, 0, 0, 0, 66, 0, 1, 0, 67, 0, -66, 1, 4, 0, -65, 1, 4, 0, -64, 1, 4, + 0, -63, 1, 4, 0, -62, 1, 4, 0, -61, 1, 4, 0, -60, 1, 2, 0, 18, 0, 2, 0, 20, 0, 2, 0, -59, 1, 2, 0, -58, 1, 7, + 0, 5, 0, 7, 0, 6, 0, 7, 0, 7, 0, 7, 0, -57, 1, 7, 0, -56, 1, 7, 0, -55, 1, 7, 0, -54, 1, 7, 0, -53, 1, 7, + 0, -52, 1, 7, 0, -51, 1, 7, 0, 23, 0, 7, 0, -50, 1, 7, 0, -49, 1, 68, 0, 15, 0, 27, 0, 31, 0, 67, 0, -66, 1, 12, + 0, -48, 1, 12, 0, -47, 1, 36, 0, 79, 0, 62, 0, -46, 1, 2, 0, 20, 0, 2, 0, -45, 1, 4, 0, -80, 0, 7, 0, 7, 1, 7, + 0, -81, 0, 7, 0, 8, 1, 7, 0, -44, 1, 7, 0, -43, 1, 7, 0, -42, 1, 35, 0, 10, 0, 7, 0, -41, 1, 7, 0, -40, 1, 7, + 0, -39, 1, 7, 0, -38, 1, 2, 0, -37, 1, 2, 0, -36, 1, 0, 0, -35, 1, 0, 0, -34, 1, 0, 0, -33, 1, 0, 0, -32, 1, 34, + 0, 7, 0, 7, 0, -31, 1, 7, 0, -40, 1, 7, 0, -39, 1, 2, 0, -35, 1, 2, 0, -32, 1, 7, 0, -38, 1, 7, 0, 37, 0, 69, + 0, 21, 0, 69, 0, 0, 0, 69, 0, 1, 0, 2, 0, 18, 0, 2, 0, -30, 1, 2, 0, -32, 1, 2, 0, 20, 0, 2, 0, -29, 1, 2, + 0, -28, 1, 2, 0, -27, 1, 2, 0, -26, 1, 2, 0, -25, 1, 2, 0, -24, 1, 2, 0, -23, 1, 2, 0, -22, 1, 7, 0, -21, 1, 7, + 0, -20, 1, 34, 0, 49, 0, 35, 0, 50, 0, 2, 0, -19, 1, 2, 0, -18, 1, 4, 0, -17, 1, 70, 0, 5, 0, 2, 0, -16, 1, 2, + 0, -30, 1, 0, 0, 20, 0, 0, 0, 37, 0, 2, 0, 70, 0, 71, 0, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, 0, 8, 0, 7, + 0, -15, 1, 72, 0, 57, 0, 27, 0, 31, 0, 67, 0, -66, 1, 12, 0, -14, 1, 12, 0, -47, 1, 32, 0, -13, 1, 32, 0, -12, 1, 32, + 0, -11, 1, 36, 0, 79, 0, 73, 0, -10, 1, 38, 0, -9, 1, 62, 0, -46, 1, 12, 0, -8, 1, 7, 0, 7, 1, 7, 0, -81, 0, 7, + 0, 8, 1, 4, 0, -80, 0, 2, 0, -7, 1, 2, 0, -45, 1, 2, 0, 20, 0, 2, 0, -6, 1, 7, 0, -5, 1, 7, 0, -4, 1, 7, + 0, -3, 1, 2, 0, -27, 1, 2, 0, -26, 1, 2, 0, -2, 1, 2, 0, -1, 1, 4, 0, 70, 0, 2, 0, 23, 0, 2, 0, 98, 0, 2, + 0, 67, 0, 2, 0, 0, 2, 7, 0, 1, 2, 7, 0, 2, 2, 7, 0, 3, 2, 7, 0, 4, 2, 7, 0, 5, 2, 7, 0, 6, 2, 7, + 0, 7, 2, 7, 0, 8, 2, 7, 0, 9, 2, 7, 0, 10, 2, 0, 0, 11, 2, 0, 0, 12, 2, 64, 0, 13, 2, 64, 0, 14, 2, 64, + 0, 15, 2, 64, 0, 16, 2, 4, 0, 17, 2, 4, 0, 18, 2, 4, 0, 19, 2, 4, 0, 37, 0, 71, 0, 20, 2, 4, 0, 21, 2, 4, + 0, 22, 2, 70, 0, 23, 2, 70, 0, 24, 2, 74, 0, 39, 0, 27, 0, 31, 0, 67, 0, -66, 1, 12, 0, 25, 2, 36, 0, 79, 0, 38, + 0, -9, 1, 62, 0, -46, 1, 75, 0, 26, 2, 76, 0, 27, 2, 77, 0, 28, 2, 78, 0, 29, 2, 79, 0, 30, 2, 80, 0, 31, 2, 81, + 0, 32, 2, 82, 0, 33, 2, 74, 0, 34, 2, 83, 0, 35, 2, 84, 0, 36, 2, 84, 0, 37, 2, 84, 0, 38, 2, 4, 0, 54, 0, 4, + 0, 39, 2, 4, 0, 40, 2, 4, 0, 41, 2, 4, 0, 42, 2, 4, 0, -80, 0, 7, 0, 7, 1, 7, 0, -81, 0, 7, 0, 8, 1, 7, + 0, 43, 2, 7, 0, 37, 0, 2, 0, 44, 2, 2, 0, 20, 0, 2, 0, 45, 2, 2, 0, 46, 2, 2, 0, -45, 1, 2, 0, 47, 2, 85, + 0, 48, 2, 86, 0, 49, 2, 9, 0, -94, 0, 77, 0, 8, 0, 9, 0, 50, 2, 7, 0, 51, 2, 4, 0, 52, 2, 0, 0, 20, 0, 0, + 0, 53, 2, 2, 0, 13, 1, 2, 0, 54, 2, 2, 0, 55, 2, 75, 0, 8, 0, 4, 0, 56, 2, 4, 0, 57, 2, 4, 0, 58, 2, 4, + 0, 59, 2, 0, 0, 37, 0, 0, 0, -30, 1, 0, 0, 60, 2, 0, 0, 20, 0, 79, 0, 5, 0, 4, 0, 56, 2, 4, 0, 57, 2, 0, + 0, 61, 2, 0, 0, 62, 2, 2, 0, 20, 0, 87, 0, 2, 0, 4, 0, 63, 2, 7, 0, -39, 1, 80, 0, 3, 0, 87, 0, 64, 2, 4, + 0, 65, 2, 4, 0, 20, 0, 78, 0, 6, 0, 7, 0, 66, 2, 2, 0, 67, 2, 0, 0, 20, 0, 0, 0, -30, 1, 0, 0, 62, 2, 0, + 0, 68, 2, 81, 0, 4, 0, 0, 0, -49, 0, 0, 0, -73, 0, 0, 0, -72, 0, 0, 0, -71, 0, 88, 0, 6, 0, 46, 0, 50, 2, 0, + 0, 20, 0, 0, 0, 53, 2, 2, 0, 13, 1, 2, 0, 54, 2, 2, 0, 55, 2, 89, 0, 1, 0, 7, 0, 69, 2, 90, 0, 5, 0, 0, + 0, -49, 0, 0, 0, -73, 0, 0, 0, -72, 0, 0, 0, -71, 0, 4, 0, 37, 0, 82, 0, 1, 0, 7, 0, 70, 2, 83, 0, 2, 0, 4, + 0, 71, 2, 4, 0, 18, 0, 76, 0, 7, 0, 7, 0, 51, 2, 46, 0, 50, 2, 0, 0, 20, 0, 0, 0, 53, 2, 2, 0, 13, 1, 2, + 0, 54, 2, 2, 0, 55, 2, 91, 0, 1, 0, 7, 0, 72, 2, 92, 0, 1, 0, 4, 0, 73, 2, 93, 0, 1, 0, 0, 0, 74, 2, 94, + 0, 1, 0, 7, 0, 51, 2, 95, 0, 4, 0, 7, 0, -49, 0, 7, 0, -73, 0, 7, 0, -72, 0, 7, 0, -71, 0, 96, 0, 1, 0, 95, + 0, 52, 2, 97, 0, 5, 0, 4, 0, 75, 2, 4, 0, 76, 2, 0, 0, 20, 0, 0, 0, -30, 1, 0, 0, -74, 0, 98, 0, 2, 0, 4, + 0, 77, 2, 4, 0, 76, 2, 99, 0, 14, 0, 99, 0, 0, 0, 99, 0, 1, 0, 97, 0, 78, 2, 96, 0, 79, 2, 98, 0, 80, 2, 0, + 0, 81, 2, 12, 0, 82, 2, 12, 0, 83, 2, 100, 0, 84, 2, 4, 0, 54, 0, 4, 0, 40, 2, 4, 0, 39, 2, 4, 0, 37, 0, 78, + 0, 85, 2, 85, 0, 14, 0, 12, 0, 86, 2, 78, 0, 85, 2, 0, 0, 87, 2, 0, 0, 88, 2, 0, 0, 89, 2, 0, 0, 90, 2, 0, + 0, 91, 2, 0, 0, 92, 2, 0, 0, 93, 2, 0, 0, 20, 0, 84, 0, 36, 2, 84, 0, 38, 2, 2, 0, 94, 2, 0, 0, 95, 2, 86, + 0, 8, 0, 4, 0, 96, 2, 4, 0, 97, 2, 75, 0, 98, 2, 79, 0, 99, 2, 4, 0, 40, 2, 4, 0, 39, 2, 4, 0, 54, 0, 4, + 0, 37, 0, 101, 0, 6, 0, 101, 0, 0, 0, 101, 0, 1, 0, 4, 0, 18, 0, 4, 0, 13, 1, 0, 0, 17, 0, 0, 0, 100, 2, 102, + 0, 7, 0, 101, 0, 101, 2, 2, 0, 102, 2, 2, 0, 86, 2, 2, 0, 103, 2, 2, 0, 93, 0, 9, 0, 104, 2, 9, 0, 105, 2, 103, + 0, 3, 0, 101, 0, 101, 2, 32, 0, -89, 0, 0, 0, 17, 0, 104, 0, 5, 0, 101, 0, 101, 2, 32, 0, -89, 0, 0, 0, 17, 0, 2, + 0, 106, 2, 0, 0, 107, 2, 105, 0, 5, 0, 101, 0, 101, 2, 7, 0, 91, 0, 7, 0, 108, 2, 4, 0, 109, 2, 4, 0, 110, 2, 106, + 0, 5, 0, 101, 0, 101, 2, 32, 0, 111, 2, 0, 0, 72, 0, 4, 0, 13, 1, 4, 0, 20, 0, 107, 0, 13, 0, 101, 0, 101, 2, 32, + 0, 112, 2, 32, 0, 113, 2, 32, 0, 114, 2, 32, 0, 115, 2, 7, 0, 116, 2, 7, 0, 117, 2, 7, 0, 108, 2, 7, 0, 118, 2, 4, + 0, 119, 2, 4, 0, 120, 2, 4, 0, 93, 0, 4, 0, 121, 2, 108, 0, 5, 0, 101, 0, 101, 2, 2, 0, 122, 2, 2, 0, 20, 0, 7, + 0, 123, 2, 32, 0, 124, 2, 109, 0, 3, 0, 101, 0, 101, 2, 7, 0, 125, 2, 4, 0, 93, 0, 110, 0, 10, 0, 101, 0, 101, 2, 7, + 0, 126, 2, 4, 0, 127, 2, 4, 0, 37, 0, 2, 0, 93, 0, 2, 0, -128, 2, 2, 0, -127, 2, 2, 0, -126, 2, 7, 0, -125, 2, 0, + 0, -124, 2, 111, 0, 3, 0, 101, 0, 101, 2, 7, 0, 37, 0, 4, 0, 18, 0, 112, 0, 11, 0, 101, 0, 101, 2, 51, 0, -123, 2, 7, + 0, -122, 2, 4, 0, -121, 2, 0, 0, -124, 2, 7, 0, -120, 2, 4, 0, -119, 2, 32, 0, -118, 2, 0, 0, -117, 2, 4, 0, -116, 2, 4, + 0, 37, 0, 113, 0, 10, 0, 101, 0, 101, 2, 32, 0, -115, 2, 46, 0, -114, 2, 4, 0, 93, 0, 4, 0, -113, 2, 7, 0, -112, 2, 7, + 0, -111, 2, 0, 0, -117, 2, 4, 0, -116, 2, 4, 0, 37, 0, 114, 0, 3, 0, 101, 0, 101, 2, 7, 0, -110, 2, 4, 0, -109, 2, 115, + 0, 5, 0, 101, 0, 101, 2, 7, 0, -108, 2, 0, 0, -124, 2, 2, 0, 20, 0, 2, 0, -107, 2, 116, 0, 8, 0, 101, 0, 101, 2, 32, + 0, -89, 0, 7, 0, -108, 2, 7, 0, -38, 1, 7, 0, 109, 0, 0, 0, -124, 2, 2, 0, 20, 0, 2, 0, 18, 0, 117, 0, 21, 0, 101, + 0, 101, 2, 32, 0, -106, 2, 0, 0, -124, 2, 51, 0, -123, 2, 32, 0, -118, 2, 2, 0, 20, 0, 2, 0, 37, 0, 7, 0, -105, 2, 7, + 0, -104, 2, 7, 0, -103, 2, 7, 0, -5, 1, 7, 0, -102, 2, 7, 0, -101, 2, 7, 0, -100, 2, 7, 0, -99, 2, 4, 0, -119, 2, 4, + 0, -116, 2, 0, 0, -117, 2, 7, 0, -98, 2, 7, 0, -97, 2, 7, 0, 43, 0, 118, 0, 7, 0, 101, 0, 101, 2, 2, 0, -96, 2, 2, + 0, -95, 2, 4, 0, 70, 0, 32, 0, -89, 0, 7, 0, -94, 2, 0, 0, -124, 2, 119, 0, 9, 0, 101, 0, 101, 2, 32, 0, -89, 0, 7, + 0, -93, 2, 7, 0, -92, 2, 7, 0, -99, 2, 4, 0, -91, 2, 4, 0, -90, 2, 7, 0, -89, 2, 0, 0, 17, 0, 120, 0, 1, 0, 101, + 0, 101, 2, 121, 0, 5, 0, 101, 0, 101, 2, 122, 0, -88, 2, 123, 0, -87, 2, 124, 0, -86, 2, 125, 0, -85, 2, 126, 0, 14, 0, 101, + 0, 101, 2, 78, 0, -84, 2, 78, 0, -83, 2, 78, 0, -82, 2, 78, 0, -81, 2, 78, 0, -80, 2, 78, 0, -79, 2, 75, 0, -78, 2, 4, + 0, -77, 2, 4, 0, -76, 2, 2, 0, -75, 2, 2, 0, 37, 0, 7, 0, -74, 2, 127, 0, -73, 2, -128, 0, 3, 0, 101, 0, 101, 2, -127, + 0, -72, 2, -126, 0, -73, 2, -125, 0, 4, 0, 101, 0, 101, 2, 32, 0, -89, 0, 4, 0, -71, 2, 4, 0, 37, 0, -124, 0, 2, 0, 4, + 0, -70, 2, 7, 0, -39, 1, -123, 0, 2, 0, 4, 0, -127, 0, 4, 0, -69, 2, -122, 0, 20, 0, 101, 0, 101, 2, 32, 0, -89, 0, 0, + 0, -124, 2, 2, 0, -68, 2, 2, 0, -67, 2, 2, 0, 20, 0, 2, 0, 37, 0, 7, 0, -66, 2, 7, 0, -65, 2, 4, 0, 54, 0, 4, + 0, -64, 2, -123, 0, -63, 2, -124, 0, -62, 2, 4, 0, -61, 2, 4, 0, -60, 2, 4, 0, -59, 2, 4, 0, -69, 2, 7, 0, -58, 2, 7, + 0, -57, 2, 7, 0, -56, 2, -121, 0, 8, 0, 101, 0, 101, 2, -120, 0, -55, 2, -127, 0, -72, 2, 4, 0, -54, 2, 4, 0, -53, 2, 4, + 0, -52, 2, 2, 0, 20, 0, 2, 0, 57, 0, -119, 0, 5, 0, 101, 0, 101, 2, 32, 0, 45, 0, 2, 0, -51, 2, 2, 0, 20, 0, 2, + 0, -50, 2, -118, 0, 5, 0, 101, 0, 101, 2, 4, 0, -49, 2, 2, 0, 20, 0, 2, 0, -48, 2, 7, 0, -47, 2, -117, 0, 3, 0, 101, + 0, 101, 2, -116, 0, -46, 2, 125, 0, -85, 2, -115, 0, 10, 0, 101, 0, 101, 2, 32, 0, -45, 2, 32, 0, -44, 2, 0, 0, -43, 2, 7, + 0, -42, 2, 2, 0, -41, 2, 2, 0, -40, 2, 0, 0, -39, 2, 0, 0, -38, 2, 0, 0, 107, 2, -114, 0, 9, 0, 101, 0, 101, 2, 32, + 0, -37, 2, 0, 0, -43, 2, 7, 0, -36, 2, 7, 0, -35, 2, 0, 0, 13, 1, 0, 0, 122, 2, 0, 0, -34, 2, 0, 0, 37, 0, -113, + 0, 24, 0, 27, 0, 31, 0, 2, 0, -29, 1, 2, 0, -28, 1, 2, 0, -33, 2, 2, 0, 20, 0, 2, 0, -32, 2, 2, 0, -31, 2, 2, + 0, -30, 2, 2, 0, 70, 0, 0, 0, -29, 2, 0, 0, -28, 2, 0, 0, -27, 2, 0, 0, 18, 0, 4, 0, 37, 0, 7, 0, -26, 2, 7, + 0, -25, 2, 7, 0, -24, 2, 7, 0, -23, 2, 7, 0, -22, 2, 7, 0, -21, 2, 34, 0, -20, 2, 36, 0, 79, 0, 38, 0, -9, 1, 80, + 0, 31, 2, -112, 0, 3, 0, -112, 0, 0, 0, -112, 0, 1, 0, 0, 0, 17, 0, 67, 0, 3, 0, 7, 0, -19, 2, 4, 0, 20, 0, 4, + 0, 37, 0, 32, 0, 111, 0, 27, 0, 31, 0, 2, 0, 18, 0, 2, 0, -18, 2, 4, 0, -17, 2, 4, 0, -16, 2, 4, 0, -15, 2, 0, + 0, -14, 2, 32, 0, 38, 0, 32, 0, -13, 2, 32, 0, -12, 2, 32, 0, -11, 2, 32, 0, -10, 2, 36, 0, 79, 0, 73, 0, -10, 1, 67, + 0, -66, 1, -111, 0, -9, 2, -111, 0, -8, 2, -110, 0, -7, 2, 9, 0, 2, 0, 12, 0, -6, 2, 12, 0, 25, 2, 12, 0, -47, 1, 12, + 0, -5, 2, 12, 0, -4, 2, 62, 0, -46, 1, 7, 0, 7, 1, 7, 0, -3, 2, 7, 0, -2, 2, 7, 0, -81, 0, 7, 0, -1, 2, 7, + 0, 8, 1, 7, 0, 0, 3, 7, 0, 1, 3, 7, 0, -93, 2, 7, 0, 2, 3, 7, 0, -45, 0, 4, 0, 3, 3, 2, 0, 20, 0, 2, + 0, 4, 3, 2, 0, 5, 3, 2, 0, 6, 3, 2, 0, 7, 3, 2, 0, 8, 3, 2, 0, 9, 3, 2, 0, 10, 3, 2, 0, 11, 3, 2, + 0, 12, 3, 2, 0, 13, 3, 2, 0, 14, 3, 4, 0, 15, 3, 4, 0, 16, 3, 4, 0, 17, 3, 4, 0, 18, 3, 7, 0, 19, 3, 7, + 0, 20, 3, 7, 0, 21, 3, 7, 0, 22, 3, 7, 0, 23, 3, 7, 0, 24, 3, 7, 0, 25, 3, 7, 0, 26, 3, 7, 0, 27, 3, 7, + 0, 28, 3, 7, 0, 29, 3, 7, 0, 30, 3, 0, 0, 31, 3, 0, 0, 32, 3, 0, 0, -45, 1, 0, 0, 33, 3, 0, 0, 34, 3, 0, + 0, 35, 3, 7, 0, 36, 3, 7, 0, 37, 3, 39, 0, 125, 0, 12, 0, 38, 3, 12, 0, 39, 3, 12, 0, 40, 3, 12, 0, 41, 3, 7, + 0, 42, 3, 2, 0, 71, 2, 2, 0, 43, 3, 7, 0, 52, 2, 4, 0, 44, 3, 4, 0, 45, 3, -109, 0, 46, 3, 2, 0, 47, 3, 2, + 0, -38, 0, 7, 0, 48, 3, 12, 0, 49, 3, 12, 0, 50, 3, 12, 0, 51, 3, 12, 0, 52, 3, -108, 0, 53, 3, -107, 0, 54, 3, 63, + 0, 55, 3, 2, 0, 56, 3, 2, 0, 57, 3, 2, 0, 58, 3, 2, 0, 59, 3, 7, 0, 44, 2, 2, 0, 60, 3, 2, 0, 61, 3, -116, + 0, 62, 3, -127, 0, 63, 3, -127, 0, 64, 3, 4, 0, 65, 3, 4, 0, 66, 3, 4, 0, 67, 3, 4, 0, 70, 0, 9, 0, -94, 0, 12, + 0, 68, 3, -106, 0, 14, 0, -106, 0, 0, 0, -106, 0, 1, 0, 32, 0, 38, 0, 7, 0, -93, 2, 7, 0, 9, 1, 7, 0, -92, 2, 7, + 0, -99, 2, 0, 0, 17, 0, 4, 0, -91, 2, 4, 0, -90, 2, 4, 0, 69, 3, 2, 0, 18, 0, 2, 0, 70, 3, 7, 0, -89, 2, -108, + 0, 36, 0, 2, 0, 71, 3, 2, 0, 72, 3, 2, 0, 20, 0, 2, 0, -99, 2, 7, 0, 73, 3, 7, 0, 74, 3, 7, 0, 75, 3, 7, + 0, 76, 3, 7, 0, 77, 3, 7, 0, 78, 3, 7, 0, 79, 3, 7, 0, 80, 3, 7, 0, 81, 3, 7, 0, 82, 3, 7, 0, 83, 3, 7, + 0, 84, 3, 7, 0, 85, 3, 7, 0, 86, 3, 7, 0, 87, 3, 7, 0, 88, 3, 7, 0, 89, 3, 7, 0, 90, 3, 7, 0, 91, 3, 7, + 0, 92, 3, 7, 0, 93, 3, 7, 0, 94, 3, 7, 0, 95, 3, 7, 0, 96, 3, 2, 0, 97, 3, 2, 0, 98, 3, 2, 0, 99, 3, 2, + 0, 100, 3, 51, 0, -88, 0, -105, 0, 101, 3, 7, 0, 102, 3, 4, 0, 110, 2, 125, 0, 5, 0, 4, 0, 20, 0, 4, 0, 103, 3, 4, + 0, 104, 3, 4, 0, 105, 3, 4, 0, 106, 3, -104, 0, 1, 0, 7, 0, -31, 1, -109, 0, 30, 0, 4, 0, 20, 0, 7, 0, 107, 3, 7, + 0, 108, 3, 7, 0, 109, 3, 4, 0, 110, 3, 4, 0, 111, 3, 4, 0, 112, 3, 4, 0, 113, 3, 7, 0, 114, 3, 7, 0, 115, 3, 7, + 0, 116, 3, 7, 0, 117, 3, 7, 0, 118, 3, 7, 0, 119, 3, 7, 0, 120, 3, 7, 0, 121, 3, 7, 0, 122, 3, 7, 0, 123, 3, 7, + 0, 124, 3, 7, 0, 125, 3, 7, 0, 126, 3, 7, 0, 127, 3, 7, 0, -128, 3, 7, 0, -127, 3, 7, 0, -126, 3, 7, 0, -125, 3, 4, + 0, -124, 3, 4, 0, -123, 3, 7, 0, -122, 3, 7, 0, 27, 3, -107, 0, 49, 0, -120, 0, -121, 3, 4, 0, -120, 3, 4, 0, -119, 3, -103, + 0, -118, 3, -102, 0, -117, 3, 0, 0, 37, 0, 0, 0, -116, 3, 2, 0, -115, 3, 7, 0, -114, 3, 0, 0, -113, 3, 7, 0, -112, 3, 7, + 0, -111, 3, 7, 0, -110, 3, 7, 0, -109, 3, 7, 0, -108, 3, 7, 0, -107, 3, 7, 0, -106, 3, 7, 0, -105, 3, 7, 0, -104, 3, 2, + 0, -103, 3, 0, 0, -102, 3, 2, 0, -101, 3, 7, 0, -100, 3, 7, 0, -99, 3, 0, 0, -98, 3, 4, 0, -126, 0, 4, 0, -97, 3, 4, + 0, -96, 3, 2, 0, -95, 3, 2, 0, -94, 3, -104, 0, -93, 3, 4, 0, -92, 3, 4, 0, 81, 0, 7, 0, -91, 3, 7, 0, -90, 3, 7, + 0, -89, 3, 7, 0, -88, 3, 2, 0, -87, 3, 2, 0, -86, 3, 2, 0, -85, 3, 2, 0, -84, 3, 2, 0, -83, 3, 2, 0, -82, 3, 2, + 0, -81, 3, 2, 0, -80, 3, -101, 0, -79, 3, 7, 0, -78, 3, 7, 0, -77, 3, 125, 0, -76, 3, -116, 0, 48, 0, 2, 0, 18, 0, 2, + 0, -75, 3, 2, 0, -74, 3, 2, 0, -73, 3, 7, 0, -72, 3, 2, 0, -71, 3, 2, 0, -70, 3, 7, 0, -69, 3, 2, 0, -68, 3, 2, + 0, -67, 3, 7, 0, -66, 3, 7, 0, -65, 3, 7, 0, -64, 3, 7, 0, -63, 3, 7, 0, -62, 3, 7, 0, -61, 3, 4, 0, -60, 3, 7, + 0, -59, 3, 7, 0, -58, 3, 7, 0, -57, 3, 74, 0, -56, 3, 74, 0, -55, 3, 74, 0, -54, 3, 0, 0, -53, 3, 7, 0, -52, 3, 7, + 0, -51, 3, 36, 0, 79, 0, 2, 0, -50, 3, 0, 0, -49, 3, 0, 0, -48, 3, 7, 0, -47, 3, 4, 0, -46, 3, 7, 0, -45, 3, 7, + 0, -44, 3, 4, 0, -43, 3, 4, 0, 20, 0, 7, 0, -42, 3, 7, 0, -41, 3, 7, 0, -40, 3, 78, 0, -39, 3, 7, 0, -38, 3, 7, + 0, -37, 3, 7, 0, -36, 3, 7, 0, -35, 3, 7, 0, -34, 3, 7, 0, -33, 3, 7, 0, -32, 3, 4, 0, -31, 3, -100, 0, 71, 0, 27, + 0, 31, 0, 2, 0, -79, 0, 2, 0, 14, 1, 2, 0, 47, 1, 2, 0, -30, 3, 7, 0, -29, 3, 7, 0, -28, 3, 7, 0, -27, 3, 7, + 0, -26, 3, 7, 0, -25, 3, 7, 0, -24, 3, 7, 0, -23, 3, 7, 0, -22, 3, 7, 0, 84, 1, 7, 0, 86, 1, 7, 0, 85, 1, 7, + 0, -21, 3, 4, 0, -20, 3, 7, 0, -19, 3, 7, 0, -18, 3, 7, 0, -17, 3, 7, 0, -16, 3, 7, 0, -15, 3, 7, 0, -14, 3, 7, + 0, -13, 3, 2, 0, -12, 3, 2, 0, 13, 1, 2, 0, -11, 3, 2, 0, -10, 3, 2, 0, -9, 3, 2, 0, -8, 3, 2, 0, -7, 3, 2, + 0, -6, 3, 7, 0, -5, 3, 7, 0, -4, 3, 7, 0, -3, 3, 7, 0, -2, 3, 7, 0, -1, 3, 7, 0, 0, 4, 7, 0, 1, 4, 7, + 0, 2, 4, 7, 0, 3, 4, 7, 0, 4, 4, 7, 0, 5, 4, 7, 0, 6, 4, 2, 0, 7, 4, 2, 0, 8, 4, 2, 0, 9, 4, 2, + 0, 10, 4, 7, 0, 11, 4, 7, 0, 12, 4, 7, 0, 13, 4, 7, 0, 14, 4, 2, 0, 15, 4, 2, 0, 16, 4, 2, 0, 17, 4, 2, + 0, 18, 4, 7, 0, 19, 4, 7, 0, 20, 4, 7, 0, 21, 4, 7, 0, 22, 4, 2, 0, 23, 4, 2, 0, 24, 4, 2, 0, 25, 4, 2, + 0, 43, 0, 7, 0, 26, 4, 7, 0, 27, 4, 36, 0, 79, 0, 50, 0, 77, 1, 30, 0, -103, 0, 39, 0, 125, 0, -99, 0, 16, 0, 2, + 0, 28, 4, 2, 0, 29, 4, 2, 0, 30, 4, 2, 0, 20, 0, 2, 0, 31, 4, 2, 0, 32, 4, 2, 0, 33, 4, 2, 0, 34, 4, 2, + 0, 35, 4, 2, 0, 36, 4, 2, 0, 37, 4, 2, 0, 38, 4, 4, 0, 39, 4, 7, 0, 40, 4, 7, 0, 41, 4, 7, 0, 42, 4, -98, + 0, 8, 0, -98, 0, 0, 0, -98, 0, 1, 0, 4, 0, 3, 3, 4, 0, 43, 4, 4, 0, 20, 0, 2, 0, 44, 4, 2, 0, 45, 4, 32, + 0, -89, 0, -97, 0, 13, 0, 9, 0, 46, 4, 9, 0, 47, 4, 4, 0, 48, 4, 4, 0, 49, 4, 4, 0, 50, 4, 4, 0, 51, 4, 4, + 0, 52, 4, 4, 0, 53, 4, 4, 0, 54, 4, 4, 0, 55, 4, 4, 0, 56, 4, 4, 0, 37, 0, 0, 0, 57, 4, -96, 0, 5, 0, 9, + 0, 58, 4, 9, 0, 59, 4, 4, 0, 60, 4, 4, 0, 70, 0, 0, 0, 61, 4, -95, 0, 13, 0, 4, 0, 18, 0, 4, 0, 62, 4, 4, + 0, 63, 4, 4, 0, 64, 4, 4, 0, 65, 4, 4, 0, 66, 4, 4, 0, 93, 0, 4, 0, 67, 4, 4, 0, 68, 4, 4, 0, 69, 4, 4, + 0, 70, 4, 4, 0, 71, 4, 26, 0, 30, 0, -94, 0, 4, 0, 4, 0, 72, 4, 7, 0, 73, 4, 2, 0, 20, 0, 2, 0, 68, 2, -93, + 0, 11, 0, -93, 0, 0, 0, -93, 0, 1, 0, 0, 0, 17, 0, 62, 0, 74, 4, 63, 0, 75, 4, 4, 0, 3, 3, 4, 0, 76, 4, 4, + 0, 77, 4, 4, 0, 37, 0, 4, 0, 78, 4, 4, 0, 79, 4, -92, 0, -126, 0, -97, 0, 80, 4, -96, 0, 81, 4, -95, 0, 82, 4, 4, + 0, 83, 4, 4, 0, -126, 0, 4, 0, -97, 3, 4, 0, 84, 4, 4, 0, 85, 4, 4, 0, 86, 4, 4, 0, 87, 4, 2, 0, 20, 0, 2, + 0, 88, 4, 7, 0, 20, 3, 7, 0, 89, 4, 7, 0, 90, 4, 7, 0, 91, 4, 7, 0, 92, 4, 7, 0, 93, 4, 2, 0, 94, 4, 2, + 0, 95, 4, 2, 0, 96, 4, 2, 0, 97, 4, 2, 0, -39, 0, 2, 0, 98, 4, 2, 0, 99, 4, 2, 0, 100, 3, 2, 0, 100, 4, 2, + 0, 101, 4, 2, 0, 34, 1, 2, 0, 109, 0, 2, 0, 102, 4, 2, 0, 103, 4, 2, 0, 104, 4, 2, 0, 105, 4, 2, 0, 106, 4, 2, + 0, 107, 4, 2, 0, 108, 4, 2, 0, 109, 4, 2, 0, 110, 4, 2, 0, 35, 1, 2, 0, 111, 4, 2, 0, 112, 4, 2, 0, 113, 4, 2, + 0, 114, 4, 4, 0, 115, 4, 4, 0, 13, 1, 2, 0, 116, 4, 2, 0, 117, 4, 2, 0, 118, 4, 2, 0, 119, 4, 2, 0, 120, 4, 2, + 0, 121, 4, 24, 0, 122, 4, 24, 0, 123, 4, 23, 0, 124, 4, 12, 0, 125, 4, 2, 0, 126, 4, 2, 0, 37, 0, 7, 0, 127, 4, 7, + 0, -128, 4, 7, 0, -127, 4, 7, 0, -126, 4, 7, 0, -125, 4, 7, 0, -124, 4, 7, 0, -123, 4, 7, 0, -122, 4, 7, 0, -121, 4, 2, + 0, -120, 4, 2, 0, -119, 4, 2, 0, -118, 4, 2, 0, -117, 4, 2, 0, -116, 4, 2, 0, -115, 4, 7, 0, -114, 4, 7, 0, -113, 4, 7, + 0, -112, 4, 2, 0, -111, 4, 2, 0, -110, 4, 2, 0, -109, 4, 2, 0, -108, 4, 2, 0, -107, 4, 2, 0, -106, 4, 2, 0, -105, 4, 2, + 0, -104, 4, 2, 0, -103, 4, 2, 0, -102, 4, 4, 0, -101, 4, 4, 0, -100, 4, 4, 0, -99, 4, 4, 0, -98, 4, 4, 0, -97, 4, 7, + 0, -96, 4, 4, 0, -95, 4, 4, 0, -94, 4, 4, 0, -93, 4, 4, 0, -92, 4, 7, 0, -91, 4, 7, 0, -90, 4, 7, 0, -89, 4, 7, + 0, -88, 4, 7, 0, -87, 4, 7, 0, -86, 4, 7, 0, -85, 4, 7, 0, -84, 4, 7, 0, -83, 4, 0, 0, -82, 4, 0, 0, -81, 4, 4, + 0, -80, 4, 2, 0, -79, 4, 2, 0, 12, 1, 0, 0, -78, 4, 7, 0, -77, 4, 7, 0, -76, 4, 4, 0, -75, 4, 4, 0, -74, 4, 7, + 0, -73, 4, 7, 0, -72, 4, 2, 0, -71, 4, 2, 0, -70, 4, 7, 0, -69, 4, 2, 0, -68, 4, 2, 0, -67, 4, 4, 0, -66, 4, 2, + 0, -65, 4, 2, 0, -64, 4, 2, 0, -63, 4, 2, 0, -62, 4, 7, 0, -61, 4, 7, 0, 70, 0, 42, 0, -60, 4, -91, 0, 9, 0, -91, + 0, 0, 0, -91, 0, 1, 0, 0, 0, 17, 0, 2, 0, -59, 4, 2, 0, -58, 4, 2, 0, -57, 4, 2, 0, 43, 0, 7, 0, -56, 4, 7, + 0, 70, 0, -90, 0, 5, 0, 7, 0, -55, 4, 0, 0, 18, 0, 0, 0, 43, 0, 0, 0, 70, 0, 0, 0, 12, 1, -89, 0, 5, 0, -89, + 0, 0, 0, -89, 0, 1, 0, 4, 0, -54, 4, 0, 0, -53, 4, 4, 0, 20, 0, -88, 0, 5, 0, -87, 0, -52, 4, 2, 0, 20, 0, 2, + 0, -51, 4, 2, 0, -50, 4, 2, 0, -49, 4, -86, 0, 4, 0, 2, 0, 109, 0, 2, 0, -122, 2, 2, 0, -48, 4, 2, 0, -47, 4, -85, + 0, 7, 0, 2, 0, 20, 0, 2, 0, -46, 4, 2, 0, -45, 4, 2, 0, -44, 4, -86, 0, -43, 4, 7, 0, -42, 4, 4, 0, -41, 4, -84, + 0, 4, 0, -84, 0, 0, 0, -84, 0, 1, 0, 0, 0, -40, 4, 7, 0, -39, 4, -83, 0, 56, 0, 2, 0, -38, 4, 2, 0, -37, 4, 7, + 0, -36, 4, 7, 0, -35, 4, 2, 0, -48, 4, 2, 0, -34, 4, 7, 0, -33, 4, 7, 0, -32, 4, 2, 0, -31, 4, 2, 0, -30, 4, 2, + 0, -29, 4, 2, 0, -28, 4, 7, 0, -27, 4, 7, 0, -26, 4, 7, 0, -25, 4, 7, 0, 37, 0, 2, 0, -24, 4, 2, 0, -23, 4, 2, + 0, -22, 4, 2, 0, -21, 4, -88, 0, -20, 4, -85, 0, -19, 4, 7, 0, -18, 4, 7, 0, -17, 4, 0, 0, -16, 4, 0, 0, -15, 4, 0, + 0, -14, 4, 0, 0, -13, 4, 0, 0, -12, 4, 0, 0, -11, 4, 2, 0, -10, 4, 7, 0, -9, 4, 7, 0, -8, 4, 7, 0, -7, 4, 7, + 0, -6, 4, 7, 0, -5, 4, 7, 0, -4, 4, 7, 0, -3, 4, 7, 0, -2, 4, 7, 0, -1, 4, 7, 0, 0, 5, 2, 0, 1, 5, 0, + 0, 2, 5, 0, 0, 3, 5, 0, 0, 4, 5, 0, 0, 5, 5, 32, 0, 6, 5, 0, 0, 7, 5, 0, 0, 8, 5, 0, 0, 9, 5, 0, + 0, 10, 5, 0, 0, 11, 5, 0, 0, 12, 5, 0, 0, 13, 5, 0, 0, 14, 5, 0, 0, 15, 5, -82, 0, 6, 0, 2, 0, 109, 0, 0, + 0, -122, 2, 0, 0, 16, 5, 0, 0, 17, 5, 0, 0, 20, 0, 0, 0, -74, 0, -81, 0, 26, 0, -80, 0, 18, 5, 50, 0, 77, 1, 60, + 0, 19, 5, -82, 0, 20, 5, -82, 0, 21, 5, -82, 0, 22, 5, -82, 0, 23, 5, -82, 0, 24, 5, -82, 0, 25, 5, -82, 0, 26, 5, 7, + 0, 27, 5, 2, 0, 28, 5, 2, 0, 47, 1, 2, 0, 29, 5, 2, 0, 1, 2, 0, 0, 30, 5, 0, 0, 31, 5, 0, 0, 32, 5, 0, + 0, 33, 5, 0, 0, 93, 0, 0, 0, 34, 5, 0, 0, 35, 5, 0, 0, 36, 5, 0, 0, 37, 5, 0, 0, 38, 5, 0, 0, -74, 0, -79, + 0, 43, 0, 27, 0, 31, 0, 32, 0, 39, 5, -100, 0, 40, 5, -79, 0, 41, 5, 46, 0, -47, 0, 12, 0, 42, 5, -98, 0, 43, 5, 7, + 0, 44, 5, 7, 0, 45, 5, 7, 0, 46, 5, 7, 0, 47, 5, 4, 0, 3, 3, 7, 0, 48, 5, 2, 0, 49, 5, 2, 0, 50, 5, 2, + 0, 51, 5, 2, 0, 52, 5, 2, 0, 53, 5, 2, 0, 54, 5, 2, 0, 55, 5, 2, 0, 5, 1, 57, 0, 1, 1, 9, 0, 56, 5, -99, + 0, 57, 5, -90, 0, 58, 5, -83, 0, 59, 5, -92, 0, -73, 0, -94, 0, 60, 5, 39, 0, 125, 0, 12, 0, 103, 0, 12, 0, 61, 5, 2, + 0, 62, 5, 2, 0, 63, 5, 2, 0, 64, 5, 2, 0, 65, 5, -78, 0, 66, 5, 2, 0, 67, 5, 2, 0, 68, 5, 2, 0, 64, 1, 2, + 0, -38, 0, -81, 0, 69, 5, 4, 0, 70, 5, 4, 0, 37, 0, -77, 0, 9, 0, 46, 0, -47, 0, 45, 0, 0, 1, 7, 0, 8, 2, 7, + 0, 9, 2, 7, 0, 109, 0, 7, 0, 71, 5, 7, 0, 72, 5, 2, 0, 73, 5, 2, 0, 74, 5, -76, 0, 75, 0, -75, 0, 0, 0, -75, + 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, 2, 0, 78, 5, 7, 0, 79, 5, 7, 0, 80, 5, 7, 0, 81, 5, 7, + 0, 82, 5, 7, 0, 83, 5, 7, 0, 84, 5, 7, 0, 85, 5, 7, 0, 20, 1, 7, 0, 86, 5, 4, 0, 87, 5, 2, 0, 88, 5, 2, + 0, 17, 5, 32, 0, 39, 5, 32, 0, 89, 5, -77, 0, 90, 5, -76, 0, 91, 5, -73, 0, 92, 5, -72, 0, 93, 5, -71, 0, 94, 5, 0, + 0, 95, 5, 2, 0, 30, 4, 2, 0, 96, 5, 4, 0, 3, 3, 4, 0, 97, 5, 2, 0, 98, 5, 2, 0, 99, 5, 2, 0, 100, 5, 0, + 0, 101, 5, 0, 0, 43, 0, 7, 0, 115, 0, 7, 0, 102, 5, 7, 0, 103, 5, 7, 0, 104, 5, 7, 0, 105, 5, 7, 0, 106, 5, 7, + 0, 107, 5, 7, 0, 108, 5, 7, 0, -82, 0, 7, 0, 44, 5, 2, 0, 109, 5, 2, 0, 110, 5, 2, 0, 111, 5, 2, 0, 112, 5, 2, + 0, -119, 0, 2, 0, 29, 5, 2, 0, 113, 5, 2, 0, 114, 5, 2, 0, 115, 5, 2, 0, 116, 5, 7, 0, 117, 5, 7, 0, 118, 5, 67, + 0, 119, 5, 12, 0, 120, 5, 2, 0, 121, 5, 2, 0, 53, 2, 2, 0, 122, 5, 2, 0, 20, 0, 2, 0, 123, 5, 2, 0, 124, 5, 2, + 0, 125, 5, 0, 0, 126, 5, 0, 0, 127, 5, 9, 0, -128, 5, -70, 0, -127, 5, 7, 0, -126, 5, 2, 0, -125, 5, 2, 0, -124, 5, 2, + 0, 53, 5, 2, 0, 54, 5, -69, 0, 19, 0, 24, 0, 36, 0, 24, 0, 64, 0, 23, 0, -123, 5, 23, 0, -122, 5, 23, 0, -121, 5, 7, + 0, -120, 5, 7, 0, -119, 5, 7, 0, -118, 5, 7, 0, -117, 5, 2, 0, -116, 5, 2, 0, -115, 5, 2, 0, -114, 5, 2, 0, -113, 5, 2, + 0, -112, 5, 2, 0, -111, 5, 4, 0, 20, 0, 7, 0, -110, 5, 2, 0, 99, 5, 0, 0, 107, 2, -75, 0, 6, 0, -75, 0, 0, 0, -75, + 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, 2, 0, 78, 5, -68, 0, 6, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, + 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, 2, 0, 78, 5, -67, 0, 27, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, + 0, 76, 5, -74, 0, 77, 5, 2, 0, 78, 5, 4, 0, -109, 5, 4, 0, 70, 0, -69, 0, -108, 5, 9, 0, -107, 5, 12, 0, -106, 5, 36, + 0, 79, 0, 27, 0, 80, 0, 0, 0, -105, 5, 0, 0, -104, 5, 0, 0, -103, 5, 2, 0, -102, 5, 2, 0, -101, 5, 2, 0, -100, 5, 2, + 0, -99, 5, 2, 0, 65, 0, 2, 0, 46, 0, 2, 0, -119, 0, 2, 0, -98, 5, 4, 0, 20, 0, 7, 0, -97, 5, 24, 0, 36, 0, -66, + 0, 29, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, -73, 0, 92, 5, 2, 0, 78, 5, 2, + 0, -96, 5, 2, 0, -95, 5, 2, 0, -94, 5, 2, 0, -93, 5, -69, 0, -108, 5, 2, 0, -92, 5, 2, 0, -119, 0, 2, 0, -101, 5, 2, + 0, -91, 5, 9, 0, -90, 5, 2, 0, 29, 5, 0, 0, -89, 5, 0, 0, -88, 5, 2, 0, -87, 5, 2, 0, -86, 5, 2, 0, 12, 3, 2, + 0, -85, 5, 2, 0, -84, 5, 0, 0, 37, 0, 0, 0, 20, 0, 0, 0, 47, 1, 0, 0, -83, 5, -65, 0, 16, 0, -75, 0, 0, 0, -75, + 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, 2, 0, 78, 5, -69, 0, -108, 5, 7, 0, 8, 2, 7, 0, 9, 2, 2, + 0, -92, 5, 2, 0, -82, 5, 2, 0, -81, 5, 2, 0, -80, 5, 4, 0, 20, 0, 7, 0, 71, 5, -70, 0, -127, 5, -64, 0, 33, 0, -75, + 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, 2, 0, 78, 5, -63, 0, -79, 5, 4, 0, -78, 5, 0, + 0, -77, 5, 0, 0, -76, 5, 0, 0, -75, 5, 2, 0, 18, 0, 2, 0, -74, 5, 2, 0, 20, 0, 2, 0, -73, 5, 2, 0, -72, 5, 2, + 0, -71, 5, 2, 0, -70, 5, 2, 0, 43, 0, 4, 0, 70, 0, 0, 0, -69, 5, -62, 0, -68, 5, 2, 0, -67, 5, 2, 0, -66, 5, 2, + 0, -65, 5, 2, 0, -48, 0, 9, 0, -64, 5, 9, 0, -63, 5, 9, 0, -62, 5, 9, 0, -61, 5, 9, 0, -60, 5, 2, 0, -59, 5, 0, + 0, -58, 5, -61, 0, 23, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, 2, 0, 78, 5, -69, + 0, -108, 5, 12, 0, -57, 5, 2, 0, -101, 5, 2, 0, -56, 5, 2, 0, 20, 0, 2, 0, 57, 0, 9, 0, -90, 5, 12, 0, -55, 5, -60, + 0, -54, 5, 0, 0, -53, 5, -59, 0, -52, 5, 4, 0, -51, 5, 4, 0, -50, 5, 2, 0, 18, 0, 2, 0, -49, 5, 2, 0, -48, 5, 2, + 0, -47, 5, -58, 0, 29, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, 2, 0, 78, 5, -69, + 0, -108, 5, 46, 0, -114, 2, 45, 0, 0, 1, 60, 0, 19, 5, 2, 0, 13, 1, 2, 0, -119, 0, 2, 0, -46, 5, 2, 0, -45, 5, 4, + 0, 20, 0, 2, 0, 49, 5, 2, 0, -44, 5, 2, 0, -98, 5, 2, 0, -101, 5, 7, 0, 71, 5, 0, 0, -43, 5, 0, 0, -42, 5, 0, + 0, -41, 5, 0, 0, -40, 5, 7, 0, 8, 2, 7, 0, 9, 2, 7, 0, -39, 5, 7, 0, -38, 5, -70, 0, -127, 5, -57, 0, 11, 0, -75, + 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, 2, 0, 78, 5, 2, 0, -119, 0, 2, 0, -98, 5, 2, + 0, -37, 5, 2, 0, 20, 0, -69, 0, -108, 5, -56, 0, 24, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, + 0, 77, 5, 2, 0, 78, 5, 42, 0, -36, 5, 4, 0, -35, 5, 4, 0, -34, 5, 2, 0, 93, 0, 2, 0, -119, 0, 4, 0, -33, 5, 4, + 0, -32, 5, 4, 0, -31, 5, 4, 0, -30, 5, 4, 0, -29, 5, 4, 0, -28, 5, 4, 0, -27, 5, 4, 0, -26, 5, 7, 0, -25, 5, 23, + 0, -24, 5, 23, 0, -23, 5, 4, 0, -22, 5, 4, 0, -21, 5, -55, 0, 10, 0, 27, 0, 31, 0, 9, 0, -20, 5, 9, 0, -19, 5, 9, + 0, -18, 5, 9, 0, -17, 5, 9, 0, -16, 5, 4, 0, 93, 0, 4, 0, -15, 5, 0, 0, -14, 5, 0, 0, -13, 5, -54, 0, 10, 0, -75, + 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, -55, 0, -12, 5, 2, 0, 93, 0, 2, 0, -119, 0, 4, + 0, 43, 0, 9, 0, -11, 5, -53, 0, 8, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, -69, + 0, -108, 5, 4, 0, 20, 0, 4, 0, -10, 5, -52, 0, 21, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, + 0, 77, 5, 2, 0, 78, 5, -69, 0, -108, 5, 27, 0, -9, 5, 27, 0, 80, 0, 2, 0, 20, 0, 2, 0, -119, 0, 7, 0, -8, 5, 9, + 0, -7, 5, 7, 0, 8, 2, 7, 0, 9, 2, 57, 0, 1, 1, 57, 0, -6, 5, 4, 0, -5, 5, 2, 0, -89, 5, 2, 0, 37, 0, -70, + 0, -127, 5, -51, 0, 42, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, 2, 0, 78, 5, -69, + 0, -108, 5, -50, 0, -4, 5, 0, 0, -77, 5, 0, 0, -76, 5, 0, 0, -75, 5, 2, 0, 18, 0, 2, 0, -66, 5, 2, 0, 20, 0, 2, + 0, -73, 5, 9, 0, -7, 5, 4, 0, -3, 5, 4, 0, -2, 5, 4, 0, -1, 5, 4, 0, 0, 6, 23, 0, 1, 6, 23, 0, 2, 6, 7, + 0, 3, 6, 7, 0, 4, 6, 7, 0, 5, 6, 7, 0, -8, 5, 2, 0, -67, 5, 2, 0, -48, 0, 2, 0, 102, 1, 2, 0, 6, 6, 2, + 0, 37, 0, 2, 0, 43, 0, 2, 0, 7, 6, 2, 0, 8, 6, 9, 0, -64, 5, 9, 0, -63, 5, 9, 0, -62, 5, 9, 0, -61, 5, 9, + 0, -60, 5, 2, 0, -59, 5, 0, 0, -58, 5, 56, 0, 9, 6, -49, 0, 20, 0, 0, 0, 10, 6, 0, 0, 11, 6, 0, 0, 12, 6, 0, + 0, 13, 6, 0, 0, 14, 6, 0, 0, 15, 6, 0, 0, 16, 6, 0, 0, 17, 6, 0, 0, 18, 6, 0, 0, 19, 6, 0, 0, 20, 6, 0, + 0, 21, 6, 0, 0, 22, 6, 0, 0, 23, 6, 0, 0, 24, 6, 0, 0, 25, 6, 0, 0, 26, 6, 0, 0, 27, 6, 0, 0, 68, 2, 0, + 0, 28, 6, -48, 0, 54, 0, 0, 0, 29, 6, 0, 0, 20, 6, 0, 0, 21, 6, 0, 0, 30, 6, 0, 0, 31, 6, 0, 0, 32, 6, 0, + 0, 33, 6, 0, 0, 34, 6, 0, 0, 35, 6, 0, 0, 36, 6, 0, 0, 37, 6, 0, 0, 38, 6, 0, 0, 39, 6, 0, 0, 40, 6, 0, + 0, 41, 6, 0, 0, 42, 6, 0, 0, 43, 6, 0, 0, 44, 6, 0, 0, 45, 6, 0, 0, 46, 6, 0, 0, 47, 6, 0, 0, 48, 6, 0, + 0, 49, 6, 0, 0, 50, 6, 0, 0, 51, 6, 0, 0, 52, 6, 0, 0, 53, 6, 0, 0, 54, 6, 0, 0, 55, 6, 0, 0, 56, 6, 0, + 0, 57, 6, 0, 0, 58, 6, 0, 0, 95, 0, 0, 0, 59, 6, 0, 0, 60, 6, 0, 0, 61, 6, 0, 0, 62, 6, 0, 0, 63, 6, 0, + 0, 64, 6, 0, 0, 65, 6, 0, 0, 66, 6, 0, 0, 67, 6, 0, 0, 68, 6, 0, 0, 69, 6, 0, 0, 70, 6, 0, 0, 71, 6, 0, + 0, 72, 6, 0, 0, 73, 6, 0, 0, 74, 6, 0, 0, 75, 6, 0, 0, 76, 6, 0, 0, 77, 6, 0, 0, 78, 6, 0, 0, 79, 6, -47, + 0, 5, 0, 0, 0, 80, 6, 0, 0, 37, 6, 0, 0, 39, 6, 2, 0, 20, 0, 2, 0, 37, 0, -46, 0, 22, 0, -46, 0, 0, 0, -46, + 0, 1, 0, 0, 0, 17, 0, -49, 0, 81, 6, -48, 0, 82, 6, -48, 0, 83, 6, -48, 0, 84, 6, -48, 0, 85, 6, -48, 0, 86, 6, -48, + 0, 87, 6, -48, 0, 88, 6, -48, 0, 89, 6, -48, 0, 90, 6, -48, 0, 91, 6, -48, 0, 92, 6, -48, 0, 93, 6, -48, 0, 94, 6, -48, + 0, 95, 6, -48, 0, 96, 6, -47, 0, 97, 6, 0, 0, 98, 6, 0, 0, 99, 6, -45, 0, 5, 0, 4, 0, 20, 0, 4, 0, 37, 0, 7, + 0, 52, 2, 7, 0, 100, 6, 7, 0, -31, 1, -44, 0, 66, 0, 4, 0, 20, 0, 4, 0, 101, 6, 4, 0, 102, 6, 0, 0, 103, 6, 0, + 0, 104, 6, 0, 0, 105, 6, 0, 0, 106, 6, 0, 0, 107, 6, 0, 0, 108, 6, 0, 0, 109, 6, 0, 0, 110, 6, 0, 0, 111, 6, 2, + 0, 112, 6, 2, 0, 113, 6, 4, 0, 114, 6, 4, 0, 115, 6, 4, 0, 116, 6, 4, 0, 117, 6, 2, 0, 118, 6, 2, 0, 119, 6, 2, + 0, 120, 6, 2, 0, 121, 6, 4, 0, 122, 6, 4, 0, 123, 6, 2, 0, 124, 6, 2, 0, 125, 6, 2, 0, 126, 6, 2, 0, 127, 6, 0, + 0, -128, 6, 12, 0, -127, 6, 2, 0, -126, 6, 2, 0, -125, 6, 2, 0, -124, 6, 2, 0, -123, 6, 2, 0, -122, 6, 2, 0, -121, 6, 2, + 0, -120, 6, 2, 0, -119, 6, -45, 0, -118, 6, 2, 0, -117, 6, 2, 0, -116, 6, 2, 0, -115, 6, 2, 0, -114, 6, 4, 0, -113, 6, 4, + 0, -112, 6, 4, 0, -111, 6, 4, 0, -110, 6, 2, 0, -109, 6, 2, 0, -108, 6, 2, 0, -107, 6, 2, 0, -106, 6, 2, 0, -105, 6, 2, + 0, -104, 6, 2, 0, -103, 6, 2, 0, -102, 6, 2, 0, -101, 6, 2, 0, -100, 6, 2, 0, -99, 6, 2, 0, 37, 0, 0, 0, -98, 6, 0, + 0, -97, 6, 0, 0, -96, 6, 7, 0, -95, 6, 2, 0, 55, 5, 2, 0, -94, 6, 54, 0, -93, 6, -43, 0, 18, 0, 27, 0, 31, 0, 12, + 0, -92, 6, 12, 0, -91, 6, 12, 0, -90, 6, -79, 0, -89, 6, 2, 0, -105, 2, 2, 0, -88, 6, 2, 0, -104, 2, 2, 0, -87, 6, 2, + 0, -86, 6, 2, 0, -85, 6, 2, 0, -84, 6, 2, 0, -83, 6, 2, 0, -82, 6, 2, 0, 37, 0, 2, 0, -81, 6, 2, 0, -80, 6, 2, + 0, -79, 6, -42, 0, 5, 0, -42, 0, 0, 0, -42, 0, 1, 0, -42, 0, -78, 6, 13, 0, -77, 6, 4, 0, 20, 0, -41, 0, 7, 0, -41, + 0, 0, 0, -41, 0, 1, 0, -42, 0, -76, 6, -42, 0, -75, 6, 2, 0, 123, 4, 2, 0, 20, 0, 4, 0, 37, 0, -40, 0, 17, 0, -40, + 0, 0, 0, -40, 0, 1, 0, 0, 0, -74, 6, 0, 0, -73, 6, 0, 0, -72, 6, 2, 0, -71, 6, 2, 0, -70, 6, 2, 0, -86, 6, 2, + 0, -85, 6, 2, 0, 20, 0, 2, 0, 70, 3, 2, 0, -69, 6, 2, 0, -68, 6, 2, 0, -67, 6, 2, 0, -66, 6, 4, 0, -65, 6, -40, + 0, -64, 6, -74, 0, 30, 0, -74, 0, 0, 0, -74, 0, 1, 0, -42, 0, -76, 6, -42, 0, -75, 6, -42, 0, -63, 6, -42, 0, -62, 6, -43, + 0, -61, 6, 7, 0, -60, 6, 23, 0, 52, 0, 23, 0, -59, 6, 23, 0, -58, 6, 2, 0, -57, 6, 2, 0, -56, 6, 2, 0, -55, 6, 0, + 0, 75, 5, 0, 0, -54, 6, 2, 0, -53, 6, 2, 0, -52, 6, 0, 0, -51, 6, 0, 0, -50, 6, 0, 0, -49, 6, 0, 0, -48, 6, 2, + 0, -47, 6, 2, 0, -46, 6, 2, 0, -45, 6, 2, 0, 20, 0, 39, 0, 125, 0, 12, 0, -44, 6, 12, 0, -43, 6, 12, 0, -42, 6, -39, + 0, 11, 0, 0, 0, -41, 6, 2, 0, -40, 6, 2, 0, -39, 6, 2, 0, -38, 6, 2, 0, -37, 6, 2, 0, -36, 6, 2, 0, 107, 4, 9, + 0, -35, 6, 9, 0, -34, 6, 4, 0, -33, 6, 4, 0, -32, 6, -38, 0, 1, 0, 0, 0, -31, 6, -37, 0, 8, 0, 56, 0, -30, 6, 56, + 0, -29, 6, -37, 0, -28, 6, -37, 0, -27, 6, -37, 0, -26, 6, 2, 0, -123, 0, 2, 0, 20, 0, 4, 0, -25, 6, -36, 0, 4, 0, 4, + 0, -35, 5, 4, 0, -24, 6, 4, 0, -31, 5, 4, 0, -23, 6, -35, 0, 2, 0, 4, 0, -22, 6, 4, 0, -21, 6, -34, 0, 9, 0, 7, + 0, -20, 6, 7, 0, -19, 6, 7, 0, -18, 6, 4, 0, 20, 0, 4, 0, 13, 1, 7, 0, -19, 3, 7, 0, -17, 6, 4, 0, 37, 0, -33, + 0, -16, 6, -32, 0, 6, 0, 0, 0, -15, 6, 0, 0, -75, 5, 48, 0, -116, 0, 2, 0, 109, 0, 2, 0, 111, 4, 4, 0, 37, 0, -31, + 0, 21, 0, -31, 0, 0, 0, -31, 0, 1, 0, 4, 0, 57, 0, 4, 0, 23, 0, 4, 0, 28, 0, 4, 0, -14, 6, 4, 0, -13, 6, 4, + 0, -12, 6, -38, 0, -11, 6, 0, 0, -15, 6, 4, 0, -10, 6, 4, 0, -9, 6, -32, 0, -12, 2, -36, 0, -8, 6, -35, 0, -7, 6, -34, + 0, -6, 6, -37, 0, -5, 6, -37, 0, -4, 6, -37, 0, -3, 6, 56, 0, -2, 6, 56, 0, -1, 6, -30, 0, 12, 0, 0, 0, -68, 1, 9, + 0, -62, 0, 0, 0, -61, 0, 4, 0, -58, 0, 4, 0, -50, 0, 9, 0, -57, 0, 7, 0, -55, 0, 7, 0, -54, 0, 9, 0, 0, 7, 9, + 0, 1, 7, 9, 0, -53, 0, 9, 0, -51, 0, -29, 0, 43, 0, -29, 0, 0, 0, -29, 0, 1, 0, 9, 0, 2, 7, 9, 0, 26, 0, 0, + 0, 27, 0, 4, 0, 20, 0, 4, 0, 18, 0, 4, 0, 23, 0, 4, 0, 91, 0, 4, 0, 3, 7, 4, 0, 4, 7, 4, 0, -13, 6, 4, + 0, -12, 6, 4, 0, 5, 7, 4, 0, -39, 0, 4, 0, 6, 7, 4, 0, 7, 7, 7, 0, 8, 7, 7, 0, 9, 7, 4, 0, -126, 0, 4, + 0, 10, 7, -31, 0, 11, 7, 36, 0, 79, 0, -79, 0, -89, 6, 48, 0, -116, 0, 7, 0, 12, 7, 7, 0, 13, 7, -30, 0, 2, 1, -29, + 0, 14, 7, -29, 0, 15, 7, -29, 0, 16, 7, 12, 0, 17, 7, -28, 0, 18, 7, -27, 0, 19, 7, 7, 0, 20, 7, 7, 0, 21, 7, 4, + 0, -84, 6, 7, 0, 22, 7, 9, 0, 23, 7, 4, 0, 24, 7, 4, 0, 25, 7, 4, 0, 26, 7, 7, 0, 27, 7, -26, 0, 4, 0, -26, + 0, 0, 0, -26, 0, 1, 0, 12, 0, 28, 7, -29, 0, 29, 7, -25, 0, 6, 0, 12, 0, 30, 7, 12, 0, 17, 7, 12, 0, 31, 7, 2, + 0, 20, 0, 2, 0, 37, 0, 4, 0, 57, 0, -24, 0, 4, 0, 7, 0, 32, 7, 7, 0, 112, 0, 2, 0, 33, 7, 2, 0, 34, 7, -23, + 0, 6, 0, 7, 0, 35, 7, 7, 0, 36, 7, 7, 0, 37, 7, 7, 0, 38, 7, 4, 0, 39, 7, 4, 0, 40, 7, -22, 0, 12, 0, 7, + 0, 41, 7, 7, 0, 42, 7, 7, 0, 43, 7, 7, 0, 44, 7, 7, 0, 45, 7, 7, 0, 46, 7, 7, 0, 47, 7, 7, 0, 48, 7, 7, + 0, 49, 7, 7, 0, 50, 7, 4, 0, -110, 2, 4, 0, 51, 7, -21, 0, 2, 0, 7, 0, -55, 4, 7, 0, 37, 0, -20, 0, 7, 0, 7, + 0, 52, 7, 7, 0, 53, 7, 4, 0, 93, 0, 4, 0, 108, 2, 4, 0, 54, 7, 4, 0, 55, 7, 4, 0, 37, 0, -19, 0, 6, 0, -19, + 0, 0, 0, -19, 0, 1, 0, 2, 0, 18, 0, 2, 0, 20, 0, 2, 0, 56, 7, 2, 0, 57, 0, -18, 0, 8, 0, -18, 0, 0, 0, -18, + 0, 1, 0, 2, 0, 18, 0, 2, 0, 20, 0, 2, 0, 56, 7, 2, 0, 57, 0, 7, 0, 23, 0, 7, 0, -126, 0, -17, 0, 45, 0, -17, + 0, 0, 0, -17, 0, 1, 0, 2, 0, 18, 0, 2, 0, 20, 0, 2, 0, 56, 7, 2, 0, -43, 0, 2, 0, -103, 3, 2, 0, 57, 7, 7, + 0, 58, 7, 7, 0, 92, 0, 7, 0, -97, 2, 4, 0, 59, 7, 4, 0, 81, 0, 4, 0, 110, 2, 7, 0, 60, 7, 7, 0, 61, 7, 7, + 0, 62, 7, 7, 0, 63, 7, 7, 0, 64, 7, 7, 0, 65, 7, 7, 0, -100, 2, 7, 0, -1, 0, 7, 0, 66, 7, 7, 0, 67, 7, 7, + 0, 37, 0, 7, 0, 68, 7, 7, 0, 69, 7, 7, 0, 70, 7, 2, 0, 71, 7, 2, 0, 72, 7, 2, 0, 73, 7, 2, 0, 74, 7, 2, + 0, 75, 7, 2, 0, 76, 7, 2, 0, 77, 7, 2, 0, 78, 7, 2, 0, 123, 5, 2, 0, 79, 7, 2, 0, -47, 1, 2, 0, 80, 7, 0, + 0, 81, 7, 0, 0, 82, 7, 7, 0, -45, 0, -16, 0, 83, 7, 63, 0, -95, 1, -15, 0, 16, 0, -15, 0, 0, 0, -15, 0, 1, 0, 2, + 0, 18, 0, 2, 0, 20, 0, 2, 0, 56, 7, 2, 0, -43, 0, 7, 0, -105, 2, 7, 0, -104, 2, 7, 0, -103, 2, 7, 0, -5, 1, 7, + 0, -102, 2, 7, 0, -101, 2, 7, 0, 84, 7, 7, 0, -100, 2, 7, 0, -98, 2, 7, 0, -97, 2, -59, 0, 5, 0, 2, 0, 18, 0, 2, + 0, -25, 6, 2, 0, 20, 0, 2, 0, 85, 7, 27, 0, -9, 5, -60, 0, 3, 0, 4, 0, 69, 0, 4, 0, 86, 7, -59, 0, 2, 0, -14, + 0, 12, 0, -14, 0, 0, 0, -14, 0, 1, 0, 2, 0, 18, 0, 2, 0, 20, 0, 2, 0, 31, 3, 2, 0, -32, 1, 7, 0, 5, 0, 7, + 0, 6, 0, 7, 0, 87, 7, 7, 0, 88, 7, 27, 0, -9, 5, 12, 0, 89, 7, -13, 0, 11, 0, -13, 0, 0, 0, -13, 0, 1, 0, 0, + 0, 17, 0, 2, 0, 18, 0, 2, 0, 90, 7, 4, 0, 22, 0, 4, 0, 91, 7, 2, 0, 20, 0, 2, 0, 37, 0, 9, 0, 92, 7, 9, + 0, 93, 7, -12, 0, 5, 0, 0, 0, 17, 0, 7, 0, 20, 1, 7, 0, 94, 7, 4, 0, 95, 7, 4, 0, 37, 0, -11, 0, 4, 0, 2, + 0, 18, 0, 2, 0, 20, 0, 2, 0, 43, 0, 2, 0, 70, 0, -10, 0, 4, 0, 0, 0, 17, 0, 62, 0, 96, 7, 7, 0, 20, 1, 7, + 0, 37, 0, -9, 0, 6, 0, 2, 0, 97, 7, 2, 0, 98, 7, 2, 0, 18, 0, 2, 0, 99, 7, 0, 0, 100, 7, 0, 0, 101, 7, -8, + 0, 5, 0, 4, 0, 18, 0, 4, 0, 37, 0, 0, 0, 17, 0, 0, 0, 102, 7, 0, 0, 103, 7, -7, 0, 3, 0, 4, 0, 18, 0, 4, + 0, 37, 0, 0, 0, 17, 0, -6, 0, 4, 0, 2, 0, 104, 7, 2, 0, 105, 7, 2, 0, 20, 0, 2, 0, 37, 0, -5, 0, 6, 0, 0, + 0, 17, 0, 0, 0, 106, 7, 2, 0, 107, 7, 2, 0, -100, 2, 2, 0, 13, 1, 2, 0, 70, 0, -4, 0, 5, 0, 0, 0, 17, 0, 7, + 0, 112, 0, 7, 0, -17, 3, 2, 0, 20, 0, 2, 0, 122, 2, -3, 0, 3, 0, 0, 0, 17, 0, 4, 0, 110, 2, 4, 0, 104, 7, -2, + 0, 7, 0, 0, 0, 17, 0, 7, 0, -17, 3, 0, 0, 108, 7, 0, 0, 109, 7, 2, 0, 13, 1, 2, 0, 43, 0, 4, 0, 110, 7, -1, + 0, 3, 0, 32, 0, 111, 7, 0, 0, 112, 7, 0, 0, 113, 7, 0, 1, 18, 0, 0, 1, 0, 0, 0, 1, 1, 0, 2, 0, 18, 0, 2, + 0, 90, 7, 2, 0, 20, 0, 2, 0, 114, 7, 2, 0, 115, 7, 2, 0, 116, 7, 2, 0, 43, 0, 2, 0, 70, 0, 0, 0, 17, 0, 9, + 0, 2, 0, 1, 1, 117, 7, 32, 0, 45, 0, 2, 0, -47, 4, 2, 0, 20, 7, 2, 0, 118, 7, 2, 0, 37, 0, 2, 1, 11, 0, 0, + 0, 17, 0, 0, 0, 18, 0, 0, 0, 119, 7, 2, 0, 20, 0, 2, 0, 122, 2, 2, 0, 120, 7, 4, 0, 121, 7, 4, 0, 122, 7, 4, + 0, 123, 7, 4, 0, 124, 7, 4, 0, 125, 7, 3, 1, 1, 0, 0, 0, 126, 7, 4, 1, 4, 0, 42, 0, -36, 5, 0, 0, 127, 7, 4, + 0, 13, 1, 4, 0, 20, 0, 1, 1, 18, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1, 1, -128, 7, 2, 0, 18, 0, 2, 0, 20, 0, 2, + 0, -127, 7, 2, 0, 116, 7, 2, 0, 90, 7, 2, 0, -126, 7, 2, 0, 70, 0, 2, 0, 12, 1, 0, 0, 17, 0, 9, 0, 2, 0, 5, + 1, 117, 7, 0, 1, -125, 7, 2, 0, 15, 0, 2, 0, -124, 7, 4, 0, -123, 7, 6, 1, 3, 0, 4, 0, -74, 2, 4, 0, 37, 0, 32, + 0, 45, 0, 7, 1, 12, 0, -111, 0, -122, 7, 2, 0, 18, 0, 2, 0, 20, 0, 4, 0, 58, 7, 4, 0, 92, 0, 0, 0, 17, 0, 0, + 0, -121, 7, 2, 0, -120, 7, 2, 0, -119, 7, 2, 0, -118, 7, 2, 0, -117, 7, 7, 0, -116, 7, 8, 1, 10, 0, 2, 0, 20, 0, 2, + 0, -115, 7, 4, 0, 58, 7, 4, 0, 92, 0, 2, 0, -114, 7, -28, 0, 18, 7, 2, 0, 18, 0, 2, 0, -113, 7, 2, 0, -112, 7, 2, + 0, -111, 7, 9, 1, 7, 0, 2, 0, 20, 0, 2, 0, -115, 7, 4, 0, 58, 7, 4, 0, 92, 0, 2, 0, 18, 0, 2, 0, -110, 7, 7, + 0, 109, 3, 10, 1, 11, 0, 4, 0, -74, 2, 2, 0, 18, 0, 2, 0, 20, 0, 32, 0, 45, 0, 74, 0, -109, 7, 0, 0, 17, 0, 7, + 0, -108, 7, 7, 0, -107, 7, 7, 0, 21, 3, 2, 0, -106, 7, 2, 0, -105, 7, 11, 1, 5, 0, 2, 0, 18, 0, 2, 0, 20, 0, 4, + 0, 37, 0, -79, 0, -89, 6, 32, 0, 39, 5, 12, 1, 5, 0, 4, 0, 20, 0, 4, 0, 18, 0, 0, 0, 17, 0, 0, 0, 102, 7, 32, + 0, 45, 0, 13, 1, 13, 0, 2, 0, 20, 0, 2, 0, 18, 0, 2, 0, 90, 7, 2, 0, 22, 3, 7, 0, -104, 7, 7, 0, -103, 7, 7, + 0, 7, 1, 7, 0, 8, 1, 7, 0, -3, 2, 7, 0, 0, 3, 7, 0, -102, 7, 7, 0, -101, 7, 32, 0, -100, 7, 14, 1, 10, 0, 2, + 0, 20, 0, 2, 0, 18, 0, 4, 0, 58, 7, 4, 0, 92, 0, 0, 0, 17, 0, 0, 0, -121, 7, 2, 0, 43, 0, 2, 0, 64, 0, 2, + 0, -99, 7, 2, 0, -98, 7, 15, 1, 8, 0, 32, 0, 45, 0, 7, 0, -103, 2, 7, 0, -97, 7, 7, 0, -96, 7, 7, 0, -108, 2, 2, + 0, 20, 0, 2, 0, 122, 2, 7, 0, -95, 7, 16, 1, 12, 0, 2, 0, 18, 0, 2, 0, 13, 1, 2, 0, 20, 0, 2, 0, -100, 2, 2, + 0, -74, 2, 2, 0, -94, 7, 4, 0, 37, 0, 7, 0, -93, 7, 7, 0, -92, 7, 7, 0, -91, 7, 7, 0, -90, 7, 0, 0, -89, 7, 17, + 1, 10, 0, 2, 0, 20, 0, 2, 0, 18, 0, 4, 0, 58, 7, 4, 0, 92, 0, 0, 0, 17, 0, 2, 0, 68, 2, 2, 0, 64, 0, 2, + 0, -99, 7, 2, 0, -98, 7, 63, 0, -95, 1, 18, 1, 7, 0, 4, 0, 110, 2, 4, 0, -88, 7, 4, 0, -87, 7, 4, 0, -86, 7, 7, + 0, -85, 7, 7, 0, -84, 7, 0, 0, 108, 7, 19, 1, 7, 0, 0, 0, -83, 7, 32, 0, -82, 7, 0, 0, 112, 7, 2, 0, -81, 7, 2, + 0, 43, 0, 4, 0, 70, 0, 0, 0, 113, 7, 20, 1, 6, 0, 2, 0, 20, 0, 2, 0, 18, 0, 4, 0, 58, 7, 4, 0, 92, 0, 0, + 0, -80, 7, 0, 0, -79, 7, 21, 1, 1, 0, 4, 0, 20, 0, 22, 1, 6, 0, 0, 0, 95, 0, 2, 0, 18, 0, 2, 0, 20, 0, 4, + 0, -78, 7, 7, 0, -77, 7, 42, 0, -36, 5, 23, 1, 4, 0, 0, 0, -74, 0, 2, 0, 20, 0, 4, 0, 18, 0, 32, 0, 45, 0, 24, + 1, 2, 0, 4, 0, 18, 0, 4, 0, -121, 5, 5, 1, 10, 0, 5, 1, 0, 0, 5, 1, 1, 0, 5, 1, -128, 7, 2, 0, 18, 0, 2, + 0, 20, 0, 2, 0, 90, 7, 2, 0, -76, 7, 0, 0, 17, 0, 9, 0, 2, 0, 32, 0, 45, 0, 25, 1, 10, 0, 7, 0, 21, 3, 7, + 0, -75, 7, 7, 0, -74, 7, 7, 0, -73, 7, 7, 0, -72, 7, 4, 0, 20, 0, 7, 0, -94, 7, 7, 0, -71, 7, 7, 0, -70, 7, 7, + 0, 37, 0, -28, 0, 20, 0, 27, 0, 31, 0, 0, 0, -63, 0, 26, 1, -69, 7, 9, 0, -68, 7, 43, 0, -104, 0, 43, 0, -67, 7, 9, + 0, -66, 7, 36, 0, 79, 0, 7, 0, 109, 3, 7, 0, -65, 7, 7, 0, -64, 7, 7, 0, -63, 7, 7, 0, -62, 7, 7, 0, -61, 7, 7, + 0, -60, 7, 4, 0, 93, 0, 4, 0, -59, 7, 0, 0, -58, 7, 0, 0, -57, 7, 0, 0, -56, 7, 27, 1, 6, 0, 27, 0, 31, 0, 7, + 0, -55, 7, 7, 0, -54, 7, 7, 0, -53, 7, 2, 0, -52, 7, 2, 0, -51, 7, 28, 1, 14, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, + 0, 75, 5, 7, 0, 76, 5, -74, 0, 77, 5, -69, 0, -108, 5, -28, 0, 18, 7, 2, 0, 13, 1, 2, 0, -115, 7, 2, 0, 8, 2, 2, + 0, 9, 2, 2, 0, 20, 0, 2, 0, -98, 5, 4, 0, 70, 0, 29, 1, 6, 0, 29, 1, 0, 0, 29, 1, 1, 0, 32, 0, 45, 0, 9, + 0, -50, 7, 4, 0, -38, 0, 4, 0, 37, 0, 63, 0, 4, 0, 27, 0, 31, 0, 12, 0, -49, 7, 4, 0, -121, 0, 7, 0, -48, 7, 30, + 1, 25, 0, 30, 1, 0, 0, 30, 1, 1, 0, 30, 1, 38, 0, 12, 0, -47, 7, 0, 0, 17, 0, 7, 0, -46, 7, 7, 0, -45, 7, 7, + 0, -44, 7, 7, 0, -43, 7, 4, 0, 20, 0, 7, 0, -42, 7, 7, 0, -41, 7, 7, 0, -40, 7, 7, 0, 20, 1, 7, 0, -39, 1, 7, + 0, -39, 7, 7, 0, 108, 2, 7, 0, -38, 7, 7, 0, -37, 7, 7, 0, -36, 7, 7, 0, -35, 7, 7, 0, -34, 7, 7, 0, -81, 0, 2, + 0, -121, 0, 2, 0, -31, 4, 31, 1, 19, 0, 27, 0, 31, 0, 12, 0, -33, 7, 12, 0, -32, 7, 4, 0, 20, 0, 4, 0, 30, 4, 2, + 0, -96, 2, 2, 0, -31, 7, 2, 0, -121, 0, 2, 0, -30, 7, 2, 0, -29, 7, 2, 0, -28, 7, 2, 0, -27, 7, 2, 0, -26, 7, 4, + 0, -25, 7, 4, 0, -24, 7, 4, 0, -23, 7, 4, 0, -22, 7, 4, 0, -21, 7, 4, 0, -20, 7, 32, 1, 34, 0, 32, 1, 0, 0, 32, + 1, 1, 0, 12, 0, 49, 3, 0, 0, 17, 0, 2, 0, 20, 0, 2, 0, -19, 7, 2, 0, -18, 7, 2, 0, -17, 7, 2, 0, 10, 3, 2, + 0, -16, 7, 4, 0, -7, 1, 4, 0, -23, 7, 4, 0, -22, 7, 30, 1, -15, 7, 32, 1, 38, 0, 32, 1, -14, 7, 12, 0, -13, 7, 9, + 0, -12, 7, 9, 0, -11, 7, 9, 0, -10, 7, 7, 0, 7, 1, 7, 0, -81, 0, 7, 0, -57, 1, 7, 0, -9, 7, 7, 0, -8, 7, 7, + 0, 2, 3, 7, 0, -7, 7, 7, 0, -6, 7, 7, 0, -5, 7, 7, 0, -4, 7, 7, 0, -3, 7, 7, 0, -2, 7, 7, 0, -10, 1, 32, + 0, -1, 7, -110, 0, 9, 0, 12, 0, 0, 8, 2, 0, 20, 0, 2, 0, 1, 8, 7, 0, 20, 3, 7, 0, 2, 8, 7, 0, 3, 8, 12, + 0, 4, 8, 4, 0, 5, 8, 4, 0, 37, 0, 33, 1, 7, 0, 33, 1, 0, 0, 33, 1, 1, 0, 12, 0, -58, 7, 4, 0, 20, 0, 4, + 0, 6, 8, 0, 0, 17, 0, -47, 0, 7, 8, 34, 1, 8, 0, 34, 1, 0, 0, 34, 1, 1, 0, 33, 1, 8, 8, 36, 0, 79, 0, 12, + 0, -6, 2, 4, 0, 20, 0, 0, 0, 17, 0, 4, 0, 9, 8, -111, 0, 6, 0, 27, 0, 31, 0, 12, 0, 0, 8, 12, 0, 10, 8, 12, + 0, 103, 0, 4, 0, 11, 8, 4, 0, 37, 0, 35, 1, 16, 0, -75, 0, 0, 0, -75, 0, 1, 0, 4, 0, 75, 5, 7, 0, 76, 5, -74, + 0, 77, 5, 2, 0, 78, 5, -69, 0, -108, 5, -111, 0, -9, 2, 0, 0, 13, 1, 0, 0, -37, 5, 2, 0, 20, 0, 2, 0, 12, 8, 2, + 0, -101, 5, 2, 0, -98, 5, 2, 0, 13, 8, 7, 0, 14, 8, 36, 1, 5, 0, 36, 1, 0, 0, 36, 1, 1, 0, 36, 0, 79, 0, 2, + 0, 20, 0, 0, 0, 15, 8, 37, 1, 12, 0, 37, 1, 0, 0, 37, 1, 1, 0, 9, 0, 2, 0, 2, 0, 18, 0, 2, 0, 20, 0, 0, + 0, 16, 8, 0, 0, 17, 8, 0, 0, 15, 8, 7, 0, 18, 8, 7, 0, 19, 8, 4, 0, 37, 0, 36, 0, 79, 0, 38, 1, 9, 0, 38, + 1, 0, 0, 38, 1, 1, 0, 32, 0, 20, 8, 0, 0, 21, 8, 7, 0, 22, 8, 2, 0, 23, 8, 2, 0, 20, 0, 2, 0, 18, 0, 2, + 0, 37, 0, 39, 1, 7, 0, 42, 0, -36, 5, 26, 0, 24, 8, 4, 0, 20, 0, 4, 0, 25, 8, 12, 0, 26, 8, 32, 0, 20, 8, 0, + 0, 21, 8, 40, 1, 12, 0, 32, 0, 20, 8, 2, 0, 27, 8, 2, 0, 20, 0, 2, 0, 28, 8, 2, 0, 29, 8, 0, 0, 21, 8, 32, + 0, 30, 8, 0, 0, 31, 8, 7, 0, 32, 8, 7, 0, -39, 1, 7, 0, 33, 8, 7, 0, 34, 8, 41, 1, 6, 0, 32, 0, 20, 8, 4, + 0, 9, 8, 4, 0, 35, 8, 4, 0, 93, 0, 4, 0, 37, 0, 0, 0, 21, 8, 42, 1, 4, 0, 32, 0, 20, 8, 4, 0, 20, 0, 4, + 0, 9, 8, 0, 0, 21, 8, 43, 1, 4, 0, 32, 0, 20, 8, 4, 0, 20, 0, 4, 0, 9, 8, 0, 0, 21, 8, 44, 1, 10, 0, 32, + 0, 20, 8, 4, 0, 36, 8, 7, 0, -127, 0, 4, 0, 20, 0, 2, 0, -42, 5, 2, 0, 37, 8, 2, 0, 43, 0, 2, 0, 70, 0, 7, + 0, 38, 8, 0, 0, 21, 8, 45, 1, 4, 0, 32, 0, 20, 8, 4, 0, 20, 0, 4, 0, 9, 8, 0, 0, 21, 8, 46, 1, 10, 0, 32, + 0, 20, 8, 2, 0, 18, 0, 2, 0, -95, 3, 4, 0, 91, 0, 4, 0, 92, 0, 7, 0, -97, 7, 7, 0, -96, 7, 4, 0, 37, 0, -111, + 0, -122, 7, 0, 0, 21, 8, 47, 1, 4, 0, 32, 0, 20, 8, 4, 0, 7, 3, 4, 0, 39, 8, 0, 0, 21, 8, 48, 1, 5, 0, 32, + 0, 20, 8, 7, 0, -127, 0, 4, 0, 40, 8, 4, 0, 7, 3, 4, 0, 8, 3, 49, 1, 6, 0, 32, 0, 20, 8, 4, 0, 41, 8, 4, + 0, 42, 8, 7, 0, 43, 8, 7, 0, 44, 8, 0, 0, 21, 8, 50, 1, 16, 0, 32, 0, 20, 8, 32, 0, -14, 7, 4, 0, 18, 0, 7, + 0, 45, 8, 7, 0, 46, 8, 7, 0, 47, 8, 7, 0, 48, 8, 7, 0, 49, 8, 7, 0, 50, 8, 7, 0, 51, 8, 7, 0, 52, 8, 7, + 0, 53, 8, 2, 0, 20, 0, 2, 0, 37, 0, 2, 0, 43, 0, 2, 0, 70, 0, 51, 1, 3, 0, 32, 0, 20, 8, 4, 0, 20, 0, 4, + 0, 123, 5, 52, 1, 5, 0, 32, 0, 20, 8, 4, 0, 20, 0, 4, 0, 37, 0, 7, 0, 54, 8, 0, 0, 21, 8, 53, 1, 10, 0, 32, + 0, 20, 8, 0, 0, 21, 8, 2, 0, 55, 8, 2, 0, 56, 8, 0, 0, 57, 8, 0, 0, 58, 8, 7, 0, 59, 8, 7, 0, 60, 8, 7, + 0, 61, 8, 7, 0, 62, 8, 54, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0, 7, 0, 63, 8, 7, + 0, 64, 8, 2, 0, 20, 0, 2, 0, 123, 5, 55, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, 0, 12, 0, 7, + 0, 63, 8, 7, 0, 64, 8, 2, 0, 20, 0, 2, 0, 123, 5, 56, 1, 8, 0, 7, 0, 9, 0, 7, 0, 10, 0, 7, 0, 11, 0, 7, + 0, 12, 0, 7, 0, 63, 8, 7, 0, 64, 8, 2, 0, 20, 0, 2, 0, 123, 5, 57, 1, 7, 0, 32, 0, 20, 8, 0, 0, 21, 8, 7, + 0, 20, 1, 7, 0, 30, 1, 2, 0, 20, 0, 2, 0, 13, 1, 4, 0, 37, 0, 58, 1, 5, 0, 32, 0, -45, 2, 7, 0, 20, 1, 2, + 0, -41, 2, 0, 0, -39, 2, 0, 0, 65, 8, 59, 1, 10, 0, 59, 1, 0, 0, 59, 1, 1, 0, 2, 0, 18, 0, 2, 0, 20, 0, 0, + 0, 66, 8, 7, 0, -36, 0, 7, 0, -35, 0, 2, 0, -58, 7, 2, 0, 67, 8, 32, 0, 45, 0, 60, 1, 22, 0, 60, 1, 0, 0, 60, + 1, 1, 0, 2, 0, 20, 0, 2, 0, 13, 1, 2, 0, 68, 8, 2, 0, 69, 8, 36, 0, 79, 0, -111, 0, -122, 7, 32, 0, -89, 0, 7, + 0, 91, 0, 7, 0, 92, 0, 7, 0, 70, 8, 7, 0, 71, 8, 7, 0, 72, 8, 7, 0, 73, 8, 7, 0, -107, 2, 7, 0, -67, 1, 7, + 0, -120, 7, 7, 0, 74, 8, 0, 0, 75, 8, 0, 0, 76, 8, 12, 0, -4, 2, 61, 1, 8, 0, 7, 0, -31, 1, 7, 0, -97, 7, 7, + 0, -96, 7, 9, 0, 2, 0, 2, 0, 77, 8, 2, 0, 78, 8, 2, 0, 79, 8, 2, 0, 80, 8, 62, 1, 18, 0, 62, 1, 0, 0, 62, + 1, 1, 0, 62, 1, 81, 8, 0, 0, 17, 0, 61, 1, 82, 8, 2, 0, 18, 0, 2, 0, 20, 0, 2, 0, 83, 8, 2, 0, 84, 8, 2, + 0, 85, 8, 2, 0, 86, 8, 4, 0, 43, 0, 7, 0, 87, 8, 7, 0, 88, 8, 4, 0, 89, 8, 4, 0, 90, 8, 62, 1, 91, 8, 63, + 1, 92, 8, 64, 1, 32, 0, 64, 1, 0, 0, 64, 1, 1, 0, 64, 1, 93, 8, 0, 0, 17, 0, 0, 0, 94, 8, 2, 0, 18, 0, 2, + 0, 20, 0, 2, 0, -14, 6, 2, 0, 20, 7, 2, 0, 95, 8, 2, 0, -119, 0, 2, 0, 84, 8, 2, 0, -25, 6, 12, 0, -127, 7, 12, + 0, 96, 8, 27, 0, -9, 5, 9, 0, 97, 8, 7, 0, 87, 8, 7, 0, 88, 8, 7, 0, -5, 1, 7, 0, 98, 8, 2, 0, 99, 8, 2, + 0, 100, 8, 7, 0, 101, 8, 7, 0, 102, 8, 2, 0, 103, 8, 2, 0, 104, 8, 24, 0, 105, 8, 24, 0, 106, 8, 24, 0, 107, 8, 65, + 1, -103, 0, 66, 1, 108, 8, 63, 1, 6, 0, 63, 1, 0, 0, 63, 1, 1, 0, 64, 1, 109, 8, 64, 1, 110, 8, 62, 1, 111, 8, 62, + 1, 91, 8, 57, 0, 16, 0, 27, 0, 31, 0, 12, 0, 112, 8, 12, 0, 113, 8, 61, 1, 114, 8, 12, 0, 115, 8, 4, 0, 18, 0, 4, + 0, 116, 8, 4, 0, 117, 8, 4, 0, 118, 8, 12, 0, 119, 8, 66, 1, 120, 8, 62, 1, 121, 8, 62, 1, 122, 8, 9, 0, 123, 8, 9, + 0, 124, 8, 4, 0, 125, 8, 67, 1, 6, 0, 4, 0, -128, 0, 4, 0, -126, 0, 4, 0, -25, 6, 0, 0, 126, 8, 0, 0, 127, 8, 2, + 0, 37, 0, 68, 1, 16, 0, 2, 0, -86, 6, 2, 0, -85, 6, 2, 0, -128, 8, 2, 0, -74, 7, 2, 0, -127, 8, 2, 0, 68, 0, 7, + 0, -108, 2, 7, 0, -126, 8, 7, 0, -125, 8, 2, 0, 34, 1, 0, 0, -124, 8, 0, 0, 42, 4, 2, 0, -123, 8, 2, 0, 37, 0, 4, + 0, -122, 8, 4, 0, -121, 8, 69, 1, 9, 0, 7, 0, -120, 8, 7, 0, -119, 8, 7, 0, -60, 7, 7, 0, 112, 0, 7, 0, -118, 8, 7, + 0, 71, 5, 2, 0, -117, 8, 0, 0, -116, 8, 0, 0, 37, 0, 70, 1, 4, 0, 7, 0, -115, 8, 7, 0, -114, 8, 2, 0, -117, 8, 2, + 0, 37, 0, 71, 1, 3, 0, 7, 0, -113, 8, 7, 0, -112, 8, 7, 0, 15, 0, 72, 1, 7, 0, 0, 0, -68, 1, 2, 0, 109, 4, 2, + 0, 110, 4, 2, 0, 111, 4, 2, 0, 62, 4, 4, 0, -126, 0, 4, 0, -97, 3, 73, 1, 7, 0, 7, 0, -111, 8, 7, 0, -110, 8, 7, + 0, -109, 8, 7, 0, 4, 2, 7, 0, -108, 8, 7, 0, -107, 8, 7, 0, -106, 8, 74, 1, 4, 0, 2, 0, -105, 8, 2, 0, -104, 8, 2, + 0, -103, 8, 2, 0, -102, 8, 75, 1, 2, 0, 7, 0, 5, 0, 7, 0, 6, 0, 76, 1, 2, 0, 0, 0, -87, 0, 0, 0, -101, 8, 77, + 1, 1, 0, 0, 0, 17, 0, 78, 1, 10, 0, 0, 0, -100, 8, 0, 0, -99, 8, 0, 0, -98, 8, 0, 0, -97, 8, 2, 0, -128, 8, 2, + 0, -96, 8, 7, 0, -95, 8, 7, 0, -94, 8, 7, 0, -93, 8, 7, 0, -67, 1, 79, 1, 2, 0, 9, 0, -92, 8, 9, 0, -91, 8, 80, + 1, 11, 0, 0, 0, 111, 4, 0, 0, 18, 0, 0, 0, -117, 8, 0, 0, 112, 0, 0, 0, -90, 8, 0, 0, 109, 0, 0, 0, -74, 0, 7, + 0, -89, 8, 7, 0, -88, 8, 7, 0, -87, 8, 7, 0, -86, 8, 81, 1, 8, 0, 7, 0, 97, 7, 7, 0, -127, 0, 7, 0, 42, 4, 7, + 0, 72, 2, 7, 0, -85, 8, 7, 0, -49, 0, 7, 0, -84, 8, 4, 0, 18, 0, 82, 1, 4, 0, 2, 0, -83, 8, 2, 0, -82, 8, 2, + 0, -81, 8, 2, 0, 37, 0, 83, 1, 1, 0, 0, 0, 17, 0, 84, 1, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 2, 0, 20, 0, 2, + 0, -80, 8, 85, 1, 10, 0, 2, 0, -120, 3, 2, 0, 20, 0, 7, 0, -17, 3, 7, 0, -79, 8, 7, 0, -78, 8, 7, 0, -77, 8, 7, + 0, -76, 8, 84, 1, -75, 8, 84, 1, -74, 8, 84, 1, -73, 8, 60, 0, 9, 0, 4, 0, 20, 0, 4, 0, 64, 0, 24, 0, -72, 8, 24, + 0, -71, 8, 85, 1, -70, 8, 7, 0, -69, 8, 7, 0, -68, 8, 7, 0, -67, 8, 7, 0, -66, 8, 86, 1, 4, 0, 46, 0, -114, 2, 7, + 0, -65, 8, 7, 0, 92, 1, 7, 0, 37, 0, -87, 0, 13, 0, 27, 0, 31, 0, 2, 0, 20, 0, 2, 0, 72, 5, 4, 0, 109, 0, 7, + 0, -64, 8, 7, 0, 1, 2, 7, 0, -63, 8, 7, 0, -62, 8, 7, 0, 92, 1, 2, 0, 47, 1, 2, 0, 37, 0, 50, 0, 77, 1, 86, + 1, -61, 8, 87, 1, 10, 0, 4, 0, 18, 0, 4, 0, -127, 0, 4, 0, 20, 0, 4, 0, 70, 3, 4, 0, -60, 8, 4, 0, -59, 8, 4, + 0, -58, 8, 0, 0, 95, 0, 0, 0, 17, 0, 9, 0, 2, 0, 84, 0, 6, 0, 87, 1, -57, 8, 4, 0, -56, 8, 4, 0, -55, 8, 4, + 0, -54, 8, 4, 0, 37, 0, 9, 0, -53, 8, 88, 1, 5, 0, 7, 0, 66, 2, 7, 0, -74, 2, 7, 0, -39, 1, 2, 0, -52, 8, 2, + 0, 37, 0, 89, 1, 5, 0, 7, 0, 66, 2, 7, 0, -51, 8, 7, 0, -50, 8, 7, 0, -49, 8, 7, 0, -74, 2, 90, 1, 7, 0, 4, + 0, -48, 8, 4, 0, -47, 8, 4, 0, -46, 8, 7, 0, -45, 8, 7, 0, -44, 8, 7, 0, -43, 8, 7, 0, -42, 8, 91, 1, 26, 0, 32, + 0, -41, 8, 89, 1, 66, 3, 89, 1, -40, 8, 88, 1, -39, 8, 89, 1, 83, 7, 7, 0, -38, 8, 7, 0, -37, 8, 7, 0, -36, 8, 7, + 0, -35, 8, 7, 0, -44, 8, 7, 0, -43, 8, 7, 0, -74, 2, 7, 0, -97, 2, 7, 0, -34, 8, 7, 0, -33, 8, 7, 0, 109, 0, 7, + 0, -32, 8, 4, 0, -48, 8, 4, 0, -31, 8, 4, 0, 37, 0, 4, 0, 81, 0, 4, 0, -30, 8, 2, 0, 20, 0, 2, 0, -29, 8, 2, + 0, -28, 8, 2, 0, 100, 3, 92, 1, 112, 0, 27, 0, 31, 0, 4, 0, 20, 0, 2, 0, 18, 0, 2, 0, 55, 8, 2, 0, -27, 8, 2, + 0, -26, 8, 2, 0, -25, 8, 2, 0, -24, 8, 2, 0, -23, 8, 2, 0, -22, 8, 2, 0, -21, 8, 2, 0, -20, 8, 2, 0, -19, 8, 2, + 0, -18, 8, 2, 0, -17, 8, 2, 0, -16, 8, 2, 0, -15, 8, 2, 0, -14, 8, 2, 0, -13, 8, 2, 0, -47, 1, 2, 0, 76, 7, 2, + 0, 51, 7, 2, 0, -12, 8, 2, 0, -11, 8, 2, 0, 98, 3, 2, 0, 99, 3, 2, 0, -10, 8, 2, 0, -9, 8, 2, 0, -8, 8, 2, + 0, -7, 8, 2, 0, -6, 8, 2, 0, -5, 8, 7, 0, -4, 8, 7, 0, -3, 8, 7, 0, -2, 8, 2, 0, -1, 8, 2, 0, 0, 9, 7, + 0, 1, 9, 7, 0, 2, 9, 7, 0, 3, 9, 7, 0, 58, 7, 7, 0, 92, 0, 7, 0, -97, 2, 7, 0, 64, 7, 7, 0, 4, 9, 7, + 0, 5, 9, 7, 0, 6, 9, 7, 0, 7, 9, 7, 0, 57, 0, 4, 0, 59, 7, 4, 0, 57, 7, 4, 0, 8, 9, 7, 0, 60, 7, 7, + 0, 61, 7, 7, 0, 62, 7, 7, 0, 9, 9, 7, 0, 10, 9, 7, 0, 11, 9, 7, 0, 12, 9, 7, 0, 13, 9, 7, 0, 14, 9, 7, + 0, 15, 9, 7, 0, 16, 9, 7, 0, 21, 3, 7, 0, 109, 0, 7, 0, 17, 9, 7, 0, 18, 9, 7, 0, 19, 9, 7, 0, 20, 9, 7, + 0, 21, 9, 7, 0, 22, 9, 7, 0, 108, 2, 7, 0, 23, 9, 7, 0, 24, 9, 4, 0, 25, 9, 4, 0, 26, 9, 7, 0, 27, 9, 7, + 0, 28, 9, 7, 0, 29, 9, 7, 0, 30, 9, 7, 0, 31, 9, 7, 0, 32, 9, 7, 0, 33, 9, 7, 0, 34, 9, 7, 0, 94, 3, 7, + 0, 92, 3, 7, 0, 93, 3, 7, 0, 35, 9, 7, 0, 36, 9, 7, 0, 37, 9, 7, 0, 38, 9, 7, 0, 39, 9, 7, 0, 40, 9, 7, + 0, 41, 9, 7, 0, 42, 9, 7, 0, 43, 9, 7, 0, 28, 3, 7, 0, 44, 9, 7, 0, 45, 9, 7, 0, 46, 9, 7, 0, 47, 9, 7, + 0, 48, 9, 7, 0, 49, 9, 7, 0, 50, 9, 0, 0, 51, 9, 63, 0, 55, 3, 63, 0, 52, 9, 32, 0, 53, 9, 32, 0, 54, 9, 36, + 0, 79, 0, -108, 0, 53, 3, -108, 0, 55, 9, -120, 0, 37, 0, -120, 0, 0, 0, -120, 0, 1, 0, 92, 1, 56, 9, 91, 1, -121, 3, 90, + 1, -14, 7, 93, 1, 57, 9, 94, 1, 58, 9, 94, 1, 59, 9, 12, 0, 60, 9, 12, 0, 61, 9, -107, 0, 54, 3, 32, 0, 62, 9, 32, + 0, 63, 9, 32, 0, 64, 9, 12, 0, 65, 9, 12, 0, 66, 9, 7, 0, -45, 0, 7, 0, 83, 4, 4, 0, 110, 2, 4, 0, 20, 0, 4, + 0, 59, 7, 4, 0, 67, 9, 4, 0, 68, 9, 4, 0, 69, 9, 4, 0, 57, 0, 2, 0, -38, 0, 2, 0, 70, 9, 2, 0, 71, 9, 2, + 0, 72, 9, 2, 0, 47, 3, 2, 0, 73, 9, 0, 0, 74, 9, 2, 0, 75, 9, 2, 0, 76, 9, 2, 0, 77, 9, 9, 0, 78, 9, 125, + 0, -76, 3, 123, 0, 34, 0, 95, 1, 79, 9, 7, 0, -106, 3, 7, 0, 80, 9, 7, 0, 81, 9, 7, 0, -14, 3, 7, 0, 82, 9, 7, + 0, 31, 3, 7, 0, 21, 3, 7, 0, 83, 9, 7, 0, 3, 2, 7, 0, 84, 9, 7, 0, 85, 9, 7, 0, 86, 9, 7, 0, 87, 9, 7, + 0, 88, 9, 7, 0, 89, 9, 7, 0, -105, 3, 7, 0, 90, 9, 7, 0, 91, 9, 7, 0, 92, 9, 7, 0, -104, 3, 7, 0, -108, 3, 7, + 0, -107, 3, 4, 0, 93, 9, 4, 0, 93, 0, 4, 0, 94, 9, 4, 0, 95, 9, 2, 0, 96, 9, 2, 0, 97, 9, 2, 0, 98, 9, 2, + 0, 99, 9, 2, 0, 100, 9, 2, 0, 37, 0, 4, 0, 70, 0, 124, 0, 8, 0, 95, 1, 101, 9, 7, 0, 102, 9, 7, 0, 103, 9, 7, + 0, -94, 1, 7, 0, 104, 9, 4, 0, 93, 0, 2, 0, 105, 9, 2, 0, 106, 9, 96, 1, 4, 0, 7, 0, 5, 0, 7, 0, 6, 0, 7, + 0, 7, 0, 7, 0, 107, 9, 97, 1, 6, 0, 97, 1, 0, 0, 97, 1, 1, 0, 96, 1, 108, 9, 4, 0, 109, 9, 2, 0, 110, 9, 2, + 0, 20, 0, 98, 1, 5, 0, 98, 1, 0, 0, 98, 1, 1, 0, 12, 0, 111, 9, 4, 0, 112, 9, 4, 0, 20, 0, 99, 1, 9, 0, 99, + 1, 0, 0, 99, 1, 1, 0, 12, 0, -128, 0, 98, 1, 113, 9, 4, 0, 20, 0, 2, 0, 110, 9, 2, 0, 114, 9, 7, 0, 94, 0, 0, + 0, 115, 9, -70, 0, 5, 0, 12, 0, 125, 4, 4, 0, 20, 0, 2, 0, 116, 9, 2, 0, 117, 9, 9, 0, 118, 9, 69, 78, 68, 66, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +int DNAlen = sizeof(DNAstr); diff --git a/Extras/Serialize/BulletFileLoader/autogenerated/bullet.h b/Extras/Serialize/BulletFileLoader/autogenerated/bullet.h index bebd92ef2..0c424d50a 100644 --- a/Extras/Serialize/BulletFileLoader/autogenerated/bullet.h +++ b/Extras/Serialize/BulletFileLoader/autogenerated/bullet.h @@ -19,1559 +19,1472 @@ // Auto generated from Bullet/Extras/HeaderGenerator/bulletGenerate.py #ifndef __BULLET_H__ #define __BULLET_H__ -namespace Bullet { - +namespace Bullet +{ // put an empty struct in the case -typedef struct bInvalidHandle { +typedef struct bInvalidHandle +{ int unused; -}bInvalidHandle; - - class PointerArray; - class btPhysicsSystem; - class ListBase; - class btVector3FloatData; - class btVector3DoubleData; - class btQuaternionFloatData; - class btQuaternionDoubleData; - class btMatrix3x3FloatData; - class btMatrix3x3DoubleData; - class btTransformFloatData; - class btTransformDoubleData; - class btBvhSubtreeInfoData; - class btOptimizedBvhNodeFloatData; - class btOptimizedBvhNodeDoubleData; - class btQuantizedBvhNodeData; - class btQuantizedBvhFloatData; - class btQuantizedBvhDoubleData; - class btCollisionShapeData; - class btStaticPlaneShapeData; - class btConvexInternalShapeData; - class btPositionAndRadius; - class btMultiSphereShapeData; - class btIntIndexData; - class btShortIntIndexData; - class btShortIntIndexTripletData; - class btCharIndexTripletData; - class btMeshPartData; - class btStridingMeshInterfaceData; - class btTriangleMeshShapeData; - class btScaledTriangleMeshShapeData; - class btCompoundShapeChildData; - class btCompoundShapeData; - class btCylinderShapeData; - class btConeShapeData; - class btCapsuleShapeData; - class btTriangleInfoData; - class btTriangleInfoMapData; - class btPersistentManifoldDoubleData; - class btPersistentManifoldFloatData; - class btGImpactMeshShapeData; - class btConvexHullShapeData; - class btCollisionObjectDoubleData; - class btCollisionObjectFloatData; - class btContactSolverInfoDoubleData; - class btContactSolverInfoFloatData; - class btDynamicsWorldDoubleData; - class btDynamicsWorldFloatData; - class btRigidBodyFloatData; - class btRigidBodyDoubleData; - class btConstraintInfo1; - class btTypedConstraintFloatData; - class btTypedConstraintData; - class btTypedConstraintDoubleData; - class btPoint2PointConstraintFloatData; - class btPoint2PointConstraintDoubleData2; - class btPoint2PointConstraintDoubleData; - class btHingeConstraintDoubleData; - class btHingeConstraintFloatData; - class btHingeConstraintDoubleData2; - class btConeTwistConstraintDoubleData; - class btConeTwistConstraintData; - class btGeneric6DofConstraintData; - class btGeneric6DofConstraintDoubleData2; - class btGeneric6DofSpringConstraintData; - class btGeneric6DofSpringConstraintDoubleData2; - class btGeneric6DofSpring2ConstraintData; - class btGeneric6DofSpring2ConstraintDoubleData2; - class btSliderConstraintData; - class btSliderConstraintDoubleData; - class btGearConstraintFloatData; - class btGearConstraintDoubleData; - class SoftBodyMaterialData; - class SoftBodyNodeData; - class SoftBodyLinkData; - class SoftBodyFaceData; - class SoftBodyTetraData; - class SoftRigidAnchorData; - class SoftBodyConfigData; - class SoftBodyPoseData; - class SoftBodyClusterData; - class btSoftBodyJointData; - class btSoftBodyFloatData; - class btMultiBodyLinkDoubleData; - class btMultiBodyLinkFloatData; - class btMultiBodyDoubleData; - class btMultiBodyFloatData; - class btMultiBodyLinkColliderFloatData; - class btMultiBodyLinkColliderDoubleData; -// -------------------------------------------------- // - class PointerArray - { - public: - int m_size; - int m_capacity; - void *m_data; - }; - - -// -------------------------------------------------- // - class btPhysicsSystem - { - public: - PointerArray m_collisionShapes; - PointerArray m_collisionObjects; - PointerArray m_constraints; - }; - - -// -------------------------------------------------- // - class ListBase - { - public: - void *first; - void *last; - }; - - -// -------------------------------------------------- // - class btVector3FloatData - { - public: - float m_floats[4]; - }; - - -// -------------------------------------------------- // - class btVector3DoubleData - { - public: - double m_floats[4]; - }; - - -// -------------------------------------------------- // - class btQuaternionFloatData - { - public: - float m_floats[4]; - }; - - -// -------------------------------------------------- // - class btQuaternionDoubleData - { - public: - double m_floats[4]; - }; - - -// -------------------------------------------------- // - class btMatrix3x3FloatData - { - public: - btVector3FloatData m_el[3]; - }; - - -// -------------------------------------------------- // - class btMatrix3x3DoubleData - { - public: - btVector3DoubleData m_el[3]; - }; - - -// -------------------------------------------------- // - class btTransformFloatData - { - public: - btMatrix3x3FloatData m_basis; - btVector3FloatData m_origin; - }; - - -// -------------------------------------------------- // - class btTransformDoubleData - { - public: - btMatrix3x3DoubleData m_basis; - btVector3DoubleData m_origin; - }; - - -// -------------------------------------------------- // - class btBvhSubtreeInfoData - { - public: - int m_rootNodeIndex; - int m_subtreeSize; - short m_quantizedAabbMin[3]; - short m_quantizedAabbMax[3]; - }; - - -// -------------------------------------------------- // - class btOptimizedBvhNodeFloatData - { - public: - btVector3FloatData m_aabbMinOrg; - btVector3FloatData m_aabbMaxOrg; - int m_escapeIndex; - int m_subPart; - int m_triangleIndex; - char m_pad[4]; - }; - - -// -------------------------------------------------- // - class btOptimizedBvhNodeDoubleData - { - public: - btVector3DoubleData m_aabbMinOrg; - btVector3DoubleData m_aabbMaxOrg; - int m_escapeIndex; - int m_subPart; - int m_triangleIndex; - char m_pad[4]; - }; - - -// -------------------------------------------------- // - class btQuantizedBvhNodeData - { - public: - short m_quantizedAabbMin[3]; - short m_quantizedAabbMax[3]; - int m_escapeIndexOrTriangleIndex; - }; - - -// -------------------------------------------------- // - class btQuantizedBvhFloatData - { - public: - btVector3FloatData m_bvhAabbMin; - btVector3FloatData m_bvhAabbMax; - btVector3FloatData m_bvhQuantization; - int m_curNodeIndex; - int m_useQuantization; - int m_numContiguousLeafNodes; - int m_numQuantizedContiguousNodes; - btOptimizedBvhNodeFloatData *m_contiguousNodesPtr; - btQuantizedBvhNodeData *m_quantizedContiguousNodesPtr; - btBvhSubtreeInfoData *m_subTreeInfoPtr; - int m_traversalMode; - int m_numSubtreeHeaders; - }; - - -// -------------------------------------------------- // - class btQuantizedBvhDoubleData - { - public: - btVector3DoubleData m_bvhAabbMin; - btVector3DoubleData m_bvhAabbMax; - btVector3DoubleData m_bvhQuantization; - int m_curNodeIndex; - int m_useQuantization; - int m_numContiguousLeafNodes; - int m_numQuantizedContiguousNodes; - btOptimizedBvhNodeDoubleData *m_contiguousNodesPtr; - btQuantizedBvhNodeData *m_quantizedContiguousNodesPtr; - int m_traversalMode; - int m_numSubtreeHeaders; - btBvhSubtreeInfoData *m_subTreeInfoPtr; - }; - - -// -------------------------------------------------- // - class btCollisionShapeData - { - public: - char *m_name; - int m_shapeType; - char m_padding[4]; - }; - - -// -------------------------------------------------- // - class btStaticPlaneShapeData - { - public: - btCollisionShapeData m_collisionShapeData; - btVector3FloatData m_localScaling; - btVector3FloatData m_planeNormal; - float m_planeConstant; - char m_pad[4]; - }; - - -// -------------------------------------------------- // - class btConvexInternalShapeData - { - public: - btCollisionShapeData m_collisionShapeData; - btVector3FloatData m_localScaling; - btVector3FloatData m_implicitShapeDimensions; - float m_collisionMargin; - int m_padding; - }; - - -// -------------------------------------------------- // - class btPositionAndRadius - { - public: - btVector3FloatData m_pos; - float m_radius; - }; - - -// -------------------------------------------------- // - class btMultiSphereShapeData - { - public: - btConvexInternalShapeData m_convexInternalShapeData; - btPositionAndRadius *m_localPositionArrayPtr; - int m_localPositionArraySize; - char m_padding[4]; - }; - - -// -------------------------------------------------- // - class btIntIndexData - { - public: - int m_value; - }; - - -// -------------------------------------------------- // - class btShortIntIndexData - { - public: - short m_value; - char m_pad[2]; - }; - - -// -------------------------------------------------- // - class btShortIntIndexTripletData - { - public: - short m_values[3]; - char m_pad[2]; - }; - - -// -------------------------------------------------- // - class btCharIndexTripletData - { - public: - char m_values[3]; - char m_pad; - }; - - -// -------------------------------------------------- // - class btMeshPartData - { - public: - btVector3FloatData *m_vertices3f; - btVector3DoubleData *m_vertices3d; - btIntIndexData *m_indices32; - btShortIntIndexTripletData *m_3indices16; - btCharIndexTripletData *m_3indices8; - btShortIntIndexData *m_indices16; - int m_numTriangles; - int m_numVertices; - }; - - -// -------------------------------------------------- // - class btStridingMeshInterfaceData - { - public: - btMeshPartData *m_meshPartsPtr; - btVector3FloatData m_scaling; - int m_numMeshParts; - char m_padding[4]; - }; - - -// -------------------------------------------------- // - class btTriangleMeshShapeData - { - public: - btCollisionShapeData m_collisionShapeData; - btStridingMeshInterfaceData m_meshInterface; - btQuantizedBvhFloatData *m_quantizedFloatBvh; - btQuantizedBvhDoubleData *m_quantizedDoubleBvh; - btTriangleInfoMapData *m_triangleInfoMap; - float m_collisionMargin; - char m_pad3[4]; - }; - - -// -------------------------------------------------- // - class btScaledTriangleMeshShapeData - { - public: - btTriangleMeshShapeData m_trimeshShapeData; - btVector3FloatData m_localScaling; - }; - - -// -------------------------------------------------- // - class btCompoundShapeChildData - { - public: - btTransformFloatData m_transform; - btCollisionShapeData *m_childShape; - int m_childShapeType; - float m_childMargin; - }; - - -// -------------------------------------------------- // - class btCompoundShapeData - { - public: - btCollisionShapeData m_collisionShapeData; - btCompoundShapeChildData *m_childShapePtr; - int m_numChildShapes; - float m_collisionMargin; - }; - - -// -------------------------------------------------- // - class btCylinderShapeData - { - public: - btConvexInternalShapeData m_convexInternalShapeData; - int m_upAxis; - char m_padding[4]; - }; - - -// -------------------------------------------------- // - class btConeShapeData - { - public: - btConvexInternalShapeData m_convexInternalShapeData; - int m_upIndex; - char m_padding[4]; - }; - - -// -------------------------------------------------- // - class btCapsuleShapeData - { - public: - btConvexInternalShapeData m_convexInternalShapeData; - int m_upAxis; - char m_padding[4]; - }; - - -// -------------------------------------------------- // - class btTriangleInfoData - { - public: - int m_flags; - float m_edgeV0V1Angle; - float m_edgeV1V2Angle; - float m_edgeV2V0Angle; - }; - - -// -------------------------------------------------- // - class btTriangleInfoMapData - { - public: - int *m_hashTablePtr; - int *m_nextPtr; - btTriangleInfoData *m_valueArrayPtr; - int *m_keyArrayPtr; - float m_convexEpsilon; - float m_planarEpsilon; - float m_equalVertexThreshold; - float m_edgeDistanceThreshold; - float m_zeroAreaThreshold; - int m_nextSize; - int m_hashTableSize; - int m_numValues; - int m_numKeys; - char m_padding[4]; - }; - - -// -------------------------------------------------- // - class btPersistentManifoldDoubleData - { - public: - btVector3DoubleData m_pointCacheLocalPointA[4]; - btVector3DoubleData m_pointCacheLocalPointB[4]; - btVector3DoubleData m_pointCachePositionWorldOnA[4]; - btVector3DoubleData m_pointCachePositionWorldOnB[4]; - btVector3DoubleData m_pointCacheNormalWorldOnB[4]; - btVector3DoubleData m_pointCacheLateralFrictionDir1[4]; - btVector3DoubleData m_pointCacheLateralFrictionDir2[4]; - double m_pointCacheDistance[4]; - double m_pointCacheAppliedImpulse[4]; - double m_pointCacheCombinedFriction[4]; - double m_pointCacheCombinedRollingFriction[4]; - double m_pointCacheCombinedSpinningFriction[4]; - double m_pointCacheCombinedRestitution[4]; - int m_pointCachePartId0[4]; - int m_pointCachePartId1[4]; - int m_pointCacheIndex0[4]; - int m_pointCacheIndex1[4]; - int m_pointCacheContactPointFlags[4]; - double m_pointCacheAppliedImpulseLateral1[4]; - double m_pointCacheAppliedImpulseLateral2[4]; - double m_pointCacheContactMotion1[4]; - double m_pointCacheContactMotion2[4]; - double m_pointCacheContactCFM[4]; - double m_pointCacheCombinedContactStiffness1[4]; - double m_pointCacheContactERP[4]; - double m_pointCacheCombinedContactDamping1[4]; - double m_pointCacheFrictionCFM[4]; - int m_pointCacheLifeTime[4]; - int m_numCachedPoints; - int m_companionIdA; - int m_companionIdB; - int m_index1a; - int m_objectType; - double m_contactBreakingThreshold; - double m_contactProcessingThreshold; - int m_padding; - btCollisionObjectDoubleData *m_body0; - btCollisionObjectDoubleData *m_body1; - }; - - -// -------------------------------------------------- // - class btPersistentManifoldFloatData - { - public: - btVector3FloatData m_pointCacheLocalPointA[4]; - btVector3FloatData m_pointCacheLocalPointB[4]; - btVector3FloatData m_pointCachePositionWorldOnA[4]; - btVector3FloatData m_pointCachePositionWorldOnB[4]; - btVector3FloatData m_pointCacheNormalWorldOnB[4]; - btVector3FloatData m_pointCacheLateralFrictionDir1[4]; - btVector3FloatData m_pointCacheLateralFrictionDir2[4]; - float m_pointCacheDistance[4]; - float m_pointCacheAppliedImpulse[4]; - float m_pointCacheCombinedFriction[4]; - float m_pointCacheCombinedRollingFriction[4]; - float m_pointCacheCombinedSpinningFriction[4]; - float m_pointCacheCombinedRestitution[4]; - int m_pointCachePartId0[4]; - int m_pointCachePartId1[4]; - int m_pointCacheIndex0[4]; - int m_pointCacheIndex1[4]; - int m_pointCacheContactPointFlags[4]; - float m_pointCacheAppliedImpulseLateral1[4]; - float m_pointCacheAppliedImpulseLateral2[4]; - float m_pointCacheContactMotion1[4]; - float m_pointCacheContactMotion2[4]; - float m_pointCacheContactCFM[4]; - float m_pointCacheCombinedContactStiffness1[4]; - float m_pointCacheContactERP[4]; - float m_pointCacheCombinedContactDamping1[4]; - float m_pointCacheFrictionCFM[4]; - int m_pointCacheLifeTime[4]; - int m_numCachedPoints; - int m_companionIdA; - int m_companionIdB; - int m_index1a; - int m_objectType; - float m_contactBreakingThreshold; - float m_contactProcessingThreshold; - int m_padding; - btCollisionObjectFloatData *m_body0; - btCollisionObjectFloatData *m_body1; - }; - - -// -------------------------------------------------- // - class btGImpactMeshShapeData - { - public: - btCollisionShapeData m_collisionShapeData; - btStridingMeshInterfaceData m_meshInterface; - btVector3FloatData m_localScaling; - float m_collisionMargin; - int m_gimpactSubType; - }; - - -// -------------------------------------------------- // - class btConvexHullShapeData - { - public: - btConvexInternalShapeData m_convexInternalShapeData; - btVector3FloatData *m_unscaledPointsFloatPtr; - btVector3DoubleData *m_unscaledPointsDoublePtr; - int m_numUnscaledPoints; - char m_padding3[4]; - }; - - -// -------------------------------------------------- // - class btCollisionObjectDoubleData - { - public: - void *m_broadphaseHandle; - void *m_collisionShape; - btCollisionShapeData *m_rootCollisionShape; - char *m_name; - btTransformDoubleData m_worldTransform; - btTransformDoubleData m_interpolationWorldTransform; - btVector3DoubleData m_interpolationLinearVelocity; - btVector3DoubleData m_interpolationAngularVelocity; - btVector3DoubleData m_anisotropicFriction; - double m_contactProcessingThreshold; - double m_deactivationTime; - double m_friction; - double m_rollingFriction; - double m_contactDamping; - double m_contactStiffness; - double m_restitution; - double m_hitFraction; - double m_ccdSweptSphereRadius; - double m_ccdMotionThreshold; - int m_hasAnisotropicFriction; - int m_collisionFlags; - int m_islandTag1; - int m_companionId; - int m_activationState1; - int m_internalType; - int m_checkCollideWith; - int m_collisionFilterGroup; - int m_collisionFilterMask; - int m_uniqueId; - }; - - -// -------------------------------------------------- // - class btCollisionObjectFloatData - { - public: - void *m_broadphaseHandle; - void *m_collisionShape; - btCollisionShapeData *m_rootCollisionShape; - char *m_name; - btTransformFloatData m_worldTransform; - btTransformFloatData m_interpolationWorldTransform; - btVector3FloatData m_interpolationLinearVelocity; - btVector3FloatData m_interpolationAngularVelocity; - btVector3FloatData m_anisotropicFriction; - float m_contactProcessingThreshold; - float m_deactivationTime; - float m_friction; - float m_rollingFriction; - float m_contactDamping; - float m_contactStiffness; - float m_restitution; - float m_hitFraction; - float m_ccdSweptSphereRadius; - float m_ccdMotionThreshold; - int m_hasAnisotropicFriction; - int m_collisionFlags; - int m_islandTag1; - int m_companionId; - int m_activationState1; - int m_internalType; - int m_checkCollideWith; - int m_collisionFilterGroup; - int m_collisionFilterMask; - int m_uniqueId; - }; - - -// -------------------------------------------------- // - class btContactSolverInfoDoubleData - { - public: - double m_tau; - double m_damping; - double m_friction; - double m_timeStep; - double m_restitution; - double m_maxErrorReduction; - double m_sor; - double m_erp; - double m_erp2; - double m_globalCfm; - double m_splitImpulsePenetrationThreshold; - double m_splitImpulseTurnErp; - double m_linearSlop; - double m_warmstartingFactor; - double m_maxGyroscopicForce; - double m_singleAxisRollingFrictionThreshold; - int m_numIterations; - int m_solverMode; - int m_restingContactRestitutionThreshold; - int m_minimumSolverBatchSize; - int m_splitImpulse; - char m_padding[4]; - }; - - -// -------------------------------------------------- // - class btContactSolverInfoFloatData - { - public: - float m_tau; - float m_damping; - float m_friction; - float m_timeStep; - float m_restitution; - float m_maxErrorReduction; - float m_sor; - float m_erp; - float m_erp2; - float m_globalCfm; - float m_splitImpulsePenetrationThreshold; - float m_splitImpulseTurnErp; - float m_linearSlop; - float m_warmstartingFactor; - float m_maxGyroscopicForce; - float m_singleAxisRollingFrictionThreshold; - int m_numIterations; - int m_solverMode; - int m_restingContactRestitutionThreshold; - int m_minimumSolverBatchSize; - int m_splitImpulse; - char m_padding[4]; - }; - - -// -------------------------------------------------- // - class btDynamicsWorldDoubleData - { - public: - btContactSolverInfoDoubleData m_solverInfo; - btVector3DoubleData m_gravity; - }; - - -// -------------------------------------------------- // - class btDynamicsWorldFloatData - { - public: - btContactSolverInfoFloatData m_solverInfo; - btVector3FloatData m_gravity; - }; - - -// -------------------------------------------------- // - class btRigidBodyFloatData - { - public: - btCollisionObjectFloatData m_collisionObjectData; - btMatrix3x3FloatData m_invInertiaTensorWorld; - btVector3FloatData m_linearVelocity; - btVector3FloatData m_angularVelocity; - btVector3FloatData m_angularFactor; - btVector3FloatData m_linearFactor; - btVector3FloatData m_gravity; - btVector3FloatData m_gravity_acceleration; - btVector3FloatData m_invInertiaLocal; - btVector3FloatData m_totalForce; - btVector3FloatData m_totalTorque; - float m_inverseMass; - float m_linearDamping; - float m_angularDamping; - float m_additionalDampingFactor; - float m_additionalLinearDampingThresholdSqr; - float m_additionalAngularDampingThresholdSqr; - float m_additionalAngularDampingFactor; - float m_linearSleepingThreshold; - float m_angularSleepingThreshold; - int m_additionalDamping; - }; - - -// -------------------------------------------------- // - class btRigidBodyDoubleData - { - public: - btCollisionObjectDoubleData m_collisionObjectData; - btMatrix3x3DoubleData m_invInertiaTensorWorld; - btVector3DoubleData m_linearVelocity; - btVector3DoubleData m_angularVelocity; - btVector3DoubleData m_angularFactor; - btVector3DoubleData m_linearFactor; - btVector3DoubleData m_gravity; - btVector3DoubleData m_gravity_acceleration; - btVector3DoubleData m_invInertiaLocal; - btVector3DoubleData m_totalForce; - btVector3DoubleData m_totalTorque; - double m_inverseMass; - double m_linearDamping; - double m_angularDamping; - double m_additionalDampingFactor; - double m_additionalLinearDampingThresholdSqr; - double m_additionalAngularDampingThresholdSqr; - double m_additionalAngularDampingFactor; - double m_linearSleepingThreshold; - double m_angularSleepingThreshold; - int m_additionalDamping; - char m_padding[4]; - }; - - -// -------------------------------------------------- // - class btConstraintInfo1 - { - public: - int m_numConstraintRows; - int nub; - }; - - -// -------------------------------------------------- // - class btTypedConstraintFloatData - { - public: - btRigidBodyFloatData *m_rbA; - btRigidBodyFloatData *m_rbB; - char *m_name; - int m_objectType; - int m_userConstraintType; - int m_userConstraintId; - int m_needsFeedback; - float m_appliedImpulse; - float m_dbgDrawSize; - int m_disableCollisionsBetweenLinkedBodies; - int m_overrideNumSolverIterations; - float m_breakingImpulseThreshold; - int m_isEnabled; - }; - - -// -------------------------------------------------- // - class btTypedConstraintData - { - public: - bInvalidHandle *m_rbA; - bInvalidHandle *m_rbB; - char *m_name; - int m_objectType; - int m_userConstraintType; - int m_userConstraintId; - int m_needsFeedback; - float m_appliedImpulse; - float m_dbgDrawSize; - int m_disableCollisionsBetweenLinkedBodies; - int m_overrideNumSolverIterations; - float m_breakingImpulseThreshold; - int m_isEnabled; - }; - - -// -------------------------------------------------- // - class btTypedConstraintDoubleData - { - public: - btRigidBodyDoubleData *m_rbA; - btRigidBodyDoubleData *m_rbB; - char *m_name; - int m_objectType; - int m_userConstraintType; - int m_userConstraintId; - int m_needsFeedback; - double m_appliedImpulse; - double m_dbgDrawSize; - int m_disableCollisionsBetweenLinkedBodies; - int m_overrideNumSolverIterations; - double m_breakingImpulseThreshold; - int m_isEnabled; - char padding[4]; - }; - - -// -------------------------------------------------- // - class btPoint2PointConstraintFloatData - { - public: - btTypedConstraintData m_typeConstraintData; - btVector3FloatData m_pivotInA; - btVector3FloatData m_pivotInB; - }; - - -// -------------------------------------------------- // - class btPoint2PointConstraintDoubleData2 - { - public: - btTypedConstraintDoubleData m_typeConstraintData; - btVector3DoubleData m_pivotInA; - btVector3DoubleData m_pivotInB; - }; - - -// -------------------------------------------------- // - class btPoint2PointConstraintDoubleData - { - public: - btTypedConstraintData m_typeConstraintData; - btVector3DoubleData m_pivotInA; - btVector3DoubleData m_pivotInB; - }; - - -// -------------------------------------------------- // - class btHingeConstraintDoubleData - { - public: - btTypedConstraintData m_typeConstraintData; - btTransformDoubleData m_rbAFrame; - btTransformDoubleData m_rbBFrame; - int m_useReferenceFrameA; - int m_angularOnly; - int m_enableAngularMotor; - float m_motorTargetVelocity; - float m_maxMotorImpulse; - float m_lowerLimit; - float m_upperLimit; - float m_limitSoftness; - float m_biasFactor; - float m_relaxationFactor; - }; - - -// -------------------------------------------------- // - class btHingeConstraintFloatData - { - public: - btTypedConstraintData m_typeConstraintData; - btTransformFloatData m_rbAFrame; - btTransformFloatData m_rbBFrame; - int m_useReferenceFrameA; - int m_angularOnly; - int m_enableAngularMotor; - float m_motorTargetVelocity; - float m_maxMotorImpulse; - float m_lowerLimit; - float m_upperLimit; - float m_limitSoftness; - float m_biasFactor; - float m_relaxationFactor; - }; - - -// -------------------------------------------------- // - class btHingeConstraintDoubleData2 - { - public: - btTypedConstraintDoubleData m_typeConstraintData; - btTransformDoubleData m_rbAFrame; - btTransformDoubleData m_rbBFrame; - int m_useReferenceFrameA; - int m_angularOnly; - int m_enableAngularMotor; - double m_motorTargetVelocity; - double m_maxMotorImpulse; - double m_lowerLimit; - double m_upperLimit; - double m_limitSoftness; - double m_biasFactor; - double m_relaxationFactor; - char m_padding1[4]; - }; - - -// -------------------------------------------------- // - class btConeTwistConstraintDoubleData - { - public: - btTypedConstraintDoubleData m_typeConstraintData; - btTransformDoubleData m_rbAFrame; - btTransformDoubleData m_rbBFrame; - double m_swingSpan1; - double m_swingSpan2; - double m_twistSpan; - double m_limitSoftness; - double m_biasFactor; - double m_relaxationFactor; - double m_damping; - }; - - -// -------------------------------------------------- // - class btConeTwistConstraintData - { - public: - btTypedConstraintData m_typeConstraintData; - btTransformFloatData m_rbAFrame; - btTransformFloatData m_rbBFrame; - float m_swingSpan1; - float m_swingSpan2; - float m_twistSpan; - float m_limitSoftness; - float m_biasFactor; - float m_relaxationFactor; - float m_damping; - char m_pad[4]; - }; - - -// -------------------------------------------------- // - class btGeneric6DofConstraintData - { - public: - btTypedConstraintData m_typeConstraintData; - btTransformFloatData m_rbAFrame; - btTransformFloatData m_rbBFrame; - btVector3FloatData m_linearUpperLimit; - btVector3FloatData m_linearLowerLimit; - btVector3FloatData m_angularUpperLimit; - btVector3FloatData m_angularLowerLimit; - int m_useLinearReferenceFrameA; - int m_useOffsetForConstraintFrame; - }; - - -// -------------------------------------------------- // - class btGeneric6DofConstraintDoubleData2 - { - public: - btTypedConstraintDoubleData m_typeConstraintData; - btTransformDoubleData m_rbAFrame; - btTransformDoubleData m_rbBFrame; - btVector3DoubleData m_linearUpperLimit; - btVector3DoubleData m_linearLowerLimit; - btVector3DoubleData m_angularUpperLimit; - btVector3DoubleData m_angularLowerLimit; - int m_useLinearReferenceFrameA; - int m_useOffsetForConstraintFrame; - }; - - -// -------------------------------------------------- // - class btGeneric6DofSpringConstraintData - { - public: - btGeneric6DofConstraintData m_6dofData; - int m_springEnabled[6]; - float m_equilibriumPoint[6]; - float m_springStiffness[6]; - float m_springDamping[6]; - }; - - -// -------------------------------------------------- // - class btGeneric6DofSpringConstraintDoubleData2 - { - public: - btGeneric6DofConstraintDoubleData2 m_6dofData; - int m_springEnabled[6]; - double m_equilibriumPoint[6]; - double m_springStiffness[6]; - double m_springDamping[6]; - }; - - -// -------------------------------------------------- // - class btGeneric6DofSpring2ConstraintData - { - public: - btTypedConstraintData m_typeConstraintData; - btTransformFloatData m_rbAFrame; - btTransformFloatData m_rbBFrame; - btVector3FloatData m_linearUpperLimit; - btVector3FloatData m_linearLowerLimit; - btVector3FloatData m_linearBounce; - btVector3FloatData m_linearStopERP; - btVector3FloatData m_linearStopCFM; - btVector3FloatData m_linearMotorERP; - btVector3FloatData m_linearMotorCFM; - btVector3FloatData m_linearTargetVelocity; - btVector3FloatData m_linearMaxMotorForce; - btVector3FloatData m_linearServoTarget; - btVector3FloatData m_linearSpringStiffness; - btVector3FloatData m_linearSpringDamping; - btVector3FloatData m_linearEquilibriumPoint; - char m_linearEnableMotor[4]; - char m_linearServoMotor[4]; - char m_linearEnableSpring[4]; - char m_linearSpringStiffnessLimited[4]; - char m_linearSpringDampingLimited[4]; - char m_padding1[4]; - btVector3FloatData m_angularUpperLimit; - btVector3FloatData m_angularLowerLimit; - btVector3FloatData m_angularBounce; - btVector3FloatData m_angularStopERP; - btVector3FloatData m_angularStopCFM; - btVector3FloatData m_angularMotorERP; - btVector3FloatData m_angularMotorCFM; - btVector3FloatData m_angularTargetVelocity; - btVector3FloatData m_angularMaxMotorForce; - btVector3FloatData m_angularServoTarget; - btVector3FloatData m_angularSpringStiffness; - btVector3FloatData m_angularSpringDamping; - btVector3FloatData m_angularEquilibriumPoint; - char m_angularEnableMotor[4]; - char m_angularServoMotor[4]; - char m_angularEnableSpring[4]; - char m_angularSpringStiffnessLimited[4]; - char m_angularSpringDampingLimited[4]; - int m_rotateOrder; - }; - - -// -------------------------------------------------- // - class btGeneric6DofSpring2ConstraintDoubleData2 - { - public: - btTypedConstraintDoubleData m_typeConstraintData; - btTransformDoubleData m_rbAFrame; - btTransformDoubleData m_rbBFrame; - btVector3DoubleData m_linearUpperLimit; - btVector3DoubleData m_linearLowerLimit; - btVector3DoubleData m_linearBounce; - btVector3DoubleData m_linearStopERP; - btVector3DoubleData m_linearStopCFM; - btVector3DoubleData m_linearMotorERP; - btVector3DoubleData m_linearMotorCFM; - btVector3DoubleData m_linearTargetVelocity; - btVector3DoubleData m_linearMaxMotorForce; - btVector3DoubleData m_linearServoTarget; - btVector3DoubleData m_linearSpringStiffness; - btVector3DoubleData m_linearSpringDamping; - btVector3DoubleData m_linearEquilibriumPoint; - char m_linearEnableMotor[4]; - char m_linearServoMotor[4]; - char m_linearEnableSpring[4]; - char m_linearSpringStiffnessLimited[4]; - char m_linearSpringDampingLimited[4]; - char m_padding1[4]; - btVector3DoubleData m_angularUpperLimit; - btVector3DoubleData m_angularLowerLimit; - btVector3DoubleData m_angularBounce; - btVector3DoubleData m_angularStopERP; - btVector3DoubleData m_angularStopCFM; - btVector3DoubleData m_angularMotorERP; - btVector3DoubleData m_angularMotorCFM; - btVector3DoubleData m_angularTargetVelocity; - btVector3DoubleData m_angularMaxMotorForce; - btVector3DoubleData m_angularServoTarget; - btVector3DoubleData m_angularSpringStiffness; - btVector3DoubleData m_angularSpringDamping; - btVector3DoubleData m_angularEquilibriumPoint; - char m_angularEnableMotor[4]; - char m_angularServoMotor[4]; - char m_angularEnableSpring[4]; - char m_angularSpringStiffnessLimited[4]; - char m_angularSpringDampingLimited[4]; - int m_rotateOrder; - }; - - -// -------------------------------------------------- // - class btSliderConstraintData - { - public: - btTypedConstraintData m_typeConstraintData; - btTransformFloatData m_rbAFrame; - btTransformFloatData m_rbBFrame; - float m_linearUpperLimit; - float m_linearLowerLimit; - float m_angularUpperLimit; - float m_angularLowerLimit; - int m_useLinearReferenceFrameA; - int m_useOffsetForConstraintFrame; - }; - - -// -------------------------------------------------- // - class btSliderConstraintDoubleData - { - public: - btTypedConstraintDoubleData m_typeConstraintData; - btTransformDoubleData m_rbAFrame; - btTransformDoubleData m_rbBFrame; - double m_linearUpperLimit; - double m_linearLowerLimit; - double m_angularUpperLimit; - double m_angularLowerLimit; - int m_useLinearReferenceFrameA; - int m_useOffsetForConstraintFrame; - }; - - -// -------------------------------------------------- // - class btGearConstraintFloatData - { - public: - btTypedConstraintFloatData m_typeConstraintData; - btVector3FloatData m_axisInA; - btVector3FloatData m_axisInB; - float m_ratio; - char m_padding[4]; - }; - - -// -------------------------------------------------- // - class btGearConstraintDoubleData - { - public: - btTypedConstraintDoubleData m_typeConstraintData; - btVector3DoubleData m_axisInA; - btVector3DoubleData m_axisInB; - double m_ratio; - }; - - -// -------------------------------------------------- // - class SoftBodyMaterialData - { - public: - float m_linearStiffness; - float m_angularStiffness; - float m_volumeStiffness; - int m_flags; - }; - - -// -------------------------------------------------- // - class SoftBodyNodeData - { - public: - SoftBodyMaterialData *m_material; - btVector3FloatData m_position; - btVector3FloatData m_previousPosition; - btVector3FloatData m_velocity; - btVector3FloatData m_accumulatedForce; - btVector3FloatData m_normal; - float m_inverseMass; - float m_area; - int m_attach; - int m_pad; - }; - - -// -------------------------------------------------- // - class SoftBodyLinkData - { - public: - SoftBodyMaterialData *m_material; - int m_nodeIndices[2]; - float m_restLength; - int m_bbending; - }; - - -// -------------------------------------------------- // - class SoftBodyFaceData - { - public: - btVector3FloatData m_normal; - SoftBodyMaterialData *m_material; - int m_nodeIndices[3]; - float m_restArea; - }; - - -// -------------------------------------------------- // - class SoftBodyTetraData - { - public: - btVector3FloatData m_c0[4]; - SoftBodyMaterialData *m_material; - int m_nodeIndices[4]; - float m_restVolume; - float m_c1; - float m_c2; - int m_pad; - }; - - -// -------------------------------------------------- // - class SoftRigidAnchorData - { - public: - btMatrix3x3FloatData m_c0; - btVector3FloatData m_c1; - btVector3FloatData m_localFrame; - bInvalidHandle *m_rigidBody; - int m_nodeIndex; - float m_c2; - }; - - -// -------------------------------------------------- // - class SoftBodyConfigData - { - public: - int m_aeroModel; - float m_baumgarte; - float m_damping; - float m_drag; - float m_lift; - float m_pressure; - float m_volume; - float m_dynamicFriction; - float m_poseMatch; - float m_rigidContactHardness; - float m_kineticContactHardness; - float m_softContactHardness; - float m_anchorHardness; - float m_softRigidClusterHardness; - float m_softKineticClusterHardness; - float m_softSoftClusterHardness; - float m_softRigidClusterImpulseSplit; - float m_softKineticClusterImpulseSplit; - float m_softSoftClusterImpulseSplit; - float m_maxVolume; - float m_timeScale; - int m_velocityIterations; - int m_positionIterations; - int m_driftIterations; - int m_clusterIterations; - int m_collisionFlags; - }; - - -// -------------------------------------------------- // - class SoftBodyPoseData - { - public: - btMatrix3x3FloatData m_rot; - btMatrix3x3FloatData m_scale; - btMatrix3x3FloatData m_aqq; - btVector3FloatData m_com; - btVector3FloatData *m_positions; - float *m_weights; - int m_numPositions; - int m_numWeigts; - int m_bvolume; - int m_bframe; - float m_restVolume; - int m_pad; - }; - - -// -------------------------------------------------- // - class SoftBodyClusterData - { - public: - btTransformFloatData m_framexform; - btMatrix3x3FloatData m_locii; - btMatrix3x3FloatData m_invwi; - btVector3FloatData m_com; - btVector3FloatData m_vimpulses[2]; - btVector3FloatData m_dimpulses[2]; - btVector3FloatData m_lv; - btVector3FloatData m_av; - btVector3FloatData *m_framerefs; - int *m_nodeIndices; - float *m_masses; - int m_numFrameRefs; - int m_numNodes; - int m_numMasses; - float m_idmass; - float m_imass; - int m_nvimpulses; - int m_ndimpulses; - float m_ndamping; - float m_ldamping; - float m_adamping; - float m_matching; - float m_maxSelfCollisionImpulse; - float m_selfCollisionImpulseFactor; - int m_containsAnchor; - int m_collide; - int m_clusterIndex; - }; - - -// -------------------------------------------------- // - class btSoftBodyJointData - { - public: - void *m_bodyA; - void *m_bodyB; - btVector3FloatData m_refs[2]; - float m_cfm; - float m_erp; - float m_split; - int m_delete; - btVector3FloatData m_relPosition[2]; - int m_bodyAtype; - int m_bodyBtype; - int m_jointType; - int m_pad; - }; - - -// -------------------------------------------------- // - class btSoftBodyFloatData - { - public: - btCollisionObjectFloatData m_collisionObjectData; - SoftBodyPoseData *m_pose; - SoftBodyMaterialData **m_materials; - SoftBodyNodeData *m_nodes; - SoftBodyLinkData *m_links; - SoftBodyFaceData *m_faces; - SoftBodyTetraData *m_tetrahedra; - SoftRigidAnchorData *m_anchors; - SoftBodyClusterData *m_clusters; - btSoftBodyJointData *m_joints; - int m_numMaterials; - int m_numNodes; - int m_numLinks; - int m_numFaces; - int m_numTetrahedra; - int m_numAnchors; - int m_numClusters; - int m_numJoints; - SoftBodyConfigData m_config; - }; - - -// -------------------------------------------------- // - class btMultiBodyLinkDoubleData - { - public: - btQuaternionDoubleData m_zeroRotParentToThis; - btVector3DoubleData m_parentComToThisPivotOffset; - btVector3DoubleData m_thisPivotToThisComOffset; - btVector3DoubleData m_jointAxisTop[6]; - btVector3DoubleData m_jointAxisBottom[6]; - btVector3DoubleData m_linkInertia; - btVector3DoubleData m_absFrameTotVelocityTop; - btVector3DoubleData m_absFrameTotVelocityBottom; - btVector3DoubleData m_absFrameLocVelocityTop; - btVector3DoubleData m_absFrameLocVelocityBottom; - double m_linkMass; - int m_parentIndex; - int m_jointType; - int m_dofCount; - int m_posVarCount; - double m_jointPos[7]; - double m_jointVel[6]; - double m_jointTorque[6]; - double m_jointDamping; - double m_jointFriction; - double m_jointLowerLimit; - double m_jointUpperLimit; - double m_jointMaxForce; - double m_jointMaxVelocity; - char *m_linkName; - char *m_jointName; - btCollisionObjectDoubleData *m_linkCollider; - char *m_paddingPtr; - }; - - -// -------------------------------------------------- // - class btMultiBodyLinkFloatData - { - public: - btQuaternionFloatData m_zeroRotParentToThis; - btVector3FloatData m_parentComToThisPivotOffset; - btVector3FloatData m_thisPivotToThisComOffset; - btVector3FloatData m_jointAxisTop[6]; - btVector3FloatData m_jointAxisBottom[6]; - btVector3FloatData m_linkInertia; - btVector3FloatData m_absFrameTotVelocityTop; - btVector3FloatData m_absFrameTotVelocityBottom; - btVector3FloatData m_absFrameLocVelocityTop; - btVector3FloatData m_absFrameLocVelocityBottom; - int m_dofCount; - float m_linkMass; - int m_parentIndex; - int m_jointType; - float m_jointPos[7]; - float m_jointVel[6]; - float m_jointTorque[6]; - int m_posVarCount; - float m_jointDamping; - float m_jointFriction; - float m_jointLowerLimit; - float m_jointUpperLimit; - float m_jointMaxForce; - float m_jointMaxVelocity; - char *m_linkName; - char *m_jointName; - btCollisionObjectFloatData *m_linkCollider; - char *m_paddingPtr; - }; - - -// -------------------------------------------------- // - class btMultiBodyDoubleData - { - public: - btVector3DoubleData m_baseWorldPosition; - btQuaternionDoubleData m_baseWorldOrientation; - btVector3DoubleData m_baseLinearVelocity; - btVector3DoubleData m_baseAngularVelocity; - btVector3DoubleData m_baseInertia; - double m_baseMass; - int m_numLinks; - char m_padding[4]; - char *m_baseName; - btMultiBodyLinkDoubleData *m_links; - btCollisionObjectDoubleData *m_baseCollider; - }; - - -// -------------------------------------------------- // - class btMultiBodyFloatData - { - public: - btVector3FloatData m_baseWorldPosition; - btQuaternionFloatData m_baseWorldOrientation; - btVector3FloatData m_baseLinearVelocity; - btVector3FloatData m_baseAngularVelocity; - btVector3FloatData m_baseInertia; - float m_baseMass; - int m_numLinks; - char *m_baseName; - btMultiBodyLinkFloatData *m_links; - btCollisionObjectFloatData *m_baseCollider; - }; - - -// -------------------------------------------------- // - class btMultiBodyLinkColliderFloatData - { - public: - btCollisionObjectFloatData m_colObjData; - btMultiBodyFloatData *m_multiBody; - int m_link; - char m_padding[4]; - }; - - -// -------------------------------------------------- // - class btMultiBodyLinkColliderDoubleData - { - public: - btCollisionObjectDoubleData m_colObjData; - btMultiBodyDoubleData *m_multiBody; - int m_link; - char m_padding[4]; - }; - - -} -#endif//__BULLET_H__ \ No newline at end of file +} bInvalidHandle; + +class PointerArray; +class btPhysicsSystem; +class ListBase; +class btVector3FloatData; +class btVector3DoubleData; +class btQuaternionFloatData; +class btQuaternionDoubleData; +class btMatrix3x3FloatData; +class btMatrix3x3DoubleData; +class btTransformFloatData; +class btTransformDoubleData; +class btBvhSubtreeInfoData; +class btOptimizedBvhNodeFloatData; +class btOptimizedBvhNodeDoubleData; +class btQuantizedBvhNodeData; +class btQuantizedBvhFloatData; +class btQuantizedBvhDoubleData; +class btCollisionShapeData; +class btStaticPlaneShapeData; +class btConvexInternalShapeData; +class btPositionAndRadius; +class btMultiSphereShapeData; +class btIntIndexData; +class btShortIntIndexData; +class btShortIntIndexTripletData; +class btCharIndexTripletData; +class btMeshPartData; +class btStridingMeshInterfaceData; +class btTriangleMeshShapeData; +class btScaledTriangleMeshShapeData; +class btCompoundShapeChildData; +class btCompoundShapeData; +class btCylinderShapeData; +class btConeShapeData; +class btCapsuleShapeData; +class btTriangleInfoData; +class btTriangleInfoMapData; +class btPersistentManifoldDoubleData; +class btPersistentManifoldFloatData; +class btGImpactMeshShapeData; +class btConvexHullShapeData; +class btCollisionObjectDoubleData; +class btCollisionObjectFloatData; +class btContactSolverInfoDoubleData; +class btContactSolverInfoFloatData; +class btDynamicsWorldDoubleData; +class btDynamicsWorldFloatData; +class btRigidBodyFloatData; +class btRigidBodyDoubleData; +class btConstraintInfo1; +class btTypedConstraintFloatData; +class btTypedConstraintData; +class btTypedConstraintDoubleData; +class btPoint2PointConstraintFloatData; +class btPoint2PointConstraintDoubleData2; +class btPoint2PointConstraintDoubleData; +class btHingeConstraintDoubleData; +class btHingeConstraintFloatData; +class btHingeConstraintDoubleData2; +class btConeTwistConstraintDoubleData; +class btConeTwistConstraintData; +class btGeneric6DofConstraintData; +class btGeneric6DofConstraintDoubleData2; +class btGeneric6DofSpringConstraintData; +class btGeneric6DofSpringConstraintDoubleData2; +class btGeneric6DofSpring2ConstraintData; +class btGeneric6DofSpring2ConstraintDoubleData2; +class btSliderConstraintData; +class btSliderConstraintDoubleData; +class btGearConstraintFloatData; +class btGearConstraintDoubleData; +class SoftBodyMaterialData; +class SoftBodyNodeData; +class SoftBodyLinkData; +class SoftBodyFaceData; +class SoftBodyTetraData; +class SoftRigidAnchorData; +class SoftBodyConfigData; +class SoftBodyPoseData; +class SoftBodyClusterData; +class btSoftBodyJointData; +class btSoftBodyFloatData; +class btMultiBodyLinkDoubleData; +class btMultiBodyLinkFloatData; +class btMultiBodyDoubleData; +class btMultiBodyFloatData; +class btMultiBodyLinkColliderFloatData; +class btMultiBodyLinkColliderDoubleData; +// -------------------------------------------------- // +class PointerArray +{ +public: + int m_size; + int m_capacity; + void *m_data; +}; + +// -------------------------------------------------- // +class btPhysicsSystem +{ +public: + PointerArray m_collisionShapes; + PointerArray m_collisionObjects; + PointerArray m_constraints; +}; + +// -------------------------------------------------- // +class ListBase +{ +public: + void *first; + void *last; +}; + +// -------------------------------------------------- // +class btVector3FloatData +{ +public: + float m_floats[4]; +}; + +// -------------------------------------------------- // +class btVector3DoubleData +{ +public: + double m_floats[4]; +}; + +// -------------------------------------------------- // +class btQuaternionFloatData +{ +public: + float m_floats[4]; +}; + +// -------------------------------------------------- // +class btQuaternionDoubleData +{ +public: + double m_floats[4]; +}; + +// -------------------------------------------------- // +class btMatrix3x3FloatData +{ +public: + btVector3FloatData m_el[3]; +}; + +// -------------------------------------------------- // +class btMatrix3x3DoubleData +{ +public: + btVector3DoubleData m_el[3]; +}; + +// -------------------------------------------------- // +class btTransformFloatData +{ +public: + btMatrix3x3FloatData m_basis; + btVector3FloatData m_origin; +}; + +// -------------------------------------------------- // +class btTransformDoubleData +{ +public: + btMatrix3x3DoubleData m_basis; + btVector3DoubleData m_origin; +}; + +// -------------------------------------------------- // +class btBvhSubtreeInfoData +{ +public: + int m_rootNodeIndex; + int m_subtreeSize; + short m_quantizedAabbMin[3]; + short m_quantizedAabbMax[3]; +}; + +// -------------------------------------------------- // +class btOptimizedBvhNodeFloatData +{ +public: + btVector3FloatData m_aabbMinOrg; + btVector3FloatData m_aabbMaxOrg; + int m_escapeIndex; + int m_subPart; + int m_triangleIndex; + char m_pad[4]; +}; + +// -------------------------------------------------- // +class btOptimizedBvhNodeDoubleData +{ +public: + btVector3DoubleData m_aabbMinOrg; + btVector3DoubleData m_aabbMaxOrg; + int m_escapeIndex; + int m_subPart; + int m_triangleIndex; + char m_pad[4]; +}; + +// -------------------------------------------------- // +class btQuantizedBvhNodeData +{ +public: + short m_quantizedAabbMin[3]; + short m_quantizedAabbMax[3]; + int m_escapeIndexOrTriangleIndex; +}; + +// -------------------------------------------------- // +class btQuantizedBvhFloatData +{ +public: + btVector3FloatData m_bvhAabbMin; + btVector3FloatData m_bvhAabbMax; + btVector3FloatData m_bvhQuantization; + int m_curNodeIndex; + int m_useQuantization; + int m_numContiguousLeafNodes; + int m_numQuantizedContiguousNodes; + btOptimizedBvhNodeFloatData *m_contiguousNodesPtr; + btQuantizedBvhNodeData *m_quantizedContiguousNodesPtr; + btBvhSubtreeInfoData *m_subTreeInfoPtr; + int m_traversalMode; + int m_numSubtreeHeaders; +}; + +// -------------------------------------------------- // +class btQuantizedBvhDoubleData +{ +public: + btVector3DoubleData m_bvhAabbMin; + btVector3DoubleData m_bvhAabbMax; + btVector3DoubleData m_bvhQuantization; + int m_curNodeIndex; + int m_useQuantization; + int m_numContiguousLeafNodes; + int m_numQuantizedContiguousNodes; + btOptimizedBvhNodeDoubleData *m_contiguousNodesPtr; + btQuantizedBvhNodeData *m_quantizedContiguousNodesPtr; + int m_traversalMode; + int m_numSubtreeHeaders; + btBvhSubtreeInfoData *m_subTreeInfoPtr; +}; + +// -------------------------------------------------- // +class btCollisionShapeData +{ +public: + char *m_name; + int m_shapeType; + char m_padding[4]; +}; + +// -------------------------------------------------- // +class btStaticPlaneShapeData +{ +public: + btCollisionShapeData m_collisionShapeData; + btVector3FloatData m_localScaling; + btVector3FloatData m_planeNormal; + float m_planeConstant; + char m_pad[4]; +}; + +// -------------------------------------------------- // +class btConvexInternalShapeData +{ +public: + btCollisionShapeData m_collisionShapeData; + btVector3FloatData m_localScaling; + btVector3FloatData m_implicitShapeDimensions; + float m_collisionMargin; + int m_padding; +}; + +// -------------------------------------------------- // +class btPositionAndRadius +{ +public: + btVector3FloatData m_pos; + float m_radius; +}; + +// -------------------------------------------------- // +class btMultiSphereShapeData +{ +public: + btConvexInternalShapeData m_convexInternalShapeData; + btPositionAndRadius *m_localPositionArrayPtr; + int m_localPositionArraySize; + char m_padding[4]; +}; + +// -------------------------------------------------- // +class btIntIndexData +{ +public: + int m_value; +}; + +// -------------------------------------------------- // +class btShortIntIndexData +{ +public: + short m_value; + char m_pad[2]; +}; + +// -------------------------------------------------- // +class btShortIntIndexTripletData +{ +public: + short m_values[3]; + char m_pad[2]; +}; + +// -------------------------------------------------- // +class btCharIndexTripletData +{ +public: + char m_values[3]; + char m_pad; +}; + +// -------------------------------------------------- // +class btMeshPartData +{ +public: + btVector3FloatData *m_vertices3f; + btVector3DoubleData *m_vertices3d; + btIntIndexData *m_indices32; + btShortIntIndexTripletData *m_3indices16; + btCharIndexTripletData *m_3indices8; + btShortIntIndexData *m_indices16; + int m_numTriangles; + int m_numVertices; +}; + +// -------------------------------------------------- // +class btStridingMeshInterfaceData +{ +public: + btMeshPartData *m_meshPartsPtr; + btVector3FloatData m_scaling; + int m_numMeshParts; + char m_padding[4]; +}; + +// -------------------------------------------------- // +class btTriangleMeshShapeData +{ +public: + btCollisionShapeData m_collisionShapeData; + btStridingMeshInterfaceData m_meshInterface; + btQuantizedBvhFloatData *m_quantizedFloatBvh; + btQuantizedBvhDoubleData *m_quantizedDoubleBvh; + btTriangleInfoMapData *m_triangleInfoMap; + float m_collisionMargin; + char m_pad3[4]; +}; + +// -------------------------------------------------- // +class btScaledTriangleMeshShapeData +{ +public: + btTriangleMeshShapeData m_trimeshShapeData; + btVector3FloatData m_localScaling; +}; + +// -------------------------------------------------- // +class btCompoundShapeChildData +{ +public: + btTransformFloatData m_transform; + btCollisionShapeData *m_childShape; + int m_childShapeType; + float m_childMargin; +}; + +// -------------------------------------------------- // +class btCompoundShapeData +{ +public: + btCollisionShapeData m_collisionShapeData; + btCompoundShapeChildData *m_childShapePtr; + int m_numChildShapes; + float m_collisionMargin; +}; + +// -------------------------------------------------- // +class btCylinderShapeData +{ +public: + btConvexInternalShapeData m_convexInternalShapeData; + int m_upAxis; + char m_padding[4]; +}; + +// -------------------------------------------------- // +class btConeShapeData +{ +public: + btConvexInternalShapeData m_convexInternalShapeData; + int m_upIndex; + char m_padding[4]; +}; + +// -------------------------------------------------- // +class btCapsuleShapeData +{ +public: + btConvexInternalShapeData m_convexInternalShapeData; + int m_upAxis; + char m_padding[4]; +}; + +// -------------------------------------------------- // +class btTriangleInfoData +{ +public: + int m_flags; + float m_edgeV0V1Angle; + float m_edgeV1V2Angle; + float m_edgeV2V0Angle; +}; + +// -------------------------------------------------- // +class btTriangleInfoMapData +{ +public: + int *m_hashTablePtr; + int *m_nextPtr; + btTriangleInfoData *m_valueArrayPtr; + int *m_keyArrayPtr; + float m_convexEpsilon; + float m_planarEpsilon; + float m_equalVertexThreshold; + float m_edgeDistanceThreshold; + float m_zeroAreaThreshold; + int m_nextSize; + int m_hashTableSize; + int m_numValues; + int m_numKeys; + char m_padding[4]; +}; + +// -------------------------------------------------- // +class btPersistentManifoldDoubleData +{ +public: + btVector3DoubleData m_pointCacheLocalPointA[4]; + btVector3DoubleData m_pointCacheLocalPointB[4]; + btVector3DoubleData m_pointCachePositionWorldOnA[4]; + btVector3DoubleData m_pointCachePositionWorldOnB[4]; + btVector3DoubleData m_pointCacheNormalWorldOnB[4]; + btVector3DoubleData m_pointCacheLateralFrictionDir1[4]; + btVector3DoubleData m_pointCacheLateralFrictionDir2[4]; + double m_pointCacheDistance[4]; + double m_pointCacheAppliedImpulse[4]; + double m_pointCacheCombinedFriction[4]; + double m_pointCacheCombinedRollingFriction[4]; + double m_pointCacheCombinedSpinningFriction[4]; + double m_pointCacheCombinedRestitution[4]; + int m_pointCachePartId0[4]; + int m_pointCachePartId1[4]; + int m_pointCacheIndex0[4]; + int m_pointCacheIndex1[4]; + int m_pointCacheContactPointFlags[4]; + double m_pointCacheAppliedImpulseLateral1[4]; + double m_pointCacheAppliedImpulseLateral2[4]; + double m_pointCacheContactMotion1[4]; + double m_pointCacheContactMotion2[4]; + double m_pointCacheContactCFM[4]; + double m_pointCacheCombinedContactStiffness1[4]; + double m_pointCacheContactERP[4]; + double m_pointCacheCombinedContactDamping1[4]; + double m_pointCacheFrictionCFM[4]; + int m_pointCacheLifeTime[4]; + int m_numCachedPoints; + int m_companionIdA; + int m_companionIdB; + int m_index1a; + int m_objectType; + double m_contactBreakingThreshold; + double m_contactProcessingThreshold; + int m_padding; + btCollisionObjectDoubleData *m_body0; + btCollisionObjectDoubleData *m_body1; +}; + +// -------------------------------------------------- // +class btPersistentManifoldFloatData +{ +public: + btVector3FloatData m_pointCacheLocalPointA[4]; + btVector3FloatData m_pointCacheLocalPointB[4]; + btVector3FloatData m_pointCachePositionWorldOnA[4]; + btVector3FloatData m_pointCachePositionWorldOnB[4]; + btVector3FloatData m_pointCacheNormalWorldOnB[4]; + btVector3FloatData m_pointCacheLateralFrictionDir1[4]; + btVector3FloatData m_pointCacheLateralFrictionDir2[4]; + float m_pointCacheDistance[4]; + float m_pointCacheAppliedImpulse[4]; + float m_pointCacheCombinedFriction[4]; + float m_pointCacheCombinedRollingFriction[4]; + float m_pointCacheCombinedSpinningFriction[4]; + float m_pointCacheCombinedRestitution[4]; + int m_pointCachePartId0[4]; + int m_pointCachePartId1[4]; + int m_pointCacheIndex0[4]; + int m_pointCacheIndex1[4]; + int m_pointCacheContactPointFlags[4]; + float m_pointCacheAppliedImpulseLateral1[4]; + float m_pointCacheAppliedImpulseLateral2[4]; + float m_pointCacheContactMotion1[4]; + float m_pointCacheContactMotion2[4]; + float m_pointCacheContactCFM[4]; + float m_pointCacheCombinedContactStiffness1[4]; + float m_pointCacheContactERP[4]; + float m_pointCacheCombinedContactDamping1[4]; + float m_pointCacheFrictionCFM[4]; + int m_pointCacheLifeTime[4]; + int m_numCachedPoints; + int m_companionIdA; + int m_companionIdB; + int m_index1a; + int m_objectType; + float m_contactBreakingThreshold; + float m_contactProcessingThreshold; + int m_padding; + btCollisionObjectFloatData *m_body0; + btCollisionObjectFloatData *m_body1; +}; + +// -------------------------------------------------- // +class btGImpactMeshShapeData +{ +public: + btCollisionShapeData m_collisionShapeData; + btStridingMeshInterfaceData m_meshInterface; + btVector3FloatData m_localScaling; + float m_collisionMargin; + int m_gimpactSubType; +}; + +// -------------------------------------------------- // +class btConvexHullShapeData +{ +public: + btConvexInternalShapeData m_convexInternalShapeData; + btVector3FloatData *m_unscaledPointsFloatPtr; + btVector3DoubleData *m_unscaledPointsDoublePtr; + int m_numUnscaledPoints; + char m_padding3[4]; +}; + +// -------------------------------------------------- // +class btCollisionObjectDoubleData +{ +public: + void *m_broadphaseHandle; + void *m_collisionShape; + btCollisionShapeData *m_rootCollisionShape; + char *m_name; + btTransformDoubleData m_worldTransform; + btTransformDoubleData m_interpolationWorldTransform; + btVector3DoubleData m_interpolationLinearVelocity; + btVector3DoubleData m_interpolationAngularVelocity; + btVector3DoubleData m_anisotropicFriction; + double m_contactProcessingThreshold; + double m_deactivationTime; + double m_friction; + double m_rollingFriction; + double m_contactDamping; + double m_contactStiffness; + double m_restitution; + double m_hitFraction; + double m_ccdSweptSphereRadius; + double m_ccdMotionThreshold; + int m_hasAnisotropicFriction; + int m_collisionFlags; + int m_islandTag1; + int m_companionId; + int m_activationState1; + int m_internalType; + int m_checkCollideWith; + int m_collisionFilterGroup; + int m_collisionFilterMask; + int m_uniqueId; +}; + +// -------------------------------------------------- // +class btCollisionObjectFloatData +{ +public: + void *m_broadphaseHandle; + void *m_collisionShape; + btCollisionShapeData *m_rootCollisionShape; + char *m_name; + btTransformFloatData m_worldTransform; + btTransformFloatData m_interpolationWorldTransform; + btVector3FloatData m_interpolationLinearVelocity; + btVector3FloatData m_interpolationAngularVelocity; + btVector3FloatData m_anisotropicFriction; + float m_contactProcessingThreshold; + float m_deactivationTime; + float m_friction; + float m_rollingFriction; + float m_contactDamping; + float m_contactStiffness; + float m_restitution; + float m_hitFraction; + float m_ccdSweptSphereRadius; + float m_ccdMotionThreshold; + int m_hasAnisotropicFriction; + int m_collisionFlags; + int m_islandTag1; + int m_companionId; + int m_activationState1; + int m_internalType; + int m_checkCollideWith; + int m_collisionFilterGroup; + int m_collisionFilterMask; + int m_uniqueId; +}; + +// -------------------------------------------------- // +class btContactSolverInfoDoubleData +{ +public: + double m_tau; + double m_damping; + double m_friction; + double m_timeStep; + double m_restitution; + double m_maxErrorReduction; + double m_sor; + double m_erp; + double m_erp2; + double m_globalCfm; + double m_splitImpulsePenetrationThreshold; + double m_splitImpulseTurnErp; + double m_linearSlop; + double m_warmstartingFactor; + double m_maxGyroscopicForce; + double m_singleAxisRollingFrictionThreshold; + int m_numIterations; + int m_solverMode; + int m_restingContactRestitutionThreshold; + int m_minimumSolverBatchSize; + int m_splitImpulse; + char m_padding[4]; +}; + +// -------------------------------------------------- // +class btContactSolverInfoFloatData +{ +public: + float m_tau; + float m_damping; + float m_friction; + float m_timeStep; + float m_restitution; + float m_maxErrorReduction; + float m_sor; + float m_erp; + float m_erp2; + float m_globalCfm; + float m_splitImpulsePenetrationThreshold; + float m_splitImpulseTurnErp; + float m_linearSlop; + float m_warmstartingFactor; + float m_maxGyroscopicForce; + float m_singleAxisRollingFrictionThreshold; + int m_numIterations; + int m_solverMode; + int m_restingContactRestitutionThreshold; + int m_minimumSolverBatchSize; + int m_splitImpulse; + char m_padding[4]; +}; + +// -------------------------------------------------- // +class btDynamicsWorldDoubleData +{ +public: + btContactSolverInfoDoubleData m_solverInfo; + btVector3DoubleData m_gravity; +}; + +// -------------------------------------------------- // +class btDynamicsWorldFloatData +{ +public: + btContactSolverInfoFloatData m_solverInfo; + btVector3FloatData m_gravity; +}; + +// -------------------------------------------------- // +class btRigidBodyFloatData +{ +public: + btCollisionObjectFloatData m_collisionObjectData; + btMatrix3x3FloatData m_invInertiaTensorWorld; + btVector3FloatData m_linearVelocity; + btVector3FloatData m_angularVelocity; + btVector3FloatData m_angularFactor; + btVector3FloatData m_linearFactor; + btVector3FloatData m_gravity; + btVector3FloatData m_gravity_acceleration; + btVector3FloatData m_invInertiaLocal; + btVector3FloatData m_totalForce; + btVector3FloatData m_totalTorque; + float m_inverseMass; + float m_linearDamping; + float m_angularDamping; + float m_additionalDampingFactor; + float m_additionalLinearDampingThresholdSqr; + float m_additionalAngularDampingThresholdSqr; + float m_additionalAngularDampingFactor; + float m_linearSleepingThreshold; + float m_angularSleepingThreshold; + int m_additionalDamping; +}; + +// -------------------------------------------------- // +class btRigidBodyDoubleData +{ +public: + btCollisionObjectDoubleData m_collisionObjectData; + btMatrix3x3DoubleData m_invInertiaTensorWorld; + btVector3DoubleData m_linearVelocity; + btVector3DoubleData m_angularVelocity; + btVector3DoubleData m_angularFactor; + btVector3DoubleData m_linearFactor; + btVector3DoubleData m_gravity; + btVector3DoubleData m_gravity_acceleration; + btVector3DoubleData m_invInertiaLocal; + btVector3DoubleData m_totalForce; + btVector3DoubleData m_totalTorque; + double m_inverseMass; + double m_linearDamping; + double m_angularDamping; + double m_additionalDampingFactor; + double m_additionalLinearDampingThresholdSqr; + double m_additionalAngularDampingThresholdSqr; + double m_additionalAngularDampingFactor; + double m_linearSleepingThreshold; + double m_angularSleepingThreshold; + int m_additionalDamping; + char m_padding[4]; +}; + +// -------------------------------------------------- // +class btConstraintInfo1 +{ +public: + int m_numConstraintRows; + int nub; +}; + +// -------------------------------------------------- // +class btTypedConstraintFloatData +{ +public: + btRigidBodyFloatData *m_rbA; + btRigidBodyFloatData *m_rbB; + char *m_name; + int m_objectType; + int m_userConstraintType; + int m_userConstraintId; + int m_needsFeedback; + float m_appliedImpulse; + float m_dbgDrawSize; + int m_disableCollisionsBetweenLinkedBodies; + int m_overrideNumSolverIterations; + float m_breakingImpulseThreshold; + int m_isEnabled; +}; + +// -------------------------------------------------- // +class btTypedConstraintData +{ +public: + bInvalidHandle *m_rbA; + bInvalidHandle *m_rbB; + char *m_name; + int m_objectType; + int m_userConstraintType; + int m_userConstraintId; + int m_needsFeedback; + float m_appliedImpulse; + float m_dbgDrawSize; + int m_disableCollisionsBetweenLinkedBodies; + int m_overrideNumSolverIterations; + float m_breakingImpulseThreshold; + int m_isEnabled; +}; + +// -------------------------------------------------- // +class btTypedConstraintDoubleData +{ +public: + btRigidBodyDoubleData *m_rbA; + btRigidBodyDoubleData *m_rbB; + char *m_name; + int m_objectType; + int m_userConstraintType; + int m_userConstraintId; + int m_needsFeedback; + double m_appliedImpulse; + double m_dbgDrawSize; + int m_disableCollisionsBetweenLinkedBodies; + int m_overrideNumSolverIterations; + double m_breakingImpulseThreshold; + int m_isEnabled; + char padding[4]; +}; + +// -------------------------------------------------- // +class btPoint2PointConstraintFloatData +{ +public: + btTypedConstraintData m_typeConstraintData; + btVector3FloatData m_pivotInA; + btVector3FloatData m_pivotInB; +}; + +// -------------------------------------------------- // +class btPoint2PointConstraintDoubleData2 +{ +public: + btTypedConstraintDoubleData m_typeConstraintData; + btVector3DoubleData m_pivotInA; + btVector3DoubleData m_pivotInB; +}; + +// -------------------------------------------------- // +class btPoint2PointConstraintDoubleData +{ +public: + btTypedConstraintData m_typeConstraintData; + btVector3DoubleData m_pivotInA; + btVector3DoubleData m_pivotInB; +}; + +// -------------------------------------------------- // +class btHingeConstraintDoubleData +{ +public: + btTypedConstraintData m_typeConstraintData; + btTransformDoubleData m_rbAFrame; + btTransformDoubleData m_rbBFrame; + int m_useReferenceFrameA; + int m_angularOnly; + int m_enableAngularMotor; + float m_motorTargetVelocity; + float m_maxMotorImpulse; + float m_lowerLimit; + float m_upperLimit; + float m_limitSoftness; + float m_biasFactor; + float m_relaxationFactor; +}; + +// -------------------------------------------------- // +class btHingeConstraintFloatData +{ +public: + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; + btTransformFloatData m_rbBFrame; + int m_useReferenceFrameA; + int m_angularOnly; + int m_enableAngularMotor; + float m_motorTargetVelocity; + float m_maxMotorImpulse; + float m_lowerLimit; + float m_upperLimit; + float m_limitSoftness; + float m_biasFactor; + float m_relaxationFactor; +}; + +// -------------------------------------------------- // +class btHingeConstraintDoubleData2 +{ +public: + btTypedConstraintDoubleData m_typeConstraintData; + btTransformDoubleData m_rbAFrame; + btTransformDoubleData m_rbBFrame; + int m_useReferenceFrameA; + int m_angularOnly; + int m_enableAngularMotor; + double m_motorTargetVelocity; + double m_maxMotorImpulse; + double m_lowerLimit; + double m_upperLimit; + double m_limitSoftness; + double m_biasFactor; + double m_relaxationFactor; + char m_padding1[4]; +}; + +// -------------------------------------------------- // +class btConeTwistConstraintDoubleData +{ +public: + btTypedConstraintDoubleData m_typeConstraintData; + btTransformDoubleData m_rbAFrame; + btTransformDoubleData m_rbBFrame; + double m_swingSpan1; + double m_swingSpan2; + double m_twistSpan; + double m_limitSoftness; + double m_biasFactor; + double m_relaxationFactor; + double m_damping; +}; + +// -------------------------------------------------- // +class btConeTwistConstraintData +{ +public: + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; + btTransformFloatData m_rbBFrame; + float m_swingSpan1; + float m_swingSpan2; + float m_twistSpan; + float m_limitSoftness; + float m_biasFactor; + float m_relaxationFactor; + float m_damping; + char m_pad[4]; +}; + +// -------------------------------------------------- // +class btGeneric6DofConstraintData +{ +public: + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; + btTransformFloatData m_rbBFrame; + btVector3FloatData m_linearUpperLimit; + btVector3FloatData m_linearLowerLimit; + btVector3FloatData m_angularUpperLimit; + btVector3FloatData m_angularLowerLimit; + int m_useLinearReferenceFrameA; + int m_useOffsetForConstraintFrame; +}; + +// -------------------------------------------------- // +class btGeneric6DofConstraintDoubleData2 +{ +public: + btTypedConstraintDoubleData m_typeConstraintData; + btTransformDoubleData m_rbAFrame; + btTransformDoubleData m_rbBFrame; + btVector3DoubleData m_linearUpperLimit; + btVector3DoubleData m_linearLowerLimit; + btVector3DoubleData m_angularUpperLimit; + btVector3DoubleData m_angularLowerLimit; + int m_useLinearReferenceFrameA; + int m_useOffsetForConstraintFrame; +}; + +// -------------------------------------------------- // +class btGeneric6DofSpringConstraintData +{ +public: + btGeneric6DofConstraintData m_6dofData; + int m_springEnabled[6]; + float m_equilibriumPoint[6]; + float m_springStiffness[6]; + float m_springDamping[6]; +}; + +// -------------------------------------------------- // +class btGeneric6DofSpringConstraintDoubleData2 +{ +public: + btGeneric6DofConstraintDoubleData2 m_6dofData; + int m_springEnabled[6]; + double m_equilibriumPoint[6]; + double m_springStiffness[6]; + double m_springDamping[6]; +}; + +// -------------------------------------------------- // +class btGeneric6DofSpring2ConstraintData +{ +public: + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; + btTransformFloatData m_rbBFrame; + btVector3FloatData m_linearUpperLimit; + btVector3FloatData m_linearLowerLimit; + btVector3FloatData m_linearBounce; + btVector3FloatData m_linearStopERP; + btVector3FloatData m_linearStopCFM; + btVector3FloatData m_linearMotorERP; + btVector3FloatData m_linearMotorCFM; + btVector3FloatData m_linearTargetVelocity; + btVector3FloatData m_linearMaxMotorForce; + btVector3FloatData m_linearServoTarget; + btVector3FloatData m_linearSpringStiffness; + btVector3FloatData m_linearSpringDamping; + btVector3FloatData m_linearEquilibriumPoint; + char m_linearEnableMotor[4]; + char m_linearServoMotor[4]; + char m_linearEnableSpring[4]; + char m_linearSpringStiffnessLimited[4]; + char m_linearSpringDampingLimited[4]; + char m_padding1[4]; + btVector3FloatData m_angularUpperLimit; + btVector3FloatData m_angularLowerLimit; + btVector3FloatData m_angularBounce; + btVector3FloatData m_angularStopERP; + btVector3FloatData m_angularStopCFM; + btVector3FloatData m_angularMotorERP; + btVector3FloatData m_angularMotorCFM; + btVector3FloatData m_angularTargetVelocity; + btVector3FloatData m_angularMaxMotorForce; + btVector3FloatData m_angularServoTarget; + btVector3FloatData m_angularSpringStiffness; + btVector3FloatData m_angularSpringDamping; + btVector3FloatData m_angularEquilibriumPoint; + char m_angularEnableMotor[4]; + char m_angularServoMotor[4]; + char m_angularEnableSpring[4]; + char m_angularSpringStiffnessLimited[4]; + char m_angularSpringDampingLimited[4]; + int m_rotateOrder; +}; + +// -------------------------------------------------- // +class btGeneric6DofSpring2ConstraintDoubleData2 +{ +public: + btTypedConstraintDoubleData m_typeConstraintData; + btTransformDoubleData m_rbAFrame; + btTransformDoubleData m_rbBFrame; + btVector3DoubleData m_linearUpperLimit; + btVector3DoubleData m_linearLowerLimit; + btVector3DoubleData m_linearBounce; + btVector3DoubleData m_linearStopERP; + btVector3DoubleData m_linearStopCFM; + btVector3DoubleData m_linearMotorERP; + btVector3DoubleData m_linearMotorCFM; + btVector3DoubleData m_linearTargetVelocity; + btVector3DoubleData m_linearMaxMotorForce; + btVector3DoubleData m_linearServoTarget; + btVector3DoubleData m_linearSpringStiffness; + btVector3DoubleData m_linearSpringDamping; + btVector3DoubleData m_linearEquilibriumPoint; + char m_linearEnableMotor[4]; + char m_linearServoMotor[4]; + char m_linearEnableSpring[4]; + char m_linearSpringStiffnessLimited[4]; + char m_linearSpringDampingLimited[4]; + char m_padding1[4]; + btVector3DoubleData m_angularUpperLimit; + btVector3DoubleData m_angularLowerLimit; + btVector3DoubleData m_angularBounce; + btVector3DoubleData m_angularStopERP; + btVector3DoubleData m_angularStopCFM; + btVector3DoubleData m_angularMotorERP; + btVector3DoubleData m_angularMotorCFM; + btVector3DoubleData m_angularTargetVelocity; + btVector3DoubleData m_angularMaxMotorForce; + btVector3DoubleData m_angularServoTarget; + btVector3DoubleData m_angularSpringStiffness; + btVector3DoubleData m_angularSpringDamping; + btVector3DoubleData m_angularEquilibriumPoint; + char m_angularEnableMotor[4]; + char m_angularServoMotor[4]; + char m_angularEnableSpring[4]; + char m_angularSpringStiffnessLimited[4]; + char m_angularSpringDampingLimited[4]; + int m_rotateOrder; +}; + +// -------------------------------------------------- // +class btSliderConstraintData +{ +public: + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; + btTransformFloatData m_rbBFrame; + float m_linearUpperLimit; + float m_linearLowerLimit; + float m_angularUpperLimit; + float m_angularLowerLimit; + int m_useLinearReferenceFrameA; + int m_useOffsetForConstraintFrame; +}; + +// -------------------------------------------------- // +class btSliderConstraintDoubleData +{ +public: + btTypedConstraintDoubleData m_typeConstraintData; + btTransformDoubleData m_rbAFrame; + btTransformDoubleData m_rbBFrame; + double m_linearUpperLimit; + double m_linearLowerLimit; + double m_angularUpperLimit; + double m_angularLowerLimit; + int m_useLinearReferenceFrameA; + int m_useOffsetForConstraintFrame; +}; + +// -------------------------------------------------- // +class btGearConstraintFloatData +{ +public: + btTypedConstraintFloatData m_typeConstraintData; + btVector3FloatData m_axisInA; + btVector3FloatData m_axisInB; + float m_ratio; + char m_padding[4]; +}; + +// -------------------------------------------------- // +class btGearConstraintDoubleData +{ +public: + btTypedConstraintDoubleData m_typeConstraintData; + btVector3DoubleData m_axisInA; + btVector3DoubleData m_axisInB; + double m_ratio; +}; + +// -------------------------------------------------- // +class SoftBodyMaterialData +{ +public: + float m_linearStiffness; + float m_angularStiffness; + float m_volumeStiffness; + int m_flags; +}; + +// -------------------------------------------------- // +class SoftBodyNodeData +{ +public: + SoftBodyMaterialData *m_material; + btVector3FloatData m_position; + btVector3FloatData m_previousPosition; + btVector3FloatData m_velocity; + btVector3FloatData m_accumulatedForce; + btVector3FloatData m_normal; + float m_inverseMass; + float m_area; + int m_attach; + int m_pad; +}; + +// -------------------------------------------------- // +class SoftBodyLinkData +{ +public: + SoftBodyMaterialData *m_material; + int m_nodeIndices[2]; + float m_restLength; + int m_bbending; +}; + +// -------------------------------------------------- // +class SoftBodyFaceData +{ +public: + btVector3FloatData m_normal; + SoftBodyMaterialData *m_material; + int m_nodeIndices[3]; + float m_restArea; +}; + +// -------------------------------------------------- // +class SoftBodyTetraData +{ +public: + btVector3FloatData m_c0[4]; + SoftBodyMaterialData *m_material; + int m_nodeIndices[4]; + float m_restVolume; + float m_c1; + float m_c2; + int m_pad; +}; + +// -------------------------------------------------- // +class SoftRigidAnchorData +{ +public: + btMatrix3x3FloatData m_c0; + btVector3FloatData m_c1; + btVector3FloatData m_localFrame; + bInvalidHandle *m_rigidBody; + int m_nodeIndex; + float m_c2; +}; + +// -------------------------------------------------- // +class SoftBodyConfigData +{ +public: + int m_aeroModel; + float m_baumgarte; + float m_damping; + float m_drag; + float m_lift; + float m_pressure; + float m_volume; + float m_dynamicFriction; + float m_poseMatch; + float m_rigidContactHardness; + float m_kineticContactHardness; + float m_softContactHardness; + float m_anchorHardness; + float m_softRigidClusterHardness; + float m_softKineticClusterHardness; + float m_softSoftClusterHardness; + float m_softRigidClusterImpulseSplit; + float m_softKineticClusterImpulseSplit; + float m_softSoftClusterImpulseSplit; + float m_maxVolume; + float m_timeScale; + int m_velocityIterations; + int m_positionIterations; + int m_driftIterations; + int m_clusterIterations; + int m_collisionFlags; +}; + +// -------------------------------------------------- // +class SoftBodyPoseData +{ +public: + btMatrix3x3FloatData m_rot; + btMatrix3x3FloatData m_scale; + btMatrix3x3FloatData m_aqq; + btVector3FloatData m_com; + btVector3FloatData *m_positions; + float *m_weights; + int m_numPositions; + int m_numWeigts; + int m_bvolume; + int m_bframe; + float m_restVolume; + int m_pad; +}; + +// -------------------------------------------------- // +class SoftBodyClusterData +{ +public: + btTransformFloatData m_framexform; + btMatrix3x3FloatData m_locii; + btMatrix3x3FloatData m_invwi; + btVector3FloatData m_com; + btVector3FloatData m_vimpulses[2]; + btVector3FloatData m_dimpulses[2]; + btVector3FloatData m_lv; + btVector3FloatData m_av; + btVector3FloatData *m_framerefs; + int *m_nodeIndices; + float *m_masses; + int m_numFrameRefs; + int m_numNodes; + int m_numMasses; + float m_idmass; + float m_imass; + int m_nvimpulses; + int m_ndimpulses; + float m_ndamping; + float m_ldamping; + float m_adamping; + float m_matching; + float m_maxSelfCollisionImpulse; + float m_selfCollisionImpulseFactor; + int m_containsAnchor; + int m_collide; + int m_clusterIndex; +}; + +// -------------------------------------------------- // +class btSoftBodyJointData +{ +public: + void *m_bodyA; + void *m_bodyB; + btVector3FloatData m_refs[2]; + float m_cfm; + float m_erp; + float m_split; + int m_delete; + btVector3FloatData m_relPosition[2]; + int m_bodyAtype; + int m_bodyBtype; + int m_jointType; + int m_pad; +}; + +// -------------------------------------------------- // +class btSoftBodyFloatData +{ +public: + btCollisionObjectFloatData m_collisionObjectData; + SoftBodyPoseData *m_pose; + SoftBodyMaterialData **m_materials; + SoftBodyNodeData *m_nodes; + SoftBodyLinkData *m_links; + SoftBodyFaceData *m_faces; + SoftBodyTetraData *m_tetrahedra; + SoftRigidAnchorData *m_anchors; + SoftBodyClusterData *m_clusters; + btSoftBodyJointData *m_joints; + int m_numMaterials; + int m_numNodes; + int m_numLinks; + int m_numFaces; + int m_numTetrahedra; + int m_numAnchors; + int m_numClusters; + int m_numJoints; + SoftBodyConfigData m_config; +}; + +// -------------------------------------------------- // +class btMultiBodyLinkDoubleData +{ +public: + btQuaternionDoubleData m_zeroRotParentToThis; + btVector3DoubleData m_parentComToThisPivotOffset; + btVector3DoubleData m_thisPivotToThisComOffset; + btVector3DoubleData m_jointAxisTop[6]; + btVector3DoubleData m_jointAxisBottom[6]; + btVector3DoubleData m_linkInertia; + btVector3DoubleData m_absFrameTotVelocityTop; + btVector3DoubleData m_absFrameTotVelocityBottom; + btVector3DoubleData m_absFrameLocVelocityTop; + btVector3DoubleData m_absFrameLocVelocityBottom; + double m_linkMass; + int m_parentIndex; + int m_jointType; + int m_dofCount; + int m_posVarCount; + double m_jointPos[7]; + double m_jointVel[6]; + double m_jointTorque[6]; + double m_jointDamping; + double m_jointFriction; + double m_jointLowerLimit; + double m_jointUpperLimit; + double m_jointMaxForce; + double m_jointMaxVelocity; + char *m_linkName; + char *m_jointName; + btCollisionObjectDoubleData *m_linkCollider; + char *m_paddingPtr; +}; + +// -------------------------------------------------- // +class btMultiBodyLinkFloatData +{ +public: + btQuaternionFloatData m_zeroRotParentToThis; + btVector3FloatData m_parentComToThisPivotOffset; + btVector3FloatData m_thisPivotToThisComOffset; + btVector3FloatData m_jointAxisTop[6]; + btVector3FloatData m_jointAxisBottom[6]; + btVector3FloatData m_linkInertia; + btVector3FloatData m_absFrameTotVelocityTop; + btVector3FloatData m_absFrameTotVelocityBottom; + btVector3FloatData m_absFrameLocVelocityTop; + btVector3FloatData m_absFrameLocVelocityBottom; + int m_dofCount; + float m_linkMass; + int m_parentIndex; + int m_jointType; + float m_jointPos[7]; + float m_jointVel[6]; + float m_jointTorque[6]; + int m_posVarCount; + float m_jointDamping; + float m_jointFriction; + float m_jointLowerLimit; + float m_jointUpperLimit; + float m_jointMaxForce; + float m_jointMaxVelocity; + char *m_linkName; + char *m_jointName; + btCollisionObjectFloatData *m_linkCollider; + char *m_paddingPtr; +}; + +// -------------------------------------------------- // +class btMultiBodyDoubleData +{ +public: + btVector3DoubleData m_baseWorldPosition; + btQuaternionDoubleData m_baseWorldOrientation; + btVector3DoubleData m_baseLinearVelocity; + btVector3DoubleData m_baseAngularVelocity; + btVector3DoubleData m_baseInertia; + double m_baseMass; + int m_numLinks; + char m_padding[4]; + char *m_baseName; + btMultiBodyLinkDoubleData *m_links; + btCollisionObjectDoubleData *m_baseCollider; +}; + +// -------------------------------------------------- // +class btMultiBodyFloatData +{ +public: + btVector3FloatData m_baseWorldPosition; + btQuaternionFloatData m_baseWorldOrientation; + btVector3FloatData m_baseLinearVelocity; + btVector3FloatData m_baseAngularVelocity; + btVector3FloatData m_baseInertia; + float m_baseMass; + int m_numLinks; + char *m_baseName; + btMultiBodyLinkFloatData *m_links; + btCollisionObjectFloatData *m_baseCollider; +}; + +// -------------------------------------------------- // +class btMultiBodyLinkColliderFloatData +{ +public: + btCollisionObjectFloatData m_colObjData; + btMultiBodyFloatData *m_multiBody; + int m_link; + char m_padding[4]; +}; + +// -------------------------------------------------- // +class btMultiBodyLinkColliderDoubleData +{ +public: + btCollisionObjectDoubleData m_colObjData; + btMultiBodyDoubleData *m_multiBody; + int m_link; + char m_padding[4]; +}; + +} // namespace Bullet +#endif //__BULLET_H__ \ No newline at end of file diff --git a/Extras/Serialize/BulletFileLoader/bChunk.cpp b/Extras/Serialize/BulletFileLoader/bChunk.cpp index 564e5507e..316c11ac1 100644 --- a/Extras/Serialize/BulletFileLoader/bChunk.cpp +++ b/Extras/Serialize/BulletFileLoader/bChunk.cpp @@ -17,15 +17,13 @@ subject to the following restrictions: #include "bDefines.h" #include "bFile.h" -#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__) +#if !defined(__CELLOS_LV2__) && !defined(__MWERKS__) #include #endif #include - using namespace bParse; - // ----------------------------------------------------- // short ChunkUtils::swapShort(short sht) { @@ -57,19 +55,15 @@ int ChunkUtils::getOffset(int flags) if (VOID_IS_8) { - if (flags &FD_BITS_VARIES) + if (flags & FD_BITS_VARIES) res = sizeof(bChunkPtr4); } else { - if (flags &FD_BITS_VARIES) + if (flags & FD_BITS_VARIES) res = sizeof(bChunkPtr8); } return res; } - - - - //eof diff --git a/Extras/Serialize/BulletFileLoader/bChunk.h b/Extras/Serialize/BulletFileLoader/bChunk.h index 77039bcf9..514a35a3a 100644 --- a/Extras/Serialize/BulletFileLoader/bChunk.h +++ b/Extras/Serialize/BulletFileLoader/bChunk.h @@ -16,77 +16,69 @@ subject to the following restrictions: #ifndef __BCHUNK_H__ #define __BCHUNK_H__ -#if defined (_WIN32) && ! defined (__MINGW32__) - #define long64 __int64 -#elif defined (__MINGW32__) - #include - #define long64 int64_t +#if defined(_WIN32) && !defined(__MINGW32__) +#define long64 __int64 +#elif defined(__MINGW32__) +#include +#define long64 int64_t #else - #define long64 long long +#define long64 long long #endif - -namespace bParse { - - - // ----------------------------------------------------- // - class bChunkPtr4 - { - public: - bChunkPtr4(){} - int code; - int len; - union - { - int m_uniqueInt; - }; - int dna_nr; - int nr; +namespace bParse +{ +// ----------------------------------------------------- // +class bChunkPtr4 +{ +public: + bChunkPtr4() {} + int code; + int len; + union { + int m_uniqueInt; }; + int dna_nr; + int nr; +}; - // ----------------------------------------------------- // - class bChunkPtr8 - { - public: - bChunkPtr8(){} - int code, len; - union - { - long64 oldPrev; - int m_uniqueInts[2]; - }; - int dna_nr, nr; +// ----------------------------------------------------- // +class bChunkPtr8 +{ +public: + bChunkPtr8() {} + int code, len; + union { + long64 oldPrev; + int m_uniqueInts[2]; }; + int dna_nr, nr; +}; - // ----------------------------------------------------- // - class bChunkInd - { - public: - bChunkInd(){} - int code, len; - void *oldPtr; - int dna_nr, nr; - }; +// ----------------------------------------------------- // +class bChunkInd +{ +public: + bChunkInd() {} + int code, len; + void *oldPtr; + int dna_nr, nr; +}; +// ----------------------------------------------------- // +class ChunkUtils +{ +public: + // file chunk offset + static int getOffset(int flags); - // ----------------------------------------------------- // - class ChunkUtils - { - public: - - // file chunk offset - static int getOffset(int flags); + // endian utils + static short swapShort(short sht); + static int swapInt(int inte); + static long64 swapLong64(long64 lng); +}; - // endian utils - static short swapShort(short sht); - static int swapInt(int inte); - static long64 swapLong64(long64 lng); +const int CHUNK_HEADER_LEN = ((sizeof(bChunkInd))); +const bool VOID_IS_8 = ((sizeof(void *) == 8)); +} // namespace bParse - }; - - - const int CHUNK_HEADER_LEN = ((sizeof(bChunkInd))); - const bool VOID_IS_8 = ((sizeof(void*)==8)); -} - -#endif//__BCHUNK_H__ +#endif //__BCHUNK_H__ diff --git a/Extras/Serialize/BulletFileLoader/bCommon.h b/Extras/Serialize/BulletFileLoader/bCommon.h index b01d2b899..a3f599f84 100644 --- a/Extras/Serialize/BulletFileLoader/bCommon.h +++ b/Extras/Serialize/BulletFileLoader/bCommon.h @@ -16,24 +16,25 @@ subject to the following restrictions: #ifndef __BCOMMON_H__ #define __BCOMMON_H__ - #include //#include "bLog.h" #include "LinearMath/btAlignedObjectArray.h" #include "LinearMath/btHashMap.h" -namespace bParse { +namespace bParse +{ +class bMain; +class bFileData; +class bFile; +class bDNA; - class bMain; - class bFileData; - class bFile; - class bDNA; +// delete void* undefined +typedef struct bStructHandle +{ + int unused; +} bStructHandle; +typedef btAlignedObjectArray bListBasePtr; +typedef btHashMap bPtrMap; +} // namespace bParse - // delete void* undefined - typedef struct bStructHandle {int unused;}bStructHandle; - typedef btAlignedObjectArray bListBasePtr; - typedef btHashMap bPtrMap; -} - - -#endif//__BCOMMON_H__ +#endif //__BCOMMON_H__ diff --git a/Extras/Serialize/BulletFileLoader/bDNA.cpp b/Extras/Serialize/BulletFileLoader/bDNA.cpp index 7b42062b3..8d581d278 100644 --- a/Extras/Serialize/BulletFileLoader/bDNA.cpp +++ b/Extras/Serialize/BulletFileLoader/bDNA.cpp @@ -23,13 +23,11 @@ subject to the following restrictions: //this define will force traversal of structures, to check backward (and forward) compatibility //#define TEST_BACKWARD_FORWARD_COMPATIBILITY - using namespace bParse; - // ----------------------------------------------------- // bDNA::bDNA() - : mPtrLen(0) + : mPtrLen(0) { // -- } @@ -43,7 +41,7 @@ bDNA::~bDNA() // ----------------------------------------------------- // bool bDNA::lessThan(bDNA *file) { - return ( m_Names.size() < file->m_Names.size()); + return (m_Names.size() < file->m_Names.size()); } // ----------------------------------------------------- // @@ -53,36 +51,31 @@ char *bDNA::getName(int ind) return m_Names[ind].m_name; } - // ----------------------------------------------------- // char *bDNA::getType(int ind) { - assert(ind<= (int)mTypes.size()); + assert(ind <= (int)mTypes.size()); return mTypes[ind]; } - // ----------------------------------------------------- // short *bDNA::getStruct(int ind) { - assert(ind <= (int)mStructs.size()); + assert(ind <= (int)mStructs.size()); return mStructs[ind]; } - // ----------------------------------------------------- // short bDNA::getLength(int ind) { - assert(ind <= (int)mTlens.size()); + assert(ind <= (int)mTlens.size()); return mTlens[ind]; } - // ----------------------------------------------------- // int bDNA::getReverseType(short type) { - - int* intPtr = mStructReverse.find(type); + int *intPtr = mStructReverse.find(type); if (intPtr) return *intPtr; @@ -92,12 +85,11 @@ int bDNA::getReverseType(short type) // ----------------------------------------------------- // int bDNA::getReverseType(const char *type) { - btHashString key(type); - int* valuePtr = mTypeLookup.find(key); + int *valuePtr = mTypeLookup.find(key); if (valuePtr) return *valuePtr; - + return -1; } @@ -110,22 +102,22 @@ int bDNA::getNumStructs() // ----------------------------------------------------- // bool bDNA::flagNotEqual(int dna_nr) { - assert(dna_nr <= (int)mCMPFlags.size()); + assert(dna_nr <= (int)mCMPFlags.size()); return mCMPFlags[dna_nr] == FDF_STRUCT_NEQU; } // ----------------------------------------------------- // bool bDNA::flagEqual(int dna_nr) { - assert(dna_nr <= (int)mCMPFlags.size()); + assert(dna_nr <= (int)mCMPFlags.size()); int flag = mCMPFlags[dna_nr]; - return flag == FDF_STRUCT_EQU; + return flag == FDF_STRUCT_EQU; } // ----------------------------------------------------- // bool bDNA::flagNone(int dna_nr) { - assert(dna_nr <= (int)mCMPFlags.size()); + assert(dna_nr <= (int)mCMPFlags.size()); return mCMPFlags[dna_nr] == FDF_NONE; } @@ -143,15 +135,15 @@ void bDNA::initRecurseCmpFlags(int iter) short *oldStrc = mStructs[iter]; short type = oldStrc[0]; - for (int i=0; i<(int)mStructs.size(); i++) + for (int i = 0; i < (int)mStructs.size(); i++) { - if (i != iter && mCMPFlags[i] == FDF_STRUCT_EQU ) + if (i != iter && mCMPFlags[i] == FDF_STRUCT_EQU) { short *curStruct = mStructs[i]; int eleLen = curStruct[1]; - curStruct+=2; + curStruct += 2; - for (int j=0; jgetReverseType(typeName); if (newLookup == -1) { @@ -211,71 +199,61 @@ void bDNA::initCmpFlags(bDNA *memDNA) if (oldLookup < memDNA->mStructs.size()) { short *curStruct = memDNA->mStructs[oldLookup]; -#endif - - +#endif - // rebuild... - mCMPFlags[i] = FDF_STRUCT_NEQU; + // rebuild... + mCMPFlags[i] = FDF_STRUCT_NEQU; #ifndef TEST_BACKWARD_FORWARD_COMPATIBILITY - if (curStruct[1] == oldStruct[1]) + if (curStruct[1] == oldStruct[1]) + { + // type len same ... + if (mTlens[oldStruct[0]] == memDNA->mTlens[curStruct[0]]) { - // type len same ... - if (mTlens[oldStruct[0]] == memDNA->mTlens[curStruct[0]]) + bool isSame = true; + int elementLength = oldStruct[1]; + + curStruct += 2; + oldStruct += 2; + + for (int j = 0; j < elementLength; j++, curStruct += 2, oldStruct += 2) { - bool isSame = true; - int elementLength = oldStruct[1]; - - - curStruct+=2; - oldStruct+=2; - - - for (int j=0; jmTypes[curStruct[0]]) != 0) { - // type the same - //const char* typeFileDNA = mTypes[oldStruct[0]]; - //const char* typeMemDNA = mTypes[curStruct[0]]; - if (strcmp(mTypes[oldStruct[0]], memDNA->mTypes[curStruct[0]])!=0) - { - isSame=false; - break; - } - - // name the same - if (strcmp(m_Names[oldStruct[1]].m_name, memDNA->m_Names[curStruct[1]].m_name)!=0) - { - isSame=false; - break; - } + isSame = false; + break; + } + + // name the same + if (strcmp(m_Names[oldStruct[1]].m_name, memDNA->m_Names[curStruct[1]].m_name) != 0) + { + isSame = false; + break; } - // flag valid == - if (isSame) - mCMPFlags[i] = FDF_STRUCT_EQU; } + // flag valid == + if (isSame) + mCMPFlags[i] = FDF_STRUCT_EQU; } -#endif } - } - - - - - - // recurse in - for ( i=0; i<(int)mStructs.size(); i++) - { - if (mCMPFlags[i] == FDF_STRUCT_NEQU) - initRecurseCmpFlags(i); +#endif } } +// recurse in +for (i = 0; i < (int)mStructs.size(); i++) +{ + if (mCMPFlags[i] == FDF_STRUCT_NEQU) + initRecurseCmpFlags(i); +} +} - - -static int name_is_array(char* name, int* dim1, int* dim2) { +static int name_is_array(char *name, int *dim1, int *dim2) +{ int len = strlen(name); /*fprintf(stderr,"[%s]",name);*/ /*if (len >= 1) { @@ -285,58 +263,77 @@ static int name_is_array(char* name, int* dim1, int* dim2) { return 0;*/ char *bp; int num; - if (dim1) { + if (dim1) + { *dim1 = 1; } - if (dim2) { + if (dim2) + { *dim2 = 1; } bp = strchr(name, '['); - if (!bp) { + if (!bp) + { return 0; } num = 0; - while (++bp < name+len-1) { + while (++bp < name + len - 1) + { const char c = *bp; - if (c == ']') { + if (c == ']') + { break; } - if (c <= '9' && c >= '0') { + if (c <= '9' && c >= '0') + { num *= 10; num += (c - '0'); - } else { + } + else + { printf("array parse error.\n"); return 0; } } - if (dim2) { + if (dim2) + { *dim2 = num; } /* find second dim, if any. */ bp = strchr(bp, '['); - if (!bp) { + if (!bp) + { return 1; /* at least we got the first dim. */ } num = 0; - while (++bp < name+len-1) { + while (++bp < name + len - 1) + { const char c = *bp; - if (c == ']') { + if (c == ']') + { break; } - if (c <= '9' && c >= '0') { + if (c <= '9' && c >= '0') + { num *= 10; num += (c - '0'); - } else { + } + else + { printf("array2 parse error.\n"); return 1; } } - if (dim1) { - if (dim2) { + if (dim1) + { + if (dim2) + { *dim1 = *dim2; *dim2 = num; - } else { + } + else + { *dim1 = num; } } @@ -344,14 +341,15 @@ static int name_is_array(char* name, int* dim1, int* dim2) { return 1; } - // ----------------------------------------------------- // void bDNA::init(char *data, int len, bool swap) { - int *intPtr=0;short *shtPtr=0; - char *cp = 0;int dataLen =0; + int *intPtr = 0; + short *shtPtr = 0; + char *cp = 0; + int dataLen = 0; //long nr=0; - intPtr = (int*)data; + intPtr = (int *)data; /* SDNA (4 bytes) (magic number) @@ -361,39 +359,36 @@ void bDNA::init(char *data, int len, bool swap) */ - if (strncmp(data, "SDNA", 4)==0) + if (strncmp(data, "SDNA", 4) == 0) { // skip ++ NAME - intPtr++; intPtr++; + intPtr++; + intPtr++; } - - // Parse names - if (swap) + if (swap) { *intPtr = ChunkUtils::swapInt(*intPtr); } dataLen = *intPtr; intPtr++; - cp = (char*)intPtr; + cp = (char *)intPtr; int i; - for ( i=0; i amount of types (int) @@ -401,26 +396,27 @@ void bDNA::init(char *data, int len, bool swap) */ - intPtr = (int*)cp; - assert(strncmp(cp, "TYPE", 4)==0); intPtr++; + intPtr = (int *)cp; + assert(strncmp(cp, "TYPE", 4) == 0); + intPtr++; - if (swap) + if (swap) { *intPtr = ChunkUtils::swapInt(*intPtr); } dataLen = *intPtr; intPtr++; - cp = (char*)intPtr; - for ( i=0; i (short) the lengths of types @@ -428,13 +424,14 @@ void bDNA::init(char *data, int len, bool swap) */ // Parse type lens - intPtr = (int*)cp; - assert(strncmp(cp, "TLEN", 4)==0); intPtr++; + intPtr = (int *)cp; + assert(strncmp(cp, "TLEN", 4) == 0); + intPtr++; dataLen = (int)mTypes.size(); - shtPtr = (short*)intPtr; - for ( i=0; i */ - intPtr = (int*)shtPtr; - cp = (char*)intPtr; - assert(strncmp(cp, "STRC", 4)==0); intPtr++; + intPtr = (int *)shtPtr; + cp = (char *)intPtr; + assert(strncmp(cp, "STRC", 4) == 0); + intPtr++; - if (swap) + if (swap) { *intPtr = ChunkUtils::swapInt(*intPtr); } dataLen = *intPtr; intPtr++; - - shtPtr = (short*)intPtr; - for ( i=0; i mCMPFlags; - int getArraySize(char* str); - int getArraySizeNew(short name) - { - const bNameInfo& nameInfo = m_Names[name]; - return nameInfo.m_dim0*nameInfo.m_dim1; - } - int getElementSize(short type, short name) - { - const bNameInfo& nameInfo = m_Names[name]; - int size = nameInfo.m_isPointer ? mPtrLen*nameInfo.m_dim0*nameInfo.m_dim1 : mTlens[type]*nameInfo.m_dim0*nameInfo.m_dim1; - return size; - } + btAlignedObjectArray m_Names; + btAlignedObjectArray mTypes; + btAlignedObjectArray mStructs; + btAlignedObjectArray mTlens; + btHashMap mStructReverse; + btHashMap mTypeLookup; - int getNumNames() const - { - return m_Names.size(); - } + int mPtrLen; +}; +} // namespace bParse - char *getName(int ind); - char *getType(int ind); - short *getStruct(int ind); - short getLength(int ind); - int getReverseType(short type); - int getReverseType(const char *type); - - - int getNumStructs(); - - // - bool lessThan(bDNA* other); - - void initCmpFlags(bDNA *memDNA); - bool flagNotEqual(int dna_nr); - bool flagEqual(int dna_nr); - bool flagNone(int dna_nr); - - - int getPointerSize(); - - void dumpTypeDefinitions(); - - - private: - enum FileDNAFlags - { - FDF_NONE=0, - FDF_STRUCT_NEQU, - FDF_STRUCT_EQU - }; - - void initRecurseCmpFlags(int i); - - btAlignedObjectArray mCMPFlags; - - btAlignedObjectArray m_Names; - btAlignedObjectArray mTypes; - btAlignedObjectArray mStructs; - btAlignedObjectArray mTlens; - btHashMap mStructReverse; - btHashMap mTypeLookup; - - int mPtrLen; - - - - - }; -} - - -#endif//__BDNA_H__ +#endif //__BDNA_H__ diff --git a/Extras/Serialize/BulletFileLoader/bDefines.h b/Extras/Serialize/BulletFileLoader/bDefines.h index 3a9e2c987..c5ad20acf 100644 --- a/Extras/Serialize/BulletFileLoader/bDefines.h +++ b/Extras/Serialize/BulletFileLoader/bDefines.h @@ -19,121 +19,134 @@ #ifndef __B_DEFINES_H__ #define __B_DEFINES_H__ - // MISC defines, see BKE_global.h, BKE_utildefines.h #define SIZEOFBLENDERHEADER 12 - // ------------------------------------------------------------ -#if defined(__sgi) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__) -# define MAKE_ID(a,b,c,d) ( (int)(a)<<24 | (int)(b)<<16 | (c)<<8 | (d) ) +#if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined(__PPC__) || defined(__ppc__) || defined(__BIG_ENDIAN__) +#define MAKE_ID(a, b, c, d) ((int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d)) #else -# define MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) ) -#endif - - -// ------------------------------------------------------------ -#if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__) -# define MAKE_ID2(c, d) ( (c)<<8 | (d) ) -# define MOST_SIG_BYTE 0 -# define BBIG_ENDIAN -#else -# define MAKE_ID2(c, d) ( (d)<<8 | (c) ) -# define MOST_SIG_BYTE 1 -# define BLITTLE_ENDIAN +#define MAKE_ID(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a)) #endif // ------------------------------------------------------------ -#define ID_SCE MAKE_ID2('S', 'C') -#define ID_LI MAKE_ID2('L', 'I') -#define ID_OB MAKE_ID2('O', 'B') -#define ID_ME MAKE_ID2('M', 'E') -#define ID_CU MAKE_ID2('C', 'U') -#define ID_MB MAKE_ID2('M', 'B') -#define ID_MA MAKE_ID2('M', 'A') -#define ID_TE MAKE_ID2('T', 'E') -#define ID_IM MAKE_ID2('I', 'M') -#define ID_IK MAKE_ID2('I', 'K') -#define ID_WV MAKE_ID2('W', 'V') -#define ID_LT MAKE_ID2('L', 'T') -#define ID_SE MAKE_ID2('S', 'E') -#define ID_LF MAKE_ID2('L', 'F') -#define ID_LA MAKE_ID2('L', 'A') -#define ID_CA MAKE_ID2('C', 'A') -#define ID_IP MAKE_ID2('I', 'P') -#define ID_KE MAKE_ID2('K', 'E') -#define ID_WO MAKE_ID2('W', 'O') -#define ID_SCR MAKE_ID2('S', 'R') -#define ID_VF MAKE_ID2('V', 'F') -#define ID_TXT MAKE_ID2('T', 'X') -#define ID_SO MAKE_ID2('S', 'O') -#define ID_SAMPLE MAKE_ID2('S', 'A') -#define ID_GR MAKE_ID2('G', 'R') -#define ID_ID MAKE_ID2('I', 'D') -#define ID_AR MAKE_ID2('A', 'R') -#define ID_AC MAKE_ID2('A', 'C') -#define ID_SCRIPT MAKE_ID2('P', 'Y') -#define ID_FLUIDSIM MAKE_ID2('F', 'S') -#define ID_NT MAKE_ID2('N', 'T') -#define ID_BR MAKE_ID2('B', 'R') - - -#define ID_SEQ MAKE_ID2('S', 'Q') -#define ID_CO MAKE_ID2('C', 'O') -#define ID_PO MAKE_ID2('A', 'C') -#define ID_NLA MAKE_ID2('N', 'L') - -#define ID_VS MAKE_ID2('V', 'S') -#define ID_VN MAKE_ID2('V', 'N') - +#if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined(__PPC__) || defined(__ppc__) || defined(__BIG_ENDIAN__) +#define MAKE_ID2(c, d) ((c) << 8 | (d)) +#define MOST_SIG_BYTE 0 +#define BBIG_ENDIAN +#else +#define MAKE_ID2(c, d) ((d) << 8 | (c)) +#define MOST_SIG_BYTE 1 +#define BLITTLE_ENDIAN +#endif // ------------------------------------------------------------ -#define FORM MAKE_ID('F','O','R','M') -#define DDG1 MAKE_ID('3','D','G','1') -#define DDG2 MAKE_ID('3','D','G','2') -#define DDG3 MAKE_ID('3','D','G','3') -#define DDG4 MAKE_ID('3','D','G','4') -#define GOUR MAKE_ID('G','O','U','R') -#define BLEN MAKE_ID('B','L','E','N') -#define DER_ MAKE_ID('D','E','R','_') -#define V100 MAKE_ID('V','1','0','0') -#define DATA MAKE_ID('D','A','T','A') -#define GLOB MAKE_ID('G','L','O','B') -#define IMAG MAKE_ID('I','M','A','G') -#define USER MAKE_ID('U','S','E','R') +#define ID_SCE MAKE_ID2('S', 'C') +#define ID_LI MAKE_ID2('L', 'I') +#define ID_OB MAKE_ID2('O', 'B') +#define ID_ME MAKE_ID2('M', 'E') +#define ID_CU MAKE_ID2('C', 'U') +#define ID_MB MAKE_ID2('M', 'B') +#define ID_MA MAKE_ID2('M', 'A') +#define ID_TE MAKE_ID2('T', 'E') +#define ID_IM MAKE_ID2('I', 'M') +#define ID_IK MAKE_ID2('I', 'K') +#define ID_WV MAKE_ID2('W', 'V') +#define ID_LT MAKE_ID2('L', 'T') +#define ID_SE MAKE_ID2('S', 'E') +#define ID_LF MAKE_ID2('L', 'F') +#define ID_LA MAKE_ID2('L', 'A') +#define ID_CA MAKE_ID2('C', 'A') +#define ID_IP MAKE_ID2('I', 'P') +#define ID_KE MAKE_ID2('K', 'E') +#define ID_WO MAKE_ID2('W', 'O') +#define ID_SCR MAKE_ID2('S', 'R') +#define ID_VF MAKE_ID2('V', 'F') +#define ID_TXT MAKE_ID2('T', 'X') +#define ID_SO MAKE_ID2('S', 'O') +#define ID_SAMPLE MAKE_ID2('S', 'A') +#define ID_GR MAKE_ID2('G', 'R') +#define ID_ID MAKE_ID2('I', 'D') +#define ID_AR MAKE_ID2('A', 'R') +#define ID_AC MAKE_ID2('A', 'C') +#define ID_SCRIPT MAKE_ID2('P', 'Y') +#define ID_FLUIDSIM MAKE_ID2('F', 'S') +#define ID_NT MAKE_ID2('N', 'T') +#define ID_BR MAKE_ID2('B', 'R') +#define ID_SEQ MAKE_ID2('S', 'Q') +#define ID_CO MAKE_ID2('C', 'O') +#define ID_PO MAKE_ID2('A', 'C') +#define ID_NLA MAKE_ID2('N', 'L') + +#define ID_VS MAKE_ID2('V', 'S') +#define ID_VN MAKE_ID2('V', 'N') // ------------------------------------------------------------ -#define DNA1 MAKE_ID('D','N','A','1') -#define REND MAKE_ID('R','E','N','D') -#define ENDB MAKE_ID('E','N','D','B') -#define NAME MAKE_ID('N','A','M','E') -#define SDNA MAKE_ID('S','D','N','A') -#define TYPE MAKE_ID('T','Y','P','E') -#define TLEN MAKE_ID('T','L','E','N') -#define STRC MAKE_ID('S','T','R','C') - +#define FORM MAKE_ID('F', 'O', 'R', 'M') +#define DDG1 MAKE_ID('3', 'D', 'G', '1') +#define DDG2 MAKE_ID('3', 'D', 'G', '2') +#define DDG3 MAKE_ID('3', 'D', 'G', '3') +#define DDG4 MAKE_ID('3', 'D', 'G', '4') +#define GOUR MAKE_ID('G', 'O', 'U', 'R') +#define BLEN MAKE_ID('B', 'L', 'E', 'N') +#define DER_ MAKE_ID('D', 'E', 'R', '_') +#define V100 MAKE_ID('V', '1', '0', '0') +#define DATA MAKE_ID('D', 'A', 'T', 'A') +#define GLOB MAKE_ID('G', 'L', 'O', 'B') +#define IMAG MAKE_ID('I', 'M', 'A', 'G') +#define USER MAKE_ID('U', 'S', 'E', 'R') // ------------------------------------------------------------ -#define SWITCH_INT(a) { \ - char s_i, *p_i; \ - p_i= (char *)&(a); \ - s_i=p_i[0]; p_i[0]=p_i[3]; p_i[3]=s_i; \ - s_i=p_i[1]; p_i[1]=p_i[2]; p_i[2]=s_i; } +#define DNA1 MAKE_ID('D', 'N', 'A', '1') +#define REND MAKE_ID('R', 'E', 'N', 'D') +#define ENDB MAKE_ID('E', 'N', 'D', 'B') +#define NAME MAKE_ID('N', 'A', 'M', 'E') +#define SDNA MAKE_ID('S', 'D', 'N', 'A') +#define TYPE MAKE_ID('T', 'Y', 'P', 'E') +#define TLEN MAKE_ID('T', 'L', 'E', 'N') +#define STRC MAKE_ID('S', 'T', 'R', 'C') // ------------------------------------------------------------ -#define SWITCH_SHORT(a) { \ - char s_i, *p_i; \ - p_i= (char *)&(a); \ - s_i=p_i[0]; p_i[0]=p_i[1]; p_i[1]=s_i; } +#define SWITCH_INT(a) \ + { \ + char s_i, *p_i; \ + p_i = (char *)&(a); \ + s_i = p_i[0]; \ + p_i[0] = p_i[3]; \ + p_i[3] = s_i; \ + s_i = p_i[1]; \ + p_i[1] = p_i[2]; \ + p_i[2] = s_i; \ + } // ------------------------------------------------------------ -#define SWITCH_LONGINT(a) { \ - char s_i, *p_i; \ - p_i= (char *)&(a); \ - s_i=p_i[0]; p_i[0]=p_i[7]; p_i[7]=s_i; \ - s_i=p_i[1]; p_i[1]=p_i[6]; p_i[6]=s_i; \ - s_i=p_i[2]; p_i[2]=p_i[5]; p_i[5]=s_i; \ - s_i=p_i[3]; p_i[3]=p_i[4]; p_i[4]=s_i; } +#define SWITCH_SHORT(a) \ + { \ + char s_i, *p_i; \ + p_i = (char *)&(a); \ + s_i = p_i[0]; \ + p_i[0] = p_i[1]; \ + p_i[1] = s_i; \ + } -#endif//__B_DEFINES_H__ +// ------------------------------------------------------------ +#define SWITCH_LONGINT(a) \ + { \ + char s_i, *p_i; \ + p_i = (char *)&(a); \ + s_i = p_i[0]; \ + p_i[0] = p_i[7]; \ + p_i[7] = s_i; \ + s_i = p_i[1]; \ + p_i[1] = p_i[6]; \ + p_i[6] = s_i; \ + s_i = p_i[2]; \ + p_i[2] = p_i[5]; \ + p_i[5] = s_i; \ + s_i = p_i[3]; \ + p_i[3] = p_i[4]; \ + p_i[4] = s_i; \ + } + +#endif //__B_DEFINES_H__ diff --git a/Extras/Serialize/BulletFileLoader/bFile.cpp b/Extras/Serialize/BulletFileLoader/bFile.cpp index 69a503e79..da9f65f20 100644 --- a/Extras/Serialize/BulletFileLoader/bFile.cpp +++ b/Extras/Serialize/BulletFileLoader/bFile.cpp @@ -29,40 +29,40 @@ subject to the following restrictions: using namespace bParse; #define MAX_STRLEN 1024 -const char* getCleanName(const char* memName, char* buffer) +const char *getCleanName(const char *memName, char *buffer) { int slen = strlen(memName); - assert(sleninit will convert part of DNA file endianness to current CPU endianness if necessary - mFileDNA->init((char*)dnaBuffer, dnaLen, (mFlags & FD_ENDIAN_SWAP)!=0); - - if (verboseMode & FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS) - mFileDNA->dumpTypeDefinitions(); + mFileDNA = new bDNA(); + + ///mFileDNA->init will convert part of DNA file endianness to current CPU endianness if necessary + mFileDNA->init((char *)dnaBuffer, dnaLen, (mFlags & FD_ENDIAN_SWAP) != 0); + + if (verboseMode & FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS) + mFileDNA->dumpTypeDefinitions(); } // ----------------------------------------------------- // -void bFile::parseInternal(int verboseMode, char* memDna,int memDnaLength) +void bFile::parseInternal(int verboseMode, char *memDna, int memDnaLength) { - if ( (mFlags &FD_OK) ==0) + if ((mFlags & FD_OK) == 0) return; if (mFlags & FD_FILEDNA_IS_MEMDNA) { - setFileDNA(verboseMode,memDna,memDnaLength); + setFileDNA(verboseMode, memDna, memDnaLength); } - if (mFileDNA==0) + if (mFileDNA == 0) { char *blenderData = mFileBuffer; bChunkInd dna; dna.oldPtr = 0; char *tempBuffer = blenderData; - for (int i=0; i 0) { - if (strncmp((tempBuffer + ChunkUtils::getOffset(mFlags)), "SDNANAME", 8) ==0) + if (strncmp((tempBuffer + ChunkUtils::getOffset(mFlags)), "SDNANAME", 8) == 0) dna.oldPtr = (tempBuffer + ChunkUtils::getOffset(mFlags)); - else dna.oldPtr = 0; + else + dna.oldPtr = 0; } - else dna.oldPtr = 0; - } + else + dna.oldPtr = 0; + } // Some Bullet files are missing the DNA1 block // In Blender it's DNA1 + ChunkUtils::getOffset() + SDNA + NAME // In Bullet tests its SDNA + NAME - else if (strncmp(tempBuffer, "SDNANAME", 8) ==0) + else if (strncmp(tempBuffer, "SDNANAME", 8) == 0) { dna.oldPtr = blenderData + i; - dna.len = mFileLen-i; + dna.len = mFileLen - i; - // Also no REND block, so exit now. - if (mVersion==276) break; + // Also no REND block, so exit now. + if (mVersion == 276) break; } if (mDataStart && dna.oldPtr) break; @@ -258,43 +251,35 @@ void bFile::parseInternal(int verboseMode, char* memDna,int memDnaLength) return; } - mFileDNA = new bDNA(); - - - ///mFileDNA->init will convert part of DNA file endianness to current CPU endianness if necessary - mFileDNA->init((char*)dna.oldPtr, dna.len, (mFlags & FD_ENDIAN_SWAP)!=0); - - if (mVersion==276) + ///mFileDNA->init will convert part of DNA file endianness to current CPU endianness if necessary + mFileDNA->init((char *)dna.oldPtr, dna.len, (mFlags & FD_ENDIAN_SWAP) != 0); + + if (mVersion == 276) { int i; - for (i=0;igetNumNames();i++) + for (i = 0; i < mFileDNA->getNumNames(); i++) { - if (strcmp(mFileDNA->getName(i),"int")==0) + if (strcmp(mFileDNA->getName(i), "int") == 0) { mFlags |= FD_BROKEN_DNA; } } - if ((mFlags&FD_BROKEN_DNA)!=0) + if ((mFlags & FD_BROKEN_DNA) != 0) { //printf("warning: fixing some broken DNA version\n"); } } - - if (verboseMode & FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS) mFileDNA->dumpTypeDefinitions(); } mMemoryDNA = new bDNA(); - int littleEndian= 1; - littleEndian= ((char*)&littleEndian)[0]; - - mMemoryDNA->init(memDna,memDnaLength,littleEndian==0); - - + int littleEndian = 1; + littleEndian = ((char *)&littleEndian)[0]; + mMemoryDNA->init(memDna, memDnaLength, littleEndian == 0); ///@todo we need a better version check, add version/sub version info from FileGlobal into memory DNA/header files if (mMemoryDNA->getNumNames() != mFileDNA->getNumNames()) @@ -309,111 +294,103 @@ void bFile::parseInternal(int verboseMode, char* memDna,int memDnaLength) //printf ("Warning, file DNA is newer than built in."); } - mFileDNA->initCmpFlags(mMemoryDNA); - + parseData(); - + resolvePointers(verboseMode); - + updateOldPointers(); - - } - - // ----------------------------------------------------- // -void bFile::swap(char *head, bChunkInd& dataChunk, bool ignoreEndianFlag) +void bFile::swap(char *head, bChunkInd &dataChunk, bool ignoreEndianFlag) { char *data = head; short *strc = mFileDNA->getStruct(dataChunk.dna_nr); - - const char s[] = "SoftBodyMaterialData"; int szs = sizeof(s); - if (strncmp((char*)&dataChunk.code,"ARAY",4)==0) + if (strncmp((char *)&dataChunk.code, "ARAY", 4) == 0) { short *oldStruct = mFileDNA->getStruct(dataChunk.dna_nr); char *oldType = mFileDNA->getType(oldStruct[0]); - if (strncmp(oldType,s,szs)==0) + if (strncmp(oldType, s, szs) == 0) { return; } } - int len = mFileDNA->getLength(strc[0]); - for (int i=0; icode & 0xFFFF)==0) - c->code >>=16; + bChunkPtr4 *c = (bChunkPtr4 *)dataPtr; + if ((c->code & 0xFFFF) == 0) + c->code >>= 16; SWITCH_INT(c->len); SWITCH_INT(c->dna_nr); SWITCH_INT(c->nr); - } else - { - bChunkPtr8* c = (bChunkPtr8*) dataPtr; - if ((c->code & 0xFFFF)==0) - c->code >>=16; - SWITCH_INT(c->len); - SWITCH_INT(c->dna_nr); - SWITCH_INT(c->nr); - } - } else - { - if (mFlags &FD_BITS_VARIES) + else { - bChunkPtr8*c = (bChunkPtr8*) dataPtr; - if ((c->code & 0xFFFF)==0) - c->code >>=16; + bChunkPtr8 *c = (bChunkPtr8 *)dataPtr; + if ((c->code & 0xFFFF) == 0) + c->code >>= 16; SWITCH_INT(c->len); SWITCH_INT(c->dna_nr); SWITCH_INT(c->nr); - - } else - { - bChunkPtr4* c = (bChunkPtr4*) dataPtr; - if ((c->code & 0xFFFF)==0) - c->code >>=16; - SWITCH_INT(c->len); - - SWITCH_INT(c->dna_nr); - SWITCH_INT(c->nr); - } } + else + { + if (mFlags & FD_BITS_VARIES) + { + bChunkPtr8 *c = (bChunkPtr8 *)dataPtr; + if ((c->code & 0xFFFF) == 0) + c->code >>= 16; + SWITCH_INT(c->len); + SWITCH_INT(c->dna_nr); + SWITCH_INT(c->nr); + } + else + { + bChunkPtr4 *c = (bChunkPtr4 *)dataPtr; + if ((c->code & 0xFFFF) == 0) + c->code >>= 16; + SWITCH_INT(c->len); + SWITCH_INT(c->dna_nr); + SWITCH_INT(c->nr); + } + } } - -void bFile::swapDNA(char* ptr) +void bFile::swapDNA(char *ptr) { - bool swap = ((mFlags & FD_ENDIAN_SWAP)!=0); + bool swap = ((mFlags & FD_ENDIAN_SWAP) != 0); - int offset = (mFlags & FD_FILE_64)? 24 : 20; - char* data = &ptr[offset]; + int offset = (mFlags & FD_FILE_64) ? 24 : 20; + char *data = &ptr[offset]; -// void bDNA::init(char *data, int len, bool swap) - int *intPtr=0;short *shtPtr=0; - char *cp = 0;int dataLen =0; - intPtr = (int*)data; + // void bDNA::init(char *data, int len, bool swap) + int *intPtr = 0; + short *shtPtr = 0; + char *cp = 0; + int dataLen = 0; + intPtr = (int *)data; /* SDNA (4 bytes) (magic number) @@ -423,46 +400,41 @@ void bFile::swapDNA(char* ptr) */ - if (strncmp(data, "SDNA", 4)==0) + if (strncmp(data, "SDNA", 4) == 0) { // skip ++ NAME - intPtr++; intPtr++; - } else + intPtr++; + } + else { - - if (strncmp(data+4, "SDNA", 4)==0) + if (strncmp(data + 4, "SDNA", 4) == 0) { // skip ++ NAME intPtr++; - intPtr++; + intPtr++; intPtr++; } } - - - // Parse names - if (swap) + if (swap) dataLen = ChunkUtils::swapInt(*intPtr); - else + else dataLen = *intPtr; - + *intPtr = ChunkUtils::swapInt(*intPtr); intPtr++; - cp = (char*)intPtr; + cp = (char *)intPtr; int i; - for ( i=0; i */ - intPtr = (int*)cp; - assert(strncmp(cp, "TYPE", 4)==0); intPtr++; + intPtr = (int *)cp; + assert(strncmp(cp, "TYPE", 4) == 0); + intPtr++; - if (swap) + if (swap) dataLen = ChunkUtils::swapInt(*intPtr); - else + else dataLen = *intPtr; *intPtr = ChunkUtils::swapInt(*intPtr); intPtr++; - cp = (char*)intPtr; - for ( i=0; i */ - intPtr = (int*)shtPtr; - cp = (char*)intPtr; - assert(strncmp(cp, "STRC", 4)==0); + intPtr = (int *)shtPtr; + cp = (char *)intPtr; + assert(strncmp(cp, "STRC", 4) == 0); intPtr++; - if (swap) + if (swap) dataLen = ChunkUtils::swapInt(*intPtr); - else + else dataLen = *intPtr; *intPtr = ChunkUtils::swapInt(*intPtr); intPtr++; - - shtPtr = (short*)intPtr; - for ( i=0; i=0) + if (dataChunk.dna_nr >= 0) { - swap(dataPtrHead, dataChunk,ignoreEndianFlag); - } else + swap(dataPtrHead, dataChunk, ignoreEndianFlag); + } + else { //printf("unknown chunk\n"); } @@ -635,7 +599,7 @@ void bFile::preSwap() // next please! dataPtr += seek; - seek = getNextBlock(&dataChunk, dataPtr, mFlags); + seek = getNextBlock(&dataChunk, dataPtr, mFlags); if (seek < 0) break; } @@ -643,56 +607,50 @@ void bFile::preSwap() if (mFlags & FD_ENDIAN_SWAP) { mFlags &= ~FD_ENDIAN_SWAP; - } else + } + else { mFlags |= FD_ENDIAN_SWAP; } - - - } - // ----------------------------------------------------- // -char* bFile::readStruct(char *head, bChunkInd& dataChunk) +char *bFile::readStruct(char *head, bChunkInd &dataChunk) { bool ignoreEndianFlag = false; if (mFlags & FD_ENDIAN_SWAP) swap(head, dataChunk, ignoreEndianFlag); - - if (!mFileDNA->flagEqual(dataChunk.dna_nr)) { // Ouch! need to rebuild the struct - short *oldStruct,*curStruct; + short *oldStruct, *curStruct; char *oldType, *newType; int oldLen, curLen, reverseOld; - oldStruct = mFileDNA->getStruct(dataChunk.dna_nr); oldType = mFileDNA->getType(oldStruct[0]); - + oldLen = mFileDNA->getLength(oldStruct[0]); - if ((mFlags&FD_BROKEN_DNA)!=0) + if ((mFlags & FD_BROKEN_DNA) != 0) { - if ((strcmp(oldType,"btQuantizedBvhNodeData")==0)&&oldLen==20) + if ((strcmp(oldType, "btQuantizedBvhNodeData") == 0) && oldLen == 20) { return 0; } - if ((strcmp(oldType,"btShortIntIndexData")==0)) + if ((strcmp(oldType, "btShortIntIndexData") == 0)) { int allocLen = 2; - char *dataAlloc = new char[(dataChunk.nr*allocLen)+1]; - memset(dataAlloc, 0, (dataChunk.nr*allocLen)+1); - short* dest = (short*) dataAlloc; - const short* src = (short*) head; - for (int i=0;igetReverseType(oldType); - if ((reverseOld!=-1)) + if ((reverseOld != -1)) { // make sure it's here //assert(reverseOld!= -1 && "getReverseType() returned -1, struct required!"); @@ -719,40 +675,39 @@ char* bFile::readStruct(char *head, bChunkInd& dataChunk) newType = mMemoryDNA->getType(curStruct[0]); curLen = mMemoryDNA->getLength(curStruct[0]); - - // make sure it's the same - assert((strcmp(oldType, newType)==0) && "internal error, struct mismatch!"); - + assert((strcmp(oldType, newType) == 0) && "internal error, struct mismatch!"); numallocs++; // numBlocks * length - int allocLen = (curLen); - char *dataAlloc = new char[(dataChunk.nr*allocLen)+1]; - memset(dataAlloc, 0, (dataChunk.nr*allocLen)); + int allocLen = (curLen); + char *dataAlloc = new char[(dataChunk.nr * allocLen) + 1]; + memset(dataAlloc, 0, (dataChunk.nr * allocLen)); // track allocated addDataBlock(dataAlloc); char *cur = dataAlloc; char *old = head; - for (int block=0; blockgetStruct(dataChunk.dna_nr); oldType = mFileDNA->getType(oldStruct[0]); - printf("%s equal structure, just memcpy\n",oldType); -#endif // + printf("%s equal structure, just memcpy\n", oldType); +#endif // } - - char *dataAlloc = new char[(dataChunk.len)+1]; - memset(dataAlloc, 0, dataChunk.len+1); - + char *dataAlloc = new char[(dataChunk.len) + 1]; + memset(dataAlloc, 0, dataChunk.len + 1); // track allocated addDataBlock(dataAlloc); memcpy(dataAlloc, head, dataChunk.len); return dataAlloc; - } - // ----------------------------------------------------- // void bFile::parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bool fixupPointers) { @@ -785,7 +736,7 @@ void bFile::parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bo if (new_dna == -1) return; //disable this, because we need to fixup pointers/ListBase - if (0)//mFileDNA->flagEqual(old_dna)) + if (0) //mFileDNA->flagEqual(old_dna)) { short *strc = mFileDNA->getStruct(old_dna); int len = mFileDNA->getLength(strc[0]); @@ -800,31 +751,29 @@ void bFile::parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bo int elementLength, size, revType, old_nr, new_nr, fpLen; short firstStructType; - // File to memory lookup memoryStruct = mMemoryDNA->getStruct(new_dna); fileStruct = mFileDNA->getStruct(old_dna); firstStruct = fileStruct; - filePtrOld = fileStruct; firstStructType = mMemoryDNA->getStruct(0)[0]; // Get number of elements elementLength = memoryStruct[1]; - memoryStruct+=2; + memoryStruct += 2; - cpc = strcPtr; cpo = 0; - for (int ele=0; elegetType(memoryStruct[0]); memName = mMemoryDNA->getName(memoryStruct[1]); - size = mMemoryDNA->getElementSize(memoryStruct[0], memoryStruct[1]); revType = mMemoryDNA->getReverseType(memoryStruct[0]); - if (revType != -1 && memoryStruct[0]>=firstStructType && memName[0] != '*') + if (revType != -1 && memoryStruct[0] >= firstStructType && memName[0] != '*') { cpo = getFileElement(firstStruct, memName, memType, dtPtr, &filePtrOld); if (cpo) @@ -833,94 +782,92 @@ void bFile::parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bo old_nr = mFileDNA->getReverseType(memType); new_nr = revType; fpLen = mFileDNA->getElementSize(filePtrOld[0], filePtrOld[1]); - if (arrayLen==1) + if (arrayLen == 1) { - parseStruct(cpc, cpo, old_nr, new_nr,fixupPointers); - } else + parseStruct(cpc, cpo, old_nr, new_nr, fixupPointers); + } + else { - char* tmpCpc = cpc; - char* tmpCpo = cpo; + char *tmpCpc = cpc; + char *tmpCpo = cpo; - for (int i=0;i3 && type <8) + if (type > 3 && type < 8) { char c; char *cp = data; - for (int i=0; igetPointerSize(); @@ -944,95 +889,90 @@ void bFile::safeSwapPtr(char *dst, const char *src) if (!src && !dst) return; - if (ptrFile == ptrMem) { memcpy(dst, src, ptrMem); } - else if (ptrMem==4 && ptrFile==8) + else if (ptrMem == 4 && ptrFile == 8) { - btPointerUid* oldPtr = (btPointerUid*)src; - btPointerUid* newPtr = (btPointerUid*)dst; + btPointerUid *oldPtr = (btPointerUid *)src; + btPointerUid *newPtr = (btPointerUid *)dst; if (oldPtr->m_uniqueIds[0] == oldPtr->m_uniqueIds[1]) { //Bullet stores the 32bit unique ID in both upper and lower part of 64bit pointers //so it can be used to distinguish between .blend and .bullet newPtr->m_uniqueIds[0] = oldPtr->m_uniqueIds[0]; - } else + } + else { //deal with pointers the Blender .blend style way, see //readfile.c in the Blender source tree - long64 longValue = *((long64*)src); + long64 longValue = *((long64 *)src); //endian swap for 64bit pointer otherwise truncation will fail due to trailing zeros if (mFlags & FD_ENDIAN_SWAP) SWITCH_LONGINT(longValue); - *((int*)dst) = (int)(longValue>>3); + *((int *)dst) = (int)(longValue >> 3); } - } - else if (ptrMem==8 && ptrFile==4) + else if (ptrMem == 8 && ptrFile == 4) { - btPointerUid* oldPtr = (btPointerUid*)src; - btPointerUid* newPtr = (btPointerUid*)dst; + btPointerUid *oldPtr = (btPointerUid *)src; + btPointerUid *newPtr = (btPointerUid *)dst; if (oldPtr->m_uniqueIds[0] == oldPtr->m_uniqueIds[1]) { newPtr->m_uniqueIds[0] = oldPtr->m_uniqueIds[0]; newPtr->m_uniqueIds[1] = 0; - } else + } + else { - *((long64*)dst)= *((int*)src); + *((long64 *)dst) = *((int *)src); } } else { - printf ("%d %d\n", ptrFile,ptrMem); + printf("%d %d\n", ptrFile, ptrMem); assert(0 && "Invalid pointer len"); } - - } - // ----------------------------------------------------- // -void bFile::getMatchingFileDNA(short* dna_addr, const char* lookupName, const char* lookupType, char *strcData, char *data, bool fixupPointers) +void bFile::getMatchingFileDNA(short *dna_addr, const char *lookupName, const char *lookupType, char *strcData, char *data, bool fixupPointers) { // find the matching memory dna data // to the file being loaded. Fill the // memory with the file data... int len = dna_addr[1]; - dna_addr+=2; + dna_addr += 2; - for (int i=0; igetType(dna_addr[0]); - const char* name = mFileDNA->getName(dna_addr[1]); - - + const char *type = mFileDNA->getType(dna_addr[0]); + const char *name = mFileDNA->getName(dna_addr[1]); int eleLen = mFileDNA->getElementSize(dna_addr[0], dna_addr[1]); - if ((mFlags&FD_BROKEN_DNA)!=0) + if ((mFlags & FD_BROKEN_DNA) != 0) { - if ((strcmp(type,"short")==0)&&(strcmp(name,"int")==0)) + if ((strcmp(type, "short") == 0) && (strcmp(name, "int") == 0)) { eleLen = 0; } } - if (strcmp(lookupName, name)==0) + if (strcmp(lookupName, name) == 0) { //int arrayLenold = mFileDNA->getArraySize((char*)name.c_str()); int arrayLen = mFileDNA->getArraySizeNew(dna_addr[1]); //assert(arrayLenold == arrayLen); - + if (name[0] == '*') { // cast pointers int ptrFile = mFileDNA->getPointerSize(); int ptrMem = mMemoryDNA->getPointerSize(); - safeSwapPtr(strcData,data); + safeSwapPtr(strcData, data); if (fixupPointers) { @@ -1040,12 +980,12 @@ void bFile::getMatchingFileDNA(short* dna_addr, const char* lookupName, const c { //void **sarray = (void**)strcData; //void **darray = (void**)data; - - char *cpc, *cpo; - cpc = (char*)strcData; - cpo = (char*)data; - - for (int a=0; agetStruct(old_nr); + short *old = firstStruct; //mFileDNA->getStruct(old_nr); int elementLength = old[1]; - old+=2; + old += 2; - for (int i=0; igetType(old[0]); - char* name = mFileDNA->getName(old[1]); + char *type = mFileDNA->getType(old[0]); + char *name = mFileDNA->getName(old[1]); int len = mFileDNA->getElementSize(old[0], old[1]); - if (strcmp(lookupName, name)==0) + if (strcmp(lookupName, name) == 0) { - if (strcmp(type, lookupType)==0) + if (strcmp(type, lookupType) == 0) { if (foundPos) *foundPos = old; @@ -1104,46 +1042,46 @@ char* bFile::getFileElement(short *firstStruct, char *lookupName, char *lookupTy } return 0; } - data+=len; + data += len; } return 0; } - // ----------------------------------------------------- // -void bFile::swapStruct(int dna_nr, char *data,bool ignoreEndianFlag) +void bFile::swapStruct(int dna_nr, char *data, bool ignoreEndianFlag) { if (dna_nr == -1) return; short *strc = mFileDNA->getStruct(dna_nr); //short *firstStrc = strc; - int elementLen= strc[1]; - strc+=2; + int elementLen = strc[1]; + strc += 2; short first = mFileDNA->getStruct(0)[0]; char *buf = data; - for (int i=0; igetType(strc[0]); char *name = mFileDNA->getName(strc[1]); int size = mFileDNA->getElementSize(strc[0], strc[1]); - if (strc[0] >= first && name[0]!='*') + if (strc[0] >= first && name[0] != '*') { int old_nr = mFileDNA->getReverseType(type); int arrayLen = mFileDNA->getArraySizeNew(strc[1]); - if (arrayLen==1) + if (arrayLen == 1) { - swapStruct(old_nr,buf,ignoreEndianFlag); - } else + swapStruct(old_nr, buf, ignoreEndianFlag); + } + else { - char* tmpBuf = buf; - for (int i=0;igetArraySize(name); int arrayLen = mFileDNA->getArraySizeNew(strc[1]); //assert(arrayLenOld == arrayLen); - swapData(buf, strc[0], arrayLen,ignoreEndianFlag); + swapData(buf, strc[0], arrayLen, ignoreEndianFlag); } - buf+=size; + buf += size; } } void bFile::resolvePointersMismatch() { -// printf("resolvePointersStructMismatch\n"); + // printf("resolvePointersStructMismatch\n"); int i; - for (i=0;i< m_pointerFixupArray.size();i++) + for (i = 0; i < m_pointerFixupArray.size(); i++) { - char* cur = m_pointerFixupArray.at(i); - void** ptrptr = (void**) cur; - void* ptr = *ptrptr; + char *cur = m_pointerFixupArray.at(i); + void **ptrptr = (void **)cur; + void *ptr = *ptrptr; ptr = findLibPointer(ptr); if (ptr) { //printf("Fixup pointer!\n"); *(ptrptr) = ptr; - } else + } + else { -// printf("pointer not found: %x\n",cur); + // printf("pointer not found: %x\n",cur); } } - - for (i=0; igetPointerSize(); int ptrFile = mFileDNA->getPointerSize(); - int blockLen = block->len / ptrFile; void *onptr = findLibPointer(*ptrptr); @@ -1202,16 +1139,16 @@ void bFile::resolvePointersMismatch() addDataBlock(newPtr); memset(newPtr, 0, blockLen * ptrMem); - void **onarray = (void**)onptr; - char *oldPtr = (char*)onarray; + void **onarray = (void **)onptr; + char *oldPtr = (char *)onarray; int p = 0; while (blockLen-- > 0) { btPointerUid dp = {{0}}; - safeSwapPtr((char*)dp.m_uniqueIds, oldPtr); + safeSwapPtr((char *)dp.m_uniqueIds, oldPtr); - void **tptr = (void**)(newPtr + p * ptrMem); + void **tptr = (void **)(newPtr + p * ptrMem); *tptr = findLibPointer(dp.m_ptr); oldPtr += ptrFile; @@ -1224,70 +1161,63 @@ void bFile::resolvePointersMismatch() } } - ///this loop only works fine if the Blender DNA structure of the file matches the headerfiles -void bFile::resolvePointersChunk(const bChunkInd& dataChunk, int verboseMode) +void bFile::resolvePointersChunk(const bChunkInd &dataChunk, int verboseMode) { - bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA; + bParse::bDNA *fileDna = mFileDNA ? mFileDNA : mMemoryDNA; - short int* oldStruct = fileDna->getStruct(dataChunk.dna_nr); + short int *oldStruct = fileDna->getStruct(dataChunk.dna_nr); short oldLen = fileDna->getLength(oldStruct[0]); //char* structType = fileDna->getType(oldStruct[0]); - char* cur = (char*)findLibPointer(dataChunk.oldPtr); - for (int block=0; blockgetStruct(0)[0]; + char *memType; + char *memName; + short firstStructType = fileDna->getStruct(0)[0]; + char *elemPtr = strcPtr; - char* elemPtr= strcPtr; + short int *oldStruct = fileDna->getStruct(dna_nr); - short int* oldStruct = fileDna->getStruct(dna_nr); - int elementLength = oldStruct[1]; - oldStruct+=2; + oldStruct += 2; int totalSize = 0; - for (int ele=0; elegetType(oldStruct[0]); memName = fileDna->getName(oldStruct[1]); - - int arrayLen = fileDna->getArraySizeNew(oldStruct[1]); if (memName[0] == '*') { if (arrayLen > 1) { - void **array= (void**)elemPtr; - for (int a=0; a ",&memName[1]); + printf("<%s type=\"pointer\"> ", &memName[1]); printf("%p ", array[a]); - printf("\n",&memName[1]); + printf("\n", &memName[1]); } array[a] = findLibPointer(array[a]); @@ -1295,266 +1225,259 @@ int bFile::resolvePointersStructRecursive(char *strcPtr, int dna_nr, int verbose } else { - void** ptrptr = (void**) elemPtr; - void* ptr = *ptrptr; + void **ptrptr = (void **)elemPtr; + void *ptr = *ptrptr; if (verboseMode & FD_VERBOSE_EXPORT_XML) { - for (int i=0;i ",&memName[1]); + printf("<%s type=\"pointer\"> ", &memName[1]); printf("%p ", ptr); - printf("\n",&memName[1]); + printf("\n", &memName[1]); } ptr = findLibPointer(ptr); if (ptr) { - // printf("Fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr); + // printf("Fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr); *(ptrptr) = ptr; if (memName[1] == '*' && ptrptr && *ptrptr) { // This will only work if the given **array is continuous - void **array= (void**)*(ptrptr); - void *np= array[0]; - int n=0; + void **array = (void **)*(ptrptr); + void *np = array[0]; + int n = 0; while (np) { - np= findLibPointer(array[n]); - if (np) array[n]= np; + np = findLibPointer(array[n]); + if (np) array[n] = np; n++; } } - } else + } + else { - // printf("Cannot fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr); + // printf("Cannot fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr); } } - } else + } + else { int revType = fileDna->getReverseType(oldStruct[0]); - if (oldStruct[0]>=firstStructType) //revType != -1 && + if (oldStruct[0] >= firstStructType) //revType != -1 && { char cleanName[MAX_STRLEN]; - getCleanName(memName,cleanName); + getCleanName(memName, cleanName); int arrayLen = fileDna->getArraySizeNew(oldStruct[1]); int byteOffset = 0; if (verboseMode & FD_VERBOSE_EXPORT_XML) { - for (int i=0;i1) + if (arrayLen > 1) { - printf("<%s type=\"%s\" count=%d>\n",cleanName,memType, arrayLen); - } else + printf("<%s type=\"%s\" count=%d>\n", cleanName, memType, arrayLen); + } + else { - printf("<%s type=\"%s\">\n",cleanName,memType); + printf("<%s type=\"%s\">\n", cleanName, memType); } } - for (int i=0;i\n",cleanName); + printf("\n", cleanName); } - } else + } + else { //export a simple type if (verboseMode & FD_VERBOSE_EXPORT_XML) { - - if (arrayLen>MAX_ARRAY_LENGTH) + if (arrayLen > MAX_ARRAY_LENGTH) { printf("too long\n"); - } else + } + else { //printf("%s %s\n",memType,memName); - bool isIntegerType = (strcmp(memType,"char")==0) || (strcmp(memType,"int")==0) || (strcmp(memType,"short")==0); + bool isIntegerType = (strcmp(memType, "char") == 0) || (strcmp(memType, "int") == 0) || (strcmp(memType, "short") == 0); if (isIntegerType) { - const char* newtype="int"; + const char *newtype = "int"; int dbarray[MAX_ARRAY_LENGTH]; - int* dbPtr = 0; - char* tmp = elemPtr; + int *dbPtr = 0; + char *tmp = elemPtr; dbPtr = &dbarray[0]; if (dbPtr) { char cleanName[MAX_STRLEN]; - getCleanName(memName,cleanName); + getCleanName(memName, cleanName); int i; - getElement(arrayLen, newtype,memType, tmp, (char*)dbPtr); - for (i=0;i",cleanName,memType); + if (arrayLen == 1) + printf("<%s type=\"%s\">", cleanName, memType); else - printf("<%s type=\"%s\" count=%d>",cleanName,memType,arrayLen); - for (i=0;i\n",cleanName); + printf("<%s type=\"%s\" count=%d>", cleanName, memType, arrayLen); + for (i = 0; i < arrayLen; i++) + printf(" %d ", dbPtr[i]); + printf("\n", cleanName); } - } else + } + else { - const char* newtype="double"; + const char *newtype = "double"; double dbarray[MAX_ARRAY_LENGTH]; - double* dbPtr = 0; - char* tmp = elemPtr; + double *dbPtr = 0; + char *tmp = elemPtr; dbPtr = &dbarray[0]; if (dbPtr) { int i; - getElement(arrayLen, newtype,memType, tmp, (char*)dbPtr); - for (i=0;i",memName,memType); + printf("<%s type=\"%s\">", memName, memType); } else { - printf("<%s type=\"%s\" count=%d>",cleanName,memType,arrayLen); + printf("<%s type=\"%s\" count=%d>", cleanName, memType, arrayLen); } - for (i=0;i\n",cleanName); + for (i = 0; i < arrayLen; i++) + printf(" %f ", dbPtr[i]); + printf("\n", cleanName); } } } - } } } int size = fileDna->getElementSize(oldStruct[0], oldStruct[1]); totalSize += size; - elemPtr+=size; - + elemPtr += size; } return totalSize; } - ///Resolve pointers replaces the original pointers in structures, and linked lists by the new in-memory structures void bFile::resolvePointers(int verboseMode) { - bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA; + bParse::bDNA *fileDna = mFileDNA ? mFileDNA : mMemoryDNA; //char *dataPtr = mFileBuffer+mDataStart; - if (1) //mFlags & (FD_BITS_VARIES | FD_VERSION_VARIES)) + if (1) //mFlags & (FD_BITS_VARIES | FD_VERSION_VARIES)) { - resolvePointersMismatch(); + resolvePointersMismatch(); } - - { + { if (verboseMode & FD_VERBOSE_EXPORT_XML) { printf("\n"); int numitems = m_chunks.size(); printf("\n", btGetVersion(), numitems); } - for (int i=0;iflagEqual(dataChunk.dna_nr)) { //dataChunk.len - short int* oldStruct = fileDna->getStruct(dataChunk.dna_nr); - char* oldType = fileDna->getType(oldStruct[0]); - + short int *oldStruct = fileDna->getStruct(dataChunk.dna_nr); + char *oldType = fileDna->getType(oldStruct[0]); + if (verboseMode & FD_VERBOSE_EXPORT_XML) - printf(" <%s pointer=%p>\n",oldType,dataChunk.oldPtr); + printf(" <%s pointer=%p>\n", oldType, dataChunk.oldPtr); resolvePointersChunk(dataChunk, verboseMode); if (verboseMode & FD_VERBOSE_EXPORT_XML) - printf(" \n",oldType); - } else + printf(" \n", oldType); + } + else { //printf("skipping mStruct\n"); } } - if (verboseMode & FD_VERBOSE_EXPORT_XML) - { - printf("\n"); - } + if (verboseMode & FD_VERBOSE_EXPORT_XML) + { + printf("\n"); + } } - - } - // ----------------------------------------------------- // -void* bFile::findLibPointer(void *ptr) +void *bFile::findLibPointer(void *ptr) { - - bStructHandle** ptrptr = getLibPointers().find(ptr); + bStructHandle **ptrptr = getLibPointers().find(ptr); if (ptrptr) return *ptrptr; return 0; } - -void bFile::updateOldPointers() +void bFile::updateOldPointers() { int i; - for (i=0;igetStruct(dataChunk.dna_nr); - char* typeName = dna->getType(newStruct[0]); - printf("%3d: %s ",i,typeName); + bChunkInd &dataChunk = m_chunks[i]; + char *codeptr = (char *)&dataChunk.code; + char codestr[5] = {codeptr[0], codeptr[1], codeptr[2], codeptr[3], 0}; - printf("code=%s ",codestr); - - printf("ptr=%p ",dataChunk.oldPtr); - printf("len=%d ",dataChunk.len); - printf("nr=%d ",dataChunk.nr); - if (dataChunk.nr!=1) + short *newStruct = dna->getStruct(dataChunk.dna_nr); + char *typeName = dna->getType(newStruct[0]); + printf("%3d: %s ", i, typeName); + + printf("code=%s ", codestr); + + printf("ptr=%p ", dataChunk.oldPtr); + printf("len=%d ", dataChunk.len); + printf("nr=%d ", dataChunk.nr); + if (dataChunk.nr != 1) { printf("not 1\n"); } printf("\n"); - - - - } #if 0 @@ -1570,31 +1493,28 @@ void bFile::dumpChunks(bParse::bDNA* dna) printf("\n"); } #endif - } - -void bFile::writeChunks(FILE* fp, bool fixupPointers) +void bFile::writeChunks(FILE *fp, bool fixupPointers) { - bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA; + bParse::bDNA *fileDna = mFileDNA ? mFileDNA : mMemoryDNA; - for (int i=0;igetStruct(dataChunk.dna_nr); oldType = fileDna->getType(oldStruct[0]); //int oldLen = fileDna->getLength(oldStruct[0]); ///don't try to convert Link block data, just memcpy it. Other data can be converted. reverseOld = mMemoryDNA->getReverseType(oldType); - - if ((reverseOld!=-1)) + if ((reverseOld != -1)) { // make sure it's here //assert(reverseOld!= -1 && "getReverseType() returned -1, struct required!"); @@ -1602,50 +1522,47 @@ void bFile::writeChunks(FILE* fp, bool fixupPointers) curStruct = mMemoryDNA->getStruct(reverseOld); newType = mMemoryDNA->getType(curStruct[0]); // make sure it's the same - assert((strcmp(oldType, newType)==0) && "internal error, struct mismatch!"); + assert((strcmp(oldType, newType) == 0) && "internal error, struct mismatch!"); - curLen = mMemoryDNA->getLength(curStruct[0]); dataChunk.dna_nr = reverseOld; - if (strcmp("Link",oldType)!=0) + if (strcmp("Link", oldType) != 0) { dataChunk.len = curLen * dataChunk.nr; - } else - { -// printf("keep length of link = %d\n",dataChunk.len); } - + else + { + // printf("keep length of link = %d\n",dataChunk.len); + } + //write the structure header - fwrite(&dataChunk,sizeof(bChunkInd),1,fp); - + fwrite(&dataChunk, sizeof(bChunkInd), 1, fp); - - short int* curStruct1; + short int *curStruct1; curStruct1 = mMemoryDNA->getStruct(dataChunk.dna_nr); assert(curStruct1 == curStruct); - char* cur = fixupPointers ? (char*)findLibPointer(dataChunk.oldPtr) : (char*)dataChunk.oldPtr; + char *cur = fixupPointers ? (char *)findLibPointer(dataChunk.oldPtr) : (char *)dataChunk.oldPtr; //write the actual contents of the structure(s) - fwrite(cur,dataChunk.len,1,fp); - } else + fwrite(cur, dataChunk.len, 1, fp); + } + else { printf("serious error, struct mismatch: don't write\n"); } } - } - // ----------------------------------------------------- // -int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags) +int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags) { bool swap = false; bool varies = false; - if (flags &FD_ENDIAN_SWAP) + if (flags & FD_ENDIAN_SWAP) swap = true; - if (flags &FD_BITS_VARIES) + if (flags & FD_BITS_VARIES) varies = true; if (VOID_IS_8) @@ -1655,27 +1572,25 @@ int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int fl bChunkPtr4 head; memcpy(&head, dataPtr, sizeof(bChunkPtr4)); - bChunkPtr8 chunk; - chunk.code = head.code; - chunk.len = head.len; + chunk.code = head.code; + chunk.len = head.len; chunk.m_uniqueInts[0] = head.m_uniqueInt; chunk.m_uniqueInts[1] = 0; - chunk.dna_nr = head.dna_nr; - chunk.nr = head.nr; + chunk.dna_nr = head.dna_nr; + chunk.nr = head.nr; if (swap) { - if ((chunk.code & 0xFFFF)==0) - chunk.code >>=16; + if ((chunk.code & 0xFFFF) == 0) + chunk.code >>= 16; SWITCH_INT(chunk.len); SWITCH_INT(chunk.dna_nr); SWITCH_INT(chunk.nr); } - memcpy(dataChunk, &chunk, sizeof(bChunkInd)); } else @@ -1685,8 +1600,8 @@ int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int fl if (swap) { - if ((c.code & 0xFFFF)==0) - c.code >>=16; + if ((c.code & 0xFFFF) == 0) + c.code >>= 16; SWITCH_INT(c.len); SWITCH_INT(c.dna_nr); @@ -1703,31 +1618,30 @@ int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int fl bChunkPtr8 head; memcpy(&head, dataPtr, sizeof(bChunkPtr8)); - bChunkPtr4 chunk; chunk.code = head.code; chunk.len = head.len; - if (head.m_uniqueInts[0]==head.m_uniqueInts[1]) + if (head.m_uniqueInts[0] == head.m_uniqueInts[1]) { chunk.m_uniqueInt = head.m_uniqueInts[0]; - } else + } + else { - long64 oldPtr =0; + long64 oldPtr = 0; memcpy(&oldPtr, &head.m_uniqueInts[0], 8); - if (swap) + if (swap) SWITCH_LONGINT(oldPtr); chunk.m_uniqueInt = (int)(oldPtr >> 3); } - chunk.dna_nr = head.dna_nr; chunk.nr = head.nr; if (swap) { - if ((chunk.code & 0xFFFF)==0) - chunk.code >>=16; + if ((chunk.code & 0xFFFF) == 0) + chunk.code >>= 16; SWITCH_INT(chunk.len); SWITCH_INT(chunk.dna_nr); @@ -1743,8 +1657,8 @@ int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int fl if (swap) { - if ((c.code & 0xFFFF)==0) - c.code >>=16; + if ((c.code & 0xFFFF) == 0) + c.code >>= 16; SWITCH_INT(c.len); SWITCH_INT(c.dna_nr); @@ -1765,9 +1679,7 @@ int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int fl print (dataChunk->dna_nr); print (dataChunk->nr); #endif - return (dataChunk->len+ChunkUtils::getOffset(flags)); + return (dataChunk->len + ChunkUtils::getOffset(flags)); } - - //eof diff --git a/Extras/Serialize/BulletFileLoader/bFile.h b/Extras/Serialize/BulletFileLoader/bFile.h index e3523febb..f6fae97ed 100644 --- a/Extras/Serialize/BulletFileLoader/bFile.h +++ b/Extras/Serialize/BulletFileLoader/bFile.h @@ -20,156 +20,147 @@ subject to the following restrictions: #include "bChunk.h" #include -namespace bParse { +namespace bParse +{ +// ----------------------------------------------------- // +enum bFileFlags +{ + FD_INVALID = 0, + FD_OK = 1, + FD_VOID_IS_8 = 2, + FD_ENDIAN_SWAP = 4, + FD_FILE_64 = 8, + FD_BITS_VARIES = 16, + FD_VERSION_VARIES = 32, + FD_DOUBLE_PRECISION = 64, + FD_BROKEN_DNA = 128, + FD_FILEDNA_IS_MEMDNA = 256 +}; - // ----------------------------------------------------- // - enum bFileFlags +enum bFileVerboseMode +{ + FD_VERBOSE_EXPORT_XML = 1, + FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS = 2, + FD_VERBOSE_DUMP_CHUNKS = 4, + FD_VERBOSE_DUMP_FILE_INFO = 8, +}; +// ----------------------------------------------------- // +class bFile +{ +protected: + char m_headerString[7]; + + bool mOwnsBuffer; + char* mFileBuffer; + int mFileLen; + int mVersion; + + bPtrMap mLibPointers; + + int mDataStart; + bDNA* mFileDNA; + bDNA* mMemoryDNA; + + btAlignedObjectArray m_pointerFixupArray; + btAlignedObjectArray m_pointerPtrFixupArray; + + btAlignedObjectArray m_chunks; + btHashMap m_chunkPtrPtrMap; + + // + + bPtrMap mDataPointers; + + int mFlags; + + // //////////////////////////////////////////////////////////////////////////// + + // buffer offset util + int getNextBlock(bChunkInd* dataChunk, const char* dataPtr, const int flags); + void safeSwapPtr(char* dst, const char* src); + + virtual void parseHeader(); + + virtual void parseData() = 0; + + void resolvePointersMismatch(); + void resolvePointersChunk(const bChunkInd& dataChunk, int verboseMode); + + int resolvePointersStructRecursive(char* strcPtr, int old_dna, int verboseMode, int recursion); + //void swapPtr(char *dst, char *src); + + void parseStruct(char* strcPtr, char* dtPtr, int old_dna, int new_dna, bool fixupPointers); + void getMatchingFileDNA(short* old, const char* lookupName, const char* lookupType, char* strcData, char* data, bool fixupPointers); + char* getFileElement(short* firstStruct, char* lookupName, char* lookupType, char* data, short** foundPos); + + void swap(char* head, class bChunkInd& ch, bool ignoreEndianFlag); + void swapData(char* data, short type, int arraySize, bool ignoreEndianFlag); + void swapStruct(int dna_nr, char* data, bool ignoreEndianFlag); + void swapLen(char* dataPtr); + void swapDNA(char* ptr); + + char* readStruct(char* head, class bChunkInd& chunk); + char* getAsString(int code); + + virtual void parseInternal(int verboseMode, char* memDna, int memDnaLength); + +public: + bFile(const char* filename, const char headerString[7]); + + //todo: make memoryBuffer const char + //bFile( const char *memoryBuffer, int len); + bFile(char* memoryBuffer, int len, const char headerString[7]); + virtual ~bFile(); + + bDNA* getFileDNA() { - FD_INVALID =0, - FD_OK =1, - FD_VOID_IS_8 =2, - FD_ENDIAN_SWAP =4, - FD_FILE_64 =8, - FD_BITS_VARIES =16, - FD_VERSION_VARIES = 32, - FD_DOUBLE_PRECISION =64, - FD_BROKEN_DNA = 128, - FD_FILEDNA_IS_MEMDNA = 256 - }; + return mFileDNA; + } - enum bFileVerboseMode + virtual void addDataBlock(char* dataBlock) = 0; + + int getFlags() const { - FD_VERBOSE_EXPORT_XML = 1, - FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS = 2, - FD_VERBOSE_DUMP_CHUNKS = 4, - FD_VERBOSE_DUMP_FILE_INFO=8, - }; - // ----------------------------------------------------- // - class bFile + return mFlags; + } + + void setFileDNAisMemoryDNA() { - protected: - - char m_headerString[7]; + mFlags |= FD_FILEDNA_IS_MEMDNA; + } - bool mOwnsBuffer; - char* mFileBuffer; - int mFileLen; - int mVersion; + bPtrMap& getLibPointers() + { + return mLibPointers; + } + void* findLibPointer(void* ptr); - bPtrMap mLibPointers; + bool ok(); - int mDataStart; - bDNA* mFileDNA; - bDNA* mMemoryDNA; + virtual void parse(int verboseMode) = 0; - btAlignedObjectArray m_pointerFixupArray; - btAlignedObjectArray m_pointerPtrFixupArray; - - btAlignedObjectArray m_chunks; - btHashMap m_chunkPtrPtrMap; + virtual int write(const char* fileName, bool fixupPointers = false) = 0; - // - - bPtrMap mDataPointers; + virtual void writeChunks(FILE* fp, bool fixupPointers); - - int mFlags; + virtual void writeDNA(FILE* fp) = 0; - // //////////////////////////////////////////////////////////////////////////// + void updateOldPointers(); + void resolvePointers(int verboseMode); - // buffer offset util - int getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags); - void safeSwapPtr(char *dst, const char *src); + void dumpChunks(bDNA* dna); - virtual void parseHeader(); - - virtual void parseData() = 0; + virtual void setFileDNA(int verboseMode, char* buffer, int len); - void resolvePointersMismatch(); - void resolvePointersChunk(const bChunkInd& dataChunk, int verboseMode); + int getVersion() const + { + return mVersion; + } + //pre-swap the endianness, so that data loaded on a target with different endianness doesn't need to be swapped + void preSwap(); + void writeFile(const char* fileName); +}; +} // namespace bParse - int resolvePointersStructRecursive(char *strcPtr, int old_dna, int verboseMode, int recursion); - //void swapPtr(char *dst, char *src); - - void parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bool fixupPointers); - void getMatchingFileDNA(short* old, const char* lookupName, const char* lookupType, char *strcData, char *data, bool fixupPointers); - char* getFileElement(short *firstStruct, char *lookupName, char *lookupType, char *data, short **foundPos); - - - void swap(char *head, class bChunkInd& ch, bool ignoreEndianFlag); - void swapData(char *data, short type, int arraySize, bool ignoreEndianFlag); - void swapStruct(int dna_nr, char *data, bool ignoreEndianFlag); - void swapLen(char *dataPtr); - void swapDNA(char* ptr); - - - char* readStruct(char *head, class bChunkInd& chunk); - char *getAsString(int code); - - virtual void parseInternal(int verboseMode, char* memDna,int memDnaLength); - - public: - bFile(const char *filename, const char headerString[7]); - - //todo: make memoryBuffer const char - //bFile( const char *memoryBuffer, int len); - bFile( char *memoryBuffer, int len, const char headerString[7]); - virtual ~bFile(); - - bDNA* getFileDNA() - { - return mFileDNA; - } - - virtual void addDataBlock(char* dataBlock) = 0; - - int getFlags() const - { - return mFlags; - } - - void setFileDNAisMemoryDNA() - { - mFlags |= FD_FILEDNA_IS_MEMDNA; - } - - bPtrMap& getLibPointers() - { - return mLibPointers; - } - - void* findLibPointer(void *ptr); - - bool ok(); - - virtual void parse(int verboseMode) = 0; - - virtual int write(const char* fileName, bool fixupPointers=false) = 0; - - virtual void writeChunks(FILE* fp, bool fixupPointers ); - - virtual void writeDNA(FILE* fp) = 0; - - void updateOldPointers(); - void resolvePointers(int verboseMode); - - void dumpChunks(bDNA* dna); - - virtual void setFileDNA(int verboseMode, char* buffer, int len); - - int getVersion() const - { - return mVersion; - } - //pre-swap the endianness, so that data loaded on a target with different endianness doesn't need to be swapped - void preSwap(); - void writeFile(const char* fileName); - - - - }; -} - - -#endif//__BFILE_H__ +#endif //__BFILE_H__ diff --git a/Extras/Serialize/BulletFileLoader/btBulletFile.cpp b/Extras/Serialize/BulletFileLoader/btBulletFile.cpp index 34333f38b..1f855f41f 100644 --- a/Extras/Serialize/BulletFileLoader/btBulletFile.cpp +++ b/Extras/Serialize/BulletFileLoader/btBulletFile.cpp @@ -17,12 +17,11 @@ subject to the following restrictions: #include "bDefines.h" #include "bDNA.h" -#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__) +#if !defined(__CELLOS_LV2__) && !defined(__MWERKS__) #include #endif #include - // 32 && 64 bit versions #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES #ifdef _WIN64 @@ -31,137 +30,123 @@ extern int sBulletDNAlen64; #else extern char sBulletDNAstr[]; extern int sBulletDNAlen; -#endif //_WIN64 -#else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +#endif //_WIN64 +#else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES extern char sBulletDNAstr64[]; extern int sBulletDNAlen64; extern char sBulletDNAstr[]; extern int sBulletDNAlen; -#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES using namespace bParse; btBulletFile::btBulletFile() -:bFile("", "BULLET ") + : bFile("", "BULLET ") { - mMemoryDNA = new bDNA(); //this memory gets released in the bFile::~bFile destructor,@todo not consistent with the rule 'who allocates it, has to deallocate it" + mMemoryDNA = new bDNA(); //this memory gets released in the bFile::~bFile destructor,@todo not consistent with the rule 'who allocates it, has to deallocate it" m_DnaCopy = 0; - #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES #ifdef _WIN64 - m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64,16); - memcpy(m_DnaCopy,sBulletDNAstr64,sBulletDNAlen64); - mMemoryDNA->init(m_DnaCopy,sBulletDNAlen64); -#else//_WIN64 - m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen,16); - memcpy(m_DnaCopy,sBulletDNAstr,sBulletDNAlen); - mMemoryDNA->init(m_DnaCopy,sBulletDNAlen); -#endif//_WIN64 -#else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64, 16); + memcpy(m_DnaCopy, sBulletDNAstr64, sBulletDNAlen64); + mMemoryDNA->init(m_DnaCopy, sBulletDNAlen64); +#else //_WIN64 + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen, 16); + memcpy(m_DnaCopy, sBulletDNAstr, sBulletDNAlen); + mMemoryDNA->init(m_DnaCopy, sBulletDNAlen); +#endif //_WIN64 +#else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES if (VOID_IS_8) { - m_DnaCopy = (char*) btAlignedAlloc(sBulletDNAlen64,16); - memcpy(m_DnaCopy,sBulletDNAstr64,sBulletDNAlen64); - mMemoryDNA->init(m_DnaCopy,sBulletDNAlen64); + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64, 16); + memcpy(m_DnaCopy, sBulletDNAstr64, sBulletDNAlen64); + mMemoryDNA->init(m_DnaCopy, sBulletDNAlen64); } else { - m_DnaCopy =(char*) btAlignedAlloc(sBulletDNAlen,16); - memcpy(m_DnaCopy,sBulletDNAstr,sBulletDNAlen); - mMemoryDNA->init(m_DnaCopy,sBulletDNAlen); + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen, 16); + memcpy(m_DnaCopy, sBulletDNAstr, sBulletDNAlen); + mMemoryDNA->init(m_DnaCopy, sBulletDNAlen); } -#endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES } - - btBulletFile::btBulletFile(const char* fileName) -:bFile(fileName, "BULLET ") + : bFile(fileName, "BULLET ") { m_DnaCopy = 0; } - - -btBulletFile::btBulletFile(char *memoryBuffer, int len) -:bFile(memoryBuffer,len, "BULLET ") +btBulletFile::btBulletFile(char* memoryBuffer, int len) + : bFile(memoryBuffer, len, "BULLET ") { m_DnaCopy = 0; } - btBulletFile::~btBulletFile() { if (m_DnaCopy) btAlignedFree(m_DnaCopy); - while (m_dataBlocks.size()) { - char* dataBlock = m_dataBlocks[m_dataBlocks.size()-1]; + char* dataBlock = m_dataBlocks[m_dataBlocks.size() - 1]; delete[] dataBlock; m_dataBlocks.pop_back(); } - } - - // ----------------------------------------------------- // void btBulletFile::parseData() { -// printf ("Building datablocks"); -// printf ("Chunk size = %d",CHUNK_HEADER_LEN); -// printf ("File chunk size = %d",ChunkUtils::getOffset(mFlags)); + // printf ("Building datablocks"); + // printf ("Chunk size = %d",CHUNK_HEADER_LEN); + // printf ("File chunk size = %d",ChunkUtils::getOffset(mFlags)); - const bool brokenDNA = (mFlags&FD_BROKEN_DNA)!=0; + const bool brokenDNA = (mFlags & FD_BROKEN_DNA) != 0; //const bool swap = (mFlags&FD_ENDIAN_SWAP)!=0; - int remain = mFileLen; mDataStart = 12; - remain-=12; - + remain -= 12; + //invalid/empty file? if (remain < sizeof(bChunkInd)) return; - char *dataPtr = mFileBuffer+mDataStart; + char* dataPtr = mFileBuffer + mDataStart; bChunkInd dataChunk; dataChunk.code = 0; - //dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags); int seek = getNextBlock(&dataChunk, dataPtr, mFlags); - - - if (mFlags &FD_ENDIAN_SWAP) + + if (mFlags & FD_ENDIAN_SWAP) swapLen(dataPtr); //dataPtr += ChunkUtils::getOffset(mFlags); - char *dataPtrHead = 0; + char* dataPtrHead = 0; while (dataChunk.code != DNA1) { - if (!brokenDNA || (dataChunk.code != BT_QUANTIZED_BVH_CODE) ) + if (!brokenDNA || (dataChunk.code != BT_QUANTIZED_BVH_CODE)) { - // one behind if (dataChunk.code == SDNA) break; //if (dataChunk.code == DNA1) break; // same as (BHEAD+DATA dependency) - dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags); - if (dataChunk.dna_nr>=0) + dataPtrHead = dataPtr + ChunkUtils::getOffset(mFlags); + if (dataChunk.dna_nr >= 0) { - char *id = readStruct(dataPtrHead, dataChunk); + char* id = readStruct(dataPtrHead, dataChunk); // lookup maps if (id) @@ -192,99 +177,94 @@ void btBulletFile::parseData() if (dataChunk.code == BT_SOFTBODY_CODE) { - m_softBodies.push_back((bStructHandle*) id); + m_softBodies.push_back((bStructHandle*)id); } - + if (dataChunk.code == BT_RIGIDBODY_CODE) { - m_rigidBodies.push_back((bStructHandle*) id); + m_rigidBodies.push_back((bStructHandle*)id); } if (dataChunk.code == BT_DYNAMICSWORLD_CODE) { - m_dynamicsWorldInfo.push_back((bStructHandle*) id); + m_dynamicsWorldInfo.push_back((bStructHandle*)id); } if (dataChunk.code == BT_CONSTRAINT_CODE) { - m_constraints.push_back((bStructHandle*) id); + m_constraints.push_back((bStructHandle*)id); } if (dataChunk.code == BT_QUANTIZED_BVH_CODE) { - m_bvhs.push_back((bStructHandle*) id); + m_bvhs.push_back((bStructHandle*)id); } if (dataChunk.code == BT_TRIANLGE_INFO_MAP) { - m_triangleInfoMaps.push_back((bStructHandle*) id); + m_triangleInfoMaps.push_back((bStructHandle*)id); } if (dataChunk.code == BT_COLLISIONOBJECT_CODE) { - m_collisionObjects.push_back((bStructHandle*) id); + m_collisionObjects.push_back((bStructHandle*)id); } if (dataChunk.code == BT_SHAPE_CODE) { - m_collisionShapes.push_back((bStructHandle*) id); + m_collisionShapes.push_back((bStructHandle*)id); } - // if (dataChunk.code == GLOB) - // { - // m_glob = (bStructHandle*) id; - // } - } else + // if (dataChunk.code == GLOB) + // { + // m_glob = (bStructHandle*) id; + // } + } + else { //printf("unknown chunk\n"); mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)dataPtrHead); } - } else + } + else { printf("skipping BT_QUANTIZED_BVH_CODE due to broken DNA\n"); } - dataPtr += seek; - remain-=seek; - if (remain<=0) + remain -= seek; + if (remain <= 0) break; - seek = getNextBlock(&dataChunk, dataPtr, mFlags); - if (mFlags &FD_ENDIAN_SWAP) + seek = getNextBlock(&dataChunk, dataPtr, mFlags); + if (mFlags & FD_ENDIAN_SWAP) swapLen(dataPtr); if (seek < 0) break; } - } -void btBulletFile::addDataBlock(char* dataBlock) +void btBulletFile::addDataBlock(char* dataBlock) { m_dataBlocks.push_back(dataBlock); - } - - - -void btBulletFile::writeDNA(FILE* fp) +void btBulletFile::writeDNA(FILE* fp) { - bChunkInd dataChunk; dataChunk.code = DNA1; dataChunk.dna_nr = 0; dataChunk.nr = 1; -#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +#ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES if (VOID_IS_8) { #ifdef _WIN64 dataChunk.len = sBulletDNAlen64; dataChunk.oldPtr = sBulletDNAstr64; - fwrite(&dataChunk,sizeof(bChunkInd),1,fp); - fwrite(sBulletDNAstr64, sBulletDNAlen64,1,fp); + fwrite(&dataChunk, sizeof(bChunkInd), 1, fp); + fwrite(sBulletDNAstr64, sBulletDNAlen64, 1, fp); #else btAssert(0); #endif @@ -294,43 +274,42 @@ void btBulletFile::writeDNA(FILE* fp) #ifndef _WIN64 dataChunk.len = sBulletDNAlen; dataChunk.oldPtr = sBulletDNAstr; - fwrite(&dataChunk,sizeof(bChunkInd),1,fp); - fwrite(sBulletDNAstr, sBulletDNAlen,1,fp); -#else//_WIN64 + fwrite(&dataChunk, sizeof(bChunkInd), 1, fp); + fwrite(sBulletDNAstr, sBulletDNAlen, 1, fp); +#else //_WIN64 btAssert(0); -#endif//_WIN64 +#endif //_WIN64 } -#else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +#else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES if (VOID_IS_8) { dataChunk.len = sBulletDNAlen64; dataChunk.oldPtr = sBulletDNAstr64; - fwrite(&dataChunk,sizeof(bChunkInd),1,fp); - fwrite(sBulletDNAstr64, sBulletDNAlen64,1,fp); + fwrite(&dataChunk, sizeof(bChunkInd), 1, fp); + fwrite(sBulletDNAstr64, sBulletDNAlen64, 1, fp); } else { dataChunk.len = sBulletDNAlen; dataChunk.oldPtr = sBulletDNAstr; - fwrite(&dataChunk,sizeof(bChunkInd),1,fp); - fwrite(sBulletDNAstr, sBulletDNAlen,1,fp); + fwrite(&dataChunk, sizeof(bChunkInd), 1, fp); + fwrite(sBulletDNAstr, sBulletDNAlen, 1, fp); } -#endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES } - -void btBulletFile::parse(int verboseMode) +void btBulletFile::parse(int verboseMode) { #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES if (VOID_IS_8) { #ifdef _WIN64 - + if (m_DnaCopy) delete m_DnaCopy; - m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64,16); - memcpy(m_DnaCopy,sBulletDNAstr64,sBulletDNAlen64); - parseInternal(verboseMode,(char*)sBulletDNAstr64,sBulletDNAlen64); + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64, 16); + memcpy(m_DnaCopy, sBulletDNAstr64, sBulletDNAlen64); + parseInternal(verboseMode, (char*)sBulletDNAstr64, sBulletDNAlen64); #else btAssert(0); #endif @@ -341,93 +320,91 @@ void btBulletFile::parse(int verboseMode) if (m_DnaCopy) delete m_DnaCopy; - m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen,16); - memcpy(m_DnaCopy,sBulletDNAstr,sBulletDNAlen); - parseInternal(verboseMode,m_DnaCopy,sBulletDNAlen); + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen, 16); + memcpy(m_DnaCopy, sBulletDNAstr, sBulletDNAlen); + parseInternal(verboseMode, m_DnaCopy, sBulletDNAlen); #else btAssert(0); #endif } -#else//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +#else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES if (VOID_IS_8) { if (m_DnaCopy) delete m_DnaCopy; - m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64,16); - memcpy(m_DnaCopy,sBulletDNAstr64,sBulletDNAlen64); - parseInternal(verboseMode,m_DnaCopy,sBulletDNAlen64); + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen64, 16); + memcpy(m_DnaCopy, sBulletDNAstr64, sBulletDNAlen64); + parseInternal(verboseMode, m_DnaCopy, sBulletDNAlen64); } else { if (m_DnaCopy) delete m_DnaCopy; - m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen,16); - memcpy(m_DnaCopy,sBulletDNAstr,sBulletDNAlen); - parseInternal(verboseMode,m_DnaCopy,sBulletDNAlen); + m_DnaCopy = (char*)btAlignedAlloc(sBulletDNAlen, 16); + memcpy(m_DnaCopy, sBulletDNAstr, sBulletDNAlen); + parseInternal(verboseMode, m_DnaCopy, sBulletDNAlen); } -#endif//BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES - - //the parsing will convert to cpu endian - mFlags &=~FD_ENDIAN_SWAP; +#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES - int littleEndian= 1; - littleEndian= ((char*)&littleEndian)[0]; - - mFileBuffer[8] = littleEndian?'v':'V'; - + //the parsing will convert to cpu endian + mFlags &= ~FD_ENDIAN_SWAP; + + int littleEndian = 1; + littleEndian = ((char*)&littleEndian)[0]; + + mFileBuffer[8] = littleEndian ? 'v' : 'V'; } // experimental -int btBulletFile::write(const char* fileName, bool fixupPointers) +int btBulletFile::write(const char* fileName, bool fixupPointers) { - FILE *fp = fopen(fileName, "wb"); + FILE* fp = fopen(fileName, "wb"); if (fp) { - char header[SIZEOFBLENDERHEADER] ; + char header[SIZEOFBLENDERHEADER]; memcpy(header, m_headerString, 7); - int endian= 1; - endian= ((char*)&endian)[0]; + int endian = 1; + endian = ((char*)&endian)[0]; if (endian) { header[7] = '_'; - } else + } + else { header[7] = '-'; } if (VOID_IS_8) { - header[8]='V'; - } else + header[8] = 'V'; + } + else { - header[8]='v'; + header[8] = 'v'; } header[9] = '2'; header[10] = '7'; header[11] = '5'; - - fwrite(header,SIZEOFBLENDERHEADER,1,fp); + + fwrite(header, SIZEOFBLENDERHEADER, 1, fp); writeChunks(fp, fixupPointers); writeDNA(fp); fclose(fp); - - } else + } + else { - printf("Error: cannot open file %s for writing\n",fileName); + printf("Error: cannot open file %s for writing\n", fileName); return 0; } return 1; } - - -void btBulletFile::addStruct(const char* structType,void* data, int len, void* oldPtr, int code) +void btBulletFile::addStruct(const char* structType, void* data, int len, void* oldPtr, int code) { - bParse::bChunkInd dataChunk; dataChunk.code = code; dataChunk.nr = 1; @@ -436,13 +413,12 @@ void btBulletFile::addStruct(const char* structType,void* data, int len, void* o dataChunk.oldPtr = oldPtr; ///Perform structure size validation - short* structInfo= mMemoryDNA->getStruct(dataChunk.dna_nr); + short* structInfo = mMemoryDNA->getStruct(dataChunk.dna_nr); int elemBytes; - elemBytes= mMemoryDNA->getLength(structInfo[0]); -// int elemBytes = mMemoryDNA->getElementSize(structInfo[0],structInfo[1]); - assert(len==elemBytes); + elemBytes = mMemoryDNA->getLength(structInfo[0]); + // int elemBytes = mMemoryDNA->getElementSize(structInfo[0],structInfo[1]); + assert(len == elemBytes); mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)data); m_chunks.push_back(dataChunk); } - diff --git a/Extras/Serialize/BulletFileLoader/btBulletFile.h b/Extras/Serialize/BulletFileLoader/btBulletFile.h index b6997c2d5..d7c1cb7e0 100644 --- a/Extras/Serialize/BulletFileLoader/btBulletFile.h +++ b/Extras/Serialize/BulletFileLoader/btBulletFile.h @@ -16,75 +16,65 @@ subject to the following restrictions: #ifndef BT_BULLET_FILE_H #define BT_BULLET_FILE_H - #include "bFile.h" #include "LinearMath/btAlignedObjectArray.h" #include "bDefines.h" - #include "LinearMath/btSerializer.h" +namespace bParse +{ +// ----------------------------------------------------- // +class btBulletFile : public bFile +{ +protected: + char* m_DnaCopy; +public: + btAlignedObjectArray m_multiBodies; -namespace bParse { + btAlignedObjectArray m_multiBodyLinkColliders; - // ----------------------------------------------------- // - class btBulletFile : public bFile - { - + btAlignedObjectArray m_softBodies; - protected: - - char* m_DnaCopy; - - public: + btAlignedObjectArray m_rigidBodies; - btAlignedObjectArray m_multiBodies; + btAlignedObjectArray m_collisionObjects; - btAlignedObjectArray m_multiBodyLinkColliders; + btAlignedObjectArray m_collisionShapes; - btAlignedObjectArray m_softBodies; + btAlignedObjectArray m_constraints; - btAlignedObjectArray m_rigidBodies; + btAlignedObjectArray m_bvhs; - btAlignedObjectArray m_collisionObjects; + btAlignedObjectArray m_triangleInfoMaps; - btAlignedObjectArray m_collisionShapes; + btAlignedObjectArray m_dynamicsWorldInfo; - btAlignedObjectArray m_constraints; + btAlignedObjectArray m_contactManifolds; - btAlignedObjectArray m_bvhs; + btAlignedObjectArray m_dataBlocks; + btBulletFile(); - btAlignedObjectArray m_triangleInfoMaps; + btBulletFile(const char* fileName); - btAlignedObjectArray m_dynamicsWorldInfo; + btBulletFile(char* memoryBuffer, int len); - btAlignedObjectArray m_contactManifolds; + virtual ~btBulletFile(); - btAlignedObjectArray m_dataBlocks; - btBulletFile(); + virtual void addDataBlock(char* dataBlock); - btBulletFile(const char* fileName); + // experimental + virtual int write(const char* fileName, bool fixupPointers = false); - btBulletFile(char *memoryBuffer, int len); + virtual void parse(int verboseMode); - virtual ~btBulletFile(); + virtual void parseData(); - virtual void addDataBlock(char* dataBlock); - - - // experimental - virtual int write(const char* fileName, bool fixupPointers=false); + virtual void writeDNA(FILE* fp); - virtual void parse(int verboseMode); - - virtual void parseData(); - - virtual void writeDNA(FILE* fp); - - void addStruct(const char* structType,void* data, int len, void* oldPtr, int code); - - }; + void addStruct(const char* structType, void* data, int len, void* oldPtr, int code); }; +}; // namespace bParse -#endif //BT_BULLET_FILE_H +#endif //BT_BULLET_FILE_H diff --git a/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp b/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp index 3605863ec..b50f05654 100644 --- a/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp +++ b/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btBulletWorldImporter.h" #include "../BulletFileLoader/btBulletFile.h" @@ -22,14 +21,13 @@ subject to the following restrictions: #include "BulletCollision/Gimpact/btGImpactShape.h" #endif - //#define USE_INTERNAL_EDGE_UTILITY #ifdef USE_INTERNAL_EDGE_UTILITY #include "BulletCollision/CollisionDispatch/btInternalEdgeUtility.h" -#endif //USE_INTERNAL_EDGE_UTILITY +#endif //USE_INTERNAL_EDGE_UTILITY btBulletWorldImporter::btBulletWorldImporter(btDynamicsWorld* world) - :btWorldImporter(world) + : btWorldImporter(world) { } @@ -37,12 +35,10 @@ btBulletWorldImporter::~btBulletWorldImporter() { } - -bool btBulletWorldImporter::loadFile( const char* fileName, const char* preSwapFilenameOut) +bool btBulletWorldImporter::loadFile(const char* fileName, const char* preSwapFilenameOut) { bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(fileName); - bool result = loadFileFromMemory(bulletFile2); //now you could save the file in 'native' format using //bulletFile2->writeFile("native.bullet"); @@ -53,19 +49,15 @@ bool btBulletWorldImporter::loadFile( const char* fileName, const char* preSwapF bulletFile2->preSwap(); bulletFile2->writeFile(preSwapFilenameOut); } - } delete bulletFile2; - - return result; + return result; } - - -bool btBulletWorldImporter::loadFileFromMemory( char* memoryBuffer, int len) +bool btBulletWorldImporter::loadFileFromMemory(char* memoryBuffer, int len) { - bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(memoryBuffer,len); + bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(memoryBuffer, len); bool result = loadFileFromMemory(bulletFile2); @@ -74,36 +66,31 @@ bool btBulletWorldImporter::loadFileFromMemory( char* memoryBuffer, int len) return result; } - - - -bool btBulletWorldImporter::loadFileFromMemory( bParse::btBulletFile* bulletFile2) +bool btBulletWorldImporter::loadFileFromMemory(bParse::btBulletFile* bulletFile2) { - bool ok = (bulletFile2->getFlags()& bParse::FD_OK)!=0; - + bool ok = (bulletFile2->getFlags() & bParse::FD_OK) != 0; + if (ok) bulletFile2->parse(m_verboseMode); - else + else return false; - + if (m_verboseMode & bParse::FD_VERBOSE_DUMP_CHUNKS) { bulletFile2->dumpChunks(bulletFile2->getFileDNA()); } return convertAllObjects(bulletFile2); - } -bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile2) +bool btBulletWorldImporter::convertAllObjects(bParse::btBulletFile* bulletFile2) { - m_shapeMap.clear(); m_bodyMap.clear(); int i; - - for (i=0;im_bvhs.size();i++) + + for (i = 0; i < bulletFile2->m_bvhs.size(); i++) { btOptimizedBvh* bvh = createOptimizedBvh(); @@ -111,41 +98,34 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile { btQuantizedBvhDoubleData* bvhData = (btQuantizedBvhDoubleData*)bulletFile2->m_bvhs[i]; bvh->deSerializeDouble(*bvhData); - } else + } + else { btQuantizedBvhFloatData* bvhData = (btQuantizedBvhFloatData*)bulletFile2->m_bvhs[i]; bvh->deSerializeFloat(*bvhData); } - m_bvhMap.insert(bulletFile2->m_bvhs[i],bvh); + m_bvhMap.insert(bulletFile2->m_bvhs[i], bvh); } - - - - - for (i=0;im_collisionShapes.size();i++) + for (i = 0; i < bulletFile2->m_collisionShapes.size(); i++) { btCollisionShapeData* shapeData = (btCollisionShapeData*)bulletFile2->m_collisionShapes[i]; btCollisionShape* shape = convertCollisionShape(shapeData); if (shape) { - // printf("shapeMap.insert(%x,%x)\n",shapeData,shape); - m_shapeMap.insert(shapeData,shape); + // printf("shapeMap.insert(%x,%x)\n",shapeData,shape); + m_shapeMap.insert(shapeData, shape); } - if (shape&& shapeData->m_name) + if (shape && shapeData->m_name) { char* newname = duplicateName(shapeData->m_name); - m_objectNameMap.insert(shape,newname); - m_nameShapeMap.insert(newname,shape); + m_objectNameMap.insert(shape, newname); + m_nameShapeMap.insert(newname, shape); } } - - - - - for (int i=0;im_dynamicsWorldInfo.size();i++) + for (int i = 0; i < bulletFile2->m_dynamicsWorldInfo.size(); i++) { if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) { @@ -169,21 +149,22 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile solverInfo.m_globalCfm = btScalar(solverInfoData->m_solverInfo.m_globalCfm); solverInfo.m_splitImpulsePenetrationThreshold = btScalar(solverInfoData->m_solverInfo.m_splitImpulsePenetrationThreshold); solverInfo.m_splitImpulseTurnErp = btScalar(solverInfoData->m_solverInfo.m_splitImpulseTurnErp); - + solverInfo.m_linearSlop = btScalar(solverInfoData->m_solverInfo.m_linearSlop); solverInfo.m_warmstartingFactor = btScalar(solverInfoData->m_solverInfo.m_warmstartingFactor); solverInfo.m_maxGyroscopicForce = btScalar(solverInfoData->m_solverInfo.m_maxGyroscopicForce); solverInfo.m_singleAxisRollingFrictionThreshold = btScalar(solverInfoData->m_solverInfo.m_singleAxisRollingFrictionThreshold); - + solverInfo.m_numIterations = solverInfoData->m_solverInfo.m_numIterations; solverInfo.m_solverMode = solverInfoData->m_solverInfo.m_solverMode; solverInfo.m_restingContactRestitutionThreshold = solverInfoData->m_solverInfo.m_restingContactRestitutionThreshold; solverInfo.m_minimumSolverBatchSize = solverInfoData->m_solverInfo.m_minimumSolverBatchSize; - + solverInfo.m_splitImpulse = solverInfoData->m_solverInfo.m_splitImpulse; - setDynamicsWorldInfo(gravity,solverInfo); - } else + setDynamicsWorldInfo(gravity, solverInfo); + } + else { btDynamicsWorldFloatData* solverInfoData = (btDynamicsWorldFloatData*)bulletFile2->m_dynamicsWorldInfo[i]; btContactSolverInfo solverInfo; @@ -205,40 +186,38 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile solverInfo.m_globalCfm = solverInfoData->m_solverInfo.m_globalCfm; solverInfo.m_splitImpulsePenetrationThreshold = solverInfoData->m_solverInfo.m_splitImpulsePenetrationThreshold; solverInfo.m_splitImpulseTurnErp = solverInfoData->m_solverInfo.m_splitImpulseTurnErp; - + solverInfo.m_linearSlop = solverInfoData->m_solverInfo.m_linearSlop; solverInfo.m_warmstartingFactor = solverInfoData->m_solverInfo.m_warmstartingFactor; solverInfo.m_maxGyroscopicForce = solverInfoData->m_solverInfo.m_maxGyroscopicForce; solverInfo.m_singleAxisRollingFrictionThreshold = solverInfoData->m_solverInfo.m_singleAxisRollingFrictionThreshold; - + solverInfo.m_numIterations = solverInfoData->m_solverInfo.m_numIterations; solverInfo.m_solverMode = solverInfoData->m_solverInfo.m_solverMode; solverInfo.m_restingContactRestitutionThreshold = solverInfoData->m_solverInfo.m_restingContactRestitutionThreshold; solverInfo.m_minimumSolverBatchSize = solverInfoData->m_solverInfo.m_minimumSolverBatchSize; - + solverInfo.m_splitImpulse = solverInfoData->m_solverInfo.m_splitImpulse; - setDynamicsWorldInfo(gravity,solverInfo); + setDynamicsWorldInfo(gravity, solverInfo); } } - - for (i=0;im_rigidBodies.size();i++) + for (i = 0; i < bulletFile2->m_rigidBodies.size(); i++) { if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) { btRigidBodyDoubleData* colObjData = (btRigidBodyDoubleData*)bulletFile2->m_rigidBodies[i]; convertRigidBodyDouble(colObjData); - } else + } + else { btRigidBodyFloatData* colObjData = (btRigidBodyFloatData*)bulletFile2->m_rigidBodies[i]; convertRigidBodyFloat(colObjData); } - - } - for (i=0;im_collisionObjects.size();i++) + for (i = 0; i < bulletFile2->m_collisionObjects.size(); i++) { if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) { @@ -249,29 +228,30 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile btTransform startTransform; colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f; startTransform.deSerializeDouble(colObjData->m_worldTransform); - + btCollisionShape* shape = (btCollisionShape*)*shapePtr; - btCollisionObject* body = createCollisionObject(startTransform,shape,colObjData->m_name); + btCollisionObject* body = createCollisionObject(startTransform, shape, colObjData->m_name); body->setFriction(btScalar(colObjData->m_friction)); body->setRestitution(btScalar(colObjData->m_restitution)); - + #ifdef USE_INTERNAL_EDGE_UTILITY if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) { btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape; if (trimesh->getTriangleInfoMap()) { - body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); } } -#endif //USE_INTERNAL_EDGE_UTILITY - m_bodyMap.insert(colObjData,body); - } else +#endif //USE_INTERNAL_EDGE_UTILITY + m_bodyMap.insert(colObjData, body); + } + else { printf("error: no shape found\n"); } - - } else + } + else { btCollisionObjectFloatData* colObjData = (btCollisionObjectFloatData*)bulletFile2->m_collisionObjects[i]; btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape); @@ -280,9 +260,9 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile btTransform startTransform; colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f; startTransform.deSerializeFloat(colObjData->m_worldTransform); - + btCollisionShape* shape = (btCollisionShape*)*shapePtr; - btCollisionObject* body = createCollisionObject(startTransform,shape,colObjData->m_name); + btCollisionObject* body = createCollisionObject(startTransform, shape, colObjData->m_name); #ifdef USE_INTERNAL_EDGE_UTILITY if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) @@ -290,21 +270,20 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape; if (trimesh->getTriangleInfoMap()) { - body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); } } -#endif //USE_INTERNAL_EDGE_UTILITY - m_bodyMap.insert(colObjData,body); - } else +#endif //USE_INTERNAL_EDGE_UTILITY + m_bodyMap.insert(colObjData, body); + } + else { printf("error: no shape found\n"); } } - } - - for (i=0;im_constraints.size();i++) + for (i = 0; i < bulletFile2->m_constraints.size(); i++) { btTypedConstraintData2* constraintData = (btTypedConstraintData2*)bulletFile2->m_constraints[i]; @@ -328,34 +307,31 @@ bool btBulletWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile } if (!rbA && !rbB) continue; - - bool isDoublePrecisionData = (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION)!=0; - + + bool isDoublePrecisionData = (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) != 0; + if (isDoublePrecisionData) { - if (bulletFile2->getVersion()>=282) + if (bulletFile2->getVersion() >= 282) { btTypedConstraintDoubleData* dc = (btTypedConstraintDoubleData*)constraintData; - convertConstraintDouble(dc, rbA,rbB, bulletFile2->getVersion()); - } else + convertConstraintDouble(dc, rbA, rbB, bulletFile2->getVersion()); + } + else { //double-precision constraints were messed up until 2.82, try to recover data... - - btTypedConstraintData* oldData = (btTypedConstraintData*)constraintData; - - convertConstraintBackwardsCompatible281(oldData, rbA,rbB, bulletFile2->getVersion()); + btTypedConstraintData* oldData = (btTypedConstraintData*)constraintData; + + convertConstraintBackwardsCompatible281(oldData, rbA, rbB, bulletFile2->getVersion()); } } else { btTypedConstraintFloatData* dc = (btTypedConstraintFloatData*)constraintData; - convertConstraintFloat(dc, rbA,rbB, bulletFile2->getVersion()); + convertConstraintFloat(dc, rbA, rbB, bulletFile2->getVersion()); } - - } return true; } - diff --git a/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.h b/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.h index 27c1e7e33..0a856bc3b 100644 --- a/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.h +++ b/Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.h @@ -13,56 +13,40 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef BULLET_WORLD_IMPORTER_H #define BULLET_WORLD_IMPORTER_H - #include "btWorldImporter.h" - class btBulletFile; - - - namespace bParse { - class btBulletFile; - +class btBulletFile; + }; - - ///The btBulletWorldImporter is a starting point to import .bullet files. ///note that not all data is converted yet. You are expected to override or modify this class. ///See Bullet/Demos/SerializeDemo for a derived class that extract btSoftBody objects too. class btBulletWorldImporter : public btWorldImporter { - - public: - - btBulletWorldImporter(btDynamicsWorld* world=0); + btBulletWorldImporter(btDynamicsWorld* world = 0); virtual ~btBulletWorldImporter(); - ///if you pass a valid preSwapFilenameOut, it will save a new file with a different endianness + ///if you pass a valid preSwapFilenameOut, it will save a new file with a different endianness ///this pre-swapped file can be loaded without swapping on a target platform of different endianness - bool loadFile(const char* fileName, const char* preSwapFilenameOut=0); + bool loadFile(const char* fileName, const char* preSwapFilenameOut = 0); ///the memoryBuffer might be modified (for example if endian swaps are necessary) - bool loadFileFromMemory(char *memoryBuffer, int len); + bool loadFileFromMemory(char* memoryBuffer, int len); - bool loadFileFromMemory(bParse::btBulletFile* file); + bool loadFileFromMemory(bParse::btBulletFile* file); //call make sure bulletFile2 has been parsed, either using btBulletFile::parse or btBulletWorldImporter::loadFileFromMemory - virtual bool convertAllObjects(bParse::btBulletFile* file); - - - - + virtual bool convertAllObjects(bParse::btBulletFile* file); }; -#endif //BULLET_WORLD_IMPORTER_H - +#endif //BULLET_WORLD_IMPORTER_H diff --git a/Extras/Serialize/BulletWorldImporter/btMultiBodyWorldImporter.cpp b/Extras/Serialize/BulletWorldImporter/btMultiBodyWorldImporter.cpp index f7eb15c75..28d069505 100644 --- a/Extras/Serialize/BulletWorldImporter/btMultiBodyWorldImporter.cpp +++ b/Extras/Serialize/BulletWorldImporter/btMultiBodyWorldImporter.cpp @@ -15,12 +15,11 @@ struct btMultiBodyWorldImporterInternalData }; btMultiBodyWorldImporter::btMultiBodyWorldImporter(btMultiBodyDynamicsWorld* world) - :btBulletWorldImporter(world) + : btBulletWorldImporter(world) { m_data = new btMultiBodyWorldImporterInternalData; m_data->m_mbDynamicsWorld = world; } - btMultiBodyWorldImporter::~btMultiBodyWorldImporter() { @@ -32,7 +31,6 @@ void btMultiBodyWorldImporter::deleteAllData() btBulletWorldImporter::deleteAllData(); } - static btCollisionObjectDoubleData* getBody0FromContactManifold(btPersistentManifoldDoubleData* manifold) { return (btCollisionObjectDoubleData*)manifold->m_body0; @@ -50,8 +48,8 @@ static btCollisionObjectFloatData* getBody1FromContactManifold(btPersistentManif return (btCollisionObjectFloatData*)manifold->m_body1; } - -template void syncContactManifolds(T** contactManifolds, int numContactManifolds, btMultiBodyWorldImporterInternalData* m_data) +template +void syncContactManifolds(T** contactManifolds, int numContactManifolds, btMultiBodyWorldImporterInternalData* m_data) { m_data->m_mbDynamicsWorld->updateAabbs(); m_data->m_mbDynamicsWorld->computeOverlappingPairs(); @@ -59,7 +57,6 @@ template void syncContactManifolds(T** contactManifolds, int numContact btDispatcherInfo& dispatchInfo = m_data->m_mbDynamicsWorld->getDispatchInfo(); - if (dispatcher) { btOverlappingPairCache* pairCache = m_data->m_mbDynamicsWorld->getBroadphase()->getOverlappingPairCache(); @@ -104,10 +101,10 @@ template void syncContactManifolds(T** contactManifolds, int numContact } } } - } -template void syncMultiBody(T* mbd, btMultiBody* mb, btMultiBodyWorldImporterInternalData* m_data, btAlignedObjectArray& scratchQ, btAlignedObjectArray& scratchM) +template +void syncMultiBody(T* mbd, btMultiBody* mb, btMultiBodyWorldImporterInternalData* m_data, btAlignedObjectArray& scratchQ, btAlignedObjectArray& scratchM) { bool isFixedBase = mbd->m_baseMass == 0; bool canSleep = false; @@ -129,7 +126,6 @@ template void syncMultiBody(T* mbd, btMultiBody* mb, btMultiBodyWorldI for (int i = 0; i < mbd->m_numLinks; i++) { - mb->getLink(i).m_absFrameTotVelocity.m_topVec.deSerialize(mbd->m_links[i].m_absFrameTotVelocityTop); mb->getLink(i).m_absFrameTotVelocity.m_bottomVec.deSerialize(mbd->m_links[i].m_absFrameTotVelocityBottom); mb->getLink(i).m_absFrameLocVelocity.m_topVec.deSerialize(mbd->m_links[i].m_absFrameLocVelocityTop); @@ -137,45 +133,46 @@ template void syncMultiBody(T* mbd, btMultiBody* mb, btMultiBodyWorldI switch (mbd->m_links[i].m_jointType) { - case btMultibodyLink::eFixed: - { - break; - } - case btMultibodyLink::ePrismatic: - { - mb->setJointPos(i, mbd->m_links[i].m_jointPos[0]); - mb->setJointVel(i, mbd->m_links[i].m_jointVel[0]); - break; - } - case btMultibodyLink::eRevolute: - { - mb->setJointPos(i, mbd->m_links[i].m_jointPos[0]); - mb->setJointVel(i, mbd->m_links[i].m_jointVel[0]); - break; - } - case btMultibodyLink::eSpherical: - { - btScalar jointPos[4] = { (btScalar)mbd->m_links[i].m_jointPos[0], (btScalar)mbd->m_links[i].m_jointPos[1], (btScalar)mbd->m_links[i].m_jointPos[2], (btScalar)mbd->m_links[i].m_jointPos[3] }; - btScalar jointVel[3] = { (btScalar)mbd->m_links[i].m_jointVel[0], (btScalar)mbd->m_links[i].m_jointVel[1], (btScalar)mbd->m_links[i].m_jointVel[2] }; - mb->setJointPosMultiDof(i, jointPos); - mb->setJointVelMultiDof(i, jointVel); + case btMultibodyLink::eFixed: + { + break; + } + case btMultibodyLink::ePrismatic: + { + mb->setJointPos(i, mbd->m_links[i].m_jointPos[0]); + mb->setJointVel(i, mbd->m_links[i].m_jointVel[0]); + break; + } + case btMultibodyLink::eRevolute: + { + mb->setJointPos(i, mbd->m_links[i].m_jointPos[0]); + mb->setJointVel(i, mbd->m_links[i].m_jointVel[0]); + break; + } + case btMultibodyLink::eSpherical: + { + btScalar jointPos[4] = {(btScalar)mbd->m_links[i].m_jointPos[0], (btScalar)mbd->m_links[i].m_jointPos[1], (btScalar)mbd->m_links[i].m_jointPos[2], (btScalar)mbd->m_links[i].m_jointPos[3]}; + btScalar jointVel[3] = {(btScalar)mbd->m_links[i].m_jointVel[0], (btScalar)mbd->m_links[i].m_jointVel[1], (btScalar)mbd->m_links[i].m_jointVel[2]}; + mb->setJointPosMultiDof(i, jointPos); + mb->setJointVelMultiDof(i, jointVel); - break; - } - case btMultibodyLink::ePlanar: - { - break; - } - default: - { - } + break; + } + case btMultibodyLink::ePlanar: + { + break; + } + default: + { + } } } mb->forwardKinematics(scratchQ, scratchM); mb->updateCollisionObjectWorldTransforms(scratchQ, scratchM); } -template void convertMultiBody(T* mbd, btMultiBodyWorldImporterInternalData* m_data) +template +void convertMultiBody(T* mbd, btMultiBodyWorldImporterInternalData* m_data) { bool isFixedBase = mbd->m_baseMass == 0; bool canSleep = false; @@ -206,71 +203,69 @@ template void convertMultiBody(T* mbd, btMultiBodyWorldImporterInterna switch (mbd->m_links[i].m_jointType) { - case btMultibodyLink::eFixed: - { + case btMultibodyLink::eFixed: + { + mb->setupFixed(i, mbd->m_links[i].m_linkMass, localInertiaDiagonal, mbd->m_links[i].m_parentIndex, + parentRotToThis, parentComToThisPivotOffset, thisPivotToThisComOffset); + //search for the collider + //mbd->m_links[i].m_linkCollider + break; + } + case btMultibodyLink::ePrismatic: + { + btVector3 jointAxis; + jointAxis.deSerialize(mbd->m_links[i].m_jointAxisBottom[0]); + bool disableParentCollision = true; //todo + mb->setupPrismatic(i, mbd->m_links[i].m_linkMass, localInertiaDiagonal, mbd->m_links[i].m_parentIndex, + parentRotToThis, jointAxis, parentComToThisPivotOffset, thisPivotToThisComOffset, disableParentCollision); + mb->setJointPos(i, mbd->m_links[i].m_jointPos[0]); + mb->setJointVel(i, mbd->m_links[i].m_jointVel[0]); + break; + } + case btMultibodyLink::eRevolute: + { + btVector3 jointAxis; + jointAxis.deSerialize(mbd->m_links[i].m_jointAxisTop[0]); + bool disableParentCollision = true; //todo + mb->setupRevolute(i, mbd->m_links[i].m_linkMass, localInertiaDiagonal, mbd->m_links[i].m_parentIndex, + parentRotToThis, jointAxis, parentComToThisPivotOffset, thisPivotToThisComOffset, disableParentCollision); + mb->setJointPos(i, mbd->m_links[i].m_jointPos[0]); + mb->setJointVel(i, mbd->m_links[i].m_jointVel[0]); + break; + } + case btMultibodyLink::eSpherical: + { + btAssert(0); + bool disableParentCollision = true; //todo + mb->setupSpherical(i, mbd->m_links[i].m_linkMass, localInertiaDiagonal, mbd->m_links[i].m_parentIndex, + parentRotToThis, parentComToThisPivotOffset, thisPivotToThisComOffset, disableParentCollision); + btScalar jointPos[4] = {(btScalar)mbd->m_links[i].m_jointPos[0], (btScalar)mbd->m_links[i].m_jointPos[1], (btScalar)mbd->m_links[i].m_jointPos[2], (btScalar)mbd->m_links[i].m_jointPos[3]}; + btScalar jointVel[3] = {(btScalar)mbd->m_links[i].m_jointVel[0], (btScalar)mbd->m_links[i].m_jointVel[1], (btScalar)mbd->m_links[i].m_jointVel[2]}; + mb->setJointPosMultiDof(i, jointPos); + mb->setJointVelMultiDof(i, jointVel); - - mb->setupFixed(i, mbd->m_links[i].m_linkMass, localInertiaDiagonal, mbd->m_links[i].m_parentIndex, - parentRotToThis, parentComToThisPivotOffset, thisPivotToThisComOffset); - //search for the collider - //mbd->m_links[i].m_linkCollider - break; - } - case btMultibodyLink::ePrismatic: - { - btVector3 jointAxis; - jointAxis.deSerialize(mbd->m_links[i].m_jointAxisBottom[0]); - bool disableParentCollision = true;//todo - mb->setupPrismatic(i, mbd->m_links[i].m_linkMass, localInertiaDiagonal, mbd->m_links[i].m_parentIndex, - parentRotToThis, jointAxis, parentComToThisPivotOffset, thisPivotToThisComOffset, disableParentCollision); - mb->setJointPos(i, mbd->m_links[i].m_jointPos[0]); - mb->setJointVel(i, mbd->m_links[i].m_jointVel[0]); - break; - } - case btMultibodyLink::eRevolute: - { - btVector3 jointAxis; - jointAxis.deSerialize(mbd->m_links[i].m_jointAxisTop[0]); - bool disableParentCollision = true;//todo - mb->setupRevolute(i, mbd->m_links[i].m_linkMass, localInertiaDiagonal, mbd->m_links[i].m_parentIndex, - parentRotToThis, jointAxis, parentComToThisPivotOffset, thisPivotToThisComOffset, disableParentCollision); - mb->setJointPos(i, mbd->m_links[i].m_jointPos[0]); - mb->setJointVel(i, mbd->m_links[i].m_jointVel[0]); - break; - } - case btMultibodyLink::eSpherical: - { - btAssert(0); - bool disableParentCollision = true;//todo - mb->setupSpherical(i, mbd->m_links[i].m_linkMass, localInertiaDiagonal, mbd->m_links[i].m_parentIndex, - parentRotToThis, parentComToThisPivotOffset, thisPivotToThisComOffset, disableParentCollision); - btScalar jointPos[4] = { (btScalar)mbd->m_links[i].m_jointPos[0], (btScalar)mbd->m_links[i].m_jointPos[1], (btScalar)mbd->m_links[i].m_jointPos[2], (btScalar)mbd->m_links[i].m_jointPos[3] }; - btScalar jointVel[3] = { (btScalar)mbd->m_links[i].m_jointVel[0], (btScalar)mbd->m_links[i].m_jointVel[1], (btScalar)mbd->m_links[i].m_jointVel[2] }; - mb->setJointPosMultiDof(i, jointPos); - mb->setJointVelMultiDof(i, jointVel); - - break; - } - case btMultibodyLink::ePlanar: - { - btAssert(0); - break; - } - default: - { - btAssert(0); - } + break; + } + case btMultibodyLink::ePlanar: + { + btAssert(0); + break; + } + default: + { + btAssert(0); + } } } } -bool btMultiBodyWorldImporter::convertAllObjects( bParse::btBulletFile* bulletFile2) +bool btMultiBodyWorldImporter::convertAllObjects(bParse::btBulletFile* bulletFile2) { bool result = false; btAlignedObjectArray scratchQ; btAlignedObjectArray scratchM; - if (m_importerFlags&eRESTORE_EXISTING_OBJECTS) + if (m_importerFlags & eRESTORE_EXISTING_OBJECTS) { //check if the snapshot is valid for the existing world //equal number of objects, # links etc @@ -284,7 +279,6 @@ bool btMultiBodyWorldImporter::convertAllObjects( bParse::btBulletFile* bulletF //convert all multibodies if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) { - //for (int i = 0; i < bulletFile2->m_multiBodies.size(); i++) for (int i = bulletFile2->m_multiBodies.size() - 1; i >= 0; i--) { @@ -352,7 +346,6 @@ bool btMultiBodyWorldImporter::convertAllObjects( bParse::btBulletFile* bulletF } } - if (bulletFile2->m_contactManifolds.size()) { syncContactManifolds((btPersistentManifoldDoubleData**)&bulletFile2->m_contactManifolds[0], bulletFile2->m_contactManifolds.size(), m_data); @@ -389,23 +382,19 @@ bool btMultiBodyWorldImporter::convertAllObjects( bParse::btBulletFile* bulletF } } - if (bulletFile2->m_contactManifolds.size()) { syncContactManifolds((btPersistentManifoldFloatData**)&bulletFile2->m_contactManifolds[0], bulletFile2->m_contactManifolds.size(), m_data); } - } } else { result = btBulletWorldImporter::convertAllObjects(bulletFile2); - //convert all multibodies for (int i = 0; i < bulletFile2->m_multiBodies.size(); i++) { - if (bulletFile2->getFlags() & bParse::FD_DOUBLE_PRECISION) { btMultiBodyDoubleData* mbd = (btMultiBodyDoubleData*)bulletFile2->m_multiBodies[i]; @@ -421,7 +410,7 @@ bool btMultiBodyWorldImporter::convertAllObjects( bParse::btBulletFile* bulletF //forward kinematics, so that the link world transforms are valid, for collision detection for (int i = 0; i < m_data->m_mbMap.size(); i++) { - btMultiBody**ptr = m_data->m_mbMap.getAtIndex(i); + btMultiBody** ptr = m_data->m_mbMap.getAtIndex(i); if (ptr) { btMultiBody* mb = *ptr; @@ -444,7 +433,6 @@ bool btMultiBodyWorldImporter::convertAllObjects( bParse::btBulletFile* bulletF { btMultiBody* multiBody = *ptr; - btCollisionShape** shapePtr = m_shapeMap.find(mblcd->m_colObjData.m_collisionShape); if (shapePtr && *shapePtr) { @@ -491,7 +479,6 @@ bool btMultiBodyWorldImporter::convertAllObjects( bParse::btBulletFile* bulletF #endif m_data->m_mbDynamicsWorld->addCollisionObject(col, collisionFilterGroup, collisionFilterMask); } - } else { @@ -503,13 +490,12 @@ bool btMultiBodyWorldImporter::convertAllObjects( bParse::btBulletFile* bulletF world1->addCollisionObject(col, collisionFilterGroup, collisionFilterMask); #endif } - } } for (int i = 0; i < m_data->m_mbMap.size(); i++) { - btMultiBody**ptr = m_data->m_mbMap.getAtIndex(i); + btMultiBody** ptr = m_data->m_mbMap.getAtIndex(i); if (ptr) { btMultiBody* mb = *ptr; diff --git a/Extras/Serialize/BulletWorldImporter/btMultiBodyWorldImporter.h b/Extras/Serialize/BulletWorldImporter/btMultiBodyWorldImporter.h index 002616e40..46dd3ce21 100644 --- a/Extras/Serialize/BulletWorldImporter/btMultiBodyWorldImporter.h +++ b/Extras/Serialize/BulletWorldImporter/btMultiBodyWorldImporter.h @@ -8,13 +8,12 @@ class btMultiBodyWorldImporter : public btBulletWorldImporter struct btMultiBodyWorldImporterInternalData* m_data; public: - btMultiBodyWorldImporter(class btMultiBodyDynamicsWorld* world); virtual ~btMultiBodyWorldImporter(); - virtual bool convertAllObjects( bParse::btBulletFile* bulletFile2); + virtual bool convertAllObjects(bParse::btBulletFile* bulletFile2); virtual void deleteAllData(); }; -#endif //BT_MULTIBODY_WORLD_IMPORTER_H +#endif //BT_MULTIBODY_WORLD_IMPORTER_H diff --git a/Extras/Serialize/BulletWorldImporter/btWorldImporter.cpp b/Extras/Serialize/BulletWorldImporter/btWorldImporter.cpp index 080b19aef..c3fa088aa 100644 --- a/Extras/Serialize/BulletWorldImporter/btWorldImporter.cpp +++ b/Extras/Serialize/BulletWorldImporter/btWorldImporter.cpp @@ -19,11 +19,10 @@ subject to the following restrictions: #include "BulletCollision/Gimpact/btGImpactShape.h" #endif btWorldImporter::btWorldImporter(btDynamicsWorld* world) -:m_dynamicsWorld(world), -m_verboseMode(0), -m_importerFlags(0) + : m_dynamicsWorld(world), + m_verboseMode(0), + m_importerFlags(0) { - } btWorldImporter::~btWorldImporter() @@ -33,141 +32,133 @@ btWorldImporter::~btWorldImporter() void btWorldImporter::deleteAllData() { int i; - for (i=0;iremoveConstraint(m_allocatedConstraints[i]); delete m_allocatedConstraints[i]; } m_allocatedConstraints.clear(); - - for (i=0;iremoveRigidBody(btRigidBody::upcast(m_allocatedRigidBodies[i])); delete m_allocatedRigidBodies[i]; } - + m_allocatedRigidBodies.clear(); - - for (i=0;im_numMeshParts;a++) + for (int a = 0; a < curData->m_numMeshParts; a++) { btMeshPartData* curPart = &curData->m_meshPartsPtr[a]; - if(curPart->m_vertices3f) - delete [] curPart->m_vertices3f; + if (curPart->m_vertices3f) + delete[] curPart->m_vertices3f; - if(curPart->m_vertices3d) - delete [] curPart->m_vertices3d; + if (curPart->m_vertices3d) + delete[] curPart->m_vertices3d; - if(curPart->m_indices32) - delete [] curPart->m_indices32; + if (curPart->m_indices32) + delete[] curPart->m_indices32; - if(curPart->m_3indices16) - delete [] curPart->m_3indices16; + if (curPart->m_3indices16) + delete[] curPart->m_3indices16; + + if (curPart->m_indices16) + delete[] curPart->m_indices16; - if(curPart->m_indices16) - delete [] curPart->m_indices16; - if (curPart->m_3indices8) - delete [] curPart->m_3indices8; - + delete[] curPart->m_3indices8; } - delete [] curData->m_meshPartsPtr; + delete[] curData->m_meshPartsPtr; delete curData; } m_allocatedbtStridingMeshInterfaceDatas.clear(); - for (i=0;im_shapeType) - { - case STATIC_PLANE_PROXYTYPE: + { + case STATIC_PLANE_PROXYTYPE: { btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*)shapeData; - btVector3 planeNormal,localScaling; + btVector3 planeNormal, localScaling; planeNormal.deSerializeFloat(planeData->m_planeNormal); localScaling.deSerializeFloat(planeData->m_localScaling); - shape = createPlaneShape(planeNormal,planeData->m_planeConstant); + shape = createPlaneShape(planeNormal, planeData->m_planeConstant); shape->setLocalScaling(localScaling); break; } - case SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE: + case SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE: { - btScaledTriangleMeshShapeData* scaledMesh = (btScaledTriangleMeshShapeData*) shapeData; - btCollisionShapeData* colShapeData = (btCollisionShapeData*) &scaledMesh->m_trimeshShapeData; + btScaledTriangleMeshShapeData* scaledMesh = (btScaledTriangleMeshShapeData*)shapeData; + btCollisionShapeData* colShapeData = (btCollisionShapeData*)&scaledMesh->m_trimeshShapeData; colShapeData->m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE; btCollisionShape* childShape = convertCollisionShape(colShapeData); btBvhTriangleMeshShape* meshShape = (btBvhTriangleMeshShape*)childShape; @@ -177,15 +168,14 @@ btCollisionShape* btWorldImporter::convertCollisionShape( btCollisionShapeData* shape = createScaledTrangleMeshShape(meshShape, localScaling); break; } - case GIMPACT_SHAPE_PROXYTYPE: + case GIMPACT_SHAPE_PROXYTYPE: { #ifdef USE_GIMPACT - btGImpactMeshShapeData* gimpactData = (btGImpactMeshShapeData*) shapeData; + btGImpactMeshShapeData* gimpactData = (btGImpactMeshShapeData*)shapeData; if (gimpactData->m_gimpactSubType == CONST_GIMPACT_TRIMESH_SHAPE) { btStridingMeshInterfaceData* interfaceData = createStridingMeshInterfaceData(&gimpactData->m_meshInterface); btTriangleIndexVertexArray* meshInterface = createMeshInterface(*interfaceData); - btGImpactMeshShape* gimpactShape = createGimpactShape(meshInterface); btVector3 localScaling; @@ -194,47 +184,45 @@ btCollisionShape* btWorldImporter::convertCollisionShape( btCollisionShapeData* gimpactShape->setMargin(btScalar(gimpactData->m_collisionMargin)); gimpactShape->updateBound(); shape = gimpactShape; - } else + } + else { printf("unsupported gimpact sub type\n"); } -#endif//USE_GIMPACT +#endif //USE_GIMPACT break; } - //The btCapsuleShape* API has issue passing the margin/scaling/halfextents unmodified through the API - //so deal with this + //The btCapsuleShape* API has issue passing the margin/scaling/halfextents unmodified through the API + //so deal with this case CAPSULE_SHAPE_PROXYTYPE: { btCapsuleShapeData* capData = (btCapsuleShapeData*)shapeData; - switch (capData->m_upAxis) { - case 0: + case 0: { - shape = createCapsuleShapeX(1,1); + shape = createCapsuleShapeX(1, 1); break; } - case 1: + case 1: { - shape = createCapsuleShapeY(1,1); + shape = createCapsuleShapeY(1, 1); break; } - case 2: + case 2: { - shape = createCapsuleShapeZ(1,1); + shape = createCapsuleShapeZ(1, 1); break; } - default: + default: { printf("error: wrong up axis for btCapsuleShape\n"); } - - }; if (shape) { - btCapsuleShape* cap = (btCapsuleShape*) shape; + btCapsuleShape* cap = (btCapsuleShape*)shape; cap->deSerializeFloat(capData); } break; @@ -245,163 +233,156 @@ btCollisionShape* btWorldImporter::convertCollisionShape( btCollisionShapeData* case SPHERE_SHAPE_PROXYTYPE: case MULTI_SPHERE_SHAPE_PROXYTYPE: case CONVEX_HULL_SHAPE_PROXYTYPE: + { + btConvexInternalShapeData* bsd = (btConvexInternalShapeData*)shapeData; + btVector3 implicitShapeDimensions; + implicitShapeDimensions.deSerializeFloat(bsd->m_implicitShapeDimensions); + btVector3 localScaling; + localScaling.deSerializeFloat(bsd->m_localScaling); + btVector3 margin(bsd->m_collisionMargin, bsd->m_collisionMargin, bsd->m_collisionMargin); + switch (shapeData->m_shapeType) { - btConvexInternalShapeData* bsd = (btConvexInternalShapeData*)shapeData; - btVector3 implicitShapeDimensions; - implicitShapeDimensions.deSerializeFloat(bsd->m_implicitShapeDimensions); + case BOX_SHAPE_PROXYTYPE: + { + btBoxShape* box = (btBoxShape*)createBoxShape(implicitShapeDimensions / localScaling + margin); + //box->initializePolyhedralFeatures(); + shape = box; + + break; + } + case SPHERE_SHAPE_PROXYTYPE: + { + shape = createSphereShape(implicitShapeDimensions.getX()); + break; + } + + case CYLINDER_SHAPE_PROXYTYPE: + { + btCylinderShapeData* cylData = (btCylinderShapeData*)shapeData; + btVector3 halfExtents = implicitShapeDimensions + margin; + switch (cylData->m_upAxis) + { + case 0: + { + shape = createCylinderShapeX(halfExtents.getY(), halfExtents.getX()); + break; + } + case 1: + { + shape = createCylinderShapeY(halfExtents.getX(), halfExtents.getY()); + break; + } + case 2: + { + shape = createCylinderShapeZ(halfExtents.getX(), halfExtents.getZ()); + break; + } + default: + { + printf("unknown Cylinder up axis\n"); + } + }; + + break; + } + case CONE_SHAPE_PROXYTYPE: + { + btConeShapeData* conData = (btConeShapeData*)shapeData; + btVector3 halfExtents = implicitShapeDimensions; //+margin; + switch (conData->m_upIndex) + { + case 0: + { + shape = createConeShapeX(halfExtents.getY(), halfExtents.getX()); + break; + } + case 1: + { + shape = createConeShapeY(halfExtents.getX(), halfExtents.getY()); + break; + } + case 2: + { + shape = createConeShapeZ(halfExtents.getX(), halfExtents.getZ()); + break; + } + default: + { + printf("unknown Cone up axis\n"); + } + }; + + break; + } + case MULTI_SPHERE_SHAPE_PROXYTYPE: + { + btMultiSphereShapeData* mss = (btMultiSphereShapeData*)bsd; + int numSpheres = mss->m_localPositionArraySize; + + btAlignedObjectArray tmpPos; + btAlignedObjectArray radii; + radii.resize(numSpheres); + tmpPos.resize(numSpheres); + int i; + for (i = 0; i < numSpheres; i++) + { + tmpPos[i].deSerializeFloat(mss->m_localPositionArrayPtr[i].m_pos); + radii[i] = mss->m_localPositionArrayPtr[i].m_radius; + } + shape = createMultiSphereShape(&tmpPos[0], &radii[0], numSpheres); + break; + } + case CONVEX_HULL_SHAPE_PROXYTYPE: + { + // int sz = sizeof(btConvexHullShapeData); + // int sz2 = sizeof(btConvexInternalShapeData); + // int sz3 = sizeof(btCollisionShapeData); + btConvexHullShapeData* convexData = (btConvexHullShapeData*)bsd; + int numPoints = convexData->m_numUnscaledPoints; + + btAlignedObjectArray tmpPoints; + tmpPoints.resize(numPoints); + int i; + for (i = 0; i < numPoints; i++) + { +#ifdef BT_USE_DOUBLE_PRECISION + if (convexData->m_unscaledPointsDoublePtr) + tmpPoints[i].deSerialize(convexData->m_unscaledPointsDoublePtr[i]); + if (convexData->m_unscaledPointsFloatPtr) + tmpPoints[i].deSerializeFloat(convexData->m_unscaledPointsFloatPtr[i]); +#else + if (convexData->m_unscaledPointsFloatPtr) + tmpPoints[i].deSerialize(convexData->m_unscaledPointsFloatPtr[i]); + if (convexData->m_unscaledPointsDoublePtr) + tmpPoints[i].deSerializeDouble(convexData->m_unscaledPointsDoublePtr[i]); +#endif //BT_USE_DOUBLE_PRECISION + } + btConvexHullShape* hullShape = createConvexHullShape(); + for (i = 0; i < numPoints; i++) + { + hullShape->addPoint(tmpPoints[i]); + } + hullShape->setMargin(bsd->m_collisionMargin); + //hullShape->initializePolyhedralFeatures(); + shape = hullShape; + break; + } + default: + { + printf("error: cannot create shape type (%d)\n", shapeData->m_shapeType); + } + } + + if (shape) + { + shape->setMargin(bsd->m_collisionMargin); + btVector3 localScaling; localScaling.deSerializeFloat(bsd->m_localScaling); - btVector3 margin(bsd->m_collisionMargin,bsd->m_collisionMargin,bsd->m_collisionMargin); - switch (shapeData->m_shapeType) - { - case BOX_SHAPE_PROXYTYPE: - { - btBoxShape* box= (btBoxShape*)createBoxShape(implicitShapeDimensions/localScaling+margin); - //box->initializePolyhedralFeatures(); - shape = box; - - break; - } - case SPHERE_SHAPE_PROXYTYPE: - { - shape = createSphereShape(implicitShapeDimensions.getX()); - break; - } - - case CYLINDER_SHAPE_PROXYTYPE: - { - btCylinderShapeData* cylData = (btCylinderShapeData*) shapeData; - btVector3 halfExtents = implicitShapeDimensions+margin; - switch (cylData->m_upAxis) - { - case 0: - { - shape = createCylinderShapeX(halfExtents.getY(),halfExtents.getX()); - break; - } - case 1: - { - shape = createCylinderShapeY(halfExtents.getX(),halfExtents.getY()); - break; - } - case 2: - { - shape = createCylinderShapeZ(halfExtents.getX(),halfExtents.getZ()); - break; - } - default: - { - printf("unknown Cylinder up axis\n"); - } - - }; - - - - break; - } - case CONE_SHAPE_PROXYTYPE: - { - btConeShapeData* conData = (btConeShapeData*) shapeData; - btVector3 halfExtents = implicitShapeDimensions;//+margin; - switch (conData->m_upIndex) - { - case 0: - { - shape = createConeShapeX(halfExtents.getY(),halfExtents.getX()); - break; - } - case 1: - { - shape = createConeShapeY(halfExtents.getX(),halfExtents.getY()); - break; - } - case 2: - { - shape = createConeShapeZ(halfExtents.getX(),halfExtents.getZ()); - break; - } - default: - { - printf("unknown Cone up axis\n"); - } - - }; - - - - break; - } - case MULTI_SPHERE_SHAPE_PROXYTYPE: - { - btMultiSphereShapeData* mss = (btMultiSphereShapeData*)bsd; - int numSpheres = mss->m_localPositionArraySize; - - btAlignedObjectArray tmpPos; - btAlignedObjectArray radii; - radii.resize(numSpheres); - tmpPos.resize(numSpheres); - int i; - for ( i=0;im_localPositionArrayPtr[i].m_pos); - radii[i] = mss->m_localPositionArrayPtr[i].m_radius; - } - shape = createMultiSphereShape(&tmpPos[0],&radii[0],numSpheres); - break; - } - case CONVEX_HULL_SHAPE_PROXYTYPE: - { - // int sz = sizeof(btConvexHullShapeData); - // int sz2 = sizeof(btConvexInternalShapeData); - // int sz3 = sizeof(btCollisionShapeData); - btConvexHullShapeData* convexData = (btConvexHullShapeData*)bsd; - int numPoints = convexData->m_numUnscaledPoints; - - btAlignedObjectArray tmpPoints; - tmpPoints.resize(numPoints); - int i; - for ( i=0;im_unscaledPointsDoublePtr) - tmpPoints[i].deSerialize(convexData->m_unscaledPointsDoublePtr[i]); - if (convexData->m_unscaledPointsFloatPtr) - tmpPoints[i].deSerializeFloat(convexData->m_unscaledPointsFloatPtr[i]); -#else - if (convexData->m_unscaledPointsFloatPtr) - tmpPoints[i].deSerialize(convexData->m_unscaledPointsFloatPtr[i]); - if (convexData->m_unscaledPointsDoublePtr) - tmpPoints[i].deSerializeDouble(convexData->m_unscaledPointsDoublePtr[i]); -#endif //BT_USE_DOUBLE_PRECISION - } - btConvexHullShape* hullShape = createConvexHullShape(); - for (i=0;iaddPoint(tmpPoints[i]); - } - hullShape->setMargin(bsd->m_collisionMargin); - //hullShape->initializePolyhedralFeatures(); - shape = hullShape; - break; - } - default: - { - printf("error: cannot create shape type (%d)\n",shapeData->m_shapeType); - } - } - - if (shape) - { - shape->setMargin(bsd->m_collisionMargin); - - btVector3 localScaling; - localScaling.deSerializeFloat(bsd->m_localScaling); - shape->setLocalScaling(localScaling); - - } - break; + shape->setLocalScaling(localScaling); } + break; + } case TRIANGLE_MESH_SHAPE_PROXYTYPE: { btTriangleMeshShapeData* trimesh = (btTriangleMeshShapeData*)shapeData; @@ -412,10 +393,10 @@ btCollisionShape* btWorldImporter::convertCollisionShape( btCollisionShapeData* return 0; } - btVector3 scaling; scaling.deSerializeFloat(trimesh->m_meshInterface.m_scaling); + btVector3 scaling; + scaling.deSerializeFloat(trimesh->m_meshInterface.m_scaling); meshInterface->setScaling(scaling); - btOptimizedBvh* bvh = 0; #if 1 if (trimesh->m_quantizedFloatBvh) @@ -424,7 +405,8 @@ btCollisionShape* btWorldImporter::convertCollisionShape( btCollisionShapeData* if (bvhPtr && *bvhPtr) { bvh = *bvhPtr; - } else + } + else { bvh = createOptimizedBvh(); bvh->deSerializeFloat(*trimesh->m_quantizedFloatBvh); @@ -436,7 +418,8 @@ btCollisionShape* btWorldImporter::convertCollisionShape( btCollisionShapeData* if (bvhPtr && *bvhPtr) { bvh = *bvhPtr; - } else + } + else { bvh = createOptimizedBvh(); bvh->deSerializeDouble(*trimesh->m_quantizedDoubleBvh); @@ -444,8 +427,7 @@ btCollisionShape* btWorldImporter::convertCollisionShape( btCollisionShapeData* } #endif - - btBvhTriangleMeshShape* trimeshShape = createBvhTriangleMeshShape(meshInterface,bvh); + btBvhTriangleMeshShape* trimeshShape = createBvhTriangleMeshShape(meshInterface, bvh); trimeshShape->setMargin(trimesh->m_collisionMargin); shape = trimeshShape; @@ -457,68 +439,62 @@ btCollisionShape* btWorldImporter::convertCollisionShape( btCollisionShapeData* #ifdef USE_INTERNAL_EDGE_UTILITY gContactAddedCallback = btAdjustInternalEdgeContactsCallback; -#endif //USE_INTERNAL_EDGE_UTILITY - +#endif //USE_INTERNAL_EDGE_UTILITY } //printf("trimesh->m_collisionMargin=%f\n",trimesh->m_collisionMargin); break; } case COMPOUND_SHAPE_PROXYTYPE: - { - btCompoundShapeData* compoundData = (btCompoundShapeData*)shapeData; - btCompoundShape* compoundShape = createCompoundShape(); + { + btCompoundShapeData* compoundData = (btCompoundShapeData*)shapeData; + btCompoundShape* compoundShape = createCompoundShape(); - - btAlignedObjectArray childShapes; - for (int i=0;im_numChildShapes;i++) + btAlignedObjectArray childShapes; + for (int i = 0; i < compoundData->m_numChildShapes; i++) + { + btCollisionShapeData* cd = compoundData->m_childShapePtr[i].m_childShape; + + btCollisionShape* childShape = convertCollisionShape(cd); + if (childShape) { - - btCollisionShapeData* cd = compoundData->m_childShapePtr[i].m_childShape; - - btCollisionShape* childShape = convertCollisionShape(cd); - if (childShape) - { - btTransform localTransform; - localTransform.deSerializeFloat(compoundData->m_childShapePtr[i].m_transform); - compoundShape->addChildShape(localTransform,childShape); - } else - { -#ifdef _DEBUG - printf("error: couldn't create childShape for compoundShape\n"); -#endif - } - + btTransform localTransform; + localTransform.deSerializeFloat(compoundData->m_childShapePtr[i].m_transform); + compoundShape->addChildShape(localTransform, childShape); } - shape = compoundShape; - - break; - } - case SOFTBODY_SHAPE_PROXYTYPE: - { - return 0; - } - default: - { + else + { #ifdef _DEBUG - printf("unsupported shape type (%d)\n",shapeData->m_shapeType); + printf("error: couldn't create childShape for compoundShape\n"); #endif + } } + shape = compoundShape; + + break; } + case SOFTBODY_SHAPE_PROXYTYPE: + { + return 0; + } + default: + { +#ifdef _DEBUG + printf("unsupported shape type (%d)\n", shapeData->m_shapeType); +#endif + } + } - return shape; - + return shape; } - - char* btWorldImporter::duplicateName(const char* name) { if (name) { int l = (int)strlen(name); - char* newName = new char[l+1]; - memcpy(newName,name,l); + char* newName = new char[l + 1]; + memcpy(newName, name, l); newName[l] = 0; m_allocatedNames.push_back(newName); return newName; @@ -526,460 +502,331 @@ char* btWorldImporter::duplicateName(const char* name) return 0; } -void btWorldImporter::convertConstraintBackwardsCompatible281(btTypedConstraintData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion) -{ - - btTypedConstraint* constraint = 0; - - switch (constraintData->m_objectType) - { - case POINT2POINT_CONSTRAINT_TYPE: - { - btPoint2PointConstraintDoubleData* p2pData = (btPoint2PointConstraintDoubleData*)constraintData; - if (rbA && rbB) - { - btVector3 pivotInA,pivotInB; - pivotInA.deSerializeDouble(p2pData->m_pivotInA); - pivotInB.deSerializeDouble(p2pData->m_pivotInB); - constraint = createPoint2PointConstraint(*rbA,*rbB,pivotInA,pivotInB); - } else - { - btVector3 pivotInA; - pivotInA.deSerializeDouble(p2pData->m_pivotInA); - constraint = createPoint2PointConstraint(*rbA,pivotInA); - } - break; - } - case HINGE_CONSTRAINT_TYPE: - { - btHingeConstraint* hinge = 0; - - btHingeConstraintDoubleData* hingeData = (btHingeConstraintDoubleData*)constraintData; - if (rbA&& rbB) - { - btTransform rbAFrame,rbBFrame; - rbAFrame.deSerializeDouble(hingeData->m_rbAFrame); - rbBFrame.deSerializeDouble(hingeData->m_rbBFrame); - hinge = createHingeConstraint(*rbA,*rbB,rbAFrame,rbBFrame,hingeData->m_useReferenceFrameA!=0); - } else - { - btTransform rbAFrame; - rbAFrame.deSerializeDouble(hingeData->m_rbAFrame); - hinge = createHingeConstraint(*rbA,rbAFrame,hingeData->m_useReferenceFrameA!=0); - } - if (hingeData->m_enableAngularMotor) - { - hinge->enableAngularMotor(true,(btScalar)hingeData->m_motorTargetVelocity,(btScalar)hingeData->m_maxMotorImpulse); - } - hinge->setAngularOnly(hingeData->m_angularOnly!=0); - hinge->setLimit(btScalar(hingeData->m_lowerLimit),btScalar(hingeData->m_upperLimit),btScalar(hingeData->m_limitSoftness),btScalar(hingeData->m_biasFactor),btScalar(hingeData->m_relaxationFactor)); - - constraint = hinge; - break; - - } - case CONETWIST_CONSTRAINT_TYPE: - { - btConeTwistConstraintData* coneData = (btConeTwistConstraintData*)constraintData; - btConeTwistConstraint* coneTwist = 0; - - if (rbA&& rbB) - { - btTransform rbAFrame,rbBFrame; - rbAFrame.deSerializeFloat(coneData->m_rbAFrame); - rbBFrame.deSerializeFloat(coneData->m_rbBFrame); - coneTwist = createConeTwistConstraint(*rbA,*rbB,rbAFrame,rbBFrame); - } else - { - btTransform rbAFrame; - rbAFrame.deSerializeFloat(coneData->m_rbAFrame); - coneTwist = createConeTwistConstraint(*rbA,rbAFrame); - } - coneTwist->setLimit((btScalar)coneData->m_swingSpan1,(btScalar)coneData->m_swingSpan2,(btScalar)coneData->m_twistSpan,(btScalar)coneData->m_limitSoftness, - (btScalar)coneData->m_biasFactor,(btScalar)coneData->m_relaxationFactor); - coneTwist->setDamping((btScalar)coneData->m_damping); - - constraint = coneTwist; - break; - } - - case D6_SPRING_CONSTRAINT_TYPE: - { - - btGeneric6DofSpringConstraintData* dofData = (btGeneric6DofSpringConstraintData*)constraintData; - // int sz = sizeof(btGeneric6DofSpringConstraintData); - btGeneric6DofSpringConstraint* dof = 0; - - if (rbA && rbB) - { - btTransform rbAFrame,rbBFrame; - rbAFrame.deSerializeFloat(dofData->m_6dofData.m_rbAFrame); - rbBFrame.deSerializeFloat(dofData->m_6dofData.m_rbBFrame); - dof = createGeneric6DofSpringConstraint(*rbA,*rbB,rbAFrame,rbBFrame,dofData->m_6dofData.m_useLinearReferenceFrameA!=0); - } else - { - printf("Error in btWorldImporter::createGeneric6DofSpringConstraint: requires rbA && rbB\n"); - } - - if (dof) - { - btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit; - angLowerLimit.deSerializeFloat(dofData->m_6dofData.m_angularLowerLimit); - angUpperLimit.deSerializeFloat(dofData->m_6dofData.m_angularUpperLimit); - linLowerLimit.deSerializeFloat(dofData->m_6dofData.m_linearLowerLimit); - linUpperlimit.deSerializeFloat(dofData->m_6dofData.m_linearUpperLimit); - - angLowerLimit.setW(0.f); - dof->setAngularLowerLimit(angLowerLimit); - dof->setAngularUpperLimit(angUpperLimit); - dof->setLinearLowerLimit(linLowerLimit); - dof->setLinearUpperLimit(linUpperlimit); - - int i; - if (fileVersion>280) - { - for (i=0;i<6;i++) - { - dof->setStiffness(i,(btScalar)dofData->m_springStiffness[i]); - dof->setEquilibriumPoint(i,(btScalar)dofData->m_equilibriumPoint[i]); - dof->enableSpring(i,dofData->m_springEnabled[i]!=0); - dof->setDamping(i,(btScalar)dofData->m_springDamping[i]); - } - } - } - - constraint = dof; - break; - - } - case D6_CONSTRAINT_TYPE: - { - btGeneric6DofConstraintData* dofData = (btGeneric6DofConstraintData*)constraintData; - btGeneric6DofConstraint* dof = 0; - - if (rbA&& rbB) - { - btTransform rbAFrame,rbBFrame; - rbAFrame.deSerializeFloat(dofData->m_rbAFrame); - rbBFrame.deSerializeFloat(dofData->m_rbBFrame); - dof = createGeneric6DofConstraint(*rbA,*rbB,rbAFrame,rbBFrame,dofData->m_useLinearReferenceFrameA!=0); - } else - { - if (rbB) - { - btTransform rbBFrame; - rbBFrame.deSerializeFloat(dofData->m_rbBFrame); - dof = createGeneric6DofConstraint(*rbB,rbBFrame,dofData->m_useLinearReferenceFrameA!=0); - } else - { - printf("Error in btWorldImporter::createGeneric6DofConstraint: missing rbB\n"); - } - } - - if (dof) - { - btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit; - angLowerLimit.deSerializeFloat(dofData->m_angularLowerLimit); - angUpperLimit.deSerializeFloat(dofData->m_angularUpperLimit); - linLowerLimit.deSerializeFloat(dofData->m_linearLowerLimit); - linUpperlimit.deSerializeFloat(dofData->m_linearUpperLimit); - - dof->setAngularLowerLimit(angLowerLimit); - dof->setAngularUpperLimit(angUpperLimit); - dof->setLinearLowerLimit(linLowerLimit); - dof->setLinearUpperLimit(linUpperlimit); - } - - constraint = dof; - break; - } - case SLIDER_CONSTRAINT_TYPE: - { - btSliderConstraintData* sliderData = (btSliderConstraintData*)constraintData; - btSliderConstraint* slider = 0; - if (rbA&& rbB) - { - btTransform rbAFrame,rbBFrame; - rbAFrame.deSerializeFloat(sliderData->m_rbAFrame); - rbBFrame.deSerializeFloat(sliderData->m_rbBFrame); - slider = createSliderConstraint(*rbA,*rbB,rbAFrame,rbBFrame,sliderData->m_useLinearReferenceFrameA!=0); - } else - { - btTransform rbBFrame; - rbBFrame.deSerializeFloat(sliderData->m_rbBFrame); - slider = createSliderConstraint(*rbB,rbBFrame,sliderData->m_useLinearReferenceFrameA!=0); - } - slider->setLowerLinLimit((btScalar)sliderData->m_linearLowerLimit); - slider->setUpperLinLimit((btScalar)sliderData->m_linearUpperLimit); - slider->setLowerAngLimit((btScalar)sliderData->m_angularLowerLimit); - slider->setUpperAngLimit((btScalar)sliderData->m_angularUpperLimit); - slider->setUseFrameOffset(sliderData->m_useOffsetForConstraintFrame!=0); - constraint = slider; - break; - } - - default: - { - printf("unknown constraint type\n"); - } - }; - - if (constraint) - { - constraint->setDbgDrawSize((btScalar)constraintData->m_dbgDrawSize); - ///those fields didn't exist and set to zero for pre-280 versions, so do a check here - if (fileVersion>=280) - { - constraint->setBreakingImpulseThreshold((btScalar)constraintData->m_breakingImpulseThreshold); - constraint->setEnabled(constraintData->m_isEnabled!=0); - constraint->setOverrideNumSolverIterations(constraintData->m_overrideNumSolverIterations); - } - - if (constraintData->m_name) - { - char* newname = duplicateName(constraintData->m_name); - m_nameConstraintMap.insert(newname,constraint); - m_objectNameMap.insert(constraint,newname); - } - if(m_dynamicsWorld) - m_dynamicsWorld->addConstraint(constraint,constraintData->m_disableCollisionsBetweenLinkedBodies!=0); - } - -} - -void btWorldImporter::convertConstraintFloat(btTypedConstraintFloatData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion) +void btWorldImporter::convertConstraintBackwardsCompatible281(btTypedConstraintData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion) { btTypedConstraint* constraint = 0; - switch (constraintData->m_objectType) - { + switch (constraintData->m_objectType) + { case POINT2POINT_CONSTRAINT_TYPE: - { - btPoint2PointConstraintFloatData* p2pData = (btPoint2PointConstraintFloatData*)constraintData; - if (rbA&& rbB) - { - btVector3 pivotInA,pivotInB; - pivotInA.deSerializeFloat(p2pData->m_pivotInA); - pivotInB.deSerializeFloat(p2pData->m_pivotInB); - constraint = createPoint2PointConstraint(*rbA,*rbB,pivotInA,pivotInB); - - } else - { - btVector3 pivotInA; - pivotInA.deSerializeFloat(p2pData->m_pivotInA); - constraint = createPoint2PointConstraint(*rbA,pivotInA); - } - break; - } - case HINGE_CONSTRAINT_TYPE: - { - btHingeConstraint* hinge = 0; - btHingeConstraintFloatData* hingeData = (btHingeConstraintFloatData*)constraintData; - if (rbA&& rbB) - { - btTransform rbAFrame,rbBFrame; - rbAFrame.deSerializeFloat(hingeData->m_rbAFrame); - rbBFrame.deSerializeFloat(hingeData->m_rbBFrame); - hinge = createHingeConstraint(*rbA,*rbB,rbAFrame,rbBFrame,hingeData->m_useReferenceFrameA!=0); - } else - { - btTransform rbAFrame; - rbAFrame.deSerializeFloat(hingeData->m_rbAFrame); - hinge = createHingeConstraint(*rbA,rbAFrame,hingeData->m_useReferenceFrameA!=0); - } - if (hingeData->m_enableAngularMotor) - { - hinge->enableAngularMotor(true,hingeData->m_motorTargetVelocity,hingeData->m_maxMotorImpulse); - } - hinge->setAngularOnly(hingeData->m_angularOnly!=0); - hinge->setLimit(btScalar(hingeData->m_lowerLimit),btScalar(hingeData->m_upperLimit),btScalar(hingeData->m_limitSoftness),btScalar(hingeData->m_biasFactor),btScalar(hingeData->m_relaxationFactor)); - - constraint = hinge; - break; - - } - case CONETWIST_CONSTRAINT_TYPE: - { - btConeTwistConstraintData* coneData = (btConeTwistConstraintData*)constraintData; - btConeTwistConstraint* coneTwist = 0; - - if (rbA&& rbB) - { - btTransform rbAFrame,rbBFrame; - rbAFrame.deSerializeFloat(coneData->m_rbAFrame); - rbBFrame.deSerializeFloat(coneData->m_rbBFrame); - coneTwist = createConeTwistConstraint(*rbA,*rbB,rbAFrame,rbBFrame); - } else - { - btTransform rbAFrame; - rbAFrame.deSerializeFloat(coneData->m_rbAFrame); - coneTwist = createConeTwistConstraint(*rbA,rbAFrame); - } - coneTwist->setLimit(coneData->m_swingSpan1,coneData->m_swingSpan2,coneData->m_twistSpan,coneData->m_limitSoftness,coneData->m_biasFactor,coneData->m_relaxationFactor); - coneTwist->setDamping(coneData->m_damping); - - constraint = coneTwist; - break; - } - - case D6_SPRING_CONSTRAINT_TYPE: - { - - btGeneric6DofSpringConstraintData* dofData = (btGeneric6DofSpringConstraintData*)constraintData; - // int sz = sizeof(btGeneric6DofSpringConstraintData); - btGeneric6DofSpringConstraint* dof = 0; - - if (rbA && rbB) - { - btTransform rbAFrame,rbBFrame; - rbAFrame.deSerializeFloat(dofData->m_6dofData.m_rbAFrame); - rbBFrame.deSerializeFloat(dofData->m_6dofData.m_rbBFrame); - dof = createGeneric6DofSpringConstraint(*rbA,*rbB,rbAFrame,rbBFrame,dofData->m_6dofData.m_useLinearReferenceFrameA!=0); - } else - { - printf("Error in btWorldImporter::createGeneric6DofSpringConstraint: requires rbA && rbB\n"); - } - - if (dof) - { - btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit; - angLowerLimit.deSerializeFloat(dofData->m_6dofData.m_angularLowerLimit); - angUpperLimit.deSerializeFloat(dofData->m_6dofData.m_angularUpperLimit); - linLowerLimit.deSerializeFloat(dofData->m_6dofData.m_linearLowerLimit); - linUpperlimit.deSerializeFloat(dofData->m_6dofData.m_linearUpperLimit); - - angLowerLimit.setW(0.f); - dof->setAngularLowerLimit(angLowerLimit); - dof->setAngularUpperLimit(angUpperLimit); - dof->setLinearLowerLimit(linLowerLimit); - dof->setLinearUpperLimit(linUpperlimit); - - int i; - if (fileVersion>280) - { - for (i=0;i<6;i++) - { - dof->setStiffness(i,dofData->m_springStiffness[i]); - dof->setEquilibriumPoint(i,dofData->m_equilibriumPoint[i]); - dof->enableSpring(i,dofData->m_springEnabled[i]!=0); - dof->setDamping(i,dofData->m_springDamping[i]); - } - } - } - - constraint = dof; - break; - } - case D6_CONSTRAINT_TYPE: - { - btGeneric6DofConstraintData* dofData = (btGeneric6DofConstraintData*)constraintData; - btGeneric6DofConstraint* dof = 0; - - if (rbA&& rbB) - { - btTransform rbAFrame,rbBFrame; - rbAFrame.deSerializeFloat(dofData->m_rbAFrame); - rbBFrame.deSerializeFloat(dofData->m_rbBFrame); - dof = createGeneric6DofConstraint(*rbA,*rbB,rbAFrame,rbBFrame,dofData->m_useLinearReferenceFrameA!=0); - } else - { - if (rbB) - { - btTransform rbBFrame; - rbBFrame.deSerializeFloat(dofData->m_rbBFrame); - dof = createGeneric6DofConstraint(*rbB,rbBFrame,dofData->m_useLinearReferenceFrameA!=0); - } else - { - printf("Error in btWorldImporter::createGeneric6DofConstraint: missing rbB\n"); - } - } - - if (dof) - { - btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit; - angLowerLimit.deSerializeFloat(dofData->m_angularLowerLimit); - angUpperLimit.deSerializeFloat(dofData->m_angularUpperLimit); - linLowerLimit.deSerializeFloat(dofData->m_linearLowerLimit); - linUpperlimit.deSerializeFloat(dofData->m_linearUpperLimit); - - dof->setAngularLowerLimit(angLowerLimit); - dof->setAngularUpperLimit(angUpperLimit); - dof->setLinearLowerLimit(linLowerLimit); - dof->setLinearUpperLimit(linUpperlimit); - } - - constraint = dof; - break; - } - case SLIDER_CONSTRAINT_TYPE: - { - btSliderConstraintData* sliderData = (btSliderConstraintData*)constraintData; - btSliderConstraint* slider = 0; - if (rbA&& rbB) - { - btTransform rbAFrame,rbBFrame; - rbAFrame.deSerializeFloat(sliderData->m_rbAFrame); - rbBFrame.deSerializeFloat(sliderData->m_rbBFrame); - slider = createSliderConstraint(*rbA,*rbB,rbAFrame,rbBFrame,sliderData->m_useLinearReferenceFrameA!=0); - } else - { - btTransform rbBFrame; - rbBFrame.deSerializeFloat(sliderData->m_rbBFrame); - slider = createSliderConstraint(*rbB,rbBFrame,sliderData->m_useLinearReferenceFrameA!=0); - } - slider->setLowerLinLimit(sliderData->m_linearLowerLimit); - slider->setUpperLinLimit(sliderData->m_linearUpperLimit); - slider->setLowerAngLimit(sliderData->m_angularLowerLimit); - slider->setUpperAngLimit(sliderData->m_angularUpperLimit); - slider->setUseFrameOffset(sliderData->m_useOffsetForConstraintFrame!=0); - constraint = slider; - break; - } - case GEAR_CONSTRAINT_TYPE: - { - btGearConstraintFloatData* gearData = (btGearConstraintFloatData*) constraintData; - btGearConstraint* gear = 0; - if (rbA&&rbB) - { - btVector3 axisInA,axisInB; - axisInA.deSerializeFloat(gearData->m_axisInA); - axisInB.deSerializeFloat(gearData->m_axisInB); - gear = createGearConstraint(*rbA, *rbB, axisInA,axisInB, gearData->m_ratio); - } else - { - btAssert(0); - //perhaps a gear against a 'fixed' body, while the 'fixed' body is not serialized? - //btGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA,const btVector3& axisInB, btScalar ratio=1.f); - } - constraint = gear; - break; - } - case D6_SPRING_2_CONSTRAINT_TYPE: - { - - btGeneric6DofSpring2ConstraintData* dofData = (btGeneric6DofSpring2ConstraintData*)constraintData; - - btGeneric6DofSpring2Constraint* dof = 0; - + { + btPoint2PointConstraintDoubleData* p2pData = (btPoint2PointConstraintDoubleData*)constraintData; if (rbA && rbB) { - btTransform rbAFrame,rbBFrame; - rbAFrame.deSerializeFloat(dofData->m_rbAFrame); - rbBFrame.deSerializeFloat(dofData->m_rbBFrame); - dof = createGeneric6DofSpring2Constraint(*rbA,*rbB,rbAFrame,rbBFrame, dofData->m_rotateOrder); - } else + btVector3 pivotInA, pivotInB; + pivotInA.deSerializeDouble(p2pData->m_pivotInA); + pivotInB.deSerializeDouble(p2pData->m_pivotInB); + constraint = createPoint2PointConstraint(*rbA, *rbB, pivotInA, pivotInB); + } + else { - printf("Error in btWorldImporter::createGeneric6DofSpring2Constraint: requires rbA && rbB\n"); + btVector3 pivotInA; + pivotInA.deSerializeDouble(p2pData->m_pivotInA); + constraint = createPoint2PointConstraint(*rbA, pivotInA); + } + break; + } + case HINGE_CONSTRAINT_TYPE: + { + btHingeConstraint* hinge = 0; + + btHingeConstraintDoubleData* hingeData = (btHingeConstraintDoubleData*)constraintData; + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeDouble(hingeData->m_rbAFrame); + rbBFrame.deSerializeDouble(hingeData->m_rbBFrame); + hinge = createHingeConstraint(*rbA, *rbB, rbAFrame, rbBFrame, hingeData->m_useReferenceFrameA != 0); + } + else + { + btTransform rbAFrame; + rbAFrame.deSerializeDouble(hingeData->m_rbAFrame); + hinge = createHingeConstraint(*rbA, rbAFrame, hingeData->m_useReferenceFrameA != 0); + } + if (hingeData->m_enableAngularMotor) + { + hinge->enableAngularMotor(true, (btScalar)hingeData->m_motorTargetVelocity, (btScalar)hingeData->m_maxMotorImpulse); + } + hinge->setAngularOnly(hingeData->m_angularOnly != 0); + hinge->setLimit(btScalar(hingeData->m_lowerLimit), btScalar(hingeData->m_upperLimit), btScalar(hingeData->m_limitSoftness), btScalar(hingeData->m_biasFactor), btScalar(hingeData->m_relaxationFactor)); + + constraint = hinge; + break; + } + case CONETWIST_CONSTRAINT_TYPE: + { + btConeTwistConstraintData* coneData = (btConeTwistConstraintData*)constraintData; + btConeTwistConstraint* coneTwist = 0; + + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeFloat(coneData->m_rbAFrame); + rbBFrame.deSerializeFloat(coneData->m_rbBFrame); + coneTwist = createConeTwistConstraint(*rbA, *rbB, rbAFrame, rbBFrame); + } + else + { + btTransform rbAFrame; + rbAFrame.deSerializeFloat(coneData->m_rbAFrame); + coneTwist = createConeTwistConstraint(*rbA, rbAFrame); + } + coneTwist->setLimit((btScalar)coneData->m_swingSpan1, (btScalar)coneData->m_swingSpan2, (btScalar)coneData->m_twistSpan, (btScalar)coneData->m_limitSoftness, + (btScalar)coneData->m_biasFactor, (btScalar)coneData->m_relaxationFactor); + coneTwist->setDamping((btScalar)coneData->m_damping); + + constraint = coneTwist; + break; + } + + case D6_SPRING_CONSTRAINT_TYPE: + { + btGeneric6DofSpringConstraintData* dofData = (btGeneric6DofSpringConstraintData*)constraintData; + // int sz = sizeof(btGeneric6DofSpringConstraintData); + btGeneric6DofSpringConstraint* dof = 0; + + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeFloat(dofData->m_6dofData.m_rbAFrame); + rbBFrame.deSerializeFloat(dofData->m_6dofData.m_rbBFrame); + dof = createGeneric6DofSpringConstraint(*rbA, *rbB, rbAFrame, rbBFrame, dofData->m_6dofData.m_useLinearReferenceFrameA != 0); + } + else + { + printf("Error in btWorldImporter::createGeneric6DofSpringConstraint: requires rbA && rbB\n"); } if (dof) { - btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit; + btVector3 angLowerLimit, angUpperLimit, linLowerLimit, linUpperlimit; + angLowerLimit.deSerializeFloat(dofData->m_6dofData.m_angularLowerLimit); + angUpperLimit.deSerializeFloat(dofData->m_6dofData.m_angularUpperLimit); + linLowerLimit.deSerializeFloat(dofData->m_6dofData.m_linearLowerLimit); + linUpperlimit.deSerializeFloat(dofData->m_6dofData.m_linearUpperLimit); + + angLowerLimit.setW(0.f); + dof->setAngularLowerLimit(angLowerLimit); + dof->setAngularUpperLimit(angUpperLimit); + dof->setLinearLowerLimit(linLowerLimit); + dof->setLinearUpperLimit(linUpperlimit); + + int i; + if (fileVersion > 280) + { + for (i = 0; i < 6; i++) + { + dof->setStiffness(i, (btScalar)dofData->m_springStiffness[i]); + dof->setEquilibriumPoint(i, (btScalar)dofData->m_equilibriumPoint[i]); + dof->enableSpring(i, dofData->m_springEnabled[i] != 0); + dof->setDamping(i, (btScalar)dofData->m_springDamping[i]); + } + } + } + + constraint = dof; + break; + } + case D6_CONSTRAINT_TYPE: + { + btGeneric6DofConstraintData* dofData = (btGeneric6DofConstraintData*)constraintData; + btGeneric6DofConstraint* dof = 0; + + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeFloat(dofData->m_rbAFrame); + rbBFrame.deSerializeFloat(dofData->m_rbBFrame); + dof = createGeneric6DofConstraint(*rbA, *rbB, rbAFrame, rbBFrame, dofData->m_useLinearReferenceFrameA != 0); + } + else + { + if (rbB) + { + btTransform rbBFrame; + rbBFrame.deSerializeFloat(dofData->m_rbBFrame); + dof = createGeneric6DofConstraint(*rbB, rbBFrame, dofData->m_useLinearReferenceFrameA != 0); + } + else + { + printf("Error in btWorldImporter::createGeneric6DofConstraint: missing rbB\n"); + } + } + + if (dof) + { + btVector3 angLowerLimit, angUpperLimit, linLowerLimit, linUpperlimit; angLowerLimit.deSerializeFloat(dofData->m_angularLowerLimit); angUpperLimit.deSerializeFloat(dofData->m_angularUpperLimit); linLowerLimit.deSerializeFloat(dofData->m_linearLowerLimit); linUpperlimit.deSerializeFloat(dofData->m_linearUpperLimit); - + + dof->setAngularLowerLimit(angLowerLimit); + dof->setAngularUpperLimit(angUpperLimit); + dof->setLinearLowerLimit(linLowerLimit); + dof->setLinearUpperLimit(linUpperlimit); + } + + constraint = dof; + break; + } + case SLIDER_CONSTRAINT_TYPE: + { + btSliderConstraintData* sliderData = (btSliderConstraintData*)constraintData; + btSliderConstraint* slider = 0; + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeFloat(sliderData->m_rbAFrame); + rbBFrame.deSerializeFloat(sliderData->m_rbBFrame); + slider = createSliderConstraint(*rbA, *rbB, rbAFrame, rbBFrame, sliderData->m_useLinearReferenceFrameA != 0); + } + else + { + btTransform rbBFrame; + rbBFrame.deSerializeFloat(sliderData->m_rbBFrame); + slider = createSliderConstraint(*rbB, rbBFrame, sliderData->m_useLinearReferenceFrameA != 0); + } + slider->setLowerLinLimit((btScalar)sliderData->m_linearLowerLimit); + slider->setUpperLinLimit((btScalar)sliderData->m_linearUpperLimit); + slider->setLowerAngLimit((btScalar)sliderData->m_angularLowerLimit); + slider->setUpperAngLimit((btScalar)sliderData->m_angularUpperLimit); + slider->setUseFrameOffset(sliderData->m_useOffsetForConstraintFrame != 0); + constraint = slider; + break; + } + + default: + { + printf("unknown constraint type\n"); + } + }; + + if (constraint) + { + constraint->setDbgDrawSize((btScalar)constraintData->m_dbgDrawSize); + ///those fields didn't exist and set to zero for pre-280 versions, so do a check here + if (fileVersion >= 280) + { + constraint->setBreakingImpulseThreshold((btScalar)constraintData->m_breakingImpulseThreshold); + constraint->setEnabled(constraintData->m_isEnabled != 0); + constraint->setOverrideNumSolverIterations(constraintData->m_overrideNumSolverIterations); + } + + if (constraintData->m_name) + { + char* newname = duplicateName(constraintData->m_name); + m_nameConstraintMap.insert(newname, constraint); + m_objectNameMap.insert(constraint, newname); + } + if (m_dynamicsWorld) + m_dynamicsWorld->addConstraint(constraint, constraintData->m_disableCollisionsBetweenLinkedBodies != 0); + } +} + +void btWorldImporter::convertConstraintFloat(btTypedConstraintFloatData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion) +{ + btTypedConstraint* constraint = 0; + + switch (constraintData->m_objectType) + { + case POINT2POINT_CONSTRAINT_TYPE: + { + btPoint2PointConstraintFloatData* p2pData = (btPoint2PointConstraintFloatData*)constraintData; + if (rbA && rbB) + { + btVector3 pivotInA, pivotInB; + pivotInA.deSerializeFloat(p2pData->m_pivotInA); + pivotInB.deSerializeFloat(p2pData->m_pivotInB); + constraint = createPoint2PointConstraint(*rbA, *rbB, pivotInA, pivotInB); + } + else + { + btVector3 pivotInA; + pivotInA.deSerializeFloat(p2pData->m_pivotInA); + constraint = createPoint2PointConstraint(*rbA, pivotInA); + } + break; + } + case HINGE_CONSTRAINT_TYPE: + { + btHingeConstraint* hinge = 0; + btHingeConstraintFloatData* hingeData = (btHingeConstraintFloatData*)constraintData; + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeFloat(hingeData->m_rbAFrame); + rbBFrame.deSerializeFloat(hingeData->m_rbBFrame); + hinge = createHingeConstraint(*rbA, *rbB, rbAFrame, rbBFrame, hingeData->m_useReferenceFrameA != 0); + } + else + { + btTransform rbAFrame; + rbAFrame.deSerializeFloat(hingeData->m_rbAFrame); + hinge = createHingeConstraint(*rbA, rbAFrame, hingeData->m_useReferenceFrameA != 0); + } + if (hingeData->m_enableAngularMotor) + { + hinge->enableAngularMotor(true, hingeData->m_motorTargetVelocity, hingeData->m_maxMotorImpulse); + } + hinge->setAngularOnly(hingeData->m_angularOnly != 0); + hinge->setLimit(btScalar(hingeData->m_lowerLimit), btScalar(hingeData->m_upperLimit), btScalar(hingeData->m_limitSoftness), btScalar(hingeData->m_biasFactor), btScalar(hingeData->m_relaxationFactor)); + + constraint = hinge; + break; + } + case CONETWIST_CONSTRAINT_TYPE: + { + btConeTwistConstraintData* coneData = (btConeTwistConstraintData*)constraintData; + btConeTwistConstraint* coneTwist = 0; + + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeFloat(coneData->m_rbAFrame); + rbBFrame.deSerializeFloat(coneData->m_rbBFrame); + coneTwist = createConeTwistConstraint(*rbA, *rbB, rbAFrame, rbBFrame); + } + else + { + btTransform rbAFrame; + rbAFrame.deSerializeFloat(coneData->m_rbAFrame); + coneTwist = createConeTwistConstraint(*rbA, rbAFrame); + } + coneTwist->setLimit(coneData->m_swingSpan1, coneData->m_swingSpan2, coneData->m_twistSpan, coneData->m_limitSoftness, coneData->m_biasFactor, coneData->m_relaxationFactor); + coneTwist->setDamping(coneData->m_damping); + + constraint = coneTwist; + break; + } + + case D6_SPRING_CONSTRAINT_TYPE: + { + btGeneric6DofSpringConstraintData* dofData = (btGeneric6DofSpringConstraintData*)constraintData; + // int sz = sizeof(btGeneric6DofSpringConstraintData); + btGeneric6DofSpringConstraint* dof = 0; + + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeFloat(dofData->m_6dofData.m_rbAFrame); + rbBFrame.deSerializeFloat(dofData->m_6dofData.m_rbBFrame); + dof = createGeneric6DofSpringConstraint(*rbA, *rbB, rbAFrame, rbBFrame, dofData->m_6dofData.m_useLinearReferenceFrameA != 0); + } + else + { + printf("Error in btWorldImporter::createGeneric6DofSpringConstraint: requires rbA && rbB\n"); + } + + if (dof) + { + btVector3 angLowerLimit, angUpperLimit, linLowerLimit, linUpperlimit; + angLowerLimit.deSerializeFloat(dofData->m_6dofData.m_angularLowerLimit); + angUpperLimit.deSerializeFloat(dofData->m_6dofData.m_angularUpperLimit); + linLowerLimit.deSerializeFloat(dofData->m_6dofData.m_linearLowerLimit); + linUpperlimit.deSerializeFloat(dofData->m_6dofData.m_linearUpperLimit); + angLowerLimit.setW(0.f); dof->setAngularLowerLimit(angLowerLimit); dof->setAngularUpperLimit(angUpperLimit); @@ -987,329 +834,135 @@ void btWorldImporter::convertConstraintFloat(btTypedConstraintFloatData* constra dof->setLinearUpperLimit(linUpperlimit); int i; - if (fileVersion>280) + if (fileVersion > 280) { - //6-dof: 3 linear followed by 3 angular - for (i=0;i<3;i++) + for (i = 0; i < 6; i++) { - dof->setStiffness(i,dofData->m_linearSpringStiffness.m_floats[i],dofData->m_linearSpringStiffnessLimited[i]!=0); - dof->setEquilibriumPoint(i,dofData->m_linearEquilibriumPoint.m_floats[i]); - dof->enableSpring(i,dofData->m_linearEnableSpring[i]!=0); - dof->setDamping(i,dofData->m_linearSpringDamping.m_floats[i],(dofData->m_linearSpringDampingLimited[i]!=0)); + dof->setStiffness(i, dofData->m_springStiffness[i]); + dof->setEquilibriumPoint(i, dofData->m_equilibriumPoint[i]); + dof->enableSpring(i, dofData->m_springEnabled[i] != 0); + dof->setDamping(i, dofData->m_springDamping[i]); } - for (i=0;i<3;i++) - { - dof->setStiffness(i+3,dofData->m_angularSpringStiffness.m_floats[i],(dofData->m_angularSpringStiffnessLimited[i]!=0)); - dof->setEquilibriumPoint(i+3,dofData->m_angularEquilibriumPoint.m_floats[i]); - dof->enableSpring(i+3,dofData->m_angularEnableSpring[i]!=0); - dof->setDamping(i+3,dofData->m_angularSpringDamping.m_floats[i],dofData->m_angularSpringDampingLimited[i]); - } - } } constraint = dof; break; - - } - case FIXED_CONSTRAINT_TYPE: - { - - btGeneric6DofSpring2Constraint* dof = 0; - if (rbA && rbB) - { - btTransform rbAFrame,rbBFrame; - //compute a shared world frame, and compute frameInA, frameInB relative to this - btTransform sharedFrame; - sharedFrame.setIdentity(); - btVector3 centerPos = btScalar(0.5)*(rbA->getWorldTransform().getOrigin()+ - rbB->getWorldTransform().getOrigin()); - sharedFrame.setOrigin(centerPos); - rbAFrame = rbA->getWorldTransform().inverse()*sharedFrame; - rbBFrame = rbB->getWorldTransform().inverse()*sharedFrame; - - - dof = createGeneric6DofSpring2Constraint(*rbA,*rbB,rbAFrame,rbBFrame, RO_XYZ); - dof->setLinearUpperLimit(btVector3(0,0,0)); - dof->setLinearLowerLimit(btVector3(0,0,0)); - dof->setAngularUpperLimit(btVector3(0,0,0)); - dof->setAngularLowerLimit(btVector3(0,0,0)); - - } else - { - printf("Error in btWorldImporter::createGeneric6DofSpring2Constraint: requires rbA && rbB\n"); - } - - constraint = dof; - break; - } - default: - { - printf("unknown constraint type\n"); - } - }; - - if (constraint) - { - constraint->setDbgDrawSize(constraintData->m_dbgDrawSize); - ///those fields didn't exist and set to zero for pre-280 versions, so do a check here - if (fileVersion>=280) - { - constraint->setBreakingImpulseThreshold(constraintData->m_breakingImpulseThreshold); - constraint->setEnabled(constraintData->m_isEnabled!=0); - constraint->setOverrideNumSolverIterations(constraintData->m_overrideNumSolverIterations); - } - - if (constraintData->m_name) - { - char* newname = duplicateName(constraintData->m_name); - m_nameConstraintMap.insert(newname,constraint); - m_objectNameMap.insert(constraint,newname); - } - if(m_dynamicsWorld) - m_dynamicsWorld->addConstraint(constraint,constraintData->m_disableCollisionsBetweenLinkedBodies!=0); } - - -} - - - -void btWorldImporter::convertConstraintDouble(btTypedConstraintDoubleData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion) -{ - btTypedConstraint* constraint = 0; - - switch (constraintData->m_objectType) - { - case POINT2POINT_CONSTRAINT_TYPE: - { - btPoint2PointConstraintDoubleData2* p2pData = (btPoint2PointConstraintDoubleData2*)constraintData; - if (rbA && rbB) - { - btVector3 pivotInA,pivotInB; - pivotInA.deSerializeDouble(p2pData->m_pivotInA); - pivotInB.deSerializeDouble(p2pData->m_pivotInB); - constraint = createPoint2PointConstraint(*rbA,*rbB,pivotInA,pivotInB); - } else - { - btVector3 pivotInA; - pivotInA.deSerializeDouble(p2pData->m_pivotInA); - constraint = createPoint2PointConstraint(*rbA,pivotInA); - } - break; - } - case HINGE_CONSTRAINT_TYPE: - { - btHingeConstraint* hinge = 0; - - btHingeConstraintDoubleData2* hingeData = (btHingeConstraintDoubleData2*)constraintData; - if (rbA&& rbB) - { - btTransform rbAFrame,rbBFrame; - rbAFrame.deSerializeDouble(hingeData->m_rbAFrame); - rbBFrame.deSerializeDouble(hingeData->m_rbBFrame); - hinge = createHingeConstraint(*rbA,*rbB,rbAFrame,rbBFrame,hingeData->m_useReferenceFrameA!=0); - } else - { - btTransform rbAFrame; - rbAFrame.deSerializeDouble(hingeData->m_rbAFrame); - hinge = createHingeConstraint(*rbA,rbAFrame,hingeData->m_useReferenceFrameA!=0); - } - if (hingeData->m_enableAngularMotor) - { - hinge->enableAngularMotor(true,(btScalar)hingeData->m_motorTargetVelocity,(btScalar)hingeData->m_maxMotorImpulse); - } - hinge->setAngularOnly(hingeData->m_angularOnly!=0); - hinge->setLimit(btScalar(hingeData->m_lowerLimit),btScalar(hingeData->m_upperLimit),btScalar(hingeData->m_limitSoftness),btScalar(hingeData->m_biasFactor),btScalar(hingeData->m_relaxationFactor)); - - constraint = hinge; - break; - - } - case CONETWIST_CONSTRAINT_TYPE: - { - btConeTwistConstraintDoubleData* coneData = (btConeTwistConstraintDoubleData*)constraintData; - btConeTwistConstraint* coneTwist = 0; - - if (rbA&& rbB) - { - btTransform rbAFrame,rbBFrame; - rbAFrame.deSerializeDouble(coneData->m_rbAFrame); - rbBFrame.deSerializeDouble(coneData->m_rbBFrame); - coneTwist = createConeTwistConstraint(*rbA,*rbB,rbAFrame,rbBFrame); - } else - { - btTransform rbAFrame; - rbAFrame.deSerializeDouble(coneData->m_rbAFrame); - coneTwist = createConeTwistConstraint(*rbA,rbAFrame); - } - coneTwist->setLimit((btScalar)coneData->m_swingSpan1,(btScalar)coneData->m_swingSpan2,(btScalar)coneData->m_twistSpan,(btScalar)coneData->m_limitSoftness, - (btScalar)coneData->m_biasFactor,(btScalar)coneData->m_relaxationFactor); - coneTwist->setDamping((btScalar)coneData->m_damping); - - constraint = coneTwist; - break; - } - - case D6_SPRING_CONSTRAINT_TYPE: - { - - btGeneric6DofSpringConstraintDoubleData2* dofData = (btGeneric6DofSpringConstraintDoubleData2*)constraintData; - // int sz = sizeof(btGeneric6DofSpringConstraintData); - btGeneric6DofSpringConstraint* dof = 0; - - if (rbA && rbB) - { - btTransform rbAFrame,rbBFrame; - rbAFrame.deSerializeDouble(dofData->m_6dofData.m_rbAFrame); - rbBFrame.deSerializeDouble(dofData->m_6dofData.m_rbBFrame); - dof = createGeneric6DofSpringConstraint(*rbA,*rbB,rbAFrame,rbBFrame,dofData->m_6dofData.m_useLinearReferenceFrameA!=0); - } else - { - printf("Error in btWorldImporter::createGeneric6DofSpringConstraint: requires rbA && rbB\n"); - } - - if (dof) - { - btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit; - angLowerLimit.deSerializeDouble(dofData->m_6dofData.m_angularLowerLimit); - angUpperLimit.deSerializeDouble(dofData->m_6dofData.m_angularUpperLimit); - linLowerLimit.deSerializeDouble(dofData->m_6dofData.m_linearLowerLimit); - linUpperlimit.deSerializeDouble(dofData->m_6dofData.m_linearUpperLimit); - - angLowerLimit.setW(0.f); - dof->setAngularLowerLimit(angLowerLimit); - dof->setAngularUpperLimit(angUpperLimit); - dof->setLinearLowerLimit(linLowerLimit); - dof->setLinearUpperLimit(linUpperlimit); - - int i; - if (fileVersion>280) - { - for (i=0;i<6;i++) - { - dof->setStiffness(i,(btScalar)dofData->m_springStiffness[i]); - dof->setEquilibriumPoint(i,(btScalar)dofData->m_equilibriumPoint[i]); - dof->enableSpring(i,dofData->m_springEnabled[i]!=0); - dof->setDamping(i,(btScalar)dofData->m_springDamping[i]); - } - } - } - - constraint = dof; - break; - } case D6_CONSTRAINT_TYPE: - { - btGeneric6DofConstraintDoubleData2* dofData = (btGeneric6DofConstraintDoubleData2*)constraintData; - btGeneric6DofConstraint* dof = 0; + { + btGeneric6DofConstraintData* dofData = (btGeneric6DofConstraintData*)constraintData; + btGeneric6DofConstraint* dof = 0; - if (rbA&& rbB) - { - btTransform rbAFrame,rbBFrame; - rbAFrame.deSerializeDouble(dofData->m_rbAFrame); - rbBFrame.deSerializeDouble(dofData->m_rbBFrame); - dof = createGeneric6DofConstraint(*rbA,*rbB,rbAFrame,rbBFrame,dofData->m_useLinearReferenceFrameA!=0); - } else - { - if (rbB) - { - btTransform rbBFrame; - rbBFrame.deSerializeDouble(dofData->m_rbBFrame); - dof = createGeneric6DofConstraint(*rbB,rbBFrame,dofData->m_useLinearReferenceFrameA!=0); - } else - { - printf("Error in btWorldImporter::createGeneric6DofConstraint: missing rbB\n"); - } - } - - if (dof) - { - btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit; - angLowerLimit.deSerializeDouble(dofData->m_angularLowerLimit); - angUpperLimit.deSerializeDouble(dofData->m_angularUpperLimit); - linLowerLimit.deSerializeDouble(dofData->m_linearLowerLimit); - linUpperlimit.deSerializeDouble(dofData->m_linearUpperLimit); - - dof->setAngularLowerLimit(angLowerLimit); - dof->setAngularUpperLimit(angUpperLimit); - dof->setLinearLowerLimit(linLowerLimit); - dof->setLinearUpperLimit(linUpperlimit); - } - - constraint = dof; - break; - } - case SLIDER_CONSTRAINT_TYPE: - { - btSliderConstraintDoubleData* sliderData = (btSliderConstraintDoubleData*)constraintData; - btSliderConstraint* slider = 0; - if (rbA&& rbB) - { - btTransform rbAFrame,rbBFrame; - rbAFrame.deSerializeDouble(sliderData->m_rbAFrame); - rbBFrame.deSerializeDouble(sliderData->m_rbBFrame); - slider = createSliderConstraint(*rbA,*rbB,rbAFrame,rbBFrame,sliderData->m_useLinearReferenceFrameA!=0); - } else - { - btTransform rbBFrame; - rbBFrame.deSerializeDouble(sliderData->m_rbBFrame); - slider = createSliderConstraint(*rbB,rbBFrame,sliderData->m_useLinearReferenceFrameA!=0); - } - slider->setLowerLinLimit((btScalar)sliderData->m_linearLowerLimit); - slider->setUpperLinLimit((btScalar)sliderData->m_linearUpperLimit); - slider->setLowerAngLimit((btScalar)sliderData->m_angularLowerLimit); - slider->setUpperAngLimit((btScalar)sliderData->m_angularUpperLimit); - slider->setUseFrameOffset(sliderData->m_useOffsetForConstraintFrame!=0); - constraint = slider; - break; - } - case GEAR_CONSTRAINT_TYPE: - { - btGearConstraintDoubleData* gearData = (btGearConstraintDoubleData*) constraintData; - btGearConstraint* gear = 0; - if (rbA&&rbB) - { - btVector3 axisInA,axisInB; - axisInA.deSerializeDouble(gearData->m_axisInA); - axisInB.deSerializeDouble(gearData->m_axisInB); - gear = createGearConstraint(*rbA, *rbB, axisInA,axisInB, gearData->m_ratio); - } else - { - btAssert(0); - //perhaps a gear against a 'fixed' body, while the 'fixed' body is not serialized? - //btGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA,const btVector3& axisInB, btScalar ratio=1.f); - } - constraint = gear; - break; - } - - case D6_SPRING_2_CONSTRAINT_TYPE: - { - - btGeneric6DofSpring2ConstraintDoubleData2* dofData = (btGeneric6DofSpring2ConstraintDoubleData2*)constraintData; - - btGeneric6DofSpring2Constraint* dof = 0; - if (rbA && rbB) { - btTransform rbAFrame,rbBFrame; - rbAFrame.deSerializeDouble(dofData->m_rbAFrame); - rbBFrame.deSerializeDouble(dofData->m_rbBFrame); - dof = createGeneric6DofSpring2Constraint(*rbA,*rbB,rbAFrame,rbBFrame, dofData->m_rotateOrder); - } else + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeFloat(dofData->m_rbAFrame); + rbBFrame.deSerializeFloat(dofData->m_rbBFrame); + dof = createGeneric6DofConstraint(*rbA, *rbB, rbAFrame, rbBFrame, dofData->m_useLinearReferenceFrameA != 0); + } + else + { + if (rbB) + { + btTransform rbBFrame; + rbBFrame.deSerializeFloat(dofData->m_rbBFrame); + dof = createGeneric6DofConstraint(*rbB, rbBFrame, dofData->m_useLinearReferenceFrameA != 0); + } + else + { + printf("Error in btWorldImporter::createGeneric6DofConstraint: missing rbB\n"); + } + } + + if (dof) + { + btVector3 angLowerLimit, angUpperLimit, linLowerLimit, linUpperlimit; + angLowerLimit.deSerializeFloat(dofData->m_angularLowerLimit); + angUpperLimit.deSerializeFloat(dofData->m_angularUpperLimit); + linLowerLimit.deSerializeFloat(dofData->m_linearLowerLimit); + linUpperlimit.deSerializeFloat(dofData->m_linearUpperLimit); + + dof->setAngularLowerLimit(angLowerLimit); + dof->setAngularUpperLimit(angUpperLimit); + dof->setLinearLowerLimit(linLowerLimit); + dof->setLinearUpperLimit(linUpperlimit); + } + + constraint = dof; + break; + } + case SLIDER_CONSTRAINT_TYPE: + { + btSliderConstraintData* sliderData = (btSliderConstraintData*)constraintData; + btSliderConstraint* slider = 0; + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeFloat(sliderData->m_rbAFrame); + rbBFrame.deSerializeFloat(sliderData->m_rbBFrame); + slider = createSliderConstraint(*rbA, *rbB, rbAFrame, rbBFrame, sliderData->m_useLinearReferenceFrameA != 0); + } + else + { + btTransform rbBFrame; + rbBFrame.deSerializeFloat(sliderData->m_rbBFrame); + slider = createSliderConstraint(*rbB, rbBFrame, sliderData->m_useLinearReferenceFrameA != 0); + } + slider->setLowerLinLimit(sliderData->m_linearLowerLimit); + slider->setUpperLinLimit(sliderData->m_linearUpperLimit); + slider->setLowerAngLimit(sliderData->m_angularLowerLimit); + slider->setUpperAngLimit(sliderData->m_angularUpperLimit); + slider->setUseFrameOffset(sliderData->m_useOffsetForConstraintFrame != 0); + constraint = slider; + break; + } + case GEAR_CONSTRAINT_TYPE: + { + btGearConstraintFloatData* gearData = (btGearConstraintFloatData*)constraintData; + btGearConstraint* gear = 0; + if (rbA && rbB) + { + btVector3 axisInA, axisInB; + axisInA.deSerializeFloat(gearData->m_axisInA); + axisInB.deSerializeFloat(gearData->m_axisInB); + gear = createGearConstraint(*rbA, *rbB, axisInA, axisInB, gearData->m_ratio); + } + else + { + btAssert(0); + //perhaps a gear against a 'fixed' body, while the 'fixed' body is not serialized? + //btGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA,const btVector3& axisInB, btScalar ratio=1.f); + } + constraint = gear; + break; + } + case D6_SPRING_2_CONSTRAINT_TYPE: + { + btGeneric6DofSpring2ConstraintData* dofData = (btGeneric6DofSpring2ConstraintData*)constraintData; + + btGeneric6DofSpring2Constraint* dof = 0; + + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeFloat(dofData->m_rbAFrame); + rbBFrame.deSerializeFloat(dofData->m_rbBFrame); + dof = createGeneric6DofSpring2Constraint(*rbA, *rbB, rbAFrame, rbBFrame, dofData->m_rotateOrder); + } + else { printf("Error in btWorldImporter::createGeneric6DofSpring2Constraint: requires rbA && rbB\n"); } if (dof) { - btVector3 angLowerLimit,angUpperLimit, linLowerLimit,linUpperlimit; - angLowerLimit.deSerializeDouble(dofData->m_angularLowerLimit); - angUpperLimit.deSerializeDouble(dofData->m_angularUpperLimit); - linLowerLimit.deSerializeDouble(dofData->m_linearLowerLimit); - linUpperlimit.deSerializeDouble(dofData->m_linearUpperLimit); - + btVector3 angLowerLimit, angUpperLimit, linLowerLimit, linUpperlimit; + angLowerLimit.deSerializeFloat(dofData->m_angularLowerLimit); + angUpperLimit.deSerializeFloat(dofData->m_angularUpperLimit); + linLowerLimit.deSerializeFloat(dofData->m_linearLowerLimit); + linUpperlimit.deSerializeFloat(dofData->m_linearUpperLimit); + angLowerLimit.setW(0.f); dof->setAngularLowerLimit(angLowerLimit); dof->setAngularUpperLimit(angUpperLimit); @@ -1317,139 +970,452 @@ void btWorldImporter::convertConstraintDouble(btTypedConstraintDoubleData* const dof->setLinearUpperLimit(linUpperlimit); int i; - if (fileVersion>280) + if (fileVersion > 280) { //6-dof: 3 linear followed by 3 angular - for (i=0;i<3;i++) + for (i = 0; i < 3; i++) { - dof->setStiffness(i,dofData->m_linearSpringStiffness.m_floats[i],dofData->m_linearSpringStiffnessLimited[i]); - dof->setEquilibriumPoint(i,dofData->m_linearEquilibriumPoint.m_floats[i]); - dof->enableSpring(i,dofData->m_linearEnableSpring[i]!=0); - dof->setDamping(i,dofData->m_linearSpringDamping.m_floats[i],(dofData->m_linearSpringDampingLimited[i]!=0)); + dof->setStiffness(i, dofData->m_linearSpringStiffness.m_floats[i], dofData->m_linearSpringStiffnessLimited[i] != 0); + dof->setEquilibriumPoint(i, dofData->m_linearEquilibriumPoint.m_floats[i]); + dof->enableSpring(i, dofData->m_linearEnableSpring[i] != 0); + dof->setDamping(i, dofData->m_linearSpringDamping.m_floats[i], (dofData->m_linearSpringDampingLimited[i] != 0)); } - for (i=0;i<3;i++) + for (i = 0; i < 3; i++) { - dof->setStiffness(i+3,dofData->m_angularSpringStiffness.m_floats[i],(dofData->m_angularSpringStiffnessLimited[i]!=0)); - dof->setEquilibriumPoint(i+3,dofData->m_angularEquilibriumPoint.m_floats[i]); - dof->enableSpring(i+3,dofData->m_angularEnableSpring[i]!=0); - dof->setDamping(i+3,dofData->m_angularSpringDamping.m_floats[i],(dofData->m_angularSpringDampingLimited[i]!=0)); + dof->setStiffness(i + 3, dofData->m_angularSpringStiffness.m_floats[i], (dofData->m_angularSpringStiffnessLimited[i] != 0)); + dof->setEquilibriumPoint(i + 3, dofData->m_angularEquilibriumPoint.m_floats[i]); + dof->enableSpring(i + 3, dofData->m_angularEnableSpring[i] != 0); + dof->setDamping(i + 3, dofData->m_angularSpringDamping.m_floats[i], dofData->m_angularSpringDampingLimited[i]); } - } } constraint = dof; break; - - } - case FIXED_CONSTRAINT_TYPE: - { - - btGeneric6DofSpring2Constraint* dof = 0; - if (rbA && rbB) - { - btTransform rbAFrame,rbBFrame; - //compute a shared world frame, and compute frameInA, frameInB relative to this - btTransform sharedFrame; - sharedFrame.setIdentity(); - btVector3 centerPos = btScalar(0.5)*(rbA->getWorldTransform().getOrigin()+ - rbB->getWorldTransform().getOrigin()); - sharedFrame.setOrigin(centerPos); - rbAFrame = rbA->getWorldTransform().inverse()*sharedFrame; - rbBFrame = rbB->getWorldTransform().inverse()*sharedFrame; - - - dof = createGeneric6DofSpring2Constraint(*rbA,*rbB,rbAFrame,rbBFrame, RO_XYZ); - dof->setLinearUpperLimit(btVector3(0,0,0)); - dof->setLinearLowerLimit(btVector3(0,0,0)); - dof->setAngularUpperLimit(btVector3(0,0,0)); - dof->setAngularLowerLimit(btVector3(0,0,0)); - - } else - { - printf("Error in btWorldImporter::createGeneric6DofSpring2Constraint: requires rbA && rbB\n"); - } - - constraint = dof; - break; - } - - default: - { - printf("unknown constraint type\n"); - } - }; - - if (constraint) - { - constraint->setDbgDrawSize((btScalar)constraintData->m_dbgDrawSize); - ///those fields didn't exist and set to zero for pre-280 versions, so do a check here - if (fileVersion>=280) - { - constraint->setBreakingImpulseThreshold((btScalar)constraintData->m_breakingImpulseThreshold); - constraint->setEnabled(constraintData->m_isEnabled!=0); - constraint->setOverrideNumSolverIterations(constraintData->m_overrideNumSolverIterations); - } - - if (constraintData->m_name) - { - char* newname = duplicateName(constraintData->m_name); - m_nameConstraintMap.insert(newname,constraint); - m_objectNameMap.insert(constraint,newname); - } - if(m_dynamicsWorld) - m_dynamicsWorld->addConstraint(constraint,constraintData->m_disableCollisionsBetweenLinkedBodies!=0); } - + case FIXED_CONSTRAINT_TYPE: + { + btGeneric6DofSpring2Constraint* dof = 0; + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + //compute a shared world frame, and compute frameInA, frameInB relative to this + btTransform sharedFrame; + sharedFrame.setIdentity(); + btVector3 centerPos = btScalar(0.5) * (rbA->getWorldTransform().getOrigin() + + rbB->getWorldTransform().getOrigin()); + sharedFrame.setOrigin(centerPos); + rbAFrame = rbA->getWorldTransform().inverse() * sharedFrame; + rbBFrame = rbB->getWorldTransform().inverse() * sharedFrame; + dof = createGeneric6DofSpring2Constraint(*rbA, *rbB, rbAFrame, rbBFrame, RO_XYZ); + dof->setLinearUpperLimit(btVector3(0, 0, 0)); + dof->setLinearLowerLimit(btVector3(0, 0, 0)); + dof->setAngularUpperLimit(btVector3(0, 0, 0)); + dof->setAngularLowerLimit(btVector3(0, 0, 0)); + } + else + { + printf("Error in btWorldImporter::createGeneric6DofSpring2Constraint: requires rbA && rbB\n"); + } + + constraint = dof; + break; + } + default: + { + printf("unknown constraint type\n"); + } + }; + + if (constraint) + { + constraint->setDbgDrawSize(constraintData->m_dbgDrawSize); + ///those fields didn't exist and set to zero for pre-280 versions, so do a check here + if (fileVersion >= 280) + { + constraint->setBreakingImpulseThreshold(constraintData->m_breakingImpulseThreshold); + constraint->setEnabled(constraintData->m_isEnabled != 0); + constraint->setOverrideNumSolverIterations(constraintData->m_overrideNumSolverIterations); + } + + if (constraintData->m_name) + { + char* newname = duplicateName(constraintData->m_name); + m_nameConstraintMap.insert(newname, constraint); + m_objectNameMap.insert(constraint, newname); + } + if (m_dynamicsWorld) + m_dynamicsWorld->addConstraint(constraint, constraintData->m_disableCollisionsBetweenLinkedBodies != 0); + } } +void btWorldImporter::convertConstraintDouble(btTypedConstraintDoubleData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion) +{ + btTypedConstraint* constraint = 0; + switch (constraintData->m_objectType) + { + case POINT2POINT_CONSTRAINT_TYPE: + { + btPoint2PointConstraintDoubleData2* p2pData = (btPoint2PointConstraintDoubleData2*)constraintData; + if (rbA && rbB) + { + btVector3 pivotInA, pivotInB; + pivotInA.deSerializeDouble(p2pData->m_pivotInA); + pivotInB.deSerializeDouble(p2pData->m_pivotInB); + constraint = createPoint2PointConstraint(*rbA, *rbB, pivotInA, pivotInB); + } + else + { + btVector3 pivotInA; + pivotInA.deSerializeDouble(p2pData->m_pivotInA); + constraint = createPoint2PointConstraint(*rbA, pivotInA); + } + break; + } + case HINGE_CONSTRAINT_TYPE: + { + btHingeConstraint* hinge = 0; + btHingeConstraintDoubleData2* hingeData = (btHingeConstraintDoubleData2*)constraintData; + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeDouble(hingeData->m_rbAFrame); + rbBFrame.deSerializeDouble(hingeData->m_rbBFrame); + hinge = createHingeConstraint(*rbA, *rbB, rbAFrame, rbBFrame, hingeData->m_useReferenceFrameA != 0); + } + else + { + btTransform rbAFrame; + rbAFrame.deSerializeDouble(hingeData->m_rbAFrame); + hinge = createHingeConstraint(*rbA, rbAFrame, hingeData->m_useReferenceFrameA != 0); + } + if (hingeData->m_enableAngularMotor) + { + hinge->enableAngularMotor(true, (btScalar)hingeData->m_motorTargetVelocity, (btScalar)hingeData->m_maxMotorImpulse); + } + hinge->setAngularOnly(hingeData->m_angularOnly != 0); + hinge->setLimit(btScalar(hingeData->m_lowerLimit), btScalar(hingeData->m_upperLimit), btScalar(hingeData->m_limitSoftness), btScalar(hingeData->m_biasFactor), btScalar(hingeData->m_relaxationFactor)); + constraint = hinge; + break; + } + case CONETWIST_CONSTRAINT_TYPE: + { + btConeTwistConstraintDoubleData* coneData = (btConeTwistConstraintDoubleData*)constraintData; + btConeTwistConstraint* coneTwist = 0; + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeDouble(coneData->m_rbAFrame); + rbBFrame.deSerializeDouble(coneData->m_rbBFrame); + coneTwist = createConeTwistConstraint(*rbA, *rbB, rbAFrame, rbBFrame); + } + else + { + btTransform rbAFrame; + rbAFrame.deSerializeDouble(coneData->m_rbAFrame); + coneTwist = createConeTwistConstraint(*rbA, rbAFrame); + } + coneTwist->setLimit((btScalar)coneData->m_swingSpan1, (btScalar)coneData->m_swingSpan2, (btScalar)coneData->m_twistSpan, (btScalar)coneData->m_limitSoftness, + (btScalar)coneData->m_biasFactor, (btScalar)coneData->m_relaxationFactor); + coneTwist->setDamping((btScalar)coneData->m_damping); + constraint = coneTwist; + break; + } + case D6_SPRING_CONSTRAINT_TYPE: + { + btGeneric6DofSpringConstraintDoubleData2* dofData = (btGeneric6DofSpringConstraintDoubleData2*)constraintData; + // int sz = sizeof(btGeneric6DofSpringConstraintData); + btGeneric6DofSpringConstraint* dof = 0; + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeDouble(dofData->m_6dofData.m_rbAFrame); + rbBFrame.deSerializeDouble(dofData->m_6dofData.m_rbBFrame); + dof = createGeneric6DofSpringConstraint(*rbA, *rbB, rbAFrame, rbBFrame, dofData->m_6dofData.m_useLinearReferenceFrameA != 0); + } + else + { + printf("Error in btWorldImporter::createGeneric6DofSpringConstraint: requires rbA && rbB\n"); + } + if (dof) + { + btVector3 angLowerLimit, angUpperLimit, linLowerLimit, linUpperlimit; + angLowerLimit.deSerializeDouble(dofData->m_6dofData.m_angularLowerLimit); + angUpperLimit.deSerializeDouble(dofData->m_6dofData.m_angularUpperLimit); + linLowerLimit.deSerializeDouble(dofData->m_6dofData.m_linearLowerLimit); + linUpperlimit.deSerializeDouble(dofData->m_6dofData.m_linearUpperLimit); -btTriangleIndexVertexArray* btWorldImporter::createMeshInterface(btStridingMeshInterfaceData& meshData) + angLowerLimit.setW(0.f); + dof->setAngularLowerLimit(angLowerLimit); + dof->setAngularUpperLimit(angUpperLimit); + dof->setLinearLowerLimit(linLowerLimit); + dof->setLinearUpperLimit(linUpperlimit); + + int i; + if (fileVersion > 280) + { + for (i = 0; i < 6; i++) + { + dof->setStiffness(i, (btScalar)dofData->m_springStiffness[i]); + dof->setEquilibriumPoint(i, (btScalar)dofData->m_equilibriumPoint[i]); + dof->enableSpring(i, dofData->m_springEnabled[i] != 0); + dof->setDamping(i, (btScalar)dofData->m_springDamping[i]); + } + } + } + + constraint = dof; + break; + } + case D6_CONSTRAINT_TYPE: + { + btGeneric6DofConstraintDoubleData2* dofData = (btGeneric6DofConstraintDoubleData2*)constraintData; + btGeneric6DofConstraint* dof = 0; + + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeDouble(dofData->m_rbAFrame); + rbBFrame.deSerializeDouble(dofData->m_rbBFrame); + dof = createGeneric6DofConstraint(*rbA, *rbB, rbAFrame, rbBFrame, dofData->m_useLinearReferenceFrameA != 0); + } + else + { + if (rbB) + { + btTransform rbBFrame; + rbBFrame.deSerializeDouble(dofData->m_rbBFrame); + dof = createGeneric6DofConstraint(*rbB, rbBFrame, dofData->m_useLinearReferenceFrameA != 0); + } + else + { + printf("Error in btWorldImporter::createGeneric6DofConstraint: missing rbB\n"); + } + } + + if (dof) + { + btVector3 angLowerLimit, angUpperLimit, linLowerLimit, linUpperlimit; + angLowerLimit.deSerializeDouble(dofData->m_angularLowerLimit); + angUpperLimit.deSerializeDouble(dofData->m_angularUpperLimit); + linLowerLimit.deSerializeDouble(dofData->m_linearLowerLimit); + linUpperlimit.deSerializeDouble(dofData->m_linearUpperLimit); + + dof->setAngularLowerLimit(angLowerLimit); + dof->setAngularUpperLimit(angUpperLimit); + dof->setLinearLowerLimit(linLowerLimit); + dof->setLinearUpperLimit(linUpperlimit); + } + + constraint = dof; + break; + } + case SLIDER_CONSTRAINT_TYPE: + { + btSliderConstraintDoubleData* sliderData = (btSliderConstraintDoubleData*)constraintData; + btSliderConstraint* slider = 0; + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeDouble(sliderData->m_rbAFrame); + rbBFrame.deSerializeDouble(sliderData->m_rbBFrame); + slider = createSliderConstraint(*rbA, *rbB, rbAFrame, rbBFrame, sliderData->m_useLinearReferenceFrameA != 0); + } + else + { + btTransform rbBFrame; + rbBFrame.deSerializeDouble(sliderData->m_rbBFrame); + slider = createSliderConstraint(*rbB, rbBFrame, sliderData->m_useLinearReferenceFrameA != 0); + } + slider->setLowerLinLimit((btScalar)sliderData->m_linearLowerLimit); + slider->setUpperLinLimit((btScalar)sliderData->m_linearUpperLimit); + slider->setLowerAngLimit((btScalar)sliderData->m_angularLowerLimit); + slider->setUpperAngLimit((btScalar)sliderData->m_angularUpperLimit); + slider->setUseFrameOffset(sliderData->m_useOffsetForConstraintFrame != 0); + constraint = slider; + break; + } + case GEAR_CONSTRAINT_TYPE: + { + btGearConstraintDoubleData* gearData = (btGearConstraintDoubleData*)constraintData; + btGearConstraint* gear = 0; + if (rbA && rbB) + { + btVector3 axisInA, axisInB; + axisInA.deSerializeDouble(gearData->m_axisInA); + axisInB.deSerializeDouble(gearData->m_axisInB); + gear = createGearConstraint(*rbA, *rbB, axisInA, axisInB, gearData->m_ratio); + } + else + { + btAssert(0); + //perhaps a gear against a 'fixed' body, while the 'fixed' body is not serialized? + //btGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA,const btVector3& axisInB, btScalar ratio=1.f); + } + constraint = gear; + break; + } + + case D6_SPRING_2_CONSTRAINT_TYPE: + { + btGeneric6DofSpring2ConstraintDoubleData2* dofData = (btGeneric6DofSpring2ConstraintDoubleData2*)constraintData; + + btGeneric6DofSpring2Constraint* dof = 0; + + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + rbAFrame.deSerializeDouble(dofData->m_rbAFrame); + rbBFrame.deSerializeDouble(dofData->m_rbBFrame); + dof = createGeneric6DofSpring2Constraint(*rbA, *rbB, rbAFrame, rbBFrame, dofData->m_rotateOrder); + } + else + { + printf("Error in btWorldImporter::createGeneric6DofSpring2Constraint: requires rbA && rbB\n"); + } + + if (dof) + { + btVector3 angLowerLimit, angUpperLimit, linLowerLimit, linUpperlimit; + angLowerLimit.deSerializeDouble(dofData->m_angularLowerLimit); + angUpperLimit.deSerializeDouble(dofData->m_angularUpperLimit); + linLowerLimit.deSerializeDouble(dofData->m_linearLowerLimit); + linUpperlimit.deSerializeDouble(dofData->m_linearUpperLimit); + + angLowerLimit.setW(0.f); + dof->setAngularLowerLimit(angLowerLimit); + dof->setAngularUpperLimit(angUpperLimit); + dof->setLinearLowerLimit(linLowerLimit); + dof->setLinearUpperLimit(linUpperlimit); + + int i; + if (fileVersion > 280) + { + //6-dof: 3 linear followed by 3 angular + for (i = 0; i < 3; i++) + { + dof->setStiffness(i, dofData->m_linearSpringStiffness.m_floats[i], dofData->m_linearSpringStiffnessLimited[i]); + dof->setEquilibriumPoint(i, dofData->m_linearEquilibriumPoint.m_floats[i]); + dof->enableSpring(i, dofData->m_linearEnableSpring[i] != 0); + dof->setDamping(i, dofData->m_linearSpringDamping.m_floats[i], (dofData->m_linearSpringDampingLimited[i] != 0)); + } + for (i = 0; i < 3; i++) + { + dof->setStiffness(i + 3, dofData->m_angularSpringStiffness.m_floats[i], (dofData->m_angularSpringStiffnessLimited[i] != 0)); + dof->setEquilibriumPoint(i + 3, dofData->m_angularEquilibriumPoint.m_floats[i]); + dof->enableSpring(i + 3, dofData->m_angularEnableSpring[i] != 0); + dof->setDamping(i + 3, dofData->m_angularSpringDamping.m_floats[i], (dofData->m_angularSpringDampingLimited[i] != 0)); + } + } + } + + constraint = dof; + break; + } + case FIXED_CONSTRAINT_TYPE: + { + btGeneric6DofSpring2Constraint* dof = 0; + if (rbA && rbB) + { + btTransform rbAFrame, rbBFrame; + //compute a shared world frame, and compute frameInA, frameInB relative to this + btTransform sharedFrame; + sharedFrame.setIdentity(); + btVector3 centerPos = btScalar(0.5) * (rbA->getWorldTransform().getOrigin() + + rbB->getWorldTransform().getOrigin()); + sharedFrame.setOrigin(centerPos); + rbAFrame = rbA->getWorldTransform().inverse() * sharedFrame; + rbBFrame = rbB->getWorldTransform().inverse() * sharedFrame; + + dof = createGeneric6DofSpring2Constraint(*rbA, *rbB, rbAFrame, rbBFrame, RO_XYZ); + dof->setLinearUpperLimit(btVector3(0, 0, 0)); + dof->setLinearLowerLimit(btVector3(0, 0, 0)); + dof->setAngularUpperLimit(btVector3(0, 0, 0)); + dof->setAngularLowerLimit(btVector3(0, 0, 0)); + } + else + { + printf("Error in btWorldImporter::createGeneric6DofSpring2Constraint: requires rbA && rbB\n"); + } + + constraint = dof; + break; + } + + default: + { + printf("unknown constraint type\n"); + } + }; + + if (constraint) + { + constraint->setDbgDrawSize((btScalar)constraintData->m_dbgDrawSize); + ///those fields didn't exist and set to zero for pre-280 versions, so do a check here + if (fileVersion >= 280) + { + constraint->setBreakingImpulseThreshold((btScalar)constraintData->m_breakingImpulseThreshold); + constraint->setEnabled(constraintData->m_isEnabled != 0); + constraint->setOverrideNumSolverIterations(constraintData->m_overrideNumSolverIterations); + } + + if (constraintData->m_name) + { + char* newname = duplicateName(constraintData->m_name); + m_nameConstraintMap.insert(newname, constraint); + m_objectNameMap.insert(constraint, newname); + } + if (m_dynamicsWorld) + m_dynamicsWorld->addConstraint(constraint, constraintData->m_disableCollisionsBetweenLinkedBodies != 0); + } +} + +btTriangleIndexVertexArray* btWorldImporter::createMeshInterface(btStridingMeshInterfaceData& meshData) { btTriangleIndexVertexArray* meshInterface = createTriangleMeshContainer(); - for (int i=0;iaddIndexedMesh(meshPart,meshPart.m_indexType); + meshInterface->addIndexedMesh(meshPart, meshPart.m_indexType); } } return meshInterface; } - btStridingMeshInterfaceData* btWorldImporter::createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData) { //create a new btStridingMeshInterfaceData that is an exact copy of shapedata and store it in the WorldImporter @@ -1540,26 +1505,26 @@ btStridingMeshInterfaceData* btWorldImporter::createStridingMeshInterfaceData(bt newData->m_numMeshParts = interfaceData->m_numMeshParts; newData->m_meshPartsPtr = new btMeshPartData[newData->m_numMeshParts]; - for(int i = 0;i < newData->m_numMeshParts;i++) + for (int i = 0; i < newData->m_numMeshParts; i++) { btMeshPartData* curPart = &interfaceData->m_meshPartsPtr[i]; btMeshPartData* curNewPart = &newData->m_meshPartsPtr[i]; curNewPart->m_numTriangles = curPart->m_numTriangles; curNewPart->m_numVertices = curPart->m_numVertices; - - if(curPart->m_vertices3f) + + if (curPart->m_vertices3f) { curNewPart->m_vertices3f = new btVector3FloatData[curNewPart->m_numVertices]; - memcpy(curNewPart->m_vertices3f,curPart->m_vertices3f,sizeof(btVector3FloatData) * curNewPart->m_numVertices); + memcpy(curNewPart->m_vertices3f, curPart->m_vertices3f, sizeof(btVector3FloatData) * curNewPart->m_numVertices); } else curNewPart->m_vertices3f = NULL; - if(curPart->m_vertices3d) + if (curPart->m_vertices3d) { curNewPart->m_vertices3d = new btVector3DoubleData[curNewPart->m_numVertices]; - memcpy(curNewPart->m_vertices3d,curPart->m_vertices3d,sizeof(btVector3DoubleData) * curNewPart->m_numVertices); + memcpy(curNewPart->m_vertices3d, curPart->m_vertices3d, sizeof(btVector3DoubleData) * curNewPart->m_numVertices); } else curNewPart->m_vertices3d = NULL; @@ -1567,109 +1532,102 @@ btStridingMeshInterfaceData* btWorldImporter::createStridingMeshInterfaceData(bt int numIndices = curNewPart->m_numTriangles * 3; ///the m_3indices8 was not initialized in some Bullet versions, this can cause crashes at loading time ///we catch it by only dealing with m_3indices8 if none of the other indices are initialized - bool uninitialized3indices8Workaround =false; + bool uninitialized3indices8Workaround = false; - if(curPart->m_indices32) + if (curPart->m_indices32) { - uninitialized3indices8Workaround=true; + uninitialized3indices8Workaround = true; curNewPart->m_indices32 = new btIntIndexData[numIndices]; - memcpy(curNewPart->m_indices32,curPart->m_indices32,sizeof(btIntIndexData) * numIndices); + memcpy(curNewPart->m_indices32, curPart->m_indices32, sizeof(btIntIndexData) * numIndices); } else curNewPart->m_indices32 = NULL; - if(curPart->m_3indices16) + if (curPart->m_3indices16) { - uninitialized3indices8Workaround=true; + uninitialized3indices8Workaround = true; curNewPart->m_3indices16 = new btShortIntIndexTripletData[curNewPart->m_numTriangles]; - memcpy(curNewPart->m_3indices16,curPart->m_3indices16,sizeof(btShortIntIndexTripletData) * curNewPart->m_numTriangles); + memcpy(curNewPart->m_3indices16, curPart->m_3indices16, sizeof(btShortIntIndexTripletData) * curNewPart->m_numTriangles); } else curNewPart->m_3indices16 = NULL; - if(curPart->m_indices16) + if (curPart->m_indices16) { - uninitialized3indices8Workaround=true; + uninitialized3indices8Workaround = true; curNewPart->m_indices16 = new btShortIntIndexData[numIndices]; - memcpy(curNewPart->m_indices16,curPart->m_indices16,sizeof(btShortIntIndexData) * numIndices); + memcpy(curNewPart->m_indices16, curPart->m_indices16, sizeof(btShortIntIndexData) * numIndices); } else curNewPart->m_indices16 = NULL; - if(!uninitialized3indices8Workaround && curPart->m_3indices8) + if (!uninitialized3indices8Workaround && curPart->m_3indices8) { curNewPart->m_3indices8 = new btCharIndexTripletData[curNewPart->m_numTriangles]; - memcpy(curNewPart->m_3indices8,curPart->m_3indices8,sizeof(btCharIndexTripletData) * curNewPart->m_numTriangles); + memcpy(curNewPart->m_3indices8, curPart->m_3indices8, sizeof(btCharIndexTripletData) * curNewPart->m_numTriangles); } else curNewPart->m_3indices8 = NULL; - } m_allocatedbtStridingMeshInterfaceDatas.push_back(newData); - return(newData); + return (newData); } #ifdef USE_INTERNAL_EDGE_UTILITY -extern ContactAddedCallback gContactAddedCallback; +extern ContactAddedCallback gContactAddedCallback; -static bool btAdjustInternalEdgeContactsCallback(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) +static bool btAdjustInternalEdgeContactsCallback(btManifoldPoint& cp, const btCollisionObject* colObj0, int partId0, int index0, const btCollisionObject* colObj1, int partId1, int index1) { - - btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1); - //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_BACKFACE_MODE); - //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_DOUBLE_SIDED+BT_TRIANGLE_CONCAVE_DOUBLE_SIDED); + btAdjustInternalEdgeContacts(cp, colObj1, colObj0, partId1, index1); + //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_BACKFACE_MODE); + //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_DOUBLE_SIDED+BT_TRIANGLE_CONCAVE_DOUBLE_SIDED); return true; } -#endif //USE_INTERNAL_EDGE_UTILITY +#endif //USE_INTERNAL_EDGE_UTILITY - - - -btCollisionObject* btWorldImporter::createCollisionObject(const btTransform& startTransform,btCollisionShape* shape, const char* bodyName) +btCollisionObject* btWorldImporter::createCollisionObject(const btTransform& startTransform, btCollisionShape* shape, const char* bodyName) { - return createRigidBody(false,0,startTransform,shape,bodyName); + return createRigidBody(false, 0, startTransform, shape, bodyName); } -void btWorldImporter::setDynamicsWorldInfo(const btVector3& gravity, const btContactSolverInfo& solverInfo) +void btWorldImporter::setDynamicsWorldInfo(const btVector3& gravity, const btContactSolverInfo& solverInfo) { if (m_dynamicsWorld) { m_dynamicsWorld->setGravity(gravity); m_dynamicsWorld->getSolverInfo() = solverInfo; } - } -btRigidBody* btWorldImporter::createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform,btCollisionShape* shape,const char* bodyName) +btRigidBody* btWorldImporter::createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform, btCollisionShape* shape, const char* bodyName) { btVector3 localInertia; localInertia.setZero(); if (mass) - shape->calculateLocalInertia(mass,localInertia); - - btRigidBody* body = new btRigidBody(mass,0,shape,localInertia); + shape->calculateLocalInertia(mass, localInertia); + + btRigidBody* body = new btRigidBody(mass, 0, shape, localInertia); body->setWorldTransform(startTransform); if (m_dynamicsWorld) m_dynamicsWorld->addRigidBody(body); - + if (bodyName) { char* newname = duplicateName(bodyName); - m_objectNameMap.insert(body,newname); - m_nameBodyMap.insert(newname,body); + m_objectNameMap.insert(body, newname); + m_nameBodyMap.insert(newname, body); } m_allocatedRigidBodies.push_back(body); return body; - } -btCollisionShape* btWorldImporter::createPlaneShape(const btVector3& planeNormal,btScalar planeConstant) +btCollisionShape* btWorldImporter::createPlaneShape(const btVector3& planeNormal, btScalar planeConstant) { - btStaticPlaneShape* shape = new btStaticPlaneShape(planeNormal,planeConstant); + btStaticPlaneShape* shape = new btStaticPlaneShape(planeNormal, planeConstant); m_allocatedCollisionShapes.push_back(shape); return shape; } @@ -1686,85 +1644,83 @@ btCollisionShape* btWorldImporter::createSphereShape(btScalar radius) return shape; } - btCollisionShape* btWorldImporter::createCapsuleShapeX(btScalar radius, btScalar height) { - btCapsuleShapeX* shape = new btCapsuleShapeX(radius,height); + btCapsuleShapeX* shape = new btCapsuleShapeX(radius, height); m_allocatedCollisionShapes.push_back(shape); return shape; } btCollisionShape* btWorldImporter::createCapsuleShapeY(btScalar radius, btScalar height) { - btCapsuleShape* shape = new btCapsuleShape(radius,height); + btCapsuleShape* shape = new btCapsuleShape(radius, height); m_allocatedCollisionShapes.push_back(shape); return shape; } btCollisionShape* btWorldImporter::createCapsuleShapeZ(btScalar radius, btScalar height) { - btCapsuleShapeZ* shape = new btCapsuleShapeZ(radius,height); + btCapsuleShapeZ* shape = new btCapsuleShapeZ(radius, height); m_allocatedCollisionShapes.push_back(shape); return shape; } -btCollisionShape* btWorldImporter::createCylinderShapeX(btScalar radius,btScalar height) +btCollisionShape* btWorldImporter::createCylinderShapeX(btScalar radius, btScalar height) { - btCylinderShapeX* shape = new btCylinderShapeX(btVector3(height,radius,radius)); + btCylinderShapeX* shape = new btCylinderShapeX(btVector3(height, radius, radius)); m_allocatedCollisionShapes.push_back(shape); return shape; } -btCollisionShape* btWorldImporter::createCylinderShapeY(btScalar radius,btScalar height) +btCollisionShape* btWorldImporter::createCylinderShapeY(btScalar radius, btScalar height) { - btCylinderShape* shape = new btCylinderShape(btVector3(radius,height,radius)); + btCylinderShape* shape = new btCylinderShape(btVector3(radius, height, radius)); m_allocatedCollisionShapes.push_back(shape); return shape; } -btCollisionShape* btWorldImporter::createCylinderShapeZ(btScalar radius,btScalar height) +btCollisionShape* btWorldImporter::createCylinderShapeZ(btScalar radius, btScalar height) { - btCylinderShapeZ* shape = new btCylinderShapeZ(btVector3(radius,radius,height)); + btCylinderShapeZ* shape = new btCylinderShapeZ(btVector3(radius, radius, height)); m_allocatedCollisionShapes.push_back(shape); return shape; } -btCollisionShape* btWorldImporter::createConeShapeX(btScalar radius,btScalar height) +btCollisionShape* btWorldImporter::createConeShapeX(btScalar radius, btScalar height) { - btConeShapeX* shape = new btConeShapeX(radius,height); + btConeShapeX* shape = new btConeShapeX(radius, height); m_allocatedCollisionShapes.push_back(shape); return shape; } -btCollisionShape* btWorldImporter::createConeShapeY(btScalar radius,btScalar height) +btCollisionShape* btWorldImporter::createConeShapeY(btScalar radius, btScalar height) { - btConeShape* shape = new btConeShape(radius,height); + btConeShape* shape = new btConeShape(radius, height); m_allocatedCollisionShapes.push_back(shape); return shape; } -btCollisionShape* btWorldImporter::createConeShapeZ(btScalar radius,btScalar height) +btCollisionShape* btWorldImporter::createConeShapeZ(btScalar radius, btScalar height) { - btConeShapeZ* shape = new btConeShapeZ(radius,height); + btConeShapeZ* shape = new btConeShapeZ(radius, height); m_allocatedCollisionShapes.push_back(shape); return shape; } -btTriangleIndexVertexArray* btWorldImporter::createTriangleMeshContainer() +btTriangleIndexVertexArray* btWorldImporter::createTriangleMeshContainer() { btTriangleIndexVertexArray* in = new btTriangleIndexVertexArray(); m_allocatedTriangleIndexArrays.push_back(in); return in; } -btOptimizedBvh* btWorldImporter::createOptimizedBvh() +btOptimizedBvh* btWorldImporter::createOptimizedBvh() { btOptimizedBvh* bvh = new btOptimizedBvh(); m_allocatedBvhs.push_back(bvh); return bvh; } - btTriangleInfoMap* btWorldImporter::createTriangleInfoMap() { btTriangleInfoMap* tim = new btTriangleInfoMap(); @@ -1776,16 +1732,15 @@ btBvhTriangleMeshShape* btWorldImporter::createBvhTriangleMeshShape(btStridingMe { if (bvh) { - btBvhTriangleMeshShape* bvhTriMesh = new btBvhTriangleMeshShape(trimesh,bvh->isQuantized(), false); + btBvhTriangleMeshShape* bvhTriMesh = new btBvhTriangleMeshShape(trimesh, bvh->isQuantized(), false); bvhTriMesh->setOptimizedBvh(bvh); m_allocatedCollisionShapes.push_back(bvhTriMesh); return bvhTriMesh; } - btBvhTriangleMeshShape* ts = new btBvhTriangleMeshShape(trimesh,true); + btBvhTriangleMeshShape* ts = new btBvhTriangleMeshShape(trimesh, true); m_allocatedCollisionShapes.push_back(ts); return ts; - } btCollisionShape* btWorldImporter::createConvexTriangleMeshShape(btStridingMeshInterface* trimesh) { @@ -1800,7 +1755,6 @@ btGImpactMeshShape* btWorldImporter::createGimpactShape(btStridingMeshInterface* #else return 0; #endif - } btConvexHullShape* btWorldImporter::createConvexHullShape() { @@ -1816,15 +1770,14 @@ btCompoundShape* btWorldImporter::createCompoundShape() return shape; } - -btScaledBvhTriangleMeshShape* btWorldImporter::createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape,const btVector3& localScaling) +btScaledBvhTriangleMeshShape* btWorldImporter::createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape, const btVector3& localScaling) { - btScaledBvhTriangleMeshShape* shape = new btScaledBvhTriangleMeshShape(meshShape,localScaling); + btScaledBvhTriangleMeshShape* shape = new btScaledBvhTriangleMeshShape(meshShape, localScaling); m_allocatedCollisionShapes.push_back(shape); return shape; } -btMultiSphereShape* btWorldImporter::createMultiSphereShape(const btVector3* positions,const btScalar* radi,int numSpheres) +btMultiSphereShape* btWorldImporter::createMultiSphereShape(const btVector3* positions, const btScalar* radi, int numSpheres) { btMultiSphereShape* shape = new btMultiSphereShape(positions, radi, numSpheres); m_allocatedCollisionShapes.push_back(shape); @@ -1833,109 +1786,104 @@ btMultiSphereShape* btWorldImporter::createMultiSphereShape(const btVector3* pos btRigidBody& btWorldImporter::getFixedBody() { - static btRigidBody s_fixed(0, 0,0); - s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.))); + static btRigidBody s_fixed(0, 0, 0); + s_fixed.setMassProps(btScalar(0.), btVector3(btScalar(0.), btScalar(0.), btScalar(0.))); return s_fixed; } -btPoint2PointConstraint* btWorldImporter::createPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB) +btPoint2PointConstraint* btWorldImporter::createPoint2PointConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& pivotInA, const btVector3& pivotInB) { - btPoint2PointConstraint* p2p = new btPoint2PointConstraint(rbA,rbB,pivotInA,pivotInB); + btPoint2PointConstraint* p2p = new btPoint2PointConstraint(rbA, rbB, pivotInA, pivotInB); m_allocatedConstraints.push_back(p2p); return p2p; } -btPoint2PointConstraint* btWorldImporter::createPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA) +btPoint2PointConstraint* btWorldImporter::createPoint2PointConstraint(btRigidBody& rbA, const btVector3& pivotInA) { - btPoint2PointConstraint* p2p = new btPoint2PointConstraint(rbA,pivotInA); + btPoint2PointConstraint* p2p = new btPoint2PointConstraint(rbA, pivotInA); m_allocatedConstraints.push_back(p2p); return p2p; } - -btHingeConstraint* btWorldImporter::createHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA) +btHingeConstraint* btWorldImporter::createHingeConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA) { - btHingeConstraint* hinge = new btHingeConstraint(rbA,rbB,rbAFrame,rbBFrame,useReferenceFrameA); + btHingeConstraint* hinge = new btHingeConstraint(rbA, rbB, rbAFrame, rbBFrame, useReferenceFrameA); m_allocatedConstraints.push_back(hinge); return hinge; } -btHingeConstraint* btWorldImporter::createHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA) +btHingeConstraint* btWorldImporter::createHingeConstraint(btRigidBody& rbA, const btTransform& rbAFrame, bool useReferenceFrameA) { - btHingeConstraint* hinge = new btHingeConstraint(rbA,rbAFrame,useReferenceFrameA); + btHingeConstraint* hinge = new btHingeConstraint(rbA, rbAFrame, useReferenceFrameA); m_allocatedConstraints.push_back(hinge); return hinge; } -btConeTwistConstraint* btWorldImporter::createConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame) +btConeTwistConstraint* btWorldImporter::createConeTwistConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame) { - btConeTwistConstraint* cone = new btConeTwistConstraint(rbA,rbB,rbAFrame,rbBFrame); + btConeTwistConstraint* cone = new btConeTwistConstraint(rbA, rbB, rbAFrame, rbBFrame); m_allocatedConstraints.push_back(cone); return cone; } -btConeTwistConstraint* btWorldImporter::createConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame) +btConeTwistConstraint* btWorldImporter::createConeTwistConstraint(btRigidBody& rbA, const btTransform& rbAFrame) { - btConeTwistConstraint* cone = new btConeTwistConstraint(rbA,rbAFrame); + btConeTwistConstraint* cone = new btConeTwistConstraint(rbA, rbAFrame); m_allocatedConstraints.push_back(cone); return cone; } - -btGeneric6DofConstraint* btWorldImporter::createGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA) +btGeneric6DofConstraint* btWorldImporter::createGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA) { - btGeneric6DofConstraint* dof = new btGeneric6DofConstraint(rbA,rbB,frameInA,frameInB,useLinearReferenceFrameA); + btGeneric6DofConstraint* dof = new btGeneric6DofConstraint(rbA, rbB, frameInA, frameInB, useLinearReferenceFrameA); m_allocatedConstraints.push_back(dof); return dof; } btGeneric6DofConstraint* btWorldImporter::createGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB) { - btGeneric6DofConstraint* dof = new btGeneric6DofConstraint(rbB,frameInB,useLinearReferenceFrameB); + btGeneric6DofConstraint* dof = new btGeneric6DofConstraint(rbB, frameInB, useLinearReferenceFrameB); m_allocatedConstraints.push_back(dof); return dof; } btGeneric6DofSpring2Constraint* btWorldImporter::createGeneric6DofSpring2Constraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, int rotateOrder) { - btGeneric6DofSpring2Constraint* dof = new btGeneric6DofSpring2Constraint(rbA,rbB,frameInA,frameInB, (RotateOrder)rotateOrder); + btGeneric6DofSpring2Constraint* dof = new btGeneric6DofSpring2Constraint(rbA, rbB, frameInA, frameInB, (RotateOrder)rotateOrder); m_allocatedConstraints.push_back(dof); return dof; } - - -btGeneric6DofSpringConstraint* btWorldImporter::createGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA) +btGeneric6DofSpringConstraint* btWorldImporter::createGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA) { - btGeneric6DofSpringConstraint* dof = new btGeneric6DofSpringConstraint(rbA,rbB,frameInA,frameInB,useLinearReferenceFrameA); + btGeneric6DofSpringConstraint* dof = new btGeneric6DofSpringConstraint(rbA, rbB, frameInA, frameInB, useLinearReferenceFrameA); m_allocatedConstraints.push_back(dof); return dof; } - -btSliderConstraint* btWorldImporter::createSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA) +btSliderConstraint* btWorldImporter::createSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA) { - btSliderConstraint* slider = new btSliderConstraint(rbA,rbB,frameInA,frameInB,useLinearReferenceFrameA); + btSliderConstraint* slider = new btSliderConstraint(rbA, rbB, frameInA, frameInB, useLinearReferenceFrameA); m_allocatedConstraints.push_back(slider); return slider; } btSliderConstraint* btWorldImporter::createSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA) { - btSliderConstraint* slider = new btSliderConstraint(rbB,frameInB,useLinearReferenceFrameA); + btSliderConstraint* slider = new btSliderConstraint(rbB, frameInB, useLinearReferenceFrameA); m_allocatedConstraints.push_back(slider); return slider; } -btGearConstraint* btWorldImporter::createGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA,const btVector3& axisInB, btScalar ratio) +btGearConstraint* btWorldImporter::createGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA, const btVector3& axisInB, btScalar ratio) { - btGearConstraint* gear = new btGearConstraint(rbA,rbB,axisInA,axisInB,ratio); + btGearConstraint* gear = new btGearConstraint(rbA, rbB, axisInA, axisInB, ratio); m_allocatedConstraints.push_back(gear); return gear; } - // query for data -int btWorldImporter::getNumCollisionShapes() const +// query for data +int btWorldImporter::getNumCollisionShapes() const { return m_allocatedCollisionShapes.size(); } @@ -1948,7 +1896,7 @@ btCollisionShape* btWorldImporter::getCollisionShapeByIndex(int index) btCollisionShape* btWorldImporter::getCollisionShapeByName(const char* name) { btCollisionShape** shapePtr = m_nameShapeMap.find(name); - if (shapePtr&& *shapePtr) + if (shapePtr && *shapePtr) { return *shapePtr; } @@ -1975,15 +1923,14 @@ btTypedConstraint* btWorldImporter::getConstraintByName(const char* name) return 0; } -const char* btWorldImporter::getNameForPointer(const void* ptr) const +const char* btWorldImporter::getNameForPointer(const void* ptr) const { - const char*const * namePtr = m_objectNameMap.find(ptr); + const char* const* namePtr = m_objectNameMap.find(ptr); if (namePtr && *namePtr) return *namePtr; return 0; } - int btWorldImporter::getNumRigidBodies() const { return m_allocatedRigidBodies.size(); @@ -2007,7 +1954,7 @@ int btWorldImporter::getNumBvhs() const { return m_allocatedBvhs.size(); } - btOptimizedBvh* btWorldImporter::getBvhByIndex(int index) const +btOptimizedBvh* btWorldImporter::getBvhByIndex(int index) const { return m_allocatedBvhs[index]; } @@ -2022,10 +1969,9 @@ btTriangleInfoMap* btWorldImporter::getTriangleInfoMapByIndex(int index) const return m_allocatedTriangleInfoMaps[index]; } - -void btWorldImporter::convertRigidBodyFloat( btRigidBodyFloatData* colObjData) +void btWorldImporter::convertRigidBodyFloat(btRigidBodyFloatData* colObjData) { - btScalar mass = btScalar(colObjData->m_inverseMass? 1.f/colObjData->m_inverseMass : 0.f); + btScalar mass = btScalar(colObjData->m_inverseMass ? 1.f / colObjData->m_inverseMass : 0.f); btVector3 localInertia; localInertia.setZero(); btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionObjectData.m_collisionShape); @@ -2034,8 +1980,8 @@ void btWorldImporter::convertRigidBodyFloat( btRigidBodyFloatData* colObjData) btTransform startTransform; colObjData->m_collisionObjectData.m_worldTransform.m_origin.m_floats[3] = 0.f; startTransform.deSerializeFloat(colObjData->m_collisionObjectData.m_worldTransform); - - // startTransform.setBasis(btMatrix3x3::getIdentity()); + + // startTransform.setBasis(btMatrix3x3::getIdentity()); btCollisionShape* shape = (btCollisionShape*)*shapePtr; if (shape->isNonMoving()) { @@ -2043,13 +1989,13 @@ void btWorldImporter::convertRigidBodyFloat( btRigidBodyFloatData* colObjData) } if (mass) { - shape->calculateLocalInertia(mass,localInertia); + shape->calculateLocalInertia(mass, localInertia); } - bool isDynamic = mass!=0.f; - btRigidBody* body = createRigidBody(isDynamic,mass,startTransform,shape,colObjData->m_collisionObjectData.m_name); + bool isDynamic = mass != 0.f; + btRigidBody* body = createRigidBody(isDynamic, mass, startTransform, shape, colObjData->m_collisionObjectData.m_name); body->setFriction(colObjData->m_collisionObjectData.m_friction); body->setRestitution(colObjData->m_collisionObjectData.m_restitution); - btVector3 linearFactor,angularFactor; + btVector3 linearFactor, angularFactor; linearFactor.deSerializeFloat(colObjData->m_linearFactor); angularFactor.deSerializeFloat(colObjData->m_angularFactor); body->setLinearFactor(linearFactor); @@ -2061,20 +2007,21 @@ void btWorldImporter::convertRigidBodyFloat( btRigidBodyFloatData* colObjData) btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape; if (trimesh->getTriangleInfoMap()) { - body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); } } -#endif //USE_INTERNAL_EDGE_UTILITY - m_bodyMap.insert(colObjData,body); - } else +#endif //USE_INTERNAL_EDGE_UTILITY + m_bodyMap.insert(colObjData, body); + } + else { printf("error: no shape found\n"); } } -void btWorldImporter::convertRigidBodyDouble( btRigidBodyDoubleData* colObjData) +void btWorldImporter::convertRigidBodyDouble(btRigidBodyDoubleData* colObjData) { - btScalar mass = btScalar(colObjData->m_inverseMass? 1.f/colObjData->m_inverseMass : 0.f); + btScalar mass = btScalar(colObjData->m_inverseMass ? 1.f / colObjData->m_inverseMass : 0.f); btVector3 localInertia; localInertia.setZero(); btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionObjectData.m_collisionShape); @@ -2083,8 +2030,8 @@ void btWorldImporter::convertRigidBodyDouble( btRigidBodyDoubleData* colObjData) btTransform startTransform; colObjData->m_collisionObjectData.m_worldTransform.m_origin.m_floats[3] = 0.f; startTransform.deSerializeDouble(colObjData->m_collisionObjectData.m_worldTransform); - - // startTransform.setBasis(btMatrix3x3::getIdentity()); + + // startTransform.setBasis(btMatrix3x3::getIdentity()); btCollisionShape* shape = (btCollisionShape*)*shapePtr; if (shape->isNonMoving()) { @@ -2092,18 +2039,17 @@ void btWorldImporter::convertRigidBodyDouble( btRigidBodyDoubleData* colObjData) } if (mass) { - shape->calculateLocalInertia(mass,localInertia); + shape->calculateLocalInertia(mass, localInertia); } - bool isDynamic = mass!=0.f; - btRigidBody* body = createRigidBody(isDynamic,mass,startTransform,shape,colObjData->m_collisionObjectData.m_name); + bool isDynamic = mass != 0.f; + btRigidBody* body = createRigidBody(isDynamic, mass, startTransform, shape, colObjData->m_collisionObjectData.m_name); body->setFriction(btScalar(colObjData->m_collisionObjectData.m_friction)); body->setRestitution(btScalar(colObjData->m_collisionObjectData.m_restitution)); - btVector3 linearFactor,angularFactor; + btVector3 linearFactor, angularFactor; linearFactor.deSerializeDouble(colObjData->m_linearFactor); angularFactor.deSerializeDouble(colObjData->m_angularFactor); body->setLinearFactor(linearFactor); body->setAngularFactor(angularFactor); - #ifdef USE_INTERNAL_EDGE_UTILITY if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) @@ -2111,12 +2057,13 @@ void btWorldImporter::convertRigidBodyDouble( btRigidBodyDoubleData* colObjData) btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape; if (trimesh->getTriangleInfoMap()) { - body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); } } -#endif //USE_INTERNAL_EDGE_UTILITY - m_bodyMap.insert(colObjData,body); - } else +#endif //USE_INTERNAL_EDGE_UTILITY + m_bodyMap.insert(colObjData, body); + } + else { printf("error: no shape found\n"); } diff --git a/Extras/Serialize/BulletWorldImporter/btWorldImporter.h b/Extras/Serialize/BulletWorldImporter/btWorldImporter.h index 97c621fb5..696064ab4 100644 --- a/Extras/Serialize/BulletWorldImporter/btWorldImporter.h +++ b/Extras/Serialize/BulletWorldImporter/btWorldImporter.h @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef BT_WORLD_IMPORTER_H #define BT_WORLD_IMPORTER_H @@ -57,76 +56,73 @@ struct btRigidBodyFloatData; #define btRigidBodyData btRigidBodyDoubleData #else #define btRigidBodyData btRigidBodyFloatData -#endif//BT_USE_DOUBLE_PRECISION +#endif //BT_USE_DOUBLE_PRECISION enum btWorldImporterFlags { - eRESTORE_EXISTING_OBJECTS=1,//don't create new objects + eRESTORE_EXISTING_OBJECTS = 1, //don't create new objects }; class btWorldImporter { protected: btDynamicsWorld* m_dynamicsWorld; - + int m_verboseMode; int m_importerFlags; - btAlignedObjectArray m_allocatedCollisionShapes; + btAlignedObjectArray m_allocatedCollisionShapes; btAlignedObjectArray m_allocatedRigidBodies; btAlignedObjectArray m_allocatedConstraints; - btAlignedObjectArray m_allocatedBvhs; + btAlignedObjectArray m_allocatedBvhs; btAlignedObjectArray m_allocatedTriangleInfoMaps; btAlignedObjectArray m_allocatedTriangleIndexArrays; btAlignedObjectArray m_allocatedbtStridingMeshInterfaceDatas; - btAlignedObjectArray m_allocatedNames; + btAlignedObjectArray m_allocatedNames; - btAlignedObjectArray m_indexArrays; - btAlignedObjectArray m_shortIndexArrays; - btAlignedObjectArray m_charIndexArrays; + btAlignedObjectArray m_indexArrays; + btAlignedObjectArray m_shortIndexArrays; + btAlignedObjectArray m_charIndexArrays; - btAlignedObjectArray m_floatVertexArrays; - btAlignedObjectArray m_doubleVertexArrays; + btAlignedObjectArray m_floatVertexArrays; + btAlignedObjectArray m_doubleVertexArrays; + btHashMap m_bvhMap; + btHashMap m_timMap; - btHashMap m_bvhMap; - btHashMap m_timMap; - - btHashMap m_nameShapeMap; - btHashMap m_nameBodyMap; - btHashMap m_nameConstraintMap; - btHashMap m_objectNameMap; - - btHashMap m_shapeMap; - btHashMap m_bodyMap; + btHashMap m_nameShapeMap; + btHashMap m_nameBodyMap; + btHashMap m_nameConstraintMap; + btHashMap m_objectNameMap; + btHashMap m_shapeMap; + btHashMap m_bodyMap; //methods static btRigidBody& getFixedBody(); - char* duplicateName(const char* name); + char* duplicateName(const char* name); - btCollisionShape* convertCollisionShape( btCollisionShapeData* shapeData ); - - void convertConstraintBackwardsCompatible281(btTypedConstraintData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion); - void convertConstraintFloat(btTypedConstraintFloatData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion); - void convertConstraintDouble(btTypedConstraintDoubleData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion); - void convertRigidBodyFloat(btRigidBodyFloatData* colObjData); - void convertRigidBodyDouble( btRigidBodyDoubleData* colObjData); + btCollisionShape* convertCollisionShape(btCollisionShapeData* shapeData); + + void convertConstraintBackwardsCompatible281(btTypedConstraintData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion); + void convertConstraintFloat(btTypedConstraintFloatData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion); + void convertConstraintDouble(btTypedConstraintDoubleData* constraintData, btRigidBody* rbA, btRigidBody* rbB, int fileVersion); + void convertRigidBodyFloat(btRigidBodyFloatData* colObjData); + void convertRigidBodyDouble(btRigidBodyDoubleData* colObjData); public: - btWorldImporter(btDynamicsWorld* world); - + virtual ~btWorldImporter(); - ///delete all memory collision shapes, rigid bodies, constraints etc. allocated during the load. + ///delete all memory collision shapes, rigid bodies, constraints etc. allocated during the load. ///make sure you don't use the dynamics world containing objects after you call this method virtual void deleteAllData(); - void setVerboseMode(int verboseMode) + void setVerboseMode(int verboseMode) { m_verboseMode = verboseMode; } @@ -136,7 +132,7 @@ public: return m_verboseMode; } - void setImporterFlags(int importerFlags) + void setImporterFlags(int importerFlags) { m_importerFlags = importerFlags; } @@ -146,87 +142,80 @@ public: return m_importerFlags; } - - - // query for data - int getNumCollisionShapes() const; + // query for data + int getNumCollisionShapes() const; btCollisionShape* getCollisionShapeByIndex(int index); int getNumRigidBodies() const; btCollisionObject* getRigidBodyByIndex(int index) const; int getNumConstraints() const; btTypedConstraint* getConstraintByIndex(int index) const; int getNumBvhs() const; - btOptimizedBvh* getBvhByIndex(int index) const; + btOptimizedBvh* getBvhByIndex(int index) const; int getNumTriangleInfoMaps() const; btTriangleInfoMap* getTriangleInfoMapByIndex(int index) const; - + // queris involving named objects btCollisionShape* getCollisionShapeByName(const char* name); btRigidBody* getRigidBodyByName(const char* name); btTypedConstraint* getConstraintByName(const char* name); - const char* getNameForPointer(const void* ptr) const; + const char* getNameForPointer(const void* ptr) const; ///those virtuals are called by load and can be overridden by the user - virtual void setDynamicsWorldInfo(const btVector3& gravity, const btContactSolverInfo& solverInfo); + virtual void setDynamicsWorldInfo(const btVector3& gravity, const btContactSolverInfo& solverInfo); //bodies - virtual btRigidBody* createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform, btCollisionShape* shape,const char* bodyName); - virtual btCollisionObject* createCollisionObject( const btTransform& startTransform, btCollisionShape* shape,const char* bodyName); + virtual btRigidBody* createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform, btCollisionShape* shape, const char* bodyName); + virtual btCollisionObject* createCollisionObject(const btTransform& startTransform, btCollisionShape* shape, const char* bodyName); ///shapes - virtual btCollisionShape* createPlaneShape(const btVector3& planeNormal,btScalar planeConstant); + virtual btCollisionShape* createPlaneShape(const btVector3& planeNormal, btScalar planeConstant); virtual btCollisionShape* createBoxShape(const btVector3& halfExtents); virtual btCollisionShape* createSphereShape(btScalar radius); virtual btCollisionShape* createCapsuleShapeX(btScalar radius, btScalar height); virtual btCollisionShape* createCapsuleShapeY(btScalar radius, btScalar height); virtual btCollisionShape* createCapsuleShapeZ(btScalar radius, btScalar height); - - virtual btCollisionShape* createCylinderShapeX(btScalar radius,btScalar height); - virtual btCollisionShape* createCylinderShapeY(btScalar radius,btScalar height); - virtual btCollisionShape* createCylinderShapeZ(btScalar radius,btScalar height); - virtual btCollisionShape* createConeShapeX(btScalar radius,btScalar height); - virtual btCollisionShape* createConeShapeY(btScalar radius,btScalar height); - virtual btCollisionShape* createConeShapeZ(btScalar radius,btScalar height); - virtual class btTriangleIndexVertexArray* createTriangleMeshContainer(); - virtual btBvhTriangleMeshShape* createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh); + + virtual btCollisionShape* createCylinderShapeX(btScalar radius, btScalar height); + virtual btCollisionShape* createCylinderShapeY(btScalar radius, btScalar height); + virtual btCollisionShape* createCylinderShapeZ(btScalar radius, btScalar height); + virtual btCollisionShape* createConeShapeX(btScalar radius, btScalar height); + virtual btCollisionShape* createConeShapeY(btScalar radius, btScalar height); + virtual btCollisionShape* createConeShapeZ(btScalar radius, btScalar height); + virtual class btTriangleIndexVertexArray* createTriangleMeshContainer(); + virtual btBvhTriangleMeshShape* createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh); virtual btCollisionShape* createConvexTriangleMeshShape(btStridingMeshInterface* trimesh); virtual btGImpactMeshShape* createGimpactShape(btStridingMeshInterface* trimesh); virtual btStridingMeshInterfaceData* createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData); virtual class btConvexHullShape* createConvexHullShape(); virtual class btCompoundShape* createCompoundShape(); - virtual class btScaledBvhTriangleMeshShape* createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape,const btVector3& localScalingbtBvhTriangleMeshShape); + virtual class btScaledBvhTriangleMeshShape* createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape, const btVector3& localScalingbtBvhTriangleMeshShape); - virtual class btMultiSphereShape* createMultiSphereShape(const btVector3* positions,const btScalar* radi,int numSpheres); + virtual class btMultiSphereShape* createMultiSphereShape(const btVector3* positions, const btScalar* radi, int numSpheres); virtual btTriangleIndexVertexArray* createMeshInterface(btStridingMeshInterfaceData& meshData); ///acceleration and connectivity structures - virtual btOptimizedBvh* createOptimizedBvh(); + virtual btOptimizedBvh* createOptimizedBvh(); virtual btTriangleInfoMap* createTriangleInfoMap(); ///constraints - virtual btPoint2PointConstraint* createPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB); - virtual btPoint2PointConstraint* createPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA); - virtual btHingeConstraint* createHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA=false); - virtual btHingeConstraint* createHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA=false); - virtual btConeTwistConstraint* createConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame); - virtual btConeTwistConstraint* createConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame); - virtual btGeneric6DofConstraint* createGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA); - virtual btGeneric6DofConstraint* createGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB); - virtual btGeneric6DofSpringConstraint* createGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA); - virtual btGeneric6DofSpring2Constraint* createGeneric6DofSpring2Constraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, int rotateOrder ); - - virtual btSliderConstraint* createSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA); - virtual btSliderConstraint* createSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA); - virtual btGearConstraint* createGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA,const btVector3& axisInB, btScalar ratio); - - - + virtual btPoint2PointConstraint* createPoint2PointConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& pivotInA, const btVector3& pivotInB); + virtual btPoint2PointConstraint* createPoint2PointConstraint(btRigidBody& rbA, const btVector3& pivotInA); + virtual btHingeConstraint* createHingeConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false); + virtual btHingeConstraint* createHingeConstraint(btRigidBody& rbA, const btTransform& rbAFrame, bool useReferenceFrameA = false); + virtual btConeTwistConstraint* createConeTwistConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame); + virtual btConeTwistConstraint* createConeTwistConstraint(btRigidBody& rbA, const btTransform& rbAFrame); + virtual btGeneric6DofConstraint* createGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA); + virtual btGeneric6DofConstraint* createGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB); + virtual btGeneric6DofSpringConstraint* createGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA); + virtual btGeneric6DofSpring2Constraint* createGeneric6DofSpring2Constraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, int rotateOrder); + virtual btSliderConstraint* createSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA); + virtual btSliderConstraint* createSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA); + virtual btGearConstraint* createGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA, const btVector3& axisInB, btScalar ratio); }; - -#endif //BT_WORLD_IMPORTER_H \ No newline at end of file +#endif //BT_WORLD_IMPORTER_H \ No newline at end of file diff --git a/Extras/Serialize/BulletXmlWorldImporter/btBulletXmlWorldImporter.cpp b/Extras/Serialize/BulletXmlWorldImporter/btBulletXmlWorldImporter.cpp index 51a6f5c23..17b144024 100644 --- a/Extras/Serialize/BulletXmlWorldImporter/btBulletXmlWorldImporter.cpp +++ b/Extras/Serialize/BulletXmlWorldImporter/btBulletXmlWorldImporter.cpp @@ -24,23 +24,20 @@ struct MyLocalCaster void* m_ptr; int m_int; MyLocalCaster() - :m_ptr(0) + : m_ptr(0) { } }; - btBulletXmlWorldImporter::btBulletXmlWorldImporter(btDynamicsWorld* world) - :btWorldImporter(world), - m_fileVersion(-1), - m_fileOk(false) + : btWorldImporter(world), + m_fileVersion(-1), + m_fileOk(false) { - } btBulletXmlWorldImporter::~btBulletXmlWorldImporter() { - } #if 0 @@ -61,19 +58,19 @@ static int get_double_attribute_by_name(const XMLElement* pElement, const char* } #endif -static int get_int_attribute_by_name(const XMLElement* pElement, const char* attribName,int* value) +static int get_int_attribute_by_name(const XMLElement* pElement, const char* attribName, int* value) { - if ( !pElement ) + if (!pElement) return 0; - const XMLAttribute* pAttrib=pElement->FirstAttribute(); + const XMLAttribute* pAttrib = pElement->FirstAttribute(); while (pAttrib) { - if (!strcmp(pAttrib->Name(),attribName)) - if (pAttrib->QueryIntValue(value)==XML_SUCCESS) + if (!strcmp(pAttrib->Name(), attribName)) + if (pAttrib->QueryIntValue(value) == XML_SUCCESS) return 1; -// if (pAttrib->QueryDoubleValue(&dval)==TIXML_SUCCESS) printf( " d=%1.1f", dval); - pAttrib=pAttrib->Next(); + // if (pAttrib->QueryDoubleValue(&dval)==TIXML_SUCCESS) printf( " d=%1.1f", dval); + pAttrib = pAttrib->Next(); } return 0; } @@ -82,13 +79,12 @@ void stringToFloatArray(const std::string& string, btAlignedObjectArray& { btAlignedObjectArray pieces; - bullet_utils::split( pieces, string, " "); - for ( int i = 0; i < pieces.size(); ++i) + bullet_utils::split(pieces, string, " "); + for (int i = 0; i < pieces.size(); ++i) { - btAssert(pieces[i]!=""); - floats.push_back((float)atof(pieces[i].c_str())); - } - + btAssert(pieces[i] != ""); + floats.push_back((float)atof(pieces[i].c_str())); + } } static btVector3FloatData TextToVector3Data(const char* txt) @@ -96,7 +92,7 @@ static btVector3FloatData TextToVector3Data(const char* txt) btAssert(txt); btAlignedObjectArray floats; stringToFloatArray(txt, floats); - btAssert(floats.size()==4); + btAssert(floats.size() == 4); btVector3FloatData vec4; vec4.m_floats[0] = floats[0]; @@ -106,145 +102,137 @@ static btVector3FloatData TextToVector3Data(const char* txt) return vec4; } -void btBulletXmlWorldImporter::deSerializeVector3FloatData(XMLNode* pParent,btAlignedObjectArray& vectors) +void btBulletXmlWorldImporter::deSerializeVector3FloatData(XMLNode* pParent, btAlignedObjectArray& vectors) { XMLNode* flNode = pParent->FirstChildElement("m_floats"); btAssert(flNode); while (flNode && flNode->FirstChildElement()) { XMLText* pText = flNode->FirstChildElement()->ToText(); -// printf("value = %s\n",pText->Value()); + // printf("value = %s\n",pText->Value()); btVector3FloatData vec4 = TextToVector3Data(pText->Value()); vectors.push_back(vec4); flNode = flNode->NextSibling(); } - } +#define SET_INT_VALUE(xmlnode, targetdata, argname) \ + btAssert((xmlnode)->FirstChildElement(#argname) && (xmlnode)->FirstChildElement(#argname)->ToElement()); \ + if ((xmlnode)->FirstChildElement(#argname) && (xmlnode)->FirstChildElement(#argname)->ToElement()) \ + (targetdata)->argname = (int)atof(xmlnode->FirstChildElement(#argname)->ToElement()->GetText()); -#define SET_INT_VALUE(xmlnode, targetdata, argname) \ - btAssert((xmlnode)->FirstChildElement(#argname) && (xmlnode)->FirstChildElement(#argname)->ToElement());\ - if ((xmlnode)->FirstChildElement(#argname) && (xmlnode)->FirstChildElement(#argname)->ToElement())\ - (targetdata)->argname= (int)atof(xmlnode->FirstChildElement(#argname)->ToElement()->GetText()); - - -#define SET_FLOAT_VALUE(xmlnode, targetdata, argname) \ - btAssert((xmlnode)->FirstChildElement(#argname) && (xmlnode)->FirstChildElement(#argname)->ToElement());\ - if ((xmlnode)->FirstChildElement(#argname) && (xmlnode)->FirstChildElement(#argname)->ToElement())\ - (targetdata)->argname= (float)atof(xmlnode->FirstChildElement(#argname)->ToElement()->GetText()); - +#define SET_FLOAT_VALUE(xmlnode, targetdata, argname) \ + btAssert((xmlnode)->FirstChildElement(#argname) && (xmlnode)->FirstChildElement(#argname)->ToElement()); \ + if ((xmlnode)->FirstChildElement(#argname) && (xmlnode)->FirstChildElement(#argname)->ToElement()) \ + (targetdata)->argname = (float)atof(xmlnode->FirstChildElement(#argname)->ToElement()->GetText()); #define SET_POINTER_VALUE(xmlnode, targetdata, argname, pointertype) \ - {\ - XMLNode* node = xmlnode->FirstChildElement(#argname);\ - btAssert(node);\ - if (node)\ - {\ - const char* txt = (node)->ToElement()->GetText();\ - MyLocalCaster cast;\ - cast.m_int = (int) atof(txt);\ - (targetdata).argname= (pointertype)cast.m_ptr;\ - }\ + { \ + XMLNode* node = xmlnode->FirstChildElement(#argname); \ + btAssert(node); \ + if (node) \ + { \ + const char* txt = (node)->ToElement()->GetText(); \ + MyLocalCaster cast; \ + cast.m_int = (int)atof(txt); \ + (targetdata).argname = (pointertype)cast.m_ptr; \ + } \ } -#define SET_VECTOR4_VALUE(xmlnode, targetdata, argname) \ - {\ - XMLNode* flNode = xmlnode->FirstChildElement(#argname);\ - btAssert(flNode);\ - if (flNode && flNode->FirstChildElement())\ - {\ - const char* txt= flNode->FirstChildElement()->ToElement()->GetText();\ - btVector3FloatData vec4 = TextToVector3Data(txt);\ - (targetdata)->argname.m_floats[0] = vec4.m_floats[0];\ - (targetdata)->argname.m_floats[1] = vec4.m_floats[1];\ - (targetdata)->argname.m_floats[2] = vec4.m_floats[2];\ - (targetdata)->argname.m_floats[3] = vec4.m_floats[3];\ - }\ +#define SET_VECTOR4_VALUE(xmlnode, targetdata, argname) \ + { \ + XMLNode* flNode = xmlnode->FirstChildElement(#argname); \ + btAssert(flNode); \ + if (flNode && flNode->FirstChildElement()) \ + { \ + const char* txt = flNode->FirstChildElement()->ToElement()->GetText(); \ + btVector3FloatData vec4 = TextToVector3Data(txt); \ + (targetdata)->argname.m_floats[0] = vec4.m_floats[0]; \ + (targetdata)->argname.m_floats[1] = vec4.m_floats[1]; \ + (targetdata)->argname.m_floats[2] = vec4.m_floats[2]; \ + (targetdata)->argname.m_floats[3] = vec4.m_floats[3]; \ + } \ } +#define SET_MATRIX33_VALUE(n, targetdata, argname) \ + { \ + XMLNode* xmlnode = n->FirstChildElement(#argname); \ + btAssert(xmlnode); \ + if (xmlnode) \ + { \ + XMLNode* eleNode = xmlnode->FirstChildElement("m_el"); \ + btAssert(eleNode); \ + if (eleNode && eleNode->FirstChildElement()) \ + { \ + const char* txt = eleNode->FirstChildElement()->ToElement()->GetText(); \ + btVector3FloatData vec4 = TextToVector3Data(txt); \ + (targetdata)->argname.m_el[0].m_floats[0] = vec4.m_floats[0]; \ + (targetdata)->argname.m_el[0].m_floats[1] = vec4.m_floats[1]; \ + (targetdata)->argname.m_el[0].m_floats[2] = vec4.m_floats[2]; \ + (targetdata)->argname.m_el[0].m_floats[3] = vec4.m_floats[3]; \ + \ + XMLNode* n1 = eleNode->FirstChildElement()->NextSibling(); \ + btAssert(n1); \ + if (n1) \ + { \ + const char* txt = n1->ToElement()->GetText(); \ + btVector3FloatData vec4 = TextToVector3Data(txt); \ + (targetdata)->argname.m_el[1].m_floats[0] = vec4.m_floats[0]; \ + (targetdata)->argname.m_el[1].m_floats[1] = vec4.m_floats[1]; \ + (targetdata)->argname.m_el[1].m_floats[2] = vec4.m_floats[2]; \ + (targetdata)->argname.m_el[1].m_floats[3] = vec4.m_floats[3]; \ + \ + XMLNode* n2 = n1->NextSibling(); \ + btAssert(n2); \ + if (n2) \ + { \ + const char* txt = n2->ToElement()->GetText(); \ + btVector3FloatData vec4 = TextToVector3Data(txt); \ + (targetdata)->argname.m_el[2].m_floats[0] = vec4.m_floats[0]; \ + (targetdata)->argname.m_el[2].m_floats[1] = vec4.m_floats[1]; \ + (targetdata)->argname.m_el[2].m_floats[2] = vec4.m_floats[2]; \ + (targetdata)->argname.m_el[2].m_floats[3] = vec4.m_floats[3]; \ + } \ + } \ + } \ + } \ + } -#define SET_MATRIX33_VALUE(n, targetdata, argname) \ -{\ - XMLNode* xmlnode = n->FirstChildElement(#argname);\ - btAssert(xmlnode);\ - if (xmlnode)\ - {\ - XMLNode* eleNode = xmlnode->FirstChildElement("m_el");\ - btAssert(eleNode);\ - if (eleNode&& eleNode->FirstChildElement())\ - {\ - const char* txt= eleNode->FirstChildElement()->ToElement()->GetText();\ - btVector3FloatData vec4 = TextToVector3Data(txt);\ - (targetdata)->argname.m_el[0].m_floats[0] = vec4.m_floats[0];\ - (targetdata)->argname.m_el[0].m_floats[1] = vec4.m_floats[1];\ - (targetdata)->argname.m_el[0].m_floats[2] = vec4.m_floats[2];\ - (targetdata)->argname.m_el[0].m_floats[3] = vec4.m_floats[3];\ - \ - XMLNode* n1 = eleNode->FirstChildElement()->NextSibling();\ - btAssert(n1);\ - if (n1)\ - {\ - const char* txt= n1->ToElement()->GetText();\ - btVector3FloatData vec4 = TextToVector3Data(txt);\ - (targetdata)->argname.m_el[1].m_floats[0] = vec4.m_floats[0];\ - (targetdata)->argname.m_el[1].m_floats[1] = vec4.m_floats[1];\ - (targetdata)->argname.m_el[1].m_floats[2] = vec4.m_floats[2];\ - (targetdata)->argname.m_el[1].m_floats[3] = vec4.m_floats[3];\ - \ - XMLNode* n2 = n1->NextSibling();\ - btAssert(n2);\ - if (n2)\ - {\ - const char* txt= n2->ToElement()->GetText();\ - btVector3FloatData vec4 = TextToVector3Data(txt);\ - (targetdata)->argname.m_el[2].m_floats[0] = vec4.m_floats[0];\ - (targetdata)->argname.m_el[2].m_floats[1] = vec4.m_floats[1];\ - (targetdata)->argname.m_el[2].m_floats[2] = vec4.m_floats[2];\ - (targetdata)->argname.m_el[2].m_floats[3] = vec4.m_floats[3];\ - }\ - }\ - }\ - }\ -}\ - -#define SET_TRANSFORM_VALUE(n, targetdata, argname) \ -{\ - XMLNode* trNode = n->FirstChildElement(#argname);\ - btAssert(trNode);\ - if (trNode)\ - {\ - SET_VECTOR4_VALUE(trNode,&(targetdata)->argname,m_origin)\ - SET_MATRIX33_VALUE(trNode, &(targetdata)->argname,m_basis)\ - }\ -}\ - +#define SET_TRANSFORM_VALUE(n, targetdata, argname) \ + { \ + XMLNode* trNode = n->FirstChildElement(#argname); \ + btAssert(trNode); \ + if (trNode) \ + { \ + SET_VECTOR4_VALUE(trNode, &(targetdata)->argname, m_origin) \ + SET_MATRIX33_VALUE(trNode, &(targetdata)->argname, m_basis) \ + } \ + } void btBulletXmlWorldImporter::deSerializeCollisionShapeData(XMLNode* pParent, btCollisionShapeData* colShapeData) { - SET_INT_VALUE(pParent,colShapeData,m_shapeType) - colShapeData->m_name = 0; + SET_INT_VALUE(pParent, colShapeData, m_shapeType) + colShapeData->m_name = 0; } - - void btBulletXmlWorldImporter::deSerializeConvexHullShapeData(XMLNode* pParent) { MyLocalCaster cast; - get_int_attribute_by_name(pParent->ToElement(),"pointer",&cast.m_int); - + get_int_attribute_by_name(pParent->ToElement(), "pointer", &cast.m_int); + btConvexHullShapeData* convexHullData = (btConvexHullShapeData*)btAlignedAlloc(sizeof(btConvexHullShapeData), 16); XMLNode* xmlConvexInt = pParent->FirstChildElement("m_convexInternalShapeData"); btAssert(xmlConvexInt); - XMLNode* xmlColShape = xmlConvexInt ->FirstChildElement("m_collisionShapeData"); + XMLNode* xmlColShape = xmlConvexInt->FirstChildElement("m_collisionShapeData"); btAssert(xmlColShape); - deSerializeCollisionShapeData(xmlColShape,&convexHullData->m_convexInternalShapeData.m_collisionShapeData); - - SET_FLOAT_VALUE(xmlConvexInt,&convexHullData->m_convexInternalShapeData,m_collisionMargin) - SET_VECTOR4_VALUE(xmlConvexInt,&convexHullData->m_convexInternalShapeData,m_localScaling) - SET_VECTOR4_VALUE(xmlConvexInt,&convexHullData->m_convexInternalShapeData,m_implicitShapeDimensions) + deSerializeCollisionShapeData(xmlColShape, &convexHullData->m_convexInternalShapeData.m_collisionShapeData); + + SET_FLOAT_VALUE(xmlConvexInt, &convexHullData->m_convexInternalShapeData, m_collisionMargin) + SET_VECTOR4_VALUE(xmlConvexInt, &convexHullData->m_convexInternalShapeData, m_localScaling) + SET_VECTOR4_VALUE(xmlConvexInt, &convexHullData->m_convexInternalShapeData, m_implicitShapeDimensions) //convexHullData->m_unscaledPointsFloatPtr //#define SET_POINTER_VALUE(xmlnode, targetdata, argname, pointertype) @@ -256,23 +244,23 @@ void btBulletXmlWorldImporter::deSerializeConvexHullShapeData(XMLNode* pParent) { const char* txt = (node)->ToElement()->GetText(); MyLocalCaster cast; - cast.m_int = (int) atof(txt); - (*convexHullData).m_unscaledPointsFloatPtr= (btVector3FloatData*) cast.m_ptr; + cast.m_int = (int)atof(txt); + (*convexHullData).m_unscaledPointsFloatPtr = (btVector3FloatData*)cast.m_ptr; } } - - SET_POINTER_VALUE(pParent,*convexHullData,m_unscaledPointsFloatPtr,btVector3FloatData*); - SET_POINTER_VALUE(pParent,*convexHullData,m_unscaledPointsDoublePtr,btVector3DoubleData*); - SET_INT_VALUE(pParent,convexHullData,m_numUnscaledPoints); + + SET_POINTER_VALUE(pParent, *convexHullData, m_unscaledPointsFloatPtr, btVector3FloatData*); + SET_POINTER_VALUE(pParent, *convexHullData, m_unscaledPointsDoublePtr, btVector3DoubleData*); + SET_INT_VALUE(pParent, convexHullData, m_numUnscaledPoints); m_collisionShapeData.push_back((btCollisionShapeData*)convexHullData); - m_pointerLookup.insert(cast.m_ptr,convexHullData); + m_pointerLookup.insert(cast.m_ptr, convexHullData); } void btBulletXmlWorldImporter::deSerializeCompoundShapeChildData(XMLNode* pParent) { MyLocalCaster cast; - get_int_attribute_by_name(pParent->ToElement(),"pointer",&cast.m_int); + get_int_attribute_by_name(pParent->ToElement(), "pointer", &cast.m_int); int numChildren = 0; btAlignedObjectArray* compoundChildArrayPtr = new btAlignedObjectArray; @@ -282,22 +270,22 @@ void btBulletXmlWorldImporter::deSerializeCompoundShapeChildData(XMLNode* pParen XMLNode* marginNode = pParent->FirstChildElement("m_childMargin"); XMLNode* childTypeNode = pParent->FirstChildElement("m_childShapeType"); - int i=0; + int i = 0; while (transNode && colShapeNode && marginNode && childTypeNode) { compoundChildArrayPtr->expandNonInitializing(); - SET_VECTOR4_VALUE (transNode,&compoundChildArrayPtr->at(i).m_transform,m_origin) - SET_MATRIX33_VALUE(transNode,&compoundChildArrayPtr->at(i).m_transform,m_basis) + SET_VECTOR4_VALUE(transNode, &compoundChildArrayPtr->at(i).m_transform, m_origin) + SET_MATRIX33_VALUE(transNode, &compoundChildArrayPtr->at(i).m_transform, m_basis) const char* txt = (colShapeNode)->ToElement()->GetText(); MyLocalCaster cast; - cast.m_int = (int) atof(txt); - compoundChildArrayPtr->at(i).m_childShape = (btCollisionShapeData*) cast.m_ptr; - + cast.m_int = (int)atof(txt); + compoundChildArrayPtr->at(i).m_childShape = (btCollisionShapeData*)cast.m_ptr; + btAssert(childTypeNode->ToElement()); if (childTypeNode->ToElement()) { - compoundChildArrayPtr->at(i).m_childShapeType = (int)atof(childTypeNode->ToElement()->GetText()); + compoundChildArrayPtr->at(i).m_childShapeType = (int)atof(childTypeNode->ToElement()->GetText()); } btAssert(marginNode->ToElement()); @@ -312,9 +300,8 @@ void btBulletXmlWorldImporter::deSerializeCompoundShapeChildData(XMLNode* pParen childTypeNode = childTypeNode->NextSiblingElement("m_childShapeType"); i++; } - + numChildren = i; - } btAssert(numChildren); @@ -322,66 +309,62 @@ void btBulletXmlWorldImporter::deSerializeCompoundShapeChildData(XMLNode* pParen { m_compoundShapeChildDataArrays.push_back(compoundChildArrayPtr); btCompoundShapeChildData* cd = &compoundChildArrayPtr->at(0); - m_pointerLookup.insert(cast.m_ptr,cd); + m_pointerLookup.insert(cast.m_ptr, cd); } - } void btBulletXmlWorldImporter::deSerializeCompoundShapeData(XMLNode* pParent) { MyLocalCaster cast; - get_int_attribute_by_name(pParent->ToElement(),"pointer",&cast.m_int); + get_int_attribute_by_name(pParent->ToElement(), "pointer", &cast.m_int); - btCompoundShapeData* compoundData = (btCompoundShapeData*) btAlignedAlloc(sizeof(btCompoundShapeData),16); + btCompoundShapeData* compoundData = (btCompoundShapeData*)btAlignedAlloc(sizeof(btCompoundShapeData), 16); - XMLNode* xmlColShape = pParent ->FirstChildElement("m_collisionShapeData"); + XMLNode* xmlColShape = pParent->FirstChildElement("m_collisionShapeData"); btAssert(xmlColShape); - deSerializeCollisionShapeData(xmlColShape,&compoundData->m_collisionShapeData); - - SET_INT_VALUE(pParent, compoundData,m_numChildShapes); + deSerializeCollisionShapeData(xmlColShape, &compoundData->m_collisionShapeData); + + SET_INT_VALUE(pParent, compoundData, m_numChildShapes); XMLNode* xmlShapeData = pParent->FirstChildElement("m_collisionShapeData"); - btAssert(xmlShapeData ); + btAssert(xmlShapeData); { - XMLNode* node = pParent->FirstChildElement("m_childShapePtr");\ + XMLNode* node = pParent->FirstChildElement("m_childShapePtr"); btAssert(node); while (node) { const char* txt = (node)->ToElement()->GetText(); MyLocalCaster cast; - cast.m_int = (int) atof(txt); - compoundData->m_childShapePtr = (btCompoundShapeChildData*) cast.m_ptr; + cast.m_int = (int)atof(txt); + compoundData->m_childShapePtr = (btCompoundShapeChildData*)cast.m_ptr; node = node->NextSiblingElement("m_childShapePtr"); } //SET_POINTER_VALUE(xmlColShape, *compoundData,m_childShapePtr,btCompoundShapeChildData*); - } - SET_FLOAT_VALUE(pParent, compoundData,m_collisionMargin); + SET_FLOAT_VALUE(pParent, compoundData, m_collisionMargin); m_collisionShapeData.push_back((btCollisionShapeData*)compoundData); - m_pointerLookup.insert(cast.m_ptr,compoundData); - + m_pointerLookup.insert(cast.m_ptr, compoundData); } void btBulletXmlWorldImporter::deSerializeStaticPlaneShapeData(XMLNode* pParent) { MyLocalCaster cast; - get_int_attribute_by_name(pParent->ToElement(),"pointer",&cast.m_int); + get_int_attribute_by_name(pParent->ToElement(), "pointer", &cast.m_int); - btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*) btAlignedAlloc(sizeof(btStaticPlaneShapeData),16); + btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*)btAlignedAlloc(sizeof(btStaticPlaneShapeData), 16); XMLNode* xmlShapeData = pParent->FirstChildElement("m_collisionShapeData"); - btAssert(xmlShapeData ); - deSerializeCollisionShapeData(xmlShapeData,&planeData->m_collisionShapeData); + btAssert(xmlShapeData); + deSerializeCollisionShapeData(xmlShapeData, &planeData->m_collisionShapeData); - SET_VECTOR4_VALUE(pParent, planeData,m_localScaling); - SET_VECTOR4_VALUE(pParent, planeData,m_planeNormal); - SET_FLOAT_VALUE(pParent, planeData,m_planeConstant); + SET_VECTOR4_VALUE(pParent, planeData, m_localScaling); + SET_VECTOR4_VALUE(pParent, planeData, m_planeNormal); + SET_FLOAT_VALUE(pParent, planeData, m_planeConstant); m_collisionShapeData.push_back((btCollisionShapeData*)planeData); - m_pointerLookup.insert(cast.m_ptr,planeData); - + m_pointerLookup.insert(cast.m_ptr, planeData); } void btBulletXmlWorldImporter::deSerializeDynamicsWorldData(XMLNode* pParent) @@ -397,25 +380,22 @@ void btBulletXmlWorldImporter::deSerializeDynamicsWorldData(XMLNode* pParent) void btBulletXmlWorldImporter::deSerializeConvexInternalShapeData(XMLNode* pParent) { MyLocalCaster cast; - get_int_attribute_by_name(pParent->ToElement(),"pointer",&cast.m_int); - + get_int_attribute_by_name(pParent->ToElement(), "pointer", &cast.m_int); - btConvexInternalShapeData* convexShape = (btConvexInternalShapeData*) btAlignedAlloc(sizeof(btConvexInternalShapeData),16); - memset(convexShape,0,sizeof(btConvexInternalShapeData)); + btConvexInternalShapeData* convexShape = (btConvexInternalShapeData*)btAlignedAlloc(sizeof(btConvexInternalShapeData), 16); + memset(convexShape, 0, sizeof(btConvexInternalShapeData)); XMLNode* xmlShapeData = pParent->FirstChildElement("m_collisionShapeData"); - btAssert(xmlShapeData ); + btAssert(xmlShapeData); - deSerializeCollisionShapeData(xmlShapeData,&convexShape->m_collisionShapeData); + deSerializeCollisionShapeData(xmlShapeData, &convexShape->m_collisionShapeData); - - SET_FLOAT_VALUE(pParent,convexShape,m_collisionMargin) - SET_VECTOR4_VALUE(pParent,convexShape,m_localScaling) - SET_VECTOR4_VALUE(pParent,convexShape,m_implicitShapeDimensions) + SET_FLOAT_VALUE(pParent, convexShape, m_collisionMargin) + SET_VECTOR4_VALUE(pParent, convexShape, m_localScaling) + SET_VECTOR4_VALUE(pParent, convexShape, m_implicitShapeDimensions) m_collisionShapeData.push_back((btCollisionShapeData*)convexShape); - m_pointerLookup.insert(cast.m_ptr,convexShape); - + m_pointerLookup.insert(cast.m_ptr, convexShape); } /* @@ -433,115 +413,110 @@ enum btTypedConstraintType }; */ - void btBulletXmlWorldImporter::deSerializeGeneric6DofConstraintData(XMLNode* pParent) { MyLocalCaster cast; - get_int_attribute_by_name(pParent->ToElement(),"pointer",&cast.m_int); - - btGeneric6DofConstraintData2* dof6Data = (btGeneric6DofConstraintData2*)btAlignedAlloc(sizeof(btGeneric6DofConstraintData2),16); + get_int_attribute_by_name(pParent->ToElement(), "pointer", &cast.m_int); + + btGeneric6DofConstraintData2* dof6Data = (btGeneric6DofConstraintData2*)btAlignedAlloc(sizeof(btGeneric6DofConstraintData2), 16); - XMLNode* n = pParent->FirstChildElement("m_typeConstraintData"); if (n) { - SET_POINTER_VALUE(n,dof6Data->m_typeConstraintData,m_rbA,btRigidBodyData*); - SET_POINTER_VALUE(n,dof6Data->m_typeConstraintData,m_rbB,btRigidBodyData*); - dof6Data->m_typeConstraintData.m_name = 0;//tbd - SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_objectType); - SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_userConstraintType); - SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_userConstraintId); - SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_needsFeedback); - SET_FLOAT_VALUE(n,&dof6Data->m_typeConstraintData,m_appliedImpulse); - SET_FLOAT_VALUE(n,&dof6Data->m_typeConstraintData,m_dbgDrawSize); - SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_disableCollisionsBetweenLinkedBodies); - SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_overrideNumSolverIterations); - SET_FLOAT_VALUE(n,&dof6Data->m_typeConstraintData,m_breakingImpulseThreshold); - SET_INT_VALUE(n,&dof6Data->m_typeConstraintData,m_isEnabled); + SET_POINTER_VALUE(n, dof6Data->m_typeConstraintData, m_rbA, btRigidBodyData*); + SET_POINTER_VALUE(n, dof6Data->m_typeConstraintData, m_rbB, btRigidBodyData*); + dof6Data->m_typeConstraintData.m_name = 0; //tbd + SET_INT_VALUE(n, &dof6Data->m_typeConstraintData, m_objectType); + SET_INT_VALUE(n, &dof6Data->m_typeConstraintData, m_userConstraintType); + SET_INT_VALUE(n, &dof6Data->m_typeConstraintData, m_userConstraintId); + SET_INT_VALUE(n, &dof6Data->m_typeConstraintData, m_needsFeedback); + SET_FLOAT_VALUE(n, &dof6Data->m_typeConstraintData, m_appliedImpulse); + SET_FLOAT_VALUE(n, &dof6Data->m_typeConstraintData, m_dbgDrawSize); + SET_INT_VALUE(n, &dof6Data->m_typeConstraintData, m_disableCollisionsBetweenLinkedBodies); + SET_INT_VALUE(n, &dof6Data->m_typeConstraintData, m_overrideNumSolverIterations); + SET_FLOAT_VALUE(n, &dof6Data->m_typeConstraintData, m_breakingImpulseThreshold); + SET_INT_VALUE(n, &dof6Data->m_typeConstraintData, m_isEnabled); + } - } - - SET_TRANSFORM_VALUE( pParent, dof6Data, m_rbAFrame); - SET_TRANSFORM_VALUE( pParent, dof6Data, m_rbBFrame); + SET_TRANSFORM_VALUE(pParent, dof6Data, m_rbAFrame); + SET_TRANSFORM_VALUE(pParent, dof6Data, m_rbBFrame); SET_VECTOR4_VALUE(pParent, dof6Data, m_linearUpperLimit); SET_VECTOR4_VALUE(pParent, dof6Data, m_linearLowerLimit); SET_VECTOR4_VALUE(pParent, dof6Data, m_angularUpperLimit); SET_VECTOR4_VALUE(pParent, dof6Data, m_angularLowerLimit); - SET_INT_VALUE(pParent, dof6Data,m_useLinearReferenceFrameA); - SET_INT_VALUE(pParent, dof6Data,m_useOffsetForConstraintFrame); - + SET_INT_VALUE(pParent, dof6Data, m_useLinearReferenceFrameA); + SET_INT_VALUE(pParent, dof6Data, m_useOffsetForConstraintFrame); + m_constraintData.push_back((btTypedConstraintData2*)dof6Data); - m_pointerLookup.insert(cast.m_ptr,dof6Data); + m_pointerLookup.insert(cast.m_ptr, dof6Data); } void btBulletXmlWorldImporter::deSerializeRigidBodyFloatData(XMLNode* pParent) { MyLocalCaster cast; - - if (!get_int_attribute_by_name(pParent->ToElement(),"pointer",&cast.m_int)) + + if (!get_int_attribute_by_name(pParent->ToElement(), "pointer", &cast.m_int)) { m_fileOk = false; return; } - - btRigidBodyData* rbData = (btRigidBodyData*)btAlignedAlloc(sizeof(btRigidBodyData),16); - + + btRigidBodyData* rbData = (btRigidBodyData*)btAlignedAlloc(sizeof(btRigidBodyData), 16); + XMLNode* n = pParent->FirstChildElement("m_collisionObjectData"); if (n) { - SET_POINTER_VALUE(n,rbData->m_collisionObjectData,m_collisionShape, void*); - SET_TRANSFORM_VALUE(n,&rbData->m_collisionObjectData,m_worldTransform); - SET_TRANSFORM_VALUE(n,&rbData->m_collisionObjectData,m_interpolationWorldTransform); - SET_VECTOR4_VALUE(n,&rbData->m_collisionObjectData,m_interpolationLinearVelocity) - SET_VECTOR4_VALUE(n,&rbData->m_collisionObjectData,m_interpolationAngularVelocity) - SET_VECTOR4_VALUE(n,&rbData->m_collisionObjectData,m_anisotropicFriction) - SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_contactProcessingThreshold); - SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_deactivationTime); - SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_friction); - SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_restitution); - SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_hitFraction); - SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_ccdSweptSphereRadius); - SET_FLOAT_VALUE(n,&rbData->m_collisionObjectData,m_ccdMotionThreshold); - SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_hasAnisotropicFriction); - SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_collisionFlags); - SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_islandTag1); - SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_companionId); - SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_activationState1); - SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_internalType); - SET_INT_VALUE(n,&rbData->m_collisionObjectData,m_checkCollideWith); + SET_POINTER_VALUE(n, rbData->m_collisionObjectData, m_collisionShape, void*); + SET_TRANSFORM_VALUE(n, &rbData->m_collisionObjectData, m_worldTransform); + SET_TRANSFORM_VALUE(n, &rbData->m_collisionObjectData, m_interpolationWorldTransform); + SET_VECTOR4_VALUE(n, &rbData->m_collisionObjectData, m_interpolationLinearVelocity) + SET_VECTOR4_VALUE(n, &rbData->m_collisionObjectData, m_interpolationAngularVelocity) + SET_VECTOR4_VALUE(n, &rbData->m_collisionObjectData, m_anisotropicFriction) + SET_FLOAT_VALUE(n, &rbData->m_collisionObjectData, m_contactProcessingThreshold); + SET_FLOAT_VALUE(n, &rbData->m_collisionObjectData, m_deactivationTime); + SET_FLOAT_VALUE(n, &rbData->m_collisionObjectData, m_friction); + SET_FLOAT_VALUE(n, &rbData->m_collisionObjectData, m_restitution); + SET_FLOAT_VALUE(n, &rbData->m_collisionObjectData, m_hitFraction); + SET_FLOAT_VALUE(n, &rbData->m_collisionObjectData, m_ccdSweptSphereRadius); + SET_FLOAT_VALUE(n, &rbData->m_collisionObjectData, m_ccdMotionThreshold); + SET_INT_VALUE(n, &rbData->m_collisionObjectData, m_hasAnisotropicFriction); + SET_INT_VALUE(n, &rbData->m_collisionObjectData, m_collisionFlags); + SET_INT_VALUE(n, &rbData->m_collisionObjectData, m_islandTag1); + SET_INT_VALUE(n, &rbData->m_collisionObjectData, m_companionId); + SET_INT_VALUE(n, &rbData->m_collisionObjectData, m_activationState1); + SET_INT_VALUE(n, &rbData->m_collisionObjectData, m_internalType); + SET_INT_VALUE(n, &rbData->m_collisionObjectData, m_checkCollideWith); } -// SET_VECTOR4_VALUE(pParent,rbData,m_linearVelocity); + // SET_VECTOR4_VALUE(pParent,rbData,m_linearVelocity); - SET_MATRIX33_VALUE(pParent,rbData,m_invInertiaTensorWorld); - - - SET_VECTOR4_VALUE(pParent,rbData,m_linearVelocity) - SET_VECTOR4_VALUE(pParent,rbData,m_angularVelocity) - SET_VECTOR4_VALUE(pParent,rbData,m_angularFactor) - SET_VECTOR4_VALUE(pParent,rbData,m_linearFactor) - SET_VECTOR4_VALUE(pParent,rbData,m_gravity) - SET_VECTOR4_VALUE(pParent,rbData,m_gravity_acceleration ) - SET_VECTOR4_VALUE(pParent,rbData,m_invInertiaLocal) - SET_VECTOR4_VALUE(pParent,rbData,m_totalTorque) - SET_VECTOR4_VALUE(pParent,rbData,m_totalForce) - SET_FLOAT_VALUE(pParent,rbData,m_inverseMass); - SET_FLOAT_VALUE(pParent,rbData,m_linearDamping); - SET_FLOAT_VALUE(pParent,rbData,m_angularDamping); - SET_FLOAT_VALUE(pParent,rbData,m_additionalDampingFactor); - SET_FLOAT_VALUE(pParent,rbData,m_additionalLinearDampingThresholdSqr); - SET_FLOAT_VALUE(pParent,rbData,m_additionalAngularDampingThresholdSqr); - SET_FLOAT_VALUE(pParent,rbData,m_additionalAngularDampingFactor); - SET_FLOAT_VALUE(pParent,rbData,m_angularSleepingThreshold); - SET_FLOAT_VALUE(pParent,rbData,m_linearSleepingThreshold); - SET_INT_VALUE(pParent,rbData,m_additionalDamping); + SET_MATRIX33_VALUE(pParent, rbData, m_invInertiaTensorWorld); + SET_VECTOR4_VALUE(pParent, rbData, m_linearVelocity) + SET_VECTOR4_VALUE(pParent, rbData, m_angularVelocity) + SET_VECTOR4_VALUE(pParent, rbData, m_angularFactor) + SET_VECTOR4_VALUE(pParent, rbData, m_linearFactor) + SET_VECTOR4_VALUE(pParent, rbData, m_gravity) + SET_VECTOR4_VALUE(pParent, rbData, m_gravity_acceleration) + SET_VECTOR4_VALUE(pParent, rbData, m_invInertiaLocal) + SET_VECTOR4_VALUE(pParent, rbData, m_totalTorque) + SET_VECTOR4_VALUE(pParent, rbData, m_totalForce) + SET_FLOAT_VALUE(pParent, rbData, m_inverseMass); + SET_FLOAT_VALUE(pParent, rbData, m_linearDamping); + SET_FLOAT_VALUE(pParent, rbData, m_angularDamping); + SET_FLOAT_VALUE(pParent, rbData, m_additionalDampingFactor); + SET_FLOAT_VALUE(pParent, rbData, m_additionalLinearDampingThresholdSqr); + SET_FLOAT_VALUE(pParent, rbData, m_additionalAngularDampingThresholdSqr); + SET_FLOAT_VALUE(pParent, rbData, m_additionalAngularDampingFactor); + SET_FLOAT_VALUE(pParent, rbData, m_angularSleepingThreshold); + SET_FLOAT_VALUE(pParent, rbData, m_linearSleepingThreshold); + SET_INT_VALUE(pParent, rbData, m_additionalDamping); m_rigidBodyData.push_back(rbData); - m_pointerLookup.insert(cast.m_ptr,rbData); - -// rbData->m_collisionObjectData.m_collisionShape = (void*) (int)atof(txt); + m_pointerLookup.insert(cast.m_ptr, rbData); + + // rbData->m_collisionObjectData.m_collisionShape = (void*) (int)atof(txt); } /* @@ -593,60 +568,59 @@ CONCAVE_SHAPES_END_HERE, MAX_BROADPHASE_COLLISION_TYPES */ -void btBulletXmlWorldImporter::fixupConstraintData(btTypedConstraintData2* tcd) +void btBulletXmlWorldImporter::fixupConstraintData(btTypedConstraintData2* tcd) { if (tcd->m_rbA) { btRigidBodyData** ptrptr = (btRigidBodyData**)m_pointerLookup.find(tcd->m_rbA); btAssert(ptrptr); - tcd->m_rbA = ptrptr? *ptrptr : 0; + tcd->m_rbA = ptrptr ? *ptrptr : 0; } if (tcd->m_rbB) { btRigidBodyData** ptrptr = (btRigidBodyData**)m_pointerLookup.find(tcd->m_rbB); btAssert(ptrptr); - tcd->m_rbB = ptrptr? *ptrptr : 0; + tcd->m_rbB = ptrptr ? *ptrptr : 0; } - } -void btBulletXmlWorldImporter::fixupCollisionDataPointers(btCollisionShapeData* shapeData) +void btBulletXmlWorldImporter::fixupCollisionDataPointers(btCollisionShapeData* shapeData) { - - switch (shapeData->m_shapeType) - { - + switch (shapeData->m_shapeType) + { case COMPOUND_SHAPE_PROXYTYPE: + { + btCompoundShapeData* compound = (btCompoundShapeData*)shapeData; + + void** cdptr = m_pointerLookup.find((void*)compound->m_childShapePtr); + btCompoundShapeChildData** c = (btCompoundShapeChildData**)cdptr; + btAssert(c); + if (c) { - btCompoundShapeData* compound = (btCompoundShapeData*) shapeData; - - void** cdptr = m_pointerLookup.find((void*)compound->m_childShapePtr); - btCompoundShapeChildData** c = (btCompoundShapeChildData**)cdptr; - btAssert(c); - if (c) - { - compound->m_childShapePtr = *c; - } else - { - compound->m_childShapePtr = 0; - } - break; + compound->m_childShapePtr = *c; } + else + { + compound->m_childShapePtr = 0; + } + break; + } case CONVEX_HULL_SHAPE_PROXYTYPE: + { + btConvexHullShapeData* convexData = (btConvexHullShapeData*)shapeData; + btVector3FloatData** ptrptr = (btVector3FloatData**)m_pointerLookup.find((void*)convexData->m_unscaledPointsFloatPtr); + btAssert(ptrptr); + if (ptrptr) { - btConvexHullShapeData* convexData = (btConvexHullShapeData*)shapeData; - btVector3FloatData** ptrptr = (btVector3FloatData**)m_pointerLookup.find((void*)convexData->m_unscaledPointsFloatPtr); - btAssert(ptrptr); - if (ptrptr) - { - convexData->m_unscaledPointsFloatPtr = *ptrptr; - } else - { - convexData->m_unscaledPointsFloatPtr = 0; - } - break; + convexData->m_unscaledPointsFloatPtr = *ptrptr; } + else + { + convexData->m_unscaledPointsFloatPtr = 0; + } + break; + } case BOX_SHAPE_PROXYTYPE: case TRIANGLE_SHAPE_PROXYTYPE: @@ -655,100 +629,98 @@ void btBulletXmlWorldImporter::fixupCollisionDataPointers(btCollisionShapeData* break; default: - { - btAssert(0); - } + { + btAssert(0); } + } } - void btBulletXmlWorldImporter::auto_serialize_root_level_children(XMLNode* pParent) { int numChildren = 0; btAssert(pParent); if (pParent) { - XMLNode*pChild; - for ( pChild = pParent->FirstChildElement(); pChild != 0; pChild = pChild->NextSibling(), numChildren++) + XMLNode* pChild; + for (pChild = pParent->FirstChildElement(); pChild != 0; pChild = pChild->NextSibling(), numChildren++) { -// printf("child Name=%s\n", pChild->Value()); - if (!strcmp(pChild->Value(),"btVector3FloatData")) + // printf("child Name=%s\n", pChild->Value()); + if (!strcmp(pChild->Value(), "btVector3FloatData")) { MyLocalCaster cast; - get_int_attribute_by_name(pChild->ToElement(),"pointer",&cast.m_int); - + get_int_attribute_by_name(pChild->ToElement(), "pointer", &cast.m_int); + btAlignedObjectArray v; - deSerializeVector3FloatData(pChild,v); + deSerializeVector3FloatData(pChild, v); int numVectors = v.size(); - btVector3FloatData* vectors= (btVector3FloatData*) btAlignedAlloc(sizeof(btVector3FloatData)*numVectors,16); - for (int i=0;iValue(),"btGeneric6DofConstraintData")) + if (!strcmp(pChild->Value(), "btGeneric6DofConstraintData")) { deSerializeGeneric6DofConstraintData(pChild); continue; } - if (!strcmp(pChild->Value(),"btStaticPlaneShapeData")) + if (!strcmp(pChild->Value(), "btStaticPlaneShapeData")) { deSerializeStaticPlaneShapeData(pChild); continue; } - if (!strcmp(pChild->Value(),"btCompoundShapeData")) + if (!strcmp(pChild->Value(), "btCompoundShapeData")) { deSerializeCompoundShapeData(pChild); continue; } - if (!strcmp(pChild->Value(),"btCompoundShapeChildData")) + if (!strcmp(pChild->Value(), "btCompoundShapeChildData")) { deSerializeCompoundShapeChildData(pChild); continue; } - if (!strcmp(pChild->Value(),"btConvexHullShapeData")) + if (!strcmp(pChild->Value(), "btConvexHullShapeData")) { deSerializeConvexHullShapeData(pChild); continue; } - if (!strcmp(pChild->Value(),"btDynamicsWorldFloatData")) + if (!strcmp(pChild->Value(), "btDynamicsWorldFloatData")) { deSerializeDynamicsWorldData(pChild); continue; } - - if (!strcmp(pChild->Value(),"btConvexInternalShapeData")) + if (!strcmp(pChild->Value(), "btConvexInternalShapeData")) { deSerializeConvexInternalShapeData(pChild); continue; } - if (!strcmp(pChild->Value(),"btRigidBodyFloatData")) + if (!strcmp(pChild->Value(), "btRigidBodyFloatData")) { deSerializeRigidBodyFloatData(pChild); continue; } //printf("Error: btBulletXmlWorldImporter doesn't support %s yet\n", pChild->Value()); - // btAssert(0); + // btAssert(0); } - } + } ///================================================================= ///fixup pointers in various places, in the right order //fixup compoundshape child data - for (int i=0;i* childDataArray = m_compoundShapeChildDataArrays[i]; - for (int c=0;csize();c++) + for (int c = 0; c < childDataArray->size(); c++) { btCompoundShapeChildData* childData = &childDataArray->at(c); btCollisionShapeData** ptrptr = (btCollisionShapeData**)m_pointerLookup[childData->m_childShape]; @@ -760,58 +732,54 @@ void btBulletXmlWorldImporter::auto_serialize_root_level_children(XMLNode* pPare } } - for (int i=0;im_collisionShapeData.size();i++) + for (int i = 0; i < this->m_collisionShapeData.size(); i++) { btCollisionShapeData* shapeData = m_collisionShapeData[i]; fixupCollisionDataPointers(shapeData); - } - + ///now fixup pointers - for (int i=0;im_collisionObjectData.m_collisionShape); //btAssert(ptrptr); rbData->m_collisionObjectData.m_broadphaseHandle = 0; rbData->m_collisionObjectData.m_rootCollisionShape = 0; - rbData->m_collisionObjectData.m_name = 0;//tbd + rbData->m_collisionObjectData.m_name = 0; //tbd if (ptrptr) { rbData->m_collisionObjectData.m_collisionShape = *ptrptr; } } - - - for (int i=0;im_collisionShapeData.size();i++) + for (int i = 0; i < this->m_collisionShapeData.size(); i++) { btCollisionShapeData* shapeData = m_collisionShapeData[i]; btCollisionShape* shape = convertCollisionShape(shapeData); if (shape) { - m_shapeMap.insert(shapeData,shape); + m_shapeMap.insert(shapeData, shape); } - if (shape&& shapeData->m_name) + if (shape && shapeData->m_name) { char* newname = duplicateName(shapeData->m_name); - m_objectNameMap.insert(shape,newname); - m_nameShapeMap.insert(newname,shape); + m_objectNameMap.insert(shape, newname); + m_nameShapeMap.insert(newname, shape); } } - for (int i=0;iFirstChildElement("bullet_physics"); + // XMLElement* root = pParent->FirstChildElement("bullet_physics"); if (pParent) { - XMLNode*pChild; - for ( pChild = pParent->FirstChildElement(); pChild != 0; pChild = pChild->NextSibling()) + XMLNode* pChild; + for (pChild = pParent->FirstChildElement(); pChild != 0; pChild = pChild->NextSibling()) { //if (pChild->Type()==XMLNode::TINYXML_ELEMENT) { -// printf("root Name=%s\n", pChild->Value()); + // printf("root Name=%s\n", pChild->Value()); auto_serialize_root_level_children(pChild); } } - } else + } + else { printf("ERROR: no bullet_physics element\n"); } } - - - bool btBulletXmlWorldImporter::loadFile(const char* fileName) { XMLDocument doc; - XMLError loadOkay = doc.LoadFile(fileName); - - if (loadOkay==XML_SUCCESS) + + if (loadOkay == XML_SUCCESS) { - if (get_int_attribute_by_name(doc.FirstChildElement()->ToElement(),"version", &m_fileVersion)) + if (get_int_attribute_by_name(doc.FirstChildElement()->ToElement(), "version", &m_fileVersion)) { - if (m_fileVersion==281) + if (m_fileVersion == 281) { m_fileOk = true; int itemcount; - get_int_attribute_by_name(doc.FirstChildElement()->ToElement(),"itemcount", &itemcount); + get_int_attribute_by_name(doc.FirstChildElement()->ToElement(), "itemcount", &itemcount); auto_serialize(&doc); return m_fileOk; - } } } return false; } - - - - diff --git a/Extras/Serialize/BulletXmlWorldImporter/btBulletXmlWorldImporter.h b/Extras/Serialize/BulletXmlWorldImporter/btBulletXmlWorldImporter.h index aabf2576a..aa88c088a 100644 --- a/Extras/Serialize/BulletXmlWorldImporter/btBulletXmlWorldImporter.h +++ b/Extras/Serialize/BulletXmlWorldImporter/btBulletXmlWorldImporter.h @@ -22,7 +22,7 @@ class btDynamicsWorld; namespace tinyxml2 { - class XMLNode; +class XMLNode; }; struct btConvexInternalShapeData; @@ -37,58 +37,53 @@ struct btRigidBodyFloatData; struct btTypedConstraintFloatData; #define btTypedConstraintData2 btTypedConstraintFloatData #define btRigidBodyData btRigidBodyFloatData -#endif//BT_USE_DOUBLE_PRECISION - +#endif //BT_USE_DOUBLE_PRECISION struct btCompoundShapeChildData; #include "LinearMath/btAlignedObjectArray.h" #include "btWorldImporter.h" - - class btBulletXmlWorldImporter : public btWorldImporter { - protected: - btAlignedObjectArray m_collisionShapeData; - btAlignedObjectArray* > m_compoundShapeChildDataArrays; - btAlignedObjectArray m_rigidBodyData; - btAlignedObjectArray m_constraintData; - btHashMap m_pointerLookup; - int m_fileVersion; - bool m_fileOk; + btAlignedObjectArray m_collisionShapeData; + btAlignedObjectArray*> m_compoundShapeChildDataArrays; + btAlignedObjectArray m_rigidBodyData; + btAlignedObjectArray m_constraintData; + btHashMap m_pointerLookup; + int m_fileVersion; + bool m_fileOk; void auto_serialize_root_level_children(tinyxml2::XMLNode* pParent); void auto_serialize(tinyxml2::XMLNode* pParent); - void deSerializeVector3FloatData(tinyxml2::XMLNode* pParent,btAlignedObjectArray& vectors); + void deSerializeVector3FloatData(tinyxml2::XMLNode* pParent, btAlignedObjectArray& vectors); - void fixupCollisionDataPointers(btCollisionShapeData* shapeData); - void fixupConstraintData(btTypedConstraintData2* tcd); + void fixupCollisionDataPointers(btCollisionShapeData* shapeData); + void fixupConstraintData(btTypedConstraintData2* tcd); //collision shapes data - void deSerializeCollisionShapeData(tinyxml2::XMLNode* pParent,btCollisionShapeData* colShapeData); + void deSerializeCollisionShapeData(tinyxml2::XMLNode* pParent, btCollisionShapeData* colShapeData); void deSerializeConvexInternalShapeData(tinyxml2::XMLNode* pParent); void deSerializeStaticPlaneShapeData(tinyxml2::XMLNode* pParent); void deSerializeCompoundShapeData(tinyxml2::XMLNode* pParent); void deSerializeCompoundShapeChildData(tinyxml2::XMLNode* pParent); void deSerializeConvexHullShapeData(tinyxml2::XMLNode* pParent); void deSerializeDynamicsWorldData(tinyxml2::XMLNode* parent); - + ///bodies void deSerializeRigidBodyFloatData(tinyxml2::XMLNode* pParent); ///constraints void deSerializeGeneric6DofConstraintData(tinyxml2::XMLNode* pParent); - public: - btBulletXmlWorldImporter(btDynamicsWorld* world); +public: + btBulletXmlWorldImporter(btDynamicsWorld* world); - virtual ~btBulletXmlWorldImporter(); - - bool loadFile(const char* fileName); + virtual ~btBulletXmlWorldImporter(); + bool loadFile(const char* fileName); }; -#endif //BT_BULLET_XML_WORLD_IMPORTER_H +#endif //BT_BULLET_XML_WORLD_IMPORTER_H diff --git a/Extras/Serialize/BulletXmlWorldImporter/string_split.cpp b/Extras/Serialize/BulletXmlWorldImporter/string_split.cpp index 424ded32a..4325126b3 100644 --- a/Extras/Serialize/BulletXmlWorldImporter/string_split.cpp +++ b/Extras/Serialize/BulletXmlWorldImporter/string_split.cpp @@ -25,18 +25,16 @@ subject to the following restrictions: namespace bullet_utils { - void split( btAlignedObjectArray&pieces, const std::string& vector_str, const std::string& separator) - { - char** strArray = str_split(vector_str.c_str(),separator.c_str()); - int numSubStr = str_array_len(strArray); - for (int i=0;i &pieces, const std::string &vector_str, const std::string &separator) +{ + char **strArray = str_split(vector_str.c_str(), separator.c_str()); + int numSubStr = str_array_len(strArray); + for (int i = 0; i < numSubStr; i++) + pieces.push_back(std::string(strArray[i])); + str_array_free(strArray); +} +}; // namespace bullet_utils /* Append an item to a dynamically allocated array of strings. On failure, return NULL, in which case the original array is intact. The item @@ -44,207 +42,220 @@ namespace bullet_utils array. Otherwise, extend the array. Make sure the array is always NULL-terminated. Input string might not be '\0'-terminated. */ char **str_array_append(char **array, size_t nitems, const char *item, - size_t itemlen) + size_t itemlen) { - /* Make a dynamic copy of the item. */ - char *copy; - if (item == NULL) - copy = NULL; - else { - copy = (char*)malloc(itemlen + 1); - if (copy == NULL) - return NULL; - memcpy(copy, item, itemlen); - copy[itemlen] = '\0'; - } - - /* Extend array with one element. Except extend it by two elements, + /* Make a dynamic copy of the item. */ + char *copy; + if (item == NULL) + copy = NULL; + else + { + copy = (char *)malloc(itemlen + 1); + if (copy == NULL) + return NULL; + memcpy(copy, item, itemlen); + copy[itemlen] = '\0'; + } + + /* Extend array with one element. Except extend it by two elements, in case it did not yet exist. This might mean it is a teeny bit too big, but we don't care. */ - array = (char**)realloc(array, (nitems + 2) * sizeof(array[0])); - if (array == NULL) { - free(copy); - return NULL; - } - - /* Add copy of item to array, and return it. */ - array[nitems] = copy; - array[nitems+1] = NULL; - return array; -} + array = (char **)realloc(array, (nitems + 2) * sizeof(array[0])); + if (array == NULL) + { + free(copy); + return NULL; + } + /* Add copy of item to array, and return it. */ + array[nitems] = copy; + array[nitems + 1] = NULL; + return array; +} /* Free a dynamic array of dynamic strings. */ void str_array_free(char **array) { - if (array == NULL) - return; - for (size_t i = 0; array[i] != NULL; ++i) - free(array[i]); - free(array); + if (array == NULL) + return; + for (size_t i = 0; array[i] != NULL; ++i) + free(array[i]); + free(array); } - /* Split a string into substrings. Return dynamic array of dynamically allocated substrings, or NULL if there was an error. Caller is expected to free the memory, for example with str_array_free. */ char **str_split(const char *input, const char *sep) { - size_t nitems = 0; - char **array = NULL; - const char *start = input; - const char *next = strstr(start, sep); - size_t seplen = strlen(sep); - const char *item; - size_t itemlen; - - for (;;) { - next = strstr(start, sep); - if (next == NULL) { - /* Add the remaining string (or empty string, if input ends with - separator. */ - char **newstr = str_array_append(array, nitems, start, strlen(start)); - if (newstr == NULL) { - str_array_free(array); - return NULL; - } - array = newstr; - ++nitems; - break; - } else if (next == input) { - /* Input starts with separator. */ - item = ""; - itemlen = 0; - } else { - item = start; - itemlen = next - item; - } - char **newstr = str_array_append(array, nitems, item, itemlen); - if (newstr == NULL) { - str_array_free(array); - return NULL; - } - array = newstr; - ++nitems; - start = next + seplen; - } - - if (nitems == 0) { - /* Input does not contain separator at all. */ - assert(array == NULL); - array = str_array_append(array, nitems, input, strlen(input)); - } - - return array; -} + size_t nitems = 0; + char **array = NULL; + const char *start = input; + const char *next = strstr(start, sep); + size_t seplen = strlen(sep); + const char *item; + size_t itemlen; + for (;;) + { + next = strstr(start, sep); + if (next == NULL) + { + /* Add the remaining string (or empty string, if input ends with + separator. */ + char **newstr = str_array_append(array, nitems, start, strlen(start)); + if (newstr == NULL) + { + str_array_free(array); + return NULL; + } + array = newstr; + ++nitems; + break; + } + else if (next == input) + { + /* Input starts with separator. */ + item = ""; + itemlen = 0; + } + else + { + item = start; + itemlen = next - item; + } + char **newstr = str_array_append(array, nitems, item, itemlen); + if (newstr == NULL) + { + str_array_free(array); + return NULL; + } + array = newstr; + ++nitems; + start = next + seplen; + } + + if (nitems == 0) + { + /* Input does not contain separator at all. */ + assert(array == NULL); + array = str_array_append(array, nitems, input, strlen(input)); + } + + return array; +} /* Return length of a NULL-delimited array of strings. */ size_t str_array_len(char **array) { - size_t len; - - for (len = 0; array[len] != NULL; ++len) - continue; - return len; + size_t len; + + for (len = 0; array[len] != NULL; ++len) + continue; + return len; } #ifdef UNIT_TEST_STRING #define MAX_OUTPUT 20 - int main(void) { - struct { - const char *input; - const char *sep; - char *output[MAX_OUTPUT]; - } tab[] = { - /* Input is empty string. Output should be a list with an empty + struct + { + const char *input; + const char *sep; + char *output[MAX_OUTPUT]; + } tab[] = { + /* Input is empty string. Output should be a list with an empty string. */ - { - "", - "and", - { - "", - NULL, - }, - }, - /* Input is exactly the separator. Output should be two empty + { + "", + "and", + { + "", + NULL, + }, + }, + /* Input is exactly the separator. Output should be two empty strings. */ - { - "and", - "and", - { - "", - "", - NULL, - }, - }, - /* Input is non-empty, but does not have separator. Output should + { + "and", + "and", + { + "", + "", + NULL, + }, + }, + /* Input is non-empty, but does not have separator. Output should be the same string. */ - { - "foo", - "and", - { - "foo", - NULL, - }, - }, - /* Input is non-empty, and does have separator. */ - { - "foo bar 1 and foo bar 2", - " and ", - { - "foo bar 1", - "foo bar 2", - NULL, - }, - }, - }; - const int tab_len = sizeof(tab) / sizeof(tab[0]); - bool errors; - - errors = false; - - for (int i = 0; i < tab_len; ++i) { - printf("test %d\n", i); - - char **output = str_split(tab[i].input, tab[i].sep); - if (output == NULL) { - fprintf(stderr, "output is NULL\n"); - errors = true; - break; - } - size_t num_output = str_array_len(output); - printf("num_output %lu\n", (unsigned long) num_output); - - size_t num_correct = str_array_len(tab[i].output); - if (num_output != num_correct) { - fprintf(stderr, "wrong number of outputs (%lu, not %lu)\n", - (unsigned long) num_output, (unsigned long) num_correct); - errors = true; - } else { - for (size_t j = 0; j < num_output; ++j) { - if (strcmp(tab[i].output[j], output[j]) != 0) { - fprintf(stderr, "output[%lu] is '%s' not '%s'\n", - (unsigned long) j, output[j], tab[i].output[j]); - errors = true; - break; - } - } - } - - str_array_free(output); - printf("\n"); - } - - if (errors) - return EXIT_FAILURE; - return 0; + { + "foo", + "and", + { + "foo", + NULL, + }, + }, + /* Input is non-empty, and does have separator. */ + { + "foo bar 1 and foo bar 2", + " and ", + { + "foo bar 1", + "foo bar 2", + NULL, + }, + }, + }; + const int tab_len = sizeof(tab) / sizeof(tab[0]); + bool errors; + + errors = false; + + for (int i = 0; i < tab_len; ++i) + { + printf("test %d\n", i); + + char **output = str_split(tab[i].input, tab[i].sep); + if (output == NULL) + { + fprintf(stderr, "output is NULL\n"); + errors = true; + break; + } + size_t num_output = str_array_len(output); + printf("num_output %lu\n", (unsigned long)num_output); + + size_t num_correct = str_array_len(tab[i].output); + if (num_output != num_correct) + { + fprintf(stderr, "wrong number of outputs (%lu, not %lu)\n", + (unsigned long)num_output, (unsigned long)num_correct); + errors = true; + } + else + { + for (size_t j = 0; j < num_output; ++j) + { + if (strcmp(tab[i].output[j], output[j]) != 0) + { + fprintf(stderr, "output[%lu] is '%s' not '%s'\n", + (unsigned long)j, output[j], tab[i].output[j]); + errors = true; + break; + } + } + } + + str_array_free(output); + printf("\n"); + } + + if (errors) + return EXIT_FAILURE; + return 0; } -#endif// - - +#endif // diff --git a/Extras/Serialize/BulletXmlWorldImporter/string_split.h b/Extras/Serialize/BulletXmlWorldImporter/string_split.h index a6d85ddb5..16d629d61 100644 --- a/Extras/Serialize/BulletXmlWorldImporter/string_split.h +++ b/Extras/Serialize/BulletXmlWorldImporter/string_split.h @@ -16,7 +16,6 @@ subject to the following restrictions: ///The string split C code is by Lars Wirzenius ///See http://stackoverflow.com/questions/2531605/how-to-split-a-string-with-a-delimiter-larger-than-one-single-char - #ifndef STRING_SPLIT_H #define STRING_SPLIT_H @@ -27,17 +26,16 @@ subject to the following restrictions: namespace bullet_utils { - void split( btAlignedObjectArray&pieces, const std::string& vector_str, const std::string& separator); +void split(btAlignedObjectArray& pieces, const std::string& vector_str, const std::string& separator); }; ///The string split C code is by Lars Wirzenius ///See http://stackoverflow.com/questions/2531605/how-to-split-a-string-with-a-delimiter-larger-than-one-single-char - /* Split a string into substrings. Return dynamic array of dynamically allocated substrings, or NULL if there was an error. Caller is expected to free the memory, for example with str_array_free. */ -char** str_split(const char* input, const char* sep); +char** str_split(const char* input, const char* sep); /* Free a dynamic array of dynamic strings. */ void str_array_free(char** array); @@ -45,5 +43,4 @@ void str_array_free(char** array); /* Return length of a NULL-delimited array of strings. */ size_t str_array_len(char** array); -#endif //STRING_SPLIT_H - +#endif //STRING_SPLIT_H diff --git a/Extras/Serialize/HeaderGenerator/apiGen.cpp b/Extras/Serialize/HeaderGenerator/apiGen.cpp index 2c4c76327..233bee9f5 100644 --- a/Extras/Serialize/HeaderGenerator/apiGen.cpp +++ b/Extras/Serialize/HeaderGenerator/apiGen.cpp @@ -36,13 +36,11 @@ typedef std::map bStringMap; typedef std::vector bVariableList; typedef std::vector bStringList; - /////////////////////////////////////////////////////////////////////////////// static FILE *dump = 0; -static bDNA *mDNA =0; +static bDNA *mDNA = 0; static bStringMap mStructs; - /////////////////////////////////////////////////////////////////////////////// class bVariable { @@ -50,11 +48,9 @@ public: bVariable(); ~bVariable(); - bString dataType; bString variableName; - bString functionName; bString classCtor; @@ -62,7 +58,6 @@ public: bString memberDataType; bString functionArgs; - void initialize(bString dataType, bString variable, bStringMap refDataTable); bool isPtr; @@ -103,26 +98,25 @@ bool dataTypeStandard(bString dataType) void writeTemplate(short *structData) { bString type = mDNA->getType(structData[0]); - bString className=type; - bString prefix = isBulletFile? "bullet_" : "blender_"; - - int thisLen = structData[1]; - structData+=2; + bString className = type; + bString prefix = isBulletFile ? "bullet_" : "blender_"; - bString fileName = prefix+type; + int thisLen = structData[1]; + structData += 2; + + bString fileName = prefix + type; bVariableList dataTypes; bStringMap includeFiles; - - for (int dataVal =0; dataValgetType(structData[0]); bString dataName = mDNA->getName(structData[1]); { bString newDataType = ""; bString newDataName = ""; - + bStringMap::iterator addB = mStructs.find(dataType); if (addB != mStructs.end()) { @@ -130,7 +124,7 @@ void writeTemplate(short *structData) newDataName = dataName; } - else + else { if (dataTypeStandard(dataType)) { @@ -148,8 +142,7 @@ void writeTemplate(short *structData) if (dataName[0] != '*') { } - - } + } } if (!newDataType.empty() && !newDataName.empty()) @@ -160,28 +153,26 @@ void writeTemplate(short *structData) } } - bStringMap::iterator include = mStructs.find(dataType); if (include != mStructs.end()) { - if (dataName[0] != '*') + if (dataName[0] != '*') { - if (includeFiles.find(dataType)== includeFiles.end()) + if (includeFiles.find(dataType) == includeFiles.end()) { - includeFiles[dataType]=prefix+dataType; + includeFiles[dataType] = prefix + dataType; } } } } - fprintf(dump, "###############################################################\n"); fprintf(dump, "%s = bStructClass()\n", fileName.c_str()); fprintf(dump, "%s.name = '%s'\n", fileName.c_str(), className.c_str()); fprintf(dump, "%s.filename = '%s'\n", fileName.c_str(), fileName.c_str()); bVariableList::iterator vars = dataTypes.begin(); - while (vars!= dataTypes.end()) + while (vars != dataTypes.end()) { fprintf(dump, "%s.dataTypes.append('%s %s')\n", fileName.c_str(), vars->dataType.c_str(), vars->variableName.c_str()); vars++; @@ -196,32 +187,27 @@ void writeTemplate(short *structData) fprintf(dump, "DataTypeList.append(%s)\n", fileName.c_str()); } +/////////////////////////////////////////////////////////////////////////////// +char data[] = { + "\n" + "class bStructClass:\n" + " def __init__(self):\n" + " self.name = \"\";\n" + " self.filename = \"\";\n" + " self.includes = []\n" + " self.dataTypes = []\n" + "\n\n" + "DataTypeList = []\n"}; /////////////////////////////////////////////////////////////////////////////// -char data[]={ -"\n" -"class bStructClass:\n" -" def __init__(self):\n" -" self.name = \"\";\n" -" self.filename = \"\";\n" -" self.includes = []\n" -" self.dataTypes = []\n" -"\n\n" -"DataTypeList = []\n" -}; - - -/////////////////////////////////////////////////////////////////////////////// -int main(int argc,char** argv) +int main(int argc, char **argv) { using namespace bParse; dump = fopen("dump.py", "w"); - if (!dump) return 0; fprintf(dump, "%s\n", data); - #if 0 char* filename = "../../../../data/r2d2_multibody.bullet"; @@ -275,73 +261,65 @@ int main(int argc,char** argv) #else isBulletFile = true; bool swap = false; - char* memBuf = sBulletDNAstr; + char *memBuf = sBulletDNAstr; int len = sBulletDNAlen; #endif - char *blenderData = memBuf; - int sdnaPos=0; + int sdnaPos = 0; int mDataStart = 12; char *tempBuffer = blenderData; - for (int i=0; iinitMemory(); - - mDNA->init(memBuf+sdnaPos, len-sdnaPos, swap); - - for (int i=0; igetNumStructs(); i++) + mDNA->init(memBuf + sdnaPos, len - sdnaPos, swap); + + for (int i = 0; i < mDNA->getNumStructs(); i++) { short *structData = mDNA->getStruct(i); bString type = mDNA->getType(structData[0]); bString className = type; - mStructs[type]=className; + mStructs[type] = className; } - - for (int i=0; igetNumStructs(); i++) + for (int i = 0; i < mDNA->getNumStructs(); i++) { short *structData = mDNA->getStruct(i); writeTemplate(structData); @@ -353,23 +331,22 @@ int main(int argc,char** argv) } /////////////////////////////////////////////////////////////////////////////// - /////////////////////////////////////////////////////////////////////////////// -int _getArraySize(char* str) +int _getArraySize(char *str) { - int a, mul=1; - char stri[100], *cp=0; + int a, mul = 1; + char stri[100], *cp = 0; int len = (int)strlen(str); - memcpy(stri, str, len+1); - for (a=0; a -///work-in-progress +///work-in-progress ///This ReadBulletSample is kept as simple as possible without dependencies to the Bullet SDK. ///It can be used to load .bullet data for other physics SDKs ///For a more complete example how to load and convert Bullet data using the Bullet SDK check out @@ -22,8 +22,8 @@ enum LocalBroadphaseNativeTypes CONVEX_HULL_SHAPE_PROXYTYPE, CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE, CUSTOM_POLYHEDRAL_SHAPE_TYPE, -//implicit convex shapes -IMPLICIT_CONVEX_SHAPES_START_HERE, + //implicit convex shapes + IMPLICIT_CONVEX_SHAPES_START_HERE, SPHERE_SHAPE_PROXYTYPE, MULTI_SPHERE_SHAPE_PROXYTYPE, CAPSULE_SHAPE_PROXYTYPE, @@ -36,8 +36,8 @@ IMPLICIT_CONVEX_SHAPES_START_HERE, BOX_2D_SHAPE_PROXYTYPE, CONVEX_2D_SHAPE_PROXYTYPE, CUSTOM_CONVEX_SHAPE_TYPE, -//concave shapes -CONCAVE_SHAPES_START_HERE, + //concave shapes + CONCAVE_SHAPES_START_HERE, //keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy! TRIANGLE_MESH_SHAPE_PROXYTYPE, SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE, @@ -45,15 +45,15 @@ CONCAVE_SHAPES_START_HERE, FAST_CONCAVE_MESH_PROXYTYPE, //terrain TERRAIN_SHAPE_PROXYTYPE, -///Used for GIMPACT Trimesh integration + ///Used for GIMPACT Trimesh integration GIMPACT_SHAPE_PROXYTYPE, -///Multimaterial mesh - MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE, - + ///Multimaterial mesh + MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE, + EMPTY_SHAPE_PROXYTYPE, STATIC_PLANE_PROXYTYPE, CUSTOM_CONCAVE_SHAPE_TYPE, -CONCAVE_SHAPES_END_HERE, + CONCAVE_SHAPES_END_HERE, COMPOUND_SHAPE_PROXYTYPE, @@ -63,7 +63,7 @@ CONCAVE_SHAPES_END_HERE, INVALID_SHAPE_PROXYTYPE, MAX_BROADPHASE_COLLISION_TYPES - + }; btBulletDataExtractor::btBulletDataExtractor() @@ -78,28 +78,25 @@ void btBulletDataExtractor::convertAllObjects(bParse::btBulletFile* bulletFile2) { int i; - for (i=0;im_collisionShapes.size();i++) + for (i = 0; i < bulletFile2->m_collisionShapes.size(); i++) { btCollisionShapeData* shapeData = (btCollisionShapeData*)bulletFile2->m_collisionShapes[i]; if (shapeData->m_name) printf("converting shape %s\n", shapeData->m_name); void* shape = convertCollisionShape(shapeData); } - } - - -void* btBulletDataExtractor::convertCollisionShape( btCollisionShapeData* shapeData ) +void* btBulletDataExtractor::convertCollisionShape(btCollisionShapeData* shapeData) { void* shape = 0; switch (shapeData->m_shapeType) - { - case STATIC_PLANE_PROXYTYPE: + { + case STATIC_PLANE_PROXYTYPE: { btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*)shapeData; - void* shape = createPlaneShape(planeData->m_planeNormal,planeData->m_planeConstant, planeData->m_localScaling); + void* shape = createPlaneShape(planeData->m_planeNormal, planeData->m_planeConstant, planeData->m_localScaling); break; } @@ -109,21 +106,21 @@ void* btBulletDataExtractor::convertCollisionShape( btCollisionShapeData* shape case SPHERE_SHAPE_PROXYTYPE: case MULTI_SPHERE_SHAPE_PROXYTYPE: case CONVEX_HULL_SHAPE_PROXYTYPE: + { + btConvexInternalShapeData* bsd = (btConvexInternalShapeData*)shapeData; + + switch (shapeData->m_shapeType) { - btConvexInternalShapeData* bsd = (btConvexInternalShapeData*)shapeData; - - switch (shapeData->m_shapeType) + case BOX_SHAPE_PROXYTYPE: { - case BOX_SHAPE_PROXYTYPE: - { - shape = createBoxShape(bsd->m_implicitShapeDimensions, bsd->m_localScaling,bsd->m_collisionMargin); - break; - } - case SPHERE_SHAPE_PROXYTYPE: - { - shape = createSphereShape(bsd->m_implicitShapeDimensions.m_floats[0],bsd->m_localScaling, bsd->m_collisionMargin); - break; - } + shape = createBoxShape(bsd->m_implicitShapeDimensions, bsd->m_localScaling, bsd->m_collisionMargin); + break; + } + case SPHERE_SHAPE_PROXYTYPE: + { + shape = createSphereShape(bsd->m_implicitShapeDimensions.m_floats[0], bsd->m_localScaling, bsd->m_collisionMargin); + break; + } #if 0 case CAPSULE_SHAPE_PROXYTYPE: { @@ -221,14 +218,14 @@ void* btBulletDataExtractor::convertCollisionShape( btCollisionShapeData* shape } #endif - default: - { - printf("error: cannot create shape type (%d)\n",shapeData->m_shapeType); - } + default: + { + printf("error: cannot create shape type (%d)\n", shapeData->m_shapeType); } - - break; } + + break; + } #if 0 case TRIANGLE_MESH_SHAPE_PROXYTYPE: { @@ -257,7 +254,7 @@ void* btBulletDataExtractor::convertCollisionShape( btCollisionShapeData* shape #ifdef USE_INTERNAL_EDGE_UTILITY gContactAddedCallback = btAdjustInternalEdgeContactsCallback; -#endif //USE_INTERNAL_EDGE_UTILITY +#endif //USE_INTERNAL_EDGE_UTILITY } @@ -313,33 +310,30 @@ void* btBulletDataExtractor::convertCollisionShape( btCollisionShapeData* shape { return 0; } -#endif +#endif default: - { - printf("unsupported shape type (%d)\n",shapeData->m_shapeType); - } + { + printf("unsupported shape type (%d)\n", shapeData->m_shapeType); } + } - return shape; - + return shape; } -void* btBulletDataExtractor::createBoxShape( const Bullet::btVector3FloatData& halfDimensions, const Bullet::btVector3FloatData& localScaling, float collisionMargin) +void* btBulletDataExtractor::createBoxShape(const Bullet::btVector3FloatData& halfDimensions, const Bullet::btVector3FloatData& localScaling, float collisionMargin) { - printf("createBoxShape with halfDimensions %f,%f,%f\n",halfDimensions.m_floats[0], halfDimensions.m_floats[1],halfDimensions.m_floats[2]); + printf("createBoxShape with halfDimensions %f,%f,%f\n", halfDimensions.m_floats[0], halfDimensions.m_floats[1], halfDimensions.m_floats[2]); return 0; } -void* btBulletDataExtractor::createSphereShape( float radius, const Bullet::btVector3FloatData& localScaling, float collisionMargin) +void* btBulletDataExtractor::createSphereShape(float radius, const Bullet::btVector3FloatData& localScaling, float collisionMargin) { - printf("createSphereShape with radius %f\n",radius); + printf("createSphereShape with radius %f\n", radius); return 0; } - -void* btBulletDataExtractor::createPlaneShape( const btVector3FloatData& planeNormal, float planeConstant, const Bullet::btVector3FloatData& localScaling) +void* btBulletDataExtractor::createPlaneShape(const btVector3FloatData& planeNormal, float planeConstant, const Bullet::btVector3FloatData& localScaling) { - printf("createPlaneShape with normal %f,%f,%f and planeConstant\n",planeNormal.m_floats[0], planeNormal.m_floats[1],planeNormal.m_floats[2],planeConstant); + printf("createPlaneShape with normal %f,%f,%f and planeConstant\n", planeNormal.m_floats[0], planeNormal.m_floats[1], planeNormal.m_floats[2], planeConstant); return 0; } - diff --git a/Extras/Serialize/ReadBulletSample/BulletDataExtractor.h b/Extras/Serialize/ReadBulletSample/BulletDataExtractor.h index 8524716ba..673e44c60 100644 --- a/Extras/Serialize/ReadBulletSample/BulletDataExtractor.h +++ b/Extras/Serialize/ReadBulletSample/BulletDataExtractor.h @@ -1,32 +1,29 @@ #ifndef BULLET_DATA_EXTRACTOR_H #define BULLET_DATA_EXTRACTOR_H - #include "../BulletFileLoader/autogenerated/bullet.h" namespace bParse { - class btBulletFile; +class btBulletFile; }; class btBulletDataExtractor { - public: - +public: btBulletDataExtractor(); - + virtual ~btBulletDataExtractor(); - + virtual void convertAllObjects(bParse::btBulletFile* bulletFile); - - virtual void* convertCollisionShape( Bullet::btCollisionShapeData* shapeData ); - virtual void* createPlaneShape( const Bullet::btVector3FloatData& planeNormal, float planeConstant, const Bullet::btVector3FloatData& localScaling); - - virtual void* createBoxShape( const Bullet::btVector3FloatData& halfDimensions, const Bullet::btVector3FloatData& localScaling, float collisionMargin); + virtual void* convertCollisionShape(Bullet::btCollisionShapeData* shapeData); - virtual void* createSphereShape( float radius, const Bullet::btVector3FloatData& localScaling, float collisionMargin); + virtual void* createPlaneShape(const Bullet::btVector3FloatData& planeNormal, float planeConstant, const Bullet::btVector3FloatData& localScaling); + virtual void* createBoxShape(const Bullet::btVector3FloatData& halfDimensions, const Bullet::btVector3FloatData& localScaling, float collisionMargin); + + virtual void* createSphereShape(float radius, const Bullet::btVector3FloatData& localScaling, float collisionMargin); }; - -#endif //BULLET_DATA_EXTRACTOR_H \ No newline at end of file + +#endif //BULLET_DATA_EXTRACTOR_H \ No newline at end of file diff --git a/Extras/Serialize/ReadBulletSample/main.cpp b/Extras/Serialize/ReadBulletSample/main.cpp index e9420c7d2..1513c6e55 100644 --- a/Extras/Serialize/ReadBulletSample/main.cpp +++ b/Extras/Serialize/ReadBulletSample/main.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include #include "../BulletFileLoader/btBulletFile.h" #include "BulletDataExtractor.h" @@ -25,39 +24,37 @@ subject to the following restrictions: int main(int argc, char** argv) { - const char* fileName="testFile.bullet"; + const char* fileName = "testFile.bullet"; bool verboseDumpAllTypes = false; bParse::btBulletFile* bulletFile2 = new bParse::btBulletFile(fileName); - bool ok = (bulletFile2->getFlags()& bParse::FD_OK)!=0; - + bool ok = (bulletFile2->getFlags() & bParse::FD_OK) != 0; + if (ok) bulletFile2->parse(verboseDumpAllTypes); else { - printf("Error loading file %s.\n",fileName); + printf("Error loading file %s.\n", fileName); exit(0); } - ok = (bulletFile2->getFlags()& bParse::FD_OK)!=0; + ok = (bulletFile2->getFlags() & bParse::FD_OK) != 0; if (!ok) { - printf("Error parsing file %s.\n",fileName); + printf("Error parsing file %s.\n", fileName); exit(0); } - + if (verboseDumpAllTypes) { bulletFile2->dumpChunks(bulletFile2->getFileDNA()); } - btBulletDataExtractor extractor; - + extractor.convertAllObjects(bulletFile2); delete bulletFile2; return 0; } - diff --git a/Extras/Serialize/makesdna/DNA_rigidbody.h b/Extras/Serialize/makesdna/DNA_rigidbody.h index 010ed1bbf..d100dab18 100644 --- a/Extras/Serialize/makesdna/DNA_rigidbody.h +++ b/Extras/Serialize/makesdna/DNA_rigidbody.h @@ -2,20 +2,18 @@ #ifndef DNA_RIGIDBODY_H #define DNA_RIGIDBODY_H - -struct PointerArray +struct PointerArray { - int m_size; - int m_capacity; - void *m_data; + int m_size; + int m_capacity; + void *m_data; }; - struct btPhysicsSystem { - PointerArray m_collisionShapes; - PointerArray m_collisionObjects; - PointerArray m_constraints; + PointerArray m_collisionShapes; + PointerArray m_collisionObjects; + PointerArray m_constraints; }; ///we need this to compute the pointer sizes @@ -25,5 +23,4 @@ struct ListBase void *last; }; - #endif diff --git a/Extras/Serialize/makesdna/makesdna.cpp b/Extras/Serialize/makesdna/makesdna.cpp index 72795506e..525ec5f06 100644 --- a/Extras/Serialize/makesdna/makesdna.cpp +++ b/Extras/Serialize/makesdna/makesdna.cpp @@ -48,47 +48,45 @@ * debugSDNA. This int can be set to 0 (no output) to some int. Higher * numbers give more output. * */ - - + #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif - + #if defined(_WIN32) && !defined(FREE_WINDOWS) -/* The __intXX are built-in types of the visual complier! So we don't + /* The __intXX are built-in types of the visual complier! So we don't * need to include anything else here. */ -typedef signed __int8 int8_t; -typedef signed __int16 int16_t; -typedef signed __int32 int32_t; -typedef signed __int64 int64_t; + typedef signed __int8 int8_t; + typedef signed __int16 int16_t; + typedef signed __int32 int32_t; + typedef signed __int64 int64_t; -typedef unsigned __int8 uint8_t; -typedef unsigned __int16 uint16_t; -typedef unsigned __int32 uint32_t; -typedef unsigned __int64 uint64_t; + typedef unsigned __int8 uint8_t; + typedef unsigned __int16 uint16_t; + typedef unsigned __int32 uint32_t; + typedef unsigned __int64 uint64_t; #ifndef _INTPTR_T_DEFINED - #ifdef _WIN64 +#ifdef _WIN64 typedef __int64 btintptr_t; - #else +#else typedef long btintptr_t; - #endif - +#endif + #else typedef intptr_t btintptr_t; #endif - - #elif defined(__linux__) || defined(__NetBSD__) - /* Linux-i386, Linux-Alpha, Linux-ppc */ +/* Linux-i386, Linux-Alpha, Linux-ppc */ #include typedef intptr_t btintptr_t; -#elif defined (__APPLE__) +#elif defined(__APPLE__) #include typedef intptr_t btintptr_t; @@ -99,7 +97,7 @@ typedef intptr_t btintptr_t; #else - /* FreeBSD, Irix, Solaris */ +/* FreeBSD, Irix, Solaris */ #include #endif /* ifdef platform for types */ @@ -108,7 +106,6 @@ typedef intptr_t btintptr_t; } #endif - #include #include #include @@ -200,30 +197,29 @@ char *includefiles[] = { "../../../src/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h", "../../../src/BulletDynamics/ConstraintSolver/btSliderConstraint.h", "../../../src/BulletDynamics/ConstraintSolver/btGearConstraint.h", - + "../../../src/BulletSoftBody/btSoftBodyData.h", "../../../src/BulletDynamics/Featherstone/btMultiBody.h", "../../../src/BulletDynamics/Featherstone/btMultiBodyLinkCollider.h", // empty string to indicate end of includefiles - "" -}; + ""}; -void* malloc_and_setzero(int numbytes) +void *malloc_and_setzero(int numbytes) { - char* buf = (char*)malloc(numbytes); - memset(buf,0,numbytes); + char *buf = (char *)malloc(numbytes); + memset(buf, 0, numbytes); return buf; } -int maxdata= 500000, maxnr= 50000; -int nr_names=0; -int nr_types=0; -int nr_structs=0; -char **names, *namedata; /* at adress names[a] is string a */ -char **types, *typedata; /* at adress types[a] is string a */ -short *typelens; /* at typelens[a] is de length of type a */ -short *alphalens; /* contains sizes as they are calculated on the DEC Alpha (64 bits) */ -short **structs, *structdata; /* at sp= structs[a] is the first adress of a struct definition +int maxdata = 500000, maxnr = 50000; +int nr_names = 0; +int nr_types = 0; +int nr_structs = 0; +char **names, *namedata; /* at adress names[a] is string a */ +char **types, *typedata; /* at adress types[a] is string a */ +short *typelens; /* at typelens[a] is de length of type a */ +short *alphalens; /* contains sizes as they are calculated on the DEC Alpha (64 bits) */ +short **structs, *structdata; /* at sp= structs[a] is the first adress of a struct definition sp[0] is type number sp[1] is amount of elements sp[2] sp[3] is typenr, namenr (etc) */ @@ -265,22 +261,22 @@ int preprocess_include(char *maindata, int len); /** * Scan this file for serializable types. - */ + */ int convert_include(char *filename); /** * Determine how many bytes are needed for an array. - */ + */ int arraysize(char *astr, int len); /** * Determine how many bytes are needed for each struct. - */ + */ static int calculate_structlens(int); /** * Construct the DNA.c file - */ + */ void dna_write(FILE *file, void *pntr, int size); /** @@ -288,8 +284,6 @@ void dna_write(FILE *file, void *pntr, int size); */ void printStructLenghts(void); - - /* ************************************************************************** */ /* Implementation */ /* ************************************************************************** */ @@ -300,37 +294,44 @@ int add_type(char *str, int len) { int nr; char *cp; - - if(str[0]==0) return -1; - + + if (str[0] == 0) return -1; + /* search through type array */ - for(nr=0; nr=maxnr) { + types[nr_types] = cp; + typelens[nr_types] = len; + alphalens[nr_types] = len; + + if (nr_types >= maxnr) + { printf("too many types\n"); - return nr_types-1;; + return nr_types - 1; + ; } nr_types++; - - return nr_types-1; + + return nr_types - 1; } /** @@ -349,20 +350,22 @@ int add_name(char *str) char *name; additional_slen_offset = 0; - - if((str[0]==0) /* || (str[1]==0) */) return -1; - if (str[0] == '(' && str[1] == '*') { + if ((str[0] == 0) /* || (str[1]==0) */) return -1; + + if (str[0] == '(' && str[1] == '*') + { if (debugSDNA > 3) printf("\t\t\t\t*** Function pointer found\n"); /* functionpointer: transform the type (sometimes) */ i = 0; j = 0; - while (str[i] != ')') { + while (str[i] != ')') + { buf[i] = str[i]; i++; } - + /* Another number we need is the extra slen offset. This extra * offset is the overshoot after a space. If there is no * space, no overshoot should be calculated. */ @@ -371,30 +374,37 @@ int add_name(char *str) if (debugSDNA > 3) printf("first brace after offset %d\n", i); j++; /* j beyond closing brace ? */ - while ((str[j] != 0) && (str[j] != ')' )) { + while ((str[j] != 0) && (str[j] != ')')) + { if (debugSDNA > 3) printf("seen %c ( %d) \n", str[j], str[j]); j++; } - if (debugSDNA > 3) printf("seen %c ( %d) \n", str[j], str[j]); - if (debugSDNA > 3) printf("special after offset %d\n", j); - - if (str[j] == 0 ) { - if (debugSDNA > 3) printf("offsetting for space\n"); + if (debugSDNA > 3) printf("seen %c ( %d) \n", str[j], str[j]); + if (debugSDNA > 3) printf("special after offset %d\n", j); + + if (str[j] == 0) + { + if (debugSDNA > 3) printf("offsetting for space\n"); /* get additional offset */ k = 0; - while (str[j] != ')') { + while (str[j] != ')') + { j++; k++; } if (debugSDNA > 3) printf("extra offset %d\n", k); additional_slen_offset = k; - } else if (str[j] == ')' ) { + } + else if (str[j] == ')') + { if (debugSDNA > 3) printf("offsetting for brace\n"); ; /* don't get extra offset */ - } else { + } + else + { printf("Error during tokening function pointer argument list\n"); } - + /* * Put )(void) at the end? Maybe )(). Should check this with * old sdna. Actually, sometimes )(), sometimes )(void...) @@ -408,53 +418,62 @@ int add_name(char *str) * * */ buf[i] = 0; - if (debugSDNA > 3) printf("Name before chomping: %s\n", buf); - if ( (strncmp(buf,"(*headdraw", 10) == 0) - || (strncmp(buf,"(*windraw", 9) == 0) ) { + if (debugSDNA > 3) printf("Name before chomping: %s\n", buf); + if ((strncmp(buf, "(*headdraw", 10) == 0) || (strncmp(buf, "(*windraw", 9) == 0)) + { buf[i] = ')'; - buf[i+1] = '('; - buf[i+2] = 'v'; - buf[i+3] = 'o'; - buf[i+4] = 'i'; - buf[i+5] = 'd'; - buf[i+6] = ')'; - buf[i+7] = 0; - } else { + buf[i + 1] = '('; + buf[i + 2] = 'v'; + buf[i + 3] = 'o'; + buf[i + 4] = 'i'; + buf[i + 5] = 'd'; + buf[i + 6] = ')'; + buf[i + 7] = 0; + } + else + { buf[i] = ')'; - buf[i+1] = '('; - buf[i+2] = ')'; - buf[i+3] = 0; + buf[i + 1] = '('; + buf[i + 2] = ')'; + buf[i + 3] = 0; } /* now precede with buf*/ - if (debugSDNA > 3) printf("\t\t\t\t\tProposing fp name %s\n", buf); + if (debugSDNA > 3) printf("\t\t\t\t\tProposing fp name %s\n", buf); name = buf; - } else { + } + else + { /* normal field: old code */ name = str; } - + /* search name array */ - for(nr=0; nr=maxnr) { + names[nr_names] = cp; + + if (nr_names >= maxnr) + { printf("too many names\n"); - return nr_names-1; + return nr_names - 1; } nr_names++; - - return nr_names-1; + + return nr_names - 1; } short *add_struct(int namecode) @@ -462,24 +481,27 @@ short *add_struct(int namecode) int len; short *sp; - if(nr_structs==0) { - structs[0]= structdata; + if (nr_structs == 0) + { + structs[0] = structdata; } - else { - sp= structs[nr_structs-1]; - len= sp[1]; - structs[nr_structs]= sp+ 2*len+2; + else + { + sp = structs[nr_structs - 1]; + len = sp[1]; + structs[nr_structs] = sp + 2 * len + 2; } - - sp= structs[nr_structs]; - sp[0]= namecode; - - if(nr_structs>=maxnr) { + + sp = structs[nr_structs]; + sp[0] = namecode; + + if (nr_structs >= maxnr) + { printf("too many structs\n"); return sp; } nr_structs++; - + return sp; } @@ -487,55 +509,64 @@ int preprocess_include(char *maindata, int len) { int a, newlen, comment = 0; char *cp, *temp, *md; - - temp= (char*) malloc_and_setzero(len); + + temp = (char *)malloc_and_setzero(len); memcpy(temp, maindata, len); - + // remove all c++ comments /* replace all enters/tabs/etc with spaces */ - cp= temp; - a= len; + cp = temp; + a = len; comment = 0; - while(a--) { - if(cp[0]=='/' && cp[1]=='/') { + while (a--) + { + if (cp[0] == '/' && cp[1] == '/') + { comment = 1; - } else if (*cp<32) { + } + else if (*cp < 32) + { comment = 0; } - if (comment || *cp<32 || *cp>128 ) *cp= 32; + if (comment || *cp < 32 || *cp > 128) *cp = 32; cp++; } - /* data from temp copy to maindata, remove comments and double spaces */ - cp= temp; - md= maindata; - newlen= 0; - comment= 0; - a= len; - while(a--) { - - if(cp[0]=='/' && cp[1]=='*') { - comment= 1; - cp[0]=cp[1]= 32; + cp = temp; + md = maindata; + newlen = 0; + comment = 0; + a = len; + while (a--) + { + if (cp[0] == '/' && cp[1] == '*') + { + comment = 1; + cp[0] = cp[1] = 32; } - if(cp[0]=='*' && cp[1]=='/') { - comment= 0; - cp[0]=cp[1]= 32; + if (cp[0] == '*' && cp[1] == '/') + { + comment = 0; + cp[0] = cp[1] = 32; } /* do not copy when: */ - if(comment); - else if( cp[0]==' ' && cp[1]==' ' ); - else if( cp[-1]=='*' && cp[0]==' ' ); /* pointers with a space */ - else { - md[0]= cp[0]; + if (comment) + ; + else if (cp[0] == ' ' && cp[1] == ' ') + ; + else if (cp[-1] == '*' && cp[0] == ' ') + ; /* pointers with a space */ + else + { + md[0] = cp[0]; md++; newlen++; } cp++; } - + free(temp); return newlen; } @@ -543,57 +574,58 @@ int preprocess_include(char *maindata, int len) static void *read_file_data(char *filename, int *len_r) { #ifdef WIN32 - FILE *fp= fopen(filename, "rb"); + FILE *fp = fopen(filename, "rb"); #else - FILE *fp= fopen(filename, "r"); + FILE *fp = fopen(filename, "r"); #endif void *data; - if (!fp) { - *len_r= -1; + if (!fp) + { + *len_r = -1; return NULL; } fseek(fp, 0L, SEEK_END); - *len_r= ftell(fp); + *len_r = ftell(fp); fseek(fp, 0L, SEEK_SET); - data= malloc_and_setzero(*len_r); - if (!data) { - *len_r= -1; + data = malloc_and_setzero(*len_r); + if (!data) + { + *len_r = -1; fclose(fp); return NULL; } - if (fread(data, *len_r, 1, fp)!=1) { - *len_r= -1; + if (fread(data, *len_r, 1, fp) != 1) + { + *len_r = -1; free(data); fclose(fp); return NULL; } - + fclose(fp); return data; } +const char *skipStructTypes[] = + { + "btContactSolverInfoData", + "btRigidBodyConstructionInfo", + "Euler", + "btConstraintInfo2", + "btConstraintSetting", + "btTriangleInfo", + ""}; -const char* skipStructTypes[]= +int skipStruct(const char *structType) { - "btContactSolverInfoData", - "btRigidBodyConstructionInfo", - "Euler", - "btConstraintInfo2", - "btConstraintSetting", - "btTriangleInfo", - "" -}; - -int skipStruct(const char* structType) -{ - int i=0; + int i = 0; while (strlen(skipStructTypes[i])) { - if (strcmp(structType,skipStructTypes[i])==0) + if (strcmp(structType, skipStructTypes[i]) == 0) { return 1; } @@ -610,122 +642,128 @@ int convert_include(char *filename) int filelen, count, overslaan, slen, type, name, strct; short *structpoin, *sp; char *maindata, *mainend, *md, *md1; - - md= maindata= (char*)read_file_data(filename, &filelen); - if (filelen==-1) { + + md = maindata = (char *)read_file_data(filename, &filelen); + if (filelen == -1) + { printf("Can't read file %s\n", filename); return 1; } - filelen= preprocess_include(maindata, filelen); - mainend= maindata+filelen-1; + filelen = preprocess_include(maindata, filelen); + mainend = maindata + filelen - 1; /* we look for '{' and then back to 'struct' */ - count= 0; - overslaan= 0; - while(count 1) printf("\t|\t|-- detected struct %s\n", types[strct]); /* first lets make it all nice strings */ - md1= md+1; - while(*md1 != '}') { - if(md1>mainend) break; - - if(*md1==',' || *md1==' ') *md1= 0; + md1 = md + 1; + while (*md1 != '}') + { + if (md1 > mainend) break; + + if (*md1 == ',' || *md1 == ' ') *md1 = 0; md1++; } - + /* read types and names until first character that is not '}' */ - md1= md+1; - while( *md1 != '}' ) { - if(md1>mainend) break; - + md1 = md + 1; + while (*md1 != '}') + { + if (md1 > mainend) break; + /* skip when it says 'struct' or 'unsigned' or 'const' */ - if(*md1) { - if( strncmp(md1, "struct", 6)==0 ) md1+= 7; - if( strncmp(md1, "unsigned", 8)==0 ) md1+= 9; - if( strncmp(md1, "const", 5)==0 ) md1+= 6; - + if (*md1) + { + if (strncmp(md1, "struct", 6) == 0) md1 += 7; + if (strncmp(md1, "unsigned", 8) == 0) md1 += 9; + if (strncmp(md1, "const", 5) == 0) md1 += 6; + /* we've got a type! */ - type= add_type(md1, 0); + type = add_type(md1, 0); if (debugSDNA > 1) printf("\t|\t|\tfound type %s (", md1); - md1+= strlen(md1); + md1 += strlen(md1); - /* read until ';' */ - while( *md1 != ';' ) { - if(md1>mainend) break; - - if(*md1) { + while (*md1 != ';') + { + if (md1 > mainend) break; + + if (*md1) + { /* We've got a name. slen needs * correction for function * pointers! */ - slen= (int) strlen(md1); - if( md1[slen-1]==';' ) { - md1[slen-1]= 0; + slen = (int)strlen(md1); + if (md1[slen - 1] == ';') + { + md1[slen - 1] = 0; - - name= add_name(md1); + name = add_name(md1); slen += additional_slen_offset; - sp[0]= type; - sp[1]= name; + sp[0] = type; + sp[1] = name; - if ((debugSDNA>1) && (names[name] != 0 )) printf("%s |", names[name]); + if ((debugSDNA > 1) && (names[name] != 0)) printf("%s |", names[name]); structpoin[1]++; - sp+= 2; - - md1+= slen; + sp += 2; + + md1 += slen; break; } - - name= add_name(md1); + name = add_name(md1); slen += additional_slen_offset; - sp[0]= type; - sp[1]= name; - if ((debugSDNA > 1) && (names[name] != 0 )) printf("%s ||", names[name]); + sp[0] = type; + sp[1] = name; + if ((debugSDNA > 1) && (names[name] != 0)) printf("%s ||", names[name]); structpoin[1]++; - sp+= 2; - - md1+= slen; + sp += 2; + + md1 += slen; } md1++; } if (debugSDNA > 1) printf(")\n"); - } md1++; } @@ -736,7 +774,7 @@ int convert_include(char *filename) count++; md++; } - + free(maindata); return 0; @@ -744,177 +782,205 @@ int convert_include(char *filename) int arraysize(char *astr, int len) { - int a, mul=1; - char str[100], *cp=0; + int a, mul = 1; + char str[100], *cp = 0; - memcpy(str, astr, len+1); - - for(a=0; a= firststruct) { - if(sizeof(void *)==8 && (len % 8) ) { - printf("Align struct error: %s %s\n", types[structtype],cp); + if (type >= firststruct) + { + if (sizeof(void *) == 8 && (len % 8)) + { + printf("Align struct error: %s %s\n", types[structtype], cp); dna_error = 1; } } - + /* 2-4 aligned/ */ - if(typelens[type]>3 && (len % 4) ) { - printf("Align 4 error in struct: %s %s (add %d padding bytes)\n", types[structtype], cp, len%4); + if (typelens[type] > 3 && (len % 4)) + { + printf("Align 4 error in struct: %s %s (add %d padding bytes)\n", types[structtype], cp, len % 4); dna_error = 1; } - else if(typelens[type]==2 && (len % 2) ) { - printf("Align 2 error in struct: %s %s (add %d padding bytes)\n", types[structtype], cp, len%2); + else if (typelens[type] == 2 && (len % 2)) + { + printf("Align 2 error in struct: %s %s (add %d padding bytes)\n", types[structtype], cp, len % 2); dna_error = 1; } - len += mul*typelens[type]; + len += mul * typelens[type]; alphalen += mul * alphalens[type]; - - } else { - len= 0; + } + else + { + len = 0; alphalen = 0; break; } } - - if (len==0) { + + if (len == 0) + { unknown++; - } else { - typelens[structtype]= len; - alphalens[structtype]= alphalen; + } + else + { + typelens[structtype] = len; + alphalens[structtype] = alphalen; // two ways to detect if a struct contains a pointer: // has_pointer is set or alphalen != len - if (has_pointer || alphalen != len) { - if (alphalen % 8) { - printf("alphalen = %d len = %d\n",alphalen,len); - printf("Sizeerror 8 in struct: %s (add %d bytes)\n", types[structtype], alphalen%8); + if (has_pointer || alphalen != len) + { + if (alphalen % 8) + { + printf("alphalen = %d len = %d\n", alphalen, len); + printf("Sizeerror 8 in struct: %s (add %d bytes)\n", types[structtype], alphalen % 8); dna_error = 1; } } - - if(len % 4) { - printf("Sizeerror 4 in struct: %s (add %d bytes)\n", types[structtype], len%4); + + if (len % 4) + { + printf("Sizeerror 4 in struct: %s (add %d bytes)\n", types[structtype], len % 4); dna_error = 1; } - } } } - - if(unknown==lastunknown) break; + + if (unknown == lastunknown) break; } - - if(unknown) { + + if (unknown) + { printf("ERROR: still %d structs unknown\n", unknown); - if (debugSDNA) { + if (debugSDNA) + { printf("*** Known structs : \n"); - - for(a=0; a= MAX_DNA_LINE_LENGTH) { + if (linelength >= MAX_DNA_LINE_LENGTH) + { fprintf(file, "\n"); linelength = 0; } @@ -938,27 +1005,27 @@ void dna_write(FILE *file, void *pntr, int size) void printStructLenghts(void) { - int a, unknown= nr_structs, lastunknown, structtype; + int a, unknown = nr_structs, lastunknown, structtype; short *structpoin; printf("\n\n*** All detected structs:\n"); - while(unknown) { - lastunknown= unknown; - unknown= 0; - + while (unknown) + { + lastunknown = unknown; + unknown = 0; + /* check all structs... */ - for(a=0; a -1) { + + if (debugSDNA > -1) + { fflush(stdout); printf("Running makesdna at debug level %d\n", debugSDNA); - } - + /* the longest known struct is 50k, so we assume 100k is sufficent! */ - namedata= (char*)malloc_and_setzero(maxdata); - typedata= (char*)malloc_and_setzero(maxdata); - structdata= (short*)malloc_and_setzero(maxdata); - + namedata = (char *)malloc_and_setzero(maxdata); + typedata = (char *)malloc_and_setzero(maxdata); + structdata = (short *)malloc_and_setzero(maxdata); + /* a maximum of 5000 variables, must be sufficient? */ - names= (char**)malloc_and_setzero(sizeof(char *)*maxnr); - types= (char**)malloc_and_setzero(sizeof(char *)*maxnr); - typelens= (short*) malloc_and_setzero(sizeof(short)*maxnr); - alphalens= (short*)malloc_and_setzero(sizeof(short)*maxnr); - structs= (short**)malloc_and_setzero(sizeof(short)*maxnr); + names = (char **)malloc_and_setzero(sizeof(char *) * maxnr); + types = (char **)malloc_and_setzero(sizeof(char *) * maxnr); + typelens = (short *)malloc_and_setzero(sizeof(short) * maxnr); + alphalens = (short *)malloc_and_setzero(sizeof(short) * maxnr); + structs = (short **)malloc_and_setzero(sizeof(short) * maxnr); /* insertion of all known types */ /* watch it: uint is not allowed! use in structs an unsigned int */ - add_type("char", 1); /* 0 */ - add_type("uchar", 1); /* 1 */ - add_type("short", 2); /* 2 */ - add_type("ushort", 2); /* 3 */ - add_type("int", 4); /* 4 */ - add_type("long", 4); /* 5 */ /* should it be 8 on 64 bits? */ - add_type("ulong", 4); /* 6 */ - add_type("float", 4); /* 7 */ - add_type("double", 8); /* 8 */ - add_type("void", 0); /* 9 */ + add_type("char", 1); /* 0 */ + add_type("uchar", 1); /* 1 */ + add_type("short", 2); /* 2 */ + add_type("ushort", 2); /* 3 */ + add_type("int", 4); /* 4 */ + add_type("long", 4); /* 5 */ /* should it be 8 on 64 bits? */ + add_type("ulong", 4); /* 6 */ + add_type("float", 4); /* 7 */ + add_type("double", 8); /* 8 */ + add_type("void", 0); /* 9 */ // the defines above shouldn't be output in the padding file... firststruct = nr_types; - + /* add all include files defined in the global array */ /* Since the internal file+path name buffer has limited length, I do a */ /* little test first... */ /* Mind the breaking condition here! */ - if (debugSDNA) printf("\tStart of header scan:\n"); - for (i = 0; strlen(includefiles[i]); i++) { + if (debugSDNA) printf("\tStart of header scan:\n"); + for (i = 0; strlen(includefiles[i]); i++) + { sprintf(str, "%s%s", baseDirectory, includefiles[i]); - if (debugSDNA) printf("\t|-- Converting %s\n", str); - if (convert_include(str)) { + if (debugSDNA) printf("\t|-- Converting %s\n", str); + if (convert_include(str)) + { return (1); } } - if (debugSDNA) printf("\tFinished scanning %d headers.\n", i); + if (debugSDNA) printf("\tFinished scanning %d headers.\n", i); - if (calculate_structlens(firststruct)) { + if (calculate_structlens(firststruct)) + { // error - return(1); + return (1); } - /* FOR DEBUG */ if (debugSDNA > 1) { - int a,b; -/* short *elem; */ + int a, b; + /* short *elem; */ short num_types; printf("nr_names %d nr_types %d nr_structs %d\n", nr_names, nr_types, nr_structs); - for(a=0; a -1) printf("Writing file ... "); - - if(nr_names==0 || nr_structs==0); - else { + + if (nr_names == 0 || nr_structs == 0) + ; + else + { strcpy(str, "SDNA"); dna_write(file, str, 4); - + /* write names */ strcpy(str, "NAME"); dna_write(file, str, 4); - len= nr_names; + len = nr_names; dna_write(file, &len, 4); - + /* calculate size of datablock with strings */ - cp= names[nr_names-1]; - cp+= strlen(names[nr_names-1]) + 1; /* +1: null-terminator */ - len= (btintptr_t) (cp - (char*) names[0]); - len= (len+3) & ~3; + cp = names[nr_names - 1]; + cp += strlen(names[nr_names - 1]) + 1; /* +1: null-terminator */ + len = (btintptr_t)(cp - (char *)names[0]); + len = (len + 3) & ~3; dna_write(file, names[0], len); - + /* write TYPES */ strcpy(str, "TYPE"); dna_write(file, str, 4); - len= nr_types; + len = nr_types; dna_write(file, &len, 4); - + /* calculate datablock size */ - cp= types[nr_types-1]; - cp+= strlen(types[nr_types-1]) + 1; /* +1: null-terminator */ - len= (btintptr_t) (cp - (char*) types[0]); - len= (len+3) & ~3; - + cp = types[nr_types - 1]; + cp += strlen(types[nr_types - 1]) + 1; /* +1: null-terminator */ + len = (btintptr_t)(cp - (char *)types[0]); + len = (len + 3) & ~3; + dna_write(file, types[0], len); - + /* WRITE TYPELENGTHS */ strcpy(str, "TLEN"); dna_write(file, str, 4); - - len= 2*nr_types; - if(nr_types & 1) len+= 2; + + len = 2 * nr_types; + if (nr_types & 1) len += 2; dna_write(file, typelens, len); - + /* WRITE STRUCTS */ strcpy(str, "STRC"); dna_write(file, str, 4); - len= nr_structs; + len = nr_structs; dna_write(file, &len, 4); - + /* calc datablock size */ - sp= structs[nr_structs-1]; - sp+= 2+ 2*( sp[1] ); - len= (btintptr_t) ((char*) sp - (char*) structs[0]); - len= (len+3) & ~3; - + sp = structs[nr_structs - 1]; + sp += 2 + 2 * (sp[1]); + len = (btintptr_t)((char *)sp - (char *)structs[0]); + len = (len + 3) & ~3; + dna_write(file, structs[0], len); - + /* a simple dna padding test */ - if (0) { + if (0) + { FILE *fp; int a; - - fp= fopen("padding.c", "w"); - if(fp==NULL); - else { + fp = fopen("padding.c", "w"); + if (fp == NULL) + ; + else + { // add all include files defined in the global array - for (i = 0; strlen(includefiles[i]); i++) { + for (i = 0; strlen(includefiles[i]); i++) + { fprintf(fp, "#include \"%s%s\"\n", baseDirectory, includefiles[i]); } fprintf(fp, "main(){\n"); sp = typelens; sp += firststruct; - for(a=firststruct; a -1) printf("done.\n"); - - return(0); + + return (0); } /* ************************* END MAKE DNA ********************** */ static void make_bad_file(char *file) { - FILE *fp= fopen(file, "w"); + FILE *fp = fopen(file, "w"); fprintf(fp, "ERROR! Cannot make correct DNA.c file, STUPID!\n"); fclose(fp); } @@ -1169,18 +1248,18 @@ static void make_bad_file(char *file) #define BASE_HEADER "../" #endif -int main(int argc, char ** argv) +int main(int argc, char **argv) { -// printf("btCollisionObject=%d\n",sizeof(btCollisionObject)); -// printf("btCollisionObjectData=%d\n",sizeof(btCollisionObjectData)); -// printf("btTransform=%d\n",sizeof(btTransform)); -// printf("btTransformData=%d\n",sizeof(btTransformData)); -// -// btCollisionObject* bla = new btCollisionObject(); -// btCollisionObjectData* bla2 = new btCollisionObjectData(); + // printf("btCollisionObject=%d\n",sizeof(btCollisionObject)); + // printf("btCollisionObjectData=%d\n",sizeof(btCollisionObjectData)); + // printf("btTransform=%d\n",sizeof(btTransform)); + // printf("btTransformData=%d\n",sizeof(btTransformData)); + // + // btCollisionObject* bla = new btCollisionObject(); + // btCollisionObjectData* bla2 = new btCollisionObjectData(); //int offsetof(bla,m_hasAnisotropicFriction); -/* + /* btTransformData m_worldTransform; btTransform m_interpolationWorldTransform; btVector3 m_interpolationLinearVelocity; @@ -1210,54 +1289,66 @@ int main(int argc, char ** argv) FILE *file; int return_status = 0; - if (argc!=2 && argc!=3) { + if (argc != 2 && argc != 3) + { printf("Usage: %s outfile.c [base directory]\n", argv[0]); return_status = 1; - } else { + } + else + { file = fopen(argv[1], "w"); - if (!file) { - printf ("Unable to open file: %s\n", argv[1]); + if (!file) + { + printf("Unable to open file: %s\n", argv[1]); return_status = 1; - } else { + } + else + { char baseDirectory[256]; - if (argc==3) { + if (argc == 3) + { strcpy(baseDirectory, argv[2]); - } else { + } + else + { strcpy(baseDirectory, BASE_HEADER); } - if (sizeof(void*)==8) + if (sizeof(void *) == 8) { - fprintf (file, "char sBulletDNAstr64[]= {\n"); - } else + fprintf(file, "char sBulletDNAstr64[]= {\n"); + } + else { - fprintf (file, "char sBulletDNAstr[]= {\n"); + fprintf(file, "char sBulletDNAstr[]= {\n"); } - if (make_structDNA(baseDirectory, file)) { + if (make_structDNA(baseDirectory, file)) + { // error fclose(file); make_bad_file(argv[1]); return_status = 1; - } else { + } + else + { fprintf(file, "};\n"); - if (sizeof(void*)==8) + if (sizeof(void *) == 8) { fprintf(file, "int sBulletDNAlen64= sizeof(sBulletDNAstr64);\n"); - } else + } + else { fprintf(file, "int sBulletDNAlen= sizeof(sBulletDNAstr);\n"); } - + fclose(file); } } } - - return(return_status); + return (return_status); } - /* end of list */ diff --git a/Extras/VHACD/inc/btAlignedAllocator.h b/Extras/VHACD/inc/btAlignedAllocator.h index 4af0472af..37ee87c7e 100644 --- a/Extras/VHACD/inc/btAlignedAllocator.h +++ b/Extras/VHACD/inc/btAlignedAllocator.h @@ -25,10 +25,10 @@ subject to the following restrictions: #ifdef BT_DEBUG_MEMORY_ALLOCATIONS #define btAlignedAlloc(a, b) \ - btAlignedAllocInternal(a, b, __LINE__, __FILE__) + btAlignedAllocInternal(a, b, __LINE__, __FILE__) #define btAlignedFree(ptr) \ - btAlignedFreeInternal(ptr, __LINE__, __FILE__) + btAlignedFreeInternal(ptr, __LINE__, __FILE__) void* btAlignedAllocInternal(size_t size, int alignment, int line, char* filename); @@ -57,48 +57,54 @@ void btAlignedAllocSetCustomAligned(btAlignedAllocFunc* allocFunc, btAlignedFree ///The btAlignedAllocator is a portable class for aligned memory allocations. ///Default implementations for unaligned and aligned allocations can be overridden by a custom allocator using btAlignedAllocSetCustom and btAlignedAllocSetCustomAligned. template -class btAlignedAllocator { - - typedef btAlignedAllocator self_type; +class btAlignedAllocator +{ + typedef btAlignedAllocator self_type; public: - //just going down a list: - btAlignedAllocator() {} - /* + //just going down a list: + btAlignedAllocator() {} + /* btAlignedAllocator( const self_type & ) {} */ - template - btAlignedAllocator(const btAlignedAllocator&) {} + template + btAlignedAllocator(const btAlignedAllocator&) + { + } - typedef const T* const_pointer; - typedef const T& const_reference; - typedef T* pointer; - typedef T& reference; - typedef T value_type; + typedef const T* const_pointer; + typedef const T& const_reference; + typedef T* pointer; + typedef T& reference; + typedef T value_type; - pointer address(reference ref) const { return &ref; } - const_pointer address(const_reference ref) const { return &ref; } - pointer allocate(size_type n, const_pointer* hint = 0) - { - (void)hint; - return reinterpret_cast(btAlignedAlloc(sizeof(value_type) * n, Alignment)); - } - void construct(pointer ptr, const value_type& value) { new (ptr) value_type(value); } - void deallocate(pointer ptr) - { - btAlignedFree(reinterpret_cast(ptr)); - } - void destroy(pointer ptr) { ptr->~value_type(); } + pointer address(reference ref) const { return &ref; } + const_pointer address(const_reference ref) const { return &ref; } + pointer allocate(size_type n, const_pointer* hint = 0) + { + (void)hint; + return reinterpret_cast(btAlignedAlloc(sizeof(value_type) * n, Alignment)); + } + void construct(pointer ptr, const value_type& value) { new (ptr) value_type(value); } + void deallocate(pointer ptr) + { + btAlignedFree(reinterpret_cast(ptr)); + } + void destroy(pointer ptr) { ptr->~value_type(); } - template - struct rebind { - typedef btAlignedAllocator other; - }; - template - self_type& operator=(const btAlignedAllocator&) { return *this; } + template + struct rebind + { + typedef btAlignedAllocator other; + }; + template + self_type& operator=(const btAlignedAllocator&) + { + return *this; + } - friend bool operator==(const self_type&, const self_type&) { return true; } + friend bool operator==(const self_type&, const self_type&) { return true; } }; -#endif //BT_ALIGNED_ALLOCATOR +#endif //BT_ALIGNED_ALLOCATOR diff --git a/Extras/VHACD/inc/btAlignedObjectArray.h b/Extras/VHACD/inc/btAlignedObjectArray.h index 49413c856..14c46049a 100644 --- a/Extras/VHACD/inc/btAlignedObjectArray.h +++ b/Extras/VHACD/inc/btAlignedObjectArray.h @@ -17,7 +17,7 @@ subject to the following restrictions: #define BT_OBJECT_ARRAY__ #include "btAlignedAllocator.h" -#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE +#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE ///If the platform doesn't support placement new, you can disable BT_USE_PLACEMENT_NEW ///then the btAlignedObjectArray doesn't support objects with virtual methods, and non-trivial constructors/destructors @@ -27,422 +27,448 @@ subject to the following restrictions: #define BT_USE_PLACEMENT_NEW 1 //#define BT_USE_MEMCPY 1 //disable, because it is cumbersome to find out for each platform where memcpy is defined. It can be in or or otherwise... -#define BT_ALLOW_ARRAY_COPY_OPERATOR // enabling this can accidently perform deep copies of data if you are not careful +#define BT_ALLOW_ARRAY_COPY_OPERATOR // enabling this can accidently perform deep copies of data if you are not careful #ifdef BT_USE_MEMCPY #include #include -#endif //BT_USE_MEMCPY +#endif //BT_USE_MEMCPY #ifdef BT_USE_PLACEMENT_NEW -#include //for placement new -#endif //BT_USE_PLACEMENT_NEW +#include //for placement new +#endif //BT_USE_PLACEMENT_NEW ///The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods ///It is developed to replace stl::vector to avoid portability issues, including STL alignment issues to add SIMD/SSE data template //template -class btAlignedObjectArray { - btAlignedAllocator m_allocator; +class btAlignedObjectArray +{ + btAlignedAllocator m_allocator; - int m_size; - int m_capacity; - T* m_data; - //PCK: added this line - bool m_ownsMemory; + int m_size; + int m_capacity; + T* m_data; + //PCK: added this line + bool m_ownsMemory; #ifdef BT_ALLOW_ARRAY_COPY_OPERATOR public: - SIMD_FORCE_INLINE btAlignedObjectArray& operator=(const btAlignedObjectArray& other) - { - copyFromArray(other); - return *this; - } -#else //BT_ALLOW_ARRAY_COPY_OPERATOR + SIMD_FORCE_INLINE btAlignedObjectArray& operator=(const btAlignedObjectArray& other) + { + copyFromArray(other); + return *this; + } +#else //BT_ALLOW_ARRAY_COPY_OPERATOR private: - SIMD_FORCE_INLINE btAlignedObjectArray& operator=(const btAlignedObjectArray& other); -#endif //BT_ALLOW_ARRAY_COPY_OPERATOR + SIMD_FORCE_INLINE btAlignedObjectArray& operator=(const btAlignedObjectArray& other); +#endif //BT_ALLOW_ARRAY_COPY_OPERATOR protected: - SIMD_FORCE_INLINE int allocSize(int size) - { - return (size ? size * 2 : 1); - } - SIMD_FORCE_INLINE void copy(int start, int end, T* dest) const - { - int i; - for (i = start; i < end; ++i) + SIMD_FORCE_INLINE int allocSize(int size) + { + return (size ? size * 2 : 1); + } + SIMD_FORCE_INLINE void copy(int start, int end, T* dest) const + { + int i; + for (i = start; i < end; ++i) #ifdef BT_USE_PLACEMENT_NEW - new (&dest[i]) T(m_data[i]); + new (&dest[i]) T(m_data[i]); #else - dest[i] = m_data[i]; -#endif //BT_USE_PLACEMENT_NEW - } + dest[i] = m_data[i]; +#endif //BT_USE_PLACEMENT_NEW + } - SIMD_FORCE_INLINE void init() - { - //PCK: added this line - m_ownsMemory = true; - m_data = 0; - m_size = 0; - m_capacity = 0; - } - SIMD_FORCE_INLINE void destroy(int first, int last) - { - int i; - for (i = first; i < last; i++) { - m_data[i].~T(); - } - } + SIMD_FORCE_INLINE void init() + { + //PCK: added this line + m_ownsMemory = true; + m_data = 0; + m_size = 0; + m_capacity = 0; + } + SIMD_FORCE_INLINE void destroy(int first, int last) + { + int i; + for (i = first; i < last; i++) + { + m_data[i].~T(); + } + } - SIMD_FORCE_INLINE void* allocate(int size) - { - if (size) - return m_allocator.allocate(size); - return 0; - } + SIMD_FORCE_INLINE void* allocate(int size) + { + if (size) + return m_allocator.allocate(size); + return 0; + } - SIMD_FORCE_INLINE void deallocate() - { - if (m_data) { - //PCK: enclosed the deallocation in this block - if (m_ownsMemory) { - m_allocator.deallocate(m_data); - } - m_data = 0; - } - } + SIMD_FORCE_INLINE void deallocate() + { + if (m_data) + { + //PCK: enclosed the deallocation in this block + if (m_ownsMemory) + { + m_allocator.deallocate(m_data); + } + m_data = 0; + } + } public: - btAlignedObjectArray() - { - init(); - } + btAlignedObjectArray() + { + init(); + } - ~btAlignedObjectArray() - { - clear(); - } + ~btAlignedObjectArray() + { + clear(); + } - ///Generally it is best to avoid using the copy constructor of an btAlignedObjectArray, and use a (const) reference to the array instead. - btAlignedObjectArray(const btAlignedObjectArray& otherArray) - { - init(); + ///Generally it is best to avoid using the copy constructor of an btAlignedObjectArray, and use a (const) reference to the array instead. + btAlignedObjectArray(const btAlignedObjectArray& otherArray) + { + init(); - int otherSize = otherArray.size(); - resize(otherSize); - otherArray.copy(0, otherSize, m_data); - } + int otherSize = otherArray.size(); + resize(otherSize); + otherArray.copy(0, otherSize, m_data); + } - /// return the number of elements in the array - SIMD_FORCE_INLINE int size() const - { - return m_size; - } + /// return the number of elements in the array + SIMD_FORCE_INLINE int size() const + { + return m_size; + } - SIMD_FORCE_INLINE const T& at(int n) const - { - btAssert(n >= 0); - btAssert(n < size()); - return m_data[n]; - } + SIMD_FORCE_INLINE const T& at(int n) const + { + btAssert(n >= 0); + btAssert(n < size()); + return m_data[n]; + } - SIMD_FORCE_INLINE T& at(int n) - { - btAssert(n >= 0); - btAssert(n < size()); - return m_data[n]; - } + SIMD_FORCE_INLINE T& at(int n) + { + btAssert(n >= 0); + btAssert(n < size()); + return m_data[n]; + } - SIMD_FORCE_INLINE const T& operator[](int n) const - { - btAssert(n >= 0); - btAssert(n < size()); - return m_data[n]; - } + SIMD_FORCE_INLINE const T& operator[](int n) const + { + btAssert(n >= 0); + btAssert(n < size()); + return m_data[n]; + } - SIMD_FORCE_INLINE T& operator[](int n) - { - btAssert(n >= 0); - btAssert(n < size()); - return m_data[n]; - } + SIMD_FORCE_INLINE T& operator[](int n) + { + btAssert(n >= 0); + btAssert(n < size()); + return m_data[n]; + } - ///clear the array, deallocated memory. Generally it is better to use array.resize(0), to reduce performance overhead of run-time memory (de)allocations. - SIMD_FORCE_INLINE void clear() - { - destroy(0, size()); + ///clear the array, deallocated memory. Generally it is better to use array.resize(0), to reduce performance overhead of run-time memory (de)allocations. + SIMD_FORCE_INLINE void clear() + { + destroy(0, size()); - deallocate(); + deallocate(); - init(); - } + init(); + } - SIMD_FORCE_INLINE void pop_back() - { - btAssert(m_size > 0); - m_size--; - m_data[m_size].~T(); - } + SIMD_FORCE_INLINE void pop_back() + { + btAssert(m_size > 0); + m_size--; + m_data[m_size].~T(); + } - ///resize changes the number of elements in the array. If the new size is larger, the new elements will be constructed using the optional second argument. - ///when the new number of elements is smaller, the destructor will be called, but memory will not be freed, to reduce performance overhead of run-time memory (de)allocations. - SIMD_FORCE_INLINE void resize(int newsize, const T& fillData = T()) - { - int curSize = size(); + ///resize changes the number of elements in the array. If the new size is larger, the new elements will be constructed using the optional second argument. + ///when the new number of elements is smaller, the destructor will be called, but memory will not be freed, to reduce performance overhead of run-time memory (de)allocations. + SIMD_FORCE_INLINE void resize(int newsize, const T& fillData = T()) + { + int curSize = size(); - if (newsize < curSize) { - for (int i = newsize; i < curSize; i++) { - m_data[i].~T(); - } - } - else { - if (newsize > size()) { - reserve(newsize); - } + if (newsize < curSize) + { + for (int i = newsize; i < curSize; i++) + { + m_data[i].~T(); + } + } + else + { + if (newsize > size()) + { + reserve(newsize); + } #ifdef BT_USE_PLACEMENT_NEW - for (int i = curSize; i < newsize; i++) { - new (&m_data[i]) T(fillData); - } -#endif //BT_USE_PLACEMENT_NEW - } + for (int i = curSize; i < newsize; i++) + { + new (&m_data[i]) T(fillData); + } +#endif //BT_USE_PLACEMENT_NEW + } - m_size = newsize; - } + m_size = newsize; + } - SIMD_FORCE_INLINE T& expandNonInitializing() - { - int sz = size(); - if (sz == capacity()) { - reserve(allocSize(size())); - } - m_size++; + SIMD_FORCE_INLINE T& expandNonInitializing() + { + int sz = size(); + if (sz == capacity()) + { + reserve(allocSize(size())); + } + m_size++; - return m_data[sz]; - } + return m_data[sz]; + } - SIMD_FORCE_INLINE T& expand(const T& fillValue = T()) - { - int sz = size(); - if (sz == capacity()) { - reserve(allocSize(size())); - } - m_size++; + SIMD_FORCE_INLINE T& expand(const T& fillValue = T()) + { + int sz = size(); + if (sz == capacity()) + { + reserve(allocSize(size())); + } + m_size++; #ifdef BT_USE_PLACEMENT_NEW - new (&m_data[sz]) T(fillValue); //use the in-place new (not really allocating heap memory) + new (&m_data[sz]) T(fillValue); //use the in-place new (not really allocating heap memory) #endif - return m_data[sz]; - } + return m_data[sz]; + } - SIMD_FORCE_INLINE void push_back(const T& _Val) - { - int sz = size(); - if (sz == capacity()) { - reserve(allocSize(size())); - } + SIMD_FORCE_INLINE void push_back(const T& _Val) + { + int sz = size(); + if (sz == capacity()) + { + reserve(allocSize(size())); + } #ifdef BT_USE_PLACEMENT_NEW - new (&m_data[m_size]) T(_Val); + new (&m_data[m_size]) T(_Val); #else - m_data[size()] = _Val; -#endif //BT_USE_PLACEMENT_NEW + m_data[size()] = _Val; +#endif //BT_USE_PLACEMENT_NEW - m_size++; - } + m_size++; + } - /// return the pre-allocated (reserved) elements, this is at least as large as the total number of elements,see size() and reserve() - SIMD_FORCE_INLINE int capacity() const - { - return m_capacity; - } + /// return the pre-allocated (reserved) elements, this is at least as large as the total number of elements,see size() and reserve() + SIMD_FORCE_INLINE int capacity() const + { + return m_capacity; + } - SIMD_FORCE_INLINE void reserve(int _Count) - { // determine new minimum length of allocated storage - if (capacity() < _Count) { // not enough room, reallocate - T* s = (T*)allocate(_Count); + SIMD_FORCE_INLINE void reserve(int _Count) + { // determine new minimum length of allocated storage + if (capacity() < _Count) + { // not enough room, reallocate + T* s = (T*)allocate(_Count); - copy(0, size(), s); + copy(0, size(), s); - destroy(0, size()); + destroy(0, size()); - deallocate(); + deallocate(); - //PCK: added this line - m_ownsMemory = true; + //PCK: added this line + m_ownsMemory = true; - m_data = s; + m_data = s; - m_capacity = _Count; - } - } + m_capacity = _Count; + } + } - class less { - public: - bool operator()(const T& a, const T& b) - { - return (a < b); - } - }; + class less + { + public: + bool operator()(const T& a, const T& b) + { + return (a < b); + } + }; - template - void quickSortInternal(const L& CompareFunc, int lo, int hi) - { - // lo is the lower index, hi is the upper index - // of the region of array a that is to be sorted - int i = lo, j = hi; - T x = m_data[(lo + hi) / 2]; + template + void quickSortInternal(const L& CompareFunc, int lo, int hi) + { + // lo is the lower index, hi is the upper index + // of the region of array a that is to be sorted + int i = lo, j = hi; + T x = m_data[(lo + hi) / 2]; - // partition - do { - while (CompareFunc(m_data[i], x)) - i++; - while (CompareFunc(x, m_data[j])) - j--; - if (i <= j) { - swap(i, j); - i++; - j--; - } - } while (i <= j); + // partition + do + { + while (CompareFunc(m_data[i], x)) + i++; + while (CompareFunc(x, m_data[j])) + j--; + if (i <= j) + { + swap(i, j); + i++; + j--; + } + } while (i <= j); - // recursion - if (lo < j) - quickSortInternal(CompareFunc, lo, j); - if (i < hi) - quickSortInternal(CompareFunc, i, hi); - } + // recursion + if (lo < j) + quickSortInternal(CompareFunc, lo, j); + if (i < hi) + quickSortInternal(CompareFunc, i, hi); + } - template - void quickSort(const L& CompareFunc) - { - //don't sort 0 or 1 elements - if (size() > 1) { - quickSortInternal(CompareFunc, 0, size() - 1); - } - } + template + void quickSort(const L& CompareFunc) + { + //don't sort 0 or 1 elements + if (size() > 1) + { + quickSortInternal(CompareFunc, 0, size() - 1); + } + } - ///heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/ - template - void downHeap(T* pArr, int k, int n, const L& CompareFunc) - { - /* PRE: a[k+1..N] is a heap */ - /* POST: a[k..N] is a heap */ + ///heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/ + template + void downHeap(T* pArr, int k, int n, const L& CompareFunc) + { + /* PRE: a[k+1..N] is a heap */ + /* POST: a[k..N] is a heap */ - T temp = pArr[k - 1]; - /* k has child(s) */ - while (k <= n / 2) { - int child = 2 * k; + T temp = pArr[k - 1]; + /* k has child(s) */ + while (k <= n / 2) + { + int child = 2 * k; - if ((child < n) && CompareFunc(pArr[child - 1], pArr[child])) { - child++; - } - /* pick larger child */ - if (CompareFunc(temp, pArr[child - 1])) { - /* move child up */ - pArr[k - 1] = pArr[child - 1]; - k = child; - } - else { - break; - } - } - pArr[k - 1] = temp; - } /*downHeap*/ + if ((child < n) && CompareFunc(pArr[child - 1], pArr[child])) + { + child++; + } + /* pick larger child */ + if (CompareFunc(temp, pArr[child - 1])) + { + /* move child up */ + pArr[k - 1] = pArr[child - 1]; + k = child; + } + else + { + break; + } + } + pArr[k - 1] = temp; + } /*downHeap*/ - void swap(int index0, int index1) - { + void swap(int index0, int index1) + { #ifdef BT_USE_MEMCPY - char temp[sizeof(T)]; - memcpy(temp, &m_data[index0], sizeof(T)); - memcpy(&m_data[index0], &m_data[index1], sizeof(T)); - memcpy(&m_data[index1], temp, sizeof(T)); + char temp[sizeof(T)]; + memcpy(temp, &m_data[index0], sizeof(T)); + memcpy(&m_data[index0], &m_data[index1], sizeof(T)); + memcpy(&m_data[index1], temp, sizeof(T)); #else - T temp = m_data[index0]; - m_data[index0] = m_data[index1]; - m_data[index1] = temp; -#endif //BT_USE_PLACEMENT_NEW - } + T temp = m_data[index0]; + m_data[index0] = m_data[index1]; + m_data[index1] = temp; +#endif //BT_USE_PLACEMENT_NEW + } - template - void heapSort(const L& CompareFunc) - { - /* sort a[0..N-1], N.B. 0 to N-1 */ - int k; - int n = m_size; - for (k = n / 2; k > 0; k--) { - downHeap(m_data, k, n, CompareFunc); - } + template + void heapSort(const L& CompareFunc) + { + /* sort a[0..N-1], N.B. 0 to N-1 */ + int k; + int n = m_size; + for (k = n / 2; k > 0; k--) + { + downHeap(m_data, k, n, CompareFunc); + } - /* a[1..N] is now a heap */ - while (n >= 1) { - swap(0, n - 1); /* largest of a[0..n-1] */ + /* a[1..N] is now a heap */ + while (n >= 1) + { + swap(0, n - 1); /* largest of a[0..n-1] */ - n = n - 1; - /* restore a[1..i-1] heap */ - downHeap(m_data, 1, n, CompareFunc); - } - } + n = n - 1; + /* restore a[1..i-1] heap */ + downHeap(m_data, 1, n, CompareFunc); + } + } - ///non-recursive binary search, assumes sorted array - int findBinarySearch(const T& key) const - { - int first = 0; - int last = size() - 1; + ///non-recursive binary search, assumes sorted array + int findBinarySearch(const T& key) const + { + int first = 0; + int last = size() - 1; - //assume sorted array - while (first <= last) { - int mid = (first + last) / 2; // compute mid point. - if (key > m_data[mid]) - first = mid + 1; // repeat search in top half. - else if (key < m_data[mid]) - last = mid - 1; // repeat search in bottom half. - else - return mid; // found it. return position ///// - } - return size(); // failed to find key - } + //assume sorted array + while (first <= last) + { + int mid = (first + last) / 2; // compute mid point. + if (key > m_data[mid]) + first = mid + 1; // repeat search in top half. + else if (key < m_data[mid]) + last = mid - 1; // repeat search in bottom half. + else + return mid; // found it. return position ///// + } + return size(); // failed to find key + } - int findLinearSearch(const T& key) const - { - int index = size(); - int i; + int findLinearSearch(const T& key) const + { + int index = size(); + int i; - for (i = 0; i < size(); i++) { - if (m_data[i] == key) { - index = i; - break; - } - } - return index; - } + for (i = 0; i < size(); i++) + { + if (m_data[i] == key) + { + index = i; + break; + } + } + return index; + } - void remove(const T& key) - { + void remove(const T& key) + { + int findIndex = findLinearSearch(key); + if (findIndex < size()) + { + swap(findIndex, size() - 1); + pop_back(); + } + } - int findIndex = findLinearSearch(key); - if (findIndex < size()) { - swap(findIndex, size() - 1); - pop_back(); - } - } + //PCK: whole function + void initializeFromBuffer(void* buffer, int size, int capacity) + { + clear(); + m_ownsMemory = false; + m_data = (T*)buffer; + m_size = size; + m_capacity = capacity; + } - //PCK: whole function - void initializeFromBuffer(void* buffer, int size, int capacity) - { - clear(); - m_ownsMemory = false; - m_data = (T*)buffer; - m_size = size; - m_capacity = capacity; - } - - void copyFromArray(const btAlignedObjectArray& otherArray) - { - int otherSize = otherArray.size(); - resize(otherSize); - otherArray.copy(0, otherSize, m_data); - } + void copyFromArray(const btAlignedObjectArray& otherArray) + { + int otherSize = otherArray.size(); + resize(otherSize); + otherArray.copy(0, otherSize, m_data); + } }; -#endif //BT_OBJECT_ARRAY__ +#endif //BT_OBJECT_ARRAY__ diff --git a/Extras/VHACD/inc/btConvexHullComputer.h b/Extras/VHACD/inc/btConvexHullComputer.h index d59b81e5d..b855e84bf 100644 --- a/Extras/VHACD/inc/btConvexHullComputer.h +++ b/Extras/VHACD/inc/btConvexHullComputer.h @@ -21,56 +21,58 @@ subject to the following restrictions: /// Convex hull implementation based on Preparata and Hong /// See http://code.google.com/p/bullet/issues/detail?id=275 /// Ole Kniemeyer, MAXON Computer GmbH -class btConvexHullComputer { +class btConvexHullComputer +{ private: - btScalar compute(const void* coords, bool doubleCoords, int stride, int count, btScalar shrink, btScalar shrinkClamp); + btScalar compute(const void* coords, bool doubleCoords, int stride, int count, btScalar shrink, btScalar shrinkClamp); public: - class Edge { - private: - int next; - int reverse; - int targetVertex; + class Edge + { + private: + int next; + int reverse; + int targetVertex; - friend class btConvexHullComputer; + friend class btConvexHullComputer; - public: - int getSourceVertex() const - { - return (this + reverse)->targetVertex; - } + public: + int getSourceVertex() const + { + return (this + reverse)->targetVertex; + } - int getTargetVertex() const - { - return targetVertex; - } + int getTargetVertex() const + { + return targetVertex; + } - const Edge* getNextEdgeOfVertex() const // clockwise list of all edges of a vertex - { - return this + next; - } + const Edge* getNextEdgeOfVertex() const // clockwise list of all edges of a vertex + { + return this + next; + } - const Edge* getNextEdgeOfFace() const // counter-clockwise list of all edges of a face - { - return (this + reverse)->getNextEdgeOfVertex(); - } + const Edge* getNextEdgeOfFace() const // counter-clockwise list of all edges of a face + { + return (this + reverse)->getNextEdgeOfVertex(); + } - const Edge* getReverseEdge() const - { - return this + reverse; - } - }; + const Edge* getReverseEdge() const + { + return this + reverse; + } + }; - // Vertices of the output hull - btAlignedObjectArray vertices; + // Vertices of the output hull + btAlignedObjectArray vertices; - // Edges of the output hull - btAlignedObjectArray edges; + // Edges of the output hull + btAlignedObjectArray edges; - // Faces of the convex hull. Each entry is an index into the "edges" array pointing to an edge of the face. Faces are planar n-gons - btAlignedObjectArray faces; + // Faces of the convex hull. Each entry is an index into the "edges" array pointing to an edge of the face. Faces are planar n-gons + btAlignedObjectArray faces; - /* + /* Compute convex hull of "count" vertices stored in "coords". "stride" is the difference in bytes between the addresses of consecutive vertices. If "shrink" is positive, the convex hull is shrunken by that amount (each face is moved by "shrink" length units towards the center along its normal). @@ -82,16 +84,16 @@ public: The output convex hull can be found in the member variables "vertices", "edges", "faces". */ - btScalar compute(const float* coords, int stride, int count, btScalar shrink, btScalar shrinkClamp) - { - return compute(coords, false, stride, count, shrink, shrinkClamp); - } + btScalar compute(const float* coords, int stride, int count, btScalar shrink, btScalar shrinkClamp) + { + return compute(coords, false, stride, count, shrink, shrinkClamp); + } - // same as above, but double precision - btScalar compute(const double* coords, int stride, int count, btScalar shrink, btScalar shrinkClamp) - { - return compute(coords, true, stride, count, shrink, shrinkClamp); - } + // same as above, but double precision + btScalar compute(const double* coords, int stride, int count, btScalar shrink, btScalar shrinkClamp) + { + return compute(coords, true, stride, count, shrink, shrinkClamp); + } }; -#endif //BT_CONVEX_HULL_COMPUTER_H +#endif //BT_CONVEX_HULL_COMPUTER_H diff --git a/Extras/VHACD/inc/btMinMax.h b/Extras/VHACD/inc/btMinMax.h index 40b0ceb6e..92fea0275 100644 --- a/Extras/VHACD/inc/btMinMax.h +++ b/Extras/VHACD/inc/btMinMax.h @@ -20,46 +20,50 @@ subject to the following restrictions: template SIMD_FORCE_INLINE const T& btMin(const T& a, const T& b) { - return a < b ? a : b; + return a < b ? a : b; } template SIMD_FORCE_INLINE const T& btMax(const T& a, const T& b) { - return a > b ? a : b; + return a > b ? a : b; } template SIMD_FORCE_INLINE const T& btClamped(const T& a, const T& lb, const T& ub) { - return a < lb ? lb : (ub < a ? ub : a); + return a < lb ? lb : (ub < a ? ub : a); } template SIMD_FORCE_INLINE void btSetMin(T& a, const T& b) { - if (b < a) { - a = b; - } + if (b < a) + { + a = b; + } } template SIMD_FORCE_INLINE void btSetMax(T& a, const T& b) { - if (a < b) { - a = b; - } + if (a < b) + { + a = b; + } } template SIMD_FORCE_INLINE void btClamp(T& a, const T& lb, const T& ub) { - if (a < lb) { - a = lb; - } - else if (ub < a) { - a = ub; - } + if (a < lb) + { + a = lb; + } + else if (ub < a) + { + a = ub; + } } -#endif //BT_GEN_MINMAX_H +#endif //BT_GEN_MINMAX_H diff --git a/Extras/VHACD/inc/btScalar.h b/Extras/VHACD/inc/btScalar.h index ad3032497..0dd7264af 100644 --- a/Extras/VHACD/inc/btScalar.h +++ b/Extras/VHACD/inc/btScalar.h @@ -22,14 +22,14 @@ subject to the following restrictions: #include #include -#include //size_t for MSVC 6.0 +#include //size_t for MSVC 6.0 /* SVN $Revision$ on $Date$ from http://bullet.googlecode.com*/ #define BT_BULLET_VERSION 279 inline int btGetVersion() { - return BT_BULLET_VERSION; + return BT_BULLET_VERSION; } #if defined(DEBUG) || defined(_DEBUG) @@ -46,7 +46,7 @@ inline int btGetVersion() #define ATTRIBUTE_ALIGNED128(a) a #else //#define BT_HAS_ALIGNED_ALLOCATOR -#pragma warning(disable : 4324) // disable padding warning +#pragma warning(disable : 4324) // disable padding warning // #pragma warning(disable:4530) // Disable the exception disable but used in MSCV Stl warning. // #pragma warning(disable:4996) //Turn off warnings about deprecated C routines // #pragma warning(disable:4786) // Disable the "debug name too long" warning @@ -68,9 +68,9 @@ inline int btGetVersion() #include #endif -#endif //_XBOX +#endif //_XBOX -#endif //__MINGW32__ +#endif //__MINGW32__ #include #ifdef BT_DEBUG @@ -99,12 +99,13 @@ inline int btGetVersion() #include #define printf spu_printf #define btAssert(x) \ - { \ - if (!(x)) { \ - printf("Assert " __FILE__ ":%u (" #x ")\n", __LINE__); \ - spu_hcmpeq(0, 0); \ - } \ - } + { \ + if (!(x)) \ + { \ + printf("Assert " __FILE__ ":%u (" #x ")\n", __LINE__); \ + spu_hcmpeq(0, 0); \ + } \ + } #else #define btAssert assert #endif @@ -191,11 +192,11 @@ inline int btGetVersion() #define btFullAssert(x) #define btLikely(_c) _c #define btUnlikely(_c) _c -#endif //__APPLE__ +#endif //__APPLE__ -#endif // LIBSPE2 +#endif // LIBSPE2 -#endif //__CELLOS_LV2__ +#endif //__CELLOS_LV2__ #endif ///The btScalar type abstracts floating point numbers, to easily switch between double and single floating point precision. @@ -210,20 +211,20 @@ typedef float btScalar; #endif #define BT_DECLARE_ALIGNED_ALLOCATOR() \ - SIMD_FORCE_INLINE void* operator new(size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes, 16); } \ - SIMD_FORCE_INLINE void operator delete(void* ptr) { btAlignedFree(ptr); } \ - SIMD_FORCE_INLINE void* operator new(size_t, void* ptr) { return ptr; } \ - SIMD_FORCE_INLINE void operator delete(void*, void*) {} \ - SIMD_FORCE_INLINE void* operator new[](size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes, 16); } \ - SIMD_FORCE_INLINE void operator delete[](void* ptr) { btAlignedFree(ptr); } \ - SIMD_FORCE_INLINE void* operator new[](size_t, void* ptr) { return ptr; } \ - SIMD_FORCE_INLINE void operator delete[](void*, void*) {} + SIMD_FORCE_INLINE void* operator new(size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes, 16); } \ + SIMD_FORCE_INLINE void operator delete(void* ptr) { btAlignedFree(ptr); } \ + SIMD_FORCE_INLINE void* operator new(size_t, void* ptr) { return ptr; } \ + SIMD_FORCE_INLINE void operator delete(void*, void*) {} \ + SIMD_FORCE_INLINE void* operator new[](size_t sizeInBytes) { return btAlignedAlloc(sizeInBytes, 16); } \ + SIMD_FORCE_INLINE void operator delete[](void* ptr) { btAlignedFree(ptr); } \ + SIMD_FORCE_INLINE void* operator new[](size_t, void* ptr) { return ptr; } \ + SIMD_FORCE_INLINE void operator delete[](void*, void*) {} #if defined(BT_USE_DOUBLE_PRECISION) || defined(BT_FORCE_DOUBLE_FUNCTIONS) SIMD_FORCE_INLINE btScalar btSqrt(btScalar x) { - return sqrt(x); + return sqrt(x); } SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabs(x); } SIMD_FORCE_INLINE btScalar btCos(btScalar x) { return cos(x); } @@ -231,19 +232,19 @@ SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sin(x); } SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tan(x); } SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { - if (x < btScalar(-1)) - x = btScalar(-1); - if (x > btScalar(1)) - x = btScalar(1); - return acos(x); + if (x < btScalar(-1)) + x = btScalar(-1); + if (x > btScalar(1)) + x = btScalar(1); + return acos(x); } SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { - if (x < btScalar(-1)) - x = btScalar(-1); - if (x > btScalar(1)) - x = btScalar(1); - return asin(x); + if (x < btScalar(-1)) + x = btScalar(-1); + if (x > btScalar(1)) + x = btScalar(1); + return asin(x); } SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atan(x); } SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2(x, y); } @@ -257,21 +258,21 @@ SIMD_FORCE_INLINE btScalar btFmod(btScalar x, btScalar y) { return fmod(x, y); } SIMD_FORCE_INLINE btScalar btSqrt(btScalar y) { #ifdef USE_APPROXIMATION - double x, z, tempf; - unsigned long* tfptr = ((unsigned long*)&tempf) + 1; + double x, z, tempf; + unsigned long* tfptr = ((unsigned long*)&tempf) + 1; - tempf = y; - *tfptr = (0xbfcdd90a - *tfptr) >> 1; /* estimate of 1/sqrt(y) */ - x = tempf; - z = y * btScalar(0.5); - x = (btScalar(1.5) * x) - (x * x) * (x * z); /* iteration formula */ - x = (btScalar(1.5) * x) - (x * x) * (x * z); - x = (btScalar(1.5) * x) - (x * x) * (x * z); - x = (btScalar(1.5) * x) - (x * x) * (x * z); - x = (btScalar(1.5) * x) - (x * x) * (x * z); - return x * y; + tempf = y; + *tfptr = (0xbfcdd90a - *tfptr) >> 1; /* estimate of 1/sqrt(y) */ + x = tempf; + z = y * btScalar(0.5); + x = (btScalar(1.5) * x) - (x * x) * (x * z); /* iteration formula */ + x = (btScalar(1.5) * x) - (x * x) * (x * z); + x = (btScalar(1.5) * x) - (x * x) * (x * z); + x = (btScalar(1.5) * x) - (x * x) * (x * z); + x = (btScalar(1.5) * x) - (x * x) * (x * z); + return x * y; #else - return sqrtf(y); + return sqrtf(y); #endif } SIMD_FORCE_INLINE btScalar btFabs(btScalar x) { return fabsf(x); } @@ -280,19 +281,19 @@ SIMD_FORCE_INLINE btScalar btSin(btScalar x) { return sinf(x); } SIMD_FORCE_INLINE btScalar btTan(btScalar x) { return tanf(x); } SIMD_FORCE_INLINE btScalar btAcos(btScalar x) { - if (x < btScalar(-1)) - x = btScalar(-1); - if (x > btScalar(1)) - x = btScalar(1); - return acosf(x); + if (x < btScalar(-1)) + x = btScalar(-1); + if (x > btScalar(1)) + x = btScalar(1); + return acosf(x); } SIMD_FORCE_INLINE btScalar btAsin(btScalar x) { - if (x < btScalar(-1)) - x = btScalar(-1); - if (x > btScalar(1)) - x = btScalar(1); - return asinf(x); + if (x < btScalar(-1)) + x = btScalar(-1); + if (x > btScalar(1)) + x = btScalar(1); + return asinf(x); } SIMD_FORCE_INLINE btScalar btAtan(btScalar x) { return atanf(x); } SIMD_FORCE_INLINE btScalar btAtan2(btScalar x, btScalar y) { return atan2f(x, y); } @@ -322,117 +323,120 @@ SIMD_FORCE_INLINE btScalar btFmod(btScalar x, btScalar y) { return fmodf(x, y); SIMD_FORCE_INLINE btScalar btAtan2Fast(btScalar y, btScalar x) { - btScalar coeff_1 = SIMD_PI / 4.0f; - btScalar coeff_2 = 3.0f * coeff_1; - btScalar abs_y = btFabs(y); - btScalar angle; - if (x >= 0.0f) { - btScalar r = (x - abs_y) / (x + abs_y); - angle = coeff_1 - coeff_1 * r; - } - else { - btScalar r = (x + abs_y) / (abs_y - x); - angle = coeff_2 - coeff_1 * r; - } - return (y < 0.0f) ? -angle : angle; + btScalar coeff_1 = SIMD_PI / 4.0f; + btScalar coeff_2 = 3.0f * coeff_1; + btScalar abs_y = btFabs(y); + btScalar angle; + if (x >= 0.0f) + { + btScalar r = (x - abs_y) / (x + abs_y); + angle = coeff_1 - coeff_1 * r; + } + else + { + btScalar r = (x + abs_y) / (abs_y - x); + angle = coeff_2 - coeff_1 * r; + } + return (y < 0.0f) ? -angle : angle; } SIMD_FORCE_INLINE bool btFuzzyZero(btScalar x) { return btFabs(x) < SIMD_EPSILON; } SIMD_FORCE_INLINE bool btEqual(btScalar a, btScalar eps) { - return (((a) <= eps) && !((a) < -eps)); + return (((a) <= eps) && !((a) < -eps)); } SIMD_FORCE_INLINE bool btGreaterEqual(btScalar a, btScalar eps) { - return (!((a) <= eps)); + return (!((a) <= eps)); } SIMD_FORCE_INLINE int btIsNegative(btScalar x) { - return x < btScalar(0.0) ? 1 : 0; + return x < btScalar(0.0) ? 1 : 0; } SIMD_FORCE_INLINE btScalar btRadians(btScalar x) { return x * SIMD_RADS_PER_DEG; } SIMD_FORCE_INLINE btScalar btDegrees(btScalar x) { return x * SIMD_DEGS_PER_RAD; } #define BT_DECLARE_HANDLE(name) \ - typedef struct name##__ { \ - int unused; \ - } * name + typedef struct name##__ \ + { \ + int unused; \ + } * name #ifndef btFsel SIMD_FORCE_INLINE btScalar btFsel(btScalar a, btScalar b, btScalar c) { - return a >= 0 ? b : c; + return a >= 0 ? b : c; } #endif #define btFsels(a, b, c) (btScalar) btFsel(a, b, c) SIMD_FORCE_INLINE bool btMachineIsLittleEndian() { - long int i = 1; - const char* p = (const char*)&i; - if (p[0] == 1) // Lowest address contains the least significant byte - return true; - else - return false; + long int i = 1; + const char* p = (const char*)&i; + if (p[0] == 1) // Lowest address contains the least significant byte + return true; + else + return false; } ///btSelect avoids branches, which makes performance much better for consoles like Playstation 3 and XBox 360 ///Thanks Phil Knight. See also http://www.cellperformance.com/articles/2006/04/more_techniques_for_eliminatin_1.html SIMD_FORCE_INLINE unsigned btSelect(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero) { - // Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero - // Rely on positive value or'ed with its negative having sign bit on - // and zero value or'ed with its negative (which is still zero) having sign bit off - // Use arithmetic shift right, shifting the sign bit through all 32 bits - unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31); - unsigned testEqz = ~testNz; - return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); + // Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero + // Rely on positive value or'ed with its negative having sign bit on + // and zero value or'ed with its negative (which is still zero) having sign bit off + // Use arithmetic shift right, shifting the sign bit through all 32 bits + unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31); + unsigned testEqz = ~testNz; + return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); } SIMD_FORCE_INLINE int btSelect(unsigned condition, int valueIfConditionNonZero, int valueIfConditionZero) { - unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31); - unsigned testEqz = ~testNz; - return static_cast((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); + unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31); + unsigned testEqz = ~testNz; + return static_cast((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); } SIMD_FORCE_INLINE float btSelect(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero) { #ifdef BT_HAVE_NATIVE_FSEL - return (float)btFsel((btScalar)condition - btScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero); + return (float)btFsel((btScalar)condition - btScalar(1.0f), valueIfConditionNonZero, valueIfConditionZero); #else - return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero; + return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero; #endif } template SIMD_FORCE_INLINE void btSwap(T& a, T& b) { - T tmp = a; - a = b; - b = tmp; + T tmp = a; + a = b; + b = tmp; } //PCK: endian swapping functions SIMD_FORCE_INLINE unsigned btSwapEndian(unsigned val) { - return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); + return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); } SIMD_FORCE_INLINE unsigned short btSwapEndian(unsigned short val) { - return static_cast(((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)); + return static_cast(((val & 0xff00) >> 8) | ((val & 0x00ff) << 8)); } SIMD_FORCE_INLINE unsigned btSwapEndian(int val) { - return btSwapEndian((unsigned)val); + return btSwapEndian((unsigned)val); } SIMD_FORCE_INLINE unsigned short btSwapEndian(short val) { - return btSwapEndian((unsigned short)val); + return btSwapEndian((unsigned short)val); } ///btSwapFloat uses using char pointers to swap the endianness @@ -443,90 +447,94 @@ SIMD_FORCE_INLINE unsigned short btSwapEndian(short val) ///so instead of returning a float/double, we return integer/long long integer SIMD_FORCE_INLINE unsigned int btSwapEndianFloat(float d) { - unsigned int a = 0; - unsigned char* dst = (unsigned char*)&a; - unsigned char* src = (unsigned char*)&d; + unsigned int a = 0; + unsigned char* dst = (unsigned char*)&a; + unsigned char* src = (unsigned char*)&d; - dst[0] = src[3]; - dst[1] = src[2]; - dst[2] = src[1]; - dst[3] = src[0]; - return a; + dst[0] = src[3]; + dst[1] = src[2]; + dst[2] = src[1]; + dst[3] = src[0]; + return a; } // unswap using char pointers SIMD_FORCE_INLINE float btUnswapEndianFloat(unsigned int a) { - float d = 0.0f; - unsigned char* src = (unsigned char*)&a; - unsigned char* dst = (unsigned char*)&d; + float d = 0.0f; + unsigned char* src = (unsigned char*)&a; + unsigned char* dst = (unsigned char*)&d; - dst[0] = src[3]; - dst[1] = src[2]; - dst[2] = src[1]; - dst[3] = src[0]; + dst[0] = src[3]; + dst[1] = src[2]; + dst[2] = src[1]; + dst[3] = src[0]; - return d; + return d; } // swap using char pointers SIMD_FORCE_INLINE void btSwapEndianDouble(double d, unsigned char* dst) { - unsigned char* src = (unsigned char*)&d; + unsigned char* src = (unsigned char*)&d; - dst[0] = src[7]; - dst[1] = src[6]; - dst[2] = src[5]; - dst[3] = src[4]; - dst[4] = src[3]; - dst[5] = src[2]; - dst[6] = src[1]; - dst[7] = src[0]; + dst[0] = src[7]; + dst[1] = src[6]; + dst[2] = src[5]; + dst[3] = src[4]; + dst[4] = src[3]; + dst[5] = src[2]; + dst[6] = src[1]; + dst[7] = src[0]; } // unswap using char pointers SIMD_FORCE_INLINE double btUnswapEndianDouble(const unsigned char* src) { - double d = 0.0; - unsigned char* dst = (unsigned char*)&d; + double d = 0.0; + unsigned char* dst = (unsigned char*)&d; - dst[0] = src[7]; - dst[1] = src[6]; - dst[2] = src[5]; - dst[3] = src[4]; - dst[4] = src[3]; - dst[5] = src[2]; - dst[6] = src[1]; - dst[7] = src[0]; + dst[0] = src[7]; + dst[1] = src[6]; + dst[2] = src[5]; + dst[3] = src[4]; + dst[4] = src[3]; + dst[5] = src[2]; + dst[6] = src[1]; + dst[7] = src[0]; - return d; + return d; } // returns normalized value in range [-SIMD_PI, SIMD_PI] SIMD_FORCE_INLINE btScalar btNormalizeAngle(btScalar angleInRadians) { - angleInRadians = btFmod(angleInRadians, SIMD_2_PI); - if (angleInRadians < -SIMD_PI) { - return angleInRadians + SIMD_2_PI; - } - else if (angleInRadians > SIMD_PI) { - return angleInRadians - SIMD_2_PI; - } - else { - return angleInRadians; - } + angleInRadians = btFmod(angleInRadians, SIMD_2_PI); + if (angleInRadians < -SIMD_PI) + { + return angleInRadians + SIMD_2_PI; + } + else if (angleInRadians > SIMD_PI) + { + return angleInRadians - SIMD_2_PI; + } + else + { + return angleInRadians; + } } ///rudimentary class to provide type info -struct btTypedObject { - btTypedObject(int objectType) - : m_objectType(objectType) - { - } - int m_objectType; - inline int getObjectType() const - { - return m_objectType; - } +struct btTypedObject +{ + btTypedObject(int objectType) + : m_objectType(objectType) + { + } + int m_objectType; + inline int getObjectType() const + { + return m_objectType; + } }; -#endif //BT_SCALAR_H +#endif //BT_SCALAR_H diff --git a/Extras/VHACD/inc/btVector3.h b/Extras/VHACD/inc/btVector3.h index 159d67bdd..b9f001ca6 100644 --- a/Extras/VHACD/inc/btVector3.h +++ b/Extras/VHACD/inc/btVector3.h @@ -24,7 +24,7 @@ subject to the following restrictions: #else #define btVector3Data btVector3FloatData #define btVector3DataName "btVector3FloatData" -#endif //BT_USE_DOUBLE_PRECISION +#endif //BT_USE_DOUBLE_PRECISION /**@brief btVector3 can be used to represent 3D points and vectors. * It has an un-used w component to suit 16-byte alignment when btVector3 is stored in containers. This extra component can be used by derived classes (Quaternion?) or by user @@ -35,426 +35,426 @@ btVector3 { public: #if defined(__SPU__) && defined(__CELLOS_LV2__) - btScalar m_floats[4]; + btScalar m_floats[4]; public: - SIMD_FORCE_INLINE const vec_float4& get128() const - { - return *((const vec_float4*)&m_floats[0]); - } + SIMD_FORCE_INLINE const vec_float4& get128() const + { + return *((const vec_float4*)&m_floats[0]); + } public: -#else //__CELLOS_LV2__ __SPU__ -#ifdef BT_USE_SSE // _WIN32 - union { - __m128 mVec128; - btScalar m_floats[4]; - }; - SIMD_FORCE_INLINE __m128 get128() const - { - return mVec128; - } - SIMD_FORCE_INLINE void set128(__m128 v128) - { - mVec128 = v128; - } +#else //__CELLOS_LV2__ __SPU__ +#ifdef BT_USE_SSE // _WIN32 + union { + __m128 mVec128; + btScalar m_floats[4]; + }; + SIMD_FORCE_INLINE __m128 get128() const + { + return mVec128; + } + SIMD_FORCE_INLINE void set128(__m128 v128) + { + mVec128 = v128; + } #else - btScalar m_floats[4]; + btScalar m_floats[4]; #endif -#endif //__CELLOS_LV2__ __SPU__ +#endif //__CELLOS_LV2__ __SPU__ public: - /**@brief No initialization constructor */ - SIMD_FORCE_INLINE btVector3() {} + /**@brief No initialization constructor */ + SIMD_FORCE_INLINE btVector3() {} - /**@brief Constructor from scalars + /**@brief Constructor from scalars * @param x X value * @param y Y value * @param z Z value */ - SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z) - { - m_floats[0] = x; - m_floats[1] = y; - m_floats[2] = z; - m_floats[3] = btScalar(0.); - } + SIMD_FORCE_INLINE btVector3(const btScalar& x, const btScalar& y, const btScalar& z) + { + m_floats[0] = x; + m_floats[1] = y; + m_floats[2] = z; + m_floats[3] = btScalar(0.); + } - /**@brief Add a vector to this one + /**@brief Add a vector to this one * @param The vector to add to this one */ - SIMD_FORCE_INLINE btVector3& operator+=(const btVector3& v) - { + SIMD_FORCE_INLINE btVector3& operator+=(const btVector3& v) + { + m_floats[0] += v.m_floats[0]; + m_floats[1] += v.m_floats[1]; + m_floats[2] += v.m_floats[2]; + return *this; + } - m_floats[0] += v.m_floats[0]; - m_floats[1] += v.m_floats[1]; - m_floats[2] += v.m_floats[2]; - return *this; - } - - /**@brief Subtract a vector from this one + /**@brief Subtract a vector from this one * @param The vector to subtract */ - SIMD_FORCE_INLINE btVector3& operator-=(const btVector3& v) - { - m_floats[0] -= v.m_floats[0]; - m_floats[1] -= v.m_floats[1]; - m_floats[2] -= v.m_floats[2]; - return *this; - } - /**@brief Scale the vector + SIMD_FORCE_INLINE btVector3& operator-=(const btVector3& v) + { + m_floats[0] -= v.m_floats[0]; + m_floats[1] -= v.m_floats[1]; + m_floats[2] -= v.m_floats[2]; + return *this; + } + /**@brief Scale the vector * @param s Scale factor */ - SIMD_FORCE_INLINE btVector3& operator*=(const btScalar& s) - { - m_floats[0] *= s; - m_floats[1] *= s; - m_floats[2] *= s; - return *this; - } + SIMD_FORCE_INLINE btVector3& operator*=(const btScalar& s) + { + m_floats[0] *= s; + m_floats[1] *= s; + m_floats[2] *= s; + return *this; + } - /**@brief Inversely scale the vector + /**@brief Inversely scale the vector * @param s Scale factor to divide by */ - SIMD_FORCE_INLINE btVector3& operator/=(const btScalar& s) - { - btFullAssert(s != btScalar(0.0)); - return * this *= btScalar(1.0) / s; - } + SIMD_FORCE_INLINE btVector3& operator/=(const btScalar& s) + { + btFullAssert(s != btScalar(0.0)); + return *this *= btScalar(1.0) / s; + } - /**@brief Return the dot product + /**@brief Return the dot product * @param v The other vector in the dot product */ - SIMD_FORCE_INLINE btScalar dot(const btVector3& v) const - { - return m_floats[0] * v.m_floats[0] + m_floats[1] * v.m_floats[1] + m_floats[2] * v.m_floats[2]; - } + SIMD_FORCE_INLINE btScalar dot(const btVector3& v) const + { + return m_floats[0] * v.m_floats[0] + m_floats[1] * v.m_floats[1] + m_floats[2] * v.m_floats[2]; + } - /**@brief Return the length of the vector squared */ - SIMD_FORCE_INLINE btScalar length2() const - { - return dot(*this); - } + /**@brief Return the length of the vector squared */ + SIMD_FORCE_INLINE btScalar length2() const + { + return dot(*this); + } - /**@brief Return the length of the vector */ - SIMD_FORCE_INLINE btScalar length() const - { - return btSqrt(length2()); - } + /**@brief Return the length of the vector */ + SIMD_FORCE_INLINE btScalar length() const + { + return btSqrt(length2()); + } - /**@brief Return the distance squared between the ends of this and another vector + /**@brief Return the distance squared between the ends of this and another vector * This is symantically treating the vector like a point */ - SIMD_FORCE_INLINE btScalar distance2(const btVector3& v) const; + SIMD_FORCE_INLINE btScalar distance2(const btVector3& v) const; - /**@brief Return the distance between the ends of this and another vector + /**@brief Return the distance between the ends of this and another vector * This is symantically treating the vector like a point */ - SIMD_FORCE_INLINE btScalar distance(const btVector3& v) const; + SIMD_FORCE_INLINE btScalar distance(const btVector3& v) const; - SIMD_FORCE_INLINE btVector3& safeNormalize() - { - btVector3 absVec = this->absolute(); - int maxIndex = absVec.maxAxis(); - if (absVec[maxIndex] > 0) { - *this /= absVec[maxIndex]; - return * this /= length(); - } - setValue(1, 0, 0); - return *this; - } + SIMD_FORCE_INLINE btVector3& safeNormalize() + { + btVector3 absVec = this->absolute(); + int maxIndex = absVec.maxAxis(); + if (absVec[maxIndex] > 0) + { + *this /= absVec[maxIndex]; + return *this /= length(); + } + setValue(1, 0, 0); + return *this; + } - /**@brief Normalize this vector + /**@brief Normalize this vector * x^2 + y^2 + z^2 = 1 */ - SIMD_FORCE_INLINE btVector3& normalize() - { - return * this /= length(); - } + SIMD_FORCE_INLINE btVector3& normalize() + { + return *this /= length(); + } - /**@brief Return a normalized version of this vector */ - SIMD_FORCE_INLINE btVector3 normalized() const; + /**@brief Return a normalized version of this vector */ + SIMD_FORCE_INLINE btVector3 normalized() const; - /**@brief Return a rotated version of this vector + /**@brief Return a rotated version of this vector * @param wAxis The axis to rotate about * @param angle The angle to rotate by */ - SIMD_FORCE_INLINE btVector3 rotate(const btVector3& wAxis, const btScalar angle) const; + SIMD_FORCE_INLINE btVector3 rotate(const btVector3& wAxis, const btScalar angle) const; - /**@brief Return the angle between this and another vector + /**@brief Return the angle between this and another vector * @param v The other vector */ - SIMD_FORCE_INLINE btScalar angle(const btVector3& v) const - { - btScalar s = btSqrt(length2() * v.length2()); - btFullAssert(s != btScalar(0.0)); - return btAcos(dot(v) / s); - } - /**@brief Return a vector will the absolute values of each element */ - SIMD_FORCE_INLINE btVector3 absolute() const - { - return btVector3( - btFabs(m_floats[0]), - btFabs(m_floats[1]), - btFabs(m_floats[2])); - } - /**@brief Return the cross product between this and another vector + SIMD_FORCE_INLINE btScalar angle(const btVector3& v) const + { + btScalar s = btSqrt(length2() * v.length2()); + btFullAssert(s != btScalar(0.0)); + return btAcos(dot(v) / s); + } + /**@brief Return a vector will the absolute values of each element */ + SIMD_FORCE_INLINE btVector3 absolute() const + { + return btVector3( + btFabs(m_floats[0]), + btFabs(m_floats[1]), + btFabs(m_floats[2])); + } + /**@brief Return the cross product between this and another vector * @param v The other vector */ - SIMD_FORCE_INLINE btVector3 cross(const btVector3& v) const - { - return btVector3( - m_floats[1] * v.m_floats[2] - m_floats[2] * v.m_floats[1], - m_floats[2] * v.m_floats[0] - m_floats[0] * v.m_floats[2], - m_floats[0] * v.m_floats[1] - m_floats[1] * v.m_floats[0]); - } + SIMD_FORCE_INLINE btVector3 cross(const btVector3& v) const + { + return btVector3( + m_floats[1] * v.m_floats[2] - m_floats[2] * v.m_floats[1], + m_floats[2] * v.m_floats[0] - m_floats[0] * v.m_floats[2], + m_floats[0] * v.m_floats[1] - m_floats[1] * v.m_floats[0]); + } - SIMD_FORCE_INLINE btScalar triple(const btVector3& v1, const btVector3& v2) const - { - return m_floats[0] * (v1.m_floats[1] * v2.m_floats[2] - v1.m_floats[2] * v2.m_floats[1]) + m_floats[1] * (v1.m_floats[2] * v2.m_floats[0] - v1.m_floats[0] * v2.m_floats[2]) + m_floats[2] * (v1.m_floats[0] * v2.m_floats[1] - v1.m_floats[1] * v2.m_floats[0]); - } + SIMD_FORCE_INLINE btScalar triple(const btVector3& v1, const btVector3& v2) const + { + return m_floats[0] * (v1.m_floats[1] * v2.m_floats[2] - v1.m_floats[2] * v2.m_floats[1]) + m_floats[1] * (v1.m_floats[2] * v2.m_floats[0] - v1.m_floats[0] * v2.m_floats[2]) + m_floats[2] * (v1.m_floats[0] * v2.m_floats[1] - v1.m_floats[1] * v2.m_floats[0]); + } - /**@brief Return the axis with the smallest value + /**@brief Return the axis with the smallest value * Note return values are 0,1,2 for x, y, or z */ - SIMD_FORCE_INLINE int minAxis() const - { - return m_floats[0] < m_floats[1] ? (m_floats[0] < m_floats[2] ? 0 : 2) : (m_floats[1] < m_floats[2] ? 1 : 2); - } + SIMD_FORCE_INLINE int minAxis() const + { + return m_floats[0] < m_floats[1] ? (m_floats[0] < m_floats[2] ? 0 : 2) : (m_floats[1] < m_floats[2] ? 1 : 2); + } - /**@brief Return the axis with the largest value + /**@brief Return the axis with the largest value * Note return values are 0,1,2 for x, y, or z */ - SIMD_FORCE_INLINE int maxAxis() const - { - return m_floats[0] < m_floats[1] ? (m_floats[1] < m_floats[2] ? 2 : 1) : (m_floats[0] < m_floats[2] ? 2 : 0); - } + SIMD_FORCE_INLINE int maxAxis() const + { + return m_floats[0] < m_floats[1] ? (m_floats[1] < m_floats[2] ? 2 : 1) : (m_floats[0] < m_floats[2] ? 2 : 0); + } - SIMD_FORCE_INLINE int furthestAxis() const - { - return absolute().minAxis(); - } + SIMD_FORCE_INLINE int furthestAxis() const + { + return absolute().minAxis(); + } - SIMD_FORCE_INLINE int closestAxis() const - { - return absolute().maxAxis(); - } + SIMD_FORCE_INLINE int closestAxis() const + { + return absolute().maxAxis(); + } - SIMD_FORCE_INLINE void setInterpolate3(const btVector3& v0, const btVector3& v1, btScalar rt) - { - btScalar s = btScalar(1.0) - rt; - m_floats[0] = s * v0.m_floats[0] + rt * v1.m_floats[0]; - m_floats[1] = s * v0.m_floats[1] + rt * v1.m_floats[1]; - m_floats[2] = s * v0.m_floats[2] + rt * v1.m_floats[2]; - //don't do the unused w component - // m_co[3] = s * v0[3] + rt * v1[3]; - } + SIMD_FORCE_INLINE void setInterpolate3(const btVector3& v0, const btVector3& v1, btScalar rt) + { + btScalar s = btScalar(1.0) - rt; + m_floats[0] = s * v0.m_floats[0] + rt * v1.m_floats[0]; + m_floats[1] = s * v0.m_floats[1] + rt * v1.m_floats[1]; + m_floats[2] = s * v0.m_floats[2] + rt * v1.m_floats[2]; + //don't do the unused w component + // m_co[3] = s * v0[3] + rt * v1[3]; + } - /**@brief Return the linear interpolation between this and another vector + /**@brief Return the linear interpolation between this and another vector * @param v The other vector * @param t The ration of this to v (t = 0 => return this, t=1 => return other) */ - SIMD_FORCE_INLINE btVector3 lerp(const btVector3& v, const btScalar& t) const - { - return btVector3(m_floats[0] + (v.m_floats[0] - m_floats[0]) * t, - m_floats[1] + (v.m_floats[1] - m_floats[1]) * t, - m_floats[2] + (v.m_floats[2] - m_floats[2]) * t); - } + SIMD_FORCE_INLINE btVector3 lerp(const btVector3& v, const btScalar& t) const + { + return btVector3(m_floats[0] + (v.m_floats[0] - m_floats[0]) * t, + m_floats[1] + (v.m_floats[1] - m_floats[1]) * t, + m_floats[2] + (v.m_floats[2] - m_floats[2]) * t); + } - /**@brief Elementwise multiply this vector by the other + /**@brief Elementwise multiply this vector by the other * @param v The other vector */ - SIMD_FORCE_INLINE btVector3& operator*=(const btVector3& v) - { - m_floats[0] *= v.m_floats[0]; - m_floats[1] *= v.m_floats[1]; - m_floats[2] *= v.m_floats[2]; - return *this; - } + SIMD_FORCE_INLINE btVector3& operator*=(const btVector3& v) + { + m_floats[0] *= v.m_floats[0]; + m_floats[1] *= v.m_floats[1]; + m_floats[2] *= v.m_floats[2]; + return *this; + } - /**@brief Return the x value */ - SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; } - /**@brief Return the y value */ - SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; } - /**@brief Return the z value */ - SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; } - /**@brief Set the x value */ - SIMD_FORCE_INLINE void setX(btScalar x) { m_floats[0] = x; }; - /**@brief Set the y value */ - SIMD_FORCE_INLINE void setY(btScalar y) { m_floats[1] = y; }; - /**@brief Set the z value */ - SIMD_FORCE_INLINE void setZ(btScalar z) { m_floats[2] = z; }; - /**@brief Set the w value */ - SIMD_FORCE_INLINE void setW(btScalar w) { m_floats[3] = w; }; - /**@brief Return the x value */ - SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; } - /**@brief Return the y value */ - SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; } - /**@brief Return the z value */ - SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; } - /**@brief Return the w value */ - SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; } + /**@brief Return the x value */ + SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; } + /**@brief Return the y value */ + SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; } + /**@brief Return the z value */ + SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; } + /**@brief Set the x value */ + SIMD_FORCE_INLINE void setX(btScalar x) { m_floats[0] = x; }; + /**@brief Set the y value */ + SIMD_FORCE_INLINE void setY(btScalar y) { m_floats[1] = y; }; + /**@brief Set the z value */ + SIMD_FORCE_INLINE void setZ(btScalar z) { m_floats[2] = z; }; + /**@brief Set the w value */ + SIMD_FORCE_INLINE void setW(btScalar w) { m_floats[3] = w; }; + /**@brief Return the x value */ + SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; } + /**@brief Return the y value */ + SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; } + /**@brief Return the z value */ + SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; } + /**@brief Return the w value */ + SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; } - //SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_floats[0])[i]; } - //SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_floats[0])[i]; } - ///operator btScalar*() replaces operator[], using implicit conversion. We added operator != and operator == to avoid pointer comparisons. - SIMD_FORCE_INLINE operator btScalar*() { return &m_floats[0]; } - SIMD_FORCE_INLINE operator const btScalar*() const { return &m_floats[0]; } + //SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_floats[0])[i]; } + //SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_floats[0])[i]; } + ///operator btScalar*() replaces operator[], using implicit conversion. We added operator != and operator == to avoid pointer comparisons. + SIMD_FORCE_INLINE operator btScalar*() { return &m_floats[0]; } + SIMD_FORCE_INLINE operator const btScalar*() const { return &m_floats[0]; } - SIMD_FORCE_INLINE bool operator==(const btVector3& other) const - { - return ((m_floats[3] == other.m_floats[3]) && (m_floats[2] == other.m_floats[2]) && (m_floats[1] == other.m_floats[1]) && (m_floats[0] == other.m_floats[0])); - } + SIMD_FORCE_INLINE bool operator==(const btVector3& other) const + { + return ((m_floats[3] == other.m_floats[3]) && (m_floats[2] == other.m_floats[2]) && (m_floats[1] == other.m_floats[1]) && (m_floats[0] == other.m_floats[0])); + } - SIMD_FORCE_INLINE bool operator!=(const btVector3& other) const - { - return !(*this == other); - } + SIMD_FORCE_INLINE bool operator!=(const btVector3& other) const + { + return !(*this == other); + } - /**@brief Set each element to the max of the current values and the values of another btVector3 + /**@brief Set each element to the max of the current values and the values of another btVector3 * @param other The other btVector3 to compare with */ - SIMD_FORCE_INLINE void setMax(const btVector3& other) - { - btSetMax(m_floats[0], other.m_floats[0]); - btSetMax(m_floats[1], other.m_floats[1]); - btSetMax(m_floats[2], other.m_floats[2]); - btSetMax(m_floats[3], other.w()); - } - /**@brief Set each element to the min of the current values and the values of another btVector3 + SIMD_FORCE_INLINE void setMax(const btVector3& other) + { + btSetMax(m_floats[0], other.m_floats[0]); + btSetMax(m_floats[1], other.m_floats[1]); + btSetMax(m_floats[2], other.m_floats[2]); + btSetMax(m_floats[3], other.w()); + } + /**@brief Set each element to the min of the current values and the values of another btVector3 * @param other The other btVector3 to compare with */ - SIMD_FORCE_INLINE void setMin(const btVector3& other) - { - btSetMin(m_floats[0], other.m_floats[0]); - btSetMin(m_floats[1], other.m_floats[1]); - btSetMin(m_floats[2], other.m_floats[2]); - btSetMin(m_floats[3], other.w()); - } + SIMD_FORCE_INLINE void setMin(const btVector3& other) + { + btSetMin(m_floats[0], other.m_floats[0]); + btSetMin(m_floats[1], other.m_floats[1]); + btSetMin(m_floats[2], other.m_floats[2]); + btSetMin(m_floats[3], other.w()); + } - SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z) - { - m_floats[0] = x; - m_floats[1] = y; - m_floats[2] = z; - m_floats[3] = btScalar(0.); - } + SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z) + { + m_floats[0] = x; + m_floats[1] = y; + m_floats[2] = z; + m_floats[3] = btScalar(0.); + } - void getSkewSymmetricMatrix(btVector3 * v0, btVector3 * v1, btVector3 * v2) const - { - v0->setValue(0., -z(), y()); - v1->setValue(z(), 0., -x()); - v2->setValue(-y(), x(), 0.); - } + void getSkewSymmetricMatrix(btVector3 * v0, btVector3 * v1, btVector3 * v2) const + { + v0->setValue(0., -z(), y()); + v1->setValue(z(), 0., -x()); + v2->setValue(-y(), x(), 0.); + } - void setZero() - { - setValue(btScalar(0.), btScalar(0.), btScalar(0.)); - } + void setZero() + { + setValue(btScalar(0.), btScalar(0.), btScalar(0.)); + } - SIMD_FORCE_INLINE bool isZero() const - { - return m_floats[0] == btScalar(0) && m_floats[1] == btScalar(0) && m_floats[2] == btScalar(0); - } + SIMD_FORCE_INLINE bool isZero() const + { + return m_floats[0] == btScalar(0) && m_floats[1] == btScalar(0) && m_floats[2] == btScalar(0); + } - SIMD_FORCE_INLINE bool fuzzyZero() const - { - return length2() < SIMD_EPSILON; - } + SIMD_FORCE_INLINE bool fuzzyZero() const + { + return length2() < SIMD_EPSILON; + } - SIMD_FORCE_INLINE void serialize(struct btVector3Data & dataOut) const; + SIMD_FORCE_INLINE void serialize(struct btVector3Data & dataOut) const; - SIMD_FORCE_INLINE void deSerialize(const struct btVector3Data& dataIn); + SIMD_FORCE_INLINE void deSerialize(const struct btVector3Data& dataIn); - SIMD_FORCE_INLINE void serializeFloat(struct btVector3FloatData & dataOut) const; + SIMD_FORCE_INLINE void serializeFloat(struct btVector3FloatData & dataOut) const; - SIMD_FORCE_INLINE void deSerializeFloat(const struct btVector3FloatData& dataIn); + SIMD_FORCE_INLINE void deSerializeFloat(const struct btVector3FloatData& dataIn); - SIMD_FORCE_INLINE void serializeDouble(struct btVector3DoubleData & dataOut) const; + SIMD_FORCE_INLINE void serializeDouble(struct btVector3DoubleData & dataOut) const; - SIMD_FORCE_INLINE void deSerializeDouble(const struct btVector3DoubleData& dataIn); + SIMD_FORCE_INLINE void deSerializeDouble(const struct btVector3DoubleData& dataIn); }; /**@brief Return the sum of two vectors (Point symantics)*/ SIMD_FORCE_INLINE btVector3 operator+(const btVector3& v1, const btVector3& v2) { - return btVector3(v1.m_floats[0] + v2.m_floats[0], v1.m_floats[1] + v2.m_floats[1], v1.m_floats[2] + v2.m_floats[2]); + return btVector3(v1.m_floats[0] + v2.m_floats[0], v1.m_floats[1] + v2.m_floats[1], v1.m_floats[2] + v2.m_floats[2]); } /**@brief Return the elementwise product of two vectors */ SIMD_FORCE_INLINE btVector3 operator*(const btVector3& v1, const btVector3& v2) { - return btVector3(v1.m_floats[0] * v2.m_floats[0], v1.m_floats[1] * v2.m_floats[1], v1.m_floats[2] * v2.m_floats[2]); + return btVector3(v1.m_floats[0] * v2.m_floats[0], v1.m_floats[1] * v2.m_floats[1], v1.m_floats[2] * v2.m_floats[2]); } /**@brief Return the difference between two vectors */ SIMD_FORCE_INLINE btVector3 operator-(const btVector3& v1, const btVector3& v2) { - return btVector3(v1.m_floats[0] - v2.m_floats[0], v1.m_floats[1] - v2.m_floats[1], v1.m_floats[2] - v2.m_floats[2]); + return btVector3(v1.m_floats[0] - v2.m_floats[0], v1.m_floats[1] - v2.m_floats[1], v1.m_floats[2] - v2.m_floats[2]); } /**@brief Return the negative of the vector */ SIMD_FORCE_INLINE btVector3 operator-(const btVector3& v) { - return btVector3(-v.m_floats[0], -v.m_floats[1], -v.m_floats[2]); + return btVector3(-v.m_floats[0], -v.m_floats[1], -v.m_floats[2]); } /**@brief Return the vector scaled by s */ SIMD_FORCE_INLINE btVector3 operator*(const btVector3& v, const btScalar& s) { - return btVector3(v.m_floats[0] * s, v.m_floats[1] * s, v.m_floats[2] * s); + return btVector3(v.m_floats[0] * s, v.m_floats[1] * s, v.m_floats[2] * s); } /**@brief Return the vector scaled by s */ SIMD_FORCE_INLINE btVector3 operator*(const btScalar& s, const btVector3& v) { - return v * s; + return v * s; } /**@brief Return the vector inversely scaled by s */ SIMD_FORCE_INLINE btVector3 operator/(const btVector3& v, const btScalar& s) { - btFullAssert(s != btScalar(0.0)); - return v * (btScalar(1.0) / s); + btFullAssert(s != btScalar(0.0)); + return v * (btScalar(1.0) / s); } /**@brief Return the vector inversely scaled by s */ SIMD_FORCE_INLINE btVector3 operator/(const btVector3& v1, const btVector3& v2) { - return btVector3(v1.m_floats[0] / v2.m_floats[0], v1.m_floats[1] / v2.m_floats[1], v1.m_floats[2] / v2.m_floats[2]); + return btVector3(v1.m_floats[0] / v2.m_floats[0], v1.m_floats[1] / v2.m_floats[1], v1.m_floats[2] / v2.m_floats[2]); } /**@brief Return the dot product between two vectors */ SIMD_FORCE_INLINE btScalar btDot(const btVector3& v1, const btVector3& v2) { - return v1.dot(v2); + return v1.dot(v2); } /**@brief Return the distance squared between two vectors */ SIMD_FORCE_INLINE btScalar btDistance2(const btVector3& v1, const btVector3& v2) { - return v1.distance2(v2); + return v1.distance2(v2); } /**@brief Return the distance between two vectors */ SIMD_FORCE_INLINE btScalar btDistance(const btVector3& v1, const btVector3& v2) { - return v1.distance(v2); + return v1.distance(v2); } /**@brief Return the angle between two vectors */ SIMD_FORCE_INLINE btScalar btAngle(const btVector3& v1, const btVector3& v2) { - return v1.angle(v2); + return v1.angle(v2); } /**@brief Return the cross product of two vectors */ SIMD_FORCE_INLINE btVector3 btCross(const btVector3& v1, const btVector3& v2) { - return v1.cross(v2); + return v1.cross(v2); } SIMD_FORCE_INLINE btScalar btTriple(const btVector3& v1, const btVector3& v2, const btVector3& v3) { - return v1.triple(v2, v3); + return v1.triple(v2, v3); } /**@brief Return the linear interpolation between two vectors @@ -464,252 +464,266 @@ btTriple(const btVector3& v1, const btVector3& v2, const btVector3& v3) SIMD_FORCE_INLINE btVector3 lerp(const btVector3& v1, const btVector3& v2, const btScalar& t) { - return v1.lerp(v2, t); + return v1.lerp(v2, t); } SIMD_FORCE_INLINE btScalar btVector3::distance2(const btVector3& v) const { - return (v - *this).length2(); + return (v - *this).length2(); } SIMD_FORCE_INLINE btScalar btVector3::distance(const btVector3& v) const { - return (v - *this).length(); + return (v - *this).length(); } SIMD_FORCE_INLINE btVector3 btVector3::normalized() const { - return *this / length(); + return *this / length(); } SIMD_FORCE_INLINE btVector3 btVector3::rotate(const btVector3& wAxis, const btScalar angle) const { - // wAxis must be a unit lenght vector + // wAxis must be a unit lenght vector - btVector3 o = wAxis * wAxis.dot(*this); - btVector3 x = *this - o; - btVector3 y; + btVector3 o = wAxis * wAxis.dot(*this); + btVector3 x = *this - o; + btVector3 y; - y = wAxis.cross(*this); + y = wAxis.cross(*this); - return (o + x * btCos(angle) + y * btSin(angle)); + return (o + x * btCos(angle) + y * btSin(angle)); } -class btVector4 : public btVector3 { +class btVector4 : public btVector3 +{ public: - SIMD_FORCE_INLINE btVector4() {} + SIMD_FORCE_INLINE btVector4() {} - SIMD_FORCE_INLINE btVector4(const btScalar& x, const btScalar& y, const btScalar& z, const btScalar& w) - : btVector3(x, y, z) - { - m_floats[3] = w; - } + SIMD_FORCE_INLINE btVector4(const btScalar& x, const btScalar& y, const btScalar& z, const btScalar& w) + : btVector3(x, y, z) + { + m_floats[3] = w; + } - SIMD_FORCE_INLINE btVector4 absolute4() const - { - return btVector4( - btFabs(m_floats[0]), - btFabs(m_floats[1]), - btFabs(m_floats[2]), - btFabs(m_floats[3])); - } + SIMD_FORCE_INLINE btVector4 absolute4() const + { + return btVector4( + btFabs(m_floats[0]), + btFabs(m_floats[1]), + btFabs(m_floats[2]), + btFabs(m_floats[3])); + } - btScalar getW() const { return m_floats[3]; } + btScalar getW() const { return m_floats[3]; } - SIMD_FORCE_INLINE int maxAxis4() const - { - int maxIndex = -1; - btScalar maxVal = btScalar(-BT_LARGE_FLOAT); - if (m_floats[0] > maxVal) { - maxIndex = 0; - maxVal = m_floats[0]; - } - if (m_floats[1] > maxVal) { - maxIndex = 1; - maxVal = m_floats[1]; - } - if (m_floats[2] > maxVal) { - maxIndex = 2; - maxVal = m_floats[2]; - } - if (m_floats[3] > maxVal) { - maxIndex = 3; - } - return maxIndex; - } + SIMD_FORCE_INLINE int maxAxis4() const + { + int maxIndex = -1; + btScalar maxVal = btScalar(-BT_LARGE_FLOAT); + if (m_floats[0] > maxVal) + { + maxIndex = 0; + maxVal = m_floats[0]; + } + if (m_floats[1] > maxVal) + { + maxIndex = 1; + maxVal = m_floats[1]; + } + if (m_floats[2] > maxVal) + { + maxIndex = 2; + maxVal = m_floats[2]; + } + if (m_floats[3] > maxVal) + { + maxIndex = 3; + } + return maxIndex; + } - SIMD_FORCE_INLINE int minAxis4() const - { - int minIndex = -1; - btScalar minVal = btScalar(BT_LARGE_FLOAT); - if (m_floats[0] < minVal) { - minIndex = 0; - minVal = m_floats[0]; - } - if (m_floats[1] < minVal) { - minIndex = 1; - minVal = m_floats[1]; - } - if (m_floats[2] < minVal) { - minIndex = 2; - minVal = m_floats[2]; - } - if (m_floats[3] < minVal) { - minIndex = 3; - } + SIMD_FORCE_INLINE int minAxis4() const + { + int minIndex = -1; + btScalar minVal = btScalar(BT_LARGE_FLOAT); + if (m_floats[0] < minVal) + { + minIndex = 0; + minVal = m_floats[0]; + } + if (m_floats[1] < minVal) + { + minIndex = 1; + minVal = m_floats[1]; + } + if (m_floats[2] < minVal) + { + minIndex = 2; + minVal = m_floats[2]; + } + if (m_floats[3] < minVal) + { + minIndex = 3; + } - return minIndex; - } + return minIndex; + } - SIMD_FORCE_INLINE int closestAxis4() const - { - return absolute4().maxAxis4(); - } + SIMD_FORCE_INLINE int closestAxis4() const + { + return absolute4().maxAxis4(); + } - /**@brief Set x,y,z and zero w + /**@brief Set x,y,z and zero w * @param x Value of x * @param y Value of y * @param z Value of z */ - /* void getValue(btScalar *m) const + /* void getValue(btScalar *m) const { m[0] = m_floats[0]; m[1] = m_floats[1]; m[2] =m_floats[2]; } */ - /**@brief Set the values + /**@brief Set the values * @param x Value of x * @param y Value of y * @param z Value of z * @param w Value of w */ - SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z, const btScalar& w) - { - m_floats[0] = x; - m_floats[1] = y; - m_floats[2] = z; - m_floats[3] = w; - } + SIMD_FORCE_INLINE void setValue(const btScalar& x, const btScalar& y, const btScalar& z, const btScalar& w) + { + m_floats[0] = x; + m_floats[1] = y; + m_floats[2] = z; + m_floats[3] = w; + } }; ///btSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization SIMD_FORCE_INLINE void btSwapScalarEndian(const btScalar& sourceVal, btScalar& destVal) { #ifdef BT_USE_DOUBLE_PRECISION - unsigned char* dest = (unsigned char*)&destVal; - unsigned char* src = (unsigned char*)&sourceVal; - dest[0] = src[7]; - dest[1] = src[6]; - dest[2] = src[5]; - dest[3] = src[4]; - dest[4] = src[3]; - dest[5] = src[2]; - dest[6] = src[1]; - dest[7] = src[0]; + unsigned char* dest = (unsigned char*)&destVal; + unsigned char* src = (unsigned char*)&sourceVal; + dest[0] = src[7]; + dest[1] = src[6]; + dest[2] = src[5]; + dest[3] = src[4]; + dest[4] = src[3]; + dest[5] = src[2]; + dest[6] = src[1]; + dest[7] = src[0]; #else - unsigned char* dest = (unsigned char*)&destVal; - unsigned char* src = (unsigned char*)&sourceVal; - dest[0] = src[3]; - dest[1] = src[2]; - dest[2] = src[1]; - dest[3] = src[0]; -#endif //BT_USE_DOUBLE_PRECISION + unsigned char* dest = (unsigned char*)&destVal; + unsigned char* src = (unsigned char*)&sourceVal; + dest[0] = src[3]; + dest[1] = src[2]; + dest[2] = src[1]; + dest[3] = src[0]; +#endif //BT_USE_DOUBLE_PRECISION } ///btSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization SIMD_FORCE_INLINE void btSwapVector3Endian(const btVector3& sourceVec, btVector3& destVec) { - for (int i = 0; i < 4; i++) { - btSwapScalarEndian(sourceVec[i], destVec[i]); - } + for (int i = 0; i < 4; i++) + { + btSwapScalarEndian(sourceVec[i], destVec[i]); + } } ///btUnSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization SIMD_FORCE_INLINE void btUnSwapVector3Endian(btVector3& vector) { - - btVector3 swappedVec; - for (int i = 0; i < 4; i++) { - btSwapScalarEndian(vector[i], swappedVec[i]); - } - vector = swappedVec; + btVector3 swappedVec; + for (int i = 0; i < 4; i++) + { + btSwapScalarEndian(vector[i], swappedVec[i]); + } + vector = swappedVec; } template SIMD_FORCE_INLINE void btPlaneSpace1(const T& n, T& p, T& q) { - if (btFabs(n[2]) > SIMDSQRT12) { - // choose p in y-z plane - btScalar a = n[1] * n[1] + n[2] * n[2]; - btScalar k = btRecipSqrt(a); - p[0] = 0; - p[1] = -n[2] * k; - p[2] = n[1] * k; - // set q = n x p - q[0] = a * k; - q[1] = -n[0] * p[2]; - q[2] = n[0] * p[1]; - } - else { - // choose p in x-y plane - btScalar a = n[0] * n[0] + n[1] * n[1]; - btScalar k = btRecipSqrt(a); - p[0] = -n[1] * k; - p[1] = n[0] * k; - p[2] = 0; - // set q = n x p - q[0] = -n[2] * p[1]; - q[1] = n[2] * p[0]; - q[2] = a * k; - } + if (btFabs(n[2]) > SIMDSQRT12) + { + // choose p in y-z plane + btScalar a = n[1] * n[1] + n[2] * n[2]; + btScalar k = btRecipSqrt(a); + p[0] = 0; + p[1] = -n[2] * k; + p[2] = n[1] * k; + // set q = n x p + q[0] = a * k; + q[1] = -n[0] * p[2]; + q[2] = n[0] * p[1]; + } + else + { + // choose p in x-y plane + btScalar a = n[0] * n[0] + n[1] * n[1]; + btScalar k = btRecipSqrt(a); + p[0] = -n[1] * k; + p[1] = n[0] * k; + p[2] = 0; + // set q = n x p + q[0] = -n[2] * p[1]; + q[1] = n[2] * p[0]; + q[2] = a * k; + } } -struct btVector3FloatData { - float m_floats[4]; +struct btVector3FloatData +{ + float m_floats[4]; }; -struct btVector3DoubleData { - double m_floats[4]; +struct btVector3DoubleData +{ + double m_floats[4]; }; SIMD_FORCE_INLINE void btVector3::serializeFloat(struct btVector3FloatData& dataOut) const { - ///could also do a memcpy, check if it is worth it - for (int i = 0; i < 4; i++) - dataOut.m_floats[i] = float(m_floats[i]); + ///could also do a memcpy, check if it is worth it + for (int i = 0; i < 4; i++) + dataOut.m_floats[i] = float(m_floats[i]); } SIMD_FORCE_INLINE void btVector3::deSerializeFloat(const struct btVector3FloatData& dataIn) { - for (int i = 0; i < 4; i++) - m_floats[i] = btScalar(dataIn.m_floats[i]); + for (int i = 0; i < 4; i++) + m_floats[i] = btScalar(dataIn.m_floats[i]); } SIMD_FORCE_INLINE void btVector3::serializeDouble(struct btVector3DoubleData& dataOut) const { - ///could also do a memcpy, check if it is worth it - for (int i = 0; i < 4; i++) - dataOut.m_floats[i] = double(m_floats[i]); + ///could also do a memcpy, check if it is worth it + for (int i = 0; i < 4; i++) + dataOut.m_floats[i] = double(m_floats[i]); } SIMD_FORCE_INLINE void btVector3::deSerializeDouble(const struct btVector3DoubleData& dataIn) { - for (int i = 0; i < 4; i++) - m_floats[i] = btScalar(dataIn.m_floats[i]); + for (int i = 0; i < 4; i++) + m_floats[i] = btScalar(dataIn.m_floats[i]); } SIMD_FORCE_INLINE void btVector3::serialize(struct btVector3Data& dataOut) const { - ///could also do a memcpy, check if it is worth it - for (int i = 0; i < 4; i++) - dataOut.m_floats[i] = m_floats[i]; + ///could also do a memcpy, check if it is worth it + for (int i = 0; i < 4; i++) + dataOut.m_floats[i] = m_floats[i]; } SIMD_FORCE_INLINE void btVector3::deSerialize(const struct btVector3Data& dataIn) { - for (int i = 0; i < 4; i++) - m_floats[i] = dataIn.m_floats[i]; + for (int i = 0; i < 4; i++) + m_floats[i] = dataIn.m_floats[i]; } -#endif //BT_VECTOR3_H +#endif //BT_VECTOR3_H diff --git a/Extras/VHACD/inc/vhacdCircularList.h b/Extras/VHACD/inc/vhacdCircularList.h index 0f5ddf9ec..9e4b7ae3f 100644 --- a/Extras/VHACD/inc/vhacdCircularList.h +++ b/Extras/VHACD/inc/vhacdCircularList.h @@ -16,64 +16,69 @@ #ifndef VHACD_CIRCULAR_LIST_H #define VHACD_CIRCULAR_LIST_H #include -namespace VHACD { +namespace VHACD +{ //! CircularListElement class. template -class CircularListElement { +class CircularListElement +{ public: - T& GetData() { return m_data; } - const T& GetData() const { return m_data; } - CircularListElement*& GetNext() { return m_next; } - CircularListElement*& GetPrev() { return m_prev; } - const CircularListElement*& GetNext() const { return m_next; } - const CircularListElement*& GetPrev() const { return m_prev; } - //! Constructor - CircularListElement(const T& data) { m_data = data; } - CircularListElement(void) {} - //! Destructor - ~CircularListElement(void) {} -private: - T m_data; - CircularListElement* m_next; - CircularListElement* m_prev; + T& GetData() { return m_data; } + const T& GetData() const { return m_data; } + CircularListElement*& GetNext() { return m_next; } + CircularListElement*& GetPrev() { return m_prev; } + const CircularListElement*& GetNext() const { return m_next; } + const CircularListElement*& GetPrev() const { return m_prev; } + //! Constructor + CircularListElement(const T& data) { m_data = data; } + CircularListElement(void) {} + //! Destructor + ~CircularListElement(void) {} - CircularListElement(const CircularListElement& rhs); +private: + T m_data; + CircularListElement* m_next; + CircularListElement* m_prev; + + CircularListElement(const CircularListElement& rhs); }; //! CircularList class. template -class CircularList { +class CircularList +{ public: - CircularListElement*& GetHead() { return m_head; } - const CircularListElement* GetHead() const { return m_head; } - bool IsEmpty() const { return (m_size == 0); } - size_t GetSize() const { return m_size; } - const T& GetData() const { return m_head->GetData(); } - T& GetData() { return m_head->GetData(); } - bool Delete(); - bool Delete(CircularListElement* element); - CircularListElement* Add(const T* data = 0); - CircularListElement* Add(const T& data); - bool Next(); - bool Prev(); - void Clear() - { - while (Delete()) - ; - }; - const CircularList& operator=(const CircularList& rhs); - //! Constructor - CircularList() - { - m_head = 0; - m_size = 0; - } - CircularList(const CircularList& rhs); - //! Destructor - ~CircularList(void) { Clear(); }; + CircularListElement*& GetHead() { return m_head; } + const CircularListElement* GetHead() const { return m_head; } + bool IsEmpty() const { return (m_size == 0); } + size_t GetSize() const { return m_size; } + const T& GetData() const { return m_head->GetData(); } + T& GetData() { return m_head->GetData(); } + bool Delete(); + bool Delete(CircularListElement* element); + CircularListElement* Add(const T* data = 0); + CircularListElement* Add(const T& data); + bool Next(); + bool Prev(); + void Clear() + { + while (Delete()) + ; + }; + const CircularList& operator=(const CircularList& rhs); + //! Constructor + CircularList() + { + m_head = 0; + m_size = 0; + } + CircularList(const CircularList& rhs); + //! Destructor + ~CircularList(void) { Clear(); }; + private: - CircularListElement* m_head; //!< a pointer to the head of the circular list - size_t m_size; //!< number of element in the circular list + CircularListElement* m_head; //!< a pointer to the head of the circular list + size_t m_size; //!< number of element in the circular list }; -} +} // namespace VHACD #include "vhacdCircularList.inl" -#endif // VHACD_CIRCULAR_LIST_H \ No newline at end of file +#endif // VHACD_CIRCULAR_LIST_H \ No newline at end of file diff --git a/Extras/VHACD/inc/vhacdICHull.h b/Extras/VHACD/inc/vhacdICHull.h index a3d941651..ef799c600 100644 --- a/Extras/VHACD/inc/vhacdICHull.h +++ b/Extras/VHACD/inc/vhacdICHull.h @@ -18,81 +18,84 @@ #include "vhacdManifoldMesh.h" #include "vhacdVector.h" -namespace VHACD { +namespace VHACD +{ //! Incremental Convex Hull algorithm (cf. http://cs.smith.edu/~orourke/books/ftp.html ). -enum ICHullError { - ICHullErrorOK = 0, - ICHullErrorCoplanarPoints, - ICHullErrorNoVolume, - ICHullErrorInconsistent, - ICHullErrorNotEnoughPoints +enum ICHullError +{ + ICHullErrorOK = 0, + ICHullErrorCoplanarPoints, + ICHullErrorNoVolume, + ICHullErrorInconsistent, + ICHullErrorNotEnoughPoints }; -class ICHull { +class ICHull +{ public: - static const double sc_eps; - //! - bool IsFlat() { return m_isFlat; } - //! Returns the computed mesh - TMMesh& GetMesh() { return m_mesh; } - //! Add one point to the convex-hull - bool AddPoint(const Vec3& point) { return AddPoints(&point, 1); } - //! Add one point to the convex-hull - bool AddPoint(const Vec3& point, int id); - //! Add points to the convex-hull - bool AddPoints(const Vec3* points, size_t nPoints); - //! - ICHullError Process(); - //! - ICHullError Process(const unsigned int nPointsCH, const double minVolume = 0.0); - //! - bool IsInside(const Vec3& pt0, const double eps = 0.0); - //! - const ICHull& operator=(ICHull& rhs); + static const double sc_eps; + //! + bool IsFlat() { return m_isFlat; } + //! Returns the computed mesh + TMMesh& GetMesh() { return m_mesh; } + //! Add one point to the convex-hull + bool AddPoint(const Vec3& point) { return AddPoints(&point, 1); } + //! Add one point to the convex-hull + bool AddPoint(const Vec3& point, int id); + //! Add points to the convex-hull + bool AddPoints(const Vec3* points, size_t nPoints); + //! + ICHullError Process(); + //! + ICHullError Process(const unsigned int nPointsCH, const double minVolume = 0.0); + //! + bool IsInside(const Vec3& pt0, const double eps = 0.0); + //! + const ICHull& operator=(ICHull& rhs); - //! Constructor - ICHull(); - //! Destructor - ~ICHull(void){}; + //! Constructor + ICHull(); + //! Destructor + ~ICHull(void){}; private: - //! DoubleTriangle builds the initial double triangle. It first finds 3 noncollinear points and makes two faces out of them, in opposite order. It then finds a fourth point that is not coplanar with that face. The vertices are stored in the face structure in counterclockwise order so that the volume between the face and the point is negative. Lastly, the 3 newfaces to the fourth point are constructed and the data structures are cleaned up. - ICHullError DoubleTriangle(); - //! MakeFace creates a new face structure from three vertices (in ccw order). It returns a pointer to the face. - CircularListElement* MakeFace(CircularListElement* v0, - CircularListElement* v1, - CircularListElement* v2, - CircularListElement* fold); - //! - CircularListElement* MakeConeFace(CircularListElement* e, CircularListElement* v); - //! - bool ProcessPoint(); - //! - bool ComputePointVolume(double& totalVolume, bool markVisibleFaces); - //! - bool FindMaxVolumePoint(const double minVolume = 0.0); - //! - bool CleanEdges(); - //! - bool CleanVertices(unsigned int& addedPoints); - //! - bool CleanTriangles(); - //! - bool CleanUp(unsigned int& addedPoints); - //! - bool MakeCCW(CircularListElement* f, - CircularListElement* e, - CircularListElement* v); - void Clear(); + //! DoubleTriangle builds the initial double triangle. It first finds 3 noncollinear points and makes two faces out of them, in opposite order. It then finds a fourth point that is not coplanar with that face. The vertices are stored in the face structure in counterclockwise order so that the volume between the face and the point is negative. Lastly, the 3 newfaces to the fourth point are constructed and the data structures are cleaned up. + ICHullError DoubleTriangle(); + //! MakeFace creates a new face structure from three vertices (in ccw order). It returns a pointer to the face. + CircularListElement* MakeFace(CircularListElement* v0, + CircularListElement* v1, + CircularListElement* v2, + CircularListElement* fold); + //! + CircularListElement* MakeConeFace(CircularListElement* e, CircularListElement* v); + //! + bool ProcessPoint(); + //! + bool ComputePointVolume(double& totalVolume, bool markVisibleFaces); + //! + bool FindMaxVolumePoint(const double minVolume = 0.0); + //! + bool CleanEdges(); + //! + bool CleanVertices(unsigned int& addedPoints); + //! + bool CleanTriangles(); + //! + bool CleanUp(unsigned int& addedPoints); + //! + bool MakeCCW(CircularListElement* f, + CircularListElement* e, + CircularListElement* v); + void Clear(); private: - static const int sc_dummyIndex; - TMMesh m_mesh; - SArray*> m_edgesToDelete; - SArray*> m_edgesToUpdate; - SArray*> m_trianglesToDelete; - Vec3 m_normal; - bool m_isFlat; - ICHull(const ICHull& rhs); + static const int sc_dummyIndex; + TMMesh m_mesh; + SArray*> m_edgesToDelete; + SArray*> m_edgesToUpdate; + SArray*> m_trianglesToDelete; + Vec3 m_normal; + bool m_isFlat; + ICHull(const ICHull& rhs); }; -} -#endif // VHACD_ICHULL_H +} // namespace VHACD +#endif // VHACD_ICHULL_H diff --git a/Extras/VHACD/inc/vhacdManifoldMesh.h b/Extras/VHACD/inc/vhacdManifoldMesh.h index f178ad3d5..2c3ebe508 100644 --- a/Extras/VHACD/inc/vhacdManifoldMesh.h +++ b/Extras/VHACD/inc/vhacdManifoldMesh.h @@ -18,125 +18,130 @@ All rights reserved. #include "vhacdCircularList.h" #include "vhacdSArray.h" #include "vhacdVector.h" -namespace VHACD { +namespace VHACD +{ class TMMTriangle; class TMMEdge; class TMMesh; class ICHull; //! Vertex data structure used in a triangular manifold mesh (TMM). -class TMMVertex { +class TMMVertex +{ public: - void Initialize(); - TMMVertex(void); - ~TMMVertex(void); + void Initialize(); + TMMVertex(void); + ~TMMVertex(void); private: - Vec3 m_pos; - int m_name; - size_t m_id; - CircularListElement* m_duplicate; // pointer to incident cone edge (or NULL) - bool m_onHull; - bool m_tag; - TMMVertex(const TMMVertex& rhs); - friend class ICHull; - friend class TMMesh; - friend class TMMTriangle; - friend class TMMEdge; + Vec3 m_pos; + int m_name; + size_t m_id; + CircularListElement* m_duplicate; // pointer to incident cone edge (or NULL) + bool m_onHull; + bool m_tag; + TMMVertex(const TMMVertex& rhs); + friend class ICHull; + friend class TMMesh; + friend class TMMTriangle; + friend class TMMEdge; }; //! Edge data structure used in a triangular manifold mesh (TMM). -class TMMEdge { +class TMMEdge +{ public: - void Initialize(); - TMMEdge(void); - ~TMMEdge(void); + void Initialize(); + TMMEdge(void); + ~TMMEdge(void); private: - size_t m_id; - CircularListElement* m_triangles[2]; - CircularListElement* m_vertices[2]; - CircularListElement* m_newFace; - TMMEdge(const TMMEdge& rhs); - friend class ICHull; - friend class TMMTriangle; - friend class TMMVertex; - friend class TMMesh; + size_t m_id; + CircularListElement* m_triangles[2]; + CircularListElement* m_vertices[2]; + CircularListElement* m_newFace; + TMMEdge(const TMMEdge& rhs); + friend class ICHull; + friend class TMMTriangle; + friend class TMMVertex; + friend class TMMesh; }; //! Triangle data structure used in a triangular manifold mesh (TMM). -class TMMTriangle { +class TMMTriangle +{ public: - void Initialize(); - TMMTriangle(void); - ~TMMTriangle(void); + void Initialize(); + TMMTriangle(void); + ~TMMTriangle(void); private: - size_t m_id; - CircularListElement* m_edges[3]; - CircularListElement* m_vertices[3]; - bool m_visible; + size_t m_id; + CircularListElement* m_edges[3]; + CircularListElement* m_vertices[3]; + bool m_visible; - TMMTriangle(const TMMTriangle& rhs); - friend class ICHull; - friend class TMMesh; - friend class TMMVertex; - friend class TMMEdge; + TMMTriangle(const TMMTriangle& rhs); + friend class ICHull; + friend class TMMesh; + friend class TMMVertex; + friend class TMMEdge; }; //! triangular manifold mesh data structure. -class TMMesh { +class TMMesh +{ public: - //! Returns the number of vertices> - inline size_t GetNVertices() const { return m_vertices.GetSize(); } - //! Returns the number of edges - inline size_t GetNEdges() const { return m_edges.GetSize(); } - //! Returns the number of triangles - inline size_t GetNTriangles() const { return m_triangles.GetSize(); } - //! Returns the vertices circular list - inline const CircularList& GetVertices() const { return m_vertices; } - //! Returns the edges circular list - inline const CircularList& GetEdges() const { return m_edges; } - //! Returns the triangles circular list - inline const CircularList& GetTriangles() const { return m_triangles; } - //! Returns the vertices circular list - inline CircularList& GetVertices() { return m_vertices; } - //! Returns the edges circular list - inline CircularList& GetEdges() { return m_edges; } - //! Returns the triangles circular list - inline CircularList& GetTriangles() { return m_triangles; } - //! Add vertex to the mesh - CircularListElement* AddVertex() { return m_vertices.Add(); } - //! Add vertex to the mesh - CircularListElement* AddEdge() { return m_edges.Add(); } - //! Add vertex to the mesh - CircularListElement* AddTriangle() { return m_triangles.Add(); } - //! Print mesh information - void Print(); - //! - void GetIFS(Vec3* const points, Vec3* const triangles); - //! - void Clear(); - //! - void Copy(TMMesh& mesh); - //! - bool CheckConsistancy(); - //! - bool Normalize(); - //! - bool Denormalize(); - //! Constructor - TMMesh(); - //! Destructor - virtual ~TMMesh(void); + //! Returns the number of vertices> + inline size_t GetNVertices() const { return m_vertices.GetSize(); } + //! Returns the number of edges + inline size_t GetNEdges() const { return m_edges.GetSize(); } + //! Returns the number of triangles + inline size_t GetNTriangles() const { return m_triangles.GetSize(); } + //! Returns the vertices circular list + inline const CircularList& GetVertices() const { return m_vertices; } + //! Returns the edges circular list + inline const CircularList& GetEdges() const { return m_edges; } + //! Returns the triangles circular list + inline const CircularList& GetTriangles() const { return m_triangles; } + //! Returns the vertices circular list + inline CircularList& GetVertices() { return m_vertices; } + //! Returns the edges circular list + inline CircularList& GetEdges() { return m_edges; } + //! Returns the triangles circular list + inline CircularList& GetTriangles() { return m_triangles; } + //! Add vertex to the mesh + CircularListElement* AddVertex() { return m_vertices.Add(); } + //! Add vertex to the mesh + CircularListElement* AddEdge() { return m_edges.Add(); } + //! Add vertex to the mesh + CircularListElement* AddTriangle() { return m_triangles.Add(); } + //! Print mesh information + void Print(); + //! + void GetIFS(Vec3* const points, Vec3* const triangles); + //! + void Clear(); + //! + void Copy(TMMesh& mesh); + //! + bool CheckConsistancy(); + //! + bool Normalize(); + //! + bool Denormalize(); + //! Constructor + TMMesh(); + //! Destructor + virtual ~TMMesh(void); private: - CircularList m_vertices; - CircularList m_edges; - CircularList m_triangles; + CircularList m_vertices; + CircularList m_edges; + CircularList m_triangles; - // not defined - TMMesh(const TMMesh& rhs); - friend class ICHull; + // not defined + TMMesh(const TMMesh& rhs); + friend class ICHull; }; -} -#endif // VHACD_MANIFOLD_MESH_H \ No newline at end of file +} // namespace VHACD +#endif // VHACD_MANIFOLD_MESH_H \ No newline at end of file diff --git a/Extras/VHACD/inc/vhacdMesh.h b/Extras/VHACD/inc/vhacdMesh.h index 0975d8e1f..a617fc8ca 100644 --- a/Extras/VHACD/inc/vhacdMesh.h +++ b/Extras/VHACD/inc/vhacdMesh.h @@ -20,110 +20,114 @@ #define VHACD_DEBUG_MESH -namespace VHACD { -enum AXIS { - AXIS_X = 0, - AXIS_Y = 1, - AXIS_Z = 2 +namespace VHACD +{ +enum AXIS +{ + AXIS_X = 0, + AXIS_Y = 1, + AXIS_Z = 2 }; -struct Plane { - double m_a; - double m_b; - double m_c; - double m_d; - AXIS m_axis; - short m_index; +struct Plane +{ + double m_a; + double m_b; + double m_c; + double m_d; + AXIS m_axis; + short m_index; }; #ifdef VHACD_DEBUG_MESH -struct Material { - - Vec3 m_diffuseColor; - double m_ambientIntensity; - Vec3 m_specularColor; - Vec3 m_emissiveColor; - double m_shininess; - double m_transparency; - Material(void) - { - m_diffuseColor.X() = 0.5; - m_diffuseColor.Y() = 0.5; - m_diffuseColor.Z() = 0.5; - m_specularColor.X() = 0.5; - m_specularColor.Y() = 0.5; - m_specularColor.Z() = 0.5; - m_ambientIntensity = 0.4; - m_emissiveColor.X() = 0.0; - m_emissiveColor.Y() = 0.0; - m_emissiveColor.Z() = 0.0; - m_shininess = 0.4; - m_transparency = 0.0; - }; +struct Material +{ + Vec3 m_diffuseColor; + double m_ambientIntensity; + Vec3 m_specularColor; + Vec3 m_emissiveColor; + double m_shininess; + double m_transparency; + Material(void) + { + m_diffuseColor.X() = 0.5; + m_diffuseColor.Y() = 0.5; + m_diffuseColor.Z() = 0.5; + m_specularColor.X() = 0.5; + m_specularColor.Y() = 0.5; + m_specularColor.Z() = 0.5; + m_ambientIntensity = 0.4; + m_emissiveColor.X() = 0.0; + m_emissiveColor.Y() = 0.0; + m_emissiveColor.Z() = 0.0; + m_shininess = 0.4; + m_transparency = 0.0; + }; }; -#endif // VHACD_DEBUG_MESH +#endif // VHACD_DEBUG_MESH //! Triangular mesh data structure -class Mesh { +class Mesh +{ public: - void AddPoint(const Vec3& pt) { m_points.PushBack(pt); }; - void SetPoint(size_t index, const Vec3& pt) { m_points[index] = pt; }; - const Vec3& GetPoint(size_t index) const { return m_points[index]; }; - Vec3& GetPoint(size_t index) { return m_points[index]; }; - size_t GetNPoints() const { return m_points.Size(); }; - double* GetPoints() { return (double*)m_points.Data(); } // ugly - const double* const GetPoints() const { return (double*)m_points.Data(); } // ugly - const Vec3* const GetPointsBuffer() const { return m_points.Data(); } // - Vec3* const GetPointsBuffer() { return m_points.Data(); } // - void AddTriangle(const Vec3& tri) { m_triangles.PushBack(tri); }; - void SetTriangle(size_t index, const Vec3& tri) { m_triangles[index] = tri; }; - const Vec3& GetTriangle(size_t index) const { return m_triangles[index]; }; - Vec3& GetTriangle(size_t index) { return m_triangles[index]; }; - size_t GetNTriangles() const { return m_triangles.Size(); }; - int* GetTriangles() { return (int*)m_triangles.Data(); } // ugly - const int* const GetTriangles() const { return (int*)m_triangles.Data(); } // ugly - const Vec3* const GetTrianglesBuffer() const { return m_triangles.Data(); } - Vec3* const GetTrianglesBuffer() { return m_triangles.Data(); } - const Vec3& GetCenter() const { return m_center; } - const Vec3& GetMinBB() const { return m_minBB; } - const Vec3& GetMaxBB() const { return m_maxBB; } - void ClearPoints() { m_points.Clear(); } - void ClearTriangles() { m_triangles.Clear(); } - void Clear() - { - ClearPoints(); - ClearTriangles(); - } - void ResizePoints(size_t nPts) { m_points.Resize(nPts); } - void ResizeTriangles(size_t nTri) { m_triangles.Resize(nTri); } - void CopyPoints(SArray >& points) const { points = m_points; } - double GetDiagBB() const { return m_diag; } - double ComputeVolume() const; - void ComputeConvexHull(const double* const pts, - const size_t nPts); - void Clip(const Plane& plane, - SArray >& positivePart, - SArray >& negativePart) const; - bool IsInside(const Vec3& pt) const; - double ComputeDiagBB(); + void AddPoint(const Vec3& pt) { m_points.PushBack(pt); }; + void SetPoint(size_t index, const Vec3& pt) { m_points[index] = pt; }; + const Vec3& GetPoint(size_t index) const { return m_points[index]; }; + Vec3& GetPoint(size_t index) { return m_points[index]; }; + size_t GetNPoints() const { return m_points.Size(); }; + double* GetPoints() { return (double*)m_points.Data(); } // ugly + const double* const GetPoints() const { return (double*)m_points.Data(); } // ugly + const Vec3* const GetPointsBuffer() const { return m_points.Data(); } // + Vec3* const GetPointsBuffer() { return m_points.Data(); } // + void AddTriangle(const Vec3& tri) { m_triangles.PushBack(tri); }; + void SetTriangle(size_t index, const Vec3& tri) { m_triangles[index] = tri; }; + const Vec3& GetTriangle(size_t index) const { return m_triangles[index]; }; + Vec3& GetTriangle(size_t index) { return m_triangles[index]; }; + size_t GetNTriangles() const { return m_triangles.Size(); }; + int* GetTriangles() { return (int*)m_triangles.Data(); } // ugly + const int* const GetTriangles() const { return (int*)m_triangles.Data(); } // ugly + const Vec3* const GetTrianglesBuffer() const { return m_triangles.Data(); } + Vec3* const GetTrianglesBuffer() { return m_triangles.Data(); } + const Vec3& GetCenter() const { return m_center; } + const Vec3& GetMinBB() const { return m_minBB; } + const Vec3& GetMaxBB() const { return m_maxBB; } + void ClearPoints() { m_points.Clear(); } + void ClearTriangles() { m_triangles.Clear(); } + void Clear() + { + ClearPoints(); + ClearTriangles(); + } + void ResizePoints(size_t nPts) { m_points.Resize(nPts); } + void ResizeTriangles(size_t nTri) { m_triangles.Resize(nTri); } + void CopyPoints(SArray >& points) const { points = m_points; } + double GetDiagBB() const { return m_diag; } + double ComputeVolume() const; + void ComputeConvexHull(const double* const pts, + const size_t nPts); + void Clip(const Plane& plane, + SArray >& positivePart, + SArray >& negativePart) const; + bool IsInside(const Vec3& pt) const; + double ComputeDiagBB(); #ifdef VHACD_DEBUG_MESH - bool LoadOFF(const std::string& fileName, bool invert); - bool SaveVRML2(const std::string& fileName) const; - bool SaveVRML2(std::ofstream& fout, const Material& material) const; - bool SaveOFF(const std::string& fileName) const; -#endif // VHACD_DEBUG_MESH + bool LoadOFF(const std::string& fileName, bool invert); + bool SaveVRML2(const std::string& fileName) const; + bool SaveVRML2(std::ofstream& fout, const Material& material) const; + bool SaveOFF(const std::string& fileName) const; +#endif // VHACD_DEBUG_MESH - //! Constructor. - Mesh(); - //! Destructor. - ~Mesh(void); + //! Constructor. + Mesh(); + //! Destructor. + ~Mesh(void); private: - SArray > m_points; - SArray > m_triangles; - Vec3 m_minBB; - Vec3 m_maxBB; - Vec3 m_center; - double m_diag; + SArray > m_points; + SArray > m_triangles; + Vec3 m_minBB; + Vec3 m_maxBB; + Vec3 m_center; + double m_diag; }; -} +} // namespace VHACD #endif \ No newline at end of file diff --git a/Extras/VHACD/inc/vhacdMutex.h b/Extras/VHACD/inc/vhacdMutex.h index a28f6be61..4d1ad2a7d 100644 --- a/Extras/VHACD/inc/vhacdMutex.h +++ b/Extras/VHACD/inc/vhacdMutex.h @@ -82,65 +82,67 @@ #define VHACD_VERIFY(x) assert((x)) #endif -namespace VHACD { -class Mutex { +namespace VHACD +{ +class Mutex +{ public: - Mutex(void) - { + Mutex(void) + { #if defined(WIN32) || defined(_XBOX) - InitializeCriticalSection(&m_mutex); + InitializeCriticalSection(&m_mutex); #elif defined(__APPLE__) || defined(__linux__) - pthread_mutexattr_t mutexAttr; // Mutex Attribute - VHACD_VERIFY(pthread_mutexattr_init(&mutexAttr) == 0); - VHACD_VERIFY(pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE_NP) == 0); - VHACD_VERIFY(pthread_mutex_init(&m_mutex, &mutexAttr) == 0); - VHACD_VERIFY(pthread_mutexattr_destroy(&mutexAttr) == 0); + pthread_mutexattr_t mutexAttr; // Mutex Attribute + VHACD_VERIFY(pthread_mutexattr_init(&mutexAttr) == 0); + VHACD_VERIFY(pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE_NP) == 0); + VHACD_VERIFY(pthread_mutex_init(&m_mutex, &mutexAttr) == 0); + VHACD_VERIFY(pthread_mutexattr_destroy(&mutexAttr) == 0); #endif - } - ~Mutex(void) - { + } + ~Mutex(void) + { #if defined(WIN32) || defined(_XBOX) - DeleteCriticalSection(&m_mutex); + DeleteCriticalSection(&m_mutex); #elif defined(__APPLE__) || defined(__linux__) - VHACD_VERIFY(pthread_mutex_destroy(&m_mutex) == 0); + VHACD_VERIFY(pthread_mutex_destroy(&m_mutex) == 0); #endif - } - void Lock(void) - { + } + void Lock(void) + { #if defined(WIN32) || defined(_XBOX) - EnterCriticalSection(&m_mutex); + EnterCriticalSection(&m_mutex); #elif defined(__APPLE__) || defined(__linux__) - VHACD_VERIFY(pthread_mutex_lock(&m_mutex) == 0); + VHACD_VERIFY(pthread_mutex_lock(&m_mutex) == 0); #endif - } - bool TryLock(void) - { + } + bool TryLock(void) + { #if defined(WIN32) || defined(_XBOX) - bool bRet = false; - //assert(("TryEnterCriticalSection seems to not work on XP???", 0)); - bRet = TryEnterCriticalSection(&m_mutex) ? true : false; - return bRet; + bool bRet = false; + //assert(("TryEnterCriticalSection seems to not work on XP???", 0)); + bRet = TryEnterCriticalSection(&m_mutex) ? true : false; + return bRet; #elif defined(__APPLE__) || defined(__linux__) - int result = pthread_mutex_trylock(&m_mutex); - return (result == 0); + int result = pthread_mutex_trylock(&m_mutex); + return (result == 0); #endif - } + } - void Unlock(void) - { + void Unlock(void) + { #if defined(WIN32) || defined(_XBOX) - LeaveCriticalSection(&m_mutex); + LeaveCriticalSection(&m_mutex); #elif defined(__APPLE__) || defined(__linux__) - VHACD_VERIFY(pthread_mutex_unlock(&m_mutex) == 0); + VHACD_VERIFY(pthread_mutex_unlock(&m_mutex) == 0); #endif - } + } private: #if defined(WIN32) || defined(_XBOX) - CRITICAL_SECTION m_mutex; + CRITICAL_SECTION m_mutex; #elif defined(__APPLE__) || defined(__linux__) - pthread_mutex_t m_mutex; + pthread_mutex_t m_mutex; #endif }; -} -#endif // VHACD_MUTEX_H +} // namespace VHACD +#endif // VHACD_MUTEX_H diff --git a/Extras/VHACD/inc/vhacdSArray.h b/Extras/VHACD/inc/vhacdSArray.h index 4d84d1ae2..22a6a9dad 100644 --- a/Extras/VHACD/inc/vhacdSArray.h +++ b/Extras/VHACD/inc/vhacdSArray.h @@ -21,138 +21,144 @@ #define SARRAY_DEFAULT_MIN_SIZE 16 -namespace VHACD { +namespace VHACD +{ //! SArray. template -class SArray { +class SArray +{ public: - T& operator[](size_t i) - { - T* const data = Data(); - return data[i]; - } - const T& operator[](size_t i) const - { - const T* const data = Data(); - return data[i]; - } - size_t Size() const - { - return m_size; - } - T* const Data() - { - return (m_maxSize == N) ? m_data0 : m_data; - } - const T* const Data() const - { - return (m_maxSize == N) ? m_data0 : m_data; - } - void Clear() - { - m_size = 0; - delete[] m_data; - m_data = 0; - m_maxSize = N; - } - void PopBack() - { - --m_size; - } - void Allocate(size_t size) - { - if (size > m_maxSize) { - T* temp = new T[size]; - memcpy(temp, Data(), m_size * sizeof(T)); - delete[] m_data; - m_data = temp; - m_maxSize = size; - } - } - void Resize(size_t size) - { - Allocate(size); - m_size = size; - } + T& operator[](size_t i) + { + T* const data = Data(); + return data[i]; + } + const T& operator[](size_t i) const + { + const T* const data = Data(); + return data[i]; + } + size_t Size() const + { + return m_size; + } + T* const Data() + { + return (m_maxSize == N) ? m_data0 : m_data; + } + const T* const Data() const + { + return (m_maxSize == N) ? m_data0 : m_data; + } + void Clear() + { + m_size = 0; + delete[] m_data; + m_data = 0; + m_maxSize = N; + } + void PopBack() + { + --m_size; + } + void Allocate(size_t size) + { + if (size > m_maxSize) + { + T* temp = new T[size]; + memcpy(temp, Data(), m_size * sizeof(T)); + delete[] m_data; + m_data = temp; + m_maxSize = size; + } + } + void Resize(size_t size) + { + Allocate(size); + m_size = size; + } - void PushBack(const T& value) - { - if (m_size == m_maxSize) { - size_t maxSize = (m_maxSize << 1); - T* temp = new T[maxSize]; - memcpy(temp, Data(), m_maxSize * sizeof(T)); - delete[] m_data; - m_data = temp; - m_maxSize = maxSize; - } - T* const data = Data(); - data[m_size++] = value; - } - bool Find(const T& value, size_t& pos) - { - T* const data = Data(); - for (pos = 0; pos < m_size; ++pos) - if (value == data[pos]) - return true; - return false; - } - bool Insert(const T& value) - { - size_t pos; - if (Find(value, pos)) - return false; - PushBack(value); - return true; - } - bool Erase(const T& value) - { - size_t pos; - T* const data = Data(); - if (Find(value, pos)) { - for (size_t j = pos + 1; j < m_size; ++j) - data[j - 1] = data[j]; - --m_size; - return true; - } - return false; - } - void operator=(const SArray& rhs) - { - if (m_maxSize < rhs.m_size) { - delete[] m_data; - m_maxSize = rhs.m_maxSize; - m_data = new T[m_maxSize]; - } - m_size = rhs.m_size; - memcpy(Data(), rhs.Data(), m_size * sizeof(T)); - } - void Initialize() - { - m_data = 0; - m_size = 0; - m_maxSize = N; - } - SArray(const SArray& rhs) - { - m_data = 0; - m_size = 0; - m_maxSize = N; - *this = rhs; - } - SArray() - { - Initialize(); - } - ~SArray() - { - delete[] m_data; - } + void PushBack(const T& value) + { + if (m_size == m_maxSize) + { + size_t maxSize = (m_maxSize << 1); + T* temp = new T[maxSize]; + memcpy(temp, Data(), m_maxSize * sizeof(T)); + delete[] m_data; + m_data = temp; + m_maxSize = maxSize; + } + T* const data = Data(); + data[m_size++] = value; + } + bool Find(const T& value, size_t& pos) + { + T* const data = Data(); + for (pos = 0; pos < m_size; ++pos) + if (value == data[pos]) + return true; + return false; + } + bool Insert(const T& value) + { + size_t pos; + if (Find(value, pos)) + return false; + PushBack(value); + return true; + } + bool Erase(const T& value) + { + size_t pos; + T* const data = Data(); + if (Find(value, pos)) + { + for (size_t j = pos + 1; j < m_size; ++j) + data[j - 1] = data[j]; + --m_size; + return true; + } + return false; + } + void operator=(const SArray& rhs) + { + if (m_maxSize < rhs.m_size) + { + delete[] m_data; + m_maxSize = rhs.m_maxSize; + m_data = new T[m_maxSize]; + } + m_size = rhs.m_size; + memcpy(Data(), rhs.Data(), m_size * sizeof(T)); + } + void Initialize() + { + m_data = 0; + m_size = 0; + m_maxSize = N; + } + SArray(const SArray& rhs) + { + m_data = 0; + m_size = 0; + m_maxSize = N; + *this = rhs; + } + SArray() + { + Initialize(); + } + ~SArray() + { + delete[] m_data; + } private: - T m_data0[N]; - T* m_data; - size_t m_size; - size_t m_maxSize; + T m_data0[N]; + T* m_data; + size_t m_size; + size_t m_maxSize; }; -} +} // namespace VHACD #endif \ No newline at end of file diff --git a/Extras/VHACD/inc/vhacdTimer.h b/Extras/VHACD/inc/vhacdTimer.h index ba0e2c336..6c50e4125 100644 --- a/Extras/VHACD/inc/vhacdTimer.h +++ b/Extras/VHACD/inc/vhacdTimer.h @@ -18,7 +18,7 @@ #ifdef _WIN32 #ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers #endif #include #elif __MACH__ @@ -29,93 +29,97 @@ #include #endif -namespace VHACD { +namespace VHACD +{ #ifdef _WIN32 -class Timer { +class Timer +{ public: - Timer(void) - { - m_start.QuadPart = 0; - m_stop.QuadPart = 0; - QueryPerformanceFrequency(&m_freq); - }; - ~Timer(void){}; - void Tic() - { - QueryPerformanceCounter(&m_start); - } - void Toc() - { - QueryPerformanceCounter(&m_stop); - } - double GetElapsedTime() // in ms - { - LARGE_INTEGER delta; - delta.QuadPart = m_stop.QuadPart - m_start.QuadPart; - return (1000.0 * delta.QuadPart) / (double)m_freq.QuadPart; - } + Timer(void) + { + m_start.QuadPart = 0; + m_stop.QuadPart = 0; + QueryPerformanceFrequency(&m_freq); + }; + ~Timer(void){}; + void Tic() + { + QueryPerformanceCounter(&m_start); + } + void Toc() + { + QueryPerformanceCounter(&m_stop); + } + double GetElapsedTime() // in ms + { + LARGE_INTEGER delta; + delta.QuadPart = m_stop.QuadPart - m_start.QuadPart; + return (1000.0 * delta.QuadPart) / (double)m_freq.QuadPart; + } private: - LARGE_INTEGER m_start; - LARGE_INTEGER m_stop; - LARGE_INTEGER m_freq; + LARGE_INTEGER m_start; + LARGE_INTEGER m_stop; + LARGE_INTEGER m_freq; }; #elif __MACH__ -class Timer { +class Timer +{ public: - Timer(void) - { - memset(this, 0, sizeof(Timer)); - host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &m_cclock); - }; - ~Timer(void) - { - mach_port_deallocate(mach_task_self(), m_cclock); - }; - void Tic() - { - clock_get_time(m_cclock, &m_start); - } - void Toc() - { - clock_get_time(m_cclock, &m_stop); - } - double GetElapsedTime() // in ms - { - return 1000.0 * (m_stop.tv_sec - m_start.tv_sec + (1.0E-9) * (m_stop.tv_nsec - m_start.tv_nsec)); - } + Timer(void) + { + memset(this, 0, sizeof(Timer)); + host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &m_cclock); + }; + ~Timer(void) + { + mach_port_deallocate(mach_task_self(), m_cclock); + }; + void Tic() + { + clock_get_time(m_cclock, &m_start); + } + void Toc() + { + clock_get_time(m_cclock, &m_stop); + } + double GetElapsedTime() // in ms + { + return 1000.0 * (m_stop.tv_sec - m_start.tv_sec + (1.0E-9) * (m_stop.tv_nsec - m_start.tv_nsec)); + } private: - clock_serv_t m_cclock; - mach_timespec_t m_start; - mach_timespec_t m_stop; + clock_serv_t m_cclock; + mach_timespec_t m_start; + mach_timespec_t m_stop; }; #else -class Timer { +class Timer +{ public: - Timer(void) - { - memset(this, 0, sizeof(Timer)); - }; - ~Timer(void){}; - void Tic() - { - clock_gettime(CLOCK_REALTIME, &m_start); - } - void Toc() - { - clock_gettime(CLOCK_REALTIME, &m_stop); - } - double GetElapsedTime() // in ms - { - return 1000.0 * (m_stop.tv_sec - m_start.tv_sec + (1.0E-9) * (m_stop.tv_nsec - m_start.tv_nsec)); - } + Timer(void) + { + memset(this, 0, sizeof(Timer)); + }; + ~Timer(void){}; + void Tic() + { + clock_gettime(CLOCK_REALTIME, &m_start); + } + void Toc() + { + clock_gettime(CLOCK_REALTIME, &m_stop); + } + double GetElapsedTime() // in ms + { + return 1000.0 * (m_stop.tv_sec - m_start.tv_sec + (1.0E-9) * (m_stop.tv_nsec - m_start.tv_nsec)); + } private: - struct timespec m_start; - struct timespec m_stop; + struct timespec m_start; + struct timespec m_stop; }; #endif -} -#endif // VHACD_TIMER_H +} // namespace VHACD +#endif // VHACD_TIMER_H diff --git a/Extras/VHACD/inc/vhacdVHACD.h b/Extras/VHACD/inc/vhacdVHACD.h index 8c6c7fea1..405296bf4 100644 --- a/Extras/VHACD/inc/vhacdVHACD.h +++ b/Extras/VHACD/inc/vhacdVHACD.h @@ -22,7 +22,7 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND #else #include #endif -#endif //OPENCL_FOUND +#endif //OPENCL_FOUND #include "vhacdMutex.h" #include "vhacdVolume.h" @@ -30,321 +30,340 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND #define USE_THREAD 1 #define OCL_MIN_NUM_PRIMITIVES 4096 #define CH_APP_MIN_NUM_PRIMITIVES 64000 -namespace VHACD { -class VHACD : public IVHACD { +namespace VHACD +{ +class VHACD : public IVHACD +{ public: - //! Constructor. - VHACD() - { + //! Constructor. + VHACD() + { #if USE_THREAD == 1 && _OPENMP - m_ompNumProcessors = 2 * omp_get_num_procs(); - omp_set_num_threads(m_ompNumProcessors); -#else //USE_THREAD == 1 && _OPENMP - m_ompNumProcessors = 1; -#endif //USE_THREAD == 1 && _OPENMP + m_ompNumProcessors = 2 * omp_get_num_procs(); + omp_set_num_threads(m_ompNumProcessors); +#else //USE_THREAD == 1 && _OPENMP + m_ompNumProcessors = 1; +#endif //USE_THREAD == 1 && _OPENMP #ifdef CL_VERSION_1_1 - m_oclWorkGroupSize = 0; - m_oclDevice = 0; - m_oclQueue = 0; - m_oclKernelComputePartialVolumes = 0; - m_oclKernelComputeSum = 0; -#endif //CL_VERSION_1_1 - Init(); - } - //! Destructor. - ~VHACD(void) {} - unsigned int GetNConvexHulls() const - { - return (unsigned int)m_convexHulls.Size(); - } - void Cancel() - { - SetCancel(true); - } - void GetConvexHull(const unsigned int index, ConvexHull& ch) const - { - Mesh* mesh = m_convexHulls[index]; - ch.m_nPoints = (unsigned int)mesh->GetNPoints(); - ch.m_nTriangles = (unsigned int)mesh->GetNTriangles(); - ch.m_points = mesh->GetPoints(); - ch.m_triangles = mesh->GetTriangles(); - } - void Clean(void) - { - delete m_volume; - delete m_pset; - size_t nCH = m_convexHulls.Size(); - for (size_t p = 0; p < nCH; ++p) { - delete m_convexHulls[p]; - } - m_convexHulls.Clear(); - Init(); - } - void Release(void) - { - delete this; - } - bool Compute(const float* const points, - const unsigned int stridePoints, - const unsigned int nPoints, - const int* const triangles, - const unsigned int strideTriangles, - const unsigned int nTriangles, - const Parameters& params); - bool Compute(const double* const points, - const unsigned int stridePoints, - const unsigned int nPoints, - const int* const triangles, - const unsigned int strideTriangles, - const unsigned int nTriangles, - const Parameters& params); - bool OCLInit(void* const oclDevice, - IUserLogger* const logger = 0); - bool OCLRelease(IUserLogger* const logger = 0); + m_oclWorkGroupSize = 0; + m_oclDevice = 0; + m_oclQueue = 0; + m_oclKernelComputePartialVolumes = 0; + m_oclKernelComputeSum = 0; +#endif //CL_VERSION_1_1 + Init(); + } + //! Destructor. + ~VHACD(void) {} + unsigned int GetNConvexHulls() const + { + return (unsigned int)m_convexHulls.Size(); + } + void Cancel() + { + SetCancel(true); + } + void GetConvexHull(const unsigned int index, ConvexHull& ch) const + { + Mesh* mesh = m_convexHulls[index]; + ch.m_nPoints = (unsigned int)mesh->GetNPoints(); + ch.m_nTriangles = (unsigned int)mesh->GetNTriangles(); + ch.m_points = mesh->GetPoints(); + ch.m_triangles = mesh->GetTriangles(); + } + void Clean(void) + { + delete m_volume; + delete m_pset; + size_t nCH = m_convexHulls.Size(); + for (size_t p = 0; p < nCH; ++p) + { + delete m_convexHulls[p]; + } + m_convexHulls.Clear(); + Init(); + } + void Release(void) + { + delete this; + } + bool Compute(const float* const points, + const unsigned int stridePoints, + const unsigned int nPoints, + const int* const triangles, + const unsigned int strideTriangles, + const unsigned int nTriangles, + const Parameters& params); + bool Compute(const double* const points, + const unsigned int stridePoints, + const unsigned int nPoints, + const int* const triangles, + const unsigned int strideTriangles, + const unsigned int nTriangles, + const Parameters& params); + bool OCLInit(void* const oclDevice, + IUserLogger* const logger = 0); + bool OCLRelease(IUserLogger* const logger = 0); private: - void SetCancel(bool cancel) - { - m_cancelMutex.Lock(); - m_cancel = cancel; - m_cancelMutex.Unlock(); - } - bool GetCancel() - { + void SetCancel(bool cancel) + { + m_cancelMutex.Lock(); + m_cancel = cancel; + m_cancelMutex.Unlock(); + } + bool GetCancel() + { + m_cancelMutex.Lock(); + bool cancel = m_cancel; + m_cancelMutex.Unlock(); + return cancel; + } + void Update(const double stageProgress, + const double operationProgress, + const Parameters& params) + { + m_stageProgress = stageProgress; + m_operationProgress = operationProgress; + if (params.m_callback) + { + params.m_callback->Update(m_overallProgress, + m_stageProgress, + m_operationProgress, + m_stage.c_str(), + m_operation.c_str()); + } + } + void Init() + { + memset(m_rot, 0, sizeof(double) * 9); + m_dim = 64; + m_volume = 0; + m_volumeCH0 = 0.0; + m_pset = 0; + m_overallProgress = 0.0; + m_stageProgress = 0.0; + m_operationProgress = 0.0; + m_stage = ""; + m_operation = ""; + m_barycenter[0] = m_barycenter[1] = m_barycenter[2] = 0.0; + m_rot[0][0] = m_rot[1][1] = m_rot[2][2] = 1.0; + SetCancel(false); + } + void ComputePrimitiveSet(const Parameters& params); + void ComputeACD(const Parameters& params); + void MergeConvexHulls(const Parameters& params); + void SimplifyConvexHulls(const Parameters& params); + void ComputeBestClippingPlane(const PrimitiveSet* inputPSet, + const double volume, + const SArray& planes, + const Vec3& preferredCuttingDirection, + const double w, + const double alpha, + const double beta, + const int convexhullDownsampling, + const double progress0, + const double progress1, + Plane& bestPlane, + double& minConcavity, + const Parameters& params); + template + void AlignMesh(const T* const points, + const unsigned int stridePoints, + const unsigned int nPoints, + const int* const triangles, + const unsigned int strideTriangles, + const unsigned int nTriangles, + const Parameters& params) + { + if (GetCancel() || !params.m_pca) + { + return; + } + m_timer.Tic(); - m_cancelMutex.Lock(); - bool cancel = m_cancel; - m_cancelMutex.Unlock(); - return cancel; - } - void Update(const double stageProgress, - const double operationProgress, - const Parameters& params) - { - m_stageProgress = stageProgress; - m_operationProgress = operationProgress; - if (params.m_callback) { - params.m_callback->Update(m_overallProgress, - m_stageProgress, - m_operationProgress, - m_stage.c_str(), - m_operation.c_str()); - } - } - void Init() - { - memset(m_rot, 0, sizeof(double) * 9); - m_dim = 64; - m_volume = 0; - m_volumeCH0 = 0.0; - m_pset = 0; - m_overallProgress = 0.0; - m_stageProgress = 0.0; - m_operationProgress = 0.0; - m_stage = ""; - m_operation = ""; - m_barycenter[0] = m_barycenter[1] = m_barycenter[2] = 0.0; - m_rot[0][0] = m_rot[1][1] = m_rot[2][2] = 1.0; - SetCancel(false); - } - void ComputePrimitiveSet(const Parameters& params); - void ComputeACD(const Parameters& params); - void MergeConvexHulls(const Parameters& params); - void SimplifyConvexHulls(const Parameters& params); - void ComputeBestClippingPlane(const PrimitiveSet* inputPSet, - const double volume, - const SArray& planes, - const Vec3& preferredCuttingDirection, - const double w, - const double alpha, - const double beta, - const int convexhullDownsampling, - const double progress0, - const double progress1, - Plane& bestPlane, - double& minConcavity, - const Parameters& params); - template - void AlignMesh(const T* const points, - const unsigned int stridePoints, - const unsigned int nPoints, - const int* const triangles, - const unsigned int strideTriangles, - const unsigned int nTriangles, - const Parameters& params) - { - if (GetCancel() || !params.m_pca) { - return; - } - m_timer.Tic(); + m_stage = "Align mesh"; + m_operation = "Voxelization"; - m_stage = "Align mesh"; - m_operation = "Voxelization"; + std::ostringstream msg; + if (params.m_logger) + { + msg << "+ " << m_stage << std::endl; + params.m_logger->Log(msg.str().c_str()); + } - std::ostringstream msg; - if (params.m_logger) { - msg << "+ " << m_stage << std::endl; - params.m_logger->Log(msg.str().c_str()); - } + Update(0.0, 0.0, params); + if (GetCancel()) + { + return; + } + m_dim = (size_t)(pow((double)params.m_resolution, 1.0 / 3.0) + 0.5); + Volume volume; + volume.Voxelize(points, stridePoints, nPoints, + triangles, strideTriangles, nTriangles, + m_dim, m_barycenter, m_rot); + size_t n = volume.GetNPrimitivesOnSurf() + volume.GetNPrimitivesInsideSurf(); + Update(50.0, 100.0, params); - Update(0.0, 0.0, params); - if (GetCancel()) { - return; - } - m_dim = (size_t)(pow((double)params.m_resolution, 1.0 / 3.0) + 0.5); - Volume volume; - volume.Voxelize(points, stridePoints, nPoints, - triangles, strideTriangles, nTriangles, - m_dim, m_barycenter, m_rot); - size_t n = volume.GetNPrimitivesOnSurf() + volume.GetNPrimitivesInsideSurf(); - Update(50.0, 100.0, params); + if (params.m_logger) + { + msg.str(""); + msg << "\t dim = " << m_dim << "\t-> " << n << " voxels" << std::endl; + params.m_logger->Log(msg.str().c_str()); + } + if (GetCancel()) + { + return; + } + m_operation = "PCA"; + Update(50.0, 0.0, params); + volume.AlignToPrincipalAxes(m_rot); + m_overallProgress = 1.0; + Update(100.0, 100.0, params); - if (params.m_logger) { - msg.str(""); - msg << "\t dim = " << m_dim << "\t-> " << n << " voxels" << std::endl; - params.m_logger->Log(msg.str().c_str()); - } - if (GetCancel()) { - return; - } - m_operation = "PCA"; - Update(50.0, 0.0, params); - volume.AlignToPrincipalAxes(m_rot); - m_overallProgress = 1.0; - Update(100.0, 100.0, params); + m_timer.Toc(); + if (params.m_logger) + { + msg.str(""); + msg << "\t time " << m_timer.GetElapsedTime() / 1000.0 << "s" << std::endl; + params.m_logger->Log(msg.str().c_str()); + } + } + template + void VoxelizeMesh(const T* const points, + const unsigned int stridePoints, + const unsigned int nPoints, + const int* const triangles, + const unsigned int strideTriangles, + const unsigned int nTriangles, + const Parameters& params) + { + if (GetCancel()) + { + return; + } - m_timer.Toc(); - if (params.m_logger) { - msg.str(""); - msg << "\t time " << m_timer.GetElapsedTime() / 1000.0 << "s" << std::endl; - params.m_logger->Log(msg.str().c_str()); - } - } - template - void VoxelizeMesh(const T* const points, - const unsigned int stridePoints, - const unsigned int nPoints, - const int* const triangles, - const unsigned int strideTriangles, - const unsigned int nTriangles, - const Parameters& params) - { - if (GetCancel()) { - return; - } + m_timer.Tic(); + m_stage = "Voxelization"; - m_timer.Tic(); - m_stage = "Voxelization"; + std::ostringstream msg; + if (params.m_logger) + { + msg << "+ " << m_stage << std::endl; + params.m_logger->Log(msg.str().c_str()); + } - std::ostringstream msg; - if (params.m_logger) { - msg << "+ " << m_stage << std::endl; - params.m_logger->Log(msg.str().c_str()); - } + delete m_volume; + m_volume = 0; + int iteration = 0; + const int maxIteration = 5; + double progress = 0.0; + while (iteration++ < maxIteration && !m_cancel) + { + msg.str(""); + msg << "Iteration " << iteration; + m_operation = msg.str(); - delete m_volume; - m_volume = 0; - int iteration = 0; - const int maxIteration = 5; - double progress = 0.0; - while (iteration++ < maxIteration && !m_cancel) { - msg.str(""); - msg << "Iteration " << iteration; - m_operation = msg.str(); + progress = iteration * 100.0 / maxIteration; + Update(progress, 0.0, params); - progress = iteration * 100.0 / maxIteration; - Update(progress, 0.0, params); + m_volume = new Volume; + m_volume->Voxelize(points, stridePoints, nPoints, + triangles, strideTriangles, nTriangles, + m_dim, m_barycenter, m_rot); - m_volume = new Volume; - m_volume->Voxelize(points, stridePoints, nPoints, - triangles, strideTriangles, nTriangles, - m_dim, m_barycenter, m_rot); + Update(progress, 100.0, params); - Update(progress, 100.0, params); + size_t n = m_volume->GetNPrimitivesOnSurf() + m_volume->GetNPrimitivesInsideSurf(); + if (params.m_logger) + { + msg.str(""); + msg << "\t dim = " << m_dim << "\t-> " << n << " voxels" << std::endl; + params.m_logger->Log(msg.str().c_str()); + } - size_t n = m_volume->GetNPrimitivesOnSurf() + m_volume->GetNPrimitivesInsideSurf(); - if (params.m_logger) { - msg.str(""); - msg << "\t dim = " << m_dim << "\t-> " << n << " voxels" << std::endl; - params.m_logger->Log(msg.str().c_str()); - } + double a = pow((double)(params.m_resolution) / n, 0.33); + size_t dim_next = (size_t)(m_dim * a + 0.5); + if (n < params.m_resolution && iteration < maxIteration && m_volume->GetNPrimitivesOnSurf() < params.m_resolution / 8 && m_dim != dim_next) + { + delete m_volume; + m_volume = 0; + m_dim = dim_next; + } + else + { + break; + } + } + m_overallProgress = 10.0; + Update(100.0, 100.0, params); - double a = pow((double)(params.m_resolution) / n, 0.33); - size_t dim_next = (size_t)(m_dim * a + 0.5); - if (n < params.m_resolution && iteration < maxIteration && m_volume->GetNPrimitivesOnSurf() < params.m_resolution / 8 && m_dim != dim_next) { - delete m_volume; - m_volume = 0; - m_dim = dim_next; - } - else { - break; - } - } - m_overallProgress = 10.0; - Update(100.0, 100.0, params); - - m_timer.Toc(); - if (params.m_logger) { - msg.str(""); - msg << "\t time " << m_timer.GetElapsedTime() / 1000.0 << "s" << std::endl; - params.m_logger->Log(msg.str().c_str()); - } - } - template - bool ComputeACD(const T* const points, - const unsigned int stridePoints, - const unsigned int nPoints, - const int* const triangles, - const unsigned int strideTriangles, - const unsigned int nTriangles, - const Parameters& params) - { - Init(); - if (params.m_oclAcceleration) { - // build kernals - } - AlignMesh(points, stridePoints, nPoints, triangles, strideTriangles, nTriangles, params); - VoxelizeMesh(points, stridePoints, nPoints, triangles, strideTriangles, nTriangles, params); - ComputePrimitiveSet(params); - ComputeACD(params); - MergeConvexHulls(params); - SimplifyConvexHulls(params); - if (params.m_oclAcceleration) { - // Release kernals - } - if (GetCancel()) { - Clean(); - return false; - } - return true; - } + m_timer.Toc(); + if (params.m_logger) + { + msg.str(""); + msg << "\t time " << m_timer.GetElapsedTime() / 1000.0 << "s" << std::endl; + params.m_logger->Log(msg.str().c_str()); + } + } + template + bool ComputeACD(const T* const points, + const unsigned int stridePoints, + const unsigned int nPoints, + const int* const triangles, + const unsigned int strideTriangles, + const unsigned int nTriangles, + const Parameters& params) + { + Init(); + if (params.m_oclAcceleration) + { + // build kernals + } + AlignMesh(points, stridePoints, nPoints, triangles, strideTriangles, nTriangles, params); + VoxelizeMesh(points, stridePoints, nPoints, triangles, strideTriangles, nTriangles, params); + ComputePrimitiveSet(params); + ComputeACD(params); + MergeConvexHulls(params); + SimplifyConvexHulls(params); + if (params.m_oclAcceleration) + { + // Release kernals + } + if (GetCancel()) + { + Clean(); + return false; + } + return true; + } private: - SArray m_convexHulls; - std::string m_stage; - std::string m_operation; - double m_overallProgress; - double m_stageProgress; - double m_operationProgress; - double m_rot[3][3]; - double m_volumeCH0; - Vec3 m_barycenter; - Timer m_timer; - size_t m_dim; - Volume* m_volume; - PrimitiveSet* m_pset; - Mutex m_cancelMutex; - bool m_cancel; - int m_ompNumProcessors; + SArray m_convexHulls; + std::string m_stage; + std::string m_operation; + double m_overallProgress; + double m_stageProgress; + double m_operationProgress; + double m_rot[3][3]; + double m_volumeCH0; + Vec3 m_barycenter; + Timer m_timer; + size_t m_dim; + Volume* m_volume; + PrimitiveSet* m_pset; + Mutex m_cancelMutex; + bool m_cancel; + int m_ompNumProcessors; #ifdef CL_VERSION_1_1 - cl_device_id* m_oclDevice; - cl_context m_oclContext; - cl_program m_oclProgram; - cl_command_queue* m_oclQueue; - cl_kernel* m_oclKernelComputePartialVolumes; - cl_kernel* m_oclKernelComputeSum; - size_t m_oclWorkGroupSize; -#endif //CL_VERSION_1_1 + cl_device_id* m_oclDevice; + cl_context m_oclContext; + cl_program m_oclProgram; + cl_command_queue* m_oclQueue; + cl_kernel* m_oclKernelComputePartialVolumes; + cl_kernel* m_oclKernelComputeSum; + size_t m_oclWorkGroupSize; +#endif //CL_VERSION_1_1 }; -} -#endif // VHACD_VHACD_H +} // namespace VHACD +#endif // VHACD_VHACD_H diff --git a/Extras/VHACD/inc/vhacdVector.h b/Extras/VHACD/inc/vhacdVector.h index c9edfb1ae..0e724cc6a 100644 --- a/Extras/VHACD/inc/vhacdVector.h +++ b/Extras/VHACD/inc/vhacdVector.h @@ -18,86 +18,89 @@ #include #include -namespace VHACD { +namespace VHACD +{ //! Vector dim 3. template -class Vec3 { +class Vec3 +{ public: - T& operator[](size_t i) { return m_data[i]; } - const T& operator[](size_t i) const { return m_data[i]; } - T& X(); - T& Y(); - T& Z(); - const T& X() const; - const T& Y() const; - const T& Z() const; - void Normalize(); - T GetNorm() const; - void operator=(const Vec3& rhs); - void operator+=(const Vec3& rhs); - void operator-=(const Vec3& rhs); - void operator-=(T a); - void operator+=(T a); - void operator/=(T a); - void operator*=(T a); - Vec3 operator^(const Vec3& rhs) const; - T operator*(const Vec3& rhs) const; - Vec3 operator+(const Vec3& rhs) const; - Vec3 operator-(const Vec3& rhs) const; - Vec3 operator-() const; - Vec3 operator*(T rhs) const; - Vec3 operator/(T rhs) const; - bool operator<(const Vec3& rhs) const; - bool operator>(const Vec3& rhs) const; - Vec3(); - Vec3(T a); - Vec3(T x, T y, T z); - Vec3(const Vec3& rhs); - /*virtual*/ ~Vec3(void); + T& operator[](size_t i) { return m_data[i]; } + const T& operator[](size_t i) const { return m_data[i]; } + T& X(); + T& Y(); + T& Z(); + const T& X() const; + const T& Y() const; + const T& Z() const; + void Normalize(); + T GetNorm() const; + void operator=(const Vec3& rhs); + void operator+=(const Vec3& rhs); + void operator-=(const Vec3& rhs); + void operator-=(T a); + void operator+=(T a); + void operator/=(T a); + void operator*=(T a); + Vec3 operator^(const Vec3& rhs) const; + T operator*(const Vec3& rhs) const; + Vec3 operator+(const Vec3& rhs) const; + Vec3 operator-(const Vec3& rhs) const; + Vec3 operator-() const; + Vec3 operator*(T rhs) const; + Vec3 operator/(T rhs) const; + bool operator<(const Vec3& rhs) const; + bool operator>(const Vec3& rhs) const; + Vec3(); + Vec3(T a); + Vec3(T x, T y, T z); + Vec3(const Vec3& rhs); + /*virtual*/ ~Vec3(void); private: - T m_data[3]; + T m_data[3]; }; //! Vector dim 2. template -class Vec2 { +class Vec2 +{ public: - T& operator[](size_t i) { return m_data[i]; } - const T& operator[](size_t i) const { return m_data[i]; } - T& X(); - T& Y(); - const T& X() const; - const T& Y() const; - void Normalize(); - T GetNorm() const; - void operator=(const Vec2& rhs); - void operator+=(const Vec2& rhs); - void operator-=(const Vec2& rhs); - void operator-=(T a); - void operator+=(T a); - void operator/=(T a); - void operator*=(T a); - T operator^(const Vec2& rhs) const; - T operator*(const Vec2& rhs) const; - Vec2 operator+(const Vec2& rhs) const; - Vec2 operator-(const Vec2& rhs) const; - Vec2 operator-() const; - Vec2 operator*(T rhs) const; - Vec2 operator/(T rhs) const; - Vec2(); - Vec2(T a); - Vec2(T x, T y); - Vec2(const Vec2& rhs); - /*virtual*/ ~Vec2(void); + T& operator[](size_t i) { return m_data[i]; } + const T& operator[](size_t i) const { return m_data[i]; } + T& X(); + T& Y(); + const T& X() const; + const T& Y() const; + void Normalize(); + T GetNorm() const; + void operator=(const Vec2& rhs); + void operator+=(const Vec2& rhs); + void operator-=(const Vec2& rhs); + void operator-=(T a); + void operator+=(T a); + void operator/=(T a); + void operator*=(T a); + T operator^(const Vec2& rhs) const; + T operator*(const Vec2& rhs) const; + Vec2 operator+(const Vec2& rhs) const; + Vec2 operator-(const Vec2& rhs) const; + Vec2 operator-() const; + Vec2 operator*(T rhs) const; + Vec2 operator/(T rhs) const; + Vec2(); + Vec2(T a); + Vec2(T x, T y); + Vec2(const Vec2& rhs); + /*virtual*/ ~Vec2(void); private: - T m_data[2]; + T m_data[2]; }; template const bool Colinear(const Vec3& a, const Vec3& b, const Vec3& c); template const T ComputeVolume4(const Vec3& a, const Vec3& b, const Vec3& c, const Vec3& d); -} -#include "vhacdVector.inl" // template implementation +} // namespace VHACD +#include "vhacdVector.inl" // template implementation #endif \ No newline at end of file diff --git a/Extras/VHACD/inc/vhacdVolume.h b/Extras/VHACD/inc/vhacdVolume.h index 31377aa6c..cd89ca784 100644 --- a/Extras/VHACD/inc/vhacdVolume.h +++ b/Extras/VHACD/inc/vhacdVolume.h @@ -19,401 +19,423 @@ #include "vhacdVector.h" #include -namespace VHACD { - -enum VOXEL_VALUE { - PRIMITIVE_UNDEFINED = 0, - PRIMITIVE_OUTSIDE_SURFACE = 1, - PRIMITIVE_INSIDE_SURFACE = 2, - PRIMITIVE_ON_SURFACE = 3 +namespace VHACD +{ +enum VOXEL_VALUE +{ + PRIMITIVE_UNDEFINED = 0, + PRIMITIVE_OUTSIDE_SURFACE = 1, + PRIMITIVE_INSIDE_SURFACE = 2, + PRIMITIVE_ON_SURFACE = 3 }; -struct Voxel { +struct Voxel +{ public: - short m_coord[3]; - short m_data; + short m_coord[3]; + short m_data; }; -class PrimitiveSet { +class PrimitiveSet +{ public: - virtual ~PrimitiveSet(){}; - virtual PrimitiveSet* Create() const = 0; - virtual const size_t GetNPrimitives() const = 0; - virtual const size_t GetNPrimitivesOnSurf() const = 0; - virtual const size_t GetNPrimitivesInsideSurf() const = 0; - virtual const double GetEigenValue(AXIS axis) const = 0; - virtual const double ComputeMaxVolumeError() const = 0; - virtual const double ComputeVolume() const = 0; - virtual void Clip(const Plane& plane, PrimitiveSet* const positivePart, - PrimitiveSet* const negativePart) const = 0; - virtual void Intersect(const Plane& plane, SArray >* const positivePts, - SArray >* const negativePts, const size_t sampling) const = 0; - virtual void ComputeExteriorPoints(const Plane& plane, const Mesh& mesh, - SArray >* const exteriorPts) const = 0; - virtual void ComputeClippedVolumes(const Plane& plane, double& positiveVolume, - double& negativeVolume) const = 0; - virtual void SelectOnSurface(PrimitiveSet* const onSurfP) const = 0; - virtual void ComputeConvexHull(Mesh& meshCH, const size_t sampling = 1) const = 0; - virtual void ComputeBB() = 0; - virtual void ComputePrincipalAxes() = 0; - virtual void AlignToPrincipalAxes() = 0; - virtual void RevertAlignToPrincipalAxes() = 0; - virtual void Convert(Mesh& mesh, const VOXEL_VALUE value) const = 0; - const Mesh& GetConvexHull() const { return m_convexHull; }; - Mesh& GetConvexHull() { return m_convexHull; }; + virtual ~PrimitiveSet(){}; + virtual PrimitiveSet* Create() const = 0; + virtual const size_t GetNPrimitives() const = 0; + virtual const size_t GetNPrimitivesOnSurf() const = 0; + virtual const size_t GetNPrimitivesInsideSurf() const = 0; + virtual const double GetEigenValue(AXIS axis) const = 0; + virtual const double ComputeMaxVolumeError() const = 0; + virtual const double ComputeVolume() const = 0; + virtual void Clip(const Plane& plane, PrimitiveSet* const positivePart, + PrimitiveSet* const negativePart) const = 0; + virtual void Intersect(const Plane& plane, SArray >* const positivePts, + SArray >* const negativePts, const size_t sampling) const = 0; + virtual void ComputeExteriorPoints(const Plane& plane, const Mesh& mesh, + SArray >* const exteriorPts) const = 0; + virtual void ComputeClippedVolumes(const Plane& plane, double& positiveVolume, + double& negativeVolume) const = 0; + virtual void SelectOnSurface(PrimitiveSet* const onSurfP) const = 0; + virtual void ComputeConvexHull(Mesh& meshCH, const size_t sampling = 1) const = 0; + virtual void ComputeBB() = 0; + virtual void ComputePrincipalAxes() = 0; + virtual void AlignToPrincipalAxes() = 0; + virtual void RevertAlignToPrincipalAxes() = 0; + virtual void Convert(Mesh& mesh, const VOXEL_VALUE value) const = 0; + const Mesh& GetConvexHull() const { return m_convexHull; }; + Mesh& GetConvexHull() { return m_convexHull; }; + private: - Mesh m_convexHull; + Mesh m_convexHull; }; //! -class VoxelSet : public PrimitiveSet { - friend class Volume; +class VoxelSet : public PrimitiveSet +{ + friend class Volume; public: - //! Destructor. - ~VoxelSet(void); - //! Constructor. - VoxelSet(); + //! Destructor. + ~VoxelSet(void); + //! Constructor. + VoxelSet(); - const size_t GetNPrimitives() const { return m_voxels.Size(); } - const size_t GetNPrimitivesOnSurf() const { return m_numVoxelsOnSurface; } - const size_t GetNPrimitivesInsideSurf() const { return m_numVoxelsInsideSurface; } - const double GetEigenValue(AXIS axis) const { return m_D[axis][axis]; } - const double ComputeVolume() const { return m_unitVolume * m_voxels.Size(); } - const double ComputeMaxVolumeError() const { return m_unitVolume * m_numVoxelsOnSurface; } - const Vec3& GetMinBBVoxels() const { return m_minBBVoxels; } - const Vec3& GetMaxBBVoxels() const { return m_maxBBVoxels; } - const Vec3& GetMinBB() const { return m_minBB; } - const double& GetScale() const { return m_scale; } - const double& GetUnitVolume() const { return m_unitVolume; } - Vec3 GetPoint(Vec3 voxel) const - { - return Vec3(voxel[0] * m_scale + m_minBB[0], - voxel[1] * m_scale + m_minBB[1], - voxel[2] * m_scale + m_minBB[2]); - } - Vec3 GetPoint(const Voxel& voxel) const - { - return Vec3(voxel.m_coord[0] * m_scale + m_minBB[0], - voxel.m_coord[1] * m_scale + m_minBB[1], - voxel.m_coord[2] * m_scale + m_minBB[2]); - } - Vec3 GetPoint(Vec3 voxel) const - { - return Vec3(voxel[0] * m_scale + m_minBB[0], - voxel[1] * m_scale + m_minBB[1], - voxel[2] * m_scale + m_minBB[2]); - } - void GetPoints(const Voxel& voxel, Vec3* const pts) const; - void ComputeConvexHull(Mesh& meshCH, const size_t sampling = 1) const; - void Clip(const Plane& plane, PrimitiveSet* const positivePart, PrimitiveSet* const negativePart) const; - void Intersect(const Plane& plane, SArray >* const positivePts, - SArray >* const negativePts, const size_t sampling) const; - void ComputeExteriorPoints(const Plane& plane, const Mesh& mesh, - SArray >* const exteriorPts) const; - void ComputeClippedVolumes(const Plane& plane, double& positiveVolume, double& negativeVolume) const; - void SelectOnSurface(PrimitiveSet* const onSurfP) const; - void ComputeBB(); - void Convert(Mesh& mesh, const VOXEL_VALUE value) const; - void ComputePrincipalAxes(); - PrimitiveSet* Create() const - { - return new VoxelSet(); - } - void AlignToPrincipalAxes(){}; - void RevertAlignToPrincipalAxes(){}; - Voxel* const GetVoxels() { return m_voxels.Data(); } - const Voxel* const GetVoxels() const { return m_voxels.Data(); } + const size_t GetNPrimitives() const { return m_voxels.Size(); } + const size_t GetNPrimitivesOnSurf() const { return m_numVoxelsOnSurface; } + const size_t GetNPrimitivesInsideSurf() const { return m_numVoxelsInsideSurface; } + const double GetEigenValue(AXIS axis) const { return m_D[axis][axis]; } + const double ComputeVolume() const { return m_unitVolume * m_voxels.Size(); } + const double ComputeMaxVolumeError() const { return m_unitVolume * m_numVoxelsOnSurface; } + const Vec3& GetMinBBVoxels() const { return m_minBBVoxels; } + const Vec3& GetMaxBBVoxels() const { return m_maxBBVoxels; } + const Vec3& GetMinBB() const { return m_minBB; } + const double& GetScale() const { return m_scale; } + const double& GetUnitVolume() const { return m_unitVolume; } + Vec3 GetPoint(Vec3 voxel) const + { + return Vec3(voxel[0] * m_scale + m_minBB[0], + voxel[1] * m_scale + m_minBB[1], + voxel[2] * m_scale + m_minBB[2]); + } + Vec3 GetPoint(const Voxel& voxel) const + { + return Vec3(voxel.m_coord[0] * m_scale + m_minBB[0], + voxel.m_coord[1] * m_scale + m_minBB[1], + voxel.m_coord[2] * m_scale + m_minBB[2]); + } + Vec3 GetPoint(Vec3 voxel) const + { + return Vec3(voxel[0] * m_scale + m_minBB[0], + voxel[1] * m_scale + m_minBB[1], + voxel[2] * m_scale + m_minBB[2]); + } + void GetPoints(const Voxel& voxel, Vec3* const pts) const; + void ComputeConvexHull(Mesh& meshCH, const size_t sampling = 1) const; + void Clip(const Plane& plane, PrimitiveSet* const positivePart, PrimitiveSet* const negativePart) const; + void Intersect(const Plane& plane, SArray >* const positivePts, + SArray >* const negativePts, const size_t sampling) const; + void ComputeExteriorPoints(const Plane& plane, const Mesh& mesh, + SArray >* const exteriorPts) const; + void ComputeClippedVolumes(const Plane& plane, double& positiveVolume, double& negativeVolume) const; + void SelectOnSurface(PrimitiveSet* const onSurfP) const; + void ComputeBB(); + void Convert(Mesh& mesh, const VOXEL_VALUE value) const; + void ComputePrincipalAxes(); + PrimitiveSet* Create() const + { + return new VoxelSet(); + } + void AlignToPrincipalAxes(){}; + void RevertAlignToPrincipalAxes(){}; + Voxel* const GetVoxels() { return m_voxels.Data(); } + const Voxel* const GetVoxels() const { return m_voxels.Data(); } private: - size_t m_numVoxelsOnSurface; - size_t m_numVoxelsInsideSurface; - Vec3 m_minBB; - double m_scale; - SArray m_voxels; - double m_unitVolume; - Vec3 m_minBBPts; - Vec3 m_maxBBPts; - Vec3 m_minBBVoxels; - Vec3 m_maxBBVoxels; - Vec3 m_barycenter; - double m_Q[3][3]; - double m_D[3][3]; - Vec3 m_barycenterPCA; + size_t m_numVoxelsOnSurface; + size_t m_numVoxelsInsideSurface; + Vec3 m_minBB; + double m_scale; + SArray m_voxels; + double m_unitVolume; + Vec3 m_minBBPts; + Vec3 m_maxBBPts; + Vec3 m_minBBVoxels; + Vec3 m_maxBBVoxels; + Vec3 m_barycenter; + double m_Q[3][3]; + double m_D[3][3]; + Vec3 m_barycenterPCA; }; -struct Tetrahedron { +struct Tetrahedron +{ public: - Vec3 m_pts[4]; - unsigned char m_data; + Vec3 m_pts[4]; + unsigned char m_data; }; //! -class TetrahedronSet : public PrimitiveSet { - friend class Volume; +class TetrahedronSet : public PrimitiveSet +{ + friend class Volume; public: - //! Destructor. - ~TetrahedronSet(void); - //! Constructor. - TetrahedronSet(); + //! Destructor. + ~TetrahedronSet(void); + //! Constructor. + TetrahedronSet(); - const size_t GetNPrimitives() const { return m_tetrahedra.Size(); } - const size_t GetNPrimitivesOnSurf() const { return m_numTetrahedraOnSurface; } - const size_t GetNPrimitivesInsideSurf() const { return m_numTetrahedraInsideSurface; } - const Vec3& GetMinBB() const { return m_minBB; } - const Vec3& GetMaxBB() const { return m_maxBB; } - const Vec3& GetBarycenter() const { return m_barycenter; } - const double GetEigenValue(AXIS axis) const { return m_D[axis][axis]; } - const double GetSacle() const { return m_scale; } - const double ComputeVolume() const; - const double ComputeMaxVolumeError() const; - void ComputeConvexHull(Mesh& meshCH, const size_t sampling = 1) const; - void ComputePrincipalAxes(); - void AlignToPrincipalAxes(); - void RevertAlignToPrincipalAxes(); - void Clip(const Plane& plane, PrimitiveSet* const positivePart, PrimitiveSet* const negativePart) const; - void Intersect(const Plane& plane, SArray >* const positivePts, - SArray >* const negativePts, const size_t sampling) const; - void ComputeExteriorPoints(const Plane& plane, const Mesh& mesh, - SArray >* const exteriorPts) const; - void ComputeClippedVolumes(const Plane& plane, double& positiveVolume, double& negativeVolume) const; - void SelectOnSurface(PrimitiveSet* const onSurfP) const; - void ComputeBB(); - void Convert(Mesh& mesh, const VOXEL_VALUE value) const; - inline bool Add(Tetrahedron& tetrahedron); - PrimitiveSet* Create() const - { - return new TetrahedronSet(); - } - static const double EPS; + const size_t GetNPrimitives() const { return m_tetrahedra.Size(); } + const size_t GetNPrimitivesOnSurf() const { return m_numTetrahedraOnSurface; } + const size_t GetNPrimitivesInsideSurf() const { return m_numTetrahedraInsideSurface; } + const Vec3& GetMinBB() const { return m_minBB; } + const Vec3& GetMaxBB() const { return m_maxBB; } + const Vec3& GetBarycenter() const { return m_barycenter; } + const double GetEigenValue(AXIS axis) const { return m_D[axis][axis]; } + const double GetSacle() const { return m_scale; } + const double ComputeVolume() const; + const double ComputeMaxVolumeError() const; + void ComputeConvexHull(Mesh& meshCH, const size_t sampling = 1) const; + void ComputePrincipalAxes(); + void AlignToPrincipalAxes(); + void RevertAlignToPrincipalAxes(); + void Clip(const Plane& plane, PrimitiveSet* const positivePart, PrimitiveSet* const negativePart) const; + void Intersect(const Plane& plane, SArray >* const positivePts, + SArray >* const negativePts, const size_t sampling) const; + void ComputeExteriorPoints(const Plane& plane, const Mesh& mesh, + SArray >* const exteriorPts) const; + void ComputeClippedVolumes(const Plane& plane, double& positiveVolume, double& negativeVolume) const; + void SelectOnSurface(PrimitiveSet* const onSurfP) const; + void ComputeBB(); + void Convert(Mesh& mesh, const VOXEL_VALUE value) const; + inline bool Add(Tetrahedron& tetrahedron); + PrimitiveSet* Create() const + { + return new TetrahedronSet(); + } + static const double EPS; private: - void AddClippedTetrahedra(const Vec3 (&pts)[10], const int nPts); + void AddClippedTetrahedra(const Vec3 (&pts)[10], const int nPts); - size_t m_numTetrahedraOnSurface; - size_t m_numTetrahedraInsideSurface; - double m_scale; - Vec3 m_minBB; - Vec3 m_maxBB; - Vec3 m_barycenter; - SArray m_tetrahedra; - double m_Q[3][3]; - double m_D[3][3]; + size_t m_numTetrahedraOnSurface; + size_t m_numTetrahedraInsideSurface; + double m_scale; + Vec3 m_minBB; + Vec3 m_maxBB; + Vec3 m_barycenter; + SArray m_tetrahedra; + double m_Q[3][3]; + double m_D[3][3]; }; //! -class Volume { +class Volume +{ public: - //! Destructor. - ~Volume(void); + //! Destructor. + ~Volume(void); - //! Constructor. - Volume(); + //! Constructor. + Volume(); - //! Voxelize - template - void Voxelize(const T* const points, const unsigned int stridePoints, const unsigned int nPoints, - const int* const triangles, const unsigned int strideTriangles, const unsigned int nTriangles, - const size_t dim, const Vec3& barycenter, const double (&rot)[3][3]); - unsigned char& GetVoxel(const size_t i, const size_t j, const size_t k) - { - assert(i < m_dim[0] || i >= 0); - assert(j < m_dim[0] || j >= 0); - assert(k < m_dim[0] || k >= 0); - return m_data[i + j * m_dim[0] + k * m_dim[0] * m_dim[1]]; - } - const unsigned char& GetVoxel(const size_t i, const size_t j, const size_t k) const - { - assert(i < m_dim[0] || i >= 0); - assert(j < m_dim[0] || j >= 0); - assert(k < m_dim[0] || k >= 0); - return m_data[i + j * m_dim[0] + k * m_dim[0] * m_dim[1]]; - } - const size_t GetNPrimitivesOnSurf() const { return m_numVoxelsOnSurface; } - const size_t GetNPrimitivesInsideSurf() const { return m_numVoxelsInsideSurface; } - void Convert(Mesh& mesh, const VOXEL_VALUE value) const; - void Convert(VoxelSet& vset) const; - void Convert(TetrahedronSet& tset) const; - void AlignToPrincipalAxes(double (&rot)[3][3]) const; + //! Voxelize + template + void Voxelize(const T* const points, const unsigned int stridePoints, const unsigned int nPoints, + const int* const triangles, const unsigned int strideTriangles, const unsigned int nTriangles, + const size_t dim, const Vec3& barycenter, const double (&rot)[3][3]); + unsigned char& GetVoxel(const size_t i, const size_t j, const size_t k) + { + assert(i < m_dim[0] || i >= 0); + assert(j < m_dim[0] || j >= 0); + assert(k < m_dim[0] || k >= 0); + return m_data[i + j * m_dim[0] + k * m_dim[0] * m_dim[1]]; + } + const unsigned char& GetVoxel(const size_t i, const size_t j, const size_t k) const + { + assert(i < m_dim[0] || i >= 0); + assert(j < m_dim[0] || j >= 0); + assert(k < m_dim[0] || k >= 0); + return m_data[i + j * m_dim[0] + k * m_dim[0] * m_dim[1]]; + } + const size_t GetNPrimitivesOnSurf() const { return m_numVoxelsOnSurface; } + const size_t GetNPrimitivesInsideSurf() const { return m_numVoxelsInsideSurface; } + void Convert(Mesh& mesh, const VOXEL_VALUE value) const; + void Convert(VoxelSet& vset) const; + void Convert(TetrahedronSet& tset) const; + void AlignToPrincipalAxes(double (&rot)[3][3]) const; private: - void FillOutsideSurface(const size_t i0, const size_t j0, const size_t k0, const size_t i1, - const size_t j1, const size_t k1); - void FillInsideSurface(); - template - void ComputeBB(const T* const points, const unsigned int stridePoints, const unsigned int nPoints, - const Vec3& barycenter, const double (&rot)[3][3]); - void Allocate(); - void Free(); + void FillOutsideSurface(const size_t i0, const size_t j0, const size_t k0, const size_t i1, + const size_t j1, const size_t k1); + void FillInsideSurface(); + template + void ComputeBB(const T* const points, const unsigned int stridePoints, const unsigned int nPoints, + const Vec3& barycenter, const double (&rot)[3][3]); + void Allocate(); + void Free(); - Vec3 m_minBB; - Vec3 m_maxBB; - double m_scale; - size_t m_dim[3]; //>! dim - size_t m_numVoxelsOnSurface; - size_t m_numVoxelsInsideSurface; - size_t m_numVoxelsOutsideSurface; - unsigned char* m_data; + Vec3 m_minBB; + Vec3 m_maxBB; + double m_scale; + size_t m_dim[3]; //>! dim + size_t m_numVoxelsOnSurface; + size_t m_numVoxelsInsideSurface; + size_t m_numVoxelsOutsideSurface; + unsigned char* m_data; }; int TriBoxOverlap(const Vec3& boxcenter, const Vec3& boxhalfsize, const Vec3& triver0, - const Vec3& triver1, const Vec3& triver2); + const Vec3& triver1, const Vec3& triver2); template inline void ComputeAlignedPoint(const T* const points, const unsigned int idx, const Vec3& barycenter, - const double (&rot)[3][3], Vec3& pt){}; + const double (&rot)[3][3], Vec3& pt){}; template <> inline void ComputeAlignedPoint(const float* const points, const unsigned int idx, const Vec3& barycenter, const double (&rot)[3][3], Vec3& pt) { - double x = points[idx + 0] - barycenter[0]; - double y = points[idx + 1] - barycenter[1]; - double z = points[idx + 2] - barycenter[2]; - pt[0] = rot[0][0] * x + rot[1][0] * y + rot[2][0] * z; - pt[1] = rot[0][1] * x + rot[1][1] * y + rot[2][1] * z; - pt[2] = rot[0][2] * x + rot[1][2] * y + rot[2][2] * z; + double x = points[idx + 0] - barycenter[0]; + double y = points[idx + 1] - barycenter[1]; + double z = points[idx + 2] - barycenter[2]; + pt[0] = rot[0][0] * x + rot[1][0] * y + rot[2][0] * z; + pt[1] = rot[0][1] * x + rot[1][1] * y + rot[2][1] * z; + pt[2] = rot[0][2] * x + rot[1][2] * y + rot[2][2] * z; } template <> inline void ComputeAlignedPoint(const double* const points, const unsigned int idx, const Vec3& barycenter, const double (&rot)[3][3], Vec3& pt) { - double x = points[idx + 0] - barycenter[0]; - double y = points[idx + 1] - barycenter[1]; - double z = points[idx + 2] - barycenter[2]; - pt[0] = rot[0][0] * x + rot[1][0] * y + rot[2][0] * z; - pt[1] = rot[0][1] * x + rot[1][1] * y + rot[2][1] * z; - pt[2] = rot[0][2] * x + rot[1][2] * y + rot[2][2] * z; + double x = points[idx + 0] - barycenter[0]; + double y = points[idx + 1] - barycenter[1]; + double z = points[idx + 2] - barycenter[2]; + pt[0] = rot[0][0] * x + rot[1][0] * y + rot[2][0] * z; + pt[1] = rot[0][1] * x + rot[1][1] * y + rot[2][1] * z; + pt[2] = rot[0][2] * x + rot[1][2] * y + rot[2][2] * z; } template void Volume::ComputeBB(const T* const points, const unsigned int stridePoints, const unsigned int nPoints, - const Vec3& barycenter, const double (&rot)[3][3]) + const Vec3& barycenter, const double (&rot)[3][3]) { - Vec3 pt; - ComputeAlignedPoint(points, 0, barycenter, rot, pt); - m_maxBB = pt; - m_minBB = pt; - for (unsigned int v = 1; v < nPoints; ++v) { - ComputeAlignedPoint(points, v * stridePoints, barycenter, rot, pt); - for (int i = 0; i < 3; ++i) { - if (pt[i] < m_minBB[i]) - m_minBB[i] = pt[i]; - else if (pt[i] > m_maxBB[i]) - m_maxBB[i] = pt[i]; - } - } + Vec3 pt; + ComputeAlignedPoint(points, 0, barycenter, rot, pt); + m_maxBB = pt; + m_minBB = pt; + for (unsigned int v = 1; v < nPoints; ++v) + { + ComputeAlignedPoint(points, v * stridePoints, barycenter, rot, pt); + for (int i = 0; i < 3; ++i) + { + if (pt[i] < m_minBB[i]) + m_minBB[i] = pt[i]; + else if (pt[i] > m_maxBB[i]) + m_maxBB[i] = pt[i]; + } + } } template void Volume::Voxelize(const T* const points, const unsigned int stridePoints, const unsigned int nPoints, - const int* const triangles, const unsigned int strideTriangles, const unsigned int nTriangles, - const size_t dim, const Vec3& barycenter, const double (&rot)[3][3]) + const int* const triangles, const unsigned int strideTriangles, const unsigned int nTriangles, + const size_t dim, const Vec3& barycenter, const double (&rot)[3][3]) { - if (nPoints == 0) { - return; - } - ComputeBB(points, stridePoints, nPoints, barycenter, rot); + if (nPoints == 0) + { + return; + } + ComputeBB(points, stridePoints, nPoints, barycenter, rot); - double d[3] = { m_maxBB[0] - m_minBB[0], m_maxBB[1] - m_minBB[1], m_maxBB[2] - m_minBB[2] }; - double r; - if (d[0] > d[1] && d[0] > d[2]) { - r = d[0]; - m_dim[0] = dim; - m_dim[1] = 2 + static_cast(dim * d[1] / d[0]); - m_dim[2] = 2 + static_cast(dim * d[2] / d[0]); - } - else if (d[1] > d[0] && d[1] > d[2]) { - r = d[1]; - m_dim[1] = dim; - m_dim[0] = 2 + static_cast(dim * d[0] / d[1]); - m_dim[2] = 2 + static_cast(dim * d[2] / d[1]); - } - else { - r = d[2]; - m_dim[2] = dim; - m_dim[0] = 2 + static_cast(dim * d[0] / d[2]); - m_dim[1] = 2 + static_cast(dim * d[1] / d[2]); - } + double d[3] = {m_maxBB[0] - m_minBB[0], m_maxBB[1] - m_minBB[1], m_maxBB[2] - m_minBB[2]}; + double r; + if (d[0] > d[1] && d[0] > d[2]) + { + r = d[0]; + m_dim[0] = dim; + m_dim[1] = 2 + static_cast(dim * d[1] / d[0]); + m_dim[2] = 2 + static_cast(dim * d[2] / d[0]); + } + else if (d[1] > d[0] && d[1] > d[2]) + { + r = d[1]; + m_dim[1] = dim; + m_dim[0] = 2 + static_cast(dim * d[0] / d[1]); + m_dim[2] = 2 + static_cast(dim * d[2] / d[1]); + } + else + { + r = d[2]; + m_dim[2] = dim; + m_dim[0] = 2 + static_cast(dim * d[0] / d[2]); + m_dim[1] = 2 + static_cast(dim * d[1] / d[2]); + } - m_scale = r / (dim - 1); - double invScale = (dim - 1) / r; + m_scale = r / (dim - 1); + double invScale = (dim - 1) / r; - Allocate(); - m_numVoxelsOnSurface = 0; - m_numVoxelsInsideSurface = 0; - m_numVoxelsOutsideSurface = 0; + Allocate(); + m_numVoxelsOnSurface = 0; + m_numVoxelsInsideSurface = 0; + m_numVoxelsOutsideSurface = 0; - Vec3 p[3]; - size_t i, j, k; - size_t i0, j0, k0; - size_t i1, j1, k1; - Vec3 boxcenter; - Vec3 pt; - const Vec3 boxhalfsize(0.5, 0.5, 0.5); - for (size_t t = 0, ti = 0; t < nTriangles; ++t, ti += strideTriangles) { - Vec3 tri(triangles[ti + 0], - triangles[ti + 1], - triangles[ti + 2]); - for (int c = 0; c < 3; ++c) { - ComputeAlignedPoint(points, tri[c] * stridePoints, barycenter, rot, pt); - p[c][0] = (pt[0] - m_minBB[0]) * invScale; - p[c][1] = (pt[1] - m_minBB[1]) * invScale; - p[c][2] = (pt[2] - m_minBB[2]) * invScale; - i = static_cast(p[c][0] + 0.5); - j = static_cast(p[c][1] + 0.5); - k = static_cast(p[c][2] + 0.5); - assert(i < m_dim[0] && i >= 0 && j < m_dim[1] && j >= 0 && k < m_dim[2] && k >= 0); + Vec3 p[3]; + size_t i, j, k; + size_t i0, j0, k0; + size_t i1, j1, k1; + Vec3 boxcenter; + Vec3 pt; + const Vec3 boxhalfsize(0.5, 0.5, 0.5); + for (size_t t = 0, ti = 0; t < nTriangles; ++t, ti += strideTriangles) + { + Vec3 tri(triangles[ti + 0], + triangles[ti + 1], + triangles[ti + 2]); + for (int c = 0; c < 3; ++c) + { + ComputeAlignedPoint(points, tri[c] * stridePoints, barycenter, rot, pt); + p[c][0] = (pt[0] - m_minBB[0]) * invScale; + p[c][1] = (pt[1] - m_minBB[1]) * invScale; + p[c][2] = (pt[2] - m_minBB[2]) * invScale; + i = static_cast(p[c][0] + 0.5); + j = static_cast(p[c][1] + 0.5); + k = static_cast(p[c][2] + 0.5); + assert(i < m_dim[0] && i >= 0 && j < m_dim[1] && j >= 0 && k < m_dim[2] && k >= 0); - if (c == 0) { - i0 = i1 = i; - j0 = j1 = j; - k0 = k1 = k; - } - else { - if (i < i0) - i0 = i; - if (j < j0) - j0 = j; - if (k < k0) - k0 = k; - if (i > i1) - i1 = i; - if (j > j1) - j1 = j; - if (k > k1) - k1 = k; - } - } - if (i0 > 0) - --i0; - if (j0 > 0) - --j0; - if (k0 > 0) - --k0; - if (i1 < m_dim[0]) - ++i1; - if (j1 < m_dim[1]) - ++j1; - if (k1 < m_dim[2]) - ++k1; - for (size_t i = i0; i < i1; ++i) { - boxcenter[0] = (double)i; - for (size_t j = j0; j < j1; ++j) { - boxcenter[1] = (double)j; - for (size_t k = k0; k < k1; ++k) { - boxcenter[2] = (double)k; - int res = TriBoxOverlap(boxcenter, boxhalfsize, p[0], p[1], p[2]); - unsigned char& value = GetVoxel(i, j, k); - if (res == 1 && value == PRIMITIVE_UNDEFINED) { - value = PRIMITIVE_ON_SURFACE; - ++m_numVoxelsOnSurface; - } - } - } - } - } - FillOutsideSurface(0, 0, 0, m_dim[0], m_dim[1], 1); - FillOutsideSurface(0, 0, m_dim[2] - 1, m_dim[0], m_dim[1], m_dim[2]); - FillOutsideSurface(0, 0, 0, m_dim[0], 1, m_dim[2]); - FillOutsideSurface(0, m_dim[1] - 1, 0, m_dim[0], m_dim[1], m_dim[2]); - FillOutsideSurface(0, 0, 0, 1, m_dim[1], m_dim[2]); - FillOutsideSurface(m_dim[0] - 1, 0, 0, m_dim[0], m_dim[1], m_dim[2]); - FillInsideSurface(); + if (c == 0) + { + i0 = i1 = i; + j0 = j1 = j; + k0 = k1 = k; + } + else + { + if (i < i0) + i0 = i; + if (j < j0) + j0 = j; + if (k < k0) + k0 = k; + if (i > i1) + i1 = i; + if (j > j1) + j1 = j; + if (k > k1) + k1 = k; + } + } + if (i0 > 0) + --i0; + if (j0 > 0) + --j0; + if (k0 > 0) + --k0; + if (i1 < m_dim[0]) + ++i1; + if (j1 < m_dim[1]) + ++j1; + if (k1 < m_dim[2]) + ++k1; + for (size_t i = i0; i < i1; ++i) + { + boxcenter[0] = (double)i; + for (size_t j = j0; j < j1; ++j) + { + boxcenter[1] = (double)j; + for (size_t k = k0; k < k1; ++k) + { + boxcenter[2] = (double)k; + int res = TriBoxOverlap(boxcenter, boxhalfsize, p[0], p[1], p[2]); + unsigned char& value = GetVoxel(i, j, k); + if (res == 1 && value == PRIMITIVE_UNDEFINED) + { + value = PRIMITIVE_ON_SURFACE; + ++m_numVoxelsOnSurface; + } + } + } + } + } + FillOutsideSurface(0, 0, 0, m_dim[0], m_dim[1], 1); + FillOutsideSurface(0, 0, m_dim[2] - 1, m_dim[0], m_dim[1], m_dim[2]); + FillOutsideSurface(0, 0, 0, m_dim[0], 1, m_dim[2]); + FillOutsideSurface(0, m_dim[1] - 1, 0, m_dim[0], m_dim[1], m_dim[2]); + FillOutsideSurface(0, 0, 0, 1, m_dim[1], m_dim[2]); + FillOutsideSurface(m_dim[0] - 1, 0, 0, m_dim[0], m_dim[1], m_dim[2]); + FillInsideSurface(); } -} -#endif // VHACD_VOLUME_H +} // namespace VHACD +#endif // VHACD_VOLUME_H diff --git a/Extras/VHACD/public/VHACD.h b/Extras/VHACD/public/VHACD.h index 20f6aacd9..2197a34ce 100644 --- a/Extras/VHACD/public/VHACD.h +++ b/Extras/VHACD/public/VHACD.h @@ -19,103 +19,105 @@ #define VHACD_VERSION_MAJOR 2 #define VHACD_VERSION_MINOR 2 -namespace VHACD { -class IVHACD { +namespace VHACD +{ +class IVHACD +{ public: - class IUserCallback { - public: - virtual ~IUserCallback(){}; - virtual void Update(const double overallProgress, - const double stageProgress, - const double operationProgress, - const char* const stage, - const char* const operation) - = 0; - }; + class IUserCallback + { + public: + virtual ~IUserCallback(){}; + virtual void Update(const double overallProgress, + const double stageProgress, + const double operationProgress, + const char* const stage, + const char* const operation) = 0; + }; - class IUserLogger { - public: - virtual ~IUserLogger(){}; - virtual void Log(const char* const msg) = 0; - }; + class IUserLogger + { + public: + virtual ~IUserLogger(){}; + virtual void Log(const char* const msg) = 0; + }; - class ConvexHull { - public: - double* m_points; - int* m_triangles; - unsigned int m_nPoints; - unsigned int m_nTriangles; - }; + class ConvexHull + { + public: + double* m_points; + int* m_triangles; + unsigned int m_nPoints; + unsigned int m_nTriangles; + }; - class Parameters { - public: - Parameters(void) { Init(); } - void Init(void) - { - m_resolution = 1000000; - m_depth = 20; - m_concavity = 0.001; - m_planeDownsampling = 4; - m_convexhullDownsampling = 4; - m_alpha = 0.05; - m_beta = 0.05; - m_gamma = 0.0005; - m_pca = 0; - m_mode = 0; // 0: voxel-based (recommended), 1: tetrahedron-based - m_maxNumVerticesPerCH = 64; - m_minVolumePerCH = 0.0001; - m_callback = 0; - m_logger = 0; - m_convexhullApproximation = true; - m_oclAcceleration = true; - } - double m_concavity; - double m_alpha; - double m_beta; - double m_gamma; - double m_minVolumePerCH; - IUserCallback* m_callback; - IUserLogger* m_logger; - unsigned int m_resolution; - unsigned int m_maxNumVerticesPerCH; - int m_depth; - int m_planeDownsampling; - int m_convexhullDownsampling; - int m_pca; - int m_mode; - int m_convexhullApproximation; - int m_oclAcceleration; - }; + class Parameters + { + public: + Parameters(void) { Init(); } + void Init(void) + { + m_resolution = 1000000; + m_depth = 20; + m_concavity = 0.001; + m_planeDownsampling = 4; + m_convexhullDownsampling = 4; + m_alpha = 0.05; + m_beta = 0.05; + m_gamma = 0.0005; + m_pca = 0; + m_mode = 0; // 0: voxel-based (recommended), 1: tetrahedron-based + m_maxNumVerticesPerCH = 64; + m_minVolumePerCH = 0.0001; + m_callback = 0; + m_logger = 0; + m_convexhullApproximation = true; + m_oclAcceleration = true; + } + double m_concavity; + double m_alpha; + double m_beta; + double m_gamma; + double m_minVolumePerCH; + IUserCallback* m_callback; + IUserLogger* m_logger; + unsigned int m_resolution; + unsigned int m_maxNumVerticesPerCH; + int m_depth; + int m_planeDownsampling; + int m_convexhullDownsampling; + int m_pca; + int m_mode; + int m_convexhullApproximation; + int m_oclAcceleration; + }; - virtual void Cancel() = 0; - virtual bool Compute(const float* const points, - const unsigned int stridePoints, - const unsigned int countPoints, - const int* const triangles, - const unsigned int strideTriangles, - const unsigned int countTriangles, - const Parameters& params) - = 0; - virtual bool Compute(const double* const points, - const unsigned int stridePoints, - const unsigned int countPoints, - const int* const triangles, - const unsigned int strideTriangles, - const unsigned int countTriangles, - const Parameters& params) - = 0; - virtual unsigned int GetNConvexHulls() const = 0; - virtual void GetConvexHull(const unsigned int index, ConvexHull& ch) const = 0; - virtual void Clean(void) = 0; // release internally allocated memory - virtual void Release(void) = 0; // release IVHACD - virtual bool OCLInit(void* const oclDevice, - IUserLogger* const logger = 0) - = 0; - virtual bool OCLRelease(IUserLogger* const logger = 0) = 0; + virtual void Cancel() = 0; + virtual bool Compute(const float* const points, + const unsigned int stridePoints, + const unsigned int countPoints, + const int* const triangles, + const unsigned int strideTriangles, + const unsigned int countTriangles, + const Parameters& params) = 0; + virtual bool Compute(const double* const points, + const unsigned int stridePoints, + const unsigned int countPoints, + const int* const triangles, + const unsigned int strideTriangles, + const unsigned int countTriangles, + const Parameters& params) = 0; + virtual unsigned int GetNConvexHulls() const = 0; + virtual void GetConvexHull(const unsigned int index, ConvexHull& ch) const = 0; + virtual void Clean(void) = 0; // release internally allocated memory + virtual void Release(void) = 0; // release IVHACD + virtual bool OCLInit(void* const oclDevice, + IUserLogger* const logger = 0) = 0; + virtual bool OCLRelease(IUserLogger* const logger = 0) = 0; protected: - virtual ~IVHACD(void) {} + virtual ~IVHACD(void) {} }; IVHACD* CreateVHACD(void); -} -#endif // VHACD_H \ No newline at end of file +} // namespace VHACD +#endif // VHACD_H \ No newline at end of file diff --git a/Extras/VHACD/src/VHACD.cpp b/Extras/VHACD/src/VHACD.cpp index 8f1d30903..d7687df84 100644 --- a/Extras/VHACD/src/VHACD.cpp +++ b/Extras/VHACD/src/VHACD.cpp @@ -22,7 +22,7 @@ #include #if _OPENMP #include -#endif // _OPENMP +#endif // _OPENMP #include "../public/VHACD.h" #include "btConvexHullComputer.h" @@ -46,88 +46,98 @@ const int SIMD_WIDTH = 4; inline int FindMinimumElement(const float* const d, float* const m, const int n) { - // Min within vectors - __m128 min_i = _mm_set1_ps(-1.0f); - __m128 min_v = _mm_set1_ps(std::numeric_limits::max()); - for (int i = 0; i <= n - SIMD_WIDTH; i += SIMD_WIDTH) { - const __m128 data = _mm_load_ps(&d[i]); - const __m128 pred = _mm_cmplt_ps(data, min_v); + // Min within vectors + __m128 min_i = _mm_set1_ps(-1.0f); + __m128 min_v = _mm_set1_ps(std::numeric_limits::max()); + for (int i = 0; i <= n - SIMD_WIDTH; i += SIMD_WIDTH) + { + const __m128 data = _mm_load_ps(&d[i]); + const __m128 pred = _mm_cmplt_ps(data, min_v); - min_i = _mm_blendv_ps(min_i, _mm_set1_ps(i), pred); - min_v = _mm_min_ps(data, min_v); - } + min_i = _mm_blendv_ps(min_i, _mm_set1_ps(i), pred); + min_v = _mm_min_ps(data, min_v); + } - /* Min within vector */ - const __m128 min1 = _mm_shuffle_ps(min_v, min_v, _MM_SHUFFLE(1, 0, 3, 2)); - const __m128 min2 = _mm_min_ps(min_v, min1); - const __m128 min3 = _mm_shuffle_ps(min2, min2, _MM_SHUFFLE(0, 1, 0, 1)); - const __m128 min4 = _mm_min_ps(min2, min3); - float min_d = _mm_cvtss_f32(min4); + /* Min within vector */ + const __m128 min1 = _mm_shuffle_ps(min_v, min_v, _MM_SHUFFLE(1, 0, 3, 2)); + const __m128 min2 = _mm_min_ps(min_v, min1); + const __m128 min3 = _mm_shuffle_ps(min2, min2, _MM_SHUFFLE(0, 1, 0, 1)); + const __m128 min4 = _mm_min_ps(min2, min3); + float min_d = _mm_cvtss_f32(min4); - // Min index - const int min_idx = __builtin_ctz(_mm_movemask_ps(_mm_cmpeq_ps(min_v, min4))); - int ret = min_i[min_idx] + min_idx; + // Min index + const int min_idx = __builtin_ctz(_mm_movemask_ps(_mm_cmpeq_ps(min_v, min4))); + int ret = min_i[min_idx] + min_idx; - // Trailing elements - for (int i = (n & ~(SIMD_WIDTH - 1)); i < n; ++i) { - if (d[i] < min_d) { - min_d = d[i]; - ret = i; - } - } + // Trailing elements + for (int i = (n & ~(SIMD_WIDTH - 1)); i < n; ++i) + { + if (d[i] < min_d) + { + min_d = d[i]; + ret = i; + } + } - *m = min_d; - return ret; + *m = min_d; + return ret; } inline int FindMinimumElement(const float* const d, float* const m, const int begin, const int end) { - // Leading elements - int min_i = -1; - float min_d = std::numeric_limits::max(); - const int aligned = (begin & ~(SIMD_WIDTH - 1)) + ((begin & (SIMD_WIDTH - 1)) ? SIMD_WIDTH : 0); - for (int i = begin; i < std::min(end, aligned); ++i) { - if (d[i] < min_d) { - min_d = d[i]; - min_i = i; - } - } + // Leading elements + int min_i = -1; + float min_d = std::numeric_limits::max(); + const int aligned = (begin & ~(SIMD_WIDTH - 1)) + ((begin & (SIMD_WIDTH - 1)) ? SIMD_WIDTH : 0); + for (int i = begin; i < std::min(end, aligned); ++i) + { + if (d[i] < min_d) + { + min_d = d[i]; + min_i = i; + } + } - // Middle and trailing elements - float r_m = std::numeric_limits::max(); - const int n = end - aligned; - const int r_i = (n > 0) ? FindMinimumElement(&d[aligned], &r_m, n) : 0; + // Middle and trailing elements + float r_m = std::numeric_limits::max(); + const int n = end - aligned; + const int r_i = (n > 0) ? FindMinimumElement(&d[aligned], &r_m, n) : 0; - // Pick the lowest - if (r_m < min_d) { - *m = r_m; - return r_i + aligned; - } - else { - *m = min_d; - return min_i; - } + // Pick the lowest + if (r_m < min_d) + { + *m = r_m; + return r_i + aligned; + } + else + { + *m = min_d; + return min_i; + } } #else inline int FindMinimumElement(const float* const d, float* const m, const int begin, const int end) { - int idx = -1; - float min = (std::numeric_limits::max)(); - for (int i = begin; i < end; ++i) { - if (d[i] < min) { - idx = i; - min = d[i]; - } - } + int idx = -1; + float min = (std::numeric_limits::max)(); + for (int i = begin; i < end; ++i) + { + if (d[i] < min) + { + idx = i; + min = d[i]; + } + } - *m = min; - return idx; + *m = min; + return idx; } #endif //#define OCL_SOURCE_FROM_FILE #ifndef OCL_SOURCE_FROM_FILE -const char* oclProgramSource = "\ +const char* oclProgramSource = + "\ __kernel void ComputePartialVolumes(__global short4 * voxels, \ const int numVoxels, \ const float4 plane, \ @@ -194,1240 +204,1398 @@ __kernel void ComputePartialSums(__global uint4 * data, data[get_group_id(0)] = partialSums[0]; \ } \ }"; -#endif //OCL_SOURCE_FROM_FILE +#endif //OCL_SOURCE_FROM_FILE -namespace VHACD { +namespace VHACD +{ IVHACD* CreateVHACD(void) { - return new VHACD(); + return new VHACD(); } bool VHACD::OCLInit(void* const oclDevice, IUserLogger* const logger) { #ifdef CL_VERSION_1_1 - m_oclDevice = (cl_device_id*)oclDevice; - cl_int error; - m_oclContext = clCreateContext(NULL, 1, m_oclDevice, NULL, NULL, &error); - if (error != CL_SUCCESS) { - if (logger) { - logger->Log("Couldn't create context\n"); - } - return false; - } + m_oclDevice = (cl_device_id*)oclDevice; + cl_int error; + m_oclContext = clCreateContext(NULL, 1, m_oclDevice, NULL, NULL, &error); + if (error != CL_SUCCESS) + { + if (logger) + { + logger->Log("Couldn't create context\n"); + } + return false; + } #ifdef OCL_SOURCE_FROM_FILE - std::string cl_files = OPENCL_CL_FILES; + std::string cl_files = OPENCL_CL_FILES; // read kernal from file #ifdef _WIN32 - std::replace(cl_files.begin(), cl_files.end(), '/', '\\'); -#endif // _WIN32 + std::replace(cl_files.begin(), cl_files.end(), '/', '\\'); +#endif // _WIN32 - FILE* program_handle = fopen(cl_files.c_str(), "rb"); - fseek(program_handle, 0, SEEK_END); - size_t program_size = ftell(program_handle); - rewind(program_handle); - char* program_buffer = new char[program_size + 1]; - program_buffer[program_size] = '\0'; - fread(program_buffer, sizeof(char), program_size, program_handle); - fclose(program_handle); - // create program - m_oclProgram = clCreateProgramWithSource(m_oclContext, 1, (const char**)&program_buffer, &program_size, &error); - delete[] program_buffer; + FILE* program_handle = fopen(cl_files.c_str(), "rb"); + fseek(program_handle, 0, SEEK_END); + size_t program_size = ftell(program_handle); + rewind(program_handle); + char* program_buffer = new char[program_size + 1]; + program_buffer[program_size] = '\0'; + fread(program_buffer, sizeof(char), program_size, program_handle); + fclose(program_handle); + // create program + m_oclProgram = clCreateProgramWithSource(m_oclContext, 1, (const char**)&program_buffer, &program_size, &error); + delete[] program_buffer; #else - size_t program_size = strlen(oclProgramSource); - m_oclProgram = clCreateProgramWithSource(m_oclContext, 1, (const char**)&oclProgramSource, &program_size, &error); + size_t program_size = strlen(oclProgramSource); + m_oclProgram = clCreateProgramWithSource(m_oclContext, 1, (const char**)&oclProgramSource, &program_size, &error); #endif - if (error != CL_SUCCESS) { - if (logger) { - logger->Log("Couldn't create program\n"); - } - return false; - } + if (error != CL_SUCCESS) + { + if (logger) + { + logger->Log("Couldn't create program\n"); + } + return false; + } - /* Build program */ - error = clBuildProgram(m_oclProgram, 1, m_oclDevice, "-cl-denorms-are-zero", NULL, NULL); - if (error != CL_SUCCESS) { - size_t log_size; - /* Find Size of log and print to std output */ - clGetProgramBuildInfo(m_oclProgram, *m_oclDevice, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size); - char* program_log = new char[log_size + 2]; - program_log[log_size] = '\n'; - program_log[log_size + 1] = '\0'; - clGetProgramBuildInfo(m_oclProgram, *m_oclDevice, CL_PROGRAM_BUILD_LOG, log_size + 1, program_log, NULL); - if (logger) { - logger->Log("Couldn't build program\n"); - logger->Log(program_log); - } - delete[] program_log; - return false; - } + /* Build program */ + error = clBuildProgram(m_oclProgram, 1, m_oclDevice, "-cl-denorms-are-zero", NULL, NULL); + if (error != CL_SUCCESS) + { + size_t log_size; + /* Find Size of log and print to std output */ + clGetProgramBuildInfo(m_oclProgram, *m_oclDevice, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size); + char* program_log = new char[log_size + 2]; + program_log[log_size] = '\n'; + program_log[log_size + 1] = '\0'; + clGetProgramBuildInfo(m_oclProgram, *m_oclDevice, CL_PROGRAM_BUILD_LOG, log_size + 1, program_log, NULL); + if (logger) + { + logger->Log("Couldn't build program\n"); + logger->Log(program_log); + } + delete[] program_log; + return false; + } - delete[] m_oclQueue; - delete[] m_oclKernelComputePartialVolumes; - delete[] m_oclKernelComputeSum; - m_oclQueue = new cl_command_queue[m_ompNumProcessors]; - m_oclKernelComputePartialVolumes = new cl_kernel[m_ompNumProcessors]; - m_oclKernelComputeSum = new cl_kernel[m_ompNumProcessors]; + delete[] m_oclQueue; + delete[] m_oclKernelComputePartialVolumes; + delete[] m_oclKernelComputeSum; + m_oclQueue = new cl_command_queue[m_ompNumProcessors]; + m_oclKernelComputePartialVolumes = new cl_kernel[m_ompNumProcessors]; + m_oclKernelComputeSum = new cl_kernel[m_ompNumProcessors]; - const char nameKernelComputePartialVolumes[] = "ComputePartialVolumes"; - const char nameKernelComputeSum[] = "ComputePartialSums"; - for (int k = 0; k < m_ompNumProcessors; ++k) { - m_oclKernelComputePartialVolumes[k] = clCreateKernel(m_oclProgram, nameKernelComputePartialVolumes, &error); - if (error != CL_SUCCESS) { - if (logger) { - logger->Log("Couldn't create kernel\n"); - } - return false; - } - m_oclKernelComputeSum[k] = clCreateKernel(m_oclProgram, nameKernelComputeSum, &error); - if (error != CL_SUCCESS) { - if (logger) { - logger->Log("Couldn't create kernel\n"); - } - return false; - } - } + const char nameKernelComputePartialVolumes[] = "ComputePartialVolumes"; + const char nameKernelComputeSum[] = "ComputePartialSums"; + for (int k = 0; k < m_ompNumProcessors; ++k) + { + m_oclKernelComputePartialVolumes[k] = clCreateKernel(m_oclProgram, nameKernelComputePartialVolumes, &error); + if (error != CL_SUCCESS) + { + if (logger) + { + logger->Log("Couldn't create kernel\n"); + } + return false; + } + m_oclKernelComputeSum[k] = clCreateKernel(m_oclProgram, nameKernelComputeSum, &error); + if (error != CL_SUCCESS) + { + if (logger) + { + logger->Log("Couldn't create kernel\n"); + } + return false; + } + } - error = clGetKernelWorkGroupInfo(m_oclKernelComputePartialVolumes[0], - *m_oclDevice, - CL_KERNEL_WORK_GROUP_SIZE, - sizeof(size_t), - &m_oclWorkGroupSize, - NULL); - size_t workGroupSize = 0; - error = clGetKernelWorkGroupInfo(m_oclKernelComputeSum[0], - *m_oclDevice, - CL_KERNEL_WORK_GROUP_SIZE, - sizeof(size_t), - &workGroupSize, - NULL); - if (error != CL_SUCCESS) { - if (logger) { - logger->Log("Couldn't query work group info\n"); - } - return false; - } + error = clGetKernelWorkGroupInfo(m_oclKernelComputePartialVolumes[0], + *m_oclDevice, + CL_KERNEL_WORK_GROUP_SIZE, + sizeof(size_t), + &m_oclWorkGroupSize, + NULL); + size_t workGroupSize = 0; + error = clGetKernelWorkGroupInfo(m_oclKernelComputeSum[0], + *m_oclDevice, + CL_KERNEL_WORK_GROUP_SIZE, + sizeof(size_t), + &workGroupSize, + NULL); + if (error != CL_SUCCESS) + { + if (logger) + { + logger->Log("Couldn't query work group info\n"); + } + return false; + } - if (workGroupSize < m_oclWorkGroupSize) { - m_oclWorkGroupSize = workGroupSize; - } + if (workGroupSize < m_oclWorkGroupSize) + { + m_oclWorkGroupSize = workGroupSize; + } - for (int k = 0; k < m_ompNumProcessors; ++k) { - m_oclQueue[k] = clCreateCommandQueue(m_oclContext, *m_oclDevice, 0 /*CL_QUEUE_PROFILING_ENABLE*/, &error); - if (error != CL_SUCCESS) { - if (logger) { - logger->Log("Couldn't create queue\n"); - } - return false; - } - } - return true; -#else //CL_VERSION_1_1 - return false; -#endif //CL_VERSION_1_1 + for (int k = 0; k < m_ompNumProcessors; ++k) + { + m_oclQueue[k] = clCreateCommandQueue(m_oclContext, *m_oclDevice, 0 /*CL_QUEUE_PROFILING_ENABLE*/, &error); + if (error != CL_SUCCESS) + { + if (logger) + { + logger->Log("Couldn't create queue\n"); + } + return false; + } + } + return true; +#else //CL_VERSION_1_1 + return false; +#endif //CL_VERSION_1_1 } bool VHACD::OCLRelease(IUserLogger* const logger) { #ifdef CL_VERSION_1_1 - cl_int error; - if (m_oclKernelComputePartialVolumes) { - for (int k = 0; k < m_ompNumProcessors; ++k) { - error = clReleaseKernel(m_oclKernelComputePartialVolumes[k]); - if (error != CL_SUCCESS) { - if (logger) { - logger->Log("Couldn't release kernal\n"); - } - return false; - } - } - delete[] m_oclKernelComputePartialVolumes; - } - if (m_oclKernelComputeSum) { - for (int k = 0; k < m_ompNumProcessors; ++k) { - error = clReleaseKernel(m_oclKernelComputeSum[k]); - if (error != CL_SUCCESS) { - if (logger) { - logger->Log("Couldn't release kernal\n"); - } - return false; - } - } - delete[] m_oclKernelComputeSum; - } - if (m_oclQueue) { - for (int k = 0; k < m_ompNumProcessors; ++k) { - error = clReleaseCommandQueue(m_oclQueue[k]); - if (error != CL_SUCCESS) { - if (logger) { - logger->Log("Couldn't release queue\n"); - } - return false; - } - } - delete[] m_oclQueue; - } - error = clReleaseProgram(m_oclProgram); - if (error != CL_SUCCESS) { - if (logger) { - logger->Log("Couldn't release program\n"); - } - return false; - } - error = clReleaseContext(m_oclContext); - if (error != CL_SUCCESS) { - if (logger) { - logger->Log("Couldn't release context\n"); - } - return false; - } + cl_int error; + if (m_oclKernelComputePartialVolumes) + { + for (int k = 0; k < m_ompNumProcessors; ++k) + { + error = clReleaseKernel(m_oclKernelComputePartialVolumes[k]); + if (error != CL_SUCCESS) + { + if (logger) + { + logger->Log("Couldn't release kernal\n"); + } + return false; + } + } + delete[] m_oclKernelComputePartialVolumes; + } + if (m_oclKernelComputeSum) + { + for (int k = 0; k < m_ompNumProcessors; ++k) + { + error = clReleaseKernel(m_oclKernelComputeSum[k]); + if (error != CL_SUCCESS) + { + if (logger) + { + logger->Log("Couldn't release kernal\n"); + } + return false; + } + } + delete[] m_oclKernelComputeSum; + } + if (m_oclQueue) + { + for (int k = 0; k < m_ompNumProcessors; ++k) + { + error = clReleaseCommandQueue(m_oclQueue[k]); + if (error != CL_SUCCESS) + { + if (logger) + { + logger->Log("Couldn't release queue\n"); + } + return false; + } + } + delete[] m_oclQueue; + } + error = clReleaseProgram(m_oclProgram); + if (error != CL_SUCCESS) + { + if (logger) + { + logger->Log("Couldn't release program\n"); + } + return false; + } + error = clReleaseContext(m_oclContext); + if (error != CL_SUCCESS) + { + if (logger) + { + logger->Log("Couldn't release context\n"); + } + return false; + } - return true; -#else //CL_VERSION_1_1 - return false; -#endif //CL_VERSION_1_1 + return true; +#else //CL_VERSION_1_1 + return false; +#endif //CL_VERSION_1_1 } void VHACD::ComputePrimitiveSet(const Parameters& params) { - if (GetCancel()) { - return; - } - m_timer.Tic(); + if (GetCancel()) + { + return; + } + m_timer.Tic(); - m_stage = "Compute primitive set"; - m_operation = "Convert volume to pset"; + m_stage = "Compute primitive set"; + m_operation = "Convert volume to pset"; - std::ostringstream msg; - if (params.m_logger) { - msg << "+ " << m_stage << std::endl; - params.m_logger->Log(msg.str().c_str()); - } + std::ostringstream msg; + if (params.m_logger) + { + msg << "+ " << m_stage << std::endl; + params.m_logger->Log(msg.str().c_str()); + } - Update(0.0, 0.0, params); - if (params.m_mode == 0) { - VoxelSet* vset = new VoxelSet; - m_volume->Convert(*vset); - m_pset = vset; - } - else { - TetrahedronSet* tset = new TetrahedronSet; - m_volume->Convert(*tset); - m_pset = tset; - } + Update(0.0, 0.0, params); + if (params.m_mode == 0) + { + VoxelSet* vset = new VoxelSet; + m_volume->Convert(*vset); + m_pset = vset; + } + else + { + TetrahedronSet* tset = new TetrahedronSet; + m_volume->Convert(*tset); + m_pset = tset; + } - delete m_volume; - m_volume = 0; + delete m_volume; + m_volume = 0; - if (params.m_logger) { - msg.str(""); - msg << "\t # primitives " << m_pset->GetNPrimitives() << std::endl; - msg << "\t # inside surface " << m_pset->GetNPrimitivesInsideSurf() << std::endl; - msg << "\t # on surface " << m_pset->GetNPrimitivesOnSurf() << std::endl; - params.m_logger->Log(msg.str().c_str()); - } + if (params.m_logger) + { + msg.str(""); + msg << "\t # primitives " << m_pset->GetNPrimitives() << std::endl; + msg << "\t # inside surface " << m_pset->GetNPrimitivesInsideSurf() << std::endl; + msg << "\t # on surface " << m_pset->GetNPrimitivesOnSurf() << std::endl; + params.m_logger->Log(msg.str().c_str()); + } - m_overallProgress = 15.0; - Update(100.0, 100.0, params); - m_timer.Toc(); - if (params.m_logger) { - msg.str(""); - msg << "\t time " << m_timer.GetElapsedTime() / 1000.0 << "s" << std::endl; - params.m_logger->Log(msg.str().c_str()); - } + m_overallProgress = 15.0; + Update(100.0, 100.0, params); + m_timer.Toc(); + if (params.m_logger) + { + msg.str(""); + msg << "\t time " << m_timer.GetElapsedTime() / 1000.0 << "s" << std::endl; + params.m_logger->Log(msg.str().c_str()); + } } bool VHACD::Compute(const double* const points, const unsigned int stridePoints, const unsigned int nPoints, - const int* const triangles, const unsigned int strideTriangles, const unsigned int nTriangles, const Parameters& params) + const int* const triangles, const unsigned int strideTriangles, const unsigned int nTriangles, const Parameters& params) { - return ComputeACD(points, stridePoints, nPoints, triangles, strideTriangles, nTriangles, params); + return ComputeACD(points, stridePoints, nPoints, triangles, strideTriangles, nTriangles, params); } bool VHACD::Compute(const float* const points, const unsigned int stridePoints, const unsigned int nPoints, - const int* const triangles, const unsigned int strideTriangles, const unsigned int nTriangles, const Parameters& params) + const int* const triangles, const unsigned int strideTriangles, const unsigned int nTriangles, const Parameters& params) { - return ComputeACD(points, stridePoints, nPoints, triangles, strideTriangles, nTriangles, params); + return ComputeACD(points, stridePoints, nPoints, triangles, strideTriangles, nTriangles, params); } double ComputePreferredCuttingDirection(const PrimitiveSet* const tset, Vec3& dir) { - double ex = tset->GetEigenValue(AXIS_X); - double ey = tset->GetEigenValue(AXIS_Y); - double ez = tset->GetEigenValue(AXIS_Z); - double vx = (ey - ez) * (ey - ez); - double vy = (ex - ez) * (ex - ez); - double vz = (ex - ey) * (ex - ey); - if (vx < vy && vx < vz) { - double e = ey * ey + ez * ez; - dir[0] = 1.0; - dir[1] = 0.0; - dir[2] = 0.0; - return (e == 0.0) ? 0.0 : 1.0 - vx / e; - } - else if (vy < vx && vy < vz) { - double e = ex * ex + ez * ez; - dir[0] = 0.0; - dir[1] = 1.0; - dir[2] = 0.0; - return (e == 0.0) ? 0.0 : 1.0 - vy / e; - } - else { - double e = ex * ex + ey * ey; - dir[0] = 0.0; - dir[1] = 0.0; - dir[2] = 1.0; - return (e == 0.0) ? 0.0 : 1.0 - vz / e; - } + double ex = tset->GetEigenValue(AXIS_X); + double ey = tset->GetEigenValue(AXIS_Y); + double ez = tset->GetEigenValue(AXIS_Z); + double vx = (ey - ez) * (ey - ez); + double vy = (ex - ez) * (ex - ez); + double vz = (ex - ey) * (ex - ey); + if (vx < vy && vx < vz) + { + double e = ey * ey + ez * ez; + dir[0] = 1.0; + dir[1] = 0.0; + dir[2] = 0.0; + return (e == 0.0) ? 0.0 : 1.0 - vx / e; + } + else if (vy < vx && vy < vz) + { + double e = ex * ex + ez * ez; + dir[0] = 0.0; + dir[1] = 1.0; + dir[2] = 0.0; + return (e == 0.0) ? 0.0 : 1.0 - vy / e; + } + else + { + double e = ex * ex + ey * ey; + dir[0] = 0.0; + dir[1] = 0.0; + dir[2] = 1.0; + return (e == 0.0) ? 0.0 : 1.0 - vz / e; + } } void ComputeAxesAlignedClippingPlanes(const VoxelSet& vset, const short downsampling, SArray& planes) { - const Vec3 minV = vset.GetMinBBVoxels(); - const Vec3 maxV = vset.GetMaxBBVoxels(); - Vec3 pt; - Plane plane; - const short i0 = minV[0]; - const short i1 = maxV[0]; - plane.m_a = 1.0; - plane.m_b = 0.0; - plane.m_c = 0.0; - plane.m_axis = AXIS_X; - for (short i = i0; i <= i1; i += downsampling) { - pt = vset.GetPoint(Vec3(i + 0.5, 0.0, 0.0)); - plane.m_d = -pt[0]; - plane.m_index = i; - planes.PushBack(plane); - } - const short j0 = minV[1]; - const short j1 = maxV[1]; - plane.m_a = 0.0; - plane.m_b = 1.0; - plane.m_c = 0.0; - plane.m_axis = AXIS_Y; - for (short j = j0; j <= j1; j += downsampling) { - pt = vset.GetPoint(Vec3(0.0, j + 0.5, 0.0)); - plane.m_d = -pt[1]; - plane.m_index = j; - planes.PushBack(plane); - } - const short k0 = minV[2]; - const short k1 = maxV[2]; - plane.m_a = 0.0; - plane.m_b = 0.0; - plane.m_c = 1.0; - plane.m_axis = AXIS_Z; - for (short k = k0; k <= k1; k += downsampling) { - pt = vset.GetPoint(Vec3(0.0, 0.0, k + 0.5)); - plane.m_d = -pt[2]; - plane.m_index = k; - planes.PushBack(plane); - } + const Vec3 minV = vset.GetMinBBVoxels(); + const Vec3 maxV = vset.GetMaxBBVoxels(); + Vec3 pt; + Plane plane; + const short i0 = minV[0]; + const short i1 = maxV[0]; + plane.m_a = 1.0; + plane.m_b = 0.0; + plane.m_c = 0.0; + plane.m_axis = AXIS_X; + for (short i = i0; i <= i1; i += downsampling) + { + pt = vset.GetPoint(Vec3(i + 0.5, 0.0, 0.0)); + plane.m_d = -pt[0]; + plane.m_index = i; + planes.PushBack(plane); + } + const short j0 = minV[1]; + const short j1 = maxV[1]; + plane.m_a = 0.0; + plane.m_b = 1.0; + plane.m_c = 0.0; + plane.m_axis = AXIS_Y; + for (short j = j0; j <= j1; j += downsampling) + { + pt = vset.GetPoint(Vec3(0.0, j + 0.5, 0.0)); + plane.m_d = -pt[1]; + plane.m_index = j; + planes.PushBack(plane); + } + const short k0 = minV[2]; + const short k1 = maxV[2]; + plane.m_a = 0.0; + plane.m_b = 0.0; + plane.m_c = 1.0; + plane.m_axis = AXIS_Z; + for (short k = k0; k <= k1; k += downsampling) + { + pt = vset.GetPoint(Vec3(0.0, 0.0, k + 0.5)); + plane.m_d = -pt[2]; + plane.m_index = k; + planes.PushBack(plane); + } } void ComputeAxesAlignedClippingPlanes(const TetrahedronSet& tset, const short downsampling, SArray& planes) { - const Vec3 minV = tset.GetMinBB(); - const Vec3 maxV = tset.GetMaxBB(); - const double scale = tset.GetSacle(); - const short i0 = 0; - const short j0 = 0; - const short k0 = 0; - const short i1 = static_cast((maxV[0] - minV[0]) / scale + 0.5); - const short j1 = static_cast((maxV[1] - minV[1]) / scale + 0.5); - const short k1 = static_cast((maxV[2] - minV[2]) / scale + 0.5); + const Vec3 minV = tset.GetMinBB(); + const Vec3 maxV = tset.GetMaxBB(); + const double scale = tset.GetSacle(); + const short i0 = 0; + const short j0 = 0; + const short k0 = 0; + const short i1 = static_cast((maxV[0] - minV[0]) / scale + 0.5); + const short j1 = static_cast((maxV[1] - minV[1]) / scale + 0.5); + const short k1 = static_cast((maxV[2] - minV[2]) / scale + 0.5); - Plane plane; - plane.m_a = 1.0; - plane.m_b = 0.0; - plane.m_c = 0.0; - plane.m_axis = AXIS_X; - for (short i = i0; i <= i1; i += downsampling) { - double x = minV[0] + scale * i; - plane.m_d = -x; - plane.m_index = i; - planes.PushBack(plane); - } - plane.m_a = 0.0; - plane.m_b = 1.0; - plane.m_c = 0.0; - plane.m_axis = AXIS_Y; - for (short j = j0; j <= j1; j += downsampling) { - double y = minV[1] + scale * j; - plane.m_d = -y; - plane.m_index = j; - planes.PushBack(plane); - } - plane.m_a = 0.0; - plane.m_b = 0.0; - plane.m_c = 1.0; - plane.m_axis = AXIS_Z; - for (short k = k0; k <= k1; k += downsampling) { - double z = minV[2] + scale * k; - plane.m_d = -z; - plane.m_index = k; - planes.PushBack(plane); - } + Plane plane; + plane.m_a = 1.0; + plane.m_b = 0.0; + plane.m_c = 0.0; + plane.m_axis = AXIS_X; + for (short i = i0; i <= i1; i += downsampling) + { + double x = minV[0] + scale * i; + plane.m_d = -x; + plane.m_index = i; + planes.PushBack(plane); + } + plane.m_a = 0.0; + plane.m_b = 1.0; + plane.m_c = 0.0; + plane.m_axis = AXIS_Y; + for (short j = j0; j <= j1; j += downsampling) + { + double y = minV[1] + scale * j; + plane.m_d = -y; + plane.m_index = j; + planes.PushBack(plane); + } + plane.m_a = 0.0; + plane.m_b = 0.0; + plane.m_c = 1.0; + plane.m_axis = AXIS_Z; + for (short k = k0; k <= k1; k += downsampling) + { + double z = minV[2] + scale * k; + plane.m_d = -z; + plane.m_index = k; + planes.PushBack(plane); + } } void RefineAxesAlignedClippingPlanes(const VoxelSet& vset, const Plane& bestPlane, const short downsampling, - SArray& planes) + SArray& planes) { - const Vec3 minV = vset.GetMinBBVoxels(); - const Vec3 maxV = vset.GetMaxBBVoxels(); - Vec3 pt; - Plane plane; + const Vec3 minV = vset.GetMinBBVoxels(); + const Vec3 maxV = vset.GetMaxBBVoxels(); + Vec3 pt; + Plane plane; - if (bestPlane.m_axis == AXIS_X) { - const short i0 = MAX(minV[0], bestPlane.m_index - downsampling); - const short i1 = MIN(maxV[0], bestPlane.m_index + downsampling); - plane.m_a = 1.0; - plane.m_b = 0.0; - plane.m_c = 0.0; - plane.m_axis = AXIS_X; - for (short i = i0; i <= i1; ++i) { - pt = vset.GetPoint(Vec3(i + 0.5, 0.0, 0.0)); - plane.m_d = -pt[0]; - plane.m_index = i; - planes.PushBack(plane); - } - } - else if (bestPlane.m_axis == AXIS_Y) { - const short j0 = MAX(minV[1], bestPlane.m_index - downsampling); - const short j1 = MIN(maxV[1], bestPlane.m_index + downsampling); - plane.m_a = 0.0; - plane.m_b = 1.0; - plane.m_c = 0.0; - plane.m_axis = AXIS_Y; - for (short j = j0; j <= j1; ++j) { - pt = vset.GetPoint(Vec3(0.0, j + 0.5, 0.0)); - plane.m_d = -pt[1]; - plane.m_index = j; - planes.PushBack(plane); - } - } - else { - const short k0 = MAX(minV[2], bestPlane.m_index - downsampling); - const short k1 = MIN(maxV[2], bestPlane.m_index + downsampling); - plane.m_a = 0.0; - plane.m_b = 0.0; - plane.m_c = 1.0; - plane.m_axis = AXIS_Z; - for (short k = k0; k <= k1; ++k) { - pt = vset.GetPoint(Vec3(0.0, 0.0, k + 0.5)); - plane.m_d = -pt[2]; - plane.m_index = k; - planes.PushBack(plane); - } - } + if (bestPlane.m_axis == AXIS_X) + { + const short i0 = MAX(minV[0], bestPlane.m_index - downsampling); + const short i1 = MIN(maxV[0], bestPlane.m_index + downsampling); + plane.m_a = 1.0; + plane.m_b = 0.0; + plane.m_c = 0.0; + plane.m_axis = AXIS_X; + for (short i = i0; i <= i1; ++i) + { + pt = vset.GetPoint(Vec3(i + 0.5, 0.0, 0.0)); + plane.m_d = -pt[0]; + plane.m_index = i; + planes.PushBack(plane); + } + } + else if (bestPlane.m_axis == AXIS_Y) + { + const short j0 = MAX(minV[1], bestPlane.m_index - downsampling); + const short j1 = MIN(maxV[1], bestPlane.m_index + downsampling); + plane.m_a = 0.0; + plane.m_b = 1.0; + plane.m_c = 0.0; + plane.m_axis = AXIS_Y; + for (short j = j0; j <= j1; ++j) + { + pt = vset.GetPoint(Vec3(0.0, j + 0.5, 0.0)); + plane.m_d = -pt[1]; + plane.m_index = j; + planes.PushBack(plane); + } + } + else + { + const short k0 = MAX(minV[2], bestPlane.m_index - downsampling); + const short k1 = MIN(maxV[2], bestPlane.m_index + downsampling); + plane.m_a = 0.0; + plane.m_b = 0.0; + plane.m_c = 1.0; + plane.m_axis = AXIS_Z; + for (short k = k0; k <= k1; ++k) + { + pt = vset.GetPoint(Vec3(0.0, 0.0, k + 0.5)); + plane.m_d = -pt[2]; + plane.m_index = k; + planes.PushBack(plane); + } + } } void RefineAxesAlignedClippingPlanes(const TetrahedronSet& tset, const Plane& bestPlane, const short downsampling, - SArray& planes) + SArray& planes) { - const Vec3 minV = tset.GetMinBB(); - const Vec3 maxV = tset.GetMaxBB(); - const double scale = tset.GetSacle(); - Plane plane; + const Vec3 minV = tset.GetMinBB(); + const Vec3 maxV = tset.GetMaxBB(); + const double scale = tset.GetSacle(); + Plane plane; - if (bestPlane.m_axis == AXIS_X) { - const short i0 = MAX(0, bestPlane.m_index - downsampling); - const short i1 = static_cast(MIN((maxV[0] - minV[0]) / scale + 0.5, bestPlane.m_index + downsampling)); - plane.m_a = 1.0; - plane.m_b = 0.0; - plane.m_c = 0.0; - plane.m_axis = AXIS_X; - for (short i = i0; i <= i1; ++i) { - double x = minV[0] + scale * i; - plane.m_d = -x; - plane.m_index = i; - planes.PushBack(plane); - } - } - else if (bestPlane.m_axis == AXIS_Y) { - const short j0 = MAX(0, bestPlane.m_index - downsampling); - const short j1 = static_cast(MIN((maxV[1] - minV[1]) / scale + 0.5, bestPlane.m_index + downsampling)); - plane.m_a = 0.0; - plane.m_b = 1.0; - plane.m_c = 0.0; - plane.m_axis = AXIS_Y; - for (short j = j0; j <= j1; ++j) { - double y = minV[1] + scale * j; - plane.m_d = -y; - plane.m_index = j; - planes.PushBack(plane); - } - } - else { - const short k0 = MAX(0, bestPlane.m_index - downsampling); - const short k1 = static_cast(MIN((maxV[2] - minV[2]) / scale + 0.5, bestPlane.m_index + downsampling)); - plane.m_a = 0.0; - plane.m_b = 0.0; - plane.m_c = 1.0; - plane.m_axis = AXIS_Z; - for (short k = k0; k <= k1; ++k) { - double z = minV[2] + scale * k; - plane.m_d = -z; - plane.m_index = k; - planes.PushBack(plane); - } - } + if (bestPlane.m_axis == AXIS_X) + { + const short i0 = MAX(0, bestPlane.m_index - downsampling); + const short i1 = static_cast(MIN((maxV[0] - minV[0]) / scale + 0.5, bestPlane.m_index + downsampling)); + plane.m_a = 1.0; + plane.m_b = 0.0; + plane.m_c = 0.0; + plane.m_axis = AXIS_X; + for (short i = i0; i <= i1; ++i) + { + double x = minV[0] + scale * i; + plane.m_d = -x; + plane.m_index = i; + planes.PushBack(plane); + } + } + else if (bestPlane.m_axis == AXIS_Y) + { + const short j0 = MAX(0, bestPlane.m_index - downsampling); + const short j1 = static_cast(MIN((maxV[1] - minV[1]) / scale + 0.5, bestPlane.m_index + downsampling)); + plane.m_a = 0.0; + plane.m_b = 1.0; + plane.m_c = 0.0; + plane.m_axis = AXIS_Y; + for (short j = j0; j <= j1; ++j) + { + double y = minV[1] + scale * j; + plane.m_d = -y; + plane.m_index = j; + planes.PushBack(plane); + } + } + else + { + const short k0 = MAX(0, bestPlane.m_index - downsampling); + const short k1 = static_cast(MIN((maxV[2] - minV[2]) / scale + 0.5, bestPlane.m_index + downsampling)); + plane.m_a = 0.0; + plane.m_b = 0.0; + plane.m_c = 1.0; + plane.m_axis = AXIS_Z; + for (short k = k0; k <= k1; ++k) + { + double z = minV[2] + scale * k; + plane.m_d = -z; + plane.m_index = k; + planes.PushBack(plane); + } + } } inline double ComputeLocalConcavity(const double volume, const double volumeCH) { - return fabs(volumeCH - volume) / volumeCH; + return fabs(volumeCH - volume) / volumeCH; } inline double ComputeConcavity(const double volume, const double volumeCH, const double volume0) { - return fabs(volumeCH - volume) / volume0; + return fabs(volumeCH - volume) / volume0; } //#define DEBUG_TEMP void VHACD::ComputeBestClippingPlane(const PrimitiveSet* inputPSet, const double volume, const SArray& planes, - const Vec3& preferredCuttingDirection, const double w, const double alpha, const double beta, - const int convexhullDownsampling, const double progress0, const double progress1, Plane& bestPlane, - double& minConcavity, const Parameters& params) + const Vec3& preferredCuttingDirection, const double w, const double alpha, const double beta, + const int convexhullDownsampling, const double progress0, const double progress1, Plane& bestPlane, + double& minConcavity, const Parameters& params) { - if (GetCancel()) { - return; - } - char msg[256]; - size_t nPrimitives = inputPSet->GetNPrimitives(); - bool oclAcceleration = (nPrimitives > OCL_MIN_NUM_PRIMITIVES && params.m_oclAcceleration && params.m_mode == 0) ? true : false; - int iBest = -1; - int nPlanes = static_cast(planes.Size()); - bool cancel = false; - int done = 0; - double minTotal = MAX_DOUBLE; - double minBalance = MAX_DOUBLE; - double minSymmetry = MAX_DOUBLE; - minConcavity = MAX_DOUBLE; + if (GetCancel()) + { + return; + } + char msg[256]; + size_t nPrimitives = inputPSet->GetNPrimitives(); + bool oclAcceleration = (nPrimitives > OCL_MIN_NUM_PRIMITIVES && params.m_oclAcceleration && params.m_mode == 0) ? true : false; + int iBest = -1; + int nPlanes = static_cast(planes.Size()); + bool cancel = false; + int done = 0; + double minTotal = MAX_DOUBLE; + double minBalance = MAX_DOUBLE; + double minSymmetry = MAX_DOUBLE; + minConcavity = MAX_DOUBLE; - SArray >* chPts = new SArray >[2 * m_ompNumProcessors]; - Mesh* chs = new Mesh[2 * m_ompNumProcessors]; - PrimitiveSet* onSurfacePSet = inputPSet->Create(); - inputPSet->SelectOnSurface(onSurfacePSet); + SArray >* chPts = new SArray >[2 * m_ompNumProcessors]; + Mesh* chs = new Mesh[2 * m_ompNumProcessors]; + PrimitiveSet* onSurfacePSet = inputPSet->Create(); + inputPSet->SelectOnSurface(onSurfacePSet); - PrimitiveSet** psets = 0; - if (!params.m_convexhullApproximation) { - psets = new PrimitiveSet*[2 * m_ompNumProcessors]; - for (int i = 0; i < 2 * m_ompNumProcessors; ++i) { - psets[i] = inputPSet->Create(); - } - } + PrimitiveSet** psets = 0; + if (!params.m_convexhullApproximation) + { + psets = new PrimitiveSet*[2 * m_ompNumProcessors]; + for (int i = 0; i < 2 * m_ompNumProcessors; ++i) + { + psets[i] = inputPSet->Create(); + } + } #ifdef CL_VERSION_1_1 - // allocate OpenCL data structures - cl_mem voxels; - cl_mem* partialVolumes = 0; - size_t globalSize = 0; - size_t nWorkGroups = 0; - double unitVolume = 0.0; - if (oclAcceleration) { - VoxelSet* vset = (VoxelSet*)inputPSet; - const Vec3 minBB = vset->GetMinBB(); - const float fMinBB[4] = { (float)minBB[0], (float)minBB[1], (float)minBB[2], 1.0f }; - const float fSclae[4] = { (float)vset->GetScale(), (float)vset->GetScale(), (float)vset->GetScale(), 0.0f }; - const int nVoxels = (int)nPrimitives; - unitVolume = vset->GetUnitVolume(); - nWorkGroups = (nPrimitives + 4 * m_oclWorkGroupSize - 1) / (4 * m_oclWorkGroupSize); - globalSize = nWorkGroups * m_oclWorkGroupSize; - cl_int error; - voxels = clCreateBuffer(m_oclContext, - CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, - sizeof(Voxel) * nPrimitives, - vset->GetVoxels(), - &error); - if (error != CL_SUCCESS) { - if (params.m_logger) { - params.m_logger->Log("Couldn't create buffer\n"); - } - SetCancel(true); - } + // allocate OpenCL data structures + cl_mem voxels; + cl_mem* partialVolumes = 0; + size_t globalSize = 0; + size_t nWorkGroups = 0; + double unitVolume = 0.0; + if (oclAcceleration) + { + VoxelSet* vset = (VoxelSet*)inputPSet; + const Vec3 minBB = vset->GetMinBB(); + const float fMinBB[4] = {(float)minBB[0], (float)minBB[1], (float)minBB[2], 1.0f}; + const float fSclae[4] = {(float)vset->GetScale(), (float)vset->GetScale(), (float)vset->GetScale(), 0.0f}; + const int nVoxels = (int)nPrimitives; + unitVolume = vset->GetUnitVolume(); + nWorkGroups = (nPrimitives + 4 * m_oclWorkGroupSize - 1) / (4 * m_oclWorkGroupSize); + globalSize = nWorkGroups * m_oclWorkGroupSize; + cl_int error; + voxels = clCreateBuffer(m_oclContext, + CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, + sizeof(Voxel) * nPrimitives, + vset->GetVoxels(), + &error); + if (error != CL_SUCCESS) + { + if (params.m_logger) + { + params.m_logger->Log("Couldn't create buffer\n"); + } + SetCancel(true); + } - partialVolumes = new cl_mem[m_ompNumProcessors]; - for (int i = 0; i < m_ompNumProcessors; ++i) { - partialVolumes[i] = clCreateBuffer(m_oclContext, - CL_MEM_WRITE_ONLY, - sizeof(unsigned int) * 4 * nWorkGroups, - NULL, - &error); - if (error != CL_SUCCESS) { - if (params.m_logger) { - params.m_logger->Log("Couldn't create buffer\n"); - } - SetCancel(true); - break; - } - error = clSetKernelArg(m_oclKernelComputePartialVolumes[i], 0, sizeof(cl_mem), &voxels); - error |= clSetKernelArg(m_oclKernelComputePartialVolumes[i], 1, sizeof(unsigned int), &nVoxels); - error |= clSetKernelArg(m_oclKernelComputePartialVolumes[i], 3, sizeof(float) * 4, fMinBB); - error |= clSetKernelArg(m_oclKernelComputePartialVolumes[i], 4, sizeof(float) * 4, &fSclae); - error |= clSetKernelArg(m_oclKernelComputePartialVolumes[i], 5, sizeof(unsigned int) * 4 * m_oclWorkGroupSize, NULL); - error |= clSetKernelArg(m_oclKernelComputePartialVolumes[i], 6, sizeof(cl_mem), &(partialVolumes[i])); - error |= clSetKernelArg(m_oclKernelComputeSum[i], 0, sizeof(cl_mem), &(partialVolumes[i])); - error |= clSetKernelArg(m_oclKernelComputeSum[i], 2, sizeof(unsigned int) * 4 * m_oclWorkGroupSize, NULL); - if (error != CL_SUCCESS) { - if (params.m_logger) { - params.m_logger->Log("Couldn't kernel atguments \n"); - } - SetCancel(true); - } - } - } -#else // CL_VERSION_1_1 - oclAcceleration = false; -#endif // CL_VERSION_1_1 + partialVolumes = new cl_mem[m_ompNumProcessors]; + for (int i = 0; i < m_ompNumProcessors; ++i) + { + partialVolumes[i] = clCreateBuffer(m_oclContext, + CL_MEM_WRITE_ONLY, + sizeof(unsigned int) * 4 * nWorkGroups, + NULL, + &error); + if (error != CL_SUCCESS) + { + if (params.m_logger) + { + params.m_logger->Log("Couldn't create buffer\n"); + } + SetCancel(true); + break; + } + error = clSetKernelArg(m_oclKernelComputePartialVolumes[i], 0, sizeof(cl_mem), &voxels); + error |= clSetKernelArg(m_oclKernelComputePartialVolumes[i], 1, sizeof(unsigned int), &nVoxels); + error |= clSetKernelArg(m_oclKernelComputePartialVolumes[i], 3, sizeof(float) * 4, fMinBB); + error |= clSetKernelArg(m_oclKernelComputePartialVolumes[i], 4, sizeof(float) * 4, &fSclae); + error |= clSetKernelArg(m_oclKernelComputePartialVolumes[i], 5, sizeof(unsigned int) * 4 * m_oclWorkGroupSize, NULL); + error |= clSetKernelArg(m_oclKernelComputePartialVolumes[i], 6, sizeof(cl_mem), &(partialVolumes[i])); + error |= clSetKernelArg(m_oclKernelComputeSum[i], 0, sizeof(cl_mem), &(partialVolumes[i])); + error |= clSetKernelArg(m_oclKernelComputeSum[i], 2, sizeof(unsigned int) * 4 * m_oclWorkGroupSize, NULL); + if (error != CL_SUCCESS) + { + if (params.m_logger) + { + params.m_logger->Log("Couldn't kernel atguments \n"); + } + SetCancel(true); + } + } + } +#else // CL_VERSION_1_1 + oclAcceleration = false; +#endif // CL_VERSION_1_1 #ifdef DEBUG_TEMP - Timer timerComputeCost; - timerComputeCost.Tic(); -#endif // DEBUG_TEMP + Timer timerComputeCost; + timerComputeCost.Tic(); +#endif // DEBUG_TEMP #if USE_THREAD == 1 && _OPENMP #pragma omp parallel for #endif - for (int x = 0; x < nPlanes; ++x) { - int threadID = 0; + for (int x = 0; x < nPlanes; ++x) + { + int threadID = 0; #if USE_THREAD == 1 && _OPENMP - threadID = omp_get_thread_num(); + threadID = omp_get_thread_num(); #pragma omp flush(cancel) #endif - if (!cancel) { - //Update progress - if (GetCancel()) { - cancel = true; + if (!cancel) + { + //Update progress + if (GetCancel()) + { + cancel = true; #if USE_THREAD == 1 && _OPENMP #pragma omp flush(cancel) #endif - } - Plane plane = planes[x]; + } + Plane plane = planes[x]; - if (oclAcceleration) { + if (oclAcceleration) + { #ifdef CL_VERSION_1_1 - const float fPlane[4] = { (float)plane.m_a, (float)plane.m_b, (float)plane.m_c, (float)plane.m_d }; - cl_int error = clSetKernelArg(m_oclKernelComputePartialVolumes[threadID], 2, sizeof(float) * 4, fPlane); - if (error != CL_SUCCESS) { - if (params.m_logger) { - params.m_logger->Log("Couldn't kernel atguments \n"); - } - SetCancel(true); - } + const float fPlane[4] = {(float)plane.m_a, (float)plane.m_b, (float)plane.m_c, (float)plane.m_d}; + cl_int error = clSetKernelArg(m_oclKernelComputePartialVolumes[threadID], 2, sizeof(float) * 4, fPlane); + if (error != CL_SUCCESS) + { + if (params.m_logger) + { + params.m_logger->Log("Couldn't kernel atguments \n"); + } + SetCancel(true); + } - error = clEnqueueNDRangeKernel(m_oclQueue[threadID], m_oclKernelComputePartialVolumes[threadID], - 1, NULL, &globalSize, &m_oclWorkGroupSize, 0, NULL, NULL); - if (error != CL_SUCCESS) { - if (params.m_logger) { - params.m_logger->Log("Couldn't run kernel \n"); - } - SetCancel(true); - } - int nValues = (int)nWorkGroups; - while (nValues > 1) { - error = clSetKernelArg(m_oclKernelComputeSum[threadID], 1, sizeof(int), &nValues); - if (error != CL_SUCCESS) { - if (params.m_logger) { - params.m_logger->Log("Couldn't kernel atguments \n"); - } - SetCancel(true); - } - size_t nWorkGroups = (nValues + m_oclWorkGroupSize - 1) / m_oclWorkGroupSize; - size_t globalSize = nWorkGroups * m_oclWorkGroupSize; - error = clEnqueueNDRangeKernel(m_oclQueue[threadID], m_oclKernelComputeSum[threadID], - 1, NULL, &globalSize, &m_oclWorkGroupSize, 0, NULL, NULL); - if (error != CL_SUCCESS) { - if (params.m_logger) { - params.m_logger->Log("Couldn't run kernel \n"); - } - SetCancel(true); - } - nValues = (int)nWorkGroups; - } -#endif // CL_VERSION_1_1 - } + error = clEnqueueNDRangeKernel(m_oclQueue[threadID], m_oclKernelComputePartialVolumes[threadID], + 1, NULL, &globalSize, &m_oclWorkGroupSize, 0, NULL, NULL); + if (error != CL_SUCCESS) + { + if (params.m_logger) + { + params.m_logger->Log("Couldn't run kernel \n"); + } + SetCancel(true); + } + int nValues = (int)nWorkGroups; + while (nValues > 1) + { + error = clSetKernelArg(m_oclKernelComputeSum[threadID], 1, sizeof(int), &nValues); + if (error != CL_SUCCESS) + { + if (params.m_logger) + { + params.m_logger->Log("Couldn't kernel atguments \n"); + } + SetCancel(true); + } + size_t nWorkGroups = (nValues + m_oclWorkGroupSize - 1) / m_oclWorkGroupSize; + size_t globalSize = nWorkGroups * m_oclWorkGroupSize; + error = clEnqueueNDRangeKernel(m_oclQueue[threadID], m_oclKernelComputeSum[threadID], + 1, NULL, &globalSize, &m_oclWorkGroupSize, 0, NULL, NULL); + if (error != CL_SUCCESS) + { + if (params.m_logger) + { + params.m_logger->Log("Couldn't run kernel \n"); + } + SetCancel(true); + } + nValues = (int)nWorkGroups; + } +#endif // CL_VERSION_1_1 + } - Mesh& leftCH = chs[threadID]; - Mesh& rightCH = chs[threadID + m_ompNumProcessors]; - rightCH.ResizePoints(0); - leftCH.ResizePoints(0); - rightCH.ResizeTriangles(0); - leftCH.ResizeTriangles(0); + Mesh& leftCH = chs[threadID]; + Mesh& rightCH = chs[threadID + m_ompNumProcessors]; + rightCH.ResizePoints(0); + leftCH.ResizePoints(0); + rightCH.ResizeTriangles(0); + leftCH.ResizeTriangles(0); // compute convex-hulls #ifdef TEST_APPROX_CH - double volumeLeftCH1; - double volumeRightCH1; -#endif //TEST_APPROX_CH - if (params.m_convexhullApproximation) { - SArray >& leftCHPts = chPts[threadID]; - SArray >& rightCHPts = chPts[threadID + m_ompNumProcessors]; - rightCHPts.Resize(0); - leftCHPts.Resize(0); - onSurfacePSet->Intersect(plane, &rightCHPts, &leftCHPts, convexhullDownsampling * 32); - inputPSet->GetConvexHull().Clip(plane, rightCHPts, leftCHPts); - rightCH.ComputeConvexHull((double*)rightCHPts.Data(), rightCHPts.Size()); - leftCH.ComputeConvexHull((double*)leftCHPts.Data(), leftCHPts.Size()); + double volumeLeftCH1; + double volumeRightCH1; +#endif //TEST_APPROX_CH + if (params.m_convexhullApproximation) + { + SArray >& leftCHPts = chPts[threadID]; + SArray >& rightCHPts = chPts[threadID + m_ompNumProcessors]; + rightCHPts.Resize(0); + leftCHPts.Resize(0); + onSurfacePSet->Intersect(plane, &rightCHPts, &leftCHPts, convexhullDownsampling * 32); + inputPSet->GetConvexHull().Clip(plane, rightCHPts, leftCHPts); + rightCH.ComputeConvexHull((double*)rightCHPts.Data(), rightCHPts.Size()); + leftCH.ComputeConvexHull((double*)leftCHPts.Data(), leftCHPts.Size()); #ifdef TEST_APPROX_CH - Mesh leftCH1; - Mesh rightCH1; - VoxelSet right; - VoxelSet left; - onSurfacePSet->Clip(plane, &right, &left); - right.ComputeConvexHull(rightCH1, convexhullDownsampling); - left.ComputeConvexHull(leftCH1, convexhullDownsampling); + Mesh leftCH1; + Mesh rightCH1; + VoxelSet right; + VoxelSet left; + onSurfacePSet->Clip(plane, &right, &left); + right.ComputeConvexHull(rightCH1, convexhullDownsampling); + left.ComputeConvexHull(leftCH1, convexhullDownsampling); - volumeLeftCH1 = leftCH1.ComputeVolume(); - volumeRightCH1 = rightCH1.ComputeVolume(); -#endif //TEST_APPROX_CH - } - else { - PrimitiveSet* const right = psets[threadID]; - PrimitiveSet* const left = psets[threadID + m_ompNumProcessors]; - onSurfacePSet->Clip(plane, right, left); - right->ComputeConvexHull(rightCH, convexhullDownsampling); - left->ComputeConvexHull(leftCH, convexhullDownsampling); - } - double volumeLeftCH = leftCH.ComputeVolume(); - double volumeRightCH = rightCH.ComputeVolume(); + volumeLeftCH1 = leftCH1.ComputeVolume(); + volumeRightCH1 = rightCH1.ComputeVolume(); +#endif //TEST_APPROX_CH + } + else + { + PrimitiveSet* const right = psets[threadID]; + PrimitiveSet* const left = psets[threadID + m_ompNumProcessors]; + onSurfacePSet->Clip(plane, right, left); + right->ComputeConvexHull(rightCH, convexhullDownsampling); + left->ComputeConvexHull(leftCH, convexhullDownsampling); + } + double volumeLeftCH = leftCH.ComputeVolume(); + double volumeRightCH = rightCH.ComputeVolume(); - // compute clipped volumes - double volumeLeft = 0.0; - double volumeRight = 0.0; - if (oclAcceleration) { + // compute clipped volumes + double volumeLeft = 0.0; + double volumeRight = 0.0; + if (oclAcceleration) + { #ifdef CL_VERSION_1_1 - unsigned int volumes[4]; - cl_int error = clEnqueueReadBuffer(m_oclQueue[threadID], partialVolumes[threadID], CL_TRUE, - 0, sizeof(unsigned int) * 4, volumes, 0, NULL, NULL); - size_t nPrimitivesRight = volumes[0] + volumes[1] + volumes[2] + volumes[3]; - size_t nPrimitivesLeft = nPrimitives - nPrimitivesRight; - volumeRight = nPrimitivesRight * unitVolume; - volumeLeft = nPrimitivesLeft * unitVolume; - if (error != CL_SUCCESS) { - if (params.m_logger) { - params.m_logger->Log("Couldn't read buffer \n"); - } - SetCancel(true); - } -#endif // CL_VERSION_1_1 - } - else { - inputPSet->ComputeClippedVolumes(plane, volumeRight, volumeLeft); - } - double concavityLeft = ComputeConcavity(volumeLeft, volumeLeftCH, m_volumeCH0); - double concavityRight = ComputeConcavity(volumeRight, volumeRightCH, m_volumeCH0); - double concavity = (concavityLeft + concavityRight); + unsigned int volumes[4]; + cl_int error = clEnqueueReadBuffer(m_oclQueue[threadID], partialVolumes[threadID], CL_TRUE, + 0, sizeof(unsigned int) * 4, volumes, 0, NULL, NULL); + size_t nPrimitivesRight = volumes[0] + volumes[1] + volumes[2] + volumes[3]; + size_t nPrimitivesLeft = nPrimitives - nPrimitivesRight; + volumeRight = nPrimitivesRight * unitVolume; + volumeLeft = nPrimitivesLeft * unitVolume; + if (error != CL_SUCCESS) + { + if (params.m_logger) + { + params.m_logger->Log("Couldn't read buffer \n"); + } + SetCancel(true); + } +#endif // CL_VERSION_1_1 + } + else + { + inputPSet->ComputeClippedVolumes(plane, volumeRight, volumeLeft); + } + double concavityLeft = ComputeConcavity(volumeLeft, volumeLeftCH, m_volumeCH0); + double concavityRight = ComputeConcavity(volumeRight, volumeRightCH, m_volumeCH0); + double concavity = (concavityLeft + concavityRight); - // compute cost - double balance = alpha * fabs(volumeLeft - volumeRight) / m_volumeCH0; - double d = w * (preferredCuttingDirection[0] * plane.m_a + preferredCuttingDirection[1] * plane.m_b + preferredCuttingDirection[2] * plane.m_c); - double symmetry = beta * d; - double total = concavity + balance + symmetry; + // compute cost + double balance = alpha * fabs(volumeLeft - volumeRight) / m_volumeCH0; + double d = w * (preferredCuttingDirection[0] * plane.m_a + preferredCuttingDirection[1] * plane.m_b + preferredCuttingDirection[2] * plane.m_c); + double symmetry = beta * d; + double total = concavity + balance + symmetry; #if USE_THREAD == 1 && _OPENMP #pragma omp critical #endif - { - if (total < minTotal || (total == minTotal && x < iBest)) { - minConcavity = concavity; - minBalance = balance; - minSymmetry = symmetry; - bestPlane = plane; - minTotal = total; - iBest = x; - } - ++done; - if (!(done & 127)) // reduce update frequency - { - double progress = done * (progress1 - progress0) / nPlanes + progress0; - Update(m_stageProgress, progress, params); - } - } - } - } + { + if (total < minTotal || (total == minTotal && x < iBest)) + { + minConcavity = concavity; + minBalance = balance; + minSymmetry = symmetry; + bestPlane = plane; + minTotal = total; + iBest = x; + } + ++done; + if (!(done & 127)) // reduce update frequency + { + double progress = done * (progress1 - progress0) / nPlanes + progress0; + Update(m_stageProgress, progress, params); + } + } + } + } #ifdef DEBUG_TEMP - timerComputeCost.Toc(); - printf_s("Cost[%i] = %f\n", nPlanes, timerComputeCost.GetElapsedTime()); -#endif // DEBUG_TEMP + timerComputeCost.Toc(); + printf_s("Cost[%i] = %f\n", nPlanes, timerComputeCost.GetElapsedTime()); +#endif // DEBUG_TEMP #ifdef CL_VERSION_1_1 - if (oclAcceleration) { - clReleaseMemObject(voxels); - for (int i = 0; i < m_ompNumProcessors; ++i) { - clReleaseMemObject(partialVolumes[i]); - } - delete[] partialVolumes; - } -#endif // CL_VERSION_1_1 + if (oclAcceleration) + { + clReleaseMemObject(voxels); + for (int i = 0; i < m_ompNumProcessors; ++i) + { + clReleaseMemObject(partialVolumes[i]); + } + delete[] partialVolumes; + } +#endif // CL_VERSION_1_1 - if (psets) { - for (int i = 0; i < 2 * m_ompNumProcessors; ++i) { - delete psets[i]; - } - delete[] psets; - } - delete onSurfacePSet; - delete[] chPts; - delete[] chs; - if (params.m_logger) { - sprintf(msg, "\n\t\t\t Best %04i T=%2.6f C=%2.6f B=%2.6f S=%2.6f (%1.1f, %1.1f, %1.1f, %3.3f)\n\n", iBest, minTotal, minConcavity, minBalance, minSymmetry, bestPlane.m_a, bestPlane.m_b, bestPlane.m_c, bestPlane.m_d); - params.m_logger->Log(msg); - } + if (psets) + { + for (int i = 0; i < 2 * m_ompNumProcessors; ++i) + { + delete psets[i]; + } + delete[] psets; + } + delete onSurfacePSet; + delete[] chPts; + delete[] chs; + if (params.m_logger) + { + sprintf(msg, "\n\t\t\t Best %04i T=%2.6f C=%2.6f B=%2.6f S=%2.6f (%1.1f, %1.1f, %1.1f, %3.3f)\n\n", iBest, minTotal, minConcavity, minBalance, minSymmetry, bestPlane.m_a, bestPlane.m_b, bestPlane.m_c, bestPlane.m_d); + params.m_logger->Log(msg); + } } void VHACD::ComputeACD(const Parameters& params) { - if (GetCancel()) { - return; - } - m_timer.Tic(); + if (GetCancel()) + { + return; + } + m_timer.Tic(); - m_stage = "Approximate Convex Decomposition"; - m_stageProgress = 0.0; - std::ostringstream msg; - if (params.m_logger) { - msg << "+ " << m_stage << std::endl; - params.m_logger->Log(msg.str().c_str()); - } + m_stage = "Approximate Convex Decomposition"; + m_stageProgress = 0.0; + std::ostringstream msg; + if (params.m_logger) + { + msg << "+ " << m_stage << std::endl; + params.m_logger->Log(msg.str().c_str()); + } - SArray parts; - SArray inputParts; - SArray temp; - inputParts.PushBack(m_pset); - m_pset = 0; - SArray planes; - SArray planesRef; - int sub = 0; - bool firstIteration = true; - m_volumeCH0 = 1.0; - while (sub++ < params.m_depth && inputParts.Size() > 0 && !m_cancel) { - msg.str(""); - msg << "Subdivision level " << sub; - m_operation = msg.str(); + SArray parts; + SArray inputParts; + SArray temp; + inputParts.PushBack(m_pset); + m_pset = 0; + SArray planes; + SArray planesRef; + int sub = 0; + bool firstIteration = true; + m_volumeCH0 = 1.0; + while (sub++ < params.m_depth && inputParts.Size() > 0 && !m_cancel) + { + msg.str(""); + msg << "Subdivision level " << sub; + m_operation = msg.str(); - if (params.m_logger) { - msg.str(""); - msg << "\t Subdivision level " << sub << std::endl; - params.m_logger->Log(msg.str().c_str()); - } + if (params.m_logger) + { + msg.str(""); + msg << "\t Subdivision level " << sub << std::endl; + params.m_logger->Log(msg.str().c_str()); + } - double maxConcavity = 0.0; - const size_t nInputParts = inputParts.Size(); - Update(m_stageProgress, 0.0, params); - for (size_t p = 0; p < nInputParts && !m_cancel; ++p) { - const double progress0 = p * 100.0 / nInputParts; - const double progress1 = (p + 0.75) * 100.0 / nInputParts; - const double progress2 = (p + 1.00) * 100.0 / nInputParts; + double maxConcavity = 0.0; + const size_t nInputParts = inputParts.Size(); + Update(m_stageProgress, 0.0, params); + for (size_t p = 0; p < nInputParts && !m_cancel; ++p) + { + const double progress0 = p * 100.0 / nInputParts; + const double progress1 = (p + 0.75) * 100.0 / nInputParts; + const double progress2 = (p + 1.00) * 100.0 / nInputParts; - Update(m_stageProgress, progress0, params); + Update(m_stageProgress, progress0, params); - PrimitiveSet* pset = inputParts[p]; - inputParts[p] = 0; - double volume = pset->ComputeVolume(); - pset->ComputeBB(); - pset->ComputePrincipalAxes(); - if (params.m_pca) { - pset->AlignToPrincipalAxes(); - } + PrimitiveSet* pset = inputParts[p]; + inputParts[p] = 0; + double volume = pset->ComputeVolume(); + pset->ComputeBB(); + pset->ComputePrincipalAxes(); + if (params.m_pca) + { + pset->AlignToPrincipalAxes(); + } - pset->ComputeConvexHull(pset->GetConvexHull()); - double volumeCH = fabs(pset->GetConvexHull().ComputeVolume()); - if (firstIteration) { - m_volumeCH0 = volumeCH; - } + pset->ComputeConvexHull(pset->GetConvexHull()); + double volumeCH = fabs(pset->GetConvexHull().ComputeVolume()); + if (firstIteration) + { + m_volumeCH0 = volumeCH; + } - double concavity = ComputeConcavity(volume, volumeCH, m_volumeCH0); - double error = 1.01 * pset->ComputeMaxVolumeError() / m_volumeCH0; + double concavity = ComputeConcavity(volume, volumeCH, m_volumeCH0); + double error = 1.01 * pset->ComputeMaxVolumeError() / m_volumeCH0; - if (firstIteration) { - firstIteration = false; - } + if (firstIteration) + { + firstIteration = false; + } - if (params.m_logger) { - msg.str(""); - msg << "\t -> Part[" << p - << "] C = " << concavity - << ", E = " << error - << ", VS = " << pset->GetNPrimitivesOnSurf() - << ", VI = " << pset->GetNPrimitivesInsideSurf() - << std::endl; - params.m_logger->Log(msg.str().c_str()); - } + if (params.m_logger) + { + msg.str(""); + msg << "\t -> Part[" << p + << "] C = " << concavity + << ", E = " << error + << ", VS = " << pset->GetNPrimitivesOnSurf() + << ", VI = " << pset->GetNPrimitivesInsideSurf() + << std::endl; + params.m_logger->Log(msg.str().c_str()); + } - if (concavity > params.m_concavity && concavity > error) { - Vec3 preferredCuttingDirection; - double w = ComputePreferredCuttingDirection(pset, preferredCuttingDirection); - planes.Resize(0); - if (params.m_mode == 0) { - VoxelSet* vset = (VoxelSet*)pset; - ComputeAxesAlignedClippingPlanes(*vset, params.m_planeDownsampling, planes); - } - else { - TetrahedronSet* tset = (TetrahedronSet*)pset; - ComputeAxesAlignedClippingPlanes(*tset, params.m_planeDownsampling, planes); - } + if (concavity > params.m_concavity && concavity > error) + { + Vec3 preferredCuttingDirection; + double w = ComputePreferredCuttingDirection(pset, preferredCuttingDirection); + planes.Resize(0); + if (params.m_mode == 0) + { + VoxelSet* vset = (VoxelSet*)pset; + ComputeAxesAlignedClippingPlanes(*vset, params.m_planeDownsampling, planes); + } + else + { + TetrahedronSet* tset = (TetrahedronSet*)pset; + ComputeAxesAlignedClippingPlanes(*tset, params.m_planeDownsampling, planes); + } - if (params.m_logger) { - msg.str(""); - msg << "\t\t [Regular sampling] Number of clipping planes " << planes.Size() << std::endl; - params.m_logger->Log(msg.str().c_str()); - } + if (params.m_logger) + { + msg.str(""); + msg << "\t\t [Regular sampling] Number of clipping planes " << planes.Size() << std::endl; + params.m_logger->Log(msg.str().c_str()); + } - Plane bestPlane; - double minConcavity = MAX_DOUBLE; - ComputeBestClippingPlane(pset, - volume, - planes, - preferredCuttingDirection, - w, - concavity * params.m_alpha, - concavity * params.m_beta, - params.m_convexhullDownsampling, - progress0, - progress1, - bestPlane, - minConcavity, - params); - if (!m_cancel && (params.m_planeDownsampling > 1 || params.m_convexhullDownsampling > 1)) { - planesRef.Resize(0); + Plane bestPlane; + double minConcavity = MAX_DOUBLE; + ComputeBestClippingPlane(pset, + volume, + planes, + preferredCuttingDirection, + w, + concavity * params.m_alpha, + concavity * params.m_beta, + params.m_convexhullDownsampling, + progress0, + progress1, + bestPlane, + minConcavity, + params); + if (!m_cancel && (params.m_planeDownsampling > 1 || params.m_convexhullDownsampling > 1)) + { + planesRef.Resize(0); - if (params.m_mode == 0) { - VoxelSet* vset = (VoxelSet*)pset; - RefineAxesAlignedClippingPlanes(*vset, bestPlane, params.m_planeDownsampling, planesRef); - } - else { - TetrahedronSet* tset = (TetrahedronSet*)pset; - RefineAxesAlignedClippingPlanes(*tset, bestPlane, params.m_planeDownsampling, planesRef); - } + if (params.m_mode == 0) + { + VoxelSet* vset = (VoxelSet*)pset; + RefineAxesAlignedClippingPlanes(*vset, bestPlane, params.m_planeDownsampling, planesRef); + } + else + { + TetrahedronSet* tset = (TetrahedronSet*)pset; + RefineAxesAlignedClippingPlanes(*tset, bestPlane, params.m_planeDownsampling, planesRef); + } - if (params.m_logger) { - msg.str(""); - msg << "\t\t [Refining] Number of clipping planes " << planesRef.Size() << std::endl; - params.m_logger->Log(msg.str().c_str()); - } - ComputeBestClippingPlane(pset, - volume, - planesRef, - preferredCuttingDirection, - w, - concavity * params.m_alpha, - concavity * params.m_beta, - 1, // convexhullDownsampling = 1 - progress1, - progress2, - bestPlane, - minConcavity, - params); - } - if (GetCancel()) { - delete pset; // clean up - break; - } - else { - if (maxConcavity < minConcavity) { - maxConcavity = minConcavity; - } - PrimitiveSet* bestLeft = pset->Create(); - PrimitiveSet* bestRight = pset->Create(); - temp.PushBack(bestLeft); - temp.PushBack(bestRight); - pset->Clip(bestPlane, bestRight, bestLeft); - if (params.m_pca) { - bestRight->RevertAlignToPrincipalAxes(); - bestLeft->RevertAlignToPrincipalAxes(); - } - delete pset; - } - } - else { - if (params.m_pca) { - pset->RevertAlignToPrincipalAxes(); - } - parts.PushBack(pset); - } - } + if (params.m_logger) + { + msg.str(""); + msg << "\t\t [Refining] Number of clipping planes " << planesRef.Size() << std::endl; + params.m_logger->Log(msg.str().c_str()); + } + ComputeBestClippingPlane(pset, + volume, + planesRef, + preferredCuttingDirection, + w, + concavity * params.m_alpha, + concavity * params.m_beta, + 1, // convexhullDownsampling = 1 + progress1, + progress2, + bestPlane, + minConcavity, + params); + } + if (GetCancel()) + { + delete pset; // clean up + break; + } + else + { + if (maxConcavity < minConcavity) + { + maxConcavity = minConcavity; + } + PrimitiveSet* bestLeft = pset->Create(); + PrimitiveSet* bestRight = pset->Create(); + temp.PushBack(bestLeft); + temp.PushBack(bestRight); + pset->Clip(bestPlane, bestRight, bestLeft); + if (params.m_pca) + { + bestRight->RevertAlignToPrincipalAxes(); + bestLeft->RevertAlignToPrincipalAxes(); + } + delete pset; + } + } + else + { + if (params.m_pca) + { + pset->RevertAlignToPrincipalAxes(); + } + parts.PushBack(pset); + } + } - Update(95.0 * (1.0 - maxConcavity) / (1.0 - params.m_concavity), 100.0, params); - if (GetCancel()) { - const size_t nTempParts = temp.Size(); - for (size_t p = 0; p < nTempParts; ++p) { - delete temp[p]; - } - temp.Resize(0); - } - else { - inputParts = temp; - temp.Resize(0); - } - } - const size_t nInputParts = inputParts.Size(); - for (size_t p = 0; p < nInputParts; ++p) { - parts.PushBack(inputParts[p]); - } + Update(95.0 * (1.0 - maxConcavity) / (1.0 - params.m_concavity), 100.0, params); + if (GetCancel()) + { + const size_t nTempParts = temp.Size(); + for (size_t p = 0; p < nTempParts; ++p) + { + delete temp[p]; + } + temp.Resize(0); + } + else + { + inputParts = temp; + temp.Resize(0); + } + } + const size_t nInputParts = inputParts.Size(); + for (size_t p = 0; p < nInputParts; ++p) + { + parts.PushBack(inputParts[p]); + } - if (GetCancel()) { - const size_t nParts = parts.Size(); - for (size_t p = 0; p < nParts; ++p) { - delete parts[p]; - } - return; - } + if (GetCancel()) + { + const size_t nParts = parts.Size(); + for (size_t p = 0; p < nParts; ++p) + { + delete parts[p]; + } + return; + } - m_overallProgress = 90.0; - Update(m_stageProgress, 100.0, params); + m_overallProgress = 90.0; + Update(m_stageProgress, 100.0, params); - msg.str(""); - msg << "Generate convex-hulls"; - m_operation = msg.str(); - size_t nConvexHulls = parts.Size(); - if (params.m_logger) { - msg.str(""); - msg << "+ Generate " << nConvexHulls << " convex-hulls " << std::endl; - params.m_logger->Log(msg.str().c_str()); - } + msg.str(""); + msg << "Generate convex-hulls"; + m_operation = msg.str(); + size_t nConvexHulls = parts.Size(); + if (params.m_logger) + { + msg.str(""); + msg << "+ Generate " << nConvexHulls << " convex-hulls " << std::endl; + params.m_logger->Log(msg.str().c_str()); + } - Update(m_stageProgress, 0.0, params); - m_convexHulls.Resize(0); - for (size_t p = 0; p < nConvexHulls && !m_cancel; ++p) { - Update(m_stageProgress, p * 100.0 / nConvexHulls, params); - m_convexHulls.PushBack(new Mesh); - parts[p]->ComputeConvexHull(*m_convexHulls[p]); - size_t nv = m_convexHulls[p]->GetNPoints(); - double x, y, z; - for (size_t i = 0; i < nv; ++i) { - Vec3& pt = m_convexHulls[p]->GetPoint(i); - x = pt[0]; - y = pt[1]; - z = pt[2]; - pt[0] = m_rot[0][0] * x + m_rot[0][1] * y + m_rot[0][2] * z + m_barycenter[0]; - pt[1] = m_rot[1][0] * x + m_rot[1][1] * y + m_rot[1][2] * z + m_barycenter[1]; - pt[2] = m_rot[2][0] * x + m_rot[2][1] * y + m_rot[2][2] * z + m_barycenter[2]; - } - } + Update(m_stageProgress, 0.0, params); + m_convexHulls.Resize(0); + for (size_t p = 0; p < nConvexHulls && !m_cancel; ++p) + { + Update(m_stageProgress, p * 100.0 / nConvexHulls, params); + m_convexHulls.PushBack(new Mesh); + parts[p]->ComputeConvexHull(*m_convexHulls[p]); + size_t nv = m_convexHulls[p]->GetNPoints(); + double x, y, z; + for (size_t i = 0; i < nv; ++i) + { + Vec3& pt = m_convexHulls[p]->GetPoint(i); + x = pt[0]; + y = pt[1]; + z = pt[2]; + pt[0] = m_rot[0][0] * x + m_rot[0][1] * y + m_rot[0][2] * z + m_barycenter[0]; + pt[1] = m_rot[1][0] * x + m_rot[1][1] * y + m_rot[1][2] * z + m_barycenter[1]; + pt[2] = m_rot[2][0] * x + m_rot[2][1] * y + m_rot[2][2] * z + m_barycenter[2]; + } + } - const size_t nParts = parts.Size(); - for (size_t p = 0; p < nParts; ++p) { - delete parts[p]; - parts[p] = 0; - } - parts.Resize(0); + const size_t nParts = parts.Size(); + for (size_t p = 0; p < nParts; ++p) + { + delete parts[p]; + parts[p] = 0; + } + parts.Resize(0); - if (GetCancel()) { - const size_t nConvexHulls = m_convexHulls.Size(); - for (size_t p = 0; p < nConvexHulls; ++p) { - delete m_convexHulls[p]; - } - m_convexHulls.Clear(); - return; - } + if (GetCancel()) + { + const size_t nConvexHulls = m_convexHulls.Size(); + for (size_t p = 0; p < nConvexHulls; ++p) + { + delete m_convexHulls[p]; + } + m_convexHulls.Clear(); + return; + } - m_overallProgress = 95.0; - Update(100.0, 100.0, params); - m_timer.Toc(); - if (params.m_logger) { - msg.str(""); - msg << "\t time " << m_timer.GetElapsedTime() / 1000.0 << "s" << std::endl; - params.m_logger->Log(msg.str().c_str()); - } + m_overallProgress = 95.0; + Update(100.0, 100.0, params); + m_timer.Toc(); + if (params.m_logger) + { + msg.str(""); + msg << "\t time " << m_timer.GetElapsedTime() / 1000.0 << "s" << std::endl; + params.m_logger->Log(msg.str().c_str()); + } } void AddPoints(const Mesh* const mesh, SArray >& pts) { - const int n = (int)mesh->GetNPoints(); - for (int i = 0; i < n; ++i) { - pts.PushBack(mesh->GetPoint(i)); - } + const int n = (int)mesh->GetNPoints(); + for (int i = 0; i < n; ++i) + { + pts.PushBack(mesh->GetPoint(i)); + } } void ComputeConvexHull(const Mesh* const ch1, const Mesh* const ch2, SArray >& pts, Mesh* const combinedCH) { - pts.Resize(0); - AddPoints(ch1, pts); - AddPoints(ch2, pts); + pts.Resize(0); + AddPoints(ch1, pts); + AddPoints(ch2, pts); - btConvexHullComputer ch; - ch.compute((double*)pts.Data(), 3 * sizeof(double), (int)pts.Size(), -1.0, -1.0); - combinedCH->ResizePoints(0); - combinedCH->ResizeTriangles(0); - for (int v = 0; v < ch.vertices.size(); v++) { - combinedCH->AddPoint(Vec3(ch.vertices[v].getX(), ch.vertices[v].getY(), ch.vertices[v].getZ())); - } - const int nt = ch.faces.size(); - for (int t = 0; t < nt; ++t) { - const btConvexHullComputer::Edge* sourceEdge = &(ch.edges[ch.faces[t]]); - int a = sourceEdge->getSourceVertex(); - int b = sourceEdge->getTargetVertex(); - const btConvexHullComputer::Edge* edge = sourceEdge->getNextEdgeOfFace(); - int c = edge->getTargetVertex(); - while (c != a) { - combinedCH->AddTriangle(Vec3(a, b, c)); - edge = edge->getNextEdgeOfFace(); - b = c; - c = edge->getTargetVertex(); - } - } + btConvexHullComputer ch; + ch.compute((double*)pts.Data(), 3 * sizeof(double), (int)pts.Size(), -1.0, -1.0); + combinedCH->ResizePoints(0); + combinedCH->ResizeTriangles(0); + for (int v = 0; v < ch.vertices.size(); v++) + { + combinedCH->AddPoint(Vec3(ch.vertices[v].getX(), ch.vertices[v].getY(), ch.vertices[v].getZ())); + } + const int nt = ch.faces.size(); + for (int t = 0; t < nt; ++t) + { + const btConvexHullComputer::Edge* sourceEdge = &(ch.edges[ch.faces[t]]); + int a = sourceEdge->getSourceVertex(); + int b = sourceEdge->getTargetVertex(); + const btConvexHullComputer::Edge* edge = sourceEdge->getNextEdgeOfFace(); + int c = edge->getTargetVertex(); + while (c != a) + { + combinedCH->AddTriangle(Vec3(a, b, c)); + edge = edge->getNextEdgeOfFace(); + b = c; + c = edge->getTargetVertex(); + } + } } void VHACD::MergeConvexHulls(const Parameters& params) { - if (GetCancel()) { - return; - } - m_timer.Tic(); + if (GetCancel()) + { + return; + } + m_timer.Tic(); - m_stage = "Merge Convex Hulls"; + m_stage = "Merge Convex Hulls"; - std::ostringstream msg; - if (params.m_logger) { - msg << "+ " << m_stage << std::endl; - params.m_logger->Log(msg.str().c_str()); - } + std::ostringstream msg; + if (params.m_logger) + { + msg << "+ " << m_stage << std::endl; + params.m_logger->Log(msg.str().c_str()); + } - size_t nConvexHulls = m_convexHulls.Size(); - int iteration = 0; - if (nConvexHulls > 1 && !m_cancel) { - const double threshold = params.m_gamma; - SArray > pts; - Mesh combinedCH; + size_t nConvexHulls = m_convexHulls.Size(); + int iteration = 0; + if (nConvexHulls > 1 && !m_cancel) + { + const double threshold = params.m_gamma; + SArray > pts; + Mesh combinedCH; - // Populate the cost matrix - size_t idx = 0; - SArray costMatrix; - costMatrix.Resize(((nConvexHulls * nConvexHulls) - nConvexHulls) >> 1); - for (size_t p1 = 1; p1 < nConvexHulls; ++p1) { - const float volume1 = m_convexHulls[p1]->ComputeVolume(); - for (size_t p2 = 0; p2 < p1; ++p2) { - ComputeConvexHull(m_convexHulls[p1], m_convexHulls[p2], pts, &combinedCH); - costMatrix[idx++] = ComputeConcavity(volume1 + m_convexHulls[p2]->ComputeVolume(), combinedCH.ComputeVolume(), m_volumeCH0); - } - } + // Populate the cost matrix + size_t idx = 0; + SArray costMatrix; + costMatrix.Resize(((nConvexHulls * nConvexHulls) - nConvexHulls) >> 1); + for (size_t p1 = 1; p1 < nConvexHulls; ++p1) + { + const float volume1 = m_convexHulls[p1]->ComputeVolume(); + for (size_t p2 = 0; p2 < p1; ++p2) + { + ComputeConvexHull(m_convexHulls[p1], m_convexHulls[p2], pts, &combinedCH); + costMatrix[idx++] = ComputeConcavity(volume1 + m_convexHulls[p2]->ComputeVolume(), combinedCH.ComputeVolume(), m_volumeCH0); + } + } - // Until we cant merge below the maximum cost - size_t costSize = m_convexHulls.Size(); - while (!m_cancel) { - msg.str(""); - msg << "Iteration " << iteration++; - m_operation = msg.str(); + // Until we cant merge below the maximum cost + size_t costSize = m_convexHulls.Size(); + while (!m_cancel) + { + msg.str(""); + msg << "Iteration " << iteration++; + m_operation = msg.str(); - // Search for lowest cost - float bestCost = (std::numeric_limits::max)(); - const size_t addr = FindMinimumElement(costMatrix.Data(), &bestCost, 0, costMatrix.Size()); + // Search for lowest cost + float bestCost = (std::numeric_limits::max)(); + const size_t addr = FindMinimumElement(costMatrix.Data(), &bestCost, 0, costMatrix.Size()); - // Check if we should merge these hulls - if (bestCost >= threshold) { - break; - } + // Check if we should merge these hulls + if (bestCost >= threshold) + { + break; + } double nr = 1 + (8 * addr); - const size_t addrI = (static_cast(sqrt(nr)) - 1) >> 1; - const size_t p1 = addrI + 1; - const size_t p2 = addr - ((addrI * (addrI + 1)) >> 1); - assert(p1 >= 0); - assert(p2 >= 0); - assert(p1 < costSize); - assert(p2 < costSize); + const size_t addrI = (static_cast(sqrt(nr)) - 1) >> 1; + const size_t p1 = addrI + 1; + const size_t p2 = addr - ((addrI * (addrI + 1)) >> 1); + assert(p1 >= 0); + assert(p2 >= 0); + assert(p1 < costSize); + assert(p2 < costSize); - if (params.m_logger) { - msg.str(""); - msg << "\t\t Merging (" << p1 << ", " << p2 << ") " << bestCost << std::endl - << std::endl; - params.m_logger->Log(msg.str().c_str()); - } + if (params.m_logger) + { + msg.str(""); + msg << "\t\t Merging (" << p1 << ", " << p2 << ") " << bestCost << std::endl + << std::endl; + params.m_logger->Log(msg.str().c_str()); + } - // Make the lowest cost row and column into a new hull - Mesh* cch = new Mesh; - ComputeConvexHull(m_convexHulls[p1], m_convexHulls[p2], pts, cch); - delete m_convexHulls[p2]; - m_convexHulls[p2] = cch; + // Make the lowest cost row and column into a new hull + Mesh* cch = new Mesh; + ComputeConvexHull(m_convexHulls[p1], m_convexHulls[p2], pts, cch); + delete m_convexHulls[p2]; + m_convexHulls[p2] = cch; - delete m_convexHulls[p1]; - std::swap(m_convexHulls[p1], m_convexHulls[m_convexHulls.Size() - 1]); - m_convexHulls.PopBack(); + delete m_convexHulls[p1]; + std::swap(m_convexHulls[p1], m_convexHulls[m_convexHulls.Size() - 1]); + m_convexHulls.PopBack(); - costSize = costSize - 1; + costSize = costSize - 1; - // Calculate costs versus the new hull - size_t rowIdx = ((p2 - 1) * p2) >> 1; - const float volume1 = m_convexHulls[p2]->ComputeVolume(); - for (size_t i = 0; (i < p2) && (!m_cancel); ++i) { - ComputeConvexHull(m_convexHulls[p2], m_convexHulls[i], pts, &combinedCH); - costMatrix[rowIdx++] = ComputeConcavity(volume1 + m_convexHulls[i]->ComputeVolume(), combinedCH.ComputeVolume(), m_volumeCH0); - } + // Calculate costs versus the new hull + size_t rowIdx = ((p2 - 1) * p2) >> 1; + const float volume1 = m_convexHulls[p2]->ComputeVolume(); + for (size_t i = 0; (i < p2) && (!m_cancel); ++i) + { + ComputeConvexHull(m_convexHulls[p2], m_convexHulls[i], pts, &combinedCH); + costMatrix[rowIdx++] = ComputeConcavity(volume1 + m_convexHulls[i]->ComputeVolume(), combinedCH.ComputeVolume(), m_volumeCH0); + } - rowIdx += p2; - for (size_t i = p2 + 1; (i < costSize) && (!m_cancel); ++i) { - ComputeConvexHull(m_convexHulls[p2], m_convexHulls[i], pts, &combinedCH); - costMatrix[rowIdx] = ComputeConcavity(volume1 + m_convexHulls[i]->ComputeVolume(), combinedCH.ComputeVolume(), m_volumeCH0); - rowIdx += i; - assert(rowIdx >= 0); - } + rowIdx += p2; + for (size_t i = p2 + 1; (i < costSize) && (!m_cancel); ++i) + { + ComputeConvexHull(m_convexHulls[p2], m_convexHulls[i], pts, &combinedCH); + costMatrix[rowIdx] = ComputeConcavity(volume1 + m_convexHulls[i]->ComputeVolume(), combinedCH.ComputeVolume(), m_volumeCH0); + rowIdx += i; + assert(rowIdx >= 0); + } - // Move the top column in to replace its space - const size_t erase_idx = ((costSize - 1) * costSize) >> 1; - if (p1 < costSize) { - rowIdx = (addrI * p1) >> 1; - size_t top_row = erase_idx; - for (size_t i = 0; i < p1; ++i) { - if (i != p2) { - costMatrix[rowIdx] = costMatrix[top_row]; - } - ++rowIdx; - ++top_row; - } + // Move the top column in to replace its space + const size_t erase_idx = ((costSize - 1) * costSize) >> 1; + if (p1 < costSize) + { + rowIdx = (addrI * p1) >> 1; + size_t top_row = erase_idx; + for (size_t i = 0; i < p1; ++i) + { + if (i != p2) + { + costMatrix[rowIdx] = costMatrix[top_row]; + } + ++rowIdx; + ++top_row; + } - ++top_row; - rowIdx += p1; - for (size_t i = p1 + 1; i < (costSize + 1); ++i) { - costMatrix[rowIdx] = costMatrix[top_row++]; - rowIdx += i; - assert(rowIdx >= 0); - } - } - costMatrix.Resize(erase_idx); - } - } - m_overallProgress = 99.0; - Update(100.0, 100.0, params); - m_timer.Toc(); - if (params.m_logger) { - msg.str(""); - msg << "\t time " << m_timer.GetElapsedTime() / 1000.0 << "s" << std::endl; - params.m_logger->Log(msg.str().c_str()); - } + ++top_row; + rowIdx += p1; + for (size_t i = p1 + 1; i < (costSize + 1); ++i) + { + costMatrix[rowIdx] = costMatrix[top_row++]; + rowIdx += i; + assert(rowIdx >= 0); + } + } + costMatrix.Resize(erase_idx); + } + } + m_overallProgress = 99.0; + Update(100.0, 100.0, params); + m_timer.Toc(); + if (params.m_logger) + { + msg.str(""); + msg << "\t time " << m_timer.GetElapsedTime() / 1000.0 << "s" << std::endl; + params.m_logger->Log(msg.str().c_str()); + } } void SimplifyConvexHull(Mesh* const ch, const size_t nvertices, const double minVolume) { - if (nvertices <= 4) { - return; - } - ICHull icHull; - icHull.AddPoints(ch->GetPointsBuffer(), ch->GetNPoints()); - icHull.Process((unsigned int)nvertices, minVolume); - TMMesh& mesh = icHull.GetMesh(); - const size_t nT = mesh.GetNTriangles(); - const size_t nV = mesh.GetNVertices(); - ch->ResizePoints(nV); - ch->ResizeTriangles(nT); - mesh.GetIFS(ch->GetPointsBuffer(), ch->GetTrianglesBuffer()); + if (nvertices <= 4) + { + return; + } + ICHull icHull; + icHull.AddPoints(ch->GetPointsBuffer(), ch->GetNPoints()); + icHull.Process((unsigned int)nvertices, minVolume); + TMMesh& mesh = icHull.GetMesh(); + const size_t nT = mesh.GetNTriangles(); + const size_t nV = mesh.GetNVertices(); + ch->ResizePoints(nV); + ch->ResizeTriangles(nT); + mesh.GetIFS(ch->GetPointsBuffer(), ch->GetTrianglesBuffer()); } void VHACD::SimplifyConvexHulls(const Parameters& params) { - if (m_cancel || params.m_maxNumVerticesPerCH < 4) { - return; - } - m_timer.Tic(); + if (m_cancel || params.m_maxNumVerticesPerCH < 4) + { + return; + } + m_timer.Tic(); - m_stage = "Simplify convex-hulls"; - m_operation = "Simplify convex-hulls"; + m_stage = "Simplify convex-hulls"; + m_operation = "Simplify convex-hulls"; - std::ostringstream msg; - const size_t nConvexHulls = m_convexHulls.Size(); - if (params.m_logger) { - msg << "+ Simplify " << nConvexHulls << " convex-hulls " << std::endl; - params.m_logger->Log(msg.str().c_str()); - } + std::ostringstream msg; + const size_t nConvexHulls = m_convexHulls.Size(); + if (params.m_logger) + { + msg << "+ Simplify " << nConvexHulls << " convex-hulls " << std::endl; + params.m_logger->Log(msg.str().c_str()); + } - Update(0.0, 0.0, params); - for (size_t i = 0; i < nConvexHulls && !m_cancel; ++i) { - if (params.m_logger) { - msg.str(""); - msg << "\t\t Simplify CH[" << std::setfill('0') << std::setw(5) << i << "] " << m_convexHulls[i]->GetNPoints() << " V, " << m_convexHulls[i]->GetNTriangles() << " T" << std::endl; - params.m_logger->Log(msg.str().c_str()); - } - SimplifyConvexHull(m_convexHulls[i], params.m_maxNumVerticesPerCH, m_volumeCH0 * params.m_minVolumePerCH); - } + Update(0.0, 0.0, params); + for (size_t i = 0; i < nConvexHulls && !m_cancel; ++i) + { + if (params.m_logger) + { + msg.str(""); + msg << "\t\t Simplify CH[" << std::setfill('0') << std::setw(5) << i << "] " << m_convexHulls[i]->GetNPoints() << " V, " << m_convexHulls[i]->GetNTriangles() << " T" << std::endl; + params.m_logger->Log(msg.str().c_str()); + } + SimplifyConvexHull(m_convexHulls[i], params.m_maxNumVerticesPerCH, m_volumeCH0 * params.m_minVolumePerCH); + } - m_overallProgress = 100.0; - Update(100.0, 100.0, params); - m_timer.Toc(); - if (params.m_logger) { - msg.str(""); - msg << "\t time " << m_timer.GetElapsedTime() / 1000.0 << "s" << std::endl; - params.m_logger->Log(msg.str().c_str()); - } -} + m_overallProgress = 100.0; + Update(100.0, 100.0, params); + m_timer.Toc(); + if (params.m_logger) + { + msg.str(""); + msg << "\t time " << m_timer.GetElapsedTime() / 1000.0 << "s" << std::endl; + params.m_logger->Log(msg.str().c_str()); + } } +} // namespace VHACD diff --git a/Extras/VHACD/src/btAlignedAllocator.cpp b/Extras/VHACD/src/btAlignedAllocator.cpp index e69442f67..6b3c07892 100644 --- a/Extras/VHACD/src/btAlignedAllocator.cpp +++ b/Extras/VHACD/src/btAlignedAllocator.cpp @@ -17,16 +17,16 @@ subject to the following restrictions: int gNumAlignedAllocs = 0; int gNumAlignedFree = 0; -int gTotalBytesAlignedAllocs = 0; //detect memory leaks +int gTotalBytesAlignedAllocs = 0; //detect memory leaks static void* btAllocDefault(size_t size) { - return malloc(size); + return malloc(size); } static void btFreeDefault(void* ptr) { - free(ptr); + free(ptr); } static btAllocFunc* sAllocFunc = btAllocDefault; @@ -36,52 +36,55 @@ static btFreeFunc* sFreeFunc = btFreeDefault; #include static void* btAlignedAllocDefault(size_t size, int alignment) { - return _aligned_malloc(size, (size_t)alignment); + return _aligned_malloc(size, (size_t)alignment); } static void btAlignedFreeDefault(void* ptr) { - _aligned_free(ptr); + _aligned_free(ptr); } #elif defined(__CELLOS_LV2__) #include static inline void* btAlignedAllocDefault(size_t size, int alignment) { - return memalign(alignment, size); + return memalign(alignment, size); } static inline void btAlignedFreeDefault(void* ptr) { - free(ptr); + free(ptr); } #else static inline void* btAlignedAllocDefault(size_t size, int alignment) { - void* ret; - char* real; - unsigned long offset; + void* ret; + char* real; + unsigned long offset; - real = (char*)sAllocFunc(size + sizeof(void*) + (alignment - 1)); - if (real) { - offset = (alignment - (unsigned long)(real + sizeof(void*))) & (alignment - 1); - ret = (void*)((real + sizeof(void*)) + offset); - *((void**)(ret)-1) = (void*)(real); - } - else { - ret = (void*)(real); - } - return (ret); + real = (char*)sAllocFunc(size + sizeof(void*) + (alignment - 1)); + if (real) + { + offset = (alignment - (unsigned long)(real + sizeof(void*))) & (alignment - 1); + ret = (void*)((real + sizeof(void*)) + offset); + *((void**)(ret)-1) = (void*)(real); + } + else + { + ret = (void*)(real); + } + return (ret); } static inline void btAlignedFreeDefault(void* ptr) { - void* real; + void* real; - if (ptr) { - real = *((void**)(ptr)-1); - sFreeFunc(real); - } + if (ptr) + { + real = *((void**)(ptr)-1); + sFreeFunc(real); + } } #endif @@ -90,14 +93,14 @@ static btAlignedFreeFunc* sAlignedFreeFunc = btAlignedFreeDefault; void btAlignedAllocSetCustomAligned(btAlignedAllocFunc* allocFunc, btAlignedFreeFunc* freeFunc) { - sAlignedAllocFunc = allocFunc ? allocFunc : btAlignedAllocDefault; - sAlignedFreeFunc = freeFunc ? freeFunc : btAlignedFreeDefault; + sAlignedAllocFunc = allocFunc ? allocFunc : btAlignedAllocDefault; + sAlignedFreeFunc = freeFunc ? freeFunc : btAlignedFreeDefault; } void btAlignedAllocSetCustom(btAllocFunc* allocFunc, btFreeFunc* freeFunc) { - sAllocFunc = allocFunc ? allocFunc : btAllocDefault; - sFreeFunc = freeFunc ? freeFunc : btFreeDefault; + sAllocFunc = allocFunc ? allocFunc : btAllocDefault; + sFreeFunc = freeFunc ? freeFunc : btFreeDefault; } #ifdef BT_DEBUG_MEMORY_ALLOCATIONS @@ -106,71 +109,75 @@ void btAlignedAllocSetCustom(btAllocFunc* allocFunc, btFreeFunc* freeFunc) void* btAlignedAllocInternal(size_t size, int alignment, int line, char* filename) { - void* ret; - char* real; - unsigned long offset; + void* ret; + char* real; + unsigned long offset; - gTotalBytesAlignedAllocs += size; - gNumAlignedAllocs++; + gTotalBytesAlignedAllocs += size; + gNumAlignedAllocs++; - real = (char*)sAllocFunc(size + 2 * sizeof(void*) + (alignment - 1)); - if (real) { - offset = (alignment - (unsigned long)(real + 2 * sizeof(void*))) & (alignment - 1); - ret = (void*)((real + 2 * sizeof(void*)) + offset); - *((void**)(ret)-1) = (void*)(real); - *((int*)(ret)-2) = size; - } - else { - ret = (void*)(real); //?? - } + real = (char*)sAllocFunc(size + 2 * sizeof(void*) + (alignment - 1)); + if (real) + { + offset = (alignment - (unsigned long)(real + 2 * sizeof(void*))) & (alignment - 1); + ret = (void*)((real + 2 * sizeof(void*)) + offset); + *((void**)(ret)-1) = (void*)(real); + *((int*)(ret)-2) = size; + } + else + { + ret = (void*)(real); //?? + } - printf("allocation#%d at address %x, from %s,line %d, size %d\n", gNumAlignedAllocs, real, filename, line, size); + printf("allocation#%d at address %x, from %s,line %d, size %d\n", gNumAlignedAllocs, real, filename, line, size); - int* ptr = (int*)ret; - *ptr = 12; - return (ret); + int* ptr = (int*)ret; + *ptr = 12; + return (ret); } void btAlignedFreeInternal(void* ptr, int line, char* filename) { + void* real; + gNumAlignedFree++; - void* real; - gNumAlignedFree++; + if (ptr) + { + real = *((void**)(ptr)-1); + int size = *((int*)(ptr)-2); + gTotalBytesAlignedAllocs -= size; - if (ptr) { - real = *((void**)(ptr)-1); - int size = *((int*)(ptr)-2); - gTotalBytesAlignedAllocs -= size; + printf("free #%d at address %x, from %s,line %d, size %d\n", gNumAlignedFree, real, filename, line, size); - printf("free #%d at address %x, from %s,line %d, size %d\n", gNumAlignedFree, real, filename, line, size); - - sFreeFunc(real); - } - else { - printf("NULL ptr\n"); - } + sFreeFunc(real); + } + else + { + printf("NULL ptr\n"); + } } -#else //BT_DEBUG_MEMORY_ALLOCATIONS +#else //BT_DEBUG_MEMORY_ALLOCATIONS void* btAlignedAllocInternal(size_t size, int alignment) { - gNumAlignedAllocs++; - void* ptr; - ptr = sAlignedAllocFunc(size, alignment); - // printf("btAlignedAllocInternal %d, %x\n",size,ptr); - return ptr; + gNumAlignedAllocs++; + void* ptr; + ptr = sAlignedAllocFunc(size, alignment); + // printf("btAlignedAllocInternal %d, %x\n",size,ptr); + return ptr; } void btAlignedFreeInternal(void* ptr) { - if (!ptr) { - return; - } + if (!ptr) + { + return; + } - gNumAlignedFree++; - // printf("btAlignedFreeInternal %x\n",ptr); - sAlignedFreeFunc(ptr); + gNumAlignedFree++; + // printf("btAlignedFreeInternal %x\n",ptr); + sAlignedFreeFunc(ptr); } -#endif //BT_DEBUG_MEMORY_ALLOCATIONS +#endif //BT_DEBUG_MEMORY_ALLOCATIONS diff --git a/Extras/VHACD/src/btConvexHullComputer.cpp b/Extras/VHACD/src/btConvexHullComputer.cpp index a84f7c02a..65f43115e 100644 --- a/Extras/VHACD/src/btConvexHullComputer.cpp +++ b/Extras/VHACD/src/btConvexHullComputer.cpp @@ -47,2429 +47,2706 @@ typedef unsigned long long int uint64_t; // Convex hull implementation based on Preparata and Hong // Ole Kniemeyer, MAXON Computer GmbH -class btConvexHullInternal { +class btConvexHullInternal +{ public: - class Point64 { - public: - int64_t x; - int64_t y; - int64_t z; + class Point64 + { + public: + int64_t x; + int64_t y; + int64_t z; - Point64(int64_t x, int64_t y, int64_t z) - : x(x) - , y(y) - , z(z) - { - } + Point64(int64_t x, int64_t y, int64_t z) + : x(x), y(y), z(z) + { + } - bool isZero() - { - return (x == 0) && (y == 0) && (z == 0); - } + bool isZero() + { + return (x == 0) && (y == 0) && (z == 0); + } - int64_t dot(const Point64& b) const - { - return x * b.x + y * b.y + z * b.z; - } - }; + int64_t dot(const Point64& b) const + { + return x * b.x + y * b.y + z * b.z; + } + }; - class Point32 { - public: - int32_t x; - int32_t y; - int32_t z; - int index; + class Point32 + { + public: + int32_t x; + int32_t y; + int32_t z; + int index; - Point32() - { - } + Point32() + { + } - Point32(int32_t x, int32_t y, int32_t z) - : x(x) - , y(y) - , z(z) - , index(-1) - { - } + Point32(int32_t x, int32_t y, int32_t z) + : x(x), y(y), z(z), index(-1) + { + } - bool operator==(const Point32& b) const - { - return (x == b.x) && (y == b.y) && (z == b.z); - } + bool operator==(const Point32& b) const + { + return (x == b.x) && (y == b.y) && (z == b.z); + } - bool operator!=(const Point32& b) const - { - return (x != b.x) || (y != b.y) || (z != b.z); - } + bool operator!=(const Point32& b) const + { + return (x != b.x) || (y != b.y) || (z != b.z); + } - bool isZero() - { - return (x == 0) && (y == 0) && (z == 0); - } + bool isZero() + { + return (x == 0) && (y == 0) && (z == 0); + } - Point64 cross(const Point32& b) const - { - return Point64(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); - } + Point64 cross(const Point32& b) const + { + return Point64(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); + } - Point64 cross(const Point64& b) const - { - return Point64(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); - } + Point64 cross(const Point64& b) const + { + return Point64(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); + } - int64_t dot(const Point32& b) const - { - return x * b.x + y * b.y + z * b.z; - } + int64_t dot(const Point32& b) const + { + return x * b.x + y * b.y + z * b.z; + } - int64_t dot(const Point64& b) const - { - return x * b.x + y * b.y + z * b.z; - } + int64_t dot(const Point64& b) const + { + return x * b.x + y * b.y + z * b.z; + } - Point32 operator+(const Point32& b) const - { - return Point32(x + b.x, y + b.y, z + b.z); - } + Point32 operator+(const Point32& b) const + { + return Point32(x + b.x, y + b.y, z + b.z); + } - Point32 operator-(const Point32& b) const - { - return Point32(x - b.x, y - b.y, z - b.z); - } - }; + Point32 operator-(const Point32& b) const + { + return Point32(x - b.x, y - b.y, z - b.z); + } + }; - class Int128 { - public: - uint64_t low; - uint64_t high; + class Int128 + { + public: + uint64_t low; + uint64_t high; - Int128() - { - } + Int128() + { + } - Int128(uint64_t low, uint64_t high) - : low(low) - , high(high) - { - } + Int128(uint64_t low, uint64_t high) + : low(low), high(high) + { + } - Int128(uint64_t low) - : low(low) - , high(0) - { - } + Int128(uint64_t low) + : low(low), high(0) + { + } - Int128(int64_t value) - : low(value) - , high((value >= 0) ? 0 : (uint64_t)-1LL) - { - } + Int128(int64_t value) + : low(value), high((value >= 0) ? 0 : (uint64_t)-1LL) + { + } - static Int128 mul(int64_t a, int64_t b); + static Int128 mul(int64_t a, int64_t b); - static Int128 mul(uint64_t a, uint64_t b); + static Int128 mul(uint64_t a, uint64_t b); - Int128 operator-() const - { - return Int128((uint64_t) - (int64_t)low, ~high + (low == 0)); - } + Int128 operator-() const + { + return Int128((uint64_t) - (int64_t)low, ~high + (low == 0)); + } - Int128 operator+(const Int128& b) const - { + Int128 operator+(const Int128& b) const + { #ifdef USE_X86_64_ASM - Int128 result; - __asm__("addq %[bl], %[rl]\n\t" - "adcq %[bh], %[rh]\n\t" - : [rl] "=r"(result.low), [rh] "=r"(result.high) - : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) - : "cc"); - return result; + Int128 result; + __asm__( + "addq %[bl], %[rl]\n\t" + "adcq %[bh], %[rh]\n\t" + : [rl] "=r"(result.low), [rh] "=r"(result.high) + : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) + : "cc"); + return result; #else - uint64_t lo = low + b.low; - return Int128(lo, high + b.high + (lo < low)); + uint64_t lo = low + b.low; + return Int128(lo, high + b.high + (lo < low)); #endif - } + } - Int128 operator-(const Int128& b) const - { + Int128 operator-(const Int128& b) const + { #ifdef USE_X86_64_ASM - Int128 result; - __asm__("subq %[bl], %[rl]\n\t" - "sbbq %[bh], %[rh]\n\t" - : [rl] "=r"(result.low), [rh] "=r"(result.high) - : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) - : "cc"); - return result; + Int128 result; + __asm__( + "subq %[bl], %[rl]\n\t" + "sbbq %[bh], %[rh]\n\t" + : [rl] "=r"(result.low), [rh] "=r"(result.high) + : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) + : "cc"); + return result; #else - return *this + -b; + return *this + -b; #endif - } + } - Int128& operator+=(const Int128& b) - { + Int128& operator+=(const Int128& b) + { #ifdef USE_X86_64_ASM - __asm__("addq %[bl], %[rl]\n\t" - "adcq %[bh], %[rh]\n\t" - : [rl] "=r"(low), [rh] "=r"(high) - : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) - : "cc"); + __asm__( + "addq %[bl], %[rl]\n\t" + "adcq %[bh], %[rh]\n\t" + : [rl] "=r"(low), [rh] "=r"(high) + : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) + : "cc"); #else - uint64_t lo = low + b.low; - if (lo < low) { - ++high; - } - low = lo; - high += b.high; + uint64_t lo = low + b.low; + if (lo < low) + { + ++high; + } + low = lo; + high += b.high; #endif - return *this; - } + return *this; + } - Int128& operator++() - { - if (++low == 0) { - ++high; - } - return *this; - } + Int128& operator++() + { + if (++low == 0) + { + ++high; + } + return *this; + } - Int128 operator*(int64_t b) const; + Int128 operator*(int64_t b) const; - btScalar toScalar() const - { - return ((int64_t)high >= 0) ? btScalar(high) * (btScalar(0x100000000LL) * btScalar(0x100000000LL)) + btScalar(low) - : -(-*this).toScalar(); - } + btScalar toScalar() const + { + return ((int64_t)high >= 0) ? btScalar(high) * (btScalar(0x100000000LL) * btScalar(0x100000000LL)) + btScalar(low) + : -(-*this).toScalar(); + } - int getSign() const - { - return ((int64_t)high < 0) ? -1 : (high || low) ? 1 : 0; - } + int getSign() const + { + return ((int64_t)high < 0) ? -1 : (high || low) ? 1 : 0; + } - bool operator<(const Int128& b) const - { - return (high < b.high) || ((high == b.high) && (low < b.low)); - } + bool operator<(const Int128& b) const + { + return (high < b.high) || ((high == b.high) && (low < b.low)); + } - int ucmp(const Int128& b) const - { - if (high < b.high) { - return -1; - } - if (high > b.high) { - return 1; - } - if (low < b.low) { - return -1; - } - if (low > b.low) { - return 1; - } - return 0; - } - }; + int ucmp(const Int128& b) const + { + if (high < b.high) + { + return -1; + } + if (high > b.high) + { + return 1; + } + if (low < b.low) + { + return -1; + } + if (low > b.low) + { + return 1; + } + return 0; + } + }; - class Rational64 { - private: - uint64_t m_numerator; - uint64_t m_denominator; - int sign; + class Rational64 + { + private: + uint64_t m_numerator; + uint64_t m_denominator; + int sign; - public: - Rational64(int64_t numerator, int64_t denominator) - { - if (numerator > 0) { - sign = 1; - m_numerator = (uint64_t)numerator; - } - else if (numerator < 0) { - sign = -1; - m_numerator = (uint64_t)-numerator; - } - else { - sign = 0; - m_numerator = 0; - } - if (denominator > 0) { - m_denominator = (uint64_t)denominator; - } - else if (denominator < 0) { - sign = -sign; - m_denominator = (uint64_t)-denominator; - } - else { - m_denominator = 0; - } - } + public: + Rational64(int64_t numerator, int64_t denominator) + { + if (numerator > 0) + { + sign = 1; + m_numerator = (uint64_t)numerator; + } + else if (numerator < 0) + { + sign = -1; + m_numerator = (uint64_t)-numerator; + } + else + { + sign = 0; + m_numerator = 0; + } + if (denominator > 0) + { + m_denominator = (uint64_t)denominator; + } + else if (denominator < 0) + { + sign = -sign; + m_denominator = (uint64_t)-denominator; + } + else + { + m_denominator = 0; + } + } - bool isNegativeInfinity() const - { - return (sign < 0) && (m_denominator == 0); - } + bool isNegativeInfinity() const + { + return (sign < 0) && (m_denominator == 0); + } - bool isNaN() const - { - return (sign == 0) && (m_denominator == 0); - } + bool isNaN() const + { + return (sign == 0) && (m_denominator == 0); + } - int compare(const Rational64& b) const; + int compare(const Rational64& b) const; - btScalar toScalar() const - { - return sign * ((m_denominator == 0) ? SIMD_INFINITY : (btScalar)m_numerator / m_denominator); - } - }; + btScalar toScalar() const + { + return sign * ((m_denominator == 0) ? SIMD_INFINITY : (btScalar)m_numerator / m_denominator); + } + }; - class Rational128 { - private: - Int128 numerator; - Int128 denominator; - int sign; - bool isInt64; + class Rational128 + { + private: + Int128 numerator; + Int128 denominator; + int sign; + bool isInt64; - public: - Rational128(int64_t value) - { - if (value > 0) { - sign = 1; - this->numerator = value; - } - else if (value < 0) { - sign = -1; - this->numerator = -value; - } - else { - sign = 0; - this->numerator = (uint64_t)0; - } - this->denominator = (uint64_t)1; - isInt64 = true; - } + public: + Rational128(int64_t value) + { + if (value > 0) + { + sign = 1; + this->numerator = value; + } + else if (value < 0) + { + sign = -1; + this->numerator = -value; + } + else + { + sign = 0; + this->numerator = (uint64_t)0; + } + this->denominator = (uint64_t)1; + isInt64 = true; + } - Rational128(const Int128& numerator, const Int128& denominator) - { - sign = numerator.getSign(); - if (sign >= 0) { - this->numerator = numerator; - } - else { - this->numerator = -numerator; - } - int dsign = denominator.getSign(); - if (dsign >= 0) { - this->denominator = denominator; - } - else { - sign = -sign; - this->denominator = -denominator; - } - isInt64 = false; - } + Rational128(const Int128& numerator, const Int128& denominator) + { + sign = numerator.getSign(); + if (sign >= 0) + { + this->numerator = numerator; + } + else + { + this->numerator = -numerator; + } + int dsign = denominator.getSign(); + if (dsign >= 0) + { + this->denominator = denominator; + } + else + { + sign = -sign; + this->denominator = -denominator; + } + isInt64 = false; + } - int compare(const Rational128& b) const; + int compare(const Rational128& b) const; - int compare(int64_t b) const; + int compare(int64_t b) const; - btScalar toScalar() const - { - return sign * ((denominator.getSign() == 0) ? SIMD_INFINITY : numerator.toScalar() / denominator.toScalar()); - } - }; + btScalar toScalar() const + { + return sign * ((denominator.getSign() == 0) ? SIMD_INFINITY : numerator.toScalar() / denominator.toScalar()); + } + }; - class PointR128 { - public: - Int128 x; - Int128 y; - Int128 z; - Int128 denominator; + class PointR128 + { + public: + Int128 x; + Int128 y; + Int128 z; + Int128 denominator; - PointR128() - { - } + PointR128() + { + } - PointR128(Int128 x, Int128 y, Int128 z, Int128 denominator) - : x(x) - , y(y) - , z(z) - , denominator(denominator) - { - } + PointR128(Int128 x, Int128 y, Int128 z, Int128 denominator) + : x(x), y(y), z(z), denominator(denominator) + { + } - btScalar xvalue() const - { - return x.toScalar() / denominator.toScalar(); - } + btScalar xvalue() const + { + return x.toScalar() / denominator.toScalar(); + } - btScalar yvalue() const - { - return y.toScalar() / denominator.toScalar(); - } + btScalar yvalue() const + { + return y.toScalar() / denominator.toScalar(); + } - btScalar zvalue() const - { - return z.toScalar() / denominator.toScalar(); - } - }; + btScalar zvalue() const + { + return z.toScalar() / denominator.toScalar(); + } + }; - class Edge; - class Face; + class Edge; + class Face; - class Vertex { - public: - Vertex* next; - Vertex* prev; - Edge* edges; - Face* firstNearbyFace; - Face* lastNearbyFace; - PointR128 point128; - Point32 point; - int copy; + class Vertex + { + public: + Vertex* next; + Vertex* prev; + Edge* edges; + Face* firstNearbyFace; + Face* lastNearbyFace; + PointR128 point128; + Point32 point; + int copy; - Vertex() - : next(NULL) - , prev(NULL) - , edges(NULL) - , firstNearbyFace(NULL) - , lastNearbyFace(NULL) - , copy(-1) - { - } + Vertex() + : next(NULL), prev(NULL), edges(NULL), firstNearbyFace(NULL), lastNearbyFace(NULL), copy(-1) + { + } #ifdef DEBUG_CONVEX_HULL - void print() - { - printf("V%d (%d, %d, %d)", point.index, point.x, point.y, point.z); - } + void print() + { + printf("V%d (%d, %d, %d)", point.index, point.x, point.y, point.z); + } - void printGraph(); + void printGraph(); #endif - Point32 operator-(const Vertex& b) const - { - return point - b.point; - } + Point32 operator-(const Vertex& b) const + { + return point - b.point; + } - Rational128 dot(const Point64& b) const - { - return (point.index >= 0) ? Rational128(point.dot(b)) - : Rational128(point128.x * b.x + point128.y * b.y + point128.z * b.z, point128.denominator); - } + Rational128 dot(const Point64& b) const + { + return (point.index >= 0) ? Rational128(point.dot(b)) + : Rational128(point128.x * b.x + point128.y * b.y + point128.z * b.z, point128.denominator); + } - btScalar xvalue() const - { - return (point.index >= 0) ? btScalar(point.x) : point128.xvalue(); - } + btScalar xvalue() const + { + return (point.index >= 0) ? btScalar(point.x) : point128.xvalue(); + } - btScalar yvalue() const - { - return (point.index >= 0) ? btScalar(point.y) : point128.yvalue(); - } + btScalar yvalue() const + { + return (point.index >= 0) ? btScalar(point.y) : point128.yvalue(); + } - btScalar zvalue() const - { - return (point.index >= 0) ? btScalar(point.z) : point128.zvalue(); - } + btScalar zvalue() const + { + return (point.index >= 0) ? btScalar(point.z) : point128.zvalue(); + } - void receiveNearbyFaces(Vertex* src) - { - if (lastNearbyFace) { - lastNearbyFace->nextWithSameNearbyVertex = src->firstNearbyFace; - } - else { - firstNearbyFace = src->firstNearbyFace; - } - if (src->lastNearbyFace) { - lastNearbyFace = src->lastNearbyFace; - } - for (Face* f = src->firstNearbyFace; f; f = f->nextWithSameNearbyVertex) { - btAssert(f->nearbyVertex == src); - f->nearbyVertex = this; - } - src->firstNearbyFace = NULL; - src->lastNearbyFace = NULL; - } - }; + void receiveNearbyFaces(Vertex* src) + { + if (lastNearbyFace) + { + lastNearbyFace->nextWithSameNearbyVertex = src->firstNearbyFace; + } + else + { + firstNearbyFace = src->firstNearbyFace; + } + if (src->lastNearbyFace) + { + lastNearbyFace = src->lastNearbyFace; + } + for (Face* f = src->firstNearbyFace; f; f = f->nextWithSameNearbyVertex) + { + btAssert(f->nearbyVertex == src); + f->nearbyVertex = this; + } + src->firstNearbyFace = NULL; + src->lastNearbyFace = NULL; + } + }; - class Edge { - public: - Edge* next; - Edge* prev; - Edge* reverse; - Vertex* target; - Face* face; - int copy; + class Edge + { + public: + Edge* next; + Edge* prev; + Edge* reverse; + Vertex* target; + Face* face; + int copy; - ~Edge() - { - next = NULL; - prev = NULL; - reverse = NULL; - target = NULL; - face = NULL; - } + ~Edge() + { + next = NULL; + prev = NULL; + reverse = NULL; + target = NULL; + face = NULL; + } - void link(Edge* n) - { - btAssert(reverse->target == n->reverse->target); - next = n; - n->prev = this; - } + void link(Edge* n) + { + btAssert(reverse->target == n->reverse->target); + next = n; + n->prev = this; + } #ifdef DEBUG_CONVEX_HULL - void print() - { - printf("E%p : %d -> %d, n=%p p=%p (0 %d\t%d\t%d) -> (%d %d %d)", this, reverse->target->point.index, target->point.index, next, prev, - reverse->target->point.x, reverse->target->point.y, reverse->target->point.z, target->point.x, target->point.y, target->point.z); - } + void print() + { + printf("E%p : %d -> %d, n=%p p=%p (0 %d\t%d\t%d) -> (%d %d %d)", this, reverse->target->point.index, target->point.index, next, prev, + reverse->target->point.x, reverse->target->point.y, reverse->target->point.z, target->point.x, target->point.y, target->point.z); + } #endif - }; + }; - class Face { - public: - Face* next; - Vertex* nearbyVertex; - Face* nextWithSameNearbyVertex; - Point32 origin; - Point32 dir0; - Point32 dir1; + class Face + { + public: + Face* next; + Vertex* nearbyVertex; + Face* nextWithSameNearbyVertex; + Point32 origin; + Point32 dir0; + Point32 dir1; - Face() - : next(NULL) - , nearbyVertex(NULL) - , nextWithSameNearbyVertex(NULL) - { - } + Face() + : next(NULL), nearbyVertex(NULL), nextWithSameNearbyVertex(NULL) + { + } - void init(Vertex* a, Vertex* b, Vertex* c) - { - nearbyVertex = a; - origin = a->point; - dir0 = *b - *a; - dir1 = *c - *a; - if (a->lastNearbyFace) { - a->lastNearbyFace->nextWithSameNearbyVertex = this; - } - else { - a->firstNearbyFace = this; - } - a->lastNearbyFace = this; - } + void init(Vertex* a, Vertex* b, Vertex* c) + { + nearbyVertex = a; + origin = a->point; + dir0 = *b - *a; + dir1 = *c - *a; + if (a->lastNearbyFace) + { + a->lastNearbyFace->nextWithSameNearbyVertex = this; + } + else + { + a->firstNearbyFace = this; + } + a->lastNearbyFace = this; + } - Point64 getNormal() - { - return dir0.cross(dir1); - } - }; + Point64 getNormal() + { + return dir0.cross(dir1); + } + }; - template - class DMul { - private: - static uint32_t high(uint64_t value) - { - return (uint32_t)(value >> 32); - } + template + class DMul + { + private: + static uint32_t high(uint64_t value) + { + return (uint32_t)(value >> 32); + } - static uint32_t low(uint64_t value) - { - return (uint32_t)value; - } + static uint32_t low(uint64_t value) + { + return (uint32_t)value; + } - static uint64_t mul(uint32_t a, uint32_t b) - { - return (uint64_t)a * (uint64_t)b; - } + static uint64_t mul(uint32_t a, uint32_t b) + { + return (uint64_t)a * (uint64_t)b; + } - static void shlHalf(uint64_t& value) - { - value <<= 32; - } + static void shlHalf(uint64_t& value) + { + value <<= 32; + } - static uint64_t high(Int128 value) - { - return value.high; - } + static uint64_t high(Int128 value) + { + return value.high; + } - static uint64_t low(Int128 value) - { - return value.low; - } + static uint64_t low(Int128 value) + { + return value.low; + } - static Int128 mul(uint64_t a, uint64_t b) - { - return Int128::mul(a, b); - } + static Int128 mul(uint64_t a, uint64_t b) + { + return Int128::mul(a, b); + } - static void shlHalf(Int128& value) - { - value.high = value.low; - value.low = 0; - } + static void shlHalf(Int128& value) + { + value.high = value.low; + value.low = 0; + } - public: - static void mul(UWord a, UWord b, UWord& resLow, UWord& resHigh) - { - UWord p00 = mul(low(a), low(b)); - UWord p01 = mul(low(a), high(b)); - UWord p10 = mul(high(a), low(b)); - UWord p11 = mul(high(a), high(b)); - UWord p0110 = UWord(low(p01)) + UWord(low(p10)); - p11 += high(p01); - p11 += high(p10); - p11 += high(p0110); - shlHalf(p0110); - p00 += p0110; - if (p00 < p0110) { - ++p11; - } - resLow = p00; - resHigh = p11; - } - }; + public: + static void mul(UWord a, UWord b, UWord& resLow, UWord& resHigh) + { + UWord p00 = mul(low(a), low(b)); + UWord p01 = mul(low(a), high(b)); + UWord p10 = mul(high(a), low(b)); + UWord p11 = mul(high(a), high(b)); + UWord p0110 = UWord(low(p01)) + UWord(low(p10)); + p11 += high(p01); + p11 += high(p10); + p11 += high(p0110); + shlHalf(p0110); + p00 += p0110; + if (p00 < p0110) + { + ++p11; + } + resLow = p00; + resHigh = p11; + } + }; private: - class IntermediateHull { - public: - Vertex* minXy; - Vertex* maxXy; - Vertex* minYx; - Vertex* maxYx; + class IntermediateHull + { + public: + Vertex* minXy; + Vertex* maxXy; + Vertex* minYx; + Vertex* maxYx; - IntermediateHull() - : minXy(NULL) - , maxXy(NULL) - , minYx(NULL) - , maxYx(NULL) - { - } + IntermediateHull() + : minXy(NULL), maxXy(NULL), minYx(NULL), maxYx(NULL) + { + } - void print(); - }; + void print(); + }; - enum Orientation { NONE, - CLOCKWISE, - COUNTER_CLOCKWISE }; + enum Orientation + { + NONE, + CLOCKWISE, + COUNTER_CLOCKWISE + }; - template - class PoolArray { - private: - T* array; - int size; + template + class PoolArray + { + private: + T* array; + int size; - public: - PoolArray* next; + public: + PoolArray* next; - PoolArray(int size) - : size(size) - , next(NULL) - { - array = (T*)btAlignedAlloc(sizeof(T) * size, 16); - } + PoolArray(int size) + : size(size), next(NULL) + { + array = (T*)btAlignedAlloc(sizeof(T) * size, 16); + } - ~PoolArray() - { - btAlignedFree(array); - } + ~PoolArray() + { + btAlignedFree(array); + } - T* init() - { - T* o = array; - for (int i = 0; i < size; i++, o++) { - o->next = (i + 1 < size) ? o + 1 : NULL; - } - return array; - } - }; + T* init() + { + T* o = array; + for (int i = 0; i < size; i++, o++) + { + o->next = (i + 1 < size) ? o + 1 : NULL; + } + return array; + } + }; - template - class Pool { - private: - PoolArray* arrays; - PoolArray* nextArray; - T* freeObjects; - int arraySize; + template + class Pool + { + private: + PoolArray* arrays; + PoolArray* nextArray; + T* freeObjects; + int arraySize; - public: - Pool() - : arrays(NULL) - , nextArray(NULL) - , freeObjects(NULL) - , arraySize(256) - { - } + public: + Pool() + : arrays(NULL), nextArray(NULL), freeObjects(NULL), arraySize(256) + { + } - ~Pool() - { - while (arrays) { - PoolArray* p = arrays; - arrays = p->next; - p->~PoolArray(); - btAlignedFree(p); - } - } + ~Pool() + { + while (arrays) + { + PoolArray* p = arrays; + arrays = p->next; + p->~PoolArray(); + btAlignedFree(p); + } + } - void reset() - { - nextArray = arrays; - freeObjects = NULL; - } + void reset() + { + nextArray = arrays; + freeObjects = NULL; + } - void setArraySize(int arraySize) - { - this->arraySize = arraySize; - } + void setArraySize(int arraySize) + { + this->arraySize = arraySize; + } - T* newObject() - { - T* o = freeObjects; - if (!o) { - PoolArray* p = nextArray; - if (p) { - nextArray = p->next; - } - else { - p = new (btAlignedAlloc(sizeof(PoolArray), 16)) PoolArray(arraySize); - p->next = arrays; - arrays = p; - } - o = p->init(); - } - freeObjects = o->next; - return new (o) T(); - }; + T* newObject() + { + T* o = freeObjects; + if (!o) + { + PoolArray* p = nextArray; + if (p) + { + nextArray = p->next; + } + else + { + p = new (btAlignedAlloc(sizeof(PoolArray), 16)) PoolArray(arraySize); + p->next = arrays; + arrays = p; + } + o = p->init(); + } + freeObjects = o->next; + return new (o) T(); + }; - void freeObject(T* object) - { - object->~T(); - object->next = freeObjects; - freeObjects = object; - } - }; + void freeObject(T* object) + { + object->~T(); + object->next = freeObjects; + freeObjects = object; + } + }; - btVector3 scaling; - btVector3 center; - Pool vertexPool; - Pool edgePool; - Pool facePool; - btAlignedObjectArray originalVertices; - int mergeStamp; - int minAxis; - int medAxis; - int maxAxis; - int usedEdgePairs; - int maxUsedEdgePairs; + btVector3 scaling; + btVector3 center; + Pool vertexPool; + Pool edgePool; + Pool facePool; + btAlignedObjectArray originalVertices; + int mergeStamp; + int minAxis; + int medAxis; + int maxAxis; + int usedEdgePairs; + int maxUsedEdgePairs; - static Orientation getOrientation(const Edge* prev, const Edge* next, const Point32& s, const Point32& t); - Edge* findMaxAngle(bool ccw, const Vertex* start, const Point32& s, const Point64& rxs, const Point64& sxrxs, Rational64& minCot); - void findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge*& e0, Edge*& e1, Vertex* stop0, Vertex* stop1); + static Orientation getOrientation(const Edge* prev, const Edge* next, const Point32& s, const Point32& t); + Edge* findMaxAngle(bool ccw, const Vertex* start, const Point32& s, const Point64& rxs, const Point64& sxrxs, Rational64& minCot); + void findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge*& e0, Edge*& e1, Vertex* stop0, Vertex* stop1); - Edge* newEdgePair(Vertex* from, Vertex* to); + Edge* newEdgePair(Vertex* from, Vertex* to); - void removeEdgePair(Edge* edge) - { - Edge* n = edge->next; - Edge* r = edge->reverse; + void removeEdgePair(Edge* edge) + { + Edge* n = edge->next; + Edge* r = edge->reverse; - btAssert(edge->target && r->target); + btAssert(edge->target && r->target); - if (n != edge) { - n->prev = edge->prev; - edge->prev->next = n; - r->target->edges = n; - } - else { - r->target->edges = NULL; - } + if (n != edge) + { + n->prev = edge->prev; + edge->prev->next = n; + r->target->edges = n; + } + else + { + r->target->edges = NULL; + } - n = r->next; + n = r->next; - if (n != r) { - n->prev = r->prev; - r->prev->next = n; - edge->target->edges = n; - } - else { - edge->target->edges = NULL; - } + if (n != r) + { + n->prev = r->prev; + r->prev->next = n; + edge->target->edges = n; + } + else + { + edge->target->edges = NULL; + } - edgePool.freeObject(edge); - edgePool.freeObject(r); - usedEdgePairs--; - } + edgePool.freeObject(edge); + edgePool.freeObject(r); + usedEdgePairs--; + } - void computeInternal(int start, int end, IntermediateHull& result); + void computeInternal(int start, int end, IntermediateHull& result); - bool mergeProjection(IntermediateHull& h0, IntermediateHull& h1, Vertex*& c0, Vertex*& c1); + bool mergeProjection(IntermediateHull& h0, IntermediateHull& h1, Vertex*& c0, Vertex*& c1); - void merge(IntermediateHull& h0, IntermediateHull& h1); + void merge(IntermediateHull& h0, IntermediateHull& h1); - btVector3 toBtVector(const Point32& v); + btVector3 toBtVector(const Point32& v); - btVector3 getBtNormal(Face* face); + btVector3 getBtNormal(Face* face); - bool shiftFace(Face* face, btScalar amount, btAlignedObjectArray stack); + bool shiftFace(Face* face, btScalar amount, btAlignedObjectArray stack); public: - Vertex* vertexList; + Vertex* vertexList; - void compute(const void* coords, bool doubleCoords, int stride, int count); + void compute(const void* coords, bool doubleCoords, int stride, int count); - btVector3 getCoordinates(const Vertex* v); + btVector3 getCoordinates(const Vertex* v); - btScalar shrink(btScalar amount, btScalar clampAmount); + btScalar shrink(btScalar amount, btScalar clampAmount); }; btConvexHullInternal::Int128 btConvexHullInternal::Int128::operator*(int64_t b) const { - bool negative = (int64_t)high < 0; - Int128 a = negative ? -*this : *this; - if (b < 0) { - negative = !negative; - b = -b; - } - Int128 result = mul(a.low, (uint64_t)b); - result.high += a.high * (uint64_t)b; - return negative ? -result : result; + bool negative = (int64_t)high < 0; + Int128 a = negative ? -*this : *this; + if (b < 0) + { + negative = !negative; + b = -b; + } + Int128 result = mul(a.low, (uint64_t)b); + result.high += a.high * (uint64_t)b; + return negative ? -result : result; } btConvexHullInternal::Int128 btConvexHullInternal::Int128::mul(int64_t a, int64_t b) { - Int128 result; + Int128 result; #ifdef USE_X86_64_ASM - __asm__("imulq %[b]" - : "=a"(result.low), "=d"(result.high) - : "0"(a), [b] "r"(b) - : "cc"); - return result; + __asm__("imulq %[b]" + : "=a"(result.low), "=d"(result.high) + : "0"(a), [b] "r"(b) + : "cc"); + return result; #else - bool negative = a < 0; - if (negative) { - a = -a; - } - if (b < 0) { - negative = !negative; - b = -b; - } - DMul::mul((uint64_t)a, (uint64_t)b, result.low, result.high); - return negative ? -result : result; + bool negative = a < 0; + if (negative) + { + a = -a; + } + if (b < 0) + { + negative = !negative; + b = -b; + } + DMul::mul((uint64_t)a, (uint64_t)b, result.low, result.high); + return negative ? -result : result; #endif } btConvexHullInternal::Int128 btConvexHullInternal::Int128::mul(uint64_t a, uint64_t b) { - Int128 result; + Int128 result; #ifdef USE_X86_64_ASM - __asm__("mulq %[b]" - : "=a"(result.low), "=d"(result.high) - : "0"(a), [b] "r"(b) - : "cc"); + __asm__("mulq %[b]" + : "=a"(result.low), "=d"(result.high) + : "0"(a), [b] "r"(b) + : "cc"); #else - DMul::mul(a, b, result.low, result.high); + DMul::mul(a, b, result.low, result.high); #endif - return result; + return result; } int btConvexHullInternal::Rational64::compare(const Rational64& b) const { - if (sign != b.sign) { - return sign - b.sign; - } - else if (sign == 0) { - return 0; - } + if (sign != b.sign) + { + return sign - b.sign; + } + else if (sign == 0) + { + return 0; + } -// return (numerator * b.denominator > b.numerator * denominator) ? sign : (numerator * b.denominator < b.numerator * denominator) ? -sign : 0; + // return (numerator * b.denominator > b.numerator * denominator) ? sign : (numerator * b.denominator < b.numerator * denominator) ? -sign : 0; #ifdef USE_X86_64_ASM - int result; - int64_t tmp; - int64_t dummy; - __asm__("mulq %[bn]\n\t" - "movq %%rax, %[tmp]\n\t" - "movq %%rdx, %%rbx\n\t" - "movq %[tn], %%rax\n\t" - "mulq %[bd]\n\t" - "subq %[tmp], %%rax\n\t" - "sbbq %%rbx, %%rdx\n\t" // rdx:rax contains 128-bit-difference "numerator*b.denominator - b.numerator*denominator" - "setnsb %%bh\n\t" // bh=1 if difference is non-negative, bh=0 otherwise - "orq %%rdx, %%rax\n\t" - "setnzb %%bl\n\t" // bl=1 if difference if non-zero, bl=0 if it is zero - "decb %%bh\n\t" // now bx=0x0000 if difference is zero, 0xff01 if it is negative, 0x0001 if it is positive (i.e., same sign as difference) - "shll $16, %%ebx\n\t" // ebx has same sign as difference - : "=&b"(result), [tmp] "=&r"(tmp), "=a"(dummy) - : "a"(denominator), [bn] "g"(b.numerator), [tn] "g"(numerator), [bd] "g"(b.denominator) - : "%rdx", "cc"); - return result ? result ^ sign // if sign is +1, only bit 0 of result is inverted, which does not change the sign of result (and cannot result in zero) - // if sign is -1, all bits of result are inverted, which changes the sign of result (and again cannot result in zero) - : 0; + int result; + int64_t tmp; + int64_t dummy; + __asm__( + "mulq %[bn]\n\t" + "movq %%rax, %[tmp]\n\t" + "movq %%rdx, %%rbx\n\t" + "movq %[tn], %%rax\n\t" + "mulq %[bd]\n\t" + "subq %[tmp], %%rax\n\t" + "sbbq %%rbx, %%rdx\n\t" // rdx:rax contains 128-bit-difference "numerator*b.denominator - b.numerator*denominator" + "setnsb %%bh\n\t" // bh=1 if difference is non-negative, bh=0 otherwise + "orq %%rdx, %%rax\n\t" + "setnzb %%bl\n\t" // bl=1 if difference if non-zero, bl=0 if it is zero + "decb %%bh\n\t" // now bx=0x0000 if difference is zero, 0xff01 if it is negative, 0x0001 if it is positive (i.e., same sign as difference) + "shll $16, %%ebx\n\t" // ebx has same sign as difference + : "=&b"(result), [tmp] "=&r"(tmp), "=a"(dummy) + : "a"(denominator), [bn] "g"(b.numerator), [tn] "g"(numerator), [bd] "g"(b.denominator) + : "%rdx", "cc"); + return result ? result ^ sign // if sign is +1, only bit 0 of result is inverted, which does not change the sign of result (and cannot result in zero) + // if sign is -1, all bits of result are inverted, which changes the sign of result (and again cannot result in zero) + : 0; #else - return sign * Int128::mul(m_numerator, b.m_denominator).ucmp(Int128::mul(m_denominator, b.m_numerator)); + return sign * Int128::mul(m_numerator, b.m_denominator).ucmp(Int128::mul(m_denominator, b.m_numerator)); #endif } int btConvexHullInternal::Rational128::compare(const Rational128& b) const { - if (sign != b.sign) { - return sign - b.sign; - } - else if (sign == 0) { - return 0; - } - if (isInt64) { - return -b.compare(sign * (int64_t)numerator.low); - } + if (sign != b.sign) + { + return sign - b.sign; + } + else if (sign == 0) + { + return 0; + } + if (isInt64) + { + return -b.compare(sign * (int64_t)numerator.low); + } - Int128 nbdLow, nbdHigh, dbnLow, dbnHigh; - DMul::mul(numerator, b.denominator, nbdLow, nbdHigh); - DMul::mul(denominator, b.numerator, dbnLow, dbnHigh); + Int128 nbdLow, nbdHigh, dbnLow, dbnHigh; + DMul::mul(numerator, b.denominator, nbdLow, nbdHigh); + DMul::mul(denominator, b.numerator, dbnLow, dbnHigh); - int cmp = nbdHigh.ucmp(dbnHigh); - if (cmp) { - return cmp * sign; - } - return nbdLow.ucmp(dbnLow) * sign; + int cmp = nbdHigh.ucmp(dbnHigh); + if (cmp) + { + return cmp * sign; + } + return nbdLow.ucmp(dbnLow) * sign; } int btConvexHullInternal::Rational128::compare(int64_t b) const { - if (isInt64) { - int64_t a = sign * (int64_t)numerator.low; - return (a > b) ? 1 : (a < b) ? -1 : 0; - } - if (b > 0) { - if (sign <= 0) { - return -1; - } - } - else if (b < 0) { - if (sign >= 0) { - return 1; - } - b = -b; - } - else { - return sign; - } + if (isInt64) + { + int64_t a = sign * (int64_t)numerator.low; + return (a > b) ? 1 : (a < b) ? -1 : 0; + } + if (b > 0) + { + if (sign <= 0) + { + return -1; + } + } + else if (b < 0) + { + if (sign >= 0) + { + return 1; + } + b = -b; + } + else + { + return sign; + } - return numerator.ucmp(denominator * b) * sign; + return numerator.ucmp(denominator * b) * sign; } btConvexHullInternal::Edge* btConvexHullInternal::newEdgePair(Vertex* from, Vertex* to) { - btAssert(from && to); - Edge* e = edgePool.newObject(); - Edge* r = edgePool.newObject(); - e->reverse = r; - r->reverse = e; - e->copy = mergeStamp; - r->copy = mergeStamp; - e->target = to; - r->target = from; - e->face = NULL; - r->face = NULL; - usedEdgePairs++; - if (usedEdgePairs > maxUsedEdgePairs) { - maxUsedEdgePairs = usedEdgePairs; - } - return e; + btAssert(from && to); + Edge* e = edgePool.newObject(); + Edge* r = edgePool.newObject(); + e->reverse = r; + r->reverse = e; + e->copy = mergeStamp; + r->copy = mergeStamp; + e->target = to; + r->target = from; + e->face = NULL; + r->face = NULL; + usedEdgePairs++; + if (usedEdgePairs > maxUsedEdgePairs) + { + maxUsedEdgePairs = usedEdgePairs; + } + return e; } bool btConvexHullInternal::mergeProjection(IntermediateHull& h0, IntermediateHull& h1, Vertex*& c0, Vertex*& c1) { - Vertex* v0 = h0.maxYx; - Vertex* v1 = h1.minYx; - if ((v0->point.x == v1->point.x) && (v0->point.y == v1->point.y)) { - btAssert(v0->point.z < v1->point.z); - Vertex* v1p = v1->prev; - if (v1p == v1) { - c0 = v0; - if (v1->edges) { - btAssert(v1->edges->next == v1->edges); - v1 = v1->edges->target; - btAssert(v1->edges->next == v1->edges); - } - c1 = v1; - return false; - } - Vertex* v1n = v1->next; - v1p->next = v1n; - v1n->prev = v1p; - if (v1 == h1.minXy) { - if ((v1n->point.x < v1p->point.x) || ((v1n->point.x == v1p->point.x) && (v1n->point.y < v1p->point.y))) { - h1.minXy = v1n; - } - else { - h1.minXy = v1p; - } - } - if (v1 == h1.maxXy) { - if ((v1n->point.x > v1p->point.x) || ((v1n->point.x == v1p->point.x) && (v1n->point.y > v1p->point.y))) { - h1.maxXy = v1n; - } - else { - h1.maxXy = v1p; - } - } - } + Vertex* v0 = h0.maxYx; + Vertex* v1 = h1.minYx; + if ((v0->point.x == v1->point.x) && (v0->point.y == v1->point.y)) + { + btAssert(v0->point.z < v1->point.z); + Vertex* v1p = v1->prev; + if (v1p == v1) + { + c0 = v0; + if (v1->edges) + { + btAssert(v1->edges->next == v1->edges); + v1 = v1->edges->target; + btAssert(v1->edges->next == v1->edges); + } + c1 = v1; + return false; + } + Vertex* v1n = v1->next; + v1p->next = v1n; + v1n->prev = v1p; + if (v1 == h1.minXy) + { + if ((v1n->point.x < v1p->point.x) || ((v1n->point.x == v1p->point.x) && (v1n->point.y < v1p->point.y))) + { + h1.minXy = v1n; + } + else + { + h1.minXy = v1p; + } + } + if (v1 == h1.maxXy) + { + if ((v1n->point.x > v1p->point.x) || ((v1n->point.x == v1p->point.x) && (v1n->point.y > v1p->point.y))) + { + h1.maxXy = v1n; + } + else + { + h1.maxXy = v1p; + } + } + } - v0 = h0.maxXy; - v1 = h1.maxXy; - Vertex* v00 = NULL; - Vertex* v10 = NULL; - int32_t sign = 1; + v0 = h0.maxXy; + v1 = h1.maxXy; + Vertex* v00 = NULL; + Vertex* v10 = NULL; + int32_t sign = 1; - for (int side = 0; side <= 1; side++) { - int32_t dx = (v1->point.x - v0->point.x) * sign; - if (dx > 0) { - while (true) { - int32_t dy = v1->point.y - v0->point.y; + for (int side = 0; side <= 1; side++) + { + int32_t dx = (v1->point.x - v0->point.x) * sign; + if (dx > 0) + { + while (true) + { + int32_t dy = v1->point.y - v0->point.y; - Vertex* w0 = side ? v0->next : v0->prev; - if (w0 != v0) { - int32_t dx0 = (w0->point.x - v0->point.x) * sign; - int32_t dy0 = w0->point.y - v0->point.y; - if ((dy0 <= 0) && ((dx0 == 0) || ((dx0 < 0) && (dy0 * dx <= dy * dx0)))) { - v0 = w0; - dx = (v1->point.x - v0->point.x) * sign; - continue; - } - } + Vertex* w0 = side ? v0->next : v0->prev; + if (w0 != v0) + { + int32_t dx0 = (w0->point.x - v0->point.x) * sign; + int32_t dy0 = w0->point.y - v0->point.y; + if ((dy0 <= 0) && ((dx0 == 0) || ((dx0 < 0) && (dy0 * dx <= dy * dx0)))) + { + v0 = w0; + dx = (v1->point.x - v0->point.x) * sign; + continue; + } + } - Vertex* w1 = side ? v1->next : v1->prev; - if (w1 != v1) { - int32_t dx1 = (w1->point.x - v1->point.x) * sign; - int32_t dy1 = w1->point.y - v1->point.y; - int32_t dxn = (w1->point.x - v0->point.x) * sign; - if ((dxn > 0) && (dy1 < 0) && ((dx1 == 0) || ((dx1 < 0) && (dy1 * dx < dy * dx1)))) { - v1 = w1; - dx = dxn; - continue; - } - } + Vertex* w1 = side ? v1->next : v1->prev; + if (w1 != v1) + { + int32_t dx1 = (w1->point.x - v1->point.x) * sign; + int32_t dy1 = w1->point.y - v1->point.y; + int32_t dxn = (w1->point.x - v0->point.x) * sign; + if ((dxn > 0) && (dy1 < 0) && ((dx1 == 0) || ((dx1 < 0) && (dy1 * dx < dy * dx1)))) + { + v1 = w1; + dx = dxn; + continue; + } + } - break; - } - } - else if (dx < 0) { - while (true) { - int32_t dy = v1->point.y - v0->point.y; + break; + } + } + else if (dx < 0) + { + while (true) + { + int32_t dy = v1->point.y - v0->point.y; - Vertex* w1 = side ? v1->prev : v1->next; - if (w1 != v1) { - int32_t dx1 = (w1->point.x - v1->point.x) * sign; - int32_t dy1 = w1->point.y - v1->point.y; - if ((dy1 >= 0) && ((dx1 == 0) || ((dx1 < 0) && (dy1 * dx <= dy * dx1)))) { - v1 = w1; - dx = (v1->point.x - v0->point.x) * sign; - continue; - } - } + Vertex* w1 = side ? v1->prev : v1->next; + if (w1 != v1) + { + int32_t dx1 = (w1->point.x - v1->point.x) * sign; + int32_t dy1 = w1->point.y - v1->point.y; + if ((dy1 >= 0) && ((dx1 == 0) || ((dx1 < 0) && (dy1 * dx <= dy * dx1)))) + { + v1 = w1; + dx = (v1->point.x - v0->point.x) * sign; + continue; + } + } - Vertex* w0 = side ? v0->prev : v0->next; - if (w0 != v0) { - int32_t dx0 = (w0->point.x - v0->point.x) * sign; - int32_t dy0 = w0->point.y - v0->point.y; - int32_t dxn = (v1->point.x - w0->point.x) * sign; - if ((dxn < 0) && (dy0 > 0) && ((dx0 == 0) || ((dx0 < 0) && (dy0 * dx < dy * dx0)))) { - v0 = w0; - dx = dxn; - continue; - } - } + Vertex* w0 = side ? v0->prev : v0->next; + if (w0 != v0) + { + int32_t dx0 = (w0->point.x - v0->point.x) * sign; + int32_t dy0 = w0->point.y - v0->point.y; + int32_t dxn = (v1->point.x - w0->point.x) * sign; + if ((dxn < 0) && (dy0 > 0) && ((dx0 == 0) || ((dx0 < 0) && (dy0 * dx < dy * dx0)))) + { + v0 = w0; + dx = dxn; + continue; + } + } - break; - } - } - else { - int32_t x = v0->point.x; - int32_t y0 = v0->point.y; - Vertex* w0 = v0; - Vertex* t; - while (((t = side ? w0->next : w0->prev) != v0) && (t->point.x == x) && (t->point.y <= y0)) { - w0 = t; - y0 = t->point.y; - } - v0 = w0; + break; + } + } + else + { + int32_t x = v0->point.x; + int32_t y0 = v0->point.y; + Vertex* w0 = v0; + Vertex* t; + while (((t = side ? w0->next : w0->prev) != v0) && (t->point.x == x) && (t->point.y <= y0)) + { + w0 = t; + y0 = t->point.y; + } + v0 = w0; - int32_t y1 = v1->point.y; - Vertex* w1 = v1; - while (((t = side ? w1->prev : w1->next) != v1) && (t->point.x == x) && (t->point.y >= y1)) { - w1 = t; - y1 = t->point.y; - } - v1 = w1; - } + int32_t y1 = v1->point.y; + Vertex* w1 = v1; + while (((t = side ? w1->prev : w1->next) != v1) && (t->point.x == x) && (t->point.y >= y1)) + { + w1 = t; + y1 = t->point.y; + } + v1 = w1; + } - if (side == 0) { - v00 = v0; - v10 = v1; + if (side == 0) + { + v00 = v0; + v10 = v1; - v0 = h0.minXy; - v1 = h1.minXy; - sign = -1; - } - } + v0 = h0.minXy; + v1 = h1.minXy; + sign = -1; + } + } - v0->prev = v1; - v1->next = v0; + v0->prev = v1; + v1->next = v0; - v00->next = v10; - v10->prev = v00; + v00->next = v10; + v10->prev = v00; - if (h1.minXy->point.x < h0.minXy->point.x) { - h0.minXy = h1.minXy; - } - if (h1.maxXy->point.x >= h0.maxXy->point.x) { - h0.maxXy = h1.maxXy; - } + if (h1.minXy->point.x < h0.minXy->point.x) + { + h0.minXy = h1.minXy; + } + if (h1.maxXy->point.x >= h0.maxXy->point.x) + { + h0.maxXy = h1.maxXy; + } - h0.maxYx = h1.maxYx; + h0.maxYx = h1.maxYx; - c0 = v00; - c1 = v10; + c0 = v00; + c1 = v10; - return true; + return true; } void btConvexHullInternal::computeInternal(int start, int end, IntermediateHull& result) { - int n = end - start; - switch (n) { - case 0: - result.minXy = NULL; - result.maxXy = NULL; - result.minYx = NULL; - result.maxYx = NULL; - return; - case 2: { - Vertex* v = originalVertices[start]; - Vertex* w = v + 1; - if (v->point != w->point) { - int32_t dx = v->point.x - w->point.x; - int32_t dy = v->point.y - w->point.y; + int n = end - start; + switch (n) + { + case 0: + result.minXy = NULL; + result.maxXy = NULL; + result.minYx = NULL; + result.maxYx = NULL; + return; + case 2: + { + Vertex* v = originalVertices[start]; + Vertex* w = v + 1; + if (v->point != w->point) + { + int32_t dx = v->point.x - w->point.x; + int32_t dy = v->point.y - w->point.y; - if ((dx == 0) && (dy == 0)) { - if (v->point.z > w->point.z) { - Vertex* t = w; - w = v; - v = t; - } - btAssert(v->point.z < w->point.z); - v->next = v; - v->prev = v; - result.minXy = v; - result.maxXy = v; - result.minYx = v; - result.maxYx = v; - } - else { - v->next = w; - v->prev = w; - w->next = v; - w->prev = v; + if ((dx == 0) && (dy == 0)) + { + if (v->point.z > w->point.z) + { + Vertex* t = w; + w = v; + v = t; + } + btAssert(v->point.z < w->point.z); + v->next = v; + v->prev = v; + result.minXy = v; + result.maxXy = v; + result.minYx = v; + result.maxYx = v; + } + else + { + v->next = w; + v->prev = w; + w->next = v; + w->prev = v; - if ((dx < 0) || ((dx == 0) && (dy < 0))) { - result.minXy = v; - result.maxXy = w; - } - else { - result.minXy = w; - result.maxXy = v; - } + if ((dx < 0) || ((dx == 0) && (dy < 0))) + { + result.minXy = v; + result.maxXy = w; + } + else + { + result.minXy = w; + result.maxXy = v; + } - if ((dy < 0) || ((dy == 0) && (dx < 0))) { - result.minYx = v; - result.maxYx = w; - } - else { - result.minYx = w; - result.maxYx = v; - } - } + if ((dy < 0) || ((dy == 0) && (dx < 0))) + { + result.minYx = v; + result.maxYx = w; + } + else + { + result.minYx = w; + result.maxYx = v; + } + } - Edge* e = newEdgePair(v, w); - e->link(e); - v->edges = e; + Edge* e = newEdgePair(v, w); + e->link(e); + v->edges = e; - e = e->reverse; - e->link(e); - w->edges = e; + e = e->reverse; + e->link(e); + w->edges = e; - return; - } - } - // lint -fallthrough - case 1: { - Vertex* v = originalVertices[start]; - v->edges = NULL; - v->next = v; - v->prev = v; + return; + } + } + // lint -fallthrough + case 1: + { + Vertex* v = originalVertices[start]; + v->edges = NULL; + v->next = v; + v->prev = v; - result.minXy = v; - result.maxXy = v; - result.minYx = v; - result.maxYx = v; + result.minXy = v; + result.maxXy = v; + result.minYx = v; + result.maxYx = v; - return; - } - } + return; + } + } - int split0 = start + n / 2; - Point32 p = originalVertices[split0 - 1]->point; - int split1 = split0; - while ((split1 < end) && (originalVertices[split1]->point == p)) { - split1++; - } - computeInternal(start, split0, result); - IntermediateHull hull1; - computeInternal(split1, end, hull1); + int split0 = start + n / 2; + Point32 p = originalVertices[split0 - 1]->point; + int split1 = split0; + while ((split1 < end) && (originalVertices[split1]->point == p)) + { + split1++; + } + computeInternal(start, split0, result); + IntermediateHull hull1; + computeInternal(split1, end, hull1); #ifdef DEBUG_CONVEX_HULL - printf("\n\nMerge\n"); - result.print(); - hull1.print(); + printf("\n\nMerge\n"); + result.print(); + hull1.print(); #endif - merge(result, hull1); + merge(result, hull1); #ifdef DEBUG_CONVEX_HULL - printf("\n Result\n"); - result.print(); + printf("\n Result\n"); + result.print(); #endif } #ifdef DEBUG_CONVEX_HULL void btConvexHullInternal::IntermediateHull::print() { - printf(" Hull\n"); - for (Vertex* v = minXy; v;) { - printf(" "); - v->print(); - if (v == maxXy) { - printf(" maxXy"); - } - if (v == minYx) { - printf(" minYx"); - } - if (v == maxYx) { - printf(" maxYx"); - } - if (v->next->prev != v) { - printf(" Inconsistency"); - } - printf("\n"); - v = v->next; - if (v == minXy) { - break; - } - } - if (minXy) { - minXy->copy = (minXy->copy == -1) ? -2 : -1; - minXy->printGraph(); - } + printf(" Hull\n"); + for (Vertex* v = minXy; v;) + { + printf(" "); + v->print(); + if (v == maxXy) + { + printf(" maxXy"); + } + if (v == minYx) + { + printf(" minYx"); + } + if (v == maxYx) + { + printf(" maxYx"); + } + if (v->next->prev != v) + { + printf(" Inconsistency"); + } + printf("\n"); + v = v->next; + if (v == minXy) + { + break; + } + } + if (minXy) + { + minXy->copy = (minXy->copy == -1) ? -2 : -1; + minXy->printGraph(); + } } void btConvexHullInternal::Vertex::printGraph() { - print(); - printf("\nEdges\n"); - Edge* e = edges; - if (e) { - do { - e->print(); - printf("\n"); - e = e->next; - } while (e != edges); - do { - Vertex* v = e->target; - if (v->copy != copy) { - v->copy = copy; - v->printGraph(); - } - e = e->next; - } while (e != edges); - } + print(); + printf("\nEdges\n"); + Edge* e = edges; + if (e) + { + do + { + e->print(); + printf("\n"); + e = e->next; + } while (e != edges); + do + { + Vertex* v = e->target; + if (v->copy != copy) + { + v->copy = copy; + v->printGraph(); + } + e = e->next; + } while (e != edges); + } } #endif btConvexHullInternal::Orientation btConvexHullInternal::getOrientation(const Edge* prev, const Edge* next, const Point32& s, const Point32& t) { - btAssert(prev->reverse->target == next->reverse->target); - if (prev->next == next) { - if (prev->prev == next) { - Point64 n = t.cross(s); - Point64 m = (*prev->target - *next->reverse->target).cross(*next->target - *next->reverse->target); - btAssert(!m.isZero()); - int64_t dot = n.dot(m); - btAssert(dot != 0); - return (dot > 0) ? COUNTER_CLOCKWISE : CLOCKWISE; - } - return COUNTER_CLOCKWISE; - } - else if (prev->prev == next) { - return CLOCKWISE; - } - else { - return NONE; - } + btAssert(prev->reverse->target == next->reverse->target); + if (prev->next == next) + { + if (prev->prev == next) + { + Point64 n = t.cross(s); + Point64 m = (*prev->target - *next->reverse->target).cross(*next->target - *next->reverse->target); + btAssert(!m.isZero()); + int64_t dot = n.dot(m); + btAssert(dot != 0); + return (dot > 0) ? COUNTER_CLOCKWISE : CLOCKWISE; + } + return COUNTER_CLOCKWISE; + } + else if (prev->prev == next) + { + return CLOCKWISE; + } + else + { + return NONE; + } } btConvexHullInternal::Edge* btConvexHullInternal::findMaxAngle(bool ccw, const Vertex* start, const Point32& s, const Point64& rxs, const Point64& sxrxs, Rational64& minCot) { - Edge* minEdge = NULL; + Edge* minEdge = NULL; #ifdef DEBUG_CONVEX_HULL - printf("find max edge for %d\n", start->point.index); + printf("find max edge for %d\n", start->point.index); #endif - Edge* e = start->edges; - if (e) { - do { - if (e->copy > mergeStamp) { - Point32 t = *e->target - *start; - Rational64 cot(t.dot(sxrxs), t.dot(rxs)); + Edge* e = start->edges; + if (e) + { + do + { + if (e->copy > mergeStamp) + { + Point32 t = *e->target - *start; + Rational64 cot(t.dot(sxrxs), t.dot(rxs)); #ifdef DEBUG_CONVEX_HULL - printf(" Angle is %f (%d) for ", (float)btAtan(cot.toScalar()), (int)cot.isNaN()); - e->print(); + printf(" Angle is %f (%d) for ", (float)btAtan(cot.toScalar()), (int)cot.isNaN()); + e->print(); #endif - if (cot.isNaN()) { - btAssert(ccw ? (t.dot(s) < 0) : (t.dot(s) > 0)); - } - else { - int cmp; - if (minEdge == NULL) { - minCot = cot; - minEdge = e; - } - else if ((cmp = cot.compare(minCot)) < 0) { - minCot = cot; - minEdge = e; - } - else if ((cmp == 0) && (ccw == (getOrientation(minEdge, e, s, t) == COUNTER_CLOCKWISE))) { - minEdge = e; - } - } + if (cot.isNaN()) + { + btAssert(ccw ? (t.dot(s) < 0) : (t.dot(s) > 0)); + } + else + { + int cmp; + if (minEdge == NULL) + { + minCot = cot; + minEdge = e; + } + else if ((cmp = cot.compare(minCot)) < 0) + { + minCot = cot; + minEdge = e; + } + else if ((cmp == 0) && (ccw == (getOrientation(minEdge, e, s, t) == COUNTER_CLOCKWISE))) + { + minEdge = e; + } + } #ifdef DEBUG_CONVEX_HULL - printf("\n"); + printf("\n"); #endif - } - e = e->next; - } while (e != start->edges); - } - return minEdge; + } + e = e->next; + } while (e != start->edges); + } + return minEdge; } void btConvexHullInternal::findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge*& e0, Edge*& e1, Vertex* stop0, Vertex* stop1) { - Edge* start0 = e0; - Edge* start1 = e1; - Point32 et0 = start0 ? start0->target->point : c0->point; - Point32 et1 = start1 ? start1->target->point : c1->point; - Point32 s = c1->point - c0->point; - Point64 normal = ((start0 ? start0 : start1)->target->point - c0->point).cross(s); - int64_t dist = c0->point.dot(normal); - btAssert(!start1 || (start1->target->point.dot(normal) == dist)); - Point64 perp = s.cross(normal); - btAssert(!perp.isZero()); + Edge* start0 = e0; + Edge* start1 = e1; + Point32 et0 = start0 ? start0->target->point : c0->point; + Point32 et1 = start1 ? start1->target->point : c1->point; + Point32 s = c1->point - c0->point; + Point64 normal = ((start0 ? start0 : start1)->target->point - c0->point).cross(s); + int64_t dist = c0->point.dot(normal); + btAssert(!start1 || (start1->target->point.dot(normal) == dist)); + Point64 perp = s.cross(normal); + btAssert(!perp.isZero()); #ifdef DEBUG_CONVEX_HULL - printf(" Advancing %d %d (%p %p, %d %d)\n", c0->point.index, c1->point.index, start0, start1, start0 ? start0->target->point.index : -1, start1 ? start1->target->point.index : -1); + printf(" Advancing %d %d (%p %p, %d %d)\n", c0->point.index, c1->point.index, start0, start1, start0 ? start0->target->point.index : -1, start1 ? start1->target->point.index : -1); #endif - int64_t maxDot0 = et0.dot(perp); - if (e0) { - while (e0->target != stop0) { - Edge* e = e0->reverse->prev; - if (e->target->point.dot(normal) < dist) { - break; - } - btAssert(e->target->point.dot(normal) == dist); - if (e->copy == mergeStamp) { - break; - } - int64_t dot = e->target->point.dot(perp); - if (dot <= maxDot0) { - break; - } - maxDot0 = dot; - e0 = e; - et0 = e->target->point; - } - } + int64_t maxDot0 = et0.dot(perp); + if (e0) + { + while (e0->target != stop0) + { + Edge* e = e0->reverse->prev; + if (e->target->point.dot(normal) < dist) + { + break; + } + btAssert(e->target->point.dot(normal) == dist); + if (e->copy == mergeStamp) + { + break; + } + int64_t dot = e->target->point.dot(perp); + if (dot <= maxDot0) + { + break; + } + maxDot0 = dot; + e0 = e; + et0 = e->target->point; + } + } - int64_t maxDot1 = et1.dot(perp); - if (e1) { - while (e1->target != stop1) { - Edge* e = e1->reverse->next; - if (e->target->point.dot(normal) < dist) { - break; - } - btAssert(e->target->point.dot(normal) == dist); - if (e->copy == mergeStamp) { - break; - } - int64_t dot = e->target->point.dot(perp); - if (dot <= maxDot1) { - break; - } - maxDot1 = dot; - e1 = e; - et1 = e->target->point; - } - } + int64_t maxDot1 = et1.dot(perp); + if (e1) + { + while (e1->target != stop1) + { + Edge* e = e1->reverse->next; + if (e->target->point.dot(normal) < dist) + { + break; + } + btAssert(e->target->point.dot(normal) == dist); + if (e->copy == mergeStamp) + { + break; + } + int64_t dot = e->target->point.dot(perp); + if (dot <= maxDot1) + { + break; + } + maxDot1 = dot; + e1 = e; + et1 = e->target->point; + } + } #ifdef DEBUG_CONVEX_HULL - printf(" Starting at %d %d\n", et0.index, et1.index); + printf(" Starting at %d %d\n", et0.index, et1.index); #endif - int64_t dx = maxDot1 - maxDot0; - if (dx > 0) { - while (true) { - int64_t dy = (et1 - et0).dot(s); + int64_t dx = maxDot1 - maxDot0; + if (dx > 0) + { + while (true) + { + int64_t dy = (et1 - et0).dot(s); - if (e0 && (e0->target != stop0)) { - Edge* f0 = e0->next->reverse; - if (f0->copy > mergeStamp) { - int64_t dx0 = (f0->target->point - et0).dot(perp); - int64_t dy0 = (f0->target->point - et0).dot(s); - if ((dx0 == 0) ? (dy0 < 0) : ((dx0 < 0) && (Rational64(dy0, dx0).compare(Rational64(dy, dx)) >= 0))) { - et0 = f0->target->point; - dx = (et1 - et0).dot(perp); - e0 = (e0 == start0) ? NULL : f0; - continue; - } - } - } + if (e0 && (e0->target != stop0)) + { + Edge* f0 = e0->next->reverse; + if (f0->copy > mergeStamp) + { + int64_t dx0 = (f0->target->point - et0).dot(perp); + int64_t dy0 = (f0->target->point - et0).dot(s); + if ((dx0 == 0) ? (dy0 < 0) : ((dx0 < 0) && (Rational64(dy0, dx0).compare(Rational64(dy, dx)) >= 0))) + { + et0 = f0->target->point; + dx = (et1 - et0).dot(perp); + e0 = (e0 == start0) ? NULL : f0; + continue; + } + } + } - if (e1 && (e1->target != stop1)) { - Edge* f1 = e1->reverse->next; - if (f1->copy > mergeStamp) { - Point32 d1 = f1->target->point - et1; - if (d1.dot(normal) == 0) { - int64_t dx1 = d1.dot(perp); - int64_t dy1 = d1.dot(s); - int64_t dxn = (f1->target->point - et0).dot(perp); - if ((dxn > 0) && ((dx1 == 0) ? (dy1 < 0) : ((dx1 < 0) && (Rational64(dy1, dx1).compare(Rational64(dy, dx)) > 0)))) { - e1 = f1; - et1 = e1->target->point; - dx = dxn; - continue; - } - } - else { - btAssert((e1 == start1) && (d1.dot(normal) < 0)); - } - } - } + if (e1 && (e1->target != stop1)) + { + Edge* f1 = e1->reverse->next; + if (f1->copy > mergeStamp) + { + Point32 d1 = f1->target->point - et1; + if (d1.dot(normal) == 0) + { + int64_t dx1 = d1.dot(perp); + int64_t dy1 = d1.dot(s); + int64_t dxn = (f1->target->point - et0).dot(perp); + if ((dxn > 0) && ((dx1 == 0) ? (dy1 < 0) : ((dx1 < 0) && (Rational64(dy1, dx1).compare(Rational64(dy, dx)) > 0)))) + { + e1 = f1; + et1 = e1->target->point; + dx = dxn; + continue; + } + } + else + { + btAssert((e1 == start1) && (d1.dot(normal) < 0)); + } + } + } - break; - } - } - else if (dx < 0) { - while (true) { - int64_t dy = (et1 - et0).dot(s); + break; + } + } + else if (dx < 0) + { + while (true) + { + int64_t dy = (et1 - et0).dot(s); - if (e1 && (e1->target != stop1)) { - Edge* f1 = e1->prev->reverse; - if (f1->copy > mergeStamp) { - int64_t dx1 = (f1->target->point - et1).dot(perp); - int64_t dy1 = (f1->target->point - et1).dot(s); - if ((dx1 == 0) ? (dy1 > 0) : ((dx1 < 0) && (Rational64(dy1, dx1).compare(Rational64(dy, dx)) <= 0))) { - et1 = f1->target->point; - dx = (et1 - et0).dot(perp); - e1 = (e1 == start1) ? NULL : f1; - continue; - } - } - } + if (e1 && (e1->target != stop1)) + { + Edge* f1 = e1->prev->reverse; + if (f1->copy > mergeStamp) + { + int64_t dx1 = (f1->target->point - et1).dot(perp); + int64_t dy1 = (f1->target->point - et1).dot(s); + if ((dx1 == 0) ? (dy1 > 0) : ((dx1 < 0) && (Rational64(dy1, dx1).compare(Rational64(dy, dx)) <= 0))) + { + et1 = f1->target->point; + dx = (et1 - et0).dot(perp); + e1 = (e1 == start1) ? NULL : f1; + continue; + } + } + } - if (e0 && (e0->target != stop0)) { - Edge* f0 = e0->reverse->prev; - if (f0->copy > mergeStamp) { - Point32 d0 = f0->target->point - et0; - if (d0.dot(normal) == 0) { - int64_t dx0 = d0.dot(perp); - int64_t dy0 = d0.dot(s); - int64_t dxn = (et1 - f0->target->point).dot(perp); - if ((dxn < 0) && ((dx0 == 0) ? (dy0 > 0) : ((dx0 < 0) && (Rational64(dy0, dx0).compare(Rational64(dy, dx)) < 0)))) { - e0 = f0; - et0 = e0->target->point; - dx = dxn; - continue; - } - } - else { - btAssert((e0 == start0) && (d0.dot(normal) < 0)); - } - } - } + if (e0 && (e0->target != stop0)) + { + Edge* f0 = e0->reverse->prev; + if (f0->copy > mergeStamp) + { + Point32 d0 = f0->target->point - et0; + if (d0.dot(normal) == 0) + { + int64_t dx0 = d0.dot(perp); + int64_t dy0 = d0.dot(s); + int64_t dxn = (et1 - f0->target->point).dot(perp); + if ((dxn < 0) && ((dx0 == 0) ? (dy0 > 0) : ((dx0 < 0) && (Rational64(dy0, dx0).compare(Rational64(dy, dx)) < 0)))) + { + e0 = f0; + et0 = e0->target->point; + dx = dxn; + continue; + } + } + else + { + btAssert((e0 == start0) && (d0.dot(normal) < 0)); + } + } + } - break; - } - } + break; + } + } #ifdef DEBUG_CONVEX_HULL - printf(" Advanced edges to %d %d\n", et0.index, et1.index); + printf(" Advanced edges to %d %d\n", et0.index, et1.index); #endif } void btConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) { - if (!h1.maxXy) { - return; - } - if (!h0.maxXy) { - h0 = h1; - return; - } + if (!h1.maxXy) + { + return; + } + if (!h0.maxXy) + { + h0 = h1; + return; + } - mergeStamp--; + mergeStamp--; - Vertex* c0 = NULL; - Edge* toPrev0 = NULL; - Edge* firstNew0 = NULL; - Edge* pendingHead0 = NULL; - Edge* pendingTail0 = NULL; - Vertex* c1 = NULL; - Edge* toPrev1 = NULL; - Edge* firstNew1 = NULL; - Edge* pendingHead1 = NULL; - Edge* pendingTail1 = NULL; - Point32 prevPoint; + Vertex* c0 = NULL; + Edge* toPrev0 = NULL; + Edge* firstNew0 = NULL; + Edge* pendingHead0 = NULL; + Edge* pendingTail0 = NULL; + Vertex* c1 = NULL; + Edge* toPrev1 = NULL; + Edge* firstNew1 = NULL; + Edge* pendingHead1 = NULL; + Edge* pendingTail1 = NULL; + Point32 prevPoint; - if (mergeProjection(h0, h1, c0, c1)) { - Point32 s = *c1 - *c0; - Point64 normal = Point32(0, 0, -1).cross(s); - Point64 t = s.cross(normal); - btAssert(!t.isZero()); + if (mergeProjection(h0, h1, c0, c1)) + { + Point32 s = *c1 - *c0; + Point64 normal = Point32(0, 0, -1).cross(s); + Point64 t = s.cross(normal); + btAssert(!t.isZero()); - Edge* e = c0->edges; - Edge* start0 = NULL; - if (e) { - do { - int64_t dot = (*e->target - *c0).dot(normal); - btAssert(dot <= 0); - if ((dot == 0) && ((*e->target - *c0).dot(t) > 0)) { - if (!start0 || (getOrientation(start0, e, s, Point32(0, 0, -1)) == CLOCKWISE)) { - start0 = e; - } - } - e = e->next; - } while (e != c0->edges); - } + Edge* e = c0->edges; + Edge* start0 = NULL; + if (e) + { + do + { + int64_t dot = (*e->target - *c0).dot(normal); + btAssert(dot <= 0); + if ((dot == 0) && ((*e->target - *c0).dot(t) > 0)) + { + if (!start0 || (getOrientation(start0, e, s, Point32(0, 0, -1)) == CLOCKWISE)) + { + start0 = e; + } + } + e = e->next; + } while (e != c0->edges); + } - e = c1->edges; - Edge* start1 = NULL; - if (e) { - do { - int64_t dot = (*e->target - *c1).dot(normal); - btAssert(dot <= 0); - if ((dot == 0) && ((*e->target - *c1).dot(t) > 0)) { - if (!start1 || (getOrientation(start1, e, s, Point32(0, 0, -1)) == COUNTER_CLOCKWISE)) { - start1 = e; - } - } - e = e->next; - } while (e != c1->edges); - } + e = c1->edges; + Edge* start1 = NULL; + if (e) + { + do + { + int64_t dot = (*e->target - *c1).dot(normal); + btAssert(dot <= 0); + if ((dot == 0) && ((*e->target - *c1).dot(t) > 0)) + { + if (!start1 || (getOrientation(start1, e, s, Point32(0, 0, -1)) == COUNTER_CLOCKWISE)) + { + start1 = e; + } + } + e = e->next; + } while (e != c1->edges); + } - if (start0 || start1) { - findEdgeForCoplanarFaces(c0, c1, start0, start1, NULL, NULL); - if (start0) { - c0 = start0->target; - } - if (start1) { - c1 = start1->target; - } - } + if (start0 || start1) + { + findEdgeForCoplanarFaces(c0, c1, start0, start1, NULL, NULL); + if (start0) + { + c0 = start0->target; + } + if (start1) + { + c1 = start1->target; + } + } - prevPoint = c1->point; - prevPoint.z++; - } - else { - prevPoint = c1->point; - prevPoint.x++; - } + prevPoint = c1->point; + prevPoint.z++; + } + else + { + prevPoint = c1->point; + prevPoint.x++; + } - Vertex* first0 = c0; - Vertex* first1 = c1; - bool firstRun = true; + Vertex* first0 = c0; + Vertex* first1 = c1; + bool firstRun = true; - while (true) { - Point32 s = *c1 - *c0; - Point32 r = prevPoint - c0->point; - Point64 rxs = r.cross(s); - Point64 sxrxs = s.cross(rxs); + while (true) + { + Point32 s = *c1 - *c0; + Point32 r = prevPoint - c0->point; + Point64 rxs = r.cross(s); + Point64 sxrxs = s.cross(rxs); #ifdef DEBUG_CONVEX_HULL - printf("\n Checking %d %d\n", c0->point.index, c1->point.index); + printf("\n Checking %d %d\n", c0->point.index, c1->point.index); #endif - Rational64 minCot0(0, 0); - Edge* min0 = findMaxAngle(false, c0, s, rxs, sxrxs, minCot0); - Rational64 minCot1(0, 0); - Edge* min1 = findMaxAngle(true, c1, s, rxs, sxrxs, minCot1); - if (!min0 && !min1) { - Edge* e = newEdgePair(c0, c1); - e->link(e); - c0->edges = e; + Rational64 minCot0(0, 0); + Edge* min0 = findMaxAngle(false, c0, s, rxs, sxrxs, minCot0); + Rational64 minCot1(0, 0); + Edge* min1 = findMaxAngle(true, c1, s, rxs, sxrxs, minCot1); + if (!min0 && !min1) + { + Edge* e = newEdgePair(c0, c1); + e->link(e); + c0->edges = e; - e = e->reverse; - e->link(e); - c1->edges = e; - return; - } - else { - int cmp = !min0 ? 1 : !min1 ? -1 : minCot0.compare(minCot1); + e = e->reverse; + e->link(e); + c1->edges = e; + return; + } + else + { + int cmp = !min0 ? 1 : !min1 ? -1 : minCot0.compare(minCot1); #ifdef DEBUG_CONVEX_HULL - printf(" -> Result %d\n", cmp); + printf(" -> Result %d\n", cmp); #endif - if (firstRun || ((cmp >= 0) ? !minCot1.isNegativeInfinity() : !minCot0.isNegativeInfinity())) { - Edge* e = newEdgePair(c0, c1); - if (pendingTail0) { - pendingTail0->prev = e; - } - else { - pendingHead0 = e; - } - e->next = pendingTail0; - pendingTail0 = e; + if (firstRun || ((cmp >= 0) ? !minCot1.isNegativeInfinity() : !minCot0.isNegativeInfinity())) + { + Edge* e = newEdgePair(c0, c1); + if (pendingTail0) + { + pendingTail0->prev = e; + } + else + { + pendingHead0 = e; + } + e->next = pendingTail0; + pendingTail0 = e; - e = e->reverse; - if (pendingTail1) { - pendingTail1->next = e; - } - else { - pendingHead1 = e; - } - e->prev = pendingTail1; - pendingTail1 = e; - } + e = e->reverse; + if (pendingTail1) + { + pendingTail1->next = e; + } + else + { + pendingHead1 = e; + } + e->prev = pendingTail1; + pendingTail1 = e; + } - Edge* e0 = min0; - Edge* e1 = min1; + Edge* e0 = min0; + Edge* e1 = min1; #ifdef DEBUG_CONVEX_HULL - printf(" Found min edges to %d %d\n", e0 ? e0->target->point.index : -1, e1 ? e1->target->point.index : -1); + printf(" Found min edges to %d %d\n", e0 ? e0->target->point.index : -1, e1 ? e1->target->point.index : -1); #endif - if (cmp == 0) { - findEdgeForCoplanarFaces(c0, c1, e0, e1, NULL, NULL); - } + if (cmp == 0) + { + findEdgeForCoplanarFaces(c0, c1, e0, e1, NULL, NULL); + } - if ((cmp >= 0) && e1) { - if (toPrev1) { - for (Edge *e = toPrev1->next, *n = NULL; e != min1; e = n) { - n = e->next; - removeEdgePair(e); - } - } + if ((cmp >= 0) && e1) + { + if (toPrev1) + { + for (Edge *e = toPrev1->next, *n = NULL; e != min1; e = n) + { + n = e->next; + removeEdgePair(e); + } + } - if (pendingTail1) { - if (toPrev1) { - toPrev1->link(pendingHead1); - } - else { - min1->prev->link(pendingHead1); - firstNew1 = pendingHead1; - } - pendingTail1->link(min1); - pendingHead1 = NULL; - pendingTail1 = NULL; - } - else if (!toPrev1) { - firstNew1 = min1; - } + if (pendingTail1) + { + if (toPrev1) + { + toPrev1->link(pendingHead1); + } + else + { + min1->prev->link(pendingHead1); + firstNew1 = pendingHead1; + } + pendingTail1->link(min1); + pendingHead1 = NULL; + pendingTail1 = NULL; + } + else if (!toPrev1) + { + firstNew1 = min1; + } - prevPoint = c1->point; - c1 = e1->target; - toPrev1 = e1->reverse; - } + prevPoint = c1->point; + c1 = e1->target; + toPrev1 = e1->reverse; + } - if ((cmp <= 0) && e0) { - if (toPrev0) { - for (Edge *e = toPrev0->prev, *n = NULL; e != min0; e = n) { - n = e->prev; - removeEdgePair(e); - } - } + if ((cmp <= 0) && e0) + { + if (toPrev0) + { + for (Edge *e = toPrev0->prev, *n = NULL; e != min0; e = n) + { + n = e->prev; + removeEdgePair(e); + } + } - if (pendingTail0) { - if (toPrev0) { - pendingHead0->link(toPrev0); - } - else { - pendingHead0->link(min0->next); - firstNew0 = pendingHead0; - } - min0->link(pendingTail0); - pendingHead0 = NULL; - pendingTail0 = NULL; - } - else if (!toPrev0) { - firstNew0 = min0; - } + if (pendingTail0) + { + if (toPrev0) + { + pendingHead0->link(toPrev0); + } + else + { + pendingHead0->link(min0->next); + firstNew0 = pendingHead0; + } + min0->link(pendingTail0); + pendingHead0 = NULL; + pendingTail0 = NULL; + } + else if (!toPrev0) + { + firstNew0 = min0; + } - prevPoint = c0->point; - c0 = e0->target; - toPrev0 = e0->reverse; - } - } + prevPoint = c0->point; + c0 = e0->target; + toPrev0 = e0->reverse; + } + } - if ((c0 == first0) && (c1 == first1)) { - if (toPrev0 == NULL) { - pendingHead0->link(pendingTail0); - c0->edges = pendingTail0; - } - else { - for (Edge *e = toPrev0->prev, *n = NULL; e != firstNew0; e = n) { - n = e->prev; - removeEdgePair(e); - } - if (pendingTail0) { - pendingHead0->link(toPrev0); - firstNew0->link(pendingTail0); - } - } + if ((c0 == first0) && (c1 == first1)) + { + if (toPrev0 == NULL) + { + pendingHead0->link(pendingTail0); + c0->edges = pendingTail0; + } + else + { + for (Edge *e = toPrev0->prev, *n = NULL; e != firstNew0; e = n) + { + n = e->prev; + removeEdgePair(e); + } + if (pendingTail0) + { + pendingHead0->link(toPrev0); + firstNew0->link(pendingTail0); + } + } - if (toPrev1 == NULL) { - pendingTail1->link(pendingHead1); - c1->edges = pendingTail1; - } - else { - for (Edge *e = toPrev1->next, *n = NULL; e != firstNew1; e = n) { - n = e->next; - removeEdgePair(e); - } - if (pendingTail1) { - toPrev1->link(pendingHead1); - pendingTail1->link(firstNew1); - } - } + if (toPrev1 == NULL) + { + pendingTail1->link(pendingHead1); + c1->edges = pendingTail1; + } + else + { + for (Edge *e = toPrev1->next, *n = NULL; e != firstNew1; e = n) + { + n = e->next; + removeEdgePair(e); + } + if (pendingTail1) + { + toPrev1->link(pendingHead1); + pendingTail1->link(firstNew1); + } + } - return; - } + return; + } - firstRun = false; - } + firstRun = false; + } } static bool pointCmp(const btConvexHullInternal::Point32& p, const btConvexHullInternal::Point32& q) { - return (p.y < q.y) || ((p.y == q.y) && ((p.x < q.x) || ((p.x == q.x) && (p.z < q.z)))); + return (p.y < q.y) || ((p.y == q.y) && ((p.x < q.x) || ((p.x == q.x) && (p.z < q.z)))); } void btConvexHullInternal::compute(const void* coords, bool doubleCoords, int stride, int count) { - btVector3 min(btScalar(1e30), btScalar(1e30), btScalar(1e30)), max(btScalar(-1e30), btScalar(-1e30), btScalar(-1e30)); - const char* ptr = (const char*)coords; - if (doubleCoords) { - for (int i = 0; i < count; i++) { - const double* v = (const double*)ptr; - btVector3 p((btScalar)v[0], (btScalar)v[1], (btScalar)v[2]); - ptr += stride; - min.setMin(p); - max.setMax(p); - } - } - else { - for (int i = 0; i < count; i++) { - const float* v = (const float*)ptr; - btVector3 p(v[0], v[1], v[2]); - ptr += stride; - min.setMin(p); - max.setMax(p); - } - } + btVector3 min(btScalar(1e30), btScalar(1e30), btScalar(1e30)), max(btScalar(-1e30), btScalar(-1e30), btScalar(-1e30)); + const char* ptr = (const char*)coords; + if (doubleCoords) + { + for (int i = 0; i < count; i++) + { + const double* v = (const double*)ptr; + btVector3 p((btScalar)v[0], (btScalar)v[1], (btScalar)v[2]); + ptr += stride; + min.setMin(p); + max.setMax(p); + } + } + else + { + for (int i = 0; i < count; i++) + { + const float* v = (const float*)ptr; + btVector3 p(v[0], v[1], v[2]); + ptr += stride; + min.setMin(p); + max.setMax(p); + } + } - btVector3 s = max - min; - maxAxis = s.maxAxis(); - minAxis = s.minAxis(); - if (minAxis == maxAxis) { - minAxis = (maxAxis + 1) % 3; - } - medAxis = 3 - maxAxis - minAxis; + btVector3 s = max - min; + maxAxis = s.maxAxis(); + minAxis = s.minAxis(); + if (minAxis == maxAxis) + { + minAxis = (maxAxis + 1) % 3; + } + medAxis = 3 - maxAxis - minAxis; - s /= btScalar(10216); - if (((medAxis + 1) % 3) != maxAxis) { - s *= -1; - } - scaling = s; + s /= btScalar(10216); + if (((medAxis + 1) % 3) != maxAxis) + { + s *= -1; + } + scaling = s; - if (s[0] != 0) { - s[0] = btScalar(1) / s[0]; - } - if (s[1] != 0) { - s[1] = btScalar(1) / s[1]; - } - if (s[2] != 0) { - s[2] = btScalar(1) / s[2]; - } + if (s[0] != 0) + { + s[0] = btScalar(1) / s[0]; + } + if (s[1] != 0) + { + s[1] = btScalar(1) / s[1]; + } + if (s[2] != 0) + { + s[2] = btScalar(1) / s[2]; + } - center = (min + max) * btScalar(0.5); + center = (min + max) * btScalar(0.5); - btAlignedObjectArray points; - points.resize(count); - ptr = (const char*)coords; - if (doubleCoords) { - for (int i = 0; i < count; i++) { - const double* v = (const double*)ptr; - btVector3 p((btScalar)v[0], (btScalar)v[1], (btScalar)v[2]); - ptr += stride; - p = (p - center) * s; - points[i].x = (int32_t)p[medAxis]; - points[i].y = (int32_t)p[maxAxis]; - points[i].z = (int32_t)p[minAxis]; - points[i].index = i; - } - } - else { - for (int i = 0; i < count; i++) { - const float* v = (const float*)ptr; - btVector3 p(v[0], v[1], v[2]); - ptr += stride; - p = (p - center) * s; - points[i].x = (int32_t)p[medAxis]; - points[i].y = (int32_t)p[maxAxis]; - points[i].z = (int32_t)p[minAxis]; - points[i].index = i; - } - } - points.quickSort(pointCmp); + btAlignedObjectArray points; + points.resize(count); + ptr = (const char*)coords; + if (doubleCoords) + { + for (int i = 0; i < count; i++) + { + const double* v = (const double*)ptr; + btVector3 p((btScalar)v[0], (btScalar)v[1], (btScalar)v[2]); + ptr += stride; + p = (p - center) * s; + points[i].x = (int32_t)p[medAxis]; + points[i].y = (int32_t)p[maxAxis]; + points[i].z = (int32_t)p[minAxis]; + points[i].index = i; + } + } + else + { + for (int i = 0; i < count; i++) + { + const float* v = (const float*)ptr; + btVector3 p(v[0], v[1], v[2]); + ptr += stride; + p = (p - center) * s; + points[i].x = (int32_t)p[medAxis]; + points[i].y = (int32_t)p[maxAxis]; + points[i].z = (int32_t)p[minAxis]; + points[i].index = i; + } + } + points.quickSort(pointCmp); - vertexPool.reset(); - vertexPool.setArraySize(count); - originalVertices.resize(count); - for (int i = 0; i < count; i++) { - Vertex* v = vertexPool.newObject(); - v->edges = NULL; - v->point = points[i]; - v->copy = -1; - originalVertices[i] = v; - } + vertexPool.reset(); + vertexPool.setArraySize(count); + originalVertices.resize(count); + for (int i = 0; i < count; i++) + { + Vertex* v = vertexPool.newObject(); + v->edges = NULL; + v->point = points[i]; + v->copy = -1; + originalVertices[i] = v; + } - points.clear(); + points.clear(); - edgePool.reset(); - edgePool.setArraySize(6 * count); + edgePool.reset(); + edgePool.setArraySize(6 * count); - usedEdgePairs = 0; - maxUsedEdgePairs = 0; + usedEdgePairs = 0; + maxUsedEdgePairs = 0; - mergeStamp = -3; + mergeStamp = -3; - IntermediateHull hull; - computeInternal(0, count, hull); - vertexList = hull.minXy; + IntermediateHull hull; + computeInternal(0, count, hull); + vertexList = hull.minXy; #ifdef DEBUG_CONVEX_HULL - printf("max. edges %d (3v = %d)", maxUsedEdgePairs, 3 * count); + printf("max. edges %d (3v = %d)", maxUsedEdgePairs, 3 * count); #endif } btVector3 btConvexHullInternal::toBtVector(const Point32& v) { - btVector3 p; - p[medAxis] = btScalar(v.x); - p[maxAxis] = btScalar(v.y); - p[minAxis] = btScalar(v.z); - return p * scaling; + btVector3 p; + p[medAxis] = btScalar(v.x); + p[maxAxis] = btScalar(v.y); + p[minAxis] = btScalar(v.z); + return p * scaling; } btVector3 btConvexHullInternal::getBtNormal(Face* face) { - return toBtVector(face->dir0).cross(toBtVector(face->dir1)).normalized(); + return toBtVector(face->dir0).cross(toBtVector(face->dir1)).normalized(); } btVector3 btConvexHullInternal::getCoordinates(const Vertex* v) { - btVector3 p; - p[medAxis] = v->xvalue(); - p[maxAxis] = v->yvalue(); - p[minAxis] = v->zvalue(); - return p * scaling + center; + btVector3 p; + p[medAxis] = v->xvalue(); + p[maxAxis] = v->yvalue(); + p[minAxis] = v->zvalue(); + return p * scaling + center; } btScalar btConvexHullInternal::shrink(btScalar amount, btScalar clampAmount) { - if (!vertexList) { - return 0; - } - int stamp = --mergeStamp; - btAlignedObjectArray stack; - vertexList->copy = stamp; - stack.push_back(vertexList); - btAlignedObjectArray faces; + if (!vertexList) + { + return 0; + } + int stamp = --mergeStamp; + btAlignedObjectArray stack; + vertexList->copy = stamp; + stack.push_back(vertexList); + btAlignedObjectArray faces; - Point32 ref = vertexList->point; - Int128 hullCenterX(0, 0); - Int128 hullCenterY(0, 0); - Int128 hullCenterZ(0, 0); - Int128 volume(0, 0); + Point32 ref = vertexList->point; + Int128 hullCenterX(0, 0); + Int128 hullCenterY(0, 0); + Int128 hullCenterZ(0, 0); + Int128 volume(0, 0); - while (stack.size() > 0) { - Vertex* v = stack[stack.size() - 1]; - stack.pop_back(); - Edge* e = v->edges; - if (e) { - do { - if (e->target->copy != stamp) { - e->target->copy = stamp; - stack.push_back(e->target); - } - if (e->copy != stamp) { - Face* face = facePool.newObject(); - face->init(e->target, e->reverse->prev->target, v); - faces.push_back(face); - Edge* f = e; + while (stack.size() > 0) + { + Vertex* v = stack[stack.size() - 1]; + stack.pop_back(); + Edge* e = v->edges; + if (e) + { + do + { + if (e->target->copy != stamp) + { + e->target->copy = stamp; + stack.push_back(e->target); + } + if (e->copy != stamp) + { + Face* face = facePool.newObject(); + face->init(e->target, e->reverse->prev->target, v); + faces.push_back(face); + Edge* f = e; - Vertex* a = NULL; - Vertex* b = NULL; - do { - if (a && b) { - int64_t vol = (v->point - ref).dot((a->point - ref).cross(b->point - ref)); - btAssert(vol >= 0); - Point32 c = v->point + a->point + b->point + ref; - hullCenterX += vol * c.x; - hullCenterY += vol * c.y; - hullCenterZ += vol * c.z; - volume += vol; - } + Vertex* a = NULL; + Vertex* b = NULL; + do + { + if (a && b) + { + int64_t vol = (v->point - ref).dot((a->point - ref).cross(b->point - ref)); + btAssert(vol >= 0); + Point32 c = v->point + a->point + b->point + ref; + hullCenterX += vol * c.x; + hullCenterY += vol * c.y; + hullCenterZ += vol * c.z; + volume += vol; + } - btAssert(f->copy != stamp); - f->copy = stamp; - f->face = face; + btAssert(f->copy != stamp); + f->copy = stamp; + f->face = face; - a = b; - b = f->target; + a = b; + b = f->target; - f = f->reverse->prev; - } while (f != e); - } - e = e->next; - } while (e != v->edges); - } - } + f = f->reverse->prev; + } while (f != e); + } + e = e->next; + } while (e != v->edges); + } + } - if (volume.getSign() <= 0) { - return 0; - } + if (volume.getSign() <= 0) + { + return 0; + } - btVector3 hullCenter; - hullCenter[medAxis] = hullCenterX.toScalar(); - hullCenter[maxAxis] = hullCenterY.toScalar(); - hullCenter[minAxis] = hullCenterZ.toScalar(); - hullCenter /= 4 * volume.toScalar(); - hullCenter *= scaling; + btVector3 hullCenter; + hullCenter[medAxis] = hullCenterX.toScalar(); + hullCenter[maxAxis] = hullCenterY.toScalar(); + hullCenter[minAxis] = hullCenterZ.toScalar(); + hullCenter /= 4 * volume.toScalar(); + hullCenter *= scaling; - int faceCount = faces.size(); + int faceCount = faces.size(); - if (clampAmount > 0) { - btScalar minDist = SIMD_INFINITY; - for (int i = 0; i < faceCount; i++) { - btVector3 normal = getBtNormal(faces[i]); - btScalar dist = normal.dot(toBtVector(faces[i]->origin) - hullCenter); - if (dist < minDist) { - minDist = dist; - } - } + if (clampAmount > 0) + { + btScalar minDist = SIMD_INFINITY; + for (int i = 0; i < faceCount; i++) + { + btVector3 normal = getBtNormal(faces[i]); + btScalar dist = normal.dot(toBtVector(faces[i]->origin) - hullCenter); + if (dist < minDist) + { + minDist = dist; + } + } - if (minDist <= 0) { - return 0; - } + if (minDist <= 0) + { + return 0; + } - amount = btMin(amount, minDist * clampAmount); - } + amount = btMin(amount, minDist * clampAmount); + } - unsigned int seed = 243703; - for (int i = 0; i < faceCount; i++, seed = 1664525 * seed + 1013904223) { - btSwap(faces[i], faces[seed % faceCount]); - } + unsigned int seed = 243703; + for (int i = 0; i < faceCount; i++, seed = 1664525 * seed + 1013904223) + { + btSwap(faces[i], faces[seed % faceCount]); + } - for (int i = 0; i < faceCount; i++) { - if (!shiftFace(faces[i], amount, stack)) { - return -amount; - } - } + for (int i = 0; i < faceCount; i++) + { + if (!shiftFace(faces[i], amount, stack)) + { + return -amount; + } + } - return amount; + return amount; } bool btConvexHullInternal::shiftFace(Face* face, btScalar amount, btAlignedObjectArray stack) { - btVector3 origShift = getBtNormal(face) * -amount; - if (scaling[0] != 0) { - origShift[0] /= scaling[0]; - } - if (scaling[1] != 0) { - origShift[1] /= scaling[1]; - } - if (scaling[2] != 0) { - origShift[2] /= scaling[2]; - } - Point32 shift((int32_t)origShift[medAxis], (int32_t)origShift[maxAxis], (int32_t)origShift[minAxis]); - if (shift.isZero()) { - return true; - } - Point64 normal = face->getNormal(); + btVector3 origShift = getBtNormal(face) * -amount; + if (scaling[0] != 0) + { + origShift[0] /= scaling[0]; + } + if (scaling[1] != 0) + { + origShift[1] /= scaling[1]; + } + if (scaling[2] != 0) + { + origShift[2] /= scaling[2]; + } + Point32 shift((int32_t)origShift[medAxis], (int32_t)origShift[maxAxis], (int32_t)origShift[minAxis]); + if (shift.isZero()) + { + return true; + } + Point64 normal = face->getNormal(); #ifdef DEBUG_CONVEX_HULL - printf("\nShrinking face (%d %d %d) (%d %d %d) (%d %d %d) by (%d %d %d)\n", - face->origin.x, face->origin.y, face->origin.z, face->dir0.x, face->dir0.y, face->dir0.z, face->dir1.x, face->dir1.y, face->dir1.z, shift.x, shift.y, shift.z); + printf("\nShrinking face (%d %d %d) (%d %d %d) (%d %d %d) by (%d %d %d)\n", + face->origin.x, face->origin.y, face->origin.z, face->dir0.x, face->dir0.y, face->dir0.z, face->dir1.x, face->dir1.y, face->dir1.z, shift.x, shift.y, shift.z); #endif - int64_t origDot = face->origin.dot(normal); - Point32 shiftedOrigin = face->origin + shift; - int64_t shiftedDot = shiftedOrigin.dot(normal); - btAssert(shiftedDot <= origDot); - if (shiftedDot >= origDot) { - return false; - } + int64_t origDot = face->origin.dot(normal); + Point32 shiftedOrigin = face->origin + shift; + int64_t shiftedDot = shiftedOrigin.dot(normal); + btAssert(shiftedDot <= origDot); + if (shiftedDot >= origDot) + { + return false; + } - Edge* intersection = NULL; + Edge* intersection = NULL; - Edge* startEdge = face->nearbyVertex->edges; + Edge* startEdge = face->nearbyVertex->edges; #ifdef DEBUG_CONVEX_HULL - printf("Start edge is "); - startEdge->print(); - printf(", normal is (%lld %lld %lld), shifted dot is %lld\n", normal.x, normal.y, normal.z, shiftedDot); + printf("Start edge is "); + startEdge->print(); + printf(", normal is (%lld %lld %lld), shifted dot is %lld\n", normal.x, normal.y, normal.z, shiftedDot); #endif - Rational128 optDot = face->nearbyVertex->dot(normal); - int cmp = optDot.compare(shiftedDot); + Rational128 optDot = face->nearbyVertex->dot(normal); + int cmp = optDot.compare(shiftedDot); #ifdef SHOW_ITERATIONS - int n = 0; + int n = 0; #endif - if (cmp >= 0) { - Edge* e = startEdge; - do { + if (cmp >= 0) + { + Edge* e = startEdge; + do + { #ifdef SHOW_ITERATIONS - n++; + n++; #endif - Rational128 dot = e->target->dot(normal); - btAssert(dot.compare(origDot) <= 0); + Rational128 dot = e->target->dot(normal); + btAssert(dot.compare(origDot) <= 0); #ifdef DEBUG_CONVEX_HULL - printf("Moving downwards, edge is "); - e->print(); - printf(", dot is %f (%f %lld)\n", (float)dot.toScalar(), (float)optDot.toScalar(), shiftedDot); + printf("Moving downwards, edge is "); + e->print(); + printf(", dot is %f (%f %lld)\n", (float)dot.toScalar(), (float)optDot.toScalar(), shiftedDot); #endif - if (dot.compare(optDot) < 0) { - int c = dot.compare(shiftedDot); - optDot = dot; - e = e->reverse; - startEdge = e; - if (c < 0) { - intersection = e; - break; - } - cmp = c; - } - e = e->prev; - } while (e != startEdge); + if (dot.compare(optDot) < 0) + { + int c = dot.compare(shiftedDot); + optDot = dot; + e = e->reverse; + startEdge = e; + if (c < 0) + { + intersection = e; + break; + } + cmp = c; + } + e = e->prev; + } while (e != startEdge); - if (!intersection) { - return false; - } - } - else { - Edge* e = startEdge; - do { + if (!intersection) + { + return false; + } + } + else + { + Edge* e = startEdge; + do + { #ifdef SHOW_ITERATIONS - n++; + n++; #endif - Rational128 dot = e->target->dot(normal); - btAssert(dot.compare(origDot) <= 0); + Rational128 dot = e->target->dot(normal); + btAssert(dot.compare(origDot) <= 0); #ifdef DEBUG_CONVEX_HULL - printf("Moving upwards, edge is "); - e->print(); - printf(", dot is %f (%f %lld)\n", (float)dot.toScalar(), (float)optDot.toScalar(), shiftedDot); + printf("Moving upwards, edge is "); + e->print(); + printf(", dot is %f (%f %lld)\n", (float)dot.toScalar(), (float)optDot.toScalar(), shiftedDot); #endif - if (dot.compare(optDot) > 0) { - cmp = dot.compare(shiftedDot); - if (cmp >= 0) { - intersection = e; - break; - } - optDot = dot; - e = e->reverse; - startEdge = e; - } - e = e->prev; - } while (e != startEdge); + if (dot.compare(optDot) > 0) + { + cmp = dot.compare(shiftedDot); + if (cmp >= 0) + { + intersection = e; + break; + } + optDot = dot; + e = e->reverse; + startEdge = e; + } + e = e->prev; + } while (e != startEdge); - if (!intersection) { - return true; - } - } + if (!intersection) + { + return true; + } + } #ifdef SHOW_ITERATIONS - printf("Needed %d iterations to find initial intersection\n", n); + printf("Needed %d iterations to find initial intersection\n", n); #endif - if (cmp == 0) { - Edge* e = intersection->reverse->next; + if (cmp == 0) + { + Edge* e = intersection->reverse->next; #ifdef SHOW_ITERATIONS - n = 0; + n = 0; #endif - while (e->target->dot(normal).compare(shiftedDot) <= 0) { + while (e->target->dot(normal).compare(shiftedDot) <= 0) + { #ifdef SHOW_ITERATIONS - n++; + n++; #endif - e = e->next; - if (e == intersection->reverse) { - return true; - } + e = e->next; + if (e == intersection->reverse) + { + return true; + } #ifdef DEBUG_CONVEX_HULL - printf("Checking for outwards edge, current edge is "); - e->print(); - printf("\n"); + printf("Checking for outwards edge, current edge is "); + e->print(); + printf("\n"); #endif - } + } #ifdef SHOW_ITERATIONS - printf("Needed %d iterations to check for complete containment\n", n); + printf("Needed %d iterations to check for complete containment\n", n); #endif - } + } - Edge* firstIntersection = NULL; - Edge* faceEdge = NULL; - Edge* firstFaceEdge = NULL; + Edge* firstIntersection = NULL; + Edge* faceEdge = NULL; + Edge* firstFaceEdge = NULL; #ifdef SHOW_ITERATIONS - int m = 0; + int m = 0; #endif - while (true) { + while (true) + { #ifdef SHOW_ITERATIONS - m++; + m++; #endif #ifdef DEBUG_CONVEX_HULL - printf("Intersecting edge is "); - intersection->print(); - printf("\n"); + printf("Intersecting edge is "); + intersection->print(); + printf("\n"); #endif - if (cmp == 0) { - Edge* e = intersection->reverse->next; - startEdge = e; + if (cmp == 0) + { + Edge* e = intersection->reverse->next; + startEdge = e; #ifdef SHOW_ITERATIONS - n = 0; + n = 0; #endif - while (true) { + while (true) + { #ifdef SHOW_ITERATIONS - n++; + n++; #endif - if (e->target->dot(normal).compare(shiftedDot) >= 0) { - break; - } - intersection = e->reverse; - e = e->next; - if (e == startEdge) { - return true; - } - } + if (e->target->dot(normal).compare(shiftedDot) >= 0) + { + break; + } + intersection = e->reverse; + e = e->next; + if (e == startEdge) + { + return true; + } + } #ifdef SHOW_ITERATIONS - printf("Needed %d iterations to advance intersection\n", n); + printf("Needed %d iterations to advance intersection\n", n); #endif - } + } #ifdef DEBUG_CONVEX_HULL - printf("Advanced intersecting edge to "); - intersection->print(); - printf(", cmp = %d\n", cmp); + printf("Advanced intersecting edge to "); + intersection->print(); + printf(", cmp = %d\n", cmp); #endif - if (!firstIntersection) { - firstIntersection = intersection; - } - else if (intersection == firstIntersection) { - break; - } + if (!firstIntersection) + { + firstIntersection = intersection; + } + else if (intersection == firstIntersection) + { + break; + } - int prevCmp = cmp; - Edge* prevIntersection = intersection; - Edge* prevFaceEdge = faceEdge; + int prevCmp = cmp; + Edge* prevIntersection = intersection; + Edge* prevFaceEdge = faceEdge; - Edge* e = intersection->reverse; + Edge* e = intersection->reverse; #ifdef SHOW_ITERATIONS - n = 0; + n = 0; #endif - while (true) { + while (true) + { #ifdef SHOW_ITERATIONS - n++; + n++; #endif - e = e->reverse->prev; - btAssert(e != intersection->reverse); - cmp = e->target->dot(normal).compare(shiftedDot); + e = e->reverse->prev; + btAssert(e != intersection->reverse); + cmp = e->target->dot(normal).compare(shiftedDot); #ifdef DEBUG_CONVEX_HULL - printf("Testing edge "); - e->print(); - printf(" -> cmp = %d\n", cmp); + printf("Testing edge "); + e->print(); + printf(" -> cmp = %d\n", cmp); #endif - if (cmp >= 0) { - intersection = e; - break; - } - } + if (cmp >= 0) + { + intersection = e; + break; + } + } #ifdef SHOW_ITERATIONS - printf("Needed %d iterations to find other intersection of face\n", n); + printf("Needed %d iterations to find other intersection of face\n", n); #endif - if (cmp > 0) { - Vertex* removed = intersection->target; - e = intersection->reverse; - if (e->prev == e) { - removed->edges = NULL; - } - else { - removed->edges = e->prev; - e->prev->link(e->next); - e->link(e); - } + if (cmp > 0) + { + Vertex* removed = intersection->target; + e = intersection->reverse; + if (e->prev == e) + { + removed->edges = NULL; + } + else + { + removed->edges = e->prev; + e->prev->link(e->next); + e->link(e); + } #ifdef DEBUG_CONVEX_HULL - printf("1: Removed part contains (%d %d %d)\n", removed->point.x, removed->point.y, removed->point.z); + printf("1: Removed part contains (%d %d %d)\n", removed->point.x, removed->point.y, removed->point.z); #endif - Point64 n0 = intersection->face->getNormal(); - Point64 n1 = intersection->reverse->face->getNormal(); - int64_t m00 = face->dir0.dot(n0); - int64_t m01 = face->dir1.dot(n0); - int64_t m10 = face->dir0.dot(n1); - int64_t m11 = face->dir1.dot(n1); - int64_t r0 = (intersection->face->origin - shiftedOrigin).dot(n0); - int64_t r1 = (intersection->reverse->face->origin - shiftedOrigin).dot(n1); - Int128 det = Int128::mul(m00, m11) - Int128::mul(m01, m10); - btAssert(det.getSign() != 0); - Vertex* v = vertexPool.newObject(); - v->point.index = -1; - v->copy = -1; - v->point128 = PointR128(Int128::mul(face->dir0.x * r0, m11) - Int128::mul(face->dir0.x * r1, m01) - + Int128::mul(face->dir1.x * r1, m00) - Int128::mul(face->dir1.x * r0, m10) + det * shiftedOrigin.x, - Int128::mul(face->dir0.y * r0, m11) - Int128::mul(face->dir0.y * r1, m01) - + Int128::mul(face->dir1.y * r1, m00) - Int128::mul(face->dir1.y * r0, m10) + det * shiftedOrigin.y, - Int128::mul(face->dir0.z * r0, m11) - Int128::mul(face->dir0.z * r1, m01) - + Int128::mul(face->dir1.z * r1, m00) - Int128::mul(face->dir1.z * r0, m10) + det * shiftedOrigin.z, - det); - v->point.x = (int32_t)v->point128.xvalue(); - v->point.y = (int32_t)v->point128.yvalue(); - v->point.z = (int32_t)v->point128.zvalue(); - intersection->target = v; - v->edges = e; + Point64 n0 = intersection->face->getNormal(); + Point64 n1 = intersection->reverse->face->getNormal(); + int64_t m00 = face->dir0.dot(n0); + int64_t m01 = face->dir1.dot(n0); + int64_t m10 = face->dir0.dot(n1); + int64_t m11 = face->dir1.dot(n1); + int64_t r0 = (intersection->face->origin - shiftedOrigin).dot(n0); + int64_t r1 = (intersection->reverse->face->origin - shiftedOrigin).dot(n1); + Int128 det = Int128::mul(m00, m11) - Int128::mul(m01, m10); + btAssert(det.getSign() != 0); + Vertex* v = vertexPool.newObject(); + v->point.index = -1; + v->copy = -1; + v->point128 = PointR128(Int128::mul(face->dir0.x * r0, m11) - Int128::mul(face->dir0.x * r1, m01) + Int128::mul(face->dir1.x * r1, m00) - Int128::mul(face->dir1.x * r0, m10) + det * shiftedOrigin.x, + Int128::mul(face->dir0.y * r0, m11) - Int128::mul(face->dir0.y * r1, m01) + Int128::mul(face->dir1.y * r1, m00) - Int128::mul(face->dir1.y * r0, m10) + det * shiftedOrigin.y, + Int128::mul(face->dir0.z * r0, m11) - Int128::mul(face->dir0.z * r1, m01) + Int128::mul(face->dir1.z * r1, m00) - Int128::mul(face->dir1.z * r0, m10) + det * shiftedOrigin.z, + det); + v->point.x = (int32_t)v->point128.xvalue(); + v->point.y = (int32_t)v->point128.yvalue(); + v->point.z = (int32_t)v->point128.zvalue(); + intersection->target = v; + v->edges = e; - stack.push_back(v); - stack.push_back(removed); - stack.push_back(NULL); - } + stack.push_back(v); + stack.push_back(removed); + stack.push_back(NULL); + } - if (cmp || prevCmp || (prevIntersection->reverse->next->target != intersection->target)) { - faceEdge = newEdgePair(prevIntersection->target, intersection->target); - if (prevCmp == 0) { - faceEdge->link(prevIntersection->reverse->next); - } - if ((prevCmp == 0) || prevFaceEdge) { - prevIntersection->reverse->link(faceEdge); - } - if (cmp == 0) { - intersection->reverse->prev->link(faceEdge->reverse); - } - faceEdge->reverse->link(intersection->reverse); - } - else { - faceEdge = prevIntersection->reverse->next; - } + if (cmp || prevCmp || (prevIntersection->reverse->next->target != intersection->target)) + { + faceEdge = newEdgePair(prevIntersection->target, intersection->target); + if (prevCmp == 0) + { + faceEdge->link(prevIntersection->reverse->next); + } + if ((prevCmp == 0) || prevFaceEdge) + { + prevIntersection->reverse->link(faceEdge); + } + if (cmp == 0) + { + intersection->reverse->prev->link(faceEdge->reverse); + } + faceEdge->reverse->link(intersection->reverse); + } + else + { + faceEdge = prevIntersection->reverse->next; + } - if (prevFaceEdge) { - if (prevCmp > 0) { - faceEdge->link(prevFaceEdge->reverse); - } - else if (faceEdge != prevFaceEdge->reverse) { - stack.push_back(prevFaceEdge->target); - while (faceEdge->next != prevFaceEdge->reverse) { - Vertex* removed = faceEdge->next->target; - removeEdgePair(faceEdge->next); - stack.push_back(removed); + if (prevFaceEdge) + { + if (prevCmp > 0) + { + faceEdge->link(prevFaceEdge->reverse); + } + else if (faceEdge != prevFaceEdge->reverse) + { + stack.push_back(prevFaceEdge->target); + while (faceEdge->next != prevFaceEdge->reverse) + { + Vertex* removed = faceEdge->next->target; + removeEdgePair(faceEdge->next); + stack.push_back(removed); #ifdef DEBUG_CONVEX_HULL - printf("2: Removed part contains (%d %d %d)\n", removed->point.x, removed->point.y, removed->point.z); + printf("2: Removed part contains (%d %d %d)\n", removed->point.x, removed->point.y, removed->point.z); #endif - } - stack.push_back(NULL); - } - } - faceEdge->face = face; - faceEdge->reverse->face = intersection->face; + } + stack.push_back(NULL); + } + } + faceEdge->face = face; + faceEdge->reverse->face = intersection->face; - if (!firstFaceEdge) { - firstFaceEdge = faceEdge; - } - } + if (!firstFaceEdge) + { + firstFaceEdge = faceEdge; + } + } #ifdef SHOW_ITERATIONS - printf("Needed %d iterations to process all intersections\n", m); + printf("Needed %d iterations to process all intersections\n", m); #endif - if (cmp > 0) { - firstFaceEdge->reverse->target = faceEdge->target; - firstIntersection->reverse->link(firstFaceEdge); - firstFaceEdge->link(faceEdge->reverse); - } - else if (firstFaceEdge != faceEdge->reverse) { - stack.push_back(faceEdge->target); - while (firstFaceEdge->next != faceEdge->reverse) { - Vertex* removed = firstFaceEdge->next->target; - removeEdgePair(firstFaceEdge->next); - stack.push_back(removed); + if (cmp > 0) + { + firstFaceEdge->reverse->target = faceEdge->target; + firstIntersection->reverse->link(firstFaceEdge); + firstFaceEdge->link(faceEdge->reverse); + } + else if (firstFaceEdge != faceEdge->reverse) + { + stack.push_back(faceEdge->target); + while (firstFaceEdge->next != faceEdge->reverse) + { + Vertex* removed = firstFaceEdge->next->target; + removeEdgePair(firstFaceEdge->next); + stack.push_back(removed); #ifdef DEBUG_CONVEX_HULL - printf("3: Removed part contains (%d %d %d)\n", removed->point.x, removed->point.y, removed->point.z); + printf("3: Removed part contains (%d %d %d)\n", removed->point.x, removed->point.y, removed->point.z); #endif - } - stack.push_back(NULL); - } + } + stack.push_back(NULL); + } - btAssert(stack.size() > 0); - vertexList = stack[0]; + btAssert(stack.size() > 0); + vertexList = stack[0]; #ifdef DEBUG_CONVEX_HULL - printf("Removing part\n"); + printf("Removing part\n"); #endif #ifdef SHOW_ITERATIONS - n = 0; + n = 0; #endif - int pos = 0; - while (pos < stack.size()) { - int end = stack.size(); - while (pos < end) { - Vertex* kept = stack[pos++]; + int pos = 0; + while (pos < stack.size()) + { + int end = stack.size(); + while (pos < end) + { + Vertex* kept = stack[pos++]; #ifdef DEBUG_CONVEX_HULL - kept->print(); + kept->print(); #endif - bool deeper = false; - Vertex* removed; - while ((removed = stack[pos++]) != NULL) { + bool deeper = false; + Vertex* removed; + while ((removed = stack[pos++]) != NULL) + { #ifdef SHOW_ITERATIONS - n++; + n++; #endif - kept->receiveNearbyFaces(removed); - while (removed->edges) { - if (!deeper) { - deeper = true; - stack.push_back(kept); - } - stack.push_back(removed->edges->target); - removeEdgePair(removed->edges); - } - } - if (deeper) { - stack.push_back(NULL); - } - } - } + kept->receiveNearbyFaces(removed); + while (removed->edges) + { + if (!deeper) + { + deeper = true; + stack.push_back(kept); + } + stack.push_back(removed->edges->target); + removeEdgePair(removed->edges); + } + } + if (deeper) + { + stack.push_back(NULL); + } + } + } #ifdef SHOW_ITERATIONS - printf("Needed %d iterations to remove part\n", n); + printf("Needed %d iterations to remove part\n", n); #endif - stack.resize(0); - face->origin = shiftedOrigin; + stack.resize(0); + face->origin = shiftedOrigin; - return true; + return true; } static int getVertexCopy(btConvexHullInternal::Vertex* vertex, btAlignedObjectArray& vertices) { - int index = vertex->copy; - if (index < 0) { - index = vertices.size(); - vertex->copy = index; - vertices.push_back(vertex); + int index = vertex->copy; + if (index < 0) + { + index = vertices.size(); + vertex->copy = index; + vertices.push_back(vertex); #ifdef DEBUG_CONVEX_HULL - printf("Vertex %d gets index *%d\n", vertex->point.index, index); + printf("Vertex %d gets index *%d\n", vertex->point.index, index); #endif - } - return index; + } + return index; } btScalar btConvexHullComputer::compute(const void* coords, bool doubleCoords, int stride, int count, btScalar shrink, btScalar shrinkClamp) { - if (count <= 0) { - vertices.clear(); - edges.clear(); - faces.clear(); - return 0; - } + if (count <= 0) + { + vertices.clear(); + edges.clear(); + faces.clear(); + return 0; + } - btConvexHullInternal hull; - hull.compute(coords, doubleCoords, stride, count); + btConvexHullInternal hull; + hull.compute(coords, doubleCoords, stride, count); - btScalar shift = 0; - if ((shrink > 0) && ((shift = hull.shrink(shrink, shrinkClamp)) < 0)) { - vertices.clear(); - edges.clear(); - faces.clear(); - return shift; - } + btScalar shift = 0; + if ((shrink > 0) && ((shift = hull.shrink(shrink, shrinkClamp)) < 0)) + { + vertices.clear(); + edges.clear(); + faces.clear(); + return shift; + } - vertices.resize(0); - edges.resize(0); - faces.resize(0); + vertices.resize(0); + edges.resize(0); + faces.resize(0); - btAlignedObjectArray oldVertices; - getVertexCopy(hull.vertexList, oldVertices); - int copied = 0; - while (copied < oldVertices.size()) { - btConvexHullInternal::Vertex* v = oldVertices[copied]; - vertices.push_back(hull.getCoordinates(v)); - btConvexHullInternal::Edge* firstEdge = v->edges; - if (firstEdge) { - int firstCopy = -1; - int prevCopy = -1; - btConvexHullInternal::Edge* e = firstEdge; - do { - if (e->copy < 0) { - int s = edges.size(); - edges.push_back(Edge()); - edges.push_back(Edge()); - Edge* c = &edges[s]; - Edge* r = &edges[s + 1]; - e->copy = s; - e->reverse->copy = s + 1; - c->reverse = 1; - r->reverse = -1; - c->targetVertex = getVertexCopy(e->target, oldVertices); - r->targetVertex = copied; + btAlignedObjectArray oldVertices; + getVertexCopy(hull.vertexList, oldVertices); + int copied = 0; + while (copied < oldVertices.size()) + { + btConvexHullInternal::Vertex* v = oldVertices[copied]; + vertices.push_back(hull.getCoordinates(v)); + btConvexHullInternal::Edge* firstEdge = v->edges; + if (firstEdge) + { + int firstCopy = -1; + int prevCopy = -1; + btConvexHullInternal::Edge* e = firstEdge; + do + { + if (e->copy < 0) + { + int s = edges.size(); + edges.push_back(Edge()); + edges.push_back(Edge()); + Edge* c = &edges[s]; + Edge* r = &edges[s + 1]; + e->copy = s; + e->reverse->copy = s + 1; + c->reverse = 1; + r->reverse = -1; + c->targetVertex = getVertexCopy(e->target, oldVertices); + r->targetVertex = copied; #ifdef DEBUG_CONVEX_HULL - printf(" CREATE: Vertex *%d has edge to *%d\n", copied, c->getTargetVertex()); + printf(" CREATE: Vertex *%d has edge to *%d\n", copied, c->getTargetVertex()); #endif - } - if (prevCopy >= 0) { - edges[e->copy].next = prevCopy - e->copy; - } - else { - firstCopy = e->copy; - } - prevCopy = e->copy; - e = e->next; - } while (e != firstEdge); - edges[firstCopy].next = prevCopy - firstCopy; - } - copied++; - } + } + if (prevCopy >= 0) + { + edges[e->copy].next = prevCopy - e->copy; + } + else + { + firstCopy = e->copy; + } + prevCopy = e->copy; + e = e->next; + } while (e != firstEdge); + edges[firstCopy].next = prevCopy - firstCopy; + } + copied++; + } - for (int i = 0; i < copied; i++) { - btConvexHullInternal::Vertex* v = oldVertices[i]; - btConvexHullInternal::Edge* firstEdge = v->edges; - if (firstEdge) { - btConvexHullInternal::Edge* e = firstEdge; - do { - if (e->copy >= 0) { + for (int i = 0; i < copied; i++) + { + btConvexHullInternal::Vertex* v = oldVertices[i]; + btConvexHullInternal::Edge* firstEdge = v->edges; + if (firstEdge) + { + btConvexHullInternal::Edge* e = firstEdge; + do + { + if (e->copy >= 0) + { #ifdef DEBUG_CONVEX_HULL - printf("Vertex *%d has edge to *%d\n", i, edges[e->copy].getTargetVertex()); + printf("Vertex *%d has edge to *%d\n", i, edges[e->copy].getTargetVertex()); #endif - faces.push_back(e->copy); - btConvexHullInternal::Edge* f = e; - do { + faces.push_back(e->copy); + btConvexHullInternal::Edge* f = e; + do + { #ifdef DEBUG_CONVEX_HULL - printf(" Face *%d\n", edges[f->copy].getTargetVertex()); + printf(" Face *%d\n", edges[f->copy].getTargetVertex()); #endif - f->copy = -1; - f = f->reverse->prev; - } while (f != e); - } - e = e->next; - } while (e != firstEdge); - } - } + f->copy = -1; + f = f->reverse->prev; + } while (f != e); + } + e = e->next; + } while (e != firstEdge); + } + } - return shift; + return shift; } diff --git a/Extras/VHACD/src/vhacdICHull.cpp b/Extras/VHACD/src/vhacdICHull.cpp index 4216f0599..eed3b784c 100644 --- a/Extras/VHACD/src/vhacdICHull.cpp +++ b/Extras/VHACD/src/vhacdICHull.cpp @@ -14,712 +14,811 @@ */ #include "vhacdICHull.h" #include -namespace VHACD { +namespace VHACD +{ const double ICHull::sc_eps = 1.0e-15; const int ICHull::sc_dummyIndex = std::numeric_limits::max(); ICHull::ICHull() { - m_isFlat = false; + m_isFlat = false; } bool ICHull::AddPoints(const Vec3* points, size_t nPoints) { - if (!points) { - return false; - } - CircularListElement* vertex = NULL; - for (size_t i = 0; i < nPoints; i++) { - vertex = m_mesh.AddVertex(); - vertex->GetData().m_pos.X() = points[i].X(); - vertex->GetData().m_pos.Y() = points[i].Y(); - vertex->GetData().m_pos.Z() = points[i].Z(); - vertex->GetData().m_name = static_cast(i); - } - return true; + if (!points) + { + return false; + } + CircularListElement* vertex = NULL; + for (size_t i = 0; i < nPoints; i++) + { + vertex = m_mesh.AddVertex(); + vertex->GetData().m_pos.X() = points[i].X(); + vertex->GetData().m_pos.Y() = points[i].Y(); + vertex->GetData().m_pos.Z() = points[i].Z(); + vertex->GetData().m_name = static_cast(i); + } + return true; } bool ICHull::AddPoint(const Vec3& point, int id) { - if (AddPoints(&point, 1)) { - m_mesh.m_vertices.GetData().m_name = id; - return true; - } - return false; + if (AddPoints(&point, 1)) + { + m_mesh.m_vertices.GetData().m_name = id; + return true; + } + return false; } ICHullError ICHull::Process() { - unsigned int addedPoints = 0; - if (m_mesh.GetNVertices() < 3) { - return ICHullErrorNotEnoughPoints; - } - if (m_mesh.GetNVertices() == 3) { - m_isFlat = true; - CircularListElement* t1 = m_mesh.AddTriangle(); - CircularListElement* t2 = m_mesh.AddTriangle(); - CircularListElement* v0 = m_mesh.m_vertices.GetHead(); - CircularListElement* v1 = v0->GetNext(); - CircularListElement* v2 = v1->GetNext(); - // Compute the normal to the plane - Vec3 p0 = v0->GetData().m_pos; - Vec3 p1 = v1->GetData().m_pos; - Vec3 p2 = v2->GetData().m_pos; - m_normal = (p1 - p0) ^ (p2 - p0); - m_normal.Normalize(); - t1->GetData().m_vertices[0] = v0; - t1->GetData().m_vertices[1] = v1; - t1->GetData().m_vertices[2] = v2; - t2->GetData().m_vertices[0] = v1; - t2->GetData().m_vertices[1] = v2; - t2->GetData().m_vertices[2] = v2; - return ICHullErrorOK; - } - if (m_isFlat) { - m_mesh.m_edges.Clear(); - m_mesh.m_triangles.Clear(); - m_isFlat = false; - } - if (m_mesh.GetNTriangles() == 0) // we have to create the first polyhedron - { - ICHullError res = DoubleTriangle(); - if (res != ICHullErrorOK) { - return res; - } - else { - addedPoints += 3; - } - } - CircularList& vertices = m_mesh.GetVertices(); - // go to the first added and not processed vertex - while (!(vertices.GetHead()->GetPrev()->GetData().m_tag)) { - vertices.Prev(); - } - while (!vertices.GetData().m_tag) // not processed - { - vertices.GetData().m_tag = true; - if (ProcessPoint()) { - addedPoints++; - CleanUp(addedPoints); - vertices.Next(); - if (!GetMesh().CheckConsistancy()) { - size_t nV = m_mesh.GetNVertices(); - CircularList& vertices = m_mesh.GetVertices(); - for (size_t v = 0; v < nV; ++v) { - if (vertices.GetData().m_name == sc_dummyIndex) { - vertices.Delete(); - break; - } - vertices.Next(); - } - return ICHullErrorInconsistent; - } - } - } - if (m_isFlat) { - SArray*> trianglesToDuplicate; - size_t nT = m_mesh.GetNTriangles(); - for (size_t f = 0; f < nT; f++) { - TMMTriangle& currentTriangle = m_mesh.m_triangles.GetHead()->GetData(); - if (currentTriangle.m_vertices[0]->GetData().m_name == sc_dummyIndex || currentTriangle.m_vertices[1]->GetData().m_name == sc_dummyIndex || currentTriangle.m_vertices[2]->GetData().m_name == sc_dummyIndex) { - m_trianglesToDelete.PushBack(m_mesh.m_triangles.GetHead()); - for (int k = 0; k < 3; k++) { - for (int h = 0; h < 2; h++) { - if (currentTriangle.m_edges[k]->GetData().m_triangles[h] == m_mesh.m_triangles.GetHead()) { - currentTriangle.m_edges[k]->GetData().m_triangles[h] = 0; - break; - } - } - } - } - else { - trianglesToDuplicate.PushBack(m_mesh.m_triangles.GetHead()); - } - m_mesh.m_triangles.Next(); - } - size_t nE = m_mesh.GetNEdges(); - for (size_t e = 0; e < nE; e++) { - TMMEdge& currentEdge = m_mesh.m_edges.GetHead()->GetData(); - if (currentEdge.m_triangles[0] == 0 && currentEdge.m_triangles[1] == 0) { - m_edgesToDelete.PushBack(m_mesh.m_edges.GetHead()); - } - m_mesh.m_edges.Next(); - } - size_t nV = m_mesh.GetNVertices(); - CircularList& vertices = m_mesh.GetVertices(); - for (size_t v = 0; v < nV; ++v) { - if (vertices.GetData().m_name == sc_dummyIndex) { - vertices.Delete(); - } - else { - vertices.GetData().m_tag = false; - vertices.Next(); - } - } - CleanEdges(); - CleanTriangles(); - CircularListElement* newTriangle; - for (size_t t = 0; t < trianglesToDuplicate.Size(); t++) { - newTriangle = m_mesh.AddTriangle(); - newTriangle->GetData().m_vertices[0] = trianglesToDuplicate[t]->GetData().m_vertices[1]; - newTriangle->GetData().m_vertices[1] = trianglesToDuplicate[t]->GetData().m_vertices[0]; - newTriangle->GetData().m_vertices[2] = trianglesToDuplicate[t]->GetData().m_vertices[2]; - } - } - return ICHullErrorOK; + unsigned int addedPoints = 0; + if (m_mesh.GetNVertices() < 3) + { + return ICHullErrorNotEnoughPoints; + } + if (m_mesh.GetNVertices() == 3) + { + m_isFlat = true; + CircularListElement* t1 = m_mesh.AddTriangle(); + CircularListElement* t2 = m_mesh.AddTriangle(); + CircularListElement* v0 = m_mesh.m_vertices.GetHead(); + CircularListElement* v1 = v0->GetNext(); + CircularListElement* v2 = v1->GetNext(); + // Compute the normal to the plane + Vec3 p0 = v0->GetData().m_pos; + Vec3 p1 = v1->GetData().m_pos; + Vec3 p2 = v2->GetData().m_pos; + m_normal = (p1 - p0) ^ (p2 - p0); + m_normal.Normalize(); + t1->GetData().m_vertices[0] = v0; + t1->GetData().m_vertices[1] = v1; + t1->GetData().m_vertices[2] = v2; + t2->GetData().m_vertices[0] = v1; + t2->GetData().m_vertices[1] = v2; + t2->GetData().m_vertices[2] = v2; + return ICHullErrorOK; + } + if (m_isFlat) + { + m_mesh.m_edges.Clear(); + m_mesh.m_triangles.Clear(); + m_isFlat = false; + } + if (m_mesh.GetNTriangles() == 0) // we have to create the first polyhedron + { + ICHullError res = DoubleTriangle(); + if (res != ICHullErrorOK) + { + return res; + } + else + { + addedPoints += 3; + } + } + CircularList& vertices = m_mesh.GetVertices(); + // go to the first added and not processed vertex + while (!(vertices.GetHead()->GetPrev()->GetData().m_tag)) + { + vertices.Prev(); + } + while (!vertices.GetData().m_tag) // not processed + { + vertices.GetData().m_tag = true; + if (ProcessPoint()) + { + addedPoints++; + CleanUp(addedPoints); + vertices.Next(); + if (!GetMesh().CheckConsistancy()) + { + size_t nV = m_mesh.GetNVertices(); + CircularList& vertices = m_mesh.GetVertices(); + for (size_t v = 0; v < nV; ++v) + { + if (vertices.GetData().m_name == sc_dummyIndex) + { + vertices.Delete(); + break; + } + vertices.Next(); + } + return ICHullErrorInconsistent; + } + } + } + if (m_isFlat) + { + SArray*> trianglesToDuplicate; + size_t nT = m_mesh.GetNTriangles(); + for (size_t f = 0; f < nT; f++) + { + TMMTriangle& currentTriangle = m_mesh.m_triangles.GetHead()->GetData(); + if (currentTriangle.m_vertices[0]->GetData().m_name == sc_dummyIndex || currentTriangle.m_vertices[1]->GetData().m_name == sc_dummyIndex || currentTriangle.m_vertices[2]->GetData().m_name == sc_dummyIndex) + { + m_trianglesToDelete.PushBack(m_mesh.m_triangles.GetHead()); + for (int k = 0; k < 3; k++) + { + for (int h = 0; h < 2; h++) + { + if (currentTriangle.m_edges[k]->GetData().m_triangles[h] == m_mesh.m_triangles.GetHead()) + { + currentTriangle.m_edges[k]->GetData().m_triangles[h] = 0; + break; + } + } + } + } + else + { + trianglesToDuplicate.PushBack(m_mesh.m_triangles.GetHead()); + } + m_mesh.m_triangles.Next(); + } + size_t nE = m_mesh.GetNEdges(); + for (size_t e = 0; e < nE; e++) + { + TMMEdge& currentEdge = m_mesh.m_edges.GetHead()->GetData(); + if (currentEdge.m_triangles[0] == 0 && currentEdge.m_triangles[1] == 0) + { + m_edgesToDelete.PushBack(m_mesh.m_edges.GetHead()); + } + m_mesh.m_edges.Next(); + } + size_t nV = m_mesh.GetNVertices(); + CircularList& vertices = m_mesh.GetVertices(); + for (size_t v = 0; v < nV; ++v) + { + if (vertices.GetData().m_name == sc_dummyIndex) + { + vertices.Delete(); + } + else + { + vertices.GetData().m_tag = false; + vertices.Next(); + } + } + CleanEdges(); + CleanTriangles(); + CircularListElement* newTriangle; + for (size_t t = 0; t < trianglesToDuplicate.Size(); t++) + { + newTriangle = m_mesh.AddTriangle(); + newTriangle->GetData().m_vertices[0] = trianglesToDuplicate[t]->GetData().m_vertices[1]; + newTriangle->GetData().m_vertices[1] = trianglesToDuplicate[t]->GetData().m_vertices[0]; + newTriangle->GetData().m_vertices[2] = trianglesToDuplicate[t]->GetData().m_vertices[2]; + } + } + return ICHullErrorOK; } ICHullError ICHull::Process(const unsigned int nPointsCH, - const double minVolume) + const double minVolume) { - unsigned int addedPoints = 0; - if (nPointsCH < 3 || m_mesh.GetNVertices() < 3) { - return ICHullErrorNotEnoughPoints; - } - if (m_mesh.GetNVertices() == 3) { - m_isFlat = true; - CircularListElement* t1 = m_mesh.AddTriangle(); - CircularListElement* t2 = m_mesh.AddTriangle(); - CircularListElement* v0 = m_mesh.m_vertices.GetHead(); - CircularListElement* v1 = v0->GetNext(); - CircularListElement* v2 = v1->GetNext(); - // Compute the normal to the plane - Vec3 p0 = v0->GetData().m_pos; - Vec3 p1 = v1->GetData().m_pos; - Vec3 p2 = v2->GetData().m_pos; - m_normal = (p1 - p0) ^ (p2 - p0); - m_normal.Normalize(); - t1->GetData().m_vertices[0] = v0; - t1->GetData().m_vertices[1] = v1; - t1->GetData().m_vertices[2] = v2; - t2->GetData().m_vertices[0] = v1; - t2->GetData().m_vertices[1] = v0; - t2->GetData().m_vertices[2] = v2; - return ICHullErrorOK; - } + unsigned int addedPoints = 0; + if (nPointsCH < 3 || m_mesh.GetNVertices() < 3) + { + return ICHullErrorNotEnoughPoints; + } + if (m_mesh.GetNVertices() == 3) + { + m_isFlat = true; + CircularListElement* t1 = m_mesh.AddTriangle(); + CircularListElement* t2 = m_mesh.AddTriangle(); + CircularListElement* v0 = m_mesh.m_vertices.GetHead(); + CircularListElement* v1 = v0->GetNext(); + CircularListElement* v2 = v1->GetNext(); + // Compute the normal to the plane + Vec3 p0 = v0->GetData().m_pos; + Vec3 p1 = v1->GetData().m_pos; + Vec3 p2 = v2->GetData().m_pos; + m_normal = (p1 - p0) ^ (p2 - p0); + m_normal.Normalize(); + t1->GetData().m_vertices[0] = v0; + t1->GetData().m_vertices[1] = v1; + t1->GetData().m_vertices[2] = v2; + t2->GetData().m_vertices[0] = v1; + t2->GetData().m_vertices[1] = v0; + t2->GetData().m_vertices[2] = v2; + return ICHullErrorOK; + } - if (m_isFlat) { - m_mesh.m_triangles.Clear(); - m_mesh.m_edges.Clear(); - m_isFlat = false; - } + if (m_isFlat) + { + m_mesh.m_triangles.Clear(); + m_mesh.m_edges.Clear(); + m_isFlat = false; + } - if (m_mesh.GetNTriangles() == 0) // we have to create the first polyhedron - { - ICHullError res = DoubleTriangle(); - if (res != ICHullErrorOK) { - return res; - } - else { - addedPoints += 3; - } - } - CircularList& vertices = m_mesh.GetVertices(); - while (!vertices.GetData().m_tag && addedPoints < nPointsCH) // not processed - { - if (!FindMaxVolumePoint((addedPoints > 4) ? minVolume : 0.0)) { - break; - } - vertices.GetData().m_tag = true; - if (ProcessPoint()) { - addedPoints++; - CleanUp(addedPoints); - if (!GetMesh().CheckConsistancy()) { - size_t nV = m_mesh.GetNVertices(); - CircularList& vertices = m_mesh.GetVertices(); - for (size_t v = 0; v < nV; ++v) { - if (vertices.GetData().m_name == sc_dummyIndex) { - vertices.Delete(); - break; - } - vertices.Next(); - } - return ICHullErrorInconsistent; - } - vertices.Next(); - } - } - // delete remaining points - while (!vertices.GetData().m_tag) { - vertices.Delete(); - } - if (m_isFlat) { - SArray*> trianglesToDuplicate; - size_t nT = m_mesh.GetNTriangles(); - for (size_t f = 0; f < nT; f++) { - TMMTriangle& currentTriangle = m_mesh.m_triangles.GetHead()->GetData(); - if (currentTriangle.m_vertices[0]->GetData().m_name == sc_dummyIndex || currentTriangle.m_vertices[1]->GetData().m_name == sc_dummyIndex || currentTriangle.m_vertices[2]->GetData().m_name == sc_dummyIndex) { - m_trianglesToDelete.PushBack(m_mesh.m_triangles.GetHead()); - for (int k = 0; k < 3; k++) { - for (int h = 0; h < 2; h++) { - if (currentTriangle.m_edges[k]->GetData().m_triangles[h] == m_mesh.m_triangles.GetHead()) { - currentTriangle.m_edges[k]->GetData().m_triangles[h] = 0; - break; - } - } - } - } - else { - trianglesToDuplicate.PushBack(m_mesh.m_triangles.GetHead()); - } - m_mesh.m_triangles.Next(); - } - size_t nE = m_mesh.GetNEdges(); - for (size_t e = 0; e < nE; e++) { - TMMEdge& currentEdge = m_mesh.m_edges.GetHead()->GetData(); - if (currentEdge.m_triangles[0] == 0 && currentEdge.m_triangles[1] == 0) { - m_edgesToDelete.PushBack(m_mesh.m_edges.GetHead()); - } - m_mesh.m_edges.Next(); - } - size_t nV = m_mesh.GetNVertices(); - CircularList& vertices = m_mesh.GetVertices(); - for (size_t v = 0; v < nV; ++v) { - if (vertices.GetData().m_name == sc_dummyIndex) { - vertices.Delete(); - } - else { - vertices.GetData().m_tag = false; - vertices.Next(); - } - } - CleanEdges(); - CleanTriangles(); - CircularListElement* newTriangle; - for (size_t t = 0; t < trianglesToDuplicate.Size(); t++) { - newTriangle = m_mesh.AddTriangle(); - newTriangle->GetData().m_vertices[0] = trianglesToDuplicate[t]->GetData().m_vertices[1]; - newTriangle->GetData().m_vertices[1] = trianglesToDuplicate[t]->GetData().m_vertices[0]; - newTriangle->GetData().m_vertices[2] = trianglesToDuplicate[t]->GetData().m_vertices[2]; - } - } - return ICHullErrorOK; + if (m_mesh.GetNTriangles() == 0) // we have to create the first polyhedron + { + ICHullError res = DoubleTriangle(); + if (res != ICHullErrorOK) + { + return res; + } + else + { + addedPoints += 3; + } + } + CircularList& vertices = m_mesh.GetVertices(); + while (!vertices.GetData().m_tag && addedPoints < nPointsCH) // not processed + { + if (!FindMaxVolumePoint((addedPoints > 4) ? minVolume : 0.0)) + { + break; + } + vertices.GetData().m_tag = true; + if (ProcessPoint()) + { + addedPoints++; + CleanUp(addedPoints); + if (!GetMesh().CheckConsistancy()) + { + size_t nV = m_mesh.GetNVertices(); + CircularList& vertices = m_mesh.GetVertices(); + for (size_t v = 0; v < nV; ++v) + { + if (vertices.GetData().m_name == sc_dummyIndex) + { + vertices.Delete(); + break; + } + vertices.Next(); + } + return ICHullErrorInconsistent; + } + vertices.Next(); + } + } + // delete remaining points + while (!vertices.GetData().m_tag) + { + vertices.Delete(); + } + if (m_isFlat) + { + SArray*> trianglesToDuplicate; + size_t nT = m_mesh.GetNTriangles(); + for (size_t f = 0; f < nT; f++) + { + TMMTriangle& currentTriangle = m_mesh.m_triangles.GetHead()->GetData(); + if (currentTriangle.m_vertices[0]->GetData().m_name == sc_dummyIndex || currentTriangle.m_vertices[1]->GetData().m_name == sc_dummyIndex || currentTriangle.m_vertices[2]->GetData().m_name == sc_dummyIndex) + { + m_trianglesToDelete.PushBack(m_mesh.m_triangles.GetHead()); + for (int k = 0; k < 3; k++) + { + for (int h = 0; h < 2; h++) + { + if (currentTriangle.m_edges[k]->GetData().m_triangles[h] == m_mesh.m_triangles.GetHead()) + { + currentTriangle.m_edges[k]->GetData().m_triangles[h] = 0; + break; + } + } + } + } + else + { + trianglesToDuplicate.PushBack(m_mesh.m_triangles.GetHead()); + } + m_mesh.m_triangles.Next(); + } + size_t nE = m_mesh.GetNEdges(); + for (size_t e = 0; e < nE; e++) + { + TMMEdge& currentEdge = m_mesh.m_edges.GetHead()->GetData(); + if (currentEdge.m_triangles[0] == 0 && currentEdge.m_triangles[1] == 0) + { + m_edgesToDelete.PushBack(m_mesh.m_edges.GetHead()); + } + m_mesh.m_edges.Next(); + } + size_t nV = m_mesh.GetNVertices(); + CircularList& vertices = m_mesh.GetVertices(); + for (size_t v = 0; v < nV; ++v) + { + if (vertices.GetData().m_name == sc_dummyIndex) + { + vertices.Delete(); + } + else + { + vertices.GetData().m_tag = false; + vertices.Next(); + } + } + CleanEdges(); + CleanTriangles(); + CircularListElement* newTriangle; + for (size_t t = 0; t < trianglesToDuplicate.Size(); t++) + { + newTriangle = m_mesh.AddTriangle(); + newTriangle->GetData().m_vertices[0] = trianglesToDuplicate[t]->GetData().m_vertices[1]; + newTriangle->GetData().m_vertices[1] = trianglesToDuplicate[t]->GetData().m_vertices[0]; + newTriangle->GetData().m_vertices[2] = trianglesToDuplicate[t]->GetData().m_vertices[2]; + } + } + return ICHullErrorOK; } bool ICHull::FindMaxVolumePoint(const double minVolume) { - CircularList& vertices = m_mesh.GetVertices(); - CircularListElement* vMaxVolume = 0; - CircularListElement* vHeadPrev = vertices.GetHead()->GetPrev(); + CircularList& vertices = m_mesh.GetVertices(); + CircularListElement* vMaxVolume = 0; + CircularListElement* vHeadPrev = vertices.GetHead()->GetPrev(); - double maxVolume = minVolume; - double volume = 0.0; - while (!vertices.GetData().m_tag) // not processed - { - if (ComputePointVolume(volume, false)) { - if (maxVolume < volume) { - maxVolume = volume; - vMaxVolume = vertices.GetHead(); - } - vertices.Next(); - } - } - CircularListElement* vHead = vHeadPrev->GetNext(); - vertices.GetHead() = vHead; - if (!vMaxVolume) { - return false; - } - if (vMaxVolume != vHead) { - Vec3 pos = vHead->GetData().m_pos; - int id = vHead->GetData().m_name; - vHead->GetData().m_pos = vMaxVolume->GetData().m_pos; - vHead->GetData().m_name = vMaxVolume->GetData().m_name; - vMaxVolume->GetData().m_pos = pos; - vHead->GetData().m_name = id; - } - return true; + double maxVolume = minVolume; + double volume = 0.0; + while (!vertices.GetData().m_tag) // not processed + { + if (ComputePointVolume(volume, false)) + { + if (maxVolume < volume) + { + maxVolume = volume; + vMaxVolume = vertices.GetHead(); + } + vertices.Next(); + } + } + CircularListElement* vHead = vHeadPrev->GetNext(); + vertices.GetHead() = vHead; + if (!vMaxVolume) + { + return false; + } + if (vMaxVolume != vHead) + { + Vec3 pos = vHead->GetData().m_pos; + int id = vHead->GetData().m_name; + vHead->GetData().m_pos = vMaxVolume->GetData().m_pos; + vHead->GetData().m_name = vMaxVolume->GetData().m_name; + vMaxVolume->GetData().m_pos = pos; + vHead->GetData().m_name = id; + } + return true; } ICHullError ICHull::DoubleTriangle() { - // find three non colinear points - m_isFlat = false; - CircularList& vertices = m_mesh.GetVertices(); - CircularListElement* v0 = vertices.GetHead(); - while (Colinear(v0->GetData().m_pos, - v0->GetNext()->GetData().m_pos, - v0->GetNext()->GetNext()->GetData().m_pos)) { - if ((v0 = v0->GetNext()) == vertices.GetHead()) { - return ICHullErrorCoplanarPoints; - } - } - CircularListElement* v1 = v0->GetNext(); - CircularListElement* v2 = v1->GetNext(); - // mark points as processed - v0->GetData().m_tag = v1->GetData().m_tag = v2->GetData().m_tag = true; + // find three non colinear points + m_isFlat = false; + CircularList& vertices = m_mesh.GetVertices(); + CircularListElement* v0 = vertices.GetHead(); + while (Colinear(v0->GetData().m_pos, + v0->GetNext()->GetData().m_pos, + v0->GetNext()->GetNext()->GetData().m_pos)) + { + if ((v0 = v0->GetNext()) == vertices.GetHead()) + { + return ICHullErrorCoplanarPoints; + } + } + CircularListElement* v1 = v0->GetNext(); + CircularListElement* v2 = v1->GetNext(); + // mark points as processed + v0->GetData().m_tag = v1->GetData().m_tag = v2->GetData().m_tag = true; - // create two triangles - CircularListElement* f0 = MakeFace(v0, v1, v2, 0); - MakeFace(v2, v1, v0, f0); + // create two triangles + CircularListElement* f0 = MakeFace(v0, v1, v2, 0); + MakeFace(v2, v1, v0, f0); - // find a fourth non-coplanar point to form tetrahedron - CircularListElement* v3 = v2->GetNext(); - vertices.GetHead() = v3; + // find a fourth non-coplanar point to form tetrahedron + CircularListElement* v3 = v2->GetNext(); + vertices.GetHead() = v3; - double vol = ComputeVolume4(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos); - while (fabs(vol) < sc_eps && !v3->GetNext()->GetData().m_tag) { - v3 = v3->GetNext(); - vol = ComputeVolume4(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos); - } - if (fabs(vol) < sc_eps) { - // compute the barycenter - Vec3 bary(0.0, 0.0, 0.0); - CircularListElement* vBary = v0; - do { - bary += vBary->GetData().m_pos; - } while ((vBary = vBary->GetNext()) != v0); - bary /= static_cast(vertices.GetSize()); + double vol = ComputeVolume4(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos); + while (fabs(vol) < sc_eps && !v3->GetNext()->GetData().m_tag) + { + v3 = v3->GetNext(); + vol = ComputeVolume4(v0->GetData().m_pos, v1->GetData().m_pos, v2->GetData().m_pos, v3->GetData().m_pos); + } + if (fabs(vol) < sc_eps) + { + // compute the barycenter + Vec3 bary(0.0, 0.0, 0.0); + CircularListElement* vBary = v0; + do + { + bary += vBary->GetData().m_pos; + } while ((vBary = vBary->GetNext()) != v0); + bary /= static_cast(vertices.GetSize()); - // Compute the normal to the plane - Vec3 p0 = v0->GetData().m_pos; - Vec3 p1 = v1->GetData().m_pos; - Vec3 p2 = v2->GetData().m_pos; - m_normal = (p1 - p0) ^ (p2 - p0); - m_normal.Normalize(); - // add dummy vertex placed at (bary + normal) - vertices.GetHead() = v2; - Vec3 newPt = bary + m_normal; - AddPoint(newPt, sc_dummyIndex); - m_isFlat = true; - return ICHullErrorOK; - } - else if (v3 != vertices.GetHead()) { - TMMVertex temp; - temp.m_name = v3->GetData().m_name; - temp.m_pos = v3->GetData().m_pos; - v3->GetData().m_name = vertices.GetHead()->GetData().m_name; - v3->GetData().m_pos = vertices.GetHead()->GetData().m_pos; - vertices.GetHead()->GetData().m_name = temp.m_name; - vertices.GetHead()->GetData().m_pos = temp.m_pos; - } - return ICHullErrorOK; + // Compute the normal to the plane + Vec3 p0 = v0->GetData().m_pos; + Vec3 p1 = v1->GetData().m_pos; + Vec3 p2 = v2->GetData().m_pos; + m_normal = (p1 - p0) ^ (p2 - p0); + m_normal.Normalize(); + // add dummy vertex placed at (bary + normal) + vertices.GetHead() = v2; + Vec3 newPt = bary + m_normal; + AddPoint(newPt, sc_dummyIndex); + m_isFlat = true; + return ICHullErrorOK; + } + else if (v3 != vertices.GetHead()) + { + TMMVertex temp; + temp.m_name = v3->GetData().m_name; + temp.m_pos = v3->GetData().m_pos; + v3->GetData().m_name = vertices.GetHead()->GetData().m_name; + v3->GetData().m_pos = vertices.GetHead()->GetData().m_pos; + vertices.GetHead()->GetData().m_name = temp.m_name; + vertices.GetHead()->GetData().m_pos = temp.m_pos; + } + return ICHullErrorOK; } CircularListElement* ICHull::MakeFace(CircularListElement* v0, - CircularListElement* v1, - CircularListElement* v2, - CircularListElement* fold) + CircularListElement* v1, + CircularListElement* v2, + CircularListElement* fold) { - CircularListElement* e0; - CircularListElement* e1; - CircularListElement* e2; - int index = 0; - if (!fold) // if first face to be created - { - e0 = m_mesh.AddEdge(); // create the three edges - e1 = m_mesh.AddEdge(); - e2 = m_mesh.AddEdge(); - } - else // otherwise re-use existing edges (in reverse order) - { - e0 = fold->GetData().m_edges[2]; - e1 = fold->GetData().m_edges[1]; - e2 = fold->GetData().m_edges[0]; - index = 1; - } - e0->GetData().m_vertices[0] = v0; - e0->GetData().m_vertices[1] = v1; - e1->GetData().m_vertices[0] = v1; - e1->GetData().m_vertices[1] = v2; - e2->GetData().m_vertices[0] = v2; - e2->GetData().m_vertices[1] = v0; - // create the new face - CircularListElement* f = m_mesh.AddTriangle(); - f->GetData().m_edges[0] = e0; - f->GetData().m_edges[1] = e1; - f->GetData().m_edges[2] = e2; - f->GetData().m_vertices[0] = v0; - f->GetData().m_vertices[1] = v1; - f->GetData().m_vertices[2] = v2; - // link edges to face f - e0->GetData().m_triangles[index] = e1->GetData().m_triangles[index] = e2->GetData().m_triangles[index] = f; - return f; + CircularListElement* e0; + CircularListElement* e1; + CircularListElement* e2; + int index = 0; + if (!fold) // if first face to be created + { + e0 = m_mesh.AddEdge(); // create the three edges + e1 = m_mesh.AddEdge(); + e2 = m_mesh.AddEdge(); + } + else // otherwise re-use existing edges (in reverse order) + { + e0 = fold->GetData().m_edges[2]; + e1 = fold->GetData().m_edges[1]; + e2 = fold->GetData().m_edges[0]; + index = 1; + } + e0->GetData().m_vertices[0] = v0; + e0->GetData().m_vertices[1] = v1; + e1->GetData().m_vertices[0] = v1; + e1->GetData().m_vertices[1] = v2; + e2->GetData().m_vertices[0] = v2; + e2->GetData().m_vertices[1] = v0; + // create the new face + CircularListElement* f = m_mesh.AddTriangle(); + f->GetData().m_edges[0] = e0; + f->GetData().m_edges[1] = e1; + f->GetData().m_edges[2] = e2; + f->GetData().m_vertices[0] = v0; + f->GetData().m_vertices[1] = v1; + f->GetData().m_vertices[2] = v2; + // link edges to face f + e0->GetData().m_triangles[index] = e1->GetData().m_triangles[index] = e2->GetData().m_triangles[index] = f; + return f; } CircularListElement* ICHull::MakeConeFace(CircularListElement* e, CircularListElement* p) { - // create two new edges if they don't already exist - CircularListElement* newEdges[2]; - for (int i = 0; i < 2; ++i) { - if (!(newEdges[i] = e->GetData().m_vertices[i]->GetData().m_duplicate)) { // if the edge doesn't exits add it and mark the vertex as duplicated - newEdges[i] = m_mesh.AddEdge(); - newEdges[i]->GetData().m_vertices[0] = e->GetData().m_vertices[i]; - newEdges[i]->GetData().m_vertices[1] = p; - e->GetData().m_vertices[i]->GetData().m_duplicate = newEdges[i]; - } - } - // make the new face - CircularListElement* newFace = m_mesh.AddTriangle(); - newFace->GetData().m_edges[0] = e; - newFace->GetData().m_edges[1] = newEdges[0]; - newFace->GetData().m_edges[2] = newEdges[1]; - MakeCCW(newFace, e, p); - for (int i = 0; i < 2; ++i) { - for (int j = 0; j < 2; ++j) { - if (!newEdges[i]->GetData().m_triangles[j]) { - newEdges[i]->GetData().m_triangles[j] = newFace; - break; - } - } - } - return newFace; + // create two new edges if they don't already exist + CircularListElement* newEdges[2]; + for (int i = 0; i < 2; ++i) + { + if (!(newEdges[i] = e->GetData().m_vertices[i]->GetData().m_duplicate)) + { // if the edge doesn't exits add it and mark the vertex as duplicated + newEdges[i] = m_mesh.AddEdge(); + newEdges[i]->GetData().m_vertices[0] = e->GetData().m_vertices[i]; + newEdges[i]->GetData().m_vertices[1] = p; + e->GetData().m_vertices[i]->GetData().m_duplicate = newEdges[i]; + } + } + // make the new face + CircularListElement* newFace = m_mesh.AddTriangle(); + newFace->GetData().m_edges[0] = e; + newFace->GetData().m_edges[1] = newEdges[0]; + newFace->GetData().m_edges[2] = newEdges[1]; + MakeCCW(newFace, e, p); + for (int i = 0; i < 2; ++i) + { + for (int j = 0; j < 2; ++j) + { + if (!newEdges[i]->GetData().m_triangles[j]) + { + newEdges[i]->GetData().m_triangles[j] = newFace; + break; + } + } + } + return newFace; } bool ICHull::ComputePointVolume(double& totalVolume, bool markVisibleFaces) { - // mark visible faces - CircularListElement* fHead = m_mesh.GetTriangles().GetHead(); - CircularListElement* f = fHead; - CircularList& vertices = m_mesh.GetVertices(); - CircularListElement* vertex0 = vertices.GetHead(); - bool visible = false; - Vec3 pos0 = Vec3(vertex0->GetData().m_pos.X(), - vertex0->GetData().m_pos.Y(), - vertex0->GetData().m_pos.Z()); - double vol = 0.0; - totalVolume = 0.0; - Vec3 ver0, ver1, ver2; - do { - ver0.X() = f->GetData().m_vertices[0]->GetData().m_pos.X(); - ver0.Y() = f->GetData().m_vertices[0]->GetData().m_pos.Y(); - ver0.Z() = f->GetData().m_vertices[0]->GetData().m_pos.Z(); - ver1.X() = f->GetData().m_vertices[1]->GetData().m_pos.X(); - ver1.Y() = f->GetData().m_vertices[1]->GetData().m_pos.Y(); - ver1.Z() = f->GetData().m_vertices[1]->GetData().m_pos.Z(); - ver2.X() = f->GetData().m_vertices[2]->GetData().m_pos.X(); - ver2.Y() = f->GetData().m_vertices[2]->GetData().m_pos.Y(); - ver2.Z() = f->GetData().m_vertices[2]->GetData().m_pos.Z(); - vol = ComputeVolume4(ver0, ver1, ver2, pos0); - if (vol < -sc_eps) { - vol = fabs(vol); - totalVolume += vol; - if (markVisibleFaces) { - f->GetData().m_visible = true; - m_trianglesToDelete.PushBack(f); - } - visible = true; - } - f = f->GetNext(); - } while (f != fHead); + // mark visible faces + CircularListElement* fHead = m_mesh.GetTriangles().GetHead(); + CircularListElement* f = fHead; + CircularList& vertices = m_mesh.GetVertices(); + CircularListElement* vertex0 = vertices.GetHead(); + bool visible = false; + Vec3 pos0 = Vec3(vertex0->GetData().m_pos.X(), + vertex0->GetData().m_pos.Y(), + vertex0->GetData().m_pos.Z()); + double vol = 0.0; + totalVolume = 0.0; + Vec3 ver0, ver1, ver2; + do + { + ver0.X() = f->GetData().m_vertices[0]->GetData().m_pos.X(); + ver0.Y() = f->GetData().m_vertices[0]->GetData().m_pos.Y(); + ver0.Z() = f->GetData().m_vertices[0]->GetData().m_pos.Z(); + ver1.X() = f->GetData().m_vertices[1]->GetData().m_pos.X(); + ver1.Y() = f->GetData().m_vertices[1]->GetData().m_pos.Y(); + ver1.Z() = f->GetData().m_vertices[1]->GetData().m_pos.Z(); + ver2.X() = f->GetData().m_vertices[2]->GetData().m_pos.X(); + ver2.Y() = f->GetData().m_vertices[2]->GetData().m_pos.Y(); + ver2.Z() = f->GetData().m_vertices[2]->GetData().m_pos.Z(); + vol = ComputeVolume4(ver0, ver1, ver2, pos0); + if (vol < -sc_eps) + { + vol = fabs(vol); + totalVolume += vol; + if (markVisibleFaces) + { + f->GetData().m_visible = true; + m_trianglesToDelete.PushBack(f); + } + visible = true; + } + f = f->GetNext(); + } while (f != fHead); - if (m_trianglesToDelete.Size() == m_mesh.m_triangles.GetSize()) { - for (size_t i = 0; i < m_trianglesToDelete.Size(); i++) { - m_trianglesToDelete[i]->GetData().m_visible = false; - } - visible = false; - } - // if no faces visible from p then p is inside the hull - if (!visible && markVisibleFaces) { - vertices.Delete(); - m_trianglesToDelete.Resize(0); - return false; - } - return true; + if (m_trianglesToDelete.Size() == m_mesh.m_triangles.GetSize()) + { + for (size_t i = 0; i < m_trianglesToDelete.Size(); i++) + { + m_trianglesToDelete[i]->GetData().m_visible = false; + } + visible = false; + } + // if no faces visible from p then p is inside the hull + if (!visible && markVisibleFaces) + { + vertices.Delete(); + m_trianglesToDelete.Resize(0); + return false; + } + return true; } bool ICHull::ProcessPoint() { - double totalVolume = 0.0; - if (!ComputePointVolume(totalVolume, true)) { - return false; - } - // Mark edges in interior of visible region for deletion. - // Create a new face based on each border edge - CircularListElement* v0 = m_mesh.GetVertices().GetHead(); - CircularListElement* eHead = m_mesh.GetEdges().GetHead(); - CircularListElement* e = eHead; - CircularListElement* tmp = 0; - int nvisible = 0; - m_edgesToDelete.Resize(0); - m_edgesToUpdate.Resize(0); - do { - tmp = e->GetNext(); - nvisible = 0; - for (int k = 0; k < 2; k++) { - if (e->GetData().m_triangles[k]->GetData().m_visible) { - nvisible++; - } - } - if (nvisible == 2) { - m_edgesToDelete.PushBack(e); - } - else if (nvisible == 1) { - e->GetData().m_newFace = MakeConeFace(e, v0); - m_edgesToUpdate.PushBack(e); - } - e = tmp; - } while (e != eHead); - return true; + double totalVolume = 0.0; + if (!ComputePointVolume(totalVolume, true)) + { + return false; + } + // Mark edges in interior of visible region for deletion. + // Create a new face based on each border edge + CircularListElement* v0 = m_mesh.GetVertices().GetHead(); + CircularListElement* eHead = m_mesh.GetEdges().GetHead(); + CircularListElement* e = eHead; + CircularListElement* tmp = 0; + int nvisible = 0; + m_edgesToDelete.Resize(0); + m_edgesToUpdate.Resize(0); + do + { + tmp = e->GetNext(); + nvisible = 0; + for (int k = 0; k < 2; k++) + { + if (e->GetData().m_triangles[k]->GetData().m_visible) + { + nvisible++; + } + } + if (nvisible == 2) + { + m_edgesToDelete.PushBack(e); + } + else if (nvisible == 1) + { + e->GetData().m_newFace = MakeConeFace(e, v0); + m_edgesToUpdate.PushBack(e); + } + e = tmp; + } while (e != eHead); + return true; } bool ICHull::MakeCCW(CircularListElement* f, - CircularListElement* e, - CircularListElement* v) + CircularListElement* e, + CircularListElement* v) { - // the visible face adjacent to e - CircularListElement* fv; - if (e->GetData().m_triangles[0]->GetData().m_visible) { - fv = e->GetData().m_triangles[0]; - } - else { - fv = e->GetData().m_triangles[1]; - } + // the visible face adjacent to e + CircularListElement* fv; + if (e->GetData().m_triangles[0]->GetData().m_visible) + { + fv = e->GetData().m_triangles[0]; + } + else + { + fv = e->GetData().m_triangles[1]; + } - // set vertex[0] and vertex[1] to have the same orientation as the corresponding vertices of fv. - int i; // index of e->m_vertices[0] in fv - CircularListElement* v0 = e->GetData().m_vertices[0]; - CircularListElement* v1 = e->GetData().m_vertices[1]; - for (i = 0; fv->GetData().m_vertices[i] != v0; i++) - ; + // set vertex[0] and vertex[1] to have the same orientation as the corresponding vertices of fv. + int i; // index of e->m_vertices[0] in fv + CircularListElement* v0 = e->GetData().m_vertices[0]; + CircularListElement* v1 = e->GetData().m_vertices[1]; + for (i = 0; fv->GetData().m_vertices[i] != v0; i++) + ; - if (fv->GetData().m_vertices[(i + 1) % 3] != e->GetData().m_vertices[1]) { - f->GetData().m_vertices[0] = v1; - f->GetData().m_vertices[1] = v0; - } - else { - f->GetData().m_vertices[0] = v0; - f->GetData().m_vertices[1] = v1; - // swap edges - CircularListElement* tmp = f->GetData().m_edges[0]; - f->GetData().m_edges[0] = f->GetData().m_edges[1]; - f->GetData().m_edges[1] = tmp; - } - f->GetData().m_vertices[2] = v; - return true; + if (fv->GetData().m_vertices[(i + 1) % 3] != e->GetData().m_vertices[1]) + { + f->GetData().m_vertices[0] = v1; + f->GetData().m_vertices[1] = v0; + } + else + { + f->GetData().m_vertices[0] = v0; + f->GetData().m_vertices[1] = v1; + // swap edges + CircularListElement* tmp = f->GetData().m_edges[0]; + f->GetData().m_edges[0] = f->GetData().m_edges[1]; + f->GetData().m_edges[1] = tmp; + } + f->GetData().m_vertices[2] = v; + return true; } bool ICHull::CleanUp(unsigned int& addedPoints) { - bool r0 = CleanEdges(); - bool r1 = CleanTriangles(); - bool r2 = CleanVertices(addedPoints); - return r0 && r1 && r2; + bool r0 = CleanEdges(); + bool r1 = CleanTriangles(); + bool r2 = CleanVertices(addedPoints); + return r0 && r1 && r2; } bool ICHull::CleanEdges() { - // integrate the new faces into the data structure - CircularListElement* e; - const size_t ne_update = m_edgesToUpdate.Size(); - for (size_t i = 0; i < ne_update; ++i) { - e = m_edgesToUpdate[i]; - if (e->GetData().m_newFace) { - if (e->GetData().m_triangles[0]->GetData().m_visible) { - e->GetData().m_triangles[0] = e->GetData().m_newFace; - } - else { - e->GetData().m_triangles[1] = e->GetData().m_newFace; - } - e->GetData().m_newFace = 0; - } - } - // delete edges maked for deletion - CircularList& edges = m_mesh.GetEdges(); - const size_t ne_delete = m_edgesToDelete.Size(); - for (size_t i = 0; i < ne_delete; ++i) { - edges.Delete(m_edgesToDelete[i]); - } - m_edgesToDelete.Resize(0); - m_edgesToUpdate.Resize(0); - return true; + // integrate the new faces into the data structure + CircularListElement* e; + const size_t ne_update = m_edgesToUpdate.Size(); + for (size_t i = 0; i < ne_update; ++i) + { + e = m_edgesToUpdate[i]; + if (e->GetData().m_newFace) + { + if (e->GetData().m_triangles[0]->GetData().m_visible) + { + e->GetData().m_triangles[0] = e->GetData().m_newFace; + } + else + { + e->GetData().m_triangles[1] = e->GetData().m_newFace; + } + e->GetData().m_newFace = 0; + } + } + // delete edges maked for deletion + CircularList& edges = m_mesh.GetEdges(); + const size_t ne_delete = m_edgesToDelete.Size(); + for (size_t i = 0; i < ne_delete; ++i) + { + edges.Delete(m_edgesToDelete[i]); + } + m_edgesToDelete.Resize(0); + m_edgesToUpdate.Resize(0); + return true; } bool ICHull::CleanTriangles() { - CircularList& triangles = m_mesh.GetTriangles(); - const size_t nt_delete = m_trianglesToDelete.Size(); - for (size_t i = 0; i < nt_delete; ++i) { - triangles.Delete(m_trianglesToDelete[i]); - } - m_trianglesToDelete.Resize(0); - return true; + CircularList& triangles = m_mesh.GetTriangles(); + const size_t nt_delete = m_trianglesToDelete.Size(); + for (size_t i = 0; i < nt_delete; ++i) + { + triangles.Delete(m_trianglesToDelete[i]); + } + m_trianglesToDelete.Resize(0); + return true; } bool ICHull::CleanVertices(unsigned int& addedPoints) { - // mark all vertices incident to some undeleted edge as on the hull - CircularList& edges = m_mesh.GetEdges(); - CircularListElement* e = edges.GetHead(); - size_t nE = edges.GetSize(); - for (size_t i = 0; i < nE; i++) { - e->GetData().m_vertices[0]->GetData().m_onHull = true; - e->GetData().m_vertices[1]->GetData().m_onHull = true; - e = e->GetNext(); - } - // delete all the vertices that have been processed but are not on the hull - CircularList& vertices = m_mesh.GetVertices(); - CircularListElement* vHead = vertices.GetHead(); - CircularListElement* v = vHead; - v = v->GetPrev(); - do { - if (v->GetData().m_tag && !v->GetData().m_onHull) { - CircularListElement* tmp = v->GetPrev(); - vertices.Delete(v); - v = tmp; - addedPoints--; - } - else { - v->GetData().m_duplicate = 0; - v->GetData().m_onHull = false; - v = v->GetPrev(); - } - } while (v->GetData().m_tag && v != vHead); - return true; + // mark all vertices incident to some undeleted edge as on the hull + CircularList& edges = m_mesh.GetEdges(); + CircularListElement* e = edges.GetHead(); + size_t nE = edges.GetSize(); + for (size_t i = 0; i < nE; i++) + { + e->GetData().m_vertices[0]->GetData().m_onHull = true; + e->GetData().m_vertices[1]->GetData().m_onHull = true; + e = e->GetNext(); + } + // delete all the vertices that have been processed but are not on the hull + CircularList& vertices = m_mesh.GetVertices(); + CircularListElement* vHead = vertices.GetHead(); + CircularListElement* v = vHead; + v = v->GetPrev(); + do + { + if (v->GetData().m_tag && !v->GetData().m_onHull) + { + CircularListElement* tmp = v->GetPrev(); + vertices.Delete(v); + v = tmp; + addedPoints--; + } + else + { + v->GetData().m_duplicate = 0; + v->GetData().m_onHull = false; + v = v->GetPrev(); + } + } while (v->GetData().m_tag && v != vHead); + return true; } void ICHull::Clear() { - m_mesh.Clear(); - m_edgesToDelete.Resize(0); - m_edgesToUpdate.Resize(0); - m_trianglesToDelete.Resize(0); - m_isFlat = false; + m_mesh.Clear(); + m_edgesToDelete.Resize(0); + m_edgesToUpdate.Resize(0); + m_trianglesToDelete.Resize(0); + m_isFlat = false; } const ICHull& ICHull::operator=(ICHull& rhs) { - if (&rhs != this) { - m_mesh.Copy(rhs.m_mesh); - m_edgesToDelete = rhs.m_edgesToDelete; - m_edgesToUpdate = rhs.m_edgesToUpdate; - m_trianglesToDelete = rhs.m_trianglesToDelete; - m_isFlat = rhs.m_isFlat; - } - return (*this); + if (&rhs != this) + { + m_mesh.Copy(rhs.m_mesh); + m_edgesToDelete = rhs.m_edgesToDelete; + m_edgesToUpdate = rhs.m_edgesToUpdate; + m_trianglesToDelete = rhs.m_trianglesToDelete; + m_isFlat = rhs.m_isFlat; + } + return (*this); } bool ICHull::IsInside(const Vec3& pt0, const double eps) { - const Vec3 pt(pt0.X(), pt0.Y(), pt0.Z()); - if (m_isFlat) { - size_t nT = m_mesh.m_triangles.GetSize(); - Vec3 ver0, ver1, ver2, a, b, c; - double u, v; - for (size_t t = 0; t < nT; t++) { - ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X(); - ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y(); - ver0.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Z(); - ver1.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.X(); - ver1.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Y(); - ver1.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Z(); - ver2.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.X(); - ver2.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Y(); - ver2.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Z(); - a = ver1 - ver0; - b = ver2 - ver0; - c = pt - ver0; - u = c * a; - v = c * b; - if (u >= 0.0 && u <= 1.0 && v >= 0.0 && u + v <= 1.0) { - return true; - } - m_mesh.m_triangles.Next(); - } - return false; - } - else { - size_t nT = m_mesh.m_triangles.GetSize(); - Vec3 ver0, ver1, ver2; - double vol; - for (size_t t = 0; t < nT; t++) { - ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X(); - ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y(); - ver0.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Z(); - ver1.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.X(); - ver1.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Y(); - ver1.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Z(); - ver2.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.X(); - ver2.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Y(); - ver2.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Z(); - vol = ComputeVolume4(ver0, ver1, ver2, pt); - if (vol < eps) { - return false; - } - m_mesh.m_triangles.Next(); - } - return true; - } -} + const Vec3 pt(pt0.X(), pt0.Y(), pt0.Z()); + if (m_isFlat) + { + size_t nT = m_mesh.m_triangles.GetSize(); + Vec3 ver0, ver1, ver2, a, b, c; + double u, v; + for (size_t t = 0; t < nT; t++) + { + ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X(); + ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y(); + ver0.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Z(); + ver1.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.X(); + ver1.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Y(); + ver1.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Z(); + ver2.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.X(); + ver2.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Y(); + ver2.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Z(); + a = ver1 - ver0; + b = ver2 - ver0; + c = pt - ver0; + u = c * a; + v = c * b; + if (u >= 0.0 && u <= 1.0 && v >= 0.0 && u + v <= 1.0) + { + return true; + } + m_mesh.m_triangles.Next(); + } + return false; + } + else + { + size_t nT = m_mesh.m_triangles.GetSize(); + Vec3 ver0, ver1, ver2; + double vol; + for (size_t t = 0; t < nT; t++) + { + ver0.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.X(); + ver0.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Y(); + ver0.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[0]->GetData().m_pos.Z(); + ver1.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.X(); + ver1.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Y(); + ver1.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[1]->GetData().m_pos.Z(); + ver2.X() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.X(); + ver2.Y() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Y(); + ver2.Z() = m_mesh.m_triangles.GetHead()->GetData().m_vertices[2]->GetData().m_pos.Z(); + vol = ComputeVolume4(ver0, ver1, ver2, pt); + if (vol < eps) + { + return false; + } + m_mesh.m_triangles.Next(); + } + return true; + } } +} // namespace VHACD diff --git a/Extras/VHACD/src/vhacdManifoldMesh.cpp b/Extras/VHACD/src/vhacdManifoldMesh.cpp index dffa0244e..8ff8aeb6c 100644 --- a/Extras/VHACD/src/vhacdManifoldMesh.cpp +++ b/Extras/VHACD/src/vhacdManifoldMesh.cpp @@ -13,18 +13,19 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "vhacdManifoldMesh.h" -namespace VHACD { +namespace VHACD +{ TMMVertex::TMMVertex(void) { - Initialize(); + Initialize(); } void TMMVertex::Initialize() { - m_name = 0; - m_id = 0; - m_duplicate = 0; - m_onHull = false; - m_tag = false; + m_name = 0; + m_id = 0; + m_duplicate = 0; + m_onHull = false; + m_tag = false; } TMMVertex::~TMMVertex(void) @@ -32,29 +33,30 @@ TMMVertex::~TMMVertex(void) } TMMEdge::TMMEdge(void) { - Initialize(); + Initialize(); } void TMMEdge::Initialize() { - m_id = 0; - m_triangles[0] = m_triangles[1] = m_newFace = 0; - m_vertices[0] = m_vertices[1] = 0; + m_id = 0; + m_triangles[0] = m_triangles[1] = m_newFace = 0; + m_vertices[0] = m_vertices[1] = 0; } TMMEdge::~TMMEdge(void) { } void TMMTriangle::Initialize() { - m_id = 0; - for (int i = 0; i < 3; i++) { - m_edges[i] = 0; - m_vertices[0] = 0; - } - m_visible = false; + m_id = 0; + for (int i = 0; i < 3; i++) + { + m_edges[i] = 0; + m_vertices[0] = 0; + } + m_visible = false; } TMMTriangle::TMMTriangle(void) { - Initialize(); + Initialize(); } TMMTriangle::~TMMTriangle(void) { @@ -67,136 +69,167 @@ TMMesh::~TMMesh(void) } void TMMesh::GetIFS(Vec3* const points, Vec3* const triangles) { - size_t nV = m_vertices.GetSize(); - size_t nT = m_triangles.GetSize(); + size_t nV = m_vertices.GetSize(); + size_t nT = m_triangles.GetSize(); - for (size_t v = 0; v < nV; v++) { - points[v] = m_vertices.GetData().m_pos; - m_vertices.GetData().m_id = v; - m_vertices.Next(); - } - for (size_t f = 0; f < nT; f++) { - TMMTriangle& currentTriangle = m_triangles.GetData(); - triangles[f].X() = static_cast(currentTriangle.m_vertices[0]->GetData().m_id); - triangles[f].Y() = static_cast(currentTriangle.m_vertices[1]->GetData().m_id); - triangles[f].Z() = static_cast(currentTriangle.m_vertices[2]->GetData().m_id); - m_triangles.Next(); - } + for (size_t v = 0; v < nV; v++) + { + points[v] = m_vertices.GetData().m_pos; + m_vertices.GetData().m_id = v; + m_vertices.Next(); + } + for (size_t f = 0; f < nT; f++) + { + TMMTriangle& currentTriangle = m_triangles.GetData(); + triangles[f].X() = static_cast(currentTriangle.m_vertices[0]->GetData().m_id); + triangles[f].Y() = static_cast(currentTriangle.m_vertices[1]->GetData().m_id); + triangles[f].Z() = static_cast(currentTriangle.m_vertices[2]->GetData().m_id); + m_triangles.Next(); + } } void TMMesh::Clear() { - m_vertices.Clear(); - m_edges.Clear(); - m_triangles.Clear(); + m_vertices.Clear(); + m_edges.Clear(); + m_triangles.Clear(); } void TMMesh::Copy(TMMesh& mesh) { - Clear(); - // updating the id's - size_t nV = mesh.m_vertices.GetSize(); - size_t nE = mesh.m_edges.GetSize(); - size_t nT = mesh.m_triangles.GetSize(); - for (size_t v = 0; v < nV; v++) { - mesh.m_vertices.GetData().m_id = v; - mesh.m_vertices.Next(); - } - for (size_t e = 0; e < nE; e++) { - mesh.m_edges.GetData().m_id = e; - mesh.m_edges.Next(); - } - for (size_t f = 0; f < nT; f++) { - mesh.m_triangles.GetData().m_id = f; - mesh.m_triangles.Next(); - } - // copying data - m_vertices = mesh.m_vertices; - m_edges = mesh.m_edges; - m_triangles = mesh.m_triangles; + Clear(); + // updating the id's + size_t nV = mesh.m_vertices.GetSize(); + size_t nE = mesh.m_edges.GetSize(); + size_t nT = mesh.m_triangles.GetSize(); + for (size_t v = 0; v < nV; v++) + { + mesh.m_vertices.GetData().m_id = v; + mesh.m_vertices.Next(); + } + for (size_t e = 0; e < nE; e++) + { + mesh.m_edges.GetData().m_id = e; + mesh.m_edges.Next(); + } + for (size_t f = 0; f < nT; f++) + { + mesh.m_triangles.GetData().m_id = f; + mesh.m_triangles.Next(); + } + // copying data + m_vertices = mesh.m_vertices; + m_edges = mesh.m_edges; + m_triangles = mesh.m_triangles; - // generate mapping - CircularListElement** vertexMap = new CircularListElement*[nV]; - CircularListElement** edgeMap = new CircularListElement*[nE]; - CircularListElement** triangleMap = new CircularListElement*[nT]; - for (size_t v = 0; v < nV; v++) { - vertexMap[v] = m_vertices.GetHead(); - m_vertices.Next(); - } - for (size_t e = 0; e < nE; e++) { - edgeMap[e] = m_edges.GetHead(); - m_edges.Next(); - } - for (size_t f = 0; f < nT; f++) { - triangleMap[f] = m_triangles.GetHead(); - m_triangles.Next(); - } + // generate mapping + CircularListElement** vertexMap = new CircularListElement*[nV]; + CircularListElement** edgeMap = new CircularListElement*[nE]; + CircularListElement** triangleMap = new CircularListElement*[nT]; + for (size_t v = 0; v < nV; v++) + { + vertexMap[v] = m_vertices.GetHead(); + m_vertices.Next(); + } + for (size_t e = 0; e < nE; e++) + { + edgeMap[e] = m_edges.GetHead(); + m_edges.Next(); + } + for (size_t f = 0; f < nT; f++) + { + triangleMap[f] = m_triangles.GetHead(); + m_triangles.Next(); + } - // updating pointers - for (size_t v = 0; v < nV; v++) { - if (vertexMap[v]->GetData().m_duplicate) { - vertexMap[v]->GetData().m_duplicate = edgeMap[vertexMap[v]->GetData().m_duplicate->GetData().m_id]; - } - } - for (size_t e = 0; e < nE; e++) { - if (edgeMap[e]->GetData().m_newFace) { - edgeMap[e]->GetData().m_newFace = triangleMap[edgeMap[e]->GetData().m_newFace->GetData().m_id]; - } - if (nT > 0) { - for (int f = 0; f < 2; f++) { - if (edgeMap[e]->GetData().m_triangles[f]) { - edgeMap[e]->GetData().m_triangles[f] = triangleMap[edgeMap[e]->GetData().m_triangles[f]->GetData().m_id]; - } - } - } - for (int v = 0; v < 2; v++) { - if (edgeMap[e]->GetData().m_vertices[v]) { - edgeMap[e]->GetData().m_vertices[v] = vertexMap[edgeMap[e]->GetData().m_vertices[v]->GetData().m_id]; - } - } - } - for (size_t f = 0; f < nT; f++) { - if (nE > 0) { - for (int e = 0; e < 3; e++) { - if (triangleMap[f]->GetData().m_edges[e]) { - triangleMap[f]->GetData().m_edges[e] = edgeMap[triangleMap[f]->GetData().m_edges[e]->GetData().m_id]; - } - } - } - for (int v = 0; v < 3; v++) { - if (triangleMap[f]->GetData().m_vertices[v]) { - triangleMap[f]->GetData().m_vertices[v] = vertexMap[triangleMap[f]->GetData().m_vertices[v]->GetData().m_id]; - } - } - } - delete[] vertexMap; - delete[] edgeMap; - delete[] triangleMap; + // updating pointers + for (size_t v = 0; v < nV; v++) + { + if (vertexMap[v]->GetData().m_duplicate) + { + vertexMap[v]->GetData().m_duplicate = edgeMap[vertexMap[v]->GetData().m_duplicate->GetData().m_id]; + } + } + for (size_t e = 0; e < nE; e++) + { + if (edgeMap[e]->GetData().m_newFace) + { + edgeMap[e]->GetData().m_newFace = triangleMap[edgeMap[e]->GetData().m_newFace->GetData().m_id]; + } + if (nT > 0) + { + for (int f = 0; f < 2; f++) + { + if (edgeMap[e]->GetData().m_triangles[f]) + { + edgeMap[e]->GetData().m_triangles[f] = triangleMap[edgeMap[e]->GetData().m_triangles[f]->GetData().m_id]; + } + } + } + for (int v = 0; v < 2; v++) + { + if (edgeMap[e]->GetData().m_vertices[v]) + { + edgeMap[e]->GetData().m_vertices[v] = vertexMap[edgeMap[e]->GetData().m_vertices[v]->GetData().m_id]; + } + } + } + for (size_t f = 0; f < nT; f++) + { + if (nE > 0) + { + for (int e = 0; e < 3; e++) + { + if (triangleMap[f]->GetData().m_edges[e]) + { + triangleMap[f]->GetData().m_edges[e] = edgeMap[triangleMap[f]->GetData().m_edges[e]->GetData().m_id]; + } + } + } + for (int v = 0; v < 3; v++) + { + if (triangleMap[f]->GetData().m_vertices[v]) + { + triangleMap[f]->GetData().m_vertices[v] = vertexMap[triangleMap[f]->GetData().m_vertices[v]->GetData().m_id]; + } + } + } + delete[] vertexMap; + delete[] edgeMap; + delete[] triangleMap; } bool TMMesh::CheckConsistancy() { - size_t nE = m_edges.GetSize(); - size_t nT = m_triangles.GetSize(); - for (size_t e = 0; e < nE; e++) { - for (int f = 0; f < 2; f++) { - if (!m_edges.GetHead()->GetData().m_triangles[f]) { - return false; - } - } - m_edges.Next(); - } - for (size_t f = 0; f < nT; f++) { - for (int e = 0; e < 3; e++) { - int found = 0; - for (int k = 0; k < 2; k++) { - if (m_triangles.GetHead()->GetData().m_edges[e]->GetData().m_triangles[k] == m_triangles.GetHead()) { - found++; - } - } - if (found != 1) { - return false; - } - } - m_triangles.Next(); - } - return true; + size_t nE = m_edges.GetSize(); + size_t nT = m_triangles.GetSize(); + for (size_t e = 0; e < nE; e++) + { + for (int f = 0; f < 2; f++) + { + if (!m_edges.GetHead()->GetData().m_triangles[f]) + { + return false; + } + } + m_edges.Next(); + } + for (size_t f = 0; f < nT; f++) + { + for (int e = 0; e < 3; e++) + { + int found = 0; + for (int k = 0; k < 2; k++) + { + if (m_triangles.GetHead()->GetData().m_edges[e]->GetData().m_triangles[k] == m_triangles.GetHead()) + { + found++; + } + } + if (found != 1) + { + return false; + } + } + m_triangles.Next(); + } + return true; } -} \ No newline at end of file +} // namespace VHACD \ No newline at end of file diff --git a/Extras/VHACD/src/vhacdMesh.cpp b/Extras/VHACD/src/vhacdMesh.cpp index 542ce430b..909bd2bb5 100644 --- a/Extras/VHACD/src/vhacdMesh.cpp +++ b/Extras/VHACD/src/vhacdMesh.cpp @@ -23,301 +23,336 @@ #include #include -namespace VHACD { +namespace VHACD +{ Mesh::Mesh() { - m_diag = 1.0; + m_diag = 1.0; } Mesh::~Mesh() { } double Mesh::ComputeVolume() const { - const size_t nV = GetNPoints(); - const size_t nT = GetNTriangles(); - if (nV == 0 || nT == 0) { - return 0.0; - } + const size_t nV = GetNPoints(); + const size_t nT = GetNTriangles(); + if (nV == 0 || nT == 0) + { + return 0.0; + } - Vec3 bary(0.0, 0.0, 0.0); - for (size_t v = 0; v < nV; v++) { - bary += GetPoint(v); - } - bary /= static_cast(nV); + Vec3 bary(0.0, 0.0, 0.0); + for (size_t v = 0; v < nV; v++) + { + bary += GetPoint(v); + } + bary /= static_cast(nV); - Vec3 ver0, ver1, ver2; - double totalVolume = 0.0; - for (int t = 0; t < nT; t++) { - const Vec3& tri = GetTriangle(t); - ver0 = GetPoint(tri[0]); - ver1 = GetPoint(tri[1]); - ver2 = GetPoint(tri[2]); - totalVolume += ComputeVolume4(ver0, ver1, ver2, bary); - } - return totalVolume / 6.0; + Vec3 ver0, ver1, ver2; + double totalVolume = 0.0; + for (int t = 0; t < nT; t++) + { + const Vec3& tri = GetTriangle(t); + ver0 = GetPoint(tri[0]); + ver1 = GetPoint(tri[1]); + ver2 = GetPoint(tri[2]); + totalVolume += ComputeVolume4(ver0, ver1, ver2, bary); + } + return totalVolume / 6.0; } void Mesh::ComputeConvexHull(const double* const pts, - const size_t nPts) + const size_t nPts) { - ResizePoints(0); - ResizeTriangles(0); - btConvexHullComputer ch; - ch.compute(pts, 3 * sizeof(double), (int)nPts, -1.0, -1.0); - for (int v = 0; v < ch.vertices.size(); v++) { - AddPoint(Vec3(ch.vertices[v].getX(), ch.vertices[v].getY(), ch.vertices[v].getZ())); - } - const int nt = ch.faces.size(); - for (int t = 0; t < nt; ++t) { - const btConvexHullComputer::Edge* sourceEdge = &(ch.edges[ch.faces[t]]); - int a = sourceEdge->getSourceVertex(); - int b = sourceEdge->getTargetVertex(); - const btConvexHullComputer::Edge* edge = sourceEdge->getNextEdgeOfFace(); - int c = edge->getTargetVertex(); - while (c != a) { - AddTriangle(Vec3(a, b, c)); - edge = edge->getNextEdgeOfFace(); - b = c; - c = edge->getTargetVertex(); - } - } + ResizePoints(0); + ResizeTriangles(0); + btConvexHullComputer ch; + ch.compute(pts, 3 * sizeof(double), (int)nPts, -1.0, -1.0); + for (int v = 0; v < ch.vertices.size(); v++) + { + AddPoint(Vec3(ch.vertices[v].getX(), ch.vertices[v].getY(), ch.vertices[v].getZ())); + } + const int nt = ch.faces.size(); + for (int t = 0; t < nt; ++t) + { + const btConvexHullComputer::Edge* sourceEdge = &(ch.edges[ch.faces[t]]); + int a = sourceEdge->getSourceVertex(); + int b = sourceEdge->getTargetVertex(); + const btConvexHullComputer::Edge* edge = sourceEdge->getNextEdgeOfFace(); + int c = edge->getTargetVertex(); + while (c != a) + { + AddTriangle(Vec3(a, b, c)); + edge = edge->getNextEdgeOfFace(); + b = c; + c = edge->getTargetVertex(); + } + } } void Mesh::Clip(const Plane& plane, - SArray >& positivePart, - SArray >& negativePart) const + SArray >& positivePart, + SArray >& negativePart) const { - const size_t nV = GetNPoints(); - if (nV == 0) { - return; - } - double d; - for (size_t v = 0; v < nV; v++) { - const Vec3& pt = GetPoint(v); - d = plane.m_a * pt[0] + plane.m_b * pt[1] + plane.m_c * pt[2] + plane.m_d; - if (d > 0.0) { - positivePart.PushBack(pt); - } - else if (d < 0.0) { - negativePart.PushBack(pt); - } - else { - positivePart.PushBack(pt); - negativePart.PushBack(pt); - } - } + const size_t nV = GetNPoints(); + if (nV == 0) + { + return; + } + double d; + for (size_t v = 0; v < nV; v++) + { + const Vec3& pt = GetPoint(v); + d = plane.m_a * pt[0] + plane.m_b * pt[1] + plane.m_c * pt[2] + plane.m_d; + if (d > 0.0) + { + positivePart.PushBack(pt); + } + else if (d < 0.0) + { + negativePart.PushBack(pt); + } + else + { + positivePart.PushBack(pt); + negativePart.PushBack(pt); + } + } } bool Mesh::IsInside(const Vec3& pt) const { - const size_t nV = GetNPoints(); - const size_t nT = GetNTriangles(); - if (nV == 0 || nT == 0) { - return false; - } - Vec3 ver0, ver1, ver2; - double volume; - for (int t = 0; t < nT; t++) { - const Vec3& tri = GetTriangle(t); - ver0 = GetPoint(tri[0]); - ver1 = GetPoint(tri[1]); - ver2 = GetPoint(tri[2]); - volume = ComputeVolume4(ver0, ver1, ver2, pt); - if (volume < 0.0) { - return false; - } - } - return true; + const size_t nV = GetNPoints(); + const size_t nT = GetNTriangles(); + if (nV == 0 || nT == 0) + { + return false; + } + Vec3 ver0, ver1, ver2; + double volume; + for (int t = 0; t < nT; t++) + { + const Vec3& tri = GetTriangle(t); + ver0 = GetPoint(tri[0]); + ver1 = GetPoint(tri[1]); + ver2 = GetPoint(tri[2]); + volume = ComputeVolume4(ver0, ver1, ver2, pt); + if (volume < 0.0) + { + return false; + } + } + return true; } double Mesh::ComputeDiagBB() { - const size_t nPoints = GetNPoints(); - if (nPoints == 0) - return 0.0; - Vec3 minBB = m_points[0]; - Vec3 maxBB = m_points[0]; - double x, y, z; - for (size_t v = 1; v < nPoints; v++) { - x = m_points[v][0]; - y = m_points[v][1]; - z = m_points[v][2]; - if (x < minBB[0]) - minBB[0] = x; - else if (x > maxBB[0]) - maxBB[0] = x; - if (y < minBB[1]) - minBB[1] = y; - else if (y > maxBB[1]) - maxBB[1] = y; - if (z < minBB[2]) - minBB[2] = z; - else if (z > maxBB[2]) - maxBB[2] = z; - } - return (m_diag = (maxBB - minBB).GetNorm()); + const size_t nPoints = GetNPoints(); + if (nPoints == 0) + return 0.0; + Vec3 minBB = m_points[0]; + Vec3 maxBB = m_points[0]; + double x, y, z; + for (size_t v = 1; v < nPoints; v++) + { + x = m_points[v][0]; + y = m_points[v][1]; + z = m_points[v][2]; + if (x < minBB[0]) + minBB[0] = x; + else if (x > maxBB[0]) + maxBB[0] = x; + if (y < minBB[1]) + minBB[1] = y; + else if (y > maxBB[1]) + maxBB[1] = y; + if (z < minBB[2]) + minBB[2] = z; + else if (z > maxBB[2]) + maxBB[2] = z; + } + return (m_diag = (maxBB - minBB).GetNorm()); } #ifdef VHACD_DEBUG_MESH bool Mesh::SaveVRML2(const std::string& fileName) const { - std::ofstream fout(fileName.c_str()); - if (fout.is_open()) { - const Material material; + std::ofstream fout(fileName.c_str()); + if (fout.is_open()) + { + const Material material; - if (SaveVRML2(fout, material)) { - fout.close(); - return true; - } - return false; - } - return false; + if (SaveVRML2(fout, material)) + { + fout.close(); + return true; + } + return false; + } + return false; } bool Mesh::SaveVRML2(std::ofstream& fout, const Material& material) const { - if (fout.is_open()) { - fout.setf(std::ios::fixed, std::ios::floatfield); - fout.setf(std::ios::showpoint); - fout.precision(6); - size_t nV = m_points.Size(); - size_t nT = m_triangles.Size(); - fout << "#VRML V2.0 utf8" << std::endl; - fout << "" << std::endl; - fout << "# Vertices: " << nV << std::endl; - fout << "# Triangles: " << nT << std::endl; - fout << "" << std::endl; - fout << "Group {" << std::endl; - fout << " children [" << std::endl; - fout << " Shape {" << std::endl; - fout << " appearance Appearance {" << std::endl; - fout << " material Material {" << std::endl; - fout << " diffuseColor " << material.m_diffuseColor[0] << " " - << material.m_diffuseColor[1] << " " - << material.m_diffuseColor[2] << std::endl; - fout << " ambientIntensity " << material.m_ambientIntensity << std::endl; - fout << " specularColor " << material.m_specularColor[0] << " " - << material.m_specularColor[1] << " " - << material.m_specularColor[2] << std::endl; - fout << " emissiveColor " << material.m_emissiveColor[0] << " " - << material.m_emissiveColor[1] << " " - << material.m_emissiveColor[2] << std::endl; - fout << " shininess " << material.m_shininess << std::endl; - fout << " transparency " << material.m_transparency << std::endl; - fout << " }" << std::endl; - fout << " }" << std::endl; - fout << " geometry IndexedFaceSet {" << std::endl; - fout << " ccw TRUE" << std::endl; - fout << " solid TRUE" << std::endl; - fout << " convex TRUE" << std::endl; - if (nV > 0) { - fout << " coord DEF co Coordinate {" << std::endl; - fout << " point [" << std::endl; - for (size_t v = 0; v < nV; v++) { - fout << " " << m_points[v][0] << " " - << m_points[v][1] << " " - << m_points[v][2] << "," << std::endl; - } - fout << " ]" << std::endl; - fout << " }" << std::endl; - } - if (nT > 0) { - fout << " coordIndex [ " << std::endl; - for (size_t f = 0; f < nT; f++) { - fout << " " << m_triangles[f][0] << ", " - << m_triangles[f][1] << ", " - << m_triangles[f][2] << ", -1," << std::endl; - } - fout << " ]" << std::endl; - } - fout << " }" << std::endl; - fout << " }" << std::endl; - fout << " ]" << std::endl; - fout << "}" << std::endl; - return true; - } - return false; + if (fout.is_open()) + { + fout.setf(std::ios::fixed, std::ios::floatfield); + fout.setf(std::ios::showpoint); + fout.precision(6); + size_t nV = m_points.Size(); + size_t nT = m_triangles.Size(); + fout << "#VRML V2.0 utf8" << std::endl; + fout << "" << std::endl; + fout << "# Vertices: " << nV << std::endl; + fout << "# Triangles: " << nT << std::endl; + fout << "" << std::endl; + fout << "Group {" << std::endl; + fout << " children [" << std::endl; + fout << " Shape {" << std::endl; + fout << " appearance Appearance {" << std::endl; + fout << " material Material {" << std::endl; + fout << " diffuseColor " << material.m_diffuseColor[0] << " " + << material.m_diffuseColor[1] << " " + << material.m_diffuseColor[2] << std::endl; + fout << " ambientIntensity " << material.m_ambientIntensity << std::endl; + fout << " specularColor " << material.m_specularColor[0] << " " + << material.m_specularColor[1] << " " + << material.m_specularColor[2] << std::endl; + fout << " emissiveColor " << material.m_emissiveColor[0] << " " + << material.m_emissiveColor[1] << " " + << material.m_emissiveColor[2] << std::endl; + fout << " shininess " << material.m_shininess << std::endl; + fout << " transparency " << material.m_transparency << std::endl; + fout << " }" << std::endl; + fout << " }" << std::endl; + fout << " geometry IndexedFaceSet {" << std::endl; + fout << " ccw TRUE" << std::endl; + fout << " solid TRUE" << std::endl; + fout << " convex TRUE" << std::endl; + if (nV > 0) + { + fout << " coord DEF co Coordinate {" << std::endl; + fout << " point [" << std::endl; + for (size_t v = 0; v < nV; v++) + { + fout << " " << m_points[v][0] << " " + << m_points[v][1] << " " + << m_points[v][2] << "," << std::endl; + } + fout << " ]" << std::endl; + fout << " }" << std::endl; + } + if (nT > 0) + { + fout << " coordIndex [ " << std::endl; + for (size_t f = 0; f < nT; f++) + { + fout << " " << m_triangles[f][0] << ", " + << m_triangles[f][1] << ", " + << m_triangles[f][2] << ", -1," << std::endl; + } + fout << " ]" << std::endl; + } + fout << " }" << std::endl; + fout << " }" << std::endl; + fout << " ]" << std::endl; + fout << "}" << std::endl; + return true; + } + return false; } bool Mesh::SaveOFF(const std::string& fileName) const { - std::ofstream fout(fileName.c_str()); - if (fout.is_open()) { - size_t nV = m_points.Size(); - size_t nT = m_triangles.Size(); - fout << "OFF" << std::endl; - fout << nV << " " << nT << " " << 0 << std::endl; - for (size_t v = 0; v < nV; v++) { - fout << m_points[v][0] << " " - << m_points[v][1] << " " - << m_points[v][2] << std::endl; - } - for (size_t f = 0; f < nT; f++) { - fout << "3 " << m_triangles[f][0] << " " - << m_triangles[f][1] << " " - << m_triangles[f][2] << std::endl; - } - fout.close(); - return true; - } - return false; + std::ofstream fout(fileName.c_str()); + if (fout.is_open()) + { + size_t nV = m_points.Size(); + size_t nT = m_triangles.Size(); + fout << "OFF" << std::endl; + fout << nV << " " << nT << " " << 0 << std::endl; + for (size_t v = 0; v < nV; v++) + { + fout << m_points[v][0] << " " + << m_points[v][1] << " " + << m_points[v][2] << std::endl; + } + for (size_t f = 0; f < nT; f++) + { + fout << "3 " << m_triangles[f][0] << " " + << m_triangles[f][1] << " " + << m_triangles[f][2] << std::endl; + } + fout.close(); + return true; + } + return false; } bool Mesh::LoadOFF(const std::string& fileName, bool invert) { - FILE* fid = fopen(fileName.c_str(), "r"); - if (fid) { - const std::string strOFF("OFF"); - char temp[1024]; - fscanf(fid, "%s", temp); - if (std::string(temp) != strOFF) { - fclose(fid); - return false; - } - else { - int nv = 0; - int nf = 0; - int ne = 0; - fscanf(fid, "%i", &nv); - fscanf(fid, "%i", &nf); - fscanf(fid, "%i", &ne); - m_points.Resize(nv); - m_triangles.Resize(nf); - Vec3 coord; - float x, y, z; - for (int p = 0; p < nv; p++) { - fscanf(fid, "%f", &x); - fscanf(fid, "%f", &y); - fscanf(fid, "%f", &z); - m_points[p][0] = x; - m_points[p][1] = y; - m_points[p][2] = z; - } - int i, j, k, s; - for (int t = 0; t < nf; ++t) { - fscanf(fid, "%i", &s); - if (s == 3) { - fscanf(fid, "%i", &i); - fscanf(fid, "%i", &j); - fscanf(fid, "%i", &k); - m_triangles[t][0] = i; - if (invert) { - m_triangles[t][1] = k; - m_triangles[t][2] = j; - } - else { - m_triangles[t][1] = j; - m_triangles[t][2] = k; - } - } - else // Fix me: support only triangular meshes - { - for (int h = 0; h < s; ++h) - fscanf(fid, "%i", &s); - } - } - fclose(fid); - } - } - else { - return false; - } - return true; -} -#endif // VHACD_DEBUG_MESH + FILE* fid = fopen(fileName.c_str(), "r"); + if (fid) + { + const std::string strOFF("OFF"); + char temp[1024]; + fscanf(fid, "%s", temp); + if (std::string(temp) != strOFF) + { + fclose(fid); + return false; + } + else + { + int nv = 0; + int nf = 0; + int ne = 0; + fscanf(fid, "%i", &nv); + fscanf(fid, "%i", &nf); + fscanf(fid, "%i", &ne); + m_points.Resize(nv); + m_triangles.Resize(nf); + Vec3 coord; + float x, y, z; + for (int p = 0; p < nv; p++) + { + fscanf(fid, "%f", &x); + fscanf(fid, "%f", &y); + fscanf(fid, "%f", &z); + m_points[p][0] = x; + m_points[p][1] = y; + m_points[p][2] = z; + } + int i, j, k, s; + for (int t = 0; t < nf; ++t) + { + fscanf(fid, "%i", &s); + if (s == 3) + { + fscanf(fid, "%i", &i); + fscanf(fid, "%i", &j); + fscanf(fid, "%i", &k); + m_triangles[t][0] = i; + if (invert) + { + m_triangles[t][1] = k; + m_triangles[t][2] = j; + } + else + { + m_triangles[t][1] = j; + m_triangles[t][2] = k; + } + } + else // Fix me: support only triangular meshes + { + for (int h = 0; h < s; ++h) + fscanf(fid, "%i", &s); + } + } + fclose(fid); + } + } + else + { + return false; + } + return true; } +#endif // VHACD_DEBUG_MESH +} // namespace VHACD diff --git a/Extras/VHACD/src/vhacdVolume.cpp b/Extras/VHACD/src/vhacdVolume.cpp index a3cf60360..8728e7c3f 100644 --- a/Extras/VHACD/src/vhacdVolume.cpp +++ b/Extras/VHACD/src/vhacdVolume.cpp @@ -21,7 +21,8 @@ #include #include -namespace VHACD { +namespace VHACD +{ /********************************************************/ /* AABB-triangle overlap test code */ /* by Tomas Akenine-Möller */ @@ -40,1578 +41,1755 @@ namespace VHACD { #define Y 1 #define Z 2 #define FINDMINMAX(x0, x1, x2, min, max) \ - min = max = x0; \ - if (x1 < min) \ - min = x1; \ - if (x1 > max) \ - max = x1; \ - if (x2 < min) \ - min = x2; \ - if (x2 > max) \ - max = x2; + min = max = x0; \ + if (x1 < min) \ + min = x1; \ + if (x1 > max) \ + max = x1; \ + if (x2 < min) \ + min = x2; \ + if (x2 > max) \ + max = x2; #define AXISTEST_X01(a, b, fa, fb) \ - p0 = a * v0[Y] - b * v0[Z]; \ - p2 = a * v2[Y] - b * v2[Z]; \ - if (p0 < p2) { \ - min = p0; \ - max = p2; \ - } \ - else { \ - min = p2; \ - max = p0; \ - } \ - rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \ - if (min > rad || max < -rad) \ - return 0; + p0 = a * v0[Y] - b * v0[Z]; \ + p2 = a * v2[Y] - b * v2[Z]; \ + if (p0 < p2) \ + { \ + min = p0; \ + max = p2; \ + } \ + else \ + { \ + min = p2; \ + max = p0; \ + } \ + rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \ + if (min > rad || max < -rad) \ + return 0; #define AXISTEST_X2(a, b, fa, fb) \ - p0 = a * v0[Y] - b * v0[Z]; \ - p1 = a * v1[Y] - b * v1[Z]; \ - if (p0 < p1) { \ - min = p0; \ - max = p1; \ - } \ - else { \ - min = p1; \ - max = p0; \ - } \ - rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \ - if (min > rad || max < -rad) \ - return 0; + p0 = a * v0[Y] - b * v0[Z]; \ + p1 = a * v1[Y] - b * v1[Z]; \ + if (p0 < p1) \ + { \ + min = p0; \ + max = p1; \ + } \ + else \ + { \ + min = p1; \ + max = p0; \ + } \ + rad = fa * boxhalfsize[Y] + fb * boxhalfsize[Z]; \ + if (min > rad || max < -rad) \ + return 0; #define AXISTEST_Y02(a, b, fa, fb) \ - p0 = -a * v0[X] + b * v0[Z]; \ - p2 = -a * v2[X] + b * v2[Z]; \ - if (p0 < p2) { \ - min = p0; \ - max = p2; \ - } \ - else { \ - min = p2; \ - max = p0; \ - } \ - rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \ - if (min > rad || max < -rad) \ - return 0; + p0 = -a * v0[X] + b * v0[Z]; \ + p2 = -a * v2[X] + b * v2[Z]; \ + if (p0 < p2) \ + { \ + min = p0; \ + max = p2; \ + } \ + else \ + { \ + min = p2; \ + max = p0; \ + } \ + rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \ + if (min > rad || max < -rad) \ + return 0; #define AXISTEST_Y1(a, b, fa, fb) \ - p0 = -a * v0[X] + b * v0[Z]; \ - p1 = -a * v1[X] + b * v1[Z]; \ - if (p0 < p1) { \ - min = p0; \ - max = p1; \ - } \ - else { \ - min = p1; \ - max = p0; \ - } \ - rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \ - if (min > rad || max < -rad) \ - return 0; + p0 = -a * v0[X] + b * v0[Z]; \ + p1 = -a * v1[X] + b * v1[Z]; \ + if (p0 < p1) \ + { \ + min = p0; \ + max = p1; \ + } \ + else \ + { \ + min = p1; \ + max = p0; \ + } \ + rad = fa * boxhalfsize[X] + fb * boxhalfsize[Z]; \ + if (min > rad || max < -rad) \ + return 0; #define AXISTEST_Z12(a, b, fa, fb) \ - p1 = a * v1[X] - b * v1[Y]; \ - p2 = a * v2[X] - b * v2[Y]; \ - if (p2 < p1) { \ - min = p2; \ - max = p1; \ - } \ - else { \ - min = p1; \ - max = p2; \ - } \ - rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \ - if (min > rad || max < -rad) \ - return 0; + p1 = a * v1[X] - b * v1[Y]; \ + p2 = a * v2[X] - b * v2[Y]; \ + if (p2 < p1) \ + { \ + min = p2; \ + max = p1; \ + } \ + else \ + { \ + min = p1; \ + max = p2; \ + } \ + rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \ + if (min > rad || max < -rad) \ + return 0; #define AXISTEST_Z0(a, b, fa, fb) \ - p0 = a * v0[X] - b * v0[Y]; \ - p1 = a * v1[X] - b * v1[Y]; \ - if (p0 < p1) { \ - min = p0; \ - max = p1; \ - } \ - else { \ - min = p1; \ - max = p0; \ - } \ - rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \ - if (min > rad || max < -rad) \ - return 0; + p0 = a * v0[X] - b * v0[Y]; \ + p1 = a * v1[X] - b * v1[Y]; \ + if (p0 < p1) \ + { \ + min = p0; \ + max = p1; \ + } \ + else \ + { \ + min = p1; \ + max = p0; \ + } \ + rad = fa * boxhalfsize[X] + fb * boxhalfsize[Y]; \ + if (min > rad || max < -rad) \ + return 0; int PlaneBoxOverlap(const Vec3& normal, - const Vec3& vert, - const Vec3& maxbox) + const Vec3& vert, + const Vec3& maxbox) { - int q; - Vec3 vmin, vmax; - double v; - for (q = X; q <= Z; q++) { - v = vert[q]; - if (normal[q] > 0.0) { - vmin[q] = -maxbox[q] - v; - vmax[q] = maxbox[q] - v; - } - else { - vmin[q] = maxbox[q] - v; - vmax[q] = -maxbox[q] - v; - } - } - if (normal * vmin > 0.0) - return 0; - if (normal * vmax >= 0.0) - return 1; - return 0; + int q; + Vec3 vmin, vmax; + double v; + for (q = X; q <= Z; q++) + { + v = vert[q]; + if (normal[q] > 0.0) + { + vmin[q] = -maxbox[q] - v; + vmax[q] = maxbox[q] - v; + } + else + { + vmin[q] = maxbox[q] - v; + vmax[q] = -maxbox[q] - v; + } + } + if (normal * vmin > 0.0) + return 0; + if (normal * vmax >= 0.0) + return 1; + return 0; } int TriBoxOverlap(const Vec3& boxcenter, - const Vec3& boxhalfsize, - const Vec3& triver0, - const Vec3& triver1, - const Vec3& triver2) + const Vec3& boxhalfsize, + const Vec3& triver0, + const Vec3& triver1, + const Vec3& triver2) { - /* use separating axis theorem to test overlap between triangle and box */ - /* need to test for overlap in these directions: */ - /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */ - /* we do not even need to test these) */ - /* 2) normal of the triangle */ - /* 3) crossproduct(edge from tri, {x,y,z}-directin) */ - /* this gives 3x3=9 more tests */ + /* use separating axis theorem to test overlap between triangle and box */ + /* need to test for overlap in these directions: */ + /* 1) the {x,y,z}-directions (actually, since we use the AABB of the triangle */ + /* we do not even need to test these) */ + /* 2) normal of the triangle */ + /* 3) crossproduct(edge from tri, {x,y,z}-directin) */ + /* this gives 3x3=9 more tests */ - Vec3 v0, v1, v2; - double min, max, p0, p1, p2, rad, fex, fey, fez; // -NJMP- "d" local variable removed - Vec3 normal, e0, e1, e2; + Vec3 v0, v1, v2; + double min, max, p0, p1, p2, rad, fex, fey, fez; // -NJMP- "d" local variable removed + Vec3 normal, e0, e1, e2; - /* This is the fastest branch on Sun */ - /* move everything so that the boxcenter is in (0,0,0) */ + /* This is the fastest branch on Sun */ + /* move everything so that the boxcenter is in (0,0,0) */ - v0 = triver0 - boxcenter; - v1 = triver1 - boxcenter; - v2 = triver2 - boxcenter; + v0 = triver0 - boxcenter; + v1 = triver1 - boxcenter; + v2 = triver2 - boxcenter; - /* compute triangle edges */ - e0 = v1 - v0; /* tri edge 0 */ - e1 = v2 - v1; /* tri edge 1 */ - e2 = v0 - v2; /* tri edge 2 */ + /* compute triangle edges */ + e0 = v1 - v0; /* tri edge 0 */ + e1 = v2 - v1; /* tri edge 1 */ + e2 = v0 - v2; /* tri edge 2 */ - /* Bullet 3: */ - /* test the 9 tests first (this was faster) */ - fex = fabs(e0[X]); - fey = fabs(e0[Y]); - fez = fabs(e0[Z]); + /* Bullet 3: */ + /* test the 9 tests first (this was faster) */ + fex = fabs(e0[X]); + fey = fabs(e0[Y]); + fez = fabs(e0[Z]); - AXISTEST_X01(e0[Z], e0[Y], fez, fey); - AXISTEST_Y02(e0[Z], e0[X], fez, fex); - AXISTEST_Z12(e0[Y], e0[X], fey, fex); + AXISTEST_X01(e0[Z], e0[Y], fez, fey); + AXISTEST_Y02(e0[Z], e0[X], fez, fex); + AXISTEST_Z12(e0[Y], e0[X], fey, fex); - fex = fabs(e1[X]); - fey = fabs(e1[Y]); - fez = fabs(e1[Z]); + fex = fabs(e1[X]); + fey = fabs(e1[Y]); + fez = fabs(e1[Z]); - AXISTEST_X01(e1[Z], e1[Y], fez, fey); - AXISTEST_Y02(e1[Z], e1[X], fez, fex); - AXISTEST_Z0(e1[Y], e1[X], fey, fex); + AXISTEST_X01(e1[Z], e1[Y], fez, fey); + AXISTEST_Y02(e1[Z], e1[X], fez, fex); + AXISTEST_Z0(e1[Y], e1[X], fey, fex); - fex = fabs(e2[X]); - fey = fabs(e2[Y]); - fez = fabs(e2[Z]); + fex = fabs(e2[X]); + fey = fabs(e2[Y]); + fez = fabs(e2[Z]); - AXISTEST_X2(e2[Z], e2[Y], fez, fey); - AXISTEST_Y1(e2[Z], e2[X], fez, fex); - AXISTEST_Z12(e2[Y], e2[X], fey, fex); + AXISTEST_X2(e2[Z], e2[Y], fez, fey); + AXISTEST_Y1(e2[Z], e2[X], fez, fex); + AXISTEST_Z12(e2[Y], e2[X], fey, fex); - /* Bullet 1: */ - /* first test overlap in the {x,y,z}-directions */ - /* find min, max of the triangle each direction, and test for overlap in */ - /* that direction -- this is equivalent to testing a minimal AABB around */ - /* the triangle against the AABB */ + /* Bullet 1: */ + /* first test overlap in the {x,y,z}-directions */ + /* find min, max of the triangle each direction, and test for overlap in */ + /* that direction -- this is equivalent to testing a minimal AABB around */ + /* the triangle against the AABB */ - /* test in X-direction */ - FINDMINMAX(v0[X], v1[X], v2[X], min, max); - if (min > boxhalfsize[X] || max < -boxhalfsize[X]) - return 0; + /* test in X-direction */ + FINDMINMAX(v0[X], v1[X], v2[X], min, max); + if (min > boxhalfsize[X] || max < -boxhalfsize[X]) + return 0; - /* test in Y-direction */ - FINDMINMAX(v0[Y], v1[Y], v2[Y], min, max); - if (min > boxhalfsize[Y] || max < -boxhalfsize[Y]) - return 0; + /* test in Y-direction */ + FINDMINMAX(v0[Y], v1[Y], v2[Y], min, max); + if (min > boxhalfsize[Y] || max < -boxhalfsize[Y]) + return 0; - /* test in Z-direction */ - FINDMINMAX(v0[Z], v1[Z], v2[Z], min, max); - if (min > boxhalfsize[Z] || max < -boxhalfsize[Z]) - return 0; + /* test in Z-direction */ + FINDMINMAX(v0[Z], v1[Z], v2[Z], min, max); + if (min > boxhalfsize[Z] || max < -boxhalfsize[Z]) + return 0; - /* Bullet 2: */ - /* test if the box intersects the plane of the triangle */ - /* compute plane equation of triangle: normal*x+d=0 */ - normal = e0 ^ e1; + /* Bullet 2: */ + /* test if the box intersects the plane of the triangle */ + /* compute plane equation of triangle: normal*x+d=0 */ + normal = e0 ^ e1; - if (!PlaneBoxOverlap(normal, v0, boxhalfsize)) - return 0; - return 1; /* box and triangle overlaps */ + if (!PlaneBoxOverlap(normal, v0, boxhalfsize)) + return 0; + return 1; /* box and triangle overlaps */ } // Slightly modified version of Stan Melax's code for 3x3 matrix diagonalization (Thanks Stan!) // source: http://www.melax.com/diag.html?attredirects=0 void Diagonalize(const double (&A)[3][3], double (&Q)[3][3], double (&D)[3][3]) { - // A must be a symmetric matrix. - // returns Q and D such that - // Diagonal matrix D = QT * A * Q; and A = Q*D*QT - const int maxsteps = 24; // certainly wont need that many. - int k0, k1, k2; - double o[3], m[3]; - double q[4] = { 0.0, 0.0, 0.0, 1.0 }; - double jr[4]; - double sqw, sqx, sqy, sqz; - double tmp1, tmp2, mq; - double AQ[3][3]; - double thet, sgn, t, c; - for (int i = 0; i < maxsteps; ++i) { - // quat to matrix - sqx = q[0] * q[0]; - sqy = q[1] * q[1]; - sqz = q[2] * q[2]; - sqw = q[3] * q[3]; - Q[0][0] = (sqx - sqy - sqz + sqw); - Q[1][1] = (-sqx + sqy - sqz + sqw); - Q[2][2] = (-sqx - sqy + sqz + sqw); - tmp1 = q[0] * q[1]; - tmp2 = q[2] * q[3]; - Q[1][0] = 2.0 * (tmp1 + tmp2); - Q[0][1] = 2.0 * (tmp1 - tmp2); - tmp1 = q[0] * q[2]; - tmp2 = q[1] * q[3]; - Q[2][0] = 2.0 * (tmp1 - tmp2); - Q[0][2] = 2.0 * (tmp1 + tmp2); - tmp1 = q[1] * q[2]; - tmp2 = q[0] * q[3]; - Q[2][1] = 2.0 * (tmp1 + tmp2); - Q[1][2] = 2.0 * (tmp1 - tmp2); + // A must be a symmetric matrix. + // returns Q and D such that + // Diagonal matrix D = QT * A * Q; and A = Q*D*QT + const int maxsteps = 24; // certainly wont need that many. + int k0, k1, k2; + double o[3], m[3]; + double q[4] = {0.0, 0.0, 0.0, 1.0}; + double jr[4]; + double sqw, sqx, sqy, sqz; + double tmp1, tmp2, mq; + double AQ[3][3]; + double thet, sgn, t, c; + for (int i = 0; i < maxsteps; ++i) + { + // quat to matrix + sqx = q[0] * q[0]; + sqy = q[1] * q[1]; + sqz = q[2] * q[2]; + sqw = q[3] * q[3]; + Q[0][0] = (sqx - sqy - sqz + sqw); + Q[1][1] = (-sqx + sqy - sqz + sqw); + Q[2][2] = (-sqx - sqy + sqz + sqw); + tmp1 = q[0] * q[1]; + tmp2 = q[2] * q[3]; + Q[1][0] = 2.0 * (tmp1 + tmp2); + Q[0][1] = 2.0 * (tmp1 - tmp2); + tmp1 = q[0] * q[2]; + tmp2 = q[1] * q[3]; + Q[2][0] = 2.0 * (tmp1 - tmp2); + Q[0][2] = 2.0 * (tmp1 + tmp2); + tmp1 = q[1] * q[2]; + tmp2 = q[0] * q[3]; + Q[2][1] = 2.0 * (tmp1 + tmp2); + Q[1][2] = 2.0 * (tmp1 - tmp2); - // AQ = A * Q - AQ[0][0] = Q[0][0] * A[0][0] + Q[1][0] * A[0][1] + Q[2][0] * A[0][2]; - AQ[0][1] = Q[0][1] * A[0][0] + Q[1][1] * A[0][1] + Q[2][1] * A[0][2]; - AQ[0][2] = Q[0][2] * A[0][0] + Q[1][2] * A[0][1] + Q[2][2] * A[0][2]; - AQ[1][0] = Q[0][0] * A[0][1] + Q[1][0] * A[1][1] + Q[2][0] * A[1][2]; - AQ[1][1] = Q[0][1] * A[0][1] + Q[1][1] * A[1][1] + Q[2][1] * A[1][2]; - AQ[1][2] = Q[0][2] * A[0][1] + Q[1][2] * A[1][1] + Q[2][2] * A[1][2]; - AQ[2][0] = Q[0][0] * A[0][2] + Q[1][0] * A[1][2] + Q[2][0] * A[2][2]; - AQ[2][1] = Q[0][1] * A[0][2] + Q[1][1] * A[1][2] + Q[2][1] * A[2][2]; - AQ[2][2] = Q[0][2] * A[0][2] + Q[1][2] * A[1][2] + Q[2][2] * A[2][2]; - // D = Qt * AQ - D[0][0] = AQ[0][0] * Q[0][0] + AQ[1][0] * Q[1][0] + AQ[2][0] * Q[2][0]; - D[0][1] = AQ[0][0] * Q[0][1] + AQ[1][0] * Q[1][1] + AQ[2][0] * Q[2][1]; - D[0][2] = AQ[0][0] * Q[0][2] + AQ[1][0] * Q[1][2] + AQ[2][0] * Q[2][2]; - D[1][0] = AQ[0][1] * Q[0][0] + AQ[1][1] * Q[1][0] + AQ[2][1] * Q[2][0]; - D[1][1] = AQ[0][1] * Q[0][1] + AQ[1][1] * Q[1][1] + AQ[2][1] * Q[2][1]; - D[1][2] = AQ[0][1] * Q[0][2] + AQ[1][1] * Q[1][2] + AQ[2][1] * Q[2][2]; - D[2][0] = AQ[0][2] * Q[0][0] + AQ[1][2] * Q[1][0] + AQ[2][2] * Q[2][0]; - D[2][1] = AQ[0][2] * Q[0][1] + AQ[1][2] * Q[1][1] + AQ[2][2] * Q[2][1]; - D[2][2] = AQ[0][2] * Q[0][2] + AQ[1][2] * Q[1][2] + AQ[2][2] * Q[2][2]; - o[0] = D[1][2]; - o[1] = D[0][2]; - o[2] = D[0][1]; - m[0] = fabs(o[0]); - m[1] = fabs(o[1]); - m[2] = fabs(o[2]); + // AQ = A * Q + AQ[0][0] = Q[0][0] * A[0][0] + Q[1][0] * A[0][1] + Q[2][0] * A[0][2]; + AQ[0][1] = Q[0][1] * A[0][0] + Q[1][1] * A[0][1] + Q[2][1] * A[0][2]; + AQ[0][2] = Q[0][2] * A[0][0] + Q[1][2] * A[0][1] + Q[2][2] * A[0][2]; + AQ[1][0] = Q[0][0] * A[0][1] + Q[1][0] * A[1][1] + Q[2][0] * A[1][2]; + AQ[1][1] = Q[0][1] * A[0][1] + Q[1][1] * A[1][1] + Q[2][1] * A[1][2]; + AQ[1][2] = Q[0][2] * A[0][1] + Q[1][2] * A[1][1] + Q[2][2] * A[1][2]; + AQ[2][0] = Q[0][0] * A[0][2] + Q[1][0] * A[1][2] + Q[2][0] * A[2][2]; + AQ[2][1] = Q[0][1] * A[0][2] + Q[1][1] * A[1][2] + Q[2][1] * A[2][2]; + AQ[2][2] = Q[0][2] * A[0][2] + Q[1][2] * A[1][2] + Q[2][2] * A[2][2]; + // D = Qt * AQ + D[0][0] = AQ[0][0] * Q[0][0] + AQ[1][0] * Q[1][0] + AQ[2][0] * Q[2][0]; + D[0][1] = AQ[0][0] * Q[0][1] + AQ[1][0] * Q[1][1] + AQ[2][0] * Q[2][1]; + D[0][2] = AQ[0][0] * Q[0][2] + AQ[1][0] * Q[1][2] + AQ[2][0] * Q[2][2]; + D[1][0] = AQ[0][1] * Q[0][0] + AQ[1][1] * Q[1][0] + AQ[2][1] * Q[2][0]; + D[1][1] = AQ[0][1] * Q[0][1] + AQ[1][1] * Q[1][1] + AQ[2][1] * Q[2][1]; + D[1][2] = AQ[0][1] * Q[0][2] + AQ[1][1] * Q[1][2] + AQ[2][1] * Q[2][2]; + D[2][0] = AQ[0][2] * Q[0][0] + AQ[1][2] * Q[1][0] + AQ[2][2] * Q[2][0]; + D[2][1] = AQ[0][2] * Q[0][1] + AQ[1][2] * Q[1][1] + AQ[2][2] * Q[2][1]; + D[2][2] = AQ[0][2] * Q[0][2] + AQ[1][2] * Q[1][2] + AQ[2][2] * Q[2][2]; + o[0] = D[1][2]; + o[1] = D[0][2]; + o[2] = D[0][1]; + m[0] = fabs(o[0]); + m[1] = fabs(o[1]); + m[2] = fabs(o[2]); - k0 = (m[0] > m[1] && m[0] > m[2]) ? 0 : (m[1] > m[2]) ? 1 : 2; // index of largest element of offdiag - k1 = (k0 + 1) % 3; - k2 = (k0 + 2) % 3; - if (o[k0] == 0.0) { - break; // diagonal already - } - thet = (D[k2][k2] - D[k1][k1]) / (2.0 * o[k0]); - sgn = (thet > 0.0) ? 1.0 : -1.0; - thet *= sgn; // make it positive - t = sgn / (thet + ((thet < 1.E6) ? sqrt(thet * thet + 1.0) : thet)); // sign(T)/(|T|+sqrt(T^2+1)) - c = 1.0 / sqrt(t * t + 1.0); // c= 1/(t^2+1) , t=s/c - if (c == 1.0) { - break; // no room for improvement - reached machine precision. - } - jr[0] = jr[1] = jr[2] = jr[3] = 0.0; - jr[k0] = sgn * sqrt((1.0 - c) / 2.0); // using 1/2 angle identity sin(a/2) = sqrt((1-cos(a))/2) - jr[k0] *= -1.0; // since our quat-to-matrix convention was for v*M instead of M*v - jr[3] = sqrt(1.0 - jr[k0] * jr[k0]); - if (jr[3] == 1.0) { - break; // reached limits of floating point precision - } - q[0] = (q[3] * jr[0] + q[0] * jr[3] + q[1] * jr[2] - q[2] * jr[1]); - q[1] = (q[3] * jr[1] - q[0] * jr[2] + q[1] * jr[3] + q[2] * jr[0]); - q[2] = (q[3] * jr[2] + q[0] * jr[1] - q[1] * jr[0] + q[2] * jr[3]); - q[3] = (q[3] * jr[3] - q[0] * jr[0] - q[1] * jr[1] - q[2] * jr[2]); - mq = sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]); - q[0] /= mq; - q[1] /= mq; - q[2] /= mq; - q[3] /= mq; - } + k0 = (m[0] > m[1] && m[0] > m[2]) ? 0 : (m[1] > m[2]) ? 1 : 2; // index of largest element of offdiag + k1 = (k0 + 1) % 3; + k2 = (k0 + 2) % 3; + if (o[k0] == 0.0) + { + break; // diagonal already + } + thet = (D[k2][k2] - D[k1][k1]) / (2.0 * o[k0]); + sgn = (thet > 0.0) ? 1.0 : -1.0; + thet *= sgn; // make it positive + t = sgn / (thet + ((thet < 1.E6) ? sqrt(thet * thet + 1.0) : thet)); // sign(T)/(|T|+sqrt(T^2+1)) + c = 1.0 / sqrt(t * t + 1.0); // c= 1/(t^2+1) , t=s/c + if (c == 1.0) + { + break; // no room for improvement - reached machine precision. + } + jr[0] = jr[1] = jr[2] = jr[3] = 0.0; + jr[k0] = sgn * sqrt((1.0 - c) / 2.0); // using 1/2 angle identity sin(a/2) = sqrt((1-cos(a))/2) + jr[k0] *= -1.0; // since our quat-to-matrix convention was for v*M instead of M*v + jr[3] = sqrt(1.0 - jr[k0] * jr[k0]); + if (jr[3] == 1.0) + { + break; // reached limits of floating point precision + } + q[0] = (q[3] * jr[0] + q[0] * jr[3] + q[1] * jr[2] - q[2] * jr[1]); + q[1] = (q[3] * jr[1] - q[0] * jr[2] + q[1] * jr[3] + q[2] * jr[0]); + q[2] = (q[3] * jr[2] + q[0] * jr[1] - q[1] * jr[0] + q[2] * jr[3]); + q[3] = (q[3] * jr[3] - q[0] * jr[0] - q[1] * jr[1] - q[2] * jr[2]); + mq = sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]); + q[0] /= mq; + q[1] /= mq; + q[2] /= mq; + q[3] /= mq; + } } const double TetrahedronSet::EPS = 0.0000000000001; VoxelSet::VoxelSet() { - m_minBB[0] = m_minBB[1] = m_minBB[2] = 0.0; - m_minBBVoxels[0] = m_minBBVoxels[1] = m_minBBVoxels[2] = 0; - m_maxBBVoxels[0] = m_maxBBVoxels[1] = m_maxBBVoxels[2] = 1; - m_minBBPts[0] = m_minBBPts[1] = m_minBBPts[2] = 0; - m_maxBBPts[0] = m_maxBBPts[1] = m_maxBBPts[2] = 1; - m_barycenter[0] = m_barycenter[1] = m_barycenter[2] = 0; - m_barycenterPCA[0] = m_barycenterPCA[1] = m_barycenterPCA[2] = 0.0; - m_scale = 1.0; - m_unitVolume = 1.0; - m_numVoxelsOnSurface = 0; - m_numVoxelsInsideSurface = 0; - memset(m_Q, 0, sizeof(double) * 9); - memset(m_D, 0, sizeof(double) * 9); + m_minBB[0] = m_minBB[1] = m_minBB[2] = 0.0; + m_minBBVoxels[0] = m_minBBVoxels[1] = m_minBBVoxels[2] = 0; + m_maxBBVoxels[0] = m_maxBBVoxels[1] = m_maxBBVoxels[2] = 1; + m_minBBPts[0] = m_minBBPts[1] = m_minBBPts[2] = 0; + m_maxBBPts[0] = m_maxBBPts[1] = m_maxBBPts[2] = 1; + m_barycenter[0] = m_barycenter[1] = m_barycenter[2] = 0; + m_barycenterPCA[0] = m_barycenterPCA[1] = m_barycenterPCA[2] = 0.0; + m_scale = 1.0; + m_unitVolume = 1.0; + m_numVoxelsOnSurface = 0; + m_numVoxelsInsideSurface = 0; + memset(m_Q, 0, sizeof(double) * 9); + memset(m_D, 0, sizeof(double) * 9); } VoxelSet::~VoxelSet(void) { } void VoxelSet::ComputeBB() { - const size_t nVoxels = m_voxels.Size(); - if (nVoxels == 0) - return; - for (int h = 0; h < 3; ++h) { - m_minBBVoxels[h] = m_voxels[0].m_coord[h]; - m_maxBBVoxels[h] = m_voxels[0].m_coord[h]; - } - Vec3 bary(0.0); - for (size_t p = 0; p < nVoxels; ++p) { - for (int h = 0; h < 3; ++h) { - bary[h] += m_voxels[p].m_coord[h]; - if (m_minBBVoxels[h] > m_voxels[p].m_coord[h]) - m_minBBVoxels[h] = m_voxels[p].m_coord[h]; - if (m_maxBBVoxels[h] < m_voxels[p].m_coord[h]) - m_maxBBVoxels[h] = m_voxels[p].m_coord[h]; - } - } - bary /= (double)nVoxels; - for (int h = 0; h < 3; ++h) { - m_minBBPts[h] = m_minBBVoxels[h] * m_scale + m_minBB[h]; - m_maxBBPts[h] = m_maxBBVoxels[h] * m_scale + m_minBB[h]; - m_barycenter[h] = (short)(bary[h] + 0.5); - } + const size_t nVoxels = m_voxels.Size(); + if (nVoxels == 0) + return; + for (int h = 0; h < 3; ++h) + { + m_minBBVoxels[h] = m_voxels[0].m_coord[h]; + m_maxBBVoxels[h] = m_voxels[0].m_coord[h]; + } + Vec3 bary(0.0); + for (size_t p = 0; p < nVoxels; ++p) + { + for (int h = 0; h < 3; ++h) + { + bary[h] += m_voxels[p].m_coord[h]; + if (m_minBBVoxels[h] > m_voxels[p].m_coord[h]) + m_minBBVoxels[h] = m_voxels[p].m_coord[h]; + if (m_maxBBVoxels[h] < m_voxels[p].m_coord[h]) + m_maxBBVoxels[h] = m_voxels[p].m_coord[h]; + } + } + bary /= (double)nVoxels; + for (int h = 0; h < 3; ++h) + { + m_minBBPts[h] = m_minBBVoxels[h] * m_scale + m_minBB[h]; + m_maxBBPts[h] = m_maxBBVoxels[h] * m_scale + m_minBB[h]; + m_barycenter[h] = (short)(bary[h] + 0.5); + } } void VoxelSet::ComputeConvexHull(Mesh& meshCH, const size_t sampling) const { - const size_t CLUSTER_SIZE = 65536; - const size_t nVoxels = m_voxels.Size(); - if (nVoxels == 0) - return; + const size_t CLUSTER_SIZE = 65536; + const size_t nVoxels = m_voxels.Size(); + if (nVoxels == 0) + return; - SArray > cpoints; + SArray > cpoints; - Vec3* points = new Vec3[CLUSTER_SIZE]; - size_t p = 0; - size_t s = 0; - short i, j, k; - while (p < nVoxels) { - size_t q = 0; - while (q < CLUSTER_SIZE && p < nVoxels) { - if (m_voxels[p].m_data == PRIMITIVE_ON_SURFACE) { - ++s; - if (s == sampling) { - s = 0; - i = m_voxels[p].m_coord[0]; - j = m_voxels[p].m_coord[1]; - k = m_voxels[p].m_coord[2]; - Vec3 p0((i - 0.5) * m_scale, (j - 0.5) * m_scale, (k - 0.5) * m_scale); - Vec3 p1((i + 0.5) * m_scale, (j - 0.5) * m_scale, (k - 0.5) * m_scale); - Vec3 p2((i + 0.5) * m_scale, (j + 0.5) * m_scale, (k - 0.5) * m_scale); - Vec3 p3((i - 0.5) * m_scale, (j + 0.5) * m_scale, (k - 0.5) * m_scale); - Vec3 p4((i - 0.5) * m_scale, (j - 0.5) * m_scale, (k + 0.5) * m_scale); - Vec3 p5((i + 0.5) * m_scale, (j - 0.5) * m_scale, (k + 0.5) * m_scale); - Vec3 p6((i + 0.5) * m_scale, (j + 0.5) * m_scale, (k + 0.5) * m_scale); - Vec3 p7((i - 0.5) * m_scale, (j + 0.5) * m_scale, (k + 0.5) * m_scale); - points[q++] = p0 + m_minBB; - points[q++] = p1 + m_minBB; - points[q++] = p2 + m_minBB; - points[q++] = p3 + m_minBB; - points[q++] = p4 + m_minBB; - points[q++] = p5 + m_minBB; - points[q++] = p6 + m_minBB; - points[q++] = p7 + m_minBB; - } - } - ++p; - } - btConvexHullComputer ch; - ch.compute((double*)points, 3 * sizeof(double), (int)q, -1.0, -1.0); - for (int v = 0; v < ch.vertices.size(); v++) { - cpoints.PushBack(Vec3(ch.vertices[v].getX(), ch.vertices[v].getY(), ch.vertices[v].getZ())); - } - } - delete[] points; + Vec3* points = new Vec3[CLUSTER_SIZE]; + size_t p = 0; + size_t s = 0; + short i, j, k; + while (p < nVoxels) + { + size_t q = 0; + while (q < CLUSTER_SIZE && p < nVoxels) + { + if (m_voxels[p].m_data == PRIMITIVE_ON_SURFACE) + { + ++s; + if (s == sampling) + { + s = 0; + i = m_voxels[p].m_coord[0]; + j = m_voxels[p].m_coord[1]; + k = m_voxels[p].m_coord[2]; + Vec3 p0((i - 0.5) * m_scale, (j - 0.5) * m_scale, (k - 0.5) * m_scale); + Vec3 p1((i + 0.5) * m_scale, (j - 0.5) * m_scale, (k - 0.5) * m_scale); + Vec3 p2((i + 0.5) * m_scale, (j + 0.5) * m_scale, (k - 0.5) * m_scale); + Vec3 p3((i - 0.5) * m_scale, (j + 0.5) * m_scale, (k - 0.5) * m_scale); + Vec3 p4((i - 0.5) * m_scale, (j - 0.5) * m_scale, (k + 0.5) * m_scale); + Vec3 p5((i + 0.5) * m_scale, (j - 0.5) * m_scale, (k + 0.5) * m_scale); + Vec3 p6((i + 0.5) * m_scale, (j + 0.5) * m_scale, (k + 0.5) * m_scale); + Vec3 p7((i - 0.5) * m_scale, (j + 0.5) * m_scale, (k + 0.5) * m_scale); + points[q++] = p0 + m_minBB; + points[q++] = p1 + m_minBB; + points[q++] = p2 + m_minBB; + points[q++] = p3 + m_minBB; + points[q++] = p4 + m_minBB; + points[q++] = p5 + m_minBB; + points[q++] = p6 + m_minBB; + points[q++] = p7 + m_minBB; + } + } + ++p; + } + btConvexHullComputer ch; + ch.compute((double*)points, 3 * sizeof(double), (int)q, -1.0, -1.0); + for (int v = 0; v < ch.vertices.size(); v++) + { + cpoints.PushBack(Vec3(ch.vertices[v].getX(), ch.vertices[v].getY(), ch.vertices[v].getZ())); + } + } + delete[] points; - points = cpoints.Data(); - btConvexHullComputer ch; - ch.compute((double*)points, 3 * sizeof(double), (int)cpoints.Size(), -1.0, -1.0); - meshCH.ResizePoints(0); - meshCH.ResizeTriangles(0); - for (int v = 0; v < ch.vertices.size(); v++) { - meshCH.AddPoint(Vec3(ch.vertices[v].getX(), ch.vertices[v].getY(), ch.vertices[v].getZ())); - } - const int nt = ch.faces.size(); - for (int t = 0; t < nt; ++t) { - const btConvexHullComputer::Edge* sourceEdge = &(ch.edges[ch.faces[t]]); - int a = sourceEdge->getSourceVertex(); - int b = sourceEdge->getTargetVertex(); - const btConvexHullComputer::Edge* edge = sourceEdge->getNextEdgeOfFace(); - int c = edge->getTargetVertex(); - while (c != a) { - meshCH.AddTriangle(Vec3(a, b, c)); - edge = edge->getNextEdgeOfFace(); - b = c; - c = edge->getTargetVertex(); - } - } + points = cpoints.Data(); + btConvexHullComputer ch; + ch.compute((double*)points, 3 * sizeof(double), (int)cpoints.Size(), -1.0, -1.0); + meshCH.ResizePoints(0); + meshCH.ResizeTriangles(0); + for (int v = 0; v < ch.vertices.size(); v++) + { + meshCH.AddPoint(Vec3(ch.vertices[v].getX(), ch.vertices[v].getY(), ch.vertices[v].getZ())); + } + const int nt = ch.faces.size(); + for (int t = 0; t < nt; ++t) + { + const btConvexHullComputer::Edge* sourceEdge = &(ch.edges[ch.faces[t]]); + int a = sourceEdge->getSourceVertex(); + int b = sourceEdge->getTargetVertex(); + const btConvexHullComputer::Edge* edge = sourceEdge->getNextEdgeOfFace(); + int c = edge->getTargetVertex(); + while (c != a) + { + meshCH.AddTriangle(Vec3(a, b, c)); + edge = edge->getNextEdgeOfFace(); + b = c; + c = edge->getTargetVertex(); + } + } } void VoxelSet::GetPoints(const Voxel& voxel, - Vec3* const pts) const + Vec3* const pts) const { - short i = voxel.m_coord[0]; - short j = voxel.m_coord[1]; - short k = voxel.m_coord[2]; - pts[0][0] = (i - 0.5) * m_scale + m_minBB[0]; - pts[1][0] = (i + 0.5) * m_scale + m_minBB[0]; - pts[2][0] = (i + 0.5) * m_scale + m_minBB[0]; - pts[3][0] = (i - 0.5) * m_scale + m_minBB[0]; - pts[4][0] = (i - 0.5) * m_scale + m_minBB[0]; - pts[5][0] = (i + 0.5) * m_scale + m_minBB[0]; - pts[6][0] = (i + 0.5) * m_scale + m_minBB[0]; - pts[7][0] = (i - 0.5) * m_scale + m_minBB[0]; - pts[0][1] = (j - 0.5) * m_scale + m_minBB[1]; - pts[1][1] = (j - 0.5) * m_scale + m_minBB[1]; - pts[2][1] = (j + 0.5) * m_scale + m_minBB[1]; - pts[3][1] = (j + 0.5) * m_scale + m_minBB[1]; - pts[4][1] = (j - 0.5) * m_scale + m_minBB[1]; - pts[5][1] = (j - 0.5) * m_scale + m_minBB[1]; - pts[6][1] = (j + 0.5) * m_scale + m_minBB[1]; - pts[7][1] = (j + 0.5) * m_scale + m_minBB[1]; - pts[0][2] = (k - 0.5) * m_scale + m_minBB[2]; - pts[1][2] = (k - 0.5) * m_scale + m_minBB[2]; - pts[2][2] = (k - 0.5) * m_scale + m_minBB[2]; - pts[3][2] = (k - 0.5) * m_scale + m_minBB[2]; - pts[4][2] = (k + 0.5) * m_scale + m_minBB[2]; - pts[5][2] = (k + 0.5) * m_scale + m_minBB[2]; - pts[6][2] = (k + 0.5) * m_scale + m_minBB[2]; - pts[7][2] = (k + 0.5) * m_scale + m_minBB[2]; + short i = voxel.m_coord[0]; + short j = voxel.m_coord[1]; + short k = voxel.m_coord[2]; + pts[0][0] = (i - 0.5) * m_scale + m_minBB[0]; + pts[1][0] = (i + 0.5) * m_scale + m_minBB[0]; + pts[2][0] = (i + 0.5) * m_scale + m_minBB[0]; + pts[3][0] = (i - 0.5) * m_scale + m_minBB[0]; + pts[4][0] = (i - 0.5) * m_scale + m_minBB[0]; + pts[5][0] = (i + 0.5) * m_scale + m_minBB[0]; + pts[6][0] = (i + 0.5) * m_scale + m_minBB[0]; + pts[7][0] = (i - 0.5) * m_scale + m_minBB[0]; + pts[0][1] = (j - 0.5) * m_scale + m_minBB[1]; + pts[1][1] = (j - 0.5) * m_scale + m_minBB[1]; + pts[2][1] = (j + 0.5) * m_scale + m_minBB[1]; + pts[3][1] = (j + 0.5) * m_scale + m_minBB[1]; + pts[4][1] = (j - 0.5) * m_scale + m_minBB[1]; + pts[5][1] = (j - 0.5) * m_scale + m_minBB[1]; + pts[6][1] = (j + 0.5) * m_scale + m_minBB[1]; + pts[7][1] = (j + 0.5) * m_scale + m_minBB[1]; + pts[0][2] = (k - 0.5) * m_scale + m_minBB[2]; + pts[1][2] = (k - 0.5) * m_scale + m_minBB[2]; + pts[2][2] = (k - 0.5) * m_scale + m_minBB[2]; + pts[3][2] = (k - 0.5) * m_scale + m_minBB[2]; + pts[4][2] = (k + 0.5) * m_scale + m_minBB[2]; + pts[5][2] = (k + 0.5) * m_scale + m_minBB[2]; + pts[6][2] = (k + 0.5) * m_scale + m_minBB[2]; + pts[7][2] = (k + 0.5) * m_scale + m_minBB[2]; } void VoxelSet::Intersect(const Plane& plane, - SArray >* const positivePts, - SArray >* const negativePts, - const size_t sampling) const + SArray >* const positivePts, + SArray >* const negativePts, + const size_t sampling) const { - const size_t nVoxels = m_voxels.Size(); - if (nVoxels == 0) - return; - const double d0 = m_scale; - double d; - Vec3 pts[8]; - Vec3 pt; - Voxel voxel; - size_t sp = 0; - size_t sn = 0; - for (size_t v = 0; v < nVoxels; ++v) { - voxel = m_voxels[v]; - pt = GetPoint(voxel); - d = plane.m_a * pt[0] + plane.m_b * pt[1] + plane.m_c * pt[2] + plane.m_d; - // if (d >= 0.0 && d <= d0) positivePts->PushBack(pt); - // else if (d < 0.0 && -d <= d0) negativePts->PushBack(pt); - if (d >= 0.0) { - if (d <= d0) { - GetPoints(voxel, pts); - for (int k = 0; k < 8; ++k) { - positivePts->PushBack(pts[k]); - } - } - else { - if (++sp == sampling) { - // positivePts->PushBack(pt); - GetPoints(voxel, pts); - for (int k = 0; k < 8; ++k) { - positivePts->PushBack(pts[k]); - } - sp = 0; - } - } - } - else { - if (-d <= d0) { - GetPoints(voxel, pts); - for (int k = 0; k < 8; ++k) { - negativePts->PushBack(pts[k]); - } - } - else { - if (++sn == sampling) { - // negativePts->PushBack(pt); - GetPoints(voxel, pts); - for (int k = 0; k < 8; ++k) { - negativePts->PushBack(pts[k]); - } - sn = 0; - } - } - } - } + const size_t nVoxels = m_voxels.Size(); + if (nVoxels == 0) + return; + const double d0 = m_scale; + double d; + Vec3 pts[8]; + Vec3 pt; + Voxel voxel; + size_t sp = 0; + size_t sn = 0; + for (size_t v = 0; v < nVoxels; ++v) + { + voxel = m_voxels[v]; + pt = GetPoint(voxel); + d = plane.m_a * pt[0] + plane.m_b * pt[1] + plane.m_c * pt[2] + plane.m_d; + // if (d >= 0.0 && d <= d0) positivePts->PushBack(pt); + // else if (d < 0.0 && -d <= d0) negativePts->PushBack(pt); + if (d >= 0.0) + { + if (d <= d0) + { + GetPoints(voxel, pts); + for (int k = 0; k < 8; ++k) + { + positivePts->PushBack(pts[k]); + } + } + else + { + if (++sp == sampling) + { + // positivePts->PushBack(pt); + GetPoints(voxel, pts); + for (int k = 0; k < 8; ++k) + { + positivePts->PushBack(pts[k]); + } + sp = 0; + } + } + } + else + { + if (-d <= d0) + { + GetPoints(voxel, pts); + for (int k = 0; k < 8; ++k) + { + negativePts->PushBack(pts[k]); + } + } + else + { + if (++sn == sampling) + { + // negativePts->PushBack(pt); + GetPoints(voxel, pts); + for (int k = 0; k < 8; ++k) + { + negativePts->PushBack(pts[k]); + } + sn = 0; + } + } + } + } } void VoxelSet::ComputeExteriorPoints(const Plane& plane, - const Mesh& mesh, - SArray >* const exteriorPts) const + const Mesh& mesh, + SArray >* const exteriorPts) const { - const size_t nVoxels = m_voxels.Size(); - if (nVoxels == 0) - return; - double d; - Vec3 pt; - Vec3 pts[8]; - Voxel voxel; - for (size_t v = 0; v < nVoxels; ++v) { - voxel = m_voxels[v]; - pt = GetPoint(voxel); - d = plane.m_a * pt[0] + plane.m_b * pt[1] + plane.m_c * pt[2] + plane.m_d; - if (d >= 0.0) { - if (!mesh.IsInside(pt)) { - GetPoints(voxel, pts); - for (int k = 0; k < 8; ++k) { - exteriorPts->PushBack(pts[k]); - } - } - } - } + const size_t nVoxels = m_voxels.Size(); + if (nVoxels == 0) + return; + double d; + Vec3 pt; + Vec3 pts[8]; + Voxel voxel; + for (size_t v = 0; v < nVoxels; ++v) + { + voxel = m_voxels[v]; + pt = GetPoint(voxel); + d = plane.m_a * pt[0] + plane.m_b * pt[1] + plane.m_c * pt[2] + plane.m_d; + if (d >= 0.0) + { + if (!mesh.IsInside(pt)) + { + GetPoints(voxel, pts); + for (int k = 0; k < 8; ++k) + { + exteriorPts->PushBack(pts[k]); + } + } + } + } } void VoxelSet::ComputeClippedVolumes(const Plane& plane, - double& positiveVolume, - double& negativeVolume) const + double& positiveVolume, + double& negativeVolume) const { - negativeVolume = 0.0; - positiveVolume = 0.0; - const size_t nVoxels = m_voxels.Size(); - if (nVoxels == 0) - return; - double d; - Vec3 pt; - size_t nPositiveVoxels = 0; - for (size_t v = 0; v < nVoxels; ++v) { - pt = GetPoint(m_voxels[v]); - d = plane.m_a * pt[0] + plane.m_b * pt[1] + plane.m_c * pt[2] + plane.m_d; - nPositiveVoxels += (d >= 0.0); - } - size_t nNegativeVoxels = nVoxels - nPositiveVoxels; - positiveVolume = m_unitVolume * nPositiveVoxels; - negativeVolume = m_unitVolume * nNegativeVoxels; + negativeVolume = 0.0; + positiveVolume = 0.0; + const size_t nVoxels = m_voxels.Size(); + if (nVoxels == 0) + return; + double d; + Vec3 pt; + size_t nPositiveVoxels = 0; + for (size_t v = 0; v < nVoxels; ++v) + { + pt = GetPoint(m_voxels[v]); + d = plane.m_a * pt[0] + plane.m_b * pt[1] + plane.m_c * pt[2] + plane.m_d; + nPositiveVoxels += (d >= 0.0); + } + size_t nNegativeVoxels = nVoxels - nPositiveVoxels; + positiveVolume = m_unitVolume * nPositiveVoxels; + negativeVolume = m_unitVolume * nNegativeVoxels; } void VoxelSet::SelectOnSurface(PrimitiveSet* const onSurfP) const { - VoxelSet* const onSurf = (VoxelSet*)onSurfP; - const size_t nVoxels = m_voxels.Size(); - if (nVoxels == 0) - return; + VoxelSet* const onSurf = (VoxelSet*)onSurfP; + const size_t nVoxels = m_voxels.Size(); + if (nVoxels == 0) + return; - for (int h = 0; h < 3; ++h) { - onSurf->m_minBB[h] = m_minBB[h]; - } - onSurf->m_voxels.Resize(0); - onSurf->m_scale = m_scale; - onSurf->m_unitVolume = m_unitVolume; - onSurf->m_numVoxelsOnSurface = 0; - onSurf->m_numVoxelsInsideSurface = 0; - Voxel voxel; - for (size_t v = 0; v < nVoxels; ++v) { - voxel = m_voxels[v]; - if (voxel.m_data == PRIMITIVE_ON_SURFACE) { - onSurf->m_voxels.PushBack(voxel); - ++onSurf->m_numVoxelsOnSurface; - } - } + for (int h = 0; h < 3; ++h) + { + onSurf->m_minBB[h] = m_minBB[h]; + } + onSurf->m_voxels.Resize(0); + onSurf->m_scale = m_scale; + onSurf->m_unitVolume = m_unitVolume; + onSurf->m_numVoxelsOnSurface = 0; + onSurf->m_numVoxelsInsideSurface = 0; + Voxel voxel; + for (size_t v = 0; v < nVoxels; ++v) + { + voxel = m_voxels[v]; + if (voxel.m_data == PRIMITIVE_ON_SURFACE) + { + onSurf->m_voxels.PushBack(voxel); + ++onSurf->m_numVoxelsOnSurface; + } + } } void VoxelSet::Clip(const Plane& plane, - PrimitiveSet* const positivePartP, - PrimitiveSet* const negativePartP) const + PrimitiveSet* const positivePartP, + PrimitiveSet* const negativePartP) const { - VoxelSet* const positivePart = (VoxelSet*)positivePartP; - VoxelSet* const negativePart = (VoxelSet*)negativePartP; - const size_t nVoxels = m_voxels.Size(); - if (nVoxels == 0) - return; + VoxelSet* const positivePart = (VoxelSet*)positivePartP; + VoxelSet* const negativePart = (VoxelSet*)negativePartP; + const size_t nVoxels = m_voxels.Size(); + if (nVoxels == 0) + return; - for (int h = 0; h < 3; ++h) { - negativePart->m_minBB[h] = positivePart->m_minBB[h] = m_minBB[h]; - } - positivePart->m_voxels.Resize(0); - negativePart->m_voxels.Resize(0); - positivePart->m_voxels.Allocate(nVoxels); - negativePart->m_voxels.Allocate(nVoxels); - negativePart->m_scale = positivePart->m_scale = m_scale; - negativePart->m_unitVolume = positivePart->m_unitVolume = m_unitVolume; - negativePart->m_numVoxelsOnSurface = positivePart->m_numVoxelsOnSurface = 0; - negativePart->m_numVoxelsInsideSurface = positivePart->m_numVoxelsInsideSurface = 0; + for (int h = 0; h < 3; ++h) + { + negativePart->m_minBB[h] = positivePart->m_minBB[h] = m_minBB[h]; + } + positivePart->m_voxels.Resize(0); + negativePart->m_voxels.Resize(0); + positivePart->m_voxels.Allocate(nVoxels); + negativePart->m_voxels.Allocate(nVoxels); + negativePart->m_scale = positivePart->m_scale = m_scale; + negativePart->m_unitVolume = positivePart->m_unitVolume = m_unitVolume; + negativePart->m_numVoxelsOnSurface = positivePart->m_numVoxelsOnSurface = 0; + negativePart->m_numVoxelsInsideSurface = positivePart->m_numVoxelsInsideSurface = 0; - double d; - Vec3 pt; - Voxel voxel; - const double d0 = m_scale; - for (size_t v = 0; v < nVoxels; ++v) { - voxel = m_voxels[v]; - pt = GetPoint(voxel); - d = plane.m_a * pt[0] + plane.m_b * pt[1] + plane.m_c * pt[2] + plane.m_d; - if (d >= 0.0) { - if (voxel.m_data == PRIMITIVE_ON_SURFACE || d <= d0) { - voxel.m_data = PRIMITIVE_ON_SURFACE; - positivePart->m_voxels.PushBack(voxel); - ++positivePart->m_numVoxelsOnSurface; - } - else { - positivePart->m_voxels.PushBack(voxel); - ++positivePart->m_numVoxelsInsideSurface; - } - } - else { - if (voxel.m_data == PRIMITIVE_ON_SURFACE || -d <= d0) { - voxel.m_data = PRIMITIVE_ON_SURFACE; - negativePart->m_voxels.PushBack(voxel); - ++negativePart->m_numVoxelsOnSurface; - } - else { - negativePart->m_voxels.PushBack(voxel); - ++negativePart->m_numVoxelsInsideSurface; - } - } - } + double d; + Vec3 pt; + Voxel voxel; + const double d0 = m_scale; + for (size_t v = 0; v < nVoxels; ++v) + { + voxel = m_voxels[v]; + pt = GetPoint(voxel); + d = plane.m_a * pt[0] + plane.m_b * pt[1] + plane.m_c * pt[2] + plane.m_d; + if (d >= 0.0) + { + if (voxel.m_data == PRIMITIVE_ON_SURFACE || d <= d0) + { + voxel.m_data = PRIMITIVE_ON_SURFACE; + positivePart->m_voxels.PushBack(voxel); + ++positivePart->m_numVoxelsOnSurface; + } + else + { + positivePart->m_voxels.PushBack(voxel); + ++positivePart->m_numVoxelsInsideSurface; + } + } + else + { + if (voxel.m_data == PRIMITIVE_ON_SURFACE || -d <= d0) + { + voxel.m_data = PRIMITIVE_ON_SURFACE; + negativePart->m_voxels.PushBack(voxel); + ++negativePart->m_numVoxelsOnSurface; + } + else + { + negativePart->m_voxels.PushBack(voxel); + ++negativePart->m_numVoxelsInsideSurface; + } + } + } } void VoxelSet::Convert(Mesh& mesh, const VOXEL_VALUE value) const { - const size_t nVoxels = m_voxels.Size(); - if (nVoxels == 0) - return; - Voxel voxel; - Vec3 pts[8]; - for (size_t v = 0; v < nVoxels; ++v) { - voxel = m_voxels[v]; - if (voxel.m_data == value) { - GetPoints(voxel, pts); - int s = (int)mesh.GetNPoints(); - for (int k = 0; k < 8; ++k) { - mesh.AddPoint(pts[k]); - } - mesh.AddTriangle(Vec3(s + 0, s + 2, s + 1)); - mesh.AddTriangle(Vec3(s + 0, s + 3, s + 2)); - mesh.AddTriangle(Vec3(s + 4, s + 5, s + 6)); - mesh.AddTriangle(Vec3(s + 4, s + 6, s + 7)); - mesh.AddTriangle(Vec3(s + 7, s + 6, s + 2)); - mesh.AddTriangle(Vec3(s + 7, s + 2, s + 3)); - mesh.AddTriangle(Vec3(s + 4, s + 1, s + 5)); - mesh.AddTriangle(Vec3(s + 4, s + 0, s + 1)); - mesh.AddTriangle(Vec3(s + 6, s + 5, s + 1)); - mesh.AddTriangle(Vec3(s + 6, s + 1, s + 2)); - mesh.AddTriangle(Vec3(s + 7, s + 0, s + 4)); - mesh.AddTriangle(Vec3(s + 7, s + 3, s + 0)); - } - } + const size_t nVoxels = m_voxels.Size(); + if (nVoxels == 0) + return; + Voxel voxel; + Vec3 pts[8]; + for (size_t v = 0; v < nVoxels; ++v) + { + voxel = m_voxels[v]; + if (voxel.m_data == value) + { + GetPoints(voxel, pts); + int s = (int)mesh.GetNPoints(); + for (int k = 0; k < 8; ++k) + { + mesh.AddPoint(pts[k]); + } + mesh.AddTriangle(Vec3(s + 0, s + 2, s + 1)); + mesh.AddTriangle(Vec3(s + 0, s + 3, s + 2)); + mesh.AddTriangle(Vec3(s + 4, s + 5, s + 6)); + mesh.AddTriangle(Vec3(s + 4, s + 6, s + 7)); + mesh.AddTriangle(Vec3(s + 7, s + 6, s + 2)); + mesh.AddTriangle(Vec3(s + 7, s + 2, s + 3)); + mesh.AddTriangle(Vec3(s + 4, s + 1, s + 5)); + mesh.AddTriangle(Vec3(s + 4, s + 0, s + 1)); + mesh.AddTriangle(Vec3(s + 6, s + 5, s + 1)); + mesh.AddTriangle(Vec3(s + 6, s + 1, s + 2)); + mesh.AddTriangle(Vec3(s + 7, s + 0, s + 4)); + mesh.AddTriangle(Vec3(s + 7, s + 3, s + 0)); + } + } } void VoxelSet::ComputePrincipalAxes() { - const size_t nVoxels = m_voxels.Size(); - if (nVoxels == 0) - return; - m_barycenterPCA[0] = m_barycenterPCA[1] = m_barycenterPCA[2] = 0.0; - for (size_t v = 0; v < nVoxels; ++v) { - Voxel& voxel = m_voxels[v]; - m_barycenterPCA[0] += voxel.m_coord[0]; - m_barycenterPCA[1] += voxel.m_coord[1]; - m_barycenterPCA[2] += voxel.m_coord[2]; - } - m_barycenterPCA /= (double)nVoxels; + const size_t nVoxels = m_voxels.Size(); + if (nVoxels == 0) + return; + m_barycenterPCA[0] = m_barycenterPCA[1] = m_barycenterPCA[2] = 0.0; + for (size_t v = 0; v < nVoxels; ++v) + { + Voxel& voxel = m_voxels[v]; + m_barycenterPCA[0] += voxel.m_coord[0]; + m_barycenterPCA[1] += voxel.m_coord[1]; + m_barycenterPCA[2] += voxel.m_coord[2]; + } + m_barycenterPCA /= (double)nVoxels; - double covMat[3][3] = { { 0.0, 0.0, 0.0 }, - { 0.0, 0.0, 0.0 }, - { 0.0, 0.0, 0.0 } }; - double x, y, z; - for (size_t v = 0; v < nVoxels; ++v) { - Voxel& voxel = m_voxels[v]; - x = voxel.m_coord[0] - m_barycenter[0]; - y = voxel.m_coord[1] - m_barycenter[1]; - z = voxel.m_coord[2] - m_barycenter[2]; - covMat[0][0] += x * x; - covMat[1][1] += y * y; - covMat[2][2] += z * z; - covMat[0][1] += x * y; - covMat[0][2] += x * z; - covMat[1][2] += y * z; - } - covMat[0][0] /= nVoxels; - covMat[1][1] /= nVoxels; - covMat[2][2] /= nVoxels; - covMat[0][1] /= nVoxels; - covMat[0][2] /= nVoxels; - covMat[1][2] /= nVoxels; - covMat[1][0] = covMat[0][1]; - covMat[2][0] = covMat[0][2]; - covMat[2][1] = covMat[1][2]; - Diagonalize(covMat, m_Q, m_D); + double covMat[3][3] = {{0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + double x, y, z; + for (size_t v = 0; v < nVoxels; ++v) + { + Voxel& voxel = m_voxels[v]; + x = voxel.m_coord[0] - m_barycenter[0]; + y = voxel.m_coord[1] - m_barycenter[1]; + z = voxel.m_coord[2] - m_barycenter[2]; + covMat[0][0] += x * x; + covMat[1][1] += y * y; + covMat[2][2] += z * z; + covMat[0][1] += x * y; + covMat[0][2] += x * z; + covMat[1][2] += y * z; + } + covMat[0][0] /= nVoxels; + covMat[1][1] /= nVoxels; + covMat[2][2] /= nVoxels; + covMat[0][1] /= nVoxels; + covMat[0][2] /= nVoxels; + covMat[1][2] /= nVoxels; + covMat[1][0] = covMat[0][1]; + covMat[2][0] = covMat[0][2]; + covMat[2][1] = covMat[1][2]; + Diagonalize(covMat, m_Q, m_D); } Volume::Volume() { - m_dim[0] = m_dim[1] = m_dim[2] = 0; - m_minBB[0] = m_minBB[1] = m_minBB[2] = 0.0; - m_maxBB[0] = m_maxBB[1] = m_maxBB[2] = 1.0; - m_numVoxelsOnSurface = 0; - m_numVoxelsInsideSurface = 0; - m_numVoxelsOutsideSurface = 0; - m_scale = 1.0; - m_data = 0; + m_dim[0] = m_dim[1] = m_dim[2] = 0; + m_minBB[0] = m_minBB[1] = m_minBB[2] = 0.0; + m_maxBB[0] = m_maxBB[1] = m_maxBB[2] = 1.0; + m_numVoxelsOnSurface = 0; + m_numVoxelsInsideSurface = 0; + m_numVoxelsOutsideSurface = 0; + m_scale = 1.0; + m_data = 0; } Volume::~Volume(void) { - delete[] m_data; + delete[] m_data; } void Volume::Allocate() { - delete[] m_data; - size_t size = m_dim[0] * m_dim[1] * m_dim[2]; - m_data = new unsigned char[size]; - memset(m_data, PRIMITIVE_UNDEFINED, sizeof(unsigned char) * size); + delete[] m_data; + size_t size = m_dim[0] * m_dim[1] * m_dim[2]; + m_data = new unsigned char[size]; + memset(m_data, PRIMITIVE_UNDEFINED, sizeof(unsigned char) * size); } void Volume::Free() { - delete[] m_data; - m_data = 0; + delete[] m_data; + m_data = 0; } void Volume::FillOutsideSurface(const size_t i0, - const size_t j0, - const size_t k0, - const size_t i1, - const size_t j1, - const size_t k1) + const size_t j0, + const size_t k0, + const size_t i1, + const size_t j1, + const size_t k1) { - const short neighbours[6][3] = { { 1, 0, 0 }, - { 0, 1, 0 }, - { 0, 0, 1 }, - { -1, 0, 0 }, - { 0, -1, 0 }, - { 0, 0, -1 } }; - std::queue > fifo; - Vec3 current; - short a, b, c; - for (size_t i = i0; i < i1; ++i) { - for (size_t j = j0; j < j1; ++j) { - for (size_t k = k0; k < k1; ++k) { - - if (GetVoxel(i, j, k) == PRIMITIVE_UNDEFINED) { - current[0] = (short)i; - current[1] = (short)j; - current[2] = (short)k; - fifo.push(current); - GetVoxel(current[0], current[1], current[2]) = PRIMITIVE_OUTSIDE_SURFACE; - ++m_numVoxelsOutsideSurface; - while (fifo.size() > 0) { - current = fifo.front(); - fifo.pop(); - for (int h = 0; h < 6; ++h) { - a = current[0] + neighbours[h][0]; - b = current[1] + neighbours[h][1]; - c = current[2] + neighbours[h][2]; - if (a < 0 || a >= (int)m_dim[0] || b < 0 || b >= (int)m_dim[1] || c < 0 || c >= (int)m_dim[2]) { - continue; - } - unsigned char& v = GetVoxel(a, b, c); - if (v == PRIMITIVE_UNDEFINED) { - v = PRIMITIVE_OUTSIDE_SURFACE; - ++m_numVoxelsOutsideSurface; - fifo.push(Vec3(a, b, c)); - } - } - } - } - } - } - } + const short neighbours[6][3] = {{1, 0, 0}, + {0, 1, 0}, + {0, 0, 1}, + {-1, 0, 0}, + {0, -1, 0}, + {0, 0, -1}}; + std::queue > fifo; + Vec3 current; + short a, b, c; + for (size_t i = i0; i < i1; ++i) + { + for (size_t j = j0; j < j1; ++j) + { + for (size_t k = k0; k < k1; ++k) + { + if (GetVoxel(i, j, k) == PRIMITIVE_UNDEFINED) + { + current[0] = (short)i; + current[1] = (short)j; + current[2] = (short)k; + fifo.push(current); + GetVoxel(current[0], current[1], current[2]) = PRIMITIVE_OUTSIDE_SURFACE; + ++m_numVoxelsOutsideSurface; + while (fifo.size() > 0) + { + current = fifo.front(); + fifo.pop(); + for (int h = 0; h < 6; ++h) + { + a = current[0] + neighbours[h][0]; + b = current[1] + neighbours[h][1]; + c = current[2] + neighbours[h][2]; + if (a < 0 || a >= (int)m_dim[0] || b < 0 || b >= (int)m_dim[1] || c < 0 || c >= (int)m_dim[2]) + { + continue; + } + unsigned char& v = GetVoxel(a, b, c); + if (v == PRIMITIVE_UNDEFINED) + { + v = PRIMITIVE_OUTSIDE_SURFACE; + ++m_numVoxelsOutsideSurface; + fifo.push(Vec3(a, b, c)); + } + } + } + } + } + } + } } void Volume::FillInsideSurface() { - const size_t i0 = m_dim[0]; - const size_t j0 = m_dim[1]; - const size_t k0 = m_dim[2]; - for (size_t i = 0; i < i0; ++i) { - for (size_t j = 0; j < j0; ++j) { - for (size_t k = 0; k < k0; ++k) { - unsigned char& v = GetVoxel(i, j, k); - if (v == PRIMITIVE_UNDEFINED) { - v = PRIMITIVE_INSIDE_SURFACE; - ++m_numVoxelsInsideSurface; - } - } - } - } + const size_t i0 = m_dim[0]; + const size_t j0 = m_dim[1]; + const size_t k0 = m_dim[2]; + for (size_t i = 0; i < i0; ++i) + { + for (size_t j = 0; j < j0; ++j) + { + for (size_t k = 0; k < k0; ++k) + { + unsigned char& v = GetVoxel(i, j, k); + if (v == PRIMITIVE_UNDEFINED) + { + v = PRIMITIVE_INSIDE_SURFACE; + ++m_numVoxelsInsideSurface; + } + } + } + } } void Volume::Convert(Mesh& mesh, const VOXEL_VALUE value) const { - const size_t i0 = m_dim[0]; - const size_t j0 = m_dim[1]; - const size_t k0 = m_dim[2]; - for (size_t i = 0; i < i0; ++i) { - for (size_t j = 0; j < j0; ++j) { - for (size_t k = 0; k < k0; ++k) { - const unsigned char& voxel = GetVoxel(i, j, k); - if (voxel == value) { - Vec3 p0((i - 0.5) * m_scale, (j - 0.5) * m_scale, (k - 0.5) * m_scale); - Vec3 p1((i + 0.5) * m_scale, (j - 0.5) * m_scale, (k - 0.5) * m_scale); - Vec3 p2((i + 0.5) * m_scale, (j + 0.5) * m_scale, (k - 0.5) * m_scale); - Vec3 p3((i - 0.5) * m_scale, (j + 0.5) * m_scale, (k - 0.5) * m_scale); - Vec3 p4((i - 0.5) * m_scale, (j - 0.5) * m_scale, (k + 0.5) * m_scale); - Vec3 p5((i + 0.5) * m_scale, (j - 0.5) * m_scale, (k + 0.5) * m_scale); - Vec3 p6((i + 0.5) * m_scale, (j + 0.5) * m_scale, (k + 0.5) * m_scale); - Vec3 p7((i - 0.5) * m_scale, (j + 0.5) * m_scale, (k + 0.5) * m_scale); - int s = (int)mesh.GetNPoints(); - mesh.AddPoint(p0 + m_minBB); - mesh.AddPoint(p1 + m_minBB); - mesh.AddPoint(p2 + m_minBB); - mesh.AddPoint(p3 + m_minBB); - mesh.AddPoint(p4 + m_minBB); - mesh.AddPoint(p5 + m_minBB); - mesh.AddPoint(p6 + m_minBB); - mesh.AddPoint(p7 + m_minBB); - mesh.AddTriangle(Vec3(s + 0, s + 2, s + 1)); - mesh.AddTriangle(Vec3(s + 0, s + 3, s + 2)); - mesh.AddTriangle(Vec3(s + 4, s + 5, s + 6)); - mesh.AddTriangle(Vec3(s + 4, s + 6, s + 7)); - mesh.AddTriangle(Vec3(s + 7, s + 6, s + 2)); - mesh.AddTriangle(Vec3(s + 7, s + 2, s + 3)); - mesh.AddTriangle(Vec3(s + 4, s + 1, s + 5)); - mesh.AddTriangle(Vec3(s + 4, s + 0, s + 1)); - mesh.AddTriangle(Vec3(s + 6, s + 5, s + 1)); - mesh.AddTriangle(Vec3(s + 6, s + 1, s + 2)); - mesh.AddTriangle(Vec3(s + 7, s + 0, s + 4)); - mesh.AddTriangle(Vec3(s + 7, s + 3, s + 0)); - } - } - } - } + const size_t i0 = m_dim[0]; + const size_t j0 = m_dim[1]; + const size_t k0 = m_dim[2]; + for (size_t i = 0; i < i0; ++i) + { + for (size_t j = 0; j < j0; ++j) + { + for (size_t k = 0; k < k0; ++k) + { + const unsigned char& voxel = GetVoxel(i, j, k); + if (voxel == value) + { + Vec3 p0((i - 0.5) * m_scale, (j - 0.5) * m_scale, (k - 0.5) * m_scale); + Vec3 p1((i + 0.5) * m_scale, (j - 0.5) * m_scale, (k - 0.5) * m_scale); + Vec3 p2((i + 0.5) * m_scale, (j + 0.5) * m_scale, (k - 0.5) * m_scale); + Vec3 p3((i - 0.5) * m_scale, (j + 0.5) * m_scale, (k - 0.5) * m_scale); + Vec3 p4((i - 0.5) * m_scale, (j - 0.5) * m_scale, (k + 0.5) * m_scale); + Vec3 p5((i + 0.5) * m_scale, (j - 0.5) * m_scale, (k + 0.5) * m_scale); + Vec3 p6((i + 0.5) * m_scale, (j + 0.5) * m_scale, (k + 0.5) * m_scale); + Vec3 p7((i - 0.5) * m_scale, (j + 0.5) * m_scale, (k + 0.5) * m_scale); + int s = (int)mesh.GetNPoints(); + mesh.AddPoint(p0 + m_minBB); + mesh.AddPoint(p1 + m_minBB); + mesh.AddPoint(p2 + m_minBB); + mesh.AddPoint(p3 + m_minBB); + mesh.AddPoint(p4 + m_minBB); + mesh.AddPoint(p5 + m_minBB); + mesh.AddPoint(p6 + m_minBB); + mesh.AddPoint(p7 + m_minBB); + mesh.AddTriangle(Vec3(s + 0, s + 2, s + 1)); + mesh.AddTriangle(Vec3(s + 0, s + 3, s + 2)); + mesh.AddTriangle(Vec3(s + 4, s + 5, s + 6)); + mesh.AddTriangle(Vec3(s + 4, s + 6, s + 7)); + mesh.AddTriangle(Vec3(s + 7, s + 6, s + 2)); + mesh.AddTriangle(Vec3(s + 7, s + 2, s + 3)); + mesh.AddTriangle(Vec3(s + 4, s + 1, s + 5)); + mesh.AddTriangle(Vec3(s + 4, s + 0, s + 1)); + mesh.AddTriangle(Vec3(s + 6, s + 5, s + 1)); + mesh.AddTriangle(Vec3(s + 6, s + 1, s + 2)); + mesh.AddTriangle(Vec3(s + 7, s + 0, s + 4)); + mesh.AddTriangle(Vec3(s + 7, s + 3, s + 0)); + } + } + } + } } void Volume::Convert(VoxelSet& vset) const { - for (int h = 0; h < 3; ++h) { - vset.m_minBB[h] = m_minBB[h]; - } - vset.m_voxels.Allocate(m_numVoxelsInsideSurface + m_numVoxelsOnSurface); - vset.m_scale = m_scale; - vset.m_unitVolume = m_scale * m_scale * m_scale; - const short i0 = (short)m_dim[0]; - const short j0 = (short)m_dim[1]; - const short k0 = (short)m_dim[2]; - Voxel voxel; - vset.m_numVoxelsOnSurface = 0; - vset.m_numVoxelsInsideSurface = 0; - for (short i = 0; i < i0; ++i) { - for (short j = 0; j < j0; ++j) { - for (short k = 0; k < k0; ++k) { - const unsigned char& value = GetVoxel(i, j, k); - if (value == PRIMITIVE_INSIDE_SURFACE) { - voxel.m_coord[0] = i; - voxel.m_coord[1] = j; - voxel.m_coord[2] = k; - voxel.m_data = PRIMITIVE_INSIDE_SURFACE; - vset.m_voxels.PushBack(voxel); - ++vset.m_numVoxelsInsideSurface; - } - else if (value == PRIMITIVE_ON_SURFACE) { - voxel.m_coord[0] = i; - voxel.m_coord[1] = j; - voxel.m_coord[2] = k; - voxel.m_data = PRIMITIVE_ON_SURFACE; - vset.m_voxels.PushBack(voxel); - ++vset.m_numVoxelsOnSurface; - } - } - } - } + for (int h = 0; h < 3; ++h) + { + vset.m_minBB[h] = m_minBB[h]; + } + vset.m_voxels.Allocate(m_numVoxelsInsideSurface + m_numVoxelsOnSurface); + vset.m_scale = m_scale; + vset.m_unitVolume = m_scale * m_scale * m_scale; + const short i0 = (short)m_dim[0]; + const short j0 = (short)m_dim[1]; + const short k0 = (short)m_dim[2]; + Voxel voxel; + vset.m_numVoxelsOnSurface = 0; + vset.m_numVoxelsInsideSurface = 0; + for (short i = 0; i < i0; ++i) + { + for (short j = 0; j < j0; ++j) + { + for (short k = 0; k < k0; ++k) + { + const unsigned char& value = GetVoxel(i, j, k); + if (value == PRIMITIVE_INSIDE_SURFACE) + { + voxel.m_coord[0] = i; + voxel.m_coord[1] = j; + voxel.m_coord[2] = k; + voxel.m_data = PRIMITIVE_INSIDE_SURFACE; + vset.m_voxels.PushBack(voxel); + ++vset.m_numVoxelsInsideSurface; + } + else if (value == PRIMITIVE_ON_SURFACE) + { + voxel.m_coord[0] = i; + voxel.m_coord[1] = j; + voxel.m_coord[2] = k; + voxel.m_data = PRIMITIVE_ON_SURFACE; + vset.m_voxels.PushBack(voxel); + ++vset.m_numVoxelsOnSurface; + } + } + } + } } void Volume::Convert(TetrahedronSet& tset) const { - tset.m_tetrahedra.Allocate(5 * (m_numVoxelsInsideSurface + m_numVoxelsOnSurface)); - tset.m_scale = m_scale; - const short i0 = (short)m_dim[0]; - const short j0 = (short)m_dim[1]; - const short k0 = (short)m_dim[2]; - tset.m_numTetrahedraOnSurface = 0; - tset.m_numTetrahedraInsideSurface = 0; - Tetrahedron tetrahedron; - for (short i = 0; i < i0; ++i) { - for (short j = 0; j < j0; ++j) { - for (short k = 0; k < k0; ++k) { - const unsigned char& value = GetVoxel(i, j, k); - if (value == PRIMITIVE_INSIDE_SURFACE || value == PRIMITIVE_ON_SURFACE) { - tetrahedron.m_data = value; - Vec3 p1((i - 0.5) * m_scale + m_minBB[0], (j - 0.5) * m_scale + m_minBB[1], (k - 0.5) * m_scale + m_minBB[2]); - Vec3 p2((i + 0.5) * m_scale + m_minBB[0], (j - 0.5) * m_scale + m_minBB[1], (k - 0.5) * m_scale + m_minBB[2]); - Vec3 p3((i + 0.5) * m_scale + m_minBB[0], (j + 0.5) * m_scale + m_minBB[1], (k - 0.5) * m_scale + m_minBB[2]); - Vec3 p4((i - 0.5) * m_scale + m_minBB[0], (j + 0.5) * m_scale + m_minBB[1], (k - 0.5) * m_scale + m_minBB[2]); - Vec3 p5((i - 0.5) * m_scale + m_minBB[0], (j - 0.5) * m_scale + m_minBB[1], (k + 0.5) * m_scale + m_minBB[2]); - Vec3 p6((i + 0.5) * m_scale + m_minBB[0], (j - 0.5) * m_scale + m_minBB[1], (k + 0.5) * m_scale + m_minBB[2]); - Vec3 p7((i + 0.5) * m_scale + m_minBB[0], (j + 0.5) * m_scale + m_minBB[1], (k + 0.5) * m_scale + m_minBB[2]); - Vec3 p8((i - 0.5) * m_scale + m_minBB[0], (j + 0.5) * m_scale + m_minBB[1], (k + 0.5) * m_scale + m_minBB[2]); + tset.m_tetrahedra.Allocate(5 * (m_numVoxelsInsideSurface + m_numVoxelsOnSurface)); + tset.m_scale = m_scale; + const short i0 = (short)m_dim[0]; + const short j0 = (short)m_dim[1]; + const short k0 = (short)m_dim[2]; + tset.m_numTetrahedraOnSurface = 0; + tset.m_numTetrahedraInsideSurface = 0; + Tetrahedron tetrahedron; + for (short i = 0; i < i0; ++i) + { + for (short j = 0; j < j0; ++j) + { + for (short k = 0; k < k0; ++k) + { + const unsigned char& value = GetVoxel(i, j, k); + if (value == PRIMITIVE_INSIDE_SURFACE || value == PRIMITIVE_ON_SURFACE) + { + tetrahedron.m_data = value; + Vec3 p1((i - 0.5) * m_scale + m_minBB[0], (j - 0.5) * m_scale + m_minBB[1], (k - 0.5) * m_scale + m_minBB[2]); + Vec3 p2((i + 0.5) * m_scale + m_minBB[0], (j - 0.5) * m_scale + m_minBB[1], (k - 0.5) * m_scale + m_minBB[2]); + Vec3 p3((i + 0.5) * m_scale + m_minBB[0], (j + 0.5) * m_scale + m_minBB[1], (k - 0.5) * m_scale + m_minBB[2]); + Vec3 p4((i - 0.5) * m_scale + m_minBB[0], (j + 0.5) * m_scale + m_minBB[1], (k - 0.5) * m_scale + m_minBB[2]); + Vec3 p5((i - 0.5) * m_scale + m_minBB[0], (j - 0.5) * m_scale + m_minBB[1], (k + 0.5) * m_scale + m_minBB[2]); + Vec3 p6((i + 0.5) * m_scale + m_minBB[0], (j - 0.5) * m_scale + m_minBB[1], (k + 0.5) * m_scale + m_minBB[2]); + Vec3 p7((i + 0.5) * m_scale + m_minBB[0], (j + 0.5) * m_scale + m_minBB[1], (k + 0.5) * m_scale + m_minBB[2]); + Vec3 p8((i - 0.5) * m_scale + m_minBB[0], (j + 0.5) * m_scale + m_minBB[1], (k + 0.5) * m_scale + m_minBB[2]); - tetrahedron.m_pts[0] = p2; - tetrahedron.m_pts[1] = p4; - tetrahedron.m_pts[2] = p7; - tetrahedron.m_pts[3] = p5; - tset.m_tetrahedra.PushBack(tetrahedron); + tetrahedron.m_pts[0] = p2; + tetrahedron.m_pts[1] = p4; + tetrahedron.m_pts[2] = p7; + tetrahedron.m_pts[3] = p5; + tset.m_tetrahedra.PushBack(tetrahedron); - tetrahedron.m_pts[0] = p6; - tetrahedron.m_pts[1] = p2; - tetrahedron.m_pts[2] = p7; - tetrahedron.m_pts[3] = p5; - tset.m_tetrahedra.PushBack(tetrahedron); + tetrahedron.m_pts[0] = p6; + tetrahedron.m_pts[1] = p2; + tetrahedron.m_pts[2] = p7; + tetrahedron.m_pts[3] = p5; + tset.m_tetrahedra.PushBack(tetrahedron); - tetrahedron.m_pts[0] = p3; - tetrahedron.m_pts[1] = p4; - tetrahedron.m_pts[2] = p7; - tetrahedron.m_pts[3] = p2; - tset.m_tetrahedra.PushBack(tetrahedron); + tetrahedron.m_pts[0] = p3; + tetrahedron.m_pts[1] = p4; + tetrahedron.m_pts[2] = p7; + tetrahedron.m_pts[3] = p2; + tset.m_tetrahedra.PushBack(tetrahedron); - tetrahedron.m_pts[0] = p1; - tetrahedron.m_pts[1] = p4; - tetrahedron.m_pts[2] = p2; - tetrahedron.m_pts[3] = p5; - tset.m_tetrahedra.PushBack(tetrahedron); + tetrahedron.m_pts[0] = p1; + tetrahedron.m_pts[1] = p4; + tetrahedron.m_pts[2] = p2; + tetrahedron.m_pts[3] = p5; + tset.m_tetrahedra.PushBack(tetrahedron); - tetrahedron.m_pts[0] = p8; - tetrahedron.m_pts[1] = p5; - tetrahedron.m_pts[2] = p7; - tetrahedron.m_pts[3] = p4; - tset.m_tetrahedra.PushBack(tetrahedron); - if (value == PRIMITIVE_INSIDE_SURFACE) { - tset.m_numTetrahedraInsideSurface += 5; - } - else { - tset.m_numTetrahedraOnSurface += 5; - } - } - } - } - } + tetrahedron.m_pts[0] = p8; + tetrahedron.m_pts[1] = p5; + tetrahedron.m_pts[2] = p7; + tetrahedron.m_pts[3] = p4; + tset.m_tetrahedra.PushBack(tetrahedron); + if (value == PRIMITIVE_INSIDE_SURFACE) + { + tset.m_numTetrahedraInsideSurface += 5; + } + else + { + tset.m_numTetrahedraOnSurface += 5; + } + } + } + } + } } void Volume::AlignToPrincipalAxes(double (&rot)[3][3]) const { - const short i0 = (short)m_dim[0]; - const short j0 = (short)m_dim[1]; - const short k0 = (short)m_dim[2]; - Vec3 barycenter(0.0); - size_t nVoxels = 0; - for (short i = 0; i < i0; ++i) { - for (short j = 0; j < j0; ++j) { - for (short k = 0; k < k0; ++k) { - const unsigned char& value = GetVoxel(i, j, k); - if (value == PRIMITIVE_INSIDE_SURFACE || value == PRIMITIVE_ON_SURFACE) { - barycenter[0] += i; - barycenter[1] += j; - barycenter[2] += k; - ++nVoxels; - } - } - } - } - barycenter /= (double)nVoxels; + const short i0 = (short)m_dim[0]; + const short j0 = (short)m_dim[1]; + const short k0 = (short)m_dim[2]; + Vec3 barycenter(0.0); + size_t nVoxels = 0; + for (short i = 0; i < i0; ++i) + { + for (short j = 0; j < j0; ++j) + { + for (short k = 0; k < k0; ++k) + { + const unsigned char& value = GetVoxel(i, j, k); + if (value == PRIMITIVE_INSIDE_SURFACE || value == PRIMITIVE_ON_SURFACE) + { + barycenter[0] += i; + barycenter[1] += j; + barycenter[2] += k; + ++nVoxels; + } + } + } + } + barycenter /= (double)nVoxels; - double covMat[3][3] = { { 0.0, 0.0, 0.0 }, - { 0.0, 0.0, 0.0 }, - { 0.0, 0.0, 0.0 } }; - double x, y, z; - for (short i = 0; i < i0; ++i) { - for (short j = 0; j < j0; ++j) { - for (short k = 0; k < k0; ++k) { - const unsigned char& value = GetVoxel(i, j, k); - if (value == PRIMITIVE_INSIDE_SURFACE || value == PRIMITIVE_ON_SURFACE) { - x = i - barycenter[0]; - y = j - barycenter[1]; - z = k - barycenter[2]; - covMat[0][0] += x * x; - covMat[1][1] += y * y; - covMat[2][2] += z * z; - covMat[0][1] += x * y; - covMat[0][2] += x * z; - covMat[1][2] += y * z; - } - } - } - } - covMat[1][0] = covMat[0][1]; - covMat[2][0] = covMat[0][2]; - covMat[2][1] = covMat[1][2]; - double D[3][3]; - Diagonalize(covMat, rot, D); + double covMat[3][3] = {{0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + double x, y, z; + for (short i = 0; i < i0; ++i) + { + for (short j = 0; j < j0; ++j) + { + for (short k = 0; k < k0; ++k) + { + const unsigned char& value = GetVoxel(i, j, k); + if (value == PRIMITIVE_INSIDE_SURFACE || value == PRIMITIVE_ON_SURFACE) + { + x = i - barycenter[0]; + y = j - barycenter[1]; + z = k - barycenter[2]; + covMat[0][0] += x * x; + covMat[1][1] += y * y; + covMat[2][2] += z * z; + covMat[0][1] += x * y; + covMat[0][2] += x * z; + covMat[1][2] += y * z; + } + } + } + } + covMat[1][0] = covMat[0][1]; + covMat[2][0] = covMat[0][2]; + covMat[2][1] = covMat[1][2]; + double D[3][3]; + Diagonalize(covMat, rot, D); } TetrahedronSet::TetrahedronSet() { - m_minBB[0] = m_minBB[1] = m_minBB[2] = 0.0; - m_maxBB[0] = m_maxBB[1] = m_maxBB[2] = 1.0; - m_barycenter[0] = m_barycenter[1] = m_barycenter[2] = 0.0; - m_scale = 1.0; - m_numTetrahedraOnSurface = 0; - m_numTetrahedraInsideSurface = 0; - memset(m_Q, 0, sizeof(double) * 9); - memset(m_D, 0, sizeof(double) * 9); + m_minBB[0] = m_minBB[1] = m_minBB[2] = 0.0; + m_maxBB[0] = m_maxBB[1] = m_maxBB[2] = 1.0; + m_barycenter[0] = m_barycenter[1] = m_barycenter[2] = 0.0; + m_scale = 1.0; + m_numTetrahedraOnSurface = 0; + m_numTetrahedraInsideSurface = 0; + memset(m_Q, 0, sizeof(double) * 9); + memset(m_D, 0, sizeof(double) * 9); } TetrahedronSet::~TetrahedronSet(void) { } void TetrahedronSet::ComputeBB() { - const size_t nTetrahedra = m_tetrahedra.Size(); - if (nTetrahedra == 0) - return; + const size_t nTetrahedra = m_tetrahedra.Size(); + if (nTetrahedra == 0) + return; - for (int h = 0; h < 3; ++h) { - m_minBB[h] = m_maxBB[h] = m_tetrahedra[0].m_pts[0][h]; - m_barycenter[h] = 0.0; - } - for (size_t p = 0; p < nTetrahedra; ++p) { - for (int i = 0; i < 4; ++i) { - for (int h = 0; h < 3; ++h) { - if (m_minBB[h] > m_tetrahedra[p].m_pts[i][h]) - m_minBB[h] = m_tetrahedra[p].m_pts[i][h]; - if (m_maxBB[h] < m_tetrahedra[p].m_pts[i][h]) - m_maxBB[h] = m_tetrahedra[p].m_pts[i][h]; - m_barycenter[h] += m_tetrahedra[p].m_pts[i][h]; - } - } - } - m_barycenter /= (double)(4 * nTetrahedra); + for (int h = 0; h < 3; ++h) + { + m_minBB[h] = m_maxBB[h] = m_tetrahedra[0].m_pts[0][h]; + m_barycenter[h] = 0.0; + } + for (size_t p = 0; p < nTetrahedra; ++p) + { + for (int i = 0; i < 4; ++i) + { + for (int h = 0; h < 3; ++h) + { + if (m_minBB[h] > m_tetrahedra[p].m_pts[i][h]) + m_minBB[h] = m_tetrahedra[p].m_pts[i][h]; + if (m_maxBB[h] < m_tetrahedra[p].m_pts[i][h]) + m_maxBB[h] = m_tetrahedra[p].m_pts[i][h]; + m_barycenter[h] += m_tetrahedra[p].m_pts[i][h]; + } + } + } + m_barycenter /= (double)(4 * nTetrahedra); } void TetrahedronSet::ComputeConvexHull(Mesh& meshCH, const size_t sampling) const { - const size_t CLUSTER_SIZE = 65536; - const size_t nTetrahedra = m_tetrahedra.Size(); - if (nTetrahedra == 0) - return; + const size_t CLUSTER_SIZE = 65536; + const size_t nTetrahedra = m_tetrahedra.Size(); + if (nTetrahedra == 0) + return; - SArray > cpoints; + SArray > cpoints; - Vec3* points = new Vec3[CLUSTER_SIZE]; - size_t p = 0; - while (p < nTetrahedra) { - size_t q = 0; - size_t s = 0; - while (q < CLUSTER_SIZE && p < nTetrahedra) { - if (m_tetrahedra[p].m_data == PRIMITIVE_ON_SURFACE) { - ++s; - if (s == sampling) { - s = 0; - for (int a = 0; a < 4; ++a) { - points[q++] = m_tetrahedra[p].m_pts[a]; - for (int xx = 0; xx < 3; ++xx) { - assert(m_tetrahedra[p].m_pts[a][xx] + EPS >= m_minBB[xx]); - assert(m_tetrahedra[p].m_pts[a][xx] <= m_maxBB[xx] + EPS); - } - } - } - } - ++p; - } - btConvexHullComputer ch; - ch.compute((double*)points, 3 * sizeof(double), (int)q, -1.0, -1.0); - for (int v = 0; v < ch.vertices.size(); v++) { - cpoints.PushBack(Vec3(ch.vertices[v].getX(), ch.vertices[v].getY(), ch.vertices[v].getZ())); - } - } - delete[] points; + Vec3* points = new Vec3[CLUSTER_SIZE]; + size_t p = 0; + while (p < nTetrahedra) + { + size_t q = 0; + size_t s = 0; + while (q < CLUSTER_SIZE && p < nTetrahedra) + { + if (m_tetrahedra[p].m_data == PRIMITIVE_ON_SURFACE) + { + ++s; + if (s == sampling) + { + s = 0; + for (int a = 0; a < 4; ++a) + { + points[q++] = m_tetrahedra[p].m_pts[a]; + for (int xx = 0; xx < 3; ++xx) + { + assert(m_tetrahedra[p].m_pts[a][xx] + EPS >= m_minBB[xx]); + assert(m_tetrahedra[p].m_pts[a][xx] <= m_maxBB[xx] + EPS); + } + } + } + } + ++p; + } + btConvexHullComputer ch; + ch.compute((double*)points, 3 * sizeof(double), (int)q, -1.0, -1.0); + for (int v = 0; v < ch.vertices.size(); v++) + { + cpoints.PushBack(Vec3(ch.vertices[v].getX(), ch.vertices[v].getY(), ch.vertices[v].getZ())); + } + } + delete[] points; - points = cpoints.Data(); - btConvexHullComputer ch; - ch.compute((double*)points, 3 * sizeof(double), (int)cpoints.Size(), -1.0, -1.0); - meshCH.ResizePoints(0); - meshCH.ResizeTriangles(0); - for (int v = 0; v < ch.vertices.size(); v++) { - meshCH.AddPoint(Vec3(ch.vertices[v].getX(), ch.vertices[v].getY(), ch.vertices[v].getZ())); - } - const int nt = ch.faces.size(); - for (int t = 0; t < nt; ++t) { - const btConvexHullComputer::Edge* sourceEdge = &(ch.edges[ch.faces[t]]); - int a = sourceEdge->getSourceVertex(); - int b = sourceEdge->getTargetVertex(); - const btConvexHullComputer::Edge* edge = sourceEdge->getNextEdgeOfFace(); - int c = edge->getTargetVertex(); - while (c != a) { - meshCH.AddTriangle(Vec3(a, b, c)); - edge = edge->getNextEdgeOfFace(); - b = c; - c = edge->getTargetVertex(); - } - } + points = cpoints.Data(); + btConvexHullComputer ch; + ch.compute((double*)points, 3 * sizeof(double), (int)cpoints.Size(), -1.0, -1.0); + meshCH.ResizePoints(0); + meshCH.ResizeTriangles(0); + for (int v = 0; v < ch.vertices.size(); v++) + { + meshCH.AddPoint(Vec3(ch.vertices[v].getX(), ch.vertices[v].getY(), ch.vertices[v].getZ())); + } + const int nt = ch.faces.size(); + for (int t = 0; t < nt; ++t) + { + const btConvexHullComputer::Edge* sourceEdge = &(ch.edges[ch.faces[t]]); + int a = sourceEdge->getSourceVertex(); + int b = sourceEdge->getTargetVertex(); + const btConvexHullComputer::Edge* edge = sourceEdge->getNextEdgeOfFace(); + int c = edge->getTargetVertex(); + while (c != a) + { + meshCH.AddTriangle(Vec3(a, b, c)); + edge = edge->getNextEdgeOfFace(); + b = c; + c = edge->getTargetVertex(); + } + } } inline bool TetrahedronSet::Add(Tetrahedron& tetrahedron) { - double v = ComputeVolume4(tetrahedron.m_pts[0], tetrahedron.m_pts[1], tetrahedron.m_pts[2], tetrahedron.m_pts[3]); + double v = ComputeVolume4(tetrahedron.m_pts[0], tetrahedron.m_pts[1], tetrahedron.m_pts[2], tetrahedron.m_pts[3]); - const double EPS = 0.0000000001; - if (fabs(v) < EPS) { - return false; - } - else if (v < 0.0) { - Vec3 tmp = tetrahedron.m_pts[0]; - tetrahedron.m_pts[0] = tetrahedron.m_pts[1]; - tetrahedron.m_pts[1] = tmp; - } + const double EPS = 0.0000000001; + if (fabs(v) < EPS) + { + return false; + } + else if (v < 0.0) + { + Vec3 tmp = tetrahedron.m_pts[0]; + tetrahedron.m_pts[0] = tetrahedron.m_pts[1]; + tetrahedron.m_pts[1] = tmp; + } - for (int a = 0; a < 4; ++a) { - for (int xx = 0; xx < 3; ++xx) { - assert(tetrahedron.m_pts[a][xx] + EPS >= m_minBB[xx]); - assert(tetrahedron.m_pts[a][xx] <= m_maxBB[xx] + EPS); - } - } - m_tetrahedra.PushBack(tetrahedron); - return true; + for (int a = 0; a < 4; ++a) + { + for (int xx = 0; xx < 3; ++xx) + { + assert(tetrahedron.m_pts[a][xx] + EPS >= m_minBB[xx]); + assert(tetrahedron.m_pts[a][xx] <= m_maxBB[xx] + EPS); + } + } + m_tetrahedra.PushBack(tetrahedron); + return true; } void TetrahedronSet::AddClippedTetrahedra(const Vec3 (&pts)[10], const int nPts) { - const int tetF[4][3] = { { 0, 1, 2 }, { 2, 1, 3 }, { 3, 1, 0 }, { 3, 0, 2 } }; - if (nPts < 4) { - return; - } - else if (nPts == 4) { - Tetrahedron tetrahedron; - tetrahedron.m_data = PRIMITIVE_ON_SURFACE; - tetrahedron.m_pts[0] = pts[0]; - tetrahedron.m_pts[1] = pts[1]; - tetrahedron.m_pts[2] = pts[2]; - tetrahedron.m_pts[3] = pts[3]; - if (Add(tetrahedron)) { - ++m_numTetrahedraOnSurface; - } - } - else if (nPts == 5) { - const int tet[15][4] = { - { 0, 1, 2, 3 }, { 1, 2, 3, 4 }, { 0, 2, 3, 4 }, { 0, 1, 3, 4 }, { 0, 1, 2, 4 }, - }; - const int rem[5] = { 4, 0, 1, 2, 3 }; - double maxVol = 0.0; - int h0 = -1; - Tetrahedron tetrahedron0; - tetrahedron0.m_data = PRIMITIVE_ON_SURFACE; - for (int h = 0; h < 5; ++h) { - double v = ComputeVolume4(pts[tet[h][0]], pts[tet[h][1]], pts[tet[h][2]], pts[tet[h][3]]); - if (v > maxVol) { - h0 = h; - tetrahedron0.m_pts[0] = pts[tet[h][0]]; - tetrahedron0.m_pts[1] = pts[tet[h][1]]; - tetrahedron0.m_pts[2] = pts[tet[h][2]]; - tetrahedron0.m_pts[3] = pts[tet[h][3]]; - maxVol = v; - } - else if (-v > maxVol) { - h0 = h; - tetrahedron0.m_pts[0] = pts[tet[h][1]]; - tetrahedron0.m_pts[1] = pts[tet[h][0]]; - tetrahedron0.m_pts[2] = pts[tet[h][2]]; - tetrahedron0.m_pts[3] = pts[tet[h][3]]; - maxVol = -v; - } - } - if (h0 == -1) - return; - if (Add(tetrahedron0)) { - ++m_numTetrahedraOnSurface; - } - else { - return; - } - int a = rem[h0]; - maxVol = 0.0; - int h1 = -1; - Tetrahedron tetrahedron1; - tetrahedron1.m_data = PRIMITIVE_ON_SURFACE; - for (int h = 0; h < 4; ++h) { - double v = ComputeVolume4(pts[a], tetrahedron0.m_pts[tetF[h][0]], tetrahedron0.m_pts[tetF[h][1]], tetrahedron0.m_pts[tetF[h][2]]); - if (v > maxVol) { - h1 = h; - tetrahedron1.m_pts[0] = pts[a]; - tetrahedron1.m_pts[1] = tetrahedron0.m_pts[tetF[h][0]]; - tetrahedron1.m_pts[2] = tetrahedron0.m_pts[tetF[h][1]]; - tetrahedron1.m_pts[3] = tetrahedron0.m_pts[tetF[h][2]]; - maxVol = v; - } - } - if (h1 == -1 && Add(tetrahedron1)) { - ++m_numTetrahedraOnSurface; - } - } - else if (nPts == 6) { + const int tetF[4][3] = {{0, 1, 2}, {2, 1, 3}, {3, 1, 0}, {3, 0, 2}}; + if (nPts < 4) + { + return; + } + else if (nPts == 4) + { + Tetrahedron tetrahedron; + tetrahedron.m_data = PRIMITIVE_ON_SURFACE; + tetrahedron.m_pts[0] = pts[0]; + tetrahedron.m_pts[1] = pts[1]; + tetrahedron.m_pts[2] = pts[2]; + tetrahedron.m_pts[3] = pts[3]; + if (Add(tetrahedron)) + { + ++m_numTetrahedraOnSurface; + } + } + else if (nPts == 5) + { + const int tet[15][4] = { + {0, 1, 2, 3}, + {1, 2, 3, 4}, + {0, 2, 3, 4}, + {0, 1, 3, 4}, + {0, 1, 2, 4}, + }; + const int rem[5] = {4, 0, 1, 2, 3}; + double maxVol = 0.0; + int h0 = -1; + Tetrahedron tetrahedron0; + tetrahedron0.m_data = PRIMITIVE_ON_SURFACE; + for (int h = 0; h < 5; ++h) + { + double v = ComputeVolume4(pts[tet[h][0]], pts[tet[h][1]], pts[tet[h][2]], pts[tet[h][3]]); + if (v > maxVol) + { + h0 = h; + tetrahedron0.m_pts[0] = pts[tet[h][0]]; + tetrahedron0.m_pts[1] = pts[tet[h][1]]; + tetrahedron0.m_pts[2] = pts[tet[h][2]]; + tetrahedron0.m_pts[3] = pts[tet[h][3]]; + maxVol = v; + } + else if (-v > maxVol) + { + h0 = h; + tetrahedron0.m_pts[0] = pts[tet[h][1]]; + tetrahedron0.m_pts[1] = pts[tet[h][0]]; + tetrahedron0.m_pts[2] = pts[tet[h][2]]; + tetrahedron0.m_pts[3] = pts[tet[h][3]]; + maxVol = -v; + } + } + if (h0 == -1) + return; + if (Add(tetrahedron0)) + { + ++m_numTetrahedraOnSurface; + } + else + { + return; + } + int a = rem[h0]; + maxVol = 0.0; + int h1 = -1; + Tetrahedron tetrahedron1; + tetrahedron1.m_data = PRIMITIVE_ON_SURFACE; + for (int h = 0; h < 4; ++h) + { + double v = ComputeVolume4(pts[a], tetrahedron0.m_pts[tetF[h][0]], tetrahedron0.m_pts[tetF[h][1]], tetrahedron0.m_pts[tetF[h][2]]); + if (v > maxVol) + { + h1 = h; + tetrahedron1.m_pts[0] = pts[a]; + tetrahedron1.m_pts[1] = tetrahedron0.m_pts[tetF[h][0]]; + tetrahedron1.m_pts[2] = tetrahedron0.m_pts[tetF[h][1]]; + tetrahedron1.m_pts[3] = tetrahedron0.m_pts[tetF[h][2]]; + maxVol = v; + } + } + if (h1 == -1 && Add(tetrahedron1)) + { + ++m_numTetrahedraOnSurface; + } + } + else if (nPts == 6) + { + const int tet[15][4] = {{2, 3, 4, 5}, {1, 3, 4, 5}, {1, 2, 4, 5}, {1, 2, 3, 5}, {1, 2, 3, 4}, {0, 3, 4, 5}, {0, 2, 4, 5}, {0, 2, 3, 5}, {0, 2, 3, 4}, {0, 1, 4, 5}, {0, 1, 3, 5}, {0, 1, 3, 4}, {0, 1, 2, 5}, {0, 1, 2, 4}, {0, 1, 2, 3}}; + const int rem[15][2] = {{0, 1}, {0, 2}, {0, 3}, {0, 4}, {0, 5}, {1, 2}, {1, 3}, {1, 4}, {1, 5}, {2, 3}, {2, 4}, {2, 5}, {3, 4}, {3, 5}, {4, 5}}; + double maxVol = 0.0; + int h0 = -1; + Tetrahedron tetrahedron0; + tetrahedron0.m_data = PRIMITIVE_ON_SURFACE; + for (int h = 0; h < 15; ++h) + { + double v = ComputeVolume4(pts[tet[h][0]], pts[tet[h][1]], pts[tet[h][2]], pts[tet[h][3]]); + if (v > maxVol) + { + h0 = h; + tetrahedron0.m_pts[0] = pts[tet[h][0]]; + tetrahedron0.m_pts[1] = pts[tet[h][1]]; + tetrahedron0.m_pts[2] = pts[tet[h][2]]; + tetrahedron0.m_pts[3] = pts[tet[h][3]]; + maxVol = v; + } + else if (-v > maxVol) + { + h0 = h; + tetrahedron0.m_pts[0] = pts[tet[h][1]]; + tetrahedron0.m_pts[1] = pts[tet[h][0]]; + tetrahedron0.m_pts[2] = pts[tet[h][2]]; + tetrahedron0.m_pts[3] = pts[tet[h][3]]; + maxVol = -v; + } + } + if (h0 == -1) + return; + if (Add(tetrahedron0)) + { + ++m_numTetrahedraOnSurface; + } + else + { + return; + } - const int tet[15][4] = { { 2, 3, 4, 5 }, { 1, 3, 4, 5 }, { 1, 2, 4, 5 }, { 1, 2, 3, 5 }, { 1, 2, 3, 4 }, - { 0, 3, 4, 5 }, { 0, 2, 4, 5 }, { 0, 2, 3, 5 }, { 0, 2, 3, 4 }, { 0, 1, 4, 5 }, - { 0, 1, 3, 5 }, { 0, 1, 3, 4 }, { 0, 1, 2, 5 }, { 0, 1, 2, 4 }, { 0, 1, 2, 3 } }; - const int rem[15][2] = { { 0, 1 }, { 0, 2 }, { 0, 3 }, { 0, 4 }, { 0, 5 }, - { 1, 2 }, { 1, 3 }, { 1, 4 }, { 1, 5 }, { 2, 3 }, - { 2, 4 }, { 2, 5 }, { 3, 4 }, { 3, 5 }, { 4, 5 } }; - double maxVol = 0.0; - int h0 = -1; - Tetrahedron tetrahedron0; - tetrahedron0.m_data = PRIMITIVE_ON_SURFACE; - for (int h = 0; h < 15; ++h) { - double v = ComputeVolume4(pts[tet[h][0]], pts[tet[h][1]], pts[tet[h][2]], pts[tet[h][3]]); - if (v > maxVol) { - h0 = h; - tetrahedron0.m_pts[0] = pts[tet[h][0]]; - tetrahedron0.m_pts[1] = pts[tet[h][1]]; - tetrahedron0.m_pts[2] = pts[tet[h][2]]; - tetrahedron0.m_pts[3] = pts[tet[h][3]]; - maxVol = v; - } - else if (-v > maxVol) { - h0 = h; - tetrahedron0.m_pts[0] = pts[tet[h][1]]; - tetrahedron0.m_pts[1] = pts[tet[h][0]]; - tetrahedron0.m_pts[2] = pts[tet[h][2]]; - tetrahedron0.m_pts[3] = pts[tet[h][3]]; - maxVol = -v; - } - } - if (h0 == -1) - return; - if (Add(tetrahedron0)) { - ++m_numTetrahedraOnSurface; - } - else { - return; - } - - int a0 = rem[h0][0]; - int a1 = rem[h0][1]; - int h1 = -1; - Tetrahedron tetrahedron1; - tetrahedron1.m_data = PRIMITIVE_ON_SURFACE; - maxVol = 0.0; - for (int h = 0; h < 4; ++h) { - double v = ComputeVolume4(pts[a0], tetrahedron0.m_pts[tetF[h][0]], tetrahedron0.m_pts[tetF[h][1]], tetrahedron0.m_pts[tetF[h][2]]); - if (v > maxVol) { - h1 = h; - tetrahedron1.m_pts[0] = pts[a0]; - tetrahedron1.m_pts[1] = tetrahedron0.m_pts[tetF[h][0]]; - tetrahedron1.m_pts[2] = tetrahedron0.m_pts[tetF[h][1]]; - tetrahedron1.m_pts[3] = tetrahedron0.m_pts[tetF[h][2]]; - maxVol = v; - } - } - if (h1 != -1 && Add(tetrahedron1)) { - ++m_numTetrahedraOnSurface; - } - else { - h1 = -1; - } - maxVol = 0.0; - int h2 = -1; - Tetrahedron tetrahedron2; - tetrahedron2.m_data = PRIMITIVE_ON_SURFACE; - for (int h = 0; h < 4; ++h) { - double v = ComputeVolume4(pts[a0], tetrahedron0.m_pts[tetF[h][0]], tetrahedron0.m_pts[tetF[h][1]], tetrahedron0.m_pts[tetF[h][2]]); - if (h == h1) - continue; - if (v > maxVol) { - h2 = h; - tetrahedron2.m_pts[0] = pts[a1]; - tetrahedron2.m_pts[1] = tetrahedron0.m_pts[tetF[h][0]]; - tetrahedron2.m_pts[2] = tetrahedron0.m_pts[tetF[h][1]]; - tetrahedron2.m_pts[3] = tetrahedron0.m_pts[tetF[h][2]]; - maxVol = v; - } - } - if (h1 != -1) { - for (int h = 0; h < 4; ++h) { - double v = ComputeVolume4(pts[a1], tetrahedron1.m_pts[tetF[h][0]], tetrahedron1.m_pts[tetF[h][1]], tetrahedron1.m_pts[tetF[h][2]]); - if (h == 1) - continue; - if (v > maxVol) { - h2 = h; - tetrahedron2.m_pts[0] = pts[a1]; - tetrahedron2.m_pts[1] = tetrahedron1.m_pts[tetF[h][0]]; - tetrahedron2.m_pts[2] = tetrahedron1.m_pts[tetF[h][1]]; - tetrahedron2.m_pts[3] = tetrahedron1.m_pts[tetF[h][2]]; - maxVol = v; - } - } - } - if (h2 != -1 && Add(tetrahedron2)) { - ++m_numTetrahedraOnSurface; - } - } - else { - assert(0); - } + int a0 = rem[h0][0]; + int a1 = rem[h0][1]; + int h1 = -1; + Tetrahedron tetrahedron1; + tetrahedron1.m_data = PRIMITIVE_ON_SURFACE; + maxVol = 0.0; + for (int h = 0; h < 4; ++h) + { + double v = ComputeVolume4(pts[a0], tetrahedron0.m_pts[tetF[h][0]], tetrahedron0.m_pts[tetF[h][1]], tetrahedron0.m_pts[tetF[h][2]]); + if (v > maxVol) + { + h1 = h; + tetrahedron1.m_pts[0] = pts[a0]; + tetrahedron1.m_pts[1] = tetrahedron0.m_pts[tetF[h][0]]; + tetrahedron1.m_pts[2] = tetrahedron0.m_pts[tetF[h][1]]; + tetrahedron1.m_pts[3] = tetrahedron0.m_pts[tetF[h][2]]; + maxVol = v; + } + } + if (h1 != -1 && Add(tetrahedron1)) + { + ++m_numTetrahedraOnSurface; + } + else + { + h1 = -1; + } + maxVol = 0.0; + int h2 = -1; + Tetrahedron tetrahedron2; + tetrahedron2.m_data = PRIMITIVE_ON_SURFACE; + for (int h = 0; h < 4; ++h) + { + double v = ComputeVolume4(pts[a0], tetrahedron0.m_pts[tetF[h][0]], tetrahedron0.m_pts[tetF[h][1]], tetrahedron0.m_pts[tetF[h][2]]); + if (h == h1) + continue; + if (v > maxVol) + { + h2 = h; + tetrahedron2.m_pts[0] = pts[a1]; + tetrahedron2.m_pts[1] = tetrahedron0.m_pts[tetF[h][0]]; + tetrahedron2.m_pts[2] = tetrahedron0.m_pts[tetF[h][1]]; + tetrahedron2.m_pts[3] = tetrahedron0.m_pts[tetF[h][2]]; + maxVol = v; + } + } + if (h1 != -1) + { + for (int h = 0; h < 4; ++h) + { + double v = ComputeVolume4(pts[a1], tetrahedron1.m_pts[tetF[h][0]], tetrahedron1.m_pts[tetF[h][1]], tetrahedron1.m_pts[tetF[h][2]]); + if (h == 1) + continue; + if (v > maxVol) + { + h2 = h; + tetrahedron2.m_pts[0] = pts[a1]; + tetrahedron2.m_pts[1] = tetrahedron1.m_pts[tetF[h][0]]; + tetrahedron2.m_pts[2] = tetrahedron1.m_pts[tetF[h][1]]; + tetrahedron2.m_pts[3] = tetrahedron1.m_pts[tetF[h][2]]; + maxVol = v; + } + } + } + if (h2 != -1 && Add(tetrahedron2)) + { + ++m_numTetrahedraOnSurface; + } + } + else + { + assert(0); + } } void TetrahedronSet::Intersect(const Plane& plane, - SArray >* const positivePts, - SArray >* const negativePts, - const size_t sampling) const + SArray >* const positivePts, + SArray >* const negativePts, + const size_t sampling) const { - const size_t nTetrahedra = m_tetrahedra.Size(); - if (nTetrahedra == 0) - return; + const size_t nTetrahedra = m_tetrahedra.Size(); + if (nTetrahedra == 0) + return; } void TetrahedronSet::ComputeExteriorPoints(const Plane& plane, - const Mesh& mesh, - SArray >* const exteriorPts) const + const Mesh& mesh, + SArray >* const exteriorPts) const { } void TetrahedronSet::ComputeClippedVolumes(const Plane& plane, - double& positiveVolume, - double& negativeVolume) const + double& positiveVolume, + double& negativeVolume) const { - const size_t nTetrahedra = m_tetrahedra.Size(); - if (nTetrahedra == 0) - return; + const size_t nTetrahedra = m_tetrahedra.Size(); + if (nTetrahedra == 0) + return; } void TetrahedronSet::SelectOnSurface(PrimitiveSet* const onSurfP) const { - TetrahedronSet* const onSurf = (TetrahedronSet*)onSurfP; - const size_t nTetrahedra = m_tetrahedra.Size(); - if (nTetrahedra == 0) - return; - onSurf->m_tetrahedra.Resize(0); - onSurf->m_scale = m_scale; - onSurf->m_numTetrahedraOnSurface = 0; - onSurf->m_numTetrahedraInsideSurface = 0; - onSurf->m_barycenter = m_barycenter; - onSurf->m_minBB = m_minBB; - onSurf->m_maxBB = m_maxBB; - for (int i = 0; i < 3; ++i) { - for (int j = 0; j < 3; ++j) { - onSurf->m_Q[i][j] = m_Q[i][j]; - onSurf->m_D[i][j] = m_D[i][j]; - } - } - Tetrahedron tetrahedron; - for (size_t v = 0; v < nTetrahedra; ++v) { - tetrahedron = m_tetrahedra[v]; - if (tetrahedron.m_data == PRIMITIVE_ON_SURFACE) { - onSurf->m_tetrahedra.PushBack(tetrahedron); - ++onSurf->m_numTetrahedraOnSurface; - } - } + TetrahedronSet* const onSurf = (TetrahedronSet*)onSurfP; + const size_t nTetrahedra = m_tetrahedra.Size(); + if (nTetrahedra == 0) + return; + onSurf->m_tetrahedra.Resize(0); + onSurf->m_scale = m_scale; + onSurf->m_numTetrahedraOnSurface = 0; + onSurf->m_numTetrahedraInsideSurface = 0; + onSurf->m_barycenter = m_barycenter; + onSurf->m_minBB = m_minBB; + onSurf->m_maxBB = m_maxBB; + for (int i = 0; i < 3; ++i) + { + for (int j = 0; j < 3; ++j) + { + onSurf->m_Q[i][j] = m_Q[i][j]; + onSurf->m_D[i][j] = m_D[i][j]; + } + } + Tetrahedron tetrahedron; + for (size_t v = 0; v < nTetrahedra; ++v) + { + tetrahedron = m_tetrahedra[v]; + if (tetrahedron.m_data == PRIMITIVE_ON_SURFACE) + { + onSurf->m_tetrahedra.PushBack(tetrahedron); + ++onSurf->m_numTetrahedraOnSurface; + } + } } void TetrahedronSet::Clip(const Plane& plane, - PrimitiveSet* const positivePartP, - PrimitiveSet* const negativePartP) const + PrimitiveSet* const positivePartP, + PrimitiveSet* const negativePartP) const { - TetrahedronSet* const positivePart = (TetrahedronSet*)positivePartP; - TetrahedronSet* const negativePart = (TetrahedronSet*)negativePartP; - const size_t nTetrahedra = m_tetrahedra.Size(); - if (nTetrahedra == 0) - return; - positivePart->m_tetrahedra.Resize(0); - negativePart->m_tetrahedra.Resize(0); - positivePart->m_tetrahedra.Allocate(nTetrahedra); - negativePart->m_tetrahedra.Allocate(nTetrahedra); - negativePart->m_scale = positivePart->m_scale = m_scale; - negativePart->m_numTetrahedraOnSurface = positivePart->m_numTetrahedraOnSurface = 0; - negativePart->m_numTetrahedraInsideSurface = positivePart->m_numTetrahedraInsideSurface = 0; - negativePart->m_barycenter = m_barycenter; - positivePart->m_barycenter = m_barycenter; - negativePart->m_minBB = m_minBB; - positivePart->m_minBB = m_minBB; - negativePart->m_maxBB = m_maxBB; - positivePart->m_maxBB = m_maxBB; - for (int i = 0; i < 3; ++i) { - for (int j = 0; j < 3; ++j) { - negativePart->m_Q[i][j] = positivePart->m_Q[i][j] = m_Q[i][j]; - negativePart->m_D[i][j] = positivePart->m_D[i][j] = m_D[i][j]; - } - } + TetrahedronSet* const positivePart = (TetrahedronSet*)positivePartP; + TetrahedronSet* const negativePart = (TetrahedronSet*)negativePartP; + const size_t nTetrahedra = m_tetrahedra.Size(); + if (nTetrahedra == 0) + return; + positivePart->m_tetrahedra.Resize(0); + negativePart->m_tetrahedra.Resize(0); + positivePart->m_tetrahedra.Allocate(nTetrahedra); + negativePart->m_tetrahedra.Allocate(nTetrahedra); + negativePart->m_scale = positivePart->m_scale = m_scale; + negativePart->m_numTetrahedraOnSurface = positivePart->m_numTetrahedraOnSurface = 0; + negativePart->m_numTetrahedraInsideSurface = positivePart->m_numTetrahedraInsideSurface = 0; + negativePart->m_barycenter = m_barycenter; + positivePart->m_barycenter = m_barycenter; + negativePart->m_minBB = m_minBB; + positivePart->m_minBB = m_minBB; + negativePart->m_maxBB = m_maxBB; + positivePart->m_maxBB = m_maxBB; + for (int i = 0; i < 3; ++i) + { + for (int j = 0; j < 3; ++j) + { + negativePart->m_Q[i][j] = positivePart->m_Q[i][j] = m_Q[i][j]; + negativePart->m_D[i][j] = positivePart->m_D[i][j] = m_D[i][j]; + } + } - Tetrahedron tetrahedron; - double delta, alpha; - int sign[4]; - int npos, nneg; - Vec3 posPts[10]; - Vec3 negPts[10]; - Vec3 P0, P1, M; - const Vec3 n(plane.m_a, plane.m_b, plane.m_c); - const int edges[6][2] = { { 0, 1 }, { 0, 2 }, { 0, 3 }, { 1, 2 }, { 1, 3 }, { 2, 3 } }; - double dist; - for (size_t v = 0; v < nTetrahedra; ++v) { - tetrahedron = m_tetrahedra[v]; - npos = nneg = 0; - for (int i = 0; i < 4; ++i) { - dist = plane.m_a * tetrahedron.m_pts[i][0] + plane.m_b * tetrahedron.m_pts[i][1] + plane.m_c * tetrahedron.m_pts[i][2] + plane.m_d; - if (dist > 0.0) { - sign[i] = 1; - posPts[npos] = tetrahedron.m_pts[i]; - ++npos; - } - else { - sign[i] = -1; - negPts[nneg] = tetrahedron.m_pts[i]; - ++nneg; - } - } + Tetrahedron tetrahedron; + double delta, alpha; + int sign[4]; + int npos, nneg; + Vec3 posPts[10]; + Vec3 negPts[10]; + Vec3 P0, P1, M; + const Vec3 n(plane.m_a, plane.m_b, plane.m_c); + const int edges[6][2] = {{0, 1}, {0, 2}, {0, 3}, {1, 2}, {1, 3}, {2, 3}}; + double dist; + for (size_t v = 0; v < nTetrahedra; ++v) + { + tetrahedron = m_tetrahedra[v]; + npos = nneg = 0; + for (int i = 0; i < 4; ++i) + { + dist = plane.m_a * tetrahedron.m_pts[i][0] + plane.m_b * tetrahedron.m_pts[i][1] + plane.m_c * tetrahedron.m_pts[i][2] + plane.m_d; + if (dist > 0.0) + { + sign[i] = 1; + posPts[npos] = tetrahedron.m_pts[i]; + ++npos; + } + else + { + sign[i] = -1; + negPts[nneg] = tetrahedron.m_pts[i]; + ++nneg; + } + } - if (npos == 4) { - positivePart->Add(tetrahedron); - if (tetrahedron.m_data == PRIMITIVE_ON_SURFACE) { - ++positivePart->m_numTetrahedraOnSurface; - } - else { - ++positivePart->m_numTetrahedraInsideSurface; - } - } - else if (nneg == 4) { - negativePart->Add(tetrahedron); - if (tetrahedron.m_data == PRIMITIVE_ON_SURFACE) { - ++negativePart->m_numTetrahedraOnSurface; - } - else { - ++negativePart->m_numTetrahedraInsideSurface; - } - } - else { - int nnew = 0; - for (int j = 0; j < 6; ++j) { - if (sign[edges[j][0]] * sign[edges[j][1]] == -1) { - P0 = tetrahedron.m_pts[edges[j][0]]; - P1 = tetrahedron.m_pts[edges[j][1]]; - delta = (P0 - P1) * n; - alpha = -(plane.m_d + (n * P1)) / delta; - assert(alpha >= 0.0 && alpha <= 1.0); - M = alpha * P0 + (1 - alpha) * P1; - for (int xx = 0; xx < 3; ++xx) { - assert(M[xx] + EPS >= m_minBB[xx]); - assert(M[xx] <= m_maxBB[xx] + EPS); - } - posPts[npos++] = M; - negPts[nneg++] = M; - ++nnew; - } - } - negativePart->AddClippedTetrahedra(negPts, nneg); - positivePart->AddClippedTetrahedra(posPts, npos); - } - } + if (npos == 4) + { + positivePart->Add(tetrahedron); + if (tetrahedron.m_data == PRIMITIVE_ON_SURFACE) + { + ++positivePart->m_numTetrahedraOnSurface; + } + else + { + ++positivePart->m_numTetrahedraInsideSurface; + } + } + else if (nneg == 4) + { + negativePart->Add(tetrahedron); + if (tetrahedron.m_data == PRIMITIVE_ON_SURFACE) + { + ++negativePart->m_numTetrahedraOnSurface; + } + else + { + ++negativePart->m_numTetrahedraInsideSurface; + } + } + else + { + int nnew = 0; + for (int j = 0; j < 6; ++j) + { + if (sign[edges[j][0]] * sign[edges[j][1]] == -1) + { + P0 = tetrahedron.m_pts[edges[j][0]]; + P1 = tetrahedron.m_pts[edges[j][1]]; + delta = (P0 - P1) * n; + alpha = -(plane.m_d + (n * P1)) / delta; + assert(alpha >= 0.0 && alpha <= 1.0); + M = alpha * P0 + (1 - alpha) * P1; + for (int xx = 0; xx < 3; ++xx) + { + assert(M[xx] + EPS >= m_minBB[xx]); + assert(M[xx] <= m_maxBB[xx] + EPS); + } + posPts[npos++] = M; + negPts[nneg++] = M; + ++nnew; + } + } + negativePart->AddClippedTetrahedra(negPts, nneg); + positivePart->AddClippedTetrahedra(posPts, npos); + } + } } void TetrahedronSet::Convert(Mesh& mesh, const VOXEL_VALUE value) const { - const size_t nTetrahedra = m_tetrahedra.Size(); - if (nTetrahedra == 0) - return; - for (size_t v = 0; v < nTetrahedra; ++v) { - const Tetrahedron& tetrahedron = m_tetrahedra[v]; - if (tetrahedron.m_data == value) { - int s = (int)mesh.GetNPoints(); - mesh.AddPoint(tetrahedron.m_pts[0]); - mesh.AddPoint(tetrahedron.m_pts[1]); - mesh.AddPoint(tetrahedron.m_pts[2]); - mesh.AddPoint(tetrahedron.m_pts[3]); - mesh.AddTriangle(Vec3(s + 0, s + 1, s + 2)); - mesh.AddTriangle(Vec3(s + 2, s + 1, s + 3)); - mesh.AddTriangle(Vec3(s + 3, s + 1, s + 0)); - mesh.AddTriangle(Vec3(s + 3, s + 0, s + 2)); - } - } + const size_t nTetrahedra = m_tetrahedra.Size(); + if (nTetrahedra == 0) + return; + for (size_t v = 0; v < nTetrahedra; ++v) + { + const Tetrahedron& tetrahedron = m_tetrahedra[v]; + if (tetrahedron.m_data == value) + { + int s = (int)mesh.GetNPoints(); + mesh.AddPoint(tetrahedron.m_pts[0]); + mesh.AddPoint(tetrahedron.m_pts[1]); + mesh.AddPoint(tetrahedron.m_pts[2]); + mesh.AddPoint(tetrahedron.m_pts[3]); + mesh.AddTriangle(Vec3(s + 0, s + 1, s + 2)); + mesh.AddTriangle(Vec3(s + 2, s + 1, s + 3)); + mesh.AddTriangle(Vec3(s + 3, s + 1, s + 0)); + mesh.AddTriangle(Vec3(s + 3, s + 0, s + 2)); + } + } } const double TetrahedronSet::ComputeVolume() const { - const size_t nTetrahedra = m_tetrahedra.Size(); - if (nTetrahedra == 0) - return 0.0; - double volume = 0.0; - for (size_t v = 0; v < nTetrahedra; ++v) { - const Tetrahedron& tetrahedron = m_tetrahedra[v]; - volume += fabs(ComputeVolume4(tetrahedron.m_pts[0], tetrahedron.m_pts[1], tetrahedron.m_pts[2], tetrahedron.m_pts[3])); - } - return volume / 6.0; + const size_t nTetrahedra = m_tetrahedra.Size(); + if (nTetrahedra == 0) + return 0.0; + double volume = 0.0; + for (size_t v = 0; v < nTetrahedra; ++v) + { + const Tetrahedron& tetrahedron = m_tetrahedra[v]; + volume += fabs(ComputeVolume4(tetrahedron.m_pts[0], tetrahedron.m_pts[1], tetrahedron.m_pts[2], tetrahedron.m_pts[3])); + } + return volume / 6.0; } const double TetrahedronSet::ComputeMaxVolumeError() const { - const size_t nTetrahedra = m_tetrahedra.Size(); - if (nTetrahedra == 0) - return 0.0; - double volume = 0.0; - for (size_t v = 0; v < nTetrahedra; ++v) { - const Tetrahedron& tetrahedron = m_tetrahedra[v]; - if (tetrahedron.m_data == PRIMITIVE_ON_SURFACE) { - volume += fabs(ComputeVolume4(tetrahedron.m_pts[0], tetrahedron.m_pts[1], tetrahedron.m_pts[2], tetrahedron.m_pts[3])); - } - } - return volume / 6.0; + const size_t nTetrahedra = m_tetrahedra.Size(); + if (nTetrahedra == 0) + return 0.0; + double volume = 0.0; + for (size_t v = 0; v < nTetrahedra; ++v) + { + const Tetrahedron& tetrahedron = m_tetrahedra[v]; + if (tetrahedron.m_data == PRIMITIVE_ON_SURFACE) + { + volume += fabs(ComputeVolume4(tetrahedron.m_pts[0], tetrahedron.m_pts[1], tetrahedron.m_pts[2], tetrahedron.m_pts[3])); + } + } + return volume / 6.0; } void TetrahedronSet::RevertAlignToPrincipalAxes() { - const size_t nTetrahedra = m_tetrahedra.Size(); - if (nTetrahedra == 0) - return; - double x, y, z; - for (size_t v = 0; v < nTetrahedra; ++v) { - Tetrahedron& tetrahedron = m_tetrahedra[v]; - for (int i = 0; i < 4; ++i) { - x = tetrahedron.m_pts[i][0] - m_barycenter[0]; - y = tetrahedron.m_pts[i][1] - m_barycenter[1]; - z = tetrahedron.m_pts[i][2] - m_barycenter[2]; - tetrahedron.m_pts[i][0] = m_Q[0][0] * x + m_Q[0][1] * y + m_Q[0][2] * z + m_barycenter[0]; - tetrahedron.m_pts[i][1] = m_Q[1][0] * x + m_Q[1][1] * y + m_Q[1][2] * z + m_barycenter[1]; - tetrahedron.m_pts[i][2] = m_Q[2][0] * x + m_Q[2][1] * y + m_Q[2][2] * z + m_barycenter[2]; - } - } - ComputeBB(); + const size_t nTetrahedra = m_tetrahedra.Size(); + if (nTetrahedra == 0) + return; + double x, y, z; + for (size_t v = 0; v < nTetrahedra; ++v) + { + Tetrahedron& tetrahedron = m_tetrahedra[v]; + for (int i = 0; i < 4; ++i) + { + x = tetrahedron.m_pts[i][0] - m_barycenter[0]; + y = tetrahedron.m_pts[i][1] - m_barycenter[1]; + z = tetrahedron.m_pts[i][2] - m_barycenter[2]; + tetrahedron.m_pts[i][0] = m_Q[0][0] * x + m_Q[0][1] * y + m_Q[0][2] * z + m_barycenter[0]; + tetrahedron.m_pts[i][1] = m_Q[1][0] * x + m_Q[1][1] * y + m_Q[1][2] * z + m_barycenter[1]; + tetrahedron.m_pts[i][2] = m_Q[2][0] * x + m_Q[2][1] * y + m_Q[2][2] * z + m_barycenter[2]; + } + } + ComputeBB(); } void TetrahedronSet::ComputePrincipalAxes() { - const size_t nTetrahedra = m_tetrahedra.Size(); - if (nTetrahedra == 0) - return; - double covMat[3][3] = { { 0.0, 0.0, 0.0 }, - { 0.0, 0.0, 0.0 }, - { 0.0, 0.0, 0.0 } }; - double x, y, z; - for (size_t v = 0; v < nTetrahedra; ++v) { - Tetrahedron& tetrahedron = m_tetrahedra[v]; - for (int i = 0; i < 4; ++i) { - x = tetrahedron.m_pts[i][0] - m_barycenter[0]; - y = tetrahedron.m_pts[i][1] - m_barycenter[1]; - z = tetrahedron.m_pts[i][2] - m_barycenter[2]; - covMat[0][0] += x * x; - covMat[1][1] += y * y; - covMat[2][2] += z * z; - covMat[0][1] += x * y; - covMat[0][2] += x * z; - covMat[1][2] += y * z; - } - } - double n = nTetrahedra * 4.0; - covMat[0][0] /= n; - covMat[1][1] /= n; - covMat[2][2] /= n; - covMat[0][1] /= n; - covMat[0][2] /= n; - covMat[1][2] /= n; - covMat[1][0] = covMat[0][1]; - covMat[2][0] = covMat[0][2]; - covMat[2][1] = covMat[1][2]; - Diagonalize(covMat, m_Q, m_D); + const size_t nTetrahedra = m_tetrahedra.Size(); + if (nTetrahedra == 0) + return; + double covMat[3][3] = {{0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0}, + {0.0, 0.0, 0.0}}; + double x, y, z; + for (size_t v = 0; v < nTetrahedra; ++v) + { + Tetrahedron& tetrahedron = m_tetrahedra[v]; + for (int i = 0; i < 4; ++i) + { + x = tetrahedron.m_pts[i][0] - m_barycenter[0]; + y = tetrahedron.m_pts[i][1] - m_barycenter[1]; + z = tetrahedron.m_pts[i][2] - m_barycenter[2]; + covMat[0][0] += x * x; + covMat[1][1] += y * y; + covMat[2][2] += z * z; + covMat[0][1] += x * y; + covMat[0][2] += x * z; + covMat[1][2] += y * z; + } + } + double n = nTetrahedra * 4.0; + covMat[0][0] /= n; + covMat[1][1] /= n; + covMat[2][2] /= n; + covMat[0][1] /= n; + covMat[0][2] /= n; + covMat[1][2] /= n; + covMat[1][0] = covMat[0][1]; + covMat[2][0] = covMat[0][2]; + covMat[2][1] = covMat[1][2]; + Diagonalize(covMat, m_Q, m_D); } void TetrahedronSet::AlignToPrincipalAxes() { - const size_t nTetrahedra = m_tetrahedra.Size(); - if (nTetrahedra == 0) - return; - double x, y, z; - for (size_t v = 0; v < nTetrahedra; ++v) { - Tetrahedron& tetrahedron = m_tetrahedra[v]; - for (int i = 0; i < 4; ++i) { - x = tetrahedron.m_pts[i][0] - m_barycenter[0]; - y = tetrahedron.m_pts[i][1] - m_barycenter[1]; - z = tetrahedron.m_pts[i][2] - m_barycenter[2]; - tetrahedron.m_pts[i][0] = m_Q[0][0] * x + m_Q[1][0] * y + m_Q[2][0] * z + m_barycenter[0]; - tetrahedron.m_pts[i][1] = m_Q[0][1] * x + m_Q[1][1] * y + m_Q[2][1] * z + m_barycenter[1]; - tetrahedron.m_pts[i][2] = m_Q[0][2] * x + m_Q[1][2] * y + m_Q[2][2] * z + m_barycenter[2]; - } - } - ComputeBB(); -} + const size_t nTetrahedra = m_tetrahedra.Size(); + if (nTetrahedra == 0) + return; + double x, y, z; + for (size_t v = 0; v < nTetrahedra; ++v) + { + Tetrahedron& tetrahedron = m_tetrahedra[v]; + for (int i = 0; i < 4; ++i) + { + x = tetrahedron.m_pts[i][0] - m_barycenter[0]; + y = tetrahedron.m_pts[i][1] - m_barycenter[1]; + z = tetrahedron.m_pts[i][2] - m_barycenter[2]; + tetrahedron.m_pts[i][0] = m_Q[0][0] * x + m_Q[1][0] * y + m_Q[2][0] * z + m_barycenter[0]; + tetrahedron.m_pts[i][1] = m_Q[0][1] * x + m_Q[1][1] * y + m_Q[2][1] * z + m_barycenter[1]; + tetrahedron.m_pts[i][2] = m_Q[0][2] * x + m_Q[1][2] * y + m_Q[2][2] * z + m_barycenter[2]; + } + } + ComputeBB(); } +} // namespace VHACD diff --git a/Extras/VHACD/test/inc/oclHelper.h b/Extras/VHACD/test/inc/oclHelper.h index ff63c3006..b53e0a960 100644 --- a/Extras/VHACD/test/inc/oclHelper.h +++ b/Extras/VHACD/test/inc/oclHelper.h @@ -27,24 +27,26 @@ #include #endif -class OCLHelper { +class OCLHelper +{ public: - OCLHelper(void){}; - ~OCLHelper(void){}; - bool InitPlatform(const unsigned int platformIndex = 0); - bool InitDevice(const unsigned int deviceIndex); - bool GetPlatformsInfo(std::vector& info, const std::string& indentation); - bool GetDevicesInfo(std::vector& info, const std::string& indentation); - cl_platform_id* GetPlatform() { return &m_platform; } - const cl_platform_id* GetPlatform() const { return &m_platform; } - cl_device_id* GetDevice() { return &m_device; } - const cl_device_id* GetDevice() const { return &m_device; } + OCLHelper(void){}; + ~OCLHelper(void){}; + bool InitPlatform(const unsigned int platformIndex = 0); + bool InitDevice(const unsigned int deviceIndex); + bool GetPlatformsInfo(std::vector& info, const std::string& indentation); + bool GetDevicesInfo(std::vector& info, const std::string& indentation); + cl_platform_id* GetPlatform() { return &m_platform; } + const cl_platform_id* GetPlatform() const { return &m_platform; } + cl_device_id* GetDevice() { return &m_device; } + const cl_device_id* GetDevice() const { return &m_device; } + private: - cl_platform_id m_platform; - cl_device_id m_device; - cl_int m_lastError; + cl_platform_id m_platform; + cl_device_id m_device; + cl_int m_lastError; }; -#endif // OCL_HELPER_H +#endif // OCL_HELPER_H -#endif //OPENCL_FOUND +#endif //OPENCL_FOUND diff --git a/Extras/VHACD/test/src/main.cpp b/Extras/VHACD/test/src/main.cpp index 1c6112339..635efef62 100644 --- a/Extras/VHACD/test/src/main.cpp +++ b/Extras/VHACD/test/src/main.cpp @@ -30,636 +30,710 @@ #ifdef _CRTDBG_MAP_ALLOC #include #include -#endif // _CRTDBG_MAP_ALLOC +#endif // _CRTDBG_MAP_ALLOC #include "VHACD.h" - using namespace VHACD; using namespace std; -bool replace(std::string& str, const std::string& from, const std::string& to) { - size_t start_pos = str.find(from); - if(start_pos == std::string::npos) - return false; - str.replace(start_pos, from.length(), to); - return true; +bool replace(std::string& str, const std::string& from, const std::string& to) +{ + size_t start_pos = str.find(from); + if (start_pos == std::string::npos) + return false; + str.replace(start_pos, from.length(), to); + return true; } -class MyCallback : public IVHACD::IUserCallback { +class MyCallback : public IVHACD::IUserCallback +{ public: - MyCallback(void) {} - ~MyCallback(){}; - void Update(const double overallProgress, const double stageProgress, const double operationProgress, - const char* const stage, const char* const operation) - { - cout << setfill(' ') << setw(3) << (int)(overallProgress + 0.5) << "% " - << "[ " << stage << " " << setfill(' ') << setw(3) << (int)(stageProgress + 0.5) << "% ] " - << operation << " " << setfill(' ') << setw(3) << (int)(operationProgress + 0.5) << "%" << endl; - }; + MyCallback(void) {} + ~MyCallback(){}; + void Update(const double overallProgress, const double stageProgress, const double operationProgress, + const char* const stage, const char* const operation) + { + cout << setfill(' ') << setw(3) << (int)(overallProgress + 0.5) << "% " + << "[ " << stage << " " << setfill(' ') << setw(3) << (int)(stageProgress + 0.5) << "% ] " + << operation << " " << setfill(' ') << setw(3) << (int)(operationProgress + 0.5) << "%" << endl; + }; }; -class MyLogger : public IVHACD::IUserLogger { +class MyLogger : public IVHACD::IUserLogger +{ public: - MyLogger(void) {} - MyLogger(const string& fileName) { OpenFile(fileName); } - ~MyLogger(){}; - void Log(const char* const msg) - { - if (m_file.is_open()) { - m_file << msg; - m_file.flush(); - } - } - void OpenFile(const string& fileName) - { - m_file.open(fileName.c_str()); - } + MyLogger(void) {} + MyLogger(const string& fileName) { OpenFile(fileName); } + ~MyLogger(){}; + void Log(const char* const msg) + { + if (m_file.is_open()) + { + m_file << msg; + m_file.flush(); + } + } + void OpenFile(const string& fileName) + { + m_file.open(fileName.c_str()); + } private: - ofstream m_file; + ofstream m_file; }; -struct Material { - - float m_diffuseColor[3]; - float m_ambientIntensity; - float m_specularColor[3]; - float m_emissiveColor[3]; - float m_shininess; - float m_transparency; - Material(void) - { - m_diffuseColor[0] = 0.5f; - m_diffuseColor[1] = 0.5f; - m_diffuseColor[2] = 0.5f; - m_specularColor[0] = 0.5f; - m_specularColor[1] = 0.5f; - m_specularColor[2] = 0.5f; - m_ambientIntensity = 0.4f; - m_emissiveColor[0] = 0.0f; - m_emissiveColor[1] = 0.0f; - m_emissiveColor[2] = 0.0f; - m_shininess = 0.4f; - m_transparency = 0.5f; - }; +struct Material +{ + float m_diffuseColor[3]; + float m_ambientIntensity; + float m_specularColor[3]; + float m_emissiveColor[3]; + float m_shininess; + float m_transparency; + Material(void) + { + m_diffuseColor[0] = 0.5f; + m_diffuseColor[1] = 0.5f; + m_diffuseColor[2] = 0.5f; + m_specularColor[0] = 0.5f; + m_specularColor[1] = 0.5f; + m_specularColor[2] = 0.5f; + m_ambientIntensity = 0.4f; + m_emissiveColor[0] = 0.0f; + m_emissiveColor[1] = 0.0f; + m_emissiveColor[2] = 0.0f; + m_shininess = 0.4f; + m_transparency = 0.5f; + }; }; -struct Parameters { - unsigned int m_oclPlatformID; - unsigned int m_oclDeviceID; - string m_fileNameIn; - string m_fileNameOut; - string m_fileNameLog; - bool m_run; - IVHACD::Parameters m_paramsVHACD; - Parameters(void) - { - m_run = true; - m_oclPlatformID = 0; - m_oclDeviceID = 0; - m_fileNameIn = ""; - m_fileNameOut = "output.obj"; - m_fileNameLog = "log.txt"; - } +struct Parameters +{ + unsigned int m_oclPlatformID; + unsigned int m_oclDeviceID; + string m_fileNameIn; + string m_fileNameOut; + string m_fileNameLog; + bool m_run; + IVHACD::Parameters m_paramsVHACD; + Parameters(void) + { + m_run = true; + m_oclPlatformID = 0; + m_oclDeviceID = 0; + m_fileNameIn = ""; + m_fileNameOut = "output.obj"; + m_fileNameLog = "log.txt"; + } }; bool LoadOFF(const string& fileName, vector& points, vector& triangles, IVHACD::IUserLogger& logger); bool LoadOBJ(const string& fileName, vector& points, vector& triangles, IVHACD::IUserLogger& logger); bool SaveOFF(const string& fileName, const float* const& points, const int* const& triangles, const unsigned int& nPoints, - const unsigned int& nTriangles, IVHACD::IUserLogger& logger); + const unsigned int& nTriangles, IVHACD::IUserLogger& logger); bool SaveOBJ(ofstream& fout, const double* const& points, const int* const& triangles, const unsigned int& nPoints, - const unsigned int& nTriangles, const Material& material, IVHACD::IUserLogger& logger, int convexPart, int vertexOffset); + const unsigned int& nTriangles, const Material& material, IVHACD::IUserLogger& logger, int convexPart, int vertexOffset); bool SaveVRML2(ofstream& fout, const double* const& points, const int* const& triangles, const unsigned int& nPoints, - const unsigned int& nTriangles, const Material& material, IVHACD::IUserLogger& logger); + const unsigned int& nTriangles, const Material& material, IVHACD::IUserLogger& logger); void GetFileExtension(const string& fileName, string& fileExtension); void ComputeRandomColor(Material& mat); void Usage(const Parameters& params); void ParseParameters(int argc, char* argv[], Parameters& params); - int main(int argc, char* argv[]) { - // --input camel.off --output camel_acd.obj --log log.txt --resolution 1000000 --depth 20 --concavity 0.0025 --planeDownsampling 4 --convexhullDownsampling 4 --alpha 0.05 --beta 0.05 --gamma 0.00125 --pca 0 --mode 0 --maxNumVerticesPerCH 256 --minVolumePerCH 0.0001 --convexhullApproximation 1 --oclDeviceID 2 - { - // set parameters - Parameters params; - ParseParameters(argc, argv, params); - MyCallback myCallback; - MyLogger myLogger(params.m_fileNameLog); - params.m_paramsVHACD.m_logger = &myLogger; - params.m_paramsVHACD.m_callback = &myCallback; - Usage(params); - if (!params.m_run) { - return 0; - } + // --input camel.off --output camel_acd.obj --log log.txt --resolution 1000000 --depth 20 --concavity 0.0025 --planeDownsampling 4 --convexhullDownsampling 4 --alpha 0.05 --beta 0.05 --gamma 0.00125 --pca 0 --mode 0 --maxNumVerticesPerCH 256 --minVolumePerCH 0.0001 --convexhullApproximation 1 --oclDeviceID 2 + { + // set parameters + Parameters params; + ParseParameters(argc, argv, params); + MyCallback myCallback; + MyLogger myLogger(params.m_fileNameLog); + params.m_paramsVHACD.m_logger = &myLogger; + params.m_paramsVHACD.m_callback = &myCallback; + Usage(params); + if (!params.m_run) + { + return 0; + } - std::ostringstream msg; + std::ostringstream msg; - msg << "+ OpenCL (OFF)" << std::endl; + msg << "+ OpenCL (OFF)" << std::endl; - msg << "+ Parameters" << std::endl; - msg << "\t input " << params.m_fileNameIn << endl; - msg << "\t resolution " << params.m_paramsVHACD.m_resolution << endl; - msg << "\t max. depth " << params.m_paramsVHACD.m_depth << endl; - msg << "\t max. concavity " << params.m_paramsVHACD.m_concavity << endl; - msg << "\t plane down-sampling " << params.m_paramsVHACD.m_planeDownsampling << endl; - msg << "\t convex-hull down-sampling " << params.m_paramsVHACD.m_convexhullDownsampling << endl; - msg << "\t alpha " << params.m_paramsVHACD.m_alpha << endl; - msg << "\t beta " << params.m_paramsVHACD.m_beta << endl; - msg << "\t gamma " << params.m_paramsVHACD.m_gamma << endl; - msg << "\t pca " << params.m_paramsVHACD.m_pca << endl; - msg << "\t mode " << params.m_paramsVHACD.m_mode << endl; - msg << "\t max. vertices per convex-hull " << params.m_paramsVHACD.m_maxNumVerticesPerCH << endl; - msg << "\t min. volume to add vertices to convex-hulls " << params.m_paramsVHACD.m_minVolumePerCH << endl; - msg << "\t convex-hull approximation " << params.m_paramsVHACD.m_convexhullApproximation << endl; - msg << "\t OpenCL acceleration " << params.m_paramsVHACD.m_oclAcceleration << endl; - msg << "\t OpenCL platform ID " << params.m_oclPlatformID << endl; - msg << "\t OpenCL device ID " << params.m_oclDeviceID << endl; - msg << "\t output " << params.m_fileNameOut << endl; - msg << "\t log " << params.m_fileNameLog << endl; - msg << "+ Load mesh" << std::endl; - myLogger.Log(msg.str().c_str()); + msg << "+ Parameters" << std::endl; + msg << "\t input " << params.m_fileNameIn << endl; + msg << "\t resolution " << params.m_paramsVHACD.m_resolution << endl; + msg << "\t max. depth " << params.m_paramsVHACD.m_depth << endl; + msg << "\t max. concavity " << params.m_paramsVHACD.m_concavity << endl; + msg << "\t plane down-sampling " << params.m_paramsVHACD.m_planeDownsampling << endl; + msg << "\t convex-hull down-sampling " << params.m_paramsVHACD.m_convexhullDownsampling << endl; + msg << "\t alpha " << params.m_paramsVHACD.m_alpha << endl; + msg << "\t beta " << params.m_paramsVHACD.m_beta << endl; + msg << "\t gamma " << params.m_paramsVHACD.m_gamma << endl; + msg << "\t pca " << params.m_paramsVHACD.m_pca << endl; + msg << "\t mode " << params.m_paramsVHACD.m_mode << endl; + msg << "\t max. vertices per convex-hull " << params.m_paramsVHACD.m_maxNumVerticesPerCH << endl; + msg << "\t min. volume to add vertices to convex-hulls " << params.m_paramsVHACD.m_minVolumePerCH << endl; + msg << "\t convex-hull approximation " << params.m_paramsVHACD.m_convexhullApproximation << endl; + msg << "\t OpenCL acceleration " << params.m_paramsVHACD.m_oclAcceleration << endl; + msg << "\t OpenCL platform ID " << params.m_oclPlatformID << endl; + msg << "\t OpenCL device ID " << params.m_oclDeviceID << endl; + msg << "\t output " << params.m_fileNameOut << endl; + msg << "\t log " << params.m_fileNameLog << endl; + msg << "+ Load mesh" << std::endl; + myLogger.Log(msg.str().c_str()); - cout << msg.str().c_str(); + cout << msg.str().c_str(); - // load mesh - vector points; - vector triangles; - string fileExtension; - GetFileExtension(params.m_fileNameIn, fileExtension); - if (fileExtension == ".OFF") { - if (!LoadOFF(params.m_fileNameIn, points, triangles, myLogger)) { - return -1; - } - } - else if (fileExtension == ".OBJ") { - if (!LoadOBJ(params.m_fileNameIn, points, triangles, myLogger)) { - return -1; - } - } - else { - myLogger.Log("Format not supported!\n"); - return -1; - } + // load mesh + vector points; + vector triangles; + string fileExtension; + GetFileExtension(params.m_fileNameIn, fileExtension); + if (fileExtension == ".OFF") + { + if (!LoadOFF(params.m_fileNameIn, points, triangles, myLogger)) + { + return -1; + } + } + else if (fileExtension == ".OBJ") + { + if (!LoadOBJ(params.m_fileNameIn, points, triangles, myLogger)) + { + return -1; + } + } + else + { + myLogger.Log("Format not supported!\n"); + return -1; + } - // run V-HACD - IVHACD* interfaceVHACD = CreateVHACD(); + // run V-HACD + IVHACD* interfaceVHACD = CreateVHACD(); #ifdef CL_VERSION_1_1 - if (params.m_paramsVHACD.m_oclAcceleration) { - bool res = interfaceVHACD->OCLInit(oclHelper.GetDevice(), &myLogger); - if (!res) { - params.m_paramsVHACD.m_oclAcceleration = false; - } - } -#endif //CL_VERSION_1_1 - bool res = interfaceVHACD->Compute(&points[0], 3, (unsigned int)points.size() / 3, - &triangles[0], 3, (unsigned int)triangles.size() / 3, params.m_paramsVHACD); - if (res) { - // save output - unsigned int nConvexHulls = interfaceVHACD->GetNConvexHulls(); - msg.str(""); - msg << "+ Generate output: " << nConvexHulls << " convex-hulls " << endl; - myLogger.Log(msg.str().c_str()); - ofstream foutCH(params.m_fileNameOut.c_str()); - IVHACD::ConvexHull ch; - if (foutCH.is_open()) { - Material mat; - int vertexOffset = 1;//obj wavefront starts counting at 1... - for (unsigned int p = 0; p < nConvexHulls; ++p) { - interfaceVHACD->GetConvexHull(p, ch); - - - SaveOBJ(foutCH, ch.m_points, ch.m_triangles, ch.m_nPoints, ch.m_nTriangles, mat, myLogger, p, vertexOffset); - vertexOffset+=ch.m_nPoints; - msg.str(""); - msg << "\t CH[" << setfill('0') << setw(5) << p << "] " << ch.m_nPoints << " V, " << ch.m_nTriangles << " T" << endl; - myLogger.Log(msg.str().c_str()); - } - foutCH.close(); - } - } - else { - myLogger.Log("Decomposition cancelled by user!\n"); - } + if (params.m_paramsVHACD.m_oclAcceleration) + { + bool res = interfaceVHACD->OCLInit(oclHelper.GetDevice(), &myLogger); + if (!res) + { + params.m_paramsVHACD.m_oclAcceleration = false; + } + } +#endif //CL_VERSION_1_1 + bool res = interfaceVHACD->Compute(&points[0], 3, (unsigned int)points.size() / 3, + &triangles[0], 3, (unsigned int)triangles.size() / 3, params.m_paramsVHACD); + if (res) + { + // save output + unsigned int nConvexHulls = interfaceVHACD->GetNConvexHulls(); + msg.str(""); + msg << "+ Generate output: " << nConvexHulls << " convex-hulls " << endl; + myLogger.Log(msg.str().c_str()); + ofstream foutCH(params.m_fileNameOut.c_str()); + IVHACD::ConvexHull ch; + if (foutCH.is_open()) + { + Material mat; + int vertexOffset = 1; //obj wavefront starts counting at 1... + for (unsigned int p = 0; p < nConvexHulls; ++p) + { + interfaceVHACD->GetConvexHull(p, ch); + + SaveOBJ(foutCH, ch.m_points, ch.m_triangles, ch.m_nPoints, ch.m_nTriangles, mat, myLogger, p, vertexOffset); + vertexOffset += ch.m_nPoints; + msg.str(""); + msg << "\t CH[" << setfill('0') << setw(5) << p << "] " << ch.m_nPoints << " V, " << ch.m_nTriangles << " T" << endl; + myLogger.Log(msg.str().c_str()); + } + foutCH.close(); + } + } + else + { + myLogger.Log("Decomposition cancelled by user!\n"); + } #ifdef CL_VERSION_1_1 - if (params.m_paramsVHACD.m_oclAcceleration) { - bool res = interfaceVHACD->OCLRelease(&myLogger); - if (!res) { - assert(-1); - } - } -#endif //CL_VERSION_1_1 + if (params.m_paramsVHACD.m_oclAcceleration) + { + bool res = interfaceVHACD->OCLRelease(&myLogger); + if (!res) + { + assert(-1); + } + } +#endif //CL_VERSION_1_1 - interfaceVHACD->Clean(); - interfaceVHACD->Release(); - } + interfaceVHACD->Clean(); + interfaceVHACD->Release(); + } #ifdef _CRTDBG_MAP_ALLOC - _CrtDumpMemoryLeaks(); -#endif // _CRTDBG_MAP_ALLOC - return 0; + _CrtDumpMemoryLeaks(); +#endif // _CRTDBG_MAP_ALLOC + return 0; } void Usage(const Parameters& params) { - std::ostringstream msg; - msg << "V-HACD V" << VHACD_VERSION_MAJOR << "." << VHACD_VERSION_MINOR << endl; - msg << "Syntax: testVHACD [options] --input infile.obj --output outfile.obj --log logfile.txt" << endl - << endl; - msg << "Options:" << endl; - msg << " --input Wavefront .obj input file name" << endl; - msg << " --output VRML 2.0 output file name" << endl; - msg << " --log Log file name" << endl; - msg << " --resolution Maximum number of voxels generated during the voxelization stage (default=100,000, range=10,000-16,000,000)" << endl; - msg << " --depth Maximum number of clipping stages. During each split stage, parts with a concavity higher than the user defined threshold are clipped according the \"best\" clipping plane (default=20, range=1-32)" << endl; - msg << " --concavity Maximum allowed concavity (default=0.0025, range=0.0-1.0)" << endl; - msg << " --planeDownsampling Controls the granularity of the search for the \"best\" clipping plane (default=4, range=1-16)" << endl; - msg << " --convexhullDownsampling Controls the precision of the convex-hull generation process during the clipping plane selection stage (default=4, range=1-16)" << endl; - msg << " --alpha Controls the bias toward clipping along symmetry planes (default=0.05, range=0.0-1.0)" << endl; - msg << " --beta Controls the bias toward clipping along revolution axes (default=0.05, range=0.0-1.0)" << endl; - msg << " --gamma Controls the maximum allowed concavity during the merge stage (default=0.00125, range=0.0-1.0)" << endl; - msg << " --delta Controls the bias toward maximaxing local concavity (default=0.05, range=0.0-1.0)" << endl; - msg << " --pca Enable/disable normalizing the mesh before applying the convex decomposition (default=0, range={0,1})" << endl; - msg << " --mode 0: voxel-based approximate convex decomposition, 1: tetrahedron-based approximate convex decomposition (default=0, range={0,1})" << endl; - msg << " --maxNumVerticesPerCH Controls the maximum number of triangles per convex-hull (default=64, range=4-1024)" << endl; - msg << " --minVolumePerCH Controls the adaptive sampling of the generated convex-hulls (default=0.0001, range=0.0-0.01)" << endl; - msg << " --convexhullApproximation Enable/disable approximation when computing convex-hulls (default=1, range={0,1})" << endl; - msg << " --oclAcceleration Enable/disable OpenCL acceleration (default=0, range={0,1})" << endl; - msg << " --oclPlatformID OpenCL platform id (default=0, range=0-# OCL platforms)" << endl; - msg << " --oclDeviceID OpenCL device id (default=0, range=0-# OCL devices)" << endl; - msg << " --help Print usage" << endl - << endl; - msg << "Examples:" << endl; - msg << " testVHACD.exe --input bunny.obj --output bunny_acd.obj --log log.txt" << endl - << endl; - cout << msg.str(); - if (params.m_paramsVHACD.m_logger) { - params.m_paramsVHACD.m_logger->Log(msg.str().c_str()); - } + std::ostringstream msg; + msg << "V-HACD V" << VHACD_VERSION_MAJOR << "." << VHACD_VERSION_MINOR << endl; + msg << "Syntax: testVHACD [options] --input infile.obj --output outfile.obj --log logfile.txt" << endl + << endl; + msg << "Options:" << endl; + msg << " --input Wavefront .obj input file name" << endl; + msg << " --output VRML 2.0 output file name" << endl; + msg << " --log Log file name" << endl; + msg << " --resolution Maximum number of voxels generated during the voxelization stage (default=100,000, range=10,000-16,000,000)" << endl; + msg << " --depth Maximum number of clipping stages. During each split stage, parts with a concavity higher than the user defined threshold are clipped according the \"best\" clipping plane (default=20, range=1-32)" << endl; + msg << " --concavity Maximum allowed concavity (default=0.0025, range=0.0-1.0)" << endl; + msg << " --planeDownsampling Controls the granularity of the search for the \"best\" clipping plane (default=4, range=1-16)" << endl; + msg << " --convexhullDownsampling Controls the precision of the convex-hull generation process during the clipping plane selection stage (default=4, range=1-16)" << endl; + msg << " --alpha Controls the bias toward clipping along symmetry planes (default=0.05, range=0.0-1.0)" << endl; + msg << " --beta Controls the bias toward clipping along revolution axes (default=0.05, range=0.0-1.0)" << endl; + msg << " --gamma Controls the maximum allowed concavity during the merge stage (default=0.00125, range=0.0-1.0)" << endl; + msg << " --delta Controls the bias toward maximaxing local concavity (default=0.05, range=0.0-1.0)" << endl; + msg << " --pca Enable/disable normalizing the mesh before applying the convex decomposition (default=0, range={0,1})" << endl; + msg << " --mode 0: voxel-based approximate convex decomposition, 1: tetrahedron-based approximate convex decomposition (default=0, range={0,1})" << endl; + msg << " --maxNumVerticesPerCH Controls the maximum number of triangles per convex-hull (default=64, range=4-1024)" << endl; + msg << " --minVolumePerCH Controls the adaptive sampling of the generated convex-hulls (default=0.0001, range=0.0-0.01)" << endl; + msg << " --convexhullApproximation Enable/disable approximation when computing convex-hulls (default=1, range={0,1})" << endl; + msg << " --oclAcceleration Enable/disable OpenCL acceleration (default=0, range={0,1})" << endl; + msg << " --oclPlatformID OpenCL platform id (default=0, range=0-# OCL platforms)" << endl; + msg << " --oclDeviceID OpenCL device id (default=0, range=0-# OCL devices)" << endl; + msg << " --help Print usage" << endl + << endl; + msg << "Examples:" << endl; + msg << " testVHACD.exe --input bunny.obj --output bunny_acd.obj --log log.txt" << endl + << endl; + cout << msg.str(); + if (params.m_paramsVHACD.m_logger) + { + params.m_paramsVHACD.m_logger->Log(msg.str().c_str()); + } } void ParseParameters(int argc, char* argv[], Parameters& params) { - for (int i = 1; i < argc; ++i) { - if (!strcmp(argv[i], "--input")) { - if (++i < argc) + for (int i = 1; i < argc; ++i) + { + if (!strcmp(argv[i], "--input")) { - params.m_fileNameIn = argv[i]; - //come up with some default output name, if not provided - if (params.m_fileNameOut.length()==0) + if (++i < argc) + { + params.m_fileNameIn = argv[i]; + //come up with some default output name, if not provided + if (params.m_fileNameOut.length() == 0) + { + string tmp = argv[i]; + replace(tmp, ".obj", ".vhacd.obj"); + params.m_fileNameOut = tmp; + } + } + } + else if (!strcmp(argv[i], "--output")) { - string tmp = argv[i]; - replace(tmp,".obj",".vhacd.obj"); - params.m_fileNameOut = tmp; + if (++i < argc) + params.m_fileNameOut = argv[i]; } + else if (!strcmp(argv[i], "--log")) + { + if (++i < argc) + params.m_fileNameLog = argv[i]; } - } - else if (!strcmp(argv[i], "--output")) { - if (++i < argc) - params.m_fileNameOut = argv[i]; - } - else if (!strcmp(argv[i], "--log")) { - if (++i < argc) - params.m_fileNameLog = argv[i]; - } - else if (!strcmp(argv[i], "--resolution")) { - if (++i < argc) - params.m_paramsVHACD.m_resolution = atoi(argv[i]); - } - else if (!strcmp(argv[i], "--depth")) { - if (++i < argc) - params.m_paramsVHACD.m_depth = atoi(argv[i]); - } - else if (!strcmp(argv[i], "--concavity")) { - if (++i < argc) - params.m_paramsVHACD.m_concavity = atof(argv[i]); - } - else if (!strcmp(argv[i], "--planeDownsampling")) { - if (++i < argc) - params.m_paramsVHACD.m_planeDownsampling = atoi(argv[i]); - } - else if (!strcmp(argv[i], "--convexhullDownsampling")) { - if (++i < argc) - params.m_paramsVHACD.m_convexhullDownsampling = atoi(argv[i]); - } - else if (!strcmp(argv[i], "--alpha")) { - if (++i < argc) - params.m_paramsVHACD.m_alpha = atof(argv[i]); - } - else if (!strcmp(argv[i], "--beta")) { - if (++i < argc) - params.m_paramsVHACD.m_beta = atof(argv[i]); - } - else if (!strcmp(argv[i], "--gamma")) { - if (++i < argc) - params.m_paramsVHACD.m_gamma = atof(argv[i]); - } - else if (!strcmp(argv[i], "--pca")) { - if (++i < argc) - params.m_paramsVHACD.m_pca = atoi(argv[i]); - } - else if (!strcmp(argv[i], "--mode")) { - if (++i < argc) - params.m_paramsVHACD.m_mode = atoi(argv[i]); - } - else if (!strcmp(argv[i], "--maxNumVerticesPerCH")) { - if (++i < argc) - params.m_paramsVHACD.m_maxNumVerticesPerCH = atoi(argv[i]); - } - else if (!strcmp(argv[i], "--minVolumePerCH")) { - if (++i < argc) - params.m_paramsVHACD.m_minVolumePerCH = atof(argv[i]); - } - else if (!strcmp(argv[i], "--convexhullApproximation")) { - if (++i < argc) - params.m_paramsVHACD.m_convexhullApproximation = atoi(argv[i]); - } - else if (!strcmp(argv[i], "--oclAcceleration")) { - if (++i < argc) - params.m_paramsVHACD.m_oclAcceleration = atoi(argv[i]); - } - else if (!strcmp(argv[i], "--oclPlatformID")) { - if (++i < argc) - params.m_oclPlatformID = atoi(argv[i]); - } - else if (!strcmp(argv[i], "--oclDeviceID")) { - if (++i < argc) - params.m_oclDeviceID = atoi(argv[i]); - } - else if (!strcmp(argv[i], "--help")) { - params.m_run = false; - } - } - params.m_paramsVHACD.m_resolution = (params.m_paramsVHACD.m_resolution < 64) ? 0 : params.m_paramsVHACD.m_resolution; - params.m_paramsVHACD.m_planeDownsampling = (params.m_paramsVHACD.m_planeDownsampling < 1) ? 1 : params.m_paramsVHACD.m_planeDownsampling; - params.m_paramsVHACD.m_convexhullDownsampling = (params.m_paramsVHACD.m_convexhullDownsampling < 1) ? 1 : params.m_paramsVHACD.m_convexhullDownsampling; + else if (!strcmp(argv[i], "--resolution")) + { + if (++i < argc) + params.m_paramsVHACD.m_resolution = atoi(argv[i]); + } + else if (!strcmp(argv[i], "--depth")) + { + if (++i < argc) + params.m_paramsVHACD.m_depth = atoi(argv[i]); + } + else if (!strcmp(argv[i], "--concavity")) + { + if (++i < argc) + params.m_paramsVHACD.m_concavity = atof(argv[i]); + } + else if (!strcmp(argv[i], "--planeDownsampling")) + { + if (++i < argc) + params.m_paramsVHACD.m_planeDownsampling = atoi(argv[i]); + } + else if (!strcmp(argv[i], "--convexhullDownsampling")) + { + if (++i < argc) + params.m_paramsVHACD.m_convexhullDownsampling = atoi(argv[i]); + } + else if (!strcmp(argv[i], "--alpha")) + { + if (++i < argc) + params.m_paramsVHACD.m_alpha = atof(argv[i]); + } + else if (!strcmp(argv[i], "--beta")) + { + if (++i < argc) + params.m_paramsVHACD.m_beta = atof(argv[i]); + } + else if (!strcmp(argv[i], "--gamma")) + { + if (++i < argc) + params.m_paramsVHACD.m_gamma = atof(argv[i]); + } + else if (!strcmp(argv[i], "--pca")) + { + if (++i < argc) + params.m_paramsVHACD.m_pca = atoi(argv[i]); + } + else if (!strcmp(argv[i], "--mode")) + { + if (++i < argc) + params.m_paramsVHACD.m_mode = atoi(argv[i]); + } + else if (!strcmp(argv[i], "--maxNumVerticesPerCH")) + { + if (++i < argc) + params.m_paramsVHACD.m_maxNumVerticesPerCH = atoi(argv[i]); + } + else if (!strcmp(argv[i], "--minVolumePerCH")) + { + if (++i < argc) + params.m_paramsVHACD.m_minVolumePerCH = atof(argv[i]); + } + else if (!strcmp(argv[i], "--convexhullApproximation")) + { + if (++i < argc) + params.m_paramsVHACD.m_convexhullApproximation = atoi(argv[i]); + } + else if (!strcmp(argv[i], "--oclAcceleration")) + { + if (++i < argc) + params.m_paramsVHACD.m_oclAcceleration = atoi(argv[i]); + } + else if (!strcmp(argv[i], "--oclPlatformID")) + { + if (++i < argc) + params.m_oclPlatformID = atoi(argv[i]); + } + else if (!strcmp(argv[i], "--oclDeviceID")) + { + if (++i < argc) + params.m_oclDeviceID = atoi(argv[i]); + } + else if (!strcmp(argv[i], "--help")) + { + params.m_run = false; + } + } + params.m_paramsVHACD.m_resolution = (params.m_paramsVHACD.m_resolution < 64) ? 0 : params.m_paramsVHACD.m_resolution; + params.m_paramsVHACD.m_planeDownsampling = (params.m_paramsVHACD.m_planeDownsampling < 1) ? 1 : params.m_paramsVHACD.m_planeDownsampling; + params.m_paramsVHACD.m_convexhullDownsampling = (params.m_paramsVHACD.m_convexhullDownsampling < 1) ? 1 : params.m_paramsVHACD.m_convexhullDownsampling; } void GetFileExtension(const string& fileName, string& fileExtension) { - size_t lastDotPosition = fileName.find_last_of("."); - if (lastDotPosition == string::npos) { - fileExtension = ""; - } - else { - fileExtension = fileName.substr(lastDotPosition, fileName.size()); - transform(fileExtension.begin(), fileExtension.end(), fileExtension.begin(), ::toupper); - } + size_t lastDotPosition = fileName.find_last_of("."); + if (lastDotPosition == string::npos) + { + fileExtension = ""; + } + else + { + fileExtension = fileName.substr(lastDotPosition, fileName.size()); + transform(fileExtension.begin(), fileExtension.end(), fileExtension.begin(), ::toupper); + } } void ComputeRandomColor(Material& mat) { - mat.m_diffuseColor[0] = mat.m_diffuseColor[1] = mat.m_diffuseColor[2] = 0.0f; - while (mat.m_diffuseColor[0] == mat.m_diffuseColor[1] || mat.m_diffuseColor[2] == mat.m_diffuseColor[1] || mat.m_diffuseColor[2] == mat.m_diffuseColor[0]) { - mat.m_diffuseColor[0] = (rand() % 100) / 100.0f; - mat.m_diffuseColor[1] = (rand() % 100) / 100.0f; - mat.m_diffuseColor[2] = (rand() % 100) / 100.0f; - } + mat.m_diffuseColor[0] = mat.m_diffuseColor[1] = mat.m_diffuseColor[2] = 0.0f; + while (mat.m_diffuseColor[0] == mat.m_diffuseColor[1] || mat.m_diffuseColor[2] == mat.m_diffuseColor[1] || mat.m_diffuseColor[2] == mat.m_diffuseColor[0]) + { + mat.m_diffuseColor[0] = (rand() % 100) / 100.0f; + mat.m_diffuseColor[1] = (rand() % 100) / 100.0f; + mat.m_diffuseColor[2] = (rand() % 100) / 100.0f; + } } bool LoadOFF(const string& fileName, vector& points, vector& triangles, IVHACD::IUserLogger& logger) { - FILE* fid = fopen(fileName.c_str(), "r"); - if (fid) { - const string strOFF("OFF"); - char temp[1024]; - fscanf(fid, "%s", temp); - if (string(temp) != strOFF) { - logger.Log("Loading error: format not recognized \n"); - fclose(fid); - return false; - } - else { - int nv = 0; - int nf = 0; - int ne = 0; - fscanf(fid, "%i", &nv); - fscanf(fid, "%i", &nf); - fscanf(fid, "%i", &ne); - points.resize(nv * 3); - triangles.resize(nf * 3); - const int np = nv * 3; - for (int p = 0; p < np; p++) { - fscanf(fid, "%f", &(points[p])); - } - int s; - for (int t = 0, r = 0; t < nf; ++t) { - fscanf(fid, "%i", &s); - if (s == 3) { - fscanf(fid, "%i", &(triangles[r++])); - fscanf(fid, "%i", &(triangles[r++])); - fscanf(fid, "%i", &(triangles[r++])); - } - else // Fix me: support only triangular meshes - { - for (int h = 0; h < s; ++h) - fscanf(fid, "%i", &s); - } - } - fclose(fid); - } - } - else { - logger.Log("Loading error: file not found \n"); - return false; - } - return true; + FILE* fid = fopen(fileName.c_str(), "r"); + if (fid) + { + const string strOFF("OFF"); + char temp[1024]; + fscanf(fid, "%s", temp); + if (string(temp) != strOFF) + { + logger.Log("Loading error: format not recognized \n"); + fclose(fid); + return false; + } + else + { + int nv = 0; + int nf = 0; + int ne = 0; + fscanf(fid, "%i", &nv); + fscanf(fid, "%i", &nf); + fscanf(fid, "%i", &ne); + points.resize(nv * 3); + triangles.resize(nf * 3); + const int np = nv * 3; + for (int p = 0; p < np; p++) + { + fscanf(fid, "%f", &(points[p])); + } + int s; + for (int t = 0, r = 0; t < nf; ++t) + { + fscanf(fid, "%i", &s); + if (s == 3) + { + fscanf(fid, "%i", &(triangles[r++])); + fscanf(fid, "%i", &(triangles[r++])); + fscanf(fid, "%i", &(triangles[r++])); + } + else // Fix me: support only triangular meshes + { + for (int h = 0; h < s; ++h) + fscanf(fid, "%i", &s); + } + } + fclose(fid); + } + } + else + { + logger.Log("Loading error: file not found \n"); + return false; + } + return true; } bool LoadOBJ(const string& fileName, vector& points, vector& triangles, IVHACD::IUserLogger& logger) { - const unsigned int BufferSize = 1024; - FILE* fid = fopen(fileName.c_str(), "r"); + const unsigned int BufferSize = 1024; + FILE* fid = fopen(fileName.c_str(), "r"); - if (fid) { - char buffer[BufferSize]; - int ip[4]; - float x[3]; - char* pch; - char* str; - while (!feof(fid)) { - if (!fgets(buffer, BufferSize, fid)) { - break; - } - else if (buffer[0] == 'v') { - if (buffer[1] == ' ') { - str = buffer + 2; - for (int k = 0; k < 3; ++k) { - pch = strtok(str, " "); - if (pch) - x[k] = (float)atof(pch); - else { - return false; - } - str = NULL; - } - points.push_back(x[0]); - points.push_back(x[1]); - points.push_back(x[2]); - } - } - else if (buffer[0] == 'f') { + if (fid) + { + char buffer[BufferSize]; + int ip[4]; + float x[3]; + char* pch; + char* str; + while (!feof(fid)) + { + if (!fgets(buffer, BufferSize, fid)) + { + break; + } + else if (buffer[0] == 'v') + { + if (buffer[1] == ' ') + { + str = buffer + 2; + for (int k = 0; k < 3; ++k) + { + pch = strtok(str, " "); + if (pch) + x[k] = (float)atof(pch); + else + { + return false; + } + str = NULL; + } + points.push_back(x[0]); + points.push_back(x[1]); + points.push_back(x[2]); + } + } + else if (buffer[0] == 'f') + { + pch = str = buffer + 2; + int k = 0; + while (pch) + { + pch = strtok(str, " "); + if (pch) + { + ip[k++] = atoi(pch) - 1; + } + else + { + break; + } + str = NULL; + } + if (k == 3) + { + triangles.push_back(ip[0]); + triangles.push_back(ip[1]); + triangles.push_back(ip[2]); + } + else if (k == 4) + { + triangles.push_back(ip[0]); + triangles.push_back(ip[1]); + triangles.push_back(ip[2]); - pch = str = buffer + 2; - int k = 0; - while (pch) { - pch = strtok(str, " "); - if (pch) { - ip[k++] = atoi(pch) - 1; - } - else { - break; - } - str = NULL; - } - if (k == 3) { - triangles.push_back(ip[0]); - triangles.push_back(ip[1]); - triangles.push_back(ip[2]); - } - else if (k == 4) { - triangles.push_back(ip[0]); - triangles.push_back(ip[1]); - triangles.push_back(ip[2]); - - triangles.push_back(ip[0]); - triangles.push_back(ip[2]); - triangles.push_back(ip[3]); - } - } - } - fclose(fid); - } - else { - logger.Log("File not found\n"); - return false; - } - return true; + triangles.push_back(ip[0]); + triangles.push_back(ip[2]); + triangles.push_back(ip[3]); + } + } + } + fclose(fid); + } + else + { + logger.Log("File not found\n"); + return false; + } + return true; } bool SaveOFF(const string& fileName, const float* const& points, const int* const& triangles, const unsigned int& nPoints, - const unsigned int& nTriangles, IVHACD::IUserLogger& logger) + const unsigned int& nTriangles, IVHACD::IUserLogger& logger) { - ofstream fout(fileName.c_str()); - if (fout.is_open()) { - size_t nV = nPoints * 3; - size_t nT = nTriangles * 3; - fout << "OFF" << std::endl; - fout << nPoints << " " << nTriangles << " " << 0 << std::endl; - for (size_t v = 0; v < nV; v += 3) { - fout << points[v + 0] << " " - << points[v + 1] << " " - << points[v + 2] << std::endl; - } - for (size_t f = 0; f < nT; f += 3) { - fout << "3 " << triangles[f + 0] << " " - << triangles[f + 1] << " " - << triangles[f + 2] << std::endl; - } - fout.close(); - return true; - } - else { - logger.Log("Can't open file\n"); - return false; - } + ofstream fout(fileName.c_str()); + if (fout.is_open()) + { + size_t nV = nPoints * 3; + size_t nT = nTriangles * 3; + fout << "OFF" << std::endl; + fout << nPoints << " " << nTriangles << " " << 0 << std::endl; + for (size_t v = 0; v < nV; v += 3) + { + fout << points[v + 0] << " " + << points[v + 1] << " " + << points[v + 2] << std::endl; + } + for (size_t f = 0; f < nT; f += 3) + { + fout << "3 " << triangles[f + 0] << " " + << triangles[f + 1] << " " + << triangles[f + 2] << std::endl; + } + fout.close(); + return true; + } + else + { + logger.Log("Can't open file\n"); + return false; + } } bool SaveOBJ(ofstream& fout, const double* const& points, const int* const& triangles, const unsigned int& nPoints, - const unsigned int& nTriangles, const Material& material, IVHACD::IUserLogger& logger, int convexPart, int vertexOffset) + const unsigned int& nTriangles, const Material& material, IVHACD::IUserLogger& logger, int convexPart, int vertexOffset) { - if (fout.is_open()) { - - fout.setf(std::ios::fixed, std::ios::floatfield); - fout.setf(std::ios::showpoint); - fout.precision(6); - size_t nV = nPoints * 3; - size_t nT = nTriangles * 3; + if (fout.is_open()) + { + fout.setf(std::ios::fixed, std::ios::floatfield); + fout.setf(std::ios::showpoint); + fout.precision(6); + size_t nV = nPoints * 3; + size_t nT = nTriangles * 3; fout << "o convex_" << convexPart << std::endl; - if (nV > 0) { - for (size_t v = 0; v < nV; v += 3) { - fout << "v " << points[v + 0] << " " << points[v + 1] << " " << points[v + 2] << std::endl; - } - } - if (nT > 0) { - for (size_t f = 0; f < nT; f += 3) { - fout << "f " - << triangles[f + 0]+vertexOffset << " " - << triangles[f + 1]+vertexOffset << " " - << triangles[f + 2]+vertexOffset << " " << std::endl; - } - } - return true; - } - else { - logger.Log("Can't open file\n"); - return false; - } + if (nV > 0) + { + for (size_t v = 0; v < nV; v += 3) + { + fout << "v " << points[v + 0] << " " << points[v + 1] << " " << points[v + 2] << std::endl; + } + } + if (nT > 0) + { + for (size_t f = 0; f < nT; f += 3) + { + fout << "f " + << triangles[f + 0] + vertexOffset << " " + << triangles[f + 1] + vertexOffset << " " + << triangles[f + 2] + vertexOffset << " " << std::endl; + } + } + return true; + } + else + { + logger.Log("Can't open file\n"); + return false; + } } - - bool SaveVRML2(ofstream& fout, const double* const& points, const int* const& triangles, const unsigned int& nPoints, - const unsigned int& nTriangles, const Material& material, IVHACD::IUserLogger& logger) + const unsigned int& nTriangles, const Material& material, IVHACD::IUserLogger& logger) { - if (fout.is_open()) { - fout.setf(std::ios::fixed, std::ios::floatfield); - fout.setf(std::ios::showpoint); - fout.precision(6); - size_t nV = nPoints * 3; - size_t nT = nTriangles * 3; - fout << "#VRML V2.0 utf8" << std::endl; - fout << "" << std::endl; - fout << "# Vertices: " << nPoints << std::endl; - fout << "# Triangles: " << nTriangles << std::endl; - fout << "" << std::endl; - fout << "Group {" << std::endl; - fout << " children [" << std::endl; - fout << " Shape {" << std::endl; - fout << " appearance Appearance {" << std::endl; - fout << " material Material {" << std::endl; - fout << " diffuseColor " << material.m_diffuseColor[0] << " " - << material.m_diffuseColor[1] << " " - << material.m_diffuseColor[2] << std::endl; - fout << " ambientIntensity " << material.m_ambientIntensity << std::endl; - fout << " specularColor " << material.m_specularColor[0] << " " - << material.m_specularColor[1] << " " - << material.m_specularColor[2] << std::endl; - fout << " emissiveColor " << material.m_emissiveColor[0] << " " - << material.m_emissiveColor[1] << " " - << material.m_emissiveColor[2] << std::endl; - fout << " shininess " << material.m_shininess << std::endl; - fout << " transparency " << material.m_transparency << std::endl; - fout << " }" << std::endl; - fout << " }" << std::endl; - fout << " geometry IndexedFaceSet {" << std::endl; - fout << " ccw TRUE" << std::endl; - fout << " solid TRUE" << std::endl; - fout << " convex TRUE" << std::endl; - if (nV > 0) { - fout << " coord DEF co Coordinate {" << std::endl; - fout << " point [" << std::endl; - for (size_t v = 0; v < nV; v += 3) { - fout << " " << points[v + 0] << " " - << points[v + 1] << " " - << points[v + 2] << "," << std::endl; - } - fout << " ]" << std::endl; - fout << " }" << std::endl; - } - if (nT > 0) { - fout << " coordIndex [ " << std::endl; - for (size_t f = 0; f < nT; f += 3) { - fout << " " << triangles[f + 0] << ", " - << triangles[f + 1] << ", " - << triangles[f + 2] << ", -1," << std::endl; - } - fout << " ]" << std::endl; - } - fout << " }" << std::endl; - fout << " }" << std::endl; - fout << " ]" << std::endl; - fout << "}" << std::endl; - return true; - } - else { - logger.Log("Can't open file\n"); - return false; - } + if (fout.is_open()) + { + fout.setf(std::ios::fixed, std::ios::floatfield); + fout.setf(std::ios::showpoint); + fout.precision(6); + size_t nV = nPoints * 3; + size_t nT = nTriangles * 3; + fout << "#VRML V2.0 utf8" << std::endl; + fout << "" << std::endl; + fout << "# Vertices: " << nPoints << std::endl; + fout << "# Triangles: " << nTriangles << std::endl; + fout << "" << std::endl; + fout << "Group {" << std::endl; + fout << " children [" << std::endl; + fout << " Shape {" << std::endl; + fout << " appearance Appearance {" << std::endl; + fout << " material Material {" << std::endl; + fout << " diffuseColor " << material.m_diffuseColor[0] << " " + << material.m_diffuseColor[1] << " " + << material.m_diffuseColor[2] << std::endl; + fout << " ambientIntensity " << material.m_ambientIntensity << std::endl; + fout << " specularColor " << material.m_specularColor[0] << " " + << material.m_specularColor[1] << " " + << material.m_specularColor[2] << std::endl; + fout << " emissiveColor " << material.m_emissiveColor[0] << " " + << material.m_emissiveColor[1] << " " + << material.m_emissiveColor[2] << std::endl; + fout << " shininess " << material.m_shininess << std::endl; + fout << " transparency " << material.m_transparency << std::endl; + fout << " }" << std::endl; + fout << " }" << std::endl; + fout << " geometry IndexedFaceSet {" << std::endl; + fout << " ccw TRUE" << std::endl; + fout << " solid TRUE" << std::endl; + fout << " convex TRUE" << std::endl; + if (nV > 0) + { + fout << " coord DEF co Coordinate {" << std::endl; + fout << " point [" << std::endl; + for (size_t v = 0; v < nV; v += 3) + { + fout << " " << points[v + 0] << " " + << points[v + 1] << " " + << points[v + 2] << "," << std::endl; + } + fout << " ]" << std::endl; + fout << " }" << std::endl; + } + if (nT > 0) + { + fout << " coordIndex [ " << std::endl; + for (size_t f = 0; f < nT; f += 3) + { + fout << " " << triangles[f + 0] << ", " + << triangles[f + 1] << ", " + << triangles[f + 2] << ", -1," << std::endl; + } + fout << " ]" << std::endl; + } + fout << " }" << std::endl; + fout << " }" << std::endl; + fout << " ]" << std::endl; + fout << "}" << std::endl; + return true; + } + else + { + logger.Log("Can't open file\n"); + return false; + } } diff --git a/Extras/VHACD/test/src/oclHelper.cpp b/Extras/VHACD/test/src/oclHelper.cpp index efaa9fa99..3b0dd3ae7 100644 --- a/Extras/VHACD/test/src/oclHelper.cpp +++ b/Extras/VHACD/test/src/oclHelper.cpp @@ -20,310 +20,349 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND bool OCLHelper::InitPlatform(const unsigned int platformIndex) { - cl_uint numPlatforms; - m_lastError = clGetPlatformIDs(1, NULL, &numPlatforms); - if (m_lastError != CL_SUCCESS || platformIndex >= numPlatforms) - return false; + cl_uint numPlatforms; + m_lastError = clGetPlatformIDs(1, NULL, &numPlatforms); + if (m_lastError != CL_SUCCESS || platformIndex >= numPlatforms) + return false; - cl_platform_id* platforms = new cl_platform_id[numPlatforms]; - m_lastError = clGetPlatformIDs(numPlatforms, platforms, NULL); - if (m_lastError != CL_SUCCESS) { - delete[] platforms; - return false; - } + cl_platform_id* platforms = new cl_platform_id[numPlatforms]; + m_lastError = clGetPlatformIDs(numPlatforms, platforms, NULL); + if (m_lastError != CL_SUCCESS) + { + delete[] platforms; + return false; + } - m_platform = platforms[platformIndex]; - delete[] platforms; - return true; + m_platform = platforms[platformIndex]; + delete[] platforms; + return true; } bool OCLHelper::GetPlatformsInfo(std::vector& info, const std::string& indentation) { - const char* platformInfoParameters[] = { "CL_PLATFORM_NAME", - "CL_PLATFORM_VENDOR", - "CL_PLATFORM_VERSION", - "CL_PLATFORM_PROFILE", - "CL_PLATFORM_EXTENSIONS" }; + const char* platformInfoParameters[] = {"CL_PLATFORM_NAME", + "CL_PLATFORM_VENDOR", + "CL_PLATFORM_VERSION", + "CL_PLATFORM_PROFILE", + "CL_PLATFORM_EXTENSIONS"}; - cl_uint numPlatforms; - m_lastError = clGetPlatformIDs(1, NULL, &numPlatforms); - if (m_lastError != CL_SUCCESS) - return false; + cl_uint numPlatforms; + m_lastError = clGetPlatformIDs(1, NULL, &numPlatforms); + if (m_lastError != CL_SUCCESS) + return false; - cl_platform_id* platforms = new cl_platform_id[numPlatforms]; - m_lastError = clGetPlatformIDs(numPlatforms, platforms, NULL); - if (m_lastError != CL_SUCCESS) { - delete[] platforms; - return false; - } + cl_platform_id* platforms = new cl_platform_id[numPlatforms]; + m_lastError = clGetPlatformIDs(numPlatforms, platforms, NULL); + if (m_lastError != CL_SUCCESS) + { + delete[] platforms; + return false; + } - size_t bufferSize = 4096; - char* buffer = new char[bufferSize]; - size_t size; - info.resize(numPlatforms); - for (cl_uint i = 0; i < numPlatforms; ++i) { - for (int j = CL_PLATFORM_PROFILE; j <= CL_PLATFORM_EXTENSIONS; ++j) { - info[i] += indentation + platformInfoParameters[j - CL_PLATFORM_PROFILE] + std::string(": "); - m_lastError = clGetPlatformInfo(platforms[i], j, 0, NULL, &size); - if (m_lastError != CL_SUCCESS) { - delete[] buffer; - delete[] platforms; - return false; - } - if (bufferSize < size) { - delete[] buffer; - bufferSize = size; - buffer = new char[bufferSize]; - } - m_lastError = clGetPlatformInfo(platforms[i], j, size, buffer, NULL); - if (m_lastError != CL_SUCCESS) { - delete[] buffer; - delete[] platforms; - return false; - } - info[i] += buffer + std::string("\n"); - } - } - delete[] platforms; - delete[] buffer; - return true; + size_t bufferSize = 4096; + char* buffer = new char[bufferSize]; + size_t size; + info.resize(numPlatforms); + for (cl_uint i = 0; i < numPlatforms; ++i) + { + for (int j = CL_PLATFORM_PROFILE; j <= CL_PLATFORM_EXTENSIONS; ++j) + { + info[i] += indentation + platformInfoParameters[j - CL_PLATFORM_PROFILE] + std::string(": "); + m_lastError = clGetPlatformInfo(platforms[i], j, 0, NULL, &size); + if (m_lastError != CL_SUCCESS) + { + delete[] buffer; + delete[] platforms; + return false; + } + if (bufferSize < size) + { + delete[] buffer; + bufferSize = size; + buffer = new char[bufferSize]; + } + m_lastError = clGetPlatformInfo(platforms[i], j, size, buffer, NULL); + if (m_lastError != CL_SUCCESS) + { + delete[] buffer; + delete[] platforms; + return false; + } + info[i] += buffer + std::string("\n"); + } + } + delete[] platforms; + delete[] buffer; + return true; } bool OCLHelper::InitDevice(const unsigned int deviceIndex) { - cl_uint numDevices; - m_lastError = clGetDeviceIDs(m_platform, CL_DEVICE_TYPE_ALL, 0, NULL, &numDevices); - if (m_lastError != CL_SUCCESS || deviceIndex >= numDevices) - return false; + cl_uint numDevices; + m_lastError = clGetDeviceIDs(m_platform, CL_DEVICE_TYPE_ALL, 0, NULL, &numDevices); + if (m_lastError != CL_SUCCESS || deviceIndex >= numDevices) + return false; - cl_device_id* devices = new cl_device_id[numDevices]; - m_lastError = clGetDeviceIDs(m_platform, CL_DEVICE_TYPE_ALL, numDevices, devices, NULL); - if (m_lastError != CL_SUCCESS) { - delete[] devices; - return false; - } - m_device = devices[deviceIndex]; - delete[] devices; - return true; + cl_device_id* devices = new cl_device_id[numDevices]; + m_lastError = clGetDeviceIDs(m_platform, CL_DEVICE_TYPE_ALL, numDevices, devices, NULL); + if (m_lastError != CL_SUCCESS) + { + delete[] devices; + return false; + } + m_device = devices[deviceIndex]; + delete[] devices; + return true; } bool OCLHelper::GetDevicesInfo(std::vector& info, const std::string& indentation) { - enum { - DATA_TYPE_CL_UINT, - DATA_TYPE_CL_BOOL, - DATA_TYPE_STRING, - DATA_TYPE_CL_ULONG, - DATA_TYPE_CL_DEVICE_FP_CONFIG, - DATA_TYPE_CL_DEVICE_EXEC_CAPABILITIES, - DATA_TYPE_CL_DEVICE_MEM_CACHE_TYPE, - DATA_TYPE_CL_DEVICE_MEM_LOCAL_TYPE, - DATA_TYPE_CL_DEVICE_CMD_QUEUE_PROP, - DATA_TYPE_CL_DEVICE_TYPE, - DATA_TYPE_SIZE_T, - DATA_TYPE_SIZE_T_3, - }; - typedef struct - { - cl_device_info id; - const char* name; - int type; - } DeviceInfoParam; - const int numDeviceInfoParameters = 49; - const DeviceInfoParam deviceInfoParameters[numDeviceInfoParameters] = { - { CL_DEVICE_NAME, "CL_DEVICE_NAME", DATA_TYPE_STRING }, - { CL_DEVICE_PROFILE, "CL_DEVICE_PROFILE", DATA_TYPE_STRING }, - { CL_DEVICE_VENDOR, "CL_DEVICE_VENDOR", DATA_TYPE_STRING }, - { CL_DEVICE_VERSION, "CL_DEVICE_VERSION", DATA_TYPE_STRING }, - { CL_DRIVER_VERSION, "CL_DRIVER_VERSION", DATA_TYPE_STRING }, - { CL_DEVICE_EXTENSIONS, "CL_DEVICE_EXTENSIONS", DATA_TYPE_STRING }, - { CL_DEVICE_VERSION, "CL_DEVICE_VERSION", DATA_TYPE_STRING }, - { CL_DEVICE_ADDRESS_BITS, "CL_DEVICE_ADDRESS_BITS", DATA_TYPE_CL_UINT }, - { CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, "CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE", DATA_TYPE_CL_UINT }, - { CL_DEVICE_MAX_CLOCK_FREQUENCY, "CL_DEVICE_MAX_CLOCK_FREQUENCY", DATA_TYPE_CL_UINT }, - { CL_DEVICE_MAX_COMPUTE_UNITS, "CL_DEVICE_MAX_COMPUTE_UNITS", DATA_TYPE_CL_UINT }, - { CL_DEVICE_MAX_CONSTANT_ARGS, "CL_DEVICE_MAX_CONSTANT_ARGS", DATA_TYPE_CL_UINT }, - { CL_DEVICE_MAX_READ_IMAGE_ARGS, "CL_DEVICE_MAX_READ_IMAGE_ARGS", DATA_TYPE_CL_UINT }, - { CL_DEVICE_MAX_SAMPLERS, "CL_DEVICE_MAX_SAMPLERS", DATA_TYPE_CL_UINT }, - { CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, "CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS", DATA_TYPE_CL_UINT }, - { CL_DEVICE_MAX_WRITE_IMAGE_ARGS, "CL_DEVICE_MAX_WRITE_IMAGE_ARGS", DATA_TYPE_CL_UINT }, - { CL_DEVICE_MEM_BASE_ADDR_ALIGN, "CL_DEVICE_MEM_BASE_ADDR_ALIGN", DATA_TYPE_CL_UINT }, - { CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, "CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE", DATA_TYPE_CL_UINT }, - { CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, "CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR", DATA_TYPE_CL_UINT }, - { CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, "CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT", DATA_TYPE_CL_UINT }, - { CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, "CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT", DATA_TYPE_CL_UINT }, - { CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, "CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG", DATA_TYPE_CL_UINT }, - { CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, "CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT", DATA_TYPE_CL_UINT }, - { CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, "CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE", DATA_TYPE_CL_UINT }, - { CL_DEVICE_VENDOR_ID, "CL_DEVICE_VENDOR_ID", DATA_TYPE_CL_UINT }, - { CL_DEVICE_AVAILABLE, "CL_DEVICE_AVAILABLE", DATA_TYPE_CL_BOOL }, - { CL_DEVICE_COMPILER_AVAILABLE, "CL_DEVICE_COMPILER_AVAILABLE", DATA_TYPE_CL_BOOL }, - { CL_DEVICE_ENDIAN_LITTLE, "CL_DEVICE_ENDIAN_LITTLE", DATA_TYPE_CL_BOOL }, - { CL_DEVICE_ERROR_CORRECTION_SUPPORT, "CL_DEVICE_ERROR_CORRECTION_SUPPORT", DATA_TYPE_CL_BOOL }, - { CL_DEVICE_IMAGE_SUPPORT, "CL_DEVICE_IMAGE_SUPPORT", DATA_TYPE_CL_BOOL }, - { CL_DEVICE_EXECUTION_CAPABILITIES, "CL_DEVICE_EXECUTION_CAPABILITIES", DATA_TYPE_CL_DEVICE_EXEC_CAPABILITIES }, - { CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, "CL_DEVICE_GLOBAL_MEM_CACHE_SIZE", DATA_TYPE_CL_ULONG }, - { CL_DEVICE_GLOBAL_MEM_SIZE, "CL_DEVICE_GLOBAL_MEM_SIZE", DATA_TYPE_CL_ULONG }, - { CL_DEVICE_LOCAL_MEM_SIZE, "CL_DEVICE_LOCAL_MEM_SIZE", DATA_TYPE_CL_ULONG }, - { CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, "CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE", DATA_TYPE_CL_ULONG }, - { CL_DEVICE_MAX_MEM_ALLOC_SIZE, "CL_DEVICE_MAX_MEM_ALLOC_SIZE", DATA_TYPE_CL_ULONG }, - { CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, "CL_DEVICE_GLOBAL_MEM_CACHE_TYPE", DATA_TYPE_CL_DEVICE_MEM_CACHE_TYPE }, - { CL_DEVICE_IMAGE2D_MAX_HEIGHT, "CL_DEVICE_IMAGE2D_MAX_HEIGHT", DATA_TYPE_SIZE_T }, - { CL_DEVICE_IMAGE2D_MAX_WIDTH, "CL_DEVICE_IMAGE2D_MAX_WIDTH", DATA_TYPE_SIZE_T }, - { CL_DEVICE_IMAGE3D_MAX_DEPTH, "CL_DEVICE_IMAGE3D_MAX_DEPTH", DATA_TYPE_SIZE_T }, - { CL_DEVICE_IMAGE3D_MAX_HEIGHT, "CL_DEVICE_IMAGE3D_MAX_HEIGHT", DATA_TYPE_SIZE_T }, - { CL_DEVICE_IMAGE3D_MAX_WIDTH, "CL_DEVICE_IMAGE3D_MAX_WIDTH", DATA_TYPE_SIZE_T }, - { CL_DEVICE_MAX_PARAMETER_SIZE, "CL_DEVICE_MAX_PARAMETER_SIZE", DATA_TYPE_SIZE_T }, - { CL_DEVICE_MAX_WORK_GROUP_SIZE, "CL_DEVICE_MAX_WORK_GROUP_SIZE", DATA_TYPE_SIZE_T }, - { CL_DEVICE_PROFILING_TIMER_RESOLUTION, "CL_DEVICE_PROFILING_TIMER_RESOLUTION", DATA_TYPE_SIZE_T }, - { CL_DEVICE_QUEUE_PROPERTIES, "CL_DEVICE_QUEUE_PROPERTIES", DATA_TYPE_CL_DEVICE_CMD_QUEUE_PROP }, - { CL_DEVICE_TYPE, "CL_DEVICE_TYPE", DATA_TYPE_CL_DEVICE_TYPE }, - { CL_DEVICE_LOCAL_MEM_TYPE, "CL_DEVICE_LOCAL_MEM_TYPE", DATA_TYPE_CL_DEVICE_MEM_LOCAL_TYPE }, - { CL_DEVICE_MAX_WORK_ITEM_SIZES, "CL_DEVICE_MAX_WORK_ITEM_SIZES", DATA_TYPE_SIZE_T_3 } - // { CL_DEVICE_DOUBLE_FP_CONFIG, "CL_DEVICE_DOUBLE_FP_CONFIG", DATA_TYPE_CL_DEVICE_FP_CONFIG }, - // - }; - cl_uint numDevices; - m_lastError = clGetDeviceIDs(m_platform, CL_DEVICE_TYPE_ALL, 0, NULL, &numDevices); - if (m_lastError != CL_SUCCESS) - return false; + enum + { + DATA_TYPE_CL_UINT, + DATA_TYPE_CL_BOOL, + DATA_TYPE_STRING, + DATA_TYPE_CL_ULONG, + DATA_TYPE_CL_DEVICE_FP_CONFIG, + DATA_TYPE_CL_DEVICE_EXEC_CAPABILITIES, + DATA_TYPE_CL_DEVICE_MEM_CACHE_TYPE, + DATA_TYPE_CL_DEVICE_MEM_LOCAL_TYPE, + DATA_TYPE_CL_DEVICE_CMD_QUEUE_PROP, + DATA_TYPE_CL_DEVICE_TYPE, + DATA_TYPE_SIZE_T, + DATA_TYPE_SIZE_T_3, + }; + typedef struct + { + cl_device_info id; + const char* name; + int type; + } DeviceInfoParam; + const int numDeviceInfoParameters = 49; + const DeviceInfoParam deviceInfoParameters[numDeviceInfoParameters] = { + {CL_DEVICE_NAME, "CL_DEVICE_NAME", DATA_TYPE_STRING}, + {CL_DEVICE_PROFILE, "CL_DEVICE_PROFILE", DATA_TYPE_STRING}, + {CL_DEVICE_VENDOR, "CL_DEVICE_VENDOR", DATA_TYPE_STRING}, + {CL_DEVICE_VERSION, "CL_DEVICE_VERSION", DATA_TYPE_STRING}, + {CL_DRIVER_VERSION, "CL_DRIVER_VERSION", DATA_TYPE_STRING}, + {CL_DEVICE_EXTENSIONS, "CL_DEVICE_EXTENSIONS", DATA_TYPE_STRING}, + {CL_DEVICE_VERSION, "CL_DEVICE_VERSION", DATA_TYPE_STRING}, + {CL_DEVICE_ADDRESS_BITS, "CL_DEVICE_ADDRESS_BITS", DATA_TYPE_CL_UINT}, + {CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, "CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE", DATA_TYPE_CL_UINT}, + {CL_DEVICE_MAX_CLOCK_FREQUENCY, "CL_DEVICE_MAX_CLOCK_FREQUENCY", DATA_TYPE_CL_UINT}, + {CL_DEVICE_MAX_COMPUTE_UNITS, "CL_DEVICE_MAX_COMPUTE_UNITS", DATA_TYPE_CL_UINT}, + {CL_DEVICE_MAX_CONSTANT_ARGS, "CL_DEVICE_MAX_CONSTANT_ARGS", DATA_TYPE_CL_UINT}, + {CL_DEVICE_MAX_READ_IMAGE_ARGS, "CL_DEVICE_MAX_READ_IMAGE_ARGS", DATA_TYPE_CL_UINT}, + {CL_DEVICE_MAX_SAMPLERS, "CL_DEVICE_MAX_SAMPLERS", DATA_TYPE_CL_UINT}, + {CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, "CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS", DATA_TYPE_CL_UINT}, + {CL_DEVICE_MAX_WRITE_IMAGE_ARGS, "CL_DEVICE_MAX_WRITE_IMAGE_ARGS", DATA_TYPE_CL_UINT}, + {CL_DEVICE_MEM_BASE_ADDR_ALIGN, "CL_DEVICE_MEM_BASE_ADDR_ALIGN", DATA_TYPE_CL_UINT}, + {CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE, "CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE", DATA_TYPE_CL_UINT}, + {CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR, "CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR", DATA_TYPE_CL_UINT}, + {CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT, "CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT", DATA_TYPE_CL_UINT}, + {CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT, "CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT", DATA_TYPE_CL_UINT}, + {CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG, "CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG", DATA_TYPE_CL_UINT}, + {CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT, "CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT", DATA_TYPE_CL_UINT}, + {CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, "CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE", DATA_TYPE_CL_UINT}, + {CL_DEVICE_VENDOR_ID, "CL_DEVICE_VENDOR_ID", DATA_TYPE_CL_UINT}, + {CL_DEVICE_AVAILABLE, "CL_DEVICE_AVAILABLE", DATA_TYPE_CL_BOOL}, + {CL_DEVICE_COMPILER_AVAILABLE, "CL_DEVICE_COMPILER_AVAILABLE", DATA_TYPE_CL_BOOL}, + {CL_DEVICE_ENDIAN_LITTLE, "CL_DEVICE_ENDIAN_LITTLE", DATA_TYPE_CL_BOOL}, + {CL_DEVICE_ERROR_CORRECTION_SUPPORT, "CL_DEVICE_ERROR_CORRECTION_SUPPORT", DATA_TYPE_CL_BOOL}, + {CL_DEVICE_IMAGE_SUPPORT, "CL_DEVICE_IMAGE_SUPPORT", DATA_TYPE_CL_BOOL}, + {CL_DEVICE_EXECUTION_CAPABILITIES, "CL_DEVICE_EXECUTION_CAPABILITIES", DATA_TYPE_CL_DEVICE_EXEC_CAPABILITIES}, + {CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, "CL_DEVICE_GLOBAL_MEM_CACHE_SIZE", DATA_TYPE_CL_ULONG}, + {CL_DEVICE_GLOBAL_MEM_SIZE, "CL_DEVICE_GLOBAL_MEM_SIZE", DATA_TYPE_CL_ULONG}, + {CL_DEVICE_LOCAL_MEM_SIZE, "CL_DEVICE_LOCAL_MEM_SIZE", DATA_TYPE_CL_ULONG}, + {CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE, "CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE", DATA_TYPE_CL_ULONG}, + {CL_DEVICE_MAX_MEM_ALLOC_SIZE, "CL_DEVICE_MAX_MEM_ALLOC_SIZE", DATA_TYPE_CL_ULONG}, + {CL_DEVICE_GLOBAL_MEM_CACHE_TYPE, "CL_DEVICE_GLOBAL_MEM_CACHE_TYPE", DATA_TYPE_CL_DEVICE_MEM_CACHE_TYPE}, + {CL_DEVICE_IMAGE2D_MAX_HEIGHT, "CL_DEVICE_IMAGE2D_MAX_HEIGHT", DATA_TYPE_SIZE_T}, + {CL_DEVICE_IMAGE2D_MAX_WIDTH, "CL_DEVICE_IMAGE2D_MAX_WIDTH", DATA_TYPE_SIZE_T}, + {CL_DEVICE_IMAGE3D_MAX_DEPTH, "CL_DEVICE_IMAGE3D_MAX_DEPTH", DATA_TYPE_SIZE_T}, + {CL_DEVICE_IMAGE3D_MAX_HEIGHT, "CL_DEVICE_IMAGE3D_MAX_HEIGHT", DATA_TYPE_SIZE_T}, + {CL_DEVICE_IMAGE3D_MAX_WIDTH, "CL_DEVICE_IMAGE3D_MAX_WIDTH", DATA_TYPE_SIZE_T}, + {CL_DEVICE_MAX_PARAMETER_SIZE, "CL_DEVICE_MAX_PARAMETER_SIZE", DATA_TYPE_SIZE_T}, + {CL_DEVICE_MAX_WORK_GROUP_SIZE, "CL_DEVICE_MAX_WORK_GROUP_SIZE", DATA_TYPE_SIZE_T}, + {CL_DEVICE_PROFILING_TIMER_RESOLUTION, "CL_DEVICE_PROFILING_TIMER_RESOLUTION", DATA_TYPE_SIZE_T}, + {CL_DEVICE_QUEUE_PROPERTIES, "CL_DEVICE_QUEUE_PROPERTIES", DATA_TYPE_CL_DEVICE_CMD_QUEUE_PROP}, + {CL_DEVICE_TYPE, "CL_DEVICE_TYPE", DATA_TYPE_CL_DEVICE_TYPE}, + {CL_DEVICE_LOCAL_MEM_TYPE, "CL_DEVICE_LOCAL_MEM_TYPE", DATA_TYPE_CL_DEVICE_MEM_LOCAL_TYPE}, + {CL_DEVICE_MAX_WORK_ITEM_SIZES, "CL_DEVICE_MAX_WORK_ITEM_SIZES", DATA_TYPE_SIZE_T_3} + // { CL_DEVICE_DOUBLE_FP_CONFIG, "CL_DEVICE_DOUBLE_FP_CONFIG", DATA_TYPE_CL_DEVICE_FP_CONFIG }, + // + }; + cl_uint numDevices; + m_lastError = clGetDeviceIDs(m_platform, CL_DEVICE_TYPE_ALL, 0, NULL, &numDevices); + if (m_lastError != CL_SUCCESS) + return false; - cl_device_id* devices = new cl_device_id[numDevices]; - m_lastError = clGetDeviceIDs(m_platform, CL_DEVICE_TYPE_ALL, numDevices, devices, NULL); - if (m_lastError != CL_SUCCESS) { - delete[] devices; - return false; - } - size_t bufferSize = 4096; - char* buffer = new char[bufferSize]; - size_t size; - info.resize(numDevices); + cl_device_id* devices = new cl_device_id[numDevices]; + m_lastError = clGetDeviceIDs(m_platform, CL_DEVICE_TYPE_ALL, numDevices, devices, NULL); + if (m_lastError != CL_SUCCESS) + { + delete[] devices; + return false; + } + size_t bufferSize = 4096; + char* buffer = new char[bufferSize]; + size_t size; + info.resize(numDevices); - for (cl_uint i = 0; i < numDevices; ++i) { - for (int j = 0; j < numDeviceInfoParameters; ++j) { - const DeviceInfoParam& infoParam = deviceInfoParameters[j]; - info[i] += indentation + infoParam.name + std::string(": "); + for (cl_uint i = 0; i < numDevices; ++i) + { + for (int j = 0; j < numDeviceInfoParameters; ++j) + { + const DeviceInfoParam& infoParam = deviceInfoParameters[j]; + info[i] += indentation + infoParam.name + std::string(": "); - if (infoParam.type == DATA_TYPE_STRING) { - m_lastError = clGetDeviceInfo(devices[i], infoParam.id, 0, NULL, &size); - if (m_lastError == CL_SUCCESS) { - if (bufferSize < size) { - delete[] buffer; - bufferSize = size; - buffer = new char[bufferSize]; - } - m_lastError = clGetDeviceInfo(devices[i], infoParam.id, size, buffer, NULL); - if (m_lastError != CL_SUCCESS) { - delete[] devices; - delete[] buffer; - return false; - } - info[i] += buffer + std::string("\n"); - } - } - else if (infoParam.type == DATA_TYPE_CL_UINT) { - cl_uint value; - m_lastError = clGetDeviceInfo(devices[i], infoParam.id, sizeof(cl_uint), &value, &size); - if (m_lastError == CL_SUCCESS) { - std::ostringstream svalue; - svalue << value; - info[i] += svalue.str() + "\n"; - } - } - else if (infoParam.type == DATA_TYPE_CL_BOOL) { - cl_bool value; - m_lastError = clGetDeviceInfo(devices[i], infoParam.id, sizeof(cl_bool), &value, &size); - if (m_lastError == CL_SUCCESS) { - std::ostringstream svalue; - svalue << value; - info[i] += svalue.str() + "\n"; - } - } - else if (infoParam.type == DATA_TYPE_CL_ULONG) { - cl_ulong value; - m_lastError = clGetDeviceInfo(devices[i], infoParam.id, sizeof(cl_ulong), &value, &size); - if (m_lastError == CL_SUCCESS) { - std::ostringstream svalue; - svalue << value; - info[i] += svalue.str() + "\n"; - } - } - else if (infoParam.type == DATA_TYPE_CL_DEVICE_FP_CONFIG) { - cl_device_fp_config value; - m_lastError = clGetDeviceInfo(devices[i], infoParam.id, sizeof(cl_device_fp_config), &value, &size); - if (m_lastError == CL_SUCCESS) { - std::ostringstream svalue; - svalue << value; - info[i] += svalue.str() + "\n"; - } - } - else if (infoParam.type == DATA_TYPE_CL_DEVICE_EXEC_CAPABILITIES) { - cl_device_exec_capabilities value; - m_lastError = clGetDeviceInfo(devices[i], infoParam.id, sizeof(cl_device_exec_capabilities), &value, &size); - if (m_lastError == CL_SUCCESS) { - std::ostringstream svalue; - svalue << value; - info[i] += svalue.str() + "\n"; - } - } - else if (infoParam.type == DATA_TYPE_CL_DEVICE_MEM_CACHE_TYPE) { - cl_device_mem_cache_type value; - m_lastError = clGetDeviceInfo(devices[i], infoParam.id, sizeof(cl_device_mem_cache_type), &value, &size); - if (m_lastError == CL_SUCCESS) { - std::ostringstream svalue; - svalue << value; - info[i] += svalue.str() + "\n"; - } - } - else if (infoParam.type == DATA_TYPE_CL_DEVICE_MEM_LOCAL_TYPE) { - cl_device_local_mem_type value; - m_lastError = clGetDeviceInfo(devices[i], infoParam.id, sizeof(cl_device_local_mem_type), &value, &size); - if (m_lastError == CL_SUCCESS) { - std::ostringstream svalue; - svalue << value; - info[i] += svalue.str() + "\n"; - } - } - else if (infoParam.type == DATA_TYPE_CL_DEVICE_CMD_QUEUE_PROP) { - cl_command_queue_properties value; - m_lastError = clGetDeviceInfo(devices[i], infoParam.id, sizeof(cl_command_queue_properties), &value, &size); - if (m_lastError == CL_SUCCESS) { - std::ostringstream svalue; - svalue << value; - info[i] += svalue.str() + "\n"; - } - } - else if (infoParam.type == DATA_TYPE_CL_DEVICE_TYPE) { - cl_device_type value; - m_lastError = clGetDeviceInfo(devices[i], infoParam.id, sizeof(cl_device_type), &value, &size); - if (m_lastError == CL_SUCCESS) { - std::ostringstream svalue; - svalue << value; - info[i] += svalue.str() + "\n"; - } - } - else if (infoParam.type == DATA_TYPE_SIZE_T) { - size_t value; - m_lastError = clGetDeviceInfo(devices[i], infoParam.id, sizeof(size_t), &value, &size); - if (m_lastError == CL_SUCCESS) { - std::ostringstream svalue; - svalue << value; - info[i] += svalue.str() + "\n"; - } - } - else if (infoParam.type == DATA_TYPE_SIZE_T_3) { - size_t value[3]; - m_lastError = clGetDeviceInfo(devices[i], infoParam.id, 3 * sizeof(size_t), &value, &size); - if (m_lastError == CL_SUCCESS) { - std::ostringstream svalue; - svalue << "(" << value[0] << ", " << value[1] << ", " << value[2] << ")"; - info[i] += svalue.str() + "\n"; - } - } - else { - assert(0); - } - } - } - delete[] devices; - delete[] buffer; - return true; + if (infoParam.type == DATA_TYPE_STRING) + { + m_lastError = clGetDeviceInfo(devices[i], infoParam.id, 0, NULL, &size); + if (m_lastError == CL_SUCCESS) + { + if (bufferSize < size) + { + delete[] buffer; + bufferSize = size; + buffer = new char[bufferSize]; + } + m_lastError = clGetDeviceInfo(devices[i], infoParam.id, size, buffer, NULL); + if (m_lastError != CL_SUCCESS) + { + delete[] devices; + delete[] buffer; + return false; + } + info[i] += buffer + std::string("\n"); + } + } + else if (infoParam.type == DATA_TYPE_CL_UINT) + { + cl_uint value; + m_lastError = clGetDeviceInfo(devices[i], infoParam.id, sizeof(cl_uint), &value, &size); + if (m_lastError == CL_SUCCESS) + { + std::ostringstream svalue; + svalue << value; + info[i] += svalue.str() + "\n"; + } + } + else if (infoParam.type == DATA_TYPE_CL_BOOL) + { + cl_bool value; + m_lastError = clGetDeviceInfo(devices[i], infoParam.id, sizeof(cl_bool), &value, &size); + if (m_lastError == CL_SUCCESS) + { + std::ostringstream svalue; + svalue << value; + info[i] += svalue.str() + "\n"; + } + } + else if (infoParam.type == DATA_TYPE_CL_ULONG) + { + cl_ulong value; + m_lastError = clGetDeviceInfo(devices[i], infoParam.id, sizeof(cl_ulong), &value, &size); + if (m_lastError == CL_SUCCESS) + { + std::ostringstream svalue; + svalue << value; + info[i] += svalue.str() + "\n"; + } + } + else if (infoParam.type == DATA_TYPE_CL_DEVICE_FP_CONFIG) + { + cl_device_fp_config value; + m_lastError = clGetDeviceInfo(devices[i], infoParam.id, sizeof(cl_device_fp_config), &value, &size); + if (m_lastError == CL_SUCCESS) + { + std::ostringstream svalue; + svalue << value; + info[i] += svalue.str() + "\n"; + } + } + else if (infoParam.type == DATA_TYPE_CL_DEVICE_EXEC_CAPABILITIES) + { + cl_device_exec_capabilities value; + m_lastError = clGetDeviceInfo(devices[i], infoParam.id, sizeof(cl_device_exec_capabilities), &value, &size); + if (m_lastError == CL_SUCCESS) + { + std::ostringstream svalue; + svalue << value; + info[i] += svalue.str() + "\n"; + } + } + else if (infoParam.type == DATA_TYPE_CL_DEVICE_MEM_CACHE_TYPE) + { + cl_device_mem_cache_type value; + m_lastError = clGetDeviceInfo(devices[i], infoParam.id, sizeof(cl_device_mem_cache_type), &value, &size); + if (m_lastError == CL_SUCCESS) + { + std::ostringstream svalue; + svalue << value; + info[i] += svalue.str() + "\n"; + } + } + else if (infoParam.type == DATA_TYPE_CL_DEVICE_MEM_LOCAL_TYPE) + { + cl_device_local_mem_type value; + m_lastError = clGetDeviceInfo(devices[i], infoParam.id, sizeof(cl_device_local_mem_type), &value, &size); + if (m_lastError == CL_SUCCESS) + { + std::ostringstream svalue; + svalue << value; + info[i] += svalue.str() + "\n"; + } + } + else if (infoParam.type == DATA_TYPE_CL_DEVICE_CMD_QUEUE_PROP) + { + cl_command_queue_properties value; + m_lastError = clGetDeviceInfo(devices[i], infoParam.id, sizeof(cl_command_queue_properties), &value, &size); + if (m_lastError == CL_SUCCESS) + { + std::ostringstream svalue; + svalue << value; + info[i] += svalue.str() + "\n"; + } + } + else if (infoParam.type == DATA_TYPE_CL_DEVICE_TYPE) + { + cl_device_type value; + m_lastError = clGetDeviceInfo(devices[i], infoParam.id, sizeof(cl_device_type), &value, &size); + if (m_lastError == CL_SUCCESS) + { + std::ostringstream svalue; + svalue << value; + info[i] += svalue.str() + "\n"; + } + } + else if (infoParam.type == DATA_TYPE_SIZE_T) + { + size_t value; + m_lastError = clGetDeviceInfo(devices[i], infoParam.id, sizeof(size_t), &value, &size); + if (m_lastError == CL_SUCCESS) + { + std::ostringstream svalue; + svalue << value; + info[i] += svalue.str() + "\n"; + } + } + else if (infoParam.type == DATA_TYPE_SIZE_T_3) + { + size_t value[3]; + m_lastError = clGetDeviceInfo(devices[i], infoParam.id, 3 * sizeof(size_t), &value, &size); + if (m_lastError == CL_SUCCESS) + { + std::ostringstream svalue; + svalue << "(" << value[0] << ", " << value[1] << ", " << value[2] << ")"; + info[i] += svalue.str() + "\n"; + } + } + else + { + assert(0); + } + } + } + delete[] devices; + delete[] buffer; + return true; } -#endif // OPENCL_FOUND +#endif // OPENCL_FOUND diff --git a/Extras/obj2sdf/obj2sdf.cpp b/Extras/obj2sdf/obj2sdf.cpp index 6bd3cf948..240f065a8 100644 --- a/Extras/obj2sdf/obj2sdf.cpp +++ b/Extras/obj2sdf/obj2sdf.cpp @@ -7,8 +7,8 @@ #include #include #include -#define ASSERT_EQ(a,b) assert((a)==(b)); -#include"Wavefront/tiny_obj_loader.h" +#define ASSERT_EQ(a, b) assert((a) == (b)); +#include "Wavefront/tiny_obj_loader.h" #include #include "Bullet3Common/b3FileUtils.h" #include "../Utils/b3ResourcePath.h" @@ -20,10 +20,10 @@ struct ShapeContainer std::string m_matName; std::string m_shapeName; tinyobj::material_t material; - std::vector positions; - std::vector normals; - std::vector texcoords; - std::vector indices; + std::vector positions; + std::vector normals; + std::vector texcoords; + std::vector indices; b3AlignedObjectArray m_shapeIndices; }; @@ -32,17 +32,17 @@ b3HashMap gMaterialNames; #define MAX_PATH_LEN 1024 -std::string StripExtension( const std::string & sPath ) +std::string StripExtension(const std::string& sPath) { - for( std::string::const_reverse_iterator i = sPath.rbegin(); i != sPath.rend(); i++ ) + for (std::string::const_reverse_iterator i = sPath.rbegin(); i != sPath.rend(); i++) { - if( *i == '.' ) + if (*i == '.') { - return std::string( sPath.begin(), i.base() - 1 ); + return std::string(sPath.begin(), i.base() - 1); } // if we find a slash there is no extension - if( *i == '\\' || *i == '/' ) + if (*i == '\\' || *i == '/') break; } @@ -52,11 +52,10 @@ std::string StripExtension( const std::string & sPath ) int main(int argc, char* argv[]) { - - b3CommandLineArgs args(argc,argv); + b3CommandLineArgs args(argc, argv); char* fileName; - args.GetCmdLineArgument("fileName",fileName); - if (fileName==0) + args.GetCmdLineArgument("fileName", fileName); + if (fileName == 0) { printf("required --fileName=\"name\""); exit(0); @@ -64,27 +63,27 @@ int main(int argc, char* argv[]) std::string matLibName = StripExtension(fileName); printf("fileName = %s\n", fileName); - if (fileName==0) + if (fileName == 0) { printf("Please use --fileName=\"pathToObj\"."); exit(0); } bool mergeMaterials = args.CheckCmdLineFlag("mergeMaterials"); - + char fileNameWithPath[MAX_PATH_LEN]; - bool fileFound = (b3ResourcePath::findResourcePath(fileName,fileNameWithPath,MAX_PATH_LEN))>0; + bool fileFound = (b3ResourcePath::findResourcePath(fileName, fileNameWithPath, MAX_PATH_LEN)) > 0; char materialPrefixPath[MAX_PATH_LEN]; - b3FileUtils::extractPath(fileNameWithPath,materialPrefixPath,MAX_PATH_LEN); + b3FileUtils::extractPath(fileNameWithPath, materialPrefixPath, MAX_PATH_LEN); std::vector shapes; std::string err = tinyobj::LoadObj(shapes, fileNameWithPath, materialPrefixPath); - + char sdfFileName[MAX_PATH_LEN]; - sprintf(sdfFileName,"%s%s.sdf",materialPrefixPath,"newsdf"); - FILE* sdfFile = fopen(sdfFileName,"w"); - if (sdfFile==0) + sprintf(sdfFileName, "%s%s.sdf", materialPrefixPath, "newsdf"); + FILE* sdfFile = fopen(sdfFileName, "w"); + if (sdfFile == 0) { - printf("Fatal error: cannot create sdf file %s\n",sdfFileName); + printf("Fatal error: cannot create sdf file %s\n", sdfFileName); exit(0); } @@ -94,7 +93,7 @@ int main(int argc, char* argv[]) { tinyobj::shape_t& shape = shapes[s]; tinyobj::material_t mat = shape.material; - + b3HashString key = mat.name.length() ? mat.name.c_str() : ""; if (!gMaterialNames.find(key)) { @@ -109,10 +108,10 @@ int main(int argc, char* argv[]) if (shapeC) { shapeC->m_shapeIndices.push_back(s); - - int curPositions = shapeC->positions.size()/3; - int curNormals = shapeC->normals.size()/3; - int curTexcoords = shapeC->texcoords.size()/2; + + int curPositions = shapeC->positions.size() / 3; + int curNormals = shapeC->normals.size() / 3; + int curTexcoords = shapeC->texcoords.size() / 2; int faceCount = shape.mesh.indices.size(); int vertexCount = shape.mesh.positions.size(); @@ -139,26 +138,25 @@ int main(int argc, char* argv[]) } shapeC->indices.push_back(shape.mesh.indices[face] + curPositions); - shapeC->indices.push_back(shape.mesh.indices[face+1] + curPositions); + shapeC->indices.push_back(shape.mesh.indices[face + 1] + curPositions); shapeC->indices.push_back(shape.mesh.indices[face + 2] + curPositions); } } } - + printf("unique materials=%d\n", gMaterialNames.size()); - if (mergeMaterials) { - for (int m = 0; m < gMaterialNames.size();m++) + for (int m = 0; m < gMaterialNames.size(); m++) { if (gMaterialNames.getAtIndex(m)->m_shapeIndices.size() == 0) continue; - ShapeContainer* shapeCon =gMaterialNames.getAtIndex(m); - + ShapeContainer* shapeCon = gMaterialNames.getAtIndex(m); + printf("object name = %s\n", shapeCon->m_shapeName.c_str()); - + char objSdfPartFileName[MAX_PATH_LEN]; sprintf(objSdfPartFileName, "part%d.obj", m); @@ -172,7 +170,6 @@ int main(int argc, char* argv[]) sprintf(objFileName, "part%d.obj", m); } - FILE* f = fopen(objFileName, "w"); if (f == 0) { @@ -187,7 +184,6 @@ int main(int argc, char* argv[]) else { fprintf(f, "mtllib bedroom.mtl\n"); - } int faceCount = shapeCon->indices.size(); @@ -237,9 +233,9 @@ int main(int argc, char* argv[]) continue; } fprintf(f, "f %d/%d/%d %d/%d/%d %d/%d/%d\n", - shapeCon->indices[face] + 1, shapeCon->indices[face] + 1, shapeCon->indices[face] + 1, - shapeCon->indices[face + 1] + 1, shapeCon->indices[face + 1] + 1, shapeCon->indices[face + 1] + 1, - shapeCon->indices[face + 2] + 1, shapeCon->indices[face + 2] + 1, shapeCon->indices[face + 2] + 1); + shapeCon->indices[face] + 1, shapeCon->indices[face] + 1, shapeCon->indices[face] + 1, + shapeCon->indices[face + 1] + 1, shapeCon->indices[face + 1] + 1, shapeCon->indices[face + 1] + 1, + shapeCon->indices[face + 2] + 1, shapeCon->indices[face + 2] + 1, shapeCon->indices[face + 2] + 1); } fclose(f); @@ -247,63 +243,54 @@ int main(int argc, char* argv[]) float kdGreen = mat.diffuse[1]; float kdBlue = mat.diffuse[2]; float transparency = mat.transparency; - - fprintf(sdfFile, "\t\t\n" - "\t\t\t1\n" - "\t\t\t0 0 0 0 0 0\n" - "\t\t\t\n" - "\t\t\t\n" - "\t\t\t0\n" - "\t\t\t\n" - "\t\t\t0.166667\n" - "\t\t\t0\n" - "\t\t\t0\n" - "\t\t\t0.166667\n" - "\t\t\t0\n" - "\t\t\t0.166667\n" - "\t\t\t\n" - "\t\t\t\n" - "\t\t\t\n" - "\t\t\t\n" - "\t\t\t\n" - "\t\t\t1 1 1\n" - "\t\t\t\t%s\n" - "\t\t\t\n" - "\t\t\t\n" - "\t\t\t \n" - "\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\t\t1 1 1\n" - "\t\t\t\t\t%s\n" - "\t\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\n" - "\t\t\t\t1 0 0 1\n" - "\t\t\t\t%f %f %f %f\n" - "\t\t\t\t0.1 0.1 0.1 1\n" - "\t\t\t\t0 0 0 0\n" - "\t\t\t \n" - "\t\t\t \n" - "\t\t\t \n" - "\t\t\t\n", objSdfPartFileName, m, m, - objSdfPartFileName, objSdfPartFileName, - kdRed, kdGreen, kdBlue, transparency); - + fprintf(sdfFile, + "\t\t\n" + "\t\t\t1\n" + "\t\t\t0 0 0 0 0 0\n" + "\t\t\t\n" + "\t\t\t\n" + "\t\t\t0\n" + "\t\t\t\n" + "\t\t\t0.166667\n" + "\t\t\t0\n" + "\t\t\t0\n" + "\t\t\t0.166667\n" + "\t\t\t0\n" + "\t\t\t0.166667\n" + "\t\t\t\n" + "\t\t\t\n" + "\t\t\t\n" + "\t\t\t\n" + "\t\t\t\n" + "\t\t\t1 1 1\n" + "\t\t\t\t%s\n" + "\t\t\t\n" + "\t\t\t\n" + "\t\t\t \n" + "\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\t1 1 1\n" + "\t\t\t\t\t%s\n" + "\t\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\n" + "\t\t\t\t1 0 0 1\n" + "\t\t\t\t%f %f %f %f\n" + "\t\t\t\t0.1 0.1 0.1 1\n" + "\t\t\t\t0 0 0 0\n" + "\t\t\t \n" + "\t\t\t \n" + "\t\t\t \n" + "\t\t\t\n", + objSdfPartFileName, m, m, + objSdfPartFileName, objSdfPartFileName, + kdRed, kdGreen, kdBlue, transparency); } - - - - - - - - } else { - for (int s = 0; s < (int)shapes.size(); s++) { tinyobj::shape_t& shape = shapes[s]; @@ -336,10 +323,8 @@ int main(int argc, char* argv[]) else { fprintf(f, "mtllib bedroom.mtl\n"); - } - int faceCount = shape.mesh.indices.size(); int vertexCount = shape.mesh.positions.size(); tinyobj::material_t mat = shape.material; @@ -387,9 +372,9 @@ int main(int argc, char* argv[]) continue; } fprintf(f, "f %d/%d/%d %d/%d/%d %d/%d/%d\n", - shape.mesh.indices[face] + 1, shape.mesh.indices[face] + 1, shape.mesh.indices[face] + 1, - shape.mesh.indices[face + 1] + 1, shape.mesh.indices[face + 1] + 1, shape.mesh.indices[face + 1] + 1, - shape.mesh.indices[face + 2] + 1, shape.mesh.indices[face + 2] + 1, shape.mesh.indices[face + 2] + 1); + shape.mesh.indices[face] + 1, shape.mesh.indices[face] + 1, shape.mesh.indices[face] + 1, + shape.mesh.indices[face + 1] + 1, shape.mesh.indices[face + 1] + 1, shape.mesh.indices[face + 1] + 1, + shape.mesh.indices[face + 2] + 1, shape.mesh.indices[face + 2] + 1, shape.mesh.indices[face + 2] + 1); } fclose(f); @@ -399,54 +384,54 @@ int main(int argc, char* argv[]) float transparency = mat.transparency; char objSdfPartFileName[MAX_PATH_LEN]; sprintf(objSdfPartFileName, "part%d.obj", s); - fprintf(sdfFile, "\t\t\n" - "\t\t\t1\n" - "\t\t\t0 0 0 0 0 0\n" - "\t\t\t\n" - "\t\t\t\n" - "\t\t\t0\n" - "\t\t\t\n" - "\t\t\t0.166667\n" - "\t\t\t0\n" - "\t\t\t0\n" - "\t\t\t0.166667\n" - "\t\t\t0\n" - "\t\t\t0.166667\n" - "\t\t\t\n" - "\t\t\t\n" - "\t\t\t\n" - "\t\t\t\n" - "\t\t\t\n" - "\t\t\t1 1 1\n" - "\t\t\t\t%s\n" - "\t\t\t\n" - "\t\t\t\n" - "\t\t\t \n" - "\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\t\t1 1 1\n" - "\t\t\t\t\t%s\n" - "\t\t\t\t\n" - "\t\t\t\t\n" - "\t\t\t\n" - "\t\t\t\t1 0 0 1\n" - "\t\t\t\t%f %f %f %f\n" - "\t\t\t\t0.1 0.1 0.1 1\n" - "\t\t\t\t0 0 0 0\n" - "\t\t\t \n" - "\t\t\t \n" - "\t\t\t \n" - "\t\t\t\n", objSdfPartFileName, s, s, - objSdfPartFileName, objSdfPartFileName, - kdRed, kdGreen, kdBlue, transparency); - - + fprintf(sdfFile, + "\t\t\n" + "\t\t\t1\n" + "\t\t\t0 0 0 0 0 0\n" + "\t\t\t\n" + "\t\t\t\n" + "\t\t\t0\n" + "\t\t\t\n" + "\t\t\t0.166667\n" + "\t\t\t0\n" + "\t\t\t0\n" + "\t\t\t0.166667\n" + "\t\t\t0\n" + "\t\t\t0.166667\n" + "\t\t\t\n" + "\t\t\t\n" + "\t\t\t\n" + "\t\t\t\n" + "\t\t\t\n" + "\t\t\t1 1 1\n" + "\t\t\t\t%s\n" + "\t\t\t\n" + "\t\t\t\n" + "\t\t\t \n" + "\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\t\t1 1 1\n" + "\t\t\t\t\t%s\n" + "\t\t\t\t\n" + "\t\t\t\t\n" + "\t\t\t\n" + "\t\t\t\t1 0 0 1\n" + "\t\t\t\t%f %f %f %f\n" + "\t\t\t\t0.1 0.1 0.1 1\n" + "\t\t\t\t0 0 0 0\n" + "\t\t\t \n" + "\t\t\t \n" + "\t\t\t \n" + "\t\t\t\n", + objSdfPartFileName, s, s, + objSdfPartFileName, objSdfPartFileName, + kdRed, kdGreen, kdBlue, transparency); } } - fprintf(sdfFile,"\t\n\n"); + fprintf(sdfFile, "\t\n\n"); fclose(sdfFile); - + return 0; } \ No newline at end of file diff --git a/clang-format-all.sh b/clang-format-all.sh new file mode 100644 index 000000000..51a84cbe3 --- /dev/null +++ b/clang-format-all.sh @@ -0,0 +1,84 @@ +#!/bin/bash +# +# clang-format-all: a tool to run clang-format on an entire project +# Copyright (C) 2016 Evan Klitzke +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +function usage { + echo "Usage: $0 DIR..." + exit 1 +} + +if [ $# -eq 0 ]; then + usage +fi + +# Variable that will hold the name of the clang-format command +FMT="" + +# Some distros just call it clang-format. Others (e.g. Ubuntu) are insistent +# that the version number be part of the command. We prefer clang-format if +# that's present, otherwise we work backwards from highest version to lowest +# version. +for clangfmt in clang-format{,-{4,3}.{9,8,7,6,5,4,3,2,1,0}}; do + if which "$clangfmt" &>/dev/null; then + FMT="$clangfmt" + break + fi +done + +# Check if we found a working clang-format +if [ -z "$FMT" ]; then + echo "failed to find clang-format" + exit 1 +fi + +# Check all of the arguments first to make sure they're all directories +for dir in "$@"; do + if [ ! -d "${dir}" ]; then + echo "${dir} is not a directory" + usage + fi +done + +# Find a dominating file, starting from a given directory and going up. +find-dominating-file() { + if [ -r "$1"/"$2" ]; then + return 0 + fi + if [ "$1" = "/" ]; then + return 1 + fi + find-dominating-file "$(realpath "$1"/..)" "$2" + return $? +} + +# Run clang-format -i on all of the things +for dir in "$@"; do + pushd "${dir}" &>/dev/null + if ! find-dominating-file . _clang-format; then + echo "Failed to find dominating .clang-format starting at $PWD" + continue + fi + find . \ + \( -name '*.c' \ + -o -name '*.cc' \ + -o -name '*.cpp' \ + -o -name '*.h' \ + -o -name '*.hh' \ + -o -name '*.hpp' \) \ + -exec "${FMT}" -i -verbose '{}' \; + popd &>/dev/null +done \ No newline at end of file diff --git a/examples/BasicDemo/BasicExample.cpp b/examples/BasicDemo/BasicExample.cpp index 0f243d6a4..67f670d07 100644 --- a/examples/BasicDemo/BasicExample.cpp +++ b/examples/BasicDemo/BasicExample.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "BasicExample.h" #include "btBulletDynamicsCommon.h" @@ -26,14 +25,13 @@ subject to the following restrictions: #include "../CommonInterfaces/CommonRigidBodyBase.h" - struct BasicExample : public CommonRigidBodyBase { BasicExample(struct GUIHelperInterface* helper) - :CommonRigidBodyBase(helper) + : CommonRigidBodyBase(helper) { } - virtual ~BasicExample(){} + virtual ~BasicExample() {} virtual void initPhysics(); virtual void renderScene(); void resetCamera() @@ -41,8 +39,8 @@ struct BasicExample : public CommonRigidBodyBase float dist = 4; float pitch = -35; float yaw = 52; - float targetPos[3]={0,0,0}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {0, 0, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } }; @@ -55,33 +53,30 @@ void BasicExample::initPhysics() m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); if (m_dynamicsWorld->getDebugDrawer()) - m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints); + m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints); ///create a few basic rigid bodies - btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); - + btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.))); //groundShape->initializePolyhedralFeatures(); //btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); - + m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0,-50,0)); + groundTransform.setOrigin(btVector3(0, -50, 0)); { btScalar mass(0.); - createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1)); + createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1)); } - { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance - btBoxShape* colShape = createBoxShape(btVector3(.1,.1,.1)); - + btBoxShape* colShape = createBoxShape(btVector3(.1, .1, .1)); //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); m_collisionShapes.push_back(colShape); @@ -90,62 +85,43 @@ void BasicExample::initPhysics() btTransform startTransform; startTransform.setIdentity(); - btScalar mass(1.f); + btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); - btVector3 localInertia(0,0,0); + btVector3 localInertia(0, 0, 0); if (isDynamic) - colShape->calculateLocalInertia(mass,localInertia); + colShape->calculateLocalInertia(mass, localInertia); - - for (int k=0;kautogenerateGraphicsObjects(m_dynamicsWorld); - } - void BasicExample::renderScene() { CommonRigidBodyBase::renderScene(); - } - - - - - - -CommonExampleInterface* BasicExampleCreateFunc(CommonExampleOptions& options) +CommonExampleInterface* BasicExampleCreateFunc(CommonExampleOptions& options) { return new BasicExample(options.m_guiHelper); - } - B3_STANDALONE_EXAMPLE(BasicExampleCreateFunc) - - - diff --git a/examples/BasicDemo/BasicExample.h b/examples/BasicDemo/BasicExample.h index a72db8482..8fb1aa060 100644 --- a/examples/BasicDemo/BasicExample.h +++ b/examples/BasicDemo/BasicExample.h @@ -16,7 +16,6 @@ subject to the following restrictions: #ifndef BASIC_EXAMPLE_H #define BASIC_EXAMPLE_H -class CommonExampleInterface* BasicExampleCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* BasicExampleCreateFunc(struct CommonExampleOptions& options); - -#endif //BASIC_DEMO_PHYSICS_SETUP_H +#endif //BASIC_DEMO_PHYSICS_SETUP_H diff --git a/examples/BasicDemo/main.cpp b/examples/BasicDemo/main.cpp index 9ee7222d6..08ac541fe 100644 --- a/examples/BasicDemo/main.cpp +++ b/examples/BasicDemo/main.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "BasicExample.h" #include "../CommonInterfaces/CommonExampleInterface.h" @@ -22,26 +21,21 @@ subject to the following restrictions: #include "BulletCollision/CollisionShapes/btCollisionShape.h" #include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" - #include "LinearMath/btTransform.h" #include "LinearMath/btHashMap.h" - int main(int argc, char* argv[]) { - DummyGUIHelper noGfx; CommonExampleOptions options(&noGfx); - CommonExampleInterface* example = BasicExampleCreateFunc(options); - + CommonExampleInterface* example = BasicExampleCreateFunc(options); + example->initPhysics(); - example->stepSimulation(1.f/60.f); + example->stepSimulation(1.f / 60.f); example->exitPhysics(); delete example; return 0; } - - diff --git a/examples/Benchmarks/BenchmarkDemo.cpp b/examples/Benchmarks/BenchmarkDemo.cpp index 255259ce7..c0130dd86 100644 --- a/examples/Benchmarks/BenchmarkDemo.cpp +++ b/examples/Benchmarks/BenchmarkDemo.cpp @@ -13,17 +13,14 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - // Collision Radius #define COLLISION_RADIUS 0.0f #include "BenchmarkDemo.h" - ///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. #include "btBulletDynamicsCommon.h" -#include //printf debugging +#include //printf debugging #include "TaruData.h" #include "landscapeData.h" #include "BulletCollision/BroadphaseCollision/btDbvtBroadphase.h" @@ -47,19 +44,15 @@ class btConstraintSolver; struct btCollisionAlgorithmCreateFunc; class btDefaultCollisionConfiguration; - #include "../MultiThreadedDemo/CommonRigidBodyMTBase.h" - - class BenchmarkDemo : public CommonRigidBodyMTBase { - //keep the collision shapes, for deletion/cleanup - btAlignedObjectArray m_ragdolls; - - int m_benchmark; + btAlignedObjectArray m_ragdolls; + + int m_benchmark; void myinit() { @@ -69,40 +62,38 @@ class BenchmarkDemo : public CommonRigidBodyMTBase void setCameraDistance(btScalar dist) { } - void createTest1(); - void createTest2(); - void createTest3(); - void createTest4(); - void createTest5(); - void createTest6(); - void createTest7(); + void createTest1(); + void createTest2(); + void createTest3(); + void createTest4(); + void createTest5(); + void createTest6(); + void createTest7(); - void createWall(const btVector3& offsetPosition,int stackSize,const btVector3& boxSize); - void createPyramid(const btVector3& offsetPosition,int stackSize,const btVector3& boxSize); - void createTowerCircle(const btVector3& offsetPosition,int stackSize,int rotSize,const btVector3& boxSize); + void createWall(const btVector3& offsetPosition, int stackSize, const btVector3& boxSize); + void createPyramid(const btVector3& offsetPosition, int stackSize, const btVector3& boxSize); + void createTowerCircle(const btVector3& offsetPosition, int stackSize, int rotSize, const btVector3& boxSize); void createLargeMeshBody(); - class SpuBatchRaycaster* m_batchRaycaster; class btThreadSupportInterface* m_batchRaycasterThreadSupport; void castRays(); void initRays(); - public: - +public: BenchmarkDemo(struct GUIHelperInterface* helper, int benchmark) - :CommonRigidBodyMTBase(helper), - m_benchmark(benchmark) + : CommonRigidBodyMTBase(helper), + m_benchmark(benchmark) { } virtual ~BenchmarkDemo() { exitPhysics(); } - void initPhysics(); + void initPhysics(); - void exitPhysics(); + void exitPhysics(); void stepSimulation(float deltaTime); @@ -111,14 +102,11 @@ class BenchmarkDemo : public CommonRigidBodyMTBase float dist = 120; float pitch = -35; float yaw = 52; - float targetPos[3]={0,10.46,0}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {0, 10.46, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } }; - - - class btRaycastBar2 { public: @@ -128,7 +116,7 @@ public: btVector3 hit[NUMRAYS]; btVector3 normal[NUMRAYS]; struct GUIHelperInterface* m_guiHelper; - + int frame_counter; int ms; int sum_ms; @@ -138,7 +126,7 @@ public: #ifdef USE_BT_CLOCK btClock frame_timer; -#endif //USE_BT_CLOCK +#endif //USE_BT_CLOCK btScalar dx; btScalar min_x; @@ -146,7 +134,7 @@ public: btScalar max_y; btScalar sign; - btRaycastBar2 () + btRaycastBar2() { m_guiHelper = 0; ms = 0; @@ -156,9 +144,7 @@ public: sum_ms = 0; } - - - btRaycastBar2 (btScalar ray_length, btScalar z,btScalar max_y,struct GUIHelperInterface* guiHelper) + btRaycastBar2(btScalar ray_length, btScalar z, btScalar max_y, struct GUIHelperInterface* guiHelper) { m_guiHelper = guiHelper; frame_counter = 0; @@ -172,28 +158,27 @@ public: max_x = 0; this->max_y = max_y; sign = 1.0; - btScalar dalpha = 2*SIMD_2_PI/NUMRAYS; + btScalar dalpha = 2 * SIMD_2_PI / NUMRAYS; for (int i = 0; i < NUMRAYS; i++) { btScalar alpha = dalpha * i; - // rotate around by alpha degrees y + // rotate around by alpha degrees y btQuaternion q(btVector3(0.0, 1.0, 0.0), alpha); direction[i] = btVector3(1.0, 0.0, 0.0); - direction[i] = quatRotate(q , direction[i]); + direction[i] = quatRotate(q, direction[i]); direction[i] = direction[i] * ray_length; - - + source[i] = btVector3(min_x, max_y, z); dest[i] = source[i] + direction[i]; - dest[i][1]=-1000; + dest[i][1] = -1000; normal[i] = btVector3(1.0, 0.0, 0.0); } } - void move (btScalar dt) + void move(btScalar dt) { - if (dt > btScalar(1.0/60.0)) - dt = btScalar(1.0/60.0); + if (dt > btScalar(1.0 / 60.0)) + dt = btScalar(1.0 / 60.0); for (int i = 0; i < NUMRAYS; i++) { source[i][0] += dx * dt * sign; @@ -205,85 +190,85 @@ public: sign = -1.0; } - void castRays( btCollisionWorld* cw, int iBegin, int iEnd ) - { - for ( int i = iBegin; i < iEnd; ++i ) - { - + void castRays(btCollisionWorld* cw, int iBegin, int iEnd) + { + for (int i = iBegin; i < iEnd; ++i) + { btCollisionWorld::ClosestRayResultCallback cb(source[i], dest[i]); - + { BT_PROFILE("cw->rayTest"); cw->rayTest(source[i], dest[i], cb); } - if (cb.hasHit ()) + if (cb.hasHit()) { hit[i] = cb.m_hitPointWorld; normal[i] = cb.m_hitNormalWorld; - normal[i].normalize (); - } else { + normal[i].normalize(); + } + else + { hit[i] = dest[i]; normal[i] = btVector3(1.0, 0.0, 0.0); } + } + } - } - } - - struct CastRaysLoopBody : public btIParallelForBody - { - btCollisionWorld* mWorld; + struct CastRaysLoopBody : public btIParallelForBody + { + btCollisionWorld* mWorld; btRaycastBar2* mRaycasts; CastRaysLoopBody(btCollisionWorld* cw, btRaycastBar2* rb) : mWorld(cw), mRaycasts(rb) {} - void forLoop( int iBegin, int iEnd ) const - { - mRaycasts->castRays(mWorld, iBegin, iEnd); - } - }; + void forLoop(int iBegin, int iEnd) const + { + mRaycasts->castRays(mWorld, iBegin, iEnd); + } + }; - void cast (btCollisionWorld* cw, bool multiThreading = false) + void cast(btCollisionWorld* cw, bool multiThreading = false) { BT_PROFILE("cast"); #ifdef USE_BT_CLOCK - frame_timer.reset (); -#endif //USE_BT_CLOCK + frame_timer.reset(); +#endif //USE_BT_CLOCK #ifdef BATCH_RAYCASTER if (!gBatchRaycaster) return; - gBatchRaycaster->clearRays (); + gBatchRaycaster->clearRays(); for (int i = 0; i < NUMRAYS; i++) { - gBatchRaycaster->addRay (source[i], dest[i]); + gBatchRaycaster->addRay(source[i], dest[i]); } - gBatchRaycaster->performBatchRaycast (); - for (int i = 0; i < gBatchRaycaster->getNumRays (); i++) + gBatchRaycaster->performBatchRaycast(); + for (int i = 0; i < gBatchRaycaster->getNumRays(); i++) { - const SpuRaycastTaskWorkUnitOut& out = (*gBatchRaycaster)[i]; - hit[i].setInterpolate3(source[i],dest[i],out.hitFraction); - normal[i] = out.hitNormal; - normal[i].normalize (); + const SpuRaycastTaskWorkUnitOut& out = (*gBatchRaycaster)[i]; + hit[i].setInterpolate3(source[i], dest[i], out.hitFraction); + normal[i] = out.hitNormal; + normal[i].normalize(); } #else #if USE_PARALLEL_RAYCASTS - if ( multiThreading ) - { - CastRaysLoopBody rayLooper(cw, this); - int grainSize = 20; // number of raycasts per task - btParallelFor( 0, NUMRAYS, grainSize, rayLooper ); - } - else -#endif // USE_PARALLEL_RAYCASTS - { - // single threaded - castRays(cw, 0, NUMRAYS); - } + if (multiThreading) + { + CastRaysLoopBody rayLooper(cw, this); + int grainSize = 20; // number of raycasts per task + btParallelFor(0, NUMRAYS, grainSize, rayLooper); + } + else +#endif // USE_PARALLEL_RAYCASTS + { + // single threaded + castRays(cw, 0, NUMRAYS); + } #ifdef USE_BT_CLOCK - ms += frame_timer.getTimeMilliseconds (); -#endif //USE_BT_CLOCK + ms += frame_timer.getTimeMilliseconds(); +#endif //USE_BT_CLOCK frame_counter++; if (frame_counter > 50) { @@ -291,7 +276,7 @@ public: max_ms = ms > max_ms ? ms : max_ms; sum_ms += ms; sum_ms_samples++; - btScalar mean_ms = (btScalar)sum_ms/(btScalar)sum_ms_samples; + btScalar mean_ms = (btScalar)sum_ms / (btScalar)sum_ms_samples; printf("%d rays in %d ms %d %d %f\n", NUMRAYS * frame_counter, ms, min_ms, max_ms, mean_ms); ms = 0; frame_counter = 0; @@ -299,35 +284,33 @@ public: #endif } - void draw () + void draw() { - if (m_guiHelper) { btAlignedObjectArray indices; btAlignedObjectArray points; - - - float lineColor[4]={1,0.4,.4,1}; - + + float lineColor[4] = {1, 0.4, .4, 1}; + for (int i = 0; i < NUMRAYS; i++) { - btVector3FloatData s,h; - for (int w=0;w<4;w++) + btVector3FloatData s, h; + for (int w = 0; w < 4; w++) { s.m_floats[w] = source[i][w]; h.m_floats[w] = hit[i][w]; } - + points.push_back(s); points.push_back(h); indices.push_back(indices.size()); indices.push_back(indices.size()); } - m_guiHelper->getRenderInterface()->drawLines(&points[0].m_floats[0],lineColor,points.size(),sizeof(btVector3FloatData),&indices[0],indices.size(),1); + m_guiHelper->getRenderInterface()->drawLines(&points[0].m_floats[0], lineColor, points.size(), sizeof(btVector3FloatData), &indices[0], indices.size(), 1); } - + #if 0 glDisable (GL_LIGHTING); glColor3f (0.0, 1.0, 0.0); @@ -356,12 +339,10 @@ public: } glEnd (); glEnable (GL_LIGHTING); -#endif //USE_GRAPHICAL_BENCHMARK - +#endif //USE_GRAPHICAL_BENCHMARK } }; - static btRaycastBar2 raycastBar; void BenchmarkDemo::stepSimulation(float deltaTime) @@ -370,28 +351,22 @@ void BenchmarkDemo::stepSimulation(float deltaTime) { m_dynamicsWorld->stepSimulation(deltaTime); } - - if (m_benchmark==7) + + if (m_benchmark == 7) { castRays(); raycastBar.draw(); - } - } - - - - -void BenchmarkDemo::initPhysics() +void BenchmarkDemo::initPhysics() { m_guiHelper->setUpAxis(1); setCameraDistance(btScalar(100.)); - createEmptyDynamicsWorld(); + createEmptyDynamicsWorld(); /////collision configuration contains default setup for memory, collision setup //btDefaultCollisionConstructionInfo cci; //cci.m_defaultMaxPersistentManifoldPoolSize = 32768; @@ -402,8 +377,6 @@ void BenchmarkDemo::initPhysics() // //m_dispatcher->setDispatcherFlags(btCollisionDispatcher::CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION); - - /////the maximum size of the collision world. Make sure objects stay within these boundaries /////Don't make the world AABB size too large, it will harm simulation quality and performance //btVector3 worldAabbMin(-1000,-1000,-1000); @@ -411,40 +384,36 @@ void BenchmarkDemo::initPhysics() // //btHashedOverlappingPairCache* pairCache = new btHashedOverlappingPairCache(); //m_broadphase = new btAxisSweep3(worldAabbMin,worldAabbMax,3500,pairCache); -// m_broadphase = new btSimpleBroadphase(); -// m_broadphase = new btDbvtBroadphase(); - + // m_broadphase = new btSimpleBroadphase(); + // m_broadphase = new btDbvtBroadphase(); ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) //btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; - - + //m_solver = sol; //btDiscreteDynamicsWorld* dynamicsWorld; //m_dynamicsWorld = dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); - ///the following 3 lines increase the performance dramatically, with a little bit of loss of quality - m_dynamicsWorld->getSolverInfo().m_solverMode |=SOLVER_ENABLE_FRICTION_DIRECTION_CACHING; //don't recalculate friction values each frame - m_dynamicsWorld->getSolverInfo().m_numIterations = 5; //few solver iterations + m_dynamicsWorld->getSolverInfo().m_solverMode |= SOLVER_ENABLE_FRICTION_DIRECTION_CACHING; //don't recalculate friction values each frame + m_dynamicsWorld->getSolverInfo().m_numIterations = 5; //few solver iterations //m_defaultContactProcessingThreshold = 0.f;//used when creating bodies: body->setContactProcessingThreshold(...); m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); - - m_dynamicsWorld->setGravity(btVector3(0,-10,0)); + m_dynamicsWorld->setGravity(btVector3(0, -10, 0)); - if (m_benchmark<5) + if (m_benchmark < 5) { ///create a few basic rigid bodies - btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(250.),btScalar(50.),btScalar(250.))); - // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),0); - + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(250.), btScalar(50.), btScalar(250.))); + // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),0); + m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0,-50,0)); + groundTransform.setOrigin(btVector3(0, -50, 0)); //We can also use DemoApplication::createRigidBody, but for clarity it is provided here: { @@ -453,13 +422,13 @@ void BenchmarkDemo::initPhysics() //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); - btVector3 localInertia(0,0,0); + btVector3 localInertia(0, 0, 0); if (isDynamic) - groundShape->calculateLocalInertia(mass,localInertia); + groundShape->calculateLocalInertia(mass, localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); - btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia); btRigidBody* body = new btRigidBody(rbInfo); //add the body to the dynamics world @@ -470,30 +439,30 @@ void BenchmarkDemo::initPhysics() switch (m_benchmark) { case 1: - { - createTest1(); - break; - } + { + createTest1(); + break; + } case 2: - { - createTest2(); - break; - } + { + createTest2(); + break; + } case 3: - { - createTest3(); - break; - } + { + createTest3(); + break; + } case 4: - { - createTest4(); - break; - } + { + createTest4(); + break; + } case 5: - { - createTest5(); - break; - } + { + createTest5(); + break; + } case 6: { createTest6(); @@ -505,81 +474,80 @@ void BenchmarkDemo::initPhysics() break; } - - default: + default: { - } + } } m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); - } - -void BenchmarkDemo::createTest1() +void BenchmarkDemo::createTest1() { // 3000 int size = 8; const float cubeSize = 1.0f; float spacing = cubeSize; - btVector3 pos(0.0f, cubeSize * 2,0.f); + btVector3 pos(0.0f, cubeSize * 2, 0.f); float offset = -size * (cubeSize * 2.0f + spacing) * 0.5f; - btBoxShape* blockShape = new btBoxShape(btVector3(cubeSize-COLLISION_RADIUS,cubeSize-COLLISION_RADIUS,cubeSize-COLLISION_RADIUS)); - btVector3 localInertia(0,0,0); + btBoxShape* blockShape = new btBoxShape(btVector3(cubeSize - COLLISION_RADIUS, cubeSize - COLLISION_RADIUS, cubeSize - COLLISION_RADIUS)); + btVector3 localInertia(0, 0, 0); float mass = 2.f; - blockShape->calculateLocalInertia(mass,localInertia); - + blockShape->calculateLocalInertia(mass, localInertia); + btTransform trans; trans.setIdentity(); - for(int k=0;k<47;k++) { - for(int j=0;jcalculateLocalInertia(mass,localInertia); + btVector3 localInertia(0, 0, 0); + blockShape->calculateLocalInertia(mass, localInertia); -// btScalar diffX = boxSize[0] * 1.0f; - btScalar diffY = boxSize[1] * 1.0f; - btScalar diffZ = boxSize[2] * 1.0f; + // btScalar diffX = boxSize[0] * 1.0f; + btScalar diffY = boxSize[1] * 1.0f; + btScalar diffZ = boxSize[2] * 1.0f; - btScalar offset = -stackSize * (diffZ * 2.0f) * 0.5f; + btScalar offset = -stackSize * (diffZ * 2.0f) * 0.5f; btVector3 pos(0.0f, diffY, 0.0f); btTransform trans; trans.setIdentity(); - while(stackSize) { - for(int i=0;icalculateLocalInertia(mass,localInertia); + btVector3 localInertia(0, 0, 0); + blockShape->calculateLocalInertia(mass, localInertia); + + btScalar diffX = boxSize[0] * 1.02f; + btScalar diffY = boxSize[1] * 1.02f; + btScalar diffZ = boxSize[2] * 1.02f; - - btScalar diffX = boxSize[0]*1.02f; - btScalar diffY = boxSize[1]*1.02f; - btScalar diffZ = boxSize[2]*1.02f; - btScalar offsetX = -stackSize * (diffX * 2.0f + space) * 0.5f; btScalar offsetZ = -stackSize * (diffZ * 2.0f + space) * 0.5f; - while(stackSize) { - for(int j=0;jcreateRigidBody(mass,trans,blockShape); - - + this->createRigidBody(mass, trans, blockShape); } } offsetX += diffX; @@ -624,87 +592,78 @@ void BenchmarkDemo::createPyramid(const btVector3& offsetPosition,int stackSize, pos[1] += (diffY * 2.0f + space); stackSize--; } - } - const btVector3 rotate( const btQuaternion& quat, const btVector3 & vec ) +const btVector3 rotate(const btQuaternion& quat, const btVector3& vec) { - float tmpX, tmpY, tmpZ, tmpW; - tmpX = ( ( ( quat.getW() * vec.getX() ) + ( quat.getY() * vec.getZ() ) ) - ( quat.getZ() * vec.getY() ) ); - tmpY = ( ( ( quat.getW() * vec.getY() ) + ( quat.getZ() * vec.getX() ) ) - ( quat.getX() * vec.getZ() ) ); - tmpZ = ( ( ( quat.getW() * vec.getZ() ) + ( quat.getX() * vec.getY() ) ) - ( quat.getY() * vec.getX() ) ); - tmpW = ( ( ( quat.getX() * vec.getX() ) + ( quat.getY() * vec.getY() ) ) + ( quat.getZ() * vec.getZ() ) ); - return btVector3( - ( ( ( ( tmpW * quat.getX() ) + ( tmpX * quat.getW() ) ) - ( tmpY * quat.getZ() ) ) + ( tmpZ * quat.getY() ) ), - ( ( ( ( tmpW * quat.getY() ) + ( tmpY * quat.getW() ) ) - ( tmpZ * quat.getX() ) ) + ( tmpX * quat.getZ() ) ), - ( ( ( ( tmpW * quat.getZ() ) + ( tmpZ * quat.getW() ) ) - ( tmpX * quat.getY() ) ) + ( tmpY * quat.getX() ) ) - ); + float tmpX, tmpY, tmpZ, tmpW; + tmpX = (((quat.getW() * vec.getX()) + (quat.getY() * vec.getZ())) - (quat.getZ() * vec.getY())); + tmpY = (((quat.getW() * vec.getY()) + (quat.getZ() * vec.getX())) - (quat.getX() * vec.getZ())); + tmpZ = (((quat.getW() * vec.getZ()) + (quat.getX() * vec.getY())) - (quat.getY() * vec.getX())); + tmpW = (((quat.getX() * vec.getX()) + (quat.getY() * vec.getY())) + (quat.getZ() * vec.getZ())); + return btVector3( + ((((tmpW * quat.getX()) + (tmpX * quat.getW())) - (tmpY * quat.getZ())) + (tmpZ * quat.getY())), + ((((tmpW * quat.getY()) + (tmpY * quat.getW())) - (tmpZ * quat.getX())) + (tmpX * quat.getZ())), + ((((tmpW * quat.getZ()) + (tmpZ * quat.getW())) - (tmpX * quat.getY())) + (tmpY * quat.getX()))); } -void BenchmarkDemo::createTowerCircle(const btVector3& offsetPosition,int stackSize,int rotSize,const btVector3& boxSize) +void BenchmarkDemo::createTowerCircle(const btVector3& offsetPosition, int stackSize, int rotSize, const btVector3& boxSize) { - - btBoxShape* blockShape = new btBoxShape(btVector3(boxSize[0]-COLLISION_RADIUS,boxSize[1]-COLLISION_RADIUS,boxSize[2]-COLLISION_RADIUS)); + btBoxShape* blockShape = new btBoxShape(btVector3(boxSize[0] - COLLISION_RADIUS, boxSize[1] - COLLISION_RADIUS, boxSize[2] - COLLISION_RADIUS)); btTransform trans; trans.setIdentity(); float mass = 1.f; - btVector3 localInertia(0,0,0); - blockShape->calculateLocalInertia(mass,localInertia); - + btVector3 localInertia(0, 0, 0); + blockShape->calculateLocalInertia(mass, localInertia); float radius = 1.3f * rotSize * boxSize[0] / SIMD_PI; // create active boxes - btQuaternion rotY(0,1,0,0); + btQuaternion rotY(0, 1, 0, 0); float posY = boxSize[1]; - for(int i=0;icalculateLocalInertia(mass,localInertia); + shape->calculateLocalInertia(mass, localInertia); btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); - - btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,shape,localInertia); + + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, shape, localInertia); btRigidBody* body = new btRigidBody(rbInfo); m_ownerWorld->addRigidBody(body); @@ -774,74 +733,75 @@ class RagDoll } public: - RagDoll (btDynamicsWorld* ownerWorld, const btVector3& positionOffset,btScalar scale) - : m_ownerWorld (ownerWorld) + RagDoll(btDynamicsWorld* ownerWorld, const btVector3& positionOffset, btScalar scale) + : m_ownerWorld(ownerWorld) { // Setup the geometry - m_shapes[BODYPART_PELVIS] = new btCapsuleShape(btScalar(0.15)*scale, btScalar(0.20)*scale); - m_shapes[BODYPART_SPINE] = new btCapsuleShape(btScalar(0.15)*scale, btScalar(0.28)*scale); - m_shapes[BODYPART_HEAD] = new btCapsuleShape(btScalar(0.10)*scale, btScalar(0.05)*scale); - m_shapes[BODYPART_LEFT_UPPER_LEG] = new btCapsuleShape(btScalar(0.07)*scale, btScalar(0.45)*scale); - m_shapes[BODYPART_LEFT_LOWER_LEG] = new btCapsuleShape(btScalar(0.05)*scale, btScalar(0.37)*scale); - m_shapes[BODYPART_RIGHT_UPPER_LEG] = new btCapsuleShape(btScalar(0.07)*scale, btScalar(0.45)*scale); - m_shapes[BODYPART_RIGHT_LOWER_LEG] = new btCapsuleShape(btScalar(0.05)*scale, btScalar(0.37)*scale); - m_shapes[BODYPART_LEFT_UPPER_ARM] = new btCapsuleShape(btScalar(0.05)*scale, btScalar(0.33)*scale); - m_shapes[BODYPART_LEFT_LOWER_ARM] = new btCapsuleShape(btScalar(0.04)*scale, btScalar(0.25)*scale); - m_shapes[BODYPART_RIGHT_UPPER_ARM] = new btCapsuleShape(btScalar(0.05)*scale, btScalar(0.33)*scale); - m_shapes[BODYPART_RIGHT_LOWER_ARM] = new btCapsuleShape(btScalar(0.04)*scale, btScalar(0.25)*scale); + m_shapes[BODYPART_PELVIS] = new btCapsuleShape(btScalar(0.15) * scale, btScalar(0.20) * scale); + m_shapes[BODYPART_SPINE] = new btCapsuleShape(btScalar(0.15) * scale, btScalar(0.28) * scale); + m_shapes[BODYPART_HEAD] = new btCapsuleShape(btScalar(0.10) * scale, btScalar(0.05) * scale); + m_shapes[BODYPART_LEFT_UPPER_LEG] = new btCapsuleShape(btScalar(0.07) * scale, btScalar(0.45) * scale); + m_shapes[BODYPART_LEFT_LOWER_LEG] = new btCapsuleShape(btScalar(0.05) * scale, btScalar(0.37) * scale); + m_shapes[BODYPART_RIGHT_UPPER_LEG] = new btCapsuleShape(btScalar(0.07) * scale, btScalar(0.45) * scale); + m_shapes[BODYPART_RIGHT_LOWER_LEG] = new btCapsuleShape(btScalar(0.05) * scale, btScalar(0.37) * scale); + m_shapes[BODYPART_LEFT_UPPER_ARM] = new btCapsuleShape(btScalar(0.05) * scale, btScalar(0.33) * scale); + m_shapes[BODYPART_LEFT_LOWER_ARM] = new btCapsuleShape(btScalar(0.04) * scale, btScalar(0.25) * scale); + m_shapes[BODYPART_RIGHT_UPPER_ARM] = new btCapsuleShape(btScalar(0.05) * scale, btScalar(0.33) * scale); + m_shapes[BODYPART_RIGHT_LOWER_ARM] = new btCapsuleShape(btScalar(0.04) * scale, btScalar(0.25) * scale); // Setup all the rigid bodies - btTransform offset; offset.setIdentity(); + btTransform offset; + offset.setIdentity(); offset.setOrigin(positionOffset); btTransform transform; transform.setIdentity(); - transform.setOrigin(scale*btVector3(btScalar(0.), btScalar(1.), btScalar(0.))); - m_bodies[BODYPART_PELVIS] = createRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_PELVIS]); + transform.setOrigin(scale * btVector3(btScalar(0.), btScalar(1.), btScalar(0.))); + m_bodies[BODYPART_PELVIS] = createRigidBody(btScalar(1.), offset * transform, m_shapes[BODYPART_PELVIS]); transform.setIdentity(); - transform.setOrigin(scale*btVector3(btScalar(0.), btScalar(1.2), btScalar(0.))); - m_bodies[BODYPART_SPINE] = createRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_SPINE]); + transform.setOrigin(scale * btVector3(btScalar(0.), btScalar(1.2), btScalar(0.))); + m_bodies[BODYPART_SPINE] = createRigidBody(btScalar(1.), offset * transform, m_shapes[BODYPART_SPINE]); transform.setIdentity(); - transform.setOrigin(scale*btVector3(btScalar(0.), btScalar(1.6), btScalar(0.))); - m_bodies[BODYPART_HEAD] = createRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_HEAD]); + transform.setOrigin(scale * btVector3(btScalar(0.), btScalar(1.6), btScalar(0.))); + m_bodies[BODYPART_HEAD] = createRigidBody(btScalar(1.), offset * transform, m_shapes[BODYPART_HEAD]); transform.setIdentity(); - transform.setOrigin(scale*btVector3(btScalar(-0.18), btScalar(0.65), btScalar(0.))); - m_bodies[BODYPART_LEFT_UPPER_LEG] = createRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_UPPER_LEG]); + transform.setOrigin(scale * btVector3(btScalar(-0.18), btScalar(0.65), btScalar(0.))); + m_bodies[BODYPART_LEFT_UPPER_LEG] = createRigidBody(btScalar(1.), offset * transform, m_shapes[BODYPART_LEFT_UPPER_LEG]); transform.setIdentity(); - transform.setOrigin(scale*btVector3(btScalar(-0.18), btScalar(0.2), btScalar(0.))); - m_bodies[BODYPART_LEFT_LOWER_LEG] = createRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_LOWER_LEG]); + transform.setOrigin(scale * btVector3(btScalar(-0.18), btScalar(0.2), btScalar(0.))); + m_bodies[BODYPART_LEFT_LOWER_LEG] = createRigidBody(btScalar(1.), offset * transform, m_shapes[BODYPART_LEFT_LOWER_LEG]); transform.setIdentity(); - transform.setOrigin(scale*btVector3(btScalar(0.18), btScalar(0.65), btScalar(0.))); - m_bodies[BODYPART_RIGHT_UPPER_LEG] = createRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_UPPER_LEG]); + transform.setOrigin(scale * btVector3(btScalar(0.18), btScalar(0.65), btScalar(0.))); + m_bodies[BODYPART_RIGHT_UPPER_LEG] = createRigidBody(btScalar(1.), offset * transform, m_shapes[BODYPART_RIGHT_UPPER_LEG]); transform.setIdentity(); - transform.setOrigin(scale*btVector3(btScalar(0.18), btScalar(0.2), btScalar(0.))); - m_bodies[BODYPART_RIGHT_LOWER_LEG] = createRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_LOWER_LEG]); + transform.setOrigin(scale * btVector3(btScalar(0.18), btScalar(0.2), btScalar(0.))); + m_bodies[BODYPART_RIGHT_LOWER_LEG] = createRigidBody(btScalar(1.), offset * transform, m_shapes[BODYPART_RIGHT_LOWER_LEG]); transform.setIdentity(); - transform.setOrigin(scale*btVector3(btScalar(-0.35), btScalar(1.45), btScalar(0.))); - transform.getBasis().setEulerZYX(0,0,M_PI_2); - m_bodies[BODYPART_LEFT_UPPER_ARM] = createRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_UPPER_ARM]); + transform.setOrigin(scale * btVector3(btScalar(-0.35), btScalar(1.45), btScalar(0.))); + transform.getBasis().setEulerZYX(0, 0, M_PI_2); + m_bodies[BODYPART_LEFT_UPPER_ARM] = createRigidBody(btScalar(1.), offset * transform, m_shapes[BODYPART_LEFT_UPPER_ARM]); transform.setIdentity(); - transform.setOrigin(scale*btVector3(btScalar(-0.7), btScalar(1.45), btScalar(0.))); - transform.getBasis().setEulerZYX(0,0,M_PI_2); - m_bodies[BODYPART_LEFT_LOWER_ARM] = createRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_LEFT_LOWER_ARM]); + transform.setOrigin(scale * btVector3(btScalar(-0.7), btScalar(1.45), btScalar(0.))); + transform.getBasis().setEulerZYX(0, 0, M_PI_2); + m_bodies[BODYPART_LEFT_LOWER_ARM] = createRigidBody(btScalar(1.), offset * transform, m_shapes[BODYPART_LEFT_LOWER_ARM]); transform.setIdentity(); - transform.setOrigin(scale*btVector3(btScalar(0.35), btScalar(1.45), btScalar(0.))); - transform.getBasis().setEulerZYX(0,0,-M_PI_2); - m_bodies[BODYPART_RIGHT_UPPER_ARM] = createRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_UPPER_ARM]); + transform.setOrigin(scale * btVector3(btScalar(0.35), btScalar(1.45), btScalar(0.))); + transform.getBasis().setEulerZYX(0, 0, -M_PI_2); + m_bodies[BODYPART_RIGHT_UPPER_ARM] = createRigidBody(btScalar(1.), offset * transform, m_shapes[BODYPART_RIGHT_UPPER_ARM]); transform.setIdentity(); - transform.setOrigin(scale*btVector3(btScalar(0.7), btScalar(1.45), btScalar(0.))); - transform.getBasis().setEulerZYX(0,0,-M_PI_2); - m_bodies[BODYPART_RIGHT_LOWER_ARM] = createRigidBody(btScalar(1.), offset*transform, m_shapes[BODYPART_RIGHT_LOWER_ARM]); + transform.setOrigin(scale * btVector3(btScalar(0.7), btScalar(1.45), btScalar(0.))); + transform.getBasis().setEulerZYX(0, 0, -M_PI_2); + m_bodies[BODYPART_RIGHT_LOWER_ARM] = createRigidBody(btScalar(1.), offset * transform, m_shapes[BODYPART_RIGHT_LOWER_ARM]); // Setup some damping on the m_bodies for (int i = 0; i < BODYPART_COUNT; ++i) @@ -857,118 +817,145 @@ public: btTransform localA, localB; - localA.setIdentity(); localB.setIdentity(); - localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(scale*btVector3(btScalar(0.), btScalar(0.15), btScalar(0.))); - localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(scale*btVector3(btScalar(0.), btScalar(-0.15), btScalar(0.))); - hingeC = new btHingeConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_SPINE], localA, localB); + localA.setIdentity(); + localB.setIdentity(); + localA.getBasis().setEulerZYX(0, M_PI_2, 0); + localA.setOrigin(scale * btVector3(btScalar(0.), btScalar(0.15), btScalar(0.))); + localB.getBasis().setEulerZYX(0, M_PI_2, 0); + localB.setOrigin(scale * btVector3(btScalar(0.), btScalar(-0.15), btScalar(0.))); + hingeC = new btHingeConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_SPINE], localA, localB); hingeC->setLimit(btScalar(-M_PI_4), btScalar(M_PI_2)); m_joints[JOINT_PELVIS_SPINE] = hingeC; m_ownerWorld->addConstraint(m_joints[JOINT_PELVIS_SPINE], true); - - localA.setIdentity(); localB.setIdentity(); - localA.getBasis().setEulerZYX(0,0,M_PI_2); localA.setOrigin(scale*btVector3(btScalar(0.), btScalar(0.30), btScalar(0.))); - localB.getBasis().setEulerZYX(0,0,M_PI_2); localB.setOrigin(scale*btVector3(btScalar(0.), btScalar(-0.14), btScalar(0.))); + localA.setIdentity(); + localB.setIdentity(); + localA.getBasis().setEulerZYX(0, 0, M_PI_2); + localA.setOrigin(scale * btVector3(btScalar(0.), btScalar(0.30), btScalar(0.))); + localB.getBasis().setEulerZYX(0, 0, M_PI_2); + localB.setOrigin(scale * btVector3(btScalar(0.), btScalar(-0.14), btScalar(0.))); coneC = new btConeTwistConstraint(*m_bodies[BODYPART_SPINE], *m_bodies[BODYPART_HEAD], localA, localB); coneC->setLimit(M_PI_4, M_PI_4, M_PI_2); m_joints[JOINT_SPINE_HEAD] = coneC; m_ownerWorld->addConstraint(m_joints[JOINT_SPINE_HEAD], true); - - localA.setIdentity(); localB.setIdentity(); - localA.getBasis().setEulerZYX(0,0,-M_PI_4*5); localA.setOrigin(scale*btVector3(btScalar(-0.18), btScalar(-0.10), btScalar(0.))); - localB.getBasis().setEulerZYX(0,0,-M_PI_4*5); localB.setOrigin(scale*btVector3(btScalar(0.), btScalar(0.225), btScalar(0.))); + localA.setIdentity(); + localB.setIdentity(); + localA.getBasis().setEulerZYX(0, 0, -M_PI_4 * 5); + localA.setOrigin(scale * btVector3(btScalar(-0.18), btScalar(-0.10), btScalar(0.))); + localB.getBasis().setEulerZYX(0, 0, -M_PI_4 * 5); + localB.setOrigin(scale * btVector3(btScalar(0.), btScalar(0.225), btScalar(0.))); coneC = new btConeTwistConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_LEFT_UPPER_LEG], localA, localB); coneC->setLimit(M_PI_4, M_PI_4, 0); m_joints[JOINT_LEFT_HIP] = coneC; m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_HIP], true); - localA.setIdentity(); localB.setIdentity(); - localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(scale*btVector3(btScalar(0.), btScalar(-0.225), btScalar(0.))); - localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(scale*btVector3(btScalar(0.), btScalar(0.185), btScalar(0.))); - hingeC = new btHingeConstraint(*m_bodies[BODYPART_LEFT_UPPER_LEG], *m_bodies[BODYPART_LEFT_LOWER_LEG], localA, localB); + localA.setIdentity(); + localB.setIdentity(); + localA.getBasis().setEulerZYX(0, M_PI_2, 0); + localA.setOrigin(scale * btVector3(btScalar(0.), btScalar(-0.225), btScalar(0.))); + localB.getBasis().setEulerZYX(0, M_PI_2, 0); + localB.setOrigin(scale * btVector3(btScalar(0.), btScalar(0.185), btScalar(0.))); + hingeC = new btHingeConstraint(*m_bodies[BODYPART_LEFT_UPPER_LEG], *m_bodies[BODYPART_LEFT_LOWER_LEG], localA, localB); hingeC->setLimit(btScalar(0), btScalar(M_PI_2)); m_joints[JOINT_LEFT_KNEE] = hingeC; m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_KNEE], true); - - localA.setIdentity(); localB.setIdentity(); - localA.getBasis().setEulerZYX(0,0,M_PI_4); localA.setOrigin(scale*btVector3(btScalar(0.18), btScalar(-0.10), btScalar(0.))); - localB.getBasis().setEulerZYX(0,0,M_PI_4); localB.setOrigin(scale*btVector3(btScalar(0.), btScalar(0.225), btScalar(0.))); + localA.setIdentity(); + localB.setIdentity(); + localA.getBasis().setEulerZYX(0, 0, M_PI_4); + localA.setOrigin(scale * btVector3(btScalar(0.18), btScalar(-0.10), btScalar(0.))); + localB.getBasis().setEulerZYX(0, 0, M_PI_4); + localB.setOrigin(scale * btVector3(btScalar(0.), btScalar(0.225), btScalar(0.))); coneC = new btConeTwistConstraint(*m_bodies[BODYPART_PELVIS], *m_bodies[BODYPART_RIGHT_UPPER_LEG], localA, localB); coneC->setLimit(M_PI_4, M_PI_4, 0); m_joints[JOINT_RIGHT_HIP] = coneC; m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_HIP], true); - localA.setIdentity(); localB.setIdentity(); - localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(scale*btVector3(btScalar(0.), btScalar(-0.225), btScalar(0.))); - localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(scale*btVector3(btScalar(0.), btScalar(0.185), btScalar(0.))); - hingeC = new btHingeConstraint(*m_bodies[BODYPART_RIGHT_UPPER_LEG], *m_bodies[BODYPART_RIGHT_LOWER_LEG], localA, localB); + localA.setIdentity(); + localB.setIdentity(); + localA.getBasis().setEulerZYX(0, M_PI_2, 0); + localA.setOrigin(scale * btVector3(btScalar(0.), btScalar(-0.225), btScalar(0.))); + localB.getBasis().setEulerZYX(0, M_PI_2, 0); + localB.setOrigin(scale * btVector3(btScalar(0.), btScalar(0.185), btScalar(0.))); + hingeC = new btHingeConstraint(*m_bodies[BODYPART_RIGHT_UPPER_LEG], *m_bodies[BODYPART_RIGHT_LOWER_LEG], localA, localB); hingeC->setLimit(btScalar(0), btScalar(M_PI_2)); m_joints[JOINT_RIGHT_KNEE] = hingeC; m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_KNEE], true); - - localA.setIdentity(); localB.setIdentity(); - localA.getBasis().setEulerZYX(0,0,M_PI); localA.setOrigin(scale*btVector3(btScalar(-0.2), btScalar(0.15), btScalar(0.))); - localB.getBasis().setEulerZYX(0,0,M_PI_2); localB.setOrigin(scale*btVector3(btScalar(0.), btScalar(-0.18), btScalar(0.))); + localA.setIdentity(); + localB.setIdentity(); + localA.getBasis().setEulerZYX(0, 0, M_PI); + localA.setOrigin(scale * btVector3(btScalar(-0.2), btScalar(0.15), btScalar(0.))); + localB.getBasis().setEulerZYX(0, 0, M_PI_2); + localB.setOrigin(scale * btVector3(btScalar(0.), btScalar(-0.18), btScalar(0.))); coneC = new btConeTwistConstraint(*m_bodies[BODYPART_SPINE], *m_bodies[BODYPART_LEFT_UPPER_ARM], localA, localB); coneC->setLimit(M_PI_2, M_PI_2, 0); m_joints[JOINT_LEFT_SHOULDER] = coneC; m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_SHOULDER], true); - localA.setIdentity(); localB.setIdentity(); - localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(scale*btVector3(btScalar(0.), btScalar(0.18), btScalar(0.))); - localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(scale*btVector3(btScalar(0.), btScalar(-0.14), btScalar(0.))); - hingeC = new btHingeConstraint(*m_bodies[BODYPART_LEFT_UPPER_ARM], *m_bodies[BODYPART_LEFT_LOWER_ARM], localA, localB); + localA.setIdentity(); + localB.setIdentity(); + localA.getBasis().setEulerZYX(0, M_PI_2, 0); + localA.setOrigin(scale * btVector3(btScalar(0.), btScalar(0.18), btScalar(0.))); + localB.getBasis().setEulerZYX(0, M_PI_2, 0); + localB.setOrigin(scale * btVector3(btScalar(0.), btScalar(-0.14), btScalar(0.))); + hingeC = new btHingeConstraint(*m_bodies[BODYPART_LEFT_UPPER_ARM], *m_bodies[BODYPART_LEFT_LOWER_ARM], localA, localB); hingeC->setLimit(btScalar(-M_PI_2), btScalar(0)); m_joints[JOINT_LEFT_ELBOW] = hingeC; m_ownerWorld->addConstraint(m_joints[JOINT_LEFT_ELBOW], true); - - - localA.setIdentity(); localB.setIdentity(); - localA.getBasis().setEulerZYX(0,0,0); localA.setOrigin(scale*btVector3(btScalar(0.2), btScalar(0.15), btScalar(0.))); - localB.getBasis().setEulerZYX(0,0,M_PI_2); localB.setOrigin(scale*btVector3(btScalar(0.), btScalar(-0.18), btScalar(0.))); + localA.setIdentity(); + localB.setIdentity(); + localA.getBasis().setEulerZYX(0, 0, 0); + localA.setOrigin(scale * btVector3(btScalar(0.2), btScalar(0.15), btScalar(0.))); + localB.getBasis().setEulerZYX(0, 0, M_PI_2); + localB.setOrigin(scale * btVector3(btScalar(0.), btScalar(-0.18), btScalar(0.))); coneC = new btConeTwistConstraint(*m_bodies[BODYPART_SPINE], *m_bodies[BODYPART_RIGHT_UPPER_ARM], localA, localB); coneC->setLimit(M_PI_2, M_PI_2, 0); m_joints[JOINT_RIGHT_SHOULDER] = coneC; m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_SHOULDER], true); - localA.setIdentity(); localB.setIdentity(); - localA.getBasis().setEulerZYX(0,M_PI_2,0); localA.setOrigin(scale*btVector3(btScalar(0.), btScalar(0.18), btScalar(0.))); - localB.getBasis().setEulerZYX(0,M_PI_2,0); localB.setOrigin(scale*btVector3(btScalar(0.), btScalar(-0.14), btScalar(0.))); - hingeC = new btHingeConstraint(*m_bodies[BODYPART_RIGHT_UPPER_ARM], *m_bodies[BODYPART_RIGHT_LOWER_ARM], localA, localB); + localA.setIdentity(); + localB.setIdentity(); + localA.getBasis().setEulerZYX(0, M_PI_2, 0); + localA.setOrigin(scale * btVector3(btScalar(0.), btScalar(0.18), btScalar(0.))); + localB.getBasis().setEulerZYX(0, M_PI_2, 0); + localB.setOrigin(scale * btVector3(btScalar(0.), btScalar(-0.14), btScalar(0.))); + hingeC = new btHingeConstraint(*m_bodies[BODYPART_RIGHT_UPPER_ARM], *m_bodies[BODYPART_RIGHT_LOWER_ARM], localA, localB); hingeC->setLimit(btScalar(-M_PI_2), btScalar(0)); m_joints[JOINT_RIGHT_ELBOW] = hingeC; m_ownerWorld->addConstraint(m_joints[JOINT_RIGHT_ELBOW], true); } - virtual ~RagDoll () + virtual ~RagDoll() { int i; // Remove all constraints - for ( i = 0; i < JOINT_COUNT; ++i) + for (i = 0; i < JOINT_COUNT; ++i) { m_ownerWorld->removeConstraint(m_joints[i]); - delete m_joints[i]; m_joints[i] = 0; + delete m_joints[i]; + m_joints[i] = 0; } // Remove all bodies and shapes - for ( i = 0; i < BODYPART_COUNT; ++i) + for (i = 0; i < BODYPART_COUNT; ++i) { m_ownerWorld->removeRigidBody(m_bodies[i]); - + delete m_bodies[i]->getMotionState(); - delete m_bodies[i]; m_bodies[i] = 0; - delete m_shapes[i]; m_shapes[i] = 0; + delete m_bodies[i]; + m_bodies[i] = 0; + delete m_shapes[i]; + m_shapes[i] = 0; } } }; -void BenchmarkDemo::createTest3() +void BenchmarkDemo::createTest3() { setCameraDistance(btScalar(50.)); @@ -981,13 +968,15 @@ void BenchmarkDemo::createTest3() btScalar scale(3.5); btVector3 pos(0.0f, sizeY, 0.0f); - while(size) { + while (size) + { float offset = -size * (sizeX * 6.0f) * 0.5f; - for(int i=0;isetLocalScaling(btVector3(scaling,scaling,scaling)); + convexHullShape->setLocalScaling(btVector3(scaling, scaling, scaling)); - for (int i=0;iaddPoint(vtx*btScalar(1./scaling)); + btVector3 vtx(TaruVtx[i * 3], TaruVtx[i * 3 + 1], TaruVtx[i * 3 + 2]); + convexHullShape->addPoint(vtx * btScalar(1. / scaling)); } //this will enable polyhedral contact clipping, better quality, slightly slower @@ -1026,25 +1014,27 @@ void BenchmarkDemo::createTest4() trans.setIdentity(); float mass = 1.f; - btVector3 localInertia(0,0,0); - convexHullShape->calculateLocalInertia(mass,localInertia); + btVector3 localInertia(0, 0, 0); + convexHullShape->calculateLocalInertia(mass, localInertia); - for(int k=0;k<15;k++) { - for(int j=0;jaddIndexedMesh(part,PHY_SHORT); + meshInterface->addIndexedMesh(part, PHY_SHORT); - bool useQuantizedAabbCompression = true; - btBvhTriangleMeshShape* trimeshShape = new btBvhTriangleMeshShape(meshInterface,useQuantizedAabbCompression); - btVector3 localInertia(0,0,0); - trans.setOrigin(btVector3(0,-25,0)); + bool useQuantizedAabbCompression = true; + btBvhTriangleMeshShape* trimeshShape = new btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression); + btVector3 localInertia(0, 0, 0); + trans.setOrigin(btVector3(0, -25, 0)); - btRigidBody* body = createRigidBody(0,trans,trimeshShape); - body->setFriction (btScalar(0.9)); - + btRigidBody* body = createRigidBody(0, trans, trimeshShape); + body->setFriction(btScalar(0.9)); } - } - -void BenchmarkDemo::createTest5() +void BenchmarkDemo::createTest5() { setCameraDistance(btScalar(250.)); - btVector3 boxSize(1.5f,1.5f,1.5f); + btVector3 boxSize(1.5f, 1.5f, 1.5f); float boxMass = 1.0f; float sphereRadius = 1.5f; float sphereMass = 1.0f; @@ -1166,42 +1153,52 @@ void BenchmarkDemo::createTest5() float spacing = 2.0f; btVector3 pos(0.0f, 20.0f, 0.0f); float offset = -size * (cubeSize * 2.0f + spacing) * 0.5f; - + int numBodies = 0; - for(int k=0;kaddPoint(vtx); } @@ -1235,9 +1232,8 @@ void BenchmarkDemo::createTest6() trans.setIdentity(); float mass = 1.f; - btVector3 localInertia(0,0,0); - convexHullShape->calculateLocalInertia(mass,localInertia); - + btVector3 localInertia(0, 0, 0); + convexHullShape->calculateLocalInertia(mass, localInertia); { int size = 10; @@ -1247,55 +1243,52 @@ void BenchmarkDemo::createTest6() float spacing = 2.0f; btVector3 pos(0.0f, 20.0f, 0.0f); float offset = -size * (cubeSize * 2.0f + spacing) * 0.5f; - - - for(int k=0;kcreateCollisionWorld( maxNumObjsCapacity, maxNumShapesCapacity, maxNumPairsCapacity); + CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle; + return sdk->createCollisionWorld(maxNumObjsCapacity, maxNumShapesCapacity, maxNumPairsCapacity); } -void plDeleteCollisionWorld(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle) +void plDeleteCollisionWorld(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle) { - CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; + CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle; if (sdk && worldHandle) { sdk->deleteCollisionWorld(worldHandle); @@ -26,7 +26,7 @@ plCollisionSdkHandle plCreateBullet2CollisionSdk() return Bullet2CollisionSdk::createBullet2SdkHandle(); #else return 0; -#endif //DISABLE_BULLET2_COLLISION_SDK +#endif //DISABLE_BULLET2_COLLISION_SDK } plCollisionSdkHandle plCreateRealTimeBullet3CollisionSdk() @@ -40,91 +40,89 @@ plCollisionSdkHandle plCreateRealTimeBullet3CollisionSdk() void plDeleteCollisionSdk(plCollisionSdkHandle collisionSdkHandle) { - CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; + CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle; delete sdk; } plCollisionShapeHandle plCreateSphereShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plReal radius) { - CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; - return sdk->createSphereShape(worldHandle,radius); - + CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle; + return sdk->createSphereShape(worldHandle, radius); } -plCollisionShapeHandle plCreatePlaneShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, - plReal planeNormalX, - plReal planeNormalY, - plReal planeNormalZ, - plReal planeConstant) +plCollisionShapeHandle plCreatePlaneShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, + plReal planeNormalX, + plReal planeNormalY, + plReal planeNormalZ, + plReal planeConstant) { - CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; - return sdk->createPlaneShape(worldHandle,planeNormalX,planeNormalY,planeNormalZ,planeConstant); -} - -plCollisionShapeHandle plCreateCapsuleShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plReal radius, plReal height, int capsuleAxis) -{ - CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; - return sdk->createCapsuleShape(worldHandle,radius,height,capsuleAxis); + CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle; + return sdk->createPlaneShape(worldHandle, planeNormalX, planeNormalY, planeNormalZ, planeConstant); } -plCollisionShapeHandle plCreateCompoundShape(plCollisionSdkHandle collisionSdkHandle,plCollisionWorldHandle worldHandle) +plCollisionShapeHandle plCreateCapsuleShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plReal radius, plReal height, int capsuleAxis) { - CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; + CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle; + return sdk->createCapsuleShape(worldHandle, radius, height, capsuleAxis); +} + +plCollisionShapeHandle plCreateCompoundShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle) +{ + CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle; return sdk->createCompoundShape(worldHandle); } -void plAddChildShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape,plCollisionShapeHandle childShape, plVector3 childPos,plQuaternion childOrn) +void plAddChildShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape, plVector3 childPos, plQuaternion childOrn) { - CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; - sdk->addChildShape(worldHandle,compoundShape,childShape,childPos,childOrn); + CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle; + sdk->addChildShape(worldHandle, compoundShape, childShape, childPos, childOrn); } void plDeleteShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle shapeHandle) { - CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; - sdk->deleteShape(worldHandle,shapeHandle); + CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle; + sdk->deleteShape(worldHandle, shapeHandle); } -plCollisionObjectHandle plCreateCollisionObject( plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, void* userData, int userIndex, plCollisionShapeHandle cshape ,plVector3 childPos,plQuaternion childOrn) +plCollisionObjectHandle plCreateCollisionObject(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, void* userData, int userIndex, plCollisionShapeHandle cshape, plVector3 childPos, plQuaternion childOrn) { - CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; + CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle; return sdk->createCollisionObject(worldHandle, userData, userIndex, cshape, childPos, childOrn); - } void plDeleteCollisionObject(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle body) { - CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; + CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle; sdk->deleteCollisionObject(body); } -void plSetCollisionObjectTransform( plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle objHandle, plVector3 position,plQuaternion orientation) +void plSetCollisionObjectTransform(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle objHandle, plVector3 position, plQuaternion orientation) { - CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; - sdk->setCollisionObjectTransform(worldHandle,objHandle,position,orientation); + CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle; + sdk->setCollisionObjectTransform(worldHandle, objHandle, position, orientation); } void plAddCollisionObject(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle world, plCollisionObjectHandle object) { - CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; - sdk->addCollisionObject(world,object); + CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle; + sdk->addCollisionObject(world, object); } void plRemoveCollisionObject(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle world, plCollisionObjectHandle object) { - CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; - sdk->removeCollisionObject(world,object); + CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle; + sdk->removeCollisionObject(world, object); } /* Collision Queries */ int plCollide(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle colA, plCollisionObjectHandle colB, - lwContactPoint* pointsOut, int pointCapacity) + lwContactPoint* pointsOut, int pointCapacity) { - CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; - return sdk->collide(worldHandle, colA,colB,pointsOut,pointCapacity); + CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle; + return sdk->collide(worldHandle, colA, colB, pointsOut, pointCapacity); } void plWorldCollide(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle world, - plNearCallback filter, void* userData) + plNearCallback filter, void* userData) { - CollisionSdkInterface* sdk = (CollisionSdkInterface*) collisionSdkHandle; - sdk->collideWorld(world,filter,userData); + CollisionSdkInterface* sdk = (CollisionSdkInterface*)collisionSdkHandle; + sdk->collideWorld(world, filter, userData); } diff --git a/examples/Collision/CollisionSdkC_Api.h b/examples/Collision/CollisionSdkC_Api.h index fbbd767e3..afbe453f5 100644 --- a/examples/Collision/CollisionSdkC_Api.h +++ b/examples/Collision/CollisionSdkC_Api.h @@ -1,111 +1,104 @@ #ifndef LW_COLLISION_C_API_H #define LW_COLLISION_C_API_H - -#define PL_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name - +#define PL_DECLARE_HANDLE(name) \ + typedef struct name##__ \ + { \ + int unused; \ + } * name #ifdef BT_USE_DOUBLE_PRECISION -typedef double plReal; +typedef double plReal; #else -typedef float plReal; +typedef float plReal; #endif -typedef plReal plVector3[3]; -typedef plReal plQuaternion[4]; +typedef plReal plVector3[3]; +typedef plReal plQuaternion[4]; #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif - - - + /** Particular collision SDK (C-API) */ PL_DECLARE_HANDLE(plCollisionSdkHandle); - + /** Collision world, belonging to some collision SDK (C-API)*/ PL_DECLARE_HANDLE(plCollisionWorldHandle); - + /** Collision object that can be part of a collision World (C-API)*/ PL_DECLARE_HANDLE(plCollisionObjectHandle); - + /** Collision Shape/Geometry, property of a collision object (C-API)*/ PL_DECLARE_HANDLE(plCollisionShapeHandle); /* Collision SDK */ - + extern plCollisionSdkHandle plCreateBullet2CollisionSdk(); #ifndef DISABLE_REAL_TIME_BULLET3_COLLISION_SDK extern plCollisionSdkHandle plCreateRealTimeBullet3CollisionSdk(); -#endif //DISABLE_REAL_TIME_BULLET3_COLLISION_SDK +#endif //DISABLE_REAL_TIME_BULLET3_COLLISION_SDK + + // extern plCollisionSdkHandle plCreateCustomCollisionSdk(); -// extern plCollisionSdkHandle plCreateCustomCollisionSdk(); - extern void plDeleteCollisionSdk(plCollisionSdkHandle collisionSdkHandle); //extern int plGetSdkWorldCreationIntParameter(); //extern int plSetSdkWorldCreationIntParameter(int newValue); /* Collision World */ - - extern plCollisionWorldHandle plCreateCollisionWorld(plCollisionSdkHandle collisionSdkHandle, int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity); - extern void plDeleteCollisionWorld(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world); - - - extern void plAddCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world, plCollisionObjectHandle object); - extern void plRemoveCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world, plCollisionObjectHandle object); - - + + extern plCollisionWorldHandle plCreateCollisionWorld(plCollisionSdkHandle collisionSdkHandle, int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity); + extern void plDeleteCollisionWorld(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world); + + extern void plAddCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world, plCollisionObjectHandle object); + extern void plRemoveCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world, plCollisionObjectHandle object); + /* Collision Object */ - - extern plCollisionObjectHandle plCreateCollisionObject( plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape , plVector3 startPosition,plQuaternion startOrientation); - extern void plDeleteCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle body); - extern void plSetCollisionObjectTransform( plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle objHandle, plVector3 startPosition,plQuaternion startOrientation); - + + extern plCollisionObjectHandle plCreateCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape, plVector3 startPosition, plQuaternion startOrientation); + extern void plDeleteCollisionObject(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle body); + extern void plSetCollisionObjectTransform(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle objHandle, plVector3 startPosition, plQuaternion startOrientation); + /* Collision Shape definition */ - - extern plCollisionShapeHandle plCreateSphereShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle, plReal radius); - extern plCollisionShapeHandle plCreateCapsuleShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle, plReal radius, plReal height, int capsuleAxis); - extern plCollisionShapeHandle plCreatePlaneShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle, - plReal planeNormalX, - plReal planeNormalY, - plReal planeNormalZ, - plReal planeConstant); - extern plCollisionShapeHandle plCreateCompoundShape(plCollisionSdkHandle sdk,plCollisionWorldHandle worldHandle); - extern void plAddChildShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape,plCollisionShapeHandle childShape, plVector3 childPos,plQuaternion childOrn); - - extern void plDeleteShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape); - - - + + extern plCollisionShapeHandle plCreateSphereShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle, plReal radius); + extern plCollisionShapeHandle plCreateCapsuleShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle, plReal radius, plReal height, int capsuleAxis); + extern plCollisionShapeHandle plCreatePlaneShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle, + plReal planeNormalX, + plReal planeNormalY, + plReal planeNormalZ, + plReal planeConstant); + extern plCollisionShapeHandle plCreateCompoundShape(plCollisionSdkHandle sdk, plCollisionWorldHandle worldHandle); + extern void plAddChildShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape, plVector3 childPos, plQuaternion childOrn); + + extern void plDeleteShape(plCollisionSdkHandle collisionSdkHandle, plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape); + /* Contact Results */ - + struct lwContactPoint { plVector3 m_ptOnAWorld; plVector3 m_ptOnBWorld; plVector3 m_normalOnB; - plReal m_distance; + plReal m_distance; }; - + /* Collision Filtering */ - typedef void(*plNearCallback)(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, void* userData, - plCollisionObjectHandle objA, plCollisionObjectHandle objB); - - + typedef void (*plNearCallback)(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, void* userData, + plCollisionObjectHandle objA, plCollisionObjectHandle objB); + /* Collision Queries */ extern int plCollide(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, plCollisionObjectHandle colA, plCollisionObjectHandle colB, lwContactPoint* pointsOut, int pointCapacity); - + extern void plWorldCollide(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle world, plNearCallback filter, void* userData); - - + #ifdef __cplusplus } #endif - -#endif //LW_COLLISION_C_API_H - +#endif //LW_COLLISION_C_API_H diff --git a/examples/Collision/CollisionTutorialBullet2.cpp b/examples/Collision/CollisionTutorialBullet2.cpp index 6e65ac0cd..015e53902 100644 --- a/examples/Collision/CollisionTutorialBullet2.cpp +++ b/examples/Collision/CollisionTutorialBullet2.cpp @@ -27,124 +27,121 @@ const int sNumSpheres = 10; lwContactPoint pointsOut[sPointCapacity]; int numNearCallbacks = 0; -static btVector4 sColors[4] = -{ - btVector4(1,0.7,0.7,1), - btVector4(1,1,0.7,1), - btVector4(0.7,1,0.7,1), - btVector4(0.7,1,1,1), +static btVector4 sColors[4] = + { + btVector4(1, 0.7, 0.7, 1), + btVector4(1, 1, 0.7, 1), + btVector4(0.7, 1, 0.7, 1), + btVector4(0.7, 1, 1, 1), }; void myNearCallback(plCollisionSdkHandle sdkHandle, plCollisionWorldHandle worldHandle, void* userData, plCollisionObjectHandle objA, plCollisionObjectHandle objB) { numNearCallbacks++; - int remainingCapacity = sPointCapacity-gTotalPoints; - btAssert(remainingCapacity>0); + int remainingCapacity = sPointCapacity - gTotalPoints; + btAssert(remainingCapacity > 0); - if (remainingCapacity>0) + if (remainingCapacity > 0) { lwContactPoint* pointPtr = &pointsOut[gTotalPoints]; - int numNewPoints = plCollide(sdkHandle, worldHandle, objA,objB,pointPtr,remainingCapacity); + int numNewPoints = plCollide(sdkHandle, worldHandle, objA, objB, pointPtr, remainingCapacity); btAssert(numNewPoints <= remainingCapacity); - gTotalPoints+=numNewPoints; + gTotalPoints += numNewPoints; } } class CollisionTutorialBullet2 : public CommonExampleInterface { - CommonGraphicsApp* m_app; + CommonGraphicsApp* m_app; GUIHelperInterface* m_guiHelper; - int m_tutorialIndex; - - TimeSeriesCanvas* m_timeSeriesCanvas0; - + int m_tutorialIndex; + + TimeSeriesCanvas* m_timeSeriesCanvas0; + plCollisionSdkHandle m_collisionSdkHandle; plCollisionWorldHandle m_collisionWorldHandle; - -// int m_stage; -// int m_counter; - + + // int m_stage; + // int m_counter; + public: - - CollisionTutorialBullet2(GUIHelperInterface* guiHelper, int tutorialIndex) - :m_app(guiHelper->getAppInterface()), - m_guiHelper(guiHelper), - m_tutorialIndex(tutorialIndex), - m_timeSeriesCanvas0(0), - m_collisionSdkHandle(0), - m_collisionWorldHandle(0) -// m_stage(0), -// m_counter(0) - { - + CollisionTutorialBullet2(GUIHelperInterface* guiHelper, int tutorialIndex) + : m_app(guiHelper->getAppInterface()), + m_guiHelper(guiHelper), + m_tutorialIndex(tutorialIndex), + m_timeSeriesCanvas0(0), + m_collisionSdkHandle(0), + m_collisionWorldHandle(0) + // m_stage(0), + // m_counter(0) + { gTotalPoints = 0; m_app->setUpAxis(1); - + switch (m_tutorialIndex) { case TUT_SPHERE_PLANE_RTB3: case TUT_SPHERE_PLANE_BULLET2: { - - if (m_tutorialIndex==TUT_SPHERE_PLANE_BULLET2) + if (m_tutorialIndex == TUT_SPHERE_PLANE_BULLET2) { m_collisionSdkHandle = plCreateBullet2CollisionSdk(); - } else + } + else { #ifndef DISABLE_REAL_TIME_BULLET3_COLLISION_SDK m_collisionSdkHandle = plCreateRealTimeBullet3CollisionSdk(); -#endif //DISABLE_REAL_TIME_BULLET3_COLLISION_SDK +#endif //DISABLE_REAL_TIME_BULLET3_COLLISION_SDK } if (m_collisionSdkHandle) { - int maxNumObjsCapacity=1024; - int maxNumShapesCapacity=1024; - int maxNumPairsCapacity=16384; + int maxNumObjsCapacity = 1024; + int maxNumShapesCapacity = 1024; + int maxNumPairsCapacity = 16384; btAlignedObjectArray colliders; - m_collisionWorldHandle = plCreateCollisionWorld(m_collisionSdkHandle,maxNumObjsCapacity,maxNumShapesCapacity,maxNumPairsCapacity); + m_collisionWorldHandle = plCreateCollisionWorld(m_collisionSdkHandle, maxNumObjsCapacity, maxNumShapesCapacity, maxNumPairsCapacity); //create objects, do query etc { float radius = 1.f; void* userPointer = 0; { - for (int j=0;jcreateCollisionObjectGraphicsObject(colObj,color); - } - if (m_tutorialIndex==TUT_SPHERE_PLANE_BULLET2) + if (m_tutorialIndex == TUT_SPHERE_PLANE_BULLET2) { - btCollisionShape* colShape = (btCollisionShape*) compoundShape; + btCollisionShape* colShape = (btCollisionShape*)compoundShape; m_guiHelper->createCollisionShapeGraphicsObject(colShape); - } else + } + else { } - + { - btVector3 pos(j*sNumSpheres*1.5,-2.4,0); - btQuaternion orn(0,0,0,1); - plCollisionObjectHandle colObjHandle = plCreateCollisionObject(m_collisionSdkHandle,m_collisionWorldHandle,userPointer, -1,compoundShape,pos,orn); - if (m_tutorialIndex==TUT_SPHERE_PLANE_BULLET2) + btVector3 pos(j * sNumSpheres * 1.5, -2.4, 0); + btQuaternion orn(0, 0, 0, 1); + plCollisionObjectHandle colObjHandle = plCreateCollisionObject(m_collisionSdkHandle, m_collisionWorldHandle, userPointer, -1, compoundShape, pos, orn); + if (m_tutorialIndex == TUT_SPHERE_PLANE_BULLET2) { - btCollisionObject* colObj = (btCollisionObject*) colObjHandle; - btVector4 color=sColors[j&3]; - m_guiHelper->createCollisionObjectGraphicsObject(colObj,color); + btCollisionObject* colObj = (btCollisionObject*)colObjHandle; + btVector4 color = sColors[j & 3]; + m_guiHelper->createCollisionObjectGraphicsObject(colObj, color); colliders.push_back(colObjHandle); - plAddCollisionObject(m_collisionSdkHandle, m_collisionWorldHandle,colObjHandle); + plAddCollisionObject(m_collisionSdkHandle, m_collisionWorldHandle, colObjHandle); } } } @@ -152,27 +149,26 @@ public: } { - plCollisionShapeHandle colShape = plCreatePlaneShape(m_collisionSdkHandle, m_collisionWorldHandle,0,1,0,-3.5); - btVector3 pos(0,0,0); - btQuaternion orn(0,0,0,1); + plCollisionShapeHandle colShape = plCreatePlaneShape(m_collisionSdkHandle, m_collisionWorldHandle, 0, 1, 0, -3.5); + btVector3 pos(0, 0, 0); + btQuaternion orn(0, 0, 0, 1); void* userPointer = 0; - plCollisionObjectHandle colObj = plCreateCollisionObject(m_collisionSdkHandle,m_collisionWorldHandle,userPointer, 0,colShape,pos,orn); + plCollisionObjectHandle colObj = plCreateCollisionObject(m_collisionSdkHandle, m_collisionWorldHandle, userPointer, 0, colShape, pos, orn); colliders.push_back(colObj); - plAddCollisionObject(m_collisionSdkHandle, m_collisionWorldHandle,colObj); + plAddCollisionObject(m_collisionSdkHandle, m_collisionWorldHandle, colObj); } - int numContacts = plCollide(m_collisionSdkHandle,m_collisionWorldHandle,colliders[0],colliders[1],pointsOut,sPointCapacity); - printf("numContacts = %d\n", numContacts); - void* myUserPtr = 0; - - plWorldCollide(m_collisionSdkHandle,m_collisionWorldHandle,myNearCallback, myUserPtr); - printf("total points=%d\n",gTotalPoints); - - //plRemoveCollisionObject(m_collisionSdkHandle,m_collisionWorldHandle,colObj); + int numContacts = plCollide(m_collisionSdkHandle, m_collisionWorldHandle, colliders[0], colliders[1], pointsOut, sPointCapacity); + printf("numContacts = %d\n", numContacts); + void* myUserPtr = 0; + + plWorldCollide(m_collisionSdkHandle, m_collisionWorldHandle, myNearCallback, myUserPtr); + printf("total points=%d\n", gTotalPoints); + + //plRemoveCollisionObject(m_collisionSdkHandle,m_collisionWorldHandle,colObj); //plDeleteCollisionObject(m_collisionSdkHandle,colObj); //plDeleteShape(m_collisionSdkHandle,colShape); } - /* m_timeSeriesCanvas0 = new TimeSeriesCanvas(m_app->m_2dCanvasInterface,512,256,"Constant Velocity"); @@ -184,100 +180,86 @@ public: */ break; } - - + default: { - - m_timeSeriesCanvas0 = new TimeSeriesCanvas(m_app->m_2dCanvasInterface,512,256,"Unknown"); - m_timeSeriesCanvas0 ->setupTimeSeries(1,60, 0); - + m_timeSeriesCanvas0 = new TimeSeriesCanvas(m_app->m_2dCanvasInterface, 512, 256, "Unknown"); + m_timeSeriesCanvas0->setupTimeSeries(1, 60, 0); } }; - - { - - int boxId = m_app->registerCubeShape(100,0.01,100); - b3Vector3 pos = b3MakeVector3(0,-3.5,0); - b3Quaternion orn(0,0,0,1); - b3Vector4 color = b3MakeVector4(1,1,1,1); - b3Vector3 scaling = b3MakeVector3(1,1,1); - m_app->m_renderer->registerGraphicsInstance(boxId,pos,orn,color,scaling); + int boxId = m_app->registerCubeShape(100, 0.01, 100); + b3Vector3 pos = b3MakeVector3(0, -3.5, 0); + b3Quaternion orn(0, 0, 0, 1); + b3Vector4 color = b3MakeVector4(1, 1, 1, 1); + b3Vector3 scaling = b3MakeVector3(1, 1, 1); + m_app->m_renderer->registerGraphicsInstance(boxId, pos, orn, color, scaling); } - { int textureIndex = -1; - + if (1) { - int width,height,n; - + int width, height, n; + const char* filename = "data/cube.png"; - const unsigned char* image=0; - - const char* prefix[]={"./","../","../../","../../../","../../../../"}; - int numprefix = sizeof(prefix)/sizeof(const char*); - - for (int i=0;!image && im_renderer->registerTexture(image,width,height); + textureIndex = m_app->m_renderer->registerTexture(image, width, height); } } - } - + m_app->m_renderer->writeTransforms(); - } - virtual ~CollisionTutorialBullet2() - { + } + virtual ~CollisionTutorialBullet2() + { delete m_timeSeriesCanvas0; - plDeleteCollisionWorld(m_collisionSdkHandle,m_collisionWorldHandle); + plDeleteCollisionWorld(m_collisionSdkHandle, m_collisionWorldHandle); plDeleteCollisionSdk(m_collisionSdkHandle); m_timeSeriesCanvas0 = 0; + } - } - - - virtual void initPhysics() - { - } - virtual void exitPhysics() - { - - } - - - virtual void stepSimulation(float deltaTime) - { + virtual void initPhysics() + { + } + virtual void exitPhysics() + { + } + + virtual void stepSimulation(float deltaTime) + { #ifndef BT_NO_PROFILE CProfileManager::Reset(); #endif - - - + void* myUserPtr = 0; - + gTotalPoints = 0; numNearCallbacks = 0; { BT_PROFILE("plWorldCollide"); if (m_collisionSdkHandle && m_collisionWorldHandle) { - plWorldCollide(m_collisionSdkHandle,m_collisionWorldHandle,myNearCallback, myUserPtr); + plWorldCollide(m_collisionSdkHandle, m_collisionWorldHandle, myNearCallback, myUserPtr); } } @@ -303,87 +285,76 @@ public: }; #endif - + if (m_timeSeriesCanvas0) m_timeSeriesCanvas0->nextTick(); - - - + // m_app->m_renderer->writeSingleInstanceTransformToCPU(m_bodies[i]->m_worldPose.m_position, m_bodies[i]->m_worldPose.m_orientation, m_bodies[i]->m_graphicsIndex); - - - m_app->m_renderer->writeTransforms(); + + m_app->m_renderer->writeTransforms(); #ifndef BT_NO_PROFILE - CProfileManager::Increment_Frame_Counter(); + CProfileManager::Increment_Frame_Counter(); #endif - } - virtual void renderScene() - { + } + virtual void renderScene() + { if (m_app && m_app->m_renderer) { m_app->m_renderer->renderScene(); m_app->m_renderer->clearZBuffer(); - m_app->drawText3D("X",1,0,0,1); - m_app->drawText3D("Y",0,1,0,1); - m_app->drawText3D("Z",0,0,1,1); + m_app->drawText3D("X", 1, 0, 0, 1); + m_app->drawText3D("Y", 0, 1, 0, 1); + m_app->drawText3D("Z", 0, 0, 1, 1); - - for (int i=0;im_renderer->drawLine(contact.m_ptOnAWorld,contact.m_ptOnBWorld,color,lineWidth); + m_app->m_renderer->drawLine(contact.m_ptOnAWorld, contact.m_ptOnBWorld, color, lineWidth); } } - - } + } - - - virtual void physicsDebugDraw(int debugDrawFlags) - { - - - } - virtual bool mouseMoveCallback(float x,float y) - { - return false; - } - virtual bool mouseButtonCallback(int button, int state, float x, float y) - { - return false; - } - virtual bool keyboardCallback(int key, int state) - { - return false; - } - + virtual void physicsDebugDraw(int debugDrawFlags) + { + } + virtual bool mouseMoveCallback(float x, float y) + { + return false; + } + virtual bool mouseButtonCallback(int button, int state, float x, float y) + { + return false; + } + virtual bool keyboardCallback(int key, int state) + { + return false; + } virtual void resetCamera() { float dist = 10.5; float pitch = -32; float yaw = 136; - float targetPos[3]={0,0,0}; - if (m_app->m_renderer && m_app->m_renderer->getActiveCamera()) + float targetPos[3] = {0, 0, 0}; + if (m_app->m_renderer && m_app->m_renderer->getActiveCamera()) { m_app->m_renderer->getActiveCamera()->setCameraDistance(dist); m_app->m_renderer->getActiveCamera()->setCameraPitch(pitch); m_app->m_renderer->getActiveCamera()->setCameraYaw(yaw); - m_app->m_renderer->getActiveCamera()->setCameraTargetPosition(targetPos[0],targetPos[1],targetPos[2]); + m_app->m_renderer->getActiveCamera()->setCameraTargetPosition(targetPos[0], targetPos[1], targetPos[2]); } } }; -class CommonExampleInterface* CollisionTutorialBullet2CreateFunc(struct CommonExampleOptions& options) +class CommonExampleInterface* CollisionTutorialBullet2CreateFunc(struct CommonExampleOptions& options) { return new CollisionTutorialBullet2(options.m_guiHelper, options.m_option); } - diff --git a/examples/Collision/CollisionTutorialBullet2.h b/examples/Collision/CollisionTutorialBullet2.h index df34e7946..6ed76f243 100644 --- a/examples/Collision/CollisionTutorialBullet2.h +++ b/examples/Collision/CollisionTutorialBullet2.h @@ -1,12 +1,12 @@ #ifndef COLLISION_TUTORIAL_H -#define COLLISION_TUTORIAL_H +#define COLLISION_TUTORIAL_H enum EnumCollisionTutorialTypes { - TUT_SPHERE_PLANE_BULLET2=0, - TUT_SPHERE_PLANE_RTB3, + TUT_SPHERE_PLANE_BULLET2 = 0, + TUT_SPHERE_PLANE_RTB3, }; -class CommonExampleInterface* CollisionTutorialBullet2CreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* CollisionTutorialBullet2CreateFunc(struct CommonExampleOptions& options); -#endif //COLLISION_TUTORIAL_H +#endif //COLLISION_TUTORIAL_H diff --git a/examples/Collision/Internal/Bullet2CollisionSdk.cpp b/examples/Collision/Internal/Bullet2CollisionSdk.cpp index ec7a689c2..b03d7fc98 100644 --- a/examples/Collision/Internal/Bullet2CollisionSdk.cpp +++ b/examples/Collision/Internal/Bullet2CollisionSdk.cpp @@ -7,103 +7,101 @@ struct Bullet2CollisionSdkInternalData btCollisionDispatcher* m_dispatcher; btBroadphaseInterface* m_aabbBroadphase; btCollisionWorld* m_collisionWorld; - + Bullet2CollisionSdkInternalData() - : - m_collisionConfig(0), - m_dispatcher(0), - m_aabbBroadphase(0), - m_collisionWorld(0) + : m_collisionConfig(0), + m_dispatcher(0), + m_aabbBroadphase(0), + m_collisionWorld(0) { } }; - Bullet2CollisionSdk::Bullet2CollisionSdk() { m_internalData = new Bullet2CollisionSdkInternalData; } - + Bullet2CollisionSdk::~Bullet2CollisionSdk() { delete m_internalData; m_internalData = 0; } - + plCollisionWorldHandle Bullet2CollisionSdk::createCollisionWorld(int /*maxNumObjsCapacity*/, int /*maxNumShapesCapacity*/, int /*maxNumPairsCapacity*/) { m_internalData->m_collisionConfig = new btDefaultCollisionConfiguration; - + m_internalData->m_dispatcher = new btCollisionDispatcher(m_internalData->m_collisionConfig); m_internalData->m_aabbBroadphase = new btDbvtBroadphase(); m_internalData->m_collisionWorld = new btCollisionWorld(m_internalData->m_dispatcher, m_internalData->m_aabbBroadphase, m_internalData->m_collisionConfig); - return (plCollisionWorldHandle) m_internalData->m_collisionWorld; + return (plCollisionWorldHandle)m_internalData->m_collisionWorld; } - + void Bullet2CollisionSdk::deleteCollisionWorld(plCollisionWorldHandle worldHandle) { - btCollisionWorld* world = (btCollisionWorld*) worldHandle; + btCollisionWorld* world = (btCollisionWorld*)worldHandle; btAssert(m_internalData->m_collisionWorld == world); - + if (m_internalData->m_collisionWorld == world) { delete m_internalData->m_collisionWorld; - m_internalData->m_collisionWorld=0; + m_internalData->m_collisionWorld = 0; delete m_internalData->m_aabbBroadphase; - m_internalData->m_aabbBroadphase=0; + m_internalData->m_aabbBroadphase = 0; delete m_internalData->m_dispatcher; - m_internalData->m_dispatcher=0; + m_internalData->m_dispatcher = 0; delete m_internalData->m_collisionConfig; - m_internalData->m_collisionConfig=0; - } + m_internalData->m_collisionConfig = 0; + } } plCollisionShapeHandle Bullet2CollisionSdk::createSphereShape(plCollisionWorldHandle /*worldHandle*/, plReal radius) { btSphereShape* sphereShape = new btSphereShape(radius); - return (plCollisionShapeHandle) sphereShape; + return (plCollisionShapeHandle)sphereShape; } -plCollisionShapeHandle Bullet2CollisionSdk::createPlaneShape(plCollisionWorldHandle worldHandle, - plReal planeNormalX, - plReal planeNormalY, - plReal planeNormalZ, - plReal planeConstant) +plCollisionShapeHandle Bullet2CollisionSdk::createPlaneShape(plCollisionWorldHandle worldHandle, + plReal planeNormalX, + plReal planeNormalY, + plReal planeNormalZ, + plReal planeConstant) { - btStaticPlaneShape* planeShape = new btStaticPlaneShape(btVector3(planeNormalX,planeNormalY,planeNormalZ),planeConstant); - return (plCollisionShapeHandle) planeShape; + btStaticPlaneShape* planeShape = new btStaticPlaneShape(btVector3(planeNormalX, planeNormalY, planeNormalZ), planeConstant); + return (plCollisionShapeHandle)planeShape; } -plCollisionShapeHandle Bullet2CollisionSdk::createCapsuleShape(plCollisionWorldHandle worldHandle, - plReal radius, - plReal height, - int capsuleAxis) +plCollisionShapeHandle Bullet2CollisionSdk::createCapsuleShape(plCollisionWorldHandle worldHandle, + plReal radius, + plReal height, + int capsuleAxis) { btCapsuleShape* capsule = 0; switch (capsuleAxis) { - case 0: - { - capsule = new btCapsuleShapeX(radius,height); - break; - } - case 1: - { - capsule = new btCapsuleShape(radius,height); - break; - } - case 2: - { - capsule = new btCapsuleShapeZ(radius,height); - break; - } - default: - { - btAssert(0); - } + case 0: + { + capsule = new btCapsuleShapeX(radius, height); + break; + } + case 1: + { + capsule = new btCapsuleShape(radius, height); + break; + } + case 2: + { + capsule = new btCapsuleShapeZ(radius, height); + break; + } + default: + { + btAssert(0); + } } return (plCollisionShapeHandle)capsule; } @@ -112,28 +110,27 @@ plCollisionShapeHandle Bullet2CollisionSdk::createCompoundShape(plCollisionWorld { return (plCollisionShapeHandle) new btCompoundShape(); } -void Bullet2CollisionSdk::addChildShape(plCollisionWorldHandle worldHandle,plCollisionShapeHandle compoundShapeHandle, plCollisionShapeHandle childShapeHandle,plVector3 childPos,plQuaternion childOrn) +void Bullet2CollisionSdk::addChildShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShapeHandle, plCollisionShapeHandle childShapeHandle, plVector3 childPos, plQuaternion childOrn) { - btCompoundShape* compound = (btCompoundShape*) compoundShapeHandle; - btCollisionShape* childShape = (btCollisionShape*) childShapeHandle; + btCompoundShape* compound = (btCompoundShape*)compoundShapeHandle; + btCollisionShape* childShape = (btCollisionShape*)childShapeHandle; btTransform localTrans; - localTrans.setOrigin(btVector3(childPos[0],childPos[1],childPos[2])); - localTrans.setRotation(btQuaternion(childOrn[0],childOrn[1],childOrn[2],childOrn[3])); - compound->addChildShape(localTrans,childShape); - + localTrans.setOrigin(btVector3(childPos[0], childPos[1], childPos[2])); + localTrans.setRotation(btQuaternion(childOrn[0], childOrn[1], childOrn[2], childOrn[3])); + compound->addChildShape(localTrans, childShape); } void Bullet2CollisionSdk::deleteShape(plCollisionWorldHandle /*worldHandle*/, plCollisionShapeHandle shapeHandle) { - btCollisionShape* shape = (btCollisionShape*) shapeHandle; + btCollisionShape* shape = (btCollisionShape*)shapeHandle; delete shape; } void Bullet2CollisionSdk::addCollisionObject(plCollisionWorldHandle worldHandle, plCollisionObjectHandle objectHandle) { - btCollisionWorld* world = (btCollisionWorld*) worldHandle; - btCollisionObject* colObj = (btCollisionObject*) objectHandle; - btAssert(world && colObj); + btCollisionWorld* world = (btCollisionWorld*)worldHandle; + btCollisionObject* colObj = (btCollisionObject*)objectHandle; + btAssert(world && colObj); if (world == m_internalData->m_collisionWorld && colObj) { world->addCollisionObject(colObj); @@ -141,101 +138,98 @@ void Bullet2CollisionSdk::addCollisionObject(plCollisionWorldHandle worldHandle, } void Bullet2CollisionSdk::removeCollisionObject(plCollisionWorldHandle worldHandle, plCollisionObjectHandle objectHandle) { - btCollisionWorld* world = (btCollisionWorld*) worldHandle; - btCollisionObject* colObj = (btCollisionObject*) objectHandle; - btAssert(world && colObj); + btCollisionWorld* world = (btCollisionWorld*)worldHandle; + btCollisionObject* colObj = (btCollisionObject*)objectHandle; + btAssert(world && colObj); if (world == m_internalData->m_collisionWorld && colObj) { world->removeCollisionObject(colObj); - } + } } -plCollisionObjectHandle Bullet2CollisionSdk::createCollisionObject( plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle shapeHandle , - plVector3 startPosition,plQuaternion startOrientation ) +plCollisionObjectHandle Bullet2CollisionSdk::createCollisionObject(plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle shapeHandle, + plVector3 startPosition, plQuaternion startOrientation) { - btCollisionShape* colShape = (btCollisionShape*) shapeHandle; + btCollisionShape* colShape = (btCollisionShape*)shapeHandle; btAssert(colShape); if (colShape) { - btCollisionObject* colObj= new btCollisionObject; + btCollisionObject* colObj = new btCollisionObject; colObj->setUserIndex(userIndex); colObj->setUserPointer(userPointer); colObj->setCollisionShape(colShape); - btTransform tr; - tr.setOrigin(btVector3(startPosition[0],startPosition[1],startPosition[2])); - tr.setRotation(btQuaternion(startOrientation[0],startOrientation[1],startOrientation[2],startOrientation[3])); + btTransform tr; + tr.setOrigin(btVector3(startPosition[0], startPosition[1], startPosition[2])); + tr.setRotation(btQuaternion(startOrientation[0], startOrientation[1], startOrientation[2], startOrientation[3])); colObj->setWorldTransform(tr); - return (plCollisionObjectHandle) colObj; + return (plCollisionObjectHandle)colObj; } return 0; } void Bullet2CollisionSdk::deleteCollisionObject(plCollisionObjectHandle bodyHandle) { - btCollisionObject* colObj = (btCollisionObject*) bodyHandle; + btCollisionObject* colObj = (btCollisionObject*)bodyHandle; delete colObj; } void Bullet2CollisionSdk::setCollisionObjectTransform(plCollisionWorldHandle /*worldHandle*/, plCollisionObjectHandle bodyHandle, - plVector3 position,plQuaternion orientation ) + plVector3 position, plQuaternion orientation) { - btCollisionObject* colObj = (btCollisionObject*) bodyHandle; - btTransform tr; - tr.setOrigin(btVector3(position[0],position[1],position[2])); - tr.setRotation(btQuaternion(orientation[0],orientation[1],orientation[2],orientation[3])); + btCollisionObject* colObj = (btCollisionObject*)bodyHandle; + btTransform tr; + tr.setOrigin(btVector3(position[0], position[1], position[2])); + tr.setRotation(btQuaternion(orientation[0], orientation[1], orientation[2], orientation[3])); colObj->setWorldTransform(tr); } - -struct Bullet2ContactResultCallback : public btCollisionWorld::ContactResultCallback +struct Bullet2ContactResultCallback : public btCollisionWorld::ContactResultCallback { - int m_numContacts; - lwContactPoint* m_pointsOut; - int m_pointCapacity; - - Bullet2ContactResultCallback(lwContactPoint* pointsOut, int pointCapacity) : - m_numContacts(0), - m_pointsOut(pointsOut), - m_pointCapacity(pointCapacity) - { - } - virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1) - { - if (m_numContactsm_collisionWorld && colObjA && colObjB) - { - Bullet2ContactResultCallback cb(pointsOut,pointCapacity); - world->contactPairTest(colObjA,colObjB,cb); - return cb.m_numContacts; - } - return 0; + btCollisionWorld* world = (btCollisionWorld*)worldHandle; + btCollisionObject* colObjA = (btCollisionObject*)colA; + btCollisionObject* colObjB = (btCollisionObject*)colB; + btAssert(world && colObjA && colObjB); + if (world == m_internalData->m_collisionWorld && colObjA && colObjB) + { + Bullet2ContactResultCallback cb(pointsOut, pointCapacity); + world->contactPairTest(colObjA, colObjB, cb); + return cb.m_numContacts; + } + return 0; } static plNearCallback gTmpFilter; @@ -247,30 +241,30 @@ static void* gUserData = 0; void Bullet2NearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo) { - btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject; - btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject; - plCollisionObjectHandle obA =(plCollisionObjectHandle) colObj0; - plCollisionObjectHandle obB =(plCollisionObjectHandle) colObj1; - if(gTmpFilter) - { - gTmpFilter(gCollisionSdk,gCollisionWorldHandle, gUserData,obA,obB); - gNearCallbackCount++; - } + btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject; + btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject; + plCollisionObjectHandle obA = (plCollisionObjectHandle)colObj0; + plCollisionObjectHandle obB = (plCollisionObjectHandle)colObj1; + if (gTmpFilter) + { + gTmpFilter(gCollisionSdk, gCollisionWorldHandle, gUserData, obA, obB); + gNearCallbackCount++; + } } -void Bullet2CollisionSdk::collideWorld( plCollisionWorldHandle worldHandle, - plNearCallback filter, void* userData) +void Bullet2CollisionSdk::collideWorld(plCollisionWorldHandle worldHandle, + plNearCallback filter, void* userData) { - btCollisionWorld* world = (btCollisionWorld*) worldHandle; - //chain the near-callback - gTmpFilter = filter; - gNearCallbackCount = 0; - gUserData = userData; - gCollisionSdk = (plCollisionSdkHandle)this; - gCollisionWorldHandle = worldHandle; - m_internalData->m_dispatcher->setNearCallback(Bullet2NearCallback); - world->performDiscreteCollisionDetection(); - gTmpFilter = 0; + btCollisionWorld* world = (btCollisionWorld*)worldHandle; + //chain the near-callback + gTmpFilter = filter; + gNearCallbackCount = 0; + gUserData = userData; + gCollisionSdk = (plCollisionSdkHandle)this; + gCollisionWorldHandle = worldHandle; + m_internalData->m_dispatcher->setNearCallback(Bullet2NearCallback); + world->performDiscreteCollisionDetection(); + gTmpFilter = 0; } plCollisionSdkHandle Bullet2CollisionSdk::createBullet2SdkHandle() diff --git a/examples/Collision/Internal/Bullet2CollisionSdk.h b/examples/Collision/Internal/Bullet2CollisionSdk.h index 9788d0444..ce46b0bad 100644 --- a/examples/Collision/Internal/Bullet2CollisionSdk.h +++ b/examples/Collision/Internal/Bullet2CollisionSdk.h @@ -6,51 +6,50 @@ class Bullet2CollisionSdk : public CollisionSdkInterface { struct Bullet2CollisionSdkInternalData* m_internalData; - + public: - Bullet2CollisionSdk(); - + virtual ~Bullet2CollisionSdk(); - + virtual plCollisionWorldHandle createCollisionWorld(int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity); - + virtual void deleteCollisionWorld(plCollisionWorldHandle worldHandle); virtual plCollisionShapeHandle createSphereShape(plCollisionWorldHandle worldHandle, plReal radius); - - virtual plCollisionShapeHandle createPlaneShape(plCollisionWorldHandle worldHandle, - plReal planeNormalX, - plReal planeNormalY, - plReal planeNormalZ, + + virtual plCollisionShapeHandle createPlaneShape(plCollisionWorldHandle worldHandle, + plReal planeNormalX, + plReal planeNormalY, + plReal planeNormalZ, plReal planeConstant); - virtual plCollisionShapeHandle createCapsuleShape(plCollisionWorldHandle worldHandle, - plReal radius, - plReal height, - int capsuleAxis); + virtual plCollisionShapeHandle createCapsuleShape(plCollisionWorldHandle worldHandle, + plReal radius, + plReal height, + int capsuleAxis); virtual plCollisionShapeHandle createCompoundShape(plCollisionWorldHandle worldHandle); - virtual void addChildShape(plCollisionWorldHandle worldHandle,plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape,plVector3 childPos,plQuaternion childOrn); + virtual void addChildShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape, plVector3 childPos, plQuaternion childOrn); virtual void deleteShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape); - + virtual void addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object); - virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object); - - virtual plCollisionObjectHandle createCollisionObject( plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape , - plVector3 startPosition,plQuaternion startOrientation ); - virtual void deleteCollisionObject(plCollisionObjectHandle body); + virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object); + + virtual plCollisionObjectHandle createCollisionObject(plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape, + plVector3 startPosition, plQuaternion startOrientation); + virtual void deleteCollisionObject(plCollisionObjectHandle body); virtual void setCollisionObjectTransform(plCollisionWorldHandle world, plCollisionObjectHandle body, - plVector3 position,plQuaternion orientation ); - - virtual int collide(plCollisionWorldHandle world,plCollisionObjectHandle colA, plCollisionObjectHandle colB, - lwContactPoint* pointsOut, int pointCapacity); - - virtual void collideWorld( plCollisionWorldHandle world, - plNearCallback filter, void* userData); + plVector3 position, plQuaternion orientation); + + virtual int collide(plCollisionWorldHandle world, plCollisionObjectHandle colA, plCollisionObjectHandle colB, + lwContactPoint* pointsOut, int pointCapacity); + + virtual void collideWorld(plCollisionWorldHandle world, + plNearCallback filter, void* userData); static plCollisionSdkHandle createBullet2SdkHandle(); }; -#endif //BULLET2_COLLISION_SDK_H +#endif //BULLET2_COLLISION_SDK_H diff --git a/examples/Collision/Internal/CollisionSdkInterface.h b/examples/Collision/Internal/CollisionSdkInterface.h index 8c3ab5f76..88c1d8af0 100644 --- a/examples/Collision/Internal/CollisionSdkInterface.h +++ b/examples/Collision/Internal/CollisionSdkInterface.h @@ -6,50 +6,46 @@ class CollisionSdkInterface { public: - virtual ~CollisionSdkInterface() { } - + virtual plCollisionWorldHandle createCollisionWorld(int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity) = 0; - + virtual void deleteCollisionWorld(plCollisionWorldHandle worldHandle) = 0; - + virtual plCollisionShapeHandle createSphereShape(plCollisionWorldHandle worldHandle, plReal radius) = 0; - virtual plCollisionShapeHandle createPlaneShape(plCollisionWorldHandle worldHandle, - plReal planeNormalX, - plReal planeNormalY, - plReal planeNormalZ, + virtual plCollisionShapeHandle createPlaneShape(plCollisionWorldHandle worldHandle, + plReal planeNormalX, + plReal planeNormalY, + plReal planeNormalZ, plReal planeConstant) = 0; - - virtual plCollisionShapeHandle createCapsuleShape(plCollisionWorldHandle worldHandle, - plReal radius, - plReal height, - int capsuleAxis) = 0; + + virtual plCollisionShapeHandle createCapsuleShape(plCollisionWorldHandle worldHandle, + plReal radius, + plReal height, + int capsuleAxis) = 0; virtual plCollisionShapeHandle createCompoundShape(plCollisionWorldHandle worldHandle) = 0; - virtual void addChildShape(plCollisionWorldHandle worldHandle,plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape,plVector3 childPos,plQuaternion childOrn)=0; + virtual void addChildShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape, plVector3 childPos, plQuaternion childOrn) = 0; virtual void deleteShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape) = 0; - - virtual void addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object)=0; - virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object)=0; - - virtual plCollisionObjectHandle createCollisionObject( plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape , - plVector3 startPosition,plQuaternion startOrientation )=0; - virtual void deleteCollisionObject(plCollisionObjectHandle body)=0; - virtual void setCollisionObjectTransform(plCollisionWorldHandle world, plCollisionObjectHandle body, - plVector3 position,plQuaternion orientation )=0; - - virtual int collide(plCollisionWorldHandle world,plCollisionObjectHandle colA, plCollisionObjectHandle colB, - lwContactPoint* pointsOut, int pointCapacity)=0; - - virtual void collideWorld( plCollisionWorldHandle world, - plNearCallback filter, void* userData)=0; - + virtual void addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object) = 0; + virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object) = 0; + + virtual plCollisionObjectHandle createCollisionObject(plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape, + plVector3 startPosition, plQuaternion startOrientation) = 0; + virtual void deleteCollisionObject(plCollisionObjectHandle body) = 0; + virtual void setCollisionObjectTransform(plCollisionWorldHandle world, plCollisionObjectHandle body, + plVector3 position, plQuaternion orientation) = 0; + + virtual int collide(plCollisionWorldHandle world, plCollisionObjectHandle colA, plCollisionObjectHandle colB, + lwContactPoint* pointsOut, int pointCapacity) = 0; + + virtual void collideWorld(plCollisionWorldHandle world, + plNearCallback filter, void* userData) = 0; }; -#endif //COLLISION_SDK_INTERFACE_H - +#endif //COLLISION_SDK_INTERFACE_H diff --git a/examples/Collision/Internal/RealTimeBullet3CollisionSdk.cpp b/examples/Collision/Internal/RealTimeBullet3CollisionSdk.cpp index 1c57c1af7..2ffff03e5 100644 --- a/examples/Collision/Internal/RealTimeBullet3CollisionSdk.cpp +++ b/examples/Collision/Internal/RealTimeBullet3CollisionSdk.cpp @@ -8,30 +8,27 @@ //convert the opaque pointer to int struct RTB3_ColliderOpaque2Int { - union - { - plCollisionObjectHandle m_ptrValue; - int m_intValue; - }; + union { + plCollisionObjectHandle m_ptrValue; + int m_intValue; + }; }; struct RTB3_ShapeOpaque2Int { - union - { - plCollisionShapeHandle m_ptrValue; - int m_intValue; - }; + union { + plCollisionShapeHandle m_ptrValue; + int m_intValue; + }; }; enum RTB3ShapeTypes { - RTB3_SHAPE_SPHERE=0, + RTB3_SHAPE_SPHERE = 0, RTB3_SHAPE_PLANE, RTB3_SHAPE_CAPSULE, MAX_NUM_SINGLE_SHAPE_TYPES, RTB3_SHAPE_COMPOUND_INTERNAL, - }; //we start at 1, so that the 0 index is 'invalid' just like a nullptr @@ -47,15 +44,14 @@ struct RTB3CollisionWorld b3AlignedObjectArray m_collidableTransforms; b3AlignedObjectArray m_collidables; - + b3AlignedObjectArray m_childShapes; - b3AlignedObjectArray m_localSpaceAabbs; - b3AlignedObjectArray m_worldSpaceAabbs; + b3AlignedObjectArray m_localSpaceAabbs; + b3AlignedObjectArray m_worldSpaceAabbs; b3AlignedObjectArray m_planeFaces; b3AlignedObjectArray m_compoundOverlappingPairs; - - union - { + + union { int m_nextFreeShapeIndex; void* m_nextFreeShapePtr; }; @@ -63,10 +59,9 @@ struct RTB3CollisionWorld int m_nextFreePlaneFaceIndex; RTB3CollisionWorld() - : - m_nextFreeShapeIndex(START_SHAPE_INDEX), - m_nextFreeCollidableIndex(START_COLLIDABLE_INDEX), - m_nextFreePlaneFaceIndex(0)//this value is never exposed to the user, so we can start from 0 + : m_nextFreeShapeIndex(START_SHAPE_INDEX), + m_nextFreeCollidableIndex(START_COLLIDABLE_INDEX), + m_nextFreePlaneFaceIndex(0) //this value is never exposed to the user, so we can start from 0 { } }; @@ -78,42 +73,42 @@ struct RealTimeBullet3CollisionSdkInternalData RealTimeBullet3CollisionSdk::RealTimeBullet3CollisionSdk() { -// int szCol = sizeof(b3Collidable); -// int szShap = sizeof(b3GpuChildShape); -// int szComPair = sizeof(b3CompoundOverlappingPair); + // int szCol = sizeof(b3Collidable); + // int szShap = sizeof(b3GpuChildShape); + // int szComPair = sizeof(b3CompoundOverlappingPair); m_internalData = new RealTimeBullet3CollisionSdkInternalData; } - + RealTimeBullet3CollisionSdk::~RealTimeBullet3CollisionSdk() { delete m_internalData; - m_internalData=0; + m_internalData = 0; } - + plCollisionWorldHandle RealTimeBullet3CollisionSdk::createCollisionWorld(int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity) { RTB3CollisionWorld* world = new RTB3CollisionWorld(); - world->m_collidables.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX); - world->m_collidablePositions.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX); - world->m_collidableOrientations.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX); - world->m_collidableTransforms.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX); - world->m_collidableUserPointers.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX); - world->m_collidableUserIndices.resize(maxNumObjsCapacity+START_COLLIDABLE_INDEX); - world->m_childShapes.resize(maxNumShapesCapacity+START_SHAPE_INDEX); + world->m_collidables.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX); + world->m_collidablePositions.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX); + world->m_collidableOrientations.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX); + world->m_collidableTransforms.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX); + world->m_collidableUserPointers.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX); + world->m_collidableUserIndices.resize(maxNumObjsCapacity + START_COLLIDABLE_INDEX); + world->m_childShapes.resize(maxNumShapesCapacity + START_SHAPE_INDEX); world->m_planeFaces.resize(maxNumShapesCapacity); - + world->m_compoundOverlappingPairs.resize(maxNumPairsCapacity); m_internalData->m_collisionWorlds.push_back(world); - return (plCollisionWorldHandle) world; + return (plCollisionWorldHandle)world; } - + void RealTimeBullet3CollisionSdk::deleteCollisionWorld(plCollisionWorldHandle worldHandle) { - RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle; + RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle; int loc = m_internalData->m_collisionWorlds.findLinearSearch(world); - b3Assert(loc >=0 && locm_collisionWorlds.size()); - if (loc >=0 && locm_collisionWorlds.size()) + b3Assert(loc >= 0 && loc < m_internalData->m_collisionWorlds.size()); + if (loc >= 0 && loc < m_internalData->m_collisionWorlds.size()) { m_internalData->m_collisionWorlds.remove(world); delete world; @@ -122,88 +117,87 @@ void RealTimeBullet3CollisionSdk::deleteCollisionWorld(plCollisionWorldHandle wo plCollisionShapeHandle RealTimeBullet3CollisionSdk::createSphereShape(plCollisionWorldHandle worldHandle, plReal radius) { - RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle; - b3Assert(world->m_nextFreeShapeIndexm_childShapes.size()); - if (world->m_nextFreeShapeIndexm_childShapes.size()) + RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle; + b3Assert(world->m_nextFreeShapeIndex < world->m_childShapes.size()); + if (world->m_nextFreeShapeIndex < world->m_childShapes.size()) { b3GpuChildShape& shape = world->m_childShapes[world->m_nextFreeShapeIndex]; shape.m_childPosition.setZero(); - shape.m_childOrientation.setValue(0,0,0,1); + shape.m_childOrientation.setValue(0, 0, 0, 1); shape.m_radius = radius; shape.m_shapeType = RTB3_SHAPE_SPHERE; world->m_nextFreeShapeIndex++; - return (plCollisionShapeHandle) world->m_nextFreeShapePtr; + return (plCollisionShapeHandle)world->m_nextFreeShapePtr; } return 0; } - -plCollisionShapeHandle RealTimeBullet3CollisionSdk::createPlaneShape(plCollisionWorldHandle worldHandle, - plReal planeNormalX, - plReal planeNormalY, - plReal planeNormalZ, - plReal planeConstant) + +plCollisionShapeHandle RealTimeBullet3CollisionSdk::createPlaneShape(plCollisionWorldHandle worldHandle, + plReal planeNormalX, + plReal planeNormalY, + plReal planeNormalZ, + plReal planeConstant) { - RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle; + RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle; b3Assert(world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size()); if (world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size()) { b3GpuChildShape& shape = world->m_childShapes[world->m_nextFreeShapeIndex]; shape.m_childPosition.setZero(); - shape.m_childOrientation.setValue(0,0,0,1); - world->m_planeFaces[world->m_nextFreePlaneFaceIndex].m_plane = b3MakeVector4(planeNormalX,planeNormalY,planeNormalZ,planeConstant); + shape.m_childOrientation.setValue(0, 0, 0, 1); + world->m_planeFaces[world->m_nextFreePlaneFaceIndex].m_plane = b3MakeVector4(planeNormalX, planeNormalY, planeNormalZ, planeConstant); shape.m_shapeIndex = world->m_nextFreePlaneFaceIndex++; shape.m_shapeType = RTB3_SHAPE_PLANE; world->m_nextFreeShapeIndex++; - return (plCollisionShapeHandle)world->m_nextFreeShapePtr ; + return (plCollisionShapeHandle)world->m_nextFreeShapePtr; } return 0; } -plCollisionShapeHandle RealTimeBullet3CollisionSdk::createCapsuleShape(plCollisionWorldHandle worldHandle, - plReal radius, - plReal height, - int capsuleAxis) +plCollisionShapeHandle RealTimeBullet3CollisionSdk::createCapsuleShape(plCollisionWorldHandle worldHandle, + plReal radius, + plReal height, + int capsuleAxis) { - RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle; + RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle; b3Assert(world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size()); if (world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size()) { b3GpuChildShape& shape = world->m_childShapes[world->m_nextFreeShapeIndex]; shape.m_childPosition.setZero(); - shape.m_childOrientation.setValue(0,0,0,1); + shape.m_childOrientation.setValue(0, 0, 0, 1); shape.m_radius = radius; shape.m_height = height; shape.m_shapeIndex = capsuleAxis; shape.m_shapeType = RTB3_SHAPE_CAPSULE; world->m_nextFreeShapeIndex++; - return (plCollisionShapeHandle) world->m_nextFreeShapePtr; + return (plCollisionShapeHandle)world->m_nextFreeShapePtr; } return 0; } plCollisionShapeHandle RealTimeBullet3CollisionSdk::createCompoundShape(plCollisionWorldHandle worldHandle) { - RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle; + RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle; b3Assert(world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size()); if (world->m_nextFreeShapeIndex < world->m_childShapes.size() && world->m_nextFreePlaneFaceIndex < world->m_planeFaces.size()) { b3GpuChildShape& shape = world->m_childShapes[world->m_nextFreeShapeIndex]; shape.m_childPosition.setZero(); - shape.m_childOrientation.setValue(0,0,0,1); + shape.m_childOrientation.setValue(0, 0, 0, 1); shape.m_numChildShapes = 0; shape.m_shapeType = RTB3_SHAPE_COMPOUND_INTERNAL; world->m_nextFreeShapeIndex++; - return (plCollisionShapeHandle) world->m_nextFreeShapePtr; + return (plCollisionShapeHandle)world->m_nextFreeShapePtr; } return 0; } -void RealTimeBullet3CollisionSdk::addChildShape(plCollisionWorldHandle worldHandle,plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape,plVector3 childPos,plQuaternion childOrn) +void RealTimeBullet3CollisionSdk::addChildShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape, plVector3 childPos, plQuaternion childOrn) { - } void RealTimeBullet3CollisionSdk::deleteShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape) { @@ -212,7 +206,7 @@ void RealTimeBullet3CollisionSdk::deleteShape(plCollisionWorldHandle worldHandle //this would be solved by one more in-direction, at some performance penalty for certain operations //for now, we don't delete and eventually run out-of-shapes } - + void RealTimeBullet3CollisionSdk::addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object) { ///createCollisionObject already adds it to the world @@ -222,46 +216,45 @@ void RealTimeBullet3CollisionSdk::removeCollisionObject(plCollisionWorldHandle w { ///todo, see deleteShape } - -plCollisionObjectHandle RealTimeBullet3CollisionSdk::createCollisionObject( plCollisionWorldHandle worldHandle, void* userPointer, - int userIndex, plCollisionShapeHandle shapeHandle , - plVector3 startPosition,plQuaternion startOrientation ) + +plCollisionObjectHandle RealTimeBullet3CollisionSdk::createCollisionObject(plCollisionWorldHandle worldHandle, void* userPointer, + int userIndex, plCollisionShapeHandle shapeHandle, + plVector3 startPosition, plQuaternion startOrientation) { - RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle; + RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle; b3Assert(world->m_nextFreeCollidableIndex < world->m_collidables.size()); if (world->m_nextFreeCollidableIndex < world->m_collidables.size()) { b3Collidable& collidable = world->m_collidables[world->m_nextFreeCollidableIndex]; - world->m_collidablePositions[world->m_nextFreeCollidableIndex].setValue(startPosition[0],startPosition[1],startPosition[2]); - world->m_collidableOrientations[world->m_nextFreeCollidableIndex].setValue(startOrientation[0],startOrientation[1],startOrientation[2],startOrientation[3]); + world->m_collidablePositions[world->m_nextFreeCollidableIndex].setValue(startPosition[0], startPosition[1], startPosition[2]); + world->m_collidableOrientations[world->m_nextFreeCollidableIndex].setValue(startOrientation[0], startOrientation[1], startOrientation[2], startOrientation[3]); world->m_collidableTransforms[world->m_nextFreeCollidableIndex].setOrigin(world->m_collidablePositions[world->m_nextFreeCollidableIndex]); world->m_collidableTransforms[world->m_nextFreeCollidableIndex].setRotation(world->m_collidableOrientations[world->m_nextFreeCollidableIndex]); world->m_collidableUserPointers[world->m_nextFreeCollidableIndex] = userPointer; world->m_collidableUserIndices[world->m_nextFreeCollidableIndex] = userIndex; - RTB3_ShapeOpaque2Int caster; - caster.m_ptrValue = shapeHandle; - int shapeIndex = caster.m_intValue; - collidable.m_shapeIndex = shapeIndex; + RTB3_ShapeOpaque2Int caster; + caster.m_ptrValue = shapeHandle; + int shapeIndex = caster.m_intValue; + collidable.m_shapeIndex = shapeIndex; b3GpuChildShape& shape = world->m_childShapes[shapeIndex]; collidable.m_shapeType = shape.m_shapeType; collidable.m_numChildShapes = 1; switch (collidable.m_shapeType) { - case RTB3_SHAPE_SPHERE: + case RTB3_SHAPE_SPHERE: { break; } - case RTB3_SHAPE_PLANE: + case RTB3_SHAPE_PLANE: { break; } - case RTB3_SHAPE_COMPOUND_INTERNAL: + case RTB3_SHAPE_COMPOUND_INTERNAL: { - break; } - default: + default: { b3Assert(0); } @@ -280,14 +273,14 @@ plCollisionObjectHandle RealTimeBullet3CollisionSdk::createCollisionObject( plC } return 0; } - + void RealTimeBullet3CollisionSdk::deleteCollisionObject(plCollisionObjectHandle body) { ///todo, see deleteShape } - + void RealTimeBullet3CollisionSdk::setCollisionObjectTransform(plCollisionWorldHandle world, plCollisionObjectHandle body, - plVector3 position,plQuaternion orientation ) + plVector3 position, plQuaternion orientation) { } @@ -298,159 +291,154 @@ struct plContactCache int numAddedPoints; }; -typedef void (*plDetectCollisionFunc)(RTB3CollisionWorld* world,int colA, int shapeIndexA, int colB, int shapeIndexB, - plContactCache* contactCache); +typedef void (*plDetectCollisionFunc)(RTB3CollisionWorld* world, int colA, int shapeIndexA, int colB, int shapeIndexB, + plContactCache* contactCache); -void detectCollisionDummy(RTB3CollisionWorld* world,int colA, int shapeIndexA, int colB, int shapeIndexB, - plContactCache* contactCache) +void detectCollisionDummy(RTB3CollisionWorld* world, int colA, int shapeIndexA, int colB, int shapeIndexB, + plContactCache* contactCache) { (void)world; - (void)colA,(void)colB; + (void)colA, (void)colB; (void)contactCache; } -void plVecCopy(float* dst,const b3Vector3& src) +void plVecCopy(float* dst, const b3Vector3& src) { dst[0] = src.x; dst[1] = src.y; dst[2] = src.z; } -void plVecCopy(double* dst,const b3Vector3& src) +void plVecCopy(double* dst, const b3Vector3& src) { - dst[0] = src.x; - dst[1] = src.y; - dst[2] = src.z; + dst[0] = src.x; + dst[1] = src.y; + dst[2] = src.z; } -void ComputeClosestPointsPlaneSphere(const b3Vector3& planeNormalWorld, b3Scalar planeConstant, const b3Vector3& spherePosWorld,b3Scalar sphereRadius, plContactCache* contactCache) +void ComputeClosestPointsPlaneSphere(const b3Vector3& planeNormalWorld, b3Scalar planeConstant, const b3Vector3& spherePosWorld, b3Scalar sphereRadius, plContactCache* contactCache) { if (contactCache->numAddedPoints < contactCache->pointCapacity) { lwContactPoint& pointOut = contactCache->pointsOut[contactCache->numAddedPoints]; - b3Scalar t = -(spherePosWorld.dot(-planeNormalWorld)+planeConstant); - b3Vector3 intersectionPoint = spherePosWorld+t*-planeNormalWorld; - b3Scalar distance = t-sphereRadius; - if (distance<=0) + b3Scalar t = -(spherePosWorld.dot(-planeNormalWorld) + planeConstant); + b3Vector3 intersectionPoint = spherePosWorld + t * -planeNormalWorld; + b3Scalar distance = t - sphereRadius; + if (distance <= 0) { pointOut.m_distance = distance; - plVecCopy(pointOut.m_ptOnBWorld,intersectionPoint); - plVecCopy(pointOut.m_ptOnAWorld,spherePosWorld+sphereRadius*-planeNormalWorld); - plVecCopy(pointOut.m_normalOnB,planeNormalWorld); + plVecCopy(pointOut.m_ptOnBWorld, intersectionPoint); + plVecCopy(pointOut.m_ptOnAWorld, spherePosWorld + sphereRadius * -planeNormalWorld); + plVecCopy(pointOut.m_normalOnB, planeNormalWorld); contactCache->numAddedPoints++; } } } -void ComputeClosestPointsSphereSphere(b3Scalar sphereARadius, const b3Vector3& sphereAPosWorld, b3Scalar sphereBRadius, const b3Vector3& sphereBPosWorld, plContactCache* contactCache) { - +void ComputeClosestPointsSphereSphere(b3Scalar sphereARadius, const b3Vector3& sphereAPosWorld, b3Scalar sphereBRadius, const b3Vector3& sphereBPosWorld, plContactCache* contactCache) +{ if (contactCache->numAddedPoints < contactCache->pointCapacity) { lwContactPoint& pointOut = contactCache->pointsOut[contactCache->numAddedPoints]; - b3Vector3 diff = sphereAPosWorld-sphereBPosWorld; + b3Vector3 diff = sphereAPosWorld - sphereBPosWorld; b3Scalar len = diff.length(); - pointOut.m_distance = len - (sphereARadius+sphereBRadius); - if (pointOut.m_distance<=0) + pointOut.m_distance = len - (sphereARadius + sphereBRadius); + if (pointOut.m_distance <= 0) { - b3Vector3 normOnB = b3MakeVector3(1,0,0); - if (len > B3_EPSILON) { + b3Vector3 normOnB = b3MakeVector3(1, 0, 0); + if (len > B3_EPSILON) + { normOnB = diff / len; } - - plVecCopy(pointOut.m_normalOnB,normOnB); - b3Vector3 ptAWorld = sphereAPosWorld - sphereARadius*normOnB; - plVecCopy(pointOut.m_ptOnAWorld,ptAWorld); - plVecCopy(pointOut.m_ptOnBWorld,ptAWorld-normOnB*pointOut.m_distance); - + + plVecCopy(pointOut.m_normalOnB, normOnB); + b3Vector3 ptAWorld = sphereAPosWorld - sphereARadius * normOnB; + plVecCopy(pointOut.m_ptOnAWorld, ptAWorld); + plVecCopy(pointOut.m_ptOnBWorld, ptAWorld - normOnB * pointOut.m_distance); + contactCache->numAddedPoints++; } } } -B3_FORCE_INLINE void detectCollisionSphereSphere(RTB3CollisionWorld* world,int colA, int shapeIndexA, int colB, int shapeIndexB, - plContactCache* contactCache) +B3_FORCE_INLINE void detectCollisionSphereSphere(RTB3CollisionWorld* world, int colA, int shapeIndexA, int colB, int shapeIndexB, + plContactCache* contactCache) { - const b3Scalar radiusA = world->m_childShapes[shapeIndexA].m_radius; const b3Scalar radiusB = world->m_childShapes[shapeIndexB].m_radius; - + const b3Transform& trA = world->m_collidableTransforms[colA]; const b3Vector3& sphereALocalPos = world->m_childShapes[shapeIndexA].m_childPosition; b3Vector3 spherePosAWorld = trA(sphereALocalPos); //b3Vector3 spherePosAWorld = b3QuatRotate( world->m_collidableOrientations[colA], sphereALocalPos ) + (world->m_collidablePositions[colA]); - + const b3Transform& trB = world->m_collidableTransforms[colB]; const b3Vector3& sphereBLocalPos = world->m_childShapes[shapeIndexB].m_childPosition; b3Vector3 spherePosBWorld = trB(sphereBLocalPos); //b3Vector3 spherePosBWorld = b3QuatRotate( world->m_collidableOrientations[colB], sphereBLocalPos ) + (world->m_collidablePositions[colB]); - ComputeClosestPointsSphereSphere(radiusA,spherePosAWorld,radiusB,spherePosBWorld,contactCache); + ComputeClosestPointsSphereSphere(radiusA, spherePosAWorld, radiusB, spherePosBWorld, contactCache); } -void detectCollisionSpherePlane(RTB3CollisionWorld* world,int colA, int shapeIndexA, int colB, int shapeIndexB, - plContactCache* contactCache) +void detectCollisionSpherePlane(RTB3CollisionWorld* world, int colA, int shapeIndexA, int colB, int shapeIndexB, + plContactCache* contactCache) { const b3Transform& trA = world->m_collidableTransforms[colA]; const b3Vector3& sphereALocalPos = world->m_childShapes[shapeIndexA].m_childPosition; b3Vector3 spherePosAWorld = trA(sphereALocalPos); - int planeFaceIndex = world->m_childShapes[shapeIndexB].m_shapeIndex; b3Vector3 planeNormal = world->m_planeFaces[planeFaceIndex].m_plane; b3Scalar planeConstant = planeNormal[3]; planeNormal[3] = 0.f; - - ComputeClosestPointsPlaneSphere(planeNormal, planeConstant, spherePosAWorld,world->m_childShapes[shapeIndexA].m_radius, contactCache); + ComputeClosestPointsPlaneSphere(planeNormal, planeConstant, spherePosAWorld, world->m_childShapes[shapeIndexA].m_radius, contactCache); } -void detectCollisionPlaneSphere(RTB3CollisionWorld* world,int colA, int shapeIndexA, int colB, int shapeIndexB, - plContactCache* contactCache) +void detectCollisionPlaneSphere(RTB3CollisionWorld* world, int colA, int shapeIndexA, int colB, int shapeIndexB, + plContactCache* contactCache) { (void)world; - (void)colA,(void)shapeIndexA,(void)colB,(void)shapeIndexB; + (void)colA, (void)shapeIndexA, (void)colB, (void)shapeIndexB; (void)contactCache; } - - #ifdef RTB3_SHAPE_CAPSULE -plDetectCollisionFunc funcTbl_detectCollision[MAX_NUM_SINGLE_SHAPE_TYPES,][MAX_NUM_SINGLE_SHAPE_TYPES,] = { - {detectCollisionSphereSphere ,detectCollisionSpherePlane ,detectCollisionSphereCapsule}, - {detectCollisionPlaneSphere ,detectCollisionDummy ,detectCollisionPlaneCapsule}, - {detectCollisionCapsuleSphere ,detectCollisionCapsulePlane ,detectCollisionCapsuleCapsule}, +plDetectCollisionFunc funcTbl_detectCollision[MAX_NUM_SINGLE_SHAPE_TYPES, ][MAX_NUM_SINGLE_SHAPE_TYPES, ] = { + {detectCollisionSphereSphere, detectCollisionSpherePlane, detectCollisionSphereCapsule}, + {detectCollisionPlaneSphere, detectCollisionDummy, detectCollisionPlaneCapsule}, + {detectCollisionCapsuleSphere, detectCollisionCapsulePlane, detectCollisionCapsuleCapsule}, }; #else plDetectCollisionFunc funcTbl_detectCollision[MAX_NUM_SINGLE_SHAPE_TYPES][MAX_NUM_SINGLE_SHAPE_TYPES] = { - {detectCollisionSphereSphere ,detectCollisionSpherePlane}, - {detectCollisionPlaneSphere ,detectCollisionDummy }, + {detectCollisionSphereSphere, detectCollisionSpherePlane}, + {detectCollisionPlaneSphere, detectCollisionDummy}, }; #endif -int RealTimeBullet3CollisionSdk::collide(plCollisionWorldHandle worldHandle,plCollisionObjectHandle colAHandle, plCollisionObjectHandle colBHandle, - lwContactPoint* pointsOutOrg, int pointCapacity) +int RealTimeBullet3CollisionSdk::collide(plCollisionWorldHandle worldHandle, plCollisionObjectHandle colAHandle, plCollisionObjectHandle colBHandle, + lwContactPoint* pointsOutOrg, int pointCapacity) { - - RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle; - RTB3_ColliderOpaque2Int caster; - caster.m_ptrValue =colAHandle; - int colAIndex = caster.m_intValue; - caster.m_ptrValue = colBHandle; - int colBIndex = caster.m_intValue; - const b3Collidable& colA = world->m_collidables[colAIndex]; + RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle; + RTB3_ColliderOpaque2Int caster; + caster.m_ptrValue = colAHandle; + int colAIndex = caster.m_intValue; + caster.m_ptrValue = colBHandle; + int colBIndex = caster.m_intValue; + const b3Collidable& colA = world->m_collidables[colAIndex]; const b3Collidable& colB = world->m_collidables[colBIndex]; plContactCache contactCache; contactCache.pointCapacity = pointCapacity; contactCache.pointsOut = pointsOutOrg; contactCache.numAddedPoints = 0; - - for (int i=0;im_childShapes[colA.m_shapeIndex+i].m_shapeType] // [world->m_childShapes[colB.m_shapeIndex+j].m_shapeType](world,colAIndex,colA.m_shapeIndex+i,colBIndex,colB.m_shapeIndex+j,&contactCache); @@ -462,25 +450,24 @@ int RealTimeBullet3CollisionSdk::collide(plCollisionWorldHandle worldHandle,plCo return 0; } -void RealTimeBullet3CollisionSdk::collideWorld( plCollisionWorldHandle worldHandle, - plNearCallback filter, void* userData) +void RealTimeBullet3CollisionSdk::collideWorld(plCollisionWorldHandle worldHandle, + plNearCallback filter, void* userData) { - RTB3CollisionWorld* world = (RTB3CollisionWorld*) worldHandle; + RTB3CollisionWorld* world = (RTB3CollisionWorld*)worldHandle; if (filter) { RTB3_ColliderOpaque2Int caster; plCollisionObjectHandle colA; plCollisionObjectHandle colB; - for (int i=START_COLLIDABLE_INDEX;im_nextFreeCollidableIndex;i++) + for (int i = START_COLLIDABLE_INDEX; i < world->m_nextFreeCollidableIndex; i++) { - - for (int j=i+1;jm_nextFreeCollidableIndex;j++) + for (int j = i + 1; j < world->m_nextFreeCollidableIndex; j++) { caster.m_intValue = i; - colA = caster.m_ptrValue; - caster.m_intValue = j; + colA = caster.m_ptrValue; + caster.m_intValue = j; colB = caster.m_ptrValue; - filter((plCollisionSdkHandle)this,worldHandle,userData,colA,colB); + filter((plCollisionSdkHandle)this, worldHandle, userData, colA, colB); } } } diff --git a/examples/Collision/Internal/RealTimeBullet3CollisionSdk.h b/examples/Collision/Internal/RealTimeBullet3CollisionSdk.h index 7e65bd8a1..76b4042e2 100644 --- a/examples/Collision/Internal/RealTimeBullet3CollisionSdk.h +++ b/examples/Collision/Internal/RealTimeBullet3CollisionSdk.h @@ -6,50 +6,48 @@ class RealTimeBullet3CollisionSdk : public CollisionSdkInterface { struct RealTimeBullet3CollisionSdkInternalData* m_internalData; - + public: - RealTimeBullet3CollisionSdk(); - + virtual ~RealTimeBullet3CollisionSdk(); - + virtual plCollisionWorldHandle createCollisionWorld(int maxNumObjsCapacity, int maxNumShapesCapacity, int maxNumPairsCapacity); - + virtual void deleteCollisionWorld(plCollisionWorldHandle worldHandle); virtual plCollisionShapeHandle createSphereShape(plCollisionWorldHandle worldHandle, plReal radius); - virtual plCollisionShapeHandle createPlaneShape(plCollisionWorldHandle worldHandle, - plReal planeNormalX, - plReal planeNormalY, - plReal planeNormalZ, + virtual plCollisionShapeHandle createPlaneShape(plCollisionWorldHandle worldHandle, + plReal planeNormalX, + plReal planeNormalY, + plReal planeNormalZ, plReal planeConstant); - virtual plCollisionShapeHandle createCapsuleShape(plCollisionWorldHandle worldHandle, - plReal radius, - plReal height, - int capsuleAxis); - + virtual plCollisionShapeHandle createCapsuleShape(plCollisionWorldHandle worldHandle, + plReal radius, + plReal height, + int capsuleAxis); + virtual plCollisionShapeHandle createCompoundShape(plCollisionWorldHandle worldHandle); - virtual void addChildShape(plCollisionWorldHandle worldHandle,plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape,plVector3 childPos,plQuaternion childOrn); + virtual void addChildShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle compoundShape, plCollisionShapeHandle childShape, plVector3 childPos, plQuaternion childOrn); virtual void deleteShape(plCollisionWorldHandle worldHandle, plCollisionShapeHandle shape); - + virtual void addCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object); - virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object); - - virtual plCollisionObjectHandle createCollisionObject( plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape , - plVector3 startPosition,plQuaternion startOrientation ); - virtual void deleteCollisionObject(plCollisionObjectHandle body); + virtual void removeCollisionObject(plCollisionWorldHandle world, plCollisionObjectHandle object); + + virtual plCollisionObjectHandle createCollisionObject(plCollisionWorldHandle worldHandle, void* userPointer, int userIndex, plCollisionShapeHandle cshape, + plVector3 startPosition, plQuaternion startOrientation); + virtual void deleteCollisionObject(plCollisionObjectHandle body); virtual void setCollisionObjectTransform(plCollisionWorldHandle world, plCollisionObjectHandle body, - plVector3 position,plQuaternion orientation ); - - virtual int collide(plCollisionWorldHandle world,plCollisionObjectHandle colA, plCollisionObjectHandle colB, - lwContactPoint* pointsOut, int pointCapacity); - - virtual void collideWorld( plCollisionWorldHandle world, - plNearCallback filter, void* userData); + plVector3 position, plQuaternion orientation); + + virtual int collide(plCollisionWorldHandle world, plCollisionObjectHandle colA, plCollisionObjectHandle colB, + lwContactPoint* pointsOut, int pointCapacity); + + virtual void collideWorld(plCollisionWorldHandle world, + plNearCallback filter, void* userData); static plCollisionSdkHandle createRealTimeBullet3CollisionSdkHandle(); }; - -#endif //REAL_TIME_COLLISION_SDK_H +#endif //REAL_TIME_COLLISION_SDK_H diff --git a/examples/CommonInterfaces/Common2dCanvasInterface.h b/examples/CommonInterfaces/Common2dCanvasInterface.h index b13dce97c..7d1e7f37d 100644 --- a/examples/CommonInterfaces/Common2dCanvasInterface.h +++ b/examples/CommonInterfaces/Common2dCanvasInterface.h @@ -4,14 +4,12 @@ struct Common2dCanvasInterface { virtual ~Common2dCanvasInterface() {} - virtual int createCanvas(const char* canvasName, int width, int height, int xPos, int yPos)=0; - virtual void destroyCanvas(int canvasId)=0; - virtual void setPixel(int canvasId, int x, int y, unsigned char red, unsigned char green,unsigned char blue, unsigned char alpha)=0; - virtual void getPixel(int canvasId, int x, int y, unsigned char& red, unsigned char& green,unsigned char& blue, unsigned char& alpha)=0; - - virtual void refreshImageData(int canvasId)=0; + virtual int createCanvas(const char* canvasName, int width, int height, int xPos, int yPos) = 0; + virtual void destroyCanvas(int canvasId) = 0; + virtual void setPixel(int canvasId, int x, int y, unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha) = 0; + virtual void getPixel(int canvasId, int x, int y, unsigned char& red, unsigned char& green, unsigned char& blue, unsigned char& alpha) = 0; + virtual void refreshImageData(int canvasId) = 0; }; -#endif //COMMON_2D_CANVAS_INTERFACE_H - +#endif //COMMON_2D_CANVAS_INTERFACE_H diff --git a/examples/CommonInterfaces/CommonCallbacks.h b/examples/CommonInterfaces/CommonCallbacks.h index 6310f0a6b..c11c28024 100644 --- a/examples/CommonInterfaces/CommonCallbacks.h +++ b/examples/CommonInterfaces/CommonCallbacks.h @@ -1,47 +1,46 @@ #ifndef COMMON_CALLBACKS_H #define COMMON_CALLBACKS_H - typedef void (*b3WheelCallback)(float deltax, float deltay); -typedef void (*b3ResizeCallback)( float width, float height); -typedef void (*b3MouseMoveCallback)( float x, float y); +typedef void (*b3ResizeCallback)(float width, float height); +typedef void (*b3MouseMoveCallback)(float x, float y); typedef void (*b3MouseButtonCallback)(int button, int state, float x, float y); typedef void (*b3KeyboardCallback)(int keycode, int state); -typedef void (*b3RenderCallback) (); +typedef void (*b3RenderCallback)(); -enum { - B3G_ESCAPE = 27, - B3G_F1 = 0xff00, - B3G_F2, - B3G_F3, - B3G_F4, - B3G_F5, - B3G_F6, - B3G_F7, - B3G_F8, - B3G_F9, - B3G_F10, - B3G_F11, - B3G_F12, - B3G_F13, - B3G_F14, - B3G_F15, - B3G_LEFT_ARROW, - B3G_RIGHT_ARROW, - B3G_UP_ARROW, - B3G_DOWN_ARROW, - B3G_PAGE_UP, - B3G_PAGE_DOWN, - B3G_END, - B3G_HOME, - B3G_INSERT, - B3G_DELETE, - B3G_BACKSPACE, - B3G_SHIFT, - B3G_CONTROL, - B3G_ALT, - B3G_RETURN +enum +{ + B3G_ESCAPE = 27, + B3G_F1 = 0xff00, + B3G_F2, + B3G_F3, + B3G_F4, + B3G_F5, + B3G_F6, + B3G_F7, + B3G_F8, + B3G_F9, + B3G_F10, + B3G_F11, + B3G_F12, + B3G_F13, + B3G_F14, + B3G_F15, + B3G_LEFT_ARROW, + B3G_RIGHT_ARROW, + B3G_UP_ARROW, + B3G_DOWN_ARROW, + B3G_PAGE_UP, + B3G_PAGE_DOWN, + B3G_END, + B3G_HOME, + B3G_INSERT, + B3G_DELETE, + B3G_BACKSPACE, + B3G_SHIFT, + B3G_CONTROL, + B3G_ALT, + B3G_RETURN }; #endif - diff --git a/examples/CommonInterfaces/CommonCameraInterface.h b/examples/CommonInterfaces/CommonCameraInterface.h index 87dc2f9d8..e0cfaa285 100644 --- a/examples/CommonInterfaces/CommonCameraInterface.h +++ b/examples/CommonInterfaces/CommonCameraInterface.h @@ -3,14 +3,14 @@ struct CommonCameraInterface { - virtual ~CommonCameraInterface(){} - virtual void getCameraProjectionMatrix(float m[16])const = 0; + virtual ~CommonCameraInterface() {} + virtual void getCameraProjectionMatrix(float m[16]) const = 0; virtual void getCameraViewMatrix(float m[16]) const = 0; - - virtual void setVRCamera(const float viewMat[16], const float projectionMatrix[16])=0; - virtual void disableVRCamera()=0; - virtual bool isVRCamera() const =0; - virtual void setVRCameraOffsetTransform(const float offset[16])=0; + + virtual void setVRCamera(const float viewMat[16], const float projectionMatrix[16]) = 0; + virtual void disableVRCamera() = 0; + virtual bool isVRCamera() const = 0; + virtual void setVRCameraOffsetTransform(const float offset[16]) = 0; virtual void getCameraTargetPosition(float pos[3]) const = 0; virtual void getCameraPosition(float pos[3]) const = 0; @@ -18,30 +18,29 @@ struct CommonCameraInterface virtual void getCameraTargetPosition(double pos[3]) const = 0; virtual void getCameraPosition(double pos[3]) const = 0; - virtual void setCameraTargetPosition(float x,float y,float z) = 0; - virtual void setCameraDistance(float dist) = 0; - virtual float getCameraDistance() const = 0; + virtual void setCameraTargetPosition(float x, float y, float z) = 0; + virtual void setCameraDistance(float dist) = 0; + virtual float getCameraDistance() const = 0; - virtual void setCameraUpVector(float x,float y, float z) = 0; - virtual void getCameraUpVector(float up[3]) const = 0; - virtual void getCameraForwardVector(float fwd[3]) const = 0; + virtual void setCameraUpVector(float x, float y, float z) = 0; + virtual void getCameraUpVector(float up[3]) const = 0; + virtual void getCameraForwardVector(float fwd[3]) const = 0; ///the setCameraUpAxis will call the 'setCameraUpVector' and 'setCameraForwardVector' - virtual void setCameraUpAxis(int axis) = 0; - virtual int getCameraUpAxis() const = 0; + virtual void setCameraUpAxis(int axis) = 0; + virtual int getCameraUpAxis() const = 0; - virtual void setCameraYaw(float yaw) = 0; - virtual float getCameraYaw() const = 0; - - virtual void setCameraPitch(float pitch) = 0; - virtual float getCameraPitch() const = 0; + virtual void setCameraYaw(float yaw) = 0; + virtual float getCameraYaw() const = 0; - virtual void setAspectRatio(float ratio) = 0; - virtual float getAspectRatio() const = 0; - - virtual float getCameraFrustumFar() const = 0; - virtual float getCameraFrustumNear() const = 0; + virtual void setCameraPitch(float pitch) = 0; + virtual float getCameraPitch() const = 0; + + virtual void setAspectRatio(float ratio) = 0; + virtual float getAspectRatio() const = 0; + + virtual float getCameraFrustumFar() const = 0; + virtual float getCameraFrustumNear() const = 0; }; -#endif //COMMON_CAMERA_INTERFACE_H - +#endif //COMMON_CAMERA_INTERFACE_H diff --git a/examples/CommonInterfaces/CommonExampleInterface.h b/examples/CommonInterfaces/CommonExampleInterface.h index 691e5dedf..fc4e05ce8 100644 --- a/examples/CommonInterfaces/CommonExampleInterface.h +++ b/examples/CommonInterfaces/CommonExampleInterface.h @@ -6,102 +6,91 @@ struct CommandProcessorCreationInterface { virtual ~CommandProcessorCreationInterface() {} - virtual class CommandProcessorInterface* createCommandProcessor()=0; - virtual void deleteCommandProcessor(CommandProcessorInterface*)=0; + virtual class CommandProcessorInterface* createCommandProcessor() = 0; + virtual void deleteCommandProcessor(CommandProcessorInterface*) = 0; }; - struct CommonExampleOptions { - struct GUIHelperInterface* m_guiHelper; + struct GUIHelperInterface* m_guiHelper; //Those are optional, some examples will use them others don't. Each example should work with them being 0. - int m_option; + int m_option; const char* m_fileName; class SharedMemoryInterface* m_sharedMem; CommandProcessorCreationInterface* m_commandProcessorCreation; - bool m_skipGraphicsUpdate; - - CommonExampleOptions(struct GUIHelperInterface* helper, int option=0) - :m_guiHelper(helper), - m_option(option), - m_fileName(0), - m_sharedMem(0), - m_commandProcessorCreation(0), - m_skipGraphicsUpdate(false) + bool m_skipGraphicsUpdate; + + CommonExampleOptions(struct GUIHelperInterface* helper, int option = 0) + : m_guiHelper(helper), + m_option(option), + m_fileName(0), + m_sharedMem(0), + m_commandProcessorCreation(0), + m_skipGraphicsUpdate(false) { } - }; class CommonExampleInterface { public: - - typedef class CommonExampleInterface* (CreateFunc)(CommonExampleOptions& options); + typedef class CommonExampleInterface*(CreateFunc)(CommonExampleOptions& options); virtual ~CommonExampleInterface() { } - - - virtual void initPhysics()=0; - virtual void exitPhysics()=0; - virtual void updateGraphics(){} - virtual void stepSimulation(float deltaTime)=0; - virtual void renderScene()=0; - virtual void physicsDebugDraw(int debugFlags)=0;//for now we reuse the flags in Bullet/src/LinearMath/btIDebugDraw.h + virtual void initPhysics() = 0; + virtual void exitPhysics() = 0; + virtual void updateGraphics() {} + virtual void stepSimulation(float deltaTime) = 0; + virtual void renderScene() = 0; + virtual void physicsDebugDraw(int debugFlags) = 0; //for now we reuse the flags in Bullet/src/LinearMath/btIDebugDraw.h //reset camera is only called when switching demo. this way you can restart (initPhysics) and watch in a specific location easier - virtual void resetCamera(){}; - virtual bool mouseMoveCallback(float x,float y)=0; - virtual bool mouseButtonCallback(int button, int state, float x, float y)=0; - virtual bool keyboardCallback(int key, int state)=0; + virtual void resetCamera(){}; + virtual bool mouseMoveCallback(float x, float y) = 0; + virtual bool mouseButtonCallback(int button, int state, float x, float y) = 0; + virtual bool keyboardCallback(int key, int state) = 0; - virtual void vrControllerMoveCallback(int controllerId, float pos[4], float orientation[4], float analogAxis, float auxAnalogAxes[10]) {} - virtual void vrControllerButtonCallback(int controllerId, int button, int state, float pos[4], float orientation[4]){} - virtual void vrHMDMoveCallback(int controllerId, float pos[4], float orientation[4]){} - virtual void vrGenericTrackerMoveCallback(int controllerId, float pos[4], float orientation[4]){} + virtual void vrControllerMoveCallback(int controllerId, float pos[4], float orientation[4], float analogAxis, float auxAnalogAxes[10]) {} + virtual void vrControllerButtonCallback(int controllerId, int button, int state, float pos[4], float orientation[4]) {} + virtual void vrHMDMoveCallback(int controllerId, float pos[4], float orientation[4]) {} + virtual void vrGenericTrackerMoveCallback(int controllerId, float pos[4], float orientation[4]) {} - virtual void processCommandLineArgs(int argc, char* argv[]){}; + virtual void processCommandLineArgs(int argc, char* argv[]){}; }; class ExampleEntries { - public: + virtual ~ExampleEntries() {} - virtual ~ExampleEntries() {} + virtual void initExampleEntries() = 0; + virtual void initOpenCLExampleEntries() = 0; - virtual void initExampleEntries()=0; + virtual int getNumRegisteredExamples() = 0; - virtual void initOpenCLExampleEntries()=0; + virtual CommonExampleInterface::CreateFunc* getExampleCreateFunc(int index) = 0; - virtual int getNumRegisteredExamples()=0; + virtual const char* getExampleName(int index) = 0; - virtual CommonExampleInterface::CreateFunc* getExampleCreateFunc(int index)=0; - - virtual const char* getExampleName(int index)=0; - - virtual const char* getExampleDescription(int index)=0; - - virtual int getExampleOption(int index)=0; + virtual const char* getExampleDescription(int index) = 0; + virtual int getExampleOption(int index) = 0; }; - CommonExampleInterface* StandaloneExampleCreateFunc(CommonExampleOptions& options); #ifdef B3_USE_STANDALONE_EXAMPLE - #define B3_STANDALONE_EXAMPLE(ExampleFunc) CommonExampleInterface* StandaloneExampleCreateFunc(CommonExampleOptions& options)\ - {\ - return ExampleFunc(options);\ +#define B3_STANDALONE_EXAMPLE(ExampleFunc) \ + CommonExampleInterface* StandaloneExampleCreateFunc(CommonExampleOptions& options) \ + { \ + return ExampleFunc(options); \ } -#else//B3_USE_STANDALONE_EXAMPLE - #define B3_STANDALONE_EXAMPLE(ExampleFunc) -#endif //B3_USE_STANDALONE_EXAMPLE +#else //B3_USE_STANDALONE_EXAMPLE +#define B3_STANDALONE_EXAMPLE(ExampleFunc) +#endif //B3_USE_STANDALONE_EXAMPLE - - -#endif //COMMON_EXAMPLE_INTERFACE_H +#endif //COMMON_EXAMPLE_INTERFACE_H diff --git a/examples/CommonInterfaces/CommonGUIHelperInterface.h b/examples/CommonInterfaces/CommonGUIHelperInterface.h index 5f24b4718..5e3478ec7 100644 --- a/examples/CommonInterfaces/CommonGUIHelperInterface.h +++ b/examples/CommonInterfaces/CommonGUIHelperInterface.h @@ -1,7 +1,6 @@ #ifndef GUI_HELPER_INTERFACE_H #define GUI_HELPER_INTERFACE_H - class btRigidBody; class btVector3; class btCollisionObject; @@ -12,8 +11,6 @@ struct CommonParameterInterface; struct CommonRenderInterface; struct CommonGraphicsApp; - - typedef void (*VisualizerFlagCallback)(int flag, bool enable); ///The Bullet 2 GraphicsPhysicsBridge let's the graphics engine create graphics representation and synchronize @@ -21,132 +18,129 @@ struct GUIHelperInterface { virtual ~GUIHelperInterface() {} - virtual void createRigidBodyGraphicsObject(btRigidBody* body,const btVector3& color) = 0; + virtual void createRigidBodyGraphicsObject(btRigidBody* body, const btVector3& color) = 0; - virtual void createCollisionObjectGraphicsObject(btCollisionObject* obj,const btVector3& color) = 0; + virtual void createCollisionObjectGraphicsObject(btCollisionObject* obj, const btVector3& color) = 0; - virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape)=0; + virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape) = 0; - virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld)=0; + virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld) = 0; - virtual void render(const btDiscreteDynamicsWorld* rbWorld)=0; + virtual void render(const btDiscreteDynamicsWorld* rbWorld) = 0; - virtual void createPhysicsDebugDrawer( btDiscreteDynamicsWorld* rbWorld)=0; + virtual void createPhysicsDebugDrawer(btDiscreteDynamicsWorld* rbWorld) = 0; - virtual int registerTexture(const unsigned char* texels, int width, int height)=0; - virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType, int textureId) = 0; - virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) =0; - virtual void removeAllGraphicsInstances()=0; + virtual int registerTexture(const unsigned char* texels, int width, int height) = 0; + virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices, int primitiveType, int textureId) = 0; + virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) = 0; + virtual void removeAllGraphicsInstances() = 0; virtual void removeGraphicsInstance(int graphicsUid) {} virtual void changeRGBAColor(int instanceUid, const double rgbaColor[4]) {} virtual void changeSpecularColor(int instanceUid, const double specularColor[3]) {} - virtual void changeTexture(int textureUniqueId, const unsigned char* rgbTexels, int width, int height){} + virtual void changeTexture(int textureUniqueId, const unsigned char* rgbTexels, int width, int height) {} - virtual int getShapeIndexFromInstance(int instanceUid){return -1;} - virtual void replaceTexture(int shapeIndex, int textureUid){} + virtual int getShapeIndexFromInstance(int instanceUid) { return -1; } + virtual void replaceTexture(int shapeIndex, int textureUid) {} virtual void removeTexture(int textureUid) {} - - - virtual Common2dCanvasInterface* get2dCanvasInterface()=0; - - virtual CommonParameterInterface* getParameterInterface()=0; - virtual CommonRenderInterface* getRenderInterface()=0; + virtual Common2dCanvasInterface* get2dCanvasInterface() = 0; + + virtual CommonParameterInterface* getParameterInterface() = 0; + + virtual CommonRenderInterface* getRenderInterface() = 0; virtual const CommonRenderInterface* getRenderInterface() const { return 0; } - virtual CommonGraphicsApp* getAppInterface()=0; + virtual CommonGraphicsApp* getAppInterface() = 0; - virtual void setUpAxis(int axis)=0; + virtual void setUpAxis(int axis) = 0; - virtual void resetCamera(float camDist, float yaw, float pitch, float camPosX,float camPosY, float camPosZ)=0; + virtual void resetCamera(float camDist, float yaw, float pitch, float camPosX, float camPosY, float camPosZ) = 0; - virtual bool getCameraInfo(int* width, int* height, float viewMatrix[16], float projectionMatrix[16], float camUp[3], float camForward[3],float hor[3], float vert[3], float* yaw, float* pitch, float* camDist, float camTarget[3]) const + virtual bool getCameraInfo(int* width, int* height, float viewMatrix[16], float projectionMatrix[16], float camUp[3], float camForward[3], float hor[3], float vert[3], float* yaw, float* pitch, float* camDist, float camTarget[3]) const { return false; } - virtual void setVisualizerFlag(int flag, int enable){}; - - virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16], - unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, - float* depthBuffer, int depthBufferSizeInPixels, - int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied) - { - copyCameraImageData(viewMatrix,projectionMatrix,pixelsRGBA,rgbaBufferSizeInPixels, - depthBuffer,depthBufferSizeInPixels, - 0,0, - startPixelIndex,destinationWidth, - destinationHeight,numPixelsCopied); - } + virtual void setVisualizerFlag(int flag, int enable){}; - virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16], - unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, - float* depthBuffer, int depthBufferSizeInPixels, - int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels, - int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied)=0; - virtual void debugDisplayCameraImageData(const float viewMatrix[16], const float projectionMatrix[16], - unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, - float* depthBuffer, int depthBufferSizeInPixels, - int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels, - int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied){} + virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16], + unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, + float* depthBuffer, int depthBufferSizeInPixels, + int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied) + { + copyCameraImageData(viewMatrix, projectionMatrix, pixelsRGBA, rgbaBufferSizeInPixels, + depthBuffer, depthBufferSizeInPixels, + 0, 0, + startPixelIndex, destinationWidth, + destinationHeight, numPixelsCopied); + } - virtual void setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16]){} - virtual void setProjectiveTexture(bool useProjectiveTexture){} + virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16], + unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, + float* depthBuffer, int depthBufferSizeInPixels, + int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels, + int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied) = 0; + virtual void debugDisplayCameraImageData(const float viewMatrix[16], const float projectionMatrix[16], + unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, + float* depthBuffer, int depthBufferSizeInPixels, + int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels, + int startPixelIndex, int destinationWidth, int destinationHeight, int* numPixelsCopied) {} - virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld) =0; - - virtual void drawText3D( const char* txt, float posX, float posY, float posZ, float size){} - virtual void drawText3D( const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag){} - - virtual int addUserDebugText3D( const char* txt, const double positionXYZ[3], const double orientation[4], const double textColorRGB[3], double size, double lifeTime, int trackingVisualShapeIndex, int optionFlags, int replaceItemUid){return -1;} - virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime , int trackingVisualShapeIndex, int replaceItemUid){return -1;}; - virtual int addUserDebugParameter(const char* txt, double rangeMin, double rangeMax, double startValue){return -1;}; - virtual int readUserDebugParameter(int itemUniqueId, double* value) { return 0;} + virtual void setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16]) {} + virtual void setProjectiveTexture(bool useProjectiveTexture) {} - virtual void removeUserDebugItem( int debugItemUniqueId){}; - virtual void removeAllUserDebugItems( ){}; - virtual void setVisualizerFlagCallback(VisualizerFlagCallback callback){} + virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld) = 0; + + virtual void drawText3D(const char* txt, float posX, float posY, float posZ, float size) {} + virtual void drawText3D(const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag) {} + + virtual int addUserDebugText3D(const char* txt, const double positionXYZ[3], const double orientation[4], const double textColorRGB[3], double size, double lifeTime, int trackingVisualShapeIndex, int optionFlags, int replaceItemUid) { return -1; } + virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime, int trackingVisualShapeIndex, int replaceItemUid) { return -1; }; + virtual int addUserDebugParameter(const char* txt, double rangeMin, double rangeMax, double startValue) { return -1; }; + virtual int readUserDebugParameter(int itemUniqueId, double* value) { return 0; } + + virtual void removeUserDebugItem(int debugItemUniqueId){}; + virtual void removeAllUserDebugItems(){}; + virtual void setVisualizerFlagCallback(VisualizerFlagCallback callback) {} //empty name stops dumping video - virtual void dumpFramesToVideo(const char* mp4FileName) {}; - + virtual void dumpFramesToVideo(const char* mp4FileName){}; }; - ///the DummyGUIHelper does nothing, so we can test the examples without GUI/graphics (in 'console mode') struct DummyGUIHelper : public GUIHelperInterface { DummyGUIHelper() {} virtual ~DummyGUIHelper() {} - virtual void createRigidBodyGraphicsObject(btRigidBody* body,const btVector3& color){} + virtual void createRigidBodyGraphicsObject(btRigidBody* body, const btVector3& color) {} - virtual void createCollisionObjectGraphicsObject(btCollisionObject* obj,const btVector3& color) {} + virtual void createCollisionObjectGraphicsObject(btCollisionObject* obj, const btVector3& color) {} - virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape){} + virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape) {} - virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld){} + virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld) {} virtual void render(const btDiscreteDynamicsWorld* rbWorld) {} - virtual void createPhysicsDebugDrawer( btDiscreteDynamicsWorld* rbWorld){} + virtual void createPhysicsDebugDrawer(btDiscreteDynamicsWorld* rbWorld) {} - virtual int registerTexture(const unsigned char* texels, int width, int height){return -1;} - virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType, int textureId){return -1;} - virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) {return -1;} - virtual void removeAllGraphicsInstances(){} - virtual void removeGraphicsInstance(int graphicsUid){} + virtual int registerTexture(const unsigned char* texels, int width, int height) { return -1; } + virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices, int primitiveType, int textureId) { return -1; } + virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) { return -1; } + virtual void removeAllGraphicsInstances() {} + virtual void removeGraphicsInstance(int graphicsUid) {} virtual void changeRGBAColor(int instanceUid, const double rgbaColor[4]) {} virtual Common2dCanvasInterface* get2dCanvasInterface() { return 0; } - + virtual CommonParameterInterface* getParameterInterface() { return 0; @@ -156,63 +150,60 @@ struct DummyGUIHelper : public GUIHelperInterface { return 0; } - + virtual CommonGraphicsApp* getAppInterface() { return 0; } - virtual void setUpAxis(int axis) { } - virtual void resetCamera(float camDist, float yaw, float pitch, float camPosX,float camPosY, float camPosZ) + virtual void resetCamera(float camDist, float yaw, float pitch, float camPosX, float camPosY, float camPosZ) { } - virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16], - unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, - float* depthBuffer, int depthBufferSizeInPixels, - int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels, - int startPixelIndex, int width, int height, int* numPixelsCopied) - + virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16], + unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, + float* depthBuffer, int depthBufferSizeInPixels, + int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels, + int startPixelIndex, int width, int height, int* numPixelsCopied) + { - if (numPixelsCopied) - *numPixelsCopied = 0; + if (numPixelsCopied) + *numPixelsCopied = 0; } - + virtual void setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16]) { } - + virtual void setProjectiveTexture(bool useProjectiveTexture) { } - virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld) - { - } - - virtual void drawText3D( const char* txt, float posX, float posZY, float posZ, float size) - { - } - - virtual void drawText3D( const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag) + virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld) { } - virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime , int trackingVisualShapeIndex, int replaceItemUid) + virtual void drawText3D(const char* txt, float posX, float posZY, float posZ, float size) + { + } + + virtual void drawText3D(const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag) + { + } + + virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime, int trackingVisualShapeIndex, int replaceItemUid) { return -1; } - virtual void removeUserDebugItem( int debugItemUniqueId) + virtual void removeUserDebugItem(int debugItemUniqueId) { } - virtual void removeAllUserDebugItems( ) + virtual void removeAllUserDebugItems() { } - }; -#endif //GUI_HELPER_INTERFACE_H - +#endif //GUI_HELPER_INTERFACE_H diff --git a/examples/CommonInterfaces/CommonGraphicsAppInterface.h b/examples/CommonInterfaces/CommonGraphicsAppInterface.h index 23118d1ac..96dde3a19 100644 --- a/examples/CommonInterfaces/CommonGraphicsAppInterface.h +++ b/examples/CommonInterfaces/CommonGraphicsAppInterface.h @@ -1,8 +1,6 @@ #ifndef COMMON_GRAPHICS_APP_H #define COMMON_GRAPHICS_APP_H - - #include "Bullet3Common/b3Vector3.h" #include "CommonRenderInterface.h" #include "CommonWindowInterface.h" @@ -10,26 +8,26 @@ struct DrawGridData { - int gridSize; - float upOffset; - int upAxis; - float gridColor[4]; + int gridSize; + float upOffset; + int upAxis; + float gridColor[4]; - DrawGridData(int upAxis=1) - :gridSize(10), - upOffset(0.001f), - upAxis(upAxis) - { - gridColor[0] = 0.6f; - gridColor[1] = 0.6f; - gridColor[2] = 0.6f; - gridColor[3] = 1.f; - } + DrawGridData(int upAxis = 1) + : gridSize(10), + upOffset(0.001f), + upAxis(upAxis) + { + gridColor[0] = 0.6f; + gridColor[1] = 0.6f; + gridColor[2] = 0.6f; + gridColor[3] = 1.f; + } }; enum EnumSphereLevelOfDetail { - SPHERE_LOD_POINT_SPRITE=0, + SPHERE_LOD_POINT_SPRITE = 0, SPHERE_LOD_LOW, SPHERE_LOD_MEDIUM, SPHERE_LOD_HIGH, @@ -39,38 +37,38 @@ struct CommonGraphicsApp { enum drawText3DOption { - eDrawText3D_OrtogonalFaceCamera=1, - eDrawText3D_TrueType=2, - eDrawText3D_TrackObject=4, + eDrawText3D_OrtogonalFaceCamera = 1, + eDrawText3D_TrueType = 2, + eDrawText3D_TrackObject = 4, }; - class CommonWindowInterface* m_window; - struct CommonRenderInterface* m_renderer; - struct CommonParameterInterface* m_parameterInterface; - struct Common2dCanvasInterface* m_2dCanvasInterface; + class CommonWindowInterface* m_window; + struct CommonRenderInterface* m_renderer; + struct CommonParameterInterface* m_parameterInterface; + struct Common2dCanvasInterface* m_2dCanvasInterface; - bool m_leftMouseButton; - bool m_middleMouseButton; - bool m_rightMouseButton; + bool m_leftMouseButton; + bool m_middleMouseButton; + bool m_rightMouseButton; float m_wheelMultiplier; float m_mouseMoveMultiplier; - float m_mouseXpos; - float m_mouseYpos; - bool m_mouseInitialized; - float m_backgroundColorRGB[3]; + float m_mouseXpos; + float m_mouseYpos; + bool m_mouseInitialized; + float m_backgroundColorRGB[3]; CommonGraphicsApp() - :m_window(0), - m_renderer(0), - m_parameterInterface(0), - m_2dCanvasInterface(0), - m_leftMouseButton(false), - m_middleMouseButton(false), - m_rightMouseButton(false), - m_wheelMultiplier(0.01f), - m_mouseMoveMultiplier(0.4f), - m_mouseXpos(0.f), - m_mouseYpos(0.f), - m_mouseInitialized(false) + : m_window(0), + m_renderer(0), + m_parameterInterface(0), + m_2dCanvasInterface(0), + m_leftMouseButton(false), + m_middleMouseButton(false), + m_rightMouseButton(false), + m_wheelMultiplier(0.01f), + m_mouseMoveMultiplier(0.4f), + m_mouseXpos(0.f), + m_mouseYpos(0.f), + m_mouseInitialized(false) { m_backgroundColorRGB[0] = 0.7; m_backgroundColorRGB[1] = 0.7; @@ -80,11 +78,11 @@ struct CommonGraphicsApp { } - virtual void dumpNextFrameToPng(const char* pngFilename){} - virtual void dumpFramesToVideo(const char* mp4Filename){} - - virtual void getScreenPixels(unsigned char* rgbaBuffer, int bufferSizeInBytes, float* depthBuffer, int depthBufferSizeInBytes){} - + virtual void dumpNextFrameToPng(const char* pngFilename) {} + virtual void dumpFramesToVideo(const char* mp4Filename) {} + + virtual void getScreenPixels(unsigned char* rgbaBuffer, int bufferSizeInBytes, float* depthBuffer, int depthBufferSizeInBytes) {} + virtual void getBackgroundColor(float* red, float* green, float* blue) const { if (red) @@ -113,190 +111,175 @@ struct CommonGraphicsApp { m_mouseMoveMultiplier = mult; } - + virtual float getMouseMoveMultiplier() const { return m_mouseMoveMultiplier; } - - - virtual void drawGrid(DrawGridData data=DrawGridData()) = 0; + virtual void drawGrid(DrawGridData data = DrawGridData()) = 0; virtual void setUpAxis(int axis) = 0; virtual int getUpAxis() const = 0; - + virtual void swapBuffer() = 0; - virtual void drawText( const char* txt, int posX, int posY) + virtual void drawText(const char* txt, int posX, int posY) { - float size=1; - float colorRGBA[4]={0,0,0,1}; - drawText(txt,posX,posY, size, colorRGBA); + float size = 1; + float colorRGBA[4] = {0, 0, 0, 1}; + drawText(txt, posX, posY, size, colorRGBA); } - virtual void drawText( const char* txt, int posX, int posY, float size) + virtual void drawText(const char* txt, int posX, int posY, float size) { - float colorRGBA[4]={0,0,0,1}; - drawText(txt,posX,posY,size,colorRGBA); + float colorRGBA[4] = {0, 0, 0, 1}; + drawText(txt, posX, posY, size, colorRGBA); } - virtual void drawText( const char* txt, int posX, int posY, float size, float colorRGBA[4]) = 0; - virtual void drawText3D( const char* txt, float posX, float posY, float posZ, float size)=0; - virtual void drawText3D( const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag)=0; - virtual void drawTexturedRect(float x0, float y0, float x1, float y1, float color[4], float u0,float v0, float u1, float v1, int useRGBA)=0; - virtual int registerCubeShape(float halfExtentsX,float halfExtentsY, float halfExtentsZ, int textureIndex = -1, float textureScaling = 1)=0; - virtual int registerGraphicsUnitSphereShape(EnumSphereLevelOfDetail lod, int textureId=-1) = 0; - + virtual void drawText(const char* txt, int posX, int posY, float size, float colorRGBA[4]) = 0; + virtual void drawText3D(const char* txt, float posX, float posY, float posZ, float size) = 0; + virtual void drawText3D(const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag) = 0; + virtual void drawTexturedRect(float x0, float y0, float x1, float y1, float color[4], float u0, float v0, float u1, float v1, int useRGBA) = 0; + virtual int registerCubeShape(float halfExtentsX, float halfExtentsY, float halfExtentsZ, int textureIndex = -1, float textureScaling = 1) = 0; + virtual int registerGraphicsUnitSphereShape(EnumSphereLevelOfDetail lod, int textureId = -1) = 0; - virtual void registerGrid(int xres, int yres, float color0[4], float color1[4])=0; + virtual void registerGrid(int xres, int yres, float color0[4], float color1[4]) = 0; - void defaultMouseButtonCallback( int button, int state, float x, float y) + void defaultMouseButtonCallback(int button, int state, float x, float y) { - if (button==0) - m_leftMouseButton= (state==1); - if (button==1) - m_middleMouseButton= (state==1); + if (button == 0) + m_leftMouseButton = (state == 1); + if (button == 1) + m_middleMouseButton = (state == 1); - if (button==2) - m_rightMouseButton= (state==1); + if (button == 2) + m_rightMouseButton = (state == 1); m_mouseXpos = x; m_mouseYpos = y; m_mouseInitialized = true; } - void defaultMouseMoveCallback( float x, float y) + void defaultMouseMoveCallback(float x, float y) { - if (m_window && m_renderer) { CommonCameraInterface* camera = m_renderer->getActiveCamera(); bool isAltPressed = m_window->isModifierKeyPressed(B3G_ALT); bool isControlPressed = m_window->isModifierKeyPressed(B3G_CONTROL); - - + if (isAltPressed || isControlPressed) { - float xDelta = x-m_mouseXpos; - float yDelta = y-m_mouseYpos; + float xDelta = x - m_mouseXpos; + float yDelta = y - m_mouseYpos; float cameraDistance = camera->getCameraDistance(); float pitch = camera->getCameraPitch(); float yaw = camera->getCameraYaw(); float targPos[3]; - float camPos[3]; + float camPos[3]; camera->getCameraTargetPosition(targPos); camera->getCameraPosition(camPos); - - b3Vector3 cameraPosition = b3MakeVector3(b3Scalar(camPos[0]), - b3Scalar(camPos[1]), - b3Scalar(camPos[2])); - b3Vector3 cameraTargetPosition = b3MakeVector3( b3Scalar(targPos[0]), - b3Scalar(targPos[1]), - b3Scalar(targPos[2])); - b3Vector3 cameraUp = b3MakeVector3(0,0,0); + b3Vector3 cameraPosition = b3MakeVector3(b3Scalar(camPos[0]), + b3Scalar(camPos[1]), + b3Scalar(camPos[2])); + + b3Vector3 cameraTargetPosition = b3MakeVector3(b3Scalar(targPos[0]), + b3Scalar(targPos[1]), + b3Scalar(targPos[2])); + b3Vector3 cameraUp = b3MakeVector3(0, 0, 0); cameraUp[camera->getCameraUpAxis()] = 1.f; - + if (m_leftMouseButton) { - // if (b3Fabs(xDelta)>b3Fabs(yDelta)) - // { - pitch -= yDelta*m_mouseMoveMultiplier; - // } else - // { - yaw -= xDelta*m_mouseMoveMultiplier; - // } + // if (b3Fabs(xDelta)>b3Fabs(yDelta)) + // { + pitch -= yDelta * m_mouseMoveMultiplier; + // } else + // { + yaw -= xDelta * m_mouseMoveMultiplier; + // } } if (m_middleMouseButton) { - cameraTargetPosition += cameraUp * yDelta*0.01; + cameraTargetPosition += cameraUp * yDelta * 0.01; - - b3Vector3 fwd = cameraTargetPosition-cameraPosition; + b3Vector3 fwd = cameraTargetPosition - cameraPosition; b3Vector3 side = cameraUp.cross(fwd); side.normalize(); - cameraTargetPosition += side * xDelta*0.01; - + cameraTargetPosition += side * xDelta * 0.01; } if (m_rightMouseButton) { - cameraDistance -= xDelta*0.01f; - cameraDistance -= yDelta*0.01f; - if (cameraDistance<1) - cameraDistance=1; - if (cameraDistance>1000) - cameraDistance=1000; + cameraDistance -= xDelta * 0.01f; + cameraDistance -= yDelta * 0.01f; + if (cameraDistance < 1) + cameraDistance = 1; + if (cameraDistance > 1000) + cameraDistance = 1000; } camera->setCameraDistance(cameraDistance); camera->setCameraPitch(pitch); camera->setCameraYaw(yaw); - camera->setCameraTargetPosition(cameraTargetPosition[0],cameraTargetPosition[1],cameraTargetPosition[2]); - - } + camera->setCameraTargetPosition(cameraTargetPosition[0], cameraTargetPosition[1], cameraTargetPosition[2]); + } + + } //m_window && m_renderer - }//m_window && m_renderer - m_mouseXpos = x; m_mouseYpos = y; m_mouseInitialized = true; } -// void defaultKeyboardCallback(int key, int state) -// { -// } - void defaultWheelCallback( float deltax, float deltay) + // void defaultKeyboardCallback(int key, int state) + // { + // } + void defaultWheelCallback(float deltax, float deltay) { - if (m_renderer) { - b3Vector3 cameraTargetPosition, cameraPosition, cameraUp = b3MakeVector3(0,0,0); + b3Vector3 cameraTargetPosition, cameraPosition, cameraUp = b3MakeVector3(0, 0, 0); cameraUp[getUpAxis()] = 1; CommonCameraInterface* camera = m_renderer->getActiveCamera(); - + camera->getCameraPosition(cameraPosition); camera->getCameraTargetPosition(cameraTargetPosition); - + if (!m_leftMouseButton) { - - float cameraDistance = camera->getCameraDistance(); - if (deltay<0 || cameraDistance>1) + float cameraDistance = camera->getCameraDistance(); + if (deltay < 0 || cameraDistance > 1) { - cameraDistance -= deltay*0.01f; - if (cameraDistance<1) - cameraDistance=1; + cameraDistance -= deltay * 0.01f; + if (cameraDistance < 1) + cameraDistance = 1; camera->setCameraDistance(cameraDistance); - - } else - { - - b3Vector3 fwd = cameraTargetPosition-cameraPosition; - fwd.normalize(); - cameraTargetPosition += fwd*deltay*m_wheelMultiplier;//todo: expose it in the GUI? } - } else - { - if (b3Fabs(deltax)>b3Fabs(deltay)) + else { - b3Vector3 fwd = cameraTargetPosition-cameraPosition; + b3Vector3 fwd = cameraTargetPosition - cameraPosition; + fwd.normalize(); + cameraTargetPosition += fwd * deltay * m_wheelMultiplier; //todo: expose it in the GUI? + } + } + else + { + if (b3Fabs(deltax) > b3Fabs(deltay)) + { + b3Vector3 fwd = cameraTargetPosition - cameraPosition; b3Vector3 side = cameraUp.cross(fwd); side.normalize(); - cameraTargetPosition += side * deltax*m_wheelMultiplier; - - } else + cameraTargetPosition += side * deltax * m_wheelMultiplier; + } + else { - cameraTargetPosition -= cameraUp * deltay*m_wheelMultiplier; - + cameraTargetPosition -= cameraUp * deltay * m_wheelMultiplier; } } - camera->setCameraTargetPosition(cameraTargetPosition[0],cameraTargetPosition[1],cameraTargetPosition[2]); + camera->setCameraTargetPosition(cameraTargetPosition[0], cameraTargetPosition[1], cameraTargetPosition[2]); } - } - - }; - -#endif //COMMON_GRAPHICS_APP_H +#endif //COMMON_GRAPHICS_APP_H diff --git a/examples/CommonInterfaces/CommonMultiBodyBase.h b/examples/CommonInterfaces/CommonMultiBodyBase.h index f18896566..7736f51a5 100644 --- a/examples/CommonInterfaces/CommonMultiBodyBase.h +++ b/examples/CommonInterfaces/CommonMultiBodyBase.h @@ -2,7 +2,6 @@ #ifndef COMMON_MULTI_BODY_SETUP_H #define COMMON_MULTI_BODY_SETUP_H - #include "btBulletDynamicsCommon.h" #include "BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h" @@ -20,32 +19,33 @@ enum MyFilterModes { - FILTER_GROUPAMASKB_AND_GROUPBMASKA2=0, + FILTER_GROUPAMASKB_AND_GROUPBMASKA2 = 0, FILTER_GROUPAMASKB_OR_GROUPBMASKA2 }; struct MyOverlapFilterCallback2 : public btOverlapFilterCallback { int m_filterMode; - + MyOverlapFilterCallback2() - :m_filterMode(FILTER_GROUPAMASKB_AND_GROUPBMASKA2) + : m_filterMode(FILTER_GROUPAMASKB_AND_GROUPBMASKA2) { } - + virtual ~MyOverlapFilterCallback2() - {} - // return true when pairs need collision - virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const { - if (m_filterMode==FILTER_GROUPAMASKB_AND_GROUPBMASKA2) + } + // return true when pairs need collision + virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) const + { + if (m_filterMode == FILTER_GROUPAMASKB_AND_GROUPBMASKA2) { bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); return collides; } - - if (m_filterMode==FILTER_GROUPAMASKB_OR_GROUPBMASKA2) + + if (m_filterMode == FILTER_GROUPAMASKB_OR_GROUPBMASKA2) { bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; collides = collides || (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); @@ -57,20 +57,20 @@ struct MyOverlapFilterCallback2 : public btOverlapFilterCallback struct CommonMultiBodyBase : public CommonExampleInterface { - //keep the collision shapes, for deletion/cleanup - btAlignedObjectArray m_collisionShapes; + //keep the collision shapes, for deletion/cleanup + btAlignedObjectArray m_collisionShapes; MyOverlapFilterCallback2* m_filterCallback; btOverlappingPairCache* m_pairCache; - btBroadphaseInterface* m_broadphase; - btCollisionDispatcher* m_dispatcher; - btMultiBodyConstraintSolver* m_solver; + btBroadphaseInterface* m_broadphase; + btCollisionDispatcher* m_dispatcher; + btMultiBodyConstraintSolver* m_solver; btDefaultCollisionConfiguration* m_collisionConfiguration; btMultiBodyDynamicsWorld* m_dynamicsWorld; //data for picking objects - class btRigidBody* m_pickedBody; + class btRigidBody* m_pickedBody; class btTypedConstraint* m_pickedConstraint; - class btMultiBodyPoint2Point* m_pickingMultiBodyPoint2Point; + class btMultiBodyPoint2Point* m_pickingMultiBodyPoint2Point; btVector3 m_oldPickingPos; btVector3 m_hitPos; @@ -80,18 +80,18 @@ struct CommonMultiBodyBase : public CommonExampleInterface struct GUIHelperInterface* m_guiHelper; CommonMultiBodyBase(GUIHelperInterface* helper) - :m_filterCallback(0), - m_pairCache(0), - m_broadphase(0), - m_dispatcher(0), - m_solver(0), - m_collisionConfiguration(0), - m_dynamicsWorld(0), - m_pickedBody(0), - m_pickedConstraint(0), - m_pickingMultiBodyPoint2Point(0), - m_prevCanSleep(false), - m_guiHelper(helper) + : m_filterCallback(0), + m_pairCache(0), + m_broadphase(0), + m_dispatcher(0), + m_solver(0), + m_collisionConfiguration(0), + m_dynamicsWorld(0), + m_pickedBody(0), + m_pickedConstraint(0), + m_pickingMultiBodyPoint2Point(0), + m_prevCanSleep(false), + m_guiHelper(helper) { } @@ -101,15 +101,15 @@ struct CommonMultiBodyBase : public CommonExampleInterface m_collisionConfiguration = new btDefaultCollisionConfiguration(); //m_collisionConfiguration->setConvexConvexMultipointIterations(); m_filterCallback = new MyOverlapFilterCallback2(); - + ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) - m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_pairCache = new btHashedOverlappingPairCache(); m_pairCache->setOverlapFilterCallback(m_filterCallback); - - m_broadphase = new btDbvtBroadphase(m_pairCache);//btSimpleBroadphase(); + + m_broadphase = new btDbvtBroadphase(m_pairCache); //btSimpleBroadphase(); m_solver = new btMultiBodyConstraintSolver; @@ -118,7 +118,6 @@ struct CommonMultiBodyBase : public CommonExampleInterface m_dynamicsWorld->setGravity(btVector3(0, -10, 0)); } - virtual void stepSimulation(float deltaTime) { if (m_dynamicsWorld) @@ -127,7 +126,6 @@ struct CommonMultiBodyBase : public CommonExampleInterface } } - virtual void exitPhysics() { removePickingConstraint(); @@ -137,13 +135,12 @@ struct CommonMultiBodyBase : public CommonExampleInterface if (m_dynamicsWorld) { + int i; + for (i = m_dynamicsWorld->getNumConstraints() - 1; i >= 0; i--) + { + m_dynamicsWorld->removeConstraint(m_dynamicsWorld->getConstraint(i)); + } - int i; - for (i = m_dynamicsWorld->getNumConstraints() - 1; i >= 0; i--) - { - m_dynamicsWorld->removeConstraint(m_dynamicsWorld->getConstraint(i)); - } - for (i = m_dynamicsWorld->getNumMultiBodyConstraints() - 1; i >= 0; i--) { btMultiBodyConstraint* mbc = m_dynamicsWorld->getMultiBodyConstraint(i); @@ -170,7 +167,7 @@ struct CommonMultiBodyBase : public CommonExampleInterface } } //delete collision shapes - for (int j = 0; jsyncPhysicsToGraphics(m_dynamicsWorld); + if (m_dynamicsWorld) + { + m_guiHelper->syncPhysicsToGraphics(m_dynamicsWorld); - m_guiHelper->render(m_dynamicsWorld); - } - + m_guiHelper->render(m_dynamicsWorld); + } } - virtual void physicsDebugDraw(int debugDrawFlags) - { - if (m_dynamicsWorld) - { + virtual void physicsDebugDraw(int debugDrawFlags) + { + if (m_dynamicsWorld) + { if (m_dynamicsWorld->getDebugDrawer()) { m_dynamicsWorld->getDebugDrawer()->setDebugMode(debugDrawFlags); } - m_dynamicsWorld->debugDrawWorld(); - } + m_dynamicsWorld->debugDrawWorld(); + } + } - } - - virtual bool keyboardCallback(int key, int state) + virtual bool keyboardCallback(int key, int state) { - if ((key==B3G_F3) && state && m_dynamicsWorld) + if ((key == B3G_F3) && state && m_dynamicsWorld) { - btDefaultSerializer* serializer = new btDefaultSerializer(); + btDefaultSerializer* serializer = new btDefaultSerializer(); m_dynamicsWorld->serialize(serializer); - FILE* file = fopen("testFile.bullet","wb"); - fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1, file); + FILE* file = fopen("testFile.bullet", "wb"); + fwrite(serializer->getBufferPointer(), serializer->getCurrentBufferSize(), 1, file); fclose(file); //b3Printf("btDefaultSerializer wrote testFile.bullet"); delete serializer; return true; - } - return false;//don't handle this key + return false; //don't handle this key } - - btVector3 getRayTo(int x,int y) + btVector3 getRayTo(int x, int y) { CommonRenderInterface* renderer = m_guiHelper->getRenderInterface(); - + if (!renderer) { btAssert(0); - return btVector3(0,0,0); + return btVector3(0, 0, 0); } float top = 1.f; float bottom = -1.f; float nearPlane = 1.f; - float tanFov = (top-bottom)*0.5f / nearPlane; + float tanFov = (top - bottom) * 0.5f / nearPlane; float fov = btScalar(2.0) * btAtan(tanFov); - btVector3 camPos,camTarget; + btVector3 camPos, camTarget; renderer->getActiveCamera()->getCameraPosition(camPos); renderer->getActiveCamera()->getCameraTargetPosition(camTarget); - btVector3 rayFrom = camPos; - btVector3 rayForward = (camTarget-camPos); + btVector3 rayFrom = camPos; + btVector3 rayForward = (camTarget - camPos); rayForward.normalize(); float farPlane = 10000.f; - rayForward*= farPlane; + rayForward *= farPlane; btVector3 rightOffset; - btVector3 cameraUp=btVector3(0,0,0); - cameraUp[m_guiHelper->getAppInterface()->getUpAxis()]=1; + btVector3 cameraUp = btVector3(0, 0, 0); + cameraUp[m_guiHelper->getAppInterface()->getUpAxis()] = 1; btVector3 vertical = cameraUp; @@ -288,25 +281,22 @@ struct CommonMultiBodyBase : public CommonExampleInterface vertical = hor.cross(rayForward); vertical.normalize(); - float tanfov = tanf(0.5f*fov); - + float tanfov = tanf(0.5f * fov); hor *= 2.f * farPlane * tanfov; vertical *= 2.f * farPlane * tanfov; btScalar aspect; float width = float(renderer->getScreenWidth()); - float height = float (renderer->getScreenHeight()); + float height = float(renderer->getScreenHeight()); - aspect = width / height; - - hor*=aspect; + aspect = width / height; + hor *= aspect; btVector3 rayToCenter = rayFrom + rayForward; - btVector3 dHor = hor * 1.f/width; - btVector3 dVert = vertical * 1.f/height; - + btVector3 dHor = hor * 1.f / width; + btVector3 dVert = vertical * 1.f / height; btVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical; rayTo += btScalar(x) * dHor; @@ -314,10 +304,10 @@ struct CommonMultiBodyBase : public CommonExampleInterface return rayTo; } - virtual bool mouseMoveCallback(float x,float y) + virtual bool mouseMoveCallback(float x, float y) { CommonRenderInterface* renderer = m_guiHelper->getRenderInterface(); - + if (!renderer) { btAssert(0); @@ -327,41 +317,39 @@ struct CommonMultiBodyBase : public CommonExampleInterface btVector3 rayTo = getRayTo(int(x), int(y)); btVector3 rayFrom; renderer->getActiveCamera()->getCameraPosition(rayFrom); - movePickedBody(rayFrom,rayTo); + movePickedBody(rayFrom, rayTo); return false; } - virtual bool mouseButtonCallback(int button, int state, float x, float y) + virtual bool mouseButtonCallback(int button, int state, float x, float y) { CommonRenderInterface* renderer = m_guiHelper->getRenderInterface(); - + if (!renderer) { btAssert(0); return false; } - + CommonWindowInterface* window = m_guiHelper->getAppInterface()->m_window; - - if (state==1) + if (state == 1) { - if(button==0 && (!window->isModifierKeyPressed(B3G_ALT) && !window->isModifierKeyPressed(B3G_CONTROL) )) + if (button == 0 && (!window->isModifierKeyPressed(B3G_ALT) && !window->isModifierKeyPressed(B3G_CONTROL))) { btVector3 camPos; renderer->getActiveCamera()->getCameraPosition(camPos); btVector3 rayFrom = camPos; - btVector3 rayTo = getRayTo(int(x),int(y)); + btVector3 rayTo = getRayTo(int(x), int(y)); pickBody(rayFrom, rayTo); - - } - } else + } + else { - if (button==0) + if (button == 0) { removePickingConstraint(); //remove p2p @@ -372,10 +360,9 @@ struct CommonMultiBodyBase : public CommonExampleInterface return false; } - virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld) { - if (m_dynamicsWorld==0) + if (m_dynamicsWorld == 0) return false; btCollisionWorld::ClosestRayResultCallback rayCallback(rayFromWorld, rayToWorld); @@ -383,7 +370,6 @@ struct CommonMultiBodyBase : public CommonExampleInterface m_dynamicsWorld->rayTest(rayFromWorld, rayToWorld, rayCallback); if (rayCallback.hasHit()) { - btVector3 pickPos = rayCallback.m_hitPointWorld; btRigidBody* body = (btRigidBody*)btRigidBody::upcast(rayCallback.m_collisionObject); if (body) @@ -403,33 +389,31 @@ struct CommonMultiBodyBase : public CommonExampleInterface //very weak constraint for picking p2p->m_setting.m_tau = 0.001f; } - } else + } + else { btMultiBodyLinkCollider* multiCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(rayCallback.m_collisionObject); if (multiCol && multiCol->m_multiBody) { - m_prevCanSleep = multiCol->m_multiBody->getCanSleep(); multiCol->m_multiBody->setCanSleep(false); btVector3 pivotInA = multiCol->m_multiBody->worldPosToLocal(multiCol->m_link, pickPos); - btMultiBodyPoint2Point* p2p = new btMultiBodyPoint2Point(multiCol->m_multiBody,multiCol->m_link,0,pivotInA,pickPos); + btMultiBodyPoint2Point* p2p = new btMultiBodyPoint2Point(multiCol->m_multiBody, multiCol->m_link, 0, pivotInA, pickPos); //if you add too much energy to the system, causing high angular velocities, simulation 'explodes' //see also http://www.bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=4&t=949 //so we try to avoid it by clamping the maximum impulse (force) that the mouse pick can apply //it is not satisfying, hopefully we find a better solution (higher order integrator, using joint friction using a zero-velocity target motor with limited force etc?) - btScalar scaling=1; - p2p->setMaxAppliedImpulse(2*scaling); - - btMultiBodyDynamicsWorld* world = (btMultiBodyDynamicsWorld*) m_dynamicsWorld; + btScalar scaling = 1; + p2p->setMaxAppliedImpulse(2 * scaling); + + btMultiBodyDynamicsWorld* world = (btMultiBodyDynamicsWorld*)m_dynamicsWorld; world->addMultiBodyConstraint(p2p); - m_pickingMultiBodyPoint2Point =p2p; + m_pickingMultiBodyPoint2Point = p2p; } } - - // pickObject(pickPos, rayCallback.m_collisionObject); m_oldPickingPos = rayToWorld; m_hitPos = pickPos; @@ -441,14 +425,14 @@ struct CommonMultiBodyBase : public CommonExampleInterface } virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld) { - if (m_pickedBody && m_pickedConstraint) + if (m_pickedBody && m_pickedConstraint) { btPoint2PointConstraint* pickCon = static_cast(m_pickedConstraint); if (pickCon) { //keep it at the same picking distance - - btVector3 dir = rayToWorld-rayFromWorld; + + btVector3 dir = rayToWorld - rayFromWorld; dir.normalize(); dir *= m_oldPickingDist; @@ -456,21 +440,20 @@ struct CommonMultiBodyBase : public CommonExampleInterface pickCon->setPivotB(newPivotB); } } - + if (m_pickingMultiBodyPoint2Point) { //keep it at the same picking distance - - btVector3 dir = rayToWorld-rayFromWorld; + btVector3 dir = rayToWorld - rayFromWorld; dir.normalize(); dir *= m_oldPickingDist; btVector3 newPivotB = rayFromWorld + dir; - + m_pickingMultiBodyPoint2Point->setPivotInB(newPivotB); } - + return false; } virtual void removePickingConstraint() @@ -491,22 +474,20 @@ struct CommonMultiBodyBase : public CommonExampleInterface if (m_pickingMultiBodyPoint2Point) { m_pickingMultiBodyPoint2Point->getMultiBodyA()->setCanSleep(m_prevCanSleep); - btMultiBodyDynamicsWorld* world = (btMultiBodyDynamicsWorld*) m_dynamicsWorld; + btMultiBodyDynamicsWorld* world = (btMultiBodyDynamicsWorld*)m_dynamicsWorld; world->removeMultiBodyConstraint(m_pickingMultiBodyPoint2Point); delete m_pickingMultiBodyPoint2Point; m_pickingMultiBodyPoint2Point = 0; } } - - btBoxShape* createBoxShape(const btVector3& halfExtents) { btBoxShape* box = new btBoxShape(halfExtents); return box; } - btRigidBody* createRigidBody(float mass, const btTransform& startTransform, btCollisionShape* shape, const btVector4& color = btVector4(1, 0, 0, 1)) + btRigidBody* createRigidBody(float mass, const btTransform& startTransform, btCollisionShape* shape, const btVector4& color = btVector4(1, 0, 0, 1)) { btAssert((!shape || shape->getShapeType() != INVALID_SHAPE_PROXYTYPE)); @@ -517,7 +498,7 @@ struct CommonMultiBodyBase : public CommonExampleInterface if (isDynamic) shape->calculateLocalInertia(mass, localInertia); - //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects #define USE_MOTIONSTATE 1 #ifdef USE_MOTIONSTATE @@ -531,7 +512,7 @@ struct CommonMultiBodyBase : public CommonExampleInterface #else btRigidBody* body = new btRigidBody(mass, 0, shape, localInertia); body->setWorldTransform(startTransform); -#endif// +#endif // body->setUserIndex(-1); m_dynamicsWorld->addRigidBody(body); @@ -539,5 +520,4 @@ struct CommonMultiBodyBase : public CommonExampleInterface } }; -#endif //COMMON_MULTI_BODY_SETUP_H - +#endif //COMMON_MULTI_BODY_SETUP_H diff --git a/examples/CommonInterfaces/CommonParameterInterface.h b/examples/CommonInterfaces/CommonParameterInterface.h index 214c07cd9..93edee89c 100644 --- a/examples/CommonInterfaces/CommonParameterInterface.h +++ b/examples/CommonInterfaces/CommonParameterInterface.h @@ -4,7 +4,7 @@ #pragma once -typedef void (*SliderParamChangedCallback) (float newVal, void* userPointer); +typedef void (*SliderParamChangedCallback)(float newVal, void* userPointer); #include "LinearMath/btScalar.h" struct SliderParams @@ -16,43 +16,42 @@ struct SliderParams btScalar* m_paramValuePointer; void* m_userPointer; bool m_clampToNotches; - bool m_clampToIntegers; - bool m_showValues; - + bool m_clampToIntegers; + bool m_showValues; + SliderParams(const char* name, btScalar* targetValuePointer) - :m_name(name), - m_minVal(-100), - m_maxVal(100), - m_callback(0), - m_paramValuePointer(targetValuePointer), - m_userPointer(0), - m_clampToNotches(false), - m_clampToIntegers(false), - m_showValues(true) + : m_name(name), + m_minVal(-100), + m_maxVal(100), + m_callback(0), + m_paramValuePointer(targetValuePointer), + m_userPointer(0), + m_clampToNotches(false), + m_clampToIntegers(false), + m_showValues(true) { } - }; -typedef void (*ButtonParamChangedCallback) (int buttonId, bool buttonState, void* userPointer); -typedef void (*ComboBoxCallback) (int combobox, const char* item, void* userPointer); +typedef void (*ButtonParamChangedCallback)(int buttonId, bool buttonState, void* userPointer); +typedef void (*ComboBoxCallback)(int combobox, const char* item, void* userPointer); struct ButtonParams { const char* m_name; int m_buttonId; void* m_userPointer; - bool m_isTrigger; - bool m_initialState; + bool m_isTrigger; + bool m_initialState; ButtonParamChangedCallback m_callback; ButtonParams(const char* name, int buttonId, bool isTrigger) - :m_name(name), - m_buttonId(buttonId), - m_userPointer(0), - m_isTrigger(isTrigger), - m_initialState(false), - m_callback(0) + : m_name(name), + m_buttonId(buttonId), + m_userPointer(0), + m_isTrigger(isTrigger), + m_initialState(false), + m_callback(0) { } }; @@ -64,32 +63,29 @@ struct ComboBoxParams const char** m_items; int m_startItem; ComboBoxCallback m_callback; - void* m_userPointer; + void* m_userPointer; ComboBoxParams() - :m_comboboxId(-1), - m_numItems(0), - m_items(0), - m_startItem(0), - m_callback(0), - m_userPointer(0) + : m_comboboxId(-1), + m_numItems(0), + m_items(0), + m_startItem(0), + m_callback(0), + m_userPointer(0) { } }; - struct CommonParameterInterface { - virtual ~CommonParameterInterface() {} - virtual void registerSliderFloatParameter(SliderParams& params)=0; - virtual void registerButtonParameter(ButtonParams& params)=0; - virtual void registerComboBox(ComboBoxParams& params)=0; - - virtual void syncParameters()=0; - virtual void removeAllParameters()=0; - virtual void setSliderValue(int sliderIndex, double sliderValue)=0; + virtual void registerSliderFloatParameter(SliderParams& params) = 0; + virtual void registerButtonParameter(ButtonParams& params) = 0; + virtual void registerComboBox(ComboBoxParams& params) = 0; + virtual void syncParameters() = 0; + virtual void removeAllParameters() = 0; + virtual void setSliderValue(int sliderIndex, double sliderValue) = 0; }; - -#endif //PARAM_INTERFACE_H + +#endif //PARAM_INTERFACE_H diff --git a/examples/CommonInterfaces/CommonRenderInterface.h b/examples/CommonInterfaces/CommonRenderInterface.h index 4401f96e7..830347c43 100644 --- a/examples/CommonInterfaces/CommonRenderInterface.h +++ b/examples/CommonInterfaces/CommonRenderInterface.h @@ -9,9 +9,9 @@ enum B3_GL_POINTS }; -enum +enum { - B3_DEFAULT_RENDERMODE=1, + B3_DEFAULT_RENDERMODE = 1, //B3_WIREFRAME_RENDERMODE, B3_CREATE_SHADOWMAP_RENDERMODE, B3_USE_SHADOWMAP_RENDERMODE, @@ -20,120 +20,117 @@ enum B3_USE_PROJECTIVE_TEXTURE_RENDERMODE, }; - struct GfxVertexFormat0 { - float x,y,z,w; - float unused0,unused1,unused2,unused3; - float u,v; + float x, y, z, w; + float unused0, unused1, unused2, unused3; + float u, v; }; struct GfxVertexFormat1 { - float x,y,z,w; - float nx,ny,nz; - float u,v; + float x, y, z, w; + float nx, ny, nz; + float u, v; }; - struct CommonRenderInterface { virtual ~CommonRenderInterface() {} - virtual void init()=0; - virtual void updateCamera(int upAxis)=0; + virtual void init() = 0; + virtual void updateCamera(int upAxis) = 0; virtual void removeAllInstances() = 0; virtual void removeGraphicsInstance(int instanceUid) = 0; - virtual const CommonCameraInterface* getActiveCamera() const =0; - virtual CommonCameraInterface* getActiveCamera()=0; - virtual void setActiveCamera(CommonCameraInterface* cam)=0; - + virtual const CommonCameraInterface* getActiveCamera() const = 0; + virtual CommonCameraInterface* getActiveCamera() = 0; + virtual void setActiveCamera(CommonCameraInterface* cam) = 0; + virtual void setLightPosition(const float lightPos[3]) = 0; virtual void setLightPosition(const double lightPos[3]) = 0; virtual void setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16]){}; virtual void setProjectiveTexture(bool useProjectiveTexture){}; - virtual void renderScene()=0; - virtual void renderSceneInternal(int renderMode=B3_DEFAULT_RENDERMODE){}; + virtual void renderScene() = 0; + virtual void renderSceneInternal(int renderMode = B3_DEFAULT_RENDERMODE){}; virtual int getScreenWidth() = 0; virtual int getScreenHeight() = 0; - virtual void resize(int width, int height) = 0; + virtual void resize(int width, int height) = 0; - virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling)=0; - virtual int registerGraphicsInstance(int shapeIndex, const double* position, const double* quaternion, const double* color, const double* scaling)=0; - virtual void drawLines(const float* positions, const float color[4], int numPoints, int pointStrideInBytes, const unsigned int* indices, int numIndices, float pointDrawSize)=0; + virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) = 0; + virtual int registerGraphicsInstance(int shapeIndex, const double* position, const double* quaternion, const double* color, const double* scaling) = 0; + virtual void drawLines(const float* positions, const float color[4], int numPoints, int pointStrideInBytes, const unsigned int* indices, int numIndices, float pointDrawSize) = 0; virtual void drawLine(const float from[4], const float to[4], const float color[4], float lineWidth) = 0; virtual void drawLine(const double from[4], const double to[4], const double color[4], double lineWidth) = 0; - virtual void drawPoint(const float* position, const float color[4], float pointDrawSize)=0; - virtual void drawPoint(const double* position, const double color[4], double pointDrawSize)=0; - virtual void drawTexturedTriangleMesh(float worldPosition[3], float worldOrientation[4], const float* vertices, int numvertices, const unsigned int* indices, int numIndices, float color[4], int textureIndex=-1, int vertexLayout=0)=0; + virtual void drawPoint(const float* position, const float color[4], float pointDrawSize) = 0; + virtual void drawPoint(const double* position, const double color[4], double pointDrawSize) = 0; + virtual void drawTexturedTriangleMesh(float worldPosition[3], float worldOrientation[4], const float* vertices, int numvertices, const unsigned int* indices, int numIndices, float color[4], int textureIndex = -1, int vertexLayout = 0) = 0; - virtual int registerShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType=B3_GL_TRIANGLES, int textureIndex=-1)=0; - virtual void updateShape(int shapeIndex, const float* vertices)=0; - - virtual int registerTexture(const unsigned char* texels, int width, int height, bool flipPixelsY=true)=0; - virtual void updateTexture(int textureIndex, const unsigned char* texels, bool flipPixelsY=true)=0; - virtual void activateTexture(int textureIndex)=0; + virtual int registerShape(const float* vertices, int numvertices, const int* indices, int numIndices, int primitiveType = B3_GL_TRIANGLES, int textureIndex = -1) = 0; + virtual void updateShape(int shapeIndex, const float* vertices) = 0; + + virtual int registerTexture(const unsigned char* texels, int width, int height, bool flipPixelsY = true) = 0; + virtual void updateTexture(int textureIndex, const unsigned char* texels, bool flipPixelsY = true) = 0; + virtual void activateTexture(int textureIndex) = 0; virtual void replaceTexture(int shapeIndex, int textureIndex){}; virtual void removeTexture(int textureIndex) = 0; virtual void setPlaneReflectionShapeIndex(int index) {} - virtual int getShapeIndexFromInstance(int srcIndex) {return -1;} + virtual int getShapeIndexFromInstance(int srcIndex) { return -1; } - virtual bool readSingleInstanceTransformToCPU(float* position, float* orientation, int srcIndex)=0; + virtual bool readSingleInstanceTransformToCPU(float* position, float* orientation, int srcIndex) = 0; - virtual void writeSingleInstanceTransformToCPU(const float* position, const float* orientation, int srcIndex)=0; - virtual void writeSingleInstanceTransformToCPU(const double* position, const double* orientation, int srcIndex)=0; - virtual void writeSingleInstanceColorToCPU(const float* color, int srcIndex)=0; - virtual void writeSingleInstanceColorToCPU(const double* color, int srcIndex)=0; - virtual void writeSingleInstanceScaleToCPU(const float* scale, int srcIndex)=0; - virtual void writeSingleInstanceScaleToCPU(const double* scale, int srcIndex)=0; - virtual void writeSingleInstanceSpecularColorToCPU(const double* specular, int srcIndex)=0; - virtual void writeSingleInstanceSpecularColorToCPU(const float* specular, int srcIndex)=0; - - - virtual int getTotalNumInstances() const = 0; - - virtual void writeTransforms()=0; - - virtual void clearZBuffer()=0; + virtual void writeSingleInstanceTransformToCPU(const float* position, const float* orientation, int srcIndex) = 0; + virtual void writeSingleInstanceTransformToCPU(const double* position, const double* orientation, int srcIndex) = 0; + virtual void writeSingleInstanceColorToCPU(const float* color, int srcIndex) = 0; + virtual void writeSingleInstanceColorToCPU(const double* color, int srcIndex) = 0; + virtual void writeSingleInstanceScaleToCPU(const float* scale, int srcIndex) = 0; + virtual void writeSingleInstanceScaleToCPU(const double* scale, int srcIndex) = 0; + virtual void writeSingleInstanceSpecularColorToCPU(const double* specular, int srcIndex) = 0; + virtual void writeSingleInstanceSpecularColorToCPU(const float* specular, int srcIndex) = 0; + + virtual int getTotalNumInstances() const = 0; + + virtual void writeTransforms() = 0; + + virtual void clearZBuffer() = 0; //This is internal access to OpenGL3+ features, mainly used for OpenCL-OpenGL interop //Only the GLInstancingRenderer supports it, just return 0 otherwise. - virtual struct GLInstanceRendererInternalData* getInternalData()=0; + virtual struct GLInstanceRendererInternalData* getInternalData() = 0; }; template inline int projectWorldCoordToScreen(T objx, T objy, T objz, - const T modelMatrix[16], - const T projMatrix[16], - const int viewport[4], - T *winx, T *winy, T *winz) + const T modelMatrix[16], + const T projMatrix[16], + const int viewport[4], + T* winx, T* winy, T* winz) { int i; T in2[4]; T tmp[4]; - in2[0]=objx; - in2[1]=objy; - in2[2]=objz; - in2[3]=T(1.0); + in2[0] = objx; + in2[1] = objy; + in2[2] = objz; + in2[3] = T(1.0); - for (i=0; i<4; i++) + for (i = 0; i < 4; i++) { - tmp[i] = in2[0] * modelMatrix[0*4+i] + in2[1] * modelMatrix[1*4+i] + - in2[2] * modelMatrix[2*4+i] + in2[3] * modelMatrix[3*4+i]; + tmp[i] = in2[0] * modelMatrix[0 * 4 + i] + in2[1] * modelMatrix[1 * 4 + i] + + in2[2] * modelMatrix[2 * 4 + i] + in2[3] * modelMatrix[3 * 4 + i]; } T out[4]; - for (i=0; i<4; i++) + for (i = 0; i < 4; i++) { - out[i] = tmp[0] * projMatrix[0*4+i] + tmp[1] * projMatrix[1*4+i] + tmp[2] * projMatrix[2*4+i] + tmp[3] * projMatrix[3*4+i]; + out[i] = tmp[0] * projMatrix[0 * 4 + i] + tmp[1] * projMatrix[1 * 4 + i] + tmp[2] * projMatrix[2 * 4 + i] + tmp[3] * projMatrix[3 * 4 + i]; } - if (out[3] == T(0.0)) + if (out[3] == T(0.0)) return 0; out[0] /= out[3]; out[1] /= out[3]; @@ -147,11 +144,10 @@ inline int projectWorldCoordToScreen(T objx, T objy, T objz, out[0] = out[0] * viewport[2] + viewport[0]; out[1] = out[1] * viewport[3] + viewport[1]; - *winx=out[0]; - *winy=out[1]; - *winz=out[2]; + *winx = out[0]; + *winy = out[1]; + *winz = out[2]; return 1; } -#endif//COMMON_RENDER_INTERFACE_H - +#endif //COMMON_RENDER_INTERFACE_H diff --git a/examples/CommonInterfaces/CommonRigidBodyBase.h b/examples/CommonInterfaces/CommonRigidBodyBase.h index 8bab88a9d..05e8f2504 100644 --- a/examples/CommonInterfaces/CommonRigidBodyBase.h +++ b/examples/CommonInterfaces/CommonRigidBodyBase.h @@ -2,7 +2,6 @@ #ifndef COMMON_RIGID_BODY_BASE_H #define COMMON_RIGID_BODY_BASE_H - #include "btBulletDynamicsCommon.h" #include "CommonExampleInterface.h" #include "CommonGUIHelperInterface.h" @@ -14,40 +13,39 @@ struct CommonRigidBodyBase : public CommonExampleInterface { - //keep the collision shapes, for deletion/cleanup - btAlignedObjectArray m_collisionShapes; - btBroadphaseInterface* m_broadphase; - btCollisionDispatcher* m_dispatcher; - btConstraintSolver* m_solver; + //keep the collision shapes, for deletion/cleanup + btAlignedObjectArray m_collisionShapes; + btBroadphaseInterface* m_broadphase; + btCollisionDispatcher* m_dispatcher; + btConstraintSolver* m_solver; btDefaultCollisionConfiguration* m_collisionConfiguration; btDiscreteDynamicsWorld* m_dynamicsWorld; //data for picking objects - class btRigidBody* m_pickedBody; + class btRigidBody* m_pickedBody; class btTypedConstraint* m_pickedConstraint; - int m_savedState; + int m_savedState; btVector3 m_oldPickingPos; btVector3 m_hitPos; btScalar m_oldPickingDist; struct GUIHelperInterface* m_guiHelper; CommonRigidBodyBase(struct GUIHelperInterface* helper) - :m_broadphase(0), - m_dispatcher(0), - m_solver(0), - m_collisionConfiguration(0), - m_dynamicsWorld(0), - m_pickedBody(0), - m_pickedConstraint(0), - m_guiHelper(helper) + : m_broadphase(0), + m_dispatcher(0), + m_solver(0), + m_collisionConfiguration(0), + m_dynamicsWorld(0), + m_pickedBody(0), + m_pickedConstraint(0), + m_guiHelper(helper) { } virtual ~CommonRigidBodyBase() { } - - btDiscreteDynamicsWorld* getDynamicsWorld() + btDiscreteDynamicsWorld* getDynamicsWorld() { return m_dynamicsWorld; } @@ -59,7 +57,7 @@ struct CommonRigidBodyBase : public CommonExampleInterface //m_collisionConfiguration->setConvexConvexMultipointIterations(); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) - m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_broadphase = new btDbvtBroadphase(); @@ -72,7 +70,6 @@ struct CommonRigidBodyBase : public CommonExampleInterface m_dynamicsWorld->setGravity(btVector3(0, -10, 0)); } - virtual void stepSimulation(float deltaTime) { if (m_dynamicsWorld) @@ -96,15 +93,14 @@ struct CommonRigidBodyBase : public CommonExampleInterface //cleanup in the reverse order of creation/initialization //remove the rigidbodies from the dynamics world and delete them - + if (m_dynamicsWorld) { - - int i; - for (i = m_dynamicsWorld->getNumConstraints() - 1; i >= 0; i--) - { - m_dynamicsWorld->removeConstraint(m_dynamicsWorld->getConstraint(i)); - } + int i; + for (i = m_dynamicsWorld->getNumConstraints() - 1; i >= 0; i--) + { + m_dynamicsWorld->removeConstraint(m_dynamicsWorld->getConstraint(i)); + } for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--) { btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; @@ -118,7 +114,7 @@ struct CommonRigidBodyBase : public CommonExampleInterface } } //delete collision shapes - for (int j = 0; jgetDebugDrawer()) { m_dynamicsWorld->getDebugDrawer()->setDebugMode(debugDrawFlags); } - m_dynamicsWorld->debugDrawWorld(); - } + m_dynamicsWorld->debugDrawWorld(); + } + } - } - - virtual bool keyboardCallback(int key, int state) + virtual bool keyboardCallback(int key, int state) { - if ((key==B3G_F3) && state && m_dynamicsWorld) + if ((key == B3G_F3) && state && m_dynamicsWorld) { - btDefaultSerializer* serializer = new btDefaultSerializer(); + btDefaultSerializer* serializer = new btDefaultSerializer(); m_dynamicsWorld->serialize(serializer); - FILE* file = fopen("testFile.bullet","wb"); - fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1, file); + FILE* file = fopen("testFile.bullet", "wb"); + fwrite(serializer->getBufferPointer(), serializer->getCurrentBufferSize(), 1, file); fclose(file); //b3Printf("btDefaultSerializer wrote testFile.bullet"); delete serializer; return true; - } - return false;//don't handle this key + return false; //don't handle this key } - - btVector3 getRayTo(int x,int y) + btVector3 getRayTo(int x, int y) { CommonRenderInterface* renderer = m_guiHelper->getRenderInterface(); - + if (!renderer) { btAssert(0); - return btVector3(0,0,0); + return btVector3(0, 0, 0); } float top = 1.f; float bottom = -1.f; float nearPlane = 1.f; - float tanFov = (top-bottom)*0.5f / nearPlane; + float tanFov = (top - bottom) * 0.5f / nearPlane; float fov = btScalar(2.0) * btAtan(tanFov); - btVector3 camPos,camTarget; - + btVector3 camPos, camTarget; + renderer->getActiveCamera()->getCameraPosition(camPos); renderer->getActiveCamera()->getCameraTargetPosition(camTarget); - btVector3 rayFrom = camPos; - btVector3 rayForward = (camTarget-camPos); + btVector3 rayFrom = camPos; + btVector3 rayForward = (camTarget - camPos); rayForward.normalize(); float farPlane = 10000.f; - rayForward*= farPlane; + rayForward *= farPlane; btVector3 rightOffset; - btVector3 cameraUp=btVector3(0,0,0); - cameraUp[m_guiHelper->getAppInterface()->getUpAxis()]=1; + btVector3 cameraUp = btVector3(0, 0, 0); + cameraUp[m_guiHelper->getAppInterface()->getUpAxis()] = 1; btVector3 vertical = cameraUp; @@ -213,25 +205,22 @@ struct CommonRigidBodyBase : public CommonExampleInterface vertical = hor.cross(rayForward); vertical.safeNormalize(); - float tanfov = tanf(0.5f*fov); - + float tanfov = tanf(0.5f * fov); hor *= 2.f * farPlane * tanfov; vertical *= 2.f * farPlane * tanfov; btScalar aspect; float width = float(renderer->getScreenWidth()); - float height = float (renderer->getScreenHeight()); + float height = float(renderer->getScreenHeight()); - aspect = width / height; - - hor*=aspect; + aspect = width / height; + hor *= aspect; btVector3 rayToCenter = rayFrom + rayForward; - btVector3 dHor = hor * 1.f/width; - btVector3 dVert = vertical * 1.f/height; - + btVector3 dHor = hor * 1.f / width; + btVector3 dVert = vertical * 1.f / height; btVector3 rayTo = rayToCenter - 0.5f * hor + 0.5f * vertical; rayTo += btScalar(x) * dHor; @@ -239,10 +228,10 @@ struct CommonRigidBodyBase : public CommonExampleInterface return rayTo; } - virtual bool mouseMoveCallback(float x,float y) + virtual bool mouseMoveCallback(float x, float y) { CommonRenderInterface* renderer = m_guiHelper->getRenderInterface(); - + if (!renderer) { btAssert(0); @@ -252,21 +241,21 @@ struct CommonRigidBodyBase : public CommonExampleInterface btVector3 rayTo = getRayTo(int(x), int(y)); btVector3 rayFrom; renderer->getActiveCamera()->getCameraPosition(rayFrom); - movePickedBody(rayFrom,rayTo); + movePickedBody(rayFrom, rayTo); return false; } - virtual bool mouseButtonCallback(int button, int state, float x, float y) + virtual bool mouseButtonCallback(int button, int state, float x, float y) { CommonRenderInterface* renderer = m_guiHelper->getRenderInterface(); - + if (!renderer) { btAssert(0); return false; } - + CommonWindowInterface* window = m_guiHelper->getAppInterface()->m_window; #if 0 @@ -294,25 +283,23 @@ struct CommonRigidBodyBase : public CommonExampleInterface printf("NO CONTROL pressed\n"); } #endif - - - if (state==1) + + if (state == 1) { - if(button==0 && (!window->isModifierKeyPressed(B3G_ALT) && !window->isModifierKeyPressed(B3G_CONTROL) )) + if (button == 0 && (!window->isModifierKeyPressed(B3G_ALT) && !window->isModifierKeyPressed(B3G_CONTROL))) { btVector3 camPos; renderer->getActiveCamera()->getCameraPosition(camPos); btVector3 rayFrom = camPos; - btVector3 rayTo = getRayTo(int(x),int(y)); + btVector3 rayTo = getRayTo(int(x), int(y)); pickBody(rayFrom, rayTo); - - } - } else + } + else { - if (button==0) + if (button == 0) { removePickingConstraint(); //remove p2p @@ -323,10 +310,9 @@ struct CommonRigidBodyBase : public CommonExampleInterface return false; } - virtual bool pickBody(const btVector3& rayFromWorld, const btVector3& rayToWorld) { - if (m_dynamicsWorld==0) + if (m_dynamicsWorld == 0) return false; btCollisionWorld::ClosestRayResultCallback rayCallback(rayFromWorld, rayToWorld); @@ -334,7 +320,6 @@ struct CommonRigidBodyBase : public CommonExampleInterface m_dynamicsWorld->rayTest(rayFromWorld, rayToWorld, rayCallback); if (rayCallback.hasHit()) { - btVector3 pickPos = rayCallback.m_hitPointWorld; btRigidBody* body = (btRigidBody*)btRigidBody::upcast(rayCallback.m_collisionObject); if (body) @@ -357,7 +342,6 @@ struct CommonRigidBodyBase : public CommonExampleInterface } } - // pickObject(pickPos, rayCallback.m_collisionObject); m_oldPickingPos = rayToWorld; m_hitPos = pickPos; @@ -369,7 +353,7 @@ struct CommonRigidBodyBase : public CommonExampleInterface } virtual bool movePickedBody(const btVector3& rayFromWorld, const btVector3& rayToWorld) { - if (m_pickedBody && m_pickedConstraint) + if (m_pickedBody && m_pickedConstraint) { btPoint2PointConstraint* pickCon = static_cast(m_pickedConstraint); if (pickCon) @@ -402,8 +386,6 @@ struct CommonRigidBodyBase : public CommonExampleInterface } } - - btBoxShape* createBoxShape(const btVector3& halfExtents) { btBoxShape* box = new btBoxShape(halfExtents); @@ -419,10 +401,9 @@ struct CommonRigidBodyBase : public CommonExampleInterface btMotionState* ms = body->getMotionState(); delete body; delete ms; - } - btRigidBody* createRigidBody(float mass, const btTransform& startTransform, btCollisionShape* shape, const btVector4& color = btVector4(1, 0, 0, 1)) + btRigidBody* createRigidBody(float mass, const btTransform& startTransform, btCollisionShape* shape, const btVector4& color = btVector4(1, 0, 0, 1)) { btAssert((!shape || shape->getShapeType() != INVALID_SHAPE_PROXYTYPE)); @@ -433,7 +414,7 @@ struct CommonRigidBodyBase : public CommonExampleInterface if (isDynamic) shape->calculateLocalInertia(mass, localInertia); - //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects #define USE_MOTIONSTATE 1 #ifdef USE_MOTIONSTATE @@ -447,28 +428,23 @@ struct CommonRigidBodyBase : public CommonExampleInterface #else btRigidBody* body = new btRigidBody(mass, 0, shape, localInertia); body->setWorldTransform(startTransform); -#endif// +#endif // body->setUserIndex(-1); m_dynamicsWorld->addRigidBody(body); return body; } - - virtual void renderScene() { { - m_guiHelper->syncPhysicsToGraphics(m_dynamicsWorld); } - + { - m_guiHelper->render(m_dynamicsWorld); } } }; -#endif //COMMON_RIGID_BODY_SETUP_H - +#endif //COMMON_RIGID_BODY_SETUP_H diff --git a/examples/CommonInterfaces/CommonWindowInterface.h b/examples/CommonInterfaces/CommonWindowInterface.h index 97c7dde16..ce212f64d 100644 --- a/examples/CommonInterfaces/CommonWindowInterface.h +++ b/examples/CommonInterfaces/CommonWindowInterface.h @@ -3,91 +3,86 @@ #include "CommonCallbacks.h" - struct b3gWindowConstructionInfo { - int m_width; - int m_height; - bool m_fullscreen; - int m_colorBitsPerPixel; - void* m_windowHandle; - const char* m_title; - int m_openglVersion; - int m_renderDevice; - + int m_width; + int m_height; + bool m_fullscreen; + int m_colorBitsPerPixel; + void* m_windowHandle; + const char* m_title; + int m_openglVersion; + int m_renderDevice; - b3gWindowConstructionInfo(int width=1024, int height=768) - :m_width(width), - m_height(height), - m_fullscreen(false), - m_colorBitsPerPixel(32), - m_windowHandle(0), - m_title("title"), - m_openglVersion(3), - m_renderDevice(-1) - { - } + b3gWindowConstructionInfo(int width = 1024, int height = 768) + : m_width(width), + m_height(height), + m_fullscreen(false), + m_colorBitsPerPixel(32), + m_windowHandle(0), + m_title("title"), + m_openglVersion(3), + m_renderDevice(-1) + { + } }; - class CommonWindowInterface { - public: - - virtual ~CommonWindowInterface() - { - } +public: + virtual ~CommonWindowInterface() + { + } - virtual void createDefaultWindow(int width, int height, const char* title) - { - b3gWindowConstructionInfo ci(width,height); - ci.m_title = title; - createWindow(ci); - } + virtual void createDefaultWindow(int width, int height, const char* title) + { + b3gWindowConstructionInfo ci(width, height); + ci.m_title = title; + createWindow(ci); + } - virtual void createWindow(const b3gWindowConstructionInfo& ci)=0; - - virtual void closeWindow()=0; + virtual void createWindow(const b3gWindowConstructionInfo& ci) = 0; - virtual void runMainLoop()=0; - virtual float getTimeInSeconds()=0; + virtual void closeWindow() = 0; - virtual bool requestedExit() const = 0; - virtual void setRequestExit() = 0; + virtual void runMainLoop() = 0; + virtual float getTimeInSeconds() = 0; - virtual void startRendering()=0; + virtual bool requestedExit() const = 0; + virtual void setRequestExit() = 0; - virtual void endRendering()=0; + virtual void startRendering() = 0; - virtual bool isModifierKeyPressed(int key) = 0; - - virtual void setMouseMoveCallback(b3MouseMoveCallback mouseCallback)=0; - virtual b3MouseMoveCallback getMouseMoveCallback()=0; - - virtual void setMouseButtonCallback(b3MouseButtonCallback mouseCallback)=0; - virtual b3MouseButtonCallback getMouseButtonCallback()=0; + virtual void endRendering() = 0; - virtual void setResizeCallback(b3ResizeCallback resizeCallback)=0; - virtual b3ResizeCallback getResizeCallback()=0; - - virtual void setWheelCallback(b3WheelCallback wheelCallback)=0; - virtual b3WheelCallback getWheelCallback()=0; - - virtual void setKeyboardCallback( b3KeyboardCallback keyboardCallback)=0; - virtual b3KeyboardCallback getKeyboardCallback()=0; + virtual bool isModifierKeyPressed(int key) = 0; - virtual void setRenderCallback( b3RenderCallback renderCallback) = 0; - - virtual void setWindowTitle(const char* title)=0; + virtual void setMouseMoveCallback(b3MouseMoveCallback mouseCallback) = 0; + virtual b3MouseMoveCallback getMouseMoveCallback() = 0; - virtual float getRetinaScale() const =0; - virtual void setAllowRetina(bool allow) =0; + virtual void setMouseButtonCallback(b3MouseButtonCallback mouseCallback) = 0; + virtual b3MouseButtonCallback getMouseButtonCallback() = 0; - virtual int getWidth() const = 0; - virtual int getHeight() const = 0; + virtual void setResizeCallback(b3ResizeCallback resizeCallback) = 0; + virtual b3ResizeCallback getResizeCallback() = 0; - virtual int fileOpenDialog(char* fileName, int maxFileNameLength) = 0; - + virtual void setWheelCallback(b3WheelCallback wheelCallback) = 0; + virtual b3WheelCallback getWheelCallback() = 0; + + virtual void setKeyboardCallback(b3KeyboardCallback keyboardCallback) = 0; + virtual b3KeyboardCallback getKeyboardCallback() = 0; + + virtual void setRenderCallback(b3RenderCallback renderCallback) = 0; + + virtual void setWindowTitle(const char* title) = 0; + + virtual float getRetinaScale() const = 0; + virtual void setAllowRetina(bool allow) = 0; + + virtual int getWidth() const = 0; + virtual int getHeight() const = 0; + + virtual int fileOpenDialog(char* fileName, int maxFileNameLength) = 0; }; -#endif //B3G_WINDOW_INTERFACE_H +#endif //B3G_WINDOW_INTERFACE_H diff --git a/examples/Constraints/ConstraintDemo.cpp b/examples/Constraints/ConstraintDemo.cpp index cf7dc063d..e609c36fd 100644 --- a/examples/Constraints/ConstraintDemo.cpp +++ b/examples/Constraints/ConstraintDemo.cpp @@ -13,60 +13,47 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "ConstraintDemo.h" #include "btBulletDynamicsCommon.h" #include "LinearMath/btIDebugDraw.h" -#include //printf debugging - +#include //printf debugging #include "../CommonInterfaces/CommonRigidBodyBase.h" - - - - ///AllConstraintDemo shows how to create a constraint, like Hinge or btGenericD6constraint -class AllConstraintDemo : public CommonRigidBodyBase +class AllConstraintDemo : public CommonRigidBodyBase { //keep track of variables to delete memory at the end - - void setupEmptyDynamicsWorld(); - - public: + void setupEmptyDynamicsWorld(); +public: AllConstraintDemo(struct GUIHelperInterface* helper); virtual ~AllConstraintDemo(); - virtual void initPhysics(); + virtual void initPhysics(); - virtual void exitPhysics(); + virtual void exitPhysics(); virtual void resetCamera() { float dist = 27; float pitch = -30; float yaw = 720; - float targetPos[3]={2,0,-10}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {2, 0, -10}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } - virtual bool keyboardCallback(int key, int state); + virtual bool keyboardCallback(int key, int state); // for cone-twist motor driving float m_Time; class btConeTwistConstraint* m_ctc; - }; - - - #define ENABLE_ALL_DEMOS 1 #define CUBE_HALF_EXTENTS 1.f @@ -74,14 +61,11 @@ class AllConstraintDemo : public CommonRigidBodyBase #define SIMD_PI_2 ((SIMD_PI)*0.5f) #define SIMD_PI_4 ((SIMD_PI)*0.25f) - - - btTransform sliderTransform; -btVector3 lowerSliderLimit = btVector3(-10,0,0); -btVector3 hiSliderLimit = btVector3(10,0,0); +btVector3 lowerSliderLimit = btVector3(-10, 0, 0); +btVector3 hiSliderLimit = btVector3(10, 0, 0); -btRigidBody* d6body0 =0; +btRigidBody* d6body0 = 0; btHingeConstraint* spDoorHinge = NULL; btHingeConstraint* spHingeDynAB = NULL; @@ -89,22 +73,16 @@ btGeneric6DofConstraint* spSlider6Dof = NULL; static bool s_bTestConeTwistMotor = false; - - - - -void AllConstraintDemo::setupEmptyDynamicsWorld() +void AllConstraintDemo::setupEmptyDynamicsWorld() { m_collisionConfiguration = new btDefaultCollisionConfiguration(); m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_broadphase = new btDbvtBroadphase(); m_solver = new btSequentialImpulseConstraintSolver(); - m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); - + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration); } - -void AllConstraintDemo::initPhysics() +void AllConstraintDemo::initPhysics() { m_guiHelper->setUpAxis(1); @@ -115,223 +93,210 @@ void AllConstraintDemo::initPhysics() m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); //btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(40.),btScalar(50.))); - btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),40); + btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0, 1, 0), 40); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0,-56,0)); + groundTransform.setOrigin(btVector3(0, -56, 0)); btRigidBody* groundBody; - groundBody= createRigidBody(0, groundTransform, groundShape); + groundBody = createRigidBody(0, groundTransform, groundShape); - - - btCollisionShape* shape = new btBoxShape(btVector3(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS)); + btCollisionShape* shape = new btBoxShape(btVector3(CUBE_HALF_EXTENTS, CUBE_HALF_EXTENTS, CUBE_HALF_EXTENTS)); m_collisionShapes.push_back(shape); btTransform trans; trans.setIdentity(); - trans.setOrigin(btVector3(0,20,0)); + trans.setOrigin(btVector3(0, 20, 0)); float mass = 1.f; #if ENABLE_ALL_DEMOS -///gear constraint demo + ///gear constraint demo -#define THETA SIMD_PI/4.f +#define THETA SIMD_PI / 4.f #define L_1 (2 - tan(THETA)) #define L_2 (1 / cos(THETA)) #define RATIO L_2 / L_1 - btRigidBody* bodyA=0; - btRigidBody* bodyB=0; + btRigidBody* bodyA = 0; + btRigidBody* bodyB = 0; { - btCollisionShape* cylA = new btCylinderShape(btVector3(0.2,0.25,0.2)); - btCollisionShape* cylB = new btCylinderShape(btVector3(L_1,0.025,L_1)); + btCollisionShape* cylA = new btCylinderShape(btVector3(0.2, 0.25, 0.2)); + btCollisionShape* cylB = new btCylinderShape(btVector3(L_1, 0.025, L_1)); btCompoundShape* cyl0 = new btCompoundShape(); - cyl0->addChildShape(btTransform::getIdentity(),cylA); - cyl0->addChildShape(btTransform::getIdentity(),cylB); + cyl0->addChildShape(btTransform::getIdentity(), cylA); + cyl0->addChildShape(btTransform::getIdentity(), cylB); btScalar mass = 6.28; btVector3 localInertia; - cyl0->calculateLocalInertia(mass,localInertia); - btRigidBody::btRigidBodyConstructionInfo ci(mass,0,cyl0,localInertia); - ci.m_startWorldTransform.setOrigin(btVector3(-8,1,-8)); + cyl0->calculateLocalInertia(mass, localInertia); + btRigidBody::btRigidBodyConstructionInfo ci(mass, 0, cyl0, localInertia); + ci.m_startWorldTransform.setOrigin(btVector3(-8, 1, -8)); - btRigidBody* body = new btRigidBody(ci);//1,0,cyl0,localInertia); + btRigidBody* body = new btRigidBody(ci); //1,0,cyl0,localInertia); m_dynamicsWorld->addRigidBody(body); - body->setLinearFactor(btVector3(0,0,0)); - body->setAngularFactor(btVector3(0,1,0)); + body->setLinearFactor(btVector3(0, 0, 0)); + body->setAngularFactor(btVector3(0, 1, 0)); bodyA = body; } { - btCollisionShape* cylA = new btCylinderShape(btVector3(0.2,0.26,0.2)); - btCollisionShape* cylB = new btCylinderShape(btVector3(L_2,0.025,L_2)); + btCollisionShape* cylA = new btCylinderShape(btVector3(0.2, 0.26, 0.2)); + btCollisionShape* cylB = new btCylinderShape(btVector3(L_2, 0.025, L_2)); btCompoundShape* cyl0 = new btCompoundShape(); - cyl0->addChildShape(btTransform::getIdentity(),cylA); - cyl0->addChildShape(btTransform::getIdentity(),cylB); + cyl0->addChildShape(btTransform::getIdentity(), cylA); + cyl0->addChildShape(btTransform::getIdentity(), cylB); btScalar mass = 6.28; btVector3 localInertia; - cyl0->calculateLocalInertia(mass,localInertia); - btRigidBody::btRigidBodyConstructionInfo ci(mass,0,cyl0,localInertia); - ci.m_startWorldTransform.setOrigin(btVector3(-10,2,-8)); + cyl0->calculateLocalInertia(mass, localInertia); + btRigidBody::btRigidBodyConstructionInfo ci(mass, 0, cyl0, localInertia); + ci.m_startWorldTransform.setOrigin(btVector3(-10, 2, -8)); - - btQuaternion orn(btVector3(0,0,1),-THETA); + btQuaternion orn(btVector3(0, 0, 1), -THETA); ci.m_startWorldTransform.setRotation(orn); - btRigidBody* body = new btRigidBody(ci);//1,0,cyl0,localInertia); - body->setLinearFactor(btVector3(0,0,0)); - btHingeConstraint* hinge = new btHingeConstraint(*body,btVector3(0,0,0),btVector3(0,1,0),true); + btRigidBody* body = new btRigidBody(ci); //1,0,cyl0,localInertia); + body->setLinearFactor(btVector3(0, 0, 0)); + btHingeConstraint* hinge = new btHingeConstraint(*body, btVector3(0, 0, 0), btVector3(0, 1, 0), true); m_dynamicsWorld->addConstraint(hinge); - bodyB= body; - body->setAngularVelocity(btVector3(0,3,0)); + bodyB = body; + body->setAngularVelocity(btVector3(0, 3, 0)); m_dynamicsWorld->addRigidBody(body); } - btVector3 axisA(0,1,0); - btVector3 axisB(0,1,0); - btQuaternion orn(btVector3(0,0,1),-THETA); + btVector3 axisA(0, 1, 0); + btVector3 axisB(0, 1, 0); + btQuaternion orn(btVector3(0, 0, 1), -THETA); btMatrix3x3 mat(orn); axisB = mat.getRow(1); - btGearConstraint* gear = new btGearConstraint(*bodyA,*bodyB, axisA,axisB,RATIO); - m_dynamicsWorld->addConstraint(gear,true); - + btGearConstraint* gear = new btGearConstraint(*bodyA, *bodyB, axisA, axisB, RATIO); + m_dynamicsWorld->addConstraint(gear, true); #endif - #if ENABLE_ALL_DEMOS //point to point constraint with a breaking threshold { trans.setIdentity(); - trans.setOrigin(btVector3(1,30,-5)); - createRigidBody( mass,trans,shape); - trans.setOrigin(btVector3(0,0,-5)); + trans.setOrigin(btVector3(1, 30, -5)); + createRigidBody(mass, trans, shape); + trans.setOrigin(btVector3(0, 0, -5)); - btRigidBody* body0 = createRigidBody( mass,trans,shape); - trans.setOrigin(btVector3(2*CUBE_HALF_EXTENTS,20,0)); + btRigidBody* body0 = createRigidBody(mass, trans, shape); + trans.setOrigin(btVector3(2 * CUBE_HALF_EXTENTS, 20, 0)); mass = 1.f; - // btRigidBody* body1 = 0;//createRigidBody( mass,trans,shape); - btVector3 pivotInA(CUBE_HALF_EXTENTS,CUBE_HALF_EXTENTS,0); - btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,pivotInA); + // btRigidBody* body1 = 0;//createRigidBody( mass,trans,shape); + btVector3 pivotInA(CUBE_HALF_EXTENTS, CUBE_HALF_EXTENTS, 0); + btTypedConstraint* p2p = new btPoint2PointConstraint(*body0, pivotInA); m_dynamicsWorld->addConstraint(p2p); - p2p ->setBreakingImpulseThreshold(10.2); + p2p->setBreakingImpulseThreshold(10.2); p2p->setDbgDrawSize(btScalar(5.f)); } #endif - - #if ENABLE_ALL_DEMOS //point to point constraint (ball socket) { - btRigidBody* body0 = createRigidBody( mass,trans,shape); - trans.setOrigin(btVector3(2*CUBE_HALF_EXTENTS,20,0)); + btRigidBody* body0 = createRigidBody(mass, trans, shape); + trans.setOrigin(btVector3(2 * CUBE_HALF_EXTENTS, 20, 0)); mass = 1.f; -// btRigidBody* body1 = 0;//createRigidBody( mass,trans,shape); -// btRigidBody* body1 = createRigidBody( 0.0,trans,0); + // btRigidBody* body1 = 0;//createRigidBody( mass,trans,shape); + // btRigidBody* body1 = createRigidBody( 0.0,trans,0); //body1->setActivationState(DISABLE_DEACTIVATION); //body1->setDamping(0.3,0.3); - btVector3 pivotInA(CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS,-CUBE_HALF_EXTENTS); - btVector3 axisInA(0,0,1); + btVector3 pivotInA(CUBE_HALF_EXTENTS, -CUBE_HALF_EXTENTS, -CUBE_HALF_EXTENTS); + btVector3 axisInA(0, 0, 1); - // btVector3 pivotInB = body1 ? body1->getCenterOfMassTransform().inverse()(body0->getCenterOfMassTransform()(pivotInA)) : pivotInA; -// btVector3 axisInB = body1? -// (body1->getCenterOfMassTransform().getBasis().inverse()*(body1->getCenterOfMassTransform().getBasis() * axisInA)) : + // btVector3 pivotInB = body1 ? body1->getCenterOfMassTransform().inverse()(body0->getCenterOfMassTransform()(pivotInA)) : pivotInA; + // btVector3 axisInB = body1? + // (body1->getCenterOfMassTransform().getBasis().inverse()*(body1->getCenterOfMassTransform().getBasis() * axisInA)) : body0->getCenterOfMassTransform().getBasis() * axisInA; #define P2P #ifdef P2P - btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,pivotInA); + btTypedConstraint* p2p = new btPoint2PointConstraint(*body0, pivotInA); //btTypedConstraint* p2p = new btPoint2PointConstraint(*body0,*body1,pivotInA,pivotInB); //btTypedConstraint* hinge = new btHingeConstraint(*body0,*body1,pivotInA,pivotInB,axisInA,axisInB); m_dynamicsWorld->addConstraint(p2p); p2p->setDbgDrawSize(btScalar(5.f)); #else - btHingeConstraint* hinge = new btHingeConstraint(*body0,pivotInA,axisInA); - + btHingeConstraint* hinge = new btHingeConstraint(*body0, pivotInA, axisInA); + //use zero targetVelocity and a small maxMotorImpulse to simulate joint friction //float targetVelocity = 0.f; //float maxMotorImpulse = 0.01; - float targetVelocity = 1.f; - float maxMotorImpulse = 1.0f; - hinge->enableAngularMotor(true,targetVelocity,maxMotorImpulse); + float targetVelocity = 1.f; + float maxMotorImpulse = 1.0f; + hinge->enableAngularMotor(true, targetVelocity, maxMotorImpulse); m_dynamicsWorld->addConstraint(hinge); hinge->setDbgDrawSize(btScalar(5.f)); -#endif //P2P - - - - +#endif //P2P } #endif - #if ENABLE_ALL_DEMOS { btTransform trans; - trans.setIdentity(); - btVector3 worldPos(-20,0,30); - trans.setOrigin(worldPos); + trans.setIdentity(); + btVector3 worldPos(-20, 0, 30); + trans.setOrigin(worldPos); - btTransform frameInA, frameInB; - frameInA = btTransform::getIdentity(); - frameInB = btTransform::getIdentity(); + btTransform frameInA, frameInB; + frameInA = btTransform::getIdentity(); + frameInB = btTransform::getIdentity(); - btRigidBody* pRbA1 = createRigidBody(mass, trans, shape); -// btRigidBody* pRbA1 = createRigidBody(0.f, trans, shape); - pRbA1->setActivationState(DISABLE_DEACTIVATION); + btRigidBody* pRbA1 = createRigidBody(mass, trans, shape); + // btRigidBody* pRbA1 = createRigidBody(0.f, trans, shape); + pRbA1->setActivationState(DISABLE_DEACTIVATION); - // add dynamic rigid body B1 - worldPos.setValue(-30,0,30); - trans.setOrigin(worldPos); - btRigidBody* pRbB1 = createRigidBody(mass, trans, shape); -// btRigidBody* pRbB1 = createRigidBody(0.f, trans, shape); - pRbB1->setActivationState(DISABLE_DEACTIVATION); + // add dynamic rigid body B1 + worldPos.setValue(-30, 0, 30); + trans.setOrigin(worldPos); + btRigidBody* pRbB1 = createRigidBody(mass, trans, shape); + // btRigidBody* pRbB1 = createRigidBody(0.f, trans, shape); + pRbB1->setActivationState(DISABLE_DEACTIVATION); - // create slider constraint between A1 and B1 and add it to world - - btSliderConstraint* spSlider1 = new btSliderConstraint(*pRbA1, *pRbB1, frameInA, frameInB, true); -// spSlider1 = new btSliderConstraint(*pRbA1, *pRbB1, frameInA, frameInB, false); - spSlider1->setLowerLinLimit(-15.0F); - spSlider1->setUpperLinLimit(-5.0F); -// spSlider1->setLowerLinLimit(5.0F); -// spSlider1->setUpperLinLimit(15.0F); -// spSlider1->setLowerLinLimit(-10.0F); -// spSlider1->setUpperLinLimit(-10.0F); + // create slider constraint between A1 and B1 and add it to world - spSlider1->setLowerAngLimit(-SIMD_PI / 3.0F); - spSlider1->setUpperAngLimit( SIMD_PI / 3.0F); + btSliderConstraint* spSlider1 = new btSliderConstraint(*pRbA1, *pRbB1, frameInA, frameInB, true); + // spSlider1 = new btSliderConstraint(*pRbA1, *pRbB1, frameInA, frameInB, false); + spSlider1->setLowerLinLimit(-15.0F); + spSlider1->setUpperLinLimit(-5.0F); + // spSlider1->setLowerLinLimit(5.0F); + // spSlider1->setUpperLinLimit(15.0F); + // spSlider1->setLowerLinLimit(-10.0F); + // spSlider1->setUpperLinLimit(-10.0F); + spSlider1->setLowerAngLimit(-SIMD_PI / 3.0F); + spSlider1->setUpperAngLimit(SIMD_PI / 3.0F); - m_dynamicsWorld->addConstraint(spSlider1, true); - spSlider1->setDbgDrawSize(btScalar(5.f)); + m_dynamicsWorld->addConstraint(spSlider1, true); + spSlider1->setDbgDrawSize(btScalar(5.f)); } #endif -#if ENABLE_ALL_DEMOS +#if ENABLE_ALL_DEMOS //create a slider, using the generic D6 constraint { mass = 1.f; - btVector3 sliderWorldPos(0,10,0); - btVector3 sliderAxis(1,0,0); - btScalar angle=0.f;//SIMD_RADS_PER_DEG * 10.f; - btMatrix3x3 sliderOrientation(btQuaternion(sliderAxis ,angle)); + btVector3 sliderWorldPos(0, 10, 0); + btVector3 sliderAxis(1, 0, 0); + btScalar angle = 0.f; //SIMD_RADS_PER_DEG * 10.f; + btMatrix3x3 sliderOrientation(btQuaternion(sliderAxis, angle)); trans.setIdentity(); trans.setOrigin(sliderWorldPos); //trans.setBasis(sliderOrientation); sliderTransform = trans; - d6body0 = createRigidBody( mass,trans,shape); + d6body0 = createRigidBody(mass, trans, shape); d6body0->setActivationState(DISABLE_DEACTIVATION); - btRigidBody* fixedBody1 = createRigidBody(0,trans,0); + btRigidBody* fixedBody1 = createRigidBody(0, trans, 0); m_dynamicsWorld->addRigidBody(fixedBody1); btTransform frameInA, frameInB; @@ -340,54 +305,52 @@ void AllConstraintDemo::initPhysics() frameInA.setOrigin(btVector3(0., 5., 0.)); frameInB.setOrigin(btVector3(0., 5., 0.)); -// bool useLinearReferenceFrameA = false;//use fixed frame B for linear llimits - bool useLinearReferenceFrameA = true;//use fixed frame A for linear llimits - spSlider6Dof = new btGeneric6DofConstraint(*fixedBody1, *d6body0,frameInA,frameInB,useLinearReferenceFrameA); + // bool useLinearReferenceFrameA = false;//use fixed frame B for linear llimits + bool useLinearReferenceFrameA = true; //use fixed frame A for linear llimits + spSlider6Dof = new btGeneric6DofConstraint(*fixedBody1, *d6body0, frameInA, frameInB, useLinearReferenceFrameA); spSlider6Dof->setLinearLowerLimit(lowerSliderLimit); spSlider6Dof->setLinearUpperLimit(hiSliderLimit); //range should be small, otherwise singularities will 'explode' the constraint -// spSlider6Dof->setAngularLowerLimit(btVector3(-1.5,0,0)); -// spSlider6Dof->setAngularUpperLimit(btVector3(1.5,0,0)); -// spSlider6Dof->setAngularLowerLimit(btVector3(0,0,0)); -// spSlider6Dof->setAngularUpperLimit(btVector3(0,0,0)); - spSlider6Dof->setAngularLowerLimit(btVector3(-SIMD_PI,0,0)); - spSlider6Dof->setAngularUpperLimit(btVector3(1.5,0,0)); + // spSlider6Dof->setAngularLowerLimit(btVector3(-1.5,0,0)); + // spSlider6Dof->setAngularUpperLimit(btVector3(1.5,0,0)); + // spSlider6Dof->setAngularLowerLimit(btVector3(0,0,0)); + // spSlider6Dof->setAngularUpperLimit(btVector3(0,0,0)); + spSlider6Dof->setAngularLowerLimit(btVector3(-SIMD_PI, 0, 0)); + spSlider6Dof->setAngularUpperLimit(btVector3(1.5, 0, 0)); spSlider6Dof->getTranslationalLimitMotor()->m_enableMotor[0] = true; spSlider6Dof->getTranslationalLimitMotor()->m_targetVelocity[0] = -5.0f; spSlider6Dof->getTranslationalLimitMotor()->m_maxMotorForce[0] = 6.0f; - m_dynamicsWorld->addConstraint(spSlider6Dof); spSlider6Dof->setDbgDrawSize(btScalar(5.f)); - } #endif #if ENABLE_ALL_DEMOS - { // create a door using hinge constraint attached to the world + { // create a door using hinge constraint attached to the world btCollisionShape* pDoorShape = new btBoxShape(btVector3(2.0f, 5.0f, 0.2f)); m_collisionShapes.push_back(pDoorShape); btTransform doorTrans; doorTrans.setIdentity(); doorTrans.setOrigin(btVector3(-5.0f, -2.0f, 0.0f)); - btRigidBody* pDoorBody = createRigidBody( 1.0, doorTrans, pDoorShape); + btRigidBody* pDoorBody = createRigidBody(1.0, doorTrans, pDoorShape); pDoorBody->setActivationState(DISABLE_DEACTIVATION); - const btVector3 btPivotA(10.f + 2.1f, -2.0f, 0.0f ); // right next to the door slightly outside - btVector3 btAxisA( 0.0f, 1.0f, 0.0f ); // pointing upwards, aka Y-axis + const btVector3 btPivotA(10.f + 2.1f, -2.0f, 0.0f); // right next to the door slightly outside + btVector3 btAxisA(0.0f, 1.0f, 0.0f); // pointing upwards, aka Y-axis - spDoorHinge = new btHingeConstraint( *pDoorBody, btPivotA, btAxisA ); + spDoorHinge = new btHingeConstraint(*pDoorBody, btPivotA, btAxisA); -// spDoorHinge->setLimit( 0.0f, SIMD_PI_2 ); + // spDoorHinge->setLimit( 0.0f, SIMD_PI_2 ); // test problem values -// spDoorHinge->setLimit( -SIMD_PI, SIMD_PI*0.8f); + // spDoorHinge->setLimit( -SIMD_PI, SIMD_PI*0.8f); -// spDoorHinge->setLimit( 1.f, -1.f); -// spDoorHinge->setLimit( -SIMD_PI*0.8f, SIMD_PI); -// spDoorHinge->setLimit( -SIMD_PI*0.8f, SIMD_PI, 0.9f, 0.3f, 0.0f); -// spDoorHinge->setLimit( -SIMD_PI*0.8f, SIMD_PI, 0.9f, 0.01f, 0.0f); // "sticky limits" - spDoorHinge->setLimit( -SIMD_PI * 0.25f, SIMD_PI * 0.25f ); -// spDoorHinge->setLimit( 0.0f, 0.0f ); + // spDoorHinge->setLimit( 1.f, -1.f); + // spDoorHinge->setLimit( -SIMD_PI*0.8f, SIMD_PI); + // spDoorHinge->setLimit( -SIMD_PI*0.8f, SIMD_PI, 0.9f, 0.3f, 0.0f); + // spDoorHinge->setLimit( -SIMD_PI*0.8f, SIMD_PI, 0.9f, 0.01f, 0.0f); // "sticky limits" + spDoorHinge->setLimit(-SIMD_PI * 0.25f, SIMD_PI * 0.25f); + // spDoorHinge->setLimit( 0.0f, 0.0f ); m_dynamicsWorld->addConstraint(spDoorHinge); spDoorHinge->setDbgDrawSize(btScalar(5.f)); @@ -396,22 +359,22 @@ void AllConstraintDemo::initPhysics() } #endif #if ENABLE_ALL_DEMOS - { // create a generic 6DOF constraint + { // create a generic 6DOF constraint btTransform tr; tr.setIdentity(); tr.setOrigin(btVector3(btScalar(10.), btScalar(6.), btScalar(0.))); - tr.getBasis().setEulerZYX(0,0,0); -// btRigidBody* pBodyA = createRigidBody( mass, tr, shape); - btRigidBody* pBodyA = createRigidBody( 0.0, tr, shape); -// btRigidBody* pBodyA = createRigidBody( 0.0, tr, 0); + tr.getBasis().setEulerZYX(0, 0, 0); + // btRigidBody* pBodyA = createRigidBody( mass, tr, shape); + btRigidBody* pBodyA = createRigidBody(0.0, tr, shape); + // btRigidBody* pBodyA = createRigidBody( 0.0, tr, 0); pBodyA->setActivationState(DISABLE_DEACTIVATION); tr.setIdentity(); tr.setOrigin(btVector3(btScalar(0.), btScalar(6.), btScalar(0.))); - tr.getBasis().setEulerZYX(0,0,0); + tr.getBasis().setEulerZYX(0, 0, 0); btRigidBody* pBodyB = createRigidBody(mass, tr, shape); -// btRigidBody* pBodyB = createRigidBody(0.f, tr, shape); + // btRigidBody* pBodyB = createRigidBody(0.f, tr, shape); pBodyB->setActivationState(DISABLE_DEACTIVATION); btTransform frameInA, frameInB; @@ -421,75 +384,72 @@ void AllConstraintDemo::initPhysics() frameInB.setOrigin(btVector3(btScalar(5.), btScalar(0.), btScalar(0.))); btGeneric6DofConstraint* pGen6DOF = new btGeneric6DofConstraint(*pBodyA, *pBodyB, frameInA, frameInB, true); -// btGeneric6DofConstraint* pGen6DOF = new btGeneric6DofConstraint(*pBodyA, *pBodyB, frameInA, frameInB, false); + // btGeneric6DofConstraint* pGen6DOF = new btGeneric6DofConstraint(*pBodyA, *pBodyB, frameInA, frameInB, false); pGen6DOF->setLinearLowerLimit(btVector3(-10., -2., -1.)); pGen6DOF->setLinearUpperLimit(btVector3(10., 2., 1.)); -// pGen6DOF->setLinearLowerLimit(btVector3(-10., 0., 0.)); -// pGen6DOF->setLinearUpperLimit(btVector3(10., 0., 0.)); -// pGen6DOF->setLinearLowerLimit(btVector3(0., 0., 0.)); -// pGen6DOF->setLinearUpperLimit(btVector3(0., 0., 0.)); + // pGen6DOF->setLinearLowerLimit(btVector3(-10., 0., 0.)); + // pGen6DOF->setLinearUpperLimit(btVector3(10., 0., 0.)); + // pGen6DOF->setLinearLowerLimit(btVector3(0., 0., 0.)); + // pGen6DOF->setLinearUpperLimit(btVector3(0., 0., 0.)); -// pGen6DOF->getTranslationalLimitMotor()->m_enableMotor[0] = true; -// pGen6DOF->getTranslationalLimitMotor()->m_targetVelocity[0] = 5.0f; -// pGen6DOF->getTranslationalLimitMotor()->m_maxMotorForce[0] = 6.0f; + // pGen6DOF->getTranslationalLimitMotor()->m_enableMotor[0] = true; + // pGen6DOF->getTranslationalLimitMotor()->m_targetVelocity[0] = 5.0f; + // pGen6DOF->getTranslationalLimitMotor()->m_maxMotorForce[0] = 6.0f; - -// pGen6DOF->setAngularLowerLimit(btVector3(0., SIMD_HALF_PI*0.9, 0.)); -// pGen6DOF->setAngularUpperLimit(btVector3(0., -SIMD_HALF_PI*0.9, 0.)); -// pGen6DOF->setAngularLowerLimit(btVector3(0., 0., -SIMD_HALF_PI)); -// pGen6DOF->setAngularUpperLimit(btVector3(0., 0., SIMD_HALF_PI)); + // pGen6DOF->setAngularLowerLimit(btVector3(0., SIMD_HALF_PI*0.9, 0.)); + // pGen6DOF->setAngularUpperLimit(btVector3(0., -SIMD_HALF_PI*0.9, 0.)); + // pGen6DOF->setAngularLowerLimit(btVector3(0., 0., -SIMD_HALF_PI)); + // pGen6DOF->setAngularUpperLimit(btVector3(0., 0., SIMD_HALF_PI)); pGen6DOF->setAngularLowerLimit(btVector3(-SIMD_HALF_PI * 0.5f, -0.75, -SIMD_HALF_PI * 0.8f)); pGen6DOF->setAngularUpperLimit(btVector3(SIMD_HALF_PI * 0.5f, 0.75, SIMD_HALF_PI * 0.8f)); -// pGen6DOF->setAngularLowerLimit(btVector3(0.f, -0.75, SIMD_HALF_PI * 0.8f)); -// pGen6DOF->setAngularUpperLimit(btVector3(0.f, 0.75, -SIMD_HALF_PI * 0.8f)); -// pGen6DOF->setAngularLowerLimit(btVector3(0.f, -SIMD_HALF_PI * 0.8f, SIMD_HALF_PI * 1.98f)); -// pGen6DOF->setAngularUpperLimit(btVector3(0.f, SIMD_HALF_PI * 0.8f, -SIMD_HALF_PI * 1.98f)); + // pGen6DOF->setAngularLowerLimit(btVector3(0.f, -0.75, SIMD_HALF_PI * 0.8f)); + // pGen6DOF->setAngularUpperLimit(btVector3(0.f, 0.75, -SIMD_HALF_PI * 0.8f)); + // pGen6DOF->setAngularLowerLimit(btVector3(0.f, -SIMD_HALF_PI * 0.8f, SIMD_HALF_PI * 1.98f)); + // pGen6DOF->setAngularUpperLimit(btVector3(0.f, SIMD_HALF_PI * 0.8f, -SIMD_HALF_PI * 1.98f)); - - -// pGen6DOF->setAngularLowerLimit(btVector3(-0.75,-0.5, -0.5)); -// pGen6DOF->setAngularUpperLimit(btVector3(0.75,0.5, 0.5)); -// pGen6DOF->setAngularLowerLimit(btVector3(-0.75,0., 0.)); -// pGen6DOF->setAngularUpperLimit(btVector3(0.75,0., 0.)); -// pGen6DOF->setAngularLowerLimit(btVector3(0., -0.7,0.)); -// pGen6DOF->setAngularUpperLimit(btVector3(0., 0.7, 0.)); -// pGen6DOF->setAngularLowerLimit(btVector3(-1., 0.,0.)); -// pGen6DOF->setAngularUpperLimit(btVector3(1., 0., 0.)); + // pGen6DOF->setAngularLowerLimit(btVector3(-0.75,-0.5, -0.5)); + // pGen6DOF->setAngularUpperLimit(btVector3(0.75,0.5, 0.5)); + // pGen6DOF->setAngularLowerLimit(btVector3(-0.75,0., 0.)); + // pGen6DOF->setAngularUpperLimit(btVector3(0.75,0., 0.)); + // pGen6DOF->setAngularLowerLimit(btVector3(0., -0.7,0.)); + // pGen6DOF->setAngularUpperLimit(btVector3(0., 0.7, 0.)); + // pGen6DOF->setAngularLowerLimit(btVector3(-1., 0.,0.)); + // pGen6DOF->setAngularUpperLimit(btVector3(1., 0., 0.)); m_dynamicsWorld->addConstraint(pGen6DOF, true); pGen6DOF->setDbgDrawSize(btScalar(5.f)); } #endif #if ENABLE_ALL_DEMOS - { // create a ConeTwist constraint + { // create a ConeTwist constraint btTransform tr; tr.setIdentity(); tr.setOrigin(btVector3(btScalar(-10.), btScalar(5.), btScalar(0.))); - tr.getBasis().setEulerZYX(0,0,0); - btRigidBody* pBodyA = createRigidBody( 1.0, tr, shape); -// btRigidBody* pBodyA = createRigidBody( 0.0, tr, shape); + tr.getBasis().setEulerZYX(0, 0, 0); + btRigidBody* pBodyA = createRigidBody(1.0, tr, shape); + // btRigidBody* pBodyA = createRigidBody( 0.0, tr, shape); pBodyA->setActivationState(DISABLE_DEACTIVATION); tr.setIdentity(); tr.setOrigin(btVector3(btScalar(-10.), btScalar(-5.), btScalar(0.))); - tr.getBasis().setEulerZYX(0,0,0); + tr.getBasis().setEulerZYX(0, 0, 0); btRigidBody* pBodyB = createRigidBody(0.0, tr, shape); -// btRigidBody* pBodyB = createRigidBody(1.0, tr, shape); + // btRigidBody* pBodyB = createRigidBody(1.0, tr, shape); btTransform frameInA, frameInB; frameInA = btTransform::getIdentity(); frameInA.getBasis().setEulerZYX(0, 0, SIMD_PI_2); frameInA.setOrigin(btVector3(btScalar(0.), btScalar(-5.), btScalar(0.))); frameInB = btTransform::getIdentity(); - frameInB.getBasis().setEulerZYX(0,0, SIMD_PI_2); + frameInB.getBasis().setEulerZYX(0, 0, SIMD_PI_2); frameInB.setOrigin(btVector3(btScalar(0.), btScalar(5.), btScalar(0.))); m_ctc = new btConeTwistConstraint(*pBodyA, *pBodyB, frameInA, frameInB); -// m_ctc->setLimit(btScalar(SIMD_PI_4), btScalar(SIMD_PI_4), btScalar(SIMD_PI) * 0.8f); -// m_ctc->setLimit(btScalar(SIMD_PI_4*0.6f), btScalar(SIMD_PI_4), btScalar(SIMD_PI) * 0.8f, 1.0f); // soft limit == hard limit - m_ctc->setLimit(btScalar(SIMD_PI_4*0.6f), btScalar(SIMD_PI_4), btScalar(SIMD_PI) * 0.8f, 0.5f); + // m_ctc->setLimit(btScalar(SIMD_PI_4), btScalar(SIMD_PI_4), btScalar(SIMD_PI) * 0.8f); + // m_ctc->setLimit(btScalar(SIMD_PI_4*0.6f), btScalar(SIMD_PI_4), btScalar(SIMD_PI) * 0.8f, 1.0f); // soft limit == hard limit + m_ctc->setLimit(btScalar(SIMD_PI_4 * 0.6f), btScalar(SIMD_PI_4), btScalar(SIMD_PI) * 0.8f, 0.5f); m_dynamicsWorld->addConstraint(m_ctc, true); m_ctc->setDbgDrawSize(btScalar(5.f)); // s_bTestConeTwistMotor = true; // use only with old solver for now @@ -497,32 +457,32 @@ void AllConstraintDemo::initPhysics() } #endif #if ENABLE_ALL_DEMOS - { // Hinge connected to the world, with motor (to hinge motor with new and old constraint solver) + { // Hinge connected to the world, with motor (to hinge motor with new and old constraint solver) btTransform tr; tr.setIdentity(); tr.setOrigin(btVector3(btScalar(0.), btScalar(0.), btScalar(0.))); - btRigidBody* pBody = createRigidBody( 1.0, tr, shape); + btRigidBody* pBody = createRigidBody(1.0, tr, shape); pBody->setActivationState(DISABLE_DEACTIVATION); - const btVector3 btPivotA( 10.0f, 0.0f, 0.0f ); - btVector3 btAxisA( 0.0f, 0.0f, 1.0f ); + const btVector3 btPivotA(10.0f, 0.0f, 0.0f); + btVector3 btAxisA(0.0f, 0.0f, 1.0f); - btHingeConstraint* pHinge = new btHingeConstraint( *pBody, btPivotA, btAxisA ); -// pHinge->enableAngularMotor(true, -1.0, 0.165); // use for the old solver - pHinge->enableAngularMotor(true, -1.0f, 1.65f); // use for the new SIMD solver + btHingeConstraint* pHinge = new btHingeConstraint(*pBody, btPivotA, btAxisA); + // pHinge->enableAngularMotor(true, -1.0, 0.165); // use for the old solver + pHinge->enableAngularMotor(true, -1.0f, 1.65f); // use for the new SIMD solver m_dynamicsWorld->addConstraint(pHinge); pHinge->setDbgDrawSize(btScalar(5.f)); } #endif #if ENABLE_ALL_DEMOS - { + { // create a universal joint using generic 6DOF constraint // create two rigid bodies // static bodyA (parent) on top: btTransform tr; tr.setIdentity(); tr.setOrigin(btVector3(btScalar(20.), btScalar(4.), btScalar(0.))); - btRigidBody* pBodyA = createRigidBody( 0.0, tr, shape); + btRigidBody* pBodyA = createRigidBody(0.0, tr, shape); pBodyA->setActivationState(DISABLE_DEACTIVATION); // dynamic bodyB (child) below it : tr.setIdentity(); @@ -530,13 +490,13 @@ void AllConstraintDemo::initPhysics() btRigidBody* pBodyB = createRigidBody(1.0, tr, shape); pBodyB->setActivationState(DISABLE_DEACTIVATION); // add some (arbitrary) data to build constraint frames - btVector3 parentAxis(1.f, 0.f, 0.f); - btVector3 childAxis(0.f, 0.f, 1.f); + btVector3 parentAxis(1.f, 0.f, 0.f); + btVector3 childAxis(0.f, 0.f, 1.f); btVector3 anchor(20.f, 2.f, 0.f); btUniversalConstraint* pUniv = new btUniversalConstraint(*pBodyA, *pBodyB, anchor, parentAxis, childAxis); pUniv->setLowerLimit(-SIMD_HALF_PI * 0.5f, -SIMD_HALF_PI * 0.5f); - pUniv->setUpperLimit(SIMD_HALF_PI * 0.5f, SIMD_HALF_PI * 0.5f); + pUniv->setUpperLimit(SIMD_HALF_PI * 0.5f, SIMD_HALF_PI * 0.5f); // add constraint to world m_dynamicsWorld->addConstraint(pUniv, true); // draw constraint frames and limits for debugging @@ -545,18 +505,18 @@ void AllConstraintDemo::initPhysics() #endif #if ENABLE_ALL_DEMOS - { // create a generic 6DOF constraint with springs + { // create a generic 6DOF constraint with springs btTransform tr; tr.setIdentity(); tr.setOrigin(btVector3(btScalar(-20.), btScalar(16.), btScalar(0.))); - tr.getBasis().setEulerZYX(0,0,0); - btRigidBody* pBodyA = createRigidBody( 0.0, tr, shape); + tr.getBasis().setEulerZYX(0, 0, 0); + btRigidBody* pBodyA = createRigidBody(0.0, tr, shape); pBodyA->setActivationState(DISABLE_DEACTIVATION); tr.setIdentity(); tr.setOrigin(btVector3(btScalar(-10.), btScalar(16.), btScalar(0.))); - tr.getBasis().setEulerZYX(0,0,0); + tr.getBasis().setEulerZYX(0, 0, 0); btRigidBody* pBodyB = createRigidBody(1.0, tr, shape); pBodyB->setActivationState(DISABLE_DEACTIVATION); @@ -575,7 +535,7 @@ void AllConstraintDemo::initPhysics() m_dynamicsWorld->addConstraint(pGen6DOFSpring, true); pGen6DOFSpring->setDbgDrawSize(btScalar(5.f)); - + pGen6DOFSpring->enableSpring(0, true); pGen6DOFSpring->setStiffness(0, 39.478f); pGen6DOFSpring->setDamping(0, 0.5f); @@ -586,14 +546,14 @@ void AllConstraintDemo::initPhysics() } #endif #if ENABLE_ALL_DEMOS - { + { // create a Hinge2 joint // create two rigid bodies // static bodyA (parent) on top: btTransform tr; tr.setIdentity(); tr.setOrigin(btVector3(btScalar(-20.), btScalar(4.), btScalar(0.))); - btRigidBody* pBodyA = createRigidBody( 0.0, tr, shape); + btRigidBody* pBodyA = createRigidBody(0.0, tr, shape); pBodyA->setActivationState(DISABLE_DEACTIVATION); // dynamic bodyB (child) below it : tr.setIdentity(); @@ -601,27 +561,27 @@ void AllConstraintDemo::initPhysics() btRigidBody* pBodyB = createRigidBody(1.0, tr, shape); pBodyB->setActivationState(DISABLE_DEACTIVATION); // add some data to build constraint frames - btVector3 parentAxis(0.f, 1.f, 0.f); - btVector3 childAxis(1.f, 0.f, 0.f); + btVector3 parentAxis(0.f, 1.f, 0.f); + btVector3 childAxis(1.f, 0.f, 0.f); btVector3 anchor(-20.f, 0.f, 0.f); btHinge2Constraint* pHinge2 = new btHinge2Constraint(*pBodyA, *pBodyB, anchor, parentAxis, childAxis); pHinge2->setLowerLimit(-SIMD_HALF_PI * 0.5f); - pHinge2->setUpperLimit( SIMD_HALF_PI * 0.5f); + pHinge2->setUpperLimit(SIMD_HALF_PI * 0.5f); // add constraint to world m_dynamicsWorld->addConstraint(pHinge2, true); // draw constraint frames and limits for debugging pHinge2->setDbgDrawSize(btScalar(5.f)); } #endif -#if ENABLE_ALL_DEMOS - { +#if ENABLE_ALL_DEMOS + { // create a Hinge joint between two dynamic bodies // create two rigid bodies // static bodyA (parent) on top: btTransform tr; tr.setIdentity(); tr.setOrigin(btVector3(btScalar(-20.), btScalar(-2.), btScalar(0.))); - btRigidBody* pBodyA = createRigidBody( 1.0f, tr, shape); + btRigidBody* pBodyA = createRigidBody(1.0f, tr, shape); pBodyA->setActivationState(DISABLE_DEACTIVATION); // dynamic bodyB: tr.setIdentity(); @@ -629,10 +589,10 @@ void AllConstraintDemo::initPhysics() btRigidBody* pBodyB = createRigidBody(10.0, tr, shape); pBodyB->setActivationState(DISABLE_DEACTIVATION); // add some data to build constraint frames - btVector3 axisA(0.f, 1.f, 0.f); - btVector3 axisB(0.f, 1.f, 0.f); + btVector3 axisA(0.f, 1.f, 0.f); + btVector3 axisB(0.f, 1.f, 0.f); btVector3 pivotA(-5.f, 0.f, 0.f); - btVector3 pivotB( 5.f, 0.f, 0.f); + btVector3 pivotB(5.f, 0.f, 0.f); spHingeDynAB = new btHingeConstraint(*pBodyA, *pBodyB, pivotA, pivotB, axisA, axisB); spHingeDynAB->setLimit(-SIMD_HALF_PI * 0.5f, SIMD_HALF_PI * 0.5f); // add constraint to world @@ -643,20 +603,20 @@ void AllConstraintDemo::initPhysics() #endif #if ENABLE_ALL_DEMOS - { // 6DOF connected to the world, with motor + { // 6DOF connected to the world, with motor btTransform tr; tr.setIdentity(); tr.setOrigin(btVector3(btScalar(10.), btScalar(-15.), btScalar(0.))); - btRigidBody* pBody = createRigidBody( 1.0, tr, shape); + btRigidBody* pBody = createRigidBody(1.0, tr, shape); pBody->setActivationState(DISABLE_DEACTIVATION); btTransform frameB; frameB.setIdentity(); - btGeneric6DofConstraint* pGen6Dof = new btGeneric6DofConstraint( *pBody, frameB, false ); + btGeneric6DofConstraint* pGen6Dof = new btGeneric6DofConstraint(*pBody, frameB, false); m_dynamicsWorld->addConstraint(pGen6Dof); pGen6Dof->setDbgDrawSize(btScalar(5.f)); - pGen6Dof->setAngularLowerLimit(btVector3(0,0,0)); - pGen6Dof->setAngularUpperLimit(btVector3(0,0,0)); + pGen6Dof->setAngularLowerLimit(btVector3(0, 0, 0)); + pGen6Dof->setAngularUpperLimit(btVector3(0, 0, 0)); pGen6Dof->setLinearLowerLimit(btVector3(-10., 0, 0)); pGen6Dof->setLinearUpperLimit(btVector3(10., 0, 0)); @@ -667,17 +627,14 @@ void AllConstraintDemo::initPhysics() #endif m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); - - } -void AllConstraintDemo::exitPhysics() +void AllConstraintDemo::exitPhysics() { - - int i; + int i; //removed/delete constraints - for (i=m_dynamicsWorld->getNumConstraints()-1; i>=0 ;i--) + for (i = m_dynamicsWorld->getNumConstraints() - 1; i >= 0; i--) { btTypedConstraint* constraint = m_dynamicsWorld->getConstraint(i); m_dynamicsWorld->removeConstraint(constraint); @@ -686,7 +643,7 @@ void AllConstraintDemo::exitPhysics() m_ctc = NULL; //remove the rigidbodies from the dynamics world and delete them - for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--) { btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; btRigidBody* body = btRigidBody::upcast(obj); @@ -694,15 +651,12 @@ void AllConstraintDemo::exitPhysics() { delete body->getMotionState(); } - m_dynamicsWorld->removeCollisionObject( obj ); + m_dynamicsWorld->removeCollisionObject(obj); delete obj; } - - - //delete collision shapes - for (int j=0;jgetUseFrameOffset(); - offectOnOff = !offectOnOff; - spDoorHinge->setUseFrameOffset(offectOnOff); - printf("DoorHinge %s frame offset\n", offectOnOff ? "uses" : "does not use"); - } - if(spHingeDynAB) - { - offectOnOff = spHingeDynAB->getUseFrameOffset(); - offectOnOff = !offectOnOff; - spHingeDynAB->setUseFrameOffset(offectOnOff); - printf("HingeDynAB %s frame offset\n", offectOnOff ? "uses" : "does not use"); - } - if(spSlider6Dof) - { - offectOnOff = spSlider6Dof->getUseFrameOffset(); - offectOnOff = !offectOnOff; - spSlider6Dof->setUseFrameOffset(offectOnOff); - printf("Slider6Dof %s frame offset\n", offectOnOff ? "uses" : "does not use"); - } + offectOnOff = spDoorHinge->getUseFrameOffset(); + offectOnOff = !offectOnOff; + spDoorHinge->setUseFrameOffset(offectOnOff); + printf("DoorHinge %s frame offset\n", offectOnOff ? "uses" : "does not use"); } + if (spHingeDynAB) + { + offectOnOff = spHingeDynAB->getUseFrameOffset(); + offectOnOff = !offectOnOff; + spHingeDynAB->setUseFrameOffset(offectOnOff); + printf("HingeDynAB %s frame offset\n", offectOnOff ? "uses" : "does not use"); + } + if (spSlider6Dof) + { + offectOnOff = spSlider6Dof->getUseFrameOffset(); + offectOnOff = !offectOnOff; + spSlider6Dof->setUseFrameOffset(offectOnOff); + printf("Slider6Dof %s frame offset\n", offectOnOff ? "uses" : "does not use"); + } + } handled = true; break; - default : - { - - } - break; + default: + { + } + break; } return handled; - } -class CommonExampleInterface* AllConstraintCreateFunc(struct CommonExampleOptions& options) +class CommonExampleInterface* AllConstraintCreateFunc(struct CommonExampleOptions& options) { return new AllConstraintDemo(options.m_guiHelper); } diff --git a/examples/Constraints/ConstraintDemo.h b/examples/Constraints/ConstraintDemo.h index 0b48c0ce2..de0061bac 100644 --- a/examples/Constraints/ConstraintDemo.h +++ b/examples/Constraints/ConstraintDemo.h @@ -15,8 +15,6 @@ subject to the following restrictions: #ifndef ALL_CONSTRAINT_DEMO_H #define ALL_CONSTRAINT_DEMO_H -class CommonExampleInterface* AllConstraintCreateFunc(struct CommonExampleOptions& options); - - -#endif //ALL_CONSTRAINT_DEMO_H +class CommonExampleInterface* AllConstraintCreateFunc(struct CommonExampleOptions& options); +#endif //ALL_CONSTRAINT_DEMO_H diff --git a/examples/Constraints/ConstraintPhysicsSetup.cpp b/examples/Constraints/ConstraintPhysicsSetup.cpp index faf31e204..40ce53eda 100644 --- a/examples/Constraints/ConstraintPhysicsSetup.cpp +++ b/examples/Constraints/ConstraintPhysicsSetup.cpp @@ -1,11 +1,8 @@ #include "ConstraintPhysicsSetup.h" - #include "../CommonInterfaces/CommonRigidBodyBase.h" #include "../CommonInterfaces/CommonParameterInterface.h" - - struct ConstraintPhysicsSetup : public CommonRigidBodyBase { ConstraintPhysicsSetup(struct GUIHelperInterface* helper); @@ -14,21 +11,18 @@ struct ConstraintPhysicsSetup : public CommonRigidBodyBase virtual void stepSimulation(float deltaTime); - virtual void resetCamera() { float dist = 7; float pitch = -44; float yaw = 721; - float targetPos[3]={8,1,-11}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {8, 1, -11}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } - - }; ConstraintPhysicsSetup::ConstraintPhysicsSetup(struct GUIHelperInterface* helper) -:CommonRigidBodyBase(helper) + : CommonRigidBodyBase(helper) { } ConstraintPhysicsSetup::~ConstraintPhysicsSetup() @@ -36,63 +30,56 @@ ConstraintPhysicsSetup::~ConstraintPhysicsSetup() } static btScalar val; -static btScalar targetVel=0; -static btScalar maxImpulse=10000; -static btHingeAccumulatedAngleConstraint* spDoorHinge=0; -static btScalar actualHingeVelocity=0.f; +static btScalar targetVel = 0; +static btScalar maxImpulse = 10000; +static btHingeAccumulatedAngleConstraint* spDoorHinge = 0; +static btScalar actualHingeVelocity = 0.f; -static btVector3 btAxisA(0,1,0); +static btVector3 btAxisA(0, 1, 0); void ConstraintPhysicsSetup::stepSimulation(float deltaTime) { - val=spDoorHinge->getAccumulatedHingeAngle()*SIMD_DEGS_PER_RAD; - if (m_dynamicsWorld) + val = spDoorHinge->getAccumulatedHingeAngle() * SIMD_DEGS_PER_RAD; + if (m_dynamicsWorld) { - spDoorHinge->enableAngularMotor(true,targetVel,maxImpulse); + spDoorHinge->enableAngularMotor(true, targetVel, maxImpulse); - m_dynamicsWorld->stepSimulation(deltaTime,10,1./240.); + m_dynamicsWorld->stepSimulation(deltaTime, 10, 1. / 240.); + btHingeConstraint* hinge = spDoorHinge; - btHingeConstraint* hinge = spDoorHinge; + if (hinge) + { + const btRigidBody& bodyA = hinge->getRigidBodyA(); + const btRigidBody& bodyB = hinge->getRigidBodyB(); - if (hinge) - { + btTransform trA = bodyA.getWorldTransform(); + btVector3 angVelA = bodyA.getAngularVelocity(); + btVector3 angVelB = bodyB.getAngularVelocity(); - const btRigidBody& bodyA = hinge->getRigidBodyA(); - const btRigidBody& bodyB = hinge->getRigidBodyB(); - - - btTransform trA = bodyA.getWorldTransform(); - btVector3 angVelA = bodyA.getAngularVelocity(); - btVector3 angVelB = bodyB.getAngularVelocity(); - - { - btVector3 ax1 = trA.getBasis()*hinge->getFrameOffsetA().getBasis().getColumn(2); - btScalar vel = angVelA.dot(ax1); - vel -= angVelB.dot(ax1); - printf("hinge velocity (q) = %f\n", vel); - actualHingeVelocity=vel; - } - btVector3 ortho0,ortho1; - btPlaneSpace1(btAxisA,ortho0,ortho1); - { - - btScalar vel2 = angVelA.dot(ortho0); - vel2 -= angVelB.dot(ortho0); - printf("hinge orthogonal1 velocity (q) = %f\n", vel2); - } - { - - btScalar vel0 = angVelA.dot(ortho1); - vel0 -= angVelB.dot(ortho1); - printf("hinge orthogonal0 velocity (q) = %f\n", vel0); - } - } + { + btVector3 ax1 = trA.getBasis() * hinge->getFrameOffsetA().getBasis().getColumn(2); + btScalar vel = angVelA.dot(ax1); + vel -= angVelB.dot(ax1); + printf("hinge velocity (q) = %f\n", vel); + actualHingeVelocity = vel; + } + btVector3 ortho0, ortho1; + btPlaneSpace1(btAxisA, ortho0, ortho1); + { + btScalar vel2 = angVelA.dot(ortho0); + vel2 -= angVelB.dot(ortho0); + printf("hinge orthogonal1 velocity (q) = %f\n", vel2); + } + { + btScalar vel0 = angVelA.dot(ortho1); + vel0 -= angVelB.dot(ortho1); + printf("hinge orthogonal0 velocity (q) = %f\n", vel0); + } + } } } - - void ConstraintPhysicsSetup::initPhysics() { m_guiHelper->setUpAxis(1); @@ -100,62 +87,59 @@ void ConstraintPhysicsSetup::initPhysics() createEmptyDynamicsWorld(); m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); - int mode = btIDebugDraw::DBG_DrawWireframe - +btIDebugDraw::DBG_DrawConstraints - +btIDebugDraw::DBG_DrawConstraintLimits; + int mode = btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawConstraints + btIDebugDraw::DBG_DrawConstraintLimits; m_dynamicsWorld->getDebugDrawer()->setDebugMode(mode); + { + SliderParams slider("target vel", &targetVel); + slider.m_minVal = -4; + slider.m_maxVal = 4; + m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); + } - { - SliderParams slider("target vel",&targetVel); - slider.m_minVal=-4; - slider.m_maxVal=4; - m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); - } + { + SliderParams slider("max impulse", &maxImpulse); + slider.m_minVal = 0; + slider.m_maxVal = 1000; + m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); + } - { - SliderParams slider("max impulse",&maxImpulse); - slider.m_minVal=0; - slider.m_maxVal=1000; - m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); - } + { + SliderParams slider("actual vel", &actualHingeVelocity); + slider.m_minVal = -4; + slider.m_maxVal = 4; + m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); + } - { - SliderParams slider("actual vel",&actualHingeVelocity); - slider.m_minVal=-4; - slider.m_maxVal=4; - m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); - } + val = 1.f; + { + SliderParams slider("angle", &val); + slider.m_minVal = -720; + slider.m_maxVal = 720; + m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); + } - val=1.f; - { - SliderParams slider("angle",&val); - slider.m_minVal=-720; - slider.m_maxVal=720; - m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); - } - - { // create a door using hinge constraint attached to the world + { // create a door using hinge constraint attached to the world btCollisionShape* pDoorShape = new btBoxShape(btVector3(2.0f, 5.0f, 0.2f)); m_collisionShapes.push_back(pDoorShape); btTransform doorTrans; doorTrans.setIdentity(); doorTrans.setOrigin(btVector3(-5.0f, -2.0f, 0.0f)); - btRigidBody* pDoorBody = createRigidBody( 1.0, doorTrans, pDoorShape); + btRigidBody* pDoorBody = createRigidBody(1.0, doorTrans, pDoorShape); pDoorBody->setActivationState(DISABLE_DEACTIVATION); - const btVector3 btPivotA(10.f + 2.1f, -2.0f, 0.0f ); // right next to the door slightly outside + const btVector3 btPivotA(10.f + 2.1f, -2.0f, 0.0f); // right next to the door slightly outside - spDoorHinge = new btHingeAccumulatedAngleConstraint( *pDoorBody, btPivotA, btAxisA ); + spDoorHinge = new btHingeAccumulatedAngleConstraint(*pDoorBody, btPivotA, btAxisA); - m_dynamicsWorld->addConstraint(spDoorHinge); + m_dynamicsWorld->addConstraint(spDoorHinge); spDoorHinge->setDbgDrawSize(btScalar(5.f)); } - + m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } -class CommonExampleInterface* ConstraintCreateFunc(CommonExampleOptions& options) +class CommonExampleInterface* ConstraintCreateFunc(CommonExampleOptions& options) { return new ConstraintPhysicsSetup(options.m_guiHelper); } diff --git a/examples/Constraints/ConstraintPhysicsSetup.h b/examples/Constraints/ConstraintPhysicsSetup.h index 3cf28d126..0c032ea9d 100644 --- a/examples/Constraints/ConstraintPhysicsSetup.h +++ b/examples/Constraints/ConstraintPhysicsSetup.h @@ -1,6 +1,6 @@ #ifndef CONSTAINT_PHYSICS_SETUP_H #define CONSTAINT_PHYSICS_SETUP_H -class CommonExampleInterface* ConstraintCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* ConstraintCreateFunc(struct CommonExampleOptions& options); -#endif //CONSTAINT_PHYSICS_SETUP_H +#endif //CONSTAINT_PHYSICS_SETUP_H diff --git a/examples/Constraints/Dof6Spring2Setup.cpp b/examples/Constraints/Dof6Spring2Setup.cpp index a3fd5e8f4..d5216a623 100644 --- a/examples/Constraints/Dof6Spring2Setup.cpp +++ b/examples/Constraints/Dof6Spring2Setup.cpp @@ -9,37 +9,32 @@ #include "BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h" - #ifndef M_PI -#define M_PI 3.14159265358979323846 +#define M_PI 3.14159265358979323846 #endif #ifndef M_PI_2 -#define M_PI_2 1.57079632679489661923 +#define M_PI_2 1.57079632679489661923 #endif #ifndef M_PI_4 -#define M_PI_4 0.785398163397448309616 +#define M_PI_4 0.785398163397448309616 #endif - extern float g_additionalBodyMass; //comment this out to compare with original spring constraint #define USE_6DOF2 #ifdef USE_6DOF2 - #define CONSTRAINT_TYPE btGeneric6DofSpring2Constraint - #define EXTRAPARAMS +#define CONSTRAINT_TYPE btGeneric6DofSpring2Constraint +#define EXTRAPARAMS #else - #define CONSTRAINT_TYPE btGeneric6DofSpringConstraint - #define EXTRAPARAMS ,true +#define CONSTRAINT_TYPE btGeneric6DofSpringConstraint +#define EXTRAPARAMS , true #endif #include "../CommonInterfaces/CommonRigidBodyBase.h" - - - struct Dof6Spring2Setup : public CommonRigidBodyBase { struct Dof6Spring2SetupInternalData* m_data; @@ -57,40 +52,37 @@ struct Dof6Spring2Setup : public CommonRigidBodyBase float dist = 5; float pitch = -35; float yaw = 722; - float targetPos[3]={4,2,-11}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {4, 2, -11}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } }; - - struct Dof6Spring2SetupInternalData { - btRigidBody* m_TranslateSpringBody; - btRigidBody* m_TranslateSpringBody2; - btRigidBody* m_RotateSpringBody; - btRigidBody* m_RotateSpringBody2; - btRigidBody* m_BouncingTranslateBody; - btRigidBody* m_MotorBody; - btRigidBody* m_ServoMotorBody; - btRigidBody* m_ChainLeftBody; - btRigidBody* m_ChainRightBody; - CONSTRAINT_TYPE* m_ServoMotorConstraint; - CONSTRAINT_TYPE* m_ChainLeftConstraint; - CONSTRAINT_TYPE* m_ChainRightConstraint; + btRigidBody* m_TranslateSpringBody; + btRigidBody* m_TranslateSpringBody2; + btRigidBody* m_RotateSpringBody; + btRigidBody* m_RotateSpringBody2; + btRigidBody* m_BouncingTranslateBody; + btRigidBody* m_MotorBody; + btRigidBody* m_ServoMotorBody; + btRigidBody* m_ChainLeftBody; + btRigidBody* m_ChainRightBody; + CONSTRAINT_TYPE* m_ServoMotorConstraint; + CONSTRAINT_TYPE* m_ChainLeftConstraint; + CONSTRAINT_TYPE* m_ChainRightConstraint; - float mDt; unsigned int frameID; Dof6Spring2SetupInternalData() - : mDt(1./60.),frameID(0) + : mDt(1. / 60.), frameID(0) { } }; Dof6Spring2Setup::Dof6Spring2Setup(struct GUIHelperInterface* helper) - :CommonRigidBodyBase(helper) + : CommonRigidBodyBase(helper) { m_data = new Dof6Spring2SetupInternalData; } @@ -102,392 +94,397 @@ Dof6Spring2Setup::~Dof6Spring2Setup() void Dof6Spring2Setup::initPhysics() { // Setup the basic world - + m_guiHelper->setUpAxis(1); - m_collisionConfiguration = new btDefaultCollisionConfiguration(); - m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); - btVector3 worldAabbMin(-10000,-10000,-10000); - btVector3 worldAabbMax(10000,10000,10000); - m_broadphase = new btAxisSweep3 (worldAabbMin, worldAabbMax); + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + btVector3 worldAabbMin(-10000, -10000, -10000); + btVector3 worldAabbMax(10000, 10000, 10000); + m_broadphase = new btAxisSweep3(worldAabbMin, worldAabbMax); -/////// uncomment the corresponding line to test a solver. - //m_solver = new btSequentialImpulseConstraintSolver; - m_solver = new btNNCGConstraintSolver; - //m_solver = new btMLCPSolver(new btSolveProjectedGaussSeidel()); - //m_solver = new btMLCPSolver(new btDantzigSolver()); - //m_solver = new btMLCPSolver(new btLemkeSolver()); + /////// uncomment the corresponding line to test a solver. + //m_solver = new btSequentialImpulseConstraintSolver; + m_solver = new btNNCGConstraintSolver; + //m_solver = new btMLCPSolver(new btSolveProjectedGaussSeidel()); + //m_solver = new btMLCPSolver(new btDantzigSolver()); + //m_solver = new btMLCPSolver(new btLemkeSolver()); - m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); - m_dynamicsWorld->getDispatchInfo().m_useContinuous = true; + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration); + m_dynamicsWorld->getDispatchInfo().m_useContinuous = true; m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); - - m_dynamicsWorld->setGravity(btVector3(0,0,0)); - // Setup a big ground box - { - btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(5.),btScalar(200.))); - btTransform groundTransform; - groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0,-10,0)); + m_dynamicsWorld->setGravity(btVector3(0, 0, 0)); + + // Setup a big ground box + { + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.), btScalar(5.), btScalar(200.))); + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0, -10, 0)); #define CREATE_GROUND_COLLISION_OBJECT 1 #ifdef CREATE_GROUND_COLLISION_OBJECT - btCollisionObject* fixedGround = new btCollisionObject(); - fixedGround->setCollisionShape(groundShape); - fixedGround->setWorldTransform(groundTransform); - m_dynamicsWorld->addCollisionObject(fixedGround); + btCollisionObject* fixedGround = new btCollisionObject(); + fixedGround->setCollisionShape(groundShape); + fixedGround->setWorldTransform(groundTransform); + m_dynamicsWorld->addCollisionObject(fixedGround); #else - localCreateRigidBody(btScalar(0.),groundTransform,groundShape); -#endif //CREATE_GROUND_COLLISION_OBJECT - } + localCreateRigidBody(btScalar(0.), groundTransform, groundShape); +#endif //CREATE_GROUND_COLLISION_OBJECT + } - m_dynamicsWorld->getSolverInfo().m_numIterations = 100; + m_dynamicsWorld->getSolverInfo().m_numIterations = 100; - btCollisionShape* shape; - btVector3 localInertia(0,0,0); - btDefaultMotionState* motionState; - btTransform bodyTransform; - btScalar mass; - btTransform localA; - btTransform localB; - CONSTRAINT_TYPE* constraint; + btCollisionShape* shape; + btVector3 localInertia(0, 0, 0); + btDefaultMotionState* motionState; + btTransform bodyTransform; + btScalar mass; + btTransform localA; + btTransform localB; + CONSTRAINT_TYPE* constraint; - //static body centered in the origo - mass = 0.0; - shape= new btBoxShape(btVector3(0.5,0.5,0.5)); - localInertia = btVector3(0,0,0); + //static body centered in the origo + mass = 0.0; + shape = new btBoxShape(btVector3(0.5, 0.5, 0.5)); + localInertia = btVector3(0, 0, 0); + bodyTransform.setIdentity(); + motionState = new btDefaultMotionState(bodyTransform); + btRigidBody* staticBody = new btRigidBody(mass, motionState, shape, localInertia); + + /////////// box with undamped translate spring attached to static body + /////////// the box should oscillate left-to-right forever + { + mass = 1.0; + shape = new btBoxShape(btVector3(0.5, 0.5, 0.5)); + shape->calculateLocalInertia(mass, localInertia); bodyTransform.setIdentity(); + bodyTransform.setOrigin(btVector3(-2, 0, -5)); motionState = new btDefaultMotionState(bodyTransform); - btRigidBody* staticBody = new btRigidBody(mass,motionState,shape,localInertia); - -/////////// box with undamped translate spring attached to static body -/////////// the box should oscillate left-to-right forever - { - mass = 1.0; - shape= new btBoxShape(btVector3(0.5,0.5,0.5)); - shape->calculateLocalInertia(mass,localInertia); - bodyTransform.setIdentity(); - bodyTransform.setOrigin(btVector3(-2,0,-5)); - motionState = new btDefaultMotionState(bodyTransform); - m_data->m_TranslateSpringBody = new btRigidBody(mass,motionState,shape,localInertia); - m_data->m_TranslateSpringBody->setActivationState(DISABLE_DEACTIVATION); - m_dynamicsWorld->addRigidBody(m_data->m_TranslateSpringBody); - localA.setIdentity();localA.getOrigin() = btVector3(0,0,-5); - localB.setIdentity(); - constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_TranslateSpringBody, localA, localB EXTRAPARAMS); - constraint->setLimit(0, 1,-1); - constraint->setLimit(1, 0, 0); - constraint->setLimit(2, 0, 0); - constraint->setLimit(3, 0, 0); - constraint->setLimit(4, 0, 0); - constraint->setLimit(5, 0, 0); - constraint->enableSpring(0, true); - constraint->setStiffness(0, 100); - #ifdef USE_6DOF2 - constraint->setDamping(0, 0); - #else - constraint->setDamping(0, 1); - #endif - constraint->setEquilibriumPoint(0, 0); - constraint->setDbgDrawSize(btScalar(2.f)); - m_dynamicsWorld->addConstraint(constraint, true); - } - -/////////// box with rotate spring, attached to static body -/////////// box should swing (rotate) left-to-right forever - { - mass = 1.0; - shape= new btBoxShape(btVector3(0.5,0.5,0.5)); - shape->calculateLocalInertia(mass,localInertia); - bodyTransform.setIdentity(); - bodyTransform.getBasis().setEulerZYX(0,0,M_PI_2); - motionState = new btDefaultMotionState(bodyTransform); - m_data->m_RotateSpringBody = new btRigidBody(mass,motionState,shape,localInertia); - m_data->m_RotateSpringBody->setActivationState(DISABLE_DEACTIVATION); - m_dynamicsWorld->addRigidBody(m_data->m_RotateSpringBody); - localA.setIdentity();localA.getOrigin() = btVector3(0,0,0); - localB.setIdentity();localB.setOrigin(btVector3(0,0.5,0)); - constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_RotateSpringBody, localA, localB EXTRAPARAMS); - constraint->setLimit(0, 0, 0); - constraint->setLimit(1, 0, 0); - constraint->setLimit(2, 0, 0); - constraint->setLimit(3, 0, 0); - constraint->setLimit(4, 0, 0); - constraint->setLimit(5, 1, -1); - constraint->enableSpring(5, true); - constraint->setStiffness(5, 100); - #ifdef USE_6DOF2 - constraint->setDamping(5, 0); - #else - constraint->setDamping(5, 1); - #endif - constraint->setEquilibriumPoint(0, 0); - constraint->setDbgDrawSize(btScalar(2.f)); - m_dynamicsWorld->addConstraint(constraint, true); - } - -/////////// box with bouncing constraint, translation is bounced at the positive x limit, but not at the negative limit -/////////// bouncing can not be set independently at low and high limits, so two constraints will be created: one that defines the low (non bouncing) limit, and one that defines the high (bouncing) limit -/////////// the box should move to the left (as an impulse will be applied to it periodically) until it reaches its limit, then bounce back - { - mass = 1.0; - shape= new btBoxShape(btVector3(0.5,0.5,0.5)); - shape->calculateLocalInertia(mass,localInertia); - bodyTransform.setIdentity(); - bodyTransform.setOrigin(btVector3(0,0,-3)); - motionState = new btDefaultMotionState(bodyTransform); - m_data->m_BouncingTranslateBody = new btRigidBody(mass,motionState,shape,localInertia); - m_data->m_BouncingTranslateBody->setActivationState(DISABLE_DEACTIVATION); - m_data->m_BouncingTranslateBody->setDeactivationTime(btScalar(20000000)); - m_dynamicsWorld->addRigidBody(m_data->m_BouncingTranslateBody); - localA.setIdentity();localA.getOrigin() = btVector3(0,0,0); - localB.setIdentity(); - constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_BouncingTranslateBody, localA, localB EXTRAPARAMS); - constraint->setLimit(0, -2, SIMD_INFINITY); - constraint->setLimit(1, 0, 0); - constraint->setLimit(2, -3, -3); - constraint->setLimit(3, 0, 0); - constraint->setLimit(4, 0, 0); - constraint->setLimit(5, 0, 0); - #ifdef USE_6DOF2 - constraint->setBounce(0,0); - #else //bounce is named restitution in 6dofspring, but not implemented for translational limit motor, so the following line has no effect - constraint->getTranslationalLimitMotor()->m_restitution = 0.0; - #endif - constraint->setParam(BT_CONSTRAINT_STOP_ERP,0.995,0); - constraint->setParam(BT_CONSTRAINT_STOP_CFM,0.0,0); - constraint->setDbgDrawSize(btScalar(2.f)); - m_dynamicsWorld->addConstraint(constraint, true); - constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_BouncingTranslateBody, localA, localB EXTRAPARAMS); - constraint->setLimit(0, -SIMD_INFINITY, 2); - constraint->setLimit(1, 0, 0); - constraint->setLimit(2, -3, -3); - constraint->setLimit(3, 0, 0); - constraint->setLimit(4, 0, 0); - constraint->setLimit(5, 0, 0); - #ifdef USE_6DOF2 - constraint->setBounce(0,1); - #else //bounce is named restitution in 6dofspring, but not implemented for translational limit motor, so the following line has no effect - constraint->getTranslationalLimitMotor()->m_restitution = 1.0; - #endif - constraint->setParam(BT_CONSTRAINT_STOP_ERP,0.995,0); - constraint->setParam(BT_CONSTRAINT_STOP_CFM,0.0,0); - constraint->setDbgDrawSize(btScalar(2.f)); - m_dynamicsWorld->addConstraint(constraint, true); - } - -/////////// box with rotational motor, attached to static body -/////////// the box should rotate around the y axis - { - mass = 1.0; - shape= new btBoxShape(btVector3(0.5,0.5,0.5)); - shape->calculateLocalInertia(mass,localInertia); - bodyTransform.setIdentity(); - bodyTransform.setOrigin(btVector3(4,0,0)); - motionState = new btDefaultMotionState(bodyTransform); - m_data->m_MotorBody = new btRigidBody(mass,motionState,shape,localInertia); - m_data->m_MotorBody->setActivationState(DISABLE_DEACTIVATION); - m_dynamicsWorld->addRigidBody(m_data->m_MotorBody); - localA.setIdentity();localA.getOrigin() = btVector3(4,0,0); - localB.setIdentity(); - constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_MotorBody, localA, localB EXTRAPARAMS); - constraint->setLimit(0, 0, 0); - constraint->setLimit(1, 0, 0); - constraint->setLimit(2, 0, 0); - constraint->setLimit(3, 0, 0); - constraint->setLimit(4, 0, 0); - constraint->setLimit(5, 1,-1); - #ifdef USE_6DOF2 - constraint->enableMotor(5,true); - constraint->setTargetVelocity(5,3.f); - constraint->setMaxMotorForce(5,600.f); - #else - constraint->getRotationalLimitMotor(2)->m_enableMotor = true; - constraint->getRotationalLimitMotor(2)->m_targetVelocity = 3.f; - constraint->getRotationalLimitMotor(2)->m_maxMotorForce = 600.f; - #endif - constraint->setDbgDrawSize(btScalar(2.f)); - m_dynamicsWorld->addConstraint(constraint, true); - } - -/////////// box with rotational servo motor, attached to static body -/////////// the box should rotate around the y axis until it reaches its target -/////////// the target will be negated periodically - { - mass = 1.0; - shape= new btBoxShape(btVector3(0.5,0.5,0.5)); - shape->calculateLocalInertia(mass,localInertia); - bodyTransform.setIdentity(); - bodyTransform.setOrigin(btVector3(7,0,0)); - motionState = new btDefaultMotionState(bodyTransform); - m_data->m_ServoMotorBody = new btRigidBody(mass,motionState,shape,localInertia); - m_data->m_ServoMotorBody->setActivationState(DISABLE_DEACTIVATION); - m_dynamicsWorld->addRigidBody(m_data->m_ServoMotorBody); - localA.setIdentity();localA.getOrigin() = btVector3(7,0,0); - localB.setIdentity(); - constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_ServoMotorBody, localA, localB EXTRAPARAMS); - constraint->setLimit(0, 0, 0); - constraint->setLimit(1, 0, 0); - constraint->setLimit(2, 0, 0); - constraint->setLimit(3, 0, 0); - constraint->setLimit(4, 0, 0); - constraint->setLimit(5, 1,-1); - #ifdef USE_6DOF2 - constraint->enableMotor(5,true); - constraint->setTargetVelocity(5,3.f); - constraint->setMaxMotorForce(5,600.f); - constraint->setServo(5,true); - constraint->setServoTarget(5, M_PI_2); - #else - constraint->getRotationalLimitMotor(2)->m_enableMotor = true; - constraint->getRotationalLimitMotor(2)->m_targetVelocity = 3.f; - constraint->getRotationalLimitMotor(2)->m_maxMotorForce = 600.f; - //servo motor is not implemented in 6dofspring constraint - #endif - constraint->setDbgDrawSize(btScalar(2.f)); - m_dynamicsWorld->addConstraint(constraint, true); - m_data->m_ServoMotorConstraint = constraint; - } - -////////// chain of boxes linked together with fully limited rotational and translational constraints -////////// the chain will be pulled to the left and to the right periodically. They should strictly stick together. - { - btScalar limitConstraintStrength = 0.6; - int bodycount = 10; - btRigidBody* prevBody = 0; - for(int i = 0; i < bodycount; ++i) - { - mass = 1.0; - shape= new btBoxShape(btVector3(0.5,0.5,0.5)); - shape->calculateLocalInertia(mass,localInertia); - bodyTransform.setIdentity(); - bodyTransform.setOrigin(btVector3(- i,0,3)); - motionState = new btDefaultMotionState(bodyTransform); - btRigidBody* body = new btRigidBody(mass,motionState,shape,localInertia); - body->setActivationState(DISABLE_DEACTIVATION); - m_dynamicsWorld->addRigidBody(body); - if(prevBody != 0) - { - localB.setIdentity(); - localB.setOrigin(btVector3(0.5,0,0)); - btTransform localA; - localA.setIdentity(); - localA.setOrigin(btVector3(-0.5,0,0)); - CONSTRAINT_TYPE* constraint = new CONSTRAINT_TYPE(*prevBody, *body, localA, localB EXTRAPARAMS); - constraint->setLimit(0, -0.01, 0.01); - constraint->setLimit(1, 0, 0); - constraint->setLimit(2, 0, 0); - constraint->setLimit(3, 0, 0); - constraint->setLimit(4, 0, 0); - constraint->setLimit(5, 0, 0); - for(int a = 0; a < 6; ++a) - { - constraint->setParam(BT_CONSTRAINT_STOP_ERP,0.9,a); - constraint->setParam(BT_CONSTRAINT_STOP_CFM,0.0,a); - } - constraint->setDbgDrawSize(btScalar(1.f)); - m_dynamicsWorld->addConstraint(constraint, true); - - if(i < bodycount - 1) - { - localA.setIdentity();localA.getOrigin() = btVector3(0,0,3); - localB.setIdentity(); - CONSTRAINT_TYPE* constraintZY = new CONSTRAINT_TYPE(*staticBody, *body, localA, localB EXTRAPARAMS); - constraintZY->setLimit(0, 1, -1); - constraintZY->setDbgDrawSize(btScalar(1.f)); - m_dynamicsWorld->addConstraint(constraintZY, true); - - } - } - else - { - localA.setIdentity();localA.getOrigin() = btVector3(bodycount,0,3); - localB.setIdentity(); - localB.setOrigin(btVector3(0,0,0)); - m_data->m_ChainLeftBody = body; - m_data->m_ChainLeftConstraint = new CONSTRAINT_TYPE(*staticBody, *body, localA, localB EXTRAPARAMS); - m_data->m_ChainLeftConstraint->setLimit(3,0,0); - m_data->m_ChainLeftConstraint->setLimit(4,0,0); - m_data->m_ChainLeftConstraint->setLimit(5,0,0); - for(int a = 0; a < 6; ++a) - { - m_data->m_ChainLeftConstraint->setParam(BT_CONSTRAINT_STOP_ERP,limitConstraintStrength,a); - m_data->m_ChainLeftConstraint->setParam(BT_CONSTRAINT_STOP_CFM,0.0,a); - } - m_data->m_ChainLeftConstraint->setDbgDrawSize(btScalar(1.f)); - m_dynamicsWorld->addConstraint(m_data->m_ChainLeftConstraint, true); - } - prevBody = body; - } - m_data->m_ChainRightBody = prevBody; - localA.setIdentity();localA.getOrigin() = btVector3(-bodycount,0,3); - localB.setIdentity(); - localB.setOrigin(btVector3(0,0,0)); - m_data->m_ChainRightConstraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_ChainRightBody, localA, localB EXTRAPARAMS); - m_data->m_ChainRightConstraint->setLimit(3,0,0); - m_data->m_ChainRightConstraint->setLimit(4,0,0); - m_data->m_ChainRightConstraint->setLimit(5,0,0); - for(int a = 0; a < 6; ++a) - { - m_data->m_ChainRightConstraint->setParam(BT_CONSTRAINT_STOP_ERP,limitConstraintStrength,a); - m_data->m_ChainRightConstraint->setParam(BT_CONSTRAINT_STOP_CFM,0.0,a); - } - } - m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); -} - - -void Dof6Spring2Setup::animate() -{ - -/////// servo motor: flip its target periodically + m_data->m_TranslateSpringBody = new btRigidBody(mass, motionState, shape, localInertia); + m_data->m_TranslateSpringBody->setActivationState(DISABLE_DEACTIVATION); + m_dynamicsWorld->addRigidBody(m_data->m_TranslateSpringBody); + localA.setIdentity(); + localA.getOrigin() = btVector3(0, 0, -5); + localB.setIdentity(); + constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_TranslateSpringBody, localA, localB EXTRAPARAMS); + constraint->setLimit(0, 1, -1); + constraint->setLimit(1, 0, 0); + constraint->setLimit(2, 0, 0); + constraint->setLimit(3, 0, 0); + constraint->setLimit(4, 0, 0); + constraint->setLimit(5, 0, 0); + constraint->enableSpring(0, true); + constraint->setStiffness(0, 100); #ifdef USE_6DOF2 - static float servoNextFrame = -1; - if(servoNextFrame < 0) - { - m_data->m_ServoMotorConstraint->getRotationalLimitMotor(2)->m_servoTarget *= -1; - servoNextFrame = 3.0; - } - servoNextFrame -= m_data->mDt; + constraint->setDamping(0, 0); +#else + constraint->setDamping(0, 1); #endif + constraint->setEquilibriumPoint(0, 0); + constraint->setDbgDrawSize(btScalar(2.f)); + m_dynamicsWorld->addConstraint(constraint, true); + } -/////// constraint chain: pull the chain left and right periodically - static float chainNextFrame = -1; - static bool left = true; - if(chainNextFrame < 0) + /////////// box with rotate spring, attached to static body + /////////// box should swing (rotate) left-to-right forever + { + mass = 1.0; + shape = new btBoxShape(btVector3(0.5, 0.5, 0.5)); + shape->calculateLocalInertia(mass, localInertia); + bodyTransform.setIdentity(); + bodyTransform.getBasis().setEulerZYX(0, 0, M_PI_2); + motionState = new btDefaultMotionState(bodyTransform); + m_data->m_RotateSpringBody = new btRigidBody(mass, motionState, shape, localInertia); + m_data->m_RotateSpringBody->setActivationState(DISABLE_DEACTIVATION); + m_dynamicsWorld->addRigidBody(m_data->m_RotateSpringBody); + localA.setIdentity(); + localA.getOrigin() = btVector3(0, 0, 0); + localB.setIdentity(); + localB.setOrigin(btVector3(0, 0.5, 0)); + constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_RotateSpringBody, localA, localB EXTRAPARAMS); + constraint->setLimit(0, 0, 0); + constraint->setLimit(1, 0, 0); + constraint->setLimit(2, 0, 0); + constraint->setLimit(3, 0, 0); + constraint->setLimit(4, 0, 0); + constraint->setLimit(5, 1, -1); + constraint->enableSpring(5, true); + constraint->setStiffness(5, 100); +#ifdef USE_6DOF2 + constraint->setDamping(5, 0); +#else + constraint->setDamping(5, 1); +#endif + constraint->setEquilibriumPoint(0, 0); + constraint->setDbgDrawSize(btScalar(2.f)); + m_dynamicsWorld->addConstraint(constraint, true); + } + + /////////// box with bouncing constraint, translation is bounced at the positive x limit, but not at the negative limit + /////////// bouncing can not be set independently at low and high limits, so two constraints will be created: one that defines the low (non bouncing) limit, and one that defines the high (bouncing) limit + /////////// the box should move to the left (as an impulse will be applied to it periodically) until it reaches its limit, then bounce back + { + mass = 1.0; + shape = new btBoxShape(btVector3(0.5, 0.5, 0.5)); + shape->calculateLocalInertia(mass, localInertia); + bodyTransform.setIdentity(); + bodyTransform.setOrigin(btVector3(0, 0, -3)); + motionState = new btDefaultMotionState(bodyTransform); + m_data->m_BouncingTranslateBody = new btRigidBody(mass, motionState, shape, localInertia); + m_data->m_BouncingTranslateBody->setActivationState(DISABLE_DEACTIVATION); + m_data->m_BouncingTranslateBody->setDeactivationTime(btScalar(20000000)); + m_dynamicsWorld->addRigidBody(m_data->m_BouncingTranslateBody); + localA.setIdentity(); + localA.getOrigin() = btVector3(0, 0, 0); + localB.setIdentity(); + constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_BouncingTranslateBody, localA, localB EXTRAPARAMS); + constraint->setLimit(0, -2, SIMD_INFINITY); + constraint->setLimit(1, 0, 0); + constraint->setLimit(2, -3, -3); + constraint->setLimit(3, 0, 0); + constraint->setLimit(4, 0, 0); + constraint->setLimit(5, 0, 0); +#ifdef USE_6DOF2 + constraint->setBounce(0, 0); +#else //bounce is named restitution in 6dofspring, but not implemented for translational limit motor, so the following line has no effect + constraint->getTranslationalLimitMotor()->m_restitution = 0.0; +#endif + constraint->setParam(BT_CONSTRAINT_STOP_ERP, 0.995, 0); + constraint->setParam(BT_CONSTRAINT_STOP_CFM, 0.0, 0); + constraint->setDbgDrawSize(btScalar(2.f)); + m_dynamicsWorld->addConstraint(constraint, true); + constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_BouncingTranslateBody, localA, localB EXTRAPARAMS); + constraint->setLimit(0, -SIMD_INFINITY, 2); + constraint->setLimit(1, 0, 0); + constraint->setLimit(2, -3, -3); + constraint->setLimit(3, 0, 0); + constraint->setLimit(4, 0, 0); + constraint->setLimit(5, 0, 0); +#ifdef USE_6DOF2 + constraint->setBounce(0, 1); +#else //bounce is named restitution in 6dofspring, but not implemented for translational limit motor, so the following line has no effect + constraint->getTranslationalLimitMotor()->m_restitution = 1.0; +#endif + constraint->setParam(BT_CONSTRAINT_STOP_ERP, 0.995, 0); + constraint->setParam(BT_CONSTRAINT_STOP_CFM, 0.0, 0); + constraint->setDbgDrawSize(btScalar(2.f)); + m_dynamicsWorld->addConstraint(constraint, true); + } + + /////////// box with rotational motor, attached to static body + /////////// the box should rotate around the y axis + { + mass = 1.0; + shape = new btBoxShape(btVector3(0.5, 0.5, 0.5)); + shape->calculateLocalInertia(mass, localInertia); + bodyTransform.setIdentity(); + bodyTransform.setOrigin(btVector3(4, 0, 0)); + motionState = new btDefaultMotionState(bodyTransform); + m_data->m_MotorBody = new btRigidBody(mass, motionState, shape, localInertia); + m_data->m_MotorBody->setActivationState(DISABLE_DEACTIVATION); + m_dynamicsWorld->addRigidBody(m_data->m_MotorBody); + localA.setIdentity(); + localA.getOrigin() = btVector3(4, 0, 0); + localB.setIdentity(); + constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_MotorBody, localA, localB EXTRAPARAMS); + constraint->setLimit(0, 0, 0); + constraint->setLimit(1, 0, 0); + constraint->setLimit(2, 0, 0); + constraint->setLimit(3, 0, 0); + constraint->setLimit(4, 0, 0); + constraint->setLimit(5, 1, -1); +#ifdef USE_6DOF2 + constraint->enableMotor(5, true); + constraint->setTargetVelocity(5, 3.f); + constraint->setMaxMotorForce(5, 600.f); +#else + constraint->getRotationalLimitMotor(2)->m_enableMotor = true; + constraint->getRotationalLimitMotor(2)->m_targetVelocity = 3.f; + constraint->getRotationalLimitMotor(2)->m_maxMotorForce = 600.f; +#endif + constraint->setDbgDrawSize(btScalar(2.f)); + m_dynamicsWorld->addConstraint(constraint, true); + } + + /////////// box with rotational servo motor, attached to static body + /////////// the box should rotate around the y axis until it reaches its target + /////////// the target will be negated periodically + { + mass = 1.0; + shape = new btBoxShape(btVector3(0.5, 0.5, 0.5)); + shape->calculateLocalInertia(mass, localInertia); + bodyTransform.setIdentity(); + bodyTransform.setOrigin(btVector3(7, 0, 0)); + motionState = new btDefaultMotionState(bodyTransform); + m_data->m_ServoMotorBody = new btRigidBody(mass, motionState, shape, localInertia); + m_data->m_ServoMotorBody->setActivationState(DISABLE_DEACTIVATION); + m_dynamicsWorld->addRigidBody(m_data->m_ServoMotorBody); + localA.setIdentity(); + localA.getOrigin() = btVector3(7, 0, 0); + localB.setIdentity(); + constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_ServoMotorBody, localA, localB EXTRAPARAMS); + constraint->setLimit(0, 0, 0); + constraint->setLimit(1, 0, 0); + constraint->setLimit(2, 0, 0); + constraint->setLimit(3, 0, 0); + constraint->setLimit(4, 0, 0); + constraint->setLimit(5, 1, -1); +#ifdef USE_6DOF2 + constraint->enableMotor(5, true); + constraint->setTargetVelocity(5, 3.f); + constraint->setMaxMotorForce(5, 600.f); + constraint->setServo(5, true); + constraint->setServoTarget(5, M_PI_2); +#else + constraint->getRotationalLimitMotor(2)->m_enableMotor = true; + constraint->getRotationalLimitMotor(2)->m_targetVelocity = 3.f; + constraint->getRotationalLimitMotor(2)->m_maxMotorForce = 600.f; + //servo motor is not implemented in 6dofspring constraint +#endif + constraint->setDbgDrawSize(btScalar(2.f)); + m_dynamicsWorld->addConstraint(constraint, true); + m_data->m_ServoMotorConstraint = constraint; + } + + ////////// chain of boxes linked together with fully limited rotational and translational constraints + ////////// the chain will be pulled to the left and to the right periodically. They should strictly stick together. + { + btScalar limitConstraintStrength = 0.6; + int bodycount = 10; + btRigidBody* prevBody = 0; + for (int i = 0; i < bodycount; ++i) { - if(!left) + mass = 1.0; + shape = new btBoxShape(btVector3(0.5, 0.5, 0.5)); + shape->calculateLocalInertia(mass, localInertia); + bodyTransform.setIdentity(); + bodyTransform.setOrigin(btVector3(-i, 0, 3)); + motionState = new btDefaultMotionState(bodyTransform); + btRigidBody* body = new btRigidBody(mass, motionState, shape, localInertia); + body->setActivationState(DISABLE_DEACTIVATION); + m_dynamicsWorld->addRigidBody(body); + if (prevBody != 0) { - m_data->m_ChainRightBody->setActivationState(ACTIVE_TAG); - m_dynamicsWorld->removeConstraint(m_data->m_ChainRightConstraint); - m_data->m_ChainLeftConstraint->setDbgDrawSize(btScalar(2.f)); - m_dynamicsWorld->addConstraint(m_data->m_ChainLeftConstraint, true); + localB.setIdentity(); + localB.setOrigin(btVector3(0.5, 0, 0)); + btTransform localA; + localA.setIdentity(); + localA.setOrigin(btVector3(-0.5, 0, 0)); + CONSTRAINT_TYPE* constraint = new CONSTRAINT_TYPE(*prevBody, *body, localA, localB EXTRAPARAMS); + constraint->setLimit(0, -0.01, 0.01); + constraint->setLimit(1, 0, 0); + constraint->setLimit(2, 0, 0); + constraint->setLimit(3, 0, 0); + constraint->setLimit(4, 0, 0); + constraint->setLimit(5, 0, 0); + for (int a = 0; a < 6; ++a) + { + constraint->setParam(BT_CONSTRAINT_STOP_ERP, 0.9, a); + constraint->setParam(BT_CONSTRAINT_STOP_CFM, 0.0, a); + } + constraint->setDbgDrawSize(btScalar(1.f)); + m_dynamicsWorld->addConstraint(constraint, true); + + if (i < bodycount - 1) + { + localA.setIdentity(); + localA.getOrigin() = btVector3(0, 0, 3); + localB.setIdentity(); + CONSTRAINT_TYPE* constraintZY = new CONSTRAINT_TYPE(*staticBody, *body, localA, localB EXTRAPARAMS); + constraintZY->setLimit(0, 1, -1); + constraintZY->setDbgDrawSize(btScalar(1.f)); + m_dynamicsWorld->addConstraint(constraintZY, true); + } } else { - m_data->m_ChainLeftBody->setActivationState(ACTIVE_TAG); - m_dynamicsWorld->removeConstraint(m_data->m_ChainLeftConstraint); - m_data->m_ChainRightConstraint->setDbgDrawSize(btScalar(2.f)); - m_dynamicsWorld->addConstraint(m_data->m_ChainRightConstraint, true); + localA.setIdentity(); + localA.getOrigin() = btVector3(bodycount, 0, 3); + localB.setIdentity(); + localB.setOrigin(btVector3(0, 0, 0)); + m_data->m_ChainLeftBody = body; + m_data->m_ChainLeftConstraint = new CONSTRAINT_TYPE(*staticBody, *body, localA, localB EXTRAPARAMS); + m_data->m_ChainLeftConstraint->setLimit(3, 0, 0); + m_data->m_ChainLeftConstraint->setLimit(4, 0, 0); + m_data->m_ChainLeftConstraint->setLimit(5, 0, 0); + for (int a = 0; a < 6; ++a) + { + m_data->m_ChainLeftConstraint->setParam(BT_CONSTRAINT_STOP_ERP, limitConstraintStrength, a); + m_data->m_ChainLeftConstraint->setParam(BT_CONSTRAINT_STOP_CFM, 0.0, a); + } + m_data->m_ChainLeftConstraint->setDbgDrawSize(btScalar(1.f)); + m_dynamicsWorld->addConstraint(m_data->m_ChainLeftConstraint, true); } - chainNextFrame = 3.0; - left = !left; + prevBody = body; } - chainNextFrame -= m_data->mDt; - -/////// bouncing constraint: push the box periodically - m_data->m_BouncingTranslateBody->setActivationState(ACTIVE_TAG); - static float bounceNextFrame = -1; - if(bounceNextFrame < 0) + m_data->m_ChainRightBody = prevBody; + localA.setIdentity(); + localA.getOrigin() = btVector3(-bodycount, 0, 3); + localB.setIdentity(); + localB.setOrigin(btVector3(0, 0, 0)); + m_data->m_ChainRightConstraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_ChainRightBody, localA, localB EXTRAPARAMS); + m_data->m_ChainRightConstraint->setLimit(3, 0, 0); + m_data->m_ChainRightConstraint->setLimit(4, 0, 0); + m_data->m_ChainRightConstraint->setLimit(5, 0, 0); + for (int a = 0; a < 6; ++a) { - m_data->m_BouncingTranslateBody->applyCentralImpulse(btVector3(10,0,0)); - bounceNextFrame = 3.0; + m_data->m_ChainRightConstraint->setParam(BT_CONSTRAINT_STOP_ERP, limitConstraintStrength, a); + m_data->m_ChainRightConstraint->setParam(BT_CONSTRAINT_STOP_CFM, 0.0, a); } - bounceNextFrame -= m_data->mDt; - - m_data->frameID++; + } + m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } +void Dof6Spring2Setup::animate() +{ +/////// servo motor: flip its target periodically +#ifdef USE_6DOF2 + static float servoNextFrame = -1; + if (servoNextFrame < 0) + { + m_data->m_ServoMotorConstraint->getRotationalLimitMotor(2)->m_servoTarget *= -1; + servoNextFrame = 3.0; + } + servoNextFrame -= m_data->mDt; +#endif + + /////// constraint chain: pull the chain left and right periodically + static float chainNextFrame = -1; + static bool left = true; + if (chainNextFrame < 0) + { + if (!left) + { + m_data->m_ChainRightBody->setActivationState(ACTIVE_TAG); + m_dynamicsWorld->removeConstraint(m_data->m_ChainRightConstraint); + m_data->m_ChainLeftConstraint->setDbgDrawSize(btScalar(2.f)); + m_dynamicsWorld->addConstraint(m_data->m_ChainLeftConstraint, true); + } + else + { + m_data->m_ChainLeftBody->setActivationState(ACTIVE_TAG); + m_dynamicsWorld->removeConstraint(m_data->m_ChainLeftConstraint); + m_data->m_ChainRightConstraint->setDbgDrawSize(btScalar(2.f)); + m_dynamicsWorld->addConstraint(m_data->m_ChainRightConstraint, true); + } + chainNextFrame = 3.0; + left = !left; + } + chainNextFrame -= m_data->mDt; + + /////// bouncing constraint: push the box periodically + m_data->m_BouncingTranslateBody->setActivationState(ACTIVE_TAG); + static float bounceNextFrame = -1; + if (bounceNextFrame < 0) + { + m_data->m_BouncingTranslateBody->applyCentralImpulse(btVector3(10, 0, 0)); + bounceNextFrame = 3.0; + } + bounceNextFrame -= m_data->mDt; + + m_data->frameID++; +} void Dof6Spring2Setup::stepSimulation(float deltaTime) { @@ -495,7 +492,7 @@ void Dof6Spring2Setup::stepSimulation(float deltaTime) m_dynamicsWorld->stepSimulation(deltaTime); } -class CommonExampleInterface* Dof6Spring2CreateFunc( CommonExampleOptions& options) +class CommonExampleInterface* Dof6Spring2CreateFunc(CommonExampleOptions& options) { return new Dof6Spring2Setup(options.m_guiHelper); } diff --git a/examples/Constraints/Dof6Spring2Setup.h b/examples/Constraints/Dof6Spring2Setup.h index 3c7dc92b8..66bda387a 100644 --- a/examples/Constraints/Dof6Spring2Setup.h +++ b/examples/Constraints/Dof6Spring2Setup.h @@ -1,6 +1,6 @@ #ifndef GENERIC_6DOF_SPRING2_CONSTRAINT_DEMO_H #define GENERIC_6DOF_SPRING2_CONSTRAINT_DEMO_H -class CommonExampleInterface* Dof6Spring2CreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* Dof6Spring2CreateFunc(struct CommonExampleOptions& options); -#endif //GENERIC_6DOF_SPRING2_CONSTRAINT_DEMO_H +#endif //GENERIC_6DOF_SPRING2_CONSTRAINT_DEMO_H diff --git a/examples/Constraints/TestHingeTorque.cpp b/examples/Constraints/TestHingeTorque.cpp index b22cfb55e..f422e219e 100644 --- a/examples/Constraints/TestHingeTorque.cpp +++ b/examples/Constraints/TestHingeTorque.cpp @@ -1,6 +1,5 @@ #include "TestHingeTorque.h" - #include "../CommonInterfaces/CommonRigidBodyBase.h" #include "../CommonInterfaces/CommonParameterInterface.h" @@ -10,99 +9,88 @@ static btScalar radius(0.2); struct TestHingeTorque : public CommonRigidBodyBase { - bool m_once; - btAlignedObjectArray m_jointFeedback; + bool m_once; + btAlignedObjectArray m_jointFeedback; TestHingeTorque(struct GUIHelperInterface* helper); - virtual ~ TestHingeTorque(); + virtual ~TestHingeTorque(); virtual void initPhysics(); virtual void stepSimulation(float deltaTime); - virtual void resetCamera() { - - float dist = 5; - float pitch = -21; - float yaw = 270; - float targetPos[3]={-1.34,3.4,-0.44}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float dist = 5; + float pitch = -21; + float yaw = 270; + float targetPos[3] = {-1.34, 3.4, -0.44}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } - - }; TestHingeTorque::TestHingeTorque(struct GUIHelperInterface* helper) -:CommonRigidBodyBase(helper), -m_once(true) + : CommonRigidBodyBase(helper), + m_once(true) { } -TestHingeTorque::~ TestHingeTorque() +TestHingeTorque::~TestHingeTorque() { - for (int i=0;igetConstraint(0); - - btRigidBody& bodyA = hinge->getRigidBodyA(); - btTransform trA = bodyA.getWorldTransform(); - btVector3 hingeAxisInWorld = trA.getBasis()*hinge->getFrameOffsetA().getBasis().getColumn(2); - hinge->getRigidBodyA().applyTorque(-hingeAxisInWorld*10); - hinge->getRigidBodyB().applyTorque(hingeAxisInWorld*10); - - } - - m_dynamicsWorld->stepSimulation(1./240,0); - + if (0) //m_once) + { + m_once = false; + btHingeConstraint* hinge = (btHingeConstraint*)m_dynamicsWorld->getConstraint(0); + + btRigidBody& bodyA = hinge->getRigidBodyA(); + btTransform trA = bodyA.getWorldTransform(); + btVector3 hingeAxisInWorld = trA.getBasis() * hinge->getFrameOffsetA().getBasis().getColumn(2); + hinge->getRigidBodyA().applyTorque(-hingeAxisInWorld * 10); + hinge->getRigidBodyB().applyTorque(hingeAxisInWorld * 10); + } + + m_dynamicsWorld->stepSimulation(1. / 240, 0); + static int count = 0; - if ((count& 0x0f)==0) + if ((count & 0x0f) == 0) { btRigidBody* base = btRigidBody::upcast(m_dynamicsWorld->getCollisionObjectArray()[0]); - - b3Printf("base angvel = %f,%f,%f",base->getAngularVelocity()[0], + + b3Printf("base angvel = %f,%f,%f", base->getAngularVelocity()[0], base->getAngularVelocity()[1], - + base->getAngularVelocity()[2]); - + btRigidBody* child = btRigidBody::upcast(m_dynamicsWorld->getCollisionObjectArray()[1]); - - - b3Printf("child angvel = %f,%f,%f",child->getAngularVelocity()[0], + + b3Printf("child angvel = %f,%f,%f", child->getAngularVelocity()[0], child->getAngularVelocity()[1], child->getAngularVelocity()[2]); - - for (int i=0;im_appliedForceBodyB.x(), - m_jointFeedback[i]->m_appliedForceBodyB.y(), - m_jointFeedback[i]->m_appliedForceBodyB.z(), - m_jointFeedback[i]->m_appliedTorqueBodyB.x(), - m_jointFeedback[i]->m_appliedTorqueBodyB.y(), - m_jointFeedback[i]->m_appliedTorqueBodyB.z()); + m_jointFeedback[i]->m_appliedForceBodyB.x(), + m_jointFeedback[i]->m_appliedForceBodyB.y(), + m_jointFeedback[i]->m_appliedForceBodyB.z(), + m_jointFeedback[i]->m_appliedTorqueBodyB.x(), + m_jointFeedback[i]->m_appliedTorqueBodyB.y(), + m_jointFeedback[i]->m_appliedTorqueBodyB.z()); } } count++; - //CommonRigidBodyBase::stepSimulation(deltaTime); + //CommonRigidBodyBase::stepSimulation(deltaTime); } - - void TestHingeTorque::initPhysics() { int upAxis = 1; @@ -110,92 +98,89 @@ void TestHingeTorque::initPhysics() createEmptyDynamicsWorld(); m_dynamicsWorld->getSolverInfo().m_splitImpulse = false; - - m_dynamicsWorld->setGravity(btVector3(0,0,-10)); - + + m_dynamicsWorld->setGravity(btVector3(0, 0, -10)); + m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); - int mode = btIDebugDraw::DBG_DrawWireframe - +btIDebugDraw::DBG_DrawConstraints - +btIDebugDraw::DBG_DrawConstraintLimits; + int mode = btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawConstraints + btIDebugDraw::DBG_DrawConstraintLimits; m_dynamicsWorld->getDebugDrawer()->setDebugMode(mode); + { // create a door using hinge constraint attached to the world - { // create a door using hinge constraint attached to the world - - int numLinks = 2; - // bool selfCollide = false; - btVector3 linkHalfExtents(0.05, 0.37, 0.1); - btVector3 baseHalfExtents(0.05, 0.37, 0.1); + int numLinks = 2; + // bool selfCollide = false; + btVector3 linkHalfExtents(0.05, 0.37, 0.1); + btVector3 baseHalfExtents(0.05, 0.37, 0.1); - btBoxShape* baseBox = new btBoxShape(baseHalfExtents); - btVector3 basePosition = btVector3(-0.4f, 3.f, 0.f); - btTransform baseWorldTrans; - baseWorldTrans.setIdentity(); - baseWorldTrans.setOrigin(basePosition); - - //mbC->forceMultiDof(); //if !spherical, you can comment this line to check the 1DoF algorithm - //init the base - btVector3 baseInertiaDiag(0.f, 0.f, 0.f); - float baseMass = 0.f; - float linkMass = 1.f; - - btRigidBody* base = createRigidBody(baseMass,baseWorldTrans,baseBox); - m_dynamicsWorld->removeRigidBody(base); - base->setDamping(0,0); - m_dynamicsWorld->addRigidBody(base,collisionFilterGroup,collisionFilterMask); - btBoxShape* linkBox1 = new btBoxShape(linkHalfExtents); + btBoxShape* baseBox = new btBoxShape(baseHalfExtents); + btVector3 basePosition = btVector3(-0.4f, 3.f, 0.f); + btTransform baseWorldTrans; + baseWorldTrans.setIdentity(); + baseWorldTrans.setOrigin(basePosition); + + //mbC->forceMultiDof(); //if !spherical, you can comment this line to check the 1DoF algorithm + //init the base + btVector3 baseInertiaDiag(0.f, 0.f, 0.f); + float baseMass = 0.f; + float linkMass = 1.f; + + btRigidBody* base = createRigidBody(baseMass, baseWorldTrans, baseBox); + m_dynamicsWorld->removeRigidBody(base); + base->setDamping(0, 0); + m_dynamicsWorld->addRigidBody(base, collisionFilterGroup, collisionFilterMask); + btBoxShape* linkBox1 = new btBoxShape(linkHalfExtents); btSphereShape* linkSphere = new btSphereShape(radius); - - btRigidBody* prevBody = base; - - for (int i=0;iremoveRigidBody(linkBody); - m_dynamicsWorld->addRigidBody(linkBody,collisionFilterGroup,collisionFilterMask); - linkBody->setDamping(0,0); + btRigidBody* linkBody = createRigidBody(linkMass, linkTrans, colOb); + m_dynamicsWorld->removeRigidBody(linkBody); + m_dynamicsWorld->addRigidBody(linkBody, collisionFilterGroup, collisionFilterMask); + linkBody->setDamping(0, 0); btTypedConstraint* con = 0; - - if (i==0) + + if (i == 0) { //create a hinge constraint - btVector3 pivotInA(0,-linkHalfExtents[1],0); - btVector3 pivotInB(0,linkHalfExtents[1],0); - btVector3 axisInA(1,0,0); - btVector3 axisInB(1,0,0); + btVector3 pivotInA(0, -linkHalfExtents[1], 0); + btVector3 pivotInB(0, linkHalfExtents[1], 0); + btVector3 axisInA(1, 0, 0); + btVector3 axisInB(1, 0, 0); bool useReferenceA = true; - btHingeConstraint* hinge = new btHingeConstraint(*prevBody,*linkBody, - pivotInA,pivotInB, - axisInA,axisInB,useReferenceA); + btHingeConstraint* hinge = new btHingeConstraint(*prevBody, *linkBody, + pivotInA, pivotInB, + axisInA, axisInB, useReferenceA); con = hinge; - } else + } + else { - - btTransform pivotInA(btQuaternion::getIdentity(),btVector3(0, -radius, 0)); //par body's COM to cur body's COM offset - btTransform pivotInB(btQuaternion::getIdentity(),btVector3(0, radius, 0)); //cur body's COM to cur body's PIV offset + btTransform pivotInA(btQuaternion::getIdentity(), btVector3(0, -radius, 0)); //par body's COM to cur body's COM offset + btTransform pivotInB(btQuaternion::getIdentity(), btVector3(0, radius, 0)); //cur body's COM to cur body's PIV offset btGeneric6DofSpring2Constraint* fixed = new btGeneric6DofSpring2Constraint(*prevBody, *linkBody, - pivotInA,pivotInB); - fixed->setLinearLowerLimit(btVector3(0,0,0)); - fixed->setLinearUpperLimit(btVector3(0,0,0)); - fixed->setAngularLowerLimit(btVector3(0,0,0)); - fixed->setAngularUpperLimit(btVector3(0,0,0)); - - con = fixed; + pivotInA, pivotInB); + fixed->setLinearLowerLimit(btVector3(0, 0, 0)); + fixed->setLinearUpperLimit(btVector3(0, 0, 0)); + fixed->setAngularLowerLimit(btVector3(0, 0, 0)); + fixed->setAngularUpperLimit(btVector3(0, 0, 0)); + con = fixed; } btAssert(con); if (con) @@ -204,38 +189,36 @@ void TestHingeTorque::initPhysics() m_jointFeedback.push_back(fb); con->setJointFeedback(fb); - m_dynamicsWorld->addConstraint(con,true); + m_dynamicsWorld->addConstraint(con, true); } prevBody = linkBody; - - } - + } } - + if (1) { - btVector3 groundHalfExtents(1,1,0.2); - groundHalfExtents[upAxis]=1.f; + btVector3 groundHalfExtents(1, 1, 0.2); + groundHalfExtents[upAxis] = 1.f; btBoxShape* box = new btBoxShape(groundHalfExtents); box->initializePolyhedralFeatures(); - - btTransform start; start.setIdentity(); + + btTransform start; + start.setIdentity(); btVector3 groundOrigin(-0.4f, 3.f, 0.f); - // btVector3 basePosition = btVector3(-0.4f, 3.f, 0.f); - btQuaternion groundOrn(btVector3(0,1,0),0.25*SIMD_PI); - - groundOrigin[upAxis] -=.5; - groundOrigin[2]-=0.6; + // btVector3 basePosition = btVector3(-0.4f, 3.f, 0.f); + btQuaternion groundOrn(btVector3(0, 1, 0), 0.25 * SIMD_PI); + + groundOrigin[upAxis] -= .5; + groundOrigin[2] -= 0.6; start.setOrigin(groundOrigin); - // start.setRotation(groundOrn); - btRigidBody* body = createRigidBody(0,start,box); + // start.setRotation(groundOrn); + btRigidBody* body = createRigidBody(0, start, box); body->setFriction(0); - } m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } -class CommonExampleInterface* TestHingeTorqueCreateFunc(CommonExampleOptions& options) +class CommonExampleInterface* TestHingeTorqueCreateFunc(CommonExampleOptions& options) { return new TestHingeTorque(options.m_guiHelper); } diff --git a/examples/Constraints/TestHingeTorque.h b/examples/Constraints/TestHingeTorque.h index 5c2bf1d2c..7d2648408 100644 --- a/examples/Constraints/TestHingeTorque.h +++ b/examples/Constraints/TestHingeTorque.h @@ -1,7 +1,6 @@ #ifndef TEST_HINGE_TORQUE_H #define TEST_HINGE_TORQUE_H -class CommonExampleInterface* TestHingeTorqueCreateFunc(struct CommonExampleOptions& options); - -#endif //TEST_HINGE_TORQUE_H +class CommonExampleInterface* TestHingeTorqueCreateFunc(struct CommonExampleOptions& options); +#endif //TEST_HINGE_TORQUE_H diff --git a/examples/DynamicControlDemo/MotorDemo.cpp b/examples/DynamicControlDemo/MotorDemo.cpp index d4025461e..0b1885911 100644 --- a/examples/DynamicControlDemo/MotorDemo.cpp +++ b/examples/DynamicControlDemo/MotorDemo.cpp @@ -13,13 +13,11 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btBulletDynamicsCommon.h" #include "LinearMath/btIDebugDraw.h" #include "MotorDemo.h" - #include "LinearMath/btAlignedObjectArray.h" class btBroadphaseInterface; class btCollisionShape; @@ -34,85 +32,80 @@ class btDefaultCollisionConfiguration; class MotorDemo : public CommonRigidBodyBase { float m_Time; - float m_fCyclePeriod; // in milliseconds + float m_fCyclePeriod; // in milliseconds float m_fMuscleStrength; - + btAlignedObjectArray m_rigs; - - + public: MotorDemo(struct GUIHelperInterface* helper) - :CommonRigidBodyBase(helper) + : CommonRigidBodyBase(helper) { } void initPhysics(); - + void exitPhysics(); - + virtual ~MotorDemo() { } - + void spawnTestRig(const btVector3& startOffset, bool bFixed); - -// virtual void keyboardCallback(unsigned char key, int x, int y); - + + // virtual void keyboardCallback(unsigned char key, int x, int y); + void setMotorTargets(btScalar deltaTime); - + void resetCamera() { float dist = 11; float pitch = -35; float yaw = 52; - float targetPos[3]={0,0.46,0}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {0, 0.46, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } }; - #ifndef M_PI -#define M_PI 3.14159265358979323846 +#define M_PI 3.14159265358979323846 #endif #ifndef M_PI_2 -#define M_PI_2 1.57079632679489661923 +#define M_PI_2 1.57079632679489661923 #endif #ifndef M_PI_4 -#define M_PI_4 0.785398163397448309616 +#define M_PI_4 0.785398163397448309616 #endif #ifndef M_PI_8 -#define M_PI_8 0.5 * M_PI_4 +#define M_PI_8 0.5 * M_PI_4 #endif - // /LOCAL FUNCTIONS - - #define NUM_LEGS 6 #define BODYPART_COUNT 2 * NUM_LEGS + 1 #define JOINT_COUNT BODYPART_COUNT - 1 class TestRig { - btDynamicsWorld* m_ownerWorld; - btCollisionShape* m_shapes[BODYPART_COUNT]; - btRigidBody* m_bodies[BODYPART_COUNT]; - btTypedConstraint* m_joints[JOINT_COUNT]; + btDynamicsWorld* m_ownerWorld; + btCollisionShape* m_shapes[BODYPART_COUNT]; + btRigidBody* m_bodies[BODYPART_COUNT]; + btTypedConstraint* m_joints[JOINT_COUNT]; - btRigidBody* localCreateRigidBody (btScalar mass, const btTransform& startTransform, btCollisionShape* shape) + btRigidBody* localCreateRigidBody(btScalar mass, const btTransform& startTransform, btCollisionShape* shape) { bool isDynamic = (mass != 0.f); - btVector3 localInertia(0,0,0); + btVector3 localInertia(0, 0, 0); if (isDynamic) - shape->calculateLocalInertia(mass,localInertia); + shape->calculateLocalInertia(mass, localInertia); btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); - btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,shape,localInertia); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, shape, localInertia); btRigidBody* body = new btRigidBody(rbInfo); m_ownerWorld->addRigidBody(body); @@ -120,33 +113,33 @@ class TestRig return body; } - public: - TestRig (btDynamicsWorld* ownerWorld, const btVector3& positionOffset, bool bFixed) - : m_ownerWorld (ownerWorld) + TestRig(btDynamicsWorld* ownerWorld, const btVector3& positionOffset, bool bFixed) + : m_ownerWorld(ownerWorld) { btVector3 vUp(0, 1, 0); // // Setup geometry // - float fBodySize = 0.25f; + float fBodySize = 0.25f; float fLegLength = 0.45f; float fForeLegLength = 0.75f; m_shapes[0] = new btCapsuleShape(btScalar(fBodySize), btScalar(0.10)); int i; - for ( i=0; isetSleepingThresholds(0.5f, 0.5f); } - // // Setup the constraints // @@ -201,74 +194,76 @@ public: btTransform localA, localB, localC; - for ( i=0; igetWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA; - hingeC = new btHingeConstraint(*m_bodies[0], *m_bodies[1+2*i], localA, localB); + localA.setIdentity(); + localB.setIdentity(); + localA.getBasis().setEulerZYX(0, -fAngle, 0); + localA.setOrigin(btVector3(btScalar(fCos * fBodySize), btScalar(0.), btScalar(fSin * fBodySize))); + localB = m_bodies[1 + 2 * i]->getWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA; + hingeC = new btHingeConstraint(*m_bodies[0], *m_bodies[1 + 2 * i], localA, localB); hingeC->setLimit(btScalar(-0.75 * M_PI_4), btScalar(M_PI_8)); //hingeC->setLimit(btScalar(-0.1), btScalar(0.1)); - m_joints[2*i] = hingeC; - m_ownerWorld->addConstraint(m_joints[2*i], true); + m_joints[2 * i] = hingeC; + m_ownerWorld->addConstraint(m_joints[2 * i], true); // knee joints - localA.setIdentity(); localB.setIdentity(); localC.setIdentity(); - localA.getBasis().setEulerZYX(0,-fAngle,0); localA.setOrigin(btVector3(btScalar(fCos*(fBodySize+fLegLength)), btScalar(0.), btScalar(fSin*(fBodySize+fLegLength)))); - localB = m_bodies[1+2*i]->getWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA; - localC = m_bodies[2+2*i]->getWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA; - hingeC = new btHingeConstraint(*m_bodies[1+2*i], *m_bodies[2+2*i], localB, localC); + localA.setIdentity(); + localB.setIdentity(); + localC.setIdentity(); + localA.getBasis().setEulerZYX(0, -fAngle, 0); + localA.setOrigin(btVector3(btScalar(fCos * (fBodySize + fLegLength)), btScalar(0.), btScalar(fSin * (fBodySize + fLegLength)))); + localB = m_bodies[1 + 2 * i]->getWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA; + localC = m_bodies[2 + 2 * i]->getWorldTransform().inverse() * m_bodies[0]->getWorldTransform() * localA; + hingeC = new btHingeConstraint(*m_bodies[1 + 2 * i], *m_bodies[2 + 2 * i], localB, localC); //hingeC->setLimit(btScalar(-0.01), btScalar(0.01)); hingeC->setLimit(btScalar(-M_PI_8), btScalar(0.2)); - m_joints[1+2*i] = hingeC; - m_ownerWorld->addConstraint(m_joints[1+2*i], true); + m_joints[1 + 2 * i] = hingeC; + m_ownerWorld->addConstraint(m_joints[1 + 2 * i], true); } } - virtual ~TestRig () + virtual ~TestRig() { int i; // Remove all constraints - for ( i = 0; i < JOINT_COUNT; ++i) + for (i = 0; i < JOINT_COUNT; ++i) { m_ownerWorld->removeConstraint(m_joints[i]); - delete m_joints[i]; m_joints[i] = 0; + delete m_joints[i]; + m_joints[i] = 0; } // Remove all bodies and shapes - for ( i = 0; i < BODYPART_COUNT; ++i) + for (i = 0; i < BODYPART_COUNT; ++i) { m_ownerWorld->removeRigidBody(m_bodies[i]); - + delete m_bodies[i]->getMotionState(); - delete m_bodies[i]; m_bodies[i] = 0; - delete m_shapes[i]; m_shapes[i] = 0; + delete m_bodies[i]; + m_bodies[i] = 0; + delete m_shapes[i]; + m_shapes[i] = 0; } } - btTypedConstraint** GetJoints() {return &m_joints[0];} - + btTypedConstraint** GetJoints() { return &m_joints[0]; } }; - - -void motorPreTickCallback (btDynamicsWorld *world, btScalar timeStep) +void motorPreTickCallback(btDynamicsWorld* world, btScalar timeStep) { MotorDemo* motorDemo = (MotorDemo*)world->getWorldUserInfo(); motorDemo->setMotorTargets(timeStep); - } - - void MotorDemo::initPhysics() { m_guiHelper->setUpAxis(1); @@ -276,70 +271,62 @@ void MotorDemo::initPhysics() // Setup the basic world m_Time = 0; - m_fCyclePeriod = 2000.f; // in milliseconds + m_fCyclePeriod = 2000.f; // in milliseconds -// m_fMuscleStrength = 0.05f; + // m_fMuscleStrength = 0.05f; // new SIMD solver for joints clips accumulated impulse, so the new limits for the motor // should be (numberOfsolverIterations * oldLimits) // currently solver uses 10 iterations, so: m_fMuscleStrength = 0.5f; - m_collisionConfiguration = new btDefaultCollisionConfiguration(); m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); - btVector3 worldAabbMin(-10000,-10000,-10000); - btVector3 worldAabbMax(10000,10000,10000); - m_broadphase = new btAxisSweep3 (worldAabbMin, worldAabbMax); + btVector3 worldAabbMin(-10000, -10000, -10000); + btVector3 worldAabbMax(10000, 10000, 10000); + m_broadphase = new btAxisSweep3(worldAabbMin, worldAabbMax); m_solver = new btSequentialImpulseConstraintSolver; - m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration); - m_dynamicsWorld->setInternalTickCallback(motorPreTickCallback,this,true); + m_dynamicsWorld->setInternalTickCallback(motorPreTickCallback, this, true); m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); - // Setup a big ground box { - btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(10.),btScalar(200.))); + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.), btScalar(10.), btScalar(200.))); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0,-10,0)); - createRigidBody(btScalar(0.),groundTransform,groundShape); + groundTransform.setOrigin(btVector3(0, -10, 0)); + createRigidBody(btScalar(0.), groundTransform, groundShape); } // Spawn one ragdoll - btVector3 startOffset(1,0.5,0); + btVector3 startOffset(1, 0.5, 0); spawnTestRig(startOffset, false); - startOffset.setValue(-2,0.5,0); + startOffset.setValue(-2, 0.5, 0); spawnTestRig(startOffset, true); m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } - void MotorDemo::spawnTestRig(const btVector3& startOffset, bool bFixed) { TestRig* rig = new TestRig(m_dynamicsWorld, startOffset, bFixed); m_rigs.push_back(rig); } -void PreStep() +void PreStep() { - } - - - void MotorDemo::setMotorTargets(btScalar deltaTime) { - - float ms = deltaTime*1000000.; - float minFPS = 1000000.f/60.f; + float ms = deltaTime * 1000000.; + float minFPS = 1000000.f / 60.f; if (ms > minFPS) ms = minFPS; @@ -347,24 +334,22 @@ void MotorDemo::setMotorTargets(btScalar deltaTime) // // set per-frame sinusoidal position targets using angular motor (hacky?) - // - for (int r=0; r(m_rigs[r]->GetJoints()[i]); - btScalar fCurAngle = hingeC->getHingeAngle(); - + btScalar fCurAngle = hingeC->getHingeAngle(); + btScalar fTargetPercent = (int(m_Time / 1000) % int(m_fCyclePeriod)) / m_fCyclePeriod; - btScalar fTargetAngle = 0.5 * (1 + sin(2 * M_PI * fTargetPercent)); + btScalar fTargetAngle = 0.5 * (1 + sin(2 * M_PI * fTargetPercent)); btScalar fTargetLimitAngle = hingeC->getLowerLimit() + fTargetAngle * (hingeC->getUpperLimit() - hingeC->getLowerLimit()); - btScalar fAngleError = fTargetLimitAngle - fCurAngle; - btScalar fDesiredAngularVel = 1000000.f * fAngleError/ms; + btScalar fAngleError = fTargetLimitAngle - fCurAngle; + btScalar fDesiredAngularVel = 1000000.f * fAngleError / ms; hingeC->enableAngularMotor(true, fDesiredAngularVel, m_fMuscleStrength); } } - - } #if 0 @@ -392,14 +377,11 @@ void MotorDemo::keyboardCallback(unsigned char key, int x, int y) } #endif - - void MotorDemo::exitPhysics() { - int i; - for (i=0;igetNumCollisionObjects()-1; i>=0 ;i--) + + for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--) { btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; btRigidBody* body = btRigidBody::upcast(obj); @@ -417,12 +399,12 @@ void MotorDemo::exitPhysics() { delete body->getMotionState(); } - m_dynamicsWorld->removeCollisionObject( obj ); + m_dynamicsWorld->removeCollisionObject(obj); delete obj; } //delete collision shapes - for (int j=0;j m_walkersInPopulation; - + TimeSeriesCanvas* m_timeSeriesCanvas; public: NN3DWalkersExample(struct GUIHelperInterface* helper) - :NN3DWalkersTimeWarpBase(helper), - m_Time(0), - m_SpeedupTimestamp(0), - m_targetAccumulator(0), - m_targetFrequency(3), - m_motorStrength(0.5f), - m_evaluationsQty(0), - m_nextReaped(0), - m_timeSeriesCanvas(0) + : NN3DWalkersTimeWarpBase(helper), + m_Time(0), + m_SpeedupTimestamp(0), + m_targetAccumulator(0), + m_targetFrequency(3), + m_motorStrength(0.5f), + m_evaluationsQty(0), + m_nextReaped(0), + m_timeSeriesCanvas(0) { } @@ -133,12 +133,12 @@ public: } void initPhysics(); - + virtual void exitPhysics(); - + void spawnWalker(int index, const btVector3& startOffset, bool bFixed); - - virtual bool keyboardCallback(int key, int state); + + virtual bool keyboardCallback(int key, int state); bool detectCollisions(); @@ -147,8 +147,8 @@ public: float dist = 11; float pitch = -35; float yaw = 52; - float targetPos[3]={0,0.46,0}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {0, 0.46, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } // Evaluation @@ -180,63 +180,63 @@ public: NNWalker* getNextReaped(); void printWalkerConfigs(); - }; static NN3DWalkersExample* nn3DWalkers = NULL; class NNWalker { - btDynamicsWorld* m_ownerWorld; - btCollisionShape* m_shapes[BODYPART_COUNT]; - btRigidBody* m_bodies[BODYPART_COUNT]; - btTransform m_bodyRelativeTransforms[BODYPART_COUNT]; - btTypedConstraint* m_joints[JOINT_COUNT]; - btHashMap m_bodyTouchSensorIndexMap; - bool m_touchSensors[BODYPART_COUNT]; - btScalar m_sensoryMotorWeights[BODYPART_COUNT*JOINT_COUNT]; + btDynamicsWorld* m_ownerWorld; + btCollisionShape* m_shapes[BODYPART_COUNT]; + btRigidBody* m_bodies[BODYPART_COUNT]; + btTransform m_bodyRelativeTransforms[BODYPART_COUNT]; + btTypedConstraint* m_joints[JOINT_COUNT]; + btHashMap m_bodyTouchSensorIndexMap; + bool m_touchSensors[BODYPART_COUNT]; + btScalar m_sensoryMotorWeights[BODYPART_COUNT * JOINT_COUNT]; - bool m_inEvaluation; - btScalar m_evaluationTime; - bool m_reaped; - btVector3 m_startPosition; - int m_index; + bool m_inEvaluation; + btScalar m_evaluationTime; + bool m_reaped; + btVector3 m_startPosition; + int m_index; - btRigidBody* localCreateRigidBody (btScalar mass, const btTransform& startTransform, btCollisionShape* shape) + btRigidBody* localCreateRigidBody(btScalar mass, const btTransform& startTransform, btCollisionShape* shape) { bool isDynamic = (mass != 0.f); - btVector3 localInertia(0,0,0); + btVector3 localInertia(0, 0, 0); if (isDynamic) - shape->calculateLocalInertia(mass,localInertia); + shape->calculateLocalInertia(mass, localInertia); btDefaultMotionState* motionState = new btDefaultMotionState(startTransform); - btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,motionState,shape,localInertia); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, motionState, shape, localInertia); btRigidBody* body = new btRigidBody(rbInfo); return body; } - public: - - void randomizeSensoryMotorWeights(){ + void randomizeSensoryMotorWeights() + { //initialize random weights - for(int i = 0;i < BODYPART_COUNT;i++){ - for(int j = 0;j < JOINT_COUNT;j++){ - m_sensoryMotorWeights[i+j*BODYPART_COUNT] = ((double) rand() / (RAND_MAX))*2.0f-1.0f; + for (int i = 0; i < BODYPART_COUNT; i++) + { + for (int j = 0; j < JOINT_COUNT; j++) + { + m_sensoryMotorWeights[i + j * BODYPART_COUNT] = ((double)rand() / (RAND_MAX)) * 2.0f - 1.0f; } } } NNWalker(int index, btDynamicsWorld* ownerWorld, const btVector3& positionOffset, bool bFixed) - : m_ownerWorld (ownerWorld), + : m_ownerWorld(ownerWorld), m_inEvaluation(false), m_evaluationTime(0), m_reaped(false) { m_index = index; - btVector3 vUp(0, 1, 0); // up in local reference frame + btVector3 vUp(0, 1, 0); // up in local reference frame NN3DWalkersExample* nnWalkersDemo = (NN3DWalkersExample*)m_ownerWorld->getWorldUserInfo(); @@ -244,29 +244,30 @@ public: // // Setup geometry - m_shapes[0] = new btCapsuleShape(gRootBodyRadius, gRootBodyHeight); // root body capsule + m_shapes[0] = new btCapsuleShape(gRootBodyRadius, gRootBodyHeight); // root body capsule int i; - for ( i=0; iaddRigidBody(m_bodies[0]); m_bodyRelativeTransforms[0] = btTransform::getIdentity(); m_bodies[0]->setUserPointer(this); @@ -280,66 +281,73 @@ public: // legs for (i = 0; i < NUM_LEGS; i++) { - float footAngle = 2 * SIMD_PI * i / NUM_LEGS; // legs are uniformly distributed around the root body - float footYUnitPosition = sin(footAngle); // y position of the leg on the unit circle - float footXUnitPosition = cos(footAngle); // x position of the leg on the unit circle + float footAngle = 2 * SIMD_PI * i / NUM_LEGS; // legs are uniformly distributed around the root body + float footYUnitPosition = sin(footAngle); // y position of the leg on the unit circle + float footXUnitPosition = cos(footAngle); // x position of the leg on the unit circle transform.setIdentity(); - btVector3 legCOM = btVector3(btScalar(footXUnitPosition*(gRootBodyRadius+0.5*gLegLength)), btScalar(rootAboveGroundHeight), btScalar(footYUnitPosition*(gRootBodyRadius+0.5*gLegLength))); + btVector3 legCOM = btVector3(btScalar(footXUnitPosition * (gRootBodyRadius + 0.5 * gLegLength)), btScalar(rootAboveGroundHeight), btScalar(footYUnitPosition * (gRootBodyRadius + 0.5 * gLegLength))); transform.setOrigin(legCOM); // thigh btVector3 legDirection = (legCOM - localRootBodyPosition).normalize(); - btVector3 kneeAxis = legDirection.cross(vUp); + btVector3 kneeAxis = legDirection.cross(vUp); transform.setRotation(btQuaternion(kneeAxis, SIMD_HALF_PI)); - m_bodies[1+2*i] = localCreateRigidBody(btScalar(1.), bodyOffset*transform, m_shapes[1+2*i]); - m_bodyRelativeTransforms[1+2*i] = transform; - m_bodies[1+2*i]->setUserPointer(this); - m_bodyTouchSensorIndexMap.insert(btHashPtr(m_bodies[1+2*i]),1+2*i); + m_bodies[1 + 2 * i] = localCreateRigidBody(btScalar(1.), bodyOffset * transform, m_shapes[1 + 2 * i]); + m_bodyRelativeTransforms[1 + 2 * i] = transform; + m_bodies[1 + 2 * i]->setUserPointer(this); + m_bodyTouchSensorIndexMap.insert(btHashPtr(m_bodies[1 + 2 * i]), 1 + 2 * i); // shin transform.setIdentity(); - transform.setOrigin(btVector3(btScalar(footXUnitPosition*(gRootBodyRadius+gLegLength)), btScalar(rootAboveGroundHeight-0.5*gForeLegLength), btScalar(footYUnitPosition*(gRootBodyRadius+gLegLength)))); - m_bodies[2+2*i] = localCreateRigidBody(btScalar(1.), bodyOffset*transform, m_shapes[2+2*i]); - m_bodyRelativeTransforms[2+2*i] = transform; - m_bodies[2+2*i]->setUserPointer(this); - m_bodyTouchSensorIndexMap.insert(btHashPtr(m_bodies[2+2*i]),2+2*i); + transform.setOrigin(btVector3(btScalar(footXUnitPosition * (gRootBodyRadius + gLegLength)), btScalar(rootAboveGroundHeight - 0.5 * gForeLegLength), btScalar(footYUnitPosition * (gRootBodyRadius + gLegLength)))); + m_bodies[2 + 2 * i] = localCreateRigidBody(btScalar(1.), bodyOffset * transform, m_shapes[2 + 2 * i]); + m_bodyRelativeTransforms[2 + 2 * i] = transform; + m_bodies[2 + 2 * i]->setUserPointer(this); + m_bodyTouchSensorIndexMap.insert(btHashPtr(m_bodies[2 + 2 * i]), 2 + 2 * i); // hip joints - localA.setIdentity(); localB.setIdentity(); - localA.getBasis().setEulerZYX(0,-footAngle,0); localA.setOrigin(btVector3(btScalar(footXUnitPosition*gRootBodyRadius), btScalar(0.), btScalar(footYUnitPosition*gRootBodyRadius))); - localB = b3ReferenceFrameHelper::getTransformWorldToLocal(m_bodies[1+2*i]->getWorldTransform(), b3ReferenceFrameHelper::getTransformLocalToWorld(m_bodies[0]->getWorldTransform(),localA)); - hingeC = new btHingeConstraint(*m_bodies[0], *m_bodies[1+2*i], localA, localB); + localA.setIdentity(); + localB.setIdentity(); + localA.getBasis().setEulerZYX(0, -footAngle, 0); + localA.setOrigin(btVector3(btScalar(footXUnitPosition * gRootBodyRadius), btScalar(0.), btScalar(footYUnitPosition * gRootBodyRadius))); + localB = b3ReferenceFrameHelper::getTransformWorldToLocal(m_bodies[1 + 2 * i]->getWorldTransform(), b3ReferenceFrameHelper::getTransformLocalToWorld(m_bodies[0]->getWorldTransform(), localA)); + hingeC = new btHingeConstraint(*m_bodies[0], *m_bodies[1 + 2 * i], localA, localB); hingeC->setLimit(btScalar(-0.75 * SIMD_PI_4), btScalar(SIMD_PI_8)); //hingeC->setLimit(btScalar(-0.1), btScalar(0.1)); - m_joints[2*i] = hingeC; + m_joints[2 * i] = hingeC; // knee joints - localA.setIdentity(); localB.setIdentity(); localC.setIdentity(); - localA.getBasis().setEulerZYX(0,-footAngle,0); localA.setOrigin(btVector3(btScalar(footXUnitPosition*(gRootBodyRadius+gLegLength)), btScalar(0.), btScalar(footYUnitPosition*(gRootBodyRadius+gLegLength)))); - localB = b3ReferenceFrameHelper::getTransformWorldToLocal(m_bodies[1+2*i]->getWorldTransform(), b3ReferenceFrameHelper::getTransformLocalToWorld(m_bodies[0]->getWorldTransform(),localA)); - localC = b3ReferenceFrameHelper::getTransformWorldToLocal(m_bodies[2+2*i]->getWorldTransform(), b3ReferenceFrameHelper::getTransformLocalToWorld(m_bodies[0]->getWorldTransform(),localA)); - hingeC = new btHingeConstraint(*m_bodies[1+2*i], *m_bodies[2+2*i], localB, localC); + localA.setIdentity(); + localB.setIdentity(); + localC.setIdentity(); + localA.getBasis().setEulerZYX(0, -footAngle, 0); + localA.setOrigin(btVector3(btScalar(footXUnitPosition * (gRootBodyRadius + gLegLength)), btScalar(0.), btScalar(footYUnitPosition * (gRootBodyRadius + gLegLength)))); + localB = b3ReferenceFrameHelper::getTransformWorldToLocal(m_bodies[1 + 2 * i]->getWorldTransform(), b3ReferenceFrameHelper::getTransformLocalToWorld(m_bodies[0]->getWorldTransform(), localA)); + localC = b3ReferenceFrameHelper::getTransformWorldToLocal(m_bodies[2 + 2 * i]->getWorldTransform(), b3ReferenceFrameHelper::getTransformLocalToWorld(m_bodies[0]->getWorldTransform(), localA)); + hingeC = new btHingeConstraint(*m_bodies[1 + 2 * i], *m_bodies[2 + 2 * i], localB, localC); //hingeC->setLimit(btScalar(-0.01), btScalar(0.01)); hingeC->setLimit(btScalar(-SIMD_PI_8), btScalar(0.2)); - m_joints[1+2*i] = hingeC; + m_joints[1 + 2 * i] = hingeC; - m_ownerWorld->addRigidBody(m_bodies[1+2*i]); // add thigh bone + m_ownerWorld->addRigidBody(m_bodies[1 + 2 * i]); // add thigh bone - m_ownerWorld->addConstraint(m_joints[2*i], true); // connect thigh bone with root + m_ownerWorld->addConstraint(m_joints[2 * i], true); // connect thigh bone with root - if(nnWalkersDemo->detectCollisions()){ // if thigh bone causes collision, remove it again - m_ownerWorld->removeRigidBody(m_bodies[1+2*i]); - m_ownerWorld->removeConstraint(m_joints[2*i]); // disconnect thigh bone from root + if (nnWalkersDemo->detectCollisions()) + { // if thigh bone causes collision, remove it again + m_ownerWorld->removeRigidBody(m_bodies[1 + 2 * i]); + m_ownerWorld->removeConstraint(m_joints[2 * i]); // disconnect thigh bone from root } - else{ + else + { + m_ownerWorld->addRigidBody(m_bodies[2 + 2 * i]); // add shin bone + m_ownerWorld->addConstraint(m_joints[1 + 2 * i], true); // connect shin bone with thigh - m_ownerWorld->addRigidBody(m_bodies[2+2*i]); // add shin bone - m_ownerWorld->addConstraint(m_joints[1+2*i], true); // connect shin bone with thigh - - if(nnWalkersDemo->detectCollisions()){ // if shin bone causes collision, remove it again - m_ownerWorld->removeRigidBody(m_bodies[2+2*i]); - m_ownerWorld->removeConstraint(m_joints[1+2*i]); // disconnect shin bone from thigh + if (nnWalkersDemo->detectCollisions()) + { // if shin bone causes collision, remove it again + m_ownerWorld->removeRigidBody(m_bodies[2 + 2 * i]); + m_ownerWorld->removeConstraint(m_joints[1 + 2 * i]); // disconnect shin bone from thigh } } } @@ -353,90 +361,102 @@ public: m_bodies[i]->setSleepingThresholds(0.5f, 0.5f); } - removeFromWorld(); // it should not yet be in the world + removeFromWorld(); // it should not yet be in the world } - virtual ~NNWalker () + virtual ~NNWalker() { int i; // Remove all constraints - for ( i = 0; i < JOINT_COUNT; ++i) + for (i = 0; i < JOINT_COUNT; ++i) { m_ownerWorld->removeConstraint(m_joints[i]); - delete m_joints[i]; m_joints[i] = 0; + delete m_joints[i]; + m_joints[i] = 0; } // Remove all bodies and shapes - for ( i = 0; i < BODYPART_COUNT; ++i) + for (i = 0; i < BODYPART_COUNT; ++i) { m_ownerWorld->removeRigidBody(m_bodies[i]); - + delete m_bodies[i]->getMotionState(); - delete m_bodies[i]; m_bodies[i] = 0; - delete m_shapes[i]; m_shapes[i] = 0; + delete m_bodies[i]; + m_bodies[i] = 0; + delete m_shapes[i]; + m_shapes[i] = 0; } } - btTypedConstraint** getJoints() { + btTypedConstraint** getJoints() + { return &m_joints[0]; } - void setTouchSensor(void* bodyPointer){ + void setTouchSensor(void* bodyPointer) + { m_touchSensors[*m_bodyTouchSensorIndexMap.find(btHashPtr(bodyPointer))] = true; } - void clearTouchSensors(){ - for(int i = 0 ; i < BODYPART_COUNT;i++){ + void clearTouchSensors() + { + for (int i = 0; i < BODYPART_COUNT; i++) + { m_touchSensors[i] = false; } } - bool getTouchSensor(int i){ + bool getTouchSensor(int i) + { return m_touchSensors[i]; } - btScalar* getSensoryMotorWeights() { + btScalar* getSensoryMotorWeights() + { return m_sensoryMotorWeights; } - void addToWorld() { + void addToWorld() + { int i; // add all bodies and shapes - for ( i = 0; i < BODYPART_COUNT; ++i) + for (i = 0; i < BODYPART_COUNT; ++i) { m_ownerWorld->addRigidBody(m_bodies[i]); } // add all constraints - for ( i = 0; i < JOINT_COUNT; ++i) + for (i = 0; i < JOINT_COUNT; ++i) { - m_ownerWorld->addConstraint(m_joints[i], true); // important! If you add constraints back, you must set bullet physics to disable collision between constrained bodies + m_ownerWorld->addConstraint(m_joints[i], true); // important! If you add constraints back, you must set bullet physics to disable collision between constrained bodies } m_startPosition = getPosition(); } - void removeFromWorld(){ + void removeFromWorld() + { int i; // Remove all constraints - for ( i = 0; i < JOINT_COUNT; ++i) + for (i = 0; i < JOINT_COUNT; ++i) { m_ownerWorld->removeConstraint(m_joints[i]); } // Remove all bodies - for ( i = 0; i < BODYPART_COUNT; ++i) + for (i = 0; i < BODYPART_COUNT; ++i) { m_ownerWorld->removeRigidBody(m_bodies[i]); } } - btVector3 getPosition() const { - btVector3 finalPosition(0,0,0); + btVector3 getPosition() const + { + btVector3 finalPosition(0, 0, 0); - for(int i = 0; i < BODYPART_COUNT;i++) + for (int i = 0; i < BODYPART_COUNT; i++) { finalPosition += m_bodies[i]->getCenterOfMassPosition(); } @@ -456,97 +476,112 @@ public: btScalar getFitness() const { - return getDistanceFitness(); // for now it is only distance + return getDistanceFitness(); // for now it is only distance } - void resetAt(const btVector3& position) { + void resetAt(const btVector3& position) + { btTransform resetPosition(btQuaternion::getIdentity(), position); for (int i = 0; i < BODYPART_COUNT; ++i) { - m_bodies[i]->setWorldTransform(resetPosition*m_bodyRelativeTransforms[i]); - if(m_bodies[i]->getMotionState()){ - m_bodies[i]->getMotionState()->setWorldTransform(resetPosition*m_bodyRelativeTransforms[i]); + m_bodies[i]->setWorldTransform(resetPosition * m_bodyRelativeTransforms[i]); + if (m_bodies[i]->getMotionState()) + { + m_bodies[i]->getMotionState()->setWorldTransform(resetPosition * m_bodyRelativeTransforms[i]); } m_bodies[i]->clearForces(); - m_bodies[i]->setAngularVelocity(btVector3(0,0,0)); - m_bodies[i]->setLinearVelocity(btVector3(0,0,0)); - + m_bodies[i]->setAngularVelocity(btVector3(0, 0, 0)); + m_bodies[i]->setLinearVelocity(btVector3(0, 0, 0)); } clearTouchSensors(); } - btScalar getEvaluationTime() const { + btScalar getEvaluationTime() const + { return m_evaluationTime; } - void setEvaluationTime(btScalar evaluationTime) { + void setEvaluationTime(btScalar evaluationTime) + { m_evaluationTime = evaluationTime; } - bool isInEvaluation() const { + bool isInEvaluation() const + { return m_inEvaluation; } - void setInEvaluation(bool inEvaluation) { + void setInEvaluation(bool inEvaluation) + { m_inEvaluation = inEvaluation; } - bool isReaped() const { + bool isReaped() const + { return m_reaped; } - void setReaped(bool reaped) { + void setReaped(bool reaped) + { m_reaped = reaped; } - int getIndex() const { + int getIndex() const + { return m_index; } }; -void evaluationUpdatePreTickCallback(btDynamicsWorld *world, btScalar timeStep); +void evaluationUpdatePreTickCallback(btDynamicsWorld* world, btScalar timeStep); bool legContactProcessedCallback(btManifoldPoint& cp, void* body0, void* body1) { - btCollisionObject* o1 = static_cast(body0); - btCollisionObject* o2 = static_cast(body1); + btCollisionObject* o1 = static_cast(body0); + btCollisionObject* o2 = static_cast(body1); - void* ID1 = o1->getUserPointer(); - void* ID2 = o2->getUserPointer(); + void* ID1 = o1->getUserPointer(); + void* ID2 = o2->getUserPointer(); - if (ID1 != GROUND_ID || ID2 != GROUND_ID) { - // Make a circle with a 0.9 radius at (0,0,0) - // with RGB color (1,0,0). - if(nn3DWalkers->m_dynamicsWorld->getDebugDrawer() != NULL){ - if(!nn3DWalkers->mIsHeadless){ + if (ID1 != GROUND_ID || ID2 != GROUND_ID) + { + // Make a circle with a 0.9 radius at (0,0,0) + // with RGB color (1,0,0). + if (nn3DWalkers->m_dynamicsWorld->getDebugDrawer() != NULL) + { + if (!nn3DWalkers->mIsHeadless) + { nn3DWalkers->m_dynamicsWorld->getDebugDrawer()->drawSphere(cp.getPositionWorldOnA(), 0.1, btVector3(1., 0., 0.)); } } - if(ID1 != GROUND_ID && ID1){ + if (ID1 != GROUND_ID && ID1) + { ((NNWalker*)ID1)->setTouchSensor(o1); } - if(ID2 != GROUND_ID && ID2){ + if (ID2 != GROUND_ID && ID2) + { ((NNWalker*)ID2)->setTouchSensor(o2); } } - return false; + return false; } struct WalkerFilterCallback : public btOverlapFilterCallback { // return true when pairs need collision - virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) const + virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) const { btCollisionObject* obj0 = static_cast(proxy0->m_clientObject); btCollisionObject* obj1 = static_cast(proxy1->m_clientObject); - if (obj0->getUserPointer() == GROUND_ID || obj1->getUserPointer() == GROUND_ID) { // everything collides with ground + if (obj0->getUserPointer() == GROUND_ID || obj1->getUserPointer() == GROUND_ID) + { // everything collides with ground return true; } - else{ + else + { return ((NNWalker*)obj0->getUserPointer())->getIndex() == ((NNWalker*)obj1->getUserPointer())->getIndex(); } } @@ -554,8 +589,7 @@ struct WalkerFilterCallback : public btOverlapFilterCallback void NN3DWalkersExample::initPhysics() { - - setupBasicParamInterface(); // parameter interface to use timewarp + setupBasicParamInterface(); // parameter interface to use timewarp gContactProcessedCallback = legContactProcessedCallback; @@ -576,8 +610,7 @@ void NN3DWalkersExample::initPhysics() // should be (numberOfsolverIterations * oldLimits) m_motorStrength = 0.05f * m_dynamicsWorld->getSolverInfo().m_numIterations; - - { // create a slider to change the motor update frequency + { // create a slider to change the motor update frequency SliderParams slider("Motor update frequency", &m_targetFrequency); slider.m_minVal = 0; slider.m_maxVal = 10; @@ -586,7 +619,7 @@ void NN3DWalkersExample::initPhysics() slider); } - { // create a slider to change the motor torque + { // create a slider to change the motor torque SliderParams slider("Motor force", &m_motorStrength); slider.m_minVal = 1; slider.m_maxVal = 50; @@ -594,8 +627,8 @@ void NN3DWalkersExample::initPhysics() m_guiHelper->getParameterInterface()->registerSliderFloatParameter( slider); } - - { // create a slider to change the root body radius + + { // create a slider to change the root body radius SliderParams slider("Root body radius", &gRootBodyRadius); slider.m_minVal = 0.01f; slider.m_maxVal = 10; @@ -604,7 +637,7 @@ void NN3DWalkersExample::initPhysics() slider); } - { // create a slider to change the root body height + { // create a slider to change the root body height SliderParams slider("Root body height", &gRootBodyHeight); slider.m_minVal = 0.01f; slider.m_maxVal = 10; @@ -613,7 +646,7 @@ void NN3DWalkersExample::initPhysics() slider); } - { // create a slider to change the leg radius + { // create a slider to change the leg radius SliderParams slider("Leg radius", &gLegRadius); slider.m_minVal = 0.01f; slider.m_maxVal = 10; @@ -622,7 +655,7 @@ void NN3DWalkersExample::initPhysics() slider); } - { // create a slider to change the leg length + { // create a slider to change the leg length SliderParams slider("Leg length", &gLegLength); slider.m_minVal = 0.01f; slider.m_maxVal = 10; @@ -631,7 +664,7 @@ void NN3DWalkersExample::initPhysics() slider); } - { // create a slider to change the fore leg radius + { // create a slider to change the fore leg radius SliderParams slider("Fore Leg radius", &gForeLegRadius); slider.m_minVal = 0.01f; slider.m_maxVal = 10; @@ -640,7 +673,7 @@ void NN3DWalkersExample::initPhysics() slider); } - { // create a slider to change the fore leg length + { // create a slider to change the fore leg length SliderParams slider("Fore Leg length", &gForeLegLength); slider.m_minVal = 0.01f; slider.m_maxVal = 10; @@ -649,57 +682,58 @@ void NN3DWalkersExample::initPhysics() slider); } - { // create a slider to change the number of parallel evaluations + { // create a slider to change the number of parallel evaluations SliderParams slider("Parallel evaluations", &gParallelEvaluations); slider.m_minVal = 1; slider.m_maxVal = NUM_WALKERS; - slider.m_clampToIntegers = true; + slider.m_clampToIntegers = true; m_guiHelper->getParameterInterface()->registerSliderFloatParameter( slider); } - // Setup a big ground box { - btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(10.),btScalar(200.))); + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.), btScalar(10.), btScalar(200.))); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0,-10,0)); - btRigidBody* ground = createRigidBody(btScalar(0.),groundTransform,groundShape); + groundTransform.setOrigin(btVector3(0, -10, 0)); + btRigidBody* ground = createRigidBody(btScalar(0.), groundTransform, groundShape); ground->setFriction(5); ground->setUserPointer(GROUND_ID); } - for(int i = 0; i < NUM_WALKERS ; i++){ - if(RANDOMIZE_DIMENSIONS){ + for (int i = 0; i < NUM_WALKERS; i++) + { + if (RANDOMIZE_DIMENSIONS) + { float maxDimension = 0.2f; // randomize the dimensions - gRootBodyRadius = ((double) rand() / (RAND_MAX)) * (maxDimension-0.01f) + 0.01f; - gRootBodyHeight = ((double) rand() / (RAND_MAX)) * (maxDimension-0.01f) + 0.01f; - gLegRadius = ((double) rand() / (RAND_MAX)) * (maxDimension-0.01f) + 0.01f; - gLegLength = ((double) rand() / (RAND_MAX)) * (maxDimension-0.01f) + 0.01f; - gForeLegLength = ((double) rand() / (RAND_MAX)) * (maxDimension-0.01f) + 0.01f; - gForeLegRadius = ((double) rand() / (RAND_MAX)) * (maxDimension-0.01f) + 0.01f; + gRootBodyRadius = ((double)rand() / (RAND_MAX)) * (maxDimension - 0.01f) + 0.01f; + gRootBodyHeight = ((double)rand() / (RAND_MAX)) * (maxDimension - 0.01f) + 0.01f; + gLegRadius = ((double)rand() / (RAND_MAX)) * (maxDimension - 0.01f) + 0.01f; + gLegLength = ((double)rand() / (RAND_MAX)) * (maxDimension - 0.01f) + 0.01f; + gForeLegLength = ((double)rand() / (RAND_MAX)) * (maxDimension - 0.01f) + 0.01f; + gForeLegRadius = ((double)rand() / (RAND_MAX)) * (maxDimension - 0.01f) + 0.01f; } // Spawn one walker - btVector3 offset(0,0,0); + btVector3 offset(0, 0, 0); spawnWalker(i, offset, false); } - btOverlapFilterCallback * filterCallback = new WalkerFilterCallback(); + btOverlapFilterCallback* filterCallback = new WalkerFilterCallback(); m_dynamicsWorld->getPairCache()->setOverlapFilterCallback(filterCallback); - m_timeSeriesCanvas = new TimeSeriesCanvas(m_guiHelper->getAppInterface()->m_2dCanvasInterface,300,200, "Fitness Performance"); - m_timeSeriesCanvas ->setupTimeSeries(40, NUM_WALKERS*EVALUATION_TIME, 0); - for(int i = 0; i < NUM_WALKERS ; i++){ - m_timeSeriesCanvas->addDataSource(" ", 100*i/NUM_WALKERS,100*(NUM_WALKERS-i)/NUM_WALKERS,100*(i)/NUM_WALKERS); + m_timeSeriesCanvas = new TimeSeriesCanvas(m_guiHelper->getAppInterface()->m_2dCanvasInterface, 300, 200, "Fitness Performance"); + m_timeSeriesCanvas->setupTimeSeries(40, NUM_WALKERS * EVALUATION_TIME, 0); + for (int i = 0; i < NUM_WALKERS; i++) + { + m_timeSeriesCanvas->addDataSource(" ", 100 * i / NUM_WALKERS, 100 * (NUM_WALKERS - i) / NUM_WALKERS, 100 * (i) / NUM_WALKERS); } } - void NN3DWalkersExample::spawnWalker(int index, const btVector3& startOffset, bool bFixed) { NNWalker* walker = new NNWalker(index, m_dynamicsWorld, startOffset, bFixed); @@ -709,35 +743,38 @@ void NN3DWalkersExample::spawnWalker(int index, const btVector3& startOffset, bo bool NN3DWalkersExample::detectCollisions() { bool collisionDetected = false; - if(m_dynamicsWorld){ - m_dynamicsWorld->performDiscreteCollisionDetection(); // let the collisions be calculated + if (m_dynamicsWorld) + { + m_dynamicsWorld->performDiscreteCollisionDetection(); // let the collisions be calculated } int numManifolds = m_dynamicsWorld->getDispatcher()->getNumManifolds(); - for (int i = 0;i < numManifolds;i++) + for (int i = 0; i < numManifolds; i++) { - btPersistentManifold* contactManifold = m_dynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i); + btPersistentManifold* contactManifold = m_dynamicsWorld->getDispatcher()->getManifoldByIndexInternal(i); const btCollisionObject* obA = contactManifold->getBody0(); const btCollisionObject* obB = contactManifold->getBody1(); - if(obA->getUserPointer() != GROUND_ID && obB->getUserPointer() != GROUND_ID){ - + if (obA->getUserPointer() != GROUND_ID && obB->getUserPointer() != GROUND_ID) + { int numContacts = contactManifold->getNumContacts(); - for (int j=0;jgetContactPoint(j); - if (pt.getDistance()<0.f) + if (pt.getDistance() < 0.f) { //const btVector3& ptA = pt.getPositionWorldOnA(); //const btVector3& ptB = pt.getPositionWorldOnB(); //const btVector3& normalOnB = pt.m_normalWorldOnB; - if(!DRAW_INTERPENETRATIONS){ + if (!DRAW_INTERPENETRATIONS) + { return collisionDetected; } - if(m_dynamicsWorld->getDebugDrawer()){ + if (m_dynamicsWorld->getDebugDrawer()) + { m_dynamicsWorld->getDebugDrawer()->drawSphere(pt.getPositionWorldOnA(), 0.1, btVector3(0., 0., 1.)); m_dynamicsWorld->getDebugDrawer()->drawSphere(pt.getPositionWorldOnB(), 0.1, btVector3(0., 0., 1.)); } @@ -753,30 +790,29 @@ bool NN3DWalkersExample::keyboardCallback(int key, int state) { switch (key) { - case '[': - m_motorStrength /= 1.1f; - return true; - case ']': - m_motorStrength *= 1.1f; - return true; - case 'l': - printWalkerConfigs(); - return true; - default: - break; + case '[': + m_motorStrength /= 1.1f; + return true; + case ']': + m_motorStrength *= 1.1f; + return true; + case 'l': + printWalkerConfigs(); + return true; + default: + break; } - return NN3DWalkersTimeWarpBase::keyboardCallback(key,state); + return NN3DWalkersTimeWarpBase::keyboardCallback(key, state); } void NN3DWalkersExample::exitPhysics() { - - gContactProcessedCallback = NULL; // clear contact processed callback on exiting + gContactProcessedCallback = NULL; // clear contact processed callback on exiting int i; - for (i = 0;i < NUM_WALKERS;i++) + for (i = 0; i < NUM_WALKERS; i++) { NNWalker* walker = m_walkersInPopulation[i]; delete walker; @@ -791,88 +827,104 @@ class CommonExampleInterface* ET_NN3DWalkersCreateFunc(struct CommonExampleOptio return nn3DWalkers; } -bool fitnessComparator (const NNWalker* a, const NNWalker* b) +bool fitnessComparator(const NNWalker* a, const NNWalker* b) { - return a->getFitness() > b->getFitness(); // sort walkers descending + return a->getFitness() > b->getFitness(); // sort walkers descending } -void NN3DWalkersExample::rateEvaluations(){ - - m_walkersInPopulation.quickSort(fitnessComparator); // Sort walkers by fitness +void NN3DWalkersExample::rateEvaluations() +{ + m_walkersInPopulation.quickSort(fitnessComparator); // Sort walkers by fitness b3Printf("Best performing walker: %f meters", btSqrt(m_walkersInPopulation[0]->getDistanceFitness())); - for(int i = 0; i < NUM_WALKERS;i++){ - m_timeSeriesCanvas->insertDataAtCurrentTime(btSqrt(m_walkersInPopulation[i]->getDistanceFitness()),0,true); + for (int i = 0; i < NUM_WALKERS; i++) + { + m_timeSeriesCanvas->insertDataAtCurrentTime(btSqrt(m_walkersInPopulation[i]->getDistanceFitness()), 0, true); } m_timeSeriesCanvas->nextTick(); - for(int i = 0; i < NUM_WALKERS;i++){ + for (int i = 0; i < NUM_WALKERS; i++) + { m_walkersInPopulation[i]->setEvaluationTime(0); } m_nextReaped = 0; } -void NN3DWalkersExample::reap() { +void NN3DWalkersExample::reap() +{ int reaped = 0; - for(int i = NUM_WALKERS-1;i >=(NUM_WALKERS-1)*(1-REAP_QTY); i--){ // reap a certain percentage + for (int i = NUM_WALKERS - 1; i >= (NUM_WALKERS - 1) * (1 - REAP_QTY); i--) + { // reap a certain percentage m_walkersInPopulation[i]->setReaped(true); reaped++; - b3Printf("%i Walker(s) reaped.",reaped); + b3Printf("%i Walker(s) reaped.", reaped); } } -NNWalker* NN3DWalkersExample::getRandomElite(){ - return m_walkersInPopulation[((NUM_WALKERS-1) * SOW_ELITE_QTY) * (rand()/RAND_MAX)]; +NNWalker* NN3DWalkersExample::getRandomElite() +{ + return m_walkersInPopulation[((NUM_WALKERS - 1) * SOW_ELITE_QTY) * (rand() / RAND_MAX)]; } -NNWalker* NN3DWalkersExample::getRandomNonElite(){ - return m_walkersInPopulation[(NUM_WALKERS-1) * SOW_ELITE_QTY + (NUM_WALKERS-1) * (1.0f-SOW_ELITE_QTY) * (rand()/RAND_MAX)]; +NNWalker* NN3DWalkersExample::getRandomNonElite() +{ + return m_walkersInPopulation[(NUM_WALKERS - 1) * SOW_ELITE_QTY + (NUM_WALKERS - 1) * (1.0f - SOW_ELITE_QTY) * (rand() / RAND_MAX)]; } -NNWalker* NN3DWalkersExample::getNextReaped() { - if((NUM_WALKERS-1) - m_nextReaped >= (NUM_WALKERS-1) * (1-REAP_QTY)){ +NNWalker* NN3DWalkersExample::getNextReaped() +{ + if ((NUM_WALKERS - 1) - m_nextReaped >= (NUM_WALKERS - 1) * (1 - REAP_QTY)) + { m_nextReaped++; } - if(m_walkersInPopulation[(NUM_WALKERS-1) - m_nextReaped+1]->isReaped()){ - return m_walkersInPopulation[(NUM_WALKERS-1) - m_nextReaped+1]; + if (m_walkersInPopulation[(NUM_WALKERS - 1) - m_nextReaped + 1]->isReaped()) + { + return m_walkersInPopulation[(NUM_WALKERS - 1) - m_nextReaped + 1]; } - else{ - return NULL; // we asked for too many + else + { + return NULL; // we asked for too many } - } -void NN3DWalkersExample::sow() { +void NN3DWalkersExample::sow() +{ int sow = 0; - for(int i = 0; i < NUM_WALKERS * (SOW_CROSSOVER_QTY);i++){ // create number of new crossover creatures + for (int i = 0; i < NUM_WALKERS * (SOW_CROSSOVER_QTY); i++) + { // create number of new crossover creatures sow++; - b3Printf("%i Walker(s) sown.",sow); - NNWalker* mother = getRandomElite(); // Get elite partner (mother) - NNWalker* father = (SOW_ELITE_PARTNER < rand()/RAND_MAX)?getRandomElite():getRandomNonElite(); //Get elite or random partner (father) + b3Printf("%i Walker(s) sown.", sow); + NNWalker* mother = getRandomElite(); // Get elite partner (mother) + NNWalker* father = (SOW_ELITE_PARTNER < rand() / RAND_MAX) ? getRandomElite() : getRandomNonElite(); //Get elite or random partner (father) NNWalker* offspring = getNextReaped(); - crossover(mother,father, offspring); + crossover(mother, father, offspring); } - for(int i = NUM_WALKERS*SOW_ELITE_QTY; i < NUM_WALKERS*(SOW_ELITE_QTY+SOW_MUTATION_QTY);i++){ // create mutants - mutate(m_walkersInPopulation[i], btScalar(MUTATION_RATE / (NUM_WALKERS * SOW_MUTATION_QTY) * (i-NUM_WALKERS*SOW_ELITE_QTY))); + for (int i = NUM_WALKERS * SOW_ELITE_QTY; i < NUM_WALKERS * (SOW_ELITE_QTY + SOW_MUTATION_QTY); i++) + { // create mutants + mutate(m_walkersInPopulation[i], btScalar(MUTATION_RATE / (NUM_WALKERS * SOW_MUTATION_QTY) * (i - NUM_WALKERS * SOW_ELITE_QTY))); } - for(int i = 0; i < (NUM_WALKERS-1) * (REAP_QTY-SOW_CROSSOVER_QTY);i++){ + for (int i = 0; i < (NUM_WALKERS - 1) * (REAP_QTY - SOW_CROSSOVER_QTY); i++) + { sow++; - b3Printf("%i Walker(s) sown.",sow); + b3Printf("%i Walker(s) sown.", sow); NNWalker* reaped = getNextReaped(); reaped->setReaped(false); reaped->randomizeSensoryMotorWeights(); } } -void NN3DWalkersExample::crossover(NNWalker* mother, NNWalker* father, NNWalker* child) { - for(int i = 0; i < BODYPART_COUNT*JOINT_COUNT;i++){ - btScalar random = ((double) rand() / (RAND_MAX)); +void NN3DWalkersExample::crossover(NNWalker* mother, NNWalker* father, NNWalker* child) +{ + for (int i = 0; i < BODYPART_COUNT * JOINT_COUNT; i++) + { + btScalar random = ((double)rand() / (RAND_MAX)); - if(random >= 0.5f){ + if (random >= 0.5f) + { child->getSensoryMotorWeights()[i] = mother->getSensoryMotorWeights()[i]; } else @@ -882,39 +934,47 @@ void NN3DWalkersExample::crossover(NNWalker* mother, NNWalker* father, NNWalker* } } -void NN3DWalkersExample::mutate(NNWalker* mutant, btScalar mutationRate) { - for(int i = 0; i < BODYPART_COUNT*JOINT_COUNT;i++){ - btScalar random = ((double) rand() / (RAND_MAX)); +void NN3DWalkersExample::mutate(NNWalker* mutant, btScalar mutationRate) +{ + for (int i = 0; i < BODYPART_COUNT * JOINT_COUNT; i++) + { + btScalar random = ((double)rand() / (RAND_MAX)); - if(random >= mutationRate){ - mutant->getSensoryMotorWeights()[i] = ((double) rand() / (RAND_MAX))*2.0f-1.0f; + if (random >= mutationRate) + { + mutant->getSensoryMotorWeights()[i] = ((double)rand() / (RAND_MAX)) * 2.0f - 1.0f; } } } -void evaluationUpdatePreTickCallback(btDynamicsWorld *world, btScalar timeStep) { +void evaluationUpdatePreTickCallback(btDynamicsWorld* world, btScalar timeStep) +{ NN3DWalkersExample* nnWalkersDemo = (NN3DWalkersExample*)world->getWorldUserInfo(); nnWalkersDemo->update(timeStep); } -void NN3DWalkersExample::update(const btScalar timeSinceLastTick) { +void NN3DWalkersExample::update(const btScalar timeSinceLastTick) +{ updateEvaluations(timeSinceLastTick); /**!< We update all evaluations that are in the loop */ scheduleEvaluations(); /**!< Start new evaluations and finish the old ones. */ drawMarkings(); /**!< Draw markings on the ground */ - if(m_Time > m_SpeedupTimestamp + 2.0f){ // print effective speedup - b3Printf("Avg Effective speedup: %f real time",calculatePerformedSpeedup()); + if (m_Time > m_SpeedupTimestamp + 2.0f) + { // print effective speedup + b3Printf("Avg Effective speedup: %f real time", calculatePerformedSpeedup()); m_SpeedupTimestamp = m_Time; } } -void NN3DWalkersExample::updateEvaluations(const btScalar timeSinceLastTick) { +void NN3DWalkersExample::updateEvaluations(const btScalar timeSinceLastTick) +{ btScalar delta = timeSinceLastTick; - btScalar minFPS = 1.f/60.f; - if (delta > minFPS){ + btScalar minFPS = 1.f / 60.f; + if (delta > minFPS) + { delta = minFPS; } @@ -922,48 +982,54 @@ void NN3DWalkersExample::updateEvaluations(const btScalar timeSinceLastTick) { m_targetAccumulator += delta; - for(int i = 0; i < NUM_WALKERS;i++) // evaluation time passes + for (int i = 0; i < NUM_WALKERS; i++) // evaluation time passes { - if(m_walkersInPopulation[i]->isInEvaluation()){ - m_walkersInPopulation[i]->setEvaluationTime(m_walkersInPopulation[i]->getEvaluationTime()+delta); // increase evaluation time + if (m_walkersInPopulation[i]->isInEvaluation()) + { + m_walkersInPopulation[i]->setEvaluationTime(m_walkersInPopulation[i]->getEvaluationTime() + delta); // increase evaluation time } } - if(m_targetAccumulator >= 1.0f /((double)m_targetFrequency)) + if (m_targetAccumulator >= 1.0f / ((double)m_targetFrequency)) { m_targetAccumulator = 0; - for (int r=0; risInEvaluation()) + if (m_walkersInPopulation[r]->isInEvaluation()) { - for (int i = 0; i < 2*NUM_LEGS; i++) + for (int i = 0; i < 2 * NUM_LEGS; i++) { btScalar targetAngle = 0; btHingeConstraint* hingeC = static_cast(m_walkersInPopulation[r]->getJoints()[i]); - if(RANDOM_MOVEMENT){ - targetAngle = ((double) rand() / (RAND_MAX)); + if (RANDOM_MOVEMENT) + { + targetAngle = ((double)rand() / (RAND_MAX)); } - else{ // neural network movement + else + { // neural network movement // accumulate sensor inputs with weights - for(int j = 0; j < JOINT_COUNT;j++){ - targetAngle += m_walkersInPopulation[r]->getSensoryMotorWeights()[i+j*BODYPART_COUNT] * m_walkersInPopulation[r]->getTouchSensor(i); + for (int j = 0; j < JOINT_COUNT; j++) + { + targetAngle += m_walkersInPopulation[r]->getSensoryMotorWeights()[i + j * BODYPART_COUNT] * m_walkersInPopulation[r]->getTouchSensor(i); } // apply the activation function - targetAngle = (tanh(targetAngle)+1.0f)*0.5f; + targetAngle = (tanh(targetAngle) + 1.0f) * 0.5f; } - btScalar targetLimitAngle = hingeC->getLowerLimit() + targetAngle * (hingeC->getUpperLimit() - hingeC->getLowerLimit()); - btScalar currentAngle = hingeC->getHingeAngle(); - btScalar angleError = targetLimitAngle - currentAngle; + btScalar targetLimitAngle = hingeC->getLowerLimit() + targetAngle * (hingeC->getUpperLimit() - hingeC->getLowerLimit()); + btScalar currentAngle = hingeC->getHingeAngle(); + btScalar angleError = targetLimitAngle - currentAngle; btScalar desiredAngularVel = 0; - if(delta){ - desiredAngularVel = angleError/delta; + if (delta) + { + desiredAngularVel = angleError / delta; } - else{ - desiredAngularVel = angleError/0.0001f; + else + { + desiredAngularVel = angleError / 0.0001f; } hingeC->enableAngularMotor(true, desiredAngularVel, m_motorStrength); } @@ -975,23 +1041,27 @@ void NN3DWalkersExample::updateEvaluations(const btScalar timeSinceLastTick) { } } -void NN3DWalkersExample::scheduleEvaluations() { - for(int i = 0; i < NUM_WALKERS;i++){ - - if(m_walkersInPopulation[i]->isInEvaluation() && m_walkersInPopulation[i]->getEvaluationTime() >= EVALUATION_TIME){ /**!< tear down evaluations */ +void NN3DWalkersExample::scheduleEvaluations() +{ + for (int i = 0; i < NUM_WALKERS; i++) + { + if (m_walkersInPopulation[i]->isInEvaluation() && m_walkersInPopulation[i]->getEvaluationTime() >= EVALUATION_TIME) + { /**!< tear down evaluations */ b3Printf("An evaluation finished at %f s. Distance: %f m", m_Time, btSqrt(m_walkersInPopulation[i]->getDistanceFitness())); m_walkersInPopulation[i]->setInEvaluation(false); m_walkersInPopulation[i]->removeFromWorld(); m_evaluationsQty--; } - if(m_evaluationsQty < gParallelEvaluations && !m_walkersInPopulation[i]->isInEvaluation() && m_walkersInPopulation[i]->getEvaluationTime() == 0){ /**!< Setup the new evaluations */ - b3Printf("An evaluation started at %f s.",m_Time); + if (m_evaluationsQty < gParallelEvaluations && !m_walkersInPopulation[i]->isInEvaluation() && m_walkersInPopulation[i]->getEvaluationTime() == 0) + { /**!< Setup the new evaluations */ + b3Printf("An evaluation started at %f s.", m_Time); m_evaluationsQty++; m_walkersInPopulation[i]->setInEvaluation(true); - if(m_walkersInPopulation[i]->getEvaluationTime() == 0){ // reset to origin if the evaluation did not yet run - m_walkersInPopulation[i]->resetAt(btVector3(0,0,0)); + if (m_walkersInPopulation[i]->getEvaluationTime() == 0) + { // reset to origin if the evaluation did not yet run + m_walkersInPopulation[i]->resetAt(btVector3(0, 0, 0)); } m_walkersInPopulation[i]->addToWorld(); @@ -999,37 +1069,44 @@ void NN3DWalkersExample::scheduleEvaluations() { } } - if(m_evaluationsQty == 0){ // if there are no more evaluations possible - rateEvaluations(); // rate evaluations by sorting them based on their fitness + if (m_evaluationsQty == 0) + { // if there are no more evaluations possible + rateEvaluations(); // rate evaluations by sorting them based on their fitness - reap(); // reap worst performing walkers + reap(); // reap worst performing walkers - sow(); // crossover & mutate and sow new walkers + sow(); // crossover & mutate and sow new walkers b3Printf("### A new generation started. ###"); } } -void NN3DWalkersExample::drawMarkings() { - if(!mIsHeadless){ - for(int i = 0; i < NUM_WALKERS;i++) // draw current distance plates of moving walkers +void NN3DWalkersExample::drawMarkings() +{ + if (!mIsHeadless) + { + for (int i = 0; i < NUM_WALKERS; i++) // draw current distance plates of moving walkers { - if(m_walkersInPopulation[i]->isInEvaluation()){ + if (m_walkersInPopulation[i]->isInEvaluation()) + { btVector3 walkerPosition = m_walkersInPopulation[i]->getPosition(); char performance[20]; sprintf(performance, "%.2f m", btSqrt(m_walkersInPopulation[i]->getDistanceFitness())); - m_guiHelper->drawText3D(performance,walkerPosition.x(),walkerPosition.y()+1,walkerPosition.z(),1); + m_guiHelper->drawText3D(performance, walkerPosition.x(), walkerPosition.y() + 1, walkerPosition.z(), 1); } } - for(int i = 2; i < 50; i+=2){ // draw distance circles - if(m_dynamicsWorld->getDebugDrawer()){ - m_dynamicsWorld->getDebugDrawer()->drawArc(btVector3(0,0,0),btVector3(0,1,0),btVector3(1,0,0),btScalar(i), btScalar(i),btScalar(0),btScalar(SIMD_2_PI),btVector3(10*i,0,0),false); + for (int i = 2; i < 50; i += 2) + { // draw distance circles + if (m_dynamicsWorld->getDebugDrawer()) + { + m_dynamicsWorld->getDebugDrawer()->drawArc(btVector3(0, 0, 0), btVector3(0, 1, 0), btVector3(1, 0, 0), btScalar(i), btScalar(i), btScalar(0), btScalar(SIMD_2_PI), btVector3(10 * i, 0, 0), false); } } } } -void NN3DWalkersExample::printWalkerConfigs(){ +void NN3DWalkersExample::printWalkerConfigs() +{ #if 0 char configString[25 + NUM_WALKERS*BODYPART_COUNT*JOINT_COUNT*(3+15+1) + NUM_WALKERS*4 + 1]; // 15 precision + [],\n char* runner = configString; diff --git a/examples/Evolution/NN3DWalkers.h b/examples/Evolution/NN3DWalkers.h index 59105f94c..26a7bf813 100755 --- a/examples/Evolution/NN3DWalkers.h +++ b/examples/Evolution/NN3DWalkers.h @@ -16,7 +16,6 @@ subject to the following restrictions: #ifndef ET_NN_3D_WALKERS_EXAMPLE_H #define ET_NN_3D_WALKERS_EXAMPLE_H -class CommonExampleInterface* ET_NN3DWalkersCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* ET_NN3DWalkersCreateFunc(struct CommonExampleOptions& options); - -#endif //ET_NN_3D_WALKERS_EXAMPLE_H +#endif //ET_NN_3D_WALKERS_EXAMPLE_H diff --git a/examples/Evolution/NN3DWalkersTimeWarpBase.h b/examples/Evolution/NN3DWalkersTimeWarpBase.h index 0c97c3850..c134ac606 100644 --- a/examples/Evolution/NN3DWalkersTimeWarpBase.h +++ b/examples/Evolution/NN3DWalkersTimeWarpBase.h @@ -19,7 +19,7 @@ #include "btBulletDynamicsCommon.h" #include "LinearMath/btVector3.h" #include "LinearMath/btAlignedObjectArray.h" -#include "LinearMath/btQuickprof.h" // Use your own timer, this timer is only used as we lack another timer +#include "LinearMath/btQuickprof.h" // Use your own timer, this timer is only used as we lack another timer #include "../CommonInterfaces/CommonRigidBodyBase.h" #include "../CommonInterfaces/CommonParameterInterface.h" @@ -34,56 +34,58 @@ #include "BulletDynamics/MLCPSolvers/btLemkeSolver.h" #include "BulletDynamics/MLCPSolvers/btMLCPSolver.h" -#include "../Utils/b3ERPCFMHelper.hpp" // ERP/CFM setting utils +#include "../Utils/b3ERPCFMHelper.hpp" // ERP/CFM setting utils -static btScalar gSimulationSpeed = 1; // default simulation speed at startup +static btScalar gSimulationSpeed = 1; // default simulation speed at startup // the current simulation speeds to choose from (the slider will snap to those using a custom form of snapping) -namespace SimulationSpeeds { -static double/*0*/PAUSE = 0; -static double/*1*/QUARTER_SPEED = 0.25; -static double/*2*/HALF_SPEED = 0.5; -static double/*3*/NORMAL_SPEED = 1; -static double/*4*/DOUBLE_SPEED = 2; -static double/*5*/QUADRUPLE_SPEED = 4; -static double/*6*/DECUPLE_SPEED = 10; -static double/*7*/CENTUPLE_SPEED = 100; -static double/*8*/QUINCENTUPLE_SPEED = 500; +namespace SimulationSpeeds +{ +static double /*0*/ PAUSE = 0; +static double /*1*/ QUARTER_SPEED = 0.25; +static double /*2*/ HALF_SPEED = 0.5; +static double /*3*/ NORMAL_SPEED = 1; +static double /*4*/ DOUBLE_SPEED = 2; +static double /*5*/ QUADRUPLE_SPEED = 4; +static double /*6*/ DECUPLE_SPEED = 10; +static double /*7*/ CENTUPLE_SPEED = 100; +static double /*8*/ QUINCENTUPLE_SPEED = 500; static double /*9*/ MILLITUPLE_SPEED = 1000; -static double/*0*/MAX_SPEED = MILLITUPLE_SPEED; -static double /**/NUM_SPEEDS = 11; -}; +static double /*0*/ MAX_SPEED = MILLITUPLE_SPEED; +static double /**/ NUM_SPEEDS = 11; +}; // namespace SimulationSpeeds // add speeds from the namespace here static double speeds[] = { SimulationSpeeds::PAUSE, - SimulationSpeeds::QUARTER_SPEED, SimulationSpeeds::HALF_SPEED, - SimulationSpeeds::NORMAL_SPEED, SimulationSpeeds::DOUBLE_SPEED, - SimulationSpeeds::QUADRUPLE_SPEED, SimulationSpeeds::DECUPLE_SPEED, - SimulationSpeeds::CENTUPLE_SPEED, SimulationSpeeds::QUINCENTUPLE_SPEED, + SimulationSpeeds::QUARTER_SPEED, SimulationSpeeds::HALF_SPEED, + SimulationSpeeds::NORMAL_SPEED, SimulationSpeeds::DOUBLE_SPEED, + SimulationSpeeds::QUADRUPLE_SPEED, SimulationSpeeds::DECUPLE_SPEED, + SimulationSpeeds::CENTUPLE_SPEED, SimulationSpeeds::QUINCENTUPLE_SPEED, SimulationSpeeds::MILLITUPLE_SPEED}; -static btScalar gSolverIterations = 10; // default number of solver iterations for the iterative solvers +static btScalar gSolverIterations = 10; // default number of solver iterations for the iterative solvers -static bool gIsHeadless = false; // demo runs with graphics by default +static bool gIsHeadless = false; // demo runs with graphics by default -static bool gChangeErpCfm = false; // flag to make recalculation of ERP/CFM +static bool gChangeErpCfm = false; // flag to make recalculation of ERP/CFM -static int gMinSpeed = SimulationSpeeds::PAUSE; // the minimum simulation speed +static int gMinSpeed = SimulationSpeeds::PAUSE; // the minimum simulation speed -static int gMaxSpeed = SimulationSpeeds::MAX_SPEED; // the maximum simulation speed +static int gMaxSpeed = SimulationSpeeds::MAX_SPEED; // the maximum simulation speed -static bool gMaximumSpeed = false; // the demo does not try to achieve maximum stepping speed by default +static bool gMaximumSpeed = false; // the demo does not try to achieve maximum stepping speed by default -static bool gInterpolate = false; // the demo does not use any bullet interpolated physics substeps +static bool gInterpolate = false; // the demo does not use any bullet interpolated physics substeps -static bool useSplitImpulse = true; // split impulse fixes issues with restitution in Baumgarte stabilization +static bool useSplitImpulse = true; // split impulse fixes issues with restitution in Baumgarte stabilization // http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=7117&p=24631&hilit=Baumgarte#p24631 // disabling continuous collision detection can also fix issues with restitution, though CCD is disabled by default an only kicks in at higher speeds // set CCD speed threshold and testing sphere radius per rigidbody (rb->setCCDSpeedThreshold()) // all supported solvers by bullet -enum SolverEnumType { +enum SolverEnumType +{ SEQUENTIALIMPULSESOLVER = 0, GAUSSSEIDELSOLVER = 1, NNCGSOLVER = 2, @@ -93,20 +95,20 @@ enum SolverEnumType { NUM_SOLVERS = 6 }; - // solvers can be changed by drop down menu -namespace SolverType { +namespace SolverType +{ static char SEQUENTIALIMPULSESOLVER[] = "Sequential Impulse Solver"; static char GAUSSSEIDELSOLVER[] = "Gauss-Seidel Solver"; static char NNCGSOLVER[] = "NNCG Solver"; static char DANZIGSOLVER[] = "Danzig Solver"; static char LEMKESOLVER[] = "Lemke Solver"; static char FSSOLVER[] = "FeatherStone Solver"; -}; +}; // namespace SolverType static const char* solverTypes[NUM_SOLVERS]; -static SolverEnumType SOLVER_TYPE = SEQUENTIALIMPULSESOLVER; // You can switch the solver here +static SolverEnumType SOLVER_TYPE = SEQUENTIALIMPULSESOLVER; // You can switch the solver here //TODO:s=== //TODO: Give specific explanations about solver values @@ -115,19 +117,19 @@ static SolverEnumType SOLVER_TYPE = SEQUENTIALIMPULSESOLVER; // You can switch t * Step size of the bullet physics simulator (solverAccuracy). Accuracy versus speed. */ // Choose an appropriate number of steps per second for your needs -static btScalar gPhysicsStepsPerSecond = 60.0f; // Default number of steps +static btScalar gPhysicsStepsPerSecond = 60.0f; // Default number of steps //static btScalar gPhysicsStepsPerSecond = 120.0f; // Double steps for more accuracy //static btScalar gPhysicsStepsPerSecond = 240.0f; // For high accuracy //static btScalar gPhysicsStepsPerSecond = 1000.0f; // Very high accuracy // appropriate inverses for seconds and milliseconds -static double fixedPhysicsStepSizeSec = 1.0f / gPhysicsStepsPerSecond; // steps size in seconds -static double fixedPhysicsStepSizeMilli = 1000.0f / gPhysicsStepsPerSecond; // step size in milliseconds +static double fixedPhysicsStepSizeSec = 1.0f / gPhysicsStepsPerSecond; // steps size in seconds +static double fixedPhysicsStepSizeMilli = 1000.0f / gPhysicsStepsPerSecond; // step size in milliseconds -static btScalar gApplicationFrequency = 60.0f; // number of internal application ticks per second -static int gApplicationTick = 1000.0f / gApplicationFrequency; //ms +static btScalar gApplicationFrequency = 60.0f; // number of internal application ticks per second +static int gApplicationTick = 1000.0f / gApplicationFrequency; //ms -static btScalar gFramesPerSecond = 30.0f; // number of frames per second +static btScalar gFramesPerSecond = 30.0f; // number of frames per second static btScalar gERPSpringK = 10; static btScalar gERPDamperC = 1; @@ -138,42 +140,49 @@ static btScalar gCFMSingularityAvoidance = 0; //GUI related parameter changing helpers -inline void twxChangePhysicsStepsPerSecond(float physicsStepsPerSecond, void*) { // function to change simulation physics steps per second +inline void twxChangePhysicsStepsPerSecond(float physicsStepsPerSecond, void*) +{ // function to change simulation physics steps per second gPhysicsStepsPerSecond = physicsStepsPerSecond; } -inline void twxChangeFPS(float framesPerSecond, void*) { +inline void twxChangeFPS(float framesPerSecond, void*) +{ gFramesPerSecond = framesPerSecond; } -inline void twxChangeERPCFM(float notUsed, void*) { // function to change ERP/CFM appropriately +inline void twxChangeERPCFM(float notUsed, void*) +{ // function to change ERP/CFM appropriately gChangeErpCfm = true; } -inline void changeSolver(int comboboxId, const char* item, void* userPointer) { // function to change the solver - for(int i = 0; i < NUM_SOLVERS;i++){ - if(strcmp(solverTypes[i], item) == 0){ // if the strings are equal +inline void changeSolver(int comboboxId, const char* item, void* userPointer) +{ // function to change the solver + for (int i = 0; i < NUM_SOLVERS; i++) + { + if (strcmp(solverTypes[i], item) == 0) + { // if the strings are equal SOLVER_TYPE = ((SolverEnumType)i); - b3Printf("=%s=\n Reset the simulation by double clicking it in the menu list.",item); + b3Printf("=%s=\n Reset the simulation by double clicking it in the menu list.", item); return; } } b3Printf("No Change"); } - -inline void twxChangeSolverIterations(float notUsed, void* userPtr) { // change the solver iterations - - +inline void twxChangeSolverIterations(float notUsed, void* userPtr) +{ // change the solver iterations } -inline void clampToCustomSpeedNotches(float speed, void*) { // function to clamp to custom speed notches +inline void clampToCustomSpeedNotches(float speed, void*) +{ // function to clamp to custom speed notches double minSpeed = 0; double minSpeedDist = SimulationSpeeds::MAX_SPEED; - for (int i = 0; i < SimulationSpeeds::NUM_SPEEDS; i++) { - double speedDist = (speeds[i]-speed >= 0)?speeds[i]-speed:speed-speeds[i]; // float absolute + for (int i = 0; i < SimulationSpeeds::NUM_SPEEDS; i++) + { + double speedDist = (speeds[i] - speed >= 0) ? speeds[i] - speed : speed - speeds[i]; // float absolute - if (minSpeedDist > speedDist) { + if (minSpeedDist > speedDist) + { minSpeedDist = speedDist; minSpeed = speeds[i]; } @@ -181,92 +190,96 @@ inline void clampToCustomSpeedNotches(float speed, void*) { // function to clamp gSimulationSpeed = minSpeed; } -inline void switchInterpolated(int buttonId, bool buttonState, void* userPointer){ // toggle if interpolation steps are taken - gInterpolate=!gInterpolate; -// b3Printf("Interpolate substeps %s", gInterpolate?"on":"off"); +inline void switchInterpolated(int buttonId, bool buttonState, void* userPointer) +{ // toggle if interpolation steps are taken + gInterpolate = !gInterpolate; + // b3Printf("Interpolate substeps %s", gInterpolate?"on":"off"); } -inline void switchHeadless(int buttonId, bool buttonState, void* userPointer){ // toggle if the demo should run headless - gIsHeadless=!gIsHeadless; -// b3Printf("Run headless %s", gIsHeadless?"on":"off"); +inline void switchHeadless(int buttonId, bool buttonState, void* userPointer) +{ // toggle if the demo should run headless + gIsHeadless = !gIsHeadless; + // b3Printf("Run headless %s", gIsHeadless?"on":"off"); } -inline void switchMaximumSpeed(int buttonId, bool buttonState, void* userPointer){ // toggle it the demo should run as fast as possible -// b3Printf("Run maximum speed %s", gMaximumSpeed?"on":"off"); +inline void switchMaximumSpeed(int buttonId, bool buttonState, void* userPointer) +{ // toggle it the demo should run as fast as possible + // b3Printf("Run maximum speed %s", gMaximumSpeed?"on":"off"); } -inline void setApplicationTick(float frequency, void*){ // set internal application tick - gApplicationTick = 1000.0f/frequency; +inline void setApplicationTick(float frequency, void*) +{ // set internal application tick + gApplicationTick = 1000.0f / frequency; } /** * @link: Gaffer on Games - Fix your timestep: http://gafferongames.com/game-physics/fix-your-timestep/ */ -struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { +struct NN3DWalkersTimeWarpBase : public CommonRigidBodyBase +{ + NN3DWalkersTimeWarpBase(struct GUIHelperInterface* helper) : CommonRigidBodyBase(helper), + mPhysicsStepsPerSecondUpdated(false), + mFramesPerSecondUpdated(false), + mSolverIterationsUpdated(false) + { + // main frame timer initialization + mApplicationStart = mLoopTimer.getTimeMilliseconds(); /**!< Initialize when the application started running */ + mInputClock = mApplicationStart; /**!< Initialize the last time the input was updated */ + mPreviousModelIteration = mApplicationStart; + mThisModelIteration = mApplicationStart; + mApplicationRuntime = mThisModelIteration - mApplicationStart; /**!< Initialize the application runtime */ - NN3DWalkersTimeWarpBase(struct GUIHelperInterface* helper): - CommonRigidBodyBase(helper), - mPhysicsStepsPerSecondUpdated(false), - mFramesPerSecondUpdated(false), - mSolverIterationsUpdated(false) { + // sub frame time initializations + mGraphicsStart = mApplicationStart; /** !< Initialize the last graphics start */ + mModelStart = mApplicationStart; /** !< Initialize the last model start */ + mInputStart = mApplicationStart; /** !< Initialize the last input start */ - // main frame timer initialization - mApplicationStart = mLoopTimer.getTimeMilliseconds(); /**!< Initialize when the application started running */ - mInputClock = mApplicationStart; /**!< Initialize the last time the input was updated */ - mPreviousModelIteration = mApplicationStart; - mThisModelIteration = mApplicationStart; - mApplicationRuntime = mThisModelIteration - mApplicationStart; /**!< Initialize the application runtime */ + mPhysicsStepStart = mApplicationStart; /**!< Initialize the physics step start */ + mPhysicsStepEnd = mApplicationStart; /**!< Initialize the physics step end */ - // sub frame time initializations - mGraphicsStart = mApplicationStart; /** !< Initialize the last graphics start */ - mModelStart = mApplicationStart; /** !< Initialize the last model start */ - mInputStart = mApplicationStart; /** !< Initialize the last input start */ + //durations + mLastGraphicsTick = 0; + mLastModelTick = 0; + mLastInputTick = 0; + mPhysicsTick = 0; - mPhysicsStepStart = mApplicationStart; /**!< Initialize the physics step start */ - mPhysicsStepEnd = mApplicationStart; /**!< Initialize the physics step end */ + mInputDt = 0; + mModelAccumulator = 0; + mFrameTime = 0; - //durations - mLastGraphicsTick = 0; - mLastModelTick = 0; - mLastInputTick = 0; - mPhysicsTick = 0; - - mInputDt = 0; - mModelAccumulator = 0; - mFrameTime = 0; - - fpsTimeStamp = mLoopTimer.getTimeMilliseconds(); // to time the fps - fpsStep = 1000.0f/gFramesPerSecond; - - // performance measurements for this demo - performanceTimestamp = 0; - performedTime = 0; // time the physics steps consumed - speedUpPrintTimeStamp = mLoopTimer.getTimeSeconds(); // timer to print the speed up periodically - mLoopTimer.reset(); - } - - ~NN3DWalkersTimeWarpBase(){ + fpsTimeStamp = mLoopTimer.getTimeMilliseconds(); // to time the fps + fpsStep = 1000.0f / gFramesPerSecond; + // performance measurements for this demo + performanceTimestamp = 0; + performedTime = 0; // time the physics steps consumed + speedUpPrintTimeStamp = mLoopTimer.getTimeSeconds(); // timer to print the speed up periodically + mLoopTimer.reset(); } + ~NN3DWalkersTimeWarpBase() + { + } - void initPhysics(){ // initialize the demo + void initPhysics() + { // initialize the demo - setupBasicParamInterface(); // setup adjustable sliders and buttons for parameters + setupBasicParamInterface(); // setup adjustable sliders and buttons for parameters - m_guiHelper->setUpAxis(1); // Set Y axis as Up axis + m_guiHelper->setUpAxis(1); // Set Y axis as Up axis - createEmptyDynamicsWorld(); // create an empty dynamic world + createEmptyDynamicsWorld(); // create an empty dynamic world m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } - void setupBasicParamInterface(){ // setup the adjustable sliders and button for parameters + void setupBasicParamInterface() + { // setup the adjustable sliders and button for parameters - { // create a slider to adjust the simulation speed + { // create a slider to adjust the simulation speed // Force increase the simulation speed to run the simulation with the same accuracy but a higher speed SliderParams slider("Simulation speed", - &gSimulationSpeed); + &gSimulationSpeed); slider.m_minVal = gMinSpeed; slider.m_maxVal = gMaxSpeed; slider.m_callback = clampToCustomSpeedNotches; @@ -276,41 +289,36 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { slider); } - { // create a button to switch to headless simulation + { // create a button to switch to headless simulation // This turns off the graphics update and therefore results in more time for the model update - ButtonParams button("Run headless",0,true); + ButtonParams button("Run headless", 0, true); button.m_callback = switchHeadless; if (m_guiHelper->getParameterInterface()) m_guiHelper->getParameterInterface()->registerButtonParameter( button); } - - - { // create a button to switch to maximum speed simulation (fully deterministic) + { // create a button to switch to maximum speed simulation (fully deterministic) // Interesting to test the maximal achievable speed on this hardware - ButtonParams button("Run maximum speed",0,true); + ButtonParams button("Run maximum speed", 0, true); button.m_callback = switchMaximumSpeed; if (m_guiHelper->getParameterInterface()) m_guiHelper->getParameterInterface()->registerButtonParameter( button); } - - - { // create a button to switch bullet to perform interpolated substeps to speed up simulation + { // create a button to switch bullet to perform interpolated substeps to speed up simulation // generally, interpolated steps are a good speed-up and should only be avoided if higher accuracy is needed (research purposes etc.) - ButtonParams button("Perform interpolated substeps",0,true); + ButtonParams button("Perform interpolated substeps", 0, true); button.m_callback = switchInterpolated; if (m_guiHelper->getParameterInterface()) m_guiHelper->getParameterInterface()->registerButtonParameter( button); } - } - void setupAdvancedParamInterface(){ - + void setupAdvancedParamInterface() + { solverTypes[0] = SolverType::SEQUENTIALIMPULSESOLVER; solverTypes[1] = SolverType::GAUSSSEIDELSOLVER; solverTypes[2] = SolverType::NNCGSOLVER; @@ -325,16 +333,16 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { comboParams.m_startItem = SOLVER_TYPE; comboParams.m_callback = changeSolver; - comboParams.m_items=solverTypes; + comboParams.m_items = solverTypes; m_guiHelper->getParameterInterface()->registerComboBox(comboParams); } - { // create a slider to adjust the number of internal application ticks + { // create a slider to adjust the number of internal application ticks // The set application tick should contain enough time to perform a full cycle of model update (physics and input) // and view update (graphics) with average application load. The graphics and input update determine the remaining time // for the physics update SliderParams slider("Application Ticks", - &gApplicationFrequency); + &gApplicationFrequency); slider.m_minVal = gMinSpeed; slider.m_maxVal = gMaxSpeed; slider.m_callback = setApplicationTick; @@ -344,7 +352,7 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { slider); } - { // create a slider to adjust the number of physics steps per second + { // create a slider to adjust the number of physics steps per second // The default number of steps is at 60, which is appropriate for most general simulations // For simulations with higher complexity or if you experience undesired behavior, try increasing the number of steps per second // Alternatively, try increasing the number of solver iterations if you experience jittering constraints due to non-converging solutions @@ -358,7 +366,7 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { slider); } - { // create a slider to adjust the number of frames per second + { // create a slider to adjust the number of frames per second SliderParams slider("Frames per second", &gFramesPerSecond); slider.m_minVal = 0; slider.m_maxVal = 200; @@ -369,7 +377,7 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { slider); } - { // create a slider to adjust the number of solver iterations to converge to a solution + { // create a slider to adjust the number of solver iterations to converge to a solution // more complex simulations might need a higher number of iterations to converge, it also // depends on the type of solver. SliderParams slider( @@ -378,7 +386,7 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { slider.m_minVal = 0; slider.m_maxVal = 1000; slider.m_callback = twxChangePhysicsStepsPerSecond; - slider.m_clampToIntegers = true; + slider.m_clampToIntegers = true; m_guiHelper->getParameterInterface()->registerSliderFloatParameter( slider); } @@ -386,7 +394,7 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { // ERP/CFM sliders // Advanced users: Check descriptions of ERP/CFM in BulletUtils.cpp - { // create a slider to adjust ERP Spring k constant + { // create a slider to adjust ERP Spring k constant SliderParams slider("Global ERP Spring k (F=k*x)", &gERPSpringK); slider.m_minVal = 0; slider.m_maxVal = 10; @@ -397,7 +405,7 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { slider); } - { // create a slider to adjust ERP damper c constant + { // create a slider to adjust ERP damper c constant SliderParams slider("Global ERP damper c (F=c*xdot)", &gERPDamperC); slider.m_minVal = 0; slider.m_maxVal = 10; @@ -408,7 +416,7 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { slider); } - { // create a slider to adjust CFM Spring k constant + { // create a slider to adjust CFM Spring k constant SliderParams slider("Global CFM Spring k (F=k*x)", &gCFMSpringK); slider.m_minVal = 0; slider.m_maxVal = 10; @@ -419,7 +427,7 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { slider); } - { // create a slider to adjust CFM damper c constant + { // create a slider to adjust CFM damper c constant SliderParams slider("Global CFM damper c (F=c*xdot)", &gCFMDamperC); slider.m_minVal = 0; slider.m_maxVal = 10; @@ -430,7 +438,7 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { slider); } - { // create a slider to adjust CFM damper c constant + { // create a slider to adjust CFM damper c constant SliderParams slider("Global CFM singularity avoidance", &gCFMSingularityAvoidance); slider.m_minVal = 0; slider.m_maxVal = 10; @@ -440,11 +448,10 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { m_guiHelper->getParameterInterface()->registerSliderFloatParameter( slider); } - - } - void createEmptyDynamicsWorld(){ // create an empty dynamics worlds according to the chosen settings via statics (top section of code) + void createEmptyDynamicsWorld() + { // create an empty dynamics worlds according to the chosen settings via statics (top section of code) ///collision configuration contains default setup for memory, collision setup m_collisionConfiguration = new btDefaultCollisionConfiguration(); @@ -457,130 +464,143 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { m_broadphase = new btDbvtBroadphase(); // different solvers require different settings - switch (SOLVER_TYPE) { - case SEQUENTIALIMPULSESOLVER: { -// b3Printf("=%s=",SolverType::SEQUENTIALIMPULSESOLVER); - m_solver = new btSequentialImpulseConstraintSolver(); - break; - } - case NNCGSOLVER: { -// b3Printf("=%s=",SolverType::NNCGSOLVER); - m_solver = new btNNCGConstraintSolver(); - break; - } - case DANZIGSOLVER: { -// b3Printf("=%s=",SolverType::DANZIGSOLVER); - btDantzigSolver* mlcp = new btDantzigSolver(); - m_solver = new btMLCPSolver(mlcp); - break; - } - case GAUSSSEIDELSOLVER: { -// b3Printf("=%s=",SolverType::GAUSSSEIDELSOLVER); - btSolveProjectedGaussSeidel* mlcp = new btSolveProjectedGaussSeidel(); - m_solver = new btMLCPSolver(mlcp); - break; - } - case LEMKESOLVER: { -// b3Printf("=%s=",SolverType::LEMKESOLVER); - btLemkeSolver* mlcp = new btLemkeSolver(); - m_solver = new btMLCPSolver(mlcp); - break; - } - case FSSOLVER: { -// b3Printf("=%s=",SolverType::FSSOLVER); - //Use the btMultiBodyConstraintSolver for Featherstone btMultiBody support - m_solver = new btMultiBodyConstraintSolver; + switch (SOLVER_TYPE) + { + case SEQUENTIALIMPULSESOLVER: + { + // b3Printf("=%s=",SolverType::SEQUENTIALIMPULSESOLVER); + m_solver = new btSequentialImpulseConstraintSolver(); + break; + } + case NNCGSOLVER: + { + // b3Printf("=%s=",SolverType::NNCGSOLVER); + m_solver = new btNNCGConstraintSolver(); + break; + } + case DANZIGSOLVER: + { + // b3Printf("=%s=",SolverType::DANZIGSOLVER); + btDantzigSolver* mlcp = new btDantzigSolver(); + m_solver = new btMLCPSolver(mlcp); + break; + } + case GAUSSSEIDELSOLVER: + { + // b3Printf("=%s=",SolverType::GAUSSSEIDELSOLVER); + btSolveProjectedGaussSeidel* mlcp = new btSolveProjectedGaussSeidel(); + m_solver = new btMLCPSolver(mlcp); + break; + } + case LEMKESOLVER: + { + // b3Printf("=%s=",SolverType::LEMKESOLVER); + btLemkeSolver* mlcp = new btLemkeSolver(); + m_solver = new btMLCPSolver(mlcp); + break; + } + case FSSOLVER: + { + // b3Printf("=%s=",SolverType::FSSOLVER); + //Use the btMultiBodyConstraintSolver for Featherstone btMultiBody support + m_solver = new btMultiBodyConstraintSolver; - break; - } - default: - break; + break; + } + default: + break; } - if (SOLVER_TYPE != FSSOLVER) { + if (SOLVER_TYPE != FSSOLVER) + { //TODO: Set parameters for other solvers m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, - m_broadphase, m_solver, m_collisionConfiguration); + m_broadphase, m_solver, m_collisionConfiguration); - if (SOLVER_TYPE == DANZIGSOLVER || SOLVER_TYPE == GAUSSSEIDELSOLVER) { - m_dynamicsWorld->getSolverInfo().m_minimumSolverBatchSize = 1; //for mlcp solver it is better to have a small A matrix - } else { - m_dynamicsWorld->getSolverInfo().m_minimumSolverBatchSize = 128; //for direct solver, it is better to solve multiple objects together, small batches have high overhead + if (SOLVER_TYPE == DANZIGSOLVER || SOLVER_TYPE == GAUSSSEIDELSOLVER) + { + m_dynamicsWorld->getSolverInfo().m_minimumSolverBatchSize = 1; //for mlcp solver it is better to have a small A matrix + } + else + { + m_dynamicsWorld->getSolverInfo().m_minimumSolverBatchSize = 128; //for direct solver, it is better to solve multiple objects together, small batches have high overhead } - m_dynamicsWorld->getDispatchInfo().m_useContinuous = true; // set continuous collision - + m_dynamicsWorld->getDispatchInfo().m_useContinuous = true; // set continuous collision } - else{ + else + { //use btMultiBodyDynamicsWorld for Featherstone btMultiBody support m_dynamicsWorld = new btMultiBodyDynamicsWorld(m_dispatcher, - m_broadphase, (btMultiBodyConstraintSolver*) m_solver, - m_collisionConfiguration); + m_broadphase, (btMultiBodyConstraintSolver*)m_solver, + m_collisionConfiguration); } - changeERPCFM(); // set appropriate ERP/CFM values according to the string and damper properties of the constraint + changeERPCFM(); // set appropriate ERP/CFM values according to the string and damper properties of the constraint - if (useSplitImpulse) { // If you experience strong repulsion forces in your constraints, it might help to enable the split impulse feature - m_dynamicsWorld->getSolverInfo().m_splitImpulse = 1; //enable split impulse feature - // m_dynamicsWorld->getSolverInfo().m_splitImpulsePenetrationThreshold = - // -0.02; - // m_dynamicsWorld->getSolverInfo().m_erp2 = BulletUtils::getERP( - // fixedPhysicsStepSizeSec, 10, 1); - // m_dynamicsWorld->getSolverInfo().m_splitImpulseTurnErp = - // BulletUtils::getERP(fixedPhysicsStepSizeSec, 10, 1); -// b3Printf("Using split impulse feature with ERP/TurnERP: (%f,%f)", -// m_dynamicsWorld->getSolverInfo().m_erp2, -// m_dynamicsWorld->getSolverInfo().m_splitImpulseTurnErp); + if (useSplitImpulse) + { // If you experience strong repulsion forces in your constraints, it might help to enable the split impulse feature + m_dynamicsWorld->getSolverInfo().m_splitImpulse = 1; //enable split impulse feature + // m_dynamicsWorld->getSolverInfo().m_splitImpulsePenetrationThreshold = + // -0.02; + // m_dynamicsWorld->getSolverInfo().m_erp2 = BulletUtils::getERP( + // fixedPhysicsStepSizeSec, 10, 1); + // m_dynamicsWorld->getSolverInfo().m_splitImpulseTurnErp = + // BulletUtils::getERP(fixedPhysicsStepSizeSec, 10, 1); + // b3Printf("Using split impulse feature with ERP/TurnERP: (%f,%f)", + // m_dynamicsWorld->getSolverInfo().m_erp2, + // m_dynamicsWorld->getSolverInfo().m_splitImpulseTurnErp); } - m_dynamicsWorld->getSolverInfo().m_numIterations = gSolverIterations; // set the number of solver iterations for iteration based solvers - - m_dynamicsWorld->setGravity(btVector3(0, -9.81f, 0)); // set gravity to -9.81 + m_dynamicsWorld->getSolverInfo().m_numIterations = gSolverIterations; // set the number of solver iterations for iteration based solvers + m_dynamicsWorld->setGravity(btVector3(0, -9.81f, 0)); // set gravity to -9.81 } - btScalar calculatePerformedSpeedup() { // calculate performed speedup + btScalar calculatePerformedSpeedup() + { // calculate performed speedup // we calculate the performed speed up - btScalar speedUp = ((double)performedTime*1000.0)/((double)(mLoopTimer.getTimeMilliseconds()-performanceTimestamp)); -// b3Printf("Avg Effective speedup: %f",speedUp); + btScalar speedUp = ((double)performedTime * 1000.0) / ((double)(mLoopTimer.getTimeMilliseconds() - performanceTimestamp)); + // b3Printf("Avg Effective speedup: %f",speedUp); performedTime = 0; performanceTimestamp = mLoopTimer.getTimeMilliseconds(); return speedUp; } - - - void timeWarpSimulation(float deltaTime) // Override this + void timeWarpSimulation(float deltaTime) // Override this { - } - void stepSimulation(float deltaTime){ // customly step the simulation - do{ - -// // settings - if(mPhysicsStepsPerSecondUpdated){ + void stepSimulation(float deltaTime) + { // customly step the simulation + do + { + // // settings + if (mPhysicsStepsPerSecondUpdated) + { changePhysicsStepsPerSecond(gPhysicsStepsPerSecond); mPhysicsStepsPerSecondUpdated = false; } - if(mFramesPerSecondUpdated){ + if (mFramesPerSecondUpdated) + { changeFPS(gFramesPerSecond); mFramesPerSecondUpdated = false; } - if(gChangeErpCfm){ + if (gChangeErpCfm) + { changeERPCFM(); gChangeErpCfm = false; } - if(mSolverIterationsUpdated){ + if (mSolverIterationsUpdated) + { changeSolverIterations(gSolverIterations); mSolverIterationsUpdated = false; } - // structure according to the canonical game loop // http://www.bulletphysics.org/mediawiki-1.5.8/index.php/Canonical_Game_Loop @@ -591,10 +611,11 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { // model update - here you perform updates of your model, be it the physics model, the game or simulation state or anything not related to graphics and input timeWarpSimulation(deltaTime); - if(mLoopTimer.getTimeSeconds() - speedUpPrintTimeStamp > 1){ + if (mLoopTimer.getTimeSeconds() - speedUpPrintTimeStamp > 1) + { // on reset, we calculate the performed speed up //double speedUp = ((double)performedTime*1000.0)/((double)(mLoopTimer.getTimeMilliseconds()-performanceTimestamp)); -// b3Printf("Avg Effective speedup: %f",speedUp); + // b3Printf("Avg Effective speedup: %f",speedUp); performedTime = 0; performanceTimestamp = mLoopTimer.getTimeMilliseconds(); speedUpPrintTimeStamp = mLoopTimer.getTimeSeconds(); @@ -609,30 +630,34 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { mApplicationRuntime = mThisModelIteration - mApplicationStart; /**!< Update main frame timer (in Milliseconds) */ - mModelStart = mLoopTimer.getTimeMilliseconds(); /**!< Begin with the model update (in Milliseconds)*/ + mModelStart = mLoopTimer.getTimeMilliseconds(); /**!< Begin with the model update (in Milliseconds)*/ mLastGraphicsTick = mModelStart - mGraphicsStart; /**!< Update graphics timer (in Milliseconds) */ - if (gMaximumSpeed /** If maximum speed is enabled*/) { + if (gMaximumSpeed /** If maximum speed is enabled*/) + { performMaxStep(); - } else { /**!< This mode tries to progress as much time as it is expected from the game loop*/ + } + else + { /**!< This mode tries to progress as much time as it is expected from the game loop*/ performSpeedStep(); } mInputStart = mLoopTimer.getTimeMilliseconds(); /**!< Start the input update */ - mLastModelTick = mInputStart - mModelStart; /**!< Calculate the time the model update took */ + mLastModelTick = mInputStart - mModelStart; /**!< Calculate the time the model update took */ //############# // Input update - Game Clock part of the loop /** This runs once every gApplicationTick milliseconds on average */ mInputDt = mThisModelIteration - mInputClock; - if (mInputDt >= gApplicationTick) { + if (mInputDt >= gApplicationTick) + { mInputClock = mThisModelIteration; // mInputHandler.injectInput(); /**!< Inject input into handlers */ // mInputHandler.update(mInputClock); /**!< update elements that work on the current input state */ } mGraphicsStart = mLoopTimer.getTimeMilliseconds(); /**!< Start the graphics update */ - mLastInputTick = mGraphicsStart - mInputStart; /**!< Calculate the time the input injection took */ + mLastInputTick = mGraphicsStart - mInputStart; /**!< Calculate the time the input injection took */ //############# // Graphics update - Here you perform the representation of your model, meaning graphics rendering according to what your game or simulation model describes @@ -643,74 +668,84 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { // "Physics time: %u milliseconds / Graphics time: %u milliseconds / Input time: %u milliseconds / Total time passed: %u milliseconds", // mLastModelTick, mLastGraphicsTick, mLastInputTick, mApplicationRuntime); - }while(mLoopTimer.getTimeMilliseconds() - fpsTimeStamp < fpsStep); // escape the loop if it is time to render + } while (mLoopTimer.getTimeMilliseconds() - fpsTimeStamp < fpsStep); // escape the loop if it is time to render // Unfortunately, the input is not included in the loop, therefore the input update frequency is equal to the fps fpsTimeStamp = mLoopTimer.getTimeMilliseconds(); - } - virtual bool keyboardCallback(int key, int state) + virtual bool keyboardCallback(int key, int state) { - switch(key) + switch (key) { - case '1':{ - gSimulationSpeed = SimulationSpeeds::QUARTER_SPEED; - gMaximumSpeed = false; - return true; + case '1': + { + gSimulationSpeed = SimulationSpeeds::QUARTER_SPEED; + gMaximumSpeed = false; + return true; + } + case '2': + { + gSimulationSpeed = SimulationSpeeds::HALF_SPEED; + gMaximumSpeed = false; + return true; + } + case '3': + { + gSimulationSpeed = SimulationSpeeds::NORMAL_SPEED; + gMaximumSpeed = false; + return true; + } + case '4': + { + gSimulationSpeed = SimulationSpeeds::DOUBLE_SPEED; + gMaximumSpeed = false; + return true; + } + case '5': + { + gSimulationSpeed = SimulationSpeeds::QUADRUPLE_SPEED; + gMaximumSpeed = false; + return true; + } + case '6': + { + gSimulationSpeed = SimulationSpeeds::DECUPLE_SPEED; + gMaximumSpeed = false; + return true; + } + case '7': + { + gSimulationSpeed = SimulationSpeeds::CENTUPLE_SPEED; + gMaximumSpeed = false; + return true; + } + case '8': + { + gSimulationSpeed = SimulationSpeeds::QUINCENTUPLE_SPEED; + gMaximumSpeed = false; + return true; + } + case '9': + { + gSimulationSpeed = SimulationSpeeds::MILLITUPLE_SPEED; + gMaximumSpeed = false; + return true; + } + case '0': + { + gSimulationSpeed = SimulationSpeeds::MAX_SPEED; + gMaximumSpeed = true; + return true; + } } - case '2':{ - gSimulationSpeed = SimulationSpeeds::HALF_SPEED; - gMaximumSpeed = false; - return true; - } - case '3':{ - gSimulationSpeed = SimulationSpeeds::NORMAL_SPEED; - gMaximumSpeed = false; - return true; - } - case '4':{ - gSimulationSpeed = SimulationSpeeds::DOUBLE_SPEED; - gMaximumSpeed = false; - return true; - } - case '5':{ - gSimulationSpeed = SimulationSpeeds::QUADRUPLE_SPEED; - gMaximumSpeed = false; - return true; - } - case '6':{ - gSimulationSpeed = SimulationSpeeds::DECUPLE_SPEED; - gMaximumSpeed = false; - return true; - } - case '7':{ - gSimulationSpeed = SimulationSpeeds::CENTUPLE_SPEED; - gMaximumSpeed = false; - return true; - } - case '8':{ - gSimulationSpeed = SimulationSpeeds::QUINCENTUPLE_SPEED; - gMaximumSpeed = false; - return true; - } - case '9':{ - gSimulationSpeed = SimulationSpeeds::MILLITUPLE_SPEED; - gMaximumSpeed = false; - return true; - } - case '0':{ - gSimulationSpeed = SimulationSpeeds::MAX_SPEED; - gMaximumSpeed = true; - return true; - } - } - return CommonRigidBodyBase::keyboardCallback(key,state); + return CommonRigidBodyBase::keyboardCallback(key, state); } - - void changePhysicsStepsPerSecond(float physicsStepsPerSecond){ // change the simulation accuracy - if (m_dynamicsWorld && physicsStepsPerSecond) { + void changePhysicsStepsPerSecond(float physicsStepsPerSecond) + { // change the simulation accuracy + if (m_dynamicsWorld && physicsStepsPerSecond) + { fixedPhysicsStepSizeSec = 1.0f / physicsStepsPerSecond; fixedPhysicsStepSizeMilli = 1000.0f / physicsStepsPerSecond; @@ -718,65 +753,76 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { } } - void changeERPCFM(){ // Change ERP/CFM appropriately to the timestep and the ERP/CFM parameters above - if(m_dynamicsWorld){ - m_dynamicsWorld->getSolverInfo().m_erp = b3ERPCFMHelper::getERP( // set the error reduction parameter - fixedPhysicsStepSizeSec, // step size per second - gERPSpringK, // k of a spring in the equation F = k * x (x:position) - gERPDamperC); // k of a damper in the equation F = k * v (v:velocity) + void changeERPCFM() + { // Change ERP/CFM appropriately to the timestep and the ERP/CFM parameters above + if (m_dynamicsWorld) + { + m_dynamicsWorld->getSolverInfo().m_erp = b3ERPCFMHelper::getERP( // set the error reduction parameter + fixedPhysicsStepSizeSec, // step size per second + gERPSpringK, // k of a spring in the equation F = k * x (x:position) + gERPDamperC); // k of a damper in the equation F = k * v (v:velocity) - m_dynamicsWorld->getSolverInfo().m_globalCfm = b3ERPCFMHelper::getCFM( // set the constraint force mixing according to the time step - gCFMSingularityAvoidance, // singularity avoidance (if you experience unsolvable constraints, increase this value - fixedPhysicsStepSizeSec, // steps size per second - gCFMSpringK, // k of a spring in the equation F = k * x (x:position) - gCFMDamperC); // k of a damper in the equation F = k * v (v:velocity) + m_dynamicsWorld->getSolverInfo().m_globalCfm = b3ERPCFMHelper::getCFM( // set the constraint force mixing according to the time step + gCFMSingularityAvoidance, // singularity avoidance (if you experience unsolvable constraints, increase this value + fixedPhysicsStepSizeSec, // steps size per second + gCFMSpringK, // k of a spring in the equation F = k * x (x:position) + gCFMDamperC); // k of a damper in the equation F = k * v (v:velocity) -// b3Printf("Bullet DynamicsWorld ERP: %f", -// m_dynamicsWorld->getSolverInfo().m_erp); + // b3Printf("Bullet DynamicsWorld ERP: %f", + // m_dynamicsWorld->getSolverInfo().m_erp); -// b3Printf("Bullet DynamicsWorld CFM: %f", -// m_dynamicsWorld->getSolverInfo().m_globalCfm); + // b3Printf("Bullet DynamicsWorld CFM: %f", + // m_dynamicsWorld->getSolverInfo().m_globalCfm); } } - void changeSolverIterations(int iterations){ // change the number of iterations + void changeSolverIterations(int iterations) + { // change the number of iterations m_dynamicsWorld->getSolverInfo().m_numIterations = iterations; } - void changeFPS(float framesPerSecond){ // change the frames per second + void changeFPS(float framesPerSecond) + { // change the frames per second fpsStep = 1000.0f / gFramesPerSecond; } - void performTrueSteps(btScalar timeStep){ // physics stepping without interpolated substeps - int subSteps = floor((timeStep / fixedPhysicsStepSizeSec)+0.5); /**!< Calculate the number of full normal time steps we can take */ + void performTrueSteps(btScalar timeStep) + { // physics stepping without interpolated substeps + int subSteps = floor((timeStep / fixedPhysicsStepSizeSec) + 0.5); /**!< Calculate the number of full normal time steps we can take */ - for (int i = 0; i < subSteps; i++) { /**!< Perform the number of substeps to reach the timestep*/ - if (timeStep && m_dynamicsWorld) { + for (int i = 0; i < subSteps; i++) + { /**!< Perform the number of substeps to reach the timestep*/ + if (timeStep && m_dynamicsWorld) + { // since we want to perform all proper steps, we perform no interpolated substeps int subSteps = 1; m_dynamicsWorld->stepSimulation(btScalar(timeStep), - btScalar(subSteps), btScalar(fixedPhysicsStepSizeSec)); + btScalar(subSteps), btScalar(fixedPhysicsStepSizeSec)); } } } - void performInterpolatedSteps(btScalar timeStep){ // physics stepping with interpolated substeps - int subSteps = 1 + floor((timeStep / fixedPhysicsStepSizeSec)+0.5); /**!< Calculate the number of full normal time steps we can take, plus 1 for safety of not losing time */ - if (timeStep && m_dynamicsWorld) { - + void performInterpolatedSteps(btScalar timeStep) + { // physics stepping with interpolated substeps + int subSteps = 1 + floor((timeStep / fixedPhysicsStepSizeSec) + 0.5); /**!< Calculate the number of full normal time steps we can take, plus 1 for safety of not losing time */ + if (timeStep && m_dynamicsWorld) + { m_dynamicsWorld->stepSimulation(btScalar(timeStep), btScalar(subSteps), - btScalar(fixedPhysicsStepSizeSec)); /**!< Perform the number of substeps to reach the timestep*/ + btScalar(fixedPhysicsStepSizeSec)); /**!< Perform the number of substeps to reach the timestep*/ } } - void performMaxStep(){ // perform as many steps as possible - if(gApplicationTick >= mLastGraphicsTick + mLastInputTick){ // if the remaining time for graphics is going to be positive + void performMaxStep() + { // perform as many steps as possible + if (gApplicationTick >= mLastGraphicsTick + mLastInputTick) + { // if the remaining time for graphics is going to be positive mPhysicsTick = gApplicationTick /**!< calculate the remaining time for physics (in Milliseconds) */ - - mLastGraphicsTick - mLastInputTick; + - mLastGraphicsTick - mLastInputTick; } - else{ - mPhysicsTick = 0; // no time for physics left / The internal application step is too high + else + { + mPhysicsTick = 0; // no time for physics left / The internal application step is too high } // b3Printf("Application tick: %u",gApplicationTick); @@ -784,18 +830,23 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { // b3Printf("Input tick: %u",mLastInputTick); // b3Printf("Physics tick: %u",mPhysicsTick); - if (mPhysicsTick > 0) { // with positive physics tick we perform as many update steps until the time for it is used up + if (mPhysicsTick > 0) + { // with positive physics tick we perform as many update steps until the time for it is used up mPhysicsStepStart = mLoopTimer.getTimeMilliseconds(); /**!< The physics updates start (in Milliseconds)*/ mPhysicsStepEnd = mPhysicsStepStart; - while (mPhysicsTick > mPhysicsStepEnd - mPhysicsStepStart) { /**!< Update the physics until we run out of time (in Milliseconds) */ + while (mPhysicsTick > mPhysicsStepEnd - mPhysicsStepStart) + { /**!< Update the physics until we run out of time (in Milliseconds) */ // b3Printf("Physics passed: %u", mPhysicsStepEnd - mPhysicsStepStart); double timeStep = fixedPhysicsStepSizeSec; /**!< update the world (in Seconds) */ - if (gInterpolate) { + if (gInterpolate) + { performInterpolatedSteps(timeStep); - } else { + } + else + { performTrueSteps(timeStep); } performedTime += timeStep; @@ -804,11 +855,12 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { } } - - void performSpeedStep(){ // force-perform the number of steps needed to achieve a certain speed (safe to too high speeds, meaning the application will lose time, not the physics) - if (mFrameTime > gApplicationTick) { /** cap frametime to make the application lose time, not the physics (in Milliseconds) */ - mFrameTime = gApplicationTick; // This prevents the physics time accumulator to sum up too much time - } // The simulation therefore gets slower, but still performs all requested physics steps + void performSpeedStep() + { // force-perform the number of steps needed to achieve a certain speed (safe to too high speeds, meaning the application will lose time, not the physics) + if (mFrameTime > gApplicationTick) + { /** cap frametime to make the application lose time, not the physics (in Milliseconds) */ + mFrameTime = gApplicationTick; // This prevents the physics time accumulator to sum up too much time + } // The simulation therefore gets slower, but still performs all requested physics steps mModelAccumulator += mFrameTime; /**!< Accumulate the time the physics simulation has to perform in order to stay in real-time (in Milliseconds) */ // b3Printf("Model time accumulator: %u", mModelAccumulator); @@ -816,49 +868,57 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { int steps = floor(mModelAccumulator / fixedPhysicsStepSizeMilli); /**!< Calculate the number of time steps we can take */ // b3Printf("Next steps: %i", steps); - if (steps > 0) { /**!< Update if we can take at least one step */ + if (steps > 0) + { /**!< Update if we can take at least one step */ double timeStep = gSimulationSpeed * steps * fixedPhysicsStepSizeSec; /**!< update the universe (in Seconds) */ - if (gInterpolate) { - performInterpolatedSteps(timeStep); // perform interpolated steps - } else { - performTrueSteps(timeStep); // perform full steps + if (gInterpolate) + { + performInterpolatedSteps(timeStep); // perform interpolated steps } - performedTime += timeStep; // sum up the performed time for measuring the speed up + else + { + performTrueSteps(timeStep); // perform full steps + } + performedTime += timeStep; // sum up the performed time for measuring the speed up mModelAccumulator -= steps * fixedPhysicsStepSizeMilli; /**!< Remove the time performed by the physics simulation from the accumulator, the remaining time carries over to the next cycle (in Milliseconds) */ } } - void renderScene() { // render the scene - if(!gIsHeadless){ // while the simulation is not running headlessly, render to screen + void renderScene() + { // render the scene + if (!gIsHeadless) + { // while the simulation is not running headlessly, render to screen CommonRigidBodyBase::renderScene(); - if(m_dynamicsWorld->getDebugDrawer()){ + if (m_dynamicsWorld->getDebugDrawer()) + { debugDraw(m_dynamicsWorld->getDebugDrawer()->getDebugMode()); } } mIsHeadless = gIsHeadless; } - void resetCamera() { // reset the camera to its original position + void resetCamera() + { // reset the camera to its original position float dist = 41; float pitch = 52; float yaw = 35; - float targetPos[3] = { 0, 0.46, 0 }; + float targetPos[3] = {0, 0.46, 0}; m_guiHelper->resetCamera(dist, pitch, yaw, targetPos[0], targetPos[1], - targetPos[2]); + targetPos[2]); } // loop timing components ################### //# loop timestamps - btClock mLoopTimer; /**!< The loop timer to time the loop correctly */ - unsigned long int mApplicationStart; /**!< The time the application was started (absolute, in Milliseconds) */ + btClock mLoopTimer; /**!< The loop timer to time the loop correctly */ + unsigned long int mApplicationStart; /**!< The time the application was started (absolute, in Milliseconds) */ unsigned long int mPreviousModelIteration; /**!< The previous model iteration timestamp (absolute, in Milliseconds) */ - unsigned long int mThisModelIteration; /**!< This model iteration timestamp (absolute, in Milliseconds) */ + unsigned long int mThisModelIteration; /**!< This model iteration timestamp (absolute, in Milliseconds) */ //# loop durations - long int mModelAccumulator; /**!< The time to forward the model in this loop iteration (relative, in Milliseconds) */ - unsigned long int mFrameTime; /**!< The time to render a frame (relative, in Milliseconds) */ + long int mModelAccumulator; /**!< The time to forward the model in this loop iteration (relative, in Milliseconds) */ + unsigned long int mFrameTime; /**!< The time to render a frame (relative, in Milliseconds) */ unsigned long int mApplicationRuntime; /**!< The total application runtime (relative, in Milliseconds) */ long int mInputDt; /**!< The time difference of input that has to be fed in */ @@ -870,13 +930,13 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { long int mLastInputTick; /**!< The time it took the input to process last time (relative, in Milliseconds) */ unsigned long int mInputStart; - long int mLastModelTick; /**!< The time it took the model to update last time + long int mLastModelTick; /**!< The time it took the model to update last time This includes the bullet physics update */ unsigned long int mModelStart; /**!< The timestamp the model started updating last (absolute, in Milliseconds)*/ - long int mPhysicsTick; /**!< The time remaining in the loop to update the physics (relative, in Milliseconds)*/ + long int mPhysicsTick; /**!< The time remaining in the loop to update the physics (relative, in Milliseconds)*/ unsigned long int mPhysicsStepStart; /**!< The physics start timestamp (absolute, in Milliseconds) */ - unsigned long int mPhysicsStepEnd; /**!< The last physics step end (absolute, in Milliseconds) */ + unsigned long int mPhysicsStepEnd; /**!< The last physics step end (absolute, in Milliseconds) */ // to measure the performance of the demo double performedTime; @@ -894,5 +954,4 @@ struct NN3DWalkersTimeWarpBase: public CommonRigidBodyBase { bool mIsHeadless; }; -#endif //NN3D_WALKERS_TIME_WARP_BASE_H - +#endif //NN3D_WALKERS_TIME_WARP_BASE_H diff --git a/examples/ExampleBrowser/CollisionShape2TriangleMesh.cpp b/examples/ExampleBrowser/CollisionShape2TriangleMesh.cpp index 378201610..d30e39bb8 100644 --- a/examples/ExampleBrowser/CollisionShape2TriangleMesh.cpp +++ b/examples/ExampleBrowser/CollisionShape2TriangleMesh.cpp @@ -2,12 +2,12 @@ #include "CollisionShape2TriangleMesh.h" #include "btBulletCollisionCommon.h" -#include "BulletCollision/CollisionShapes/btShapeHull.h"//to create a tesselation of a generic btConvexShape +#include "BulletCollision/CollisionShapes/btShapeHull.h" //to create a tesselation of a generic btConvexShape void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTransform& parentTransform, btAlignedObjectArray& vertexPositions, btAlignedObjectArray& vertexNormals, btAlignedObjectArray& indicesOut) { -//todo: support all collision shape types + //todo: support all collision shape types switch (collisionShape->getShapeType()) { case SOFTBODY_SHAPE_PROXYTYPE: @@ -22,31 +22,30 @@ void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTrans btScalar planeConst = staticPlaneShape->getPlaneConstant(); const btVector3& planeNormal = staticPlaneShape->getPlaneNormal(); btVector3 planeOrigin = planeNormal * planeConst; - btVector3 vec0,vec1; - btPlaneSpace1(planeNormal,vec0,vec1); + btVector3 vec0, vec1; + btPlaneSpace1(planeNormal, vec0, vec1); btScalar vecLen = 100.f; btVector3 verts[4]; - verts[0] = planeOrigin + vec0*vecLen + vec1*vecLen; - verts[1] = planeOrigin - vec0*vecLen + vec1*vecLen; - verts[2] = planeOrigin - vec0*vecLen - vec1*vecLen; - verts[3] = planeOrigin + vec0*vecLen - vec1*vecLen; - + verts[0] = planeOrigin + vec0 * vecLen + vec1 * vecLen; + verts[1] = planeOrigin - vec0 * vecLen + vec1 * vecLen; + verts[2] = planeOrigin - vec0 * vecLen - vec1 * vecLen; + verts[3] = planeOrigin + vec0 * vecLen - vec1 * vecLen; + int startIndex = vertexPositions.size(); - indicesOut.push_back(startIndex+0); - indicesOut.push_back(startIndex+1); - indicesOut.push_back(startIndex+2); - indicesOut.push_back(startIndex+0); - indicesOut.push_back(startIndex+2); - indicesOut.push_back(startIndex+3); + indicesOut.push_back(startIndex + 0); + indicesOut.push_back(startIndex + 1); + indicesOut.push_back(startIndex + 2); + indicesOut.push_back(startIndex + 0); + indicesOut.push_back(startIndex + 2); + indicesOut.push_back(startIndex + 3); - btVector3 triNormal = parentTransform.getBasis()*planeNormal; - + btVector3 triNormal = parentTransform.getBasis() * planeNormal; - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) { btVector3 vtxPos; - btVector3 pos =parentTransform*verts[i]; + btVector3 pos = parentTransform * verts[i]; vertexPositions.push_back(pos); vertexNormals.push_back(triNormal); } @@ -54,53 +53,49 @@ void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTrans } case TRIANGLE_MESH_SHAPE_PROXYTYPE: { - - - btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*) collisionShape; + btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)collisionShape; btVector3 trimeshScaling = trimesh->getLocalScaling(); btStridingMeshInterface* meshInterface = trimesh->getMeshInterface(); btAlignedObjectArray vertices; btAlignedObjectArray indices; - - for (int partId=0;partIdgetNumSubParts();partId++) + + for (int partId = 0; partId < meshInterface->getNumSubParts(); partId++) { - - const unsigned char *vertexbase = 0; + const unsigned char* vertexbase = 0; int numverts = 0; PHY_ScalarType type = PHY_INTEGER; int stride = 0; - const unsigned char *indexbase = 0; + const unsigned char* indexbase = 0; int indexstride = 0; int numfaces = 0; PHY_ScalarType indicestype = PHY_INTEGER; //PHY_ScalarType indexType=0; - + btVector3 triangleVerts[3]; - meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,partId); - btVector3 aabbMin,aabbMax; - - for (int triangleIndex = 0 ; triangleIndex < numfaces;triangleIndex++) + meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase, numverts, type, stride, &indexbase, indexstride, numfaces, indicestype, partId); + btVector3 aabbMin, aabbMax; + + for (int triangleIndex = 0; triangleIndex < numfaces; triangleIndex++) { - unsigned int* gfxbase = (unsigned int*)(indexbase+triangleIndex*indexstride); - - for (int j=2;j>=0;j--) + unsigned int* gfxbase = (unsigned int*)(indexbase + triangleIndex * indexstride); + + for (int j = 2; j >= 0; j--) { - - int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; + int graphicsindex = indicestype == PHY_SHORT ? ((unsigned short*)gfxbase)[j] : gfxbase[j]; if (type == PHY_FLOAT) { - float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); + float* graphicsbase = (float*)(vertexbase + graphicsindex * stride); triangleVerts[j] = btVector3( - graphicsbase[0]*trimeshScaling.getX(), - graphicsbase[1]*trimeshScaling.getY(), - graphicsbase[2]*trimeshScaling.getZ()); + graphicsbase[0] * trimeshScaling.getX(), + graphicsbase[1] * trimeshScaling.getY(), + graphicsbase[2] * trimeshScaling.getZ()); } else { - double* graphicsbase = (double*)(vertexbase+graphicsindex*stride); - triangleVerts[j] = btVector3( btScalar(graphicsbase[0]*trimeshScaling.getX()), - btScalar(graphicsbase[1]*trimeshScaling.getY()), - btScalar(graphicsbase[2]*trimeshScaling.getZ())); + double* graphicsbase = (double*)(vertexbase + graphicsindex * stride); + triangleVerts[j] = btVector3(btScalar(graphicsbase[0] * trimeshScaling.getX()), + btScalar(graphicsbase[1] * trimeshScaling.getY()), + btScalar(graphicsbase[2] * trimeshScaling.getZ())); } } indices.push_back(vertices.size()); @@ -110,26 +105,24 @@ void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTrans indices.push_back(vertices.size()); vertices.push_back(triangleVerts[2]); - btVector3 triNormal = (triangleVerts[1]-triangleVerts[0]).cross(triangleVerts[2]-triangleVerts[0]); + btVector3 triNormal = (triangleVerts[1] - triangleVerts[0]).cross(triangleVerts[2] - triangleVerts[0]); btScalar dot = triNormal.dot(triNormal); //cull degenerate triangles - if (dot >= SIMD_EPSILON*SIMD_EPSILON) + if (dot >= SIMD_EPSILON * SIMD_EPSILON) { triNormal /= btSqrt(dot); for (int v = 0; v < 3; v++) { - - btVector3 pos = parentTransform*triangleVerts[v]; + btVector3 pos = parentTransform * triangleVerts[v]; indicesOut.push_back(vertexPositions.size()); vertexPositions.push_back(pos); vertexNormals.push_back(triNormal); } } - } } - + break; } default: @@ -146,24 +139,23 @@ void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTrans //int numVertices = hull->numVertices(); //int numIndices =hull->numIndices(); - for (int t=0;tnumTriangles();t++) + for (int t = 0; t < hull->numTriangles(); t++) { - btVector3 triNormal; - int index0 = hull->getIndexPointer()[t*3+0]; - int index1 = hull->getIndexPointer()[t*3+1]; - int index2 = hull->getIndexPointer()[t*3+2]; - btVector3 pos0 =parentTransform*hull->getVertexPointer()[index0]; - btVector3 pos1 =parentTransform*hull->getVertexPointer()[index1]; - btVector3 pos2 =parentTransform*hull->getVertexPointer()[index2]; - triNormal = (pos1-pos0).cross(pos2-pos0); + int index0 = hull->getIndexPointer()[t * 3 + 0]; + int index1 = hull->getIndexPointer()[t * 3 + 1]; + int index2 = hull->getIndexPointer()[t * 3 + 2]; + btVector3 pos0 = parentTransform * hull->getVertexPointer()[index0]; + btVector3 pos1 = parentTransform * hull->getVertexPointer()[index1]; + btVector3 pos2 = parentTransform * hull->getVertexPointer()[index2]; + triNormal = (pos1 - pos0).cross(pos2 - pos0); triNormal.safeNormalize(); - for (int v=0;v<3;v++) + for (int v = 0; v < 3; v++) { - int index = hull->getIndexPointer()[t*3+v]; - btVector3 pos =parentTransform*hull->getVertexPointer()[index]; + int index = hull->getIndexPointer()[t * 3 + v]; + btVector3 pos = parentTransform * hull->getVertexPointer()[index]; indicesOut.push_back(vertexPositions.size()); vertexPositions.push_back(pos); vertexNormals.push_back(triNormal); @@ -172,31 +164,30 @@ void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTrans } delete hull; } - } else + } + else { if (collisionShape->isCompound()) { - btCompoundShape* compound = (btCompoundShape*) collisionShape; - for (int i=0;igetNumChildShapes();i++) + btCompoundShape* compound = (btCompoundShape*)collisionShape; + for (int i = 0; i < compound->getNumChildShapes(); i++) { - btTransform childWorldTrans = parentTransform * compound->getChildTransform(i); - CollisionShape2TriangleMesh(compound->getChildShape(i),childWorldTrans,vertexPositions,vertexNormals,indicesOut); + CollisionShape2TriangleMesh(compound->getChildShape(i), childWorldTrans, vertexPositions, vertexNormals, indicesOut); } - } else + } + else { - if (collisionShape->getShapeType()==SDF_SHAPE_PROXYTYPE) + if (collisionShape->getShapeType() == SDF_SHAPE_PROXYTYPE) { //not yet - } else + } + else { btAssert(0); } } - } } }; } - - diff --git a/examples/ExampleBrowser/CollisionShape2TriangleMesh.h b/examples/ExampleBrowser/CollisionShape2TriangleMesh.h index 6025d6413..b4aafbb00 100644 --- a/examples/ExampleBrowser/CollisionShape2TriangleMesh.h +++ b/examples/ExampleBrowser/CollisionShape2TriangleMesh.h @@ -7,4 +7,4 @@ class btCollisionShape; void CollisionShape2TriangleMesh(btCollisionShape* collisionShape, const btTransform& parentTransform, btAlignedObjectArray& vertexPositions, btAlignedObjectArray& vertexNormals, btAlignedObjectArray& indicesOut); -#endif //COLLISION_SHAPE_2_GRAPHICS_H +#endif //COLLISION_SHAPE_2_GRAPHICS_H diff --git a/examples/ExampleBrowser/EmptyBrowser.h b/examples/ExampleBrowser/EmptyBrowser.h index 240e4d17f..eea06873b 100644 --- a/examples/ExampleBrowser/EmptyBrowser.h +++ b/examples/ExampleBrowser/EmptyBrowser.h @@ -7,7 +7,6 @@ class EmptyBrowser : public ExampleBrowserInterface { public: - EmptyExample m_emptyExample; virtual CommonExampleInterface* getCurrentExample() @@ -35,4 +34,4 @@ public: } }; -#endif //EMPTY_BROWSER +#endif //EMPTY_BROWSER diff --git a/examples/ExampleBrowser/EmptyExample.h b/examples/ExampleBrowser/EmptyExample.h index af41f8af8..95ba27ffa 100644 --- a/examples/ExampleBrowser/EmptyExample.h +++ b/examples/ExampleBrowser/EmptyExample.h @@ -6,27 +6,22 @@ class EmptyExample : public CommonExampleInterface { public: - EmptyExample() {} - virtual ~EmptyExample(){} + virtual ~EmptyExample() {} static CommonExampleInterface* CreateFunc(struct CommonExampleOptions& /* unusedOptions*/) { return new EmptyExample; } - virtual void initPhysics(){} - virtual void exitPhysics(){} - virtual void stepSimulation(float deltaTime){} - virtual void renderScene(){} - virtual void physicsDebugDraw(int debugFlags){} - virtual bool mouseMoveCallback(float x,float y){ return false;} - virtual bool mouseButtonCallback(int button, int state, float x, float y){return false;} - virtual bool keyboardCallback(int key, int state){return false;} - + virtual void initPhysics() {} + virtual void exitPhysics() {} + virtual void stepSimulation(float deltaTime) {} + virtual void renderScene() {} + virtual void physicsDebugDraw(int debugFlags) {} + virtual bool mouseMoveCallback(float x, float y) { return false; } + virtual bool mouseButtonCallback(int button, int state, float x, float y) { return false; } + virtual bool keyboardCallback(int key, int state) { return false; } }; - - -#endif //EMPTY_EXAMPLE_H - +#endif //EMPTY_EXAMPLE_H diff --git a/examples/ExampleBrowser/ExampleBrowserInterface.h b/examples/ExampleBrowser/ExampleBrowserInterface.h index a3cb5e8d5..5d8ecbd80 100644 --- a/examples/ExampleBrowser/ExampleBrowserInterface.h +++ b/examples/ExampleBrowser/ExampleBrowserInterface.h @@ -5,19 +5,16 @@ class ExampleBrowserInterface { - public: - +public: virtual ~ExampleBrowserInterface() {} virtual CommonExampleInterface* getCurrentExample() = 0; - - virtual bool init(int argc, char* argv[])=0; - virtual void update(float deltaTime)=0; + virtual bool init(int argc, char* argv[]) = 0; - virtual bool requestedExit()=0; + virtual void update(float deltaTime) = 0; + + virtual bool requestedExit() = 0; }; - - -#endif //EXAMPLE_BROWSER_GUI_H \ No newline at end of file +#endif //EXAMPLE_BROWSER_GUI_H \ No newline at end of file diff --git a/examples/ExampleBrowser/ExampleEntries.cpp b/examples/ExampleBrowser/ExampleEntries.cpp index 7a114f35c..683fb8fb5 100644 --- a/examples/ExampleBrowser/ExampleEntries.cpp +++ b/examples/ExampleBrowser/ExampleEntries.cpp @@ -56,7 +56,7 @@ #ifdef B3_ENABLE_TINY_AUDIO #include "../TinyAudio/TinyAudioExample.h" -#endif //B3_ENABLE_TINY_AUDIO +#endif //B3_ENABLE_TINY_AUDIO #ifdef ENABLE_LUA #include "../LuaDemo/LuaPhysicsSetup.h" @@ -67,7 +67,7 @@ #include "../OpenCL/broadphase/PairBench.h" #include "../OpenCL/rigidbody/GpuConvexScene.h" #endif -#endif //B3_USE_CLEW +#endif //B3_USE_CLEW //Extended Tutorial Includes Added by Mobeen and Benelot #include "../ExtendedTutorials/SimpleBox.h" @@ -86,280 +86,262 @@ struct ExampleEntry { - int m_menuLevel; - const char* m_name; - const char* m_description; - CommonExampleInterface::CreateFunc* m_createFunc; - int m_option; + int m_menuLevel; + const char* m_name; + const char* m_description; + CommonExampleInterface::CreateFunc* m_createFunc; + int m_option; ExampleEntry(int menuLevel, const char* name) - :m_menuLevel(menuLevel), m_name(name), m_description(0), m_createFunc(0), m_option(0) + : m_menuLevel(menuLevel), m_name(name), m_description(0), m_createFunc(0), m_option(0) { } - ExampleEntry(int menuLevel, const char* name,const char* description, CommonExampleInterface::CreateFunc* createFunc, int option=0) - :m_menuLevel(menuLevel), m_name(name), m_description(description), m_createFunc(createFunc), m_option(option) + ExampleEntry(int menuLevel, const char* name, const char* description, CommonExampleInterface::CreateFunc* createFunc, int option = 0) + : m_menuLevel(menuLevel), m_name(name), m_description(description), m_createFunc(createFunc), m_option(option) { } }; +static ExampleEntry gDefaultExamples[] = + { + ExampleEntry(0, "API"), + ExampleEntry(1, "Basic Example", "Create some rigid bodies using box collision shapes. This is a good example to familiarize with the basic initialization of Bullet. The Basic Example can also be compiled without graphical user interface, as a console application. Press W for wireframe, A to show AABBs, I to suspend/restart physics simulation. Press D to toggle auto-deactivation of the simulation. ", BasicExampleCreateFunc), -static ExampleEntry gDefaultExamples[]= -{ - ExampleEntry(0,"API"), + ExampleEntry(1, "Rolling Friction", "Damping is often not good enough to keep rounded objects from rolling down a sloped surface. Instead, you can set the rolling friction of a rigid body. Generally it is best to leave the rolling friction to zero, to avoid artifacts.", RollingFrictionCreateFunc), - ExampleEntry(1,"Basic Example","Create some rigid bodies using box collision shapes. This is a good example to familiarize with the basic initialization of Bullet. The Basic Example can also be compiled without graphical user interface, as a console application. Press W for wireframe, A to show AABBs, I to suspend/restart physics simulation. Press D to toggle auto-deactivation of the simulation. ", BasicExampleCreateFunc), + ExampleEntry(1, "Constraints", "Show the use of the various constraints in Bullet. Press the L key to visualize the constraint limits. Press the C key to visualize the constraint frames.", + AllConstraintCreateFunc), - ExampleEntry(1,"Rolling Friction", "Damping is often not good enough to keep rounded objects from rolling down a sloped surface. Instead, you can set the rolling friction of a rigid body. Generally it is best to leave the rolling friction to zero, to avoid artifacts.", RollingFrictionCreateFunc), + ExampleEntry(1, "Motorized Hinge", "Use of a btHingeConstraint. You can adjust the first slider to change the target velocity, and the second slider to adjust the maximum impulse applied to reach the target velocity. Note that the hinge angle can reach beyond -360 and 360 degrees.", ConstraintCreateFunc), + ExampleEntry(1, "TestHingeTorque", "Apply a torque in the hinge axis. This example uses a btHingeConstraint and btRigidBody. The setup is similar to the multi body example TestJointTorque.", + TestHingeTorqueCreateFunc), + // ExampleEntry(0,"What's new in 2.83"), - ExampleEntry(1,"Constraints","Show the use of the various constraints in Bullet. Press the L key to visualize the constraint limits. Press the C key to visualize the constraint frames.", - AllConstraintCreateFunc), + ExampleEntry(1, "6DofSpring2", "Show the use of the btGeneric6DofSpring2Constraint. This is a replacement of the btGeneric6DofSpringConstraint, it has various improvements. This includes improved spring implementation and better control over the restitution (bounce) when the constraint hits its limits.", + Dof6Spring2CreateFunc), - ExampleEntry(1,"Motorized Hinge","Use of a btHingeConstraint. You can adjust the first slider to change the target velocity, and the second slider to adjust the maximum impulse applied to reach the target velocity. Note that the hinge angle can reach beyond -360 and 360 degrees.", ConstraintCreateFunc), - ExampleEntry(1,"TestHingeTorque", "Apply a torque in the hinge axis. This example uses a btHingeConstraint and btRigidBody. The setup is similar to the multi body example TestJointTorque.", - TestHingeTorqueCreateFunc), -// ExampleEntry(0,"What's new in 2.83"), + ExampleEntry(1, "Motor Demo", "Dynamic control the target velocity of a motor of a btHingeConstraint. This demo makes use of the 'internal tick callback'. You can press W for wireframe, C and L to visualize constraint frame and limits.", MotorControlCreateFunc), - ExampleEntry(1,"6DofSpring2","Show the use of the btGeneric6DofSpring2Constraint. This is a replacement of the btGeneric6DofSpringConstraint, it has various improvements. This includes improved spring implementation and better control over the restitution (bounce) when the constraint hits its limits.", - Dof6Spring2CreateFunc), + ExampleEntry(1, "Gyroscopic", "Show the Dzhanibekov effect using various settings of the gyroscopic term. You can select the gyroscopic term computation using btRigidBody::setFlags, with arguments BT_ENABLE_GYROSCOPIC_FORCE_EXPLICIT (using explicit integration, which adds energy and can lead to explosions), BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD, BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY. If you don't set any of these flags, there is no gyroscopic term used.", GyroscopicCreateFunc), - ExampleEntry(1,"Motor Demo", "Dynamic control the target velocity of a motor of a btHingeConstraint. This demo makes use of the 'internal tick callback'. You can press W for wireframe, C and L to visualize constraint frame and limits.", MotorControlCreateFunc), + ExampleEntry(1, "Soft Contact", "Using the error correction parameter (ERP) and constraint force mixing (CFM) values for contacts to simulate compliant contact.", RigidBodySoftContactCreateFunc), - ExampleEntry(1,"Gyroscopic", "Show the Dzhanibekov effect using various settings of the gyroscopic term. You can select the gyroscopic term computation using btRigidBody::setFlags, with arguments BT_ENABLE_GYROSCOPIC_FORCE_EXPLICIT (using explicit integration, which adds energy and can lead to explosions), BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD, BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY. If you don't set any of these flags, there is no gyroscopic term used.", GyroscopicCreateFunc), + ExampleEntry(0, "MultiBody"), + ExampleEntry(1, "MultiDof", "Create a basic btMultiBody with 3-DOF spherical joints (mobilizers). The demo uses a fixed base or a floating base at restart.", MultiDofCreateFunc), + ExampleEntry(1, "TestJointTorque", "Apply a torque to a btMultiBody with 1-DOF joints (mobilizers). This setup is similar to API/TestHingeTorque.", TestJointTorqueCreateFunc), + ExampleEntry(1, "TestPendulum", "Simulate a pendulum using btMultiBody with a constant joint torque applied. The same code is also used as a unit test comparing Bullet with the numerical solution of second-order non-linear differential equation stored in pendulum_gold.h", TestPendulumCreateFunc), - ExampleEntry(1,"Soft Contact", "Using the error correction parameter (ERP) and constraint force mixing (CFM) values for contacts to simulate compliant contact.",RigidBodySoftContactCreateFunc), + ExampleEntry(1, "Constraint Feedback", "The example shows how to receive joint reaction forces in a btMultiBody. Also the applied impulse is available for a btMultiBodyJointMotor", MultiBodyConstraintFeedbackCreateFunc), + ExampleEntry(1, "Inverted Pendulum PD", "Keep an inverted pendulum up using open loop PD control", InvertedPendulumPDControlCreateFunc), + ExampleEntry(1, "MultiBody Soft Contact", "Using the error correction parameter (ERP) and constraint force mixing (CFM) values for contacts to simulate compliant contact.", MultiBodySoftContactCreateFunc, 0), + ExampleEntry(1, "Serial Chains", "Show colliding two serial chains using different constraint solvers.", SerialChainsCreateFunc, 0), - ExampleEntry(0,"MultiBody"), - ExampleEntry(1,"MultiDof","Create a basic btMultiBody with 3-DOF spherical joints (mobilizers). The demo uses a fixed base or a floating base at restart.", MultiDofCreateFunc), - ExampleEntry(1,"TestJointTorque","Apply a torque to a btMultiBody with 1-DOF joints (mobilizers). This setup is similar to API/TestHingeTorque.", TestJointTorqueCreateFunc), - ExampleEntry(1,"TestPendulum","Simulate a pendulum using btMultiBody with a constant joint torque applied. The same code is also used as a unit test comparing Bullet with the numerical solution of second-order non-linear differential equation stored in pendulum_gold.h", TestPendulumCreateFunc), + ExampleEntry(0, "Physics Client-Server"), + ExampleEntry(1, "Physics Server", "Create a physics server that communicates with a physics client over shared memory. You can connect to the server using pybullet, a PhysicsClient or a UDP/TCP Bridge.", + PhysicsServerCreateFuncBullet2), + ExampleEntry(1, "Physics Client (Shared Mem)", "Create a physics client that can communicate with a physics server over shared memory.", PhysicsClientCreateFunc), - ExampleEntry(1,"Constraint Feedback", "The example shows how to receive joint reaction forces in a btMultiBody. Also the applied impulse is available for a btMultiBodyJointMotor", MultiBodyConstraintFeedbackCreateFunc), - ExampleEntry(1,"Inverted Pendulum PD","Keep an inverted pendulum up using open loop PD control", InvertedPendulumPDControlCreateFunc), - ExampleEntry(1,"MultiBody Soft Contact", "Using the error correction parameter (ERP) and constraint force mixing (CFM) values for contacts to simulate compliant contact.",MultiBodySoftContactCreateFunc,0), - ExampleEntry(1,"Serial Chains", "Show colliding two serial chains using different constraint solvers.", SerialChainsCreateFunc,0), + ExampleEntry(1, "Physics Server (Logging)", "Create a physics server that communicates with a physics client over shared memory. It will log all commands to a file.", + PhysicsServerCreateFuncBullet2, PHYSICS_SERVER_ENABLE_COMMAND_LOGGING), + ExampleEntry(1, "Physics Server (Replay Log)", "Create a physics server that replay a command log from disk.", + PhysicsServerCreateFuncBullet2, PHYSICS_SERVER_REPLAY_FROM_COMMAND_LOG), + // + // ExampleEntry(1, "Physics Client (Direct)", "Create a physics client that can communicate with a physics server directly in-process.", PhysicsClientCreateFunc,eCLIENTEXAMPLE_DIRECT), - ExampleEntry(0,"Physics Client-Server"), - ExampleEntry(1,"Physics Server", "Create a physics server that communicates with a physics client over shared memory. You can connect to the server using pybullet, a PhysicsClient or a UDP/TCP Bridge.", - PhysicsServerCreateFuncBullet2), - ExampleEntry(1, "Physics Client (Shared Mem)", "Create a physics client that can communicate with a physics server over shared memory.", PhysicsClientCreateFunc), + ExampleEntry(0, "Inverse Dynamics"), + ExampleEntry(1, "Inverse Dynamics URDF", "Create a btMultiBody from URDF. Create an inverse MultiBodyTree model from that. Use either decoupled PD control or computed torque control using the inverse model to track joint position targets", InverseDynamicsExampleCreateFunc, BT_ID_LOAD_URDF), + ExampleEntry(1, "Inverse Dynamics Prog", "Create a btMultiBody programatically. Create an inverse MultiBodyTree model from that. Use either decoupled PD control or computed torque control using the inverse model to track joint position targets", InverseDynamicsExampleCreateFunc, BT_ID_PROGRAMMATICALLY), - ExampleEntry(1,"Physics Server (Logging)", "Create a physics server that communicates with a physics client over shared memory. It will log all commands to a file.", - PhysicsServerCreateFuncBullet2,PHYSICS_SERVER_ENABLE_COMMAND_LOGGING), - ExampleEntry(1,"Physics Server (Replay Log)", "Create a physics server that replay a command log from disk.", - PhysicsServerCreateFuncBullet2,PHYSICS_SERVER_REPLAY_FROM_COMMAND_LOG), -// -// ExampleEntry(1, "Physics Client (Direct)", "Create a physics client that can communicate with a physics server directly in-process.", PhysicsClientCreateFunc,eCLIENTEXAMPLE_DIRECT), + ExampleEntry(0, "Inverse Kinematics"), + ExampleEntry(1, "SDLS", "Selectively Damped Least Squares by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_SDLS), + ExampleEntry(1, "DLS", "Damped Least Squares by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_DLS), + ExampleEntry(1, "DLS-SVD", "Damped Least Squares with Singular Value Decomposition by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_DLS_SVD), - ExampleEntry(0,"Inverse Dynamics"), - ExampleEntry(1,"Inverse Dynamics URDF", "Create a btMultiBody from URDF. Create an inverse MultiBodyTree model from that. Use either decoupled PD control or computed torque control using the inverse model to track joint position targets", InverseDynamicsExampleCreateFunc,BT_ID_LOAD_URDF), - ExampleEntry(1,"Inverse Dynamics Prog", "Create a btMultiBody programatically. Create an inverse MultiBodyTree model from that. Use either decoupled PD control or computed torque control using the inverse model to track joint position targets", InverseDynamicsExampleCreateFunc,BT_ID_PROGRAMMATICALLY), - - ExampleEntry(0, "Inverse Kinematics"), - ExampleEntry(1, "SDLS", "Selectively Damped Least Squares by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_SDLS), - ExampleEntry(1, "DLS", "Damped Least Squares by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_DLS), - ExampleEntry(1, "DLS-SVD", "Damped Least Squares with Singular Value Decomposition by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_DLS_SVD), - - - - ExampleEntry(1, "Jacobi Transpose", "Jacobi Transpose by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_JACOB_TRANS), - ExampleEntry(1, "Jacobi Pseudo Inv", "Jacobi Pseudo Inverse Method by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_PURE_PSEUDO), - - - ExampleEntry(0,"Tutorial"), - ExampleEntry(1,"Constant Velocity","Free moving rigid body, without external or constraint forces", TutorialCreateFunc,TUT_VELOCITY), - ExampleEntry(1,"Gravity Acceleration","Motion of a free falling rigid body under constant gravitational acceleration", TutorialCreateFunc,TUT_ACCELERATION), - ExampleEntry(1,"Contact Computation","Discrete Collision Detection for sphere-sphere", TutorialCreateFunc,TUT_COLLISION), - ExampleEntry(1,"Solve Contact Constraint","Compute and apply the impulses needed to satisfy non-penetrating contact constraints", TutorialCreateFunc,TUT_SOLVE_CONTACT_CONSTRAINT), - ExampleEntry(1,"Spring constraint","A rigid body with a spring constraint attached", Dof6ConstraintTutorialCreateFunc,0), - - ExampleEntry(0,"Collision"), - ExampleEntry(1, "Spheres & Plane C-API (Bullet2)", "Collision C-API using Bullet 2.x backend", CollisionTutorialBullet2CreateFunc,TUT_SPHERE_PLANE_BULLET2), - //ExampleEntry(1, "Spheres & Plane C-API (Bullet3)", "Collision C-API using Bullet 3.x backend", CollisionTutorialBullet2CreateFunc,TUT_SPHERE_PLANE_RTB3), + ExampleEntry(1, "Jacobi Transpose", "Jacobi Transpose by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_JACOB_TRANS), + ExampleEntry(1, "Jacobi Pseudo Inv", "Jacobi Pseudo Inverse Method by Sam Buss. Example configures the IK tree of a Kuka IIWA", InverseKinematicsExampleCreateFunc, IK_PURE_PSEUDO), + ExampleEntry(0, "Tutorial"), + ExampleEntry(1, "Constant Velocity", "Free moving rigid body, without external or constraint forces", TutorialCreateFunc, TUT_VELOCITY), + ExampleEntry(1, "Gravity Acceleration", "Motion of a free falling rigid body under constant gravitational acceleration", TutorialCreateFunc, TUT_ACCELERATION), + ExampleEntry(1, "Contact Computation", "Discrete Collision Detection for sphere-sphere", TutorialCreateFunc, TUT_COLLISION), + ExampleEntry(1, "Solve Contact Constraint", "Compute and apply the impulses needed to satisfy non-penetrating contact constraints", TutorialCreateFunc, TUT_SOLVE_CONTACT_CONSTRAINT), + ExampleEntry(1, "Spring constraint", "A rigid body with a spring constraint attached", Dof6ConstraintTutorialCreateFunc, 0), + ExampleEntry(0, "Collision"), + ExampleEntry(1, "Spheres & Plane C-API (Bullet2)", "Collision C-API using Bullet 2.x backend", CollisionTutorialBullet2CreateFunc, TUT_SPHERE_PLANE_BULLET2), +//ExampleEntry(1, "Spheres & Plane C-API (Bullet3)", "Collision C-API using Bullet 3.x backend", CollisionTutorialBullet2CreateFunc,TUT_SPHERE_PLANE_RTB3), #ifdef INCLUDE_CLOTH_DEMOS - ExampleEntry(0,"Soft Body"), - ExampleEntry(1,"Cloth","Simulate a patch of cloth.", SoftDemoCreateFunc,0), + ExampleEntry(0, "Soft Body"), + ExampleEntry(1, "Cloth", "Simulate a patch of cloth.", SoftDemoCreateFunc, 0), - ExampleEntry(1,"Pressure","Simulate 3d soft body using a pressure constraint.",SoftDemoCreateFunc,1), - ExampleEntry(1,"Volume","Simulate 3d soft body using a volume constraint.",SoftDemoCreateFunc,2), - ExampleEntry(1,"Ropes","Simulate ropes", SoftDemoCreateFunc,3), - ExampleEntry(1,"Rope Attach","Simulate a rigid body connected to a rope.", SoftDemoCreateFunc,4), - ExampleEntry(1,"Cloth Attach","A rigid body attached to a cloth.", SoftDemoCreateFunc,5), - ExampleEntry(1,"Sticks","Show simulation of ropes fixed to the ground.", SoftDemoCreateFunc,6), - ExampleEntry(1,"Capsule Collision","Collision detection between a capsule shape and cloth.", SoftDemoCreateFunc,7), + ExampleEntry(1, "Pressure", "Simulate 3d soft body using a pressure constraint.", SoftDemoCreateFunc, 1), + ExampleEntry(1, "Volume", "Simulate 3d soft body using a volume constraint.", SoftDemoCreateFunc, 2), + ExampleEntry(1, "Ropes", "Simulate ropes", SoftDemoCreateFunc, 3), + ExampleEntry(1, "Rope Attach", "Simulate a rigid body connected to a rope.", SoftDemoCreateFunc, 4), + ExampleEntry(1, "Cloth Attach", "A rigid body attached to a cloth.", SoftDemoCreateFunc, 5), + ExampleEntry(1, "Sticks", "Show simulation of ropes fixed to the ground.", SoftDemoCreateFunc, 6), + ExampleEntry(1, "Capsule Collision", "Collision detection between a capsule shape and cloth.", SoftDemoCreateFunc, 7), - ExampleEntry(1,"Collide","Soft body collision", SoftDemoCreateFunc,8), - ExampleEntry(1,"Collide 2","Soft body collision",SoftDemoCreateFunc,9), - ExampleEntry(1,"Collide 3","Soft body collision",SoftDemoCreateFunc,10), - ExampleEntry(1,"Impact","Soft body impact",SoftDemoCreateFunc,11), - ExampleEntry(1,"Aero","Rudimentary aero dynamics simulation", SoftDemoCreateFunc,12), - ExampleEntry(1,"Aero 2","Rudimentary aero dynamics simulation",SoftDemoCreateFunc,13), - ExampleEntry(1,"Friction","Simulate soft body friction with friction coefficients ranging from 0 to 1.", SoftDemoCreateFunc,14), - ExampleEntry(1,"Torus","Simulate a soft body torus.",SoftDemoCreateFunc,15), - ExampleEntry(1,"Torus (Shape Match)","Simulate a soft body torus using shape matching.", SoftDemoCreateFunc,16), - ExampleEntry(1,"Bunny","Simulate the Stanford bunny as deformable object.", SoftDemoCreateFunc,17), - ExampleEntry(1,"Bunny (Shape Match)","Simulate the Stanford bunny as deformable object including shape matching.", SoftDemoCreateFunc,18), - ExampleEntry(1,"Cutting","Allow cutting of the soft body, by clicking on the cloth", SoftDemoCreateFunc,19), - ExampleEntry(1,"Cluster Deform","Soft body collision detection using convex collision clusters.", SoftDemoCreateFunc,20), - ExampleEntry(1,"Cluster Collide1","Collision detection between soft bodies using convex collision clusters.", SoftDemoCreateFunc,21), - ExampleEntry(1,"Cluster Collide2","Collision detection between soft bodies using convex collision clusters.",SoftDemoCreateFunc,22), - ExampleEntry(1,"Cluster Socket","Soft bodies connected by a point to point (ball-socket) constraints. This requires collision clusters, in order to define a frame of reference for the constraint." - , SoftDemoCreateFunc,23), - ExampleEntry(1,"Cluster Hinge","Soft bodies connected by a hinge constraints. This requires collision clusters, in order to define a frame of reference for the constraint.", SoftDemoCreateFunc,24), - ExampleEntry(1,"Cluster Combine","Simulate soft bodies using collision clusters.", SoftDemoCreateFunc,25), - ExampleEntry(1,"Cluster Car","Simulate the Stanford bunny by multiple soft bodies connected by constraints.", SoftDemoCreateFunc,26), - ExampleEntry(1,"Cluster Robot","A rigid body base connected by soft body wheels, connected by constraints.", SoftDemoCreateFunc,27), - ExampleEntry(1,"Cluster Stack Soft","Stacking of soft bodies.", SoftDemoCreateFunc,28), - ExampleEntry(1,"Cluster Stack Mixed","Stacking of soft bodies and rigid bodies.",SoftDemoCreateFunc,29), - ExampleEntry(1,"Tetra Cube","Simulate a volumetric soft body cube defined by tetrahedra.", SoftDemoCreateFunc,30), - ExampleEntry(1,"Tetra Bunny","Simulate a volumetric soft body Stanford bunny defined by tetrahedra.", SoftDemoCreateFunc,31), + ExampleEntry(1, "Collide", "Soft body collision", SoftDemoCreateFunc, 8), + ExampleEntry(1, "Collide 2", "Soft body collision", SoftDemoCreateFunc, 9), + ExampleEntry(1, "Collide 3", "Soft body collision", SoftDemoCreateFunc, 10), + ExampleEntry(1, "Impact", "Soft body impact", SoftDemoCreateFunc, 11), + ExampleEntry(1, "Aero", "Rudimentary aero dynamics simulation", SoftDemoCreateFunc, 12), + ExampleEntry(1, "Aero 2", "Rudimentary aero dynamics simulation", SoftDemoCreateFunc, 13), + ExampleEntry(1, "Friction", "Simulate soft body friction with friction coefficients ranging from 0 to 1.", SoftDemoCreateFunc, 14), + ExampleEntry(1, "Torus", "Simulate a soft body torus.", SoftDemoCreateFunc, 15), + ExampleEntry(1, "Torus (Shape Match)", "Simulate a soft body torus using shape matching.", SoftDemoCreateFunc, 16), + ExampleEntry(1, "Bunny", "Simulate the Stanford bunny as deformable object.", SoftDemoCreateFunc, 17), + ExampleEntry(1, "Bunny (Shape Match)", "Simulate the Stanford bunny as deformable object including shape matching.", SoftDemoCreateFunc, 18), + ExampleEntry(1, "Cutting", "Allow cutting of the soft body, by clicking on the cloth", SoftDemoCreateFunc, 19), + ExampleEntry(1, "Cluster Deform", "Soft body collision detection using convex collision clusters.", SoftDemoCreateFunc, 20), + ExampleEntry(1, "Cluster Collide1", "Collision detection between soft bodies using convex collision clusters.", SoftDemoCreateFunc, 21), + ExampleEntry(1, "Cluster Collide2", "Collision detection between soft bodies using convex collision clusters.", SoftDemoCreateFunc, 22), + ExampleEntry(1, "Cluster Socket", "Soft bodies connected by a point to point (ball-socket) constraints. This requires collision clusters, in order to define a frame of reference for the constraint.", SoftDemoCreateFunc, 23), + ExampleEntry(1, "Cluster Hinge", "Soft bodies connected by a hinge constraints. This requires collision clusters, in order to define a frame of reference for the constraint.", SoftDemoCreateFunc, 24), + ExampleEntry(1, "Cluster Combine", "Simulate soft bodies using collision clusters.", SoftDemoCreateFunc, 25), + ExampleEntry(1, "Cluster Car", "Simulate the Stanford bunny by multiple soft bodies connected by constraints.", SoftDemoCreateFunc, 26), + ExampleEntry(1, "Cluster Robot", "A rigid body base connected by soft body wheels, connected by constraints.", SoftDemoCreateFunc, 27), + ExampleEntry(1, "Cluster Stack Soft", "Stacking of soft bodies.", SoftDemoCreateFunc, 28), + ExampleEntry(1, "Cluster Stack Mixed", "Stacking of soft bodies and rigid bodies.", SoftDemoCreateFunc, 29), + ExampleEntry(1, "Tetra Cube", "Simulate a volumetric soft body cube defined by tetrahedra.", SoftDemoCreateFunc, 30), + ExampleEntry(1, "Tetra Bunny", "Simulate a volumetric soft body Stanford bunny defined by tetrahedra.", SoftDemoCreateFunc, 31), -#endif //INCLUDE_CLOTH_DEMOS +#endif //INCLUDE_CLOTH_DEMOS - ///we disable the benchmarks in debug mode, they are way too slow and benchmarking in debug mode is not recommended -//#ifndef _DEBUG - ExampleEntry(0,"Benchmarks"), - ExampleEntry(1,"3000 boxes", "Benchmark a stack of 3000 boxes. It will stress the collision detection, a specialized box-box implementation based on the separating axis test, and the constraint solver. ", BenchmarkCreateFunc, 1), - ExampleEntry(1,"1000 stack", "Benchmark a stack of 3000 boxes. It will stress the collision detection, a specialized box-box implementation based on the separating axis test, and the constraint solver. ", - BenchmarkCreateFunc, 2), - ExampleEntry(1,"Ragdolls", "Benchmark the performance of the ragdoll constraints, btHingeConstraint and btConeTwistConstraint, in addition to capsule collision detection.", BenchmarkCreateFunc, 3), - ExampleEntry(1,"Convex stack", "Benchmark the performance and stability of rigid bodies using btConvexHullShape.", BenchmarkCreateFunc, 4), - ExampleEntry(1,"Prim vs Mesh", "Benchmark the performance and stability of rigid bodies using primitive collision shapes (btSphereShape, btBoxShape), resting on a triangle mesh, btBvhTriangleMeshShape.", BenchmarkCreateFunc, 5), - ExampleEntry(1,"Convex vs Mesh", "Benchmark the performance and stability of rigid bodies using convex hull collision shapes (btConvexHullShape), resting on a triangle mesh, btBvhTriangleMeshShape.", BenchmarkCreateFunc, 6), - ExampleEntry(1,"Raycast", "Benchmark the performance of the btCollisionWorld::rayTest. Note that currently the rays are not rendered.", BenchmarkCreateFunc, 7), -//#endif + ///we disable the benchmarks in debug mode, they are way too slow and benchmarking in debug mode is not recommended + //#ifndef _DEBUG + ExampleEntry(0, "Benchmarks"), + ExampleEntry(1, "3000 boxes", "Benchmark a stack of 3000 boxes. It will stress the collision detection, a specialized box-box implementation based on the separating axis test, and the constraint solver. ", BenchmarkCreateFunc, 1), + ExampleEntry(1, "1000 stack", "Benchmark a stack of 3000 boxes. It will stress the collision detection, a specialized box-box implementation based on the separating axis test, and the constraint solver. ", + BenchmarkCreateFunc, 2), + ExampleEntry(1, "Ragdolls", "Benchmark the performance of the ragdoll constraints, btHingeConstraint and btConeTwistConstraint, in addition to capsule collision detection.", BenchmarkCreateFunc, 3), + ExampleEntry(1, "Convex stack", "Benchmark the performance and stability of rigid bodies using btConvexHullShape.", BenchmarkCreateFunc, 4), + ExampleEntry(1, "Prim vs Mesh", "Benchmark the performance and stability of rigid bodies using primitive collision shapes (btSphereShape, btBoxShape), resting on a triangle mesh, btBvhTriangleMeshShape.", BenchmarkCreateFunc, 5), + ExampleEntry(1, "Convex vs Mesh", "Benchmark the performance and stability of rigid bodies using convex hull collision shapes (btConvexHullShape), resting on a triangle mesh, btBvhTriangleMeshShape.", BenchmarkCreateFunc, 6), + ExampleEntry(1, "Raycast", "Benchmark the performance of the btCollisionWorld::rayTest. Note that currently the rays are not rendered.", BenchmarkCreateFunc, 7), + //#endif + ExampleEntry(0, "Importers"), + ExampleEntry(1, "Import .bullet", "Load a binary .bullet file. The serialization mechanism can deal with versioning, differences in endianess, 32 and 64bit, double/single precision. It is easy to save a .bullet file, see the examples/Importers/ImportBullet/SerializeDemo.cpp for a code example how to export a .bullet file.", SerializeBulletCreateFunc), + ExampleEntry(1, "Wavefront Obj", "Import a Wavefront .obj file", ImportObjCreateFunc, 0), + ExampleEntry(1, "Obj2RigidBody (Show Obj)", "Load a triangle mesh from Wavefront .obj and turn it in a convex hull collision shape, connected to a rigid body. We can use the original .obj mesh data to visualize the rigid body. In 'debug' wireframe mode (press 'w' to toggle) we still see the convex hull data.", ET_RigidBodyFromObjCreateFunc), + ExampleEntry(1, "Obj2RigidBody (Show Hull)", "Load a triangle mesh from Wavefront .obj and turn it in a convex hull collision shape, connected to a rigid body", ET_RigidBodyFromObjCreateFunc, ObjUseConvexHullForRendering), + ExampleEntry(1, "Obj2RigidBody Optimize", "Load a triangle mesh from Wavefront .obj, remove the vertices that are not on the convex hull", ET_RigidBodyFromObjCreateFunc, OptimizeConvexObj), + ExampleEntry(1, "Quake BSP", "Import a Quake .bsp file", ImportBspCreateFunc, 0), + ExampleEntry(1, "COLLADA dae", "Import the geometric mesh data from a COLLADA file. This is used as part of the URDF importer. This loader can also be used to import collision geometry in general. ", + ImportColladaCreateFunc, 0), + ExampleEntry(1, "STL", "Import the geometric mesh data from a STL file. This is used as part of the URDF importer. This loader can also be used to import collision geometry in general. ", ImportSTLCreateFunc, 0), + ExampleEntry(1, "URDF (RigidBody)", "Import a URDF file, and create rigid bodies (btRigidBody) connected by constraints.", ImportURDFCreateFunc, 0), + ExampleEntry(1, "URDF (MultiBody)", "Import a URDF file and create a single multibody (btMultiBody) with tree hierarchy of links (mobilizers).", + ImportURDFCreateFunc, 1), + ExampleEntry(1, "MJCF (MultiBody)", "Import a MJCF xml file, create multiple multibodies etc", ImportMJCFCreateFunc), + ExampleEntry(1, "SDF (MultiBody)", "Import an SDF file, create multiple multibodies etc", ImportSDFCreateFunc), - ExampleEntry(0,"Importers"), - ExampleEntry(1,"Import .bullet", "Load a binary .bullet file. The serialization mechanism can deal with versioning, differences in endianess, 32 and 64bit, double/single precision. It is easy to save a .bullet file, see the examples/Importers/ImportBullet/SerializeDemo.cpp for a code example how to export a .bullet file.", SerializeBulletCreateFunc), - ExampleEntry(1,"Wavefront Obj", "Import a Wavefront .obj file", ImportObjCreateFunc, 0), - ExampleEntry(1,"Obj2RigidBody (Show Obj)", "Load a triangle mesh from Wavefront .obj and turn it in a convex hull collision shape, connected to a rigid body. We can use the original .obj mesh data to visualize the rigid body. In 'debug' wireframe mode (press 'w' to toggle) we still see the convex hull data.", ET_RigidBodyFromObjCreateFunc), - ExampleEntry(1,"Obj2RigidBody (Show Hull)", "Load a triangle mesh from Wavefront .obj and turn it in a convex hull collision shape, connected to a rigid body", ET_RigidBodyFromObjCreateFunc,ObjUseConvexHullForRendering), - ExampleEntry(1,"Obj2RigidBody Optimize", "Load a triangle mesh from Wavefront .obj, remove the vertices that are not on the convex hull", ET_RigidBodyFromObjCreateFunc,OptimizeConvexObj), + ExampleEntry(0, "Vehicles"), + ExampleEntry(1, "Hinge2 Vehicle", "A rigid body chassis with 4 rigid body wheels attached by a btHinge2Constraint", Hinge2VehicleCreateFunc), + ExampleEntry(1, "ForkLift", + "Simulate a fork lift vehicle with a working fork lift that can be moved using the cursor keys. The wheels collision is simplified using ray tests." + "There are currently some issues with the wheel rendering, the wheels rotate when picking up the object." + "The demo implementation allows to choose various MLCP constraint solvers.", + ForkLiftCreateFunc), - ExampleEntry(1,"Quake BSP", "Import a Quake .bsp file", ImportBspCreateFunc, 0), - ExampleEntry(1,"COLLADA dae", "Import the geometric mesh data from a COLLADA file. This is used as part of the URDF importer. This loader can also be used to import collision geometry in general. ", - ImportColladaCreateFunc, 0), - ExampleEntry(1,"STL", "Import the geometric mesh data from a STL file. This is used as part of the URDF importer. This loader can also be used to import collision geometry in general. ",ImportSTLCreateFunc, 0), - ExampleEntry(1,"URDF (RigidBody)", "Import a URDF file, and create rigid bodies (btRigidBody) connected by constraints.", ImportURDFCreateFunc, 0), - ExampleEntry(1,"URDF (MultiBody)", "Import a URDF file and create a single multibody (btMultiBody) with tree hierarchy of links (mobilizers).", - ImportURDFCreateFunc, 1), - ExampleEntry(1,"MJCF (MultiBody)", "Import a MJCF xml file, create multiple multibodies etc", ImportMJCFCreateFunc), + ExampleEntry(0, "Raycast"), + ExampleEntry(1, "Raytest", "Cast rays using the btCollisionWorld::rayTest method. The example shows how to receive the hit position and normal along the ray against the first object. Also it shows how to receive all the hits along a ray.", RaytestCreateFunc), + ExampleEntry(1, "Raytracer", "Implement an extremely simple ray tracer using the ray trace functionality in btCollisionWorld.", + RayTracerCreateFunc), - ExampleEntry(1,"SDF (MultiBody)", "Import an SDF file, create multiple multibodies etc", ImportSDFCreateFunc), + ExampleEntry(0, "Experiments"), - ExampleEntry(0,"Vehicles"), - ExampleEntry(1,"Hinge2 Vehicle", "A rigid body chassis with 4 rigid body wheels attached by a btHinge2Constraint",Hinge2VehicleCreateFunc), - ExampleEntry(1,"ForkLift","Simulate a fork lift vehicle with a working fork lift that can be moved using the cursor keys. The wheels collision is simplified using ray tests." - "There are currently some issues with the wheel rendering, the wheels rotate when picking up the object." - "The demo implementation allows to choose various MLCP constraint solvers.", - ForkLiftCreateFunc), + ExampleEntry(1, "Robot Control", "Create a physics client and server to create and control robots.", + PhysicsClientCreateFunc, eCLIENTEXAMPLE_SERVER), - ExampleEntry(0,"Raycast"), - ExampleEntry(1,"Raytest", "Cast rays using the btCollisionWorld::rayTest method. The example shows how to receive the hit position and normal along the ray against the first object. Also it shows how to receive all the hits along a ray.", RaytestCreateFunc), - ExampleEntry(1,"Raytracer","Implement an extremely simple ray tracer using the ray trace functionality in btCollisionWorld.", - RayTracerCreateFunc), - - - - ExampleEntry(0,"Experiments"), - - - ExampleEntry(1,"Robot Control", "Create a physics client and server to create and control robots.", - PhysicsClientCreateFunc, eCLIENTEXAMPLE_SERVER), - - ExampleEntry(1,"R2D2 Grasp","Load the R2D2 robot from URDF file and control it to grasp objects", R2D2GraspExampleCreateFunc, eROBOTIC_LEARN_GRASP), - ExampleEntry(1,"Kuka IK","Control a Kuka IIWA robot to follow a target using IK. This IK is not setup properly yet.", KukaGraspExampleCreateFunc,0), - ExampleEntry(1,"URDF Compliant Contact","Work-in-progress, experiment/improve compliant rigid contact using parameters from URDF file (contact_cfm, contact_erp, lateral_friction, rolling_friction)", R2D2GraspExampleCreateFunc,eROBOTIC_LEARN_COMPLIANT_CONTACT), - ExampleEntry(1,"Rolling friction","Experiment on multibody rolling friction", R2D2GraspExampleCreateFunc,eROBOTIC_LEARN_ROLLING_FRICTION), - ExampleEntry(1,"Gripper Grasp","Grasp experiment with a gripper to improve contact model", GripperGraspExampleCreateFunc,eGRIPPER_GRASP), - ExampleEntry(1,"Two Point Grasp","Grasp experiment with two point contact to test rolling friction", GripperGraspExampleCreateFunc, eTWO_POINT_GRASP), - ExampleEntry(1,"One Motor Gripper Grasp","Grasp experiment with a gripper with one motor to test slider constraint for closed loop structure", GripperGraspExampleCreateFunc, eONE_MOTOR_GRASP), -#ifndef SKIP_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD - ExampleEntry(1,"Grasp Soft Body","Grasp soft body experiment", GripperGraspExampleCreateFunc, eGRASP_SOFT_BODY), - ExampleEntry(1,"Softbody Multibody Coupling","Two way coupling between soft body and multibody experiment", GripperGraspExampleCreateFunc, eSOFTBODY_MULTIBODY_COUPLING), -#endif //SKIP_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD + ExampleEntry(1, "R2D2 Grasp", "Load the R2D2 robot from URDF file and control it to grasp objects", R2D2GraspExampleCreateFunc, eROBOTIC_LEARN_GRASP), + ExampleEntry(1, "Kuka IK", "Control a Kuka IIWA robot to follow a target using IK. This IK is not setup properly yet.", KukaGraspExampleCreateFunc, 0), + ExampleEntry(1, "URDF Compliant Contact", "Work-in-progress, experiment/improve compliant rigid contact using parameters from URDF file (contact_cfm, contact_erp, lateral_friction, rolling_friction)", R2D2GraspExampleCreateFunc, eROBOTIC_LEARN_COMPLIANT_CONTACT), + ExampleEntry(1, "Rolling friction", "Experiment on multibody rolling friction", R2D2GraspExampleCreateFunc, eROBOTIC_LEARN_ROLLING_FRICTION), + ExampleEntry(1, "Gripper Grasp", "Grasp experiment with a gripper to improve contact model", GripperGraspExampleCreateFunc, eGRIPPER_GRASP), + ExampleEntry(1, "Two Point Grasp", "Grasp experiment with two point contact to test rolling friction", GripperGraspExampleCreateFunc, eTWO_POINT_GRASP), + ExampleEntry(1, "One Motor Gripper Grasp", "Grasp experiment with a gripper with one motor to test slider constraint for closed loop structure", GripperGraspExampleCreateFunc, eONE_MOTOR_GRASP), +#ifndef SKIP_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD + ExampleEntry(1, "Grasp Soft Body", "Grasp soft body experiment", GripperGraspExampleCreateFunc, eGRASP_SOFT_BODY), + ExampleEntry(1, "Softbody Multibody Coupling", "Two way coupling between soft body and multibody experiment", GripperGraspExampleCreateFunc, eSOFTBODY_MULTIBODY_COUPLING), +#endif //SKIP_SOFT_BODY_MULTI_BODY_DYNAMICS_WORLD #ifdef ENABLE_LUA - ExampleEntry(1,"Lua Script", "Create the dynamics world, collision shapes and rigid bodies using Lua scripting", - LuaDemoCreateFunc), + ExampleEntry(1, "Lua Script", "Create the dynamics world, collision shapes and rigid bodies using Lua scripting", + LuaDemoCreateFunc), #endif - ExampleEntry(1,"MultiThreading (submitJob)", "Simple example of executing jobs across multiple threads.", - MultiThreadingExampleCreateFunc,SINGLE_SIM_THREAD), + ExampleEntry(1, "MultiThreading (submitJob)", "Simple example of executing jobs across multiple threads.", + MultiThreadingExampleCreateFunc, SINGLE_SIM_THREAD), - ExampleEntry(1,"Voronoi Fracture", "Automatically create a compound rigid body using voronoi tesselation. Individual parts are modeled as rigid bodies using a btConvexHullShape.", - VoronoiFractureCreateFunc), + ExampleEntry(1, "Voronoi Fracture", "Automatically create a compound rigid body using voronoi tesselation. Individual parts are modeled as rigid bodies using a btConvexHullShape.", + VoronoiFractureCreateFunc), - ExampleEntry(1,"Fracture demo", "Create a basic custom implementation to model fracturing objects, based on a btCompoundShape. It explicitly propagates the collision impulses and breaks the rigid body into multiple rigid bodies. Press F to toggle fracture and glue mode.", FractureDemoCreateFunc), + ExampleEntry(1, "Fracture demo", "Create a basic custom implementation to model fracturing objects, based on a btCompoundShape. It explicitly propagates the collision impulses and breaks the rigid body into multiple rigid bodies. Press F to toggle fracture and glue mode.", FractureDemoCreateFunc), - ExampleEntry(1,"Planar 2D","Show the use of 2D collision shapes and rigid body simulation. The collision shape is wrapped into a btConvex2dShape. The rigid bodies are restricted in a plane using the 'setAngularFactor' and 'setLinearFactor' API call.",Planar2DCreateFunc), + ExampleEntry(1, "Planar 2D", "Show the use of 2D collision shapes and rigid body simulation. The collision shape is wrapped into a btConvex2dShape. The rigid bodies are restricted in a plane using the 'setAngularFactor' and 'setLinearFactor' API call.", Planar2DCreateFunc), #if BT_THREADSAFE - // only enable MultiThreaded demo if a task scheduler is available - ExampleEntry( 1, "Multithreaded Demo", - "Stacks of boxes that do not sleep. Good for testing performance with large numbers of bodies and contacts. Sliders can be used to change the number of stacks (restart needed after each change)." - , - MultiThreadedDemoCreateFunc ), + // only enable MultiThreaded demo if a task scheduler is available + ExampleEntry(1, "Multithreaded Demo", + "Stacks of boxes that do not sleep. Good for testing performance with large numbers of bodies and contacts. Sliders can be used to change the number of stacks (restart needed after each change).", + MultiThreadedDemoCreateFunc), #endif - - ExampleEntry(0,"Rendering"), - ExampleEntry(1,"Instanced Rendering", "Simple example of fast instanced rendering, only active when using OpenGL3+.",RenderInstancingCreateFunc), - ExampleEntry(1,"CoordinateSystemDemo","Show the axis and positive rotation direction around the axis.", CoordinateSystemCreateFunc), - ExampleEntry(1,"Time Series", "Render some value(s) in a 2D graph window, shifting to the left", TimeSeriesCreateFunc), - ExampleEntry(1,"TinyRenderer", "Very small software renderer.", TinyRendererCreateFunc), - ExampleEntry(1,"Dynamic Texture", "Dynamic updated textured applied to a cube.", DynamicTexturedCubeDemoCreateFunc), + ExampleEntry(0, "Rendering"), + ExampleEntry(1, "Instanced Rendering", "Simple example of fast instanced rendering, only active when using OpenGL3+.", RenderInstancingCreateFunc), + ExampleEntry(1, "CoordinateSystemDemo", "Show the axis and positive rotation direction around the axis.", CoordinateSystemCreateFunc), + ExampleEntry(1, "Time Series", "Render some value(s) in a 2D graph window, shifting to the left", TimeSeriesCreateFunc), + ExampleEntry(1, "TinyRenderer", "Very small software renderer.", TinyRendererCreateFunc), + ExampleEntry(1, "Dynamic Texture", "Dynamic updated textured applied to a cube.", DynamicTexturedCubeDemoCreateFunc), #ifdef B3_ENABLE_TINY_AUDIO - ExampleEntry(0,"Audio"), - ExampleEntry(1,"Simple Audio","Play some sound", TinyAudioExampleCreateFunc), + ExampleEntry(0, "Audio"), + ExampleEntry(1, "Simple Audio", "Play some sound", TinyAudioExampleCreateFunc), #endif + //Extended Tutorials Added by Mobeen + ExampleEntry(0, "Extended Tutorials"), + ExampleEntry(1, "Simple Box", "Simplest possible demo creating a single box rigid body that falls under gravity", ET_SimpleBoxCreateFunc), + ExampleEntry(1, "Multiple Boxes", "Add multiple box rigid bodies that fall under gravity", ET_MultipleBoxesCreateFunc), + ExampleEntry(1, "Compound Boxes", "Add multiple boxes to a single CompoundShape to form a simple rigid L-beam, that falls under gravity", ET_CompoundBoxesCreateFunc), + ExampleEntry(1, "Simple Joint", "Create a single distance constraint between two box rigid bodies", ET_SimpleJointCreateFunc), + ExampleEntry(1, "Simple Cloth", "Create a simple piece of cloth", ET_SimpleClothCreateFunc), + ExampleEntry(1, "Simple Chain", "Create a simple chain using a pair of point2point/distance constraints. You may click and drag any box to see the chain respond.", ET_ChainCreateFunc), + ExampleEntry(1, "Simple Bridge", "Create a simple bridge using a pair of point2point/distance constraints. You may click and drag any plank to see the bridge respond.", ET_BridgeCreateFunc), + ExampleEntry(1, "Inclined Plane", "Create an inclined plane to show restitution and different types of friction. Use the sliders to vary restitution and friction and press space to reset the scene.", ET_InclinedPlaneCreateFunc), + ExampleEntry(1, "Newton's Cradle", "Create a Newton's Cradle using a pair of point2point/slider constraints. Press 1/2 to lengthen/shorten the pendula, press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula, the number of displaced pendula and apply the displacement force.", ET_NewtonsCradleCreateFunc), + ExampleEntry(1, "Newton's Rope Cradle", "Create a Newton's Cradle using ropes. Press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula and the number of displaced pendula and apply the displacement force.", ET_NewtonsRopeCradleCreateFunc), + ExampleEntry(1, "Multi-Pendulum", "Create a Multi-Pendulum using point2point/slider constraints. Press 1/2 to lengthen/shorten the pendula, press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula, the number of displaced pendula and apply the displacement force.", ET_MultiPendulumCreateFunc), - //Extended Tutorials Added by Mobeen - ExampleEntry(0,"Extended Tutorials"), - ExampleEntry(1,"Simple Box", "Simplest possible demo creating a single box rigid body that falls under gravity", ET_SimpleBoxCreateFunc), - ExampleEntry(1,"Multiple Boxes", "Add multiple box rigid bodies that fall under gravity", ET_MultipleBoxesCreateFunc), - ExampleEntry(1,"Compound Boxes", "Add multiple boxes to a single CompoundShape to form a simple rigid L-beam, that falls under gravity", ET_CompoundBoxesCreateFunc), - ExampleEntry(1,"Simple Joint", "Create a single distance constraint between two box rigid bodies", ET_SimpleJointCreateFunc), - ExampleEntry(1,"Simple Cloth", "Create a simple piece of cloth", ET_SimpleClothCreateFunc), - ExampleEntry(1,"Simple Chain", "Create a simple chain using a pair of point2point/distance constraints. You may click and drag any box to see the chain respond.", ET_ChainCreateFunc), - ExampleEntry(1,"Simple Bridge", "Create a simple bridge using a pair of point2point/distance constraints. You may click and drag any plank to see the bridge respond.", ET_BridgeCreateFunc), - ExampleEntry(1,"Inclined Plane", "Create an inclined plane to show restitution and different types of friction. Use the sliders to vary restitution and friction and press space to reset the scene.", ET_InclinedPlaneCreateFunc), - ExampleEntry(1,"Newton's Cradle", "Create a Newton's Cradle using a pair of point2point/slider constraints. Press 1/2 to lengthen/shorten the pendula, press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula, the number of displaced pendula and apply the displacement force.", ET_NewtonsCradleCreateFunc), - ExampleEntry(1,"Newton's Rope Cradle", "Create a Newton's Cradle using ropes. Press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula and the number of displaced pendula and apply the displacement force.",ET_NewtonsRopeCradleCreateFunc), - ExampleEntry(1,"Multi-Pendulum", "Create a Multi-Pendulum using point2point/slider constraints. Press 1/2 to lengthen/shorten the pendula, press 3 to displace pendula. Use the sliders to select the number (reset simulation), length and restitution of pendula, the number of displaced pendula and apply the displacement force.",ET_MultiPendulumCreateFunc), - - ExampleEntry(9,"Evolution"), - ExampleEntry(1,"Neural Network 3D Walkers","A simple example of using evolution to make a creature walk.",ET_NN3DWalkersCreateFunc), - - //todo: create a category/tutorial about advanced topics, such as optimizations, using different collision detection algorithm, different constraint solvers etc. - //ExampleEntry(0,"Advanced"), - //ExampleEntry(1,"Obj2RigidBody Add Features", "Load a triangle mesh from Wavefront .obj and create polyhedral features to perform the separating axis test (instead of GJK/MPR). It is best to combine optimization and polyhedral feature generation.", ET_RigidBodyFromObjCreateFunc,OptimizeConvexObj+ComputePolyhedralFeatures), + ExampleEntry(9, "Evolution"), + ExampleEntry(1, "Neural Network 3D Walkers", "A simple example of using evolution to make a creature walk.", ET_NN3DWalkersCreateFunc), + //todo: create a category/tutorial about advanced topics, such as optimizations, using different collision detection algorithm, different constraint solvers etc. + //ExampleEntry(0,"Advanced"), + //ExampleEntry(1,"Obj2RigidBody Add Features", "Load a triangle mesh from Wavefront .obj and create polyhedral features to perform the separating axis test (instead of GJK/MPR). It is best to combine optimization and polyhedral feature generation.", ET_RigidBodyFromObjCreateFunc,OptimizeConvexObj+ComputePolyhedralFeatures), }; #ifdef B3_USE_CLEW #ifndef NO_OPENGL3 -static ExampleEntry gOpenCLExamples[]= -{ - ExampleEntry(0,"OpenCL (experimental)"), - ExampleEntry(1,"Box-Box", "Full OpenCL implementation of the entire physics and collision detection pipeline, showing box-box rigid body", - OpenCLBoxBoxCreateFunc), - ExampleEntry(1,"Pair Bench", "Benchmark of overlapping pair search using OpenCL.", PairBenchOpenCLCreateFunc), +static ExampleEntry gOpenCLExamples[] = + { + ExampleEntry(0, "OpenCL (experimental)"), + ExampleEntry(1, "Box-Box", "Full OpenCL implementation of the entire physics and collision detection pipeline, showing box-box rigid body", + OpenCLBoxBoxCreateFunc), + ExampleEntry(1, "Pair Bench", "Benchmark of overlapping pair search using OpenCL.", PairBenchOpenCLCreateFunc), }; #endif -#endif // +#endif // static btAlignedObjectArray gAdditionalRegisteredExamples; - struct ExampleEntriesInternalData { btAlignedObjectArray m_allExamples; @@ -379,51 +361,47 @@ void ExampleEntriesAll::initOpenCLExampleEntries() { #ifdef B3_USE_CLEW #ifndef NO_OPENGL3 - int numDefaultEntries = sizeof(gOpenCLExamples)/sizeof(ExampleEntry); - for (int i=0;im_allExamples.push_back(gOpenCLExamples[i]); } #endif -#endif //B3_USE_CLEW +#endif //B3_USE_CLEW } void ExampleEntriesAll::initExampleEntries() { m_data->m_allExamples.clear(); - for (int i=0;im_allExamples.push_back(gAdditionalRegisteredExamples[i]); } - - - int numDefaultEntries = sizeof(gDefaultExamples)/sizeof(ExampleEntry); - for (int i=0;im_allExamples.push_back(gDefaultExamples[i]); } - if (m_data->m_allExamples.size()==0) + if (m_data->m_allExamples.size() == 0) { - { - ExampleEntry e(0,"Empty"); + ExampleEntry e(0, "Empty"); m_data->m_allExamples.push_back(e); } { - ExampleEntry e(1,"Empty","Empty Description", EmptyExample::CreateFunc); + ExampleEntry e(1, "Empty", "Empty Description", EmptyExample::CreateFunc); m_data->m_allExamples.push_back(e); } } - } -void ExampleEntriesAll::registerExampleEntry(int menuLevel, const char* name,const char* description, CommonExampleInterface::CreateFunc* createFunc, int option) +void ExampleEntriesAll::registerExampleEntry(int menuLevel, const char* name, const char* description, CommonExampleInterface::CreateFunc* createFunc, int option) { - ExampleEntry e( menuLevel,name,description, createFunc, option); + ExampleEntry e(menuLevel, name, description, createFunc, option); gAdditionalRegisteredExamples.push_back(e); } diff --git a/examples/ExampleBrowser/ExampleEntries.h b/examples/ExampleBrowser/ExampleEntries.h index 0158863d0..d4b4119c4 100644 --- a/examples/ExampleBrowser/ExampleEntries.h +++ b/examples/ExampleBrowser/ExampleEntries.h @@ -4,36 +4,29 @@ #include "../CommonInterfaces/CommonExampleInterface.h" - - class ExampleEntriesAll : public ExampleEntries { - struct ExampleEntriesInternalData* m_data; public: - ExampleEntriesAll(); virtual ~ExampleEntriesAll(); - static void registerExampleEntry(int menuLevel, const char* name,const char* description, CommonExampleInterface::CreateFunc* createFunc, int option=0); - + static void registerExampleEntry(int menuLevel, const char* name, const char* description, CommonExampleInterface::CreateFunc* createFunc, int option = 0); + virtual void initExampleEntries(); virtual void initOpenCLExampleEntries(); - + virtual int getNumRegisteredExamples(); virtual CommonExampleInterface::CreateFunc* getExampleCreateFunc(int index); virtual const char* getExampleName(int index); - + virtual const char* getExampleDescription(int index); - virtual int getExampleOption(int index); - + virtual int getExampleOption(int index); }; - - -#endif //EXAMPLE_ENTRIES_H +#endif //EXAMPLE_ENTRIES_H diff --git a/examples/ExampleBrowser/GL_ShapeDrawer.cpp b/examples/ExampleBrowser/GL_ShapeDrawer.cpp index 2b730af5b..81617ad29 100644 --- a/examples/ExampleBrowser/GL_ShapeDrawer.cpp +++ b/examples/ExampleBrowser/GL_ShapeDrawer.cpp @@ -13,13 +13,12 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ -#ifdef _WIN32 //needed for glut.h +#ifdef _WIN32 //needed for glut.h #include #endif #include "../OpenGLWindow/OpenGL2Include.h" - #include "GL_ShapeDrawer.h" #include "BulletCollision/CollisionShapes/btPolyhedralConvexShape.h" #include "BulletCollision/CollisionShapes/btTriangleMeshShape.h" @@ -44,11 +43,10 @@ subject to the following restrictions: #include "LinearMath/btTransformUtil.h" - #include "LinearMath/btIDebugDraw.h" //for debugmodes -#include //printf debugging +#include //printf debugging #if defined(BT_USE_DOUBLE_PRECISION) #define btglLoadMatrix glLoadMatrixd @@ -62,7 +60,8 @@ subject to the following restrictions: #define btglVertex3 glVertex3d #endif -void GL_ShapeDrawer::drawCoordSystem() { +void GL_ShapeDrawer::drawCoordSystem() +{ glBegin(GL_LINES); glColor3f(1, 0, 0); glVertex3d(0, 0, 0); @@ -74,32 +73,23 @@ void GL_ShapeDrawer::drawCoordSystem() { glVertex3d(0, 0, 0); glVertex3d(0, 0, 1); glEnd(); - } - - - - class GlDrawcallback : public btTriangleCallback { - public: - - bool m_wireframe; + bool m_wireframe; GlDrawcallback() - :m_wireframe(false) + : m_wireframe(false) { } - virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex) + virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) { - (void)triangleIndex; (void)partId; - if (m_wireframe) { glBegin(GL_LINES); @@ -113,12 +103,12 @@ public: glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ()); glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ()); glEnd(); - } else + } + else { glBegin(GL_TRIANGLES); //glColor3f(1, 1, 1); - - + glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ()); glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ()); glVertex3d(triangle[2].getX(), triangle[2].getY(), triangle[2].getZ()); @@ -134,13 +124,12 @@ public: class TriangleGlDrawcallback : public btInternalTriangleIndexCallback { public: - virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex) { (void)triangleIndex; (void)partId; - - glBegin(GL_TRIANGLES);//LINES); + glBegin(GL_TRIANGLES); //LINES); glColor3f(1, 0, 0); glVertex3d(triangle[0].getX(), triangle[0].getY(), triangle[0].getZ()); glVertex3d(triangle[1].getX(), triangle[1].getY(), triangle[1].getZ()); @@ -154,22 +143,23 @@ public: } }; - -void GL_ShapeDrawer::drawSphere(btScalar radius, int lats, int longs) +void GL_ShapeDrawer::drawSphere(btScalar radius, int lats, int longs) { int i, j; - for(i = 0; i <= lats; i++) { - btScalar lat0 = SIMD_PI * (-btScalar(0.5) + (btScalar) (i - 1) / lats); - btScalar z0 = radius*sin(lat0); - btScalar zr0 = radius*cos(lat0); + for (i = 0; i <= lats; i++) + { + btScalar lat0 = SIMD_PI * (-btScalar(0.5) + (btScalar)(i - 1) / lats); + btScalar z0 = radius * sin(lat0); + btScalar zr0 = radius * cos(lat0); - btScalar lat1 = SIMD_PI * (-btScalar(0.5) + (btScalar) i / lats); - btScalar z1 = radius*sin(lat1); - btScalar zr1 = radius*cos(lat1); + btScalar lat1 = SIMD_PI * (-btScalar(0.5) + (btScalar)i / lats); + btScalar z1 = radius * sin(lat1); + btScalar zr1 = radius * cos(lat1); glBegin(GL_QUAD_STRIP); - for(j = 0; j <= longs; j++) { - btScalar lng = 2 * SIMD_PI * (btScalar) (j - 1) / longs; + for (j = 0; j <= longs; j++) + { + btScalar lng = 2 * SIMD_PI * (btScalar)(j - 1) / longs; btScalar x = cos(lng); btScalar y = sin(lng); glNormal3f(x * zr1, y * zr1, z1); @@ -181,48 +171,49 @@ void GL_ShapeDrawer::drawSphere(btScalar radius, int lats, int longs) } } - -GL_ShapeDrawer::ShapeCache* GL_ShapeDrawer::cache(btConvexShape* shape) +GL_ShapeDrawer::ShapeCache* GL_ShapeDrawer::cache(btConvexShape* shape) { - ShapeCache* sc=(ShapeCache*)shape->getUserPointer(); - if(!sc) + ShapeCache* sc = (ShapeCache*)shape->getUserPointer(); + if (!sc) { - sc=new(btAlignedAlloc(sizeof(ShapeCache),16)) ShapeCache(shape); + sc = new (btAlignedAlloc(sizeof(ShapeCache), 16)) ShapeCache(shape); sc->m_shapehull.buildHull(shape->getMargin()); m_shapecaches.push_back(sc); shape->setUserPointer(sc); - /* Build edges */ - const int ni=sc->m_shapehull.numIndices(); - const int nv=sc->m_shapehull.numVertices(); - const unsigned int* pi=sc->m_shapehull.getIndexPointer(); - const btVector3* pv=sc->m_shapehull.getVertexPointer(); - btAlignedObjectArray edges; + /* Build edges */ + const int ni = sc->m_shapehull.numIndices(); + const int nv = sc->m_shapehull.numVertices(); + const unsigned int* pi = sc->m_shapehull.getIndexPointer(); + const btVector3* pv = sc->m_shapehull.getVertexPointer(); + btAlignedObjectArray edges; sc->m_edges.reserve(ni); - edges.resize(nv*nv,0); - for(int i=0;im_edges.push_back(ShapeCache::Edge()); - e=&sc->m_edges[sc->m_edges.size()-1]; - e->n[0]=nrm;e->n[1]=-nrm; - e->v[0]=a;e->v[1]=b; + e = &sc->m_edges[sc->m_edges.size() - 1]; + e->n[0] = nrm; + e->n[1] = -nrm; + e->v[0] = a; + e->v[1] = b; } else { - e->n[1]=nrm; + e->n[1] = nrm; } } } } - return(sc); + return (sc); } void renderSquareA(float x, float y, float z) @@ -237,22 +228,20 @@ void renderSquareA(float x, float y, float z) inline void glDrawVector(const btVector3& v) { glVertex3d(v[0], v[1], v[2]); } - -void GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, const btVector3& color,int debugMode,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax) +void GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, const btVector3& color, int debugMode, const btVector3& worldBoundsMin, const btVector3& worldBoundsMax) { - if (shape->getShapeType() == CUSTOM_CONVEX_SHAPE_TYPE) { btVector3 org(m[12], m[13], m[14]); btVector3 dx(m[0], m[1], m[2]); btVector3 dy(m[4], m[5], m[6]); -// btVector3 dz(m[8], m[9], m[10]); + // btVector3 dz(m[8], m[9], m[10]); const btBoxShape* boxShape = static_cast(shape); btVector3 halfExtent = boxShape->getHalfExtentsWithMargin(); dx *= halfExtent[0]; dy *= halfExtent[1]; -// dz *= halfExtent[2]; - glColor3f(1,1,1); + // dz *= halfExtent[2]; + glColor3f(1, 1, 1); glDisable(GL_LIGHTING); glLineWidth(2); @@ -263,8 +252,8 @@ void GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, cons glDrawVector(org + dx - dy); glEnd(); return; - } - else if((shape->getShapeType() == BOX_SHAPE_PROXYTYPE) && (debugMode & btIDebugDraw::DBG_FastWireframe)) + } + else if ((shape->getShapeType() == BOX_SHAPE_PROXYTYPE) && (debugMode & btIDebugDraw::DBG_FastWireframe)) { btVector3 org(m[12], m[13], m[14]); btVector3 dx(m[0], m[1], m[2]); @@ -298,22 +287,21 @@ void GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, cons return; } - glPushMatrix(); + glPushMatrix(); btglMultMatrix(m); - if (shape->getShapeType() == UNIFORM_SCALING_SHAPE_PROXYTYPE) { const btUniformScalingShape* scalingShape = static_cast(shape); const btConvexShape* convexShape = scalingShape->getChildShape(); - float scalingFactor = (float)scalingShape->getUniformScalingFactor(); + float scalingFactor = (float)scalingShape->getUniformScalingFactor(); { - btScalar tmpScaling[4][4]={{scalingFactor,0,0,0}, - {0,scalingFactor,0,0}, - {0,0,scalingFactor,0}, - {0,0,0,1}}; + btScalar tmpScaling[4][4] = {{scalingFactor, 0, 0, 0}, + {0, scalingFactor, 0, 0}, + {0, 0, scalingFactor, 0}, + {0, 0, 0, 1}}; - drawOpenGL( (btScalar*)tmpScaling,convexShape,color,debugMode,worldBoundsMin,worldBoundsMax); + drawOpenGL((btScalar*)tmpScaling, convexShape, color, debugMode, worldBoundsMin, worldBoundsMax); } glPopMatrix(); return; @@ -322,83 +310,79 @@ void GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, cons if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) { const btCompoundShape* compoundShape = static_cast(shape); - for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--) + for (int i = compoundShape->getNumChildShapes() - 1; i >= 0; i--) { btTransform childTrans = compoundShape->getChildTransform(i); const btCollisionShape* colShape = compoundShape->getChildShape(i); - ATTRIBUTE_ALIGNED16(btScalar) childMat[16]; + ATTRIBUTE_ALIGNED16(btScalar) + childMat[16]; childTrans.getOpenGLMatrix(childMat); - drawOpenGL(childMat,colShape,color,debugMode,worldBoundsMin,worldBoundsMax); + drawOpenGL(childMat, colShape, color, debugMode, worldBoundsMin, worldBoundsMax); } - - } else + } + else { - if(m_textureenabled&&(!m_textureinitialized)) + if (m_textureenabled && (!m_textureinitialized)) { - GLubyte* image=new GLubyte[256*256*4]; - for(int y=0;y<256;++y) + GLubyte* image = new GLubyte[256 * 256 * 4]; + for (int y = 0; y < 256; ++y) { - const int t=y>>4; - GLubyte* pi=image+y*256*3; - for(int x=0;x<256;++x) + const int t = y >> 4; + GLubyte* pi = image + y * 256 * 3; + for (int x = 0; x < 256; ++x) { - const int s=x>>4; - const GLubyte b=180; - GLubyte c=b+((s+(t&1))&1)*(255-b); - pi[0]=pi[1]=pi[2]=pi[3]=c;pi+=3; + const int s = x >> 4; + const GLubyte b = 180; + GLubyte c = b + ((s + (t & 1)) & 1) * (255 - b); + pi[0] = pi[1] = pi[2] = pi[3] = c; + pi += 3; } } - glGenTextures(1,(GLuint*)&m_texturehandle); - glBindTexture(GL_TEXTURE_2D,m_texturehandle); + glGenTextures(1, (GLuint*)&m_texturehandle); + glBindTexture(GL_TEXTURE_2D, m_texturehandle); - - glGenTextures(1,(GLuint*)&m_texturehandle); - glBindTexture(GL_TEXTURE_2D,m_texturehandle); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); - glTexImage2D(GL_TEXTURE_2D, 0, 3, 256 , 256 , 0, GL_RGB, GL_UNSIGNED_BYTE, image); - //glGenerateMipmap(GL_TEXTURE_2D); - delete[] image; - - + glGenTextures(1, (GLuint*)&m_texturehandle); + glBindTexture(GL_TEXTURE_2D, m_texturehandle); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexImage2D(GL_TEXTURE_2D, 0, 3, 256, 256, 0, GL_RGB, GL_UNSIGNED_BYTE, image); + //glGenerateMipmap(GL_TEXTURE_2D); + delete[] image; } glMatrixMode(GL_TEXTURE); glLoadIdentity(); - glScalef(0.025f,0.025f,0.025f); + glScalef(0.025f, 0.025f, 0.025f); glMatrixMode(GL_MODELVIEW); - static const GLfloat planex[]={1,0,0,0}; + static const GLfloat planex[] = {1, 0, 0, 0}; // static const GLfloat planey[]={0,1,0,0}; - static const GLfloat planez[]={0,0,1,0}; - glTexGenfv(GL_S,GL_OBJECT_PLANE,planex); - glTexGenfv(GL_T,GL_OBJECT_PLANE,planez); - glTexGeni(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); - glTexGeni(GL_T,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR); - glEnable(GL_TEXTURE_GEN_S); - glEnable(GL_TEXTURE_GEN_T); - glEnable(GL_TEXTURE_GEN_R); - m_textureinitialized=true; - - - + static const GLfloat planez[] = {0, 0, 1, 0}; + glTexGenfv(GL_S, GL_OBJECT_PLANE, planex); + glTexGenfv(GL_T, GL_OBJECT_PLANE, planez); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + m_textureinitialized = true; //drawCoordSystem(); //glPushMatrix(); glEnable(GL_COLOR_MATERIAL); - if(m_textureenabled) + if (m_textureenabled) { glEnable(GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D,m_texturehandle); - } else + glBindTexture(GL_TEXTURE_2D, m_texturehandle); + } + else { glDisable(GL_TEXTURE_2D); } - - glColor3f(color.x(),color.y(), color.z()); + glColor3f(color.x(), color.y(), color.z()); //bool useWireframeFallback = true; @@ -408,15 +392,14 @@ void GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, cons ///the benefit of 'default' is that it approximates the actual collision shape including collision margin //int shapetype=m_textureenabled?MAX_BROADPHASE_COLLISION_TYPES:shape->getShapeType(); - int shapetype=shape->getShapeType(); + int shapetype = shape->getShapeType(); switch (shapetype) { - case SPHERE_SHAPE_PROXYTYPE: { const btSphereShape* sphereShape = static_cast(shape); - float radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin - drawSphere(radius,10,10); + float radius = sphereShape->getMargin(); //radius doesn't include the margin, so draw with margin + drawSphere(radius, 10, 10); //useWireframeFallback = false; break; } @@ -425,45 +408,45 @@ void GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, cons { const btBoxShape* boxShape = static_cast(shape); btVector3 halfExtent = boxShape->getHalfExtentsWithMargin(); - - static int indices[36] = { - 0,1,2, - 3,2,1, - 4,0,6, - 6,0,2, - 5,1,4, - 4,1,0, - 7,3,1, - 7,1,5, - 5,4,7, - 7,4,6, - 7,2,3, - 7,6,2}; - btVector3 vertices[8]={ - btVector3(halfExtent[0],halfExtent[1],halfExtent[2]), - btVector3(-halfExtent[0],halfExtent[1],halfExtent[2]), - btVector3(halfExtent[0],-halfExtent[1],halfExtent[2]), - btVector3(-halfExtent[0],-halfExtent[1],halfExtent[2]), - btVector3(halfExtent[0],halfExtent[1],-halfExtent[2]), - btVector3(-halfExtent[0],halfExtent[1],-halfExtent[2]), - btVector3(halfExtent[0],-halfExtent[1],-halfExtent[2]), - btVector3(-halfExtent[0],-halfExtent[1],-halfExtent[2])}; + static int indices[36] = { + 0, 1, 2, + 3, 2, 1, + 4, 0, 6, + 6, 0, 2, + 5, 1, 4, + 4, 1, 0, + 7, 3, 1, + 7, 1, 5, + 5, 4, 7, + 7, 4, 6, + 7, 2, 3, + 7, 6, 2}; + + btVector3 vertices[8] = { + btVector3(halfExtent[0], halfExtent[1], halfExtent[2]), + btVector3(-halfExtent[0], halfExtent[1], halfExtent[2]), + btVector3(halfExtent[0], -halfExtent[1], halfExtent[2]), + btVector3(-halfExtent[0], -halfExtent[1], halfExtent[2]), + btVector3(halfExtent[0], halfExtent[1], -halfExtent[2]), + btVector3(-halfExtent[0], halfExtent[1], -halfExtent[2]), + btVector3(halfExtent[0], -halfExtent[1], -halfExtent[2]), + btVector3(-halfExtent[0], -halfExtent[1], -halfExtent[2])}; #if 1 - glBegin (GL_TRIANGLES); - int si=36; - for (int i=0;i(shape); btScalar planeConst = staticPlaneShape->getPlaneConstant(); const btVector3& planeNormal = staticPlaneShape->getPlaneNormal(); btVector3 planeOrigin = planeNormal * planeConst; - btVector3 vec0,vec1; - btPlaneSpace1(planeNormal,vec0,vec1); + btVector3 vec0, vec1; + btPlaneSpace1(planeNormal, vec0, vec1); btScalar vecLen = 100.f; - btVector3 pt0 = planeOrigin + vec0*vecLen; - btVector3 pt1 = planeOrigin - vec0*vecLen; - btVector3 pt2 = planeOrigin + vec1*vecLen; - btVector3 pt3 = planeOrigin - vec1*vecLen; + btVector3 pt0 = planeOrigin + vec0 * vecLen; + btVector3 pt1 = planeOrigin - vec0 * vecLen; + btVector3 pt2 = planeOrigin + vec1 * vecLen; + btVector3 pt3 = planeOrigin - vec1 * vecLen; glBegin(GL_LINES); - glVertex3f(pt0.getX(),pt0.getY(),pt0.getZ()); - glVertex3f(pt1.getX(),pt1.getY(),pt1.getZ()); - glVertex3f(pt2.getX(),pt2.getY(),pt2.getZ()); - glVertex3f(pt3.getX(),pt3.getY(),pt3.getZ()); + glVertex3f(pt0.getX(), pt0.getY(), pt0.getZ()); + glVertex3f(pt1.getX(), pt1.getY(), pt1.getZ()); + glVertex3f(pt2.getX(), pt2.getY(), pt2.getZ()); + glVertex3f(pt3.getX(), pt3.getY(), pt3.getZ()); glEnd(); + break; + } + + case MULTI_SPHERE_SHAPE_PROXYTYPE: + { + const btMultiSphereShape* multiSphereShape = static_cast(shape); + + btTransform childTransform; + childTransform.setIdentity(); + + for (int i = multiSphereShape->getSphereCount() - 1; i >= 0; i--) + { + btSphereShape sc(multiSphereShape->getSphereRadius(i)); + childTransform.setOrigin(multiSphereShape->getSpherePosition(i)); + ATTRIBUTE_ALIGNED16(btScalar) + childMat[16]; + childTransform.getOpenGLMatrix(childMat); + drawOpenGL(childMat, &sc, color, debugMode, worldBoundsMin, worldBoundsMax); + } break; - } - - case MULTI_SPHERE_SHAPE_PROXYTYPE: - { - const btMultiSphereShape* multiSphereShape = static_cast(shape); - - btTransform childTransform; - childTransform.setIdentity(); - - - for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--) - { - btSphereShape sc(multiSphereShape->getSphereRadius(i)); - childTransform.setOrigin(multiSphereShape->getSpherePosition(i)); - ATTRIBUTE_ALIGNED16(btScalar) childMat[16]; - childTransform.getOpenGLMatrix(childMat); - drawOpenGL(childMat,&sc,color,debugMode,worldBoundsMin,worldBoundsMax); - } - - break; - } - - default: + default: { if (shape->isConvex()) { - const btConvexPolyhedron* poly = shape->isPolyhedral() ? ((btPolyhedralConvexShape*) shape)->getConvexPolyhedron() : 0; + const btConvexPolyhedron* poly = shape->isPolyhedral() ? ((btPolyhedralConvexShape*)shape)->getConvexPolyhedron() : 0; if (poly) { int i; - glBegin (GL_TRIANGLES); - for (i=0;im_faces.size();i++) + glBegin(GL_TRIANGLES); + for (i = 0; i < poly->m_faces.size(); i++) { - btVector3 centroid(0,0,0); + btVector3 centroid(0, 0, 0); int numVerts = poly->m_faces[i].m_indices.size(); - if (numVerts>2) + if (numVerts > 2) { btVector3 v1 = poly->m_vertices[poly->m_faces[i].m_indices[0]]; - for (int v=0;vm_faces[i].m_indices.size()-2;v++) + for (int v = 0; v < poly->m_faces[i].m_indices.size() - 2; v++) { - - btVector3 v2 = poly->m_vertices[poly->m_faces[i].m_indices[v+1]]; - btVector3 v3 = poly->m_vertices[poly->m_faces[i].m_indices[v+2]]; - btVector3 normal = (v3-v1).cross(v2-v1); - normal.normalize (); - glNormal3f(normal.getX(),normal.getY(),normal.getZ()); - glVertex3f (v1.x(), v1.y(), v1.z()); - glVertex3f (v2.x(), v2.y(), v2.z()); - glVertex3f (v3.x(), v3.y(), v3.z()); + btVector3 v2 = poly->m_vertices[poly->m_faces[i].m_indices[v + 1]]; + btVector3 v3 = poly->m_vertices[poly->m_faces[i].m_indices[v + 2]]; + btVector3 normal = (v3 - v1).cross(v2 - v1); + normal.normalize(); + glNormal3f(normal.getX(), normal.getY(), normal.getZ()); + glVertex3f(v1.x(), v1.y(), v1.z()); + glVertex3f(v2.x(), v2.y(), v2.z()); + glVertex3f(v3.x(), v3.y(), v3.z()); } } } - glEnd (); - } else + glEnd(); + } + else { - ShapeCache* sc=cache((btConvexShape*)shape); + ShapeCache* sc = cache((btConvexShape*)shape); //glutSolidCube(1.0); - btShapeHull* hull = &sc->m_shapehull/*(btShapeHull*)shape->getUserPointer()*/; + btShapeHull* hull = &sc->m_shapehull /*(btShapeHull*)shape->getUserPointer()*/; - if (hull->numTriangles () > 0) + if (hull->numTriangles() > 0) { int index = 0; const unsigned int* idx = hull->getIndexPointer(); const btVector3* vtx = hull->getVertexPointer(); - glBegin (GL_TRIANGLES); + glBegin(GL_TRIANGLES); - for (int i = 0; i < hull->numTriangles (); i++) + for (int i = 0; i < hull->numTriangles(); i++) { int i1 = index++; int i2 = index++; int i3 = index++; - btAssert(i1 < hull->numIndices () && - i2 < hull->numIndices () && - i3 < hull->numIndices ()); + btAssert(i1 < hull->numIndices() && + i2 < hull->numIndices() && + i3 < hull->numIndices()); int index1 = idx[i1]; int index2 = idx[i2]; int index3 = idx[i3]; - btAssert(index1 < hull->numVertices () && - index2 < hull->numVertices () && - index3 < hull->numVertices ()); + btAssert(index1 < hull->numVertices() && + index2 < hull->numVertices() && + index3 < hull->numVertices()); btVector3 v1 = vtx[index1]; btVector3 v2 = vtx[index2]; btVector3 v3 = vtx[index3]; - btVector3 normal = (v3-v1).cross(v2-v1); - normal.normalize (); - glNormal3f(normal.getX(),normal.getY(),normal.getZ()); - glVertex3f (v1.x(), v1.y(), v1.z()); - glVertex3f (v2.x(), v2.y(), v2.z()); - glVertex3f (v3.x(), v3.y(), v3.z()); - + btVector3 normal = (v3 - v1).cross(v2 - v1); + normal.normalize(); + glNormal3f(normal.getX(), normal.getY(), normal.getZ()); + glVertex3f(v1.x(), v1.y(), v1.z()); + glVertex3f(v2.x(), v2.y(), v2.z()); + glVertex3f(v3.x(), v3.y(), v3.z()); } - glEnd (); - + glEnd(); } } } } } - } - - glNormal3f(0,1,0); - + glNormal3f(0, 1, 0); /// for polyhedral shapes - if (debugMode==btIDebugDraw::DBG_DrawFeaturesText && (shape->isPolyhedral())) + if (debugMode == btIDebugDraw::DBG_DrawFeaturesText && (shape->isPolyhedral())) { - btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape; + btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*)shape; { - glColor3f(1.f, 1.f, 1.f); int i; - for (i=0;igetNumVertices();i++) + for (i = 0; i < polyshape->getNumVertices(); i++) { btVector3 vtx; - polyshape->getVertex(i,vtx); + polyshape->getVertex(i, vtx); char buf[12]; - sprintf(buf," %d",i); + sprintf(buf, " %d", i); //btDrawString(BMF_GetFont(BMF_kHelvetica10),buf); } - for (i=0;igetNumPlanes();i++) + for (i = 0; i < polyshape->getNumPlanes(); i++) { btVector3 normal; btVector3 vtx; - polyshape->getPlane(normal,vtx,i); + polyshape->getPlane(normal, vtx, i); //btScalar d = vtx.dot(normal); //char buf[12]; //sprintf(buf," plane %d",i); //btDrawString(BMF_GetFont(BMF_kHelvetica10),buf); - } } - } - - - - - - - - } glPopMatrix(); @@ -685,199 +647,197 @@ void GL_ShapeDrawer::drawOpenGL(btScalar* m, const btCollisionShape* shape, cons } // -void GL_ShapeDrawer::drawShadow(btScalar* m,const btVector3& extrusion,const btCollisionShape* shape,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax) +void GL_ShapeDrawer::drawShadow(btScalar* m, const btVector3& extrusion, const btCollisionShape* shape, const btVector3& worldBoundsMin, const btVector3& worldBoundsMax) { - glPushMatrix(); + glPushMatrix(); btglMultMatrix(m); - if(shape->getShapeType() == UNIFORM_SCALING_SHAPE_PROXYTYPE) + if (shape->getShapeType() == UNIFORM_SCALING_SHAPE_PROXYTYPE) { const btUniformScalingShape* scalingShape = static_cast(shape); const btConvexShape* convexShape = scalingShape->getChildShape(); - float scalingFactor = (float)scalingShape->getUniformScalingFactor(); - btScalar tmpScaling[4][4]={ {scalingFactor,0,0,0}, - {0,scalingFactor,0,0}, - {0,0,scalingFactor,0}, - {0,0,0,1}}; - drawShadow((btScalar*)tmpScaling,extrusion,convexShape,worldBoundsMin,worldBoundsMax); + float scalingFactor = (float)scalingShape->getUniformScalingFactor(); + btScalar tmpScaling[4][4] = {{scalingFactor, 0, 0, 0}, + {0, scalingFactor, 0, 0}, + {0, 0, scalingFactor, 0}, + {0, 0, 0, 1}}; + drawShadow((btScalar*)tmpScaling, extrusion, convexShape, worldBoundsMin, worldBoundsMax); glPopMatrix(); return; } - else if(shape->getShapeType()==COMPOUND_SHAPE_PROXYTYPE) + else if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) { const btCompoundShape* compoundShape = static_cast(shape); - for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--) + for (int i = compoundShape->getNumChildShapes() - 1; i >= 0; i--) { btTransform childTrans = compoundShape->getChildTransform(i); const btCollisionShape* colShape = compoundShape->getChildShape(i); - ATTRIBUTE_ALIGNED16(btScalar) childMat[16]; + ATTRIBUTE_ALIGNED16(btScalar) + childMat[16]; childTrans.getOpenGLMatrix(childMat); - drawShadow(childMat,extrusion*childTrans.getBasis(),colShape,worldBoundsMin,worldBoundsMax); + drawShadow(childMat, extrusion * childTrans.getBasis(), colShape, worldBoundsMin, worldBoundsMax); } } else { - // bool useWireframeFallback = true; + // bool useWireframeFallback = true; if (shape->isConvex()) { - ShapeCache* sc=cache((btConvexShape*)shape); - btShapeHull* hull =&sc->m_shapehull; + ShapeCache* sc = cache((btConvexShape*)shape); + btShapeHull* hull = &sc->m_shapehull; glBegin(GL_QUADS); - for(int i=0;im_edges.size();++i) - { - const btScalar d=btDot(sc->m_edges[i].n[0],extrusion); - if((d*btDot(sc->m_edges[i].n[1],extrusion))<0) + for (int i = 0; i < sc->m_edges.size(); ++i) + { + const btScalar d = btDot(sc->m_edges[i].n[0], extrusion); + if ((d * btDot(sc->m_edges[i].n[1], extrusion)) < 0) { - const int q= d<0?1:0; - const btVector3& a= hull->getVertexPointer()[sc->m_edges[i].v[q]]; - const btVector3& b= hull->getVertexPointer()[sc->m_edges[i].v[1-q]]; - glVertex3f(a[0],a[1],a[2]); - glVertex3f(b[0],b[1],b[2]); - glVertex3f(b[0]+extrusion[0],b[1]+extrusion[1],b[2]+extrusion[2]); - glVertex3f(a[0]+extrusion[0],a[1]+extrusion[1],a[2]+extrusion[2]); + const int q = d < 0 ? 1 : 0; + const btVector3& a = hull->getVertexPointer()[sc->m_edges[i].v[q]]; + const btVector3& b = hull->getVertexPointer()[sc->m_edges[i].v[1 - q]]; + glVertex3f(a[0], a[1], a[2]); + glVertex3f(b[0], b[1], b[2]); + glVertex3f(b[0] + extrusion[0], b[1] + extrusion[1], b[2] + extrusion[2]); + glVertex3f(a[0] + extrusion[0], a[1] + extrusion[1], a[2] + extrusion[2]); } } glEnd(); } - } - - - - if (shape->isConcave())//>getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE||shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE) - // if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + if (shape->isConcave()) //>getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE||shape->getShapeType() == GIMPACT_SHAPE_PROXYTYPE) + // if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) { - btConcaveShape* concaveMesh = (btConcaveShape*) shape; + btConcaveShape* concaveMesh = (btConcaveShape*)shape; GlDrawcallback drawCallback; drawCallback.m_wireframe = false; - concaveMesh->processAllTriangles(&drawCallback,worldBoundsMin,worldBoundsMax); - + concaveMesh->processAllTriangles(&drawCallback, worldBoundsMin, worldBoundsMax); } glPopMatrix(); - } // GL_ShapeDrawer::GL_ShapeDrawer() { - m_texturehandle = 0; - m_textureenabled = false; - m_textureinitialized = false; + m_texturehandle = 0; + m_textureenabled = false; + m_textureinitialized = false; } GL_ShapeDrawer::~GL_ShapeDrawer() { int i; - for (i=0;i~ShapeCache(); btAlignedFree(m_shapecaches[i]); } m_shapecaches.clear(); - if(m_textureinitialized) + if (m_textureinitialized) { - glDeleteTextures(1,(const GLuint*) &m_texturehandle); + glDeleteTextures(1, (const GLuint*)&m_texturehandle); } } void GL_ShapeDrawer::drawSceneInternal(const btDiscreteDynamicsWorld* dynamicsWorld, int pass, int cameraUpAxis) { - btAssert(dynamicsWorld); - - btScalar m[16]; - btMatrix3x3 rot;rot.setIdentity(); - const int numObjects=dynamicsWorld->getNumCollisionObjects(); - btVector3 wireColor(1,0,0); + btScalar m[16]; + btMatrix3x3 rot; + rot.setIdentity(); + const int numObjects = dynamicsWorld->getNumCollisionObjects(); + btVector3 wireColor(1, 0, 0); //glDisable(GL_CULL_FACE); - - for(int i=0;igetCollisionObjectArray()[i]; - const btRigidBody* body=btRigidBody::upcast(colObj); - if(body&&body->getMotionState()) + const btCollisionObject* colObj = dynamicsWorld->getCollisionObjectArray()[i]; + const btRigidBody* body = btRigidBody::upcast(colObj); + if (body && body->getMotionState()) { btDefaultMotionState* myMotionState = (btDefaultMotionState*)body->getMotionState(); myMotionState->m_graphicsWorldTrans.getOpenGLMatrix(m); - rot=myMotionState->m_graphicsWorldTrans.getBasis(); + rot = myMotionState->m_graphicsWorldTrans.getBasis(); } else { colObj->getWorldTransform().getOpenGLMatrix(m); - rot=colObj->getWorldTransform().getBasis(); + rot = colObj->getWorldTransform().getBasis(); } - btVector3 wireColor(1.f,1.0f,0.5f); //wants deactivation - if(i&1) wireColor=btVector3(0.f,0.0f,1.f); + btVector3 wireColor(1.f, 1.0f, 0.5f); //wants deactivation + if (i & 1) wireColor = btVector3(0.f, 0.0f, 1.f); ///color differently for active, sleeping, wantsdeactivation states - if (colObj->getActivationState() == 1) //active + if (colObj->getActivationState() == 1) //active { if (i & 1) { - wireColor += btVector3 (1.f,0.f,0.f); + wireColor += btVector3(1.f, 0.f, 0.f); } else { - wireColor += btVector3 (.5f,0.f,0.f); + wireColor += btVector3(.5f, 0.f, 0.f); } } - if(colObj->getActivationState()==2) //ISLAND_SLEEPING + if (colObj->getActivationState() == 2) //ISLAND_SLEEPING { - if(i&1) + if (i & 1) { - wireColor += btVector3 (0.f,1.f, 0.f); + wireColor += btVector3(0.f, 1.f, 0.f); } else { - wireColor += btVector3 (0.f,0.5f,0.f); + wireColor += btVector3(0.f, 0.5f, 0.f); } } - btVector3 aabbMin(0,0,0),aabbMax(0,0,0); + btVector3 aabbMin(0, 0, 0), aabbMax(0, 0, 0); //m_dynamicsWorld->getBroadphase()->getBroadphaseAabb(aabbMin,aabbMax); - aabbMin-=btVector3(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT); - aabbMax+=btVector3(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT); - // printf("aabbMin=(%f,%f,%f)\n",aabbMin.getX(),aabbMin.getY(),aabbMin.getZ()); - // printf("aabbMax=(%f,%f,%f)\n",aabbMax.getX(),aabbMax.getY(),aabbMax.getZ()); - // m_dynamicsWorld->getDebugDrawer()->drawAabb(aabbMin,aabbMax,btVector3(1,1,1)); + aabbMin -= btVector3(BT_LARGE_FLOAT, BT_LARGE_FLOAT, BT_LARGE_FLOAT); + aabbMax += btVector3(BT_LARGE_FLOAT, BT_LARGE_FLOAT, BT_LARGE_FLOAT); + // printf("aabbMin=(%f,%f,%f)\n",aabbMin.getX(),aabbMin.getY(),aabbMin.getZ()); + // printf("aabbMax=(%f,%f,%f)\n",aabbMax.getX(),aabbMax.getY(),aabbMax.getZ()); + // m_dynamicsWorld->getDebugDrawer()->drawAabb(aabbMin,aabbMax,btVector3(1,1,1)); //switch(pass) - + //if (!(getDebugMode()& btIDebugDraw::DBG_DrawWireframe)) - int debugMode = 0;//getDebugMode() + int debugMode = 0; //getDebugMode() //btVector3 m_sundirection(-1,-1,-1); - - btVector3 m_sundirection(btVector3(1,-2,1)*1000); - if (cameraUpAxis==2) + + btVector3 m_sundirection(btVector3(1, -2, 1) * 1000); + if (cameraUpAxis == 2) { - m_sundirection = btVector3(1,1,-2)*1000; + m_sundirection = btVector3(1, 1, -2) * 1000; } - - switch(pass) + + switch (pass) { - case 0: drawOpenGL(m,colObj->getCollisionShape(),wireColor,debugMode,aabbMin,aabbMax);break; - case 1: drawShadow(m,m_sundirection*rot,colObj->getCollisionShape(),aabbMin,aabbMax);break; - case 2: drawOpenGL(m,colObj->getCollisionShape(),wireColor*btScalar(0.3),0,aabbMin,aabbMax);break; + case 0: + drawOpenGL(m, colObj->getCollisionShape(), wireColor, debugMode, aabbMin, aabbMax); + break; + case 1: + drawShadow(m, m_sundirection * rot, colObj->getCollisionShape(), aabbMin, aabbMax); + break; + case 2: + drawOpenGL(m, colObj->getCollisionShape(), wireColor * btScalar(0.3), 0, aabbMin, aabbMax); + break; } } - } //this GL_ShapeDrawer will be removed, in the meanwhile directly access this global 'useShadoMaps' extern bool useShadowMap; void GL_ShapeDrawer::drawScene(const btDiscreteDynamicsWorld* dynamicsWorld, bool useShadows1, int cameraUpAxis) { - bool useShadows = useShadowMap; - GLfloat light_ambient[] = { btScalar(0.2), btScalar(0.2), btScalar(0.2), btScalar(1.0) }; - GLfloat light_diffuse[] = { btScalar(1.0), btScalar(1.0), btScalar(1.0), btScalar(1.0) }; - GLfloat light_specular[] = { btScalar(1.0), btScalar(1.0), btScalar(1.0), btScalar(1.0 )}; + GLfloat light_ambient[] = {btScalar(0.2), btScalar(0.2), btScalar(0.2), btScalar(1.0)}; + GLfloat light_diffuse[] = {btScalar(1.0), btScalar(1.0), btScalar(1.0), btScalar(1.0)}; + GLfloat light_specular[] = {btScalar(1.0), btScalar(1.0), btScalar(1.0), btScalar(1.0)}; /* light_position is NOT default value */ - GLfloat light_position0[] = { btScalar(1.0), btScalar(10.0), btScalar(1.0), btScalar(0.0 )}; - GLfloat light_position1[] = { btScalar(-1.0), btScalar(-10.0), btScalar(-1.0), btScalar(0.0) }; + GLfloat light_position0[] = {btScalar(1.0), btScalar(10.0), btScalar(1.0), btScalar(0.0)}; + GLfloat light_position1[] = {btScalar(-1.0), btScalar(-10.0), btScalar(-1.0), btScalar(0.0)}; glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); @@ -893,59 +853,57 @@ void GL_ShapeDrawer::drawScene(const btDiscreteDynamicsWorld* dynamicsWorld, boo glEnable(GL_LIGHT0); glEnable(GL_LIGHT1); - glShadeModel(GL_SMOOTH); glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS); - glClearColor(btScalar(0.7),btScalar(0.7),btScalar(0.7),btScalar(0)); + glClearColor(btScalar(0.7), btScalar(0.7), btScalar(0.7), btScalar(0)); + if (useShadows) + { + glClear(GL_STENCIL_BUFFER_BIT); + glEnable(GL_CULL_FACE); + drawSceneInternal(dynamicsWorld, 0, cameraUpAxis); - if(useShadows) - { - glClear(GL_STENCIL_BUFFER_BIT); - glEnable(GL_CULL_FACE); - drawSceneInternal(dynamicsWorld,0, cameraUpAxis); + glDisable(GL_LIGHTING); + glDepthMask(GL_FALSE); + glDepthFunc(GL_LEQUAL); + glEnable(GL_STENCIL_TEST); + glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); + glStencilFunc(GL_ALWAYS, 1, 0xFFFFFFFFL); + glFrontFace(GL_CCW); + glStencilOp(GL_KEEP, GL_KEEP, GL_INCR); + drawSceneInternal(dynamicsWorld, 1, cameraUpAxis); + glFrontFace(GL_CW); + glStencilOp(GL_KEEP, GL_KEEP, GL_DECR); + drawSceneInternal(dynamicsWorld, 1, cameraUpAxis); + glFrontFace(GL_CCW); - glDisable(GL_LIGHTING); - glDepthMask(GL_FALSE); - glDepthFunc(GL_LEQUAL); - glEnable(GL_STENCIL_TEST); - glColorMask(GL_FALSE,GL_FALSE,GL_FALSE,GL_FALSE); - glStencilFunc(GL_ALWAYS,1,0xFFFFFFFFL); - glFrontFace(GL_CCW); - glStencilOp(GL_KEEP,GL_KEEP,GL_INCR); - drawSceneInternal(dynamicsWorld,1,cameraUpAxis); - glFrontFace(GL_CW); - glStencilOp(GL_KEEP,GL_KEEP,GL_DECR); - drawSceneInternal(dynamicsWorld,1,cameraUpAxis); - glFrontFace(GL_CCW); + glPolygonMode(GL_FRONT, GL_FILL); + glPolygonMode(GL_BACK, GL_FILL); + glShadeModel(GL_SMOOTH); + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_LESS); + glEnable(GL_LIGHTING); + glDepthMask(GL_TRUE); + glCullFace(GL_BACK); + glFrontFace(GL_CCW); + glEnable(GL_CULL_FACE); + glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - glPolygonMode(GL_FRONT,GL_FILL); - glPolygonMode(GL_BACK,GL_FILL); - glShadeModel(GL_SMOOTH); - glEnable(GL_DEPTH_TEST); - glDepthFunc(GL_LESS); - glEnable(GL_LIGHTING); - glDepthMask(GL_TRUE); - glCullFace(GL_BACK); - glFrontFace(GL_CCW); - glEnable(GL_CULL_FACE); - glColorMask(GL_TRUE,GL_TRUE,GL_TRUE,GL_TRUE); - - glDepthFunc(GL_LEQUAL); - glStencilFunc( GL_NOTEQUAL, 0, 0xFFFFFFFFL ); - glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP ); - glDisable(GL_LIGHTING); - drawSceneInternal(dynamicsWorld,2,cameraUpAxis); - glEnable(GL_LIGHTING); - glDepthFunc(GL_LESS); - glDisable(GL_STENCIL_TEST); - glDisable(GL_CULL_FACE); - } - else - { - glDisable(GL_CULL_FACE); - drawSceneInternal(dynamicsWorld,0,cameraUpAxis); - } + glDepthFunc(GL_LEQUAL); + glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFFL); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); + glDisable(GL_LIGHTING); + drawSceneInternal(dynamicsWorld, 2, cameraUpAxis); + glEnable(GL_LIGHTING); + glDepthFunc(GL_LESS); + glDisable(GL_STENCIL_TEST); + glDisable(GL_CULL_FACE); + } + else + { + glDisable(GL_CULL_FACE); + drawSceneInternal(dynamicsWorld, 0, cameraUpAxis); + } } \ No newline at end of file diff --git a/examples/ExampleBrowser/GL_ShapeDrawer.h b/examples/ExampleBrowser/GL_ShapeDrawer.h index e004420c4..9eb13bfd3 100644 --- a/examples/ExampleBrowser/GL_ShapeDrawer.h +++ b/examples/ExampleBrowser/GL_ShapeDrawer.h @@ -30,48 +30,52 @@ class GL_ShapeDrawer protected: struct ShapeCache { - struct Edge { btVector3 n[2];int v[2]; }; - ShapeCache(btConvexShape* s) : m_shapehull(s) {} - btShapeHull m_shapehull; - btAlignedObjectArray m_edges; + struct Edge + { + btVector3 n[2]; + int v[2]; + }; + ShapeCache(btConvexShape* s) : m_shapehull(s) {} + btShapeHull m_shapehull; + btAlignedObjectArray m_edges; }; //clean-up memory of dynamically created shape hulls - btAlignedObjectArray m_shapecaches; - unsigned int m_texturehandle; - bool m_textureenabled; - bool m_textureinitialized; - + btAlignedObjectArray m_shapecaches; + unsigned int m_texturehandle; + bool m_textureenabled; + bool m_textureinitialized; - ShapeCache* cache(btConvexShape*); + ShapeCache* cache(btConvexShape*); virtual void drawSceneInternal(const btDiscreteDynamicsWorld* world, int pass, int cameraUpAxis); public: - GL_ShapeDrawer(); + GL_ShapeDrawer(); - virtual ~GL_ShapeDrawer(); + virtual ~GL_ShapeDrawer(); - + virtual void drawScene(const btDiscreteDynamicsWorld* world, bool useShadows, int cameraUpAxis); - virtual void drawScene(const btDiscreteDynamicsWorld* world, bool useShadows, int cameraUpAxis); + ///drawOpenGL might allocate temporary memoty, stores pointer in shape userpointer + virtual void drawOpenGL(btScalar* m, const btCollisionShape* shape, const btVector3& color, int debugMode, const btVector3& worldBoundsMin, const btVector3& worldBoundsMax); + virtual void drawShadow(btScalar* m, const btVector3& extrusion, const btCollisionShape* shape, const btVector3& worldBoundsMin, const btVector3& worldBoundsMax); - ///drawOpenGL might allocate temporary memoty, stores pointer in shape userpointer - virtual void drawOpenGL(btScalar* m, const btCollisionShape* shape, const btVector3& color,int debugMode,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax); - virtual void drawShadow(btScalar* m, const btVector3& extrusion,const btCollisionShape* shape,const btVector3& worldBoundsMin,const btVector3& worldBoundsMax); - - bool enableTexture(bool enable) { bool p=m_textureenabled;m_textureenabled=enable;return(p); } - bool hasTextureEnabled() const - { - return m_textureenabled; - } - - void drawSphere(btScalar r, int lats, int longs); - static void drawCoordSystem(); - + bool enableTexture(bool enable) + { + bool p = m_textureenabled; + m_textureenabled = enable; + return (p); + } + bool hasTextureEnabled() const + { + return m_textureenabled; + } + + void drawSphere(btScalar r, int lats, int longs); + static void drawCoordSystem(); }; -void OGL_displaylist_register_shape(btCollisionShape * shape); +void OGL_displaylist_register_shape(btCollisionShape* shape); void OGL_displaylist_clean(); -#endif //GL_SHAPE_DRAWER_H - +#endif //GL_SHAPE_DRAWER_H diff --git a/examples/ExampleBrowser/GwenGUISupport/GraphingTexture.cpp b/examples/ExampleBrowser/GwenGUISupport/GraphingTexture.cpp index 7a87be819..5d366618a 100644 --- a/examples/ExampleBrowser/GwenGUISupport/GraphingTexture.cpp +++ b/examples/ExampleBrowser/GwenGUISupport/GraphingTexture.cpp @@ -3,9 +3,9 @@ #include GraphingTexture::GraphingTexture() -:m_textureId(0), -m_width(0), -m_height(0) + : m_textureId(0), + m_width(0), + m_height(0) { } @@ -18,10 +18,9 @@ void GraphingTexture::destroy() { //TODO(erwincoumans) release memory etc... m_width = 0; - m_height=0; - glDeleteTextures(1,(GLuint*)&m_textureId); - m_textureId=0; - + m_height = 0; + glDeleteTextures(1, (GLuint*)&m_textureId); + m_textureId = 0; } bool GraphingTexture::create(int texWidth, int texHeight) @@ -29,50 +28,46 @@ bool GraphingTexture::create(int texWidth, int texHeight) m_width = texWidth; m_height = texHeight; glActiveTexture(GL_TEXTURE0); - - m_imageData.resize(texWidth*texHeight*4); - for(int y=0;y>5; - GLubyte* pi=&m_imageData[y*texWidth*4]; - for(int x=0;x=y)//x<2||y<2||x>253||y>253) + if (x >= y) //x<2||y<2||x>253||y>253) { - pi[0]=0; - pi[1]=0; - pi[2]=255; - pi[3]=255; - } else - { - pi[0]=255; - pi[1]=0; - pi[2]=0; - pi[3]=255; + pi[0] = 0; + pi[1] = 0; + pi[2] = 255; + pi[3] = 255; } - - pi+=4; + else + { + pi[0] = 255; + pi[1] = 0; + pi[2] = 0; + pi[3] = 255; + } + + pi += 4; } } - - - glGenTextures(1,(GLuint*)&m_textureId); - + + glGenTextures(1, (GLuint*)&m_textureId); + uploadImageData(); return true; } void GraphingTexture::uploadImageData() { - glBindTexture(GL_TEXTURE_2D,m_textureId); - assert(glGetError()==GL_NO_ERROR); - - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width,m_height,0,GL_RGBA,GL_UNSIGNED_BYTE,&m_imageData[0]); + glBindTexture(GL_TEXTURE_2D, m_textureId); + assert(glGetError() == GL_NO_ERROR); + + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_width, m_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &m_imageData[0]); glGenerateMipmap(GL_TEXTURE_2D); - - assert(glGetError()==GL_NO_ERROR); - - + + assert(glGetError() == GL_NO_ERROR); } - - diff --git a/examples/ExampleBrowser/GwenGUISupport/GraphingTexture.h b/examples/ExampleBrowser/GwenGUISupport/GraphingTexture.h index 4751ee603..27d52e71b 100644 --- a/examples/ExampleBrowser/GwenGUISupport/GraphingTexture.h +++ b/examples/ExampleBrowser/GwenGUISupport/GraphingTexture.h @@ -9,38 +9,37 @@ struct GraphingTexture btAlignedObjectArray m_imageData; int m_width; int m_height; - + GraphingTexture(); virtual ~GraphingTexture(); - + bool create(int texWidth, int texHeight); - void destroy(); - + void destroy(); + void setPixel(int x, int y, unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha) { - if (y>=0 && y=0 && x= 0 && y < m_height && x >= 0 && x < m_width) { - m_imageData[x*4+y*4*m_width+0] = red; - m_imageData[x*4+y*4*m_width+1] = green; - m_imageData[x*4+y*4*m_width+2] = blue; - m_imageData[x*4+y*4*m_width+3] = alpha; + m_imageData[x * 4 + y * 4 * m_width + 0] = red; + m_imageData[x * 4 + y * 4 * m_width + 1] = green; + m_imageData[x * 4 + y * 4 * m_width + 2] = blue; + m_imageData[x * 4 + y * 4 * m_width + 3] = alpha; } } - + void getPixel(int x, int y, unsigned char& red, unsigned char& green, unsigned char& blue, unsigned char& alpha) { - red = m_imageData[x*4+y*4*m_width+0]; - green = m_imageData[x*4+y*4*m_width+1]; - blue = m_imageData[x*4+y*4*m_width+2]; - alpha = m_imageData[x*4+y*4*m_width+3]; + red = m_imageData[x * 4 + y * 4 * m_width + 0]; + green = m_imageData[x * 4 + y * 4 * m_width + 1]; + blue = m_imageData[x * 4 + y * 4 * m_width + 2]; + alpha = m_imageData[x * 4 + y * 4 * m_width + 3]; } void uploadImageData(); - + int getTextureId() { return m_textureId; } }; -#endif //GRAPHING_TEXTURE_H - +#endif //GRAPHING_TEXTURE_H diff --git a/examples/ExampleBrowser/GwenGUISupport/GwenParameterInterface.cpp b/examples/ExampleBrowser/GwenGUISupport/GwenParameterInterface.cpp index 908106259..afa3d5f4d 100644 --- a/examples/ExampleBrowser/GwenGUISupport/GwenParameterInterface.cpp +++ b/examples/ExampleBrowser/GwenGUISupport/GwenParameterInterface.cpp @@ -3,35 +3,34 @@ struct MyButtonEventHandler : public Gwen::Event::Handler { - Gwen::Controls::Button* m_buttonControl; + Gwen::Controls::Button* m_buttonControl; ButtonParamChangedCallback m_callback; void* m_userPointer; int m_buttonId; MyButtonEventHandler(Gwen::Controls::Button* buttonControl, ButtonParamChangedCallback callback, int buttonId, void* userPointer) - :m_buttonControl(buttonControl), - m_callback(callback), - m_userPointer(userPointer), - m_buttonId(buttonId) + : m_buttonControl(buttonControl), + m_callback(callback), + m_userPointer(userPointer), + m_buttonId(buttonId) { } - void onButtonPress( Gwen::Controls::Base* pControl ) + void onButtonPress(Gwen::Controls::Base* pControl) { if (m_callback) { - bool buttonState = true; - if (m_buttonControl->IsToggle()) - { - buttonState = m_buttonControl->GetToggleState(); - } - ( *m_callback )( m_buttonId, buttonState, m_userPointer ); + bool buttonState = true; + if (m_buttonControl->IsToggle()) + { + buttonState = m_buttonControl->GetToggleState(); + } + (*m_callback)(m_buttonId, buttonState, m_userPointer); } } }; - -template +template struct MySliderEventHandler : public Gwen::Event::Handler { SliderParamChangedCallback m_callback; @@ -40,22 +39,21 @@ struct MySliderEventHandler : public Gwen::Event::Handler Gwen::Controls::Slider* m_pSlider; char m_variableName[1024]; T* m_targetValue; - bool m_showValue; + bool m_showValue; - MySliderEventHandler(const char* varName, Gwen::Controls::TextBox* label, Gwen::Controls::Slider* pSlider,T* target, SliderParamChangedCallback callback, void* userPtr) - : m_callback(callback), - m_userPointer(userPtr), - m_label(label), - m_pSlider(pSlider), - m_targetValue(target), - m_showValue(true) + MySliderEventHandler(const char* varName, Gwen::Controls::TextBox* label, Gwen::Controls::Slider* pSlider, T* target, SliderParamChangedCallback callback, void* userPtr) + : m_callback(callback), + m_userPointer(userPtr), + m_label(label), + m_pSlider(pSlider), + m_targetValue(target), + m_showValue(true) { - memcpy(m_variableName,varName,strlen(varName)+1); + memcpy(m_variableName, varName, strlen(varName) + 1); } - - void SliderMoved( Gwen::Controls::Base* pControl ) + void SliderMoved(Gwen::Controls::Base* pControl) { Gwen::Controls::Slider* pSlider = (Gwen::Controls::Slider*)pControl; //printf("value = %f\n", pSlider->GetValue());//UnitPrint( Utility::Format( L"Slider Value: %.2f", pSlider->GetValue() ) ); @@ -67,10 +65,9 @@ struct MySliderEventHandler : public Gwen::Event::Handler { (*m_callback)(v, m_userPointer); } - } - void SetValue(T v) + void SetValue(T v) { if (v < m_pSlider->GetRangeMin()) { @@ -79,24 +76,21 @@ struct MySliderEventHandler : public Gwen::Event::Handler if (v > m_pSlider->GetRangeMax()) { - printf("?\n"); - + printf("?\n"); } - m_pSlider->SetValue(v,true); + m_pSlider->SetValue(v, true); (*m_targetValue) = v; - float val = float(v);//todo: specialize on template type - if (m_showValue) - { - char txt[1024]; - sprintf(txt,"%s : %.3f", m_variableName,val); - m_label->SetText(txt); - } - + float val = float(v); //todo: specialize on template type + if (m_showValue) + { + char txt[1024]; + sprintf(txt, "%s : %.3f", m_variableName, val); + m_label->SetText(txt); + } } }; - -struct GwenParameters +struct GwenParameters { b3AlignedObjectArray*> m_sliderEventHandlers; b3AlignedObjectArray m_sliders; @@ -108,113 +102,103 @@ struct GwenParameters }; GwenParameterInterface::GwenParameterInterface(GwenInternalData* gwenInternalData) -:m_gwenInternalData(gwenInternalData) + : m_gwenInternalData(gwenInternalData) { m_paramInternalData = new GwenParameters; m_paramInternalData->m_savedYposition = m_gwenInternalData->m_curYposition; - } GwenParameterInterface::~GwenParameterInterface() { - removeAllParameters(); delete m_paramInternalData; } - void GwenParameterInterface::setSliderValue(int sliderIndex, double sliderValue) { - int sliderCapped = sliderValue+4; - sliderCapped /= 8; - sliderCapped *= 8; - - if (sliderIndex>=0 && sliderIndexm_sliders.size()) - { - m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin(); - - m_paramInternalData->m_sliders[sliderIndex]->GetRangeMax(); - float mappedValue =m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin()+ - (m_paramInternalData->m_sliders[sliderIndex]->GetRangeMax()- - m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin())*sliderCapped/128.f; - printf("mappedValue = %f\n",mappedValue); - m_paramInternalData->m_sliders[sliderIndex]->SetValue(mappedValue); - } + int sliderCapped = sliderValue + 4; + sliderCapped /= 8; + sliderCapped *= 8; + + if (sliderIndex >= 0 && sliderIndex < m_paramInternalData->m_sliders.size()) + { + m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin(); + + m_paramInternalData->m_sliders[sliderIndex]->GetRangeMax(); + float mappedValue = m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin() + + (m_paramInternalData->m_sliders[sliderIndex]->GetRangeMax() - + m_paramInternalData->m_sliders[sliderIndex]->GetRangeMin()) * + sliderCapped / 128.f; + printf("mappedValue = %f\n", mappedValue); + m_paramInternalData->m_sliders[sliderIndex]->SetValue(mappedValue); + } } #include void GwenParameterInterface::registerButtonParameter(ButtonParams& params) { - Gwen::Controls::Button* button = new Gwen::Controls::Button(m_gwenInternalData->m_demoPage->GetPage()); - MyButtonEventHandler* handler = new MyButtonEventHandler(button, params.m_callback,params.m_buttonId,params.m_userPointer); + MyButtonEventHandler* handler = new MyButtonEventHandler(button, params.m_callback, params.m_buttonId, params.m_userPointer); button->SetText(params.m_name); - button->onPress.Add( handler, &MyButtonEventHandler::onButtonPress ); - button->SetIsToggle(params.m_isTrigger); - button->SetToggleState(params.m_initialState); - + button->onPress.Add(handler, &MyButtonEventHandler::onButtonPress); + button->SetIsToggle(params.m_isTrigger); + button->SetToggleState(params.m_initialState); + m_paramInternalData->m_buttons.push_back(button); m_paramInternalData->m_buttonEventHandlers.push_back(handler); - button->SetPos( 5, m_gwenInternalData->m_curYposition ); + button->SetPos(5, m_gwenInternalData->m_curYposition); button->SetWidth(220); - - m_gwenInternalData->m_curYposition+=22; + m_gwenInternalData->m_curYposition += 22; } -struct MyComboBoxHander2 :public Gwen::Event::Handler +struct MyComboBoxHander2 : public Gwen::Event::Handler { - GwenInternalData* m_data; - int m_buttonId; - ComboBoxCallback m_callback; - void* m_userPointer; + GwenInternalData* m_data; + int m_buttonId; + ComboBoxCallback m_callback; + void* m_userPointer; - MyComboBoxHander2 (GwenInternalData* data, int buttonId,ComboBoxCallback callback, void* userPointer) - :m_data(data), - m_buttonId(buttonId), - m_callback(callback), - m_userPointer(userPointer) + MyComboBoxHander2(GwenInternalData* data, int buttonId, ComboBoxCallback callback, void* userPointer) + : m_data(data), + m_buttonId(buttonId), + m_callback(callback), + m_userPointer(userPointer) { } - void onSelect( Gwen::Controls::Base* pControl ) + void onSelect(Gwen::Controls::Base* pControl) { - Gwen::Controls::ComboBox* but = (Gwen::Controls::ComboBox*) pControl; + Gwen::Controls::ComboBox* but = (Gwen::Controls::ComboBox*)pControl; - Gwen::String str = Gwen::Utility::UnicodeToString( but->GetSelectedItem()->GetText()); + Gwen::String str = Gwen::Utility::UnicodeToString(but->GetSelectedItem()->GetText()); if (m_callback) - (*m_callback)(m_buttonId,str.c_str(),m_userPointer); + (*m_callback)(m_buttonId, str.c_str(), m_userPointer); } - }; - void GwenParameterInterface::registerComboBox(ComboBoxParams& params) { Gwen::Controls::ComboBox* combobox = new Gwen::Controls::ComboBox(m_gwenInternalData->m_demoPage->GetPage()); m_paramInternalData->m_comboBoxes.push_back(combobox); - MyComboBoxHander2* handler = new MyComboBoxHander2(m_gwenInternalData, params.m_comboboxId,params.m_callback, params.m_userPointer); + MyComboBoxHander2* handler = new MyComboBoxHander2(m_gwenInternalData, params.m_comboboxId, params.m_callback, params.m_userPointer); m_gwenInternalData->m_handlers.push_back(handler); - combobox->onSelection.Add(handler,&MyComboBoxHander2::onSelect); + combobox->onSelection.Add(handler, &MyComboBoxHander2::onSelect); int ypos = m_gwenInternalData->m_curYposition; - m_gwenInternalData->m_curYposition+=22; - combobox->SetPos(5, ypos ); - combobox->SetWidth( 220 ); + m_gwenInternalData->m_curYposition += 22; + combobox->SetPos(5, ypos); + combobox->SetWidth(220); //box->SetPos(120,130); - for (int i=0;iAddItem(Gwen::Utility::StringToUnicode(params.m_items[i])); - if (i==params.m_startItem) + if (i == params.m_startItem) combobox->OnItemSelected(item); } - - - - } void GwenParameterInterface::registerSliderFloatParameter(SliderParams& params) @@ -222,99 +206,94 @@ void GwenParameterInterface::registerSliderFloatParameter(SliderParams& params) Gwen::Controls::TextBox* label = new Gwen::Controls::TextBox(m_gwenInternalData->m_demoPage->GetPage()); m_paramInternalData->m_textLabels.push_back(label); //m_data->m_myControls.push_back(label); - label->SetText( params.m_name); - label->SetPos( 10, 10 + 25 ); + label->SetText(params.m_name); + label->SetPos(10, 10 + 25); label->SetWidth(210); - label->SetPos(10,m_gwenInternalData->m_curYposition); - m_gwenInternalData->m_curYposition+=22; + label->SetPos(10, m_gwenInternalData->m_curYposition); + m_gwenInternalData->m_curYposition += 22; - Gwen::Controls::HorizontalSlider* pSlider = new Gwen::Controls::HorizontalSlider( m_gwenInternalData->m_demoPage->GetPage()); + Gwen::Controls::HorizontalSlider* pSlider = new Gwen::Controls::HorizontalSlider(m_gwenInternalData->m_demoPage->GetPage()); m_paramInternalData->m_sliders.push_back(pSlider); //m_data->m_myControls.push_back(pSlider); - pSlider->SetPos( 10, m_gwenInternalData->m_curYposition ); - pSlider->SetSize( 200, 20 ); - pSlider->SetRange( params.m_minVal, params.m_maxVal); - if (params.m_clampToIntegers) - { - pSlider->SetNotchCount( int( params.m_maxVal - params.m_minVal ) ); - pSlider->SetClampToNotches( true ); - } - else - { - pSlider->SetNotchCount( 16 );//float(params.m_maxVal-params.m_minVal)/100.f); - pSlider->SetClampToNotches( params.m_clampToNotches ); - } - pSlider->SetValue( *params.m_paramValuePointer);//dimensions[i] ); + pSlider->SetPos(10, m_gwenInternalData->m_curYposition); + pSlider->SetSize(200, 20); + pSlider->SetRange(params.m_minVal, params.m_maxVal); + if (params.m_clampToIntegers) + { + pSlider->SetNotchCount(int(params.m_maxVal - params.m_minVal)); + pSlider->SetClampToNotches(true); + } + else + { + pSlider->SetNotchCount(16); //float(params.m_maxVal-params.m_minVal)/100.f); + pSlider->SetClampToNotches(params.m_clampToNotches); + } + pSlider->SetValue(*params.m_paramValuePointer); //dimensions[i] ); char labelName[1024]; - sprintf(labelName,"%s",params.m_name);//axisNames[0]); - MySliderEventHandler* handler = new MySliderEventHandler(labelName,label,pSlider,params.m_paramValuePointer,params.m_callback, params.m_userPointer); - handler->m_showValue = params.m_showValues; + sprintf(labelName, "%s", params.m_name); //axisNames[0]); + MySliderEventHandler* handler = new MySliderEventHandler(labelName, label, pSlider, params.m_paramValuePointer, params.m_callback, params.m_userPointer); + handler->m_showValue = params.m_showValues; m_paramInternalData->m_sliderEventHandlers.push_back(handler); - pSlider->onValueChanged.Add( handler, &MySliderEventHandler::SliderMoved ); + pSlider->onValueChanged.Add(handler, &MySliderEventHandler::SliderMoved); handler->SliderMoved(pSlider); -// float v = pSlider->GetValue(); - m_gwenInternalData->m_curYposition+=22; + // float v = pSlider->GetValue(); + m_gwenInternalData->m_curYposition += 22; } void GwenParameterInterface::syncParameters() { - for (int i=0;im_sliderEventHandlers.size();i++) + for (int i = 0; i < m_paramInternalData->m_sliderEventHandlers.size(); i++) { MySliderEventHandler* handler = m_paramInternalData->m_sliderEventHandlers[i]; - handler->m_pSlider->SetValue(*handler->m_targetValue,true); + handler->m_pSlider->SetValue(*handler->m_targetValue, true); } } void GwenParameterInterface::removeAllParameters() { - - for (int i=0;im_buttons.size();i++) + for (int i = 0; i < m_paramInternalData->m_buttons.size(); i++) { delete m_paramInternalData->m_buttons[i]; } m_paramInternalData->m_buttons.clear(); - - for (int i=0;im_buttonEventHandlers.size();i++) + + for (int i = 0; i < m_paramInternalData->m_buttonEventHandlers.size(); i++) { delete m_paramInternalData->m_buttonEventHandlers[i]; } m_paramInternalData->m_buttonEventHandlers.clear(); - - - m_gwenInternalData->m_curYposition+=22; - - for (int i=0;im_sliders.size();i++) + m_gwenInternalData->m_curYposition += 22; + + for (int i = 0; i < m_paramInternalData->m_sliders.size(); i++) { delete m_paramInternalData->m_sliders[i]; } m_paramInternalData->m_sliders.clear(); - for (int i=0;im_sliderEventHandlers.size();i++) + for (int i = 0; i < m_paramInternalData->m_sliderEventHandlers.size(); i++) { delete m_paramInternalData->m_sliderEventHandlers[i]; } m_paramInternalData->m_sliderEventHandlers.clear(); - - for (int i=0;im_textLabels.size();i++) + + for (int i = 0; i < m_paramInternalData->m_textLabels.size(); i++) { delete m_paramInternalData->m_textLabels[i]; } m_paramInternalData->m_textLabels.clear(); - - for (int i=0;im_comboBoxes.size();i++) + + for (int i = 0; i < m_paramInternalData->m_comboBoxes.size(); i++) { delete m_paramInternalData->m_comboBoxes[i]; } m_paramInternalData->m_comboBoxes.clear(); m_gwenInternalData->m_curYposition = this->m_paramInternalData->m_savedYposition; - for (int i=0;im_handlers.size();i++) + for (int i = 0; i < m_gwenInternalData->m_handlers.size(); i++) { delete m_gwenInternalData->m_handlers[i]; } m_gwenInternalData->m_handlers.clear(); - - } diff --git a/examples/ExampleBrowser/GwenGUISupport/GwenParameterInterface.h b/examples/ExampleBrowser/GwenGUISupport/GwenParameterInterface.h index 262b6e9fa..819090b4c 100644 --- a/examples/ExampleBrowser/GwenGUISupport/GwenParameterInterface.h +++ b/examples/ExampleBrowser/GwenGUISupport/GwenParameterInterface.h @@ -7,7 +7,7 @@ struct GwenParameterInterface : public CommonParameterInterface { struct GwenInternalData* m_gwenInternalData; - struct GwenParameters* m_paramInternalData; + struct GwenParameters* m_paramInternalData; GwenParameterInterface(struct GwenInternalData* gwenInternalData); virtual ~GwenParameterInterface(); @@ -15,12 +15,9 @@ struct GwenParameterInterface : public CommonParameterInterface virtual void registerButtonParameter(ButtonParams& params); virtual void registerComboBox(ComboBoxParams& params); - virtual void setSliderValue(int sliderIndex, double sliderValue); + virtual void setSliderValue(int sliderIndex, double sliderValue); virtual void syncParameters(); virtual void removeAllParameters(); - - - }; -#endif//GWEN_PARAMETER_INTERFACE_H +#endif //GWEN_PARAMETER_INTERFACE_H diff --git a/examples/ExampleBrowser/GwenGUISupport/GwenProfileWindow.cpp b/examples/ExampleBrowser/GwenGUISupport/GwenProfileWindow.cpp index 4cc6e63a6..f886a23fa 100644 --- a/examples/ExampleBrowser/GwenGUISupport/GwenProfileWindow.cpp +++ b/examples/ExampleBrowser/GwenGUISupport/GwenProfileWindow.cpp @@ -3,293 +3,258 @@ #include "gwenInternalData.h" #include "LinearMath/btQuickprof.h" - -#ifndef BT_NO_PROFILE - +#ifndef BT_NO_PROFILE class MyProfileWindow : public Gwen::Controls::WindowControl { - // Gwen::Controls::TabControl* m_TabControl; //Gwen::Controls::ListBox* m_TextOutput; - unsigned int m_iFrames; - float m_fLastSecond; - + unsigned int m_iFrames; + float m_fLastSecond; + Gwen::Controls::TreeNode* m_node; Gwen::Controls::TreeControl* m_ctrl; - - + protected: - - void onButtonA( Gwen::Controls::Base* pControl ) + void onButtonA(Gwen::Controls::Base* pControl) { - // OpenTissue::glut::toggleIdle(); + // OpenTissue::glut::toggleIdle(); } - - void SliderMoved(Gwen::Controls::Base* pControl ) + + void SliderMoved(Gwen::Controls::Base* pControl) { - // Gwen::Controls::Slider* pSlider = (Gwen::Controls::Slider*)pControl; + // Gwen::Controls::Slider* pSlider = (Gwen::Controls::Slider*)pControl; //this->m_app->scaleYoungModulus(pSlider->GetValue()); // printf("Slider Value: %.2f", pSlider->GetValue() ); } - - - void OnCheckChangedStiffnessWarping (Gwen::Controls::Base* pControl) + + void OnCheckChangedStiffnessWarping(Gwen::Controls::Base* pControl) { - // Gwen::Controls::CheckBox* labeled = (Gwen::Controls::CheckBox* )pControl; -// bool checked = labeled->IsChecked(); + // Gwen::Controls::CheckBox* labeled = (Gwen::Controls::CheckBox* )pControl; + // bool checked = labeled->IsChecked(); //m_app->m_stiffness_warp_on = checked; } + public: - - CProfileIterator* profIter; class MyMenuItems3* m_menuItems; - MyProfileWindow ( Gwen::Controls::Base* pParent) - : Gwen::Controls::WindowControl( pParent ), - profIter(0) + MyProfileWindow(Gwen::Controls::Base* pParent) + : Gwen::Controls::WindowControl(pParent), + profIter(0) { - SetTitle( L"Time Profiler" ); - - SetSize( 450, 450 ); - this->SetPos(10,400); - - // this->Dock( Gwen::Pos::Bottom); - - - + SetTitle(L"Time Profiler"); + + SetSize(450, 450); + this->SetPos(10, 400); + + // this->Dock( Gwen::Pos::Bottom); + { - m_ctrl = new Gwen::Controls::TreeControl( this ); - m_node = m_ctrl->AddNode( L"Total Parent Time" ); - - + m_ctrl = new Gwen::Controls::TreeControl(this); + m_node = m_ctrl->AddNode(L"Total Parent Time"); + //Gwen::Controls::TreeNode* pNode = ctrl->AddNode( L"Node Two" ); //pNode->AddNode( L"Node Two Inside" ); //pNode->AddNode( L"Eyes" ); //pNode->AddNode( L"Brown" )->AddNode( L"Node Two Inside" )->AddNode( L"Eyes" )->AddNode( L"Brown" ); //Gwen::Controls::TreeNode* node = ctrl->AddNode( L"Node Three" ); - - - + //m_ctrl->Dock(Gwen::Pos::Bottom); - + m_ctrl->ExpandAll(); - m_ctrl->SetKeyboardInputEnabled(true); - m_ctrl->SetBounds( this->GetInnerBounds().x,this->GetInnerBounds().y,this->GetInnerBounds().w,this->GetInnerBounds().h); - + m_ctrl->SetKeyboardInputEnabled(true); + m_ctrl->SetBounds(this->GetInnerBounds().x, this->GetInnerBounds().y, this->GetInnerBounds().w, this->GetInnerBounds().h); } - - - } - + virtual ~MyProfileWindow() { - delete m_node; delete m_ctrl; } - - float dumpRecursive(CProfileIterator* profileIterator, Gwen::Controls::TreeNode* parentNode) + + float dumpRecursive(CProfileIterator* profileIterator, Gwen::Controls::TreeNode* parentNode) { profileIterator->First(); if (profileIterator->Is_Done()) return 0.f; - - float accumulated_time=0,parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time(); + + float accumulated_time = 0, parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time(); int i; int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset(); - if (0==frames_since_reset) + if (0 == frames_since_reset) return 0.f; - + //printf("Profiling: %s (total running time: %.3f ms) ---\n", profileIterator->Get_Current_Parent_Name(), parent_time ); float totalTime = 0.f; - - + int numChildren = 0; Gwen::UnicodeString txt; std::vector nodes; - - for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next()) + + for (i = 0; !profileIterator->Is_Done(); i++, profileIterator->Next()) { numChildren++; float current_total_time = profileIterator->Get_Current_Total_Time(); accumulated_time += current_total_time; double fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f; - + Gwen::String name(profileIterator->Get_Current_Name()); #ifdef _WIN32 Gwen::UnicodeString uname = Gwen::Utility::StringToUnicode(name); - - txt = Gwen::Utility::Format(L"%s (%.2f %%) :: %.3f ms / frame (%d calls)",uname.c_str(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls()); - + + txt = Gwen::Utility::Format(L"%s (%.2f %%) :: %.3f ms / frame (%d calls)", uname.c_str(), fraction, (current_total_time / (double)frames_since_reset), profileIterator->Get_Current_Total_Calls()); + #else - txt = Gwen::Utility::Format(L"%s (%.2f %%) :: %.3f ms / frame (%d calls)",name.c_str(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls()); - + txt = Gwen::Utility::Format(L"%s (%.2f %%) :: %.3f ms / frame (%d calls)", name.c_str(), fraction, (current_total_time / (double)frames_since_reset), profileIterator->Get_Current_Total_Calls()); + #endif - + Gwen::Controls::TreeNode* childNode = (Gwen::Controls::TreeNode*)profileIterator->Get_Current_UserPointer(); if (!childNode) { - childNode = parentNode->AddNode(L""); - profileIterator->Set_Current_UserPointer(childNode); + childNode = parentNode->AddNode(L""); + profileIterator->Set_Current_UserPointer(childNode); } childNode->SetText(txt); nodes.push_back(childNode); - + totalTime += current_total_time; //recurse into children } - - for (i=0;iEnter_Child(i); Gwen::Controls::TreeNode* curNode = nodes[i]; - + dumpRecursive(profileIterator, curNode); - + profileIterator->Enter_Parent(); } return accumulated_time; - } - - void UpdateText(CProfileIterator* profileIterator, bool idle) + + void UpdateText(CProfileIterator* profileIterator, bool idle) { - - // static bool update=true; - - m_ctrl->SetBounds(0,0,this->GetInnerBounds().w,this->GetInnerBounds().h); - - // if (!update) - // return; - // update=false; - - + // static bool update=true; + + m_ctrl->SetBounds(0, 0, this->GetInnerBounds().w, this->GetInnerBounds().h); + + // if (!update) + // return; + // update=false; + static int test = 1; test++; - + static double time_since_reset = 0.f; if (!idle) { time_since_reset = CProfileManager::Get_Time_Since_Reset(); } - + //Gwen::UnicodeString txt = Gwen::Utility::Format( L"FEM Settings %i fps", test ); { - //recompute profiling data, and store profile strings - - // char blockTime[128]; - - // double totalTime = 0; - - // int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset(); - - profileIterator->First(); - - double parent_time = profileIterator->Is_Root() ? time_since_reset : profileIterator->Get_Current_Parent_Total_Time(); - - - // Gwen::Controls::TreeNode* curParent = m_node; + //recompute profiling data, and store profile strings + // char blockTime[128]; - double accumulated_time = dumpRecursive(profileIterator,m_node); - - const char* name = profileIterator->Get_Current_Parent_Name(); + // double totalTime = 0; + + // int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset(); + + profileIterator->First(); + + double parent_time = profileIterator->Is_Root() ? time_since_reset : profileIterator->Get_Current_Parent_Total_Time(); + + // Gwen::Controls::TreeNode* curParent = m_node; + + double accumulated_time = dumpRecursive(profileIterator, m_node); + + const char* name = profileIterator->Get_Current_Parent_Name(); #ifdef _WIN32 - Gwen::UnicodeString uname = Gwen::Utility::StringToUnicode(name); - Gwen::UnicodeString txt = Gwen::Utility::Format( L"Profiling: %s total time: %.3f ms, unaccounted %.3f %% :: %.3f ms", uname.c_str(), parent_time , - parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time); + Gwen::UnicodeString uname = Gwen::Utility::StringToUnicode(name); + Gwen::UnicodeString txt = Gwen::Utility::Format(L"Profiling: %s total time: %.3f ms, unaccounted %.3f %% :: %.3f ms", uname.c_str(), parent_time, + parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time); #else - Gwen::UnicodeString txt = Gwen::Utility::Format( L"Profiling: %s total time: %.3f ms, unaccounted %.3f %% :: %.3f ms", name, parent_time , - parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time); + Gwen::UnicodeString txt = Gwen::Utility::Format(L"Profiling: %s total time: %.3f ms, unaccounted %.3f %% :: %.3f ms", name, parent_time, + parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time); #endif - //sprintf(blockTime,"--- Profiling: %s (total running time: %.3f ms) ---", profileIterator->Get_Current_Parent_Name(), parent_time ); - //displayProfileString(xOffset,yStart,blockTime); - m_node->SetText(txt); - - + //sprintf(blockTime,"--- Profiling: %s (total running time: %.3f ms) ---", profileIterator->Get_Current_Parent_Name(), parent_time ); + //displayProfileString(xOffset,yStart,blockTime); + m_node->SetText(txt); + //printf("%s (%.3f %%) :: %.3f ms\n", "Unaccounted:",); - - } - - static int counter=10; + + static int counter = 10; if (counter) { - counter--; + counter--; m_ctrl->ExpandAll(); } - } - void PrintText( const Gwen::UnicodeString& str ) + void PrintText(const Gwen::UnicodeString& str) { - } - - void Render( Gwen::Skin::Base* skin ) + + void Render(Gwen::Skin::Base* skin) { m_iFrames++; - - if ( m_fLastSecond < Gwen::Platform::GetTimeInSeconds() ) + + if (m_fLastSecond < Gwen::Platform::GetTimeInSeconds()) { - SetTitle( Gwen::Utility::Format( L"Profiler %i fps", m_iFrames ) ); - + SetTitle(Gwen::Utility::Format(L"Profiler %i fps", m_iFrames)); + m_fLastSecond = Gwen::Platform::GetTimeInSeconds() + 1.0f; m_iFrames = 0; } - - Gwen::Controls::WindowControl::Render( skin ); - + + Gwen::Controls::WindowControl::Render(skin); } - - }; -class MyMenuItems3 : public Gwen::Controls::Base +class MyMenuItems3 : public Gwen::Controls::Base { - public: - class MyProfileWindow* m_profWindow; - MyMenuItems3() :Gwen::Controls::Base(0) - { - } - virtual ~MyMenuItems3() {} - - void MenuItemSelect(Gwen::Controls::Base* pControl) - { + MyMenuItems3() : Gwen::Controls::Base(0) + { + } + virtual ~MyMenuItems3() {} + + void MenuItemSelect(Gwen::Controls::Base* pControl) + { if (m_profWindow->Hidden()) { m_profWindow->SetHidden(false); - } else + } + else { m_profWindow->SetHidden(true); } - - } + } }; - MyProfileWindow* setupProfileWindow(GwenInternalData* data) { MyMenuItems3* menuItems = new MyMenuItems3; - + MyProfileWindow* profWindow = new MyProfileWindow(data->pCanvas); - //profWindow->SetHidden(true); - + //profWindow->SetHidden(true); + profWindow->m_menuItems = menuItems; profWindow->profIter = CProfileManager::Get_Iterator(); - data->m_viewMenu->GetMenu()->AddItem( L"Profiler", menuItems,(Gwen::Event::Handler::Function)&MyMenuItems3::MenuItemSelect); - + data->m_viewMenu->GetMenu()->AddItem(L"Profiler", menuItems, (Gwen::Event::Handler::Function)&MyMenuItems3::MenuItemSelect); + menuItems->m_profWindow = profWindow; - + return profWindow; } - -void processProfileData( MyProfileWindow* profWindow, bool idle) +void processProfileData(MyProfileWindow* profWindow, bool idle) { if (profWindow) { @@ -297,7 +262,7 @@ void processProfileData( MyProfileWindow* profWindow, bool idle) { profWindow->UpdateText(profWindow->profIter, idle); } - } + } } bool isProfileWindowVisible(MyProfileWindow* window) @@ -315,7 +280,6 @@ void destroyProfileWindow(MyProfileWindow* window) delete window->m_menuItems; delete window; CProfileManager::CleanupMemory(); - } -#endif //BT_NO_PROFILE +#endif //BT_NO_PROFILE diff --git a/examples/ExampleBrowser/GwenGUISupport/GwenProfileWindow.h b/examples/ExampleBrowser/GwenGUISupport/GwenProfileWindow.h index fc0ba2982..fbe69e819 100644 --- a/examples/ExampleBrowser/GwenGUISupport/GwenProfileWindow.h +++ b/examples/ExampleBrowser/GwenGUISupport/GwenProfileWindow.h @@ -8,6 +8,4 @@ bool isProfileWindowVisible(MyProfileWindow* window); void destroyProfileWindow(MyProfileWindow* window); -#endif//GWEN_PROFILE_WINDOW_H - - +#endif //GWEN_PROFILE_WINDOW_H diff --git a/examples/ExampleBrowser/GwenGUISupport/GwenTextureWindow.cpp b/examples/ExampleBrowser/GwenGUISupport/GwenTextureWindow.cpp index 477553f25..0e0a2c732 100644 --- a/examples/ExampleBrowser/GwenGUISupport/GwenTextureWindow.cpp +++ b/examples/ExampleBrowser/GwenGUISupport/GwenTextureWindow.cpp @@ -3,79 +3,70 @@ #include "gwenInternalData.h" #include "Gwen/Controls/ImagePanel.h" - - class MyGraphWindow : public Gwen::Controls::WindowControl { Gwen::Controls::ImagePanel* m_imgPanel; public: - class MyMenuItems2* m_menuItems; - - MyGraphWindow ( const MyGraphInput& input) - : Gwen::Controls::WindowControl( input.m_data->pCanvas ), - m_menuItems(0) + + MyGraphWindow(const MyGraphInput& input) + : Gwen::Controls::WindowControl(input.m_data->pCanvas), + m_menuItems(0) { Gwen::UnicodeString str = Gwen::Utility::StringToUnicode(input.m_name); - SetTitle( str ); + SetTitle(str); + SetPos(input.m_xPos, input.m_yPos); + SetSize(12 + input.m_width + 2 * input.m_borderWidth, 30 + input.m_height + 2 * input.m_borderWidth); - SetPos(input.m_xPos,input.m_yPos); - SetSize( 12+input.m_width+2*input.m_borderWidth, 30+input.m_height+2*input.m_borderWidth ); - - m_imgPanel = new Gwen::Controls::ImagePanel( this ); + m_imgPanel = new Gwen::Controls::ImagePanel(this); if (input.m_texName) { Gwen::UnicodeString texName = Gwen::Utility::StringToUnicode(input.m_texName); - m_imgPanel->SetImage( texName ); + m_imgPanel->SetImage(texName); } - m_imgPanel->SetBounds( input.m_borderWidth, input.m_borderWidth, - input.m_width, - input.m_height ); - // this->Dock( Gwen::Pos::Bottom); + m_imgPanel->SetBounds(input.m_borderWidth, input.m_borderWidth, + input.m_width, + input.m_height); + // this->Dock( Gwen::Pos::Bottom); } virtual ~MyGraphWindow() { delete m_imgPanel; } - - }; -class MyMenuItems2 : public Gwen::Controls::Base +class MyMenuItems2 : public Gwen::Controls::Base { MyGraphWindow* m_graphWindow; - + public: - Gwen::Controls::MenuItem* m_item; - - MyMenuItems2(MyGraphWindow* graphWindow) - :Gwen::Controls::Base(0), - m_graphWindow(graphWindow), - m_item(0) - { - } - - void MenuItemSelect(Gwen::Controls::Base* pControl) - { + + MyMenuItems2(MyGraphWindow* graphWindow) + : Gwen::Controls::Base(0), + m_graphWindow(graphWindow), + m_item(0) + { + } + + void MenuItemSelect(Gwen::Controls::Base* pControl) + { if (m_graphWindow->Hidden()) { m_graphWindow->SetHidden(false); //@TODO(erwincoumans) setCheck/SetCheckable drawing is broken, need to see what's wrong -// if (m_item) -// m_item->SetCheck(false); - - } else + // if (m_item) + // m_item->SetCheck(false); + } + else { m_graphWindow->SetHidden(true); -// if (m_item) -// m_item->SetCheck(true); - + // if (m_item) + // m_item->SetCheck(true); } - - } + } }; MyGraphWindow* setupTextureWindow(const MyGraphInput& input) @@ -83,13 +74,12 @@ MyGraphWindow* setupTextureWindow(const MyGraphInput& input) MyGraphWindow* graphWindow = new MyGraphWindow(input); MyMenuItems2* menuItems = new MyMenuItems2(graphWindow); graphWindow->m_menuItems = menuItems; - + Gwen::UnicodeString str = Gwen::Utility::StringToUnicode(input.m_name); - menuItems->m_item = input.m_data->m_viewMenu->GetMenu()->AddItem( str, menuItems,(Gwen::Event::Handler::Function)&MyMenuItems2::MenuItemSelect); -// menuItems->m_item->SetCheckable(true); + menuItems->m_item = input.m_data->m_viewMenu->GetMenu()->AddItem(str, menuItems, (Gwen::Event::Handler::Function)&MyMenuItems2::MenuItemSelect); + // menuItems->m_item->SetCheckable(true); return graphWindow; - } void destroyTextureWindow(MyGraphWindow* window) diff --git a/examples/ExampleBrowser/GwenGUISupport/GwenTextureWindow.h b/examples/ExampleBrowser/GwenGUISupport/GwenTextureWindow.h index da06dc55b..85866b1d5 100644 --- a/examples/ExampleBrowser/GwenGUISupport/GwenTextureWindow.h +++ b/examples/ExampleBrowser/GwenGUISupport/GwenTextureWindow.h @@ -14,19 +14,18 @@ struct MyGraphInput const char* m_name; const char* m_texName; MyGraphInput(struct GwenInternalData* data) - :m_data(data), - m_xPos(0), - m_yPos(0), - m_width(400), - m_height(400), - m_borderWidth(0), - m_name("GraphWindow"), - m_texName(0) + : m_data(data), + m_xPos(0), + m_yPos(0), + m_width(400), + m_height(400), + m_borderWidth(0), + m_name("GraphWindow"), + m_texName(0) { } }; class MyGraphWindow* setupTextureWindow(const MyGraphInput& input); void destroyTextureWindow(MyGraphWindow* window); - -#endif //GWEN_TEXTURE_WINDOW_H +#endif //GWEN_TEXTURE_WINDOW_H diff --git a/examples/ExampleBrowser/GwenGUISupport/gwenInternalData.h b/examples/ExampleBrowser/GwenGUISupport/gwenInternalData.h index 3fc3bb4b4..6ce62fc15 100644 --- a/examples/ExampleBrowser/GwenGUISupport/gwenInternalData.h +++ b/examples/ExampleBrowser/GwenGUISupport/gwenInternalData.h @@ -28,37 +28,34 @@ //#include "Gwen/Skins/TexturedBase.h" #include "gwenUserInterface.h" - struct GwenInternalData { //struct sth_stash; //class GwenOpenGL3CoreRenderer* pRenderer; - Gwen::Renderer::Base* pRenderer; - Gwen::Skin::Simple skin; - Gwen::Controls::Canvas* pCanvas; + Gwen::Renderer::Base* pRenderer; + Gwen::Skin::Simple skin; + Gwen::Controls::Canvas* pCanvas; //GLPrimitiveRenderer* m_primRenderer; - Gwen::Controls::TabButton* m_demoPage; - Gwen::Controls::TabButton* m_explorerPage; - Gwen::Controls::TreeControl* m_explorerTreeCtrl; - Gwen::Controls::MenuItem* m_viewMenu; - class MyMenuItems* m_menuItems; - Gwen::Controls::ListBox* m_TextOutput; - Gwen::Controls::Label* m_exampleInfoGroupBox; - Gwen::Controls::ListBox* m_exampleInfoTextOutput; - struct MyTestMenuBar* m_menubar; + Gwen::Controls::TabButton* m_demoPage; + Gwen::Controls::TabButton* m_explorerPage; + Gwen::Controls::TreeControl* m_explorerTreeCtrl; + Gwen::Controls::MenuItem* m_viewMenu; + class MyMenuItems* m_menuItems; + Gwen::Controls::ListBox* m_TextOutput; + Gwen::Controls::Label* m_exampleInfoGroupBox; + Gwen::Controls::ListBox* m_exampleInfoTextOutput; + struct MyTestMenuBar* m_menubar; Gwen::Controls::StatusBar* m_bar; Gwen::Controls::ScrollControl* m_windowRight; Gwen::Controls::TabControl* m_tab; - int m_curYposition; + int m_curYposition; Gwen::Controls::Label* m_rightStatusBar; Gwen::Controls::Label* m_leftStatusBar; - b3AlignedObjectArray m_handlers; - b3ToggleButtonCallback m_toggleButtonCallback; - b3ComboBoxCallback m_comboBoxCallback; - - + b3AlignedObjectArray m_handlers; + b3ToggleButtonCallback m_toggleButtonCallback; + b3ComboBoxCallback m_comboBoxCallback; }; -#endif//GWEN_INTERNAL_DATA_H +#endif //GWEN_INTERNAL_DATA_H diff --git a/examples/ExampleBrowser/GwenGUISupport/gwenUserInterface.cpp b/examples/ExampleBrowser/GwenGUISupport/gwenUserInterface.cpp index fcff13968..3b8bde1f1 100644 --- a/examples/ExampleBrowser/GwenGUISupport/gwenUserInterface.cpp +++ b/examples/ExampleBrowser/GwenGUISupport/gwenUserInterface.cpp @@ -7,24 +7,20 @@ class MyGraphWindow* graphWindow = 0; - - GwenUserInterface::GwenUserInterface() { m_data = new GwenInternalData(); m_data->m_toggleButtonCallback = 0; m_data->m_comboBoxCallback = 0; - } class MyMenuItems : public Gwen::Controls::Base { public: - b3FileOpenCallback m_fileOpenCallback; b3QuitCallback m_quitCallback; - MyMenuItems() :Gwen::Controls::Base(0), m_fileOpenCallback(0) + MyMenuItems() : Gwen::Controls::Base(0), m_fileOpenCallback(0) { } void myQuitApp(Gwen::Controls::Base* pControl) @@ -41,20 +37,16 @@ public: (*m_fileOpenCallback)(); } } - }; - - struct MyTestMenuBar : public Gwen::Controls::MenuStrip { - Gwen::Controls::MenuItem* m_fileMenu; Gwen::Controls::MenuItem* m_viewMenu; - MyMenuItems* m_menuItems; + MyMenuItems* m_menuItems; MyTestMenuBar(Gwen::Controls::Base* pParent) - :Gwen::Controls::MenuStrip(pParent) + : Gwen::Controls::MenuStrip(pParent) { // Gwen::Controls::MenuStrip* menu = new Gwen::Controls::MenuStrip( pParent ); { @@ -67,18 +59,15 @@ struct MyTestMenuBar : public Gwen::Controls::MenuStrip m_fileMenu->GetMenu()->AddItem(L"Open", m_menuItems, (Gwen::Event::Handler::Function)&MyMenuItems::fileOpen); m_fileMenu->GetMenu()->AddItem(L"Quit", m_menuItems, (Gwen::Event::Handler::Function)&MyMenuItems::myQuitApp); m_viewMenu = AddItem(L"View"); - } } virtual ~MyTestMenuBar() { delete m_menuItems; } - }; - -void GwenUserInterface::exit() +void GwenUserInterface::exit() { //m_data->m_menubar->RemoveAllChildren(); delete m_data->m_tab; @@ -88,7 +77,7 @@ void GwenUserInterface::exit() delete m_data->m_rightStatusBar; delete m_data->m_bar; delete m_data->m_menubar; - + m_data->m_menubar = 0; delete m_data->pCanvas; m_data->pCanvas = 0; @@ -96,262 +85,226 @@ void GwenUserInterface::exit() GwenUserInterface::~GwenUserInterface() { - for (int i=0;im_handlers.size();i++) + for (int i = 0; i < m_data->m_handlers.size(); i++) { delete m_data->m_handlers[i]; } m_data->m_handlers.clear(); - delete m_data; - } - - - - - -void GwenUserInterface::resize(int width, int height) +void GwenUserInterface::resize(int width, int height) { - m_data->pCanvas->SetSize(width,height); + m_data->pCanvas->SetSize(width, height); } - -struct MyComboBoxHander :public Gwen::Event::Handler +struct MyComboBoxHander : public Gwen::Event::Handler { - GwenInternalData* m_data; - int m_buttonId; + GwenInternalData* m_data; + int m_buttonId; - MyComboBoxHander (GwenInternalData* data, int buttonId) - :m_data(data), - m_buttonId(buttonId) + MyComboBoxHander(GwenInternalData* data, int buttonId) + : m_data(data), + m_buttonId(buttonId) { } - void onSelect( Gwen::Controls::Base* pControl ) + void onSelect(Gwen::Controls::Base* pControl) { - Gwen::Controls::ComboBox* but = (Gwen::Controls::ComboBox*) pControl; + Gwen::Controls::ComboBox* but = (Gwen::Controls::ComboBox*)pControl; - - - Gwen::String str = Gwen::Utility::UnicodeToString( but->GetSelectedItem()->GetText()); + Gwen::String str = Gwen::Utility::UnicodeToString(but->GetSelectedItem()->GetText()); if (m_data->m_comboBoxCallback) - (*m_data->m_comboBoxCallback)(m_buttonId,str.c_str()); + (*m_data->m_comboBoxCallback)(m_buttonId, str.c_str()); } - }; -struct MyButtonHander :public Gwen::Event::Handler +struct MyButtonHander : public Gwen::Event::Handler { - GwenInternalData* m_data; - int m_buttonId; + GwenInternalData* m_data; + int m_buttonId; - MyButtonHander (GwenInternalData* data, int buttonId) - :m_data(data), - m_buttonId(buttonId) + MyButtonHander(GwenInternalData* data, int buttonId) + : m_data(data), + m_buttonId(buttonId) { } - void onButtonA( Gwen::Controls::Base* pControl ) + void onButtonA(Gwen::Controls::Base* pControl) { - Gwen::Controls::Button* but = (Gwen::Controls::Button*) pControl; -// int dep = but->IsDepressed(); + Gwen::Controls::Button* but = (Gwen::Controls::Button*)pControl; + // int dep = but->IsDepressed(); int tog = but->GetToggleState(); if (m_data->m_toggleButtonCallback) - (*m_data->m_toggleButtonCallback)(m_buttonId,tog); + (*m_data->m_toggleButtonCallback)(m_buttonId, tog); } - }; - -void GwenUserInterface::textOutput(const char* message) +void GwenUserInterface::textOutput(const char* message) { Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(message); - m_data->m_TextOutput->AddItem( msg ); + m_data->m_TextOutput->AddItem(msg); m_data->m_TextOutput->Scroller()->ScrollToBottom(); } - -void GwenUserInterface::setExampleDescription(const char* message) +void GwenUserInterface::setExampleDescription(const char* message) { //Gwen apparently doesn't have text/word wrap, so do rudimentary brute-force implementation here. - - std::string wrapmessage=message; + + std::string wrapmessage = message; int startPos = 0; - + std::string lastFit = ""; bool hasSpace = false; std::string lastFitSpace = ""; int spacePos = 0; m_data->m_exampleInfoTextOutput->Clear(); - int fixedWidth = m_data->m_exampleInfoTextOutput->GetBounds().w-25; + int fixedWidth = m_data->m_exampleInfoTextOutput->GetBounds().w - 25; int wrapLen = int(wrapmessage.length()); - for (int endPos=0;endPos<=wrapLen;endPos++) + for (int endPos = 0; endPos <= wrapLen; endPos++) { - std::string sub = wrapmessage.substr(startPos,(endPos-startPos)); - Gwen::Point pt = m_data->pRenderer->MeasureText(m_data->pCanvas->GetSkin()->GetDefaultFont(),sub); - + std::string sub = wrapmessage.substr(startPos, (endPos - startPos)); + Gwen::Point pt = m_data->pRenderer->MeasureText(m_data->pCanvas->GetSkin()->GetDefaultFont(), sub); + if (pt.x <= fixedWidth) { lastFit = sub; - if (message[endPos]==' ' ||message[endPos]=='.' || message[endPos]==',' ) + if (message[endPos] == ' ' || message[endPos] == '.' || message[endPos] == ',') { hasSpace = true; lastFitSpace = sub; spacePos = endPos; } - } else + } + else { - //submit and + //submit and if (hasSpace) { - endPos = spacePos+1; + endPos = spacePos + 1; hasSpace = false; lastFit = lastFitSpace; startPos = endPos; - } else + } + else { - startPos = endPos-1; + startPos = endPos - 1; } Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(lastFit); - - m_data->m_exampleInfoTextOutput->AddItem( msg ); + + m_data->m_exampleInfoTextOutput->AddItem(msg); m_data->m_exampleInfoTextOutput->Scroller()->ScrollToBottom(); - } } - + if (lastFit.length()) { Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(lastFit); - m_data->m_exampleInfoTextOutput->AddItem( msg ); + m_data->m_exampleInfoTextOutput->AddItem(msg); m_data->m_exampleInfoTextOutput->Scroller()->ScrollToBottom(); - } - } - - - -void GwenUserInterface::setStatusBarMessage(const char* message, bool isLeft) +void GwenUserInterface::setStatusBarMessage(const char* message, bool isLeft) { Gwen::UnicodeString msg = Gwen::Utility::StringToUnicode(message); if (isLeft) { - m_data->m_leftStatusBar->SetText( msg); - } else + m_data->m_leftStatusBar->SetText(msg); + } + else { - m_data->m_rightStatusBar->SetText( msg); - + m_data->m_rightStatusBar->SetText(msg); } } - void GwenUserInterface::registerFileOpenCallback(b3FileOpenCallback callback) { - m_data->m_menuItems->m_fileOpenCallback = callback; + m_data->m_menuItems->m_fileOpenCallback = callback; } void GwenUserInterface::registerQuitCallback(b3QuitCallback callback) { - m_data->m_menuItems->m_quitCallback = callback; + m_data->m_menuItems->m_quitCallback = callback; } -void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* renderer,float retinaScale) +void GwenUserInterface::init(int width, int height, Gwen::Renderer::Base* renderer, float retinaScale) { m_data->m_curYposition = 20; //m_data->m_primRenderer = new GLPrimitiveRenderer(width,height); - m_data->pRenderer = renderer;//new GwenOpenGL3CoreRenderer(m_data->m_primRenderer,stash,width,height,retinaScale); + m_data->pRenderer = renderer; //new GwenOpenGL3CoreRenderer(m_data->m_primRenderer,stash,width,height,retinaScale); - m_data->skin.SetRender( m_data->pRenderer ); - + m_data->skin.SetRender(m_data->pRenderer); + + m_data->pCanvas = new Gwen::Controls::Canvas(&m_data->skin); + m_data->pCanvas->SetSize(width, height); + m_data->pCanvas->SetDrawBackground(false); + m_data->pCanvas->SetBackgroundColor(Gwen::Color(150, 170, 170, 255)); - m_data->pCanvas= new Gwen::Controls::Canvas( &m_data->skin ); - m_data->pCanvas->SetSize( width,height); - m_data->pCanvas->SetDrawBackground( false); - m_data->pCanvas->SetBackgroundColor( Gwen::Color( 150, 170, 170, 255 ) ); - - - MyTestMenuBar* menubar = new MyTestMenuBar(m_data->pCanvas); m_data->m_viewMenu = menubar->m_viewMenu; - m_data->m_menuItems = menubar->m_menuItems; + m_data->m_menuItems = menubar->m_menuItems; m_data->m_menubar = menubar; - - - + Gwen::Controls::StatusBar* bar = new Gwen::Controls::StatusBar(m_data->pCanvas); m_data->m_bar = bar; - - m_data->m_rightStatusBar = new Gwen::Controls::Label( bar ); - - m_data->m_rightStatusBar->SetWidth(width/2); + m_data->m_rightStatusBar = new Gwen::Controls::Label(bar); + + m_data->m_rightStatusBar->SetWidth(width / 2); //m_data->m_rightStatusBar->SetText( L"Label Added to Right" ); - bar->AddControl( m_data->m_rightStatusBar, true ); - - m_data->m_TextOutput = new Gwen::Controls::ListBox( m_data->pCanvas ); - - m_data->m_TextOutput->Dock( Gwen::Pos::Bottom ); - m_data->m_TextOutput->SetHeight( 100 ); - - m_data->m_leftStatusBar = new Gwen::Controls::Label( bar ); - + bar->AddControl(m_data->m_rightStatusBar, true); + + m_data->m_TextOutput = new Gwen::Controls::ListBox(m_data->pCanvas); + + m_data->m_TextOutput->Dock(Gwen::Pos::Bottom); + m_data->m_TextOutput->SetHeight(100); + + m_data->m_leftStatusBar = new Gwen::Controls::Label(bar); + //m_data->m_leftStatusBar->SetText( L"Label Added to Left" ); - m_data->m_leftStatusBar->SetWidth(width/2); - bar->AddControl( m_data->m_leftStatusBar,false); - + m_data->m_leftStatusBar->SetWidth(width / 2); + bar->AddControl(m_data->m_leftStatusBar, false); + //Gwen::KeyboardFocus /*Gwen::Controls::GroupBox* box = new Gwen::Controls::GroupBox(m_data->pCanvas); box->SetText("text"); box->SetName("name"); box->SetHeight(500); */ - Gwen::Controls::ScrollControl* windowRight= new Gwen::Controls::ScrollControl(m_data->pCanvas); + Gwen::Controls::ScrollControl* windowRight = new Gwen::Controls::ScrollControl(m_data->pCanvas); windowRight->Dock(Gwen::Pos::Right); windowRight->SetWidth(250); windowRight->SetHeight(250); - windowRight->SetScroll(false,true); + windowRight->SetScroll(false, true); m_data->m_windowRight = windowRight; - //windowLeft->SetSkin( Gwen::Controls::TabControl* tab = new Gwen::Controls::TabControl(windowRight); m_data->m_tab = tab; - - //tab->SetHeight(300); tab->SetWidth(240); tab->SetHeight(1250); //tab->Dock(Gwen::Pos::Left); - tab->Dock( Gwen::Pos::Fill ); + tab->Dock(Gwen::Pos::Fill); //tab->SetMargin( Gwen::Margin( 2, 2, 2, 2 ) ); Gwen::UnicodeString str1(L"Params"); m_data->m_demoPage = tab->AddPage(str1); - - - - -// Gwen::UnicodeString str2(L"OpenCL"); -// tab->AddPage(str2); + // Gwen::UnicodeString str2(L"OpenCL"); + // tab->AddPage(str2); //Gwen::UnicodeString str3(L"page3"); -// tab->AddPage(str3); - - + // tab->AddPage(str3); //but->onPress.Add(handler, &MyHander::onButtonA); - - //box->Dock(Gwen::Pos::Left); /*Gwen::Controls::WindowControl* windowBottom = new Gwen::Controls::WindowControl(m_data->pCanvas); @@ -359,7 +312,7 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere windowBottom->Dock(Gwen::Pos::Bottom); windowBottom->SetTitle("bottom"); */ -// Gwen::Controls::Property::Text* prop = new Gwen::Controls::Property::Text(m_data->pCanvas); + // Gwen::Controls::Property::Text* prop = new Gwen::Controls::Property::Text(m_data->pCanvas); //prop->Dock(Gwen::Pos::Bottom); /*Gwen::Controls::SplitterBar* split = new Gwen::Controls::SplitterBar(m_data->pCanvas); split->Dock(Gwen::Pos::Center); @@ -381,19 +334,15 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere //windowLeft->SetClosable(false); // windowLeft->SetShouldDrawBackground(true); windowLeft->SetTabable(true); - + Gwen::Controls::TabControl* explorerTab = new Gwen::Controls::TabControl(windowLeft); //tab->SetHeight(300); -// explorerTab->SetWidth(230); + // explorerTab->SetWidth(230); explorerTab->SetHeight(250); //tab->Dock(Gwen::Pos::Left); explorerTab->Dock(Gwen::Pos::Fill); - - - - //m_data->m_exampleInfoTextOutput->SetBounds(2, 10, 236, 400); //windowRight @@ -407,16 +356,16 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere //Gwen::Controls::HSVColorPicker* color = new Gwen::Controls::HSVColorPicker(shapes->GetPage()); Gwen::Controls::ColorPicker* color = new Gwen::Controls::ColorPicker(shapes->GetPage()); color->SetKeyboardInputEnabled(true); - + Gwen::Controls::TreeControl* ctrl = new Gwen::Controls::TreeControl(m_data->m_explorerPage->GetPage()); m_data->m_explorerTreeCtrl = ctrl; ctrl->SetKeyboardInputEnabled(true); ctrl->Focus(); ctrl->SetBounds(2, 10, 236, 300); - m_data->m_exampleInfoGroupBox = new Gwen::Controls::Label( m_data->m_explorerPage->GetPage() ); + m_data->m_exampleInfoGroupBox = new Gwen::Controls::Label(m_data->m_explorerPage->GetPage()); m_data->m_exampleInfoGroupBox->SetPos(2, 314); - m_data->m_exampleInfoGroupBox->SetHeight( 15 ); + m_data->m_exampleInfoGroupBox->SetHeight(15); m_data->m_exampleInfoGroupBox->SetWidth(234); m_data->m_exampleInfoGroupBox->SetText("Example Description"); @@ -424,14 +373,11 @@ void GwenUserInterface::init(int width, int height,Gwen::Renderer::Base* rendere //m_data->m_exampleInfoTextOutput->Dock( Gwen::Pos::Bottom ); m_data->m_exampleInfoTextOutput->SetPos(2, 332); - m_data->m_exampleInfoTextOutput->SetHeight( 150 ); + m_data->m_exampleInfoTextOutput->SetHeight(150); m_data->m_exampleInfoTextOutput->SetWidth(233); - - - } -void GwenUserInterface::forceUpdateScrollBars() +void GwenUserInterface::forceUpdateScrollBars() { b3Assert(m_data); b3Assert(m_data->m_explorerTreeCtrl); @@ -441,7 +387,7 @@ void GwenUserInterface::forceUpdateScrollBars() } } -void GwenUserInterface::setFocus() +void GwenUserInterface::setFocus() { b3Assert(m_data); b3Assert(m_data->m_explorerTreeCtrl); @@ -451,16 +397,16 @@ void GwenUserInterface::setFocus() } } -b3ToggleButtonCallback GwenUserInterface::getToggleButtonCallback() +b3ToggleButtonCallback GwenUserInterface::getToggleButtonCallback() { return m_data->m_toggleButtonCallback; } -void GwenUserInterface::setToggleButtonCallback(b3ToggleButtonCallback callback) +void GwenUserInterface::setToggleButtonCallback(b3ToggleButtonCallback callback) { m_data->m_toggleButtonCallback = callback; } -void GwenUserInterface::registerToggleButton2(int buttonId, const char* name) +void GwenUserInterface::registerToggleButton2(int buttonId, const char* name) { assert(m_data); assert(m_data->m_demoPage); @@ -469,21 +415,20 @@ void GwenUserInterface::registerToggleButton2(int buttonId, const char* name) ///some heuristic to find the button location int ypos = m_data->m_curYposition; - but->SetPos(10, ypos ); - but->SetWidth( 200 ); + but->SetPos(10, ypos); + but->SetWidth(200); //but->SetBounds( 200, 30, 300, 200 ); MyButtonHander* handler = new MyButtonHander(m_data, buttonId); m_data->m_handlers.push_back(handler); - m_data->m_curYposition+=22; + m_data->m_curYposition += 22; but->onToggle.Add(handler, &MyButtonHander::onButtonA); but->SetIsToggle(true); but->SetToggleState(false); but->SetText(name); - } -void GwenUserInterface::setComboBoxCallback(b3ComboBoxCallback callback) +void GwenUserInterface::setComboBoxCallback(b3ComboBoxCallback callback) { m_data->m_comboBoxCallback = callback; } @@ -492,67 +437,61 @@ b3ComboBoxCallback GwenUserInterface::getComboBoxCallback() { return m_data->m_comboBoxCallback; } -void GwenUserInterface::registerComboBox2(int comboboxId, int numItems, const char** items, int startItem) +void GwenUserInterface::registerComboBox2(int comboboxId, int numItems, const char** items, int startItem) { Gwen::Controls::ComboBox* combobox = new Gwen::Controls::ComboBox(m_data->m_demoPage->GetPage()); MyComboBoxHander* handler = new MyComboBoxHander(m_data, comboboxId); m_data->m_handlers.push_back(handler); - combobox->onSelection.Add(handler,&MyComboBoxHander::onSelect); + combobox->onSelection.Add(handler, &MyComboBoxHander::onSelect); int ypos = m_data->m_curYposition; - combobox->SetPos(10, ypos ); - combobox->SetWidth( 100 ); + combobox->SetPos(10, ypos); + combobox->SetWidth(100); //box->SetPos(120,130); - for (int i=0;iAddItem(Gwen::Utility::StringToUnicode(items[i])); - if (i==startItem) + if (i == startItem) combobox->OnItemSelected(item); } - m_data->m_curYposition+=22; - - - + m_data->m_curYposition += 22; } -void GwenUserInterface::draw(int width, int height) +void GwenUserInterface::draw(int width, int height) { - -// printf("width = %d, height=%d\n", width,height); + // printf("width = %d, height=%d\n", width,height); if (m_data->pCanvas) { - m_data->pCanvas->SetSize(width,height); + m_data->pCanvas->SetSize(width, height); //m_data->m_primRenderer->setScreenSize(width,height); - m_data->pRenderer->Resize(width,height); + m_data->pRenderer->Resize(width, height); m_data->pCanvas->RenderCanvas(); //restoreOpenGLState(); } - } -bool GwenUserInterface::mouseMoveCallback( float x, float y) +bool GwenUserInterface::mouseMoveCallback(float x, float y) { - bool handled = false; + bool handled = false; - static int m_lastmousepos[2] = {0,0}; + static int m_lastmousepos[2] = {0, 0}; static bool isInitialized = false; if (m_data->pCanvas) { if (!isInitialized) { isInitialized = true; - m_lastmousepos[0] = x+1; - m_lastmousepos[1] = y+1; + m_lastmousepos[0] = x + 1; + m_lastmousepos[1] = y + 1; } - handled = m_data->pCanvas->InputMouseMoved(x,y,m_lastmousepos[0],m_lastmousepos[1]); + handled = m_data->pCanvas->InputMouseMoved(x, y, m_lastmousepos[0], m_lastmousepos[1]); } return handled; - } #include "../CommonInterfaces/CommonWindowInterface.h" -bool GwenUserInterface::keyboardCallback(int bulletKey, int state) +bool GwenUserInterface::keyboardCallback(int bulletKey, int state) { int gwenKey = -1; if (m_data->pCanvas) @@ -560,96 +499,93 @@ bool GwenUserInterface::keyboardCallback(int bulletKey, int state) //convert 'Bullet' keys into 'Gwen' keys switch (bulletKey) { - case B3G_RETURN: - { - gwenKey = Gwen::Key::Return; - break; - } - case B3G_LEFT_ARROW: - { - gwenKey = Gwen::Key::Left; - break; - } - case B3G_RIGHT_ARROW: - { - gwenKey = Gwen::Key::Right; - break; - } - case B3G_UP_ARROW: - { - gwenKey = Gwen::Key::Up; - break; - } - case B3G_DOWN_ARROW: - { - gwenKey = Gwen::Key::Down; - break; - } - case B3G_BACKSPACE: - { - gwenKey = Gwen::Key::Backspace; - break; - } - case B3G_DELETE: - { - gwenKey = Gwen::Key::Delete; - break; - } - case B3G_HOME: - { - gwenKey = Gwen::Key::Home; - break; - } - case B3G_END: - { - gwenKey = Gwen::Key::End; - break; - } - case B3G_SHIFT: - { - gwenKey = Gwen::Key::Shift; - break; - } - case B3G_CONTROL: - { - gwenKey = Gwen::Key::Control; - break; - } + case B3G_RETURN: + { + gwenKey = Gwen::Key::Return; + break; + } + case B3G_LEFT_ARROW: + { + gwenKey = Gwen::Key::Left; + break; + } + case B3G_RIGHT_ARROW: + { + gwenKey = Gwen::Key::Right; + break; + } + case B3G_UP_ARROW: + { + gwenKey = Gwen::Key::Up; + break; + } + case B3G_DOWN_ARROW: + { + gwenKey = Gwen::Key::Down; + break; + } + case B3G_BACKSPACE: + { + gwenKey = Gwen::Key::Backspace; + break; + } + case B3G_DELETE: + { + gwenKey = Gwen::Key::Delete; + break; + } + case B3G_HOME: + { + gwenKey = Gwen::Key::Home; + break; + } + case B3G_END: + { + gwenKey = Gwen::Key::End; + break; + } + case B3G_SHIFT: + { + gwenKey = Gwen::Key::Shift; + break; + } + case B3G_CONTROL: + { + gwenKey = Gwen::Key::Control; + break; + } - default: - { - - } + default: + { + } }; - if (gwenKey>=0) + if (gwenKey >= 0) { - return m_data->pCanvas->InputKey(gwenKey,state==1); - } else + return m_data->pCanvas->InputKey(gwenKey, state == 1); + } + else { - if (bulletKey<256 && state) + if (bulletKey < 256 && state) { - Gwen::UnicodeChar c = ( Gwen::UnicodeChar ) bulletKey; + Gwen::UnicodeChar c = (Gwen::UnicodeChar)bulletKey; return m_data->pCanvas->InputCharacter(c); } } - - } return false; } - -bool GwenUserInterface::mouseButtonCallback(int button, int state, float x, float y) +bool GwenUserInterface::mouseButtonCallback(int button, int state, float x, float y) { bool handled = false; if (m_data->pCanvas) { - handled = m_data->pCanvas->InputMouseMoved(x,y,x, y); + handled = m_data->pCanvas->InputMouseMoved(x, y, x, y); - if (button>=0) + if (button >= 0) { - handled = m_data->pCanvas->InputMouseButton(button,(bool)state); + handled = m_data->pCanvas->InputMouseButton(button, (bool)state); if (handled) { //if (!state) diff --git a/examples/ExampleBrowser/GwenGUISupport/gwenUserInterface.h b/examples/ExampleBrowser/GwenGUISupport/gwenUserInterface.h index d66b59828..5f246180e 100644 --- a/examples/ExampleBrowser/GwenGUISupport/gwenUserInterface.h +++ b/examples/ExampleBrowser/GwenGUISupport/gwenUserInterface.h @@ -3,68 +3,61 @@ struct GwenInternalData; -typedef void (*b3ComboBoxCallback) (int combobox, const char* item); +typedef void (*b3ComboBoxCallback)(int combobox, const char* item); typedef void (*b3ToggleButtonCallback)(int button, int state); typedef void (*b3FileOpenCallback)(); typedef void (*b3QuitCallback)(); namespace Gwen { - namespace Renderer - { - class Base; - }; +namespace Renderer +{ +class Base; }; +}; // namespace Gwen class GwenUserInterface { - GwenInternalData* m_data; + GwenInternalData* m_data; - public: - - GwenUserInterface(); - - virtual ~GwenUserInterface(); - - void init(int width, int height,Gwen::Renderer::Base* gwenRenderer,float retinaScale); - void exit(); - void setFocus(); - void forceUpdateScrollBars(); - - void draw(int width, int height); +public: + GwenUserInterface(); - void resize(int width, int height); - - bool mouseMoveCallback( float x, float y); - bool mouseButtonCallback(int button, int state, float x, float y); - bool keyboardCallback(int key, int state); + virtual ~GwenUserInterface(); + void init(int width, int height, Gwen::Renderer::Base* gwenRenderer, float retinaScale); + void exit(); + void setFocus(); + void forceUpdateScrollBars(); - void setToggleButtonCallback(b3ToggleButtonCallback callback); - b3ToggleButtonCallback getToggleButtonCallback(); + void draw(int width, int height); - void registerToggleButton2(int buttonId, const char* name); + void resize(int width, int height); - void setComboBoxCallback(b3ComboBoxCallback callback); - b3ComboBoxCallback getComboBoxCallback(); - void registerComboBox2(int buttonId, int numItems, const char** items, int startItem = 0); - - void setStatusBarMessage(const char* message, bool isLeft=true); + bool mouseMoveCallback(float x, float y); + bool mouseButtonCallback(int button, int state, float x, float y); + bool keyboardCallback(int key, int state); - void textOutput(const char* msg); - void setExampleDescription(const char* msg); - + void setToggleButtonCallback(b3ToggleButtonCallback callback); + b3ToggleButtonCallback getToggleButtonCallback(); - void registerFileOpenCallback(b3FileOpenCallback callback); - void registerQuitCallback(b3QuitCallback callback); - - GwenInternalData* getInternalData() - { - return m_data; - } + void registerToggleButton2(int buttonId, const char* name); + void setComboBoxCallback(b3ComboBoxCallback callback); + b3ComboBoxCallback getComboBoxCallback(); + void registerComboBox2(int buttonId, int numItems, const char** items, int startItem = 0); + + void setStatusBarMessage(const char* message, bool isLeft = true); + + void textOutput(const char* msg); + void setExampleDescription(const char* msg); + + void registerFileOpenCallback(b3FileOpenCallback callback); + void registerQuitCallback(b3QuitCallback callback); + + GwenInternalData* getInternalData() + { + return m_data; + } }; - - -#endif //_GWEN_USER_INTERFACE_H - +#endif //_GWEN_USER_INTERFACE_H diff --git a/examples/ExampleBrowser/InProcessExampleBrowser.cpp b/examples/ExampleBrowser/InProcessExampleBrowser.cpp index 6a6d413a1..e686bfda6 100644 --- a/examples/ExampleBrowser/InProcessExampleBrowser.cpp +++ b/examples/ExampleBrowser/InProcessExampleBrowser.cpp @@ -2,12 +2,12 @@ //#define EXAMPLE_CONSOLE_ONLY #ifdef EXAMPLE_CONSOLE_ONLY - #include "EmptyBrowser.h" - typedef EmptyBrowser DefaultBrowser; +#include "EmptyBrowser.h" +typedef EmptyBrowser DefaultBrowser; #else - #include "OpenGLExampleBrowser.h" - typedef OpenGLExampleBrowser DefaultBrowser; -#endif //EXAMPLE_CONSOLE_ONLY +#include "OpenGLExampleBrowser.h" +typedef OpenGLExampleBrowser DefaultBrowser; +#endif //EXAMPLE_CONSOLE_ONLY #include "Bullet3Common/b3CommandLineArgs.h" #include "../Utils/b3Clock.h" @@ -16,11 +16,10 @@ #include "Bullet3Common/b3Scalar.h" #include "../SharedMemory/InProcessMemory.h" -void ExampleBrowserThreadFunc(void* userPtr,void* lsMemory); -void* ExampleBrowserMemoryFunc(); +void ExampleBrowserThreadFunc(void* userPtr, void* lsMemory); +void* ExampleBrowserMemoryFunc(); void ExampleBrowserMemoryReleaseFunc(void* ptr); - #include //#include "BulletMultiThreaded/PlatformDefinitions.h" @@ -37,50 +36,38 @@ void ExampleBrowserMemoryReleaseFunc(void* ptr); #ifndef _WIN32 #include "../MultiThreading/b3PosixThreadSupport.h" - - static b3ThreadSupportInterface* createExampleBrowserThreadSupport(int numThreads) { b3PosixThreadSupport::ThreadConstructionInfo constructionInfo("testThreads", - ExampleBrowserThreadFunc, - ExampleBrowserMemoryFunc, - ExampleBrowserMemoryReleaseFunc, - numThreads); - b3ThreadSupportInterface* threadSupport = new b3PosixThreadSupport(constructionInfo); + ExampleBrowserThreadFunc, + ExampleBrowserMemoryFunc, + ExampleBrowserMemoryReleaseFunc, + numThreads); + b3ThreadSupportInterface* threadSupport = new b3PosixThreadSupport(constructionInfo); return threadSupport; - } - - -#elif defined( _WIN32) +#elif defined(_WIN32) #include "../MultiThreading/b3Win32ThreadSupport.h" b3ThreadSupportInterface* createExampleBrowserThreadSupport(int numThreads) { - b3Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("testThreads",ExampleBrowserThreadFunc,ExampleBrowserMemoryFunc,ExampleBrowserMemoryReleaseFunc,numThreads); + b3Win32ThreadSupport::Win32ThreadConstructionInfo threadConstructionInfo("testThreads", ExampleBrowserThreadFunc, ExampleBrowserMemoryFunc, ExampleBrowserMemoryReleaseFunc, numThreads); b3Win32ThreadSupport* threadSupport = new b3Win32ThreadSupport(threadConstructionInfo); return threadSupport; - } #endif - - - - class ExampleEntriesPhysicsServer : public ExampleEntries { - struct ExampleEntriesInternalData2* m_data; public: - ExampleEntriesPhysicsServer(); virtual ~ExampleEntriesPhysicsServer(); - static void registerExampleEntry(int menuLevel, const char* name,const char* description, CommonExampleInterface::CreateFunc* createFunc, int option=0); + static void registerExampleEntry(int menuLevel, const char* name, const char* description, CommonExampleInterface::CreateFunc* createFunc, int option = 0); virtual void initExampleEntries(); @@ -94,54 +81,50 @@ public: virtual const char* getExampleDescription(int index); - virtual int getExampleOption(int index); - + virtual int getExampleOption(int index); }; - struct ExampleEntryPhysicsServer { - int m_menuLevel; - const char* m_name; - const char* m_description; - CommonExampleInterface::CreateFunc* m_createFunc; - int m_option; + int m_menuLevel; + const char* m_name; + const char* m_description; + CommonExampleInterface::CreateFunc* m_createFunc; + int m_option; ExampleEntryPhysicsServer(int menuLevel, const char* name) - :m_menuLevel(menuLevel), m_name(name), m_description(0), m_createFunc(0), m_option(0) + : m_menuLevel(menuLevel), m_name(name), m_description(0), m_createFunc(0), m_option(0) { } - ExampleEntryPhysicsServer(int menuLevel, const char* name,const char* description, CommonExampleInterface::CreateFunc* createFunc, int option=0) - :m_menuLevel(menuLevel), m_name(name), m_description(description), m_createFunc(createFunc), m_option(option) + ExampleEntryPhysicsServer(int menuLevel, const char* name, const char* description, CommonExampleInterface::CreateFunc* createFunc, int option = 0) + : m_menuLevel(menuLevel), m_name(name), m_description(description), m_createFunc(createFunc), m_option(option) { } }; struct ExampleEntriesInternalData2 { - btAlignedObjectArray m_allExamples; + btAlignedObjectArray m_allExamples; }; -static ExampleEntryPhysicsServer gDefaultExamplesPhysicsServer[]= -{ +static ExampleEntryPhysicsServer gDefaultExamplesPhysicsServer[] = + { - ExampleEntryPhysicsServer(0,"Robotics Control"), + ExampleEntryPhysicsServer(0, "Robotics Control"), - ExampleEntryPhysicsServer(1,"Physics Server", "Create a physics server that communicates with a physics client over shared memory", - PhysicsServerCreateFuncBullet2), - ExampleEntryPhysicsServer(1,"Physics Server (RTC)", "Create a physics server that communicates with a physics client over shared memory. At each update, the Physics Server will continue calling 'stepSimulation' based on the real-time clock (RTC).", - PhysicsServerCreateFuncBullet2,PHYSICS_SERVER_USE_RTC_CLOCK), - - ExampleEntryPhysicsServer(1,"Physics Server (Logging)", "Create a physics server that communicates with a physics client over shared memory. It will log all commands to a file.", - PhysicsServerCreateFuncBullet2,PHYSICS_SERVER_ENABLE_COMMAND_LOGGING), - ExampleEntryPhysicsServer(1,"Physics Server (Replay Log)", "Create a physics server that replay a command log from disk.", - PhysicsServerCreateFuncBullet2,PHYSICS_SERVER_REPLAY_FROM_COMMAND_LOG), + ExampleEntryPhysicsServer(1, "Physics Server", "Create a physics server that communicates with a physics client over shared memory", + PhysicsServerCreateFuncBullet2), + ExampleEntryPhysicsServer(1, "Physics Server (RTC)", "Create a physics server that communicates with a physics client over shared memory. At each update, the Physics Server will continue calling 'stepSimulation' based on the real-time clock (RTC).", + PhysicsServerCreateFuncBullet2, PHYSICS_SERVER_USE_RTC_CLOCK), + ExampleEntryPhysicsServer(1, "Physics Server (Logging)", "Create a physics server that communicates with a physics client over shared memory. It will log all commands to a file.", + PhysicsServerCreateFuncBullet2, PHYSICS_SERVER_ENABLE_COMMAND_LOGGING), + ExampleEntryPhysicsServer(1, "Physics Server (Replay Log)", "Create a physics server that replay a command log from disk.", + PhysicsServerCreateFuncBullet2, PHYSICS_SERVER_REPLAY_FROM_COMMAND_LOG), }; - ExampleEntriesPhysicsServer::ExampleEntriesPhysicsServer() { m_data = new ExampleEntriesInternalData2; @@ -160,17 +143,14 @@ void ExampleEntriesPhysicsServer::initExampleEntries() { m_data->m_allExamples.clear(); - - - int numDefaultEntries = sizeof(gDefaultExamplesPhysicsServer)/sizeof(ExampleEntryPhysicsServer); - for (int i=0;im_allExamples.push_back(gDefaultExamplesPhysicsServer[i]); } - } -void ExampleEntriesPhysicsServer::registerExampleEntry(int menuLevel, const char* name,const char* description, CommonExampleInterface::CreateFunc* createFunc, int option) +void ExampleEntriesPhysicsServer::registerExampleEntry(int menuLevel, const char* name, const char* description, CommonExampleInterface::CreateFunc* createFunc, int option) { } @@ -199,19 +179,16 @@ const char* ExampleEntriesPhysicsServer::getExampleDescription(int index) return m_data->m_allExamples[index].m_description; } - - - -struct ExampleBrowserArgs +struct ExampleBrowserArgs { ExampleBrowserArgs() - :m_fakeWork(1),m_argc(0) + : m_fakeWork(1), m_argc(0) { } b3CriticalSection* m_cs; float m_fakeWork; - int m_argc; - char** m_argv; + int m_argc; + char** m_argv; }; struct ExampleBrowserThreadLocalStorage @@ -231,32 +208,29 @@ enum TestExampleBrowserCommunicationEnums static double gMinUpdateTimeMicroSecs = 4000.; -void ExampleBrowserThreadFunc(void* userPtr,void* lsMemory) +void ExampleBrowserThreadFunc(void* userPtr, void* lsMemory) { - printf("ExampleBrowserThreadFunc started\n"); - ExampleBrowserThreadLocalStorage* localStorage = (ExampleBrowserThreadLocalStorage*) lsMemory; + ExampleBrowserThreadLocalStorage* localStorage = (ExampleBrowserThreadLocalStorage*)lsMemory; - ExampleBrowserArgs* args = (ExampleBrowserArgs*) userPtr; + ExampleBrowserArgs* args = (ExampleBrowserArgs*)userPtr; //int workLeft = true; - b3CommandLineArgs args2(args->m_argc,args->m_argv); + b3CommandLineArgs args2(args->m_argc, args->m_argv); b3Clock clock; - ExampleEntriesPhysicsServer examples; examples.initExampleEntries(); DefaultBrowser* exampleBrowser = new DefaultBrowser(&examples); exampleBrowser->setSharedMemoryInterface(localStorage->m_sharedMem); - bool init = exampleBrowser->init(args->m_argc,args->m_argv); + bool init = exampleBrowser->init(args->m_argc, args->m_argv); clock.reset(); if (init) { - args->m_cs->lock(); - args->m_cs->setSharedParam(0,eExampleBrowserIsInitialized); + args->m_cs->setSharedParam(0, eExampleBrowserIsInitialized); args->m_cs->unlock(); do @@ -264,17 +238,18 @@ void ExampleBrowserThreadFunc(void* userPtr,void* lsMemory) clock.usleep(0); //B3_PROFILE("ExampleBrowserThreadFunc"); - float deltaTimeInSeconds = clock.getTimeMicroseconds()/1000000.f; + float deltaTimeInSeconds = clock.getTimeMicroseconds() / 1000000.f; { if (deltaTimeInSeconds > 0.1) { deltaTimeInSeconds = 0.1; } - if (deltaTimeInSeconds < (gMinUpdateTimeMicroSecs/1e6)) + if (deltaTimeInSeconds < (gMinUpdateTimeMicroSecs / 1e6)) { //B3_PROFILE("clock.usleep"); exampleBrowser->updateGraphics(); - } else + } + else { //B3_PROFILE("exampleBrowser->update"); clock.reset(); @@ -283,24 +258,24 @@ void ExampleBrowserThreadFunc(void* userPtr,void* lsMemory) } } - } while (!exampleBrowser->requestedExit() && (args->m_cs->getSharedParam(0)!=eRequestTerminateExampleBrowser)); - } else + } while (!exampleBrowser->requestedExit() && (args->m_cs->getSharedParam(0) != eRequestTerminateExampleBrowser)); + } + else { args->m_cs->lock(); - args->m_cs->setSharedParam(0,eExampleBrowserInitializationFailed); + args->m_cs->setSharedParam(0, eExampleBrowserInitializationFailed); args->m_cs->unlock(); } delete exampleBrowser; args->m_cs->lock(); - args->m_cs->setSharedParam(0,eExampleBrowserHasTerminated); + args->m_cs->setSharedParam(0, eExampleBrowserHasTerminated); args->m_cs->unlock(); printf("finished\n"); //do nothing } - -void* ExampleBrowserMemoryFunc() +void* ExampleBrowserMemoryFunc() { //don't create local store memory, just return 0 return new ExampleBrowserThreadLocalStorage; @@ -308,14 +283,10 @@ void* ExampleBrowserMemoryFunc() void ExampleBrowserMemoryReleaseFunc(void* ptr) { - ExampleBrowserThreadLocalStorage* p = (ExampleBrowserThreadLocalStorage*) ptr; + ExampleBrowserThreadLocalStorage* p = (ExampleBrowserThreadLocalStorage*)ptr; delete p; } - - - - struct btInProcessExampleBrowserInternalData { ExampleBrowserArgs m_args; @@ -323,13 +294,10 @@ struct btInProcessExampleBrowserInternalData SharedMemoryInterface* m_sharedMem; }; - - -btInProcessExampleBrowserInternalData* btCreateInProcessExampleBrowser(int argc,char** argv2, bool useInProcessMemory) +btInProcessExampleBrowserInternalData* btCreateInProcessExampleBrowser(int argc, char** argv2, bool useInProcessMemory) { - btInProcessExampleBrowserInternalData* data = new btInProcessExampleBrowserInternalData; - + data->m_sharedMem = useInProcessMemory ? new InProcessMemory : 0; int numThreads = 1; @@ -338,32 +306,30 @@ btInProcessExampleBrowserInternalData* btCreateInProcessExampleBrowser(int argc, data->m_threadSupport = createExampleBrowserThreadSupport(numThreads); printf("argc=%d\n", argc); - for (i=0;im_threadSupport->getNumTasks();i++) + for (i = 0; i < data->m_threadSupport->getNumTasks(); i++) { - ExampleBrowserThreadLocalStorage* storage = (ExampleBrowserThreadLocalStorage*) data->m_threadSupport->getThreadLocalMemory(i); + ExampleBrowserThreadLocalStorage* storage = (ExampleBrowserThreadLocalStorage*)data->m_threadSupport->getThreadLocalMemory(i); b3Assert(storage); storage->threadId = i; storage->m_sharedMem = data->m_sharedMem; } - data->m_args.m_cs = data->m_threadSupport->createCriticalSection(); - data->m_args.m_cs->setSharedParam(0,eExampleBrowserIsUnInitialized); - data->m_args.m_argc = argc; - data->m_args.m_argv = argv2; + data->m_args.m_cs->setSharedParam(0, eExampleBrowserIsUnInitialized); + data->m_args.m_argc = argc; + data->m_args.m_argv = argv2; - - for (i=0;im_threadSupport->runTask(B3_THREAD_SCHEDULE_TASK, (void*) &data->m_args, i); + data->m_threadSupport->runTask(B3_THREAD_SCHEDULE_TASK, (void*)&data->m_args, i); } - while (data->m_args.m_cs->getSharedParam(0)==eExampleBrowserIsUnInitialized) + while (data->m_args.m_cs->getSharedParam(0) == eExampleBrowserIsUnInitialized) { b3Clock::usleep(1000); } @@ -373,7 +339,7 @@ btInProcessExampleBrowserInternalData* btCreateInProcessExampleBrowser(int argc, bool btIsExampleBrowserTerminated(btInProcessExampleBrowserInternalData* data) { - return (data->m_args.m_cs->getSharedParam(0)==eExampleBrowserHasTerminated); + return (data->m_args.m_cs->getSharedParam(0) == eExampleBrowserHasTerminated); } SharedMemoryInterface* btGetSharedMemoryInterface(btInProcessExampleBrowserInternalData* data) @@ -386,23 +352,23 @@ void btShutDownExampleBrowser(btInProcessExampleBrowserInternalData* data) int numActiveThreads = 1; data->m_args.m_cs->lock(); - data->m_args.m_cs->setSharedParam(0,eRequestTerminateExampleBrowser); + data->m_args.m_cs->setSharedParam(0, eRequestTerminateExampleBrowser); data->m_args.m_cs->unlock(); while (numActiveThreads) - { - int arg0,arg1; - if (data->m_threadSupport->isTaskCompleted(&arg0,&arg1,0)) - { - numActiveThreads--; - printf("numActiveThreads = %d\n",numActiveThreads); - - } else - { -// printf("polling.."); - b3Clock::usleep(0); - } - }; + { + int arg0, arg1; + if (data->m_threadSupport->isTaskCompleted(&arg0, &arg1, 0)) + { + numActiveThreads--; + printf("numActiveThreads = %d\n", numActiveThreads); + } + else + { + // printf("polling.."); + b3Clock::usleep(0); + } + }; printf("btShutDownExampleBrowser stopping threads\n"); data->m_threadSupport->deleteCriticalSection(data->m_args.m_cs); @@ -414,46 +380,45 @@ void btShutDownExampleBrowser(btInProcessExampleBrowserInternalData* data) struct btInProcessExampleBrowserMainThreadInternalData { - ExampleEntriesPhysicsServer m_examples; - DefaultBrowser* m_exampleBrowser; - SharedMemoryInterface* m_sharedMem; - b3Clock m_clock; + ExampleEntriesPhysicsServer m_examples; + DefaultBrowser* m_exampleBrowser; + SharedMemoryInterface* m_sharedMem; + b3Clock m_clock; }; -btInProcessExampleBrowserMainThreadInternalData* btCreateInProcessExampleBrowserMainThread(int argc,char** argv, bool useInProcessMemory) +btInProcessExampleBrowserMainThreadInternalData* btCreateInProcessExampleBrowserMainThread(int argc, char** argv, bool useInProcessMemory) { - btInProcessExampleBrowserMainThreadInternalData* data = new btInProcessExampleBrowserMainThreadInternalData; - data->m_examples.initExampleEntries(); - data->m_exampleBrowser = new DefaultBrowser(&data->m_examples); - data->m_sharedMem = useInProcessMemory ? new InProcessMemory : 0; - data->m_exampleBrowser->setSharedMemoryInterface(data->m_sharedMem ); + btInProcessExampleBrowserMainThreadInternalData* data = new btInProcessExampleBrowserMainThreadInternalData; + data->m_examples.initExampleEntries(); + data->m_exampleBrowser = new DefaultBrowser(&data->m_examples); + data->m_sharedMem = useInProcessMemory ? new InProcessMemory : 0; + data->m_exampleBrowser->setSharedMemoryInterface(data->m_sharedMem); bool init; - init = data->m_exampleBrowser->init(argc,argv); - data->m_clock.reset(); - return data; + init = data->m_exampleBrowser->init(argc, argv); + data->m_clock.reset(); + return data; } bool btIsExampleBrowserMainThreadTerminated(btInProcessExampleBrowserMainThreadInternalData* data) { - return data->m_exampleBrowser->requestedExit(); + return data->m_exampleBrowser->requestedExit(); } void btUpdateInProcessExampleBrowserMainThread(btInProcessExampleBrowserMainThreadInternalData* data) { - float deltaTimeInSeconds = data->m_clock.getTimeMicroseconds()/1000000.f; - data->m_clock.reset(); - data->m_exampleBrowser->updateGraphics(); - data->m_exampleBrowser->update(deltaTimeInSeconds); + float deltaTimeInSeconds = data->m_clock.getTimeMicroseconds() / 1000000.f; + data->m_clock.reset(); + data->m_exampleBrowser->updateGraphics(); + data->m_exampleBrowser->update(deltaTimeInSeconds); } void btShutDownExampleBrowserMainThread(btInProcessExampleBrowserMainThreadInternalData* data) { - - data->m_exampleBrowser->setSharedMemoryInterface(0); - delete data->m_exampleBrowser; - delete data; + data->m_exampleBrowser->setSharedMemoryInterface(0); + delete data->m_exampleBrowser; + delete data; } class SharedMemoryInterface* btGetSharedMemoryInterfaceMainThread(btInProcessExampleBrowserMainThreadInternalData* data) { - return data->m_sharedMem; + return data->m_sharedMem; } diff --git a/examples/ExampleBrowser/InProcessExampleBrowser.h b/examples/ExampleBrowser/InProcessExampleBrowser.h index 526c42058..f231091e7 100644 --- a/examples/ExampleBrowser/InProcessExampleBrowser.h +++ b/examples/ExampleBrowser/InProcessExampleBrowser.h @@ -3,7 +3,7 @@ struct btInProcessExampleBrowserInternalData; -btInProcessExampleBrowserInternalData* btCreateInProcessExampleBrowser(int argc,char** argv2, bool useInProcessMemory); +btInProcessExampleBrowserInternalData* btCreateInProcessExampleBrowser(int argc, char** argv2, bool useInProcessMemory); bool btIsExampleBrowserTerminated(btInProcessExampleBrowserInternalData* data); @@ -11,13 +11,11 @@ void btShutDownExampleBrowser(btInProcessExampleBrowserInternalData* data); class SharedMemoryInterface* btGetSharedMemoryInterface(btInProcessExampleBrowserInternalData* data); - /////////////////////// - struct btInProcessExampleBrowserMainThreadInternalData; -btInProcessExampleBrowserMainThreadInternalData* btCreateInProcessExampleBrowserMainThread(int argc,char** argv, bool useInProcessMemory); +btInProcessExampleBrowserMainThreadInternalData* btCreateInProcessExampleBrowserMainThread(int argc, char** argv, bool useInProcessMemory); bool btIsExampleBrowserMainThreadTerminated(btInProcessExampleBrowserMainThreadInternalData* data); @@ -27,7 +25,6 @@ void btShutDownExampleBrowserMainThread(btInProcessExampleBrowserMainThreadInter class SharedMemoryInterface* btGetSharedMemoryInterfaceMainThread(btInProcessExampleBrowserMainThreadInternalData* data); - ////////////////////// -#endif //IN_PROCESS_EXAMPLE_BROWSER_H +#endif //IN_PROCESS_EXAMPLE_BROWSER_H diff --git a/examples/ExampleBrowser/OpenGLExampleBrowser.cpp b/examples/ExampleBrowser/OpenGLExampleBrowser.cpp index 871e4c9b1..1ed8c7a37 100644 --- a/examples/ExampleBrowser/OpenGLExampleBrowser.cpp +++ b/examples/ExampleBrowser/OpenGLExampleBrowser.cpp @@ -17,9 +17,9 @@ #include "../OpenGLWindow/EGLOpenGLWindow.h" #else #include "../OpenGLWindow/X11OpenGLWindow.h" -#endif //BT_USE_EGL -#endif //_WIN32 -#endif//__APPLE__ +#endif //BT_USE_EGL +#endif //_WIN32 +#endif //__APPLE__ #include "../ThirdPartyLibs/Gwen/Renderers/OpenGL_DebugFont.h" #include "LinearMath/btThreads.h" #include "Bullet3Common/b3Vector3.h" @@ -69,14 +69,13 @@ struct GL3TexLoader : public MyTextureLoader } }; - struct OpenGLExampleBrowserInternalData { Gwen::Renderer::Base* m_gwenRenderer; CommonGraphicsApp* m_app; #ifndef BT_NO_PROFILE MyProfileWindow* m_profWindow; -#endif //BT_NO_PROFILE +#endif //BT_NO_PROFILE btAlignedObjectArray m_nodes; GwenUserInterface* m_gui; GL3TexLoader* m_myTexLoader; @@ -85,25 +84,24 @@ struct OpenGLExampleBrowserInternalData OpenGLExampleBrowserInternalData() : m_gwenRenderer(0), - m_app(0), -// m_profWindow(0), - m_gui(0), - m_myTexLoader(0), - m_handler2(0) + m_app(0), + // m_profWindow(0), + m_gui(0), + m_myTexLoader(0), + m_handler2(0) { - } }; -static CommonGraphicsApp* s_app=0; +static CommonGraphicsApp* s_app = 0; static CommonWindowInterface* s_window = 0; -static CommonParameterInterface* s_parameterInterface=0; -static CommonRenderInterface* s_instancingRenderer=0; -static OpenGLGuiHelper* s_guiHelper=0; +static CommonParameterInterface* s_parameterInterface = 0; +static CommonRenderInterface* s_instancingRenderer = 0; +static OpenGLGuiHelper* s_guiHelper = 0; #ifndef BT_NO_PROFILE -static MyProfileWindow* s_profWindow =0; -#endif //BT_NO_PROFILE +static MyProfileWindow* s_profWindow = 0; +#endif //BT_NO_PROFILE static SharedMemoryInterface* sSharedMem = 0; #define DEMO_SELECTION_COMBOBOX 13 @@ -120,14 +118,14 @@ bool gAllowRetina = true; bool gDisableDemoSelection = false; int gRenderDevice = -1; int gWindowBackend = 0; -static class ExampleEntries* gAllExamples=0; +static class ExampleEntries* gAllExamples = 0; bool sUseOpenGL2 = false; #ifndef USE_OPENGL3 extern bool useShadowMap; #endif -bool visualWireframe=false; -static bool renderVisualGeometry=true; +bool visualWireframe = false; +static bool renderVisualGeometry = true; static bool renderGrid = true; static bool gEnableRenderLoop = true; @@ -136,85 +134,74 @@ static bool enable_experimental_opencl = false; static bool gEnableDefaultKeyboardShortcuts = true; static bool gEnableDefaultMousePicking = true; - int gDebugDrawFlags = 0; -static bool pauseSimulation=false; +static bool pauseSimulation = false; static bool singleStepSimulation = false; int midiBaseIndex = 176; extern bool gDisableDeactivation; -int gSharedMemoryKey=-1; - +int gSharedMemoryKey = -1; ///some quick test variable for the OpenCL examples -int gPreferredOpenCLDeviceIndex=-1; -int gPreferredOpenCLPlatformIndex=-1; -int gGpuArraySizeX=45; -int gGpuArraySizeY=55; -int gGpuArraySizeZ=45; +int gPreferredOpenCLDeviceIndex = -1; +int gPreferredOpenCLPlatformIndex = -1; +int gGpuArraySizeX = 45; +int gGpuArraySizeY = 55; +int gGpuArraySizeZ = 45; //#include //unsigned int fp_control_state = _controlfp(_EM_INEXACT, _MCW_EM); - - void deleteDemo() { - if (sCurrentDemo) + if (sCurrentDemo) { sCurrentDemo->exitPhysics(); s_instancingRenderer->removeAllInstances(); delete sCurrentDemo; - sCurrentDemo=0; + sCurrentDemo = 0; delete s_guiHelper; s_guiHelper = 0; -// CProfileManager::CleanupMemory(); + // CProfileManager::CleanupMemory(); } } const char* gPngFileName = 0; int gPngSkipFrames = 0; - - - b3KeyboardCallback prevKeyboardCallback = 0; void MyKeyboardCallback(int key, int state) { - //b3Printf("key=%d, state=%d", key, state); bool handled = false; if (renderGui) { - if (gui2 && !handled ) + if (gui2 && !handled) { handled = gui2->keyboardCallback(key, state); } } - + if (!handled && sCurrentDemo) { - handled = sCurrentDemo->keyboardCallback(key,state); + handled = sCurrentDemo->keyboardCallback(key, state); } - - - //checkout: is it desired to ignore keys, if the demo already handles them? //if (handled) // return; if (gEnableDefaultKeyboardShortcuts) { - if (key=='a' && state) + if (key == 'a' && state) { gDebugDrawFlags ^= btIDebugDraw::DBG_DrawAabb; } - if (key=='c' && state) + if (key == 'c' && state) { gDebugDrawFlags ^= btIDebugDraw::DBG_DrawContactPoints; } @@ -233,29 +220,27 @@ void MyKeyboardCallback(int key, int state) gDebugDrawFlags ^= btIDebugDraw::DBG_DrawConstraints; } - if (key=='l' && state) + if (key == 'l' && state) { gDebugDrawFlags ^= btIDebugDraw::DBG_DrawConstraintLimits; } - if (key=='w' && state) + if (key == 'w' && state) { - visualWireframe=!visualWireframe; + visualWireframe = !visualWireframe; gDebugDrawFlags ^= btIDebugDraw::DBG_DrawWireframe; } - - if (key=='v' && state) + if (key == 'v' && state) { renderVisualGeometry = !renderVisualGeometry; } - if (key=='g' && state) + if (key == 'g' && state) { renderGrid = !renderGrid; renderGui = !renderGui; } - - if (key=='i' && state) + if (key == 'i' && state) { pauseSimulation = !pauseSimulation; } @@ -264,29 +249,29 @@ void MyKeyboardCallback(int key, int state) singleStepSimulation = true; } - if (key=='p') + if (key == 'p') { - #ifndef BT_NO_PROFILE +#ifndef BT_NO_PROFILE if (state) { b3ChromeUtilsStartTimings(); - - } else + } + else { b3ChromeUtilsStopTimingsAndWriteJsonFile("timings"); } - #endif //BT_NO_PROFILE +#endif //BT_NO_PROFILE } - #ifndef NO_OPENGL3 - if (key=='s' && state) +#ifndef NO_OPENGL3 + if (key == 's' && state) { - useShadowMap=!useShadowMap; + useShadowMap = !useShadowMap; } - #endif - if (key==B3G_F1) +#endif + if (key == B3G_F1) { - static int count=0; + static int count = 0; if (state) { b3Printf("F1 pressed %d", count++); @@ -295,66 +280,65 @@ void MyKeyboardCallback(int key, int state) { b3Printf("disable image dump"); - gPngFileName=0; - } else + gPngFileName = 0; + } + else { gPngFileName = gAllExamples->getExampleName(sCurrentDemoIndex); - b3Printf("enable image dump %s",gPngFileName); - + b3Printf("enable image dump %s", gPngFileName); } - } else + } + else { - b3Printf("F1 released %d",count++); + b3Printf("F1 released %d", count++); } } } - if (key==B3G_ESCAPE && s_window) + if (key == B3G_ESCAPE && s_window) { - s_window->setRequestExit(); } if (prevKeyboardCallback) - prevKeyboardCallback(key,state); + prevKeyboardCallback(key, state); } - b3MouseMoveCallback prevMouseMoveCallback = 0; -static void MyMouseMoveCallback( float x, float y) +static void MyMouseMoveCallback(float x, float y) { - bool handled = false; + bool handled = false; if (sCurrentDemo) - handled = sCurrentDemo->mouseMoveCallback(x,y); + handled = sCurrentDemo->mouseMoveCallback(x, y); if (renderGui) { if (!handled && gui2) - handled = gui2->mouseMoveCallback(x,y); + handled = gui2->mouseMoveCallback(x, y); } if (!handled) { if (prevMouseMoveCallback) - prevMouseMoveCallback(x,y); + prevMouseMoveCallback(x, y); } } -b3MouseButtonCallback prevMouseButtonCallback = 0; +b3MouseButtonCallback prevMouseButtonCallback = 0; static void MyMouseButtonCallback(int button, int state, float x, float y) { bool handled = false; //try picking first if (sCurrentDemo) - handled = sCurrentDemo->mouseButtonCallback(button,state,x,y); + handled = sCurrentDemo->mouseButtonCallback(button, state, x, y); if (renderGui) { if (!handled && gui2) - handled = gui2->mouseButtonCallback(button,state,x,y); + handled = gui2->mouseButtonCallback(button, state, x, y); } if (!handled) { - if (prevMouseButtonCallback ) - prevMouseButtonCallback (button,state,x,y); + if (prevMouseButtonCallback) + prevMouseButtonCallback(button, state, x, y); } // b3DefaultMouseButtonCallback(button,state,x,y); } @@ -362,18 +346,18 @@ static void MyMouseButtonCallback(int button, int state, float x, float y) #include struct FileImporterByExtension { - std::string m_extension; - CommonExampleInterface::CreateFunc* m_createFunc; + std::string m_extension; + CommonExampleInterface::CreateFunc* m_createFunc; }; static btAlignedObjectArray gFileImporterByExtension; -void OpenGLExampleBrowser::registerFileImporter(const char* extension, CommonExampleInterface::CreateFunc* createFunc) +void OpenGLExampleBrowser::registerFileImporter(const char* extension, CommonExampleInterface::CreateFunc* createFunc) { - FileImporterByExtension fi; - fi.m_extension = extension; - fi.m_createFunc = createFunc; - gFileImporterByExtension.push_back(fi); + FileImporterByExtension fi; + fi.m_extension = extension; + fi.m_createFunc = createFunc; + gFileImporterByExtension.push_back(fi); } #include "../SharedMemory/SharedMemoryPublic.h" @@ -382,39 +366,39 @@ void OpenGLExampleBrowserVisualizerFlagCallback(int flag, bool enable) if (flag == COV_ENABLE_Y_AXIS_UP) { //either Y = up or Z - int upAxis = enable? 1:2; + int upAxis = enable ? 1 : 2; s_app->setUpAxis(upAxis); } if (flag == COV_ENABLE_RENDERING) { - gEnableRenderLoop = (enable!=0); + gEnableRenderLoop = (enable != 0); } if (flag == COV_ENABLE_SINGLE_STEP_RENDERING) - { + { if (enable) { gEnableRenderLoop = false; singleStepSimulation = true; - } else + } + else { gEnableRenderLoop = true; singleStepSimulation = false; } - } + } - - if (flag == COV_ENABLE_SHADOWS) - { - useShadowMap = enable; - } - if (flag == COV_ENABLE_GUI) - { - renderGui = enable; + if (flag == COV_ENABLE_SHADOWS) + { + useShadowMap = enable; + } + if (flag == COV_ENABLE_GUI) + { + renderGui = enable; renderGrid = enable; - } - + } + if (flag == COV_ENABLE_KEYBOARD_SHORTCUTS) { gEnableDefaultKeyboardShortcuts = enable; @@ -424,9 +408,9 @@ void OpenGLExampleBrowserVisualizerFlagCallback(int flag, bool enable) gEnableDefaultMousePicking = enable; } - if (flag == COV_ENABLE_WIREFRAME) - { - visualWireframe = enable; + if (flag == COV_ENABLE_WIREFRAME) + { + visualWireframe = enable; if (visualWireframe) { gDebugDrawFlags |= btIDebugDraw::DBG_DrawWireframe; @@ -435,62 +419,52 @@ void OpenGLExampleBrowserVisualizerFlagCallback(int flag, bool enable) { gDebugDrawFlags &= ~btIDebugDraw::DBG_DrawWireframe; } - } + } } void openFileDemo(const char* filename) { - deleteDemo(); - - s_guiHelper= new OpenGLGuiHelper(s_app, sUseOpenGL2); + + s_guiHelper = new OpenGLGuiHelper(s_app, sUseOpenGL2); s_guiHelper->setVisualizerFlagCallback(OpenGLExampleBrowserVisualizerFlagCallback); - s_parameterInterface->removeAllParameters(); - + s_parameterInterface->removeAllParameters(); - CommonExampleOptions options(s_guiHelper,1); + CommonExampleOptions options(s_guiHelper, 1); options.m_fileName = filename; char fullPath[1024]; sprintf(fullPath, "%s", filename); b3FileUtils::toLower(fullPath); - - for (int i=0;iinitPhysics(); + + for (int i = 0; i < gFileImporterByExtension.size(); i++) + { + if (strstr(fullPath, gFileImporterByExtension[i].m_extension.c_str())) + { + sCurrentDemo = gFileImporterByExtension[i].m_createFunc(options); + } + } + + if (sCurrentDemo) + { + sCurrentDemo->initPhysics(); sCurrentDemo->resetCamera(); - } - - + } } - - void selectDemo(int demoIndex) { bool resetCamera = (sCurrentDemoIndex != demoIndex); sCurrentDemoIndex = demoIndex; sCurrentHightlighted = demoIndex; int numDemos = gAllExamples->getNumRegisteredExamples(); - - - if (demoIndex>numDemos) + if (demoIndex > numDemos) { demoIndex = 0; } deleteDemo(); - CommonExampleInterface::CreateFunc* func = gAllExamples->getExampleCreateFunc(demoIndex); if (func) { @@ -499,7 +473,7 @@ void selectDemo(int demoIndex) s_parameterInterface->removeAllParameters(); } int option = gAllExamples->getExampleOption(demoIndex); - s_guiHelper= new OpenGLGuiHelper(s_app, sUseOpenGL2); + s_guiHelper = new OpenGLGuiHelper(s_app, sUseOpenGL2); s_guiHelper->setVisualizerFlagCallback(OpenGLExampleBrowserVisualizerFlagCallback); CommonExampleOptions options(s_guiHelper, option); @@ -511,52 +485,50 @@ void selectDemo(int demoIndex) { gui2->setStatusBarMessage("Status: OK", false); } - b3Printf("Selected demo: %s",gAllExamples->getExampleName(demoIndex)); + b3Printf("Selected demo: %s", gAllExamples->getExampleName(demoIndex)); if (gui2) { gui2->setExampleDescription(gAllExamples->getExampleDescription(demoIndex)); } - + sCurrentDemo->initPhysics(); - if(resetCamera) + if (resetCamera) { sCurrentDemo->resetCamera(); } } } - } #include - -static void saveCurrentSettings(int currentEntry,const char* startFileName) +static void saveCurrentSettings(int currentEntry, const char* startFileName) { - FILE* f = fopen(startFileName,"w"); + FILE* f = fopen(startFileName, "w"); if (f) { - fprintf(f,"--start_demo_name=%s\n", gAllExamples->getExampleName(sCurrentDemoIndex)); - fprintf(f,"--mouse_move_multiplier=%f\n", s_app->getMouseMoveMultiplier()); - fprintf(f,"--mouse_wheel_multiplier=%f\n", s_app->getMouseWheelMultiplier()); - float red,green,blue; - s_app->getBackgroundColor(&red,&green,&blue); - fprintf(f,"--background_color_red= %f\n", red); - fprintf(f,"--background_color_green= %f\n", green); - fprintf(f,"--background_color_blue= %f\n", blue); - fprintf(f,"--fixed_timestep= %f\n", gFixedTimeStep); + fprintf(f, "--start_demo_name=%s\n", gAllExamples->getExampleName(sCurrentDemoIndex)); + fprintf(f, "--mouse_move_multiplier=%f\n", s_app->getMouseMoveMultiplier()); + fprintf(f, "--mouse_wheel_multiplier=%f\n", s_app->getMouseWheelMultiplier()); + float red, green, blue; + s_app->getBackgroundColor(&red, &green, &blue); + fprintf(f, "--background_color_red= %f\n", red); + fprintf(f, "--background_color_green= %f\n", green); + fprintf(f, "--background_color_blue= %f\n", blue); + fprintf(f, "--fixed_timestep= %f\n", gFixedTimeStep); if (!gAllowRetina) { - fprintf(f,"--disable_retina"); + fprintf(f, "--disable_retina"); } if (enable_experimental_opencl) { - fprintf(f,"--enable_experimental_opencl\n"); + fprintf(f, "--enable_experimental_opencl\n"); } -// if (sUseOpenGL2 ) -// { -// fprintf(f,"--opengl2\n"); -// } + // if (sUseOpenGL2 ) + // { + // fprintf(f,"--opengl2\n"); + // } fclose(f); } @@ -565,41 +537,39 @@ static void saveCurrentSettings(int currentEntry,const char* startFileName) static void loadCurrentSettings(const char* startFileName, b3CommandLineArgs& args) { //int currentEntry= 0; - FILE* f = fopen(startFileName,"r"); + FILE* f = fopen(startFileName, "r"); if (f) { char oneline[1024]; - char* argv[] = {0,&oneline[0]}; - - while( fgets (oneline, 1024, f)!=NULL ) + char* argv[] = {0, &oneline[0]}; + + while (fgets(oneline, 1024, f) != NULL) { - char *pos; - if ((pos=strchr(oneline, '\n')) != NULL) + char* pos; + if ((pos = strchr(oneline, '\n')) != NULL) *pos = '\0'; - args.addArgs(2,argv); + args.addArgs(2, argv); } fclose(f); } - }; -void MyComboBoxCallback(int comboId, const char* item) +void MyComboBoxCallback(int comboId, const char* item) { //printf("comboId = %d, item = %s\n",comboId, item); - if (comboId==DEMO_SELECTION_COMBOBOX) + if (comboId == DEMO_SELECTION_COMBOBOX) { //find selected item - for (int i=0;itextOutput(msg); @@ -615,39 +585,35 @@ void MyGuiPrintf(const char* msg) } } - - void MyStatusBarPrintf(const char* msg) { printf("b3Printf: %s\n", msg); if (!gDisableDemoSelection && !gBlockGuiMessages) { bool isLeft = true; - gui2->setStatusBarMessage(msg,isLeft); + gui2->setStatusBarMessage(msg, isLeft); } } - void MyStatusBarError(const char* msg) { printf("Warning: %s\n", msg); if (!gDisableDemoSelection && !gBlockGuiMessages) { bool isLeft = false; - gui2->setStatusBarMessage(msg,isLeft); + gui2->setStatusBarMessage(msg, isLeft); gui2->textOutput(msg); gui2->forceUpdateScrollBars(); } - btAssert(0); - + btAssert(0); } -struct MyMenuItemHander :public Gwen::Event::Handler +struct MyMenuItemHander : public Gwen::Event::Handler { - int m_buttonId; + int m_buttonId; - MyMenuItemHander( int buttonId) - :m_buttonId(buttonId) + MyMenuItemHander(int buttonId) + : m_buttonId(buttonId) { } @@ -655,26 +621,26 @@ struct MyMenuItemHander :public Gwen::Event::Handler { //const Gwen::String& name = pControl->GetName(); Gwen::Controls::TreeNode* node = (Gwen::Controls::TreeNode*)pControl; - // Gwen::Controls::Label* l = node->GetButton(); + // Gwen::Controls::Label* l = node->GetButton(); - Gwen::UnicodeString la = node->GetButton()->GetText();// node->GetButton()->GetName();// GetText(); + Gwen::UnicodeString la = node->GetButton()->GetText(); // node->GetButton()->GetName();// GetText(); Gwen::String laa = Gwen::Utility::UnicodeToString(la); - // const char* ha = laa.c_str(); + // const char* ha = laa.c_str(); //printf("selected %s\n", ha); //int dep = but->IsDepressed(); //int tog = but->GetToggleState(); -// if (m_data->m_toggleButtonCallback) - // (*m_data->m_toggleButtonCallback)(m_buttonId, tog); + // if (m_data->m_toggleButtonCallback) + // (*m_data->m_toggleButtonCallback)(m_buttonId, tog); } void onButtonB(Gwen::Controls::Base* pControl) { - Gwen::Controls::Label* label = (Gwen::Controls::Label*) pControl; - Gwen::UnicodeString la = label->GetText();// node->GetButton()->GetName();// GetText(); + Gwen::Controls::Label* label = (Gwen::Controls::Label*)pControl; + Gwen::UnicodeString la = label->GetText(); // node->GetButton()->GetName();// GetText(); Gwen::String laa = Gwen::Utility::UnicodeToString(la); //const char* ha = laa.c_str(); - if (!gDisableDemoSelection ) + if (!gDisableDemoSelection) { selectDemo(sCurrentHightlighted); saveCurrentSettings(sCurrentDemoIndex, startFileName); @@ -693,24 +659,23 @@ struct MyMenuItemHander :public Gwen::Event::Handler } void onButtonD(Gwen::Controls::Base* pControl) { -/* Gwen::Controls::Label* label = (Gwen::Controls::Label*) pControl; + /* Gwen::Controls::Label* label = (Gwen::Controls::Label*) pControl; Gwen::UnicodeString la = label->GetText();// node->GetButton()->GetName();// GetText(); Gwen::String laa = Gwen::Utility::UnicodeToString(la); const char* ha = laa.c_str(); */ - // printf("onKeyReturn ! \n"); - if (!gDisableDemoSelection ) + // printf("onKeyReturn ! \n"); + if (!gDisableDemoSelection) { selectDemo(sCurrentHightlighted); saveCurrentSettings(sCurrentDemoIndex, startFileName); } - } void onButtonE(Gwen::Controls::Base* pControl) { - // printf("select %d\n",m_buttonId); + // printf("select %d\n",m_buttonId); sCurrentHightlighted = m_buttonId; gui2->setExampleDescription(gAllExamples->getExampleDescription(sCurrentHightlighted)); } @@ -724,28 +689,23 @@ struct MyMenuItemHander :public Gwen::Event::Handler { //printf("onButtonG !\n"); } - - - }; void quitCallback() { - - s_window->setRequestExit(); + s_window->setRequestExit(); } void fileOpenCallback() { - - char filename[1024]; - int len = s_window->fileOpenDialog(filename,1024); - if (len) - { - //todo(erwincoumans) check if it is actually URDF - //printf("file open:%s\n", filename); - openFileDemo(filename); - } + char filename[1024]; + int len = s_window->fileOpenDialog(filename, 1024); + if (len) + { + //todo(erwincoumans) check if it is actually URDF + //printf("file open:%s\n", filename); + openFileDemo(filename); + } } #define MAX_GRAPH_WINDOWS 5 @@ -757,13 +717,12 @@ struct QuickCanvas : public Common2dCanvasInterface MyGraphWindow* m_gw[MAX_GRAPH_WINDOWS]; GraphingTexture* m_gt[MAX_GRAPH_WINDOWS]; int m_curNumGraphWindows; - QuickCanvas(GL3TexLoader* myTexLoader) - :m_myTexLoader(myTexLoader), - m_curNumGraphWindows(0) + : m_myTexLoader(myTexLoader), + m_curNumGraphWindows(0) { - for (int i=0;i=MAX_GRAPH_WINDOWS) - return 0;//don't crash - + btAssert(slot < MAX_GRAPH_WINDOWS); + if (slot >= MAX_GRAPH_WINDOWS) + return 0; //don't crash + m_curNumGraphWindows++; MyGraphInput input(gui2->getInternalData()); - input.m_width=width; - input.m_height=height; + input.m_width = width; + input.m_height = height; input.m_xPos = xPos; input.m_yPos = yPos; - input.m_name=canvasName; + input.m_name = canvasName; input.m_texName = canvasName; m_gt[slot] = new GraphingTexture; - m_gt[slot]->create(width,height); + m_gt[slot]->create(width, height); int texId = m_gt[slot]->getTextureId(); m_myTexLoader->m_hashMap.insert(canvasName, texId); m_gw[slot] = setupTextureWindow(input); - + return slot; } return -1; } virtual void destroyCanvas(int canvasId) { - btAssert(canvasId>=0); + btAssert(canvasId >= 0); delete m_gt[canvasId]; m_gt[canvasId] = 0; destroyTextureWindow(m_gw[canvasId]); m_gw[canvasId] = 0; m_curNumGraphWindows--; } - virtual void setPixel(int canvasId, int x, int y, unsigned char red, unsigned char green,unsigned char blue, unsigned char alpha) + virtual void setPixel(int canvasId, int x, int y, unsigned char red, unsigned char green, unsigned char blue, unsigned char alpha) { - btAssert(canvasId>=0); - btAssert(canvasIdsetPixel(x,y,red,green,blue,alpha); + btAssert(canvasId >= 0); + btAssert(canvasId < m_curNumGraphWindows); + m_gt[canvasId]->setPixel(x, y, red, green, blue, alpha); } - - virtual void getPixel(int canvasId, int x, int y, unsigned char& red, unsigned char& green,unsigned char& blue, unsigned char& alpha) + + virtual void getPixel(int canvasId, int x, int y, unsigned char& red, unsigned char& green, unsigned char& blue, unsigned char& alpha) { - btAssert(canvasId>=0); - btAssert(canvasIdgetPixel(x,y,red,green,blue,alpha); + btAssert(canvasId >= 0); + btAssert(canvasId < m_curNumGraphWindows); + m_gt[canvasId]->getPixel(x, y, red, green, blue, alpha); } - + virtual void refreshImageData(int canvasId) { m_gt[canvasId]->uploadImageData(); } }; - OpenGLExampleBrowser::OpenGLExampleBrowser(class ExampleEntries* examples) { m_internalData = new OpenGLExampleBrowserInternalData; @@ -860,41 +818,26 @@ OpenGLExampleBrowser::~OpenGLExampleBrowser() #endif m_internalData->m_gui->exit(); - - - delete m_internalData->m_gui; delete m_internalData->m_gwenRenderer; delete m_internalData->m_myTexLoader; - - - - delete m_internalData->m_app; s_app = 0; - - - - delete m_internalData; - + gFileImporterByExtension.clear(); gAllExamples = 0; - - } - - #include "EmptyExample.h" bool OpenGLExampleBrowser::init(int argc, char* argv[]) { - b3CommandLineArgs args(argc,argv); - + b3CommandLineArgs args(argc, argv); + loadCurrentSettings(startFileName, args); if (args.CheckCmdLineFlag("nogui")) { @@ -905,9 +848,9 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[]) { b3ChromeUtilsStartTimings(); } - args.GetCmdLineArgument("fixed_timestep",gFixedTimeStep); - args.GetCmdLineArgument("png_skip_frames", gPngSkipFrames); - ///The OpenCL rigid body pipeline is experimental and + args.GetCmdLineArgument("fixed_timestep", gFixedTimeStep); + args.GetCmdLineArgument("png_skip_frames", gPngSkipFrames); + ///The OpenCL rigid body pipeline is experimental and ///most OpenCL drivers and OpenCL compilers have issues with our kernels. ///If you have a high-end desktop GPU such as AMD 7970 or better, or NVIDIA GTX 680 with up-to-date drivers ///you could give it a try @@ -917,35 +860,34 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[]) enable_experimental_opencl = true; gAllExamples->initOpenCLExampleEntries(); } - + if (args.CheckCmdLineFlag("disable_retina")) { gAllowRetina = false; } - - + int width = 1024; - int height=768; + int height = 768; if (args.CheckCmdLineFlag("width")) { - args.GetCmdLineArgument("width",width ); + args.GetCmdLineArgument("width", width); } if (args.CheckCmdLineFlag("height")) { - args.GetCmdLineArgument("height",height); + args.GetCmdLineArgument("height", height); } #ifndef NO_OPENGL3 - SimpleOpenGL3App* simpleApp=0; - sUseOpenGL2 = args.CheckCmdLineFlag("opengl2"); - args.GetCmdLineArgument("render_device", gRenderDevice); - args.GetCmdLineArgument("window_backend", gWindowBackend); + SimpleOpenGL3App* simpleApp = 0; + sUseOpenGL2 = args.CheckCmdLineFlag("opengl2"); + args.GetCmdLineArgument("render_device", gRenderDevice); + args.GetCmdLineArgument("window_backend", gWindowBackend); #else sUseOpenGL2 = true; #endif const char* appTitle = "Bullet Physics ExampleBrowser"; -#if defined (_DEBUG) || defined (DEBUG) +#if defined(_DEBUG) || defined(DEBUG) const char* optMode = "Debug build (slow)"; #else const char* optMode = "Release build"; @@ -957,40 +899,40 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[]) const char* glContext = "[btgl]"; #endif - if (sUseOpenGL2 ) - { + if (sUseOpenGL2) + { char title[1024]; - sprintf(title,"%s using limited OpenGL2 fallback %s %s", appTitle,glContext, optMode); - s_app = new SimpleOpenGL2App(title,width,height); - s_app->m_renderer = new SimpleOpenGL2Renderer(width,height); - } + sprintf(title, "%s using limited OpenGL2 fallback %s %s", appTitle, glContext, optMode); + s_app = new SimpleOpenGL2App(title, width, height); + s_app->m_renderer = new SimpleOpenGL2Renderer(width, height); + } #ifndef NO_OPENGL3 else - { + { char title[1024]; - sprintf(title,"%s using OpenGL3+ %s %s", appTitle,glContext, optMode); - simpleApp = new SimpleOpenGL3App(title,width,height, gAllowRetina, gWindowBackend, gRenderDevice); - s_app = simpleApp; - } + sprintf(title, "%s using OpenGL3+ %s %s", appTitle, glContext, optMode); + simpleApp = new SimpleOpenGL3App(title, width, height, gAllowRetina, gWindowBackend, gRenderDevice); + s_app = simpleApp; + } #endif m_internalData->m_app = s_app; - char* gVideoFileName = 0; - args.GetCmdLineArgument("mp4",gVideoFileName); - #ifndef NO_OPENGL3 - if (gVideoFileName) - simpleApp->dumpFramesToVideo(gVideoFileName); - #endif - - s_instancingRenderer = s_app->m_renderer; - s_window = s_app->m_window; + char* gVideoFileName = 0; + args.GetCmdLineArgument("mp4", gVideoFileName); +#ifndef NO_OPENGL3 + if (gVideoFileName) + simpleApp->dumpFramesToVideo(gVideoFileName); +#endif - width = s_window->getWidth(); - height = s_window->getHeight(); - - prevMouseMoveCallback = s_window->getMouseMoveCallback(); + s_instancingRenderer = s_app->m_renderer; + s_window = s_app->m_window; + + width = s_window->getWidth(); + height = s_window->getHeight(); + + prevMouseMoveCallback = s_window->getMouseMoveCallback(); s_window->setMouseMoveCallback(MyMouseMoveCallback); - + prevMouseButtonCallback = s_window->getMouseButtonCallback(); s_window->setMouseButtonCallback(MyMouseButtonCallback); prevKeyboardCallback = s_window->getKeyboardCallback(); @@ -998,44 +940,39 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[]) s_app->m_renderer->getActiveCamera()->setCameraDistance(13); s_app->m_renderer->getActiveCamera()->setCameraPitch(0); - s_app->m_renderer->getActiveCamera()->setCameraTargetPosition(0,0,0); + s_app->m_renderer->getActiveCamera()->setCameraTargetPosition(0, 0, 0); - float mouseMoveMult= s_app->getMouseMoveMultiplier(); + float mouseMoveMult = s_app->getMouseMoveMultiplier(); if (args.GetCmdLineArgument("mouse_move_multiplier", mouseMoveMult)) { s_app->setMouseMoveMultiplier(mouseMoveMult); } - - float mouseWheelMult= s_app->getMouseWheelMultiplier(); - if (args.GetCmdLineArgument("mouse_wheel_multiplier",mouseWheelMult)) + float mouseWheelMult = s_app->getMouseWheelMultiplier(); + if (args.GetCmdLineArgument("mouse_wheel_multiplier", mouseWheelMult)) { s_app->setMouseWheelMultiplier(mouseWheelMult); } - args.GetCmdLineArgument("shared_memory_key", gSharedMemoryKey); - - float red,green,blue; - s_app->getBackgroundColor(&red,&green,&blue); - args.GetCmdLineArgument("background_color_red",red); - args.GetCmdLineArgument("background_color_green",green); - args.GetCmdLineArgument("background_color_blue",blue); - s_app->setBackgroundColor(red,green,blue); + + float red, green, blue; + s_app->getBackgroundColor(&red, &green, &blue); + args.GetCmdLineArgument("background_color_red", red); + args.GetCmdLineArgument("background_color_green", green); + args.GetCmdLineArgument("background_color_blue", blue); + s_app->setBackgroundColor(red, green, blue); b3SetCustomWarningMessageFunc(MyGuiPrintf); b3SetCustomPrintfFunc(MyGuiPrintf); b3SetCustomErrorMessageFunc(MyStatusBarError); - - - assert(glGetError()==GL_NO_ERROR); - + assert(glGetError() == GL_NO_ERROR); + { GL3TexLoader* myTexLoader = new GL3TexLoader; m_internalData->m_myTexLoader = myTexLoader; - if (sUseOpenGL2) { m_internalData->m_gwenRenderer = new Gwen::Renderer::OpenGL_DebugFont(s_window->getRetinaScale()); @@ -1049,173 +986,154 @@ bool OpenGLExampleBrowser::init(int argc, char* argv[]) #endif gui2 = new GwenUserInterface; - + m_internalData->m_gui = gui2; - + m_internalData->m_myTexLoader = myTexLoader; - - gui2->init(width, height, m_internalData->m_gwenRenderer, s_window->getRetinaScale()); - - } //gui = 0;// new GwenUserInterface; - + GL3TexLoader* myTexLoader = m_internalData->m_myTexLoader; // = myTexLoader; - - - + // if (gui2) { - - - - - // gui->getInternalData()->m_explorerPage Gwen::Controls::TreeControl* tree = gui2->getInternalData()->m_explorerTreeCtrl; - //gui->getInternalData()->pRenderer->setTextureLoader(myTexLoader); #ifndef BT_NO_PROFILE - s_profWindow= setupProfileWindow(gui2->getInternalData()); + s_profWindow = setupProfileWindow(gui2->getInternalData()); m_internalData->m_profWindow = s_profWindow; - profileWindowSetVisible(s_profWindow,false); -#endif //BT_NO_PROFILE + profileWindowSetVisible(s_profWindow, false); +#endif //BT_NO_PROFILE gui2->setFocus(); s_parameterInterface = s_app->m_parameterInterface = new GwenParameterInterface(gui2->getInternalData()); s_app->m_2dCanvasInterface = new QuickCanvas(myTexLoader); - - ///add some demos to the gAllExamples + ///add some demos to the gAllExamples - - int numDemos = gAllExamples->getNumRegisteredExamples(); + int numDemos = gAllExamples->getNumRegisteredExamples(); - //char nodeText[1024]; - //int curDemo = 0; - int selectedDemo = 0; - Gwen::Controls::TreeNode* curNode = tree; - m_internalData->m_handler2 = new MyMenuItemHander(-1); + //char nodeText[1024]; + //int curDemo = 0; + int selectedDemo = 0; + Gwen::Controls::TreeNode* curNode = tree; + m_internalData->m_handler2 = new MyMenuItemHander(-1); - char* demoNameFromCommandOption = 0; - args.GetCmdLineArgument("start_demo_name", demoNameFromCommandOption); - if (demoNameFromCommandOption) { - selectedDemo = -1; - } - - tree->onReturnKeyDown.Add(m_internalData->m_handler2, &MyMenuItemHander::onButtonD); - int firstAvailableDemoIndex=-1; - Gwen::Controls::TreeNode* firstNode=0; - - for (int d = 0; dgetExampleName(d)); - if (gAllExamples->getExampleCreateFunc(d))//was test for gAllExamples[d].m_menuLevel==1 + char* demoNameFromCommandOption = 0; + args.GetCmdLineArgument("start_demo_name", demoNameFromCommandOption); + if (demoNameFromCommandOption) { - Gwen::Controls::TreeNode* pNode = curNode->AddNode(nodeUText); - - if (firstAvailableDemoIndex<0) - { - firstAvailableDemoIndex = d; - firstNode = pNode; - } - - if (d == selectedDemo) - { - firstAvailableDemoIndex = d; - firstNode = pNode; - //pNode->SetSelected(true); - //tree->ExpandAll(); - // tree->ForceUpdateScrollBars(); - //tree->OnKeyLeft(true); - // tree->OnKeyRight(true); - - - //tree->ExpandAll(); + selectedDemo = -1; + } - // selectDemo(d); + tree->onReturnKeyDown.Add(m_internalData->m_handler2, &MyMenuItemHander::onButtonD); + int firstAvailableDemoIndex = -1; + Gwen::Controls::TreeNode* firstNode = 0; - - } - - if (demoNameFromCommandOption ) + for (int d = 0; d < numDemos; d++) + { + // sprintf(nodeText, "Node %d", i); + Gwen::UnicodeString nodeUText = Gwen::Utility::StringToUnicode(gAllExamples->getExampleName(d)); + if (gAllExamples->getExampleCreateFunc(d)) //was test for gAllExamples[d].m_menuLevel==1 { - const char* demoName = gAllExamples->getExampleName(d); - int res = strcmp(demoName, demoNameFromCommandOption); - if (res==0) + Gwen::Controls::TreeNode* pNode = curNode->AddNode(nodeUText); + + if (firstAvailableDemoIndex < 0) { firstAvailableDemoIndex = d; firstNode = pNode; } - } + + if (d == selectedDemo) + { + firstAvailableDemoIndex = d; + firstNode = pNode; + //pNode->SetSelected(true); + //tree->ExpandAll(); + // tree->ForceUpdateScrollBars(); + //tree->OnKeyLeft(true); + // tree->OnKeyRight(true); + + //tree->ExpandAll(); + + // selectDemo(d); + } + + if (demoNameFromCommandOption) + { + const char* demoName = gAllExamples->getExampleName(d); + int res = strcmp(demoName, demoNameFromCommandOption); + if (res == 0) + { + firstAvailableDemoIndex = d; + firstNode = pNode; + } + } #if 1 - MyMenuItemHander* handler = new MyMenuItemHander(d); - m_internalData->m_handlers.push_back(handler); - - pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonA); - pNode->GetButton()->onDoubleClick.Add(handler, &MyMenuItemHander::onButtonB); - pNode->GetButton()->onDown.Add(handler, &MyMenuItemHander::onButtonC); - pNode->onSelect.Add(handler, &MyMenuItemHander::onButtonE); - pNode->onReturnKeyDown.Add(handler, &MyMenuItemHander::onButtonG); - pNode->onSelectChange.Add(handler, &MyMenuItemHander::onButtonF); - + MyMenuItemHander* handler = new MyMenuItemHander(d); + m_internalData->m_handlers.push_back(handler); + + pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonA); + pNode->GetButton()->onDoubleClick.Add(handler, &MyMenuItemHander::onButtonB); + pNode->GetButton()->onDown.Add(handler, &MyMenuItemHander::onButtonC); + pNode->onSelect.Add(handler, &MyMenuItemHander::onButtonE); + pNode->onReturnKeyDown.Add(handler, &MyMenuItemHander::onButtonG); + pNode->onSelectChange.Add(handler, &MyMenuItemHander::onButtonF); + #endif -// pNode->onKeyReturn.Add(handler, &MyMenuItemHander::onButtonD); -// pNode->GetButton()->onKeyboardReturn.Add(handler, &MyMenuItemHander::onButtonD); - // pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonD); -// pNode->onKeyboardPressed.Add(handler, &MyMenuItemHander::onButtonD); -// pNode->OnKeyPress - } - else - { - curNode = tree->AddNode(nodeUText); - m_internalData->m_nodes.push_back(curNode); - } - } - - if (sCurrentDemo==0) - { - if (firstAvailableDemoIndex>=0) - { - firstNode->SetSelected(true); - while (firstNode != tree) - { - firstNode->ExpandAll(); - firstNode = (Gwen::Controls::TreeNode*)firstNode->GetParent(); + // pNode->onKeyReturn.Add(handler, &MyMenuItemHander::onButtonD); + // pNode->GetButton()->onKeyboardReturn.Add(handler, &MyMenuItemHander::onButtonD); + // pNode->onNamePress.Add(handler, &MyMenuItemHander::onButtonD); + // pNode->onKeyboardPressed.Add(handler, &MyMenuItemHander::onButtonD); + // pNode->OnKeyPress + } + else + { + curNode = tree->AddNode(nodeUText); + m_internalData->m_nodes.push_back(curNode); } - - selectDemo(firstAvailableDemoIndex); } - } - free(demoNameFromCommandOption); - demoNameFromCommandOption = 0; + if (sCurrentDemo == 0) + { + if (firstAvailableDemoIndex >= 0) + { + firstNode->SetSelected(true); + while (firstNode != tree) + { + firstNode->ExpandAll(); + firstNode = (Gwen::Controls::TreeNode*)firstNode->GetParent(); + } - btAssert(sCurrentDemo!=0); - if (sCurrentDemo==0) - { - printf("Error, no demo/example\n"); - exit(0); - } - - gui2->registerFileOpenCallback(fileOpenCallback); - gui2->registerQuitCallback(quitCallback); - } + selectDemo(firstAvailableDemoIndex); + } + } + free(demoNameFromCommandOption); + demoNameFromCommandOption = 0; + btAssert(sCurrentDemo != 0); + if (sCurrentDemo == 0) + { + printf("Error, no demo/example\n"); + exit(0); + } + + gui2->registerFileOpenCallback(fileOpenCallback); + gui2->registerQuitCallback(quitCallback); + } return true; } - CommonExampleInterface* OpenGLExampleBrowser::getCurrentExample() { btAssert(sCurrentDemo); @@ -1231,194 +1149,177 @@ void OpenGLExampleBrowser::updateGraphics() { if (sCurrentDemo) { - if (!pauseSimulation || singleStepSimulation) - { - //B3_PROFILE("sCurrentDemo->updateGraphics"); - sCurrentDemo->updateGraphics(); - } + if (!pauseSimulation || singleStepSimulation) + { + //B3_PROFILE("sCurrentDemo->updateGraphics"); + sCurrentDemo->updateGraphics(); + } } } void OpenGLExampleBrowser::update(float deltaTime) { - b3ChromeUtilsEnableProfiling(); + b3ChromeUtilsEnableProfiling(); - if (!gEnableRenderLoop && !singleStepSimulation) - { - sCurrentDemo->updateGraphics(); + if (!gEnableRenderLoop && !singleStepSimulation) + { + sCurrentDemo->updateGraphics(); return; - } - - B3_PROFILE("OpenGLExampleBrowser::update"); - assert(glGetError()==GL_NO_ERROR); - s_instancingRenderer->init(); - DrawGridData dg; - dg.upAxis = s_app->getUpAxis(); + } - { - BT_PROFILE("Update Camera and Light"); + B3_PROFILE("OpenGLExampleBrowser::update"); + assert(glGetError() == GL_NO_ERROR); + s_instancingRenderer->init(); + DrawGridData dg; + dg.upAxis = s_app->getUpAxis(); - + { + BT_PROFILE("Update Camera and Light"); - s_instancingRenderer->updateCamera(dg.upAxis); - } + s_instancingRenderer->updateCamera(dg.upAxis); + } - - static int frameCount = 0; - frameCount++; + static int frameCount = 0; + frameCount++; - if (0) + if (0) + { + BT_PROFILE("Draw frame counter"); + char bla[1024]; + sprintf(bla, "Frame %d", frameCount); + s_app->drawText(bla, 10, 10); + } + + if (gPngFileName) + { + static int skip = 0; + skip--; + if (skip < 0) { - BT_PROFILE("Draw frame counter"); - char bla[1024]; - sprintf(bla,"Frame %d", frameCount); - s_app->drawText(bla,10,10); + skip = gPngSkipFrames; + //printf("gPngFileName=%s\n",gPngFileName); + static int s_frameCount = 0; + + sprintf(staticPngFileName, "%s%d.png", gPngFileName, s_frameCount++); + //b3Printf("Made screenshot %s",staticPngFileName); + s_app->dumpNextFrameToPng(staticPngFileName); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } + } - if (gPngFileName) - { - - static int skip = 0; - skip--; - if (skip<0) - { - skip=gPngSkipFrames; - //printf("gPngFileName=%s\n",gPngFileName); - static int s_frameCount = 0; - - sprintf(staticPngFileName,"%s%d.png",gPngFileName,s_frameCount++); - //b3Printf("Made screenshot %s",staticPngFileName); - s_app->dumpNextFrameToPng(staticPngFileName); - glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - } - } - - - if (sCurrentDemo) + if (sCurrentDemo) + { + if (!pauseSimulation || singleStepSimulation) { - if (!pauseSimulation || singleStepSimulation) - { - - //printf("---------------------------------------------------\n"); - //printf("Framecount = %d\n",frameCount); - B3_PROFILE("sCurrentDemo->stepSimulation"); + //printf("---------------------------------------------------\n"); + //printf("Framecount = %d\n",frameCount); + B3_PROFILE("sCurrentDemo->stepSimulation"); - if (gFixedTimeStep>0) - { - - sCurrentDemo->stepSimulation(gFixedTimeStep); - } else - { - sCurrentDemo->stepSimulation(deltaTime);//1./60.f); - } + if (gFixedTimeStep > 0) + { + sCurrentDemo->stepSimulation(gFixedTimeStep); } - - if (renderGrid) - { - BT_PROFILE("Draw Grid"); - //glPolygonOffset(3.0, 3); - //glEnable(GL_POLYGON_OFFSET_FILL); - s_app->drawGrid(dg); - - } - if (renderVisualGeometry && ((gDebugDrawFlags&btIDebugDraw::DBG_DrawWireframe)==0)) - { - if (visualWireframe) - { - glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); - } - BT_PROFILE("Render Scene"); - sCurrentDemo->renderScene(); - } else - { - B3_PROFILE("physicsDebugDraw"); - glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); - sCurrentDemo->physicsDebugDraw(gDebugDrawFlags); - } - } - - - - { - - if (gui2 && s_guiHelper && s_guiHelper->getRenderInterface() && s_guiHelper->getRenderInterface()->getActiveCamera()) { - B3_PROFILE("setStatusBarMessage"); - char msg[1024]; - float camDist = s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraDistance(); - float pitch = s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraPitch(); - float yaw = s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraYaw(); - float camTarget[3]; - float camPos[3]; - s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraPosition(camPos); - s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraTargetPosition(camTarget); - sprintf(msg,"camTargetPos=%2.2f,%2.2f,%2.2f, dist=%2.2f, pitch=%2.2f, yaw=%2.2f", camTarget[0],camTarget[1],camTarget[2],camDist,pitch,yaw); - gui2->setStatusBarMessage(msg, true); + sCurrentDemo->stepSimulation(deltaTime); //1./60.f); } - } - static int toggle = 1; - if (renderGui) + if (renderGrid) { - B3_PROFILE("renderGui"); + BT_PROFILE("Draw Grid"); + //glPolygonOffset(3.0, 3); + //glEnable(GL_POLYGON_OFFSET_FILL); + s_app->drawGrid(dg); + } + if (renderVisualGeometry && ((gDebugDrawFlags & btIDebugDraw::DBG_DrawWireframe) == 0)) + { + if (visualWireframe) + { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + } + BT_PROFILE("Render Scene"); + sCurrentDemo->renderScene(); + } + else + { + B3_PROFILE("physicsDebugDraw"); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + sCurrentDemo->physicsDebugDraw(gDebugDrawFlags); + } + } + + { + if (gui2 && s_guiHelper && s_guiHelper->getRenderInterface() && s_guiHelper->getRenderInterface()->getActiveCamera()) + { + B3_PROFILE("setStatusBarMessage"); + char msg[1024]; + float camDist = s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraDistance(); + float pitch = s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraPitch(); + float yaw = s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraYaw(); + float camTarget[3]; + float camPos[3]; + s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraPosition(camPos); + s_guiHelper->getRenderInterface()->getActiveCamera()->getCameraTargetPosition(camTarget); + sprintf(msg, "camTargetPos=%2.2f,%2.2f,%2.2f, dist=%2.2f, pitch=%2.2f, yaw=%2.2f", camTarget[0], camTarget[1], camTarget[2], camDist, pitch, yaw); + gui2->setStatusBarMessage(msg, true); + } + } + + static int toggle = 1; + if (renderGui) + { + B3_PROFILE("renderGui"); #ifndef BT_NO_PROFILE - if (!pauseSimulation || singleStepSimulation) - { - if (isProfileWindowVisible(s_profWindow)) - { - processProfileData(s_profWindow,false); - } - } -#endif //#ifndef BT_NO_PROFILE - - - if (sUseOpenGL2) - { - - saveOpenGLState(s_instancingRenderer->getScreenWidth()*s_window->getRetinaScale(), s_instancingRenderer->getScreenHeight()*s_window->getRetinaScale()); - } - - if (m_internalData->m_gui) - { - gBlockGuiMessages = true; - m_internalData->m_gui->draw(s_instancingRenderer->getScreenWidth(), s_instancingRenderer->getScreenHeight()); - - - gBlockGuiMessages = false; - } - - if (sUseOpenGL2) - { - restoreOpenGLState(); - } - - } - - singleStepSimulation = false; - - - toggle=1-toggle; - { - BT_PROFILE("Sync Parameters"); - if (s_parameterInterface) - { - s_parameterInterface->syncParameters(); - } - } - { - BT_PROFILE("Swap Buffers"); - s_app->swapBuffer(); - } - - if (gui2) + if (!pauseSimulation || singleStepSimulation) { - B3_PROFILE("forceUpdateScrollBars"); - gui2->forceUpdateScrollBars(); + if (isProfileWindowVisible(s_profWindow)) + { + processProfileData(s_profWindow, false); + } + } +#endif //#ifndef BT_NO_PROFILE + + if (sUseOpenGL2) + { + saveOpenGLState(s_instancingRenderer->getScreenWidth() * s_window->getRetinaScale(), s_instancingRenderer->getScreenHeight() * s_window->getRetinaScale()); } + if (m_internalData->m_gui) + { + gBlockGuiMessages = true; + m_internalData->m_gui->draw(s_instancingRenderer->getScreenWidth(), s_instancingRenderer->getScreenHeight()); + + gBlockGuiMessages = false; + } + + if (sUseOpenGL2) + { + restoreOpenGLState(); + } + } + + singleStepSimulation = false; + + toggle = 1 - toggle; + { + BT_PROFILE("Sync Parameters"); + if (s_parameterInterface) + { + s_parameterInterface->syncParameters(); + } + } + { + BT_PROFILE("Swap Buffers"); + s_app->swapBuffer(); + } + + if (gui2) + { + B3_PROFILE("forceUpdateScrollBars"); + gui2->forceUpdateScrollBars(); + } } void OpenGLExampleBrowser::setSharedMemoryInterface(class SharedMemoryInterface* sharedMem) diff --git a/examples/ExampleBrowser/OpenGLExampleBrowser.h b/examples/ExampleBrowser/OpenGLExampleBrowser.h index 533b666ff..df26f9e4f 100644 --- a/examples/ExampleBrowser/OpenGLExampleBrowser.h +++ b/examples/ExampleBrowser/OpenGLExampleBrowser.h @@ -5,16 +5,14 @@ class OpenGLExampleBrowser : public ExampleBrowserInterface { - struct OpenGLExampleBrowserInternalData* m_internalData; public: - OpenGLExampleBrowser(class ExampleEntries* examples); virtual ~OpenGLExampleBrowser(); - + virtual CommonExampleInterface* getCurrentExample(); - + virtual bool init(int argc, char* argv[]); virtual void update(float deltaTime); @@ -24,8 +22,8 @@ public: virtual bool requestedExit(); virtual void setSharedMemoryInterface(class SharedMemoryInterface* sharedMem); - - static void registerFileImporter(const char* extension, CommonExampleInterface::CreateFunc* createFunc); + + static void registerFileImporter(const char* extension, CommonExampleInterface::CreateFunc* createFunc); }; -#endif //OPENGL_BROWSER_GUI_H +#endif //OPENGL_BROWSER_GUI_H diff --git a/examples/ExampleBrowser/OpenGLGuiHelper.cpp b/examples/ExampleBrowser/OpenGLGuiHelper.cpp index 536843450..33de3d05a 100644 --- a/examples/ExampleBrowser/OpenGLGuiHelper.cpp +++ b/examples/ExampleBrowser/OpenGLGuiHelper.cpp @@ -17,9 +17,9 @@ struct MyDebugVec3 { MyDebugVec3(const btVector3& org) - :x(org.x()), - y(org.y()), - z(org.z()) + : x(org.x()), + y(org.y()), + z(org.z()) { } @@ -28,130 +28,118 @@ struct MyDebugVec3 float z; }; -ATTRIBUTE_ALIGNED16( class )MyDebugDrawer : public btIDebugDraw +ATTRIBUTE_ALIGNED16(class) +MyDebugDrawer : public btIDebugDraw { CommonGraphicsApp* m_glApp; int m_debugMode; - btAlignedObjectArray m_linePoints; - btAlignedObjectArray m_lineIndices; + btAlignedObjectArray m_linePoints; + btAlignedObjectArray m_lineIndices; - - btVector3 m_currentLineColor; + btVector3 m_currentLineColor; DefaultColors m_ourColors; public: BT_DECLARE_ALIGNED_ALLOCATOR(); - MyDebugDrawer(CommonGraphicsApp* app) - : m_glApp(app) - ,m_debugMode(btIDebugDraw::DBG_DrawWireframe|btIDebugDraw::DBG_DrawAabb), - m_currentLineColor(-1,-1,-1) + MyDebugDrawer(CommonGraphicsApp * app) + : m_glApp(app), m_debugMode(btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb), m_currentLineColor(-1, -1, -1) { - - } virtual ~MyDebugDrawer() { } - virtual DefaultColors getDefaultColors() const - { + virtual DefaultColors getDefaultColors() const + { return m_ourColors; } ///the default implementation for setDefaultColors has no effect. A derived class can implement it and store the colors. - virtual void setDefaultColors(const DefaultColors& colors) + virtual void setDefaultColors(const DefaultColors& colors) { m_ourColors = colors; } - - virtual void drawLine(const btVector3& from1,const btVector3& to1,const btVector3& color1) + virtual void drawLine(const btVector3& from1, const btVector3& to1, const btVector3& color1) { - //float from[4] = {from1[0],from1[1],from1[2],from1[3]}; - //float to[4] = {to1[0],to1[1],to1[2],to1[3]}; - //float color[4] = {color1[0],color1[1],color1[2],color1[3]}; + //float from[4] = {from1[0],from1[1],from1[2],from1[3]}; + //float to[4] = {to1[0],to1[1],to1[2],to1[3]}; + //float color[4] = {color1[0],color1[1],color1[2],color1[3]}; //m_glApp->m_instancingRenderer->drawLine(from,to,color); - if (m_currentLineColor!=color1 || m_linePoints.size() >= BT_LINE_BATCH_SIZE) - { - flushLines(); - m_currentLineColor = color1; - } + if (m_currentLineColor != color1 || m_linePoints.size() >= BT_LINE_BATCH_SIZE) + { + flushLines(); + m_currentLineColor = color1; + } MyDebugVec3 from(from1); MyDebugVec3 to(to1); - + m_linePoints.push_back(from); m_linePoints.push_back(to); m_lineIndices.push_back(m_lineIndices.size()); m_lineIndices.push_back(m_lineIndices.size()); - } - virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color) + virtual void drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color) { - drawLine(PointOnB,PointOnB+normalOnB*distance,color); + drawLine(PointOnB, PointOnB + normalOnB * distance, color); btVector3 ncolor(0, 0, 0); - drawLine(PointOnB, PointOnB + normalOnB*0.01, ncolor); - + drawLine(PointOnB, PointOnB + normalOnB * 0.01, ncolor); } - - virtual void reportErrorWarning(const char* warningString) + virtual void reportErrorWarning(const char* warningString) { } - virtual void draw3dText(const btVector3& location,const char* textString) + virtual void draw3dText(const btVector3& location, const char* textString) { } - virtual void setDebugMode(int debugMode) + virtual void setDebugMode(int debugMode) { m_debugMode = debugMode; } - virtual int getDebugMode() const + virtual int getDebugMode() const { return m_debugMode; } - virtual void flushLines() + virtual void flushLines() { - int sz = m_linePoints.size(); - if (sz) - { + int sz = m_linePoints.size(); + if (sz) + { float debugColor[4]; - debugColor[0] = m_currentLineColor.x(); - debugColor[1] = m_currentLineColor.y(); - debugColor[2] = m_currentLineColor.z(); - debugColor[3] = 1.f; - m_glApp->m_renderer->drawLines(&m_linePoints[0].x,debugColor, - m_linePoints.size(),sizeof(MyDebugVec3), - &m_lineIndices[0], - m_lineIndices.size(), - 1); - m_linePoints.clear(); - m_lineIndices.clear(); - } + debugColor[0] = m_currentLineColor.x(); + debugColor[1] = m_currentLineColor.y(); + debugColor[2] = m_currentLineColor.z(); + debugColor[3] = 1.f; + m_glApp->m_renderer->drawLines(&m_linePoints[0].x, debugColor, + m_linePoints.size(), sizeof(MyDebugVec3), + &m_lineIndices[0], + m_lineIndices.size(), + 1); + m_linePoints.clear(); + m_lineIndices.clear(); + } } - }; static btVector4 sColors[4] = -{ - btVector4(60./256.,186./256.,84./256.,1), - btVector4(244./256.,194./256.,13./256.,1), - btVector4(219./256.,50./256.,54./256.,1), - btVector4(72./256.,133./256.,237./256.,1), + { + btVector4(60. / 256., 186. / 256., 84. / 256., 1), + btVector4(244. / 256., 194. / 256., 13. / 256., 1), + btVector4(219. / 256., 50. / 256., 54. / 256., 1), + btVector4(72. / 256., 133. / 256., 237. / 256., 1), - //btVector4(1,1,0,1), + //btVector4(1,1,0,1), }; - - struct MyHashShape { - int m_shapeKey; int m_shapeType; btVector3 m_sphere0Pos; @@ -164,42 +152,47 @@ struct MyHashShape btScalar m_halfHeight; MyHashShape() - :m_shapeKey(0), - m_shapeType(0), - m_sphere0Pos(btVector3(0,0,0)), - m_sphere1Pos(btVector3(0,0,0)), - m_radius0(0), - m_radius1(0), - m_deformFunc(0), - m_upAxis(-1), - m_halfHeight(0) + : m_shapeKey(0), + m_shapeType(0), + m_sphere0Pos(btVector3(0, 0, 0)), + m_sphere1Pos(btVector3(0, 0, 0)), + m_radius0(0), + m_radius1(0), + m_deformFunc(0), + m_upAxis(-1), + m_halfHeight(0) { m_childTransform.setIdentity(); } bool equals(const MyHashShape& other) const { - bool sameShapeType = m_shapeType==other.m_shapeType; - bool sameSphere0= m_sphere0Pos == other.m_sphere0Pos; - bool sameSphere1= m_sphere1Pos == other.m_sphere1Pos; - bool sameRadius0 = m_radius0== other.m_radius0; - bool sameRadius1 = m_radius1== other.m_radius1; - bool sameTransform = m_childTransform== other.m_childTransform; + bool sameShapeType = m_shapeType == other.m_shapeType; + bool sameSphere0 = m_sphere0Pos == other.m_sphere0Pos; + bool sameSphere1 = m_sphere1Pos == other.m_sphere1Pos; + bool sameRadius0 = m_radius0 == other.m_radius0; + bool sameRadius1 = m_radius1 == other.m_radius1; + bool sameTransform = m_childTransform == other.m_childTransform; bool sameUpAxis = m_upAxis == other.m_upAxis; bool sameHalfHeight = m_halfHeight == other.m_halfHeight; return sameShapeType && sameSphere0 && sameSphere1 && sameRadius0 && sameRadius1 && sameTransform && sameUpAxis && sameHalfHeight; } //to our success - SIMD_FORCE_INLINE unsigned int getHash()const + SIMD_FORCE_INLINE unsigned int getHash() const { unsigned int key = m_shapeKey; // Thomas Wang's hash - key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16); - + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); + return key; } }; - + struct OpenGLGuiHelperInternalData { struct CommonGraphicsApp* m_glApp; @@ -211,21 +204,19 @@ struct OpenGLGuiHelperInternalData btAlignedObjectArray m_depthBuffer1; btHashMap m_hashShapes; - VisualizerFlagCallback m_visualizerFlagCallback; int m_checkedTexture; int m_checkedTextureGrey; OpenGLGuiHelperInternalData() - :m_vrMode(false), - m_vrSkipShadowPass(0), - m_visualizerFlagCallback(0), - m_checkedTexture(-1), - m_checkedTextureGrey(-1) + : m_vrMode(false), + m_vrSkipShadowPass(0), + m_visualizerFlagCallback(0), + m_checkedTexture(-1), + m_checkedTextureGrey(-1) { } - }; void OpenGLGuiHelper::setVRMode(bool vrMode) @@ -234,15 +225,11 @@ void OpenGLGuiHelper::setVRMode(bool vrMode) m_data->m_vrSkipShadowPass = 0; } - - OpenGLGuiHelper::OpenGLGuiHelper(CommonGraphicsApp* glApp, bool useOpenGL2) { m_data = new OpenGLGuiHelperInternalData; m_data->m_glApp = glApp; m_data->m_debugDraw = 0; - - } OpenGLGuiHelper::~OpenGLGuiHelper() @@ -264,78 +251,73 @@ const struct CommonRenderInterface* OpenGLGuiHelper::getRenderInterface() const void OpenGLGuiHelper::createRigidBodyGraphicsObject(btRigidBody* body, const btVector3& color) { - createCollisionObjectGraphicsObject(body,color); + createCollisionObjectGraphicsObject(body, color); } void OpenGLGuiHelper::createCollisionObjectGraphicsObject(btCollisionObject* body, const btVector3& color) { - if (body->getUserIndex()<0) + if (body->getUserIndex() < 0) { btCollisionShape* shape = body->getCollisionShape(); btTransform startTransform = body->getWorldTransform(); int graphicsShapeId = shape->getUserIndex(); - if (graphicsShapeId>=0) + if (graphicsShapeId >= 0) { - // btAssert(graphicsShapeId >= 0); + // btAssert(graphicsShapeId >= 0); //the graphics shape is already scaled - btVector3 localScaling(1,1,1); + btVector3 localScaling(1, 1, 1); int graphicsInstanceId = m_data->m_glApp->m_renderer->registerGraphicsInstance(graphicsShapeId, startTransform.getOrigin(), startTransform.getRotation(), color, localScaling); body->setUserIndex(graphicsInstanceId); } } } -int OpenGLGuiHelper::registerTexture(const unsigned char* texels, int width, int height) +int OpenGLGuiHelper::registerTexture(const unsigned char* texels, int width, int height) { - int textureId = m_data->m_glApp->m_renderer->registerTexture(texels,width,height); + int textureId = m_data->m_glApp->m_renderer->registerTexture(texels, width, height); return textureId; } - void OpenGLGuiHelper::removeTexture(int textureUid) { m_data->m_glApp->m_renderer->removeTexture(textureUid); } - - - void OpenGLGuiHelper::changeTexture(int textureUniqueId, const unsigned char* rgbTexels, int width, int height) { bool flipPixelsY = true; - m_data->m_glApp->m_renderer->updateTexture(textureUniqueId, rgbTexels,flipPixelsY); + m_data->m_glApp->m_renderer->updateTexture(textureUniqueId, rgbTexels, flipPixelsY); } - -int OpenGLGuiHelper::registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType, int textureId) +int OpenGLGuiHelper::registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices, int primitiveType, int textureId) { if (textureId == -2) { - if (m_data->m_checkedTextureGrey<0) + if (m_data->m_checkedTextureGrey < 0) { m_data->m_checkedTextureGrey = createCheckeredTexture(192, 192, 192); } textureId = m_data->m_checkedTextureGrey; } - int shapeId = m_data->m_glApp->m_renderer->registerShape(vertices, numvertices,indices,numIndices,primitiveType, textureId); + int shapeId = m_data->m_glApp->m_renderer->registerShape(vertices, numvertices, indices, numIndices, primitiveType, textureId); return shapeId; } int OpenGLGuiHelper::registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling) { - return m_data->m_glApp->m_renderer->registerGraphicsInstance(shapeIndex,position,quaternion,color,scaling); + return m_data->m_glApp->m_renderer->registerGraphicsInstance(shapeIndex, position, quaternion, color, scaling); } void OpenGLGuiHelper::removeAllGraphicsInstances() { m_data->m_hashShapes.clear(); - m_data->m_glApp->m_renderer->removeAllInstances(); + m_data->m_glApp->m_renderer->removeAllInstances(); } void OpenGLGuiHelper::removeGraphicsInstance(int graphicsUid) { - if (graphicsUid>=0) + if (graphicsUid >= 0) { m_data->m_glApp->m_renderer->removeGraphicsInstance(graphicsUid); }; @@ -348,85 +330,81 @@ int OpenGLGuiHelper::getShapeIndexFromInstance(int instanceUid) void OpenGLGuiHelper::replaceTexture(int shapeIndex, int textureUid) { - if (shapeIndex>=0) + if (shapeIndex >= 0) { m_data->m_glApp->m_renderer->replaceTexture(shapeIndex, textureUid); }; } void OpenGLGuiHelper::changeRGBAColor(int instanceUid, const double rgbaColor[4]) { - if (instanceUid>=0) + if (instanceUid >= 0) { - m_data->m_glApp->m_renderer->writeSingleInstanceColorToCPU(rgbaColor,instanceUid); + m_data->m_glApp->m_renderer->writeSingleInstanceColorToCPU(rgbaColor, instanceUid); }; } void OpenGLGuiHelper::changeSpecularColor(int instanceUid, const double specularColor[3]) { - if (instanceUid>=0) + if (instanceUid >= 0) { - m_data->m_glApp->m_renderer->writeSingleInstanceSpecularColorToCPU(specularColor,instanceUid); + m_data->m_glApp->m_renderer->writeSingleInstanceSpecularColorToCPU(specularColor, instanceUid); }; } -int OpenGLGuiHelper::createCheckeredTexture(int red,int green, int blue) +int OpenGLGuiHelper::createCheckeredTexture(int red, int green, int blue) { - int texWidth=1024; - int texHeight=1024; - btAlignedObjectArray texels; - texels.resize(texWidth*texHeight*3); - for (int i=0;i texels; + texels.resize(texWidth * texHeight * 3); + for (int i = 0; i < texWidth * texHeight * 3; i++) + texels[i] = 255; + + for (int i = 0; i < texWidth; i++) + { + for (int j = 0; j < texHeight; j++) { - for (int j=0;jgetUserIndex()>=0) + if (collisionShape->getUserIndex() >= 0) return; - if (m_data->m_checkedTexture<0) + if (m_data->m_checkedTexture < 0) { - m_data->m_checkedTexture = createCheckeredTexture(192,192,255); + m_data->m_checkedTexture = createCheckeredTexture(192, 192, 255); } - if (m_data->m_checkedTextureGrey<0) + if (m_data->m_checkedTextureGrey < 0) { - m_data->m_checkedTextureGrey = createCheckeredTexture(192,192,192); + m_data->m_checkedTextureGrey = createCheckeredTexture(192, 192, 192); } - btAlignedObjectArray gfxVertices; btAlignedObjectArray indices; - int strideInBytes = 9*sizeof(float); + int strideInBytes = 9 * sizeof(float); //if (collisionShape->getShapeType()==BOX_SHAPE_PROXYTYPE) { } @@ -437,269 +415,264 @@ void OpenGLGuiHelper::createCollisionShapeGraphicsObject(btCollisionShape* colli { int shapeId = registerGraphicsShape(&gfxVertices[0].xyzw[0], gfxVertices.size(), &indices[0], indices.size(), B3_GL_TRIANGLES, m_data->m_checkedTexture); - + b3Assert(shapeId >= 0); collisionShape->setUserIndex(shapeId); } } - if (collisionShape->getShapeType()==MULTI_SPHERE_SHAPE_PROXYTYPE) + if (collisionShape->getShapeType() == MULTI_SPHERE_SHAPE_PROXYTYPE) { - btMultiSphereShape* ms = (btMultiSphereShape*) collisionShape; - if (ms->getSphereCount()==2) + btMultiSphereShape* ms = (btMultiSphereShape*)collisionShape; + if (ms->getSphereCount() == 2) { btAlignedObjectArray transformedVertices; - int numVertices = sizeof(textured_detailed_sphere_vertices)/strideInBytes; - transformedVertices.resize(numVertices*9); + int numVertices = sizeof(textured_detailed_sphere_vertices) / strideInBytes; + transformedVertices.resize(numVertices * 9); btVector3 sphere0Pos = ms->getSpherePosition(0); btVector3 sphere1Pos = ms->getSpherePosition(1); - btVector3 fromTo = sphere1Pos-sphere0Pos; + btVector3 fromTo = sphere1Pos - sphere0Pos; MyHashShape shape; shape.m_sphere0Pos = sphere0Pos; shape.m_sphere1Pos = sphere1Pos; - shape.m_radius0 = 2.*ms->getSphereRadius(0); - shape.m_radius1 = 2.*ms->getSphereRadius(1); - shape.m_deformFunc = 1;//vert.dot(fromTo) + shape.m_radius0 = 2. * ms->getSphereRadius(0); + shape.m_radius1 = 2. * ms->getSphereRadius(1); + shape.m_deformFunc = 1; //vert.dot(fromTo) int graphicsShapeIndex = -1; int* graphicsShapeIndexPtr = m_data->m_hashShapes[shape]; - + if (graphicsShapeIndexPtr) { //cache hit graphicsShapeIndex = *graphicsShapeIndexPtr; - } else + } + else { //cache miss - for (int i=0;i0) + if (vert.dot(fromTo) > 0) { - btScalar radiusScale = 2.*ms->getSphereRadius(1); - trVer = radiusScale*vert; - trVer+=sphere1Pos; - } else + btScalar radiusScale = 2. * ms->getSphereRadius(1); + trVer = radiusScale * vert; + trVer += sphere1Pos; + } + else { - btScalar radiusScale = 2.*ms->getSphereRadius(0); - trVer = radiusScale*vert; - trVer+=sphere0Pos; + btScalar radiusScale = 2. * ms->getSphereRadius(0); + trVer = radiusScale * vert; + trVer += sphere0Pos; } - transformedVertices[i*9+0] = trVer[0]; - transformedVertices[i*9+1] = trVer[1]; - transformedVertices[i*9+2] = trVer[2]; - transformedVertices[i*9+3] =textured_detailed_sphere_vertices[i*9+3]; - transformedVertices[i*9+4] =textured_detailed_sphere_vertices[i*9+4]; - transformedVertices[i*9+5] =textured_detailed_sphere_vertices[i*9+5]; - transformedVertices[i*9+6] =textured_detailed_sphere_vertices[i*9+6]; - transformedVertices[i*9+7] =textured_detailed_sphere_vertices[i*9+7]; - transformedVertices[i*9+8] =textured_detailed_sphere_vertices[i*9+8]; + transformedVertices[i * 9 + 0] = trVer[0]; + transformedVertices[i * 9 + 1] = trVer[1]; + transformedVertices[i * 9 + 2] = trVer[2]; + transformedVertices[i * 9 + 3] = textured_detailed_sphere_vertices[i * 9 + 3]; + transformedVertices[i * 9 + 4] = textured_detailed_sphere_vertices[i * 9 + 4]; + transformedVertices[i * 9 + 5] = textured_detailed_sphere_vertices[i * 9 + 5]; + transformedVertices[i * 9 + 6] = textured_detailed_sphere_vertices[i * 9 + 6]; + transformedVertices[i * 9 + 7] = textured_detailed_sphere_vertices[i * 9 + 7]; + transformedVertices[i * 9 + 8] = textured_detailed_sphere_vertices[i * 9 + 8]; } - - int numIndices = sizeof(textured_detailed_sphere_indices)/sizeof(int); - graphicsShapeIndex = registerGraphicsShape(&transformedVertices[0],numVertices,textured_detailed_sphere_indices,numIndices,B3_GL_TRIANGLES,m_data->m_checkedTextureGrey); - - m_data->m_hashShapes.insert(shape,graphicsShapeIndex); + + int numIndices = sizeof(textured_detailed_sphere_indices) / sizeof(int); + graphicsShapeIndex = registerGraphicsShape(&transformedVertices[0], numVertices, textured_detailed_sphere_indices, numIndices, B3_GL_TRIANGLES, m_data->m_checkedTextureGrey); + + m_data->m_hashShapes.insert(shape, graphicsShapeIndex); } collisionShape->setUserIndex(graphicsShapeIndex); return; } } - if (collisionShape->getShapeType()==SPHERE_SHAPE_PROXYTYPE) + if (collisionShape->getShapeType() == SPHERE_SHAPE_PROXYTYPE) { - btSphereShape* sphereShape = (btSphereShape*) collisionShape; - btScalar radius = sphereShape->getRadius(); - btScalar sphereSize = 2.*radius; - btVector3 radiusScale(sphereSize,sphereSize,sphereSize); - btAlignedObjectArray transformedVertices; + btSphereShape* sphereShape = (btSphereShape*)collisionShape; + btScalar radius = sphereShape->getRadius(); + btScalar sphereSize = 2. * radius; + btVector3 radiusScale(sphereSize, sphereSize, sphereSize); + btAlignedObjectArray transformedVertices; + MyHashShape shape; + shape.m_radius0 = sphereSize; + shape.m_deformFunc = 0; ////no deform + int graphicsShapeIndex = -1; + int* graphicsShapeIndexPtr = m_data->m_hashShapes[shape]; - MyHashShape shape; - shape.m_radius0 = sphereSize; - shape.m_deformFunc = 0;////no deform - int graphicsShapeIndex = -1; - int* graphicsShapeIndexPtr = m_data->m_hashShapes[shape]; - - if (graphicsShapeIndexPtr) + if (graphicsShapeIndexPtr) + { + graphicsShapeIndex = *graphicsShapeIndexPtr; + } + else + { + int numVertices = sizeof(textured_detailed_sphere_vertices) / strideInBytes; + transformedVertices.resize(numVertices * 9); + for (int i = 0; i < numVertices; i++) { - graphicsShapeIndex = *graphicsShapeIndexPtr; - } else - { - int numVertices = sizeof(textured_detailed_sphere_vertices)/strideInBytes; - transformedVertices.resize(numVertices*9); - for (int i=0;im_checkedTextureGrey); - m_data->m_hashShapes.insert(shape,graphicsShapeIndex); + btVector3 trVer = radiusScale * vert; + transformedVertices[i * 9 + 0] = trVer[0]; + transformedVertices[i * 9 + 1] = trVer[1]; + transformedVertices[i * 9 + 2] = trVer[2]; + transformedVertices[i * 9 + 3] = textured_detailed_sphere_vertices[i * 9 + 3]; + transformedVertices[i * 9 + 4] = textured_detailed_sphere_vertices[i * 9 + 4]; + transformedVertices[i * 9 + 5] = textured_detailed_sphere_vertices[i * 9 + 5]; + transformedVertices[i * 9 + 6] = textured_detailed_sphere_vertices[i * 9 + 6]; + transformedVertices[i * 9 + 7] = textured_detailed_sphere_vertices[i * 9 + 7]; + transformedVertices[i * 9 + 8] = textured_detailed_sphere_vertices[i * 9 + 8]; } - collisionShape->setUserIndex(graphicsShapeIndex); - return; + int numIndices = sizeof(textured_detailed_sphere_indices) / sizeof(int); + graphicsShapeIndex = registerGraphicsShape(&transformedVertices[0], numVertices, textured_detailed_sphere_indices, numIndices, B3_GL_TRIANGLES, m_data->m_checkedTextureGrey); + m_data->m_hashShapes.insert(shape, graphicsShapeIndex); + } + + collisionShape->setUserIndex(graphicsShapeIndex); + return; } - if (collisionShape->getShapeType()==COMPOUND_SHAPE_PROXYTYPE) + if (collisionShape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) { btCompoundShape* compound = (btCompoundShape*)collisionShape; - if (compound->getNumChildShapes()==1) + if (compound->getNumChildShapes() == 1) { - if (compound->getChildShape(0)->getShapeType()==SPHERE_SHAPE_PROXYTYPE) + if (compound->getChildShape(0)->getShapeType() == SPHERE_SHAPE_PROXYTYPE) { - btSphereShape* sphereShape = (btSphereShape*) compound->getChildShape(0); + btSphereShape* sphereShape = (btSphereShape*)compound->getChildShape(0); btScalar radius = sphereShape->getRadius(); - btScalar sphereSize = 2.*radius; - btVector3 radiusScale(sphereSize,sphereSize,sphereSize); + btScalar sphereSize = 2. * radius; + btVector3 radiusScale(sphereSize, sphereSize, sphereSize); MyHashShape shape; shape.m_radius0 = sphereSize; - shape.m_deformFunc = 0;//no deform - shape.m_childTransform = compound->getChildTransform(0); + shape.m_deformFunc = 0; //no deform + shape.m_childTransform = compound->getChildTransform(0); int graphicsShapeIndex = -1; int* graphicsShapeIndexPtr = m_data->m_hashShapes[shape]; - + if (graphicsShapeIndexPtr) { graphicsShapeIndex = *graphicsShapeIndexPtr; - } + } else { - btAlignedObjectArray transformedVertices; - int numVertices = sizeof(textured_detailed_sphere_vertices)/strideInBytes; - transformedVertices.resize(numVertices*9); - for (int i=0;igetChildTransform(0)*(radiusScale*vert); - transformedVertices[i*9+0] = trVer[0]; - transformedVertices[i*9+1] = trVer[1]; - transformedVertices[i*9+2] = trVer[2]; - transformedVertices[i*9+3] =textured_detailed_sphere_vertices[i*9+3]; - transformedVertices[i*9+4] =textured_detailed_sphere_vertices[i*9+4]; - transformedVertices[i*9+5] =textured_detailed_sphere_vertices[i*9+5]; - transformedVertices[i*9+6] =textured_detailed_sphere_vertices[i*9+6]; - transformedVertices[i*9+7] =textured_detailed_sphere_vertices[i*9+7]; - transformedVertices[i*9+8] =textured_detailed_sphere_vertices[i*9+8]; + btVector3 trVer = compound->getChildTransform(0) * (radiusScale * vert); + transformedVertices[i * 9 + 0] = trVer[0]; + transformedVertices[i * 9 + 1] = trVer[1]; + transformedVertices[i * 9 + 2] = trVer[2]; + transformedVertices[i * 9 + 3] = textured_detailed_sphere_vertices[i * 9 + 3]; + transformedVertices[i * 9 + 4] = textured_detailed_sphere_vertices[i * 9 + 4]; + transformedVertices[i * 9 + 5] = textured_detailed_sphere_vertices[i * 9 + 5]; + transformedVertices[i * 9 + 6] = textured_detailed_sphere_vertices[i * 9 + 6]; + transformedVertices[i * 9 + 7] = textured_detailed_sphere_vertices[i * 9 + 7]; + transformedVertices[i * 9 + 8] = textured_detailed_sphere_vertices[i * 9 + 8]; } - - int numIndices = sizeof(textured_detailed_sphere_indices)/sizeof(int); - graphicsShapeIndex = registerGraphicsShape(&transformedVertices[0],numVertices,textured_detailed_sphere_indices,numIndices,B3_GL_TRIANGLES,m_data->m_checkedTextureGrey); - m_data->m_hashShapes.insert(shape,graphicsShapeIndex); + + int numIndices = sizeof(textured_detailed_sphere_indices) / sizeof(int); + graphicsShapeIndex = registerGraphicsShape(&transformedVertices[0], numVertices, textured_detailed_sphere_indices, numIndices, B3_GL_TRIANGLES, m_data->m_checkedTextureGrey); + m_data->m_hashShapes.insert(shape, graphicsShapeIndex); } collisionShape->setUserIndex(graphicsShapeIndex); return; } - if (compound->getChildShape(0)->getShapeType()==CAPSULE_SHAPE_PROXYTYPE) + if (compound->getChildShape(0)->getShapeType() == CAPSULE_SHAPE_PROXYTYPE) { - btCapsuleShape* sphereShape = (btCapsuleShape*) compound->getChildShape(0); + btCapsuleShape* sphereShape = (btCapsuleShape*)compound->getChildShape(0); int up = sphereShape->getUpAxis(); btScalar halfHeight = sphereShape->getHalfHeight(); btScalar radius = sphereShape->getRadius(); - btScalar sphereSize = 2.*radius; - - btVector3 radiusScale = btVector3(sphereSize,sphereSize,sphereSize); + btScalar sphereSize = 2. * radius; + btVector3 radiusScale = btVector3(sphereSize, sphereSize, sphereSize); MyHashShape shape; shape.m_radius0 = sphereSize; - shape.m_deformFunc = 2;//no deform - shape.m_childTransform = compound->getChildTransform(0); + shape.m_deformFunc = 2; //no deform + shape.m_childTransform = compound->getChildTransform(0); shape.m_upAxis = up; int graphicsShapeIndex = -1; int* graphicsShapeIndexPtr = m_data->m_hashShapes[shape]; - + if (graphicsShapeIndexPtr) { graphicsShapeIndex = *graphicsShapeIndexPtr; - } + } else { - btAlignedObjectArray transformedVertices; - int numVertices = sizeof(textured_detailed_sphere_vertices)/strideInBytes; - transformedVertices.resize(numVertices*9); - for (int i=0;i0) - trVer[up]+=halfHeight; + vert.setValue(textured_detailed_sphere_vertices[i * 9 + 0], + textured_detailed_sphere_vertices[i * 9 + 1], + textured_detailed_sphere_vertices[i * 9 + 2]); + + btVector3 trVer = (radiusScale * vert); + if (trVer[up] > 0) + trVer[up] += halfHeight; else - trVer[up]-=halfHeight; + trVer[up] -= halfHeight; - trVer = compound->getChildTransform(0)*trVer; + trVer = compound->getChildTransform(0) * trVer; - transformedVertices[i*9+0] = trVer[0]; - transformedVertices[i*9+1] = trVer[1]; - transformedVertices[i*9+2] = trVer[2]; - transformedVertices[i*9+3] =textured_detailed_sphere_vertices[i*9+3]; - transformedVertices[i*9+4] =textured_detailed_sphere_vertices[i*9+4]; - transformedVertices[i*9+5] =textured_detailed_sphere_vertices[i*9+5]; - transformedVertices[i*9+6] =textured_detailed_sphere_vertices[i*9+6]; - transformedVertices[i*9+7] =textured_detailed_sphere_vertices[i*9+7]; - transformedVertices[i*9+8] =textured_detailed_sphere_vertices[i*9+8]; + transformedVertices[i * 9 + 0] = trVer[0]; + transformedVertices[i * 9 + 1] = trVer[1]; + transformedVertices[i * 9 + 2] = trVer[2]; + transformedVertices[i * 9 + 3] = textured_detailed_sphere_vertices[i * 9 + 3]; + transformedVertices[i * 9 + 4] = textured_detailed_sphere_vertices[i * 9 + 4]; + transformedVertices[i * 9 + 5] = textured_detailed_sphere_vertices[i * 9 + 5]; + transformedVertices[i * 9 + 6] = textured_detailed_sphere_vertices[i * 9 + 6]; + transformedVertices[i * 9 + 7] = textured_detailed_sphere_vertices[i * 9 + 7]; + transformedVertices[i * 9 + 8] = textured_detailed_sphere_vertices[i * 9 + 8]; } - - int numIndices = sizeof(textured_detailed_sphere_indices)/sizeof(int); - graphicsShapeIndex = registerGraphicsShape(&transformedVertices[0],numVertices,textured_detailed_sphere_indices,numIndices,B3_GL_TRIANGLES,m_data->m_checkedTextureGrey); - m_data->m_hashShapes.insert(shape,graphicsShapeIndex); + + int numIndices = sizeof(textured_detailed_sphere_indices) / sizeof(int); + graphicsShapeIndex = registerGraphicsShape(&transformedVertices[0], numVertices, textured_detailed_sphere_indices, numIndices, B3_GL_TRIANGLES, m_data->m_checkedTextureGrey); + m_data->m_hashShapes.insert(shape, graphicsShapeIndex); } collisionShape->setUserIndex(graphicsShapeIndex); return; - } - if (compound->getChildShape(0)->getShapeType()==MULTI_SPHERE_SHAPE_PROXYTYPE) + if (compound->getChildShape(0)->getShapeType() == MULTI_SPHERE_SHAPE_PROXYTYPE) { - btMultiSphereShape* ms = (btMultiSphereShape*) compound->getChildShape(0); - if (ms->getSphereCount()==2) + btMultiSphereShape* ms = (btMultiSphereShape*)compound->getChildShape(0); + if (ms->getSphereCount() == 2) { btAlignedObjectArray transformedVertices; - int numVertices = sizeof(textured_detailed_sphere_vertices)/strideInBytes; - transformedVertices.resize(numVertices*9); + int numVertices = sizeof(textured_detailed_sphere_vertices) / strideInBytes; + transformedVertices.resize(numVertices * 9); btVector3 sphere0Pos = ms->getSpherePosition(0); btVector3 sphere1Pos = ms->getSpherePosition(1); - btVector3 fromTo = sphere1Pos-sphere0Pos; - btScalar radiusScale1 = 2.0*ms->getSphereRadius(1); - btScalar radiusScale0 = 2.0*ms->getSphereRadius(0); + btVector3 fromTo = sphere1Pos - sphere0Pos; + btScalar radiusScale1 = 2.0 * ms->getSphereRadius(1); + btScalar radiusScale0 = 2.0 * ms->getSphereRadius(0); MyHashShape shape; shape.m_radius0 = radiusScale0; @@ -711,51 +684,48 @@ void OpenGLGuiHelper::createCollisionShapeGraphicsObject(btCollisionShape* colli int graphicsShapeIndex = -1; int* graphicsShapeIndexPtr = m_data->m_hashShapes[shape]; - + if (graphicsShapeIndexPtr) { graphicsShapeIndex = *graphicsShapeIndexPtr; - } + } else { - for (int i=0;i0) + btVector3 trVer(0, 0, 0); + if (vert.dot(fromTo) > 0) { - - trVer = vert*radiusScale1; - trVer+=sphere1Pos; - trVer = compound->getChildTransform(0)*trVer; - } else + trVer = vert * radiusScale1; + trVer += sphere1Pos; + trVer = compound->getChildTransform(0) * trVer; + } + else { - trVer = vert*radiusScale0; - trVer+=sphere0Pos; - trVer=compound->getChildTransform(0)*trVer; + trVer = vert * radiusScale0; + trVer += sphere0Pos; + trVer = compound->getChildTransform(0) * trVer; } - - - transformedVertices[i*9+0] = trVer[0]; - transformedVertices[i*9+1] = trVer[1]; - transformedVertices[i*9+2] = trVer[2]; - transformedVertices[i*9+3] =textured_detailed_sphere_vertices[i*9+3]; - transformedVertices[i*9+4] =textured_detailed_sphere_vertices[i*9+4]; - transformedVertices[i*9+5] =textured_detailed_sphere_vertices[i*9+5]; - transformedVertices[i*9+6] =textured_detailed_sphere_vertices[i*9+6]; - transformedVertices[i*9+7] =textured_detailed_sphere_vertices[i*9+7]; - transformedVertices[i*9+8] =textured_detailed_sphere_vertices[i*9+8]; + transformedVertices[i * 9 + 0] = trVer[0]; + transformedVertices[i * 9 + 1] = trVer[1]; + transformedVertices[i * 9 + 2] = trVer[2]; + transformedVertices[i * 9 + 3] = textured_detailed_sphere_vertices[i * 9 + 3]; + transformedVertices[i * 9 + 4] = textured_detailed_sphere_vertices[i * 9 + 4]; + transformedVertices[i * 9 + 5] = textured_detailed_sphere_vertices[i * 9 + 5]; + transformedVertices[i * 9 + 6] = textured_detailed_sphere_vertices[i * 9 + 6]; + transformedVertices[i * 9 + 7] = textured_detailed_sphere_vertices[i * 9 + 7]; + transformedVertices[i * 9 + 8] = textured_detailed_sphere_vertices[i * 9 + 8]; } - - int numIndices = sizeof(textured_detailed_sphere_indices)/sizeof(int); - graphicsShapeIndex = registerGraphicsShape(&transformedVertices[0],numVertices,textured_detailed_sphere_indices,numIndices,B3_GL_TRIANGLES,m_data->m_checkedTextureGrey); - m_data->m_hashShapes.insert(shape,graphicsShapeIndex); + + int numIndices = sizeof(textured_detailed_sphere_indices) / sizeof(int); + graphicsShapeIndex = registerGraphicsShape(&transformedVertices[0], numVertices, textured_detailed_sphere_indices, numIndices, B3_GL_TRIANGLES, m_data->m_checkedTextureGrey); + m_data->m_hashShapes.insert(shape, graphicsShapeIndex); } collisionShape->setUserIndex(graphicsShapeIndex); return; @@ -763,17 +733,16 @@ void OpenGLGuiHelper::createCollisionShapeGraphicsObject(btCollisionShape* colli } } } - if (collisionShape->getShapeType()==CAPSULE_SHAPE_PROXYTYPE) + if (collisionShape->getShapeType() == CAPSULE_SHAPE_PROXYTYPE) { - btCapsuleShape* sphereShape = (btCapsuleShape*) collisionShape;//Y up + btCapsuleShape* sphereShape = (btCapsuleShape*)collisionShape; //Y up int up = sphereShape->getUpAxis(); btScalar halfHeight = sphereShape->getHalfHeight(); btScalar radius = sphereShape->getRadius(); - btScalar sphereSize = 2.*radius; - btVector3 radiusScale(sphereSize,sphereSize,sphereSize); - - + btScalar sphereSize = 2. * radius; + btVector3 radiusScale(sphereSize, sphereSize, sphereSize); + MyHashShape shape; shape.m_radius0 = sphereSize; shape.m_deformFunc = 3; @@ -781,86 +750,81 @@ void OpenGLGuiHelper::createCollisionShapeGraphicsObject(btCollisionShape* colli shape.m_halfHeight = halfHeight; int graphicsShapeIndex = -1; int* graphicsShapeIndexPtr = m_data->m_hashShapes[shape]; - + if (graphicsShapeIndexPtr) { graphicsShapeIndex = *graphicsShapeIndexPtr; - } + } else { - btAlignedObjectArray transformedVertices; - int numVertices = sizeof(textured_detailed_sphere_vertices)/strideInBytes; - transformedVertices.resize(numVertices*9); - for (int i=0;i0) - trVer[up]+=halfHeight; + vert.setValue(textured_detailed_sphere_vertices[i * 9 + 0], + textured_detailed_sphere_vertices[i * 9 + 1], + textured_detailed_sphere_vertices[i * 9 + 2]); + + btVector3 trVer = radiusScale * vert; + if (trVer[up] > 0) + trVer[up] += halfHeight; else - trVer[up]-=halfHeight; + trVer[up] -= halfHeight; - - - transformedVertices[i*9+0] = trVer[0]; - transformedVertices[i*9+1] = trVer[1]; - transformedVertices[i*9+2] = trVer[2]; - transformedVertices[i*9+3] =textured_detailed_sphere_vertices[i*9+3]; - transformedVertices[i*9+4] =textured_detailed_sphere_vertices[i*9+4]; - transformedVertices[i*9+5] =textured_detailed_sphere_vertices[i*9+5]; - transformedVertices[i*9+6] =textured_detailed_sphere_vertices[i*9+6]; - transformedVertices[i*9+7] =textured_detailed_sphere_vertices[i*9+7]; - transformedVertices[i*9+8] =textured_detailed_sphere_vertices[i*9+8]; + transformedVertices[i * 9 + 0] = trVer[0]; + transformedVertices[i * 9 + 1] = trVer[1]; + transformedVertices[i * 9 + 2] = trVer[2]; + transformedVertices[i * 9 + 3] = textured_detailed_sphere_vertices[i * 9 + 3]; + transformedVertices[i * 9 + 4] = textured_detailed_sphere_vertices[i * 9 + 4]; + transformedVertices[i * 9 + 5] = textured_detailed_sphere_vertices[i * 9 + 5]; + transformedVertices[i * 9 + 6] = textured_detailed_sphere_vertices[i * 9 + 6]; + transformedVertices[i * 9 + 7] = textured_detailed_sphere_vertices[i * 9 + 7]; + transformedVertices[i * 9 + 8] = textured_detailed_sphere_vertices[i * 9 + 8]; } - - int numIndices = sizeof(textured_detailed_sphere_indices)/sizeof(int); - graphicsShapeIndex = registerGraphicsShape(&transformedVertices[0],numVertices,textured_detailed_sphere_indices,numIndices,B3_GL_TRIANGLES,m_data->m_checkedTextureGrey); - m_data->m_hashShapes.insert(shape,graphicsShapeIndex); + + int numIndices = sizeof(textured_detailed_sphere_indices) / sizeof(int); + graphicsShapeIndex = registerGraphicsShape(&transformedVertices[0], numVertices, textured_detailed_sphere_indices, numIndices, B3_GL_TRIANGLES, m_data->m_checkedTextureGrey); + m_data->m_hashShapes.insert(shape, graphicsShapeIndex); } collisionShape->setUserIndex(graphicsShapeIndex); return; - } - if (collisionShape->getShapeType()==STATIC_PLANE_PROXYTYPE) + if (collisionShape->getShapeType() == STATIC_PLANE_PROXYTYPE) { const btStaticPlaneShape* staticPlaneShape = static_cast(collisionShape); btScalar planeConst = staticPlaneShape->getPlaneConstant(); const btVector3& planeNormal = staticPlaneShape->getPlaneNormal(); btVector3 planeOrigin = planeNormal * planeConst; - btVector3 vec0,vec1; - btPlaneSpace1(planeNormal,vec0,vec1); + btVector3 vec0, vec1; + btPlaneSpace1(planeNormal, vec0, vec1); btScalar vecLen = 128; btVector3 verts[4]; - verts[0] = planeOrigin + vec0*vecLen + vec1*vecLen; - verts[1] = planeOrigin - vec0*vecLen + vec1*vecLen; - verts[2] = planeOrigin - vec0*vecLen - vec1*vecLen; - verts[3] = planeOrigin + vec0*vecLen - vec1*vecLen; - + verts[0] = planeOrigin + vec0 * vecLen + vec1 * vecLen; + verts[1] = planeOrigin - vec0 * vecLen + vec1 * vecLen; + verts[2] = planeOrigin - vec0 * vecLen - vec1 * vecLen; + verts[3] = planeOrigin + vec0 * vecLen - vec1 * vecLen; + int startIndex = 0; - indices.push_back(startIndex+0); - indices.push_back(startIndex+1); - indices.push_back(startIndex+2); - indices.push_back(startIndex+0); - indices.push_back(startIndex+2); - indices.push_back(startIndex+3); + indices.push_back(startIndex + 0); + indices.push_back(startIndex + 1); + indices.push_back(startIndex + 2); + indices.push_back(startIndex + 0); + indices.push_back(startIndex + 2); + indices.push_back(startIndex + 3); btTransform parentTransform; parentTransform.setIdentity(); - btVector3 triNormal = parentTransform.getBasis()*planeNormal; - + btVector3 triNormal = parentTransform.getBasis() * planeNormal; + gfxVertices.resize(4); - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) { btVector3 vtxPos; - btVector3 pos =parentTransform*verts[i]; + btVector3 pos = parentTransform * verts[i]; gfxVertices[i].xyzw[0] = pos[0]; gfxVertices[i].xyzw[1] = pos[1]; @@ -876,68 +840,68 @@ void OpenGLGuiHelper::createCollisionShapeGraphicsObject(btCollisionShape* colli //verts[2] = planeOrigin - vec0*vecLen - vec1*vecLen; //verts[3] = planeOrigin + vec0*vecLen - vec1*vecLen; - gfxVertices[0].uv[0] = vecLen/2; - gfxVertices[0].uv[1] = vecLen/2; - gfxVertices[1].uv[0] = -vecLen/2; - gfxVertices[1].uv[1] = vecLen/2; - gfxVertices[2].uv[0] = -vecLen/2; - gfxVertices[2].uv[1] = -vecLen/2; - gfxVertices[3].uv[0] = vecLen/2; - gfxVertices[3].uv[1] = -vecLen/2; + gfxVertices[0].uv[0] = vecLen / 2; + gfxVertices[0].uv[1] = vecLen / 2; + gfxVertices[1].uv[0] = -vecLen / 2; + gfxVertices[1].uv[1] = vecLen / 2; + gfxVertices[2].uv[0] = -vecLen / 2; + gfxVertices[2].uv[1] = -vecLen / 2; + gfxVertices[3].uv[0] = vecLen / 2; + gfxVertices[3].uv[1] = -vecLen / 2; - int shapeId = registerGraphicsShape(&gfxVertices[0].xyzw[0],gfxVertices.size(),&indices[0],indices.size(),B3_GL_TRIANGLES,m_data->m_checkedTexture); + int shapeId = registerGraphicsShape(&gfxVertices[0].xyzw[0], gfxVertices.size(), &indices[0], indices.size(), B3_GL_TRIANGLES, m_data->m_checkedTexture); collisionShape->setUserIndex(shapeId); return; } - btTransform startTrans;startTrans.setIdentity(); + btTransform startTrans; + startTrans.setIdentity(); //todo: create some textured objects for popular objects, like plane, cube, sphere, capsule - { - btAlignedObjectArray vertexPositions; - btAlignedObjectArray vertexNormals; - CollisionShape2TriangleMesh(collisionShape,startTrans,vertexPositions,vertexNormals,indices); - gfxVertices.resize(vertexPositions.size()); - for (int i=0;i vertexPositions; + btAlignedObjectArray vertexNormals; + CollisionShape2TriangleMesh(collisionShape, startTrans, vertexPositions, vertexNormals, indices); + gfxVertices.resize(vertexPositions.size()); + for (int i = 0; i < vertexPositions.size(); i++) + { + for (int j = 0; j < 4; j++) + { + gfxVertices[i].xyzw[j] = vertexPositions[i][j]; + } + for (int j = 0; j < 3; j++) + { + gfxVertices[i].normal[j] = vertexNormals[i][j]; + } + for (int j = 0; j < 2; j++) + { + gfxVertices[i].uv[j] = 0.5; //we don't have UV info... + } + } + } if (gfxVertices.size() && indices.size()) { - int shapeId = registerGraphicsShape(&gfxVertices[0].xyzw[0],gfxVertices.size(),&indices[0],indices.size(),B3_GL_TRIANGLES,-1); + int shapeId = registerGraphicsShape(&gfxVertices[0].xyzw[0], gfxVertices.size(), &indices[0], indices.size(), B3_GL_TRIANGLES, -1); collisionShape->setUserIndex(shapeId); } - } void OpenGLGuiHelper::syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld) { //in VR mode, we skip the synchronization for the second eye - if (m_data->m_vrMode && m_data->m_vrSkipShadowPass==1) + if (m_data->m_vrMode && m_data->m_vrSkipShadowPass == 1) return; int numCollisionObjects = rbWorld->getNumCollisionObjects(); { B3_PROFILE("write all InstanceTransformToCPU"); - for (int i = 0; igetCollisionObjectArray()[i]; btCollisionShape* collisionShape = colObj->getCollisionShape(); - if (collisionShape->getShapeType()==SOFTBODY_SHAPE_PROXYTYPE && collisionShape->getUserIndex() >=0) { + if (collisionShape->getShapeType() == SOFTBODY_SHAPE_PROXYTYPE && collisionShape->getUserIndex() >= 0) + { btAlignedObjectArray gfxVertices; btAlignedObjectArray indices; computeSoftBodyVertices(collisionShape, gfxVertices, indices); @@ -959,30 +923,27 @@ void OpenGLGuiHelper::syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWor } } - - void OpenGLGuiHelper::render(const btDiscreteDynamicsWorld* rbWorld) { if (m_data->m_vrMode) { //in VR, we skip the shadow generation for the second eye - - if (m_data->m_vrSkipShadowPass>=1) + + if (m_data->m_vrSkipShadowPass >= 1) { m_data->m_glApp->m_renderer->renderSceneInternal(B3_USE_SHADOWMAP_RENDERMODE); - m_data->m_vrSkipShadowPass=0; - - } else + m_data->m_vrSkipShadowPass = 0; + } + else { - m_data->m_glApp->m_renderer->renderScene(); + m_data->m_glApp->m_renderer->renderScene(); m_data->m_vrSkipShadowPass++; } - } else - { - m_data->m_glApp->m_renderer->renderScene(); } - - + else + { + m_data->m_glApp->m_renderer->renderScene(); + } } void OpenGLGuiHelper::createPhysicsDebugDrawer(btDiscreteDynamicsWorld* rbWorld) { @@ -993,19 +954,16 @@ void OpenGLGuiHelper::createPhysicsDebugDrawer(btDiscreteDynamicsWorld* rbWorld) m_data->m_debugDraw = 0; } - m_data->m_debugDraw = new MyDebugDrawer(m_data->m_glApp); - rbWorld->setDebugDrawer(m_data->m_debugDraw ); - - - m_data->m_debugDraw->setDebugMode( - btIDebugDraw::DBG_DrawWireframe - +btIDebugDraw::DBG_DrawAabb - //btIDebugDraw::DBG_DrawContactPoints - ); + m_data->m_debugDraw = new MyDebugDrawer(m_data->m_glApp); + rbWorld->setDebugDrawer(m_data->m_debugDraw); + m_data->m_debugDraw->setDebugMode( + btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawAabb + //btIDebugDraw::DBG_DrawContactPoints + ); } -struct Common2dCanvasInterface* OpenGLGuiHelper::get2dCanvasInterface() +struct Common2dCanvasInterface* OpenGLGuiHelper::get2dCanvasInterface() { return m_data->m_glApp->m_2dCanvasInterface; } @@ -1018,75 +976,71 @@ CommonParameterInterface* OpenGLGuiHelper::getParameterInterface() void OpenGLGuiHelper::setUpAxis(int axis) { m_data->m_glApp->setUpAxis(axis); - } - -void OpenGLGuiHelper::setVisualizerFlagCallback(VisualizerFlagCallback callback) +void OpenGLGuiHelper::setVisualizerFlagCallback(VisualizerFlagCallback callback) { m_data->m_visualizerFlagCallback = callback; } - void OpenGLGuiHelper::setVisualizerFlag(int flag, int enable) { - if (getRenderInterface() && flag==16)//COV_ENABLE_PLANAR_REFLECTION + if (getRenderInterface() && flag == 16) //COV_ENABLE_PLANAR_REFLECTION { getRenderInterface()->setPlaneReflectionShapeIndex(enable); } if (m_data->m_visualizerFlagCallback) - (m_data->m_visualizerFlagCallback)(flag,enable); + (m_data->m_visualizerFlagCallback)(flag, enable); } - -void OpenGLGuiHelper::resetCamera(float camDist, float yaw, float pitch, float camPosX,float camPosY, float camPosZ) +void OpenGLGuiHelper::resetCamera(float camDist, float yaw, float pitch, float camPosX, float camPosY, float camPosZ) { if (getRenderInterface() && getRenderInterface()->getActiveCamera()) { getRenderInterface()->getActiveCamera()->setCameraDistance(camDist); getRenderInterface()->getActiveCamera()->setCameraPitch(pitch); getRenderInterface()->getActiveCamera()->setCameraYaw(yaw); - getRenderInterface()->getActiveCamera()->setCameraTargetPosition(camPosX,camPosY,camPosZ); + getRenderInterface()->getActiveCamera()->setCameraTargetPosition(camPosX, camPosY, camPosZ); } } -bool OpenGLGuiHelper::getCameraInfo(int* width, int* height, float viewMatrix[16], float projectionMatrix[16], float camUp[3], float camForward[3],float hor[3], float vert[3], float* yaw, float* pitch, float* camDist, float cameraTarget[3]) const +bool OpenGLGuiHelper::getCameraInfo(int* width, int* height, float viewMatrix[16], float projectionMatrix[16], float camUp[3], float camForward[3], float hor[3], float vert[3], float* yaw, float* pitch, float* camDist, float cameraTarget[3]) const { if (getRenderInterface() && getRenderInterface()->getActiveCamera()) { - *width = m_data->m_glApp->m_window->getWidth()*m_data->m_glApp->m_window->getRetinaScale(); - *height = m_data->m_glApp->m_window->getHeight()*m_data->m_glApp->m_window->getRetinaScale(); + *width = m_data->m_glApp->m_window->getWidth() * m_data->m_glApp->m_window->getRetinaScale(); + *height = m_data->m_glApp->m_window->getHeight() * m_data->m_glApp->m_window->getRetinaScale(); getRenderInterface()->getActiveCamera()->getCameraViewMatrix(viewMatrix); getRenderInterface()->getActiveCamera()->getCameraProjectionMatrix(projectionMatrix); getRenderInterface()->getActiveCamera()->getCameraUpVector(camUp); getRenderInterface()->getActiveCamera()->getCameraForwardVector(camForward); - + float top = 1.f; float bottom = -1.f; - float tanFov = (top-bottom)*0.5f / 1; + float tanFov = (top - bottom) * 0.5f / 1; float fov = btScalar(2.0) * btAtan(tanFov); - btVector3 camPos,camTarget; + btVector3 camPos, camTarget; getRenderInterface()->getActiveCamera()->getCameraPosition(camPos); getRenderInterface()->getActiveCamera()->getCameraTargetPosition(camTarget); - btVector3 rayFrom = camPos; - btVector3 rayForward = (camTarget-camPos); + btVector3 rayFrom = camPos; + btVector3 rayForward = (camTarget - camPos); rayForward.normalize(); float farPlane = 10000.f; - rayForward*= farPlane; + rayForward *= farPlane; btVector3 rightOffset; - btVector3 cameraUp=btVector3(camUp[0],camUp[1],camUp[2]); + btVector3 cameraUp = btVector3(camUp[0], camUp[1], camUp[2]); btVector3 vertical = cameraUp; btVector3 hori; hori = rayForward.cross(vertical); hori.normalize(); vertical = hori.cross(rayForward); vertical.normalize(); - float tanfov = tanf(0.5f*fov); + float tanfov = tanf(0.5f * fov); hori *= 2.f * farPlane * tanfov; vertical *= 2.f * farPlane * tanfov; - btScalar aspect = float(*width) / float(*height); - hori*=aspect; + btScalar aspect = float(*width) / float(*height); + hori *= aspect; //compute 'hor' and 'vert' vectors, useful to generate raytracer rays hor[0] = hori[0]; hor[1] = hori[1]; @@ -1094,7 +1048,7 @@ bool OpenGLGuiHelper::getCameraInfo(int* width, int* height, float viewMatrix[16 vert[0] = vertical[0]; vert[1] = vertical[1]; vert[2] = vertical[2]; - + *yaw = getRenderInterface()->getActiveCamera()->getCameraYaw(); *pitch = getRenderInterface()->getActiveCamera()->getCameraPitch(); *camDist = getRenderInterface()->getActiveCamera()->getCameraDistance(); @@ -1116,87 +1070,86 @@ void OpenGLGuiHelper::setProjectiveTexture(bool useProjectiveTexture) m_data->m_glApp->m_renderer->setProjectiveTexture(useProjectiveTexture); } -void OpenGLGuiHelper::copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16], - unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, - float* depthBuffer, int depthBufferSizeInPixels, - int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels, - int startPixelIndex, int destinationWidth, - int destinationHeight, int* numPixelsCopied) +void OpenGLGuiHelper::copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16], + unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, + float* depthBuffer, int depthBufferSizeInPixels, + int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels, + int startPixelIndex, int destinationWidth, + int destinationHeight, int* numPixelsCopied) { - int sourceWidth = m_data->m_glApp->m_window->getWidth()*m_data->m_glApp->m_window->getRetinaScale(); - int sourceHeight = m_data->m_glApp->m_window->getHeight()*m_data->m_glApp->m_window->getRetinaScale(); - - if (numPixelsCopied) - *numPixelsCopied = 0; + int sourceWidth = m_data->m_glApp->m_window->getWidth() * m_data->m_glApp->m_window->getRetinaScale(); + int sourceHeight = m_data->m_glApp->m_window->getHeight() * m_data->m_glApp->m_window->getRetinaScale(); - int numTotalPixels = destinationWidth*destinationHeight; - int numRemainingPixels = numTotalPixels - startPixelIndex; - int numBytesPerPixel = 4;//RGBA - int numRequestedPixels = btMin(rgbaBufferSizeInPixels,numRemainingPixels); - if (numRequestedPixels) - { - if (startPixelIndex==0) - { - CommonCameraInterface* oldCam = getRenderInterface()->getActiveCamera(); + if (numPixelsCopied) + *numPixelsCopied = 0; + + int numTotalPixels = destinationWidth * destinationHeight; + int numRemainingPixels = numTotalPixels - startPixelIndex; + int numBytesPerPixel = 4; //RGBA + int numRequestedPixels = btMin(rgbaBufferSizeInPixels, numRemainingPixels); + if (numRequestedPixels) + { + if (startPixelIndex == 0) + { + CommonCameraInterface* oldCam = getRenderInterface()->getActiveCamera(); SimpleCamera tempCam; getRenderInterface()->setActiveCamera(&tempCam); - getRenderInterface()->getActiveCamera()->setVRCamera(viewMatrix,projectionMatrix); + getRenderInterface()->getActiveCamera()->setVRCamera(viewMatrix, projectionMatrix); { BT_PROFILE("renderScene"); getRenderInterface()->renderScene(); } getRenderInterface()->setActiveCamera(oldCam); - + { BT_PROFILE("copy pixels"); - btAlignedObjectArray sourceRgbaPixelBuffer; - btAlignedObjectArray sourceDepthBuffer; - //copy the image into our local cache - sourceRgbaPixelBuffer.resize(sourceWidth*sourceHeight*numBytesPerPixel); - sourceDepthBuffer.resize(sourceWidth*sourceHeight); + btAlignedObjectArray sourceRgbaPixelBuffer; + btAlignedObjectArray sourceDepthBuffer; + //copy the image into our local cache + sourceRgbaPixelBuffer.resize(sourceWidth * sourceHeight * numBytesPerPixel); + sourceDepthBuffer.resize(sourceWidth * sourceHeight); { BT_PROFILE("getScreenPixels"); - m_data->m_glApp->getScreenPixels(&(sourceRgbaPixelBuffer[0]),sourceRgbaPixelBuffer.size(), &sourceDepthBuffer[0],sizeof(float)*sourceDepthBuffer.size()); + m_data->m_glApp->getScreenPixels(&(sourceRgbaPixelBuffer[0]), sourceRgbaPixelBuffer.size(), &sourceDepthBuffer[0], sizeof(float) * sourceDepthBuffer.size()); } - - m_data->m_rgbaPixelBuffer1.resize(destinationWidth*destinationHeight*numBytesPerPixel); - m_data->m_depthBuffer1.resize(destinationWidth*destinationHeight); - //rescale and flip + + m_data->m_rgbaPixelBuffer1.resize(destinationWidth * destinationHeight * numBytesPerPixel); + m_data->m_depthBuffer1.resize(destinationWidth * destinationHeight); + //rescale and flip { BT_PROFILE("resize and flip"); - for (int j=0;jm_rgbaPixelBuffer1[(i+j*destinationWidth)*4+0]; - int* src = (int*)&sourceRgbaPixelBuffer[sourcePixelIndex+0]; + int* dst = (int*)&m_data->m_rgbaPixelBuffer1[(i + j * destinationWidth) * 4 + 0]; + int* src = (int*)&sourceRgbaPixelBuffer[sourcePixelIndex + 0]; *dst = *src; - + #else - m_data->m_rgbaPixelBuffer1[(i+j*destinationWidth)*4+0] = sourceRgbaPixelBuffer[sourcePixelIndex+0]; - m_data->m_rgbaPixelBuffer1[(i+j*destinationWidth)*4+1] = sourceRgbaPixelBuffer[sourcePixelIndex+1]; - m_data->m_rgbaPixelBuffer1[(i+j*destinationWidth)*4+2] = sourceRgbaPixelBuffer[sourcePixelIndex+2]; - m_data->m_rgbaPixelBuffer1[(i+j*destinationWidth)*4+3] = 255; -#endif + m_data->m_rgbaPixelBuffer1[(i + j * destinationWidth) * 4 + 0] = sourceRgbaPixelBuffer[sourcePixelIndex + 0]; + m_data->m_rgbaPixelBuffer1[(i + j * destinationWidth) * 4 + 1] = sourceRgbaPixelBuffer[sourcePixelIndex + 1]; + m_data->m_rgbaPixelBuffer1[(i + j * destinationWidth) * 4 + 2] = sourceRgbaPixelBuffer[sourcePixelIndex + 2]; + m_data->m_rgbaPixelBuffer1[(i + j * destinationWidth) * 4 + 3] = 255; +#endif if (depthBuffer) - { - m_data->m_depthBuffer1[i+j*destinationWidth] = sourceDepthBuffer[sourceDepthIndex]; + { + m_data->m_depthBuffer1[i + j * destinationWidth] = sourceDepthBuffer[sourceDepthIndex]; } - } } - } - } + } + } if (1) { @@ -1206,65 +1159,58 @@ void OpenGLGuiHelper::copyCameraImageData(const float viewMatrix[16], const floa getRenderInterface()->updateCamera(dg.upAxis); m_data->m_glApp->m_window->startRendering(); } - } - if (pixelsRGBA) - { + } + if (pixelsRGBA) + { BT_PROFILE("copy rgba pixels"); - for (int i=0;im_rgbaPixelBuffer1[i+startPixelIndex*numBytesPerPixel]; - } - } - if (depthBuffer) - { + for (int i = 0; i < numRequestedPixels * numBytesPerPixel; i++) + { + pixelsRGBA[i] = m_data->m_rgbaPixelBuffer1[i + startPixelIndex * numBytesPerPixel]; + } + } + if (depthBuffer) + { BT_PROFILE("copy depth buffer pixels"); - for (int i=0;im_depthBuffer1[i+startPixelIndex]; - } - } + for (int i = 0; i < numRequestedPixels; i++) + { + depthBuffer[i] = m_data->m_depthBuffer1[i + startPixelIndex]; + } + } if (numPixelsCopied) - *numPixelsCopied = numRequestedPixels; - - - } - - + *numPixelsCopied = numRequestedPixels; + } } - - struct MyConvertPointerSizeT { - union - { - const void* m_ptr; - size_t m_int; + union { + const void* m_ptr; + size_t m_int; }; }; bool shapePointerCompareFunc(const btCollisionObject* colA, const btCollisionObject* colB) { - MyConvertPointerSizeT a,b; + MyConvertPointerSizeT a, b; a.m_ptr = colA->getCollisionShape(); b.m_ptr = colB->getCollisionShape(); - return (a.m_int sortedObjects; sortedObjects.reserve(rbWorld->getNumCollisionObjects()); - for (int i=0;igetNumCollisionObjects();i++) + for (int i = 0; i < rbWorld->getNumCollisionObjects(); i++) { btCollisionObject* colObj = rbWorld->getCollisionObjectArray()[i]; sortedObjects.push_back(colObj); } sortedObjects.quickSort(shapePointerCompareFunc); - for (int i=0;igetCollisionShape()->getShapeType()==STATIC_PLANE_PROXYTYPE) + if (colObj->getCollisionShape()->getShapeType() == STATIC_PLANE_PROXYTYPE) { - color.setValue(1,1,1,1); + color.setValue(1, 1, 1, 1); } - createCollisionObjectGraphicsObject(colObj,color); - + createCollisionObjectGraphicsObject(colObj, color); } } - -void OpenGLGuiHelper::drawText3D( const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlags) + +void OpenGLGuiHelper::drawText3D(const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlags) { B3_PROFILE("OpenGLGuiHelper::drawText3D"); - btAssert(m_data->m_glApp); - m_data->m_glApp->drawText3D(txt,position, orientation, color,size, optionFlags); - + btAssert(m_data->m_glApp); + m_data->m_glApp->drawText3D(txt, position, orientation, color, size, optionFlags); } -void OpenGLGuiHelper::drawText3D( const char* txt, float posX, float posY, float posZ, float size) +void OpenGLGuiHelper::drawText3D(const char* txt, float posX, float posY, float posZ, float size) { B3_PROFILE("OpenGLGuiHelper::drawText3D"); - btAssert(m_data->m_glApp); - m_data->m_glApp->drawText3D(txt,posX,posY,posZ,size); + btAssert(m_data->m_glApp); + m_data->m_glApp->drawText3D(txt, posX, posY, posZ, size); } struct CommonGraphicsApp* OpenGLGuiHelper::getAppInterface() @@ -1310,7 +1254,7 @@ struct CommonGraphicsApp* OpenGLGuiHelper::getAppInterface() return m_data->m_glApp; } -void OpenGLGuiHelper::dumpFramesToVideo(const char* mp4FileName) +void OpenGLGuiHelper::dumpFramesToVideo(const char* mp4FileName) { if (m_data->m_glApp) { @@ -1322,7 +1266,7 @@ void OpenGLGuiHelper::computeSoftBodyVertices(btCollisionShape* collisionShape, btAlignedObjectArray& gfxVertices, btAlignedObjectArray& indices) { - if (collisionShape->getUserPointer()==0) + if (collisionShape->getUserPointer() == 0) return; b3Assert(collisionShape->getUserPointer()); btSoftBody* psb = (btSoftBody*)collisionShape->getUserPointer(); diff --git a/examples/ExampleBrowser/OpenGLGuiHelper.h b/examples/ExampleBrowser/OpenGLGuiHelper.h index cf5a4c4f4..b388ec2c4 100644 --- a/examples/ExampleBrowser/OpenGLGuiHelper.h +++ b/examples/ExampleBrowser/OpenGLGuiHelper.h @@ -22,8 +22,8 @@ struct OpenGLGuiHelper : public GUIHelperInterface virtual void createCollisionObjectGraphicsObject(btCollisionObject* body, const btVector3& color); - virtual int registerTexture(const unsigned char* texels, int width, int height); - virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices,int primitiveType, int textureId); + virtual int registerTexture(const unsigned char* texels, int width, int height); + virtual int registerGraphicsShape(const float* vertices, int numvertices, const int* indices, int numIndices, int primitiveType, int textureId); virtual int registerGraphicsInstance(int shapeIndex, const float* position, const float* quaternion, const float* color, const float* scaling); virtual void removeAllGraphicsInstances(); virtual void removeGraphicsInstance(int graphicsUid); @@ -31,84 +31,80 @@ struct OpenGLGuiHelper : public GUIHelperInterface virtual void changeSpecularColor(int instanceUid, const double specularColor[3]); virtual void changeTexture(int textureUniqueId, const unsigned char* rgbTexels, int width, int height); virtual void removeTexture(int textureUid); - virtual int getShapeIndexFromInstance(int instanceUid); + virtual int getShapeIndexFromInstance(int instanceUid); virtual void replaceTexture(int shapeIndex, int textureUid); virtual void createCollisionShapeGraphicsObject(btCollisionShape* collisionShape); virtual void syncPhysicsToGraphics(const btDiscreteDynamicsWorld* rbWorld); - virtual void render(const btDiscreteDynamicsWorld* rbWorld); virtual void createPhysicsDebugDrawer(btDiscreteDynamicsWorld* rbWorld); - virtual struct Common2dCanvasInterface* get2dCanvasInterface(); + virtual struct Common2dCanvasInterface* get2dCanvasInterface(); virtual CommonParameterInterface* getParameterInterface(); virtual struct CommonGraphicsApp* getAppInterface(); virtual void setUpAxis(int axis); - - - virtual void resetCamera(float camDist, float yaw, float pitch, float camPosX,float camPosY, float camPosZ); - virtual bool getCameraInfo(int* width, int* height, float viewMatrix[16], float projectionMatrix[16], float camUp[3], float camForward[3],float hor[3], float vert[3], float* yaw, float* pitch, float* camDist, float cameraTarget[3]) const; - virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16], - unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, - float* depthBuffer, int depthBufferSizeInPixels, - int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels, - int startPixelIndex, int destinationWidth, - int destinationHeight, int* numPixelsCopied); - + virtual void resetCamera(float camDist, float yaw, float pitch, float camPosX, float camPosY, float camPosZ); + virtual bool getCameraInfo(int* width, int* height, float viewMatrix[16], float projectionMatrix[16], float camUp[3], float camForward[3], float hor[3], float vert[3], float* yaw, float* pitch, float* camDist, float cameraTarget[3]) const; + + virtual void copyCameraImageData(const float viewMatrix[16], const float projectionMatrix[16], + unsigned char* pixelsRGBA, int rgbaBufferSizeInPixels, + float* depthBuffer, int depthBufferSizeInPixels, + int* segmentationMaskBuffer, int segmentationMaskBufferSizeInPixels, + int startPixelIndex, int destinationWidth, + int destinationHeight, int* numPixelsCopied); + virtual void setProjectiveTextureMatrices(const float viewMatrix[16], const float projectionMatrix[16]); virtual void setProjectiveTexture(bool useProjectiveTexture); - virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld) ; + virtual void autogenerateGraphicsObjects(btDiscreteDynamicsWorld* rbWorld); - virtual void drawText3D( const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag); + virtual void drawText3D(const char* txt, float position[3], float orientation[4], float color[4], float size, int optionFlag); - virtual void drawText3D( const char* txt, float posX, float posY, float posZ, float size); + virtual void drawText3D(const char* txt, float posX, float posY, float posZ, float size); - virtual int addUserDebugText3D( const char* txt, const double positionXYZ[3], const double textColorRGB[3], double size, double lifeTime) - { - return -1; - } - - virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime , int trackingVisualShapeIndex, int replaceItemUid ) - { - return -1; - } - virtual int addUserDebugParameter(const char* txt, double rangeMin, double rangeMax, double startValue) + virtual int addUserDebugText3D(const char* txt, const double positionXYZ[3], const double textColorRGB[3], double size, double lifeTime) { return -1; } - virtual void removeUserDebugItem( int debugItemUniqueId) + virtual int addUserDebugLine(const double debugLineFromXYZ[3], const double debugLineToXYZ[3], const double debugLineColorRGB[3], double lineWidth, double lifeTime, int trackingVisualShapeIndex, int replaceItemUid) + { + return -1; + } + virtual int addUserDebugParameter(const char* txt, double rangeMin, double rangeMax, double startValue) + { + return -1; + } + + virtual void removeUserDebugItem(int debugItemUniqueId) { } - virtual void removeAllUserDebugItems( ) + virtual void removeAllUserDebugItems() { } - - void renderInternalGl2(int pass, const btDiscreteDynamicsWorld* dynamicsWorld); + void renderInternalGl2(int pass, const btDiscreteDynamicsWorld* dynamicsWorld); void setVRMode(bool vrMode); void setVisualizerFlag(int flag, int enable); - virtual void setVisualizerFlagCallback(VisualizerFlagCallback callback); + virtual void setVisualizerFlagCallback(VisualizerFlagCallback callback); - virtual void dumpFramesToVideo(const char* mp4FileName); + virtual void dumpFramesToVideo(const char* mp4FileName); - int createCheckeredTexture(int r,int g, int b); + int createCheckeredTexture(int r, int g, int b); void computeSoftBodyVertices(btCollisionShape* collisionShape, - btAlignedObjectArray& gfxVertices, - btAlignedObjectArray& indices); + btAlignedObjectArray& gfxVertices, + btAlignedObjectArray& indices); }; -#endif //OPENGL_GUI_HELPER_H - +#endif //OPENGL_GUI_HELPER_H diff --git a/examples/ExampleBrowser/main.cpp b/examples/ExampleBrowser/main.cpp index 3847181b5..f306c3f02 100644 --- a/examples/ExampleBrowser/main.cpp +++ b/examples/ExampleBrowser/main.cpp @@ -19,9 +19,8 @@ static double gMinUpdateTimeMicroSecs = 1000.; - -static bool interrupted=false; -static OpenGLExampleBrowser* sExampleBrowser=0; +static bool interrupted = false; +static OpenGLExampleBrowser* sExampleBrowser = 0; #ifndef _WIN32 #include @@ -29,48 +28,50 @@ static OpenGLExampleBrowser* sExampleBrowser=0; #include static void cleanup(int signo) { - - if (!interrupted) { // this is the second time, we're hanging somewhere - b3Printf("Aborting and deleting SharedMemoryCommon object"); - delete sExampleBrowser; + if (!interrupted) + { // this is the second time, we're hanging somewhere + b3Printf("Aborting and deleting SharedMemoryCommon object"); + delete sExampleBrowser; sleep(1); sExampleBrowser = 0; - errx(EXIT_FAILURE, "aborted example on signal %d", signo); - } else - { + errx(EXIT_FAILURE, "aborted example on signal %d", signo); + } + else + { b3Printf("no action"); exit(EXIT_FAILURE); - } - interrupted = true; - warnx("caught signal %d", signo); + } + interrupted = true; + warnx("caught signal %d", signo); } -#endif//_WIN32 +#endif //_WIN32 int main(int argc, char* argv[]) { - #ifndef _WIN32 - struct sigaction action; - memset(&action, 0x0, sizeof(action)); - action.sa_handler = cleanup; - static const int signos[] = { SIGHUP, SIGINT, SIGQUIT, SIGABRT, SIGSEGV, SIGPIPE, SIGTERM }; - for (int ii(0); ii < sizeof(signos) / sizeof(*signos); ++ii) { - if (0 != sigaction(signos[ii], &action, NULL)) { - err(EXIT_FAILURE, "signal %d", signos[ii]); - } - } + struct sigaction action; + memset(&action, 0x0, sizeof(action)); + action.sa_handler = cleanup; + static const int signos[] = {SIGHUP, SIGINT, SIGQUIT, SIGABRT, SIGSEGV, SIGPIPE, SIGTERM}; + for (int ii(0); ii < sizeof(signos) / sizeof(*signos); ++ii) + { + if (0 != sigaction(signos[ii], &action, NULL)) + { + err(EXIT_FAILURE, "signal %d", signos[ii]); + } + } #endif { b3CommandLineArgs args(argc, argv); b3Clock clock; - args.GetCmdLineArgument("minUpdateTimeMicroSecs",gMinUpdateTimeMicroSecs); + args.GetCmdLineArgument("minUpdateTimeMicroSecs", gMinUpdateTimeMicroSecs); ExampleEntriesAll examples; examples.initExampleEntries(); OpenGLExampleBrowser* exampleBrowser = new OpenGLExampleBrowser(&examples); - sExampleBrowser = exampleBrowser;//for etc, cleanup shared memory + sExampleBrowser = exampleBrowser; //for etc, cleanup shared memory bool init = exampleBrowser->init(argc, argv); exampleBrowser->registerFileImporter(".urdf", ImportURDFCreateFunc); exampleBrowser->registerFileImporter(".sdf", ImportSDFCreateFunc); @@ -78,7 +79,6 @@ int main(int argc, char* argv[]) exampleBrowser->registerFileImporter(".stl", ImportSTLCreateFunc); exampleBrowser->registerFileImporter(".bullet", SerializeBulletCreateFunc); - clock.reset(); if (init) { @@ -89,10 +89,11 @@ int main(int argc, char* argv[]) { deltaTimeInSeconds = 0.1; } - if (deltaTimeInSeconds < (gMinUpdateTimeMicroSecs/1e6)) + if (deltaTimeInSeconds < (gMinUpdateTimeMicroSecs / 1e6)) { - b3Clock::usleep(gMinUpdateTimeMicroSecs/10.); - } else + b3Clock::usleep(gMinUpdateTimeMicroSecs / 10.); + } + else { clock.reset(); exampleBrowser->update(deltaTimeInSeconds); @@ -100,13 +101,12 @@ int main(int argc, char* argv[]) } while (!exampleBrowser->requestedExit() && !interrupted); } delete exampleBrowser; - } - + #ifdef BT_DEBUG_MEMORY_ALLOCATIONS int numBytesLeaked = btDumpMemoryLeaks(); - btAssert(numBytesLeaked==0); -#endif//BT_DEBUG_MEMORY_ALLOCATIONS - + btAssert(numBytesLeaked == 0); +#endif //BT_DEBUG_MEMORY_ALLOCATIONS + return 0; } diff --git a/examples/Experiments/ImplicitCloth/ImplicitClothExample.cpp b/examples/Experiments/ImplicitCloth/ImplicitClothExample.cpp index ab102be56..d04f9c612 100644 --- a/examples/Experiments/ImplicitCloth/ImplicitClothExample.cpp +++ b/examples/Experiments/ImplicitCloth/ImplicitClothExample.cpp @@ -1,6 +1,5 @@ #include "ImplicitClothExample.h" - #include "../CommonInterfaces/CommonExampleInterface.h" #include "../CommonInterfaces/CommonGUIHelperInterface.h" #include "../CommonInterfaces/CommonRenderInterface.h" @@ -12,46 +11,41 @@ #include "Bullet3Common/b3Vector3.h" #include "Bullet3Common/b3AlignedObjectArray.h" - #ifdef _DEBUG -int numX = 20, numY=20; +int numX = 20, numY = 20; #else -int numX = 60, numY=60; +int numX = 60, numY = 60; #endif -const size_t total_points = (numX)*(numY); +const size_t total_points = (numX) * (numY); - -struct ImplicitClothExample : public CommonExampleInterface +struct ImplicitClothExample : public CommonExampleInterface { struct GUIHelperInterface* m_guiHelper; int m_option; Cloth* m_cloth; - - - - + public: ImplicitClothExample(struct GUIHelperInterface* helper, int option) - :m_guiHelper(helper), - m_option(option), - m_cloth(0) + : m_guiHelper(helper), + m_option(option), + m_cloth(0) { } - virtual void initPhysics(); - virtual void exitPhysics(); - virtual void stepSimulation(float deltaTime); - virtual void renderScene(); - virtual void physicsDebugDraw(int debugFlags);//for now we reuse the flags in Bullet/src/LinearMath/btIDebugDraw.h - virtual bool mouseMoveCallback(float x,float y) + virtual void initPhysics(); + virtual void exitPhysics(); + virtual void stepSimulation(float deltaTime); + virtual void renderScene(); + virtual void physicsDebugDraw(int debugFlags); //for now we reuse the flags in Bullet/src/LinearMath/btIDebugDraw.h + virtual bool mouseMoveCallback(float x, float y) { return false; } - virtual bool mouseButtonCallback(int button, int state, float x, float y) + virtual bool mouseButtonCallback(int button, int state, float x, float y) { return false; } - virtual bool keyboardCallback(int key, int state) + virtual bool keyboardCallback(int key, int state) { return false; } @@ -61,69 +55,59 @@ public: float dist = 10; float pitch = 62; float yaw = 33; - float targetPos[3]={-3,2.4,-3.6}; - m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {-3, 2.4, -3.6}; + m_guiHelper->resetCamera(dist, pitch, yaw, targetPos[0], targetPos[1], targetPos[2]); } - - }; - -void ImplicitClothExample::initPhysics() +void ImplicitClothExample::initPhysics() { - float size=10; + float size = 10; m_guiHelper->setUpAxis(1); - m_cloth = ClothCreate(numX,numY,size); - + m_cloth = ClothCreate(numX, numY, size); } -void ImplicitClothExample::exitPhysics() +void ImplicitClothExample::exitPhysics() { delete m_cloth; - m_cloth=0; + m_cloth = 0; } -void ImplicitClothExample::stepSimulation(float deltaTime) +void ImplicitClothExample::stepSimulation(float deltaTime) { m_cloth->Simulate(deltaTime); - m_cloth->cloth_gravity.y = -9.8;//-9.8;//-9.8;//-9.8;//0;//-9.8;//0;//-9.8;//0;//-9.8; - m_cloth->cloth_gravity.z =-9.8;//0;//-9.8;//0;//-9.8; - - m_cloth->spring_struct=10000000.0f; - m_cloth->spring_shear=10000000.0f; - + m_cloth->cloth_gravity.y = -9.8; //-9.8;//-9.8;//-9.8;//0;//-9.8;//0;//-9.8;//0;//-9.8; + m_cloth->cloth_gravity.z = -9.8; //0;//-9.8;//0;//-9.8; + + m_cloth->spring_struct = 10000000.0f; + m_cloth->spring_shear = 10000000.0f; + //m_cloth->spring_struct=1000000.0f; //m_cloth->spring_shear=1000000.0f; - - m_cloth->spring_damp = 0;//100; - + m_cloth->spring_damp = 0; //100; } -void ImplicitClothExample::renderScene() +void ImplicitClothExample::renderScene() { } -void ImplicitClothExample::physicsDebugDraw(int debugFlags) +void ImplicitClothExample::physicsDebugDraw(int debugFlags) { - CommonRenderInterface* renderer = m_guiHelper->getRenderInterface(); - - b3AlignedObjectArray indices; - - for (int i=0;isprings.count;i++) - { - indices.push_back(m_cloth->springs[i].a); - indices.push_back(m_cloth->springs[i].b); - } - float lineColor[4]={0.4,0.4,1.0,1}; - renderer->drawLines(&m_cloth->X[0].x,lineColor,total_points,sizeof(float3),&indices[0],indices.size(),1); - - float pointColor[4]={1,0.4,0.4,1}; - -// renderer->drawPoints(&m_cloth->X[0].x,pointColor,total_points,sizeof(float3),3); - - + + b3AlignedObjectArray indices; + + for (int i = 0; i < m_cloth->springs.count; i++) + { + indices.push_back(m_cloth->springs[i].a); + indices.push_back(m_cloth->springs[i].b); + } + float lineColor[4] = {0.4, 0.4, 1.0, 1}; + renderer->drawLines(&m_cloth->X[0].x, lineColor, total_points, sizeof(float3), &indices[0], indices.size(), 1); + + float pointColor[4] = {1, 0.4, 0.4, 1}; + + // renderer->drawPoints(&m_cloth->X[0].x,pointColor,total_points,sizeof(float3),3); } - -class CommonExampleInterface* ImplicitClothCreateFunc(struct CommonExampleOptions& options) +class CommonExampleInterface* ImplicitClothCreateFunc(struct CommonExampleOptions& options) { return new ImplicitClothExample(options.m_guiHelper, options.m_option); } diff --git a/examples/Experiments/ImplicitCloth/ImplicitClothExample.h b/examples/Experiments/ImplicitCloth/ImplicitClothExample.h index 634e354dc..07849e196 100644 --- a/examples/Experiments/ImplicitCloth/ImplicitClothExample.h +++ b/examples/Experiments/ImplicitCloth/ImplicitClothExample.h @@ -1,8 +1,6 @@ #ifndef IMPLICIT_CLOTH_EXAMPLE_H #define IMPLICIT_CLOTH_EXAMPLE_H -class CommonExampleInterface* ImplicitClothCreateFunc(struct CommonExampleOptions& options); - - -#endif //IMPLICIT_CLOTH_EXAMPLE_H +class CommonExampleInterface* ImplicitClothCreateFunc(struct CommonExampleOptions& options); +#endif //IMPLICIT_CLOTH_EXAMPLE_H diff --git a/examples/Experiments/ImplicitCloth/stan/Cloth.cpp b/examples/Experiments/ImplicitCloth/stan/Cloth.cpp index 35859e686..4095f2b83 100644 --- a/examples/Experiments/ImplicitCloth/stan/Cloth.cpp +++ b/examples/Experiments/ImplicitCloth/stan/Cloth.cpp @@ -9,62 +9,54 @@ #include "Cloth.h" -Array cloths; +Array cloths; -Cloth::Cloth(const char *_name,int _n):SpringNetwork(_n), - color(0,0.5f,1.0f) +Cloth::Cloth(const char *_name, int _n) : SpringNetwork(_n), + color(0, 0.5f, 1.0f) { - - cloths.Add(this); + cloths.Add(this); } Cloth::~Cloth() { - cloths.Remove(this); + cloths.Remove(this); } // // I/O support for serialization of our springnetwork and cloth objects. // +int cloth_showbbox = 0; // for debug visualization shows bounding box. +float cloth_showvert = 0.025f; // size of box to put around current vert selected, 0 turns off - - -int cloth_showbbox = 0; // for debug visualization shows bounding box. -float cloth_showvert = 0.025f; // size of box to put around current vert selected, 0 turns off - - - -Cloth *ClothCreate(int w,int h,float size) +Cloth *ClothCreate(int w, int h, float size) { - // simple cloth generation routine that creates a typical square cloth. - // better to use a real pipeline to generate these, this is just for testing. - int i,j; - Cloth *cloth = new Cloth("cloth",w*h); - cloth->w=w; - cloth->h=h; // later for rendering. - for(i=0;iX[i*w+j] = (float3(-0.5f,-0.5f,0)+float3((float)j/(w-1.0f),1.0f-(float)i/(h-1.0f),0)) * size; - } - for(i=0;iCreateSpring(SPRING_STRUCT,i*w+j,(i+1)*w+j); // structural - if(jCreateSpring(SPRING_STRUCT,i*w+j,i*w+(j+1)); // structural - if(jCreateSpring(SPRING_SHEAR ,i*w+j,(i+1)*w+(j+1)); // shear - if(j>0 &&iCreateSpring(SPRING_SHEAR ,i*w+j,(i+1)*w+(j-1)); // shear - if(iCreateSpring(SPRING_BEND ,i*w+j,(i+2)*w+j); // benders - if(jCreateSpring(SPRING_BEND ,i*w+j,i*w+(j+2)); // benders - } - cloth->UpdateLimits(); - return cloth; + // simple cloth generation routine that creates a typical square cloth. + // better to use a real pipeline to generate these, this is just for testing. + int i, j; + Cloth *cloth = new Cloth("cloth", w * h); + cloth->w = w; + cloth->h = h; // later for rendering. + for (i = 0; i < h; i++) + for (j = 0; j < w; j++) + { + cloth->X[i * w + j] = (float3(-0.5f, -0.5f, 0) + float3((float)j / (w - 1.0f), 1.0f - (float)i / (h - 1.0f), 0)) * size; + } + for (i = 0; i < h; i++) + for (j = 0; j < w; j++) + { + if (i < h - 1) cloth->CreateSpring(SPRING_STRUCT, i * w + j, (i + 1) * w + j); // structural + if (j < w - 1) cloth->CreateSpring(SPRING_STRUCT, i * w + j, i * w + (j + 1)); // structural + if (j < w - 1 && i < h - 1) cloth->CreateSpring(SPRING_SHEAR, i * w + j, (i + 1) * w + (j + 1)); // shear + if (j > 0 && i < h - 1) cloth->CreateSpring(SPRING_SHEAR, i * w + j, (i + 1) * w + (j - 1)); // shear + if (i < h - 2) cloth->CreateSpring(SPRING_BEND, i * w + j, (i + 2) * w + j); // benders + if (j < w - 2) cloth->CreateSpring(SPRING_BEND, i * w + j, i * w + (j + 2)); // benders + } + cloth->UpdateLimits(); + return cloth; } - -int cloth_tess = 20; -float3 cloth_spawnpoint(0,3,5.0f); - +int cloth_tess = 20; +float3 cloth_spawnpoint(0, 3, 5.0f); /* static void ClothDrawSprings(Cloth *cloth) @@ -79,18 +71,17 @@ static void ClothDrawSprings(Cloth *cloth) } } */ -int cloth_showsprings=0; +int cloth_showsprings = 0; void DoCloths() { - int i; - for(i=0;iSimulate((cloth->cloth_step<0)?DeltaT:cloth->cloth_step); - //if(cloth_showsprings) - // ClothDrawSprings(cloth); // debug visualization - - } + int i; + for (i = 0; i < cloths.count; i++) + { + Cloth *cloth = cloths[i]; + + // cloth->Simulate((cloth->cloth_step<0)?DeltaT:cloth->cloth_step); + //if(cloth_showsprings) + // ClothDrawSprings(cloth); // debug visualization + } } diff --git a/examples/Experiments/ImplicitCloth/stan/Cloth.h b/examples/Experiments/ImplicitCloth/stan/Cloth.h index 4a4ec9166..79c334e25 100644 --- a/examples/Experiments/ImplicitCloth/stan/Cloth.h +++ b/examples/Experiments/ImplicitCloth/stan/Cloth.h @@ -5,14 +5,14 @@ class Cloth : public SpringNetwork { - public: - int w,h; - - float3 color; // for debug rendering - Cloth(const char* _name,int _n); - ~Cloth(); +public: + int w, h; + + float3 color; // for debug rendering + Cloth(const char* _name, int _n); + ~Cloth(); }; -Cloth *ClothCreate(int w,int h,float size); +Cloth* ClothCreate(int w, int h, float size); -#endif //STAN_CLOTH_H +#endif //STAN_CLOTH_H diff --git a/examples/Experiments/ImplicitCloth/stan/SpringNetwork.cpp b/examples/Experiments/ImplicitCloth/stan/SpringNetwork.cpp index d9b2b29c4..82db71f8b 100644 --- a/examples/Experiments/ImplicitCloth/stan/SpringNetwork.cpp +++ b/examples/Experiments/ImplicitCloth/stan/SpringNetwork.cpp @@ -1,10 +1,8 @@ #include "vec3n.h" //#include "console.h" - extern int numX; - // // Cloth - Backward Integrated Spring Network // @@ -42,157 +40,144 @@ extern int numX; //#include "object.h" //#include "xmlparse.h" +static const float3x3 I(1, 0, 0, 0, 1, 0, 0, 0, 1); - - -static const float3x3 I(1,0,0,0,1,0,0,0,1); - -inline float3x3 dfdx_spring(const float3 &dir,float length,float rest,float k) +inline float3x3 dfdx_spring(const float3 &dir, float length, float rest, float k) { - // dir is unit length direction, rest is spring's restlength, k is spring constant. - return ( (I-outerprod(dir,dir))*Min(1.0f,rest/length) - I) * -k; + // dir is unit length direction, rest is spring's restlength, k is spring constant. + return ((I - outerprod(dir, dir)) * Min(1.0f, rest / length) - I) * -k; } -inline float3x3 dfdx_damp(const float3 &dir,float length,const float3& vel,float rest,float damping) +inline float3x3 dfdx_damp(const float3 &dir, float length, const float3 &vel, float rest, float damping) { - // inner spring damping vel is the relative velocity of the endpoints. - return (I-outerprod(dir,dir)) * (-damping * -(dot(dir,vel)/Max(length,rest))); + // inner spring damping vel is the relative velocity of the endpoints. + return (I - outerprod(dir, dir)) * (-damping * -(dot(dir, vel) / Max(length, rest))); } -inline float3x3 dfdv_damp(const float3 &dir,float damping) +inline float3x3 dfdv_damp(const float3 &dir, float damping) { - // derivative of force wrt velocity. - return outerprod(dir,dir) * damping; + // derivative of force wrt velocity. + return outerprod(dir, dir) * damping; } - - #include "SpringNetwork.h" - -SpringNetwork::SpringNetwork(int _n):X(_n),V(_n),F(_n),dV(_n),A(_n),dFdX(_n),dFdV(_n) +SpringNetwork::SpringNetwork(int _n) : X(_n), V(_n), F(_n), dV(_n), A(_n), dFdX(_n), dFdV(_n) { - assert(SPRING_STRUCT==0); - assert(&spring_shear == &spring_struct +SPRING_SHEAR); - assert(&spring_bend == &spring_struct +SPRING_BEND); - assert(&spring_struct== &spring_k[SPRING_STRUCT]); - assert(&spring_shear == &spring_k[SPRING_SHEAR ]); - assert(&spring_bend == &spring_k[SPRING_BEND ]); - // spring_struct=1000000.0f; - // spring_shear=1000000.0f; - - spring_struct=1000.0f; - spring_shear=100.0f; - - spring_bend=25.0f; - spring_damp=5.0f; - spring_air=1.0f; - spring_air=1.0f; - cloth_step = 0.25f; // delta time for cloth - cloth_gravity=float3(0,-10,0); - cloth_sleepthreshold = 0.001f; - cloth_sleepcount = 100; - awake = cloth_sleepcount; - - //fix/pin two points in worldspace - float3Nx3N::Block zero; - zero.m = float3x3(0,0,0,0,0,0,0,0,0); - zero.c = 0; - zero.r = 0; - S.blocks.Add(zero); - zero.r = numX-1; - S.blocks.Add(zero); + assert(SPRING_STRUCT == 0); + assert(&spring_shear == &spring_struct + SPRING_SHEAR); + assert(&spring_bend == &spring_struct + SPRING_BEND); + assert(&spring_struct == &spring_k[SPRING_STRUCT]); + assert(&spring_shear == &spring_k[SPRING_SHEAR]); + assert(&spring_bend == &spring_k[SPRING_BEND]); + // spring_struct=1000000.0f; + // spring_shear=1000000.0f; + spring_struct = 1000.0f; + spring_shear = 100.0f; + spring_bend = 25.0f; + spring_damp = 5.0f; + spring_air = 1.0f; + spring_air = 1.0f; + cloth_step = 0.25f; // delta time for cloth + cloth_gravity = float3(0, -10, 0); + cloth_sleepthreshold = 0.001f; + cloth_sleepcount = 100; + awake = cloth_sleepcount; + //fix/pin two points in worldspace + float3Nx3N::Block zero; + zero.m = float3x3(0, 0, 0, 0, 0, 0, 0, 0, 0); + zero.c = 0; + zero.r = 0; + S.blocks.Add(zero); + zero.r = numX - 1; + S.blocks.Add(zero); } - SpringNetwork::Spring &SpringNetwork::AddBlocks(Spring &s) { - // Called during initial creation of springs in our spring network. - // Sets up the sparse matrices corresponding to connections. - // Note the indices (s.iab,s.iba) are also stored with spring to avoid looking them up each time a spring is applied - // All 3 matrices A,dFdX, and dFdV are contstructed identically so the block array layout will be the same for each. - s.iab = A.blocks.count; // added 'ab' blocks will have this index. - A.blocks.Add(float3Nx3N::Block(s.a,s.b)); - dFdX.blocks.Add(float3Nx3N::Block(s.a,s.b)); - dFdV.blocks.Add(float3Nx3N::Block(s.a,s.b)); - s.iba = A.blocks.count; // added 'ba' blocks will have this index. - A.blocks.Add(float3Nx3N::Block(s.b,s.a)); - dFdX.blocks.Add(float3Nx3N::Block(s.b,s.a)); - dFdV.blocks.Add(float3Nx3N::Block(s.b,s.a)); - return s; + // Called during initial creation of springs in our spring network. + // Sets up the sparse matrices corresponding to connections. + // Note the indices (s.iab,s.iba) are also stored with spring to avoid looking them up each time a spring is applied + // All 3 matrices A,dFdX, and dFdV are contstructed identically so the block array layout will be the same for each. + s.iab = A.blocks.count; // added 'ab' blocks will have this index. + A.blocks.Add(float3Nx3N::Block(s.a, s.b)); + dFdX.blocks.Add(float3Nx3N::Block(s.a, s.b)); + dFdV.blocks.Add(float3Nx3N::Block(s.a, s.b)); + s.iba = A.blocks.count; // added 'ba' blocks will have this index. + A.blocks.Add(float3Nx3N::Block(s.b, s.a)); + dFdX.blocks.Add(float3Nx3N::Block(s.b, s.a)); + dFdV.blocks.Add(float3Nx3N::Block(s.b, s.a)); + return s; } void SpringNetwork::PreSolveSpring(const SpringNetwork::Spring &s) { - // Adds this spring's contribution into force vector F and force derivitves dFdX and dFdV - // One optimization would be premultiply dfdx by dt*dt and F and dFdV by dt right here in this function. - // However, for educational purposes we wont do that now and intead just follow the paper directly. - //assert(dFdX.blocks[s.a].c==s.a); // delete this assert, no bugs here - //assert(dFdX.blocks[s.a].r==s.a); - float3 extent = X[s.b] - X[s.a]; - float length = magnitude(extent); - float3 dir = (length==0)?float3(0,0,0): extent * 1.0f/length; - float3 vel = V[s.b] - V[s.a]; - float k = spring_k[s.type]; - float3 f = dir * ((k * (length-s.restlen) ) + spring_damp * dot(vel,dir)); // spring force + damping force - F[s.a] += f; - F[s.b] -= f; - float3x3 dfdx = dfdx_spring(dir,length,s.restlen,k) + dfdx_damp(dir,length,vel,s.restlen,spring_damp); - dFdX.blocks[s.a].m -= dfdx; // diagonal chunk dFdX[a,a] - dFdX.blocks[s.b].m -= dfdx; // diagonal chunk dFdX[b,b] - dFdX.blocks[s.iab].m += dfdx; // off-diag chunk dFdX[a,b] - dFdX.blocks[s.iba].m += dfdx; // off-diag chunk dFdX[b,a] - float3x3 dfdv = dfdv_damp(dir,spring_damp); - dFdV.blocks[s.a].m -= dfdv; // diagonal chunk dFdV[a,a] - dFdV.blocks[s.b].m -= dfdv; // diagonal chunk dFdV[b,b] - dFdV.blocks[s.iab].m += dfdv; // off-diag chunk dFdV[a,b] - dFdV.blocks[s.iba].m += dfdv; // off-diag chunk dFdV[b,a] + // Adds this spring's contribution into force vector F and force derivitves dFdX and dFdV + // One optimization would be premultiply dfdx by dt*dt and F and dFdV by dt right here in this function. + // However, for educational purposes we wont do that now and intead just follow the paper directly. + //assert(dFdX.blocks[s.a].c==s.a); // delete this assert, no bugs here + //assert(dFdX.blocks[s.a].r==s.a); + float3 extent = X[s.b] - X[s.a]; + float length = magnitude(extent); + float3 dir = (length == 0) ? float3(0, 0, 0) : extent * 1.0f / length; + float3 vel = V[s.b] - V[s.a]; + float k = spring_k[s.type]; + float3 f = dir * ((k * (length - s.restlen)) + spring_damp * dot(vel, dir)); // spring force + damping force + F[s.a] += f; + F[s.b] -= f; + float3x3 dfdx = dfdx_spring(dir, length, s.restlen, k) + dfdx_damp(dir, length, vel, s.restlen, spring_damp); + dFdX.blocks[s.a].m -= dfdx; // diagonal chunk dFdX[a,a] + dFdX.blocks[s.b].m -= dfdx; // diagonal chunk dFdX[b,b] + dFdX.blocks[s.iab].m += dfdx; // off-diag chunk dFdX[a,b] + dFdX.blocks[s.iba].m += dfdx; // off-diag chunk dFdX[b,a] + float3x3 dfdv = dfdv_damp(dir, spring_damp); + dFdV.blocks[s.a].m -= dfdv; // diagonal chunk dFdV[a,a] + dFdV.blocks[s.b].m -= dfdv; // diagonal chunk dFdV[b,b] + dFdV.blocks[s.iab].m += dfdv; // off-diag chunk dFdV[a,b] + dFdV.blocks[s.iba].m += dfdv; // off-diag chunk dFdV[b,a] } - - - void SpringNetwork::CalcForces() { - // Collect forces and derivatives: F,dFdX,dFdV - dFdX.Zero(); - dFdV.InitDiagonal(-spring_air); - F.Init(cloth_gravity); + // Collect forces and derivatives: F,dFdX,dFdV + dFdX.Zero(); + dFdV.InitDiagonal(-spring_air); + F.Init(cloth_gravity); - F.element[0]=float3(0,0,0); - F.element[numX-1]=float3(0,0,0); - - F -= V * spring_air; - for(int i=0;i springs; - float3N X; // positions of all points - float3N V; // velocities - float3N F; // force on each point - float3N dV; // change in velocity - float3Nx3N A; // big matrix we solve system with - float3Nx3N dFdX; // big matrix of derivative of force wrt position - float3Nx3N dFdV; // big matrix of derivative of force wrt velocity - float3Nx3N S; // used for our constraints - contains only some diagonal blocks as needed S[i,i] - int awake; - float3 bmin,bmax; - union - { - struct - { - float spring_struct; - float spring_shear; - float spring_bend; - }; - float spring_k[3]; - }; - float spring_damp; - float spring_air; - float cloth_step; // delta time for cloth - float3 cloth_gravity; - float cloth_sleepthreshold; - int cloth_sleepcount; +public: + class Spring + { + public: + int type; // index into coefficients spring_k[] + float restlen; + int a, b; // spring endpoints vector indices + int iab, iba; // indices into off-diagonal blocks of sparse matrix + Spring() {} + Spring(int _type, int _a, int _b, float _restlen) : type(_type), a(_a), b(_b), restlen(_restlen) { iab = iba = -1; } + }; + Array springs; + float3N X; // positions of all points + float3N V; // velocities + float3N F; // force on each point + float3N dV; // change in velocity + float3Nx3N A; // big matrix we solve system with + float3Nx3N dFdX; // big matrix of derivative of force wrt position + float3Nx3N dFdV; // big matrix of derivative of force wrt velocity + float3Nx3N S; // used for our constraints - contains only some diagonal blocks as needed S[i,i] + int awake; + float3 bmin, bmax; + union { + struct + { + float spring_struct; + float spring_shear; + float spring_bend; + }; + float spring_k[3]; + }; + float spring_damp; + float spring_air; + float cloth_step; // delta time for cloth + float3 cloth_gravity; + float cloth_sleepthreshold; + int cloth_sleepcount; - SpringNetwork(int _n); - Spring &AddBlocks(Spring &s); - Spring &CreateSpring(int type,int a,int b,float restlen){return AddBlocks(springs.Add(Spring(type,a,b,restlen)));} - Spring &CreateSpring(int type,int a,int b){return CreateSpring(type,a,b,magnitude(X[b]-X[a]));} - void UpdateLimits() { BoxLimits(X.element,X.count,bmin,bmax);} - void Wake(){awake=cloth_sleepcount;} - void Simulate(float dt); - void PreSolveSpring(const Spring &s); - void CalcForces(); + SpringNetwork(int _n); + Spring &AddBlocks(Spring &s); + Spring &CreateSpring(int type, int a, int b, float restlen) { return AddBlocks(springs.Add(Spring(type, a, b, restlen))); } + Spring &CreateSpring(int type, int a, int b) { return CreateSpring(type, a, b, magnitude(X[b] - X[a])); } + void UpdateLimits() { BoxLimits(X.element, X.count, bmin, bmax); } + void Wake() { awake = cloth_sleepcount; } + void Simulate(float dt); + void PreSolveSpring(const Spring &s); + void CalcForces(); }; -#endif //STAN_SPRING_NETWORK_H +#endif //STAN_SPRING_NETWORK_H diff --git a/examples/Experiments/ImplicitCloth/stan/array.h b/examples/Experiments/ImplicitCloth/stan/array.h index d55714698..e422c509c 100644 --- a/examples/Experiments/ImplicitCloth/stan/array.h +++ b/examples/Experiments/ImplicitCloth/stan/array.h @@ -1,41 +1,41 @@ // // Typical template dynamic array container class. // By S Melax 1998 -// +// // anyone is free to use, inspect, learn from, or ignore -// the code here as they see fit. +// the code here as they see fit. // // A very simple template array class. // Its easiest to understand this array // class by seeing how it is used in code. // // For example: -// for(i=0;i #include -template class Array { - public: - Array(int s=0); - Array(Array &array); - ~Array(); - void allocate(int s); - void SetSize(int s); - void Pack(); - Type& Add(Type); - void AddUnique(Type); - int Contains(Type); - void Insert(Type,int); - int IndexOf(Type); - void Remove(Type); - void DelIndex(int i); - Type& DelIndexWithLast(int i); - Type * element; - int count; - int array_size; - const Type &operator[](int i) const { assert(i>=0 && i=0 && i +class Array +{ +public: + Array(int s = 0); + Array(Array &array); + ~Array(); + void allocate(int s); + void SetSize(int s); + void Pack(); + Type &Add(Type); + void AddUnique(Type); + int Contains(Type); + void Insert(Type, int); + int IndexOf(Type); + void Remove(Type); + void DelIndex(int i); + Type &DelIndexWithLast(int i); + Type *element; + int count; + int array_size; + const Type &operator[](int i) const + { + assert(i >= 0 && i < count); + return element[i]; + } + Type &operator[](int i) + { + assert(i >= 0 && i < count); + return element[i]; + } + Type &Pop() + { + assert(count); + count--; + return element[count]; + } Array ©(const Array &array); Array &operator=(Array &array); }; - -template Array::Array(int s) +template +Array::Array(int s) { - if(s==-1) return; - count=0; + if (s == -1) return; + count = 0; array_size = 0; element = NULL; - if(s) - { + if (s) + { allocate(s); } } - -template Array::Array(Array &array) +template +Array::Array(Array &array) { - count=0; + count = 0; array_size = 0; element = NULL; *this = array; } - - - -template Array &Array::copy(const Array &array) +template +Array &Array::copy(const Array &array) { - assert(array.array_size>=0); - count=0; - for(int i=0;i= 0); + count = 0; + for (int i = 0; i < array.count; i++) + { Add(array[i]); } return *this; } -template Array &Array::operator=( Array &array) +template +Array &Array::operator=(Array &array) { - if(array.array_size<0) // negative number means steal the data buffer instead of copying + if (array.array_size < 0) // negative number means steal the data buffer instead of copying { - delete[] element; + delete[] element; element = array.element; array_size = -array.array_size; count = array.count; - array.count =array.array_size = 0; + array.count = array.array_size = 0; array.element = NULL; return *this; } - count=0; - for(int i=0;i Array::~Array() +template +Array::~Array() { - if (element != NULL && array_size!=0) - { - delete[] element; - } - count=0;array_size=0;element=NULL; + if (element != NULL && array_size != 0) + { + delete[] element; + } + count = 0; + array_size = 0; + element = NULL; } -template void Array::allocate(int s) +template +void Array::allocate(int s) { - assert(s>0); - assert(s>=count); - if(s==array_size) return; + assert(s > 0); + assert(s >= count); + if (s == array_size) return; Type *old = element; - array_size =s; + array_size = s; element = new Type[array_size]; assert(element); - for(int i=0;i void Array::SetSize(int s) +template +void Array::SetSize(int s) { - if(s==0) - { - if(element) - { - delete[] element; - element = NULL; - } + if (s == 0) + { + if (element) + { + delete[] element; + element = NULL; + } array_size = s; - } - else - { - allocate(s); - } - count=s; + } + else + { + allocate(s); + } + count = s; } -template void Array::Pack() +template +void Array::Pack() { allocate(count); } -template Type& Array::Add(Type t) +template +Type &Array::Add(Type t) { - assert(count<=array_size); - if(count==array_size) - { - allocate((array_size)?array_size *2:16); + assert(count <= array_size); + if (count == array_size) + { + allocate((array_size) ? array_size * 2 : 16); } //int i; //for(i=0;i int Array::Contains(Type t) +template +int Array::Contains(Type t) { int i; - int found=0; - for(i=0;i void Array::AddUnique(Type t) +template +void Array::AddUnique(Type t) { - if(!Contains(t)) Add(t); + if (!Contains(t)) Add(t); } - -template void Array::DelIndex(int i) +template +void Array::DelIndex(int i) { - assert(i Type& Array::DelIndexWithLast(int i) +template +Type &Array::DelIndexWithLast(int i) { - assert(i void Array::Remove(Type t) +template +void Array::Remove(Type t) { int i; - for(i=0;i void Array::Insert(Type t,int k) +template +void Array::Insert(Type t, int k) { - int i=count; - Add(t); // to allocate space - while(i>k) - { - element[i]=element[i-1]; + int i = count; + Add(t); // to allocate space + while (i > k) + { + element[i] = element[i - 1]; i--; } - assert(i==k); - element[k]=t; + assert(i == k); + element[k] = t; } - -template int Array::IndexOf(Type t) +template +int Array::IndexOf(Type t) { int i; - for(i=0;i int Array::IndexOf(Type t) return -1; } - - - #endif diff --git a/examples/Experiments/ImplicitCloth/stan/vec3n.cpp b/examples/Experiments/ImplicitCloth/stan/vec3n.cpp index fa6e9f5cc..67f1c5d1a 100644 --- a/examples/Experiments/ImplicitCloth/stan/vec3n.cpp +++ b/examples/Experiments/ImplicitCloth/stan/vec3n.cpp @@ -1,16 +1,15 @@ // // Big Vector and Sparse Matrix Classes -// +// #include #include "vec3n.h" - float conjgrad_lasterror; float conjgrad_epsilon = 0.1f; -int conjgrad_loopcount; -int conjgrad_looplimit = 100; +int conjgrad_loopcount; +int conjgrad_looplimit = 100; /*EXPORTVAR(conjgrad_lasterror); EXPORTVAR(conjgrad_epsilon ); @@ -18,135 +17,131 @@ EXPORTVAR(conjgrad_loopcount); EXPORTVAR(conjgrad_looplimit); */ -int ConjGradient(float3N &X, float3Nx3N &A, float3N &B) +int ConjGradient(float3N &X, float3Nx3N &A, float3N &B) { - // Solves for unknown X in equation AX=B - conjgrad_loopcount=0; - int n=B.count; - float3N q(n),d(n),tmp(n),r(n); - r = B - Mul(tmp,A,X); // just use B if X known to be zero - d = r; - float s = dot(r,r); - float starget = s * squared(conjgrad_epsilon); - while( s>starget && conjgrad_loopcount++ < conjgrad_looplimit) - { - Mul(q,A,d); // q = A*d; - float a = s/dot(d,q); - X = X + d*a; - if(conjgrad_loopcount%50==0) - { - r = B - Mul(tmp,A,X); - } - else - { - r = r - q*a; - } - float s_prev = s; - s = dot(r,r); - d = r+d*(s/s_prev); - } - conjgrad_lasterror = s; - return conjgrad_loopcount starget && conjgrad_loopcount++ < conjgrad_looplimit) + { + Mul(q, A, d); // q = A*d; + float a = s / dot(d, q); + X = X + d * a; + if (conjgrad_loopcount % 50 == 0) + { + r = B - Mul(tmp, A, X); + } + else + { + r = r - q * a; + } + float s_prev = s; + s = dot(r, r); + d = r + d * (s / s_prev); + } + conjgrad_lasterror = s; + return conjgrad_loopcount < conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable } - -int ConjGradientMod(float3N &X, float3Nx3N &A, float3N &B,int3 hack) +int ConjGradientMod(float3N &X, float3Nx3N &A, float3N &B, int3 hack) { -// obsolete!!! - // Solves for unknown X in equation AX=B - conjgrad_loopcount=0; - int n=B.count; - float3N q(n),d(n),tmp(n),r(n); - r = B - Mul(tmp,A,X); // just use B if X known to be zero - r[hack[0]] = r[hack[1]] = r[hack[2]] = float3(0,0,0); - d = r; - float s = dot(r,r); - float starget = s * squared(conjgrad_epsilon); - while( s>starget && conjgrad_loopcount++ < conjgrad_looplimit) - { - Mul(q,A,d); // q = A*d; - q[hack[0]] = q[hack[1]] = q[hack[2]] = float3(0,0,0); - float a = s/dot(d,q); - X = X + d*a; - if(conjgrad_loopcount%50==0) - { - r = B - Mul(tmp,A,X); - r[hack[0]] = r[hack[1]] = r[hack[2]] = float3(0,0,0); - } - else - { - r = r - q*a; - } - float s_prev = s; - s = dot(r,r); - d = r+d*(s/s_prev); - d[hack[0]] = d[hack[1]] = d[hack[2]] = float3(0,0,0); - } - conjgrad_lasterror = s; - return conjgrad_loopcount starget && conjgrad_loopcount++ < conjgrad_looplimit) + { + Mul(q, A, d); // q = A*d; + q[hack[0]] = q[hack[1]] = q[hack[2]] = float3(0, 0, 0); + float a = s / dot(d, q); + X = X + d * a; + if (conjgrad_loopcount % 50 == 0) + { + r = B - Mul(tmp, A, X); + r[hack[0]] = r[hack[1]] = r[hack[2]] = float3(0, 0, 0); + } + else + { + r = r - q * a; + } + float s_prev = s; + s = dot(r, r); + d = r + d * (s / s_prev); + d[hack[0]] = d[hack[1]] = d[hack[2]] = float3(0, 0, 0); + } + conjgrad_lasterror = s; + return conjgrad_loopcount < conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable } - - -static inline void filter(float3N &V,const float3Nx3N &S) +static inline void filter(float3N &V, const float3Nx3N &S) { - for(int i=0;istarget && conjgrad_loopcount++ < conjgrad_looplimit) - { - Mul(q,A,d); // q = A*d; - filter(q,S); - float a = s/dot(d,q); - X = X + d*a; - if(conjgrad_loopcount%50==0) - { - r = B - Mul(tmp,A,X); - filter(r,S); - } - else - { - r = r - q*a; - } - float s_prev = s; - s = dot(r,r); - d = r+d*(s/s_prev); - filter(d,S); - } - conjgrad_lasterror = s; - return conjgrad_loopcount starget && conjgrad_loopcount++ < conjgrad_looplimit) + { + Mul(q, A, d); // q = A*d; + filter(q, S); + float a = s / dot(d, q); + X = X + d * a; + if (conjgrad_loopcount % 50 == 0) + { + r = B - Mul(tmp, A, X); + filter(r, S); + } + else + { + r = r - q * a; + } + float s_prev = s; + s = dot(r, r); + d = r + d * (s / s_prev); + filter(d, S); + } + conjgrad_lasterror = s; + return conjgrad_loopcount < conjgrad_looplimit; // true means we reached desired accuracy in given time - ie stable } - - - // test big vector math library: static void testfloat3N() { - float3N a(2),b(2),c(2); - a[0] = float3(1,2,3); - a[1] = float3(4,5,6); - b[0] = float3(10,20,30); - b[1] = float3(40,50,60); -// c = a+b+b * 10.0f; -// float d = dot(a+b,-b); - int k; - k=0; + float3N a(2), b(2), c(2); + a[0] = float3(1, 2, 3); + a[1] = float3(4, 5, 6); + b[0] = float3(10, 20, 30); + b[1] = float3(40, 50, 60); + // c = a+b+b * 10.0f; + // float d = dot(a+b,-b); + int k; + k = 0; } -class dotest{public:dotest(){testfloat3N();}}do_test_at_program_startup; - - +class dotest +{ +public: + dotest() { testfloat3N(); } +} do_test_at_program_startup; diff --git a/examples/Experiments/ImplicitCloth/stan/vec3n.h b/examples/Experiments/ImplicitCloth/stan/vec3n.h index f9a301e8c..c4db53d60 100644 --- a/examples/Experiments/ImplicitCloth/stan/vec3n.h +++ b/examples/Experiments/ImplicitCloth/stan/vec3n.h @@ -1,33 +1,33 @@ // // Big Vector and Sparse Matrix Classes -// +// // (c) S Melax 2006 // -// The focus is on 3D applications, so +// The focus is on 3D applications, so // the big vector is an array of float3s // and the matrix class uses 3x3 blocks. // // This file includes both: -// - basic non-optimized version -// - an expression optimized version +// - basic non-optimized version +// - an expression optimized version // // Optimized Expressions // // We want to write sweet looking code such as V=As+Bt with big vectors. // However, we dont want the extra overheads with allocating memory for temps and excessing copying. -// Instead of a full Template Metaprogramming approach, we explicitly write +// Instead of a full Template Metaprogramming approach, we explicitly write // classes to specifically handle all the expressions we are likely to use. -// Most applicable lines of code will be of the same handful of basic forms, +// Most applicable lines of code will be of the same handful of basic forms, // but with different parameters for the operands. -// In the future, if we ever need a longer expression with more operands, +// In the future, if we ever need a longer expression with more operands, // then we will just add whatever additional building blocks that are necessary - not a big deal. -// This approach is much simpler to develop, debug and optimize (restrict keyword, simd etc) -// than template metaprogramming is. We do not rely on the implementation -// of a particular compiler to be able to expand extensive nested inline codes. -// Additionally, we reliably get our optimizations even within a debug build. -// Therefore we believe that our Optimized Expressions +// This approach is much simpler to develop, debug and optimize (restrict keyword, simd etc) +// than template metaprogramming is. We do not rely on the implementation +// of a particular compiler to be able to expand extensive nested inline codes. +// Additionally, we reliably get our optimizations even within a debug build. +// Therefore we believe that our Optimized Expressions // are a good compromise that give us the best of both worlds. -// The code within those important algorithms, which use this library, +// The code within those important algorithms, which use this library, // can now remain clean and readable yet still execute quickly. // @@ -41,111 +41,144 @@ //template void * vec4::operator new[](size_t n){ return _mm_malloc(n,64); } //template void vec4::operator delete[](void *a) { _mm_free(a); } - -struct HalfConstraint { - float3 n;int vi; - float s,t; - HalfConstraint(const float3& _n,int _vi,float _t):n(_n),vi(_vi),s(0),t(_t){} - HalfConstraint():vi(-1){} +struct HalfConstraint +{ + float3 n; + int vi; + float s, t; + HalfConstraint(const float3 &_n, int _vi, float _t) : n(_n), vi(_vi), s(0), t(_t) {} + HalfConstraint() : vi(-1) {} }; class float3Nx3N { - public: +public: class Block { - public: - + public: float3x3 m; - int r,c; + int r, c; float unused[16]; - - - Block(){} - Block(short _r,short _c):r(_r),c(_c){m.x=m.y=m.z=float3(0,0,0);} + + Block() {} + Block(short _r, short _c) : r(_r), c(_c) { m.x = m.y = m.z = float3(0, 0, 0); } }; Array blocks; // the first n blocks use as the diagonal. - int n; + int n; void Zero(); void InitDiagonal(float d); - void Identity(){InitDiagonal(1.0f);} - float3Nx3N():n(0){} - float3Nx3N(int _n):n(_n) {for(int i=0;i float3Nx3N &operator= (const E& expression) {expression.evalequals(*this);return *this;} - template float3Nx3N &operator+=(const E& expression) {expression.evalpluseq(*this);return *this;} - template float3Nx3N &operator-=(const E& expression) {expression.evalmnuseq(*this);return *this;} + void Identity() { InitDiagonal(1.0f); } + float3Nx3N() : n(0) {} + float3Nx3N(int _n) : n(_n) + { + for (int i = 0; i < n; i++) blocks.Add(Block((short)i, (short)i)); + } + template + float3Nx3N &operator=(const E &expression) + { + expression.evalequals(*this); + return *this; + } + template + float3Nx3N &operator+=(const E &expression) + { + expression.evalpluseq(*this); + return *this; + } + template + float3Nx3N &operator-=(const E &expression) + { + expression.evalmnuseq(*this); + return *this; + } }; -class float3N: public Array +class float3N : public Array { public: - float3N(int _count=0) + float3N(int _count = 0) { SetSize(_count); } void Zero(); void Init(const float3 &v); // sets each subvector to v - template float3N &operator= (const E& expression) {expression.evalequals(*this);return *this;} - template float3N &operator+=(const E& expression) {expression.evalpluseq(*this);return *this;} - template float3N &operator-=(const E& expression) {expression.evalmnuseq(*this);return *this;} - float3N &operator=( const float3N &V) { this->copy(V); return *this;} + template + float3N &operator=(const E &expression) + { + expression.evalequals(*this); + return *this; + } + template + float3N &operator+=(const E &expression) + { + expression.evalpluseq(*this); + return *this; + } + template + float3N &operator-=(const E &expression) + { + expression.evalmnuseq(*this); + return *this; + } + float3N &operator=(const float3N &V) + { + this->copy(V); + return *this; + } }; -int ConjGradient(float3N &X, float3Nx3N &A, float3N &B); -int ConjGradientFiltered(float3N &X, const float3Nx3N &A, const float3N &B,const float3Nx3N &S,Array &H); -int ConjGradientFiltered(float3N &X, const float3Nx3N &A, const float3N &B,const float3Nx3N &S); +int ConjGradient(float3N &X, float3Nx3N &A, float3N &B); +int ConjGradientFiltered(float3N &X, const float3Nx3N &A, const float3N &B, const float3Nx3N &S, Array &H); +int ConjGradientFiltered(float3N &X, const float3Nx3N &A, const float3N &B, const float3Nx3N &S); -inline float3N& Mul(float3N &r,const float3Nx3N &m, const float3N &v) +inline float3N &Mul(float3N &r, const float3Nx3N &m, const float3N &v) { int i; - for(i=0;i // for memcpy +#include // for memcpy #include -float squared(float a){return a*a;} -float clamp(float a,const float minval, const float maxval) {return Min(maxval,Max(minval,a));} -int clamp(int a,const int minval, const int maxval) {return Min(maxval,Max(minval,a));} +float squared(float a) { return a * a; } +float clamp(float a, const float minval, const float maxval) { return Min(maxval, Max(minval, a)); } +int clamp(int a, const int minval, const int maxval) { return Min(maxval, Max(minval, a)); } - -float Round(float a,float precision) +float Round(float a, float precision) { - return floorf(0.5f+a/precision)*precision; + return floorf(0.5f + a / precision) * precision; } - -float Interpolate(const float &f0,const float &f1,float alpha) +float Interpolate(const float &f0, const float &f1, float alpha) { - return f0*(1-alpha) + f1*alpha; + return f0 * (1 - alpha) + f1 * alpha; } - -int argmin(const float a[],int n) +int argmin(const float a[], int n) { - int r=0; - for(int i=1;ia[r]) + if (a[i] < a[r]) { - r = i; + r = i; } } return r; } - +int argmax(const float a[], int n) +{ + int r = 0; + for (int i = 1; i < n; i++) + { + if (a[i] > a[r]) + { + r = i; + } + } + return r; +} //------------ float3 (3D) -------------- - - float3 vabs(const float3 &v) { - return float3(fabsf(v.x),fabsf(v.y),fabsf(v.z)); + return float3(fabsf(v.x), fabsf(v.y), fabsf(v.z)); } - - float3 safenormalize(const float3 &v) { - if(magnitude(v)<=0.0f) + if (magnitude(v) <= 0.0f) { - return float3(1,0,0); + return float3(1, 0, 0); } return normalize(v); } -float3 Round(const float3 &a,float precision) +float3 Round(const float3 &a, float precision) { - return float3(Round(a.x,precision),Round(a.y,precision),Round(a.z,precision)); + return float3(Round(a.x, precision), Round(a.y, precision), Round(a.z, precision)); } - -float3 Interpolate(const float3 &v0,const float3 &v1,float alpha) +float3 Interpolate(const float3 &v0, const float3 &v1, float alpha) { - return v0*(1-alpha) + v1*alpha; + return v0 * (1 - alpha) + v1 * alpha; } -float3 Orth(const float3& v) +float3 Orth(const float3 &v) { - float3 absv=vabs(v); - float3 u(1,1,1); - u[argmax(&absv[0],3)] =0.0f; - return normalize(cross(u,v)); + float3 absv = vabs(v); + float3 u(1, 1, 1); + u[argmax(&absv[0], 3)] = 0.0f; + return normalize(cross(u, v)); } -void BoxLimits(const float3 *verts,int verts_count, float3 &bmin,float3 &bmax) +void BoxLimits(const float3 *verts, int verts_count, float3 &bmin, float3 &bmax) { - bmin=float3( FLT_MAX, FLT_MAX, FLT_MAX); - bmax=float3(-FLT_MAX,-FLT_MAX,-FLT_MAX); - for(int i=0;ibmaxb[j]) return 0; - if(bminb[j]>bmaxa[j]) return 0; + bmin = VectorMin(bmin, verts[i].xyz()); + bmax = VectorMax(bmax, verts[i].xyz()); + } +} +int overlap(const float3 &bmina, const float3 &bmaxa, const float3 &bminb, const float3 &bmaxb) +{ + for (int j = 0; j < 3; j++) + { + if (bmina[j] > bmaxb[j]) return 0; + if (bminb[j] > bmaxa[j]) return 0; } return 1; } @@ -131,115 +120,109 @@ int overlap(const float3 &bmina,const float3 &bmaxa,const float3 &bminb,const fl // - dot product // - cross product // Therefore we never declare/implement this function. -// So we will never see: float3 operator*(float3 a,float3 b) - - - +// So we will never see: float3 operator*(float3 a,float3 b) //------------ float3x3 --------------- float Determinant(const float3x3 &m) { - return m.x.x*m.y.y*m.z.z + m.y.x*m.z.y*m.x.z + m.z.x*m.x.y*m.y.z - -m.x.x*m.z.y*m.y.z - m.y.x*m.x.y*m.z.z - m.z.x*m.y.y*m.x.z ; + return m.x.x * m.y.y * m.z.z + m.y.x * m.z.y * m.x.z + m.z.x * m.x.y * m.y.z - m.x.x * m.z.y * m.y.z - m.y.x * m.x.y * m.z.z - m.z.x * m.y.y * m.x.z; } float3x3 Inverse(const float3x3 &a) { float3x3 b; - float d=Determinant(a); - assert(d!=0); - for(int i=0;i<3;i++) - { - for(int j=0;j<3;j++) - { - int i1=(i+1)%3; - int i2=(i+2)%3; - int j1=(j+1)%3; - int j2=(j+2)%3; + float d = Determinant(a); + assert(d != 0); + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 3; j++) + { + int i1 = (i + 1) % 3; + int i2 = (i + 2) % 3; + int j1 = (j + 1) % 3; + int j2 = (j + 2) % 3; // reverse indexs i&j to take transpose - b[j][i] = (a[i1][j1]*a[i2][j2]-a[i1][j2]*a[i2][j1])/d; + b[j][i] = (a[i1][j1] * a[i2][j2] - a[i1][j2] * a[i2][j1]) / d; } } // Matrix check=a*b; // Matrix 'check' should be the identity (or close to it) return b; } - -float3x3 Transpose( const float3x3& m ) +float3x3 Transpose(const float3x3 &m) { - return float3x3( float3(m.x.x,m.y.x,m.z.x), - float3(m.x.y,m.y.y,m.z.y), - float3(m.x.z,m.y.z,m.z.z)); + return float3x3(float3(m.x.x, m.y.x, m.z.x), + float3(m.x.y, m.y.y, m.z.y), + float3(m.x.z, m.y.z, m.z.z)); } - -float3 operator*(const float3& v , const float3x3 &m ) { - return float3((m.x.x*v.x + m.y.x*v.y + m.z.x*v.z), - (m.x.y*v.x + m.y.y*v.y + m.z.y*v.z), - (m.x.z*v.x + m.y.z*v.y + m.z.z*v.z)); -} -float3 operator*(const float3x3 &m,const float3& v ) { - return float3(dot(m.x,v),dot(m.y,v),dot(m.z,v)); -} - - -float3x3 operator*( const float3x3& a, const float3x3& b ) -{ - return float3x3(a.x*b,a.y*b,a.z*b); -} - -float3x3 operator*( const float3x3& a, const float& s ) -{ - return float3x3(a.x*s, a.y*s ,a.z*s); -} -float3x3 operator/( const float3x3& a, const float& s ) -{ - float t=1/s; - return float3x3(a.x*t, a.y*t ,a.z*t); -} -float3x3 operator+( const float3x3& a, const float3x3& b ) +float3 operator*(const float3 &v, const float3x3 &m) { - return float3x3(a.x+b.x, a.y+b.y, a.z+b.z); + return float3((m.x.x * v.x + m.y.x * v.y + m.z.x * v.z), + (m.x.y * v.x + m.y.y * v.y + m.z.y * v.z), + (m.x.z * v.x + m.y.z * v.y + m.z.z * v.z)); } -float3x3 operator-( const float3x3& a, const float3x3& b ) +float3 operator*(const float3x3 &m, const float3 &v) { - return float3x3(a.x-b.x, a.y-b.y, a.z-b.z); + return float3(dot(m.x, v), dot(m.y, v), dot(m.z, v)); } -float3x3 &operator+=( float3x3& a, const float3x3& b ) + +float3x3 operator*(const float3x3 &a, const float3x3 &b) { - a.x+=b.x; - a.y+=b.y; - a.z+=b.z; + return float3x3(a.x * b, a.y * b, a.z * b); +} + +float3x3 operator*(const float3x3 &a, const float &s) +{ + return float3x3(a.x * s, a.y * s, a.z * s); +} +float3x3 operator/(const float3x3 &a, const float &s) +{ + float t = 1 / s; + return float3x3(a.x * t, a.y * t, a.z * t); +} +float3x3 operator+(const float3x3 &a, const float3x3 &b) +{ + return float3x3(a.x + b.x, a.y + b.y, a.z + b.z); +} +float3x3 operator-(const float3x3 &a, const float3x3 &b) +{ + return float3x3(a.x - b.x, a.y - b.y, a.z - b.z); +} +float3x3 &operator+=(float3x3 &a, const float3x3 &b) +{ + a.x += b.x; + a.y += b.y; + a.z += b.z; return a; } -float3x3 &operator-=( float3x3& a, const float3x3& b ) +float3x3 &operator-=(float3x3 &a, const float3x3 &b) { - a.x-=b.x; - a.y-=b.y; - a.z-=b.z; + a.x -= b.x; + a.y -= b.y; + a.z -= b.z; return a; } -float3x3 &operator*=( float3x3& a, const float& s ) +float3x3 &operator*=(float3x3 &a, const float &s) { - a.x*=s; - a.y*=s; - a.z*=s; + a.x *= s; + a.y *= s; + a.z *= s; return a; } -float3x3 outerprod(const float3& a,const float3& b) +float3x3 outerprod(const float3 &a, const float3 &b) { - return float3x3(a.x*b,a.y*b,a.z*b); // a is a column vector b is a row vector + return float3x3(a.x * b, a.y * b, a.z * b); // a is a column vector b is a row vector } //--------------- 4D ---------------- -float4 operator*( const float4& v, const float4x4& m ) +float4 operator*(const float4 &v, const float4x4 &m) { - return v.x*m.x + v.y*m.y + v.z*m.z + v.w*m.w; // yes this actually works + return v.x * m.x + v.y * m.y + v.z * m.z + v.w * m.w; // yes this actually works } - // Dont implement m*v for now, since that might confuse us // All our transforms are based on multiplying the "row" vector on the left //float4 operator*(const float4x4& m , const float4& v ) @@ -247,10 +230,9 @@ float4 operator*( const float4& v, const float4x4& m ) // return float4(dot(v,m.x),dot(v,m.y),dot(v,m.z),dot(v,m.w)); //} - -float4x4 operator*( const float4x4& a, const float4x4& b ) +float4x4 operator*(const float4x4 &a, const float4x4 &b) { - return float4x4(a.x*b,a.y*b,a.z*b,a.w*b); + return float4x4(a.x * b, a.y * b, a.z * b, a.w * b); } float4x4 MatrixTranspose(const float4x4 &m) @@ -259,450 +241,435 @@ float4x4 MatrixTranspose(const float4x4 &m) m.x.x, m.y.x, m.z.x, m.w.x, m.x.y, m.y.y, m.z.y, m.w.y, m.x.z, m.y.z, m.z.z, m.w.z, - m.x.w, m.y.w, m.z.w, m.w.w ); + m.x.w, m.y.w, m.z.w, m.w.w); } float4x4 MatrixRigidInverse(const float4x4 &m) { float4x4 trans_inverse = MatrixTranslation(-m.w.xyz()); - float4x4 rot = m; - rot.w = float4(0,0,0,1); + float4x4 rot = m; + rot.w = float4(0, 0, 0, 1); return trans_inverse * MatrixTranspose(rot); } - -float4x4 MatrixPerspectiveFov(float fovy, float aspect, float zn, float zf ) +float4x4 MatrixPerspectiveFov(float fovy, float aspect, float zn, float zf) { - float h = 1.0f/tanf(fovy/2.0f); // view space height - float w = h / aspect ; // view space width + float h = 1.0f / tanf(fovy / 2.0f); // view space height + float w = h / aspect; // view space width return float4x4( - w, 0, 0 , 0, - 0, h, 0 , 0, - 0, 0, zf/(zn-zf) , -1, - 0, 0, zn*zf/(zn-zf) , 0 ); + w, 0, 0, 0, + 0, h, 0, 0, + 0, 0, zf / (zn - zf), -1, + 0, 0, zn * zf / (zn - zf), 0); } - - -float4x4 MatrixLookAt(const float3& eye, const float3& at, const float3& up) +float4x4 MatrixLookAt(const float3 &eye, const float3 &at, const float3 &up) { float4x4 m; m.w.w = 1.0f; m.w.xyz() = eye; - m.z.xyz() = normalize(eye-at); - m.x.xyz() = normalize(cross(up,m.z.xyz())); - m.y.xyz() = cross(m.z.xyz(),m.x.xyz()); + m.z.xyz() = normalize(eye - at); + m.x.xyz() = normalize(cross(up, m.z.xyz())); + m.y.xyz() = cross(m.z.xyz(), m.x.xyz()); return MatrixRigidInverse(m); } - float4x4 MatrixTranslation(const float3 &t) { return float4x4( - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - t.x,t.y,t.z,1 ); + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + t.x, t.y, t.z, 1); } - float4x4 MatrixRotationZ(const float angle_radians) { - float s = sinf(angle_radians); - float c = cosf(angle_radians); + float s = sinf(angle_radians); + float c = cosf(angle_radians); return float4x4( - c, s, 0, 0, - -s, c, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 ); + c, s, 0, 0, + -s, c, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); } - - -int operator==( const float4x4 &a, const float4x4 &b ) +int operator==(const float4x4 &a, const float4x4 &b) { - return (a.x==b.x && a.y==b.y && a.z==b.z && a.w==b.w); + return (a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w); } - float4x4 Inverse(const float4x4 &m) { float4x4 d; float *dst = &d.x.x; float tmp[12]; /* temp array for pairs */ float src[16]; /* array of transpose source matrix */ - float det; /* determinant */ + float det; /* determinant */ /* transpose matrix */ - for ( int i = 0; i < 4; i++) { - src[i] = m(i,0) ; - src[i + 4] = m(i,1); - src[i + 8] = m(i,2); - src[i + 12] = m(i,3); + for (int i = 0; i < 4; i++) + { + src[i] = m(i, 0); + src[i + 4] = m(i, 1); + src[i + 8] = m(i, 2); + src[i + 12] = m(i, 3); } /* calculate pairs for first 8 elements (cofactors) */ - tmp[0] = src[10] * src[15]; - tmp[1] = src[11] * src[14]; - tmp[2] = src[9] * src[15]; - tmp[3] = src[11] * src[13]; - tmp[4] = src[9] * src[14]; - tmp[5] = src[10] * src[13]; - tmp[6] = src[8] * src[15]; - tmp[7] = src[11] * src[12]; - tmp[8] = src[8] * src[14]; - tmp[9] = src[10] * src[12]; + tmp[0] = src[10] * src[15]; + tmp[1] = src[11] * src[14]; + tmp[2] = src[9] * src[15]; + tmp[3] = src[11] * src[13]; + tmp[4] = src[9] * src[14]; + tmp[5] = src[10] * src[13]; + tmp[6] = src[8] * src[15]; + tmp[7] = src[11] * src[12]; + tmp[8] = src[8] * src[14]; + tmp[9] = src[10] * src[12]; tmp[10] = src[8] * src[13]; tmp[11] = src[9] * src[12]; /* calculate first 8 elements (cofactors) */ - dst[0] = tmp[0]*src[5] + tmp[3]*src[6] + tmp[4]*src[7]; - dst[0] -= tmp[1]*src[5] + tmp[2]*src[6] + tmp[5]*src[7]; - dst[1] = tmp[1]*src[4] + tmp[6]*src[6] + tmp[9]*src[7]; - dst[1] -= tmp[0]*src[4] + tmp[7]*src[6] + tmp[8]*src[7]; - dst[2] = tmp[2]*src[4] + tmp[7]*src[5] + tmp[10]*src[7]; - dst[2] -= tmp[3]*src[4] + tmp[6]*src[5] + tmp[11]*src[7]; - dst[3] = tmp[5]*src[4] + tmp[8]*src[5] + tmp[11]*src[6]; - dst[3] -= tmp[4]*src[4] + tmp[9]*src[5] + tmp[10]*src[6]; - dst[4] = tmp[1]*src[1] + tmp[2]*src[2] + tmp[5]*src[3]; - dst[4] -= tmp[0]*src[1] + tmp[3]*src[2] + tmp[4]*src[3]; - dst[5] = tmp[0]*src[0] + tmp[7]*src[2] + tmp[8]*src[3]; - dst[5] -= tmp[1]*src[0] + tmp[6]*src[2] + tmp[9]*src[3]; - dst[6] = tmp[3]*src[0] + tmp[6]*src[1] + tmp[11]*src[3]; - dst[6] -= tmp[2]*src[0] + tmp[7]*src[1] + tmp[10]*src[3]; - dst[7] = tmp[4]*src[0] + tmp[9]*src[1] + tmp[10]*src[2]; - dst[7] -= tmp[5]*src[0] + tmp[8]*src[1] + tmp[11]*src[2]; + dst[0] = tmp[0] * src[5] + tmp[3] * src[6] + tmp[4] * src[7]; + dst[0] -= tmp[1] * src[5] + tmp[2] * src[6] + tmp[5] * src[7]; + dst[1] = tmp[1] * src[4] + tmp[6] * src[6] + tmp[9] * src[7]; + dst[1] -= tmp[0] * src[4] + tmp[7] * src[6] + tmp[8] * src[7]; + dst[2] = tmp[2] * src[4] + tmp[7] * src[5] + tmp[10] * src[7]; + dst[2] -= tmp[3] * src[4] + tmp[6] * src[5] + tmp[11] * src[7]; + dst[3] = tmp[5] * src[4] + tmp[8] * src[5] + tmp[11] * src[6]; + dst[3] -= tmp[4] * src[4] + tmp[9] * src[5] + tmp[10] * src[6]; + dst[4] = tmp[1] * src[1] + tmp[2] * src[2] + tmp[5] * src[3]; + dst[4] -= tmp[0] * src[1] + tmp[3] * src[2] + tmp[4] * src[3]; + dst[5] = tmp[0] * src[0] + tmp[7] * src[2] + tmp[8] * src[3]; + dst[5] -= tmp[1] * src[0] + tmp[6] * src[2] + tmp[9] * src[3]; + dst[6] = tmp[3] * src[0] + tmp[6] * src[1] + tmp[11] * src[3]; + dst[6] -= tmp[2] * src[0] + tmp[7] * src[1] + tmp[10] * src[3]; + dst[7] = tmp[4] * src[0] + tmp[9] * src[1] + tmp[10] * src[2]; + dst[7] -= tmp[5] * src[0] + tmp[8] * src[1] + tmp[11] * src[2]; /* calculate pairs for second 8 elements (cofactors) */ - tmp[0] = src[2]*src[7]; - tmp[1] = src[3]*src[6]; - tmp[2] = src[1]*src[7]; - tmp[3] = src[3]*src[5]; - tmp[4] = src[1]*src[6]; - tmp[5] = src[2]*src[5]; - tmp[6] = src[0]*src[7]; - tmp[7] = src[3]*src[4]; - tmp[8] = src[0]*src[6]; - tmp[9] = src[2]*src[4]; - tmp[10] = src[0]*src[5]; - tmp[11] = src[1]*src[4]; + tmp[0] = src[2] * src[7]; + tmp[1] = src[3] * src[6]; + tmp[2] = src[1] * src[7]; + tmp[3] = src[3] * src[5]; + tmp[4] = src[1] * src[6]; + tmp[5] = src[2] * src[5]; + tmp[6] = src[0] * src[7]; + tmp[7] = src[3] * src[4]; + tmp[8] = src[0] * src[6]; + tmp[9] = src[2] * src[4]; + tmp[10] = src[0] * src[5]; + tmp[11] = src[1] * src[4]; /* calculate second 8 elements (cofactors) */ - dst[8] = tmp[0]*src[13] + tmp[3]*src[14] + tmp[4]*src[15]; - dst[8] -= tmp[1]*src[13] + tmp[2]*src[14] + tmp[5]*src[15]; - dst[9] = tmp[1]*src[12] + tmp[6]*src[14] + tmp[9]*src[15]; - dst[9] -= tmp[0]*src[12] + tmp[7]*src[14] + tmp[8]*src[15]; - dst[10] = tmp[2]*src[12] + tmp[7]*src[13] + tmp[10]*src[15]; - dst[10]-= tmp[3]*src[12] + tmp[6]*src[13] + tmp[11]*src[15]; - dst[11] = tmp[5]*src[12] + tmp[8]*src[13] + tmp[11]*src[14]; - dst[11]-= tmp[4]*src[12] + tmp[9]*src[13] + tmp[10]*src[14]; - dst[12] = tmp[2]*src[10] + tmp[5]*src[11] + tmp[1]*src[9]; - dst[12]-= tmp[4]*src[11] + tmp[0]*src[9] + tmp[3]*src[10]; - dst[13] = tmp[8]*src[11] + tmp[0]*src[8] + tmp[7]*src[10]; - dst[13]-= tmp[6]*src[10] + tmp[9]*src[11] + tmp[1]*src[8]; - dst[14] = tmp[6]*src[9] + tmp[11]*src[11] + tmp[3]*src[8]; - dst[14]-= tmp[10]*src[11] + tmp[2]*src[8] + tmp[7]*src[9]; - dst[15] = tmp[10]*src[10] + tmp[4]*src[8] + tmp[9]*src[9]; - dst[15]-= tmp[8]*src[9] + tmp[11]*src[10] + tmp[5]*src[8]; + dst[8] = tmp[0] * src[13] + tmp[3] * src[14] + tmp[4] * src[15]; + dst[8] -= tmp[1] * src[13] + tmp[2] * src[14] + tmp[5] * src[15]; + dst[9] = tmp[1] * src[12] + tmp[6] * src[14] + tmp[9] * src[15]; + dst[9] -= tmp[0] * src[12] + tmp[7] * src[14] + tmp[8] * src[15]; + dst[10] = tmp[2] * src[12] + tmp[7] * src[13] + tmp[10] * src[15]; + dst[10] -= tmp[3] * src[12] + tmp[6] * src[13] + tmp[11] * src[15]; + dst[11] = tmp[5] * src[12] + tmp[8] * src[13] + tmp[11] * src[14]; + dst[11] -= tmp[4] * src[12] + tmp[9] * src[13] + tmp[10] * src[14]; + dst[12] = tmp[2] * src[10] + tmp[5] * src[11] + tmp[1] * src[9]; + dst[12] -= tmp[4] * src[11] + tmp[0] * src[9] + tmp[3] * src[10]; + dst[13] = tmp[8] * src[11] + tmp[0] * src[8] + tmp[7] * src[10]; + dst[13] -= tmp[6] * src[10] + tmp[9] * src[11] + tmp[1] * src[8]; + dst[14] = tmp[6] * src[9] + tmp[11] * src[11] + tmp[3] * src[8]; + dst[14] -= tmp[10] * src[11] + tmp[2] * src[8] + tmp[7] * src[9]; + dst[15] = tmp[10] * src[10] + tmp[4] * src[8] + tmp[9] * src[9]; + dst[15] -= tmp[8] * src[9] + tmp[11] * src[10] + tmp[5] * src[8]; /* calculate determinant */ - det=src[0]*dst[0]+src[1]*dst[1]+src[2]*dst[2]+src[3]*dst[3]; + det = src[0] * dst[0] + src[1] * dst[1] + src[2] * dst[2] + src[3] * dst[3]; /* calculate matrix inverse */ - det = 1/det; - for ( int j = 0; j < 16; j++) - dst[j] *= det; + det = 1 / det; + for (int j = 0; j < 16; j++) + dst[j] *= det; return d; } - //--------- Quaternion -------------- - -template<> void Quaternion::Normalize() + +template <> +void Quaternion::Normalize() { - float m = sqrtf(squared(w)+squared(x)+squared(y)+squared(z)); - if(m<0.000000001f) { - w=1.0f; - x=y=z=0.0f; + float m = sqrtf(squared(w) + squared(x) + squared(y) + squared(z)); + if (m < 0.000000001f) + { + w = 1.0f; + x = y = z = 0.0f; return; } - (*this) *= (1.0f/m); + (*this) *= (1.0f / m); } -float3 rotate( const Quaternion& q, const float3& v ) +float3 rotate(const Quaternion &q, const float3 &v) { - // The following is equivalent to: - //return (q.getmatrix() * v); - float qx2 = q.x*q.x; - float qy2 = q.y*q.y; - float qz2 = q.z*q.z; + // The following is equivalent to: + //return (q.getmatrix() * v); + float qx2 = q.x * q.x; + float qy2 = q.y * q.y; + float qz2 = q.z * q.z; - float qxqy = q.x*q.y; - float qxqz = q.x*q.z; - float qxqw = q.x*q.w; - float qyqz = q.y*q.z; - float qyqw = q.y*q.w; - float qzqw = q.z*q.w; + float qxqy = q.x * q.y; + float qxqz = q.x * q.z; + float qxqw = q.x * q.w; + float qyqz = q.y * q.z; + float qyqw = q.y * q.w; + float qzqw = q.z * q.w; return float3( - (1-2*(qy2+qz2))*v.x + (2*(qxqy-qzqw))*v.y + (2*(qxqz+qyqw))*v.z , - (2*(qxqy+qzqw))*v.x + (1-2*(qx2+qz2))*v.y + (2*(qyqz-qxqw))*v.z , - (2*(qxqz-qyqw))*v.x + (2*(qyqz+qxqw))*v.y + (1-2*(qx2+qy2))*v.z ); + (1 - 2 * (qy2 + qz2)) * v.x + (2 * (qxqy - qzqw)) * v.y + (2 * (qxqz + qyqw)) * v.z, + (2 * (qxqy + qzqw)) * v.x + (1 - 2 * (qx2 + qz2)) * v.y + (2 * (qyqz - qxqw)) * v.z, + (2 * (qxqz - qyqw)) * v.x + (2 * (qyqz + qxqw)) * v.y + (1 - 2 * (qx2 + qy2)) * v.z); } - -Quaternion slerp(const Quaternion &_a, const Quaternion& b, float interp ) +Quaternion slerp(const Quaternion &_a, const Quaternion &b, float interp) { - Quaternion a=_a; - if(dot(a,b) <0.0) - { - a.w=-a.w; - a.x=-a.x; - a.y=-a.y; - a.z=-a.z; + Quaternion a = _a; + if (dot(a, b) < 0.0) + { + a.w = -a.w; + a.x = -a.x; + a.y = -a.y; + a.z = -a.z; } - float d = dot(a,b); - if(d>=1.0) { + float d = dot(a, b); + if (d >= 1.0) + { return a; } float theta = acosf(d); - if(theta==0.0f) { return(a);} - return a*(sinf(theta-interp*theta)/sinf(theta)) + b*(sinf(interp*theta)/sinf(theta)); + if (theta == 0.0f) + { + return (a); + } + return a * (sinf(theta - interp * theta) / sinf(theta)) + b * (sinf(interp * theta) / sinf(theta)); } - -Quaternion Interpolate(const Quaternion &q0,const Quaternion &q1,float alpha) { - return slerp(q0,q1,alpha); -} - - -Quaternion YawPitchRoll( float yaw, float pitch, float roll ) +Quaternion Interpolate(const Quaternion &q0, const Quaternion &q1, float alpha) { - return QuatFromAxisAngle(float3(0.0f,0.0f,1.0f),DegToRad(yaw )) - * QuatFromAxisAngle(float3(1.0f,0.0f,0.0f),DegToRad(pitch)) - * QuatFromAxisAngle(float3(0.0f,1.0f,0.0f),DegToRad(roll )); + return slerp(q0, q1, alpha); } -float Yaw( const Quaternion& q ) +Quaternion YawPitchRoll(float yaw, float pitch, float roll) +{ + return QuatFromAxisAngle(float3(0.0f, 0.0f, 1.0f), DegToRad(yaw)) * QuatFromAxisAngle(float3(1.0f, 0.0f, 0.0f), DegToRad(pitch)) * QuatFromAxisAngle(float3(0.0f, 1.0f, 0.0f), DegToRad(roll)); +} + +float Yaw(const Quaternion &q) { static float3 v; - v=q.ydir(); - return (v.y==0.0&&v.x==0.0) ? 0.0f: RadToDeg(atan2f(-v.x,v.y)); + v = q.ydir(); + return (v.y == 0.0 && v.x == 0.0) ? 0.0f : RadToDeg(atan2f(-v.x, v.y)); } -float Pitch( const Quaternion& q ) +float Pitch(const Quaternion &q) { static float3 v; - v=q.ydir(); - return RadToDeg(atan2f(v.z,sqrtf(squared(v.x)+squared(v.y)))); + v = q.ydir(); + return RadToDeg(atan2f(v.z, sqrtf(squared(v.x) + squared(v.y)))); } -float Roll( const Quaternion &_q ) +float Roll(const Quaternion &_q) { - Quaternion q=_q; - q = QuatFromAxisAngle(float3(0.0f,0.0f,1.0f),-DegToRad(Yaw(q))) *q; - q = QuatFromAxisAngle(float3(1.0f,0.0f,0.0f),-DegToRad(Pitch(q))) *q; - return RadToDeg(atan2f(-q.xdir().z,q.xdir().x)); + Quaternion q = _q; + q = QuatFromAxisAngle(float3(0.0f, 0.0f, 1.0f), -DegToRad(Yaw(q))) * q; + q = QuatFromAxisAngle(float3(1.0f, 0.0f, 0.0f), -DegToRad(Pitch(q))) * q; + return RadToDeg(atan2f(-q.xdir().z, q.xdir().x)); } -float Yaw( const float3& v ) +float Yaw(const float3 &v) { - return (v.y==0.0&&v.x==0.0) ? 0.0f: RadToDeg(atan2f(-v.x,v.y)); + return (v.y == 0.0 && v.x == 0.0) ? 0.0f : RadToDeg(atan2f(-v.x, v.y)); } -float Pitch( const float3& v ) +float Pitch(const float3 &v) { - return RadToDeg(atan2f(v.z,sqrtf(squared(v.x)+squared(v.y)))); + return RadToDeg(atan2f(v.z, sqrtf(squared(v.x) + squared(v.y)))); } - - - - - //--------- utility functions ------------- // RotationArc() // Given two vectors v0 and v1 this function // returns quaternion q where q*v0==v1. // Routine taken from game programming gems. -Quaternion RotationArc(float3 v0,float3 v1){ +Quaternion RotationArc(float3 v0, float3 v1) +{ static Quaternion q; v0 = normalize(v0); // Comment these two lines out if you know its not needed. v1 = normalize(v1); // If vector is already unit length then why do it again? - float3 c = cross(v0,v1); - float d = dot(v0,v1); - if(d<=-1.0f) { float3 a=Orth(v0); return Quaternion(a.x,a.y,a.z,0);} // 180 about any orthogonal axis axis - float s = sqrtf((1+d)*2); + float3 c = cross(v0, v1); + float d = dot(v0, v1); + if (d <= -1.0f) + { + float3 a = Orth(v0); + return Quaternion(a.x, a.y, a.z, 0); + } // 180 about any orthogonal axis axis + float s = sqrtf((1 + d) * 2); q.x = c.x / s; q.y = c.y / s; q.z = c.z / s; - q.w = s /2.0f; + q.w = s / 2.0f; return q; } - -float4x4 MatrixFromQuatVec(const Quaternion &q, const float3 &v) +float4x4 MatrixFromQuatVec(const Quaternion &q, const float3 &v) { - // builds a 4x4 transformation matrix based on orientation q and translation v - float qx2 = q.x*q.x; - float qy2 = q.y*q.y; - float qz2 = q.z*q.z; + // builds a 4x4 transformation matrix based on orientation q and translation v + float qx2 = q.x * q.x; + float qy2 = q.y * q.y; + float qz2 = q.z * q.z; - float qxqy = q.x*q.y; - float qxqz = q.x*q.z; - float qxqw = q.x*q.w; - float qyqz = q.y*q.z; - float qyqw = q.y*q.w; - float qzqw = q.z*q.w; + float qxqy = q.x * q.y; + float qxqz = q.x * q.z; + float qxqw = q.x * q.w; + float qyqz = q.y * q.z; + float qyqw = q.y * q.w; + float qzqw = q.z * q.w; return float4x4( - 1-2*(qy2+qz2), - 2*(qxqy+qzqw), - 2*(qxqz-qyqw), - 0 , - 2*(qxqy-qzqw), - 1-2*(qx2+qz2), - 2*(qyqz+qxqw), - 0 , - 2*(qxqz+qyqw), - 2*(qyqz-qxqw), - 1-2*(qx2+qy2), - 0 , - v.x , - v.y , - v.z , - 1.0f ); + 1 - 2 * (qy2 + qz2), + 2 * (qxqy + qzqw), + 2 * (qxqz - qyqw), + 0, + 2 * (qxqy - qzqw), + 1 - 2 * (qx2 + qz2), + 2 * (qyqz + qxqw), + 0, + 2 * (qxqz + qyqw), + 2 * (qyqz - qxqw), + 1 - 2 * (qx2 + qy2), + 0, + v.x, + v.y, + v.z, + 1.0f); } - - -float3 PlaneLineIntersection(const float3 &normal,const float dist, const float3 &p0, const float3 &p1) +float3 PlaneLineIntersection(const float3 &normal, const float dist, const float3 &p0, const float3 &p1) { // returns the point where the line p0-p1 intersects the plane n&d float3 dif; - dif = p1-p0; - float dn= dot(normal,dif); - float t = -(dist+dot(normal,p0) )/dn; - return p0 + (dif*t); + dif = p1 - p0; + float dn = dot(normal, dif); + float t = -(dist + dot(normal, p0)) / dn; + return p0 + (dif * t); } float3 LineProject(const float3 &p0, const float3 &p1, const float3 &a) { // project point a on segment [p0,p1] - float3 d= p1-p0; - float t= dot(d,(a-p0)) / dot(d,d); - return p0+ d*t; + float3 d = p1 - p0; + float t = dot(d, (a - p0)) / dot(d, d); + return p0 + d * t; } - float LineProjectTime(const float3 &p0, const float3 &p1, const float3 &a) { // project point a on segment [p0,p1] - float3 d= p1-p0; - float t= dot(d,(a-p0)) / dot(d,d); + float3 d = p1 - p0; + float t = dot(d, (a - p0)) / dot(d, d); return t; } - - float3 TriNormal(const float3 &v0, const float3 &v1, const float3 &v2) { // return the normal of the triangle // inscribed by v0, v1, and v2 - float3 cp=cross(v1-v0,v2-v1); - float m=magnitude(cp); - if(m==0) return float3(1,0,0); - return cp*(1.0f/m); + float3 cp = cross(v1 - v0, v2 - v1); + float m = magnitude(cp); + if (m == 0) return float3(1, 0, 0); + return cp * (1.0f / m); } - - -int BoxInside(const float3 &p, const float3 &bmin, const float3 &bmax) +int BoxInside(const float3 &p, const float3 &bmin, const float3 &bmax) { - return (p.x >= bmin.x && p.x <=bmax.x && - p.y >= bmin.y && p.y <=bmax.y && - p.z >= bmin.z && p.z <=bmax.z ); + return (p.x >= bmin.x && p.x <= bmax.x && + p.y >= bmin.y && p.y <= bmax.y && + p.z >= bmin.z && p.z <= bmax.z); } - -int BoxIntersect(const float3 &v0, const float3 &v1, const float3 &bmin, const float3 &bmax,float3 *impact) +int BoxIntersect(const float3 &v0, const float3 &v1, const float3 &bmin, const float3 &bmax, float3 *impact) { - if(BoxInside(v0,bmin,bmax)) - { - *impact=v0; - return 1; - } - if(v0.x<=bmin.x && v1.x>=bmin.x) - { - float a = (bmin.x-v0.x)/(v1.x-v0.x); + if (BoxInside(v0, bmin, bmax)) + { + *impact = v0; + return 1; + } + if (v0.x <= bmin.x && v1.x >= bmin.x) + { + float a = (bmin.x - v0.x) / (v1.x - v0.x); //v.x = bmin.x; - float vy = (1-a) *v0.y + a*v1.y; - float vz = (1-a) *v0.z + a*v1.z; - if(vy>=bmin.y && vy<=bmax.y && vz>=bmin.z && vz<=bmax.z) - { + float vy = (1 - a) * v0.y + a * v1.y; + float vz = (1 - a) * v0.z + a * v1.z; + if (vy >= bmin.y && vy <= bmax.y && vz >= bmin.z && vz <= bmax.z) + { impact->x = bmin.x; impact->y = vy; impact->z = vz; return 1; } } - else if(v0.x >= bmax.x && v1.x <= bmax.x) - { - float a = (bmax.x-v0.x)/(v1.x-v0.x); + else if (v0.x >= bmax.x && v1.x <= bmax.x) + { + float a = (bmax.x - v0.x) / (v1.x - v0.x); //v.x = bmax.x; - float vy = (1-a) *v0.y + a*v1.y; - float vz = (1-a) *v0.z + a*v1.z; - if(vy>=bmin.y && vy<=bmax.y && vz>=bmin.z && vz<=bmax.z) - { + float vy = (1 - a) * v0.y + a * v1.y; + float vz = (1 - a) * v0.z + a * v1.z; + if (vy >= bmin.y && vy <= bmax.y && vz >= bmin.z && vz <= bmax.z) + { impact->x = bmax.x; impact->y = vy; impact->z = vz; return 1; } } - if(v0.y<=bmin.y && v1.y>=bmin.y) - { - float a = (bmin.y-v0.y)/(v1.y-v0.y); - float vx = (1-a) *v0.x + a*v1.x; + if (v0.y <= bmin.y && v1.y >= bmin.y) + { + float a = (bmin.y - v0.y) / (v1.y - v0.y); + float vx = (1 - a) * v0.x + a * v1.x; //v.y = bmin.y; - float vz = (1-a) *v0.z + a*v1.z; - if(vx>=bmin.x && vx<=bmax.x && vz>=bmin.z && vz<=bmax.z) - { + float vz = (1 - a) * v0.z + a * v1.z; + if (vx >= bmin.x && vx <= bmax.x && vz >= bmin.z && vz <= bmax.z) + { impact->x = vx; impact->y = bmin.y; impact->z = vz; return 1; } } - else if(v0.y >= bmax.y && v1.y <= bmax.y) - { - float a = (bmax.y-v0.y)/(v1.y-v0.y); - float vx = (1-a) *v0.x + a*v1.x; + else if (v0.y >= bmax.y && v1.y <= bmax.y) + { + float a = (bmax.y - v0.y) / (v1.y - v0.y); + float vx = (1 - a) * v0.x + a * v1.x; // vy = bmax.y; - float vz = (1-a) *v0.z + a*v1.z; - if(vx>=bmin.x && vx<=bmax.x && vz>=bmin.z && vz<=bmax.z) - { + float vz = (1 - a) * v0.z + a * v1.z; + if (vx >= bmin.x && vx <= bmax.x && vz >= bmin.z && vz <= bmax.z) + { impact->x = vx; impact->y = bmax.y; impact->z = vz; return 1; } } - if(v0.z<=bmin.z && v1.z>=bmin.z) - { - float a = (bmin.z-v0.z)/(v1.z-v0.z); - float vx = (1-a) *v0.x + a*v1.x; - float vy = (1-a) *v0.y + a*v1.y; + if (v0.z <= bmin.z && v1.z >= bmin.z) + { + float a = (bmin.z - v0.z) / (v1.z - v0.z); + float vx = (1 - a) * v0.x + a * v1.x; + float vy = (1 - a) * v0.y + a * v1.y; // v.z = bmin.z; - if(vy>=bmin.y && vy<=bmax.y && vx>=bmin.x && vx<=bmax.x) - { + if (vy >= bmin.y && vy <= bmax.y && vx >= bmin.x && vx <= bmax.x) + { impact->x = vx; impact->y = vy; impact->z = bmin.z; return 1; } } - else if(v0.z >= bmax.z && v1.z <= bmax.z) - { - float a = (bmax.z-v0.z)/(v1.z-v0.z); - float vx = (1-a) *v0.x + a*v1.x; - float vy = (1-a) *v0.y + a*v1.y; + else if (v0.z >= bmax.z && v1.z <= bmax.z) + { + float a = (bmax.z - v0.z) / (v1.z - v0.z); + float vx = (1 - a) * v0.x + a * v1.x; + float vy = (1 - a) * v0.y + a * v1.y; // v.z = bmax.z; - if(vy>=bmin.y && vy<=bmax.y && vx>=bmin.x && vx<=bmax.x) - { + if (vy >= bmin.y && vy <= bmax.y && vx >= bmin.x && vx <= bmax.x) + { impact->x = vx; impact->y = vy; impact->z = bmax.z; @@ -712,325 +679,321 @@ int BoxIntersect(const float3 &v0, const float3 &v1, const float3 &bmin, const f return 0; } - float DistanceBetweenLines(const float3 &ustart, const float3 &udir, const float3 &vstart, const float3 &vdir, float3 *upoint, float3 *vpoint) { static float3 cp; - cp = normalize(cross(udir,vdir)); + cp = normalize(cross(udir, vdir)); - float distu = -dot(cp,ustart); - float distv = -dot(cp,vstart); - float dist = (float)fabs(distu-distv); - if(upoint) - { - float3 normal = normalize(cross(vdir,cp)); - *upoint = PlaneLineIntersection(normal,-dot(normal,vstart),ustart,ustart+udir); + float distu = -dot(cp, ustart); + float distv = -dot(cp, vstart); + float dist = (float)fabs(distu - distv); + if (upoint) + { + float3 normal = normalize(cross(vdir, cp)); + *upoint = PlaneLineIntersection(normal, -dot(normal, vstart), ustart, ustart + udir); } - if(vpoint) - { - float3 normal = normalize(cross(udir,cp)); - *vpoint = PlaneLineIntersection(normal,-dot(normal,ustart),vstart,vstart+vdir); + if (vpoint) + { + float3 normal = normalize(cross(udir, cp)); + *vpoint = PlaneLineIntersection(normal, -dot(normal, ustart), vstart, vstart + vdir); } return dist; } - -Quaternion VirtualTrackBall(const float3 &cop, const float3 &cor, const float3 &dir1, const float3 &dir2) +Quaternion VirtualTrackBall(const float3 &cop, const float3 &cor, const float3 &dir1, const float3 &dir2) { // routine taken from game programming gems. // Implement track ball functionality to spin stuf on the screen // cop center of projection // cor center of rotation - // dir1 old mouse direction + // dir1 old mouse direction // dir2 new mouse direction // pretend there is a sphere around cor. Then find the points // where dir1 and dir2 intersect that sphere. Find the // rotation that takes the first point to the second. float m; - // compute plane + // compute plane float3 nrml = cor - cop; - float fudgefactor = 1.0f/(magnitude(nrml) * 0.25f); // since trackball proportional to distance from cop + float fudgefactor = 1.0f / (magnitude(nrml) * 0.25f); // since trackball proportional to distance from cop nrml = normalize(nrml); - float dist = -dot(nrml,cor); - float3 u= PlaneLineIntersection(nrml,dist,cop,cop+dir1); - u=u-cor; - u=u*fudgefactor; - m= magnitude(u); - if(m>1) - { - u/=m; - } - else - { - u=u - (nrml * sqrtf(1-m*m)); + float dist = -dot(nrml, cor); + float3 u = PlaneLineIntersection(nrml, dist, cop, cop + dir1); + u = u - cor; + u = u * fudgefactor; + m = magnitude(u); + if (m > 1) + { + u /= m; } - float3 v= PlaneLineIntersection(nrml,dist,cop,cop+dir2); - v=v-cor; - v=v*fudgefactor; - m= magnitude(v); - if(m>1) - { - v/=m; - } - else - { - v=v - (nrml * sqrtf(1-m*m)); + else + { + u = u - (nrml * sqrtf(1 - m * m)); } - return RotationArc(u,v); + float3 v = PlaneLineIntersection(nrml, dist, cop, cop + dir2); + v = v - cor; + v = v * fudgefactor; + m = magnitude(v); + if (m > 1) + { + v /= m; + } + else + { + v = v - (nrml * sqrtf(1 - m * m)); + } + return RotationArc(u, v); } - -int countpolyhit=0; +int countpolyhit = 0; int HitCheckPoly(const float3 *vert, const int n, const float3 &v0, const float3 &v1, float3 *impact, float3 *normal) { countpolyhit++; int i; - float3 nrml(0,0,0); - for(i=0;i0) - { - return 0; - } + if (m == 0.0) + { + return 0; + } + nrml = nrml * (1.0f / m); + float dist = -dot(nrml, vert[0]); + float d0, d1; + if ((d0 = dot(v0, nrml) + dist) < 0 || (d1 = dot(v1, nrml) + dist) > 0) + { + return 0; + } - static float3 the_point; + static float3 the_point; // By using the cached plane distances d0 and d1 // we can optimize the following: // the_point = planelineintersection(nrml,dist,v0,v1); - float a = d0/(d0-d1); - the_point = v0*(1-a) + v1*a; + float a = d0 / (d0 - d1); + the_point = v0 * (1 - a) + v1 * a; - - int inside=1; - for(int j=0;inside && j= 0.0); + int inside = 1; + for (int j = 0; inside && j < n; j++) + { + // let inside = 0 if outside + float3 pp1, pp2, side; + pp1 = vert[j]; + pp2 = vert[(j + 1) % n]; + side = cross((pp2 - pp1), (the_point - pp1)); + inside = (dot(nrml, side) >= 0.0); } - if(inside) - { - if(normal){*normal=nrml;} - if(impact){*impact=the_point;} + if (inside) + { + if (normal) + { + *normal = nrml; + } + if (impact) + { + *impact = the_point; + } } return inside; } -int SolveQuadratic(float a,float b,float c,float *ta,float *tb) // if true returns roots ta,tb where ta<=tb +int SolveQuadratic(float a, float b, float c, float *ta, float *tb) // if true returns roots ta,tb where ta<=tb { assert(ta); assert(tb); - float d = b*b-4.0f*a*c; // discriminant - if(d<0.0f) return 0; + float d = b * b - 4.0f * a * c; // discriminant + if (d < 0.0f) return 0; float sqd = sqrtf(d); - *ta = (-b-sqd) / (2.0f * a); - *tb = (-b+sqd) / (2.0f * a); + *ta = (-b - sqd) / (2.0f * a); + *tb = (-b + sqd) / (2.0f * a); return 1; } -int HitCheckRaySphere(const float3& sphereposition,float radius, const float3& _v0, const float3& _v1, float3 *impact,float3 *normal) +int HitCheckRaySphere(const float3 &sphereposition, float radius, const float3 &_v0, const float3 &_v1, float3 *impact, float3 *normal) { assert(impact); assert(normal); - float3 dv = _v1-_v0; - float3 v0 = _v0 - sphereposition; // solve in coord system of the sphere - if(radius<=0.0f || _v0==_v1) return 0; // only true if point moves from outside to inside sphere. - float a = dot(dv,dv); - float b = 2.0f * dot(dv,v0); - float c = dot(v0,v0) - radius*radius; - if(c<0.0f) return 0; // we are already inside the sphere. + float3 dv = _v1 - _v0; + float3 v0 = _v0 - sphereposition; // solve in coord system of the sphere + if (radius <= 0.0f || _v0 == _v1) return 0; // only true if point moves from outside to inside sphere. + float a = dot(dv, dv); + float b = 2.0f * dot(dv, v0); + float c = dot(v0, v0) - radius * radius; + if (c < 0.0f) return 0; // we are already inside the sphere. float ta, tb; int doesIntersect = SolveQuadratic(a, b, c, &ta, &tb); if (!doesIntersect) return 0; - if (ta >= 0.0f && ta <= 1.0f && (ta <= tb || tb<=0.0f)) + if (ta >= 0.0f && ta <= 1.0f && (ta <= tb || tb <= 0.0f)) { *impact = _v0 + dv * ta; - *normal = (v0 + dv*ta)/radius; + *normal = (v0 + dv * ta) / radius; return 1; } if (tb >= 0.0f && tb <= 1.0f) { - assert(tb <= ta || ta <=0.0f); // tb must be better than ta + assert(tb <= ta || ta <= 0.0f); // tb must be better than ta *impact = _v0 + dv * tb; - *normal = (v0 + dv*tb)/radius; + *normal = (v0 + dv * tb) / radius; return 1; } return 0; } -int HitCheckRayCylinder(const float3 &p0,const float3 &p1,float radius,const float3& _v0,const float3& _v1, float3 *impact,float3 *normal) +int HitCheckRayCylinder(const float3 &p0, const float3 &p1, float radius, const float3 &_v0, const float3 &_v1, float3 *impact, float3 *normal) { assert(impact); assert(normal); // only concerned about hitting the sides, not the caps for now - float3x3 m=RotationArc(p1-p0,float3(0,0,1.0f)).getmatrix(); - float h = ((p1-p0)*m ).z; - float3 v0 = (_v0-p0) *m; - float3 v1 = (_v1-p0) *m; - if(v0.z <= 0.0f && v1.z <= 0.0f) return 0; // entirely below cylinder - if(v0.z >= h && v1.z >= h ) return 0; // ray is above cylinder - if(v0.z <0.0f ) v0 = PlaneLineIntersection(float3(0,0,1.0f), 0,v0,v1); // crop to cylinder range - if(v1.z <0.0f ) v1 = PlaneLineIntersection(float3(0,0,1.0f), 0,v0,v1); - if(v0.z > h ) v0 = PlaneLineIntersection(float3(0,0,1.0f),-h,v0,v1); - if(v1.z > h ) v1 = PlaneLineIntersection(float3(0,0,1.0f),-h,v0,v1); - if(v0.x==v1.x && v0.y==v1.y) return 0; - float3 dv = v1-v0; - - float a = dv.x*dv.x+dv.y*dv.y; - float b = 2.0f * (dv.x*v0.x+dv.y*v0.y); - float c = (v0.x*v0.x+v0.y*v0.y) - radius*radius; - if(c<0.0f) return 0; // we are already inside the cylinder . + float3x3 m = RotationArc(p1 - p0, float3(0, 0, 1.0f)).getmatrix(); + float h = ((p1 - p0) * m).z; + float3 v0 = (_v0 - p0) * m; + float3 v1 = (_v1 - p0) * m; + if (v0.z <= 0.0f && v1.z <= 0.0f) return 0; // entirely below cylinder + if (v0.z >= h && v1.z >= h) return 0; // ray is above cylinder + if (v0.z < 0.0f) v0 = PlaneLineIntersection(float3(0, 0, 1.0f), 0, v0, v1); // crop to cylinder range + if (v1.z < 0.0f) v1 = PlaneLineIntersection(float3(0, 0, 1.0f), 0, v0, v1); + if (v0.z > h) v0 = PlaneLineIntersection(float3(0, 0, 1.0f), -h, v0, v1); + if (v1.z > h) v1 = PlaneLineIntersection(float3(0, 0, 1.0f), -h, v0, v1); + if (v0.x == v1.x && v0.y == v1.y) return 0; + float3 dv = v1 - v0; + + float a = dv.x * dv.x + dv.y * dv.y; + float b = 2.0f * (dv.x * v0.x + dv.y * v0.y); + float c = (v0.x * v0.x + v0.y * v0.y) - radius * radius; + if (c < 0.0f) return 0; // we are already inside the cylinder . float ta, tb; int doesIntersect = SolveQuadratic(a, b, c, &ta, &tb); if (!doesIntersect) return 0; - if (ta >= 0.0f && ta <= 1.0f && (ta <= tb || tb<=0.0f)) + if (ta >= 0.0f && ta <= 1.0f && (ta <= tb || tb <= 0.0f)) { - *impact = (v0 + dv * ta)*Transpose(m) + p0; - *normal = (float3(v0.x,v0.y,0.0f) + float3(dv.x,dv.y,0) * ta) /radius * Transpose(m); + *impact = (v0 + dv * ta) * Transpose(m) + p0; + *normal = (float3(v0.x, v0.y, 0.0f) + float3(dv.x, dv.y, 0) * ta) / radius * Transpose(m); return 1; } if (tb >= 0.0f && tb <= 1.0f) { - assert(tb <= ta || ta <=0.0f); // tb must be better than ta - *impact = (v0 + dv * tb)*Transpose(m) + p0; // compute intersection in original space - *normal = (float3(v0.x,v0.y,0.0f) + float3(dv.x,dv.y,0) * tb) /radius * Transpose(m); + assert(tb <= ta || ta <= 0.0f); // tb must be better than ta + *impact = (v0 + dv * tb) * Transpose(m) + p0; // compute intersection in original space + *normal = (float3(v0.x, v0.y, 0.0f) + float3(dv.x, dv.y, 0) * tb) / radius * Transpose(m); return 1; } return 0; } -int HitCheckSweptSphereTri(const float3 &p0,const float3 &p1,const float3 &p2,float radius, const float3& v0,const float3& _v1, float3 *impact,float3 *normal) +int HitCheckSweptSphereTri(const float3 &p0, const float3 &p1, const float3 &p2, float radius, const float3 &v0, const float3 &_v1, float3 *impact, float3 *normal) { float3 unused; - if(!normal) normal=&unused; - float3 v1=_v1; // so we can update v1 after each sub intersection test if necessary - int hit=0; - float3 cp = cross(p1-p0,p2-p0); - if(dot(cp,v1-v0)>=0.0f) return 0; // coming from behind and/or moving away + if (!normal) normal = &unused; + float3 v1 = _v1; // so we can update v1 after each sub intersection test if necessary + int hit = 0; + float3 cp = cross(p1 - p0, p2 - p0); + if (dot(cp, v1 - v0) >= 0.0f) return 0; // coming from behind and/or moving away float3 n = normalize(cp); float3 tv[3]; - tv[0] = p0 + n*radius; - tv[1] = p1 + n*radius; - tv[2] = p2 + n*radius; - hit += HitCheckPoly(tv,3,v0,v1,&v1,normal); - hit += HitCheckRayCylinder(p0,p1,radius,v0,v1,&v1,normal); - hit += HitCheckRayCylinder(p1,p2,radius,v0,v1,&v1,normal); - hit += HitCheckRayCylinder(p2,p0,radius,v0,v1,&v1,normal); - hit += HitCheckRaySphere(p0,radius,v0,v1,&v1,normal); - hit += HitCheckRaySphere(p1,radius,v0,v1,&v1,normal); - hit += HitCheckRaySphere(p2,radius,v0,v1,&v1,normal); - if(hit && impact) *impact = v1 + *normal * 0.001f; + tv[0] = p0 + n * radius; + tv[1] = p1 + n * radius; + tv[2] = p2 + n * radius; + hit += HitCheckPoly(tv, 3, v0, v1, &v1, normal); + hit += HitCheckRayCylinder(p0, p1, radius, v0, v1, &v1, normal); + hit += HitCheckRayCylinder(p1, p2, radius, v0, v1, &v1, normal); + hit += HitCheckRayCylinder(p2, p0, radius, v0, v1, &v1, normal); + hit += HitCheckRaySphere(p0, radius, v0, v1, &v1, normal); + hit += HitCheckRaySphere(p1, radius, v0, v1, &v1, normal); + hit += HitCheckRaySphere(p2, radius, v0, v1, &v1, normal); + if (hit && impact) *impact = v1 + *normal * 0.001f; return hit; } - -float3 PlanesIntersection(const Plane &p0,const Plane &p1, const Plane &p2) +float3 PlanesIntersection(const Plane &p0, const Plane &p1, const Plane &p2) { - float3x3 mp =Transpose(float3x3(p0.normal(),p1.normal(),p2.normal())); + float3x3 mp = Transpose(float3x3(p0.normal(), p1.normal(), p2.normal())); float3x3 mi = Inverse(mp); - float3 b(p0.dist(),p1.dist(),p2.dist()); - return -b * mi; + float3 b(p0.dist(), p1.dist(), p2.dist()); + return -b * mi; } - -float3 PlanesIntersection(const Plane *planes,int planes_count,const float3 &seed) +float3 PlanesIntersection(const Plane *planes, int planes_count, const float3 &seed) { int i; - float3x3 A; // gets initilized to 0 matrix - float3 b(0,0,0); - for(i=0;i= count+1 assert(verts_out); - int n=0; - int prev_status = (dot(plane_normal,verts_in[count_in-1])+plane_dist > 0) ; - for(int i=0;i 0); + for (int i = 0; i < count_in; i++) { - int status = (dot(plane_normal,verts_in[i])+plane_dist > 0) ; - if(status != prev_status) + int status = (dot(plane_normal, verts_in[i]) + plane_dist > 0); + if (status != prev_status) { - verts_out[n++] = PlaneLineIntersection(plane_normal,plane_dist,verts_in[(i==0)?count_in-1:i-1],verts_in[i]); + verts_out[n++] = PlaneLineIntersection(plane_normal, plane_dist, verts_in[(i == 0) ? count_in - 1 : i - 1], verts_in[i]); } - if(status==0) // under + if (status == 0) // under { verts_out[n++] = verts_in[i]; } } - assert(n<=count_in+1); // remove if intention to use this routine on convex polygons + assert(n <= count_in + 1); // remove if intention to use this routine on convex polygons return n; } -int ClipPolyPoly(const float3 &normal,const float3 *clipper,int clipper_count,const float3 *verts_in, int in_count,float3 *scratch) +int ClipPolyPoly(const float3 &normal, const float3 *clipper, int clipper_count, const float3 *verts_in, int in_count, float3 *scratch) { // clips polys against each other. // requires sufficiently allocated temporary memory in scratch buffer @@ -1041,86 +1004,87 @@ int ClipPolyPoly(const float3 &normal,const float3 *clipper,int clipper_count,co // its generally assumed both are convex polygons. assert(scratch); // size should be >= 2*(clipper_count+in_count) int i; - int bsize = clipper_count+in_count; + int bsize = clipper_count + in_count; int count = in_count; - for(i=0;iom.y&&om.x>om.z)?0: (om.y>om.z)? 1 : 2; // index of largest element of offdiag - int k1 = (k+1)%3; - int k2 = (k+2)%3; - if(offdiag[k]==0.0f) break; // diagonal already - float thet = (D[k2][k2]-D[k1][k1])/(2.0f*offdiag[k]); - float sgn = (thet>0.0f)?1.0f:-1.0f; - thet *= sgn; // make it positive - float t = sgn /(thet +((thet<1.E6f)?sqrtf(squared(thet)+1.0f):thet)) ; // sign(T)/(|T|+sqrt(T^2+1)) - float c = 1.0f/sqrtf(squared(t)+1.0f); // c= 1/(t^2+1) , t=s/c - if(c==1.0f) break; // no room for improvement - reached machine precision. - Quaternion jr(0,0,0,0); // jacobi rotation for this iteration. - jr[k] = sgn*sqrtf((1.0f-c)/2.0f); // using 1/2 angle identity sin(a/2) = sqrt((1-cos(a))/2) - jr[k] *= -1.0f; // since our quat-to-matrix convention was for v*M instead of M*v - jr.w = sqrtf(1.0f - squared(jr[k])); - if(jr.w==1.0f) break; // reached limits of floating point precision - q = q*jr; + float3x3 Q = q.getmatrix(); // v*Q == q*v*conj(q) + float3x3 D = Q * A * Transpose(Q); // A = Q^T*D*Q + float3 offdiag(D[1][2], D[0][2], D[0][1]); // elements not on the diagonal + float3 om(fabsf(offdiag.x), fabsf(offdiag.y), fabsf(offdiag.z)); // mag of each offdiag elem + int k = (om.x > om.y && om.x > om.z) ? 0 : (om.y > om.z) ? 1 : 2; // index of largest element of offdiag + int k1 = (k + 1) % 3; + int k2 = (k + 2) % 3; + if (offdiag[k] == 0.0f) break; // diagonal already + float thet = (D[k2][k2] - D[k1][k1]) / (2.0f * offdiag[k]); + float sgn = (thet > 0.0f) ? 1.0f : -1.0f; + thet *= sgn; // make it positive + float t = sgn / (thet + ((thet < 1.E6f) ? sqrtf(squared(thet) + 1.0f) : thet)); // sign(T)/(|T|+sqrt(T^2+1)) + float c = 1.0f / sqrtf(squared(t) + 1.0f); // c= 1/(t^2+1) , t=s/c + if (c == 1.0f) break; // no room for improvement - reached machine precision. + Quaternion jr(0, 0, 0, 0); // jacobi rotation for this iteration. + jr[k] = sgn * sqrtf((1.0f - c) / 2.0f); // using 1/2 angle identity sin(a/2) = sqrt((1-cos(a))/2) + jr[k] *= -1.0f; // since our quat-to-matrix convention was for v*M instead of M*v + jr.w = sqrtf(1.0f - squared(jr[k])); + if (jr.w == 1.0f) break; // reached limits of floating point precision + q = q * jr; q.Normalize(); - } + } return q; } float3 Diagonal(const float3x3 &M) { - return float3(M[0][0],M[1][1],M[2][2]); + return float3(M[0][0], M[1][1], M[2][2]); } diff --git a/examples/Experiments/ImplicitCloth/stan/vecmath.h b/examples/Experiments/ImplicitCloth/stan/vecmath.h index a83ed8cfb..c219eb131 100644 --- a/examples/Experiments/ImplicitCloth/stan/vecmath.h +++ b/examples/Experiments/ImplicitCloth/stan/vecmath.h @@ -1,8 +1,8 @@ -// +// // // Typical 3d vector math code. // By S Melax 1998-2008 -// +// // #ifndef SM_VEC_MATH_H @@ -15,265 +15,493 @@ #define M_PIf (3.1415926535897932384626433832795f) -inline float DegToRad(float angle_degrees) { return angle_degrees * M_PIf / 180.0f; } // returns Radians. -inline float RadToDeg(float angle_radians) { return angle_radians * 180.0f / M_PIf; } // returns Degrees. +inline float DegToRad(float angle_degrees) { return angle_degrees * M_PIf / 180.0f; } // returns Radians. +inline float RadToDeg(float angle_radians) { return angle_radians * 180.0f / M_PIf; } // returns Degrees. -#define OFFSET(Class,Member) (((char*) (&(((Class*)NULL)-> Member )))- ((char*)NULL)) +#define OFFSET(Class, Member) (((char *)(&(((Class *)NULL)->Member))) - ((char *)NULL)) - - - -int argmin(const float a[],int n); -int argmax(const float a[],int n); -float squared(float a); -float clamp(float a,const float minval=0.0f, const float maxval=1.0f); -int clamp(int a,const int minval,const int maxval) ; -float Round(float a,float precision); -float Interpolate(const float &f0,const float &f1,float alpha) ; +int argmin(const float a[], int n); +int argmax(const float a[], int n); +float squared(float a); +float clamp(float a, const float minval = 0.0f, const float maxval = 1.0f); +int clamp(int a, const int minval, const int maxval); +float Round(float a, float precision); +float Interpolate(const float &f0, const float &f1, float alpha); template -void Swap(T &a,T &b) +void Swap(T &a, T &b) { T tmp = a; - a=b; - b=tmp; -} - - - -template -T Max(const T &a,const T &b) -{ - return (a>b)?a:b; + a = b; + b = tmp; } template -T Min(const T &a,const T &b) +T Max(const T &a, const T &b) { - return (a b) ? a : b; +} + +template +T Min(const T &a, const T &b) +{ + return (a < b) ? a : b; } //for template normalize functions: -inline float squareroot(float a){return sqrtf(a);} -inline double squareroot(double a){return sqrt(a); } +inline float squareroot(float a) { return sqrtf(a); } +inline double squareroot(double a) { return sqrt(a); } //---------------------------------- - - //-------- 2D -------- - -template +template class vec2 { - public: - T x,y; - inline vec2(){x=0;y=0;} - inline vec2(const T &_x, const T &_y){x=_x;y=_y;} - inline T& operator[](int i) {return ((T*)this)[i];} - inline const T& operator[](int i) const {return ((T*)this)[i];} +public: + T x, y; + inline vec2() + { + x = 0; + y = 0; + } + inline vec2(const T &_x, const T &_y) + { + x = _x; + y = _y; + } + inline T &operator[](int i) { return ((T *)this)[i]; } + inline const T &operator[](int i) const { return ((T *)this)[i]; } }; -typedef vec2 int2; -typedef vec2 float2; +typedef vec2 int2; +typedef vec2 float2; - -template inline int operator ==(const vec2 &a,const vec2 &b) {return (a.x==b.x && a.y==b.y);} -template inline vec2 operator-( const vec2& a, const vec2& b ){return vec2(a.x-b.x,a.y-b.y);} -template inline vec2 operator+( const vec2& a, const vec2& b ){return float2(a.x+b.x,a.y+b.y);} +template +inline int operator==(const vec2 &a, const vec2 &b) +{ + return (a.x == b.x && a.y == b.y); +} +template +inline vec2 operator-(const vec2 &a, const vec2 &b) +{ + return vec2(a.x - b.x, a.y - b.y); +} +template +inline vec2 operator+(const vec2 &a, const vec2 &b) +{ + return float2(a.x + b.x, a.y + b.y); +} //--------- 3D --------- - - -template +template class vec3 { - public: - T x,y,z; - inline vec3(){x=0;y=0;z=0;}; - inline vec3(const T &_x,const T &_y,const T &_z){x=_x;y=_y;z=_z;}; - inline T& operator[](int i) {return ((T*)this)[i];} - inline const T& operator[](int i) const {return ((T*)this)[i];} +public: + T x, y, z; + inline vec3() + { + x = 0; + y = 0; + z = 0; + }; + inline vec3(const T &_x, const T &_y, const T &_z) + { + x = _x; + y = _y; + z = _z; + }; + inline T &operator[](int i) { return ((T *)this)[i]; } + inline const T &operator[](int i) const { return ((T *)this)[i]; } }; - -typedef vec3 int3; +typedef vec3 int3; typedef vec3 short3; typedef vec3 float3; -// due to ambiguity there is no overloaded operators for v3*v3 use dot,cross,outerprod,cmul -template inline int operator==(const vec3 &a,const vec3 &b) {return (a.x==b.x && a.y==b.y && a.z==b.z);} -template inline int operator!=(const vec3 &a,const vec3 &b) {return !(a==b);} -template inline vec3 operator+(const vec3& a, const vec3& b ){return vec3(a.x+b.x, a.y+b.y, a.z+b.z);} -template inline vec3 operator-(const vec3& a, const vec3& b ){return vec3(a.x-b.x, a.y-b.y, a.z-b.z);} -template inline vec3 operator-(const vec3& v){return vec3(-v.x,-v.y,-v.z );} -template inline vec3 operator*(const vec3& v, const T &s ){ return vec3( v.x*s, v.y*s, v.z*s );} -template inline vec3 operator*(T s, const vec3& v ){return v*s;} -template inline vec3 operator/(const vec3& v, T s ){return vec3( v.x/s, v.y/s, v.z/s );} -template inline T dot (const vec3& a, const vec3& b){return a.x*b.x + a.y*b.y + a.z*b.z;} -template inline vec3 cmul (const vec3& a, const vec3& b){return vec3(a.x*b.x, a.y*b.y, a.z*b.z);} -template inline vec3 cross(const vec3& a, const vec3& b){return vec3(a.y*b.z-a.z*b.y, a.z*b.x-a.x*b.z, a.x*b.y-a.y*b.x);} -template inline T magnitude( const vec3& v ){return squareroot(dot(v,v));} -template inline vec3 normalize( const vec3& v ){return v/magnitude(v);} -template inline vec3& operator+=(vec3& a, const vec3& b){a.x+=b.x;a.y+=b.y;a.z+=b.z;return a;} -template inline vec3& operator-=(vec3& a, const vec3& b){a.x-=b.x;a.y-=b.y;a.z-=b.z;return a;} -template inline vec3& operator*=(vec3& v, T s){v.x*=s;v.y*=s;v.z*= s;return v;} -template inline vec3& operator/=(vec3& v, T s){v.x/=s;v.y/=s;v.z/=s;return v;} - +// due to ambiguity there is no overloaded operators for v3*v3 use dot,cross,outerprod,cmul +template +inline int operator==(const vec3 &a, const vec3 &b) +{ + return (a.x == b.x && a.y == b.y && a.z == b.z); +} +template +inline int operator!=(const vec3 &a, const vec3 &b) +{ + return !(a == b); +} +template +inline vec3 operator+(const vec3 &a, const vec3 &b) +{ + return vec3(a.x + b.x, a.y + b.y, a.z + b.z); +} +template +inline vec3 operator-(const vec3 &a, const vec3 &b) +{ + return vec3(a.x - b.x, a.y - b.y, a.z - b.z); +} +template +inline vec3 operator-(const vec3 &v) +{ + return vec3(-v.x, -v.y, -v.z); +} +template +inline vec3 operator*(const vec3 &v, const T &s) +{ + return vec3(v.x * s, v.y * s, v.z * s); +} +template +inline vec3 operator*(T s, const vec3 &v) +{ + return v * s; +} +template +inline vec3 operator/(const vec3 &v, T s) +{ + return vec3(v.x / s, v.y / s, v.z / s); +} +template +inline T dot(const vec3 &a, const vec3 &b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z; +} +template +inline vec3 cmul(const vec3 &a, const vec3 &b) +{ + return vec3(a.x * b.x, a.y * b.y, a.z * b.z); +} +template +inline vec3 cross(const vec3 &a, const vec3 &b) +{ + return vec3(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); +} +template +inline T magnitude(const vec3 &v) +{ + return squareroot(dot(v, v)); +} +template +inline vec3 normalize(const vec3 &v) +{ + return v / magnitude(v); +} +template +inline vec3 &operator+=(vec3 &a, const vec3 &b) +{ + a.x += b.x; + a.y += b.y; + a.z += b.z; + return a; +} +template +inline vec3 &operator-=(vec3 &a, const vec3 &b) +{ + a.x -= b.x; + a.y -= b.y; + a.z -= b.z; + return a; +} +template +inline vec3 &operator*=(vec3 &v, T s) +{ + v.x *= s; + v.y *= s; + v.z *= s; + return v; +} +template +inline vec3 &operator/=(vec3 &v, T s) +{ + v.x /= s; + v.y /= s; + v.z /= s; + return v; +} float3 safenormalize(const float3 &v); float3 vabs(const float3 &v); -float3 Interpolate(const float3 &v0,const float3 &v1,float alpha); -float3 Round(const float3& a,float precision); -template inline vec3VectorMin(const vec3 &a,const vec3 &b) {return vec3(Min(a.x,b.x),Min(a.y,b.y),Min(a.z,b.z));} -template inline vec3VectorMax(const vec3 &a,const vec3 &b) {return vec3(Max(a.x,b.x),Max(a.y,b.y),Max(a.z,b.z));} -int overlap(const float3 &bmina,const float3 &bmaxa,const float3 &bminb,const float3 &bmaxb); +float3 Interpolate(const float3 &v0, const float3 &v1, float alpha); +float3 Round(const float3 &a, float precision); +template +inline vec3 VectorMin(const vec3 &a, const vec3 &b) +{ + return vec3(Min(a.x, b.x), Min(a.y, b.y), Min(a.z, b.z)); +} +template +inline vec3 VectorMax(const vec3 &a, const vec3 &b) +{ + return vec3(Max(a.x, b.x), Max(a.y, b.y), Max(a.z, b.z)); +} +int overlap(const float3 &bmina, const float3 &bmaxa, const float3 &bminb, const float3 &bmaxb); template class mat3x3 { - public: - vec3 x,y,z; // the 3 rows of the Matrix - inline mat3x3(){} - inline mat3x3(const T &xx,const T &xy,const T &xz,const T &yx,const T &yy,const T &yz,const T &zx,const T &zy,const T &zz):x(xx,xy,xz),y(yx,yy,yz),z(zx,zy,zz){} - inline mat3x3(const vec3 &_x,const vec3 &_y,const vec3 &_z):x(_x),y(_y),z(_z){} - inline vec3& operator[](int i) {return (&x)[i];} - inline const vec3& operator[](int i) const {return (&x)[i];} - inline T& operator()(int r, int c) {return ((&x)[r])[c];} - inline const T& operator()(int r, int c) const {return ((&x)[r])[c];} -}; +public: + vec3 x, y, z; // the 3 rows of the Matrix + inline mat3x3() {} + inline mat3x3(const T &xx, const T &xy, const T &xz, const T &yx, const T &yy, const T &yz, const T &zx, const T &zy, const T &zz) : x(xx, xy, xz), y(yx, yy, yz), z(zx, zy, zz) {} + inline mat3x3(const vec3 &_x, const vec3 &_y, const vec3 &_z) : x(_x), y(_y), z(_z) {} + inline vec3 &operator[](int i) { return (&x)[i]; } + inline const vec3 &operator[](int i) const { return (&x)[i]; } + inline T &operator()(int r, int c) { return ((&x)[r])[c]; } + inline const T &operator()(int r, int c) const { return ((&x)[r])[c]; } +}; typedef mat3x3 float3x3; -float3x3 Transpose( const float3x3& m ); -template vec3 operator*( const vec3& v , const mat3x3& m ) +float3x3 Transpose(const float3x3 &m); +template +vec3 operator*(const vec3 &v, const mat3x3 &m) { - return vec3((m.x.x*v.x + m.y.x*v.y + m.z.x*v.z), - (m.x.y*v.x + m.y.y*v.y + m.z.y*v.z), - (m.x.z*v.x + m.y.z*v.y + m.z.z*v.z)); + return vec3((m.x.x * v.x + m.y.x * v.y + m.z.x * v.z), + (m.x.y * v.x + m.y.y * v.y + m.z.y * v.z), + (m.x.z * v.x + m.y.z * v.y + m.z.z * v.z)); } -float3 operator*( const float3x3& m , const float3& v ); -float3x3 operator*( const float3x3& m , const float& s ); -float3x3 operator*( const float3x3& ma, const float3x3& mb ); -float3x3 operator/( const float3x3& a, const float& s ) ; -float3x3 operator+( const float3x3& a, const float3x3& b ); -float3x3 operator-( const float3x3& a, const float3x3& b ); -float3x3 &operator+=( float3x3& a, const float3x3& b ); -float3x3 &operator-=( float3x3& a, const float3x3& b ); -float3x3 &operator*=( float3x3& a, const float& s ); -float Determinant(const float3x3& m ); -float3x3 Inverse(const float3x3& a); // its just 3x3 so we simply do that cofactor method -float3x3 outerprod(const float3& a,const float3& b); +float3 operator*(const float3x3 &m, const float3 &v); +float3x3 operator*(const float3x3 &m, const float &s); +float3x3 operator*(const float3x3 &ma, const float3x3 &mb); +float3x3 operator/(const float3x3 &a, const float &s); +float3x3 operator+(const float3x3 &a, const float3x3 &b); +float3x3 operator-(const float3x3 &a, const float3x3 &b); +float3x3 &operator+=(float3x3 &a, const float3x3 &b); +float3x3 &operator-=(float3x3 &a, const float3x3 &b); +float3x3 &operator*=(float3x3 &a, const float &s); +float Determinant(const float3x3 &m); +float3x3 Inverse(const float3x3 &a); // its just 3x3 so we simply do that cofactor method +float3x3 outerprod(const float3 &a, const float3 &b); //-------- 4D Math -------- -template +template class vec4 { public: - T x,y,z,w; - inline vec4(){x=0;y=0;z=0;w=0;}; - inline vec4(const T &_x, const T &_y, const T &_z, const T &_w){x=_x;y=_y;z=_z;w=_w;} - inline vec4(const vec3 &v,const T &_w){x=v.x;y=v.y;z=v.z;w=_w;} + T x, y, z, w; + inline vec4() + { + x = 0; + y = 0; + z = 0; + w = 0; + }; + inline vec4(const T &_x, const T &_y, const T &_z, const T &_w) + { + x = _x; + y = _y; + z = _z; + w = _w; + } + inline vec4(const vec3 &v, const T &_w) + { + x = v.x; + y = v.y; + z = v.z; + w = _w; + } //operator float *() { return &x;}; - T& operator[](int i) {return ((T*)this)[i];} - const T& operator[](int i) const {return ((T*)this)[i];} - inline const vec3& xyz() const { return *((vec3*)this);} - inline vec3& xyz() { return *((vec3*)this);} + T &operator[](int i) { return ((T *)this)[i]; } + const T &operator[](int i) const { return ((T *)this)[i]; } + inline const vec3 &xyz() const { return *((vec3 *)this); } + inline vec3 &xyz() { return *((vec3 *)this); } }; - typedef vec4 float4; -typedef vec4 int4; -typedef vec4 byte4; +typedef vec4 int4; +typedef vec4 byte4; +template +inline int operator==(const vec4 &a, const vec4 &b) +{ + return (a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w); +} +template +inline int operator!=(const vec4 &a, const vec4 &b) +{ + return !(a == b); +} +template +inline vec4 operator+(const vec4 &a, const vec4 &b) +{ + return vec4(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); +} +template +inline vec4 operator-(const vec4 &a, const vec4 &b) +{ + return vec4(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); +} +template +inline vec4 operator-(const vec4 &v) +{ + return vec4(-v.x, -v.y, -v.z, -v.w); +} +template +inline vec4 operator*(const vec4 &v, const T &s) +{ + return vec4(v.x * s, v.y * s, v.z * s, v.w * s); +} +template +inline vec4 operator*(T s, const vec4 &v) +{ + return v * s; +} +template +inline vec4 operator/(const vec4 &v, T s) +{ + return vec4(v.x / s, v.y / s, v.z / s, v.w / s); +} +template +inline T dot(const vec4 &a, const vec4 &b) +{ + return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; +} +template +inline vec4 cmul(const vec4 &a, const vec4 &b) +{ + return vec4(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); +} +template +inline vec4 &operator+=(vec4 &a, const vec4 &b) +{ + a.x += b.x; + a.y += b.y; + a.z += b.z; + a.w += b.w; + return a; +} +template +inline vec4 &operator-=(vec4 &a, const vec4 &b) +{ + a.x -= b.x; + a.y -= b.y; + a.z -= b.z; + a.w -= b.w; + return a; +} +template +inline vec4 &operator*=(vec4 &v, T s) +{ + v.x *= s; + v.y *= s; + v.z *= s; + v.w *= s; + return v; +} +template +inline vec4 &operator/=(vec4 &v, T s) +{ + v.x /= s; + v.y /= s; + v.z /= s; + v.w /= s; + return v; +} +template +inline T magnitude(const vec4 &v) +{ + return squareroot(dot(v, v)); +} +template +inline vec4 normalize(const vec4 &v) +{ + return v / magnitude(v); +} -template inline int operator==(const vec4 &a,const vec4 &b) {return (a.x==b.x && a.y==b.y && a.z==b.z && a.w==b.w);} -template inline int operator!=(const vec4 &a,const vec4 &b) {return !(a==b);} -template inline vec4 operator+(const vec4& a, const vec4& b ){return vec4(a.x+b.x,a.y+b.y,a.z+b.z,a.w+b.w);} -template inline vec4 operator-(const vec4& a, const vec4& b ){return vec4(a.x-b.x,a.y-b.y,a.z-b.z,a.w-b.w);} -template inline vec4 operator-(const vec4& v){return vec4(-v.x,-v.y,-v.z,-v.w);} -template inline vec4 operator*(const vec4& v, const T &s ){ return vec4( v.x*s, v.y*s, v.z*s,v.w*s);} -template inline vec4 operator*(T s, const vec4& v ){return v*s;} -template inline vec4 operator/(const vec4& v, T s ){return vec4( v.x/s, v.y/s, v.z/s,v.w/s );} -template inline T dot(const vec4& a, const vec4& b ){return a.x*b.x + a.y*b.y + a.z*b.z+a.w*b.w;} -template inline vec4 cmul(const vec4 &a, const vec4 &b) {return vec4(a.x*b.x, a.y*b.y, a.z*b.z,a.w*b.w);} -template inline vec4& operator+=(vec4& a, const vec4& b ){a.x+=b.x;a.y+=b.y;a.z+=b.z;a.w+=b.w;return a;} -template inline vec4& operator-=(vec4& a, const vec4& b ){a.x-=b.x;a.y-=b.y;a.z-=b.z;a.w-=b.w;return a;} -template inline vec4& operator*=(vec4& v, T s){v.x*=s;v.y*=s;v.z*=s;v.w*=s;return v;} -template inline vec4& operator/=(vec4& v, T s){v.x/=s;v.y/=s;v.z/=s;v.w/=s;return v;} -template inline T magnitude( const vec4& v ){return squareroot(dot(v,v));} -template inline vec4 normalize( const vec4& v ){return v/magnitude(v);} +struct D3DXMATRIX; - - -struct D3DXMATRIX; - -template +template class mat4x4 { - public: - vec4 x,y,z,w; // the 4 rows - inline mat4x4(){} - inline mat4x4(const vec4 &_x, const vec4 &_y, const vec4 &_z, const vec4 &_w):x(_x),y(_y),z(_z),w(_w){} - inline mat4x4(const T& m00, const T& m01, const T& m02, const T& m03, - const T& m10, const T& m11, const T& m12, const T& m13, - const T& m20, const T& m21, const T& m22, const T& m23, - const T& m30, const T& m31, const T& m32, const T& m33 ) - :x(m00,m01,m02,m03),y(m10,m11,m12,m13),z(m20,m21,m22,m23),w(m30,m31,m32,m33){} - inline vec4& operator[](int i) {assert(i>=0&&i<4);return (&x)[i];} - inline const vec4& operator[](int i) const {assert(i>=0&&i<4);return (&x)[i];} - inline T& operator()(int r, int c) {assert(r>=0&&r<4&&c>=0&&c<4);return ((&x)[r])[c];} - inline const T& operator()(int r, int c) const {assert(r>=0&&r<4&&c>=0&&c<4);return ((&x)[r])[c];} - inline operator T* () {return &x.x;} - inline operator const T* () const {return &x.x;} - operator struct D3DXMATRIX* () { return (struct D3DXMATRIX*) this;} - operator const struct D3DXMATRIX* () const { return (struct D3DXMATRIX*) this;} +public: + vec4 x, y, z, w; // the 4 rows + inline mat4x4() {} + inline mat4x4(const vec4 &_x, const vec4 &_y, const vec4 &_z, const vec4 &_w) : x(_x), y(_y), z(_z), w(_w) {} + inline mat4x4(const T &m00, const T &m01, const T &m02, const T &m03, + const T &m10, const T &m11, const T &m12, const T &m13, + const T &m20, const T &m21, const T &m22, const T &m23, + const T &m30, const T &m31, const T &m32, const T &m33) + : x(m00, m01, m02, m03), y(m10, m11, m12, m13), z(m20, m21, m22, m23), w(m30, m31, m32, m33) {} + inline vec4 &operator[](int i) + { + assert(i >= 0 && i < 4); + return (&x)[i]; + } + inline const vec4 &operator[](int i) const + { + assert(i >= 0 && i < 4); + return (&x)[i]; + } + inline T &operator()(int r, int c) + { + assert(r >= 0 && r < 4 && c >= 0 && c < 4); + return ((&x)[r])[c]; + } + inline const T &operator()(int r, int c) const + { + assert(r >= 0 && r < 4 && c >= 0 && c < 4); + return ((&x)[r])[c]; + } + inline operator T *() { return &x.x; } + inline operator const T *() const { return &x.x; } + operator struct D3DXMATRIX *() { return (struct D3DXMATRIX *)this; } + operator const struct D3DXMATRIX *() const { return (struct D3DXMATRIX *)this; } }; typedef mat4x4 float4x4; - -float4x4 operator*( const float4x4& a, const float4x4& b ); -float4 operator*( const float4& v, const float4x4& m ); +float4x4 operator*(const float4x4 &a, const float4x4 &b); +float4 operator*(const float4 &v, const float4x4 &m); float4x4 Inverse(const float4x4 &m); float4x4 MatrixRigidInverse(const float4x4 &m); float4x4 MatrixTranspose(const float4x4 &m); -float4x4 MatrixPerspectiveFov(float fovy, float Aspect, float zn, float zf ); +float4x4 MatrixPerspectiveFov(float fovy, float Aspect, float zn, float zf); float4x4 MatrixTranslation(const float3 &t); float4x4 MatrixRotationZ(const float angle_radians); -float4x4 MatrixLookAt(const float3& eye, const float3& at, const float3& up); -int operator==( const float4x4 &a, const float4x4 &b ); - +float4x4 MatrixLookAt(const float3 &eye, const float3 &at, const float3 &up); +int operator==(const float4x4 &a, const float4x4 &b); //-------- Quaternion ------------ -template +template class quaternion : public vec4 { - public: - inline quaternion() { this->x = this->y = this->z = 0.0f; this->w = 1.0f; } - inline quaternion(const T &_x, const T &_y, const T &_z, const T &_w){this->x=_x;this->y=_y;this->z=_z;this->w=_w;} - inline explicit quaternion(const vec4 &v):vec4(v){} - T angle() const { return acosf(this->w)*2.0f; } - vec3 axis() const { vec3 a(this->x,this->y,this->z); if(fabsf(angle())<0.0000001f) return vec3(1,0,0); return a*(1/sinf(angle()/2.0f)); } - inline vec3 xdir() const { return vec3( 1-2*(this->y*this->y+this->z*this->z), 2*(this->x*this->y+this->w*this->z), - 2*(this->x*this->z-this->w*this->y) ); } - inline vec3 ydir() const { return vec3( 2*(this->x*this->y-this->w*this->z),1-2*(this->x*this->x+this->z*this->z), 2*(this->y*this->z+this->w*this->x) ); } - inline vec3 zdir() const { return vec3( 2*(this->x*this->z+this->w*this->y), - 2*(this->y*this->z-this->w*this->x),1- - 2*(this->x*this->x+this->y*this->y) ); } - inline mat3x3 getmatrix() const { return mat3x3( xdir(), ydir(), zdir() ); } +public: + inline quaternion() + { + this->x = this->y = this->z = 0.0f; + this->w = 1.0f; + } + inline quaternion(const T &_x, const T &_y, const T &_z, const T &_w) + { + this->x = _x; + this->y = _y; + this->z = _z; + this->w = _w; + } + inline explicit quaternion(const vec4 &v) : vec4(v) {} + T angle() const { return acosf(this->w) * 2.0f; } + vec3 axis() const + { + vec3 a(this->x, this->y, this->z); + if (fabsf(angle()) < 0.0000001f) return vec3(1, 0, 0); + return a * (1 / sinf(angle() / 2.0f)); + } + inline vec3 xdir() const { return vec3(1 - 2 * (this->y * this->y + this->z * this->z), 2 * (this->x * this->y + this->w * this->z), + 2 * (this->x * this->z - this->w * this->y)); } + inline vec3 ydir() const { return vec3(2 * (this->x * this->y - this->w * this->z), 1 - 2 * (this->x * this->x + this->z * this->z), 2 * (this->y * this->z + this->w * this->x)); } + inline vec3 zdir() const { return vec3(2 * (this->x * this->z + this->w * this->y), + 2 * (this->y * this->z - this->w * this->x), 1 - 2 * (this->x * this->x + this->y * this->y)); } + inline mat3x3 getmatrix() const { return mat3x3(xdir(), ydir(), zdir()); } //operator float3x3() { return getmatrix(); } void Normalize(); }; -template +template inline quaternion quatfrommat(const mat3x3 &m) { - T magw = m[0 ][ 0] + m[1 ][ 1] + m[2 ][ 2]; + T magw = m[0][0] + m[1][1] + m[2][2]; T magxy; T magzw; vec3 pre; @@ -282,69 +510,100 @@ inline quaternion quatfrommat(const mat3x3 &m) quaternion postxy; quaternion postzw; quaternion post; - int wvsz = (magw > m[2][2] ) ; - magzw = (wvsz) ? magw : m[2][2]; - prezw = (wvsz) ? vec3(1.0f,1.0f,1.0f) : vec3(-1.0f,-1.0f,1.0f) ; - postzw = (wvsz) ? quaternion(0.0f,0.0f,0.0f,1.0f): quaternion(0.0f,0.0f,1.0f,0.0f); - int xvsy = (m[0][0]>m[1][1]); - magxy = (xvsy) ? m[0][0] : m[1][1]; - prexy = (xvsy) ? vec3(1.0f,-1.0f,-1.0f) : vec3(-1.0f,1.0f,-1.0f) ; - postxy = (xvsy) ? quaternion(1.0f,0.0f,0.0f,0.0f): quaternion(0.0f,1.0f,0.0f,0.0f); + int wvsz = (magw > m[2][2]); + magzw = (wvsz) ? magw : m[2][2]; + prezw = (wvsz) ? vec3(1.0f, 1.0f, 1.0f) : vec3(-1.0f, -1.0f, 1.0f); + postzw = (wvsz) ? quaternion(0.0f, 0.0f, 0.0f, 1.0f) : quaternion(0.0f, 0.0f, 1.0f, 0.0f); + int xvsy = (m[0][0] > m[1][1]); + magxy = (xvsy) ? m[0][0] : m[1][1]; + prexy = (xvsy) ? vec3(1.0f, -1.0f, -1.0f) : vec3(-1.0f, 1.0f, -1.0f); + postxy = (xvsy) ? quaternion(1.0f, 0.0f, 0.0f, 0.0f) : quaternion(0.0f, 1.0f, 0.0f, 0.0f); int zwvsxy = (magzw > magxy); - pre = (zwvsxy) ? prezw : prexy ; + pre = (zwvsxy) ? prezw : prexy; post = (zwvsxy) ? postzw : postxy; - T t = pre.x * m[0 ][ 0] + pre.y * m[1 ][ 1] + pre.z * m[2 ][ 2] + 1.0f; - T s = 1/sqrt(t) * 0.5f; + T t = pre.x * m[0][0] + pre.y * m[1][1] + pre.z * m[2][2] + 1.0f; + T s = 1 / sqrt(t) * 0.5f; quaternion qp; - qp.x = ( pre.y * m[1][2] - pre.z * m[2][1] ) * s; - qp.y = ( pre.z * m[2][0] - pre.x * m[0][2] ) * s; - qp.z = ( pre.x * m[0][1] - pre.y * m[1][0] ) * s; - qp.w = t * s ; - return qp * post ; + qp.x = (pre.y * m[1][2] - pre.z * m[2][1]) * s; + qp.y = (pre.z * m[2][0] - pre.x * m[0][2]) * s; + qp.z = (pre.x * m[0][1] - pre.y * m[1][0]) * s; + qp.w = t * s; + return qp * post; } typedef quaternion Quaternion; -inline Quaternion QuatFromAxisAngle(const float3 &_v, float angle_radians ) -{ - float3 v = normalize(_v)*sinf(angle_radians/2.0f); - return Quaternion(v.x,v.y,v.z,cosf(angle_radians/2.0f)); +inline Quaternion QuatFromAxisAngle(const float3 &_v, float angle_radians) +{ + float3 v = normalize(_v) * sinf(angle_radians / 2.0f); + return Quaternion(v.x, v.y, v.z, cosf(angle_radians / 2.0f)); } -template inline quaternion Conjugate(const quaternion &q){return quaternion(-q.x,-q.y,-q.z,q.w);} -template inline quaternion Inverse(const quaternion &q){return Conjugate(q);} -template inline quaternion normalize( const quaternion & a ){return quaternion (normalize((vec4&)a));} -template inline quaternion& operator*=(quaternion& a, T s ){return (quaternion&)((vec4&)a *=s);} -template inline quaternion operator*( const quaternion& a, float s ){return quaternion((vec4&)a*s);} -template inline quaternion operator+( const quaternion& a, const quaternion& b){return quaternion((vec4&)a+(vec4&)b);} -template inline quaternion operator-( const quaternion& a, const quaternion& b){return quaternion((vec4&)a-(vec4&)b);} -template inline quaternion operator-( const quaternion& b){return quaternion(-(vec4&)b);} -template inline quaternion operator*( const quaternion& a, const quaternion& b) +template +inline quaternion Conjugate(const quaternion &q) +{ + return quaternion(-q.x, -q.y, -q.z, q.w); +} +template +inline quaternion Inverse(const quaternion &q) +{ + return Conjugate(q); +} +template +inline quaternion normalize(const quaternion &a) +{ + return quaternion(normalize((vec4 &)a)); +} +template +inline quaternion &operator*=(quaternion &a, T s) +{ + return (quaternion &)((vec4 &)a *= s); +} +template +inline quaternion operator*(const quaternion &a, float s) +{ + return quaternion((vec4 &)a * s); +} +template +inline quaternion operator+(const quaternion &a, const quaternion &b) +{ + return quaternion((vec4 &)a + (vec4 &)b); +} +template +inline quaternion operator-(const quaternion &a, const quaternion &b) +{ + return quaternion((vec4 &)a - (vec4 &)b); +} +template +inline quaternion operator-(const quaternion &b) +{ + return quaternion(-(vec4 &)b); +} +template +inline quaternion operator*(const quaternion &a, const quaternion &b) { return quaternion( - a.w*b.x + a.x*b.w + a.y*b.z - a.z*b.y, //x - a.w*b.y - a.x*b.z + a.y*b.w + a.z*b.x, //y - a.w*b.z + a.x*b.y - a.y*b.x + a.z*b.w, //z - a.w*b.w - a.x*b.x - a.y*b.y - a.z*b.z ); //w + a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y, //x + a.w * b.y - a.x * b.z + a.y * b.w + a.z * b.x, //y + a.w * b.z + a.x * b.y - a.y * b.x + a.z * b.w, //z + a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z); //w } - -float3 rotate( const Quaternion& q, const float3& v ); +float3 rotate(const Quaternion &q, const float3 &v); //float3 operator*( const Quaternion& q, const float3& v ); //float3 operator*( const float3& v, const Quaternion& q ); -Quaternion slerp(const Quaternion &a, const Quaternion& b, float t ); -Quaternion Interpolate(const Quaternion &q0,const Quaternion &q1,float t); -Quaternion RotationArc(float3 v0, float3 v1 ); // returns quat q where q*v0*q^-1=v1 -float4x4 MatrixFromQuatVec(const Quaternion &q, const float3 &v); +Quaternion slerp(const Quaternion &a, const Quaternion &b, float t); +Quaternion Interpolate(const Quaternion &q0, const Quaternion &q1, float t); +Quaternion RotationArc(float3 v0, float3 v1); // returns quat q where q*v0*q^-1=v1 +float4x4 MatrixFromQuatVec(const Quaternion &q, const float3 &v); inline Quaternion QuatFromMat(const float3 &t, const float3 &b, const float3 &n) { - return normalize(quatfrommat(float3x3(t,b,n))); + return normalize(quatfrommat(float3x3(t, b, n))); } - //---------------- Pose ------------------ class Pose @@ -352,115 +611,113 @@ class Pose public: float3 position; Quaternion orientation; - Pose(){} - Pose(const float3 &p,const Quaternion &q):position(p),orientation(q){} - Pose &pose(){return *this;} - const Pose &pose() const {return *this;} + Pose() {} + Pose(const float3 &p, const Quaternion &q) : position(p), orientation(q) {} + Pose &pose() { return *this; } + const Pose &pose() const { return *this; } }; -inline float3 operator*(const Pose &a,const float3 &v) +inline float3 operator*(const Pose &a, const float3 &v) { - return a.position + rotate(a.orientation,v); + return a.position + rotate(a.orientation, v); } -inline Pose operator*(const Pose &a,const Pose &b) +inline Pose operator*(const Pose &a, const Pose &b) { - return Pose(a.position + rotate(a.orientation,b.position),a.orientation*b.orientation); + return Pose(a.position + rotate(a.orientation, b.position), a.orientation * b.orientation); } inline Pose Inverse(const Pose &a) { Quaternion q = Inverse(a.orientation); - return Pose(rotate(q,-a.position),q); + return Pose(rotate(q, -a.position), q); } -inline Pose slerp(const Pose &p0,const Pose &p1,float t) +inline Pose slerp(const Pose &p0, const Pose &p1, float t) { - return Pose(p0.position * (1.0f-t) + p1.position * t,slerp(p0.orientation,p1.orientation,t)); + return Pose(p0.position * (1.0f - t) + p1.position * t, slerp(p0.orientation, p1.orientation, t)); } inline float4x4 MatrixFromPose(const Pose &pose) { - return MatrixFromQuatVec(pose.orientation,pose.position); + return MatrixFromQuatVec(pose.orientation, pose.position); } //------ Euler Angle ----- -Quaternion YawPitchRoll( float yaw, float pitch, float roll ); -float Yaw( const Quaternion& q ); -float Pitch( const Quaternion& q ); -float Roll( const Quaternion &q ); -float Yaw( const float3& v ); -float Pitch( const float3& v ); +Quaternion YawPitchRoll(float yaw, float pitch, float roll); +float Yaw(const Quaternion &q); +float Pitch(const Quaternion &q); +float Roll(const Quaternion &q); +float Yaw(const float3 &v); +float Pitch(const float3 &v); //------- Plane ---------- class Plane : public float4 { - public: - float3& normal(){ return xyz(); } - const float3& normal() const { return xyz(); } - float& dist(){return w;} // distance below origin - the D from plane equasion Ax+By+Cz+D=0 - const float& dist() const{return w;} // distance below origin - the D from plane equasion Ax+By+Cz+D=0 - Plane(const float3 &n,float d):float4(n,d){} - Plane(){dist()=0;} - explicit Plane(const float4 &v):float4(v){} +public: + float3 &normal() { return xyz(); } + const float3 &normal() const { return xyz(); } + float &dist() { return w; } // distance below origin - the D from plane equasion Ax+By+Cz+D=0 + const float &dist() const { return w; } // distance below origin - the D from plane equasion Ax+By+Cz+D=0 + Plane(const float3 &n, float d) : float4(n, d) {} + Plane() { dist() = 0; } + explicit Plane(const float4 &v) : float4(v) {} }; -Plane Transform(const Plane &p, const float3 &translation, const Quaternion &rotation); +Plane Transform(const Plane &p, const float3 &translation, const Quaternion &rotation); -inline Plane PlaneFlip(const Plane &p){return Plane(-p.normal(),-p.dist());} -inline int operator==( const Plane &a, const Plane &b ) { return (a.normal()==b.normal() && a.dist()==b.dist()); } -inline int coplanar( const Plane &a, const Plane &b ) { return (a==b || a==PlaneFlip(b)); } +inline Plane PlaneFlip(const Plane &p) { return Plane(-p.normal(), -p.dist()); } +inline int operator==(const Plane &a, const Plane &b) { return (a.normal() == b.normal() && a.dist() == b.dist()); } +inline int coplanar(const Plane &a, const Plane &b) { return (a == b || a == PlaneFlip(b)); } -float3 PlaneLineIntersection(const Plane &plane, const float3 &p0, const float3 &p1); -float3 PlaneProject(const Plane &plane, const float3 &point); -float3 PlanesIntersection(const Plane &p0,const Plane &p1, const Plane &p2); -float3 PlanesIntersection(const Plane *planes,int planes_count,const float3 &seed=float3(0,0,0)); - -int Clip(const Plane &p,const float3 *verts_in,int count,float* verts_out); // verts_out must be preallocated with sufficient size >= count+1 or more if concave -int ClipPolyPoly(const float3 &normal,const float3 *clipper,int clipper_count,const float3 *verts_in, int in_count,float3 *scratch); //scratch must be preallocated +float3 PlaneLineIntersection(const Plane &plane, const float3 &p0, const float3 &p1); +float3 PlaneProject(const Plane &plane, const float3 &point); +float3 PlanesIntersection(const Plane &p0, const Plane &p1, const Plane &p2); +float3 PlanesIntersection(const Plane *planes, int planes_count, const float3 &seed = float3(0, 0, 0)); +int Clip(const Plane &p, const float3 *verts_in, int count, float *verts_out); // verts_out must be preallocated with sufficient size >= count+1 or more if concave +int ClipPolyPoly(const float3 &normal, const float3 *clipper, int clipper_count, const float3 *verts_in, int in_count, float3 *scratch); //scratch must be preallocated //--------- Utility Functions ------ -float3 PlaneLineIntersection(const float3 &normal,const float dist, const float3 &p0, const float3 &p1); -float3 LineProject(const float3 &p0, const float3 &p1, const float3 &a); // projects a onto infinite line p0p1 -float LineProjectTime(const float3 &p0, const float3 &p1, const float3 &a); -int BoxInside(const float3 &p,const float3 &bmin, const float3 &bmax) ; -int BoxIntersect(const float3 &v0, const float3 &v1, const float3 &bmin, const float3 &bmax, float3 *impact); -float DistanceBetweenLines(const float3 &ustart, const float3 &udir, const float3 &vstart, const float3 &vdir, float3 *upoint=NULL, float3 *vpoint=NULL); -float3 TriNormal(const float3 &v0, const float3 &v1, const float3 &v2); -float3 NormalOf(const float3 *vert, const int n); +float3 PlaneLineIntersection(const float3 &normal, const float dist, const float3 &p0, const float3 &p1); +float3 LineProject(const float3 &p0, const float3 &p1, const float3 &a); // projects a onto infinite line p0p1 +float LineProjectTime(const float3 &p0, const float3 &p1, const float3 &a); +int BoxInside(const float3 &p, const float3 &bmin, const float3 &bmax); +int BoxIntersect(const float3 &v0, const float3 &v1, const float3 &bmin, const float3 &bmax, float3 *impact); +float DistanceBetweenLines(const float3 &ustart, const float3 &udir, const float3 &vstart, const float3 &vdir, float3 *upoint = NULL, float3 *vpoint = NULL); +float3 TriNormal(const float3 &v0, const float3 &v1, const float3 &v2); +float3 NormalOf(const float3 *vert, const int n); Quaternion VirtualTrackBall(const float3 &cop, const float3 &cor, const float3 &dir0, const float3 &dir1); -int Clip(const float3 &plane_normal,float plane_dist,const float3 *verts_in,int count,float* verts_out); // verts_out must be preallocated with sufficient size >= count+1 or more if concave -int ClipPolyPoly(const float3 &normal,const float3 *clipper,int clipper_count,const float3 *verts_in, int in_count,float3 *scratch); //scratch must be preallocated -float3 Diagonal(const float3x3 &M); +int Clip(const float3 &plane_normal, float plane_dist, const float3 *verts_in, int count, float *verts_out); // verts_out must be preallocated with sufficient size >= count+1 or more if concave +int ClipPolyPoly(const float3 &normal, const float3 *clipper, int clipper_count, const float3 *verts_in, int in_count, float3 *scratch); //scratch must be preallocated +float3 Diagonal(const float3x3 &M); Quaternion Diagonalizer(const float3x3 &A); -float3 Orth(const float3& v); -int SolveQuadratic(float a,float b,float c,float *ta,float *tb); // if true returns roots ta,tb where ta<=tb -int HitCheckPoly(const float3 *vert,const int n,const float3 &v0, const float3 &v1, float3 *impact=NULL, float3 *normal=NULL); -int HitCheckRaySphere(const float3& sphereposition,float radius, const float3& _v0, const float3& _v1, float3 *impact,float3 *normal); -int HitCheckRayCylinder(const float3 &p0,const float3 &p1,float radius,const float3& _v0,const float3& _v1, float3 *impact,float3 *normal); -int HitCheckSweptSphereTri(const float3 &p0,const float3 &p1,const float3 &p2,float radius, const float3& v0,const float3& _v1, float3 *impact,float3 *normal); -void BoxLimits(const float3 *verts,int verts_count, float3 &bmin_out,float3 &bmax_out); -void BoxLimits(const float4 *verts,int verts_count, float3 &bmin_out,float3 &bmax_out); +float3 Orth(const float3 &v); +int SolveQuadratic(float a, float b, float c, float *ta, float *tb); // if true returns roots ta,tb where ta<=tb +int HitCheckPoly(const float3 *vert, const int n, const float3 &v0, const float3 &v1, float3 *impact = NULL, float3 *normal = NULL); +int HitCheckRaySphere(const float3 &sphereposition, float radius, const float3 &_v0, const float3 &_v1, float3 *impact, float3 *normal); +int HitCheckRayCylinder(const float3 &p0, const float3 &p1, float radius, const float3 &_v0, const float3 &_v1, float3 *impact, float3 *normal); +int HitCheckSweptSphereTri(const float3 &p0, const float3 &p1, const float3 &p2, float radius, const float3 &v0, const float3 &_v1, float3 *impact, float3 *normal); +void BoxLimits(const float3 *verts, int verts_count, float3 &bmin_out, float3 &bmax_out); +void BoxLimits(const float4 *verts, int verts_count, float3 &bmin_out, float3 &bmax_out); - -template -inline int maxdir(const T *p,int count,const T &dir) +template +inline int maxdir(const T *p, int count, const T &dir) { assert(count); - int m=0; - for(int i=1;idot(p[m],dir)) m=i; + if (dot(p[i], dir) > dot(p[m], dir)) m = i; } return m; } -float3 CenterOfMass(const float3 *vertices, const int3 *tris, const int count) ; -float3x3 Inertia(const float3 *vertices, const int3 *tris, const int count, const float3& com=float3(0,0,0)) ; -float Volume(const float3 *vertices, const int3 *tris, const int count) ; -int calchull(float3 *verts,int verts_count, int3 *&tris_out, int &tris_count,int vlimit); // computes convex hull see hull.cpp +float3 CenterOfMass(const float3 *vertices, const int3 *tris, const int count); +float3x3 Inertia(const float3 *vertices, const int3 *tris, const int count, const float3 &com = float3(0, 0, 0)); +float Volume(const float3 *vertices, const int3 *tris, const int count); +int calchull(float3 *verts, int verts_count, int3 *&tris_out, int &tris_count, int vlimit); // computes convex hull see hull.cpp -#endif // VEC_MATH_H +#endif // VEC_MATH_H diff --git a/examples/ExtendedTutorials/Bridge.cpp b/examples/ExtendedTutorials/Bridge.cpp index 41fe55290..1bc43a80c 100644 --- a/examples/ExtendedTutorials/Bridge.cpp +++ b/examples/ExtendedTutorials/Bridge.cpp @@ -13,23 +13,21 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "Bridge.h" #include "btBulletDynamicsCommon.h" #include "LinearMath/btVector3.h" -#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAlignedObjectArray.h" #include "../CommonInterfaces/CommonRigidBodyBase.h" const int TOTAL_PLANKS = 10; struct BridgeExample : public CommonRigidBodyBase { BridgeExample(struct GUIHelperInterface* helper) - :CommonRigidBodyBase(helper) + : CommonRigidBodyBase(helper) { } - virtual ~BridgeExample(){} + virtual ~BridgeExample() {} virtual void initPhysics(); virtual void renderScene(); void resetCamera() @@ -37,8 +35,8 @@ struct BridgeExample : public CommonRigidBodyBase float dist = 41; float pitch = -35; float yaw = 52; - float targetPos[3]={0,0.46,0}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {0, 0.46, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } }; @@ -47,81 +45,78 @@ void BridgeExample::initPhysics() m_guiHelper->setUpAxis(1); createEmptyDynamicsWorld(); - + m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); if (m_dynamicsWorld->getDebugDrawer()) - m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints); + m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints); ///create a few basic rigid bodies - btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); + btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.))); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0,-50,0)); + groundTransform.setOrigin(btVector3(0, -50, 0)); { btScalar mass(0.); - createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1)); + createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1)); } //create two fixed boxes to hold the planks - - { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance btScalar plankWidth = 0.4; btScalar plankHeight = 0.2; btScalar plankBreadth = 1; - btScalar plankOffset = plankWidth; //distance between two planks - btScalar bridgeWidth = plankWidth*TOTAL_PLANKS + plankOffset*(TOTAL_PLANKS-1); + btScalar plankOffset = plankWidth; //distance between two planks + btScalar bridgeWidth = plankWidth * TOTAL_PLANKS + plankOffset * (TOTAL_PLANKS - 1); btScalar bridgeHeight = 5; - btScalar halfBridgeWidth = bridgeWidth*0.5f; + btScalar halfBridgeWidth = bridgeWidth * 0.5f; + + btBoxShape* colShape = createBoxShape(btVector3(plankWidth, plankHeight, plankBreadth)); - btBoxShape* colShape = createBoxShape(btVector3(plankWidth,plankHeight,plankBreadth)); - m_collisionShapes.push_back(colShape); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); - btScalar mass(1.f); + btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); - btVector3 localInertia(0,0,0); + btVector3 localInertia(0, 0, 0); if (isDynamic) - colShape->calculateLocalInertia(mass,localInertia); + colShape->calculateLocalInertia(mass, localInertia); - //create a set of boxes to represent bridge + //create a set of boxes to represent bridge btAlignedObjectArray boxes; - int lastBoxIndex = TOTAL_PLANKS-1; - for(int i=0;iaddConstraint(leftSpring); - - btPoint2PointConstraint* rightSpring = new btPoint2PointConstraint(*b1, *b2, btVector3(-0.5,0,0.5), btVector3(0.5,0,0.5)); + + btPoint2PointConstraint* rightSpring = new btPoint2PointConstraint(*b1, *b2, btVector3(-0.5, 0, 0.5), btVector3(0.5, 0, 0.5)); m_dynamicsWorld->addConstraint(rightSpring); } } @@ -129,22 +124,12 @@ void BridgeExample::initPhysics() m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } - void BridgeExample::renderScene() { - CommonRigidBodyBase::renderScene(); + CommonRigidBodyBase::renderScene(); } - - - - - - -CommonExampleInterface* ET_BridgeCreateFunc(CommonExampleOptions& options) +CommonExampleInterface* ET_BridgeCreateFunc(CommonExampleOptions& options) { return new BridgeExample(options.m_guiHelper); } - - - diff --git a/examples/ExtendedTutorials/Bridge.h b/examples/ExtendedTutorials/Bridge.h index 5f8331183..5848e2fe0 100644 --- a/examples/ExtendedTutorials/Bridge.h +++ b/examples/ExtendedTutorials/Bridge.h @@ -16,7 +16,6 @@ subject to the following restrictions: #ifndef ET_BRIDGE_EXAMPLE_H #define ET_BRIDGE_EXAMPLE_H -class CommonExampleInterface* ET_BridgeCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* ET_BridgeCreateFunc(struct CommonExampleOptions& options); - -#endif //ET_BRIDGE_EXAMPLE_H +#endif //ET_BRIDGE_EXAMPLE_H diff --git a/examples/ExtendedTutorials/Chain.cpp b/examples/ExtendedTutorials/Chain.cpp index 73d2eb7e7..d8f0b8964 100644 --- a/examples/ExtendedTutorials/Chain.cpp +++ b/examples/ExtendedTutorials/Chain.cpp @@ -13,23 +13,21 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "Chain.h" #include "btBulletDynamicsCommon.h" #include "LinearMath/btVector3.h" -#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAlignedObjectArray.h" #include "../CommonInterfaces/CommonRigidBodyBase.h" const int TOTAL_BOXES = 10; struct ChainExample : public CommonRigidBodyBase { ChainExample(struct GUIHelperInterface* helper) - :CommonRigidBodyBase(helper) + : CommonRigidBodyBase(helper) { } - virtual ~ChainExample(){} + virtual ~ChainExample() {} virtual void initPhysics(); virtual void renderScene(); void resetCamera() @@ -37,8 +35,8 @@ struct ChainExample : public CommonRigidBodyBase float dist = 41; float pitch = -35; float yaw = 52; - float targetPos[3]={0,0.46,0}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {0, 0.46, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } }; @@ -47,67 +45,66 @@ void ChainExample::initPhysics() m_guiHelper->setUpAxis(1); createEmptyDynamicsWorld(); - + m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); if (m_dynamicsWorld->getDebugDrawer()) - m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints); + m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints); ///create a few basic rigid bodies - btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); + btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.))); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0,-50,0)); + groundTransform.setOrigin(btVector3(0, -50, 0)); { btScalar mass(0.); - createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1)); + createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1)); } - { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance - btBoxShape* colShape = createBoxShape(btVector3(1,1,0.25)); - + btBoxShape* colShape = createBoxShape(btVector3(1, 1, 0.25)); + m_collisionShapes.push_back(colShape); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); - btScalar mass(1.f); + btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); - btVector3 localInertia(0,0,0); + btVector3 localInertia(0, 0, 0); if (isDynamic) - colShape->calculateLocalInertia(mass,localInertia); - + colShape->calculateLocalInertia(mass, localInertia); + btAlignedObjectArray boxes; - int lastBoxIndex = TOTAL_BOXES-1; - for(int i=0;iaddConstraint(leftSpring); - - btPoint2PointConstraint* rightSpring = new btPoint2PointConstraint(*b1, *b2, btVector3(0.5,1,0), btVector3(0.5,-1,0)); + + btPoint2PointConstraint* rightSpring = new btPoint2PointConstraint(*b1, *b2, btVector3(0.5, 1, 0), btVector3(0.5, -1, 0)); m_dynamicsWorld->addConstraint(rightSpring); } @@ -116,22 +113,12 @@ void ChainExample::initPhysics() m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } - void ChainExample::renderScene() { - CommonRigidBodyBase::renderScene(); + CommonRigidBodyBase::renderScene(); } - - - - - - -CommonExampleInterface* ET_ChainCreateFunc(CommonExampleOptions& options) +CommonExampleInterface* ET_ChainCreateFunc(CommonExampleOptions& options) { return new ChainExample(options.m_guiHelper); } - - - diff --git a/examples/ExtendedTutorials/Chain.h b/examples/ExtendedTutorials/Chain.h index b9cea1195..5def1db92 100644 --- a/examples/ExtendedTutorials/Chain.h +++ b/examples/ExtendedTutorials/Chain.h @@ -16,7 +16,6 @@ subject to the following restrictions: #ifndef ET_CHAIN_EXAMPLE_H #define ET_CHAIN_EXAMPLE_H -class CommonExampleInterface* ET_ChainCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* ET_ChainCreateFunc(struct CommonExampleOptions& options); - -#endif //ET_CHAIN_EXAMPLE_H +#endif //ET_CHAIN_EXAMPLE_H diff --git a/examples/ExtendedTutorials/CompoundBoxes.cpp b/examples/ExtendedTutorials/CompoundBoxes.cpp index 3a67fc504..89ddefb80 100644 --- a/examples/ExtendedTutorials/CompoundBoxes.cpp +++ b/examples/ExtendedTutorials/CompoundBoxes.cpp @@ -13,23 +13,20 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "CompoundBoxes.h" #include "btBulletDynamicsCommon.h" #include "LinearMath/btVector3.h" -#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAlignedObjectArray.h" #include "../CommonInterfaces/CommonRigidBodyBase.h" - struct CompoundBoxesExample : public CommonRigidBodyBase { CompoundBoxesExample(struct GUIHelperInterface* helper) - :CommonRigidBodyBase(helper) + : CommonRigidBodyBase(helper) { } - virtual ~CompoundBoxesExample(){} + virtual ~CompoundBoxesExample() {} virtual void initPhysics(); virtual void renderScene(); void resetCamera() @@ -37,8 +34,8 @@ struct CompoundBoxesExample : public CommonRigidBodyBase float dist = 41; float pitch = -35; float yaw = 52; - float targetPos[3]={0,0.46,0}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {0, 0.46, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } }; @@ -47,36 +44,35 @@ void CompoundBoxesExample::initPhysics() m_guiHelper->setUpAxis(1); createEmptyDynamicsWorld(); - + m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); if (m_dynamicsWorld->getDebugDrawer()) - m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints); + m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints); ///create a few basic rigid bodies - btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); + btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.))); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0,-50,0)); + groundTransform.setOrigin(btVector3(0, -50, 0)); { btScalar mass(0.); - createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1)); + createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1)); } - { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance - btBoxShape* cube = createBoxShape(btVector3(0.5,0.5,0.5)); + btBoxShape* cube = createBoxShape(btVector3(0.5, 0.5, 0.5)); m_collisionShapes.push_back(cube); // create a new compound shape for making an L-beam from `cube`s btCompoundShape* compoundShape = new btCompoundShape(); btTransform transform; - + // add cubes in an L-beam fashion to the compound shape transform.setIdentity(); transform.setOrigin(btVector3(0, 0, 0)); @@ -90,8 +86,7 @@ void CompoundBoxesExample::initPhysics() transform.setOrigin(btVector3(0, 0, 1)); compoundShape->addChildShape(transform, cube); - - btScalar masses[3]={1, 1, 1}; + btScalar masses[3] = {1, 1, 1}; btTransform principal; btVector3 inertia; compoundShape->calculatePrincipalAxisTransform(masses, principal, inertia); @@ -103,9 +98,9 @@ void CompoundBoxesExample::initPhysics() // less efficient way to add the entire compund shape // to a new compund shape as a child compound2->addChildShape(principal.inverse(), compoundShape); -#else +#else // recompute the shift to make sure the compound shape is re-aligned - for (int i=0; i < compoundShape->getNumChildShapes(); i++) + for (int i = 0; i < compoundShape->getNumChildShapes(); i++) compound2->addChildShape(compoundShape->getChildTransform(i) * principal.inverse(), compoundShape->getChildShape(i)); #endif @@ -113,23 +108,18 @@ void CompoundBoxesExample::initPhysics() transform.setIdentity(); transform.setOrigin(btVector3(0, 10, 0)); - createRigidBody(1.0, transform, compound2); + createRigidBody(1.0, transform, compound2); } m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } - void CompoundBoxesExample::renderScene() { - CommonRigidBodyBase::renderScene(); + CommonRigidBodyBase::renderScene(); } - -CommonExampleInterface* ET_CompoundBoxesCreateFunc(CommonExampleOptions& options) +CommonExampleInterface* ET_CompoundBoxesCreateFunc(CommonExampleOptions& options) { return new CompoundBoxesExample(options.m_guiHelper); } - - - diff --git a/examples/ExtendedTutorials/CompoundBoxes.h b/examples/ExtendedTutorials/CompoundBoxes.h index a453d03e8..02a7eb087 100644 --- a/examples/ExtendedTutorials/CompoundBoxes.h +++ b/examples/ExtendedTutorials/CompoundBoxes.h @@ -16,7 +16,6 @@ subject to the following restrictions: #ifndef ET_COMPOUND_BOXES_EXAMPLE_H #define ET_COMPOUND_BOXES_EXAMPLE_H -class CommonExampleInterface* ET_CompoundBoxesCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* ET_CompoundBoxesCreateFunc(struct CommonExampleOptions& options); - -#endif //ET_COMPOUND_BOXES_EXAMPLE_H +#endif //ET_COMPOUND_BOXES_EXAMPLE_H diff --git a/examples/ExtendedTutorials/InclinedPlane.cpp b/examples/ExtendedTutorials/InclinedPlane.cpp index d6322f034..5cccc3bd9 100644 --- a/examples/ExtendedTutorials/InclinedPlane.cpp +++ b/examples/ExtendedTutorials/InclinedPlane.cpp @@ -13,34 +13,30 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "InclinedPlane.h" #include "btBulletDynamicsCommon.h" #include "LinearMath/btVector3.h" -#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAlignedObjectArray.h" #include "../CommonInterfaces/CommonRigidBodyBase.h" #include "../CommonInterfaces/CommonParameterInterface.h" -static btScalar gTilt = 20.0f/180.0f*SIMD_PI; // tilt the ramp 20 degrees +static btScalar gTilt = 20.0f / 180.0f * SIMD_PI; // tilt the ramp 20 degrees -static btScalar gRampFriction = 1; // set ramp friction to 1 +static btScalar gRampFriction = 1; // set ramp friction to 1 -static btScalar gRampRestitution = 0; // set ramp restitution to 0 (no restitution) +static btScalar gRampRestitution = 0; // set ramp restitution to 0 (no restitution) -static btScalar gBoxFriction = 1; // set box friction to 1 +static btScalar gBoxFriction = 1; // set box friction to 1 -static btScalar gBoxRestitution = 0; // set box restitution to 0 +static btScalar gBoxRestitution = 0; // set box restitution to 0 -static btScalar gSphereFriction = 1; // set sphere friction to 1 +static btScalar gSphereFriction = 1; // set sphere friction to 1 -static btScalar gSphereRollingFriction = 1; // set sphere rolling friction to 1 -static btScalar gSphereSpinningFriction = 0.3; // set sphere spinning friction to 0.3 +static btScalar gSphereRollingFriction = 1; // set sphere rolling friction to 1 +static btScalar gSphereSpinningFriction = 0.3; // set sphere spinning friction to 0.3 - - -static btScalar gSphereRestitution = 0; // set sphere restitution to 0 +static btScalar gSphereRestitution = 0; // set sphere restitution to 0 // handles for changes static btRigidBody* ramp = NULL; @@ -50,10 +46,10 @@ static btRigidBody* gSphere = NULL; struct InclinedPlaneExample : public CommonRigidBodyBase { InclinedPlaneExample(struct GUIHelperInterface* helper) - :CommonRigidBodyBase(helper) + : CommonRigidBodyBase(helper) { } - virtual ~InclinedPlaneExample(){} + virtual ~InclinedPlaneExample() {} virtual void initPhysics(); virtual void resetScene(); virtual void renderScene(); @@ -64,12 +60,9 @@ struct InclinedPlaneExample : public CommonRigidBodyBase float dist = 41; float pitch = -35; float yaw = 52; - float targetPos[3]={0,0.46,0}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {0, 0.46, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } - - - }; void onBoxFrictionChanged(float friction, void* userPtr); @@ -88,112 +81,109 @@ void onRampRestitutionChanged(float restitution, void* userPtr); void InclinedPlaneExample::initPhysics() { + { // create slider to change the ramp tilt + SliderParams slider("Ramp Tilt", &gTilt); + slider.m_minVal = 0; + slider.m_maxVal = SIMD_PI / 2.0f; + slider.m_clampToNotches = false; + slider.m_callback = onRampInclinationChanged; + m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); + } - { // create slider to change the ramp tilt - SliderParams slider("Ramp Tilt",&gTilt); - slider.m_minVal=0; - slider.m_maxVal=SIMD_PI/2.0f; - slider.m_clampToNotches = false; - slider.m_callback = onRampInclinationChanged; - m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); - } + { // create slider to change the ramp friction + SliderParams slider("Ramp Friction", &gRampFriction); + slider.m_minVal = 0; + slider.m_maxVal = 10; + slider.m_clampToNotches = false; + slider.m_callback = onRampFrictionChanged; + m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); + } - { // create slider to change the ramp friction - SliderParams slider("Ramp Friction",&gRampFriction); - slider.m_minVal=0; - slider.m_maxVal=10; - slider.m_clampToNotches = false; - slider.m_callback = onRampFrictionChanged; - m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); - } + { // create slider to change the ramp restitution + SliderParams slider("Ramp Restitution", &gRampRestitution); + slider.m_minVal = 0; + slider.m_maxVal = 1; + slider.m_clampToNotches = false; + slider.m_callback = onRampRestitutionChanged; + m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); + } - { // create slider to change the ramp restitution - SliderParams slider("Ramp Restitution",&gRampRestitution); - slider.m_minVal=0; - slider.m_maxVal=1; - slider.m_clampToNotches = false; - slider.m_callback = onRampRestitutionChanged; - m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); - } + { // create slider to change the box friction + SliderParams slider("Box Friction", &gBoxFriction); + slider.m_minVal = 0; + slider.m_maxVal = 10; + slider.m_clampToNotches = false; + slider.m_callback = onBoxFrictionChanged; + m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); + } - { // create slider to change the box friction - SliderParams slider("Box Friction",&gBoxFriction); - slider.m_minVal=0; - slider.m_maxVal=10; - slider.m_clampToNotches = false; - slider.m_callback = onBoxFrictionChanged; - m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); - } + { // create slider to change the box restitution + SliderParams slider("Box Restitution", &gBoxRestitution); + slider.m_minVal = 0; + slider.m_maxVal = 1; + slider.m_clampToNotches = false; + slider.m_callback = onBoxRestitutionChanged; + m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); + } - { // create slider to change the box restitution - SliderParams slider("Box Restitution",&gBoxRestitution); - slider.m_minVal=0; - slider.m_maxVal=1; - slider.m_clampToNotches = false; - slider.m_callback = onBoxRestitutionChanged; - m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); - } + { // create slider to change the sphere friction + SliderParams slider("Sphere Friction", &gSphereFriction); + slider.m_minVal = 0; + slider.m_maxVal = 10; + slider.m_clampToNotches = false; + slider.m_callback = onSphereFrictionChanged; + m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); + } - { // create slider to change the sphere friction - SliderParams slider("Sphere Friction",&gSphereFriction); - slider.m_minVal=0; - slider.m_maxVal=10; - slider.m_clampToNotches = false; - slider.m_callback = onSphereFrictionChanged; - m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); - } + { // create slider to change the sphere rolling friction + SliderParams slider("Sphere Rolling Friction", &gSphereRollingFriction); + slider.m_minVal = 0; + slider.m_maxVal = 10; + slider.m_clampToNotches = false; + slider.m_callback = onSphereRestitutionChanged; + m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); + } - { // create slider to change the sphere rolling friction - SliderParams slider("Sphere Rolling Friction",&gSphereRollingFriction); - slider.m_minVal=0; - slider.m_maxVal=10; - slider.m_clampToNotches = false; - slider.m_callback = onSphereRestitutionChanged; - m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); - } + { // create slider to change the sphere rolling friction + SliderParams slider("Sphere Spinning", &gSphereSpinningFriction); + slider.m_minVal = 0; + slider.m_maxVal = 2; + slider.m_clampToNotches = false; + slider.m_callback = onSphereRestitutionChanged; + m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); + } - { // create slider to change the sphere rolling friction - SliderParams slider("Sphere Spinning",&gSphereSpinningFriction); - slider.m_minVal=0; - slider.m_maxVal=2; - slider.m_clampToNotches = false; - slider.m_callback = onSphereRestitutionChanged; - m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); - } - + { // create slider to change the sphere restitution + SliderParams slider("Sphere Restitution", &gSphereRestitution); + slider.m_minVal = 0; + slider.m_maxVal = 1; + slider.m_clampToNotches = false; + m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); + } - { // create slider to change the sphere restitution - SliderParams slider("Sphere Restitution",&gSphereRestitution); - slider.m_minVal=0; - slider.m_maxVal=1; - slider.m_clampToNotches = false; - m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); - } - - m_guiHelper->setUpAxis(1); // set Y axis as up axis + m_guiHelper->setUpAxis(1); // set Y axis as up axis createEmptyDynamicsWorld(); - + // create debug drawer m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); if (m_dynamicsWorld->getDebugDrawer()) - m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints); + m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints); - - { // create a static ground - btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); + { // create a static ground + btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.))); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0,-50,0)); + groundTransform.setOrigin(btVector3(0, -50, 0)); btScalar mass(0.); - createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1)); + createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1)); } - { //create a static inclined plane - btBoxShape* inclinedPlaneShape = createBoxShape(btVector3(btScalar(20.),btScalar(1.),btScalar(10.))); + { //create a static inclined plane + btBoxShape* inclinedPlaneShape = createBoxShape(btVector3(btScalar(20.), btScalar(1.), btScalar(10.))); m_collisionShapes.push_back(inclinedPlaneShape); btTransform startTransform; @@ -201,24 +191,23 @@ void InclinedPlaneExample::initPhysics() // position the inclined plane above ground startTransform.setOrigin(btVector3( - btScalar(0), - btScalar(15), - btScalar(0))); + btScalar(0), + btScalar(15), + btScalar(0))); btQuaternion incline; - incline.setRotation(btVector3(0,0,1),gTilt); + incline.setRotation(btVector3(0, 0, 1), gTilt); startTransform.setRotation(incline); btScalar mass(0.); - ramp = createRigidBody(mass,startTransform,inclinedPlaneShape); + ramp = createRigidBody(mass, startTransform, inclinedPlaneShape); ramp->setFriction(gRampFriction); ramp->setRestitution(gRampRestitution); } + { //create a cube above the inclined plane + btBoxShape* boxShape = createBoxShape(btVector3(1, 1, 1)); - { //create a cube above the inclined plane - btBoxShape* boxShape = createBoxShape(btVector3(1,1,1)); - m_collisionShapes.push_back(boxShape); btTransform startTransform; @@ -230,13 +219,13 @@ void InclinedPlaneExample::initPhysics() btVector3(btScalar(0), btScalar(20), btScalar(2))); gBox = createRigidBody(boxMass, startTransform, boxShape); - gBox->forceActivationState(DISABLE_DEACTIVATION); // to prevent the box on the ramp from disabling + gBox->forceActivationState(DISABLE_DEACTIVATION); // to prevent the box on the ramp from disabling gBox->setFriction(gBoxFriction); gBox->setRestitution(gBoxRestitution); } - { //create a sphere above the inclined plane - btSphereShape* sphereShape = new btSphereShape(btScalar(1)); + { //create a sphere above the inclined plane + btSphereShape* sphereShape = new btSphereShape(btScalar(1)); m_collisionShapes.push_back(sphereShape); @@ -249,19 +238,19 @@ void InclinedPlaneExample::initPhysics() btVector3(btScalar(0), btScalar(20), btScalar(4))); gSphere = createRigidBody(sphereMass, startTransform, sphereShape); - gSphere->forceActivationState(DISABLE_DEACTIVATION); // to prevent the sphere on the ramp from disabling + gSphere->forceActivationState(DISABLE_DEACTIVATION); // to prevent the sphere on the ramp from disabling gSphere->setFriction(gSphereFriction); gSphere->setRestitution(gSphereRestitution); gSphere->setRollingFriction(gSphereRollingFriction); gSphere->setSpinningFriction(gSphereSpinningFriction); - } m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } -void InclinedPlaneExample::resetScene() { - { //reset a cube above the inclined plane +void InclinedPlaneExample::resetScene() +{ + { //reset a cube above the inclined plane btTransform startTransform; startTransform.setIdentity(); @@ -276,7 +265,7 @@ void InclinedPlaneExample::resetScene() { gBox->clearForces(); } - { //reset a sphere above the inclined plane + { //reset a sphere above the inclined plane btTransform startTransform; startTransform.setIdentity(); @@ -297,60 +286,70 @@ void InclinedPlaneExample::stepSimulation(float deltaTime) { m_dynamicsWorld->stepSimulation(deltaTime); } - } - void InclinedPlaneExample::renderScene() { CommonRigidBodyBase::renderScene(); } -bool InclinedPlaneExample::keyboardCallback(int key, int state) { -// b3Printf("Key pressed: %d in state %d \n",key,state); +bool InclinedPlaneExample::keyboardCallback(int key, int state) +{ + // b3Printf("Key pressed: %d in state %d \n",key,state); - switch (key) { - case 32 /*ASCII for space*/: { - resetScene(); - break; - } + switch (key) + { + case 32 /*ASCII for space*/: + { + resetScene(); + break; + } } return false; } - // GUI parameter modifiers -void onBoxFrictionChanged(float friction, void*){ - if(gBox){ +void onBoxFrictionChanged(float friction, void*) +{ + if (gBox) + { gBox->setFriction(friction); -// b3Printf("Friction of box changed to %f",friction ); + // b3Printf("Friction of box changed to %f",friction ); } } -void onBoxRestitutionChanged(float restitution, void*){ - if(gBox){ +void onBoxRestitutionChanged(float restitution, void*) +{ + if (gBox) + { gBox->setRestitution(restitution); //b3Printf("Restitution of box changed to %f",restitution); } } -void onSphereFrictionChanged(float friction, void*){ - if(gSphere){ +void onSphereFrictionChanged(float friction, void*) +{ + if (gSphere) + { gSphere->setFriction(friction); //b3Printf("Friction of sphere changed to %f",friction ); } } -void onSphereRestitutionChanged(float restitution, void*){ - if(gSphere){ +void onSphereRestitutionChanged(float restitution, void*) +{ + if (gSphere) + { gSphere->setRestitution(restitution); //b3Printf("Restitution of sphere changed to %f",restitution); } } -void onRampInclinationChanged(float inclination, void*){ - if(ramp){ +void onRampInclinationChanged(float inclination, void*) +{ + if (ramp) + { btTransform startTransform; startTransform.setIdentity(); @@ -359,29 +358,32 @@ void onRampInclinationChanged(float inclination, void*){ btVector3(btScalar(0), btScalar(15), btScalar(0))); btQuaternion incline; - incline.setRotation(btVector3(0,0,1),gTilt); + incline.setRotation(btVector3(0, 0, 1), gTilt); startTransform.setRotation(incline); ramp->setWorldTransform(startTransform); //b3Printf("Inclination of ramp changed to %f",inclination ); } } -void onRampFrictionChanged(float friction, void*){ - if(ramp){ +void onRampFrictionChanged(float friction, void*) +{ + if (ramp) + { ramp->setFriction(friction); //b3Printf("Friction of ramp changed to %f \n",friction ); } } -void onRampRestitutionChanged(float restitution, void*){ - if(ramp){ +void onRampRestitutionChanged(float restitution, void*) +{ + if (ramp) + { ramp->setRestitution(restitution); //b3Printf("Restitution of ramp changed to %f \n",restitution); } } - -CommonExampleInterface* ET_InclinedPlaneCreateFunc(CommonExampleOptions& options) +CommonExampleInterface* ET_InclinedPlaneCreateFunc(CommonExampleOptions& options) { return new InclinedPlaneExample(options.m_guiHelper); } diff --git a/examples/ExtendedTutorials/InclinedPlane.h b/examples/ExtendedTutorials/InclinedPlane.h index 23ea92dfd..fc61fe174 100644 --- a/examples/ExtendedTutorials/InclinedPlane.h +++ b/examples/ExtendedTutorials/InclinedPlane.h @@ -16,7 +16,6 @@ subject to the following restrictions: #ifndef ET_INCLINED_PLANE_EXAMPLE_H #define ET_INCLINED_PLANE_EXAMPLE_H -class CommonExampleInterface* ET_InclinedPlaneCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* ET_InclinedPlaneCreateFunc(struct CommonExampleOptions& options); - -#endif //ET_INCLINED_PLANE_EXAMPLE_H +#endif //ET_INCLINED_PLANE_EXAMPLE_H diff --git a/examples/ExtendedTutorials/MultiPendulum.cpp b/examples/ExtendedTutorials/MultiPendulum.cpp index 7dfdffea3..f10ebb29b 100644 --- a/examples/ExtendedTutorials/MultiPendulum.cpp +++ b/examples/ExtendedTutorials/MultiPendulum.cpp @@ -15,7 +15,7 @@ #include "MultiPendulum.h" -#include // TODO: Should I use another data structure? +#include // TODO: Should I use another data structure? #include #include "btBulletDynamicsCommon.h" @@ -24,80 +24,84 @@ #include "../CommonInterfaces/CommonRigidBodyBase.h" #include "../CommonInterfaces/CommonParameterInterface.h" -static btScalar gPendulaQty = 2; //TODO: This would actually be an Integer, but the Slider does not like integers, so I floor it when changed +static btScalar gPendulaQty = 2; //TODO: This would actually be an Integer, but the Slider does not like integers, so I floor it when changed -static btScalar gDisplacedPendula = 1; //TODO: This is an int as well +static btScalar gDisplacedPendula = 1; //TODO: This is an int as well -static btScalar gPendulaRestitution = 1; // Default pendulum restitution is 1 to restore all force +static btScalar gPendulaRestitution = 1; // Default pendulum restitution is 1 to restore all force -static btScalar gSphereRadius = 1; // The sphere radius +static btScalar gSphereRadius = 1; // The sphere radius static btScalar gCurrentPendulumLength = 8; -static btScalar gInitialPendulumLength = 8; // Default pendulum length (distance between two spheres) +static btScalar gInitialPendulumLength = 8; // Default pendulum length (distance between two spheres) -static btScalar gDisplacementForce = 30; // The default force with which we move the pendulum +static btScalar gDisplacementForce = 30; // The default force with which we move the pendulum -static btScalar gForceScalar = 0; // default force scalar to apply a displacement +static btScalar gForceScalar = 0; // default force scalar to apply a displacement -struct MultiPendulumExample: public CommonRigidBodyBase { - MultiPendulumExample(struct GUIHelperInterface* helper) : - CommonRigidBodyBase(helper) { +struct MultiPendulumExample : public CommonRigidBodyBase +{ + MultiPendulumExample(struct GUIHelperInterface* helper) : CommonRigidBodyBase(helper) + { } - virtual ~MultiPendulumExample() { + virtual ~MultiPendulumExample() + { } - virtual void initPhysics(); // build a multi pendulum - virtual void renderScene(); // render the scene to screen - virtual void createMultiPendulum(btSphereShape* colShape, btScalar pendulaQty, const btVector3& position, btScalar length, btScalar mass); // create a multi pendulum at the indicated x and y position, the specified number of pendula formed into a chain, each with indicated length and mass - virtual void changePendulaLength(btScalar length); // change the pendulum length - virtual void changePendulaRestitution(btScalar restitution); // change the pendula restitution - virtual void stepSimulation(float deltaTime); // step the simulation - virtual bool keyboardCallback(int key, int state); // handle keyboard callbacks + virtual void initPhysics(); // build a multi pendulum + virtual void renderScene(); // render the scene to screen + virtual void createMultiPendulum(btSphereShape* colShape, btScalar pendulaQty, const btVector3& position, btScalar length, btScalar mass); // create a multi pendulum at the indicated x and y position, the specified number of pendula formed into a chain, each with indicated length and mass + virtual void changePendulaLength(btScalar length); // change the pendulum length + virtual void changePendulaRestitution(btScalar restitution); // change the pendula restitution + virtual void stepSimulation(float deltaTime); // step the simulation + virtual bool keyboardCallback(int key, int state); // handle keyboard callbacks virtual void applyPendulumForce(btScalar pendulumForce); - void resetCamera() { + void resetCamera() + { float dist = 41; float pitch = -35; float yaw = 52; - float targetPos[3] = { 0, 0.46, 0 }; + float targetPos[3] = {0, 0.46, 0}; m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], - targetPos[2]); + targetPos[2]); } - std::vector constraints; // keep a handle to the slider constraints - std::vector pendula; // keep a handle to the pendula + std::vector constraints; // keep a handle to the slider constraints + std::vector pendula; // keep a handle to the pendula }; -static MultiPendulumExample* mex = NULL; // Handle to the example to access it via functions. Do not use this in your simulation! +static MultiPendulumExample* mex = NULL; // Handle to the example to access it via functions. Do not use this in your simulation! -void onMultiPendulaLengthChanged(float pendulaLength, void*); // Change the pendula length +void onMultiPendulaLengthChanged(float pendulaLength, void*); // Change the pendula length -void onMultiPendulaRestitutionChanged(float pendulaRestitution, void*); // change the pendula restitution +void onMultiPendulaRestitutionChanged(float pendulaRestitution, void*); // change the pendula restitution void applyMForceWithForceScalar(float forceScalar); -void MultiPendulumExample::initPhysics() { // Setup your physics scene +void MultiPendulumExample::initPhysics() +{ // Setup your physics scene - { // create a slider to change the number of pendula + { // create a slider to change the number of pendula SliderParams slider("Number of Pendula", &gPendulaQty); slider.m_minVal = 1; slider.m_maxVal = 50; - slider.m_clampToIntegers = true; + slider.m_clampToIntegers = true; m_guiHelper->getParameterInterface()->registerSliderFloatParameter( slider); } - { // create a slider to change the number of displaced pendula + { // create a slider to change the number of displaced pendula SliderParams slider("Number of Displaced Pendula", &gDisplacedPendula); slider.m_minVal = 0; slider.m_maxVal = 49; - slider.m_clampToIntegers = true; + slider.m_clampToIntegers = true; m_guiHelper->getParameterInterface()->registerSliderFloatParameter( slider); } - { // create a slider to change the pendula restitution + { // create a slider to change the pendula restitution SliderParams slider("Pendula Restitution", &gPendulaRestitution); slider.m_minVal = 0; slider.m_maxVal = 1; @@ -107,7 +111,7 @@ void MultiPendulumExample::initPhysics() { // Setup your physics scene slider); } - { // create a slider to change the pendulum length + { // create a slider to change the pendulum length SliderParams slider("Pendula Length", &gCurrentPendulumLength); slider.m_minVal = 0; slider.m_maxVal = 49; @@ -117,7 +121,7 @@ void MultiPendulumExample::initPhysics() { // Setup your physics scene slider); } - { // create a slider to change the force to displace the lowest pendulum + { // create a slider to change the force to displace the lowest pendulum SliderParams slider("Displacement force", &gDisplacementForce); slider.m_minVal = 0.1; slider.m_maxVal = 200; @@ -126,7 +130,7 @@ void MultiPendulumExample::initPhysics() { // Setup your physics scene slider); } - { // create a slider to apply the force by slider + { // create a slider to apply the force by slider SliderParams slider("Apply displacement force", &gForceScalar); slider.m_minVal = -1; slider.m_maxVal = 1; @@ -143,15 +147,12 @@ void MultiPendulumExample::initPhysics() { // Setup your physics scene m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); if (m_dynamicsWorld->getDebugDrawer()) m_dynamicsWorld->getDebugDrawer()->setDebugMode( - btIDebugDraw::DBG_DrawWireframe - + btIDebugDraw::DBG_DrawContactPoints - + btIDebugDraw::DBG_DrawConstraints - + btIDebugDraw::DBG_DrawConstraintLimits); + btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints + btIDebugDraw::DBG_DrawConstraints + btIDebugDraw::DBG_DrawConstraintLimits); - { // create the multipendulum starting at the indicated position below and where each pendulum has the following mass + { // create the multipendulum starting at the indicated position below and where each pendulum has the following mass btScalar pendulumMass(1.f); - btVector3 position(0.0f,15.0f,0.0f); // initial top-most pendulum position + btVector3 position(0.0f, 15.0f, 0.0f); // initial top-most pendulum position // Re-using the same collision is better for memory usage and performance btSphereShape* pendulumShape = new btSphereShape(gSphereRadius); @@ -159,25 +160,26 @@ void MultiPendulumExample::initPhysics() { // Setup your physics scene // create multi-pendulum createMultiPendulum(pendulumShape, floor(gPendulaQty), position, - gInitialPendulumLength, pendulumMass); + gInitialPendulumLength, pendulumMass); } m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } -void MultiPendulumExample::stepSimulation(float deltaTime) { +void MultiPendulumExample::stepSimulation(float deltaTime) +{ + applyMForceWithForceScalar(gForceScalar); // apply force defined by apply force slider - applyMForceWithForceScalar(gForceScalar); // apply force defined by apply force slider - - if (m_dynamicsWorld) { + if (m_dynamicsWorld) + { m_dynamicsWorld->stepSimulation(deltaTime); } } void MultiPendulumExample::createMultiPendulum(btSphereShape* colShape, - btScalar pendulaQty, const btVector3& position, - btScalar length, btScalar mass) { - + btScalar pendulaQty, const btVector3& position, + btScalar length, btScalar mass) +{ // The multi-pendulum looks like this (names when built): //..........0......./.......1...../.......2......./..etc...:pendulum build iterations // O parentSphere @@ -196,7 +198,7 @@ void MultiPendulumExample::createMultiPendulum(btSphereShape* colShape, // position the top sphere startTransform.setOrigin(position); - startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation + startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation btRigidBody* topSphere = createRigidBody(mass, startTransform, colShape); @@ -209,25 +211,26 @@ void MultiPendulumExample::createMultiPendulum(btSphereShape* colShape, btPoint2PointConstraint* p2pconst = new btPoint2PointConstraint( *topSphere, constraintPivot); - p2pconst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing + p2pconst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing // add the constraint to the world m_dynamicsWorld->addConstraint(p2pconst, true); - btRigidBody* parentSphere = topSphere; // set the top sphere as the parent sphere for the next sphere to be created + btRigidBody* parentSphere = topSphere; // set the top sphere as the parent sphere for the next sphere to be created - for (int i = 0; i < pendulaQty; i++) { // produce the number of pendula + for (int i = 0; i < pendulaQty; i++) + { // produce the number of pendula // create joint element to make the pendulum rotate it // position the joint sphere at the same position as the top sphere - startTransform.setOrigin(position - btVector3(0,length*(i),0)); + startTransform.setOrigin(position - btVector3(0, length * (i), 0)); - startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation + startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation btRigidBody* jointSphere = createRigidBody(mass, startTransform, - colShape); - jointSphere->setFriction(0); // we do not need friction here + colShape); + jointSphere->setFriction(0); // we do not need friction here // disable the deactivation when object does not move anymore jointSphere->setActivationState(DISABLE_DEACTIVATION); @@ -248,25 +251,25 @@ void MultiPendulumExample::createMultiPendulum(btSphereShape* colShape, constraintPivotInJointSphereRF.setOrigin(parentSphereInJointSphereRF); btPoint2PointConstraint* p2pconst = new btPoint2PointConstraint( - *parentSphere,*jointSphere,constraintPivotInParentSphereRF.getOrigin(), constraintPivotInJointSphereRF.getOrigin()); + *parentSphere, *jointSphere, constraintPivotInParentSphereRF.getOrigin(), constraintPivotInJointSphereRF.getOrigin()); - p2pconst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing + p2pconst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing // add the constraint to the world m_dynamicsWorld->addConstraint(p2pconst, true); // create a slider constraint to change the length of the pendula while it swings - startTransform.setIdentity(); // reset start transform + startTransform.setIdentity(); // reset start transform // position the child sphere below the joint sphere - startTransform.setOrigin(position - btVector3(0,length*(i+1),0)); + startTransform.setOrigin(position - btVector3(0, length * (i + 1), 0)); - startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation + startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation btRigidBody* childSphere = createRigidBody(mass, startTransform, - colShape); - childSphere->setFriction(0); // we do not need friction here + colShape); + childSphere->setFriction(0); // we do not need friction here pendula.push_back(childSphere); // disable the deactivation when object does not move anymore @@ -291,13 +294,13 @@ void MultiPendulumExample::createMultiPendulum(btSphereShape* colShape, // the slider constraint is x aligned per default, but we want it to be y aligned, therefore we rotate it btQuaternion qt; qt.setEuler(0, 0, -SIMD_HALF_PI); - constraintPivotInJointSphereRF.setRotation(qt); //we use Y like up Axis - constraintPivotInChildSphereRF.setRotation(qt); //we use Y like up Axis + constraintPivotInJointSphereRF.setRotation(qt); //we use Y like up Axis + constraintPivotInChildSphereRF.setRotation(qt); //we use Y like up Axis btSliderConstraint* sliderConst = new btSliderConstraint(*jointSphere, - *childSphere, constraintPivotInJointSphereRF, constraintPivotInChildSphereRF, true); + *childSphere, constraintPivotInJointSphereRF, constraintPivotInChildSphereRF, true); - sliderConst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing + sliderConst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing // set limits // the initial setup of the constraint defines the origins of the limit dimensions, @@ -314,77 +317,89 @@ void MultiPendulumExample::createMultiPendulum(btSphereShape* colShape, } } -void MultiPendulumExample::changePendulaLength(btScalar length) { +void MultiPendulumExample::changePendulaLength(btScalar length) +{ btScalar lowerLimit = -gInitialPendulumLength; for (std::vector::iterator sit = constraints.begin(); - sit != constraints.end(); sit++) { + sit != constraints.end(); sit++) + { btAssert((*sit) && "Null constraint"); // if the pendulum is being shortened beyond it's own length, we don't let the lower sphere to go past the upper one - if (lowerLimit <= length) { + if (lowerLimit <= length) + { (*sit)->setLowerLinLimit(length + lowerLimit); (*sit)->setUpperLinLimit(length + lowerLimit); } } } -void MultiPendulumExample::changePendulaRestitution(btScalar restitution) { +void MultiPendulumExample::changePendulaRestitution(btScalar restitution) +{ for (std::vector::iterator rit = pendula.begin(); - rit != pendula.end(); rit++) { + rit != pendula.end(); rit++) + { btAssert((*rit) && "Null constraint"); (*rit)->setRestitution(restitution); } } -void MultiPendulumExample::renderScene() { +void MultiPendulumExample::renderScene() +{ CommonRigidBodyBase::renderScene(); } -bool MultiPendulumExample::keyboardCallback(int key, int state) { - +bool MultiPendulumExample::keyboardCallback(int key, int state) +{ //b3Printf("Key pressed: %d in state %d \n",key,state); //key 1, key 2, key 3 - switch (key) { - case '1' /*ASCII for 1*/: { + switch (key) + { + case '1' /*ASCII for 1*/: + { + //assumption: Sphere are aligned in Z axis + btScalar newLimit = btScalar(gCurrentPendulumLength + 0.1); - //assumption: Sphere are aligned in Z axis - btScalar newLimit = btScalar(gCurrentPendulumLength + 0.1); - - changePendulaLength(newLimit); - gCurrentPendulumLength = newLimit; - - b3Printf("Increase pendulum length to %f", gCurrentPendulumLength); - return true; - } - case '2' /*ASCII for 2*/: { - - //assumption: Sphere are aligned in Z axis - btScalar newLimit = btScalar(gCurrentPendulumLength - 0.1); - - //is being shortened beyond it's own length, we don't let the lower sphere to go over the upper one - if (0 <= newLimit) { changePendulaLength(newLimit); gCurrentPendulumLength = newLimit; - } - b3Printf("Decrease pendulum length to %f", gCurrentPendulumLength); - return true; - } - case '3' /*ASCII for 3*/: { - applyPendulumForce(gDisplacementForce); - return true; - } + b3Printf("Increase pendulum length to %f", gCurrentPendulumLength); + return true; + } + case '2' /*ASCII for 2*/: + { + //assumption: Sphere are aligned in Z axis + btScalar newLimit = btScalar(gCurrentPendulumLength - 0.1); + + //is being shortened beyond it's own length, we don't let the lower sphere to go over the upper one + if (0 <= newLimit) + { + changePendulaLength(newLimit); + gCurrentPendulumLength = newLimit; + } + + b3Printf("Decrease pendulum length to %f", gCurrentPendulumLength); + return true; + } + case '3' /*ASCII for 3*/: + { + applyPendulumForce(gDisplacementForce); + return true; + } } return false; } -void MultiPendulumExample::applyPendulumForce(btScalar pendulumForce){ - if(pendulumForce != 0){ - b3Printf("Apply %f to pendulum",pendulumForce); - for (int i = 0; i < gDisplacedPendula; i++) { +void MultiPendulumExample::applyPendulumForce(btScalar pendulumForce) +{ + if (pendulumForce != 0) + { + b3Printf("Apply %f to pendulum", pendulumForce); + for (int i = 0; i < gDisplacedPendula; i++) + { if (gDisplacedPendula >= 0 && gDisplacedPendula <= gPendulaQty) pendula[i]->applyCentralForce(btVector3(pendulumForce, 0, 0)); } @@ -393,26 +408,30 @@ void MultiPendulumExample::applyPendulumForce(btScalar pendulumForce){ // GUI parameter modifiers -void onMultiPendulaLengthChanged(float pendulaLength, void*) { // Change the pendula length - if (mex){ +void onMultiPendulaLengthChanged(float pendulaLength, void*) +{ // Change the pendula length + if (mex) + { mex->changePendulaLength(pendulaLength); } //b3Printf("Pendula length changed to %f \n",sliderValue ); - } -void onMultiPendulaRestitutionChanged(float pendulaRestitution, void*) { // change the pendula restitution - if (mex){ +void onMultiPendulaRestitutionChanged(float pendulaRestitution, void*) +{ // change the pendula restitution + if (mex) + { mex->changePendulaRestitution(pendulaRestitution); } - } -void applyMForceWithForceScalar(float forceScalar) { - if(mex){ +void applyMForceWithForceScalar(float forceScalar) +{ + if (mex) + { btScalar appliedForce = forceScalar * gDisplacementForce; - if(fabs(gForceScalar) < 0.2f) + if (fabs(gForceScalar) < 0.2f) gForceScalar = 0; mex->applyPendulumForce(appliedForce); @@ -420,7 +439,8 @@ void applyMForceWithForceScalar(float forceScalar) { } CommonExampleInterface* ET_MultiPendulumCreateFunc( - CommonExampleOptions& options) { + CommonExampleOptions& options) +{ mex = new MultiPendulumExample(options.m_guiHelper); return mex; } diff --git a/examples/ExtendedTutorials/MultiPendulum.h b/examples/ExtendedTutorials/MultiPendulum.h index 336c1be3c..75e67fe86 100644 --- a/examples/ExtendedTutorials/MultiPendulum.h +++ b/examples/ExtendedTutorials/MultiPendulum.h @@ -16,7 +16,6 @@ subject to the following restrictions: #ifndef ET_MULTI_PENDULUM_EXAMPLE_H #define ET_MULTI_PENDULUM_EXAMPLE_H -class CommonExampleInterface* ET_MultiPendulumCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* ET_MultiPendulumCreateFunc(struct CommonExampleOptions& options); - -#endif //ET_MULTI_PENDULUM_EXAMPLE_H +#endif //ET_MULTI_PENDULUM_EXAMPLE_H diff --git a/examples/ExtendedTutorials/MultipleBoxes.cpp b/examples/ExtendedTutorials/MultipleBoxes.cpp index 8db651aa0..cbb690188 100644 --- a/examples/ExtendedTutorials/MultipleBoxes.cpp +++ b/examples/ExtendedTutorials/MultipleBoxes.cpp @@ -13,23 +13,21 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "MultipleBoxes.h" #include "btBulletDynamicsCommon.h" #include "LinearMath/btVector3.h" -#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAlignedObjectArray.h" #include "../CommonInterfaces/CommonRigidBodyBase.h" const int TOTAL_BOXES = 10; struct MultipleBoxesExample : public CommonRigidBodyBase { MultipleBoxesExample(struct GUIHelperInterface* helper) - :CommonRigidBodyBase(helper) + : CommonRigidBodyBase(helper) { } - virtual ~MultipleBoxesExample(){} + virtual ~MultipleBoxesExample() {} virtual void initPhysics(); virtual void renderScene(); void resetCamera() @@ -37,8 +35,8 @@ struct MultipleBoxesExample : public CommonRigidBodyBase float dist = 41; float pitch = -35; float yaw = 52; - float targetPos[3]={0,0.46,0}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {0, 0.46, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } }; @@ -47,74 +45,63 @@ void MultipleBoxesExample::initPhysics() m_guiHelper->setUpAxis(1); createEmptyDynamicsWorld(); - + m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); if (m_dynamicsWorld->getDebugDrawer()) - m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints); + m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints); ///create a few basic rigid bodies - btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); + btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.))); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0,-50,0)); + groundTransform.setOrigin(btVector3(0, -50, 0)); { btScalar mass(0.); - createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1)); + createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1)); } - { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance - btBoxShape* colShape = createBoxShape(btVector3(1,1,1)); - + btBoxShape* colShape = createBoxShape(btVector3(1, 1, 1)); + m_collisionShapes.push_back(colShape); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); - btScalar mass(1.f); + btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); - btVector3 localInertia(0,0,0); + btVector3 localInertia(0, 0, 0); if (isDynamic) - colShape->calculateLocalInertia(mass,localInertia); + colShape->calculateLocalInertia(mass, localInertia); - - for(int i=0;iautogenerateGraphicsObjects(m_dynamicsWorld); } - void MultipleBoxesExample::renderScene() { - CommonRigidBodyBase::renderScene(); + CommonRigidBodyBase::renderScene(); } - - - - - - -CommonExampleInterface* ET_MultipleBoxesCreateFunc(CommonExampleOptions& options) +CommonExampleInterface* ET_MultipleBoxesCreateFunc(CommonExampleOptions& options) { return new MultipleBoxesExample(options.m_guiHelper); } - - - diff --git a/examples/ExtendedTutorials/MultipleBoxes.h b/examples/ExtendedTutorials/MultipleBoxes.h index 56e28b61d..5f34c585a 100644 --- a/examples/ExtendedTutorials/MultipleBoxes.h +++ b/examples/ExtendedTutorials/MultipleBoxes.h @@ -16,7 +16,6 @@ subject to the following restrictions: #ifndef ET_MULTIPLE_BOXES_EXAMPLE_H #define ET_MULTIPLE_BOXES_EXAMPLE_H -class CommonExampleInterface* ET_MultipleBoxesCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* ET_MultipleBoxesCreateFunc(struct CommonExampleOptions& options); - -#endif //ET_MULTIPLE_BOXES_EXAMPLE_H +#endif //ET_MULTIPLE_BOXES_EXAMPLE_H diff --git a/examples/ExtendedTutorials/NewtonsCradle.cpp b/examples/ExtendedTutorials/NewtonsCradle.cpp index 92924bc7d..eae300a7e 100644 --- a/examples/ExtendedTutorials/NewtonsCradle.cpp +++ b/examples/ExtendedTutorials/NewtonsCradle.cpp @@ -15,38 +15,40 @@ #include "NewtonsCradle.h" -#include // TODO: Should I use another data structure? +#include // TODO: Should I use another data structure? #include #include "btBulletDynamicsCommon.h" #include "LinearMath/btVector3.h" -#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAlignedObjectArray.h" #include "../CommonInterfaces/CommonRigidBodyBase.h" #include "../CommonInterfaces/CommonParameterInterface.h" -static btScalar gPendulaQty = 5; // Number of pendula in newton's cradle +static btScalar gPendulaQty = 5; // Number of pendula in newton's cradle //TODO: This would actually be an Integer, but the Slider does not like integers, so I floor it when changed -static btScalar gDisplacedPendula = 1; // number of displaced pendula +static btScalar gDisplacedPendula = 1; // number of displaced pendula //TODO: This is an int as well -static btScalar gPendulaRestitution = 1; // pendula restitution when hitting against each other +static btScalar gPendulaRestitution = 1; // pendula restitution when hitting against each other -static btScalar gSphereRadius = 1; // pendula radius +static btScalar gSphereRadius = 1; // pendula radius -static btScalar gCurrentPendulumLength = 8; // current pendula length +static btScalar gCurrentPendulumLength = 8; // current pendula length -static btScalar gInitialPendulumLength = 8; // default pendula length +static btScalar gInitialPendulumLength = 8; // default pendula length -static btScalar gDisplacementForce = 30; // default force to displace the pendula +static btScalar gDisplacementForce = 30; // default force to displace the pendula -static btScalar gForceScalar = 0; // default force scalar to apply a displacement +static btScalar gForceScalar = 0; // default force scalar to apply a displacement -struct NewtonsCradleExample: public CommonRigidBodyBase { - NewtonsCradleExample(struct GUIHelperInterface* helper) : - CommonRigidBodyBase(helper) { +struct NewtonsCradleExample : public CommonRigidBodyBase +{ + NewtonsCradleExample(struct GUIHelperInterface* helper) : CommonRigidBodyBase(helper) + { } - virtual ~NewtonsCradleExample() { + virtual ~NewtonsCradleExample() + { } virtual void initPhysics(); virtual void renderScene(); @@ -56,48 +58,49 @@ struct NewtonsCradleExample: public CommonRigidBodyBase { virtual void stepSimulation(float deltaTime); virtual bool keyboardCallback(int key, int state); virtual void applyPendulumForce(btScalar pendulumForce); - void resetCamera() { + void resetCamera() + { float dist = 41; float pitch = -35; float yaw = 52; - float targetPos[3] = { 0, 0.46, 0 }; + float targetPos[3] = {0, 0.46, 0}; m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], - targetPos[2]); + targetPos[2]); } - std::vector constraints; // keep a handle to the slider constraints - std::vector pendula; // keep a handle to the pendula + std::vector constraints; // keep a handle to the slider constraints + std::vector pendula; // keep a handle to the pendula }; static NewtonsCradleExample* nex = NULL; -void onPendulaLengthChanged(float pendulaLength, void* userPtr); // Change the pendula length +void onPendulaLengthChanged(float pendulaLength, void* userPtr); // Change the pendula length -void onPendulaRestitutionChanged(float pendulaRestitution, void* userPtr); // change the pendula restitution +void onPendulaRestitutionChanged(float pendulaRestitution, void* userPtr); // change the pendula restitution void applyForceWithForceScalar(float forceScalar); -void NewtonsCradleExample::initPhysics() { - - { // create a slider to change the number of pendula +void NewtonsCradleExample::initPhysics() +{ + { // create a slider to change the number of pendula SliderParams slider("Number of Pendula", &gPendulaQty); slider.m_minVal = 1; slider.m_maxVal = 50; - slider.m_clampToIntegers = true; + slider.m_clampToIntegers = true; m_guiHelper->getParameterInterface()->registerSliderFloatParameter( slider); } - { // create a slider to change the number of displaced pendula + { // create a slider to change the number of displaced pendula SliderParams slider("Number of Displaced Pendula", &gDisplacedPendula); slider.m_minVal = 0; slider.m_maxVal = 49; - slider.m_clampToIntegers = true; + slider.m_clampToIntegers = true; m_guiHelper->getParameterInterface()->registerSliderFloatParameter( slider); } - { // create a slider to change the pendula restitution + { // create a slider to change the pendula restitution SliderParams slider("Pendula Restitution", &gPendulaRestitution); slider.m_minVal = 0; slider.m_maxVal = 1; @@ -107,7 +110,7 @@ void NewtonsCradleExample::initPhysics() { slider); } - { // create a slider to change the pendulum length + { // create a slider to change the pendulum length SliderParams slider("Pendula Length", &gCurrentPendulumLength); slider.m_minVal = 0; slider.m_maxVal = 49; @@ -117,7 +120,7 @@ void NewtonsCradleExample::initPhysics() { slider); } - { // create a slider to change the force to displace the lowest pendulum + { // create a slider to change the force to displace the lowest pendulum SliderParams slider("Displacement force", &gDisplacementForce); slider.m_minVal = 0.1; slider.m_maxVal = 200; @@ -126,7 +129,7 @@ void NewtonsCradleExample::initPhysics() { slider); } - { // create a slider to apply the force by slider + { // create a slider to apply the force by slider SliderParams slider("Apply displacement force", &gForceScalar); slider.m_minVal = -1; slider.m_maxVal = 1; @@ -143,45 +146,43 @@ void NewtonsCradleExample::initPhysics() { m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); if (m_dynamicsWorld->getDebugDrawer()) m_dynamicsWorld->getDebugDrawer()->setDebugMode( - btIDebugDraw::DBG_DrawWireframe - + btIDebugDraw::DBG_DrawContactPoints - + btIDebugDraw::DBG_DrawConstraints - + btIDebugDraw::DBG_DrawConstraintLimits); + btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints + btIDebugDraw::DBG_DrawConstraints + btIDebugDraw::DBG_DrawConstraintLimits); - { // create the pendula starting at the indicated position below and where each pendulum has the following mass + { // create the pendula starting at the indicated position below and where each pendulum has the following mass btScalar pendulumMass(1.f); - btVector3 position(0.0f,15.0f,0.0f); // initial left-most pendulum position - btQuaternion orientation(0,0,0,1); // orientation of the pendula + btVector3 position(0.0f, 15.0f, 0.0f); // initial left-most pendulum position + btQuaternion orientation(0, 0, 0, 1); // orientation of the pendula // Re-using the same collision is better for memory usage and performance btSphereShape* pendulumShape = new btSphereShape(gSphereRadius); m_collisionShapes.push_back(pendulumShape); - for (int i = 0; i < floor(gPendulaQty); i++) { - + for (int i = 0; i < floor(gPendulaQty); i++) + { // create pendulum createPendulum(pendulumShape, position, gInitialPendulumLength, pendulumMass); // displace the pendula 1.05 sphere size, so that they all nearly touch (small spacings in between - position.setX(position.x()-2.1f * gSphereRadius); + position.setX(position.x() - 2.1f * gSphereRadius); } } m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } -void NewtonsCradleExample::stepSimulation(float deltaTime) { +void NewtonsCradleExample::stepSimulation(float deltaTime) +{ + applyForceWithForceScalar(gForceScalar); // apply force defined by apply force slider - applyForceWithForceScalar(gForceScalar); // apply force defined by apply force slider - - if (m_dynamicsWorld) { + if (m_dynamicsWorld) + { m_dynamicsWorld->stepSimulation(deltaTime); } } -void NewtonsCradleExample::createPendulum(btSphereShape* colShape, const btVector3& position, btScalar length, btScalar mass) { - +void NewtonsCradleExample::createPendulum(btSphereShape* colShape, const btVector3& position, btScalar length, btScalar mass) +{ // The pendulum looks like this (names when built): // O topSphere // | @@ -193,32 +194,32 @@ void NewtonsCradleExample::createPendulum(btSphereShape* colShape, const btVecto // position the top sphere above ground with a moving x position startTransform.setOrigin(position); - startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation + startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation btRigidBody* topSphere = createRigidBody(mass, startTransform, colShape); // position the bottom sphere below the top sphere startTransform.setOrigin( btVector3(position.x(), btScalar(position.y() - length), - position.z())); + position.z())); - startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation + startTransform.setRotation(btQuaternion(0, 0, 0, 1)); // zero rotation btRigidBody* bottomSphere = createRigidBody(mass, startTransform, colShape); - bottomSphere->setFriction(0); // we do not need friction here + bottomSphere->setFriction(0); // we do not need friction here pendula.push_back(bottomSphere); // disable the deactivation when objects do not move anymore topSphere->setActivationState(DISABLE_DEACTIVATION); bottomSphere->setActivationState(DISABLE_DEACTIVATION); - bottomSphere->setRestitution(gPendulaRestitution); // set pendula restitution + bottomSphere->setRestitution(gPendulaRestitution); // set pendula restitution //make the top sphere position "fixed" to the world by attaching with a point to point constraint // The pivot is defined in the reference frame of topSphere, so the attachment is exactly at the center of the topSphere btVector3 constraintPivot(btVector3(0.0f, 0.0f, 0.0f)); btPoint2PointConstraint* p2pconst = new btPoint2PointConstraint(*topSphere, - constraintPivot); + constraintPivot); - p2pconst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing + p2pconst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing // add the constraint to the world m_dynamicsWorld->addConstraint(p2pconst, true); @@ -234,8 +235,8 @@ void NewtonsCradleExample::createPendulum(btSphereShape* colShape, const btVecto // the slider constraint is x aligned per default, but we want it to be y aligned, therefore we rotate it btQuaternion qt; qt.setEuler(0, 0, -SIMD_HALF_PI); - constraintPivotInTopSphereRF.setRotation(qt); //we use Y like up Axis - constraintPivotInBottomSphereRF.setRotation(qt); //we use Y like up Axis + constraintPivotInTopSphereRF.setRotation(qt); //we use Y like up Axis + constraintPivotInBottomSphereRF.setRotation(qt); //we use Y like up Axis //Obtain the position of topSphere in local reference frame of bottomSphere (the pivot is therefore in the center of topSphere) btVector3 topSphereInBottomSphereRF = @@ -244,9 +245,9 @@ void NewtonsCradleExample::createPendulum(btSphereShape* colShape, const btVecto constraintPivotInBottomSphereRF.setOrigin(topSphereInBottomSphereRF); btSliderConstraint* sliderConst = new btSliderConstraint(*topSphere, - *bottomSphere, constraintPivotInTopSphereRF, constraintPivotInBottomSphereRF, true); + *bottomSphere, constraintPivotInTopSphereRF, constraintPivotInBottomSphereRF, true); - sliderConst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing + sliderConst->setDbgDrawSize(btScalar(5.f)); // set the size of the debug drawing // set limits // the initial setup of the constraint defines the origins of the limit dimensions, @@ -261,76 +262,89 @@ void NewtonsCradleExample::createPendulum(btSphereShape* colShape, const btVecto m_dynamicsWorld->addConstraint(sliderConst, true); } -void NewtonsCradleExample::changePendulaLength(btScalar length) { +void NewtonsCradleExample::changePendulaLength(btScalar length) +{ btScalar lowerLimit = -gInitialPendulumLength; for (std::vector::iterator sit = constraints.begin(); - sit != constraints.end(); sit++) { + sit != constraints.end(); sit++) + { btAssert((*sit) && "Null constraint"); //if the pendulum is being shortened beyond it's own length, we don't let the lower sphere to go past the upper one - if (lowerLimit <= length) { + if (lowerLimit <= length) + { (*sit)->setLowerLinLimit(length + lowerLimit); (*sit)->setUpperLinLimit(length + lowerLimit); } } } -void NewtonsCradleExample::changePendulaRestitution(btScalar restitution) { +void NewtonsCradleExample::changePendulaRestitution(btScalar restitution) +{ for (std::vector::iterator rit = pendula.begin(); - rit != pendula.end(); rit++) { + rit != pendula.end(); rit++) + { btAssert((*rit) && "Null constraint"); (*rit)->setRestitution(restitution); } } -void NewtonsCradleExample::renderScene() { +void NewtonsCradleExample::renderScene() +{ CommonRigidBodyBase::renderScene(); } -bool NewtonsCradleExample::keyboardCallback(int key, int state) { +bool NewtonsCradleExample::keyboardCallback(int key, int state) +{ //b3Printf("Key pressed: %d in state %d \n",key,state); //key 1, key 2, key 3 - switch (key) { - case '1' /*ASCII for 1*/: { + switch (key) + { + case '1' /*ASCII for 1*/: + { + //assumption: Sphere are aligned in Z axis + btScalar newLimit = btScalar(gCurrentPendulumLength + 0.1); - //assumption: Sphere are aligned in Z axis - btScalar newLimit = btScalar(gCurrentPendulumLength + 0.1); - - changePendulaLength(newLimit); - gCurrentPendulumLength = newLimit; - - b3Printf("Increase pendulum length to %f", gCurrentPendulumLength); - return true; - } - case '2' /*ASCII for 2*/: { - - //assumption: Sphere are aligned in Z axis - btScalar newLimit = btScalar(gCurrentPendulumLength - 0.1); - - //is being shortened beyond it's own length, we don't let the lower sphere to go over the upper one - if (0 <= newLimit) { changePendulaLength(newLimit); gCurrentPendulumLength = newLimit; - } - b3Printf("Decrease pendulum length to %f", gCurrentPendulumLength); - return true; - } - case '3' /*ASCII for 3*/: { - applyPendulumForce(gDisplacementForce); - return true; - } + b3Printf("Increase pendulum length to %f", gCurrentPendulumLength); + return true; + } + case '2' /*ASCII for 2*/: + { + //assumption: Sphere are aligned in Z axis + btScalar newLimit = btScalar(gCurrentPendulumLength - 0.1); + + //is being shortened beyond it's own length, we don't let the lower sphere to go over the upper one + if (0 <= newLimit) + { + changePendulaLength(newLimit); + gCurrentPendulumLength = newLimit; + } + + b3Printf("Decrease pendulum length to %f", gCurrentPendulumLength); + return true; + } + case '3' /*ASCII for 3*/: + { + applyPendulumForce(gDisplacementForce); + return true; + } } return false; } -void NewtonsCradleExample::applyPendulumForce(btScalar pendulumForce){ - if(pendulumForce != 0){ - b3Printf("Apply %f to pendulum",pendulumForce); - for (int i = 0; i < gDisplacedPendula; i++) { +void NewtonsCradleExample::applyPendulumForce(btScalar pendulumForce) +{ + if (pendulumForce != 0) + { + b3Printf("Apply %f to pendulum", pendulumForce); + for (int i = 0; i < gDisplacedPendula; i++) + { if (gDisplacedPendula >= 0 && gDisplacedPendula <= gPendulaQty) pendula[i]->applyCentralForce(btVector3(pendulumForce, 0, 0)); } @@ -339,24 +353,30 @@ void NewtonsCradleExample::applyPendulumForce(btScalar pendulumForce){ // GUI parameter modifiers -void onPendulaLengthChanged(float pendulaLength, void*) { - if (nex){ +void onPendulaLengthChanged(float pendulaLength, void*) +{ + if (nex) + { nex->changePendulaLength(pendulaLength); //b3Printf("Pendula length changed to %f \n",sliderValue ); } } -void onPendulaRestitutionChanged(float pendulaRestitution, void*) { - if (nex){ +void onPendulaRestitutionChanged(float pendulaRestitution, void*) +{ + if (nex) + { nex->changePendulaRestitution(pendulaRestitution); } } -void applyForceWithForceScalar(float forceScalar) { - if(nex){ +void applyForceWithForceScalar(float forceScalar) +{ + if (nex) + { btScalar appliedForce = forceScalar * gDisplacementForce; - if(fabs(gForceScalar) < 0.2f) + if (fabs(gForceScalar) < 0.2f) gForceScalar = 0; nex->applyPendulumForce(appliedForce); @@ -364,7 +384,8 @@ void applyForceWithForceScalar(float forceScalar) { } CommonExampleInterface* ET_NewtonsCradleCreateFunc( - CommonExampleOptions& options) { + CommonExampleOptions& options) +{ nex = new NewtonsCradleExample(options.m_guiHelper); return nex; } diff --git a/examples/ExtendedTutorials/NewtonsCradle.h b/examples/ExtendedTutorials/NewtonsCradle.h index 028754f7e..16099834d 100644 --- a/examples/ExtendedTutorials/NewtonsCradle.h +++ b/examples/ExtendedTutorials/NewtonsCradle.h @@ -16,7 +16,6 @@ subject to the following restrictions: #ifndef ET_NEWTONS_CRADLE_EXAMPLE_H #define ET_NEWTONS_CRADLE_EXAMPLE_H -class CommonExampleInterface* ET_NewtonsCradleCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* ET_NewtonsCradleCreateFunc(struct CommonExampleOptions& options); - -#endif //ET_NEWTONS_CRADLE_EXAMPLE_H +#endif //ET_NEWTONS_CRADLE_EXAMPLE_H diff --git a/examples/ExtendedTutorials/NewtonsRopeCradle.cpp b/examples/ExtendedTutorials/NewtonsRopeCradle.cpp index 8786ebed7..7a7c74eaa 100644 --- a/examples/ExtendedTutorials/NewtonsRopeCradle.cpp +++ b/examples/ExtendedTutorials/NewtonsRopeCradle.cpp @@ -15,12 +15,12 @@ #include "NewtonsRopeCradle.h" -#include // TODO: Should I use another data structure? +#include // TODO: Should I use another data structure? #include #include "btBulletDynamicsCommon.h" #include "LinearMath/btVector3.h" -#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAlignedObjectArray.h" #include "../CommonInterfaces/CommonRigidBodyBase.h" #include "BulletSoftBody/btSoftRigidDynamicsWorld.h" @@ -28,31 +28,32 @@ #include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h" #include "../CommonInterfaces/CommonParameterInterface.h" -static btScalar gPendulaQty = 5; // Number of pendula in newton's cradle +static btScalar gPendulaQty = 5; // Number of pendula in newton's cradle //TODO: This would actually be an Integer, but the Slider does not like integers, so I floor it when changed -static btScalar gDisplacedPendula = 1; // number of displaced pendula +static btScalar gDisplacedPendula = 1; // number of displaced pendula //TODO: This is an int as well -static btScalar gPendulaRestitution = 1; // pendula restition when hitting against each other +static btScalar gPendulaRestitution = 1; // pendula restition when hitting against each other -static btScalar gSphereRadius = 1; // pendula radius +static btScalar gSphereRadius = 1; // pendula radius -static btScalar gInitialPendulumWidth = 4; // default pendula width +static btScalar gInitialPendulumWidth = 4; // default pendula width -static btScalar gInitialPendulumHeight = 8; // default pendula height +static btScalar gInitialPendulumHeight = 8; // default pendula height -static btScalar gRopeResolution = 1; // default rope resolution (number of links as in a chain) +static btScalar gRopeResolution = 1; // default rope resolution (number of links as in a chain) -static btScalar gDisplacementForce = 30; // default force to displace the pendula +static btScalar gDisplacementForce = 30; // default force to displace the pendula -static btScalar gForceScalar = 0; // default force scalar to apply a displacement +static btScalar gForceScalar = 0; // default force scalar to apply a displacement -struct NewtonsRopeCradleExample : public CommonRigidBodyBase { - NewtonsRopeCradleExample(struct GUIHelperInterface* helper) : - CommonRigidBodyBase(helper) { +struct NewtonsRopeCradleExample : public CommonRigidBodyBase +{ + NewtonsRopeCradleExample(struct GUIHelperInterface* helper) : CommonRigidBodyBase(helper) + { } - virtual ~NewtonsRopeCradleExample(){} + virtual ~NewtonsRopeCradleExample() {} virtual void initPhysics(); virtual void stepSimulation(float deltaTime); virtual void renderScene(); @@ -60,7 +61,7 @@ struct NewtonsRopeCradleExample : public CommonRigidBodyBase { void createEmptyDynamicsWorld() { m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration(); - m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_broadphase = new btDbvtBroadphase(); @@ -76,31 +77,30 @@ struct NewtonsRopeCradleExample : public CommonRigidBodyBase { } virtual void createRopePendulum(btSphereShape* colShape, - const btVector3& position, const btQuaternion& pendulumOrientation, btScalar width, btScalar height, btScalar mass); + const btVector3& position, const btQuaternion& pendulumOrientation, btScalar width, btScalar height, btScalar mass); virtual void changePendulaRestitution(btScalar restitution); virtual void connectWithRope(btRigidBody* body1, btRigidBody* body2); virtual bool keyboardCallback(int key, int state); - virtual btSoftRigidDynamicsWorld* getSoftDynamicsWorld() + virtual btSoftRigidDynamicsWorld* getSoftDynamicsWorld() { ///just make it a btSoftRigidDynamicsWorld please ///or we will add type checking - return (btSoftRigidDynamicsWorld*) m_dynamicsWorld; + return (btSoftRigidDynamicsWorld*)m_dynamicsWorld; } void resetCamera() { float dist = 41; float pitch = -35; float yaw = 52; - float targetPos[3]={0,0.46,0}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {0, 0.46, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } std::vector constraints; std::vector pendula; - - btSoftBodyWorldInfo softBodyWorldInfo; + btSoftBodyWorldInfo softBodyWorldInfo; }; static NewtonsRopeCradleExample* nex = NULL; @@ -111,26 +111,25 @@ void applyRForceWithForceScalar(float forceScalar); void NewtonsRopeCradleExample::initPhysics() { - - { // create a slider to change the number of pendula + { // create a slider to change the number of pendula SliderParams slider("Number of Pendula", &gPendulaQty); slider.m_minVal = 1; slider.m_maxVal = 50; - slider.m_clampToIntegers = true; + slider.m_clampToIntegers = true; m_guiHelper->getParameterInterface()->registerSliderFloatParameter( slider); } - { // create a slider to change the number of displaced pendula + { // create a slider to change the number of displaced pendula SliderParams slider("Number of Displaced Pendula", &gDisplacedPendula); slider.m_minVal = 0; slider.m_maxVal = 49; - slider.m_clampToIntegers = true; + slider.m_clampToIntegers = true; m_guiHelper->getParameterInterface()->registerSliderFloatParameter( slider); } - { // create a slider to change the pendula restitution + { // create a slider to change the pendula restitution SliderParams slider("Pendula Restitution", &gPendulaRestitution); slider.m_minVal = 0; slider.m_maxVal = 1; @@ -140,16 +139,16 @@ void NewtonsRopeCradleExample::initPhysics() slider); } - { // create a slider to change the rope resolution + { // create a slider to change the rope resolution SliderParams slider("Rope Resolution", &gRopeResolution); slider.m_minVal = 1; slider.m_maxVal = 20; - slider.m_clampToIntegers = true; + slider.m_clampToIntegers = true; m_guiHelper->getParameterInterface()->registerSliderFloatParameter( slider); } - { // create a slider to change the pendulum width + { // create a slider to change the pendulum width SliderParams slider("Pendulum Width", &gInitialPendulumWidth); slider.m_minVal = 0; slider.m_maxVal = 40; @@ -158,7 +157,7 @@ void NewtonsRopeCradleExample::initPhysics() slider); } - { // create a slider to change the pendulum height + { // create a slider to change the pendulum height SliderParams slider("Pendulum Height", &gInitialPendulumHeight); slider.m_minVal = 0; slider.m_maxVal = 40; @@ -167,7 +166,7 @@ void NewtonsRopeCradleExample::initPhysics() slider); } - { // create a slider to change the force to displace the lowest pendulum + { // create a slider to change the force to displace the lowest pendulum SliderParams slider("Displacement force", &gDisplacementForce); slider.m_minVal = 0.1; slider.m_maxVal = 200; @@ -175,8 +174,8 @@ void NewtonsRopeCradleExample::initPhysics() m_guiHelper->getParameterInterface()->registerSliderFloatParameter( slider); } - - { // create a slider to apply the force by slider + + { // create a slider to apply the force by slider SliderParams slider("Apply displacement force", &gForceScalar); slider.m_minVal = -1; slider.m_maxVal = 1; @@ -193,29 +192,26 @@ void NewtonsRopeCradleExample::initPhysics() m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); if (m_dynamicsWorld->getDebugDrawer()) m_dynamicsWorld->getDebugDrawer()->setDebugMode( - btIDebugDraw::DBG_DrawWireframe - + btIDebugDraw::DBG_DrawContactPoints - + btIDebugDraw::DBG_DrawConstraints - + btIDebugDraw::DBG_DrawConstraintLimits); + btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints + btIDebugDraw::DBG_DrawConstraints + btIDebugDraw::DBG_DrawConstraintLimits); - { // create the pendula starting at the indicated position below and where each pendulum has the following mass + { // create the pendula starting at the indicated position below and where each pendulum has the following mass btScalar pendulumMass(1.0f); - btVector3 position(0.0f,15.0f,0.0f); // initial left-most pendulum position - btQuaternion orientation(0,0,0,1); // orientation of the pendula + btVector3 position(0.0f, 15.0f, 0.0f); // initial left-most pendulum position + btQuaternion orientation(0, 0, 0, 1); // orientation of the pendula // Re-using the same collision is better for memory usage and performance btSphereShape* pendulumShape = new btSphereShape(gSphereRadius); m_collisionShapes.push_back(pendulumShape); - for (int i = 0; i < floor(gPendulaQty); i++) { - + for (int i = 0; i < floor(gPendulaQty); i++) + { // create pendulum - createRopePendulum(pendulumShape, position, orientation,gInitialPendulumWidth, - gInitialPendulumHeight, pendulumMass); + createRopePendulum(pendulumShape, position, orientation, gInitialPendulumWidth, + gInitialPendulumHeight, pendulumMass); // displace the pendula 1.05 sphere size, so that they all nearly touch (small spacings in between) - position.setX(position.x()-2.1f * gSphereRadius); + position.setX(position.x() - 2.1f * gSphereRadius); } } @@ -224,11 +220,11 @@ void NewtonsRopeCradleExample::initPhysics() void NewtonsRopeCradleExample::connectWithRope(btRigidBody* body1, btRigidBody* body2) { - btSoftBody* softBodyRope0 = btSoftBodyHelpers::CreateRope(softBodyWorldInfo,body1->getWorldTransform().getOrigin(),body2->getWorldTransform().getOrigin(),gRopeResolution,0); + btSoftBody* softBodyRope0 = btSoftBodyHelpers::CreateRope(softBodyWorldInfo, body1->getWorldTransform().getOrigin(), body2->getWorldTransform().getOrigin(), gRopeResolution, 0); softBodyRope0->setTotalMass(0.1f); - softBodyRope0->appendAnchor(0,body1); - softBodyRope0->appendAnchor(softBodyRope0->m_nodes.size()-1,body2); + softBodyRope0->appendAnchor(0, body1); + softBodyRope0->appendAnchor(softBodyRope0->m_nodes.size() - 1, body2); softBodyRope0->m_cfg.piterations = 5; softBodyRope0->m_cfg.kDP = 0.005f; @@ -239,18 +235,19 @@ void NewtonsRopeCradleExample::connectWithRope(btRigidBody* body1, btRigidBody* getSoftDynamicsWorld()->addSoftBody(softBodyRope0); } -void NewtonsRopeCradleExample::stepSimulation(float deltaTime) { +void NewtonsRopeCradleExample::stepSimulation(float deltaTime) +{ + applyRForceWithForceScalar(gForceScalar); // apply force defined by apply force slider - applyRForceWithForceScalar(gForceScalar); // apply force defined by apply force slider - - if (m_dynamicsWorld) { + if (m_dynamicsWorld) + { m_dynamicsWorld->stepSimulation(deltaTime); } } void NewtonsRopeCradleExample::createRopePendulum(btSphereShape* colShape, - const btVector3& position, const btQuaternion& pendulumOrientation, btScalar width, btScalar height, btScalar mass) { - + const btVector3& position, const btQuaternion& pendulumOrientation, btScalar width, btScalar height, btScalar mass) +{ // The pendulum looks like this (names when built): // O O topSphere1 topSphere2 // \ / @@ -261,32 +258,31 @@ void NewtonsRopeCradleExample::createRopePendulum(btSphereShape* colShape, startTransform.setIdentity(); // calculate sphere positions - btVector3 topSphere1RelPosition(0,0,width); - btVector3 topSphere2RelPosition(0,0,-width); - btVector3 bottomSphereRelPosition(0,-height,0); - + btVector3 topSphere1RelPosition(0, 0, width); + btVector3 topSphere2RelPosition(0, 0, -width); + btVector3 bottomSphereRelPosition(0, -height, 0); // position the top sphere above ground with appropriate orientation - startTransform.setOrigin(btVector3(0,0,0)); // no translation intitially - startTransform.setRotation(pendulumOrientation); // pendulum rotation - startTransform.setOrigin(startTransform * topSphere1RelPosition); // rotate this position - startTransform.setOrigin(position + startTransform.getOrigin()); // add non-rotated position to the relative position - btRigidBody* topSphere1 = createRigidBody(0, startTransform, colShape); // make top sphere static + startTransform.setOrigin(btVector3(0, 0, 0)); // no translation intitially + startTransform.setRotation(pendulumOrientation); // pendulum rotation + startTransform.setOrigin(startTransform * topSphere1RelPosition); // rotate this position + startTransform.setOrigin(position + startTransform.getOrigin()); // add non-rotated position to the relative position + btRigidBody* topSphere1 = createRigidBody(0, startTransform, colShape); // make top sphere static // position the top sphere above ground with appropriate orientation - startTransform.setOrigin(btVector3(0,0,0)); // no translation intitially - startTransform.setRotation(pendulumOrientation); // pendulum rotation - startTransform.setOrigin(startTransform * topSphere2RelPosition); // rotate this position - startTransform.setOrigin(position + startTransform.getOrigin()); // add non-rotated position to the relative position - btRigidBody* topSphere2 = createRigidBody(0, startTransform, colShape); // make top sphere static + startTransform.setOrigin(btVector3(0, 0, 0)); // no translation intitially + startTransform.setRotation(pendulumOrientation); // pendulum rotation + startTransform.setOrigin(startTransform * topSphere2RelPosition); // rotate this position + startTransform.setOrigin(position + startTransform.getOrigin()); // add non-rotated position to the relative position + btRigidBody* topSphere2 = createRigidBody(0, startTransform, colShape); // make top sphere static // position the bottom sphere below the top sphere - startTransform.setOrigin(btVector3(0,0,0)); // no translation intitially - startTransform.setRotation(pendulumOrientation); // pendulum rotation - startTransform.setOrigin(startTransform * bottomSphereRelPosition); // rotate this position - startTransform.setOrigin(position + startTransform.getOrigin()); // add non-rotated position to the relative position + startTransform.setOrigin(btVector3(0, 0, 0)); // no translation intitially + startTransform.setRotation(pendulumOrientation); // pendulum rotation + startTransform.setOrigin(startTransform * bottomSphereRelPosition); // rotate this position + startTransform.setOrigin(position + startTransform.getOrigin()); // add non-rotated position to the relative position btRigidBody* bottomSphere = createRigidBody(mass, startTransform, colShape); - bottomSphere->setFriction(0); // we do not need friction here + bottomSphere->setFriction(0); // we do not need friction here pendula.push_back(bottomSphere); // disable the deactivation when objects do not move anymore @@ -294,7 +290,7 @@ void NewtonsRopeCradleExample::createRopePendulum(btSphereShape* colShape, topSphere2->setActivationState(DISABLE_DEACTIVATION); bottomSphere->setActivationState(DISABLE_DEACTIVATION); - bottomSphere->setRestitution(gPendulaRestitution); // set pendula restitution + bottomSphere->setRestitution(gPendulaRestitution); // set pendula restitution // add ropes between spheres connectWithRope(topSphere1, bottomSphere); @@ -306,44 +302,52 @@ void NewtonsRopeCradleExample::renderScene() CommonRigidBodyBase::renderScene(); btSoftRigidDynamicsWorld* softWorld = getSoftDynamicsWorld(); - for ( int i=0;igetSoftBodyArray().size();i++) + for (int i = 0; i < softWorld->getSoftBodyArray().size(); i++) + { + btSoftBody* psb = (btSoftBody*)softWorld->getSoftBodyArray()[i]; + //if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe))) { - btSoftBody* psb=(btSoftBody*)softWorld->getSoftBodyArray()[i]; - //if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe))) - { - btSoftBodyHelpers::DrawFrame(psb,softWorld->getDebugDrawer()); - btSoftBodyHelpers::Draw(psb,softWorld->getDebugDrawer(),softWorld->getDrawFlags()); - } + btSoftBodyHelpers::DrawFrame(psb, softWorld->getDebugDrawer()); + btSoftBodyHelpers::Draw(psb, softWorld->getDebugDrawer(), softWorld->getDrawFlags()); } + } } -void NewtonsRopeCradleExample::changePendulaRestitution(btScalar restitution) { +void NewtonsRopeCradleExample::changePendulaRestitution(btScalar restitution) +{ for (std::vector::iterator rit = pendula.begin(); - rit != pendula.end(); rit++) { + rit != pendula.end(); rit++) + { btAssert((*rit) && "Null constraint"); (*rit)->setRestitution(restitution); } } -bool NewtonsRopeCradleExample::keyboardCallback(int key, int state) { +bool NewtonsRopeCradleExample::keyboardCallback(int key, int state) +{ //b3Printf("Key pressed: %d in state %d \n",key,state); // key 3 - switch (key) { - case '3' /*ASCII for 3*/: { - applyPendulumForce(gDisplacementForce); - return true; - } + switch (key) + { + case '3' /*ASCII for 3*/: + { + applyPendulumForce(gDisplacementForce); + return true; + } } return false; } -void NewtonsRopeCradleExample::applyPendulumForce(btScalar pendulumForce){ - if(pendulumForce != 0){ - b3Printf("Apply %f to pendulum",pendulumForce); - for (int i = 0; i < gDisplacedPendula; i++) { +void NewtonsRopeCradleExample::applyPendulumForce(btScalar pendulumForce) +{ + if (pendulumForce != 0) + { + b3Printf("Apply %f to pendulum", pendulumForce); + for (int i = 0; i < gDisplacedPendula; i++) + { if (gDisplacedPendula >= 0 && gDisplacedPendula <= gPendulaQty) pendula[i]->applyCentralForce(btVector3(pendulumForce, 0, 0)); } @@ -352,17 +356,21 @@ void NewtonsRopeCradleExample::applyPendulumForce(btScalar pendulumForce){ // GUI parameter modifiers -void onRopePendulaRestitutionChanged(float pendulaRestitution, void*) { - if (nex){ +void onRopePendulaRestitutionChanged(float pendulaRestitution, void*) +{ + if (nex) + { nex->changePendulaRestitution(pendulaRestitution); } } -void applyRForceWithForceScalar(float forceScalar) { - if(nex){ +void applyRForceWithForceScalar(float forceScalar) +{ + if (nex) + { btScalar appliedForce = forceScalar * gDisplacementForce; - if(fabs(gForceScalar) < 0.2f) + if (fabs(gForceScalar) < 0.2f) gForceScalar = 0; nex->applyPendulumForce(appliedForce); @@ -370,7 +378,8 @@ void applyRForceWithForceScalar(float forceScalar) { } CommonExampleInterface* ET_NewtonsRopeCradleCreateFunc( - CommonExampleOptions& options) { + CommonExampleOptions& options) +{ nex = new NewtonsRopeCradleExample(options.m_guiHelper); return nex; } diff --git a/examples/ExtendedTutorials/NewtonsRopeCradle.h b/examples/ExtendedTutorials/NewtonsRopeCradle.h index 3edbcd5af..d2907db70 100644 --- a/examples/ExtendedTutorials/NewtonsRopeCradle.h +++ b/examples/ExtendedTutorials/NewtonsRopeCradle.h @@ -16,7 +16,6 @@ subject to the following restrictions: #ifndef ET_NEWTONS_ROPE_CRADLE_EXAMPLE_H #define ET_NEWTONS_ROPE_CRADLE_EXAMPLE_H -class CommonExampleInterface* ET_NewtonsRopeCradleCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* ET_NewtonsRopeCradleCreateFunc(struct CommonExampleOptions& options); - -#endif //ET_NEWTONS_ROPE_CRADLE_EXAMPLE_H +#endif //ET_NEWTONS_ROPE_CRADLE_EXAMPLE_H diff --git a/examples/ExtendedTutorials/RigidBodyFromObj.cpp b/examples/ExtendedTutorials/RigidBodyFromObj.cpp index 7d2a59b91..f0c6699ef 100644 --- a/examples/ExtendedTutorials/RigidBodyFromObj.cpp +++ b/examples/ExtendedTutorials/RigidBodyFromObj.cpp @@ -13,13 +13,11 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "RigidBodyFromObj.h" #include "btBulletDynamicsCommon.h" #include "LinearMath/btVector3.h" -#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAlignedObjectArray.h" #include "../CommonInterfaces/CommonRigidBodyBase.h" #include "../Utils/b3ResourcePath.h" @@ -27,17 +25,16 @@ subject to the following restrictions: #include "../Importers/ImportObjDemo/LoadMeshFromObj.h" #include "../OpenGLWindow/GLInstanceGraphicsShape.h" - struct RigidBodyFromObjExample : public CommonRigidBodyBase { - int m_options; - + int m_options; + RigidBodyFromObjExample(struct GUIHelperInterface* helper, int options) - :CommonRigidBodyBase(helper), - m_options(options) + : CommonRigidBodyBase(helper), + m_options(options) { } - virtual ~RigidBodyFromObjExample(){} + virtual ~RigidBodyFromObjExample() {} virtual void initPhysics(); virtual void renderScene(); void resetCamera() @@ -45,8 +42,8 @@ struct RigidBodyFromObjExample : public CommonRigidBodyBase float dist = 11; float pitch = -35; float yaw = 52; - float targetPos[3]={0,0.46,0}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {0, 0.46, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } }; @@ -55,111 +52,98 @@ void RigidBodyFromObjExample::initPhysics() m_guiHelper->setUpAxis(1); createEmptyDynamicsWorld(); - + m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); //if (m_dynamicsWorld->getDebugDrawer()) // m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints); ///create a few basic rigid bodies - btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); + btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.))); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0,-50,0)); + groundTransform.setOrigin(btVector3(0, -50, 0)); { btScalar mass(0.); - createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1)); + createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1)); } //load our obj mesh - const char* fileName = "teddy.obj";//sphere8.obj";//sponza_closed.obj";//sphere8.obj"; - char relativeFileName[1024]; - if (b3ResourcePath::findResourcePath(fileName, relativeFileName, 1024)) - { + const char* fileName = "teddy.obj"; //sphere8.obj";//sponza_closed.obj";//sphere8.obj"; + char relativeFileName[1024]; + if (b3ResourcePath::findResourcePath(fileName, relativeFileName, 1024)) + { char pathPrefix[1024]; b3FileUtils::extractPath(relativeFileName, pathPrefix, 1024); } - + GLInstanceGraphicsShape* glmesh = LoadMeshFromObj(relativeFileName, ""); printf("[INFO] Obj loaded: Extracted %d verticed from obj file [%s]\n", glmesh->m_numvertices, fileName); const GLInstanceVertex& v = glmesh->m_vertices->at(0); btConvexHullShape* shape = new btConvexHullShape((const btScalar*)(&(v.xyzw[0])), glmesh->m_numvertices, sizeof(GLInstanceVertex)); - float scaling[4] = {0.1,0.1,0.1,1}; - - btVector3 localScaling(scaling[0],scaling[1],scaling[2]); - shape->setLocalScaling(localScaling); - - if (m_options & OptimizeConvexObj) - { - shape->optimizeConvexHull(); - } + float scaling[4] = {0.1, 0.1, 0.1, 1}; + + btVector3 localScaling(scaling[0], scaling[1], scaling[2]); + shape->setLocalScaling(localScaling); + + if (m_options & OptimizeConvexObj) + { + shape->optimizeConvexHull(); + } + + if (m_options & ComputePolyhedralFeatures) + { + shape->initializePolyhedralFeatures(); + } - if (m_options & ComputePolyhedralFeatures) - { - shape->initializePolyhedralFeatures(); - } - - - //shape->setMargin(0.001); m_collisionShapes.push_back(shape); btTransform startTransform; startTransform.setIdentity(); - btScalar mass(1.f); + btScalar mass(1.f); bool isDynamic = (mass != 0.f); - btVector3 localInertia(0,0,0); + btVector3 localInertia(0, 0, 0); if (isDynamic) - shape->calculateLocalInertia(mass,localInertia); + shape->calculateLocalInertia(mass, localInertia); - float color[4] = {1,1,1,1}; - float orn[4] = {0,0,0,1}; - float pos[4] = {0,3,0,0}; - btVector3 position(pos[0],pos[1],pos[2]); + float color[4] = {1, 1, 1, 1}; + float orn[4] = {0, 0, 0, 1}; + float pos[4] = {0, 3, 0, 0}; + btVector3 position(pos[0], pos[1], pos[2]); startTransform.setOrigin(position); - btRigidBody* body = createRigidBody(mass,startTransform,shape); + btRigidBody* body = createRigidBody(mass, startTransform, shape); + bool useConvexHullForRendering = ((m_options & ObjUseConvexHullForRendering) != 0); - - bool useConvexHullForRendering = ((m_options & ObjUseConvexHullForRendering)!=0); - - if (!useConvexHullForRendering) - { - int shapeId = m_guiHelper->registerGraphicsShape(&glmesh->m_vertices->at(0).xyzw[0], - glmesh->m_numvertices, - &glmesh->m_indices->at(0), - glmesh->m_numIndices, - B3_GL_TRIANGLES, -1); + { + int shapeId = m_guiHelper->registerGraphicsShape(&glmesh->m_vertices->at(0).xyzw[0], + glmesh->m_numvertices, + &glmesh->m_indices->at(0), + glmesh->m_numIndices, + B3_GL_TRIANGLES, -1); shape->setUserIndex(shapeId); - int renderInstance = m_guiHelper->registerGraphicsInstance(shapeId,pos,orn,color,scaling); + int renderInstance = m_guiHelper->registerGraphicsInstance(shapeId, pos, orn, color, scaling); body->setUserIndex(renderInstance); - } - + } + m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } - void RigidBodyFromObjExample::renderScene() { - CommonRigidBodyBase::renderScene(); + CommonRigidBodyBase::renderScene(); } - - - - - - -CommonExampleInterface* ET_RigidBodyFromObjCreateFunc(CommonExampleOptions& options) +CommonExampleInterface* ET_RigidBodyFromObjCreateFunc(CommonExampleOptions& options) { - return new RigidBodyFromObjExample(options.m_guiHelper,options.m_option); + return new RigidBodyFromObjExample(options.m_guiHelper, options.m_option); } B3_STANDALONE_EXAMPLE(ET_RigidBodyFromObjCreateFunc) - diff --git a/examples/ExtendedTutorials/RigidBodyFromObj.h b/examples/ExtendedTutorials/RigidBodyFromObj.h index 829e9e14a..cd133a339 100644 --- a/examples/ExtendedTutorials/RigidBodyFromObj.h +++ b/examples/ExtendedTutorials/RigidBodyFromObj.h @@ -18,11 +18,10 @@ subject to the following restrictions: enum ObjToRigidBodyOptionsEnum { - ObjUseConvexHullForRendering=1, - OptimizeConvexObj=2, - ComputePolyhedralFeatures=4, + ObjUseConvexHullForRendering = 1, + OptimizeConvexObj = 2, + ComputePolyhedralFeatures = 4, }; -class CommonExampleInterface* ET_RigidBodyFromObjCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* ET_RigidBodyFromObjCreateFunc(struct CommonExampleOptions& options); - -#endif //ET_RIGIDBODYFROMOBJ_EXAMPLE_H +#endif //ET_RIGIDBODYFROMOBJ_EXAMPLE_H diff --git a/examples/ExtendedTutorials/SimpleBox.cpp b/examples/ExtendedTutorials/SimpleBox.cpp index 49e252739..e2e5bee46 100644 --- a/examples/ExtendedTutorials/SimpleBox.cpp +++ b/examples/ExtendedTutorials/SimpleBox.cpp @@ -13,23 +13,20 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "SimpleBox.h" #include "btBulletDynamicsCommon.h" #include "LinearMath/btVector3.h" -#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAlignedObjectArray.h" #include "../CommonInterfaces/CommonRigidBodyBase.h" - struct SimpleBoxExample : public CommonRigidBodyBase { SimpleBoxExample(struct GUIHelperInterface* helper) - :CommonRigidBodyBase(helper) + : CommonRigidBodyBase(helper) { } - virtual ~SimpleBoxExample(){} + virtual ~SimpleBoxExample() {} virtual void initPhysics(); virtual void renderScene(); void resetCamera() @@ -37,8 +34,8 @@ struct SimpleBoxExample : public CommonRigidBodyBase float dist = 41; float pitch = -35; float yaw = 52; - float targetPos[3]={0,0.46,0}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {0, 0.46, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } }; @@ -47,72 +44,60 @@ void SimpleBoxExample::initPhysics() m_guiHelper->setUpAxis(1); createEmptyDynamicsWorld(); - + m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); if (m_dynamicsWorld->getDebugDrawer()) - m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints); + m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints); ///create a few basic rigid bodies - btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); + btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.))); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0,-50,0)); + groundTransform.setOrigin(btVector3(0, -50, 0)); { btScalar mass(0.); - createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1)); + createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1)); } - { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance - btBoxShape* colShape = createBoxShape(btVector3(1,1,1)); - + btBoxShape* colShape = createBoxShape(btVector3(1, 1, 1)); + m_collisionShapes.push_back(colShape); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); - btScalar mass(1.f); + btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); - btVector3 localInertia(0,0,0); + btVector3 localInertia(0, 0, 0); if (isDynamic) - colShape->calculateLocalInertia(mass,localInertia); - + colShape->calculateLocalInertia(mass, localInertia); startTransform.setOrigin(btVector3( - btScalar(0), - btScalar(20), - btScalar(0))); - createRigidBody(mass,startTransform,colShape); + btScalar(0), + btScalar(20), + btScalar(0))); + createRigidBody(mass, startTransform, colShape); } m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } - void SimpleBoxExample::renderScene() { - CommonRigidBodyBase::renderScene(); + CommonRigidBodyBase::renderScene(); } - - - - - - -CommonExampleInterface* ET_SimpleBoxCreateFunc(CommonExampleOptions& options) +CommonExampleInterface* ET_SimpleBoxCreateFunc(CommonExampleOptions& options) { return new SimpleBoxExample(options.m_guiHelper); } - - - diff --git a/examples/ExtendedTutorials/SimpleBox.h b/examples/ExtendedTutorials/SimpleBox.h index 494b3fd03..03c2e637d 100644 --- a/examples/ExtendedTutorials/SimpleBox.h +++ b/examples/ExtendedTutorials/SimpleBox.h @@ -16,7 +16,6 @@ subject to the following restrictions: #ifndef ET_SIMPLE_BOX_EXAMPLE_H #define ET_SIMPLE_BOX_EXAMPLE_H -class CommonExampleInterface* ET_SimpleBoxCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* ET_SimpleBoxCreateFunc(struct CommonExampleOptions& options); - -#endif //ET_SIMPLE_BOX_EXAMPLE_H +#endif //ET_SIMPLE_BOX_EXAMPLE_H diff --git a/examples/ExtendedTutorials/SimpleCloth.cpp b/examples/ExtendedTutorials/SimpleCloth.cpp index 0d62a2dc2..f5064d10f 100644 --- a/examples/ExtendedTutorials/SimpleCloth.cpp +++ b/examples/ExtendedTutorials/SimpleCloth.cpp @@ -13,13 +13,11 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "SimpleCloth.h" #include "btBulletDynamicsCommon.h" #include "LinearMath/btVector3.h" -#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAlignedObjectArray.h" #include "../CommonInterfaces/CommonRigidBodyBase.h" #include "BulletSoftBody/btSoftRigidDynamicsWorld.h" @@ -29,21 +27,21 @@ subject to the following restrictions: struct SimpleClothExample : public CommonRigidBodyBase { SimpleClothExample(struct GUIHelperInterface* helper) - :CommonRigidBodyBase(helper) + : CommonRigidBodyBase(helper) { } - virtual ~SimpleClothExample(){} + virtual ~SimpleClothExample() {} virtual void initPhysics(); virtual void renderScene(); void createEmptyDynamicsWorld() { - m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration(); - m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); - + m_collisionConfiguration = new btSoftBodyRigidBodyCollisionConfiguration(); + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + m_broadphase = new btDbvtBroadphase(); - - m_solver = new btSequentialImpulseConstraintSolver; - + + m_solver = new btSequentialImpulseConstraintSolver; + m_dynamicsWorld = new btSoftRigidDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration); m_dynamicsWorld->setGravity(btVector3(0, -10, 0)); @@ -52,22 +50,22 @@ struct SimpleClothExample : public CommonRigidBodyBase softBodyWorldInfo.m_gravity = m_dynamicsWorld->getGravity(); softBodyWorldInfo.m_sparsesdf.Initialize(); } - virtual btSoftRigidDynamicsWorld* getSoftDynamicsWorld() + virtual btSoftRigidDynamicsWorld* getSoftDynamicsWorld() { ///just make it a btSoftRigidDynamicsWorld please ///or we will add type checking - return (btSoftRigidDynamicsWorld*) m_dynamicsWorld; + return (btSoftRigidDynamicsWorld*)m_dynamicsWorld; } void resetCamera() { float dist = 41; float pitch = -35; float yaw = 52; - float targetPos[3]={0,0.46,0}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {0, 0.46, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } - void createSoftBody(const btScalar size, const int num_x, const int num_z, const int fixed=1+2); + void createSoftBody(const btScalar size, const int num_x, const int num_z, const int fixed = 1 + 2); btSoftBodyWorldInfo softBodyWorldInfo; }; @@ -76,30 +74,29 @@ void SimpleClothExample::initPhysics() m_guiHelper->setUpAxis(1); createEmptyDynamicsWorld(); - + m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); if (m_dynamicsWorld->getDebugDrawer()) - m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints); + m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints); ///create a few basic rigid bodies - btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); + btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.))); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0,-50,0)); + groundTransform.setOrigin(btVector3(0, -50, 0)); { btScalar mass(0.); - createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1)); + createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1)); } - { - const btScalar s=4; //size of cloth patch - const int NUM_X=31; //vertices on X axis - const int NUM_Z=31; //vertices on Z axis - createSoftBody(s,NUM_X, NUM_Z); + const btScalar s = 4; //size of cloth patch + const int NUM_X = 31; //vertices on X axis + const int NUM_Z = 31; //vertices on Z axis + createSoftBody(s, NUM_X, NUM_Z); } m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); @@ -107,57 +104,45 @@ void SimpleClothExample::initPhysics() void SimpleClothExample::createSoftBody(const btScalar s, const int numX, - const int numY, - const int fixed) { - - - - btSoftBody* cloth=btSoftBodyHelpers::CreatePatch(softBodyWorldInfo, - btVector3(-s/2,s+1,0), - btVector3(+s/2,s+1,0), - btVector3(-s/2,s+1,+s), - btVector3(+s/2,s+1,+s), - numX,numY, - fixed,true); - + const int numY, + const int fixed) +{ + btSoftBody* cloth = btSoftBodyHelpers::CreatePatch(softBodyWorldInfo, + btVector3(-s / 2, s + 1, 0), + btVector3(+s / 2, s + 1, 0), + btVector3(-s / 2, s + 1, +s), + btVector3(+s / 2, s + 1, +s), + numX, numY, + fixed, true); + cloth->getCollisionShape()->setMargin(0.001f); - cloth->getCollisionShape()->setUserPointer((void*)cloth); - cloth->generateBendingConstraints(2,cloth->appendMaterial()); - cloth->setTotalMass(10); + cloth->getCollisionShape()->setUserPointer((void*)cloth); + cloth->generateBendingConstraints(2, cloth->appendMaterial()); + cloth->setTotalMass(10); //cloth->m_cfg.citerations = 10; -// cloth->m_cfg.diterations = 10; + // cloth->m_cfg.diterations = 10; cloth->m_cfg.piterations = 5; cloth->m_cfg.kDP = 0.005f; getSoftDynamicsWorld()->addSoftBody(cloth); - } void SimpleClothExample::renderScene() { - CommonRigidBodyBase::renderScene(); + CommonRigidBodyBase::renderScene(); btSoftRigidDynamicsWorld* softWorld = getSoftDynamicsWorld(); - for ( int i=0;igetSoftBodyArray().size();i++) + for (int i = 0; i < softWorld->getSoftBodyArray().size(); i++) + { + btSoftBody* psb = (btSoftBody*)softWorld->getSoftBodyArray()[i]; + //if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe))) { - btSoftBody* psb=(btSoftBody*)softWorld->getSoftBodyArray()[i]; - //if (softWorld->getDebugDrawer() && !(softWorld->getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe))) - { - btSoftBodyHelpers::DrawFrame(psb,softWorld->getDebugDrawer()); - btSoftBodyHelpers::Draw(psb,softWorld->getDebugDrawer(),softWorld->getDrawFlags()); - } + btSoftBodyHelpers::DrawFrame(psb, softWorld->getDebugDrawer()); + btSoftBodyHelpers::Draw(psb, softWorld->getDebugDrawer(), softWorld->getDrawFlags()); } + } } - - - - - - -CommonExampleInterface* ET_SimpleClothCreateFunc(CommonExampleOptions& options) +CommonExampleInterface* ET_SimpleClothCreateFunc(CommonExampleOptions& options) { return new SimpleClothExample(options.m_guiHelper); } - - - diff --git a/examples/ExtendedTutorials/SimpleCloth.h b/examples/ExtendedTutorials/SimpleCloth.h index d956833e9..d8269b01c 100644 --- a/examples/ExtendedTutorials/SimpleCloth.h +++ b/examples/ExtendedTutorials/SimpleCloth.h @@ -16,7 +16,6 @@ subject to the following restrictions: #ifndef ET_SIMPLE_CLOTH_EXAMPLE_H #define ET_SIMPLE_CLOTH_EXAMPLE_H -class CommonExampleInterface* ET_SimpleClothCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* ET_SimpleClothCreateFunc(struct CommonExampleOptions& options); - -#endif //ET_SIMPLE_CLOTH_EXAMPLE_H +#endif //ET_SIMPLE_CLOTH_EXAMPLE_H diff --git a/examples/ExtendedTutorials/SimpleJoint.cpp b/examples/ExtendedTutorials/SimpleJoint.cpp index 1a76f20ec..ee438cce3 100644 --- a/examples/ExtendedTutorials/SimpleJoint.cpp +++ b/examples/ExtendedTutorials/SimpleJoint.cpp @@ -13,23 +13,20 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "SimpleJoint.h" #include "btBulletDynamicsCommon.h" #include "LinearMath/btVector3.h" -#include "LinearMath/btAlignedObjectArray.h" +#include "LinearMath/btAlignedObjectArray.h" #include "../CommonInterfaces/CommonRigidBodyBase.h" - struct SimpleJointExample : public CommonRigidBodyBase { SimpleJointExample(struct GUIHelperInterface* helper) - :CommonRigidBodyBase(helper) + : CommonRigidBodyBase(helper) { } - virtual ~SimpleJointExample(){} + virtual ~SimpleJointExample() {} virtual void initPhysics(); virtual void renderScene(); void resetCamera() @@ -37,8 +34,8 @@ struct SimpleJointExample : public CommonRigidBodyBase float dist = 41; float pitch = -35; float yaw = 52; - float targetPos[3]={0,0.46,0}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {0, 0.46, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } }; @@ -47,63 +44,61 @@ void SimpleJointExample::initPhysics() m_guiHelper->setUpAxis(1); createEmptyDynamicsWorld(); - + m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); if (m_dynamicsWorld->getDebugDrawer()) - m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints); + m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints); ///create a few basic rigid bodies - btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); + btBoxShape* groundShape = createBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.))); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0,-50,0)); + groundTransform.setOrigin(btVector3(0, -50, 0)); { btScalar mass(0.); - createRigidBody(mass,groundTransform,groundShape, btVector4(0,0,1,1)); + createRigidBody(mass, groundTransform, groundShape, btVector4(0, 0, 1, 1)); } - { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance - btBoxShape* colShape = createBoxShape(btVector3(1,1,1)); - + btBoxShape* colShape = createBoxShape(btVector3(1, 1, 1)); + m_collisionShapes.push_back(colShape); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); - btScalar mass(1.f); + btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); - btVector3 localInertia(0,0,0); + btVector3 localInertia(0, 0, 0); if (isDynamic) - colShape->calculateLocalInertia(mass,localInertia); - + colShape->calculateLocalInertia(mass, localInertia); startTransform.setOrigin(btVector3( - btScalar(0), - btScalar(10), - btScalar(0))); - btRigidBody* dynamicBox = createRigidBody(mass,startTransform,colShape); + btScalar(0), + btScalar(10), + btScalar(0))); + btRigidBody* dynamicBox = createRigidBody(mass, startTransform, colShape); //create a static rigid body mass = 0; startTransform.setOrigin(btVector3( - btScalar(0), - btScalar(20), - btScalar(0))); - - btRigidBody* staticBox = createRigidBody(mass,startTransform,colShape); + btScalar(0), + btScalar(20), + btScalar(0))); + + btRigidBody* staticBox = createRigidBody(mass, startTransform, colShape); //create a simple p2pjoint constraint - btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*dynamicBox, *staticBox, btVector3(0,3,0), btVector3(0,0,0)); + btPoint2PointConstraint* p2p = new btPoint2PointConstraint(*dynamicBox, *staticBox, btVector3(0, 3, 0), btVector3(0, 0, 0)); p2p->m_setting.m_damping = 0.0625; p2p->m_setting.m_impulseClamp = 0.95; m_dynamicsWorld->addConstraint(p2p); @@ -112,22 +107,12 @@ void SimpleJointExample::initPhysics() m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } - void SimpleJointExample::renderScene() { - CommonRigidBodyBase::renderScene(); + CommonRigidBodyBase::renderScene(); } - - - - - - -CommonExampleInterface* ET_SimpleJointCreateFunc(CommonExampleOptions& options) +CommonExampleInterface* ET_SimpleJointCreateFunc(CommonExampleOptions& options) { return new SimpleJointExample(options.m_guiHelper); } - - - diff --git a/examples/ExtendedTutorials/SimpleJoint.h b/examples/ExtendedTutorials/SimpleJoint.h index a3d245a23..7097c8d50 100644 --- a/examples/ExtendedTutorials/SimpleJoint.h +++ b/examples/ExtendedTutorials/SimpleJoint.h @@ -16,7 +16,6 @@ subject to the following restrictions: #ifndef ET_SIMPLE_JOINT_EXAMPLE_H #define ET_SIMPLE_JOINT_EXAMPLE_H -class CommonExampleInterface* ET_SimpleJointCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* ET_SimpleJointCreateFunc(struct CommonExampleOptions& options); - -#endif //ET_SIMPLE_JOINT_EXAMPLE_H +#endif //ET_SIMPLE_JOINT_EXAMPLE_H diff --git a/examples/ForkLift/ForkLiftDemo.cpp b/examples/ForkLift/ForkLiftDemo.cpp index bac041662..8f84b7fc8 100644 --- a/examples/ForkLift/ForkLiftDemo.cpp +++ b/examples/ForkLift/ForkLiftDemo.cpp @@ -21,7 +21,6 @@ subject to the following restrictions: #include "btBulletDynamicsCommon.h" #include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h" - #include "BulletDynamics/MLCPSolvers/btDantzigSolver.h" #include "BulletDynamics/MLCPSolvers/btSolveProjectedGaussSeidel.h" #include "BulletDynamics/MLCPSolvers/btMLCPSolver.h" @@ -43,12 +42,12 @@ class btCollisionShape; #include "../CommonInterfaces/CommonGraphicsAppInterface.h" ///VehicleDemo shows how to setup and use the built-in raycast vehicle -class ForkLiftDemo : public CommonExampleInterface +class ForkLiftDemo : public CommonExampleInterface { - public: +public: GUIHelperInterface* m_guiHelper; - /* extra stuff*/ + /* extra stuff*/ btVector3 m_cameraPosition; class btDiscreteDynamicsWorld* m_dynamicsWorld; btDiscreteDynamicsWorld* getDynamicsWorld() @@ -60,83 +59,79 @@ class ForkLiftDemo : public CommonExampleInterface int m_wheelInstances[4]; -//---------------------------- + //---------------------------- btRigidBody* m_liftBody; - btVector3 m_liftStartPos; + btVector3 m_liftStartPos; btHingeConstraint* m_liftHinge; btRigidBody* m_forkBody; - btVector3 m_forkStartPos; + btVector3 m_forkStartPos; btSliderConstraint* m_forkSlider; btRigidBody* m_loadBody; - btVector3 m_loadStartPos; + btVector3 m_loadStartPos; void lockLiftHinge(void); void lockForkSlider(void); bool m_useDefaultCamera; -//---------------------------- - + //---------------------------- btAlignedObjectArray m_collisionShapes; - class btBroadphaseInterface* m_overlappingPairCache; + class btBroadphaseInterface* m_overlappingPairCache; - class btCollisionDispatcher* m_dispatcher; + class btCollisionDispatcher* m_dispatcher; - class btConstraintSolver* m_constraintSolver; + class btConstraintSolver* m_constraintSolver; class btDefaultCollisionConfiguration* m_collisionConfiguration; - class btTriangleIndexVertexArray* m_indexVertexArrays; + class btTriangleIndexVertexArray* m_indexVertexArrays; - btVector3* m_vertices; + btVector3* m_vertices; - - btRaycastVehicle::btVehicleTuning m_tuning; - btVehicleRaycaster* m_vehicleRayCaster; - btRaycastVehicle* m_vehicle; - btCollisionShape* m_wheelShape; + btRaycastVehicle::btVehicleTuning m_tuning; + btVehicleRaycaster* m_vehicleRayCaster; + btRaycastVehicle* m_vehicle; + btCollisionShape* m_wheelShape; - float m_cameraHeight; - - float m_minCameraDistance; - float m_maxCameraDistance; + float m_cameraHeight; + float m_minCameraDistance; + float m_maxCameraDistance; ForkLiftDemo(struct GUIHelperInterface* helper); virtual ~ForkLiftDemo(); virtual void stepSimulation(float deltaTime); - - virtual void resetForklift(); - + + virtual void resetForklift(); + virtual void clientResetScene(); virtual void displayCallback(); - + virtual void specialKeyboard(int key, int x, int y); virtual void specialKeyboardUp(int key, int x, int y); - virtual bool mouseMoveCallback(float x,float y) + virtual bool mouseMoveCallback(float x, float y) { return false; } - virtual bool mouseButtonCallback(int button, int state, float x, float y) + virtual bool mouseButtonCallback(int button, int state, float x, float y) { return false; } - virtual bool keyboardCallback(int key, int state); + virtual bool keyboardCallback(int key, int state); virtual void renderScene(); virtual void physicsDebugDraw(int debugFlags); - void initPhysics(); void exitPhysics(); @@ -146,8 +141,8 @@ class ForkLiftDemo : public CommonExampleInterface float dist = 8; float pitch = -32; float yaw = -45; - float targetPos[3]={-0.33,-0.72,4.5}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {-0.33, -0.72, 4.5}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } /*static DemoApplication* Create() @@ -160,112 +155,97 @@ class ForkLiftDemo : public CommonExampleInterface */ }; - btScalar maxMotorImpulse = 4000.f; //the sequential impulse solver has difficulties dealing with large mass ratios (differences), between loadMass and the fork parts -btScalar loadMass = 350.f;// +btScalar loadMass = 350.f; // //btScalar loadMass = 10.f;//this should work fine for the SI solver - #ifndef M_PI -#define M_PI 3.14159265358979323846 +#define M_PI 3.14159265358979323846 #endif #ifndef M_PI_2 -#define M_PI_2 1.57079632679489661923 +#define M_PI_2 1.57079632679489661923 #endif #ifndef M_PI_4 -#define M_PI_4 0.785398163397448309616 +#define M_PI_4 0.785398163397448309616 #endif - int rightIndex = 0; - int upIndex = 1; - int forwardIndex = 2; - btVector3 wheelDirectionCS0(0,-1,0); - btVector3 wheelAxleCS(-1,0,0); +int rightIndex = 0; +int upIndex = 1; +int forwardIndex = 2; +btVector3 wheelDirectionCS0(0, -1, 0); +btVector3 wheelAxleCS(-1, 0, 0); bool useMCLPSolver = true; - -#include //printf debugging - +#include //printf debugging #include "ForkLiftDemo.h" - - ///btRaycastVehicle is the interface for the constraint that implements the raycast vehicle ///notice that for higher-quality slow-moving vehicles, another approach might be better ///implementing explicit hinged-wheel constraints with cylinder collision, rather then raycasts -float gEngineForce = 0.f; +float gEngineForce = 0.f; -float defaultBreakingForce = 10.f; -float gBreakingForce = 100.f; +float defaultBreakingForce = 10.f; +float gBreakingForce = 100.f; -float maxEngineForce = 1000.f;//this should be engine/velocity dependent -float maxBreakingForce = 100.f; - -float gVehicleSteering = 0.f; -float steeringIncrement = 0.04f; -float steeringClamp = 0.3f; -float wheelRadius = 0.5f; -float wheelWidth = 0.4f; -float wheelFriction = 1000;//BT_LARGE_FLOAT; -float suspensionStiffness = 20.f; -float suspensionDamping = 2.3f; -float suspensionCompression = 4.4f; -float rollInfluence = 0.1f;//1.0f; +float maxEngineForce = 1000.f; //this should be engine/velocity dependent +float maxBreakingForce = 100.f; +float gVehicleSteering = 0.f; +float steeringIncrement = 0.04f; +float steeringClamp = 0.3f; +float wheelRadius = 0.5f; +float wheelWidth = 0.4f; +float wheelFriction = 1000; //BT_LARGE_FLOAT; +float suspensionStiffness = 20.f; +float suspensionDamping = 2.3f; +float suspensionCompression = 4.4f; +float rollInfluence = 0.1f; //1.0f; btScalar suspensionRestLength(0.6); #define CUBE_HALF_EXTENTS 1 - - //////////////////////////////////// - - - ForkLiftDemo::ForkLiftDemo(struct GUIHelperInterface* helper) -:m_guiHelper(helper), -m_carChassis(0), -m_liftBody(0), -m_forkBody(0), -m_loadBody(0), -m_indexVertexArrays(0), -m_vertices(0), -m_cameraHeight(4.f), -m_minCameraDistance(3.f), -m_maxCameraDistance(10.f) + : m_guiHelper(helper), + m_carChassis(0), + m_liftBody(0), + m_forkBody(0), + m_loadBody(0), + m_indexVertexArrays(0), + m_vertices(0), + m_cameraHeight(4.f), + m_minCameraDistance(3.f), + m_maxCameraDistance(10.f) { helper->setUpAxis(1); m_vehicle = 0; m_wheelShape = 0; - m_cameraPosition = btVector3(30,30,30); + m_cameraPosition = btVector3(30, 30, 30); m_useDefaultCamera = false; -// setTexturing(true); -// setShadows(true); - + // setTexturing(true); + // setShadows(true); } - void ForkLiftDemo::exitPhysics() { - //cleanup in the reverse order of creation/initialization + //cleanup in the reverse order of creation/initialization //remove the rigidbodies from the dynamics world and delete them int i; - for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--) { btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; btRigidBody* body = btRigidBody::upcast(obj); if (body && body->getMotionState()) { - while (body->getNumConstraintRefs()) { btTypedConstraint* constraint = body->getConstraintRef(0); @@ -274,15 +254,16 @@ void ForkLiftDemo::exitPhysics() } delete body->getMotionState(); m_dynamicsWorld->removeRigidBody(body); - } else + } + else { - m_dynamicsWorld->removeCollisionObject( obj ); + m_dynamicsWorld->removeCollisionObject(obj); } delete obj; } //delete collision shapes - for (int j=0;jsetUpAxis(upAxis); - btVector3 groundExtents(50,50,50); - groundExtents[upAxis]=3; + btVector3 groundExtents(50, 50, 50); + groundExtents[upAxis] = 3; btCollisionShape* groundShape = new btBoxShape(groundExtents); m_collisionShapes.push_back(groundShape); m_collisionConfiguration = new btDefaultCollisionConfiguration(); m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); - btVector3 worldMin(-1000,-1000,-1000); - btVector3 worldMax(1000,1000,1000); - m_overlappingPairCache = new btAxisSweep3(worldMin,worldMax); + btVector3 worldMin(-1000, -1000, -1000); + btVector3 worldMax(1000, 1000, 1000); + m_overlappingPairCache = new btAxisSweep3(worldMin, worldMax); if (useMCLPSolver) { btDantzigSolver* mlcp = new btDantzigSolver(); //btSolveProjectedGaussSeidel* mlcp = new btSolveProjectedGaussSeidel; btMLCPSolver* sol = new btMLCPSolver(mlcp); m_constraintSolver = sol; - } else + } + else { m_constraintSolver = new btSequentialImpulseConstraintSolver(); } - m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_overlappingPairCache,m_constraintSolver,m_collisionConfiguration); + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_overlappingPairCache, m_constraintSolver, m_collisionConfiguration); if (useMCLPSolver) { - m_dynamicsWorld ->getSolverInfo().m_minimumSolverBatchSize = 1;//for direct solver it is better to have a small A matrix - } else + m_dynamicsWorld->getSolverInfo().m_minimumSolverBatchSize = 1; //for direct solver it is better to have a small A matrix + } + else { - m_dynamicsWorld ->getSolverInfo().m_minimumSolverBatchSize = 128;//for direct solver, it is better to solve multiple objects together, small batches have high overhead + m_dynamicsWorld->getSolverInfo().m_minimumSolverBatchSize = 128; //for direct solver, it is better to solve multiple objects together, small batches have high overhead } m_dynamicsWorld->getSolverInfo().m_globalCfm = 0.00001; m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); - //m_dynamicsWorld->setGravity(btVector3(0,0,0)); -btTransform tr; -tr.setIdentity(); -tr.setOrigin(btVector3(0,-3,0)); - -//either use heightfield or triangle mesh + btTransform tr; + tr.setIdentity(); + tr.setOrigin(btVector3(0, -3, 0)); + //either use heightfield or triangle mesh //create ground object - localCreateRigidBody(0,tr,groundShape); + localCreateRigidBody(0, tr, groundShape); - btCollisionShape* chassisShape = new btBoxShape(btVector3(1.f,0.5f,2.f)); + btCollisionShape* chassisShape = new btBoxShape(btVector3(1.f, 0.5f, 2.f)); m_collisionShapes.push_back(chassisShape); btCompoundShape* compound = new btCompoundShape(); @@ -387,49 +364,47 @@ tr.setOrigin(btVector3(0,-3,0)); btTransform localTrans; localTrans.setIdentity(); //localTrans effectively shifts the center of mass with respect to the chassis - localTrans.setOrigin(btVector3(0,1,0)); + localTrans.setOrigin(btVector3(0, 1, 0)); - compound->addChildShape(localTrans,chassisShape); + compound->addChildShape(localTrans, chassisShape); { - btCollisionShape* suppShape = new btBoxShape(btVector3(0.5f,0.1f,0.5f)); + btCollisionShape* suppShape = new btBoxShape(btVector3(0.5f, 0.1f, 0.5f)); btTransform suppLocalTrans; suppLocalTrans.setIdentity(); //localTrans effectively shifts the center of mass with respect to the chassis - suppLocalTrans.setOrigin(btVector3(0,1.0,2.5)); + suppLocalTrans.setOrigin(btVector3(0, 1.0, 2.5)); compound->addChildShape(suppLocalTrans, suppShape); } - tr.setOrigin(btVector3(0,0.f,0)); + tr.setOrigin(btVector3(0, 0.f, 0)); - m_carChassis = localCreateRigidBody(800,tr,compound);//chassisShape); + m_carChassis = localCreateRigidBody(800, tr, compound); //chassisShape); //m_carChassis->setDamping(0.2,0.2); - - m_wheelShape = new btCylinderShapeX(btVector3(wheelWidth,wheelRadius,wheelRadius)); + + m_wheelShape = new btCylinderShapeX(btVector3(wheelWidth, wheelRadius, wheelRadius)); m_guiHelper->createCollisionShapeGraphicsObject(m_wheelShape); int wheelGraphicsIndex = m_wheelShape->getUserIndex(); - const float position[4]={0,10,10,0}; - const float quaternion[4]={0,0,0,1}; - const float color[4]={0,1,0,1}; - const float scaling[4] = {1,1,1,1}; + const float position[4] = {0, 10, 10, 0}; + const float quaternion[4] = {0, 0, 0, 1}; + const float color[4] = {0, 1, 0, 1}; + const float scaling[4] = {1, 1, 1, 1}; - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) { m_wheelInstances[i] = m_guiHelper->registerGraphicsInstance(wheelGraphicsIndex, position, quaternion, color, scaling); } - - { - btCollisionShape* liftShape = new btBoxShape(btVector3(0.5f,2.0f,0.05f)); + btCollisionShape* liftShape = new btBoxShape(btVector3(0.5f, 2.0f, 0.05f)); m_collisionShapes.push_back(liftShape); btTransform liftTrans; m_liftStartPos = btVector3(0.0f, 2.5f, 3.05f); liftTrans.setIdentity(); liftTrans.setOrigin(m_liftStartPos); - m_liftBody = localCreateRigidBody(10,liftTrans, liftShape); + m_liftBody = localCreateRigidBody(10, liftTrans, liftShape); btTransform localA, localB; localA.setIdentity(); @@ -438,12 +413,12 @@ tr.setOrigin(btVector3(0,-3,0)); localA.setOrigin(btVector3(0.0, 1.0, 3.05)); localB.getBasis().setEulerZYX(0, M_PI_2, 0); localB.setOrigin(btVector3(0.0, -1.5, -0.05)); - m_liftHinge = new btHingeConstraint(*m_carChassis,*m_liftBody, localA, localB); -// m_liftHinge->setLimit(-LIFT_EPS, LIFT_EPS); + m_liftHinge = new btHingeConstraint(*m_carChassis, *m_liftBody, localA, localB); + // m_liftHinge->setLimit(-LIFT_EPS, LIFT_EPS); m_liftHinge->setLimit(0.0f, 0.0f); m_dynamicsWorld->addConstraint(m_liftHinge, true); - btCollisionShape* forkShapeA = new btBoxShape(btVector3(1.0f,0.1f,0.1f)); + btCollisionShape* forkShapeA = new btBoxShape(btVector3(1.0f, 0.1f, 0.1f)); m_collisionShapes.push_back(forkShapeA); btCompoundShape* forkCompound = new btCompoundShape(); m_collisionShapes.push_back(forkCompound); @@ -451,13 +426,13 @@ tr.setOrigin(btVector3(0,-3,0)); forkLocalTrans.setIdentity(); forkCompound->addChildShape(forkLocalTrans, forkShapeA); - btCollisionShape* forkShapeB = new btBoxShape(btVector3(0.1f,0.02f,0.6f)); + btCollisionShape* forkShapeB = new btBoxShape(btVector3(0.1f, 0.02f, 0.6f)); m_collisionShapes.push_back(forkShapeB); forkLocalTrans.setIdentity(); forkLocalTrans.setOrigin(btVector3(-0.9f, -0.08f, 0.7f)); forkCompound->addChildShape(forkLocalTrans, forkShapeB); - btCollisionShape* forkShapeC = new btBoxShape(btVector3(0.1f,0.02f,0.6f)); + btCollisionShape* forkShapeC = new btBoxShape(btVector3(0.1f, 0.02f, 0.6f)); m_collisionShapes.push_back(forkShapeC); forkLocalTrans.setIdentity(); forkLocalTrans.setOrigin(btVector3(0.9f, -0.08f, 0.7f)); @@ -478,26 +453,25 @@ tr.setOrigin(btVector3(0,-3,0)); m_forkSlider = new btSliderConstraint(*m_liftBody, *m_forkBody, localA, localB, true); m_forkSlider->setLowerLinLimit(0.1f); m_forkSlider->setUpperLinLimit(0.1f); -// m_forkSlider->setLowerAngLimit(-LIFT_EPS); -// m_forkSlider->setUpperAngLimit(LIFT_EPS); + // m_forkSlider->setLowerAngLimit(-LIFT_EPS); + // m_forkSlider->setUpperAngLimit(LIFT_EPS); m_forkSlider->setLowerAngLimit(0.0f); m_forkSlider->setUpperAngLimit(0.0f); m_dynamicsWorld->addConstraint(m_forkSlider, true); - btCompoundShape* loadCompound = new btCompoundShape(); m_collisionShapes.push_back(loadCompound); - btCollisionShape* loadShapeA = new btBoxShape(btVector3(2.0f,0.5f,0.5f)); + btCollisionShape* loadShapeA = new btBoxShape(btVector3(2.0f, 0.5f, 0.5f)); m_collisionShapes.push_back(loadShapeA); btTransform loadTrans; loadTrans.setIdentity(); loadCompound->addChildShape(loadTrans, loadShapeA); - btCollisionShape* loadShapeB = new btBoxShape(btVector3(0.1f,1.0f,1.0f)); + btCollisionShape* loadShapeB = new btBoxShape(btVector3(0.1f, 1.0f, 1.0f)); m_collisionShapes.push_back(loadShapeB); loadTrans.setIdentity(); loadTrans.setOrigin(btVector3(2.1f, 0.0f, 0.0f)); loadCompound->addChildShape(loadTrans, loadShapeB); - btCollisionShape* loadShapeC = new btBoxShape(btVector3(0.1f,1.0f,1.0f)); + btCollisionShape* loadShapeC = new btBoxShape(btVector3(0.1f, 1.0f, 1.0f)); m_collisionShapes.push_back(loadShapeC); loadTrans.setIdentity(); loadTrans.setOrigin(btVector3(-2.1f, 0.0f, 0.0f)); @@ -505,19 +479,14 @@ tr.setOrigin(btVector3(0,-3,0)); loadTrans.setIdentity(); m_loadStartPos = btVector3(0.0f, 3.5f, 7.0f); loadTrans.setOrigin(m_loadStartPos); - m_loadBody = localCreateRigidBody(loadMass, loadTrans, loadCompound); + m_loadBody = localCreateRigidBody(loadMass, loadTrans, loadCompound); } - - - - /// create vehicle { - m_vehicleRayCaster = new btDefaultVehicleRaycaster(m_dynamicsWorld); - m_vehicle = new btRaycastVehicle(m_tuning,m_carChassis,m_vehicleRayCaster); - + m_vehicle = new btRaycastVehicle(m_tuning, m_carChassis, m_vehicleRayCaster); + ///never deactivate the vehicle m_carChassis->setActivationState(DISABLE_DEACTIVATION); @@ -525,25 +494,24 @@ tr.setOrigin(btVector3(0,-3,0)); float connectionHeight = 1.2f; - - bool isFrontWheel=true; + bool isFrontWheel = true; //choose coordinate system - m_vehicle->setCoordinateSystem(rightIndex,upIndex,forwardIndex); + m_vehicle->setCoordinateSystem(rightIndex, upIndex, forwardIndex); - btVector3 connectionPointCS0(CUBE_HALF_EXTENTS-(0.3*wheelWidth),connectionHeight,2*CUBE_HALF_EXTENTS-wheelRadius); + btVector3 connectionPointCS0(CUBE_HALF_EXTENTS - (0.3 * wheelWidth), connectionHeight, 2 * CUBE_HALF_EXTENTS - wheelRadius); - m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); - connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),connectionHeight,2*CUBE_HALF_EXTENTS-wheelRadius); + m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel); + connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS + (0.3 * wheelWidth), connectionHeight, 2 * CUBE_HALF_EXTENTS - wheelRadius); - m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); - connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS+(0.3*wheelWidth),connectionHeight,-2*CUBE_HALF_EXTENTS+wheelRadius); + m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel); + connectionPointCS0 = btVector3(-CUBE_HALF_EXTENTS + (0.3 * wheelWidth), connectionHeight, -2 * CUBE_HALF_EXTENTS + wheelRadius); isFrontWheel = false; - m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); - connectionPointCS0 = btVector3(CUBE_HALF_EXTENTS-(0.3*wheelWidth),connectionHeight,-2*CUBE_HALF_EXTENTS+wheelRadius); - m_vehicle->addWheel(connectionPointCS0,wheelDirectionCS0,wheelAxleCS,suspensionRestLength,wheelRadius,m_tuning,isFrontWheel); - - for (int i=0;igetNumWheels();i++) + m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel); + connectionPointCS0 = btVector3(CUBE_HALF_EXTENTS - (0.3 * wheelWidth), connectionHeight, -2 * CUBE_HALF_EXTENTS + wheelRadius); + m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel); + + for (int i = 0; i < m_vehicle->getNumWheels(); i++) { btWheelInfo& wheel = m_vehicle->getWheelInfo(i); wheel.m_suspensionStiffness = suspensionStiffness; @@ -555,8 +523,8 @@ tr.setOrigin(btVector3(0,-3,0)); } resetForklift(); - -// setCameraDistance(26.f); + + // setCameraDistance(26.f); m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } @@ -575,43 +543,39 @@ void ForkLiftDemo::renderScene() { m_guiHelper->syncPhysicsToGraphics(m_dynamicsWorld); - for (int i=0;igetNumWheels();i++) + for (int i = 0; i < m_vehicle->getNumWheels(); i++) { //synchronize the wheels with the (interpolated) chassis worldtransform - m_vehicle->updateWheelTransform(i,true); + m_vehicle->updateWheelTransform(i, true); CommonRenderInterface* renderer = m_guiHelper->getRenderInterface(); if (renderer) { btTransform tr = m_vehicle->getWheelInfo(i).m_worldTransform; - btVector3 pos=tr.getOrigin(); + btVector3 pos = tr.getOrigin(); btQuaternion orn = tr.getRotation(); - renderer->writeSingleInstanceTransformToCPU(pos,orn,m_wheelInstances[i]); + renderer->writeSingleInstanceTransformToCPU(pos, orn, m_wheelInstances[i]); } } - m_guiHelper->render(m_dynamicsWorld); - - - ATTRIBUTE_ALIGNED16(btScalar) m[16]; + ATTRIBUTE_ALIGNED16(btScalar) + m[16]; int i; - btVector3 wheelColor(1,0,0); + btVector3 wheelColor(1, 0, 0); - btVector3 worldBoundsMin,worldBoundsMax; - getDynamicsWorld()->getBroadphase()->getBroadphaseAabb(worldBoundsMin,worldBoundsMax); + btVector3 worldBoundsMin, worldBoundsMax; + getDynamicsWorld()->getBroadphase()->getBroadphaseAabb(worldBoundsMin, worldBoundsMax); - - - for (i=0;igetNumWheels();i++) + for (i = 0; i < m_vehicle->getNumWheels(); i++) { //synchronize the wheels with the (interpolated) chassis worldtransform - m_vehicle->updateWheelTransform(i,true); + m_vehicle->updateWheelTransform(i, true); //draw wheels (cylinders) m_vehicle->getWheelInfo(i).m_worldTransform.getOpenGLMatrix(m); -// m_shapeDrawer->drawOpenGL(m,m_wheelShape,wheelColor,getDebugMode(),worldBoundsMin,worldBoundsMax); + // m_shapeDrawer->drawOpenGL(m,m_wheelShape,wheelColor,getDebugMode(),worldBoundsMin,worldBoundsMax); } #if 0 @@ -676,92 +640,79 @@ void ForkLiftDemo::renderScene() void ForkLiftDemo::stepSimulation(float deltaTime) { + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - - - { + { int wheelIndex = 2; - m_vehicle->applyEngineForce(gEngineForce,wheelIndex); - m_vehicle->setBrake(gBreakingForce,wheelIndex); + m_vehicle->applyEngineForce(gEngineForce, wheelIndex); + m_vehicle->setBrake(gBreakingForce, wheelIndex); wheelIndex = 3; - m_vehicle->applyEngineForce(gEngineForce,wheelIndex); - m_vehicle->setBrake(gBreakingForce,wheelIndex); - + m_vehicle->applyEngineForce(gEngineForce, wheelIndex); + m_vehicle->setBrake(gBreakingForce, wheelIndex); wheelIndex = 0; - m_vehicle->setSteeringValue(gVehicleSteering,wheelIndex); + m_vehicle->setSteeringValue(gVehicleSteering, wheelIndex); wheelIndex = 1; - m_vehicle->setSteeringValue(gVehicleSteering,wheelIndex); - + m_vehicle->setSteeringValue(gVehicleSteering, wheelIndex); } - float dt = deltaTime; - + if (m_dynamicsWorld) { //during idle mode, just run 1 simulation step maximum - int maxSimSubSteps = 2; - - int numSimSteps; - numSimSteps = m_dynamicsWorld->stepSimulation(dt,maxSimSubSteps); + int maxSimSubSteps = 2; - if (m_dynamicsWorld->getConstraintSolver()->getSolverType()==BT_MLCP_SOLVER) + int numSimSteps; + numSimSteps = m_dynamicsWorld->stepSimulation(dt, maxSimSubSteps); + + if (m_dynamicsWorld->getConstraintSolver()->getSolverType() == BT_MLCP_SOLVER) { - btMLCPSolver* sol = (btMLCPSolver*) m_dynamicsWorld->getConstraintSolver(); + btMLCPSolver* sol = (btMLCPSolver*)m_dynamicsWorld->getConstraintSolver(); int numFallbacks = sol->getNumFallbacks(); if (numFallbacks) { static int totalFailures = 0; - totalFailures+=numFallbacks; - printf("MLCP solver failed %d times, falling back to btSequentialImpulseSolver (SI)\n",totalFailures); + totalFailures += numFallbacks; + printf("MLCP solver failed %d times, falling back to btSequentialImpulseSolver (SI)\n", totalFailures); } sol->setNumFallbacks(0); } - //#define VERBOSE_FEEDBACK #ifdef VERBOSE_FEEDBACK - if (!numSimSteps) + if (!numSimSteps) printf("Interpolated transforms\n"); else { if (numSimSteps > maxSimSubSteps) { //detect dropping frames - printf("Dropped (%i) simulation steps out of %i\n",numSimSteps - maxSimSubSteps,numSimSteps); - } else + printf("Dropped (%i) simulation steps out of %i\n", numSimSteps - maxSimSubSteps, numSimSteps); + } + else { - printf("Simulated (%i) steps\n",numSimSteps); + printf("Simulated (%i) steps\n", numSimSteps); } } -#endif //VERBOSE_FEEDBACK - +#endif //VERBOSE_FEEDBACK } - - - - } - - -void ForkLiftDemo::displayCallback(void) +void ForkLiftDemo::displayCallback(void) { -// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //renderme(); -//optional but useful: debug drawing + //optional but useful: debug drawing if (m_dynamicsWorld) m_dynamicsWorld->debugDrawWorld(); -// glFlush(); -// glutSwapBuffers(); + // glFlush(); + // glutSwapBuffers(); } - void ForkLiftDemo::clientResetScene() { exitPhysics(); @@ -775,16 +726,16 @@ void ForkLiftDemo::resetForklift() gEngineForce = 0.f; m_carChassis->setCenterOfMassTransform(btTransform::getIdentity()); - m_carChassis->setLinearVelocity(btVector3(0,0,0)); - m_carChassis->setAngularVelocity(btVector3(0,0,0)); - m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(m_carChassis->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); + m_carChassis->setLinearVelocity(btVector3(0, 0, 0)); + m_carChassis->setAngularVelocity(btVector3(0, 0, 0)); + m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(m_carChassis->getBroadphaseHandle(), getDynamicsWorld()->getDispatcher()); if (m_vehicle) { m_vehicle->resetSuspension(); - for (int i=0;igetNumWheels();i++) + for (int i = 0; i < m_vehicle->getNumWheels(); i++) { //synchronize the wheels with the (interpolated) chassis worldtransform - m_vehicle->updateWheelTransform(i,true); + m_vehicle->updateWheelTransform(i, true); } } btTransform liftTrans; @@ -792,22 +743,21 @@ void ForkLiftDemo::resetForklift() liftTrans.setOrigin(m_liftStartPos); m_liftBody->activate(); m_liftBody->setCenterOfMassTransform(liftTrans); - m_liftBody->setLinearVelocity(btVector3(0,0,0)); - m_liftBody->setAngularVelocity(btVector3(0,0,0)); + m_liftBody->setLinearVelocity(btVector3(0, 0, 0)); + m_liftBody->setAngularVelocity(btVector3(0, 0, 0)); btTransform forkTrans; forkTrans.setIdentity(); forkTrans.setOrigin(m_forkStartPos); m_forkBody->activate(); m_forkBody->setCenterOfMassTransform(forkTrans); - m_forkBody->setLinearVelocity(btVector3(0,0,0)); - m_forkBody->setAngularVelocity(btVector3(0,0,0)); + m_forkBody->setLinearVelocity(btVector3(0, 0, 0)); + m_forkBody->setAngularVelocity(btVector3(0, 0, 0)); -// m_liftHinge->setLimit(-LIFT_EPS, LIFT_EPS); + // m_liftHinge->setLimit(-LIFT_EPS, LIFT_EPS); m_liftHinge->setLimit(0.0f, 0.0f); m_liftHinge->enableAngularMotor(false, 0, 0); - m_forkSlider->setLowerLinLimit(0.1f); m_forkSlider->setUpperLinLimit(0.1f); m_forkSlider->setPoweredLinMotor(false); @@ -817,40 +767,36 @@ void ForkLiftDemo::resetForklift() loadTrans.setOrigin(m_loadStartPos); m_loadBody->activate(); m_loadBody->setCenterOfMassTransform(loadTrans); - m_loadBody->setLinearVelocity(btVector3(0,0,0)); - m_loadBody->setAngularVelocity(btVector3(0,0,0)); - + m_loadBody->setLinearVelocity(btVector3(0, 0, 0)); + m_loadBody->setAngularVelocity(btVector3(0, 0, 0)); } - -bool ForkLiftDemo::keyboardCallback(int key, int state) +bool ForkLiftDemo::keyboardCallback(int key, int state) { bool handled = false; bool isShiftPressed = m_guiHelper->getAppInterface()->m_window->isModifierKeyPressed(B3G_SHIFT); if (state) { - if (isShiftPressed) - { - switch (key) + if (isShiftPressed) + { + switch (key) { - case B3G_LEFT_ARROW : + case B3G_LEFT_ARROW: { - - m_liftHinge->setLimit(-M_PI/16.0f, M_PI/8.0f); + m_liftHinge->setLimit(-M_PI / 16.0f, M_PI / 8.0f); m_liftHinge->enableAngularMotor(true, -0.1, maxMotorImpulse); handled = true; break; } - case B3G_RIGHT_ARROW : + case B3G_RIGHT_ARROW: { - - m_liftHinge->setLimit(-M_PI/16.0f, M_PI/8.0f); + m_liftHinge->setLimit(-M_PI / 16.0f, M_PI / 8.0f); m_liftHinge->enableAngularMotor(true, 0.1, maxMotorImpulse); handled = true; break; } - case B3G_UP_ARROW : + case B3G_UP_ARROW: { m_forkSlider->setLowerLinLimit(0.1f); m_forkSlider->setUpperLinLimit(3.9f); @@ -860,7 +806,7 @@ bool ForkLiftDemo::keyboardCallback(int key, int state) handled = true; break; } - case B3G_DOWN_ARROW : + case B3G_DOWN_ARROW: { m_forkSlider->setLowerLinLimit(0.1f); m_forkSlider->setUpperLinLimit(3.9f); @@ -871,37 +817,37 @@ bool ForkLiftDemo::keyboardCallback(int key, int state) break; } } - - } else - { - switch (key) + } + else + { + switch (key) { - case B3G_LEFT_ARROW : + case B3G_LEFT_ARROW: { handled = true; gVehicleSteering += steeringIncrement; - if ( gVehicleSteering > steeringClamp) + if (gVehicleSteering > steeringClamp) gVehicleSteering = steeringClamp; break; } - case B3G_RIGHT_ARROW : + case B3G_RIGHT_ARROW: { handled = true; gVehicleSteering -= steeringIncrement; - if ( gVehicleSteering < -steeringClamp) + if (gVehicleSteering < -steeringClamp) gVehicleSteering = -steeringClamp; break; } - case B3G_UP_ARROW : + case B3G_UP_ARROW: { handled = true; gEngineForce = maxEngineForce; gBreakingForce = 0.f; break; } - case B3G_DOWN_ARROW : + case B3G_DOWN_ARROW: { handled = true; gEngineForce = -maxEngineForce; @@ -909,7 +855,7 @@ bool ForkLiftDemo::keyboardCallback(int key, int state) break; } - case B3G_F7: + case B3G_F7: { handled = true; btDiscreteDynamicsWorld* world = (btDiscreteDynamicsWorld*)m_dynamicsWorld; @@ -917,7 +863,7 @@ bool ForkLiftDemo::keyboardCallback(int key, int state) printf("world latencyMotionStateInterpolation = %d\n", world->getLatencyMotionStateInterpolation()); break; } - case B3G_F6: + case B3G_F6: { handled = true; //switch solver (needs demo restart) @@ -931,58 +877,58 @@ bool ForkLiftDemo::keyboardCallback(int key, int state) //btSolveProjectedGaussSeidel* mlcp = new btSolveProjectedGaussSeidel; btMLCPSolver* sol = new btMLCPSolver(mlcp); m_constraintSolver = sol; - } else + } + else { m_constraintSolver = new btSequentialImpulseConstraintSolver(); } m_dynamicsWorld->setConstraintSolver(m_constraintSolver); - //exitPhysics(); //initPhysics(); break; } - case B3G_F5: - handled = true; - m_useDefaultCamera = !m_useDefaultCamera; - break; - default: - break; + case B3G_F5: + handled = true; + m_useDefaultCamera = !m_useDefaultCamera; + break; + default: + break; } + } } - - } else + else { - switch (key) + switch (key) { - case B3G_UP_ARROW: - { - lockForkSlider(); - gEngineForce = 0.f; - gBreakingForce = defaultBreakingForce; - handled=true; - break; - } - case B3G_DOWN_ARROW: + case B3G_UP_ARROW: { lockForkSlider(); gEngineForce = 0.f; gBreakingForce = defaultBreakingForce; - handled=true; - break; - } - case B3G_LEFT_ARROW: - case B3G_RIGHT_ARROW: - { - lockLiftHinge(); - handled=true; + handled = true; break; } - default: - - break; + case B3G_DOWN_ARROW: + { + lockForkSlider(); + gEngineForce = 0.f; + gBreakingForce = defaultBreakingForce; + handled = true; + break; + } + case B3G_LEFT_ARROW: + case B3G_RIGHT_ARROW: + { + lockLiftHinge(); + handled = true; + break; + } + default: + + break; } } return handled; @@ -991,11 +937,10 @@ bool ForkLiftDemo::keyboardCallback(int key, int state) void ForkLiftDemo::specialKeyboardUp(int key, int x, int y) { #if 0 - + #endif } - void ForkLiftDemo::specialKeyboard(int key, int x, int y) { #if 0 @@ -1128,30 +1073,29 @@ void ForkLiftDemo::specialKeyboard(int key, int x, int y) #endif } - void ForkLiftDemo::lockLiftHinge(void) { btScalar hingeAngle = m_liftHinge->getHingeAngle(); btScalar lowLim = m_liftHinge->getLowerLimit(); btScalar hiLim = m_liftHinge->getUpperLimit(); m_liftHinge->enableAngularMotor(false, 0, 0); - if(hingeAngle < lowLim) + if (hingeAngle < lowLim) { -// m_liftHinge->setLimit(lowLim, lowLim + LIFT_EPS); + // m_liftHinge->setLimit(lowLim, lowLim + LIFT_EPS); m_liftHinge->setLimit(lowLim, lowLim); } - else if(hingeAngle > hiLim) + else if (hingeAngle > hiLim) { -// m_liftHinge->setLimit(hiLim - LIFT_EPS, hiLim); + // m_liftHinge->setLimit(hiLim - LIFT_EPS, hiLim); m_liftHinge->setLimit(hiLim, hiLim); } else { -// m_liftHinge->setLimit(hingeAngle - LIFT_EPS, hingeAngle + LIFT_EPS); + // m_liftHinge->setLimit(hingeAngle - LIFT_EPS, hingeAngle + LIFT_EPS); m_liftHinge->setLimit(hingeAngle, hingeAngle); } return; -} // ForkLiftDemo::lockLiftHinge() +} // ForkLiftDemo::lockLiftHinge() void ForkLiftDemo::lockForkSlider(void) { @@ -1159,12 +1103,12 @@ void ForkLiftDemo::lockForkSlider(void) btScalar lowLim = m_forkSlider->getLowerLinLimit(); btScalar hiLim = m_forkSlider->getUpperLinLimit(); m_forkSlider->setPoweredLinMotor(false); - if(linDepth <= lowLim) + if (linDepth <= lowLim) { m_forkSlider->setLowerLinLimit(lowLim); m_forkSlider->setUpperLinLimit(lowLim); } - else if(linDepth > hiLim) + else if (linDepth > hiLim) { m_forkSlider->setLowerLinLimit(hiLim); m_forkSlider->setUpperLinLimit(hiLim); @@ -1175,7 +1119,7 @@ void ForkLiftDemo::lockForkSlider(void) m_forkSlider->setUpperLinLimit(linDepth); } return; -} // ForkLiftDemo::lockForkSlider() +} // ForkLiftDemo::lockForkSlider() btRigidBody* ForkLiftDemo::localCreateRigidBody(btScalar mass, const btTransform& startTransform, btCollisionShape* shape) { @@ -1184,31 +1128,31 @@ btRigidBody* ForkLiftDemo::localCreateRigidBody(btScalar mass, const btTransform //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); - btVector3 localInertia(0,0,0); + btVector3 localInertia(0, 0, 0); if (isDynamic) - shape->calculateLocalInertia(mass,localInertia); + shape->calculateLocalInertia(mass, localInertia); - //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects #define USE_MOTIONSTATE 1 #ifdef USE_MOTIONSTATE btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); - btRigidBody::btRigidBodyConstructionInfo cInfo(mass,myMotionState,shape,localInertia); + btRigidBody::btRigidBodyConstructionInfo cInfo(mass, myMotionState, shape, localInertia); btRigidBody* body = new btRigidBody(cInfo); //body->setContactProcessingThreshold(m_defaultContactProcessingThreshold); #else - btRigidBody* body = new btRigidBody(mass,0,shape,localInertia); + btRigidBody* body = new btRigidBody(mass, 0, shape, localInertia); body->setWorldTransform(startTransform); -#endif// +#endif // m_dynamicsWorld->addRigidBody(body); return body; } -CommonExampleInterface* ForkLiftCreateFunc(struct CommonExampleOptions& options) +CommonExampleInterface* ForkLiftCreateFunc(struct CommonExampleOptions& options) { return new ForkLiftDemo(options.m_guiHelper); } diff --git a/examples/ForkLift/ForkLiftDemo.h b/examples/ForkLift/ForkLiftDemo.h index 030acf4e1..497c2d4c3 100644 --- a/examples/ForkLift/ForkLiftDemo.h +++ b/examples/ForkLift/ForkLiftDemo.h @@ -15,8 +15,6 @@ subject to the following restrictions: #ifndef FORKLIFT_DEMO_H #define FORKLIFT_DEMO_H -class CommonExampleInterface* ForkLiftCreateFunc(struct CommonExampleOptions& options); - -#endif // FORKLIFT_DEMO_H - +class CommonExampleInterface* ForkLiftCreateFunc(struct CommonExampleOptions& options); +#endif // FORKLIFT_DEMO_H diff --git a/examples/FractureDemo/FractureDemo.cpp b/examples/FractureDemo/FractureDemo.cpp index 4e46f472c..8bf44bf35 100644 --- a/examples/FractureDemo/FractureDemo.cpp +++ b/examples/FractureDemo/FractureDemo.cpp @@ -13,14 +13,12 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - ///FractureDemo shows how to break objects. ///It assumes a btCompoundShaps (where the childshapes are the pre-fractured pieces) ///The btFractureBody is a class derived from btRigidBody, dealing with the collision impacts. ///Press the F key to toggle between fracture and glue mode ///This is preliminary work - #define CUBE_HALF_EXTENTS 1.f #define EXTRA_HEIGHT 1.f ///scaling of the objects (0.1 = 20 centimeter boxes ) @@ -33,87 +31,73 @@ subject to the following restrictions: ///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. #include "btBulletDynamicsCommon.h" - -#include //printf debugging - +#include //printf debugging int sFrameNumber = 0; #include "btFractureBody.h" #include "btFractureDynamicsWorld.h" - #include "LinearMath/btAlignedObjectArray.h" #include "../CommonInterfaces/CommonRigidBodyBase.h" - ///FractureDemo shows basic breaking and glueing of objects class FractureDemo : public CommonRigidBodyBase { - - public: - FractureDemo(struct GUIHelperInterface* helper) - :CommonRigidBodyBase(helper) + : CommonRigidBodyBase(helper) { } virtual ~FractureDemo() { } - void initPhysics(); - - void exitPhysics(); - + void initPhysics(); + + void exitPhysics(); + virtual void stepSimulation(float deltaTime) { CommonRigidBodyBase::stepSimulation(deltaTime); - + { - BT_PROFILE("recreate graphics"); - //@todo: make this graphics re-creation better - //right now: brute force remove all graphics objects, and re-create them every frame - m_guiHelper->getRenderInterface()->removeAllInstances(); - for (int i=0;igetNumCollisionObjects();i++) - { - btCollisionObject* colObj = m_dynamicsWorld->getCollisionObjectArray()[i]; - colObj->getCollisionShape()->setUserIndex(-1); - colObj->setUserIndex(-1); - } - m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); + BT_PROFILE("recreate graphics"); + //@todo: make this graphics re-creation better + //right now: brute force remove all graphics objects, and re-create them every frame + m_guiHelper->getRenderInterface()->removeAllInstances(); + for (int i = 0; i < m_dynamicsWorld->getNumCollisionObjects(); i++) + { + btCollisionObject* colObj = m_dynamicsWorld->getCollisionObjectArray()[i]; + colObj->getCollisionShape()->setUserIndex(-1); + colObj->setUserIndex(-1); + } + m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } } - - virtual bool keyboardCallback(int key, int state); - + + virtual bool keyboardCallback(int key, int state); + void resetCamera() { float dist = 41; float pitch = -35; float yaw = 52; - float targetPos[3]={0,0.46,0}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {0, 0.46, 0}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } - - }; - - - -void FractureDemo::initPhysics() +void FractureDemo::initPhysics() { - m_guiHelper->setUpAxis(1); - ///collision configuration contains default setup for memory, collision setup m_collisionConfiguration = new btDefaultCollisionConfiguration(); //m_collisionConfiguration->setConvexConvexMultipointIterations(); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) - m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_broadphase = new btDbvtBroadphase(); @@ -123,42 +107,39 @@ void FractureDemo::initPhysics() //m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); - btFractureDynamicsWorld* fractureWorld = new btFractureDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + btFractureDynamicsWorld* fractureWorld = new btFractureDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration); m_dynamicsWorld = fractureWorld; m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); - //m_splitImpulse removes the penetration resolution from the applied impulse, otherwise objects might fracture due to deep penetrations. m_dynamicsWorld->getSolverInfo().m_splitImpulse = true; { ///create a few basic rigid bodies - btCollisionShape* groundShape = new btBoxShape(btVector3(50,1,50)); - /// btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),0); + btCollisionShape* groundShape = new btBoxShape(btVector3(50, 1, 50)); + /// btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),0); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0,0,0)); - createRigidBody(0.f,groundTransform,groundShape); + groundTransform.setOrigin(btVector3(0, 0, 0)); + createRigidBody(0.f, groundTransform, groundShape); } { ///create a few basic rigid bodies - btCollisionShape* shape = new btBoxShape(btVector3(1,1,1)); + btCollisionShape* shape = new btBoxShape(btVector3(1, 1, 1)); m_collisionShapes.push_back(shape); btTransform tr; tr.setIdentity(); - tr.setOrigin(btVector3(5,2,0)); - createRigidBody(0.f,tr,shape); + tr.setOrigin(btVector3(5, 2, 0)); + createRigidBody(0.f, tr, shape); } - - { //create a few dynamic rigidbodies // Re-using the same collision is better for memory usage and performance - btCollisionShape* colShape = new btBoxShape(btVector3(SCALING*1,SCALING*1,SCALING*1)); + btCollisionShape* colShape = new btBoxShape(btVector3(SCALING * 1, SCALING * 1, SCALING * 1)); //btCollisionShape* colShape = new btCapsuleShape(SCALING*0.4,SCALING*1); //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); m_collisionShapes.push_back(colShape); @@ -167,44 +148,38 @@ void FractureDemo::initPhysics() btTransform startTransform; startTransform.setIdentity(); - btScalar mass(1.f); + btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); - btVector3 localInertia(0,0,0); + btVector3 localInertia(0, 0, 0); if (isDynamic) - colShape->calculateLocalInertia(mass,localInertia); - + colShape->calculateLocalInertia(mass, localInertia); int gNumObjects = 10; - for (int i=0;isetLinearVelocity(btVector3(0,-10,0)); + body->setLinearVelocity(btVector3(0, -10, 0)); m_dynamicsWorld->addRigidBody(body); - } - } - - - fractureWorld->stepSimulation(1./60.,0); + fractureWorld->stepSimulation(1. / 60., 0); fractureWorld->glueCallback(); - m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } @@ -263,29 +238,26 @@ void FractureDemo::displayCallback(void) { } #endif - -bool FractureDemo::keyboardCallback(int key, int state) +bool FractureDemo::keyboardCallback(int key, int state) { - - if (key=='f' && (state==0)) + if (key == 'f' && (state == 0)) { btFractureDynamicsWorld* world = (btFractureDynamicsWorld*)m_dynamicsWorld; world->setFractureMode(!world->getFractureMode()); if (world->getFractureMode()) { b3Printf("Fracturing mode"); - } else + } + else { b3Printf("Gluing mode"); - } return true; } - + return false; } - #if 0 void FractureDemo::keyboardUpCallback(unsigned char key, int x, int y) { @@ -350,20 +322,13 @@ void FractureDemo::shootBox(const btVector3& destination) } #endif - - - - - - -void FractureDemo::exitPhysics() +void FractureDemo::exitPhysics() { - //cleanup in the reverse order of creation/initialization //remove the rigidbodies from the dynamics world and delete them int i; - for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--) { btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; btRigidBody* body = btRigidBody::upcast(obj); @@ -371,12 +336,12 @@ void FractureDemo::exitPhysics() { delete body->getMotionState(); } - m_dynamicsWorld->removeCollisionObject( obj ); + m_dynamicsWorld->removeCollisionObject(obj); delete obj; } //delete collision shapes - for (int j=0;jisCompound()) { btCompoundShape* compound = (btCompoundShape*)getCollisionShape(); - for (int i=0;igetNumChildShapes();i++) + for (int i = 0; i < compound->getNumChildShapes(); i++) { - for (int j=i+1;jgetNumChildShapes();j++) + for (int j = i + 1; j < compound->getNumChildShapes(); j++) { - - struct MyContactResultCallback : public btCollisionWorld::ContactResultCallback + struct MyContactResultCallback : public btCollisionWorld::ContactResultCallback { bool m_connected; btScalar m_margin; - MyContactResultCallback() :m_connected(false),m_margin(0.05) + MyContactResultCallback() : m_connected(false), m_margin(0.05) { } - virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1) + virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper* colObj1Wrap, int partId1, int index1) { - if (cp.getDistance()<=m_margin) + if (cp.getDistance() <= m_margin) m_connected = true; return 1.f; } - }; + }; MyContactResultCallback result; @@ -42,7 +39,7 @@ void btFractureBody::recomputeConnectivity(btCollisionWorld* world) btCollisionObject obB; obB.setWorldTransform(compound->getChildTransform(j)); obB.setCollisionShape(compound->getChildShape(j)); - world->contactPairTest(&obA,&obB,result); + world->contactPairTest(&obA, &obB, result); if (result.m_connected) { btConnection tmp; @@ -50,48 +47,42 @@ void btFractureBody::recomputeConnectivity(btCollisionWorld* world) tmp.m_childIndex1 = j; tmp.m_childShape0 = compound->getChildShape(i); tmp.m_childShape1 = compound->getChildShape(j); - tmp.m_strength = 1.f;//?? + tmp.m_strength = 1.f; //?? m_connections.push_back(tmp); } } } } - - } -btCompoundShape* btFractureBody::shiftTransformDistributeMass(btCompoundShape* boxCompound,btScalar mass,btTransform& shift) +btCompoundShape* btFractureBody::shiftTransformDistributeMass(btCompoundShape* boxCompound, btScalar mass, btTransform& shift) { - btVector3 principalInertia; btScalar* masses = new btScalar[boxCompound->getNumChildShapes()]; - for (int j=0;jgetNumChildShapes();j++) + for (int j = 0; j < boxCompound->getNumChildShapes(); j++) { //evenly distribute mass - masses[j]=mass/boxCompound->getNumChildShapes(); + masses[j] = mass / boxCompound->getNumChildShapes(); } - return shiftTransform(boxCompound,masses,shift,principalInertia); - + return shiftTransform(boxCompound, masses, shift, principalInertia); } - -btCompoundShape* btFractureBody::shiftTransform(btCompoundShape* boxCompound,btScalar* masses,btTransform& shift, btVector3& principalInertia) +btCompoundShape* btFractureBody::shiftTransform(btCompoundShape* boxCompound, btScalar* masses, btTransform& shift, btVector3& principalInertia) { btTransform principal; - boxCompound->calculatePrincipalAxisTransform(masses,principal,principalInertia); - + boxCompound->calculatePrincipalAxisTransform(masses, principal, principalInertia); ///create a new compound with world transform/center of mass properly aligned with the principal axis ///non-recursive compound shapes perform better - + #ifdef USE_RECURSIVE_COMPOUND btCompoundShape* newCompound = new btCompoundShape(); - newCompound->addChildShape(principal.inverse(),boxCompound); + newCompound->addChildShape(principal.inverse(), boxCompound); newBoxCompound = newCompound; //m_collisionShapes.push_back(newCompound); @@ -101,39 +92,31 @@ btCompoundShape* btFractureBody::shiftTransform(btCompoundShape* boxCompound,btS #else #ifdef CHANGE_COMPOUND_INPLACE newBoxCompound = boxCompound; - for (int i=0;igetNumChildShapes();i++) + for (int i = 0; i < boxCompound->getNumChildShapes(); i++) { - btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i); + btTransform newChildTransform = principal.inverse() * boxCompound->getChildTransform(i); ///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update - boxCompound->updateChildTransform(i,newChildTransform); + boxCompound->updateChildTransform(i, newChildTransform); } bool isDynamic = (mass != 0.f); - btVector3 localInertia(0,0,0); + btVector3 localInertia(0, 0, 0); if (isDynamic) - boxCompound->calculateLocalInertia(mass,localInertia); - + boxCompound->calculateLocalInertia(mass, localInertia); + #else ///creation is faster using a new compound to store the shifted children btCompoundShape* newBoxCompound = new btCompoundShape(); - for (int i=0;igetNumChildShapes();i++) + for (int i = 0; i < boxCompound->getNumChildShapes(); i++) { - btTransform newChildTransform = principal.inverse()*boxCompound->getChildTransform(i); + btTransform newChildTransform = principal.inverse() * boxCompound->getChildTransform(i); ///updateChildTransform is really slow, because it re-calculates the AABB each time. todo: add option to disable this update - newBoxCompound->addChildShape(newChildTransform,boxCompound->getChildShape(i)); + newBoxCompound->addChildShape(newChildTransform, boxCompound->getChildShape(i)); } - - #endif -#endif//USE_RECURSIVE_COMPOUND +#endif //USE_RECURSIVE_COMPOUND shift = principal; return newBoxCompound; } - - - - - - diff --git a/examples/FractureDemo/btFractureBody.h b/examples/FractureDemo/btFractureBody.h index 922db3c22..746babde1 100644 --- a/examples/FractureDemo/btFractureBody.h +++ b/examples/FractureDemo/btFractureBody.h @@ -11,68 +11,55 @@ class btManifoldPoint; #include "LinearMath/btAlignedObjectArray.h" #include "BulletDynamics/Dynamics/btRigidBody.h" -#define CUSTOM_FRACTURE_TYPE (btRigidBody::CO_USER_TYPE+1) - +#define CUSTOM_FRACTURE_TYPE (btRigidBody::CO_USER_TYPE + 1) struct btConnection { - - btCollisionShape* m_childShape0; - btCollisionShape* m_childShape1; - int m_childIndex0; - int m_childIndex1; - btScalar m_strength; + btCollisionShape* m_childShape0; + btCollisionShape* m_childShape1; + int m_childIndex0; + int m_childIndex1; + btScalar m_strength; }; class btFractureBody : public btRigidBody { //connections public: + btDynamicsWorld* m_world; + btAlignedObjectArray m_masses; + btAlignedObjectArray m_connections; - btDynamicsWorld* m_world; - btAlignedObjectArray m_masses; - btAlignedObjectArray m_connections; - - - - btFractureBody( const btRigidBodyConstructionInfo& constructionInfo, btDynamicsWorld* world) - :btRigidBody(constructionInfo), - m_world(world) + btFractureBody(const btRigidBodyConstructionInfo& constructionInfo, btDynamicsWorld* world) + : btRigidBody(constructionInfo), + m_world(world) { m_masses.push_back(constructionInfo.m_mass); - m_internalType=CUSTOM_FRACTURE_TYPE+CO_RIGID_BODY; + m_internalType = CUSTOM_FRACTURE_TYPE + CO_RIGID_BODY; } - - - ///btRigidBody constructor for backwards compatibility. + ///btRigidBody constructor for backwards compatibility. ///To specify friction (etc) during rigid body construction, please use the other constructor (using btRigidBodyConstructionInfo) - btFractureBody( btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia, btScalar* masses, int numMasses, btDynamicsWorld* world) - :btRigidBody(mass,motionState,collisionShape,localInertia), - m_world(world) + btFractureBody(btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia, btScalar* masses, int numMasses, btDynamicsWorld* world) + : btRigidBody(mass, motionState, collisionShape, localInertia), + m_world(world) { - - for (int i=0;igetNumManifolds(); ///first build the islands based on axis aligned bounding box overlap @@ -24,24 +21,24 @@ void btFractureDynamicsWorld::glueCallback() int index = 0; { - int i; - for (i=0;iisStaticOrKinematicObject()) { collisionObject->setIslandTag(index++); - } else + } + else { collisionObject->setIslandTag(-1); } #else collisionObject->setIslandTag(i); - index=i+1; + index = i + 1; #endif } } @@ -50,20 +47,20 @@ void btFractureDynamicsWorld::glueCallback() int numElem = unionFind.getNumElements(); - for (int i=0;igetManifoldByIndexInternal(i); if (!manifold->getNumContacts()) continue; btScalar minDist = 1e30f; - for (int v=0;vgetNumContacts();v++) + for (int v = 0; v < manifold->getNumContacts(); v++) { - minDist = btMin(minDist,manifold->getContactPoint(v).getDistance()); + minDist = btMin(minDist, manifold->getContactPoint(v).getDistance()); } - if (minDist>0.) + if (minDist > 0.) continue; - + btCollisionObject* colObj0 = (btCollisionObject*)manifold->getBody0(); btCollisionObject* colObj1 = (btCollisionObject*)manifold->getBody1(); int tag0 = (colObj0)->getIslandTag(); @@ -71,65 +68,57 @@ void btFractureDynamicsWorld::glueCallback() //btRigidBody* body0 = btRigidBody::upcast(colObj0); //btRigidBody* body1 = btRigidBody::upcast(colObj1); - if (!colObj0->isStaticOrKinematicObject() && !colObj1->isStaticOrKinematicObject()) { unionFind.unite(tag0, tag1); } } - - - numElem = unionFind.getNumElements(); - - - index=0; - for (int ai=0;aiisStaticOrKinematicObject()) { int tag = unionFind.find(index); - collisionObject->setIslandTag( tag); + collisionObject->setIslandTag(tag); //Set the correct object offset in Collision Object Array #if STATIC_SIMULATION_ISLAND_OPTIMIZATION unionFind.getElement(index).m_sz = ai; -#endif //STATIC_SIMULATION_ISLAND_OPTIMIZATION +#endif //STATIC_SIMULATION_ISLAND_OPTIMIZATION index++; } } unionFind.sortIslands(); - - - int endIslandIndex=1; + int endIslandIndex = 1; int startIslandIndex; btAlignedObjectArray removedObjects; ///iterate over all islands - for ( startIslandIndex=0;startIslandIndexgetInternalType()& CUSTOM_FRACTURE_TYPE) + if (colObj0->getInternalType() & CUSTOM_FRACTURE_TYPE) { fractureObjectIndex = i; } @@ -140,9 +129,8 @@ void btFractureDynamicsWorld::glueCallback() } ///Then for each island that contains at least two objects and one fracture object - if (fractureObjectIndex>=0 && numObjects>1) + if (fractureObjectIndex >= 0 && numObjects > 1) { - btFractureBody* fracObj = (btFractureBody*)getCollisionObjectArray()[fractureObjectIndex]; ///glueing objects means creating a new compound and removing the old objects @@ -155,40 +143,38 @@ void btFractureDynamicsWorld::glueCallback() btAlignedObjectArray oldImpulses; btAlignedObjectArray oldCenterOfMassesWS; - oldImpulses.push_back(fracObj->getLinearVelocity()/1./fracObj->getInvMass()); + oldImpulses.push_back(fracObj->getLinearVelocity() / 1. / fracObj->getInvMass()); oldCenterOfMassesWS.push_back(fracObj->getCenterOfMassPosition()); btScalar totalMass = 0.f; - btCompoundShape* compound = new btCompoundShape(); if (fracObj->getCollisionShape()->isCompound()) { btTransform tr; tr.setIdentity(); btCompoundShape* oldCompound = (btCompoundShape*)fracObj->getCollisionShape(); - for (int c=0;cgetNumChildShapes();c++) + for (int c = 0; c < oldCompound->getNumChildShapes(); c++) { - compound->addChildShape(oldCompound->getChildTransform(c),oldCompound->getChildShape(c)); + compound->addChildShape(oldCompound->getChildTransform(c), oldCompound->getChildShape(c)); massArray.push_back(fracObj->m_masses[c]); - totalMass+=fracObj->m_masses[c]; + totalMass += fracObj->m_masses[c]; } - - } else + } + else { btTransform tr; tr.setIdentity(); - compound->addChildShape(tr,fracObj->getCollisionShape()); + compound->addChildShape(tr, fracObj->getCollisionShape()); massArray.push_back(fracObj->m_masses[0]); - totalMass+=fracObj->m_masses[0]; + totalMass += fracObj->m_masses[0]; } - for (idx=startIslandIndex;idxgetInvMass()) continue; - - oldImpulses.push_back(otherObject->getLinearVelocity()*(1.f/otherObject->getInvMass())); + oldImpulses.push_back(otherObject->getLinearVelocity() * (1.f / otherObject->getInvMass())); oldCenterOfMassesWS.push_back(otherObject->getCenterOfMassPosition()); removedObjects.push_back(otherObject); m_fractureBodies.remove((btFractureBody*)otherObject); - btScalar curMass = 1.f/otherObject->getInvMass(); - + btScalar curMass = 1.f / otherObject->getInvMass(); if (otherObject->getCollisionShape()->isCompound()) { btTransform tr; btCompoundShape* oldCompound = (btCompoundShape*)otherObject->getCollisionShape(); - for (int c=0;cgetNumChildShapes();c++) + for (int c = 0; c < oldCompound->getNumChildShapes(); c++) { - tr = fracObj->getWorldTransform().inverseTimes(otherObject->getWorldTransform()*oldCompound->getChildTransform(c)); - compound->addChildShape(tr,oldCompound->getChildShape(c)); - massArray.push_back(curMass/(btScalar)oldCompound->getNumChildShapes()); - + tr = fracObj->getWorldTransform().inverseTimes(otherObject->getWorldTransform() * oldCompound->getChildTransform(c)); + compound->addChildShape(tr, oldCompound->getChildShape(c)); + massArray.push_back(curMass / (btScalar)oldCompound->getNumChildShapes()); } - } else + } + else { btTransform tr; tr = fracObj->getWorldTransform().inverseTimes(otherObject->getWorldTransform()); - compound->addChildShape(tr,otherObject->getCollisionShape()); + compound->addChildShape(tr, otherObject->getCollisionShape()); massArray.push_back(curMass); } - totalMass+=curMass; + totalMass += curMass; } - - btTransform shift; shift.setIdentity(); - btCompoundShape* newCompound = btFractureBody::shiftTransformDistributeMass(compound,totalMass,shift); + btCompoundShape* newCompound = btFractureBody::shiftTransformDistributeMass(compound, totalMass, shift); int numChildren = newCompound->getNumChildShapes(); btAssert(numChildren == massArray.size()); btVector3 localInertia; - newCompound->calculateLocalInertia(totalMass,localInertia); - btFractureBody* newBody = new btFractureBody(totalMass,0,newCompound,localInertia, &massArray[0], numChildren,this); + newCompound->calculateLocalInertia(totalMass, localInertia); + btFractureBody* newBody = new btFractureBody(totalMass, 0, newCompound, localInertia, &massArray[0], numChildren, this); newBody->recomputeConnectivity(this); - newBody->setWorldTransform(fracObj->getWorldTransform()*shift); + newBody->setWorldTransform(fracObj->getWorldTransform() * shift); //now the linear/angular velocity is still zero, apply the impulses - for (int i=0;igetCenterOfMassPosition(); + btVector3 rel_pos = oldCenterOfMassesWS[i] - newBody->getCenterOfMassPosition(); const btVector3& imp = oldImpulses[i]; newBody->applyImpulse(imp, rel_pos); } addRigidBody(newBody); - - } - - } - //remove the objects from the world at the very end, + //remove the objects from the world at the very end, //otherwise the island tags would not match the world collision object array indices anymore while (removedObjects.size()) { - btCollisionObject* otherCollider = removedObjects[removedObjects.size()-1]; + btCollisionObject* otherCollider = removedObjects[removedObjects.size() - 1]; removedObjects.pop_back(); btRigidBody* otherObject = btRigidBody::upcast(otherCollider); @@ -273,18 +251,14 @@ void btFractureDynamicsWorld::glueCallback() continue; removeRigidBody(otherObject); } - } - -struct btFracturePair +struct btFracturePair { btFractureBody* m_fracObj; - btAlignedObjectArray m_contactManifolds; + btAlignedObjectArray m_contactManifolds; }; - - void btFractureDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) { // todo: after fracture we should run the solver again for better realism @@ -299,24 +273,24 @@ void btFractureDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) fractureCallback(); } -btFractureBody* btFractureDynamicsWorld::addNewBody(const btTransform& oldTransform,btScalar* masses, btCompoundShape* oldCompound) +btFractureBody* btFractureDynamicsWorld::addNewBody(const btTransform& oldTransform, btScalar* masses, btCompoundShape* oldCompound) { int i; btTransform shift; shift.setIdentity(); btVector3 localInertia; - btCompoundShape* newCompound = btFractureBody::shiftTransform(oldCompound,masses,shift,localInertia); + btCompoundShape* newCompound = btFractureBody::shiftTransform(oldCompound, masses, shift, localInertia); btScalar totalMass = 0; - for (i=0;igetNumChildShapes();i++) + for (i = 0; i < newCompound->getNumChildShapes(); i++) totalMass += masses[i]; //newCompound->calculateLocalInertia(totalMass,localInertia); - btFractureBody* newBody = new btFractureBody(totalMass,0,newCompound,localInertia, masses,newCompound->getNumChildShapes(), this); + btFractureBody* newBody = new btFractureBody(totalMass, 0, newCompound, localInertia, masses, newCompound->getNumChildShapes(), this); newBody->recomputeConnectivity(this); - newBody->setCollisionFlags(newBody->getCollisionFlags()|btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); - newBody->setWorldTransform(oldTransform*shift); + newBody->setCollisionFlags(newBody->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + newBody->setWorldTransform(oldTransform * shift); addRigidBody(newBody); return newBody; } @@ -331,40 +305,37 @@ void btFractureDynamicsWorld::addRigidBody(btRigidBody* body) btDiscreteDynamicsWorld::addRigidBody(body); } -void btFractureDynamicsWorld::removeRigidBody(btRigidBody* body) +void btFractureDynamicsWorld::removeRigidBody(btRigidBody* body) { if (body->getInternalType() & CUSTOM_FRACTURE_TYPE) { btFractureBody* fbody = (btFractureBody*)body; btAlignedObjectArray tmpConstraints; - for (int i=0;igetNumConstraintRefs();i++) + for (int i = 0; i < fbody->getNumConstraintRefs(); i++) { tmpConstraints.push_back(fbody->getConstraintRef(i)); } - //remove all constraints attached to this rigid body too - for (int i=0;igetCollisionShape()->isCompound()) return; btCompoundShape* compound = (btCompoundShape*)fracObj->getCollisionShape(); int numChildren = compound->getNumChildShapes(); - if (numChildren<=1) + if (numChildren <= 1) return; //compute connectivity @@ -373,19 +344,19 @@ void btFractureDynamicsWorld::breakDisconnectedParts( btFractureBody* fracObj) btAlignedObjectArray tags; tags.resize(numChildren); int i, index = 0; - for ( i=0;im_connections.size();i++) + for (i = 0; i < fracObj->m_connections.size(); i++) { btConnection& connection = fracObj->m_connections[i]; if (connection.m_strength > 0.) @@ -397,53 +368,52 @@ void btFractureDynamicsWorld::breakDisconnectedParts( btFractureBody* fracObj) } numElem = unionFind.getNumElements(); - index=0; - for (int ai=0;ai removedObjects; int numIslands = 0; - for ( startIslandIndex=0;startIslandIndex masses; int idx; - for (idx=startIslandIndex;idxgetChildShape(i); - newCompound->addChildShape(compound->getChildTransform(i),compound->getChildShape(i)); + // btCollisionShape* shape = compound->getChildShape(i); + newCompound->addChildShape(compound->getChildTransform(i), compound->getChildShape(i)); masses.push_back(fracObj->m_masses[i]); numShapes++; } if (numShapes) { - btFractureBody* newBody = addNewBody(fracObj->getWorldTransform(),&masses[0],newCompound); + btFractureBody* newBody = addNewBody(fracObj->getWorldTransform(), &masses[0], newCompound); newBody->setLinearVelocity(fracObj->getLinearVelocity()); newBody->setAngularVelocity(fracObj->getAngularVelocity()); @@ -451,21 +421,13 @@ void btFractureDynamicsWorld::breakDisconnectedParts( btFractureBody* fracObj) } } - - - - - removeRigidBody(fracObj);//should it also be removed from the array? - - + removeRigidBody(fracObj); //should it also be removed from the array? } #include - -void btFractureDynamicsWorld::fractureCallback( ) +void btFractureDynamicsWorld::fractureCallback() { - btAlignedObjectArray sFracturePairs; if (!m_fracturingMode) @@ -478,24 +440,22 @@ void btFractureDynamicsWorld::fractureCallback( ) sFracturePairs.clear(); - - for (int i=0;igetManifoldByIndexInternal(i); if (!manifold->getNumContacts()) continue; btScalar totalImpact = 0.f; - for (int p=0;pgetNumContacts();p++) + for (int p = 0; p < manifold->getNumContacts(); p++) { totalImpact += manifold->getContactPoint(p).m_appliedImpulse; } - -// printf("totalImpact=%f\n",totalImpact); + // printf("totalImpact=%f\n",totalImpact); static float maxImpact = 0; - if (totalImpact>maxImpact) + if (totalImpact > maxImpact) maxImpact = totalImpact; //some threshold otherwise resting contact would break objects after a while @@ -504,17 +464,16 @@ void btFractureDynamicsWorld::fractureCallback( ) // printf("strong impact\n"); - //@todo: add better logic to decide what parts to fracture //For example use the idea from the SIGGRAPH talk about the fracture in the movie 2012: // //Breaking thresholds can be stored as connectivity information between child shapes in the fracture object // - //You can calculate some "impact value" by simulating all the individual child shapes - //as rigid bodies, without constraints, running it in a separate simulation world + //You can calculate some "impact value" by simulating all the individual child shapes + //as rigid bodies, without constraints, running it in a separate simulation world //(or by running the constraint solver without actually modifying the dynamics world) //Then measure some "impact value" using the offset and applied impulse for each child shape - //weaken the connections based on this "impact value" and only break + //weaken the connections based on this "impact value" and only break //if this impact value exceeds the breaking threshold. //you can propagate the weakening and breaking of connections using the connectivity information @@ -524,68 +483,69 @@ void btFractureDynamicsWorld::fractureCallback( ) if (f0 == f1 == m_fractureBodies.size()) continue; - - if (f0getBody1(); - // btRigidBody* otherOb = btRigidBody::upcast(colOb); + // btCollisionObject* colOb = (btCollisionObject*)manifold->getBody1(); + // btRigidBody* otherOb = btRigidBody::upcast(colOb); // if (!otherOb->getInvMass()) // continue; - int pi=-1; + int pi = -1; - for (int p=0;pgetBody0(); //btRigidBody* otherOb = btRigidBody::upcast(colOb); // if (!otherOb->getInvMass()) // continue; + int pi = -1; - int pi=-1; - - for (int p=0;pgetCollisionShape()->isCompound()) { btTransform tr; tr.setIdentity(); btCompoundShape* oldCompound = (btCompoundShape*)sFracturePairs[i].m_fracObj->getCollisionShape(); - if (oldCompound->getNumChildShapes()>1) + if (oldCompound->getNumChildShapes() > 1) { bool needsBreakingCheck = false; - //weaken/break the connections //@todo: propagate along the connection graph - for (int j=0;jgetNumContacts();k++) + for (int k = 0; k < manifold->getNumContacts(); k++) { btManifoldPoint& pt = manifold->getContactPoint(k); - if (manifold->getBody0()==sFracturePairs[i].m_fracObj) + if (manifold->getBody0() == sFracturePairs[i].m_fracObj) { - for (int f=0;fm_connections.size();f++) + for (int f = 0; f < sFracturePairs[i].m_fracObj->m_connections.size(); f++) { btConnection& connection = sFracturePairs[i].m_fracObj->m_connections[f]; - if ( (connection.m_childIndex0 == pt.m_index0) || - (connection.m_childIndex1 == pt.m_index0) - ) + if ((connection.m_childIndex0 == pt.m_index0) || + (connection.m_childIndex1 == pt.m_index0)) { connection.m_strength -= pt.m_appliedImpulse; - if (connection.m_strength<0) + if (connection.m_strength < 0) { //remove or set to zero - connection.m_strength=0.f; + connection.m_strength = 0.f; needsBreakingCheck = true; } } } - } else + } + else { - for (int f=0;fm_connections.size();f++) + for (int f = 0; f < sFracturePairs[i].m_fracObj->m_connections.size(); f++) { btConnection& connection = sFracturePairs[i].m_fracObj->m_connections[f]; - if ( (connection.m_childIndex0 == pt.m_index1) || - (connection.m_childIndex1 == pt.m_index1) - ) + if ((connection.m_childIndex0 == pt.m_index1) || + (connection.m_childIndex1 == pt.m_index1)) { connection.m_strength -= pt.m_appliedImpulse; - if (connection.m_strength<0) + if (connection.m_strength < 0) { //remove or set to zero - connection.m_strength=0.f; + connection.m_strength = 0.f; needsBreakingCheck = true; } } @@ -676,13 +632,9 @@ void btFractureDynamicsWorld::fractureCallback( ) breakDisconnectedParts(sFracturePairs[i].m_fracObj); } } - } - } } sFracturePairs.clear(); - } - diff --git a/examples/FractureDemo/btFractureDynamicsWorld.h b/examples/FractureDemo/btFractureDynamicsWorld.h index 255487729..857f8ca04 100644 --- a/examples/FractureDemo/btFractureDynamicsWorld.h +++ b/examples/FractureDemo/btFractureDynamicsWorld.h @@ -8,44 +8,40 @@ class btFractureBody; class btCompoundShape; class btTransform; - -///The btFractureDynamicsWorld class enabled basic glue and fracture of objects. +///The btFractureDynamicsWorld class enabled basic glue and fracture of objects. ///If/once this implementation is stablized/tested we might merge it into btDiscreteDynamicsWorld and remove the class. class btFractureDynamicsWorld : public btDiscreteDynamicsWorld { btAlignedObjectArray m_fractureBodies; - bool m_fracturingMode; + bool m_fracturingMode; - btFractureBody* addNewBody(const btTransform& oldTransform,btScalar* masses, btCompoundShape* oldCompound); + btFractureBody* addNewBody(const btTransform& oldTransform, btScalar* masses, btCompoundShape* oldCompound); - void breakDisconnectedParts( btFractureBody* fracObj); + void breakDisconnectedParts(btFractureBody* fracObj); public: + btFractureDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration); - btFractureDynamicsWorld ( btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration); + virtual void addRigidBody(btRigidBody* body); - virtual void addRigidBody(btRigidBody* body); + virtual void removeRigidBody(btRigidBody* body); - virtual void removeRigidBody(btRigidBody* body); - - void solveConstraints(btContactSolverInfo& solverInfo); + void solveConstraints(btContactSolverInfo& solverInfo); ///either fracture or glue (!fracture) - void setFractureMode(bool fracture) + void setFractureMode(bool fracture) { m_fracturingMode = fracture; } - bool getFractureMode() const { return m_fracturingMode;} + bool getFractureMode() const { return m_fracturingMode; } ///normally those callbacks are called internally by the 'solveConstraints' void glueCallback(); ///normally those callbacks are called internally by the 'solveConstraints' void fractureCallback(); - }; -#endif //_BT_FRACTURE_DYNAMICS_WORLD_H - +#endif //_BT_FRACTURE_DYNAMICS_WORLD_H diff --git a/examples/GyroscopicDemo/GyroscopicSetup.cpp b/examples/GyroscopicDemo/GyroscopicSetup.cpp index 5ef115678..1324fb74f 100644 --- a/examples/GyroscopicDemo/GyroscopicSetup.cpp +++ b/examples/GyroscopicDemo/GyroscopicSetup.cpp @@ -1,13 +1,9 @@ #include "GyroscopicSetup.h" - - #include "../CommonInterfaces/CommonRigidBodyBase.h" - struct GyroscopicSetup : public CommonRigidBodyBase { - GyroscopicSetup(struct GUIHelperInterface* helper); virtual ~GyroscopicSetup() @@ -15,7 +11,6 @@ struct GyroscopicSetup : public CommonRigidBodyBase } virtual void initPhysics(); - virtual void physicsDebugDraw(int debugFlags); void resetCamera() @@ -23,32 +18,26 @@ struct GyroscopicSetup : public CommonRigidBodyBase float dist = 20; float pitch = -16; float yaw = 180; - float targetPos[3]={-2.4,0.4,-0.24}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {-2.4, 0.4, -0.24}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } - }; - static int gyroflags[4] = { - 0,//none, no gyroscopic term - BT_ENABLE_GYROSCOPIC_FORCE_EXPLICIT, - BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD, - BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY -}; + 0, //none, no gyroscopic term + BT_ENABLE_GYROSCOPIC_FORCE_EXPLICIT, + BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD, + BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY}; static const char* gyroNames[4] = { - "No Gyroscopic", - "Explicit", - "Implicit (World)", - "Implicit (Body)" -}; - + "No Gyroscopic", + "Explicit", + "Implicit (World)", + "Implicit (Body)"}; GyroscopicSetup::GyroscopicSetup(struct GUIHelperInterface* helper) -:CommonRigidBodyBase(helper) + : CommonRigidBodyBase(helper) { - } void GyroscopicSetup::initPhysics() @@ -58,81 +47,76 @@ void GyroscopicSetup::initPhysics() m_dynamicsWorld->setGravity(btVector3(0, 0, 0)); m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); - btVector3 positions[4] = { - btVector3( -10, 8,4), - btVector3( -5, 8,4), - btVector3( 0, 8,4), - btVector3( 5, 8,4), + btVector3(-10, 8, 4), + btVector3(-5, 8, 4), + btVector3(0, 8, 4), + btVector3(5, 8, 4), }; - - for (int i = 0; i<4; i++) + for (int i = 0; i < 4; i++) { - btCylinderShapeZ* pin = new btCylinderShapeZ(btVector3(0.1,0.1, 0.2)); - btBoxShape* box = new btBoxShape(btVector3(1,0.1,0.1)); + btCylinderShapeZ* pin = new btCylinderShapeZ(btVector3(0.1, 0.1, 0.2)); + btBoxShape* box = new btBoxShape(btVector3(1, 0.1, 0.1)); box->setMargin(0.01); pin->setMargin(0.01); btCompoundShape* compound = new btCompoundShape(); compound->addChildShape(btTransform::getIdentity(), pin); - btTransform offsetBox(btMatrix3x3::getIdentity(),btVector3(0,0,0.2)); + btTransform offsetBox(btMatrix3x3::getIdentity(), btVector3(0, 0, 0.2)); compound->addChildShape(offsetBox, box); - btScalar masses[2] = {0.3,0.1}; + btScalar masses[2] = {0.3, 0.1}; btVector3 localInertia; btTransform principal; - compound->calculatePrincipalAxisTransform(masses,principal,localInertia); - + compound->calculatePrincipalAxisTransform(masses, principal, localInertia); + btRigidBody* body = new btRigidBody(1, 0, compound, localInertia); btTransform tr; tr.setIdentity(); tr.setOrigin(positions[i]); body->setCenterOfMassTransform(tr); - body->setAngularVelocity(btVector3(0, 0.1, 10));//51)); + body->setAngularVelocity(btVector3(0, 0.1, 10)); //51)); //body->setLinearVelocity(btVector3(3, 0, 0)); body->setFriction(btSqrt(1)); m_dynamicsWorld->addRigidBody(body); body->setFlags(gyroflags[i]); m_dynamicsWorld->getSolverInfo().m_maxGyroscopicForce = 10.f; body->setDamping(0.0000f, 0.000f); - - } - { - //btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(0.5))); - btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0, 1, 0), 0); - - m_collisionShapes.push_back(groundShape); - btTransform groundTransform; - groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0, 0, 0)); - btRigidBody* groundBody; - groundBody = createRigidBody(0, groundTransform, groundShape); - groundBody->setFriction(btSqrt(2)); - } + { + //btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(0.5))); + btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0, 1, 0), 0); + + m_collisionShapes.push_back(groundShape); + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0, 0, 0)); + btRigidBody* groundBody; + groundBody = createRigidBody(0, groundTransform, groundShape); + groundBody->setFriction(btSqrt(2)); + } m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } void GyroscopicSetup::physicsDebugDraw(int debugFlags) { CommonRigidBodyBase::physicsDebugDraw(debugFlags); - - //render method names above objects - for (int i=0;igetNumCollisionObjects();i++) - { - btRigidBody* body = btRigidBody::upcast(m_dynamicsWorld->getCollisionObjectArray()[i]); - if (body && body->getInvMass()>0) - { - btTransform tr = body->getWorldTransform(); - btVector3 pos = tr.getOrigin()+btVector3(0,0,2); - btScalar size=1; - m_guiHelper->drawText3D(gyroNames[i],pos.x(),pos.y(),pos.z(),size); - } - } + + //render method names above objects + for (int i = 0; i < m_dynamicsWorld->getNumCollisionObjects(); i++) + { + btRigidBody* body = btRigidBody::upcast(m_dynamicsWorld->getCollisionObjectArray()[i]); + if (body && body->getInvMass() > 0) + { + btTransform tr = body->getWorldTransform(); + btVector3 pos = tr.getOrigin() + btVector3(0, 0, 2); + btScalar size = 1; + m_guiHelper->drawText3D(gyroNames[i], pos.x(), pos.y(), pos.z(), size); + } + } } - -class CommonExampleInterface* GyroscopicCreateFunc(CommonExampleOptions& options) +class CommonExampleInterface* GyroscopicCreateFunc(CommonExampleOptions& options) { return new GyroscopicSetup(options.m_guiHelper); } diff --git a/examples/GyroscopicDemo/GyroscopicSetup.h b/examples/GyroscopicDemo/GyroscopicSetup.h index 94cad4169..a53781436 100644 --- a/examples/GyroscopicDemo/GyroscopicSetup.h +++ b/examples/GyroscopicDemo/GyroscopicSetup.h @@ -2,6 +2,6 @@ #ifndef GYROSCOPIC_SETUP_H #define GYROSCOPIC_SETUP_H -class CommonExampleInterface* GyroscopicCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* GyroscopicCreateFunc(struct CommonExampleOptions& options); -#endif //GYROSCOPIC_SETUP_H +#endif //GYROSCOPIC_SETUP_H diff --git a/examples/Importers/ImportBsp/BspConverter.cpp b/examples/Importers/ImportBsp/BspConverter.cpp index 8d750c32a..dcf414018 100644 --- a/examples/Importers/ImportBsp/BspConverter.cpp +++ b/examples/Importers/ImportBsp/BspConverter.cpp @@ -20,60 +20,55 @@ subject to the following restrictions: #include #include - -void BspConverter::convertBsp(BspLoader& bspLoader,float scaling) +void BspConverter::convertBsp(BspLoader& bspLoader, float scaling) { { - - float playstartf[3] = {0,0,100}; + float playstartf[3] = {0, 0, 100}; - if (bspLoader.findVectorByName(&playstartf[0],"info_player_start")) + if (bspLoader.findVectorByName(&playstartf[0], "info_player_start")) { printf("found playerstart\n"); - } + } else { - if (bspLoader.findVectorByName(&playstartf[0],"info_player_deathmatch")) + if (bspLoader.findVectorByName(&playstartf[0], "info_player_deathmatch")) { printf("found deatchmatch start\n"); } } - btVector3 playerStart (playstartf[0],playstartf[1],playstartf[2]); + btVector3 playerStart(playstartf[0], playstartf[1], playstartf[2]); - - playerStart[2] += 20.f; //start a bit higher + playerStart[2] += 20.f; //start a bit higher playerStart *= scaling; - - //progressBegin("Loading bsp"); - for (int i=0;i planeEquations; - - int brushid = bspLoader.m_dleafbrushes[leaf.firstLeafBrush+b]; + + int brushid = bspLoader.m_dleafbrushes[leaf.firstLeafBrush + b]; BSPBrush& brush = bspLoader.m_dbrushes[brushid]; - if (brush.shaderNum!=-1) + if (brush.shaderNum != -1) { - if (bspLoader.m_dshaders[ brush.shaderNum ].contentFlags & BSPCONTENTS_SOLID) + if (bspLoader.m_dshaders[brush.shaderNum].contentFlags & BSPCONTENTS_SOLID) { brush.shaderNum = -1; - for (int p=0;p vertices; + btGeometryUtil::getVerticesFromPlaneEquations(planeEquations, vertices); - btAlignedObjectArray vertices; - btGeometryUtil::getVerticesFromPlaneEquations(planeEquations,vertices); - bool isEntity = false; - btVector3 entityTarget(0.f,0.f,0.f); - addConvexVerticesCollider(vertices,isEntity,entityTarget); - + btVector3 entityTarget(0.f, 0.f, 0.f); + addConvexVerticesCollider(vertices, isEntity, entityTarget); } } - } + } } } #define USE_ENTITIES #ifdef USE_ENTITIES - { int i; - for (i=0;i= 0) && (modelnr < bspLoader.m_nummodels)) { - int modelnr = atoi(&cl[1]); - if ((modelnr >=0) && (modelnr < bspLoader.m_nummodels)) + const BSPModel& model = bspLoader.m_dmodels[modelnr]; + for (int n = 0; n < model.numBrushes; n++) { - const BSPModel& model = bspLoader.m_dmodels[modelnr]; - for (int n=0;n planeEquations; + bool isValidBrush = false; + + //convert brush + const BSPBrush& brush = bspLoader.m_dbrushes[model.firstBrush + n]; { - btAlignedObjectArray planeEquations; - bool isValidBrush = false; - - //convert brush - const BSPBrush& brush = bspLoader.m_dbrushes[model.firstBrush+n]; + for (int p = 0; p < brush.numSides; p++) { - for (int p=0;p vertices; - btGeometryUtil::getVerticesFromPlaneEquations(planeEquations,vertices); - - bool isEntity=true; - addConvexVerticesCollider(vertices,isEntity,targetLocation); - - } + int sideid = brush.firstSide + p; + BSPBrushSide& brushside = bspLoader.m_dbrushsides[sideid]; + int planeid = brushside.planeNum; + BSPPlane& plane = bspLoader.m_dplanes[planeid]; + btVector3 planeEq; + planeEq.setValue( + plane.normal[0], + plane.normal[1], + plane.normal[2]); + planeEq[3] = scaling * -plane.dist; + planeEquations.push_back(planeEq); + isValidBrush = true; } + if (isValidBrush) + { + btAlignedObjectArray vertices; + btGeometryUtil::getVerticesFromPlaneEquations(planeEquations, vertices); + bool isEntity = true; + addConvexVerticesCollider(vertices, isEntity, targetLocation); + } } } - } - else - { - printf("unsupported trigger_push model, md3 ?\n"); } } - + else + { + printf("unsupported trigger_push model, md3 ?\n"); + } } } } } - -#endif //USE_ENTITIES + } - +#endif //USE_ENTITIES //progressEnd(); - } - } - - - - - - +} diff --git a/examples/Importers/ImportBsp/BspConverter.h b/examples/Importers/ImportBsp/BspConverter.h index aca44db27..20faae66d 100644 --- a/examples/Importers/ImportBsp/BspConverter.h +++ b/examples/Importers/ImportBsp/BspConverter.h @@ -23,17 +23,14 @@ class BspLoader; ///BspConverter turns a loaded bsp level into convex parts (vertices) class BspConverter { - public: - - void convertBsp(BspLoader& bspLoader,float scaling); - virtual ~BspConverter() - { - } - - ///this callback is called for each brush that succesfully converted into vertices - virtual void addConvexVerticesCollider(btAlignedObjectArray& vertices, bool isEntity, const btVector3& entityTargetLocation) = 0; +public: + void convertBsp(BspLoader& bspLoader, float scaling); + virtual ~BspConverter() + { + } + ///this callback is called for each brush that succesfully converted into vertices + virtual void addConvexVerticesCollider(btAlignedObjectArray& vertices, bool isEntity, const btVector3& entityTargetLocation) = 0; }; -#endif //BSP_CONVERTER_H - +#endif //BSP_CONVERTER_H diff --git a/examples/Importers/ImportBsp/BspLoader.cpp b/examples/Importers/ImportBsp/BspLoader.cpp index 0572463ae..140294e1a 100644 --- a/examples/Importers/ImportBsp/BspLoader.cpp +++ b/examples/Importers/ImportBsp/BspLoader.cpp @@ -20,26 +20,25 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ - #include "BspLoader.h" #include #include typedef struct { - char filename[1024]; - char *buffer,*script_p,*end_p; - int line; + char filename[1024]; + char *buffer, *script_p, *end_p; + int line; } BSPScript; -#define MAX_INCLUDES 8 -BSPScript scriptstack[MAX_INCLUDES]; -BSPScript *script; -int scriptline; +#define MAX_INCLUDES 8 +BSPScript scriptstack[MAX_INCLUDES]; +BSPScript *script; +int scriptline; -char token[BSPMAXTOKEN]; +char token[BSPMAXTOKEN]; bool endofscript; -bool tokenready; // only true if UnGetToken was just called +bool tokenready; // only true if UnGetToken was just called // //loadBSPFile @@ -48,143 +47,137 @@ bool tokenready; // only true if UnGetToken was just called int extrasize = 100; BspLoader::BspLoader() - :m_num_entities(0) + : m_num_entities(0) { m_Endianness = getMachineEndianness(); if (m_Endianness == BSP_BIG_ENDIAN) { printf("Machine is BIG_ENDIAN\n"); - } else + } + else { printf("Machine is Little Endian\n"); } } - -bool BspLoader::loadBSPFile( void* memoryBuffer) { - - BSPHeader *header = (BSPHeader*) memoryBuffer; +bool BspLoader::loadBSPFile(void *memoryBuffer) +{ + BSPHeader *header = (BSPHeader *)memoryBuffer; // load the file header if (header) { // swap the header - swapBlock( (int *)header, sizeof(*header) ); - + swapBlock((int *)header, sizeof(*header)); + int length = (header->lumps[BSPLUMP_SHADERS].filelen) / sizeof(BSPShader); - m_dshaders.resize(length+extrasize); - m_numShaders = copyLump( header, BSPLUMP_SHADERS, &m_dshaders[0], sizeof(BSPShader) ); + m_dshaders.resize(length + extrasize); + m_numShaders = copyLump(header, BSPLUMP_SHADERS, &m_dshaders[0], sizeof(BSPShader)); length = (header->lumps[LUMP_MODELS].filelen) / sizeof(BSPModel); - m_dmodels.resize(length+extrasize); - m_nummodels = copyLump( header, LUMP_MODELS, &m_dmodels[0], sizeof(BSPModel) ); + m_dmodels.resize(length + extrasize); + m_nummodels = copyLump(header, LUMP_MODELS, &m_dmodels[0], sizeof(BSPModel)); length = (header->lumps[BSPLUMP_PLANES].filelen) / sizeof(BSPPlane); - m_dplanes.resize(length+extrasize); - m_numplanes = copyLump( header, BSPLUMP_PLANES, &m_dplanes[0], sizeof(BSPPlane) ); + m_dplanes.resize(length + extrasize); + m_numplanes = copyLump(header, BSPLUMP_PLANES, &m_dplanes[0], sizeof(BSPPlane)); length = (header->lumps[BSPLUMP_LEAFS].filelen) / sizeof(BSPLeaf); - m_dleafs.resize(length+extrasize); - m_numleafs = copyLump( header, BSPLUMP_LEAFS, &m_dleafs[0], sizeof(BSPLeaf) ); + m_dleafs.resize(length + extrasize); + m_numleafs = copyLump(header, BSPLUMP_LEAFS, &m_dleafs[0], sizeof(BSPLeaf)); length = (header->lumps[BSPLUMP_NODES].filelen) / sizeof(BSPNode); - m_dnodes.resize(length+extrasize); - m_numnodes = copyLump( header, BSPLUMP_NODES, &m_dnodes[0], sizeof(BSPNode) ); + m_dnodes.resize(length + extrasize); + m_numnodes = copyLump(header, BSPLUMP_NODES, &m_dnodes[0], sizeof(BSPNode)); length = (header->lumps[BSPLUMP_LEAFSURFACES].filelen) / sizeof(m_dleafsurfaces[0]); - m_dleafsurfaces.resize(length+extrasize); - m_numleafsurfaces = copyLump( header, BSPLUMP_LEAFSURFACES, &m_dleafsurfaces[0], sizeof(m_dleafsurfaces[0]) ); + m_dleafsurfaces.resize(length + extrasize); + m_numleafsurfaces = copyLump(header, BSPLUMP_LEAFSURFACES, &m_dleafsurfaces[0], sizeof(m_dleafsurfaces[0])); - length = (header->lumps[BSPLUMP_LEAFBRUSHES].filelen) / sizeof(m_dleafbrushes[0]) ; - m_dleafbrushes.resize(length+extrasize); - m_numleafbrushes = copyLump( header, BSPLUMP_LEAFBRUSHES, &m_dleafbrushes[0], sizeof(m_dleafbrushes[0]) ); + length = (header->lumps[BSPLUMP_LEAFBRUSHES].filelen) / sizeof(m_dleafbrushes[0]); + m_dleafbrushes.resize(length + extrasize); + m_numleafbrushes = copyLump(header, BSPLUMP_LEAFBRUSHES, &m_dleafbrushes[0], sizeof(m_dleafbrushes[0])); length = (header->lumps[LUMP_BRUSHES].filelen) / sizeof(BSPBrush); - m_dbrushes.resize(length+extrasize); - m_numbrushes = copyLump( header, LUMP_BRUSHES, &m_dbrushes[0], sizeof(BSPBrush) ); - + m_dbrushes.resize(length + extrasize); + m_numbrushes = copyLump(header, LUMP_BRUSHES, &m_dbrushes[0], sizeof(BSPBrush)); length = (header->lumps[LUMP_BRUSHSIDES].filelen) / sizeof(BSPBrushSide); - m_dbrushsides.resize(length+extrasize); - m_numbrushsides = copyLump( header, LUMP_BRUSHSIDES, &m_dbrushsides[0], sizeof(BSPBrushSide) ); + m_dbrushsides.resize(length + extrasize); + m_numbrushsides = copyLump(header, LUMP_BRUSHSIDES, &m_dbrushsides[0], sizeof(BSPBrushSide)); - length = (header->lumps[LUMP_SURFACES].filelen) / sizeof(BSPSurface); - m_drawSurfaces.resize(length+extrasize); - m_numDrawSurfaces = copyLump( header, LUMP_SURFACES, &m_drawSurfaces[0], sizeof(BSPSurface) ); - + m_drawSurfaces.resize(length + extrasize); + m_numDrawSurfaces = copyLump(header, LUMP_SURFACES, &m_drawSurfaces[0], sizeof(BSPSurface)); length = (header->lumps[LUMP_DRAWINDEXES].filelen) / sizeof(m_drawIndexes[0]); - m_drawIndexes.resize(length+extrasize); - m_numDrawIndexes = copyLump( header, LUMP_DRAWINDEXES, &m_drawIndexes[0], sizeof(m_drawIndexes[0]) ); + m_drawIndexes.resize(length + extrasize); + m_numDrawIndexes = copyLump(header, LUMP_DRAWINDEXES, &m_drawIndexes[0], sizeof(m_drawIndexes[0])); length = (header->lumps[LUMP_VISIBILITY].filelen) / 1; - m_visBytes.resize(length+extrasize); - m_numVisBytes = copyLump( header, LUMP_VISIBILITY, &m_visBytes[0], 1 ); + m_visBytes.resize(length + extrasize); + m_numVisBytes = copyLump(header, LUMP_VISIBILITY, &m_visBytes[0], 1); length = (header->lumps[LUMP_LIGHTMAPS].filelen) / 1; - m_lightBytes.resize(length+extrasize); - m_numLightBytes = copyLump( header, LUMP_LIGHTMAPS, &m_lightBytes[0], 1 ); + m_lightBytes.resize(length + extrasize); + m_numLightBytes = copyLump(header, LUMP_LIGHTMAPS, &m_lightBytes[0], 1); length = (header->lumps[BSPLUMP_ENTITIES].filelen) / 1; - m_dentdata.resize(length+extrasize); - m_entdatasize = copyLump( header, BSPLUMP_ENTITIES, &m_dentdata[0], 1); + m_dentdata.resize(length + extrasize); + m_entdatasize = copyLump(header, BSPLUMP_ENTITIES, &m_dentdata[0], 1); length = (header->lumps[LUMP_LIGHTGRID].filelen) / 1; - m_gridData.resize(length+extrasize); - m_numGridPoints = copyLump( header, LUMP_LIGHTGRID, &m_gridData[0], 8 ); + m_gridData.resize(length + extrasize); + m_numGridPoints = copyLump(header, LUMP_LIGHTGRID, &m_gridData[0], 8); // swap everything swapBSPFile(); return true; - } return false; } +const char *BspLoader::getValueForKey(const BSPEntity *ent, const char *key) const +{ + const BSPKeyValuePair *ep; - -const char* BspLoader::getValueForKey( const BSPEntity* ent, const char* key ) const { - - const BSPKeyValuePair* ep; - - for (ep=ent->epairs ; ep ; ep=ep->next) { - if (!strcmp(ep->key, key) ) { + for (ep = ent->epairs; ep; ep = ep->next) + { + if (!strcmp(ep->key, key)) + { return ep->value; } } return ""; } -float BspLoader::getFloatForKey( const BSPEntity *ent, const char *key ) { - const char *k; - - k = getValueForKey( ent, key ); +float BspLoader::getFloatForKey(const BSPEntity *ent, const char *key) +{ + const char *k; + + k = getValueForKey(ent, key); return float(atof(k)); } -bool BspLoader::getVectorForKey( const BSPEntity *ent, const char *key, BSPVector3 vec ) { - - const char *k; - k = getValueForKey (ent, key); +bool BspLoader::getVectorForKey(const BSPEntity *ent, const char *key, BSPVector3 vec) +{ + const char *k; + k = getValueForKey(ent, key); if (strcmp(k, "")) { - sscanf (k, "%f %f %f", &vec[0], &vec[1], &vec[2]); + sscanf(k, "%f %f %f", &vec[0], &vec[1], &vec[2]); return true; } return false; } - - - /* ============== parseFromMemory ============== */ -void BspLoader::parseFromMemory (char *buffer, int size) +void BspLoader::parseFromMemory(char *buffer, int size) { script = scriptstack; script++; @@ -192,7 +185,7 @@ void BspLoader::parseFromMemory (char *buffer, int size) { //printf("script file exceeded MAX_INCLUDES"); } - strcpy (script->filename, "memory buffer" ); + strcpy(script->filename, "memory buffer"); script->buffer = buffer; script->line = 1; @@ -203,20 +196,19 @@ void BspLoader::parseFromMemory (char *buffer, int size) tokenready = false; } - -bool BspLoader::isEndOfScript (bool crossline) +bool BspLoader::isEndOfScript(bool crossline) { if (!crossline) //printf("Line %i is incomplete\n",scriptline); - if (!strcmp (script->filename, "memory buffer")) - { - endofscript = true; - return false; - } + if (!strcmp(script->filename, "memory buffer")) + { + endofscript = true; + return false; + } //free (script->buffer); - if (script == scriptstack+1) + if (script == scriptstack + 1) { endofscript = true; return false; @@ -224,7 +216,7 @@ bool BspLoader::isEndOfScript (bool crossline) script--; scriptline = script->line; //printf ("returning to %s\n", script->filename); - return getToken (crossline); + return getToken(crossline); } /* @@ -233,18 +225,18 @@ bool BspLoader::isEndOfScript (bool crossline) getToken ============== */ -bool BspLoader::getToken (bool crossline) +bool BspLoader::getToken(bool crossline) { - char *token_p; + char *token_p; - if (tokenready) // is a token allready waiting? + if (tokenready) // is a token allready waiting? { tokenready = false; return true; } if (script->script_p >= script->end_p) - return isEndOfScript (crossline); + return isEndOfScript(crossline); // // skip space @@ -253,7 +245,7 @@ skipspace: while (*script->script_p <= 32) { if (script->script_p >= script->end_p) - return isEndOfScript (crossline); + return isEndOfScript(crossline); if (*script->script_p++ == '\n') { if (!crossline) @@ -265,11 +257,10 @@ skipspace: } if (script->script_p >= script->end_p) - return isEndOfScript (crossline); + return isEndOfScript(crossline); // ; # // comments - if (*script->script_p == ';' || *script->script_p == '#' - || ( script->script_p[0] == '/' && script->script_p[1] == '/') ) + if (*script->script_p == ';' || *script->script_p == '#' || (script->script_p[0] == '/' && script->script_p[1] == '/')) { if (!crossline) { @@ -277,7 +268,7 @@ skipspace: } while (*script->script_p++ != '\n') if (script->script_p >= script->end_p) - return isEndOfScript (crossline); + return isEndOfScript(crossline); scriptline = script->line++; goto skipspace; } @@ -289,23 +280,24 @@ skipspace: { //printf("Line %i is incomplete\n",scriptline); } - script->script_p+=2; + script->script_p += 2; while (script->script_p[0] != '*' && script->script_p[1] != '/') { - if ( *script->script_p == '\n' ) { + if (*script->script_p == '\n') + { scriptline = script->line++; } script->script_p++; if (script->script_p >= script->end_p) - return isEndOfScript (crossline); + return isEndOfScript(crossline); } script->script_p += 2; goto skipspace; } -// -// copy token -// + // + // copy token + // token_p = token; if (*script->script_p == '"') @@ -324,25 +316,25 @@ skipspace: } script->script_p++; } - else // regular token - while ( *script->script_p > 32 && *script->script_p != ';') - { - *token_p++ = *script->script_p++; - if (script->script_p == script->end_p) - break; - if (token_p == &token[BSPMAXTOKEN]) + else // regular token + while (*script->script_p > 32 && *script->script_p != ';') { - //printf ("Token too large on line %i\n",scriptline); + *token_p++ = *script->script_p++; + if (script->script_p == script->end_p) + break; + if (token_p == &token[BSPMAXTOKEN]) + { + //printf ("Token too large on line %i\n",scriptline); + } } - } *token_p = 0; - if (!strcmp (token, "$include")) + if (!strcmp(token, "$include")) { //getToken (false); //AddScriptToStack (token); - return false;//getToken (crossline); + return false; //getToken (crossline); } return true; @@ -350,16 +342,17 @@ skipspace: char *BspLoader::copystring(const char *s) { - char *b; - b = (char*) malloc( strlen(s)+1); - strcpy (b, s); + char *b; + b = (char *)malloc(strlen(s) + 1); + strcpy(b, s); return b; } -void BspLoader::stripTrailing( char *e ) { - char *s; +void BspLoader::stripTrailing(char *e) +{ + char *s; - s = e + strlen(e)-1; + s = e + strlen(e) - 1; while (s >= e && *s <= 32) { *s = 0; @@ -371,47 +364,50 @@ void BspLoader::stripTrailing( char *e ) { parseEpair ================= */ -BSPKeyValuePair *BspLoader::parseEpair( void ) { - BSPKeyValuePair *e; +BSPKeyValuePair *BspLoader::parseEpair(void) +{ + BSPKeyValuePair *e; - e = (struct BSPPair*) malloc( sizeof(BSPKeyValuePair)); - memset( e, 0, sizeof(BSPKeyValuePair) ); - - if ( strlen(token) >= BSPMAX_KEY-1 ) { + e = (struct BSPPair *)malloc(sizeof(BSPKeyValuePair)); + memset(e, 0, sizeof(BSPKeyValuePair)); + + if (strlen(token) >= BSPMAX_KEY - 1) + { //printf ("ParseEpar: token too long"); } - e->key = copystring( token ); - getToken( false ); - if ( strlen(token) >= BSPMAX_VALUE-1 ) { - + e->key = copystring(token); + getToken(false); + if (strlen(token) >= BSPMAX_VALUE - 1) + { //printf ("ParseEpar: token too long"); } - e->value = copystring( token ); + e->value = copystring(token); // strip trailing spaces that sometimes get accidentally // added in the editor - stripTrailing( e->key ); - stripTrailing( e->value ); + stripTrailing(e->key); + stripTrailing(e->value); return e; } - /* ================ parseEntity ================ */ -bool BspLoader::parseEntity( void ) { - BSPKeyValuePair *e; - BSPEntity *mapent; +bool BspLoader::parseEntity(void) +{ + BSPKeyValuePair *e; + BSPEntity *mapent; - if ( !getToken (true) ) { + if (!getToken(true)) + { return false; } - if ( strcmp (token, "{") ) { - + if (strcmp(token, "{")) + { //printf ("parseEntity: { not found"); } @@ -425,21 +421,24 @@ bool BspLoader::parseEntity( void ) { bla.patches = 0; m_entities.push_back(bla); - mapent = &m_entities[m_entities.size()-1]; + mapent = &m_entities[m_entities.size() - 1]; m_num_entities++; - do { - if ( !getToken (true) ) { + do + { + if (!getToken(true)) + { //printf("parseEntity: EOF without closing brace"); } - if ( !strcmp (token, "}") ) { + if (!strcmp(token, "}")) + { break; } - e = (struct BSPPair*)parseEpair (); + e = (struct BSPPair *)parseEpair(); e->next = mapent->epairs; mapent->epairs = e; } while (1); - + return true; } @@ -450,113 +449,108 @@ parseEntities Parses the dentdata string into entities ================ */ -void BspLoader::parseEntities( void ) { +void BspLoader::parseEntities(void) +{ m_num_entities = 0; m_entities.clear(); - parseFromMemory( &m_dentdata[0], m_entdatasize ); + parseFromMemory(&m_dentdata[0], m_entdatasize); - while ( parseEntity () ) { - } + while (parseEntity()) + { + } } - - int BspLoader::getMachineEndianness() { - long int i = 1; - const char *p = (const char *) &i; - if (p[0] == 1) // Lowest address contains the least significant byte - return BSP_LITTLE_ENDIAN; - else - return BSP_BIG_ENDIAN; + long int i = 1; + const char *p = (const char *)&i; + if (p[0] == 1) // Lowest address contains the least significant byte + return BSP_LITTLE_ENDIAN; + else + return BSP_BIG_ENDIAN; } -short BspLoader::isLittleShort (short l) +short BspLoader::isLittleShort(short l) { if (machineEndianness() == BSP_BIG_ENDIAN) { - unsigned char b1,b2; + unsigned char b1, b2; - b1 = l&255; - b2 = (l>>8)&255; + b1 = l & 255; + b2 = (l >> 8) & 255; - return (b1<<8) + b2; + return (b1 << 8) + b2; } //little endian return l; } -short BspLoader::isBigShort (short l) +short BspLoader::isBigShort(short l) { if (machineEndianness() == BSP_BIG_ENDIAN) { return l; } - unsigned char b1,b2; - - b1 = l&255; - b2 = (l>>8)&255; - - return (b1<<8) + b2; - + unsigned char b1, b2; + b1 = l & 255; + b2 = (l >> 8) & 255; + return (b1 << 8) + b2; } - -int BspLoader::isLittleLong (int l) +int BspLoader::isLittleLong(int l) { if (machineEndianness() == BSP_BIG_ENDIAN) { - unsigned char b1,b2,b3,b4; + unsigned char b1, b2, b3, b4; - b1 = l&255; - b2 = (l>>8)&255; - b3 = (l>>16)&255; - b4 = (l>>24)&255; + b1 = l & 255; + b2 = (l >> 8) & 255; + b3 = (l >> 16) & 255; + b4 = (l >> 24) & 255; - return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; + return ((int)b1 << 24) + ((int)b2 << 16) + ((int)b3 << 8) + b4; } //little endian return l; - } -int BspLoader::isBigLong (int l) +int BspLoader::isBigLong(int l) { if (machineEndianness() == BSP_BIG_ENDIAN) { return l; } + unsigned char b1, b2, b3, b4; - unsigned char b1,b2,b3,b4; - - b1 = l&255; - b2 = (l>>8)&255; - b3 = (l>>16)&255; - b4 = (l>>24)&255; - - return ((int)b1<<24) + ((int)b2<<16) + ((int)b3<<8) + b4; + b1 = l & 255; + b2 = (l >> 8) & 255; + b3 = (l >> 16) & 255; + b4 = (l >> 24) & 255; + return ((int)b1 << 24) + ((int)b2 << 16) + ((int)b3 << 8) + b4; } - -float BspLoader::isLittleFloat (float l) +float BspLoader::isLittleFloat(float l) { if (machineEndianness() == BSP_BIG_ENDIAN) { - union {unsigned char b[4]; float f;} in, out; - + union { + unsigned char b[4]; + float f; + } in, out; + in.f = l; out.b[0] = in.b[3]; out.b[1] = in.b[2]; out.b[2] = in.b[1]; out.b[3] = in.b[0]; - + return out.f; } @@ -564,40 +558,40 @@ float BspLoader::isLittleFloat (float l) return l; } -float BspLoader::isBigFloat (float l) +float BspLoader::isBigFloat(float l) { if (machineEndianness() == BSP_BIG_ENDIAN) { return l; } //little endian - union {unsigned char b[4]; float f;} in, out; - + union { + unsigned char b[4]; + float f; + } in, out; + in.f = l; out.b[0] = in.b[3]; out.b[1] = in.b[2]; out.b[2] = in.b[1]; out.b[3] = in.b[0]; - + return out.f; } - - - - - // // swapBlock // If all values are 32 bits, this can be used to swap everything // -void BspLoader::swapBlock( int *block, int sizeOfBlock ) { - int i; +void BspLoader::swapBlock(int *block, int sizeOfBlock) +{ + int i; sizeOfBlock >>= 2; - for ( i = 0 ; i < sizeOfBlock ; i++ ) { - block[i] = isLittleLong( block[i] ); + for (i = 0; i < sizeOfBlock; i++) + { + block[i] = isLittleLong(block[i]); } } @@ -605,99 +599,96 @@ void BspLoader::swapBlock( int *block, int sizeOfBlock ) { // copyLump // -int BspLoader::copyLump( BSPHeader *header, int lump, void *dest, int size ) { - int length, ofs; +int BspLoader::copyLump(BSPHeader *header, int lump, void *dest, int size) +{ + int length, ofs; length = header->lumps[lump].filelen; ofs = header->lumps[lump].fileofs; - + //if ( length % size ) { // printf ("loadBSPFile: odd lump size"); //} - memcpy( dest, (unsigned char *)header + ofs, length ); + memcpy(dest, (unsigned char *)header + ofs, length); return length / size; } - - - // // swapBSPFile // -void BspLoader::swapBSPFile( void ) { - int i; - - // models - swapBlock( (int *) &m_dmodels[0], m_nummodels * sizeof( m_dmodels[0] ) ); +void BspLoader::swapBSPFile(void) +{ + int i; + + // models + swapBlock((int *)&m_dmodels[0], m_nummodels * sizeof(m_dmodels[0])); // shaders (don't swap the name) - for ( i = 0 ; i < m_numShaders ; i++ ) { - m_dshaders[i].contentFlags = isLittleLong( m_dshaders[i].contentFlags ); - m_dshaders[i].surfaceFlags = isLittleLong( m_dshaders[i].surfaceFlags ); + for (i = 0; i < m_numShaders; i++) + { + m_dshaders[i].contentFlags = isLittleLong(m_dshaders[i].contentFlags); + m_dshaders[i].surfaceFlags = isLittleLong(m_dshaders[i].surfaceFlags); } // planes - swapBlock( (int *)&m_dplanes[0], m_numplanes * sizeof( m_dplanes[0] ) ); - + swapBlock((int *)&m_dplanes[0], m_numplanes * sizeof(m_dplanes[0])); + // nodes - swapBlock( (int *)&m_dnodes[0], m_numnodes * sizeof( m_dnodes[0] ) ); + swapBlock((int *)&m_dnodes[0], m_numnodes * sizeof(m_dnodes[0])); // leafs - swapBlock( (int *)&m_dleafs[0], m_numleafs * sizeof( m_dleafs[0] ) ); + swapBlock((int *)&m_dleafs[0], m_numleafs * sizeof(m_dleafs[0])); // leaffaces - swapBlock( (int *)&m_dleafsurfaces[0], m_numleafsurfaces * sizeof( m_dleafsurfaces[0] ) ); + swapBlock((int *)&m_dleafsurfaces[0], m_numleafsurfaces * sizeof(m_dleafsurfaces[0])); // leafbrushes - swapBlock( (int *)&m_dleafbrushes[0], m_numleafbrushes * sizeof( m_dleafbrushes[0] ) ); + swapBlock((int *)&m_dleafbrushes[0], m_numleafbrushes * sizeof(m_dleafbrushes[0])); // brushes - swapBlock( (int *)&m_dbrushes[0], m_numbrushes * sizeof( m_dbrushes[0] ) ); + swapBlock((int *)&m_dbrushes[0], m_numbrushes * sizeof(m_dbrushes[0])); // brushsides - swapBlock( (int *)&m_dbrushsides[0], m_numbrushsides * sizeof( m_dbrushsides[0] ) ); + swapBlock((int *)&m_dbrushsides[0], m_numbrushsides * sizeof(m_dbrushsides[0])); // vis - ((int *)&m_visBytes)[0] = isLittleLong( ((int *)&m_visBytes)[0] ); - ((int *)&m_visBytes)[1] = isLittleLong( ((int *)&m_visBytes)[1] ); - + ((int *)&m_visBytes)[0] = isLittleLong(((int *)&m_visBytes)[0]); + ((int *)&m_visBytes)[1] = isLittleLong(((int *)&m_visBytes)[1]); // drawindexes - swapBlock( (int *)&m_drawIndexes[0], m_numDrawIndexes * sizeof( m_drawIndexes[0] ) ); + swapBlock((int *)&m_drawIndexes[0], m_numDrawIndexes * sizeof(m_drawIndexes[0])); // drawsurfs - swapBlock( (int *)&m_drawSurfaces[0], m_numDrawSurfaces * sizeof( m_drawSurfaces[0] ) ); - + swapBlock((int *)&m_drawSurfaces[0], m_numDrawSurfaces * sizeof(m_drawSurfaces[0])); } - - - - -bool BspLoader::findVectorByName(float* outvec,const char* name) +bool BspLoader::findVectorByName(float *outvec, const char *name) { const char *cl; BSPVector3 origin; - + bool found = false; parseEntities(); - for ( int i = 1; i < m_num_entities; i++ ) { - cl = getValueForKey (&m_entities[i], "classname"); - if ( !strcmp( cl, "info_player_start" ) ) { - getVectorForKey( &m_entities[i], "origin", origin ); - found = true; - break; - } - if ( !strcmp( cl, "info_player_deathmatch" ) ) { - getVectorForKey( &m_entities[i], "origin", origin ); - found = true; - break; - } + for (int i = 1; i < m_num_entities; i++) + { + cl = getValueForKey(&m_entities[i], "classname"); + if (!strcmp(cl, "info_player_start")) + { + getVectorForKey(&m_entities[i], "origin", origin); + found = true; + break; + } + if (!strcmp(cl, "info_player_deathmatch")) + { + getVectorForKey(&m_entities[i], "origin", origin); + found = true; + break; + } } if (found) @@ -708,23 +699,21 @@ bool BspLoader::findVectorByName(float* outvec,const char* name) } return found; } - - -const BSPEntity * BspLoader::getEntityByValue( const char* name, const char* value) +const BSPEntity *BspLoader::getEntityByValue(const char *name, const char *value) { - const BSPEntity* entity = NULL; + const BSPEntity *entity = NULL; - for ( int i = 1; i < m_num_entities; i++ ) { + for (int i = 1; i < m_num_entities; i++) + { + const BSPEntity &ent = m_entities[i]; - const BSPEntity& ent = m_entities[i]; - - const char* cl = getValueForKey (&m_entities[i], name); - if ( !strcmp( cl, value ) ) { + const char *cl = getValueForKey(&m_entities[i], name); + if (!strcmp(cl, value)) + { entity = &ent; break; } } return entity; } - diff --git a/examples/Importers/ImportBsp/BspLoader.h b/examples/Importers/ImportBsp/BspLoader.h index b7fc302d7..b7089cc1f 100644 --- a/examples/Importers/ImportBsp/BspLoader.h +++ b/examples/Importers/ImportBsp/BspLoader.h @@ -20,276 +20,269 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ - - #ifndef BSP_LOADER_H #define BSP_LOADER_H #include "LinearMath/btAlignedObjectArray.h" -#define BSPMAXTOKEN 1024 -#define BSPMAX_KEY 32 -#define BSPMAX_VALUE 1024 -#define BSPCONTENTS_SOLID 1 -#define BSPCONTENTS_AREAPORTAL 0x8000 -#define BSPLUMP_ENTITIES 0 -#define BSPLUMP_SHADERS 1 -#define BSPLUMP_PLANES 2 -#define BSPLUMP_NODES 3 -#define BSPLUMP_LEAFS 4 -#define BSPLUMP_LEAFSURFACES 5 -#define BSPLUMP_LEAFBRUSHES 6 -#define LUMP_MODELS 7 -#define LUMP_BRUSHES 8 -#define LUMP_BRUSHSIDES 9 -#define LUMP_DRAWVERTS 10 -#define LUMP_DRAWINDEXES 11 -#define LUMP_SURFACES 13 -#define LUMP_LIGHTMAPS 14 -#define LUMP_LIGHTGRID 15 -#define LUMP_VISIBILITY 16 -#define HEADER_LUMPS 17 -#define MAX_QPATH 64 +#define BSPMAXTOKEN 1024 +#define BSPMAX_KEY 32 +#define BSPMAX_VALUE 1024 +#define BSPCONTENTS_SOLID 1 +#define BSPCONTENTS_AREAPORTAL 0x8000 +#define BSPLUMP_ENTITIES 0 +#define BSPLUMP_SHADERS 1 +#define BSPLUMP_PLANES 2 +#define BSPLUMP_NODES 3 +#define BSPLUMP_LEAFS 4 +#define BSPLUMP_LEAFSURFACES 5 +#define BSPLUMP_LEAFBRUSHES 6 +#define LUMP_MODELS 7 +#define LUMP_BRUSHES 8 +#define LUMP_BRUSHSIDES 9 +#define LUMP_DRAWVERTS 10 +#define LUMP_DRAWINDEXES 11 +#define LUMP_SURFACES 13 +#define LUMP_LIGHTMAPS 14 +#define LUMP_LIGHTGRID 15 +#define LUMP_VISIBILITY 16 +#define HEADER_LUMPS 17 +#define MAX_QPATH 64 - - -typedef struct { - int fileofs, filelen; +typedef struct +{ + int fileofs, filelen; } BSPLump; typedef float BSPVector3[3]; -typedef struct { - int ident; - int version; - - BSPLump lumps[HEADER_LUMPS]; +typedef struct +{ + int ident; + int version; + + BSPLump lumps[HEADER_LUMPS]; } BSPHeader; - -typedef struct { - float mins[3], maxs[3]; - int firstSurface, numSurfaces; - int firstBrush, numBrushes; +typedef struct +{ + float mins[3], maxs[3]; + int firstSurface, numSurfaces; + int firstBrush, numBrushes; } BSPModel; -typedef struct { - char shader[MAX_QPATH]; - int surfaceFlags; - int contentFlags; +typedef struct +{ + char shader[MAX_QPATH]; + int surfaceFlags; + int contentFlags; } BSPShader; -typedef struct { - float normal[3]; - float dist; +typedef struct +{ + float normal[3]; + float dist; } BSPPlane; -typedef struct { - int planeNum; - int children[2]; - int mins[3]; - int maxs[3]; +typedef struct +{ + int planeNum; + int children[2]; + int mins[3]; + int maxs[3]; } BSPNode; -typedef struct { - int cluster; - int area; - - int mins[3]; - int maxs[3]; - - int firstLeafSurface; - int numLeafSurfaces; - - int firstLeafBrush; - int numLeafBrushes; +typedef struct +{ + int cluster; + int area; + + int mins[3]; + int maxs[3]; + + int firstLeafSurface; + int numLeafSurfaces; + + int firstLeafBrush; + int numLeafBrushes; } BSPLeaf; -typedef struct { - int planeNum; - int shaderNum; +typedef struct +{ + int planeNum; + int shaderNum; } BSPBrushSide; -typedef struct { - int firstSide; - int numSides; - int shaderNum; +typedef struct +{ + int firstSide; + int numSides; + int shaderNum; } BSPBrush; - - - -typedef struct BSPPair { - struct BSPPair *next; - char *key; - char *value; +typedef struct BSPPair +{ + struct BSPPair *next; + char *key; + char *value; } BSPKeyValuePair; -typedef struct { - BSPVector3 origin; - struct bspbrush_s *brushes; - struct parseMesh_s *patches; - int firstDrawSurf; - BSPKeyValuePair *epairs; +typedef struct +{ + BSPVector3 origin; + struct bspbrush_s *brushes; + struct parseMesh_s *patches; + int firstDrawSurf; + BSPKeyValuePair *epairs; } BSPEntity; -typedef enum { +typedef enum +{ MST_BAD, - MST_PLANAR, - MST_PATCH, - MST_TRIANGLE_SOUP, - MST_FLARE + MST_PLANAR, + MST_PATCH, + MST_TRIANGLE_SOUP, + MST_FLARE } BSPMapSurface; -typedef struct { - int shaderNum; - int fogNum; - int surfaceType; - - int firstVert; - int numVerts; - - int firstIndex; - int numIndexes; - - int lightmapNum; - int lightmapX, lightmapY; - int lightmapWidth, lightmapHeight; - - BSPVector3 lightmapOrigin; - BSPVector3 lightmapVecs[3]; - - int patchWidth; - int patchHeight; +typedef struct +{ + int shaderNum; + int fogNum; + int surfaceType; + + int firstVert; + int numVerts; + + int firstIndex; + int numIndexes; + + int lightmapNum; + int lightmapX, lightmapY; + int lightmapWidth, lightmapHeight; + + BSPVector3 lightmapOrigin; + BSPVector3 lightmapVecs[3]; + + int patchWidth; + int patchHeight; } BSPSurface; - - ///GPL code from IdSofware to parse a Quake 3 BSP file ///check that your platform define __BIG_ENDIAN__ correctly (in BspLoader.cpp) class BspLoader { int m_Endianness; - public: +public: + BspLoader(); - BspLoader(); + bool loadBSPFile(void *memoryBuffer); - bool loadBSPFile( void* memoryBuffer); + const char *getValueForKey(const BSPEntity *ent, const char *key) const; - const char* getValueForKey( const BSPEntity *ent, const char *key ) const; + bool getVectorForKey(const BSPEntity *ent, const char *key, BSPVector3 vec); - bool getVectorForKey( const BSPEntity *ent, const char *key, BSPVector3 vec ); - - float getFloatForKey( const BSPEntity *ent, const char *key ); + float getFloatForKey(const BSPEntity *ent, const char *key); - void parseEntities( void ); + void parseEntities(void); - bool findVectorByName(float* outvec,const char* name); + bool findVectorByName(float *outvec, const char *name); - const BSPEntity * getEntityByValue( const char* name, const char* value); + const BSPEntity *getEntityByValue(const char *name, const char *value); +protected: + void parseFromMemory(char *buffer, int size); - protected: + bool isEndOfScript(bool crossline); - void parseFromMemory (char *buffer, int size); - + bool getToken(bool crossline); + char *copystring(const char *s); - bool isEndOfScript (bool crossline); + void stripTrailing(char *e); - bool getToken (bool crossline); + BSPKeyValuePair *parseEpair(void); - char *copystring(const char *s); - - void stripTrailing( char *e ); + bool parseEntity(void); - BSPKeyValuePair * parseEpair( void ); + short isLittleShort(short l); + int isLittleLong(int l); + float isLittleFloat(float l); - bool parseEntity( void ); + int isBigLong(int l); + short isBigShort(short l); + float isBigFloat(float l); - short isLittleShort (short l); - int isLittleLong (int l); - float isLittleFloat (float l); + void swapBlock(int *block, int sizeOfBlock); - int isBigLong (int l); - short isBigShort (short l); - float isBigFloat (float l); + int copyLump(BSPHeader *header, int lump, void *dest, int size); - void swapBlock( int *block, int sizeOfBlock ); + void swapBSPFile(void); - int copyLump( BSPHeader *header, int lump, void *dest, int size ); +public: //easier for conversion + int m_num_entities; + btAlignedObjectArray m_entities; - void swapBSPFile( void ); - - + int m_nummodels; + btAlignedObjectArray m_dmodels; - - public: //easier for conversion - int m_num_entities; - btAlignedObjectArray m_entities; - - int m_nummodels; - btAlignedObjectArray m_dmodels; + int m_numShaders; + btAlignedObjectArray m_dshaders; - int m_numShaders; - btAlignedObjectArray m_dshaders; + int m_entdatasize; + btAlignedObjectArray m_dentdata; - int m_entdatasize; - btAlignedObjectArray m_dentdata; + int m_numleafs; + btAlignedObjectArray m_dleafs; - int m_numleafs; - btAlignedObjectArray m_dleafs; + int m_numplanes; + btAlignedObjectArray m_dplanes; - int m_numplanes; - btAlignedObjectArray m_dplanes; + int m_numnodes; + btAlignedObjectArray m_dnodes; - int m_numnodes; - btAlignedObjectArray m_dnodes; + int m_numleafsurfaces; + btAlignedObjectArray m_dleafsurfaces; - int m_numleafsurfaces; - btAlignedObjectArray m_dleafsurfaces; + int m_numleafbrushes; + btAlignedObjectArray m_dleafbrushes; - int m_numleafbrushes; - btAlignedObjectArray m_dleafbrushes; + int m_numbrushes; + btAlignedObjectArray m_dbrushes; - int m_numbrushes; - btAlignedObjectArray m_dbrushes; + int m_numbrushsides; + btAlignedObjectArray m_dbrushsides; - int m_numbrushsides; - btAlignedObjectArray m_dbrushsides; + int m_numLightBytes; + btAlignedObjectArray m_lightBytes; - int m_numLightBytes; - btAlignedObjectArray m_lightBytes; + int m_numGridPoints; + btAlignedObjectArray m_gridData; - int m_numGridPoints; - btAlignedObjectArray m_gridData; + int m_numVisBytes; + btAlignedObjectArray m_visBytes; - int m_numVisBytes; - btAlignedObjectArray m_visBytes; + int m_numDrawIndexes; + btAlignedObjectArray m_drawIndexes; - - int m_numDrawIndexes; - btAlignedObjectArray m_drawIndexes; + int m_numDrawSurfaces; + btAlignedObjectArray m_drawSurfaces; - int m_numDrawSurfaces; - btAlignedObjectArray m_drawSurfaces; + enum + { + BSP_LITTLE_ENDIAN = 0, + BSP_BIG_ENDIAN = 1 + }; - enum - { - BSP_LITTLE_ENDIAN = 0, - BSP_BIG_ENDIAN = 1 - }; - - //returns machines big endian / little endian - // - int getMachineEndianness(); - - inline int machineEndianness() - { - return m_Endianness; - } + //returns machines big endian / little endian + // + int getMachineEndianness(); + inline int machineEndianness() + { + return m_Endianness; + } }; -#endif //BSP_LOADER_H +#endif //BSP_LOADER_H diff --git a/examples/Importers/ImportBsp/ImportBspExample.cpp b/examples/Importers/ImportBsp/ImportBspExample.cpp index 31b4cb41b..17d515865 100644 --- a/examples/Importers/ImportBsp/ImportBspExample.cpp +++ b/examples/Importers/ImportBsp/ImportBspExample.cpp @@ -19,198 +19,163 @@ subject to the following restrictions: #include "LinearMath/btQuickprof.h" - - - #define QUAKE_BSP_IMPORTING 1 #ifdef QUAKE_BSP_IMPORTING #include "BspLoader.h" #include "BspConverter.h" -#endif //QUAKE_BSP_IMPORTING - - -#include //printf debugging - - - - +#endif //QUAKE_BSP_IMPORTING +#include //printf debugging #include "LinearMath/btAlignedObjectArray.h" - - - #include "../CommonInterfaces/CommonRigidBodyBase.h" - ///BspDemo shows the convex collision detection, by converting a Quake BSP file into convex objects and allowing interaction with boxes. class BspDemo : public CommonRigidBodyBase { - public: - +public: //keep the collision shapes, for deletion/cleanup - BspDemo(struct GUIHelperInterface* helper) - :CommonRigidBodyBase(helper) + : CommonRigidBodyBase(helper) { } virtual ~BspDemo(); - virtual void initPhysics(); + virtual void initPhysics(); - void initPhysics(const char* bspfilename); + void initPhysics(const char* bspfilename); virtual void resetCamera() { float dist = 43; float pitch = -12; float yaw = -175; - float targetPos[3]={4,-25,-6}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {4, -25, -6}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } - - }; - #define CUBE_HALF_EXTENTS 1 #define EXTRA_HEIGHT -20.f - - ///BspToBulletConverter extends the BspConverter to convert to Bullet datastructures class BspToBulletConverter : public BspConverter { BspDemo* m_demoApp; public: - - BspToBulletConverter(BspDemo* demoApp) - :m_demoApp(demoApp) + BspToBulletConverter(BspDemo* demoApp) + : m_demoApp(demoApp) { } - virtual void addConvexVerticesCollider(btAlignedObjectArray& vertices, bool isEntity, const btVector3& entityTargetLocation) + virtual void addConvexVerticesCollider(btAlignedObjectArray& vertices, bool isEntity, const btVector3& entityTargetLocation) + { + ///perhaps we can do something special with entities (isEntity) + ///like adding a collision Triggering (as example) + + if (vertices.size() > 0) { - ///perhaps we can do something special with entities (isEntity) - ///like adding a collision Triggering (as example) + float mass = 0.f; + btTransform startTransform; + //can use a shift + startTransform.setIdentity(); + startTransform.setOrigin(btVector3(0, 0, -10.f)); + //this create an internal copy of the vertices - if (vertices.size() > 0) - { - float mass = 0.f; - btTransform startTransform; - //can use a shift - startTransform.setIdentity(); - startTransform.setOrigin(btVector3(0,0,-10.f)); - //this create an internal copy of the vertices + btCollisionShape* shape = new btConvexHullShape(&(vertices[0].getX()), vertices.size()); + m_demoApp->m_collisionShapes.push_back(shape); - btCollisionShape* shape = new btConvexHullShape(&(vertices[0].getX()),vertices.size()); - m_demoApp->m_collisionShapes.push_back(shape); - - //btRigidBody* body = m_demoApp->localCreateRigidBody(mass, startTransform,shape); - m_demoApp->createRigidBody(mass, startTransform,shape); - } + //btRigidBody* body = m_demoApp->localCreateRigidBody(mass, startTransform,shape); + m_demoApp->createRigidBody(mass, startTransform, shape); } + } }; - - - - //////////////////////////////////// - - - - - - BspDemo::~BspDemo() { - exitPhysics(); //will delete all default data + exitPhysics(); //will delete all default data } -void BspDemo::initPhysics() +void BspDemo::initPhysics() { const char* bspfilename = "BspDemo.bsp"; initPhysics(bspfilename); } - - -void BspDemo::initPhysics(const char* bspfilename) +void BspDemo::initPhysics(const char* bspfilename) { - - int cameraUpAxis =2; + int cameraUpAxis = 2; m_guiHelper->setUpAxis(cameraUpAxis); - btVector3 grav(0,0,0); + btVector3 grav(0, 0, 0); grav[cameraUpAxis] = -10; m_guiHelper->setUpAxis(cameraUpAxis); - -//_cameraUp = btVector3(0,0,1); -//_forwardAxis = 1; -//etCameraDistance(22.f); + //_cameraUp = btVector3(0,0,1); + //_forwardAxis = 1; + + //etCameraDistance(22.f); ///Setup a Physics Simulation Environment m_collisionConfiguration = new btDefaultCollisionConfiguration(); -// btCollisionShape* groundShape = new btBoxShape(btVector3(50,3,50)); + // btCollisionShape* groundShape = new btBoxShape(btVector3(50,3,50)); m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); - btVector3 worldMin(-1000,-1000,-1000); - btVector3 worldMax(1000,1000,1000); + btVector3 worldMin(-1000, -1000, -1000); + btVector3 worldMax(1000, 1000, 1000); m_broadphase = new btDbvtBroadphase(); //m_broadphase = new btAxisSweep3(worldMin,worldMax); //btOverlappingPairCache* broadphase = new btSimpleBroadphase(); m_solver = new btSequentialImpulseConstraintSolver(); //ConstraintSolver* solver = new OdeConstraintSolver; - m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration); m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); m_dynamicsWorld->setGravity(grav); - #ifdef QUAKE_BSP_IMPORTING void* memoryBuffer = 0; const char* filename = "BspDemo.bsp"; - const char* prefix[]={"./","./data/","../data/","../../data/","../../../data/","../../../../data/"}; - int numPrefixes = sizeof(prefix)/sizeof(const char*); - char relativeFileName[1024]; - FILE* file=0; - - for (int i=0;iautogenerateGraphicsObjects(m_dynamicsWorld); - - } - - - - - - - - //some code that de-mangles the windows filename passed in as argument char cleaned_filename[512]; char* getLastFileName() @@ -238,33 +193,31 @@ char* getLastFileName() } char* makeExeToBspFilename(const char* lpCmdLine) { - - // We might get a windows-style path on the command line, this can mess up the DOM which expects // all paths to be URI's. This block of code does some conversion to try and make the input // compliant without breaking the ability to accept a properly formatted URI. Right now this only // displays the first filename - const char *in = lpCmdLine; + const char* in = lpCmdLine; char* out = cleaned_filename; *out = '\0'; // If the first character is a ", skip it (filenames with spaces in them are quoted) - if(*in == '\"') + if (*in == '\"') { in++; } int i; - for(i =0; i<512; i++) + for (i = 0; i < 512; i++) { //if we get '.' we stop as well, unless it's the first character. Then we add .bsp as extension // If we hit a null or a quote, stop copying. This will get just the first filename. - if(i && (in[0] == '.') && (in[1] == 'e') && (in[2] == 'x') && (in[3] == 'e')) + if (i && (in[0] == '.') && (in[1] == 'e') && (in[2] == 'x') && (in[3] == 'e')) break; // If we hit a null or a quote, stop copying. This will get just the first filename. - if(*in == '\0' || *in == '\"') + if (*in == '\0' || *in == '\"') break; // Copy while swapping backslashes for forward ones - if(*in == '\\') + if (*in == '\\') { *out = '/'; } @@ -284,14 +237,12 @@ char* makeExeToBspFilename(const char* lpCmdLine) return cleaned_filename; } - -CommonExampleInterface* ImportBspCreateFunc(struct CommonExampleOptions& options) +CommonExampleInterface* ImportBspCreateFunc(struct CommonExampleOptions& options) { BspDemo* demo = new BspDemo(options.m_guiHelper); - - demo->initPhysics("BspDemo.bsp"); - return demo; - + + demo->initPhysics("BspDemo.bsp"); + return demo; } /* static DemoApplication* Create() diff --git a/examples/Importers/ImportBsp/ImportBspExample.h b/examples/Importers/ImportBsp/ImportBspExample.h index b1d51ab95..71f6ca921 100644 --- a/examples/Importers/ImportBsp/ImportBspExample.h +++ b/examples/Importers/ImportBsp/ImportBspExample.h @@ -15,9 +15,6 @@ subject to the following restrictions: #ifndef BSP_DEMO_H #define BSP_DEMO_H -class CommonExampleInterface* ImportBspCreateFunc(struct CommonExampleOptions& options); - - -#endif //BSP_DEMO_H - +class CommonExampleInterface* ImportBspCreateFunc(struct CommonExampleOptions& options); +#endif //BSP_DEMO_H diff --git a/examples/Importers/ImportBullet/SerializeSetup.cpp b/examples/Importers/ImportBullet/SerializeSetup.cpp index 0d6931e4f..f0caed3b1 100644 --- a/examples/Importers/ImportBullet/SerializeSetup.cpp +++ b/examples/Importers/ImportBullet/SerializeSetup.cpp @@ -1,114 +1,104 @@ #include "SerializeSetup.h" #include "../Extras/Serialize/BulletWorldImporter/btBulletWorldImporter.h" - #include "../CommonInterfaces/CommonRigidBodyBase.h" class SerializeSetup : public CommonRigidBodyBase { - char m_fileName[1024]; public: SerializeSetup(struct GUIHelperInterface* helper, const char* fileName); virtual ~SerializeSetup(); - + virtual void initPhysics(); virtual void stepSimulation(float deltaTime); virtual void setFileName(const char* fileName) { - memcpy(m_fileName,fileName,strlen(fileName)+1); + memcpy(m_fileName, fileName, strlen(fileName) + 1); } virtual void resetCamera() { float dist = 9.5; float pitch = -20; float yaw = -2.8; - float targetPos[3]={-0.2,-1.4,3.5}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {-0.2, -1.4, 3.5}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } - }; - SerializeSetup::SerializeSetup(struct GUIHelperInterface* helper, const char* fileName) -:CommonRigidBodyBase(helper) + : CommonRigidBodyBase(helper) { if (fileName) { setFileName(fileName); - } else + } + else { setFileName("spider.bullet"); } } SerializeSetup::~SerializeSetup() { - } void SerializeSetup::initPhysics() { - this->createEmptyDynamicsWorld(); - m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); - m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe+btIDebugDraw::DBG_DrawContactPoints); - btBulletWorldImporter* importer = new btBulletWorldImporter(m_dynamicsWorld); - + this->createEmptyDynamicsWorld(); + m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); + m_dynamicsWorld->getDebugDrawer()->setDebugMode(btIDebugDraw::DBG_DrawWireframe + btIDebugDraw::DBG_DrawContactPoints); + btBulletWorldImporter* importer = new btBulletWorldImporter(m_dynamicsWorld); - const char* prefix[]={"","./","./data/","../data/","../../data/","../../../data/","../../../../data/"}; - int numPrefixes = sizeof(prefix)/sizeof(const char*); - char relativeFileName[1024]; - FILE* f=0; + const char* prefix[] = {"", "./", "./data/", "../data/", "../../data/", "../../../data/", "../../../../data/"}; + int numPrefixes = sizeof(prefix) / sizeof(const char*); + char relativeFileName[1024]; + FILE* f = 0; - for (int i=0;!f && iloadFile(relativeFileName); + importer->loadFile(relativeFileName); //for now, guess the up axis from gravity if (m_dynamicsWorld->getGravity()[1] == 0.f) { m_guiHelper->setUpAxis(2); - } else + } + else { m_guiHelper->setUpAxis(1); } - //example code to export the dynamics world to a .bullet file - - btDefaultSerializer* serializer = new btDefaultSerializer(); + btDefaultSerializer* serializer = new btDefaultSerializer(); m_dynamicsWorld->serialize(serializer); - FILE* file = fopen("SerializeSetupTestFile.bullet","wb"); - fwrite(serializer->getBufferPointer(),serializer->getCurrentBufferSize(),1, file); + FILE* file = fopen("SerializeSetupTestFile.bullet", "wb"); + fwrite(serializer->getBufferPointer(), serializer->getCurrentBufferSize(), 1, file); fclose(file); - - - m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } void SerializeSetup::stepSimulation(float deltaTime) { - CommonRigidBodyBase::stepSimulation(deltaTime); + CommonRigidBodyBase::stepSimulation(deltaTime); } -class CommonExampleInterface* SerializeBulletCreateFunc(struct CommonExampleOptions& options) +class CommonExampleInterface* SerializeBulletCreateFunc(struct CommonExampleOptions& options) { return new SerializeSetup(options.m_guiHelper, options.m_fileName); } diff --git a/examples/Importers/ImportBullet/SerializeSetup.h b/examples/Importers/ImportBullet/SerializeSetup.h index 673f65d82..eae85c614 100644 --- a/examples/Importers/ImportBullet/SerializeSetup.h +++ b/examples/Importers/ImportBullet/SerializeSetup.h @@ -1,7 +1,6 @@ #ifndef SERIALIZE_SETUP_H #define SERIALIZE_SETUP_H -class CommonExampleInterface* SerializeBulletCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* SerializeBulletCreateFunc(struct CommonExampleOptions& options); - -#endif //SERIALIZE_SETUP_H +#endif //SERIALIZE_SETUP_H diff --git a/examples/Importers/ImportColladaDemo/ColladaGraphicsInstance.h b/examples/Importers/ImportColladaDemo/ColladaGraphicsInstance.h index 65f703760..ef750d16a 100644 --- a/examples/Importers/ImportColladaDemo/ColladaGraphicsInstance.h +++ b/examples/Importers/ImportColladaDemo/ColladaGraphicsInstance.h @@ -23,13 +23,13 @@ subject to the following restrictions: struct ColladaGraphicsInstance { ColladaGraphicsInstance() - :m_shapeIndex(-1) + : m_shapeIndex(-1) { m_worldTransform.setIdentity(); } - btMatrix4x4 m_worldTransform; - int m_shapeIndex;//could be index into array of GLInstanceGraphicsShape + btMatrix4x4 m_worldTransform; + int m_shapeIndex; //could be index into array of GLInstanceGraphicsShape float m_color[4]; }; -#endif //COLLADA_GRAPHICS_INSTANCE_H +#endif //COLLADA_GRAPHICS_INSTANCE_H diff --git a/examples/Importers/ImportColladaDemo/ImportColladaSetup.cpp b/examples/Importers/ImportColladaDemo/ImportColladaSetup.cpp index 453d16298..66fa901b2 100644 --- a/examples/Importers/ImportColladaDemo/ImportColladaSetup.cpp +++ b/examples/Importers/ImportColladaDemo/ImportColladaSetup.cpp @@ -15,7 +15,6 @@ subject to the following restrictions: //original author: Erwin Coumans */ - #include "ImportColladaSetup.h" #include #include "../OpenGLWindow/GLInstancingRenderer.h" @@ -28,49 +27,42 @@ subject to the following restrictions: #include "../CommonInterfaces/CommonRigidBodyBase.h" - - class ImportColladaSetup : public CommonRigidBodyBase { - public: - ImportColladaSetup(struct GUIHelperInterface* helper); - virtual ~ImportColladaSetup(); - + ImportColladaSetup(struct GUIHelperInterface* helper); + virtual ~ImportColladaSetup(); + virtual void initPhysics(); virtual void resetCamera() { float dist = 16; float pitch = -28; float yaw = -140; - float targetPos[3]={-4,-3,-3}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {-4, -3, -3}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } - }; ImportColladaSetup::ImportColladaSetup(struct GUIHelperInterface* helper) -:CommonRigidBodyBase(helper) + : CommonRigidBodyBase(helper) { - } ImportColladaSetup::~ImportColladaSetup() { - } -static int ColladaGraphicsInstanceSortfnc(const ColladaGraphicsInstance& a,const ColladaGraphicsInstance& b) +static int ColladaGraphicsInstanceSortfnc(const ColladaGraphicsInstance& a, const ColladaGraphicsInstance& b) { - if (a.m_shapeIndexb.m_shapeIndex) return -1; + if (a.m_shapeIndex < b.m_shapeIndex) return +1; + if (a.m_shapeIndex > b.m_shapeIndex) return -1; return 0; } - void ImportColladaSetup::initPhysics() { - int upAxis=1; + int upAxis = 1; m_guiHelper->setUpAxis(upAxis); this->createEmptyDynamicsWorld(); m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); @@ -81,28 +73,20 @@ void ImportColladaSetup::initPhysics() const char* fileNames[] = { "duck.dae", "seymourplane_triangulate.dae", - }; + }; const char* fileName = fileNames[fileIndex]; - int numFiles = sizeof(fileNames)/sizeof(const char*); - - char relativeFileName[1024]; + int numFiles = sizeof(fileNames) / sizeof(const char*); - if (!b3ResourcePath::findResourcePath(fileName,relativeFileName,1024)) - return; + char relativeFileName[1024]; + if (!b3ResourcePath::findResourcePath(fileName, relativeFileName, 1024)) + return; - btVector3 shift(0,0,0); - btVector3 scaling(1,1,1); -// int index=10; - - - - + btVector3 shift(0, 0, 0); + btVector3 scaling(1, 1, 1); + // int index=10; - - { - btAlignedObjectArray visualShapes; btAlignedObjectArray visualShapeInstances; @@ -110,69 +94,64 @@ void ImportColladaSetup::initPhysics() btTransform upAxisTrans; upAxisTrans.setIdentity(); - btVector3 color(0,0,1); + btVector3 color(0, 0, 1); #ifdef COMPARE_WITH_ASSIMP static int useAssimp = 0; if (useAssimp) { - - LoadMeshFromColladaAssimp(relativeFileName, visualShapes, visualShapeInstances,upAxisTrans,unitMeterScaling); + LoadMeshFromColladaAssimp(relativeFileName, visualShapes, visualShapeInstances, upAxisTrans, unitMeterScaling); fileIndex++; - if (fileIndex>=numFiles) + if (fileIndex >= numFiles) { fileIndex = 0; } - color.setValue(1,0,0); + color.setValue(1, 0, 0); } else { - LoadMeshFromCollada(relativeFileName, visualShapes, visualShapeInstances,upAxisTrans,unitMeterScaling); - + LoadMeshFromCollada(relativeFileName, visualShapes, visualShapeInstances, upAxisTrans, unitMeterScaling); } - useAssimp=1-useAssimp; + useAssimp = 1 - useAssimp; #else fileIndex++; - if (fileIndex>=numFiles) + if (fileIndex >= numFiles) { fileIndex = 0; } - LoadMeshFromCollada(relativeFileName, visualShapes, visualShapeInstances,upAxisTrans,unitMeterScaling, upAxis); -#endif// COMPARE_WITH_ASSIMP - - + LoadMeshFromCollada(relativeFileName, visualShapes, visualShapeInstances, upAxisTrans, unitMeterScaling, upAxis); +#endif // COMPARE_WITH_ASSIMP + //at the moment our graphics engine requires instances that share the same visual shape to be added right after registering the shape //so perform a sort, just to be sure visualShapeInstances.quickSort(ColladaGraphicsInstanceSortfnc); - for (int i=0;im_shapeIndex]; - btVector3 position(0,0,0);// = scaling*btVector3(instance->m_pos[0],instance->m_pos[1],instance->m_pos[2]); - btQuaternion orn(0,0,0,1);//instance->m_orn[0],instance->m_orn[1],instance->m_orn[2],instance->m_orn[3]); + btVector3 position(0, 0, 0); // = scaling*btVector3(instance->m_pos[0],instance->m_pos[1],instance->m_pos[2]); + btQuaternion orn(0, 0, 0, 1); //instance->m_orn[0],instance->m_orn[1],instance->m_orn[2],instance->m_orn[3]); //sort the visualShapeInstances, then iterate etc //void LoadMeshFromCollada(const char* relativeFileName, - //btAlignedObjectArray& visualShapes, + //btAlignedObjectArray& visualShapes, //btAlignedObjectArray visualShapeInstances); - + if (gfxShape) { //btTransform trans; //trans.setIdentity(); //trans.setRotation(btQuaternion(btVector3(1,0,0),SIMD_HALF_PI)); - - - + b3AlignedObjectArray verts; verts.resize(gfxShape->m_vertices->size()); - - for (int i=0;im_vertices->size();i++) + + for (int i = 0; i < gfxShape->m_vertices->size(); i++) { - verts[i].normal[0] = gfxShape->m_vertices->at(i).normal[0]; - verts[i].normal[1] = gfxShape->m_vertices->at(i).normal[1]; - verts[i].normal[2] = gfxShape->m_vertices->at(i).normal[2]; + verts[i].normal[0] = gfxShape->m_vertices->at(i).normal[0]; + verts[i].normal[1] = gfxShape->m_vertices->at(i).normal[1]; + verts[i].normal[2] = gfxShape->m_vertices->at(i).normal[2]; verts[i].uv[0] = gfxShape->m_vertices->at(i).uv[0]; verts[i].uv[1] = gfxShape->m_vertices->at(i).uv[1]; verts[i].xyzw[0] = gfxShape->m_vertices->at(i).xyzw[0]; @@ -180,34 +159,33 @@ void ImportColladaSetup::initPhysics() verts[i].xyzw[2] = gfxShape->m_vertices->at(i).xyzw[2]; verts[i].xyzw[3] = gfxShape->m_vertices->at(i).xyzw[3]; } - + //compensate upAxisTrans and unitMeterScaling here btMatrix4x4 upAxisMat; upAxisMat.setPureRotation(upAxisTrans.getRotation()); btMatrix4x4 unitMeterScalingMat; - unitMeterScalingMat.setPureScaling(btVector3(unitMeterScaling,unitMeterScaling,unitMeterScaling)); - btMatrix4x4 worldMat = unitMeterScalingMat*upAxisMat*instance->m_worldTransform; + unitMeterScalingMat.setPureScaling(btVector3(unitMeterScaling, unitMeterScaling, unitMeterScaling)); + btMatrix4x4 worldMat = unitMeterScalingMat * upAxisMat * instance->m_worldTransform; //btMatrix4x4 worldMat = instance->m_worldTransform; - for(int v=0;vgetRenderInterface()->registerShape(&verts[0].xyzw[0], gfxShape->m_numvertices, &gfxShape->m_indices->at(0), gfxShape->m_numIndices); - + //btVector3 instanceScaling(instance->m_scaling[0],instance->m_scaling[1],instance->m_scaling[2]); - m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId,position,orn,color,scaling); + m_guiHelper->getRenderInterface()->registerGraphicsInstance(shapeId, position, orn, color, scaling); } } } - } -class CommonExampleInterface* ImportColladaCreateFunc(struct CommonExampleOptions& options) +class CommonExampleInterface* ImportColladaCreateFunc(struct CommonExampleOptions& options) { return new ImportColladaSetup(options.m_guiHelper); } diff --git a/examples/Importers/ImportColladaDemo/ImportColladaSetup.h b/examples/Importers/ImportColladaDemo/ImportColladaSetup.h index f53c65579..7f37a1727 100644 --- a/examples/Importers/ImportColladaDemo/ImportColladaSetup.h +++ b/examples/Importers/ImportColladaDemo/ImportColladaSetup.h @@ -15,11 +15,9 @@ subject to the following restrictions: //original author: Erwin Coumans */ - #ifndef IMPORT_COLLADA_SETUP_H #define IMPORT_COLLADA_SETUP_H -class CommonExampleInterface* ImportColladaCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* ImportColladaCreateFunc(struct CommonExampleOptions& options); - -#endif //IMPORT_COLLADA_SETUP_H +#endif //IMPORT_COLLADA_SETUP_H diff --git a/examples/Importers/ImportColladaDemo/LoadMeshFromCollada.cpp b/examples/Importers/ImportColladaDemo/LoadMeshFromCollada.cpp index 47fa737d8..bd0949585 100644 --- a/examples/Importers/ImportColladaDemo/LoadMeshFromCollada.cpp +++ b/examples/Importers/ImportColladaDemo/LoadMeshFromCollada.cpp @@ -15,9 +15,8 @@ subject to the following restrictions: //original author: Erwin Coumans */ - #include "LoadMeshFromCollada.h" -#include //fopen +#include //fopen #include "Bullet3Common/b3AlignedObjectArray.h" #include #include "../../ThirdPartyLibs/tinyxml2/tinyxml2.h" @@ -28,10 +27,8 @@ using namespace tinyxml2; #include #include "btMatrix4x4.h" - #define MAX_VISUAL_SHAPES 512 - struct VertexSource { std::string m_positionArrayId; @@ -42,7 +39,8 @@ struct TokenFloatArray { btAlignedObjectArray& m_values; TokenFloatArray(btAlignedObjectArray& floatArray) - :m_values(floatArray) { + : m_values(floatArray) + { } inline void add(const char* token) { @@ -54,7 +52,8 @@ struct TokenIntArray { btAlignedObjectArray& m_values; TokenIntArray(btAlignedObjectArray& intArray) - :m_values(intArray) { + : m_values(intArray) + { } inline void add(const char* token) { @@ -66,127 +65,125 @@ struct TokenIntArray template void tokenize(const std::string& str, AddToken& tokenAdder, const std::string& delimiters = " ") { - std::string::size_type pos, lastPos = 0; - while(true) - { - pos = str.find_first_of(delimiters, lastPos); - if(pos == std::string::npos) - { - pos = str.length(); - if(pos != lastPos) - { - tokenAdder.add(str.data()+lastPos); - } - break; - } - else - { - if(pos != lastPos) - { - tokenAdder.add(str.data()+lastPos); - } - } - lastPos = pos + 1; - } + std::string::size_type pos, lastPos = 0; + while (true) + { + pos = str.find_first_of(delimiters, lastPos); + if (pos == std::string::npos) + { + pos = str.length(); + if (pos != lastPos) + { + tokenAdder.add(str.data() + lastPos); + } + break; + } + else + { + if (pos != lastPos) + { + tokenAdder.add(str.data() + lastPos); + } + } + lastPos = pos + 1; + } } - -void readFloatArray(XMLElement* source, btAlignedObjectArray& floatArray, int& componentStride) +void readFloatArray(XMLElement* source, btAlignedObjectArray& floatArray, int& componentStride) { int numVals, stride; XMLElement* array = source->FirstChildElement("float_array"); - if(array) + if (array) { componentStride = 1; - if (source->FirstChildElement("technique_common")->FirstChildElement("accessor")->QueryIntAttribute("stride", &stride)!= XML_NO_ATTRIBUTE) + if (source->FirstChildElement("technique_common")->FirstChildElement("accessor")->QueryIntAttribute("stride", &stride) != XML_NO_ATTRIBUTE) { componentStride = stride; } array->QueryIntAttribute("count", &numVals); TokenFloatArray adder(floatArray); floatArray.reserve(numVals); - tokenize(array->GetText(),adder); + tokenize(array->GetText(), adder); assert(floatArray.size() == numVals); } } btVector3 getVector3FromXmlText(const char* text) { - btVector3 vec(0,0,0); + btVector3 vec(0, 0, 0); btAlignedObjectArray floatArray; TokenFloatArray adder(floatArray); floatArray.reserve(3); - tokenize(text,adder); + tokenize(text, adder); assert(floatArray.size() == 3); - if (floatArray.size()==3) + if (floatArray.size() == 3) { - vec.setValue(floatArray[0],floatArray[1],floatArray[2]); + vec.setValue(floatArray[0], floatArray[1], floatArray[2]); } return vec; } btVector4 getVector4FromXmlText(const char* text) { - btVector4 vec(0,0,0,0); + btVector4 vec(0, 0, 0, 0); btAlignedObjectArray floatArray; TokenFloatArray adder(floatArray); floatArray.reserve(4); - tokenize(text,adder); + tokenize(text, adder); assert(floatArray.size() == 4); - if (floatArray.size()==4) + if (floatArray.size() == 4) { - vec.setValue(floatArray[0],floatArray[1],floatArray[2],floatArray[3]); + vec.setValue(floatArray[0], floatArray[1], floatArray[2], floatArray[3]); } return vec; } - -void readLibraryGeometries(XMLDocument& doc, btAlignedObjectArray& visualShapes, btHashMap& name2Shape, float extraScaling) +void readLibraryGeometries(XMLDocument& doc, btAlignedObjectArray& visualShapes, btHashMap& name2Shape, float extraScaling) { - btHashMap allSources; - btHashMap vertexSources; - for(XMLElement* geometry = doc.RootElement()->FirstChildElement("library_geometries")->FirstChildElement("geometry"); - geometry != NULL; geometry = geometry->NextSiblingElement("geometry")) + btHashMap allSources; + btHashMap vertexSources; + for (XMLElement* geometry = doc.RootElement()->FirstChildElement("library_geometries")->FirstChildElement("geometry"); + geometry != NULL; geometry = geometry->NextSiblingElement("geometry")) { btAlignedObjectArray vertexPositions; btAlignedObjectArray vertexNormals; btAlignedObjectArray indices; const char* geometryName = geometry->Attribute("id"); - for (XMLElement* mesh = geometry->FirstChildElement("mesh");(mesh != NULL); mesh = mesh->NextSiblingElement("mesh")) + for (XMLElement* mesh = geometry->FirstChildElement("mesh"); (mesh != NULL); mesh = mesh->NextSiblingElement("mesh")) { XMLElement* vertices2 = mesh->FirstChildElement("vertices"); - - for (XMLElement* source = mesh->FirstChildElement("source");source != NULL;source = source->NextSiblingElement("source")) + + for (XMLElement* source = mesh->FirstChildElement("source"); source != NULL; source = source->NextSiblingElement("source")) { - const char* srcId= source->Attribute("id"); -// printf("source id=%s\n",srcId); - allSources.insert(srcId,source); + const char* srcId = source->Attribute("id"); + // printf("source id=%s\n",srcId); + allSources.insert(srcId, source); } const char* vertexId = vertices2->Attribute("id"); //printf("vertices id=%s\n",vertexId); VertexSource vs; - for(XMLElement* input = vertices2->FirstChildElement("input");input != NULL;input = input->NextSiblingElement("input")) + for (XMLElement* input = vertices2->FirstChildElement("input"); input != NULL; input = input->NextSiblingElement("input")) { const char* sem = input->Attribute("semantic"); std::string semName(sem); -// printf("sem=%s\n",sem); - // const char* src = input->Attribute("source"); -// printf("src=%s\n",src); + // printf("sem=%s\n",sem); + // const char* src = input->Attribute("source"); + // printf("src=%s\n",src); const char* srcIdRef = input->Attribute("source"); std::string source_name; source_name = std::string(srcIdRef); source_name = source_name.erase(0, 1); - if (semName=="POSITION") + if (semName == "POSITION") { vs.m_positionArrayId = source_name; } - if (semName=="NORMAL") + if (semName == "NORMAL") { vs.m_normalArrayId = source_name; } } - vertexSources.insert(vertexId,vs); + vertexSources.insert(vertexId, vs); btAlignedObjectArray trianglesAndPolylists; @@ -199,36 +196,35 @@ void readLibraryGeometries(XMLDocument& doc, btAlignedObjectArrayQueryIntAttribute("count", &primitiveCount); - int indexStride=1; + int indexStride = 1; int posOffset = 0; int normalOffset = 0; int numIndices = 0; { - - for (XMLElement* input = primitive->FirstChildElement("input");input != NULL;input = input->NextSiblingElement("input")) + for (XMLElement* input = primitive->FirstChildElement("input"); input != NULL; input = input->NextSiblingElement("input")) { const char* sem = input->Attribute("semantic"); std::string semName(sem); int offset = atoi(input->Attribute("offset")); - if ((offset+1)>indexStride) - indexStride=offset+1; + if ((offset + 1) > indexStride) + indexStride = offset + 1; //printf("sem=%s\n",sem); - // const char* src = input->Attribute("source"); + // const char* src = input->Attribute("source"); //printf("src=%s\n",src); const char* srcIdRef = input->Attribute("source"); std::string source_name; source_name = std::string(srcIdRef); source_name = source_name.erase(0, 1); - - if (semName=="VERTEX") + + if (semName == "VERTEX") { //now we have POSITION and possibly NORMAL too, using same index array (

) VertexSource* vs = vertexSources[source_name.c_str()]; @@ -240,138 +236,138 @@ void readLibraryGeometries(XMLDocument& doc, btAlignedObjectArraym_normalArrayId.length()) { normalSourceName = vs->m_normalArrayId; - normalOffset = offset; + normalOffset = offset; } } - if (semName=="NORMAL") + if (semName == "NORMAL") { - btAssert(normalSourceName.length()==0); + btAssert(normalSourceName.length() == 0); normalSourceName = source_name; - normalOffset = offset; + normalOffset = offset; } } - numIndices = primitiveCount * 3; + numIndices = primitiveCount * 3; } btAlignedObjectArray positionFloatArray; - int posStride=1; + int posStride = 1; XMLElement** sourcePtr = allSources[positionSourceName.c_str()]; if (sourcePtr) { - readFloatArray(*sourcePtr,positionFloatArray, posStride); + readFloatArray(*sourcePtr, positionFloatArray, posStride); } btAlignedObjectArray normalFloatArray; - int normalStride=1; + int normalStride = 1; sourcePtr = allSources[normalSourceName.c_str()]; if (sourcePtr) { - readFloatArray(*sourcePtr,normalFloatArray,normalStride); + readFloatArray(*sourcePtr, normalFloatArray, normalStride); } btAlignedObjectArray curIndices; - curIndices.reserve(numIndices*indexStride); + curIndices.reserve(numIndices * indexStride); TokenIntArray adder(curIndices); - tokenize(primitive->FirstChildElement("p")->GetText(),adder); - assert(curIndices.size() == numIndices*indexStride); + tokenize(primitive->FirstChildElement("p")->GetText(), adder); + assert(curIndices.size() == numIndices * indexStride); int indexOffset = vertexPositions.size(); - for(int index=0; indexnormalIndex)) + int posIndex = curIndices[index * indexStride + posOffset]; + int normalIndex = curIndices[index * indexStride + normalOffset]; + vertexPositions.push_back(btVector3(extraScaling * positionFloatArray[posIndex * 3 + 0], + extraScaling * positionFloatArray[posIndex * 3 + 1], + extraScaling * positionFloatArray[posIndex * 3 + 2])); + + if (normalFloatArray.size() && (normalFloatArray.size() > normalIndex)) { - vertexNormals.push_back(btVector3(normalFloatArray[normalIndex*3+0], - normalFloatArray[normalIndex*3+1], - normalFloatArray[normalIndex*3+2])); - } else + vertexNormals.push_back(btVector3(normalFloatArray[normalIndex * 3 + 0], + normalFloatArray[normalIndex * 3 + 1], + normalFloatArray[normalIndex * 3 + 2])); + } + else { //add a dummy normal of length zero, so it is easy to detect that it is an invalid normal - vertexNormals.push_back(btVector3(0,0,0)); + vertexNormals.push_back(btVector3(0, 0, 0)); } } int curNumIndices = indices.size(); - indices.resize(curNumIndices+numIndices); - for(int index=0; index; - visualShape.m_indices = new b3AlignedObjectArray; - int indexBase = 0; + if (shapeIndex < MAX_VISUAL_SHAPES) + { + GLInstanceGraphicsShape& visualShape = visualShapes.expand(); + { + visualShape.m_vertices = new b3AlignedObjectArray; + visualShape.m_indices = new b3AlignedObjectArray; + int indexBase = 0; - btAssert(vertexNormals.size()==vertexPositions.size()); - for (int v=0;vpush_back(vtx); - } + btAssert(vertexNormals.size() == vertexPositions.size()); + for (int v = 0; v < vertexPositions.size(); v++) + { + GLInstanceVertex vtx; + vtx.xyzw[0] = vertexPositions[v].x(); + vtx.xyzw[1] = vertexPositions[v].y(); + vtx.xyzw[2] = vertexPositions[v].z(); + vtx.xyzw[3] = 1.f; + vtx.normal[0] = vertexNormals[v].x(); + vtx.normal[1] = vertexNormals[v].y(); + vtx.normal[2] = vertexNormals[v].z(); + vtx.uv[0] = 0.5f; + vtx.uv[1] = 0.5f; + visualShape.m_vertices->push_back(vtx); + } - for (int index=0;indexpush_back(indices[index]+indexBase); - } - - - //b3Printf(" index_count =%dand vertexPositions.size=%d\n",indices.size(), vertexPositions.size()); - indexBase=visualShape.m_vertices->size(); - visualShape.m_numIndices = visualShape.m_indices->size(); - visualShape.m_numvertices = visualShape.m_vertices->size(); - } - //b3Printf("geometry name=%s\n",geometryName); - name2Shape.insert(geometryName,shapeIndex); - } else - { - b3Warning("DAE exceeds number of visual shapes (%d/%d)",shapeIndex, MAX_VISUAL_SHAPES); - } + for (int index = 0; index < indices.size(); index++) + { + visualShape.m_indices->push_back(indices[index] + indexBase); + } - }//for each geometry + //b3Printf(" index_count =%dand vertexPositions.size=%d\n",indices.size(), vertexPositions.size()); + indexBase = visualShape.m_vertices->size(); + visualShape.m_numIndices = visualShape.m_indices->size(); + visualShape.m_numvertices = visualShape.m_vertices->size(); + } + //b3Printf("geometry name=%s\n",geometryName); + name2Shape.insert(geometryName, shapeIndex); + } + else + { + b3Warning("DAE exceeds number of visual shapes (%d/%d)", shapeIndex, MAX_VISUAL_SHAPES); + } + + } //for each geometry } -void readNodeHierarchy(XMLElement* node,btHashMap& name2Shape, btAlignedObjectArray& visualShapeInstances, const btMatrix4x4& parentTransMat) +void readNodeHierarchy(XMLElement* node, btHashMap& name2Shape, btAlignedObjectArray& visualShapeInstances, const btMatrix4x4& parentTransMat) { - - btMatrix4x4 nodeTrans; nodeTrans.setIdentity(); ///todo(erwincoumans) we probably have to read the elements 'translate', 'scale', 'rotate' and 'matrix' in-order and accumulate them... { - for (XMLElement* transElem = node->FirstChildElement("matrix");transElem;transElem=node->NextSiblingElement("matrix")) + for (XMLElement* transElem = node->FirstChildElement("matrix"); transElem; transElem = node->NextSiblingElement("matrix")) { if (transElem->GetText()) { btAlignedObjectArray floatArray; TokenFloatArray adder(floatArray); - tokenize(transElem->GetText(),adder); - if (floatArray.size()==16) + tokenize(transElem->GetText(), adder); + if (floatArray.size() == 16) { - btMatrix4x4 t(floatArray[0],floatArray[1],floatArray[2],floatArray[3], - floatArray[4],floatArray[5],floatArray[6],floatArray[7], - floatArray[8],floatArray[9],floatArray[10],floatArray[11], - floatArray[12],floatArray[13],floatArray[14],floatArray[15]); + btMatrix4x4 t(floatArray[0], floatArray[1], floatArray[2], floatArray[3], + floatArray[4], floatArray[5], floatArray[6], floatArray[7], + floatArray[8], floatArray[9], floatArray[10], floatArray[11], + floatArray[12], floatArray[13], floatArray[14], floatArray[15]); - nodeTrans = nodeTrans*t; - } else + nodeTrans = nodeTrans * t; + } + else { b3Warning("Error: expected 16 elements in a element, skipping\n"); } @@ -380,7 +376,7 @@ void readNodeHierarchy(XMLElement* node,btHashMap& name2Shape, } { - for (XMLElement* transElem = node->FirstChildElement("translate");transElem;transElem=node->NextSiblingElement("translate")) + for (XMLElement* transElem = node->FirstChildElement("translate"); transElem; transElem = node->NextSiblingElement("translate")) { if (transElem->GetText()) { @@ -388,45 +384,44 @@ void readNodeHierarchy(XMLElement* node,btHashMap& name2Shape, //nodePos+= unitScaling*parentScaling*pos; btMatrix4x4 t; t.setPureTranslation(pos); - nodeTrans = nodeTrans*t; - + nodeTrans = nodeTrans * t; } } } { - for(XMLElement* scaleElem = node->FirstChildElement("scale"); - scaleElem!= NULL; scaleElem= node->NextSiblingElement("scale")) + for (XMLElement* scaleElem = node->FirstChildElement("scale"); + scaleElem != NULL; scaleElem = node->NextSiblingElement("scale")) { if (scaleElem->GetText()) { btVector3 scaling = getVector3FromXmlText(scaleElem->GetText()); btMatrix4x4 t; t.setPureScaling(scaling); - nodeTrans = nodeTrans*t; + nodeTrans = nodeTrans * t; } } } { - for(XMLElement* rotateElem = node->FirstChildElement("rotate"); - rotateElem!= NULL; rotateElem= node->NextSiblingElement("rotate")) + for (XMLElement* rotateElem = node->FirstChildElement("rotate"); + rotateElem != NULL; rotateElem = node->NextSiblingElement("rotate")) { if (rotateElem->GetText()) { //accumulate orientation btVector4 rotate = getVector4FromXmlText(rotateElem->GetText()); - btQuaternion orn(btVector3(rotate),btRadians(rotate[3]));//COLLADA DAE rotate is in degrees, convert to radians + btQuaternion orn(btVector3(rotate), btRadians(rotate[3])); //COLLADA DAE rotate is in degrees, convert to radians btMatrix4x4 t; t.setPureRotation(orn); - nodeTrans = nodeTrans*t; + nodeTrans = nodeTrans * t; } } } - - nodeTrans = parentTransMat*nodeTrans; - + + nodeTrans = parentTransMat * nodeTrans; + for (XMLElement* instanceGeom = node->FirstChildElement("instance_geometry"); - instanceGeom!=0; - instanceGeom=instanceGeom->NextSiblingElement("instance_geometry")) + instanceGeom != 0; + instanceGeom = instanceGeom->NextSiblingElement("instance_geometry")) { const char* geomUrl = instanceGeom->Attribute("url"); //printf("node referring to geom %s\n", geomUrl); @@ -434,37 +429,38 @@ void readNodeHierarchy(XMLElement* node,btHashMap& name2Shape, int* shapeIndexPtr = name2Shape[geomUrl]; if (shapeIndexPtr) { - // int index = *shapeIndexPtr; + // int index = *shapeIndexPtr; //printf("found geom with index %d\n", *shapeIndexPtr); ColladaGraphicsInstance& instance = visualShapeInstances.expand(); instance.m_shapeIndex = *shapeIndexPtr; instance.m_worldTransform = nodeTrans; - } else + } + else { b3Warning("geom not found\n"); } } - for(XMLElement* childNode = node->FirstChildElement("node"); - childNode!= NULL; childNode = childNode->NextSiblingElement("node")) + for (XMLElement* childNode = node->FirstChildElement("node"); + childNode != NULL; childNode = childNode->NextSiblingElement("node")) { - readNodeHierarchy(childNode,name2Shape,visualShapeInstances, nodeTrans); + readNodeHierarchy(childNode, name2Shape, visualShapeInstances, nodeTrans); } } -void readVisualSceneInstanceGeometries(XMLDocument& doc, btHashMap& name2Shape, btAlignedObjectArray& visualShapeInstances) +void readVisualSceneInstanceGeometries(XMLDocument& doc, btHashMap& name2Shape, btAlignedObjectArray& visualShapeInstances) { - btHashMap allVisualScenes; + btHashMap allVisualScenes; XMLElement* libVisualScenes = doc.RootElement()->FirstChildElement("library_visual_scenes"); - if (libVisualScenes==0) + if (libVisualScenes == 0) return; { - for(XMLElement* scene = libVisualScenes->FirstChildElement("visual_scene"); - scene != NULL; scene = scene->NextSiblingElement("visual_scene")) + for (XMLElement* scene = libVisualScenes->FirstChildElement("visual_scene"); + scene != NULL; scene = scene->NextSiblingElement("visual_scene")) { const char* sceneName = scene->Attribute("id"); - allVisualScenes.insert(sceneName,scene); + allVisualScenes.insert(sceneName, scene); } } @@ -477,7 +473,7 @@ void readVisualSceneInstanceGeometries(XMLDocument& doc, btHashMapAttribute("url"); - XMLElement** sceneInstancePtr = allVisualScenes[instanceSceneUrl+1];//skip # + XMLElement** sceneInstancePtr = allVisualScenes[instanceSceneUrl + 1]; //skip # if (sceneInstancePtr) { scene = *sceneInstancePtr; @@ -488,28 +484,26 @@ void readVisualSceneInstanceGeometries(XMLDocument& doc, btHashMapFirstChildElement("node"); - node != NULL; node = node->NextSiblingElement("node")) + for (XMLElement* node = scene->FirstChildElement("node"); + node != NULL; node = node->NextSiblingElement("node")) { btMatrix4x4 identity; identity.setIdentity(); - btVector3 identScaling(1,1,1); - readNodeHierarchy(node,name2Shape,visualShapeInstances, identity); - + btVector3 identScaling(1, 1, 1); + readNodeHierarchy(node, name2Shape, visualShapeInstances, identity); } - } } void getUnitMeterScalingAndUpAxisTransform(XMLDocument& doc, btTransform& tr, float& unitMeterScaling, int clientUpAxis) { ///todo(erwincoumans) those up-axis transformations have been quickly coded without rigorous testing - + XMLElement* unitMeter = doc.RootElement()->FirstChildElement("asset")->FirstChildElement("unit"); if (unitMeter) { const char* meterText = unitMeter->Attribute("meter"); - //printf("meterText=%s\n", meterText); + //printf("meterText=%s\n", meterText); unitMeterScaling = atof(meterText); } @@ -518,13 +512,12 @@ void getUnitMeterScalingAndUpAxisTransform(XMLDocument& doc, btTransform& tr, fl { switch (clientUpAxis) { - case 1: { std::string upAxisTxt = upAxisElem->GetText(); if (upAxisTxt == "X_UP") { - btQuaternion x2y(btVector3(0,0,1),SIMD_HALF_PI); + btQuaternion x2y(btVector3(0, 0, 1), SIMD_HALF_PI); tr.setRotation(x2y); } if (upAxisTxt == "Y_UP") @@ -534,7 +527,7 @@ void getUnitMeterScalingAndUpAxisTransform(XMLDocument& doc, btTransform& tr, fl } if (upAxisTxt == "Z_UP") { - btQuaternion z2y(btVector3(1,0,0),-SIMD_HALF_PI); + btQuaternion z2y(btVector3(1, 0, 0), -SIMD_HALF_PI); tr.setRotation(z2y); } break; @@ -544,12 +537,12 @@ void getUnitMeterScalingAndUpAxisTransform(XMLDocument& doc, btTransform& tr, fl std::string upAxisTxt = upAxisElem->GetText(); if (upAxisTxt == "X_UP") { - btQuaternion x2z(btVector3(0,1,0),-SIMD_HALF_PI); + btQuaternion x2z(btVector3(0, 1, 0), -SIMD_HALF_PI); tr.setRotation(x2z); } if (upAxisTxt == "Y_UP") { - btQuaternion y2z(btVector3(1,0,0),SIMD_HALF_PI); + btQuaternion y2z(btVector3(1, 0, 0), SIMD_HALF_PI); tr.setRotation(y2z); } if (upAxisTxt == "Z_UP") @@ -568,46 +561,42 @@ void getUnitMeterScalingAndUpAxisTransform(XMLDocument& doc, btTransform& tr, fl } } -void LoadMeshFromCollada(const char* relativeFileName, btAlignedObjectArray& visualShapes, btAlignedObjectArray& visualShapeInstances, btTransform& upAxisTransform, float& unitMeterScaling,int clientUpAxis) +void LoadMeshFromCollada(const char* relativeFileName, btAlignedObjectArray& visualShapes, btAlignedObjectArray& visualShapeInstances, btTransform& upAxisTransform, float& unitMeterScaling, int clientUpAxis) { + // GLInstanceGraphicsShape* instance = 0; -// GLInstanceGraphicsShape* instance = 0; - //usually COLLADA files don't have that many visual geometries/shapes visualShapes.reserve(MAX_VISUAL_SHAPES); - float extraScaling = 1;//0.01; + float extraScaling = 1; //0.01; btHashMap name2ShapeIndex; b3FileUtils f; char filename[1024]; - if (!f.findFile(relativeFileName,filename,1024)) + if (!f.findFile(relativeFileName, filename, 1024)) { b3Warning("File not found: %s\n", filename); return; } - + XMLDocument doc; if (doc.LoadFile(filename) != XML_SUCCESS) return; - //We need units to be in meter, so apply a scaling using the asset/units meter - unitMeterScaling=1; + //We need units to be in meter, so apply a scaling using the asset/units meter + unitMeterScaling = 1; upAxisTransform.setIdentity(); //Also we can optionally compensate all transforms using the asset/up_axis as well as unit meter scaling - getUnitMeterScalingAndUpAxisTransform(doc, upAxisTransform, unitMeterScaling,clientUpAxis); - + getUnitMeterScalingAndUpAxisTransform(doc, upAxisTransform, unitMeterScaling, clientUpAxis); + btMatrix4x4 ident; ident.setIdentity(); readLibraryGeometries(doc, visualShapes, name2ShapeIndex, extraScaling); - + readVisualSceneInstanceGeometries(doc, name2ShapeIndex, visualShapeInstances); - } - - #ifdef COMPARE_WITH_ASSIMP #include @@ -615,127 +604,128 @@ void LoadMeshFromCollada(const char* relativeFileName, btAlignedObjectArray #include - -# include "assimp/ColladaLoader.h" +#include "assimp/ColladaLoader.h" //# include "STLLoader.h" -# include "assimp/SortByPTypeProcess.h" -# include "assimp/LimitBoneWeightsProcess.h" -# include "assimp/TriangulateProcess.h" -# include "assimp/JoinVerticesProcess.h" -# include "assimp/RemoveVCProcess.h" +#include "assimp/SortByPTypeProcess.h" +#include "assimp/LimitBoneWeightsProcess.h" +#include "assimp/TriangulateProcess.h" +#include "assimp/JoinVerticesProcess.h" +#include "assimp/RemoveVCProcess.h" - -namespace Assimp { - // ------------------------------------------------------------------------------------------------ -void GetImporterInstanceList(std::vector< BaseImporter* >& out) - { - out.push_back( new ColladaLoader()); - } - // ------------------------------------------------------------------------------------------------ -void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out) - { - out.push_back( new SortByPTypeProcess()); - out.push_back( new LimitBoneWeightsProcess()); - out.push_back( new TriangulateProcess()); - out.push_back( new JoinVerticesProcess()); - //out.push_back( new RemoveVCProcess()); - } - +namespace Assimp +{ +// ------------------------------------------------------------------------------------------------ +void GetImporterInstanceList(std::vector& out) +{ + out.push_back(new ColladaLoader()); } +// ------------------------------------------------------------------------------------------------ +void GetPostProcessingStepInstanceList(std::vector& out) +{ + out.push_back(new SortByPTypeProcess()); + out.push_back(new LimitBoneWeightsProcess()); + out.push_back(new TriangulateProcess()); + out.push_back(new JoinVerticesProcess()); + //out.push_back( new RemoveVCProcess()); +} + +} // namespace Assimp static void addMeshParts(const aiScene* scene, const aiNode* node, GLInstanceGraphicsShape* outverts, const aiMatrix4x4& parentTr) { - aiMatrix4x4 const& nodeTrans(node->mTransformation); - - aiMatrix4x4 trans; - trans = parentTr * nodeTrans; - - for (size_t i = 0; i < node->mNumMeshes; ++i) + aiMatrix4x4 const& nodeTrans(node->mTransformation); + + aiMatrix4x4 trans; + trans = parentTr * nodeTrans; + + for (size_t i = 0; i < node->mNumMeshes; ++i) + { + aiMesh const* mesh = scene->mMeshes[node->mMeshes[i]]; + size_t num_vertices = mesh->mNumVertices; + if (mesh->mPrimitiveTypes == aiPrimitiveType_TRIANGLE) { - aiMesh const* mesh = scene->mMeshes[node->mMeshes[i]]; - size_t num_vertices = mesh->mNumVertices; - if (mesh->mPrimitiveTypes==aiPrimitiveType_TRIANGLE) + int curVertexBase = outverts->m_vertices->size(); + + for (int v = 0; v < mesh->mNumVertices; v++) { - int curVertexBase = outverts->m_vertices->size(); - - for (int v=0;vmNumVertices;v++) + GLInstanceVertex vtx; + aiVector3D vWorld = trans * mesh->mVertices[v]; + vtx.xyzw[0] = vWorld.x; + vtx.xyzw[1] = vWorld.y; + vtx.xyzw[2] = vWorld.z; + vtx.xyzw[3] = 1; + if (mesh->HasNormals()) { - GLInstanceVertex vtx; - aiVector3D vWorld = trans*mesh->mVertices[v]; - vtx.xyzw[0] = vWorld.x; - vtx.xyzw[1] = vWorld.y; - vtx.xyzw[2] = vWorld.z; - vtx.xyzw[3] = 1; - if (mesh->HasNormals()) - { - vtx.normal[0] = mesh->mNormals[v].x; - vtx.normal[1] = mesh->mNormals[v].y; - vtx.normal[2] = mesh->mNormals[v].z; - } else - { - vtx.normal[0] = 0; - vtx.normal[1] = 0; - vtx.normal[2] = 1; - } - if (mesh->HasTextureCoords(0)) - { - vtx.uv[0] = mesh->mTextureCoords[0][v].x; - vtx.uv[1] = mesh->mTextureCoords[0][v].y; - } else - { - vtx.uv[0]=0.5f; - vtx.uv[1]=0.5f; - } - outverts->m_vertices->push_back(vtx); + vtx.normal[0] = mesh->mNormals[v].x; + vtx.normal[1] = mesh->mNormals[v].y; + vtx.normal[2] = mesh->mNormals[v].z; } - for (int f=0;fmNumFaces;f++) + else { - b3Assert(mesh->mFaces[f].mNumIndices == 3); - int i0 = mesh->mFaces[f].mIndices[0]; - int i1 = mesh->mFaces[f].mIndices[1]; - int i2 = mesh->mFaces[f].mIndices[2]; - outverts->m_indices->push_back(i0+curVertexBase); - outverts->m_indices->push_back(i1+curVertexBase); - outverts->m_indices->push_back(i2+curVertexBase); + vtx.normal[0] = 0; + vtx.normal[1] = 0; + vtx.normal[2] = 1; } + if (mesh->HasTextureCoords(0)) + { + vtx.uv[0] = mesh->mTextureCoords[0][v].x; + vtx.uv[1] = mesh->mTextureCoords[0][v].y; + } + else + { + vtx.uv[0] = 0.5f; + vtx.uv[1] = 0.5f; + } + outverts->m_vertices->push_back(vtx); } - } - for (size_t i=0 ; imNumChildren ; ++i) { - addMeshParts(scene,node->mChildren[i], outverts, trans); - } + for (int f = 0; f < mesh->mNumFaces; f++) + { + b3Assert(mesh->mFaces[f].mNumIndices == 3); + int i0 = mesh->mFaces[f].mIndices[0]; + int i1 = mesh->mFaces[f].mIndices[1]; + int i2 = mesh->mFaces[f].mIndices[2]; + outverts->m_indices->push_back(i0 + curVertexBase); + outverts->m_indices->push_back(i1 + curVertexBase); + outverts->m_indices->push_back(i2 + curVertexBase); + } + } + } + for (size_t i = 0; i < node->mNumChildren; ++i) + { + addMeshParts(scene, node->mChildren[i], outverts, trans); + } } - -void LoadMeshFromColladaAssimp(const char* relativeFileName, btAlignedObjectArray& visualShapes, btAlignedObjectArray& visualShapeInstances,btTransform& upAxisTrans, float& unitMeterScaling) +void LoadMeshFromColladaAssimp(const char* relativeFileName, btAlignedObjectArray& visualShapes, btAlignedObjectArray& visualShapeInstances, btTransform& upAxisTrans, float& unitMeterScaling) { upAxisTrans.setIdentity(); - unitMeterScaling=1; + unitMeterScaling = 1; GLInstanceGraphicsShape* shape = 0; - - - FILE* file = fopen(relativeFileName,"rb"); + + FILE* file = fopen(relativeFileName, "rb"); if (file) { - int size=0; + int size = 0; if (fseek(file, 0, SEEK_END) || (size = ftell(file)) == EOF || fseek(file, 0, SEEK_SET)) { b3Warning("Error: Cannot access file to determine size of %s\n", relativeFileName); - } else + } + else { if (size) { //printf("Open DAE file of %d bytes\n",size); - + Assimp::Importer importer; //importer.SetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS, aiComponent_NORMALS | aiComponent_COLORS); importer.SetPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE | aiPrimitiveType_POINT); - // importer.SetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION, 1); + // importer.SetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION, 1); aiScene const* scene = importer.ReadFile(relativeFileName, - aiProcess_JoinIdenticalVertices | - //aiProcess_RemoveComponent | - aiProcess_SortByPType | - aiProcess_Triangulate); + aiProcess_JoinIdenticalVertices | + //aiProcess_RemoveComponent | + aiProcess_SortByPType | + aiProcess_Triangulate); if (scene) { shape = &visualShapes.expand(); @@ -749,16 +739,14 @@ void LoadMeshFromColladaAssimp(const char* relativeFileName, btAlignedObjectArra aiMatrix4x4 ident; addMeshParts(scene, scene->mRootNode, shape, ident); - shape->m_numIndices = shape->m_indices->size(); + shape->m_numIndices = shape->m_indices->size(); shape->m_numvertices = shape->m_vertices->size(); ColladaGraphicsInstance& instance = visualShapeInstances.expand(); - instance.m_shapeIndex = visualShapes.size()-1; + instance.m_shapeIndex = visualShapes.size() - 1; } } } - } - } -#endif //COMPARE_WITH_ASSIMP +#endif //COMPARE_WITH_ASSIMP diff --git a/examples/Importers/ImportColladaDemo/LoadMeshFromCollada.h b/examples/Importers/ImportColladaDemo/LoadMeshFromCollada.h index 2e939b575..14e135b5d 100644 --- a/examples/Importers/ImportColladaDemo/LoadMeshFromCollada.h +++ b/examples/Importers/ImportColladaDemo/LoadMeshFromCollada.h @@ -15,7 +15,6 @@ subject to the following restrictions: //original author: Erwin Coumans */ - #ifndef LOAD_MESH_FROM_COLLADA_H #define LOAD_MESH_FROM_COLLADA_H @@ -24,22 +23,20 @@ subject to the following restrictions: #include "../../OpenGLWindow/GLInstanceGraphicsShape.h" #include "ColladaGraphicsInstance.h" - void LoadMeshFromCollada(const char* relativeFileName, - btAlignedObjectArray& visualShapes, - btAlignedObjectArray& visualShapeInstances, - btTransform& upAxisTrans, - float& unitMeterScaling, + btAlignedObjectArray& visualShapes, + btAlignedObjectArray& visualShapeInstances, + btTransform& upAxisTrans, + float& unitMeterScaling, int clientUpAxis); //#define COMPARE_WITH_ASSIMP #ifdef COMPARE_WITH_ASSIMP -void LoadMeshFromColladaAssimp(const char* relativeFileName, - btAlignedObjectArray& visualShapes, - btAlignedObjectArray& visualShapeInstances, - btTransform& upAxisTrans, - float& unitMeterScaling - ); -#endif //COMPARE_WITH_ASSIMP +void LoadMeshFromColladaAssimp(const char* relativeFileName, + btAlignedObjectArray& visualShapes, + btAlignedObjectArray& visualShapeInstances, + btTransform& upAxisTrans, + float& unitMeterScaling); +#endif //COMPARE_WITH_ASSIMP -#endif //LOAD_MESH_FROM_COLLADA_H +#endif //LOAD_MESH_FROM_COLLADA_H diff --git a/examples/Importers/ImportColladaDemo/btMatrix4x4.h b/examples/Importers/ImportColladaDemo/btMatrix4x4.h index 0a71e86a8..54e449a2e 100644 --- a/examples/Importers/ImportColladaDemo/btMatrix4x4.h +++ b/examples/Importers/ImportColladaDemo/btMatrix4x4.h @@ -15,7 +15,6 @@ subject to the following restrictions: //original author: Erwin Coumans */ - #ifndef MATRIX4x4_H #define MATRIX4x4_H @@ -23,55 +22,56 @@ subject to the following restrictions: #include "LinearMath/btQuaternion.h" ///This 4x4 matrix class is extremely limited, just created for the purpose of accumulating transform matrices in COLLADA .dae files -ATTRIBUTE_ALIGNED16(class) btMatrix4x4 +ATTRIBUTE_ALIGNED16(class) +btMatrix4x4 { btVector4 m_el[4]; - public: +public: btMatrix4x4() { } - btMatrix4x4(const btScalar& xx, const btScalar& xy, const btScalar& xz,const btScalar& xw, - const btScalar& yx, const btScalar& yy, const btScalar& yz,const btScalar& yw, - const btScalar& zx, const btScalar& zy, const btScalar& zz, const btScalar& zw, - const btScalar& wx, const btScalar& wy, const btScalar& wz, const btScalar& ww) - { + btMatrix4x4(const btScalar& xx, const btScalar& xy, const btScalar& xz, const btScalar& xw, + const btScalar& yx, const btScalar& yy, const btScalar& yz, const btScalar& yw, + const btScalar& zx, const btScalar& zy, const btScalar& zz, const btScalar& zw, + const btScalar& wx, const btScalar& wy, const btScalar& wz, const btScalar& ww) + { setValue(xx, xy, xz, xw, - yx, yy, yz, yw, - zx, zy, zz,zw, - wx, wy, wz,ww); + yx, yy, yz, yw, + zx, zy, zz, zw, + wx, wy, wz, ww); } ~btMatrix4x4() { } - inline void setValue(const btScalar& xx, const btScalar& xy, const btScalar& xz,const btScalar& xw, - const btScalar& yx, const btScalar& yy, const btScalar& yz,const btScalar& yw, - const btScalar& zx, const btScalar& zy, const btScalar& zz, const btScalar& zw, - const btScalar& wx, const btScalar& wy, const btScalar& wz, const btScalar& ww) - { - m_el[0].setValue(xx,xy,xz,xw); - m_el[1].setValue(yx,yy,yz,yw); - m_el[2].setValue(zx,zy,zz,zw); - m_el[3].setValue(wx,wy,wz,ww); + inline void setValue(const btScalar& xx, const btScalar& xy, const btScalar& xz, const btScalar& xw, + const btScalar& yx, const btScalar& yy, const btScalar& yz, const btScalar& yw, + const btScalar& zx, const btScalar& zy, const btScalar& zz, const btScalar& zw, + const btScalar& wx, const btScalar& wy, const btScalar& wz, const btScalar& ww) + { + m_el[0].setValue(xx, xy, xz, xw); + m_el[1].setValue(yx, yy, yz, yw); + m_el[2].setValue(zx, zy, zz, zw); + m_el[3].setValue(wx, wy, wz, ww); } inline void setIdentity() { - m_el[0].setValue(1,0,0,0); - m_el[1].setValue(0,1,0,0); - m_el[2].setValue(0,0,1,0); - m_el[3].setValue(0,0,0,1); + m_el[0].setValue(1, 0, 0, 0); + m_el[1].setValue(0, 1, 0, 0); + m_el[2].setValue(0, 0, 1, 0); + m_el[3].setValue(0, 0, 0, 1); } inline void setPureRotation(const btQuaternion& orn) { setIdentity(); btMatrix3x3 m3(orn); - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) { - for (int j=0;j<3;j++) + for (int j = 0; j < 3; j++) { m_el[i][j] = m3[i][j]; } @@ -80,78 +80,73 @@ ATTRIBUTE_ALIGNED16(class) btMatrix4x4 inline void setPureScaling(const btVector3& scale) { - m_el[0].setValue(scale[0],0,0,0); - m_el[1].setValue(0,scale[1],0,0); - m_el[2].setValue(0,0,scale[2],0); - m_el[3].setValue(0,0,0,1); + m_el[0].setValue(scale[0], 0, 0, 0); + m_el[1].setValue(0, scale[1], 0, 0); + m_el[2].setValue(0, 0, scale[2], 0); + m_el[3].setValue(0, 0, 0, 1); } inline void setPureTranslation(const btVector3& pos) { - m_el[0].setValue(1,0,0,pos[0]); - m_el[1].setValue(0,1,0,pos[1]); - m_el[2].setValue(0,0,1,pos[2]); - m_el[3].setValue(0,0,0,1); - + m_el[0].setValue(1, 0, 0, pos[0]); + m_el[1].setValue(0, 1, 0, pos[1]); + m_el[2].setValue(0, 0, 1, pos[2]); + m_el[3].setValue(0, 0, 0, 1); } SIMD_FORCE_INLINE const btVector4& operator[](int i) const { btFullAssert(0 <= i && i < 3); - return m_el[i]; + return m_el[i]; } - SIMD_FORCE_INLINE btScalar tdotx(const btVector4& v) const + SIMD_FORCE_INLINE btScalar tdotx(const btVector4& v) const { - return m_el[0].x() * v.x() + m_el[1].x() * v.y() + m_el[2].x() * v.z() + m_el[3].x()* v.w(); + return m_el[0].x() * v.x() + m_el[1].x() * v.y() + m_el[2].x() * v.z() + m_el[3].x() * v.w(); } - SIMD_FORCE_INLINE btScalar tdoty(const btVector4& v) const + SIMD_FORCE_INLINE btScalar tdoty(const btVector4& v) const { return m_el[0].y() * v.x() + m_el[1].y() * v.y() + m_el[2].y() * v.z() + m_el[3].y() * v.w(); } - SIMD_FORCE_INLINE btScalar tdotz(const btVector4& v) const + SIMD_FORCE_INLINE btScalar tdotz(const btVector4& v) const { return m_el[0].z() * v.x() + m_el[1].z() * v.y() + m_el[2].z() * v.z() + m_el[3].z() * v.w(); } - SIMD_FORCE_INLINE btScalar tdotw(const btVector4& v) const + SIMD_FORCE_INLINE btScalar tdotw(const btVector4& v) const { return m_el[0].w() * v.x() + m_el[1].w() * v.y() + m_el[2].w() * v.z() + m_el[3].w() * v.w(); } - SIMD_FORCE_INLINE btMatrix4x4 & + SIMD_FORCE_INLINE btMatrix4x4& operator*=(const btMatrix4x4& m) { setValue( - m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]),m.tdotw(m_el[0]), - m.tdotx(m_el[1]), m.tdoty(m_el[1]), m.tdotz(m_el[1]),m.tdotw(m_el[1]), - m.tdotx(m_el[2]), m.tdoty(m_el[2]), m.tdotz(m_el[2]),m.tdotw(m_el[2]), - m.tdotx(m_el[3]), m.tdoty(m_el[3]), m.tdotz(m_el[3]),m.tdotw(m_el[3])); + m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]), m.tdotw(m_el[0]), + m.tdotx(m_el[1]), m.tdoty(m_el[1]), m.tdotz(m_el[1]), m.tdotw(m_el[1]), + m.tdotx(m_el[2]), m.tdoty(m_el[2]), m.tdotz(m_el[2]), m.tdotw(m_el[2]), + m.tdotx(m_el[3]), m.tdoty(m_el[3]), m.tdotz(m_el[3]), m.tdotw(m_el[3])); return *this; } - - - }; inline btScalar btDot4(const btVector4& v0, const btVector4& v1) { - return v0.x()*v1.x()+v0.y()*v1.y()+v0.z()*v1.z()+v0.w()*v1.w(); + return v0.x() * v1.x() + v0.y() * v1.y() + v0.z() * v1.z() + v0.w() * v1.w(); } -SIMD_FORCE_INLINE btVector3 -operator*(const btMatrix4x4& m, const btVector3& v1) +SIMD_FORCE_INLINE btVector3 +operator*(const btMatrix4x4& m, const btVector3& v1) { - btVector4 v(v1[0],v1[1],v1[2],1); - return btVector3(btDot4(m[0],v), btDot4(m[1],v), btDot4(m[2],v)); + btVector4 v(v1[0], v1[1], v1[2], 1); + return btVector3(btDot4(m[0], v), btDot4(m[1], v), btDot4(m[2], v)); } -SIMD_FORCE_INLINE btMatrix4x4 - operator*(const btMatrix4x4& m1, btMatrix4x4& m2) - { - return btMatrix4x4( - m2.tdotx(m1[0]), m2.tdoty(m1[0]), m2.tdotz(m1[0]),m2.tdotw(m1[0]), - m2.tdotx(m1[1]), m2.tdoty(m1[1]), m2.tdotz(m1[1]),m2.tdotw(m1[1]), - m2.tdotx(m1[2]), m2.tdoty(m1[2]), m2.tdotz(m1[2]),m2.tdotw(m1[2]), - m2.tdotx(m1[3]), m2.tdoty(m1[3]), m2.tdotz(m1[3]),m2.tdotw(m1[3])); - } +SIMD_FORCE_INLINE btMatrix4x4 +operator*(const btMatrix4x4& m1, btMatrix4x4& m2) +{ + return btMatrix4x4( + m2.tdotx(m1[0]), m2.tdoty(m1[0]), m2.tdotz(m1[0]), m2.tdotw(m1[0]), + m2.tdotx(m1[1]), m2.tdoty(m1[1]), m2.tdotz(m1[1]), m2.tdotw(m1[1]), + m2.tdotx(m1[2]), m2.tdoty(m1[2]), m2.tdotz(m1[2]), m2.tdotw(m1[2]), + m2.tdotx(m1[3]), m2.tdoty(m1[3]), m2.tdotz(m1[3]), m2.tdotw(m1[3])); +} - -#endif //MATRIX4x4_H +#endif //MATRIX4x4_H diff --git a/examples/Importers/ImportMJCFDemo/BulletMJCFImporter.cpp b/examples/Importers/ImportMJCFDemo/BulletMJCFImporter.cpp index 97696a839..88f657a76 100644 --- a/examples/Importers/ImportMJCFDemo/BulletMJCFImporter.cpp +++ b/examples/Importers/ImportMJCFDemo/BulletMJCFImporter.cpp @@ -19,7 +19,7 @@ #include "../ImportColladaDemo/LoadMeshFromCollada.h" #include "../OpenGLWindow/ShapeData.h" -#include"../../ThirdPartyLibs/Wavefront/tiny_obj_loader.h" +#include "../../ThirdPartyLibs/Wavefront/tiny_obj_loader.h" #include "../ImportMeshUtility/b3ImportMeshUtility.h" #include "BulletCollision/CollisionDispatch/btCollisionObject.h" #include "BulletCollision/CollisionShapes/btCompoundShape.h" @@ -34,33 +34,27 @@ #include "BulletCollision/CollisionShapes/btTriangleMesh.h" using namespace tinyxml2; - - - #define mjcf_sphere_indiced textured_detailed_sphere_indices #define mjcf_sphere_vertices textured_detailed_sphere_vertices - - static btVector4 sGoogleColors[4] = -{ - btVector4(60. / 256., 186. / 256., 84. / 256., 1), - btVector4(244. / 256., 194. / 256., 13. / 256., 1), - btVector4(219. / 256., 50. / 256., 54. / 256., 1), - btVector4(72. / 256., 133. / 256., 237. / 256., 1), + { + btVector4(60. / 256., 186. / 256., 84. / 256., 1), + btVector4(244. / 256., 194. / 256., 13. / 256., 1), + btVector4(219. / 256., 50. / 256., 54. / 256., 1), + btVector4(72. / 256., 133. / 256., 237. / 256., 1), }; - #include enum ePARENT_LINK_ENUMS { - BASE_LINK_INDEX=-1, + BASE_LINK_INDEX = -1, - INVALID_LINK_INDEX=-2 + INVALID_LINK_INDEX = -2 }; -static int gUid=0; +static int gUid = 0; static bool parseVector4(btVector4& vec4, const std::string& vector_str) { @@ -81,7 +75,7 @@ static bool parseVector4(btVector4& vec4, const std::string& vector_str) { return false; } - vec4.setValue(rgba[0],rgba[1],rgba[2],rgba[3]); + vec4.setValue(rgba[0], rgba[1], rgba[2], rgba[3]); return true; } @@ -102,21 +96,20 @@ static bool parseVector3(btVector3& vec3, const std::string& vector_str, MJCFErr } if (rgba.size() < 3) { - logger->reportWarning( ("Couldn't parse vector3 '" + vector_str + "'").c_str() ); + logger->reportWarning(("Couldn't parse vector3 '" + vector_str + "'").c_str()); return false; } - if (lastThree) { - vec3.setValue(rgba[rgba.size()-3], rgba[rgba.size()-2], rgba[rgba.size()-1]); - } - else - { - vec3.setValue(rgba[0],rgba[1],rgba[2]); - - } + if (lastThree) + { + vec3.setValue(rgba[rgba.size() - 3], rgba[rgba.size() - 2], rgba[rgba.size() - 1]); + } + else + { + vec3.setValue(rgba[0], rgba[1], rgba[2]); + } return true; } - static bool parseVector6(btVector3& v0, btVector3& v1, const std::string& vector_str, MJCFErrorLogger* logger) { v0.setZero(); @@ -136,20 +129,19 @@ static bool parseVector6(btVector3& v0, btVector3& v1, const std::string& vector } if (values.size() < 6) { - logger->reportWarning( ("Couldn't parse 6 floats '" + vector_str + "'").c_str() ); + logger->reportWarning(("Couldn't parse 6 floats '" + vector_str + "'").c_str()); return false; } - v0.setValue(values[0],values[1],values[2]); - v1.setValue(values[3],values[4],values[5]); + v0.setValue(values[0], values[1], values[2]); + v1.setValue(values[3], values[4], values[5]); return true; } - struct MyMJCFAsset { - std::string m_fileName; + std::string m_fileName; }; struct MyMJCFDefaults @@ -169,16 +161,15 @@ struct MyMJCFDefaults double m_defaultRollingFriction; MyMJCFDefaults() - :m_defaultCollisionGroup(1), - m_defaultCollisionMask(1), - m_defaultCollisionMargin(0.001),//assume unit meters, margin is 1mm - m_defaultConDim(3), - m_defaultLateralFriction(0.5), - m_defaultSpinningFriction(0), - m_defaultRollingFriction(0) + : m_defaultCollisionGroup(1), + m_defaultCollisionMask(1), + m_defaultCollisionMargin(0.001), //assume unit meters, margin is 1mm + m_defaultConDim(3), + m_defaultLateralFriction(0.5), + m_defaultSpinningFriction(0), + m_defaultRollingFriction(0) { } - }; struct BulletMJCFImporterInternalData @@ -187,11 +178,11 @@ struct BulletMJCFImporterInternalData struct UrdfRenderingInterface* m_customVisualShapesConverter; char m_pathPrefix[1024]; - std::string m_sourceFileName; // with path - std::string m_fileModelName; // without path - btHashMap m_assets; + std::string m_sourceFileName; // with path + std::string m_fileModelName; // without path + btHashMap m_assets; - btAlignedObjectArray m_models; + btAlignedObjectArray m_models; // std::string m_meshDir; @@ -199,7 +190,6 @@ struct BulletMJCFImporterInternalData std::string m_angleUnits; bool m_inertiaFromGeom; - int m_activeModel; int m_activeBodyUniqueId; @@ -215,18 +205,18 @@ struct BulletMJCFImporterInternalData int m_textureId; BulletMJCFImporterInternalData() - :m_inertiaFromGeom(true), - m_activeModel(-1), - m_activeBodyUniqueId(-1), - m_flags(0), - m_textureId(-1) + : m_inertiaFromGeom(true), + m_activeModel(-1), + m_activeBodyUniqueId(-1), + m_flags(0), + m_textureId(-1) { m_pathPrefix[0] = 0; } ~BulletMJCFImporterInternalData() { - for (int i=0;iGetLineNum()); + sprintf(row, "%d", e->GetLineNum()); #endif std::string str = m_sourceFileName.c_str() + std::string(":") + std::string(row); return str; #endif } - + const UrdfLink* getLink(int modelIndex, int linkIndex) const { - if (modelIndex>=0 && modelIndex= 0 && modelIndex < m_models.size()) { UrdfLink** linkPtrPtr = m_models[modelIndex]->m_links.getAtIndex(linkIndex); if (linkPtrPtr && *linkPtrPtr) @@ -267,7 +257,6 @@ struct BulletMJCFImporterInternalData void parseCompiler(XMLElement* root_xml, MJCFErrorLogger* logger) { - const char* meshDirStr = root_xml->Attribute("meshdir"); if (meshDirStr) { @@ -281,20 +270,19 @@ struct BulletMJCFImporterInternalData const char* angle = root_xml->Attribute("angle"); m_angleUnits = angle ? angle : "degree"; // degrees by default, http://www.mujoco.org/book/modeling.html#compiler const char* inertiaFromGeom = root_xml->Attribute("inertiafromgeom"); - if(inertiaFromGeom && inertiaFromGeom[0] == 'f') // false, other values assumed `true`. + if (inertiaFromGeom && inertiaFromGeom[0] == 'f') // false, other values assumed `true`. { m_inertiaFromGeom = false; } - } - + void parseAssets(XMLElement* root_xml, MJCFErrorLogger* logger) { // - for (XMLElement* child_xml = root_xml->FirstChildElement() ; child_xml ; child_xml = child_xml->NextSiblingElement()) + for (XMLElement* child_xml = root_xml->FirstChildElement(); child_xml; child_xml = child_xml->NextSiblingElement()) { std::string n = child_xml->Value(); - if (n=="mesh") + if (n == "mesh") { const char* assetNameStr = child_xml->Attribute("name"); const char* fileNameStr = child_xml->Attribute("file"); @@ -303,23 +291,21 @@ struct BulletMJCFImporterInternalData btHashString assetName = assetNameStr; MyMJCFAsset asset; asset.m_fileName = m_meshDir + fileNameStr; - m_assets.insert(assetName,asset); + m_assets.insert(assetName, asset); } } - } } - - + bool parseDefaults(MyMJCFDefaults& defaults, XMLElement* root_xml, MJCFErrorLogger* logger) { - bool handled= false; + bool handled = false; //rudimentary 'default' support, would need more work for better feature coverage - for (XMLElement* child_xml = root_xml->FirstChildElement() ; child_xml ; child_xml = child_xml->NextSiblingElement()) + for (XMLElement* child_xml = root_xml->FirstChildElement(); child_xml; child_xml = child_xml->NextSiblingElement()) { std::string n = child_xml->Value(); - - if (n.find("default")!=std::string::npos) + + if (n.find("default") != std::string::npos) { const char* className = child_xml->Attribute("class"); @@ -329,25 +315,25 @@ struct BulletMJCFImporterInternalData if (!curDefaultsPtr) { MyMJCFDefaults def; - m_classDefaults.insert(className,def); + m_classDefaults.insert(className, def); curDefaultsPtr = m_classDefaults[className]; } if (curDefaultsPtr) { - MyMJCFDefaults& curDefaults = *curDefaultsPtr; + MyMJCFDefaults& curDefaults = *curDefaultsPtr; parseDefaults(curDefaults, child_xml, logger); } } } - if (n=="inertial") + if (n == "inertial") { } - if (n=="asset") + if (n == "asset") { - parseAssets(child_xml,logger); + parseAssets(child_xml, logger); } - if (n=="joint") + if (n == "joint") { // Other attributes here: // armature="1" @@ -358,9 +344,9 @@ struct BulletMJCFImporterInternalData defaults.m_defaultJointLimited = child_xml->Attribute("limited"); } } - if (n=="geom") + if (n == "geom") { - //contype, conaffinity + //contype, conaffinity const char* conTypeStr = child_xml->Attribute("contype"); if (conTypeStr) { @@ -380,7 +366,7 @@ struct BulletMJCFImporterInternalData const char* conDimS = child_xml->Attribute("condim"); if (conDimS) { - defaults.m_defaultConDim=urdfLexicalCast(conDimS); + defaults.m_defaultConDim = urdfLexicalCast(conDimS); } int conDim = defaults.m_defaultConDim; @@ -399,43 +385,42 @@ struct BulletMJCFImporterInternalData frictions.push_back(urdfLexicalCast(pieces[i].c_str())); } } - if (frictions.size()>0) + if (frictions.size() > 0) { defaults.m_defaultLateralFriction = frictions[0]; } - if (frictions.size()>1) + if (frictions.size() > 1) { defaults.m_defaultSpinningFriction = frictions[1]; } - if (frictions.size()>2) + if (frictions.size() > 2) { defaults.m_defaultRollingFriction = frictions[2]; } } } } - handled=true; + handled = true; return handled; } - bool parseRootLevel(MyMJCFDefaults& defaults, XMLElement* root_xml,MJCFErrorLogger* logger) + bool parseRootLevel(MyMJCFDefaults& defaults, XMLElement* root_xml, MJCFErrorLogger* logger) { - for (XMLElement* rootxml = root_xml->FirstChildElement() ; rootxml ; rootxml = rootxml->NextSiblingElement()) + for (XMLElement* rootxml = root_xml->FirstChildElement(); rootxml; rootxml = rootxml->NextSiblingElement()) { bool handled = false; std::string n = rootxml->Value(); - - if (n=="body") + if (n == "body") { int modelIndex = m_models.size(); UrdfModel* model = new UrdfModel(); m_models.push_back(model); - parseBody(defaults, rootxml,modelIndex, INVALID_LINK_INDEX,logger); - initTreeAndRoot(*model,logger); + parseBody(defaults, rootxml, modelIndex, INVALID_LINK_INDEX, logger); + initTreeAndRoot(*model, logger); handled = true; } - if (n=="geom") + if (n == "geom") { int modelIndex = m_models.size(); UrdfModel* modelPtr = new UrdfModel(); @@ -450,28 +435,27 @@ struct BulletMJCFImporterInternalData } int linkIndex = modelPtr->m_links.size(); linkPtr->m_linkIndex = linkIndex; - modelPtr->m_links.insert(linkPtr->m_name.c_str(),linkPtr); + modelPtr->m_links.insert(linkPtr->m_name.c_str(), linkPtr); //don't parse geom transform here, it will be inside 'parseGeom' linkPtr->m_linkTransformInWorld.setIdentity(); - -// modelPtr->m_rootLinks.push_back(linkPtr); - btVector3 inertialShift(0,0,0); - parseGeom(defaults, rootxml,modelIndex, linkIndex,logger,inertialShift); - initTreeAndRoot(*modelPtr,logger); + // modelPtr->m_rootLinks.push_back(linkPtr); + + btVector3 inertialShift(0, 0, 0); + parseGeom(defaults, rootxml, modelIndex, linkIndex, logger, inertialShift); + initTreeAndRoot(*modelPtr, logger); handled = true; } - - if (n=="site") + if (n == "site") { handled = true; } if (!handled) { - logger->reportWarning( (sourceFileLocation(rootxml) + ": unhandled root element '" + n + "'").c_str() ); + logger->reportWarning((sourceFileLocation(rootxml) + ": unhandled root element '" + n + "'").c_str()); } } return true; @@ -493,8 +477,8 @@ struct BulletMJCFImporterInternalData if (posStr) { btVector3 pos; - std::string p=posStr; - if (parseVector3(pos,p,logger)) + std::string p = posStr; + if (parseVector3(pos, p, logger)) { jointTrans.setOrigin(pos); } @@ -503,30 +487,31 @@ struct BulletMJCFImporterInternalData { std::string o = ornStr; btVector4 o4; - if (parseVector4(o4,o)) + if (parseVector4(o4, o)) { - btQuaternion orn(o4[3],o4[0],o4[1],o4[2]); + btQuaternion orn(o4[3], o4[0], o4[1], o4[2]); jointTrans.setRotation(orn); } } - btVector3 jointAxis(1,0,0); + btVector3 jointAxis(1, 0, 0); if (axisStr) { std::string ax = axisStr; - parseVector3(jointAxis,ax,logger); - } else + parseVector3(jointAxis, ax, logger); + } + else { - logger->reportWarning( (sourceFileLocation(link_xml) + ": joint without axis attribute").c_str() ); + logger->reportWarning((sourceFileLocation(link_xml) + ": joint without axis attribute").c_str()); } - double range[2] = {1,0}; + double range[2] = {1, 0}; std::string lim = m_globalDefaults.m_defaultJointLimited; if (limitedStr) { lim = limitedStr; } - bool isLimited = lim=="true"; + bool isLimited = lim == "true"; UrdfJointTypes ejtype; if (jType) @@ -547,15 +532,17 @@ struct BulletMJCFImporterInternalData if (isLimited) { ejtype = URDFRevoluteJoint; - } else + } + else { ejtype = URDFContinuousJoint; } jointHandled = true; } - } else + } + else { - logger->reportWarning( (sourceFileLocation(link_xml) + ": expected 'type' attribute for joint").c_str() ); + logger->reportWarning((sourceFileLocation(link_xml) + ": expected 'type' attribute for joint").c_str()); } if (isLimited) @@ -573,11 +560,11 @@ struct BulletMJCFImporterInternalData limits.push_back(urdfLexicalCast(pieces[i].c_str())); } } - if (limits.size()==2) + if (limits.size() == 2) { range[0] = limits[0]; range[1] = limits[1]; - if (m_angleUnits=="degree" && ejtype==URDFRevoluteJoint) + if (m_angleUnits == "degree" && ejtype == URDFRevoluteJoint) { range[0] = limits[0] * B3_PI / 180; range[1] = limits[1] * B3_PI / 180; @@ -585,7 +572,7 @@ struct BulletMJCFImporterInternalData } else { - logger->reportWarning( (sourceFileLocation(link_xml) + ": cannot parse 'range' attribute (units='" + m_angleUnits + "'')").c_str() ); + logger->reportWarning((sourceFileLocation(link_xml) + ": cannot parse 'range' attribute (units='" + m_angleUnits + "'')").c_str()); } } @@ -609,20 +596,20 @@ struct BulletMJCFImporterInternalData // which is why our Euler integrator handles damping // implicitly. See Integration in the Computation chapter. - const UrdfLink* linkPtr = getLink(modelIndex,linkIndex); - + const UrdfLink* linkPtr = getLink(modelIndex, linkIndex); + btTransform parentLinkToJointTransform; parentLinkToJointTransform.setIdentity(); - parentLinkToJointTransform = parentToLinkTrans*jointTrans; + parentLinkToJointTransform = parentToLinkTrans * jointTrans; jointTransOut = jointTrans; if (jointHandled) { UrdfJoint* jointPtr = new UrdfJoint(); - jointPtr->m_childLinkName=linkPtr->m_name; - const UrdfLink* parentLink = getLink(modelIndex,parentLinkIndex); - jointPtr->m_parentLinkName =parentLink->m_name; - jointPtr->m_localJointAxis=jointAxis; + jointPtr->m_childLinkName = linkPtr->m_name; + const UrdfLink* parentLink = getLink(modelIndex, parentLinkIndex); + jointPtr->m_parentLinkName = parentLink->m_name; + jointPtr->m_localJointAxis = jointAxis; jointPtr->m_parentLinkToJointTransform = parentLinkToJointTransform; jointPtr->m_type = ejtype; int numJoints = m_models[modelIndex]->m_joints.size(); @@ -633,14 +620,15 @@ struct BulletMJCFImporterInternalData if (nameStr) { - jointPtr->m_name =nameStr; - } else + jointPtr->m_name = nameStr; + } + else { char jointName[1024]; - sprintf(jointName,"joint%d_%d_%d",gUid++,linkIndex,numJoints); - jointPtr->m_name =jointName; + sprintf(jointName, "joint%d_%d_%d", gUid++, linkIndex, numJoints); + jointPtr->m_name = jointName; } - m_models[modelIndex]->m_joints.insert(jointPtr->m_name.c_str(),jointPtr); + m_models[modelIndex]->m_joints.insert(jointPtr->m_name.c_str(), jointPtr); return true; } /* @@ -656,18 +644,17 @@ struct BulletMJCFImporterInternalData bool parseGeom(MyMJCFDefaults& defaults, XMLElement* link_xml, int modelIndex, int linkIndex, MJCFErrorLogger* logger, btVector3& inertialShift) { UrdfLink** linkPtrPtr = m_models[modelIndex]->m_links.getAtIndex(linkIndex); - if (linkPtrPtr==0) + if (linkPtrPtr == 0) { // XXX: should it be assert? logger->reportWarning("Invalide linkindex"); return false; } UrdfLink* linkPtr = *linkPtrPtr; - + btTransform linkLocalFrame; linkLocalFrame.setIdentity(); - bool handledGeomType = false; UrdfGeometry geom; @@ -679,7 +666,7 @@ struct BulletMJCFImporterInternalData if (conDimS) { conDim = urdfLexicalCast(conDimS); - } + } } double lateralFriction = defaults.m_defaultLateralFriction; @@ -701,33 +688,32 @@ struct BulletMJCFImporterInternalData frictions.push_back(urdfLexicalCast(pieces[i].c_str())); } } - if (frictions.size()>0) + if (frictions.size() > 0) { lateralFriction = frictions[0]; } - if (frictions.size()>1 && conDim>3) + if (frictions.size() > 1 && conDim > 3) { spinningFriction = frictions[1]; } - if (frictions.size()>2 && conDim>4) + if (frictions.size() > 2 && conDim > 4) { rollingFriction = frictions[2]; } - } - linkPtr->m_contactInfo.m_lateralFriction=lateralFriction; - linkPtr->m_contactInfo.m_spinningFriction=spinningFriction; - linkPtr->m_contactInfo.m_rollingFriction=rollingFriction; + linkPtr->m_contactInfo.m_lateralFriction = lateralFriction; + linkPtr->m_contactInfo.m_spinningFriction = spinningFriction; + linkPtr->m_contactInfo.m_rollingFriction = rollingFriction; - if (conDim>3) + if (conDim > 3) { - linkPtr->m_contactInfo.m_spinningFriction=defaults.m_defaultSpinningFriction; + linkPtr->m_contactInfo.m_spinningFriction = defaults.m_defaultSpinningFriction; linkPtr->m_contactInfo.m_flags |= URDF_CONTACT_HAS_SPINNING_FRICTION; } - if (conDim>4) + if (conDim > 4) { - linkPtr->m_contactInfo.m_rollingFriction=defaults.m_defaultRollingFriction; + linkPtr->m_contactInfo.m_rollingFriction = defaults.m_defaultRollingFriction; linkPtr->m_contactInfo.m_flags |= URDF_CONTACT_HAS_ROLLING_FRICTION; } @@ -745,7 +731,7 @@ struct BulletMJCFImporterInternalData if (!rgba.empty()) { // "0 0.7 0.7 1" - if ((m_flags&CUF_MJCF_COLORS_FROM_FILE)) + if ((m_flags & CUF_MJCF_COLORS_FROM_FILE)) { parseVector4(geom.m_localMaterial.m_matColor.m_rgbaColor, rgba); geom.m_hasLocalMaterial = true; @@ -753,14 +739,12 @@ struct BulletMJCFImporterInternalData } } - - const char* posS = link_xml->Attribute("pos"); if (posS) { - btVector3 pos(0,0,0); + btVector3 pos(0, 0, 0); std::string p = posS; - if (parseVector3(pos,p,logger)) + if (parseVector3(pos, p, logger)) { linkLocalFrame.setOrigin(pos); } @@ -769,11 +753,11 @@ struct BulletMJCFImporterInternalData const char* ornS = link_xml->Attribute("quat"); if (ornS) { - btQuaternion orn(0,0,0,1); + btQuaternion orn(0, 0, 0, 1); btVector4 o4; if (parseVector4(o4, ornS)) { - orn.setValue(o4[1],o4[2],o4[3],o4[0]); + orn.setValue(o4[1], o4[2], o4[3], o4[0]); linkLocalFrame.setRotation(orn); } } @@ -781,11 +765,11 @@ struct BulletMJCFImporterInternalData const char* axis_and_angle = link_xml->Attribute("axisangle"); if (axis_and_angle) { - btQuaternion orn(0,0,0,1); + btQuaternion orn(0, 0, 0, 1); btVector4 o4; if (parseVector4(o4, axis_and_angle)) { - orn.setRotation(btVector3(o4[0],o4[1],o4[2]), o4[3]); + orn.setRotation(btVector3(o4[0], o4[1], o4[2]), o4[3]); linkLocalFrame.setRotation(orn); } } @@ -795,29 +779,28 @@ struct BulletMJCFImporterInternalData { std::string geomType = gType; - if (geomType == "plane") { geom.m_type = URDF_GEOM_PLANE; - geom.m_planeNormal.setValue(0,0,1); - btVector3 size(1,1,1); + geom.m_planeNormal.setValue(0, 0, 1); + btVector3 size(1, 1, 1); if (sz) { std::string sizeStr = sz; bool lastThree = false; - parseVector3(size,sizeStr,logger,lastThree); + parseVector3(size, sizeStr, logger, lastThree); } geom.m_boxSize = size; handledGeomType = true; } if (geomType == "box") { - btVector3 size(1,1,1); + btVector3 size(1, 1, 1); if (sz) { std::string sizeStr = sz; bool lastThree = false; - parseVector3(size,sizeStr,logger,lastThree); + parseVector3(size, sizeStr, logger, lastThree); } geom.m_type = URDF_GEOM_BOX; geom.m_boxSize = size; @@ -830,9 +813,10 @@ struct BulletMJCFImporterInternalData if (sz) { geom.m_sphereRadius = urdfLexicalCast(sz); - } else + } + else { - logger->reportWarning( (sourceFileLocation(link_xml) + ": no size field (scalar) in sphere geom").c_str() ); + logger->reportWarning((sourceFileLocation(link_xml) + ": no size field (scalar) in sphere geom").c_str()); } handledGeomType = true; } @@ -840,7 +824,7 @@ struct BulletMJCFImporterInternalData if (geomType == "capsule" || geomType == "cylinder") { // - geom.m_type = geomType=="cylinder" ? URDF_GEOM_CYLINDER : URDF_GEOM_CAPSULE; + geom.m_type = geomType == "cylinder" ? URDF_GEOM_CYLINDER : URDF_GEOM_CAPSULE; btArray pieces; btArray sizes; @@ -855,19 +839,20 @@ struct BulletMJCFImporterInternalData } } - geom.m_capsuleRadius = 2.00f; // 2 to make it visible if something is wrong + geom.m_capsuleRadius = 2.00f; // 2 to make it visible if something is wrong geom.m_capsuleHeight = 2.00f; - if (sizes.size()>0) + if (sizes.size() > 0) { geom.m_capsuleRadius = sizes[0]; - if (sizes.size()>1) + if (sizes.size() > 1) { - geom.m_capsuleHeight = 2*sizes[1]; + geom.m_capsuleHeight = 2 * sizes[1]; } - } else + } + else { - logger->reportWarning( (sourceFileLocation(link_xml) + ": couldn't convert 'size' attribute of capsule geom").c_str() ); + logger->reportWarning((sourceFileLocation(link_xml) + ": couldn't convert 'size' attribute of capsule geom").c_str()); } const char* fromtoStr = link_xml->Attribute("fromto"); geom.m_hasFromTo = false; @@ -876,21 +861,23 @@ struct BulletMJCFImporterInternalData { geom.m_hasFromTo = true; std::string fromto = fromtoStr; - parseVector6(geom.m_capsuleFrom,geom.m_capsuleTo,fromto,logger); - inertialShift=0.5*(geom.m_capsuleFrom+geom.m_capsuleTo); + parseVector6(geom.m_capsuleFrom, geom.m_capsuleTo, fromto, logger); + inertialShift = 0.5 * (geom.m_capsuleFrom + geom.m_capsuleTo); handledGeomType = true; - } else + } + else { - if (sizes.size()<2) + if (sizes.size() < 2) { - logger->reportWarning( (sourceFileLocation(link_xml) + ": capsule without fromto attribute requires 2 sizes (radius and halfheight)").c_str() ); - } else + logger->reportWarning((sourceFileLocation(link_xml) + ": capsule without fromto attribute requires 2 sizes (radius and halfheight)").c_str()); + } + else { handledGeomType = true; } } } - if (geomType=="mesh") + if (geomType == "mesh") { const char* meshStr = link_xml->Attribute("mesh"); if (meshStr) @@ -906,7 +893,7 @@ struct BulletMJCFImporterInternalData &geom.m_meshFileType); handledGeomType = exists; - geom.m_meshScale.setValue(1,1,1); + geom.m_meshScale.setValue(1, 1, 1); //todo: parse mesh scale if (sz) { @@ -916,7 +903,6 @@ struct BulletMJCFImporterInternalData } if (handledGeomType) { - { UrdfCollision col; col.m_flags |= URDF_HAS_COLLISION_GROUP; @@ -925,7 +911,7 @@ struct BulletMJCFImporterInternalData col.m_flags |= URDF_HAS_COLLISION_MASK; col.m_collisionMask = defaults.m_defaultCollisionMask; - //contype, conaffinity + //contype, conaffinity const char* conTypeStr = link_xml->Attribute("contype"); if (conTypeStr) { @@ -950,18 +936,16 @@ struct BulletMJCFImporterInternalData vis.m_linkLocalFrame = linkLocalFrame; vis.m_sourceFileLocation = sourceFileLocation(link_xml); linkPtr->m_visualArray.push_back(vis); - } - - - - } else - { - logger->reportWarning( (sourceFileLocation(link_xml) + ": unhandled geom type '" + geomType + "'").c_str() ); } - } else + else + { + logger->reportWarning((sourceFileLocation(link_xml) + ": unhandled geom type '" + geomType + "'").c_str()); + } + } + else { - logger->reportWarning( (sourceFileLocation(link_xml) + ": geom requires type").c_str() ); + logger->reportWarning((sourceFileLocation(link_xml) + ": geom requires type").c_str()); } return handledGeomType; @@ -975,96 +959,98 @@ struct BulletMJCFImporterInternalData const char* p = link_xml->Attribute("pos"); if (p) { - btVector3 pos(0,0,0); + btVector3 pos(0, 0, 0); std::string pstr = p; - if (parseVector3(pos,pstr,logger)) + if (parseVector3(pos, pstr, logger)) { tr.setOrigin(pos); } - - } else + } + else { -// logger->reportWarning("body should have pos attribute"); + // logger->reportWarning("body should have pos attribute"); } const char* o = link_xml->Attribute("quat"); if (o) { std::string ornstr = o; btVector4 o4; - btQuaternion orn(0,0,0,1); - if (parseVector4(o4,ornstr)) + btQuaternion orn(0, 0, 0, 1); + if (parseVector4(o4, ornstr)) { - orn.setValue(o4[1],o4[2],o4[3],o4[0]);//MuJoCo quats are [w,x,y,z], Bullet uses [x,y,z,w] + orn.setValue(o4[1], o4[2], o4[3], o4[0]); //MuJoCo quats are [w,x,y,z], Bullet uses [x,y,z,w] tr.setRotation(orn); } - } else + } + else { -// logger->reportWarning("body doesn't have quat (orientation) attribute"); + // logger->reportWarning("body doesn't have quat (orientation) attribute"); } return tr; } - double computeVolume(const UrdfLink* linkPtr,MJCFErrorLogger* logger) const + double computeVolume(const UrdfLink* linkPtr, MJCFErrorLogger* logger) const { double totalVolume = 0; - for (int i=0;im_collisionArray.size();i++) + for (int i = 0; i < linkPtr->m_collisionArray.size(); i++) { const UrdfCollision* col = &linkPtr->m_collisionArray[i]; switch (col->m_geometry.m_type) { - case URDF_GEOM_SPHERE: - { - double r = col->m_geometry.m_sphereRadius; - totalVolume += 4./3.*SIMD_PI*r*r*r; - break; - } - case URDF_GEOM_BOX: - { - totalVolume += 8. * col->m_geometry.m_boxSize[0]* - col->m_geometry.m_boxSize[1]* - col->m_geometry.m_boxSize[2]; - break; - } - case URDF_GEOM_MESH: - { - //todo (based on mesh bounding box?) - break; - } - case URDF_GEOM_PLANE: - { - //todo - break; - } - case URDF_GEOM_CDF: - { - //todo - break; - } - case URDF_GEOM_CYLINDER: - case URDF_GEOM_CAPSULE: - { - //one sphere - double r = col->m_geometry.m_capsuleRadius; - if (col->m_geometry.m_type==URDF_GEOM_CAPSULE) + case URDF_GEOM_SPHERE: { - totalVolume += 4./3.*SIMD_PI*r*r*r; + double r = col->m_geometry.m_sphereRadius; + totalVolume += 4. / 3. * SIMD_PI * r * r * r; + break; } - btScalar h(0); - if (col->m_geometry.m_hasFromTo) + case URDF_GEOM_BOX: + { + totalVolume += 8. * col->m_geometry.m_boxSize[0] * + col->m_geometry.m_boxSize[1] * + col->m_geometry.m_boxSize[2]; + break; + } + case URDF_GEOM_MESH: + { + //todo (based on mesh bounding box?) + break; + } + case URDF_GEOM_PLANE: + { + //todo + break; + } + case URDF_GEOM_CDF: + { + //todo + break; + } + case URDF_GEOM_CYLINDER: + case URDF_GEOM_CAPSULE: + { + //one sphere + double r = col->m_geometry.m_capsuleRadius; + if (col->m_geometry.m_type == URDF_GEOM_CAPSULE) + { + totalVolume += 4. / 3. * SIMD_PI * r * r * r; + } + btScalar h(0); + if (col->m_geometry.m_hasFromTo) + { + //and one cylinder of 'height' + h = (col->m_geometry.m_capsuleFrom - col->m_geometry.m_capsuleTo).length(); + } + else + { + h = col->m_geometry.m_capsuleHeight; + } + totalVolume += SIMD_PI * r * r * h; + break; + } + default: { - //and one cylinder of 'height' - h = (col->m_geometry.m_capsuleFrom-col->m_geometry.m_capsuleTo).length(); - } else - { - h = col->m_geometry.m_capsuleHeight; } - totalVolume += SIMD_PI*r*r*h; - break; - } - default: - { - } } } @@ -1093,8 +1079,8 @@ struct BulletMJCFImporterInternalData { linkPtr->m_name = namePtr; } - linkPtr->m_linkIndex = orgChildLinkIndex ; - modelPtr->m_links.insert(linkPtr->m_name.c_str(),linkPtr); + linkPtr->m_linkIndex = orgChildLinkIndex; + modelPtr->m_links.insert(linkPtr->m_name.c_str(), linkPtr); return orgChildLinkIndex; } @@ -1115,56 +1101,53 @@ struct BulletMJCFImporterInternalData } } const char* bodyName = link_xml->Attribute("name"); - int orgChildLinkIndex = createBody(modelIndex,bodyName); + int orgChildLinkIndex = createBody(modelIndex, bodyName); btTransform localInertialFrame; localInertialFrame.setIdentity(); -// int curChildLinkIndex = orgChildLinkIndex; + // int curChildLinkIndex = orgChildLinkIndex; std::string bodyN; - + if (bodyName) { bodyN = bodyName; - } else + } + else { char anon[1024]; - sprintf(anon,"anon%d",gUid++); - bodyN = anon; + sprintf(anon, "anon%d", gUid++); + bodyN = anon; } - -// btTransform orgLinkTransform = parseTransform(link_xml,logger); + // btTransform orgLinkTransform = parseTransform(link_xml,logger); - btTransform linkTransform = parseTransform(link_xml,logger); - UrdfLink* linkPtr = getLink(modelIndex,orgChildLinkIndex); - - + btTransform linkTransform = parseTransform(link_xml, logger); + UrdfLink* linkPtr = getLink(modelIndex, orgChildLinkIndex); bool massDefined = false; - - + btScalar mass = 0.f; - btVector3 localInertiaDiag(0,0,0); - // int thisLinkIndex = -2; + btVector3 localInertiaDiag(0, 0, 0); + // int thisLinkIndex = -2; bool hasJoint = false; btTransform jointTrans; jointTrans.setIdentity(); bool skipFixedJoint = false; - - for (XMLElement* xml = link_xml->FirstChildElement() ; xml ; xml = xml->NextSiblingElement()) + + for (XMLElement* xml = link_xml->FirstChildElement(); xml; xml = xml->NextSiblingElement()) { bool handled = false; std::string n = xml->Value(); - if (n=="inertial") + if (n == "inertial") { // - + const char* p = xml->Attribute("pos"); if (p) { std::string posStr = p; - btVector3 inertialPos(0,0,0); - if (parseVector3(inertialPos,posStr,logger)) + btVector3 inertialPos(0, 0, 0); + if (parseVector3(inertialPos, posStr, logger)) { localInertialFrame.setOrigin(inertialPos); } @@ -1173,11 +1156,11 @@ struct BulletMJCFImporterInternalData if (o) { std::string ornStr = o; - btQuaternion orn(0,0,0,1); + btQuaternion orn(0, 0, 0, 1); btVector4 o4; - if (parseVector4(o4,ornStr)) + if (parseVector4(o4, ornStr)) { - orn.setValue(o4[1],o4[2],o4[3],o4[0]); + orn.setValue(o4[1], o4[2], o4[3], o4[0]); localInertialFrame.setRotation(orn); } } @@ -1190,68 +1173,68 @@ struct BulletMJCFImporterInternalData if (i) { std::string istr = i; - parseVector3(localInertiaDiag,istr,logger); + parseVector3(localInertiaDiag, istr, logger); } - + massDefined = true; handled = true; - if (!m_inertiaFromGeom) { + if (!m_inertiaFromGeom) + { linkPtr->m_inertia.m_mass = mass; linkPtr->m_inertia.m_linkLocalFrame = localInertialFrame; linkPtr->m_inertia.m_ixx = localInertiaDiag[0]; linkPtr->m_inertia.m_iyy = localInertiaDiag[1]; linkPtr->m_inertia.m_izz = localInertiaDiag[2]; } - } - if (n=="joint") + if (n == "joint") { if (!hasJoint) { const char* jType = xml->Attribute("type"); - std::string jointType = jType? jType:""; + std::string jointType = jType ? jType : ""; - if (newParentLinkIndex!=INVALID_LINK_INDEX || jointType!="free") + if (newParentLinkIndex != INVALID_LINK_INDEX || jointType != "free") { - if (newParentLinkIndex==INVALID_LINK_INDEX) + if (newParentLinkIndex == INVALID_LINK_INDEX) { - int newRootLinkIndex = createBody(modelIndex,0); - UrdfLink* rootLink = getLink(modelIndex,newRootLinkIndex); + int newRootLinkIndex = createBody(modelIndex, 0); + UrdfLink* rootLink = getLink(modelIndex, newRootLinkIndex); rootLink->m_inertia.m_mass = 0; rootLink->m_linkTransformInWorld.setIdentity(); newParentLinkIndex = newRootLinkIndex; } - int newLinkIndex = createBody(modelIndex,0); - parseJoint(curDefaults,xml,modelIndex,newParentLinkIndex, newLinkIndex,logger,linkTransform,jointTrans); - + int newLinkIndex = createBody(modelIndex, 0); + parseJoint(curDefaults, xml, modelIndex, newParentLinkIndex, newLinkIndex, logger, linkTransform, jointTrans); + //getLink(modelIndex,newLinkIndex)->m_linkTransformInWorld = jointTrans*linkTransform; - + linkTransform = jointTrans.inverse(); newParentLinkIndex = newLinkIndex; //newParentLinkIndex, curChildLinkIndex hasJoint = true; handled = true; } - } else + } + else { - int newLinkIndex = createBody(modelIndex,0); - btTransform joint2nextjoint = jointTrans.inverse(); + int newLinkIndex = createBody(modelIndex, 0); + btTransform joint2nextjoint = jointTrans.inverse(); btTransform unused; - parseJoint(curDefaults, xml,modelIndex,newParentLinkIndex, newLinkIndex,logger,joint2nextjoint,unused); + parseJoint(curDefaults, xml, modelIndex, newParentLinkIndex, newLinkIndex, logger, joint2nextjoint, unused); newParentLinkIndex = newLinkIndex; //todo: compute relative joint transforms (if any) and append to linkTransform hasJoint = true; handled = true; } - } if (n == "geom") { - btVector3 inertialShift(0,0,0); - parseGeom(curDefaults, xml,modelIndex, orgChildLinkIndex , logger,inertialShift); + btVector3 inertialShift(0, 0, 0); + parseGeom(curDefaults, xml, modelIndex, orgChildLinkIndex, logger, inertialShift); if (!massDefined) { localInertialFrame.setOrigin(inertialShift); @@ -1260,24 +1243,24 @@ struct BulletMJCFImporterInternalData } //recursive - if (n=="body") + if (n == "body") { - parseBody(curDefaults, xml,modelIndex,orgChildLinkIndex,logger); + parseBody(curDefaults, xml, modelIndex, orgChildLinkIndex, logger); handled = true; } - if (n=="light") + if (n == "light") { handled = true; } - if (n=="site") + if (n == "site") { handled = true; } if (!handled) { - logger->reportWarning( (sourceFileLocation(xml) + ": unknown field '" + n + "'").c_str() ); + logger->reportWarning((sourceFileLocation(xml) + ": unknown field '" + n + "'").c_str()); } } @@ -1288,42 +1271,42 @@ struct BulletMJCFImporterInternalData //linkPtr->m_linkTransformInWorld.setIdentity(); //default to 'fixed' joint UrdfJoint* jointPtr = new UrdfJoint(); - jointPtr->m_childLinkName=linkPtr->m_name; - const UrdfLink* parentLink = getLink(modelIndex,newParentLinkIndex); - jointPtr->m_parentLinkName =parentLink->m_name; - jointPtr->m_localJointAxis.setValue(1,0,0); + jointPtr->m_childLinkName = linkPtr->m_name; + const UrdfLink* parentLink = getLink(modelIndex, newParentLinkIndex); + jointPtr->m_parentLinkName = parentLink->m_name; + jointPtr->m_localJointAxis.setValue(1, 0, 0); jointPtr->m_parentLinkToJointTransform = linkTransform; jointPtr->m_type = URDFFixedJoint; char jointName[1024]; - sprintf(jointName,"jointfix_%d_%d",gUid++,newParentLinkIndex); - jointPtr->m_name =jointName; - m_models[modelIndex]->m_joints.insert(jointPtr->m_name.c_str(),jointPtr); + sprintf(jointName, "jointfix_%d_%d", gUid++, newParentLinkIndex); + jointPtr->m_name = jointName; + m_models[modelIndex]->m_joints.insert(jointPtr->m_name.c_str(), jointPtr); } //check mass/inertia if (!massDefined) { double density = 1000; - double volume = computeVolume(linkPtr,logger); + double volume = computeVolume(linkPtr, logger); mass = density * volume; } - linkPtr->m_inertia.m_linkLocalFrame = localInertialFrame;// = jointTrans.inverse(); + linkPtr->m_inertia.m_linkLocalFrame = localInertialFrame; // = jointTrans.inverse(); linkPtr->m_inertia.m_mass = mass; return true; } void recurseAddChildLinks(UrdfModel* model, UrdfLink* link) { - for (int i=0;im_childLinks.size();i++) + for (int i = 0; i < link->m_childLinks.size(); i++) { int linkIndex = model->m_links.size(); link->m_childLinks[i]->m_linkIndex = linkIndex; const char* linkName = link->m_childLinks[i]->m_name.c_str(); - model->m_links.insert(linkName,link->m_childLinks[i]); + model->m_links.insert(linkName, link->m_childLinks[i]); } - for (int i=0;im_childLinks.size();i++) + for (int i = 0; i < link->m_childLinks.size(); i++) { - recurseAddChildLinks(model,link->m_childLinks[i]); + recurseAddChildLinks(model, link->m_childLinks[i]); } } @@ -1331,10 +1314,10 @@ struct BulletMJCFImporterInternalData { // every link has children links and joints, but no parents, so we create a // local convenience data structure for keeping child->parent relations - btHashMap parentLinkTree; - + btHashMap parentLinkTree; + // loop through all joints, for every link, assign children links and children joints - for (int i=0;ireportError(joint->m_name.c_str()); return false; } - + UrdfLink** childLinkPtr = model.m_links.find(joint->m_childLinkName.c_str()); if (!childLinkPtr) { @@ -1358,7 +1341,7 @@ struct BulletMJCFImporterInternalData return false; } UrdfLink* childLink = *childLinkPtr; - + UrdfLink** parentLinkPtr = model.m_links.find(joint->m_parentLinkName.c_str()); if (!parentLinkPtr) { @@ -1367,18 +1350,18 @@ struct BulletMJCFImporterInternalData return false; } UrdfLink* parentLink = *parentLinkPtr; - - childLink->m_parentLink = parentLink; - + + childLink->m_parentLink = parentLink; + childLink->m_parentJoint = joint; parentLink->m_childJoints.push_back(joint); parentLink->m_childLinks.push_back(childLink); - parentLinkTree.insert(childLink->m_name.c_str(),parentLink->m_name.c_str()); + parentLinkTree.insert(childLink->m_name.c_str(), parentLink->m_name.c_str()); } } //search for children that have no parent, those are 'root' - for (int i=0;im_linkIndex = i; - + if (!link->m_parentLink) { model.m_rootLinks.push_back(link); } } - } - - if (model.m_rootLinks.size()>1) + + if (model.m_rootLinks.size() > 1) { logger->reportWarning("URDF file with multiple root links found"); } - - if (model.m_rootLinks.size()==0) + + if (model.m_rootLinks.size() == 0) { logger->reportError("URDF without root link found"); return false; @@ -1409,23 +1391,21 @@ struct BulletMJCFImporterInternalData //re-index the link indices so parent indices are always smaller than child indices btAlignedObjectArray links; links.resize(model.m_links.size()); - for (int i=0;im_linkIndex = linkIndex; - model.m_links.insert(rootLink->m_name.c_str(),rootLink); + model.m_links.insert(rootLink->m_name.c_str(), rootLink); recurseAddChildLinks(&model, rootLink); } return true; - } - }; BulletMJCFImporter::BulletMJCFImporter(struct GUIHelperInterface* helper, UrdfRenderingInterface* customConverter, int flags) @@ -1444,47 +1424,45 @@ BulletMJCFImporter::~BulletMJCFImporter() bool BulletMJCFImporter::loadMJCF(const char* fileName, MJCFErrorLogger* logger, bool forceFixedBase) { - if (strlen(fileName)==0) - return false; + if (strlen(fileName) == 0) + return false; -//int argc=0; + //int argc=0; char relativeFileName[1024]; - + b3FileUtils fu; - + //bool fileFound = fu.findFile(fileName, relativeFileName, 1024); - bool fileFound = (b3ResourcePath::findResourcePath(fileName,relativeFileName,1024)>0); + bool fileFound = (b3ResourcePath::findResourcePath(fileName, relativeFileName, 1024) > 0); m_data->m_sourceFileName = relativeFileName; - + std::string xml_string; m_data->m_pathPrefix[0] = 0; - - if (!fileFound){ - std::cerr << "MJCF file not found" << std::endl; + + if (!fileFound) + { + std::cerr << "MJCF file not found" << std::endl; return false; - } else - { - + } + else + { int maxPathLen = 1024; - fu.extractPath(relativeFileName,m_data->m_pathPrefix,maxPathLen); + fu.extractPath(relativeFileName, m_data->m_pathPrefix, maxPathLen); - - std::fstream xml_file(relativeFileName, std::fstream::in); - while ( xml_file.good()) - { - std::string line; - std::getline( xml_file, line); - xml_string += (line + "\n"); - } - xml_file.close(); + std::fstream xml_file(relativeFileName, std::fstream::in); + while (xml_file.good()) + { + std::string line; + std::getline(xml_file, line); + xml_string += (line + "\n"); + } + xml_file.close(); if (parseMJCFString(xml_string.c_str(), logger)) { return true; } - } - - + } return false; } @@ -1504,7 +1482,7 @@ bool BulletMJCFImporter::parseMJCFString(const char* xmlText, MJCFErrorLogger* l return false; } - XMLElement *mujoco_xml = xml_doc.FirstChildElement("mujoco"); + XMLElement* mujoco_xml = xml_doc.FirstChildElement("mujoco"); if (!mujoco_xml) { logger->reportWarning("Cannot find root element"); @@ -1522,32 +1500,29 @@ bool BulletMJCFImporter::parseMJCFString(const char* xmlText, MJCFErrorLogger* l for (XMLElement* link_xml = mujoco_xml->FirstChildElement("default"); link_xml; link_xml = link_xml->NextSiblingElement("default")) { - m_data->parseDefaults(m_data->m_globalDefaults,link_xml,logger); + m_data->parseDefaults(m_data->m_globalDefaults, link_xml, logger); } for (XMLElement* link_xml = mujoco_xml->FirstChildElement("compiler"); link_xml; link_xml = link_xml->NextSiblingElement("compiler")) { - m_data->parseCompiler(link_xml,logger); + m_data->parseCompiler(link_xml, logger); } - for (XMLElement* link_xml = mujoco_xml->FirstChildElement("asset"); link_xml; link_xml = link_xml->NextSiblingElement("asset")) { - m_data->parseAssets(link_xml,logger); + m_data->parseAssets(link_xml, logger); } - + for (XMLElement* link_xml = mujoco_xml->FirstChildElement("body"); link_xml; link_xml = link_xml->NextSiblingElement("body")) { - m_data->parseRootLevel(m_data->m_globalDefaults, link_xml,logger); + m_data->parseRootLevel(m_data->m_globalDefaults, link_xml, logger); } for (XMLElement* link_xml = mujoco_xml->FirstChildElement("worldbody"); link_xml; link_xml = link_xml->NextSiblingElement("worldbody")) { - m_data->parseRootLevel(m_data->m_globalDefaults, link_xml,logger); + m_data->parseRootLevel(m_data->m_globalDefaults, link_xml, logger); } - - return true; } @@ -1558,7 +1533,7 @@ const char* BulletMJCFImporter::getPathPrefix() int BulletMJCFImporter::getRootLinkIndex() const { - if (m_data->m_activeModel>=0 && m_data->m_activeModelm_models.size()) + if (m_data->m_activeModel >= 0 && m_data->m_activeModel < m_data->m_models.size()) { if (m_data->m_models[m_data->m_activeModel]->m_rootLinks.size()) { @@ -1568,24 +1543,21 @@ int BulletMJCFImporter::getRootLinkIndex() const return -1; } - - std::string BulletMJCFImporter::getLinkName(int linkIndex) const - { - const UrdfLink* link = m_data->getLink(m_data->m_activeModel,linkIndex); - if (link) - { - return link->m_name; - } +std::string BulletMJCFImporter::getLinkName(int linkIndex) const +{ + const UrdfLink* link = m_data->getLink(m_data->m_activeModel, linkIndex); + if (link) + { + return link->m_name; + } return ""; - } +} std::string BulletMJCFImporter::getBodyName() const { return m_data->m_fileModelName; } - - bool BulletMJCFImporter::getLinkColor2(int linkIndex, struct UrdfMaterialColor& matCol) const { bool hasLinkColor = false; @@ -1629,38 +1601,36 @@ bool BulletMJCFImporter::getLinkColor2(int linkIndex, struct UrdfMaterialColor& bool BulletMJCFImporter::getLinkColor(int linkIndex, btVector4& colorRGBA) const { -// UrdfLink* link = m_data->getLink(linkIndex); + // UrdfLink* link = m_data->getLink(linkIndex); return false; } //todo: placeholder implementation //MuJoCo type/affinity is different from Bullet group/mask, so we should implement a custom collision filter instead //(contype1 & conaffinity2) || (contype2 & conaffinity1) -int BulletMJCFImporter::getCollisionGroupAndMask(int linkIndex, int& colGroup, int& colMask) const +int BulletMJCFImporter::getCollisionGroupAndMask(int linkIndex, int& colGroup, int& colMask) const { int flags = 0; - - const UrdfLink* link = m_data->getLink(m_data->m_activeModel,linkIndex); + + const UrdfLink* link = m_data->getLink(m_data->m_activeModel, linkIndex); if (link) { - for (int i=0;im_collisionArray.size();i++) + for (int i = 0; i < link->m_collisionArray.size(); i++) { const UrdfCollision& col = link->m_collisionArray[i]; colGroup = col.m_collisionGroup; flags |= URDF_HAS_COLLISION_GROUP; colMask = col.m_collisionMask; flags |= URDF_HAS_COLLISION_MASK; - } } - + return flags; } - std::string BulletMJCFImporter::getJointName(int linkIndex) const { - const UrdfLink* link = m_data->getLink(m_data->m_activeModel,linkIndex); + const UrdfLink* link = m_data->getLink(m_data->m_activeModel, linkIndex); if (link) { if (link->m_parentJoint) @@ -1672,55 +1642,55 @@ std::string BulletMJCFImporter::getJointName(int linkIndex) const return ""; } - //fill mass and inertial data. If inertial data is missing, please initialize mass, inertia to sensitive values, and inertialFrame to identity. -void BulletMJCFImporter::getMassAndInertia(int urdfLinkIndex, btScalar& mass,btVector3& localInertiaDiagonal, btTransform& inertialFrame) const +//fill mass and inertial data. If inertial data is missing, please initialize mass, inertia to sensitive values, and inertialFrame to identity. +void BulletMJCFImporter::getMassAndInertia(int urdfLinkIndex, btScalar& mass, btVector3& localInertiaDiagonal, btTransform& inertialFrame) const { - const UrdfLink* link = m_data->getLink(m_data->m_activeModel,urdfLinkIndex); + const UrdfLink* link = m_data->getLink(m_data->m_activeModel, urdfLinkIndex); if (link) { mass = link->m_inertia.m_mass; localInertiaDiagonal.setValue(link->m_inertia.m_ixx, - link->m_inertia.m_iyy, - link->m_inertia.m_izz); + link->m_inertia.m_iyy, + link->m_inertia.m_izz); inertialFrame.setIdentity(); inertialFrame = link->m_inertia.m_linkLocalFrame; - } else + } + else { mass = 0; localInertiaDiagonal.setZero(); inertialFrame.setIdentity(); } } - + ///fill an array of child link indices for this link, btAlignedObjectArray behaves like a std::vector so just use push_back and resize(0) if needed void BulletMJCFImporter::getLinkChildIndices(int urdfLinkIndex, btAlignedObjectArray& childLinkIndices) const { - const UrdfLink* link = m_data->getLink(m_data->m_activeModel,urdfLinkIndex); + const UrdfLink* link = m_data->getLink(m_data->m_activeModel, urdfLinkIndex); if (link) { - for (int i=0;im_childLinks.size();i++) + for (int i = 0; i < link->m_childLinks.size(); i++) { int childIndex = link->m_childLinks[i]->m_linkIndex; childLinkIndices.push_back(childIndex); } } } - + bool BulletMJCFImporter::getJointInfo2(int urdfLinkIndex, btTransform& parent2joint, btTransform& linkTransformInWorld, btVector3& jointAxisInJointSpace, int& jointType, btScalar& jointLowerLimit, btScalar& jointUpperLimit, btScalar& jointDamping, btScalar& jointFriction, btScalar& jointMaxForce, btScalar& jointMaxVelocity) const { jointLowerLimit = 0.f; - jointUpperLimit = 0.f; + jointUpperLimit = 0.f; jointDamping = 0.f; jointFriction = 0.f; jointMaxForce = 0; jointMaxVelocity = 0; - const UrdfLink* link = m_data->getLink(m_data->m_activeModel,urdfLinkIndex); + const UrdfLink* link = m_data->getLink(m_data->m_activeModel, urdfLinkIndex); if (link) { - linkTransformInWorld = link->m_linkTransformInWorld; - + if (link->m_parentJoint) { UrdfJoint* pj = link->m_parentJoint; @@ -1733,15 +1703,16 @@ bool BulletMJCFImporter::getJointInfo2(int urdfLinkIndex, btTransform& parent2jo jointFriction = pj->m_jointFriction; jointMaxForce = pj->m_effortLimit; jointMaxVelocity = pj->m_velocityLimit; - + return true; - } else + } + else { parent2joint.setIdentity(); return false; } } - + return false; } @@ -1750,9 +1721,9 @@ bool BulletMJCFImporter::getJointInfo(int urdfLinkIndex, btTransform& parent2joi //backwards compatibility for custom file importers btScalar jointMaxForce = 0; btScalar jointMaxVelocity = 0; - return getJointInfo2(urdfLinkIndex, parent2joint, linkTransformInWorld, jointAxisInJointSpace, jointType, jointLowerLimit, jointUpperLimit, jointDamping, jointFriction,jointMaxForce, jointMaxVelocity); + return getJointInfo2(urdfLinkIndex, parent2joint, linkTransformInWorld, jointAxisInJointSpace, jointType, jointLowerLimit, jointUpperLimit, jointDamping, jointFriction, jointMaxForce, jointMaxVelocity); } - + bool BulletMJCFImporter::getRootTransformInWorld(btTransform& rootTransformInWorld) const { rootTransformInWorld.setIdentity(); @@ -1768,8 +1739,6 @@ bool BulletMJCFImporter::getRootTransformInWorld(btTransform& rootTransformInWor void BulletMJCFImporter::convertURDFToVisualShapeInternal(const UrdfVisual* visual, const char* urdfPathPrefix, const btTransform& visualTransform, btAlignedObjectArray& verticesOut, btAlignedObjectArray& indicesOut, btAlignedObjectArray& texturesOut) const { - - GLInstanceGraphicsShape* glmesh = 0; int strideInBytes = 9 * sizeof(float); @@ -1777,357 +1746,350 @@ void BulletMJCFImporter::convertURDFToVisualShapeInternal(const UrdfVisual* visu switch (visual->m_geometry.m_type) { - case URDF_GEOM_CAPSULE: - { - + case URDF_GEOM_CAPSULE: + { #if 1 - btScalar height = visual->m_geometry.m_capsuleHeight; + btScalar height = visual->m_geometry.m_capsuleHeight; - btTransform capsuleTrans; - capsuleTrans.setIdentity(); - if (visual->m_geometry.m_hasFromTo) - { - btVector3 f = visual->m_geometry.m_capsuleFrom; - btVector3 t = visual->m_geometry.m_capsuleTo; - - //compute the local 'fromto' transform - btVector3 localPosition = btScalar(0.5)*(t + f); - btQuaternion localOrn; - localOrn = btQuaternion::getIdentity(); - - btVector3 diff = t - f; - btScalar lenSqr = diff.length2(); - height = 0.f; - - if (lenSqr > SIMD_EPSILON) + btTransform capsuleTrans; + capsuleTrans.setIdentity(); + if (visual->m_geometry.m_hasFromTo) { - height = btSqrt(lenSqr); - btVector3 ax = diff / height; + btVector3 f = visual->m_geometry.m_capsuleFrom; + btVector3 t = visual->m_geometry.m_capsuleTo; - btVector3 zAxis(0, 0, 1); - localOrn = shortestArcQuat(zAxis, ax); - } - capsuleTrans.setOrigin(localPosition); - capsuleTrans.setRotation(localOrn); - } - - btScalar diam = 2.*visual->m_geometry.m_capsuleRadius; - b3AlignedObjectArray transformedVertices; - int numVertices = sizeof(mjcf_sphere_vertices) / strideInBytes; - transformedVertices.resize(numVertices); - for (int i = 0; i0) - trVer[up] += halfHeight; - else - trVer[up] -= halfHeight; - - trVer = capsuleTrans*trVer; - - transformedVertices[i].xyzw[0] = trVer[0]; - transformedVertices[i].xyzw[1] = trVer[1]; - transformedVertices[i].xyzw[2] = trVer[2]; - transformedVertices[i].xyzw[3] = 0; - transformedVertices[i].normal[0] = mjcf_sphere_vertices[i * 9 + 4]; - transformedVertices[i].normal[1] = mjcf_sphere_vertices[i * 9 + 5]; - transformedVertices[i].normal[2] = mjcf_sphere_vertices[i * 9 + 6]; - //transformedVertices[i].uv[0] = mjcf_sphere_vertices[i * 9 + 7]; - //transformedVertices[i].uv[1] = mjcf_sphere_vertices[i * 9 + 8]; - - btScalar u = btAtan2(transformedVertices[i].normal[0], transformedVertices[i].normal[2]) / (2 * SIMD_PI) + 0.5; - btScalar v = transformedVertices[i].normal[1] * 0.5 + 0.5; - transformedVertices[i].uv[0] = u; - transformedVertices[i].uv[1] = v; - } - - glmesh = new GLInstanceGraphicsShape; - // int index = 0; - glmesh->m_indices = new b3AlignedObjectArray(); - glmesh->m_vertices = new b3AlignedObjectArray(); - - int numIndices = sizeof(mjcf_sphere_indiced) / sizeof(int); - for (int i = 0; i < numIndices; i++) - { - glmesh->m_indices->push_back(mjcf_sphere_indiced[i]); - } - for (int i = 0; i < transformedVertices.size(); i++) - { - glmesh->m_vertices->push_back(transformedVertices[i]); - } - glmesh->m_numIndices = numIndices; - glmesh->m_numvertices = transformedVertices.size(); - glmesh->m_scaling[0] = 1; - glmesh->m_scaling[1] = 1; - glmesh->m_scaling[2] = 1; - glmesh->m_scaling[3] = 1; -#else - if (visual->m_geometry.m_hasFromTo) - { - btVector3 f = visual->m_geometry.m_capsuleFrom; - btVector3 t = visual->m_geometry.m_capsuleTo; - btVector3 fromto[2] = { f, t }; - btScalar radii[2] = { btScalar(visual->m_geometry.m_capsuleRadius) - , btScalar(visual->m_geometry.m_capsuleRadius) }; - - btMultiSphereShape* ms = new btMultiSphereShape(fromto, radii, 2); - convexColShape = ms; - } - else - { - btCapsuleShapeZ* cap = new btCapsuleShapeZ(visual->m_geometry.m_capsuleRadius, - visual->m_geometry.m_capsuleHeight); - convexColShape = cap; - } -#endif - - break; - } - - case URDF_GEOM_CYLINDER: - { - btAlignedObjectArray vertices; - - //int numVerts = sizeof(barrel_vertices)/(9*sizeof(float)); - int numSteps = 32; - for (int i = 0; im_geometry.m_capsuleRadius; - btScalar cylLength = visual->m_geometry.m_capsuleHeight; - - btVector3 vert(cylRadius*btSin(SIMD_2_PI*(float(i) / numSteps)), cylRadius*btCos(SIMD_2_PI*(float(i) / numSteps)), cylLength / 2.); - vertices.push_back(vert); - vert[2] = -cylLength / 2.; - vertices.push_back(vert); - } - - btConvexHullShape* cylZShape = new btConvexHullShape(&vertices[0].x(), vertices.size(), sizeof(btVector3)); - cylZShape->setMargin(m_data->m_globalDefaults.m_defaultCollisionMargin); - cylZShape->recalcLocalAabb(); - convexColShape = cylZShape; - break; - } - - case URDF_GEOM_BOX: - { - btVector3 extents = visual->m_geometry.m_boxSize; - btBoxShape* boxShape = new btBoxShape(extents*0.5f); - //btConvexShape* boxShape = new btConeShapeX(extents[2]*0.5,extents[0]*0.5); - convexColShape = boxShape; - convexColShape->setMargin(m_data->m_globalDefaults.m_defaultCollisionMargin); - break; - } - - case URDF_GEOM_SPHERE: - { -#if 1 - btScalar sphereSize = 2.*visual->m_geometry.m_sphereRadius; - b3AlignedObjectArray transformedVertices; - int numVertices = sizeof(mjcf_sphere_vertices) / strideInBytes; - transformedVertices.resize(numVertices); - - - glmesh = new GLInstanceGraphicsShape; - // int index = 0; - glmesh->m_indices = new b3AlignedObjectArray(); - glmesh->m_vertices = new b3AlignedObjectArray(); - printf("vertices:\n"); - for (int i = 0; im_indices->push_back(mjcf_sphere_indiced[i]); - } - for (int i = 0; i < transformedVertices.size(); i++) - { - glmesh->m_vertices->push_back(transformedVertices[i]); - } - glmesh->m_numIndices = numIndices; - glmesh->m_numvertices = transformedVertices.size(); - glmesh->m_scaling[0] = 1; - glmesh->m_scaling[1] = 1; - glmesh->m_scaling[2] = 1; - glmesh->m_scaling[3] = 1; - -#else - - btScalar radius = visual->m_geometry.m_sphereRadius; - btSphereShape* sphereShape = new btSphereShape(radius); - convexColShape = sphereShape; - convexColShape->setMargin(m_data->m_globalDefaults.m_defaultCollisionMargin); -#endif - break; - } - - case URDF_GEOM_MESH: - { - switch (visual->m_geometry.m_meshFileType) - { - case UrdfGeometry::FILE_OBJ: - { - b3ImportMeshData meshData; - if (b3ImportMeshUtility::loadAndRegisterMeshFromFileInternal(visual->m_geometry.m_meshFileName, meshData)) - { - - if (meshData.m_textureImage1) + if (lenSqr > SIMD_EPSILON) { - MJCFURDFTexture texData; - texData.m_width = meshData.m_textureWidth; - texData.m_height = meshData.m_textureHeight; - texData.textureData1 = meshData.m_textureImage1; - texData.m_isCached = meshData.m_isCached; - texturesOut.push_back(texData); + height = btSqrt(lenSqr); + btVector3 ax = diff / height; + + btVector3 zAxis(0, 0, 1); + localOrn = shortestArcQuat(zAxis, ax); } - glmesh = meshData.m_gfxShape; + capsuleTrans.setOrigin(localPosition); + capsuleTrans.setRotation(localOrn); } - break; - } - case UrdfGeometry::FILE_STL: - { - glmesh = LoadMeshFromSTL(visual->m_geometry.m_meshFileName.c_str()); - break; - } + btScalar diam = 2. * visual->m_geometry.m_capsuleRadius; + b3AlignedObjectArray transformedVertices; + int numVertices = sizeof(mjcf_sphere_vertices) / strideInBytes; + transformedVertices.resize(numVertices); + for (int i = 0; i < numVertices; i++) + { + btVector3 vert; + vert.setValue(mjcf_sphere_vertices[i * 9 + 0], + mjcf_sphere_vertices[i * 9 + 1], + mjcf_sphere_vertices[i * 9 + 2]); - case UrdfGeometry::FILE_COLLADA: - { - btAlignedObjectArray visualShapes; - btAlignedObjectArray visualShapeInstances; - btTransform upAxisTrans; upAxisTrans.setIdentity(); - float unitMeterScaling = 1; - int upAxis = 2; + btScalar halfHeight = 0.5 * height; + btVector3 trVer = (diam * vert); + int up = 2; //default to z axis up for capsule + if (trVer[up] > 0) + trVer[up] += halfHeight; + else + trVer[up] -= halfHeight; - LoadMeshFromCollada(visual->m_geometry.m_meshFileName.c_str(), - visualShapes, - visualShapeInstances, - upAxisTrans, - unitMeterScaling, - upAxis); + trVer = capsuleTrans * trVer; + + transformedVertices[i].xyzw[0] = trVer[0]; + transformedVertices[i].xyzw[1] = trVer[1]; + transformedVertices[i].xyzw[2] = trVer[2]; + transformedVertices[i].xyzw[3] = 0; + transformedVertices[i].normal[0] = mjcf_sphere_vertices[i * 9 + 4]; + transformedVertices[i].normal[1] = mjcf_sphere_vertices[i * 9 + 5]; + transformedVertices[i].normal[2] = mjcf_sphere_vertices[i * 9 + 6]; + //transformedVertices[i].uv[0] = mjcf_sphere_vertices[i * 9 + 7]; + //transformedVertices[i].uv[1] = mjcf_sphere_vertices[i * 9 + 8]; + + btScalar u = btAtan2(transformedVertices[i].normal[0], transformedVertices[i].normal[2]) / (2 * SIMD_PI) + 0.5; + btScalar v = transformedVertices[i].normal[1] * 0.5 + 0.5; + transformedVertices[i].uv[0] = u; + transformedVertices[i].uv[1] = v; + } glmesh = new GLInstanceGraphicsShape; // int index = 0; glmesh->m_indices = new b3AlignedObjectArray(); glmesh->m_vertices = new b3AlignedObjectArray(); - for (int i = 0; im_shapeIndex]; - - b3AlignedObjectArray verts; - verts.resize(gfxShape->m_vertices->size()); - - int baseIndex = glmesh->m_vertices->size(); - - for (int i = 0; im_vertices->size(); i++) - { - verts[i].normal[0] = gfxShape->m_vertices->at(i).normal[0]; - verts[i].normal[1] = gfxShape->m_vertices->at(i).normal[1]; - verts[i].normal[2] = gfxShape->m_vertices->at(i).normal[2]; - verts[i].uv[0] = gfxShape->m_vertices->at(i).uv[0]; - verts[i].uv[1] = gfxShape->m_vertices->at(i).uv[1]; - verts[i].xyzw[0] = gfxShape->m_vertices->at(i).xyzw[0]; - verts[i].xyzw[1] = gfxShape->m_vertices->at(i).xyzw[1]; - verts[i].xyzw[2] = gfxShape->m_vertices->at(i).xyzw[2]; - verts[i].xyzw[3] = gfxShape->m_vertices->at(i).xyzw[3]; - - } - - int curNumIndices = glmesh->m_indices->size(); - int additionalIndices = gfxShape->m_indices->size(); - glmesh->m_indices->resize(curNumIndices + additionalIndices); - for (int k = 0; km_indices->at(curNumIndices + k) = gfxShape->m_indices->at(k) + baseIndex; - } - - //compensate upAxisTrans and unitMeterScaling here - btMatrix4x4 upAxisMat; - upAxisMat.setIdentity(); - // upAxisMat.setPureRotation(upAxisTrans.getRotation()); - btMatrix4x4 unitMeterScalingMat; - unitMeterScalingMat.setPureScaling(btVector3(unitMeterScaling, unitMeterScaling, unitMeterScaling)); - btMatrix4x4 worldMat = unitMeterScalingMat*upAxisMat*instance->m_worldTransform; - //btMatrix4x4 worldMat = instance->m_worldTransform; - int curNumVertices = glmesh->m_vertices->size(); - int additionalVertices = verts.size(); - glmesh->m_vertices->reserve(curNumVertices + additionalVertices); - - for (int v = 0; vm_vertices->push_back(verts[v]); - } + glmesh->m_indices->push_back(mjcf_sphere_indiced[i]); } - glmesh->m_numIndices = glmesh->m_indices->size(); - glmesh->m_numvertices = glmesh->m_vertices->size(); - //glmesh = LoadMeshFromCollada(visual->m_geometry.m_meshFileName); + for (int i = 0; i < transformedVertices.size(); i++) + { + glmesh->m_vertices->push_back(transformedVertices[i]); + } + glmesh->m_numIndices = numIndices; + glmesh->m_numvertices = transformedVertices.size(); + glmesh->m_scaling[0] = 1; + glmesh->m_scaling[1] = 1; + glmesh->m_scaling[2] = 1; + glmesh->m_scaling[3] = 1; +#else + if (visual->m_geometry.m_hasFromTo) + { + btVector3 f = visual->m_geometry.m_capsuleFrom; + btVector3 t = visual->m_geometry.m_capsuleTo; + btVector3 fromto[2] = {f, t}; + btScalar radii[2] = {btScalar(visual->m_geometry.m_capsuleRadius), btScalar(visual->m_geometry.m_capsuleRadius)}; + + btMultiSphereShape* ms = new btMultiSphereShape(fromto, radii, 2); + convexColShape = ms; + } + else + { + btCapsuleShapeZ* cap = new btCapsuleShapeZ(visual->m_geometry.m_capsuleRadius, + visual->m_geometry.m_capsuleHeight); + convexColShape = cap; + } +#endif break; } - } // switch file type - if (!glmesh || !glmesh->m_vertices || glmesh->m_numvertices <= 0) + case URDF_GEOM_CYLINDER: { - b3Warning("%s: cannot extract anything useful from mesh '%s'\n", urdfPathPrefix, visual->m_geometry.m_meshFileName.c_str()); + btAlignedObjectArray vertices; + + //int numVerts = sizeof(barrel_vertices)/(9*sizeof(float)); + int numSteps = 32; + for (int i = 0; i < numSteps; i++) + { + btScalar cylRadius = visual->m_geometry.m_capsuleRadius; + btScalar cylLength = visual->m_geometry.m_capsuleHeight; + + btVector3 vert(cylRadius * btSin(SIMD_2_PI * (float(i) / numSteps)), cylRadius * btCos(SIMD_2_PI * (float(i) / numSteps)), cylLength / 2.); + vertices.push_back(vert); + vert[2] = -cylLength / 2.; + vertices.push_back(vert); + } + + btConvexHullShape* cylZShape = new btConvexHullShape(&vertices[0].x(), vertices.size(), sizeof(btVector3)); + cylZShape->setMargin(m_data->m_globalDefaults.m_defaultCollisionMargin); + cylZShape->recalcLocalAabb(); + convexColShape = cylZShape; break; } - //apply the geometry scaling - for (int i = 0; im_vertices->size(); i++) + case URDF_GEOM_BOX: { - glmesh->m_vertices->at(i).xyzw[0] *= visual->m_geometry.m_meshScale[0]; - glmesh->m_vertices->at(i).xyzw[1] *= visual->m_geometry.m_meshScale[1]; - glmesh->m_vertices->at(i).xyzw[2] *= visual->m_geometry.m_meshScale[2]; + btVector3 extents = visual->m_geometry.m_boxSize; + btBoxShape* boxShape = new btBoxShape(extents * 0.5f); + //btConvexShape* boxShape = new btConeShapeX(extents[2]*0.5,extents[0]*0.5); + convexColShape = boxShape; + convexColShape->setMargin(m_data->m_globalDefaults.m_defaultCollisionMargin); + break; + } + + case URDF_GEOM_SPHERE: + { +#if 1 + btScalar sphereSize = 2. * visual->m_geometry.m_sphereRadius; + b3AlignedObjectArray transformedVertices; + int numVertices = sizeof(mjcf_sphere_vertices) / strideInBytes; + transformedVertices.resize(numVertices); + + glmesh = new GLInstanceGraphicsShape; + // int index = 0; + glmesh->m_indices = new b3AlignedObjectArray(); + glmesh->m_vertices = new b3AlignedObjectArray(); + printf("vertices:\n"); + for (int i = 0; i < numVertices; i++) + { + btVector3 vert; + vert.setValue(mjcf_sphere_vertices[i * 9 + 0], + mjcf_sphere_vertices[i * 9 + 1], + mjcf_sphere_vertices[i * 9 + 2]); + + btVector3 trVer = sphereSize * vert; + transformedVertices[i].xyzw[0] = trVer[0]; + transformedVertices[i].xyzw[1] = trVer[1]; + transformedVertices[i].xyzw[2] = trVer[2]; + transformedVertices[i].xyzw[3] = 0; + transformedVertices[i].normal[0] = mjcf_sphere_vertices[i * 9 + 4]; + transformedVertices[i].normal[1] = mjcf_sphere_vertices[i * 9 + 5]; + transformedVertices[i].normal[2] = mjcf_sphere_vertices[i * 9 + 6]; + //transformedVertices[i].uv[0] = mjcf_sphere_vertices[i * 9 + 7]; + //transformedVertices[i].uv[1] = mjcf_sphere_vertices[i * 9 + 8]; + + btScalar u = btAtan2(transformedVertices[i].normal[0], transformedVertices[i].normal[2]) / (2 * SIMD_PI) + 0.5; + btScalar v = transformedVertices[i].normal[1] * 0.5 + 0.5; + transformedVertices[i].uv[0] = u; + transformedVertices[i].uv[1] = v; + } + int numIndices = sizeof(mjcf_sphere_indiced) / sizeof(int); + for (int i = 0; i < numIndices; i++) + { + glmesh->m_indices->push_back(mjcf_sphere_indiced[i]); + } + for (int i = 0; i < transformedVertices.size(); i++) + { + glmesh->m_vertices->push_back(transformedVertices[i]); + } + glmesh->m_numIndices = numIndices; + glmesh->m_numvertices = transformedVertices.size(); + glmesh->m_scaling[0] = 1; + glmesh->m_scaling[1] = 1; + glmesh->m_scaling[2] = 1; + glmesh->m_scaling[3] = 1; + +#else + + btScalar radius = visual->m_geometry.m_sphereRadius; + btSphereShape* sphereShape = new btSphereShape(radius); + convexColShape = sphereShape; + convexColShape->setMargin(m_data->m_globalDefaults.m_defaultCollisionMargin); +#endif + break; + } + + case URDF_GEOM_MESH: + { + switch (visual->m_geometry.m_meshFileType) + { + case UrdfGeometry::FILE_OBJ: + { + b3ImportMeshData meshData; + if (b3ImportMeshUtility::loadAndRegisterMeshFromFileInternal(visual->m_geometry.m_meshFileName, meshData)) + { + if (meshData.m_textureImage1) + { + MJCFURDFTexture texData; + texData.m_width = meshData.m_textureWidth; + texData.m_height = meshData.m_textureHeight; + texData.textureData1 = meshData.m_textureImage1; + texData.m_isCached = meshData.m_isCached; + texturesOut.push_back(texData); + } + glmesh = meshData.m_gfxShape; + } + break; + } + + case UrdfGeometry::FILE_STL: + { + glmesh = LoadMeshFromSTL(visual->m_geometry.m_meshFileName.c_str()); + break; + } + + case UrdfGeometry::FILE_COLLADA: + { + btAlignedObjectArray visualShapes; + btAlignedObjectArray visualShapeInstances; + btTransform upAxisTrans; + upAxisTrans.setIdentity(); + float unitMeterScaling = 1; + int upAxis = 2; + + LoadMeshFromCollada(visual->m_geometry.m_meshFileName.c_str(), + visualShapes, + visualShapeInstances, + upAxisTrans, + unitMeterScaling, + upAxis); + + glmesh = new GLInstanceGraphicsShape; + // int index = 0; + glmesh->m_indices = new b3AlignedObjectArray(); + glmesh->m_vertices = new b3AlignedObjectArray(); + + for (int i = 0; i < visualShapeInstances.size(); i++) + { + ColladaGraphicsInstance* instance = &visualShapeInstances[i]; + GLInstanceGraphicsShape* gfxShape = &visualShapes[instance->m_shapeIndex]; + + b3AlignedObjectArray verts; + verts.resize(gfxShape->m_vertices->size()); + + int baseIndex = glmesh->m_vertices->size(); + + for (int i = 0; i < gfxShape->m_vertices->size(); i++) + { + verts[i].normal[0] = gfxShape->m_vertices->at(i).normal[0]; + verts[i].normal[1] = gfxShape->m_vertices->at(i).normal[1]; + verts[i].normal[2] = gfxShape->m_vertices->at(i).normal[2]; + verts[i].uv[0] = gfxShape->m_vertices->at(i).uv[0]; + verts[i].uv[1] = gfxShape->m_vertices->at(i).uv[1]; + verts[i].xyzw[0] = gfxShape->m_vertices->at(i).xyzw[0]; + verts[i].xyzw[1] = gfxShape->m_vertices->at(i).xyzw[1]; + verts[i].xyzw[2] = gfxShape->m_vertices->at(i).xyzw[2]; + verts[i].xyzw[3] = gfxShape->m_vertices->at(i).xyzw[3]; + } + + int curNumIndices = glmesh->m_indices->size(); + int additionalIndices = gfxShape->m_indices->size(); + glmesh->m_indices->resize(curNumIndices + additionalIndices); + for (int k = 0; k < additionalIndices; k++) + { + glmesh->m_indices->at(curNumIndices + k) = gfxShape->m_indices->at(k) + baseIndex; + } + + //compensate upAxisTrans and unitMeterScaling here + btMatrix4x4 upAxisMat; + upAxisMat.setIdentity(); + // upAxisMat.setPureRotation(upAxisTrans.getRotation()); + btMatrix4x4 unitMeterScalingMat; + unitMeterScalingMat.setPureScaling(btVector3(unitMeterScaling, unitMeterScaling, unitMeterScaling)); + btMatrix4x4 worldMat = unitMeterScalingMat * upAxisMat * instance->m_worldTransform; + //btMatrix4x4 worldMat = instance->m_worldTransform; + int curNumVertices = glmesh->m_vertices->size(); + int additionalVertices = verts.size(); + glmesh->m_vertices->reserve(curNumVertices + additionalVertices); + + for (int v = 0; v < verts.size(); v++) + { + btVector3 pos(verts[v].xyzw[0], verts[v].xyzw[1], verts[v].xyzw[2]); + pos = worldMat * pos; + verts[v].xyzw[0] = float(pos[0]); + verts[v].xyzw[1] = float(pos[1]); + verts[v].xyzw[2] = float(pos[2]); + glmesh->m_vertices->push_back(verts[v]); + } + } + glmesh->m_numIndices = glmesh->m_indices->size(); + glmesh->m_numvertices = glmesh->m_vertices->size(); + //glmesh = LoadMeshFromCollada(visual->m_geometry.m_meshFileName); + + break; + } + } // switch file type + + if (!glmesh || !glmesh->m_vertices || glmesh->m_numvertices <= 0) + { + b3Warning("%s: cannot extract anything useful from mesh '%s'\n", urdfPathPrefix, visual->m_geometry.m_meshFileName.c_str()); + break; + } + + //apply the geometry scaling + for (int i = 0; i < glmesh->m_vertices->size(); i++) + { + glmesh->m_vertices->at(i).xyzw[0] *= visual->m_geometry.m_meshScale[0]; + glmesh->m_vertices->at(i).xyzw[1] *= visual->m_geometry.m_meshScale[1]; + glmesh->m_vertices->at(i).xyzw[2] *= visual->m_geometry.m_meshScale[2]; + } + break; + } + case URDF_GEOM_PLANE: + { + b3Warning("No default visual for URDF_GEOM_PLANE"); + break; + } + default: + { + b3Warning("Error: unknown visual geometry type %i\n", visual->m_geometry.m_type); } - break; - } - case URDF_GEOM_PLANE: - { - b3Warning("No default visual for URDF_GEOM_PLANE"); - break; - } - default: - { - b3Warning("Error: unknown visual geometry type %i\n", visual->m_geometry.m_type); - } } //if we have a convex, tesselate into localVertices/localIndices @@ -2142,15 +2104,11 @@ void BulletMJCFImporter::convertURDFToVisualShapeInternal(const UrdfVisual* visu int numVertices = hull->numVertices(); int numIndices = hull->numIndices(); - glmesh = new GLInstanceGraphicsShape; // int index = 0; glmesh->m_indices = new b3AlignedObjectArray(); glmesh->m_vertices = new b3AlignedObjectArray(); - - - for (int i = 0; i < numVertices; i++) { GLInstanceVertex vtx; @@ -2182,16 +2140,13 @@ void BulletMJCFImporter::convertURDFToVisualShapeInternal(const UrdfVisual* visu delete hull; delete convexColShape; convexColShape = 0; - } - if (glmesh && glmesh->m_numIndices>0 && glmesh->m_numvertices >0) + if (glmesh && glmesh->m_numIndices > 0 && glmesh->m_numvertices > 0) { BT_PROFILE("glmesh"); int baseIndex = verticesOut.size(); - - for (int i = 0; i < glmesh->m_indices->size(); i++) { indicesOut.push_back(glmesh->m_indices->at(i) + baseIndex); @@ -2201,12 +2156,12 @@ void BulletMJCFImporter::convertURDFToVisualShapeInternal(const UrdfVisual* visu { GLInstanceVertex& v = glmesh->m_vertices->at(i); btVector3 vert(v.xyzw[0], v.xyzw[1], v.xyzw[2]); - btVector3 vt = visualTransform*vert; + btVector3 vt = visualTransform * vert; v.xyzw[0] = vt[0]; v.xyzw[1] = vt[1]; v.xyzw[2] = vt[2]; btVector3 triNormal(v.normal[0], v.normal[1], v.normal[2]); - triNormal = visualTransform.getBasis()*triNormal; + triNormal = visualTransform.getBasis() * triNormal; v.normal[0] = triNormal[0]; v.normal[1] = triNormal[1]; v.normal[2] = triNormal[2]; @@ -2218,19 +2173,19 @@ void BulletMJCFImporter::convertURDFToVisualShapeInternal(const UrdfVisual* visu int BulletMJCFImporter::convertLinkVisualShapes(int linkIndex, const char* pathPrefix, const btTransform& inertialFrame) const { - int graphicsIndex = -1; - if (m_data->m_flags&CUF_MJCF_COLORS_FROM_FILE) + int graphicsIndex = -1; + if (m_data->m_flags & CUF_MJCF_COLORS_FROM_FILE) { btAlignedObjectArray vertices; btAlignedObjectArray indices; - btTransform startTrans; startTrans.setIdentity(); + btTransform startTrans; + startTrans.setIdentity(); btAlignedObjectArray textures; const UrdfModel& model = *m_data->m_models[m_data->m_activeModel]; UrdfLink* const* linkPtr = model.m_links.getAtIndex(linkIndex); if (linkPtr) { - const UrdfLink* link = *linkPtr; for (int v = 0; v < link->m_visualArray.size(); v++) @@ -2238,10 +2193,9 @@ int BulletMJCFImporter::convertLinkVisualShapes(int linkIndex, const char* pathP const UrdfVisual& vis = link->m_visualArray[v]; btTransform childTrans = vis.m_linkLocalFrame; btHashString matName(vis.m_materialName.c_str()); - UrdfMaterial *const * matPtr = model.m_materials[matName]; - - convertURDFToVisualShapeInternal(&vis, pathPrefix, inertialFrame.inverse()*childTrans, vertices, indices, textures); + UrdfMaterial* const* matPtr = model.m_materials[matName]; + convertURDFToVisualShapeInternal(&vis, pathPrefix, inertialFrame.inverse() * childTrans, vertices, indices, textures); } } if (vertices.size() && indices.size()) @@ -2257,7 +2211,6 @@ int BulletMJCFImporter::convertLinkVisualShapes(int linkIndex, const char* pathP B3_PROFILE("registerGraphicsShape"); graphicsIndex = m_data->m_guiHelper->registerGraphicsShape(&vertices[0].xyzw[0], vertices.size(), &indices[0], indices.size(), B3_GL_TRIANGLES, textureIndex); } - } } @@ -2274,9 +2227,9 @@ int BulletMJCFImporter::convertLinkVisualShapes(int linkIndex, const char* pathP return graphicsIndex; } -bool BulletMJCFImporter::getLinkContactInfo(int linkIndex, URDFLinkContactInfo& contactInfo ) const +bool BulletMJCFImporter::getLinkContactInfo(int linkIndex, URDFLinkContactInfo& contactInfo) const { - const UrdfLink* link = m_data->getLink(m_data->m_activeModel,linkIndex); + const UrdfLink* link = m_data->getLink(m_data->m_activeModel, linkIndex); if (link) { contactInfo = link->m_contactInfo; @@ -2290,7 +2243,7 @@ void BulletMJCFImporter::convertLinkVisualShapes2(int linkIndex, int urdfIndex, if (m_data->m_customVisualShapesConverter) { const UrdfLink* link = m_data->getLink(m_data->m_activeModel, urdfIndex); - m_data->m_customVisualShapesConverter->convertVisualShapes(linkIndex,pathPrefix,inertialFrame, link, 0, colObj->getBroadphaseHandle()->getUid(), objectIndex); + m_data->m_customVisualShapesConverter->convertVisualShapes(linkIndex, pathPrefix, inertialFrame, link, 0, colObj->getBroadphaseHandle()->getUid(), objectIndex); } } @@ -2299,8 +2252,8 @@ void BulletMJCFImporter::setBodyUniqueId(int bodyId) m_data->m_activeBodyUniqueId = bodyId; } -int BulletMJCFImporter::getBodyUniqueId() const -{ +int BulletMJCFImporter::getBodyUniqueId() const +{ b3Assert(m_data->m_activeBodyUniqueId != -1); return m_data->m_activeBodyUniqueId; } @@ -2313,211 +2266,84 @@ static btCollisionShape* MjcfCreateConvexHullFromShapes(std::vectorsetMargin(collisionMargin); tinyobj::shape_t& shape = shapes[s]; int faceCount = shape.mesh.indices.size(); - for (int f = 0; faddPoint(pt*geomScale,false); + shape.mesh.positions[shape.mesh.indices[f] * 3 + 1], + shape.mesh.positions[shape.mesh.indices[f] * 3 + 2]); + + convexHull->addPoint(pt * geomScale, false); pt.setValue(shape.mesh.positions[shape.mesh.indices[f + 1] * 3 + 0], shape.mesh.positions[shape.mesh.indices[f + 1] * 3 + 1], shape.mesh.positions[shape.mesh.indices[f + 1] * 3 + 2]); - convexHull->addPoint(pt*geomScale, false); + convexHull->addPoint(pt * geomScale, false); pt.setValue(shape.mesh.positions[shape.mesh.indices[f + 2] * 3 + 0], shape.mesh.positions[shape.mesh.indices[f + 2] * 3 + 1], shape.mesh.positions[shape.mesh.indices[f + 2] * 3 + 2]); - convexHull->addPoint(pt*geomScale, false); + convexHull->addPoint(pt * geomScale, false); } convexHull->recalcLocalAabb(); convexHull->optimizeConvexHull(); - compound->addChildShape(identity,convexHull); + compound->addChildShape(identity, convexHull); } return compound; } - -class btCompoundShape* BulletMJCFImporter::convertLinkCollisionShapes( int linkIndex, const char* pathPrefix, const btTransform& localInertiaFrame) const +class btCompoundShape* BulletMJCFImporter::convertLinkCollisionShapes(int linkIndex, const char* pathPrefix, const btTransform& localInertiaFrame) const { btCompoundShape* compound = new btCompoundShape(); m_data->m_allocatedCollisionShapes.push_back(compound); - const UrdfLink* link = m_data->getLink(m_data->m_activeModel,linkIndex); + const UrdfLink* link = m_data->getLink(m_data->m_activeModel, linkIndex); if (link) { - for (int i=0;i< link->m_collisionArray.size();i++) + for (int i = 0; i < link->m_collisionArray.size(); i++) { const UrdfCollision* col = &link->m_collisionArray[i]; btCollisionShape* childShape = 0; switch (col->m_geometry.m_type) { - case URDF_GEOM_PLANE: - { - childShape = new btStaticPlaneShape(col->m_geometry.m_planeNormal,0); - break; - } - case URDF_GEOM_SPHERE: - { - childShape = new btSphereShape(col->m_geometry.m_sphereRadius); - break; - } - case URDF_GEOM_BOX: - { - childShape = new btBoxShape(col->m_geometry.m_boxSize); - break; - } - case URDF_GEOM_CYLINDER: - { - if (col->m_geometry.m_hasFromTo) + case URDF_GEOM_PLANE: { - btVector3 f = col->m_geometry.m_capsuleFrom; - btVector3 t = col->m_geometry.m_capsuleTo; - - //compute the local 'fromto' transform - btVector3 localPosition = btScalar(0.5)*(t+f); - btQuaternion localOrn; - localOrn = btQuaternion::getIdentity(); - - btVector3 diff = t-f; - btScalar lenSqr = diff.length2(); - btScalar height = 0.f; - - if (lenSqr > SIMD_EPSILON) - { - height = btSqrt(lenSqr); - btVector3 ax = diff / height; - - btVector3 zAxis(0,0,1); - localOrn = shortestArcQuat(zAxis,ax); - } - btCylinderShapeZ* cyl = new btCylinderShapeZ(btVector3(col->m_geometry.m_capsuleRadius,col->m_geometry.m_capsuleRadius,btScalar(0.5)*height)); - - btCompoundShape* compound = new btCompoundShape(); - btTransform localTransform(localOrn,localPosition); - compound->addChildShape(localTransform,cyl); - childShape = compound; - } else - { - btCylinderShapeZ* cap = new btCylinderShapeZ(btVector3(col->m_geometry.m_capsuleRadius, - col->m_geometry.m_capsuleRadius,btScalar(0.5)*col->m_geometry.m_capsuleHeight)); - childShape = cap; + childShape = new btStaticPlaneShape(col->m_geometry.m_planeNormal, 0); + break; } - break; - } - case URDF_GEOM_MESH: - { - GLInstanceGraphicsShape* glmesh = 0; - switch (col->m_geometry.m_meshFileType) + case URDF_GEOM_SPHERE: { - case UrdfGeometry::FILE_OBJ: - { - if (col->m_flags & URDF_FORCE_CONCAVE_TRIMESH) - { - glmesh = LoadMeshFromObj(col->m_geometry.m_meshFileName.c_str(), 0); - } - else - { - std::vector shapes; - std::string err = tinyobj::LoadObj(shapes, col->m_geometry.m_meshFileName.c_str()); - //create a convex hull for each shape, and store it in a btCompoundShape - - childShape = MjcfCreateConvexHullFromShapes( shapes, col->m_geometry.m_meshScale, m_data->m_globalDefaults.m_defaultCollisionMargin); - - } - break; - } - case UrdfGeometry::FILE_STL: - { - glmesh = LoadMeshFromSTL(col->m_geometry.m_meshFileName.c_str()); - break; - } - default: - b3Warning("%s: Unsupported file type in Collision: %s (maybe .dae?)\n", col->m_sourceFileLocation.c_str(), col->m_geometry.m_meshFileType); + childShape = new btSphereShape(col->m_geometry.m_sphereRadius); + break; } - - if (childShape) + case URDF_GEOM_BOX: { - // okay! + childShape = new btBoxShape(col->m_geometry.m_boxSize); + break; } - else if (!glmesh || glmesh->m_numvertices<=0) + case URDF_GEOM_CYLINDER: { - b3Warning("%s: cannot extract anything useful from mesh '%s'\n", col->m_sourceFileLocation.c_str(), col->m_geometry.m_meshFileName.c_str()); - } - else - { - //b3Printf("extracted %d verticed from STL file %s\n", glmesh->m_numvertices,fullPath); - //int shapeId = m_glApp->m_instancingRenderer->registerShape(&gvertices[0].pos[0],gvertices.size(),&indices[0],indices.size()); - //convex->setUserIndex(shapeId); - btAlignedObjectArray convertedVerts; - convertedVerts.reserve(glmesh->m_numvertices); - for (int i=0;im_numvertices;i++) - { - convertedVerts.push_back(btVector3( - glmesh->m_vertices->at(i).xyzw[0]*col->m_geometry.m_meshScale[0], - glmesh->m_vertices->at(i).xyzw[1]*col->m_geometry.m_meshScale[1], - glmesh->m_vertices->at(i).xyzw[2]*col->m_geometry.m_meshScale[2])); - } - - if (col->m_flags & URDF_FORCE_CONCAVE_TRIMESH) - { - - btTriangleMesh* meshInterface = new btTriangleMesh(); - m_data->m_allocatedMeshInterfaces.push_back(meshInterface); - - for (int i=0;im_numIndices/3;i++) - { - float* v0 = glmesh->m_vertices->at(glmesh->m_indices->at(i*3)).xyzw; - float* v1 = glmesh->m_vertices->at(glmesh->m_indices->at(i*3+1)).xyzw; - float* v2 = glmesh->m_vertices->at(glmesh->m_indices->at(i*3+2)).xyzw; - meshInterface->addTriangle(btVector3(v0[0],v0[1],v0[2]), - btVector3(v1[0],v1[1],v1[2]), - btVector3(v2[0],v2[1],v2[2])); - } - - btBvhTriangleMeshShape* trimesh = new btBvhTriangleMeshShape(meshInterface,true,true); - childShape = trimesh; - } else - { - btConvexHullShape* convexHull = new btConvexHullShape(&convertedVerts[0].getX(), convertedVerts.size(), sizeof(btVector3)); - convexHull->optimizeConvexHull(); - //convexHull->initializePolyhedralFeatures(); - convexHull->setMargin(m_data->m_globalDefaults.m_defaultCollisionMargin); - childShape = convexHull; - } - } - - delete glmesh; - break; - } - case URDF_GEOM_CAPSULE: - { - if (col->m_geometry.m_hasFromTo) - { - if (m_data->m_flags&CUF_USE_IMPLICIT_CYLINDER) + if (col->m_geometry.m_hasFromTo) { btVector3 f = col->m_geometry.m_capsuleFrom; btVector3 t = col->m_geometry.m_capsuleTo; - + //compute the local 'fromto' transform - btVector3 localPosition = btScalar(0.5)*(t+f); + btVector3 localPosition = btScalar(0.5) * (t + f); btQuaternion localOrn; localOrn = btQuaternion::getIdentity(); - btVector3 diff = t-f; + btVector3 diff = t - f; btScalar lenSqr = diff.length2(); btScalar height = 0.f; @@ -2526,50 +2352,176 @@ class btCompoundShape* BulletMJCFImporter::convertLinkCollisionShapes( int linkI height = btSqrt(lenSqr); btVector3 ax = diff / height; - btVector3 zAxis(0,0,1); - localOrn = shortestArcQuat(zAxis,ax); + btVector3 zAxis(0, 0, 1); + localOrn = shortestArcQuat(zAxis, ax); } - btCapsuleShapeZ* capsule= new btCapsuleShapeZ(col->m_geometry.m_capsuleRadius,height); + btCylinderShapeZ* cyl = new btCylinderShapeZ(btVector3(col->m_geometry.m_capsuleRadius, col->m_geometry.m_capsuleRadius, btScalar(0.5) * height)); btCompoundShape* compound = new btCompoundShape(); - btTransform localTransform(localOrn,localPosition); - compound->addChildShape(localTransform,capsule); + btTransform localTransform(localOrn, localPosition); + compound->addChildShape(localTransform, cyl); childShape = compound; - } else - { - btVector3 f = col->m_geometry.m_capsuleFrom; - btVector3 t = col->m_geometry.m_capsuleTo; - btVector3 fromto[2] = {f,t}; - btScalar radii[2] = {btScalar(col->m_geometry.m_capsuleRadius) - ,btScalar(col->m_geometry.m_capsuleRadius)}; - - btMultiSphereShape* ms = new btMultiSphereShape(fromto,radii,2); - childShape = ms; } - } else - { - btCapsuleShapeZ* cap = new btCapsuleShapeZ(col->m_geometry.m_capsuleRadius, - col->m_geometry.m_capsuleHeight); - childShape = cap; + else + { + btCylinderShapeZ* cap = new btCylinderShapeZ(btVector3(col->m_geometry.m_capsuleRadius, + col->m_geometry.m_capsuleRadius, btScalar(0.5) * col->m_geometry.m_capsuleHeight)); + childShape = cap; + } + break; } - break; - } - case URDF_GEOM_CDF: - { - //todo - break; - } - case URDF_GEOM_UNKNOWN: - { - break; - } + case URDF_GEOM_MESH: + { + GLInstanceGraphicsShape* glmesh = 0; + switch (col->m_geometry.m_meshFileType) + { + case UrdfGeometry::FILE_OBJ: + { + if (col->m_flags & URDF_FORCE_CONCAVE_TRIMESH) + { + glmesh = LoadMeshFromObj(col->m_geometry.m_meshFileName.c_str(), 0); + } + else + { + std::vector shapes; + std::string err = tinyobj::LoadObj(shapes, col->m_geometry.m_meshFileName.c_str()); + //create a convex hull for each shape, and store it in a btCompoundShape - } // switch geom + childShape = MjcfCreateConvexHullFromShapes(shapes, col->m_geometry.m_meshScale, m_data->m_globalDefaults.m_defaultCollisionMargin); + } + break; + } + case UrdfGeometry::FILE_STL: + { + glmesh = LoadMeshFromSTL(col->m_geometry.m_meshFileName.c_str()); + break; + } + default: + b3Warning("%s: Unsupported file type in Collision: %s (maybe .dae?)\n", col->m_sourceFileLocation.c_str(), col->m_geometry.m_meshFileType); + } + + if (childShape) + { + // okay! + } + else if (!glmesh || glmesh->m_numvertices <= 0) + { + b3Warning("%s: cannot extract anything useful from mesh '%s'\n", col->m_sourceFileLocation.c_str(), col->m_geometry.m_meshFileName.c_str()); + } + else + { + //b3Printf("extracted %d verticed from STL file %s\n", glmesh->m_numvertices,fullPath); + //int shapeId = m_glApp->m_instancingRenderer->registerShape(&gvertices[0].pos[0],gvertices.size(),&indices[0],indices.size()); + //convex->setUserIndex(shapeId); + btAlignedObjectArray convertedVerts; + convertedVerts.reserve(glmesh->m_numvertices); + for (int i = 0; i < glmesh->m_numvertices; i++) + { + convertedVerts.push_back(btVector3( + glmesh->m_vertices->at(i).xyzw[0] * col->m_geometry.m_meshScale[0], + glmesh->m_vertices->at(i).xyzw[1] * col->m_geometry.m_meshScale[1], + glmesh->m_vertices->at(i).xyzw[2] * col->m_geometry.m_meshScale[2])); + } + + if (col->m_flags & URDF_FORCE_CONCAVE_TRIMESH) + { + btTriangleMesh* meshInterface = new btTriangleMesh(); + m_data->m_allocatedMeshInterfaces.push_back(meshInterface); + + for (int i = 0; i < glmesh->m_numIndices / 3; i++) + { + float* v0 = glmesh->m_vertices->at(glmesh->m_indices->at(i * 3)).xyzw; + float* v1 = glmesh->m_vertices->at(glmesh->m_indices->at(i * 3 + 1)).xyzw; + float* v2 = glmesh->m_vertices->at(glmesh->m_indices->at(i * 3 + 2)).xyzw; + meshInterface->addTriangle(btVector3(v0[0], v0[1], v0[2]), + btVector3(v1[0], v1[1], v1[2]), + btVector3(v2[0], v2[1], v2[2])); + } + + btBvhTriangleMeshShape* trimesh = new btBvhTriangleMeshShape(meshInterface, true, true); + childShape = trimesh; + } + else + { + btConvexHullShape* convexHull = new btConvexHullShape(&convertedVerts[0].getX(), convertedVerts.size(), sizeof(btVector3)); + convexHull->optimizeConvexHull(); + //convexHull->initializePolyhedralFeatures(); + convexHull->setMargin(m_data->m_globalDefaults.m_defaultCollisionMargin); + childShape = convexHull; + } + } + + delete glmesh; + break; + } + case URDF_GEOM_CAPSULE: + { + if (col->m_geometry.m_hasFromTo) + { + if (m_data->m_flags & CUF_USE_IMPLICIT_CYLINDER) + { + btVector3 f = col->m_geometry.m_capsuleFrom; + btVector3 t = col->m_geometry.m_capsuleTo; + + //compute the local 'fromto' transform + btVector3 localPosition = btScalar(0.5) * (t + f); + btQuaternion localOrn; + localOrn = btQuaternion::getIdentity(); + + btVector3 diff = t - f; + btScalar lenSqr = diff.length2(); + btScalar height = 0.f; + + if (lenSqr > SIMD_EPSILON) + { + height = btSqrt(lenSqr); + btVector3 ax = diff / height; + + btVector3 zAxis(0, 0, 1); + localOrn = shortestArcQuat(zAxis, ax); + } + btCapsuleShapeZ* capsule = new btCapsuleShapeZ(col->m_geometry.m_capsuleRadius, height); + + btCompoundShape* compound = new btCompoundShape(); + btTransform localTransform(localOrn, localPosition); + compound->addChildShape(localTransform, capsule); + childShape = compound; + } + else + { + btVector3 f = col->m_geometry.m_capsuleFrom; + btVector3 t = col->m_geometry.m_capsuleTo; + btVector3 fromto[2] = {f, t}; + btScalar radii[2] = {btScalar(col->m_geometry.m_capsuleRadius), btScalar(col->m_geometry.m_capsuleRadius)}; + + btMultiSphereShape* ms = new btMultiSphereShape(fromto, radii, 2); + childShape = ms; + } + } + else + { + btCapsuleShapeZ* cap = new btCapsuleShapeZ(col->m_geometry.m_capsuleRadius, + col->m_geometry.m_capsuleHeight); + childShape = cap; + } + break; + } + case URDF_GEOM_CDF: + { + //todo + break; + } + case URDF_GEOM_UNKNOWN: + { + break; + } + + } // switch geom if (childShape) { m_data->m_allocatedCollisionShapes.push_back(childShape); - compound->addChildShape(localInertiaFrame.inverse()*col->m_linkLocalFrame,childShape); + compound->addChildShape(localInertiaFrame.inverse() * col->m_linkLocalFrame, childShape); } } } @@ -2587,12 +2539,12 @@ class btCollisionShape* BulletMJCFImporter::getAllocatedCollisionShape(int index int BulletMJCFImporter::getNumAllocatedMeshInterfaces() const { - return m_data->m_allocatedMeshInterfaces.size(); + return m_data->m_allocatedMeshInterfaces.size(); } btStridingMeshInterface* BulletMJCFImporter::getAllocatedMeshInterface(int index) { - return m_data->m_allocatedMeshInterfaces[index]; + return m_data->m_allocatedMeshInterfaces[index]; } int BulletMJCFImporter::getNumModels() const @@ -2602,9 +2554,8 @@ int BulletMJCFImporter::getNumModels() const void BulletMJCFImporter::activateModel(int modelIndex) { - if ((modelIndex>=0) && (modelIndexm_models.size())) + if ((modelIndex >= 0) && (modelIndex < m_data->m_models.size())) { m_data->m_activeModel = modelIndex; } } - diff --git a/examples/Importers/ImportMJCFDemo/BulletMJCFImporter.h b/examples/Importers/ImportMJCFDemo/BulletMJCFImporter.h index a1b39454e..2c89fdbc9 100644 --- a/examples/Importers/ImportMJCFDemo/BulletMJCFImporter.h +++ b/examples/Importers/ImportMJCFDemo/BulletMJCFImporter.h @@ -4,13 +4,12 @@ #include "../ImportURDFDemo/URDFImporterInterface.h" #include "../ImportURDFDemo/UrdfRenderingInterface.h" - struct MJCFErrorLogger { virtual ~MJCFErrorLogger() {} - virtual void reportError(const char* error)=0; - virtual void reportWarning(const char* warning)=0; - virtual void printMessage(const char* msg)=0; + virtual void reportError(const char* error) = 0; + virtual void reportWarning(const char* warning) = 0; + virtual void printMessage(const char* msg) = 0; }; struct MJCFURDFTexture @@ -30,27 +29,26 @@ class BulletMJCFImporter : public URDFImporterInterface public: BulletMJCFImporter(struct GUIHelperInterface* helper, UrdfRenderingInterface* customConverter, int flags); virtual ~BulletMJCFImporter(); - + virtual bool parseMJCFString(const char* xmlString, MJCFErrorLogger* logger); virtual bool loadMJCF(const char* fileName, MJCFErrorLogger* logger, bool forceFixedBase = false); - virtual bool loadURDF(const char* fileName, bool forceFixedBase = false) { return false; } - virtual bool loadSDF(const char* fileName, bool forceFixedBase = false) { return false;} + virtual bool loadSDF(const char* fileName, bool forceFixedBase = false) { return false; } + + virtual const char* getPathPrefix(); + + ///return >=0 for the root link index, -1 if there is no root link + virtual int getRootLinkIndex() const; + + ///pure virtual interfaces, precondition is a valid linkIndex (you can assert/terminate if the linkIndex is out of range) + virtual std::string getLinkName(int linkIndex) const; - virtual const char* getPathPrefix(); - - ///return >=0 for the root link index, -1 if there is no root link - virtual int getRootLinkIndex() const; - - ///pure virtual interfaces, precondition is a valid linkIndex (you can assert/terminate if the linkIndex is out of range) - virtual std::string getLinkName(int linkIndex) const; - virtual std::string getBodyName() const; /// optional method to provide the link color. return true if the color is available and copied into colorRGBA, return false otherwise @@ -58,40 +56,38 @@ public: bool getLinkColor2(int linkIndex, struct UrdfMaterialColor& matCol) const; //optional method to get collision group (type) and mask (affinity) - virtual int getCollisionGroupAndMask(int linkIndex, int& colGroup, int& colMask) const ; - - ///this API will likely change, don't override it! - virtual bool getLinkContactInfo(int linkIndex, URDFLinkContactInfo& contactInfo ) const; - - virtual std::string getJointName(int linkIndex) const; + virtual int getCollisionGroupAndMask(int linkIndex, int& colGroup, int& colMask) const; - //fill mass and inertial data. If inertial data is missing, please initialize mass, inertia to sensitive values, and inertialFrame to identity. - virtual void getMassAndInertia(int urdfLinkIndex, btScalar& mass,btVector3& localInertiaDiagonal, btTransform& inertialFrame) const; - - ///fill an array of child link indices for this link, btAlignedObjectArray behaves like a std::vector so just use push_back and resize(0) if needed - virtual void getLinkChildIndices(int urdfLinkIndex, btAlignedObjectArray& childLinkIndices) const; - - virtual bool getJointInfo(int urdfLinkIndex, btTransform& parent2joint, btTransform& linkTransformInWorld, btVector3& jointAxisInJointSpace, int& jointType, btScalar& jointLowerLimit, btScalar& jointUpperLimit, btScalar& jointDamping, btScalar& jointFriction) const; + ///this API will likely change, don't override it! + virtual bool getLinkContactInfo(int linkIndex, URDFLinkContactInfo& contactInfo) const; + + virtual std::string getJointName(int linkIndex) const; + + //fill mass and inertial data. If inertial data is missing, please initialize mass, inertia to sensitive values, and inertialFrame to identity. + virtual void getMassAndInertia(int urdfLinkIndex, btScalar& mass, btVector3& localInertiaDiagonal, btTransform& inertialFrame) const; + + ///fill an array of child link indices for this link, btAlignedObjectArray behaves like a std::vector so just use push_back and resize(0) if needed + virtual void getLinkChildIndices(int urdfLinkIndex, btAlignedObjectArray& childLinkIndices) const; + + virtual bool getJointInfo(int urdfLinkIndex, btTransform& parent2joint, btTransform& linkTransformInWorld, btVector3& jointAxisInJointSpace, int& jointType, btScalar& jointLowerLimit, btScalar& jointUpperLimit, btScalar& jointDamping, btScalar& jointFriction) const; virtual bool getJointInfo2(int urdfLinkIndex, btTransform& parent2joint, btTransform& linkTransformInWorld, btVector3& jointAxisInJointSpace, int& jointType, btScalar& jointLowerLimit, btScalar& jointUpperLimit, btScalar& jointDamping, btScalar& jointFriction, btScalar& jointMaxForce, btScalar& jointMaxVelocity) const; - virtual bool getRootTransformInWorld(btTransform& rootTransformInWorld) const; - + virtual bool getRootTransformInWorld(btTransform& rootTransformInWorld) const; + virtual int convertLinkVisualShapes(int linkIndex, const char* pathPrefix, const btTransform& inertialFrame) const; - - virtual void convertLinkVisualShapes2(int linkIndex, int urdfIndex, const char* pathPrefix, const btTransform& inertialFrame, class btCollisionObject* colObj, int objectIndex) const; - virtual void setBodyUniqueId(int bodyId); - virtual int getBodyUniqueId() const; - - virtual class btCompoundShape* convertLinkCollisionShapes(int linkIndex, const char* pathPrefix, const btTransform& localInertiaFrame) const ; + + virtual void convertLinkVisualShapes2(int linkIndex, int urdfIndex, const char* pathPrefix, const btTransform& inertialFrame, class btCollisionObject* colObj, int objectIndex) const; + virtual void setBodyUniqueId(int bodyId); + virtual int getBodyUniqueId() const; + + virtual class btCompoundShape* convertLinkCollisionShapes(int linkIndex, const char* pathPrefix, const btTransform& localInertiaFrame) const; virtual int getNumAllocatedCollisionShapes() const; - virtual class btCollisionShape* getAllocatedCollisionShape(int index); + virtual class btCollisionShape* getAllocatedCollisionShape(int index); virtual int getNumModels() const; - virtual void activateModel(int modelIndex); + virtual void activateModel(int modelIndex); virtual int getNumAllocatedMeshInterfaces() const; virtual btStridingMeshInterface* getAllocatedMeshInterface(int index); - - }; -#endif //BULLET_MJCF_IMPORTER_H +#endif //BULLET_MJCF_IMPORTER_H diff --git a/examples/Importers/ImportMJCFDemo/ImportMJCFSetup.cpp b/examples/Importers/ImportMJCFDemo/ImportMJCFSetup.cpp index 53a30ea57..d0d57a1ca 100644 --- a/examples/Importers/ImportMJCFDemo/ImportMJCFSetup.cpp +++ b/examples/Importers/ImportMJCFDemo/ImportMJCFSetup.cpp @@ -19,86 +19,79 @@ class ImportMJCFSetup : public CommonMultiBodyBase { - char m_fileName[1024]; + char m_fileName[1024]; - struct ImportMJCFInternalData* m_data; + struct ImportMJCFInternalData* m_data; bool m_useMultiBody; - btAlignedObjectArray m_nameMemory; + btAlignedObjectArray m_nameMemory; btScalar m_grav; int m_upAxis; + public: - ImportMJCFSetup(struct GUIHelperInterface* helper, int option, const char* fileName); - virtual ~ImportMJCFSetup(); + ImportMJCFSetup(struct GUIHelperInterface* helper, int option, const char* fileName); + virtual ~ImportMJCFSetup(); virtual void initPhysics(); virtual void stepSimulation(float deltaTime); - void setFileName(const char* mjcfFileName); + void setFileName(const char* mjcfFileName); virtual void resetCamera() { float dist = 3.5; float pitch = -28; float yaw = -136; - float targetPos[3]={0.47,0,-0.64}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {0.47, 0, -0.64}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } }; - static btAlignedObjectArray gMCFJFileNameArray; - #define MAX_NUM_MOTORS 1024 - - struct ImportMJCFInternalData { - ImportMJCFInternalData() - :m_numMotors(0), - m_mb(0) - { - for (int i=0;i=numFileNames) + if (count >= numFileNames) { - count=0; + count = 0; } - sprintf(m_fileName,"%s",gMCFJFileNameArray[count++].c_str()); + sprintf(m_fileName, "%s", gMCFJFileNameArray[count++].c_str()); } } ImportMJCFSetup::~ImportMJCFSetup() { - for (int i=0;isetUpAxis(m_upAxis); - + createEmptyDynamicsWorld(); - + //MuJoCo uses a slightly different collision filter mode, use the FILTER_GROUPAMASKB_OR_GROUPBMASKA2 //@todo also use the modified collision filter for raycast and other collision related queries m_filterCallback->m_filterMode = FILTER_GROUPAMASKB_OR_GROUPBMASKA2; - + //m_dynamicsWorld->getSolverInfo().m_numIterations = 50; m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); m_dynamicsWorld->getDebugDrawer()->setDebugMode( - btIDebugDraw::DBG_DrawConstraints - +btIDebugDraw::DBG_DrawContactPoints - +btIDebugDraw::DBG_DrawAabb - );//+btIDebugDraw::DBG_DrawConstraintLimits); - + btIDebugDraw::DBG_DrawConstraints + btIDebugDraw::DBG_DrawContactPoints + btIDebugDraw::DBG_DrawAabb); //+btIDebugDraw::DBG_DrawConstraintLimits); if (m_guiHelper->getParameterInterface()) { @@ -216,16 +199,16 @@ void ImportMJCFSetup::initPhysics() m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); } - int flags=0; - BulletMJCFImporter importer(m_guiHelper, 0,flags); + int flags = 0; + BulletMJCFImporter importer(m_guiHelper, 0, flags); MyMJCFLogger logger; - bool result = importer.loadMJCF(m_fileName,&logger); + bool result = importer.loadMJCF(m_fileName, &logger); if (result) { btTransform rootTrans; rootTrans.setIdentity(); - for (int m =0; m

- /// @param bEnable true to enable option false to disable option. - /// @param nTime time in seconds to linger. - /// @return true if option successfully set - bool SetOptionLinger(bool bEnable, uint16 nTime); + /// Controls the actions taken when CSimpleSocket::Close is executed on a + /// socket object that has unsent data. The default value for this option + /// is \b off. + /// - Following are the three possible scenarios. + /// -# \b bEnable is false, CSimpleSocket::Close returns immediately, but + /// any unset data is transmitted (after CSimpleSocket::Close returns) + /// -# \b bEnable is true and \b nTime is zero, CSimpleSocket::Close return + /// immediately and any unsent data is discarded. + /// -# \b bEnable is true and \b nTime is nonzero, CSimpleSocket::Close does + /// not return until all unsent data is transmitted (or the connection is + /// Closed by the remote system). + ///

+ /// @param bEnable true to enable option false to disable option. + /// @param nTime time in seconds to linger. + /// @return true if option successfully set + bool SetOptionLinger(bool bEnable, uint16 nTime); - /// Tells the kernel that even if this port is busy (in the TIME_WAIT state), - /// go ahead and reuse it anyway. If it is busy, but with another state, - /// you will still get an address already in use error. - /// @return true if option successfully set - bool SetOptionReuseAddr(); + /// Tells the kernel that even if this port is busy (in the TIME_WAIT state), + /// go ahead and reuse it anyway. If it is busy, but with another state, + /// you will still get an address already in use error. + /// @return true if option successfully set + bool SetOptionReuseAddr(); - /// Gets the timeout value that specifies the maximum number of seconds a - /// call to CSimpleSocket::Open waits until it completes. - /// @return the length of time in seconds - int32 GetConnectTimeoutSec(void) { - return m_stConnectTimeout.tv_sec; - }; + /// Gets the timeout value that specifies the maximum number of seconds a + /// call to CSimpleSocket::Open waits until it completes. + /// @return the length of time in seconds + int32 GetConnectTimeoutSec(void) + { + return m_stConnectTimeout.tv_sec; + }; - /// Gets the timeout value that specifies the maximum number of microseconds - /// a call to CSimpleSocket::Open waits until it completes. - /// @return the length of time in microseconds - int32 GetConnectTimeoutUSec(void) { - return m_stConnectTimeout.tv_usec; - }; + /// Gets the timeout value that specifies the maximum number of microseconds + /// a call to CSimpleSocket::Open waits until it completes. + /// @return the length of time in microseconds + int32 GetConnectTimeoutUSec(void) + { + return m_stConnectTimeout.tv_usec; + }; - /// Sets the timeout value that specifies the maximum amount of time a call - /// to CSimpleSocket::Receive waits until it completes. Use the method - /// CSimpleSocket::SetReceiveTimeout to specify the number of seconds to wait. - /// If a call to CSimpleSocket::Receive has blocked for the specified length of - /// time without receiving additional data, it returns with a partial count - /// or CSimpleSocket::GetSocketError set to CSimpleSocket::SocketEwouldblock if no data - /// were received. - /// @param nConnectTimeoutSec of timeout in seconds. - /// @param nConnectTimeoutUsec of timeout in microseconds. - /// @return true if socket connection timeout was successfully set. - void SetConnectTimeout(int32 nConnectTimeoutSec, int32 nConnectTimeoutUsec = 0) - { - m_stConnectTimeout.tv_sec = nConnectTimeoutSec; - m_stConnectTimeout.tv_usec = nConnectTimeoutUsec; - }; + /// Sets the timeout value that specifies the maximum amount of time a call + /// to CSimpleSocket::Receive waits until it completes. Use the method + /// CSimpleSocket::SetReceiveTimeout to specify the number of seconds to wait. + /// If a call to CSimpleSocket::Receive has blocked for the specified length of + /// time without receiving additional data, it returns with a partial count + /// or CSimpleSocket::GetSocketError set to CSimpleSocket::SocketEwouldblock if no data + /// were received. + /// @param nConnectTimeoutSec of timeout in seconds. + /// @param nConnectTimeoutUsec of timeout in microseconds. + /// @return true if socket connection timeout was successfully set. + void SetConnectTimeout(int32 nConnectTimeoutSec, int32 nConnectTimeoutUsec = 0) + { + m_stConnectTimeout.tv_sec = nConnectTimeoutSec; + m_stConnectTimeout.tv_usec = nConnectTimeoutUsec; + }; - /// Gets the timeout value that specifies the maximum number of seconds a - /// a call to CSimpleSocket::Receive waits until it completes. - /// @return the length of time in seconds - int32 GetReceiveTimeoutSec(void) { - return m_stRecvTimeout.tv_sec; - }; + /// Gets the timeout value that specifies the maximum number of seconds a + /// a call to CSimpleSocket::Receive waits until it completes. + /// @return the length of time in seconds + int32 GetReceiveTimeoutSec(void) + { + return m_stRecvTimeout.tv_sec; + }; - /// Gets the timeout value that specifies the maximum number of microseconds - /// a call to CSimpleSocket::Receive waits until it completes. - /// @return the length of time in microseconds - int32 GetReceiveTimeoutUSec(void) { - return m_stRecvTimeout.tv_usec; - }; + /// Gets the timeout value that specifies the maximum number of microseconds + /// a call to CSimpleSocket::Receive waits until it completes. + /// @return the length of time in microseconds + int32 GetReceiveTimeoutUSec(void) + { + return m_stRecvTimeout.tv_usec; + }; - /// Sets the timeout value that specifies the maximum amount of time a call - /// to CSimpleSocket::Receive waits until it completes. Use the method - /// CSimpleSocket::SetReceiveTimeout to specify the number of seconds to wait. - /// If a call to CSimpleSocket::Receive has blocked for the specified length of - /// time without receiving additional data, it returns with a partial count - /// or CSimpleSocket::GetSocketError set to CSimpleSocket::SocketEwouldblock if no data - /// were received. - /// @param nRecvTimeoutSec of timeout in seconds. - /// @param nRecvTimeoutUsec of timeout in microseconds. - /// @return true if socket timeout was successfully set. - bool SetReceiveTimeout(int32 nRecvTimeoutSec, int32 nRecvTimeoutUsec = 0); + /// Sets the timeout value that specifies the maximum amount of time a call + /// to CSimpleSocket::Receive waits until it completes. Use the method + /// CSimpleSocket::SetReceiveTimeout to specify the number of seconds to wait. + /// If a call to CSimpleSocket::Receive has blocked for the specified length of + /// time without receiving additional data, it returns with a partial count + /// or CSimpleSocket::GetSocketError set to CSimpleSocket::SocketEwouldblock if no data + /// were received. + /// @param nRecvTimeoutSec of timeout in seconds. + /// @param nRecvTimeoutUsec of timeout in microseconds. + /// @return true if socket timeout was successfully set. + bool SetReceiveTimeout(int32 nRecvTimeoutSec, int32 nRecvTimeoutUsec = 0); - /// Enable/disable multicast for a socket. This options is only valid for - /// socket descriptors of type CSimpleSocket::SocketTypeUdp. - /// @return true if multicast was enabled or false if socket type is not - /// CSimpleSocket::SocketTypeUdp and the error will be set to - /// CSimpleSocket::SocketProtocolError - bool SetMulticast(bool bEnable, uint8 multicastTTL = 1); + /// Enable/disable multicast for a socket. This options is only valid for + /// socket descriptors of type CSimpleSocket::SocketTypeUdp. + /// @return true if multicast was enabled or false if socket type is not + /// CSimpleSocket::SocketTypeUdp and the error will be set to + /// CSimpleSocket::SocketProtocolError + bool SetMulticast(bool bEnable, uint8 multicastTTL = 1); - /// Return true if socket is multicast or false is socket is unicast - /// @return true if multicast is enabled - bool GetMulticast() { - return m_bIsMulticast; - }; + /// Return true if socket is multicast or false is socket is unicast + /// @return true if multicast is enabled + bool GetMulticast() + { + return m_bIsMulticast; + }; - /// Bind socket to a specific interface when using multicast. - /// @return true if successfully bound to interface - bool BindInterface(const char *pInterface); + /// Bind socket to a specific interface when using multicast. + /// @return true if successfully bound to interface + bool BindInterface(const char *pInterface); - /// Gets the timeout value that specifies the maximum number of seconds a - /// a call to CSimpleSocket::Send waits until it completes. - /// @return the length of time in seconds - int32 GetSendTimeoutSec(void) { - return m_stSendTimeout.tv_sec; - }; + /// Gets the timeout value that specifies the maximum number of seconds a + /// a call to CSimpleSocket::Send waits until it completes. + /// @return the length of time in seconds + int32 GetSendTimeoutSec(void) + { + return m_stSendTimeout.tv_sec; + }; - /// Gets the timeout value that specifies the maximum number of microseconds - /// a call to CSimpleSocket::Send waits until it completes. - /// @return the length of time in microseconds - int32 GetSendTimeoutUSec(void) { - return m_stSendTimeout.tv_usec; - }; + /// Gets the timeout value that specifies the maximum number of microseconds + /// a call to CSimpleSocket::Send waits until it completes. + /// @return the length of time in microseconds + int32 GetSendTimeoutUSec(void) + { + return m_stSendTimeout.tv_usec; + }; - /// Gets the timeout value that specifies the maximum amount of time a call - /// to CSimpleSocket::Send waits until it completes. - /// @return the length of time in seconds - bool SetSendTimeout(int32 nSendTimeoutSec, int32 nSendTimeoutUsec = 0); + /// Gets the timeout value that specifies the maximum amount of time a call + /// to CSimpleSocket::Send waits until it completes. + /// @return the length of time in seconds + bool SetSendTimeout(int32 nSendTimeoutSec, int32 nSendTimeoutUsec = 0); - /// Returns the last error that occured for the instace of the CSimpleSocket - /// instance. This method should be called immediately to retrieve the - /// error code for the failing mehtod call. - /// @return last error that occured. - CSocketError GetSocketError(void) { - return m_socketErrno; - }; - /* + /// Returns the last error that occured for the instace of the CSimpleSocket + /// instance. This method should be called immediately to retrieve the + /// error code for the failing mehtod call. + /// @return last error that occured. + CSocketError GetSocketError(void) + { + return m_socketErrno; + }; + /* CSocketError GetSocketError(void) { CSocketError err = m_socketErrno; m_socketErrno = SocketSuccess; @@ -422,170 +438,180 @@ public: }; */ - /// Get the total time the of the last operation in milliseconds. - /// @return number of milliseconds of last operation. - uint32 GetTotalTimeMs() { - return m_timer.GetMilliSeconds(); - }; + /// Get the total time the of the last operation in milliseconds. + /// @return number of milliseconds of last operation. + uint32 GetTotalTimeMs() + { + return m_timer.GetMilliSeconds(); + }; - /// Get the total time the of the last operation in microseconds. - /// @return number of microseconds or last operation. - uint32 GetTotalTimeUsec() { - return m_timer.GetMicroSeconds(); - }; + /// Get the total time the of the last operation in microseconds. + /// @return number of microseconds or last operation. + uint32 GetTotalTimeUsec() + { + return m_timer.GetMicroSeconds(); + }; - /// Return Differentiated Services Code Point (DSCP) value currently set on the socket object. - /// @return DSCP for current socket object. - ///

\b NOTE: Windows special notes http://support.microsoft.com/kb/248611. - int GetSocketDscp(void); + /// Return Differentiated Services Code Point (DSCP) value currently set on the socket object. + /// @return DSCP for current socket object. + ///

\b NOTE: Windows special notes http://support.microsoft.com/kb/248611. + int GetSocketDscp(void); - /// Set Differentiated Services Code Point (DSCP) for socket object. - /// @param nDscp value of TOS setting which will be converted to DSCP - /// @return true if DSCP value was properly set - ///

\b NOTE: Windows special notes http://support.microsoft.com/kb/248611. - bool SetSocketDscp(int nDscp); + /// Set Differentiated Services Code Point (DSCP) for socket object. + /// @param nDscp value of TOS setting which will be converted to DSCP + /// @return true if DSCP value was properly set + ///

\b NOTE: Windows special notes http://support.microsoft.com/kb/248611. + bool SetSocketDscp(int nDscp); - /// Return socket descriptor - /// @return socket descriptor which is a signed 32 bit integer. - SOCKET GetSocketDescriptor() { - return m_socket; - }; + /// Return socket descriptor + /// @return socket descriptor which is a signed 32 bit integer. + SOCKET GetSocketDescriptor() + { + return m_socket; + }; - /// Return socket descriptor - /// @return socket descriptor which is a signed 32 bit integer. - CSocketType GetSocketType() { - return m_nSocketType; - }; + /// Return socket descriptor + /// @return socket descriptor which is a signed 32 bit integer. + CSocketType GetSocketType() + { + return m_nSocketType; + }; - /// Returns clients Internet host address as a string in standard numbers-and-dots notation. - /// @return NULL if invalid - const char *GetClientAddr() { - return inet_ntoa(m_stClientSockaddr.sin_addr); - }; + /// Returns clients Internet host address as a string in standard numbers-and-dots notation. + /// @return NULL if invalid + const char *GetClientAddr() + { + return inet_ntoa(m_stClientSockaddr.sin_addr); + }; - /// Returns the port number on which the client is connected. - /// @return client port number. - uint16 GetClientPort() { - return m_stClientSockaddr.sin_port; - }; + /// Returns the port number on which the client is connected. + /// @return client port number. + uint16 GetClientPort() + { + return m_stClientSockaddr.sin_port; + }; - /// Returns server Internet host address as a string in standard numbers-and-dots notation. - /// @return NULL if invalid - const char *GetServerAddr() { - return inet_ntoa(m_stServerSockaddr.sin_addr); - }; + /// Returns server Internet host address as a string in standard numbers-and-dots notation. + /// @return NULL if invalid + const char *GetServerAddr() + { + return inet_ntoa(m_stServerSockaddr.sin_addr); + }; - /// Returns the port number on which the server is connected. - /// @return server port number. - uint16 GetServerPort() { - return ntohs(m_stServerSockaddr.sin_port); - }; + /// Returns the port number on which the server is connected. + /// @return server port number. + uint16 GetServerPort() + { + return ntohs(m_stServerSockaddr.sin_port); + }; - /// Get the TCP receive buffer window size for the current socket object. - ///

\b NOTE: Linux will set the receive buffer to twice the value passed. - /// @return zero on failure else the number of bytes of the TCP receive buffer window size if successful. - uint32 GetReceiveWindowSize() { - return GetWindowSize(SO_RCVBUF); - }; + /// Get the TCP receive buffer window size for the current socket object. + ///

\b NOTE: Linux will set the receive buffer to twice the value passed. + /// @return zero on failure else the number of bytes of the TCP receive buffer window size if successful. + uint32 GetReceiveWindowSize() + { + return GetWindowSize(SO_RCVBUF); + }; - /// Get the TCP send buffer window size for the current socket object. - ///

\b NOTE: Linux will set the send buffer to twice the value passed. - /// @return zero on failure else the number of bytes of the TCP receive buffer window size if successful. - uint32 GetSendWindowSize() { - return GetWindowSize(SO_SNDBUF); - }; + /// Get the TCP send buffer window size for the current socket object. + ///

\b NOTE: Linux will set the send buffer to twice the value passed. + /// @return zero on failure else the number of bytes of the TCP receive buffer window size if successful. + uint32 GetSendWindowSize() + { + return GetWindowSize(SO_SNDBUF); + }; - /// Set the TCP receive buffer window size for the current socket object. - ///

\b NOTE: Linux will set the receive buffer to twice the value passed. - /// @return zero on failure else the number of bytes of the TCP send buffer window size if successful. - uint32 SetReceiveWindowSize(uint32 nWindowSize) { - return SetWindowSize(SO_RCVBUF, nWindowSize); - }; + /// Set the TCP receive buffer window size for the current socket object. + ///

\b NOTE: Linux will set the receive buffer to twice the value passed. + /// @return zero on failure else the number of bytes of the TCP send buffer window size if successful. + uint32 SetReceiveWindowSize(uint32 nWindowSize) + { + return SetWindowSize(SO_RCVBUF, nWindowSize); + }; - /// Set the TCP send buffer window size for the current socket object. - ///

\b NOTE: Linux will set the send buffer to twice the value passed. - /// @return zero on failure else the number of bytes of the TCP send buffer window size if successful. - uint32 SetSendWindowSize(uint32 nWindowSize) { - return SetWindowSize(SO_SNDBUF, nWindowSize); - }; + /// Set the TCP send buffer window size for the current socket object. + ///

\b NOTE: Linux will set the send buffer to twice the value passed. + /// @return zero on failure else the number of bytes of the TCP send buffer window size if successful. + uint32 SetSendWindowSize(uint32 nWindowSize) + { + return SetWindowSize(SO_SNDBUF, nWindowSize); + }; - /// Disable the Nagle algorithm (Set TCP_NODELAY to true) - /// @return false if failed to set socket option otherwise return true; - bool DisableNagleAlgoritm(); - - /// Enable the Nagle algorithm (Set TCP_NODELAY to false) - /// @return false if failed to set socket option otherwise return true; - bool EnableNagleAlgoritm(); + /// Disable the Nagle algorithm (Set TCP_NODELAY to true) + /// @return false if failed to set socket option otherwise return true; + bool DisableNagleAlgoritm(); + /// Enable the Nagle algorithm (Set TCP_NODELAY to false) + /// @return false if failed to set socket option otherwise return true; + bool EnableNagleAlgoritm(); protected: - /// Set internal socket error to that specified error - /// @param error type of error - void SetSocketError(CSimpleSocket::CSocketError error) { - m_socketErrno = error; - }; + /// Set internal socket error to that specified error + /// @param error type of error + void SetSocketError(CSimpleSocket::CSocketError error) + { + m_socketErrno = error; + }; - /// Set object socket handle to that specified as parameter - /// @param socket value of socket descriptor - void SetSocketHandle(SOCKET socket) { - m_socket = socket; - }; + /// Set object socket handle to that specified as parameter + /// @param socket value of socket descriptor + void SetSocketHandle(SOCKET socket) + { + m_socket = socket; + }; private: - /// Generic function used to get the send/receive window size - /// @return zero on failure else the number of bytes of the TCP window size if successful. - uint32 GetWindowSize(uint32 nOptionName); + /// Generic function used to get the send/receive window size + /// @return zero on failure else the number of bytes of the TCP window size if successful. + uint32 GetWindowSize(uint32 nOptionName); - /// Generic function used to set the send/receive window size - /// @return zero on failure else the number of bytes of the TCP window size if successful. - uint32 SetWindowSize(uint32 nOptionName, uint32 nWindowSize); + /// Generic function used to set the send/receive window size + /// @return zero on failure else the number of bytes of the TCP window size if successful. + uint32 SetWindowSize(uint32 nOptionName, uint32 nWindowSize); + /// Attempts to send at most nNumItem blocks described by sendVector + /// to the socket descriptor associated with the socket object. + /// @param sendVector pointer to an array of iovec structures + /// @param nNumItems number of items in the vector to process + ///
\b Note: This implementation is for systems that don't natively + /// support this functionality. + /// @return number of bytes actually sent, return of zero means the + /// connection has been shutdown on the other side, and a return of -1 + /// means that an error has occurred. + int32 Writev(const struct iovec *pVector, size_t nCount); - /// Attempts to send at most nNumItem blocks described by sendVector - /// to the socket descriptor associated with the socket object. - /// @param sendVector pointer to an array of iovec structures - /// @param nNumItems number of items in the vector to process - ///
\b Note: This implementation is for systems that don't natively - /// support this functionality. - /// @return number of bytes actually sent, return of zero means the - /// connection has been shutdown on the other side, and a return of -1 - /// means that an error has occurred. - int32 Writev(const struct iovec *pVector, size_t nCount); + /// Flush the socket descriptor owned by the object. + /// @return true data was successfully sent, else return false; + bool Flush(); - /// Flush the socket descriptor owned by the object. - /// @return true data was successfully sent, else return false; - bool Flush(); - - CSimpleSocket *operator=(CSimpleSocket &socket); + CSimpleSocket *operator=(CSimpleSocket &socket); protected: - SOCKET m_socket; /// socket handle - CSocketError m_socketErrno; /// number of last error - uint8 *m_pBuffer; /// internal send/receive buffer - int32 m_nBufferSize; /// size of internal send/receive buffer - int32 m_nSocketDomain; /// socket type PF_INET, PF_INET6 - CSocketType m_nSocketType; /// socket type - UDP, TCP or RAW - int32 m_nBytesReceived; /// number of bytes received - int32 m_nBytesSent; /// number of bytes sent - uint32 m_nFlags; /// socket flags - bool m_bIsBlocking; /// is socket blocking - bool m_bIsMulticast; /// is the UDP socket multicast; - struct timeval m_stConnectTimeout; /// connection timeout - struct timeval m_stRecvTimeout; /// receive timeout - struct timeval m_stSendTimeout; /// send timeout - struct sockaddr_in m_stServerSockaddr; /// server address - struct sockaddr_in m_stClientSockaddr; /// client address - struct sockaddr_in m_stMulticastGroup; /// multicast group to bind to - struct linger m_stLinger; /// linger flag - CStatTimer m_timer; /// internal statistics. + SOCKET m_socket; /// socket handle + CSocketError m_socketErrno; /// number of last error + uint8 *m_pBuffer; /// internal send/receive buffer + int32 m_nBufferSize; /// size of internal send/receive buffer + int32 m_nSocketDomain; /// socket type PF_INET, PF_INET6 + CSocketType m_nSocketType; /// socket type - UDP, TCP or RAW + int32 m_nBytesReceived; /// number of bytes received + int32 m_nBytesSent; /// number of bytes sent + uint32 m_nFlags; /// socket flags + bool m_bIsBlocking; /// is socket blocking + bool m_bIsMulticast; /// is the UDP socket multicast; + struct timeval m_stConnectTimeout; /// connection timeout + struct timeval m_stRecvTimeout; /// receive timeout + struct timeval m_stSendTimeout; /// send timeout + struct sockaddr_in m_stServerSockaddr; /// server address + struct sockaddr_in m_stClientSockaddr; /// client address + struct sockaddr_in m_stMulticastGroup; /// multicast group to bind to + struct linger m_stLinger; /// linger flag + CStatTimer m_timer; /// internal statistics. #ifdef WIN32 - WSADATA m_hWSAData; /// Windows + WSADATA m_hWSAData; /// Windows #endif - fd_set m_writeFds; /// write file descriptor set - fd_set m_readFds; /// read file descriptor set - fd_set m_errorFds; /// error file descriptor set + fd_set m_writeFds; /// write file descriptor set + fd_set m_readFds; /// read file descriptor set + fd_set m_errorFds; /// error file descriptor set }; - #endif /* __SOCKET_H__ */ - diff --git a/examples/ThirdPartyLibs/clsocket/src/StatTimer.h b/examples/ThirdPartyLibs/clsocket/src/StatTimer.h index 2e049432e..dce3f8c96 100644 --- a/examples/ThirdPartyLibs/clsocket/src/StatTimer.h +++ b/examples/ThirdPartyLibs/clsocket/src/StatTimer.h @@ -46,21 +46,21 @@ #include #if WIN32 - #include - #include +#include +#include #endif #ifdef _LINUX - #include - #include +#include +#include #endif #include "Host.h" #if defined(WIN32) - #define GET_CLOCK_COUNT(x) QueryPerformanceCounter((LARGE_INTEGER *)x) +#define GET_CLOCK_COUNT(x) QueryPerformanceCounter((LARGE_INTEGER *)x) #else - #define GET_CLOCK_COUNT(x) gettimeofday(x, NULL) +#define GET_CLOCK_COUNT(x) gettimeofday(x, NULL) #endif #define MILLISECONDS_CONVERSION 1000 @@ -68,47 +68,43 @@ /// Class to abstract socket communications in a cross platform manner. /// This class is designed -class CStatTimer { +class CStatTimer +{ public: - CStatTimer() - { - }; + CStatTimer(){}; - ~CStatTimer() - { - }; + ~CStatTimer(){}; - void Initialize() - { - memset(&m_startTime, 0, sizeof(struct timeval)); - memset(&m_endTime, 0, sizeof(struct timeval)); - }; + void Initialize() + { + memset(&m_startTime, 0, sizeof(struct timeval)); + memset(&m_endTime, 0, sizeof(struct timeval)); + }; - struct timeval GetStartTime() { return m_startTime; }; - void SetStartTime() { GET_CLOCK_COUNT(&m_startTime); }; + struct timeval GetStartTime() { return m_startTime; }; + void SetStartTime() { GET_CLOCK_COUNT(&m_startTime); }; - struct timeval GetEndTime() { return m_endTime; }; - void SetEndTime() { GET_CLOCK_COUNT(&m_endTime); }; + struct timeval GetEndTime() { return m_endTime; }; + void SetEndTime() { GET_CLOCK_COUNT(&m_endTime); }; - uint32 GetMilliSeconds() { return (CalcTotalUSec() / MILLISECONDS_CONVERSION); }; - uint32 GetMicroSeconds() { return (CalcTotalUSec()); }; - uint32 GetSeconds() { return (CalcTotalUSec() / MICROSECONDS_CONVERSION); }; + uint32 GetMilliSeconds() { return (CalcTotalUSec() / MILLISECONDS_CONVERSION); }; + uint32 GetMicroSeconds() { return (CalcTotalUSec()); }; + uint32 GetSeconds() { return (CalcTotalUSec() / MICROSECONDS_CONVERSION); }; - uint32 GetCurrentTime() - { - struct timeval tmpTime; - GET_CLOCK_COUNT(&tmpTime); - return ((tmpTime.tv_sec * MICROSECONDS_CONVERSION) + tmpTime.tv_usec); - }; + uint32 GetCurrentTime() + { + struct timeval tmpTime; + GET_CLOCK_COUNT(&tmpTime); + return ((tmpTime.tv_sec * MICROSECONDS_CONVERSION) + tmpTime.tv_usec); + }; private: - uint32 CalcTotalUSec() { return (((m_endTime.tv_sec - m_startTime.tv_sec) * MICROSECONDS_CONVERSION) + - (m_endTime.tv_usec - m_startTime.tv_usec)); }; - + uint32 CalcTotalUSec() { return (((m_endTime.tv_sec - m_startTime.tv_sec) * MICROSECONDS_CONVERSION) + + (m_endTime.tv_usec - m_startTime.tv_usec)); }; private: - struct timeval m_startTime; - struct timeval m_endTime; + struct timeval m_startTime; + struct timeval m_endTime; }; -#endif // __CSTATTIMER_H__ +#endif // __CSTATTIMER_H__ diff --git a/examples/ThirdPartyLibs/enet/callbacks.c b/examples/ThirdPartyLibs/enet/callbacks.c index f94128256..cb6174b41 100644 --- a/examples/ThirdPartyLibs/enet/callbacks.c +++ b/examples/ThirdPartyLibs/enet/callbacks.c @@ -5,43 +5,39 @@ #define ENET_BUILDING_LIB 1 #include "enet/enet.h" -static ENetCallbacks callbacks = { malloc, free, abort }; +static ENetCallbacks callbacks = {malloc, free, abort}; -int -enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits) +int enet_initialize_with_callbacks(ENetVersion version, const ENetCallbacks* inits) { - if (version < ENET_VERSION_CREATE (1, 3, 0)) - return -1; + if (version < ENET_VERSION_CREATE(1, 3, 0)) + return -1; - if (inits -> malloc != NULL || inits -> free != NULL) - { - if (inits -> malloc == NULL || inits -> free == NULL) - return -1; + if (inits->malloc != NULL || inits->free != NULL) + { + if (inits->malloc == NULL || inits->free == NULL) + return -1; - callbacks.malloc = inits -> malloc; - callbacks.free = inits -> free; - } - - if (inits -> no_memory != NULL) - callbacks.no_memory = inits -> no_memory; + callbacks.malloc = inits->malloc; + callbacks.free = inits->free; + } - return enet_initialize (); -} - -void * -enet_malloc (size_t size) -{ - void * memory = callbacks.malloc (size); + if (inits->no_memory != NULL) + callbacks.no_memory = inits->no_memory; - if (memory == NULL) - callbacks.no_memory (); - - return memory; + return enet_initialize(); } -void -enet_free (void * memory) +void* enet_malloc(size_t size) { - callbacks.free (memory); + void* memory = callbacks.malloc(size); + + if (memory == NULL) + callbacks.no_memory(); + + return memory; } +void enet_free(void* memory) +{ + callbacks.free(memory); +} diff --git a/examples/ThirdPartyLibs/enet/compress.c b/examples/ThirdPartyLibs/enet/compress.c index 784489a78..25b98ac50 100644 --- a/examples/ThirdPartyLibs/enet/compress.c +++ b/examples/ThirdPartyLibs/enet/compress.c @@ -8,32 +8,32 @@ typedef struct _ENetSymbol { - /* binary indexed tree of symbols */ - enet_uint8 value; - enet_uint8 count; - enet_uint16 under; - enet_uint16 left, right; + /* binary indexed tree of symbols */ + enet_uint8 value; + enet_uint8 count; + enet_uint16 under; + enet_uint16 left, right; - /* context defined by this symbol */ - enet_uint16 symbols; - enet_uint16 escapes; - enet_uint16 total; - enet_uint16 parent; + /* context defined by this symbol */ + enet_uint16 symbols; + enet_uint16 escapes; + enet_uint16 total; + enet_uint16 parent; } ENetSymbol; /* adaptation constants tuned aggressively for small packet sizes rather than large file compression */ enum { - ENET_RANGE_CODER_TOP = 1<<24, - ENET_RANGE_CODER_BOTTOM = 1<<16, + ENET_RANGE_CODER_TOP = 1 << 24, + ENET_RANGE_CODER_BOTTOM = 1 << 16, - ENET_CONTEXT_SYMBOL_DELTA = 3, - ENET_CONTEXT_SYMBOL_MINIMUM = 1, - ENET_CONTEXT_ESCAPE_MINIMUM = 1, + ENET_CONTEXT_SYMBOL_DELTA = 3, + ENET_CONTEXT_SYMBOL_MINIMUM = 1, + ENET_CONTEXT_ESCAPE_MINIMUM = 1, - ENET_SUBCONTEXT_ORDER = 2, - ENET_SUBCONTEXT_SYMBOL_DELTA = 2, - ENET_SUBCONTEXT_ESCAPE_DELTA = 5 + ENET_SUBCONTEXT_ORDER = 2, + ENET_SUBCONTEXT_SYMBOL_DELTA = 2, + ENET_SUBCONTEXT_ESCAPE_DELTA = 5 }; /* context exclusion roughly halves compression speed, so disable for now */ @@ -41,589 +41,601 @@ enum typedef struct _ENetRangeCoder { - /* only allocate enough symbols for reasonable MTUs, would need to be larger for large file compression */ - ENetSymbol symbols[4096]; + /* only allocate enough symbols for reasonable MTUs, would need to be larger for large file compression */ + ENetSymbol symbols[4096]; } ENetRangeCoder; void * -enet_range_coder_create (void) +enet_range_coder_create(void) { - ENetRangeCoder * rangeCoder = (ENetRangeCoder *) enet_malloc (sizeof (ENetRangeCoder)); - if (rangeCoder == NULL) - return NULL; + ENetRangeCoder *rangeCoder = (ENetRangeCoder *)enet_malloc(sizeof(ENetRangeCoder)); + if (rangeCoder == NULL) + return NULL; - return rangeCoder; + return rangeCoder; } -void -enet_range_coder_destroy (void * context) +void enet_range_coder_destroy(void *context) { - ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context; - if (rangeCoder == NULL) - return; + ENetRangeCoder *rangeCoder = (ENetRangeCoder *)context; + if (rangeCoder == NULL) + return; - enet_free (rangeCoder); + enet_free(rangeCoder); } -#define ENET_SYMBOL_CREATE(symbol, value_, count_) \ -{ \ - symbol = & rangeCoder -> symbols [nextSymbol ++]; \ - symbol -> value = value_; \ - symbol -> count = count_; \ - symbol -> under = count_; \ - symbol -> left = 0; \ - symbol -> right = 0; \ - symbol -> symbols = 0; \ - symbol -> escapes = 0; \ - symbol -> total = 0; \ - symbol -> parent = 0; \ -} +#define ENET_SYMBOL_CREATE(symbol, value_, count_) \ + { \ + symbol = &rangeCoder->symbols[nextSymbol++]; \ + symbol->value = value_; \ + symbol->count = count_; \ + symbol->under = count_; \ + symbol->left = 0; \ + symbol->right = 0; \ + symbol->symbols = 0; \ + symbol->escapes = 0; \ + symbol->total = 0; \ + symbol->parent = 0; \ + } #define ENET_CONTEXT_CREATE(context, escapes_, minimum) \ -{ \ - ENET_SYMBOL_CREATE (context, 0, 0); \ - (context) -> escapes = escapes_; \ - (context) -> total = escapes_ + 256*minimum; \ - (context) -> symbols = 0; \ -} + { \ + ENET_SYMBOL_CREATE(context, 0, 0); \ + (context)->escapes = escapes_; \ + (context)->total = escapes_ + 256 * minimum; \ + (context)->symbols = 0; \ + } static enet_uint16 -enet_symbol_rescale (ENetSymbol * symbol) +enet_symbol_rescale(ENetSymbol *symbol) { - enet_uint16 total = 0; - for (;;) - { - symbol -> count -= symbol->count >> 1; - symbol -> under = symbol -> count; - if (symbol -> left) - symbol -> under += enet_symbol_rescale (symbol + symbol -> left); - total += symbol -> under; - if (! symbol -> right) break; - symbol += symbol -> right; - } - return total; + enet_uint16 total = 0; + for (;;) + { + symbol->count -= symbol->count >> 1; + symbol->under = symbol->count; + if (symbol->left) + symbol->under += enet_symbol_rescale(symbol + symbol->left); + total += symbol->under; + if (!symbol->right) break; + symbol += symbol->right; + } + return total; } -#define ENET_CONTEXT_RESCALE(context, minimum) \ -{ \ - (context) -> total = (context) -> symbols ? enet_symbol_rescale ((context) + (context) -> symbols) : 0; \ - (context) -> escapes -= (context) -> escapes >> 1; \ - (context) -> total += (context) -> escapes + 256*minimum; \ -} +#define ENET_CONTEXT_RESCALE(context, minimum) \ + { \ + (context)->total = (context)->symbols ? enet_symbol_rescale((context) + (context)->symbols) : 0; \ + (context)->escapes -= (context)->escapes >> 1; \ + (context)->total += (context)->escapes + 256 * minimum; \ + } #define ENET_RANGE_CODER_OUTPUT(value) \ -{ \ - if (outData >= outEnd) \ - return 0; \ - * outData ++ = value; \ -} + { \ + if (outData >= outEnd) \ + return 0; \ + *outData++ = value; \ + } -#define ENET_RANGE_CODER_ENCODE(under, count, total) \ -{ \ - encodeRange /= (total); \ - encodeLow += (under) * encodeRange; \ - encodeRange *= (count); \ - for (;;) \ - { \ - if((encodeLow ^ (encodeLow + encodeRange)) >= ENET_RANGE_CODER_TOP) \ - { \ - if(encodeRange >= ENET_RANGE_CODER_BOTTOM) break; \ - encodeRange = -encodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \ - } \ - ENET_RANGE_CODER_OUTPUT (encodeLow >> 24); \ - encodeRange <<= 8; \ - encodeLow <<= 8; \ - } \ -} +#define ENET_RANGE_CODER_ENCODE(under, count, total) \ + { \ + encodeRange /= (total); \ + encodeLow += (under)*encodeRange; \ + encodeRange *= (count); \ + for (;;) \ + { \ + if ((encodeLow ^ (encodeLow + encodeRange)) >= ENET_RANGE_CODER_TOP) \ + { \ + if (encodeRange >= ENET_RANGE_CODER_BOTTOM) break; \ + encodeRange = -encodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \ + } \ + ENET_RANGE_CODER_OUTPUT(encodeLow >> 24); \ + encodeRange <<= 8; \ + encodeLow <<= 8; \ + } \ + } -#define ENET_RANGE_CODER_FLUSH \ -{ \ - while (encodeLow) \ - { \ - ENET_RANGE_CODER_OUTPUT (encodeLow >> 24); \ - encodeLow <<= 8; \ - } \ -} +#define ENET_RANGE_CODER_FLUSH \ + { \ + while (encodeLow) \ + { \ + ENET_RANGE_CODER_OUTPUT(encodeLow >> 24); \ + encodeLow <<= 8; \ + } \ + } -#define ENET_RANGE_CODER_FREE_SYMBOLS \ -{ \ - if (nextSymbol >= sizeof (rangeCoder -> symbols) / sizeof (ENetSymbol) - ENET_SUBCONTEXT_ORDER ) \ - { \ - nextSymbol = 0; \ - ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM); \ - predicted = 0; \ - order = 0; \ - } \ -} +#define ENET_RANGE_CODER_FREE_SYMBOLS \ + { \ + if (nextSymbol >= sizeof(rangeCoder->symbols) / sizeof(ENetSymbol) - ENET_SUBCONTEXT_ORDER) \ + { \ + nextSymbol = 0; \ + ENET_CONTEXT_CREATE(root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM); \ + predicted = 0; \ + order = 0; \ + } \ + } #define ENET_CONTEXT_ENCODE(context, symbol_, value_, under_, count_, update, minimum) \ -{ \ - under_ = value*minimum; \ - count_ = minimum; \ - if (! (context) -> symbols) \ - { \ - ENET_SYMBOL_CREATE (symbol_, value_, update); \ - (context) -> symbols = symbol_ - (context); \ - } \ - else \ - { \ - ENetSymbol * node = (context) + (context) -> symbols; \ - for (;;) \ - { \ - if (value_ < node -> value) \ - { \ - node -> under += update; \ - if (node -> left) { node += node -> left; continue; } \ - ENET_SYMBOL_CREATE (symbol_, value_, update); \ - node -> left = symbol_ - node; \ - } \ - else \ - if (value_ > node -> value) \ - { \ - under_ += node -> under; \ - if (node -> right) { node += node -> right; continue; } \ - ENET_SYMBOL_CREATE (symbol_, value_, update); \ - node -> right = symbol_ - node; \ - } \ - else \ - { \ - count_ += node -> count; \ - under_ += node -> under - node -> count; \ - node -> under += update; \ - node -> count += update; \ - symbol_ = node; \ - } \ - break; \ - } \ - } \ -} + { \ + under_ = value * minimum; \ + count_ = minimum; \ + if (!(context)->symbols) \ + { \ + ENET_SYMBOL_CREATE(symbol_, value_, update); \ + (context)->symbols = symbol_ - (context); \ + } \ + else \ + { \ + ENetSymbol *node = (context) + (context)->symbols; \ + for (;;) \ + { \ + if (value_ < node->value) \ + { \ + node->under += update; \ + if (node->left) \ + { \ + node += node->left; \ + continue; \ + } \ + ENET_SYMBOL_CREATE(symbol_, value_, update); \ + node->left = symbol_ - node; \ + } \ + else if (value_ > node->value) \ + { \ + under_ += node->under; \ + if (node->right) \ + { \ + node += node->right; \ + continue; \ + } \ + ENET_SYMBOL_CREATE(symbol_, value_, update); \ + node->right = symbol_ - node; \ + } \ + else \ + { \ + count_ += node->count; \ + under_ += node->under - node->count; \ + node->under += update; \ + node->count += update; \ + symbol_ = node; \ + } \ + break; \ + } \ + } \ + } #ifdef ENET_CONTEXT_EXCLUSION -static const ENetSymbol emptyContext = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; +static const ENetSymbol emptyContext = {0, 0, 0, 0, 0, 0, 0, 0, 0}; -#define ENET_CONTEXT_WALK(context, body) \ -{ \ - const ENetSymbol * node = (context) + (context) -> symbols; \ - const ENetSymbol * stack [256]; \ - size_t stackSize = 0; \ - while (node -> left) \ - { \ - stack [stackSize ++] = node; \ - node += node -> left; \ - } \ - for (;;) \ - { \ - body; \ - if (node -> right) \ - { \ - node += node -> right; \ - while (node -> left) \ - { \ - stack [stackSize ++] = node; \ - node += node -> left; \ - } \ - } \ - else \ - if (stackSize <= 0) \ - break; \ - else \ - node = stack [-- stackSize]; \ - } \ -} +#define ENET_CONTEXT_WALK(context, body) \ + { \ + const ENetSymbol *node = (context) + (context)->symbols; \ + const ENetSymbol *stack[256]; \ + size_t stackSize = 0; \ + while (node->left) \ + { \ + stack[stackSize++] = node; \ + node += node->left; \ + } \ + for (;;) \ + { \ + body; \ + if (node->right) \ + { \ + node += node->right; \ + while (node->left) \ + { \ + stack[stackSize++] = node; \ + node += node->left; \ + } \ + } \ + else if (stackSize <= 0) \ + break; \ + else \ + node = stack[--stackSize]; \ + } \ + } -#define ENET_CONTEXT_ENCODE_EXCLUDE(context, value_, under, total, minimum) \ -ENET_CONTEXT_WALK(context, { \ - if (node -> value != value_) \ - { \ - enet_uint16 parentCount = rangeCoder -> symbols [node -> parent].count + minimum; \ - if (node -> value < value_) \ - under -= parentCount; \ - total -= parentCount; \ - } \ -}) +#define ENET_CONTEXT_ENCODE_EXCLUDE(context, value_, under, total, minimum) \ + ENET_CONTEXT_WALK(context, { \ + if (node->value != value_) \ + { \ + enet_uint16 parentCount = rangeCoder->symbols[node->parent].count + minimum; \ + if (node->value < value_) \ + under -= parentCount; \ + total -= parentCount; \ + } \ + }) #endif size_t -enet_range_coder_compress (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit) +enet_range_coder_compress(void *context, const ENetBuffer *inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 *outData, size_t outLimit) { - ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context; - enet_uint8 * outStart = outData, * outEnd = & outData [outLimit]; - const enet_uint8 * inData, * inEnd; - enet_uint32 encodeLow = 0, encodeRange = ~0; - ENetSymbol * root; - enet_uint16 predicted = 0; - size_t order = 0, nextSymbol = 0; + ENetRangeCoder *rangeCoder = (ENetRangeCoder *)context; + enet_uint8 *outStart = outData, *outEnd = &outData[outLimit]; + const enet_uint8 *inData, *inEnd; + enet_uint32 encodeLow = 0, encodeRange = ~0; + ENetSymbol *root; + enet_uint16 predicted = 0; + size_t order = 0, nextSymbol = 0; - if (rangeCoder == NULL || inBufferCount <= 0 || inLimit <= 0) - return 0; + if (rangeCoder == NULL || inBufferCount <= 0 || inLimit <= 0) + return 0; - inData = (const enet_uint8 *) inBuffers -> data; - inEnd = & inData [inBuffers -> dataLength]; - inBuffers ++; - inBufferCount --; + inData = (const enet_uint8 *)inBuffers->data; + inEnd = &inData[inBuffers->dataLength]; + inBuffers++; + inBufferCount--; - ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM); + ENET_CONTEXT_CREATE(root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM); - for (;;) - { - ENetSymbol * subcontext, * symbol; + for (;;) + { + ENetSymbol *subcontext, *symbol; #ifdef ENET_CONTEXT_EXCLUSION - const ENetSymbol * childContext = & emptyContext; + const ENetSymbol *childContext = &emptyContext; #endif - enet_uint8 value; - enet_uint16 count, under, * parent = & predicted, total; - if (inData >= inEnd) - { - if (inBufferCount <= 0) - break; - inData = (const enet_uint8 *) inBuffers -> data; - inEnd = & inData [inBuffers -> dataLength]; - inBuffers ++; - inBufferCount --; - } - value = * inData ++; - - for (subcontext = & rangeCoder -> symbols [predicted]; - subcontext != root; + enet_uint8 value; + enet_uint16 count, under, *parent = &predicted, total; + if (inData >= inEnd) + { + if (inBufferCount <= 0) + break; + inData = (const enet_uint8 *)inBuffers->data; + inEnd = &inData[inBuffers->dataLength]; + inBuffers++; + inBufferCount--; + } + value = *inData++; + + for (subcontext = &rangeCoder->symbols[predicted]; + subcontext != root; #ifdef ENET_CONTEXT_EXCLUSION - childContext = subcontext, + childContext = subcontext, #endif - subcontext = & rangeCoder -> symbols [subcontext -> parent]) - { - ENET_CONTEXT_ENCODE (subcontext, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0); - * parent = symbol - rangeCoder -> symbols; - parent = & symbol -> parent; - total = subcontext -> total; + subcontext = &rangeCoder->symbols[subcontext->parent]) + { + ENET_CONTEXT_ENCODE(subcontext, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0); + *parent = symbol - rangeCoder->symbols; + parent = &symbol->parent; + total = subcontext->total; #ifdef ENET_CONTEXT_EXCLUSION - if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA) - ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, 0); + if (childContext->total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA) + ENET_CONTEXT_ENCODE_EXCLUDE(childContext, value, under, total, 0); #endif - if (count > 0) - { - ENET_RANGE_CODER_ENCODE (subcontext -> escapes + under, count, total); - } - else - { - if (subcontext -> escapes > 0 && subcontext -> escapes < total) - ENET_RANGE_CODER_ENCODE (0, subcontext -> escapes, total); - subcontext -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA; - subcontext -> total += ENET_SUBCONTEXT_ESCAPE_DELTA; - } - subcontext -> total += ENET_SUBCONTEXT_SYMBOL_DELTA; - if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext -> total > ENET_RANGE_CODER_BOTTOM - 0x100) - ENET_CONTEXT_RESCALE (subcontext, 0); - if (count > 0) goto nextInput; - } + if (count > 0) + { + ENET_RANGE_CODER_ENCODE(subcontext->escapes + under, count, total); + } + else + { + if (subcontext->escapes > 0 && subcontext->escapes < total) + ENET_RANGE_CODER_ENCODE(0, subcontext->escapes, total); + subcontext->escapes += ENET_SUBCONTEXT_ESCAPE_DELTA; + subcontext->total += ENET_SUBCONTEXT_ESCAPE_DELTA; + } + subcontext->total += ENET_SUBCONTEXT_SYMBOL_DELTA; + if (count > 0xFF - 2 * ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext->total > ENET_RANGE_CODER_BOTTOM - 0x100) + ENET_CONTEXT_RESCALE(subcontext, 0); + if (count > 0) goto nextInput; + } - ENET_CONTEXT_ENCODE (root, symbol, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM); - * parent = symbol - rangeCoder -> symbols; - parent = & symbol -> parent; - total = root -> total; + ENET_CONTEXT_ENCODE(root, symbol, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM); + *parent = symbol - rangeCoder->symbols; + parent = &symbol->parent; + total = root->total; #ifdef ENET_CONTEXT_EXCLUSION - if (childContext -> total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA) - ENET_CONTEXT_ENCODE_EXCLUDE (childContext, value, under, total, ENET_CONTEXT_SYMBOL_MINIMUM); + if (childContext->total > ENET_SUBCONTEXT_SYMBOL_DELTA + ENET_SUBCONTEXT_ESCAPE_DELTA) + ENET_CONTEXT_ENCODE_EXCLUDE(childContext, value, under, total, ENET_CONTEXT_SYMBOL_MINIMUM); #endif - ENET_RANGE_CODER_ENCODE (root -> escapes + under, count, total); - root -> total += ENET_CONTEXT_SYMBOL_DELTA; - if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100) - ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM); + ENET_RANGE_CODER_ENCODE(root->escapes + under, count, total); + root->total += ENET_CONTEXT_SYMBOL_DELTA; + if (count > 0xFF - 2 * ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root->total > ENET_RANGE_CODER_BOTTOM - 0x100) + ENET_CONTEXT_RESCALE(root, ENET_CONTEXT_SYMBOL_MINIMUM); - nextInput: - if (order >= ENET_SUBCONTEXT_ORDER) - predicted = rangeCoder -> symbols [predicted].parent; - else - order ++; - ENET_RANGE_CODER_FREE_SYMBOLS; - } + nextInput: + if (order >= ENET_SUBCONTEXT_ORDER) + predicted = rangeCoder->symbols[predicted].parent; + else + order++; + ENET_RANGE_CODER_FREE_SYMBOLS; + } - ENET_RANGE_CODER_FLUSH; + ENET_RANGE_CODER_FLUSH; - return (size_t) (outData - outStart); + return (size_t)(outData - outStart); } -#define ENET_RANGE_CODER_SEED \ -{ \ - if (inData < inEnd) decodeCode |= * inData ++ << 24; \ - if (inData < inEnd) decodeCode |= * inData ++ << 16; \ - if (inData < inEnd) decodeCode |= * inData ++ << 8; \ - if (inData < inEnd) decodeCode |= * inData ++; \ -} +#define ENET_RANGE_CODER_SEED \ + { \ + if (inData < inEnd) decodeCode |= *inData++ << 24; \ + if (inData < inEnd) decodeCode |= *inData++ << 16; \ + if (inData < inEnd) decodeCode |= *inData++ << 8; \ + if (inData < inEnd) decodeCode |= *inData++; \ + } #define ENET_RANGE_CODER_READ(total) ((decodeCode - decodeLow) / (decodeRange /= (total))) -#define ENET_RANGE_CODER_DECODE(under, count, total) \ -{ \ - decodeLow += (under) * decodeRange; \ - decodeRange *= (count); \ - for (;;) \ - { \ - if((decodeLow ^ (decodeLow + decodeRange)) >= ENET_RANGE_CODER_TOP) \ - { \ - if(decodeRange >= ENET_RANGE_CODER_BOTTOM) break; \ - decodeRange = -decodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \ - } \ - decodeCode <<= 8; \ - if (inData < inEnd) \ - decodeCode |= * inData ++; \ - decodeRange <<= 8; \ - decodeLow <<= 8; \ - } \ -} +#define ENET_RANGE_CODER_DECODE(under, count, total) \ + { \ + decodeLow += (under)*decodeRange; \ + decodeRange *= (count); \ + for (;;) \ + { \ + if ((decodeLow ^ (decodeLow + decodeRange)) >= ENET_RANGE_CODER_TOP) \ + { \ + if (decodeRange >= ENET_RANGE_CODER_BOTTOM) break; \ + decodeRange = -decodeLow & (ENET_RANGE_CODER_BOTTOM - 1); \ + } \ + decodeCode <<= 8; \ + if (inData < inEnd) \ + decodeCode |= *inData++; \ + decodeRange <<= 8; \ + decodeLow <<= 8; \ + } \ + } #define ENET_CONTEXT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, createRoot, visitNode, createRight, createLeft) \ -{ \ - under_ = 0; \ - count_ = minimum; \ - if (! (context) -> symbols) \ - { \ - createRoot; \ - } \ - else \ - { \ - ENetSymbol * node = (context) + (context) -> symbols; \ - for (;;) \ - { \ - enet_uint16 after = under_ + node -> under + (node -> value + 1)*minimum, before = node -> count + minimum; \ - visitNode; \ - if (code >= after) \ - { \ - under_ += node -> under; \ - if (node -> right) { node += node -> right; continue; } \ - createRight; \ - } \ - else \ - if (code < after - before) \ - { \ - node -> under += update; \ - if (node -> left) { node += node -> left; continue; } \ - createLeft; \ - } \ - else \ - { \ - value_ = node -> value; \ - count_ += node -> count; \ - under_ = after - before; \ - node -> under += update; \ - node -> count += update; \ - symbol_ = node; \ - } \ - break; \ - } \ - } \ -} + { \ + under_ = 0; \ + count_ = minimum; \ + if (!(context)->symbols) \ + { \ + createRoot; \ + } \ + else \ + { \ + ENetSymbol *node = (context) + (context)->symbols; \ + for (;;) \ + { \ + enet_uint16 after = under_ + node->under + (node->value + 1) * minimum, before = node->count + minimum; \ + visitNode; \ + if (code >= after) \ + { \ + under_ += node->under; \ + if (node->right) \ + { \ + node += node->right; \ + continue; \ + } \ + createRight; \ + } \ + else if (code < after - before) \ + { \ + node->under += update; \ + if (node->left) \ + { \ + node += node->left; \ + continue; \ + } \ + createLeft; \ + } \ + else \ + { \ + value_ = node->value; \ + count_ += node->count; \ + under_ = after - before; \ + node->under += update; \ + node->count += update; \ + symbol_ = node; \ + } \ + break; \ + } \ + } \ + } #define ENET_CONTEXT_TRY_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, exclude) \ -ENET_CONTEXT_DECODE (context, symbol_, code, value_, under_, count_, update, minimum, return 0, exclude (node -> value, after, before), return 0, return 0) + ENET_CONTEXT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, return 0, exclude(node->value, after, before), return 0, return 0) #define ENET_CONTEXT_ROOT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, exclude) \ -ENET_CONTEXT_DECODE (context, symbol_, code, value_, under_, count_, update, minimum, \ - { \ - value_ = code / minimum; \ - under_ = code - code%minimum; \ - ENET_SYMBOL_CREATE (symbol_, value_, update); \ - (context) -> symbols = symbol_ - (context); \ - }, \ - exclude (node -> value, after, before), \ - { \ - value_ = node->value + 1 + (code - after)/minimum; \ - under_ = code - (code - after)%minimum; \ - ENET_SYMBOL_CREATE (symbol_, value_, update); \ - node -> right = symbol_ - node; \ - }, \ - { \ - value_ = node->value - 1 - (after - before - code - 1)/minimum; \ - under_ = code - (after - before - code - 1)%minimum; \ - ENET_SYMBOL_CREATE (symbol_, value_, update); \ - node -> left = symbol_ - node; \ - }) \ + ENET_CONTEXT_DECODE(context, symbol_, code, value_, under_, count_, update, minimum, \ + { \ + value_ = code / minimum; \ + under_ = code - code % minimum; \ + ENET_SYMBOL_CREATE(symbol_, value_, update); \ + (context)->symbols = symbol_ - (context); \ + }, \ + exclude(node->value, after, before), \ + { \ + value_ = node->value + 1 + (code - after) / minimum; \ + under_ = code - (code - after) % minimum; \ + ENET_SYMBOL_CREATE(symbol_, value_, update); \ + node->right = symbol_ - node; \ + }, \ + { \ + value_ = node->value - 1 - (after - before - code - 1) / minimum; \ + under_ = code - (after - before - code - 1) % minimum; \ + ENET_SYMBOL_CREATE(symbol_, value_, update); \ + node->left = symbol_ - node; \ + }) #ifdef ENET_CONTEXT_EXCLUSION typedef struct _ENetExclude { - enet_uint8 value; - enet_uint16 under; + enet_uint8 value; + enet_uint16 under; } ENetExclude; -#define ENET_CONTEXT_DECODE_EXCLUDE(context, total, minimum) \ -{ \ - enet_uint16 under = 0; \ - nextExclude = excludes; \ - ENET_CONTEXT_WALK (context, { \ - under += rangeCoder -> symbols [node -> parent].count + minimum; \ - nextExclude -> value = node -> value; \ - nextExclude -> under = under; \ - nextExclude ++; \ - }); \ - total -= under; \ -} +#define ENET_CONTEXT_DECODE_EXCLUDE(context, total, minimum) \ + { \ + enet_uint16 under = 0; \ + nextExclude = excludes; \ + ENET_CONTEXT_WALK(context, { \ + under += rangeCoder->symbols[node->parent].count + minimum; \ + nextExclude->value = node->value; \ + nextExclude->under = under; \ + nextExclude++; \ + }); \ + total -= under; \ + } -#define ENET_CONTEXT_EXCLUDED(value_, after, before) \ -{ \ - size_t low = 0, high = nextExclude - excludes; \ - for(;;) \ - { \ - size_t mid = (low + high) >> 1; \ - const ENetExclude * exclude = & excludes [mid]; \ - if (value_ < exclude -> value) \ - { \ - if (low + 1 < high) \ - { \ - high = mid; \ - continue; \ - } \ - if (exclude > excludes) \ - after -= exclude [-1].under; \ - } \ - else \ - { \ - if (value_ > exclude -> value) \ - { \ - if (low + 1 < high) \ - { \ - low = mid; \ - continue; \ - } \ - } \ - else \ - before = 0; \ - after -= exclude -> under; \ - } \ - break; \ - } \ -} +#define ENET_CONTEXT_EXCLUDED(value_, after, before) \ + { \ + size_t low = 0, high = nextExclude - excludes; \ + for (;;) \ + { \ + size_t mid = (low + high) >> 1; \ + const ENetExclude *exclude = &excludes[mid]; \ + if (value_ < exclude->value) \ + { \ + if (low + 1 < high) \ + { \ + high = mid; \ + continue; \ + } \ + if (exclude > excludes) \ + after -= exclude[-1].under; \ + } \ + else \ + { \ + if (value_ > exclude->value) \ + { \ + if (low + 1 < high) \ + { \ + low = mid; \ + continue; \ + } \ + } \ + else \ + before = 0; \ + after -= exclude->under; \ + } \ + break; \ + } \ + } #endif #define ENET_CONTEXT_NOT_EXCLUDED(value_, after, before) size_t -enet_range_coder_decompress (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit) +enet_range_coder_decompress(void *context, const enet_uint8 *inData, size_t inLimit, enet_uint8 *outData, size_t outLimit) { - ENetRangeCoder * rangeCoder = (ENetRangeCoder *) context; - enet_uint8 * outStart = outData, * outEnd = & outData [outLimit]; - const enet_uint8 * inEnd = & inData [inLimit]; - enet_uint32 decodeLow = 0, decodeCode = 0, decodeRange = ~0; - ENetSymbol * root; - enet_uint16 predicted = 0; - size_t order = 0, nextSymbol = 0; + ENetRangeCoder *rangeCoder = (ENetRangeCoder *)context; + enet_uint8 *outStart = outData, *outEnd = &outData[outLimit]; + const enet_uint8 *inEnd = &inData[inLimit]; + enet_uint32 decodeLow = 0, decodeCode = 0, decodeRange = ~0; + ENetSymbol *root; + enet_uint16 predicted = 0; + size_t order = 0, nextSymbol = 0; #ifdef ENET_CONTEXT_EXCLUSION - ENetExclude excludes [256]; - ENetExclude * nextExclude = excludes; + ENetExclude excludes[256]; + ENetExclude *nextExclude = excludes; #endif - - if (rangeCoder == NULL || inLimit <= 0) - return 0; - ENET_CONTEXT_CREATE (root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM); + if (rangeCoder == NULL || inLimit <= 0) + return 0; - ENET_RANGE_CODER_SEED; + ENET_CONTEXT_CREATE(root, ENET_CONTEXT_ESCAPE_MINIMUM, ENET_CONTEXT_SYMBOL_MINIMUM); - for (;;) - { - ENetSymbol * subcontext, * symbol, * patch; + ENET_RANGE_CODER_SEED; + + for (;;) + { + ENetSymbol *subcontext, *symbol, *patch; #ifdef ENET_CONTEXT_EXCLUSION - const ENetSymbol * childContext = & emptyContext; + const ENetSymbol *childContext = &emptyContext; #endif - enet_uint8 value = 0; - enet_uint16 code, under, count, bottom, * parent = & predicted, total; + enet_uint8 value = 0; + enet_uint16 code, under, count, bottom, *parent = &predicted, total; - for (subcontext = & rangeCoder -> symbols [predicted]; - subcontext != root; + for (subcontext = &rangeCoder->symbols[predicted]; + subcontext != root; #ifdef ENET_CONTEXT_EXCLUSION - childContext = subcontext, + childContext = subcontext, #endif - subcontext = & rangeCoder -> symbols [subcontext -> parent]) - { - if (subcontext -> escapes <= 0) - continue; - total = subcontext -> total; + subcontext = &rangeCoder->symbols[subcontext->parent]) + { + if (subcontext->escapes <= 0) + continue; + total = subcontext->total; #ifdef ENET_CONTEXT_EXCLUSION - if (childContext -> total > 0) - ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, 0); + if (childContext->total > 0) + ENET_CONTEXT_DECODE_EXCLUDE(childContext, total, 0); #endif - if (subcontext -> escapes >= total) - continue; - code = ENET_RANGE_CODER_READ (total); - if (code < subcontext -> escapes) - { - ENET_RANGE_CODER_DECODE (0, subcontext -> escapes, total); - continue; - } - code -= subcontext -> escapes; + if (subcontext->escapes >= total) + continue; + code = ENET_RANGE_CODER_READ(total); + if (code < subcontext->escapes) + { + ENET_RANGE_CODER_DECODE(0, subcontext->escapes, total); + continue; + } + code -= subcontext->escapes; #ifdef ENET_CONTEXT_EXCLUSION - if (childContext -> total > 0) - { - ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_EXCLUDED); - } - else + if (childContext->total > 0) + { + ENET_CONTEXT_TRY_DECODE(subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_EXCLUDED); + } + else #endif - { - ENET_CONTEXT_TRY_DECODE (subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_NOT_EXCLUDED); - } - bottom = symbol - rangeCoder -> symbols; - ENET_RANGE_CODER_DECODE (subcontext -> escapes + under, count, total); - subcontext -> total += ENET_SUBCONTEXT_SYMBOL_DELTA; - if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext -> total > ENET_RANGE_CODER_BOTTOM - 0x100) - ENET_CONTEXT_RESCALE (subcontext, 0); - goto patchContexts; - } + { + ENET_CONTEXT_TRY_DECODE(subcontext, symbol, code, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0, ENET_CONTEXT_NOT_EXCLUDED); + } + bottom = symbol - rangeCoder->symbols; + ENET_RANGE_CODER_DECODE(subcontext->escapes + under, count, total); + subcontext->total += ENET_SUBCONTEXT_SYMBOL_DELTA; + if (count > 0xFF - 2 * ENET_SUBCONTEXT_SYMBOL_DELTA || subcontext->total > ENET_RANGE_CODER_BOTTOM - 0x100) + ENET_CONTEXT_RESCALE(subcontext, 0); + goto patchContexts; + } - total = root -> total; + total = root->total; #ifdef ENET_CONTEXT_EXCLUSION - if (childContext -> total > 0) - ENET_CONTEXT_DECODE_EXCLUDE (childContext, total, ENET_CONTEXT_SYMBOL_MINIMUM); + if (childContext->total > 0) + ENET_CONTEXT_DECODE_EXCLUDE(childContext, total, ENET_CONTEXT_SYMBOL_MINIMUM); #endif - code = ENET_RANGE_CODER_READ (total); - if (code < root -> escapes) - { - ENET_RANGE_CODER_DECODE (0, root -> escapes, total); - break; - } - code -= root -> escapes; + code = ENET_RANGE_CODER_READ(total); + if (code < root->escapes) + { + ENET_RANGE_CODER_DECODE(0, root->escapes, total); + break; + } + code -= root->escapes; #ifdef ENET_CONTEXT_EXCLUSION - if (childContext -> total > 0) - { - ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_EXCLUDED); - } - else + if (childContext->total > 0) + { + ENET_CONTEXT_ROOT_DECODE(root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_EXCLUDED); + } + else #endif - { - ENET_CONTEXT_ROOT_DECODE (root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_NOT_EXCLUDED); - } - bottom = symbol - rangeCoder -> symbols; - ENET_RANGE_CODER_DECODE (root -> escapes + under, count, total); - root -> total += ENET_CONTEXT_SYMBOL_DELTA; - if (count > 0xFF - 2*ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root -> total > ENET_RANGE_CODER_BOTTOM - 0x100) - ENET_CONTEXT_RESCALE (root, ENET_CONTEXT_SYMBOL_MINIMUM); + { + ENET_CONTEXT_ROOT_DECODE(root, symbol, code, value, under, count, ENET_CONTEXT_SYMBOL_DELTA, ENET_CONTEXT_SYMBOL_MINIMUM, ENET_CONTEXT_NOT_EXCLUDED); + } + bottom = symbol - rangeCoder->symbols; + ENET_RANGE_CODER_DECODE(root->escapes + under, count, total); + root->total += ENET_CONTEXT_SYMBOL_DELTA; + if (count > 0xFF - 2 * ENET_CONTEXT_SYMBOL_DELTA + ENET_CONTEXT_SYMBOL_MINIMUM || root->total > ENET_RANGE_CODER_BOTTOM - 0x100) + ENET_CONTEXT_RESCALE(root, ENET_CONTEXT_SYMBOL_MINIMUM); - patchContexts: - for (patch = & rangeCoder -> symbols [predicted]; - patch != subcontext; - patch = & rangeCoder -> symbols [patch -> parent]) - { - ENET_CONTEXT_ENCODE (patch, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0); - * parent = symbol - rangeCoder -> symbols; - parent = & symbol -> parent; - if (count <= 0) - { - patch -> escapes += ENET_SUBCONTEXT_ESCAPE_DELTA; - patch -> total += ENET_SUBCONTEXT_ESCAPE_DELTA; - } - patch -> total += ENET_SUBCONTEXT_SYMBOL_DELTA; - if (count > 0xFF - 2*ENET_SUBCONTEXT_SYMBOL_DELTA || patch -> total > ENET_RANGE_CODER_BOTTOM - 0x100) - ENET_CONTEXT_RESCALE (patch, 0); - } - * parent = bottom; + patchContexts: + for (patch = &rangeCoder->symbols[predicted]; + patch != subcontext; + patch = &rangeCoder->symbols[patch->parent]) + { + ENET_CONTEXT_ENCODE(patch, symbol, value, under, count, ENET_SUBCONTEXT_SYMBOL_DELTA, 0); + *parent = symbol - rangeCoder->symbols; + parent = &symbol->parent; + if (count <= 0) + { + patch->escapes += ENET_SUBCONTEXT_ESCAPE_DELTA; + patch->total += ENET_SUBCONTEXT_ESCAPE_DELTA; + } + patch->total += ENET_SUBCONTEXT_SYMBOL_DELTA; + if (count > 0xFF - 2 * ENET_SUBCONTEXT_SYMBOL_DELTA || patch->total > ENET_RANGE_CODER_BOTTOM - 0x100) + ENET_CONTEXT_RESCALE(patch, 0); + } + *parent = bottom; - ENET_RANGE_CODER_OUTPUT (value); + ENET_RANGE_CODER_OUTPUT(value); - if (order >= ENET_SUBCONTEXT_ORDER) - predicted = rangeCoder -> symbols [predicted].parent; - else - order ++; - ENET_RANGE_CODER_FREE_SYMBOLS; - } - - return (size_t) (outData - outStart); + if (order >= ENET_SUBCONTEXT_ORDER) + predicted = rangeCoder->symbols[predicted].parent; + else + order++; + ENET_RANGE_CODER_FREE_SYMBOLS; + } + + return (size_t)(outData - outStart); } /** @defgroup host ENet host functions @@ -634,21 +646,18 @@ enet_range_coder_decompress (void * context, const enet_uint8 * inData, size_t i @param host host to enable the range coder for @returns 0 on success, < 0 on failure */ -int -enet_host_compress_with_range_coder (ENetHost * host) +int enet_host_compress_with_range_coder(ENetHost *host) { - ENetCompressor compressor; - memset (& compressor, 0, sizeof (compressor)); - compressor.context = enet_range_coder_create(); - if (compressor.context == NULL) - return -1; - compressor.compress = enet_range_coder_compress; - compressor.decompress = enet_range_coder_decompress; - compressor.destroy = enet_range_coder_destroy; - enet_host_compress (host, & compressor); - return 0; + ENetCompressor compressor; + memset(&compressor, 0, sizeof(compressor)); + compressor.context = enet_range_coder_create(); + if (compressor.context == NULL) + return -1; + compressor.compress = enet_range_coder_compress; + compressor.decompress = enet_range_coder_decompress; + compressor.destroy = enet_range_coder_destroy; + enet_host_compress(host, &compressor); + return 0; } - + /** @} */ - - diff --git a/examples/ThirdPartyLibs/enet/host.c b/examples/ThirdPartyLibs/enet/host.c index d0ee595cf..fa3304f85 100644 --- a/examples/ThirdPartyLibs/enet/host.c +++ b/examples/ThirdPartyLibs/enet/host.c @@ -27,137 +27,135 @@ at any given time. */ ENetHost * -enet_host_create (const ENetAddress * address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth) +enet_host_create(const ENetAddress *address, size_t peerCount, size_t channelLimit, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth) { - ENetHost * host; - ENetPeer * currentPeer; + ENetHost *host; + ENetPeer *currentPeer; - if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID) - return NULL; + if (peerCount > ENET_PROTOCOL_MAXIMUM_PEER_ID) + return NULL; - host = (ENetHost *) enet_malloc (sizeof (ENetHost)); - if (host == NULL) - return NULL; - memset (host, 0, sizeof (ENetHost)); + host = (ENetHost *)enet_malloc(sizeof(ENetHost)); + if (host == NULL) + return NULL; + memset(host, 0, sizeof(ENetHost)); - host -> peers = (ENetPeer *) enet_malloc (peerCount * sizeof (ENetPeer)); - if (host -> peers == NULL) - { - enet_free (host); + host->peers = (ENetPeer *)enet_malloc(peerCount * sizeof(ENetPeer)); + if (host->peers == NULL) + { + enet_free(host); - return NULL; - } - memset (host -> peers, 0, peerCount * sizeof (ENetPeer)); + return NULL; + } + memset(host->peers, 0, peerCount * sizeof(ENetPeer)); - host -> socket = enet_socket_create (ENET_SOCKET_TYPE_DATAGRAM); - if (host -> socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind (host -> socket, address) < 0)) - { - if (host -> socket != ENET_SOCKET_NULL) - enet_socket_destroy (host -> socket); + host->socket = enet_socket_create(ENET_SOCKET_TYPE_DATAGRAM); + if (host->socket == ENET_SOCKET_NULL || (address != NULL && enet_socket_bind(host->socket, address) < 0)) + { + if (host->socket != ENET_SOCKET_NULL) + enet_socket_destroy(host->socket); - enet_free (host -> peers); - enet_free (host); + enet_free(host->peers); + enet_free(host); - return NULL; - } + return NULL; + } - enet_socket_set_option (host -> socket, ENET_SOCKOPT_NONBLOCK, 1); - enet_socket_set_option (host -> socket, ENET_SOCKOPT_BROADCAST, 1); - enet_socket_set_option (host -> socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE); - enet_socket_set_option (host -> socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE); + enet_socket_set_option(host->socket, ENET_SOCKOPT_NONBLOCK, 1); + enet_socket_set_option(host->socket, ENET_SOCKOPT_BROADCAST, 1); + enet_socket_set_option(host->socket, ENET_SOCKOPT_RCVBUF, ENET_HOST_RECEIVE_BUFFER_SIZE); + enet_socket_set_option(host->socket, ENET_SOCKOPT_SNDBUF, ENET_HOST_SEND_BUFFER_SIZE); - if (address != NULL) - host -> address = * address; + if (address != NULL) + host->address = *address; - if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) - channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; - else - if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) - channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; + if (!channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) + channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; + else if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) + channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; - host -> randomSeed = (enet_uint32) (size_t) host; + host->randomSeed = (enet_uint32)(size_t)host; #ifdef WIN32 - host -> randomSeed += (enet_uint32) timeGetTime(); + host->randomSeed += (enet_uint32)timeGetTime(); #else - host -> randomSeed += (enet_uint32) time(NULL); + host->randomSeed += (enet_uint32)time(NULL); #endif - host -> randomSeed = (host -> randomSeed << 16) | (host -> randomSeed >> 16); - host -> channelLimit = channelLimit; - host -> incomingBandwidth = incomingBandwidth; - host -> outgoingBandwidth = outgoingBandwidth; - host -> bandwidthThrottleEpoch = 0; - host -> recalculateBandwidthLimits = 0; - host -> mtu = ENET_HOST_DEFAULT_MTU; - host -> peerCount = peerCount; - host -> commandCount = 0; - host -> bufferCount = 0; - host -> checksum = NULL; - host -> receivedAddress.host = ENET_HOST_ANY; - host -> receivedAddress.port = 0; - host -> receivedData = NULL; - host -> receivedDataLength = 0; - - host -> totalSentData = 0; - host -> totalSentPackets = 0; - host -> totalReceivedData = 0; - host -> totalReceivedPackets = 0; + host->randomSeed = (host->randomSeed << 16) | (host->randomSeed >> 16); + host->channelLimit = channelLimit; + host->incomingBandwidth = incomingBandwidth; + host->outgoingBandwidth = outgoingBandwidth; + host->bandwidthThrottleEpoch = 0; + host->recalculateBandwidthLimits = 0; + host->mtu = ENET_HOST_DEFAULT_MTU; + host->peerCount = peerCount; + host->commandCount = 0; + host->bufferCount = 0; + host->checksum = NULL; + host->receivedAddress.host = ENET_HOST_ANY; + host->receivedAddress.port = 0; + host->receivedData = NULL; + host->receivedDataLength = 0; - host -> compressor.context = NULL; - host -> compressor.compress = NULL; - host -> compressor.decompress = NULL; - host -> compressor.destroy = NULL; + host->totalSentData = 0; + host->totalSentPackets = 0; + host->totalReceivedData = 0; + host->totalReceivedPackets = 0; - host -> intercept = NULL; + host->compressor.context = NULL; + host->compressor.compress = NULL; + host->compressor.decompress = NULL; + host->compressor.destroy = NULL; - enet_list_clear (& host -> dispatchQueue); + host->intercept = NULL; - for (currentPeer = host -> peers; - currentPeer < & host -> peers [host -> peerCount]; - ++ currentPeer) - { - currentPeer -> host = host; - currentPeer -> incomingPeerID = currentPeer - host -> peers; - currentPeer -> outgoingSessionID = currentPeer -> incomingSessionID = 0xFF; - currentPeer -> data = NULL; + enet_list_clear(&host->dispatchQueue); - enet_list_clear (& currentPeer -> acknowledgements); - enet_list_clear (& currentPeer -> sentReliableCommands); - enet_list_clear (& currentPeer -> sentUnreliableCommands); - enet_list_clear (& currentPeer -> outgoingReliableCommands); - enet_list_clear (& currentPeer -> outgoingUnreliableCommands); - enet_list_clear (& currentPeer -> dispatchedCommands); + for (currentPeer = host->peers; + currentPeer < &host->peers[host->peerCount]; + ++currentPeer) + { + currentPeer->host = host; + currentPeer->incomingPeerID = currentPeer - host->peers; + currentPeer->outgoingSessionID = currentPeer->incomingSessionID = 0xFF; + currentPeer->data = NULL; - enet_peer_reset (currentPeer); - } + enet_list_clear(¤tPeer->acknowledgements); + enet_list_clear(¤tPeer->sentReliableCommands); + enet_list_clear(¤tPeer->sentUnreliableCommands); + enet_list_clear(¤tPeer->outgoingReliableCommands); + enet_list_clear(¤tPeer->outgoingUnreliableCommands); + enet_list_clear(¤tPeer->dispatchedCommands); - return host; + enet_peer_reset(currentPeer); + } + + return host; } /** Destroys the host and all resources associated with it. @param host pointer to the host to destroy */ -void -enet_host_destroy (ENetHost * host) +void enet_host_destroy(ENetHost *host) { - ENetPeer * currentPeer; + ENetPeer *currentPeer; - if (host == NULL) - return; + if (host == NULL) + return; - enet_socket_destroy (host -> socket); + enet_socket_destroy(host->socket); - for (currentPeer = host -> peers; - currentPeer < & host -> peers [host -> peerCount]; - ++ currentPeer) - { - enet_peer_reset (currentPeer); - } + for (currentPeer = host->peers; + currentPeer < &host->peers[host->peerCount]; + ++currentPeer) + { + enet_peer_reset(currentPeer); + } - if (host -> compressor.context != NULL && host -> compressor.destroy) - (* host -> compressor.destroy) (host -> compressor.context); + if (host->compressor.context != NULL && host->compressor.destroy) + (*host->compressor.destroy)(host->compressor.context); - enet_free (host -> peers); - enet_free (host); + enet_free(host->peers); + enet_free(host); } /** Initiates a connection to a foreign host. @@ -170,85 +168,83 @@ enet_host_destroy (ENetHost * host) notifies of an ENET_EVENT_TYPE_CONNECT event for the peer. */ ENetPeer * -enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelCount, enet_uint32 data) +enet_host_connect(ENetHost *host, const ENetAddress *address, size_t channelCount, enet_uint32 data) { - ENetPeer * currentPeer; - ENetChannel * channel; - ENetProtocol command; + ENetPeer *currentPeer; + ENetChannel *channel; + ENetProtocol command; - if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) - channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; - else - if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) - channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; + if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) + channelCount = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; + else if (channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) + channelCount = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; - for (currentPeer = host -> peers; - currentPeer < & host -> peers [host -> peerCount]; - ++ currentPeer) - { - if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED) - break; - } + for (currentPeer = host->peers; + currentPeer < &host->peers[host->peerCount]; + ++currentPeer) + { + if (currentPeer->state == ENET_PEER_STATE_DISCONNECTED) + break; + } - if (currentPeer >= & host -> peers [host -> peerCount]) - return NULL; + if (currentPeer >= &host->peers[host->peerCount]) + return NULL; - currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel)); - if (currentPeer -> channels == NULL) - return NULL; - currentPeer -> channelCount = channelCount; - currentPeer -> state = ENET_PEER_STATE_CONNECTING; - currentPeer -> address = * address; - currentPeer -> connectID = ++ host -> randomSeed; + currentPeer->channels = (ENetChannel *)enet_malloc(channelCount * sizeof(ENetChannel)); + if (currentPeer->channels == NULL) + return NULL; + currentPeer->channelCount = channelCount; + currentPeer->state = ENET_PEER_STATE_CONNECTING; + currentPeer->address = *address; + currentPeer->connectID = ++host->randomSeed; - if (host -> outgoingBandwidth == 0) - currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; - else - currentPeer -> windowSize = (host -> outgoingBandwidth / - ENET_PEER_WINDOW_SIZE_SCALE) * - ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + if (host->outgoingBandwidth == 0) + currentPeer->windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + else + currentPeer->windowSize = (host->outgoingBandwidth / + ENET_PEER_WINDOW_SIZE_SCALE) * + ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; - if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) - currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; - else - if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) - currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; - - for (channel = currentPeer -> channels; - channel < & currentPeer -> channels [channelCount]; - ++ channel) - { - channel -> outgoingReliableSequenceNumber = 0; - channel -> outgoingUnreliableSequenceNumber = 0; - channel -> incomingReliableSequenceNumber = 0; - channel -> incomingUnreliableSequenceNumber = 0; + if (currentPeer->windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) + currentPeer->windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + else if (currentPeer->windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) + currentPeer->windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; - enet_list_clear (& channel -> incomingReliableCommands); - enet_list_clear (& channel -> incomingUnreliableCommands); + for (channel = currentPeer->channels; + channel < ¤tPeer->channels[channelCount]; + ++channel) + { + channel->outgoingReliableSequenceNumber = 0; + channel->outgoingUnreliableSequenceNumber = 0; + channel->incomingReliableSequenceNumber = 0; + channel->incomingUnreliableSequenceNumber = 0; - channel -> usedReliableWindows = 0; - memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows)); - } - - command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; - command.header.channelID = 0xFF; - command.connect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID); - command.connect.incomingSessionID = currentPeer -> incomingSessionID; - command.connect.outgoingSessionID = currentPeer -> outgoingSessionID; - command.connect.mtu = ENET_HOST_TO_NET_32 (currentPeer -> mtu); - command.connect.windowSize = ENET_HOST_TO_NET_32 (currentPeer -> windowSize); - command.connect.channelCount = ENET_HOST_TO_NET_32 (channelCount); - command.connect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth); - command.connect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth); - command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval); - command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration); - command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration); - command.connect.connectID = currentPeer -> connectID; - command.connect.data = ENET_HOST_TO_NET_32 (data); - - enet_peer_queue_outgoing_command (currentPeer, & command, NULL, 0, 0); + enet_list_clear(&channel->incomingReliableCommands); + enet_list_clear(&channel->incomingUnreliableCommands); - return currentPeer; + channel->usedReliableWindows = 0; + memset(channel->reliableWindows, 0, sizeof(channel->reliableWindows)); + } + + command.header.command = ENET_PROTOCOL_COMMAND_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; + command.header.channelID = 0xFF; + command.connect.outgoingPeerID = ENET_HOST_TO_NET_16(currentPeer->incomingPeerID); + command.connect.incomingSessionID = currentPeer->incomingSessionID; + command.connect.outgoingSessionID = currentPeer->outgoingSessionID; + command.connect.mtu = ENET_HOST_TO_NET_32(currentPeer->mtu); + command.connect.windowSize = ENET_HOST_TO_NET_32(currentPeer->windowSize); + command.connect.channelCount = ENET_HOST_TO_NET_32(channelCount); + command.connect.incomingBandwidth = ENET_HOST_TO_NET_32(host->incomingBandwidth); + command.connect.outgoingBandwidth = ENET_HOST_TO_NET_32(host->outgoingBandwidth); + command.connect.packetThrottleInterval = ENET_HOST_TO_NET_32(currentPeer->packetThrottleInterval); + command.connect.packetThrottleAcceleration = ENET_HOST_TO_NET_32(currentPeer->packetThrottleAcceleration); + command.connect.packetThrottleDeceleration = ENET_HOST_TO_NET_32(currentPeer->packetThrottleDeceleration); + command.connect.connectID = currentPeer->connectID; + command.connect.data = ENET_HOST_TO_NET_32(data); + + enet_peer_queue_outgoing_command(currentPeer, &command, NULL, 0, 0); + + return currentPeer; } /** Queues a packet to be sent to all peers associated with the host. @@ -256,58 +252,53 @@ enet_host_connect (ENetHost * host, const ENetAddress * address, size_t channelC @param channelID channel on which to broadcast @param packet packet to broadcast */ -void -enet_host_broadcast (ENetHost * host, enet_uint8 channelID, ENetPacket * packet) +void enet_host_broadcast(ENetHost *host, enet_uint8 channelID, ENetPacket *packet) { - ENetPeer * currentPeer; + ENetPeer *currentPeer; - for (currentPeer = host -> peers; - currentPeer < & host -> peers [host -> peerCount]; - ++ currentPeer) - { - if (currentPeer -> state != ENET_PEER_STATE_CONNECTED) - continue; + for (currentPeer = host->peers; + currentPeer < &host->peers[host->peerCount]; + ++currentPeer) + { + if (currentPeer->state != ENET_PEER_STATE_CONNECTED) + continue; - enet_peer_send (currentPeer, channelID, packet); - } + enet_peer_send(currentPeer, channelID, packet); + } - if (packet -> referenceCount == 0) - enet_packet_destroy (packet); + if (packet->referenceCount == 0) + enet_packet_destroy(packet); } /** Sets the packet compressor the host should use to compress and decompress packets. @param host host to enable or disable compression for @param compressor callbacks for for the packet compressor; if NULL, then compression is disabled */ -void -enet_host_compress (ENetHost * host, const ENetCompressor * compressor) +void enet_host_compress(ENetHost *host, const ENetCompressor *compressor) { - if (host -> compressor.context != NULL && host -> compressor.destroy) - (* host -> compressor.destroy) (host -> compressor.context); + if (host->compressor.context != NULL && host->compressor.destroy) + (*host->compressor.destroy)(host->compressor.context); - if (compressor) - host -> compressor = * compressor; - else - host -> compressor.context = NULL; + if (compressor) + host->compressor = *compressor; + else + host->compressor.context = NULL; } /** Limits the maximum allowed channels of future incoming connections. @param host host to limit @param channelLimit the maximum number of channels allowed; if 0, then this is equivalent to ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT */ -void -enet_host_channel_limit (ENetHost * host, size_t channelLimit) +void enet_host_channel_limit(ENetHost *host, size_t channelLimit) { - if (! channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) - channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; - else - if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) - channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; + if (!channelLimit || channelLimit > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) + channelLimit = ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT; + else if (channelLimit < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT) + channelLimit = ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT; - host -> channelLimit = channelLimit; + host->channelLimit = channelLimit; } - /** Adjusts the bandwidth limits of a host. @param host host to adjust @param incomingBandwidth new incoming bandwidth @@ -315,177 +306,175 @@ enet_host_channel_limit (ENetHost * host, size_t channelLimit) @remarks the incoming and outgoing bandwidth parameters are identical in function to those specified in enet_host_create(). */ -void -enet_host_bandwidth_limit (ENetHost * host, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth) +void enet_host_bandwidth_limit(ENetHost *host, enet_uint32 incomingBandwidth, enet_uint32 outgoingBandwidth) { - host -> incomingBandwidth = incomingBandwidth; - host -> outgoingBandwidth = outgoingBandwidth; - host -> recalculateBandwidthLimits = 1; + host->incomingBandwidth = incomingBandwidth; + host->outgoingBandwidth = outgoingBandwidth; + host->recalculateBandwidthLimits = 1; } -void -enet_host_bandwidth_throttle (ENetHost * host) +void enet_host_bandwidth_throttle(ENetHost *host) { - enet_uint32 timeCurrent = enet_time_get (), - elapsedTime = timeCurrent - host -> bandwidthThrottleEpoch, - peersTotal = 0, - dataTotal = 0, - peersRemaining, - bandwidth, - throttle = 0, - bandwidthLimit = 0; - int needsAdjustment; - ENetPeer * peer; - ENetProtocol command; + enet_uint32 timeCurrent = enet_time_get(), + elapsedTime = timeCurrent - host->bandwidthThrottleEpoch, + peersTotal = 0, + dataTotal = 0, + peersRemaining, + bandwidth, + throttle = 0, + bandwidthLimit = 0; + int needsAdjustment; + ENetPeer *peer; + ENetProtocol command; - if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL) - return; + if (elapsedTime < ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL) + return; - for (peer = host -> peers; - peer < & host -> peers [host -> peerCount]; - ++ peer) - { - if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) - continue; + for (peer = host->peers; + peer < &host->peers[host->peerCount]; + ++peer) + { + if (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER) + continue; - ++ peersTotal; - dataTotal += peer -> outgoingDataTotal; - } + ++peersTotal; + dataTotal += peer->outgoingDataTotal; + } - if (peersTotal == 0) - return; + if (peersTotal == 0) + return; - peersRemaining = peersTotal; - needsAdjustment = 1; + peersRemaining = peersTotal; + needsAdjustment = 1; - if (host -> outgoingBandwidth == 0) - bandwidth = ~0; - else - bandwidth = (host -> outgoingBandwidth * elapsedTime) / 1000; + if (host->outgoingBandwidth == 0) + bandwidth = ~0; + else + bandwidth = (host->outgoingBandwidth * elapsedTime) / 1000; - while (peersRemaining > 0 && needsAdjustment != 0) - { - needsAdjustment = 0; - - if (dataTotal < bandwidth) - throttle = ENET_PEER_PACKET_THROTTLE_SCALE; - else - throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal; + while (peersRemaining > 0 && needsAdjustment != 0) + { + needsAdjustment = 0; - for (peer = host -> peers; - peer < & host -> peers [host -> peerCount]; - ++ peer) - { - enet_uint32 peerBandwidth; - - if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) || - peer -> incomingBandwidth == 0 || - peer -> outgoingBandwidthThrottleEpoch == timeCurrent) - continue; + if (dataTotal < bandwidth) + throttle = ENET_PEER_PACKET_THROTTLE_SCALE; + else + throttle = (bandwidth * ENET_PEER_PACKET_THROTTLE_SCALE) / dataTotal; - peerBandwidth = (peer -> incomingBandwidth * elapsedTime) / 1000; - if ((throttle * peer -> outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth) - continue; + for (peer = host->peers; + peer < &host->peers[host->peerCount]; + ++peer) + { + enet_uint32 peerBandwidth; - peer -> packetThrottleLimit = (peerBandwidth * - ENET_PEER_PACKET_THROTTLE_SCALE) / peer -> outgoingDataTotal; - - if (peer -> packetThrottleLimit == 0) - peer -> packetThrottleLimit = 1; - - if (peer -> packetThrottle > peer -> packetThrottleLimit) - peer -> packetThrottle = peer -> packetThrottleLimit; + if ((peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER) || + peer->incomingBandwidth == 0 || + peer->outgoingBandwidthThrottleEpoch == timeCurrent) + continue; - peer -> outgoingBandwidthThrottleEpoch = timeCurrent; + peerBandwidth = (peer->incomingBandwidth * elapsedTime) / 1000; + if ((throttle * peer->outgoingDataTotal) / ENET_PEER_PACKET_THROTTLE_SCALE <= peerBandwidth) + continue; - - needsAdjustment = 1; - -- peersRemaining; - bandwidth -= peerBandwidth; - dataTotal -= peerBandwidth; - } - } + peer->packetThrottleLimit = (peerBandwidth * + ENET_PEER_PACKET_THROTTLE_SCALE) / + peer->outgoingDataTotal; - if (peersRemaining > 0) - for (peer = host -> peers; - peer < & host -> peers [host -> peerCount]; - ++ peer) - { - if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) || - peer -> outgoingBandwidthThrottleEpoch == timeCurrent) - continue; + if (peer->packetThrottleLimit == 0) + peer->packetThrottleLimit = 1; - peer -> packetThrottleLimit = throttle; + if (peer->packetThrottle > peer->packetThrottleLimit) + peer->packetThrottle = peer->packetThrottleLimit; - if (peer -> packetThrottle > peer -> packetThrottleLimit) - peer -> packetThrottle = peer -> packetThrottleLimit; - } - - if (host -> recalculateBandwidthLimits) - { - host -> recalculateBandwidthLimits = 0; + peer->outgoingBandwidthThrottleEpoch = timeCurrent; - peersRemaining = peersTotal; - bandwidth = host -> incomingBandwidth; - needsAdjustment = 1; + needsAdjustment = 1; + --peersRemaining; + bandwidth -= peerBandwidth; + dataTotal -= peerBandwidth; + } + } - if (bandwidth == 0) - bandwidthLimit = 0; - else - while (peersRemaining > 0 && needsAdjustment != 0) - { - needsAdjustment = 0; - bandwidthLimit = bandwidth / peersRemaining; + if (peersRemaining > 0) + for (peer = host->peers; + peer < &host->peers[host->peerCount]; + ++peer) + { + if ((peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER) || + peer->outgoingBandwidthThrottleEpoch == timeCurrent) + continue; - for (peer = host -> peers; - peer < & host -> peers [host -> peerCount]; - ++ peer) - { - if ((peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) || - peer -> incomingBandwidthThrottleEpoch == timeCurrent) - continue; + peer->packetThrottleLimit = throttle; - if (peer -> outgoingBandwidth > 0 && - peer -> outgoingBandwidth >= bandwidthLimit) - continue; + if (peer->packetThrottle > peer->packetThrottleLimit) + peer->packetThrottle = peer->packetThrottleLimit; + } - peer -> incomingBandwidthThrottleEpoch = timeCurrent; - - needsAdjustment = 1; - -- peersRemaining; - bandwidth -= peer -> outgoingBandwidth; - } - } + if (host->recalculateBandwidthLimits) + { + host->recalculateBandwidthLimits = 0; - for (peer = host -> peers; - peer < & host -> peers [host -> peerCount]; - ++ peer) - { - if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) - continue; + peersRemaining = peersTotal; + bandwidth = host->incomingBandwidth; + needsAdjustment = 1; - command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; - command.header.channelID = 0xFF; - command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth); + if (bandwidth == 0) + bandwidthLimit = 0; + else + while (peersRemaining > 0 && needsAdjustment != 0) + { + needsAdjustment = 0; + bandwidthLimit = bandwidth / peersRemaining; - if (peer -> incomingBandwidthThrottleEpoch == timeCurrent) - command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (peer -> outgoingBandwidth); - else - command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32 (bandwidthLimit); + for (peer = host->peers; + peer < &host->peers[host->peerCount]; + ++peer) + { + if ((peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER) || + peer->incomingBandwidthThrottleEpoch == timeCurrent) + continue; - enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); - } - } + if (peer->outgoingBandwidth > 0 && + peer->outgoingBandwidth >= bandwidthLimit) + continue; - host -> bandwidthThrottleEpoch = timeCurrent; + peer->incomingBandwidthThrottleEpoch = timeCurrent; - for (peer = host -> peers; - peer < & host -> peers [host -> peerCount]; - ++ peer) - { - peer -> incomingDataTotal = 0; - peer -> outgoingDataTotal = 0; - } + needsAdjustment = 1; + --peersRemaining; + bandwidth -= peer->outgoingBandwidth; + } + } + + for (peer = host->peers; + peer < &host->peers[host->peerCount]; + ++peer) + { + if (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER) + continue; + + command.header.command = ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; + command.header.channelID = 0xFF; + command.bandwidthLimit.outgoingBandwidth = ENET_HOST_TO_NET_32(host->outgoingBandwidth); + + if (peer->incomingBandwidthThrottleEpoch == timeCurrent) + command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32(peer->outgoingBandwidth); + else + command.bandwidthLimit.incomingBandwidth = ENET_HOST_TO_NET_32(bandwidthLimit); + + enet_peer_queue_outgoing_command(peer, &command, NULL, 0, 0); + } + } + + host->bandwidthThrottleEpoch = timeCurrent; + + for (peer = host->peers; + peer < &host->peers[host->peerCount]; + ++peer) + { + peer->incomingDataTotal = 0; + peer->outgoingDataTotal = 0; + } } - + /** @} */ diff --git a/examples/ThirdPartyLibs/enet/include/enet/callbacks.h b/examples/ThirdPartyLibs/enet/include/enet/callbacks.h index 340a4a989..46a0f4f48 100644 --- a/examples/ThirdPartyLibs/enet/include/enet/callbacks.h +++ b/examples/ThirdPartyLibs/enet/include/enet/callbacks.h @@ -9,19 +9,18 @@ typedef struct _ENetCallbacks { - void * (ENET_CALLBACK * malloc) (size_t size); - void (ENET_CALLBACK * free) (void * memory); - void (ENET_CALLBACK * no_memory) (void); + void *(ENET_CALLBACK *malloc)(size_t size); + void(ENET_CALLBACK *free)(void *memory); + void(ENET_CALLBACK *no_memory)(void); } ENetCallbacks; /** @defgroup callbacks ENet internal callbacks @{ @ingroup private */ -extern void * enet_malloc (size_t); -extern void enet_free (void *); +extern void *enet_malloc(size_t); +extern void enet_free(void *); /** @} */ #endif /* __ENET_CALLBACKS_H__ */ - diff --git a/examples/ThirdPartyLibs/enet/include/enet/enet.h b/examples/ThirdPartyLibs/enet/include/enet/enet.h index 5f9d5403c..1d27227e4 100644 --- a/examples/ThirdPartyLibs/enet/include/enet/enet.h +++ b/examples/ThirdPartyLibs/enet/include/enet/enet.h @@ -26,55 +26,55 @@ extern "C" #define ENET_VERSION_MAJOR 1 #define ENET_VERSION_MINOR 3 #define ENET_VERSION_PATCH 7 -#define ENET_VERSION_CREATE(major, minor, patch) (((major)<<16) | ((minor)<<8) | (patch)) +#define ENET_VERSION_CREATE(major, minor, patch) (((major) << 16) | ((minor) << 8) | (patch)) #define ENET_VERSION ENET_VERSION_CREATE(ENET_VERSION_MAJOR, ENET_VERSION_MINOR, ENET_VERSION_PATCH) -typedef enet_uint32 ENetVersion; + typedef enet_uint32 ENetVersion; -struct _ENetHost; -struct _ENetEvent; -struct _ENetPacket; + struct _ENetHost; + struct _ENetEvent; + struct _ENetPacket; -typedef enum _ENetSocketType -{ - ENET_SOCKET_TYPE_STREAM = 1, - ENET_SOCKET_TYPE_DATAGRAM = 2 -} ENetSocketType; + typedef enum _ENetSocketType + { + ENET_SOCKET_TYPE_STREAM = 1, + ENET_SOCKET_TYPE_DATAGRAM = 2 + } ENetSocketType; -typedef enum _ENetSocketWait -{ - ENET_SOCKET_WAIT_NONE = 0, - ENET_SOCKET_WAIT_SEND = (1 << 0), - ENET_SOCKET_WAIT_RECEIVE = (1 << 1) -} ENetSocketWait; + typedef enum _ENetSocketWait + { + ENET_SOCKET_WAIT_NONE = 0, + ENET_SOCKET_WAIT_SEND = (1 << 0), + ENET_SOCKET_WAIT_RECEIVE = (1 << 1) + } ENetSocketWait; -typedef enum _ENetSocketOption -{ - ENET_SOCKOPT_NONBLOCK = 1, - ENET_SOCKOPT_BROADCAST = 2, - ENET_SOCKOPT_RCVBUF = 3, - ENET_SOCKOPT_SNDBUF = 4, - ENET_SOCKOPT_REUSEADDR = 5, - ENET_SOCKOPT_RCVTIMEO = 6, - ENET_SOCKOPT_SNDTIMEO = 7 -} ENetSocketOption; + typedef enum _ENetSocketOption + { + ENET_SOCKOPT_NONBLOCK = 1, + ENET_SOCKOPT_BROADCAST = 2, + ENET_SOCKOPT_RCVBUF = 3, + ENET_SOCKOPT_SNDBUF = 4, + ENET_SOCKOPT_REUSEADDR = 5, + ENET_SOCKOPT_RCVTIMEO = 6, + ENET_SOCKOPT_SNDTIMEO = 7 + } ENetSocketOption; -typedef enum _ENetSocketShutdown -{ - ENET_SOCKET_SHUTDOWN_READ = 0, - ENET_SOCKET_SHUTDOWN_WRITE = 1, - ENET_SOCKET_SHUTDOWN_READ_WRITE = 2 -} ENetSocketShutdown; + typedef enum _ENetSocketShutdown + { + ENET_SOCKET_SHUTDOWN_READ = 0, + ENET_SOCKET_SHUTDOWN_WRITE = 1, + ENET_SOCKET_SHUTDOWN_READ_WRITE = 2 + } ENetSocketShutdown; -enum -{ - ENET_HOST_ANY = 0, /**< specifies the default server host */ - ENET_HOST_BROADCAST = 0xFFFFFFFF, /**< specifies a subnet-wide broadcast */ + enum + { + ENET_HOST_ANY = 0, /**< specifies the default server host */ + ENET_HOST_BROADCAST = 0xFFFFFFFF, /**< specifies a subnet-wide broadcast */ - ENET_PORT_ANY = 0 /**< specifies that a port should be automatically chosen */ -}; + ENET_PORT_ANY = 0 /**< specifies that a port should be automatically chosen */ + }; -/** + /** * Portable internet address structure. * * The host must be specified in network byte-order, and the port must be in host @@ -84,13 +84,13 @@ enum * but not for enet_host_create. Once a server responds to a broadcast, the * address is updated from ENET_HOST_BROADCAST to the server's actual IP address. */ -typedef struct _ENetAddress -{ - enet_uint32 host; - enet_uint16 port; -} ENetAddress; + typedef struct _ENetAddress + { + enet_uint32 host; + enet_uint16 port; + } ENetAddress; -/** + /** * Packet flag bit constants. * * The host must be specified in network byte-order, and the port must be in @@ -99,28 +99,28 @@ typedef struct _ENetAddress @sa ENetPacket */ -typedef enum _ENetPacketFlag -{ - /** packet must be received by the target peer and resend attempts should be + typedef enum _ENetPacketFlag + { + /** packet must be received by the target peer and resend attempts should be * made until the packet is delivered */ - ENET_PACKET_FLAG_RELIABLE = (1 << 0), - /** packet will not be sequenced with other packets + ENET_PACKET_FLAG_RELIABLE = (1 << 0), + /** packet will not be sequenced with other packets * not supported for reliable packets */ - ENET_PACKET_FLAG_UNSEQUENCED = (1 << 1), - /** packet will not allocate data, and user must supply it instead */ - ENET_PACKET_FLAG_NO_ALLOCATE = (1 << 2), - /** packet will be fragmented using unreliable (instead of reliable) sends + ENET_PACKET_FLAG_UNSEQUENCED = (1 << 1), + /** packet will not allocate data, and user must supply it instead */ + ENET_PACKET_FLAG_NO_ALLOCATE = (1 << 2), + /** packet will be fragmented using unreliable (instead of reliable) sends * if it exceeds the MTU */ - ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT = (1 << 3), + ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT = (1 << 3), - /** whether the packet has been sent from all queues it has been entered into */ - ENET_PACKET_FLAG_SENT = (1<<8) -} ENetPacketFlag; + /** whether the packet has been sent from all queues it has been entered into */ + ENET_PACKET_FLAG_SENT = (1 << 8) + } ENetPacketFlag; -typedef void (ENET_CALLBACK * ENetPacketFreeCallback) (struct _ENetPacket *); + typedef void(ENET_CALLBACK *ENetPacketFreeCallback)(struct _ENetPacket *); -/** + /** * ENet packet structure. * * An ENet data packet that may be sent to or received from a peer. The shown @@ -139,198 +139,198 @@ typedef void (ENET_CALLBACK * ENetPacketFreeCallback) (struct _ENetPacket *); @sa ENetPacketFlag */ -typedef struct _ENetPacket -{ - size_t referenceCount; /**< internal use only */ - enet_uint32 flags; /**< bitwise-or of ENetPacketFlag constants */ - enet_uint8 * data; /**< allocated data for packet */ - size_t dataLength; /**< length of data */ - ENetPacketFreeCallback freeCallback; /**< function to be called when the packet is no longer in use */ - void * userData; /**< application private data, may be freely modified */ -} ENetPacket; + typedef struct _ENetPacket + { + size_t referenceCount; /**< internal use only */ + enet_uint32 flags; /**< bitwise-or of ENetPacketFlag constants */ + enet_uint8 *data; /**< allocated data for packet */ + size_t dataLength; /**< length of data */ + ENetPacketFreeCallback freeCallback; /**< function to be called when the packet is no longer in use */ + void *userData; /**< application private data, may be freely modified */ + } ENetPacket; -typedef struct _ENetAcknowledgement -{ - ENetListNode acknowledgementList; - enet_uint32 sentTime; - ENetProtocol command; -} ENetAcknowledgement; + typedef struct _ENetAcknowledgement + { + ENetListNode acknowledgementList; + enet_uint32 sentTime; + ENetProtocol command; + } ENetAcknowledgement; -typedef struct _ENetOutgoingCommand -{ - ENetListNode outgoingCommandList; - enet_uint16 reliableSequenceNumber; - enet_uint16 unreliableSequenceNumber; - enet_uint32 sentTime; - enet_uint32 roundTripTimeout; - enet_uint32 roundTripTimeoutLimit; - enet_uint32 fragmentOffset; - enet_uint16 fragmentLength; - enet_uint16 sendAttempts; - ENetProtocol command; - ENetPacket * packet; -} ENetOutgoingCommand; + typedef struct _ENetOutgoingCommand + { + ENetListNode outgoingCommandList; + enet_uint16 reliableSequenceNumber; + enet_uint16 unreliableSequenceNumber; + enet_uint32 sentTime; + enet_uint32 roundTripTimeout; + enet_uint32 roundTripTimeoutLimit; + enet_uint32 fragmentOffset; + enet_uint16 fragmentLength; + enet_uint16 sendAttempts; + ENetProtocol command; + ENetPacket *packet; + } ENetOutgoingCommand; -typedef struct _ENetIncomingCommand -{ - ENetListNode incomingCommandList; - enet_uint16 reliableSequenceNumber; - enet_uint16 unreliableSequenceNumber; - ENetProtocol command; - enet_uint32 fragmentCount; - enet_uint32 fragmentsRemaining; - enet_uint32 * fragments; - ENetPacket * packet; -} ENetIncomingCommand; + typedef struct _ENetIncomingCommand + { + ENetListNode incomingCommandList; + enet_uint16 reliableSequenceNumber; + enet_uint16 unreliableSequenceNumber; + ENetProtocol command; + enet_uint32 fragmentCount; + enet_uint32 fragmentsRemaining; + enet_uint32 *fragments; + ENetPacket *packet; + } ENetIncomingCommand; -typedef enum _ENetPeerState -{ - ENET_PEER_STATE_DISCONNECTED = 0, - ENET_PEER_STATE_CONNECTING = 1, - ENET_PEER_STATE_ACKNOWLEDGING_CONNECT = 2, - ENET_PEER_STATE_CONNECTION_PENDING = 3, - ENET_PEER_STATE_CONNECTION_SUCCEEDED = 4, - ENET_PEER_STATE_CONNECTED = 5, - ENET_PEER_STATE_DISCONNECT_LATER = 6, - ENET_PEER_STATE_DISCONNECTING = 7, - ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT = 8, - ENET_PEER_STATE_ZOMBIE = 9 -} ENetPeerState; + typedef enum _ENetPeerState + { + ENET_PEER_STATE_DISCONNECTED = 0, + ENET_PEER_STATE_CONNECTING = 1, + ENET_PEER_STATE_ACKNOWLEDGING_CONNECT = 2, + ENET_PEER_STATE_CONNECTION_PENDING = 3, + ENET_PEER_STATE_CONNECTION_SUCCEEDED = 4, + ENET_PEER_STATE_CONNECTED = 5, + ENET_PEER_STATE_DISCONNECT_LATER = 6, + ENET_PEER_STATE_DISCONNECTING = 7, + ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT = 8, + ENET_PEER_STATE_ZOMBIE = 9 + } ENetPeerState; #ifndef ENET_BUFFER_MAXIMUM #define ENET_BUFFER_MAXIMUM (1 + 2 * ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS) #endif -enum -{ - ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024, - ENET_HOST_SEND_BUFFER_SIZE = 256 * 1024, - ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL = 1000, - ENET_HOST_DEFAULT_MTU = 1400, + enum + { + ENET_HOST_RECEIVE_BUFFER_SIZE = 256 * 1024, + ENET_HOST_SEND_BUFFER_SIZE = 256 * 1024, + ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL = 1000, + ENET_HOST_DEFAULT_MTU = 1400, - ENET_PEER_DEFAULT_ROUND_TRIP_TIME = 500, - ENET_PEER_DEFAULT_PACKET_THROTTLE = 32, - ENET_PEER_PACKET_THROTTLE_SCALE = 32, - ENET_PEER_PACKET_THROTTLE_COUNTER = 7, - ENET_PEER_PACKET_THROTTLE_ACCELERATION = 2, - ENET_PEER_PACKET_THROTTLE_DECELERATION = 2, - ENET_PEER_PACKET_THROTTLE_INTERVAL = 5000, - ENET_PEER_PACKET_LOSS_SCALE = (1 << 16), - ENET_PEER_PACKET_LOSS_INTERVAL = 10000, - ENET_PEER_WINDOW_SIZE_SCALE = 64 * 1024, - ENET_PEER_TIMEOUT_LIMIT = 32, - ENET_PEER_TIMEOUT_MINIMUM = 5000, - ENET_PEER_TIMEOUT_MAXIMUM = 30000, - ENET_PEER_PING_INTERVAL = 500, - ENET_PEER_UNSEQUENCED_WINDOWS = 64, - ENET_PEER_UNSEQUENCED_WINDOW_SIZE = 1024, - ENET_PEER_FREE_UNSEQUENCED_WINDOWS = 32, - ENET_PEER_RELIABLE_WINDOWS = 16, - ENET_PEER_RELIABLE_WINDOW_SIZE = 0x1000, - ENET_PEER_FREE_RELIABLE_WINDOWS = 8 -}; + ENET_PEER_DEFAULT_ROUND_TRIP_TIME = 500, + ENET_PEER_DEFAULT_PACKET_THROTTLE = 32, + ENET_PEER_PACKET_THROTTLE_SCALE = 32, + ENET_PEER_PACKET_THROTTLE_COUNTER = 7, + ENET_PEER_PACKET_THROTTLE_ACCELERATION = 2, + ENET_PEER_PACKET_THROTTLE_DECELERATION = 2, + ENET_PEER_PACKET_THROTTLE_INTERVAL = 5000, + ENET_PEER_PACKET_LOSS_SCALE = (1 << 16), + ENET_PEER_PACKET_LOSS_INTERVAL = 10000, + ENET_PEER_WINDOW_SIZE_SCALE = 64 * 1024, + ENET_PEER_TIMEOUT_LIMIT = 32, + ENET_PEER_TIMEOUT_MINIMUM = 5000, + ENET_PEER_TIMEOUT_MAXIMUM = 30000, + ENET_PEER_PING_INTERVAL = 500, + ENET_PEER_UNSEQUENCED_WINDOWS = 64, + ENET_PEER_UNSEQUENCED_WINDOW_SIZE = 1024, + ENET_PEER_FREE_UNSEQUENCED_WINDOWS = 32, + ENET_PEER_RELIABLE_WINDOWS = 16, + ENET_PEER_RELIABLE_WINDOW_SIZE = 0x1000, + ENET_PEER_FREE_RELIABLE_WINDOWS = 8 + }; -typedef struct _ENetChannel -{ - enet_uint16 outgoingReliableSequenceNumber; - enet_uint16 outgoingUnreliableSequenceNumber; - enet_uint16 usedReliableWindows; - enet_uint16 reliableWindows [ENET_PEER_RELIABLE_WINDOWS]; - enet_uint16 incomingReliableSequenceNumber; - enet_uint16 incomingUnreliableSequenceNumber; - ENetList incomingReliableCommands; - ENetList incomingUnreliableCommands; -} ENetChannel; + typedef struct _ENetChannel + { + enet_uint16 outgoingReliableSequenceNumber; + enet_uint16 outgoingUnreliableSequenceNumber; + enet_uint16 usedReliableWindows; + enet_uint16 reliableWindows[ENET_PEER_RELIABLE_WINDOWS]; + enet_uint16 incomingReliableSequenceNumber; + enet_uint16 incomingUnreliableSequenceNumber; + ENetList incomingReliableCommands; + ENetList incomingUnreliableCommands; + } ENetChannel; -/** + /** * An ENet peer which data packets may be sent or received from. * * No fields should be modified unless otherwise specified. */ -typedef struct _ENetPeer -{ - ENetListNode dispatchList; - struct _ENetHost * host; - enet_uint16 outgoingPeerID; - enet_uint16 incomingPeerID; - enet_uint32 connectID; - enet_uint8 outgoingSessionID; - enet_uint8 incomingSessionID; - ENetAddress address; /**< Internet address of the peer */ - void * data; /**< Application private data, may be freely modified */ - ENetPeerState state; - ENetChannel * channels; - size_t channelCount; /**< Number of channels allocated for communication with peer */ - enet_uint32 incomingBandwidth; /**< Downstream bandwidth of the client in bytes/second */ - enet_uint32 outgoingBandwidth; /**< Upstream bandwidth of the client in bytes/second */ - enet_uint32 incomingBandwidthThrottleEpoch; - enet_uint32 outgoingBandwidthThrottleEpoch; - enet_uint32 incomingDataTotal; - enet_uint32 outgoingDataTotal; - enet_uint32 lastSendTime; - enet_uint32 lastReceiveTime; - enet_uint32 nextTimeout; - enet_uint32 earliestTimeout; - enet_uint32 packetLossEpoch; - enet_uint32 packetsSent; - enet_uint32 packetsLost; - enet_uint32 packetLoss; /**< mean packet loss of reliable packets as a ratio with respect to the constant ENET_PEER_PACKET_LOSS_SCALE */ - enet_uint32 packetLossVariance; - enet_uint32 packetThrottle; - enet_uint32 packetThrottleLimit; - enet_uint32 packetThrottleCounter; - enet_uint32 packetThrottleEpoch; - enet_uint32 packetThrottleAcceleration; - enet_uint32 packetThrottleDeceleration; - enet_uint32 packetThrottleInterval; - enet_uint32 pingInterval; - enet_uint32 timeoutLimit; - enet_uint32 timeoutMinimum; - enet_uint32 timeoutMaximum; - enet_uint32 lastRoundTripTime; - enet_uint32 lowestRoundTripTime; - enet_uint32 lastRoundTripTimeVariance; - enet_uint32 highestRoundTripTimeVariance; - enet_uint32 roundTripTime; /**< mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgement */ - enet_uint32 roundTripTimeVariance; - enet_uint32 mtu; - enet_uint32 windowSize; - enet_uint32 reliableDataInTransit; - enet_uint16 outgoingReliableSequenceNumber; - ENetList acknowledgements; - ENetList sentReliableCommands; - ENetList sentUnreliableCommands; - ENetList outgoingReliableCommands; - ENetList outgoingUnreliableCommands; - ENetList dispatchedCommands; - int needsDispatch; - enet_uint16 incomingUnsequencedGroup; - enet_uint16 outgoingUnsequencedGroup; - enet_uint32 unsequencedWindow [ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32]; - enet_uint32 eventData; -} ENetPeer; + typedef struct _ENetPeer + { + ENetListNode dispatchList; + struct _ENetHost *host; + enet_uint16 outgoingPeerID; + enet_uint16 incomingPeerID; + enet_uint32 connectID; + enet_uint8 outgoingSessionID; + enet_uint8 incomingSessionID; + ENetAddress address; /**< Internet address of the peer */ + void *data; /**< Application private data, may be freely modified */ + ENetPeerState state; + ENetChannel *channels; + size_t channelCount; /**< Number of channels allocated for communication with peer */ + enet_uint32 incomingBandwidth; /**< Downstream bandwidth of the client in bytes/second */ + enet_uint32 outgoingBandwidth; /**< Upstream bandwidth of the client in bytes/second */ + enet_uint32 incomingBandwidthThrottleEpoch; + enet_uint32 outgoingBandwidthThrottleEpoch; + enet_uint32 incomingDataTotal; + enet_uint32 outgoingDataTotal; + enet_uint32 lastSendTime; + enet_uint32 lastReceiveTime; + enet_uint32 nextTimeout; + enet_uint32 earliestTimeout; + enet_uint32 packetLossEpoch; + enet_uint32 packetsSent; + enet_uint32 packetsLost; + enet_uint32 packetLoss; /**< mean packet loss of reliable packets as a ratio with respect to the constant ENET_PEER_PACKET_LOSS_SCALE */ + enet_uint32 packetLossVariance; + enet_uint32 packetThrottle; + enet_uint32 packetThrottleLimit; + enet_uint32 packetThrottleCounter; + enet_uint32 packetThrottleEpoch; + enet_uint32 packetThrottleAcceleration; + enet_uint32 packetThrottleDeceleration; + enet_uint32 packetThrottleInterval; + enet_uint32 pingInterval; + enet_uint32 timeoutLimit; + enet_uint32 timeoutMinimum; + enet_uint32 timeoutMaximum; + enet_uint32 lastRoundTripTime; + enet_uint32 lowestRoundTripTime; + enet_uint32 lastRoundTripTimeVariance; + enet_uint32 highestRoundTripTimeVariance; + enet_uint32 roundTripTime; /**< mean round trip time (RTT), in milliseconds, between sending a reliable packet and receiving its acknowledgement */ + enet_uint32 roundTripTimeVariance; + enet_uint32 mtu; + enet_uint32 windowSize; + enet_uint32 reliableDataInTransit; + enet_uint16 outgoingReliableSequenceNumber; + ENetList acknowledgements; + ENetList sentReliableCommands; + ENetList sentUnreliableCommands; + ENetList outgoingReliableCommands; + ENetList outgoingUnreliableCommands; + ENetList dispatchedCommands; + int needsDispatch; + enet_uint16 incomingUnsequencedGroup; + enet_uint16 outgoingUnsequencedGroup; + enet_uint32 unsequencedWindow[ENET_PEER_UNSEQUENCED_WINDOW_SIZE / 32]; + enet_uint32 eventData; + } ENetPeer; -/** An ENet packet compressor for compressing UDP packets before socket sends or receives. + /** An ENet packet compressor for compressing UDP packets before socket sends or receives. */ -typedef struct _ENetCompressor -{ - /** Context data for the compressor. Must be non-NULL. */ - void * context; - /** Compresses from inBuffers[0:inBufferCount-1], containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */ - size_t (ENET_CALLBACK * compress) (void * context, const ENetBuffer * inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 * outData, size_t outLimit); - /** Decompresses from inData, containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */ - size_t (ENET_CALLBACK * decompress) (void * context, const enet_uint8 * inData, size_t inLimit, enet_uint8 * outData, size_t outLimit); - /** Destroys the context when compression is disabled or the host is destroyed. May be NULL. */ - void (ENET_CALLBACK * destroy) (void * context); -} ENetCompressor; + typedef struct _ENetCompressor + { + /** Context data for the compressor. Must be non-NULL. */ + void *context; + /** Compresses from inBuffers[0:inBufferCount-1], containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */ + size_t(ENET_CALLBACK *compress)(void *context, const ENetBuffer *inBuffers, size_t inBufferCount, size_t inLimit, enet_uint8 *outData, size_t outLimit); + /** Decompresses from inData, containing inLimit bytes, to outData, outputting at most outLimit bytes. Should return 0 on failure. */ + size_t(ENET_CALLBACK *decompress)(void *context, const enet_uint8 *inData, size_t inLimit, enet_uint8 *outData, size_t outLimit); + /** Destroys the context when compression is disabled or the host is destroyed. May be NULL. */ + void(ENET_CALLBACK *destroy)(void *context); + } ENetCompressor; -/** Callback that computes the checksum of the data held in buffers[0:bufferCount-1] */ -typedef enet_uint32 (ENET_CALLBACK * ENetChecksumCallback) (const ENetBuffer * buffers, size_t bufferCount); + /** Callback that computes the checksum of the data held in buffers[0:bufferCount-1] */ + typedef enet_uint32(ENET_CALLBACK *ENetChecksumCallback)(const ENetBuffer *buffers, size_t bufferCount); -/** Callback for intercepting received raw UDP packets. Should return 1 to intercept, 0 to ignore, or -1 to propagate an error. */ -typedef int (ENET_CALLBACK * ENetInterceptCallback) (struct _ENetHost * host, struct _ENetEvent * event); - -/** An ENet host for communicating with peers. + /** Callback for intercepting received raw UDP packets. Should return 1 to intercept, 0 to ignore, or -1 to propagate an error. */ + typedef int(ENET_CALLBACK *ENetInterceptCallback)(struct _ENetHost *host, struct _ENetEvent *event); + + /** An ENet host for communicating with peers. * * No fields should be modified unless otherwise stated. @@ -346,148 +346,148 @@ typedef int (ENET_CALLBACK * ENetInterceptCallback) (struct _ENetHost * host, st @sa enet_host_bandwidth_limit() @sa enet_host_bandwidth_throttle() */ -typedef struct _ENetHost -{ - ENetSocket socket; - ENetAddress address; /**< Internet address of the host */ - enet_uint32 incomingBandwidth; /**< downstream bandwidth of the host */ - enet_uint32 outgoingBandwidth; /**< upstream bandwidth of the host */ - enet_uint32 bandwidthThrottleEpoch; - enet_uint32 mtu; - enet_uint32 randomSeed; - int recalculateBandwidthLimits; - ENetPeer * peers; /**< array of peers allocated for this host */ - size_t peerCount; /**< number of peers allocated for this host */ - size_t channelLimit; /**< maximum number of channels allowed for connected peers */ - enet_uint32 serviceTime; - ENetList dispatchQueue; - int continueSending; - size_t packetSize; - enet_uint16 headerFlags; - ENetProtocol commands [ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS]; - size_t commandCount; - ENetBuffer buffers [ENET_BUFFER_MAXIMUM]; - size_t bufferCount; - ENetChecksumCallback checksum; /**< callback the user can set to enable packet checksums for this host */ - ENetCompressor compressor; - enet_uint8 packetData [2][ENET_PROTOCOL_MAXIMUM_MTU]; - ENetAddress receivedAddress; - enet_uint8 * receivedData; - size_t receivedDataLength; - enet_uint32 totalSentData; /**< total data sent, user should reset to 0 as needed to prevent overflow */ - enet_uint32 totalSentPackets; /**< total UDP packets sent, user should reset to 0 as needed to prevent overflow */ - enet_uint32 totalReceivedData; /**< total data received, user should reset to 0 as needed to prevent overflow */ - enet_uint32 totalReceivedPackets; /**< total UDP packets received, user should reset to 0 as needed to prevent overflow */ - ENetInterceptCallback intercept; /**< callback the user can set to intercept received raw UDP packets */ -} ENetHost; + typedef struct _ENetHost + { + ENetSocket socket; + ENetAddress address; /**< Internet address of the host */ + enet_uint32 incomingBandwidth; /**< downstream bandwidth of the host */ + enet_uint32 outgoingBandwidth; /**< upstream bandwidth of the host */ + enet_uint32 bandwidthThrottleEpoch; + enet_uint32 mtu; + enet_uint32 randomSeed; + int recalculateBandwidthLimits; + ENetPeer *peers; /**< array of peers allocated for this host */ + size_t peerCount; /**< number of peers allocated for this host */ + size_t channelLimit; /**< maximum number of channels allowed for connected peers */ + enet_uint32 serviceTime; + ENetList dispatchQueue; + int continueSending; + size_t packetSize; + enet_uint16 headerFlags; + ENetProtocol commands[ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS]; + size_t commandCount; + ENetBuffer buffers[ENET_BUFFER_MAXIMUM]; + size_t bufferCount; + ENetChecksumCallback checksum; /**< callback the user can set to enable packet checksums for this host */ + ENetCompressor compressor; + enet_uint8 packetData[2][ENET_PROTOCOL_MAXIMUM_MTU]; + ENetAddress receivedAddress; + enet_uint8 *receivedData; + size_t receivedDataLength; + enet_uint32 totalSentData; /**< total data sent, user should reset to 0 as needed to prevent overflow */ + enet_uint32 totalSentPackets; /**< total UDP packets sent, user should reset to 0 as needed to prevent overflow */ + enet_uint32 totalReceivedData; /**< total data received, user should reset to 0 as needed to prevent overflow */ + enet_uint32 totalReceivedPackets; /**< total UDP packets received, user should reset to 0 as needed to prevent overflow */ + ENetInterceptCallback intercept; /**< callback the user can set to intercept received raw UDP packets */ + } ENetHost; -/** + /** * An ENet event type, as specified in @ref ENetEvent. */ -typedef enum _ENetEventType -{ - /** no event occurred within the specified time limit */ - ENET_EVENT_TYPE_NONE = 0, + typedef enum _ENetEventType + { + /** no event occurred within the specified time limit */ + ENET_EVENT_TYPE_NONE = 0, - /** a connection request initiated by enet_host_connect has completed. + /** a connection request initiated by enet_host_connect has completed. * The peer field contains the peer which successfully connected. */ - ENET_EVENT_TYPE_CONNECT = 1, + ENET_EVENT_TYPE_CONNECT = 1, - /** a peer has disconnected. This event is generated on a successful + /** a peer has disconnected. This event is generated on a successful * completion of a disconnect initiated by enet_pper_disconnect, if * a peer has timed out, or if a connection request intialized by * enet_host_connect has timed out. The peer field contains the peer * which disconnected. The data field contains user supplied data * describing the disconnection, or 0, if none is available. */ - ENET_EVENT_TYPE_DISCONNECT = 2, + ENET_EVENT_TYPE_DISCONNECT = 2, - /** a packet has been received from a peer. The peer field specifies the + /** a packet has been received from a peer. The peer field specifies the * peer which sent the packet. The channelID field specifies the channel * number upon which the packet was received. The packet field contains * the packet that was received; this packet must be destroyed with * enet_packet_destroy after use. */ - ENET_EVENT_TYPE_RECEIVE = 3 -} ENetEventType; + ENET_EVENT_TYPE_RECEIVE = 3 + } ENetEventType; -/** + /** * An ENet event as returned by enet_host_service(). @sa enet_host_service */ -typedef struct _ENetEvent -{ - ENetEventType type; /**< type of the event */ - ENetPeer * peer; /**< peer that generated a connect, disconnect or receive event */ - enet_uint8 channelID; /**< channel on the peer that generated the event, if appropriate */ - enet_uint32 data; /**< data associated with the event, if appropriate */ - ENetPacket * packet; /**< packet associated with the event, if appropriate */ -} ENetEvent; + typedef struct _ENetEvent + { + ENetEventType type; /**< type of the event */ + ENetPeer *peer; /**< peer that generated a connect, disconnect or receive event */ + enet_uint8 channelID; /**< channel on the peer that generated the event, if appropriate */ + enet_uint32 data; /**< data associated with the event, if appropriate */ + ENetPacket *packet; /**< packet associated with the event, if appropriate */ + } ENetEvent; -/** @defgroup global ENet global functions + /** @defgroup global ENet global functions @{ */ -/** + /** Initializes ENet globally. Must be called prior to using any functions in ENet. @returns 0 on success, < 0 on failure */ -ENET_API int enet_initialize (void); + ENET_API int enet_initialize(void); -/** + /** Initializes ENet globally and supplies user-overridden callbacks. Must be called prior to using any functions in ENet. Do not use enet_initialize() if you use this variant. Make sure the ENetCallbacks structure is zeroed out so that any additional callbacks added in future versions will be properly ignored. @param version the constant ENET_VERSION should be supplied so ENet knows which version of ENetCallbacks struct to use @param inits user-overriden callbacks where any NULL callbacks will use ENet's defaults @returns 0 on success, < 0 on failure */ -ENET_API int enet_initialize_with_callbacks (ENetVersion version, const ENetCallbacks * inits); + ENET_API int enet_initialize_with_callbacks(ENetVersion version, const ENetCallbacks *inits); -/** + /** Shuts down ENet globally. Should be called when a program that has initialized ENet exits. */ -ENET_API void enet_deinitialize (void); + ENET_API void enet_deinitialize(void); -/** @} */ + /** @} */ -/** @defgroup private ENet private implementation functions */ + /** @defgroup private ENet private implementation functions */ -/** + /** Returns the wall-time in milliseconds. Its initial value is unspecified unless otherwise set. */ -ENET_API enet_uint32 enet_time_get (void); -/** + ENET_API enet_uint32 enet_time_get(void); + /** Sets the current wall-time in milliseconds. */ -ENET_API void enet_time_set (enet_uint32); + ENET_API void enet_time_set(enet_uint32); -/** @defgroup socket ENet socket functions + /** @defgroup socket ENet socket functions @{ */ -ENET_API ENetSocket enet_socket_create (ENetSocketType); -ENET_API int enet_socket_bind (ENetSocket, const ENetAddress *); -ENET_API int enet_socket_listen (ENetSocket, int); -ENET_API ENetSocket enet_socket_accept (ENetSocket, ENetAddress *); -ENET_API int enet_socket_connect (ENetSocket, const ENetAddress *); -ENET_API int enet_socket_send (ENetSocket, const ENetAddress *, const ENetBuffer *, size_t); -ENET_API int enet_socket_receive (ENetSocket, ENetAddress *, ENetBuffer *, size_t); -ENET_API int enet_socket_wait (ENetSocket, enet_uint32 *, enet_uint32); -ENET_API int enet_socket_set_option (ENetSocket, ENetSocketOption, int); -ENET_API int enet_socket_shutdown (ENetSocket, ENetSocketShutdown); -ENET_API void enet_socket_destroy (ENetSocket); -ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32); + ENET_API ENetSocket enet_socket_create(ENetSocketType); + ENET_API int enet_socket_bind(ENetSocket, const ENetAddress *); + ENET_API int enet_socket_listen(ENetSocket, int); + ENET_API ENetSocket enet_socket_accept(ENetSocket, ENetAddress *); + ENET_API int enet_socket_connect(ENetSocket, const ENetAddress *); + ENET_API int enet_socket_send(ENetSocket, const ENetAddress *, const ENetBuffer *, size_t); + ENET_API int enet_socket_receive(ENetSocket, ENetAddress *, ENetBuffer *, size_t); + ENET_API int enet_socket_wait(ENetSocket, enet_uint32 *, enet_uint32); + ENET_API int enet_socket_set_option(ENetSocket, ENetSocketOption, int); + ENET_API int enet_socket_shutdown(ENetSocket, ENetSocketShutdown); + ENET_API void enet_socket_destroy(ENetSocket); + ENET_API int enet_socketset_select(ENetSocket, ENetSocketSet *, ENetSocketSet *, enet_uint32); -/** @} */ + /** @} */ -/** @defgroup Address ENet address functions + /** @defgroup Address ENet address functions @{ */ -/** Attempts to resolve the host named by the parameter hostName and sets + /** Attempts to resolve the host named by the parameter hostName and sets the host field in the address parameter if successful. @param address destination to store resolved address @param hostName host name to lookup @@ -495,9 +495,9 @@ ENET_API int enet_socketset_select (ENetSocket, ENetSocketSet *, ENetSock @retval < 0 on failure @returns the address of the given hostName in address on success */ -ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName); + ENET_API int enet_address_set_host(ENetAddress *address, const char *hostName); -/** Gives the printable form of the ip address specified in the address parameter. + /** Gives the printable form of the ip address specified in the address parameter. @param address address printed @param hostName destination for name, must not be NULL @param nameLength maximum length of hostName. @@ -505,9 +505,9 @@ ENET_API int enet_address_set_host (ENetAddress * address, const char * hostName @retval 0 on success @retval < 0 on failure */ -ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostName, size_t nameLength); + ENET_API int enet_address_get_host_ip(const ENetAddress *address, char *hostName, size_t nameLength); -/** Attempts to do a reverse lookup of the host field in the address parameter. + /** Attempts to do a reverse lookup of the host field in the address parameter. @param address address used for reverse lookup @param hostName destination for name, must not be NULL @param nameLength maximum length of hostName. @@ -515,57 +515,56 @@ ENET_API int enet_address_get_host_ip (const ENetAddress * address, char * hostN @retval 0 on success @retval < 0 on failure */ -ENET_API int enet_address_get_host (const ENetAddress * address, char * hostName, size_t nameLength); + ENET_API int enet_address_get_host(const ENetAddress *address, char *hostName, size_t nameLength); -/** @} */ + /** @} */ -ENET_API ENetPacket * enet_packet_create (const void *, size_t, enet_uint32); -ENET_API void enet_packet_destroy (ENetPacket *); -ENET_API int enet_packet_resize (ENetPacket *, size_t); -ENET_API enet_uint32 enet_crc32 (const ENetBuffer *, size_t); - -ENET_API ENetHost * enet_host_create (const ENetAddress *, size_t, size_t, enet_uint32, enet_uint32); -ENET_API void enet_host_destroy (ENetHost *); -ENET_API ENetPeer * enet_host_connect (ENetHost *, const ENetAddress *, size_t, enet_uint32); -ENET_API int enet_host_check_events (ENetHost *, ENetEvent *); -ENET_API int enet_host_service (ENetHost *, ENetEvent *, enet_uint32); -ENET_API void enet_host_flush (ENetHost *); -ENET_API void enet_host_broadcast (ENetHost *, enet_uint8, ENetPacket *); -ENET_API void enet_host_compress (ENetHost *, const ENetCompressor *); -ENET_API int enet_host_compress_with_range_coder (ENetHost * host); -ENET_API void enet_host_channel_limit (ENetHost *, size_t); -ENET_API void enet_host_bandwidth_limit (ENetHost *, enet_uint32, enet_uint32); -extern void enet_host_bandwidth_throttle (ENetHost *); + ENET_API ENetPacket *enet_packet_create(const void *, size_t, enet_uint32); + ENET_API void enet_packet_destroy(ENetPacket *); + ENET_API int enet_packet_resize(ENetPacket *, size_t); + ENET_API enet_uint32 enet_crc32(const ENetBuffer *, size_t); -ENET_API int enet_peer_send (ENetPeer *, enet_uint8, ENetPacket *); -ENET_API ENetPacket * enet_peer_receive (ENetPeer *, enet_uint8 * channelID); -ENET_API void enet_peer_ping (ENetPeer *); -ENET_API void enet_peer_ping_interval (ENetPeer *, enet_uint32); -ENET_API void enet_peer_timeout (ENetPeer *, enet_uint32, enet_uint32, enet_uint32); -ENET_API void enet_peer_reset (ENetPeer *); -ENET_API void enet_peer_disconnect (ENetPeer *, enet_uint32); -ENET_API void enet_peer_disconnect_now (ENetPeer *, enet_uint32); -ENET_API void enet_peer_disconnect_later (ENetPeer *, enet_uint32); -ENET_API void enet_peer_throttle_configure (ENetPeer *, enet_uint32, enet_uint32, enet_uint32); -extern int enet_peer_throttle (ENetPeer *, enet_uint32); -extern void enet_peer_reset_queues (ENetPeer *); -extern void enet_peer_setup_outgoing_command (ENetPeer *, ENetOutgoingCommand *); -extern ENetOutgoingCommand * enet_peer_queue_outgoing_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16); -extern ENetIncomingCommand * enet_peer_queue_incoming_command (ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32); -extern ENetAcknowledgement * enet_peer_queue_acknowledgement (ENetPeer *, const ENetProtocol *, enet_uint16); -extern void enet_peer_dispatch_incoming_unreliable_commands (ENetPeer *, ENetChannel *); -extern void enet_peer_dispatch_incoming_reliable_commands (ENetPeer *, ENetChannel *); + ENET_API ENetHost *enet_host_create(const ENetAddress *, size_t, size_t, enet_uint32, enet_uint32); + ENET_API void enet_host_destroy(ENetHost *); + ENET_API ENetPeer *enet_host_connect(ENetHost *, const ENetAddress *, size_t, enet_uint32); + ENET_API int enet_host_check_events(ENetHost *, ENetEvent *); + ENET_API int enet_host_service(ENetHost *, ENetEvent *, enet_uint32); + ENET_API void enet_host_flush(ENetHost *); + ENET_API void enet_host_broadcast(ENetHost *, enet_uint8, ENetPacket *); + ENET_API void enet_host_compress(ENetHost *, const ENetCompressor *); + ENET_API int enet_host_compress_with_range_coder(ENetHost *host); + ENET_API void enet_host_channel_limit(ENetHost *, size_t); + ENET_API void enet_host_bandwidth_limit(ENetHost *, enet_uint32, enet_uint32); + extern void enet_host_bandwidth_throttle(ENetHost *); -ENET_API void * enet_range_coder_create (void); -ENET_API void enet_range_coder_destroy (void *); -ENET_API size_t enet_range_coder_compress (void *, const ENetBuffer *, size_t, size_t, enet_uint8 *, size_t); -ENET_API size_t enet_range_coder_decompress (void *, const enet_uint8 *, size_t, enet_uint8 *, size_t); - -extern size_t enet_protocol_command_size (enet_uint8); + ENET_API int enet_peer_send(ENetPeer *, enet_uint8, ENetPacket *); + ENET_API ENetPacket *enet_peer_receive(ENetPeer *, enet_uint8 *channelID); + ENET_API void enet_peer_ping(ENetPeer *); + ENET_API void enet_peer_ping_interval(ENetPeer *, enet_uint32); + ENET_API void enet_peer_timeout(ENetPeer *, enet_uint32, enet_uint32, enet_uint32); + ENET_API void enet_peer_reset(ENetPeer *); + ENET_API void enet_peer_disconnect(ENetPeer *, enet_uint32); + ENET_API void enet_peer_disconnect_now(ENetPeer *, enet_uint32); + ENET_API void enet_peer_disconnect_later(ENetPeer *, enet_uint32); + ENET_API void enet_peer_throttle_configure(ENetPeer *, enet_uint32, enet_uint32, enet_uint32); + extern int enet_peer_throttle(ENetPeer *, enet_uint32); + extern void enet_peer_reset_queues(ENetPeer *); + extern void enet_peer_setup_outgoing_command(ENetPeer *, ENetOutgoingCommand *); + extern ENetOutgoingCommand *enet_peer_queue_outgoing_command(ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32, enet_uint16); + extern ENetIncomingCommand *enet_peer_queue_incoming_command(ENetPeer *, const ENetProtocol *, ENetPacket *, enet_uint32); + extern ENetAcknowledgement *enet_peer_queue_acknowledgement(ENetPeer *, const ENetProtocol *, enet_uint16); + extern void enet_peer_dispatch_incoming_unreliable_commands(ENetPeer *, ENetChannel *); + extern void enet_peer_dispatch_incoming_reliable_commands(ENetPeer *, ENetChannel *); + + ENET_API void *enet_range_coder_create(void); + ENET_API void enet_range_coder_destroy(void *); + ENET_API size_t enet_range_coder_compress(void *, const ENetBuffer *, size_t, size_t, enet_uint8 *, size_t); + ENET_API size_t enet_range_coder_decompress(void *, const enet_uint8 *, size_t, enet_uint8 *, size_t); + + extern size_t enet_protocol_command_size(enet_uint8); #ifdef __cplusplus } #endif #endif /* __ENET_ENET_H__ */ - diff --git a/examples/ThirdPartyLibs/enet/include/enet/list.h b/examples/ThirdPartyLibs/enet/include/enet/list.h index d7b260084..ec1b39660 100644 --- a/examples/ThirdPartyLibs/enet/include/enet/list.h +++ b/examples/ThirdPartyLibs/enet/include/enet/list.h @@ -9,35 +9,34 @@ typedef struct _ENetListNode { - struct _ENetListNode * next; - struct _ENetListNode * previous; + struct _ENetListNode *next; + struct _ENetListNode *previous; } ENetListNode; -typedef ENetListNode * ENetListIterator; +typedef ENetListNode *ENetListIterator; typedef struct _ENetList { - ENetListNode sentinel; + ENetListNode sentinel; } ENetList; -extern void enet_list_clear (ENetList *); +extern void enet_list_clear(ENetList *); -extern ENetListIterator enet_list_insert (ENetListIterator, void *); -extern void * enet_list_remove (ENetListIterator); -extern ENetListIterator enet_list_move (ENetListIterator, void *, void *); +extern ENetListIterator enet_list_insert(ENetListIterator, void *); +extern void *enet_list_remove(ENetListIterator); +extern ENetListIterator enet_list_move(ENetListIterator, void *, void *); -extern size_t enet_list_size (ENetList *); +extern size_t enet_list_size(ENetList *); -#define enet_list_begin(list) ((list) -> sentinel.next) -#define enet_list_end(list) (& (list) -> sentinel) +#define enet_list_begin(list) ((list)->sentinel.next) +#define enet_list_end(list) (&(list)->sentinel) -#define enet_list_empty(list) (enet_list_begin (list) == enet_list_end (list)) +#define enet_list_empty(list) (enet_list_begin(list) == enet_list_end(list)) -#define enet_list_next(iterator) ((iterator) -> next) -#define enet_list_previous(iterator) ((iterator) -> previous) +#define enet_list_next(iterator) ((iterator)->next) +#define enet_list_previous(iterator) ((iterator)->previous) -#define enet_list_front(list) ((void *) (list) -> sentinel.next) -#define enet_list_back(list) ((void *) (list) -> sentinel.previous) +#define enet_list_front(list) ((void *)(list)->sentinel.next) +#define enet_list_back(list) ((void *)(list)->sentinel.previous) #endif /* __ENET_LIST_H__ */ - diff --git a/examples/ThirdPartyLibs/enet/include/enet/protocol.h b/examples/ThirdPartyLibs/enet/include/enet/protocol.h index f8a27d8e1..ba71419d5 100644 --- a/examples/ThirdPartyLibs/enet/include/enet/protocol.h +++ b/examples/ThirdPartyLibs/enet/include/enet/protocol.h @@ -9,186 +9,185 @@ enum { - ENET_PROTOCOL_MINIMUM_MTU = 576, - ENET_PROTOCOL_MAXIMUM_MTU = 4096, - ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32, - ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096, - ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 32768, - ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT = 1, - ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255, - ENET_PROTOCOL_MAXIMUM_PEER_ID = 0xFFF, - ENET_PROTOCOL_MAXIMUM_PACKET_SIZE = 1024 * 1024 * 1024, - ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT = 1024 * 1024 + ENET_PROTOCOL_MINIMUM_MTU = 576, + ENET_PROTOCOL_MAXIMUM_MTU = 4096, + ENET_PROTOCOL_MAXIMUM_PACKET_COMMANDS = 32, + ENET_PROTOCOL_MINIMUM_WINDOW_SIZE = 4096, + ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE = 32768, + ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT = 1, + ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT = 255, + ENET_PROTOCOL_MAXIMUM_PEER_ID = 0xFFF, + ENET_PROTOCOL_MAXIMUM_PACKET_SIZE = 1024 * 1024 * 1024, + ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT = 1024 * 1024 }; typedef enum _ENetProtocolCommand { - ENET_PROTOCOL_COMMAND_NONE = 0, - ENET_PROTOCOL_COMMAND_ACKNOWLEDGE = 1, - ENET_PROTOCOL_COMMAND_CONNECT = 2, - ENET_PROTOCOL_COMMAND_VERIFY_CONNECT = 3, - ENET_PROTOCOL_COMMAND_DISCONNECT = 4, - ENET_PROTOCOL_COMMAND_PING = 5, - ENET_PROTOCOL_COMMAND_SEND_RELIABLE = 6, - ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE = 7, - ENET_PROTOCOL_COMMAND_SEND_FRAGMENT = 8, - ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 9, - ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 10, - ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11, - ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT = 12, - ENET_PROTOCOL_COMMAND_COUNT = 13, + ENET_PROTOCOL_COMMAND_NONE = 0, + ENET_PROTOCOL_COMMAND_ACKNOWLEDGE = 1, + ENET_PROTOCOL_COMMAND_CONNECT = 2, + ENET_PROTOCOL_COMMAND_VERIFY_CONNECT = 3, + ENET_PROTOCOL_COMMAND_DISCONNECT = 4, + ENET_PROTOCOL_COMMAND_PING = 5, + ENET_PROTOCOL_COMMAND_SEND_RELIABLE = 6, + ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE = 7, + ENET_PROTOCOL_COMMAND_SEND_FRAGMENT = 8, + ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED = 9, + ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT = 10, + ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE = 11, + ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT = 12, + ENET_PROTOCOL_COMMAND_COUNT = 13, - ENET_PROTOCOL_COMMAND_MASK = 0x0F + ENET_PROTOCOL_COMMAND_MASK = 0x0F } ENetProtocolCommand; typedef enum _ENetProtocolFlag { - ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 << 7), - ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 << 6), + ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE = (1 << 7), + ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED = (1 << 6), - ENET_PROTOCOL_HEADER_FLAG_COMPRESSED = (1 << 14), - ENET_PROTOCOL_HEADER_FLAG_SENT_TIME = (1 << 15), - ENET_PROTOCOL_HEADER_FLAG_MASK = ENET_PROTOCOL_HEADER_FLAG_COMPRESSED | ENET_PROTOCOL_HEADER_FLAG_SENT_TIME, + ENET_PROTOCOL_HEADER_FLAG_COMPRESSED = (1 << 14), + ENET_PROTOCOL_HEADER_FLAG_SENT_TIME = (1 << 15), + ENET_PROTOCOL_HEADER_FLAG_MASK = ENET_PROTOCOL_HEADER_FLAG_COMPRESSED | ENET_PROTOCOL_HEADER_FLAG_SENT_TIME, - ENET_PROTOCOL_HEADER_SESSION_MASK = (3 << 12), - ENET_PROTOCOL_HEADER_SESSION_SHIFT = 12 + ENET_PROTOCOL_HEADER_SESSION_MASK = (3 << 12), + ENET_PROTOCOL_HEADER_SESSION_SHIFT = 12 } ENetProtocolFlag; #ifdef _MSC_VER_ #pragma pack(push, 1) #define ENET_PACKED #elif defined(__GNUC__) -#define ENET_PACKED __attribute__ ((packed)) +#define ENET_PACKED __attribute__((packed)) #else #define ENET_PACKED #endif typedef struct _ENetProtocolHeader { - enet_uint16 peerID; - enet_uint16 sentTime; + enet_uint16 peerID; + enet_uint16 sentTime; } ENET_PACKED ENetProtocolHeader; typedef struct _ENetProtocolCommandHeader { - enet_uint8 command; - enet_uint8 channelID; - enet_uint16 reliableSequenceNumber; + enet_uint8 command; + enet_uint8 channelID; + enet_uint16 reliableSequenceNumber; } ENET_PACKED ENetProtocolCommandHeader; typedef struct _ENetProtocolAcknowledge { - ENetProtocolCommandHeader header; - enet_uint16 receivedReliableSequenceNumber; - enet_uint16 receivedSentTime; + ENetProtocolCommandHeader header; + enet_uint16 receivedReliableSequenceNumber; + enet_uint16 receivedSentTime; } ENET_PACKED ENetProtocolAcknowledge; typedef struct _ENetProtocolConnect { - ENetProtocolCommandHeader header; - enet_uint16 outgoingPeerID; - enet_uint8 incomingSessionID; - enet_uint8 outgoingSessionID; - enet_uint32 mtu; - enet_uint32 windowSize; - enet_uint32 channelCount; - enet_uint32 incomingBandwidth; - enet_uint32 outgoingBandwidth; - enet_uint32 packetThrottleInterval; - enet_uint32 packetThrottleAcceleration; - enet_uint32 packetThrottleDeceleration; - enet_uint32 connectID; - enet_uint32 data; + ENetProtocolCommandHeader header; + enet_uint16 outgoingPeerID; + enet_uint8 incomingSessionID; + enet_uint8 outgoingSessionID; + enet_uint32 mtu; + enet_uint32 windowSize; + enet_uint32 channelCount; + enet_uint32 incomingBandwidth; + enet_uint32 outgoingBandwidth; + enet_uint32 packetThrottleInterval; + enet_uint32 packetThrottleAcceleration; + enet_uint32 packetThrottleDeceleration; + enet_uint32 connectID; + enet_uint32 data; } ENET_PACKED ENetProtocolConnect; typedef struct _ENetProtocolVerifyConnect { - ENetProtocolCommandHeader header; - enet_uint16 outgoingPeerID; - enet_uint8 incomingSessionID; - enet_uint8 outgoingSessionID; - enet_uint32 mtu; - enet_uint32 windowSize; - enet_uint32 channelCount; - enet_uint32 incomingBandwidth; - enet_uint32 outgoingBandwidth; - enet_uint32 packetThrottleInterval; - enet_uint32 packetThrottleAcceleration; - enet_uint32 packetThrottleDeceleration; - enet_uint32 connectID; + ENetProtocolCommandHeader header; + enet_uint16 outgoingPeerID; + enet_uint8 incomingSessionID; + enet_uint8 outgoingSessionID; + enet_uint32 mtu; + enet_uint32 windowSize; + enet_uint32 channelCount; + enet_uint32 incomingBandwidth; + enet_uint32 outgoingBandwidth; + enet_uint32 packetThrottleInterval; + enet_uint32 packetThrottleAcceleration; + enet_uint32 packetThrottleDeceleration; + enet_uint32 connectID; } ENET_PACKED ENetProtocolVerifyConnect; typedef struct _ENetProtocolBandwidthLimit { - ENetProtocolCommandHeader header; - enet_uint32 incomingBandwidth; - enet_uint32 outgoingBandwidth; + ENetProtocolCommandHeader header; + enet_uint32 incomingBandwidth; + enet_uint32 outgoingBandwidth; } ENET_PACKED ENetProtocolBandwidthLimit; typedef struct _ENetProtocolThrottleConfigure { - ENetProtocolCommandHeader header; - enet_uint32 packetThrottleInterval; - enet_uint32 packetThrottleAcceleration; - enet_uint32 packetThrottleDeceleration; + ENetProtocolCommandHeader header; + enet_uint32 packetThrottleInterval; + enet_uint32 packetThrottleAcceleration; + enet_uint32 packetThrottleDeceleration; } ENET_PACKED ENetProtocolThrottleConfigure; typedef struct _ENetProtocolDisconnect { - ENetProtocolCommandHeader header; - enet_uint32 data; + ENetProtocolCommandHeader header; + enet_uint32 data; } ENET_PACKED ENetProtocolDisconnect; typedef struct _ENetProtocolPing { - ENetProtocolCommandHeader header; + ENetProtocolCommandHeader header; } ENET_PACKED ENetProtocolPing; typedef struct _ENetProtocolSendReliable { - ENetProtocolCommandHeader header; - enet_uint16 dataLength; + ENetProtocolCommandHeader header; + enet_uint16 dataLength; } ENET_PACKED ENetProtocolSendReliable; typedef struct _ENetProtocolSendUnreliable { - ENetProtocolCommandHeader header; - enet_uint16 unreliableSequenceNumber; - enet_uint16 dataLength; + ENetProtocolCommandHeader header; + enet_uint16 unreliableSequenceNumber; + enet_uint16 dataLength; } ENET_PACKED ENetProtocolSendUnreliable; typedef struct _ENetProtocolSendUnsequenced { - ENetProtocolCommandHeader header; - enet_uint16 unsequencedGroup; - enet_uint16 dataLength; + ENetProtocolCommandHeader header; + enet_uint16 unsequencedGroup; + enet_uint16 dataLength; } ENET_PACKED ENetProtocolSendUnsequenced; typedef struct _ENetProtocolSendFragment { - ENetProtocolCommandHeader header; - enet_uint16 startSequenceNumber; - enet_uint16 dataLength; - enet_uint32 fragmentCount; - enet_uint32 fragmentNumber; - enet_uint32 totalLength; - enet_uint32 fragmentOffset; + ENetProtocolCommandHeader header; + enet_uint16 startSequenceNumber; + enet_uint16 dataLength; + enet_uint32 fragmentCount; + enet_uint32 fragmentNumber; + enet_uint32 totalLength; + enet_uint32 fragmentOffset; } ENET_PACKED ENetProtocolSendFragment; -typedef union _ENetProtocol -{ - ENetProtocolCommandHeader header; - ENetProtocolAcknowledge acknowledge; - ENetProtocolConnect connect; - ENetProtocolVerifyConnect verifyConnect; - ENetProtocolDisconnect disconnect; - ENetProtocolPing ping; - ENetProtocolSendReliable sendReliable; - ENetProtocolSendUnreliable sendUnreliable; - ENetProtocolSendUnsequenced sendUnsequenced; - ENetProtocolSendFragment sendFragment; - ENetProtocolBandwidthLimit bandwidthLimit; - ENetProtocolThrottleConfigure throttleConfigure; +typedef union _ENetProtocol { + ENetProtocolCommandHeader header; + ENetProtocolAcknowledge acknowledge; + ENetProtocolConnect connect; + ENetProtocolVerifyConnect verifyConnect; + ENetProtocolDisconnect disconnect; + ENetProtocolPing ping; + ENetProtocolSendReliable sendReliable; + ENetProtocolSendUnreliable sendUnreliable; + ENetProtocolSendUnsequenced sendUnsequenced; + ENetProtocolSendFragment sendFragment; + ENetProtocolBandwidthLimit bandwidthLimit; + ENetProtocolThrottleConfigure throttleConfigure; } ENET_PACKED ENetProtocol; #ifdef _MSC_VER_ @@ -196,4 +195,3 @@ typedef union _ENetProtocol #endif #endif /* __ENET_PROTOCOL_H__ */ - diff --git a/examples/ThirdPartyLibs/enet/include/enet/time.h b/examples/ThirdPartyLibs/enet/include/enet/time.h index c82a54603..3297e4930 100644 --- a/examples/ThirdPartyLibs/enet/include/enet/time.h +++ b/examples/ThirdPartyLibs/enet/include/enet/time.h @@ -9,10 +9,9 @@ #define ENET_TIME_LESS(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW) #define ENET_TIME_GREATER(a, b) ((b) - (a) >= ENET_TIME_OVERFLOW) -#define ENET_TIME_LESS_EQUAL(a, b) (! ENET_TIME_GREATER (a, b)) -#define ENET_TIME_GREATER_EQUAL(a, b) (! ENET_TIME_LESS (a, b)) +#define ENET_TIME_LESS_EQUAL(a, b) (!ENET_TIME_GREATER(a, b)) +#define ENET_TIME_GREATER_EQUAL(a, b) (!ENET_TIME_LESS(a, b)) #define ENET_TIME_DIFFERENCE(a, b) ((a) - (b) >= ENET_TIME_OVERFLOW ? (b) - (a) : (a) - (b)) #endif /* __ENET_TIME_H__ */ - diff --git a/examples/ThirdPartyLibs/enet/include/enet/types.h b/examples/ThirdPartyLibs/enet/include/enet/types.h index ab010a4b1..1337ef3ac 100644 --- a/examples/ThirdPartyLibs/enet/include/enet/types.h +++ b/examples/ThirdPartyLibs/enet/include/enet/types.h @@ -5,9 +5,8 @@ #ifndef __ENET_TYPES_H__ #define __ENET_TYPES_H__ -typedef unsigned char enet_uint8; /**< unsigned 8-bit type */ -typedef unsigned short enet_uint16; /**< unsigned 16-bit type */ -typedef unsigned int enet_uint32; /**< unsigned 32-bit type */ +typedef unsigned char enet_uint8; /**< unsigned 8-bit type */ +typedef unsigned short enet_uint16; /**< unsigned 16-bit type */ +typedef unsigned int enet_uint32; /**< unsigned 32-bit type */ #endif /* __ENET_TYPES_H__ */ - diff --git a/examples/ThirdPartyLibs/enet/include/enet/unix.h b/examples/ThirdPartyLibs/enet/include/enet/unix.h index 087015e51..a63dc70af 100644 --- a/examples/ThirdPartyLibs/enet/include/enet/unix.h +++ b/examples/ThirdPartyLibs/enet/include/enet/unix.h @@ -15,19 +15,19 @@ typedef int ENetSocket; enum { - ENET_SOCKET_NULL = -1 + ENET_SOCKET_NULL = -1 }; -#define ENET_HOST_TO_NET_16(value) (htons (value)) /**< macro that converts host to net byte-order of a 16-bit value */ -#define ENET_HOST_TO_NET_32(value) (htonl (value)) /**< macro that converts host to net byte-order of a 32-bit value */ +#define ENET_HOST_TO_NET_16(value) (htons(value)) /**< macro that converts host to net byte-order of a 16-bit value */ +#define ENET_HOST_TO_NET_32(value) (htonl(value)) /**< macro that converts host to net byte-order of a 32-bit value */ -#define ENET_NET_TO_HOST_16(value) (ntohs (value)) /**< macro that converts net to host byte-order of a 16-bit value */ -#define ENET_NET_TO_HOST_32(value) (ntohl (value)) /**< macro that converts net to host byte-order of a 32-bit value */ +#define ENET_NET_TO_HOST_16(value) (ntohs(value)) /**< macro that converts net to host byte-order of a 16-bit value */ +#define ENET_NET_TO_HOST_32(value) (ntohl(value)) /**< macro that converts net to host byte-order of a 32-bit value */ typedef struct { - void * data; - size_t dataLength; + void* data; + size_t dataLength; } ENetBuffer; #define ENET_CALLBACK @@ -36,10 +36,9 @@ typedef struct typedef fd_set ENetSocketSet; -#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset)) -#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset)) -#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset)) -#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset)) - -#endif /* __ENET_UNIX_H__ */ +#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO(&(sockset)) +#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET(socket, &(sockset)) +#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR(socket, &(sockset)) +#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET(socket, &(sockset)) +#endif /* __ENET_UNIX_H__ */ diff --git a/examples/ThirdPartyLibs/enet/include/enet/utility.h b/examples/ThirdPartyLibs/enet/include/enet/utility.h index e48a476be..18f511d92 100644 --- a/examples/ThirdPartyLibs/enet/include/enet/utility.h +++ b/examples/ThirdPartyLibs/enet/include/enet/utility.h @@ -9,4 +9,3 @@ #define ENET_MIN(x, y) ((x) < (y) ? (x) : (y)) #endif /* __ENET_UTILITY_H__ */ - diff --git a/examples/ThirdPartyLibs/enet/include/enet/win32.h b/examples/ThirdPartyLibs/enet/include/enet/win32.h index 0e1cf0c5a..b4646e67b 100644 --- a/examples/ThirdPartyLibs/enet/include/enet/win32.h +++ b/examples/ThirdPartyLibs/enet/include/enet/win32.h @@ -6,10 +6,10 @@ #define __ENET_WIN32_H__ #ifdef ENET_BUILDING_LIB -#pragma warning (disable: 4996) // 'strncpy' was declared deprecated -#pragma warning (disable: 4267) // size_t to int conversion -#pragma warning (disable: 4244) // 64bit to 32bit int -#pragma warning (disable: 4018) // signed/unsigned mismatch +#pragma warning(disable : 4996) // 'strncpy' was declared deprecated +#pragma warning(disable : 4267) // size_t to int conversion +#pragma warning(disable : 4244) // 64bit to 32bit int +#pragma warning(disable : 4018) // signed/unsigned mismatch #endif #include @@ -19,40 +19,38 @@ typedef SOCKET ENetSocket; enum { - ENET_SOCKET_NULL = INVALID_SOCKET + ENET_SOCKET_NULL = INVALID_SOCKET }; -#define ENET_HOST_TO_NET_16(value) (htons (value)) -#define ENET_HOST_TO_NET_32(value) (htonl (value)) +#define ENET_HOST_TO_NET_16(value) (htons(value)) +#define ENET_HOST_TO_NET_32(value) (htonl(value)) -#define ENET_NET_TO_HOST_16(value) (ntohs (value)) -#define ENET_NET_TO_HOST_32(value) (ntohl (value)) +#define ENET_NET_TO_HOST_16(value) (ntohs(value)) +#define ENET_NET_TO_HOST_32(value) (ntohl(value)) typedef struct { - size_t dataLength; - void * data; + size_t dataLength; + void* data; } ENetBuffer; #define ENET_CALLBACK __cdecl #if defined ENET_DLL #if defined ENET_BUILDING_LIB -#define ENET_API __declspec( dllexport ) +#define ENET_API __declspec(dllexport) #else -#define ENET_API __declspec( dllimport ) +#define ENET_API __declspec(dllimport) #endif /* ENET_BUILDING_LIB */ -#else /* !ENET_DLL */ +#else /* !ENET_DLL */ #define ENET_API extern #endif /* ENET_DLL */ typedef fd_set ENetSocketSet; -#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO (& (sockset)) -#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET (socket, & (sockset)) -#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR (socket, & (sockset)) -#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET (socket, & (sockset)) +#define ENET_SOCKETSET_EMPTY(sockset) FD_ZERO(&(sockset)) +#define ENET_SOCKETSET_ADD(sockset, socket) FD_SET(socket, &(sockset)) +#define ENET_SOCKETSET_REMOVE(sockset, socket) FD_CLEAR(socket, &(sockset)) +#define ENET_SOCKETSET_CHECK(sockset, socket) FD_ISSET(socket, &(sockset)) #endif /* __ENET_WIN32_H__ */ - - diff --git a/examples/ThirdPartyLibs/enet/list.c b/examples/ThirdPartyLibs/enet/list.c index 1c1a8dfaa..473bbeec0 100644 --- a/examples/ThirdPartyLibs/enet/list.c +++ b/examples/ThirdPartyLibs/enet/list.c @@ -10,66 +10,64 @@ @ingroup private @{ */ -void -enet_list_clear (ENetList * list) +void enet_list_clear(ENetList* list) { - list -> sentinel.next = & list -> sentinel; - list -> sentinel.previous = & list -> sentinel; + list->sentinel.next = &list->sentinel; + list->sentinel.previous = &list->sentinel; } ENetListIterator -enet_list_insert (ENetListIterator position, void * data) +enet_list_insert(ENetListIterator position, void* data) { - ENetListIterator result = (ENetListIterator) data; + ENetListIterator result = (ENetListIterator)data; - result -> previous = position -> previous; - result -> next = position; + result->previous = position->previous; + result->next = position; - result -> previous -> next = result; - position -> previous = result; + result->previous->next = result; + position->previous = result; - return result; + return result; } -void * -enet_list_remove (ENetListIterator position) +void* enet_list_remove(ENetListIterator position) { - position -> previous -> next = position -> next; - position -> next -> previous = position -> previous; + position->previous->next = position->next; + position->next->previous = position->previous; - return position; + return position; } ENetListIterator -enet_list_move (ENetListIterator position, void * dataFirst, void * dataLast) +enet_list_move(ENetListIterator position, void* dataFirst, void* dataLast) { - ENetListIterator first = (ENetListIterator) dataFirst, - last = (ENetListIterator) dataLast; + ENetListIterator first = (ENetListIterator)dataFirst, + last = (ENetListIterator)dataLast; - first -> previous -> next = last -> next; - last -> next -> previous = first -> previous; + first->previous->next = last->next; + last->next->previous = first->previous; - first -> previous = position -> previous; - last -> next = position; + first->previous = position->previous; + last->next = position; - first -> previous -> next = first; - position -> previous = last; - - return first; + first->previous->next = first; + position->previous = last; + + return first; } size_t -enet_list_size (ENetList * list) +enet_list_size(ENetList* list) { - size_t size = 0; - ENetListIterator position; + size_t size = 0; + ENetListIterator position; - for (position = enet_list_begin (list); - position != enet_list_end (list); - position = enet_list_next (position)) - ++ size; - - return size; + for (position = enet_list_begin(list); + position != enet_list_end(list); + position = enet_list_next(position)) + ++size; + + return size; } /** @} */ diff --git a/examples/ThirdPartyLibs/enet/packet.c b/examples/ThirdPartyLibs/enet/packet.c index 9a997be4e..84824e5be 100644 --- a/examples/ThirdPartyLibs/enet/packet.c +++ b/examples/ThirdPartyLibs/enet/packet.c @@ -17,54 +17,52 @@ @returns the packet on success, NULL on failure */ ENetPacket * -enet_packet_create (const void * data, size_t dataLength, enet_uint32 flags) +enet_packet_create(const void *data, size_t dataLength, enet_uint32 flags) { - ENetPacket * packet = (ENetPacket *) enet_malloc (sizeof (ENetPacket)); - if (packet == NULL) - return NULL; + ENetPacket *packet = (ENetPacket *)enet_malloc(sizeof(ENetPacket)); + if (packet == NULL) + return NULL; - if (flags & ENET_PACKET_FLAG_NO_ALLOCATE) - packet -> data = (enet_uint8 *) data; - else - if (dataLength <= 0) - packet -> data = NULL; - else - { - packet -> data = (enet_uint8 *) enet_malloc (dataLength); - if (packet -> data == NULL) - { - enet_free (packet); - return NULL; - } + if (flags & ENET_PACKET_FLAG_NO_ALLOCATE) + packet->data = (enet_uint8 *)data; + else if (dataLength <= 0) + packet->data = NULL; + else + { + packet->data = (enet_uint8 *)enet_malloc(dataLength); + if (packet->data == NULL) + { + enet_free(packet); + return NULL; + } - if (data != NULL) - memcpy (packet -> data, data, dataLength); - } + if (data != NULL) + memcpy(packet->data, data, dataLength); + } - packet -> referenceCount = 0; - packet -> flags = flags; - packet -> dataLength = dataLength; - packet -> freeCallback = NULL; - packet -> userData = NULL; + packet->referenceCount = 0; + packet->flags = flags; + packet->dataLength = dataLength; + packet->freeCallback = NULL; + packet->userData = NULL; - return packet; + return packet; } /** Destroys the packet and deallocates its data. @param packet packet to be destroyed */ -void -enet_packet_destroy (ENetPacket * packet) +void enet_packet_destroy(ENetPacket *packet) { - if (packet == NULL) - return; + if (packet == NULL) + return; - if (packet -> freeCallback != NULL) - (* packet -> freeCallback) (packet); - if (! (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE) && - packet -> data != NULL) - enet_free (packet -> data); - enet_free (packet); + if (packet->freeCallback != NULL) + (*packet->freeCallback)(packet); + if (!(packet->flags & ENET_PACKET_FLAG_NO_ALLOCATE) && + packet->data != NULL) + enet_free(packet->data); + enet_free(packet); } /** Attempts to resize the data in the packet to length specified in the @@ -73,93 +71,92 @@ enet_packet_destroy (ENetPacket * packet) @param dataLength new size for the packet data @returns 0 on success, < 0 on failure */ -int -enet_packet_resize (ENetPacket * packet, size_t dataLength) +int enet_packet_resize(ENetPacket *packet, size_t dataLength) { - enet_uint8 * newData; - - if (dataLength <= packet -> dataLength || (packet -> flags & ENET_PACKET_FLAG_NO_ALLOCATE)) - { - packet -> dataLength = dataLength; + enet_uint8 *newData; - return 0; - } + if (dataLength <= packet->dataLength || (packet->flags & ENET_PACKET_FLAG_NO_ALLOCATE)) + { + packet->dataLength = dataLength; - newData = (enet_uint8 *) enet_malloc (dataLength); - if (newData == NULL) - return -1; + return 0; + } - memcpy (newData, packet -> data, packet -> dataLength); - enet_free (packet -> data); - - packet -> data = newData; - packet -> dataLength = dataLength; + newData = (enet_uint8 *)enet_malloc(dataLength); + if (newData == NULL) + return -1; - return 0; + memcpy(newData, packet->data, packet->dataLength); + enet_free(packet->data); + + packet->data = newData; + packet->dataLength = dataLength; + + return 0; } static int initializedCRC32 = 0; -static enet_uint32 crcTable [256]; +static enet_uint32 crcTable[256]; -static enet_uint32 -reflect_crc (int val, int bits) +static enet_uint32 +reflect_crc(int val, int bits) { - int result = 0, bit; + int result = 0, bit; - for (bit = 0; bit < bits; bit ++) - { - if(val & 1) result |= 1 << (bits - 1 - bit); - val >>= 1; - } + for (bit = 0; bit < bits; bit++) + { + if (val & 1) result |= 1 << (bits - 1 - bit); + val >>= 1; + } - return result; + return result; } -static void -initialize_crc32 (void) +static void +initialize_crc32(void) { - int byte; + int byte; - for (byte = 0; byte < 256; ++ byte) - { - enet_uint32 crc = reflect_crc (byte, 8) << 24; - int offset; + for (byte = 0; byte < 256; ++byte) + { + enet_uint32 crc = reflect_crc(byte, 8) << 24; + int offset; - for(offset = 0; offset < 8; ++ offset) - { - if (crc & 0x80000000) - crc = (crc << 1) ^ 0x04c11db7; - else - crc <<= 1; - } + for (offset = 0; offset < 8; ++offset) + { + if (crc & 0x80000000) + crc = (crc << 1) ^ 0x04c11db7; + else + crc <<= 1; + } - crcTable [byte] = reflect_crc (crc, 32); - } + crcTable[byte] = reflect_crc(crc, 32); + } - initializedCRC32 = 1; + initializedCRC32 = 1; } - + enet_uint32 -enet_crc32 (const ENetBuffer * buffers, size_t bufferCount) +enet_crc32(const ENetBuffer *buffers, size_t bufferCount) { - enet_uint32 crc = 0xFFFFFFFF; - - if (! initializedCRC32) initialize_crc32 (); + enet_uint32 crc = 0xFFFFFFFF; - while (bufferCount -- > 0) - { - const enet_uint8 * data = (const enet_uint8 *) buffers -> data, - * dataEnd = & data [buffers -> dataLength]; + if (!initializedCRC32) initialize_crc32(); - while (data < dataEnd) - { - crc = (crc >> 8) ^ crcTable [(crc & 0xFF) ^ *data++]; - } + while (bufferCount-- > 0) + { + const enet_uint8 *data = (const enet_uint8 *)buffers->data, + *dataEnd = &data[buffers->dataLength]; - ++ buffers; - } + while (data < dataEnd) + { + crc = (crc >> 8) ^ crcTable[(crc & 0xFF) ^ *data++]; + } - return ENET_HOST_TO_NET_32 (~ crc); + ++buffers; + } + + return ENET_HOST_TO_NET_32(~crc); } /** @} */ diff --git a/examples/ThirdPartyLibs/enet/peer.c b/examples/ThirdPartyLibs/enet/peer.c index a86d793d8..0af70dfd0 100644 --- a/examples/ThirdPartyLibs/enet/peer.c +++ b/examples/ThirdPartyLibs/enet/peer.c @@ -39,54 +39,50 @@ @param acceleration rate at which to increase the throttle probability as mean RTT declines @param deceleration rate at which to decrease the throttle probability as mean RTT increases */ -void -enet_peer_throttle_configure (ENetPeer * peer, enet_uint32 interval, enet_uint32 acceleration, enet_uint32 deceleration) +void enet_peer_throttle_configure(ENetPeer *peer, enet_uint32 interval, enet_uint32 acceleration, enet_uint32 deceleration) { - ENetProtocol command; + ENetProtocol command; - peer -> packetThrottleInterval = interval; - peer -> packetThrottleAcceleration = acceleration; - peer -> packetThrottleDeceleration = deceleration; + peer->packetThrottleInterval = interval; + peer->packetThrottleAcceleration = acceleration; + peer->packetThrottleDeceleration = deceleration; - command.header.command = ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; - command.header.channelID = 0xFF; + command.header.command = ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; + command.header.channelID = 0xFF; - command.throttleConfigure.packetThrottleInterval = ENET_HOST_TO_NET_32 (interval); - command.throttleConfigure.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (acceleration); - command.throttleConfigure.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (deceleration); + command.throttleConfigure.packetThrottleInterval = ENET_HOST_TO_NET_32(interval); + command.throttleConfigure.packetThrottleAcceleration = ENET_HOST_TO_NET_32(acceleration); + command.throttleConfigure.packetThrottleDeceleration = ENET_HOST_TO_NET_32(deceleration); - enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); + enet_peer_queue_outgoing_command(peer, &command, NULL, 0, 0); } -int -enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt) +int enet_peer_throttle(ENetPeer *peer, enet_uint32 rtt) { - if (peer -> lastRoundTripTime <= peer -> lastRoundTripTimeVariance) - { - peer -> packetThrottle = peer -> packetThrottleLimit; - } - else - if (rtt < peer -> lastRoundTripTime) - { - peer -> packetThrottle += peer -> packetThrottleAcceleration; + if (peer->lastRoundTripTime <= peer->lastRoundTripTimeVariance) + { + peer->packetThrottle = peer->packetThrottleLimit; + } + else if (rtt < peer->lastRoundTripTime) + { + peer->packetThrottle += peer->packetThrottleAcceleration; - if (peer -> packetThrottle > peer -> packetThrottleLimit) - peer -> packetThrottle = peer -> packetThrottleLimit; + if (peer->packetThrottle > peer->packetThrottleLimit) + peer->packetThrottle = peer->packetThrottleLimit; - return 1; - } - else - if (rtt > peer -> lastRoundTripTime + 2 * peer -> lastRoundTripTimeVariance) - { - if (peer -> packetThrottle > peer -> packetThrottleDeceleration) - peer -> packetThrottle -= peer -> packetThrottleDeceleration; - else - peer -> packetThrottle = 0; + return 1; + } + else if (rtt > peer->lastRoundTripTime + 2 * peer->lastRoundTripTimeVariance) + { + if (peer->packetThrottle > peer->packetThrottleDeceleration) + peer->packetThrottle -= peer->packetThrottleDeceleration; + else + peer->packetThrottle = 0; - return -1; - } + return -1; + } - return 0; + return 0; } /** Queues a packet to be sent. @@ -96,121 +92,119 @@ enet_peer_throttle (ENetPeer * peer, enet_uint32 rtt) @retval 0 on success @retval < 0 on failure */ -int -enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) +int enet_peer_send(ENetPeer *peer, enet_uint8 channelID, ENetPacket *packet) { - ENetChannel * channel = & peer -> channels [channelID]; - ENetProtocol command; - size_t fragmentLength; + ENetChannel *channel = &peer->channels[channelID]; + ENetProtocol command; + size_t fragmentLength; - if (peer -> state != ENET_PEER_STATE_CONNECTED || - channelID >= peer -> channelCount || - packet -> dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE) - return -1; + if (peer->state != ENET_PEER_STATE_CONNECTED || + channelID >= peer->channelCount || + packet->dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE) + return -1; - fragmentLength = peer -> mtu - sizeof (ENetProtocolHeader) - sizeof (ENetProtocolSendFragment); - if (peer -> host -> checksum != NULL) - fragmentLength -= sizeof(enet_uint32); + fragmentLength = peer->mtu - sizeof(ENetProtocolHeader) - sizeof(ENetProtocolSendFragment); + if (peer->host->checksum != NULL) + fragmentLength -= sizeof(enet_uint32); - if (packet -> dataLength > fragmentLength) - { - enet_uint32 fragmentCount = (packet -> dataLength + fragmentLength - 1) / fragmentLength, - fragmentNumber, - fragmentOffset; - enet_uint8 commandNumber; - enet_uint16 startSequenceNumber; - ENetList fragments; - ENetOutgoingCommand * fragment; + if (packet->dataLength > fragmentLength) + { + enet_uint32 fragmentCount = (packet->dataLength + fragmentLength - 1) / fragmentLength, + fragmentNumber, + fragmentOffset; + enet_uint8 commandNumber; + enet_uint16 startSequenceNumber; + ENetList fragments; + ENetOutgoingCommand *fragment; - if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT) - return -1; + if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT) + return -1; - if ((packet -> flags & (ENET_PACKET_FLAG_RELIABLE | ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT)) == ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT && - channel -> outgoingUnreliableSequenceNumber < 0xFFFF) - { - commandNumber = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT; - startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingUnreliableSequenceNumber + 1); - } - else - { - commandNumber = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; - startSequenceNumber = ENET_HOST_TO_NET_16 (channel -> outgoingReliableSequenceNumber + 1); - } - - enet_list_clear (& fragments); + if ((packet->flags & (ENET_PACKET_FLAG_RELIABLE | ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT)) == ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT && + channel->outgoingUnreliableSequenceNumber < 0xFFFF) + { + commandNumber = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT; + startSequenceNumber = ENET_HOST_TO_NET_16(channel->outgoingUnreliableSequenceNumber + 1); + } + else + { + commandNumber = ENET_PROTOCOL_COMMAND_SEND_FRAGMENT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; + startSequenceNumber = ENET_HOST_TO_NET_16(channel->outgoingReliableSequenceNumber + 1); + } - for (fragmentNumber = 0, - fragmentOffset = 0; - fragmentOffset < packet -> dataLength; - ++ fragmentNumber, - fragmentOffset += fragmentLength) - { - if (packet -> dataLength - fragmentOffset < fragmentLength) - fragmentLength = packet -> dataLength - fragmentOffset; + enet_list_clear(&fragments); - fragment = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand)); - if (fragment == NULL) - { - while (! enet_list_empty (& fragments)) - { - fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments)); - - enet_free (fragment); - } - - return -1; - } - - fragment -> fragmentOffset = fragmentOffset; - fragment -> fragmentLength = fragmentLength; - fragment -> packet = packet; - fragment -> command.header.command = commandNumber; - fragment -> command.header.channelID = channelID; - fragment -> command.sendFragment.startSequenceNumber = startSequenceNumber; - fragment -> command.sendFragment.dataLength = ENET_HOST_TO_NET_16 (fragmentLength); - fragment -> command.sendFragment.fragmentCount = ENET_HOST_TO_NET_32 (fragmentCount); - fragment -> command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32 (fragmentNumber); - fragment -> command.sendFragment.totalLength = ENET_HOST_TO_NET_32 (packet -> dataLength); - fragment -> command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32 (fragmentOffset); - - enet_list_insert (enet_list_end (& fragments), fragment); - } + for (fragmentNumber = 0, + fragmentOffset = 0; + fragmentOffset < packet->dataLength; + ++fragmentNumber, + fragmentOffset += fragmentLength) + { + if (packet->dataLength - fragmentOffset < fragmentLength) + fragmentLength = packet->dataLength - fragmentOffset; - packet -> referenceCount += fragmentNumber; + fragment = (ENetOutgoingCommand *)enet_malloc(sizeof(ENetOutgoingCommand)); + if (fragment == NULL) + { + while (!enet_list_empty(&fragments)) + { + fragment = (ENetOutgoingCommand *)enet_list_remove(enet_list_begin(&fragments)); - while (! enet_list_empty (& fragments)) - { - fragment = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (& fragments)); - - enet_peer_setup_outgoing_command (peer, fragment); - } + enet_free(fragment); + } - return 0; - } + return -1; + } - command.header.channelID = channelID; + fragment->fragmentOffset = fragmentOffset; + fragment->fragmentLength = fragmentLength; + fragment->packet = packet; + fragment->command.header.command = commandNumber; + fragment->command.header.channelID = channelID; + fragment->command.sendFragment.startSequenceNumber = startSequenceNumber; + fragment->command.sendFragment.dataLength = ENET_HOST_TO_NET_16(fragmentLength); + fragment->command.sendFragment.fragmentCount = ENET_HOST_TO_NET_32(fragmentCount); + fragment->command.sendFragment.fragmentNumber = ENET_HOST_TO_NET_32(fragmentNumber); + fragment->command.sendFragment.totalLength = ENET_HOST_TO_NET_32(packet->dataLength); + fragment->command.sendFragment.fragmentOffset = ENET_NET_TO_HOST_32(fragmentOffset); - if ((packet -> flags & (ENET_PACKET_FLAG_RELIABLE | ENET_PACKET_FLAG_UNSEQUENCED)) == ENET_PACKET_FLAG_UNSEQUENCED) - { - command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED; - command.sendUnsequenced.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength); - } - else - if (packet -> flags & ENET_PACKET_FLAG_RELIABLE || channel -> outgoingUnreliableSequenceNumber >= 0xFFFF) - { - command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; - command.sendReliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength); - } - else - { - command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE; - command.sendUnreliable.dataLength = ENET_HOST_TO_NET_16 (packet -> dataLength); - } + enet_list_insert(enet_list_end(&fragments), fragment); + } - if (enet_peer_queue_outgoing_command (peer, & command, packet, 0, packet -> dataLength) == NULL) - return -1; + packet->referenceCount += fragmentNumber; - return 0; + while (!enet_list_empty(&fragments)) + { + fragment = (ENetOutgoingCommand *)enet_list_remove(enet_list_begin(&fragments)); + + enet_peer_setup_outgoing_command(peer, fragment); + } + + return 0; + } + + command.header.channelID = channelID; + + if ((packet->flags & (ENET_PACKET_FLAG_RELIABLE | ENET_PACKET_FLAG_UNSEQUENCED)) == ENET_PACKET_FLAG_UNSEQUENCED) + { + command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED; + command.sendUnsequenced.dataLength = ENET_HOST_TO_NET_16(packet->dataLength); + } + else if (packet->flags & ENET_PACKET_FLAG_RELIABLE || channel->outgoingUnreliableSequenceNumber >= 0xFFFF) + { + command.header.command = ENET_PROTOCOL_COMMAND_SEND_RELIABLE | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; + command.sendReliable.dataLength = ENET_HOST_TO_NET_16(packet->dataLength); + } + else + { + command.header.command = ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE; + command.sendUnreliable.dataLength = ENET_HOST_TO_NET_16(packet->dataLength); + } + + if (enet_peer_queue_outgoing_command(peer, &command, packet, 0, packet->dataLength) == NULL) + return -1; + + return 0; } /** Attempts to dequeue any incoming queued packet. @@ -219,122 +213,121 @@ enet_peer_send (ENetPeer * peer, enet_uint8 channelID, ENetPacket * packet) @returns a pointer to the packet, or NULL if there are no available incoming queued packets */ ENetPacket * -enet_peer_receive (ENetPeer * peer, enet_uint8 * channelID) +enet_peer_receive(ENetPeer *peer, enet_uint8 *channelID) { - ENetIncomingCommand * incomingCommand; - ENetPacket * packet; - - if (enet_list_empty (& peer -> dispatchedCommands)) - return NULL; + ENetIncomingCommand *incomingCommand; + ENetPacket *packet; - incomingCommand = (ENetIncomingCommand *) enet_list_remove (enet_list_begin (& peer -> dispatchedCommands)); + if (enet_list_empty(&peer->dispatchedCommands)) + return NULL; - if (channelID != NULL) - * channelID = incomingCommand -> command.header.channelID; + incomingCommand = (ENetIncomingCommand *)enet_list_remove(enet_list_begin(&peer->dispatchedCommands)); - packet = incomingCommand -> packet; + if (channelID != NULL) + *channelID = incomingCommand->command.header.channelID; - -- packet -> referenceCount; + packet = incomingCommand->packet; - if (incomingCommand -> fragments != NULL) - enet_free (incomingCommand -> fragments); + --packet->referenceCount; - enet_free (incomingCommand); + if (incomingCommand->fragments != NULL) + enet_free(incomingCommand->fragments); - return packet; + enet_free(incomingCommand); + + return packet; } static void -enet_peer_reset_outgoing_commands (ENetList * queue) +enet_peer_reset_outgoing_commands(ENetList *queue) { - ENetOutgoingCommand * outgoingCommand; + ENetOutgoingCommand *outgoingCommand; - while (! enet_list_empty (queue)) - { - outgoingCommand = (ENetOutgoingCommand *) enet_list_remove (enet_list_begin (queue)); + while (!enet_list_empty(queue)) + { + outgoingCommand = (ENetOutgoingCommand *)enet_list_remove(enet_list_begin(queue)); - if (outgoingCommand -> packet != NULL) - { - -- outgoingCommand -> packet -> referenceCount; + if (outgoingCommand->packet != NULL) + { + --outgoingCommand->packet->referenceCount; - if (outgoingCommand -> packet -> referenceCount == 0) - enet_packet_destroy (outgoingCommand -> packet); - } + if (outgoingCommand->packet->referenceCount == 0) + enet_packet_destroy(outgoingCommand->packet); + } - enet_free (outgoingCommand); - } + enet_free(outgoingCommand); + } } static void -enet_peer_remove_incoming_commands (ENetList * queue, ENetListIterator startCommand, ENetListIterator endCommand) +enet_peer_remove_incoming_commands(ENetList *queue, ENetListIterator startCommand, ENetListIterator endCommand) { - ENetListIterator currentCommand; - - for (currentCommand = startCommand; currentCommand != endCommand; ) - { - ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; + ENetListIterator currentCommand; - currentCommand = enet_list_next (currentCommand); + for (currentCommand = startCommand; currentCommand != endCommand;) + { + ENetIncomingCommand *incomingCommand = (ENetIncomingCommand *)currentCommand; - enet_list_remove (& incomingCommand -> incomingCommandList); - - if (incomingCommand -> packet != NULL) - { - -- incomingCommand -> packet -> referenceCount; + currentCommand = enet_list_next(currentCommand); - if (incomingCommand -> packet -> referenceCount == 0) - enet_packet_destroy (incomingCommand -> packet); - } + enet_list_remove(&incomingCommand->incomingCommandList); - if (incomingCommand -> fragments != NULL) - enet_free (incomingCommand -> fragments); + if (incomingCommand->packet != NULL) + { + --incomingCommand->packet->referenceCount; - enet_free (incomingCommand); - } + if (incomingCommand->packet->referenceCount == 0) + enet_packet_destroy(incomingCommand->packet); + } + + if (incomingCommand->fragments != NULL) + enet_free(incomingCommand->fragments); + + enet_free(incomingCommand); + } } static void -enet_peer_reset_incoming_commands (ENetList * queue) +enet_peer_reset_incoming_commands(ENetList *queue) { - enet_peer_remove_incoming_commands(queue, enet_list_begin (queue), enet_list_end (queue)); + enet_peer_remove_incoming_commands(queue, enet_list_begin(queue), enet_list_end(queue)); } - -void -enet_peer_reset_queues (ENetPeer * peer) + +void enet_peer_reset_queues(ENetPeer *peer) { - ENetChannel * channel; + ENetChannel *channel; - if (peer -> needsDispatch) - { - enet_list_remove (& peer -> dispatchList); + if (peer->needsDispatch) + { + enet_list_remove(&peer->dispatchList); - peer -> needsDispatch = 0; - } + peer->needsDispatch = 0; + } - while (! enet_list_empty (& peer -> acknowledgements)) - enet_free (enet_list_remove (enet_list_begin (& peer -> acknowledgements))); + while (!enet_list_empty(&peer->acknowledgements)) + enet_free(enet_list_remove(enet_list_begin(&peer->acknowledgements))); - enet_peer_reset_outgoing_commands (& peer -> sentReliableCommands); - enet_peer_reset_outgoing_commands (& peer -> sentUnreliableCommands); - enet_peer_reset_outgoing_commands (& peer -> outgoingReliableCommands); - enet_peer_reset_outgoing_commands (& peer -> outgoingUnreliableCommands); - enet_peer_reset_incoming_commands (& peer -> dispatchedCommands); + enet_peer_reset_outgoing_commands(&peer->sentReliableCommands); + enet_peer_reset_outgoing_commands(&peer->sentUnreliableCommands); + enet_peer_reset_outgoing_commands(&peer->outgoingReliableCommands); + enet_peer_reset_outgoing_commands(&peer->outgoingUnreliableCommands); + enet_peer_reset_incoming_commands(&peer->dispatchedCommands); - if (peer -> channels != NULL && peer -> channelCount > 0) - { - for (channel = peer -> channels; - channel < & peer -> channels [peer -> channelCount]; - ++ channel) - { - enet_peer_reset_incoming_commands (& channel -> incomingReliableCommands); - enet_peer_reset_incoming_commands (& channel -> incomingUnreliableCommands); - } + if (peer->channels != NULL && peer->channelCount > 0) + { + for (channel = peer->channels; + channel < &peer->channels[peer->channelCount]; + ++channel) + { + enet_peer_reset_incoming_commands(&channel->incomingReliableCommands); + enet_peer_reset_incoming_commands(&channel->incomingUnreliableCommands); + } - enet_free (peer -> channels); - } + enet_free(peer->channels); + } - peer -> channels = NULL; - peer -> channelCount = 0; + peer->channels = NULL; + peer->channelCount = 0; } /** Forcefully disconnects a peer. @@ -342,57 +335,56 @@ enet_peer_reset_queues (ENetPeer * peer) @remarks The foreign host represented by the peer is not notified of the disconnection and will timeout on its connection to the local host. */ -void -enet_peer_reset (ENetPeer * peer) +void enet_peer_reset(ENetPeer *peer) { - peer -> outgoingPeerID = ENET_PROTOCOL_MAXIMUM_PEER_ID; - peer -> connectID = 0; + peer->outgoingPeerID = ENET_PROTOCOL_MAXIMUM_PEER_ID; + peer->connectID = 0; - peer -> state = ENET_PEER_STATE_DISCONNECTED; + peer->state = ENET_PEER_STATE_DISCONNECTED; - peer -> incomingBandwidth = 0; - peer -> outgoingBandwidth = 0; - peer -> incomingBandwidthThrottleEpoch = 0; - peer -> outgoingBandwidthThrottleEpoch = 0; - peer -> incomingDataTotal = 0; - peer -> outgoingDataTotal = 0; - peer -> lastSendTime = 0; - peer -> lastReceiveTime = 0; - peer -> nextTimeout = 0; - peer -> earliestTimeout = 0; - peer -> packetLossEpoch = 0; - peer -> packetsSent = 0; - peer -> packetsLost = 0; - peer -> packetLoss = 0; - peer -> packetLossVariance = 0; - peer -> packetThrottle = ENET_PEER_DEFAULT_PACKET_THROTTLE; - peer -> packetThrottleLimit = ENET_PEER_PACKET_THROTTLE_SCALE; - peer -> packetThrottleCounter = 0; - peer -> packetThrottleEpoch = 0; - peer -> packetThrottleAcceleration = ENET_PEER_PACKET_THROTTLE_ACCELERATION; - peer -> packetThrottleDeceleration = ENET_PEER_PACKET_THROTTLE_DECELERATION; - peer -> packetThrottleInterval = ENET_PEER_PACKET_THROTTLE_INTERVAL; - peer -> pingInterval = ENET_PEER_PING_INTERVAL; - peer -> timeoutLimit = ENET_PEER_TIMEOUT_LIMIT; - peer -> timeoutMinimum = ENET_PEER_TIMEOUT_MINIMUM; - peer -> timeoutMaximum = ENET_PEER_TIMEOUT_MAXIMUM; - peer -> lastRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME; - peer -> lowestRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME; - peer -> lastRoundTripTimeVariance = 0; - peer -> highestRoundTripTimeVariance = 0; - peer -> roundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME; - peer -> roundTripTimeVariance = 0; - peer -> mtu = peer -> host -> mtu; - peer -> reliableDataInTransit = 0; - peer -> outgoingReliableSequenceNumber = 0; - peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; - peer -> incomingUnsequencedGroup = 0; - peer -> outgoingUnsequencedGroup = 0; - peer -> eventData = 0; + peer->incomingBandwidth = 0; + peer->outgoingBandwidth = 0; + peer->incomingBandwidthThrottleEpoch = 0; + peer->outgoingBandwidthThrottleEpoch = 0; + peer->incomingDataTotal = 0; + peer->outgoingDataTotal = 0; + peer->lastSendTime = 0; + peer->lastReceiveTime = 0; + peer->nextTimeout = 0; + peer->earliestTimeout = 0; + peer->packetLossEpoch = 0; + peer->packetsSent = 0; + peer->packetsLost = 0; + peer->packetLoss = 0; + peer->packetLossVariance = 0; + peer->packetThrottle = ENET_PEER_DEFAULT_PACKET_THROTTLE; + peer->packetThrottleLimit = ENET_PEER_PACKET_THROTTLE_SCALE; + peer->packetThrottleCounter = 0; + peer->packetThrottleEpoch = 0; + peer->packetThrottleAcceleration = ENET_PEER_PACKET_THROTTLE_ACCELERATION; + peer->packetThrottleDeceleration = ENET_PEER_PACKET_THROTTLE_DECELERATION; + peer->packetThrottleInterval = ENET_PEER_PACKET_THROTTLE_INTERVAL; + peer->pingInterval = ENET_PEER_PING_INTERVAL; + peer->timeoutLimit = ENET_PEER_TIMEOUT_LIMIT; + peer->timeoutMinimum = ENET_PEER_TIMEOUT_MINIMUM; + peer->timeoutMaximum = ENET_PEER_TIMEOUT_MAXIMUM; + peer->lastRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME; + peer->lowestRoundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME; + peer->lastRoundTripTimeVariance = 0; + peer->highestRoundTripTimeVariance = 0; + peer->roundTripTime = ENET_PEER_DEFAULT_ROUND_TRIP_TIME; + peer->roundTripTimeVariance = 0; + peer->mtu = peer->host->mtu; + peer->reliableDataInTransit = 0; + peer->outgoingReliableSequenceNumber = 0; + peer->windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + peer->incomingUnsequencedGroup = 0; + peer->outgoingUnsequencedGroup = 0; + peer->eventData = 0; - memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow)); - - enet_peer_reset_queues (peer); + memset(peer->unsequencedWindow, 0, sizeof(peer->unsequencedWindow)); + + enet_peer_reset_queues(peer); } /** Sends a ping request to a peer. @@ -402,18 +394,17 @@ enet_peer_reset (ENetPeer * peer) peers at regular intervals, however, this function may be called to ensure more frequent ping requests. */ -void -enet_peer_ping (ENetPeer * peer) +void enet_peer_ping(ENetPeer *peer) { - ENetProtocol command; + ENetProtocol command; - if (peer -> state != ENET_PEER_STATE_CONNECTED) - return; + if (peer->state != ENET_PEER_STATE_CONNECTED) + return; - command.header.command = ENET_PROTOCOL_COMMAND_PING | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; - command.header.channelID = 0xFF; - - enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); + command.header.command = ENET_PROTOCOL_COMMAND_PING | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; + command.header.channelID = 0xFF; + + enet_peer_queue_outgoing_command(peer, &command, NULL, 0, 0); } /** Sets the interval at which pings will be sent to a peer. @@ -425,10 +416,9 @@ enet_peer_ping (ENetPeer * peer) @param peer the peer to adjust @param pingInterval the interval at which to send pings; defaults to ENET_PEER_PING_INTERVAL if 0 */ -void -enet_peer_ping_interval (ENetPeer * peer, enet_uint32 pingInterval) +void enet_peer_ping_interval(ENetPeer *peer, enet_uint32 pingInterval) { - peer -> pingInterval = pingInterval ? pingInterval : ENET_PEER_PING_INTERVAL; + peer->pingInterval = pingInterval ? pingInterval : ENET_PEER_PING_INTERVAL; } /** Sets the timeout parameters for a peer. @@ -448,12 +438,11 @@ enet_peer_ping_interval (ENetPeer * peer, enet_uint32 pingInterval) @param timeoutMaximum the timeout maximum; defaults to ENET_PEER_TIMEOUT_MAXIMUM if 0 */ -void -enet_peer_timeout (ENetPeer * peer, enet_uint32 timeoutLimit, enet_uint32 timeoutMinimum, enet_uint32 timeoutMaximum) +void enet_peer_timeout(ENetPeer *peer, enet_uint32 timeoutLimit, enet_uint32 timeoutMinimum, enet_uint32 timeoutMaximum) { - peer -> timeoutLimit = timeoutLimit ? timeoutLimit : ENET_PEER_TIMEOUT_LIMIT; - peer -> timeoutMinimum = timeoutMinimum ? timeoutMinimum : ENET_PEER_TIMEOUT_MINIMUM; - peer -> timeoutMaximum = timeoutMaximum ? timeoutMaximum : ENET_PEER_TIMEOUT_MAXIMUM; + peer->timeoutLimit = timeoutLimit ? timeoutLimit : ENET_PEER_TIMEOUT_LIMIT; + peer->timeoutMinimum = timeoutMinimum ? timeoutMinimum : ENET_PEER_TIMEOUT_MINIMUM; + peer->timeoutMaximum = timeoutMaximum ? timeoutMaximum : ENET_PEER_TIMEOUT_MAXIMUM; } /** Force an immediate disconnection from a peer. @@ -463,29 +452,28 @@ enet_peer_timeout (ENetPeer * peer, enet_uint32 timeoutLimit, enet_uint32 timeou guarenteed to receive the disconnect notification, and is reset immediately upon return from this function. */ -void -enet_peer_disconnect_now (ENetPeer * peer, enet_uint32 data) +void enet_peer_disconnect_now(ENetPeer *peer, enet_uint32 data) { - ENetProtocol command; + ENetProtocol command; - if (peer -> state == ENET_PEER_STATE_DISCONNECTED) - return; + if (peer->state == ENET_PEER_STATE_DISCONNECTED) + return; - if (peer -> state != ENET_PEER_STATE_ZOMBIE && - peer -> state != ENET_PEER_STATE_DISCONNECTING) - { - enet_peer_reset_queues (peer); + if (peer->state != ENET_PEER_STATE_ZOMBIE && + peer->state != ENET_PEER_STATE_DISCONNECTING) + { + enet_peer_reset_queues(peer); - command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED; - command.header.channelID = 0xFF; - command.disconnect.data = ENET_HOST_TO_NET_32 (data); + command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT | ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED; + command.header.channelID = 0xFF; + command.disconnect.data = ENET_HOST_TO_NET_32(data); - enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); + enet_peer_queue_outgoing_command(peer, &command, NULL, 0, 0); - enet_host_flush (peer -> host); - } + enet_host_flush(peer->host); + } - enet_peer_reset (peer); + enet_peer_reset(peer); } /** Request a disconnection from a peer. @@ -494,37 +482,36 @@ enet_peer_disconnect_now (ENetPeer * peer, enet_uint32 data) @remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service() once the disconnection is complete. */ -void -enet_peer_disconnect (ENetPeer * peer, enet_uint32 data) +void enet_peer_disconnect(ENetPeer *peer, enet_uint32 data) { - ENetProtocol command; + ENetProtocol command; - if (peer -> state == ENET_PEER_STATE_DISCONNECTING || - peer -> state == ENET_PEER_STATE_DISCONNECTED || - peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT || - peer -> state == ENET_PEER_STATE_ZOMBIE) - return; + if (peer->state == ENET_PEER_STATE_DISCONNECTING || + peer->state == ENET_PEER_STATE_DISCONNECTED || + peer->state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT || + peer->state == ENET_PEER_STATE_ZOMBIE) + return; - enet_peer_reset_queues (peer); + enet_peer_reset_queues(peer); - command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT; - command.header.channelID = 0xFF; - command.disconnect.data = ENET_HOST_TO_NET_32 (data); + command.header.command = ENET_PROTOCOL_COMMAND_DISCONNECT; + command.header.channelID = 0xFF; + command.disconnect.data = ENET_HOST_TO_NET_32(data); - if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) - command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; - else - command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED; - - enet_peer_queue_outgoing_command (peer, & command, NULL, 0, 0); + if (peer->state == ENET_PEER_STATE_CONNECTED || peer->state == ENET_PEER_STATE_DISCONNECT_LATER) + command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; + else + command.header.command |= ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED; - if (peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) - peer -> state = ENET_PEER_STATE_DISCONNECTING; - else - { - enet_host_flush (peer -> host); - enet_peer_reset (peer); - } + enet_peer_queue_outgoing_command(peer, &command, NULL, 0, 0); + + if (peer->state == ENET_PEER_STATE_CONNECTED || peer->state == ENET_PEER_STATE_DISCONNECT_LATER) + peer->state = ENET_PEER_STATE_DISCONNECTING; + else + { + enet_host_flush(peer->host); + enet_peer_reset(peer); + } } /** Request a disconnection from a peer, but only after all queued outgoing packets are sent. @@ -533,427 +520,418 @@ enet_peer_disconnect (ENetPeer * peer, enet_uint32 data) @remarks An ENET_EVENT_DISCONNECT event will be generated by enet_host_service() once the disconnection is complete. */ -void -enet_peer_disconnect_later (ENetPeer * peer, enet_uint32 data) -{ - if ((peer -> state == ENET_PEER_STATE_CONNECTED || peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) && - ! (enet_list_empty (& peer -> outgoingReliableCommands) && - enet_list_empty (& peer -> outgoingUnreliableCommands) && - enet_list_empty (& peer -> sentReliableCommands))) - { - peer -> state = ENET_PEER_STATE_DISCONNECT_LATER; - peer -> eventData = data; - } - else - enet_peer_disconnect (peer, data); +void enet_peer_disconnect_later(ENetPeer *peer, enet_uint32 data) +{ + if ((peer->state == ENET_PEER_STATE_CONNECTED || peer->state == ENET_PEER_STATE_DISCONNECT_LATER) && + !(enet_list_empty(&peer->outgoingReliableCommands) && + enet_list_empty(&peer->outgoingUnreliableCommands) && + enet_list_empty(&peer->sentReliableCommands))) + { + peer->state = ENET_PEER_STATE_DISCONNECT_LATER; + peer->eventData = data; + } + else + enet_peer_disconnect(peer, data); } ENetAcknowledgement * -enet_peer_queue_acknowledgement (ENetPeer * peer, const ENetProtocol * command, enet_uint16 sentTime) +enet_peer_queue_acknowledgement(ENetPeer *peer, const ENetProtocol *command, enet_uint16 sentTime) { - ENetAcknowledgement * acknowledgement; + ENetAcknowledgement *acknowledgement; - if (command -> header.channelID < peer -> channelCount) - { - ENetChannel * channel = & peer -> channels [command -> header.channelID]; - enet_uint16 reliableWindow = command -> header.reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE, - currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + if (command->header.channelID < peer->channelCount) + { + ENetChannel *channel = &peer->channels[command->header.channelID]; + enet_uint16 reliableWindow = command->header.reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE, + currentWindow = channel->incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; - if (command -> header.reliableSequenceNumber < channel -> incomingReliableSequenceNumber) - reliableWindow += ENET_PEER_RELIABLE_WINDOWS; + if (command->header.reliableSequenceNumber < channel->incomingReliableSequenceNumber) + reliableWindow += ENET_PEER_RELIABLE_WINDOWS; - if (reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1 && reliableWindow <= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS) - return NULL; - } + if (reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1 && reliableWindow <= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS) + return NULL; + } - acknowledgement = (ENetAcknowledgement *) enet_malloc (sizeof (ENetAcknowledgement)); - if (acknowledgement == NULL) - return NULL; + acknowledgement = (ENetAcknowledgement *)enet_malloc(sizeof(ENetAcknowledgement)); + if (acknowledgement == NULL) + return NULL; - peer -> outgoingDataTotal += sizeof (ENetProtocolAcknowledge); + peer->outgoingDataTotal += sizeof(ENetProtocolAcknowledge); - acknowledgement -> sentTime = sentTime; - acknowledgement -> command = * command; - - enet_list_insert (enet_list_end (& peer -> acknowledgements), acknowledgement); - - return acknowledgement; + acknowledgement->sentTime = sentTime; + acknowledgement->command = *command; + + enet_list_insert(enet_list_end(&peer->acknowledgements), acknowledgement); + + return acknowledgement; } -void -enet_peer_setup_outgoing_command (ENetPeer * peer, ENetOutgoingCommand * outgoingCommand) +void enet_peer_setup_outgoing_command(ENetPeer *peer, ENetOutgoingCommand *outgoingCommand) { - ENetChannel * channel = & peer -> channels [outgoingCommand -> command.header.channelID]; + ENetChannel *channel = &peer->channels[outgoingCommand->command.header.channelID]; - peer -> outgoingDataTotal += enet_protocol_command_size (outgoingCommand -> command.header.command) + outgoingCommand -> fragmentLength; + peer->outgoingDataTotal += enet_protocol_command_size(outgoingCommand->command.header.command) + outgoingCommand->fragmentLength; - if (outgoingCommand -> command.header.channelID == 0xFF) - { - ++ peer -> outgoingReliableSequenceNumber; + if (outgoingCommand->command.header.channelID == 0xFF) + { + ++peer->outgoingReliableSequenceNumber; - outgoingCommand -> reliableSequenceNumber = peer -> outgoingReliableSequenceNumber; - outgoingCommand -> unreliableSequenceNumber = 0; - } - else - if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) - { - ++ channel -> outgoingReliableSequenceNumber; - channel -> outgoingUnreliableSequenceNumber = 0; + outgoingCommand->reliableSequenceNumber = peer->outgoingReliableSequenceNumber; + outgoingCommand->unreliableSequenceNumber = 0; + } + else if (outgoingCommand->command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) + { + ++channel->outgoingReliableSequenceNumber; + channel->outgoingUnreliableSequenceNumber = 0; - outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber; - outgoingCommand -> unreliableSequenceNumber = 0; - } - else - if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED) - { - ++ peer -> outgoingUnsequencedGroup; + outgoingCommand->reliableSequenceNumber = channel->outgoingReliableSequenceNumber; + outgoingCommand->unreliableSequenceNumber = 0; + } + else if (outgoingCommand->command.header.command & ENET_PROTOCOL_COMMAND_FLAG_UNSEQUENCED) + { + ++peer->outgoingUnsequencedGroup; - outgoingCommand -> reliableSequenceNumber = 0; - outgoingCommand -> unreliableSequenceNumber = 0; - } - else - { - if (outgoingCommand -> fragmentOffset == 0) - ++ channel -> outgoingUnreliableSequenceNumber; - - outgoingCommand -> reliableSequenceNumber = channel -> outgoingReliableSequenceNumber; - outgoingCommand -> unreliableSequenceNumber = channel -> outgoingUnreliableSequenceNumber; - } - - outgoingCommand -> sendAttempts = 0; - outgoingCommand -> sentTime = 0; - outgoingCommand -> roundTripTimeout = 0; - outgoingCommand -> roundTripTimeoutLimit = 0; - outgoingCommand -> command.header.reliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> reliableSequenceNumber); + outgoingCommand->reliableSequenceNumber = 0; + outgoingCommand->unreliableSequenceNumber = 0; + } + else + { + if (outgoingCommand->fragmentOffset == 0) + ++channel->outgoingUnreliableSequenceNumber; - switch (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) - { - case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: - outgoingCommand -> command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_16 (outgoingCommand -> unreliableSequenceNumber); - break; + outgoingCommand->reliableSequenceNumber = channel->outgoingReliableSequenceNumber; + outgoingCommand->unreliableSequenceNumber = channel->outgoingUnreliableSequenceNumber; + } - case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: - outgoingCommand -> command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16 (peer -> outgoingUnsequencedGroup); - break; - - default: - break; - } + outgoingCommand->sendAttempts = 0; + outgoingCommand->sentTime = 0; + outgoingCommand->roundTripTimeout = 0; + outgoingCommand->roundTripTimeoutLimit = 0; + outgoingCommand->command.header.reliableSequenceNumber = ENET_HOST_TO_NET_16(outgoingCommand->reliableSequenceNumber); - if (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) - enet_list_insert (enet_list_end (& peer -> outgoingReliableCommands), outgoingCommand); - else - enet_list_insert (enet_list_end (& peer -> outgoingUnreliableCommands), outgoingCommand); + switch (outgoingCommand->command.header.command & ENET_PROTOCOL_COMMAND_MASK) + { + case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: + outgoingCommand->command.sendUnreliable.unreliableSequenceNumber = ENET_HOST_TO_NET_16(outgoingCommand->unreliableSequenceNumber); + break; + + case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: + outgoingCommand->command.sendUnsequenced.unsequencedGroup = ENET_HOST_TO_NET_16(peer->outgoingUnsequencedGroup); + break; + + default: + break; + } + + if (outgoingCommand->command.header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) + enet_list_insert(enet_list_end(&peer->outgoingReliableCommands), outgoingCommand); + else + enet_list_insert(enet_list_end(&peer->outgoingUnreliableCommands), outgoingCommand); } ENetOutgoingCommand * -enet_peer_queue_outgoing_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 offset, enet_uint16 length) +enet_peer_queue_outgoing_command(ENetPeer *peer, const ENetProtocol *command, ENetPacket *packet, enet_uint32 offset, enet_uint16 length) { - ENetOutgoingCommand * outgoingCommand = (ENetOutgoingCommand *) enet_malloc (sizeof (ENetOutgoingCommand)); - if (outgoingCommand == NULL) - return NULL; + ENetOutgoingCommand *outgoingCommand = (ENetOutgoingCommand *)enet_malloc(sizeof(ENetOutgoingCommand)); + if (outgoingCommand == NULL) + return NULL; - outgoingCommand -> command = * command; - outgoingCommand -> fragmentOffset = offset; - outgoingCommand -> fragmentLength = length; - outgoingCommand -> packet = packet; - if (packet != NULL) - ++ packet -> referenceCount; + outgoingCommand->command = *command; + outgoingCommand->fragmentOffset = offset; + outgoingCommand->fragmentLength = length; + outgoingCommand->packet = packet; + if (packet != NULL) + ++packet->referenceCount; - enet_peer_setup_outgoing_command (peer, outgoingCommand); + enet_peer_setup_outgoing_command(peer, outgoingCommand); - return outgoingCommand; + return outgoingCommand; } -void -enet_peer_dispatch_incoming_unreliable_commands (ENetPeer * peer, ENetChannel * channel) +void enet_peer_dispatch_incoming_unreliable_commands(ENetPeer *peer, ENetChannel *channel) { - ENetListIterator droppedCommand, startCommand, currentCommand; + ENetListIterator droppedCommand, startCommand, currentCommand; - for (droppedCommand = startCommand = currentCommand = enet_list_begin (& channel -> incomingUnreliableCommands); - currentCommand != enet_list_end (& channel -> incomingUnreliableCommands); - currentCommand = enet_list_next (currentCommand)) - { - ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; + for (droppedCommand = startCommand = currentCommand = enet_list_begin(&channel->incomingUnreliableCommands); + currentCommand != enet_list_end(&channel->incomingUnreliableCommands); + currentCommand = enet_list_next(currentCommand)) + { + ENetIncomingCommand *incomingCommand = (ENetIncomingCommand *)currentCommand; - if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED) - continue; + if ((incomingCommand->command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED) + continue; - if (incomingCommand -> reliableSequenceNumber == channel -> incomingReliableSequenceNumber) - { - if (incomingCommand -> fragmentsRemaining <= 0) - { - channel -> incomingUnreliableSequenceNumber = incomingCommand -> unreliableSequenceNumber; - continue; - } + if (incomingCommand->reliableSequenceNumber == channel->incomingReliableSequenceNumber) + { + if (incomingCommand->fragmentsRemaining <= 0) + { + channel->incomingUnreliableSequenceNumber = incomingCommand->unreliableSequenceNumber; + continue; + } - if (startCommand != currentCommand) - { - enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand)); + if (startCommand != currentCommand) + { + enet_list_move(enet_list_end(&peer->dispatchedCommands), startCommand, enet_list_previous(currentCommand)); - if (! peer -> needsDispatch) - { - enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); + if (!peer->needsDispatch) + { + enet_list_insert(enet_list_end(&peer->host->dispatchQueue), &peer->dispatchList); - peer -> needsDispatch = 1; - } + peer->needsDispatch = 1; + } - droppedCommand = currentCommand; - } - else - if (droppedCommand != currentCommand) - droppedCommand = enet_list_previous (currentCommand); - } - else - { - enet_uint16 reliableWindow = incomingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE, - currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; - if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber) - reliableWindow += ENET_PEER_RELIABLE_WINDOWS; - if (reliableWindow >= currentWindow && reliableWindow < currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) - break; + droppedCommand = currentCommand; + } + else if (droppedCommand != currentCommand) + droppedCommand = enet_list_previous(currentCommand); + } + else + { + enet_uint16 reliableWindow = incomingCommand->reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE, + currentWindow = channel->incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + if (incomingCommand->reliableSequenceNumber < channel->incomingReliableSequenceNumber) + reliableWindow += ENET_PEER_RELIABLE_WINDOWS; + if (reliableWindow >= currentWindow && reliableWindow < currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) + break; - droppedCommand = enet_list_next (currentCommand); + droppedCommand = enet_list_next(currentCommand); - if (startCommand != currentCommand) - { - enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand)); + if (startCommand != currentCommand) + { + enet_list_move(enet_list_end(&peer->dispatchedCommands), startCommand, enet_list_previous(currentCommand)); - if (! peer -> needsDispatch) - { - enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); + if (!peer->needsDispatch) + { + enet_list_insert(enet_list_end(&peer->host->dispatchQueue), &peer->dispatchList); - peer -> needsDispatch = 1; - } - } - } - - startCommand = enet_list_next (currentCommand); - } + peer->needsDispatch = 1; + } + } + } - if (startCommand != currentCommand) - { - enet_list_move (enet_list_end (& peer -> dispatchedCommands), startCommand, enet_list_previous (currentCommand)); + startCommand = enet_list_next(currentCommand); + } - if (! peer -> needsDispatch) - { - enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); + if (startCommand != currentCommand) + { + enet_list_move(enet_list_end(&peer->dispatchedCommands), startCommand, enet_list_previous(currentCommand)); - peer -> needsDispatch = 1; - } + if (!peer->needsDispatch) + { + enet_list_insert(enet_list_end(&peer->host->dispatchQueue), &peer->dispatchList); - droppedCommand = currentCommand; - } + peer->needsDispatch = 1; + } - enet_peer_remove_incoming_commands (& channel -> incomingUnreliableCommands, enet_list_begin (& channel -> incomingUnreliableCommands), droppedCommand); + droppedCommand = currentCommand; + } + + enet_peer_remove_incoming_commands(&channel->incomingUnreliableCommands, enet_list_begin(&channel->incomingUnreliableCommands), droppedCommand); } -void -enet_peer_dispatch_incoming_reliable_commands (ENetPeer * peer, ENetChannel * channel) +void enet_peer_dispatch_incoming_reliable_commands(ENetPeer *peer, ENetChannel *channel) { - ENetListIterator currentCommand; + ENetListIterator currentCommand; - for (currentCommand = enet_list_begin (& channel -> incomingReliableCommands); - currentCommand != enet_list_end (& channel -> incomingReliableCommands); - currentCommand = enet_list_next (currentCommand)) - { - ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; - - if (incomingCommand -> fragmentsRemaining > 0 || - incomingCommand -> reliableSequenceNumber != (enet_uint16) (channel -> incomingReliableSequenceNumber + 1)) - break; + for (currentCommand = enet_list_begin(&channel->incomingReliableCommands); + currentCommand != enet_list_end(&channel->incomingReliableCommands); + currentCommand = enet_list_next(currentCommand)) + { + ENetIncomingCommand *incomingCommand = (ENetIncomingCommand *)currentCommand; - channel -> incomingReliableSequenceNumber = incomingCommand -> reliableSequenceNumber; + if (incomingCommand->fragmentsRemaining > 0 || + incomingCommand->reliableSequenceNumber != (enet_uint16)(channel->incomingReliableSequenceNumber + 1)) + break; - if (incomingCommand -> fragmentCount > 0) - channel -> incomingReliableSequenceNumber += incomingCommand -> fragmentCount - 1; - } + channel->incomingReliableSequenceNumber = incomingCommand->reliableSequenceNumber; - if (currentCommand == enet_list_begin (& channel -> incomingReliableCommands)) - return; + if (incomingCommand->fragmentCount > 0) + channel->incomingReliableSequenceNumber += incomingCommand->fragmentCount - 1; + } - channel -> incomingUnreliableSequenceNumber = 0; + if (currentCommand == enet_list_begin(&channel->incomingReliableCommands)) + return; - enet_list_move (enet_list_end (& peer -> dispatchedCommands), enet_list_begin (& channel -> incomingReliableCommands), enet_list_previous (currentCommand)); + channel->incomingUnreliableSequenceNumber = 0; - if (! peer -> needsDispatch) - { - enet_list_insert (enet_list_end (& peer -> host -> dispatchQueue), & peer -> dispatchList); + enet_list_move(enet_list_end(&peer->dispatchedCommands), enet_list_begin(&channel->incomingReliableCommands), enet_list_previous(currentCommand)); - peer -> needsDispatch = 1; - } + if (!peer->needsDispatch) + { + enet_list_insert(enet_list_end(&peer->host->dispatchQueue), &peer->dispatchList); - if (! enet_list_empty (& channel -> incomingUnreliableCommands)) - enet_peer_dispatch_incoming_unreliable_commands (peer, channel); + peer->needsDispatch = 1; + } + + if (!enet_list_empty(&channel->incomingUnreliableCommands)) + enet_peer_dispatch_incoming_unreliable_commands(peer, channel); } ENetIncomingCommand * -enet_peer_queue_incoming_command (ENetPeer * peer, const ENetProtocol * command, ENetPacket * packet, enet_uint32 fragmentCount) +enet_peer_queue_incoming_command(ENetPeer *peer, const ENetProtocol *command, ENetPacket *packet, enet_uint32 fragmentCount) { - static ENetIncomingCommand dummyCommand; + static ENetIncomingCommand dummyCommand; - ENetChannel * channel = & peer -> channels [command -> header.channelID]; - enet_uint32 unreliableSequenceNumber = 0, reliableSequenceNumber = 0; - enet_uint16 reliableWindow, currentWindow; - ENetIncomingCommand * incomingCommand; - ENetListIterator currentCommand; + ENetChannel *channel = &peer->channels[command->header.channelID]; + enet_uint32 unreliableSequenceNumber = 0, reliableSequenceNumber = 0; + enet_uint16 reliableWindow, currentWindow; + ENetIncomingCommand *incomingCommand; + ENetListIterator currentCommand; - if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER) - goto freePacket; + if (peer->state == ENET_PEER_STATE_DISCONNECT_LATER) + goto freePacket; - if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED) - { - reliableSequenceNumber = command -> header.reliableSequenceNumber; - reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; - currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + if ((command->header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED) + { + reliableSequenceNumber = command->header.reliableSequenceNumber; + reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + currentWindow = channel->incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; - if (reliableSequenceNumber < channel -> incomingReliableSequenceNumber) - reliableWindow += ENET_PEER_RELIABLE_WINDOWS; + if (reliableSequenceNumber < channel->incomingReliableSequenceNumber) + reliableWindow += ENET_PEER_RELIABLE_WINDOWS; - if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) - goto freePacket; - } - - switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK) - { - case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: - case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: - if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber) - goto freePacket; - - for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands)); - currentCommand != enet_list_end (& channel -> incomingReliableCommands); - currentCommand = enet_list_previous (currentCommand)) - { - incomingCommand = (ENetIncomingCommand *) currentCommand; + if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) + goto freePacket; + } - if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) - { - if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber) - continue; - } - else - if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) - break; + switch (command->header.command & ENET_PROTOCOL_COMMAND_MASK) + { + case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: + case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: + if (reliableSequenceNumber == channel->incomingReliableSequenceNumber) + goto freePacket; - if (incomingCommand -> reliableSequenceNumber <= reliableSequenceNumber) - { - if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber) - break; + for (currentCommand = enet_list_previous(enet_list_end(&channel->incomingReliableCommands)); + currentCommand != enet_list_end(&channel->incomingReliableCommands); + currentCommand = enet_list_previous(currentCommand)) + { + incomingCommand = (ENetIncomingCommand *)currentCommand; - goto freePacket; - } - } - break; + if (reliableSequenceNumber >= channel->incomingReliableSequenceNumber) + { + if (incomingCommand->reliableSequenceNumber < channel->incomingReliableSequenceNumber) + continue; + } + else if (incomingCommand->reliableSequenceNumber >= channel->incomingReliableSequenceNumber) + break; - case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: - case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT: - unreliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendUnreliable.unreliableSequenceNumber); + if (incomingCommand->reliableSequenceNumber <= reliableSequenceNumber) + { + if (incomingCommand->reliableSequenceNumber < reliableSequenceNumber) + break; - if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber && - unreliableSequenceNumber <= channel -> incomingUnreliableSequenceNumber) - goto freePacket; + goto freePacket; + } + } + break; - for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands)); - currentCommand != enet_list_end (& channel -> incomingUnreliableCommands); - currentCommand = enet_list_previous (currentCommand)) - { - incomingCommand = (ENetIncomingCommand *) currentCommand; + case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: + case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT: + unreliableSequenceNumber = ENET_NET_TO_HOST_16(command->sendUnreliable.unreliableSequenceNumber); - if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED) - continue; + if (reliableSequenceNumber == channel->incomingReliableSequenceNumber && + unreliableSequenceNumber <= channel->incomingUnreliableSequenceNumber) + goto freePacket; - if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) - { - if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber) - continue; - } - else - if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) - break; + for (currentCommand = enet_list_previous(enet_list_end(&channel->incomingUnreliableCommands)); + currentCommand != enet_list_end(&channel->incomingUnreliableCommands); + currentCommand = enet_list_previous(currentCommand)) + { + incomingCommand = (ENetIncomingCommand *)currentCommand; - if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber) - break; + if ((command->header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED) + continue; - if (incomingCommand -> reliableSequenceNumber > reliableSequenceNumber) - continue; + if (reliableSequenceNumber >= channel->incomingReliableSequenceNumber) + { + if (incomingCommand->reliableSequenceNumber < channel->incomingReliableSequenceNumber) + continue; + } + else if (incomingCommand->reliableSequenceNumber >= channel->incomingReliableSequenceNumber) + break; - if (incomingCommand -> unreliableSequenceNumber <= unreliableSequenceNumber) - { - if (incomingCommand -> unreliableSequenceNumber < unreliableSequenceNumber) - break; + if (incomingCommand->reliableSequenceNumber < reliableSequenceNumber) + break; - goto freePacket; - } - } - break; + if (incomingCommand->reliableSequenceNumber > reliableSequenceNumber) + continue; - case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: - currentCommand = enet_list_end (& channel -> incomingUnreliableCommands); - break; + if (incomingCommand->unreliableSequenceNumber <= unreliableSequenceNumber) + { + if (incomingCommand->unreliableSequenceNumber < unreliableSequenceNumber) + break; - default: - goto freePacket; - } + goto freePacket; + } + } + break; - incomingCommand = (ENetIncomingCommand *) enet_malloc (sizeof (ENetIncomingCommand)); - if (incomingCommand == NULL) - goto notifyError; + case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: + currentCommand = enet_list_end(&channel->incomingUnreliableCommands); + break; - incomingCommand -> reliableSequenceNumber = command -> header.reliableSequenceNumber; - incomingCommand -> unreliableSequenceNumber = unreliableSequenceNumber & 0xFFFF; - incomingCommand -> command = * command; - incomingCommand -> fragmentCount = fragmentCount; - incomingCommand -> fragmentsRemaining = fragmentCount; - incomingCommand -> packet = packet; - incomingCommand -> fragments = NULL; - - if (fragmentCount > 0) - { - if (fragmentCount <= ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT) - incomingCommand -> fragments = (enet_uint32 *) enet_malloc ((fragmentCount + 31) / 32 * sizeof (enet_uint32)); - if (incomingCommand -> fragments == NULL) - { - enet_free (incomingCommand); + default: + goto freePacket; + } - goto notifyError; - } - memset (incomingCommand -> fragments, 0, (fragmentCount + 31) / 32 * sizeof (enet_uint32)); - } + incomingCommand = (ENetIncomingCommand *)enet_malloc(sizeof(ENetIncomingCommand)); + if (incomingCommand == NULL) + goto notifyError; - if (packet != NULL) - ++ packet -> referenceCount; + incomingCommand->reliableSequenceNumber = command->header.reliableSequenceNumber; + incomingCommand->unreliableSequenceNumber = unreliableSequenceNumber & 0xFFFF; + incomingCommand->command = *command; + incomingCommand->fragmentCount = fragmentCount; + incomingCommand->fragmentsRemaining = fragmentCount; + incomingCommand->packet = packet; + incomingCommand->fragments = NULL; - enet_list_insert (enet_list_next (currentCommand), incomingCommand); + if (fragmentCount > 0) + { + if (fragmentCount <= ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT) + incomingCommand->fragments = (enet_uint32 *)enet_malloc((fragmentCount + 31) / 32 * sizeof(enet_uint32)); + if (incomingCommand->fragments == NULL) + { + enet_free(incomingCommand); - switch (command -> header.command & ENET_PROTOCOL_COMMAND_MASK) - { - case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: - case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: - enet_peer_dispatch_incoming_reliable_commands (peer, channel); - break; + goto notifyError; + } + memset(incomingCommand->fragments, 0, (fragmentCount + 31) / 32 * sizeof(enet_uint32)); + } - default: - enet_peer_dispatch_incoming_unreliable_commands (peer, channel); - break; - } + if (packet != NULL) + ++packet->referenceCount; - return incomingCommand; + enet_list_insert(enet_list_next(currentCommand), incomingCommand); + + switch (command->header.command & ENET_PROTOCOL_COMMAND_MASK) + { + case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: + case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: + enet_peer_dispatch_incoming_reliable_commands(peer, channel); + break; + + default: + enet_peer_dispatch_incoming_unreliable_commands(peer, channel); + break; + } + + return incomingCommand; freePacket: - if (fragmentCount > 0) - goto notifyError; + if (fragmentCount > 0) + goto notifyError; - if (packet != NULL && packet -> referenceCount == 0) - enet_packet_destroy (packet); + if (packet != NULL && packet->referenceCount == 0) + enet_packet_destroy(packet); - return & dummyCommand; + return &dummyCommand; notifyError: - if (packet != NULL && packet -> referenceCount == 0) - enet_packet_destroy (packet); + if (packet != NULL && packet->referenceCount == 0) + enet_packet_destroy(packet); - return NULL; + return NULL; } /** @} */ diff --git a/examples/ThirdPartyLibs/enet/protocol.c b/examples/ThirdPartyLibs/enet/protocol.c index d6cc33a49..3de4f889a 100644 --- a/examples/ThirdPartyLibs/enet/protocol.c +++ b/examples/ThirdPartyLibs/enet/protocol.c @@ -9,1734 +9,1720 @@ #include "enet/time.h" #include "enet/enet.h" -static size_t commandSizes [ENET_PROTOCOL_COMMAND_COUNT] = -{ - 0, - sizeof (ENetProtocolAcknowledge), - sizeof (ENetProtocolConnect), - sizeof (ENetProtocolVerifyConnect), - sizeof (ENetProtocolDisconnect), - sizeof (ENetProtocolPing), - sizeof (ENetProtocolSendReliable), - sizeof (ENetProtocolSendUnreliable), - sizeof (ENetProtocolSendFragment), - sizeof (ENetProtocolSendUnsequenced), - sizeof (ENetProtocolBandwidthLimit), - sizeof (ENetProtocolThrottleConfigure), - sizeof (ENetProtocolSendFragment) -}; +static size_t commandSizes[ENET_PROTOCOL_COMMAND_COUNT] = + { + 0, + sizeof(ENetProtocolAcknowledge), + sizeof(ENetProtocolConnect), + sizeof(ENetProtocolVerifyConnect), + sizeof(ENetProtocolDisconnect), + sizeof(ENetProtocolPing), + sizeof(ENetProtocolSendReliable), + sizeof(ENetProtocolSendUnreliable), + sizeof(ENetProtocolSendFragment), + sizeof(ENetProtocolSendUnsequenced), + sizeof(ENetProtocolBandwidthLimit), + sizeof(ENetProtocolThrottleConfigure), + sizeof(ENetProtocolSendFragment)}; size_t -enet_protocol_command_size (enet_uint8 commandNumber) +enet_protocol_command_size(enet_uint8 commandNumber) { - return commandSizes [commandNumber & ENET_PROTOCOL_COMMAND_MASK]; + return commandSizes[commandNumber & ENET_PROTOCOL_COMMAND_MASK]; } static int -enet_protocol_dispatch_incoming_commands (ENetHost * host, ENetEvent * event) +enet_protocol_dispatch_incoming_commands(ENetHost *host, ENetEvent *event) { - while (! enet_list_empty (& host -> dispatchQueue)) - { - ENetPeer * peer = (ENetPeer *) enet_list_remove (enet_list_begin (& host -> dispatchQueue)); + while (!enet_list_empty(&host->dispatchQueue)) + { + ENetPeer *peer = (ENetPeer *)enet_list_remove(enet_list_begin(&host->dispatchQueue)); - peer -> needsDispatch = 0; + peer->needsDispatch = 0; - switch (peer -> state) - { - case ENET_PEER_STATE_CONNECTION_PENDING: - case ENET_PEER_STATE_CONNECTION_SUCCEEDED: - peer -> state = ENET_PEER_STATE_CONNECTED; + switch (peer->state) + { + case ENET_PEER_STATE_CONNECTION_PENDING: + case ENET_PEER_STATE_CONNECTION_SUCCEEDED: + peer->state = ENET_PEER_STATE_CONNECTED; - event -> type = ENET_EVENT_TYPE_CONNECT; - event -> peer = peer; - event -> data = peer -> eventData; + event->type = ENET_EVENT_TYPE_CONNECT; + event->peer = peer; + event->data = peer->eventData; - return 1; - - case ENET_PEER_STATE_ZOMBIE: - host -> recalculateBandwidthLimits = 1; + return 1; - event -> type = ENET_EVENT_TYPE_DISCONNECT; - event -> peer = peer; - event -> data = peer -> eventData; + case ENET_PEER_STATE_ZOMBIE: + host->recalculateBandwidthLimits = 1; - enet_peer_reset (peer); + event->type = ENET_EVENT_TYPE_DISCONNECT; + event->peer = peer; + event->data = peer->eventData; - return 1; + enet_peer_reset(peer); - case ENET_PEER_STATE_CONNECTED: - if (enet_list_empty (& peer -> dispatchedCommands)) - continue; + return 1; - event -> packet = enet_peer_receive (peer, & event -> channelID); - if (event -> packet == NULL) - continue; - - event -> type = ENET_EVENT_TYPE_RECEIVE; - event -> peer = peer; + case ENET_PEER_STATE_CONNECTED: + if (enet_list_empty(&peer->dispatchedCommands)) + continue; - if (! enet_list_empty (& peer -> dispatchedCommands)) - { - peer -> needsDispatch = 1; - - enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList); - } + event->packet = enet_peer_receive(peer, &event->channelID); + if (event->packet == NULL) + continue; - return 1; + event->type = ENET_EVENT_TYPE_RECEIVE; + event->peer = peer; - default: - break; - } - } + if (!enet_list_empty(&peer->dispatchedCommands)) + { + peer->needsDispatch = 1; - return 0; + enet_list_insert(enet_list_end(&host->dispatchQueue), &peer->dispatchList); + } + + return 1; + + default: + break; + } + } + + return 0; } static void -enet_protocol_dispatch_state (ENetHost * host, ENetPeer * peer, ENetPeerState state) +enet_protocol_dispatch_state(ENetHost *host, ENetPeer *peer, ENetPeerState state) { - peer -> state = state; + peer->state = state; - if (! peer -> needsDispatch) - { - enet_list_insert (enet_list_end (& host -> dispatchQueue), & peer -> dispatchList); + if (!peer->needsDispatch) + { + enet_list_insert(enet_list_end(&host->dispatchQueue), &peer->dispatchList); - peer -> needsDispatch = 1; - } -} - -static void -enet_protocol_notify_connect (ENetHost * host, ENetPeer * peer, ENetEvent * event) -{ - host -> recalculateBandwidthLimits = 1; - - if (event != NULL) - { - peer -> state = ENET_PEER_STATE_CONNECTED; - - event -> type = ENET_EVENT_TYPE_CONNECT; - event -> peer = peer; - event -> data = peer -> eventData; - } - else - enet_protocol_dispatch_state (host, peer, peer -> state == ENET_PEER_STATE_CONNECTING ? ENET_PEER_STATE_CONNECTION_SUCCEEDED : ENET_PEER_STATE_CONNECTION_PENDING); + peer->needsDispatch = 1; + } } static void -enet_protocol_notify_disconnect (ENetHost * host, ENetPeer * peer, ENetEvent * event) +enet_protocol_notify_connect(ENetHost *host, ENetPeer *peer, ENetEvent *event) { - if (peer -> state >= ENET_PEER_STATE_CONNECTION_PENDING) - host -> recalculateBandwidthLimits = 1; + host->recalculateBandwidthLimits = 1; - if (peer -> state != ENET_PEER_STATE_CONNECTING && peer -> state < ENET_PEER_STATE_CONNECTION_SUCCEEDED) - enet_peer_reset (peer); - else - if (event != NULL) - { - event -> type = ENET_EVENT_TYPE_DISCONNECT; - event -> peer = peer; - event -> data = 0; + if (event != NULL) + { + peer->state = ENET_PEER_STATE_CONNECTED; - enet_peer_reset (peer); - } - else - { - peer -> eventData = 0; - - enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); - } + event->type = ENET_EVENT_TYPE_CONNECT; + event->peer = peer; + event->data = peer->eventData; + } + else + enet_protocol_dispatch_state(host, peer, peer->state == ENET_PEER_STATE_CONNECTING ? ENET_PEER_STATE_CONNECTION_SUCCEEDED : ENET_PEER_STATE_CONNECTION_PENDING); } static void -enet_protocol_remove_sent_unreliable_commands (ENetPeer * peer) +enet_protocol_notify_disconnect(ENetHost *host, ENetPeer *peer, ENetEvent *event) { - ENetOutgoingCommand * outgoingCommand; + if (peer->state >= ENET_PEER_STATE_CONNECTION_PENDING) + host->recalculateBandwidthLimits = 1; - while (! enet_list_empty (& peer -> sentUnreliableCommands)) - { - outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentUnreliableCommands); - - enet_list_remove (& outgoingCommand -> outgoingCommandList); + if (peer->state != ENET_PEER_STATE_CONNECTING && peer->state < ENET_PEER_STATE_CONNECTION_SUCCEEDED) + enet_peer_reset(peer); + else if (event != NULL) + { + event->type = ENET_EVENT_TYPE_DISCONNECT; + event->peer = peer; + event->data = 0; - if (outgoingCommand -> packet != NULL) - { - -- outgoingCommand -> packet -> referenceCount; + enet_peer_reset(peer); + } + else + { + peer->eventData = 0; - if (outgoingCommand -> packet -> referenceCount == 0) - { - outgoingCommand -> packet -> flags |= ENET_PACKET_FLAG_SENT; - - enet_packet_destroy (outgoingCommand -> packet); - } - } + enet_protocol_dispatch_state(host, peer, ENET_PEER_STATE_ZOMBIE); + } +} - enet_free (outgoingCommand); - } +static void +enet_protocol_remove_sent_unreliable_commands(ENetPeer *peer) +{ + ENetOutgoingCommand *outgoingCommand; + + while (!enet_list_empty(&peer->sentUnreliableCommands)) + { + outgoingCommand = (ENetOutgoingCommand *)enet_list_front(&peer->sentUnreliableCommands); + + enet_list_remove(&outgoingCommand->outgoingCommandList); + + if (outgoingCommand->packet != NULL) + { + --outgoingCommand->packet->referenceCount; + + if (outgoingCommand->packet->referenceCount == 0) + { + outgoingCommand->packet->flags |= ENET_PACKET_FLAG_SENT; + + enet_packet_destroy(outgoingCommand->packet); + } + } + + enet_free(outgoingCommand); + } } static ENetProtocolCommand -enet_protocol_remove_sent_reliable_command (ENetPeer * peer, enet_uint16 reliableSequenceNumber, enet_uint8 channelID) +enet_protocol_remove_sent_reliable_command(ENetPeer *peer, enet_uint16 reliableSequenceNumber, enet_uint8 channelID) { - ENetOutgoingCommand * outgoingCommand = NULL; - ENetListIterator currentCommand; - ENetProtocolCommand commandNumber; - int wasSent = 1; + ENetOutgoingCommand *outgoingCommand = NULL; + ENetListIterator currentCommand; + ENetProtocolCommand commandNumber; + int wasSent = 1; - for (currentCommand = enet_list_begin (& peer -> sentReliableCommands); - currentCommand != enet_list_end (& peer -> sentReliableCommands); - currentCommand = enet_list_next (currentCommand)) - { - outgoingCommand = (ENetOutgoingCommand *) currentCommand; - - if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber && - outgoingCommand -> command.header.channelID == channelID) - break; - } + for (currentCommand = enet_list_begin(&peer->sentReliableCommands); + currentCommand != enet_list_end(&peer->sentReliableCommands); + currentCommand = enet_list_next(currentCommand)) + { + outgoingCommand = (ENetOutgoingCommand *)currentCommand; - if (currentCommand == enet_list_end (& peer -> sentReliableCommands)) - { - for (currentCommand = enet_list_begin (& peer -> outgoingReliableCommands); - currentCommand != enet_list_end (& peer -> outgoingReliableCommands); - currentCommand = enet_list_next (currentCommand)) - { - outgoingCommand = (ENetOutgoingCommand *) currentCommand; + if (outgoingCommand->reliableSequenceNumber == reliableSequenceNumber && + outgoingCommand->command.header.channelID == channelID) + break; + } - if (outgoingCommand -> sendAttempts < 1) return ENET_PROTOCOL_COMMAND_NONE; + if (currentCommand == enet_list_end(&peer->sentReliableCommands)) + { + for (currentCommand = enet_list_begin(&peer->outgoingReliableCommands); + currentCommand != enet_list_end(&peer->outgoingReliableCommands); + currentCommand = enet_list_next(currentCommand)) + { + outgoingCommand = (ENetOutgoingCommand *)currentCommand; - if (outgoingCommand -> reliableSequenceNumber == reliableSequenceNumber && - outgoingCommand -> command.header.channelID == channelID) - break; - } + if (outgoingCommand->sendAttempts < 1) return ENET_PROTOCOL_COMMAND_NONE; - if (currentCommand == enet_list_end (& peer -> outgoingReliableCommands)) - return ENET_PROTOCOL_COMMAND_NONE; + if (outgoingCommand->reliableSequenceNumber == reliableSequenceNumber && + outgoingCommand->command.header.channelID == channelID) + break; + } - wasSent = 0; - } + if (currentCommand == enet_list_end(&peer->outgoingReliableCommands)) + return ENET_PROTOCOL_COMMAND_NONE; - if (outgoingCommand == NULL) - return ENET_PROTOCOL_COMMAND_NONE; + wasSent = 0; + } - if (channelID < peer -> channelCount) - { - ENetChannel * channel = & peer -> channels [channelID]; - enet_uint16 reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; - if (channel -> reliableWindows [reliableWindow] > 0) - { - -- channel -> reliableWindows [reliableWindow]; - if (! channel -> reliableWindows [reliableWindow]) - channel -> usedReliableWindows &= ~ (1 << reliableWindow); - } - } + if (outgoingCommand == NULL) + return ENET_PROTOCOL_COMMAND_NONE; - commandNumber = (ENetProtocolCommand) (outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK); - - enet_list_remove (& outgoingCommand -> outgoingCommandList); + if (channelID < peer->channelCount) + { + ENetChannel *channel = &peer->channels[channelID]; + enet_uint16 reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + if (channel->reliableWindows[reliableWindow] > 0) + { + --channel->reliableWindows[reliableWindow]; + if (!channel->reliableWindows[reliableWindow]) + channel->usedReliableWindows &= ~(1 << reliableWindow); + } + } - if (outgoingCommand -> packet != NULL) - { - if (wasSent) - peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength; + commandNumber = (ENetProtocolCommand)(outgoingCommand->command.header.command & ENET_PROTOCOL_COMMAND_MASK); - -- outgoingCommand -> packet -> referenceCount; + enet_list_remove(&outgoingCommand->outgoingCommandList); - if (outgoingCommand -> packet -> referenceCount == 0) - { - outgoingCommand -> packet -> flags |= ENET_PACKET_FLAG_SENT; + if (outgoingCommand->packet != NULL) + { + if (wasSent) + peer->reliableDataInTransit -= outgoingCommand->fragmentLength; - enet_packet_destroy (outgoingCommand -> packet); - } - } + --outgoingCommand->packet->referenceCount; - enet_free (outgoingCommand); + if (outgoingCommand->packet->referenceCount == 0) + { + outgoingCommand->packet->flags |= ENET_PACKET_FLAG_SENT; - if (enet_list_empty (& peer -> sentReliableCommands)) - return commandNumber; - - outgoingCommand = (ENetOutgoingCommand *) enet_list_front (& peer -> sentReliableCommands); - - peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout; + enet_packet_destroy(outgoingCommand->packet); + } + } - return commandNumber; -} + enet_free(outgoingCommand); + + if (enet_list_empty(&peer->sentReliableCommands)) + return commandNumber; + + outgoingCommand = (ENetOutgoingCommand *)enet_list_front(&peer->sentReliableCommands); + + peer->nextTimeout = outgoingCommand->sentTime + outgoingCommand->roundTripTimeout; + + return commandNumber; +} static ENetPeer * -enet_protocol_handle_connect (ENetHost * host, ENetProtocolHeader * header, ENetProtocol * command) +enet_protocol_handle_connect(ENetHost *host, ENetProtocolHeader *header, ENetProtocol *command) { - enet_uint8 incomingSessionID, outgoingSessionID; - enet_uint32 mtu, windowSize; - ENetChannel * channel; - size_t channelCount; - ENetPeer * currentPeer; - ENetProtocol verifyCommand; + enet_uint8 incomingSessionID, outgoingSessionID; + enet_uint32 mtu, windowSize; + ENetChannel *channel; + size_t channelCount; + ENetPeer *currentPeer; + ENetProtocol verifyCommand; - channelCount = ENET_NET_TO_HOST_32 (command -> connect.channelCount); + channelCount = ENET_NET_TO_HOST_32(command->connect.channelCount); - if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || - channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) - return NULL; + if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || + channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT) + return NULL; - for (currentPeer = host -> peers; - currentPeer < & host -> peers [host -> peerCount]; - ++ currentPeer) - { - if (currentPeer -> state != ENET_PEER_STATE_DISCONNECTED && - currentPeer -> address.host == host -> receivedAddress.host && - currentPeer -> address.port == host -> receivedAddress.port && - currentPeer -> connectID == command -> connect.connectID) - return NULL; - } + for (currentPeer = host->peers; + currentPeer < &host->peers[host->peerCount]; + ++currentPeer) + { + if (currentPeer->state != ENET_PEER_STATE_DISCONNECTED && + currentPeer->address.host == host->receivedAddress.host && + currentPeer->address.port == host->receivedAddress.port && + currentPeer->connectID == command->connect.connectID) + return NULL; + } - for (currentPeer = host -> peers; - currentPeer < & host -> peers [host -> peerCount]; - ++ currentPeer) - { - if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED) - break; - } + for (currentPeer = host->peers; + currentPeer < &host->peers[host->peerCount]; + ++currentPeer) + { + if (currentPeer->state == ENET_PEER_STATE_DISCONNECTED) + break; + } - if (currentPeer >= & host -> peers [host -> peerCount]) - return NULL; + if (currentPeer >= &host->peers[host->peerCount]) + return NULL; - if (channelCount > host -> channelLimit) - channelCount = host -> channelLimit; - currentPeer -> channels = (ENetChannel *) enet_malloc (channelCount * sizeof (ENetChannel)); - if (currentPeer -> channels == NULL) - return NULL; - currentPeer -> channelCount = channelCount; - currentPeer -> state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT; - currentPeer -> connectID = command -> connect.connectID; - currentPeer -> address = host -> receivedAddress; - currentPeer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> connect.outgoingPeerID); - currentPeer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.incomingBandwidth); - currentPeer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> connect.outgoingBandwidth); - currentPeer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleInterval); - currentPeer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleAcceleration); - currentPeer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> connect.packetThrottleDeceleration); - currentPeer -> eventData = ENET_NET_TO_HOST_32 (command -> connect.data); + if (channelCount > host->channelLimit) + channelCount = host->channelLimit; + currentPeer->channels = (ENetChannel *)enet_malloc(channelCount * sizeof(ENetChannel)); + if (currentPeer->channels == NULL) + return NULL; + currentPeer->channelCount = channelCount; + currentPeer->state = ENET_PEER_STATE_ACKNOWLEDGING_CONNECT; + currentPeer->connectID = command->connect.connectID; + currentPeer->address = host->receivedAddress; + currentPeer->outgoingPeerID = ENET_NET_TO_HOST_16(command->connect.outgoingPeerID); + currentPeer->incomingBandwidth = ENET_NET_TO_HOST_32(command->connect.incomingBandwidth); + currentPeer->outgoingBandwidth = ENET_NET_TO_HOST_32(command->connect.outgoingBandwidth); + currentPeer->packetThrottleInterval = ENET_NET_TO_HOST_32(command->connect.packetThrottleInterval); + currentPeer->packetThrottleAcceleration = ENET_NET_TO_HOST_32(command->connect.packetThrottleAcceleration); + currentPeer->packetThrottleDeceleration = ENET_NET_TO_HOST_32(command->connect.packetThrottleDeceleration); + currentPeer->eventData = ENET_NET_TO_HOST_32(command->connect.data); - incomingSessionID = command -> connect.incomingSessionID == 0xFF ? currentPeer -> outgoingSessionID : command -> connect.incomingSessionID; - incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); - if (incomingSessionID == currentPeer -> outgoingSessionID) - incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); - currentPeer -> outgoingSessionID = incomingSessionID; + incomingSessionID = command->connect.incomingSessionID == 0xFF ? currentPeer->outgoingSessionID : command->connect.incomingSessionID; + incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); + if (incomingSessionID == currentPeer->outgoingSessionID) + incomingSessionID = (incomingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); + currentPeer->outgoingSessionID = incomingSessionID; - outgoingSessionID = command -> connect.outgoingSessionID == 0xFF ? currentPeer -> incomingSessionID : command -> connect.outgoingSessionID; - outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); - if (outgoingSessionID == currentPeer -> incomingSessionID) - outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); - currentPeer -> incomingSessionID = outgoingSessionID; + outgoingSessionID = command->connect.outgoingSessionID == 0xFF ? currentPeer->incomingSessionID : command->connect.outgoingSessionID; + outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); + if (outgoingSessionID == currentPeer->incomingSessionID) + outgoingSessionID = (outgoingSessionID + 1) & (ENET_PROTOCOL_HEADER_SESSION_MASK >> ENET_PROTOCOL_HEADER_SESSION_SHIFT); + currentPeer->incomingSessionID = outgoingSessionID; - for (channel = currentPeer -> channels; - channel < & currentPeer -> channels [channelCount]; - ++ channel) - { - channel -> outgoingReliableSequenceNumber = 0; - channel -> outgoingUnreliableSequenceNumber = 0; - channel -> incomingReliableSequenceNumber = 0; - channel -> incomingUnreliableSequenceNumber = 0; + for (channel = currentPeer->channels; + channel < ¤tPeer->channels[channelCount]; + ++channel) + { + channel->outgoingReliableSequenceNumber = 0; + channel->outgoingUnreliableSequenceNumber = 0; + channel->incomingReliableSequenceNumber = 0; + channel->incomingUnreliableSequenceNumber = 0; - enet_list_clear (& channel -> incomingReliableCommands); - enet_list_clear (& channel -> incomingUnreliableCommands); + enet_list_clear(&channel->incomingReliableCommands); + enet_list_clear(&channel->incomingUnreliableCommands); - channel -> usedReliableWindows = 0; - memset (channel -> reliableWindows, 0, sizeof (channel -> reliableWindows)); - } + channel->usedReliableWindows = 0; + memset(channel->reliableWindows, 0, sizeof(channel->reliableWindows)); + } - mtu = ENET_NET_TO_HOST_32 (command -> connect.mtu); + mtu = ENET_NET_TO_HOST_32(command->connect.mtu); - if (mtu < ENET_PROTOCOL_MINIMUM_MTU) - mtu = ENET_PROTOCOL_MINIMUM_MTU; - else - if (mtu > ENET_PROTOCOL_MAXIMUM_MTU) - mtu = ENET_PROTOCOL_MAXIMUM_MTU; + if (mtu < ENET_PROTOCOL_MINIMUM_MTU) + mtu = ENET_PROTOCOL_MINIMUM_MTU; + else if (mtu > ENET_PROTOCOL_MAXIMUM_MTU) + mtu = ENET_PROTOCOL_MAXIMUM_MTU; - currentPeer -> mtu = mtu; + currentPeer->mtu = mtu; - if (host -> outgoingBandwidth == 0 && - currentPeer -> incomingBandwidth == 0) - currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; - else - if (host -> outgoingBandwidth == 0 || - currentPeer -> incomingBandwidth == 0) - currentPeer -> windowSize = (ENET_MAX (host -> outgoingBandwidth, currentPeer -> incomingBandwidth) / - ENET_PEER_WINDOW_SIZE_SCALE) * - ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; - else - currentPeer -> windowSize = (ENET_MIN (host -> outgoingBandwidth, currentPeer -> incomingBandwidth) / - ENET_PEER_WINDOW_SIZE_SCALE) * - ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + if (host->outgoingBandwidth == 0 && + currentPeer->incomingBandwidth == 0) + currentPeer->windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + else if (host->outgoingBandwidth == 0 || + currentPeer->incomingBandwidth == 0) + currentPeer->windowSize = (ENET_MAX(host->outgoingBandwidth, currentPeer->incomingBandwidth) / + ENET_PEER_WINDOW_SIZE_SCALE) * + ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + else + currentPeer->windowSize = (ENET_MIN(host->outgoingBandwidth, currentPeer->incomingBandwidth) / + ENET_PEER_WINDOW_SIZE_SCALE) * + ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; - if (currentPeer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) - currentPeer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; - else - if (currentPeer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) - currentPeer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + if (currentPeer->windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) + currentPeer->windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + else if (currentPeer->windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) + currentPeer->windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; - if (host -> incomingBandwidth == 0) - windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; - else - windowSize = (host -> incomingBandwidth / ENET_PEER_WINDOW_SIZE_SCALE) * - ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + if (host->incomingBandwidth == 0) + windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + else + windowSize = (host->incomingBandwidth / ENET_PEER_WINDOW_SIZE_SCALE) * + ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; - if (windowSize > ENET_NET_TO_HOST_32 (command -> connect.windowSize)) - windowSize = ENET_NET_TO_HOST_32 (command -> connect.windowSize); + if (windowSize > ENET_NET_TO_HOST_32(command->connect.windowSize)) + windowSize = ENET_NET_TO_HOST_32(command->connect.windowSize); - if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) - windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; - else - if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) - windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) + windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + else if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) + windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; - verifyCommand.header.command = ENET_PROTOCOL_COMMAND_VERIFY_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; - verifyCommand.header.channelID = 0xFF; - verifyCommand.verifyConnect.outgoingPeerID = ENET_HOST_TO_NET_16 (currentPeer -> incomingPeerID); - verifyCommand.verifyConnect.incomingSessionID = incomingSessionID; - verifyCommand.verifyConnect.outgoingSessionID = outgoingSessionID; - verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_32 (currentPeer -> mtu); - verifyCommand.verifyConnect.windowSize = ENET_HOST_TO_NET_32 (windowSize); - verifyCommand.verifyConnect.channelCount = ENET_HOST_TO_NET_32 (channelCount); - verifyCommand.verifyConnect.incomingBandwidth = ENET_HOST_TO_NET_32 (host -> incomingBandwidth); - verifyCommand.verifyConnect.outgoingBandwidth = ENET_HOST_TO_NET_32 (host -> outgoingBandwidth); - verifyCommand.verifyConnect.packetThrottleInterval = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleInterval); - verifyCommand.verifyConnect.packetThrottleAcceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleAcceleration); - verifyCommand.verifyConnect.packetThrottleDeceleration = ENET_HOST_TO_NET_32 (currentPeer -> packetThrottleDeceleration); - verifyCommand.verifyConnect.connectID = currentPeer -> connectID; + verifyCommand.header.command = ENET_PROTOCOL_COMMAND_VERIFY_CONNECT | ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE; + verifyCommand.header.channelID = 0xFF; + verifyCommand.verifyConnect.outgoingPeerID = ENET_HOST_TO_NET_16(currentPeer->incomingPeerID); + verifyCommand.verifyConnect.incomingSessionID = incomingSessionID; + verifyCommand.verifyConnect.outgoingSessionID = outgoingSessionID; + verifyCommand.verifyConnect.mtu = ENET_HOST_TO_NET_32(currentPeer->mtu); + verifyCommand.verifyConnect.windowSize = ENET_HOST_TO_NET_32(windowSize); + verifyCommand.verifyConnect.channelCount = ENET_HOST_TO_NET_32(channelCount); + verifyCommand.verifyConnect.incomingBandwidth = ENET_HOST_TO_NET_32(host->incomingBandwidth); + verifyCommand.verifyConnect.outgoingBandwidth = ENET_HOST_TO_NET_32(host->outgoingBandwidth); + verifyCommand.verifyConnect.packetThrottleInterval = ENET_HOST_TO_NET_32(currentPeer->packetThrottleInterval); + verifyCommand.verifyConnect.packetThrottleAcceleration = ENET_HOST_TO_NET_32(currentPeer->packetThrottleAcceleration); + verifyCommand.verifyConnect.packetThrottleDeceleration = ENET_HOST_TO_NET_32(currentPeer->packetThrottleDeceleration); + verifyCommand.verifyConnect.connectID = currentPeer->connectID; - enet_peer_queue_outgoing_command (currentPeer, & verifyCommand, NULL, 0, 0); + enet_peer_queue_outgoing_command(currentPeer, &verifyCommand, NULL, 0, 0); - return currentPeer; + return currentPeer; } static int -enet_protocol_handle_send_reliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData) +enet_protocol_handle_send_reliable(ENetHost *host, ENetPeer *peer, const ENetProtocol *command, enet_uint8 **currentData) { - ENetPacket * packet; - size_t dataLength; + ENetPacket *packet; + size_t dataLength; - if (command -> header.channelID >= peer -> channelCount || - (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)) - return -1; + if (command->header.channelID >= peer->channelCount || + (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER)) + return -1; - dataLength = ENET_NET_TO_HOST_16 (command -> sendReliable.dataLength); - * currentData += dataLength; - if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || - * currentData < host -> receivedData || - * currentData > & host -> receivedData [host -> receivedDataLength]) - return -1; + dataLength = ENET_NET_TO_HOST_16(command->sendReliable.dataLength); + *currentData += dataLength; + if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + *currentData < host->receivedData || + *currentData > &host->receivedData[host->receivedDataLength]) + return -1; - packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendReliable), - dataLength, - ENET_PACKET_FLAG_RELIABLE); - if (packet == NULL || - enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL) - return -1; + packet = enet_packet_create((const enet_uint8 *)command + sizeof(ENetProtocolSendReliable), + dataLength, + ENET_PACKET_FLAG_RELIABLE); + if (packet == NULL || + enet_peer_queue_incoming_command(peer, command, packet, 0) == NULL) + return -1; - return 0; + return 0; } static int -enet_protocol_handle_send_unsequenced (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData) +enet_protocol_handle_send_unsequenced(ENetHost *host, ENetPeer *peer, const ENetProtocol *command, enet_uint8 **currentData) { - ENetPacket * packet; - enet_uint32 unsequencedGroup, index; - size_t dataLength; + ENetPacket *packet; + enet_uint32 unsequencedGroup, index; + size_t dataLength; - if (command -> header.channelID >= peer -> channelCount || - (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)) - return -1; + if (command->header.channelID >= peer->channelCount || + (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER)) + return -1; - dataLength = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.dataLength); - * currentData += dataLength; - if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || - * currentData < host -> receivedData || - * currentData > & host -> receivedData [host -> receivedDataLength]) - return -1; + dataLength = ENET_NET_TO_HOST_16(command->sendUnsequenced.dataLength); + *currentData += dataLength; + if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + *currentData < host->receivedData || + *currentData > &host->receivedData[host->receivedDataLength]) + return -1; - unsequencedGroup = ENET_NET_TO_HOST_16 (command -> sendUnsequenced.unsequencedGroup); - index = unsequencedGroup % ENET_PEER_UNSEQUENCED_WINDOW_SIZE; - - if (unsequencedGroup < peer -> incomingUnsequencedGroup) - unsequencedGroup += 0x10000; + unsequencedGroup = ENET_NET_TO_HOST_16(command->sendUnsequenced.unsequencedGroup); + index = unsequencedGroup % ENET_PEER_UNSEQUENCED_WINDOW_SIZE; - if (unsequencedGroup >= (enet_uint32) peer -> incomingUnsequencedGroup + ENET_PEER_FREE_UNSEQUENCED_WINDOWS * ENET_PEER_UNSEQUENCED_WINDOW_SIZE) - return 0; + if (unsequencedGroup < peer->incomingUnsequencedGroup) + unsequencedGroup += 0x10000; - unsequencedGroup &= 0xFFFF; + if (unsequencedGroup >= (enet_uint32)peer->incomingUnsequencedGroup + ENET_PEER_FREE_UNSEQUENCED_WINDOWS * ENET_PEER_UNSEQUENCED_WINDOW_SIZE) + return 0; - if (unsequencedGroup - index != peer -> incomingUnsequencedGroup) - { - peer -> incomingUnsequencedGroup = unsequencedGroup - index; + unsequencedGroup &= 0xFFFF; - memset (peer -> unsequencedWindow, 0, sizeof (peer -> unsequencedWindow)); - } - else - if (peer -> unsequencedWindow [index / 32] & (1 << (index % 32))) - return 0; - - packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnsequenced), - dataLength, - ENET_PACKET_FLAG_UNSEQUENCED); - if (packet == NULL || - enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL) - return -1; - - peer -> unsequencedWindow [index / 32] |= 1 << (index % 32); - - return 0; + if (unsequencedGroup - index != peer->incomingUnsequencedGroup) + { + peer->incomingUnsequencedGroup = unsequencedGroup - index; + + memset(peer->unsequencedWindow, 0, sizeof(peer->unsequencedWindow)); + } + else if (peer->unsequencedWindow[index / 32] & (1 << (index % 32))) + return 0; + + packet = enet_packet_create((const enet_uint8 *)command + sizeof(ENetProtocolSendUnsequenced), + dataLength, + ENET_PACKET_FLAG_UNSEQUENCED); + if (packet == NULL || + enet_peer_queue_incoming_command(peer, command, packet, 0) == NULL) + return -1; + + peer->unsequencedWindow[index / 32] |= 1 << (index % 32); + + return 0; } static int -enet_protocol_handle_send_unreliable (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData) +enet_protocol_handle_send_unreliable(ENetHost *host, ENetPeer *peer, const ENetProtocol *command, enet_uint8 **currentData) { - ENetPacket * packet; - size_t dataLength; + ENetPacket *packet; + size_t dataLength; - if (command -> header.channelID >= peer -> channelCount || - (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)) - return -1; + if (command->header.channelID >= peer->channelCount || + (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER)) + return -1; - dataLength = ENET_NET_TO_HOST_16 (command -> sendUnreliable.dataLength); - * currentData += dataLength; - if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || - * currentData < host -> receivedData || - * currentData > & host -> receivedData [host -> receivedDataLength]) - return -1; + dataLength = ENET_NET_TO_HOST_16(command->sendUnreliable.dataLength); + *currentData += dataLength; + if (dataLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + *currentData < host->receivedData || + *currentData > &host->receivedData[host->receivedDataLength]) + return -1; - packet = enet_packet_create ((const enet_uint8 *) command + sizeof (ENetProtocolSendUnreliable), - dataLength, - 0); - if (packet == NULL || - enet_peer_queue_incoming_command (peer, command, packet, 0) == NULL) - return -1; + packet = enet_packet_create((const enet_uint8 *)command + sizeof(ENetProtocolSendUnreliable), + dataLength, + 0); + if (packet == NULL || + enet_peer_queue_incoming_command(peer, command, packet, 0) == NULL) + return -1; - return 0; + return 0; } static int -enet_protocol_handle_send_fragment (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData) +enet_protocol_handle_send_fragment(ENetHost *host, ENetPeer *peer, const ENetProtocol *command, enet_uint8 **currentData) { - enet_uint32 fragmentNumber, - fragmentCount, - fragmentOffset, - fragmentLength, - startSequenceNumber, - totalLength; - ENetChannel * channel; - enet_uint16 startWindow, currentWindow; - ENetListIterator currentCommand; - ENetIncomingCommand * startCommand = NULL; + enet_uint32 fragmentNumber, + fragmentCount, + fragmentOffset, + fragmentLength, + startSequenceNumber, + totalLength; + ENetChannel *channel; + enet_uint16 startWindow, currentWindow; + ENetListIterator currentCommand; + ENetIncomingCommand *startCommand = NULL; - if (command -> header.channelID >= peer -> channelCount || - (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)) - return -1; + if (command->header.channelID >= peer->channelCount || + (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER)) + return -1; - fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength); - * currentData += fragmentLength; - if (fragmentLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || - * currentData < host -> receivedData || - * currentData > & host -> receivedData [host -> receivedDataLength]) - return -1; + fragmentLength = ENET_NET_TO_HOST_16(command->sendFragment.dataLength); + *currentData += fragmentLength; + if (fragmentLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + *currentData < host->receivedData || + *currentData > &host->receivedData[host->receivedDataLength]) + return -1; - channel = & peer -> channels [command -> header.channelID]; - startSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendFragment.startSequenceNumber); - startWindow = startSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; - currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + channel = &peer->channels[command->header.channelID]; + startSequenceNumber = ENET_NET_TO_HOST_16(command->sendFragment.startSequenceNumber); + startWindow = startSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + currentWindow = channel->incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; - if (startSequenceNumber < channel -> incomingReliableSequenceNumber) - startWindow += ENET_PEER_RELIABLE_WINDOWS; + if (startSequenceNumber < channel->incomingReliableSequenceNumber) + startWindow += ENET_PEER_RELIABLE_WINDOWS; - if (startWindow < currentWindow || startWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) - return 0; + if (startWindow < currentWindow || startWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) + return 0; - fragmentNumber = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentNumber); - fragmentCount = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentCount); - fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset); - totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength); - - if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT || - fragmentNumber >= fragmentCount || - totalLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || - fragmentOffset >= totalLength || - fragmentLength > totalLength - fragmentOffset) - return -1; - - for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingReliableCommands)); - currentCommand != enet_list_end (& channel -> incomingReliableCommands); - currentCommand = enet_list_previous (currentCommand)) - { - ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; + fragmentNumber = ENET_NET_TO_HOST_32(command->sendFragment.fragmentNumber); + fragmentCount = ENET_NET_TO_HOST_32(command->sendFragment.fragmentCount); + fragmentOffset = ENET_NET_TO_HOST_32(command->sendFragment.fragmentOffset); + totalLength = ENET_NET_TO_HOST_32(command->sendFragment.totalLength); - if (startSequenceNumber >= channel -> incomingReliableSequenceNumber) - { - if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber) - continue; - } - else - if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) - break; + if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT || + fragmentNumber >= fragmentCount || + totalLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + fragmentOffset >= totalLength || + fragmentLength > totalLength - fragmentOffset) + return -1; - if (incomingCommand -> reliableSequenceNumber <= startSequenceNumber) - { - if (incomingCommand -> reliableSequenceNumber < startSequenceNumber) - break; - - if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_FRAGMENT || - totalLength != incomingCommand -> packet -> dataLength || - fragmentCount != incomingCommand -> fragmentCount) - return -1; + for (currentCommand = enet_list_previous(enet_list_end(&channel->incomingReliableCommands)); + currentCommand != enet_list_end(&channel->incomingReliableCommands); + currentCommand = enet_list_previous(currentCommand)) + { + ENetIncomingCommand *incomingCommand = (ENetIncomingCommand *)currentCommand; - startCommand = incomingCommand; - break; - } - } - - if (startCommand == NULL) - { - ENetProtocol hostCommand = * command; - ENetPacket * packet = enet_packet_create (NULL, totalLength, ENET_PACKET_FLAG_RELIABLE); - if (packet == NULL) - return -1; + if (startSequenceNumber >= channel->incomingReliableSequenceNumber) + { + if (incomingCommand->reliableSequenceNumber < channel->incomingReliableSequenceNumber) + continue; + } + else if (incomingCommand->reliableSequenceNumber >= channel->incomingReliableSequenceNumber) + break; - hostCommand.header.reliableSequenceNumber = startSequenceNumber; + if (incomingCommand->reliableSequenceNumber <= startSequenceNumber) + { + if (incomingCommand->reliableSequenceNumber < startSequenceNumber) + break; - startCommand = enet_peer_queue_incoming_command (peer, & hostCommand, packet, fragmentCount); - if (startCommand == NULL) - return -1; - } - - if ((startCommand -> fragments [fragmentNumber / 32] & (1 << (fragmentNumber % 32))) == 0) - { - -- startCommand -> fragmentsRemaining; + if ((incomingCommand->command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_FRAGMENT || + totalLength != incomingCommand->packet->dataLength || + fragmentCount != incomingCommand->fragmentCount) + return -1; - startCommand -> fragments [fragmentNumber / 32] |= (1 << (fragmentNumber % 32)); + startCommand = incomingCommand; + break; + } + } - if (fragmentOffset + fragmentLength > startCommand -> packet -> dataLength) - fragmentLength = startCommand -> packet -> dataLength - fragmentOffset; + if (startCommand == NULL) + { + ENetProtocol hostCommand = *command; + ENetPacket *packet = enet_packet_create(NULL, totalLength, ENET_PACKET_FLAG_RELIABLE); + if (packet == NULL) + return -1; - memcpy (startCommand -> packet -> data + fragmentOffset, - (enet_uint8 *) command + sizeof (ENetProtocolSendFragment), - fragmentLength); + hostCommand.header.reliableSequenceNumber = startSequenceNumber; - if (startCommand -> fragmentsRemaining <= 0) - enet_peer_dispatch_incoming_reliable_commands (peer, channel); - } + startCommand = enet_peer_queue_incoming_command(peer, &hostCommand, packet, fragmentCount); + if (startCommand == NULL) + return -1; + } - return 0; + if ((startCommand->fragments[fragmentNumber / 32] & (1 << (fragmentNumber % 32))) == 0) + { + --startCommand->fragmentsRemaining; + + startCommand->fragments[fragmentNumber / 32] |= (1 << (fragmentNumber % 32)); + + if (fragmentOffset + fragmentLength > startCommand->packet->dataLength) + fragmentLength = startCommand->packet->dataLength - fragmentOffset; + + memcpy(startCommand->packet->data + fragmentOffset, + (enet_uint8 *)command + sizeof(ENetProtocolSendFragment), + fragmentLength); + + if (startCommand->fragmentsRemaining <= 0) + enet_peer_dispatch_incoming_reliable_commands(peer, channel); + } + + return 0; } static int -enet_protocol_handle_send_unreliable_fragment (ENetHost * host, ENetPeer * peer, const ENetProtocol * command, enet_uint8 ** currentData) +enet_protocol_handle_send_unreliable_fragment(ENetHost *host, ENetPeer *peer, const ENetProtocol *command, enet_uint8 **currentData) { - enet_uint32 fragmentNumber, - fragmentCount, - fragmentOffset, - fragmentLength, - reliableSequenceNumber, - startSequenceNumber, - totalLength; - enet_uint16 reliableWindow, currentWindow; - ENetChannel * channel; - ENetListIterator currentCommand; - ENetIncomingCommand * startCommand = NULL; + enet_uint32 fragmentNumber, + fragmentCount, + fragmentOffset, + fragmentLength, + reliableSequenceNumber, + startSequenceNumber, + totalLength; + enet_uint16 reliableWindow, currentWindow; + ENetChannel *channel; + ENetListIterator currentCommand; + ENetIncomingCommand *startCommand = NULL; - if (command -> header.channelID >= peer -> channelCount || - (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER)) - return -1; + if (command->header.channelID >= peer->channelCount || + (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER)) + return -1; - fragmentLength = ENET_NET_TO_HOST_16 (command -> sendFragment.dataLength); - * currentData += fragmentLength; - if (fragmentLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || - * currentData < host -> receivedData || - * currentData > & host -> receivedData [host -> receivedDataLength]) - return -1; + fragmentLength = ENET_NET_TO_HOST_16(command->sendFragment.dataLength); + *currentData += fragmentLength; + if (fragmentLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + *currentData < host->receivedData || + *currentData > &host->receivedData[host->receivedDataLength]) + return -1; - channel = & peer -> channels [command -> header.channelID]; - reliableSequenceNumber = command -> header.reliableSequenceNumber; - startSequenceNumber = ENET_NET_TO_HOST_16 (command -> sendFragment.startSequenceNumber); + channel = &peer->channels[command->header.channelID]; + reliableSequenceNumber = command->header.reliableSequenceNumber; + startSequenceNumber = ENET_NET_TO_HOST_16(command->sendFragment.startSequenceNumber); - reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; - currentWindow = channel -> incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + reliableWindow = reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + currentWindow = channel->incomingReliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; - if (reliableSequenceNumber < channel -> incomingReliableSequenceNumber) - reliableWindow += ENET_PEER_RELIABLE_WINDOWS; + if (reliableSequenceNumber < channel->incomingReliableSequenceNumber) + reliableWindow += ENET_PEER_RELIABLE_WINDOWS; - if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) - return 0; + if (reliableWindow < currentWindow || reliableWindow >= currentWindow + ENET_PEER_FREE_RELIABLE_WINDOWS - 1) + return 0; - if (reliableSequenceNumber == channel -> incomingReliableSequenceNumber && - startSequenceNumber <= channel -> incomingUnreliableSequenceNumber) - return 0; + if (reliableSequenceNumber == channel->incomingReliableSequenceNumber && + startSequenceNumber <= channel->incomingUnreliableSequenceNumber) + return 0; - fragmentNumber = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentNumber); - fragmentCount = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentCount); - fragmentOffset = ENET_NET_TO_HOST_32 (command -> sendFragment.fragmentOffset); - totalLength = ENET_NET_TO_HOST_32 (command -> sendFragment.totalLength); + fragmentNumber = ENET_NET_TO_HOST_32(command->sendFragment.fragmentNumber); + fragmentCount = ENET_NET_TO_HOST_32(command->sendFragment.fragmentCount); + fragmentOffset = ENET_NET_TO_HOST_32(command->sendFragment.fragmentOffset); + totalLength = ENET_NET_TO_HOST_32(command->sendFragment.totalLength); - if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT || - fragmentNumber >= fragmentCount || - totalLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || - fragmentOffset >= totalLength || - fragmentLength > totalLength - fragmentOffset) - return -1; + if (fragmentCount > ENET_PROTOCOL_MAXIMUM_FRAGMENT_COUNT || + fragmentNumber >= fragmentCount || + totalLength > ENET_PROTOCOL_MAXIMUM_PACKET_SIZE || + fragmentOffset >= totalLength || + fragmentLength > totalLength - fragmentOffset) + return -1; - for (currentCommand = enet_list_previous (enet_list_end (& channel -> incomingUnreliableCommands)); - currentCommand != enet_list_end (& channel -> incomingUnreliableCommands); - currentCommand = enet_list_previous (currentCommand)) - { - ENetIncomingCommand * incomingCommand = (ENetIncomingCommand *) currentCommand; + for (currentCommand = enet_list_previous(enet_list_end(&channel->incomingUnreliableCommands)); + currentCommand != enet_list_end(&channel->incomingUnreliableCommands); + currentCommand = enet_list_previous(currentCommand)) + { + ENetIncomingCommand *incomingCommand = (ENetIncomingCommand *)currentCommand; - if (reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) - { - if (incomingCommand -> reliableSequenceNumber < channel -> incomingReliableSequenceNumber) - continue; - } - else - if (incomingCommand -> reliableSequenceNumber >= channel -> incomingReliableSequenceNumber) - break; + if (reliableSequenceNumber >= channel->incomingReliableSequenceNumber) + { + if (incomingCommand->reliableSequenceNumber < channel->incomingReliableSequenceNumber) + continue; + } + else if (incomingCommand->reliableSequenceNumber >= channel->incomingReliableSequenceNumber) + break; - if (incomingCommand -> reliableSequenceNumber < reliableSequenceNumber) - break; + if (incomingCommand->reliableSequenceNumber < reliableSequenceNumber) + break; - if (incomingCommand -> reliableSequenceNumber > reliableSequenceNumber) - continue; + if (incomingCommand->reliableSequenceNumber > reliableSequenceNumber) + continue; - if (incomingCommand -> unreliableSequenceNumber <= startSequenceNumber) - { - if (incomingCommand -> unreliableSequenceNumber < startSequenceNumber) - break; + if (incomingCommand->unreliableSequenceNumber <= startSequenceNumber) + { + if (incomingCommand->unreliableSequenceNumber < startSequenceNumber) + break; - if ((incomingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT || - totalLength != incomingCommand -> packet -> dataLength || - fragmentCount != incomingCommand -> fragmentCount) - return -1; + if ((incomingCommand->command.header.command & ENET_PROTOCOL_COMMAND_MASK) != ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT || + totalLength != incomingCommand->packet->dataLength || + fragmentCount != incomingCommand->fragmentCount) + return -1; - startCommand = incomingCommand; - break; - } - } + startCommand = incomingCommand; + break; + } + } - if (startCommand == NULL) - { - ENetPacket * packet = enet_packet_create (NULL, totalLength, ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT); - if (packet == NULL) - return -1; + if (startCommand == NULL) + { + ENetPacket *packet = enet_packet_create(NULL, totalLength, ENET_PACKET_FLAG_UNRELIABLE_FRAGMENT); + if (packet == NULL) + return -1; - startCommand = enet_peer_queue_incoming_command (peer, command, packet, fragmentCount); - if (startCommand == NULL) - return -1; - } + startCommand = enet_peer_queue_incoming_command(peer, command, packet, fragmentCount); + if (startCommand == NULL) + return -1; + } - if ((startCommand -> fragments [fragmentNumber / 32] & (1 << (fragmentNumber % 32))) == 0) - { - -- startCommand -> fragmentsRemaining; + if ((startCommand->fragments[fragmentNumber / 32] & (1 << (fragmentNumber % 32))) == 0) + { + --startCommand->fragmentsRemaining; - startCommand -> fragments [fragmentNumber / 32] |= (1 << (fragmentNumber % 32)); + startCommand->fragments[fragmentNumber / 32] |= (1 << (fragmentNumber % 32)); - if (fragmentOffset + fragmentLength > startCommand -> packet -> dataLength) - fragmentLength = startCommand -> packet -> dataLength - fragmentOffset; + if (fragmentOffset + fragmentLength > startCommand->packet->dataLength) + fragmentLength = startCommand->packet->dataLength - fragmentOffset; - memcpy (startCommand -> packet -> data + fragmentOffset, - (enet_uint8 *) command + sizeof (ENetProtocolSendFragment), - fragmentLength); + memcpy(startCommand->packet->data + fragmentOffset, + (enet_uint8 *)command + sizeof(ENetProtocolSendFragment), + fragmentLength); - if (startCommand -> fragmentsRemaining <= 0) - enet_peer_dispatch_incoming_unreliable_commands (peer, channel); - } + if (startCommand->fragmentsRemaining <= 0) + enet_peer_dispatch_incoming_unreliable_commands(peer, channel); + } - return 0; + return 0; } static int -enet_protocol_handle_ping (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) +enet_protocol_handle_ping(ENetHost *host, ENetPeer *peer, const ENetProtocol *command) { - if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) - return -1; + if (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER) + return -1; - return 0; + return 0; } static int -enet_protocol_handle_bandwidth_limit (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) +enet_protocol_handle_bandwidth_limit(ENetHost *host, ENetPeer *peer, const ENetProtocol *command) { - if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) - return -1; + if (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER) + return -1; - peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.incomingBandwidth); - peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> bandwidthLimit.outgoingBandwidth); + peer->incomingBandwidth = ENET_NET_TO_HOST_32(command->bandwidthLimit.incomingBandwidth); + peer->outgoingBandwidth = ENET_NET_TO_HOST_32(command->bandwidthLimit.outgoingBandwidth); - if (peer -> incomingBandwidth == 0 && host -> outgoingBandwidth == 0) - peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; - else - peer -> windowSize = (ENET_MIN (peer -> incomingBandwidth, host -> outgoingBandwidth) / - ENET_PEER_WINDOW_SIZE_SCALE) * ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + if (peer->incomingBandwidth == 0 && host->outgoingBandwidth == 0) + peer->windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + else + peer->windowSize = (ENET_MIN(peer->incomingBandwidth, host->outgoingBandwidth) / + ENET_PEER_WINDOW_SIZE_SCALE) * + ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; - if (peer -> windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) - peer -> windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; - else - if (peer -> windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) - peer -> windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + if (peer->windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) + peer->windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + else if (peer->windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) + peer->windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; - return 0; + return 0; } static int -enet_protocol_handle_throttle_configure (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) +enet_protocol_handle_throttle_configure(ENetHost *host, ENetPeer *peer, const ENetProtocol *command) { - if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) - return -1; + if (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER) + return -1; - peer -> packetThrottleInterval = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleInterval); - peer -> packetThrottleAcceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleAcceleration); - peer -> packetThrottleDeceleration = ENET_NET_TO_HOST_32 (command -> throttleConfigure.packetThrottleDeceleration); + peer->packetThrottleInterval = ENET_NET_TO_HOST_32(command->throttleConfigure.packetThrottleInterval); + peer->packetThrottleAcceleration = ENET_NET_TO_HOST_32(command->throttleConfigure.packetThrottleAcceleration); + peer->packetThrottleDeceleration = ENET_NET_TO_HOST_32(command->throttleConfigure.packetThrottleDeceleration); - return 0; + return 0; } static int -enet_protocol_handle_disconnect (ENetHost * host, ENetPeer * peer, const ENetProtocol * command) +enet_protocol_handle_disconnect(ENetHost *host, ENetPeer *peer, const ENetProtocol *command) { - if (peer -> state == ENET_PEER_STATE_DISCONNECTED || peer -> state == ENET_PEER_STATE_ZOMBIE || peer -> state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT) - return 0; + if (peer->state == ENET_PEER_STATE_DISCONNECTED || peer->state == ENET_PEER_STATE_ZOMBIE || peer->state == ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT) + return 0; - enet_peer_reset_queues (peer); + enet_peer_reset_queues(peer); - if (peer -> state == ENET_PEER_STATE_CONNECTION_SUCCEEDED || peer -> state == ENET_PEER_STATE_DISCONNECTING) - enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); - else - if (peer -> state != ENET_PEER_STATE_CONNECTED && peer -> state != ENET_PEER_STATE_DISCONNECT_LATER) - { - if (peer -> state == ENET_PEER_STATE_CONNECTION_PENDING) host -> recalculateBandwidthLimits = 1; + if (peer->state == ENET_PEER_STATE_CONNECTION_SUCCEEDED || peer->state == ENET_PEER_STATE_DISCONNECTING) + enet_protocol_dispatch_state(host, peer, ENET_PEER_STATE_ZOMBIE); + else if (peer->state != ENET_PEER_STATE_CONNECTED && peer->state != ENET_PEER_STATE_DISCONNECT_LATER) + { + if (peer->state == ENET_PEER_STATE_CONNECTION_PENDING) host->recalculateBandwidthLimits = 1; - enet_peer_reset (peer); - } - else - if (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) - peer -> state = ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT; - else - enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); + enet_peer_reset(peer); + } + else if (command->header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) + peer->state = ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT; + else + enet_protocol_dispatch_state(host, peer, ENET_PEER_STATE_ZOMBIE); - if (peer -> state != ENET_PEER_STATE_DISCONNECTED) - peer -> eventData = ENET_NET_TO_HOST_32 (command -> disconnect.data); + if (peer->state != ENET_PEER_STATE_DISCONNECTED) + peer->eventData = ENET_NET_TO_HOST_32(command->disconnect.data); - return 0; + return 0; } static int -enet_protocol_handle_acknowledge (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command) +enet_protocol_handle_acknowledge(ENetHost *host, ENetEvent *event, ENetPeer *peer, const ENetProtocol *command) { - enet_uint32 roundTripTime, - receivedSentTime, - receivedReliableSequenceNumber; - ENetProtocolCommand commandNumber; + enet_uint32 roundTripTime, + receivedSentTime, + receivedReliableSequenceNumber; + ENetProtocolCommand commandNumber; - if (peer -> state == ENET_PEER_STATE_DISCONNECTED || peer -> state == ENET_PEER_STATE_ZOMBIE) - return 0; + if (peer->state == ENET_PEER_STATE_DISCONNECTED || peer->state == ENET_PEER_STATE_ZOMBIE) + return 0; - receivedSentTime = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedSentTime); - receivedSentTime |= host -> serviceTime & 0xFFFF0000; - if ((receivedSentTime & 0x8000) > (host -> serviceTime & 0x8000)) - receivedSentTime -= 0x10000; + receivedSentTime = ENET_NET_TO_HOST_16(command->acknowledge.receivedSentTime); + receivedSentTime |= host->serviceTime & 0xFFFF0000; + if ((receivedSentTime & 0x8000) > (host->serviceTime & 0x8000)) + receivedSentTime -= 0x10000; - if (ENET_TIME_LESS (host -> serviceTime, receivedSentTime)) - return 0; + if (ENET_TIME_LESS(host->serviceTime, receivedSentTime)) + return 0; - peer -> lastReceiveTime = host -> serviceTime; - peer -> earliestTimeout = 0; + peer->lastReceiveTime = host->serviceTime; + peer->earliestTimeout = 0; - roundTripTime = ENET_TIME_DIFFERENCE (host -> serviceTime, receivedSentTime); + roundTripTime = ENET_TIME_DIFFERENCE(host->serviceTime, receivedSentTime); - enet_peer_throttle (peer, roundTripTime); + enet_peer_throttle(peer, roundTripTime); - peer -> roundTripTimeVariance -= peer -> roundTripTimeVariance / 4; + peer->roundTripTimeVariance -= peer->roundTripTimeVariance / 4; - if (roundTripTime >= peer -> roundTripTime) - { - peer -> roundTripTime += (roundTripTime - peer -> roundTripTime) / 8; - peer -> roundTripTimeVariance += (roundTripTime - peer -> roundTripTime) / 4; - } - else - { - peer -> roundTripTime -= (peer -> roundTripTime - roundTripTime) / 8; - peer -> roundTripTimeVariance += (peer -> roundTripTime - roundTripTime) / 4; - } + if (roundTripTime >= peer->roundTripTime) + { + peer->roundTripTime += (roundTripTime - peer->roundTripTime) / 8; + peer->roundTripTimeVariance += (roundTripTime - peer->roundTripTime) / 4; + } + else + { + peer->roundTripTime -= (peer->roundTripTime - roundTripTime) / 8; + peer->roundTripTimeVariance += (peer->roundTripTime - roundTripTime) / 4; + } - if (peer -> roundTripTime < peer -> lowestRoundTripTime) - peer -> lowestRoundTripTime = peer -> roundTripTime; + if (peer->roundTripTime < peer->lowestRoundTripTime) + peer->lowestRoundTripTime = peer->roundTripTime; - if (peer -> roundTripTimeVariance > peer -> highestRoundTripTimeVariance) - peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance; + if (peer->roundTripTimeVariance > peer->highestRoundTripTimeVariance) + peer->highestRoundTripTimeVariance = peer->roundTripTimeVariance; - if (peer -> packetThrottleEpoch == 0 || - ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> packetThrottleEpoch) >= peer -> packetThrottleInterval) - { - peer -> lastRoundTripTime = peer -> lowestRoundTripTime; - peer -> lastRoundTripTimeVariance = peer -> highestRoundTripTimeVariance; - peer -> lowestRoundTripTime = peer -> roundTripTime; - peer -> highestRoundTripTimeVariance = peer -> roundTripTimeVariance; - peer -> packetThrottleEpoch = host -> serviceTime; - } + if (peer->packetThrottleEpoch == 0 || + ENET_TIME_DIFFERENCE(host->serviceTime, peer->packetThrottleEpoch) >= peer->packetThrottleInterval) + { + peer->lastRoundTripTime = peer->lowestRoundTripTime; + peer->lastRoundTripTimeVariance = peer->highestRoundTripTimeVariance; + peer->lowestRoundTripTime = peer->roundTripTime; + peer->highestRoundTripTimeVariance = peer->roundTripTimeVariance; + peer->packetThrottleEpoch = host->serviceTime; + } - receivedReliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> acknowledge.receivedReliableSequenceNumber); + receivedReliableSequenceNumber = ENET_NET_TO_HOST_16(command->acknowledge.receivedReliableSequenceNumber); - commandNumber = enet_protocol_remove_sent_reliable_command (peer, receivedReliableSequenceNumber, command -> header.channelID); + commandNumber = enet_protocol_remove_sent_reliable_command(peer, receivedReliableSequenceNumber, command->header.channelID); - switch (peer -> state) - { - case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT: - if (commandNumber != ENET_PROTOCOL_COMMAND_VERIFY_CONNECT) - return -1; + switch (peer->state) + { + case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT: + if (commandNumber != ENET_PROTOCOL_COMMAND_VERIFY_CONNECT) + return -1; - enet_protocol_notify_connect (host, peer, event); - break; + enet_protocol_notify_connect(host, peer, event); + break; - case ENET_PEER_STATE_DISCONNECTING: - if (commandNumber != ENET_PROTOCOL_COMMAND_DISCONNECT) - return -1; + case ENET_PEER_STATE_DISCONNECTING: + if (commandNumber != ENET_PROTOCOL_COMMAND_DISCONNECT) + return -1; - enet_protocol_notify_disconnect (host, peer, event); - break; + enet_protocol_notify_disconnect(host, peer, event); + break; - case ENET_PEER_STATE_DISCONNECT_LATER: - if (enet_list_empty (& peer -> outgoingReliableCommands) && - enet_list_empty (& peer -> outgoingUnreliableCommands) && - enet_list_empty (& peer -> sentReliableCommands)) - enet_peer_disconnect (peer, peer -> eventData); - break; + case ENET_PEER_STATE_DISCONNECT_LATER: + if (enet_list_empty(&peer->outgoingReliableCommands) && + enet_list_empty(&peer->outgoingUnreliableCommands) && + enet_list_empty(&peer->sentReliableCommands)) + enet_peer_disconnect(peer, peer->eventData); + break; - default: - break; - } - - return 0; + default: + break; + } + + return 0; } static int -enet_protocol_handle_verify_connect (ENetHost * host, ENetEvent * event, ENetPeer * peer, const ENetProtocol * command) +enet_protocol_handle_verify_connect(ENetHost *host, ENetEvent *event, ENetPeer *peer, const ENetProtocol *command) { - enet_uint32 mtu, windowSize; - size_t channelCount; + enet_uint32 mtu, windowSize; + size_t channelCount; - if (peer -> state != ENET_PEER_STATE_CONNECTING) - return 0; + if (peer->state != ENET_PEER_STATE_CONNECTING) + return 0; - channelCount = ENET_NET_TO_HOST_32 (command -> verifyConnect.channelCount); + channelCount = ENET_NET_TO_HOST_32(command->verifyConnect.channelCount); - if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT || - ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleInterval) != peer -> packetThrottleInterval || - ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleAcceleration) != peer -> packetThrottleAcceleration || - ENET_NET_TO_HOST_32 (command -> verifyConnect.packetThrottleDeceleration) != peer -> packetThrottleDeceleration || - command -> verifyConnect.connectID != peer -> connectID) - { - peer -> eventData = 0; + if (channelCount < ENET_PROTOCOL_MINIMUM_CHANNEL_COUNT || channelCount > ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT || + ENET_NET_TO_HOST_32(command->verifyConnect.packetThrottleInterval) != peer->packetThrottleInterval || + ENET_NET_TO_HOST_32(command->verifyConnect.packetThrottleAcceleration) != peer->packetThrottleAcceleration || + ENET_NET_TO_HOST_32(command->verifyConnect.packetThrottleDeceleration) != peer->packetThrottleDeceleration || + command->verifyConnect.connectID != peer->connectID) + { + peer->eventData = 0; - enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); + enet_protocol_dispatch_state(host, peer, ENET_PEER_STATE_ZOMBIE); - return -1; - } + return -1; + } - enet_protocol_remove_sent_reliable_command (peer, 1, 0xFF); - - if (channelCount < peer -> channelCount) - peer -> channelCount = channelCount; + enet_protocol_remove_sent_reliable_command(peer, 1, 0xFF); - peer -> outgoingPeerID = ENET_NET_TO_HOST_16 (command -> verifyConnect.outgoingPeerID); - peer -> incomingSessionID = command -> verifyConnect.incomingSessionID; - peer -> outgoingSessionID = command -> verifyConnect.outgoingSessionID; + if (channelCount < peer->channelCount) + peer->channelCount = channelCount; - mtu = ENET_NET_TO_HOST_32 (command -> verifyConnect.mtu); + peer->outgoingPeerID = ENET_NET_TO_HOST_16(command->verifyConnect.outgoingPeerID); + peer->incomingSessionID = command->verifyConnect.incomingSessionID; + peer->outgoingSessionID = command->verifyConnect.outgoingSessionID; - if (mtu < ENET_PROTOCOL_MINIMUM_MTU) - mtu = ENET_PROTOCOL_MINIMUM_MTU; - else - if (mtu > ENET_PROTOCOL_MAXIMUM_MTU) - mtu = ENET_PROTOCOL_MAXIMUM_MTU; + mtu = ENET_NET_TO_HOST_32(command->verifyConnect.mtu); - if (mtu < peer -> mtu) - peer -> mtu = mtu; + if (mtu < ENET_PROTOCOL_MINIMUM_MTU) + mtu = ENET_PROTOCOL_MINIMUM_MTU; + else if (mtu > ENET_PROTOCOL_MAXIMUM_MTU) + mtu = ENET_PROTOCOL_MAXIMUM_MTU; - windowSize = ENET_NET_TO_HOST_32 (command -> verifyConnect.windowSize); + if (mtu < peer->mtu) + peer->mtu = mtu; - if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) - windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; + windowSize = ENET_NET_TO_HOST_32(command->verifyConnect.windowSize); - if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) - windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; + if (windowSize < ENET_PROTOCOL_MINIMUM_WINDOW_SIZE) + windowSize = ENET_PROTOCOL_MINIMUM_WINDOW_SIZE; - if (windowSize < peer -> windowSize) - peer -> windowSize = windowSize; + if (windowSize > ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE) + windowSize = ENET_PROTOCOL_MAXIMUM_WINDOW_SIZE; - peer -> incomingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.incomingBandwidth); - peer -> outgoingBandwidth = ENET_NET_TO_HOST_32 (command -> verifyConnect.outgoingBandwidth); + if (windowSize < peer->windowSize) + peer->windowSize = windowSize; - enet_protocol_notify_connect (host, peer, event); - return 0; + peer->incomingBandwidth = ENET_NET_TO_HOST_32(command->verifyConnect.incomingBandwidth); + peer->outgoingBandwidth = ENET_NET_TO_HOST_32(command->verifyConnect.outgoingBandwidth); + + enet_protocol_notify_connect(host, peer, event); + return 0; } static int -enet_protocol_handle_incoming_commands (ENetHost * host, ENetEvent * event) +enet_protocol_handle_incoming_commands(ENetHost *host, ENetEvent *event) { - ENetProtocolHeader * header; - ENetProtocol * command; - ENetPeer * peer; - enet_uint8 * currentData; - size_t headerSize; - enet_uint16 peerID, flags; - enet_uint8 sessionID; + ENetProtocolHeader *header; + ENetProtocol *command; + ENetPeer *peer; + enet_uint8 *currentData; + size_t headerSize; + enet_uint16 peerID, flags; + enet_uint8 sessionID; - if (host -> receivedDataLength < (size_t) & ((ENetProtocolHeader *) 0) -> sentTime) - return 0; + if (host->receivedDataLength < (size_t) & ((ENetProtocolHeader *)0)->sentTime) + return 0; - header = (ENetProtocolHeader *) host -> receivedData; + header = (ENetProtocolHeader *)host->receivedData; - peerID = ENET_NET_TO_HOST_16 (header -> peerID); - sessionID = (peerID & ENET_PROTOCOL_HEADER_SESSION_MASK) >> ENET_PROTOCOL_HEADER_SESSION_SHIFT; - flags = peerID & ENET_PROTOCOL_HEADER_FLAG_MASK; - peerID &= ~ (ENET_PROTOCOL_HEADER_FLAG_MASK | ENET_PROTOCOL_HEADER_SESSION_MASK); + peerID = ENET_NET_TO_HOST_16(header->peerID); + sessionID = (peerID & ENET_PROTOCOL_HEADER_SESSION_MASK) >> ENET_PROTOCOL_HEADER_SESSION_SHIFT; + flags = peerID & ENET_PROTOCOL_HEADER_FLAG_MASK; + peerID &= ~(ENET_PROTOCOL_HEADER_FLAG_MASK | ENET_PROTOCOL_HEADER_SESSION_MASK); - headerSize = (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME ? sizeof (ENetProtocolHeader) : (size_t) & ((ENetProtocolHeader *) 0) -> sentTime); - if (host -> checksum != NULL) - headerSize += sizeof (enet_uint32); + headerSize = (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME ? sizeof(ENetProtocolHeader) : (size_t) & ((ENetProtocolHeader *)0)->sentTime); + if (host->checksum != NULL) + headerSize += sizeof(enet_uint32); - if (peerID == ENET_PROTOCOL_MAXIMUM_PEER_ID) - peer = NULL; - else - if (peerID >= host -> peerCount) - return 0; - else - { - peer = & host -> peers [peerID]; + if (peerID == ENET_PROTOCOL_MAXIMUM_PEER_ID) + peer = NULL; + else if (peerID >= host->peerCount) + return 0; + else + { + peer = &host->peers[peerID]; - if (peer -> state == ENET_PEER_STATE_DISCONNECTED || - peer -> state == ENET_PEER_STATE_ZOMBIE || - ((host -> receivedAddress.host != peer -> address.host || - host -> receivedAddress.port != peer -> address.port) && - peer -> address.host != ENET_HOST_BROADCAST) || - (peer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID && - sessionID != peer -> incomingSessionID)) - return 0; - } - - if (flags & ENET_PROTOCOL_HEADER_FLAG_COMPRESSED) - { - size_t originalSize; - if (host -> compressor.context == NULL || host -> compressor.decompress == NULL) - return 0; + if (peer->state == ENET_PEER_STATE_DISCONNECTED || + peer->state == ENET_PEER_STATE_ZOMBIE || + ((host->receivedAddress.host != peer->address.host || + host->receivedAddress.port != peer->address.port) && + peer->address.host != ENET_HOST_BROADCAST) || + (peer->outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID && + sessionID != peer->incomingSessionID)) + return 0; + } - originalSize = host -> compressor.decompress (host -> compressor.context, - host -> receivedData + headerSize, - host -> receivedDataLength - headerSize, - host -> packetData [1] + headerSize, - sizeof (host -> packetData [1]) - headerSize); - if (originalSize <= 0 || originalSize > sizeof (host -> packetData [1]) - headerSize) - return 0; + if (flags & ENET_PROTOCOL_HEADER_FLAG_COMPRESSED) + { + size_t originalSize; + if (host->compressor.context == NULL || host->compressor.decompress == NULL) + return 0; - memcpy (host -> packetData [1], header, headerSize); - host -> receivedData = host -> packetData [1]; - host -> receivedDataLength = headerSize + originalSize; - } + originalSize = host->compressor.decompress(host->compressor.context, + host->receivedData + headerSize, + host->receivedDataLength - headerSize, + host->packetData[1] + headerSize, + sizeof(host->packetData[1]) - headerSize); + if (originalSize <= 0 || originalSize > sizeof(host->packetData[1]) - headerSize) + return 0; - if (host -> checksum != NULL) - { - enet_uint32 * checksum = (enet_uint32 *) & host -> receivedData [headerSize - sizeof (enet_uint32)], - desiredChecksum = * checksum; - ENetBuffer buffer; + memcpy(host->packetData[1], header, headerSize); + host->receivedData = host->packetData[1]; + host->receivedDataLength = headerSize + originalSize; + } - * checksum = peer != NULL ? peer -> connectID : 0; + if (host->checksum != NULL) + { + enet_uint32 *checksum = (enet_uint32 *)&host->receivedData[headerSize - sizeof(enet_uint32)], + desiredChecksum = *checksum; + ENetBuffer buffer; - buffer.data = host -> receivedData; - buffer.dataLength = host -> receivedDataLength; + *checksum = peer != NULL ? peer->connectID : 0; - if (host -> checksum (& buffer, 1) != desiredChecksum) - return 0; - } - - if (peer != NULL) - { - peer -> address.host = host -> receivedAddress.host; - peer -> address.port = host -> receivedAddress.port; - peer -> incomingDataTotal += host -> receivedDataLength; - } - - currentData = host -> receivedData + headerSize; - - while (currentData < & host -> receivedData [host -> receivedDataLength]) - { - enet_uint8 commandNumber; - size_t commandSize; + buffer.data = host->receivedData; + buffer.dataLength = host->receivedDataLength; - command = (ENetProtocol *) currentData; + if (host->checksum(&buffer, 1) != desiredChecksum) + return 0; + } - if (currentData + sizeof (ENetProtocolCommandHeader) > & host -> receivedData [host -> receivedDataLength]) - break; + if (peer != NULL) + { + peer->address.host = host->receivedAddress.host; + peer->address.port = host->receivedAddress.port; + peer->incomingDataTotal += host->receivedDataLength; + } - commandNumber = command -> header.command & ENET_PROTOCOL_COMMAND_MASK; - if (commandNumber >= ENET_PROTOCOL_COMMAND_COUNT) - break; - - commandSize = commandSizes [commandNumber]; - if (commandSize == 0 || currentData + commandSize > & host -> receivedData [host -> receivedDataLength]) - break; + currentData = host->receivedData + headerSize; - currentData += commandSize; + while (currentData < &host->receivedData[host->receivedDataLength]) + { + enet_uint8 commandNumber; + size_t commandSize; - if (peer == NULL && commandNumber != ENET_PROTOCOL_COMMAND_CONNECT) - break; - - command -> header.reliableSequenceNumber = ENET_NET_TO_HOST_16 (command -> header.reliableSequenceNumber); + command = (ENetProtocol *)currentData; - switch (commandNumber) - { - case ENET_PROTOCOL_COMMAND_ACKNOWLEDGE: - if (enet_protocol_handle_acknowledge (host, event, peer, command)) - goto commandError; - break; + if (currentData + sizeof(ENetProtocolCommandHeader) > &host->receivedData[host->receivedDataLength]) + break; - case ENET_PROTOCOL_COMMAND_CONNECT: - if (peer != NULL) - goto commandError; - peer = enet_protocol_handle_connect (host, header, command); - if (peer == NULL) - goto commandError; - break; + commandNumber = command->header.command & ENET_PROTOCOL_COMMAND_MASK; + if (commandNumber >= ENET_PROTOCOL_COMMAND_COUNT) + break; - case ENET_PROTOCOL_COMMAND_VERIFY_CONNECT: - if (enet_protocol_handle_verify_connect (host, event, peer, command)) - goto commandError; - break; + commandSize = commandSizes[commandNumber]; + if (commandSize == 0 || currentData + commandSize > &host->receivedData[host->receivedDataLength]) + break; - case ENET_PROTOCOL_COMMAND_DISCONNECT: - if (enet_protocol_handle_disconnect (host, peer, command)) - goto commandError; - break; + currentData += commandSize; - case ENET_PROTOCOL_COMMAND_PING: - if (enet_protocol_handle_ping (host, peer, command)) - goto commandError; - break; + if (peer == NULL && commandNumber != ENET_PROTOCOL_COMMAND_CONNECT) + break; - case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: - if (enet_protocol_handle_send_reliable (host, peer, command, & currentData)) - goto commandError; - break; + command->header.reliableSequenceNumber = ENET_NET_TO_HOST_16(command->header.reliableSequenceNumber); - case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: - if (enet_protocol_handle_send_unreliable (host, peer, command, & currentData)) - goto commandError; - break; + switch (commandNumber) + { + case ENET_PROTOCOL_COMMAND_ACKNOWLEDGE: + if (enet_protocol_handle_acknowledge(host, event, peer, command)) + goto commandError; + break; - case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: - if (enet_protocol_handle_send_unsequenced (host, peer, command, & currentData)) - goto commandError; - break; + case ENET_PROTOCOL_COMMAND_CONNECT: + if (peer != NULL) + goto commandError; + peer = enet_protocol_handle_connect(host, header, command); + if (peer == NULL) + goto commandError; + break; - case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: - if (enet_protocol_handle_send_fragment (host, peer, command, & currentData)) - goto commandError; - break; + case ENET_PROTOCOL_COMMAND_VERIFY_CONNECT: + if (enet_protocol_handle_verify_connect(host, event, peer, command)) + goto commandError; + break; - case ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT: - if (enet_protocol_handle_bandwidth_limit (host, peer, command)) - goto commandError; - break; + case ENET_PROTOCOL_COMMAND_DISCONNECT: + if (enet_protocol_handle_disconnect(host, peer, command)) + goto commandError; + break; - case ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE: - if (enet_protocol_handle_throttle_configure (host, peer, command)) - goto commandError; - break; + case ENET_PROTOCOL_COMMAND_PING: + if (enet_protocol_handle_ping(host, peer, command)) + goto commandError; + break; - case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT: - if (enet_protocol_handle_send_unreliable_fragment (host, peer, command, & currentData)) - goto commandError; - break; + case ENET_PROTOCOL_COMMAND_SEND_RELIABLE: + if (enet_protocol_handle_send_reliable(host, peer, command, ¤tData)) + goto commandError; + break; - default: - goto commandError; - } + case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE: + if (enet_protocol_handle_send_unreliable(host, peer, command, ¤tData)) + goto commandError; + break; - if (peer != NULL && - (command -> header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) != 0) - { - enet_uint16 sentTime; + case ENET_PROTOCOL_COMMAND_SEND_UNSEQUENCED: + if (enet_protocol_handle_send_unsequenced(host, peer, command, ¤tData)) + goto commandError; + break; - if (! (flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME)) - break; + case ENET_PROTOCOL_COMMAND_SEND_FRAGMENT: + if (enet_protocol_handle_send_fragment(host, peer, command, ¤tData)) + goto commandError; + break; - sentTime = ENET_NET_TO_HOST_16 (header -> sentTime); + case ENET_PROTOCOL_COMMAND_BANDWIDTH_LIMIT: + if (enet_protocol_handle_bandwidth_limit(host, peer, command)) + goto commandError; + break; - switch (peer -> state) - { - case ENET_PEER_STATE_DISCONNECTING: - case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT: - case ENET_PEER_STATE_DISCONNECTED: - case ENET_PEER_STATE_ZOMBIE: - break; + case ENET_PROTOCOL_COMMAND_THROTTLE_CONFIGURE: + if (enet_protocol_handle_throttle_configure(host, peer, command)) + goto commandError; + break; - case ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT: - if ((command -> header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT) - enet_peer_queue_acknowledgement (peer, command, sentTime); - break; + case ENET_PROTOCOL_COMMAND_SEND_UNRELIABLE_FRAGMENT: + if (enet_protocol_handle_send_unreliable_fragment(host, peer, command, ¤tData)) + goto commandError; + break; - default: - enet_peer_queue_acknowledgement (peer, command, sentTime); - break; - } - } - } + default: + goto commandError; + } + + if (peer != NULL && + (command->header.command & ENET_PROTOCOL_COMMAND_FLAG_ACKNOWLEDGE) != 0) + { + enet_uint16 sentTime; + + if (!(flags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME)) + break; + + sentTime = ENET_NET_TO_HOST_16(header->sentTime); + + switch (peer->state) + { + case ENET_PEER_STATE_DISCONNECTING: + case ENET_PEER_STATE_ACKNOWLEDGING_CONNECT: + case ENET_PEER_STATE_DISCONNECTED: + case ENET_PEER_STATE_ZOMBIE: + break; + + case ENET_PEER_STATE_ACKNOWLEDGING_DISCONNECT: + if ((command->header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT) + enet_peer_queue_acknowledgement(peer, command, sentTime); + break; + + default: + enet_peer_queue_acknowledgement(peer, command, sentTime); + break; + } + } + } commandError: - if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE) - return 1; + if (event != NULL && event->type != ENET_EVENT_TYPE_NONE) + return 1; - return 0; + return 0; } - + static int -enet_protocol_receive_incoming_commands (ENetHost * host, ENetEvent * event) +enet_protocol_receive_incoming_commands(ENetHost *host, ENetEvent *event) { - for (;;) - { - int receivedLength; - ENetBuffer buffer; + for (;;) + { + int receivedLength; + ENetBuffer buffer; - buffer.data = host -> packetData [0]; - buffer.dataLength = sizeof (host -> packetData [0]); + buffer.data = host->packetData[0]; + buffer.dataLength = sizeof(host->packetData[0]); - receivedLength = enet_socket_receive (host -> socket, - & host -> receivedAddress, - & buffer, - 1); + receivedLength = enet_socket_receive(host->socket, + &host->receivedAddress, + &buffer, + 1); - if (receivedLength < 0) - return -1; + if (receivedLength < 0) + return -1; - if (receivedLength == 0) - return 0; + if (receivedLength == 0) + return 0; - host -> receivedData = host -> packetData [0]; - host -> receivedDataLength = receivedLength; - - host -> totalReceivedData += receivedLength; - host -> totalReceivedPackets ++; + host->receivedData = host->packetData[0]; + host->receivedDataLength = receivedLength; - if (host -> intercept != NULL) - { - switch (host -> intercept (host, event)) - { - case 1: - if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE) - return 1; + host->totalReceivedData += receivedLength; + host->totalReceivedPackets++; - continue; - - case -1: - return -1; - - default: - break; - } - } - - switch (enet_protocol_handle_incoming_commands (host, event)) - { - case 1: - return 1; - - case -1: - return -1; + if (host->intercept != NULL) + { + switch (host->intercept(host, event)) + { + case 1: + if (event != NULL && event->type != ENET_EVENT_TYPE_NONE) + return 1; - default: - break; - } - } + continue; - return -1; + case -1: + return -1; + + default: + break; + } + } + + switch (enet_protocol_handle_incoming_commands(host, event)) + { + case 1: + return 1; + + case -1: + return -1; + + default: + break; + } + } + + return -1; } static void -enet_protocol_send_acknowledgements (ENetHost * host, ENetPeer * peer) +enet_protocol_send_acknowledgements(ENetHost *host, ENetPeer *peer) { - ENetProtocol * command = & host -> commands [host -> commandCount]; - ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; - ENetAcknowledgement * acknowledgement; - ENetListIterator currentAcknowledgement; - - currentAcknowledgement = enet_list_begin (& peer -> acknowledgements); - - while (currentAcknowledgement != enet_list_end (& peer -> acknowledgements)) - { - if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || - buffer >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || - peer -> mtu - host -> packetSize < sizeof (ENetProtocolAcknowledge)) - { - host -> continueSending = 1; + ENetProtocol *command = &host->commands[host->commandCount]; + ENetBuffer *buffer = &host->buffers[host->bufferCount]; + ENetAcknowledgement *acknowledgement; + ENetListIterator currentAcknowledgement; - break; - } + currentAcknowledgement = enet_list_begin(&peer->acknowledgements); - acknowledgement = (ENetAcknowledgement *) currentAcknowledgement; - - currentAcknowledgement = enet_list_next (currentAcknowledgement); + while (currentAcknowledgement != enet_list_end(&peer->acknowledgements)) + { + if (command >= &host->commands[sizeof(host->commands) / sizeof(ENetProtocol)] || + buffer >= &host->buffers[sizeof(host->buffers) / sizeof(ENetBuffer)] || + peer->mtu - host->packetSize < sizeof(ENetProtocolAcknowledge)) + { + host->continueSending = 1; - buffer -> data = command; - buffer -> dataLength = sizeof (ENetProtocolAcknowledge); + break; + } - host -> packetSize += buffer -> dataLength; - - command -> header.command = ENET_PROTOCOL_COMMAND_ACKNOWLEDGE; - command -> header.channelID = acknowledgement -> command.header.channelID; - command -> acknowledge.receivedReliableSequenceNumber = ENET_HOST_TO_NET_16 (acknowledgement -> command.header.reliableSequenceNumber); - command -> acknowledge.receivedSentTime = ENET_HOST_TO_NET_16 (acknowledgement -> sentTime); - - if ((acknowledgement -> command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT) - enet_protocol_dispatch_state (host, peer, ENET_PEER_STATE_ZOMBIE); + acknowledgement = (ENetAcknowledgement *)currentAcknowledgement; - enet_list_remove (& acknowledgement -> acknowledgementList); - enet_free (acknowledgement); + currentAcknowledgement = enet_list_next(currentAcknowledgement); - ++ command; - ++ buffer; - } + buffer->data = command; + buffer->dataLength = sizeof(ENetProtocolAcknowledge); - host -> commandCount = command - host -> commands; - host -> bufferCount = buffer - host -> buffers; + host->packetSize += buffer->dataLength; + + command->header.command = ENET_PROTOCOL_COMMAND_ACKNOWLEDGE; + command->header.channelID = acknowledgement->command.header.channelID; + command->acknowledge.receivedReliableSequenceNumber = ENET_HOST_TO_NET_16(acknowledgement->command.header.reliableSequenceNumber); + command->acknowledge.receivedSentTime = ENET_HOST_TO_NET_16(acknowledgement->sentTime); + + if ((acknowledgement->command.header.command & ENET_PROTOCOL_COMMAND_MASK) == ENET_PROTOCOL_COMMAND_DISCONNECT) + enet_protocol_dispatch_state(host, peer, ENET_PEER_STATE_ZOMBIE); + + enet_list_remove(&acknowledgement->acknowledgementList); + enet_free(acknowledgement); + + ++command; + ++buffer; + } + + host->commandCount = command - host->commands; + host->bufferCount = buffer - host->buffers; } static void -enet_protocol_send_unreliable_outgoing_commands (ENetHost * host, ENetPeer * peer) +enet_protocol_send_unreliable_outgoing_commands(ENetHost *host, ENetPeer *peer) { - ENetProtocol * command = & host -> commands [host -> commandCount]; - ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; - ENetOutgoingCommand * outgoingCommand; - ENetListIterator currentCommand; + ENetProtocol *command = &host->commands[host->commandCount]; + ENetBuffer *buffer = &host->buffers[host->bufferCount]; + ENetOutgoingCommand *outgoingCommand; + ENetListIterator currentCommand; - currentCommand = enet_list_begin (& peer -> outgoingUnreliableCommands); - - while (currentCommand != enet_list_end (& peer -> outgoingUnreliableCommands)) - { - size_t commandSize; + currentCommand = enet_list_begin(&peer->outgoingUnreliableCommands); - outgoingCommand = (ENetOutgoingCommand *) currentCommand; - commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK]; + while (currentCommand != enet_list_end(&peer->outgoingUnreliableCommands)) + { + size_t commandSize; - if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || - buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || - peer -> mtu - host -> packetSize < commandSize || - (outgoingCommand -> packet != NULL && - peer -> mtu - host -> packetSize < commandSize + outgoingCommand -> fragmentLength)) - { - host -> continueSending = 1; + outgoingCommand = (ENetOutgoingCommand *)currentCommand; + commandSize = commandSizes[outgoingCommand->command.header.command & ENET_PROTOCOL_COMMAND_MASK]; - break; - } + if (command >= &host->commands[sizeof(host->commands) / sizeof(ENetProtocol)] || + buffer + 1 >= &host->buffers[sizeof(host->buffers) / sizeof(ENetBuffer)] || + peer->mtu - host->packetSize < commandSize || + (outgoingCommand->packet != NULL && + peer->mtu - host->packetSize < commandSize + outgoingCommand->fragmentLength)) + { + host->continueSending = 1; - currentCommand = enet_list_next (currentCommand); + break; + } - if (outgoingCommand -> packet != NULL && outgoingCommand -> fragmentOffset == 0) - { - peer -> packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER; - peer -> packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE; - - if (peer -> packetThrottleCounter > peer -> packetThrottle) - { - enet_uint16 reliableSequenceNumber = outgoingCommand -> reliableSequenceNumber, - unreliableSequenceNumber = outgoingCommand -> unreliableSequenceNumber; - for (;;) - { - -- outgoingCommand -> packet -> referenceCount; + currentCommand = enet_list_next(currentCommand); - if (outgoingCommand -> packet -> referenceCount == 0) - enet_packet_destroy (outgoingCommand -> packet); - - enet_list_remove (& outgoingCommand -> outgoingCommandList); - enet_free (outgoingCommand); + if (outgoingCommand->packet != NULL && outgoingCommand->fragmentOffset == 0) + { + peer->packetThrottleCounter += ENET_PEER_PACKET_THROTTLE_COUNTER; + peer->packetThrottleCounter %= ENET_PEER_PACKET_THROTTLE_SCALE; - if (currentCommand == enet_list_end (& peer -> outgoingUnreliableCommands)) - break; + if (peer->packetThrottleCounter > peer->packetThrottle) + { + enet_uint16 reliableSequenceNumber = outgoingCommand->reliableSequenceNumber, + unreliableSequenceNumber = outgoingCommand->unreliableSequenceNumber; + for (;;) + { + --outgoingCommand->packet->referenceCount; - outgoingCommand = (ENetOutgoingCommand *) currentCommand; - if (outgoingCommand -> reliableSequenceNumber != reliableSequenceNumber || - outgoingCommand -> unreliableSequenceNumber != unreliableSequenceNumber) - break; + if (outgoingCommand->packet->referenceCount == 0) + enet_packet_destroy(outgoingCommand->packet); - currentCommand = enet_list_next (currentCommand); - } - - continue; - } - } + enet_list_remove(&outgoingCommand->outgoingCommandList); + enet_free(outgoingCommand); - buffer -> data = command; - buffer -> dataLength = commandSize; - - host -> packetSize += buffer -> dataLength; + if (currentCommand == enet_list_end(&peer->outgoingUnreliableCommands)) + break; - * command = outgoingCommand -> command; - - enet_list_remove (& outgoingCommand -> outgoingCommandList); + outgoingCommand = (ENetOutgoingCommand *)currentCommand; + if (outgoingCommand->reliableSequenceNumber != reliableSequenceNumber || + outgoingCommand->unreliableSequenceNumber != unreliableSequenceNumber) + break; - if (outgoingCommand -> packet != NULL) - { - ++ buffer; - - buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset; - buffer -> dataLength = outgoingCommand -> fragmentLength; + currentCommand = enet_list_next(currentCommand); + } - host -> packetSize += buffer -> dataLength; + continue; + } + } - enet_list_insert (enet_list_end (& peer -> sentUnreliableCommands), outgoingCommand); - } - else - enet_free (outgoingCommand); + buffer->data = command; + buffer->dataLength = commandSize; - ++ command; - ++ buffer; - } + host->packetSize += buffer->dataLength; - host -> commandCount = command - host -> commands; - host -> bufferCount = buffer - host -> buffers; + *command = outgoingCommand->command; - if (peer -> state == ENET_PEER_STATE_DISCONNECT_LATER && - enet_list_empty (& peer -> outgoingReliableCommands) && - enet_list_empty (& peer -> outgoingUnreliableCommands) && - enet_list_empty (& peer -> sentReliableCommands)) - enet_peer_disconnect (peer, peer -> eventData); + enet_list_remove(&outgoingCommand->outgoingCommandList); + + if (outgoingCommand->packet != NULL) + { + ++buffer; + + buffer->data = outgoingCommand->packet->data + outgoingCommand->fragmentOffset; + buffer->dataLength = outgoingCommand->fragmentLength; + + host->packetSize += buffer->dataLength; + + enet_list_insert(enet_list_end(&peer->sentUnreliableCommands), outgoingCommand); + } + else + enet_free(outgoingCommand); + + ++command; + ++buffer; + } + + host->commandCount = command - host->commands; + host->bufferCount = buffer - host->buffers; + + if (peer->state == ENET_PEER_STATE_DISCONNECT_LATER && + enet_list_empty(&peer->outgoingReliableCommands) && + enet_list_empty(&peer->outgoingUnreliableCommands) && + enet_list_empty(&peer->sentReliableCommands)) + enet_peer_disconnect(peer, peer->eventData); } static int -enet_protocol_check_timeouts (ENetHost * host, ENetPeer * peer, ENetEvent * event) +enet_protocol_check_timeouts(ENetHost *host, ENetPeer *peer, ENetEvent *event) { - ENetOutgoingCommand * outgoingCommand; - ENetListIterator currentCommand, insertPosition; + ENetOutgoingCommand *outgoingCommand; + ENetListIterator currentCommand, insertPosition; - currentCommand = enet_list_begin (& peer -> sentReliableCommands); - insertPosition = enet_list_begin (& peer -> outgoingReliableCommands); + currentCommand = enet_list_begin(&peer->sentReliableCommands); + insertPosition = enet_list_begin(&peer->outgoingReliableCommands); - while (currentCommand != enet_list_end (& peer -> sentReliableCommands)) - { - outgoingCommand = (ENetOutgoingCommand *) currentCommand; + while (currentCommand != enet_list_end(&peer->sentReliableCommands)) + { + outgoingCommand = (ENetOutgoingCommand *)currentCommand; - currentCommand = enet_list_next (currentCommand); + currentCommand = enet_list_next(currentCommand); - if (ENET_TIME_DIFFERENCE (host -> serviceTime, outgoingCommand -> sentTime) < outgoingCommand -> roundTripTimeout) - continue; + if (ENET_TIME_DIFFERENCE(host->serviceTime, outgoingCommand->sentTime) < outgoingCommand->roundTripTimeout) + continue; - if (peer -> earliestTimeout == 0 || - ENET_TIME_LESS (outgoingCommand -> sentTime, peer -> earliestTimeout)) - peer -> earliestTimeout = outgoingCommand -> sentTime; + if (peer->earliestTimeout == 0 || + ENET_TIME_LESS(outgoingCommand->sentTime, peer->earliestTimeout)) + peer->earliestTimeout = outgoingCommand->sentTime; - if (peer -> earliestTimeout != 0 && - (ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMaximum || - (outgoingCommand -> roundTripTimeout >= outgoingCommand -> roundTripTimeoutLimit && - ENET_TIME_DIFFERENCE (host -> serviceTime, peer -> earliestTimeout) >= peer -> timeoutMinimum))) - { - enet_protocol_notify_disconnect (host, peer, event); + if (peer->earliestTimeout != 0 && + (ENET_TIME_DIFFERENCE(host->serviceTime, peer->earliestTimeout) >= peer->timeoutMaximum || + (outgoingCommand->roundTripTimeout >= outgoingCommand->roundTripTimeoutLimit && + ENET_TIME_DIFFERENCE(host->serviceTime, peer->earliestTimeout) >= peer->timeoutMinimum))) + { + enet_protocol_notify_disconnect(host, peer, event); - return 1; - } + return 1; + } - if (outgoingCommand -> packet != NULL) - peer -> reliableDataInTransit -= outgoingCommand -> fragmentLength; - - ++ peer -> packetsLost; + if (outgoingCommand->packet != NULL) + peer->reliableDataInTransit -= outgoingCommand->fragmentLength; - outgoingCommand -> roundTripTimeout *= 2; + ++peer->packetsLost; - enet_list_insert (insertPosition, enet_list_remove (& outgoingCommand -> outgoingCommandList)); + outgoingCommand->roundTripTimeout *= 2; - if (currentCommand == enet_list_begin (& peer -> sentReliableCommands) && - ! enet_list_empty (& peer -> sentReliableCommands)) - { - outgoingCommand = (ENetOutgoingCommand *) currentCommand; + enet_list_insert(insertPosition, enet_list_remove(&outgoingCommand->outgoingCommandList)); - peer -> nextTimeout = outgoingCommand -> sentTime + outgoingCommand -> roundTripTimeout; - } - } - - return 0; + if (currentCommand == enet_list_begin(&peer->sentReliableCommands) && + !enet_list_empty(&peer->sentReliableCommands)) + { + outgoingCommand = (ENetOutgoingCommand *)currentCommand; + + peer->nextTimeout = outgoingCommand->sentTime + outgoingCommand->roundTripTimeout; + } + } + + return 0; } static int -enet_protocol_send_reliable_outgoing_commands (ENetHost * host, ENetPeer * peer) +enet_protocol_send_reliable_outgoing_commands(ENetHost *host, ENetPeer *peer) { - ENetProtocol * command = & host -> commands [host -> commandCount]; - ENetBuffer * buffer = & host -> buffers [host -> bufferCount]; - ENetOutgoingCommand * outgoingCommand; - ENetListIterator currentCommand; - ENetChannel *channel; - enet_uint16 reliableWindow; - size_t commandSize; - int windowExceeded = 0, windowWrap = 0, canPing = 1; + ENetProtocol *command = &host->commands[host->commandCount]; + ENetBuffer *buffer = &host->buffers[host->bufferCount]; + ENetOutgoingCommand *outgoingCommand; + ENetListIterator currentCommand; + ENetChannel *channel; + enet_uint16 reliableWindow; + size_t commandSize; + int windowExceeded = 0, windowWrap = 0, canPing = 1; - currentCommand = enet_list_begin (& peer -> outgoingReliableCommands); - - while (currentCommand != enet_list_end (& peer -> outgoingReliableCommands)) - { - outgoingCommand = (ENetOutgoingCommand *) currentCommand; + currentCommand = enet_list_begin(&peer->outgoingReliableCommands); - channel = outgoingCommand -> command.header.channelID < peer -> channelCount ? & peer -> channels [outgoingCommand -> command.header.channelID] : NULL; - reliableWindow = outgoingCommand -> reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; - if (channel != NULL) - { - if (! windowWrap && - outgoingCommand -> sendAttempts < 1 && - ! (outgoingCommand -> reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) && - (channel -> reliableWindows [(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE || - channel -> usedReliableWindows & ((((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) << reliableWindow) | - (((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOW_SIZE - reliableWindow))))) - windowWrap = 1; - if (windowWrap) - { - currentCommand = enet_list_next (currentCommand); - - continue; - } - } - - if (outgoingCommand -> packet != NULL) - { - if (! windowExceeded) - { - enet_uint32 windowSize = (peer -> packetThrottle * peer -> windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE; - - if (peer -> reliableDataInTransit + outgoingCommand -> fragmentLength > ENET_MAX (windowSize, peer -> mtu)) - windowExceeded = 1; - } - if (windowExceeded) - { - currentCommand = enet_list_next (currentCommand); + while (currentCommand != enet_list_end(&peer->outgoingReliableCommands)) + { + outgoingCommand = (ENetOutgoingCommand *)currentCommand; - continue; - } - } + channel = outgoingCommand->command.header.channelID < peer->channelCount ? &peer->channels[outgoingCommand->command.header.channelID] : NULL; + reliableWindow = outgoingCommand->reliableSequenceNumber / ENET_PEER_RELIABLE_WINDOW_SIZE; + if (channel != NULL) + { + if (!windowWrap && + outgoingCommand->sendAttempts < 1 && + !(outgoingCommand->reliableSequenceNumber % ENET_PEER_RELIABLE_WINDOW_SIZE) && + (channel->reliableWindows[(reliableWindow + ENET_PEER_RELIABLE_WINDOWS - 1) % ENET_PEER_RELIABLE_WINDOWS] >= ENET_PEER_RELIABLE_WINDOW_SIZE || + channel->usedReliableWindows & ((((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) << reliableWindow) | + (((1 << ENET_PEER_FREE_RELIABLE_WINDOWS) - 1) >> (ENET_PEER_RELIABLE_WINDOW_SIZE - reliableWindow))))) + windowWrap = 1; + if (windowWrap) + { + currentCommand = enet_list_next(currentCommand); - canPing = 0; + continue; + } + } - commandSize = commandSizes [outgoingCommand -> command.header.command & ENET_PROTOCOL_COMMAND_MASK]; - if (command >= & host -> commands [sizeof (host -> commands) / sizeof (ENetProtocol)] || - buffer + 1 >= & host -> buffers [sizeof (host -> buffers) / sizeof (ENetBuffer)] || - peer -> mtu - host -> packetSize < commandSize || - (outgoingCommand -> packet != NULL && - (enet_uint16) (peer -> mtu - host -> packetSize) < (enet_uint16) (commandSize + outgoingCommand -> fragmentLength))) - { - host -> continueSending = 1; - - break; - } + if (outgoingCommand->packet != NULL) + { + if (!windowExceeded) + { + enet_uint32 windowSize = (peer->packetThrottle * peer->windowSize) / ENET_PEER_PACKET_THROTTLE_SCALE; - currentCommand = enet_list_next (currentCommand); + if (peer->reliableDataInTransit + outgoingCommand->fragmentLength > ENET_MAX(windowSize, peer->mtu)) + windowExceeded = 1; + } + if (windowExceeded) + { + currentCommand = enet_list_next(currentCommand); - if (channel != NULL && outgoingCommand -> sendAttempts < 1) - { - channel -> usedReliableWindows |= 1 << reliableWindow; - ++ channel -> reliableWindows [reliableWindow]; - } + continue; + } + } - ++ outgoingCommand -> sendAttempts; - - if (outgoingCommand -> roundTripTimeout == 0) - { - outgoingCommand -> roundTripTimeout = peer -> roundTripTime + 4 * peer -> roundTripTimeVariance; - outgoingCommand -> roundTripTimeoutLimit = peer -> timeoutLimit * outgoingCommand -> roundTripTimeout; - } + canPing = 0; - if (enet_list_empty (& peer -> sentReliableCommands)) - peer -> nextTimeout = host -> serviceTime + outgoingCommand -> roundTripTimeout; + commandSize = commandSizes[outgoingCommand->command.header.command & ENET_PROTOCOL_COMMAND_MASK]; + if (command >= &host->commands[sizeof(host->commands) / sizeof(ENetProtocol)] || + buffer + 1 >= &host->buffers[sizeof(host->buffers) / sizeof(ENetBuffer)] || + peer->mtu - host->packetSize < commandSize || + (outgoingCommand->packet != NULL && + (enet_uint16)(peer->mtu - host->packetSize) < (enet_uint16)(commandSize + outgoingCommand->fragmentLength))) + { + host->continueSending = 1; - enet_list_insert (enet_list_end (& peer -> sentReliableCommands), - enet_list_remove (& outgoingCommand -> outgoingCommandList)); + break; + } - outgoingCommand -> sentTime = host -> serviceTime; + currentCommand = enet_list_next(currentCommand); - buffer -> data = command; - buffer -> dataLength = commandSize; + if (channel != NULL && outgoingCommand->sendAttempts < 1) + { + channel->usedReliableWindows |= 1 << reliableWindow; + ++channel->reliableWindows[reliableWindow]; + } - host -> packetSize += buffer -> dataLength; - host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME; + ++outgoingCommand->sendAttempts; - * command = outgoingCommand -> command; + if (outgoingCommand->roundTripTimeout == 0) + { + outgoingCommand->roundTripTimeout = peer->roundTripTime + 4 * peer->roundTripTimeVariance; + outgoingCommand->roundTripTimeoutLimit = peer->timeoutLimit * outgoingCommand->roundTripTimeout; + } - if (outgoingCommand -> packet != NULL) - { - ++ buffer; - - buffer -> data = outgoingCommand -> packet -> data + outgoingCommand -> fragmentOffset; - buffer -> dataLength = outgoingCommand -> fragmentLength; + if (enet_list_empty(&peer->sentReliableCommands)) + peer->nextTimeout = host->serviceTime + outgoingCommand->roundTripTimeout; - host -> packetSize += outgoingCommand -> fragmentLength; + enet_list_insert(enet_list_end(&peer->sentReliableCommands), + enet_list_remove(&outgoingCommand->outgoingCommandList)); - peer -> reliableDataInTransit += outgoingCommand -> fragmentLength; - } + outgoingCommand->sentTime = host->serviceTime; - ++ peer -> packetsSent; - - ++ command; - ++ buffer; - } + buffer->data = command; + buffer->dataLength = commandSize; - host -> commandCount = command - host -> commands; - host -> bufferCount = buffer - host -> buffers; + host->packetSize += buffer->dataLength; + host->headerFlags |= ENET_PROTOCOL_HEADER_FLAG_SENT_TIME; - return canPing; + *command = outgoingCommand->command; + + if (outgoingCommand->packet != NULL) + { + ++buffer; + + buffer->data = outgoingCommand->packet->data + outgoingCommand->fragmentOffset; + buffer->dataLength = outgoingCommand->fragmentLength; + + host->packetSize += outgoingCommand->fragmentLength; + + peer->reliableDataInTransit += outgoingCommand->fragmentLength; + } + + ++peer->packetsSent; + + ++command; + ++buffer; + } + + host->commandCount = command - host->commands; + host->bufferCount = buffer - host->buffers; + + return canPing; } static int -enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int checkForTimeouts) +enet_protocol_send_outgoing_commands(ENetHost *host, ENetEvent *event, int checkForTimeouts) { - enet_uint8 headerData [sizeof (ENetProtocolHeader) + sizeof (enet_uint32)]; - ENetProtocolHeader * header = (ENetProtocolHeader *) headerData; - ENetPeer * currentPeer; - int sentLength; - size_t shouldCompress = 0; - - host -> continueSending = 1; + enet_uint8 headerData[sizeof(ENetProtocolHeader) + sizeof(enet_uint32)]; + ENetProtocolHeader *header = (ENetProtocolHeader *)headerData; + ENetPeer *currentPeer; + int sentLength; + size_t shouldCompress = 0; - while (host -> continueSending) - for (host -> continueSending = 0, - currentPeer = host -> peers; - currentPeer < & host -> peers [host -> peerCount]; - ++ currentPeer) - { - if (currentPeer -> state == ENET_PEER_STATE_DISCONNECTED || - currentPeer -> state == ENET_PEER_STATE_ZOMBIE) - continue; + host->continueSending = 1; - host -> headerFlags = 0; - host -> commandCount = 0; - host -> bufferCount = 1; - host -> packetSize = sizeof (ENetProtocolHeader); + while (host->continueSending) + for (host->continueSending = 0, + currentPeer = host->peers; + currentPeer < &host->peers[host->peerCount]; + ++currentPeer) + { + if (currentPeer->state == ENET_PEER_STATE_DISCONNECTED || + currentPeer->state == ENET_PEER_STATE_ZOMBIE) + continue; - if (! enet_list_empty (& currentPeer -> acknowledgements)) - enet_protocol_send_acknowledgements (host, currentPeer); + host->headerFlags = 0; + host->commandCount = 0; + host->bufferCount = 1; + host->packetSize = sizeof(ENetProtocolHeader); - if (checkForTimeouts != 0 && - ! enet_list_empty (& currentPeer -> sentReliableCommands) && - ENET_TIME_GREATER_EQUAL (host -> serviceTime, currentPeer -> nextTimeout) && - enet_protocol_check_timeouts (host, currentPeer, event) == 1) - { - if (event != NULL && event -> type != ENET_EVENT_TYPE_NONE) - return 1; - else - continue; - } + if (!enet_list_empty(¤tPeer->acknowledgements)) + enet_protocol_send_acknowledgements(host, currentPeer); - if ((enet_list_empty (& currentPeer -> outgoingReliableCommands) || - enet_protocol_send_reliable_outgoing_commands (host, currentPeer)) && - enet_list_empty (& currentPeer -> sentReliableCommands) && - ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> lastReceiveTime) >= currentPeer -> pingInterval && - currentPeer -> mtu - host -> packetSize >= sizeof (ENetProtocolPing)) - { - enet_peer_ping (currentPeer); - enet_protocol_send_reliable_outgoing_commands (host, currentPeer); - } - - if (! enet_list_empty (& currentPeer -> outgoingUnreliableCommands)) - enet_protocol_send_unreliable_outgoing_commands (host, currentPeer); + if (checkForTimeouts != 0 && + !enet_list_empty(¤tPeer->sentReliableCommands) && + ENET_TIME_GREATER_EQUAL(host->serviceTime, currentPeer->nextTimeout) && + enet_protocol_check_timeouts(host, currentPeer, event) == 1) + { + if (event != NULL && event->type != ENET_EVENT_TYPE_NONE) + return 1; + else + continue; + } - if (host -> commandCount == 0) - continue; + if ((enet_list_empty(¤tPeer->outgoingReliableCommands) || + enet_protocol_send_reliable_outgoing_commands(host, currentPeer)) && + enet_list_empty(¤tPeer->sentReliableCommands) && + ENET_TIME_DIFFERENCE(host->serviceTime, currentPeer->lastReceiveTime) >= currentPeer->pingInterval && + currentPeer->mtu - host->packetSize >= sizeof(ENetProtocolPing)) + { + enet_peer_ping(currentPeer); + enet_protocol_send_reliable_outgoing_commands(host, currentPeer); + } - if (currentPeer -> packetLossEpoch == 0) - currentPeer -> packetLossEpoch = host -> serviceTime; - else - if (ENET_TIME_DIFFERENCE (host -> serviceTime, currentPeer -> packetLossEpoch) >= ENET_PEER_PACKET_LOSS_INTERVAL && - currentPeer -> packetsSent > 0) - { - enet_uint32 packetLoss = currentPeer -> packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer -> packetsSent; + if (!enet_list_empty(¤tPeer->outgoingUnreliableCommands)) + enet_protocol_send_unreliable_outgoing_commands(host, currentPeer); + + if (host->commandCount == 0) + continue; + + if (currentPeer->packetLossEpoch == 0) + currentPeer->packetLossEpoch = host->serviceTime; + else if (ENET_TIME_DIFFERENCE(host->serviceTime, currentPeer->packetLossEpoch) >= ENET_PEER_PACKET_LOSS_INTERVAL && + currentPeer->packetsSent > 0) + { + enet_uint32 packetLoss = currentPeer->packetsLost * ENET_PEER_PACKET_LOSS_SCALE / currentPeer->packetsSent; #ifdef ENET_DEBUG #ifdef WIN32 - printf ( + printf( #else - fprintf (stderr, + fprintf(stderr, #endif - "peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer -> incomingPeerID, currentPeer -> packetLoss / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> packetLossVariance / (float) ENET_PEER_PACKET_LOSS_SCALE, currentPeer -> roundTripTime, currentPeer -> roundTripTimeVariance, currentPeer -> packetThrottle / (float) ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size (& currentPeer -> outgoingReliableCommands), enet_list_size (& currentPeer -> outgoingUnreliableCommands), currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingReliableCommands) : 0, currentPeer -> channels != NULL ? enet_list_size (& currentPeer -> channels -> incomingUnreliableCommands) : 0); + "peer %u: %f%%+-%f%% packet loss, %u+-%u ms round trip time, %f%% throttle, %u/%u outgoing, %u/%u incoming\n", currentPeer->incomingPeerID, currentPeer->packetLoss / (float)ENET_PEER_PACKET_LOSS_SCALE, currentPeer->packetLossVariance / (float)ENET_PEER_PACKET_LOSS_SCALE, currentPeer->roundTripTime, currentPeer->roundTripTimeVariance, currentPeer->packetThrottle / (float)ENET_PEER_PACKET_THROTTLE_SCALE, enet_list_size(¤tPeer->outgoingReliableCommands), enet_list_size(¤tPeer->outgoingUnreliableCommands), currentPeer->channels != NULL ? enet_list_size(¤tPeer->channels->incomingReliableCommands) : 0, currentPeer->channels != NULL ? enet_list_size(¤tPeer->channels->incomingUnreliableCommands) : 0); #endif - - currentPeer -> packetLossVariance -= currentPeer -> packetLossVariance / 4; - if (packetLoss >= currentPeer -> packetLoss) - { - currentPeer -> packetLoss += (packetLoss - currentPeer -> packetLoss) / 8; - currentPeer -> packetLossVariance += (packetLoss - currentPeer -> packetLoss) / 4; - } - else - { - currentPeer -> packetLoss -= (currentPeer -> packetLoss - packetLoss) / 8; - currentPeer -> packetLossVariance += (currentPeer -> packetLoss - packetLoss) / 4; - } + currentPeer->packetLossVariance -= currentPeer->packetLossVariance / 4; - currentPeer -> packetLossEpoch = host -> serviceTime; - currentPeer -> packetsSent = 0; - currentPeer -> packetsLost = 0; - } + if (packetLoss >= currentPeer->packetLoss) + { + currentPeer->packetLoss += (packetLoss - currentPeer->packetLoss) / 8; + currentPeer->packetLossVariance += (packetLoss - currentPeer->packetLoss) / 4; + } + else + { + currentPeer->packetLoss -= (currentPeer->packetLoss - packetLoss) / 8; + currentPeer->packetLossVariance += (currentPeer->packetLoss - packetLoss) / 4; + } - host -> buffers -> data = headerData; - if (host -> headerFlags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME) - { - header -> sentTime = ENET_HOST_TO_NET_16 (host -> serviceTime & 0xFFFF); + currentPeer->packetLossEpoch = host->serviceTime; + currentPeer->packetsSent = 0; + currentPeer->packetsLost = 0; + } - host -> buffers -> dataLength = sizeof (ENetProtocolHeader); - } - else - host -> buffers -> dataLength = (size_t) & ((ENetProtocolHeader *) 0) -> sentTime; + host->buffers->data = headerData; + if (host->headerFlags & ENET_PROTOCOL_HEADER_FLAG_SENT_TIME) + { + header->sentTime = ENET_HOST_TO_NET_16(host->serviceTime & 0xFFFF); - shouldCompress = 0; - if (host -> compressor.context != NULL && host -> compressor.compress != NULL) - { - size_t originalSize = host -> packetSize - sizeof(ENetProtocolHeader), - compressedSize = host -> compressor.compress (host -> compressor.context, - & host -> buffers [1], host -> bufferCount - 1, - originalSize, - host -> packetData [1], - originalSize); - if (compressedSize > 0 && compressedSize < originalSize) - { - host -> headerFlags |= ENET_PROTOCOL_HEADER_FLAG_COMPRESSED; - shouldCompress = compressedSize; + host->buffers->dataLength = sizeof(ENetProtocolHeader); + } + else + host->buffers->dataLength = (size_t) & ((ENetProtocolHeader *)0)->sentTime; + + shouldCompress = 0; + if (host->compressor.context != NULL && host->compressor.compress != NULL) + { + size_t originalSize = host->packetSize - sizeof(ENetProtocolHeader), + compressedSize = host->compressor.compress(host->compressor.context, + &host->buffers[1], host->bufferCount - 1, + originalSize, + host->packetData[1], + originalSize); + if (compressedSize > 0 && compressedSize < originalSize) + { + host->headerFlags |= ENET_PROTOCOL_HEADER_FLAG_COMPRESSED; + shouldCompress = compressedSize; #ifdef ENET_DEBUG_COMPRESS #ifdef WIN32 - printf ( + printf( #else - fprintf (stderr, + fprintf(stderr, #endif - "peer %u: compressed %u -> %u (%u%%)\n", currentPeer -> incomingPeerID, originalSize, compressedSize, (compressedSize * 100) / originalSize); + "peer %u: compressed %u -> %u (%u%%)\n", currentPeer->incomingPeerID, originalSize, compressedSize, (compressedSize * 100) / originalSize); #endif - } - } + } + } - if (currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID) - host -> headerFlags |= currentPeer -> outgoingSessionID << ENET_PROTOCOL_HEADER_SESSION_SHIFT; - header -> peerID = ENET_HOST_TO_NET_16 (currentPeer -> outgoingPeerID | host -> headerFlags); - if (host -> checksum != NULL) - { - enet_uint32 * checksum = (enet_uint32 *) & headerData [host -> buffers -> dataLength]; - * checksum = currentPeer -> outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID ? currentPeer -> connectID : 0; - host -> buffers -> dataLength += sizeof (enet_uint32); - * checksum = host -> checksum (host -> buffers, host -> bufferCount); - } + if (currentPeer->outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID) + host->headerFlags |= currentPeer->outgoingSessionID << ENET_PROTOCOL_HEADER_SESSION_SHIFT; + header->peerID = ENET_HOST_TO_NET_16(currentPeer->outgoingPeerID | host->headerFlags); + if (host->checksum != NULL) + { + enet_uint32 *checksum = (enet_uint32 *)&headerData[host->buffers->dataLength]; + *checksum = currentPeer->outgoingPeerID < ENET_PROTOCOL_MAXIMUM_PEER_ID ? currentPeer->connectID : 0; + host->buffers->dataLength += sizeof(enet_uint32); + *checksum = host->checksum(host->buffers, host->bufferCount); + } - if (shouldCompress > 0) - { - host -> buffers [1].data = host -> packetData [1]; - host -> buffers [1].dataLength = shouldCompress; - host -> bufferCount = 2; - } + if (shouldCompress > 0) + { + host->buffers[1].data = host->packetData[1]; + host->buffers[1].dataLength = shouldCompress; + host->bufferCount = 2; + } - currentPeer -> lastSendTime = host -> serviceTime; + currentPeer->lastSendTime = host->serviceTime; - sentLength = enet_socket_send (host -> socket, & currentPeer -> address, host -> buffers, host -> bufferCount); + sentLength = enet_socket_send(host->socket, ¤tPeer->address, host->buffers, host->bufferCount); - enet_protocol_remove_sent_unreliable_commands (currentPeer); + enet_protocol_remove_sent_unreliable_commands(currentPeer); - if (sentLength < 0) - return -1; + if (sentLength < 0) + return -1; - host -> totalSentData += sentLength; - host -> totalSentPackets ++; - } - - return 0; + host->totalSentData += sentLength; + host->totalSentPackets++; + } + + return 0; } /** Sends any queued packets on the host specified to its designated peers. @@ -1745,12 +1731,11 @@ enet_protocol_send_outgoing_commands (ENetHost * host, ENetEvent * event, int ch @remarks this function need only be used in circumstances where one wishes to send queued packets earlier than in a call to enet_host_service(). @ingroup host */ -void -enet_host_flush (ENetHost * host) +void enet_host_flush(ENetHost *host) { - host -> serviceTime = enet_time_get (); + host->serviceTime = enet_time_get(); - enet_protocol_send_outgoing_commands (host, NULL, 0); + enet_protocol_send_outgoing_commands(host, NULL, 0); } /** Checks for any queued events on the host and dispatches one if available. @@ -1762,16 +1747,15 @@ enet_host_flush (ENetHost * host) @retval < 0 on failure @ingroup host */ -int -enet_host_check_events (ENetHost * host, ENetEvent * event) +int enet_host_check_events(ENetHost *host, ENetEvent *event) { - if (event == NULL) return -1; + if (event == NULL) return -1; - event -> type = ENET_EVENT_TYPE_NONE; - event -> peer = NULL; - event -> packet = NULL; + event->type = ENET_EVENT_TYPE_NONE; + event->peer = NULL; + event->packet = NULL; - return enet_protocol_dispatch_incoming_commands (host, event); + return enet_protocol_dispatch_incoming_commands(host, event); } /** Waits for events on the host specified and shuttles packets between @@ -1787,113 +1771,111 @@ enet_host_check_events (ENetHost * host, ENetEvent * event) @remarks enet_host_service should be called fairly regularly for adequate performance @ingroup host */ -int -enet_host_service (ENetHost * host, ENetEvent * event, enet_uint32 timeout) +int enet_host_service(ENetHost *host, ENetEvent *event, enet_uint32 timeout) { - enet_uint32 waitCondition; + enet_uint32 waitCondition; - if (event != NULL) - { - event -> type = ENET_EVENT_TYPE_NONE; - event -> peer = NULL; - event -> packet = NULL; + if (event != NULL) + { + event->type = ENET_EVENT_TYPE_NONE; + event->peer = NULL; + event->packet = NULL; - switch (enet_protocol_dispatch_incoming_commands (host, event)) - { - case 1: - return 1; + switch (enet_protocol_dispatch_incoming_commands(host, event)) + { + case 1: + return 1; - case -1: - perror ("Error dispatching incoming packets"); + case -1: + perror("Error dispatching incoming packets"); - return -1; + return -1; - default: - break; - } - } + default: + break; + } + } - host -> serviceTime = enet_time_get (); - - timeout += host -> serviceTime; + host->serviceTime = enet_time_get(); - do - { - if (ENET_TIME_DIFFERENCE (host -> serviceTime, host -> bandwidthThrottleEpoch) >= ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL) - enet_host_bandwidth_throttle (host); + timeout += host->serviceTime; - switch (enet_protocol_send_outgoing_commands (host, event, 1)) - { - case 1: - return 1; + do + { + if (ENET_TIME_DIFFERENCE(host->serviceTime, host->bandwidthThrottleEpoch) >= ENET_HOST_BANDWIDTH_THROTTLE_INTERVAL) + enet_host_bandwidth_throttle(host); - case -1: - perror ("Error sending outgoing packets"); + switch (enet_protocol_send_outgoing_commands(host, event, 1)) + { + case 1: + return 1; - return -1; + case -1: + perror("Error sending outgoing packets"); - default: - break; - } + return -1; - switch (enet_protocol_receive_incoming_commands (host, event)) - { - case 1: - return 1; + default: + break; + } - case -1: - perror ("Error receiving incoming packets"); + switch (enet_protocol_receive_incoming_commands(host, event)) + { + case 1: + return 1; - return -1; + case -1: + perror("Error receiving incoming packets"); - default: - break; - } + return -1; - switch (enet_protocol_send_outgoing_commands (host, event, 1)) - { - case 1: - return 1; + default: + break; + } - case -1: - perror ("Error sending outgoing packets"); + switch (enet_protocol_send_outgoing_commands(host, event, 1)) + { + case 1: + return 1; - return -1; + case -1: + perror("Error sending outgoing packets"); - default: - break; - } + return -1; - if (event != NULL) - { - switch (enet_protocol_dispatch_incoming_commands (host, event)) - { - case 1: - return 1; + default: + break; + } - case -1: - perror ("Error dispatching incoming packets"); + if (event != NULL) + { + switch (enet_protocol_dispatch_incoming_commands(host, event)) + { + case 1: + return 1; - return -1; + case -1: + perror("Error dispatching incoming packets"); - default: - break; - } - } + return -1; - host -> serviceTime = enet_time_get (); + default: + break; + } + } - if (ENET_TIME_GREATER_EQUAL (host -> serviceTime, timeout)) - return 0; + host->serviceTime = enet_time_get(); - waitCondition = ENET_SOCKET_WAIT_RECEIVE; + if (ENET_TIME_GREATER_EQUAL(host->serviceTime, timeout)) + return 0; - if (enet_socket_wait (host -> socket, & waitCondition, ENET_TIME_DIFFERENCE (timeout, host -> serviceTime)) != 0) - return -1; - - host -> serviceTime = enet_time_get (); - } while (waitCondition == ENET_SOCKET_WAIT_RECEIVE); + waitCondition = ENET_SOCKET_WAIT_RECEIVE; - return 0; + if (enet_socket_wait(host->socket, &waitCondition, ENET_TIME_DIFFERENCE(timeout, host->serviceTime)) != 0) + return -1; + + host->serviceTime = enet_time_get(); + } while (waitCondition == ENET_SOCKET_WAIT_RECEIVE); + + return 0; } - diff --git a/examples/ThirdPartyLibs/enet/unix.c b/examples/ThirdPartyLibs/enet/unix.c index d425b4b8a..9998a3b1f 100644 --- a/examples/ThirdPartyLibs/enet/unix.c +++ b/examples/ThirdPartyLibs/enet/unix.c @@ -57,419 +57,402 @@ typedef int socklen_t; static enet_uint32 timeBase = 0; -int -enet_initialize (void) +int enet_initialize(void) { - return 0; + return 0; } -void -enet_deinitialize (void) +void enet_deinitialize(void) { } enet_uint32 -enet_time_get (void) +enet_time_get(void) { - struct timeval timeVal; + struct timeval timeVal; - gettimeofday (& timeVal, NULL); + gettimeofday(&timeVal, NULL); - return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase; + return timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - timeBase; } -void -enet_time_set (enet_uint32 newTimeBase) +void enet_time_set(enet_uint32 newTimeBase) { - struct timeval timeVal; + struct timeval timeVal; - gettimeofday (& timeVal, NULL); - - timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase; + gettimeofday(&timeVal, NULL); + + timeBase = timeVal.tv_sec * 1000 + timeVal.tv_usec / 1000 - newTimeBase; } -int -enet_address_set_host (ENetAddress * address, const char * name) +int enet_address_set_host(ENetAddress *address, const char *name) { - struct hostent * hostEntry = NULL; + struct hostent *hostEntry = NULL; #ifdef HAS_GETHOSTBYNAME_R - struct hostent hostData; - char buffer [2048]; - int errnum; + struct hostent hostData; + char buffer[2048]; + int errnum; #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum); + gethostbyname_r(name, &hostData, buffer, sizeof(buffer), &hostEntry, &errnum); #else - hostEntry = gethostbyname_r (name, & hostData, buffer, sizeof (buffer), & errnum); + hostEntry = gethostbyname_r(name, &hostData, buffer, sizeof(buffer), &errnum); #endif #else - hostEntry = gethostbyname (name); + hostEntry = gethostbyname(name); #endif - if (hostEntry == NULL || - hostEntry -> h_addrtype != AF_INET) - { + if (hostEntry == NULL || + hostEntry->h_addrtype != AF_INET) + { #ifdef HAS_INET_PTON - if (! inet_pton (AF_INET, name, & address -> host)) + if (!inet_pton(AF_INET, name, &address->host)) #else - if (! inet_aton (name, (struct in_addr *) & address -> host)) + if (!inet_aton(name, (struct in_addr *)&address->host)) #endif - return -1; - return 0; - } + return -1; + return 0; + } - address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0]; + address->host = *(enet_uint32 *)hostEntry->h_addr_list[0]; - return 0; + return 0; } -int -enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength) +int enet_address_get_host_ip(const ENetAddress *address, char *name, size_t nameLength) { #ifdef HAS_INET_NTOP - if (inet_ntop (AF_INET, & address -> host, name, nameLength) == NULL) + if (inet_ntop(AF_INET, &address->host, name, nameLength) == NULL) #else - char * addr = inet_ntoa (* (struct in_addr *) & address -> host); - if (addr != NULL) - strncpy (name, addr, nameLength); - else + char *addr = inet_ntoa(*(struct in_addr *)&address->host); + if (addr != NULL) + strncpy(name, addr, nameLength); + else #endif - return -1; - return 0; + return -1; + return 0; } -int -enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength) +int enet_address_get_host(const ENetAddress *address, char *name, size_t nameLength) { - struct in_addr in; - struct hostent * hostEntry = NULL; + struct in_addr in; + struct hostent *hostEntry = NULL; #ifdef HAS_GETHOSTBYADDR_R - struct hostent hostData; - char buffer [2048]; - int errnum; + struct hostent hostData; + char buffer[2048]; + int errnum; - in.s_addr = address -> host; + in.s_addr = address->host; #if defined(linux) || defined(__linux) || defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__) - gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & hostEntry, & errnum); + gethostbyaddr_r((char *)&in, sizeof(struct in_addr), AF_INET, &hostData, buffer, sizeof(buffer), &hostEntry, &errnum); #else - hostEntry = gethostbyaddr_r ((char *) & in, sizeof (struct in_addr), AF_INET, & hostData, buffer, sizeof (buffer), & errnum); + hostEntry = gethostbyaddr_r((char *)&in, sizeof(struct in_addr), AF_INET, &hostData, buffer, sizeof(buffer), &errnum); #endif #else - in.s_addr = address -> host; + in.s_addr = address->host; - hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET); + hostEntry = gethostbyaddr((char *)&in, sizeof(struct in_addr), AF_INET); #endif - if (hostEntry == NULL) - return enet_address_get_host_ip (address, name, nameLength); + if (hostEntry == NULL) + return enet_address_get_host_ip(address, name, nameLength); - strncpy (name, hostEntry -> h_name, nameLength); + strncpy(name, hostEntry->h_name, nameLength); - return 0; + return 0; } -int -enet_socket_bind (ENetSocket socket, const ENetAddress * address) +int enet_socket_bind(ENetSocket socket, const ENetAddress *address) { - struct sockaddr_in sin; + struct sockaddr_in sin; - memset (& sin, 0, sizeof (struct sockaddr_in)); + memset(&sin, 0, sizeof(struct sockaddr_in)); - sin.sin_family = AF_INET; + sin.sin_family = AF_INET; - if (address != NULL) - { - sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); - sin.sin_addr.s_addr = address -> host; - } - else - { - sin.sin_port = 0; - sin.sin_addr.s_addr = INADDR_ANY; - } + if (address != NULL) + { + sin.sin_port = ENET_HOST_TO_NET_16(address->port); + sin.sin_addr.s_addr = address->host; + } + else + { + sin.sin_port = 0; + sin.sin_addr.s_addr = INADDR_ANY; + } - return bind (socket, - (struct sockaddr *) & sin, - sizeof (struct sockaddr_in)); + return bind(socket, + (struct sockaddr *)&sin, + sizeof(struct sockaddr_in)); } -int -enet_socket_listen (ENetSocket socket, int backlog) +int enet_socket_listen(ENetSocket socket, int backlog) { - return listen (socket, backlog < 0 ? SOMAXCONN : backlog); + return listen(socket, backlog < 0 ? SOMAXCONN : backlog); } ENetSocket -enet_socket_create (ENetSocketType type) +enet_socket_create(ENetSocketType type) { - return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); + return socket(PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); } -int -enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value) +int enet_socket_set_option(ENetSocket socket, ENetSocketOption option, int value) { - int result = -1; - switch (option) - { - case ENET_SOCKOPT_NONBLOCK: + int result = -1; + switch (option) + { + case ENET_SOCKOPT_NONBLOCK: #ifdef HAS_FCNTL - result = fcntl (socket, F_SETFL, O_NONBLOCK | fcntl (socket, F_GETFL)); + result = fcntl(socket, F_SETFL, O_NONBLOCK | fcntl(socket, F_GETFL)); #else - result = ioctl (socket, FIONBIO, & value); + result = ioctl(socket, FIONBIO, &value); #endif - break; + break; - case ENET_SOCKOPT_BROADCAST: - result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int)); - break; + case ENET_SOCKOPT_BROADCAST: + result = setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char *)&value, sizeof(int)); + break; - case ENET_SOCKOPT_REUSEADDR: - result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int)); - break; + case ENET_SOCKOPT_REUSEADDR: + result = setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (char *)&value, sizeof(int)); + break; - case ENET_SOCKOPT_RCVBUF: - result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int)); - break; + case ENET_SOCKOPT_RCVBUF: + result = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char *)&value, sizeof(int)); + break; - case ENET_SOCKOPT_SNDBUF: - result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int)); - break; + case ENET_SOCKOPT_SNDBUF: + result = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char *)&value, sizeof(int)); + break; - case ENET_SOCKOPT_RCVTIMEO: - result = setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, (char *) & value, sizeof (int)); - break; + case ENET_SOCKOPT_RCVTIMEO: + result = setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&value, sizeof(int)); + break; - case ENET_SOCKOPT_SNDTIMEO: - result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & value, sizeof (int)); - break; + case ENET_SOCKOPT_SNDTIMEO: + result = setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&value, sizeof(int)); + break; - default: - break; - } - return result == -1 ? -1 : 0; + default: + break; + } + return result == -1 ? -1 : 0; } -int -enet_socket_connect (ENetSocket socket, const ENetAddress * address) +int enet_socket_connect(ENetSocket socket, const ENetAddress *address) { - struct sockaddr_in sin; - int result; + struct sockaddr_in sin; + int result; - memset (& sin, 0, sizeof (struct sockaddr_in)); + memset(&sin, 0, sizeof(struct sockaddr_in)); - sin.sin_family = AF_INET; - sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); - sin.sin_addr.s_addr = address -> host; + sin.sin_family = AF_INET; + sin.sin_port = ENET_HOST_TO_NET_16(address->port); + sin.sin_addr.s_addr = address->host; - result = connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)); - if (result == -1 && errno == EINPROGRESS) - return 0; + result = connect(socket, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)); + if (result == -1 && errno == EINPROGRESS) + return 0; - return result; + return result; } ENetSocket -enet_socket_accept (ENetSocket socket, ENetAddress * address) +enet_socket_accept(ENetSocket socket, ENetAddress *address) { - int result; - struct sockaddr_in sin; - socklen_t sinLength = sizeof (struct sockaddr_in); + int result; + struct sockaddr_in sin; + socklen_t sinLength = sizeof(struct sockaddr_in); - result = accept (socket, - address != NULL ? (struct sockaddr *) & sin : NULL, - address != NULL ? & sinLength : NULL); - - if (result == -1) - return ENET_SOCKET_NULL; + result = accept(socket, + address != NULL ? (struct sockaddr *)&sin : NULL, + address != NULL ? &sinLength : NULL); - if (address != NULL) - { - address -> host = (enet_uint32) sin.sin_addr.s_addr; - address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); - } + if (result == -1) + return ENET_SOCKET_NULL; - return result; -} - -int -enet_socket_shutdown (ENetSocket socket, ENetSocketShutdown how) -{ - return shutdown (socket, (int) how); + if (address != NULL) + { + address->host = (enet_uint32)sin.sin_addr.s_addr; + address->port = ENET_NET_TO_HOST_16(sin.sin_port); + } + + return result; } -void -enet_socket_destroy (ENetSocket socket) +int enet_socket_shutdown(ENetSocket socket, ENetSocketShutdown how) { - if (socket != -1) - close (socket); + return shutdown(socket, (int)how); } -int -enet_socket_send (ENetSocket socket, - const ENetAddress * address, - const ENetBuffer * buffers, - size_t bufferCount) +void enet_socket_destroy(ENetSocket socket) { - struct msghdr msgHdr; - struct sockaddr_in sin; - int sentLength; - - memset (& msgHdr, 0, sizeof (struct msghdr)); - - if (address != NULL) - { - memset (& sin, 0, sizeof (struct sockaddr_in)); - - sin.sin_family = AF_INET; - sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); - sin.sin_addr.s_addr = address -> host; - - msgHdr.msg_name = & sin; - msgHdr.msg_namelen = sizeof (struct sockaddr_in); - } - - msgHdr.msg_iov = (struct iovec *) buffers; - msgHdr.msg_iovlen = bufferCount; - - sentLength = sendmsg (socket, & msgHdr, MSG_NOSIGNAL); - - if (sentLength == -1) - { - if (errno == EWOULDBLOCK) - return 0; - - return -1; - } - - return sentLength; + if (socket != -1) + close(socket); } -int -enet_socket_receive (ENetSocket socket, - ENetAddress * address, - ENetBuffer * buffers, - size_t bufferCount) +int enet_socket_send(ENetSocket socket, + const ENetAddress *address, + const ENetBuffer *buffers, + size_t bufferCount) { - struct msghdr msgHdr; - struct sockaddr_in sin; - int recvLength; + struct msghdr msgHdr; + struct sockaddr_in sin; + int sentLength; - memset (& msgHdr, 0, sizeof (struct msghdr)); + memset(&msgHdr, 0, sizeof(struct msghdr)); - if (address != NULL) - { - msgHdr.msg_name = & sin; - msgHdr.msg_namelen = sizeof (struct sockaddr_in); - } + if (address != NULL) + { + memset(&sin, 0, sizeof(struct sockaddr_in)); - msgHdr.msg_iov = (struct iovec *) buffers; - msgHdr.msg_iovlen = bufferCount; + sin.sin_family = AF_INET; + sin.sin_port = ENET_HOST_TO_NET_16(address->port); + sin.sin_addr.s_addr = address->host; - recvLength = recvmsg (socket, & msgHdr, MSG_NOSIGNAL); + msgHdr.msg_name = &sin; + msgHdr.msg_namelen = sizeof(struct sockaddr_in); + } - if (recvLength == -1) - { - if (errno == EWOULDBLOCK) - return 0; + msgHdr.msg_iov = (struct iovec *)buffers; + msgHdr.msg_iovlen = bufferCount; - return -1; - } + sentLength = sendmsg(socket, &msgHdr, MSG_NOSIGNAL); + + if (sentLength == -1) + { + if (errno == EWOULDBLOCK) + return 0; + + return -1; + } + + return sentLength; +} + +int enet_socket_receive(ENetSocket socket, + ENetAddress *address, + ENetBuffer *buffers, + size_t bufferCount) +{ + struct msghdr msgHdr; + struct sockaddr_in sin; + int recvLength; + + memset(&msgHdr, 0, sizeof(struct msghdr)); + + if (address != NULL) + { + msgHdr.msg_name = &sin; + msgHdr.msg_namelen = sizeof(struct sockaddr_in); + } + + msgHdr.msg_iov = (struct iovec *)buffers; + msgHdr.msg_iovlen = bufferCount; + + recvLength = recvmsg(socket, &msgHdr, MSG_NOSIGNAL); + + if (recvLength == -1) + { + if (errno == EWOULDBLOCK) + return 0; + + return -1; + } #ifdef HAS_MSGHDR_FLAGS - if (msgHdr.msg_flags & MSG_TRUNC) - return -1; + if (msgHdr.msg_flags & MSG_TRUNC) + return -1; #endif - if (address != NULL) - { - address -> host = (enet_uint32) sin.sin_addr.s_addr; - address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); - } + if (address != NULL) + { + address->host = (enet_uint32)sin.sin_addr.s_addr; + address->port = ENET_NET_TO_HOST_16(sin.sin_port); + } - return recvLength; + return recvLength; } -int -enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout) +int enet_socketset_select(ENetSocket maxSocket, ENetSocketSet *readSet, ENetSocketSet *writeSet, enet_uint32 timeout) { - struct timeval timeVal; + struct timeval timeVal; - timeVal.tv_sec = timeout / 1000; - timeVal.tv_usec = (timeout % 1000) * 1000; + timeVal.tv_sec = timeout / 1000; + timeVal.tv_usec = (timeout % 1000) * 1000; - return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal); + return select(maxSocket + 1, readSet, writeSet, NULL, &timeVal); } -int -enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout) +int enet_socket_wait(ENetSocket socket, enet_uint32 *condition, enet_uint32 timeout) { #ifdef HAS_POLL - struct pollfd pollSocket; - int pollCount; - - pollSocket.fd = socket; - pollSocket.events = 0; + struct pollfd pollSocket; + int pollCount; - if (* condition & ENET_SOCKET_WAIT_SEND) - pollSocket.events |= POLLOUT; + pollSocket.fd = socket; + pollSocket.events = 0; - if (* condition & ENET_SOCKET_WAIT_RECEIVE) - pollSocket.events |= POLLIN; + if (*condition & ENET_SOCKET_WAIT_SEND) + pollSocket.events |= POLLOUT; - pollCount = poll (& pollSocket, 1, timeout); + if (*condition & ENET_SOCKET_WAIT_RECEIVE) + pollSocket.events |= POLLIN; - if (pollCount < 0) - return -1; + pollCount = poll(&pollSocket, 1, timeout); - * condition = ENET_SOCKET_WAIT_NONE; + if (pollCount < 0) + return -1; - if (pollCount == 0) - return 0; + *condition = ENET_SOCKET_WAIT_NONE; - if (pollSocket.revents & POLLOUT) - * condition |= ENET_SOCKET_WAIT_SEND; - - if (pollSocket.revents & POLLIN) - * condition |= ENET_SOCKET_WAIT_RECEIVE; + if (pollCount == 0) + return 0; - return 0; + if (pollSocket.revents & POLLOUT) + *condition |= ENET_SOCKET_WAIT_SEND; + + if (pollSocket.revents & POLLIN) + *condition |= ENET_SOCKET_WAIT_RECEIVE; + + return 0; #else - fd_set readSet, writeSet; - struct timeval timeVal; - int selectCount; + fd_set readSet, writeSet; + struct timeval timeVal; + int selectCount; - timeVal.tv_sec = timeout / 1000; - timeVal.tv_usec = (timeout % 1000) * 1000; + timeVal.tv_sec = timeout / 1000; + timeVal.tv_usec = (timeout % 1000) * 1000; - FD_ZERO (& readSet); - FD_ZERO (& writeSet); + FD_ZERO(&readSet); + FD_ZERO(&writeSet); - if (* condition & ENET_SOCKET_WAIT_SEND) - FD_SET (socket, & writeSet); + if (*condition & ENET_SOCKET_WAIT_SEND) + FD_SET(socket, &writeSet); - if (* condition & ENET_SOCKET_WAIT_RECEIVE) - FD_SET (socket, & readSet); + if (*condition & ENET_SOCKET_WAIT_RECEIVE) + FD_SET(socket, &readSet); - selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal); + selectCount = select(socket + 1, &readSet, &writeSet, NULL, &timeVal); - if (selectCount < 0) - return -1; + if (selectCount < 0) + return -1; - * condition = ENET_SOCKET_WAIT_NONE; + *condition = ENET_SOCKET_WAIT_NONE; - if (selectCount == 0) - return 0; + if (selectCount == 0) + return 0; - if (FD_ISSET (socket, & writeSet)) - * condition |= ENET_SOCKET_WAIT_SEND; + if (FD_ISSET(socket, &writeSet)) + *condition |= ENET_SOCKET_WAIT_SEND; - if (FD_ISSET (socket, & readSet)) - * condition |= ENET_SOCKET_WAIT_RECEIVE; + if (FD_ISSET(socket, &readSet)) + *condition |= ENET_SOCKET_WAIT_RECEIVE; - return 0; + return 0; #endif } #endif - diff --git a/examples/ThirdPartyLibs/enet/win32.c b/examples/ThirdPartyLibs/enet/win32.c index dcc0791bd..9caeb94dc 100644 --- a/examples/ThirdPartyLibs/enet/win32.c +++ b/examples/ThirdPartyLibs/enet/win32.c @@ -10,359 +10,344 @@ static enet_uint32 timeBase = 0; -int -enet_initialize (void) +int enet_initialize(void) { - WORD versionRequested = MAKEWORD (1, 1); - WSADATA wsaData; - - if (WSAStartup (versionRequested, & wsaData)) - return -1; + WORD versionRequested = MAKEWORD(1, 1); + WSADATA wsaData; - if (LOBYTE (wsaData.wVersion) != 1|| - HIBYTE (wsaData.wVersion) != 1) - { - WSACleanup (); - - return -1; - } + if (WSAStartup(versionRequested, &wsaData)) + return -1; - timeBeginPeriod (1); + if (LOBYTE(wsaData.wVersion) != 1 || + HIBYTE(wsaData.wVersion) != 1) + { + WSACleanup(); - return 0; + return -1; + } + + timeBeginPeriod(1); + + return 0; } -void -enet_deinitialize (void) +void enet_deinitialize(void) { - timeEndPeriod (1); + timeEndPeriod(1); - WSACleanup (); + WSACleanup(); } enet_uint32 -enet_time_get (void) +enet_time_get(void) { - return (enet_uint32) timeGetTime () - timeBase; + return (enet_uint32)timeGetTime() - timeBase; } -void -enet_time_set (enet_uint32 newTimeBase) +void enet_time_set(enet_uint32 newTimeBase) { - timeBase = (enet_uint32) timeGetTime () - newTimeBase; + timeBase = (enet_uint32)timeGetTime() - newTimeBase; } -int -enet_address_set_host (ENetAddress * address, const char * name) +int enet_address_set_host(ENetAddress *address, const char *name) { - struct hostent * hostEntry; + struct hostent *hostEntry; - hostEntry = gethostbyname (name); - if (hostEntry == NULL || - hostEntry -> h_addrtype != AF_INET) - { - unsigned long host = inet_addr (name); - if (host == INADDR_NONE) - return -1; - address -> host = host; - return 0; - } + hostEntry = gethostbyname(name); + if (hostEntry == NULL || + hostEntry->h_addrtype != AF_INET) + { + unsigned long host = inet_addr(name); + if (host == INADDR_NONE) + return -1; + address->host = host; + return 0; + } - address -> host = * (enet_uint32 *) hostEntry -> h_addr_list [0]; + address->host = *(enet_uint32 *)hostEntry->h_addr_list[0]; - return 0; + return 0; } -int -enet_address_get_host_ip (const ENetAddress * address, char * name, size_t nameLength) +int enet_address_get_host_ip(const ENetAddress *address, char *name, size_t nameLength) { - char * addr = inet_ntoa (* (struct in_addr *) & address -> host); - if (addr == NULL) - return -1; - strncpy (name, addr, nameLength); - return 0; + char *addr = inet_ntoa(*(struct in_addr *)&address->host); + if (addr == NULL) + return -1; + strncpy(name, addr, nameLength); + return 0; } -int -enet_address_get_host (const ENetAddress * address, char * name, size_t nameLength) +int enet_address_get_host(const ENetAddress *address, char *name, size_t nameLength) { - struct in_addr in; - struct hostent * hostEntry; - - in.s_addr = address -> host; - - hostEntry = gethostbyaddr ((char *) & in, sizeof (struct in_addr), AF_INET); - if (hostEntry == NULL) - return enet_address_get_host_ip (address, name, nameLength); + struct in_addr in; + struct hostent *hostEntry; - strncpy (name, hostEntry -> h_name, nameLength); + in.s_addr = address->host; - return 0; + hostEntry = gethostbyaddr((char *)&in, sizeof(struct in_addr), AF_INET); + if (hostEntry == NULL) + return enet_address_get_host_ip(address, name, nameLength); + + strncpy(name, hostEntry->h_name, nameLength); + + return 0; } -int -enet_socket_bind (ENetSocket socket, const ENetAddress * address) +int enet_socket_bind(ENetSocket socket, const ENetAddress *address) { - struct sockaddr_in sin; + struct sockaddr_in sin; - memset (& sin, 0, sizeof (struct sockaddr_in)); + memset(&sin, 0, sizeof(struct sockaddr_in)); - sin.sin_family = AF_INET; + sin.sin_family = AF_INET; - if (address != NULL) - { - sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); - sin.sin_addr.s_addr = address -> host; - } - else - { - sin.sin_port = 0; - sin.sin_addr.s_addr = INADDR_ANY; - } + if (address != NULL) + { + sin.sin_port = ENET_HOST_TO_NET_16(address->port); + sin.sin_addr.s_addr = address->host; + } + else + { + sin.sin_port = 0; + sin.sin_addr.s_addr = INADDR_ANY; + } - return bind (socket, - (struct sockaddr *) & sin, - sizeof (struct sockaddr_in)) == SOCKET_ERROR ? -1 : 0; + return bind(socket, + (struct sockaddr *)&sin, + sizeof(struct sockaddr_in)) == SOCKET_ERROR + ? -1 + : 0; } -int -enet_socket_listen (ENetSocket socket, int backlog) +int enet_socket_listen(ENetSocket socket, int backlog) { - return listen (socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0; + return listen(socket, backlog < 0 ? SOMAXCONN : backlog) == SOCKET_ERROR ? -1 : 0; } ENetSocket -enet_socket_create (ENetSocketType type) +enet_socket_create(ENetSocketType type) { - return socket (PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); + return socket(PF_INET, type == ENET_SOCKET_TYPE_DATAGRAM ? SOCK_DGRAM : SOCK_STREAM, 0); } -int -enet_socket_set_option (ENetSocket socket, ENetSocketOption option, int value) +int enet_socket_set_option(ENetSocket socket, ENetSocketOption option, int value) { - int result = SOCKET_ERROR; - switch (option) - { - case ENET_SOCKOPT_NONBLOCK: - { - u_long nonBlocking = (u_long) value; - result = ioctlsocket (socket, FIONBIO, & nonBlocking); - break; - } + int result = SOCKET_ERROR; + switch (option) + { + case ENET_SOCKOPT_NONBLOCK: + { + u_long nonBlocking = (u_long)value; + result = ioctlsocket(socket, FIONBIO, &nonBlocking); + break; + } - case ENET_SOCKOPT_BROADCAST: - result = setsockopt (socket, SOL_SOCKET, SO_BROADCAST, (char *) & value, sizeof (int)); - break; + case ENET_SOCKOPT_BROADCAST: + result = setsockopt(socket, SOL_SOCKET, SO_BROADCAST, (char *)&value, sizeof(int)); + break; - case ENET_SOCKOPT_REUSEADDR: - result = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR, (char *) & value, sizeof (int)); - break; + case ENET_SOCKOPT_REUSEADDR: + result = setsockopt(socket, SOL_SOCKET, SO_REUSEADDR, (char *)&value, sizeof(int)); + break; - case ENET_SOCKOPT_RCVBUF: - result = setsockopt (socket, SOL_SOCKET, SO_RCVBUF, (char *) & value, sizeof (int)); - break; + case ENET_SOCKOPT_RCVBUF: + result = setsockopt(socket, SOL_SOCKET, SO_RCVBUF, (char *)&value, sizeof(int)); + break; - case ENET_SOCKOPT_SNDBUF: - result = setsockopt (socket, SOL_SOCKET, SO_SNDBUF, (char *) & value, sizeof (int)); - break; + case ENET_SOCKOPT_SNDBUF: + result = setsockopt(socket, SOL_SOCKET, SO_SNDBUF, (char *)&value, sizeof(int)); + break; - case ENET_SOCKOPT_RCVTIMEO: - result = setsockopt (socket, SOL_SOCKET, SO_RCVTIMEO, (char *) & value, sizeof (int)); - break; + case ENET_SOCKOPT_RCVTIMEO: + result = setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (char *)&value, sizeof(int)); + break; - case ENET_SOCKOPT_SNDTIMEO: - result = setsockopt (socket, SOL_SOCKET, SO_SNDTIMEO, (char *) & value, sizeof (int)); - break; + case ENET_SOCKOPT_SNDTIMEO: + result = setsockopt(socket, SOL_SOCKET, SO_SNDTIMEO, (char *)&value, sizeof(int)); + break; - default: - break; - } - return result == SOCKET_ERROR ? -1 : 0; + default: + break; + } + return result == SOCKET_ERROR ? -1 : 0; } -int -enet_socket_connect (ENetSocket socket, const ENetAddress * address) +int enet_socket_connect(ENetSocket socket, const ENetAddress *address) { - struct sockaddr_in sin; - int result; + struct sockaddr_in sin; + int result; - memset (& sin, 0, sizeof (struct sockaddr_in)); + memset(&sin, 0, sizeof(struct sockaddr_in)); - sin.sin_family = AF_INET; - sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); - sin.sin_addr.s_addr = address -> host; + sin.sin_family = AF_INET; + sin.sin_port = ENET_HOST_TO_NET_16(address->port); + sin.sin_addr.s_addr = address->host; - result = connect (socket, (struct sockaddr *) & sin, sizeof (struct sockaddr_in)); - if (result == SOCKET_ERROR && WSAGetLastError () != WSAEWOULDBLOCK) - return -1; + result = connect(socket, (struct sockaddr *)&sin, sizeof(struct sockaddr_in)); + if (result == SOCKET_ERROR && WSAGetLastError() != WSAEWOULDBLOCK) + return -1; - return 0; + return 0; } ENetSocket -enet_socket_accept (ENetSocket socket, ENetAddress * address) +enet_socket_accept(ENetSocket socket, ENetAddress *address) { - SOCKET result; - struct sockaddr_in sin; - int sinLength = sizeof (struct sockaddr_in); + SOCKET result; + struct sockaddr_in sin; + int sinLength = sizeof(struct sockaddr_in); - result = accept (socket, - address != NULL ? (struct sockaddr *) & sin : NULL, - address != NULL ? & sinLength : NULL); + result = accept(socket, + address != NULL ? (struct sockaddr *)&sin : NULL, + address != NULL ? &sinLength : NULL); - if (result == INVALID_SOCKET) - return ENET_SOCKET_NULL; + if (result == INVALID_SOCKET) + return ENET_SOCKET_NULL; - if (address != NULL) - { - address -> host = (enet_uint32) sin.sin_addr.s_addr; - address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); - } + if (address != NULL) + { + address->host = (enet_uint32)sin.sin_addr.s_addr; + address->port = ENET_NET_TO_HOST_16(sin.sin_port); + } - return result; + return result; } -int -enet_socket_shutdown (ENetSocket socket, ENetSocketShutdown how) +int enet_socket_shutdown(ENetSocket socket, ENetSocketShutdown how) { - return shutdown (socket, (int) how) == SOCKET_ERROR ? -1 : 0; + return shutdown(socket, (int)how) == SOCKET_ERROR ? -1 : 0; } -void -enet_socket_destroy (ENetSocket socket) +void enet_socket_destroy(ENetSocket socket) { - if (socket != INVALID_SOCKET) - closesocket (socket); + if (socket != INVALID_SOCKET) + closesocket(socket); } -int -enet_socket_send (ENetSocket socket, - const ENetAddress * address, - const ENetBuffer * buffers, - size_t bufferCount) +int enet_socket_send(ENetSocket socket, + const ENetAddress *address, + const ENetBuffer *buffers, + size_t bufferCount) { - struct sockaddr_in sin; - DWORD sentLength; + struct sockaddr_in sin; + DWORD sentLength; - if (address != NULL) - { - memset (& sin, 0, sizeof (struct sockaddr_in)); + if (address != NULL) + { + memset(&sin, 0, sizeof(struct sockaddr_in)); - sin.sin_family = AF_INET; - sin.sin_port = ENET_HOST_TO_NET_16 (address -> port); - sin.sin_addr.s_addr = address -> host; - } + sin.sin_family = AF_INET; + sin.sin_port = ENET_HOST_TO_NET_16(address->port); + sin.sin_addr.s_addr = address->host; + } - if (WSASendTo (socket, - (LPWSABUF) buffers, - (DWORD) bufferCount, - & sentLength, - 0, - address != NULL ? (struct sockaddr *) & sin : NULL, - address != NULL ? sizeof (struct sockaddr_in) : 0, - NULL, - NULL) == SOCKET_ERROR) - { - if (WSAGetLastError () == WSAEWOULDBLOCK) - return 0; + if (WSASendTo(socket, + (LPWSABUF)buffers, + (DWORD)bufferCount, + &sentLength, + 0, + address != NULL ? (struct sockaddr *)&sin : NULL, + address != NULL ? sizeof(struct sockaddr_in) : 0, + NULL, + NULL) == SOCKET_ERROR) + { + if (WSAGetLastError() == WSAEWOULDBLOCK) + return 0; - return -1; - } + return -1; + } - return (int) sentLength; + return (int)sentLength; } -int -enet_socket_receive (ENetSocket socket, - ENetAddress * address, - ENetBuffer * buffers, - size_t bufferCount) +int enet_socket_receive(ENetSocket socket, + ENetAddress *address, + ENetBuffer *buffers, + size_t bufferCount) { - INT sinLength = sizeof (struct sockaddr_in); - DWORD flags = 0, - recvLength; - struct sockaddr_in sin; + INT sinLength = sizeof(struct sockaddr_in); + DWORD flags = 0, + recvLength; + struct sockaddr_in sin; - if (WSARecvFrom (socket, - (LPWSABUF) buffers, - (DWORD) bufferCount, - & recvLength, - & flags, - address != NULL ? (struct sockaddr *) & sin : NULL, - address != NULL ? & sinLength : NULL, - NULL, - NULL) == SOCKET_ERROR) - { - switch (WSAGetLastError ()) - { - case WSAEWOULDBLOCK: - case WSAECONNRESET: - return 0; - } + if (WSARecvFrom(socket, + (LPWSABUF)buffers, + (DWORD)bufferCount, + &recvLength, + &flags, + address != NULL ? (struct sockaddr *)&sin : NULL, + address != NULL ? &sinLength : NULL, + NULL, + NULL) == SOCKET_ERROR) + { + switch (WSAGetLastError()) + { + case WSAEWOULDBLOCK: + case WSAECONNRESET: + return 0; + } - return -1; - } + return -1; + } - if (flags & MSG_PARTIAL) - return -1; + if (flags & MSG_PARTIAL) + return -1; - if (address != NULL) - { - address -> host = (enet_uint32) sin.sin_addr.s_addr; - address -> port = ENET_NET_TO_HOST_16 (sin.sin_port); - } + if (address != NULL) + { + address->host = (enet_uint32)sin.sin_addr.s_addr; + address->port = ENET_NET_TO_HOST_16(sin.sin_port); + } - return (int) recvLength; + return (int)recvLength; } -int -enet_socketset_select (ENetSocket maxSocket, ENetSocketSet * readSet, ENetSocketSet * writeSet, enet_uint32 timeout) +int enet_socketset_select(ENetSocket maxSocket, ENetSocketSet *readSet, ENetSocketSet *writeSet, enet_uint32 timeout) { - struct timeval timeVal; + struct timeval timeVal; - timeVal.tv_sec = timeout / 1000; - timeVal.tv_usec = (timeout % 1000) * 1000; + timeVal.tv_sec = timeout / 1000; + timeVal.tv_usec = (timeout % 1000) * 1000; - return select (maxSocket + 1, readSet, writeSet, NULL, & timeVal); + return select(maxSocket + 1, readSet, writeSet, NULL, &timeVal); } -int -enet_socket_wait (ENetSocket socket, enet_uint32 * condition, enet_uint32 timeout) +int enet_socket_wait(ENetSocket socket, enet_uint32 *condition, enet_uint32 timeout) { - fd_set readSet, writeSet; - struct timeval timeVal; - int selectCount; - - timeVal.tv_sec = timeout / 1000; - timeVal.tv_usec = (timeout % 1000) * 1000; - - FD_ZERO (& readSet); - FD_ZERO (& writeSet); + fd_set readSet, writeSet; + struct timeval timeVal; + int selectCount; - if (* condition & ENET_SOCKET_WAIT_SEND) - FD_SET (socket, & writeSet); + timeVal.tv_sec = timeout / 1000; + timeVal.tv_usec = (timeout % 1000) * 1000; - if (* condition & ENET_SOCKET_WAIT_RECEIVE) - FD_SET (socket, & readSet); + FD_ZERO(&readSet); + FD_ZERO(&writeSet); - selectCount = select (socket + 1, & readSet, & writeSet, NULL, & timeVal); + if (*condition & ENET_SOCKET_WAIT_SEND) + FD_SET(socket, &writeSet); - if (selectCount < 0) - return -1; + if (*condition & ENET_SOCKET_WAIT_RECEIVE) + FD_SET(socket, &readSet); - * condition = ENET_SOCKET_WAIT_NONE; + selectCount = select(socket + 1, &readSet, &writeSet, NULL, &timeVal); - if (selectCount == 0) - return 0; + if (selectCount < 0) + return -1; - if (FD_ISSET (socket, & writeSet)) - * condition |= ENET_SOCKET_WAIT_SEND; - - if (FD_ISSET (socket, & readSet)) - * condition |= ENET_SOCKET_WAIT_RECEIVE; + *condition = ENET_SOCKET_WAIT_NONE; - return 0; -} + if (selectCount == 0) + return 0; + + if (FD_ISSET(socket, &writeSet)) + *condition |= ENET_SOCKET_WAIT_SEND; + + if (FD_ISSET(socket, &readSet)) + *condition |= ENET_SOCKET_WAIT_RECEIVE; + + return 0; +} #endif - diff --git a/examples/ThirdPartyLibs/glad/EGL/eglplatform.h b/examples/ThirdPartyLibs/glad/EGL/eglplatform.h index bf9ec0bf5..694ef5679 100644 --- a/examples/ThirdPartyLibs/glad/EGL/eglplatform.h +++ b/examples/ThirdPartyLibs/glad/EGL/eglplatform.h @@ -51,7 +51,7 @@ #endif #ifndef EGLAPIENTRY -#define EGLAPIENTRY KHRONOS_APIENTRY +#define EGLAPIENTRY KHRONOS_APIENTRY #endif #define EGLAPIENTRYP EGLAPIENTRY* @@ -73,42 +73,42 @@ #endif #include -typedef HDC EGLNativeDisplayType; +typedef HDC EGLNativeDisplayType; typedef HBITMAP EGLNativePixmapType; -typedef HWND EGLNativeWindowType; +typedef HWND EGLNativeWindowType; -#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */ +#elif defined(__WINSCW__) || defined(__SYMBIAN32__) /* Symbian */ -typedef int EGLNativeDisplayType; +typedef int EGLNativeDisplayType; typedef void *EGLNativeWindowType; typedef void *EGLNativePixmapType; #elif defined(WL_EGL_PLATFORM) -typedef struct wl_display *EGLNativeDisplayType; -typedef struct wl_egl_pixmap *EGLNativePixmapType; -typedef struct wl_egl_window *EGLNativeWindowType; +typedef struct wl_display *EGLNativeDisplayType; +typedef struct wl_egl_pixmap *EGLNativePixmapType; +typedef struct wl_egl_window *EGLNativeWindowType; #elif defined(__GBM__) -typedef struct gbm_device *EGLNativeDisplayType; -typedef struct gbm_bo *EGLNativePixmapType; -typedef void *EGLNativeWindowType; +typedef struct gbm_device *EGLNativeDisplayType; +typedef struct gbm_bo *EGLNativePixmapType; +typedef void *EGLNativeWindowType; #elif defined(__ANDROID__) || defined(ANDROID) struct ANativeWindow; struct egl_native_pixmap_t; -typedef struct ANativeWindow* EGLNativeWindowType; -typedef struct egl_native_pixmap_t* EGLNativePixmapType; -typedef void* EGLNativeDisplayType; +typedef struct ANativeWindow* EGLNativeWindowType; +typedef struct egl_native_pixmap_t* EGLNativePixmapType; +typedef void* EGLNativeDisplayType; #elif defined(__unix__) || defined(__APPLE__) #if defined(MESA_EGL_NO_X11_HEADERS) -typedef void *EGLNativeDisplayType; +typedef void *EGLNativeDisplayType; typedef khronos_uintptr_t EGLNativePixmapType; typedef khronos_uintptr_t EGLNativeWindowType; @@ -119,16 +119,16 @@ typedef khronos_uintptr_t EGLNativeWindowType; #include typedef Display *EGLNativeDisplayType; -typedef Pixmap EGLNativePixmapType; -typedef Window EGLNativeWindowType; +typedef Pixmap EGLNativePixmapType; +typedef Window EGLNativeWindowType; #endif /* MESA_EGL_NO_X11_HEADERS */ #elif __HAIKU__ #include -typedef void *EGLNativeDisplayType; -typedef khronos_uintptr_t EGLNativePixmapType; -typedef khronos_uintptr_t EGLNativeWindowType; +typedef void *EGLNativeDisplayType; +typedef khronos_uintptr_t EGLNativePixmapType; +typedef khronos_uintptr_t EGLNativeWindowType; #else #error "Platform not recognized" @@ -136,9 +136,8 @@ typedef khronos_uintptr_t EGLNativeWindowType; /* EGL 1.2 types, renamed for consistency in EGL 1.3 */ typedef EGLNativeDisplayType NativeDisplayType; -typedef EGLNativePixmapType NativePixmapType; -typedef EGLNativeWindowType NativeWindowType; - +typedef EGLNativePixmapType NativePixmapType; +typedef EGLNativeWindowType NativeWindowType; /* Define EGLint. This must be a signed integral type large enough to contain * all legal attribute names and values passed into and out of EGL, whether @@ -149,12 +148,11 @@ typedef EGLNativeWindowType NativeWindowType; */ typedef khronos_int32_t EGLint; - /* C++ / C typecast macros for special EGL handle values */ #if defined(__cplusplus) #define EGL_CAST(type, value) (static_cast(value)) #else -#define EGL_CAST(type, value) ((type) (value)) +#define EGL_CAST(type, value) ((type)(value)) #endif #endif /* __eglplatform_h */ diff --git a/examples/ThirdPartyLibs/glad/KHR/khrplatform.h b/examples/ThirdPartyLibs/glad/KHR/khrplatform.h index 1ad3554a7..6b368ee99 100644 --- a/examples/ThirdPartyLibs/glad/KHR/khrplatform.h +++ b/examples/ThirdPartyLibs/glad/KHR/khrplatform.h @@ -98,13 +98,13 @@ * This precedes the return type of the function in the function prototype. */ #if defined(_WIN32) && !defined(__SCITECH_SNAP__) -# define KHRONOS_APICALL __declspec(dllimport) -#elif defined (__SYMBIAN32__) -# define KHRONOS_APICALL IMPORT_C +#define KHRONOS_APICALL __declspec(dllimport) +#elif defined(__SYMBIAN32__) +#define KHRONOS_APICALL IMPORT_C #elif defined(__ANDROID__) -# define KHRONOS_APICALL __attribute__((visibility("default"))) +#define KHRONOS_APICALL __attribute__((visibility("default"))) #else -# define KHRONOS_APICALL +#define KHRONOS_APICALL #endif /*------------------------------------------------------------------------- @@ -114,10 +114,10 @@ * name in the function prototype. */ #if defined(_WIN32) && !defined(_WIN32_WCE) && !defined(__SCITECH_SNAP__) - /* Win32 but not WinCE */ -# define KHRONOS_APIENTRY __stdcall +/* Win32 but not WinCE */ +#define KHRONOS_APIENTRY __stdcall #else -# define KHRONOS_APIENTRY +#define KHRONOS_APIENTRY #endif /*------------------------------------------------------------------------- @@ -125,7 +125,7 @@ *------------------------------------------------------------------------- * This follows the closing parenthesis of the function prototype arguments. */ -#if defined (__ARMCC_2__) +#if defined(__ARMCC_2__) #define KHRONOS_APIATTRIBUTES __softfp #else #define KHRONOS_APIATTRIBUTES @@ -136,69 +136,68 @@ *-----------------------------------------------------------------------*/ #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__GNUC__) || defined(__SCO__) || defined(__USLC__) - /* * Using */ #include -typedef int32_t khronos_int32_t; -typedef uint32_t khronos_uint32_t; -typedef int64_t khronos_int64_t; -typedef uint64_t khronos_uint64_t; -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 -#elif defined(__VMS ) || defined(__sgi) +#elif defined(__VMS) || defined(__sgi) /* * Using */ #include -typedef int32_t khronos_int32_t; -typedef uint32_t khronos_uint32_t; -typedef int64_t khronos_int64_t; -typedef uint64_t khronos_uint64_t; -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 #elif defined(_WIN32) && !defined(__SCITECH_SNAP__) /* * Win32 */ -typedef __int32 khronos_int32_t; -typedef unsigned __int32 khronos_uint32_t; -typedef __int64 khronos_int64_t; -typedef unsigned __int64 khronos_uint64_t; -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 +typedef __int32 khronos_int32_t; +typedef unsigned __int32 khronos_uint32_t; +typedef __int64 khronos_int64_t; +typedef unsigned __int64 khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 #elif defined(__sun__) || defined(__digital__) /* * Sun or Digital */ -typedef int khronos_int32_t; -typedef unsigned int khronos_uint32_t; +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; #if defined(__arch64__) || defined(_LP64) -typedef long int khronos_int64_t; -typedef unsigned long int khronos_uint64_t; +typedef long int khronos_int64_t; +typedef unsigned long int khronos_uint64_t; #else -typedef long long int khronos_int64_t; -typedef unsigned long long int khronos_uint64_t; +typedef long long int khronos_int64_t; +typedef unsigned long long int khronos_uint64_t; #endif /* __arch64__ */ -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 #elif 0 /* * Hypothetical platform with no float or int64 support */ -typedef int khronos_int32_t; -typedef unsigned int khronos_uint32_t; -#define KHRONOS_SUPPORT_INT64 0 -#define KHRONOS_SUPPORT_FLOAT 0 +typedef int khronos_int32_t; +typedef unsigned int khronos_uint32_t; +#define KHRONOS_SUPPORT_INT64 0 +#define KHRONOS_SUPPORT_FLOAT 0 #else @@ -206,23 +205,22 @@ typedef unsigned int khronos_uint32_t; * Generic fallback */ #include -typedef int32_t khronos_int32_t; -typedef uint32_t khronos_uint32_t; -typedef int64_t khronos_int64_t; -typedef uint64_t khronos_uint64_t; -#define KHRONOS_SUPPORT_INT64 1 -#define KHRONOS_SUPPORT_FLOAT 1 +typedef int32_t khronos_int32_t; +typedef uint32_t khronos_uint32_t; +typedef int64_t khronos_int64_t; +typedef uint64_t khronos_uint64_t; +#define KHRONOS_SUPPORT_INT64 1 +#define KHRONOS_SUPPORT_FLOAT 1 #endif - /* * Types that are (so far) the same on all platforms */ -typedef signed char khronos_int8_t; -typedef unsigned char khronos_uint8_t; -typedef signed short int khronos_int16_t; -typedef unsigned short int khronos_uint16_t; +typedef signed char khronos_int8_t; +typedef unsigned char khronos_uint8_t; +typedef signed short int khronos_int16_t; +typedef unsigned short int khronos_uint16_t; /* * Types that differ between LLP64 and LP64 architectures - in LLP64, @@ -230,22 +228,22 @@ typedef unsigned short int khronos_uint16_t; * to be the only LLP64 architecture in current use. */ #ifdef _WIN64 -typedef signed long long int khronos_intptr_t; +typedef signed long long int khronos_intptr_t; typedef unsigned long long int khronos_uintptr_t; -typedef signed long long int khronos_ssize_t; +typedef signed long long int khronos_ssize_t; typedef unsigned long long int khronos_usize_t; #else -typedef signed long int khronos_intptr_t; -typedef unsigned long int khronos_uintptr_t; -typedef signed long int khronos_ssize_t; -typedef unsigned long int khronos_usize_t; +typedef signed long int khronos_intptr_t; +typedef unsigned long int khronos_uintptr_t; +typedef signed long int khronos_ssize_t; +typedef unsigned long int khronos_usize_t; #endif #if KHRONOS_SUPPORT_FLOAT /* * Float type */ -typedef float khronos_float_t; +typedef float khronos_float_t; #endif #if KHRONOS_SUPPORT_INT64 @@ -258,8 +256,8 @@ typedef float khronos_float_t; * 64 bit value that wraps back to 0 every 584 years. Time intervals * may be either signed or unsigned. */ -typedef khronos_uint64_t khronos_utime_nanoseconds_t; -typedef khronos_int64_t khronos_stime_nanoseconds_t; +typedef khronos_uint64_t khronos_utime_nanoseconds_t; +typedef khronos_int64_t khronos_stime_nanoseconds_t; #endif /* @@ -275,10 +273,11 @@ typedef khronos_int64_t khronos_stime_nanoseconds_t; * Values other than zero should be considered to be true. Therefore * comparisons should not be made against KHRONOS_TRUE. */ -typedef enum { - KHRONOS_FALSE = 0, - KHRONOS_TRUE = 1, - KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM +typedef enum +{ + KHRONOS_FALSE = 0, + KHRONOS_TRUE = 1, + KHRONOS_BOOLEAN_ENUM_FORCE_SIZE = KHRONOS_MAX_ENUM } khronos_boolean_enum_t; #endif /* __khrplatform_h_ */ diff --git a/examples/ThirdPartyLibs/glad/egl.c b/examples/ThirdPartyLibs/glad/egl.c index 57c1181d6..d1aa1fa39 100644 --- a/examples/ThirdPartyLibs/glad/egl.c +++ b/examples/ThirdPartyLibs/glad/egl.c @@ -7,7 +7,7 @@ #define GLAD_IMPL_UTIL_C_ #if _MSC_VER >= 1400 -#define GLAD_IMPL_UTIL_STRNCPY(dest, source, len) strncpy_s(dest, len, source, len-1); +#define GLAD_IMPL_UTIL_STRNCPY(dest, source, len) strncpy_s(dest, len, source, len - 1); #else #define GLAD_IMPL_UTIL_STRNCPY(dest, source, len) strncpy(dest, source, len); #endif @@ -20,7 +20,6 @@ #endif /* GLAD_IMPL_UTIL_C_ */ - int GLAD_EGL_VERSION_1_0; int GLAD_EGL_VERSION_1_1; int GLAD_EGL_VERSION_1_2; @@ -35,8 +34,6 @@ int GLAD_EGL_EXT_device_query; int GLAD_EGL_EXT_device_base; int GLAD_EGL_NV_cuda_event; - - PFNEGLQUERYDEVICESEXTPROC glad_eglQueryDevicesEXT; PFNEGLCREATEPBUFFERSURFACEPROC glad_eglCreatePbufferSurface; PFNEGLGETERRORPROC glad_eglGetError; @@ -90,206 +87,229 @@ PFNEGLGETCONFIGSPROC glad_eglGetConfigs; PFNEGLWAITCLIENTPROC glad_eglWaitClient; PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC glad_eglCreatePbufferFromClientBuffer; - -static void load_EGL_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_EGL_VERSION_1_0) return; - eglCreatePbufferSurface = (PFNEGLCREATEPBUFFERSURFACEPROC) load("eglCreatePbufferSurface", userptr); - eglGetError = (PFNEGLGETERRORPROC) load("eglGetError", userptr); - eglGetProcAddress = (PFNEGLGETPROCADDRESSPROC) load("eglGetProcAddress", userptr); - eglGetCurrentDisplay = (PFNEGLGETCURRENTDISPLAYPROC) load("eglGetCurrentDisplay", userptr); - eglQueryContext = (PFNEGLQUERYCONTEXTPROC) load("eglQueryContext", userptr); - eglSwapBuffers = (PFNEGLSWAPBUFFERSPROC) load("eglSwapBuffers", userptr); - eglCreateContext = (PFNEGLCREATECONTEXTPROC) load("eglCreateContext", userptr); - eglChooseConfig = (PFNEGLCHOOSECONFIGPROC) load("eglChooseConfig", userptr); - eglWaitNative = (PFNEGLWAITNATIVEPROC) load("eglWaitNative", userptr); - eglTerminate = (PFNEGLTERMINATEPROC) load("eglTerminate", userptr); - eglCopyBuffers = (PFNEGLCOPYBUFFERSPROC) load("eglCopyBuffers", userptr); - eglGetConfigAttrib = (PFNEGLGETCONFIGATTRIBPROC) load("eglGetConfigAttrib", userptr); - eglGetCurrentSurface = (PFNEGLGETCURRENTSURFACEPROC) load("eglGetCurrentSurface", userptr); - eglCreatePixmapSurface = (PFNEGLCREATEPIXMAPSURFACEPROC) load("eglCreatePixmapSurface", userptr); - eglGetDisplay = (PFNEGLGETDISPLAYPROC) load("eglGetDisplay", userptr); - eglQueryString = (PFNEGLQUERYSTRINGPROC) load("eglQueryString", userptr); - eglDestroyContext = (PFNEGLDESTROYCONTEXTPROC) load("eglDestroyContext", userptr); - eglCreateWindowSurface = (PFNEGLCREATEWINDOWSURFACEPROC) load("eglCreateWindowSurface", userptr); - eglInitialize = (PFNEGLINITIALIZEPROC) load("eglInitialize", userptr); - eglDestroySurface = (PFNEGLDESTROYSURFACEPROC) load("eglDestroySurface", userptr); - eglMakeCurrent = (PFNEGLMAKECURRENTPROC) load("eglMakeCurrent", userptr); - eglWaitGL = (PFNEGLWAITGLPROC) load("eglWaitGL", userptr); - eglQuerySurface = (PFNEGLQUERYSURFACEPROC) load("eglQuerySurface", userptr); - eglGetConfigs = (PFNEGLGETCONFIGSPROC) load("eglGetConfigs", userptr); +static void load_EGL_VERSION_1_0(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_EGL_VERSION_1_0) return; + eglCreatePbufferSurface = (PFNEGLCREATEPBUFFERSURFACEPROC)load("eglCreatePbufferSurface", userptr); + eglGetError = (PFNEGLGETERRORPROC)load("eglGetError", userptr); + eglGetProcAddress = (PFNEGLGETPROCADDRESSPROC)load("eglGetProcAddress", userptr); + eglGetCurrentDisplay = (PFNEGLGETCURRENTDISPLAYPROC)load("eglGetCurrentDisplay", userptr); + eglQueryContext = (PFNEGLQUERYCONTEXTPROC)load("eglQueryContext", userptr); + eglSwapBuffers = (PFNEGLSWAPBUFFERSPROC)load("eglSwapBuffers", userptr); + eglCreateContext = (PFNEGLCREATECONTEXTPROC)load("eglCreateContext", userptr); + eglChooseConfig = (PFNEGLCHOOSECONFIGPROC)load("eglChooseConfig", userptr); + eglWaitNative = (PFNEGLWAITNATIVEPROC)load("eglWaitNative", userptr); + eglTerminate = (PFNEGLTERMINATEPROC)load("eglTerminate", userptr); + eglCopyBuffers = (PFNEGLCOPYBUFFERSPROC)load("eglCopyBuffers", userptr); + eglGetConfigAttrib = (PFNEGLGETCONFIGATTRIBPROC)load("eglGetConfigAttrib", userptr); + eglGetCurrentSurface = (PFNEGLGETCURRENTSURFACEPROC)load("eglGetCurrentSurface", userptr); + eglCreatePixmapSurface = (PFNEGLCREATEPIXMAPSURFACEPROC)load("eglCreatePixmapSurface", userptr); + eglGetDisplay = (PFNEGLGETDISPLAYPROC)load("eglGetDisplay", userptr); + eglQueryString = (PFNEGLQUERYSTRINGPROC)load("eglQueryString", userptr); + eglDestroyContext = (PFNEGLDESTROYCONTEXTPROC)load("eglDestroyContext", userptr); + eglCreateWindowSurface = (PFNEGLCREATEWINDOWSURFACEPROC)load("eglCreateWindowSurface", userptr); + eglInitialize = (PFNEGLINITIALIZEPROC)load("eglInitialize", userptr); + eglDestroySurface = (PFNEGLDESTROYSURFACEPROC)load("eglDestroySurface", userptr); + eglMakeCurrent = (PFNEGLMAKECURRENTPROC)load("eglMakeCurrent", userptr); + eglWaitGL = (PFNEGLWAITGLPROC)load("eglWaitGL", userptr); + eglQuerySurface = (PFNEGLQUERYSURFACEPROC)load("eglQuerySurface", userptr); + eglGetConfigs = (PFNEGLGETCONFIGSPROC)load("eglGetConfigs", userptr); } -static void load_EGL_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_EGL_VERSION_1_1) return; - eglReleaseTexImage = (PFNEGLRELEASETEXIMAGEPROC) load("eglReleaseTexImage", userptr); - eglSurfaceAttrib = (PFNEGLSURFACEATTRIBPROC) load("eglSurfaceAttrib", userptr); - eglBindTexImage = (PFNEGLBINDTEXIMAGEPROC) load("eglBindTexImage", userptr); - eglSwapInterval = (PFNEGLSWAPINTERVALPROC) load("eglSwapInterval", userptr); +static void load_EGL_VERSION_1_1(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_EGL_VERSION_1_1) return; + eglReleaseTexImage = (PFNEGLRELEASETEXIMAGEPROC)load("eglReleaseTexImage", userptr); + eglSurfaceAttrib = (PFNEGLSURFACEATTRIBPROC)load("eglSurfaceAttrib", userptr); + eglBindTexImage = (PFNEGLBINDTEXIMAGEPROC)load("eglBindTexImage", userptr); + eglSwapInterval = (PFNEGLSWAPINTERVALPROC)load("eglSwapInterval", userptr); } -static void load_EGL_VERSION_1_2( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_EGL_VERSION_1_2) return; - eglBindAPI = (PFNEGLBINDAPIPROC) load("eglBindAPI", userptr); - eglQueryAPI = (PFNEGLQUERYAPIPROC) load("eglQueryAPI", userptr); - eglWaitClient = (PFNEGLWAITCLIENTPROC) load("eglWaitClient", userptr); - eglCreatePbufferFromClientBuffer = (PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC) load("eglCreatePbufferFromClientBuffer", userptr); - eglReleaseThread = (PFNEGLRELEASETHREADPROC) load("eglReleaseThread", userptr); +static void load_EGL_VERSION_1_2(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_EGL_VERSION_1_2) return; + eglBindAPI = (PFNEGLBINDAPIPROC)load("eglBindAPI", userptr); + eglQueryAPI = (PFNEGLQUERYAPIPROC)load("eglQueryAPI", userptr); + eglWaitClient = (PFNEGLWAITCLIENTPROC)load("eglWaitClient", userptr); + eglCreatePbufferFromClientBuffer = (PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC)load("eglCreatePbufferFromClientBuffer", userptr); + eglReleaseThread = (PFNEGLRELEASETHREADPROC)load("eglReleaseThread", userptr); } -static void load_EGL_VERSION_1_4( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_EGL_VERSION_1_4) return; - eglGetCurrentContext = (PFNEGLGETCURRENTCONTEXTPROC) load("eglGetCurrentContext", userptr); +static void load_EGL_VERSION_1_4(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_EGL_VERSION_1_4) return; + eglGetCurrentContext = (PFNEGLGETCURRENTCONTEXTPROC)load("eglGetCurrentContext", userptr); } -static void load_EGL_VERSION_1_5( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_EGL_VERSION_1_5) return; - eglDestroySync = (PFNEGLDESTROYSYNCPROC) load("eglDestroySync", userptr); - eglCreateImage = (PFNEGLCREATEIMAGEPROC) load("eglCreateImage", userptr); - eglGetPlatformDisplay = (PFNEGLGETPLATFORMDISPLAYPROC) load("eglGetPlatformDisplay", userptr); - eglDestroyImage = (PFNEGLDESTROYIMAGEPROC) load("eglDestroyImage", userptr); - eglClientWaitSync = (PFNEGLCLIENTWAITSYNCPROC) load("eglClientWaitSync", userptr); - eglWaitSync = (PFNEGLWAITSYNCPROC) load("eglWaitSync", userptr); - eglCreateSync = (PFNEGLCREATESYNCPROC) load("eglCreateSync", userptr); - eglGetSyncAttrib = (PFNEGLGETSYNCATTRIBPROC) load("eglGetSyncAttrib", userptr); - eglCreatePlatformWindowSurface = (PFNEGLCREATEPLATFORMWINDOWSURFACEPROC) load("eglCreatePlatformWindowSurface", userptr); - eglCreatePlatformPixmapSurface = (PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC) load("eglCreatePlatformPixmapSurface", userptr); +static void load_EGL_VERSION_1_5(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_EGL_VERSION_1_5) return; + eglDestroySync = (PFNEGLDESTROYSYNCPROC)load("eglDestroySync", userptr); + eglCreateImage = (PFNEGLCREATEIMAGEPROC)load("eglCreateImage", userptr); + eglGetPlatformDisplay = (PFNEGLGETPLATFORMDISPLAYPROC)load("eglGetPlatformDisplay", userptr); + eglDestroyImage = (PFNEGLDESTROYIMAGEPROC)load("eglDestroyImage", userptr); + eglClientWaitSync = (PFNEGLCLIENTWAITSYNCPROC)load("eglClientWaitSync", userptr); + eglWaitSync = (PFNEGLWAITSYNCPROC)load("eglWaitSync", userptr); + eglCreateSync = (PFNEGLCREATESYNCPROC)load("eglCreateSync", userptr); + eglGetSyncAttrib = (PFNEGLGETSYNCATTRIBPROC)load("eglGetSyncAttrib", userptr); + eglCreatePlatformWindowSurface = (PFNEGLCREATEPLATFORMWINDOWSURFACEPROC)load("eglCreatePlatformWindowSurface", userptr); + eglCreatePlatformPixmapSurface = (PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC)load("eglCreatePlatformPixmapSurface", userptr); } -static void load_EGL_EXT_platform_base( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_EGL_EXT_platform_base) return; - eglCreatePlatformWindowSurfaceEXT = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC) load("eglCreatePlatformWindowSurfaceEXT", userptr); - eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC) load("eglGetPlatformDisplayEXT", userptr); - eglCreatePlatformPixmapSurfaceEXT = (PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC) load("eglCreatePlatformPixmapSurfaceEXT", userptr); +static void load_EGL_EXT_platform_base(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_EGL_EXT_platform_base) return; + eglCreatePlatformWindowSurfaceEXT = (PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)load("eglCreatePlatformWindowSurfaceEXT", userptr); + eglGetPlatformDisplayEXT = (PFNEGLGETPLATFORMDISPLAYEXTPROC)load("eglGetPlatformDisplayEXT", userptr); + eglCreatePlatformPixmapSurfaceEXT = (PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC)load("eglCreatePlatformPixmapSurfaceEXT", userptr); } -static void load_EGL_EXT_device_enumeration( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_EGL_EXT_device_enumeration) return; - eglQueryDevicesEXT = (PFNEGLQUERYDEVICESEXTPROC) load("eglQueryDevicesEXT", userptr); +static void load_EGL_EXT_device_enumeration(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_EGL_EXT_device_enumeration) return; + eglQueryDevicesEXT = (PFNEGLQUERYDEVICESEXTPROC)load("eglQueryDevicesEXT", userptr); } -static void load_EGL_EXT_device_query( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_EGL_EXT_device_query) return; - eglQueryDisplayAttribEXT = (PFNEGLQUERYDISPLAYATTRIBEXTPROC) load("eglQueryDisplayAttribEXT", userptr); - eglQueryDeviceStringEXT = (PFNEGLQUERYDEVICESTRINGEXTPROC) load("eglQueryDeviceStringEXT", userptr); - eglQueryDeviceAttribEXT = (PFNEGLQUERYDEVICEATTRIBEXTPROC) load("eglQueryDeviceAttribEXT", userptr); - eglQueryDisplayAttribKHR = (PFNEGLQUERYDISPLAYATTRIBKHRPROC) load("eglQueryDisplayAttribKHR", userptr); +static void load_EGL_EXT_device_query(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_EGL_EXT_device_query) return; + eglQueryDisplayAttribEXT = (PFNEGLQUERYDISPLAYATTRIBEXTPROC)load("eglQueryDisplayAttribEXT", userptr); + eglQueryDeviceStringEXT = (PFNEGLQUERYDEVICESTRINGEXTPROC)load("eglQueryDeviceStringEXT", userptr); + eglQueryDeviceAttribEXT = (PFNEGLQUERYDEVICEATTRIBEXTPROC)load("eglQueryDeviceAttribEXT", userptr); + eglQueryDisplayAttribKHR = (PFNEGLQUERYDISPLAYATTRIBKHRPROC)load("eglQueryDisplayAttribKHR", userptr); } -static void load_EGL_EXT_device_base( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_EGL_EXT_device_base) return; - eglQueryDisplayAttribEXT = (PFNEGLQUERYDISPLAYATTRIBEXTPROC) load("eglQueryDisplayAttribEXT", userptr); - eglQueryDevicesEXT = (PFNEGLQUERYDEVICESEXTPROC) load("eglQueryDevicesEXT", userptr); - eglQueryDeviceStringEXT = (PFNEGLQUERYDEVICESTRINGEXTPROC) load("eglQueryDeviceStringEXT", userptr); - eglQueryDeviceAttribEXT = (PFNEGLQUERYDEVICEATTRIBEXTPROC) load("eglQueryDeviceAttribEXT", userptr); - eglQueryDisplayAttribKHR = (PFNEGLQUERYDISPLAYATTRIBKHRPROC) load("eglQueryDisplayAttribKHR", userptr); +static void load_EGL_EXT_device_base(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_EGL_EXT_device_base) return; + eglQueryDisplayAttribEXT = (PFNEGLQUERYDISPLAYATTRIBEXTPROC)load("eglQueryDisplayAttribEXT", userptr); + eglQueryDevicesEXT = (PFNEGLQUERYDEVICESEXTPROC)load("eglQueryDevicesEXT", userptr); + eglQueryDeviceStringEXT = (PFNEGLQUERYDEVICESTRINGEXTPROC)load("eglQueryDeviceStringEXT", userptr); + eglQueryDeviceAttribEXT = (PFNEGLQUERYDEVICEATTRIBEXTPROC)load("eglQueryDeviceAttribEXT", userptr); + eglQueryDisplayAttribKHR = (PFNEGLQUERYDISPLAYATTRIBKHRPROC)load("eglQueryDisplayAttribKHR", userptr); } +static int get_exts(EGLDisplay display, const char **extensions) +{ + *extensions = eglQueryString(display, EGL_EXTENSIONS); - -static int get_exts(EGLDisplay display, const char **extensions) { - *extensions = eglQueryString(display, EGL_EXTENSIONS); - - return extensions != NULL; + return extensions != NULL; } -static int has_ext(const char *extensions, const char *ext) { - const char *loc; - const char *terminator; - if(extensions == NULL) { - return 0; - } - while(1) { - loc = strstr(extensions, ext); - if(loc == NULL) { - return 0; - } - terminator = loc + strlen(ext); - if((loc == extensions || *(loc - 1) == ' ') && - (*terminator == ' ' || *terminator == '\0')) { - return 1; - } - extensions = terminator; - } +static int has_ext(const char *extensions, const char *ext) +{ + const char *loc; + const char *terminator; + if (extensions == NULL) + { + return 0; + } + while (1) + { + loc = strstr(extensions, ext); + if (loc == NULL) + { + return 0; + } + terminator = loc + strlen(ext); + if ((loc == extensions || *(loc - 1) == ' ') && + (*terminator == ' ' || *terminator == '\0')) + { + return 1; + } + extensions = terminator; + } } -static GLADapiproc glad_egl_get_proc_from_userptr(const char *name, void *userptr) { - return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name); +static GLADapiproc glad_egl_get_proc_from_userptr(const char *name, void *userptr) +{ + return (GLAD_GNUC_EXTENSION(GLADapiproc(*)(const char *name)) userptr)(name); } -static int find_extensionsEGL(EGLDisplay display) { - const char *extensions; - if (!get_exts(display, &extensions)) return 0; +static int find_extensionsEGL(EGLDisplay display) +{ + const char *extensions; + if (!get_exts(display, &extensions)) return 0; - GLAD_EGL_EXT_platform_device = has_ext(extensions, "EGL_EXT_platform_device"); - GLAD_EGL_EXT_platform_base = has_ext(extensions, "EGL_EXT_platform_base"); - GLAD_EGL_NV_device_cuda = has_ext(extensions, "EGL_NV_device_cuda"); - GLAD_EGL_EXT_device_enumeration = has_ext(extensions, "EGL_EXT_device_enumeration"); - GLAD_EGL_EXT_device_query = has_ext(extensions, "EGL_EXT_device_query"); - GLAD_EGL_EXT_device_base = has_ext(extensions, "EGL_EXT_device_base"); - GLAD_EGL_NV_cuda_event = has_ext(extensions, "EGL_NV_cuda_event"); + GLAD_EGL_EXT_platform_device = has_ext(extensions, "EGL_EXT_platform_device"); + GLAD_EGL_EXT_platform_base = has_ext(extensions, "EGL_EXT_platform_base"); + GLAD_EGL_NV_device_cuda = has_ext(extensions, "EGL_NV_device_cuda"); + GLAD_EGL_EXT_device_enumeration = has_ext(extensions, "EGL_EXT_device_enumeration"); + GLAD_EGL_EXT_device_query = has_ext(extensions, "EGL_EXT_device_query"); + GLAD_EGL_EXT_device_base = has_ext(extensions, "EGL_EXT_device_base"); + GLAD_EGL_NV_cuda_event = has_ext(extensions, "EGL_NV_cuda_event"); - return 1; + return 1; } -static int find_coreEGL(EGLDisplay display) { - int major, minor; - const char *version; +static int find_coreEGL(EGLDisplay display) +{ + int major, minor; + const char *version; - if (display == NULL) { - display = EGL_NO_DISPLAY; /* this is usually NULL, better safe than sorry */ - } - if (display == EGL_NO_DISPLAY) { - display = eglGetCurrentDisplay(); - } - if (display == EGL_NO_DISPLAY) { - display = eglGetDisplay(EGL_DEFAULT_DISPLAY); - } - if (display == EGL_NO_DISPLAY) { - return 0; - } + if (display == NULL) + { + display = EGL_NO_DISPLAY; /* this is usually NULL, better safe than sorry */ + } + if (display == EGL_NO_DISPLAY) + { + display = eglGetCurrentDisplay(); + } + if (display == EGL_NO_DISPLAY) + { + display = eglGetDisplay(EGL_DEFAULT_DISPLAY); + } + if (display == EGL_NO_DISPLAY) + { + return 0; + } - version = eglQueryString(display, EGL_VERSION); - (void) eglGetError(); + version = eglQueryString(display, EGL_VERSION); + (void)eglGetError(); - if (version == NULL) { - major = 1; - minor = 0; - } else { - GLAD_IMPL_UTIL_SSCANF(version, "%d.%d", &major, &minor); - } + if (version == NULL) + { + major = 1; + minor = 0; + } + else + { + GLAD_IMPL_UTIL_SSCANF(version, "%d.%d", &major, &minor); + } - GLAD_EGL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; - GLAD_EGL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; - GLAD_EGL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; - GLAD_EGL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; - GLAD_EGL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; - GLAD_EGL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; + GLAD_EGL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; + GLAD_EGL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; + GLAD_EGL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; + GLAD_EGL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; + GLAD_EGL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; + GLAD_EGL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; - return GLAD_MAKE_VERSION(major, minor); + return GLAD_MAKE_VERSION(major, minor); } -int gladLoadEGLUserPtr(EGLDisplay display, GLADuserptrloadfunc load, void* userptr) { - int version; - eglGetDisplay = (PFNEGLGETDISPLAYPROC) load("eglGetDisplay", userptr); - eglGetCurrentDisplay = (PFNEGLGETCURRENTDISPLAYPROC) load("eglGetCurrentDisplay", userptr); - eglQueryString = (PFNEGLQUERYSTRINGPROC) load("eglQueryString", userptr); - eglGetError = (PFNEGLGETERRORPROC) load("eglGetError", userptr); - if (eglGetDisplay == NULL || eglGetCurrentDisplay == NULL || eglQueryString == NULL || eglGetError == NULL) return 0; +int gladLoadEGLUserPtr(EGLDisplay display, GLADuserptrloadfunc load, void *userptr) +{ + int version; + eglGetDisplay = (PFNEGLGETDISPLAYPROC)load("eglGetDisplay", userptr); + eglGetCurrentDisplay = (PFNEGLGETCURRENTDISPLAYPROC)load("eglGetCurrentDisplay", userptr); + eglQueryString = (PFNEGLQUERYSTRINGPROC)load("eglQueryString", userptr); + eglGetError = (PFNEGLGETERRORPROC)load("eglGetError", userptr); + if (eglGetDisplay == NULL || eglGetCurrentDisplay == NULL || eglQueryString == NULL || eglGetError == NULL) return 0; - version = find_coreEGL(display); - if (!version) return 0; - load_EGL_VERSION_1_0(load, userptr); - load_EGL_VERSION_1_1(load, userptr); - load_EGL_VERSION_1_2(load, userptr); - load_EGL_VERSION_1_4(load, userptr); - load_EGL_VERSION_1_5(load, userptr); + version = find_coreEGL(display); + if (!version) return 0; + load_EGL_VERSION_1_0(load, userptr); + load_EGL_VERSION_1_1(load, userptr); + load_EGL_VERSION_1_2(load, userptr); + load_EGL_VERSION_1_4(load, userptr); + load_EGL_VERSION_1_5(load, userptr); - if (!find_extensionsEGL(display)) return 0; - load_EGL_EXT_platform_base(load, userptr); - load_EGL_EXT_device_enumeration(load, userptr); - load_EGL_EXT_device_query(load, userptr); - load_EGL_EXT_device_base(load, userptr); + if (!find_extensionsEGL(display)) return 0; + load_EGL_EXT_platform_base(load, userptr); + load_EGL_EXT_device_enumeration(load, userptr); + load_EGL_EXT_device_query(load, userptr); + load_EGL_EXT_device_base(load, userptr); - return version; + return version; } -int gladLoadEGL(EGLDisplay display, GLADloadfunc load) { - return gladLoadEGLUserPtr(display, glad_egl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); +int gladLoadEGL(EGLDisplay display, GLADloadfunc load) +{ + return gladLoadEGLUserPtr(display, glad_egl_get_proc_from_userptr, GLAD_GNUC_EXTENSION(void *) load); } - #ifdef GLAD_EGL #ifndef GLAD_LOADER_LIBRARY_C_ @@ -304,119 +324,137 @@ int gladLoadEGL(EGLDisplay display, GLADloadfunc load) { #include #endif +static void *glad_get_dlopen_handle(const char *lib_names[], int length) +{ + void *handle = NULL; + int i; -static void* glad_get_dlopen_handle(const char *lib_names[], int length) { - void *handle = NULL; - int i; - - for (i = 0; i < length; ++i) { + for (i = 0; i < length; ++i) + { #if GLAD_PLATFORM_WIN32 - #if GLAD_PLATFORM_UWP - size_t buffer_size = (strlen(lib_names[i]) + 1) * sizeof(WCHAR); - LPWSTR buffer = (LPWSTR) malloc(buffer_size); - if (buffer != NULL) { - int ret = MultiByteToWideChar(CP_ACP, 0, lib_names[i], -1, buffer, buffer_size); - if (ret != 0) { - handle = (void*) LoadPackagedLibrary(buffer, 0); - } - free((void*) buffer); - } - #else - handle = (void*) LoadLibraryA(lib_names[i]); - #endif +#if GLAD_PLATFORM_UWP + size_t buffer_size = (strlen(lib_names[i]) + 1) * sizeof(WCHAR); + LPWSTR buffer = (LPWSTR)malloc(buffer_size); + if (buffer != NULL) + { + int ret = MultiByteToWideChar(CP_ACP, 0, lib_names[i], -1, buffer, buffer_size); + if (ret != 0) + { + handle = (void *)LoadPackagedLibrary(buffer, 0); + } + free((void *)buffer); + } #else - handle = dlopen(lib_names[i], RTLD_LAZY | RTLD_LOCAL); + handle = (void *)LoadLibraryA(lib_names[i]); #endif - if (handle != NULL) { - return handle; - } - } +#else + handle = dlopen(lib_names[i], RTLD_LAZY | RTLD_LOCAL); +#endif + if (handle != NULL) + { + return handle; + } + } - return NULL; + return NULL; } -static void glad_close_dlopen_handle(void* handle) { - if (handle != NULL) { +static void glad_close_dlopen_handle(void *handle) +{ + if (handle != NULL) + { #if GLAD_PLATFORM_WIN32 - FreeLibrary((HMODULE) handle); + FreeLibrary((HMODULE)handle); #else - dlclose(handle); + dlclose(handle); #endif - } + } } -static GLADapiproc glad_dlsym_handle(void* handle, const char *name) { - if (handle == NULL) { - return NULL; - } +static GLADapiproc glad_dlsym_handle(void *handle, const char *name) +{ + if (handle == NULL) + { + return NULL; + } #if GLAD_PLATFORM_WIN32 - return (GLADapiproc) GetProcAddress((HMODULE) handle, name); + return (GLADapiproc)GetProcAddress((HMODULE)handle, name); #else - return GLAD_GNUC_EXTENSION (GLADapiproc) dlsym(handle, name); + return GLAD_GNUC_EXTENSION(GLADapiproc) dlsym(handle, name); #endif } #endif /* GLAD_LOADER_LIBRARY_C_ */ -struct _glad_egl_userptr { - void *handle; - PFNEGLGETPROCADDRESSPROC get_proc_address_ptr; +struct _glad_egl_userptr +{ + void *handle; + PFNEGLGETPROCADDRESSPROC get_proc_address_ptr; }; -static GLADapiproc glad_egl_get_proc(const char* name, void *vuserptr) { - struct _glad_egl_userptr userptr = *(struct _glad_egl_userptr*) vuserptr; - GLADapiproc result = NULL; +static GLADapiproc glad_egl_get_proc(const char *name, void *vuserptr) +{ + struct _glad_egl_userptr userptr = *(struct _glad_egl_userptr *)vuserptr; + GLADapiproc result = NULL; - result = glad_dlsym_handle(userptr.handle, name); - if (result == NULL) { - result = GLAD_GNUC_EXTENSION (GLADapiproc) userptr.get_proc_address_ptr(name); - } + result = glad_dlsym_handle(userptr.handle, name); + if (result == NULL) + { + result = GLAD_GNUC_EXTENSION(GLADapiproc) userptr.get_proc_address_ptr(name); + } - return result; + return result; } -static void* _egl_handle = NULL; +static void *_egl_handle = NULL; -int gladLoaderLoadEGL(EGLDisplay display) { +int gladLoaderLoadEGL(EGLDisplay display) +{ #ifdef __APPLE__ - static const char *NAMES[] = {"libEGL.dylib"}; + static const char *NAMES[] = {"libEGL.dylib"}; #elif GLAD_PLATFORM_WIN32 - static const char *NAMES[] = {"libEGL.dll", "EGL.dll"}; + static const char *NAMES[] = {"libEGL.dll", "EGL.dll"}; #else - static const char *NAMES[] = {"libEGL.so.1", "libEGL.so"}; + static const char *NAMES[] = {"libEGL.so.1", "libEGL.so"}; #endif - int version = 0; - int did_load = 0; - struct _glad_egl_userptr userptr; + int version = 0; + int did_load = 0; + struct _glad_egl_userptr userptr; - if (_egl_handle == NULL) { - _egl_handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0])); - did_load = _egl_handle != NULL; - } + if (_egl_handle == NULL) + { + _egl_handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0])); + did_load = _egl_handle != NULL; + } - if (_egl_handle != NULL) { - userptr.handle = _egl_handle; - userptr.get_proc_address_ptr = (PFNEGLGETPROCADDRESSPROC) glad_dlsym_handle(_egl_handle, "eglGetProcAddress"); - if (userptr.get_proc_address_ptr != NULL) { - version = gladLoadEGLUserPtr(display, glad_egl_get_proc, &userptr); - } + if (_egl_handle != NULL) + { + userptr.handle = _egl_handle; + userptr.get_proc_address_ptr = (PFNEGLGETPROCADDRESSPROC)glad_dlsym_handle(_egl_handle, "eglGetProcAddress"); + if (userptr.get_proc_address_ptr != NULL) + { + version = gladLoadEGLUserPtr(display, glad_egl_get_proc, &userptr); + } - if (!version && did_load) { - glad_close_dlopen_handle(_egl_handle); - _egl_handle = NULL; - } - } + if (!version && did_load) + { + glad_close_dlopen_handle(_egl_handle); + _egl_handle = NULL; + } + } - return version; + return version; } -void gladLoaderUnloadEGL() { - if (_egl_handle != NULL) { - glad_close_dlopen_handle(_egl_handle); - _egl_handle = NULL; - } +void gladLoaderUnloadEGL() +{ + if (_egl_handle != NULL) + { + glad_close_dlopen_handle(_egl_handle); + _egl_handle = NULL; + } } #endif /* GLAD_EGL */ diff --git a/examples/ThirdPartyLibs/glad/gl.c b/examples/ThirdPartyLibs/glad/gl.c index b699ec6ea..490f6c1d2 100644 --- a/examples/ThirdPartyLibs/glad/gl.c +++ b/examples/ThirdPartyLibs/glad/gl.c @@ -7,7 +7,7 @@ #define GLAD_IMPL_UTIL_C_ #if _MSC_VER >= 1400 -#define GLAD_IMPL_UTIL_STRNCPY(dest, source, len) strncpy_s(dest, len, source, len-1); +#define GLAD_IMPL_UTIL_STRNCPY(dest, source, len) strncpy_s(dest, len, source, len - 1); #else #define GLAD_IMPL_UTIL_STRNCPY(dest, source, len) strncpy(dest, source, len); #endif @@ -20,7 +20,6 @@ #endif /* GLAD_IMPL_UTIL_C_ */ - int GLAD_GL_VERSION_1_0; int GLAD_GL_VERSION_1_1; int GLAD_GL_VERSION_1_2; @@ -42,8 +41,6 @@ int GLAD_GL_VERSION_4_5; int GLAD_GL_VERSION_4_6; int GLAD_GL_ARB_point_sprite; - - PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv; PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv; PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample; @@ -1093,1316 +1090,1355 @@ PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv; PFNGLMULTITEXCOORD1FVPROC glad_glMultiTexCoord1fv; PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel; - -static void load_GL_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_1_0) return; - glEvalPoint2 = (PFNGLEVALPOINT2PROC) load("glEvalPoint2", userptr); - glEvalCoord2d = (PFNGLEVALCOORD2DPROC) load("glEvalCoord2d", userptr); - glPixelStoref = (PFNGLPIXELSTOREFPROC) load("glPixelStoref", userptr); - glTexCoord2f = (PFNGLTEXCOORD2FPROC) load("glTexCoord2f", userptr); - glFinish = (PFNGLFINISHPROC) load("glFinish", userptr); - glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC) load("glGetTexLevelParameterfv", userptr); - glPixelTransferf = (PFNGLPIXELTRANSFERFPROC) load("glPixelTransferf", userptr); - glClearAccum = (PFNGLCLEARACCUMPROC) load("glClearAccum", userptr); - glLoadName = (PFNGLLOADNAMEPROC) load("glLoadName", userptr); - glRasterPos2sv = (PFNGLRASTERPOS2SVPROC) load("glRasterPos2sv", userptr); - glVertex2i = (PFNGLVERTEX2IPROC) load("glVertex2i", userptr); - glFrustum = (PFNGLFRUSTUMPROC) load("glFrustum", userptr); - glGetString = (PFNGLGETSTRINGPROC) load("glGetString", userptr); - glLineWidth = (PFNGLLINEWIDTHPROC) load("glLineWidth", userptr); - glColor3dv = (PFNGLCOLOR3DVPROC) load("glColor3dv", userptr); - glColor4s = (PFNGLCOLOR4SPROC) load("glColor4s", userptr); - glTexGendv = (PFNGLTEXGENDVPROC) load("glTexGendv", userptr); - glRasterPos3s = (PFNGLRASTERPOS3SPROC) load("glRasterPos3s", userptr); - glRasterPos4dv = (PFNGLRASTERPOS4DVPROC) load("glRasterPos4dv", userptr); - glGetFloatv = (PFNGLGETFLOATVPROC) load("glGetFloatv", userptr); - glRasterPos3i = (PFNGLRASTERPOS3IPROC) load("glRasterPos3i", userptr); - glTexCoord4f = (PFNGLTEXCOORD4FPROC) load("glTexCoord4f", userptr); - glGetMapfv = (PFNGLGETMAPFVPROC) load("glGetMapfv", userptr); - glNormal3d = (PFNGLNORMAL3DPROC) load("glNormal3d", userptr); - glLightModeliv = (PFNGLLIGHTMODELIVPROC) load("glLightModeliv", userptr); - glTexCoord3sv = (PFNGLTEXCOORD3SVPROC) load("glTexCoord3sv", userptr); - glEvalCoord1d = (PFNGLEVALCOORD1DPROC) load("glEvalCoord1d", userptr); - glGetMapdv = (PFNGLGETMAPDVPROC) load("glGetMapdv", userptr); - glRecti = (PFNGLRECTIPROC) load("glRecti", userptr); - glTexCoord1d = (PFNGLTEXCOORD1DPROC) load("glTexCoord1d", userptr); - glGetPixelMapfv = (PFNGLGETPIXELMAPFVPROC) load("glGetPixelMapfv", userptr); - glVertex4sv = (PFNGLVERTEX4SVPROC) load("glVertex4sv", userptr); - glTexCoord1s = (PFNGLTEXCOORD1SPROC) load("glTexCoord1s", userptr); - glIndexsv = (PFNGLINDEXSVPROC) load("glIndexsv", userptr); - glRasterPos4iv = (PFNGLRASTERPOS4IVPROC) load("glRasterPos4iv", userptr); - glTexCoord2fv = (PFNGLTEXCOORD2FVPROC) load("glTexCoord2fv", userptr); - glGetTexEnviv = (PFNGLGETTEXENVIVPROC) load("glGetTexEnviv", userptr); - glCallList = (PFNGLCALLLISTPROC) load("glCallList", userptr); - glLoadMatrixf = (PFNGLLOADMATRIXFPROC) load("glLoadMatrixf", userptr); - glPolygonMode = (PFNGLPOLYGONMODEPROC) load("glPolygonMode", userptr); - glTranslatef = (PFNGLTRANSLATEFPROC) load("glTranslatef", userptr); - glGetTexImage = (PFNGLGETTEXIMAGEPROC) load("glGetTexImage", userptr); - glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC) load("glGetTexParameterfv", userptr); - glMapGrid2f = (PFNGLMAPGRID2FPROC) load("glMapGrid2f", userptr); - glVertex4d = (PFNGLVERTEX4DPROC) load("glVertex4d", userptr); - glNormal3sv = (PFNGLNORMAL3SVPROC) load("glNormal3sv", userptr); - glRasterPos4f = (PFNGLRASTERPOS4FPROC) load("glRasterPos4f", userptr); - glEvalCoord1dv = (PFNGLEVALCOORD1DVPROC) load("glEvalCoord1dv", userptr); - glIndexs = (PFNGLINDEXSPROC) load("glIndexs", userptr); - glIndexdv = (PFNGLINDEXDVPROC) load("glIndexdv", userptr); - glIsEnabled = (PFNGLISENABLEDPROC) load("glIsEnabled", userptr); - glGetPixelMapusv = (PFNGLGETPIXELMAPUSVPROC) load("glGetPixelMapusv", userptr); - glColor3us = (PFNGLCOLOR3USPROC) load("glColor3us", userptr); - glEvalPoint1 = (PFNGLEVALPOINT1PROC) load("glEvalPoint1", userptr); - glColor4sv = (PFNGLCOLOR4SVPROC) load("glColor4sv", userptr); - glColor3i = (PFNGLCOLOR3IPROC) load("glColor3i", userptr); - glRectf = (PFNGLRECTFPROC) load("glRectf", userptr); - glEvalCoord1fv = (PFNGLEVALCOORD1FVPROC) load("glEvalCoord1fv", userptr); - glTexCoord1sv = (PFNGLTEXCOORD1SVPROC) load("glTexCoord1sv", userptr); - glColor4d = (PFNGLCOLOR4DPROC) load("glColor4d", userptr); - glColor4ubv = (PFNGLCOLOR4UBVPROC) load("glColor4ubv", userptr); - glGetMaterialfv = (PFNGLGETMATERIALFVPROC) load("glGetMaterialfv", userptr); - glRasterPos3iv = (PFNGLRASTERPOS3IVPROC) load("glRasterPos3iv", userptr); - glGetMaterialiv = (PFNGLGETMATERIALIVPROC) load("glGetMaterialiv", userptr); - glBlendFunc = (PFNGLBLENDFUNCPROC) load("glBlendFunc", userptr); - glGetMapiv = (PFNGLGETMAPIVPROC) load("glGetMapiv", userptr); - glMatrixMode = (PFNGLMATRIXMODEPROC) load("glMatrixMode", userptr); - glScissor = (PFNGLSCISSORPROC) load("glScissor", userptr); - glVertex4iv = (PFNGLVERTEX4IVPROC) load("glVertex4iv", userptr); - glColorMask = (PFNGLCOLORMASKPROC) load("glColorMask", userptr); - glGetBooleanv = (PFNGLGETBOOLEANVPROC) load("glGetBooleanv", userptr); - glVertex2sv = (PFNGLVERTEX2SVPROC) load("glVertex2sv", userptr); - glRectsv = (PFNGLRECTSVPROC) load("glRectsv", userptr); - glRasterPos2f = (PFNGLRASTERPOS2FPROC) load("glRasterPos2f", userptr); - glVertex3d = (PFNGLVERTEX3DPROC) load("glVertex3d", userptr); - glStencilOp = (PFNGLSTENCILOPPROC) load("glStencilOp", userptr); - glViewport = (PFNGLVIEWPORTPROC) load("glViewport", userptr); - glMaterialiv = (PFNGLMATERIALIVPROC) load("glMaterialiv", userptr); - glDrawBuffer = (PFNGLDRAWBUFFERPROC) load("glDrawBuffer", userptr); - glVertex2f = (PFNGLVERTEX2FPROC) load("glVertex2f", userptr); - glPixelTransferi = (PFNGLPIXELTRANSFERIPROC) load("glPixelTransferi", userptr); - glGetPolygonStipple = (PFNGLGETPOLYGONSTIPPLEPROC) load("glGetPolygonStipple", userptr); - glDeleteLists = (PFNGLDELETELISTSPROC) load("glDeleteLists", userptr); - glRenderMode = (PFNGLRENDERMODEPROC) load("glRenderMode", userptr); - glTexCoord2sv = (PFNGLTEXCOORD2SVPROC) load("glTexCoord2sv", userptr); - glTexGend = (PFNGLTEXGENDPROC) load("glTexGend", userptr); - glBitmap = (PFNGLBITMAPPROC) load("glBitmap", userptr); - glMultMatrixf = (PFNGLMULTMATRIXFPROC) load("glMultMatrixf", userptr); - glColor3fv = (PFNGLCOLOR3FVPROC) load("glColor3fv", userptr); - glClearColor = (PFNGLCLEARCOLORPROC) load("glClearColor", userptr); - glRectiv = (PFNGLRECTIVPROC) load("glRectiv", userptr); - glGetTexGenfv = (PFNGLGETTEXGENFVPROC) load("glGetTexGenfv", userptr); - glColor4dv = (PFNGLCOLOR4DVPROC) load("glColor4dv", userptr); - glLogicOp = (PFNGLLOGICOPPROC) load("glLogicOp", userptr); - glTexCoord4s = (PFNGLTEXCOORD4SPROC) load("glTexCoord4s", userptr); - glRasterPos2d = (PFNGLRASTERPOS2DPROC) load("glRasterPos2d", userptr); - glMapGrid1f = (PFNGLMAPGRID1FPROC) load("glMapGrid1f", userptr); - glLightModeli = (PFNGLLIGHTMODELIPROC) load("glLightModeli", userptr); - glPixelMapuiv = (PFNGLPIXELMAPUIVPROC) load("glPixelMapuiv", userptr); - glTexGenfv = (PFNGLTEXGENFVPROC) load("glTexGenfv", userptr); - glRotated = (PFNGLROTATEDPROC) load("glRotated", userptr); - glAlphaFunc = (PFNGLALPHAFUNCPROC) load("glAlphaFunc", userptr); - glRects = (PFNGLRECTSPROC) load("glRects", userptr); - glPolygonStipple = (PFNGLPOLYGONSTIPPLEPROC) load("glPolygonStipple", userptr); - glTexImage1D = (PFNGLTEXIMAGE1DPROC) load("glTexImage1D", userptr); - glColor4fv = (PFNGLCOLOR4FVPROC) load("glColor4fv", userptr); - glLineStipple = (PFNGLLINESTIPPLEPROC) load("glLineStipple", userptr); - glVertex4f = (PFNGLVERTEX4FPROC) load("glVertex4f", userptr); - glColor3ub = (PFNGLCOLOR3UBPROC) load("glColor3ub", userptr); - glNormal3f = (PFNGLNORMAL3FPROC) load("glNormal3f", userptr); - glTexGeni = (PFNGLTEXGENIPROC) load("glTexGeni", userptr); - glTexCoord4dv = (PFNGLTEXCOORD4DVPROC) load("glTexCoord4dv", userptr); - glTexCoord3s = (PFNGLTEXCOORD3SPROC) load("glTexCoord3s", userptr); - glLightf = (PFNGLLIGHTFPROC) load("glLightf", userptr); - glTexGenf = (PFNGLTEXGENFPROC) load("glTexGenf", userptr); - glTexCoord3fv = (PFNGLTEXCOORD3FVPROC) load("glTexCoord3fv", userptr); - glIndexiv = (PFNGLINDEXIVPROC) load("glIndexiv", userptr); - glRasterPos4sv = (PFNGLRASTERPOS4SVPROC) load("glRasterPos4sv", userptr); - glVertex3i = (PFNGLVERTEX3IPROC) load("glVertex3i", userptr); - glColor4usv = (PFNGLCOLOR4USVPROC) load("glColor4usv", userptr); - glLoadIdentity = (PFNGLLOADIDENTITYPROC) load("glLoadIdentity", userptr); - glIndexf = (PFNGLINDEXFPROC) load("glIndexf", userptr); - glVertex2s = (PFNGLVERTEX2SPROC) load("glVertex2s", userptr); - glRasterPos4s = (PFNGLRASTERPOS4SPROC) load("glRasterPos4s", userptr); - glGetClipPlane = (PFNGLGETCLIPPLANEPROC) load("glGetClipPlane", userptr); - glGetError = (PFNGLGETERRORPROC) load("glGetError", userptr); - glTexParameterfv = (PFNGLTEXPARAMETERFVPROC) load("glTexParameterfv", userptr); - glColor4ui = (PFNGLCOLOR4UIPROC) load("glColor4ui", userptr); - glTexCoord4d = (PFNGLTEXCOORD4DPROC) load("glTexCoord4d", userptr); - glTexParameterf = (PFNGLTEXPARAMETERFPROC) load("glTexParameterf", userptr); - glTexCoord2i = (PFNGLTEXCOORD2IPROC) load("glTexCoord2i", userptr); - glTexCoord4i = (PFNGLTEXCOORD4IPROC) load("glTexCoord4i", userptr); - glGetTexEnvfv = (PFNGLGETTEXENVFVPROC) load("glGetTexEnvfv", userptr); - glFrontFace = (PFNGLFRONTFACEPROC) load("glFrontFace", userptr); - glRasterPos2i = (PFNGLRASTERPOS2IPROC) load("glRasterPos2i", userptr); - glIsList = (PFNGLISLISTPROC) load("glIsList", userptr); - glGetLightiv = (PFNGLGETLIGHTIVPROC) load("glGetLightiv", userptr); - glTexParameteri = (PFNGLTEXPARAMETERIPROC) load("glTexParameteri", userptr); - glPushAttrib = (PFNGLPUSHATTRIBPROC) load("glPushAttrib", userptr); - glColor4f = (PFNGLCOLOR4FPROC) load("glColor4f", userptr); - glStencilMask = (PFNGLSTENCILMASKPROC) load("glStencilMask", userptr); - glEvalMesh1 = (PFNGLEVALMESH1PROC) load("glEvalMesh1", userptr); - glIndexd = (PFNGLINDEXDPROC) load("glIndexd", userptr); - glNormal3iv = (PFNGLNORMAL3IVPROC) load("glNormal3iv", userptr); - glRasterPos4fv = (PFNGLRASTERPOS4FVPROC) load("glRasterPos4fv", userptr); - glTexGeniv = (PFNGLTEXGENIVPROC) load("glTexGeniv", userptr); - glPopName = (PFNGLPOPNAMEPROC) load("glPopName", userptr); - glFeedbackBuffer = (PFNGLFEEDBACKBUFFERPROC) load("glFeedbackBuffer", userptr); - glEvalMesh2 = (PFNGLEVALMESH2PROC) load("glEvalMesh2", userptr); - glScaled = (PFNGLSCALEDPROC) load("glScaled", userptr); - glPushMatrix = (PFNGLPUSHMATRIXPROC) load("glPushMatrix", userptr); - glEvalCoord1f = (PFNGLEVALCOORD1FPROC) load("glEvalCoord1f", userptr); - glLighti = (PFNGLLIGHTIPROC) load("glLighti", userptr); - glHint = (PFNGLHINTPROC) load("glHint", userptr); - glIndexMask = (PFNGLINDEXMASKPROC) load("glIndexMask", userptr); - glRasterPos3d = (PFNGLRASTERPOS3DPROC) load("glRasterPos3d", userptr); - glEvalCoord2fv = (PFNGLEVALCOORD2FVPROC) load("glEvalCoord2fv", userptr); - glColor3b = (PFNGLCOLOR3BPROC) load("glColor3b", userptr); - glMaterialfv = (PFNGLMATERIALFVPROC) load("glMaterialfv", userptr); - glStencilFunc = (PFNGLSTENCILFUNCPROC) load("glStencilFunc", userptr); - glGetLightfv = (PFNGLGETLIGHTFVPROC) load("glGetLightfv", userptr); - glInitNames = (PFNGLINITNAMESPROC) load("glInitNames", userptr); - glRasterPos4i = (PFNGLRASTERPOS4IPROC) load("glRasterPos4i", userptr); - glPixelMapusv = (PFNGLPIXELMAPUSVPROC) load("glPixelMapusv", userptr); - glRasterPos2s = (PFNGLRASTERPOS2SPROC) load("glRasterPos2s", userptr); - glFogfv = (PFNGLFOGFVPROC) load("glFogfv", userptr); - glTexCoord3iv = (PFNGLTEXCOORD3IVPROC) load("glTexCoord3iv", userptr); - glMap1f = (PFNGLMAP1FPROC) load("glMap1f", userptr); - glVertex3s = (PFNGLVERTEX3SPROC) load("glVertex3s", userptr); - glRasterPos3f = (PFNGLRASTERPOS3FPROC) load("glRasterPos3f", userptr); - glDepthFunc = (PFNGLDEPTHFUNCPROC) load("glDepthFunc", userptr); - glDepthRange = (PFNGLDEPTHRANGEPROC) load("glDepthRange", userptr); - glVertex4s = (PFNGLVERTEX4SPROC) load("glVertex4s", userptr); - glColor3bv = (PFNGLCOLOR3BVPROC) load("glColor3bv", userptr); - glColor3ubv = (PFNGLCOLOR3UBVPROC) load("glColor3ubv", userptr); - glNormal3b = (PFNGLNORMAL3BPROC) load("glNormal3b", userptr); - glVertex3sv = (PFNGLVERTEX3SVPROC) load("glVertex3sv", userptr); - glVertex2iv = (PFNGLVERTEX2IVPROC) load("glVertex2iv", userptr); - glTexCoord4sv = (PFNGLTEXCOORD4SVPROC) load("glTexCoord4sv", userptr); - glMap2d = (PFNGLMAP2DPROC) load("glMap2d", userptr); - glGetTexGendv = (PFNGLGETTEXGENDVPROC) load("glGetTexGendv", userptr); - glTexCoord3i = (PFNGLTEXCOORD3IPROC) load("glTexCoord3i", userptr); - glCallLists = (PFNGLCALLLISTSPROC) load("glCallLists", userptr); - glDrawPixels = (PFNGLDRAWPIXELSPROC) load("glDrawPixels", userptr); - glMap1d = (PFNGLMAP1DPROC) load("glMap1d", userptr); - glEdgeFlagv = (PFNGLEDGEFLAGVPROC) load("glEdgeFlagv", userptr); - glTexCoord1dv = (PFNGLTEXCOORD1DVPROC) load("glTexCoord1dv", userptr); - glRectfv = (PFNGLRECTFVPROC) load("glRectfv", userptr); - glVertex3iv = (PFNGLVERTEX3IVPROC) load("glVertex3iv", userptr); - glMateriali = (PFNGLMATERIALIPROC) load("glMateriali", userptr); - glBegin = (PFNGLBEGINPROC) load("glBegin", userptr); - glTexCoord3d = (PFNGLTEXCOORD3DPROC) load("glTexCoord3d", userptr); - glNewList = (PFNGLNEWLISTPROC) load("glNewList", userptr); - glPixelMapfv = (PFNGLPIXELMAPFVPROC) load("glPixelMapfv", userptr); - glVertex3f = (PFNGLVERTEX3FPROC) load("glVertex3f", userptr); - glColor3f = (PFNGLCOLOR3FPROC) load("glColor3f", userptr); - glMultMatrixd = (PFNGLMULTMATRIXDPROC) load("glMultMatrixd", userptr); - glScalef = (PFNGLSCALEFPROC) load("glScalef", userptr); - glRasterPos3fv = (PFNGLRASTERPOS3FVPROC) load("glRasterPos3fv", userptr); - glTexCoord1iv = (PFNGLTEXCOORD1IVPROC) load("glTexCoord1iv", userptr); - glGetDoublev = (PFNGLGETDOUBLEVPROC) load("glGetDoublev", userptr); - glMapGrid2d = (PFNGLMAPGRID2DPROC) load("glMapGrid2d", userptr); - glReadPixels = (PFNGLREADPIXELSPROC) load("glReadPixels", userptr); - glColor4bv = (PFNGLCOLOR4BVPROC) load("glColor4bv", userptr); - glOrtho = (PFNGLORTHOPROC) load("glOrtho", userptr); - glCopyPixels = (PFNGLCOPYPIXELSPROC) load("glCopyPixels", userptr); - glFogf = (PFNGLFOGFPROC) load("glFogf", userptr); - glTexCoord3f = (PFNGLTEXCOORD3FPROC) load("glTexCoord3f", userptr); - glColor3s = (PFNGLCOLOR3SPROC) load("glColor3s", userptr); - glColor3sv = (PFNGLCOLOR3SVPROC) load("glColor3sv", userptr); - glIndexfv = (PFNGLINDEXFVPROC) load("glIndexfv", userptr); - glPixelZoom = (PFNGLPIXELZOOMPROC) load("glPixelZoom", userptr); - glColor3uiv = (PFNGLCOLOR3UIVPROC) load("glColor3uiv", userptr); - glRasterPos2dv = (PFNGLRASTERPOS2DVPROC) load("glRasterPos2dv", userptr); - glEvalCoord2dv = (PFNGLEVALCOORD2DVPROC) load("glEvalCoord2dv", userptr); - glMapGrid1d = (PFNGLMAPGRID1DPROC) load("glMapGrid1d", userptr); - glVertex3dv = (PFNGLVERTEX3DVPROC) load("glVertex3dv", userptr); - glClear = (PFNGLCLEARPROC) load("glClear", userptr); - glEnable = (PFNGLENABLEPROC) load("glEnable", userptr); - glSelectBuffer = (PFNGLSELECTBUFFERPROC) load("glSelectBuffer", userptr); - glRasterPos3sv = (PFNGLRASTERPOS3SVPROC) load("glRasterPos3sv", userptr); - glNormal3dv = (PFNGLNORMAL3DVPROC) load("glNormal3dv", userptr); - glPopAttrib = (PFNGLPOPATTRIBPROC) load("glPopAttrib", userptr); - glColor3iv = (PFNGLCOLOR3IVPROC) load("glColor3iv", userptr); - glTexCoord2s = (PFNGLTEXCOORD2SPROC) load("glTexCoord2s", userptr); - glTexEnvi = (PFNGLTEXENVIPROC) load("glTexEnvi", userptr); - glTexCoord2dv = (PFNGLTEXCOORD2DVPROC) load("glTexCoord2dv", userptr); - glPassThrough = (PFNGLPASSTHROUGHPROC) load("glPassThrough", userptr); - glMaterialf = (PFNGLMATERIALFPROC) load("glMaterialf", userptr); - glColor4b = (PFNGLCOLOR4BPROC) load("glColor4b", userptr); - glColor4uiv = (PFNGLCOLOR4UIVPROC) load("glColor4uiv", userptr); - glClearIndex = (PFNGLCLEARINDEXPROC) load("glClearIndex", userptr); - glRotatef = (PFNGLROTATEFPROC) load("glRotatef", userptr); - glFogiv = (PFNGLFOGIVPROC) load("glFogiv", userptr); - glTexParameteriv = (PFNGLTEXPARAMETERIVPROC) load("glTexParameteriv", userptr); - glListBase = (PFNGLLISTBASEPROC) load("glListBase", userptr); - glIndexi = (PFNGLINDEXIPROC) load("glIndexi", userptr); - glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC) load("glGetTexLevelParameteriv", userptr); - glVertex4i = (PFNGLVERTEX4IPROC) load("glVertex4i", userptr); - glGetPixelMapuiv = (PFNGLGETPIXELMAPUIVPROC) load("glGetPixelMapuiv", userptr); - glTexEnvfv = (PFNGLTEXENVFVPROC) load("glTexEnvfv", userptr); - glEvalCoord2f = (PFNGLEVALCOORD2FPROC) load("glEvalCoord2f", userptr); - glVertex4dv = (PFNGLVERTEX4DVPROC) load("glVertex4dv", userptr); - glGetTexGeniv = (PFNGLGETTEXGENIVPROC) load("glGetTexGeniv", userptr); - glPointSize = (PFNGLPOINTSIZEPROC) load("glPointSize", userptr); - glTranslated = (PFNGLTRANSLATEDPROC) load("glTranslated", userptr); - glColor4i = (PFNGLCOLOR4IPROC) load("glColor4i", userptr); - glCullFace = (PFNGLCULLFACEPROC) load("glCullFace", userptr); - glGenLists = (PFNGLGENLISTSPROC) load("glGenLists", userptr); - glReadBuffer = (PFNGLREADBUFFERPROC) load("glReadBuffer", userptr); - glRasterPos2fv = (PFNGLRASTERPOS2FVPROC) load("glRasterPos2fv", userptr); - glEnd = (PFNGLENDPROC) load("glEnd", userptr); - glVertex2dv = (PFNGLVERTEX2DVPROC) load("glVertex2dv", userptr); - glColor4us = (PFNGLCOLOR4USPROC) load("glColor4us", userptr); - glPushName = (PFNGLPUSHNAMEPROC) load("glPushName", userptr); - glShadeModel = (PFNGLSHADEMODELPROC) load("glShadeModel", userptr); - glNormal3fv = (PFNGLNORMAL3FVPROC) load("glNormal3fv", userptr); - glTexCoord4iv = (PFNGLTEXCOORD4IVPROC) load("glTexCoord4iv", userptr); - glColor3ui = (PFNGLCOLOR3UIPROC) load("glColor3ui", userptr); - glRectd = (PFNGLRECTDPROC) load("glRectd", userptr); - glTexCoord4fv = (PFNGLTEXCOORD4FVPROC) load("glTexCoord4fv", userptr); - glTexCoord1f = (PFNGLTEXCOORD1FPROC) load("glTexCoord1f", userptr); - glEdgeFlag = (PFNGLEDGEFLAGPROC) load("glEdgeFlag", userptr); - glTexEnvf = (PFNGLTEXENVFPROC) load("glTexEnvf", userptr); - glMap2f = (PFNGLMAP2FPROC) load("glMap2f", userptr); - glNormal3i = (PFNGLNORMAL3IPROC) load("glNormal3i", userptr); - glColor3usv = (PFNGLCOLOR3USVPROC) load("glColor3usv", userptr); - glRasterPos2iv = (PFNGLRASTERPOS2IVPROC) load("glRasterPos2iv", userptr); - glGetIntegerv = (PFNGLGETINTEGERVPROC) load("glGetIntegerv", userptr); - glRectdv = (PFNGLRECTDVPROC) load("glRectdv", userptr); - glNormal3bv = (PFNGLNORMAL3BVPROC) load("glNormal3bv", userptr); - glVertex2fv = (PFNGLVERTEX2FVPROC) load("glVertex2fv", userptr); - glVertex2d = (PFNGLVERTEX2DPROC) load("glVertex2d", userptr); - glEndList = (PFNGLENDLISTPROC) load("glEndList", userptr); - glFlush = (PFNGLFLUSHPROC) load("glFlush", userptr); - glPixelStorei = (PFNGLPIXELSTOREIPROC) load("glPixelStorei", userptr); - glColor4ub = (PFNGLCOLOR4UBPROC) load("glColor4ub", userptr); - glNormal3s = (PFNGLNORMAL3SPROC) load("glNormal3s", userptr); - glColor4iv = (PFNGLCOLOR4IVPROC) load("glColor4iv", userptr); - glClipPlane = (PFNGLCLIPPLANEPROC) load("glClipPlane", userptr); - glTexCoord1i = (PFNGLTEXCOORD1IPROC) load("glTexCoord1i", userptr); - glLightModelf = (PFNGLLIGHTMODELFPROC) load("glLightModelf", userptr); - glPopMatrix = (PFNGLPOPMATRIXPROC) load("glPopMatrix", userptr); - glLoadMatrixd = (PFNGLLOADMATRIXDPROC) load("glLoadMatrixd", userptr); - glRasterPos3dv = (PFNGLRASTERPOS3DVPROC) load("glRasterPos3dv", userptr); - glTexCoord1fv = (PFNGLTEXCOORD1FVPROC) load("glTexCoord1fv", userptr); - glTexCoord2iv = (PFNGLTEXCOORD2IVPROC) load("glTexCoord2iv", userptr); - glClearDepth = (PFNGLCLEARDEPTHPROC) load("glClearDepth", userptr); - glTexCoord2d = (PFNGLTEXCOORD2DPROC) load("glTexCoord2d", userptr); - glRasterPos4d = (PFNGLRASTERPOS4DPROC) load("glRasterPos4d", userptr); - glColorMaterial = (PFNGLCOLORMATERIALPROC) load("glColorMaterial", userptr); - glAccum = (PFNGLACCUMPROC) load("glAccum", userptr); - glClearStencil = (PFNGLCLEARSTENCILPROC) load("glClearStencil", userptr); - glLightModelfv = (PFNGLLIGHTMODELFVPROC) load("glLightModelfv", userptr); - glColor3d = (PFNGLCOLOR3DPROC) load("glColor3d", userptr); - glDisable = (PFNGLDISABLEPROC) load("glDisable", userptr); - glFogi = (PFNGLFOGIPROC) load("glFogi", userptr); - glTexEnviv = (PFNGLTEXENVIVPROC) load("glTexEnviv", userptr); - glLightfv = (PFNGLLIGHTFVPROC) load("glLightfv", userptr); - glDepthMask = (PFNGLDEPTHMASKPROC) load("glDepthMask", userptr); - glTexImage2D = (PFNGLTEXIMAGE2DPROC) load("glTexImage2D", userptr); - glVertex3fv = (PFNGLVERTEX3FVPROC) load("glVertex3fv", userptr); - glVertex4fv = (PFNGLVERTEX4FVPROC) load("glVertex4fv", userptr); - glLightiv = (PFNGLLIGHTIVPROC) load("glLightiv", userptr); - glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC) load("glGetTexParameteriv", userptr); - glTexCoord3dv = (PFNGLTEXCOORD3DVPROC) load("glTexCoord3dv", userptr); +static void load_GL_VERSION_1_0(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_GL_VERSION_1_0) return; + glEvalPoint2 = (PFNGLEVALPOINT2PROC)load("glEvalPoint2", userptr); + glEvalCoord2d = (PFNGLEVALCOORD2DPROC)load("glEvalCoord2d", userptr); + glPixelStoref = (PFNGLPIXELSTOREFPROC)load("glPixelStoref", userptr); + glTexCoord2f = (PFNGLTEXCOORD2FPROC)load("glTexCoord2f", userptr); + glFinish = (PFNGLFINISHPROC)load("glFinish", userptr); + glGetTexLevelParameterfv = (PFNGLGETTEXLEVELPARAMETERFVPROC)load("glGetTexLevelParameterfv", userptr); + glPixelTransferf = (PFNGLPIXELTRANSFERFPROC)load("glPixelTransferf", userptr); + glClearAccum = (PFNGLCLEARACCUMPROC)load("glClearAccum", userptr); + glLoadName = (PFNGLLOADNAMEPROC)load("glLoadName", userptr); + glRasterPos2sv = (PFNGLRASTERPOS2SVPROC)load("glRasterPos2sv", userptr); + glVertex2i = (PFNGLVERTEX2IPROC)load("glVertex2i", userptr); + glFrustum = (PFNGLFRUSTUMPROC)load("glFrustum", userptr); + glGetString = (PFNGLGETSTRINGPROC)load("glGetString", userptr); + glLineWidth = (PFNGLLINEWIDTHPROC)load("glLineWidth", userptr); + glColor3dv = (PFNGLCOLOR3DVPROC)load("glColor3dv", userptr); + glColor4s = (PFNGLCOLOR4SPROC)load("glColor4s", userptr); + glTexGendv = (PFNGLTEXGENDVPROC)load("glTexGendv", userptr); + glRasterPos3s = (PFNGLRASTERPOS3SPROC)load("glRasterPos3s", userptr); + glRasterPos4dv = (PFNGLRASTERPOS4DVPROC)load("glRasterPos4dv", userptr); + glGetFloatv = (PFNGLGETFLOATVPROC)load("glGetFloatv", userptr); + glRasterPos3i = (PFNGLRASTERPOS3IPROC)load("glRasterPos3i", userptr); + glTexCoord4f = (PFNGLTEXCOORD4FPROC)load("glTexCoord4f", userptr); + glGetMapfv = (PFNGLGETMAPFVPROC)load("glGetMapfv", userptr); + glNormal3d = (PFNGLNORMAL3DPROC)load("glNormal3d", userptr); + glLightModeliv = (PFNGLLIGHTMODELIVPROC)load("glLightModeliv", userptr); + glTexCoord3sv = (PFNGLTEXCOORD3SVPROC)load("glTexCoord3sv", userptr); + glEvalCoord1d = (PFNGLEVALCOORD1DPROC)load("glEvalCoord1d", userptr); + glGetMapdv = (PFNGLGETMAPDVPROC)load("glGetMapdv", userptr); + glRecti = (PFNGLRECTIPROC)load("glRecti", userptr); + glTexCoord1d = (PFNGLTEXCOORD1DPROC)load("glTexCoord1d", userptr); + glGetPixelMapfv = (PFNGLGETPIXELMAPFVPROC)load("glGetPixelMapfv", userptr); + glVertex4sv = (PFNGLVERTEX4SVPROC)load("glVertex4sv", userptr); + glTexCoord1s = (PFNGLTEXCOORD1SPROC)load("glTexCoord1s", userptr); + glIndexsv = (PFNGLINDEXSVPROC)load("glIndexsv", userptr); + glRasterPos4iv = (PFNGLRASTERPOS4IVPROC)load("glRasterPos4iv", userptr); + glTexCoord2fv = (PFNGLTEXCOORD2FVPROC)load("glTexCoord2fv", userptr); + glGetTexEnviv = (PFNGLGETTEXENVIVPROC)load("glGetTexEnviv", userptr); + glCallList = (PFNGLCALLLISTPROC)load("glCallList", userptr); + glLoadMatrixf = (PFNGLLOADMATRIXFPROC)load("glLoadMatrixf", userptr); + glPolygonMode = (PFNGLPOLYGONMODEPROC)load("glPolygonMode", userptr); + glTranslatef = (PFNGLTRANSLATEFPROC)load("glTranslatef", userptr); + glGetTexImage = (PFNGLGETTEXIMAGEPROC)load("glGetTexImage", userptr); + glGetTexParameterfv = (PFNGLGETTEXPARAMETERFVPROC)load("glGetTexParameterfv", userptr); + glMapGrid2f = (PFNGLMAPGRID2FPROC)load("glMapGrid2f", userptr); + glVertex4d = (PFNGLVERTEX4DPROC)load("glVertex4d", userptr); + glNormal3sv = (PFNGLNORMAL3SVPROC)load("glNormal3sv", userptr); + glRasterPos4f = (PFNGLRASTERPOS4FPROC)load("glRasterPos4f", userptr); + glEvalCoord1dv = (PFNGLEVALCOORD1DVPROC)load("glEvalCoord1dv", userptr); + glIndexs = (PFNGLINDEXSPROC)load("glIndexs", userptr); + glIndexdv = (PFNGLINDEXDVPROC)load("glIndexdv", userptr); + glIsEnabled = (PFNGLISENABLEDPROC)load("glIsEnabled", userptr); + glGetPixelMapusv = (PFNGLGETPIXELMAPUSVPROC)load("glGetPixelMapusv", userptr); + glColor3us = (PFNGLCOLOR3USPROC)load("glColor3us", userptr); + glEvalPoint1 = (PFNGLEVALPOINT1PROC)load("glEvalPoint1", userptr); + glColor4sv = (PFNGLCOLOR4SVPROC)load("glColor4sv", userptr); + glColor3i = (PFNGLCOLOR3IPROC)load("glColor3i", userptr); + glRectf = (PFNGLRECTFPROC)load("glRectf", userptr); + glEvalCoord1fv = (PFNGLEVALCOORD1FVPROC)load("glEvalCoord1fv", userptr); + glTexCoord1sv = (PFNGLTEXCOORD1SVPROC)load("glTexCoord1sv", userptr); + glColor4d = (PFNGLCOLOR4DPROC)load("glColor4d", userptr); + glColor4ubv = (PFNGLCOLOR4UBVPROC)load("glColor4ubv", userptr); + glGetMaterialfv = (PFNGLGETMATERIALFVPROC)load("glGetMaterialfv", userptr); + glRasterPos3iv = (PFNGLRASTERPOS3IVPROC)load("glRasterPos3iv", userptr); + glGetMaterialiv = (PFNGLGETMATERIALIVPROC)load("glGetMaterialiv", userptr); + glBlendFunc = (PFNGLBLENDFUNCPROC)load("glBlendFunc", userptr); + glGetMapiv = (PFNGLGETMAPIVPROC)load("glGetMapiv", userptr); + glMatrixMode = (PFNGLMATRIXMODEPROC)load("glMatrixMode", userptr); + glScissor = (PFNGLSCISSORPROC)load("glScissor", userptr); + glVertex4iv = (PFNGLVERTEX4IVPROC)load("glVertex4iv", userptr); + glColorMask = (PFNGLCOLORMASKPROC)load("glColorMask", userptr); + glGetBooleanv = (PFNGLGETBOOLEANVPROC)load("glGetBooleanv", userptr); + glVertex2sv = (PFNGLVERTEX2SVPROC)load("glVertex2sv", userptr); + glRectsv = (PFNGLRECTSVPROC)load("glRectsv", userptr); + glRasterPos2f = (PFNGLRASTERPOS2FPROC)load("glRasterPos2f", userptr); + glVertex3d = (PFNGLVERTEX3DPROC)load("glVertex3d", userptr); + glStencilOp = (PFNGLSTENCILOPPROC)load("glStencilOp", userptr); + glViewport = (PFNGLVIEWPORTPROC)load("glViewport", userptr); + glMaterialiv = (PFNGLMATERIALIVPROC)load("glMaterialiv", userptr); + glDrawBuffer = (PFNGLDRAWBUFFERPROC)load("glDrawBuffer", userptr); + glVertex2f = (PFNGLVERTEX2FPROC)load("glVertex2f", userptr); + glPixelTransferi = (PFNGLPIXELTRANSFERIPROC)load("glPixelTransferi", userptr); + glGetPolygonStipple = (PFNGLGETPOLYGONSTIPPLEPROC)load("glGetPolygonStipple", userptr); + glDeleteLists = (PFNGLDELETELISTSPROC)load("glDeleteLists", userptr); + glRenderMode = (PFNGLRENDERMODEPROC)load("glRenderMode", userptr); + glTexCoord2sv = (PFNGLTEXCOORD2SVPROC)load("glTexCoord2sv", userptr); + glTexGend = (PFNGLTEXGENDPROC)load("glTexGend", userptr); + glBitmap = (PFNGLBITMAPPROC)load("glBitmap", userptr); + glMultMatrixf = (PFNGLMULTMATRIXFPROC)load("glMultMatrixf", userptr); + glColor3fv = (PFNGLCOLOR3FVPROC)load("glColor3fv", userptr); + glClearColor = (PFNGLCLEARCOLORPROC)load("glClearColor", userptr); + glRectiv = (PFNGLRECTIVPROC)load("glRectiv", userptr); + glGetTexGenfv = (PFNGLGETTEXGENFVPROC)load("glGetTexGenfv", userptr); + glColor4dv = (PFNGLCOLOR4DVPROC)load("glColor4dv", userptr); + glLogicOp = (PFNGLLOGICOPPROC)load("glLogicOp", userptr); + glTexCoord4s = (PFNGLTEXCOORD4SPROC)load("glTexCoord4s", userptr); + glRasterPos2d = (PFNGLRASTERPOS2DPROC)load("glRasterPos2d", userptr); + glMapGrid1f = (PFNGLMAPGRID1FPROC)load("glMapGrid1f", userptr); + glLightModeli = (PFNGLLIGHTMODELIPROC)load("glLightModeli", userptr); + glPixelMapuiv = (PFNGLPIXELMAPUIVPROC)load("glPixelMapuiv", userptr); + glTexGenfv = (PFNGLTEXGENFVPROC)load("glTexGenfv", userptr); + glRotated = (PFNGLROTATEDPROC)load("glRotated", userptr); + glAlphaFunc = (PFNGLALPHAFUNCPROC)load("glAlphaFunc", userptr); + glRects = (PFNGLRECTSPROC)load("glRects", userptr); + glPolygonStipple = (PFNGLPOLYGONSTIPPLEPROC)load("glPolygonStipple", userptr); + glTexImage1D = (PFNGLTEXIMAGE1DPROC)load("glTexImage1D", userptr); + glColor4fv = (PFNGLCOLOR4FVPROC)load("glColor4fv", userptr); + glLineStipple = (PFNGLLINESTIPPLEPROC)load("glLineStipple", userptr); + glVertex4f = (PFNGLVERTEX4FPROC)load("glVertex4f", userptr); + glColor3ub = (PFNGLCOLOR3UBPROC)load("glColor3ub", userptr); + glNormal3f = (PFNGLNORMAL3FPROC)load("glNormal3f", userptr); + glTexGeni = (PFNGLTEXGENIPROC)load("glTexGeni", userptr); + glTexCoord4dv = (PFNGLTEXCOORD4DVPROC)load("glTexCoord4dv", userptr); + glTexCoord3s = (PFNGLTEXCOORD3SPROC)load("glTexCoord3s", userptr); + glLightf = (PFNGLLIGHTFPROC)load("glLightf", userptr); + glTexGenf = (PFNGLTEXGENFPROC)load("glTexGenf", userptr); + glTexCoord3fv = (PFNGLTEXCOORD3FVPROC)load("glTexCoord3fv", userptr); + glIndexiv = (PFNGLINDEXIVPROC)load("glIndexiv", userptr); + glRasterPos4sv = (PFNGLRASTERPOS4SVPROC)load("glRasterPos4sv", userptr); + glVertex3i = (PFNGLVERTEX3IPROC)load("glVertex3i", userptr); + glColor4usv = (PFNGLCOLOR4USVPROC)load("glColor4usv", userptr); + glLoadIdentity = (PFNGLLOADIDENTITYPROC)load("glLoadIdentity", userptr); + glIndexf = (PFNGLINDEXFPROC)load("glIndexf", userptr); + glVertex2s = (PFNGLVERTEX2SPROC)load("glVertex2s", userptr); + glRasterPos4s = (PFNGLRASTERPOS4SPROC)load("glRasterPos4s", userptr); + glGetClipPlane = (PFNGLGETCLIPPLANEPROC)load("glGetClipPlane", userptr); + glGetError = (PFNGLGETERRORPROC)load("glGetError", userptr); + glTexParameterfv = (PFNGLTEXPARAMETERFVPROC)load("glTexParameterfv", userptr); + glColor4ui = (PFNGLCOLOR4UIPROC)load("glColor4ui", userptr); + glTexCoord4d = (PFNGLTEXCOORD4DPROC)load("glTexCoord4d", userptr); + glTexParameterf = (PFNGLTEXPARAMETERFPROC)load("glTexParameterf", userptr); + glTexCoord2i = (PFNGLTEXCOORD2IPROC)load("glTexCoord2i", userptr); + glTexCoord4i = (PFNGLTEXCOORD4IPROC)load("glTexCoord4i", userptr); + glGetTexEnvfv = (PFNGLGETTEXENVFVPROC)load("glGetTexEnvfv", userptr); + glFrontFace = (PFNGLFRONTFACEPROC)load("glFrontFace", userptr); + glRasterPos2i = (PFNGLRASTERPOS2IPROC)load("glRasterPos2i", userptr); + glIsList = (PFNGLISLISTPROC)load("glIsList", userptr); + glGetLightiv = (PFNGLGETLIGHTIVPROC)load("glGetLightiv", userptr); + glTexParameteri = (PFNGLTEXPARAMETERIPROC)load("glTexParameteri", userptr); + glPushAttrib = (PFNGLPUSHATTRIBPROC)load("glPushAttrib", userptr); + glColor4f = (PFNGLCOLOR4FPROC)load("glColor4f", userptr); + glStencilMask = (PFNGLSTENCILMASKPROC)load("glStencilMask", userptr); + glEvalMesh1 = (PFNGLEVALMESH1PROC)load("glEvalMesh1", userptr); + glIndexd = (PFNGLINDEXDPROC)load("glIndexd", userptr); + glNormal3iv = (PFNGLNORMAL3IVPROC)load("glNormal3iv", userptr); + glRasterPos4fv = (PFNGLRASTERPOS4FVPROC)load("glRasterPos4fv", userptr); + glTexGeniv = (PFNGLTEXGENIVPROC)load("glTexGeniv", userptr); + glPopName = (PFNGLPOPNAMEPROC)load("glPopName", userptr); + glFeedbackBuffer = (PFNGLFEEDBACKBUFFERPROC)load("glFeedbackBuffer", userptr); + glEvalMesh2 = (PFNGLEVALMESH2PROC)load("glEvalMesh2", userptr); + glScaled = (PFNGLSCALEDPROC)load("glScaled", userptr); + glPushMatrix = (PFNGLPUSHMATRIXPROC)load("glPushMatrix", userptr); + glEvalCoord1f = (PFNGLEVALCOORD1FPROC)load("glEvalCoord1f", userptr); + glLighti = (PFNGLLIGHTIPROC)load("glLighti", userptr); + glHint = (PFNGLHINTPROC)load("glHint", userptr); + glIndexMask = (PFNGLINDEXMASKPROC)load("glIndexMask", userptr); + glRasterPos3d = (PFNGLRASTERPOS3DPROC)load("glRasterPos3d", userptr); + glEvalCoord2fv = (PFNGLEVALCOORD2FVPROC)load("glEvalCoord2fv", userptr); + glColor3b = (PFNGLCOLOR3BPROC)load("glColor3b", userptr); + glMaterialfv = (PFNGLMATERIALFVPROC)load("glMaterialfv", userptr); + glStencilFunc = (PFNGLSTENCILFUNCPROC)load("glStencilFunc", userptr); + glGetLightfv = (PFNGLGETLIGHTFVPROC)load("glGetLightfv", userptr); + glInitNames = (PFNGLINITNAMESPROC)load("glInitNames", userptr); + glRasterPos4i = (PFNGLRASTERPOS4IPROC)load("glRasterPos4i", userptr); + glPixelMapusv = (PFNGLPIXELMAPUSVPROC)load("glPixelMapusv", userptr); + glRasterPos2s = (PFNGLRASTERPOS2SPROC)load("glRasterPos2s", userptr); + glFogfv = (PFNGLFOGFVPROC)load("glFogfv", userptr); + glTexCoord3iv = (PFNGLTEXCOORD3IVPROC)load("glTexCoord3iv", userptr); + glMap1f = (PFNGLMAP1FPROC)load("glMap1f", userptr); + glVertex3s = (PFNGLVERTEX3SPROC)load("glVertex3s", userptr); + glRasterPos3f = (PFNGLRASTERPOS3FPROC)load("glRasterPos3f", userptr); + glDepthFunc = (PFNGLDEPTHFUNCPROC)load("glDepthFunc", userptr); + glDepthRange = (PFNGLDEPTHRANGEPROC)load("glDepthRange", userptr); + glVertex4s = (PFNGLVERTEX4SPROC)load("glVertex4s", userptr); + glColor3bv = (PFNGLCOLOR3BVPROC)load("glColor3bv", userptr); + glColor3ubv = (PFNGLCOLOR3UBVPROC)load("glColor3ubv", userptr); + glNormal3b = (PFNGLNORMAL3BPROC)load("glNormal3b", userptr); + glVertex3sv = (PFNGLVERTEX3SVPROC)load("glVertex3sv", userptr); + glVertex2iv = (PFNGLVERTEX2IVPROC)load("glVertex2iv", userptr); + glTexCoord4sv = (PFNGLTEXCOORD4SVPROC)load("glTexCoord4sv", userptr); + glMap2d = (PFNGLMAP2DPROC)load("glMap2d", userptr); + glGetTexGendv = (PFNGLGETTEXGENDVPROC)load("glGetTexGendv", userptr); + glTexCoord3i = (PFNGLTEXCOORD3IPROC)load("glTexCoord3i", userptr); + glCallLists = (PFNGLCALLLISTSPROC)load("glCallLists", userptr); + glDrawPixels = (PFNGLDRAWPIXELSPROC)load("glDrawPixels", userptr); + glMap1d = (PFNGLMAP1DPROC)load("glMap1d", userptr); + glEdgeFlagv = (PFNGLEDGEFLAGVPROC)load("glEdgeFlagv", userptr); + glTexCoord1dv = (PFNGLTEXCOORD1DVPROC)load("glTexCoord1dv", userptr); + glRectfv = (PFNGLRECTFVPROC)load("glRectfv", userptr); + glVertex3iv = (PFNGLVERTEX3IVPROC)load("glVertex3iv", userptr); + glMateriali = (PFNGLMATERIALIPROC)load("glMateriali", userptr); + glBegin = (PFNGLBEGINPROC)load("glBegin", userptr); + glTexCoord3d = (PFNGLTEXCOORD3DPROC)load("glTexCoord3d", userptr); + glNewList = (PFNGLNEWLISTPROC)load("glNewList", userptr); + glPixelMapfv = (PFNGLPIXELMAPFVPROC)load("glPixelMapfv", userptr); + glVertex3f = (PFNGLVERTEX3FPROC)load("glVertex3f", userptr); + glColor3f = (PFNGLCOLOR3FPROC)load("glColor3f", userptr); + glMultMatrixd = (PFNGLMULTMATRIXDPROC)load("glMultMatrixd", userptr); + glScalef = (PFNGLSCALEFPROC)load("glScalef", userptr); + glRasterPos3fv = (PFNGLRASTERPOS3FVPROC)load("glRasterPos3fv", userptr); + glTexCoord1iv = (PFNGLTEXCOORD1IVPROC)load("glTexCoord1iv", userptr); + glGetDoublev = (PFNGLGETDOUBLEVPROC)load("glGetDoublev", userptr); + glMapGrid2d = (PFNGLMAPGRID2DPROC)load("glMapGrid2d", userptr); + glReadPixels = (PFNGLREADPIXELSPROC)load("glReadPixels", userptr); + glColor4bv = (PFNGLCOLOR4BVPROC)load("glColor4bv", userptr); + glOrtho = (PFNGLORTHOPROC)load("glOrtho", userptr); + glCopyPixels = (PFNGLCOPYPIXELSPROC)load("glCopyPixels", userptr); + glFogf = (PFNGLFOGFPROC)load("glFogf", userptr); + glTexCoord3f = (PFNGLTEXCOORD3FPROC)load("glTexCoord3f", userptr); + glColor3s = (PFNGLCOLOR3SPROC)load("glColor3s", userptr); + glColor3sv = (PFNGLCOLOR3SVPROC)load("glColor3sv", userptr); + glIndexfv = (PFNGLINDEXFVPROC)load("glIndexfv", userptr); + glPixelZoom = (PFNGLPIXELZOOMPROC)load("glPixelZoom", userptr); + glColor3uiv = (PFNGLCOLOR3UIVPROC)load("glColor3uiv", userptr); + glRasterPos2dv = (PFNGLRASTERPOS2DVPROC)load("glRasterPos2dv", userptr); + glEvalCoord2dv = (PFNGLEVALCOORD2DVPROC)load("glEvalCoord2dv", userptr); + glMapGrid1d = (PFNGLMAPGRID1DPROC)load("glMapGrid1d", userptr); + glVertex3dv = (PFNGLVERTEX3DVPROC)load("glVertex3dv", userptr); + glClear = (PFNGLCLEARPROC)load("glClear", userptr); + glEnable = (PFNGLENABLEPROC)load("glEnable", userptr); + glSelectBuffer = (PFNGLSELECTBUFFERPROC)load("glSelectBuffer", userptr); + glRasterPos3sv = (PFNGLRASTERPOS3SVPROC)load("glRasterPos3sv", userptr); + glNormal3dv = (PFNGLNORMAL3DVPROC)load("glNormal3dv", userptr); + glPopAttrib = (PFNGLPOPATTRIBPROC)load("glPopAttrib", userptr); + glColor3iv = (PFNGLCOLOR3IVPROC)load("glColor3iv", userptr); + glTexCoord2s = (PFNGLTEXCOORD2SPROC)load("glTexCoord2s", userptr); + glTexEnvi = (PFNGLTEXENVIPROC)load("glTexEnvi", userptr); + glTexCoord2dv = (PFNGLTEXCOORD2DVPROC)load("glTexCoord2dv", userptr); + glPassThrough = (PFNGLPASSTHROUGHPROC)load("glPassThrough", userptr); + glMaterialf = (PFNGLMATERIALFPROC)load("glMaterialf", userptr); + glColor4b = (PFNGLCOLOR4BPROC)load("glColor4b", userptr); + glColor4uiv = (PFNGLCOLOR4UIVPROC)load("glColor4uiv", userptr); + glClearIndex = (PFNGLCLEARINDEXPROC)load("glClearIndex", userptr); + glRotatef = (PFNGLROTATEFPROC)load("glRotatef", userptr); + glFogiv = (PFNGLFOGIVPROC)load("glFogiv", userptr); + glTexParameteriv = (PFNGLTEXPARAMETERIVPROC)load("glTexParameteriv", userptr); + glListBase = (PFNGLLISTBASEPROC)load("glListBase", userptr); + glIndexi = (PFNGLINDEXIPROC)load("glIndexi", userptr); + glGetTexLevelParameteriv = (PFNGLGETTEXLEVELPARAMETERIVPROC)load("glGetTexLevelParameteriv", userptr); + glVertex4i = (PFNGLVERTEX4IPROC)load("glVertex4i", userptr); + glGetPixelMapuiv = (PFNGLGETPIXELMAPUIVPROC)load("glGetPixelMapuiv", userptr); + glTexEnvfv = (PFNGLTEXENVFVPROC)load("glTexEnvfv", userptr); + glEvalCoord2f = (PFNGLEVALCOORD2FPROC)load("glEvalCoord2f", userptr); + glVertex4dv = (PFNGLVERTEX4DVPROC)load("glVertex4dv", userptr); + glGetTexGeniv = (PFNGLGETTEXGENIVPROC)load("glGetTexGeniv", userptr); + glPointSize = (PFNGLPOINTSIZEPROC)load("glPointSize", userptr); + glTranslated = (PFNGLTRANSLATEDPROC)load("glTranslated", userptr); + glColor4i = (PFNGLCOLOR4IPROC)load("glColor4i", userptr); + glCullFace = (PFNGLCULLFACEPROC)load("glCullFace", userptr); + glGenLists = (PFNGLGENLISTSPROC)load("glGenLists", userptr); + glReadBuffer = (PFNGLREADBUFFERPROC)load("glReadBuffer", userptr); + glRasterPos2fv = (PFNGLRASTERPOS2FVPROC)load("glRasterPos2fv", userptr); + glEnd = (PFNGLENDPROC)load("glEnd", userptr); + glVertex2dv = (PFNGLVERTEX2DVPROC)load("glVertex2dv", userptr); + glColor4us = (PFNGLCOLOR4USPROC)load("glColor4us", userptr); + glPushName = (PFNGLPUSHNAMEPROC)load("glPushName", userptr); + glShadeModel = (PFNGLSHADEMODELPROC)load("glShadeModel", userptr); + glNormal3fv = (PFNGLNORMAL3FVPROC)load("glNormal3fv", userptr); + glTexCoord4iv = (PFNGLTEXCOORD4IVPROC)load("glTexCoord4iv", userptr); + glColor3ui = (PFNGLCOLOR3UIPROC)load("glColor3ui", userptr); + glRectd = (PFNGLRECTDPROC)load("glRectd", userptr); + glTexCoord4fv = (PFNGLTEXCOORD4FVPROC)load("glTexCoord4fv", userptr); + glTexCoord1f = (PFNGLTEXCOORD1FPROC)load("glTexCoord1f", userptr); + glEdgeFlag = (PFNGLEDGEFLAGPROC)load("glEdgeFlag", userptr); + glTexEnvf = (PFNGLTEXENVFPROC)load("glTexEnvf", userptr); + glMap2f = (PFNGLMAP2FPROC)load("glMap2f", userptr); + glNormal3i = (PFNGLNORMAL3IPROC)load("glNormal3i", userptr); + glColor3usv = (PFNGLCOLOR3USVPROC)load("glColor3usv", userptr); + glRasterPos2iv = (PFNGLRASTERPOS2IVPROC)load("glRasterPos2iv", userptr); + glGetIntegerv = (PFNGLGETINTEGERVPROC)load("glGetIntegerv", userptr); + glRectdv = (PFNGLRECTDVPROC)load("glRectdv", userptr); + glNormal3bv = (PFNGLNORMAL3BVPROC)load("glNormal3bv", userptr); + glVertex2fv = (PFNGLVERTEX2FVPROC)load("glVertex2fv", userptr); + glVertex2d = (PFNGLVERTEX2DPROC)load("glVertex2d", userptr); + glEndList = (PFNGLENDLISTPROC)load("glEndList", userptr); + glFlush = (PFNGLFLUSHPROC)load("glFlush", userptr); + glPixelStorei = (PFNGLPIXELSTOREIPROC)load("glPixelStorei", userptr); + glColor4ub = (PFNGLCOLOR4UBPROC)load("glColor4ub", userptr); + glNormal3s = (PFNGLNORMAL3SPROC)load("glNormal3s", userptr); + glColor4iv = (PFNGLCOLOR4IVPROC)load("glColor4iv", userptr); + glClipPlane = (PFNGLCLIPPLANEPROC)load("glClipPlane", userptr); + glTexCoord1i = (PFNGLTEXCOORD1IPROC)load("glTexCoord1i", userptr); + glLightModelf = (PFNGLLIGHTMODELFPROC)load("glLightModelf", userptr); + glPopMatrix = (PFNGLPOPMATRIXPROC)load("glPopMatrix", userptr); + glLoadMatrixd = (PFNGLLOADMATRIXDPROC)load("glLoadMatrixd", userptr); + glRasterPos3dv = (PFNGLRASTERPOS3DVPROC)load("glRasterPos3dv", userptr); + glTexCoord1fv = (PFNGLTEXCOORD1FVPROC)load("glTexCoord1fv", userptr); + glTexCoord2iv = (PFNGLTEXCOORD2IVPROC)load("glTexCoord2iv", userptr); + glClearDepth = (PFNGLCLEARDEPTHPROC)load("glClearDepth", userptr); + glTexCoord2d = (PFNGLTEXCOORD2DPROC)load("glTexCoord2d", userptr); + glRasterPos4d = (PFNGLRASTERPOS4DPROC)load("glRasterPos4d", userptr); + glColorMaterial = (PFNGLCOLORMATERIALPROC)load("glColorMaterial", userptr); + glAccum = (PFNGLACCUMPROC)load("glAccum", userptr); + glClearStencil = (PFNGLCLEARSTENCILPROC)load("glClearStencil", userptr); + glLightModelfv = (PFNGLLIGHTMODELFVPROC)load("glLightModelfv", userptr); + glColor3d = (PFNGLCOLOR3DPROC)load("glColor3d", userptr); + glDisable = (PFNGLDISABLEPROC)load("glDisable", userptr); + glFogi = (PFNGLFOGIPROC)load("glFogi", userptr); + glTexEnviv = (PFNGLTEXENVIVPROC)load("glTexEnviv", userptr); + glLightfv = (PFNGLLIGHTFVPROC)load("glLightfv", userptr); + glDepthMask = (PFNGLDEPTHMASKPROC)load("glDepthMask", userptr); + glTexImage2D = (PFNGLTEXIMAGE2DPROC)load("glTexImage2D", userptr); + glVertex3fv = (PFNGLVERTEX3FVPROC)load("glVertex3fv", userptr); + glVertex4fv = (PFNGLVERTEX4FVPROC)load("glVertex4fv", userptr); + glLightiv = (PFNGLLIGHTIVPROC)load("glLightiv", userptr); + glGetTexParameteriv = (PFNGLGETTEXPARAMETERIVPROC)load("glGetTexParameteriv", userptr); + glTexCoord3dv = (PFNGLTEXCOORD3DVPROC)load("glTexCoord3dv", userptr); } -static void load_GL_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_1_1) return; - glVertexPointer = (PFNGLVERTEXPOINTERPROC) load("glVertexPointer", userptr); - glBindTexture = (PFNGLBINDTEXTUREPROC) load("glBindTexture", userptr); - glGetPointerv = (PFNGLGETPOINTERVPROC) load("glGetPointerv", userptr); - glTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC) load("glTexSubImage1D", userptr); - glEdgeFlagPointer = (PFNGLEDGEFLAGPOINTERPROC) load("glEdgeFlagPointer", userptr); - glIndexPointer = (PFNGLINDEXPOINTERPROC) load("glIndexPointer", userptr); - glDrawElements = (PFNGLDRAWELEMENTSPROC) load("glDrawElements", userptr); - glNormalPointer = (PFNGLNORMALPOINTERPROC) load("glNormalPointer", userptr); - glIndexub = (PFNGLINDEXUBPROC) load("glIndexub", userptr); - glDrawArrays = (PFNGLDRAWARRAYSPROC) load("glDrawArrays", userptr); - glDeleteTextures = (PFNGLDELETETEXTURESPROC) load("glDeleteTextures", userptr); - glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC) load("glCopyTexImage2D", userptr); - glGenTextures = (PFNGLGENTEXTURESPROC) load("glGenTextures", userptr); - glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC) load("glTexSubImage2D", userptr); - glCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC) load("glCopyTexImage1D", userptr); - glIndexubv = (PFNGLINDEXUBVPROC) load("glIndexubv", userptr); - glPopClientAttrib = (PFNGLPOPCLIENTATTRIBPROC) load("glPopClientAttrib", userptr); - glAreTexturesResident = (PFNGLARETEXTURESRESIDENTPROC) load("glAreTexturesResident", userptr); - glPushClientAttrib = (PFNGLPUSHCLIENTATTRIBPROC) load("glPushClientAttrib", userptr); - glDisableClientState = (PFNGLDISABLECLIENTSTATEPROC) load("glDisableClientState", userptr); - glEnableClientState = (PFNGLENABLECLIENTSTATEPROC) load("glEnableClientState", userptr); - glIsTexture = (PFNGLISTEXTUREPROC) load("glIsTexture", userptr); - glArrayElement = (PFNGLARRAYELEMENTPROC) load("glArrayElement", userptr); - glTexCoordPointer = (PFNGLTEXCOORDPOINTERPROC) load("glTexCoordPointer", userptr); - glInterleavedArrays = (PFNGLINTERLEAVEDARRAYSPROC) load("glInterleavedArrays", userptr); - glPolygonOffset = (PFNGLPOLYGONOFFSETPROC) load("glPolygonOffset", userptr); - glPrioritizeTextures = (PFNGLPRIORITIZETEXTURESPROC) load("glPrioritizeTextures", userptr); - glColorPointer = (PFNGLCOLORPOINTERPROC) load("glColorPointer", userptr); - glCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC) load("glCopyTexSubImage1D", userptr); - glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC) load("glCopyTexSubImage2D", userptr); +static void load_GL_VERSION_1_1(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_GL_VERSION_1_1) return; + glVertexPointer = (PFNGLVERTEXPOINTERPROC)load("glVertexPointer", userptr); + glBindTexture = (PFNGLBINDTEXTUREPROC)load("glBindTexture", userptr); + glGetPointerv = (PFNGLGETPOINTERVPROC)load("glGetPointerv", userptr); + glTexSubImage1D = (PFNGLTEXSUBIMAGE1DPROC)load("glTexSubImage1D", userptr); + glEdgeFlagPointer = (PFNGLEDGEFLAGPOINTERPROC)load("glEdgeFlagPointer", userptr); + glIndexPointer = (PFNGLINDEXPOINTERPROC)load("glIndexPointer", userptr); + glDrawElements = (PFNGLDRAWELEMENTSPROC)load("glDrawElements", userptr); + glNormalPointer = (PFNGLNORMALPOINTERPROC)load("glNormalPointer", userptr); + glIndexub = (PFNGLINDEXUBPROC)load("glIndexub", userptr); + glDrawArrays = (PFNGLDRAWARRAYSPROC)load("glDrawArrays", userptr); + glDeleteTextures = (PFNGLDELETETEXTURESPROC)load("glDeleteTextures", userptr); + glCopyTexImage2D = (PFNGLCOPYTEXIMAGE2DPROC)load("glCopyTexImage2D", userptr); + glGenTextures = (PFNGLGENTEXTURESPROC)load("glGenTextures", userptr); + glTexSubImage2D = (PFNGLTEXSUBIMAGE2DPROC)load("glTexSubImage2D", userptr); + glCopyTexImage1D = (PFNGLCOPYTEXIMAGE1DPROC)load("glCopyTexImage1D", userptr); + glIndexubv = (PFNGLINDEXUBVPROC)load("glIndexubv", userptr); + glPopClientAttrib = (PFNGLPOPCLIENTATTRIBPROC)load("glPopClientAttrib", userptr); + glAreTexturesResident = (PFNGLARETEXTURESRESIDENTPROC)load("glAreTexturesResident", userptr); + glPushClientAttrib = (PFNGLPUSHCLIENTATTRIBPROC)load("glPushClientAttrib", userptr); + glDisableClientState = (PFNGLDISABLECLIENTSTATEPROC)load("glDisableClientState", userptr); + glEnableClientState = (PFNGLENABLECLIENTSTATEPROC)load("glEnableClientState", userptr); + glIsTexture = (PFNGLISTEXTUREPROC)load("glIsTexture", userptr); + glArrayElement = (PFNGLARRAYELEMENTPROC)load("glArrayElement", userptr); + glTexCoordPointer = (PFNGLTEXCOORDPOINTERPROC)load("glTexCoordPointer", userptr); + glInterleavedArrays = (PFNGLINTERLEAVEDARRAYSPROC)load("glInterleavedArrays", userptr); + glPolygonOffset = (PFNGLPOLYGONOFFSETPROC)load("glPolygonOffset", userptr); + glPrioritizeTextures = (PFNGLPRIORITIZETEXTURESPROC)load("glPrioritizeTextures", userptr); + glColorPointer = (PFNGLCOLORPOINTERPROC)load("glColorPointer", userptr); + glCopyTexSubImage1D = (PFNGLCOPYTEXSUBIMAGE1DPROC)load("glCopyTexSubImage1D", userptr); + glCopyTexSubImage2D = (PFNGLCOPYTEXSUBIMAGE2DPROC)load("glCopyTexSubImage2D", userptr); } -static void load_GL_VERSION_1_2( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_1_2) return; - glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC) load("glDrawRangeElements", userptr); - glTexImage3D = (PFNGLTEXIMAGE3DPROC) load("glTexImage3D", userptr); - glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC) load("glCopyTexSubImage3D", userptr); - glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC) load("glTexSubImage3D", userptr); +static void load_GL_VERSION_1_2(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_GL_VERSION_1_2) return; + glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)load("glDrawRangeElements", userptr); + glTexImage3D = (PFNGLTEXIMAGE3DPROC)load("glTexImage3D", userptr); + glCopyTexSubImage3D = (PFNGLCOPYTEXSUBIMAGE3DPROC)load("glCopyTexSubImage3D", userptr); + glTexSubImage3D = (PFNGLTEXSUBIMAGE3DPROC)load("glTexSubImage3D", userptr); } -static void load_GL_VERSION_1_3( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_1_3) return; - glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC) load("glMultiTexCoord4f", userptr); - glLoadTransposeMatrixf = (PFNGLLOADTRANSPOSEMATRIXFPROC) load("glLoadTransposeMatrixf", userptr); - glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC) load("glCompressedTexImage3D", userptr); - glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC) load("glClientActiveTexture", userptr); - glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) load("glCompressedTexSubImage2D", userptr); - glMultiTexCoord2s = (PFNGLMULTITEXCOORD2SPROC) load("glMultiTexCoord2s", userptr); - glMultiTexCoord4i = (PFNGLMULTITEXCOORD4IPROC) load("glMultiTexCoord4i", userptr); - glLoadTransposeMatrixd = (PFNGLLOADTRANSPOSEMATRIXDPROC) load("glLoadTransposeMatrixd", userptr); - glMultiTexCoord2i = (PFNGLMULTITEXCOORD2IPROC) load("glMultiTexCoord2i", userptr); - glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) load("glCompressedTexSubImage3D", userptr); - glMultiTexCoord4dv = (PFNGLMULTITEXCOORD4DVPROC) load("glMultiTexCoord4dv", userptr); - glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC) load("glCompressedTexImage1D", userptr); - glMultiTexCoord3s = (PFNGLMULTITEXCOORD3SPROC) load("glMultiTexCoord3s", userptr); - glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC) load("glMultiTexCoord1f", userptr); - glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC) load("glGetCompressedTexImage", userptr); - glMultiTexCoord1i = (PFNGLMULTITEXCOORD1IPROC) load("glMultiTexCoord1i", userptr); - glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC) load("glMultiTexCoord3f", userptr); - glMultiTexCoord3dv = (PFNGLMULTITEXCOORD3DVPROC) load("glMultiTexCoord3dv", userptr); - glMultTransposeMatrixd = (PFNGLMULTTRANSPOSEMATRIXDPROC) load("glMultTransposeMatrixd", userptr); - glActiveTexture = (PFNGLACTIVETEXTUREPROC) load("glActiveTexture", userptr); - glMultiTexCoord1dv = (PFNGLMULTITEXCOORD1DVPROC) load("glMultiTexCoord1dv", userptr); - glMultiTexCoord3sv = (PFNGLMULTITEXCOORD3SVPROC) load("glMultiTexCoord3sv", userptr); - glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC) load("glMultiTexCoord3d", userptr); - glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC) load("glCompressedTexImage2D", userptr); - glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC) load("glMultiTexCoord1d", userptr); - glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC) load("glMultiTexCoord4d", userptr); - glMultiTexCoord1sv = (PFNGLMULTITEXCOORD1SVPROC) load("glMultiTexCoord1sv", userptr); - glMultiTexCoord4sv = (PFNGLMULTITEXCOORD4SVPROC) load("glMultiTexCoord4sv", userptr); - glMultiTexCoord3i = (PFNGLMULTITEXCOORD3IPROC) load("glMultiTexCoord3i", userptr); - glMultiTexCoord1iv = (PFNGLMULTITEXCOORD1IVPROC) load("glMultiTexCoord1iv", userptr); - glMultTransposeMatrixf = (PFNGLMULTTRANSPOSEMATRIXFPROC) load("glMultTransposeMatrixf", userptr); - glMultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC) load("glMultiTexCoord2fv", userptr); - glMultiTexCoord4s = (PFNGLMULTITEXCOORD4SPROC) load("glMultiTexCoord4s", userptr); - glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC) load("glMultiTexCoord2f", userptr); - glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC) load("glCompressedTexSubImage1D", userptr); - glMultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC) load("glMultiTexCoord2dv", userptr); - glMultiTexCoord2sv = (PFNGLMULTITEXCOORD2SVPROC) load("glMultiTexCoord2sv", userptr); - glMultiTexCoord3iv = (PFNGLMULTITEXCOORD3IVPROC) load("glMultiTexCoord3iv", userptr); - glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC) load("glSampleCoverage", userptr); - glMultiTexCoord2iv = (PFNGLMULTITEXCOORD2IVPROC) load("glMultiTexCoord2iv", userptr); - glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC) load("glMultiTexCoord2d", userptr); - glMultiTexCoord1s = (PFNGLMULTITEXCOORD1SPROC) load("glMultiTexCoord1s", userptr); - glMultiTexCoord4fv = (PFNGLMULTITEXCOORD4FVPROC) load("glMultiTexCoord4fv", userptr); - glMultiTexCoord3fv = (PFNGLMULTITEXCOORD3FVPROC) load("glMultiTexCoord3fv", userptr); - glMultiTexCoord4iv = (PFNGLMULTITEXCOORD4IVPROC) load("glMultiTexCoord4iv", userptr); - glMultiTexCoord1fv = (PFNGLMULTITEXCOORD1FVPROC) load("glMultiTexCoord1fv", userptr); +static void load_GL_VERSION_1_3(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_GL_VERSION_1_3) return; + glMultiTexCoord4f = (PFNGLMULTITEXCOORD4FPROC)load("glMultiTexCoord4f", userptr); + glLoadTransposeMatrixf = (PFNGLLOADTRANSPOSEMATRIXFPROC)load("glLoadTransposeMatrixf", userptr); + glCompressedTexImage3D = (PFNGLCOMPRESSEDTEXIMAGE3DPROC)load("glCompressedTexImage3D", userptr); + glClientActiveTexture = (PFNGLCLIENTACTIVETEXTUREPROC)load("glClientActiveTexture", userptr); + glCompressedTexSubImage2D = (PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)load("glCompressedTexSubImage2D", userptr); + glMultiTexCoord2s = (PFNGLMULTITEXCOORD2SPROC)load("glMultiTexCoord2s", userptr); + glMultiTexCoord4i = (PFNGLMULTITEXCOORD4IPROC)load("glMultiTexCoord4i", userptr); + glLoadTransposeMatrixd = (PFNGLLOADTRANSPOSEMATRIXDPROC)load("glLoadTransposeMatrixd", userptr); + glMultiTexCoord2i = (PFNGLMULTITEXCOORD2IPROC)load("glMultiTexCoord2i", userptr); + glCompressedTexSubImage3D = (PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)load("glCompressedTexSubImage3D", userptr); + glMultiTexCoord4dv = (PFNGLMULTITEXCOORD4DVPROC)load("glMultiTexCoord4dv", userptr); + glCompressedTexImage1D = (PFNGLCOMPRESSEDTEXIMAGE1DPROC)load("glCompressedTexImage1D", userptr); + glMultiTexCoord3s = (PFNGLMULTITEXCOORD3SPROC)load("glMultiTexCoord3s", userptr); + glMultiTexCoord1f = (PFNGLMULTITEXCOORD1FPROC)load("glMultiTexCoord1f", userptr); + glGetCompressedTexImage = (PFNGLGETCOMPRESSEDTEXIMAGEPROC)load("glGetCompressedTexImage", userptr); + glMultiTexCoord1i = (PFNGLMULTITEXCOORD1IPROC)load("glMultiTexCoord1i", userptr); + glMultiTexCoord3f = (PFNGLMULTITEXCOORD3FPROC)load("glMultiTexCoord3f", userptr); + glMultiTexCoord3dv = (PFNGLMULTITEXCOORD3DVPROC)load("glMultiTexCoord3dv", userptr); + glMultTransposeMatrixd = (PFNGLMULTTRANSPOSEMATRIXDPROC)load("glMultTransposeMatrixd", userptr); + glActiveTexture = (PFNGLACTIVETEXTUREPROC)load("glActiveTexture", userptr); + glMultiTexCoord1dv = (PFNGLMULTITEXCOORD1DVPROC)load("glMultiTexCoord1dv", userptr); + glMultiTexCoord3sv = (PFNGLMULTITEXCOORD3SVPROC)load("glMultiTexCoord3sv", userptr); + glMultiTexCoord3d = (PFNGLMULTITEXCOORD3DPROC)load("glMultiTexCoord3d", userptr); + glCompressedTexImage2D = (PFNGLCOMPRESSEDTEXIMAGE2DPROC)load("glCompressedTexImage2D", userptr); + glMultiTexCoord1d = (PFNGLMULTITEXCOORD1DPROC)load("glMultiTexCoord1d", userptr); + glMultiTexCoord4d = (PFNGLMULTITEXCOORD4DPROC)load("glMultiTexCoord4d", userptr); + glMultiTexCoord1sv = (PFNGLMULTITEXCOORD1SVPROC)load("glMultiTexCoord1sv", userptr); + glMultiTexCoord4sv = (PFNGLMULTITEXCOORD4SVPROC)load("glMultiTexCoord4sv", userptr); + glMultiTexCoord3i = (PFNGLMULTITEXCOORD3IPROC)load("glMultiTexCoord3i", userptr); + glMultiTexCoord1iv = (PFNGLMULTITEXCOORD1IVPROC)load("glMultiTexCoord1iv", userptr); + glMultTransposeMatrixf = (PFNGLMULTTRANSPOSEMATRIXFPROC)load("glMultTransposeMatrixf", userptr); + glMultiTexCoord2fv = (PFNGLMULTITEXCOORD2FVPROC)load("glMultiTexCoord2fv", userptr); + glMultiTexCoord4s = (PFNGLMULTITEXCOORD4SPROC)load("glMultiTexCoord4s", userptr); + glMultiTexCoord2f = (PFNGLMULTITEXCOORD2FPROC)load("glMultiTexCoord2f", userptr); + glCompressedTexSubImage1D = (PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)load("glCompressedTexSubImage1D", userptr); + glMultiTexCoord2dv = (PFNGLMULTITEXCOORD2DVPROC)load("glMultiTexCoord2dv", userptr); + glMultiTexCoord2sv = (PFNGLMULTITEXCOORD2SVPROC)load("glMultiTexCoord2sv", userptr); + glMultiTexCoord3iv = (PFNGLMULTITEXCOORD3IVPROC)load("glMultiTexCoord3iv", userptr); + glSampleCoverage = (PFNGLSAMPLECOVERAGEPROC)load("glSampleCoverage", userptr); + glMultiTexCoord2iv = (PFNGLMULTITEXCOORD2IVPROC)load("glMultiTexCoord2iv", userptr); + glMultiTexCoord2d = (PFNGLMULTITEXCOORD2DPROC)load("glMultiTexCoord2d", userptr); + glMultiTexCoord1s = (PFNGLMULTITEXCOORD1SPROC)load("glMultiTexCoord1s", userptr); + glMultiTexCoord4fv = (PFNGLMULTITEXCOORD4FVPROC)load("glMultiTexCoord4fv", userptr); + glMultiTexCoord3fv = (PFNGLMULTITEXCOORD3FVPROC)load("glMultiTexCoord3fv", userptr); + glMultiTexCoord4iv = (PFNGLMULTITEXCOORD4IVPROC)load("glMultiTexCoord4iv", userptr); + glMultiTexCoord1fv = (PFNGLMULTITEXCOORD1FVPROC)load("glMultiTexCoord1fv", userptr); } -static void load_GL_VERSION_1_4( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_1_4) return; - glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC) load("glMultiDrawElements", userptr); - glWindowPos3sv = (PFNGLWINDOWPOS3SVPROC) load("glWindowPos3sv", userptr); - glSecondaryColor3us = (PFNGLSECONDARYCOLOR3USPROC) load("glSecondaryColor3us", userptr); - glSecondaryColor3iv = (PFNGLSECONDARYCOLOR3IVPROC) load("glSecondaryColor3iv", userptr); - glPointParameterf = (PFNGLPOINTPARAMETERFPROC) load("glPointParameterf", userptr); - glSecondaryColor3s = (PFNGLSECONDARYCOLOR3SPROC) load("glSecondaryColor3s", userptr); - glSecondaryColor3sv = (PFNGLSECONDARYCOLOR3SVPROC) load("glSecondaryColor3sv", userptr); - glSecondaryColor3uiv = (PFNGLSECONDARYCOLOR3UIVPROC) load("glSecondaryColor3uiv", userptr); - glWindowPos2d = (PFNGLWINDOWPOS2DPROC) load("glWindowPos2d", userptr); - glSecondaryColor3ubv = (PFNGLSECONDARYCOLOR3UBVPROC) load("glSecondaryColor3ubv", userptr); - glWindowPos3dv = (PFNGLWINDOWPOS3DVPROC) load("glWindowPos3dv", userptr); - glWindowPos2iv = (PFNGLWINDOWPOS2IVPROC) load("glWindowPos2iv", userptr); - glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC) load("glMultiDrawArrays", userptr); - glSecondaryColor3bv = (PFNGLSECONDARYCOLOR3BVPROC) load("glSecondaryColor3bv", userptr); - glSecondaryColor3ui = (PFNGLSECONDARYCOLOR3UIPROC) load("glSecondaryColor3ui", userptr); - glWindowPos2f = (PFNGLWINDOWPOS2FPROC) load("glWindowPos2f", userptr); - glWindowPos2s = (PFNGLWINDOWPOS2SPROC) load("glWindowPos2s", userptr); - glSecondaryColor3fv = (PFNGLSECONDARYCOLOR3FVPROC) load("glSecondaryColor3fv", userptr); - glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC) load("glPointParameteriv", userptr); - glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC) load("glSecondaryColorPointer", userptr); - glBlendColor = (PFNGLBLENDCOLORPROC) load("glBlendColor", userptr); - glWindowPos2dv = (PFNGLWINDOWPOS2DVPROC) load("glWindowPos2dv", userptr); - glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC) load("glBlendFuncSeparate", userptr); - glPointParameteri = (PFNGLPOINTPARAMETERIPROC) load("glPointParameteri", userptr); - glFogCoordf = (PFNGLFOGCOORDFPROC) load("glFogCoordf", userptr); - glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC) load("glSecondaryColor3f", userptr); - glSecondaryColor3i = (PFNGLSECONDARYCOLOR3IPROC) load("glSecondaryColor3i", userptr); - glSecondaryColor3ub = (PFNGLSECONDARYCOLOR3UBPROC) load("glSecondaryColor3ub", userptr); - glWindowPos3i = (PFNGLWINDOWPOS3IPROC) load("glWindowPos3i", userptr); - glWindowPos3f = (PFNGLWINDOWPOS3FPROC) load("glWindowPos3f", userptr); - glSecondaryColor3b = (PFNGLSECONDARYCOLOR3BPROC) load("glSecondaryColor3b", userptr); - glWindowPos3iv = (PFNGLWINDOWPOS3IVPROC) load("glWindowPos3iv", userptr); - glSecondaryColor3d = (PFNGLSECONDARYCOLOR3DPROC) load("glSecondaryColor3d", userptr); - glFogCoordd = (PFNGLFOGCOORDDPROC) load("glFogCoordd", userptr); - glWindowPos3fv = (PFNGLWINDOWPOS3FVPROC) load("glWindowPos3fv", userptr); - glWindowPos2i = (PFNGLWINDOWPOS2IPROC) load("glWindowPos2i", userptr); - glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC) load("glPointParameterfv", userptr); - glFogCoordfv = (PFNGLFOGCOORDFVPROC) load("glFogCoordfv", userptr); - glSecondaryColor3usv = (PFNGLSECONDARYCOLOR3USVPROC) load("glSecondaryColor3usv", userptr); - glWindowPos2fv = (PFNGLWINDOWPOS2FVPROC) load("glWindowPos2fv", userptr); - glBlendEquation = (PFNGLBLENDEQUATIONPROC) load("glBlendEquation", userptr); - glWindowPos2sv = (PFNGLWINDOWPOS2SVPROC) load("glWindowPos2sv", userptr); - glSecondaryColor3dv = (PFNGLSECONDARYCOLOR3DVPROC) load("glSecondaryColor3dv", userptr); - glWindowPos3s = (PFNGLWINDOWPOS3SPROC) load("glWindowPos3s", userptr); - glWindowPos3d = (PFNGLWINDOWPOS3DPROC) load("glWindowPos3d", userptr); - glFogCoorddv = (PFNGLFOGCOORDDVPROC) load("glFogCoorddv", userptr); - glFogCoordPointer = (PFNGLFOGCOORDPOINTERPROC) load("glFogCoordPointer", userptr); +static void load_GL_VERSION_1_4(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_GL_VERSION_1_4) return; + glMultiDrawElements = (PFNGLMULTIDRAWELEMENTSPROC)load("glMultiDrawElements", userptr); + glWindowPos3sv = (PFNGLWINDOWPOS3SVPROC)load("glWindowPos3sv", userptr); + glSecondaryColor3us = (PFNGLSECONDARYCOLOR3USPROC)load("glSecondaryColor3us", userptr); + glSecondaryColor3iv = (PFNGLSECONDARYCOLOR3IVPROC)load("glSecondaryColor3iv", userptr); + glPointParameterf = (PFNGLPOINTPARAMETERFPROC)load("glPointParameterf", userptr); + glSecondaryColor3s = (PFNGLSECONDARYCOLOR3SPROC)load("glSecondaryColor3s", userptr); + glSecondaryColor3sv = (PFNGLSECONDARYCOLOR3SVPROC)load("glSecondaryColor3sv", userptr); + glSecondaryColor3uiv = (PFNGLSECONDARYCOLOR3UIVPROC)load("glSecondaryColor3uiv", userptr); + glWindowPos2d = (PFNGLWINDOWPOS2DPROC)load("glWindowPos2d", userptr); + glSecondaryColor3ubv = (PFNGLSECONDARYCOLOR3UBVPROC)load("glSecondaryColor3ubv", userptr); + glWindowPos3dv = (PFNGLWINDOWPOS3DVPROC)load("glWindowPos3dv", userptr); + glWindowPos2iv = (PFNGLWINDOWPOS2IVPROC)load("glWindowPos2iv", userptr); + glMultiDrawArrays = (PFNGLMULTIDRAWARRAYSPROC)load("glMultiDrawArrays", userptr); + glSecondaryColor3bv = (PFNGLSECONDARYCOLOR3BVPROC)load("glSecondaryColor3bv", userptr); + glSecondaryColor3ui = (PFNGLSECONDARYCOLOR3UIPROC)load("glSecondaryColor3ui", userptr); + glWindowPos2f = (PFNGLWINDOWPOS2FPROC)load("glWindowPos2f", userptr); + glWindowPos2s = (PFNGLWINDOWPOS2SPROC)load("glWindowPos2s", userptr); + glSecondaryColor3fv = (PFNGLSECONDARYCOLOR3FVPROC)load("glSecondaryColor3fv", userptr); + glPointParameteriv = (PFNGLPOINTPARAMETERIVPROC)load("glPointParameteriv", userptr); + glSecondaryColorPointer = (PFNGLSECONDARYCOLORPOINTERPROC)load("glSecondaryColorPointer", userptr); + glBlendColor = (PFNGLBLENDCOLORPROC)load("glBlendColor", userptr); + glWindowPos2dv = (PFNGLWINDOWPOS2DVPROC)load("glWindowPos2dv", userptr); + glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)load("glBlendFuncSeparate", userptr); + glPointParameteri = (PFNGLPOINTPARAMETERIPROC)load("glPointParameteri", userptr); + glFogCoordf = (PFNGLFOGCOORDFPROC)load("glFogCoordf", userptr); + glSecondaryColor3f = (PFNGLSECONDARYCOLOR3FPROC)load("glSecondaryColor3f", userptr); + glSecondaryColor3i = (PFNGLSECONDARYCOLOR3IPROC)load("glSecondaryColor3i", userptr); + glSecondaryColor3ub = (PFNGLSECONDARYCOLOR3UBPROC)load("glSecondaryColor3ub", userptr); + glWindowPos3i = (PFNGLWINDOWPOS3IPROC)load("glWindowPos3i", userptr); + glWindowPos3f = (PFNGLWINDOWPOS3FPROC)load("glWindowPos3f", userptr); + glSecondaryColor3b = (PFNGLSECONDARYCOLOR3BPROC)load("glSecondaryColor3b", userptr); + glWindowPos3iv = (PFNGLWINDOWPOS3IVPROC)load("glWindowPos3iv", userptr); + glSecondaryColor3d = (PFNGLSECONDARYCOLOR3DPROC)load("glSecondaryColor3d", userptr); + glFogCoordd = (PFNGLFOGCOORDDPROC)load("glFogCoordd", userptr); + glWindowPos3fv = (PFNGLWINDOWPOS3FVPROC)load("glWindowPos3fv", userptr); + glWindowPos2i = (PFNGLWINDOWPOS2IPROC)load("glWindowPos2i", userptr); + glPointParameterfv = (PFNGLPOINTPARAMETERFVPROC)load("glPointParameterfv", userptr); + glFogCoordfv = (PFNGLFOGCOORDFVPROC)load("glFogCoordfv", userptr); + glSecondaryColor3usv = (PFNGLSECONDARYCOLOR3USVPROC)load("glSecondaryColor3usv", userptr); + glWindowPos2fv = (PFNGLWINDOWPOS2FVPROC)load("glWindowPos2fv", userptr); + glBlendEquation = (PFNGLBLENDEQUATIONPROC)load("glBlendEquation", userptr); + glWindowPos2sv = (PFNGLWINDOWPOS2SVPROC)load("glWindowPos2sv", userptr); + glSecondaryColor3dv = (PFNGLSECONDARYCOLOR3DVPROC)load("glSecondaryColor3dv", userptr); + glWindowPos3s = (PFNGLWINDOWPOS3SPROC)load("glWindowPos3s", userptr); + glWindowPos3d = (PFNGLWINDOWPOS3DPROC)load("glWindowPos3d", userptr); + glFogCoorddv = (PFNGLFOGCOORDDVPROC)load("glFogCoorddv", userptr); + glFogCoordPointer = (PFNGLFOGCOORDPOINTERPROC)load("glFogCoordPointer", userptr); } -static void load_GL_VERSION_1_5( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_1_5) return; - glMapBuffer = (PFNGLMAPBUFFERPROC) load("glMapBuffer", userptr); - glBufferSubData = (PFNGLBUFFERSUBDATAPROC) load("glBufferSubData", userptr); - glBeginQuery = (PFNGLBEGINQUERYPROC) load("glBeginQuery", userptr); - glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC) load("glGetBufferParameteriv", userptr); - glGenQueries = (PFNGLGENQUERIESPROC) load("glGenQueries", userptr); - glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC) load("glGetQueryObjectuiv", userptr); - glIsBuffer = (PFNGLISBUFFERPROC) load("glIsBuffer", userptr); - glGetQueryiv = (PFNGLGETQUERYIVPROC) load("glGetQueryiv", userptr); - glEndQuery = (PFNGLENDQUERYPROC) load("glEndQuery", userptr); - glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC) load("glGetQueryObjectiv", userptr); - glGenBuffers = (PFNGLGENBUFFERSPROC) load("glGenBuffers", userptr); - glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC) load("glGetBufferSubData", userptr); - glDeleteBuffers = (PFNGLDELETEBUFFERSPROC) load("glDeleteBuffers", userptr); - glIsQuery = (PFNGLISQUERYPROC) load("glIsQuery", userptr); - glBindBuffer = (PFNGLBINDBUFFERPROC) load("glBindBuffer", userptr); - glDeleteQueries = (PFNGLDELETEQUERIESPROC) load("glDeleteQueries", userptr); - glUnmapBuffer = (PFNGLUNMAPBUFFERPROC) load("glUnmapBuffer", userptr); - glBufferData = (PFNGLBUFFERDATAPROC) load("glBufferData", userptr); - glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC) load("glGetBufferPointerv", userptr); +static void load_GL_VERSION_1_5(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_GL_VERSION_1_5) return; + glMapBuffer = (PFNGLMAPBUFFERPROC)load("glMapBuffer", userptr); + glBufferSubData = (PFNGLBUFFERSUBDATAPROC)load("glBufferSubData", userptr); + glBeginQuery = (PFNGLBEGINQUERYPROC)load("glBeginQuery", userptr); + glGetBufferParameteriv = (PFNGLGETBUFFERPARAMETERIVPROC)load("glGetBufferParameteriv", userptr); + glGenQueries = (PFNGLGENQUERIESPROC)load("glGenQueries", userptr); + glGetQueryObjectuiv = (PFNGLGETQUERYOBJECTUIVPROC)load("glGetQueryObjectuiv", userptr); + glIsBuffer = (PFNGLISBUFFERPROC)load("glIsBuffer", userptr); + glGetQueryiv = (PFNGLGETQUERYIVPROC)load("glGetQueryiv", userptr); + glEndQuery = (PFNGLENDQUERYPROC)load("glEndQuery", userptr); + glGetQueryObjectiv = (PFNGLGETQUERYOBJECTIVPROC)load("glGetQueryObjectiv", userptr); + glGenBuffers = (PFNGLGENBUFFERSPROC)load("glGenBuffers", userptr); + glGetBufferSubData = (PFNGLGETBUFFERSUBDATAPROC)load("glGetBufferSubData", userptr); + glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)load("glDeleteBuffers", userptr); + glIsQuery = (PFNGLISQUERYPROC)load("glIsQuery", userptr); + glBindBuffer = (PFNGLBINDBUFFERPROC)load("glBindBuffer", userptr); + glDeleteQueries = (PFNGLDELETEQUERIESPROC)load("glDeleteQueries", userptr); + glUnmapBuffer = (PFNGLUNMAPBUFFERPROC)load("glUnmapBuffer", userptr); + glBufferData = (PFNGLBUFFERDATAPROC)load("glBufferData", userptr); + glGetBufferPointerv = (PFNGLGETBUFFERPOINTERVPROC)load("glGetBufferPointerv", userptr); } -static void load_GL_VERSION_2_0( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_2_0) return; - glUniform2i = (PFNGLUNIFORM2IPROC) load("glUniform2i", userptr); - glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC) load("glVertexAttrib2fv", userptr); - glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC) load("glUniformMatrix3fv", userptr); - glUniform2iv = (PFNGLUNIFORM2IVPROC) load("glUniform2iv", userptr); - glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC) load("glGetActiveUniform", userptr); - glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC) load("glUniformMatrix4fv", userptr); - glDetachShader = (PFNGLDETACHSHADERPROC) load("glDetachShader", userptr); - glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC) load("glVertexAttrib4s", userptr); - glAttachShader = (PFNGLATTACHSHADERPROC) load("glAttachShader", userptr); - glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC) load("glVertexAttrib4Nuiv", userptr); - glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC) load("glGetAttribLocation", userptr); - glUniform2f = (PFNGLUNIFORM2FPROC) load("glUniform2f", userptr); - glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC) load("glVertexAttrib1s", userptr); - glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC) load("glVertexAttrib4Nsv", userptr); - glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC) load("glVertexAttrib1f", userptr); - glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC) load("glVertexAttrib3sv", userptr); - glGetUniformiv = (PFNGLGETUNIFORMIVPROC) load("glGetUniformiv", userptr); - glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC) load("glVertexAttrib4sv", userptr); - glCreateShader = (PFNGLCREATESHADERPROC) load("glCreateShader", userptr); - glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC) load("glStencilOpSeparate", userptr); - glUniform3f = (PFNGLUNIFORM3FPROC) load("glUniform3f", userptr); - glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC) load("glVertexAttrib4usv", userptr); - glCreateProgram = (PFNGLCREATEPROGRAMPROC) load("glCreateProgram", userptr); - glUniform4f = (PFNGLUNIFORM4FPROC) load("glUniform4f", userptr); - glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC) load("glGetShaderInfoLog", userptr); - glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC) load("glVertexAttrib2d", userptr); - glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC) load("glVertexAttrib2f", userptr); - glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC) load("glUniformMatrix2fv", userptr); - glUniform4fv = (PFNGLUNIFORM4FVPROC) load("glUniform4fv", userptr); - glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC) load("glVertexAttrib4d", userptr); - glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC) load("glVertexAttrib1fv", userptr); - glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC) load("glVertexAttrib4Nubv", userptr); - glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC) load("glVertexAttrib1sv", userptr); - glDrawBuffers = (PFNGLDRAWBUFFERSPROC) load("glDrawBuffers", userptr); - glGetShaderSource = (PFNGLGETSHADERSOURCEPROC) load("glGetShaderSource", userptr); - glUniform3i = (PFNGLUNIFORM3IPROC) load("glUniform3i", userptr); - glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC) load("glVertexAttrib4bv", userptr); - glIsShader = (PFNGLISSHADERPROC) load("glIsShader", userptr); - glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC) load("glVertexAttrib4iv", userptr); - glIsProgram = (PFNGLISPROGRAMPROC) load("glIsProgram", userptr); - glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC) load("glVertexAttrib1d", userptr); - glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC) load("glVertexAttrib2dv", userptr); - glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC) load("glVertexAttrib3f", userptr); - glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC) load("glVertexAttrib3fv", userptr); - glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC) load("glVertexAttrib4Nusv", userptr); - glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC) load("glVertexAttrib4Nub", userptr); - glLinkProgram = (PFNGLLINKPROGRAMPROC) load("glLinkProgram", userptr); - glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC) load("glVertexAttrib2s", userptr); - glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC) load("glVertexAttrib3dv", userptr); - glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC) load("glVertexAttrib4ubv", userptr); - glUniform1i = (PFNGLUNIFORM1IPROC) load("glUniform1i", userptr); - glCompileShader = (PFNGLCOMPILESHADERPROC) load("glCompileShader", userptr); - glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC) load("glBlendEquationSeparate", userptr); - glDeleteShader = (PFNGLDELETESHADERPROC) load("glDeleteShader", userptr); - glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC) load("glGetVertexAttribfv", userptr); - glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC) load("glGetVertexAttribiv", userptr); - glShaderSource = (PFNGLSHADERSOURCEPROC) load("glShaderSource", userptr); - glUniform1f = (PFNGLUNIFORM1FPROC) load("glUniform1f", userptr); - glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC) load("glStencilFuncSeparate", userptr); - glUniform1iv = (PFNGLUNIFORM1IVPROC) load("glUniform1iv", userptr); - glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC) load("glVertexAttrib4fv", userptr); - glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC) load("glVertexAttrib4dv", userptr); - glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC) load("glGetActiveAttrib", userptr); - glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC) load("glEnableVertexAttribArray", userptr); - glUniform1fv = (PFNGLUNIFORM1FVPROC) load("glUniform1fv", userptr); - glUniform2fv = (PFNGLUNIFORM2FVPROC) load("glUniform2fv", userptr); - glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC) load("glVertexAttrib2sv", userptr); - glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC) load("glVertexAttrib4Nbv", userptr); - glUniform3fv = (PFNGLUNIFORM3FVPROC) load("glUniform3fv", userptr); - glGetShaderiv = (PFNGLGETSHADERIVPROC) load("glGetShaderiv", userptr); - glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC) load("glVertexAttribPointer", userptr); - glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC) load("glGetVertexAttribPointerv", userptr); - glDeleteProgram = (PFNGLDELETEPROGRAMPROC) load("glDeleteProgram", userptr); - glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC) load("glVertexAttrib3s", userptr); - glValidateProgram = (PFNGLVALIDATEPROGRAMPROC) load("glValidateProgram", userptr); - glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC) load("glVertexAttrib4uiv", userptr); - glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC) load("glGetVertexAttribdv", userptr); - glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC) load("glGetProgramInfoLog", userptr); - glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC) load("glStencilMaskSeparate", userptr); - glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC) load("glBindAttribLocation", userptr); - glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC) load("glGetUniformLocation", userptr); - glUseProgram = (PFNGLUSEPROGRAMPROC) load("glUseProgram", userptr); - glGetProgramiv = (PFNGLGETPROGRAMIVPROC) load("glGetProgramiv", userptr); - glUniform3iv = (PFNGLUNIFORM3IVPROC) load("glUniform3iv", userptr); - glUniform4i = (PFNGLUNIFORM4IPROC) load("glUniform4i", userptr); - glGetUniformfv = (PFNGLGETUNIFORMFVPROC) load("glGetUniformfv", userptr); - glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC) load("glVertexAttrib4Niv", userptr); - glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC) load("glDisableVertexAttribArray", userptr); - glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC) load("glGetAttachedShaders", userptr); - glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC) load("glVertexAttrib3d", userptr); - glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC) load("glVertexAttrib4f", userptr); - glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC) load("glVertexAttrib1dv", userptr); - glUniform4iv = (PFNGLUNIFORM4IVPROC) load("glUniform4iv", userptr); +static void load_GL_VERSION_2_0(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_GL_VERSION_2_0) return; + glUniform2i = (PFNGLUNIFORM2IPROC)load("glUniform2i", userptr); + glVertexAttrib2fv = (PFNGLVERTEXATTRIB2FVPROC)load("glVertexAttrib2fv", userptr); + glUniformMatrix3fv = (PFNGLUNIFORMMATRIX3FVPROC)load("glUniformMatrix3fv", userptr); + glUniform2iv = (PFNGLUNIFORM2IVPROC)load("glUniform2iv", userptr); + glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)load("glGetActiveUniform", userptr); + glUniformMatrix4fv = (PFNGLUNIFORMMATRIX4FVPROC)load("glUniformMatrix4fv", userptr); + glDetachShader = (PFNGLDETACHSHADERPROC)load("glDetachShader", userptr); + glVertexAttrib4s = (PFNGLVERTEXATTRIB4SPROC)load("glVertexAttrib4s", userptr); + glAttachShader = (PFNGLATTACHSHADERPROC)load("glAttachShader", userptr); + glVertexAttrib4Nuiv = (PFNGLVERTEXATTRIB4NUIVPROC)load("glVertexAttrib4Nuiv", userptr); + glGetAttribLocation = (PFNGLGETATTRIBLOCATIONPROC)load("glGetAttribLocation", userptr); + glUniform2f = (PFNGLUNIFORM2FPROC)load("glUniform2f", userptr); + glVertexAttrib1s = (PFNGLVERTEXATTRIB1SPROC)load("glVertexAttrib1s", userptr); + glVertexAttrib4Nsv = (PFNGLVERTEXATTRIB4NSVPROC)load("glVertexAttrib4Nsv", userptr); + glVertexAttrib1f = (PFNGLVERTEXATTRIB1FPROC)load("glVertexAttrib1f", userptr); + glVertexAttrib3sv = (PFNGLVERTEXATTRIB3SVPROC)load("glVertexAttrib3sv", userptr); + glGetUniformiv = (PFNGLGETUNIFORMIVPROC)load("glGetUniformiv", userptr); + glVertexAttrib4sv = (PFNGLVERTEXATTRIB4SVPROC)load("glVertexAttrib4sv", userptr); + glCreateShader = (PFNGLCREATESHADERPROC)load("glCreateShader", userptr); + glStencilOpSeparate = (PFNGLSTENCILOPSEPARATEPROC)load("glStencilOpSeparate", userptr); + glUniform3f = (PFNGLUNIFORM3FPROC)load("glUniform3f", userptr); + glVertexAttrib4usv = (PFNGLVERTEXATTRIB4USVPROC)load("glVertexAttrib4usv", userptr); + glCreateProgram = (PFNGLCREATEPROGRAMPROC)load("glCreateProgram", userptr); + glUniform4f = (PFNGLUNIFORM4FPROC)load("glUniform4f", userptr); + glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)load("glGetShaderInfoLog", userptr); + glVertexAttrib2d = (PFNGLVERTEXATTRIB2DPROC)load("glVertexAttrib2d", userptr); + glVertexAttrib2f = (PFNGLVERTEXATTRIB2FPROC)load("glVertexAttrib2f", userptr); + glUniformMatrix2fv = (PFNGLUNIFORMMATRIX2FVPROC)load("glUniformMatrix2fv", userptr); + glUniform4fv = (PFNGLUNIFORM4FVPROC)load("glUniform4fv", userptr); + glVertexAttrib4d = (PFNGLVERTEXATTRIB4DPROC)load("glVertexAttrib4d", userptr); + glVertexAttrib1fv = (PFNGLVERTEXATTRIB1FVPROC)load("glVertexAttrib1fv", userptr); + glVertexAttrib4Nubv = (PFNGLVERTEXATTRIB4NUBVPROC)load("glVertexAttrib4Nubv", userptr); + glVertexAttrib1sv = (PFNGLVERTEXATTRIB1SVPROC)load("glVertexAttrib1sv", userptr); + glDrawBuffers = (PFNGLDRAWBUFFERSPROC)load("glDrawBuffers", userptr); + glGetShaderSource = (PFNGLGETSHADERSOURCEPROC)load("glGetShaderSource", userptr); + glUniform3i = (PFNGLUNIFORM3IPROC)load("glUniform3i", userptr); + glVertexAttrib4bv = (PFNGLVERTEXATTRIB4BVPROC)load("glVertexAttrib4bv", userptr); + glIsShader = (PFNGLISSHADERPROC)load("glIsShader", userptr); + glVertexAttrib4iv = (PFNGLVERTEXATTRIB4IVPROC)load("glVertexAttrib4iv", userptr); + glIsProgram = (PFNGLISPROGRAMPROC)load("glIsProgram", userptr); + glVertexAttrib1d = (PFNGLVERTEXATTRIB1DPROC)load("glVertexAttrib1d", userptr); + glVertexAttrib2dv = (PFNGLVERTEXATTRIB2DVPROC)load("glVertexAttrib2dv", userptr); + glVertexAttrib3f = (PFNGLVERTEXATTRIB3FPROC)load("glVertexAttrib3f", userptr); + glVertexAttrib3fv = (PFNGLVERTEXATTRIB3FVPROC)load("glVertexAttrib3fv", userptr); + glVertexAttrib4Nusv = (PFNGLVERTEXATTRIB4NUSVPROC)load("glVertexAttrib4Nusv", userptr); + glVertexAttrib4Nub = (PFNGLVERTEXATTRIB4NUBPROC)load("glVertexAttrib4Nub", userptr); + glLinkProgram = (PFNGLLINKPROGRAMPROC)load("glLinkProgram", userptr); + glVertexAttrib2s = (PFNGLVERTEXATTRIB2SPROC)load("glVertexAttrib2s", userptr); + glVertexAttrib3dv = (PFNGLVERTEXATTRIB3DVPROC)load("glVertexAttrib3dv", userptr); + glVertexAttrib4ubv = (PFNGLVERTEXATTRIB4UBVPROC)load("glVertexAttrib4ubv", userptr); + glUniform1i = (PFNGLUNIFORM1IPROC)load("glUniform1i", userptr); + glCompileShader = (PFNGLCOMPILESHADERPROC)load("glCompileShader", userptr); + glBlendEquationSeparate = (PFNGLBLENDEQUATIONSEPARATEPROC)load("glBlendEquationSeparate", userptr); + glDeleteShader = (PFNGLDELETESHADERPROC)load("glDeleteShader", userptr); + glGetVertexAttribfv = (PFNGLGETVERTEXATTRIBFVPROC)load("glGetVertexAttribfv", userptr); + glGetVertexAttribiv = (PFNGLGETVERTEXATTRIBIVPROC)load("glGetVertexAttribiv", userptr); + glShaderSource = (PFNGLSHADERSOURCEPROC)load("glShaderSource", userptr); + glUniform1f = (PFNGLUNIFORM1FPROC)load("glUniform1f", userptr); + glStencilFuncSeparate = (PFNGLSTENCILFUNCSEPARATEPROC)load("glStencilFuncSeparate", userptr); + glUniform1iv = (PFNGLUNIFORM1IVPROC)load("glUniform1iv", userptr); + glVertexAttrib4fv = (PFNGLVERTEXATTRIB4FVPROC)load("glVertexAttrib4fv", userptr); + glVertexAttrib4dv = (PFNGLVERTEXATTRIB4DVPROC)load("glVertexAttrib4dv", userptr); + glGetActiveAttrib = (PFNGLGETACTIVEATTRIBPROC)load("glGetActiveAttrib", userptr); + glEnableVertexAttribArray = (PFNGLENABLEVERTEXATTRIBARRAYPROC)load("glEnableVertexAttribArray", userptr); + glUniform1fv = (PFNGLUNIFORM1FVPROC)load("glUniform1fv", userptr); + glUniform2fv = (PFNGLUNIFORM2FVPROC)load("glUniform2fv", userptr); + glVertexAttrib2sv = (PFNGLVERTEXATTRIB2SVPROC)load("glVertexAttrib2sv", userptr); + glVertexAttrib4Nbv = (PFNGLVERTEXATTRIB4NBVPROC)load("glVertexAttrib4Nbv", userptr); + glUniform3fv = (PFNGLUNIFORM3FVPROC)load("glUniform3fv", userptr); + glGetShaderiv = (PFNGLGETSHADERIVPROC)load("glGetShaderiv", userptr); + glVertexAttribPointer = (PFNGLVERTEXATTRIBPOINTERPROC)load("glVertexAttribPointer", userptr); + glGetVertexAttribPointerv = (PFNGLGETVERTEXATTRIBPOINTERVPROC)load("glGetVertexAttribPointerv", userptr); + glDeleteProgram = (PFNGLDELETEPROGRAMPROC)load("glDeleteProgram", userptr); + glVertexAttrib3s = (PFNGLVERTEXATTRIB3SPROC)load("glVertexAttrib3s", userptr); + glValidateProgram = (PFNGLVALIDATEPROGRAMPROC)load("glValidateProgram", userptr); + glVertexAttrib4uiv = (PFNGLVERTEXATTRIB4UIVPROC)load("glVertexAttrib4uiv", userptr); + glGetVertexAttribdv = (PFNGLGETVERTEXATTRIBDVPROC)load("glGetVertexAttribdv", userptr); + glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)load("glGetProgramInfoLog", userptr); + glStencilMaskSeparate = (PFNGLSTENCILMASKSEPARATEPROC)load("glStencilMaskSeparate", userptr); + glBindAttribLocation = (PFNGLBINDATTRIBLOCATIONPROC)load("glBindAttribLocation", userptr); + glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)load("glGetUniformLocation", userptr); + glUseProgram = (PFNGLUSEPROGRAMPROC)load("glUseProgram", userptr); + glGetProgramiv = (PFNGLGETPROGRAMIVPROC)load("glGetProgramiv", userptr); + glUniform3iv = (PFNGLUNIFORM3IVPROC)load("glUniform3iv", userptr); + glUniform4i = (PFNGLUNIFORM4IPROC)load("glUniform4i", userptr); + glGetUniformfv = (PFNGLGETUNIFORMFVPROC)load("glGetUniformfv", userptr); + glVertexAttrib4Niv = (PFNGLVERTEXATTRIB4NIVPROC)load("glVertexAttrib4Niv", userptr); + glDisableVertexAttribArray = (PFNGLDISABLEVERTEXATTRIBARRAYPROC)load("glDisableVertexAttribArray", userptr); + glGetAttachedShaders = (PFNGLGETATTACHEDSHADERSPROC)load("glGetAttachedShaders", userptr); + glVertexAttrib3d = (PFNGLVERTEXATTRIB3DPROC)load("glVertexAttrib3d", userptr); + glVertexAttrib4f = (PFNGLVERTEXATTRIB4FPROC)load("glVertexAttrib4f", userptr); + glVertexAttrib1dv = (PFNGLVERTEXATTRIB1DVPROC)load("glVertexAttrib1dv", userptr); + glUniform4iv = (PFNGLUNIFORM4IVPROC)load("glUniform4iv", userptr); } -static void load_GL_VERSION_2_1( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_2_1) return; - glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC) load("glUniformMatrix3x2fv", userptr); - glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC) load("glUniformMatrix2x4fv", userptr); - glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC) load("glUniformMatrix4x2fv", userptr); - glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC) load("glUniformMatrix3x4fv", userptr); - glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC) load("glUniformMatrix2x3fv", userptr); - glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC) load("glUniformMatrix4x3fv", userptr); +static void load_GL_VERSION_2_1(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_GL_VERSION_2_1) return; + glUniformMatrix3x2fv = (PFNGLUNIFORMMATRIX3X2FVPROC)load("glUniformMatrix3x2fv", userptr); + glUniformMatrix2x4fv = (PFNGLUNIFORMMATRIX2X4FVPROC)load("glUniformMatrix2x4fv", userptr); + glUniformMatrix4x2fv = (PFNGLUNIFORMMATRIX4X2FVPROC)load("glUniformMatrix4x2fv", userptr); + glUniformMatrix3x4fv = (PFNGLUNIFORMMATRIX3X4FVPROC)load("glUniformMatrix3x4fv", userptr); + glUniformMatrix2x3fv = (PFNGLUNIFORMMATRIX2X3FVPROC)load("glUniformMatrix2x3fv", userptr); + glUniformMatrix4x3fv = (PFNGLUNIFORMMATRIX4X3FVPROC)load("glUniformMatrix4x3fv", userptr); } -static void load_GL_VERSION_3_0( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_3_0) return; - glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC) load("glMapBufferRange", userptr); - glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC) load("glTexParameterIuiv", userptr); - glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC) load("glVertexAttribI4uiv", userptr); - glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC) load("glBindFragDataLocation", userptr); - glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC) load("glClearBufferuiv", userptr); - glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) load("glGenVertexArrays", userptr); - glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC) load("glVertexAttribI4usv", userptr); - glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC) load("glVertexAttribI1iv", userptr); - glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC) load("glTexParameterIiv", userptr); - glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC) load("glVertexAttribI3ui", userptr); - glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC) load("glGenFramebuffers", userptr); - glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC) load("glVertexAttribI4ui", userptr); - glUniform4uiv = (PFNGLUNIFORM4UIVPROC) load("glUniform4uiv", userptr); - glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC) load("glEndTransformFeedback", userptr); - glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC) load("glVertexAttribI1uiv", userptr); - glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC) load("glGetTexParameterIuiv", userptr); - glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC) load("glEndConditionalRender", userptr); - glColorMaski = (PFNGLCOLORMASKIPROC) load("glColorMaski", userptr); - glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC) load("glVertexAttribI4bv", userptr); - glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC) load("glVertexAttribI4sv", userptr); - glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC) load("glIsRenderbuffer", userptr); - glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC) load("glFramebufferTexture1D", userptr); - glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC) load("glGetVertexAttribIiv", userptr); - glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC) load("glVertexAttribI1ui", userptr); - glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC) load("glVertexAttribI2uiv", userptr); - glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC) load("glDeleteFramebuffers", userptr); - glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC) load("glCheckFramebufferStatus", userptr); - glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC) load("glVertexAttribI3uiv", userptr); - glClearBufferiv = (PFNGLCLEARBUFFERIVPROC) load("glClearBufferiv", userptr); - glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC) load("glVertexAttribI4ubv", userptr); - glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC) load("glFramebufferRenderbuffer", userptr); - glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC) load("glVertexAttribIPointer", userptr); - glClearBufferfi = (PFNGLCLEARBUFFERFIPROC) load("glClearBufferfi", userptr); - glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load("glBindBufferBase", userptr); - glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC) load("glVertexAttribI1i", userptr); - glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC) load("glBindFramebuffer", userptr); - glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC) load("glBeginConditionalRender", userptr); - glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC) load("glGenerateMipmap", userptr); - glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC) load("glBindRenderbuffer", userptr); - glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC) load("glDeleteRenderbuffers", userptr); - glUniform2ui = (PFNGLUNIFORM2UIPROC) load("glUniform2ui", userptr); - glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC) load("glDeleteVertexArrays", userptr); - glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC) load("glRenderbufferStorageMultisample", userptr); - glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC) load("glGetBooleani_v", userptr); - glEnablei = (PFNGLENABLEIPROC) load("glEnablei", userptr); - glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC) load("glFramebufferTexture2D", userptr); - glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC) load("glGetUniformuiv", userptr); - glUniform3ui = (PFNGLUNIFORM3UIPROC) load("glUniform3ui", userptr); - glClampColor = (PFNGLCLAMPCOLORPROC) load("glClampColor", userptr); - glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC) load("glGetVertexAttribIuiv", userptr); - glUniform1ui = (PFNGLUNIFORM1UIPROC) load("glUniform1ui", userptr); - glIsVertexArray = (PFNGLISVERTEXARRAYPROC) load("glIsVertexArray", userptr); - glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC) load("glBeginTransformFeedback", userptr); - glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC) load("glRenderbufferStorage", userptr); - glDisablei = (PFNGLDISABLEIPROC) load("glDisablei", userptr); - glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC) load("glGetTexParameterIiv", userptr); - glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC) load("glVertexAttribI2i", userptr); - glIsEnabledi = (PFNGLISENABLEDIPROC) load("glIsEnabledi", userptr); - glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC) load("glVertexAttribI4iv", userptr); - glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC) load("glGenRenderbuffers", userptr); - glGetStringi = (PFNGLGETSTRINGIPROC) load("glGetStringi", userptr); - glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC) load("glTransformFeedbackVaryings", userptr); - glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load("glGetFramebufferAttachmentParameteriv", userptr); - glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load("glBindBufferRange", userptr); - glUniform3uiv = (PFNGLUNIFORM3UIVPROC) load("glUniform3uiv", userptr); - glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC) load("glVertexAttribI2iv", userptr); - glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC) load("glFlushMappedBufferRange", userptr); - glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC) load("glVertexAttribI2ui", userptr); - glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) load("glBindVertexArray", userptr); - glUniform2uiv = (PFNGLUNIFORM2UIVPROC) load("glUniform2uiv", userptr); - glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC) load("glVertexAttribI3iv", userptr); - glUniform1uiv = (PFNGLUNIFORM1UIVPROC) load("glUniform1uiv", userptr); - glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC) load("glBlitFramebuffer", userptr); - glClearBufferfv = (PFNGLCLEARBUFFERFVPROC) load("glClearBufferfv", userptr); - glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC) load("glIsFramebuffer", userptr); - glUniform4ui = (PFNGLUNIFORM4UIPROC) load("glUniform4ui", userptr); - glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load("glGetIntegeri_v", userptr); - glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC) load("glVertexAttribI4i", userptr); - glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC) load("glVertexAttribI3i", userptr); - glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC) load("glGetFragDataLocation", userptr); - glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC) load("glGetTransformFeedbackVarying", userptr); - glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC) load("glFramebufferTextureLayer", userptr); - glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC) load("glFramebufferTexture3D", userptr); - glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC) load("glGetRenderbufferParameteriv", userptr); +static void load_GL_VERSION_3_0(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_GL_VERSION_3_0) return; + glMapBufferRange = (PFNGLMAPBUFFERRANGEPROC)load("glMapBufferRange", userptr); + glTexParameterIuiv = (PFNGLTEXPARAMETERIUIVPROC)load("glTexParameterIuiv", userptr); + glVertexAttribI4uiv = (PFNGLVERTEXATTRIBI4UIVPROC)load("glVertexAttribI4uiv", userptr); + glBindFragDataLocation = (PFNGLBINDFRAGDATALOCATIONPROC)load("glBindFragDataLocation", userptr); + glClearBufferuiv = (PFNGLCLEARBUFFERUIVPROC)load("glClearBufferuiv", userptr); + glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC)load("glGenVertexArrays", userptr); + glVertexAttribI4usv = (PFNGLVERTEXATTRIBI4USVPROC)load("glVertexAttribI4usv", userptr); + glVertexAttribI1iv = (PFNGLVERTEXATTRIBI1IVPROC)load("glVertexAttribI1iv", userptr); + glTexParameterIiv = (PFNGLTEXPARAMETERIIVPROC)load("glTexParameterIiv", userptr); + glVertexAttribI3ui = (PFNGLVERTEXATTRIBI3UIPROC)load("glVertexAttribI3ui", userptr); + glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)load("glGenFramebuffers", userptr); + glVertexAttribI4ui = (PFNGLVERTEXATTRIBI4UIPROC)load("glVertexAttribI4ui", userptr); + glUniform4uiv = (PFNGLUNIFORM4UIVPROC)load("glUniform4uiv", userptr); + glEndTransformFeedback = (PFNGLENDTRANSFORMFEEDBACKPROC)load("glEndTransformFeedback", userptr); + glVertexAttribI1uiv = (PFNGLVERTEXATTRIBI1UIVPROC)load("glVertexAttribI1uiv", userptr); + glGetTexParameterIuiv = (PFNGLGETTEXPARAMETERIUIVPROC)load("glGetTexParameterIuiv", userptr); + glEndConditionalRender = (PFNGLENDCONDITIONALRENDERPROC)load("glEndConditionalRender", userptr); + glColorMaski = (PFNGLCOLORMASKIPROC)load("glColorMaski", userptr); + glVertexAttribI4bv = (PFNGLVERTEXATTRIBI4BVPROC)load("glVertexAttribI4bv", userptr); + glVertexAttribI4sv = (PFNGLVERTEXATTRIBI4SVPROC)load("glVertexAttribI4sv", userptr); + glIsRenderbuffer = (PFNGLISRENDERBUFFERPROC)load("glIsRenderbuffer", userptr); + glFramebufferTexture1D = (PFNGLFRAMEBUFFERTEXTURE1DPROC)load("glFramebufferTexture1D", userptr); + glGetVertexAttribIiv = (PFNGLGETVERTEXATTRIBIIVPROC)load("glGetVertexAttribIiv", userptr); + glVertexAttribI1ui = (PFNGLVERTEXATTRIBI1UIPROC)load("glVertexAttribI1ui", userptr); + glVertexAttribI2uiv = (PFNGLVERTEXATTRIBI2UIVPROC)load("glVertexAttribI2uiv", userptr); + glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)load("glDeleteFramebuffers", userptr); + glCheckFramebufferStatus = (PFNGLCHECKFRAMEBUFFERSTATUSPROC)load("glCheckFramebufferStatus", userptr); + glVertexAttribI3uiv = (PFNGLVERTEXATTRIBI3UIVPROC)load("glVertexAttribI3uiv", userptr); + glClearBufferiv = (PFNGLCLEARBUFFERIVPROC)load("glClearBufferiv", userptr); + glVertexAttribI4ubv = (PFNGLVERTEXATTRIBI4UBVPROC)load("glVertexAttribI4ubv", userptr); + glFramebufferRenderbuffer = (PFNGLFRAMEBUFFERRENDERBUFFERPROC)load("glFramebufferRenderbuffer", userptr); + glVertexAttribIPointer = (PFNGLVERTEXATTRIBIPOINTERPROC)load("glVertexAttribIPointer", userptr); + glClearBufferfi = (PFNGLCLEARBUFFERFIPROC)load("glClearBufferfi", userptr); + glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)load("glBindBufferBase", userptr); + glVertexAttribI1i = (PFNGLVERTEXATTRIBI1IPROC)load("glVertexAttribI1i", userptr); + glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)load("glBindFramebuffer", userptr); + glBeginConditionalRender = (PFNGLBEGINCONDITIONALRENDERPROC)load("glBeginConditionalRender", userptr); + glGenerateMipmap = (PFNGLGENERATEMIPMAPPROC)load("glGenerateMipmap", userptr); + glBindRenderbuffer = (PFNGLBINDRENDERBUFFERPROC)load("glBindRenderbuffer", userptr); + glDeleteRenderbuffers = (PFNGLDELETERENDERBUFFERSPROC)load("glDeleteRenderbuffers", userptr); + glUniform2ui = (PFNGLUNIFORM2UIPROC)load("glUniform2ui", userptr); + glDeleteVertexArrays = (PFNGLDELETEVERTEXARRAYSPROC)load("glDeleteVertexArrays", userptr); + glRenderbufferStorageMultisample = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)load("glRenderbufferStorageMultisample", userptr); + glGetBooleani_v = (PFNGLGETBOOLEANI_VPROC)load("glGetBooleani_v", userptr); + glEnablei = (PFNGLENABLEIPROC)load("glEnablei", userptr); + glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)load("glFramebufferTexture2D", userptr); + glGetUniformuiv = (PFNGLGETUNIFORMUIVPROC)load("glGetUniformuiv", userptr); + glUniform3ui = (PFNGLUNIFORM3UIPROC)load("glUniform3ui", userptr); + glClampColor = (PFNGLCLAMPCOLORPROC)load("glClampColor", userptr); + glGetVertexAttribIuiv = (PFNGLGETVERTEXATTRIBIUIVPROC)load("glGetVertexAttribIuiv", userptr); + glUniform1ui = (PFNGLUNIFORM1UIPROC)load("glUniform1ui", userptr); + glIsVertexArray = (PFNGLISVERTEXARRAYPROC)load("glIsVertexArray", userptr); + glBeginTransformFeedback = (PFNGLBEGINTRANSFORMFEEDBACKPROC)load("glBeginTransformFeedback", userptr); + glRenderbufferStorage = (PFNGLRENDERBUFFERSTORAGEPROC)load("glRenderbufferStorage", userptr); + glDisablei = (PFNGLDISABLEIPROC)load("glDisablei", userptr); + glGetTexParameterIiv = (PFNGLGETTEXPARAMETERIIVPROC)load("glGetTexParameterIiv", userptr); + glVertexAttribI2i = (PFNGLVERTEXATTRIBI2IPROC)load("glVertexAttribI2i", userptr); + glIsEnabledi = (PFNGLISENABLEDIPROC)load("glIsEnabledi", userptr); + glVertexAttribI4iv = (PFNGLVERTEXATTRIBI4IVPROC)load("glVertexAttribI4iv", userptr); + glGenRenderbuffers = (PFNGLGENRENDERBUFFERSPROC)load("glGenRenderbuffers", userptr); + glGetStringi = (PFNGLGETSTRINGIPROC)load("glGetStringi", userptr); + glTransformFeedbackVaryings = (PFNGLTRANSFORMFEEDBACKVARYINGSPROC)load("glTransformFeedbackVaryings", userptr); + glGetFramebufferAttachmentParameteriv = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)load("glGetFramebufferAttachmentParameteriv", userptr); + glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)load("glBindBufferRange", userptr); + glUniform3uiv = (PFNGLUNIFORM3UIVPROC)load("glUniform3uiv", userptr); + glVertexAttribI2iv = (PFNGLVERTEXATTRIBI2IVPROC)load("glVertexAttribI2iv", userptr); + glFlushMappedBufferRange = (PFNGLFLUSHMAPPEDBUFFERRANGEPROC)load("glFlushMappedBufferRange", userptr); + glVertexAttribI2ui = (PFNGLVERTEXATTRIBI2UIPROC)load("glVertexAttribI2ui", userptr); + glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC)load("glBindVertexArray", userptr); + glUniform2uiv = (PFNGLUNIFORM2UIVPROC)load("glUniform2uiv", userptr); + glVertexAttribI3iv = (PFNGLVERTEXATTRIBI3IVPROC)load("glVertexAttribI3iv", userptr); + glUniform1uiv = (PFNGLUNIFORM1UIVPROC)load("glUniform1uiv", userptr); + glBlitFramebuffer = (PFNGLBLITFRAMEBUFFERPROC)load("glBlitFramebuffer", userptr); + glClearBufferfv = (PFNGLCLEARBUFFERFVPROC)load("glClearBufferfv", userptr); + glIsFramebuffer = (PFNGLISFRAMEBUFFERPROC)load("glIsFramebuffer", userptr); + glUniform4ui = (PFNGLUNIFORM4UIPROC)load("glUniform4ui", userptr); + glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)load("glGetIntegeri_v", userptr); + glVertexAttribI4i = (PFNGLVERTEXATTRIBI4IPROC)load("glVertexAttribI4i", userptr); + glVertexAttribI3i = (PFNGLVERTEXATTRIBI3IPROC)load("glVertexAttribI3i", userptr); + glGetFragDataLocation = (PFNGLGETFRAGDATALOCATIONPROC)load("glGetFragDataLocation", userptr); + glGetTransformFeedbackVarying = (PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)load("glGetTransformFeedbackVarying", userptr); + glFramebufferTextureLayer = (PFNGLFRAMEBUFFERTEXTURELAYERPROC)load("glFramebufferTextureLayer", userptr); + glFramebufferTexture3D = (PFNGLFRAMEBUFFERTEXTURE3DPROC)load("glFramebufferTexture3D", userptr); + glGetRenderbufferParameteriv = (PFNGLGETRENDERBUFFERPARAMETERIVPROC)load("glGetRenderbufferParameteriv", userptr); } -static void load_GL_VERSION_3_1( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_3_1) return; - glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC) load("glDrawArraysInstanced", userptr); - glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC) load("glBindBufferRange", userptr); - glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC) load("glGetActiveUniformName", userptr); - glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC) load("glGetUniformBlockIndex", userptr); - glBindBufferBase = (PFNGLBINDBUFFERBASEPROC) load("glBindBufferBase", userptr); - glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC) load("glGetActiveUniformBlockiv", userptr); - glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC) load("glCopyBufferSubData", userptr); - glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC) load("glGetUniformIndices", userptr); - glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) load("glGetActiveUniformBlockName", userptr); - glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC) load("glGetIntegeri_v", userptr); - glTexBuffer = (PFNGLTEXBUFFERPROC) load("glTexBuffer", userptr); - glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC) load("glUniformBlockBinding", userptr); - glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC) load("glDrawElementsInstanced", userptr); - glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC) load("glGetActiveUniformsiv", userptr); - glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC) load("glPrimitiveRestartIndex", userptr); +static void load_GL_VERSION_3_1(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_GL_VERSION_3_1) return; + glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)load("glDrawArraysInstanced", userptr); + glBindBufferRange = (PFNGLBINDBUFFERRANGEPROC)load("glBindBufferRange", userptr); + glGetActiveUniformName = (PFNGLGETACTIVEUNIFORMNAMEPROC)load("glGetActiveUniformName", userptr); + glGetUniformBlockIndex = (PFNGLGETUNIFORMBLOCKINDEXPROC)load("glGetUniformBlockIndex", userptr); + glBindBufferBase = (PFNGLBINDBUFFERBASEPROC)load("glBindBufferBase", userptr); + glGetActiveUniformBlockiv = (PFNGLGETACTIVEUNIFORMBLOCKIVPROC)load("glGetActiveUniformBlockiv", userptr); + glCopyBufferSubData = (PFNGLCOPYBUFFERSUBDATAPROC)load("glCopyBufferSubData", userptr); + glGetUniformIndices = (PFNGLGETUNIFORMINDICESPROC)load("glGetUniformIndices", userptr); + glGetActiveUniformBlockName = (PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)load("glGetActiveUniformBlockName", userptr); + glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)load("glGetIntegeri_v", userptr); + glTexBuffer = (PFNGLTEXBUFFERPROC)load("glTexBuffer", userptr); + glUniformBlockBinding = (PFNGLUNIFORMBLOCKBINDINGPROC)load("glUniformBlockBinding", userptr); + glDrawElementsInstanced = (PFNGLDRAWELEMENTSINSTANCEDPROC)load("glDrawElementsInstanced", userptr); + glGetActiveUniformsiv = (PFNGLGETACTIVEUNIFORMSIVPROC)load("glGetActiveUniformsiv", userptr); + glPrimitiveRestartIndex = (PFNGLPRIMITIVERESTARTINDEXPROC)load("glPrimitiveRestartIndex", userptr); } -static void load_GL_VERSION_3_2( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_3_2) return; - glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC) load("glDrawElementsInstancedBaseVertex", userptr); - glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC) load("glGetMultisamplefv", userptr); - glGetInteger64v = (PFNGLGETINTEGER64VPROC) load("glGetInteger64v", userptr); - glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC) load("glGetInteger64i_v", userptr); - glGetSynciv = (PFNGLGETSYNCIVPROC) load("glGetSynciv", userptr); - glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC) load("glDrawRangeElementsBaseVertex", userptr); - glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC) load("glFramebufferTexture", userptr); - glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC) load("glGetBufferParameteri64v", userptr); - glSampleMaski = (PFNGLSAMPLEMASKIPROC) load("glSampleMaski", userptr); - glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC) load("glTexImage3DMultisample", userptr); - glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC) load("glMultiDrawElementsBaseVertex", userptr); - glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC) load("glClientWaitSync", userptr); - glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC) load("glProvokingVertex", userptr); - glWaitSync = (PFNGLWAITSYNCPROC) load("glWaitSync", userptr); - glDeleteSync = (PFNGLDELETESYNCPROC) load("glDeleteSync", userptr); - glIsSync = (PFNGLISSYNCPROC) load("glIsSync", userptr); - glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC) load("glTexImage2DMultisample", userptr); - glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC) load("glDrawElementsBaseVertex", userptr); - glFenceSync = (PFNGLFENCESYNCPROC) load("glFenceSync", userptr); +static void load_GL_VERSION_3_2(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_GL_VERSION_3_2) return; + glDrawElementsInstancedBaseVertex = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)load("glDrawElementsInstancedBaseVertex", userptr); + glGetMultisamplefv = (PFNGLGETMULTISAMPLEFVPROC)load("glGetMultisamplefv", userptr); + glGetInteger64v = (PFNGLGETINTEGER64VPROC)load("glGetInteger64v", userptr); + glGetInteger64i_v = (PFNGLGETINTEGER64I_VPROC)load("glGetInteger64i_v", userptr); + glGetSynciv = (PFNGLGETSYNCIVPROC)load("glGetSynciv", userptr); + glDrawRangeElementsBaseVertex = (PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)load("glDrawRangeElementsBaseVertex", userptr); + glFramebufferTexture = (PFNGLFRAMEBUFFERTEXTUREPROC)load("glFramebufferTexture", userptr); + glGetBufferParameteri64v = (PFNGLGETBUFFERPARAMETERI64VPROC)load("glGetBufferParameteri64v", userptr); + glSampleMaski = (PFNGLSAMPLEMASKIPROC)load("glSampleMaski", userptr); + glTexImage3DMultisample = (PFNGLTEXIMAGE3DMULTISAMPLEPROC)load("glTexImage3DMultisample", userptr); + glMultiDrawElementsBaseVertex = (PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)load("glMultiDrawElementsBaseVertex", userptr); + glClientWaitSync = (PFNGLCLIENTWAITSYNCPROC)load("glClientWaitSync", userptr); + glProvokingVertex = (PFNGLPROVOKINGVERTEXPROC)load("glProvokingVertex", userptr); + glWaitSync = (PFNGLWAITSYNCPROC)load("glWaitSync", userptr); + glDeleteSync = (PFNGLDELETESYNCPROC)load("glDeleteSync", userptr); + glIsSync = (PFNGLISSYNCPROC)load("glIsSync", userptr); + glTexImage2DMultisample = (PFNGLTEXIMAGE2DMULTISAMPLEPROC)load("glTexImage2DMultisample", userptr); + glDrawElementsBaseVertex = (PFNGLDRAWELEMENTSBASEVERTEXPROC)load("glDrawElementsBaseVertex", userptr); + glFenceSync = (PFNGLFENCESYNCPROC)load("glFenceSync", userptr); } -static void load_GL_VERSION_3_3( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_3_3) return; - glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC) load("glSamplerParameterf", userptr); - glGenSamplers = (PFNGLGENSAMPLERSPROC) load("glGenSamplers", userptr); - glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC) load("glVertexAttribDivisor", userptr); - glNormalP3uiv = (PFNGLNORMALP3UIVPROC) load("glNormalP3uiv", userptr); - glNormalP3ui = (PFNGLNORMALP3UIPROC) load("glNormalP3ui", userptr); - glTexCoordP1uiv = (PFNGLTEXCOORDP1UIVPROC) load("glTexCoordP1uiv", userptr); - glVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC) load("glVertexAttribP1ui", userptr); - glVertexP2uiv = (PFNGLVERTEXP2UIVPROC) load("glVertexP2uiv", userptr); - glVertexP3uiv = (PFNGLVERTEXP3UIVPROC) load("glVertexP3uiv", userptr); - glVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC) load("glVertexAttribP3uiv", userptr); - glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC) load("glSamplerParameterIuiv", userptr); - glVertexP2ui = (PFNGLVERTEXP2UIPROC) load("glVertexP2ui", userptr); - glTexCoordP2uiv = (PFNGLTEXCOORDP2UIVPROC) load("glTexCoordP2uiv", userptr); - glVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC) load("glVertexAttribP1uiv", userptr); - glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC) load("glSamplerParameteri", userptr); - glMultiTexCoordP3ui = (PFNGLMULTITEXCOORDP3UIPROC) load("glMultiTexCoordP3ui", userptr); - glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC) load("glGetQueryObjecti64v", userptr); - glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC) load("glGetSamplerParameterIiv", userptr); - glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC) load("glSamplerParameterfv", userptr); - glMultiTexCoordP2ui = (PFNGLMULTITEXCOORDP2UIPROC) load("glMultiTexCoordP2ui", userptr); - glVertexP3ui = (PFNGLVERTEXP3UIPROC) load("glVertexP3ui", userptr); - glTexCoordP2ui = (PFNGLTEXCOORDP2UIPROC) load("glTexCoordP2ui", userptr); - glColorP4uiv = (PFNGLCOLORP4UIVPROC) load("glColorP4uiv", userptr); - glBindSampler = (PFNGLBINDSAMPLERPROC) load("glBindSampler", userptr); - glVertexP4uiv = (PFNGLVERTEXP4UIVPROC) load("glVertexP4uiv", userptr); - glVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC) load("glVertexAttribP3ui", userptr); - glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC) load("glGetSamplerParameterIuiv", userptr); - glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC) load("glBindFragDataLocationIndexed", userptr); - glMultiTexCoordP4uiv = (PFNGLMULTITEXCOORDP4UIVPROC) load("glMultiTexCoordP4uiv", userptr); - glIsSampler = (PFNGLISSAMPLERPROC) load("glIsSampler", userptr); - glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC) load("glGetSamplerParameterfv", userptr); - glTexCoordP3ui = (PFNGLTEXCOORDP3UIPROC) load("glTexCoordP3ui", userptr); - glVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC) load("glVertexAttribP4uiv", userptr); - glSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC) load("glSecondaryColorP3uiv", userptr); - glQueryCounter = (PFNGLQUERYCOUNTERPROC) load("glQueryCounter", userptr); - glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC) load("glGetQueryObjectui64v", userptr); - glColorP3uiv = (PFNGLCOLORP3UIVPROC) load("glColorP3uiv", userptr); - glColorP4ui = (PFNGLCOLORP4UIPROC) load("glColorP4ui", userptr); - glVertexP4ui = (PFNGLVERTEXP4UIPROC) load("glVertexP4ui", userptr); - glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC) load("glGetSamplerParameteriv", userptr); - glMultiTexCoordP2uiv = (PFNGLMULTITEXCOORDP2UIVPROC) load("glMultiTexCoordP2uiv", userptr); - glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC) load("glSamplerParameteriv", userptr); - glTexCoordP3uiv = (PFNGLTEXCOORDP3UIVPROC) load("glTexCoordP3uiv", userptr); - glTexCoordP4ui = (PFNGLTEXCOORDP4UIPROC) load("glTexCoordP4ui", userptr); - glMultiTexCoordP1ui = (PFNGLMULTITEXCOORDP1UIPROC) load("glMultiTexCoordP1ui", userptr); - glColorP3ui = (PFNGLCOLORP3UIPROC) load("glColorP3ui", userptr); - glMultiTexCoordP1uiv = (PFNGLMULTITEXCOORDP1UIVPROC) load("glMultiTexCoordP1uiv", userptr); - glMultiTexCoordP4ui = (PFNGLMULTITEXCOORDP4UIPROC) load("glMultiTexCoordP4ui", userptr); - glVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC) load("glVertexAttribP2ui", userptr); - glSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC) load("glSecondaryColorP3ui", userptr); - glTexCoordP1ui = (PFNGLTEXCOORDP1UIPROC) load("glTexCoordP1ui", userptr); - glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC) load("glSamplerParameterIiv", userptr); - glDeleteSamplers = (PFNGLDELETESAMPLERSPROC) load("glDeleteSamplers", userptr); - glVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC) load("glVertexAttribP2uiv", userptr); - glMultiTexCoordP3uiv = (PFNGLMULTITEXCOORDP3UIVPROC) load("glMultiTexCoordP3uiv", userptr); - glVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC) load("glVertexAttribP4ui", userptr); - glTexCoordP4uiv = (PFNGLTEXCOORDP4UIVPROC) load("glTexCoordP4uiv", userptr); - glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC) load("glGetFragDataIndex", userptr); +static void load_GL_VERSION_3_3(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_GL_VERSION_3_3) return; + glSamplerParameterf = (PFNGLSAMPLERPARAMETERFPROC)load("glSamplerParameterf", userptr); + glGenSamplers = (PFNGLGENSAMPLERSPROC)load("glGenSamplers", userptr); + glVertexAttribDivisor = (PFNGLVERTEXATTRIBDIVISORPROC)load("glVertexAttribDivisor", userptr); + glNormalP3uiv = (PFNGLNORMALP3UIVPROC)load("glNormalP3uiv", userptr); + glNormalP3ui = (PFNGLNORMALP3UIPROC)load("glNormalP3ui", userptr); + glTexCoordP1uiv = (PFNGLTEXCOORDP1UIVPROC)load("glTexCoordP1uiv", userptr); + glVertexAttribP1ui = (PFNGLVERTEXATTRIBP1UIPROC)load("glVertexAttribP1ui", userptr); + glVertexP2uiv = (PFNGLVERTEXP2UIVPROC)load("glVertexP2uiv", userptr); + glVertexP3uiv = (PFNGLVERTEXP3UIVPROC)load("glVertexP3uiv", userptr); + glVertexAttribP3uiv = (PFNGLVERTEXATTRIBP3UIVPROC)load("glVertexAttribP3uiv", userptr); + glSamplerParameterIuiv = (PFNGLSAMPLERPARAMETERIUIVPROC)load("glSamplerParameterIuiv", userptr); + glVertexP2ui = (PFNGLVERTEXP2UIPROC)load("glVertexP2ui", userptr); + glTexCoordP2uiv = (PFNGLTEXCOORDP2UIVPROC)load("glTexCoordP2uiv", userptr); + glVertexAttribP1uiv = (PFNGLVERTEXATTRIBP1UIVPROC)load("glVertexAttribP1uiv", userptr); + glSamplerParameteri = (PFNGLSAMPLERPARAMETERIPROC)load("glSamplerParameteri", userptr); + glMultiTexCoordP3ui = (PFNGLMULTITEXCOORDP3UIPROC)load("glMultiTexCoordP3ui", userptr); + glGetQueryObjecti64v = (PFNGLGETQUERYOBJECTI64VPROC)load("glGetQueryObjecti64v", userptr); + glGetSamplerParameterIiv = (PFNGLGETSAMPLERPARAMETERIIVPROC)load("glGetSamplerParameterIiv", userptr); + glSamplerParameterfv = (PFNGLSAMPLERPARAMETERFVPROC)load("glSamplerParameterfv", userptr); + glMultiTexCoordP2ui = (PFNGLMULTITEXCOORDP2UIPROC)load("glMultiTexCoordP2ui", userptr); + glVertexP3ui = (PFNGLVERTEXP3UIPROC)load("glVertexP3ui", userptr); + glTexCoordP2ui = (PFNGLTEXCOORDP2UIPROC)load("glTexCoordP2ui", userptr); + glColorP4uiv = (PFNGLCOLORP4UIVPROC)load("glColorP4uiv", userptr); + glBindSampler = (PFNGLBINDSAMPLERPROC)load("glBindSampler", userptr); + glVertexP4uiv = (PFNGLVERTEXP4UIVPROC)load("glVertexP4uiv", userptr); + glVertexAttribP3ui = (PFNGLVERTEXATTRIBP3UIPROC)load("glVertexAttribP3ui", userptr); + glGetSamplerParameterIuiv = (PFNGLGETSAMPLERPARAMETERIUIVPROC)load("glGetSamplerParameterIuiv", userptr); + glBindFragDataLocationIndexed = (PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)load("glBindFragDataLocationIndexed", userptr); + glMultiTexCoordP4uiv = (PFNGLMULTITEXCOORDP4UIVPROC)load("glMultiTexCoordP4uiv", userptr); + glIsSampler = (PFNGLISSAMPLERPROC)load("glIsSampler", userptr); + glGetSamplerParameterfv = (PFNGLGETSAMPLERPARAMETERFVPROC)load("glGetSamplerParameterfv", userptr); + glTexCoordP3ui = (PFNGLTEXCOORDP3UIPROC)load("glTexCoordP3ui", userptr); + glVertexAttribP4uiv = (PFNGLVERTEXATTRIBP4UIVPROC)load("glVertexAttribP4uiv", userptr); + glSecondaryColorP3uiv = (PFNGLSECONDARYCOLORP3UIVPROC)load("glSecondaryColorP3uiv", userptr); + glQueryCounter = (PFNGLQUERYCOUNTERPROC)load("glQueryCounter", userptr); + glGetQueryObjectui64v = (PFNGLGETQUERYOBJECTUI64VPROC)load("glGetQueryObjectui64v", userptr); + glColorP3uiv = (PFNGLCOLORP3UIVPROC)load("glColorP3uiv", userptr); + glColorP4ui = (PFNGLCOLORP4UIPROC)load("glColorP4ui", userptr); + glVertexP4ui = (PFNGLVERTEXP4UIPROC)load("glVertexP4ui", userptr); + glGetSamplerParameteriv = (PFNGLGETSAMPLERPARAMETERIVPROC)load("glGetSamplerParameteriv", userptr); + glMultiTexCoordP2uiv = (PFNGLMULTITEXCOORDP2UIVPROC)load("glMultiTexCoordP2uiv", userptr); + glSamplerParameteriv = (PFNGLSAMPLERPARAMETERIVPROC)load("glSamplerParameteriv", userptr); + glTexCoordP3uiv = (PFNGLTEXCOORDP3UIVPROC)load("glTexCoordP3uiv", userptr); + glTexCoordP4ui = (PFNGLTEXCOORDP4UIPROC)load("glTexCoordP4ui", userptr); + glMultiTexCoordP1ui = (PFNGLMULTITEXCOORDP1UIPROC)load("glMultiTexCoordP1ui", userptr); + glColorP3ui = (PFNGLCOLORP3UIPROC)load("glColorP3ui", userptr); + glMultiTexCoordP1uiv = (PFNGLMULTITEXCOORDP1UIVPROC)load("glMultiTexCoordP1uiv", userptr); + glMultiTexCoordP4ui = (PFNGLMULTITEXCOORDP4UIPROC)load("glMultiTexCoordP4ui", userptr); + glVertexAttribP2ui = (PFNGLVERTEXATTRIBP2UIPROC)load("glVertexAttribP2ui", userptr); + glSecondaryColorP3ui = (PFNGLSECONDARYCOLORP3UIPROC)load("glSecondaryColorP3ui", userptr); + glTexCoordP1ui = (PFNGLTEXCOORDP1UIPROC)load("glTexCoordP1ui", userptr); + glSamplerParameterIiv = (PFNGLSAMPLERPARAMETERIIVPROC)load("glSamplerParameterIiv", userptr); + glDeleteSamplers = (PFNGLDELETESAMPLERSPROC)load("glDeleteSamplers", userptr); + glVertexAttribP2uiv = (PFNGLVERTEXATTRIBP2UIVPROC)load("glVertexAttribP2uiv", userptr); + glMultiTexCoordP3uiv = (PFNGLMULTITEXCOORDP3UIVPROC)load("glMultiTexCoordP3uiv", userptr); + glVertexAttribP4ui = (PFNGLVERTEXATTRIBP4UIPROC)load("glVertexAttribP4ui", userptr); + glTexCoordP4uiv = (PFNGLTEXCOORDP4UIVPROC)load("glTexCoordP4uiv", userptr); + glGetFragDataIndex = (PFNGLGETFRAGDATAINDEXPROC)load("glGetFragDataIndex", userptr); } -static void load_GL_VERSION_4_0( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_4_0) return; - glBeginQueryIndexed = (PFNGLBEGINQUERYINDEXEDPROC) load("glBeginQueryIndexed", userptr); - glPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC) load("glPauseTransformFeedback", userptr); - glUniformMatrix3x4dv = (PFNGLUNIFORMMATRIX3X4DVPROC) load("glUniformMatrix3x4dv", userptr); - glGetUniformdv = (PFNGLGETUNIFORMDVPROC) load("glGetUniformdv", userptr); - glUniformSubroutinesuiv = (PFNGLUNIFORMSUBROUTINESUIVPROC) load("glUniformSubroutinesuiv", userptr); - glEndQueryIndexed = (PFNGLENDQUERYINDEXEDPROC) load("glEndQueryIndexed", userptr); - glUniform3dv = (PFNGLUNIFORM3DVPROC) load("glUniform3dv", userptr); - glGetProgramStageiv = (PFNGLGETPROGRAMSTAGEIVPROC) load("glGetProgramStageiv", userptr); - glBlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC) load("glBlendFuncSeparatei", userptr); - glBlendEquationi = (PFNGLBLENDEQUATIONIPROC) load("glBlendEquationi", userptr); - glMinSampleShading = (PFNGLMINSAMPLESHADINGPROC) load("glMinSampleShading", userptr); - glUniform4d = (PFNGLUNIFORM4DPROC) load("glUniform4d", userptr); - glUniformMatrix3dv = (PFNGLUNIFORMMATRIX3DVPROC) load("glUniformMatrix3dv", userptr); - glUniform3d = (PFNGLUNIFORM3DPROC) load("glUniform3d", userptr); - glGetActiveSubroutineName = (PFNGLGETACTIVESUBROUTINENAMEPROC) load("glGetActiveSubroutineName", userptr); - glDrawTransformFeedbackStream = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC) load("glDrawTransformFeedbackStream", userptr); - glPatchParameterfv = (PFNGLPATCHPARAMETERFVPROC) load("glPatchParameterfv", userptr); - glUniformMatrix4x2dv = (PFNGLUNIFORMMATRIX4X2DVPROC) load("glUniformMatrix4x2dv", userptr); - glUniform1dv = (PFNGLUNIFORM1DVPROC) load("glUniform1dv", userptr); - glDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC) load("glDrawArraysIndirect", userptr); - glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC) load("glDrawTransformFeedback", userptr); - glGetUniformSubroutineuiv = (PFNGLGETUNIFORMSUBROUTINEUIVPROC) load("glGetUniformSubroutineuiv", userptr); - glUniform4dv = (PFNGLUNIFORM4DVPROC) load("glUniform4dv", userptr); - glBlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC) load("glBlendEquationSeparatei", userptr); - glGetSubroutineUniformLocation = (PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC) load("glGetSubroutineUniformLocation", userptr); - glUniformMatrix2dv = (PFNGLUNIFORMMATRIX2DVPROC) load("glUniformMatrix2dv", userptr); - glUniformMatrix3x2dv = (PFNGLUNIFORMMATRIX3X2DVPROC) load("glUniformMatrix3x2dv", userptr); - glIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC) load("glIsTransformFeedback", userptr); - glDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC) load("glDeleteTransformFeedbacks", userptr); - glGetActiveSubroutineUniformName = (PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC) load("glGetActiveSubroutineUniformName", userptr); - glUniform2d = (PFNGLUNIFORM2DPROC) load("glUniform2d", userptr); - glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC) load("glGenTransformFeedbacks", userptr); - glUniformMatrix4x3dv = (PFNGLUNIFORMMATRIX4X3DVPROC) load("glUniformMatrix4x3dv", userptr); - glUniformMatrix2x4dv = (PFNGLUNIFORMMATRIX2X4DVPROC) load("glUniformMatrix2x4dv", userptr); - glGetActiveSubroutineUniformiv = (PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC) load("glGetActiveSubroutineUniformiv", userptr); - glBlendFunci = (PFNGLBLENDFUNCIPROC) load("glBlendFunci", userptr); - glUniformMatrix2x3dv = (PFNGLUNIFORMMATRIX2X3DVPROC) load("glUniformMatrix2x3dv", userptr); - glGetQueryIndexediv = (PFNGLGETQUERYINDEXEDIVPROC) load("glGetQueryIndexediv", userptr); - glUniform2dv = (PFNGLUNIFORM2DVPROC) load("glUniform2dv", userptr); - glGetSubroutineIndex = (PFNGLGETSUBROUTINEINDEXPROC) load("glGetSubroutineIndex", userptr); - glResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC) load("glResumeTransformFeedback", userptr); - glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC) load("glBindTransformFeedback", userptr); - glUniform1d = (PFNGLUNIFORM1DPROC) load("glUniform1d", userptr); - glPatchParameteri = (PFNGLPATCHPARAMETERIPROC) load("glPatchParameteri", userptr); - glDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC) load("glDrawElementsIndirect", userptr); - glUniformMatrix4dv = (PFNGLUNIFORMMATRIX4DVPROC) load("glUniformMatrix4dv", userptr); +static void load_GL_VERSION_4_0(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_GL_VERSION_4_0) return; + glBeginQueryIndexed = (PFNGLBEGINQUERYINDEXEDPROC)load("glBeginQueryIndexed", userptr); + glPauseTransformFeedback = (PFNGLPAUSETRANSFORMFEEDBACKPROC)load("glPauseTransformFeedback", userptr); + glUniformMatrix3x4dv = (PFNGLUNIFORMMATRIX3X4DVPROC)load("glUniformMatrix3x4dv", userptr); + glGetUniformdv = (PFNGLGETUNIFORMDVPROC)load("glGetUniformdv", userptr); + glUniformSubroutinesuiv = (PFNGLUNIFORMSUBROUTINESUIVPROC)load("glUniformSubroutinesuiv", userptr); + glEndQueryIndexed = (PFNGLENDQUERYINDEXEDPROC)load("glEndQueryIndexed", userptr); + glUniform3dv = (PFNGLUNIFORM3DVPROC)load("glUniform3dv", userptr); + glGetProgramStageiv = (PFNGLGETPROGRAMSTAGEIVPROC)load("glGetProgramStageiv", userptr); + glBlendFuncSeparatei = (PFNGLBLENDFUNCSEPARATEIPROC)load("glBlendFuncSeparatei", userptr); + glBlendEquationi = (PFNGLBLENDEQUATIONIPROC)load("glBlendEquationi", userptr); + glMinSampleShading = (PFNGLMINSAMPLESHADINGPROC)load("glMinSampleShading", userptr); + glUniform4d = (PFNGLUNIFORM4DPROC)load("glUniform4d", userptr); + glUniformMatrix3dv = (PFNGLUNIFORMMATRIX3DVPROC)load("glUniformMatrix3dv", userptr); + glUniform3d = (PFNGLUNIFORM3DPROC)load("glUniform3d", userptr); + glGetActiveSubroutineName = (PFNGLGETACTIVESUBROUTINENAMEPROC)load("glGetActiveSubroutineName", userptr); + glDrawTransformFeedbackStream = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC)load("glDrawTransformFeedbackStream", userptr); + glPatchParameterfv = (PFNGLPATCHPARAMETERFVPROC)load("glPatchParameterfv", userptr); + glUniformMatrix4x2dv = (PFNGLUNIFORMMATRIX4X2DVPROC)load("glUniformMatrix4x2dv", userptr); + glUniform1dv = (PFNGLUNIFORM1DVPROC)load("glUniform1dv", userptr); + glDrawArraysIndirect = (PFNGLDRAWARRAYSINDIRECTPROC)load("glDrawArraysIndirect", userptr); + glDrawTransformFeedback = (PFNGLDRAWTRANSFORMFEEDBACKPROC)load("glDrawTransformFeedback", userptr); + glGetUniformSubroutineuiv = (PFNGLGETUNIFORMSUBROUTINEUIVPROC)load("glGetUniformSubroutineuiv", userptr); + glUniform4dv = (PFNGLUNIFORM4DVPROC)load("glUniform4dv", userptr); + glBlendEquationSeparatei = (PFNGLBLENDEQUATIONSEPARATEIPROC)load("glBlendEquationSeparatei", userptr); + glGetSubroutineUniformLocation = (PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC)load("glGetSubroutineUniformLocation", userptr); + glUniformMatrix2dv = (PFNGLUNIFORMMATRIX2DVPROC)load("glUniformMatrix2dv", userptr); + glUniformMatrix3x2dv = (PFNGLUNIFORMMATRIX3X2DVPROC)load("glUniformMatrix3x2dv", userptr); + glIsTransformFeedback = (PFNGLISTRANSFORMFEEDBACKPROC)load("glIsTransformFeedback", userptr); + glDeleteTransformFeedbacks = (PFNGLDELETETRANSFORMFEEDBACKSPROC)load("glDeleteTransformFeedbacks", userptr); + glGetActiveSubroutineUniformName = (PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC)load("glGetActiveSubroutineUniformName", userptr); + glUniform2d = (PFNGLUNIFORM2DPROC)load("glUniform2d", userptr); + glGenTransformFeedbacks = (PFNGLGENTRANSFORMFEEDBACKSPROC)load("glGenTransformFeedbacks", userptr); + glUniformMatrix4x3dv = (PFNGLUNIFORMMATRIX4X3DVPROC)load("glUniformMatrix4x3dv", userptr); + glUniformMatrix2x4dv = (PFNGLUNIFORMMATRIX2X4DVPROC)load("glUniformMatrix2x4dv", userptr); + glGetActiveSubroutineUniformiv = (PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC)load("glGetActiveSubroutineUniformiv", userptr); + glBlendFunci = (PFNGLBLENDFUNCIPROC)load("glBlendFunci", userptr); + glUniformMatrix2x3dv = (PFNGLUNIFORMMATRIX2X3DVPROC)load("glUniformMatrix2x3dv", userptr); + glGetQueryIndexediv = (PFNGLGETQUERYINDEXEDIVPROC)load("glGetQueryIndexediv", userptr); + glUniform2dv = (PFNGLUNIFORM2DVPROC)load("glUniform2dv", userptr); + glGetSubroutineIndex = (PFNGLGETSUBROUTINEINDEXPROC)load("glGetSubroutineIndex", userptr); + glResumeTransformFeedback = (PFNGLRESUMETRANSFORMFEEDBACKPROC)load("glResumeTransformFeedback", userptr); + glBindTransformFeedback = (PFNGLBINDTRANSFORMFEEDBACKPROC)load("glBindTransformFeedback", userptr); + glUniform1d = (PFNGLUNIFORM1DPROC)load("glUniform1d", userptr); + glPatchParameteri = (PFNGLPATCHPARAMETERIPROC)load("glPatchParameteri", userptr); + glDrawElementsIndirect = (PFNGLDRAWELEMENTSINDIRECTPROC)load("glDrawElementsIndirect", userptr); + glUniformMatrix4dv = (PFNGLUNIFORMMATRIX4DVPROC)load("glUniformMatrix4dv", userptr); } -static void load_GL_VERSION_4_1( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_4_1) return; - glGetDoublei_v = (PFNGLGETDOUBLEI_VPROC) load("glGetDoublei_v", userptr); - glProgramUniform4d = (PFNGLPROGRAMUNIFORM4DPROC) load("glProgramUniform4d", userptr); - glGetFloati_v = (PFNGLGETFLOATI_VPROC) load("glGetFloati_v", userptr); - glIsProgramPipeline = (PFNGLISPROGRAMPIPELINEPROC) load("glIsProgramPipeline", userptr); - glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC) load("glGetProgramBinary", userptr); - glDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC) load("glDepthRangeArrayv", userptr); - glProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC) load("glProgramUniform1iv", userptr); - glProgramUniformMatrix3x2dv = (PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC) load("glProgramUniformMatrix3x2dv", userptr); - glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC) load("glProgramParameteri", userptr); - glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC) load("glVertexAttribLPointer", userptr); - glProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC) load("glProgramUniformMatrix2x3fv", userptr); - glProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC) load("glProgramUniform3fv", userptr); - glProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC) load("glProgramUniform4i", userptr); - glProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC) load("glProgramUniform2iv", userptr); - glProgramUniform1dv = (PFNGLPROGRAMUNIFORM1DVPROC) load("glProgramUniform1dv", userptr); - glDepthRangeIndexed = (PFNGLDEPTHRANGEINDEXEDPROC) load("glDepthRangeIndexed", userptr); - glDeleteProgramPipelines = (PFNGLDELETEPROGRAMPIPELINESPROC) load("glDeleteProgramPipelines", userptr); - glProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC) load("glProgramUniform4fv", userptr); - glVertexAttribL3dv = (PFNGLVERTEXATTRIBL3DVPROC) load("glVertexAttribL3dv", userptr); - glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC) load("glViewportArrayv", userptr); - glVertexAttribL4d = (PFNGLVERTEXATTRIBL4DPROC) load("glVertexAttribL4d", userptr); - glVertexAttribL1dv = (PFNGLVERTEXATTRIBL1DVPROC) load("glVertexAttribL1dv", userptr); - glProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC) load("glProgramUniform3i", userptr); - glCreateShaderProgramv = (PFNGLCREATESHADERPROGRAMVPROC) load("glCreateShaderProgramv", userptr); - glProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC) load("glProgramUniform3uiv", userptr); - glViewportIndexedf = (PFNGLVIEWPORTINDEXEDFPROC) load("glViewportIndexedf", userptr); - glActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC) load("glActiveShaderProgram", userptr); - glViewportIndexedfv = (PFNGLVIEWPORTINDEXEDFVPROC) load("glViewportIndexedfv", userptr); - glProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC) load("glProgramUniform4uiv", userptr); - glProgramUniform1d = (PFNGLPROGRAMUNIFORM1DPROC) load("glProgramUniform1d", userptr); - glProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC) load("glProgramUniform2fv", userptr); - glScissorIndexed = (PFNGLSCISSORINDEXEDPROC) load("glScissorIndexed", userptr); - glProgramBinary = (PFNGLPROGRAMBINARYPROC) load("glProgramBinary", userptr); - glUseProgramStages = (PFNGLUSEPROGRAMSTAGESPROC) load("glUseProgramStages", userptr); - glVertexAttribL2d = (PFNGLVERTEXATTRIBL2DPROC) load("glVertexAttribL2d", userptr); - glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC) load("glReleaseShaderCompiler", userptr); - glProgramUniform3dv = (PFNGLPROGRAMUNIFORM3DVPROC) load("glProgramUniform3dv", userptr); - glProgramUniformMatrix3dv = (PFNGLPROGRAMUNIFORMMATRIX3DVPROC) load("glProgramUniformMatrix3dv", userptr); - glScissorArrayv = (PFNGLSCISSORARRAYVPROC) load("glScissorArrayv", userptr); - glProgramUniformMatrix3x4dv = (PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC) load("glProgramUniformMatrix3x4dv", userptr); - glVertexAttribL4dv = (PFNGLVERTEXATTRIBL4DVPROC) load("glVertexAttribL4dv", userptr); - glProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC) load("glProgramUniform2f", userptr); - glProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC) load("glProgramUniform2i", userptr); - glProgramUniformMatrix4dv = (PFNGLPROGRAMUNIFORMMATRIX4DVPROC) load("glProgramUniformMatrix4dv", userptr); - glProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC) load("glProgramUniform2uiv", userptr); - glProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC) load("glProgramUniformMatrix3x4fv", userptr); - glProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC) load("glProgramUniform4f", userptr); - glClearDepthf = (PFNGLCLEARDEPTHFPROC) load("glClearDepthf", userptr); - glShaderBinary = (PFNGLSHADERBINARYPROC) load("glShaderBinary", userptr); - glProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC) load("glProgramUniform2ui", userptr); - glGetProgramPipelineiv = (PFNGLGETPROGRAMPIPELINEIVPROC) load("glGetProgramPipelineiv", userptr); - glProgramUniformMatrix2x3dv = (PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC) load("glProgramUniformMatrix2x3dv", userptr); - glVertexAttribL2dv = (PFNGLVERTEXATTRIBL2DVPROC) load("glVertexAttribL2dv", userptr); - glProgramUniformMatrix2dv = (PFNGLPROGRAMUNIFORMMATRIX2DVPROC) load("glProgramUniformMatrix2dv", userptr); - glProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC) load("glProgramUniformMatrix2fv", userptr); - glGetProgramPipelineInfoLog = (PFNGLGETPROGRAMPIPELINEINFOLOGPROC) load("glGetProgramPipelineInfoLog", userptr); - glProgramUniformMatrix4x3dv = (PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC) load("glProgramUniformMatrix4x3dv", userptr); - glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC) load("glGetShaderPrecisionFormat", userptr); - glProgramUniform3d = (PFNGLPROGRAMUNIFORM3DPROC) load("glProgramUniform3d", userptr); - glProgramUniformMatrix4x2dv = (PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC) load("glProgramUniformMatrix4x2dv", userptr); - glProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC) load("glProgramUniform3f", userptr); - glProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC) load("glProgramUniform3iv", userptr); - glDepthRangef = (PFNGLDEPTHRANGEFPROC) load("glDepthRangef", userptr); - glProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC) load("glProgramUniform4iv", userptr); - glScissorIndexedv = (PFNGLSCISSORINDEXEDVPROC) load("glScissorIndexedv", userptr); - glProgramUniformMatrix2x4dv = (PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC) load("glProgramUniformMatrix2x4dv", userptr); - glGetVertexAttribLdv = (PFNGLGETVERTEXATTRIBLDVPROC) load("glGetVertexAttribLdv", userptr); - glProgramUniform2dv = (PFNGLPROGRAMUNIFORM2DVPROC) load("glProgramUniform2dv", userptr); - glProgramUniform4dv = (PFNGLPROGRAMUNIFORM4DVPROC) load("glProgramUniform4dv", userptr); - glProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC) load("glProgramUniform1fv", userptr); - glProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC) load("glProgramUniform3ui", userptr); - glProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC) load("glProgramUniform4ui", userptr); - glProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC) load("glProgramUniformMatrix4fv", userptr); - glVertexAttribL1d = (PFNGLVERTEXATTRIBL1DPROC) load("glVertexAttribL1d", userptr); - glProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC) load("glProgramUniformMatrix3x2fv", userptr); - glProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC) load("glProgramUniformMatrix2x4fv", userptr); - glProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC) load("glProgramUniform1i", userptr); - glValidateProgramPipeline = (PFNGLVALIDATEPROGRAMPIPELINEPROC) load("glValidateProgramPipeline", userptr); - glBindProgramPipeline = (PFNGLBINDPROGRAMPIPELINEPROC) load("glBindProgramPipeline", userptr); - glProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC) load("glProgramUniform1uiv", userptr); - glProgramUniform2d = (PFNGLPROGRAMUNIFORM2DPROC) load("glProgramUniform2d", userptr); - glProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC) load("glProgramUniformMatrix3fv", userptr); - glProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC) load("glProgramUniformMatrix4x2fv", userptr); - glProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC) load("glProgramUniform1f", userptr); - glGenProgramPipelines = (PFNGLGENPROGRAMPIPELINESPROC) load("glGenProgramPipelines", userptr); - glProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC) load("glProgramUniform1ui", userptr); - glProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC) load("glProgramUniformMatrix4x3fv", userptr); - glVertexAttribL3d = (PFNGLVERTEXATTRIBL3DPROC) load("glVertexAttribL3d", userptr); +static void load_GL_VERSION_4_1(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_GL_VERSION_4_1) return; + glGetDoublei_v = (PFNGLGETDOUBLEI_VPROC)load("glGetDoublei_v", userptr); + glProgramUniform4d = (PFNGLPROGRAMUNIFORM4DPROC)load("glProgramUniform4d", userptr); + glGetFloati_v = (PFNGLGETFLOATI_VPROC)load("glGetFloati_v", userptr); + glIsProgramPipeline = (PFNGLISPROGRAMPIPELINEPROC)load("glIsProgramPipeline", userptr); + glGetProgramBinary = (PFNGLGETPROGRAMBINARYPROC)load("glGetProgramBinary", userptr); + glDepthRangeArrayv = (PFNGLDEPTHRANGEARRAYVPROC)load("glDepthRangeArrayv", userptr); + glProgramUniform1iv = (PFNGLPROGRAMUNIFORM1IVPROC)load("glProgramUniform1iv", userptr); + glProgramUniformMatrix3x2dv = (PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC)load("glProgramUniformMatrix3x2dv", userptr); + glProgramParameteri = (PFNGLPROGRAMPARAMETERIPROC)load("glProgramParameteri", userptr); + glVertexAttribLPointer = (PFNGLVERTEXATTRIBLPOINTERPROC)load("glVertexAttribLPointer", userptr); + glProgramUniformMatrix2x3fv = (PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC)load("glProgramUniformMatrix2x3fv", userptr); + glProgramUniform3fv = (PFNGLPROGRAMUNIFORM3FVPROC)load("glProgramUniform3fv", userptr); + glProgramUniform4i = (PFNGLPROGRAMUNIFORM4IPROC)load("glProgramUniform4i", userptr); + glProgramUniform2iv = (PFNGLPROGRAMUNIFORM2IVPROC)load("glProgramUniform2iv", userptr); + glProgramUniform1dv = (PFNGLPROGRAMUNIFORM1DVPROC)load("glProgramUniform1dv", userptr); + glDepthRangeIndexed = (PFNGLDEPTHRANGEINDEXEDPROC)load("glDepthRangeIndexed", userptr); + glDeleteProgramPipelines = (PFNGLDELETEPROGRAMPIPELINESPROC)load("glDeleteProgramPipelines", userptr); + glProgramUniform4fv = (PFNGLPROGRAMUNIFORM4FVPROC)load("glProgramUniform4fv", userptr); + glVertexAttribL3dv = (PFNGLVERTEXATTRIBL3DVPROC)load("glVertexAttribL3dv", userptr); + glViewportArrayv = (PFNGLVIEWPORTARRAYVPROC)load("glViewportArrayv", userptr); + glVertexAttribL4d = (PFNGLVERTEXATTRIBL4DPROC)load("glVertexAttribL4d", userptr); + glVertexAttribL1dv = (PFNGLVERTEXATTRIBL1DVPROC)load("glVertexAttribL1dv", userptr); + glProgramUniform3i = (PFNGLPROGRAMUNIFORM3IPROC)load("glProgramUniform3i", userptr); + glCreateShaderProgramv = (PFNGLCREATESHADERPROGRAMVPROC)load("glCreateShaderProgramv", userptr); + glProgramUniform3uiv = (PFNGLPROGRAMUNIFORM3UIVPROC)load("glProgramUniform3uiv", userptr); + glViewportIndexedf = (PFNGLVIEWPORTINDEXEDFPROC)load("glViewportIndexedf", userptr); + glActiveShaderProgram = (PFNGLACTIVESHADERPROGRAMPROC)load("glActiveShaderProgram", userptr); + glViewportIndexedfv = (PFNGLVIEWPORTINDEXEDFVPROC)load("glViewportIndexedfv", userptr); + glProgramUniform4uiv = (PFNGLPROGRAMUNIFORM4UIVPROC)load("glProgramUniform4uiv", userptr); + glProgramUniform1d = (PFNGLPROGRAMUNIFORM1DPROC)load("glProgramUniform1d", userptr); + glProgramUniform2fv = (PFNGLPROGRAMUNIFORM2FVPROC)load("glProgramUniform2fv", userptr); + glScissorIndexed = (PFNGLSCISSORINDEXEDPROC)load("glScissorIndexed", userptr); + glProgramBinary = (PFNGLPROGRAMBINARYPROC)load("glProgramBinary", userptr); + glUseProgramStages = (PFNGLUSEPROGRAMSTAGESPROC)load("glUseProgramStages", userptr); + glVertexAttribL2d = (PFNGLVERTEXATTRIBL2DPROC)load("glVertexAttribL2d", userptr); + glReleaseShaderCompiler = (PFNGLRELEASESHADERCOMPILERPROC)load("glReleaseShaderCompiler", userptr); + glProgramUniform3dv = (PFNGLPROGRAMUNIFORM3DVPROC)load("glProgramUniform3dv", userptr); + glProgramUniformMatrix3dv = (PFNGLPROGRAMUNIFORMMATRIX3DVPROC)load("glProgramUniformMatrix3dv", userptr); + glScissorArrayv = (PFNGLSCISSORARRAYVPROC)load("glScissorArrayv", userptr); + glProgramUniformMatrix3x4dv = (PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC)load("glProgramUniformMatrix3x4dv", userptr); + glVertexAttribL4dv = (PFNGLVERTEXATTRIBL4DVPROC)load("glVertexAttribL4dv", userptr); + glProgramUniform2f = (PFNGLPROGRAMUNIFORM2FPROC)load("glProgramUniform2f", userptr); + glProgramUniform2i = (PFNGLPROGRAMUNIFORM2IPROC)load("glProgramUniform2i", userptr); + glProgramUniformMatrix4dv = (PFNGLPROGRAMUNIFORMMATRIX4DVPROC)load("glProgramUniformMatrix4dv", userptr); + glProgramUniform2uiv = (PFNGLPROGRAMUNIFORM2UIVPROC)load("glProgramUniform2uiv", userptr); + glProgramUniformMatrix3x4fv = (PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC)load("glProgramUniformMatrix3x4fv", userptr); + glProgramUniform4f = (PFNGLPROGRAMUNIFORM4FPROC)load("glProgramUniform4f", userptr); + glClearDepthf = (PFNGLCLEARDEPTHFPROC)load("glClearDepthf", userptr); + glShaderBinary = (PFNGLSHADERBINARYPROC)load("glShaderBinary", userptr); + glProgramUniform2ui = (PFNGLPROGRAMUNIFORM2UIPROC)load("glProgramUniform2ui", userptr); + glGetProgramPipelineiv = (PFNGLGETPROGRAMPIPELINEIVPROC)load("glGetProgramPipelineiv", userptr); + glProgramUniformMatrix2x3dv = (PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC)load("glProgramUniformMatrix2x3dv", userptr); + glVertexAttribL2dv = (PFNGLVERTEXATTRIBL2DVPROC)load("glVertexAttribL2dv", userptr); + glProgramUniformMatrix2dv = (PFNGLPROGRAMUNIFORMMATRIX2DVPROC)load("glProgramUniformMatrix2dv", userptr); + glProgramUniformMatrix2fv = (PFNGLPROGRAMUNIFORMMATRIX2FVPROC)load("glProgramUniformMatrix2fv", userptr); + glGetProgramPipelineInfoLog = (PFNGLGETPROGRAMPIPELINEINFOLOGPROC)load("glGetProgramPipelineInfoLog", userptr); + glProgramUniformMatrix4x3dv = (PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC)load("glProgramUniformMatrix4x3dv", userptr); + glGetShaderPrecisionFormat = (PFNGLGETSHADERPRECISIONFORMATPROC)load("glGetShaderPrecisionFormat", userptr); + glProgramUniform3d = (PFNGLPROGRAMUNIFORM3DPROC)load("glProgramUniform3d", userptr); + glProgramUniformMatrix4x2dv = (PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC)load("glProgramUniformMatrix4x2dv", userptr); + glProgramUniform3f = (PFNGLPROGRAMUNIFORM3FPROC)load("glProgramUniform3f", userptr); + glProgramUniform3iv = (PFNGLPROGRAMUNIFORM3IVPROC)load("glProgramUniform3iv", userptr); + glDepthRangef = (PFNGLDEPTHRANGEFPROC)load("glDepthRangef", userptr); + glProgramUniform4iv = (PFNGLPROGRAMUNIFORM4IVPROC)load("glProgramUniform4iv", userptr); + glScissorIndexedv = (PFNGLSCISSORINDEXEDVPROC)load("glScissorIndexedv", userptr); + glProgramUniformMatrix2x4dv = (PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC)load("glProgramUniformMatrix2x4dv", userptr); + glGetVertexAttribLdv = (PFNGLGETVERTEXATTRIBLDVPROC)load("glGetVertexAttribLdv", userptr); + glProgramUniform2dv = (PFNGLPROGRAMUNIFORM2DVPROC)load("glProgramUniform2dv", userptr); + glProgramUniform4dv = (PFNGLPROGRAMUNIFORM4DVPROC)load("glProgramUniform4dv", userptr); + glProgramUniform1fv = (PFNGLPROGRAMUNIFORM1FVPROC)load("glProgramUniform1fv", userptr); + glProgramUniform3ui = (PFNGLPROGRAMUNIFORM3UIPROC)load("glProgramUniform3ui", userptr); + glProgramUniform4ui = (PFNGLPROGRAMUNIFORM4UIPROC)load("glProgramUniform4ui", userptr); + glProgramUniformMatrix4fv = (PFNGLPROGRAMUNIFORMMATRIX4FVPROC)load("glProgramUniformMatrix4fv", userptr); + glVertexAttribL1d = (PFNGLVERTEXATTRIBL1DPROC)load("glVertexAttribL1d", userptr); + glProgramUniformMatrix3x2fv = (PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC)load("glProgramUniformMatrix3x2fv", userptr); + glProgramUniformMatrix2x4fv = (PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC)load("glProgramUniformMatrix2x4fv", userptr); + glProgramUniform1i = (PFNGLPROGRAMUNIFORM1IPROC)load("glProgramUniform1i", userptr); + glValidateProgramPipeline = (PFNGLVALIDATEPROGRAMPIPELINEPROC)load("glValidateProgramPipeline", userptr); + glBindProgramPipeline = (PFNGLBINDPROGRAMPIPELINEPROC)load("glBindProgramPipeline", userptr); + glProgramUniform1uiv = (PFNGLPROGRAMUNIFORM1UIVPROC)load("glProgramUniform1uiv", userptr); + glProgramUniform2d = (PFNGLPROGRAMUNIFORM2DPROC)load("glProgramUniform2d", userptr); + glProgramUniformMatrix3fv = (PFNGLPROGRAMUNIFORMMATRIX3FVPROC)load("glProgramUniformMatrix3fv", userptr); + glProgramUniformMatrix4x2fv = (PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC)load("glProgramUniformMatrix4x2fv", userptr); + glProgramUniform1f = (PFNGLPROGRAMUNIFORM1FPROC)load("glProgramUniform1f", userptr); + glGenProgramPipelines = (PFNGLGENPROGRAMPIPELINESPROC)load("glGenProgramPipelines", userptr); + glProgramUniform1ui = (PFNGLPROGRAMUNIFORM1UIPROC)load("glProgramUniform1ui", userptr); + glProgramUniformMatrix4x3fv = (PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC)load("glProgramUniformMatrix4x3fv", userptr); + glVertexAttribL3d = (PFNGLVERTEXATTRIBL3DPROC)load("glVertexAttribL3d", userptr); } -static void load_GL_VERSION_4_2( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_4_2) return; - glTexStorage2D = (PFNGLTEXSTORAGE2DPROC) load("glTexStorage2D", userptr); - glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC) load("glGetInternalformativ", userptr); - glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC) load("glBindImageTexture", userptr); - glDrawTransformFeedbackStreamInstanced = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC) load("glDrawTransformFeedbackStreamInstanced", userptr); - glDrawArraysInstancedBaseInstance = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC) load("glDrawArraysInstancedBaseInstance", userptr); - glTexStorage3D = (PFNGLTEXSTORAGE3DPROC) load("glTexStorage3D", userptr); - glDrawElementsInstancedBaseVertexBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC) load("glDrawElementsInstancedBaseVertexBaseInstance", userptr); - glDrawTransformFeedbackInstanced = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC) load("glDrawTransformFeedbackInstanced", userptr); - glMemoryBarrier = (PFNGLMEMORYBARRIERPROC) load("glMemoryBarrier", userptr); - glGetActiveAtomicCounterBufferiv = (PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC) load("glGetActiveAtomicCounterBufferiv", userptr); - glTexStorage1D = (PFNGLTEXSTORAGE1DPROC) load("glTexStorage1D", userptr); - glDrawElementsInstancedBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC) load("glDrawElementsInstancedBaseInstance", userptr); +static void load_GL_VERSION_4_2(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_GL_VERSION_4_2) return; + glTexStorage2D = (PFNGLTEXSTORAGE2DPROC)load("glTexStorage2D", userptr); + glGetInternalformativ = (PFNGLGETINTERNALFORMATIVPROC)load("glGetInternalformativ", userptr); + glBindImageTexture = (PFNGLBINDIMAGETEXTUREPROC)load("glBindImageTexture", userptr); + glDrawTransformFeedbackStreamInstanced = (PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC)load("glDrawTransformFeedbackStreamInstanced", userptr); + glDrawArraysInstancedBaseInstance = (PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)load("glDrawArraysInstancedBaseInstance", userptr); + glTexStorage3D = (PFNGLTEXSTORAGE3DPROC)load("glTexStorage3D", userptr); + glDrawElementsInstancedBaseVertexBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)load("glDrawElementsInstancedBaseVertexBaseInstance", userptr); + glDrawTransformFeedbackInstanced = (PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC)load("glDrawTransformFeedbackInstanced", userptr); + glMemoryBarrier = (PFNGLMEMORYBARRIERPROC)load("glMemoryBarrier", userptr); + glGetActiveAtomicCounterBufferiv = (PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC)load("glGetActiveAtomicCounterBufferiv", userptr); + glTexStorage1D = (PFNGLTEXSTORAGE1DPROC)load("glTexStorage1D", userptr); + glDrawElementsInstancedBaseInstance = (PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)load("glDrawElementsInstancedBaseInstance", userptr); } -static void load_GL_VERSION_4_3( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_4_3) return; - glDispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC) load("glDispatchComputeIndirect", userptr); - glVertexAttribLFormat = (PFNGLVERTEXATTRIBLFORMATPROC) load("glVertexAttribLFormat", userptr); - glClearBufferData = (PFNGLCLEARBUFFERDATAPROC) load("glClearBufferData", userptr); - glTextureView = (PFNGLTEXTUREVIEWPROC) load("glTextureView", userptr); - glGetPointerv = (PFNGLGETPOINTERVPROC) load("glGetPointerv", userptr); - glFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC) load("glFramebufferParameteri", userptr); - glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC) load("glDebugMessageCallback", userptr); - glInvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC) load("glInvalidateBufferData", userptr); - glGetInternalformati64v = (PFNGLGETINTERNALFORMATI64VPROC) load("glGetInternalformati64v", userptr); - glVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC) load("glVertexAttribBinding", userptr); - glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC) load("glDispatchCompute", userptr); - glVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC) load("glVertexBindingDivisor", userptr); - glMultiDrawArraysIndirect = (PFNGLMULTIDRAWARRAYSINDIRECTPROC) load("glMultiDrawArraysIndirect", userptr); - glGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC) load("glGetProgramResourceName", userptr); - glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC) load("glDebugMessageControl", userptr); - glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC) load("glGetProgramResourceiv", userptr); - glInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC) load("glInvalidateSubFramebuffer", userptr); - glVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC) load("glVertexAttribIFormat", userptr); - glInvalidateBufferSubData = (PFNGLINVALIDATEBUFFERSUBDATAPROC) load("glInvalidateBufferSubData", userptr); - glTexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC) load("glTexStorage2DMultisample", userptr); - glTexStorage3DMultisample = (PFNGLTEXSTORAGE3DMULTISAMPLEPROC) load("glTexStorage3DMultisample", userptr); - glInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC) load("glInvalidateFramebuffer", userptr); - glGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC) load("glGetProgramInterfaceiv", userptr); - glShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC) load("glShaderStorageBlockBinding", userptr); - glClearBufferSubData = (PFNGLCLEARBUFFERSUBDATAPROC) load("glClearBufferSubData", userptr); - glGetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC) load("glGetProgramResourceIndex", userptr); - glInvalidateTexImage = (PFNGLINVALIDATETEXIMAGEPROC) load("glInvalidateTexImage", userptr); - glGetFramebufferParameteriv = (PFNGLGETFRAMEBUFFERPARAMETERIVPROC) load("glGetFramebufferParameteriv", userptr); - glGetProgramResourceLocationIndex = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC) load("glGetProgramResourceLocationIndex", userptr); - glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC) load("glObjectPtrLabel", userptr); - glTexBufferRange = (PFNGLTEXBUFFERRANGEPROC) load("glTexBufferRange", userptr); - glGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC) load("glGetProgramResourceLocation", userptr); - glMultiDrawElementsIndirect = (PFNGLMULTIDRAWELEMENTSINDIRECTPROC) load("glMultiDrawElementsIndirect", userptr); - glInvalidateTexSubImage = (PFNGLINVALIDATETEXSUBIMAGEPROC) load("glInvalidateTexSubImage", userptr); - glBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC) load("glBindVertexBuffer", userptr); - glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC) load("glDebugMessageInsert", userptr); - glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC) load("glGetDebugMessageLog", userptr); - glObjectLabel = (PFNGLOBJECTLABELPROC) load("glObjectLabel", userptr); - glGetObjectLabel = (PFNGLGETOBJECTLABELPROC) load("glGetObjectLabel", userptr); - glCopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC) load("glCopyImageSubData", userptr); - glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC) load("glPushDebugGroup", userptr); - glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC) load("glPopDebugGroup", userptr); - glVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC) load("glVertexAttribFormat", userptr); - glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC) load("glGetObjectPtrLabel", userptr); +static void load_GL_VERSION_4_3(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_GL_VERSION_4_3) return; + glDispatchComputeIndirect = (PFNGLDISPATCHCOMPUTEINDIRECTPROC)load("glDispatchComputeIndirect", userptr); + glVertexAttribLFormat = (PFNGLVERTEXATTRIBLFORMATPROC)load("glVertexAttribLFormat", userptr); + glClearBufferData = (PFNGLCLEARBUFFERDATAPROC)load("glClearBufferData", userptr); + glTextureView = (PFNGLTEXTUREVIEWPROC)load("glTextureView", userptr); + glGetPointerv = (PFNGLGETPOINTERVPROC)load("glGetPointerv", userptr); + glFramebufferParameteri = (PFNGLFRAMEBUFFERPARAMETERIPROC)load("glFramebufferParameteri", userptr); + glDebugMessageCallback = (PFNGLDEBUGMESSAGECALLBACKPROC)load("glDebugMessageCallback", userptr); + glInvalidateBufferData = (PFNGLINVALIDATEBUFFERDATAPROC)load("glInvalidateBufferData", userptr); + glGetInternalformati64v = (PFNGLGETINTERNALFORMATI64VPROC)load("glGetInternalformati64v", userptr); + glVertexAttribBinding = (PFNGLVERTEXATTRIBBINDINGPROC)load("glVertexAttribBinding", userptr); + glDispatchCompute = (PFNGLDISPATCHCOMPUTEPROC)load("glDispatchCompute", userptr); + glVertexBindingDivisor = (PFNGLVERTEXBINDINGDIVISORPROC)load("glVertexBindingDivisor", userptr); + glMultiDrawArraysIndirect = (PFNGLMULTIDRAWARRAYSINDIRECTPROC)load("glMultiDrawArraysIndirect", userptr); + glGetProgramResourceName = (PFNGLGETPROGRAMRESOURCENAMEPROC)load("glGetProgramResourceName", userptr); + glDebugMessageControl = (PFNGLDEBUGMESSAGECONTROLPROC)load("glDebugMessageControl", userptr); + glGetProgramResourceiv = (PFNGLGETPROGRAMRESOURCEIVPROC)load("glGetProgramResourceiv", userptr); + glInvalidateSubFramebuffer = (PFNGLINVALIDATESUBFRAMEBUFFERPROC)load("glInvalidateSubFramebuffer", userptr); + glVertexAttribIFormat = (PFNGLVERTEXATTRIBIFORMATPROC)load("glVertexAttribIFormat", userptr); + glInvalidateBufferSubData = (PFNGLINVALIDATEBUFFERSUBDATAPROC)load("glInvalidateBufferSubData", userptr); + glTexStorage2DMultisample = (PFNGLTEXSTORAGE2DMULTISAMPLEPROC)load("glTexStorage2DMultisample", userptr); + glTexStorage3DMultisample = (PFNGLTEXSTORAGE3DMULTISAMPLEPROC)load("glTexStorage3DMultisample", userptr); + glInvalidateFramebuffer = (PFNGLINVALIDATEFRAMEBUFFERPROC)load("glInvalidateFramebuffer", userptr); + glGetProgramInterfaceiv = (PFNGLGETPROGRAMINTERFACEIVPROC)load("glGetProgramInterfaceiv", userptr); + glShaderStorageBlockBinding = (PFNGLSHADERSTORAGEBLOCKBINDINGPROC)load("glShaderStorageBlockBinding", userptr); + glClearBufferSubData = (PFNGLCLEARBUFFERSUBDATAPROC)load("glClearBufferSubData", userptr); + glGetProgramResourceIndex = (PFNGLGETPROGRAMRESOURCEINDEXPROC)load("glGetProgramResourceIndex", userptr); + glInvalidateTexImage = (PFNGLINVALIDATETEXIMAGEPROC)load("glInvalidateTexImage", userptr); + glGetFramebufferParameteriv = (PFNGLGETFRAMEBUFFERPARAMETERIVPROC)load("glGetFramebufferParameteriv", userptr); + glGetProgramResourceLocationIndex = (PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC)load("glGetProgramResourceLocationIndex", userptr); + glObjectPtrLabel = (PFNGLOBJECTPTRLABELPROC)load("glObjectPtrLabel", userptr); + glTexBufferRange = (PFNGLTEXBUFFERRANGEPROC)load("glTexBufferRange", userptr); + glGetProgramResourceLocation = (PFNGLGETPROGRAMRESOURCELOCATIONPROC)load("glGetProgramResourceLocation", userptr); + glMultiDrawElementsIndirect = (PFNGLMULTIDRAWELEMENTSINDIRECTPROC)load("glMultiDrawElementsIndirect", userptr); + glInvalidateTexSubImage = (PFNGLINVALIDATETEXSUBIMAGEPROC)load("glInvalidateTexSubImage", userptr); + glBindVertexBuffer = (PFNGLBINDVERTEXBUFFERPROC)load("glBindVertexBuffer", userptr); + glDebugMessageInsert = (PFNGLDEBUGMESSAGEINSERTPROC)load("glDebugMessageInsert", userptr); + glGetDebugMessageLog = (PFNGLGETDEBUGMESSAGELOGPROC)load("glGetDebugMessageLog", userptr); + glObjectLabel = (PFNGLOBJECTLABELPROC)load("glObjectLabel", userptr); + glGetObjectLabel = (PFNGLGETOBJECTLABELPROC)load("glGetObjectLabel", userptr); + glCopyImageSubData = (PFNGLCOPYIMAGESUBDATAPROC)load("glCopyImageSubData", userptr); + glPushDebugGroup = (PFNGLPUSHDEBUGGROUPPROC)load("glPushDebugGroup", userptr); + glPopDebugGroup = (PFNGLPOPDEBUGGROUPPROC)load("glPopDebugGroup", userptr); + glVertexAttribFormat = (PFNGLVERTEXATTRIBFORMATPROC)load("glVertexAttribFormat", userptr); + glGetObjectPtrLabel = (PFNGLGETOBJECTPTRLABELPROC)load("glGetObjectPtrLabel", userptr); } -static void load_GL_VERSION_4_4( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_4_4) return; - glBindSamplers = (PFNGLBINDSAMPLERSPROC) load("glBindSamplers", userptr); - glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC) load("glBindImageTextures", userptr); - glBufferStorage = (PFNGLBUFFERSTORAGEPROC) load("glBufferStorage", userptr); - glBindVertexBuffers = (PFNGLBINDVERTEXBUFFERSPROC) load("glBindVertexBuffers", userptr); - glBindBuffersBase = (PFNGLBINDBUFFERSBASEPROC) load("glBindBuffersBase", userptr); - glClearTexSubImage = (PFNGLCLEARTEXSUBIMAGEPROC) load("glClearTexSubImage", userptr); - glClearTexImage = (PFNGLCLEARTEXIMAGEPROC) load("glClearTexImage", userptr); - glBindBuffersRange = (PFNGLBINDBUFFERSRANGEPROC) load("glBindBuffersRange", userptr); - glBindTextures = (PFNGLBINDTEXTURESPROC) load("glBindTextures", userptr); +static void load_GL_VERSION_4_4(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_GL_VERSION_4_4) return; + glBindSamplers = (PFNGLBINDSAMPLERSPROC)load("glBindSamplers", userptr); + glBindImageTextures = (PFNGLBINDIMAGETEXTURESPROC)load("glBindImageTextures", userptr); + glBufferStorage = (PFNGLBUFFERSTORAGEPROC)load("glBufferStorage", userptr); + glBindVertexBuffers = (PFNGLBINDVERTEXBUFFERSPROC)load("glBindVertexBuffers", userptr); + glBindBuffersBase = (PFNGLBINDBUFFERSBASEPROC)load("glBindBuffersBase", userptr); + glClearTexSubImage = (PFNGLCLEARTEXSUBIMAGEPROC)load("glClearTexSubImage", userptr); + glClearTexImage = (PFNGLCLEARTEXIMAGEPROC)load("glClearTexImage", userptr); + glBindBuffersRange = (PFNGLBINDBUFFERSRANGEPROC)load("glBindBuffersRange", userptr); + glBindTextures = (PFNGLBINDTEXTURESPROC)load("glBindTextures", userptr); } -static void load_GL_VERSION_4_5( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_4_5) return; - glGetTextureParameterIiv = (PFNGLGETTEXTUREPARAMETERIIVPROC) load("glGetTextureParameterIiv", userptr); - glTextureStorage3DMultisample = (PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC) load("glTextureStorage3DMultisample", userptr); - glTextureSubImage3D = (PFNGLTEXTURESUBIMAGE3DPROC) load("glTextureSubImage3D", userptr); - glVertexArrayAttribBinding = (PFNGLVERTEXARRAYATTRIBBINDINGPROC) load("glVertexArrayAttribBinding", userptr); - glGetnCompressedTexImage = (PFNGLGETNCOMPRESSEDTEXIMAGEPROC) load("glGetnCompressedTexImage", userptr); - glTextureStorage2DMultisample = (PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC) load("glTextureStorage2DMultisample", userptr); - glFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC) load("glFlushMappedNamedBufferRange", userptr); - glGetNamedFramebufferParameteriv = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC) load("glGetNamedFramebufferParameteriv", userptr); - glTextureBufferRange = (PFNGLTEXTUREBUFFERRANGEPROC) load("glTextureBufferRange", userptr); - glGetnMapdv = (PFNGLGETNMAPDVPROC) load("glGetnMapdv", userptr); - glCopyTextureSubImage1D = (PFNGLCOPYTEXTURESUBIMAGE1DPROC) load("glCopyTextureSubImage1D", userptr); - glGetnUniformuiv = (PFNGLGETNUNIFORMUIVPROC) load("glGetnUniformuiv", userptr); - glTextureParameteri = (PFNGLTEXTUREPARAMETERIPROC) load("glTextureParameteri", userptr); - glCheckNamedFramebufferStatus = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC) load("glCheckNamedFramebufferStatus", userptr); - glGetnColorTable = (PFNGLGETNCOLORTABLEPROC) load("glGetnColorTable", userptr); - glClearNamedBufferData = (PFNGLCLEARNAMEDBUFFERDATAPROC) load("glClearNamedBufferData", userptr); - glInvalidateNamedFramebufferSubData = (PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC) load("glInvalidateNamedFramebufferSubData", userptr); - glGetnPixelMapfv = (PFNGLGETNPIXELMAPFVPROC) load("glGetnPixelMapfv", userptr); - glGetGraphicsResetStatus = (PFNGLGETGRAPHICSRESETSTATUSPROC) load("glGetGraphicsResetStatus", userptr); - glTransformFeedbackBufferBase = (PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC) load("glTransformFeedbackBufferBase", userptr); - glNamedBufferSubData = (PFNGLNAMEDBUFFERSUBDATAPROC) load("glNamedBufferSubData", userptr); - glClearNamedFramebufferuiv = (PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC) load("glClearNamedFramebufferuiv", userptr); - glVertexArrayAttribLFormat = (PFNGLVERTEXARRAYATTRIBLFORMATPROC) load("glVertexArrayAttribLFormat", userptr); - glGetTextureLevelParameterfv = (PFNGLGETTEXTURELEVELPARAMETERFVPROC) load("glGetTextureLevelParameterfv", userptr); - glBlitNamedFramebuffer = (PFNGLBLITNAMEDFRAMEBUFFERPROC) load("glBlitNamedFramebuffer", userptr); - glClearNamedFramebufferfi = (PFNGLCLEARNAMEDFRAMEBUFFERFIPROC) load("glClearNamedFramebufferfi", userptr); - glNamedFramebufferReadBuffer = (PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC) load("glNamedFramebufferReadBuffer", userptr); - glGetCompressedTextureImage = (PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC) load("glGetCompressedTextureImage", userptr); - glGetTextureSubImage = (PFNGLGETTEXTURESUBIMAGEPROC) load("glGetTextureSubImage", userptr); - glTextureSubImage2D = (PFNGLTEXTURESUBIMAGE2DPROC) load("glTextureSubImage2D", userptr); - glNamedRenderbufferStorage = (PFNGLNAMEDRENDERBUFFERSTORAGEPROC) load("glNamedRenderbufferStorage", userptr); - glNamedFramebufferRenderbuffer = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC) load("glNamedFramebufferRenderbuffer", userptr); - glNamedBufferData = (PFNGLNAMEDBUFFERDATAPROC) load("glNamedBufferData", userptr); - glGetNamedBufferSubData = (PFNGLGETNAMEDBUFFERSUBDATAPROC) load("glGetNamedBufferSubData", userptr); - glGetNamedBufferPointerv = (PFNGLGETNAMEDBUFFERPOINTERVPROC) load("glGetNamedBufferPointerv", userptr); - glTextureStorage2D = (PFNGLTEXTURESTORAGE2DPROC) load("glTextureStorage2D", userptr); - glGetTextureParameteriv = (PFNGLGETTEXTUREPARAMETERIVPROC) load("glGetTextureParameteriv", userptr); - glVertexArrayVertexBuffer = (PFNGLVERTEXARRAYVERTEXBUFFERPROC) load("glVertexArrayVertexBuffer", userptr); - glGetQueryBufferObjectui64v = (PFNGLGETQUERYBUFFEROBJECTUI64VPROC) load("glGetQueryBufferObjectui64v", userptr); - glGetnPolygonStipple = (PFNGLGETNPOLYGONSTIPPLEPROC) load("glGetnPolygonStipple", userptr); - glVertexArrayBindingDivisor = (PFNGLVERTEXARRAYBINDINGDIVISORPROC) load("glVertexArrayBindingDivisor", userptr); - glGetnHistogram = (PFNGLGETNHISTOGRAMPROC) load("glGetnHistogram", userptr); - glEnableVertexArrayAttrib = (PFNGLENABLEVERTEXARRAYATTRIBPROC) load("glEnableVertexArrayAttrib", userptr); - glGetVertexArrayIndexed64iv = (PFNGLGETVERTEXARRAYINDEXED64IVPROC) load("glGetVertexArrayIndexed64iv", userptr); - glGetnUniformdv = (PFNGLGETNUNIFORMDVPROC) load("glGetnUniformdv", userptr); - glCreateSamplers = (PFNGLCREATESAMPLERSPROC) load("glCreateSamplers", userptr); - glNamedFramebufferParameteri = (PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC) load("glNamedFramebufferParameteri", userptr); - glNamedBufferStorage = (PFNGLNAMEDBUFFERSTORAGEPROC) load("glNamedBufferStorage", userptr); - glNamedFramebufferTexture = (PFNGLNAMEDFRAMEBUFFERTEXTUREPROC) load("glNamedFramebufferTexture", userptr); - glGetnSeparableFilter = (PFNGLGETNSEPARABLEFILTERPROC) load("glGetnSeparableFilter", userptr); - glCreateQueries = (PFNGLCREATEQUERIESPROC) load("glCreateQueries", userptr); - glTransformFeedbackBufferRange = (PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC) load("glTransformFeedbackBufferRange", userptr); - glGetVertexArrayiv = (PFNGLGETVERTEXARRAYIVPROC) load("glGetVertexArrayiv", userptr); - glGetnMapfv = (PFNGLGETNMAPFVPROC) load("glGetnMapfv", userptr); - glGetNamedRenderbufferParameteriv = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC) load("glGetNamedRenderbufferParameteriv", userptr); - glGetnPixelMapuiv = (PFNGLGETNPIXELMAPUIVPROC) load("glGetnPixelMapuiv", userptr); - glGetQueryBufferObjectiv = (PFNGLGETQUERYBUFFEROBJECTIVPROC) load("glGetQueryBufferObjectiv", userptr); - glGetnConvolutionFilter = (PFNGLGETNCONVOLUTIONFILTERPROC) load("glGetnConvolutionFilter", userptr); - glCreateRenderbuffers = (PFNGLCREATERENDERBUFFERSPROC) load("glCreateRenderbuffers", userptr); - glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC) load("glGenerateTextureMipmap", userptr); - glTextureStorage1D = (PFNGLTEXTURESTORAGE1DPROC) load("glTextureStorage1D", userptr); - glCreateProgramPipelines = (PFNGLCREATEPROGRAMPIPELINESPROC) load("glCreateProgramPipelines", userptr); - glGetNamedFramebufferAttachmentParameteriv = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC) load("glGetNamedFramebufferAttachmentParameteriv", userptr); - glBindTextureUnit = (PFNGLBINDTEXTUREUNITPROC) load("glBindTextureUnit", userptr); - glGetTransformFeedbacki64_v = (PFNGLGETTRANSFORMFEEDBACKI64_VPROC) load("glGetTransformFeedbacki64_v", userptr); - glNamedFramebufferDrawBuffer = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC) load("glNamedFramebufferDrawBuffer", userptr); - glInvalidateNamedFramebufferData = (PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC) load("glInvalidateNamedFramebufferData", userptr); - glReadnPixels = (PFNGLREADNPIXELSPROC) load("glReadnPixels", userptr); - glTextureParameterfv = (PFNGLTEXTUREPARAMETERFVPROC) load("glTextureParameterfv", userptr); - glGetVertexArrayIndexediv = (PFNGLGETVERTEXARRAYINDEXEDIVPROC) load("glGetVertexArrayIndexediv", userptr); - glMapNamedBuffer = (PFNGLMAPNAMEDBUFFERPROC) load("glMapNamedBuffer", userptr); - glGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64VPROC) load("glGetNamedBufferParameteri64v", userptr); - glVertexArrayElementBuffer = (PFNGLVERTEXARRAYELEMENTBUFFERPROC) load("glVertexArrayElementBuffer", userptr); - glClipControl = (PFNGLCLIPCONTROLPROC) load("glClipControl", userptr); - glClearNamedFramebufferfv = (PFNGLCLEARNAMEDFRAMEBUFFERFVPROC) load("glClearNamedFramebufferfv", userptr); - glGetTransformFeedbackiv = (PFNGLGETTRANSFORMFEEDBACKIVPROC) load("glGetTransformFeedbackiv", userptr); - glGetnMinmax = (PFNGLGETNMINMAXPROC) load("glGetnMinmax", userptr); - glNamedRenderbufferStorageMultisample = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC) load("glNamedRenderbufferStorageMultisample", userptr); - glNamedFramebufferDrawBuffers = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC) load("glNamedFramebufferDrawBuffers", userptr); - glGetNamedBufferParameteriv = (PFNGLGETNAMEDBUFFERPARAMETERIVPROC) load("glGetNamedBufferParameteriv", userptr); - glNamedFramebufferTextureLayer = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC) load("glNamedFramebufferTextureLayer", userptr); - glClearNamedFramebufferiv = (PFNGLCLEARNAMEDFRAMEBUFFERIVPROC) load("glClearNamedFramebufferiv", userptr); - glCompressedTextureSubImage3D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC) load("glCompressedTextureSubImage3D", userptr); - glDisableVertexArrayAttrib = (PFNGLDISABLEVERTEXARRAYATTRIBPROC) load("glDisableVertexArrayAttrib", userptr); - glGetQueryBufferObjectuiv = (PFNGLGETQUERYBUFFEROBJECTUIVPROC) load("glGetQueryBufferObjectuiv", userptr); - glTextureParameterIuiv = (PFNGLTEXTUREPARAMETERIUIVPROC) load("glTextureParameterIuiv", userptr); - glGetTextureParameterIuiv = (PFNGLGETTEXTUREPARAMETERIUIVPROC) load("glGetTextureParameterIuiv", userptr); - glTextureBuffer = (PFNGLTEXTUREBUFFERPROC) load("glTextureBuffer", userptr); - glMemoryBarrierByRegion = (PFNGLMEMORYBARRIERBYREGIONPROC) load("glMemoryBarrierByRegion", userptr); - glTextureParameterf = (PFNGLTEXTUREPARAMETERFPROC) load("glTextureParameterf", userptr); - glCopyNamedBufferSubData = (PFNGLCOPYNAMEDBUFFERSUBDATAPROC) load("glCopyNamedBufferSubData", userptr); - glVertexArrayAttribFormat = (PFNGLVERTEXARRAYATTRIBFORMATPROC) load("glVertexArrayAttribFormat", userptr); - glMapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGEPROC) load("glMapNamedBufferRange", userptr); - glTextureSubImage1D = (PFNGLTEXTURESUBIMAGE1DPROC) load("glTextureSubImage1D", userptr); - glGetTextureParameterfv = (PFNGLGETTEXTUREPARAMETERFVPROC) load("glGetTextureParameterfv", userptr); - glTextureParameteriv = (PFNGLTEXTUREPARAMETERIVPROC) load("glTextureParameteriv", userptr); - glCreateFramebuffers = (PFNGLCREATEFRAMEBUFFERSPROC) load("glCreateFramebuffers", userptr); - glTextureParameterIiv = (PFNGLTEXTUREPARAMETERIIVPROC) load("glTextureParameterIiv", userptr); - glGetnTexImage = (PFNGLGETNTEXIMAGEPROC) load("glGetnTexImage", userptr); - glTextureBarrier = (PFNGLTEXTUREBARRIERPROC) load("glTextureBarrier", userptr); - glCreateTextures = (PFNGLCREATETEXTURESPROC) load("glCreateTextures", userptr); - glCompressedTextureSubImage1D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC) load("glCompressedTextureSubImage1D", userptr); - glCopyTextureSubImage3D = (PFNGLCOPYTEXTURESUBIMAGE3DPROC) load("glCopyTextureSubImage3D", userptr); - glCreateVertexArrays = (PFNGLCREATEVERTEXARRAYSPROC) load("glCreateVertexArrays", userptr); - glCompressedTextureSubImage2D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC) load("glCompressedTextureSubImage2D", userptr); - glCreateBuffers = (PFNGLCREATEBUFFERSPROC) load("glCreateBuffers", userptr); - glCreateTransformFeedbacks = (PFNGLCREATETRANSFORMFEEDBACKSPROC) load("glCreateTransformFeedbacks", userptr); - glGetnMapiv = (PFNGLGETNMAPIVPROC) load("glGetnMapiv", userptr); - glClearNamedBufferSubData = (PFNGLCLEARNAMEDBUFFERSUBDATAPROC) load("glClearNamedBufferSubData", userptr); - glGetTextureImage = (PFNGLGETTEXTUREIMAGEPROC) load("glGetTextureImage", userptr); - glGetTextureLevelParameteriv = (PFNGLGETTEXTURELEVELPARAMETERIVPROC) load("glGetTextureLevelParameteriv", userptr); - glGetnUniformiv = (PFNGLGETNUNIFORMIVPROC) load("glGetnUniformiv", userptr); - glGetCompressedTextureSubImage = (PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC) load("glGetCompressedTextureSubImage", userptr); - glVertexArrayVertexBuffers = (PFNGLVERTEXARRAYVERTEXBUFFERSPROC) load("glVertexArrayVertexBuffers", userptr); - glCopyTextureSubImage2D = (PFNGLCOPYTEXTURESUBIMAGE2DPROC) load("glCopyTextureSubImage2D", userptr); - glGetTransformFeedbacki_v = (PFNGLGETTRANSFORMFEEDBACKI_VPROC) load("glGetTransformFeedbacki_v", userptr); - glUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFERPROC) load("glUnmapNamedBuffer", userptr); - glVertexArrayAttribIFormat = (PFNGLVERTEXARRAYATTRIBIFORMATPROC) load("glVertexArrayAttribIFormat", userptr); - glGetnPixelMapusv = (PFNGLGETNPIXELMAPUSVPROC) load("glGetnPixelMapusv", userptr); - glGetnUniformfv = (PFNGLGETNUNIFORMFVPROC) load("glGetnUniformfv", userptr); - glTextureStorage3D = (PFNGLTEXTURESTORAGE3DPROC) load("glTextureStorage3D", userptr); - glGetQueryBufferObjecti64v = (PFNGLGETQUERYBUFFEROBJECTI64VPROC) load("glGetQueryBufferObjecti64v", userptr); +static void load_GL_VERSION_4_5(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_GL_VERSION_4_5) return; + glGetTextureParameterIiv = (PFNGLGETTEXTUREPARAMETERIIVPROC)load("glGetTextureParameterIiv", userptr); + glTextureStorage3DMultisample = (PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC)load("glTextureStorage3DMultisample", userptr); + glTextureSubImage3D = (PFNGLTEXTURESUBIMAGE3DPROC)load("glTextureSubImage3D", userptr); + glVertexArrayAttribBinding = (PFNGLVERTEXARRAYATTRIBBINDINGPROC)load("glVertexArrayAttribBinding", userptr); + glGetnCompressedTexImage = (PFNGLGETNCOMPRESSEDTEXIMAGEPROC)load("glGetnCompressedTexImage", userptr); + glTextureStorage2DMultisample = (PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC)load("glTextureStorage2DMultisample", userptr); + glFlushMappedNamedBufferRange = (PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC)load("glFlushMappedNamedBufferRange", userptr); + glGetNamedFramebufferParameteriv = (PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC)load("glGetNamedFramebufferParameteriv", userptr); + glTextureBufferRange = (PFNGLTEXTUREBUFFERRANGEPROC)load("glTextureBufferRange", userptr); + glGetnMapdv = (PFNGLGETNMAPDVPROC)load("glGetnMapdv", userptr); + glCopyTextureSubImage1D = (PFNGLCOPYTEXTURESUBIMAGE1DPROC)load("glCopyTextureSubImage1D", userptr); + glGetnUniformuiv = (PFNGLGETNUNIFORMUIVPROC)load("glGetnUniformuiv", userptr); + glTextureParameteri = (PFNGLTEXTUREPARAMETERIPROC)load("glTextureParameteri", userptr); + glCheckNamedFramebufferStatus = (PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC)load("glCheckNamedFramebufferStatus", userptr); + glGetnColorTable = (PFNGLGETNCOLORTABLEPROC)load("glGetnColorTable", userptr); + glClearNamedBufferData = (PFNGLCLEARNAMEDBUFFERDATAPROC)load("glClearNamedBufferData", userptr); + glInvalidateNamedFramebufferSubData = (PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC)load("glInvalidateNamedFramebufferSubData", userptr); + glGetnPixelMapfv = (PFNGLGETNPIXELMAPFVPROC)load("glGetnPixelMapfv", userptr); + glGetGraphicsResetStatus = (PFNGLGETGRAPHICSRESETSTATUSPROC)load("glGetGraphicsResetStatus", userptr); + glTransformFeedbackBufferBase = (PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC)load("glTransformFeedbackBufferBase", userptr); + glNamedBufferSubData = (PFNGLNAMEDBUFFERSUBDATAPROC)load("glNamedBufferSubData", userptr); + glClearNamedFramebufferuiv = (PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC)load("glClearNamedFramebufferuiv", userptr); + glVertexArrayAttribLFormat = (PFNGLVERTEXARRAYATTRIBLFORMATPROC)load("glVertexArrayAttribLFormat", userptr); + glGetTextureLevelParameterfv = (PFNGLGETTEXTURELEVELPARAMETERFVPROC)load("glGetTextureLevelParameterfv", userptr); + glBlitNamedFramebuffer = (PFNGLBLITNAMEDFRAMEBUFFERPROC)load("glBlitNamedFramebuffer", userptr); + glClearNamedFramebufferfi = (PFNGLCLEARNAMEDFRAMEBUFFERFIPROC)load("glClearNamedFramebufferfi", userptr); + glNamedFramebufferReadBuffer = (PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC)load("glNamedFramebufferReadBuffer", userptr); + glGetCompressedTextureImage = (PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC)load("glGetCompressedTextureImage", userptr); + glGetTextureSubImage = (PFNGLGETTEXTURESUBIMAGEPROC)load("glGetTextureSubImage", userptr); + glTextureSubImage2D = (PFNGLTEXTURESUBIMAGE2DPROC)load("glTextureSubImage2D", userptr); + glNamedRenderbufferStorage = (PFNGLNAMEDRENDERBUFFERSTORAGEPROC)load("glNamedRenderbufferStorage", userptr); + glNamedFramebufferRenderbuffer = (PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC)load("glNamedFramebufferRenderbuffer", userptr); + glNamedBufferData = (PFNGLNAMEDBUFFERDATAPROC)load("glNamedBufferData", userptr); + glGetNamedBufferSubData = (PFNGLGETNAMEDBUFFERSUBDATAPROC)load("glGetNamedBufferSubData", userptr); + glGetNamedBufferPointerv = (PFNGLGETNAMEDBUFFERPOINTERVPROC)load("glGetNamedBufferPointerv", userptr); + glTextureStorage2D = (PFNGLTEXTURESTORAGE2DPROC)load("glTextureStorage2D", userptr); + glGetTextureParameteriv = (PFNGLGETTEXTUREPARAMETERIVPROC)load("glGetTextureParameteriv", userptr); + glVertexArrayVertexBuffer = (PFNGLVERTEXARRAYVERTEXBUFFERPROC)load("glVertexArrayVertexBuffer", userptr); + glGetQueryBufferObjectui64v = (PFNGLGETQUERYBUFFEROBJECTUI64VPROC)load("glGetQueryBufferObjectui64v", userptr); + glGetnPolygonStipple = (PFNGLGETNPOLYGONSTIPPLEPROC)load("glGetnPolygonStipple", userptr); + glVertexArrayBindingDivisor = (PFNGLVERTEXARRAYBINDINGDIVISORPROC)load("glVertexArrayBindingDivisor", userptr); + glGetnHistogram = (PFNGLGETNHISTOGRAMPROC)load("glGetnHistogram", userptr); + glEnableVertexArrayAttrib = (PFNGLENABLEVERTEXARRAYATTRIBPROC)load("glEnableVertexArrayAttrib", userptr); + glGetVertexArrayIndexed64iv = (PFNGLGETVERTEXARRAYINDEXED64IVPROC)load("glGetVertexArrayIndexed64iv", userptr); + glGetnUniformdv = (PFNGLGETNUNIFORMDVPROC)load("glGetnUniformdv", userptr); + glCreateSamplers = (PFNGLCREATESAMPLERSPROC)load("glCreateSamplers", userptr); + glNamedFramebufferParameteri = (PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC)load("glNamedFramebufferParameteri", userptr); + glNamedBufferStorage = (PFNGLNAMEDBUFFERSTORAGEPROC)load("glNamedBufferStorage", userptr); + glNamedFramebufferTexture = (PFNGLNAMEDFRAMEBUFFERTEXTUREPROC)load("glNamedFramebufferTexture", userptr); + glGetnSeparableFilter = (PFNGLGETNSEPARABLEFILTERPROC)load("glGetnSeparableFilter", userptr); + glCreateQueries = (PFNGLCREATEQUERIESPROC)load("glCreateQueries", userptr); + glTransformFeedbackBufferRange = (PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC)load("glTransformFeedbackBufferRange", userptr); + glGetVertexArrayiv = (PFNGLGETVERTEXARRAYIVPROC)load("glGetVertexArrayiv", userptr); + glGetnMapfv = (PFNGLGETNMAPFVPROC)load("glGetnMapfv", userptr); + glGetNamedRenderbufferParameteriv = (PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC)load("glGetNamedRenderbufferParameteriv", userptr); + glGetnPixelMapuiv = (PFNGLGETNPIXELMAPUIVPROC)load("glGetnPixelMapuiv", userptr); + glGetQueryBufferObjectiv = (PFNGLGETQUERYBUFFEROBJECTIVPROC)load("glGetQueryBufferObjectiv", userptr); + glGetnConvolutionFilter = (PFNGLGETNCONVOLUTIONFILTERPROC)load("glGetnConvolutionFilter", userptr); + glCreateRenderbuffers = (PFNGLCREATERENDERBUFFERSPROC)load("glCreateRenderbuffers", userptr); + glGenerateTextureMipmap = (PFNGLGENERATETEXTUREMIPMAPPROC)load("glGenerateTextureMipmap", userptr); + glTextureStorage1D = (PFNGLTEXTURESTORAGE1DPROC)load("glTextureStorage1D", userptr); + glCreateProgramPipelines = (PFNGLCREATEPROGRAMPIPELINESPROC)load("glCreateProgramPipelines", userptr); + glGetNamedFramebufferAttachmentParameteriv = (PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC)load("glGetNamedFramebufferAttachmentParameteriv", userptr); + glBindTextureUnit = (PFNGLBINDTEXTUREUNITPROC)load("glBindTextureUnit", userptr); + glGetTransformFeedbacki64_v = (PFNGLGETTRANSFORMFEEDBACKI64_VPROC)load("glGetTransformFeedbacki64_v", userptr); + glNamedFramebufferDrawBuffer = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC)load("glNamedFramebufferDrawBuffer", userptr); + glInvalidateNamedFramebufferData = (PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC)load("glInvalidateNamedFramebufferData", userptr); + glReadnPixels = (PFNGLREADNPIXELSPROC)load("glReadnPixels", userptr); + glTextureParameterfv = (PFNGLTEXTUREPARAMETERFVPROC)load("glTextureParameterfv", userptr); + glGetVertexArrayIndexediv = (PFNGLGETVERTEXARRAYINDEXEDIVPROC)load("glGetVertexArrayIndexediv", userptr); + glMapNamedBuffer = (PFNGLMAPNAMEDBUFFERPROC)load("glMapNamedBuffer", userptr); + glGetNamedBufferParameteri64v = (PFNGLGETNAMEDBUFFERPARAMETERI64VPROC)load("glGetNamedBufferParameteri64v", userptr); + glVertexArrayElementBuffer = (PFNGLVERTEXARRAYELEMENTBUFFERPROC)load("glVertexArrayElementBuffer", userptr); + glClipControl = (PFNGLCLIPCONTROLPROC)load("glClipControl", userptr); + glClearNamedFramebufferfv = (PFNGLCLEARNAMEDFRAMEBUFFERFVPROC)load("glClearNamedFramebufferfv", userptr); + glGetTransformFeedbackiv = (PFNGLGETTRANSFORMFEEDBACKIVPROC)load("glGetTransformFeedbackiv", userptr); + glGetnMinmax = (PFNGLGETNMINMAXPROC)load("glGetnMinmax", userptr); + glNamedRenderbufferStorageMultisample = (PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC)load("glNamedRenderbufferStorageMultisample", userptr); + glNamedFramebufferDrawBuffers = (PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC)load("glNamedFramebufferDrawBuffers", userptr); + glGetNamedBufferParameteriv = (PFNGLGETNAMEDBUFFERPARAMETERIVPROC)load("glGetNamedBufferParameteriv", userptr); + glNamedFramebufferTextureLayer = (PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC)load("glNamedFramebufferTextureLayer", userptr); + glClearNamedFramebufferiv = (PFNGLCLEARNAMEDFRAMEBUFFERIVPROC)load("glClearNamedFramebufferiv", userptr); + glCompressedTextureSubImage3D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC)load("glCompressedTextureSubImage3D", userptr); + glDisableVertexArrayAttrib = (PFNGLDISABLEVERTEXARRAYATTRIBPROC)load("glDisableVertexArrayAttrib", userptr); + glGetQueryBufferObjectuiv = (PFNGLGETQUERYBUFFEROBJECTUIVPROC)load("glGetQueryBufferObjectuiv", userptr); + glTextureParameterIuiv = (PFNGLTEXTUREPARAMETERIUIVPROC)load("glTextureParameterIuiv", userptr); + glGetTextureParameterIuiv = (PFNGLGETTEXTUREPARAMETERIUIVPROC)load("glGetTextureParameterIuiv", userptr); + glTextureBuffer = (PFNGLTEXTUREBUFFERPROC)load("glTextureBuffer", userptr); + glMemoryBarrierByRegion = (PFNGLMEMORYBARRIERBYREGIONPROC)load("glMemoryBarrierByRegion", userptr); + glTextureParameterf = (PFNGLTEXTUREPARAMETERFPROC)load("glTextureParameterf", userptr); + glCopyNamedBufferSubData = (PFNGLCOPYNAMEDBUFFERSUBDATAPROC)load("glCopyNamedBufferSubData", userptr); + glVertexArrayAttribFormat = (PFNGLVERTEXARRAYATTRIBFORMATPROC)load("glVertexArrayAttribFormat", userptr); + glMapNamedBufferRange = (PFNGLMAPNAMEDBUFFERRANGEPROC)load("glMapNamedBufferRange", userptr); + glTextureSubImage1D = (PFNGLTEXTURESUBIMAGE1DPROC)load("glTextureSubImage1D", userptr); + glGetTextureParameterfv = (PFNGLGETTEXTUREPARAMETERFVPROC)load("glGetTextureParameterfv", userptr); + glTextureParameteriv = (PFNGLTEXTUREPARAMETERIVPROC)load("glTextureParameteriv", userptr); + glCreateFramebuffers = (PFNGLCREATEFRAMEBUFFERSPROC)load("glCreateFramebuffers", userptr); + glTextureParameterIiv = (PFNGLTEXTUREPARAMETERIIVPROC)load("glTextureParameterIiv", userptr); + glGetnTexImage = (PFNGLGETNTEXIMAGEPROC)load("glGetnTexImage", userptr); + glTextureBarrier = (PFNGLTEXTUREBARRIERPROC)load("glTextureBarrier", userptr); + glCreateTextures = (PFNGLCREATETEXTURESPROC)load("glCreateTextures", userptr); + glCompressedTextureSubImage1D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC)load("glCompressedTextureSubImage1D", userptr); + glCopyTextureSubImage3D = (PFNGLCOPYTEXTURESUBIMAGE3DPROC)load("glCopyTextureSubImage3D", userptr); + glCreateVertexArrays = (PFNGLCREATEVERTEXARRAYSPROC)load("glCreateVertexArrays", userptr); + glCompressedTextureSubImage2D = (PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC)load("glCompressedTextureSubImage2D", userptr); + glCreateBuffers = (PFNGLCREATEBUFFERSPROC)load("glCreateBuffers", userptr); + glCreateTransformFeedbacks = (PFNGLCREATETRANSFORMFEEDBACKSPROC)load("glCreateTransformFeedbacks", userptr); + glGetnMapiv = (PFNGLGETNMAPIVPROC)load("glGetnMapiv", userptr); + glClearNamedBufferSubData = (PFNGLCLEARNAMEDBUFFERSUBDATAPROC)load("glClearNamedBufferSubData", userptr); + glGetTextureImage = (PFNGLGETTEXTUREIMAGEPROC)load("glGetTextureImage", userptr); + glGetTextureLevelParameteriv = (PFNGLGETTEXTURELEVELPARAMETERIVPROC)load("glGetTextureLevelParameteriv", userptr); + glGetnUniformiv = (PFNGLGETNUNIFORMIVPROC)load("glGetnUniformiv", userptr); + glGetCompressedTextureSubImage = (PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC)load("glGetCompressedTextureSubImage", userptr); + glVertexArrayVertexBuffers = (PFNGLVERTEXARRAYVERTEXBUFFERSPROC)load("glVertexArrayVertexBuffers", userptr); + glCopyTextureSubImage2D = (PFNGLCOPYTEXTURESUBIMAGE2DPROC)load("glCopyTextureSubImage2D", userptr); + glGetTransformFeedbacki_v = (PFNGLGETTRANSFORMFEEDBACKI_VPROC)load("glGetTransformFeedbacki_v", userptr); + glUnmapNamedBuffer = (PFNGLUNMAPNAMEDBUFFERPROC)load("glUnmapNamedBuffer", userptr); + glVertexArrayAttribIFormat = (PFNGLVERTEXARRAYATTRIBIFORMATPROC)load("glVertexArrayAttribIFormat", userptr); + glGetnPixelMapusv = (PFNGLGETNPIXELMAPUSVPROC)load("glGetnPixelMapusv", userptr); + glGetnUniformfv = (PFNGLGETNUNIFORMFVPROC)load("glGetnUniformfv", userptr); + glTextureStorage3D = (PFNGLTEXTURESTORAGE3DPROC)load("glTextureStorage3D", userptr); + glGetQueryBufferObjecti64v = (PFNGLGETQUERYBUFFEROBJECTI64VPROC)load("glGetQueryBufferObjecti64v", userptr); } -static void load_GL_VERSION_4_6( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GL_VERSION_4_6) return; - glPolygonOffsetClamp = (PFNGLPOLYGONOFFSETCLAMPPROC) load("glPolygonOffsetClamp", userptr); - glSpecializeShader = (PFNGLSPECIALIZESHADERPROC) load("glSpecializeShader", userptr); - glMultiDrawArraysIndirectCount = (PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC) load("glMultiDrawArraysIndirectCount", userptr); - glMultiDrawElementsIndirectCount = (PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC) load("glMultiDrawElementsIndirectCount", userptr); +static void load_GL_VERSION_4_6(GLADuserptrloadfunc load, void *userptr) +{ + if (!GLAD_GL_VERSION_4_6) return; + glPolygonOffsetClamp = (PFNGLPOLYGONOFFSETCLAMPPROC)load("glPolygonOffsetClamp", userptr); + glSpecializeShader = (PFNGLSPECIALIZESHADERPROC)load("glSpecializeShader", userptr); + glMultiDrawArraysIndirectCount = (PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC)load("glMultiDrawArraysIndirectCount", userptr); + glMultiDrawElementsIndirectCount = (PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC)load("glMultiDrawElementsIndirectCount", userptr); } - - #if defined(GL_ES_VERSION_3_0) || defined(GL_VERSION_3_0) #define GLAD_GL_IS_SOME_NEW_VERSION 1 #else #define GLAD_GL_IS_SOME_NEW_VERSION 0 #endif -static int get_exts( int version, const char **out_exts, unsigned int *out_num_exts_i, char ***out_exts_i) { +static int get_exts(int version, const char **out_exts, unsigned int *out_num_exts_i, char ***out_exts_i) +{ #if GLAD_GL_IS_SOME_NEW_VERSION - if(GLAD_VERSION_MAJOR(version) < 3) { + if (GLAD_VERSION_MAJOR(version) < 3) + { #else - (void) version; - (void) out_num_exts_i; - (void) out_exts_i; + (void)version; + (void)out_num_exts_i; + (void)out_exts_i; #endif - if (glGetString == NULL) { - return 0; - } - *out_exts = (const char *)glGetString(GL_EXTENSIONS); + if (glGetString == NULL) + { + return 0; + } + *out_exts = (const char *)glGetString(GL_EXTENSIONS); #if GLAD_GL_IS_SOME_NEW_VERSION - } else { - unsigned int index = 0; - unsigned int num_exts_i = 0; - char **exts_i = NULL; - if (glGetStringi == NULL || glGetIntegerv == NULL) { - return 0; - } - glGetIntegerv(GL_NUM_EXTENSIONS, (int*) &num_exts_i); - if (num_exts_i > 0) { - exts_i = (char **) malloc(num_exts_i * (sizeof *exts_i)); - } - if (exts_i == NULL) { - return 0; - } - for(index = 0; index < num_exts_i; index++) { - const char *gl_str_tmp = (const char*) glGetStringi(GL_EXTENSIONS, index); - size_t len = strlen(gl_str_tmp) + 1; + } + else + { + unsigned int index = 0; + unsigned int num_exts_i = 0; + char **exts_i = NULL; + if (glGetStringi == NULL || glGetIntegerv == NULL) + { + return 0; + } + glGetIntegerv(GL_NUM_EXTENSIONS, (int *)&num_exts_i); + if (num_exts_i > 0) + { + exts_i = (char **)malloc(num_exts_i * (sizeof *exts_i)); + } + if (exts_i == NULL) + { + return 0; + } + for (index = 0; index < num_exts_i; index++) + { + const char *gl_str_tmp = (const char *)glGetStringi(GL_EXTENSIONS, index); + size_t len = strlen(gl_str_tmp) + 1; - char *local_str = (char*) malloc(len * sizeof(char)); - if(local_str != NULL) { - GLAD_IMPL_UTIL_STRNCPY(local_str, gl_str_tmp, len); - } + char *local_str = (char *)malloc(len * sizeof(char)); + if (local_str != NULL) + { + GLAD_IMPL_UTIL_STRNCPY(local_str, gl_str_tmp, len); + } - exts_i[index] = local_str; - } + exts_i[index] = local_str; + } - *out_num_exts_i = num_exts_i; - *out_exts_i = exts_i; - } + *out_num_exts_i = num_exts_i; + *out_exts_i = exts_i; + } #endif - return 1; + return 1; } -static void free_exts(char **exts_i, unsigned int num_exts_i) { - if (exts_i != NULL) { - unsigned int index; - for(index = 0; index < num_exts_i; index++) { - free((void *) (exts_i[index])); - } - free((void *)exts_i); - exts_i = NULL; - } +static void free_exts(char **exts_i, unsigned int num_exts_i) +{ + if (exts_i != NULL) + { + unsigned int index; + for (index = 0; index < num_exts_i; index++) + { + free((void *)(exts_i[index])); + } + free((void *)exts_i); + exts_i = NULL; + } } -static int has_ext(int version, const char *exts, unsigned int num_exts_i, char **exts_i, const char *ext) { - if(GLAD_VERSION_MAJOR(version) < 3 || !GLAD_GL_IS_SOME_NEW_VERSION) { - const char *extensions; - const char *loc; - const char *terminator; - extensions = exts; - if(extensions == NULL || ext == NULL) { - return 0; - } - while(1) { - loc = strstr(extensions, ext); - if(loc == NULL) { - return 0; - } - terminator = loc + strlen(ext); - if((loc == extensions || *(loc - 1) == ' ') && - (*terminator == ' ' || *terminator == '\0')) { - return 1; - } - extensions = terminator; - } - } else { - unsigned int index; - for(index = 0; index < num_exts_i; index++) { - const char *e = exts_i[index]; - if(strcmp(e, ext) == 0) { - return 1; - } - } - } - return 0; +static int has_ext(int version, const char *exts, unsigned int num_exts_i, char **exts_i, const char *ext) +{ + if (GLAD_VERSION_MAJOR(version) < 3 || !GLAD_GL_IS_SOME_NEW_VERSION) + { + const char *extensions; + const char *loc; + const char *terminator; + extensions = exts; + if (extensions == NULL || ext == NULL) + { + return 0; + } + while (1) + { + loc = strstr(extensions, ext); + if (loc == NULL) + { + return 0; + } + terminator = loc + strlen(ext); + if ((loc == extensions || *(loc - 1) == ' ') && + (*terminator == ' ' || *terminator == '\0')) + { + return 1; + } + extensions = terminator; + } + } + else + { + unsigned int index; + for (index = 0; index < num_exts_i; index++) + { + const char *e = exts_i[index]; + if (strcmp(e, ext) == 0) + { + return 1; + } + } + } + return 0; } -static GLADapiproc glad_gl_get_proc_from_userptr(const char* name, void *userptr) { - return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name); +static GLADapiproc glad_gl_get_proc_from_userptr(const char *name, void *userptr) +{ + return (GLAD_GNUC_EXTENSION(GLADapiproc(*)(const char *name)) userptr)(name); } -static int find_extensionsGL( int version) { - const char *exts = NULL; - unsigned int num_exts_i = 0; - char **exts_i = NULL; - if (!get_exts(version, &exts, &num_exts_i, &exts_i)) return 0; +static int find_extensionsGL(int version) +{ + const char *exts = NULL; + unsigned int num_exts_i = 0; + char **exts_i = NULL; + if (!get_exts(version, &exts, &num_exts_i, &exts_i)) return 0; - GLAD_GL_ARB_point_sprite = has_ext(version, exts, num_exts_i, exts_i, "GL_ARB_point_sprite"); + GLAD_GL_ARB_point_sprite = has_ext(version, exts, num_exts_i, exts_i, "GL_ARB_point_sprite"); - free_exts(exts_i, num_exts_i); - return 1; + free_exts(exts_i, num_exts_i); + return 1; } -static int find_coreGL(void) { - int i, major, minor; - const char* version; - const char* prefixes[] = { - "OpenGL ES-CM ", - "OpenGL ES-CL ", - "OpenGL ES ", - NULL - }; - version = (const char*) glGetString(GL_VERSION); - if (!version) return 0; - for (i = 0; prefixes[i]; i++) { - const size_t length = strlen(prefixes[i]); - if (strncmp(version, prefixes[i], length) == 0) { - version += length; - break; - } - } +static int find_coreGL(void) +{ + int i, major, minor; + const char *version; + const char *prefixes[] = { + "OpenGL ES-CM ", + "OpenGL ES-CL ", + "OpenGL ES ", + NULL}; + version = (const char *)glGetString(GL_VERSION); + if (!version) return 0; + for (i = 0; prefixes[i]; i++) + { + const size_t length = strlen(prefixes[i]); + if (strncmp(version, prefixes[i], length) == 0) + { + version += length; + break; + } + } - GLAD_IMPL_UTIL_SSCANF(version, "%d.%d", &major, &minor); + GLAD_IMPL_UTIL_SSCANF(version, "%d.%d", &major, &minor); - GLAD_GL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; - GLAD_GL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; - GLAD_GL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; - GLAD_GL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; - GLAD_GL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; - GLAD_GL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; - GLAD_GL_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; - GLAD_GL_VERSION_2_1 = (major == 2 && minor >= 1) || major > 2; - GLAD_GL_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; - GLAD_GL_VERSION_3_1 = (major == 3 && minor >= 1) || major > 3; - GLAD_GL_VERSION_3_2 = (major == 3 && minor >= 2) || major > 3; - GLAD_GL_VERSION_3_3 = (major == 3 && minor >= 3) || major > 3; - GLAD_GL_VERSION_4_0 = (major == 4 && minor >= 0) || major > 4; - GLAD_GL_VERSION_4_1 = (major == 4 && minor >= 1) || major > 4; - GLAD_GL_VERSION_4_2 = (major == 4 && minor >= 2) || major > 4; - GLAD_GL_VERSION_4_3 = (major == 4 && minor >= 3) || major > 4; - GLAD_GL_VERSION_4_4 = (major == 4 && minor >= 4) || major > 4; - GLAD_GL_VERSION_4_5 = (major == 4 && minor >= 5) || major > 4; - GLAD_GL_VERSION_4_6 = (major == 4 && minor >= 6) || major > 4; + GLAD_GL_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; + GLAD_GL_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; + GLAD_GL_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; + GLAD_GL_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; + GLAD_GL_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; + GLAD_GL_VERSION_1_5 = (major == 1 && minor >= 5) || major > 1; + GLAD_GL_VERSION_2_0 = (major == 2 && minor >= 0) || major > 2; + GLAD_GL_VERSION_2_1 = (major == 2 && minor >= 1) || major > 2; + GLAD_GL_VERSION_3_0 = (major == 3 && minor >= 0) || major > 3; + GLAD_GL_VERSION_3_1 = (major == 3 && minor >= 1) || major > 3; + GLAD_GL_VERSION_3_2 = (major == 3 && minor >= 2) || major > 3; + GLAD_GL_VERSION_3_3 = (major == 3 && minor >= 3) || major > 3; + GLAD_GL_VERSION_4_0 = (major == 4 && minor >= 0) || major > 4; + GLAD_GL_VERSION_4_1 = (major == 4 && minor >= 1) || major > 4; + GLAD_GL_VERSION_4_2 = (major == 4 && minor >= 2) || major > 4; + GLAD_GL_VERSION_4_3 = (major == 4 && minor >= 3) || major > 4; + GLAD_GL_VERSION_4_4 = (major == 4 && minor >= 4) || major > 4; + GLAD_GL_VERSION_4_5 = (major == 4 && minor >= 5) || major > 4; + GLAD_GL_VERSION_4_6 = (major == 4 && minor >= 6) || major > 4; - return GLAD_MAKE_VERSION(major, minor); + return GLAD_MAKE_VERSION(major, minor); } -int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr) { - int version; +int gladLoadGLUserPtr(GLADuserptrloadfunc load, void *userptr) +{ + int version; - glGetString = (PFNGLGETSTRINGPROC) load("glGetString", userptr); - if(glGetString == NULL) return 0; - if(glGetString(GL_VERSION) == NULL) return 0; - version = find_coreGL(); + glGetString = (PFNGLGETSTRINGPROC)load("glGetString", userptr); + if (glGetString == NULL) return 0; + if (glGetString(GL_VERSION) == NULL) return 0; + version = find_coreGL(); - load_GL_VERSION_1_0(load, userptr); - load_GL_VERSION_1_1(load, userptr); - load_GL_VERSION_1_2(load, userptr); - load_GL_VERSION_1_3(load, userptr); - load_GL_VERSION_1_4(load, userptr); - load_GL_VERSION_1_5(load, userptr); - load_GL_VERSION_2_0(load, userptr); - load_GL_VERSION_2_1(load, userptr); - load_GL_VERSION_3_0(load, userptr); - load_GL_VERSION_3_1(load, userptr); - load_GL_VERSION_3_2(load, userptr); - load_GL_VERSION_3_3(load, userptr); - load_GL_VERSION_4_0(load, userptr); - load_GL_VERSION_4_1(load, userptr); - load_GL_VERSION_4_2(load, userptr); - load_GL_VERSION_4_3(load, userptr); - load_GL_VERSION_4_4(load, userptr); - load_GL_VERSION_4_5(load, userptr); - load_GL_VERSION_4_6(load, userptr); + load_GL_VERSION_1_0(load, userptr); + load_GL_VERSION_1_1(load, userptr); + load_GL_VERSION_1_2(load, userptr); + load_GL_VERSION_1_3(load, userptr); + load_GL_VERSION_1_4(load, userptr); + load_GL_VERSION_1_5(load, userptr); + load_GL_VERSION_2_0(load, userptr); + load_GL_VERSION_2_1(load, userptr); + load_GL_VERSION_3_0(load, userptr); + load_GL_VERSION_3_1(load, userptr); + load_GL_VERSION_3_2(load, userptr); + load_GL_VERSION_3_3(load, userptr); + load_GL_VERSION_4_0(load, userptr); + load_GL_VERSION_4_1(load, userptr); + load_GL_VERSION_4_2(load, userptr); + load_GL_VERSION_4_3(load, userptr); + load_GL_VERSION_4_4(load, userptr); + load_GL_VERSION_4_5(load, userptr); + load_GL_VERSION_4_6(load, userptr); - if (!find_extensionsGL(version)) return 0; + if (!find_extensionsGL(version)) return 0; - - - return version; + return version; } - -int gladLoadGL( GLADloadfunc load) { - return gladLoadGLUserPtr( glad_gl_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); +int gladLoadGL(GLADloadfunc load) +{ + return gladLoadGLUserPtr(glad_gl_get_proc_from_userptr, GLAD_GNUC_EXTENSION(void *) load); } - - - #ifdef GLAD_GL #ifndef GLAD_LOADER_LIBRARY_C_ @@ -2417,126 +2453,138 @@ int gladLoadGL( GLADloadfunc load) { #include #endif +static void *glad_get_dlopen_handle(const char *lib_names[], int length) +{ + void *handle = NULL; + int i; -static void* glad_get_dlopen_handle(const char *lib_names[], int length) { - void *handle = NULL; - int i; - - for (i = 0; i < length; ++i) { + for (i = 0; i < length; ++i) + { #if GLAD_PLATFORM_WIN32 - #if GLAD_PLATFORM_UWP - size_t buffer_size = (strlen(lib_names[i]) + 1) * sizeof(WCHAR); - LPWSTR buffer = (LPWSTR) malloc(buffer_size); - if (buffer != NULL) { - int ret = MultiByteToWideChar(CP_ACP, 0, lib_names[i], -1, buffer, buffer_size); - if (ret != 0) { - handle = (void*) LoadPackagedLibrary(buffer, 0); - } - free((void*) buffer); - } - #else - handle = (void*) LoadLibraryA(lib_names[i]); - #endif +#if GLAD_PLATFORM_UWP + size_t buffer_size = (strlen(lib_names[i]) + 1) * sizeof(WCHAR); + LPWSTR buffer = (LPWSTR)malloc(buffer_size); + if (buffer != NULL) + { + int ret = MultiByteToWideChar(CP_ACP, 0, lib_names[i], -1, buffer, buffer_size); + if (ret != 0) + { + handle = (void *)LoadPackagedLibrary(buffer, 0); + } + free((void *)buffer); + } #else - handle = dlopen(lib_names[i], RTLD_LAZY | RTLD_LOCAL); + handle = (void *)LoadLibraryA(lib_names[i]); #endif - if (handle != NULL) { - return handle; - } - } +#else + handle = dlopen(lib_names[i], RTLD_LAZY | RTLD_LOCAL); +#endif + if (handle != NULL) + { + return handle; + } + } - return NULL; + return NULL; } -static void glad_close_dlopen_handle(void* handle) { - if (handle != NULL) { +static void glad_close_dlopen_handle(void *handle) +{ + if (handle != NULL) + { #if GLAD_PLATFORM_WIN32 - FreeLibrary((HMODULE) handle); + FreeLibrary((HMODULE)handle); #else - dlclose(handle); + dlclose(handle); #endif - } + } } -static GLADapiproc glad_dlsym_handle(void* handle, const char *name) { - if (handle == NULL) { - return NULL; - } +static GLADapiproc glad_dlsym_handle(void *handle, const char *name) +{ + if (handle == NULL) + { + return NULL; + } #if GLAD_PLATFORM_WIN32 - return (GLADapiproc) GetProcAddress((HMODULE) handle, name); + return (GLADapiproc)GetProcAddress((HMODULE)handle, name); #else - return GLAD_GNUC_EXTENSION (GLADapiproc) dlsym(handle, name); + return GLAD_GNUC_EXTENSION(GLADapiproc) dlsym(handle, name); #endif } #endif /* GLAD_LOADER_LIBRARY_C_ */ -typedef void* (GLAD_API_PTR *GLADglprocaddrfunc)(const char*); -struct _glad_gl_userptr { - void *gl_handle; - GLADglprocaddrfunc gl_get_proc_address_ptr; +typedef void *(GLAD_API_PTR *GLADglprocaddrfunc)(const char *); +struct _glad_gl_userptr +{ + void *gl_handle; + GLADglprocaddrfunc gl_get_proc_address_ptr; }; -static GLADapiproc glad_gl_get_proc(const char *name, void *vuserptr) { - struct _glad_gl_userptr userptr = *(struct _glad_gl_userptr*) vuserptr; - GLADapiproc result = NULL; +static GLADapiproc glad_gl_get_proc(const char *name, void *vuserptr) +{ + struct _glad_gl_userptr userptr = *(struct _glad_gl_userptr *)vuserptr; + GLADapiproc result = NULL; #ifndef __APPLE__ - if(userptr.gl_get_proc_address_ptr != NULL) { - result = GLAD_GNUC_EXTENSION (GLADapiproc) userptr.gl_get_proc_address_ptr(name); - } + if (userptr.gl_get_proc_address_ptr != NULL) + { + result = GLAD_GNUC_EXTENSION(GLADapiproc) userptr.gl_get_proc_address_ptr(name); + } #endif - if(result == NULL) { - result = glad_dlsym_handle(userptr.gl_handle, name); - } + if (result == NULL) + { + result = glad_dlsym_handle(userptr.gl_handle, name); + } - return result; + return result; } -int gladLoaderLoadGL(void) { +int gladLoaderLoadGL(void) +{ #ifdef __APPLE__ - static const char *NAMES[] = { - "../Frameworks/OpenGL.framework/OpenGL", - "/Library/Frameworks/OpenGL.framework/OpenGL", - "/System/Library/Frameworks/OpenGL.framework/OpenGL", - "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL" - }; + static const char *NAMES[] = { + "../Frameworks/OpenGL.framework/OpenGL", + "/Library/Frameworks/OpenGL.framework/OpenGL", + "/System/Library/Frameworks/OpenGL.framework/OpenGL", + "/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL"}; #elif GLAD_PLATFORM_WIN32 - static const char *NAMES[] = {"opengl32.dll"}; + static const char *NAMES[] = {"opengl32.dll"}; #else - static const char *NAMES[] = { + static const char *NAMES[] = { #if defined __CYGWIN__ - "libGL-1.so", + "libGL-1.so", #endif - "libGL.so.1", - "libGL.so" - }; + "libGL.so.1", + "libGL.so" + }; #endif - int version = 0; - void *handle; - struct _glad_gl_userptr userptr; + int version = 0; + void *handle; + struct _glad_gl_userptr userptr; - handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0])); - if (handle) { - userptr.gl_handle = handle; + handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0])); + if (handle) + { + userptr.gl_handle = handle; #ifdef __APPLE__ - userptr.gl_get_proc_address_ptr = NULL; + userptr.gl_get_proc_address_ptr = NULL; #elif GLAD_PLATFORM_WIN32 - userptr.gl_get_proc_address_ptr = - (GLADglprocaddrfunc) glad_dlsym_handle(handle, "wglGetProcAddress"); + userptr.gl_get_proc_address_ptr = + (GLADglprocaddrfunc)glad_dlsym_handle(handle, "wglGetProcAddress"); #else - userptr.gl_get_proc_address_ptr = - (GLADglprocaddrfunc) glad_dlsym_handle(handle, "glXGetProcAddressARB"); + userptr.gl_get_proc_address_ptr = + (GLADglprocaddrfunc)glad_dlsym_handle(handle, "glXGetProcAddressARB"); #endif - version = gladLoadGLUserPtr(glad_gl_get_proc, &userptr); + version = gladLoadGLUserPtr(glad_gl_get_proc, &userptr); - glad_close_dlopen_handle(handle); - } + glad_close_dlopen_handle(handle); + } - return version; + return version; } - #endif /* GLAD_GL */ diff --git a/examples/ThirdPartyLibs/glad/glad/egl.h b/examples/ThirdPartyLibs/glad/glad/egl.h index a28168a63..5c7e3cd98 100644 --- a/examples/ThirdPartyLibs/glad/glad/egl.h +++ b/examples/ThirdPartyLibs/glad/glad/egl.h @@ -27,99 +27,97 @@ #ifndef GLAD_EGL_H_ #define GLAD_EGL_H_ - #define GLAD_EGL #define GLAD_OPTION_EGL_LOADER #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #ifndef GLAD_PLATFORM_H_ #define GLAD_PLATFORM_H_ #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__) - #define GLAD_PLATFORM_WIN32 1 +#define GLAD_PLATFORM_WIN32 1 #else - #define GLAD_PLATFORM_WIN32 0 +#define GLAD_PLATFORM_WIN32 0 #endif +#ifndef GLAD_PLATFORM_UWP +#if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY) +#ifdef __has_include +#if __has_include() +#define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 +#endif +#elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ +#define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 +#endif +#endif + +#ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY +#include +#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +#define GLAD_PLATFORM_UWP 1 +#endif +#endif #ifndef GLAD_PLATFORM_UWP - #if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY) - #ifdef __has_include - #if __has_include() - #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 - #endif - #elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ - #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 - #endif - #endif - - #ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY - #include - #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) - #define GLAD_PLATFORM_UWP 1 - #endif - #endif - - #ifndef GLAD_PLATFORM_UWP - #define GLAD_PLATFORM_UWP 0 - #endif +#define GLAD_PLATFORM_UWP 0 +#endif #endif #ifdef __GNUC__ - #define GLAD_GNUC_EXTENSION __extension__ +#define GLAD_GNUC_EXTENSION __extension__ #else - #define GLAD_GNUC_EXTENSION +#define GLAD_GNUC_EXTENSION #endif #ifndef GLAD_API_CALL - #if defined(GLAD_API_CALL_EXPORT) - #if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) - #if defined(GLAD_API_CALL_EXPORT_BUILD) - #if defined(__GNUC__) - #define GLAD_API_CALL __attribute__ ((dllexport)) extern - #else - #define GLAD_API_CALL __declspec(dllexport) extern - #endif - #else - #if defined(__GNUC__) - #define GLAD_API_CALL __attribute__ ((dllimport)) extern - #else - #define GLAD_API_CALL __declspec(dllimport) extern - #endif - #endif - #elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD) - #define GLAD_API_CALL __attribute__ ((visibility ("default"))) extern - #else - #define GLAD_API_CALL extern - #endif - #else - #define GLAD_API_CALL extern - #endif +#if defined(GLAD_API_CALL_EXPORT) +#if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) +#if defined(GLAD_API_CALL_EXPORT_BUILD) +#if defined(__GNUC__) +#define GLAD_API_CALL __attribute__((dllexport)) extern +#else +#define GLAD_API_CALL __declspec(dllexport) extern +#endif +#else +#if defined(__GNUC__) +#define GLAD_API_CALL __attribute__((dllimport)) extern +#else +#define GLAD_API_CALL __declspec(dllimport) extern +#endif +#endif +#elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD) +#define GLAD_API_CALL __attribute__((visibility("default"))) extern +#else +#define GLAD_API_CALL extern +#endif +#else +#define GLAD_API_CALL extern +#endif #endif #ifdef APIENTRY - #define GLAD_API_PTR APIENTRY +#define GLAD_API_PTR APIENTRY #elif GLAD_PLATFORM_WIN32 - #define GLAD_API_PTR __stdcall +#define GLAD_API_PTR __stdcall #else - #define GLAD_API_PTR +#define GLAD_API_PTR #endif - #define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor) #define GLAD_VERSION_MAJOR(version) (version / 10000) #define GLAD_VERSION_MINOR(version) (version % 10000) -typedef void (*GLADapiproc)(void); + typedef void (*GLADapiproc)(void); -typedef GLADapiproc (*GLADloadfunc)(const char *name); -typedef GLADapiproc (*GLADuserptrloadfunc)(const char *name, void *userptr); + typedef GLADapiproc (*GLADloadfunc)(const char *name); + typedef GLADapiproc (*GLADuserptrloadfunc)(const char *name, void *userptr); -typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...); -typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...); + typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...); + typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...); #endif /* GLAD_PLATFORM_H_ */ @@ -173,7 +171,7 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro #define EGL_VG_ALPHA_FORMAT 0x3088 #define EGL_RENDER_BUFFER 0x3086 #define EGL_VG_COLORSPACE 0x3087 -#define EGL_NO_CONTEXT EGL_CAST(EGLContext,0) +#define EGL_NO_CONTEXT EGL_CAST(EGLContext, 0) #define EGL_OPENGL_API 0x30A2 #define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_Z 0x30B7 #define EGL_LUMINANCE_BUFFER 0x308F @@ -183,8 +181,8 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro #define EGL_BAD_ACCESS 0x3002 #define EGL_OPENGL_ES2_BIT 0x0004 #define EGL_LOSE_CONTEXT_ON_RESET 0x31BF -#define EGL_NO_DISPLAY EGL_CAST(EGLDisplay,0) -#define EGL_NO_DEVICE_EXT EGL_CAST(EGLDeviceEXT,0) +#define EGL_NO_DISPLAY EGL_CAST(EGLDisplay, 0) +#define EGL_NO_DEVICE_EXT EGL_CAST(EGLDeviceEXT, 0) #define EGL_BAD_CONFIG 0x3005 #define EGL_NO_TEXTURE 0x305C #define EGL_LARGEST_PBUFFER 0x3058 @@ -201,10 +199,10 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro #define EGL_COLORSPACE EGL_VG_COLORSPACE #define EGL_SYNC_CUDA_EVENT_NV 0x323C #define EGL_OPENVG_IMAGE 0x3096 -#define EGL_NO_IMAGE EGL_CAST(EGLImage,0) +#define EGL_NO_IMAGE EGL_CAST(EGLImage, 0) #define EGL_TEXTURE_TARGET 0x3081 #define EGL_CORE_NATIVE_ENGINE 0x305B -#define EGL_DEFAULT_DISPLAY EGL_CAST(EGLNativeDisplayType,0) +#define EGL_DEFAULT_DISPLAY EGL_CAST(EGLNativeDisplayType, 0) #define EGL_SIGNALED 0x30F2 #define EGL_GL_COLORSPACE 0x309D #define EGL_SYNC_PRIOR_COMMANDS_COMPLETE 0x30F0 @@ -250,13 +248,13 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro #define EGL_SYNC_STATUS 0x30F1 #define EGL_TRUE 1 #define EGL_TIMEOUT_EXPIRED 0x30F5 -#define EGL_NO_SURFACE EGL_CAST(EGLSurface,0) +#define EGL_NO_SURFACE EGL_CAST(EGLSurface, 0) #define EGL_RED_SIZE 0x3024 #define EGL_TEXTURE_RGBA 0x305E #define EGL_TRANSPARENT_GREEN_VALUE 0x3036 #define EGL_GL_TEXTURE_ZOFFSET 0x30BD #define EGL_ALPHA_FORMAT_PRE EGL_VG_ALPHA_FORMAT_PRE -#define EGL_UNKNOWN EGL_CAST(EGLint,-1) +#define EGL_UNKNOWN EGL_CAST(EGLint, -1) #define EGL_SUCCESS 0x3000 #define EGL_CONTEXT_CLIENT_VERSION 0x3098 #define EGL_GL_TEXTURE_CUBE_MAP_POSITIVE_X 0x30B3 @@ -290,267 +288,251 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro #define EGL_CLIENT_APIS 0x308D #define EGL_GL_TEXTURE_LEVEL 0x30BC #define EGL_NOT_INITIALIZED 0x3001 -#define EGL_NO_SYNC EGL_CAST(EGLSync,0) +#define EGL_NO_SYNC EGL_CAST(EGLSync, 0) #define EGL_VG_ALPHA_FORMAT_PRE 0x308C -#define EGL_DONT_CARE EGL_CAST(EGLint,-1) +#define EGL_DONT_CARE EGL_CAST(EGLint, -1) #define EGL_GL_TEXTURE_CUBE_MAP_NEGATIVE_Y 0x30B6 #define EGL_GL_COLORSPACE_SRGB EGL_COLORSPACE_sRGB #define EGL_CUDA_EVENT_HANDLE_NV 0x323B - #include #include + struct AHardwareBuffer; - - - - - - - - - -struct AHardwareBuffer; - -typedef unsigned int EGLBoolean; -typedef unsigned int EGLenum; -typedef intptr_t EGLAttribKHR; -typedef intptr_t EGLAttrib; -typedef void *EGLClientBuffer; -typedef void *EGLConfig; -typedef void *EGLContext; -typedef void *EGLDeviceEXT; -typedef void *EGLDisplay; -typedef void *EGLImage; -typedef void *EGLImageKHR; -typedef void *EGLLabelKHR; -typedef void *EGLObjectKHR; -typedef void *EGLOutputLayerEXT; -typedef void *EGLOutputPortEXT; -typedef void *EGLStreamKHR; -typedef void *EGLSurface; -typedef void *EGLSync; -typedef void *EGLSyncKHR; -typedef void *EGLSyncNV; -typedef void (*__eglMustCastToProperFunctionPointerType)(void); -typedef khronos_utime_nanoseconds_t EGLTimeKHR; -typedef khronos_utime_nanoseconds_t EGLTime; -typedef khronos_utime_nanoseconds_t EGLTimeNV; -typedef khronos_utime_nanoseconds_t EGLuint64NV; -typedef khronos_uint64_t EGLuint64KHR; -typedef khronos_stime_nanoseconds_t EGLnsecsANDROID; -typedef int EGLNativeFileDescriptorKHR; -typedef khronos_ssize_t EGLsizeiANDROID; -typedef void (*EGLSetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize); -typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID) (const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize); -struct EGLClientPixmapHI { - void *pData; - EGLint iWidth; - EGLint iHeight; - EGLint iStride; -}; -typedef void (GLAD_API_PTR *EGLDEBUGPROCKHR)(EGLenum error,const char *command,EGLint messageType,EGLLabelKHR threadLabel,EGLLabelKHR objectLabel,const char* message); - + typedef unsigned int EGLBoolean; + typedef unsigned int EGLenum; + typedef intptr_t EGLAttribKHR; + typedef intptr_t EGLAttrib; + typedef void *EGLClientBuffer; + typedef void *EGLConfig; + typedef void *EGLContext; + typedef void *EGLDeviceEXT; + typedef void *EGLDisplay; + typedef void *EGLImage; + typedef void *EGLImageKHR; + typedef void *EGLLabelKHR; + typedef void *EGLObjectKHR; + typedef void *EGLOutputLayerEXT; + typedef void *EGLOutputPortEXT; + typedef void *EGLStreamKHR; + typedef void *EGLSurface; + typedef void *EGLSync; + typedef void *EGLSyncKHR; + typedef void *EGLSyncNV; + typedef void (*__eglMustCastToProperFunctionPointerType)(void); + typedef khronos_utime_nanoseconds_t EGLTimeKHR; + typedef khronos_utime_nanoseconds_t EGLTime; + typedef khronos_utime_nanoseconds_t EGLTimeNV; + typedef khronos_utime_nanoseconds_t EGLuint64NV; + typedef khronos_uint64_t EGLuint64KHR; + typedef khronos_stime_nanoseconds_t EGLnsecsANDROID; + typedef int EGLNativeFileDescriptorKHR; + typedef khronos_ssize_t EGLsizeiANDROID; + typedef void (*EGLSetBlobFuncANDROID)(const void *key, EGLsizeiANDROID keySize, const void *value, EGLsizeiANDROID valueSize); + typedef EGLsizeiANDROID (*EGLGetBlobFuncANDROID)(const void *key, EGLsizeiANDROID keySize, void *value, EGLsizeiANDROID valueSize); + struct EGLClientPixmapHI + { + void *pData; + EGLint iWidth; + EGLint iHeight; + EGLint iStride; + }; + typedef void(GLAD_API_PTR *EGLDEBUGPROCKHR)(EGLenum error, const char *command, EGLint messageType, EGLLabelKHR threadLabel, EGLLabelKHR objectLabel, const char *message); #define EGL_VERSION_1_0 1 -GLAD_API_CALL int GLAD_EGL_VERSION_1_0; + GLAD_API_CALL int GLAD_EGL_VERSION_1_0; #define EGL_VERSION_1_1 1 -GLAD_API_CALL int GLAD_EGL_VERSION_1_1; + GLAD_API_CALL int GLAD_EGL_VERSION_1_1; #define EGL_VERSION_1_2 1 -GLAD_API_CALL int GLAD_EGL_VERSION_1_2; + GLAD_API_CALL int GLAD_EGL_VERSION_1_2; #define EGL_VERSION_1_3 1 -GLAD_API_CALL int GLAD_EGL_VERSION_1_3; + GLAD_API_CALL int GLAD_EGL_VERSION_1_3; #define EGL_VERSION_1_4 1 -GLAD_API_CALL int GLAD_EGL_VERSION_1_4; + GLAD_API_CALL int GLAD_EGL_VERSION_1_4; #define EGL_VERSION_1_5 1 -GLAD_API_CALL int GLAD_EGL_VERSION_1_5; + GLAD_API_CALL int GLAD_EGL_VERSION_1_5; #define EGL_EXT_platform_device 1 -GLAD_API_CALL int GLAD_EGL_EXT_platform_device; + GLAD_API_CALL int GLAD_EGL_EXT_platform_device; #define EGL_EXT_platform_base 1 -GLAD_API_CALL int GLAD_EGL_EXT_platform_base; + GLAD_API_CALL int GLAD_EGL_EXT_platform_base; #define EGL_NV_device_cuda 1 -GLAD_API_CALL int GLAD_EGL_NV_device_cuda; + GLAD_API_CALL int GLAD_EGL_NV_device_cuda; #define EGL_EXT_device_enumeration 1 -GLAD_API_CALL int GLAD_EGL_EXT_device_enumeration; + GLAD_API_CALL int GLAD_EGL_EXT_device_enumeration; #define EGL_EXT_device_query 1 -GLAD_API_CALL int GLAD_EGL_EXT_device_query; + GLAD_API_CALL int GLAD_EGL_EXT_device_query; #define EGL_EXT_device_base 1 -GLAD_API_CALL int GLAD_EGL_EXT_device_base; + GLAD_API_CALL int GLAD_EGL_EXT_device_base; #define EGL_NV_cuda_event 1 -GLAD_API_CALL int GLAD_EGL_NV_cuda_event; + GLAD_API_CALL int GLAD_EGL_NV_cuda_event; + typedef EGLBoolean(GLAD_API_PTR *PFNEGLQUERYDEVICESEXTPROC)(EGLint max_devices, EGLDeviceEXT *devices, EGLint *num_devices); + typedef EGLSurface(GLAD_API_PTR *PFNEGLCREATEPBUFFERSURFACEPROC)(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list); + typedef EGLint(GLAD_API_PTR *PFNEGLGETERRORPROC)(void); + typedef __eglMustCastToProperFunctionPointerType(GLAD_API_PTR *PFNEGLGETPROCADDRESSPROC)(const char *procname); + typedef EGLDisplay(GLAD_API_PTR *PFNEGLGETCURRENTDISPLAYPROC)(void); + typedef EGLenum(GLAD_API_PTR *PFNEGLQUERYAPIPROC)(void); + typedef EGLSurface(GLAD_API_PTR *PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC)(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLAttrib *attrib_list); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLQUERYDISPLAYATTRIBKHRPROC)(EGLDisplay dpy, EGLint name, EGLAttrib *value); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLDESTROYSYNCPROC)(EGLDisplay dpy, EGLSync sync); + typedef EGLImage(GLAD_API_PTR *PFNEGLCREATEIMAGEPROC)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib *attrib_list); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLQUERYCONTEXTPROC)(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLSWAPBUFFERSPROC)(EGLDisplay dpy, EGLSurface surface); + typedef EGLContext(GLAD_API_PTR *PFNEGLCREATECONTEXTPROC)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint *attrib_list); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLCHOOSECONFIGPROC)(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLBINDAPIPROC)(EGLenum api); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLWAITNATIVEPROC)(EGLint engine); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLTERMINATEPROC)(EGLDisplay dpy); + typedef EGLSurface(GLAD_API_PTR *PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC)(EGLDisplay dpy, EGLConfig config, void *native_pixmap, const EGLint *attrib_list); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLRELEASETHREADPROC)(void); + typedef EGLSurface(GLAD_API_PTR *PFNEGLCREATEPLATFORMWINDOWSURFACEPROC)(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLAttrib *attrib_list); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLGETCONFIGATTRIBPROC)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value); + typedef EGLSurface(GLAD_API_PTR *PFNEGLGETCURRENTSURFACEPROC)(EGLint readdraw); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLCOPYBUFFERSPROC)(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target); + typedef EGLDisplay(GLAD_API_PTR *PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum platform, void *native_display, const EGLint *attrib_list); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLQUERYDEVICEATTRIBEXTPROC)(EGLDeviceEXT device, EGLint attribute, EGLAttrib *value); + typedef EGLSurface(GLAD_API_PTR *PFNEGLCREATEPIXMAPSURFACEPROC)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLBINDTEXIMAGEPROC)(EGLDisplay dpy, EGLSurface surface, EGLint buffer); + typedef EGLDisplay(GLAD_API_PTR *PFNEGLGETPLATFORMDISPLAYPROC)(EGLenum platform, void *native_display, const EGLAttrib *attrib_list); + typedef EGLDisplay(GLAD_API_PTR *PFNEGLGETDISPLAYPROC)(EGLNativeDisplayType display_id); + typedef const char *(GLAD_API_PTR *PFNEGLQUERYSTRINGPROC)(EGLDisplay dpy, EGLint name); + typedef EGLint(GLAD_API_PTR *PFNEGLCLIENTWAITSYNCPROC)(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLWAITSYNCPROC)(EGLDisplay dpy, EGLSync sync, EGLint flags); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLDESTROYIMAGEPROC)(EGLDisplay dpy, EGLImage image); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLRELEASETEXIMAGEPROC)(EGLDisplay dpy, EGLSurface surface, EGLint buffer); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLQUERYDISPLAYATTRIBEXTPROC)(EGLDisplay dpy, EGLint attribute, EGLAttrib *value); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLDESTROYCONTEXTPROC)(EGLDisplay dpy, EGLContext ctx); + typedef const char *(GLAD_API_PTR *PFNEGLQUERYDEVICESTRINGEXTPROC)(EGLDeviceEXT device, EGLint name); + typedef EGLSurface(GLAD_API_PTR *PFNEGLCREATEWINDOWSURFACEPROC)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint *attrib_list); + typedef EGLContext(GLAD_API_PTR *PFNEGLGETCURRENTCONTEXTPROC)(void); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLINITIALIZEPROC)(EGLDisplay dpy, EGLint *major, EGLint *minor); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLDESTROYSURFACEPROC)(EGLDisplay dpy, EGLSurface surface); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLMAKECURRENTPROC)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); + typedef EGLSurface(GLAD_API_PTR *PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)(EGLDisplay dpy, EGLConfig config, void *native_window, const EGLint *attrib_list); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLSWAPINTERVALPROC)(EGLDisplay dpy, EGLint interval); + typedef EGLSync(GLAD_API_PTR *PFNEGLCREATESYNCPROC)(EGLDisplay dpy, EGLenum type, const EGLAttrib *attrib_list); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLGETSYNCATTRIBPROC)(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib *value); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLSURFACEATTRIBPROC)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLWAITGLPROC)(void); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLQUERYSURFACEPROC)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLGETCONFIGSPROC)(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config); + typedef EGLBoolean(GLAD_API_PTR *PFNEGLWAITCLIENTPROC)(void); + typedef EGLSurface(GLAD_API_PTR *PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC)(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLQUERYDEVICESEXTPROC)(EGLint max_devices, EGLDeviceEXT * devices, EGLint * num_devices); -typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPBUFFERSURFACEPROC)(EGLDisplay dpy, EGLConfig config, const EGLint * attrib_list); -typedef EGLint (GLAD_API_PTR *PFNEGLGETERRORPROC)(void); -typedef __eglMustCastToProperFunctionPointerType (GLAD_API_PTR *PFNEGLGETPROCADDRESSPROC)(const char * procname); -typedef EGLDisplay (GLAD_API_PTR *PFNEGLGETCURRENTDISPLAYPROC)(void); -typedef EGLenum (GLAD_API_PTR *PFNEGLQUERYAPIPROC)(void); -typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC)(EGLDisplay dpy, EGLConfig config, void * native_pixmap, const EGLAttrib * attrib_list); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLQUERYDISPLAYATTRIBKHRPROC)(EGLDisplay dpy, EGLint name, EGLAttrib * value); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLDESTROYSYNCPROC)(EGLDisplay dpy, EGLSync sync); -typedef EGLImage (GLAD_API_PTR *PFNEGLCREATEIMAGEPROC)(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLAttrib * attrib_list); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLQUERYCONTEXTPROC)(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint * value); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLSWAPBUFFERSPROC)(EGLDisplay dpy, EGLSurface surface); -typedef EGLContext (GLAD_API_PTR *PFNEGLCREATECONTEXTPROC)(EGLDisplay dpy, EGLConfig config, EGLContext share_context, const EGLint * attrib_list); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLCHOOSECONFIGPROC)(EGLDisplay dpy, const EGLint * attrib_list, EGLConfig * configs, EGLint config_size, EGLint * num_config); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLBINDAPIPROC)(EGLenum api); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLWAITNATIVEPROC)(EGLint engine); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLTERMINATEPROC)(EGLDisplay dpy); -typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC)(EGLDisplay dpy, EGLConfig config, void * native_pixmap, const EGLint * attrib_list); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLRELEASETHREADPROC)(void); -typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPLATFORMWINDOWSURFACEPROC)(EGLDisplay dpy, EGLConfig config, void * native_window, const EGLAttrib * attrib_list); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLGETCONFIGATTRIBPROC)(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint * value); -typedef EGLSurface (GLAD_API_PTR *PFNEGLGETCURRENTSURFACEPROC)(EGLint readdraw); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLCOPYBUFFERSPROC)(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target); -typedef EGLDisplay (GLAD_API_PTR *PFNEGLGETPLATFORMDISPLAYEXTPROC)(EGLenum platform, void * native_display, const EGLint * attrib_list); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLQUERYDEVICEATTRIBEXTPROC)(EGLDeviceEXT device, EGLint attribute, EGLAttrib * value); -typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPIXMAPSURFACEPROC)(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint * attrib_list); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLBINDTEXIMAGEPROC)(EGLDisplay dpy, EGLSurface surface, EGLint buffer); -typedef EGLDisplay (GLAD_API_PTR *PFNEGLGETPLATFORMDISPLAYPROC)(EGLenum platform, void * native_display, const EGLAttrib * attrib_list); -typedef EGLDisplay (GLAD_API_PTR *PFNEGLGETDISPLAYPROC)(EGLNativeDisplayType display_id); -typedef const char * (GLAD_API_PTR *PFNEGLQUERYSTRINGPROC)(EGLDisplay dpy, EGLint name); -typedef EGLint (GLAD_API_PTR *PFNEGLCLIENTWAITSYNCPROC)(EGLDisplay dpy, EGLSync sync, EGLint flags, EGLTime timeout); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLWAITSYNCPROC)(EGLDisplay dpy, EGLSync sync, EGLint flags); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLDESTROYIMAGEPROC)(EGLDisplay dpy, EGLImage image); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLRELEASETEXIMAGEPROC)(EGLDisplay dpy, EGLSurface surface, EGLint buffer); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLQUERYDISPLAYATTRIBEXTPROC)(EGLDisplay dpy, EGLint attribute, EGLAttrib * value); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLDESTROYCONTEXTPROC)(EGLDisplay dpy, EGLContext ctx); -typedef const char * (GLAD_API_PTR *PFNEGLQUERYDEVICESTRINGEXTPROC)(EGLDeviceEXT device, EGLint name); -typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEWINDOWSURFACEPROC)(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType win, const EGLint * attrib_list); -typedef EGLContext (GLAD_API_PTR *PFNEGLGETCURRENTCONTEXTPROC)(void); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLINITIALIZEPROC)(EGLDisplay dpy, EGLint * major, EGLint * minor); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLDESTROYSURFACEPROC)(EGLDisplay dpy, EGLSurface surface); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLMAKECURRENTPROC)(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx); -typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC)(EGLDisplay dpy, EGLConfig config, void * native_window, const EGLint * attrib_list); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLSWAPINTERVALPROC)(EGLDisplay dpy, EGLint interval); -typedef EGLSync (GLAD_API_PTR *PFNEGLCREATESYNCPROC)(EGLDisplay dpy, EGLenum type, const EGLAttrib * attrib_list); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLGETSYNCATTRIBPROC)(EGLDisplay dpy, EGLSync sync, EGLint attribute, EGLAttrib * value); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLSURFACEATTRIBPROC)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLWAITGLPROC)(void); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLQUERYSURFACEPROC)(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint * value); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLGETCONFIGSPROC)(EGLDisplay dpy, EGLConfig * configs, EGLint config_size, EGLint * num_config); -typedef EGLBoolean (GLAD_API_PTR *PFNEGLWAITCLIENTPROC)(void); -typedef EGLSurface (GLAD_API_PTR *PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC)(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint * attrib_list); - -GLAD_API_CALL PFNEGLQUERYDEVICESEXTPROC glad_eglQueryDevicesEXT; + GLAD_API_CALL PFNEGLQUERYDEVICESEXTPROC glad_eglQueryDevicesEXT; #define eglQueryDevicesEXT glad_eglQueryDevicesEXT -GLAD_API_CALL PFNEGLCREATEPBUFFERSURFACEPROC glad_eglCreatePbufferSurface; + GLAD_API_CALL PFNEGLCREATEPBUFFERSURFACEPROC glad_eglCreatePbufferSurface; #define eglCreatePbufferSurface glad_eglCreatePbufferSurface -GLAD_API_CALL PFNEGLGETERRORPROC glad_eglGetError; + GLAD_API_CALL PFNEGLGETERRORPROC glad_eglGetError; #define eglGetError glad_eglGetError -GLAD_API_CALL PFNEGLGETPROCADDRESSPROC glad_eglGetProcAddress; + GLAD_API_CALL PFNEGLGETPROCADDRESSPROC glad_eglGetProcAddress; #define eglGetProcAddress glad_eglGetProcAddress -GLAD_API_CALL PFNEGLGETCURRENTDISPLAYPROC glad_eglGetCurrentDisplay; + GLAD_API_CALL PFNEGLGETCURRENTDISPLAYPROC glad_eglGetCurrentDisplay; #define eglGetCurrentDisplay glad_eglGetCurrentDisplay -GLAD_API_CALL PFNEGLQUERYAPIPROC glad_eglQueryAPI; + GLAD_API_CALL PFNEGLQUERYAPIPROC glad_eglQueryAPI; #define eglQueryAPI glad_eglQueryAPI -GLAD_API_CALL PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC glad_eglCreatePlatformPixmapSurface; + GLAD_API_CALL PFNEGLCREATEPLATFORMPIXMAPSURFACEPROC glad_eglCreatePlatformPixmapSurface; #define eglCreatePlatformPixmapSurface glad_eglCreatePlatformPixmapSurface -GLAD_API_CALL PFNEGLQUERYDISPLAYATTRIBKHRPROC glad_eglQueryDisplayAttribKHR; + GLAD_API_CALL PFNEGLQUERYDISPLAYATTRIBKHRPROC glad_eglQueryDisplayAttribKHR; #define eglQueryDisplayAttribKHR glad_eglQueryDisplayAttribKHR -GLAD_API_CALL PFNEGLDESTROYSYNCPROC glad_eglDestroySync; + GLAD_API_CALL PFNEGLDESTROYSYNCPROC glad_eglDestroySync; #define eglDestroySync glad_eglDestroySync -GLAD_API_CALL PFNEGLCREATEIMAGEPROC glad_eglCreateImage; + GLAD_API_CALL PFNEGLCREATEIMAGEPROC glad_eglCreateImage; #define eglCreateImage glad_eglCreateImage -GLAD_API_CALL PFNEGLQUERYCONTEXTPROC glad_eglQueryContext; + GLAD_API_CALL PFNEGLQUERYCONTEXTPROC glad_eglQueryContext; #define eglQueryContext glad_eglQueryContext -GLAD_API_CALL PFNEGLSWAPBUFFERSPROC glad_eglSwapBuffers; + GLAD_API_CALL PFNEGLSWAPBUFFERSPROC glad_eglSwapBuffers; #define eglSwapBuffers glad_eglSwapBuffers -GLAD_API_CALL PFNEGLCREATECONTEXTPROC glad_eglCreateContext; + GLAD_API_CALL PFNEGLCREATECONTEXTPROC glad_eglCreateContext; #define eglCreateContext glad_eglCreateContext -GLAD_API_CALL PFNEGLCHOOSECONFIGPROC glad_eglChooseConfig; + GLAD_API_CALL PFNEGLCHOOSECONFIGPROC glad_eglChooseConfig; #define eglChooseConfig glad_eglChooseConfig -GLAD_API_CALL PFNEGLBINDAPIPROC glad_eglBindAPI; + GLAD_API_CALL PFNEGLBINDAPIPROC glad_eglBindAPI; #define eglBindAPI glad_eglBindAPI -GLAD_API_CALL PFNEGLWAITNATIVEPROC glad_eglWaitNative; + GLAD_API_CALL PFNEGLWAITNATIVEPROC glad_eglWaitNative; #define eglWaitNative glad_eglWaitNative -GLAD_API_CALL PFNEGLTERMINATEPROC glad_eglTerminate; + GLAD_API_CALL PFNEGLTERMINATEPROC glad_eglTerminate; #define eglTerminate glad_eglTerminate -GLAD_API_CALL PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC glad_eglCreatePlatformPixmapSurfaceEXT; + GLAD_API_CALL PFNEGLCREATEPLATFORMPIXMAPSURFACEEXTPROC glad_eglCreatePlatformPixmapSurfaceEXT; #define eglCreatePlatformPixmapSurfaceEXT glad_eglCreatePlatformPixmapSurfaceEXT -GLAD_API_CALL PFNEGLRELEASETHREADPROC glad_eglReleaseThread; + GLAD_API_CALL PFNEGLRELEASETHREADPROC glad_eglReleaseThread; #define eglReleaseThread glad_eglReleaseThread -GLAD_API_CALL PFNEGLCREATEPLATFORMWINDOWSURFACEPROC glad_eglCreatePlatformWindowSurface; + GLAD_API_CALL PFNEGLCREATEPLATFORMWINDOWSURFACEPROC glad_eglCreatePlatformWindowSurface; #define eglCreatePlatformWindowSurface glad_eglCreatePlatformWindowSurface -GLAD_API_CALL PFNEGLGETCONFIGATTRIBPROC glad_eglGetConfigAttrib; + GLAD_API_CALL PFNEGLGETCONFIGATTRIBPROC glad_eglGetConfigAttrib; #define eglGetConfigAttrib glad_eglGetConfigAttrib -GLAD_API_CALL PFNEGLGETCURRENTSURFACEPROC glad_eglGetCurrentSurface; + GLAD_API_CALL PFNEGLGETCURRENTSURFACEPROC glad_eglGetCurrentSurface; #define eglGetCurrentSurface glad_eglGetCurrentSurface -GLAD_API_CALL PFNEGLCOPYBUFFERSPROC glad_eglCopyBuffers; + GLAD_API_CALL PFNEGLCOPYBUFFERSPROC glad_eglCopyBuffers; #define eglCopyBuffers glad_eglCopyBuffers -GLAD_API_CALL PFNEGLGETPLATFORMDISPLAYEXTPROC glad_eglGetPlatformDisplayEXT; + GLAD_API_CALL PFNEGLGETPLATFORMDISPLAYEXTPROC glad_eglGetPlatformDisplayEXT; #define eglGetPlatformDisplayEXT glad_eglGetPlatformDisplayEXT -GLAD_API_CALL PFNEGLQUERYDEVICEATTRIBEXTPROC glad_eglQueryDeviceAttribEXT; + GLAD_API_CALL PFNEGLQUERYDEVICEATTRIBEXTPROC glad_eglQueryDeviceAttribEXT; #define eglQueryDeviceAttribEXT glad_eglQueryDeviceAttribEXT -GLAD_API_CALL PFNEGLCREATEPIXMAPSURFACEPROC glad_eglCreatePixmapSurface; + GLAD_API_CALL PFNEGLCREATEPIXMAPSURFACEPROC glad_eglCreatePixmapSurface; #define eglCreatePixmapSurface glad_eglCreatePixmapSurface -GLAD_API_CALL PFNEGLBINDTEXIMAGEPROC glad_eglBindTexImage; + GLAD_API_CALL PFNEGLBINDTEXIMAGEPROC glad_eglBindTexImage; #define eglBindTexImage glad_eglBindTexImage -GLAD_API_CALL PFNEGLGETPLATFORMDISPLAYPROC glad_eglGetPlatformDisplay; + GLAD_API_CALL PFNEGLGETPLATFORMDISPLAYPROC glad_eglGetPlatformDisplay; #define eglGetPlatformDisplay glad_eglGetPlatformDisplay -GLAD_API_CALL PFNEGLGETDISPLAYPROC glad_eglGetDisplay; + GLAD_API_CALL PFNEGLGETDISPLAYPROC glad_eglGetDisplay; #define eglGetDisplay glad_eglGetDisplay -GLAD_API_CALL PFNEGLQUERYSTRINGPROC glad_eglQueryString; + GLAD_API_CALL PFNEGLQUERYSTRINGPROC glad_eglQueryString; #define eglQueryString glad_eglQueryString -GLAD_API_CALL PFNEGLCLIENTWAITSYNCPROC glad_eglClientWaitSync; + GLAD_API_CALL PFNEGLCLIENTWAITSYNCPROC glad_eglClientWaitSync; #define eglClientWaitSync glad_eglClientWaitSync -GLAD_API_CALL PFNEGLWAITSYNCPROC glad_eglWaitSync; + GLAD_API_CALL PFNEGLWAITSYNCPROC glad_eglWaitSync; #define eglWaitSync glad_eglWaitSync -GLAD_API_CALL PFNEGLDESTROYIMAGEPROC glad_eglDestroyImage; + GLAD_API_CALL PFNEGLDESTROYIMAGEPROC glad_eglDestroyImage; #define eglDestroyImage glad_eglDestroyImage -GLAD_API_CALL PFNEGLRELEASETEXIMAGEPROC glad_eglReleaseTexImage; + GLAD_API_CALL PFNEGLRELEASETEXIMAGEPROC glad_eglReleaseTexImage; #define eglReleaseTexImage glad_eglReleaseTexImage -GLAD_API_CALL PFNEGLQUERYDISPLAYATTRIBEXTPROC glad_eglQueryDisplayAttribEXT; + GLAD_API_CALL PFNEGLQUERYDISPLAYATTRIBEXTPROC glad_eglQueryDisplayAttribEXT; #define eglQueryDisplayAttribEXT glad_eglQueryDisplayAttribEXT -GLAD_API_CALL PFNEGLDESTROYCONTEXTPROC glad_eglDestroyContext; + GLAD_API_CALL PFNEGLDESTROYCONTEXTPROC glad_eglDestroyContext; #define eglDestroyContext glad_eglDestroyContext -GLAD_API_CALL PFNEGLQUERYDEVICESTRINGEXTPROC glad_eglQueryDeviceStringEXT; + GLAD_API_CALL PFNEGLQUERYDEVICESTRINGEXTPROC glad_eglQueryDeviceStringEXT; #define eglQueryDeviceStringEXT glad_eglQueryDeviceStringEXT -GLAD_API_CALL PFNEGLCREATEWINDOWSURFACEPROC glad_eglCreateWindowSurface; + GLAD_API_CALL PFNEGLCREATEWINDOWSURFACEPROC glad_eglCreateWindowSurface; #define eglCreateWindowSurface glad_eglCreateWindowSurface -GLAD_API_CALL PFNEGLGETCURRENTCONTEXTPROC glad_eglGetCurrentContext; + GLAD_API_CALL PFNEGLGETCURRENTCONTEXTPROC glad_eglGetCurrentContext; #define eglGetCurrentContext glad_eglGetCurrentContext -GLAD_API_CALL PFNEGLINITIALIZEPROC glad_eglInitialize; + GLAD_API_CALL PFNEGLINITIALIZEPROC glad_eglInitialize; #define eglInitialize glad_eglInitialize -GLAD_API_CALL PFNEGLDESTROYSURFACEPROC glad_eglDestroySurface; + GLAD_API_CALL PFNEGLDESTROYSURFACEPROC glad_eglDestroySurface; #define eglDestroySurface glad_eglDestroySurface -GLAD_API_CALL PFNEGLMAKECURRENTPROC glad_eglMakeCurrent; + GLAD_API_CALL PFNEGLMAKECURRENTPROC glad_eglMakeCurrent; #define eglMakeCurrent glad_eglMakeCurrent -GLAD_API_CALL PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC glad_eglCreatePlatformWindowSurfaceEXT; + GLAD_API_CALL PFNEGLCREATEPLATFORMWINDOWSURFACEEXTPROC glad_eglCreatePlatformWindowSurfaceEXT; #define eglCreatePlatformWindowSurfaceEXT glad_eglCreatePlatformWindowSurfaceEXT -GLAD_API_CALL PFNEGLSWAPINTERVALPROC glad_eglSwapInterval; + GLAD_API_CALL PFNEGLSWAPINTERVALPROC glad_eglSwapInterval; #define eglSwapInterval glad_eglSwapInterval -GLAD_API_CALL PFNEGLCREATESYNCPROC glad_eglCreateSync; + GLAD_API_CALL PFNEGLCREATESYNCPROC glad_eglCreateSync; #define eglCreateSync glad_eglCreateSync -GLAD_API_CALL PFNEGLGETSYNCATTRIBPROC glad_eglGetSyncAttrib; + GLAD_API_CALL PFNEGLGETSYNCATTRIBPROC glad_eglGetSyncAttrib; #define eglGetSyncAttrib glad_eglGetSyncAttrib -GLAD_API_CALL PFNEGLSURFACEATTRIBPROC glad_eglSurfaceAttrib; + GLAD_API_CALL PFNEGLSURFACEATTRIBPROC glad_eglSurfaceAttrib; #define eglSurfaceAttrib glad_eglSurfaceAttrib -GLAD_API_CALL PFNEGLWAITGLPROC glad_eglWaitGL; + GLAD_API_CALL PFNEGLWAITGLPROC glad_eglWaitGL; #define eglWaitGL glad_eglWaitGL -GLAD_API_CALL PFNEGLQUERYSURFACEPROC glad_eglQuerySurface; + GLAD_API_CALL PFNEGLQUERYSURFACEPROC glad_eglQuerySurface; #define eglQuerySurface glad_eglQuerySurface -GLAD_API_CALL PFNEGLGETCONFIGSPROC glad_eglGetConfigs; + GLAD_API_CALL PFNEGLGETCONFIGSPROC glad_eglGetConfigs; #define eglGetConfigs glad_eglGetConfigs -GLAD_API_CALL PFNEGLWAITCLIENTPROC glad_eglWaitClient; + GLAD_API_CALL PFNEGLWAITCLIENTPROC glad_eglWaitClient; #define eglWaitClient glad_eglWaitClient -GLAD_API_CALL PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC glad_eglCreatePbufferFromClientBuffer; + GLAD_API_CALL PFNEGLCREATEPBUFFERFROMCLIENTBUFFERPROC glad_eglCreatePbufferFromClientBuffer; #define eglCreatePbufferFromClientBuffer glad_eglCreatePbufferFromClientBuffer - -GLAD_API_CALL int gladLoadEGLUserPtr(EGLDisplay display, GLADuserptrloadfunc load, void *userptr); -GLAD_API_CALL int gladLoadEGL(EGLDisplay display, GLADloadfunc load); - - - + GLAD_API_CALL int gladLoadEGLUserPtr(EGLDisplay display, GLADuserptrloadfunc load, void *userptr); + GLAD_API_CALL int gladLoadEGL(EGLDisplay display, GLADloadfunc load); #ifdef GLAD_EGL -GLAD_API_CALL int gladLoaderLoadEGL(EGLDisplay display); + GLAD_API_CALL int gladLoaderLoadEGL(EGLDisplay display); -GLAD_API_CALL void gladLoaderUnloadEGL(void); + GLAD_API_CALL void gladLoaderUnloadEGL(void); #endif #ifdef __cplusplus diff --git a/examples/ThirdPartyLibs/glad/glad/gl.h b/examples/ThirdPartyLibs/glad/glad/gl.h index 409819d31..3d08b2d45 100644 --- a/examples/ThirdPartyLibs/glad/glad/gl.h +++ b/examples/ThirdPartyLibs/glad/glad/gl.h @@ -28,103 +28,101 @@ #define GLAD_GL_H_ #ifdef __gl_h_ - #error OpenGL header already included (API: gl), remove previous include! +#error OpenGL header already included (API: gl), remove previous include! #endif #define __gl_h_ 1 - #define GLAD_GL #define GLAD_OPTION_GL_LOADER #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #ifndef GLAD_PLATFORM_H_ #define GLAD_PLATFORM_H_ #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__) - #define GLAD_PLATFORM_WIN32 1 +#define GLAD_PLATFORM_WIN32 1 #else - #define GLAD_PLATFORM_WIN32 0 +#define GLAD_PLATFORM_WIN32 0 #endif +#ifndef GLAD_PLATFORM_UWP +#if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY) +#ifdef __has_include +#if __has_include() +#define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 +#endif +#elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ +#define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 +#endif +#endif + +#ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY +#include +#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +#define GLAD_PLATFORM_UWP 1 +#endif +#endif #ifndef GLAD_PLATFORM_UWP - #if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY) - #ifdef __has_include - #if __has_include() - #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 - #endif - #elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ - #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 - #endif - #endif - - #ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY - #include - #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) - #define GLAD_PLATFORM_UWP 1 - #endif - #endif - - #ifndef GLAD_PLATFORM_UWP - #define GLAD_PLATFORM_UWP 0 - #endif +#define GLAD_PLATFORM_UWP 0 +#endif #endif #ifdef __GNUC__ - #define GLAD_GNUC_EXTENSION __extension__ +#define GLAD_GNUC_EXTENSION __extension__ #else - #define GLAD_GNUC_EXTENSION +#define GLAD_GNUC_EXTENSION #endif #ifndef GLAD_API_CALL - #if defined(GLAD_API_CALL_EXPORT) - #if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) - #if defined(GLAD_API_CALL_EXPORT_BUILD) - #if defined(__GNUC__) - #define GLAD_API_CALL __attribute__ ((dllexport)) extern - #else - #define GLAD_API_CALL __declspec(dllexport) extern - #endif - #else - #if defined(__GNUC__) - #define GLAD_API_CALL __attribute__ ((dllimport)) extern - #else - #define GLAD_API_CALL __declspec(dllimport) extern - #endif - #endif - #elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD) - #define GLAD_API_CALL __attribute__ ((visibility ("default"))) extern - #else - #define GLAD_API_CALL extern - #endif - #else - #define GLAD_API_CALL extern - #endif +#if defined(GLAD_API_CALL_EXPORT) +#if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) +#if defined(GLAD_API_CALL_EXPORT_BUILD) +#if defined(__GNUC__) +#define GLAD_API_CALL __attribute__((dllexport)) extern +#else +#define GLAD_API_CALL __declspec(dllexport) extern +#endif +#else +#if defined(__GNUC__) +#define GLAD_API_CALL __attribute__((dllimport)) extern +#else +#define GLAD_API_CALL __declspec(dllimport) extern +#endif +#endif +#elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD) +#define GLAD_API_CALL __attribute__((visibility("default"))) extern +#else +#define GLAD_API_CALL extern +#endif +#else +#define GLAD_API_CALL extern +#endif #endif #ifdef APIENTRY - #define GLAD_API_PTR APIENTRY +#define GLAD_API_PTR APIENTRY #elif GLAD_PLATFORM_WIN32 - #define GLAD_API_PTR __stdcall +#define GLAD_API_PTR __stdcall #else - #define GLAD_API_PTR +#define GLAD_API_PTR #endif - #define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor) #define GLAD_VERSION_MAJOR(version) (version / 10000) #define GLAD_VERSION_MINOR(version) (version % 10000) -typedef void (*GLADapiproc)(void); + typedef void (*GLADapiproc)(void); -typedef GLADapiproc (*GLADloadfunc)(const char *name); -typedef GLADapiproc (*GLADuserptrloadfunc)(const char *name, void *userptr); + typedef GLADapiproc (*GLADloadfunc)(const char *name); + typedef GLADapiproc (*GLADuserptrloadfunc)(const char *name, void *userptr); -typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...); -typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...); + typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...); + typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...); #endif /* GLAD_PLATFORM_H_ */ @@ -1927,7 +1925,6 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro #define GL_CLIENT_VERTEX_ARRAY_BIT 0x00000002 #define GL_SAMPLER_2D_RECT_SHADOW 0x8B64 - #include #include #ifndef GLEXT_64_TYPES_DEFINED @@ -1941,3295 +1938,3288 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro #include #if defined(__STDC__) #if defined(__arch64__) || defined(_LP64) -typedef long int int64_t; -typedef unsigned long int uint64_t; + typedef long int int64_t; + typedef unsigned long int uint64_t; #else -typedef long long int int64_t; -typedef unsigned long long int uint64_t; + typedef long long int int64_t; + typedef unsigned long long int uint64_t; #endif /* __arch64__ */ #endif /* __STDC__ */ -#elif defined( __VMS ) || defined(__sgi) +#elif defined(__VMS) || defined(__sgi) #include #elif defined(__SCO__) || defined(__USLC__) #include #elif defined(__UNIXOS2__) || defined(__SOL64__) -typedef long int int32_t; -typedef long long int int64_t; -typedef unsigned long long int uint64_t; + typedef long int int32_t; + typedef long long int int64_t; + typedef unsigned long long int uint64_t; #elif defined(_WIN32) && defined(__GNUC__) #include #elif defined(_WIN32) -typedef __int32 int32_t; -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; + typedef __int32 int32_t; + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; #else /* Fallback if nothing above works */ #include #endif #endif -typedef unsigned int GLenum; -typedef unsigned char GLboolean; -typedef unsigned int GLbitfield; -typedef void GLvoid; -typedef signed char GLbyte; -typedef short GLshort; -typedef int GLint; -typedef int GLclampx; -typedef unsigned char GLubyte; -typedef unsigned short GLushort; -typedef unsigned int GLuint; -typedef int GLsizei; -typedef float GLfloat; -typedef float GLclampf; -typedef double GLdouble; -typedef double GLclampd; -typedef void *GLeglClientBufferEXT; -typedef void *GLeglImageOES; -typedef char GLchar; -typedef char GLcharARB; + typedef unsigned int GLenum; + typedef unsigned char GLboolean; + typedef unsigned int GLbitfield; + typedef void GLvoid; + typedef signed char GLbyte; + typedef short GLshort; + typedef int GLint; + typedef int GLclampx; + typedef unsigned char GLubyte; + typedef unsigned short GLushort; + typedef unsigned int GLuint; + typedef int GLsizei; + typedef float GLfloat; + typedef float GLclampf; + typedef double GLdouble; + typedef double GLclampd; + typedef void *GLeglClientBufferEXT; + typedef void *GLeglImageOES; + typedef char GLchar; + typedef char GLcharARB; #ifdef __APPLE__ -typedef void *GLhandleARB; + typedef void *GLhandleARB; #else typedef unsigned int GLhandleARB; #endif -typedef unsigned short GLhalfARB; -typedef unsigned short GLhalf; -typedef GLint GLfixed; + typedef unsigned short GLhalfARB; + typedef unsigned short GLhalf; + typedef GLint GLfixed; #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) -typedef khronos_intptr_t GLintptr; + typedef khronos_intptr_t GLintptr; #else typedef khronos_intptr_t GLintptr; #endif #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) -typedef khronos_ssize_t GLsizeiptr; + typedef khronos_ssize_t GLsizeiptr; #else typedef khronos_ssize_t GLsizeiptr; #endif -typedef int64_t GLint64; -typedef uint64_t GLuint64; + typedef int64_t GLint64; + typedef uint64_t GLuint64; #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) -typedef long GLintptrARB; + typedef long GLintptrARB; #else typedef ptrdiff_t GLintptrARB; #endif #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) -typedef long GLsizeiptrARB; + typedef long GLsizeiptrARB; #else typedef ptrdiff_t GLsizeiptrARB; #endif -typedef int64_t GLint64EXT; -typedef uint64_t GLuint64EXT; -typedef struct __GLsync *GLsync; -struct _cl_context; -struct _cl_event; -typedef void (GLAD_API_PTR *GLDEBUGPROC)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); -typedef void (GLAD_API_PTR *GLDEBUGPROCARB)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); -typedef void (GLAD_API_PTR *GLDEBUGPROCKHR)(GLenum source,GLenum type,GLuint id,GLenum severity,GLsizei length,const GLchar *message,const void *userParam); -typedef void (GLAD_API_PTR *GLDEBUGPROCAMD)(GLuint id,GLenum category,GLenum severity,GLsizei length,const GLchar *message,void *userParam); -typedef unsigned short GLhalfNV; -typedef GLintptr GLvdpauSurfaceNV; -typedef void (GLAD_API_PTR *GLVULKANPROCNV)(void); - + typedef int64_t GLint64EXT; + typedef uint64_t GLuint64EXT; + typedef struct __GLsync *GLsync; + struct _cl_context; + struct _cl_event; + typedef void(GLAD_API_PTR *GLDEBUGPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam); + typedef void(GLAD_API_PTR *GLDEBUGPROCARB)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam); + typedef void(GLAD_API_PTR *GLDEBUGPROCKHR)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam); + typedef void(GLAD_API_PTR *GLDEBUGPROCAMD)(GLuint id, GLenum category, GLenum severity, GLsizei length, const GLchar *message, void *userParam); + typedef unsigned short GLhalfNV; + typedef GLintptr GLvdpauSurfaceNV; + typedef void(GLAD_API_PTR *GLVULKANPROCNV)(void); #define GL_VERSION_1_0 1 -GLAD_API_CALL int GLAD_GL_VERSION_1_0; + GLAD_API_CALL int GLAD_GL_VERSION_1_0; #define GL_VERSION_1_1 1 -GLAD_API_CALL int GLAD_GL_VERSION_1_1; + GLAD_API_CALL int GLAD_GL_VERSION_1_1; #define GL_VERSION_1_2 1 -GLAD_API_CALL int GLAD_GL_VERSION_1_2; + GLAD_API_CALL int GLAD_GL_VERSION_1_2; #define GL_VERSION_1_3 1 -GLAD_API_CALL int GLAD_GL_VERSION_1_3; + GLAD_API_CALL int GLAD_GL_VERSION_1_3; #define GL_VERSION_1_4 1 -GLAD_API_CALL int GLAD_GL_VERSION_1_4; + GLAD_API_CALL int GLAD_GL_VERSION_1_4; #define GL_VERSION_1_5 1 -GLAD_API_CALL int GLAD_GL_VERSION_1_5; + GLAD_API_CALL int GLAD_GL_VERSION_1_5; #define GL_VERSION_2_0 1 -GLAD_API_CALL int GLAD_GL_VERSION_2_0; + GLAD_API_CALL int GLAD_GL_VERSION_2_0; #define GL_VERSION_2_1 1 -GLAD_API_CALL int GLAD_GL_VERSION_2_1; + GLAD_API_CALL int GLAD_GL_VERSION_2_1; #define GL_VERSION_3_0 1 -GLAD_API_CALL int GLAD_GL_VERSION_3_0; + GLAD_API_CALL int GLAD_GL_VERSION_3_0; #define GL_VERSION_3_1 1 -GLAD_API_CALL int GLAD_GL_VERSION_3_1; + GLAD_API_CALL int GLAD_GL_VERSION_3_1; #define GL_VERSION_3_2 1 -GLAD_API_CALL int GLAD_GL_VERSION_3_2; + GLAD_API_CALL int GLAD_GL_VERSION_3_2; #define GL_VERSION_3_3 1 -GLAD_API_CALL int GLAD_GL_VERSION_3_3; + GLAD_API_CALL int GLAD_GL_VERSION_3_3; #define GL_VERSION_4_0 1 -GLAD_API_CALL int GLAD_GL_VERSION_4_0; + GLAD_API_CALL int GLAD_GL_VERSION_4_0; #define GL_VERSION_4_1 1 -GLAD_API_CALL int GLAD_GL_VERSION_4_1; + GLAD_API_CALL int GLAD_GL_VERSION_4_1; #define GL_VERSION_4_2 1 -GLAD_API_CALL int GLAD_GL_VERSION_4_2; + GLAD_API_CALL int GLAD_GL_VERSION_4_2; #define GL_VERSION_4_3 1 -GLAD_API_CALL int GLAD_GL_VERSION_4_3; + GLAD_API_CALL int GLAD_GL_VERSION_4_3; #define GL_VERSION_4_4 1 -GLAD_API_CALL int GLAD_GL_VERSION_4_4; + GLAD_API_CALL int GLAD_GL_VERSION_4_4; #define GL_VERSION_4_5 1 -GLAD_API_CALL int GLAD_GL_VERSION_4_5; + GLAD_API_CALL int GLAD_GL_VERSION_4_5; #define GL_VERSION_4_6 1 -GLAD_API_CALL int GLAD_GL_VERSION_4_6; + GLAD_API_CALL int GLAD_GL_VERSION_4_6; #define GL_ARB_point_sprite 1 -GLAD_API_CALL int GLAD_GL_ARB_point_sprite; + GLAD_API_CALL int GLAD_GL_ARB_point_sprite; + typedef void(GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIIVPROC)(GLuint texture, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLTEXCOORDP1UIVPROC)(GLenum type, const GLuint *coords); + typedef void(GLAD_API_PTR *PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC)(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); + typedef void(GLAD_API_PTR *PFNGLEVALPOINT2PROC)(GLint i, GLint j); + typedef void(GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBBINDINGPROC)(GLuint vaobj, GLuint attribindex, GLuint bindingindex); + typedef void(GLAD_API_PTR *PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length); + typedef void(GLAD_API_PTR *PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC)(GLuint framebuffer, GLenum pname, GLint *param); + typedef void(GLAD_API_PTR *PFNGLPIXELTRANSFERFPROC)(GLenum pname, GLfloat param); + typedef void(GLAD_API_PTR *PFNGLGETFLOATI_VPROC)(GLenum target, GLuint index, GLfloat *data); + typedef void(GLAD_API_PTR *PFNGLLOADNAMEPROC)(GLuint name); + typedef void(GLAD_API_PTR *PFNGLUNIFORMMATRIX4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLSECONDARYCOLOR3SVPROC)(const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE1DPROC)(GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); + typedef void(GLAD_API_PTR *PFNGLSECONDARYCOLOR3UIVPROC)(const GLuint *v); + typedef void(GLAD_API_PTR *PFNGLUNIFORM1DVPROC)(GLint location, GLsizei count, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLWINDOWPOS3DVPROC)(const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLSECONDARYCOLOR3BVPROC)(const GLbyte *v); + typedef void(GLAD_API_PTR *PFNGLSECONDARYCOLOR3UIPROC)(GLuint red, GLuint green, GLuint blue); + typedef void(GLAD_API_PTR *PFNGLGETNCOLORTABLEPROC)(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *table); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS3IPROC)(GLint x, GLint y, GLint z); + typedef void(GLAD_API_PTR *PFNGLACTIVETEXTUREPROC)(GLenum texture); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB4NUIVPROC)(GLuint index, const GLuint *v); + typedef void(GLAD_API_PTR *PFNGLCLEARNAMEDBUFFERDATAPROC)(GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); + typedef void(GLAD_API_PTR *PFNGLNORMAL3DPROC)(GLdouble nx, GLdouble ny, GLdouble nz); + typedef void(GLAD_API_PTR *PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC)(GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); + typedef void(GLAD_API_PTR *PFNGLBINDBUFFERSBASEPROC)(GLenum target, GLuint first, GLsizei count, const GLuint *buffers); + typedef void(GLAD_API_PTR *PFNGLEVALCOORD1DPROC)(GLdouble u); + typedef void(GLAD_API_PTR *PFNGLGETMAPFVPROC)(GLenum target, GLenum query, GLfloat *v); + typedef GLboolean(GLAD_API_PTR *PFNGLISSYNCPROC)(GLsync sync); + typedef void(GLAD_API_PTR *PFNGLTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); + typedef GLint(GLAD_API_PTR *PFNGLGETATTRIBLOCATIONPROC)(GLuint program, const GLchar *name); + typedef void(GLAD_API_PTR *PFNGLCOPYTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM4IPROC)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); + typedef void(GLAD_API_PTR *PFNGLGETPIXELMAPFVPROC)(GLenum map, GLfloat *values); + typedef void(GLAD_API_PTR *PFNGLVERTEX4SVPROC)(const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLTEXSTORAGE2DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD2FVPROC)(const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLUNIFORMMATRIX3X2DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLGETVERTEXATTRIBIUIVPROC)(GLuint index, GLenum pname, GLuint *params); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB3SVPROC)(GLuint index, const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices, GLint basevertex); + typedef void(GLAD_API_PTR *PFNGLDEPTHRANGEINDEXEDPROC)(GLuint index, GLdouble n, GLdouble f); + typedef GLboolean(GLAD_API_PTR *PFNGLISQUERYPROC)(GLuint id); + typedef void(GLAD_API_PTR *PFNGLDELETEPROGRAMPIPELINESPROC)(GLsizei n, const GLuint *pipelines); + typedef void(GLAD_API_PTR *PFNGLGETTEXTURELEVELPARAMETERFVPROC)(GLuint texture, GLint level, GLenum pname, GLfloat *params); + typedef void(GLAD_API_PTR *PFNGLUNIFORMMATRIX4X3DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLBLITNAMEDFRAMEBUFFERPROC)(GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORDP1UIPROC)(GLenum texture, GLenum type, GLuint coords); + typedef void(GLAD_API_PTR *PFNGLINDEXSPROC)(GLshort c); + typedef void(GLAD_API_PTR *PFNGLCOLORP3UIPROC)(GLenum type, GLuint color); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORDP4UIPROC)(GLenum texture, GLenum type, GLuint coords); + typedef GLuint(GLAD_API_PTR *PFNGLCREATESHADERPROC)(GLenum type); + typedef void(GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERFIPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); + typedef void(GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC)(GLuint texture, GLint level, GLsizei bufSize, void *pixels); + typedef void(GLAD_API_PTR *PFNGLCOLOR4SVPROC)(const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLDEBUGMESSAGEINSERTPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *buf); + typedef void(GLAD_API_PTR *PFNGLRECTFPROC)(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); + typedef GLuint(GLAD_API_PTR *PFNGLGETDEBUGMESSAGELOGPROC)(GLuint count, GLsizei bufSize, GLenum *sources, GLenum *types, GLuint *ids, GLenum *severities, GLsizei *lengths, GLchar *messageLog); + typedef void(GLAD_API_PTR *PFNGLWINDOWPOS3SPROC)(GLshort x, GLshort y, GLshort z); + typedef GLboolean(GLAD_API_PTR *PFNGLISFRAMEBUFFERPROC)(GLuint framebuffer); + typedef void(GLAD_API_PTR *PFNGLCOPYIMAGESUBDATAPROC)(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); + typedef void(GLAD_API_PTR *PFNGLCOLORPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void *pointer); + typedef void(GLAD_API_PTR *PFNGLUNIFORMMATRIX4X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLGETMATERIALFVPROC)(GLenum face, GLenum pname, GLfloat *params); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD4IVPROC)(GLenum target, const GLint *v); + typedef void(GLAD_API_PTR *PFNGLDELETESAMPLERSPROC)(GLsizei count, const GLuint *samplers); + typedef void(GLAD_API_PTR *PFNGLGETMATERIALIVPROC)(GLenum face, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLBLENDFUNCPROC)(GLenum sfactor, GLenum dfactor); + typedef void(GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC)(GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); + typedef void(GLAD_API_PTR *PFNGLNAMEDBUFFERDATAPROC)(GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); + typedef void(GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSPROC)(GLenum mode, const GLsizei *count, GLenum type, const void *const *indices, GLsizei drawcount); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM3IPROC)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2); + typedef void(GLAD_API_PTR *PFNGLGETPROGRAMSTAGEIVPROC)(GLuint program, GLenum shadertype, GLenum pname, GLint *values); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBLFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); + typedef void(GLAD_API_PTR *PFNGLVERTEX2SVPROC)(const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLRECTSVPROC)(const GLshort *v1, const GLshort *v2); + typedef void(GLAD_API_PTR *PFNGLTEXTURESTORAGE2DPROC)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); + typedef void(GLAD_API_PTR *PFNGLUNIFORM3FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); + typedef void(GLAD_API_PTR *PFNGLDRAWBUFFERPROC)(GLenum buf); + typedef void(GLAD_API_PTR *PFNGLTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); + typedef void(GLAD_API_PTR *PFNGLTEXCOORDP2UIVPROC)(GLenum type, const GLuint *coords); + typedef void(GLAD_API_PTR *PFNGLUNIFORM4FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB2DPROC)(GLuint index, GLdouble x, GLdouble y); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB2FPROC)(GLuint index, GLfloat x, GLfloat y); + typedef void(GLAD_API_PTR *PFNGLSECONDARYCOLOR3UBVPROC)(const GLubyte *v); + typedef void(GLAD_API_PTR *PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint *framebuffers); + typedef void(GLAD_API_PTR *PFNGLCLEARCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + typedef void(GLAD_API_PTR *PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); + typedef void(GLAD_API_PTR *PFNGLGETTEXGENFVPROC)(GLenum coord, GLenum pname, GLfloat *params); + typedef void(GLAD_API_PTR *PFNGLCOLOR4DVPROC)(const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORDP4UIVPROC)(GLenum texture, GLenum type, const GLuint *coords); + typedef void(GLAD_API_PTR *PFNGLACTIVESHADERPROGRAMPROC)(GLuint pipeline, GLuint program); + typedef void(GLAD_API_PTR *PFNGLBEGINCONDITIONALRENDERPROC)(GLuint id, GLenum mode); + typedef void(GLAD_API_PTR *PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); + typedef void(GLAD_API_PTR *PFNGLVIEWPORTINDEXEDFVPROC)(GLuint index, const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLMAPGRID1FPROC)(GLint un, GLfloat u1, GLfloat u2); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD3DPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r); + typedef void(GLAD_API_PTR *PFNGLWINDOWPOS2DVPROC)(const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLGETBUFFERPOINTERVPROC)(GLenum target, GLenum pname, void **params); + typedef void(GLAD_API_PTR *PFNGLTEXGENFVPROC)(GLenum coord, GLenum pname, const GLfloat *params); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBP4UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); + typedef void(GLAD_API_PTR *PFNGLROTATEDPROC)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); + typedef void(GLAD_API_PTR *PFNGLCREATEQUERIESPROC)(GLenum target, GLsizei n, GLuint *ids); + typedef void(GLAD_API_PTR *PFNGLUNIFORMMATRIX3X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLTEXIMAGE1DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void *pixels); + typedef void(GLAD_API_PTR *PFNGLWINDOWPOS3IPROC)(GLint x, GLint y, GLint z); + typedef void(GLAD_API_PTR *PFNGLCLAMPCOLORPROC)(GLenum target, GLenum clamp); + typedef void(GLAD_API_PTR *PFNGLUNIFORMMATRIX4X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLVERTEX4FPROC)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); + typedef void(GLAD_API_PTR *PFNGLNORMAL3FPROC)(GLfloat nx, GLfloat ny, GLfloat nz); + typedef void(GLAD_API_PTR *PFNGLCOLOR3UBPROC)(GLubyte red, GLubyte green, GLubyte blue); + typedef void(GLAD_API_PTR *PFNGLSCISSORINDEXEDPROC)(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); + typedef void(GLAD_API_PTR *PFNGLPUSHCLIENTATTRIBPROC)(GLbitfield mask); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB4DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); + typedef void(GLAD_API_PTR *PFNGLUSEPROGRAMSTAGESPROC)(GLuint pipeline, GLbitfield stages, GLuint program); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD3SPROC)(GLshort s, GLshort t, GLshort r); + typedef void(GLAD_API_PTR *PFNGLLIGHTFPROC)(GLenum light, GLenum pname, GLfloat param); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD3FVPROC)(const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB4NUBVPROC)(GLuint index, const GLubyte *v); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBL2DPROC)(GLuint index, GLdouble x, GLdouble y); + typedef void(GLAD_API_PTR *PFNGLFOGCOORDDPROC)(GLdouble coord); + typedef void(GLAD_API_PTR *PFNGLGETNPIXELMAPUIVPROC)(GLenum map, GLsizei bufSize, GLuint *values); + typedef void(GLAD_API_PTR *PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); + typedef void(GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTIVPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset); + typedef const GLubyte *(GLAD_API_PTR *PFNGLGETSTRINGIPROC)(GLenum name, GLuint index); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS4SPROC)(GLshort x, GLshort y, GLshort z, GLshort w); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBP2UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); + typedef void(GLAD_API_PTR *PFNGLGETQUERYIVPROC)(GLenum target, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLBINDVERTEXARRAYPROC)(GLuint array); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM3DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLTEXPARAMETERFPROC)(GLenum target, GLenum pname, GLfloat param); + typedef void(GLAD_API_PTR *PFNGLWINDOWPOS3DPROC)(GLdouble x, GLdouble y, GLdouble z); + typedef void(GLAD_API_PTR *PFNGLGENERATETEXTUREMIPMAPPROC)(GLuint texture); + typedef void(GLAD_API_PTR *PFNGLDELETESYNCPROC)(GLsync sync); + typedef void(GLAD_API_PTR *PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer); + typedef void(GLAD_API_PTR *PFNGLPUSHDEBUGGROUPPROC)(GLenum source, GLuint id, GLsizei length, const GLchar *message); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS2IPROC)(GLint x, GLint y); + typedef void(GLAD_API_PTR *PFNGLBINDIMAGETEXTUREPROC)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); + typedef void(GLAD_API_PTR *PFNGLFEEDBACKBUFFERPROC)(GLsizei size, GLenum type, GLfloat *buffer); + typedef void(GLAD_API_PTR *PFNGLEVALMESH2PROC)(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); + typedef void(GLAD_API_PTR *PFNGLLINKPROGRAMPROC)(GLuint program); + typedef void(GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); + typedef void(GLAD_API_PTR *PFNGLPUSHMATRIXPROC)(void); + typedef void(GLAD_API_PTR *PFNGLFRAMEBUFFERPARAMETERIPROC)(GLenum target, GLenum pname, GLint param); + typedef void(GLAD_API_PTR *PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName); + typedef void(GLAD_API_PTR *PFNGLUNIFORM3DPROC)(GLint location, GLdouble x, GLdouble y, GLdouble z); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB4UBVPROC)(GLuint index, const GLubyte *v); + typedef void(GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void *data); + typedef void(GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKI64_VPROC)(GLuint xfb, GLenum pname, GLuint index, GLint64 *param); + typedef void(GLAD_API_PTR *PFNGLCOMPILESHADERPROC)(GLuint shader); + typedef void(GLAD_API_PTR *PFNGLGETLIGHTFVPROC)(GLenum light, GLenum pname, GLfloat *params); + typedef void(GLAD_API_PTR *PFNGLPIXELMAPUSVPROC)(GLenum map, GLsizei mapsize, const GLushort *values); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS4IPROC)(GLint x, GLint y, GLint z, GLint w); + typedef void(GLAD_API_PTR *PFNGLUNIFORMMATRIX4X2DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE1DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + typedef void(GLAD_API_PTR *PFNGLINITNAMESPROC)(void); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBI1UIPROC)(GLuint index, GLuint x); + typedef void(GLAD_API_PTR *PFNGLCLEARBUFFERIVPROC)(GLenum buffer, GLint drawbuffer, const GLint *value); + typedef void(GLAD_API_PTR *PFNGLMAP1FPROC)(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat *points); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLGETVERTEXATTRIBFVPROC)(GLuint index, GLenum pname, GLfloat *params); + typedef void(GLAD_API_PTR *PFNGLGETACTIVEUNIFORMBLOCKIVPROC)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + typedef void(GLAD_API_PTR *PFNGLGETVERTEXARRAYINDEXEDIVPROC)(GLuint vaobj, GLuint index, GLenum pname, GLint *param); + typedef void(GLAD_API_PTR *PFNGLVERTEXARRAYELEMENTBUFFERPROC)(GLuint vaobj, GLuint buffer); + typedef void(GLAD_API_PTR *PFNGLGETTEXGENDVPROC)(GLenum coord, GLenum pname, GLdouble *params); + typedef void(GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERFVPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLSECONDARYCOLOR3FPROC)(GLfloat red, GLfloat green, GLfloat blue); + typedef void(GLAD_API_PTR *PFNGLSHADERBINARYPROC)(GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length); + typedef void(GLAD_API_PTR *PFNGLMAP1DPROC)(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *points); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBL2DVPROC)(GLuint index, const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD4DPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD1DVPROC)(const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLTEXSTORAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); + typedef void(GLAD_API_PTR *PFNGLGENTRANSFORMFEEDBACKSPROC)(GLsizei n, GLuint *ids); + typedef void(GLAD_API_PTR *PFNGLCLEARBUFFERSUBDATAPROC)(GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLGETFRAMEBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLPIXELMAPFVPROC)(GLenum map, GLsizei mapsize, const GLfloat *values); + typedef void(GLAD_API_PTR *PFNGLCOLOR3FPROC)(GLfloat red, GLfloat green, GLfloat blue); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLMULTMATRIXDPROC)(const GLdouble *m); + typedef void(GLAD_API_PTR *PFNGLCOPYPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); + typedef void(GLAD_API_PTR *PFNGLUNIFORM2DVPROC)(GLint location, GLsizei count, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLCOLOR3SVPROC)(const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLOBJECTLABELPROC)(GLenum identifier, GLuint name, GLsizei length, const GLchar *label); + typedef void(GLAD_API_PTR *PFNGLGETOBJECTLABELPROC)(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei *length, GLchar *label); + typedef void(GLAD_API_PTR *PFNGLINDEXFVPROC)(const GLfloat *c); + typedef void(GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); + typedef void(GLAD_API_PTR *PFNGLMAPGRID1DPROC)(GLint un, GLdouble u1, GLdouble u2); + typedef void(GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTUIVPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS3SVPROC)(const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLSELECTBUFFERPROC)(GLsizei size, GLuint *buffer); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBI3IVPROC)(GLuint index, const GLint *v); + typedef void(GLAD_API_PTR *PFNGLPATCHPARAMETERIPROC)(GLenum pname, GLint value); + typedef void(GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIUIVPROC)(GLuint texture, GLenum pname, GLuint *params); + typedef void(GLAD_API_PTR *PFNGLCOLOR3IVPROC)(const GLint *v); + typedef void *(GLAD_API_PTR *PFNGLMAPBUFFERPROC)(GLenum target, GLenum access); + typedef void(GLAD_API_PTR *PFNGLNORMALP3UIPROC)(GLenum type, GLuint coords); + typedef void(GLAD_API_PTR *PFNGLVERTEXPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void *pointer); + typedef void(GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERFVPROC)(GLuint texture, GLenum pname, GLfloat *params); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer); + typedef void(GLAD_API_PTR *PFNGLDEPTHRANGEFPROC)(GLfloat n, GLfloat f); + typedef void(GLAD_API_PTR *PFNGLTEXTUREPARAMETERIVPROC)(GLuint texture, GLenum pname, const GLint *param); + typedef void(GLAD_API_PTR *PFNGLVERTEXP2UIVPROC)(GLenum type, const GLuint *value); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBI4USVPROC)(GLuint index, const GLushort *v); + typedef void(GLAD_API_PTR *PFNGLTEXPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint *params); + typedef void(GLAD_API_PTR *PFNGLBINDVERTEXBUFFERSPROC)(GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); + typedef void(GLAD_API_PTR *PFNGLVERTEXP3UIVPROC)(GLenum type, const GLuint *value); + typedef void(GLAD_API_PTR *PFNGLINDEXIPROC)(GLint c); + typedef void(GLAD_API_PTR *PFNGLGETACTIVESUBROUTINENAMEPROC)(GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); + typedef void(GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data); + typedef void(GLAD_API_PTR *PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint index, GLenum pname, void **pointer); + typedef void(GLAD_API_PTR *PFNGLGETPIXELMAPUIVPROC)(GLenum map, GLuint *values); + typedef void(GLAD_API_PTR *PFNGLGETTEXGENIVPROC)(GLenum coord, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB3SPROC)(GLuint index, GLshort x, GLshort y, GLshort z); + typedef void(GLAD_API_PTR *PFNGLPOINTSIZEPROC)(GLfloat size); + typedef void(GLAD_API_PTR *PFNGLVERTEXP2UIPROC)(GLenum type, GLuint value); + typedef void(GLAD_API_PTR *PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC)(GLenum mode, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); + typedef void(GLAD_API_PTR *PFNGLGETNTEXIMAGEPROC)(GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); + typedef void(GLAD_API_PTR *PFNGLCULLFACEPROC)(GLenum mode); + typedef void(GLAD_API_PTR *PFNGLSAMPLERPARAMETERIPROC)(GLuint sampler, GLenum pname, GLint param); + typedef void(GLAD_API_PTR *PFNGLTEXTUREBARRIERPROC)(void); + typedef GLboolean(GLAD_API_PTR *PFNGLISRENDERBUFFERPROC)(GLuint renderbuffer); + typedef void(GLAD_API_PTR *PFNGLBEGINQUERYPROC)(GLenum target, GLuint id); + typedef void(GLAD_API_PTR *PFNGLCOLOR4USPROC)(GLushort red, GLushort green, GLushort blue, GLushort alpha); + typedef void(GLAD_API_PTR *PFNGLGETVERTEXATTRIBDVPROC)(GLuint index, GLenum pname, GLdouble *params); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD4IVPROC)(const GLint *v); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM1FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint *textures); + typedef void(GLAD_API_PTR *PFNGLWINDOWPOS2IVPROC)(const GLint *v); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBIPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); + typedef void(GLAD_API_PTR *PFNGLCREATEVERTEXARRAYSPROC)(GLsizei n, GLuint *arrays); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBI1IPROC)(GLuint index, GLint x); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM3UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); + typedef void(GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data); + typedef void(GLAD_API_PTR *PFNGLRECTDPROC)(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); + typedef void(GLAD_API_PTR *PFNGLMULTTRANSPOSEMATRIXDPROC)(const GLdouble *m); + typedef void(GLAD_API_PTR *PFNGLTEXENVFPROC)(GLenum target, GLenum pname, GLfloat param); + typedef void(GLAD_API_PTR *PFNGLNORMAL3IPROC)(GLint nx, GLint ny, GLint nz); + typedef void(GLAD_API_PTR *PFNGLBINDATTRIBLOCATIONPROC)(GLuint program, GLuint index, const GLchar *name); + typedef void(GLAD_API_PTR *PFNGLSTENCILMASKSEPARATEPROC)(GLenum face, GLuint mask); + typedef void(GLAD_API_PTR *PFNGLGETINTEGERVPROC)(GLenum pname, GLint *data); + typedef void(GLAD_API_PTR *PFNGLUSEPROGRAMPROC)(GLuint program); + typedef void(GLAD_API_PTR *PFNGLNORMAL3BVPROC)(const GLbyte *v); + typedef void(GLAD_API_PTR *PFNGLPIXELSTOREIPROC)(GLenum pname, GLint param); + typedef void(GLAD_API_PTR *PFNGLNORMAL3SPROC)(GLshort nx, GLshort ny, GLshort nz); + typedef void(GLAD_API_PTR *PFNGLCOLOR4IVPROC)(const GLint *v); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORDP2UIVPROC)(GLenum texture, GLenum type, const GLuint *coords); + typedef GLboolean(GLAD_API_PTR *PFNGLARETEXTURESRESIDENTPROC)(GLsizei n, const GLuint *textures, GLboolean *residences); + typedef void(GLAD_API_PTR *PFNGLGETUNIFORMFVPROC)(GLuint program, GLint location, GLfloat *params); + typedef void(GLAD_API_PTR *PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC)(GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei *length, GLchar *name); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLTEXSTORAGE3DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD1IPROC)(GLint s); + typedef void(GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void *pixels); + typedef void(GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXBUFFERSPROC)(GLuint vaobj, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizei *strides); + typedef void(GLAD_API_PTR *PFNGLSECONDARYCOLOR3DPROC)(GLdouble red, GLdouble green, GLdouble blue); + typedef void(GLAD_API_PTR *PFNGLINTERLEAVEDARRAYSPROC)(GLenum format, GLsizei stride, const void *pointer); + typedef GLboolean(GLAD_API_PTR *PFNGLUNMAPBUFFERPROC)(GLenum target); + typedef GLboolean(GLAD_API_PTR *PFNGLISENABLEDIPROC)(GLenum target, GLuint index); + typedef void(GLAD_API_PTR *PFNGLBINDSAMPLERSPROC)(GLuint first, GLsizei count, const GLuint *samplers); + typedef void(GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); + typedef void(GLAD_API_PTR *PFNGLPRIORITIZETEXTURESPROC)(GLsizei n, const GLuint *textures, const GLfloat *priorities); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS4DPROC)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); + typedef void(GLAD_API_PTR *PFNGLSECONDARYCOLOR3USVPROC)(const GLushort *v); + typedef void(GLAD_API_PTR *PFNGLGETSYNCIVPROC)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, GLint *values); + typedef void(GLAD_API_PTR *PFNGLSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, const GLint *param); + typedef void(GLAD_API_PTR *PFNGLLIGHTMODELFVPROC)(GLenum pname, const GLfloat *params); + typedef void(GLAD_API_PTR *PFNGLTEXTURESTORAGE3DPROC)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); + typedef void(GLAD_API_PTR *PFNGLRESUMETRANSFORMFEEDBACKPROC)(void); + typedef void(GLAD_API_PTR *PFNGLGENPROGRAMPIPELINESPROC)(GLsizei n, GLuint *pipelines); + typedef void(GLAD_API_PTR *PFNGLVERTEX4FVPROC)(const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLLIGHTIVPROC)(GLenum light, GLenum pname, const GLint *params); + typedef void(GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERIVPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint *value); + typedef void(GLAD_API_PTR *PFNGLGETTEXPARAMETERIVPROC)(GLenum target, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD3DVPROC)(const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLFOGCOORDPOINTERPROC)(GLenum type, GLsizei stride, const void *pointer); + typedef void(GLAD_API_PTR *PFNGLUNIFORM2IPROC)(GLint location, GLint v0, GLint v1); + typedef void(GLAD_API_PTR *PFNGLTEXTURESUBIMAGE3DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); + typedef void(GLAD_API_PTR *PFNGLGETDOUBLEI_VPROC)(GLenum target, GLuint index, GLdouble *data); + typedef void(GLAD_API_PTR *PFNGLCLEARBUFFERDATAPROC)(GLenum target, GLenum internalformat, GLenum format, GLenum type, const void *data); + typedef void(GLAD_API_PTR *PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture); + typedef void(GLAD_API_PTR *PFNGLTEXTUREBUFFERRANGEPROC)(GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); + typedef void(GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERFVPROC)(GLenum target, GLint level, GLenum pname, GLfloat *params); + typedef void(GLAD_API_PTR *PFNGLSAMPLEMASKIPROC)(GLuint maskNumber, GLbitfield mask); + typedef void(GLAD_API_PTR *PFNGLCLEARACCUMPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + typedef void(GLAD_API_PTR *PFNGLGETACTIVEUNIFORMPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); + typedef void(GLAD_API_PTR *PFNGLGETPROGRAMBINARYPROC)(GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary); + typedef void(GLAD_API_PTR *PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB4SPROC)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); + typedef void(GLAD_API_PTR *PFNGLTEXTUREPARAMETERIPROC)(GLuint texture, GLenum pname, GLint param); + typedef void(GLAD_API_PTR *PFNGLCOLOR3DVPROC)(const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLBINDSAMPLERPROC)(GLuint unit, GLuint sampler); + typedef GLenum(GLAD_API_PTR *PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC)(GLuint framebuffer, GLenum target); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM1IVPROC)(GLuint program, GLint location, GLsizei count, const GLint *value); + typedef void(GLAD_API_PTR *PFNGLMULTIDRAWARRAYSPROC)(GLenum mode, const GLint *first, const GLsizei *count, GLsizei drawcount); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS4DVPROC)(const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLGETFLOATVPROC)(GLenum pname, GLfloat *data); + typedef void(GLAD_API_PTR *PFNGLPROGRAMPARAMETERIPROC)(GLuint program, GLenum pname, GLint value); + typedef void(GLAD_API_PTR *PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint *renderbuffers); + typedef void(GLAD_API_PTR *PFNGLSECONDARYCOLORPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void *pointer); + typedef GLboolean(GLAD_API_PTR *PFNGLISSAMPLERPROC)(GLuint sampler); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD1DVPROC)(GLenum target, const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLDEBUGMESSAGECONTROLPROC)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled); + typedef void(GLAD_API_PTR *PFNGLBINDBUFFERSRANGEPROC)(GLenum target, GLuint first, GLsizei count, const GLuint *buffers, const GLintptr *offsets, const GLsizeiptr *sizes); + typedef void(GLAD_API_PTR *PFNGLMULTIDRAWARRAYSINDIRECTPROC)(GLenum mode, const void *indirect, GLsizei drawcount, GLsizei stride); + typedef void(GLAD_API_PTR *PFNGLGETMAPDVPROC)(GLenum target, GLenum query, GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLTEXCOORDP3UIPROC)(GLenum type, GLuint coords); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBIFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); + typedef void(GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC)(GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); + typedef void(GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC)(GLuint xfb, GLuint index, GLuint buffer); + typedef void(GLAD_API_PTR *PFNGLGETTEXENVIVPROC)(GLenum target, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLCOLORP3UIVPROC)(GLenum type, const GLuint *color); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB1FPROC)(GLuint index, GLfloat x); + typedef void(GLAD_API_PTR *PFNGLPOPCLIENTATTRIBPROC)(void); + typedef void(GLAD_API_PTR *PFNGLGETTEXIMAGEPROC)(GLenum target, GLint level, GLenum format, GLenum type, void *pixels); + typedef void(GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); + typedef void(GLAD_API_PTR *PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint *buffers); + typedef GLenum(GLAD_API_PTR *PFNGLCLIENTWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM1DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLCLEARTEXIMAGEPROC)(GLuint texture, GLint level, GLenum format, GLenum type, const void *data); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD2FVPROC)(GLenum target, const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLUNIFORM3UIVPROC)(GLint location, GLsizei count, const GLuint *value); + typedef void(GLAD_API_PTR *PFNGLGETACTIVEUNIFORMNAMEPROC)(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformName); + typedef void(GLAD_API_PTR *PFNGLEVALPOINT1PROC)(GLint i); + typedef void(GLAD_API_PTR *PFNGLCOLOR3USPROC)(GLushort red, GLushort green, GLushort blue); + typedef void(GLAD_API_PTR *PFNGLGETTEXTURESUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void *pixels); + typedef void(GLAD_API_PTR *PFNGLCOLOR3IPROC)(GLint red, GLint green, GLint blue); + typedef void(GLAD_API_PTR *PFNGLSECONDARYCOLOR3DVPROC)(const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLEVALCOORD1FVPROC)(const GLfloat *u); + typedef void(GLAD_API_PTR *PFNGLVIEWPORTARRAYVPROC)(GLuint first, GLsizei count, const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBI4IPROC)(GLuint index, GLint x, GLint y, GLint z, GLint w); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBL4DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); + typedef void(GLAD_API_PTR *PFNGLCOLOR4DPROC)(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); + typedef GLint(GLAD_API_PTR *PFNGLGETFRAGDATALOCATIONPROC)(GLuint program, const GLchar *name); + typedef void(GLAD_API_PTR *PFNGLCOLOR4UBVPROC)(const GLubyte *v); + typedef void(GLAD_API_PTR *PFNGLUNIFORMMATRIX4DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLUNIFORMMATRIX3X4DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLSCISSORPROC)(GLint x, GLint y, GLsizei width, GLsizei height); + typedef void(GLAD_API_PTR *PFNGLUNIFORMSUBROUTINESUIVPROC)(GLenum shadertype, GLsizei count, const GLuint *indices); + typedef void(GLAD_API_PTR *PFNGLVERTEX4IVPROC)(const GLint *v); + typedef void(GLAD_API_PTR *PFNGLCOLORMASKPROC)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); + typedef void(GLAD_API_PTR *PFNGLSTENCILOPSEPARATEPROC)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); + typedef void(GLAD_API_PTR *PFNGLGETBOOLEANVPROC)(GLenum pname, GLboolean *data); + typedef void(GLAD_API_PTR *PFNGLVERTEX3DPROC)(GLdouble x, GLdouble y, GLdouble z); + typedef void(GLAD_API_PTR *PFNGLGETNAMEDBUFFERPOINTERVPROC)(GLuint buffer, GLenum pname, void **params); + typedef void(GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXBUFFERPROC)(GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); + typedef void(GLAD_API_PTR *PFNGLGETPOLYGONSTIPPLEPROC)(GLubyte *mask); + typedef void(GLAD_API_PTR *PFNGLSTENCILOPPROC)(GLenum fail, GLenum zfail, GLenum zpass); + typedef void(GLAD_API_PTR *PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height); + typedef void(GLAD_API_PTR *PFNGLGETNPOLYGONSTIPPLEPROC)(GLsizei bufSize, GLubyte *pattern); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB4USVPROC)(GLuint index, const GLushort *v); + typedef void(GLAD_API_PTR *PFNGLENDTRANSFORMFEEDBACKPROC)(void); + typedef GLuint(GLAD_API_PTR *PFNGLCREATEPROGRAMPROC)(void); + typedef void(GLAD_API_PTR *PFNGLGETSHADERINFOLOGPROC)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog); + typedef void(GLAD_API_PTR *PFNGLGETVERTEXARRAYINDEXED64IVPROC)(GLuint vaobj, GLuint index, GLenum pname, GLint64 *param); + typedef void(GLAD_API_PTR *PFNGLTEXGENDPROC)(GLenum coord, GLenum pname, GLdouble param); + typedef void(GLAD_API_PTR *PFNGLINDEXUBPROC)(GLubyte c); + typedef void(GLAD_API_PTR *PFNGLMULTMATRIXFPROC)(const GLfloat *m); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORDP2UIPROC)(GLenum texture, GLenum type, GLuint coords); + typedef void(GLAD_API_PTR *PFNGLTEXIMAGE3DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels); + typedef void(GLAD_API_PTR *PFNGLGETNUNIFORMDVPROC)(GLuint program, GLint location, GLsizei bufSize, GLdouble *params); + typedef void(GLAD_API_PTR *PFNGLRECTIVPROC)(const GLint *v1, const GLint *v2); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD4SPROC)(GLshort s, GLshort t, GLshort r, GLshort q); + typedef void(GLAD_API_PTR *PFNGLCOPYTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); + typedef void(GLAD_API_PTR *PFNGLLOGICOPPROC)(GLenum opcode); + typedef void(GLAD_API_PTR *PFNGLUNIFORMMATRIX2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLSECONDARYCOLOR3FVPROC)(const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM4UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint *value); + typedef void(GLAD_API_PTR *PFNGLCREATESAMPLERSPROC)(GLsizei n, GLuint *samplers); + typedef void(GLAD_API_PTR *PFNGLPIXELMAPUIVPROC)(GLenum map, GLsizei mapsize, const GLuint *values); + typedef void(GLAD_API_PTR *PFNGLBLENDCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + typedef void(GLAD_API_PTR *PFNGLLIGHTMODELIPROC)(GLenum pname, GLint param); + typedef void(GLAD_API_PTR *PFNGLPOINTPARAMETERIPROC)(GLenum pname, GLint param); + typedef void(GLAD_API_PTR *PFNGLGENQUERIESPROC)(GLsizei n, GLuint *ids); + typedef void(GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERTEXTUREPROC)(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); + typedef void(GLAD_API_PTR *PFNGLGETNSEPARABLEFILTERPROC)(GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void *row, GLsizei columnBufSize, void *column, void *span); + typedef void(GLAD_API_PTR *PFNGLGETQUERYOBJECTUIVPROC)(GLuint id, GLenum pname, GLuint *params); + typedef void(GLAD_API_PTR *PFNGLCOLOR4FVPROC)(const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLGETVERTEXARRAYIVPROC)(GLuint vaobj, GLenum pname, GLint *param); + typedef void(GLAD_API_PTR *PFNGLUNIFORM1UIPROC)(GLint location, GLuint v0); + typedef void(GLAD_API_PTR *PFNGLGETNMAPFVPROC)(GLenum target, GLenum query, GLsizei bufSize, GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLUNIFORM4FVPROC)(GLint location, GLsizei count, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLTEXGENFPROC)(GLenum coord, GLenum pname, GLfloat param); + typedef void(GLAD_API_PTR *PFNGLINDEXIVPROC)(const GLint *c); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB1FVPROC)(GLuint index, const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD3IPROC)(GLenum target, GLint s, GLint t, GLint r); + typedef void(GLAD_API_PTR *PFNGLCOLOR4USVPROC)(const GLushort *v); + typedef void(GLAD_API_PTR *PFNGLDRAWBUFFERSPROC)(GLsizei n, const GLenum *bufs); + typedef void(GLAD_API_PTR *PFNGLWINDOWPOS2IPROC)(GLint x, GLint y); + typedef void(GLAD_API_PTR *PFNGLTEXBUFFERRANGEPROC)(GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORDP1UIVPROC)(GLenum texture, GLenum type, const GLuint *coords); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBI2IVPROC)(GLuint index, const GLint *v); + typedef void(GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSINDIRECTPROC)(GLenum mode, GLenum type, const void *indirect, GLsizei drawcount, GLsizei stride); + typedef void(GLAD_API_PTR *PFNGLUNIFORMMATRIX2X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLUNIFORM3IPROC)(GLint location, GLint v0, GLint v1, GLint v2); + typedef void(GLAD_API_PTR *PFNGLGETCLIPPLANEPROC)(GLenum plane, GLdouble *equation); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBP2UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD2IPROC)(GLint s, GLint t); + typedef void(GLAD_API_PTR *PFNGLUNIFORM4UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + typedef void(GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB4NUSVPROC)(GLuint index, const GLushort *v); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB1DPROC)(GLuint index, GLdouble x); + typedef void(GLAD_API_PTR *PFNGLGETLIGHTIVPROC)(GLenum light, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLTEXTURESTORAGE1DPROC)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); + typedef void(GLAD_API_PTR *PFNGLSTENCILMASKPROC)(GLuint mask); + typedef void(GLAD_API_PTR *PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD4FPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); + typedef void(GLAD_API_PTR *PFNGLINDEXDPROC)(GLdouble c); + typedef void(GLAD_API_PTR *PFNGLNORMALP3UIVPROC)(GLenum type, const GLuint *coords); + typedef void(GLAD_API_PTR *PFNGLEVALMESH1PROC)(GLenum mode, GLint i1, GLint i2); + typedef void(GLAD_API_PTR *PFNGLTEXCOORDP3UIVPROC)(GLenum type, const GLuint *coords); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBL4DVPROC)(GLuint index, const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLCLIENTACTIVETEXTUREPROC)(GLenum texture); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB2SPROC)(GLuint index, GLshort x, GLshort y); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB3DVPROC)(GLuint index, const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, const GLint *params); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS3DPROC)(GLdouble x, GLdouble y, GLdouble z); + typedef void(GLAD_API_PTR *PFNGLEVALCOORD2FVPROC)(const GLfloat *u); + typedef void(GLAD_API_PTR *PFNGLBINDTEXTUREUNITPROC)(GLuint unit, GLuint texture); + typedef void(GLAD_API_PTR *PFNGLWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); + typedef void(GLAD_API_PTR *PFNGLMATERIALFVPROC)(GLenum face, GLenum pname, const GLfloat *params); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM2IPROC)(GLuint program, GLint location, GLint v0, GLint v1); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS2SPROC)(GLshort x, GLshort y); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBI4BVPROC)(GLuint index, const GLbyte *v); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBI4SVPROC)(GLuint index, const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum modeRGB, GLenum modeAlpha); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBI3UIVPROC)(GLuint index, const GLuint *v); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBI2UIVPROC)(GLuint index, const GLuint *v); + typedef void(GLAD_API_PTR *PFNGLVERTEXP4UIVPROC)(GLenum type, const GLuint *value); + typedef GLuint(GLAD_API_PTR *PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint program, const GLchar *uniformBlockName); + typedef void(GLAD_API_PTR *PFNGLDEPTHFUNCPROC)(GLenum func); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM4FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); + typedef void(GLAD_API_PTR *PFNGLSHADERSOURCEPROC)(GLuint shader, GLsizei count, const GLchar *const *string, const GLint *length); + typedef void(GLAD_API_PTR *PFNGLVERTEX2IVPROC)(const GLint *v); + typedef void *(GLAD_API_PTR *PFNGLMAPNAMEDBUFFERPROC)(GLuint buffer, GLenum access); + typedef void(GLAD_API_PTR *PFNGLCLEARDEPTHFPROC)(GLfloat d); + typedef void(GLAD_API_PTR *PFNGLUNIFORM1FPROC)(GLint location, GLfloat v0); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD1DPROC)(GLenum target, GLdouble s); + typedef void(GLAD_API_PTR *PFNGLGETQUERYOBJECTUI64VPROC)(GLuint id, GLenum pname, GLuint64 *params); + typedef void(GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC)(GLuint framebuffer, GLsizei n, const GLenum *bufs); + typedef void(GLAD_API_PTR *PFNGLTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels); + typedef void(GLAD_API_PTR *PFNGLDELETETRANSFORMFEEDBACKSPROC)(GLsizei n, const GLuint *ids); + typedef void(GLAD_API_PTR *PFNGLVERTEX3IVPROC)(const GLint *v); + typedef void(GLAD_API_PTR *PFNGLUNIFORMMATRIX2X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef GLboolean(GLAD_API_PTR *PFNGLISTEXTUREPROC)(GLuint texture); + typedef void(GLAD_API_PTR *PFNGLMULTTRANSPOSEMATRIXFPROC)(const GLfloat *m); + typedef void(GLAD_API_PTR *PFNGLNEWLISTPROC)(GLuint list, GLenum mode); + typedef void(GLAD_API_PTR *PFNGLSCALEFPROC)(GLfloat x, GLfloat y, GLfloat z); + typedef void(GLAD_API_PTR *PFNGLVERTEX3FPROC)(GLfloat x, GLfloat y, GLfloat z); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD1IVPROC)(const GLint *v); + typedef void(GLAD_API_PTR *PFNGLFOGCOORDFVPROC)(const GLfloat *coord); + typedef void(GLAD_API_PTR *PFNGLMAPGRID2DPROC)(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); + typedef void(GLAD_API_PTR *PFNGLWINDOWPOS2FVPROC)(const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLREADPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels); + typedef void(GLAD_API_PTR *PFNGLINVALIDATETEXSUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); + typedef void(GLAD_API_PTR *PFNGLORTHOPROC)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); + typedef void(GLAD_API_PTR *PFNGLGETQUERYOBJECTIVPROC)(GLuint id, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLWINDOWPOS2SVPROC)(const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLFOGFPROC)(GLenum pname, GLfloat param); + typedef void(GLAD_API_PTR *PFNGLCOLOR3SPROC)(GLshort red, GLshort green, GLshort blue); + typedef void(GLAD_API_PTR *PFNGLUNIFORM2UIVPROC)(GLint location, GLsizei count, const GLuint *value); + typedef void(GLAD_API_PTR *PFNGLPIXELZOOMPROC)(GLfloat xfactor, GLfloat yfactor); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM3FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); + typedef void(GLAD_API_PTR *PFNGLEVALCOORD2DVPROC)(const GLdouble *u); + typedef void(GLAD_API_PTR *PFNGLVERTEX3DVPROC)(const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLUNIFORM3FVPROC)(GLint location, GLsizei count, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLENABLEPROC)(GLenum cap); + typedef void(GLAD_API_PTR *PFNGLTEXTUREPARAMETERIUIVPROC)(GLuint texture, GLenum pname, const GLuint *params); + typedef void(GLAD_API_PTR *PFNGLFOGCOORDDVPROC)(const GLdouble *coord); + typedef void(GLAD_API_PTR *PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const void *data, GLenum usage); + typedef void(GLAD_API_PTR *PFNGLPOPATTRIBPROC)(void); + typedef void(GLAD_API_PTR *PFNGLNORMAL3DVPROC)(const GLdouble *v); + typedef GLint(GLAD_API_PTR *PFNGLGETFRAGDATAINDEXPROC)(GLuint program, const GLchar *name); + typedef void(GLAD_API_PTR *PFNGLPASSTHROUGHPROC)(GLfloat token); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD2DVPROC)(const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLTEXCOORDP4UIVPROC)(GLenum type, const GLuint *coords); + typedef void(GLAD_API_PTR *PFNGLCLEARBUFFERUIVPROC)(GLenum buffer, GLint drawbuffer, const GLuint *value); + typedef void(GLAD_API_PTR *PFNGLUNIFORM3DVPROC)(GLint location, GLsizei count, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLBLENDEQUATIONIPROC)(GLuint buf, GLenum mode); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); + typedef void(GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERIVPROC)(GLenum target, GLint level, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLVERTEX4IPROC)(GLint x, GLint y, GLint z, GLint w); + typedef void(GLAD_API_PTR *PFNGLUNIFORM4UIVPROC)(GLint location, GLsizei count, const GLuint *value); + typedef void(GLAD_API_PTR *PFNGLTEXENVFVPROC)(GLenum target, GLenum pname, const GLfloat *params); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD4DVPROC)(GLenum target, const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLCLEARTEXSUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *data); + typedef void(GLAD_API_PTR *PFNGLTRANSLATEDPROC)(GLdouble x, GLdouble y, GLdouble z); + typedef void(GLAD_API_PTR *PFNGLPOINTPARAMETERFPROC)(GLenum pname, GLfloat param); + typedef void(GLAD_API_PTR *PFNGLSCISSORINDEXEDVPROC)(GLuint index, const GLint *v); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM2DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLREADBUFFERPROC)(GLenum src); + typedef void(GLAD_API_PTR *PFNGLENDPROC)(void); + typedef void(GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB4UIVPROC)(GLuint index, const GLuint *v); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBI4UBVPROC)(GLuint index, const GLubyte *v); + typedef void(GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC)(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void *data); + typedef void(GLAD_API_PTR *PFNGLVERTEX2DVPROC)(const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLPUSHNAMEPROC)(GLuint name); + typedef void(GLAD_API_PTR *PFNGLINVALIDATEBUFFERDATAPROC)(GLuint buffer); + typedef void(GLAD_API_PTR *PFNGLPOINTPARAMETERIVPROC)(GLenum pname, const GLint *params); + typedef void(GLAD_API_PTR *PFNGLGENTEXTURESPROC)(GLsizei n, GLuint *textures); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD4FVPROC)(const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLDISPATCHCOMPUTEPROC)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); + typedef void(GLAD_API_PTR *PFNGLGETUNIFORMUIVPROC)(GLuint program, GLint location, GLuint *params); + typedef void(GLAD_API_PTR *PFNGLGETACTIVEUNIFORMSIVPROC)(GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLGETPROGRAMRESOURCENAMEPROC)(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name); + typedef void(GLAD_API_PTR *PFNGLVERTEX2FVPROC)(const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLCOLOR4UBPROC)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); + typedef void(GLAD_API_PTR *PFNGLUNIFORM3IVPROC)(GLint location, GLsizei count, const GLint *value); + typedef void(GLAD_API_PTR *PFNGLCLIPPLANEPROC)(GLenum plane, const GLdouble *equation); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLUNIFORM4IPROC)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); + typedef void(GLAD_API_PTR *PFNGLWINDOWPOS3IVPROC)(const GLint *v); + typedef void(GLAD_API_PTR *PFNGLSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, const GLint *param); + typedef void(GLAD_API_PTR *PFNGLUNIFORM2DPROC)(GLint location, GLdouble x, GLdouble y); + typedef void(GLAD_API_PTR *PFNGLPOPMATRIXPROC)(void); + typedef void(GLAD_API_PTR *PFNGLVALIDATEPROGRAMPIPELINEPROC)(GLuint pipeline); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS3DVPROC)(const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD1FVPROC)(const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD2IVPROC)(const GLint *v); + typedef void(GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE2DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); + typedef void(GLAD_API_PTR *PFNGLGETATTACHEDSHADERSPROC)(GLuint program, GLsizei maxCount, GLsizei *count, GLuint *shaders); + typedef void(GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKI_VPROC)(GLuint xfb, GLenum pname, GLuint index, GLint *param); + typedef void(GLAD_API_PTR *PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum target, GLenum attachment, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBIFORMATPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); + typedef void(GLAD_API_PTR *PFNGLOBJECTPTRLABELPROC)(const void *ptr, GLsizei length, const GLchar *label); + typedef void(GLAD_API_PTR *PFNGLGETNPIXELMAPUSVPROC)(GLenum map, GLsizei bufSize, GLushort *values); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM1FPROC)(GLuint program, GLint location, GLfloat v0); + typedef void(GLAD_API_PTR *PFNGLCLEARSTENCILPROC)(GLint s); + typedef void(GLAD_API_PTR *PFNGLDISABLEPROC)(GLenum cap); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB4FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); + typedef GLuint(GLAD_API_PTR *PFNGLGETSUBROUTINEINDEXPROC)(GLuint program, GLenum shadertype, const GLchar *name); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD2DPROC)(GLenum target, GLdouble s, GLdouble t); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORDP3UIVPROC)(GLenum texture, GLenum type, const GLuint *coords); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD3FVPROC)(GLenum target, const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLUNIFORM4IVPROC)(GLint location, GLsizei count, const GLint *value); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBDIVISORPROC)(GLuint index, GLuint divisor); + typedef void(GLAD_API_PTR *PFNGLBINDFRAGDATALOCATIONPROC)(GLuint program, GLuint color, const GLchar *name); + typedef void(GLAD_API_PTR *PFNGLGETNCOMPRESSEDTEXIMAGEPROC)(GLenum target, GLint lod, GLsizei bufSize, void *pixels); + typedef void(GLAD_API_PTR *PFNGLUNIFORMMATRIX3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB2FVPROC)(GLuint index, const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLEVALCOORD2DPROC)(GLdouble u, GLdouble v); + typedef void(GLAD_API_PTR *PFNGLGETPOINTERVPROC)(GLenum pname, void **params); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM4DPROC)(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD2FPROC)(GLfloat s, GLfloat t); + typedef void(GLAD_API_PTR *PFNGLCOPYBUFFERSUBDATAPROC)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + typedef void(GLAD_API_PTR *PFNGLUNIFORMMATRIX3DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLSECONDARYCOLOR3IVPROC)(const GLint *v); + typedef void(GLAD_API_PTR *PFNGLFINISHPROC)(void); + typedef GLboolean(GLAD_API_PTR *PFNGLISPROGRAMPIPELINEPROC)(GLuint pipeline); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBP1UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); + typedef void(GLAD_API_PTR *PFNGLGETNMAPDVPROC)(GLenum target, GLenum query, GLsizei bufSize, GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLBINDTEXTURESPROC)(GLuint first, GLsizei count, const GLuint *textures); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORDP3UIPROC)(GLenum texture, GLenum type, GLuint coords); + typedef void(GLAD_API_PTR *PFNGLCOLORMASKIPROC)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); + typedef void(GLAD_API_PTR *PFNGLGETQUERYOBJECTI64VPROC)(GLuint id, GLenum pname, GLint64 *params); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD3SPROC)(GLenum target, GLshort s, GLshort t, GLshort r); + typedef void(GLAD_API_PTR *PFNGLWINDOWPOS2DPROC)(GLdouble x, GLdouble y); + typedef void(GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); + typedef void(GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKPROC)(GLenum mode, GLuint id); + typedef void(GLAD_API_PTR *PFNGLWINDOWPOS2FPROC)(GLfloat x, GLfloat y); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBLPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD4FPROC)(GLfloat s, GLfloat t, GLfloat r, GLfloat q); + typedef void(GLAD_API_PTR *PFNGLLIGHTMODELIVPROC)(GLenum pname, const GLint *params); + typedef void(GLAD_API_PTR *PFNGLUNIFORM2UIPROC)(GLint location, GLuint v0, GLuint v1); + typedef void(GLAD_API_PTR *PFNGLDELETEVERTEXARRAYSPROC)(GLsizei n, const GLuint *arrays); + typedef void(GLAD_API_PTR *PFNGLTEXBUFFERPROC)(GLenum target, GLenum internalformat, GLuint buffer); + typedef void(GLAD_API_PTR *PFNGLUNIFORM2FPROC)(GLint location, GLfloat v0, GLfloat v1); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD1DPROC)(GLdouble s); + typedef void(GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void *data); + typedef GLenum(GLAD_API_PTR *PFNGLGETGRAPHICSRESETSTATUSPROC)(void); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD1SPROC)(GLshort s); + typedef void(GLAD_API_PTR *PFNGLINDEXSVPROC)(const GLshort *c); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS4IVPROC)(const GLint *v); + typedef void(GLAD_API_PTR *PFNGLSECONDARYCOLOR3IPROC)(GLint red, GLint green, GLint blue); + typedef void(GLAD_API_PTR *PFNGLCALLLISTPROC)(GLuint list); + typedef void(GLAD_API_PTR *PFNGLINDEXUBVPROC)(const GLubyte *c); + typedef void(GLAD_API_PTR *PFNGLPOLYGONMODEPROC)(GLenum face, GLenum mode); + typedef void(GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTUREPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level); + typedef void(GLAD_API_PTR *PFNGLUNIFORMMATRIX3X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef GLboolean(GLAD_API_PTR *PFNGLISTRANSFORMFEEDBACKPROC)(GLuint id); + typedef void(GLAD_API_PTR *PFNGLNAMEDBUFFERSUBDATAPROC)(GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); + typedef void(GLAD_API_PTR *PFNGLGETPROGRAMINTERFACEIVPROC)(GLuint program, GLenum programInterface, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLDISABLECLIENTSTATEPROC)(GLenum array); + typedef void(GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint *value); + typedef void(GLAD_API_PTR *PFNGLGETTEXPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat *params); + typedef void(GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBLFORMATPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); + typedef void(GLAD_API_PTR *PFNGLVERTEX4DPROC)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); + typedef void(GLAD_API_PTR *PFNGLNORMAL3SVPROC)(const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS4FPROC)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); + typedef void(GLAD_API_PTR *PFNGLTEXCOORDP4UIPROC)(GLenum type, GLuint coords); + typedef void(GLAD_API_PTR *PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint *renderbuffers); + typedef void(GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKVARYINGSPROC)(GLuint program, GLsizei count, const GLchar *const *varyings, GLenum bufferMode); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM4FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC)(GLuint framebuffer, GLenum src); + typedef void(GLAD_API_PTR *PFNGLUNIFORMMATRIX2X3DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBL3DVPROC)(GLuint index, const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLUNIFORM1UIVPROC)(GLint location, GLsizei count, const GLuint *value); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD1SVPROC)(const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLGETINTEGERI_VPROC)(GLenum target, GLuint index, GLint *data); + typedef void(GLAD_API_PTR *PFNGLTEXTURESUBIMAGE2DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); + typedef void(GLAD_API_PTR *PFNGLNAMEDRENDERBUFFERSTORAGEPROC)(GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); + typedef void(GLAD_API_PTR *PFNGLGETMAPIVPROC)(GLenum target, GLenum query, GLint *v); + typedef void(GLAD_API_PTR *PFNGLMATRIXMODEPROC)(GLenum mode); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIVPROC)(GLuint index, const GLuint *v); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBL1DVPROC)(GLuint index, const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLGETNAMEDBUFFERSUBDATAPROC)(GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); + typedef void(GLAD_API_PTR *PFNGLGENVERTEXARRAYSPROC)(GLsizei n, GLuint *arrays); + typedef void(GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIVPROC)(GLuint texture, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLVERTEX3FVPROC)(const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLMATERIALIVPROC)(GLenum face, GLenum pname, const GLint *params); + typedef void(GLAD_API_PTR *PFNGLPIXELTRANSFERIPROC)(GLenum pname, GLint param); + typedef void(GLAD_API_PTR *PFNGLGETNHISTOGRAMPROC)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); + typedef GLuint(GLAD_API_PTR *PFNGLCREATESHADERPROGRAMVPROC)(GLenum type, GLsizei count, const GLchar *const *strings); + typedef void(GLAD_API_PTR *PFNGLENABLEVERTEXARRAYATTRIBPROC)(GLuint vaobj, GLuint index); + typedef void(GLAD_API_PTR *PFNGLENDCONDITIONALRENDERPROC)(void); + typedef void(GLAD_API_PTR *PFNGLDELETELISTSPROC)(GLuint list, GLsizei range); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD2SVPROC)(const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLDEBUGMESSAGECALLBACKPROC)(GLDEBUGPROC callback, const void *userParam); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD1FPROC)(GLenum target, GLfloat s); + typedef void(GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXIMAGEPROC)(GLenum target, GLint level, void *img); + typedef GLenum(GLAD_API_PTR *PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target); + typedef void(GLAD_API_PTR *PFNGLGETINTERNALFORMATI64VPROC)(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 *params); + typedef void(GLAD_API_PTR *PFNGLGENERATEMIPMAPPROC)(GLenum target); + typedef void(GLAD_API_PTR *PFNGLDELETEQUERIESPROC)(GLsizei n, const GLuint *ids); + typedef void(GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC)(GLuint framebuffer, GLenum pname, GLint param); + typedef void(GLAD_API_PTR *PFNGLDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLint basevertex); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM1DPROC)(GLuint program, GLint location, GLdouble v0); + typedef void(GLAD_API_PTR *PFNGLALPHAFUNCPROC)(GLenum func, GLfloat ref); + typedef void(GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC)(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); + typedef void(GLAD_API_PTR *PFNGLLINESTIPPLEPROC)(GLint factor, GLushort pattern); + typedef void(GLAD_API_PTR *PFNGLTEXGENIPROC)(GLenum coord, GLenum pname, GLint param); + typedef void(GLAD_API_PTR *PFNGLTEXSTORAGE3DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); + typedef GLboolean(GLAD_API_PTR *PFNGLISVERTEXARRAYPROC)(GLuint array); + typedef void(GLAD_API_PTR *PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC)(GLuint renderbuffer, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLINVALIDATEFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum *attachments); + typedef void(GLAD_API_PTR *PFNGLPROGRAMBINARYPROC)(GLuint program, GLenum binaryFormat, const void *binary, GLsizei length); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD4DVPROC)(const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLVERTEX3IPROC)(GLint x, GLint y, GLint z); + typedef void(GLAD_API_PTR *PFNGLSECONDARYCOLOR3BPROC)(GLbyte red, GLbyte green, GLbyte blue); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS4SVPROC)(const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLDISABLEIPROC)(GLenum target, GLuint index); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB1SVPROC)(GLuint index, const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLINVALIDATETEXIMAGEPROC)(GLuint texture, GLint level); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBI2IPROC)(GLuint index, GLint x, GLint y); + typedef void(GLAD_API_PTR *PFNGLINDEXFPROC)(GLfloat c); + typedef void(GLAD_API_PTR *PFNGLPRIMITIVERESTARTINDEXPROC)(GLuint index); + typedef void(GLAD_API_PTR *PFNGLGETNCONVOLUTIONFILTERPROC)(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void *image); + typedef GLenum(GLAD_API_PTR *PFNGLGETERRORPROC)(void); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB4BVPROC)(GLuint index, const GLbyte *v); + typedef void(GLAD_API_PTR *PFNGLFLUSHMAPPEDBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length); + typedef void(GLAD_API_PTR *PFNGLTEXCOORDP1UIPROC)(GLenum type, GLuint coords); + typedef void(GLAD_API_PTR *PFNGLSAMPLECOVERAGEPROC)(GLfloat value, GLboolean invert); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD2IVPROC)(GLenum target, const GLint *v); + typedef GLboolean(GLAD_API_PTR *PFNGLISPROGRAMPROC)(GLuint program); + typedef GLboolean(GLAD_API_PTR *PFNGLISLISTPROC)(GLuint list); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB2DVPROC)(GLuint index, const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB3FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z); + typedef void(GLAD_API_PTR *PFNGLTEXPARAMETERIPROC)(GLenum target, GLenum pname, GLint param); + typedef void(GLAD_API_PTR *PFNGLPUSHATTRIBPROC)(GLbitfield mask); + typedef void(GLAD_API_PTR *PFNGLFRONTFACEPROC)(GLenum mode); + typedef void(GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLuint baseinstance); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD1SPROC)(GLenum target, GLshort s); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBI3IPROC)(GLuint index, GLint x, GLint y, GLint z); + typedef void(GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); + typedef void(GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE3DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); + typedef void(GLAD_API_PTR *PFNGLGENSAMPLERSPROC)(GLsizei count, GLuint *samplers); + typedef void(GLAD_API_PTR *PFNGLSAMPLERPARAMETERFPROC)(GLuint sampler, GLenum pname, GLfloat param); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS4FVPROC)(const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLPAUSETRANSFORMFEEDBACKPROC)(void); + typedef void(GLAD_API_PTR *PFNGLPOPNAMEPROC)(void); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBI1IVPROC)(GLuint index, const GLint *v); + typedef void(GLAD_API_PTR *PFNGLEVALCOORD1FPROC)(GLfloat u); + typedef void(GLAD_API_PTR *PFNGLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint *framebuffers); + typedef void(GLAD_API_PTR *PFNGLLIGHTIPROC)(GLenum light, GLenum pname, GLint param); + typedef void(GLAD_API_PTR *PFNGLTEXTUREVIEWPROC)(GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); + typedef void(GLAD_API_PTR *PFNGLLOADTRANSPOSEMATRIXDPROC)(const GLdouble *m); + typedef void(GLAD_API_PTR *PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLuint framebuffer, GLenum attachment, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLUNIFORM4DPROC)(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBI3UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z); + typedef void(GLAD_API_PTR *PFNGLEDGEFLAGPOINTERPROC)(GLsizei stride, const void *pointer); + typedef void(GLAD_API_PTR *PFNGLSTENCILFUNCPROC)(GLenum func, GLint ref, GLuint mask); + typedef void(GLAD_API_PTR *PFNGLUNIFORM1IPROC)(GLint location, GLint v0); + typedef void(GLAD_API_PTR *PFNGLGETTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, GLuint *params); + typedef void(GLAD_API_PTR *PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC)(GLuint framebuffer, GLsizei numAttachments, const GLenum *attachments); + typedef void(GLAD_API_PTR *PFNGLPATCHPARAMETERFVPROC)(GLenum pname, const GLfloat *values); + typedef void(GLAD_API_PTR *PFNGLFOGFVPROC)(GLenum pname, const GLfloat *params); + typedef void(GLAD_API_PTR *PFNGLVERTEXP3UIPROC)(GLenum type, GLuint value); + typedef void(GLAD_API_PTR *PFNGLREADNPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void *data); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD1IPROC)(GLenum target, GLint s); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBBINDINGPROC)(GLuint attribindex, GLuint bindingindex); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD3DVPROC)(GLenum target, const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLVERTEX4SPROC)(GLshort x, GLshort y, GLshort z, GLshort w); + typedef void(GLAD_API_PTR *PFNGLVERTEXBINDINGDIVISORPROC)(GLuint bindingindex, GLuint divisor); + typedef void(GLAD_API_PTR *PFNGLTEXTUREPARAMETERFVPROC)(GLuint texture, GLenum pname, const GLfloat *param); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLNORMAL3BPROC)(GLbyte nx, GLbyte ny, GLbyte nz); + typedef void(GLAD_API_PTR *PFNGLGETUNIFORMSUBROUTINEUIVPROC)(GLenum shadertype, GLint location, GLuint *params); + typedef void(GLAD_API_PTR *PFNGLVERTEX3SVPROC)(const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD3SVPROC)(GLenum target, const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLGETNAMEDBUFFERPARAMETERI64VPROC)(GLuint buffer, GLenum pname, GLint64 *params); + typedef void(GLAD_API_PTR *PFNGLDRAWPIXELSPROC)(GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); + typedef void(GLAD_API_PTR *PFNGLCALLLISTSPROC)(GLsizei n, GLenum type, const void *lists); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD3IPROC)(GLint s, GLint t, GLint r); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM2UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1); + typedef void(GLAD_API_PTR *PFNGLQUERYCOUNTERPROC)(GLuint id, GLenum target); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLUNIFORM1IVPROC)(GLint location, GLsizei count, const GLint *value); + typedef void(GLAD_API_PTR *PFNGLSTENCILFUNCSEPARATEPROC)(GLenum face, GLenum func, GLint ref, GLuint mask); + typedef void(GLAD_API_PTR *PFNGLGETNAMEDBUFFERPARAMETERIVPROC)(GLuint buffer, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLGETACTIVEATTRIBPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name); + typedef void(GLAD_API_PTR *PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index); + typedef void(GLAD_API_PTR *PFNGLMATERIALIPROC)(GLenum face, GLenum pname, GLint param); + typedef void(GLAD_API_PTR *PFNGLUNIFORM2FVPROC)(GLint location, GLsizei count, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS3FVPROC)(const GLfloat *v); + typedef GLint(GLAD_API_PTR *PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC)(GLuint program, GLenum programInterface, const GLchar *name); + typedef void(GLAD_API_PTR *PFNGLGETDOUBLEVPROC)(GLenum pname, GLdouble *data); + typedef void(GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount, GLint basevertex); + typedef void(GLAD_API_PTR *PFNGLUNIFORMMATRIX2X4DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLCOLOR4BVPROC)(const GLbyte *v); + typedef void(GLAD_API_PTR *PFNGLGETINTERNALFORMATIVPROC)(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint *params); + typedef void(GLAD_API_PTR *PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC)(GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint *values); + typedef void(GLAD_API_PTR *PFNGLGETQUERYINDEXEDIVPROC)(GLenum target, GLuint index, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLBINDVERTEXBUFFERPROC)(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD3FPROC)(GLfloat s, GLfloat t, GLfloat r); + typedef void(GLAD_API_PTR *PFNGLCOLOR3UIVPROC)(const GLuint *v); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB4NBVPROC)(GLuint index, const GLbyte *v); + typedef void(GLAD_API_PTR *PFNGLCLEARPROC)(GLbitfield mask); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS2DVPROC)(const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD2SPROC)(GLshort s, GLshort t); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBP4UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); + typedef void(GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURELAYERPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); + typedef void(GLAD_API_PTR *PFNGLTEXENVIPROC)(GLenum target, GLenum pname, GLint param); + typedef void(GLAD_API_PTR *PFNGLTEXTUREPARAMETERFPROC)(GLuint texture, GLenum pname, GLfloat param); + typedef void(GLAD_API_PTR *PFNGLMATERIALFPROC)(GLenum face, GLenum pname, GLfloat param); + typedef void(GLAD_API_PTR *PFNGLGETUNIFORMDVPROC)(GLuint program, GLint location, GLdouble *params); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM3IVPROC)(GLuint program, GLint location, GLsizei count, const GLint *value); + typedef void(GLAD_API_PTR *PFNGLTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, const GLuint *params); + typedef void(GLAD_API_PTR *PFNGLCLEARINDEXPROC)(GLfloat c); + typedef void(GLAD_API_PTR *PFNGLDISPATCHCOMPUTEINDIRECTPROC)(GLintptr indirect); + typedef void(GLAD_API_PTR *PFNGLROTATEFPROC)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); + typedef void(GLAD_API_PTR *PFNGLTEXTURESUBIMAGE1DPROC)(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void *pixels); + typedef void(GLAD_API_PTR *PFNGLPOLYGONOFFSETCLAMPPROC)(GLfloat factor, GLfloat units, GLfloat clamp); + typedef void(GLAD_API_PTR *PFNGLSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, const GLuint *param); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM4IVPROC)(GLuint program, GLint location, GLsizei count, const GLint *value); + typedef void(GLAD_API_PTR *PFNGLSECONDARYCOLOR3SPROC)(GLshort red, GLshort green, GLshort blue); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLGETVERTEXATTRIBLDVPROC)(GLuint index, GLenum pname, GLdouble *params); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS2FVPROC)(const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLSHADEMODELPROC)(GLenum mode); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM4DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLNORMAL3FVPROC)(const GLfloat *v); + typedef GLboolean(GLAD_API_PTR *PFNGLISBUFFERPROC)(GLuint buffer); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD3FPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r); + typedef void(GLAD_API_PTR *PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer); + typedef void(GLAD_API_PTR *PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)(GLuint program, GLuint colorNumber, GLuint index, const GLchar *name); + typedef void(GLAD_API_PTR *PFNGLBINDBUFFERBASEPROC)(GLenum target, GLuint index, GLuint buffer); + typedef void(GLAD_API_PTR *PFNGLGENBUFFERSPROC)(GLsizei n, GLuint *buffers); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD1FPROC)(GLfloat s); + typedef void(GLAD_API_PTR *PFNGLGETBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, void *data); + typedef void(GLAD_API_PTR *PFNGLCREATETRANSFORMFEEDBACKSPROC)(GLsizei n, GLuint *ids); + typedef void(GLAD_API_PTR *PFNGLMAP2FPROC)(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat *points); + typedef void(GLAD_API_PTR *PFNGLCREATEBUFFERSPROC)(GLsizei n, GLuint *buffers); + typedef void(GLAD_API_PTR *PFNGLCOLOR3USVPROC)(const GLushort *v); + typedef void(GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, GLfloat *params); + typedef GLint(GLAD_API_PTR *PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar *name); + typedef void(GLAD_API_PTR *PFNGLVERTEX2DPROC)(GLdouble x, GLdouble y); + typedef GLint(GLAD_API_PTR *PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC)(GLuint program, GLenum shadertype, const GLchar *name); + typedef void(GLAD_API_PTR *PFNGLINVALIDATEBUFFERSUBDATAPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length); + typedef void(GLAD_API_PTR *PFNGLUNIFORMMATRIX2DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLCLEARNAMEDBUFFERSUBDATAPROC)(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); + typedef void(GLAD_API_PTR *PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void *indices); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLGETINTEGER64I_VPROC)(GLenum target, GLuint index, GLint64 *data); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBL1DPROC)(GLuint index, GLdouble x); + typedef void(GLAD_API_PTR *PFNGLGETTEXTUREIMAGEPROC)(GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void *pixels); + typedef void(GLAD_API_PTR *PFNGLGETNUNIFORMIVPROC)(GLuint program, GLint location, GLsizei bufSize, GLint *params); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM1IPROC)(GLuint program, GLint location, GLint v0); + typedef void(GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC)(GLenum mode, GLuint id, GLsizei instancecount); + typedef GLuint(GLAD_API_PTR *PFNGLGETPROGRAMRESOURCEINDEXPROC)(GLuint program, GLenum programInterface, const GLchar *name); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM2DPROC)(GLuint program, GLint location, GLdouble v0, GLdouble v1); + typedef GLboolean(GLAD_API_PTR *PFNGLUNMAPNAMEDBUFFERPROC)(GLuint buffer); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD2FPROC)(GLenum target, GLfloat s, GLfloat t); + typedef void(GLAD_API_PTR *PFNGLPOINTPARAMETERFVPROC)(GLenum pname, const GLfloat *params); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLBINDBUFFERRANGEPROC)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD2DVPROC)(GLenum target, const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLCOLORMATERIALPROC)(GLenum face, GLenum mode); + typedef void(GLAD_API_PTR *PFNGLBLENDEQUATIONPROC)(GLenum mode); + typedef void(GLAD_API_PTR *PFNGLBLITFRAMEBUFFERPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + typedef void(GLAD_API_PTR *PFNGLCOLOR3DPROC)(GLdouble red, GLdouble green, GLdouble blue); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD3IVPROC)(GLenum target, const GLint *v); + typedef void(GLAD_API_PTR *PFNGLLIGHTFVPROC)(GLenum light, GLenum pname, const GLfloat *params); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB1DVPROC)(GLuint index, const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLDEPTHMASKPROC)(GLboolean flag); + typedef void(GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLsizei *size, GLenum *type, GLchar *name); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM1UIPROC)(GLuint program, GLint location, GLuint v0); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBL3DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z); + typedef void(GLAD_API_PTR *PFNGLDRAWELEMENTSINDIRECTPROC)(GLenum mode, GLenum type, const void *indirect); + typedef void(GLAD_API_PTR *PFNGLLOADTRANSPOSEMATRIXFPROC)(const GLfloat *m); + typedef void(GLAD_API_PTR *PFNGLENDQUERYINDEXEDPROC)(GLenum target, GLuint index); + typedef void(GLAD_API_PTR *PFNGLSECONDARYCOLOR3USPROC)(GLushort red, GLushort green, GLushort blue); + typedef void(GLAD_API_PTR *PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC)(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); + typedef void(GLAD_API_PTR *PFNGLPIXELSTOREFPROC)(GLenum pname, GLfloat param); + typedef void(GLAD_API_PTR *PFNGLUNIFORM2IVPROC)(GLint location, GLsizei count, const GLint *value); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS2SVPROC)(const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLVERTEX2IPROC)(GLint x, GLint y); + typedef void(GLAD_API_PTR *PFNGLFRUSTUMPROC)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); + typedef void(GLAD_API_PTR *PFNGLMEMORYBARRIERPROC)(GLbitfield barriers); + typedef const GLubyte *(GLAD_API_PTR *PFNGLGETSTRINGPROC)(GLenum name); + typedef void(GLAD_API_PTR *PFNGLLINEWIDTHPROC)(GLfloat width); + typedef void(GLAD_API_PTR *PFNGLNORMALPOINTERPROC)(GLenum type, GLsizei stride, const void *pointer); + typedef void(GLAD_API_PTR *PFNGLGETNUNIFORMUIVPROC)(GLuint program, GLint location, GLsizei bufSize, GLuint *params); + typedef void(GLAD_API_PTR *PFNGLDEPTHRANGEARRAYVPROC)(GLuint first, GLsizei count, const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLTEXCOORDP2UIPROC)(GLenum type, GLuint coords); + typedef void(GLAD_API_PTR *PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader); + typedef void(GLAD_API_PTR *PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count); + typedef void(GLAD_API_PTR *PFNGLCOLOR4SPROC)(GLshort red, GLshort green, GLshort blue, GLshort alpha); + typedef void(GLAD_API_PTR *PFNGLTEXGENDVPROC)(GLenum coord, GLenum pname, const GLdouble *params); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, GLuint *params); + typedef void(GLAD_API_PTR *PFNGLENDQUERYPROC)(GLenum target); + typedef void(GLAD_API_PTR *PFNGLWINDOWPOS2SPROC)(GLshort x, GLshort y); + typedef void(GLAD_API_PTR *PFNGLDRAWARRAYSINDIRECTPROC)(GLenum mode, const void *indirect); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS3SPROC)(GLshort x, GLshort y, GLshort z); + typedef void(GLAD_API_PTR *PFNGLGETNPIXELMAPFVPROC)(GLenum map, GLsizei bufSize, GLfloat *values); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD3SVPROC)(const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLRECTIPROC)(GLint x1, GLint y1, GLint x2, GLint y2); + typedef void(GLAD_API_PTR *PFNGLUNIFORM4DVPROC)(GLint location, GLsizei count, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEIPROC)(GLuint buf, GLenum modeRGB, GLenum modeAlpha); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM3FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLGETPROGRAMRESOURCEIVPROC)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params); + typedef void(GLAD_API_PTR *PFNGLINVALIDATESUBFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum *attachments, GLint x, GLint y, GLsizei width, GLsizei height); + typedef GLsync(GLAD_API_PTR *PFNGLFENCESYNCPROC)(GLenum condition, GLbitfield flags); + typedef void(GLAD_API_PTR *PFNGLUNIFORM3UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2); + typedef void(GLAD_API_PTR *PFNGLSECONDARYCOLORP3UIVPROC)(GLenum type, const GLuint *color); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB1SPROC)(GLuint index, GLshort x); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB4NSVPROC)(GLuint index, const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLLOADMATRIXFPROC)(const GLfloat *m); + typedef void(GLAD_API_PTR *PFNGLTRANSLATEFPROC)(GLfloat x, GLfloat y, GLfloat z); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD4SVPROC)(GLenum target, const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM2IVPROC)(GLuint program, GLint location, GLsizei count, const GLint *value); + typedef void(GLAD_API_PTR *PFNGLMAPGRID2FPROC)(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); + typedef void(GLAD_API_PTR *PFNGLENABLECLIENTSTATEPROC)(GLenum array); + typedef void(GLAD_API_PTR *PFNGLGETUNIFORMIVPROC)(GLuint program, GLint location, GLint *params); + typedef void(GLAD_API_PTR *PFNGLEVALCOORD1DVPROC)(const GLdouble *u); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBI4IVPROC)(GLuint index, const GLint *v); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB4SVPROC)(GLuint index, const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLGETMULTISAMPLEFVPROC)(GLenum pname, GLuint index, GLfloat *val); + typedef void(GLAD_API_PTR *PFNGLINDEXDVPROC)(const GLdouble *c); + typedef void(GLAD_API_PTR *PFNGLBLENDFUNCIPROC)(GLuint buf, GLenum src, GLenum dst); + typedef GLboolean(GLAD_API_PTR *PFNGLISENABLEDPROC)(GLenum cap); + typedef void(GLAD_API_PTR *PFNGLGETPIXELMAPUSVPROC)(GLenum map, GLushort *values); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS3IVPROC)(const GLint *v); + typedef void *(GLAD_API_PTR *PFNGLMAPBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD2SPROC)(GLenum target, GLshort s, GLshort t); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS2FPROC)(GLfloat x, GLfloat y); + typedef void(GLAD_API_PTR *PFNGLMINSAMPLESHADINGPROC)(GLfloat value); + typedef void(GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTUI64VPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD2IPROC)(GLenum target, GLint s, GLint t); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBP3UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value); + typedef void(GLAD_API_PTR *PFNGLVERTEX2FPROC)(GLfloat x, GLfloat y); + typedef void(GLAD_API_PTR *PFNGLVERTEXARRAYBINDINGDIVISORPROC)(GLuint vaobj, GLuint bindingindex, GLuint divisor); + typedef void(GLAD_API_PTR *PFNGLINDEXPOINTERPROC)(GLenum type, GLsizei stride, const void *pointer); + typedef void(GLAD_API_PTR *PFNGLUNIFORMBLOCKBINDINGPROC)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); + typedef GLint(GLAD_API_PTR *PFNGLRENDERMODEPROC)(GLenum mode); + typedef void(GLAD_API_PTR *PFNGLTEXSTORAGE1DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); + typedef void(GLAD_API_PTR *PFNGLBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, const void *data); + typedef void(GLAD_API_PTR *PFNGLCOLOR3FVPROC)(const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLBITMAPPROC)(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte *bitmap); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM3UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint *value); + typedef void(GLAD_API_PTR *PFNGLVIEWPORTINDEXEDFPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS2DPROC)(GLdouble x, GLdouble y); + typedef void(GLAD_API_PTR *PFNGLGETUNIFORMINDICESPROC)(GLuint program, GLsizei uniformCount, const GLchar *const *uniformNames, GLuint *uniformIndices); + typedef void(GLAD_API_PTR *PFNGLENABLEIPROC)(GLenum target, GLuint index); + typedef void(GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); + typedef void(GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); + typedef void(GLAD_API_PTR *PFNGLNAMEDBUFFERSTORAGEPROC)(GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); + typedef void(GLAD_API_PTR *PFNGLRECTSPROC)(GLshort x1, GLshort y1, GLshort x2, GLshort y2); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM2FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLPOLYGONSTIPPLEPROC)(const GLubyte *mask); + typedef void(GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + typedef void(GLAD_API_PTR *PFNGLSECONDARYCOLOR3UBPROC)(GLubyte red, GLubyte green, GLubyte blue); + typedef void(GLAD_API_PTR *PFNGLWINDOWPOS3FPROC)(GLfloat x, GLfloat y, GLfloat z); + typedef void(GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLSHADERSTORAGEBLOCKBINDINGPROC)(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); + typedef void(GLAD_API_PTR *PFNGLLOADIDENTITYPROC)(void); + typedef void(GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, const GLsizei *count, GLenum type, const void *const *indices, GLsizei drawcount, const GLint *basevertex); + typedef void(GLAD_API_PTR *PFNGLVERTEX2SPROC)(GLshort x, GLshort y); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD1IVPROC)(GLenum target, const GLint *v); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD4SPROC)(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); + typedef void(GLAD_API_PTR *PFNGLRELEASESHADERCOMPILERPROC)(void); + typedef void(GLAD_API_PTR *PFNGLGETSHADERSOURCEPROC)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD2SVPROC)(GLenum target, const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLTEXPARAMETERFVPROC)(GLenum target, GLenum pname, const GLfloat *params); + typedef GLboolean(GLAD_API_PTR *PFNGLISSHADERPROC)(GLuint shader); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB4IVPROC)(GLuint index, const GLint *v); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD4IPROC)(GLint s, GLint t, GLint r, GLint q); + typedef void(GLAD_API_PTR *PFNGLCOLOR4UIPROC)(GLuint red, GLuint green, GLuint blue, GLuint alpha); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLGETTEXENVFVPROC)(GLenum target, GLenum pname, GLfloat *params); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD4DPROC)(GLdouble s, GLdouble t, GLdouble r, GLdouble q); + typedef void(GLAD_API_PTR *PFNGLSCISSORARRAYVPROC)(GLuint first, GLsizei count, const GLint *v); + typedef void(GLAD_API_PTR *PFNGLCREATERENDERBUFFERSPROC)(GLsizei n, GLuint *renderbuffers); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB3FVPROC)(GLuint index, const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLCOLOR4FPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB4NUBPROC)(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); + typedef void(GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); + typedef void(GLAD_API_PTR *PFNGLNORMAL3IVPROC)(const GLint *v); + typedef void(GLAD_API_PTR *PFNGLBINDIMAGETEXTURESPROC)(GLuint first, GLsizei count, const GLuint *textures); + typedef void(GLAD_API_PTR *PFNGLTEXGENIVPROC)(GLenum coord, GLenum pname, const GLint *params); + typedef void(GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE3DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void *data); + typedef void(GLAD_API_PTR *PFNGLSCALEDPROC)(GLdouble x, GLdouble y, GLdouble z); + typedef void(GLAD_API_PTR *PFNGLCREATEPROGRAMPIPELINESPROC)(GLsizei n, GLuint *pipelines); + typedef void(GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEIPROC)(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); + typedef void(GLAD_API_PTR *PFNGLHINTPROC)(GLenum target, GLenum mode); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD4IPROC)(GLenum target, GLint s, GLint t, GLint r, GLint q); + typedef void(GLAD_API_PTR *PFNGLINDEXMASKPROC)(GLuint mask); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM2FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1); + typedef void(GLAD_API_PTR *PFNGLCOLOR3BPROC)(GLbyte red, GLbyte green, GLbyte blue); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBI1UIVPROC)(GLuint index, const GLuint *v); + typedef void(GLAD_API_PTR *PFNGLSPECIALIZESHADERPROC)(GLuint shader, const GLchar *pEntryPoint, GLuint numSpecializationConstants, const GLuint *pConstantIndex, const GLuint *pConstantValue); + typedef void(GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC)(GLuint framebuffer, GLenum buf); + typedef void(GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTI64VPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD3IVPROC)(const GLint *v); + typedef void(GLAD_API_PTR *PFNGLSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, const GLfloat *param); + typedef void(GLAD_API_PTR *PFNGLGETVERTEXATTRIBIIVPROC)(GLuint index, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLBUFFERSTORAGEPROC)(GLenum target, GLsizeiptr size, const void *data, GLbitfield flags); + typedef void(GLAD_API_PTR *PFNGLVERTEX3SPROC)(GLshort x, GLshort y, GLshort z); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM2UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint *value); + typedef void(GLAD_API_PTR *PFNGLDEPTHRANGEPROC)(GLdouble n, GLdouble f); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS3FPROC)(GLfloat x, GLfloat y, GLfloat z); + typedef void(GLAD_API_PTR *PFNGLDELETESHADERPROC)(GLuint shader); + typedef void(GLAD_API_PTR *PFNGLCOLOR3BVPROC)(const GLbyte *v); + typedef void(GLAD_API_PTR *PFNGLCOLOR3UBVPROC)(const GLubyte *v); + typedef void(GLAD_API_PTR *PFNGLGETVERTEXATTRIBIVPROC)(GLuint index, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD4SVPROC)(const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLMAP2DPROC)(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble *points); + typedef void(GLAD_API_PTR *PFNGLFOGCOORDFPROC)(GLfloat coord); + typedef void(GLAD_API_PTR *PFNGLEDGEFLAGVPROC)(const GLboolean *flag); + typedef void(GLAD_API_PTR *PFNGLCLIPCONTROLPROC)(GLenum origin, GLenum depth); + typedef void(GLAD_API_PTR *PFNGLGETBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKIVPROC)(GLuint xfb, GLenum pname, GLint *param); + typedef void(GLAD_API_PTR *PFNGLGETPROGRAMPIPELINEIVPROC)(GLuint pipeline, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLGETNMINMAXPROC)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void *values); + typedef void(GLAD_API_PTR *PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + typedef void(GLAD_API_PTR *PFNGLCOLORP4UIPROC)(GLenum type, GLuint color); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD1SVPROC)(GLenum target, const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB4FVPROC)(GLuint index, const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB4DVPROC)(GLuint index, const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLVERTEXP4UIPROC)(GLenum type, GLuint value); + typedef void(GLAD_API_PTR *PFNGLRECTFVPROC)(const GLfloat *v1, const GLfloat *v2); + typedef void(GLAD_API_PTR *PFNGLBEGINTRANSFORMFEEDBACKPROC)(GLenum primitiveMode); + typedef void(GLAD_API_PTR *PFNGLARRAYELEMENTPROC)(GLint i); + typedef void(GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC)(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); + typedef void(GLAD_API_PTR *PFNGLBEGINPROC)(GLenum mode); + typedef void(GLAD_API_PTR *PFNGLTEXCOORDPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void *pointer); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD3DPROC)(GLdouble s, GLdouble t, GLdouble r); + typedef void(GLAD_API_PTR *PFNGLUNIFORM1FVPROC)(GLint location, GLsizei count, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB2SVPROC)(GLuint index, const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLGETPROGRAMPIPELINEINFOLOGPROC)(GLuint pipeline, GLsizei bufSize, GLsizei *length, GLchar *infoLog); + typedef void(GLAD_API_PTR *PFNGLPOLYGONOFFSETPROC)(GLfloat factor, GLfloat units); + typedef void(GLAD_API_PTR *PFNGLGETSHADERPRECISIONFORMATPROC)(GLenum shadertype, GLenum precisiontype, GLint *range, GLint *precision); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM3DPROC)(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *value); + typedef void(GLAD_API_PTR *PFNGLBINDTRANSFORMFEEDBACKPROC)(GLenum target, GLuint id); + typedef void(GLAD_API_PTR *PFNGLPROVOKINGVERTEXPROC)(GLenum mode); + typedef void(GLAD_API_PTR *PFNGLDISABLEVERTEXARRAYATTRIBPROC)(GLuint vaobj, GLuint index); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD4FVPROC)(GLenum target, const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLUNIFORM1DPROC)(GLint location, GLdouble x); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); + typedef void(GLAD_API_PTR *PFNGLMEMORYBARRIERBYREGIONPROC)(GLbitfield barriers); + typedef void(GLAD_API_PTR *PFNGLPOPDEBUGGROUPPROC)(void); + typedef void(GLAD_API_PTR *PFNGLCOLOR4BPROC)(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); + typedef void(GLAD_API_PTR *PFNGLTEXTUREBUFFERPROC)(GLuint texture, GLenum internalformat, GLuint buffer); + typedef void(GLAD_API_PTR *PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLBEGINQUERYINDEXEDPROC)(GLenum target, GLuint index, GLuint id); + typedef void(GLAD_API_PTR *PFNGLCOPYNAMEDBUFFERSUBDATAPROC)(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + typedef void(GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBFORMATPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); + typedef void *(GLAD_API_PTR *PFNGLMAPNAMEDBUFFERRANGEPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); + typedef void(GLAD_API_PTR *PFNGLCOLOR4UIVPROC)(const GLuint *v); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBP1UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); + typedef void(GLAD_API_PTR *PFNGLWINDOWPOS3SVPROC)(const GLshort *v); + typedef void(GLAD_API_PTR *PFNGLFOGIVPROC)(GLenum pname, const GLint *params); + typedef void(GLAD_API_PTR *PFNGLTEXTUREPARAMETERIIVPROC)(GLuint texture, GLenum pname, const GLint *params); + typedef void(GLAD_API_PTR *PFNGLLISTBASEPROC)(GLuint base); + typedef void(GLAD_API_PTR *PFNGLCREATEFRAMEBUFFERSPROC)(GLsizei n, GLuint *framebuffers); + typedef void(GLAD_API_PTR *PFNGLEVALCOORD2FPROC)(GLfloat u, GLfloat v); + typedef void(GLAD_API_PTR *PFNGLVERTEX4DVPROC)(const GLdouble *v); + typedef void(GLAD_API_PTR *PFNGLDELETEPROGRAMPROC)(GLuint program); + typedef void(GLAD_API_PTR *PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices); + typedef void(GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC)(GLenum mode, GLuint id, GLuint stream); + typedef void(GLAD_API_PTR *PFNGLVALIDATEPROGRAMPROC)(GLuint program); + typedef void(GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDPROC)(GLenum mode, GLsizei count, GLenum type, const void *indices, GLsizei instancecount); + typedef GLuint(GLAD_API_PTR *PFNGLGENLISTSPROC)(GLsizei range); + typedef void(GLAD_API_PTR *PFNGLCOLOR4IPROC)(GLint red, GLint green, GLint blue, GLint alpha); + typedef void(GLAD_API_PTR *PFNGLCOLOR3UIPROC)(GLuint red, GLuint green, GLuint blue); + typedef void(GLAD_API_PTR *PFNGLCREATETEXTURESPROC)(GLenum target, GLsizei n, GLuint *textures); + typedef void(GLAD_API_PTR *PFNGLCOLORP4UIVPROC)(GLenum type, const GLuint *color); + typedef void(GLAD_API_PTR *PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBP3UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); + typedef void(GLAD_API_PTR *PFNGLCLEARBUFFERFIPROC)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); + typedef void(GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE3DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); + typedef void(GLAD_API_PTR *PFNGLEDGEFLAGPROC)(GLboolean flag); + typedef void(GLAD_API_PTR *PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum target, GLenum pname, GLint64 *params); + typedef void(GLAD_API_PTR *PFNGLRASTERPOS2IVPROC)(const GLint *v); + typedef void(GLAD_API_PTR *PFNGLGETNMAPIVPROC)(GLenum target, GLenum query, GLsizei bufSize, GLint *v); + typedef void(GLAD_API_PTR *PFNGLRECTDVPROC)(const GLdouble *v1, const GLdouble *v2); + typedef void(GLAD_API_PTR *PFNGLGETBOOLEANI_VPROC)(GLenum target, GLuint index, GLboolean *data); + typedef void(GLAD_API_PTR *PFNGLENDLISTPROC)(void); + typedef void(GLAD_API_PTR *PFNGLFLUSHPROC)(void); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM4UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); + typedef void(GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC)(GLenum mode, GLenum type, const void *indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); + typedef void(GLAD_API_PTR *PFNGLGETINTEGER64VPROC)(GLenum pname, GLint64 *data); + typedef void(GLAD_API_PTR *PFNGLLIGHTMODELFPROC)(GLenum pname, GLfloat param); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB4NIVPROC)(GLuint index, const GLint *v); + typedef void(GLAD_API_PTR *PFNGLGETTEXTURELEVELPARAMETERIVPROC)(GLuint texture, GLint level, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLLOADMATRIXDPROC)(const GLdouble *m); + typedef void(GLAD_API_PTR *PFNGLBINDPROGRAMPIPELINEPROC)(GLuint pipeline); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORM1UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint *value); + typedef void(GLAD_API_PTR *PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index); + typedef void(GLAD_API_PTR *PFNGLCLEARDEPTHPROC)(GLdouble depth); + typedef void(GLAD_API_PTR *PFNGLGETTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLWINDOWPOS3FVPROC)(const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIB3DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z); + typedef GLint(GLAD_API_PTR *PFNGLGETPROGRAMRESOURCELOCATIONPROC)(GLuint program, GLenum programInterface, const GLchar *name); + typedef void(GLAD_API_PTR *PFNGLTEXCOORD2DPROC)(GLdouble s, GLdouble t); + typedef void(GLAD_API_PTR *PFNGLACCUMPROC)(GLenum op, GLfloat value); + typedef void(GLAD_API_PTR *PFNGLSECONDARYCOLORP3UIPROC)(GLenum type, GLuint color); + typedef void(GLAD_API_PTR *PFNGLVERTEXATTRIBI2UIPROC)(GLuint index, GLuint x, GLuint y); + typedef void(GLAD_API_PTR *PFNGLGETNUNIFORMFVPROC)(GLuint program, GLint location, GLsizei bufSize, GLfloat *params); + typedef void(GLAD_API_PTR *PFNGLFOGIPROC)(GLenum pname, GLint param); + typedef void(GLAD_API_PTR *PFNGLCLEARBUFFERFVPROC)(GLenum buffer, GLint drawbuffer, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLTEXENVIVPROC)(GLenum target, GLenum pname, const GLint *params); + typedef void(GLAD_API_PTR *PFNGLTEXIMAGE2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels); + typedef void(GLAD_API_PTR *PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC)(GLuint program, GLuint bufferIndex, GLenum pname, GLint *params); + typedef void(GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); + typedef void(GLAD_API_PTR *PFNGLMULTITEXCOORD1FVPROC)(GLenum target, const GLfloat *v); + typedef void(GLAD_API_PTR *PFNGLGETOBJECTPTRLABELPROC)(const void *ptr, GLsizei bufSize, GLsizei *length, GLchar *label); -typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIIVPROC)(GLuint texture, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLTEXCOORDP1UIVPROC)(GLenum type, const GLuint * coords); -typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC)(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -typedef void (GLAD_API_PTR *PFNGLEVALPOINT2PROC)(GLint i, GLint j); -typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBBINDINGPROC)(GLuint vaobj, GLuint attribindex, GLuint bindingindex); -typedef void (GLAD_API_PTR *PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length); -typedef void (GLAD_API_PTR *PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC)(GLuint framebuffer, GLenum pname, GLint * param); -typedef void (GLAD_API_PTR *PFNGLPIXELTRANSFERFPROC)(GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLGETFLOATI_VPROC)(GLenum target, GLuint index, GLfloat * data); -typedef void (GLAD_API_PTR *PFNGLLOADNAMEPROC)(GLuint name); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE1DPROC)(GLuint texture, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3UIVPROC)(const GLuint * v); -typedef void (GLAD_API_PTR *PFNGLUNIFORM1DVPROC)(GLint location, GLsizei count, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3BVPROC)(const GLbyte * v); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3UIPROC)(GLuint red, GLuint green, GLuint blue); -typedef void (GLAD_API_PTR *PFNGLGETNCOLORTABLEPROC)(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void * table); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS3IPROC)(GLint x, GLint y, GLint z); -typedef void (GLAD_API_PTR *PFNGLACTIVETEXTUREPROC)(GLenum texture); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUIVPROC)(GLuint index, const GLuint * v); -typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDBUFFERDATAPROC)(GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void * data); -typedef void (GLAD_API_PTR *PFNGLNORMAL3DPROC)(GLdouble nx, GLdouble ny, GLdouble nz); -typedef void (GLAD_API_PTR *PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC)(GLuint framebuffer, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLBINDBUFFERSBASEPROC)(GLenum target, GLuint first, GLsizei count, const GLuint * buffers); -typedef void (GLAD_API_PTR *PFNGLEVALCOORD1DPROC)(GLdouble u); -typedef void (GLAD_API_PTR *PFNGLGETMAPFVPROC)(GLenum target, GLenum query, GLfloat * v); -typedef GLboolean (GLAD_API_PTR *PFNGLISSYNCPROC)(GLsync sync); -typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); -typedef GLint (GLAD_API_PTR *PFNGLGETATTRIBLOCATIONPROC)(GLuint program, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLCOPYTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4IPROC)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (GLAD_API_PTR *PFNGLGETPIXELMAPFVPROC)(GLenum map, GLfloat * values); -typedef void (GLAD_API_PTR *PFNGLVERTEX4SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE2DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD2FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X2DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIUIVPROC)(GLuint index, GLenum pname, GLuint * params); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3SVPROC)(GLuint index, const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices, GLint basevertex); -typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEINDEXEDPROC)(GLuint index, GLdouble n, GLdouble f); -typedef GLboolean (GLAD_API_PTR *PFNGLISQUERYPROC)(GLuint id); -typedef void (GLAD_API_PTR *PFNGLDELETEPROGRAMPIPELINESPROC)(GLsizei n, const GLuint * pipelines); -typedef void (GLAD_API_PTR *PFNGLGETTEXTURELEVELPARAMETERFVPROC)(GLuint texture, GLint level, GLenum pname, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X3DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLBLITNAMEDFRAMEBUFFERPROC)(GLuint readFramebuffer, GLuint drawFramebuffer, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP1UIPROC)(GLenum texture, GLenum type, GLuint coords); -typedef void (GLAD_API_PTR *PFNGLINDEXSPROC)(GLshort c); -typedef void (GLAD_API_PTR *PFNGLCOLORP3UIPROC)(GLenum type, GLuint color); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP4UIPROC)(GLenum texture, GLenum type, GLuint coords); -typedef GLuint (GLAD_API_PTR *PFNGLCREATESHADERPROC)(GLenum type); -typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERFIPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); -typedef void (GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC)(GLuint texture, GLint level, GLsizei bufSize, void * pixels); -typedef void (GLAD_API_PTR *PFNGLCOLOR4SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGEINSERTPROC)(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar * buf); -typedef void (GLAD_API_PTR *PFNGLRECTFPROC)(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); -typedef GLuint (GLAD_API_PTR *PFNGLGETDEBUGMESSAGELOGPROC)(GLuint count, GLsizei bufSize, GLenum * sources, GLenum * types, GLuint * ids, GLenum * severities, GLsizei * lengths, GLchar * messageLog); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3SPROC)(GLshort x, GLshort y, GLshort z); -typedef GLboolean (GLAD_API_PTR *PFNGLISFRAMEBUFFERPROC)(GLuint framebuffer); -typedef void (GLAD_API_PTR *PFNGLCOPYIMAGESUBDATAPROC)(GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); -typedef void (GLAD_API_PTR *PFNGLCOLORPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLGETMATERIALFVPROC)(GLenum face, GLenum pname, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4IVPROC)(GLenum target, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLDELETESAMPLERSPROC)(GLsizei count, const GLuint * samplers); -typedef void (GLAD_API_PTR *PFNGLGETMATERIALIVPROC)(GLenum face, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLBLENDFUNCPROC)(GLenum sfactor, GLenum dfactor); -typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC)(GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERDATAPROC)(GLuint buffer, GLsizeiptr size, const void * data, GLenum usage); -typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSPROC)(GLenum mode, const GLsizei * count, GLenum type, const void *const* indices, GLsizei drawcount); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3IPROC)(GLuint program, GLint location, GLint v0, GLint v1, GLint v2); -typedef void (GLAD_API_PTR *PFNGLGETPROGRAMSTAGEIVPROC)(GLuint program, GLenum shadertype, GLenum pname, GLint * values); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBLFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (GLAD_API_PTR *PFNGLVERTEX2SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLRECTSVPROC)(const GLshort * v1, const GLshort * v2); -typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE2DPROC)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLUNIFORM3FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERPROC)(GLenum buf); -typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void * pixels); -typedef void (GLAD_API_PTR *PFNGLTEXCOORDP2UIVPROC)(GLenum type, const GLuint * coords); -typedef void (GLAD_API_PTR *PFNGLUNIFORM4FPROC)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2DPROC)(GLuint index, GLdouble x, GLdouble y); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FPROC)(GLuint index, GLfloat x, GLfloat y); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3UBVPROC)(const GLubyte * v); -typedef void (GLAD_API_PTR *PFNGLDELETEFRAMEBUFFERSPROC)(GLsizei n, const GLuint * framebuffers); -typedef void (GLAD_API_PTR *PFNGLCLEARCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERRENDERBUFFERPROC)(GLenum target, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); -typedef void (GLAD_API_PTR *PFNGLGETTEXGENFVPROC)(GLenum coord, GLenum pname, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLCOLOR4DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP4UIVPROC)(GLenum texture, GLenum type, const GLuint * coords); -typedef void (GLAD_API_PTR *PFNGLACTIVESHADERPROGRAMPROC)(GLuint pipeline, GLuint program); -typedef void (GLAD_API_PTR *PFNGLBEGINCONDITIONALRENDERPROC)(GLuint id, GLenum mode); -typedef void (GLAD_API_PTR *PFNGLTEXIMAGE3DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -typedef void (GLAD_API_PTR *PFNGLVIEWPORTINDEXEDFVPROC)(GLuint index, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLMAPGRID1FPROC)(GLint un, GLfloat u1, GLfloat u2); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3DPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLGETBUFFERPOINTERVPROC)(GLenum target, GLenum pname, void ** params); -typedef void (GLAD_API_PTR *PFNGLTEXGENFVPROC)(GLenum coord, GLenum pname, const GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP4UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLROTATEDPROC)(GLdouble angle, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAD_API_PTR *PFNGLCREATEQUERIESPROC)(GLenum target, GLsizei n, GLuint * ids); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLTEXIMAGE1DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLint border, GLenum format, GLenum type, const void * pixels); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3IPROC)(GLint x, GLint y, GLint z); -typedef void (GLAD_API_PTR *PFNGLCLAMPCOLORPROC)(GLenum target, GLenum clamp); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLVERTEX4FPROC)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAD_API_PTR *PFNGLNORMAL3FPROC)(GLfloat nx, GLfloat ny, GLfloat nz); -typedef void (GLAD_API_PTR *PFNGLCOLOR3UBPROC)(GLubyte red, GLubyte green, GLubyte blue); -typedef void (GLAD_API_PTR *PFNGLSCISSORINDEXEDPROC)(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLPUSHCLIENTATTRIBPROC)(GLbitfield mask); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAD_API_PTR *PFNGLUSEPROGRAMSTAGESPROC)(GLuint pipeline, GLbitfield stages, GLuint program); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD3SPROC)(GLshort s, GLshort t, GLshort r); -typedef void (GLAD_API_PTR *PFNGLLIGHTFPROC)(GLenum light, GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD3FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUBVPROC)(GLuint index, const GLubyte * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL2DPROC)(GLuint index, GLdouble x, GLdouble y); -typedef void (GLAD_API_PTR *PFNGLFOGCOORDDPROC)(GLdouble coord); -typedef void (GLAD_API_PTR *PFNGLGETNPIXELMAPUIVPROC)(GLenum map, GLsizei bufSize, GLuint * values); -typedef void (GLAD_API_PTR *PFNGLTEXIMAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -typedef void (GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTIVPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGIPROC)(GLenum name, GLuint index); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS4SPROC)(GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP2UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (GLAD_API_PTR *PFNGLGETQUERYIVPROC)(GLenum target, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLBINDVERTEXARRAYPROC)(GLuint array); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFPROC)(GLenum target, GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3DPROC)(GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAD_API_PTR *PFNGLGENERATETEXTUREMIPMAPPROC)(GLuint texture); -typedef void (GLAD_API_PTR *PFNGLDELETESYNCPROC)(GLsync sync); -typedef void (GLAD_API_PTR *PFNGLBINDBUFFERPROC)(GLenum target, GLuint buffer); -typedef void (GLAD_API_PTR *PFNGLPUSHDEBUGGROUPPROC)(GLenum source, GLuint id, GLsizei length, const GLchar * message); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS2IPROC)(GLint x, GLint y); -typedef void (GLAD_API_PTR *PFNGLBINDIMAGETEXTUREPROC)(GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format); -typedef void (GLAD_API_PTR *PFNGLFEEDBACKBUFFERPROC)(GLsizei size, GLenum type, GLfloat * buffer); -typedef void (GLAD_API_PTR *PFNGLEVALMESH2PROC)(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); -typedef void (GLAD_API_PTR *PFNGLLINKPROGRAMPROC)(GLuint program); -typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data); -typedef void (GLAD_API_PTR *PFNGLPUSHMATRIXPROC)(void); -typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERPARAMETERIPROC)(GLenum target, GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC)(GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei * length, GLchar * uniformBlockName); -typedef void (GLAD_API_PTR *PFNGLUNIFORM3DPROC)(GLint location, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4UBVPROC)(GLuint index, const GLubyte * v); -typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE1DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLint border, GLsizei imageSize, const void * data); -typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKI64_VPROC)(GLuint xfb, GLenum pname, GLuint index, GLint64 * param); -typedef void (GLAD_API_PTR *PFNGLCOMPILESHADERPROC)(GLuint shader); -typedef void (GLAD_API_PTR *PFNGLGETLIGHTFVPROC)(GLenum light, GLenum pname, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLPIXELMAPUSVPROC)(GLenum map, GLsizei mapsize, const GLushort * values); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS4IPROC)(GLint x, GLint y, GLint z, GLint w); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4X2DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE1DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (GLAD_API_PTR *PFNGLINITNAMESPROC)(void); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1UIPROC)(GLuint index, GLuint x); -typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERIVPROC)(GLenum buffer, GLint drawbuffer, const GLint * value); -typedef void (GLAD_API_PTR *PFNGLMAP1FPROC)(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat * points); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBFVPROC)(GLuint index, GLenum pname, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMBLOCKIVPROC)(GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLGETVERTEXARRAYINDEXEDIVPROC)(GLuint vaobj, GLuint index, GLenum pname, GLint * param); -typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYELEMENTBUFFERPROC)(GLuint vaobj, GLuint buffer); -typedef void (GLAD_API_PTR *PFNGLGETTEXGENDVPROC)(GLenum coord, GLenum pname, GLdouble * params); -typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERFVPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3FPROC)(GLfloat red, GLfloat green, GLfloat blue); -typedef void (GLAD_API_PTR *PFNGLSHADERBINARYPROC)(GLsizei count, const GLuint * shaders, GLenum binaryformat, const void * binary, GLsizei length); -typedef void (GLAD_API_PTR *PFNGLMAP1DPROC)(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble * points); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL2DVPROC)(GLuint index, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4DPROC)(GLenum target, GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD1DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE2DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -typedef void (GLAD_API_PTR *PFNGLGENTRANSFORMFEEDBACKSPROC)(GLsizei n, GLuint * ids); -typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERSUBDATAPROC)(GLenum target, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void * data); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLPIXELMAPFVPROC)(GLenum map, GLsizei mapsize, const GLfloat * values); -typedef void (GLAD_API_PTR *PFNGLCOLOR3FPROC)(GLfloat red, GLfloat green, GLfloat blue); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLMULTMATRIXDPROC)(const GLdouble * m); -typedef void (GLAD_API_PTR *PFNGLCOPYPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type); -typedef void (GLAD_API_PTR *PFNGLUNIFORM2DVPROC)(GLint location, GLsizei count, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLCOLOR3SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLOBJECTLABELPROC)(GLenum identifier, GLuint name, GLsizei length, const GLchar * label); -typedef void (GLAD_API_PTR *PFNGLGETOBJECTLABELPROC)(GLenum identifier, GLuint name, GLsizei bufSize, GLsizei * length, GLchar * label); -typedef void (GLAD_API_PTR *PFNGLINDEXFVPROC)(const GLfloat * c); -typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data); -typedef void (GLAD_API_PTR *PFNGLMAPGRID1DPROC)(GLint un, GLdouble u1, GLdouble u2); -typedef void (GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTUIVPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS3SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLSELECTBUFFERPROC)(GLsizei size, GLuint * buffer); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3IVPROC)(GLuint index, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLPATCHPARAMETERIPROC)(GLenum pname, GLint value); -typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIUIVPROC)(GLuint texture, GLenum pname, GLuint * params); -typedef void (GLAD_API_PTR *PFNGLCOLOR3IVPROC)(const GLint * v); -typedef void * (GLAD_API_PTR *PFNGLMAPBUFFERPROC)(GLenum target, GLenum access); -typedef void (GLAD_API_PTR *PFNGLNORMALP3UIPROC)(GLenum type, GLuint coords); -typedef void (GLAD_API_PTR *PFNGLVERTEXPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERFVPROC)(GLuint texture, GLenum pname, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBPOINTERPROC)(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEFPROC)(GLfloat n, GLfloat f); -typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIVPROC)(GLuint texture, GLenum pname, const GLint * param); -typedef void (GLAD_API_PTR *PFNGLVERTEXP2UIVPROC)(GLenum type, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4USVPROC)(GLuint index, const GLushort * v); -typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIVPROC)(GLenum target, GLenum pname, const GLint * params); -typedef void (GLAD_API_PTR *PFNGLBINDVERTEXBUFFERSPROC)(GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizei * strides); -typedef void (GLAD_API_PTR *PFNGLVERTEXP3UIVPROC)(GLenum type, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLINDEXIPROC)(GLint c); -typedef void (GLAD_API_PTR *PFNGLGETACTIVESUBROUTINENAMEPROC)(GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei * length, GLchar * name); -typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void * data); -typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBPOINTERVPROC)(GLuint index, GLenum pname, void ** pointer); -typedef void (GLAD_API_PTR *PFNGLGETPIXELMAPUIVPROC)(GLenum map, GLuint * values); -typedef void (GLAD_API_PTR *PFNGLGETTEXGENIVPROC)(GLenum coord, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3SPROC)(GLuint index, GLshort x, GLshort y, GLshort z); -typedef void (GLAD_API_PTR *PFNGLPOINTSIZEPROC)(GLfloat size); -typedef void (GLAD_API_PTR *PFNGLVERTEXP2UIPROC)(GLenum type, GLuint value); -typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC)(GLenum mode, const void * indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); -typedef void (GLAD_API_PTR *PFNGLGETNTEXIMAGEPROC)(GLenum target, GLint level, GLenum format, GLenum type, GLsizei bufSize, void * pixels); -typedef void (GLAD_API_PTR *PFNGLCULLFACEPROC)(GLenum mode); -typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIPROC)(GLuint sampler, GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLTEXTUREBARRIERPROC)(void); -typedef GLboolean (GLAD_API_PTR *PFNGLISRENDERBUFFERPROC)(GLuint renderbuffer); -typedef void (GLAD_API_PTR *PFNGLBEGINQUERYPROC)(GLenum target, GLuint id); -typedef void (GLAD_API_PTR *PFNGLCOLOR4USPROC)(GLushort red, GLushort green, GLushort blue, GLushort alpha); -typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBDVPROC)(GLuint index, GLenum pname, GLdouble * params); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD4IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLDELETETEXTURESPROC)(GLsizei n, const GLuint * textures); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBIPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLCREATEVERTEXARRAYSPROC)(GLsizei n, GLuint * arrays); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1IPROC)(GLuint index, GLint x); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void * data); -typedef void (GLAD_API_PTR *PFNGLRECTDPROC)(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); -typedef void (GLAD_API_PTR *PFNGLMULTTRANSPOSEMATRIXDPROC)(const GLdouble * m); -typedef void (GLAD_API_PTR *PFNGLTEXENVFPROC)(GLenum target, GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLNORMAL3IPROC)(GLint nx, GLint ny, GLint nz); -typedef void (GLAD_API_PTR *PFNGLBINDATTRIBLOCATIONPROC)(GLuint program, GLuint index, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLSTENCILMASKSEPARATEPROC)(GLenum face, GLuint mask); -typedef void (GLAD_API_PTR *PFNGLGETINTEGERVPROC)(GLenum pname, GLint * data); -typedef void (GLAD_API_PTR *PFNGLUSEPROGRAMPROC)(GLuint program); -typedef void (GLAD_API_PTR *PFNGLNORMAL3BVPROC)(const GLbyte * v); -typedef void (GLAD_API_PTR *PFNGLPIXELSTOREIPROC)(GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLNORMAL3SPROC)(GLshort nx, GLshort ny, GLshort nz); -typedef void (GLAD_API_PTR *PFNGLCOLOR4IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP2UIVPROC)(GLenum texture, GLenum type, const GLuint * coords); -typedef GLboolean (GLAD_API_PTR *PFNGLARETEXTURESRESIDENTPROC)(GLsizei n, const GLuint * textures, GLboolean * residences); -typedef void (GLAD_API_PTR *PFNGLGETUNIFORMFVPROC)(GLuint program, GLint location, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC)(GLuint program, GLenum shadertype, GLuint index, GLsizei bufsize, GLsizei * length, GLchar * name); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE3DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD1IPROC)(GLint s); -typedef void (GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLsizei bufSize, void * pixels); -typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXBUFFERSPROC)(GLuint vaobj, GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizei * strides); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3DPROC)(GLdouble red, GLdouble green, GLdouble blue); -typedef void (GLAD_API_PTR *PFNGLINTERLEAVEDARRAYSPROC)(GLenum format, GLsizei stride, const void * pointer); -typedef GLboolean (GLAD_API_PTR *PFNGLUNMAPBUFFERPROC)(GLenum target); -typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDIPROC)(GLenum target, GLuint index); -typedef void (GLAD_API_PTR *PFNGLBINDSAMPLERSPROC)(GLuint first, GLsizei count, const GLuint * samplers); -typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * data); -typedef void (GLAD_API_PTR *PFNGLPRIORITIZETEXTURESPROC)(GLsizei n, const GLuint * textures, const GLfloat * priorities); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS4DPROC)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3USVPROC)(const GLushort * v); -typedef void (GLAD_API_PTR *PFNGLGETSYNCIVPROC)(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei * length, GLint * values); -typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, const GLint * param); -typedef void (GLAD_API_PTR *PFNGLLIGHTMODELFVPROC)(GLenum pname, const GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE3DPROC)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); -typedef void (GLAD_API_PTR *PFNGLRESUMETRANSFORMFEEDBACKPROC)(void); -typedef void (GLAD_API_PTR *PFNGLGENPROGRAMPIPELINESPROC)(GLsizei n, GLuint * pipelines); -typedef void (GLAD_API_PTR *PFNGLVERTEX4FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLLIGHTIVPROC)(GLenum light, GLenum pname, const GLint * params); -typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERIVPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLint * value); -typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD3DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLFOGCOORDPOINTERPROC)(GLenum type, GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLUNIFORM2IPROC)(GLint location, GLint v0, GLint v1); -typedef void (GLAD_API_PTR *PFNGLTEXTURESUBIMAGE3DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels); -typedef void (GLAD_API_PTR *PFNGLGETDOUBLEI_VPROC)(GLenum target, GLuint index, GLdouble * data); -typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERDATAPROC)(GLenum target, GLenum internalformat, GLenum format, GLenum type, const void * data); -typedef void (GLAD_API_PTR *PFNGLBINDTEXTUREPROC)(GLenum target, GLuint texture); -typedef void (GLAD_API_PTR *PFNGLTEXTUREBUFFERRANGEPROC)(GLuint texture, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERFVPROC)(GLenum target, GLint level, GLenum pname, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLSAMPLEMASKIPROC)(GLuint maskNumber, GLbitfield mask); -typedef void (GLAD_API_PTR *PFNGLCLEARACCUMPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); -typedef void (GLAD_API_PTR *PFNGLGETPROGRAMBINARYPROC)(GLuint program, GLsizei bufSize, GLsizei * length, GLenum * binaryFormat, void * binary); -typedef void (GLAD_API_PTR *PFNGLDETACHSHADERPROC)(GLuint program, GLuint shader); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4SPROC)(GLuint index, GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIPROC)(GLuint texture, GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLCOLOR3DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLBINDSAMPLERPROC)(GLuint unit, GLuint sampler); -typedef GLenum (GLAD_API_PTR *PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC)(GLuint framebuffer, GLenum target); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value); -typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSPROC)(GLenum mode, const GLint * first, const GLsizei * count, GLsizei drawcount); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS4DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLGETFLOATVPROC)(GLenum pname, GLfloat * data); -typedef void (GLAD_API_PTR *PFNGLPROGRAMPARAMETERIPROC)(GLuint program, GLenum pname, GLint value); -typedef void (GLAD_API_PTR *PFNGLDELETERENDERBUFFERSPROC)(GLsizei n, const GLuint * renderbuffers); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLORPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); -typedef GLboolean (GLAD_API_PTR *PFNGLISSAMPLERPROC)(GLuint sampler); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1DVPROC)(GLenum target, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECONTROLPROC)(GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint * ids, GLboolean enabled); -typedef void (GLAD_API_PTR *PFNGLBINDBUFFERSRANGEPROC)(GLenum target, GLuint first, GLsizei count, const GLuint * buffers, const GLintptr * offsets, const GLsizeiptr * sizes); -typedef void (GLAD_API_PTR *PFNGLMULTIDRAWARRAYSINDIRECTPROC)(GLenum mode, const void * indirect, GLsizei drawcount, GLsizei stride); -typedef void (GLAD_API_PTR *PFNGLGETMAPDVPROC)(GLenum target, GLenum query, GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORDP3UIPROC)(GLenum type, GLuint coords); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBIFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC)(GLenum mode, GLuint id, GLuint stream, GLsizei instancecount); -typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC)(GLuint xfb, GLuint index, GLuint buffer); -typedef void (GLAD_API_PTR *PFNGLGETTEXENVIVPROC)(GLenum target, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLCOLORP3UIVPROC)(GLenum type, const GLuint * color); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FPROC)(GLuint index, GLfloat x); -typedef void (GLAD_API_PTR *PFNGLPOPCLIENTATTRIBPROC)(void); -typedef void (GLAD_API_PTR *PFNGLGETTEXIMAGEPROC)(GLenum target, GLint level, GLenum format, GLenum type, void * pixels); -typedef void (GLAD_API_PTR *PFNGLRENDERBUFFERSTORAGEPROC)(GLenum target, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLDELETEBUFFERSPROC)(GLsizei n, const GLuint * buffers); -typedef GLenum (GLAD_API_PTR *PFNGLCLIENTWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLCLEARTEXIMAGEPROC)(GLuint texture, GLint level, GLenum format, GLenum type, const void * data); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2FVPROC)(GLenum target, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLUNIFORM3UIVPROC)(GLint location, GLsizei count, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMNAMEPROC)(GLuint program, GLuint uniformIndex, GLsizei bufSize, GLsizei * length, GLchar * uniformName); -typedef void (GLAD_API_PTR *PFNGLEVALPOINT1PROC)(GLint i); -typedef void (GLAD_API_PTR *PFNGLCOLOR3USPROC)(GLushort red, GLushort green, GLushort blue); -typedef void (GLAD_API_PTR *PFNGLGETTEXTURESUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, GLsizei bufSize, void * pixels); -typedef void (GLAD_API_PTR *PFNGLCOLOR3IPROC)(GLint red, GLint green, GLint blue); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLEVALCOORD1FVPROC)(const GLfloat * u); -typedef void (GLAD_API_PTR *PFNGLVIEWPORTARRAYVPROC)(GLuint first, GLsizei count, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4IPROC)(GLuint index, GLint x, GLint y, GLint z, GLint w); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL4DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAD_API_PTR *PFNGLCOLOR4DPROC)(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha); -typedef GLint (GLAD_API_PTR *PFNGLGETFRAGDATALOCATIONPROC)(GLuint program, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLCOLOR4UBVPROC)(const GLubyte * v); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX4DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X4DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLSCISSORPROC)(GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLUNIFORMSUBROUTINESUIVPROC)(GLenum shadertype, GLsizei count, const GLuint * indices); -typedef void (GLAD_API_PTR *PFNGLVERTEX4IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLCOLORMASKPROC)(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); -typedef void (GLAD_API_PTR *PFNGLSTENCILOPSEPARATEPROC)(GLenum face, GLenum sfail, GLenum dpfail, GLenum dppass); -typedef void (GLAD_API_PTR *PFNGLGETBOOLEANVPROC)(GLenum pname, GLboolean * data); -typedef void (GLAD_API_PTR *PFNGLVERTEX3DPROC)(GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERPOINTERVPROC)(GLuint buffer, GLenum pname, void ** params); -typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYVERTEXBUFFERPROC)(GLuint vaobj, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); -typedef void (GLAD_API_PTR *PFNGLGETPOLYGONSTIPPLEPROC)(GLubyte * mask); -typedef void (GLAD_API_PTR *PFNGLSTENCILOPPROC)(GLenum fail, GLenum zfail, GLenum zpass); -typedef void (GLAD_API_PTR *PFNGLVIEWPORTPROC)(GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLGETNPOLYGONSTIPPLEPROC)(GLsizei bufSize, GLubyte * pattern); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4USVPROC)(GLuint index, const GLushort * v); -typedef void (GLAD_API_PTR *PFNGLENDTRANSFORMFEEDBACKPROC)(void); -typedef GLuint (GLAD_API_PTR *PFNGLCREATEPROGRAMPROC)(void); -typedef void (GLAD_API_PTR *PFNGLGETSHADERINFOLOGPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * infoLog); -typedef void (GLAD_API_PTR *PFNGLGETVERTEXARRAYINDEXED64IVPROC)(GLuint vaobj, GLuint index, GLenum pname, GLint64 * param); -typedef void (GLAD_API_PTR *PFNGLTEXGENDPROC)(GLenum coord, GLenum pname, GLdouble param); -typedef void (GLAD_API_PTR *PFNGLINDEXUBPROC)(GLubyte c); -typedef void (GLAD_API_PTR *PFNGLMULTMATRIXFPROC)(const GLfloat * m); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP2UIPROC)(GLenum texture, GLenum type, GLuint coords); -typedef void (GLAD_API_PTR *PFNGLTEXIMAGE3DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void * pixels); -typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMDVPROC)(GLuint program, GLint location, GLsizei bufSize, GLdouble * params); -typedef void (GLAD_API_PTR *PFNGLRECTIVPROC)(const GLint * v1, const GLint * v2); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD4SPROC)(GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (GLAD_API_PTR *PFNGLCOPYTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border); -typedef void (GLAD_API_PTR *PFNGLLOGICOPPROC)(GLenum opcode); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLBINDRENDERBUFFERPROC)(GLenum target, GLuint renderbuffer); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLCREATESAMPLERSPROC)(GLsizei n, GLuint * samplers); -typedef void (GLAD_API_PTR *PFNGLPIXELMAPUIVPROC)(GLenum map, GLsizei mapsize, const GLuint * values); -typedef void (GLAD_API_PTR *PFNGLBLENDCOLORPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -typedef void (GLAD_API_PTR *PFNGLLIGHTMODELIPROC)(GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERIPROC)(GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLGENQUERIESPROC)(GLsizei n, GLuint * ids); -typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERTEXTUREPROC)(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level); -typedef void (GLAD_API_PTR *PFNGLGETNSEPARABLEFILTERPROC)(GLenum target, GLenum format, GLenum type, GLsizei rowBufSize, void * row, GLsizei columnBufSize, void * column, void * span); -typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTUIVPROC)(GLuint id, GLenum pname, GLuint * params); -typedef void (GLAD_API_PTR *PFNGLCOLOR4FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLGETVERTEXARRAYIVPROC)(GLuint vaobj, GLenum pname, GLint * param); -typedef void (GLAD_API_PTR *PFNGLUNIFORM1UIPROC)(GLint location, GLuint v0); -typedef void (GLAD_API_PTR *PFNGLGETNMAPFVPROC)(GLenum target, GLenum query, GLsizei bufSize, GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLUNIFORM4FVPROC)(GLint location, GLsizei count, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLTEXGENFPROC)(GLenum coord, GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLINDEXIVPROC)(const GLint * c); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1FVPROC)(GLuint index, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3IPROC)(GLenum target, GLint s, GLint t, GLint r); -typedef void (GLAD_API_PTR *PFNGLCOLOR4USVPROC)(const GLushort * v); -typedef void (GLAD_API_PTR *PFNGLDRAWBUFFERSPROC)(GLsizei n, const GLenum * bufs); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2IPROC)(GLint x, GLint y); -typedef void (GLAD_API_PTR *PFNGLTEXBUFFERRANGEPROC)(GLenum target, GLenum internalformat, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP1UIVPROC)(GLenum texture, GLenum type, const GLuint * coords); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2IVPROC)(GLuint index, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSINDIRECTPROC)(GLenum mode, GLenum type, const void * indirect, GLsizei drawcount, GLsizei stride); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM3IPROC)(GLint location, GLint v0, GLint v1, GLint v2); -typedef void (GLAD_API_PTR *PFNGLGETCLIPPLANEPROC)(GLenum plane, GLdouble * equation); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP2UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD2IPROC)(GLint s, GLint t); -typedef void (GLAD_API_PTR *PFNGLUNIFORM4UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex, GLuint baseinstance); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUSVPROC)(GLuint index, const GLushort * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1DPROC)(GLuint index, GLdouble x); -typedef void (GLAD_API_PTR *PFNGLGETLIGHTIVPROC)(GLenum light, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE1DPROC)(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width); -typedef void (GLAD_API_PTR *PFNGLSTENCILMASKPROC)(GLuint mask); -typedef void (GLAD_API_PTR *PFNGLGETRENDERBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4FPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (GLAD_API_PTR *PFNGLINDEXDPROC)(GLdouble c); -typedef void (GLAD_API_PTR *PFNGLNORMALP3UIVPROC)(GLenum type, const GLuint * coords); -typedef void (GLAD_API_PTR *PFNGLEVALMESH1PROC)(GLenum mode, GLint i1, GLint i2); -typedef void (GLAD_API_PTR *PFNGLTEXCOORDP3UIVPROC)(GLenum type, const GLuint * coords); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL4DVPROC)(GLuint index, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLCLIENTACTIVETEXTUREPROC)(GLenum texture); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2SPROC)(GLuint index, GLshort x, GLshort y); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3DVPROC)(GLuint index, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, const GLint * params); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS3DPROC)(GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAD_API_PTR *PFNGLEVALCOORD2FVPROC)(const GLfloat * u); -typedef void (GLAD_API_PTR *PFNGLBINDTEXTUREUNITPROC)(GLuint unit, GLuint texture); -typedef void (GLAD_API_PTR *PFNGLWAITSYNCPROC)(GLsync sync, GLbitfield flags, GLuint64 timeout); -typedef void (GLAD_API_PTR *PFNGLMATERIALFVPROC)(GLenum face, GLenum pname, const GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2IPROC)(GLuint program, GLint location, GLint v0, GLint v1); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS2SPROC)(GLshort x, GLshort y); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4BVPROC)(GLuint index, const GLbyte * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4SVPROC)(GLuint index, const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEPROC)(GLenum modeRGB, GLenum modeAlpha); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3UIVPROC)(GLuint index, const GLuint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2UIVPROC)(GLuint index, const GLuint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXP4UIVPROC)(GLenum type, const GLuint * value); -typedef GLuint (GLAD_API_PTR *PFNGLGETUNIFORMBLOCKINDEXPROC)(GLuint program, const GLchar * uniformBlockName); -typedef void (GLAD_API_PTR *PFNGLDEPTHFUNCPROC)(GLenum func); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); -typedef void (GLAD_API_PTR *PFNGLSHADERSOURCEPROC)(GLuint shader, GLsizei count, const GLchar *const* string, const GLint * length); -typedef void (GLAD_API_PTR *PFNGLVERTEX2IVPROC)(const GLint * v); -typedef void * (GLAD_API_PTR *PFNGLMAPNAMEDBUFFERPROC)(GLuint buffer, GLenum access); -typedef void (GLAD_API_PTR *PFNGLCLEARDEPTHFPROC)(GLfloat d); -typedef void (GLAD_API_PTR *PFNGLUNIFORM1FPROC)(GLint location, GLfloat v0); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1DPROC)(GLenum target, GLdouble s); -typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTUI64VPROC)(GLuint id, GLenum pname, GLuint64 * params); -typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC)(GLuint framebuffer, GLsizei n, const GLenum * bufs); -typedef void (GLAD_API_PTR *PFNGLTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * pixels); -typedef void (GLAD_API_PTR *PFNGLDELETETRANSFORMFEEDBACKSPROC)(GLsizei n, const GLuint * ids); -typedef void (GLAD_API_PTR *PFNGLVERTEX3IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef GLboolean (GLAD_API_PTR *PFNGLISTEXTUREPROC)(GLuint texture); -typedef void (GLAD_API_PTR *PFNGLMULTTRANSPOSEMATRIXFPROC)(const GLfloat * m); -typedef void (GLAD_API_PTR *PFNGLNEWLISTPROC)(GLuint list, GLenum mode); -typedef void (GLAD_API_PTR *PFNGLSCALEFPROC)(GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAD_API_PTR *PFNGLVERTEX3FPROC)(GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD1IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLFOGCOORDFVPROC)(const GLfloat * coord); -typedef void (GLAD_API_PTR *PFNGLMAPGRID2DPROC)(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLREADPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void * pixels); -typedef void (GLAD_API_PTR *PFNGLINVALIDATETEXSUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth); -typedef void (GLAD_API_PTR *PFNGLORTHOPROC)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTIVPROC)(GLuint id, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLFOGFPROC)(GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLCOLOR3SPROC)(GLshort red, GLshort green, GLshort blue); -typedef void (GLAD_API_PTR *PFNGLUNIFORM2UIVPROC)(GLint location, GLsizei count, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLPIXELZOOMPROC)(GLfloat xfactor, GLfloat yfactor); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1, GLfloat v2); -typedef void (GLAD_API_PTR *PFNGLEVALCOORD2DVPROC)(const GLdouble * u); -typedef void (GLAD_API_PTR *PFNGLVERTEX3DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLUNIFORM3FVPROC)(GLint location, GLsizei count, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLENABLEPROC)(GLenum cap); -typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIUIVPROC)(GLuint texture, GLenum pname, const GLuint * params); -typedef void (GLAD_API_PTR *PFNGLFOGCOORDDVPROC)(const GLdouble * coord); -typedef void (GLAD_API_PTR *PFNGLBUFFERDATAPROC)(GLenum target, GLsizeiptr size, const void * data, GLenum usage); -typedef void (GLAD_API_PTR *PFNGLPOPATTRIBPROC)(void); -typedef void (GLAD_API_PTR *PFNGLNORMAL3DVPROC)(const GLdouble * v); -typedef GLint (GLAD_API_PTR *PFNGLGETFRAGDATAINDEXPROC)(GLuint program, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLPASSTHROUGHPROC)(GLfloat token); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD2DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORDP4UIVPROC)(GLenum type, const GLuint * coords); -typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERUIVPROC)(GLenum buffer, GLint drawbuffer, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM3DVPROC)(GLint location, GLsizei count, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONIPROC)(GLuint buf, GLenum mode); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); -typedef void (GLAD_API_PTR *PFNGLGETTEXLEVELPARAMETERIVPROC)(GLenum target, GLint level, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLVERTEX4IPROC)(GLint x, GLint y, GLint z, GLint w); -typedef void (GLAD_API_PTR *PFNGLUNIFORM4UIVPROC)(GLint location, GLsizei count, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLTEXENVFVPROC)(GLenum target, GLenum pname, const GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4DVPROC)(GLenum target, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLCLEARTEXSUBIMAGEPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void * data); -typedef void (GLAD_API_PTR *PFNGLTRANSLATEDPROC)(GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERFPROC)(GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLSCISSORINDEXEDVPROC)(GLuint index, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLREADBUFFERPROC)(GLenum src); -typedef void (GLAD_API_PTR *PFNGLENDPROC)(void); -typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4UIVPROC)(GLuint index, const GLuint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UBVPROC)(GLuint index, const GLubyte * v); -typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC)(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const void * data); -typedef void (GLAD_API_PTR *PFNGLVERTEX2DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLPUSHNAMEPROC)(GLuint name); -typedef void (GLAD_API_PTR *PFNGLINVALIDATEBUFFERDATAPROC)(GLuint buffer); -typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERIVPROC)(GLenum pname, const GLint * params); -typedef void (GLAD_API_PTR *PFNGLGENTEXTURESPROC)(GLsizei n, GLuint * textures); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD4FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLDISPATCHCOMPUTEPROC)(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z); -typedef void (GLAD_API_PTR *PFNGLGETUNIFORMUIVPROC)(GLuint program, GLint location, GLuint * params); -typedef void (GLAD_API_PTR *PFNGLGETACTIVEUNIFORMSIVPROC)(GLuint program, GLsizei uniformCount, const GLuint * uniformIndices, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCENAMEPROC)(GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei * length, GLchar * name); -typedef void (GLAD_API_PTR *PFNGLVERTEX2FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLCOLOR4UBPROC)(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); -typedef void (GLAD_API_PTR *PFNGLUNIFORM3IVPROC)(GLint location, GLsizei count, const GLint * value); -typedef void (GLAD_API_PTR *PFNGLCLIPPLANEPROC)(GLenum plane, const GLdouble * equation); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM4IPROC)(GLint location, GLint v0, GLint v1, GLint v2, GLint v3); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, const GLint * param); -typedef void (GLAD_API_PTR *PFNGLUNIFORM2DPROC)(GLint location, GLdouble x, GLdouble y); -typedef void (GLAD_API_PTR *PFNGLPOPMATRIXPROC)(void); -typedef void (GLAD_API_PTR *PFNGLVALIDATEPROGRAMPIPELINEPROC)(GLuint pipeline); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS3DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD1FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD2IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE2DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLGETATTACHEDSHADERSPROC)(GLuint program, GLsizei maxCount, GLsizei * count, GLuint * shaders); -typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKI_VPROC)(GLuint xfb, GLenum pname, GLuint index, GLint * param); -typedef void (GLAD_API_PTR *PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLenum target, GLenum attachment, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBIFORMATPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (GLAD_API_PTR *PFNGLOBJECTPTRLABELPROC)(const void * ptr, GLsizei length, const GLchar * label); -typedef void (GLAD_API_PTR *PFNGLGETNPIXELMAPUSVPROC)(GLenum map, GLsizei bufSize, GLushort * values); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1FPROC)(GLuint program, GLint location, GLfloat v0); -typedef void (GLAD_API_PTR *PFNGLCLEARSTENCILPROC)(GLint s); -typedef void (GLAD_API_PTR *PFNGLDISABLEPROC)(GLenum cap); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef GLuint (GLAD_API_PTR *PFNGLGETSUBROUTINEINDEXPROC)(GLuint program, GLenum shadertype, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2DPROC)(GLenum target, GLdouble s, GLdouble t); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP3UIVPROC)(GLenum texture, GLenum type, const GLuint * coords); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3FVPROC)(GLenum target, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLUNIFORM4IVPROC)(GLint location, GLsizei count, const GLint * value); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBDIVISORPROC)(GLuint index, GLuint divisor); -typedef void (GLAD_API_PTR *PFNGLBINDFRAGDATALOCATIONPROC)(GLuint program, GLuint color, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLGETNCOMPRESSEDTEXIMAGEPROC)(GLenum target, GLint lod, GLsizei bufSize, void * pixels); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2FVPROC)(GLuint index, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLEVALCOORD2DPROC)(GLdouble u, GLdouble v); -typedef void (GLAD_API_PTR *PFNGLGETPOINTERVPROC)(GLenum pname, void ** params); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4DPROC)(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2, GLdouble v3); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD2FPROC)(GLfloat s, GLfloat t); -typedef void (GLAD_API_PTR *PFNGLCOPYBUFFERSUBDATAPROC)(GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLFINISHPROC)(void); -typedef GLboolean (GLAD_API_PTR *PFNGLISPROGRAMPIPELINEPROC)(GLuint pipeline); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP1UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLGETNMAPDVPROC)(GLenum target, GLenum query, GLsizei bufSize, GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLBINDTEXTURESPROC)(GLuint first, GLsizei count, const GLuint * textures); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORDP3UIPROC)(GLenum texture, GLenum type, GLuint coords); -typedef void (GLAD_API_PTR *PFNGLCOLORMASKIPROC)(GLuint index, GLboolean r, GLboolean g, GLboolean b, GLboolean a); -typedef void (GLAD_API_PTR *PFNGLGETQUERYOBJECTI64VPROC)(GLuint id, GLenum pname, GLint64 * params); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3SPROC)(GLenum target, GLshort s, GLshort t, GLshort r); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2DPROC)(GLdouble x, GLdouble y); -typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount, GLuint baseinstance); -typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKPROC)(GLenum mode, GLuint id); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2FPROC)(GLfloat x, GLfloat y); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBLPOINTERPROC)(GLuint index, GLint size, GLenum type, GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD4FPROC)(GLfloat s, GLfloat t, GLfloat r, GLfloat q); -typedef void (GLAD_API_PTR *PFNGLLIGHTMODELIVPROC)(GLenum pname, const GLint * params); -typedef void (GLAD_API_PTR *PFNGLUNIFORM2UIPROC)(GLint location, GLuint v0, GLuint v1); -typedef void (GLAD_API_PTR *PFNGLDELETEVERTEXARRAYSPROC)(GLsizei n, const GLuint * arrays); -typedef void (GLAD_API_PTR *PFNGLTEXBUFFERPROC)(GLenum target, GLenum internalformat, GLuint buffer); -typedef void (GLAD_API_PTR *PFNGLUNIFORM2FPROC)(GLint location, GLfloat v0, GLfloat v1); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD1DPROC)(GLdouble s); -typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE2DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const void * data); -typedef GLenum (GLAD_API_PTR *PFNGLGETGRAPHICSRESETSTATUSPROC)(void); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD1SPROC)(GLshort s); -typedef void (GLAD_API_PTR *PFNGLINDEXSVPROC)(const GLshort * c); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS4IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3IPROC)(GLint red, GLint green, GLint blue); -typedef void (GLAD_API_PTR *PFNGLCALLLISTPROC)(GLuint list); -typedef void (GLAD_API_PTR *PFNGLINDEXUBVPROC)(const GLubyte * c); -typedef void (GLAD_API_PTR *PFNGLPOLYGONMODEPROC)(GLenum face, GLenum mode); -typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTUREPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX3X4FVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef GLboolean (GLAD_API_PTR *PFNGLISTRANSFORMFEEDBACKPROC)(GLuint id); -typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERSUBDATAPROC)(GLuint buffer, GLintptr offset, GLsizeiptr size, const void * data); -typedef void (GLAD_API_PTR *PFNGLGETPROGRAMINTERFACEIVPROC)(GLuint program, GLenum programInterface, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLDISABLECLIENTSTATEPROC)(GLenum array); -typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC)(GLuint framebuffer, GLenum buffer, GLint drawbuffer, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERFVPROC)(GLenum target, GLenum pname, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBLFORMATPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLuint relativeoffset); -typedef void (GLAD_API_PTR *PFNGLVERTEX4DPROC)(GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAD_API_PTR *PFNGLNORMAL3SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS4FPROC)(GLfloat x, GLfloat y, GLfloat z, GLfloat w); -typedef void (GLAD_API_PTR *PFNGLTEXCOORDP4UIPROC)(GLenum type, GLuint coords); -typedef void (GLAD_API_PTR *PFNGLGENRENDERBUFFERSPROC)(GLsizei n, GLuint * renderbuffers); -typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKVARYINGSPROC)(GLuint program, GLsizei count, const GLchar *const* varyings, GLenum bufferMode); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC)(GLuint framebuffer, GLenum src); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X3DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL3DVPROC)(GLuint index, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLUNIFORM1UIVPROC)(GLint location, GLsizei count, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD1SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLGETINTEGERI_VPROC)(GLenum target, GLuint index, GLint * data); -typedef void (GLAD_API_PTR *PFNGLTEXTURESUBIMAGE2DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); -typedef void (GLAD_API_PTR *PFNGLNAMEDRENDERBUFFERSTORAGEPROC)(GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLGETMAPIVPROC)(GLenum target, GLenum query, GLint * v); -typedef void (GLAD_API_PTR *PFNGLMATRIXMODEPROC)(GLenum mode); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4UIVPROC)(GLuint index, const GLuint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL1DVPROC)(GLuint index, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERSUBDATAPROC)(GLuint buffer, GLintptr offset, GLsizeiptr size, void * data); -typedef void (GLAD_API_PTR *PFNGLGENVERTEXARRAYSPROC)(GLsizei n, GLuint * arrays); -typedef void (GLAD_API_PTR *PFNGLGETTEXTUREPARAMETERIVPROC)(GLuint texture, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLVERTEX3FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLMATERIALIVPROC)(GLenum face, GLenum pname, const GLint * params); -typedef void (GLAD_API_PTR *PFNGLPIXELTRANSFERIPROC)(GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLGETNHISTOGRAMPROC)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void * values); -typedef GLuint (GLAD_API_PTR *PFNGLCREATESHADERPROGRAMVPROC)(GLenum type, GLsizei count, const GLchar *const* strings); -typedef void (GLAD_API_PTR *PFNGLENABLEVERTEXARRAYATTRIBPROC)(GLuint vaobj, GLuint index); -typedef void (GLAD_API_PTR *PFNGLENDCONDITIONALRENDERPROC)(void); -typedef void (GLAD_API_PTR *PFNGLDELETELISTSPROC)(GLuint list, GLsizei range); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD2SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLDEBUGMESSAGECALLBACKPROC)(GLDEBUGPROC callback, const void * userParam); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1FPROC)(GLenum target, GLfloat s); -typedef void (GLAD_API_PTR *PFNGLGETCOMPRESSEDTEXIMAGEPROC)(GLenum target, GLint level, void * img); -typedef GLenum (GLAD_API_PTR *PFNGLCHECKFRAMEBUFFERSTATUSPROC)(GLenum target); -typedef void (GLAD_API_PTR *PFNGLGETINTERNALFORMATI64VPROC)(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint64 * params); -typedef void (GLAD_API_PTR *PFNGLGENERATEMIPMAPPROC)(GLenum target); -typedef void (GLAD_API_PTR *PFNGLDELETEQUERIESPROC)(GLsizei n, const GLuint * ids); -typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC)(GLuint framebuffer, GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLint basevertex); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1DPROC)(GLuint program, GLint location, GLdouble v0); -typedef void (GLAD_API_PTR *PFNGLALPHAFUNCPROC)(GLenum func, GLfloat ref); -typedef void (GLAD_API_PTR *PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC)(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (GLAD_API_PTR *PFNGLLINESTIPPLEPROC)(GLint factor, GLushort pattern); -typedef void (GLAD_API_PTR *PFNGLTEXGENIPROC)(GLenum coord, GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE3DMULTISAMPLEPROC)(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); -typedef GLboolean (GLAD_API_PTR *PFNGLISVERTEXARRAYPROC)(GLuint array); -typedef void (GLAD_API_PTR *PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC)(GLuint renderbuffer, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLINVALIDATEFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum * attachments); -typedef void (GLAD_API_PTR *PFNGLPROGRAMBINARYPROC)(GLuint program, GLenum binaryFormat, const void * binary, GLsizei length); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD4DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLVERTEX3IPROC)(GLint x, GLint y, GLint z); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3BPROC)(GLbyte red, GLbyte green, GLbyte blue); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS4SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLDISABLEIPROC)(GLenum target, GLuint index); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1SVPROC)(GLuint index, const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLINVALIDATETEXIMAGEPROC)(GLuint texture, GLint level); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2IPROC)(GLuint index, GLint x, GLint y); -typedef void (GLAD_API_PTR *PFNGLINDEXFPROC)(GLfloat c); -typedef void (GLAD_API_PTR *PFNGLPRIMITIVERESTARTINDEXPROC)(GLuint index); -typedef void (GLAD_API_PTR *PFNGLGETNCONVOLUTIONFILTERPROC)(GLenum target, GLenum format, GLenum type, GLsizei bufSize, void * image); -typedef GLenum (GLAD_API_PTR *PFNGLGETERRORPROC)(void); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4BVPROC)(GLuint index, const GLbyte * v); -typedef void (GLAD_API_PTR *PFNGLFLUSHMAPPEDBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length); -typedef void (GLAD_API_PTR *PFNGLTEXCOORDP1UIPROC)(GLenum type, GLuint coords); -typedef void (GLAD_API_PTR *PFNGLSAMPLECOVERAGEPROC)(GLfloat value, GLboolean invert); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2IVPROC)(GLenum target, const GLint * v); -typedef GLboolean (GLAD_API_PTR *PFNGLISPROGRAMPROC)(GLuint program); -typedef GLboolean (GLAD_API_PTR *PFNGLISLISTPROC)(GLuint list); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2DVPROC)(GLuint index, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIPROC)(GLenum target, GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLPUSHATTRIBPROC)(GLbitfield mask); -typedef void (GLAD_API_PTR *PFNGLFRONTFACEPROC)(GLenum mode); -typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLuint baseinstance); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1SPROC)(GLenum target, GLshort s); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3IPROC)(GLuint index, GLint x, GLint y, GLint z); -typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE1DPROC)(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width); -typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE3DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level, GLint zoffset); -typedef void (GLAD_API_PTR *PFNGLGENSAMPLERSPROC)(GLsizei count, GLuint * samplers); -typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERFPROC)(GLuint sampler, GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS4FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLPAUSETRANSFORMFEEDBACKPROC)(void); -typedef void (GLAD_API_PTR *PFNGLPOPNAMEPROC)(void); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1IVPROC)(GLuint index, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLEVALCOORD1FPROC)(GLfloat u); -typedef void (GLAD_API_PTR *PFNGLGENFRAMEBUFFERSPROC)(GLsizei n, GLuint * framebuffers); -typedef void (GLAD_API_PTR *PFNGLLIGHTIPROC)(GLenum light, GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLTEXTUREVIEWPROC)(GLuint texture, GLenum target, GLuint origtexture, GLenum internalformat, GLuint minlevel, GLuint numlevels, GLuint minlayer, GLuint numlayers); -typedef void (GLAD_API_PTR *PFNGLLOADTRANSPOSEMATRIXDPROC)(const GLdouble * m); -typedef void (GLAD_API_PTR *PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC)(GLuint framebuffer, GLenum attachment, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLUNIFORM4DPROC)(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI3UIPROC)(GLuint index, GLuint x, GLuint y, GLuint z); -typedef void (GLAD_API_PTR *PFNGLEDGEFLAGPOINTERPROC)(GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCPROC)(GLenum func, GLint ref, GLuint mask); -typedef void (GLAD_API_PTR *PFNGLUNIFORM1IPROC)(GLint location, GLint v0); -typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, GLuint * params); -typedef void (GLAD_API_PTR *PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC)(GLuint framebuffer, GLsizei numAttachments, const GLenum * attachments); -typedef void (GLAD_API_PTR *PFNGLPATCHPARAMETERFVPROC)(GLenum pname, const GLfloat * values); -typedef void (GLAD_API_PTR *PFNGLFOGFVPROC)(GLenum pname, const GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLVERTEXP3UIPROC)(GLenum type, GLuint value); -typedef void (GLAD_API_PTR *PFNGLREADNPIXELSPROC)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLsizei bufSize, void * data); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1IPROC)(GLenum target, GLint s); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBBINDINGPROC)(GLuint attribindex, GLuint bindingindex); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3DVPROC)(GLenum target, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLVERTEX4SPROC)(GLshort x, GLshort y, GLshort z, GLshort w); -typedef void (GLAD_API_PTR *PFNGLVERTEXBINDINGDIVISORPROC)(GLuint bindingindex, GLuint divisor); -typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERFVPROC)(GLuint texture, GLenum pname, const GLfloat * param); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLNORMAL3BPROC)(GLbyte nx, GLbyte ny, GLbyte nz); -typedef void (GLAD_API_PTR *PFNGLGETUNIFORMSUBROUTINEUIVPROC)(GLenum shadertype, GLint location, GLuint * params); -typedef void (GLAD_API_PTR *PFNGLVERTEX3SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3SVPROC)(GLenum target, const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERPARAMETERI64VPROC)(GLuint buffer, GLenum pname, GLint64 * params); -typedef void (GLAD_API_PTR *PFNGLDRAWPIXELSPROC)(GLsizei width, GLsizei height, GLenum format, GLenum type, const void * pixels); -typedef void (GLAD_API_PTR *PFNGLCALLLISTSPROC)(GLsizei n, GLenum type, const void * lists); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD3IPROC)(GLint s, GLint t, GLint r); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1); -typedef void (GLAD_API_PTR *PFNGLQUERYCOUNTERPROC)(GLuint id, GLenum target); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLUNIFORM1IVPROC)(GLint location, GLsizei count, const GLint * value); -typedef void (GLAD_API_PTR *PFNGLSTENCILFUNCSEPARATEPROC)(GLenum face, GLenum func, GLint ref, GLuint mask); -typedef void (GLAD_API_PTR *PFNGLGETNAMEDBUFFERPARAMETERIVPROC)(GLuint buffer, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLGETACTIVEATTRIBPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLint * size, GLenum * type, GLchar * name); -typedef void (GLAD_API_PTR *PFNGLENABLEVERTEXATTRIBARRAYPROC)(GLuint index); -typedef void (GLAD_API_PTR *PFNGLMATERIALIPROC)(GLenum face, GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLUNIFORM2FVPROC)(GLint location, GLsizei count, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS3FVPROC)(const GLfloat * v); -typedef GLint (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC)(GLuint program, GLenum programInterface, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLGETDOUBLEVPROC)(GLenum pname, GLdouble * data); -typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount, GLint basevertex); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2X4DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLCOLOR4BVPROC)(const GLbyte * v); -typedef void (GLAD_API_PTR *PFNGLGETINTERNALFORMATIVPROC)(GLenum target, GLenum internalformat, GLenum pname, GLsizei bufSize, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC)(GLuint program, GLenum shadertype, GLuint index, GLenum pname, GLint * values); -typedef void (GLAD_API_PTR *PFNGLGETQUERYINDEXEDIVPROC)(GLenum target, GLuint index, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLBINDVERTEXBUFFERPROC)(GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD3FPROC)(GLfloat s, GLfloat t, GLfloat r); -typedef void (GLAD_API_PTR *PFNGLCOLOR3UIVPROC)(const GLuint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NBVPROC)(GLuint index, const GLbyte * v); -typedef void (GLAD_API_PTR *PFNGLCLEARPROC)(GLbitfield mask); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS2DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD2SPROC)(GLshort s, GLshort t); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP4UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURELAYERPROC)(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (GLAD_API_PTR *PFNGLTEXENVIPROC)(GLenum target, GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERFPROC)(GLuint texture, GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLMATERIALFPROC)(GLenum face, GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLGETUNIFORMDVPROC)(GLuint program, GLint location, GLdouble * params); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value); -typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERIUIVPROC)(GLenum target, GLenum pname, const GLuint * params); -typedef void (GLAD_API_PTR *PFNGLCLEARINDEXPROC)(GLfloat c); -typedef void (GLAD_API_PTR *PFNGLDISPATCHCOMPUTEINDIRECTPROC)(GLintptr indirect); -typedef void (GLAD_API_PTR *PFNGLROTATEFPROC)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAD_API_PTR *PFNGLTEXTURESUBIMAGE1DPROC)(GLuint texture, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const void * pixels); -typedef void (GLAD_API_PTR *PFNGLPOLYGONOFFSETCLAMPPROC)(GLfloat factor, GLfloat units, GLfloat clamp); -typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, const GLuint * param); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3SPROC)(GLshort red, GLshort green, GLshort blue); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBLDVPROC)(GLuint index, GLenum pname, GLdouble * params); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS2FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLSHADEMODELPROC)(GLenum mode); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4DVPROC)(GLuint program, GLint location, GLsizei count, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLNORMAL3FVPROC)(const GLfloat * v); -typedef GLboolean (GLAD_API_PTR *PFNGLISBUFFERPROC)(GLuint buffer); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3FPROC)(GLenum target, GLfloat s, GLfloat t, GLfloat r); -typedef void (GLAD_API_PTR *PFNGLBINDFRAMEBUFFERPROC)(GLenum target, GLuint framebuffer); -typedef void (GLAD_API_PTR *PFNGLBINDFRAGDATALOCATIONINDEXEDPROC)(GLuint program, GLuint colorNumber, GLuint index, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLBINDBUFFERBASEPROC)(GLenum target, GLuint index, GLuint buffer); -typedef void (GLAD_API_PTR *PFNGLGENBUFFERSPROC)(GLsizei n, GLuint * buffers); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD1FPROC)(GLfloat s); -typedef void (GLAD_API_PTR *PFNGLGETBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, void * data); -typedef void (GLAD_API_PTR *PFNGLCREATETRANSFORMFEEDBACKSPROC)(GLsizei n, GLuint * ids); -typedef void (GLAD_API_PTR *PFNGLMAP2FPROC)(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, const GLfloat * points); -typedef void (GLAD_API_PTR *PFNGLCREATEBUFFERSPROC)(GLsizei n, GLuint * buffers); -typedef void (GLAD_API_PTR *PFNGLCOLOR3USVPROC)(const GLushort * v); -typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, GLfloat * params); -typedef GLint (GLAD_API_PTR *PFNGLGETUNIFORMLOCATIONPROC)(GLuint program, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLVERTEX2DPROC)(GLdouble x, GLdouble y); -typedef GLint (GLAD_API_PTR *PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC)(GLuint program, GLenum shadertype, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLINVALIDATEBUFFERSUBDATAPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length); -typedef void (GLAD_API_PTR *PFNGLUNIFORMMATRIX2DVPROC)(GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLCLEARNAMEDBUFFERSUBDATAPROC)(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void * data); -typedef void (GLAD_API_PTR *PFNGLGETPROGRAMIVPROC)(GLuint program, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLDRAWRANGEELEMENTSPROC)(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const void * indices); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLGETINTEGER64I_VPROC)(GLenum target, GLuint index, GLint64 * data); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL1DPROC)(GLuint index, GLdouble x); -typedef void (GLAD_API_PTR *PFNGLGETTEXTUREIMAGEPROC)(GLuint texture, GLint level, GLenum format, GLenum type, GLsizei bufSize, void * pixels); -typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMIVPROC)(GLuint program, GLint location, GLsizei bufSize, GLint * params); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1IPROC)(GLuint program, GLint location, GLint v0); -typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC)(GLenum mode, GLuint id, GLsizei instancecount); -typedef GLuint (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCEINDEXPROC)(GLuint program, GLenum programInterface, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2DPROC)(GLuint program, GLint location, GLdouble v0, GLdouble v1); -typedef GLboolean (GLAD_API_PTR *PFNGLUNMAPNAMEDBUFFERPROC)(GLuint buffer); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2FPROC)(GLenum target, GLfloat s, GLfloat t); -typedef void (GLAD_API_PTR *PFNGLPOINTPARAMETERFVPROC)(GLenum pname, const GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLBINDBUFFERRANGEPROC)(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2DVPROC)(GLenum target, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLCOLORMATERIALPROC)(GLenum face, GLenum mode); -typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONPROC)(GLenum mode); -typedef void (GLAD_API_PTR *PFNGLBLITFRAMEBUFFERPROC)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -typedef void (GLAD_API_PTR *PFNGLCOLOR3DPROC)(GLdouble red, GLdouble green, GLdouble blue); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD3IVPROC)(GLenum target, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLLIGHTFVPROC)(GLenum light, GLenum pname, const GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1DVPROC)(GLuint index, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLDEPTHMASKPROC)(GLboolean flag); -typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKVARYINGPROC)(GLuint program, GLuint index, GLsizei bufSize, GLsizei * length, GLsizei * size, GLenum * type, GLchar * name); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1UIPROC)(GLuint program, GLint location, GLuint v0); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBL3DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINDIRECTPROC)(GLenum mode, GLenum type, const void * indirect); -typedef void (GLAD_API_PTR *PFNGLLOADTRANSPOSEMATRIXFPROC)(const GLfloat * m); -typedef void (GLAD_API_PTR *PFNGLENDQUERYINDEXEDPROC)(GLenum target, GLuint index); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3USPROC)(GLushort red, GLushort green, GLushort blue); -typedef void (GLAD_API_PTR *PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC)(GLuint texture, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations); -typedef void (GLAD_API_PTR *PFNGLPIXELSTOREFPROC)(GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLUNIFORM2IVPROC)(GLint location, GLsizei count, const GLint * value); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS2SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLVERTEX2IPROC)(GLint x, GLint y); -typedef void (GLAD_API_PTR *PFNGLFRUSTUMPROC)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar); -typedef void (GLAD_API_PTR *PFNGLMEMORYBARRIERPROC)(GLbitfield barriers); -typedef const GLubyte * (GLAD_API_PTR *PFNGLGETSTRINGPROC)(GLenum name); -typedef void (GLAD_API_PTR *PFNGLLINEWIDTHPROC)(GLfloat width); -typedef void (GLAD_API_PTR *PFNGLNORMALPOINTERPROC)(GLenum type, GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMUIVPROC)(GLuint program, GLint location, GLsizei bufSize, GLuint * params); -typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEARRAYVPROC)(GLuint first, GLsizei count, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORDP2UIPROC)(GLenum type, GLuint coords); -typedef void (GLAD_API_PTR *PFNGLATTACHSHADERPROC)(GLuint program, GLuint shader); -typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSPROC)(GLenum mode, GLint first, GLsizei count); -typedef void (GLAD_API_PTR *PFNGLCOLOR4SPROC)(GLshort red, GLshort green, GLshort blue, GLshort alpha); -typedef void (GLAD_API_PTR *PFNGLTEXGENDVPROC)(GLenum coord, GLenum pname, const GLdouble * params); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIUIVPROC)(GLuint sampler, GLenum pname, GLuint * params); -typedef void (GLAD_API_PTR *PFNGLENDQUERYPROC)(GLenum target); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS2SPROC)(GLshort x, GLshort y); -typedef void (GLAD_API_PTR *PFNGLDRAWARRAYSINDIRECTPROC)(GLenum mode, const void * indirect); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS3SPROC)(GLshort x, GLshort y, GLshort z); -typedef void (GLAD_API_PTR *PFNGLGETNPIXELMAPFVPROC)(GLenum map, GLsizei bufSize, GLfloat * values); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD3SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLRECTIPROC)(GLint x1, GLint y1, GLint x2, GLint y2); -typedef void (GLAD_API_PTR *PFNGLUNIFORM4DVPROC)(GLint location, GLsizei count, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLBLENDEQUATIONSEPARATEIPROC)(GLuint buf, GLenum modeRGB, GLenum modeAlpha); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCEIVPROC)(GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum * props, GLsizei bufSize, GLsizei * length, GLint * params); -typedef void (GLAD_API_PTR *PFNGLINVALIDATESUBFRAMEBUFFERPROC)(GLenum target, GLsizei numAttachments, const GLenum * attachments, GLint x, GLint y, GLsizei width, GLsizei height); -typedef GLsync (GLAD_API_PTR *PFNGLFENCESYNCPROC)(GLenum condition, GLbitfield flags); -typedef void (GLAD_API_PTR *PFNGLUNIFORM3UIPROC)(GLint location, GLuint v0, GLuint v1, GLuint v2); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLORP3UIVPROC)(GLenum type, const GLuint * color); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB1SPROC)(GLuint index, GLshort x); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NSVPROC)(GLuint index, const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLLOADMATRIXFPROC)(const GLfloat * m); -typedef void (GLAD_API_PTR *PFNGLTRANSLATEFPROC)(GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4SVPROC)(GLenum target, const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2IVPROC)(GLuint program, GLint location, GLsizei count, const GLint * value); -typedef void (GLAD_API_PTR *PFNGLMAPGRID2FPROC)(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2); -typedef void (GLAD_API_PTR *PFNGLENABLECLIENTSTATEPROC)(GLenum array); -typedef void (GLAD_API_PTR *PFNGLGETUNIFORMIVPROC)(GLuint program, GLint location, GLint * params); -typedef void (GLAD_API_PTR *PFNGLEVALCOORD1DVPROC)(const GLdouble * u); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI4IVPROC)(GLuint index, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4SVPROC)(GLuint index, const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLGETMULTISAMPLEFVPROC)(GLenum pname, GLuint index, GLfloat * val); -typedef void (GLAD_API_PTR *PFNGLINDEXDVPROC)(const GLdouble * c); -typedef void (GLAD_API_PTR *PFNGLBLENDFUNCIPROC)(GLuint buf, GLenum src, GLenum dst); -typedef GLboolean (GLAD_API_PTR *PFNGLISENABLEDPROC)(GLenum cap); -typedef void (GLAD_API_PTR *PFNGLGETPIXELMAPUSVPROC)(GLenum map, GLushort * values); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS3IVPROC)(const GLint * v); -typedef void * (GLAD_API_PTR *PFNGLMAPBUFFERRANGEPROC)(GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2SPROC)(GLenum target, GLshort s, GLshort t); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS2FPROC)(GLfloat x, GLfloat y); -typedef void (GLAD_API_PTR *PFNGLMINSAMPLESHADINGPROC)(GLfloat value); -typedef void (GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTUI64VPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2IPROC)(GLenum target, GLint s, GLint t); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP3UIVPROC)(GLuint index, GLenum type, GLboolean normalized, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLVERTEX2FPROC)(GLfloat x, GLfloat y); -typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYBINDINGDIVISORPROC)(GLuint vaobj, GLuint bindingindex, GLuint divisor); -typedef void (GLAD_API_PTR *PFNGLINDEXPOINTERPROC)(GLenum type, GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLUNIFORMBLOCKBINDINGPROC)(GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding); -typedef GLint (GLAD_API_PTR *PFNGLRENDERMODEPROC)(GLenum mode); -typedef void (GLAD_API_PTR *PFNGLTEXSTORAGE1DPROC)(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width); -typedef void (GLAD_API_PTR *PFNGLBUFFERSUBDATAPROC)(GLenum target, GLintptr offset, GLsizeiptr size, const void * data); -typedef void (GLAD_API_PTR *PFNGLCOLOR3FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLBITMAPPROC)(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte * bitmap); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLVIEWPORTINDEXEDFPROC)(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS2DPROC)(GLdouble x, GLdouble y); -typedef void (GLAD_API_PTR *PFNGLGETUNIFORMINDICESPROC)(GLuint program, GLsizei uniformCount, const GLchar *const* uniformNames, GLuint * uniformIndices); -typedef void (GLAD_API_PTR *PFNGLENABLEIPROC)(GLenum target, GLuint index); -typedef void (GLAD_API_PTR *PFNGLFRAMEBUFFERTEXTURE2DPROC)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level); -typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEPROC)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha); -typedef void (GLAD_API_PTR *PFNGLNAMEDBUFFERSTORAGEPROC)(GLuint buffer, GLsizeiptr size, const void * data, GLbitfield flags); -typedef void (GLAD_API_PTR *PFNGLRECTSPROC)(GLshort x1, GLshort y1, GLshort x2, GLshort y2); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2FVPROC)(GLuint program, GLint location, GLsizei count, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLPOLYGONSTIPPLEPROC)(const GLubyte * mask); -typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE3DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLOR3UBPROC)(GLubyte red, GLubyte green, GLubyte blue); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3FPROC)(GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIVPROC)(GLuint sampler, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLSHADERSTORAGEBLOCKBINDINGPROC)(GLuint program, GLuint storageBlockIndex, GLuint storageBlockBinding); -typedef void (GLAD_API_PTR *PFNGLLOADIDENTITYPROC)(void); -typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC)(GLenum mode, const GLsizei * count, GLenum type, const void *const* indices, GLsizei drawcount, const GLint * basevertex); -typedef void (GLAD_API_PTR *PFNGLVERTEX2SPROC)(GLshort x, GLshort y); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1IVPROC)(GLenum target, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4SPROC)(GLenum target, GLshort s, GLshort t, GLshort r, GLshort q); -typedef void (GLAD_API_PTR *PFNGLRELEASESHADERCOMPILERPROC)(void); -typedef void (GLAD_API_PTR *PFNGLGETSHADERSOURCEPROC)(GLuint shader, GLsizei bufSize, GLsizei * length, GLchar * source); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD2SVPROC)(GLenum target, const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLTEXPARAMETERFVPROC)(GLenum target, GLenum pname, const GLfloat * params); -typedef GLboolean (GLAD_API_PTR *PFNGLISSHADERPROC)(GLuint shader); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4IVPROC)(GLuint index, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD4IPROC)(GLint s, GLint t, GLint r, GLint q); -typedef void (GLAD_API_PTR *PFNGLCOLOR4UIPROC)(GLuint red, GLuint green, GLuint blue, GLuint alpha); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX3DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLGETTEXENVFVPROC)(GLenum target, GLenum pname, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD4DPROC)(GLdouble s, GLdouble t, GLdouble r, GLdouble q); -typedef void (GLAD_API_PTR *PFNGLSCISSORARRAYVPROC)(GLuint first, GLsizei count, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLCREATERENDERBUFFERSPROC)(GLsizei n, GLuint * renderbuffers); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3FVPROC)(GLuint index, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLCOLOR4FPROC)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NUBPROC)(GLuint index, GLubyte x, GLubyte y, GLubyte z, GLubyte w); -typedef void (GLAD_API_PTR *PFNGLGETSAMPLERPARAMETERIIVPROC)(GLuint sampler, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLCOPYTEXSUBIMAGE2DPROC)(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLNORMAL3IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLBINDIMAGETEXTURESPROC)(GLuint first, GLsizei count, const GLuint * textures); -typedef void (GLAD_API_PTR *PFNGLTEXGENIVPROC)(GLenum coord, GLenum pname, const GLint * params); -typedef void (GLAD_API_PTR *PFNGLCOMPRESSEDTEXIMAGE3DPROC)(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const void * data); -typedef void (GLAD_API_PTR *PFNGLSCALEDPROC)(GLdouble x, GLdouble y, GLdouble z); -typedef void (GLAD_API_PTR *PFNGLCREATEPROGRAMPIPELINESPROC)(GLsizei n, GLuint * pipelines); -typedef void (GLAD_API_PTR *PFNGLBLENDFUNCSEPARATEIPROC)(GLuint buf, GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha); -typedef void (GLAD_API_PTR *PFNGLHINTPROC)(GLenum target, GLenum mode); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4IPROC)(GLenum target, GLint s, GLint t, GLint r, GLint q); -typedef void (GLAD_API_PTR *PFNGLINDEXMASKPROC)(GLuint mask); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2FPROC)(GLuint program, GLint location, GLfloat v0, GLfloat v1); -typedef void (GLAD_API_PTR *PFNGLCOLOR3BPROC)(GLbyte red, GLbyte green, GLbyte blue); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI1UIVPROC)(GLuint index, const GLuint * v); -typedef void (GLAD_API_PTR *PFNGLSPECIALIZESHADERPROC)(GLuint shader, const GLchar * pEntryPoint, GLuint numSpecializationConstants, const GLuint * pConstantIndex, const GLuint * pConstantValue); -typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC)(GLuint framebuffer, GLenum buf); -typedef void (GLAD_API_PTR *PFNGLGETQUERYBUFFEROBJECTI64VPROC)(GLuint id, GLuint buffer, GLenum pname, GLintptr offset); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD3IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLSAMPLERPARAMETERFVPROC)(GLuint sampler, GLenum pname, const GLfloat * param); -typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIIVPROC)(GLuint index, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLBUFFERSTORAGEPROC)(GLenum target, GLsizeiptr size, const void * data, GLbitfield flags); -typedef void (GLAD_API_PTR *PFNGLVERTEX3SPROC)(GLshort x, GLshort y, GLshort z); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM2UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLDEPTHRANGEPROC)(GLdouble n, GLdouble f); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS3FPROC)(GLfloat x, GLfloat y, GLfloat z); -typedef void (GLAD_API_PTR *PFNGLDELETESHADERPROC)(GLuint shader); -typedef void (GLAD_API_PTR *PFNGLCOLOR3BVPROC)(const GLbyte * v); -typedef void (GLAD_API_PTR *PFNGLCOLOR3UBVPROC)(const GLubyte * v); -typedef void (GLAD_API_PTR *PFNGLGETVERTEXATTRIBIVPROC)(GLuint index, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD4SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLMAP2DPROC)(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, const GLdouble * points); -typedef void (GLAD_API_PTR *PFNGLFOGCOORDFPROC)(GLfloat coord); -typedef void (GLAD_API_PTR *PFNGLEDGEFLAGVPROC)(const GLboolean * flag); -typedef void (GLAD_API_PTR *PFNGLCLIPCONTROLPROC)(GLenum origin, GLenum depth); -typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERIVPROC)(GLenum target, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETTRANSFORMFEEDBACKIVPROC)(GLuint xfb, GLenum pname, GLint * param); -typedef void (GLAD_API_PTR *PFNGLGETPROGRAMPIPELINEIVPROC)(GLuint pipeline, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLGETNMINMAXPROC)(GLenum target, GLboolean reset, GLenum format, GLenum type, GLsizei bufSize, void * values); -typedef void (GLAD_API_PTR *PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC)(GLuint renderbuffer, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLCOLORP4UIPROC)(GLenum type, GLuint color); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1SVPROC)(GLenum target, const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4FVPROC)(GLuint index, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4DVPROC)(GLuint index, const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXP4UIPROC)(GLenum type, GLuint value); -typedef void (GLAD_API_PTR *PFNGLRECTFVPROC)(const GLfloat * v1, const GLfloat * v2); -typedef void (GLAD_API_PTR *PFNGLBEGINTRANSFORMFEEDBACKPROC)(GLenum primitiveMode); -typedef void (GLAD_API_PTR *PFNGLARRAYELEMENTPROC)(GLint i); -typedef void (GLAD_API_PTR *PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC)(GLuint framebuffer, GLenum attachment, GLuint texture, GLint level, GLint layer); -typedef void (GLAD_API_PTR *PFNGLBEGINPROC)(GLenum mode); -typedef void (GLAD_API_PTR *PFNGLTEXCOORDPOINTERPROC)(GLint size, GLenum type, GLsizei stride, const void * pointer); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD3DPROC)(GLdouble s, GLdouble t, GLdouble r); -typedef void (GLAD_API_PTR *PFNGLUNIFORM1FVPROC)(GLint location, GLsizei count, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB2SVPROC)(GLuint index, const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLGETPROGRAMPIPELINEINFOLOGPROC)(GLuint pipeline, GLsizei bufSize, GLsizei * length, GLchar * infoLog); -typedef void (GLAD_API_PTR *PFNGLPOLYGONOFFSETPROC)(GLfloat factor, GLfloat units); -typedef void (GLAD_API_PTR *PFNGLGETSHADERPRECISIONFORMATPROC)(GLenum shadertype, GLenum precisiontype, GLint * range, GLint * precision); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM3DPROC)(GLuint program, GLint location, GLdouble v0, GLdouble v1, GLdouble v2); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble * value); -typedef void (GLAD_API_PTR *PFNGLBINDTRANSFORMFEEDBACKPROC)(GLenum target, GLuint id); -typedef void (GLAD_API_PTR *PFNGLPROVOKINGVERTEXPROC)(GLenum mode); -typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXARRAYATTRIBPROC)(GLuint vaobj, GLuint index); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD4FVPROC)(GLenum target, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLUNIFORM1DPROC)(GLint location, GLdouble x); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBFORMATPROC)(GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); -typedef void (GLAD_API_PTR *PFNGLMEMORYBARRIERBYREGIONPROC)(GLbitfield barriers); -typedef void (GLAD_API_PTR *PFNGLPOPDEBUGGROUPPROC)(void); -typedef void (GLAD_API_PTR *PFNGLCOLOR4BPROC)(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha); -typedef void (GLAD_API_PTR *PFNGLTEXTUREBUFFERPROC)(GLuint texture, GLenum internalformat, GLuint buffer); -typedef void (GLAD_API_PTR *PFNGLGETSHADERIVPROC)(GLuint shader, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLBEGINQUERYINDEXEDPROC)(GLenum target, GLuint index, GLuint id); -typedef void (GLAD_API_PTR *PFNGLCOPYNAMEDBUFFERSUBDATAPROC)(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -typedef void (GLAD_API_PTR *PFNGLVERTEXARRAYATTRIBFORMATPROC)(GLuint vaobj, GLuint attribindex, GLint size, GLenum type, GLboolean normalized, GLuint relativeoffset); -typedef void * (GLAD_API_PTR *PFNGLMAPNAMEDBUFFERRANGEPROC)(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); -typedef void (GLAD_API_PTR *PFNGLCOLOR4UIVPROC)(const GLuint * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP1UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3SVPROC)(const GLshort * v); -typedef void (GLAD_API_PTR *PFNGLFOGIVPROC)(GLenum pname, const GLint * params); -typedef void (GLAD_API_PTR *PFNGLTEXTUREPARAMETERIIVPROC)(GLuint texture, GLenum pname, const GLint * params); -typedef void (GLAD_API_PTR *PFNGLLISTBASEPROC)(GLuint base); -typedef void (GLAD_API_PTR *PFNGLCREATEFRAMEBUFFERSPROC)(GLsizei n, GLuint * framebuffers); -typedef void (GLAD_API_PTR *PFNGLEVALCOORD2FPROC)(GLfloat u, GLfloat v); -typedef void (GLAD_API_PTR *PFNGLVERTEX4DVPROC)(const GLdouble * v); -typedef void (GLAD_API_PTR *PFNGLDELETEPROGRAMPROC)(GLuint program); -typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices); -typedef void (GLAD_API_PTR *PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC)(GLenum mode, GLuint id, GLuint stream); -typedef void (GLAD_API_PTR *PFNGLVALIDATEPROGRAMPROC)(GLuint program); -typedef void (GLAD_API_PTR *PFNGLDRAWELEMENTSINSTANCEDPROC)(GLenum mode, GLsizei count, GLenum type, const void * indices, GLsizei instancecount); -typedef GLuint (GLAD_API_PTR *PFNGLGENLISTSPROC)(GLsizei range); -typedef void (GLAD_API_PTR *PFNGLCOLOR4IPROC)(GLint red, GLint green, GLint blue, GLint alpha); -typedef void (GLAD_API_PTR *PFNGLCOLOR3UIPROC)(GLuint red, GLuint green, GLuint blue); -typedef void (GLAD_API_PTR *PFNGLCREATETEXTURESPROC)(GLenum target, GLsizei n, GLuint * textures); -typedef void (GLAD_API_PTR *PFNGLCOLORP4UIVPROC)(GLenum type, const GLuint * color); -typedef void (GLAD_API_PTR *PFNGLGETPROGRAMINFOLOGPROC)(GLuint program, GLsizei bufSize, GLsizei * length, GLchar * infoLog); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBP3UIPROC)(GLuint index, GLenum type, GLboolean normalized, GLuint value); -typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERFIPROC)(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil); -typedef void (GLAD_API_PTR *PFNGLCOPYTEXTURESUBIMAGE3DPROC)(GLuint texture, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLsizei height); -typedef void (GLAD_API_PTR *PFNGLEDGEFLAGPROC)(GLboolean flag); -typedef void (GLAD_API_PTR *PFNGLGETBUFFERPARAMETERI64VPROC)(GLenum target, GLenum pname, GLint64 * params); -typedef void (GLAD_API_PTR *PFNGLRASTERPOS2IVPROC)(const GLint * v); -typedef void (GLAD_API_PTR *PFNGLGETNMAPIVPROC)(GLenum target, GLenum query, GLsizei bufSize, GLint * v); -typedef void (GLAD_API_PTR *PFNGLRECTDVPROC)(const GLdouble * v1, const GLdouble * v2); -typedef void (GLAD_API_PTR *PFNGLGETBOOLEANI_VPROC)(GLenum target, GLuint index, GLboolean * data); -typedef void (GLAD_API_PTR *PFNGLENDLISTPROC)(void); -typedef void (GLAD_API_PTR *PFNGLFLUSHPROC)(void); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM4UIPROC)(GLuint program, GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -typedef void (GLAD_API_PTR *PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC)(GLenum mode, GLenum type, const void * indirect, GLintptr drawcount, GLsizei maxdrawcount, GLsizei stride); -typedef void (GLAD_API_PTR *PFNGLGETINTEGER64VPROC)(GLenum pname, GLint64 * data); -typedef void (GLAD_API_PTR *PFNGLLIGHTMODELFPROC)(GLenum pname, GLfloat param); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB4NIVPROC)(GLuint index, const GLint * v); -typedef void (GLAD_API_PTR *PFNGLGETTEXTURELEVELPARAMETERIVPROC)(GLuint texture, GLint level, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLLOADMATRIXDPROC)(const GLdouble * m); -typedef void (GLAD_API_PTR *PFNGLBINDPROGRAMPIPELINEPROC)(GLuint pipeline); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORM1UIVPROC)(GLuint program, GLint location, GLsizei count, const GLuint * value); -typedef void (GLAD_API_PTR *PFNGLDISABLEVERTEXATTRIBARRAYPROC)(GLuint index); -typedef void (GLAD_API_PTR *PFNGLCLEARDEPTHPROC)(GLdouble depth); -typedef void (GLAD_API_PTR *PFNGLGETTEXPARAMETERIIVPROC)(GLenum target, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLWINDOWPOS3FVPROC)(const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIB3DPROC)(GLuint index, GLdouble x, GLdouble y, GLdouble z); -typedef GLint (GLAD_API_PTR *PFNGLGETPROGRAMRESOURCELOCATIONPROC)(GLuint program, GLenum programInterface, const GLchar * name); -typedef void (GLAD_API_PTR *PFNGLTEXCOORD2DPROC)(GLdouble s, GLdouble t); -typedef void (GLAD_API_PTR *PFNGLACCUMPROC)(GLenum op, GLfloat value); -typedef void (GLAD_API_PTR *PFNGLSECONDARYCOLORP3UIPROC)(GLenum type, GLuint color); -typedef void (GLAD_API_PTR *PFNGLVERTEXATTRIBI2UIPROC)(GLuint index, GLuint x, GLuint y); -typedef void (GLAD_API_PTR *PFNGLGETNUNIFORMFVPROC)(GLuint program, GLint location, GLsizei bufSize, GLfloat * params); -typedef void (GLAD_API_PTR *PFNGLFOGIPROC)(GLenum pname, GLint param); -typedef void (GLAD_API_PTR *PFNGLCLEARBUFFERFVPROC)(GLenum buffer, GLint drawbuffer, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLTEXENVIVPROC)(GLenum target, GLenum pname, const GLint * params); -typedef void (GLAD_API_PTR *PFNGLTEXIMAGE2DPROC)(GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void * pixels); -typedef void (GLAD_API_PTR *PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC)(GLuint program, GLuint bufferIndex, GLenum pname, GLint * params); -typedef void (GLAD_API_PTR *PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat * value); -typedef void (GLAD_API_PTR *PFNGLMULTITEXCOORD1FVPROC)(GLenum target, const GLfloat * v); -typedef void (GLAD_API_PTR *PFNGLGETOBJECTPTRLABELPROC)(const void * ptr, GLsizei bufSize, GLsizei * length, GLchar * label); - -GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv; + GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIIVPROC glad_glGetTextureParameterIiv; #define glGetTextureParameterIiv glad_glGetTextureParameterIiv -GLAD_API_CALL PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv; + GLAD_API_CALL PFNGLTEXCOORDP1UIVPROC glad_glTexCoordP1uiv; #define glTexCoordP1uiv glad_glTexCoordP1uiv -GLAD_API_CALL PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample; + GLAD_API_CALL PFNGLTEXTURESTORAGE3DMULTISAMPLEPROC glad_glTextureStorage3DMultisample; #define glTextureStorage3DMultisample glad_glTextureStorage3DMultisample -GLAD_API_CALL PFNGLEVALPOINT2PROC glad_glEvalPoint2; + GLAD_API_CALL PFNGLEVALPOINT2PROC glad_glEvalPoint2; #define glEvalPoint2 glad_glEvalPoint2 -GLAD_API_CALL PFNGLVERTEXARRAYATTRIBBINDINGPROC glad_glVertexArrayAttribBinding; + GLAD_API_CALL PFNGLVERTEXARRAYATTRIBBINDINGPROC glad_glVertexArrayAttribBinding; #define glVertexArrayAttribBinding glad_glVertexArrayAttribBinding -GLAD_API_CALL PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange; + GLAD_API_CALL PFNGLFLUSHMAPPEDNAMEDBUFFERRANGEPROC glad_glFlushMappedNamedBufferRange; #define glFlushMappedNamedBufferRange glad_glFlushMappedNamedBufferRange -GLAD_API_CALL PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv; + GLAD_API_CALL PFNGLGETNAMEDFRAMEBUFFERPARAMETERIVPROC glad_glGetNamedFramebufferParameteriv; #define glGetNamedFramebufferParameteriv glad_glGetNamedFramebufferParameteriv -GLAD_API_CALL PFNGLPIXELTRANSFERFPROC glad_glPixelTransferf; + GLAD_API_CALL PFNGLPIXELTRANSFERFPROC glad_glPixelTransferf; #define glPixelTransferf glad_glPixelTransferf -GLAD_API_CALL PFNGLGETFLOATI_VPROC glad_glGetFloati_v; + GLAD_API_CALL PFNGLGETFLOATI_VPROC glad_glGetFloati_v; #define glGetFloati_v glad_glGetFloati_v -GLAD_API_CALL PFNGLLOADNAMEPROC glad_glLoadName; + GLAD_API_CALL PFNGLLOADNAMEPROC glad_glLoadName; #define glLoadName glad_glLoadName -GLAD_API_CALL PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; + GLAD_API_CALL PFNGLUNIFORMMATRIX4FVPROC glad_glUniformMatrix4fv; #define glUniformMatrix4fv glad_glUniformMatrix4fv -GLAD_API_CALL PFNGLSECONDARYCOLOR3SVPROC glad_glSecondaryColor3sv; + GLAD_API_CALL PFNGLSECONDARYCOLOR3SVPROC glad_glSecondaryColor3sv; #define glSecondaryColor3sv glad_glSecondaryColor3sv -GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE1DPROC glad_glCopyTextureSubImage1D; + GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE1DPROC glad_glCopyTextureSubImage1D; #define glCopyTextureSubImage1D glad_glCopyTextureSubImage1D -GLAD_API_CALL PFNGLSECONDARYCOLOR3UIVPROC glad_glSecondaryColor3uiv; + GLAD_API_CALL PFNGLSECONDARYCOLOR3UIVPROC glad_glSecondaryColor3uiv; #define glSecondaryColor3uiv glad_glSecondaryColor3uiv -GLAD_API_CALL PFNGLUNIFORM1DVPROC glad_glUniform1dv; + GLAD_API_CALL PFNGLUNIFORM1DVPROC glad_glUniform1dv; #define glUniform1dv glad_glUniform1dv -GLAD_API_CALL PFNGLWINDOWPOS3DVPROC glad_glWindowPos3dv; + GLAD_API_CALL PFNGLWINDOWPOS3DVPROC glad_glWindowPos3dv; #define glWindowPos3dv glad_glWindowPos3dv -GLAD_API_CALL PFNGLSECONDARYCOLOR3BVPROC glad_glSecondaryColor3bv; + GLAD_API_CALL PFNGLSECONDARYCOLOR3BVPROC glad_glSecondaryColor3bv; #define glSecondaryColor3bv glad_glSecondaryColor3bv -GLAD_API_CALL PFNGLSECONDARYCOLOR3UIPROC glad_glSecondaryColor3ui; + GLAD_API_CALL PFNGLSECONDARYCOLOR3UIPROC glad_glSecondaryColor3ui; #define glSecondaryColor3ui glad_glSecondaryColor3ui -GLAD_API_CALL PFNGLGETNCOLORTABLEPROC glad_glGetnColorTable; + GLAD_API_CALL PFNGLGETNCOLORTABLEPROC glad_glGetnColorTable; #define glGetnColorTable glad_glGetnColorTable -GLAD_API_CALL PFNGLRASTERPOS3IPROC glad_glRasterPos3i; + GLAD_API_CALL PFNGLRASTERPOS3IPROC glad_glRasterPos3i; #define glRasterPos3i glad_glRasterPos3i -GLAD_API_CALL PFNGLACTIVETEXTUREPROC glad_glActiveTexture; + GLAD_API_CALL PFNGLACTIVETEXTUREPROC glad_glActiveTexture; #define glActiveTexture glad_glActiveTexture -GLAD_API_CALL PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv; + GLAD_API_CALL PFNGLVERTEXATTRIB4NUIVPROC glad_glVertexAttrib4Nuiv; #define glVertexAttrib4Nuiv glad_glVertexAttrib4Nuiv -GLAD_API_CALL PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData; + GLAD_API_CALL PFNGLCLEARNAMEDBUFFERDATAPROC glad_glClearNamedBufferData; #define glClearNamedBufferData glad_glClearNamedBufferData -GLAD_API_CALL PFNGLNORMAL3DPROC glad_glNormal3d; + GLAD_API_CALL PFNGLNORMAL3DPROC glad_glNormal3d; #define glNormal3d glad_glNormal3d -GLAD_API_CALL PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glad_glInvalidateNamedFramebufferSubData; + GLAD_API_CALL PFNGLINVALIDATENAMEDFRAMEBUFFERSUBDATAPROC glad_glInvalidateNamedFramebufferSubData; #define glInvalidateNamedFramebufferSubData glad_glInvalidateNamedFramebufferSubData -GLAD_API_CALL PFNGLBINDBUFFERSBASEPROC glad_glBindBuffersBase; + GLAD_API_CALL PFNGLBINDBUFFERSBASEPROC glad_glBindBuffersBase; #define glBindBuffersBase glad_glBindBuffersBase -GLAD_API_CALL PFNGLEVALCOORD1DPROC glad_glEvalCoord1d; + GLAD_API_CALL PFNGLEVALCOORD1DPROC glad_glEvalCoord1d; #define glEvalCoord1d glad_glEvalCoord1d -GLAD_API_CALL PFNGLGETMAPFVPROC glad_glGetMapfv; + GLAD_API_CALL PFNGLGETMAPFVPROC glad_glGetMapfv; #define glGetMapfv glad_glGetMapfv -GLAD_API_CALL PFNGLISSYNCPROC glad_glIsSync; + GLAD_API_CALL PFNGLISSYNCPROC glad_glIsSync; #define glIsSync glad_glIsSync -GLAD_API_CALL PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; + GLAD_API_CALL PFNGLTEXSUBIMAGE2DPROC glad_glTexSubImage2D; #define glTexSubImage2D glad_glTexSubImage2D -GLAD_API_CALL PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; + GLAD_API_CALL PFNGLGETATTRIBLOCATIONPROC glad_glGetAttribLocation; #define glGetAttribLocation glad_glGetAttribLocation -GLAD_API_CALL PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D; + GLAD_API_CALL PFNGLCOPYTEXIMAGE1DPROC glad_glCopyTexImage1D; #define glCopyTexImage1D glad_glCopyTexImage1D -GLAD_API_CALL PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i; + GLAD_API_CALL PFNGLPROGRAMUNIFORM4IPROC glad_glProgramUniform4i; #define glProgramUniform4i glad_glProgramUniform4i -GLAD_API_CALL PFNGLGETPIXELMAPFVPROC glad_glGetPixelMapfv; + GLAD_API_CALL PFNGLGETPIXELMAPFVPROC glad_glGetPixelMapfv; #define glGetPixelMapfv glad_glGetPixelMapfv -GLAD_API_CALL PFNGLVERTEX4SVPROC glad_glVertex4sv; + GLAD_API_CALL PFNGLVERTEX4SVPROC glad_glVertex4sv; #define glVertex4sv glad_glVertex4sv -GLAD_API_CALL PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D; + GLAD_API_CALL PFNGLTEXSTORAGE2DPROC glad_glTexStorage2D; #define glTexStorage2D glad_glTexStorage2D -GLAD_API_CALL PFNGLTEXCOORD2FVPROC glad_glTexCoord2fv; + GLAD_API_CALL PFNGLTEXCOORD2FVPROC glad_glTexCoord2fv; #define glTexCoord2fv glad_glTexCoord2fv -GLAD_API_CALL PFNGLUNIFORMMATRIX3X2DVPROC glad_glUniformMatrix3x2dv; + GLAD_API_CALL PFNGLUNIFORMMATRIX3X2DVPROC glad_glUniformMatrix3x2dv; #define glUniformMatrix3x2dv glad_glUniformMatrix3x2dv -GLAD_API_CALL PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; + GLAD_API_CALL PFNGLGETVERTEXATTRIBIUIVPROC glad_glGetVertexAttribIuiv; #define glGetVertexAttribIuiv glad_glGetVertexAttribIuiv -GLAD_API_CALL PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv; + GLAD_API_CALL PFNGLVERTEXATTRIB3SVPROC glad_glVertexAttrib3sv; #define glVertexAttrib3sv glad_glVertexAttrib3sv -GLAD_API_CALL PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; + GLAD_API_CALL PFNGLDRAWRANGEELEMENTSBASEVERTEXPROC glad_glDrawRangeElementsBaseVertex; #define glDrawRangeElementsBaseVertex glad_glDrawRangeElementsBaseVertex -GLAD_API_CALL PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed; + GLAD_API_CALL PFNGLDEPTHRANGEINDEXEDPROC glad_glDepthRangeIndexed; #define glDepthRangeIndexed glad_glDepthRangeIndexed -GLAD_API_CALL PFNGLISQUERYPROC glad_glIsQuery; + GLAD_API_CALL PFNGLISQUERYPROC glad_glIsQuery; #define glIsQuery glad_glIsQuery -GLAD_API_CALL PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines; + GLAD_API_CALL PFNGLDELETEPROGRAMPIPELINESPROC glad_glDeleteProgramPipelines; #define glDeleteProgramPipelines glad_glDeleteProgramPipelines -GLAD_API_CALL PFNGLGETTEXTURELEVELPARAMETERFVPROC glad_glGetTextureLevelParameterfv; + GLAD_API_CALL PFNGLGETTEXTURELEVELPARAMETERFVPROC glad_glGetTextureLevelParameterfv; #define glGetTextureLevelParameterfv glad_glGetTextureLevelParameterfv -GLAD_API_CALL PFNGLUNIFORMMATRIX4X3DVPROC glad_glUniformMatrix4x3dv; + GLAD_API_CALL PFNGLUNIFORMMATRIX4X3DVPROC glad_glUniformMatrix4x3dv; #define glUniformMatrix4x3dv glad_glUniformMatrix4x3dv -GLAD_API_CALL PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer; + GLAD_API_CALL PFNGLBLITNAMEDFRAMEBUFFERPROC glad_glBlitNamedFramebuffer; #define glBlitNamedFramebuffer glad_glBlitNamedFramebuffer -GLAD_API_CALL PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui; + GLAD_API_CALL PFNGLMULTITEXCOORDP1UIPROC glad_glMultiTexCoordP1ui; #define glMultiTexCoordP1ui glad_glMultiTexCoordP1ui -GLAD_API_CALL PFNGLINDEXSPROC glad_glIndexs; + GLAD_API_CALL PFNGLINDEXSPROC glad_glIndexs; #define glIndexs glad_glIndexs -GLAD_API_CALL PFNGLCOLORP3UIPROC glad_glColorP3ui; + GLAD_API_CALL PFNGLCOLORP3UIPROC glad_glColorP3ui; #define glColorP3ui glad_glColorP3ui -GLAD_API_CALL PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui; + GLAD_API_CALL PFNGLMULTITEXCOORDP4UIPROC glad_glMultiTexCoordP4ui; #define glMultiTexCoordP4ui glad_glMultiTexCoordP4ui -GLAD_API_CALL PFNGLCREATESHADERPROC glad_glCreateShader; + GLAD_API_CALL PFNGLCREATESHADERPROC glad_glCreateShader; #define glCreateShader glad_glCreateShader -GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glad_glClearNamedFramebufferfi; + GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERFIPROC glad_glClearNamedFramebufferfi; #define glClearNamedFramebufferfi glad_glClearNamedFramebufferfi -GLAD_API_CALL PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage; + GLAD_API_CALL PFNGLGETCOMPRESSEDTEXTUREIMAGEPROC glad_glGetCompressedTextureImage; #define glGetCompressedTextureImage glad_glGetCompressedTextureImage -GLAD_API_CALL PFNGLCOLOR4SVPROC glad_glColor4sv; + GLAD_API_CALL PFNGLCOLOR4SVPROC glad_glColor4sv; #define glColor4sv glad_glColor4sv -GLAD_API_CALL PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert; + GLAD_API_CALL PFNGLDEBUGMESSAGEINSERTPROC glad_glDebugMessageInsert; #define glDebugMessageInsert glad_glDebugMessageInsert -GLAD_API_CALL PFNGLRECTFPROC glad_glRectf; + GLAD_API_CALL PFNGLRECTFPROC glad_glRectf; #define glRectf glad_glRectf -GLAD_API_CALL PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog; + GLAD_API_CALL PFNGLGETDEBUGMESSAGELOGPROC glad_glGetDebugMessageLog; #define glGetDebugMessageLog glad_glGetDebugMessageLog -GLAD_API_CALL PFNGLWINDOWPOS3SPROC glad_glWindowPos3s; + GLAD_API_CALL PFNGLWINDOWPOS3SPROC glad_glWindowPos3s; #define glWindowPos3s glad_glWindowPos3s -GLAD_API_CALL PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; + GLAD_API_CALL PFNGLISFRAMEBUFFERPROC glad_glIsFramebuffer; #define glIsFramebuffer glad_glIsFramebuffer -GLAD_API_CALL PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData; + GLAD_API_CALL PFNGLCOPYIMAGESUBDATAPROC glad_glCopyImageSubData; #define glCopyImageSubData glad_glCopyImageSubData -GLAD_API_CALL PFNGLCOLORPOINTERPROC glad_glColorPointer; + GLAD_API_CALL PFNGLCOLORPOINTERPROC glad_glColorPointer; #define glColorPointer glad_glColorPointer -GLAD_API_CALL PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; + GLAD_API_CALL PFNGLUNIFORMMATRIX4X3FVPROC glad_glUniformMatrix4x3fv; #define glUniformMatrix4x3fv glad_glUniformMatrix4x3fv -GLAD_API_CALL PFNGLGETMATERIALFVPROC glad_glGetMaterialfv; + GLAD_API_CALL PFNGLGETMATERIALFVPROC glad_glGetMaterialfv; #define glGetMaterialfv glad_glGetMaterialfv -GLAD_API_CALL PFNGLMULTITEXCOORD4IVPROC glad_glMultiTexCoord4iv; + GLAD_API_CALL PFNGLMULTITEXCOORD4IVPROC glad_glMultiTexCoord4iv; #define glMultiTexCoord4iv glad_glMultiTexCoord4iv -GLAD_API_CALL PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers; + GLAD_API_CALL PFNGLDELETESAMPLERSPROC glad_glDeleteSamplers; #define glDeleteSamplers glad_glDeleteSamplers -GLAD_API_CALL PFNGLGETMATERIALIVPROC glad_glGetMaterialiv; + GLAD_API_CALL PFNGLGETMATERIALIVPROC glad_glGetMaterialiv; #define glGetMaterialiv glad_glGetMaterialiv -GLAD_API_CALL PFNGLBLENDFUNCPROC glad_glBlendFunc; + GLAD_API_CALL PFNGLBLENDFUNCPROC glad_glBlendFunc; #define glBlendFunc glad_glBlendFunc -GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glad_glNamedFramebufferRenderbuffer; + GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERRENDERBUFFERPROC glad_glNamedFramebufferRenderbuffer; #define glNamedFramebufferRenderbuffer glad_glNamedFramebufferRenderbuffer -GLAD_API_CALL PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData; + GLAD_API_CALL PFNGLNAMEDBUFFERDATAPROC glad_glNamedBufferData; #define glNamedBufferData glad_glNamedBufferData -GLAD_API_CALL PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements; + GLAD_API_CALL PFNGLMULTIDRAWELEMENTSPROC glad_glMultiDrawElements; #define glMultiDrawElements glad_glMultiDrawElements -GLAD_API_CALL PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i; + GLAD_API_CALL PFNGLPROGRAMUNIFORM3IPROC glad_glProgramUniform3i; #define glProgramUniform3i glad_glProgramUniform3i -GLAD_API_CALL PFNGLGETPROGRAMSTAGEIVPROC glad_glGetProgramStageiv; + GLAD_API_CALL PFNGLGETPROGRAMSTAGEIVPROC glad_glGetProgramStageiv; #define glGetProgramStageiv glad_glGetProgramStageiv -GLAD_API_CALL PFNGLVERTEXATTRIBLFORMATPROC glad_glVertexAttribLFormat; + GLAD_API_CALL PFNGLVERTEXATTRIBLFORMATPROC glad_glVertexAttribLFormat; #define glVertexAttribLFormat glad_glVertexAttribLFormat -GLAD_API_CALL PFNGLVERTEX2SVPROC glad_glVertex2sv; + GLAD_API_CALL PFNGLVERTEX2SVPROC glad_glVertex2sv; #define glVertex2sv glad_glVertex2sv -GLAD_API_CALL PFNGLRECTSVPROC glad_glRectsv; + GLAD_API_CALL PFNGLRECTSVPROC glad_glRectsv; #define glRectsv glad_glRectsv -GLAD_API_CALL PFNGLTEXTURESTORAGE2DPROC glad_glTextureStorage2D; + GLAD_API_CALL PFNGLTEXTURESTORAGE2DPROC glad_glTextureStorage2D; #define glTextureStorage2D glad_glTextureStorage2D -GLAD_API_CALL PFNGLUNIFORM3FPROC glad_glUniform3f; + GLAD_API_CALL PFNGLUNIFORM3FPROC glad_glUniform3f; #define glUniform3f glad_glUniform3f -GLAD_API_CALL PFNGLDRAWBUFFERPROC glad_glDrawBuffer; + GLAD_API_CALL PFNGLDRAWBUFFERPROC glad_glDrawBuffer; #define glDrawBuffer glad_glDrawBuffer -GLAD_API_CALL PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D; + GLAD_API_CALL PFNGLTEXSUBIMAGE1DPROC glad_glTexSubImage1D; #define glTexSubImage1D glad_glTexSubImage1D -GLAD_API_CALL PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv; + GLAD_API_CALL PFNGLTEXCOORDP2UIVPROC glad_glTexCoordP2uiv; #define glTexCoordP2uiv glad_glTexCoordP2uiv -GLAD_API_CALL PFNGLUNIFORM4FPROC glad_glUniform4f; + GLAD_API_CALL PFNGLUNIFORM4FPROC glad_glUniform4f; #define glUniform4f glad_glUniform4f -GLAD_API_CALL PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d; + GLAD_API_CALL PFNGLVERTEXATTRIB2DPROC glad_glVertexAttrib2d; #define glVertexAttrib2d glad_glVertexAttrib2d -GLAD_API_CALL PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; + GLAD_API_CALL PFNGLVERTEXATTRIB2FPROC glad_glVertexAttrib2f; #define glVertexAttrib2f glad_glVertexAttrib2f -GLAD_API_CALL PFNGLSECONDARYCOLOR3UBVPROC glad_glSecondaryColor3ubv; + GLAD_API_CALL PFNGLSECONDARYCOLOR3UBVPROC glad_glSecondaryColor3ubv; #define glSecondaryColor3ubv glad_glSecondaryColor3ubv -GLAD_API_CALL PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; + GLAD_API_CALL PFNGLDELETEFRAMEBUFFERSPROC glad_glDeleteFramebuffers; #define glDeleteFramebuffers glad_glDeleteFramebuffers -GLAD_API_CALL PFNGLCLEARCOLORPROC glad_glClearColor; + GLAD_API_CALL PFNGLCLEARCOLORPROC glad_glClearColor; #define glClearColor glad_glClearColor -GLAD_API_CALL PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; + GLAD_API_CALL PFNGLFRAMEBUFFERRENDERBUFFERPROC glad_glFramebufferRenderbuffer; #define glFramebufferRenderbuffer glad_glFramebufferRenderbuffer -GLAD_API_CALL PFNGLGETTEXGENFVPROC glad_glGetTexGenfv; + GLAD_API_CALL PFNGLGETTEXGENFVPROC glad_glGetTexGenfv; #define glGetTexGenfv glad_glGetTexGenfv -GLAD_API_CALL PFNGLCOLOR4DVPROC glad_glColor4dv; + GLAD_API_CALL PFNGLCOLOR4DVPROC glad_glColor4dv; #define glColor4dv glad_glColor4dv -GLAD_API_CALL PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv; + GLAD_API_CALL PFNGLMULTITEXCOORDP4UIVPROC glad_glMultiTexCoordP4uiv; #define glMultiTexCoordP4uiv glad_glMultiTexCoordP4uiv -GLAD_API_CALL PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram; + GLAD_API_CALL PFNGLACTIVESHADERPROGRAMPROC glad_glActiveShaderProgram; #define glActiveShaderProgram glad_glActiveShaderProgram -GLAD_API_CALL PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender; + GLAD_API_CALL PFNGLBEGINCONDITIONALRENDERPROC glad_glBeginConditionalRender; #define glBeginConditionalRender glad_glBeginConditionalRender -GLAD_API_CALL PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; + GLAD_API_CALL PFNGLTEXIMAGE3DMULTISAMPLEPROC glad_glTexImage3DMultisample; #define glTexImage3DMultisample glad_glTexImage3DMultisample -GLAD_API_CALL PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv; + GLAD_API_CALL PFNGLVIEWPORTINDEXEDFVPROC glad_glViewportIndexedfv; #define glViewportIndexedfv glad_glViewportIndexedfv -GLAD_API_CALL PFNGLMAPGRID1FPROC glad_glMapGrid1f; + GLAD_API_CALL PFNGLMAPGRID1FPROC glad_glMapGrid1f; #define glMapGrid1f glad_glMapGrid1f -GLAD_API_CALL PFNGLMULTITEXCOORD3DPROC glad_glMultiTexCoord3d; + GLAD_API_CALL PFNGLMULTITEXCOORD3DPROC glad_glMultiTexCoord3d; #define glMultiTexCoord3d glad_glMultiTexCoord3d -GLAD_API_CALL PFNGLWINDOWPOS2DVPROC glad_glWindowPos2dv; + GLAD_API_CALL PFNGLWINDOWPOS2DVPROC glad_glWindowPos2dv; #define glWindowPos2dv glad_glWindowPos2dv -GLAD_API_CALL PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; + GLAD_API_CALL PFNGLGETBUFFERPOINTERVPROC glad_glGetBufferPointerv; #define glGetBufferPointerv glad_glGetBufferPointerv -GLAD_API_CALL PFNGLTEXGENFVPROC glad_glTexGenfv; + GLAD_API_CALL PFNGLTEXGENFVPROC glad_glTexGenfv; #define glTexGenfv glad_glTexGenfv -GLAD_API_CALL PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv; + GLAD_API_CALL PFNGLVERTEXATTRIBP4UIVPROC glad_glVertexAttribP4uiv; #define glVertexAttribP4uiv glad_glVertexAttribP4uiv -GLAD_API_CALL PFNGLROTATEDPROC glad_glRotated; + GLAD_API_CALL PFNGLROTATEDPROC glad_glRotated; #define glRotated glad_glRotated -GLAD_API_CALL PFNGLCREATEQUERIESPROC glad_glCreateQueries; + GLAD_API_CALL PFNGLCREATEQUERIESPROC glad_glCreateQueries; #define glCreateQueries glad_glCreateQueries -GLAD_API_CALL PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; + GLAD_API_CALL PFNGLUNIFORMMATRIX3X2FVPROC glad_glUniformMatrix3x2fv; #define glUniformMatrix3x2fv glad_glUniformMatrix3x2fv -GLAD_API_CALL PFNGLTEXIMAGE1DPROC glad_glTexImage1D; + GLAD_API_CALL PFNGLTEXIMAGE1DPROC glad_glTexImage1D; #define glTexImage1D glad_glTexImage1D -GLAD_API_CALL PFNGLWINDOWPOS3IPROC glad_glWindowPos3i; + GLAD_API_CALL PFNGLWINDOWPOS3IPROC glad_glWindowPos3i; #define glWindowPos3i glad_glWindowPos3i -GLAD_API_CALL PFNGLCLAMPCOLORPROC glad_glClampColor; + GLAD_API_CALL PFNGLCLAMPCOLORPROC glad_glClampColor; #define glClampColor glad_glClampColor -GLAD_API_CALL PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; + GLAD_API_CALL PFNGLUNIFORMMATRIX4X2FVPROC glad_glUniformMatrix4x2fv; #define glUniformMatrix4x2fv glad_glUniformMatrix4x2fv -GLAD_API_CALL PFNGLVERTEX4FPROC glad_glVertex4f; + GLAD_API_CALL PFNGLVERTEX4FPROC glad_glVertex4f; #define glVertex4f glad_glVertex4f -GLAD_API_CALL PFNGLNORMAL3FPROC glad_glNormal3f; + GLAD_API_CALL PFNGLNORMAL3FPROC glad_glNormal3f; #define glNormal3f glad_glNormal3f -GLAD_API_CALL PFNGLCOLOR3UBPROC glad_glColor3ub; + GLAD_API_CALL PFNGLCOLOR3UBPROC glad_glColor3ub; #define glColor3ub glad_glColor3ub -GLAD_API_CALL PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed; + GLAD_API_CALL PFNGLSCISSORINDEXEDPROC glad_glScissorIndexed; #define glScissorIndexed glad_glScissorIndexed -GLAD_API_CALL PFNGLPUSHCLIENTATTRIBPROC glad_glPushClientAttrib; + GLAD_API_CALL PFNGLPUSHCLIENTATTRIBPROC glad_glPushClientAttrib; #define glPushClientAttrib glad_glPushClientAttrib -GLAD_API_CALL PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d; + GLAD_API_CALL PFNGLVERTEXATTRIB4DPROC glad_glVertexAttrib4d; #define glVertexAttrib4d glad_glVertexAttrib4d -GLAD_API_CALL PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages; + GLAD_API_CALL PFNGLUSEPROGRAMSTAGESPROC glad_glUseProgramStages; #define glUseProgramStages glad_glUseProgramStages -GLAD_API_CALL PFNGLTEXCOORD3SPROC glad_glTexCoord3s; + GLAD_API_CALL PFNGLTEXCOORD3SPROC glad_glTexCoord3s; #define glTexCoord3s glad_glTexCoord3s -GLAD_API_CALL PFNGLLIGHTFPROC glad_glLightf; + GLAD_API_CALL PFNGLLIGHTFPROC glad_glLightf; #define glLightf glad_glLightf -GLAD_API_CALL PFNGLTEXCOORD3FVPROC glad_glTexCoord3fv; + GLAD_API_CALL PFNGLTEXCOORD3FVPROC glad_glTexCoord3fv; #define glTexCoord3fv glad_glTexCoord3fv -GLAD_API_CALL PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv; + GLAD_API_CALL PFNGLVERTEXATTRIB4NUBVPROC glad_glVertexAttrib4Nubv; #define glVertexAttrib4Nubv glad_glVertexAttrib4Nubv -GLAD_API_CALL PFNGLVERTEXATTRIBL2DPROC glad_glVertexAttribL2d; + GLAD_API_CALL PFNGLVERTEXATTRIBL2DPROC glad_glVertexAttribL2d; #define glVertexAttribL2d glad_glVertexAttribL2d -GLAD_API_CALL PFNGLFOGCOORDDPROC glad_glFogCoordd; + GLAD_API_CALL PFNGLFOGCOORDDPROC glad_glFogCoordd; #define glFogCoordd glad_glFogCoordd -GLAD_API_CALL PFNGLGETNPIXELMAPUIVPROC glad_glGetnPixelMapuiv; + GLAD_API_CALL PFNGLGETNPIXELMAPUIVPROC glad_glGetnPixelMapuiv; #define glGetnPixelMapuiv glad_glGetnPixelMapuiv -GLAD_API_CALL PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; + GLAD_API_CALL PFNGLTEXIMAGE2DMULTISAMPLEPROC glad_glTexImage2DMultisample; #define glTexImage2DMultisample glad_glTexImage2DMultisample -GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTIVPROC glad_glGetQueryBufferObjectiv; + GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTIVPROC glad_glGetQueryBufferObjectiv; #define glGetQueryBufferObjectiv glad_glGetQueryBufferObjectiv -GLAD_API_CALL PFNGLGETSTRINGIPROC glad_glGetStringi; + GLAD_API_CALL PFNGLGETSTRINGIPROC glad_glGetStringi; #define glGetStringi glad_glGetStringi -GLAD_API_CALL PFNGLRASTERPOS4SPROC glad_glRasterPos4s; + GLAD_API_CALL PFNGLRASTERPOS4SPROC glad_glRasterPos4s; #define glRasterPos4s glad_glRasterPos4s -GLAD_API_CALL PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui; + GLAD_API_CALL PFNGLVERTEXATTRIBP2UIPROC glad_glVertexAttribP2ui; #define glVertexAttribP2ui glad_glVertexAttribP2ui -GLAD_API_CALL PFNGLGETQUERYIVPROC glad_glGetQueryiv; + GLAD_API_CALL PFNGLGETQUERYIVPROC glad_glGetQueryiv; #define glGetQueryiv glad_glGetQueryiv -GLAD_API_CALL PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; + GLAD_API_CALL PFNGLBINDVERTEXARRAYPROC glad_glBindVertexArray; #define glBindVertexArray glad_glBindVertexArray -GLAD_API_CALL PFNGLPROGRAMUNIFORM3DVPROC glad_glProgramUniform3dv; + GLAD_API_CALL PFNGLPROGRAMUNIFORM3DVPROC glad_glProgramUniform3dv; #define glProgramUniform3dv glad_glProgramUniform3dv -GLAD_API_CALL PFNGLTEXPARAMETERFPROC glad_glTexParameterf; + GLAD_API_CALL PFNGLTEXPARAMETERFPROC glad_glTexParameterf; #define glTexParameterf glad_glTexParameterf -GLAD_API_CALL PFNGLWINDOWPOS3DPROC glad_glWindowPos3d; + GLAD_API_CALL PFNGLWINDOWPOS3DPROC glad_glWindowPos3d; #define glWindowPos3d glad_glWindowPos3d -GLAD_API_CALL PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap; + GLAD_API_CALL PFNGLGENERATETEXTUREMIPMAPPROC glad_glGenerateTextureMipmap; #define glGenerateTextureMipmap glad_glGenerateTextureMipmap -GLAD_API_CALL PFNGLDELETESYNCPROC glad_glDeleteSync; + GLAD_API_CALL PFNGLDELETESYNCPROC glad_glDeleteSync; #define glDeleteSync glad_glDeleteSync -GLAD_API_CALL PFNGLBINDBUFFERPROC glad_glBindBuffer; + GLAD_API_CALL PFNGLBINDBUFFERPROC glad_glBindBuffer; #define glBindBuffer glad_glBindBuffer -GLAD_API_CALL PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup; + GLAD_API_CALL PFNGLPUSHDEBUGGROUPPROC glad_glPushDebugGroup; #define glPushDebugGroup glad_glPushDebugGroup -GLAD_API_CALL PFNGLRASTERPOS2IPROC glad_glRasterPos2i; + GLAD_API_CALL PFNGLRASTERPOS2IPROC glad_glRasterPos2i; #define glRasterPos2i glad_glRasterPos2i -GLAD_API_CALL PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture; + GLAD_API_CALL PFNGLBINDIMAGETEXTUREPROC glad_glBindImageTexture; #define glBindImageTexture glad_glBindImageTexture -GLAD_API_CALL PFNGLFEEDBACKBUFFERPROC glad_glFeedbackBuffer; + GLAD_API_CALL PFNGLFEEDBACKBUFFERPROC glad_glFeedbackBuffer; #define glFeedbackBuffer glad_glFeedbackBuffer -GLAD_API_CALL PFNGLEVALMESH2PROC glad_glEvalMesh2; + GLAD_API_CALL PFNGLEVALMESH2PROC glad_glEvalMesh2; #define glEvalMesh2 glad_glEvalMesh2 -GLAD_API_CALL PFNGLLINKPROGRAMPROC glad_glLinkProgram; + GLAD_API_CALL PFNGLLINKPROGRAMPROC glad_glLinkProgram; #define glLinkProgram glad_glLinkProgram -GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; + GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC glad_glCompressedTexSubImage2D; #define glCompressedTexSubImage2D glad_glCompressedTexSubImage2D -GLAD_API_CALL PFNGLPUSHMATRIXPROC glad_glPushMatrix; + GLAD_API_CALL PFNGLPUSHMATRIXPROC glad_glPushMatrix; #define glPushMatrix glad_glPushMatrix -GLAD_API_CALL PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri; + GLAD_API_CALL PFNGLFRAMEBUFFERPARAMETERIPROC glad_glFramebufferParameteri; #define glFramebufferParameteri glad_glFramebufferParameteri -GLAD_API_CALL PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; + GLAD_API_CALL PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC glad_glGetActiveUniformBlockName; #define glGetActiveUniformBlockName glad_glGetActiveUniformBlockName -GLAD_API_CALL PFNGLUNIFORM3DPROC glad_glUniform3d; + GLAD_API_CALL PFNGLUNIFORM3DPROC glad_glUniform3d; #define glUniform3d glad_glUniform3d -GLAD_API_CALL PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv; + GLAD_API_CALL PFNGLVERTEXATTRIB4UBVPROC glad_glVertexAttrib4ubv; #define glVertexAttrib4ubv glad_glVertexAttrib4ubv -GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D; + GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE1DPROC glad_glCompressedTexImage1D; #define glCompressedTexImage1D glad_glCompressedTexImage1D -GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKI64_VPROC glad_glGetTransformFeedbacki64_v; + GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKI64_VPROC glad_glGetTransformFeedbacki64_v; #define glGetTransformFeedbacki64_v glad_glGetTransformFeedbacki64_v -GLAD_API_CALL PFNGLCOMPILESHADERPROC glad_glCompileShader; + GLAD_API_CALL PFNGLCOMPILESHADERPROC glad_glCompileShader; #define glCompileShader glad_glCompileShader -GLAD_API_CALL PFNGLGETLIGHTFVPROC glad_glGetLightfv; + GLAD_API_CALL PFNGLGETLIGHTFVPROC glad_glGetLightfv; #define glGetLightfv glad_glGetLightfv -GLAD_API_CALL PFNGLPIXELMAPUSVPROC glad_glPixelMapusv; + GLAD_API_CALL PFNGLPIXELMAPUSVPROC glad_glPixelMapusv; #define glPixelMapusv glad_glPixelMapusv -GLAD_API_CALL PFNGLRASTERPOS4IPROC glad_glRasterPos4i; + GLAD_API_CALL PFNGLRASTERPOS4IPROC glad_glRasterPos4i; #define glRasterPos4i glad_glRasterPos4i -GLAD_API_CALL PFNGLUNIFORMMATRIX4X2DVPROC glad_glUniformMatrix4x2dv; + GLAD_API_CALL PFNGLUNIFORMMATRIX4X2DVPROC glad_glUniformMatrix4x2dv; #define glUniformMatrix4x2dv glad_glUniformMatrix4x2dv -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D; + GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE1DPROC glad_glFramebufferTexture1D; #define glFramebufferTexture1D glad_glFramebufferTexture1D -GLAD_API_CALL PFNGLINITNAMESPROC glad_glInitNames; + GLAD_API_CALL PFNGLINITNAMESPROC glad_glInitNames; #define glInitNames glad_glInitNames -GLAD_API_CALL PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui; + GLAD_API_CALL PFNGLVERTEXATTRIBI1UIPROC glad_glVertexAttribI1ui; #define glVertexAttribI1ui glad_glVertexAttribI1ui -GLAD_API_CALL PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; + GLAD_API_CALL PFNGLCLEARBUFFERIVPROC glad_glClearBufferiv; #define glClearBufferiv glad_glClearBufferiv -GLAD_API_CALL PFNGLMAP1FPROC glad_glMap1f; + GLAD_API_CALL PFNGLMAP1FPROC glad_glMap1f; #define glMap1f glad_glMap1f -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4DVPROC glad_glProgramUniformMatrix4dv; + GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4DVPROC glad_glProgramUniformMatrix4dv; #define glProgramUniformMatrix4dv glad_glProgramUniformMatrix4dv -GLAD_API_CALL PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; + GLAD_API_CALL PFNGLGETVERTEXATTRIBFVPROC glad_glGetVertexAttribfv; #define glGetVertexAttribfv glad_glGetVertexAttribfv -GLAD_API_CALL PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; + GLAD_API_CALL PFNGLGETACTIVEUNIFORMBLOCKIVPROC glad_glGetActiveUniformBlockiv; #define glGetActiveUniformBlockiv glad_glGetActiveUniformBlockiv -GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; + GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glRenderbufferStorageMultisample; #define glRenderbufferStorageMultisample glad_glRenderbufferStorageMultisample -GLAD_API_CALL PFNGLGETVERTEXARRAYINDEXEDIVPROC glad_glGetVertexArrayIndexediv; + GLAD_API_CALL PFNGLGETVERTEXARRAYINDEXEDIVPROC glad_glGetVertexArrayIndexediv; #define glGetVertexArrayIndexediv glad_glGetVertexArrayIndexediv -GLAD_API_CALL PFNGLVERTEXARRAYELEMENTBUFFERPROC glad_glVertexArrayElementBuffer; + GLAD_API_CALL PFNGLVERTEXARRAYELEMENTBUFFERPROC glad_glVertexArrayElementBuffer; #define glVertexArrayElementBuffer glad_glVertexArrayElementBuffer -GLAD_API_CALL PFNGLGETTEXGENDVPROC glad_glGetTexGendv; + GLAD_API_CALL PFNGLGETTEXGENDVPROC glad_glGetTexGendv; #define glGetTexGendv glad_glGetTexGendv -GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glad_glClearNamedFramebufferfv; + GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERFVPROC glad_glClearNamedFramebufferfv; #define glClearNamedFramebufferfv glad_glClearNamedFramebufferfv -GLAD_API_CALL PFNGLSECONDARYCOLOR3FPROC glad_glSecondaryColor3f; + GLAD_API_CALL PFNGLSECONDARYCOLOR3FPROC glad_glSecondaryColor3f; #define glSecondaryColor3f glad_glSecondaryColor3f -GLAD_API_CALL PFNGLSHADERBINARYPROC glad_glShaderBinary; + GLAD_API_CALL PFNGLSHADERBINARYPROC glad_glShaderBinary; #define glShaderBinary glad_glShaderBinary -GLAD_API_CALL PFNGLMAP1DPROC glad_glMap1d; + GLAD_API_CALL PFNGLMAP1DPROC glad_glMap1d; #define glMap1d glad_glMap1d -GLAD_API_CALL PFNGLVERTEXATTRIBL2DVPROC glad_glVertexAttribL2dv; + GLAD_API_CALL PFNGLVERTEXATTRIBL2DVPROC glad_glVertexAttribL2dv; #define glVertexAttribL2dv glad_glVertexAttribL2dv -GLAD_API_CALL PFNGLMULTITEXCOORD4DPROC glad_glMultiTexCoord4d; + GLAD_API_CALL PFNGLMULTITEXCOORD4DPROC glad_glMultiTexCoord4d; #define glMultiTexCoord4d glad_glMultiTexCoord4d -GLAD_API_CALL PFNGLTEXCOORD1DVPROC glad_glTexCoord1dv; + GLAD_API_CALL PFNGLTEXCOORD1DVPROC glad_glTexCoord1dv; #define glTexCoord1dv glad_glTexCoord1dv -GLAD_API_CALL PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample; + GLAD_API_CALL PFNGLTEXSTORAGE2DMULTISAMPLEPROC glad_glTexStorage2DMultisample; #define glTexStorage2DMultisample glad_glTexStorage2DMultisample -GLAD_API_CALL PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks; + GLAD_API_CALL PFNGLGENTRANSFORMFEEDBACKSPROC glad_glGenTransformFeedbacks; #define glGenTransformFeedbacks glad_glGenTransformFeedbacks -GLAD_API_CALL PFNGLCLEARBUFFERSUBDATAPROC glad_glClearBufferSubData; + GLAD_API_CALL PFNGLCLEARBUFFERSUBDATAPROC glad_glClearBufferSubData; #define glClearBufferSubData glad_glClearBufferSubData -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv; + GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2FVPROC glad_glProgramUniformMatrix2fv; #define glProgramUniformMatrix2fv glad_glProgramUniformMatrix2fv -GLAD_API_CALL PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv; + GLAD_API_CALL PFNGLGETFRAMEBUFFERPARAMETERIVPROC glad_glGetFramebufferParameteriv; #define glGetFramebufferParameteriv glad_glGetFramebufferParameteriv -GLAD_API_CALL PFNGLPIXELMAPFVPROC glad_glPixelMapfv; + GLAD_API_CALL PFNGLPIXELMAPFVPROC glad_glPixelMapfv; #define glPixelMapfv glad_glPixelMapfv -GLAD_API_CALL PFNGLCOLOR3FPROC glad_glColor3f; + GLAD_API_CALL PFNGLCOLOR3FPROC glad_glColor3f; #define glColor3f glad_glColor3f -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv; + GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X3DVPROC glad_glProgramUniformMatrix4x3dv; #define glProgramUniformMatrix4x3dv glad_glProgramUniformMatrix4x3dv -GLAD_API_CALL PFNGLMULTMATRIXDPROC glad_glMultMatrixd; + GLAD_API_CALL PFNGLMULTMATRIXDPROC glad_glMultMatrixd; #define glMultMatrixd glad_glMultMatrixd -GLAD_API_CALL PFNGLCOPYPIXELSPROC glad_glCopyPixels; + GLAD_API_CALL PFNGLCOPYPIXELSPROC glad_glCopyPixels; #define glCopyPixels glad_glCopyPixels -GLAD_API_CALL PFNGLUNIFORM2DVPROC glad_glUniform2dv; + GLAD_API_CALL PFNGLUNIFORM2DVPROC glad_glUniform2dv; #define glUniform2dv glad_glUniform2dv -GLAD_API_CALL PFNGLCOLOR3SVPROC glad_glColor3sv; + GLAD_API_CALL PFNGLCOLOR3SVPROC glad_glColor3sv; #define glColor3sv glad_glColor3sv -GLAD_API_CALL PFNGLOBJECTLABELPROC glad_glObjectLabel; + GLAD_API_CALL PFNGLOBJECTLABELPROC glad_glObjectLabel; #define glObjectLabel glad_glObjectLabel -GLAD_API_CALL PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel; + GLAD_API_CALL PFNGLGETOBJECTLABELPROC glad_glGetObjectLabel; #define glGetObjectLabel glad_glGetObjectLabel -GLAD_API_CALL PFNGLINDEXFVPROC glad_glIndexfv; + GLAD_API_CALL PFNGLINDEXFVPROC glad_glIndexfv; #define glIndexfv glad_glIndexfv -GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D; + GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE3DPROC glad_glCompressedTextureSubImage3D; #define glCompressedTextureSubImage3D glad_glCompressedTextureSubImage3D -GLAD_API_CALL PFNGLMAPGRID1DPROC glad_glMapGrid1d; + GLAD_API_CALL PFNGLMAPGRID1DPROC glad_glMapGrid1d; #define glMapGrid1d glad_glMapGrid1d -GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTUIVPROC glad_glGetQueryBufferObjectuiv; + GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTUIVPROC glad_glGetQueryBufferObjectuiv; #define glGetQueryBufferObjectuiv glad_glGetQueryBufferObjectuiv -GLAD_API_CALL PFNGLRASTERPOS3SVPROC glad_glRasterPos3sv; + GLAD_API_CALL PFNGLRASTERPOS3SVPROC glad_glRasterPos3sv; #define glRasterPos3sv glad_glRasterPos3sv -GLAD_API_CALL PFNGLSELECTBUFFERPROC glad_glSelectBuffer; + GLAD_API_CALL PFNGLSELECTBUFFERPROC glad_glSelectBuffer; #define glSelectBuffer glad_glSelectBuffer -GLAD_API_CALL PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv; + GLAD_API_CALL PFNGLVERTEXATTRIBI3IVPROC glad_glVertexAttribI3iv; #define glVertexAttribI3iv glad_glVertexAttribI3iv -GLAD_API_CALL PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri; + GLAD_API_CALL PFNGLPATCHPARAMETERIPROC glad_glPatchParameteri; #define glPatchParameteri glad_glPatchParameteri -GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIUIVPROC glad_glGetTextureParameterIuiv; + GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIUIVPROC glad_glGetTextureParameterIuiv; #define glGetTextureParameterIuiv glad_glGetTextureParameterIuiv -GLAD_API_CALL PFNGLCOLOR3IVPROC glad_glColor3iv; + GLAD_API_CALL PFNGLCOLOR3IVPROC glad_glColor3iv; #define glColor3iv glad_glColor3iv -GLAD_API_CALL PFNGLMAPBUFFERPROC glad_glMapBuffer; + GLAD_API_CALL PFNGLMAPBUFFERPROC glad_glMapBuffer; #define glMapBuffer glad_glMapBuffer -GLAD_API_CALL PFNGLNORMALP3UIPROC glad_glNormalP3ui; + GLAD_API_CALL PFNGLNORMALP3UIPROC glad_glNormalP3ui; #define glNormalP3ui glad_glNormalP3ui -GLAD_API_CALL PFNGLVERTEXPOINTERPROC glad_glVertexPointer; + GLAD_API_CALL PFNGLVERTEXPOINTERPROC glad_glVertexPointer; #define glVertexPointer glad_glVertexPointer -GLAD_API_CALL PFNGLGETTEXTUREPARAMETERFVPROC glad_glGetTextureParameterfv; + GLAD_API_CALL PFNGLGETTEXTUREPARAMETERFVPROC glad_glGetTextureParameterfv; #define glGetTextureParameterfv glad_glGetTextureParameterfv -GLAD_API_CALL PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; + GLAD_API_CALL PFNGLVERTEXATTRIBPOINTERPROC glad_glVertexAttribPointer; #define glVertexAttribPointer glad_glVertexAttribPointer -GLAD_API_CALL PFNGLDEPTHRANGEFPROC glad_glDepthRangef; + GLAD_API_CALL PFNGLDEPTHRANGEFPROC glad_glDepthRangef; #define glDepthRangef glad_glDepthRangef -GLAD_API_CALL PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv; + GLAD_API_CALL PFNGLTEXTUREPARAMETERIVPROC glad_glTextureParameteriv; #define glTextureParameteriv glad_glTextureParameteriv -GLAD_API_CALL PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv; + GLAD_API_CALL PFNGLVERTEXP2UIVPROC glad_glVertexP2uiv; #define glVertexP2uiv glad_glVertexP2uiv -GLAD_API_CALL PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv; + GLAD_API_CALL PFNGLVERTEXATTRIBI4USVPROC glad_glVertexAttribI4usv; #define glVertexAttribI4usv glad_glVertexAttribI4usv -GLAD_API_CALL PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; + GLAD_API_CALL PFNGLTEXPARAMETERIVPROC glad_glTexParameteriv; #define glTexParameteriv glad_glTexParameteriv -GLAD_API_CALL PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers; + GLAD_API_CALL PFNGLBINDVERTEXBUFFERSPROC glad_glBindVertexBuffers; #define glBindVertexBuffers glad_glBindVertexBuffers -GLAD_API_CALL PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv; + GLAD_API_CALL PFNGLVERTEXP3UIVPROC glad_glVertexP3uiv; #define glVertexP3uiv glad_glVertexP3uiv -GLAD_API_CALL PFNGLINDEXIPROC glad_glIndexi; + GLAD_API_CALL PFNGLINDEXIPROC glad_glIndexi; #define glIndexi glad_glIndexi -GLAD_API_CALL PFNGLGETACTIVESUBROUTINENAMEPROC glad_glGetActiveSubroutineName; + GLAD_API_CALL PFNGLGETACTIVESUBROUTINENAMEPROC glad_glGetActiveSubroutineName; #define glGetActiveSubroutineName glad_glGetActiveSubroutineName -GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; + GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC glad_glCompressedTexSubImage3D; #define glCompressedTexSubImage3D glad_glCompressedTexSubImage3D -GLAD_API_CALL PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; + GLAD_API_CALL PFNGLGETVERTEXATTRIBPOINTERVPROC glad_glGetVertexAttribPointerv; #define glGetVertexAttribPointerv glad_glGetVertexAttribPointerv -GLAD_API_CALL PFNGLGETPIXELMAPUIVPROC glad_glGetPixelMapuiv; + GLAD_API_CALL PFNGLGETPIXELMAPUIVPROC glad_glGetPixelMapuiv; #define glGetPixelMapuiv glad_glGetPixelMapuiv -GLAD_API_CALL PFNGLGETTEXGENIVPROC glad_glGetTexGeniv; + GLAD_API_CALL PFNGLGETTEXGENIVPROC glad_glGetTexGeniv; #define glGetTexGeniv glad_glGetTexGeniv -GLAD_API_CALL PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s; + GLAD_API_CALL PFNGLVERTEXATTRIB3SPROC glad_glVertexAttrib3s; #define glVertexAttrib3s glad_glVertexAttrib3s -GLAD_API_CALL PFNGLPOINTSIZEPROC glad_glPointSize; + GLAD_API_CALL PFNGLPOINTSIZEPROC glad_glPointSize; #define glPointSize glad_glPointSize -GLAD_API_CALL PFNGLVERTEXP2UIPROC glad_glVertexP2ui; + GLAD_API_CALL PFNGLVERTEXP2UIPROC glad_glVertexP2ui; #define glVertexP2ui glad_glVertexP2ui -GLAD_API_CALL PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC glad_glMultiDrawArraysIndirectCount; + GLAD_API_CALL PFNGLMULTIDRAWARRAYSINDIRECTCOUNTPROC glad_glMultiDrawArraysIndirectCount; #define glMultiDrawArraysIndirectCount glad_glMultiDrawArraysIndirectCount -GLAD_API_CALL PFNGLGETNTEXIMAGEPROC glad_glGetnTexImage; + GLAD_API_CALL PFNGLGETNTEXIMAGEPROC glad_glGetnTexImage; #define glGetnTexImage glad_glGetnTexImage -GLAD_API_CALL PFNGLCULLFACEPROC glad_glCullFace; + GLAD_API_CALL PFNGLCULLFACEPROC glad_glCullFace; #define glCullFace glad_glCullFace -GLAD_API_CALL PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri; + GLAD_API_CALL PFNGLSAMPLERPARAMETERIPROC glad_glSamplerParameteri; #define glSamplerParameteri glad_glSamplerParameteri -GLAD_API_CALL PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier; + GLAD_API_CALL PFNGLTEXTUREBARRIERPROC glad_glTextureBarrier; #define glTextureBarrier glad_glTextureBarrier -GLAD_API_CALL PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; + GLAD_API_CALL PFNGLISRENDERBUFFERPROC glad_glIsRenderbuffer; #define glIsRenderbuffer glad_glIsRenderbuffer -GLAD_API_CALL PFNGLBEGINQUERYPROC glad_glBeginQuery; + GLAD_API_CALL PFNGLBEGINQUERYPROC glad_glBeginQuery; #define glBeginQuery glad_glBeginQuery -GLAD_API_CALL PFNGLCOLOR4USPROC glad_glColor4us; + GLAD_API_CALL PFNGLCOLOR4USPROC glad_glColor4us; #define glColor4us glad_glColor4us -GLAD_API_CALL PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv; + GLAD_API_CALL PFNGLGETVERTEXATTRIBDVPROC glad_glGetVertexAttribdv; #define glGetVertexAttribdv glad_glGetVertexAttribdv -GLAD_API_CALL PFNGLTEXCOORD4IVPROC glad_glTexCoord4iv; + GLAD_API_CALL PFNGLTEXCOORD4IVPROC glad_glTexCoord4iv; #define glTexCoord4iv glad_glTexCoord4iv -GLAD_API_CALL PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv; + GLAD_API_CALL PFNGLPROGRAMUNIFORM1FVPROC glad_glProgramUniform1fv; #define glProgramUniform1fv glad_glProgramUniform1fv -GLAD_API_CALL PFNGLDELETETEXTURESPROC glad_glDeleteTextures; + GLAD_API_CALL PFNGLDELETETEXTURESPROC glad_glDeleteTextures; #define glDeleteTextures glad_glDeleteTextures -GLAD_API_CALL PFNGLWINDOWPOS2IVPROC glad_glWindowPos2iv; + GLAD_API_CALL PFNGLWINDOWPOS2IVPROC glad_glWindowPos2iv; #define glWindowPos2iv glad_glWindowPos2iv -GLAD_API_CALL PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; + GLAD_API_CALL PFNGLVERTEXATTRIBIPOINTERPROC glad_glVertexAttribIPointer; #define glVertexAttribIPointer glad_glVertexAttribIPointer -GLAD_API_CALL PFNGLCREATEVERTEXARRAYSPROC glad_glCreateVertexArrays; + GLAD_API_CALL PFNGLCREATEVERTEXARRAYSPROC glad_glCreateVertexArrays; #define glCreateVertexArrays glad_glCreateVertexArrays -GLAD_API_CALL PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i; + GLAD_API_CALL PFNGLVERTEXATTRIBI1IPROC glad_glVertexAttribI1i; #define glVertexAttribI1i glad_glVertexAttribI1i -GLAD_API_CALL PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui; + GLAD_API_CALL PFNGLPROGRAMUNIFORM3UIPROC glad_glProgramUniform3ui; #define glProgramUniform3ui glad_glProgramUniform3ui -GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glad_glCompressedTextureSubImage2D; + GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE2DPROC glad_glCompressedTextureSubImage2D; #define glCompressedTextureSubImage2D glad_glCompressedTextureSubImage2D -GLAD_API_CALL PFNGLRECTDPROC glad_glRectd; + GLAD_API_CALL PFNGLRECTDPROC glad_glRectd; #define glRectd glad_glRectd -GLAD_API_CALL PFNGLMULTTRANSPOSEMATRIXDPROC glad_glMultTransposeMatrixd; + GLAD_API_CALL PFNGLMULTTRANSPOSEMATRIXDPROC glad_glMultTransposeMatrixd; #define glMultTransposeMatrixd glad_glMultTransposeMatrixd -GLAD_API_CALL PFNGLTEXENVFPROC glad_glTexEnvf; + GLAD_API_CALL PFNGLTEXENVFPROC glad_glTexEnvf; #define glTexEnvf glad_glTexEnvf -GLAD_API_CALL PFNGLNORMAL3IPROC glad_glNormal3i; + GLAD_API_CALL PFNGLNORMAL3IPROC glad_glNormal3i; #define glNormal3i glad_glNormal3i -GLAD_API_CALL PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; + GLAD_API_CALL PFNGLBINDATTRIBLOCATIONPROC glad_glBindAttribLocation; #define glBindAttribLocation glad_glBindAttribLocation -GLAD_API_CALL PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; + GLAD_API_CALL PFNGLSTENCILMASKSEPARATEPROC glad_glStencilMaskSeparate; #define glStencilMaskSeparate glad_glStencilMaskSeparate -GLAD_API_CALL PFNGLGETINTEGERVPROC glad_glGetIntegerv; + GLAD_API_CALL PFNGLGETINTEGERVPROC glad_glGetIntegerv; #define glGetIntegerv glad_glGetIntegerv -GLAD_API_CALL PFNGLUSEPROGRAMPROC glad_glUseProgram; + GLAD_API_CALL PFNGLUSEPROGRAMPROC glad_glUseProgram; #define glUseProgram glad_glUseProgram -GLAD_API_CALL PFNGLNORMAL3BVPROC glad_glNormal3bv; + GLAD_API_CALL PFNGLNORMAL3BVPROC glad_glNormal3bv; #define glNormal3bv glad_glNormal3bv -GLAD_API_CALL PFNGLPIXELSTOREIPROC glad_glPixelStorei; + GLAD_API_CALL PFNGLPIXELSTOREIPROC glad_glPixelStorei; #define glPixelStorei glad_glPixelStorei -GLAD_API_CALL PFNGLNORMAL3SPROC glad_glNormal3s; + GLAD_API_CALL PFNGLNORMAL3SPROC glad_glNormal3s; #define glNormal3s glad_glNormal3s -GLAD_API_CALL PFNGLCOLOR4IVPROC glad_glColor4iv; + GLAD_API_CALL PFNGLCOLOR4IVPROC glad_glColor4iv; #define glColor4iv glad_glColor4iv -GLAD_API_CALL PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv; + GLAD_API_CALL PFNGLMULTITEXCOORDP2UIVPROC glad_glMultiTexCoordP2uiv; #define glMultiTexCoordP2uiv glad_glMultiTexCoordP2uiv -GLAD_API_CALL PFNGLARETEXTURESRESIDENTPROC glad_glAreTexturesResident; + GLAD_API_CALL PFNGLARETEXTURESRESIDENTPROC glad_glAreTexturesResident; #define glAreTexturesResident glad_glAreTexturesResident -GLAD_API_CALL PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; + GLAD_API_CALL PFNGLGETUNIFORMFVPROC glad_glGetUniformfv; #define glGetUniformfv glad_glGetUniformfv -GLAD_API_CALL PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glad_glGetActiveSubroutineUniformName; + GLAD_API_CALL PFNGLGETACTIVESUBROUTINEUNIFORMNAMEPROC glad_glGetActiveSubroutineUniformName; #define glGetActiveSubroutineUniformName glad_glGetActiveSubroutineUniformName -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv; + GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X4FVPROC glad_glProgramUniformMatrix2x4fv; #define glProgramUniformMatrix2x4fv glad_glProgramUniformMatrix2x4fv -GLAD_API_CALL PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D; + GLAD_API_CALL PFNGLTEXSTORAGE3DPROC glad_glTexStorage3D; #define glTexStorage3D glad_glTexStorage3D -GLAD_API_CALL PFNGLTEXCOORD1IPROC glad_glTexCoord1i; + GLAD_API_CALL PFNGLTEXCOORD1IPROC glad_glTexCoord1i; #define glTexCoord1i glad_glTexCoord1i -GLAD_API_CALL PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage; + GLAD_API_CALL PFNGLGETCOMPRESSEDTEXTURESUBIMAGEPROC glad_glGetCompressedTextureSubImage; #define glGetCompressedTextureSubImage glad_glGetCompressedTextureSubImage -GLAD_API_CALL PFNGLVERTEXARRAYVERTEXBUFFERSPROC glad_glVertexArrayVertexBuffers; + GLAD_API_CALL PFNGLVERTEXARRAYVERTEXBUFFERSPROC glad_glVertexArrayVertexBuffers; #define glVertexArrayVertexBuffers glad_glVertexArrayVertexBuffers -GLAD_API_CALL PFNGLSECONDARYCOLOR3DPROC glad_glSecondaryColor3d; + GLAD_API_CALL PFNGLSECONDARYCOLOR3DPROC glad_glSecondaryColor3d; #define glSecondaryColor3d glad_glSecondaryColor3d -GLAD_API_CALL PFNGLINTERLEAVEDARRAYSPROC glad_glInterleavedArrays; + GLAD_API_CALL PFNGLINTERLEAVEDARRAYSPROC glad_glInterleavedArrays; #define glInterleavedArrays glad_glInterleavedArrays -GLAD_API_CALL PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; + GLAD_API_CALL PFNGLUNMAPBUFFERPROC glad_glUnmapBuffer; #define glUnmapBuffer glad_glUnmapBuffer -GLAD_API_CALL PFNGLISENABLEDIPROC glad_glIsEnabledi; + GLAD_API_CALL PFNGLISENABLEDIPROC glad_glIsEnabledi; #define glIsEnabledi glad_glIsEnabledi -GLAD_API_CALL PFNGLBINDSAMPLERSPROC glad_glBindSamplers; + GLAD_API_CALL PFNGLBINDSAMPLERSPROC glad_glBindSamplers; #define glBindSamplers glad_glBindSamplers -GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; + GLAD_API_CALL PFNGLCOMPRESSEDTEXSUBIMAGE1DPROC glad_glCompressedTexSubImage1D; #define glCompressedTexSubImage1D glad_glCompressedTexSubImage1D -GLAD_API_CALL PFNGLPRIORITIZETEXTURESPROC glad_glPrioritizeTextures; + GLAD_API_CALL PFNGLPRIORITIZETEXTURESPROC glad_glPrioritizeTextures; #define glPrioritizeTextures glad_glPrioritizeTextures -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv; + GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X2FVPROC glad_glProgramUniformMatrix4x2fv; #define glProgramUniformMatrix4x2fv glad_glProgramUniformMatrix4x2fv -GLAD_API_CALL PFNGLRASTERPOS4DPROC glad_glRasterPos4d; + GLAD_API_CALL PFNGLRASTERPOS4DPROC glad_glRasterPos4d; #define glRasterPos4d glad_glRasterPos4d -GLAD_API_CALL PFNGLSECONDARYCOLOR3USVPROC glad_glSecondaryColor3usv; + GLAD_API_CALL PFNGLSECONDARYCOLOR3USVPROC glad_glSecondaryColor3usv; #define glSecondaryColor3usv glad_glSecondaryColor3usv -GLAD_API_CALL PFNGLGETSYNCIVPROC glad_glGetSynciv; + GLAD_API_CALL PFNGLGETSYNCIVPROC glad_glGetSynciv; #define glGetSynciv glad_glGetSynciv -GLAD_API_CALL PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv; + GLAD_API_CALL PFNGLSAMPLERPARAMETERIIVPROC glad_glSamplerParameterIiv; #define glSamplerParameterIiv glad_glSamplerParameterIiv -GLAD_API_CALL PFNGLLIGHTMODELFVPROC glad_glLightModelfv; + GLAD_API_CALL PFNGLLIGHTMODELFVPROC glad_glLightModelfv; #define glLightModelfv glad_glLightModelfv -GLAD_API_CALL PFNGLTEXTURESTORAGE3DPROC glad_glTextureStorage3D; + GLAD_API_CALL PFNGLTEXTURESTORAGE3DPROC glad_glTextureStorage3D; #define glTextureStorage3D glad_glTextureStorage3D -GLAD_API_CALL PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback; + GLAD_API_CALL PFNGLRESUMETRANSFORMFEEDBACKPROC glad_glResumeTransformFeedback; #define glResumeTransformFeedback glad_glResumeTransformFeedback -GLAD_API_CALL PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines; + GLAD_API_CALL PFNGLGENPROGRAMPIPELINESPROC glad_glGenProgramPipelines; #define glGenProgramPipelines glad_glGenProgramPipelines -GLAD_API_CALL PFNGLVERTEX4FVPROC glad_glVertex4fv; + GLAD_API_CALL PFNGLVERTEX4FVPROC glad_glVertex4fv; #define glVertex4fv glad_glVertex4fv -GLAD_API_CALL PFNGLLIGHTIVPROC glad_glLightiv; + GLAD_API_CALL PFNGLLIGHTIVPROC glad_glLightiv; #define glLightiv glad_glLightiv -GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glad_glClearNamedFramebufferiv; + GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERIVPROC glad_glClearNamedFramebufferiv; #define glClearNamedFramebufferiv glad_glClearNamedFramebufferiv -GLAD_API_CALL PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; + GLAD_API_CALL PFNGLGETTEXPARAMETERIVPROC glad_glGetTexParameteriv; #define glGetTexParameteriv glad_glGetTexParameteriv -GLAD_API_CALL PFNGLTEXCOORD3DVPROC glad_glTexCoord3dv; + GLAD_API_CALL PFNGLTEXCOORD3DVPROC glad_glTexCoord3dv; #define glTexCoord3dv glad_glTexCoord3dv -GLAD_API_CALL PFNGLFOGCOORDPOINTERPROC glad_glFogCoordPointer; + GLAD_API_CALL PFNGLFOGCOORDPOINTERPROC glad_glFogCoordPointer; #define glFogCoordPointer glad_glFogCoordPointer -GLAD_API_CALL PFNGLUNIFORM2IPROC glad_glUniform2i; + GLAD_API_CALL PFNGLUNIFORM2IPROC glad_glUniform2i; #define glUniform2i glad_glUniform2i -GLAD_API_CALL PFNGLTEXTURESUBIMAGE3DPROC glad_glTextureSubImage3D; + GLAD_API_CALL PFNGLTEXTURESUBIMAGE3DPROC glad_glTextureSubImage3D; #define glTextureSubImage3D glad_glTextureSubImage3D -GLAD_API_CALL PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v; + GLAD_API_CALL PFNGLGETDOUBLEI_VPROC glad_glGetDoublei_v; #define glGetDoublei_v glad_glGetDoublei_v -GLAD_API_CALL PFNGLCLEARBUFFERDATAPROC glad_glClearBufferData; + GLAD_API_CALL PFNGLCLEARBUFFERDATAPROC glad_glClearBufferData; #define glClearBufferData glad_glClearBufferData -GLAD_API_CALL PFNGLBINDTEXTUREPROC glad_glBindTexture; + GLAD_API_CALL PFNGLBINDTEXTUREPROC glad_glBindTexture; #define glBindTexture glad_glBindTexture -GLAD_API_CALL PFNGLTEXTUREBUFFERRANGEPROC glad_glTextureBufferRange; + GLAD_API_CALL PFNGLTEXTUREBUFFERRANGEPROC glad_glTextureBufferRange; #define glTextureBufferRange glad_glTextureBufferRange -GLAD_API_CALL PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; + GLAD_API_CALL PFNGLGETTEXLEVELPARAMETERFVPROC glad_glGetTexLevelParameterfv; #define glGetTexLevelParameterfv glad_glGetTexLevelParameterfv -GLAD_API_CALL PFNGLSAMPLEMASKIPROC glad_glSampleMaski; + GLAD_API_CALL PFNGLSAMPLEMASKIPROC glad_glSampleMaski; #define glSampleMaski glad_glSampleMaski -GLAD_API_CALL PFNGLCLEARACCUMPROC glad_glClearAccum; + GLAD_API_CALL PFNGLCLEARACCUMPROC glad_glClearAccum; #define glClearAccum glad_glClearAccum -GLAD_API_CALL PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; + GLAD_API_CALL PFNGLGETACTIVEUNIFORMPROC glad_glGetActiveUniform; #define glGetActiveUniform glad_glGetActiveUniform -GLAD_API_CALL PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary; + GLAD_API_CALL PFNGLGETPROGRAMBINARYPROC glad_glGetProgramBinary; #define glGetProgramBinary glad_glGetProgramBinary -GLAD_API_CALL PFNGLDETACHSHADERPROC glad_glDetachShader; + GLAD_API_CALL PFNGLDETACHSHADERPROC glad_glDetachShader; #define glDetachShader glad_glDetachShader -GLAD_API_CALL PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s; + GLAD_API_CALL PFNGLVERTEXATTRIB4SPROC glad_glVertexAttrib4s; #define glVertexAttrib4s glad_glVertexAttrib4s -GLAD_API_CALL PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri; + GLAD_API_CALL PFNGLTEXTUREPARAMETERIPROC glad_glTextureParameteri; #define glTextureParameteri glad_glTextureParameteri -GLAD_API_CALL PFNGLCOLOR3DVPROC glad_glColor3dv; + GLAD_API_CALL PFNGLCOLOR3DVPROC glad_glColor3dv; #define glColor3dv glad_glColor3dv -GLAD_API_CALL PFNGLBINDSAMPLERPROC glad_glBindSampler; + GLAD_API_CALL PFNGLBINDSAMPLERPROC glad_glBindSampler; #define glBindSampler glad_glBindSampler -GLAD_API_CALL PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus; + GLAD_API_CALL PFNGLCHECKNAMEDFRAMEBUFFERSTATUSPROC glad_glCheckNamedFramebufferStatus; #define glCheckNamedFramebufferStatus glad_glCheckNamedFramebufferStatus -GLAD_API_CALL PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv; + GLAD_API_CALL PFNGLPROGRAMUNIFORM1IVPROC glad_glProgramUniform1iv; #define glProgramUniform1iv glad_glProgramUniform1iv -GLAD_API_CALL PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays; + GLAD_API_CALL PFNGLMULTIDRAWARRAYSPROC glad_glMultiDrawArrays; #define glMultiDrawArrays glad_glMultiDrawArrays -GLAD_API_CALL PFNGLRASTERPOS4DVPROC glad_glRasterPos4dv; + GLAD_API_CALL PFNGLRASTERPOS4DVPROC glad_glRasterPos4dv; #define glRasterPos4dv glad_glRasterPos4dv -GLAD_API_CALL PFNGLGETFLOATVPROC glad_glGetFloatv; + GLAD_API_CALL PFNGLGETFLOATVPROC glad_glGetFloatv; #define glGetFloatv glad_glGetFloatv -GLAD_API_CALL PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri; + GLAD_API_CALL PFNGLPROGRAMPARAMETERIPROC glad_glProgramParameteri; #define glProgramParameteri glad_glProgramParameteri -GLAD_API_CALL PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; + GLAD_API_CALL PFNGLDELETERENDERBUFFERSPROC glad_glDeleteRenderbuffers; #define glDeleteRenderbuffers glad_glDeleteRenderbuffers -GLAD_API_CALL PFNGLSECONDARYCOLORPOINTERPROC glad_glSecondaryColorPointer; + GLAD_API_CALL PFNGLSECONDARYCOLORPOINTERPROC glad_glSecondaryColorPointer; #define glSecondaryColorPointer glad_glSecondaryColorPointer -GLAD_API_CALL PFNGLISSAMPLERPROC glad_glIsSampler; + GLAD_API_CALL PFNGLISSAMPLERPROC glad_glIsSampler; #define glIsSampler glad_glIsSampler -GLAD_API_CALL PFNGLMULTITEXCOORD1DVPROC glad_glMultiTexCoord1dv; + GLAD_API_CALL PFNGLMULTITEXCOORD1DVPROC glad_glMultiTexCoord1dv; #define glMultiTexCoord1dv glad_glMultiTexCoord1dv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv; + GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X3FVPROC glad_glProgramUniformMatrix2x3fv; #define glProgramUniformMatrix2x3fv glad_glProgramUniformMatrix2x3fv -GLAD_API_CALL PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl; + GLAD_API_CALL PFNGLDEBUGMESSAGECONTROLPROC glad_glDebugMessageControl; #define glDebugMessageControl glad_glDebugMessageControl -GLAD_API_CALL PFNGLBINDBUFFERSRANGEPROC glad_glBindBuffersRange; + GLAD_API_CALL PFNGLBINDBUFFERSRANGEPROC glad_glBindBuffersRange; #define glBindBuffersRange glad_glBindBuffersRange -GLAD_API_CALL PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect; + GLAD_API_CALL PFNGLMULTIDRAWARRAYSINDIRECTPROC glad_glMultiDrawArraysIndirect; #define glMultiDrawArraysIndirect glad_glMultiDrawArraysIndirect -GLAD_API_CALL PFNGLGETMAPDVPROC glad_glGetMapdv; + GLAD_API_CALL PFNGLGETMAPDVPROC glad_glGetMapdv; #define glGetMapdv glad_glGetMapdv -GLAD_API_CALL PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui; + GLAD_API_CALL PFNGLTEXCOORDP3UIPROC glad_glTexCoordP3ui; #define glTexCoordP3ui glad_glTexCoordP3ui -GLAD_API_CALL PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat; + GLAD_API_CALL PFNGLVERTEXATTRIBIFORMATPROC glad_glVertexAttribIFormat; #define glVertexAttribIFormat glad_glVertexAttribIFormat -GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced; + GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKSTREAMINSTANCEDPROC glad_glDrawTransformFeedbackStreamInstanced; #define glDrawTransformFeedbackStreamInstanced glad_glDrawTransformFeedbackStreamInstanced -GLAD_API_CALL PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase; + GLAD_API_CALL PFNGLTRANSFORMFEEDBACKBUFFERBASEPROC glad_glTransformFeedbackBufferBase; #define glTransformFeedbackBufferBase glad_glTransformFeedbackBufferBase -GLAD_API_CALL PFNGLGETTEXENVIVPROC glad_glGetTexEnviv; + GLAD_API_CALL PFNGLGETTEXENVIVPROC glad_glGetTexEnviv; #define glGetTexEnviv glad_glGetTexEnviv -GLAD_API_CALL PFNGLCOLORP3UIVPROC glad_glColorP3uiv; + GLAD_API_CALL PFNGLCOLORP3UIVPROC glad_glColorP3uiv; #define glColorP3uiv glad_glColorP3uiv -GLAD_API_CALL PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; + GLAD_API_CALL PFNGLVERTEXATTRIB1FPROC glad_glVertexAttrib1f; #define glVertexAttrib1f glad_glVertexAttrib1f -GLAD_API_CALL PFNGLPOPCLIENTATTRIBPROC glad_glPopClientAttrib; + GLAD_API_CALL PFNGLPOPCLIENTATTRIBPROC glad_glPopClientAttrib; #define glPopClientAttrib glad_glPopClientAttrib -GLAD_API_CALL PFNGLGETTEXIMAGEPROC glad_glGetTexImage; + GLAD_API_CALL PFNGLGETTEXIMAGEPROC glad_glGetTexImage; #define glGetTexImage glad_glGetTexImage -GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; + GLAD_API_CALL PFNGLRENDERBUFFERSTORAGEPROC glad_glRenderbufferStorage; #define glRenderbufferStorage glad_glRenderbufferStorage -GLAD_API_CALL PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; + GLAD_API_CALL PFNGLDELETEBUFFERSPROC glad_glDeleteBuffers; #define glDeleteBuffers glad_glDeleteBuffers -GLAD_API_CALL PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; + GLAD_API_CALL PFNGLCLIENTWAITSYNCPROC glad_glClientWaitSync; #define glClientWaitSync glad_glClientWaitSync -GLAD_API_CALL PFNGLPROGRAMUNIFORM1DVPROC glad_glProgramUniform1dv; + GLAD_API_CALL PFNGLPROGRAMUNIFORM1DVPROC glad_glProgramUniform1dv; #define glProgramUniform1dv glad_glProgramUniform1dv -GLAD_API_CALL PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage; + GLAD_API_CALL PFNGLCLEARTEXIMAGEPROC glad_glClearTexImage; #define glClearTexImage glad_glClearTexImage -GLAD_API_CALL PFNGLMULTITEXCOORD2FVPROC glad_glMultiTexCoord2fv; + GLAD_API_CALL PFNGLMULTITEXCOORD2FVPROC glad_glMultiTexCoord2fv; #define glMultiTexCoord2fv glad_glMultiTexCoord2fv -GLAD_API_CALL PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; + GLAD_API_CALL PFNGLUNIFORM3UIVPROC glad_glUniform3uiv; #define glUniform3uiv glad_glUniform3uiv -GLAD_API_CALL PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName; + GLAD_API_CALL PFNGLGETACTIVEUNIFORMNAMEPROC glad_glGetActiveUniformName; #define glGetActiveUniformName glad_glGetActiveUniformName -GLAD_API_CALL PFNGLEVALPOINT1PROC glad_glEvalPoint1; + GLAD_API_CALL PFNGLEVALPOINT1PROC glad_glEvalPoint1; #define glEvalPoint1 glad_glEvalPoint1 -GLAD_API_CALL PFNGLCOLOR3USPROC glad_glColor3us; + GLAD_API_CALL PFNGLCOLOR3USPROC glad_glColor3us; #define glColor3us glad_glColor3us -GLAD_API_CALL PFNGLGETTEXTURESUBIMAGEPROC glad_glGetTextureSubImage; + GLAD_API_CALL PFNGLGETTEXTURESUBIMAGEPROC glad_glGetTextureSubImage; #define glGetTextureSubImage glad_glGetTextureSubImage -GLAD_API_CALL PFNGLCOLOR3IPROC glad_glColor3i; + GLAD_API_CALL PFNGLCOLOR3IPROC glad_glColor3i; #define glColor3i glad_glColor3i -GLAD_API_CALL PFNGLSECONDARYCOLOR3DVPROC glad_glSecondaryColor3dv; + GLAD_API_CALL PFNGLSECONDARYCOLOR3DVPROC glad_glSecondaryColor3dv; #define glSecondaryColor3dv glad_glSecondaryColor3dv -GLAD_API_CALL PFNGLEVALCOORD1FVPROC glad_glEvalCoord1fv; + GLAD_API_CALL PFNGLEVALCOORD1FVPROC glad_glEvalCoord1fv; #define glEvalCoord1fv glad_glEvalCoord1fv -GLAD_API_CALL PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv; + GLAD_API_CALL PFNGLVIEWPORTARRAYVPROC glad_glViewportArrayv; #define glViewportArrayv glad_glViewportArrayv -GLAD_API_CALL PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; + GLAD_API_CALL PFNGLVERTEXATTRIBI4IPROC glad_glVertexAttribI4i; #define glVertexAttribI4i glad_glVertexAttribI4i -GLAD_API_CALL PFNGLVERTEXATTRIBL4DPROC glad_glVertexAttribL4d; + GLAD_API_CALL PFNGLVERTEXATTRIBL4DPROC glad_glVertexAttribL4d; #define glVertexAttribL4d glad_glVertexAttribL4d -GLAD_API_CALL PFNGLCOLOR4DPROC glad_glColor4d; + GLAD_API_CALL PFNGLCOLOR4DPROC glad_glColor4d; #define glColor4d glad_glColor4d -GLAD_API_CALL PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; + GLAD_API_CALL PFNGLGETFRAGDATALOCATIONPROC glad_glGetFragDataLocation; #define glGetFragDataLocation glad_glGetFragDataLocation -GLAD_API_CALL PFNGLCOLOR4UBVPROC glad_glColor4ubv; + GLAD_API_CALL PFNGLCOLOR4UBVPROC glad_glColor4ubv; #define glColor4ubv glad_glColor4ubv -GLAD_API_CALL PFNGLUNIFORMMATRIX4DVPROC glad_glUniformMatrix4dv; + GLAD_API_CALL PFNGLUNIFORMMATRIX4DVPROC glad_glUniformMatrix4dv; #define glUniformMatrix4dv glad_glUniformMatrix4dv -GLAD_API_CALL PFNGLUNIFORMMATRIX3X4DVPROC glad_glUniformMatrix3x4dv; + GLAD_API_CALL PFNGLUNIFORMMATRIX3X4DVPROC glad_glUniformMatrix3x4dv; #define glUniformMatrix3x4dv glad_glUniformMatrix3x4dv -GLAD_API_CALL PFNGLSCISSORPROC glad_glScissor; + GLAD_API_CALL PFNGLSCISSORPROC glad_glScissor; #define glScissor glad_glScissor -GLAD_API_CALL PFNGLUNIFORMSUBROUTINESUIVPROC glad_glUniformSubroutinesuiv; + GLAD_API_CALL PFNGLUNIFORMSUBROUTINESUIVPROC glad_glUniformSubroutinesuiv; #define glUniformSubroutinesuiv glad_glUniformSubroutinesuiv -GLAD_API_CALL PFNGLVERTEX4IVPROC glad_glVertex4iv; + GLAD_API_CALL PFNGLVERTEX4IVPROC glad_glVertex4iv; #define glVertex4iv glad_glVertex4iv -GLAD_API_CALL PFNGLCOLORMASKPROC glad_glColorMask; + GLAD_API_CALL PFNGLCOLORMASKPROC glad_glColorMask; #define glColorMask glad_glColorMask -GLAD_API_CALL PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; + GLAD_API_CALL PFNGLSTENCILOPSEPARATEPROC glad_glStencilOpSeparate; #define glStencilOpSeparate glad_glStencilOpSeparate -GLAD_API_CALL PFNGLGETBOOLEANVPROC glad_glGetBooleanv; + GLAD_API_CALL PFNGLGETBOOLEANVPROC glad_glGetBooleanv; #define glGetBooleanv glad_glGetBooleanv -GLAD_API_CALL PFNGLVERTEX3DPROC glad_glVertex3d; + GLAD_API_CALL PFNGLVERTEX3DPROC glad_glVertex3d; #define glVertex3d glad_glVertex3d -GLAD_API_CALL PFNGLGETNAMEDBUFFERPOINTERVPROC glad_glGetNamedBufferPointerv; + GLAD_API_CALL PFNGLGETNAMEDBUFFERPOINTERVPROC glad_glGetNamedBufferPointerv; #define glGetNamedBufferPointerv glad_glGetNamedBufferPointerv -GLAD_API_CALL PFNGLVERTEXARRAYVERTEXBUFFERPROC glad_glVertexArrayVertexBuffer; + GLAD_API_CALL PFNGLVERTEXARRAYVERTEXBUFFERPROC glad_glVertexArrayVertexBuffer; #define glVertexArrayVertexBuffer glad_glVertexArrayVertexBuffer -GLAD_API_CALL PFNGLGETPOLYGONSTIPPLEPROC glad_glGetPolygonStipple; + GLAD_API_CALL PFNGLGETPOLYGONSTIPPLEPROC glad_glGetPolygonStipple; #define glGetPolygonStipple glad_glGetPolygonStipple -GLAD_API_CALL PFNGLSTENCILOPPROC glad_glStencilOp; + GLAD_API_CALL PFNGLSTENCILOPPROC glad_glStencilOp; #define glStencilOp glad_glStencilOp -GLAD_API_CALL PFNGLVIEWPORTPROC glad_glViewport; + GLAD_API_CALL PFNGLVIEWPORTPROC glad_glViewport; #define glViewport glad_glViewport -GLAD_API_CALL PFNGLGETNPOLYGONSTIPPLEPROC glad_glGetnPolygonStipple; + GLAD_API_CALL PFNGLGETNPOLYGONSTIPPLEPROC glad_glGetnPolygonStipple; #define glGetnPolygonStipple glad_glGetnPolygonStipple -GLAD_API_CALL PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv; + GLAD_API_CALL PFNGLVERTEXATTRIB4USVPROC glad_glVertexAttrib4usv; #define glVertexAttrib4usv glad_glVertexAttrib4usv -GLAD_API_CALL PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; + GLAD_API_CALL PFNGLENDTRANSFORMFEEDBACKPROC glad_glEndTransformFeedback; #define glEndTransformFeedback glad_glEndTransformFeedback -GLAD_API_CALL PFNGLCREATEPROGRAMPROC glad_glCreateProgram; + GLAD_API_CALL PFNGLCREATEPROGRAMPROC glad_glCreateProgram; #define glCreateProgram glad_glCreateProgram -GLAD_API_CALL PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; + GLAD_API_CALL PFNGLGETSHADERINFOLOGPROC glad_glGetShaderInfoLog; #define glGetShaderInfoLog glad_glGetShaderInfoLog -GLAD_API_CALL PFNGLGETVERTEXARRAYINDEXED64IVPROC glad_glGetVertexArrayIndexed64iv; + GLAD_API_CALL PFNGLGETVERTEXARRAYINDEXED64IVPROC glad_glGetVertexArrayIndexed64iv; #define glGetVertexArrayIndexed64iv glad_glGetVertexArrayIndexed64iv -GLAD_API_CALL PFNGLTEXGENDPROC glad_glTexGend; + GLAD_API_CALL PFNGLTEXGENDPROC glad_glTexGend; #define glTexGend glad_glTexGend -GLAD_API_CALL PFNGLINDEXUBPROC glad_glIndexub; + GLAD_API_CALL PFNGLINDEXUBPROC glad_glIndexub; #define glIndexub glad_glIndexub -GLAD_API_CALL PFNGLMULTMATRIXFPROC glad_glMultMatrixf; + GLAD_API_CALL PFNGLMULTMATRIXFPROC glad_glMultMatrixf; #define glMultMatrixf glad_glMultMatrixf -GLAD_API_CALL PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui; + GLAD_API_CALL PFNGLMULTITEXCOORDP2UIPROC glad_glMultiTexCoordP2ui; #define glMultiTexCoordP2ui glad_glMultiTexCoordP2ui -GLAD_API_CALL PFNGLTEXIMAGE3DPROC glad_glTexImage3D; + GLAD_API_CALL PFNGLTEXIMAGE3DPROC glad_glTexImage3D; #define glTexImage3D glad_glTexImage3D -GLAD_API_CALL PFNGLGETNUNIFORMDVPROC glad_glGetnUniformdv; + GLAD_API_CALL PFNGLGETNUNIFORMDVPROC glad_glGetnUniformdv; #define glGetnUniformdv glad_glGetnUniformdv -GLAD_API_CALL PFNGLRECTIVPROC glad_glRectiv; + GLAD_API_CALL PFNGLRECTIVPROC glad_glRectiv; #define glRectiv glad_glRectiv -GLAD_API_CALL PFNGLTEXCOORD4SPROC glad_glTexCoord4s; + GLAD_API_CALL PFNGLTEXCOORD4SPROC glad_glTexCoord4s; #define glTexCoord4s glad_glTexCoord4s -GLAD_API_CALL PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; + GLAD_API_CALL PFNGLCOPYTEXIMAGE2DPROC glad_glCopyTexImage2D; #define glCopyTexImage2D glad_glCopyTexImage2D -GLAD_API_CALL PFNGLLOGICOPPROC glad_glLogicOp; + GLAD_API_CALL PFNGLLOGICOPPROC glad_glLogicOp; #define glLogicOp glad_glLogicOp -GLAD_API_CALL PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; + GLAD_API_CALL PFNGLUNIFORMMATRIX2FVPROC glad_glUniformMatrix2fv; #define glUniformMatrix2fv glad_glUniformMatrix2fv -GLAD_API_CALL PFNGLSECONDARYCOLOR3FVPROC glad_glSecondaryColor3fv; + GLAD_API_CALL PFNGLSECONDARYCOLOR3FVPROC glad_glSecondaryColor3fv; #define glSecondaryColor3fv glad_glSecondaryColor3fv -GLAD_API_CALL PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; + GLAD_API_CALL PFNGLBINDRENDERBUFFERPROC glad_glBindRenderbuffer; #define glBindRenderbuffer glad_glBindRenderbuffer -GLAD_API_CALL PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv; + GLAD_API_CALL PFNGLPROGRAMUNIFORM4UIVPROC glad_glProgramUniform4uiv; #define glProgramUniform4uiv glad_glProgramUniform4uiv -GLAD_API_CALL PFNGLCREATESAMPLERSPROC glad_glCreateSamplers; + GLAD_API_CALL PFNGLCREATESAMPLERSPROC glad_glCreateSamplers; #define glCreateSamplers glad_glCreateSamplers -GLAD_API_CALL PFNGLPIXELMAPUIVPROC glad_glPixelMapuiv; + GLAD_API_CALL PFNGLPIXELMAPUIVPROC glad_glPixelMapuiv; #define glPixelMapuiv glad_glPixelMapuiv -GLAD_API_CALL PFNGLBLENDCOLORPROC glad_glBlendColor; + GLAD_API_CALL PFNGLBLENDCOLORPROC glad_glBlendColor; #define glBlendColor glad_glBlendColor -GLAD_API_CALL PFNGLLIGHTMODELIPROC glad_glLightModeli; + GLAD_API_CALL PFNGLLIGHTMODELIPROC glad_glLightModeli; #define glLightModeli glad_glLightModeli -GLAD_API_CALL PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; + GLAD_API_CALL PFNGLPOINTPARAMETERIPROC glad_glPointParameteri; #define glPointParameteri glad_glPointParameteri -GLAD_API_CALL PFNGLGENQUERIESPROC glad_glGenQueries; + GLAD_API_CALL PFNGLGENQUERIESPROC glad_glGenQueries; #define glGenQueries glad_glGenQueries -GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture; + GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTUREPROC glad_glNamedFramebufferTexture; #define glNamedFramebufferTexture glad_glNamedFramebufferTexture -GLAD_API_CALL PFNGLGETNSEPARABLEFILTERPROC glad_glGetnSeparableFilter; + GLAD_API_CALL PFNGLGETNSEPARABLEFILTERPROC glad_glGetnSeparableFilter; #define glGetnSeparableFilter glad_glGetnSeparableFilter -GLAD_API_CALL PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; + GLAD_API_CALL PFNGLGETQUERYOBJECTUIVPROC glad_glGetQueryObjectuiv; #define glGetQueryObjectuiv glad_glGetQueryObjectuiv -GLAD_API_CALL PFNGLCOLOR4FVPROC glad_glColor4fv; + GLAD_API_CALL PFNGLCOLOR4FVPROC glad_glColor4fv; #define glColor4fv glad_glColor4fv -GLAD_API_CALL PFNGLGETVERTEXARRAYIVPROC glad_glGetVertexArrayiv; + GLAD_API_CALL PFNGLGETVERTEXARRAYIVPROC glad_glGetVertexArrayiv; #define glGetVertexArrayiv glad_glGetVertexArrayiv -GLAD_API_CALL PFNGLUNIFORM1UIPROC glad_glUniform1ui; + GLAD_API_CALL PFNGLUNIFORM1UIPROC glad_glUniform1ui; #define glUniform1ui glad_glUniform1ui -GLAD_API_CALL PFNGLGETNMAPFVPROC glad_glGetnMapfv; + GLAD_API_CALL PFNGLGETNMAPFVPROC glad_glGetnMapfv; #define glGetnMapfv glad_glGetnMapfv -GLAD_API_CALL PFNGLUNIFORM4FVPROC glad_glUniform4fv; + GLAD_API_CALL PFNGLUNIFORM4FVPROC glad_glUniform4fv; #define glUniform4fv glad_glUniform4fv -GLAD_API_CALL PFNGLTEXGENFPROC glad_glTexGenf; + GLAD_API_CALL PFNGLTEXGENFPROC glad_glTexGenf; #define glTexGenf glad_glTexGenf -GLAD_API_CALL PFNGLINDEXIVPROC glad_glIndexiv; + GLAD_API_CALL PFNGLINDEXIVPROC glad_glIndexiv; #define glIndexiv glad_glIndexiv -GLAD_API_CALL PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; + GLAD_API_CALL PFNGLVERTEXATTRIB1FVPROC glad_glVertexAttrib1fv; #define glVertexAttrib1fv glad_glVertexAttrib1fv -GLAD_API_CALL PFNGLMULTITEXCOORD3IPROC glad_glMultiTexCoord3i; + GLAD_API_CALL PFNGLMULTITEXCOORD3IPROC glad_glMultiTexCoord3i; #define glMultiTexCoord3i glad_glMultiTexCoord3i -GLAD_API_CALL PFNGLCOLOR4USVPROC glad_glColor4usv; + GLAD_API_CALL PFNGLCOLOR4USVPROC glad_glColor4usv; #define glColor4usv glad_glColor4usv -GLAD_API_CALL PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; + GLAD_API_CALL PFNGLDRAWBUFFERSPROC glad_glDrawBuffers; #define glDrawBuffers glad_glDrawBuffers -GLAD_API_CALL PFNGLWINDOWPOS2IPROC glad_glWindowPos2i; + GLAD_API_CALL PFNGLWINDOWPOS2IPROC glad_glWindowPos2i; #define glWindowPos2i glad_glWindowPos2i -GLAD_API_CALL PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange; + GLAD_API_CALL PFNGLTEXBUFFERRANGEPROC glad_glTexBufferRange; #define glTexBufferRange glad_glTexBufferRange -GLAD_API_CALL PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv; + GLAD_API_CALL PFNGLMULTITEXCOORDP1UIVPROC glad_glMultiTexCoordP1uiv; #define glMultiTexCoordP1uiv glad_glMultiTexCoordP1uiv -GLAD_API_CALL PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv; + GLAD_API_CALL PFNGLVERTEXATTRIBI2IVPROC glad_glVertexAttribI2iv; #define glVertexAttribI2iv glad_glVertexAttribI2iv -GLAD_API_CALL PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect; + GLAD_API_CALL PFNGLMULTIDRAWELEMENTSINDIRECTPROC glad_glMultiDrawElementsIndirect; #define glMultiDrawElementsIndirect glad_glMultiDrawElementsIndirect -GLAD_API_CALL PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; + GLAD_API_CALL PFNGLUNIFORMMATRIX2X4FVPROC glad_glUniformMatrix2x4fv; #define glUniformMatrix2x4fv glad_glUniformMatrix2x4fv -GLAD_API_CALL PFNGLUNIFORM3IPROC glad_glUniform3i; + GLAD_API_CALL PFNGLUNIFORM3IPROC glad_glUniform3i; #define glUniform3i glad_glUniform3i -GLAD_API_CALL PFNGLGETCLIPPLANEPROC glad_glGetClipPlane; + GLAD_API_CALL PFNGLGETCLIPPLANEPROC glad_glGetClipPlane; #define glGetClipPlane glad_glGetClipPlane -GLAD_API_CALL PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv; + GLAD_API_CALL PFNGLVERTEXATTRIBP2UIVPROC glad_glVertexAttribP2uiv; #define glVertexAttribP2uiv glad_glVertexAttribP2uiv -GLAD_API_CALL PFNGLTEXCOORD2IPROC glad_glTexCoord2i; + GLAD_API_CALL PFNGLTEXCOORD2IPROC glad_glTexCoord2i; #define glTexCoord2i glad_glTexCoord2i -GLAD_API_CALL PFNGLUNIFORM4UIPROC glad_glUniform4ui; + GLAD_API_CALL PFNGLUNIFORM4UIPROC glad_glUniform4ui; #define glUniform4ui glad_glUniform4ui -GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance; + GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCEPROC glad_glDrawElementsInstancedBaseVertexBaseInstance; #define glDrawElementsInstancedBaseVertexBaseInstance glad_glDrawElementsInstancedBaseVertexBaseInstance -GLAD_API_CALL PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv; + GLAD_API_CALL PFNGLVERTEXATTRIB4NUSVPROC glad_glVertexAttrib4Nusv; #define glVertexAttrib4Nusv glad_glVertexAttrib4Nusv -GLAD_API_CALL PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d; + GLAD_API_CALL PFNGLVERTEXATTRIB1DPROC glad_glVertexAttrib1d; #define glVertexAttrib1d glad_glVertexAttrib1d -GLAD_API_CALL PFNGLGETLIGHTIVPROC glad_glGetLightiv; + GLAD_API_CALL PFNGLGETLIGHTIVPROC glad_glGetLightiv; #define glGetLightiv glad_glGetLightiv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glad_glProgramUniformMatrix3x4dv; + GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X4DVPROC glad_glProgramUniformMatrix3x4dv; #define glProgramUniformMatrix3x4dv glad_glProgramUniformMatrix3x4dv -GLAD_API_CALL PFNGLTEXTURESTORAGE1DPROC glad_glTextureStorage1D; + GLAD_API_CALL PFNGLTEXTURESTORAGE1DPROC glad_glTextureStorage1D; #define glTextureStorage1D glad_glTextureStorage1D -GLAD_API_CALL PFNGLSTENCILMASKPROC glad_glStencilMask; + GLAD_API_CALL PFNGLSTENCILMASKPROC glad_glStencilMask; #define glStencilMask glad_glStencilMask -GLAD_API_CALL PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; + GLAD_API_CALL PFNGLGETRENDERBUFFERPARAMETERIVPROC glad_glGetRenderbufferParameteriv; #define glGetRenderbufferParameteriv glad_glGetRenderbufferParameteriv -GLAD_API_CALL PFNGLMULTITEXCOORD4FPROC glad_glMultiTexCoord4f; + GLAD_API_CALL PFNGLMULTITEXCOORD4FPROC glad_glMultiTexCoord4f; #define glMultiTexCoord4f glad_glMultiTexCoord4f -GLAD_API_CALL PFNGLINDEXDPROC glad_glIndexd; + GLAD_API_CALL PFNGLINDEXDPROC glad_glIndexd; #define glIndexd glad_glIndexd -GLAD_API_CALL PFNGLNORMALP3UIVPROC glad_glNormalP3uiv; + GLAD_API_CALL PFNGLNORMALP3UIVPROC glad_glNormalP3uiv; #define glNormalP3uiv glad_glNormalP3uiv -GLAD_API_CALL PFNGLEVALMESH1PROC glad_glEvalMesh1; + GLAD_API_CALL PFNGLEVALMESH1PROC glad_glEvalMesh1; #define glEvalMesh1 glad_glEvalMesh1 -GLAD_API_CALL PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv; + GLAD_API_CALL PFNGLTEXCOORDP3UIVPROC glad_glTexCoordP3uiv; #define glTexCoordP3uiv glad_glTexCoordP3uiv -GLAD_API_CALL PFNGLVERTEXATTRIBL4DVPROC glad_glVertexAttribL4dv; + GLAD_API_CALL PFNGLVERTEXATTRIBL4DVPROC glad_glVertexAttribL4dv; #define glVertexAttribL4dv glad_glVertexAttribL4dv -GLAD_API_CALL PFNGLCLIENTACTIVETEXTUREPROC glad_glClientActiveTexture; + GLAD_API_CALL PFNGLCLIENTACTIVETEXTUREPROC glad_glClientActiveTexture; #define glClientActiveTexture glad_glClientActiveTexture -GLAD_API_CALL PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s; + GLAD_API_CALL PFNGLVERTEXATTRIB2SPROC glad_glVertexAttrib2s; #define glVertexAttrib2s glad_glVertexAttrib2s -GLAD_API_CALL PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv; + GLAD_API_CALL PFNGLVERTEXATTRIB3DVPROC glad_glVertexAttrib3dv; #define glVertexAttrib3dv glad_glVertexAttrib3dv -GLAD_API_CALL PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv; + GLAD_API_CALL PFNGLTEXPARAMETERIIVPROC glad_glTexParameterIiv; #define glTexParameterIiv glad_glTexParameterIiv -GLAD_API_CALL PFNGLRASTERPOS3DPROC glad_glRasterPos3d; + GLAD_API_CALL PFNGLRASTERPOS3DPROC glad_glRasterPos3d; #define glRasterPos3d glad_glRasterPos3d -GLAD_API_CALL PFNGLEVALCOORD2FVPROC glad_glEvalCoord2fv; + GLAD_API_CALL PFNGLEVALCOORD2FVPROC glad_glEvalCoord2fv; #define glEvalCoord2fv glad_glEvalCoord2fv -GLAD_API_CALL PFNGLBINDTEXTUREUNITPROC glad_glBindTextureUnit; + GLAD_API_CALL PFNGLBINDTEXTUREUNITPROC glad_glBindTextureUnit; #define glBindTextureUnit glad_glBindTextureUnit -GLAD_API_CALL PFNGLWAITSYNCPROC glad_glWaitSync; + GLAD_API_CALL PFNGLWAITSYNCPROC glad_glWaitSync; #define glWaitSync glad_glWaitSync -GLAD_API_CALL PFNGLMATERIALFVPROC glad_glMaterialfv; + GLAD_API_CALL PFNGLMATERIALFVPROC glad_glMaterialfv; #define glMaterialfv glad_glMaterialfv -GLAD_API_CALL PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i; + GLAD_API_CALL PFNGLPROGRAMUNIFORM2IPROC glad_glProgramUniform2i; #define glProgramUniform2i glad_glProgramUniform2i -GLAD_API_CALL PFNGLRASTERPOS2SPROC glad_glRasterPos2s; + GLAD_API_CALL PFNGLRASTERPOS2SPROC glad_glRasterPos2s; #define glRasterPos2s glad_glRasterPos2s -GLAD_API_CALL PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv; + GLAD_API_CALL PFNGLVERTEXATTRIBI4BVPROC glad_glVertexAttribI4bv; #define glVertexAttribI4bv glad_glVertexAttribI4bv -GLAD_API_CALL PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv; + GLAD_API_CALL PFNGLVERTEXATTRIBI4SVPROC glad_glVertexAttribI4sv; #define glVertexAttribI4sv glad_glVertexAttribI4sv -GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; + GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEPROC glad_glBlendEquationSeparate; #define glBlendEquationSeparate glad_glBlendEquationSeparate -GLAD_API_CALL PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv; + GLAD_API_CALL PFNGLVERTEXATTRIBI3UIVPROC glad_glVertexAttribI3uiv; #define glVertexAttribI3uiv glad_glVertexAttribI3uiv -GLAD_API_CALL PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv; + GLAD_API_CALL PFNGLVERTEXATTRIBI2UIVPROC glad_glVertexAttribI2uiv; #define glVertexAttribI2uiv glad_glVertexAttribI2uiv -GLAD_API_CALL PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv; + GLAD_API_CALL PFNGLVERTEXP4UIVPROC glad_glVertexP4uiv; #define glVertexP4uiv glad_glVertexP4uiv -GLAD_API_CALL PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; + GLAD_API_CALL PFNGLGETUNIFORMBLOCKINDEXPROC glad_glGetUniformBlockIndex; #define glGetUniformBlockIndex glad_glGetUniformBlockIndex -GLAD_API_CALL PFNGLDEPTHFUNCPROC glad_glDepthFunc; + GLAD_API_CALL PFNGLDEPTHFUNCPROC glad_glDepthFunc; #define glDepthFunc glad_glDepthFunc -GLAD_API_CALL PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f; + GLAD_API_CALL PFNGLPROGRAMUNIFORM4FPROC glad_glProgramUniform4f; #define glProgramUniform4f glad_glProgramUniform4f -GLAD_API_CALL PFNGLSHADERSOURCEPROC glad_glShaderSource; + GLAD_API_CALL PFNGLSHADERSOURCEPROC glad_glShaderSource; #define glShaderSource glad_glShaderSource -GLAD_API_CALL PFNGLVERTEX2IVPROC glad_glVertex2iv; + GLAD_API_CALL PFNGLVERTEX2IVPROC glad_glVertex2iv; #define glVertex2iv glad_glVertex2iv -GLAD_API_CALL PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer; + GLAD_API_CALL PFNGLMAPNAMEDBUFFERPROC glad_glMapNamedBuffer; #define glMapNamedBuffer glad_glMapNamedBuffer -GLAD_API_CALL PFNGLCLEARDEPTHFPROC glad_glClearDepthf; + GLAD_API_CALL PFNGLCLEARDEPTHFPROC glad_glClearDepthf; #define glClearDepthf glad_glClearDepthf -GLAD_API_CALL PFNGLUNIFORM1FPROC glad_glUniform1f; + GLAD_API_CALL PFNGLUNIFORM1FPROC glad_glUniform1f; #define glUniform1f glad_glUniform1f -GLAD_API_CALL PFNGLMULTITEXCOORD1DPROC glad_glMultiTexCoord1d; + GLAD_API_CALL PFNGLMULTITEXCOORD1DPROC glad_glMultiTexCoord1d; #define glMultiTexCoord1d glad_glMultiTexCoord1d -GLAD_API_CALL PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v; + GLAD_API_CALL PFNGLGETQUERYOBJECTUI64VPROC glad_glGetQueryObjectui64v; #define glGetQueryObjectui64v glad_glGetQueryObjectui64v -GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glad_glNamedFramebufferDrawBuffers; + GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERDRAWBUFFERSPROC glad_glNamedFramebufferDrawBuffers; #define glNamedFramebufferDrawBuffers glad_glNamedFramebufferDrawBuffers -GLAD_API_CALL PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; + GLAD_API_CALL PFNGLTEXSUBIMAGE3DPROC glad_glTexSubImage3D; #define glTexSubImage3D glad_glTexSubImage3D -GLAD_API_CALL PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks; + GLAD_API_CALL PFNGLDELETETRANSFORMFEEDBACKSPROC glad_glDeleteTransformFeedbacks; #define glDeleteTransformFeedbacks glad_glDeleteTransformFeedbacks -GLAD_API_CALL PFNGLVERTEX3IVPROC glad_glVertex3iv; + GLAD_API_CALL PFNGLVERTEX3IVPROC glad_glVertex3iv; #define glVertex3iv glad_glVertex3iv -GLAD_API_CALL PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; + GLAD_API_CALL PFNGLUNIFORMMATRIX2X3FVPROC glad_glUniformMatrix2x3fv; #define glUniformMatrix2x3fv glad_glUniformMatrix2x3fv -GLAD_API_CALL PFNGLISTEXTUREPROC glad_glIsTexture; + GLAD_API_CALL PFNGLISTEXTUREPROC glad_glIsTexture; #define glIsTexture glad_glIsTexture -GLAD_API_CALL PFNGLMULTTRANSPOSEMATRIXFPROC glad_glMultTransposeMatrixf; + GLAD_API_CALL PFNGLMULTTRANSPOSEMATRIXFPROC glad_glMultTransposeMatrixf; #define glMultTransposeMatrixf glad_glMultTransposeMatrixf -GLAD_API_CALL PFNGLNEWLISTPROC glad_glNewList; + GLAD_API_CALL PFNGLNEWLISTPROC glad_glNewList; #define glNewList glad_glNewList -GLAD_API_CALL PFNGLSCALEFPROC glad_glScalef; + GLAD_API_CALL PFNGLSCALEFPROC glad_glScalef; #define glScalef glad_glScalef -GLAD_API_CALL PFNGLVERTEX3FPROC glad_glVertex3f; + GLAD_API_CALL PFNGLVERTEX3FPROC glad_glVertex3f; #define glVertex3f glad_glVertex3f -GLAD_API_CALL PFNGLTEXCOORD1IVPROC glad_glTexCoord1iv; + GLAD_API_CALL PFNGLTEXCOORD1IVPROC glad_glTexCoord1iv; #define glTexCoord1iv glad_glTexCoord1iv -GLAD_API_CALL PFNGLFOGCOORDFVPROC glad_glFogCoordfv; + GLAD_API_CALL PFNGLFOGCOORDFVPROC glad_glFogCoordfv; #define glFogCoordfv glad_glFogCoordfv -GLAD_API_CALL PFNGLMAPGRID2DPROC glad_glMapGrid2d; + GLAD_API_CALL PFNGLMAPGRID2DPROC glad_glMapGrid2d; #define glMapGrid2d glad_glMapGrid2d -GLAD_API_CALL PFNGLWINDOWPOS2FVPROC glad_glWindowPos2fv; + GLAD_API_CALL PFNGLWINDOWPOS2FVPROC glad_glWindowPos2fv; #define glWindowPos2fv glad_glWindowPos2fv -GLAD_API_CALL PFNGLREADPIXELSPROC glad_glReadPixels; + GLAD_API_CALL PFNGLREADPIXELSPROC glad_glReadPixels; #define glReadPixels glad_glReadPixels -GLAD_API_CALL PFNGLINVALIDATETEXSUBIMAGEPROC glad_glInvalidateTexSubImage; + GLAD_API_CALL PFNGLINVALIDATETEXSUBIMAGEPROC glad_glInvalidateTexSubImage; #define glInvalidateTexSubImage glad_glInvalidateTexSubImage -GLAD_API_CALL PFNGLORTHOPROC glad_glOrtho; + GLAD_API_CALL PFNGLORTHOPROC glad_glOrtho; #define glOrtho glad_glOrtho -GLAD_API_CALL PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv; + GLAD_API_CALL PFNGLGETQUERYOBJECTIVPROC glad_glGetQueryObjectiv; #define glGetQueryObjectiv glad_glGetQueryObjectiv -GLAD_API_CALL PFNGLWINDOWPOS2SVPROC glad_glWindowPos2sv; + GLAD_API_CALL PFNGLWINDOWPOS2SVPROC glad_glWindowPos2sv; #define glWindowPos2sv glad_glWindowPos2sv -GLAD_API_CALL PFNGLFOGFPROC glad_glFogf; + GLAD_API_CALL PFNGLFOGFPROC glad_glFogf; #define glFogf glad_glFogf -GLAD_API_CALL PFNGLCOLOR3SPROC glad_glColor3s; + GLAD_API_CALL PFNGLCOLOR3SPROC glad_glColor3s; #define glColor3s glad_glColor3s -GLAD_API_CALL PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; + GLAD_API_CALL PFNGLUNIFORM2UIVPROC glad_glUniform2uiv; #define glUniform2uiv glad_glUniform2uiv -GLAD_API_CALL PFNGLPIXELZOOMPROC glad_glPixelZoom; + GLAD_API_CALL PFNGLPIXELZOOMPROC glad_glPixelZoom; #define glPixelZoom glad_glPixelZoom -GLAD_API_CALL PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f; + GLAD_API_CALL PFNGLPROGRAMUNIFORM3FPROC glad_glProgramUniform3f; #define glProgramUniform3f glad_glProgramUniform3f -GLAD_API_CALL PFNGLEVALCOORD2DVPROC glad_glEvalCoord2dv; + GLAD_API_CALL PFNGLEVALCOORD2DVPROC glad_glEvalCoord2dv; #define glEvalCoord2dv glad_glEvalCoord2dv -GLAD_API_CALL PFNGLVERTEX3DVPROC glad_glVertex3dv; + GLAD_API_CALL PFNGLVERTEX3DVPROC glad_glVertex3dv; #define glVertex3dv glad_glVertex3dv -GLAD_API_CALL PFNGLUNIFORM3FVPROC glad_glUniform3fv; + GLAD_API_CALL PFNGLUNIFORM3FVPROC glad_glUniform3fv; #define glUniform3fv glad_glUniform3fv -GLAD_API_CALL PFNGLENABLEPROC glad_glEnable; + GLAD_API_CALL PFNGLENABLEPROC glad_glEnable; #define glEnable glad_glEnable -GLAD_API_CALL PFNGLTEXTUREPARAMETERIUIVPROC glad_glTextureParameterIuiv; + GLAD_API_CALL PFNGLTEXTUREPARAMETERIUIVPROC glad_glTextureParameterIuiv; #define glTextureParameterIuiv glad_glTextureParameterIuiv -GLAD_API_CALL PFNGLFOGCOORDDVPROC glad_glFogCoorddv; + GLAD_API_CALL PFNGLFOGCOORDDVPROC glad_glFogCoorddv; #define glFogCoorddv glad_glFogCoorddv -GLAD_API_CALL PFNGLBUFFERDATAPROC glad_glBufferData; + GLAD_API_CALL PFNGLBUFFERDATAPROC glad_glBufferData; #define glBufferData glad_glBufferData -GLAD_API_CALL PFNGLPOPATTRIBPROC glad_glPopAttrib; + GLAD_API_CALL PFNGLPOPATTRIBPROC glad_glPopAttrib; #define glPopAttrib glad_glPopAttrib -GLAD_API_CALL PFNGLNORMAL3DVPROC glad_glNormal3dv; + GLAD_API_CALL PFNGLNORMAL3DVPROC glad_glNormal3dv; #define glNormal3dv glad_glNormal3dv -GLAD_API_CALL PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex; + GLAD_API_CALL PFNGLGETFRAGDATAINDEXPROC glad_glGetFragDataIndex; #define glGetFragDataIndex glad_glGetFragDataIndex -GLAD_API_CALL PFNGLPASSTHROUGHPROC glad_glPassThrough; + GLAD_API_CALL PFNGLPASSTHROUGHPROC glad_glPassThrough; #define glPassThrough glad_glPassThrough -GLAD_API_CALL PFNGLTEXCOORD2DVPROC glad_glTexCoord2dv; + GLAD_API_CALL PFNGLTEXCOORD2DVPROC glad_glTexCoord2dv; #define glTexCoord2dv glad_glTexCoord2dv -GLAD_API_CALL PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv; + GLAD_API_CALL PFNGLTEXCOORDP4UIVPROC glad_glTexCoordP4uiv; #define glTexCoordP4uiv glad_glTexCoordP4uiv -GLAD_API_CALL PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; + GLAD_API_CALL PFNGLCLEARBUFFERUIVPROC glad_glClearBufferuiv; #define glClearBufferuiv glad_glClearBufferuiv -GLAD_API_CALL PFNGLUNIFORM3DVPROC glad_glUniform3dv; + GLAD_API_CALL PFNGLUNIFORM3DVPROC glad_glUniform3dv; #define glUniform3dv glad_glUniform3dv -GLAD_API_CALL PFNGLBLENDEQUATIONIPROC glad_glBlendEquationi; + GLAD_API_CALL PFNGLBLENDEQUATIONIPROC glad_glBlendEquationi; #define glBlendEquationi glad_glBlendEquationi -GLAD_API_CALL PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; + GLAD_API_CALL PFNGLVERTEXATTRIBI4UIPROC glad_glVertexAttribI4ui; #define glVertexAttribI4ui glad_glVertexAttribI4ui -GLAD_API_CALL PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; + GLAD_API_CALL PFNGLGETTEXLEVELPARAMETERIVPROC glad_glGetTexLevelParameteriv; #define glGetTexLevelParameteriv glad_glGetTexLevelParameteriv -GLAD_API_CALL PFNGLVERTEX4IPROC glad_glVertex4i; + GLAD_API_CALL PFNGLVERTEX4IPROC glad_glVertex4i; #define glVertex4i glad_glVertex4i -GLAD_API_CALL PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; + GLAD_API_CALL PFNGLUNIFORM4UIVPROC glad_glUniform4uiv; #define glUniform4uiv glad_glUniform4uiv -GLAD_API_CALL PFNGLTEXENVFVPROC glad_glTexEnvfv; + GLAD_API_CALL PFNGLTEXENVFVPROC glad_glTexEnvfv; #define glTexEnvfv glad_glTexEnvfv -GLAD_API_CALL PFNGLMULTITEXCOORD4DVPROC glad_glMultiTexCoord4dv; + GLAD_API_CALL PFNGLMULTITEXCOORD4DVPROC glad_glMultiTexCoord4dv; #define glMultiTexCoord4dv glad_glMultiTexCoord4dv -GLAD_API_CALL PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage; + GLAD_API_CALL PFNGLCLEARTEXSUBIMAGEPROC glad_glClearTexSubImage; #define glClearTexSubImage glad_glClearTexSubImage -GLAD_API_CALL PFNGLTRANSLATEDPROC glad_glTranslated; + GLAD_API_CALL PFNGLTRANSLATEDPROC glad_glTranslated; #define glTranslated glad_glTranslated -GLAD_API_CALL PFNGLPOINTPARAMETERFPROC glad_glPointParameterf; + GLAD_API_CALL PFNGLPOINTPARAMETERFPROC glad_glPointParameterf; #define glPointParameterf glad_glPointParameterf -GLAD_API_CALL PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv; + GLAD_API_CALL PFNGLSCISSORINDEXEDVPROC glad_glScissorIndexedv; #define glScissorIndexedv glad_glScissorIndexedv -GLAD_API_CALL PFNGLPROGRAMUNIFORM2DVPROC glad_glProgramUniform2dv; + GLAD_API_CALL PFNGLPROGRAMUNIFORM2DVPROC glad_glProgramUniform2dv; #define glProgramUniform2dv glad_glProgramUniform2dv -GLAD_API_CALL PFNGLREADBUFFERPROC glad_glReadBuffer; + GLAD_API_CALL PFNGLREADBUFFERPROC glad_glReadBuffer; #define glReadBuffer glad_glReadBuffer -GLAD_API_CALL PFNGLENDPROC glad_glEnd; + GLAD_API_CALL PFNGLENDPROC glad_glEnd; #define glEnd glad_glEnd -GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; + GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDPROC glad_glDrawArraysInstanced; #define glDrawArraysInstanced glad_glDrawArraysInstanced -GLAD_API_CALL PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv; + GLAD_API_CALL PFNGLVERTEXATTRIB4UIVPROC glad_glVertexAttrib4uiv; #define glVertexAttrib4uiv glad_glVertexAttrib4uiv -GLAD_API_CALL PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv; + GLAD_API_CALL PFNGLVERTEXATTRIBI4UBVPROC glad_glVertexAttribI4ubv; #define glVertexAttribI4ubv glad_glVertexAttribI4ubv -GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glad_glCompressedTextureSubImage1D; + GLAD_API_CALL PFNGLCOMPRESSEDTEXTURESUBIMAGE1DPROC glad_glCompressedTextureSubImage1D; #define glCompressedTextureSubImage1D glad_glCompressedTextureSubImage1D -GLAD_API_CALL PFNGLVERTEX2DVPROC glad_glVertex2dv; + GLAD_API_CALL PFNGLVERTEX2DVPROC glad_glVertex2dv; #define glVertex2dv glad_glVertex2dv -GLAD_API_CALL PFNGLPUSHNAMEPROC glad_glPushName; + GLAD_API_CALL PFNGLPUSHNAMEPROC glad_glPushName; #define glPushName glad_glPushName -GLAD_API_CALL PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData; + GLAD_API_CALL PFNGLINVALIDATEBUFFERDATAPROC glad_glInvalidateBufferData; #define glInvalidateBufferData glad_glInvalidateBufferData -GLAD_API_CALL PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; + GLAD_API_CALL PFNGLPOINTPARAMETERIVPROC glad_glPointParameteriv; #define glPointParameteriv glad_glPointParameteriv -GLAD_API_CALL PFNGLGENTEXTURESPROC glad_glGenTextures; + GLAD_API_CALL PFNGLGENTEXTURESPROC glad_glGenTextures; #define glGenTextures glad_glGenTextures -GLAD_API_CALL PFNGLTEXCOORD4FVPROC glad_glTexCoord4fv; + GLAD_API_CALL PFNGLTEXCOORD4FVPROC glad_glTexCoord4fv; #define glTexCoord4fv glad_glTexCoord4fv -GLAD_API_CALL PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute; + GLAD_API_CALL PFNGLDISPATCHCOMPUTEPROC glad_glDispatchCompute; #define glDispatchCompute glad_glDispatchCompute -GLAD_API_CALL PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; + GLAD_API_CALL PFNGLGETUNIFORMUIVPROC glad_glGetUniformuiv; #define glGetUniformuiv glad_glGetUniformuiv -GLAD_API_CALL PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; + GLAD_API_CALL PFNGLGETACTIVEUNIFORMSIVPROC glad_glGetActiveUniformsiv; #define glGetActiveUniformsiv glad_glGetActiveUniformsiv -GLAD_API_CALL PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName; + GLAD_API_CALL PFNGLGETPROGRAMRESOURCENAMEPROC glad_glGetProgramResourceName; #define glGetProgramResourceName glad_glGetProgramResourceName -GLAD_API_CALL PFNGLVERTEX2FVPROC glad_glVertex2fv; + GLAD_API_CALL PFNGLVERTEX2FVPROC glad_glVertex2fv; #define glVertex2fv glad_glVertex2fv -GLAD_API_CALL PFNGLCOLOR4UBPROC glad_glColor4ub; + GLAD_API_CALL PFNGLCOLOR4UBPROC glad_glColor4ub; #define glColor4ub glad_glColor4ub -GLAD_API_CALL PFNGLUNIFORM3IVPROC glad_glUniform3iv; + GLAD_API_CALL PFNGLUNIFORM3IVPROC glad_glUniform3iv; #define glUniform3iv glad_glUniform3iv -GLAD_API_CALL PFNGLCLIPPLANEPROC glad_glClipPlane; + GLAD_API_CALL PFNGLCLIPPLANEPROC glad_glClipPlane; #define glClipPlane glad_glClipPlane -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv; + GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X2FVPROC glad_glProgramUniformMatrix3x2fv; #define glProgramUniformMatrix3x2fv glad_glProgramUniformMatrix3x2fv -GLAD_API_CALL PFNGLUNIFORM4IPROC glad_glUniform4i; + GLAD_API_CALL PFNGLUNIFORM4IPROC glad_glUniform4i; #define glUniform4i glad_glUniform4i -GLAD_API_CALL PFNGLWINDOWPOS3IVPROC glad_glWindowPos3iv; + GLAD_API_CALL PFNGLWINDOWPOS3IVPROC glad_glWindowPos3iv; #define glWindowPos3iv glad_glWindowPos3iv -GLAD_API_CALL PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv; + GLAD_API_CALL PFNGLSAMPLERPARAMETERIVPROC glad_glSamplerParameteriv; #define glSamplerParameteriv glad_glSamplerParameteriv -GLAD_API_CALL PFNGLUNIFORM2DPROC glad_glUniform2d; + GLAD_API_CALL PFNGLUNIFORM2DPROC glad_glUniform2d; #define glUniform2d glad_glUniform2d -GLAD_API_CALL PFNGLPOPMATRIXPROC glad_glPopMatrix; + GLAD_API_CALL PFNGLPOPMATRIXPROC glad_glPopMatrix; #define glPopMatrix glad_glPopMatrix -GLAD_API_CALL PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline; + GLAD_API_CALL PFNGLVALIDATEPROGRAMPIPELINEPROC glad_glValidateProgramPipeline; #define glValidateProgramPipeline glad_glValidateProgramPipeline -GLAD_API_CALL PFNGLRASTERPOS3DVPROC glad_glRasterPos3dv; + GLAD_API_CALL PFNGLRASTERPOS3DVPROC glad_glRasterPos3dv; #define glRasterPos3dv glad_glRasterPos3dv -GLAD_API_CALL PFNGLTEXCOORD1FVPROC glad_glTexCoord1fv; + GLAD_API_CALL PFNGLTEXCOORD1FVPROC glad_glTexCoord1fv; #define glTexCoord1fv glad_glTexCoord1fv -GLAD_API_CALL PFNGLTEXCOORD2IVPROC glad_glTexCoord2iv; + GLAD_API_CALL PFNGLTEXCOORD2IVPROC glad_glTexCoord2iv; #define glTexCoord2iv glad_glTexCoord2iv -GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE2DPROC glad_glCopyTextureSubImage2D; + GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE2DPROC glad_glCopyTextureSubImage2D; #define glCopyTextureSubImage2D glad_glCopyTextureSubImage2D -GLAD_API_CALL PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; + GLAD_API_CALL PFNGLGETATTACHEDSHADERSPROC glad_glGetAttachedShaders; #define glGetAttachedShaders glad_glGetAttachedShaders -GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKI_VPROC glad_glGetTransformFeedbacki_v; + GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKI_VPROC glad_glGetTransformFeedbacki_v; #define glGetTransformFeedbacki_v glad_glGetTransformFeedbacki_v -GLAD_API_CALL PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; + GLAD_API_CALL PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetFramebufferAttachmentParameteriv; #define glGetFramebufferAttachmentParameteriv glad_glGetFramebufferAttachmentParameteriv -GLAD_API_CALL PFNGLVERTEXARRAYATTRIBIFORMATPROC glad_glVertexArrayAttribIFormat; + GLAD_API_CALL PFNGLVERTEXARRAYATTRIBIFORMATPROC glad_glVertexArrayAttribIFormat; #define glVertexArrayAttribIFormat glad_glVertexArrayAttribIFormat -GLAD_API_CALL PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel; + GLAD_API_CALL PFNGLOBJECTPTRLABELPROC glad_glObjectPtrLabel; #define glObjectPtrLabel glad_glObjectPtrLabel -GLAD_API_CALL PFNGLGETNPIXELMAPUSVPROC glad_glGetnPixelMapusv; + GLAD_API_CALL PFNGLGETNPIXELMAPUSVPROC glad_glGetnPixelMapusv; #define glGetnPixelMapusv glad_glGetnPixelMapusv -GLAD_API_CALL PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f; + GLAD_API_CALL PFNGLPROGRAMUNIFORM1FPROC glad_glProgramUniform1f; #define glProgramUniform1f glad_glProgramUniform1f -GLAD_API_CALL PFNGLCLEARSTENCILPROC glad_glClearStencil; + GLAD_API_CALL PFNGLCLEARSTENCILPROC glad_glClearStencil; #define glClearStencil glad_glClearStencil -GLAD_API_CALL PFNGLDISABLEPROC glad_glDisable; + GLAD_API_CALL PFNGLDISABLEPROC glad_glDisable; #define glDisable glad_glDisable -GLAD_API_CALL PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; + GLAD_API_CALL PFNGLVERTEXATTRIB4FPROC glad_glVertexAttrib4f; #define glVertexAttrib4f glad_glVertexAttrib4f -GLAD_API_CALL PFNGLGETSUBROUTINEINDEXPROC glad_glGetSubroutineIndex; + GLAD_API_CALL PFNGLGETSUBROUTINEINDEXPROC glad_glGetSubroutineIndex; #define glGetSubroutineIndex glad_glGetSubroutineIndex -GLAD_API_CALL PFNGLMULTITEXCOORD2DPROC glad_glMultiTexCoord2d; + GLAD_API_CALL PFNGLMULTITEXCOORD2DPROC glad_glMultiTexCoord2d; #define glMultiTexCoord2d glad_glMultiTexCoord2d -GLAD_API_CALL PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv; + GLAD_API_CALL PFNGLMULTITEXCOORDP3UIVPROC glad_glMultiTexCoordP3uiv; #define glMultiTexCoordP3uiv glad_glMultiTexCoordP3uiv -GLAD_API_CALL PFNGLMULTITEXCOORD3FVPROC glad_glMultiTexCoord3fv; + GLAD_API_CALL PFNGLMULTITEXCOORD3FVPROC glad_glMultiTexCoord3fv; #define glMultiTexCoord3fv glad_glMultiTexCoord3fv -GLAD_API_CALL PFNGLUNIFORM4IVPROC glad_glUniform4iv; + GLAD_API_CALL PFNGLUNIFORM4IVPROC glad_glUniform4iv; #define glUniform4iv glad_glUniform4iv -GLAD_API_CALL PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor; + GLAD_API_CALL PFNGLVERTEXATTRIBDIVISORPROC glad_glVertexAttribDivisor; #define glVertexAttribDivisor glad_glVertexAttribDivisor -GLAD_API_CALL PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation; + GLAD_API_CALL PFNGLBINDFRAGDATALOCATIONPROC glad_glBindFragDataLocation; #define glBindFragDataLocation glad_glBindFragDataLocation -GLAD_API_CALL PFNGLGETNCOMPRESSEDTEXIMAGEPROC glad_glGetnCompressedTexImage; + GLAD_API_CALL PFNGLGETNCOMPRESSEDTEXIMAGEPROC glad_glGetnCompressedTexImage; #define glGetnCompressedTexImage glad_glGetnCompressedTexImage -GLAD_API_CALL PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; + GLAD_API_CALL PFNGLUNIFORMMATRIX3FVPROC glad_glUniformMatrix3fv; #define glUniformMatrix3fv glad_glUniformMatrix3fv -GLAD_API_CALL PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; + GLAD_API_CALL PFNGLVERTEXATTRIB2FVPROC glad_glVertexAttrib2fv; #define glVertexAttrib2fv glad_glVertexAttrib2fv -GLAD_API_CALL PFNGLEVALCOORD2DPROC glad_glEvalCoord2d; + GLAD_API_CALL PFNGLEVALCOORD2DPROC glad_glEvalCoord2d; #define glEvalCoord2d glad_glEvalCoord2d -GLAD_API_CALL PFNGLGETPOINTERVPROC glad_glGetPointerv; + GLAD_API_CALL PFNGLGETPOINTERVPROC glad_glGetPointerv; #define glGetPointerv glad_glGetPointerv -GLAD_API_CALL PFNGLPROGRAMUNIFORM4DPROC glad_glProgramUniform4d; + GLAD_API_CALL PFNGLPROGRAMUNIFORM4DPROC glad_glProgramUniform4d; #define glProgramUniform4d glad_glProgramUniform4d -GLAD_API_CALL PFNGLTEXCOORD2FPROC glad_glTexCoord2f; + GLAD_API_CALL PFNGLTEXCOORD2FPROC glad_glTexCoord2f; #define glTexCoord2f glad_glTexCoord2f -GLAD_API_CALL PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; + GLAD_API_CALL PFNGLCOPYBUFFERSUBDATAPROC glad_glCopyBufferSubData; #define glCopyBufferSubData glad_glCopyBufferSubData -GLAD_API_CALL PFNGLUNIFORMMATRIX3DVPROC glad_glUniformMatrix3dv; + GLAD_API_CALL PFNGLUNIFORMMATRIX3DVPROC glad_glUniformMatrix3dv; #define glUniformMatrix3dv glad_glUniformMatrix3dv -GLAD_API_CALL PFNGLSECONDARYCOLOR3IVPROC glad_glSecondaryColor3iv; + GLAD_API_CALL PFNGLSECONDARYCOLOR3IVPROC glad_glSecondaryColor3iv; #define glSecondaryColor3iv glad_glSecondaryColor3iv -GLAD_API_CALL PFNGLFINISHPROC glad_glFinish; + GLAD_API_CALL PFNGLFINISHPROC glad_glFinish; #define glFinish glad_glFinish -GLAD_API_CALL PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline; + GLAD_API_CALL PFNGLISPROGRAMPIPELINEPROC glad_glIsProgramPipeline; #define glIsProgramPipeline glad_glIsProgramPipeline -GLAD_API_CALL PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv; + GLAD_API_CALL PFNGLVERTEXATTRIBP1UIVPROC glad_glVertexAttribP1uiv; #define glVertexAttribP1uiv glad_glVertexAttribP1uiv -GLAD_API_CALL PFNGLGETNMAPDVPROC glad_glGetnMapdv; + GLAD_API_CALL PFNGLGETNMAPDVPROC glad_glGetnMapdv; #define glGetnMapdv glad_glGetnMapdv -GLAD_API_CALL PFNGLBINDTEXTURESPROC glad_glBindTextures; + GLAD_API_CALL PFNGLBINDTEXTURESPROC glad_glBindTextures; #define glBindTextures glad_glBindTextures -GLAD_API_CALL PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui; + GLAD_API_CALL PFNGLMULTITEXCOORDP3UIPROC glad_glMultiTexCoordP3ui; #define glMultiTexCoordP3ui glad_glMultiTexCoordP3ui -GLAD_API_CALL PFNGLCOLORMASKIPROC glad_glColorMaski; + GLAD_API_CALL PFNGLCOLORMASKIPROC glad_glColorMaski; #define glColorMaski glad_glColorMaski -GLAD_API_CALL PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v; + GLAD_API_CALL PFNGLGETQUERYOBJECTI64VPROC glad_glGetQueryObjecti64v; #define glGetQueryObjecti64v glad_glGetQueryObjecti64v -GLAD_API_CALL PFNGLMULTITEXCOORD3SPROC glad_glMultiTexCoord3s; + GLAD_API_CALL PFNGLMULTITEXCOORD3SPROC glad_glMultiTexCoord3s; #define glMultiTexCoord3s glad_glMultiTexCoord3s -GLAD_API_CALL PFNGLWINDOWPOS2DPROC glad_glWindowPos2d; + GLAD_API_CALL PFNGLWINDOWPOS2DPROC glad_glWindowPos2d; #define glWindowPos2d glad_glWindowPos2d -GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance; + GLAD_API_CALL PFNGLDRAWARRAYSINSTANCEDBASEINSTANCEPROC glad_glDrawArraysInstancedBaseInstance; #define glDrawArraysInstancedBaseInstance glad_glDrawArraysInstancedBaseInstance -GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback; + GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKPROC glad_glDrawTransformFeedback; #define glDrawTransformFeedback glad_glDrawTransformFeedback -GLAD_API_CALL PFNGLWINDOWPOS2FPROC glad_glWindowPos2f; + GLAD_API_CALL PFNGLWINDOWPOS2FPROC glad_glWindowPos2f; #define glWindowPos2f glad_glWindowPos2f -GLAD_API_CALL PFNGLVERTEXATTRIBLPOINTERPROC glad_glVertexAttribLPointer; + GLAD_API_CALL PFNGLVERTEXATTRIBLPOINTERPROC glad_glVertexAttribLPointer; #define glVertexAttribLPointer glad_glVertexAttribLPointer -GLAD_API_CALL PFNGLTEXCOORD4FPROC glad_glTexCoord4f; + GLAD_API_CALL PFNGLTEXCOORD4FPROC glad_glTexCoord4f; #define glTexCoord4f glad_glTexCoord4f -GLAD_API_CALL PFNGLLIGHTMODELIVPROC glad_glLightModeliv; + GLAD_API_CALL PFNGLLIGHTMODELIVPROC glad_glLightModeliv; #define glLightModeliv glad_glLightModeliv -GLAD_API_CALL PFNGLUNIFORM2UIPROC glad_glUniform2ui; + GLAD_API_CALL PFNGLUNIFORM2UIPROC glad_glUniform2ui; #define glUniform2ui glad_glUniform2ui -GLAD_API_CALL PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; + GLAD_API_CALL PFNGLDELETEVERTEXARRAYSPROC glad_glDeleteVertexArrays; #define glDeleteVertexArrays glad_glDeleteVertexArrays -GLAD_API_CALL PFNGLTEXBUFFERPROC glad_glTexBuffer; + GLAD_API_CALL PFNGLTEXBUFFERPROC glad_glTexBuffer; #define glTexBuffer glad_glTexBuffer -GLAD_API_CALL PFNGLUNIFORM2FPROC glad_glUniform2f; + GLAD_API_CALL PFNGLUNIFORM2FPROC glad_glUniform2f; #define glUniform2f glad_glUniform2f -GLAD_API_CALL PFNGLTEXCOORD1DPROC glad_glTexCoord1d; + GLAD_API_CALL PFNGLTEXCOORD1DPROC glad_glTexCoord1d; #define glTexCoord1d glad_glTexCoord1d -GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; + GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE2DPROC glad_glCompressedTexImage2D; #define glCompressedTexImage2D glad_glCompressedTexImage2D -GLAD_API_CALL PFNGLGETGRAPHICSRESETSTATUSPROC glad_glGetGraphicsResetStatus; + GLAD_API_CALL PFNGLGETGRAPHICSRESETSTATUSPROC glad_glGetGraphicsResetStatus; #define glGetGraphicsResetStatus glad_glGetGraphicsResetStatus -GLAD_API_CALL PFNGLTEXCOORD1SPROC glad_glTexCoord1s; + GLAD_API_CALL PFNGLTEXCOORD1SPROC glad_glTexCoord1s; #define glTexCoord1s glad_glTexCoord1s -GLAD_API_CALL PFNGLINDEXSVPROC glad_glIndexsv; + GLAD_API_CALL PFNGLINDEXSVPROC glad_glIndexsv; #define glIndexsv glad_glIndexsv -GLAD_API_CALL PFNGLRASTERPOS4IVPROC glad_glRasterPos4iv; + GLAD_API_CALL PFNGLRASTERPOS4IVPROC glad_glRasterPos4iv; #define glRasterPos4iv glad_glRasterPos4iv -GLAD_API_CALL PFNGLSECONDARYCOLOR3IPROC glad_glSecondaryColor3i; + GLAD_API_CALL PFNGLSECONDARYCOLOR3IPROC glad_glSecondaryColor3i; #define glSecondaryColor3i glad_glSecondaryColor3i -GLAD_API_CALL PFNGLCALLLISTPROC glad_glCallList; + GLAD_API_CALL PFNGLCALLLISTPROC glad_glCallList; #define glCallList glad_glCallList -GLAD_API_CALL PFNGLINDEXUBVPROC glad_glIndexubv; + GLAD_API_CALL PFNGLINDEXUBVPROC glad_glIndexubv; #define glIndexubv glad_glIndexubv -GLAD_API_CALL PFNGLPOLYGONMODEPROC glad_glPolygonMode; + GLAD_API_CALL PFNGLPOLYGONMODEPROC glad_glPolygonMode; #define glPolygonMode glad_glPolygonMode -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; + GLAD_API_CALL PFNGLFRAMEBUFFERTEXTUREPROC glad_glFramebufferTexture; #define glFramebufferTexture glad_glFramebufferTexture -GLAD_API_CALL PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; + GLAD_API_CALL PFNGLUNIFORMMATRIX3X4FVPROC glad_glUniformMatrix3x4fv; #define glUniformMatrix3x4fv glad_glUniformMatrix3x4fv -GLAD_API_CALL PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback; + GLAD_API_CALL PFNGLISTRANSFORMFEEDBACKPROC glad_glIsTransformFeedback; #define glIsTransformFeedback glad_glIsTransformFeedback -GLAD_API_CALL PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData; + GLAD_API_CALL PFNGLNAMEDBUFFERSUBDATAPROC glad_glNamedBufferSubData; #define glNamedBufferSubData glad_glNamedBufferSubData -GLAD_API_CALL PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv; + GLAD_API_CALL PFNGLGETPROGRAMINTERFACEIVPROC glad_glGetProgramInterfaceiv; #define glGetProgramInterfaceiv glad_glGetProgramInterfaceiv -GLAD_API_CALL PFNGLDISABLECLIENTSTATEPROC glad_glDisableClientState; + GLAD_API_CALL PFNGLDISABLECLIENTSTATEPROC glad_glDisableClientState; #define glDisableClientState glad_glDisableClientState -GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glad_glClearNamedFramebufferuiv; + GLAD_API_CALL PFNGLCLEARNAMEDFRAMEBUFFERUIVPROC glad_glClearNamedFramebufferuiv; #define glClearNamedFramebufferuiv glad_glClearNamedFramebufferuiv -GLAD_API_CALL PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; + GLAD_API_CALL PFNGLGETTEXPARAMETERFVPROC glad_glGetTexParameterfv; #define glGetTexParameterfv glad_glGetTexParameterfv -GLAD_API_CALL PFNGLVERTEXARRAYATTRIBLFORMATPROC glad_glVertexArrayAttribLFormat; + GLAD_API_CALL PFNGLVERTEXARRAYATTRIBLFORMATPROC glad_glVertexArrayAttribLFormat; #define glVertexArrayAttribLFormat glad_glVertexArrayAttribLFormat -GLAD_API_CALL PFNGLVERTEX4DPROC glad_glVertex4d; + GLAD_API_CALL PFNGLVERTEX4DPROC glad_glVertex4d; #define glVertex4d glad_glVertex4d -GLAD_API_CALL PFNGLNORMAL3SVPROC glad_glNormal3sv; + GLAD_API_CALL PFNGLNORMAL3SVPROC glad_glNormal3sv; #define glNormal3sv glad_glNormal3sv -GLAD_API_CALL PFNGLRASTERPOS4FPROC glad_glRasterPos4f; + GLAD_API_CALL PFNGLRASTERPOS4FPROC glad_glRasterPos4f; #define glRasterPos4f glad_glRasterPos4f -GLAD_API_CALL PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui; + GLAD_API_CALL PFNGLTEXCOORDP4UIPROC glad_glTexCoordP4ui; #define glTexCoordP4ui glad_glTexCoordP4ui -GLAD_API_CALL PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; + GLAD_API_CALL PFNGLGENRENDERBUFFERSPROC glad_glGenRenderbuffers; #define glGenRenderbuffers glad_glGenRenderbuffers -GLAD_API_CALL PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; + GLAD_API_CALL PFNGLTRANSFORMFEEDBACKVARYINGSPROC glad_glTransformFeedbackVaryings; #define glTransformFeedbackVaryings glad_glTransformFeedbackVaryings -GLAD_API_CALL PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv; + GLAD_API_CALL PFNGLPROGRAMUNIFORM4FVPROC glad_glProgramUniform4fv; #define glProgramUniform4fv glad_glProgramUniform4fv -GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glad_glNamedFramebufferReadBuffer; + GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERREADBUFFERPROC glad_glNamedFramebufferReadBuffer; #define glNamedFramebufferReadBuffer glad_glNamedFramebufferReadBuffer -GLAD_API_CALL PFNGLUNIFORMMATRIX2X3DVPROC glad_glUniformMatrix2x3dv; + GLAD_API_CALL PFNGLUNIFORMMATRIX2X3DVPROC glad_glUniformMatrix2x3dv; #define glUniformMatrix2x3dv glad_glUniformMatrix2x3dv -GLAD_API_CALL PFNGLVERTEXATTRIBL3DVPROC glad_glVertexAttribL3dv; + GLAD_API_CALL PFNGLVERTEXATTRIBL3DVPROC glad_glVertexAttribL3dv; #define glVertexAttribL3dv glad_glVertexAttribL3dv -GLAD_API_CALL PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; + GLAD_API_CALL PFNGLUNIFORM1UIVPROC glad_glUniform1uiv; #define glUniform1uiv glad_glUniform1uiv -GLAD_API_CALL PFNGLTEXCOORD1SVPROC glad_glTexCoord1sv; + GLAD_API_CALL PFNGLTEXCOORD1SVPROC glad_glTexCoord1sv; #define glTexCoord1sv glad_glTexCoord1sv -GLAD_API_CALL PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; + GLAD_API_CALL PFNGLGETINTEGERI_VPROC glad_glGetIntegeri_v; #define glGetIntegeri_v glad_glGetIntegeri_v -GLAD_API_CALL PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D; + GLAD_API_CALL PFNGLTEXTURESUBIMAGE2DPROC glad_glTextureSubImage2D; #define glTextureSubImage2D glad_glTextureSubImage2D -GLAD_API_CALL PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage; + GLAD_API_CALL PFNGLNAMEDRENDERBUFFERSTORAGEPROC glad_glNamedRenderbufferStorage; #define glNamedRenderbufferStorage glad_glNamedRenderbufferStorage -GLAD_API_CALL PFNGLGETMAPIVPROC glad_glGetMapiv; + GLAD_API_CALL PFNGLGETMAPIVPROC glad_glGetMapiv; #define glGetMapiv glad_glGetMapiv -GLAD_API_CALL PFNGLMATRIXMODEPROC glad_glMatrixMode; + GLAD_API_CALL PFNGLMATRIXMODEPROC glad_glMatrixMode; #define glMatrixMode glad_glMatrixMode -GLAD_API_CALL PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; + GLAD_API_CALL PFNGLVERTEXATTRIBI4UIVPROC glad_glVertexAttribI4uiv; #define glVertexAttribI4uiv glad_glVertexAttribI4uiv -GLAD_API_CALL PFNGLVERTEXATTRIBL1DVPROC glad_glVertexAttribL1dv; + GLAD_API_CALL PFNGLVERTEXATTRIBL1DVPROC glad_glVertexAttribL1dv; #define glVertexAttribL1dv glad_glVertexAttribL1dv -GLAD_API_CALL PFNGLGETNAMEDBUFFERSUBDATAPROC glad_glGetNamedBufferSubData; + GLAD_API_CALL PFNGLGETNAMEDBUFFERSUBDATAPROC glad_glGetNamedBufferSubData; #define glGetNamedBufferSubData glad_glGetNamedBufferSubData -GLAD_API_CALL PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; + GLAD_API_CALL PFNGLGENVERTEXARRAYSPROC glad_glGenVertexArrays; #define glGenVertexArrays glad_glGenVertexArrays -GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIVPROC glad_glGetTextureParameteriv; + GLAD_API_CALL PFNGLGETTEXTUREPARAMETERIVPROC glad_glGetTextureParameteriv; #define glGetTextureParameteriv glad_glGetTextureParameteriv -GLAD_API_CALL PFNGLVERTEX3FVPROC glad_glVertex3fv; + GLAD_API_CALL PFNGLVERTEX3FVPROC glad_glVertex3fv; #define glVertex3fv glad_glVertex3fv -GLAD_API_CALL PFNGLMATERIALIVPROC glad_glMaterialiv; + GLAD_API_CALL PFNGLMATERIALIVPROC glad_glMaterialiv; #define glMaterialiv glad_glMaterialiv -GLAD_API_CALL PFNGLPIXELTRANSFERIPROC glad_glPixelTransferi; + GLAD_API_CALL PFNGLPIXELTRANSFERIPROC glad_glPixelTransferi; #define glPixelTransferi glad_glPixelTransferi -GLAD_API_CALL PFNGLGETNHISTOGRAMPROC glad_glGetnHistogram; + GLAD_API_CALL PFNGLGETNHISTOGRAMPROC glad_glGetnHistogram; #define glGetnHistogram glad_glGetnHistogram -GLAD_API_CALL PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv; + GLAD_API_CALL PFNGLCREATESHADERPROGRAMVPROC glad_glCreateShaderProgramv; #define glCreateShaderProgramv glad_glCreateShaderProgramv -GLAD_API_CALL PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib; + GLAD_API_CALL PFNGLENABLEVERTEXARRAYATTRIBPROC glad_glEnableVertexArrayAttrib; #define glEnableVertexArrayAttrib glad_glEnableVertexArrayAttrib -GLAD_API_CALL PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender; + GLAD_API_CALL PFNGLENDCONDITIONALRENDERPROC glad_glEndConditionalRender; #define glEndConditionalRender glad_glEndConditionalRender -GLAD_API_CALL PFNGLDELETELISTSPROC glad_glDeleteLists; + GLAD_API_CALL PFNGLDELETELISTSPROC glad_glDeleteLists; #define glDeleteLists glad_glDeleteLists -GLAD_API_CALL PFNGLTEXCOORD2SVPROC glad_glTexCoord2sv; + GLAD_API_CALL PFNGLTEXCOORD2SVPROC glad_glTexCoord2sv; #define glTexCoord2sv glad_glTexCoord2sv -GLAD_API_CALL PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback; + GLAD_API_CALL PFNGLDEBUGMESSAGECALLBACKPROC glad_glDebugMessageCallback; #define glDebugMessageCallback glad_glDebugMessageCallback -GLAD_API_CALL PFNGLMULTITEXCOORD1FPROC glad_glMultiTexCoord1f; + GLAD_API_CALL PFNGLMULTITEXCOORD1FPROC glad_glMultiTexCoord1f; #define glMultiTexCoord1f glad_glMultiTexCoord1f -GLAD_API_CALL PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; + GLAD_API_CALL PFNGLGETCOMPRESSEDTEXIMAGEPROC glad_glGetCompressedTexImage; #define glGetCompressedTexImage glad_glGetCompressedTexImage -GLAD_API_CALL PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; + GLAD_API_CALL PFNGLCHECKFRAMEBUFFERSTATUSPROC glad_glCheckFramebufferStatus; #define glCheckFramebufferStatus glad_glCheckFramebufferStatus -GLAD_API_CALL PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v; + GLAD_API_CALL PFNGLGETINTERNALFORMATI64VPROC glad_glGetInternalformati64v; #define glGetInternalformati64v glad_glGetInternalformati64v -GLAD_API_CALL PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; + GLAD_API_CALL PFNGLGENERATEMIPMAPPROC glad_glGenerateMipmap; #define glGenerateMipmap glad_glGenerateMipmap -GLAD_API_CALL PFNGLDELETEQUERIESPROC glad_glDeleteQueries; + GLAD_API_CALL PFNGLDELETEQUERIESPROC glad_glDeleteQueries; #define glDeleteQueries glad_glDeleteQueries -GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glad_glNamedFramebufferParameteri; + GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERPARAMETERIPROC glad_glNamedFramebufferParameteri; #define glNamedFramebufferParameteri glad_glNamedFramebufferParameteri -GLAD_API_CALL PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex; + GLAD_API_CALL PFNGLDRAWELEMENTSBASEVERTEXPROC glad_glDrawElementsBaseVertex; #define glDrawElementsBaseVertex glad_glDrawElementsBaseVertex -GLAD_API_CALL PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d; + GLAD_API_CALL PFNGLPROGRAMUNIFORM1DPROC glad_glProgramUniform1d; #define glProgramUniform1d glad_glProgramUniform1d -GLAD_API_CALL PFNGLALPHAFUNCPROC glad_glAlphaFunc; + GLAD_API_CALL PFNGLALPHAFUNCPROC glad_glAlphaFunc; #define glAlphaFunc glad_glAlphaFunc -GLAD_API_CALL PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange; + GLAD_API_CALL PFNGLTRANSFORMFEEDBACKBUFFERRANGEPROC glad_glTransformFeedbackBufferRange; #define glTransformFeedbackBufferRange glad_glTransformFeedbackBufferRange -GLAD_API_CALL PFNGLLINESTIPPLEPROC glad_glLineStipple; + GLAD_API_CALL PFNGLLINESTIPPLEPROC glad_glLineStipple; #define glLineStipple glad_glLineStipple -GLAD_API_CALL PFNGLTEXGENIPROC glad_glTexGeni; + GLAD_API_CALL PFNGLTEXGENIPROC glad_glTexGeni; #define glTexGeni glad_glTexGeni -GLAD_API_CALL PFNGLTEXSTORAGE3DMULTISAMPLEPROC glad_glTexStorage3DMultisample; + GLAD_API_CALL PFNGLTEXSTORAGE3DMULTISAMPLEPROC glad_glTexStorage3DMultisample; #define glTexStorage3DMultisample glad_glTexStorage3DMultisample -GLAD_API_CALL PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; + GLAD_API_CALL PFNGLISVERTEXARRAYPROC glad_glIsVertexArray; #define glIsVertexArray glad_glIsVertexArray -GLAD_API_CALL PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv; + GLAD_API_CALL PFNGLGETNAMEDRENDERBUFFERPARAMETERIVPROC glad_glGetNamedRenderbufferParameteriv; #define glGetNamedRenderbufferParameteriv glad_glGetNamedRenderbufferParameteriv -GLAD_API_CALL PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer; + GLAD_API_CALL PFNGLINVALIDATEFRAMEBUFFERPROC glad_glInvalidateFramebuffer; #define glInvalidateFramebuffer glad_glInvalidateFramebuffer -GLAD_API_CALL PFNGLPROGRAMBINARYPROC glad_glProgramBinary; + GLAD_API_CALL PFNGLPROGRAMBINARYPROC glad_glProgramBinary; #define glProgramBinary glad_glProgramBinary -GLAD_API_CALL PFNGLTEXCOORD4DVPROC glad_glTexCoord4dv; + GLAD_API_CALL PFNGLTEXCOORD4DVPROC glad_glTexCoord4dv; #define glTexCoord4dv glad_glTexCoord4dv -GLAD_API_CALL PFNGLVERTEX3IPROC glad_glVertex3i; + GLAD_API_CALL PFNGLVERTEX3IPROC glad_glVertex3i; #define glVertex3i glad_glVertex3i -GLAD_API_CALL PFNGLSECONDARYCOLOR3BPROC glad_glSecondaryColor3b; + GLAD_API_CALL PFNGLSECONDARYCOLOR3BPROC glad_glSecondaryColor3b; #define glSecondaryColor3b glad_glSecondaryColor3b -GLAD_API_CALL PFNGLRASTERPOS4SVPROC glad_glRasterPos4sv; + GLAD_API_CALL PFNGLRASTERPOS4SVPROC glad_glRasterPos4sv; #define glRasterPos4sv glad_glRasterPos4sv -GLAD_API_CALL PFNGLDISABLEIPROC glad_glDisablei; + GLAD_API_CALL PFNGLDISABLEIPROC glad_glDisablei; #define glDisablei glad_glDisablei -GLAD_API_CALL PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv; + GLAD_API_CALL PFNGLVERTEXATTRIB1SVPROC glad_glVertexAttrib1sv; #define glVertexAttrib1sv glad_glVertexAttrib1sv -GLAD_API_CALL PFNGLINVALIDATETEXIMAGEPROC glad_glInvalidateTexImage; + GLAD_API_CALL PFNGLINVALIDATETEXIMAGEPROC glad_glInvalidateTexImage; #define glInvalidateTexImage glad_glInvalidateTexImage -GLAD_API_CALL PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i; + GLAD_API_CALL PFNGLVERTEXATTRIBI2IPROC glad_glVertexAttribI2i; #define glVertexAttribI2i glad_glVertexAttribI2i -GLAD_API_CALL PFNGLINDEXFPROC glad_glIndexf; + GLAD_API_CALL PFNGLINDEXFPROC glad_glIndexf; #define glIndexf glad_glIndexf -GLAD_API_CALL PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; + GLAD_API_CALL PFNGLPRIMITIVERESTARTINDEXPROC glad_glPrimitiveRestartIndex; #define glPrimitiveRestartIndex glad_glPrimitiveRestartIndex -GLAD_API_CALL PFNGLGETNCONVOLUTIONFILTERPROC glad_glGetnConvolutionFilter; + GLAD_API_CALL PFNGLGETNCONVOLUTIONFILTERPROC glad_glGetnConvolutionFilter; #define glGetnConvolutionFilter glad_glGetnConvolutionFilter -GLAD_API_CALL PFNGLGETERRORPROC glad_glGetError; + GLAD_API_CALL PFNGLGETERRORPROC glad_glGetError; #define glGetError glad_glGetError -GLAD_API_CALL PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv; + GLAD_API_CALL PFNGLVERTEXATTRIB4BVPROC glad_glVertexAttrib4bv; #define glVertexAttrib4bv glad_glVertexAttrib4bv -GLAD_API_CALL PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; + GLAD_API_CALL PFNGLFLUSHMAPPEDBUFFERRANGEPROC glad_glFlushMappedBufferRange; #define glFlushMappedBufferRange glad_glFlushMappedBufferRange -GLAD_API_CALL PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui; + GLAD_API_CALL PFNGLTEXCOORDP1UIPROC glad_glTexCoordP1ui; #define glTexCoordP1ui glad_glTexCoordP1ui -GLAD_API_CALL PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; + GLAD_API_CALL PFNGLSAMPLECOVERAGEPROC glad_glSampleCoverage; #define glSampleCoverage glad_glSampleCoverage -GLAD_API_CALL PFNGLMULTITEXCOORD2IVPROC glad_glMultiTexCoord2iv; + GLAD_API_CALL PFNGLMULTITEXCOORD2IVPROC glad_glMultiTexCoord2iv; #define glMultiTexCoord2iv glad_glMultiTexCoord2iv -GLAD_API_CALL PFNGLISPROGRAMPROC glad_glIsProgram; + GLAD_API_CALL PFNGLISPROGRAMPROC glad_glIsProgram; #define glIsProgram glad_glIsProgram -GLAD_API_CALL PFNGLISLISTPROC glad_glIsList; + GLAD_API_CALL PFNGLISLISTPROC glad_glIsList; #define glIsList glad_glIsList -GLAD_API_CALL PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv; + GLAD_API_CALL PFNGLVERTEXATTRIB2DVPROC glad_glVertexAttrib2dv; #define glVertexAttrib2dv glad_glVertexAttrib2dv -GLAD_API_CALL PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; + GLAD_API_CALL PFNGLVERTEXATTRIB3FPROC glad_glVertexAttrib3f; #define glVertexAttrib3f glad_glVertexAttrib3f -GLAD_API_CALL PFNGLTEXPARAMETERIPROC glad_glTexParameteri; + GLAD_API_CALL PFNGLTEXPARAMETERIPROC glad_glTexParameteri; #define glTexParameteri glad_glTexParameteri -GLAD_API_CALL PFNGLPUSHATTRIBPROC glad_glPushAttrib; + GLAD_API_CALL PFNGLPUSHATTRIBPROC glad_glPushAttrib; #define glPushAttrib glad_glPushAttrib -GLAD_API_CALL PFNGLFRONTFACEPROC glad_glFrontFace; + GLAD_API_CALL PFNGLFRONTFACEPROC glad_glFrontFace; #define glFrontFace glad_glFrontFace -GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance; + GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEINSTANCEPROC glad_glDrawElementsInstancedBaseInstance; #define glDrawElementsInstancedBaseInstance glad_glDrawElementsInstancedBaseInstance -GLAD_API_CALL PFNGLMULTITEXCOORD1SPROC glad_glMultiTexCoord1s; + GLAD_API_CALL PFNGLMULTITEXCOORD1SPROC glad_glMultiTexCoord1s; #define glMultiTexCoord1s glad_glMultiTexCoord1s -GLAD_API_CALL PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i; + GLAD_API_CALL PFNGLVERTEXATTRIBI3IPROC glad_glVertexAttribI3i; #define glVertexAttribI3i glad_glVertexAttribI3i -GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D; + GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE1DPROC glad_glCopyTexSubImage1D; #define glCopyTexSubImage1D glad_glCopyTexSubImage1D -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D; + GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE3DPROC glad_glFramebufferTexture3D; #define glFramebufferTexture3D glad_glFramebufferTexture3D -GLAD_API_CALL PFNGLGENSAMPLERSPROC glad_glGenSamplers; + GLAD_API_CALL PFNGLGENSAMPLERSPROC glad_glGenSamplers; #define glGenSamplers glad_glGenSamplers -GLAD_API_CALL PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf; + GLAD_API_CALL PFNGLSAMPLERPARAMETERFPROC glad_glSamplerParameterf; #define glSamplerParameterf glad_glSamplerParameterf -GLAD_API_CALL PFNGLRASTERPOS4FVPROC glad_glRasterPos4fv; + GLAD_API_CALL PFNGLRASTERPOS4FVPROC glad_glRasterPos4fv; #define glRasterPos4fv glad_glRasterPos4fv -GLAD_API_CALL PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback; + GLAD_API_CALL PFNGLPAUSETRANSFORMFEEDBACKPROC glad_glPauseTransformFeedback; #define glPauseTransformFeedback glad_glPauseTransformFeedback -GLAD_API_CALL PFNGLPOPNAMEPROC glad_glPopName; + GLAD_API_CALL PFNGLPOPNAMEPROC glad_glPopName; #define glPopName glad_glPopName -GLAD_API_CALL PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv; + GLAD_API_CALL PFNGLVERTEXATTRIBI1IVPROC glad_glVertexAttribI1iv; #define glVertexAttribI1iv glad_glVertexAttribI1iv -GLAD_API_CALL PFNGLEVALCOORD1FPROC glad_glEvalCoord1f; + GLAD_API_CALL PFNGLEVALCOORD1FPROC glad_glEvalCoord1f; #define glEvalCoord1f glad_glEvalCoord1f -GLAD_API_CALL PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; + GLAD_API_CALL PFNGLGENFRAMEBUFFERSPROC glad_glGenFramebuffers; #define glGenFramebuffers glad_glGenFramebuffers -GLAD_API_CALL PFNGLLIGHTIPROC glad_glLighti; + GLAD_API_CALL PFNGLLIGHTIPROC glad_glLighti; #define glLighti glad_glLighti -GLAD_API_CALL PFNGLTEXTUREVIEWPROC glad_glTextureView; + GLAD_API_CALL PFNGLTEXTUREVIEWPROC glad_glTextureView; #define glTextureView glad_glTextureView -GLAD_API_CALL PFNGLLOADTRANSPOSEMATRIXDPROC glad_glLoadTransposeMatrixd; + GLAD_API_CALL PFNGLLOADTRANSPOSEMATRIXDPROC glad_glLoadTransposeMatrixd; #define glLoadTransposeMatrixd glad_glLoadTransposeMatrixd -GLAD_API_CALL PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetNamedFramebufferAttachmentParameteriv; + GLAD_API_CALL PFNGLGETNAMEDFRAMEBUFFERATTACHMENTPARAMETERIVPROC glad_glGetNamedFramebufferAttachmentParameteriv; #define glGetNamedFramebufferAttachmentParameteriv glad_glGetNamedFramebufferAttachmentParameteriv -GLAD_API_CALL PFNGLUNIFORM4DPROC glad_glUniform4d; + GLAD_API_CALL PFNGLUNIFORM4DPROC glad_glUniform4d; #define glUniform4d glad_glUniform4d -GLAD_API_CALL PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui; + GLAD_API_CALL PFNGLVERTEXATTRIBI3UIPROC glad_glVertexAttribI3ui; #define glVertexAttribI3ui glad_glVertexAttribI3ui -GLAD_API_CALL PFNGLEDGEFLAGPOINTERPROC glad_glEdgeFlagPointer; + GLAD_API_CALL PFNGLEDGEFLAGPOINTERPROC glad_glEdgeFlagPointer; #define glEdgeFlagPointer glad_glEdgeFlagPointer -GLAD_API_CALL PFNGLSTENCILFUNCPROC glad_glStencilFunc; + GLAD_API_CALL PFNGLSTENCILFUNCPROC glad_glStencilFunc; #define glStencilFunc glad_glStencilFunc -GLAD_API_CALL PFNGLUNIFORM1IPROC glad_glUniform1i; + GLAD_API_CALL PFNGLUNIFORM1IPROC glad_glUniform1i; #define glUniform1i glad_glUniform1i -GLAD_API_CALL PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv; + GLAD_API_CALL PFNGLGETTEXPARAMETERIUIVPROC glad_glGetTexParameterIuiv; #define glGetTexParameterIuiv glad_glGetTexParameterIuiv -GLAD_API_CALL PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glad_glInvalidateNamedFramebufferData; + GLAD_API_CALL PFNGLINVALIDATENAMEDFRAMEBUFFERDATAPROC glad_glInvalidateNamedFramebufferData; #define glInvalidateNamedFramebufferData glad_glInvalidateNamedFramebufferData -GLAD_API_CALL PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv; + GLAD_API_CALL PFNGLPATCHPARAMETERFVPROC glad_glPatchParameterfv; #define glPatchParameterfv glad_glPatchParameterfv -GLAD_API_CALL PFNGLFOGFVPROC glad_glFogfv; + GLAD_API_CALL PFNGLFOGFVPROC glad_glFogfv; #define glFogfv glad_glFogfv -GLAD_API_CALL PFNGLVERTEXP3UIPROC glad_glVertexP3ui; + GLAD_API_CALL PFNGLVERTEXP3UIPROC glad_glVertexP3ui; #define glVertexP3ui glad_glVertexP3ui -GLAD_API_CALL PFNGLREADNPIXELSPROC glad_glReadnPixels; + GLAD_API_CALL PFNGLREADNPIXELSPROC glad_glReadnPixels; #define glReadnPixels glad_glReadnPixels -GLAD_API_CALL PFNGLMULTITEXCOORD1IPROC glad_glMultiTexCoord1i; + GLAD_API_CALL PFNGLMULTITEXCOORD1IPROC glad_glMultiTexCoord1i; #define glMultiTexCoord1i glad_glMultiTexCoord1i -GLAD_API_CALL PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding; + GLAD_API_CALL PFNGLVERTEXATTRIBBINDINGPROC glad_glVertexAttribBinding; #define glVertexAttribBinding glad_glVertexAttribBinding -GLAD_API_CALL PFNGLMULTITEXCOORD3DVPROC glad_glMultiTexCoord3dv; + GLAD_API_CALL PFNGLMULTITEXCOORD3DVPROC glad_glMultiTexCoord3dv; #define glMultiTexCoord3dv glad_glMultiTexCoord3dv -GLAD_API_CALL PFNGLVERTEX4SPROC glad_glVertex4s; + GLAD_API_CALL PFNGLVERTEX4SPROC glad_glVertex4s; #define glVertex4s glad_glVertex4s -GLAD_API_CALL PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor; + GLAD_API_CALL PFNGLVERTEXBINDINGDIVISORPROC glad_glVertexBindingDivisor; #define glVertexBindingDivisor glad_glVertexBindingDivisor -GLAD_API_CALL PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv; + GLAD_API_CALL PFNGLTEXTUREPARAMETERFVPROC glad_glTextureParameterfv; #define glTextureParameterfv glad_glTextureParameterfv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv; + GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X4FVPROC glad_glProgramUniformMatrix3x4fv; #define glProgramUniformMatrix3x4fv glad_glProgramUniformMatrix3x4fv -GLAD_API_CALL PFNGLNORMAL3BPROC glad_glNormal3b; + GLAD_API_CALL PFNGLNORMAL3BPROC glad_glNormal3b; #define glNormal3b glad_glNormal3b -GLAD_API_CALL PFNGLGETUNIFORMSUBROUTINEUIVPROC glad_glGetUniformSubroutineuiv; + GLAD_API_CALL PFNGLGETUNIFORMSUBROUTINEUIVPROC glad_glGetUniformSubroutineuiv; #define glGetUniformSubroutineuiv glad_glGetUniformSubroutineuiv -GLAD_API_CALL PFNGLVERTEX3SVPROC glad_glVertex3sv; + GLAD_API_CALL PFNGLVERTEX3SVPROC glad_glVertex3sv; #define glVertex3sv glad_glVertex3sv -GLAD_API_CALL PFNGLMULTITEXCOORD3SVPROC glad_glMultiTexCoord3sv; + GLAD_API_CALL PFNGLMULTITEXCOORD3SVPROC glad_glMultiTexCoord3sv; #define glMultiTexCoord3sv glad_glMultiTexCoord3sv -GLAD_API_CALL PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v; + GLAD_API_CALL PFNGLGETNAMEDBUFFERPARAMETERI64VPROC glad_glGetNamedBufferParameteri64v; #define glGetNamedBufferParameteri64v glad_glGetNamedBufferParameteri64v -GLAD_API_CALL PFNGLDRAWPIXELSPROC glad_glDrawPixels; + GLAD_API_CALL PFNGLDRAWPIXELSPROC glad_glDrawPixels; #define glDrawPixels glad_glDrawPixels -GLAD_API_CALL PFNGLCALLLISTSPROC glad_glCallLists; + GLAD_API_CALL PFNGLCALLLISTSPROC glad_glCallLists; #define glCallLists glad_glCallLists -GLAD_API_CALL PFNGLTEXCOORD3IPROC glad_glTexCoord3i; + GLAD_API_CALL PFNGLTEXCOORD3IPROC glad_glTexCoord3i; #define glTexCoord3i glad_glTexCoord3i -GLAD_API_CALL PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui; + GLAD_API_CALL PFNGLPROGRAMUNIFORM2UIPROC glad_glProgramUniform2ui; #define glProgramUniform2ui glad_glProgramUniform2ui -GLAD_API_CALL PFNGLQUERYCOUNTERPROC glad_glQueryCounter; + GLAD_API_CALL PFNGLQUERYCOUNTERPROC glad_glQueryCounter; #define glQueryCounter glad_glQueryCounter -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glad_glProgramUniformMatrix2x3dv; + GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X3DVPROC glad_glProgramUniformMatrix2x3dv; #define glProgramUniformMatrix2x3dv glad_glProgramUniformMatrix2x3dv -GLAD_API_CALL PFNGLUNIFORM1IVPROC glad_glUniform1iv; + GLAD_API_CALL PFNGLUNIFORM1IVPROC glad_glUniform1iv; #define glUniform1iv glad_glUniform1iv -GLAD_API_CALL PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; + GLAD_API_CALL PFNGLSTENCILFUNCSEPARATEPROC glad_glStencilFuncSeparate; #define glStencilFuncSeparate glad_glStencilFuncSeparate -GLAD_API_CALL PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv; + GLAD_API_CALL PFNGLGETNAMEDBUFFERPARAMETERIVPROC glad_glGetNamedBufferParameteriv; #define glGetNamedBufferParameteriv glad_glGetNamedBufferParameteriv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2DVPROC glad_glProgramUniformMatrix2dv; + GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2DVPROC glad_glProgramUniformMatrix2dv; #define glProgramUniformMatrix2dv glad_glProgramUniformMatrix2dv -GLAD_API_CALL PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; + GLAD_API_CALL PFNGLGETACTIVEATTRIBPROC glad_glGetActiveAttrib; #define glGetActiveAttrib glad_glGetActiveAttrib -GLAD_API_CALL PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; + GLAD_API_CALL PFNGLENABLEVERTEXATTRIBARRAYPROC glad_glEnableVertexAttribArray; #define glEnableVertexAttribArray glad_glEnableVertexAttribArray -GLAD_API_CALL PFNGLMATERIALIPROC glad_glMateriali; + GLAD_API_CALL PFNGLMATERIALIPROC glad_glMateriali; #define glMateriali glad_glMateriali -GLAD_API_CALL PFNGLUNIFORM2FVPROC glad_glUniform2fv; + GLAD_API_CALL PFNGLUNIFORM2FVPROC glad_glUniform2fv; #define glUniform2fv glad_glUniform2fv -GLAD_API_CALL PFNGLRASTERPOS3FVPROC glad_glRasterPos3fv; + GLAD_API_CALL PFNGLRASTERPOS3FVPROC glad_glRasterPos3fv; #define glRasterPos3fv glad_glRasterPos3fv -GLAD_API_CALL PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glad_glGetProgramResourceLocationIndex; + GLAD_API_CALL PFNGLGETPROGRAMRESOURCELOCATIONINDEXPROC glad_glGetProgramResourceLocationIndex; #define glGetProgramResourceLocationIndex glad_glGetProgramResourceLocationIndex -GLAD_API_CALL PFNGLGETDOUBLEVPROC glad_glGetDoublev; + GLAD_API_CALL PFNGLGETDOUBLEVPROC glad_glGetDoublev; #define glGetDoublev glad_glGetDoublev -GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex; + GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDBASEVERTEXPROC glad_glDrawElementsInstancedBaseVertex; #define glDrawElementsInstancedBaseVertex glad_glDrawElementsInstancedBaseVertex -GLAD_API_CALL PFNGLUNIFORMMATRIX2X4DVPROC glad_glUniformMatrix2x4dv; + GLAD_API_CALL PFNGLUNIFORMMATRIX2X4DVPROC glad_glUniformMatrix2x4dv; #define glUniformMatrix2x4dv glad_glUniformMatrix2x4dv -GLAD_API_CALL PFNGLCOLOR4BVPROC glad_glColor4bv; + GLAD_API_CALL PFNGLCOLOR4BVPROC glad_glColor4bv; #define glColor4bv glad_glColor4bv -GLAD_API_CALL PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ; + GLAD_API_CALL PFNGLGETINTERNALFORMATIVPROC glad_glGetInternalformativ; #define glGetInternalformativ glad_glGetInternalformativ -GLAD_API_CALL PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glad_glGetActiveSubroutineUniformiv; + GLAD_API_CALL PFNGLGETACTIVESUBROUTINEUNIFORMIVPROC glad_glGetActiveSubroutineUniformiv; #define glGetActiveSubroutineUniformiv glad_glGetActiveSubroutineUniformiv -GLAD_API_CALL PFNGLGETQUERYINDEXEDIVPROC glad_glGetQueryIndexediv; + GLAD_API_CALL PFNGLGETQUERYINDEXEDIVPROC glad_glGetQueryIndexediv; #define glGetQueryIndexediv glad_glGetQueryIndexediv -GLAD_API_CALL PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer; + GLAD_API_CALL PFNGLBINDVERTEXBUFFERPROC glad_glBindVertexBuffer; #define glBindVertexBuffer glad_glBindVertexBuffer -GLAD_API_CALL PFNGLTEXCOORD3FPROC glad_glTexCoord3f; + GLAD_API_CALL PFNGLTEXCOORD3FPROC glad_glTexCoord3f; #define glTexCoord3f glad_glTexCoord3f -GLAD_API_CALL PFNGLCOLOR3UIVPROC glad_glColor3uiv; + GLAD_API_CALL PFNGLCOLOR3UIVPROC glad_glColor3uiv; #define glColor3uiv glad_glColor3uiv -GLAD_API_CALL PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv; + GLAD_API_CALL PFNGLVERTEXATTRIB4NBVPROC glad_glVertexAttrib4Nbv; #define glVertexAttrib4Nbv glad_glVertexAttrib4Nbv -GLAD_API_CALL PFNGLCLEARPROC glad_glClear; + GLAD_API_CALL PFNGLCLEARPROC glad_glClear; #define glClear glad_glClear -GLAD_API_CALL PFNGLRASTERPOS2DVPROC glad_glRasterPos2dv; + GLAD_API_CALL PFNGLRASTERPOS2DVPROC glad_glRasterPos2dv; #define glRasterPos2dv glad_glRasterPos2dv -GLAD_API_CALL PFNGLTEXCOORD2SPROC glad_glTexCoord2s; + GLAD_API_CALL PFNGLTEXCOORD2SPROC glad_glTexCoord2s; #define glTexCoord2s glad_glTexCoord2s -GLAD_API_CALL PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui; + GLAD_API_CALL PFNGLVERTEXATTRIBP4UIPROC glad_glVertexAttribP4ui; #define glVertexAttribP4ui glad_glVertexAttribP4ui -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; + GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURELAYERPROC glad_glFramebufferTextureLayer; #define glFramebufferTextureLayer glad_glFramebufferTextureLayer -GLAD_API_CALL PFNGLTEXENVIPROC glad_glTexEnvi; + GLAD_API_CALL PFNGLTEXENVIPROC glad_glTexEnvi; #define glTexEnvi glad_glTexEnvi -GLAD_API_CALL PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf; + GLAD_API_CALL PFNGLTEXTUREPARAMETERFPROC glad_glTextureParameterf; #define glTextureParameterf glad_glTextureParameterf -GLAD_API_CALL PFNGLMATERIALFPROC glad_glMaterialf; + GLAD_API_CALL PFNGLMATERIALFPROC glad_glMaterialf; #define glMaterialf glad_glMaterialf -GLAD_API_CALL PFNGLGETUNIFORMDVPROC glad_glGetUniformdv; + GLAD_API_CALL PFNGLGETUNIFORMDVPROC glad_glGetUniformdv; #define glGetUniformdv glad_glGetUniformdv -GLAD_API_CALL PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv; + GLAD_API_CALL PFNGLPROGRAMUNIFORM3IVPROC glad_glProgramUniform3iv; #define glProgramUniform3iv glad_glProgramUniform3iv -GLAD_API_CALL PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv; + GLAD_API_CALL PFNGLTEXPARAMETERIUIVPROC glad_glTexParameterIuiv; #define glTexParameterIuiv glad_glTexParameterIuiv -GLAD_API_CALL PFNGLCLEARINDEXPROC glad_glClearIndex; + GLAD_API_CALL PFNGLCLEARINDEXPROC glad_glClearIndex; #define glClearIndex glad_glClearIndex -GLAD_API_CALL PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect; + GLAD_API_CALL PFNGLDISPATCHCOMPUTEINDIRECTPROC glad_glDispatchComputeIndirect; #define glDispatchComputeIndirect glad_glDispatchComputeIndirect -GLAD_API_CALL PFNGLROTATEFPROC glad_glRotatef; + GLAD_API_CALL PFNGLROTATEFPROC glad_glRotatef; #define glRotatef glad_glRotatef -GLAD_API_CALL PFNGLTEXTURESUBIMAGE1DPROC glad_glTextureSubImage1D; + GLAD_API_CALL PFNGLTEXTURESUBIMAGE1DPROC glad_glTextureSubImage1D; #define glTextureSubImage1D glad_glTextureSubImage1D -GLAD_API_CALL PFNGLPOLYGONOFFSETCLAMPPROC glad_glPolygonOffsetClamp; + GLAD_API_CALL PFNGLPOLYGONOFFSETCLAMPPROC glad_glPolygonOffsetClamp; #define glPolygonOffsetClamp glad_glPolygonOffsetClamp -GLAD_API_CALL PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv; + GLAD_API_CALL PFNGLSAMPLERPARAMETERIUIVPROC glad_glSamplerParameterIuiv; #define glSamplerParameterIuiv glad_glSamplerParameterIuiv -GLAD_API_CALL PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv; + GLAD_API_CALL PFNGLPROGRAMUNIFORM4IVPROC glad_glProgramUniform4iv; #define glProgramUniform4iv glad_glProgramUniform4iv -GLAD_API_CALL PFNGLSECONDARYCOLOR3SPROC glad_glSecondaryColor3s; + GLAD_API_CALL PFNGLSECONDARYCOLOR3SPROC glad_glSecondaryColor3s; #define glSecondaryColor3s glad_glSecondaryColor3s -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glad_glProgramUniformMatrix2x4dv; + GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX2X4DVPROC glad_glProgramUniformMatrix2x4dv; #define glProgramUniformMatrix2x4dv glad_glProgramUniformMatrix2x4dv -GLAD_API_CALL PFNGLGETVERTEXATTRIBLDVPROC glad_glGetVertexAttribLdv; + GLAD_API_CALL PFNGLGETVERTEXATTRIBLDVPROC glad_glGetVertexAttribLdv; #define glGetVertexAttribLdv glad_glGetVertexAttribLdv -GLAD_API_CALL PFNGLRASTERPOS2FVPROC glad_glRasterPos2fv; + GLAD_API_CALL PFNGLRASTERPOS2FVPROC glad_glRasterPos2fv; #define glRasterPos2fv glad_glRasterPos2fv -GLAD_API_CALL PFNGLSHADEMODELPROC glad_glShadeModel; + GLAD_API_CALL PFNGLSHADEMODELPROC glad_glShadeModel; #define glShadeModel glad_glShadeModel -GLAD_API_CALL PFNGLPROGRAMUNIFORM4DVPROC glad_glProgramUniform4dv; + GLAD_API_CALL PFNGLPROGRAMUNIFORM4DVPROC glad_glProgramUniform4dv; #define glProgramUniform4dv glad_glProgramUniform4dv -GLAD_API_CALL PFNGLNORMAL3FVPROC glad_glNormal3fv; + GLAD_API_CALL PFNGLNORMAL3FVPROC glad_glNormal3fv; #define glNormal3fv glad_glNormal3fv -GLAD_API_CALL PFNGLISBUFFERPROC glad_glIsBuffer; + GLAD_API_CALL PFNGLISBUFFERPROC glad_glIsBuffer; #define glIsBuffer glad_glIsBuffer -GLAD_API_CALL PFNGLMULTITEXCOORD3FPROC glad_glMultiTexCoord3f; + GLAD_API_CALL PFNGLMULTITEXCOORD3FPROC glad_glMultiTexCoord3f; #define glMultiTexCoord3f glad_glMultiTexCoord3f -GLAD_API_CALL PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; + GLAD_API_CALL PFNGLBINDFRAMEBUFFERPROC glad_glBindFramebuffer; #define glBindFramebuffer glad_glBindFramebuffer -GLAD_API_CALL PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed; + GLAD_API_CALL PFNGLBINDFRAGDATALOCATIONINDEXEDPROC glad_glBindFragDataLocationIndexed; #define glBindFragDataLocationIndexed glad_glBindFragDataLocationIndexed -GLAD_API_CALL PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; + GLAD_API_CALL PFNGLBINDBUFFERBASEPROC glad_glBindBufferBase; #define glBindBufferBase glad_glBindBufferBase -GLAD_API_CALL PFNGLGENBUFFERSPROC glad_glGenBuffers; + GLAD_API_CALL PFNGLGENBUFFERSPROC glad_glGenBuffers; #define glGenBuffers glad_glGenBuffers -GLAD_API_CALL PFNGLTEXCOORD1FPROC glad_glTexCoord1f; + GLAD_API_CALL PFNGLTEXCOORD1FPROC glad_glTexCoord1f; #define glTexCoord1f glad_glTexCoord1f -GLAD_API_CALL PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData; + GLAD_API_CALL PFNGLGETBUFFERSUBDATAPROC glad_glGetBufferSubData; #define glGetBufferSubData glad_glGetBufferSubData -GLAD_API_CALL PFNGLCREATETRANSFORMFEEDBACKSPROC glad_glCreateTransformFeedbacks; + GLAD_API_CALL PFNGLCREATETRANSFORMFEEDBACKSPROC glad_glCreateTransformFeedbacks; #define glCreateTransformFeedbacks glad_glCreateTransformFeedbacks -GLAD_API_CALL PFNGLMAP2FPROC glad_glMap2f; + GLAD_API_CALL PFNGLMAP2FPROC glad_glMap2f; #define glMap2f glad_glMap2f -GLAD_API_CALL PFNGLCREATEBUFFERSPROC glad_glCreateBuffers; + GLAD_API_CALL PFNGLCREATEBUFFERSPROC glad_glCreateBuffers; #define glCreateBuffers glad_glCreateBuffers -GLAD_API_CALL PFNGLCOLOR3USVPROC glad_glColor3usv; + GLAD_API_CALL PFNGLCOLOR3USVPROC glad_glColor3usv; #define glColor3usv glad_glColor3usv -GLAD_API_CALL PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv; + GLAD_API_CALL PFNGLGETSAMPLERPARAMETERFVPROC glad_glGetSamplerParameterfv; #define glGetSamplerParameterfv glad_glGetSamplerParameterfv -GLAD_API_CALL PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; + GLAD_API_CALL PFNGLGETUNIFORMLOCATIONPROC glad_glGetUniformLocation; #define glGetUniformLocation glad_glGetUniformLocation -GLAD_API_CALL PFNGLVERTEX2DPROC glad_glVertex2d; + GLAD_API_CALL PFNGLVERTEX2DPROC glad_glVertex2d; #define glVertex2d glad_glVertex2d -GLAD_API_CALL PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glad_glGetSubroutineUniformLocation; + GLAD_API_CALL PFNGLGETSUBROUTINEUNIFORMLOCATIONPROC glad_glGetSubroutineUniformLocation; #define glGetSubroutineUniformLocation glad_glGetSubroutineUniformLocation -GLAD_API_CALL PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData; + GLAD_API_CALL PFNGLINVALIDATEBUFFERSUBDATAPROC glad_glInvalidateBufferSubData; #define glInvalidateBufferSubData glad_glInvalidateBufferSubData -GLAD_API_CALL PFNGLUNIFORMMATRIX2DVPROC glad_glUniformMatrix2dv; + GLAD_API_CALL PFNGLUNIFORMMATRIX2DVPROC glad_glUniformMatrix2dv; #define glUniformMatrix2dv glad_glUniformMatrix2dv -GLAD_API_CALL PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData; + GLAD_API_CALL PFNGLCLEARNAMEDBUFFERSUBDATAPROC glad_glClearNamedBufferSubData; #define glClearNamedBufferSubData glad_glClearNamedBufferSubData -GLAD_API_CALL PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; + GLAD_API_CALL PFNGLGETPROGRAMIVPROC glad_glGetProgramiv; #define glGetProgramiv glad_glGetProgramiv -GLAD_API_CALL PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; + GLAD_API_CALL PFNGLDRAWRANGEELEMENTSPROC glad_glDrawRangeElements; #define glDrawRangeElements glad_glDrawRangeElements -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv; + GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4FVPROC glad_glProgramUniformMatrix4fv; #define glProgramUniformMatrix4fv glad_glProgramUniformMatrix4fv -GLAD_API_CALL PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; + GLAD_API_CALL PFNGLGETINTEGER64I_VPROC glad_glGetInteger64i_v; #define glGetInteger64i_v glad_glGetInteger64i_v -GLAD_API_CALL PFNGLVERTEXATTRIBL1DPROC glad_glVertexAttribL1d; + GLAD_API_CALL PFNGLVERTEXATTRIBL1DPROC glad_glVertexAttribL1d; #define glVertexAttribL1d glad_glVertexAttribL1d -GLAD_API_CALL PFNGLGETTEXTUREIMAGEPROC glad_glGetTextureImage; + GLAD_API_CALL PFNGLGETTEXTUREIMAGEPROC glad_glGetTextureImage; #define glGetTextureImage glad_glGetTextureImage -GLAD_API_CALL PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv; + GLAD_API_CALL PFNGLGETNUNIFORMIVPROC glad_glGetnUniformiv; #define glGetnUniformiv glad_glGetnUniformiv -GLAD_API_CALL PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i; + GLAD_API_CALL PFNGLPROGRAMUNIFORM1IPROC glad_glProgramUniform1i; #define glProgramUniform1i glad_glProgramUniform1i -GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced; + GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKINSTANCEDPROC glad_glDrawTransformFeedbackInstanced; #define glDrawTransformFeedbackInstanced glad_glDrawTransformFeedbackInstanced -GLAD_API_CALL PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex; + GLAD_API_CALL PFNGLGETPROGRAMRESOURCEINDEXPROC glad_glGetProgramResourceIndex; #define glGetProgramResourceIndex glad_glGetProgramResourceIndex -GLAD_API_CALL PFNGLPROGRAMUNIFORM2DPROC glad_glProgramUniform2d; + GLAD_API_CALL PFNGLPROGRAMUNIFORM2DPROC glad_glProgramUniform2d; #define glProgramUniform2d glad_glProgramUniform2d -GLAD_API_CALL PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer; + GLAD_API_CALL PFNGLUNMAPNAMEDBUFFERPROC glad_glUnmapNamedBuffer; #define glUnmapNamedBuffer glad_glUnmapNamedBuffer -GLAD_API_CALL PFNGLMULTITEXCOORD2FPROC glad_glMultiTexCoord2f; + GLAD_API_CALL PFNGLMULTITEXCOORD2FPROC glad_glMultiTexCoord2f; #define glMultiTexCoord2f glad_glMultiTexCoord2f -GLAD_API_CALL PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv; + GLAD_API_CALL PFNGLPOINTPARAMETERFVPROC glad_glPointParameterfv; #define glPointParameterfv glad_glPointParameterfv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv; + GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3FVPROC glad_glProgramUniformMatrix3fv; #define glProgramUniformMatrix3fv glad_glProgramUniformMatrix3fv -GLAD_API_CALL PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; + GLAD_API_CALL PFNGLBINDBUFFERRANGEPROC glad_glBindBufferRange; #define glBindBufferRange glad_glBindBufferRange -GLAD_API_CALL PFNGLMULTITEXCOORD2DVPROC glad_glMultiTexCoord2dv; + GLAD_API_CALL PFNGLMULTITEXCOORD2DVPROC glad_glMultiTexCoord2dv; #define glMultiTexCoord2dv glad_glMultiTexCoord2dv -GLAD_API_CALL PFNGLCOLORMATERIALPROC glad_glColorMaterial; + GLAD_API_CALL PFNGLCOLORMATERIALPROC glad_glColorMaterial; #define glColorMaterial glad_glColorMaterial -GLAD_API_CALL PFNGLBLENDEQUATIONPROC glad_glBlendEquation; + GLAD_API_CALL PFNGLBLENDEQUATIONPROC glad_glBlendEquation; #define glBlendEquation glad_glBlendEquation -GLAD_API_CALL PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; + GLAD_API_CALL PFNGLBLITFRAMEBUFFERPROC glad_glBlitFramebuffer; #define glBlitFramebuffer glad_glBlitFramebuffer -GLAD_API_CALL PFNGLCOLOR3DPROC glad_glColor3d; + GLAD_API_CALL PFNGLCOLOR3DPROC glad_glColor3d; #define glColor3d glad_glColor3d -GLAD_API_CALL PFNGLMULTITEXCOORD3IVPROC glad_glMultiTexCoord3iv; + GLAD_API_CALL PFNGLMULTITEXCOORD3IVPROC glad_glMultiTexCoord3iv; #define glMultiTexCoord3iv glad_glMultiTexCoord3iv -GLAD_API_CALL PFNGLLIGHTFVPROC glad_glLightfv; + GLAD_API_CALL PFNGLLIGHTFVPROC glad_glLightfv; #define glLightfv glad_glLightfv -GLAD_API_CALL PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv; + GLAD_API_CALL PFNGLVERTEXATTRIB1DVPROC glad_glVertexAttrib1dv; #define glVertexAttrib1dv glad_glVertexAttrib1dv -GLAD_API_CALL PFNGLDEPTHMASKPROC glad_glDepthMask; + GLAD_API_CALL PFNGLDEPTHMASKPROC glad_glDepthMask; #define glDepthMask glad_glDepthMask -GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; + GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKVARYINGPROC glad_glGetTransformFeedbackVarying; #define glGetTransformFeedbackVarying glad_glGetTransformFeedbackVarying -GLAD_API_CALL PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui; + GLAD_API_CALL PFNGLPROGRAMUNIFORM1UIPROC glad_glProgramUniform1ui; #define glProgramUniform1ui glad_glProgramUniform1ui -GLAD_API_CALL PFNGLVERTEXATTRIBL3DPROC glad_glVertexAttribL3d; + GLAD_API_CALL PFNGLVERTEXATTRIBL3DPROC glad_glVertexAttribL3d; #define glVertexAttribL3d glad_glVertexAttribL3d -GLAD_API_CALL PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect; + GLAD_API_CALL PFNGLDRAWELEMENTSINDIRECTPROC glad_glDrawElementsIndirect; #define glDrawElementsIndirect glad_glDrawElementsIndirect -GLAD_API_CALL PFNGLLOADTRANSPOSEMATRIXFPROC glad_glLoadTransposeMatrixf; + GLAD_API_CALL PFNGLLOADTRANSPOSEMATRIXFPROC glad_glLoadTransposeMatrixf; #define glLoadTransposeMatrixf glad_glLoadTransposeMatrixf -GLAD_API_CALL PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed; + GLAD_API_CALL PFNGLENDQUERYINDEXEDPROC glad_glEndQueryIndexed; #define glEndQueryIndexed glad_glEndQueryIndexed -GLAD_API_CALL PFNGLSECONDARYCOLOR3USPROC glad_glSecondaryColor3us; + GLAD_API_CALL PFNGLSECONDARYCOLOR3USPROC glad_glSecondaryColor3us; #define glSecondaryColor3us glad_glSecondaryColor3us -GLAD_API_CALL PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glad_glTextureStorage2DMultisample; + GLAD_API_CALL PFNGLTEXTURESTORAGE2DMULTISAMPLEPROC glad_glTextureStorage2DMultisample; #define glTextureStorage2DMultisample glad_glTextureStorage2DMultisample -GLAD_API_CALL PFNGLPIXELSTOREFPROC glad_glPixelStoref; + GLAD_API_CALL PFNGLPIXELSTOREFPROC glad_glPixelStoref; #define glPixelStoref glad_glPixelStoref -GLAD_API_CALL PFNGLUNIFORM2IVPROC glad_glUniform2iv; + GLAD_API_CALL PFNGLUNIFORM2IVPROC glad_glUniform2iv; #define glUniform2iv glad_glUniform2iv -GLAD_API_CALL PFNGLRASTERPOS2SVPROC glad_glRasterPos2sv; + GLAD_API_CALL PFNGLRASTERPOS2SVPROC glad_glRasterPos2sv; #define glRasterPos2sv glad_glRasterPos2sv -GLAD_API_CALL PFNGLVERTEX2IPROC glad_glVertex2i; + GLAD_API_CALL PFNGLVERTEX2IPROC glad_glVertex2i; #define glVertex2i glad_glVertex2i -GLAD_API_CALL PFNGLFRUSTUMPROC glad_glFrustum; + GLAD_API_CALL PFNGLFRUSTUMPROC glad_glFrustum; #define glFrustum glad_glFrustum -GLAD_API_CALL PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier; + GLAD_API_CALL PFNGLMEMORYBARRIERPROC glad_glMemoryBarrier; #define glMemoryBarrier glad_glMemoryBarrier -GLAD_API_CALL PFNGLGETSTRINGPROC glad_glGetString; + GLAD_API_CALL PFNGLGETSTRINGPROC glad_glGetString; #define glGetString glad_glGetString -GLAD_API_CALL PFNGLLINEWIDTHPROC glad_glLineWidth; + GLAD_API_CALL PFNGLLINEWIDTHPROC glad_glLineWidth; #define glLineWidth glad_glLineWidth -GLAD_API_CALL PFNGLNORMALPOINTERPROC glad_glNormalPointer; + GLAD_API_CALL PFNGLNORMALPOINTERPROC glad_glNormalPointer; #define glNormalPointer glad_glNormalPointer -GLAD_API_CALL PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv; + GLAD_API_CALL PFNGLGETNUNIFORMUIVPROC glad_glGetnUniformuiv; #define glGetnUniformuiv glad_glGetnUniformuiv -GLAD_API_CALL PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv; + GLAD_API_CALL PFNGLDEPTHRANGEARRAYVPROC glad_glDepthRangeArrayv; #define glDepthRangeArrayv glad_glDepthRangeArrayv -GLAD_API_CALL PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui; + GLAD_API_CALL PFNGLTEXCOORDP2UIPROC glad_glTexCoordP2ui; #define glTexCoordP2ui glad_glTexCoordP2ui -GLAD_API_CALL PFNGLATTACHSHADERPROC glad_glAttachShader; + GLAD_API_CALL PFNGLATTACHSHADERPROC glad_glAttachShader; #define glAttachShader glad_glAttachShader -GLAD_API_CALL PFNGLDRAWARRAYSPROC glad_glDrawArrays; + GLAD_API_CALL PFNGLDRAWARRAYSPROC glad_glDrawArrays; #define glDrawArrays glad_glDrawArrays -GLAD_API_CALL PFNGLCOLOR4SPROC glad_glColor4s; + GLAD_API_CALL PFNGLCOLOR4SPROC glad_glColor4s; #define glColor4s glad_glColor4s -GLAD_API_CALL PFNGLTEXGENDVPROC glad_glTexGendv; + GLAD_API_CALL PFNGLTEXGENDVPROC glad_glTexGendv; #define glTexGendv glad_glTexGendv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glad_glProgramUniformMatrix3x2dv; + GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3X2DVPROC glad_glProgramUniformMatrix3x2dv; #define glProgramUniformMatrix3x2dv glad_glProgramUniformMatrix3x2dv -GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv; + GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIUIVPROC glad_glGetSamplerParameterIuiv; #define glGetSamplerParameterIuiv glad_glGetSamplerParameterIuiv -GLAD_API_CALL PFNGLENDQUERYPROC glad_glEndQuery; + GLAD_API_CALL PFNGLENDQUERYPROC glad_glEndQuery; #define glEndQuery glad_glEndQuery -GLAD_API_CALL PFNGLWINDOWPOS2SPROC glad_glWindowPos2s; + GLAD_API_CALL PFNGLWINDOWPOS2SPROC glad_glWindowPos2s; #define glWindowPos2s glad_glWindowPos2s -GLAD_API_CALL PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect; + GLAD_API_CALL PFNGLDRAWARRAYSINDIRECTPROC glad_glDrawArraysIndirect; #define glDrawArraysIndirect glad_glDrawArraysIndirect -GLAD_API_CALL PFNGLRASTERPOS3SPROC glad_glRasterPos3s; + GLAD_API_CALL PFNGLRASTERPOS3SPROC glad_glRasterPos3s; #define glRasterPos3s glad_glRasterPos3s -GLAD_API_CALL PFNGLGETNPIXELMAPFVPROC glad_glGetnPixelMapfv; + GLAD_API_CALL PFNGLGETNPIXELMAPFVPROC glad_glGetnPixelMapfv; #define glGetnPixelMapfv glad_glGetnPixelMapfv -GLAD_API_CALL PFNGLTEXCOORD3SVPROC glad_glTexCoord3sv; + GLAD_API_CALL PFNGLTEXCOORD3SVPROC glad_glTexCoord3sv; #define glTexCoord3sv glad_glTexCoord3sv -GLAD_API_CALL PFNGLRECTIPROC glad_glRecti; + GLAD_API_CALL PFNGLRECTIPROC glad_glRecti; #define glRecti glad_glRecti -GLAD_API_CALL PFNGLUNIFORM4DVPROC glad_glUniform4dv; + GLAD_API_CALL PFNGLUNIFORM4DVPROC glad_glUniform4dv; #define glUniform4dv glad_glUniform4dv -GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEIPROC glad_glBlendEquationSeparatei; + GLAD_API_CALL PFNGLBLENDEQUATIONSEPARATEIPROC glad_glBlendEquationSeparatei; #define glBlendEquationSeparatei glad_glBlendEquationSeparatei -GLAD_API_CALL PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv; + GLAD_API_CALL PFNGLPROGRAMUNIFORM3FVPROC glad_glProgramUniform3fv; #define glProgramUniform3fv glad_glProgramUniform3fv -GLAD_API_CALL PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv; + GLAD_API_CALL PFNGLGETPROGRAMRESOURCEIVPROC glad_glGetProgramResourceiv; #define glGetProgramResourceiv glad_glGetProgramResourceiv -GLAD_API_CALL PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer; + GLAD_API_CALL PFNGLINVALIDATESUBFRAMEBUFFERPROC glad_glInvalidateSubFramebuffer; #define glInvalidateSubFramebuffer glad_glInvalidateSubFramebuffer -GLAD_API_CALL PFNGLFENCESYNCPROC glad_glFenceSync; + GLAD_API_CALL PFNGLFENCESYNCPROC glad_glFenceSync; #define glFenceSync glad_glFenceSync -GLAD_API_CALL PFNGLUNIFORM3UIPROC glad_glUniform3ui; + GLAD_API_CALL PFNGLUNIFORM3UIPROC glad_glUniform3ui; #define glUniform3ui glad_glUniform3ui -GLAD_API_CALL PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv; + GLAD_API_CALL PFNGLSECONDARYCOLORP3UIVPROC glad_glSecondaryColorP3uiv; #define glSecondaryColorP3uiv glad_glSecondaryColorP3uiv -GLAD_API_CALL PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s; + GLAD_API_CALL PFNGLVERTEXATTRIB1SPROC glad_glVertexAttrib1s; #define glVertexAttrib1s glad_glVertexAttrib1s -GLAD_API_CALL PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv; + GLAD_API_CALL PFNGLVERTEXATTRIB4NSVPROC glad_glVertexAttrib4Nsv; #define glVertexAttrib4Nsv glad_glVertexAttrib4Nsv -GLAD_API_CALL PFNGLLOADMATRIXFPROC glad_glLoadMatrixf; + GLAD_API_CALL PFNGLLOADMATRIXFPROC glad_glLoadMatrixf; #define glLoadMatrixf glad_glLoadMatrixf -GLAD_API_CALL PFNGLTRANSLATEFPROC glad_glTranslatef; + GLAD_API_CALL PFNGLTRANSLATEFPROC glad_glTranslatef; #define glTranslatef glad_glTranslatef -GLAD_API_CALL PFNGLMULTITEXCOORD4SVPROC glad_glMultiTexCoord4sv; + GLAD_API_CALL PFNGLMULTITEXCOORD4SVPROC glad_glMultiTexCoord4sv; #define glMultiTexCoord4sv glad_glMultiTexCoord4sv -GLAD_API_CALL PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv; + GLAD_API_CALL PFNGLPROGRAMUNIFORM2IVPROC glad_glProgramUniform2iv; #define glProgramUniform2iv glad_glProgramUniform2iv -GLAD_API_CALL PFNGLMAPGRID2FPROC glad_glMapGrid2f; + GLAD_API_CALL PFNGLMAPGRID2FPROC glad_glMapGrid2f; #define glMapGrid2f glad_glMapGrid2f -GLAD_API_CALL PFNGLENABLECLIENTSTATEPROC glad_glEnableClientState; + GLAD_API_CALL PFNGLENABLECLIENTSTATEPROC glad_glEnableClientState; #define glEnableClientState glad_glEnableClientState -GLAD_API_CALL PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; + GLAD_API_CALL PFNGLGETUNIFORMIVPROC glad_glGetUniformiv; #define glGetUniformiv glad_glGetUniformiv -GLAD_API_CALL PFNGLEVALCOORD1DVPROC glad_glEvalCoord1dv; + GLAD_API_CALL PFNGLEVALCOORD1DVPROC glad_glEvalCoord1dv; #define glEvalCoord1dv glad_glEvalCoord1dv -GLAD_API_CALL PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; + GLAD_API_CALL PFNGLVERTEXATTRIBI4IVPROC glad_glVertexAttribI4iv; #define glVertexAttribI4iv glad_glVertexAttribI4iv -GLAD_API_CALL PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv; + GLAD_API_CALL PFNGLVERTEXATTRIB4SVPROC glad_glVertexAttrib4sv; #define glVertexAttrib4sv glad_glVertexAttrib4sv -GLAD_API_CALL PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; + GLAD_API_CALL PFNGLGETMULTISAMPLEFVPROC glad_glGetMultisamplefv; #define glGetMultisamplefv glad_glGetMultisamplefv -GLAD_API_CALL PFNGLINDEXDVPROC glad_glIndexdv; + GLAD_API_CALL PFNGLINDEXDVPROC glad_glIndexdv; #define glIndexdv glad_glIndexdv -GLAD_API_CALL PFNGLBLENDFUNCIPROC glad_glBlendFunci; + GLAD_API_CALL PFNGLBLENDFUNCIPROC glad_glBlendFunci; #define glBlendFunci glad_glBlendFunci -GLAD_API_CALL PFNGLISENABLEDPROC glad_glIsEnabled; + GLAD_API_CALL PFNGLISENABLEDPROC glad_glIsEnabled; #define glIsEnabled glad_glIsEnabled -GLAD_API_CALL PFNGLGETPIXELMAPUSVPROC glad_glGetPixelMapusv; + GLAD_API_CALL PFNGLGETPIXELMAPUSVPROC glad_glGetPixelMapusv; #define glGetPixelMapusv glad_glGetPixelMapusv -GLAD_API_CALL PFNGLRASTERPOS3IVPROC glad_glRasterPos3iv; + GLAD_API_CALL PFNGLRASTERPOS3IVPROC glad_glRasterPos3iv; #define glRasterPos3iv glad_glRasterPos3iv -GLAD_API_CALL PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; + GLAD_API_CALL PFNGLMAPBUFFERRANGEPROC glad_glMapBufferRange; #define glMapBufferRange glad_glMapBufferRange -GLAD_API_CALL PFNGLMULTITEXCOORD2SPROC glad_glMultiTexCoord2s; + GLAD_API_CALL PFNGLMULTITEXCOORD2SPROC glad_glMultiTexCoord2s; #define glMultiTexCoord2s glad_glMultiTexCoord2s -GLAD_API_CALL PFNGLRASTERPOS2FPROC glad_glRasterPos2f; + GLAD_API_CALL PFNGLRASTERPOS2FPROC glad_glRasterPos2f; #define glRasterPos2f glad_glRasterPos2f -GLAD_API_CALL PFNGLMINSAMPLESHADINGPROC glad_glMinSampleShading; + GLAD_API_CALL PFNGLMINSAMPLESHADINGPROC glad_glMinSampleShading; #define glMinSampleShading glad_glMinSampleShading -GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTUI64VPROC glad_glGetQueryBufferObjectui64v; + GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTUI64VPROC glad_glGetQueryBufferObjectui64v; #define glGetQueryBufferObjectui64v glad_glGetQueryBufferObjectui64v -GLAD_API_CALL PFNGLMULTITEXCOORD2IPROC glad_glMultiTexCoord2i; + GLAD_API_CALL PFNGLMULTITEXCOORD2IPROC glad_glMultiTexCoord2i; #define glMultiTexCoord2i glad_glMultiTexCoord2i -GLAD_API_CALL PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv; + GLAD_API_CALL PFNGLVERTEXATTRIBP3UIVPROC glad_glVertexAttribP3uiv; #define glVertexAttribP3uiv glad_glVertexAttribP3uiv -GLAD_API_CALL PFNGLVERTEX2FPROC glad_glVertex2f; + GLAD_API_CALL PFNGLVERTEX2FPROC glad_glVertex2f; #define glVertex2f glad_glVertex2f -GLAD_API_CALL PFNGLVERTEXARRAYBINDINGDIVISORPROC glad_glVertexArrayBindingDivisor; + GLAD_API_CALL PFNGLVERTEXARRAYBINDINGDIVISORPROC glad_glVertexArrayBindingDivisor; #define glVertexArrayBindingDivisor glad_glVertexArrayBindingDivisor -GLAD_API_CALL PFNGLINDEXPOINTERPROC glad_glIndexPointer; + GLAD_API_CALL PFNGLINDEXPOINTERPROC glad_glIndexPointer; #define glIndexPointer glad_glIndexPointer -GLAD_API_CALL PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; + GLAD_API_CALL PFNGLUNIFORMBLOCKBINDINGPROC glad_glUniformBlockBinding; #define glUniformBlockBinding glad_glUniformBlockBinding -GLAD_API_CALL PFNGLRENDERMODEPROC glad_glRenderMode; + GLAD_API_CALL PFNGLRENDERMODEPROC glad_glRenderMode; #define glRenderMode glad_glRenderMode -GLAD_API_CALL PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D; + GLAD_API_CALL PFNGLTEXSTORAGE1DPROC glad_glTexStorage1D; #define glTexStorage1D glad_glTexStorage1D -GLAD_API_CALL PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; + GLAD_API_CALL PFNGLBUFFERSUBDATAPROC glad_glBufferSubData; #define glBufferSubData glad_glBufferSubData -GLAD_API_CALL PFNGLCOLOR3FVPROC glad_glColor3fv; + GLAD_API_CALL PFNGLCOLOR3FVPROC glad_glColor3fv; #define glColor3fv glad_glColor3fv -GLAD_API_CALL PFNGLBITMAPPROC glad_glBitmap; + GLAD_API_CALL PFNGLBITMAPPROC glad_glBitmap; #define glBitmap glad_glBitmap -GLAD_API_CALL PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv; + GLAD_API_CALL PFNGLPROGRAMUNIFORM3UIVPROC glad_glProgramUniform3uiv; #define glProgramUniform3uiv glad_glProgramUniform3uiv -GLAD_API_CALL PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf; + GLAD_API_CALL PFNGLVIEWPORTINDEXEDFPROC glad_glViewportIndexedf; #define glViewportIndexedf glad_glViewportIndexedf -GLAD_API_CALL PFNGLRASTERPOS2DPROC glad_glRasterPos2d; + GLAD_API_CALL PFNGLRASTERPOS2DPROC glad_glRasterPos2d; #define glRasterPos2d glad_glRasterPos2d -GLAD_API_CALL PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; + GLAD_API_CALL PFNGLGETUNIFORMINDICESPROC glad_glGetUniformIndices; #define glGetUniformIndices glad_glGetUniformIndices -GLAD_API_CALL PFNGLENABLEIPROC glad_glEnablei; + GLAD_API_CALL PFNGLENABLEIPROC glad_glEnablei; #define glEnablei glad_glEnablei -GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; + GLAD_API_CALL PFNGLFRAMEBUFFERTEXTURE2DPROC glad_glFramebufferTexture2D; #define glFramebufferTexture2D glad_glFramebufferTexture2D -GLAD_API_CALL PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; + GLAD_API_CALL PFNGLBLENDFUNCSEPARATEPROC glad_glBlendFuncSeparate; #define glBlendFuncSeparate glad_glBlendFuncSeparate -GLAD_API_CALL PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage; + GLAD_API_CALL PFNGLNAMEDBUFFERSTORAGEPROC glad_glNamedBufferStorage; #define glNamedBufferStorage glad_glNamedBufferStorage -GLAD_API_CALL PFNGLRECTSPROC glad_glRects; + GLAD_API_CALL PFNGLRECTSPROC glad_glRects; #define glRects glad_glRects -GLAD_API_CALL PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv; + GLAD_API_CALL PFNGLPROGRAMUNIFORM2FVPROC glad_glProgramUniform2fv; #define glProgramUniform2fv glad_glProgramUniform2fv -GLAD_API_CALL PFNGLPOLYGONSTIPPLEPROC glad_glPolygonStipple; + GLAD_API_CALL PFNGLPOLYGONSTIPPLEPROC glad_glPolygonStipple; #define glPolygonStipple glad_glPolygonStipple -GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; + GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE3DPROC glad_glCopyTexSubImage3D; #define glCopyTexSubImage3D glad_glCopyTexSubImage3D -GLAD_API_CALL PFNGLSECONDARYCOLOR3UBPROC glad_glSecondaryColor3ub; + GLAD_API_CALL PFNGLSECONDARYCOLOR3UBPROC glad_glSecondaryColor3ub; #define glSecondaryColor3ub glad_glSecondaryColor3ub -GLAD_API_CALL PFNGLWINDOWPOS3FPROC glad_glWindowPos3f; + GLAD_API_CALL PFNGLWINDOWPOS3FPROC glad_glWindowPos3f; #define glWindowPos3f glad_glWindowPos3f -GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv; + GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIVPROC glad_glGetSamplerParameteriv; #define glGetSamplerParameteriv glad_glGetSamplerParameteriv -GLAD_API_CALL PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding; + GLAD_API_CALL PFNGLSHADERSTORAGEBLOCKBINDINGPROC glad_glShaderStorageBlockBinding; #define glShaderStorageBlockBinding glad_glShaderStorageBlockBinding -GLAD_API_CALL PFNGLLOADIDENTITYPROC glad_glLoadIdentity; + GLAD_API_CALL PFNGLLOADIDENTITYPROC glad_glLoadIdentity; #define glLoadIdentity glad_glLoadIdentity -GLAD_API_CALL PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; + GLAD_API_CALL PFNGLMULTIDRAWELEMENTSBASEVERTEXPROC glad_glMultiDrawElementsBaseVertex; #define glMultiDrawElementsBaseVertex glad_glMultiDrawElementsBaseVertex -GLAD_API_CALL PFNGLVERTEX2SPROC glad_glVertex2s; + GLAD_API_CALL PFNGLVERTEX2SPROC glad_glVertex2s; #define glVertex2s glad_glVertex2s -GLAD_API_CALL PFNGLMULTITEXCOORD1IVPROC glad_glMultiTexCoord1iv; + GLAD_API_CALL PFNGLMULTITEXCOORD1IVPROC glad_glMultiTexCoord1iv; #define glMultiTexCoord1iv glad_glMultiTexCoord1iv -GLAD_API_CALL PFNGLMULTITEXCOORD4SPROC glad_glMultiTexCoord4s; + GLAD_API_CALL PFNGLMULTITEXCOORD4SPROC glad_glMultiTexCoord4s; #define glMultiTexCoord4s glad_glMultiTexCoord4s -GLAD_API_CALL PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler; + GLAD_API_CALL PFNGLRELEASESHADERCOMPILERPROC glad_glReleaseShaderCompiler; #define glReleaseShaderCompiler glad_glReleaseShaderCompiler -GLAD_API_CALL PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; + GLAD_API_CALL PFNGLGETSHADERSOURCEPROC glad_glGetShaderSource; #define glGetShaderSource glad_glGetShaderSource -GLAD_API_CALL PFNGLMULTITEXCOORD2SVPROC glad_glMultiTexCoord2sv; + GLAD_API_CALL PFNGLMULTITEXCOORD2SVPROC glad_glMultiTexCoord2sv; #define glMultiTexCoord2sv glad_glMultiTexCoord2sv -GLAD_API_CALL PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; + GLAD_API_CALL PFNGLTEXPARAMETERFVPROC glad_glTexParameterfv; #define glTexParameterfv glad_glTexParameterfv -GLAD_API_CALL PFNGLISSHADERPROC glad_glIsShader; + GLAD_API_CALL PFNGLISSHADERPROC glad_glIsShader; #define glIsShader glad_glIsShader -GLAD_API_CALL PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv; + GLAD_API_CALL PFNGLVERTEXATTRIB4IVPROC glad_glVertexAttrib4iv; #define glVertexAttrib4iv glad_glVertexAttrib4iv -GLAD_API_CALL PFNGLTEXCOORD4IPROC glad_glTexCoord4i; + GLAD_API_CALL PFNGLTEXCOORD4IPROC glad_glTexCoord4i; #define glTexCoord4i glad_glTexCoord4i -GLAD_API_CALL PFNGLCOLOR4UIPROC glad_glColor4ui; + GLAD_API_CALL PFNGLCOLOR4UIPROC glad_glColor4ui; #define glColor4ui glad_glColor4ui -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3DVPROC glad_glProgramUniformMatrix3dv; + GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX3DVPROC glad_glProgramUniformMatrix3dv; #define glProgramUniformMatrix3dv glad_glProgramUniformMatrix3dv -GLAD_API_CALL PFNGLGETTEXENVFVPROC glad_glGetTexEnvfv; + GLAD_API_CALL PFNGLGETTEXENVFVPROC glad_glGetTexEnvfv; #define glGetTexEnvfv glad_glGetTexEnvfv -GLAD_API_CALL PFNGLTEXCOORD4DPROC glad_glTexCoord4d; + GLAD_API_CALL PFNGLTEXCOORD4DPROC glad_glTexCoord4d; #define glTexCoord4d glad_glTexCoord4d -GLAD_API_CALL PFNGLSCISSORARRAYVPROC glad_glScissorArrayv; + GLAD_API_CALL PFNGLSCISSORARRAYVPROC glad_glScissorArrayv; #define glScissorArrayv glad_glScissorArrayv -GLAD_API_CALL PFNGLCREATERENDERBUFFERSPROC glad_glCreateRenderbuffers; + GLAD_API_CALL PFNGLCREATERENDERBUFFERSPROC glad_glCreateRenderbuffers; #define glCreateRenderbuffers glad_glCreateRenderbuffers -GLAD_API_CALL PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; + GLAD_API_CALL PFNGLVERTEXATTRIB3FVPROC glad_glVertexAttrib3fv; #define glVertexAttrib3fv glad_glVertexAttrib3fv -GLAD_API_CALL PFNGLCOLOR4FPROC glad_glColor4f; + GLAD_API_CALL PFNGLCOLOR4FPROC glad_glColor4f; #define glColor4f glad_glColor4f -GLAD_API_CALL PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub; + GLAD_API_CALL PFNGLVERTEXATTRIB4NUBPROC glad_glVertexAttrib4Nub; #define glVertexAttrib4Nub glad_glVertexAttrib4Nub -GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv; + GLAD_API_CALL PFNGLGETSAMPLERPARAMETERIIVPROC glad_glGetSamplerParameterIiv; #define glGetSamplerParameterIiv glad_glGetSamplerParameterIiv -GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; + GLAD_API_CALL PFNGLCOPYTEXSUBIMAGE2DPROC glad_glCopyTexSubImage2D; #define glCopyTexSubImage2D glad_glCopyTexSubImage2D -GLAD_API_CALL PFNGLNORMAL3IVPROC glad_glNormal3iv; + GLAD_API_CALL PFNGLNORMAL3IVPROC glad_glNormal3iv; #define glNormal3iv glad_glNormal3iv -GLAD_API_CALL PFNGLBINDIMAGETEXTURESPROC glad_glBindImageTextures; + GLAD_API_CALL PFNGLBINDIMAGETEXTURESPROC glad_glBindImageTextures; #define glBindImageTextures glad_glBindImageTextures -GLAD_API_CALL PFNGLTEXGENIVPROC glad_glTexGeniv; + GLAD_API_CALL PFNGLTEXGENIVPROC glad_glTexGeniv; #define glTexGeniv glad_glTexGeniv -GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; + GLAD_API_CALL PFNGLCOMPRESSEDTEXIMAGE3DPROC glad_glCompressedTexImage3D; #define glCompressedTexImage3D glad_glCompressedTexImage3D -GLAD_API_CALL PFNGLSCALEDPROC glad_glScaled; + GLAD_API_CALL PFNGLSCALEDPROC glad_glScaled; #define glScaled glad_glScaled -GLAD_API_CALL PFNGLCREATEPROGRAMPIPELINESPROC glad_glCreateProgramPipelines; + GLAD_API_CALL PFNGLCREATEPROGRAMPIPELINESPROC glad_glCreateProgramPipelines; #define glCreateProgramPipelines glad_glCreateProgramPipelines -GLAD_API_CALL PFNGLBLENDFUNCSEPARATEIPROC glad_glBlendFuncSeparatei; + GLAD_API_CALL PFNGLBLENDFUNCSEPARATEIPROC glad_glBlendFuncSeparatei; #define glBlendFuncSeparatei glad_glBlendFuncSeparatei -GLAD_API_CALL PFNGLHINTPROC glad_glHint; + GLAD_API_CALL PFNGLHINTPROC glad_glHint; #define glHint glad_glHint -GLAD_API_CALL PFNGLMULTITEXCOORD4IPROC glad_glMultiTexCoord4i; + GLAD_API_CALL PFNGLMULTITEXCOORD4IPROC glad_glMultiTexCoord4i; #define glMultiTexCoord4i glad_glMultiTexCoord4i -GLAD_API_CALL PFNGLINDEXMASKPROC glad_glIndexMask; + GLAD_API_CALL PFNGLINDEXMASKPROC glad_glIndexMask; #define glIndexMask glad_glIndexMask -GLAD_API_CALL PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f; + GLAD_API_CALL PFNGLPROGRAMUNIFORM2FPROC glad_glProgramUniform2f; #define glProgramUniform2f glad_glProgramUniform2f -GLAD_API_CALL PFNGLCOLOR3BPROC glad_glColor3b; + GLAD_API_CALL PFNGLCOLOR3BPROC glad_glColor3b; #define glColor3b glad_glColor3b -GLAD_API_CALL PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv; + GLAD_API_CALL PFNGLVERTEXATTRIBI1UIVPROC glad_glVertexAttribI1uiv; #define glVertexAttribI1uiv glad_glVertexAttribI1uiv -GLAD_API_CALL PFNGLSPECIALIZESHADERPROC glad_glSpecializeShader; + GLAD_API_CALL PFNGLSPECIALIZESHADERPROC glad_glSpecializeShader; #define glSpecializeShader glad_glSpecializeShader -GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glad_glNamedFramebufferDrawBuffer; + GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERDRAWBUFFERPROC glad_glNamedFramebufferDrawBuffer; #define glNamedFramebufferDrawBuffer glad_glNamedFramebufferDrawBuffer -GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTI64VPROC glad_glGetQueryBufferObjecti64v; + GLAD_API_CALL PFNGLGETQUERYBUFFEROBJECTI64VPROC glad_glGetQueryBufferObjecti64v; #define glGetQueryBufferObjecti64v glad_glGetQueryBufferObjecti64v -GLAD_API_CALL PFNGLTEXCOORD3IVPROC glad_glTexCoord3iv; + GLAD_API_CALL PFNGLTEXCOORD3IVPROC glad_glTexCoord3iv; #define glTexCoord3iv glad_glTexCoord3iv -GLAD_API_CALL PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv; + GLAD_API_CALL PFNGLSAMPLERPARAMETERFVPROC glad_glSamplerParameterfv; #define glSamplerParameterfv glad_glSamplerParameterfv -GLAD_API_CALL PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; + GLAD_API_CALL PFNGLGETVERTEXATTRIBIIVPROC glad_glGetVertexAttribIiv; #define glGetVertexAttribIiv glad_glGetVertexAttribIiv -GLAD_API_CALL PFNGLBUFFERSTORAGEPROC glad_glBufferStorage; + GLAD_API_CALL PFNGLBUFFERSTORAGEPROC glad_glBufferStorage; #define glBufferStorage glad_glBufferStorage -GLAD_API_CALL PFNGLVERTEX3SPROC glad_glVertex3s; + GLAD_API_CALL PFNGLVERTEX3SPROC glad_glVertex3s; #define glVertex3s glad_glVertex3s -GLAD_API_CALL PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv; + GLAD_API_CALL PFNGLPROGRAMUNIFORM2UIVPROC glad_glProgramUniform2uiv; #define glProgramUniform2uiv glad_glProgramUniform2uiv -GLAD_API_CALL PFNGLDEPTHRANGEPROC glad_glDepthRange; + GLAD_API_CALL PFNGLDEPTHRANGEPROC glad_glDepthRange; #define glDepthRange glad_glDepthRange -GLAD_API_CALL PFNGLRASTERPOS3FPROC glad_glRasterPos3f; + GLAD_API_CALL PFNGLRASTERPOS3FPROC glad_glRasterPos3f; #define glRasterPos3f glad_glRasterPos3f -GLAD_API_CALL PFNGLDELETESHADERPROC glad_glDeleteShader; + GLAD_API_CALL PFNGLDELETESHADERPROC glad_glDeleteShader; #define glDeleteShader glad_glDeleteShader -GLAD_API_CALL PFNGLCOLOR3BVPROC glad_glColor3bv; + GLAD_API_CALL PFNGLCOLOR3BVPROC glad_glColor3bv; #define glColor3bv glad_glColor3bv -GLAD_API_CALL PFNGLCOLOR3UBVPROC glad_glColor3ubv; + GLAD_API_CALL PFNGLCOLOR3UBVPROC glad_glColor3ubv; #define glColor3ubv glad_glColor3ubv -GLAD_API_CALL PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; + GLAD_API_CALL PFNGLGETVERTEXATTRIBIVPROC glad_glGetVertexAttribiv; #define glGetVertexAttribiv glad_glGetVertexAttribiv -GLAD_API_CALL PFNGLTEXCOORD4SVPROC glad_glTexCoord4sv; + GLAD_API_CALL PFNGLTEXCOORD4SVPROC glad_glTexCoord4sv; #define glTexCoord4sv glad_glTexCoord4sv -GLAD_API_CALL PFNGLMAP2DPROC glad_glMap2d; + GLAD_API_CALL PFNGLMAP2DPROC glad_glMap2d; #define glMap2d glad_glMap2d -GLAD_API_CALL PFNGLFOGCOORDFPROC glad_glFogCoordf; + GLAD_API_CALL PFNGLFOGCOORDFPROC glad_glFogCoordf; #define glFogCoordf glad_glFogCoordf -GLAD_API_CALL PFNGLEDGEFLAGVPROC glad_glEdgeFlagv; + GLAD_API_CALL PFNGLEDGEFLAGVPROC glad_glEdgeFlagv; #define glEdgeFlagv glad_glEdgeFlagv -GLAD_API_CALL PFNGLCLIPCONTROLPROC glad_glClipControl; + GLAD_API_CALL PFNGLCLIPCONTROLPROC glad_glClipControl; #define glClipControl glad_glClipControl -GLAD_API_CALL PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; + GLAD_API_CALL PFNGLGETBUFFERPARAMETERIVPROC glad_glGetBufferParameteriv; #define glGetBufferParameteriv glad_glGetBufferParameteriv -GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKIVPROC glad_glGetTransformFeedbackiv; + GLAD_API_CALL PFNGLGETTRANSFORMFEEDBACKIVPROC glad_glGetTransformFeedbackiv; #define glGetTransformFeedbackiv glad_glGetTransformFeedbackiv -GLAD_API_CALL PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv; + GLAD_API_CALL PFNGLGETPROGRAMPIPELINEIVPROC glad_glGetProgramPipelineiv; #define glGetProgramPipelineiv glad_glGetProgramPipelineiv -GLAD_API_CALL PFNGLGETNMINMAXPROC glad_glGetnMinmax; + GLAD_API_CALL PFNGLGETNMINMAXPROC glad_glGetnMinmax; #define glGetnMinmax glad_glGetnMinmax -GLAD_API_CALL PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample; + GLAD_API_CALL PFNGLNAMEDRENDERBUFFERSTORAGEMULTISAMPLEPROC glad_glNamedRenderbufferStorageMultisample; #define glNamedRenderbufferStorageMultisample glad_glNamedRenderbufferStorageMultisample -GLAD_API_CALL PFNGLCOLORP4UIPROC glad_glColorP4ui; + GLAD_API_CALL PFNGLCOLORP4UIPROC glad_glColorP4ui; #define glColorP4ui glad_glColorP4ui -GLAD_API_CALL PFNGLMULTITEXCOORD1SVPROC glad_glMultiTexCoord1sv; + GLAD_API_CALL PFNGLMULTITEXCOORD1SVPROC glad_glMultiTexCoord1sv; #define glMultiTexCoord1sv glad_glMultiTexCoord1sv -GLAD_API_CALL PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; + GLAD_API_CALL PFNGLVERTEXATTRIB4FVPROC glad_glVertexAttrib4fv; #define glVertexAttrib4fv glad_glVertexAttrib4fv -GLAD_API_CALL PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv; + GLAD_API_CALL PFNGLVERTEXATTRIB4DVPROC glad_glVertexAttrib4dv; #define glVertexAttrib4dv glad_glVertexAttrib4dv -GLAD_API_CALL PFNGLVERTEXP4UIPROC glad_glVertexP4ui; + GLAD_API_CALL PFNGLVERTEXP4UIPROC glad_glVertexP4ui; #define glVertexP4ui glad_glVertexP4ui -GLAD_API_CALL PFNGLRECTFVPROC glad_glRectfv; + GLAD_API_CALL PFNGLRECTFVPROC glad_glRectfv; #define glRectfv glad_glRectfv -GLAD_API_CALL PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; + GLAD_API_CALL PFNGLBEGINTRANSFORMFEEDBACKPROC glad_glBeginTransformFeedback; #define glBeginTransformFeedback glad_glBeginTransformFeedback -GLAD_API_CALL PFNGLARRAYELEMENTPROC glad_glArrayElement; + GLAD_API_CALL PFNGLARRAYELEMENTPROC glad_glArrayElement; #define glArrayElement glad_glArrayElement -GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer; + GLAD_API_CALL PFNGLNAMEDFRAMEBUFFERTEXTURELAYERPROC glad_glNamedFramebufferTextureLayer; #define glNamedFramebufferTextureLayer glad_glNamedFramebufferTextureLayer -GLAD_API_CALL PFNGLBEGINPROC glad_glBegin; + GLAD_API_CALL PFNGLBEGINPROC glad_glBegin; #define glBegin glad_glBegin -GLAD_API_CALL PFNGLTEXCOORDPOINTERPROC glad_glTexCoordPointer; + GLAD_API_CALL PFNGLTEXCOORDPOINTERPROC glad_glTexCoordPointer; #define glTexCoordPointer glad_glTexCoordPointer -GLAD_API_CALL PFNGLTEXCOORD3DPROC glad_glTexCoord3d; + GLAD_API_CALL PFNGLTEXCOORD3DPROC glad_glTexCoord3d; #define glTexCoord3d glad_glTexCoord3d -GLAD_API_CALL PFNGLUNIFORM1FVPROC glad_glUniform1fv; + GLAD_API_CALL PFNGLUNIFORM1FVPROC glad_glUniform1fv; #define glUniform1fv glad_glUniform1fv -GLAD_API_CALL PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv; + GLAD_API_CALL PFNGLVERTEXATTRIB2SVPROC glad_glVertexAttrib2sv; #define glVertexAttrib2sv glad_glVertexAttrib2sv -GLAD_API_CALL PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog; + GLAD_API_CALL PFNGLGETPROGRAMPIPELINEINFOLOGPROC glad_glGetProgramPipelineInfoLog; #define glGetProgramPipelineInfoLog glad_glGetProgramPipelineInfoLog -GLAD_API_CALL PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; + GLAD_API_CALL PFNGLPOLYGONOFFSETPROC glad_glPolygonOffset; #define glPolygonOffset glad_glPolygonOffset -GLAD_API_CALL PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat; + GLAD_API_CALL PFNGLGETSHADERPRECISIONFORMATPROC glad_glGetShaderPrecisionFormat; #define glGetShaderPrecisionFormat glad_glGetShaderPrecisionFormat -GLAD_API_CALL PFNGLPROGRAMUNIFORM3DPROC glad_glProgramUniform3d; + GLAD_API_CALL PFNGLPROGRAMUNIFORM3DPROC glad_glProgramUniform3d; #define glProgramUniform3d glad_glProgramUniform3d -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glad_glProgramUniformMatrix4x2dv; + GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X2DVPROC glad_glProgramUniformMatrix4x2dv; #define glProgramUniformMatrix4x2dv glad_glProgramUniformMatrix4x2dv -GLAD_API_CALL PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback; + GLAD_API_CALL PFNGLBINDTRANSFORMFEEDBACKPROC glad_glBindTransformFeedback; #define glBindTransformFeedback glad_glBindTransformFeedback -GLAD_API_CALL PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; + GLAD_API_CALL PFNGLPROVOKINGVERTEXPROC glad_glProvokingVertex; #define glProvokingVertex glad_glProvokingVertex -GLAD_API_CALL PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib; + GLAD_API_CALL PFNGLDISABLEVERTEXARRAYATTRIBPROC glad_glDisableVertexArrayAttrib; #define glDisableVertexArrayAttrib glad_glDisableVertexArrayAttrib -GLAD_API_CALL PFNGLMULTITEXCOORD4FVPROC glad_glMultiTexCoord4fv; + GLAD_API_CALL PFNGLMULTITEXCOORD4FVPROC glad_glMultiTexCoord4fv; #define glMultiTexCoord4fv glad_glMultiTexCoord4fv -GLAD_API_CALL PFNGLUNIFORM1DPROC glad_glUniform1d; + GLAD_API_CALL PFNGLUNIFORM1DPROC glad_glUniform1d; #define glUniform1d glad_glUniform1d -GLAD_API_CALL PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat; + GLAD_API_CALL PFNGLVERTEXATTRIBFORMATPROC glad_glVertexAttribFormat; #define glVertexAttribFormat glad_glVertexAttribFormat -GLAD_API_CALL PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion; + GLAD_API_CALL PFNGLMEMORYBARRIERBYREGIONPROC glad_glMemoryBarrierByRegion; #define glMemoryBarrierByRegion glad_glMemoryBarrierByRegion -GLAD_API_CALL PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup; + GLAD_API_CALL PFNGLPOPDEBUGGROUPPROC glad_glPopDebugGroup; #define glPopDebugGroup glad_glPopDebugGroup -GLAD_API_CALL PFNGLCOLOR4BPROC glad_glColor4b; + GLAD_API_CALL PFNGLCOLOR4BPROC glad_glColor4b; #define glColor4b glad_glColor4b -GLAD_API_CALL PFNGLTEXTUREBUFFERPROC glad_glTextureBuffer; + GLAD_API_CALL PFNGLTEXTUREBUFFERPROC glad_glTextureBuffer; #define glTextureBuffer glad_glTextureBuffer -GLAD_API_CALL PFNGLGETSHADERIVPROC glad_glGetShaderiv; + GLAD_API_CALL PFNGLGETSHADERIVPROC glad_glGetShaderiv; #define glGetShaderiv glad_glGetShaderiv -GLAD_API_CALL PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed; + GLAD_API_CALL PFNGLBEGINQUERYINDEXEDPROC glad_glBeginQueryIndexed; #define glBeginQueryIndexed glad_glBeginQueryIndexed -GLAD_API_CALL PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData; + GLAD_API_CALL PFNGLCOPYNAMEDBUFFERSUBDATAPROC glad_glCopyNamedBufferSubData; #define glCopyNamedBufferSubData glad_glCopyNamedBufferSubData -GLAD_API_CALL PFNGLVERTEXARRAYATTRIBFORMATPROC glad_glVertexArrayAttribFormat; + GLAD_API_CALL PFNGLVERTEXARRAYATTRIBFORMATPROC glad_glVertexArrayAttribFormat; #define glVertexArrayAttribFormat glad_glVertexArrayAttribFormat -GLAD_API_CALL PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange; + GLAD_API_CALL PFNGLMAPNAMEDBUFFERRANGEPROC glad_glMapNamedBufferRange; #define glMapNamedBufferRange glad_glMapNamedBufferRange -GLAD_API_CALL PFNGLCOLOR4UIVPROC glad_glColor4uiv; + GLAD_API_CALL PFNGLCOLOR4UIVPROC glad_glColor4uiv; #define glColor4uiv glad_glColor4uiv -GLAD_API_CALL PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui; + GLAD_API_CALL PFNGLVERTEXATTRIBP1UIPROC glad_glVertexAttribP1ui; #define glVertexAttribP1ui glad_glVertexAttribP1ui -GLAD_API_CALL PFNGLWINDOWPOS3SVPROC glad_glWindowPos3sv; + GLAD_API_CALL PFNGLWINDOWPOS3SVPROC glad_glWindowPos3sv; #define glWindowPos3sv glad_glWindowPos3sv -GLAD_API_CALL PFNGLFOGIVPROC glad_glFogiv; + GLAD_API_CALL PFNGLFOGIVPROC glad_glFogiv; #define glFogiv glad_glFogiv -GLAD_API_CALL PFNGLTEXTUREPARAMETERIIVPROC glad_glTextureParameterIiv; + GLAD_API_CALL PFNGLTEXTUREPARAMETERIIVPROC glad_glTextureParameterIiv; #define glTextureParameterIiv glad_glTextureParameterIiv -GLAD_API_CALL PFNGLLISTBASEPROC glad_glListBase; + GLAD_API_CALL PFNGLLISTBASEPROC glad_glListBase; #define glListBase glad_glListBase -GLAD_API_CALL PFNGLCREATEFRAMEBUFFERSPROC glad_glCreateFramebuffers; + GLAD_API_CALL PFNGLCREATEFRAMEBUFFERSPROC glad_glCreateFramebuffers; #define glCreateFramebuffers glad_glCreateFramebuffers -GLAD_API_CALL PFNGLEVALCOORD2FPROC glad_glEvalCoord2f; + GLAD_API_CALL PFNGLEVALCOORD2FPROC glad_glEvalCoord2f; #define glEvalCoord2f glad_glEvalCoord2f -GLAD_API_CALL PFNGLVERTEX4DVPROC glad_glVertex4dv; + GLAD_API_CALL PFNGLVERTEX4DVPROC glad_glVertex4dv; #define glVertex4dv glad_glVertex4dv -GLAD_API_CALL PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; + GLAD_API_CALL PFNGLDELETEPROGRAMPROC glad_glDeleteProgram; #define glDeleteProgram glad_glDeleteProgram -GLAD_API_CALL PFNGLDRAWELEMENTSPROC glad_glDrawElements; + GLAD_API_CALL PFNGLDRAWELEMENTSPROC glad_glDrawElements; #define glDrawElements glad_glDrawElements -GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream; + GLAD_API_CALL PFNGLDRAWTRANSFORMFEEDBACKSTREAMPROC glad_glDrawTransformFeedbackStream; #define glDrawTransformFeedbackStream glad_glDrawTransformFeedbackStream -GLAD_API_CALL PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; + GLAD_API_CALL PFNGLVALIDATEPROGRAMPROC glad_glValidateProgram; #define glValidateProgram glad_glValidateProgram -GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; + GLAD_API_CALL PFNGLDRAWELEMENTSINSTANCEDPROC glad_glDrawElementsInstanced; #define glDrawElementsInstanced glad_glDrawElementsInstanced -GLAD_API_CALL PFNGLGENLISTSPROC glad_glGenLists; + GLAD_API_CALL PFNGLGENLISTSPROC glad_glGenLists; #define glGenLists glad_glGenLists -GLAD_API_CALL PFNGLCOLOR4IPROC glad_glColor4i; + GLAD_API_CALL PFNGLCOLOR4IPROC glad_glColor4i; #define glColor4i glad_glColor4i -GLAD_API_CALL PFNGLCOLOR3UIPROC glad_glColor3ui; + GLAD_API_CALL PFNGLCOLOR3UIPROC glad_glColor3ui; #define glColor3ui glad_glColor3ui -GLAD_API_CALL PFNGLCREATETEXTURESPROC glad_glCreateTextures; + GLAD_API_CALL PFNGLCREATETEXTURESPROC glad_glCreateTextures; #define glCreateTextures glad_glCreateTextures -GLAD_API_CALL PFNGLCOLORP4UIVPROC glad_glColorP4uiv; + GLAD_API_CALL PFNGLCOLORP4UIVPROC glad_glColorP4uiv; #define glColorP4uiv glad_glColorP4uiv -GLAD_API_CALL PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; + GLAD_API_CALL PFNGLGETPROGRAMINFOLOGPROC glad_glGetProgramInfoLog; #define glGetProgramInfoLog glad_glGetProgramInfoLog -GLAD_API_CALL PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui; + GLAD_API_CALL PFNGLVERTEXATTRIBP3UIPROC glad_glVertexAttribP3ui; #define glVertexAttribP3ui glad_glVertexAttribP3ui -GLAD_API_CALL PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; + GLAD_API_CALL PFNGLCLEARBUFFERFIPROC glad_glClearBufferfi; #define glClearBufferfi glad_glClearBufferfi -GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE3DPROC glad_glCopyTextureSubImage3D; + GLAD_API_CALL PFNGLCOPYTEXTURESUBIMAGE3DPROC glad_glCopyTextureSubImage3D; #define glCopyTextureSubImage3D glad_glCopyTextureSubImage3D -GLAD_API_CALL PFNGLEDGEFLAGPROC glad_glEdgeFlag; + GLAD_API_CALL PFNGLEDGEFLAGPROC glad_glEdgeFlag; #define glEdgeFlag glad_glEdgeFlag -GLAD_API_CALL PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; + GLAD_API_CALL PFNGLGETBUFFERPARAMETERI64VPROC glad_glGetBufferParameteri64v; #define glGetBufferParameteri64v glad_glGetBufferParameteri64v -GLAD_API_CALL PFNGLRASTERPOS2IVPROC glad_glRasterPos2iv; + GLAD_API_CALL PFNGLRASTERPOS2IVPROC glad_glRasterPos2iv; #define glRasterPos2iv glad_glRasterPos2iv -GLAD_API_CALL PFNGLGETNMAPIVPROC glad_glGetnMapiv; + GLAD_API_CALL PFNGLGETNMAPIVPROC glad_glGetnMapiv; #define glGetnMapiv glad_glGetnMapiv -GLAD_API_CALL PFNGLRECTDVPROC glad_glRectdv; + GLAD_API_CALL PFNGLRECTDVPROC glad_glRectdv; #define glRectdv glad_glRectdv -GLAD_API_CALL PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; + GLAD_API_CALL PFNGLGETBOOLEANI_VPROC glad_glGetBooleani_v; #define glGetBooleani_v glad_glGetBooleani_v -GLAD_API_CALL PFNGLENDLISTPROC glad_glEndList; + GLAD_API_CALL PFNGLENDLISTPROC glad_glEndList; #define glEndList glad_glEndList -GLAD_API_CALL PFNGLFLUSHPROC glad_glFlush; + GLAD_API_CALL PFNGLFLUSHPROC glad_glFlush; #define glFlush glad_glFlush -GLAD_API_CALL PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui; + GLAD_API_CALL PFNGLPROGRAMUNIFORM4UIPROC glad_glProgramUniform4ui; #define glProgramUniform4ui glad_glProgramUniform4ui -GLAD_API_CALL PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC glad_glMultiDrawElementsIndirectCount; + GLAD_API_CALL PFNGLMULTIDRAWELEMENTSINDIRECTCOUNTPROC glad_glMultiDrawElementsIndirectCount; #define glMultiDrawElementsIndirectCount glad_glMultiDrawElementsIndirectCount -GLAD_API_CALL PFNGLGETINTEGER64VPROC glad_glGetInteger64v; + GLAD_API_CALL PFNGLGETINTEGER64VPROC glad_glGetInteger64v; #define glGetInteger64v glad_glGetInteger64v -GLAD_API_CALL PFNGLLIGHTMODELFPROC glad_glLightModelf; + GLAD_API_CALL PFNGLLIGHTMODELFPROC glad_glLightModelf; #define glLightModelf glad_glLightModelf -GLAD_API_CALL PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv; + GLAD_API_CALL PFNGLVERTEXATTRIB4NIVPROC glad_glVertexAttrib4Niv; #define glVertexAttrib4Niv glad_glVertexAttrib4Niv -GLAD_API_CALL PFNGLGETTEXTURELEVELPARAMETERIVPROC glad_glGetTextureLevelParameteriv; + GLAD_API_CALL PFNGLGETTEXTURELEVELPARAMETERIVPROC glad_glGetTextureLevelParameteriv; #define glGetTextureLevelParameteriv glad_glGetTextureLevelParameteriv -GLAD_API_CALL PFNGLLOADMATRIXDPROC glad_glLoadMatrixd; + GLAD_API_CALL PFNGLLOADMATRIXDPROC glad_glLoadMatrixd; #define glLoadMatrixd glad_glLoadMatrixd -GLAD_API_CALL PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline; + GLAD_API_CALL PFNGLBINDPROGRAMPIPELINEPROC glad_glBindProgramPipeline; #define glBindProgramPipeline glad_glBindProgramPipeline -GLAD_API_CALL PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv; + GLAD_API_CALL PFNGLPROGRAMUNIFORM1UIVPROC glad_glProgramUniform1uiv; #define glProgramUniform1uiv glad_glProgramUniform1uiv -GLAD_API_CALL PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; + GLAD_API_CALL PFNGLDISABLEVERTEXATTRIBARRAYPROC glad_glDisableVertexAttribArray; #define glDisableVertexAttribArray glad_glDisableVertexAttribArray -GLAD_API_CALL PFNGLCLEARDEPTHPROC glad_glClearDepth; + GLAD_API_CALL PFNGLCLEARDEPTHPROC glad_glClearDepth; #define glClearDepth glad_glClearDepth -GLAD_API_CALL PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv; + GLAD_API_CALL PFNGLGETTEXPARAMETERIIVPROC glad_glGetTexParameterIiv; #define glGetTexParameterIiv glad_glGetTexParameterIiv -GLAD_API_CALL PFNGLWINDOWPOS3FVPROC glad_glWindowPos3fv; + GLAD_API_CALL PFNGLWINDOWPOS3FVPROC glad_glWindowPos3fv; #define glWindowPos3fv glad_glWindowPos3fv -GLAD_API_CALL PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d; + GLAD_API_CALL PFNGLVERTEXATTRIB3DPROC glad_glVertexAttrib3d; #define glVertexAttrib3d glad_glVertexAttrib3d -GLAD_API_CALL PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation; + GLAD_API_CALL PFNGLGETPROGRAMRESOURCELOCATIONPROC glad_glGetProgramResourceLocation; #define glGetProgramResourceLocation glad_glGetProgramResourceLocation -GLAD_API_CALL PFNGLTEXCOORD2DPROC glad_glTexCoord2d; + GLAD_API_CALL PFNGLTEXCOORD2DPROC glad_glTexCoord2d; #define glTexCoord2d glad_glTexCoord2d -GLAD_API_CALL PFNGLACCUMPROC glad_glAccum; + GLAD_API_CALL PFNGLACCUMPROC glad_glAccum; #define glAccum glad_glAccum -GLAD_API_CALL PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui; + GLAD_API_CALL PFNGLSECONDARYCOLORP3UIPROC glad_glSecondaryColorP3ui; #define glSecondaryColorP3ui glad_glSecondaryColorP3ui -GLAD_API_CALL PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui; + GLAD_API_CALL PFNGLVERTEXATTRIBI2UIPROC glad_glVertexAttribI2ui; #define glVertexAttribI2ui glad_glVertexAttribI2ui -GLAD_API_CALL PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv; + GLAD_API_CALL PFNGLGETNUNIFORMFVPROC glad_glGetnUniformfv; #define glGetnUniformfv glad_glGetnUniformfv -GLAD_API_CALL PFNGLFOGIPROC glad_glFogi; + GLAD_API_CALL PFNGLFOGIPROC glad_glFogi; #define glFogi glad_glFogi -GLAD_API_CALL PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; + GLAD_API_CALL PFNGLCLEARBUFFERFVPROC glad_glClearBufferfv; #define glClearBufferfv glad_glClearBufferfv -GLAD_API_CALL PFNGLTEXENVIVPROC glad_glTexEnviv; + GLAD_API_CALL PFNGLTEXENVIVPROC glad_glTexEnviv; #define glTexEnviv glad_glTexEnviv -GLAD_API_CALL PFNGLTEXIMAGE2DPROC glad_glTexImage2D; + GLAD_API_CALL PFNGLTEXIMAGE2DPROC glad_glTexImage2D; #define glTexImage2D glad_glTexImage2D -GLAD_API_CALL PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glad_glGetActiveAtomicCounterBufferiv; + GLAD_API_CALL PFNGLGETACTIVEATOMICCOUNTERBUFFERIVPROC glad_glGetActiveAtomicCounterBufferiv; #define glGetActiveAtomicCounterBufferiv glad_glGetActiveAtomicCounterBufferiv -GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv; + GLAD_API_CALL PFNGLPROGRAMUNIFORMMATRIX4X3FVPROC glad_glProgramUniformMatrix4x3fv; #define glProgramUniformMatrix4x3fv glad_glProgramUniformMatrix4x3fv -GLAD_API_CALL PFNGLMULTITEXCOORD1FVPROC glad_glMultiTexCoord1fv; + GLAD_API_CALL PFNGLMULTITEXCOORD1FVPROC glad_glMultiTexCoord1fv; #define glMultiTexCoord1fv glad_glMultiTexCoord1fv -GLAD_API_CALL PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel; + GLAD_API_CALL PFNGLGETOBJECTPTRLABELPROC glad_glGetObjectPtrLabel; #define glGetObjectPtrLabel glad_glGetObjectPtrLabel - -GLAD_API_CALL int gladLoadGLUserPtr( GLADuserptrloadfunc load, void *userptr); -GLAD_API_CALL int gladLoadGL( GLADloadfunc load); - - - - + GLAD_API_CALL int gladLoadGLUserPtr(GLADuserptrloadfunc load, void *userptr); + GLAD_API_CALL int gladLoadGL(GLADloadfunc load); #ifdef GLAD_GL -GLAD_API_CALL int gladLoaderLoadGL(void); + GLAD_API_CALL int gladLoaderLoadGL(void); #endif diff --git a/examples/ThirdPartyLibs/glad/glad/glx.h b/examples/ThirdPartyLibs/glad/glad/glx.h index 5ccf8cde9..a0401e836 100644 --- a/examples/ThirdPartyLibs/glad/glad/glx.h +++ b/examples/ThirdPartyLibs/glad/glad/glx.h @@ -28,11 +28,10 @@ #define GLAD_GLX_H_ #ifdef GLX_H - #error GLX header already included (API: glx), remove previous include! +#error GLX header already included (API: glx), remove previous include! #endif #define GLX_H 1 - #include #include #include @@ -43,94 +42,93 @@ #define GLAD_OPTION_GLX_LOADER #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #ifndef GLAD_PLATFORM_H_ #define GLAD_PLATFORM_H_ #if defined(_WIN32) || defined(__WIN32__) || defined(WIN32) || defined(__MINGW32__) - #define GLAD_PLATFORM_WIN32 1 +#define GLAD_PLATFORM_WIN32 1 #else - #define GLAD_PLATFORM_WIN32 0 +#define GLAD_PLATFORM_WIN32 0 #endif +#ifndef GLAD_PLATFORM_UWP +#if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY) +#ifdef __has_include +#if __has_include() +#define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 +#endif +#elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ +#define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 +#endif +#endif + +#ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY +#include +#if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) +#define GLAD_PLATFORM_UWP 1 +#endif +#endif #ifndef GLAD_PLATFORM_UWP - #if defined(_MSC_VER) && !defined(GLAD_INTERNAL_HAVE_WINAPIFAMILY) - #ifdef __has_include - #if __has_include() - #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 - #endif - #elif _MSC_VER >= 1700 && !_USING_V110_SDK71_ - #define GLAD_INTERNAL_HAVE_WINAPIFAMILY 1 - #endif - #endif - - #ifdef GLAD_INTERNAL_HAVE_WINAPIFAMILY - #include - #if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP) - #define GLAD_PLATFORM_UWP 1 - #endif - #endif - - #ifndef GLAD_PLATFORM_UWP - #define GLAD_PLATFORM_UWP 0 - #endif +#define GLAD_PLATFORM_UWP 0 +#endif #endif #ifdef __GNUC__ - #define GLAD_GNUC_EXTENSION __extension__ +#define GLAD_GNUC_EXTENSION __extension__ #else - #define GLAD_GNUC_EXTENSION +#define GLAD_GNUC_EXTENSION #endif #ifndef GLAD_API_CALL - #if defined(GLAD_API_CALL_EXPORT) - #if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) - #if defined(GLAD_API_CALL_EXPORT_BUILD) - #if defined(__GNUC__) - #define GLAD_API_CALL __attribute__ ((dllexport)) extern - #else - #define GLAD_API_CALL __declspec(dllexport) extern - #endif - #else - #if defined(__GNUC__) - #define GLAD_API_CALL __attribute__ ((dllimport)) extern - #else - #define GLAD_API_CALL __declspec(dllimport) extern - #endif - #endif - #elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD) - #define GLAD_API_CALL __attribute__ ((visibility ("default"))) extern - #else - #define GLAD_API_CALL extern - #endif - #else - #define GLAD_API_CALL extern - #endif +#if defined(GLAD_API_CALL_EXPORT) +#if GLAD_PLATFORM_WIN32 || defined(__CYGWIN__) +#if defined(GLAD_API_CALL_EXPORT_BUILD) +#if defined(__GNUC__) +#define GLAD_API_CALL __attribute__((dllexport)) extern +#else +#define GLAD_API_CALL __declspec(dllexport) extern +#endif +#else +#if defined(__GNUC__) +#define GLAD_API_CALL __attribute__((dllimport)) extern +#else +#define GLAD_API_CALL __declspec(dllimport) extern +#endif +#endif +#elif defined(__GNUC__) && defined(GLAD_API_CALL_EXPORT_BUILD) +#define GLAD_API_CALL __attribute__((visibility("default"))) extern +#else +#define GLAD_API_CALL extern +#endif +#else +#define GLAD_API_CALL extern +#endif #endif #ifdef APIENTRY - #define GLAD_API_PTR APIENTRY +#define GLAD_API_PTR APIENTRY #elif GLAD_PLATFORM_WIN32 - #define GLAD_API_PTR __stdcall +#define GLAD_API_PTR __stdcall #else - #define GLAD_API_PTR +#define GLAD_API_PTR #endif - #define GLAD_MAKE_VERSION(major, minor) (major * 10000 + minor) #define GLAD_VERSION_MAJOR(version) (version / 10000) #define GLAD_VERSION_MINOR(version) (version % 10000) -typedef void (*GLADapiproc)(void); + typedef void (*GLADapiproc)(void); -typedef GLADapiproc (*GLADloadfunc)(const char *name); -typedef GLADapiproc (*GLADuserptrloadfunc)(const char *name, void *userptr); + typedef GLADapiproc (*GLADloadfunc)(const char *name); + typedef GLADapiproc (*GLADuserptrloadfunc)(const char *name, void *userptr); -typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...); -typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...); + typedef void (*GLADprecallback)(const char *name, GLADapiproc apiproc, int len_args, ...); + typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apiproc, int len_args, ...); #endif /* GLAD_PLATFORM_H_ */ @@ -420,7 +418,6 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro #define GLX_RGBA_BIT 0x00000001 #define GLX_VERSION 0x2 - #ifndef GLEXT_64_TYPES_DEFINED /* This code block is duplicated in glext.h, so must be protected */ #define GLEXT_64_TYPES_DEFINED @@ -432,48 +429,33 @@ typedef void (*GLADpostcallback)(void *ret, const char *name, GLADapiproc apipro #include #if defined(__STDC__) #if defined(__arch64__) || defined(_LP64) -typedef long int int64_t; -typedef unsigned long int uint64_t; + typedef long int int64_t; + typedef unsigned long int uint64_t; #else -typedef long long int int64_t; -typedef unsigned long long int uint64_t; + typedef long long int int64_t; + typedef unsigned long long int uint64_t; #endif /* __arch64__ */ #endif /* __STDC__ */ -#elif defined( __VMS ) || defined(__sgi) +#elif defined(__VMS) || defined(__sgi) #include #elif defined(__SCO__) || defined(__USLC__) #include #elif defined(__UNIXOS2__) || defined(__SOL64__) -typedef long int int32_t; -typedef long long int int64_t; -typedef unsigned long long int uint64_t; + typedef long int int32_t; + typedef long long int int64_t; + typedef unsigned long long int uint64_t; #elif defined(_WIN32) && defined(__GNUC__) #include #elif defined(_WIN32) -typedef __int32 int32_t; -typedef __int64 int64_t; -typedef unsigned __int64 uint64_t; + typedef __int32 int32_t; + typedef __int64 int64_t; + typedef unsigned __int64 uint64_t; #else /* Fallback if nothing above works */ #include #endif #endif - - - - - - - - - - - - - - - #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && (__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ > 1060) #else @@ -486,645 +468,641 @@ typedef unsigned __int64 uint64_t; #endif - - - - - - -typedef XID GLXFBConfigID; -typedef struct __GLXFBConfigRec *GLXFBConfig; -typedef XID GLXContextID; -typedef struct __GLXcontextRec *GLXContext; -typedef XID GLXPixmap; -typedef XID GLXDrawable; -typedef XID GLXWindow; -typedef XID GLXPbuffer; -typedef void (GLAD_API_PTR *__GLXextFuncPtr)(void); -typedef XID GLXVideoCaptureDeviceNV; -typedef unsigned int GLXVideoDeviceNV; -typedef XID GLXVideoSourceSGIX; -typedef XID GLXFBConfigIDSGIX; -typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; -typedef XID GLXPbufferSGIX; -typedef struct { - int event_type; /* GLX_DAMAGED or GLX_SAVED */ - int draw_type; /* GLX_WINDOW or GLX_PBUFFER */ - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came for SendEvent request */ - Display *display; /* display the event was read from */ - GLXDrawable drawable; /* XID of Drawable */ - unsigned int buffer_mask; /* mask indicating which buffers are affected */ - unsigned int aux_buffer; /* which aux buffer was affected */ - int x, y; - int width, height; - int count; /* if nonzero, at least this many more */ -} GLXPbufferClobberEvent; -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - GLXDrawable drawable; /* drawable on which event was requested in event mask */ - int event_type; - int64_t ust; - int64_t msc; - int64_t sbc; -} GLXBufferSwapComplete; -typedef union __GLXEvent { - GLXPbufferClobberEvent glxpbufferclobber; - GLXBufferSwapComplete glxbufferswapcomplete; - long pad[24]; -} GLXEvent; -typedef struct { - int type; - unsigned long serial; - Bool send_event; - Display *display; - int extension; - int evtype; - GLXDrawable window; - Bool stereo_tree; -} GLXStereoNotifyEventEXT; -typedef struct { - int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came for SendEvent request */ - Display *display; /* display the event was read from */ - GLXDrawable drawable; /* i.d. of Drawable */ - int event_type; /* GLX_DAMAGED_SGIX or GLX_SAVED_SGIX */ - int draw_type; /* GLX_WINDOW_SGIX or GLX_PBUFFER_SGIX */ - unsigned int mask; /* mask indicating which buffers are affected*/ - int x, y; - int width, height; - int count; /* if nonzero, at least this many more */ -} GLXBufferClobberEventSGIX; -typedef struct { - char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ - int networkId; -} GLXHyperpipeNetworkSGIX; -typedef struct { - char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ - int channel; - unsigned int participationType; - int timeSlice; -} GLXHyperpipeConfigSGIX; -typedef struct { - char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ - int srcXOrigin, srcYOrigin, srcWidth, srcHeight; - int destXOrigin, destYOrigin, destWidth, destHeight; -} GLXPipeRect; -typedef struct { - char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ - int XOrigin, YOrigin, maxHeight, maxWidth; -} GLXPipeRectLimits; - + typedef XID GLXFBConfigID; + typedef struct __GLXFBConfigRec *GLXFBConfig; + typedef XID GLXContextID; + typedef struct __GLXcontextRec *GLXContext; + typedef XID GLXPixmap; + typedef XID GLXDrawable; + typedef XID GLXWindow; + typedef XID GLXPbuffer; + typedef void(GLAD_API_PTR *__GLXextFuncPtr)(void); + typedef XID GLXVideoCaptureDeviceNV; + typedef unsigned int GLXVideoDeviceNV; + typedef XID GLXVideoSourceSGIX; + typedef XID GLXFBConfigIDSGIX; + typedef struct __GLXFBConfigRec *GLXFBConfigSGIX; + typedef XID GLXPbufferSGIX; + typedef struct + { + int event_type; /* GLX_DAMAGED or GLX_SAVED */ + int draw_type; /* GLX_WINDOW or GLX_PBUFFER */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came for SendEvent request */ + Display *display; /* display the event was read from */ + GLXDrawable drawable; /* XID of Drawable */ + unsigned int buffer_mask; /* mask indicating which buffers are affected */ + unsigned int aux_buffer; /* which aux buffer was affected */ + int x, y; + int width, height; + int count; /* if nonzero, at least this many more */ + } GLXPbufferClobberEvent; + typedef struct + { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + GLXDrawable drawable; /* drawable on which event was requested in event mask */ + int event_type; + int64_t ust; + int64_t msc; + int64_t sbc; + } GLXBufferSwapComplete; + typedef union __GLXEvent { + GLXPbufferClobberEvent glxpbufferclobber; + GLXBufferSwapComplete glxbufferswapcomplete; + long pad[24]; + } GLXEvent; + typedef struct + { + int type; + unsigned long serial; + Bool send_event; + Display *display; + int extension; + int evtype; + GLXDrawable window; + Bool stereo_tree; + } GLXStereoNotifyEventEXT; + typedef struct + { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came for SendEvent request */ + Display *display; /* display the event was read from */ + GLXDrawable drawable; /* i.d. of Drawable */ + int event_type; /* GLX_DAMAGED_SGIX or GLX_SAVED_SGIX */ + int draw_type; /* GLX_WINDOW_SGIX or GLX_PBUFFER_SGIX */ + unsigned int mask; /* mask indicating which buffers are affected*/ + int x, y; + int width, height; + int count; /* if nonzero, at least this many more */ + } GLXBufferClobberEventSGIX; + typedef struct + { + char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ + int networkId; + } GLXHyperpipeNetworkSGIX; + typedef struct + { + char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ + int channel; + unsigned int participationType; + int timeSlice; + } GLXHyperpipeConfigSGIX; + typedef struct + { + char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ + int srcXOrigin, srcYOrigin, srcWidth, srcHeight; + int destXOrigin, destYOrigin, destWidth, destHeight; + } GLXPipeRect; + typedef struct + { + char pipeName[80]; /* Should be [GLX_HYPERPIPE_PIPE_NAME_LENGTH_SGIX] */ + int XOrigin, YOrigin, maxHeight, maxWidth; + } GLXPipeRectLimits; #define GLX_VERSION_1_0 1 -GLAD_API_CALL int GLAD_GLX_VERSION_1_0; + GLAD_API_CALL int GLAD_GLX_VERSION_1_0; #define GLX_VERSION_1_1 1 -GLAD_API_CALL int GLAD_GLX_VERSION_1_1; + GLAD_API_CALL int GLAD_GLX_VERSION_1_1; #define GLX_VERSION_1_2 1 -GLAD_API_CALL int GLAD_GLX_VERSION_1_2; + GLAD_API_CALL int GLAD_GLX_VERSION_1_2; #define GLX_VERSION_1_3 1 -GLAD_API_CALL int GLAD_GLX_VERSION_1_3; + GLAD_API_CALL int GLAD_GLX_VERSION_1_3; #define GLX_VERSION_1_4 1 -GLAD_API_CALL int GLAD_GLX_VERSION_1_4; + GLAD_API_CALL int GLAD_GLX_VERSION_1_4; #define GLX_MESA_copy_sub_buffer 1 -GLAD_API_CALL int GLAD_GLX_MESA_copy_sub_buffer; + GLAD_API_CALL int GLAD_GLX_MESA_copy_sub_buffer; #define GLX_EXT_create_context_es_profile 1 -GLAD_API_CALL int GLAD_GLX_EXT_create_context_es_profile; + GLAD_API_CALL int GLAD_GLX_EXT_create_context_es_profile; #define GLX_SGIX_pbuffer 1 -GLAD_API_CALL int GLAD_GLX_SGIX_pbuffer; + GLAD_API_CALL int GLAD_GLX_SGIX_pbuffer; #define GLX_SGI_make_current_read 1 -GLAD_API_CALL int GLAD_GLX_SGI_make_current_read; + GLAD_API_CALL int GLAD_GLX_SGI_make_current_read; #define GLX_OML_sync_control 1 -GLAD_API_CALL int GLAD_GLX_OML_sync_control; + GLAD_API_CALL int GLAD_GLX_OML_sync_control; #define GLX_SGIX_hyperpipe 1 -GLAD_API_CALL int GLAD_GLX_SGIX_hyperpipe; + GLAD_API_CALL int GLAD_GLX_SGIX_hyperpipe; #define GLX_INTEL_swap_event 1 -GLAD_API_CALL int GLAD_GLX_INTEL_swap_event; + GLAD_API_CALL int GLAD_GLX_INTEL_swap_event; #define GLX_EXT_swap_control 1 -GLAD_API_CALL int GLAD_GLX_EXT_swap_control; + GLAD_API_CALL int GLAD_GLX_EXT_swap_control; #define GLX_NV_robustness_video_memory_purge 1 -GLAD_API_CALL int GLAD_GLX_NV_robustness_video_memory_purge; + GLAD_API_CALL int GLAD_GLX_NV_robustness_video_memory_purge; #define GLX_MESA_pixmap_colormap 1 -GLAD_API_CALL int GLAD_GLX_MESA_pixmap_colormap; + GLAD_API_CALL int GLAD_GLX_MESA_pixmap_colormap; #define GLX_ARB_fbconfig_float 1 -GLAD_API_CALL int GLAD_GLX_ARB_fbconfig_float; + GLAD_API_CALL int GLAD_GLX_ARB_fbconfig_float; #define GLX_EXT_fbconfig_packed_float 1 -GLAD_API_CALL int GLAD_GLX_EXT_fbconfig_packed_float; + GLAD_API_CALL int GLAD_GLX_EXT_fbconfig_packed_float; #define GLX_OML_swap_method 1 -GLAD_API_CALL int GLAD_GLX_OML_swap_method; + GLAD_API_CALL int GLAD_GLX_OML_swap_method; #define GLX_NV_video_capture 1 -GLAD_API_CALL int GLAD_GLX_NV_video_capture; + GLAD_API_CALL int GLAD_GLX_NV_video_capture; #define GLX_ARB_robustness_application_isolation 1 -GLAD_API_CALL int GLAD_GLX_ARB_robustness_application_isolation; + GLAD_API_CALL int GLAD_GLX_ARB_robustness_application_isolation; #define GLX_ARB_create_context_robustness 1 -GLAD_API_CALL int GLAD_GLX_ARB_create_context_robustness; + GLAD_API_CALL int GLAD_GLX_ARB_create_context_robustness; #define GLX_EXT_visual_rating 1 -GLAD_API_CALL int GLAD_GLX_EXT_visual_rating; + GLAD_API_CALL int GLAD_GLX_EXT_visual_rating; #define GLX_NV_swap_group 1 -GLAD_API_CALL int GLAD_GLX_NV_swap_group; + GLAD_API_CALL int GLAD_GLX_NV_swap_group; #define GLX_EXT_texture_from_pixmap 1 -GLAD_API_CALL int GLAD_GLX_EXT_texture_from_pixmap; + GLAD_API_CALL int GLAD_GLX_EXT_texture_from_pixmap; #define GLX_SUN_get_transparent_index 1 -GLAD_API_CALL int GLAD_GLX_SUN_get_transparent_index; + GLAD_API_CALL int GLAD_GLX_SUN_get_transparent_index; #define GLX_MESA_release_buffers 1 -GLAD_API_CALL int GLAD_GLX_MESA_release_buffers; + GLAD_API_CALL int GLAD_GLX_MESA_release_buffers; #define GLX_NV_delay_before_swap 1 -GLAD_API_CALL int GLAD_GLX_NV_delay_before_swap; + GLAD_API_CALL int GLAD_GLX_NV_delay_before_swap; #define GLX_EXT_buffer_age 1 -GLAD_API_CALL int GLAD_GLX_EXT_buffer_age; + GLAD_API_CALL int GLAD_GLX_EXT_buffer_age; #define GLX_MESA_agp_offset 1 -GLAD_API_CALL int GLAD_GLX_MESA_agp_offset; + GLAD_API_CALL int GLAD_GLX_MESA_agp_offset; #define GLX_EXT_visual_info 1 -GLAD_API_CALL int GLAD_GLX_EXT_visual_info; + GLAD_API_CALL int GLAD_GLX_EXT_visual_info; #define GLX_SGI_swap_control 1 -GLAD_API_CALL int GLAD_GLX_SGI_swap_control; + GLAD_API_CALL int GLAD_GLX_SGI_swap_control; #define GLX_EXT_import_context 1 -GLAD_API_CALL int GLAD_GLX_EXT_import_context; + GLAD_API_CALL int GLAD_GLX_EXT_import_context; #define GLX_SGI_video_sync 1 -GLAD_API_CALL int GLAD_GLX_SGI_video_sync; + GLAD_API_CALL int GLAD_GLX_SGI_video_sync; #define GLX_3DFX_multisample 1 -GLAD_API_CALL int GLAD_GLX_3DFX_multisample; + GLAD_API_CALL int GLAD_GLX_3DFX_multisample; #define GLX_ARB_multisample 1 -GLAD_API_CALL int GLAD_GLX_ARB_multisample; + GLAD_API_CALL int GLAD_GLX_ARB_multisample; #define GLX_EXT_framebuffer_sRGB 1 -GLAD_API_CALL int GLAD_GLX_EXT_framebuffer_sRGB; + GLAD_API_CALL int GLAD_GLX_EXT_framebuffer_sRGB; #define GLX_SGI_cushion 1 -GLAD_API_CALL int GLAD_GLX_SGI_cushion; + GLAD_API_CALL int GLAD_GLX_SGI_cushion; #define GLX_ARB_robustness_share_group_isolation 1 -GLAD_API_CALL int GLAD_GLX_ARB_robustness_share_group_isolation; + GLAD_API_CALL int GLAD_GLX_ARB_robustness_share_group_isolation; #define GLX_SGIX_fbconfig 1 -GLAD_API_CALL int GLAD_GLX_SGIX_fbconfig; + GLAD_API_CALL int GLAD_GLX_SGIX_fbconfig; #define GLX_NV_copy_buffer 1 -GLAD_API_CALL int GLAD_GLX_NV_copy_buffer; + GLAD_API_CALL int GLAD_GLX_NV_copy_buffer; #define GLX_SGIX_visual_select_group 1 -GLAD_API_CALL int GLAD_GLX_SGIX_visual_select_group; + GLAD_API_CALL int GLAD_GLX_SGIX_visual_select_group; #define GLX_EXT_swap_control_tear 1 -GLAD_API_CALL int GLAD_GLX_EXT_swap_control_tear; + GLAD_API_CALL int GLAD_GLX_EXT_swap_control_tear; #define GLX_ARB_create_context 1 -GLAD_API_CALL int GLAD_GLX_ARB_create_context; + GLAD_API_CALL int GLAD_GLX_ARB_create_context; #define GLX_AMD_gpu_association 1 -GLAD_API_CALL int GLAD_GLX_AMD_gpu_association; + GLAD_API_CALL int GLAD_GLX_AMD_gpu_association; #define GLX_MESA_query_renderer 1 -GLAD_API_CALL int GLAD_GLX_MESA_query_renderer; + GLAD_API_CALL int GLAD_GLX_MESA_query_renderer; #define GLX_EXT_create_context_es2_profile 1 -GLAD_API_CALL int GLAD_GLX_EXT_create_context_es2_profile; + GLAD_API_CALL int GLAD_GLX_EXT_create_context_es2_profile; #define GLX_MESA_swap_control 1 -GLAD_API_CALL int GLAD_GLX_MESA_swap_control; + GLAD_API_CALL int GLAD_GLX_MESA_swap_control; #define GLX_SGIX_video_resize 1 -GLAD_API_CALL int GLAD_GLX_SGIX_video_resize; + GLAD_API_CALL int GLAD_GLX_SGIX_video_resize; #define GLX_ARB_context_flush_control 1 -GLAD_API_CALL int GLAD_GLX_ARB_context_flush_control; + GLAD_API_CALL int GLAD_GLX_ARB_context_flush_control; #define GLX_NV_video_out 1 -GLAD_API_CALL int GLAD_GLX_NV_video_out; + GLAD_API_CALL int GLAD_GLX_NV_video_out; #define GLX_EXT_no_config_context 1 -GLAD_API_CALL int GLAD_GLX_EXT_no_config_context; + GLAD_API_CALL int GLAD_GLX_EXT_no_config_context; #define GLX_SGIS_blended_overlay 1 -GLAD_API_CALL int GLAD_GLX_SGIS_blended_overlay; + GLAD_API_CALL int GLAD_GLX_SGIS_blended_overlay; #define GLX_EXT_stereo_tree 1 -GLAD_API_CALL int GLAD_GLX_EXT_stereo_tree; + GLAD_API_CALL int GLAD_GLX_EXT_stereo_tree; #define GLX_ARB_create_context_no_error 1 -GLAD_API_CALL int GLAD_GLX_ARB_create_context_no_error; + GLAD_API_CALL int GLAD_GLX_ARB_create_context_no_error; #define GLX_EXT_libglvnd 1 -GLAD_API_CALL int GLAD_GLX_EXT_libglvnd; + GLAD_API_CALL int GLAD_GLX_EXT_libglvnd; #define GLX_ARB_create_context_profile 1 -GLAD_API_CALL int GLAD_GLX_ARB_create_context_profile; + GLAD_API_CALL int GLAD_GLX_ARB_create_context_profile; #define GLX_NV_float_buffer 1 -GLAD_API_CALL int GLAD_GLX_NV_float_buffer; + GLAD_API_CALL int GLAD_GLX_NV_float_buffer; #define GLX_MESA_set_3dfx_mode 1 -GLAD_API_CALL int GLAD_GLX_MESA_set_3dfx_mode; + GLAD_API_CALL int GLAD_GLX_MESA_set_3dfx_mode; #define GLX_ARB_framebuffer_sRGB 1 -GLAD_API_CALL int GLAD_GLX_ARB_framebuffer_sRGB; + GLAD_API_CALL int GLAD_GLX_ARB_framebuffer_sRGB; #define GLX_ARB_get_proc_address 1 -GLAD_API_CALL int GLAD_GLX_ARB_get_proc_address; + GLAD_API_CALL int GLAD_GLX_ARB_get_proc_address; #define GLX_SGIS_shared_multisample 1 -GLAD_API_CALL int GLAD_GLX_SGIS_shared_multisample; + GLAD_API_CALL int GLAD_GLX_SGIS_shared_multisample; #define GLX_NV_copy_image 1 -GLAD_API_CALL int GLAD_GLX_NV_copy_image; + GLAD_API_CALL int GLAD_GLX_NV_copy_image; #define GLX_NV_present_video 1 -GLAD_API_CALL int GLAD_GLX_NV_present_video; + GLAD_API_CALL int GLAD_GLX_NV_present_video; #define GLX_SGIX_swap_barrier 1 -GLAD_API_CALL int GLAD_GLX_SGIX_swap_barrier; + GLAD_API_CALL int GLAD_GLX_SGIX_swap_barrier; #define GLX_SGIS_multisample 1 -GLAD_API_CALL int GLAD_GLX_SGIS_multisample; + GLAD_API_CALL int GLAD_GLX_SGIS_multisample; #define GLX_SGIX_swap_group 1 -GLAD_API_CALL int GLAD_GLX_SGIX_swap_group; + GLAD_API_CALL int GLAD_GLX_SGIX_swap_group; #define GLX_ARB_vertex_buffer_object 1 -GLAD_API_CALL int GLAD_GLX_ARB_vertex_buffer_object; + GLAD_API_CALL int GLAD_GLX_ARB_vertex_buffer_object; #define GLX_NV_multisample_coverage 1 -GLAD_API_CALL int GLAD_GLX_NV_multisample_coverage; + GLAD_API_CALL int GLAD_GLX_NV_multisample_coverage; + typedef void(GLAD_API_PTR *PFNGLXCUSHIONSGIPROC)(Display *dpy, Window window, float cushion); + typedef void(GLAD_API_PTR *PFNGLXDESTROYGLXPBUFFERSGIXPROC)(Display *dpy, GLXPbufferSGIX pbuf); + typedef int(GLAD_API_PTR *PFNGLXSENDPBUFFERTOVIDEONVPROC)(Display *dpy, GLXPbuffer pbuf, int iBufferType, unsigned long *pulCounterPbuffer, GLboolean bBlock); + typedef __GLXextFuncPtr(GLAD_API_PTR *PFNGLXGETPROCADDRESSARBPROC)(const GLubyte *procName); + typedef GLXContext(GLAD_API_PTR *PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display *dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int *attrib_list); + typedef void(GLAD_API_PTR *PFNGLXJOINSWAPGROUPSGIXPROC)(Display *dpy, GLXDrawable drawable, GLXDrawable member); + typedef void(GLAD_API_PTR *PFNGLXSWAPINTERVALEXTPROC)(Display *dpy, GLXDrawable drawable, int interval); + typedef GLXHyperpipeConfigSGIX *(GLAD_API_PTR *PFNGLXQUERYHYPERPIPECONFIGSGIXPROC)(Display *dpy, int hpId, int *npipes); + typedef int(GLAD_API_PTR *PFNGLXGETGPUINFOAMDPROC)(unsigned int id, int property, GLenum dataType, unsigned int size, void *data); + typedef Status(GLAD_API_PTR *PFNGLXGETTRANSPARENTINDEXSUNPROC)(Display *dpy, Window overlay, Window underlay, long *pTransparentIndex); + typedef GLXHyperpipeNetworkSGIX *(GLAD_API_PTR *PFNGLXQUERYHYPERPIPENETWORKSGIXPROC)(Display *dpy, int *npipes); + typedef int(GLAD_API_PTR *PFNGLXQUERYGLXPBUFFERSGIXPROC)(Display *dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int *value); + typedef GLXPixmap(GLAD_API_PTR *PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC)(Display *dpy, GLXFBConfigSGIX config, Pixmap pixmap); + typedef void(GLAD_API_PTR *PFNGLXCOPYCONTEXTPROC)(Display *dpy, GLXContext src, GLXContext dst, unsigned long mask); + typedef GLXPbufferSGIX(GLAD_API_PTR *PFNGLXCREATEGLXPBUFFERSGIXPROC)(Display *dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int *attrib_list); + typedef unsigned int(GLAD_API_PTR *PFNGLXGETGPUIDSAMDPROC)(unsigned int maxCount, unsigned int *ids); + typedef Bool(GLAD_API_PTR *PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC)(GLXContext ctx); + typedef int(GLAD_API_PTR *PFNGLXGETVIDEODEVICENVPROC)(Display *dpy, int screen, int numVideoDevices, GLXVideoDeviceNV *pVideoDevice); + typedef void(GLAD_API_PTR *PFNGLXWAITGLPROC)(void); + typedef int(GLAD_API_PTR *PFNGLXGETVIDEOSYNCSGIPROC)(unsigned int *count); + typedef int(GLAD_API_PTR *PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC)(Display *dpy, int hpId); + typedef int(GLAD_API_PTR *PFNGLXHYPERPIPECONFIGSGIXPROC)(Display *dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX *cfg, int *hpId); + typedef int64_t(GLAD_API_PTR *PFNGLXSWAPBUFFERSMSCOMLPROC)(Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); + typedef GLXFBConfigSGIX *(GLAD_API_PTR *PFNGLXCHOOSEFBCONFIGSGIXPROC)(Display *dpy, int screen, int *attrib_list, int *nelements); + typedef int(GLAD_API_PTR *PFNGLXWAITVIDEOSYNCSGIPROC)(int divisor, int remainder, unsigned int *count); + typedef Bool(GLAD_API_PTR *PFNGLXWAITFORSBCOMLPROC)(Display *dpy, GLXDrawable drawable, int64_t target_sbc, int64_t *ust, int64_t *msc, int64_t *sbc); + typedef __GLXextFuncPtr(GLAD_API_PTR *PFNGLXGETPROCADDRESSPROC)(const GLubyte *procName); + typedef int(GLAD_API_PTR *PFNGLXGETSWAPINTERVALMESAPROC)(void); + typedef int(GLAD_API_PTR *PFNGLXCHANNELRECTSGIXPROC)(Display *display, int screen, int channel, int x, int y, int w, int h); + typedef void(GLAD_API_PTR *PFNGLXWAITXPROC)(void); + typedef const char *(GLAD_API_PTR *PFNGLXQUERYSERVERSTRINGPROC)(Display *dpy, int screen, int name); + typedef GLXPixmap(GLAD_API_PTR *PFNGLXCREATEGLXPIXMAPPROC)(Display *dpy, XVisualInfo *visual, Pixmap pixmap); + typedef Bool(GLAD_API_PTR *PFNGLXBINDSWAPBARRIERNVPROC)(Display *dpy, GLuint group, GLuint barrier); + typedef const char *(GLAD_API_PTR *PFNGLXQUERYRENDERERSTRINGMESAPROC)(Display *dpy, int screen, int renderer, int attribute); + typedef void(GLAD_API_PTR *PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC)(Display *dpy, GLXVideoCaptureDeviceNV device); + typedef Bool(GLAD_API_PTR *PFNGLXWAITFORMSCOMLPROC)(Display *dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t *ust, int64_t *msc, int64_t *sbc); + typedef void(GLAD_API_PTR *PFNGLXCOPYSUBBUFFERMESAPROC)(Display *dpy, GLXDrawable drawable, int x, int y, int width, int height); + typedef GLXContext(GLAD_API_PTR *PFNGLXGETCURRENTCONTEXTPROC)(void); + typedef void(GLAD_API_PTR *PFNGLXSELECTEVENTPROC)(Display *dpy, GLXDrawable draw, unsigned long event_mask); + typedef int(GLAD_API_PTR *PFNGLXSWAPINTERVALSGIPROC)(int interval); + typedef Bool(GLAD_API_PTR *PFNGLXQUERYSWAPGROUPNVPROC)(Display *dpy, GLXDrawable drawable, GLuint *group, GLuint *barrier); + typedef Bool(GLAD_API_PTR *PFNGLXMAKECURRENTREADSGIPROC)(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); + typedef void(GLAD_API_PTR *PFNGLXQUERYDRAWABLEPROC)(Display *dpy, GLXDrawable draw, int attribute, unsigned int *value); + typedef void(GLAD_API_PTR *PFNGLXCOPYBUFFERSUBDATANVPROC)(Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + typedef int(GLAD_API_PTR *PFNGLXQUERYCONTEXTPROC)(Display *dpy, GLXContext ctx, int attribute, int *value); + typedef int(GLAD_API_PTR *PFNGLXGETCONFIGPROC)(Display *dpy, XVisualInfo *visual, int attrib, int *value); + typedef Bool(GLAD_API_PTR *PFNGLXSET3DFXMODEMESAPROC)(int mode); + typedef int(GLAD_API_PTR *PFNGLXGETVIDEOINFONVPROC)(Display *dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); + typedef Bool(GLAD_API_PTR *PFNGLXISDIRECTPROC)(Display *dpy, GLXContext ctx); + typedef int(GLAD_API_PTR *PFNGLXGETFBCONFIGATTRIBPROC)(Display *dpy, GLXFBConfig config, int attribute, int *value); + typedef XVisualInfo *(GLAD_API_PTR *PFNGLXGETVISUALFROMFBCONFIGPROC)(Display *dpy, GLXFBConfig config); + typedef void(GLAD_API_PTR *PFNGLXBINDTEXIMAGEEXTPROC)(Display *dpy, GLXDrawable drawable, int buffer, const int *attrib_list); + typedef void(GLAD_API_PTR *PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC)(GLXContext dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); + typedef Bool(GLAD_API_PTR *PFNGLXQUERYVERSIONPROC)(Display *dpy, int *maj, int *min); + typedef void(GLAD_API_PTR *PFNGLXSELECTEVENTSGIXPROC)(Display *dpy, GLXDrawable drawable, unsigned long mask); + typedef Bool(GLAD_API_PTR *PFNGLXGETMSCRATEOMLPROC)(Display *dpy, GLXDrawable drawable, int32_t *numerator, int32_t *denominator); + typedef Bool(GLAD_API_PTR *PFNGLXQUERYRENDERERINTEGERMESAPROC)(Display *dpy, int screen, int renderer, int attribute, unsigned int *value); + typedef GLXWindow(GLAD_API_PTR *PFNGLXCREATEWINDOWPROC)(Display *dpy, GLXFBConfig config, Window win, const int *attrib_list); + typedef void(GLAD_API_PTR *PFNGLXCOPYIMAGESUBDATANVPROC)(Display *dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); + typedef int(GLAD_API_PTR *PFNGLXSWAPINTERVALMESAPROC)(unsigned int interval); + typedef int(GLAD_API_PTR *PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC)(Display *dpy, int timeSlice, int attrib, int size, void *returnAttribList); + typedef int(GLAD_API_PTR *PFNGLXBINDVIDEOCAPTUREDEVICENVPROC)(Display *dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device); + typedef GLXContext(GLAD_API_PTR *PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC)(Display *dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct); + typedef unsigned int *(GLAD_API_PTR *PFNGLXENUMERATEVIDEODEVICESNVPROC)(Display *dpy, int screen, int *nelements); + typedef int(GLAD_API_PTR *PFNGLXHYPERPIPEATTRIBSGIXPROC)(Display *dpy, int timeSlice, int attrib, int size, void *attribList); + typedef void(GLAD_API_PTR *PFNGLXDESTROYPBUFFERPROC)(Display *dpy, GLXPbuffer pbuf); + typedef void(GLAD_API_PTR *PFNGLXNAMEDCOPYBUFFERSUBDATANVPROC)(Display *dpy, GLXContext readCtx, GLXContext writeCtx, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + typedef GLXPbuffer(GLAD_API_PTR *PFNGLXCREATEPBUFFERPROC)(Display *dpy, GLXFBConfig config, const int *attrib_list); + typedef const char *(GLAD_API_PTR *PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC)(int attribute); + typedef int(GLAD_API_PTR *PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC)(Display *dpy, int timeSlice, int attrib, int size, void *attribList, void *returnAttribList); + typedef int(GLAD_API_PTR *PFNGLXGETFBCONFIGATTRIBSGIXPROC)(Display *dpy, GLXFBConfigSGIX config, int attribute, int *value); + typedef const char *(GLAD_API_PTR *PFNGLXQUERYEXTENSIONSSTRINGPROC)(Display *dpy, int screen); + typedef int(GLAD_API_PTR *PFNGLXBINDVIDEODEVICENVPROC)(Display *dpy, unsigned int video_slot, unsigned int video_device, const int *attrib_list); + typedef GLXContext(GLAD_API_PTR *PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC)(unsigned int id, GLXContext share_list); + typedef int(GLAD_API_PTR *PFNGLXQUERYCONTEXTINFOEXTPROC)(Display *dpy, GLXContext context, int attribute, int *value); + typedef void(GLAD_API_PTR *PFNGLXGETSELECTEDEVENTPROC)(Display *dpy, GLXDrawable draw, unsigned long *event_mask); + typedef Display *(GLAD_API_PTR *PFNGLXGETCURRENTDISPLAYPROC)(void); + typedef void(GLAD_API_PTR *PFNGLXDESTROYPIXMAPPROC)(Display *dpy, GLXPixmap pixmap); + typedef void(GLAD_API_PTR *PFNGLXGETSELECTEDEVENTSGIXPROC)(Display *dpy, GLXDrawable drawable, unsigned long *mask); + typedef void(GLAD_API_PTR *PFNGLXRELEASETEXIMAGEEXTPROC)(Display *dpy, GLXDrawable drawable, int buffer); + typedef void(GLAD_API_PTR *PFNGLXUSEXFONTPROC)(Font font, int first, int count, int list); + typedef Bool(GLAD_API_PTR *PFNGLXGETSYNCVALUESOMLPROC)(Display *dpy, GLXDrawable drawable, int64_t *ust, int64_t *msc, int64_t *sbc); + typedef Bool(GLAD_API_PTR *PFNGLXJOINSWAPGROUPNVPROC)(Display *dpy, GLXDrawable drawable, GLuint group); + typedef void(GLAD_API_PTR *PFNGLXSWAPBUFFERSPROC)(Display *dpy, GLXDrawable drawable); + typedef Bool(GLAD_API_PTR *PFNGLXDELAYBEFORESWAPNVPROC)(Display *dpy, GLXDrawable drawable, GLfloat seconds); + typedef int(GLAD_API_PTR *PFNGLXBINDHYPERPIPESGIXPROC)(Display *dpy, int hpId); + typedef void(GLAD_API_PTR *PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC)(Display *dpy, GLXVideoCaptureDeviceNV device); + typedef Display *(GLAD_API_PTR *PFNGLXGETCURRENTDISPLAYEXTPROC)(void); + typedef GLXFBConfig *(GLAD_API_PTR *PFNGLXGETFBCONFIGSPROC)(Display *dpy, int screen, int *nelements); + typedef GLXDrawable(GLAD_API_PTR *PFNGLXGETCURRENTREADDRAWABLEPROC)(void); + typedef int(GLAD_API_PTR *PFNGLXRELEASEVIDEOIMAGENVPROC)(Display *dpy, GLXPbuffer pbuf); + typedef Bool(GLAD_API_PTR *PFNGLXQUERYEXTENSIONPROC)(Display *dpy, int *errorb, int *event); + typedef Bool(GLAD_API_PTR *PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC)(GLXContext ctx); + typedef XVisualInfo *(GLAD_API_PTR *PFNGLXCHOOSEVISUALPROC)(Display *dpy, int screen, int *attribList); + typedef void(GLAD_API_PTR *PFNGLXDESTROYCONTEXTPROC)(Display *dpy, GLXContext ctx); + typedef const char *(GLAD_API_PTR *PFNGLXGETCLIENTSTRINGPROC)(Display *dpy, int name); + typedef void(GLAD_API_PTR *PFNGLXDESTROYGLXPIXMAPPROC)(Display *dpy, GLXPixmap pixmap); + typedef Bool(GLAD_API_PTR *PFNGLXRESETFRAMECOUNTNVPROC)(Display *dpy, int screen); + typedef int(GLAD_API_PTR *PFNGLXRELEASEVIDEODEVICENVPROC)(Display *dpy, int screen, GLXVideoDeviceNV VideoDevice); + typedef GLXFBConfigSGIX(GLAD_API_PTR *PFNGLXGETFBCONFIGFROMVISUALSGIXPROC)(Display *dpy, XVisualInfo *vis); + typedef GLXContext(GLAD_API_PTR *PFNGLXCREATENEWCONTEXTPROC)(Display *dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); + typedef Bool(GLAD_API_PTR *PFNGLXMAKECONTEXTCURRENTPROC)(Display *dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); + typedef Bool(GLAD_API_PTR *PFNGLXQUERYMAXSWAPGROUPSNVPROC)(Display *dpy, int screen, GLuint *maxGroups, GLuint *maxBarriers); + typedef XVisualInfo *(GLAD_API_PTR *PFNGLXGETVISUALFROMFBCONFIGSGIXPROC)(Display *dpy, GLXFBConfigSGIX config); + typedef GLXDrawable(GLAD_API_PTR *PFNGLXGETCURRENTDRAWABLEPROC)(void); + typedef GLXDrawable(GLAD_API_PTR *PFNGLXGETCURRENTREADDRAWABLESGIPROC)(void); + typedef Bool(GLAD_API_PTR *PFNGLXQUERYFRAMECOUNTNVPROC)(Display *dpy, int screen, GLuint *count); + typedef unsigned int(GLAD_API_PTR *PFNGLXGETCONTEXTGPUIDAMDPROC)(GLXContext ctx); + typedef void(GLAD_API_PTR *PFNGLXBINDSWAPBARRIERSGIXPROC)(Display *dpy, GLXDrawable drawable, int barrier); + typedef Bool(GLAD_API_PTR *PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC)(Display *dpy, int screen, int *max); + typedef GLXPixmap(GLAD_API_PTR *PFNGLXCREATEGLXPIXMAPMESAPROC)(Display *dpy, XVisualInfo *visual, Pixmap pixmap, Colormap cmap); + typedef Bool(GLAD_API_PTR *PFNGLXMAKECURRENTPROC)(Display *dpy, GLXDrawable drawable, GLXContext ctx); + typedef void(GLAD_API_PTR *PFNGLXDESTROYWINDOWPROC)(Display *dpy, GLXWindow win); + typedef int(GLAD_API_PTR *PFNGLXBINDVIDEOIMAGENVPROC)(Display *dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer); + typedef int(GLAD_API_PTR *PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC)(Display *dpy, GLXVideoCaptureDeviceNV device, int attribute, int *value); + typedef int(GLAD_API_PTR *PFNGLXQUERYCHANNELDELTASSGIXPROC)(Display *display, int screen, int channel, int *x, int *y, int *w, int *h); + typedef GLXVideoCaptureDeviceNV *(GLAD_API_PTR *PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC)(Display *dpy, int screen, int *nelements); + typedef GLXContext(GLAD_API_PTR *PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC)(unsigned int id, GLXContext share_context, const int *attribList); + typedef GLXContext(GLAD_API_PTR *PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC)(void); + typedef int(GLAD_API_PTR *PFNGLXQUERYCHANNELRECTSGIXPROC)(Display *display, int screen, int channel, int *dx, int *dy, int *dw, int *dh); + typedef GLXContext(GLAD_API_PTR *PFNGLXCREATECONTEXTPROC)(Display *dpy, XVisualInfo *vis, GLXContext shareList, Bool direct); + typedef void(GLAD_API_PTR *PFNGLXFREECONTEXTEXTPROC)(Display *dpy, GLXContext context); + typedef GLXContextID(GLAD_API_PTR *PFNGLXGETCONTEXTIDEXTPROC)(const GLXContext context); + typedef Bool(GLAD_API_PTR *PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC)(int attribute, unsigned int *value); + typedef GLXFBConfig *(GLAD_API_PTR *PFNGLXCHOOSEFBCONFIGPROC)(Display *dpy, int screen, const int *attrib_list, int *nelements); + typedef int(GLAD_API_PTR *PFNGLXBINDCHANNELTOWINDOWSGIXPROC)(Display *display, int screen, int channel, Window window); + typedef int(GLAD_API_PTR *PFNGLXCHANNELRECTSYNCSGIXPROC)(Display *display, int screen, int channel, GLenum synctype); + typedef GLXContext(GLAD_API_PTR *PFNGLXIMPORTCONTEXTEXTPROC)(Display *dpy, GLXContextID contextID); + typedef Bool(GLAD_API_PTR *PFNGLXRELEASEBUFFERSMESAPROC)(Display *dpy, GLXDrawable drawable); + typedef GLXPixmap(GLAD_API_PTR *PFNGLXCREATEPIXMAPPROC)(Display *dpy, GLXFBConfig config, Pixmap pixmap, const int *attrib_list); + typedef unsigned int(GLAD_API_PTR *PFNGLXGETAGPOFFSETMESAPROC)(const void *pointer); -typedef void (GLAD_API_PTR *PFNGLXCUSHIONSGIPROC)(Display * dpy, Window window, float cushion); -typedef void (GLAD_API_PTR *PFNGLXDESTROYGLXPBUFFERSGIXPROC)(Display * dpy, GLXPbufferSGIX pbuf); -typedef int (GLAD_API_PTR *PFNGLXSENDPBUFFERTOVIDEONVPROC)(Display * dpy, GLXPbuffer pbuf, int iBufferType, unsigned long * pulCounterPbuffer, GLboolean bBlock); -typedef __GLXextFuncPtr (GLAD_API_PTR *PFNGLXGETPROCADDRESSARBPROC)(const GLubyte * procName); -typedef GLXContext (GLAD_API_PTR *PFNGLXCREATECONTEXTATTRIBSARBPROC)(Display * dpy, GLXFBConfig config, GLXContext share_context, Bool direct, const int * attrib_list); -typedef void (GLAD_API_PTR *PFNGLXJOINSWAPGROUPSGIXPROC)(Display * dpy, GLXDrawable drawable, GLXDrawable member); -typedef void (GLAD_API_PTR *PFNGLXSWAPINTERVALEXTPROC)(Display * dpy, GLXDrawable drawable, int interval); -typedef GLXHyperpipeConfigSGIX * (GLAD_API_PTR *PFNGLXQUERYHYPERPIPECONFIGSGIXPROC)(Display * dpy, int hpId, int * npipes); -typedef int (GLAD_API_PTR *PFNGLXGETGPUINFOAMDPROC)(unsigned int id, int property, GLenum dataType, unsigned int size, void * data); -typedef Status (GLAD_API_PTR *PFNGLXGETTRANSPARENTINDEXSUNPROC)(Display * dpy, Window overlay, Window underlay, long * pTransparentIndex); -typedef GLXHyperpipeNetworkSGIX * (GLAD_API_PTR *PFNGLXQUERYHYPERPIPENETWORKSGIXPROC)(Display * dpy, int * npipes); -typedef int (GLAD_API_PTR *PFNGLXQUERYGLXPBUFFERSGIXPROC)(Display * dpy, GLXPbufferSGIX pbuf, int attribute, unsigned int * value); -typedef GLXPixmap (GLAD_API_PTR *PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC)(Display * dpy, GLXFBConfigSGIX config, Pixmap pixmap); -typedef void (GLAD_API_PTR *PFNGLXCOPYCONTEXTPROC)(Display * dpy, GLXContext src, GLXContext dst, unsigned long mask); -typedef GLXPbufferSGIX (GLAD_API_PTR *PFNGLXCREATEGLXPBUFFERSGIXPROC)(Display * dpy, GLXFBConfigSGIX config, unsigned int width, unsigned int height, int * attrib_list); -typedef unsigned int (GLAD_API_PTR *PFNGLXGETGPUIDSAMDPROC)(unsigned int maxCount, unsigned int * ids); -typedef Bool (GLAD_API_PTR *PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC)(GLXContext ctx); -typedef int (GLAD_API_PTR *PFNGLXGETVIDEODEVICENVPROC)(Display * dpy, int screen, int numVideoDevices, GLXVideoDeviceNV * pVideoDevice); -typedef void (GLAD_API_PTR *PFNGLXWAITGLPROC)(void); -typedef int (GLAD_API_PTR *PFNGLXGETVIDEOSYNCSGIPROC)(unsigned int * count); -typedef int (GLAD_API_PTR *PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC)(Display * dpy, int hpId); -typedef int (GLAD_API_PTR *PFNGLXHYPERPIPECONFIGSGIXPROC)(Display * dpy, int networkId, int npipes, GLXHyperpipeConfigSGIX * cfg, int * hpId); -typedef int64_t (GLAD_API_PTR *PFNGLXSWAPBUFFERSMSCOMLPROC)(Display * dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder); -typedef GLXFBConfigSGIX * (GLAD_API_PTR *PFNGLXCHOOSEFBCONFIGSGIXPROC)(Display * dpy, int screen, int * attrib_list, int * nelements); -typedef int (GLAD_API_PTR *PFNGLXWAITVIDEOSYNCSGIPROC)(int divisor, int remainder, unsigned int * count); -typedef Bool (GLAD_API_PTR *PFNGLXWAITFORSBCOMLPROC)(Display * dpy, GLXDrawable drawable, int64_t target_sbc, int64_t * ust, int64_t * msc, int64_t * sbc); -typedef __GLXextFuncPtr (GLAD_API_PTR *PFNGLXGETPROCADDRESSPROC)(const GLubyte * procName); -typedef int (GLAD_API_PTR *PFNGLXGETSWAPINTERVALMESAPROC)(void); -typedef int (GLAD_API_PTR *PFNGLXCHANNELRECTSGIXPROC)(Display * display, int screen, int channel, int x, int y, int w, int h); -typedef void (GLAD_API_PTR *PFNGLXWAITXPROC)(void); -typedef const char * (GLAD_API_PTR *PFNGLXQUERYSERVERSTRINGPROC)(Display * dpy, int screen, int name); -typedef GLXPixmap (GLAD_API_PTR *PFNGLXCREATEGLXPIXMAPPROC)(Display * dpy, XVisualInfo * visual, Pixmap pixmap); -typedef Bool (GLAD_API_PTR *PFNGLXBINDSWAPBARRIERNVPROC)(Display * dpy, GLuint group, GLuint barrier); -typedef const char * (GLAD_API_PTR *PFNGLXQUERYRENDERERSTRINGMESAPROC)(Display * dpy, int screen, int renderer, int attribute); -typedef void (GLAD_API_PTR *PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC)(Display * dpy, GLXVideoCaptureDeviceNV device); -typedef Bool (GLAD_API_PTR *PFNGLXWAITFORMSCOMLPROC)(Display * dpy, GLXDrawable drawable, int64_t target_msc, int64_t divisor, int64_t remainder, int64_t * ust, int64_t * msc, int64_t * sbc); -typedef void (GLAD_API_PTR *PFNGLXCOPYSUBBUFFERMESAPROC)(Display * dpy, GLXDrawable drawable, int x, int y, int width, int height); -typedef GLXContext (GLAD_API_PTR *PFNGLXGETCURRENTCONTEXTPROC)(void); -typedef void (GLAD_API_PTR *PFNGLXSELECTEVENTPROC)(Display * dpy, GLXDrawable draw, unsigned long event_mask); -typedef int (GLAD_API_PTR *PFNGLXSWAPINTERVALSGIPROC)(int interval); -typedef Bool (GLAD_API_PTR *PFNGLXQUERYSWAPGROUPNVPROC)(Display * dpy, GLXDrawable drawable, GLuint * group, GLuint * barrier); -typedef Bool (GLAD_API_PTR *PFNGLXMAKECURRENTREADSGIPROC)(Display * dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); -typedef void (GLAD_API_PTR *PFNGLXQUERYDRAWABLEPROC)(Display * dpy, GLXDrawable draw, int attribute, unsigned int * value); -typedef void (GLAD_API_PTR *PFNGLXCOPYBUFFERSUBDATANVPROC)(Display * dpy, GLXContext readCtx, GLXContext writeCtx, GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -typedef int (GLAD_API_PTR *PFNGLXQUERYCONTEXTPROC)(Display * dpy, GLXContext ctx, int attribute, int * value); -typedef int (GLAD_API_PTR *PFNGLXGETCONFIGPROC)(Display * dpy, XVisualInfo * visual, int attrib, int * value); -typedef Bool (GLAD_API_PTR *PFNGLXSET3DFXMODEMESAPROC)(int mode); -typedef int (GLAD_API_PTR *PFNGLXGETVIDEOINFONVPROC)(Display * dpy, int screen, GLXVideoDeviceNV VideoDevice, unsigned long * pulCounterOutputPbuffer, unsigned long * pulCounterOutputVideo); -typedef Bool (GLAD_API_PTR *PFNGLXISDIRECTPROC)(Display * dpy, GLXContext ctx); -typedef int (GLAD_API_PTR *PFNGLXGETFBCONFIGATTRIBPROC)(Display * dpy, GLXFBConfig config, int attribute, int * value); -typedef XVisualInfo * (GLAD_API_PTR *PFNGLXGETVISUALFROMFBCONFIGPROC)(Display * dpy, GLXFBConfig config); -typedef void (GLAD_API_PTR *PFNGLXBINDTEXIMAGEEXTPROC)(Display * dpy, GLXDrawable drawable, int buffer, const int * attrib_list); -typedef void (GLAD_API_PTR *PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC)(GLXContext dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); -typedef Bool (GLAD_API_PTR *PFNGLXQUERYVERSIONPROC)(Display * dpy, int * maj, int * min); -typedef void (GLAD_API_PTR *PFNGLXSELECTEVENTSGIXPROC)(Display * dpy, GLXDrawable drawable, unsigned long mask); -typedef Bool (GLAD_API_PTR *PFNGLXGETMSCRATEOMLPROC)(Display * dpy, GLXDrawable drawable, int32_t * numerator, int32_t * denominator); -typedef Bool (GLAD_API_PTR *PFNGLXQUERYRENDERERINTEGERMESAPROC)(Display * dpy, int screen, int renderer, int attribute, unsigned int * value); -typedef GLXWindow (GLAD_API_PTR *PFNGLXCREATEWINDOWPROC)(Display * dpy, GLXFBConfig config, Window win, const int * attrib_list); -typedef void (GLAD_API_PTR *PFNGLXCOPYIMAGESUBDATANVPROC)(Display * dpy, GLXContext srcCtx, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, GLXContext dstCtx, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); -typedef int (GLAD_API_PTR *PFNGLXSWAPINTERVALMESAPROC)(unsigned int interval); -typedef int (GLAD_API_PTR *PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC)(Display * dpy, int timeSlice, int attrib, int size, void * returnAttribList); -typedef int (GLAD_API_PTR *PFNGLXBINDVIDEOCAPTUREDEVICENVPROC)(Display * dpy, unsigned int video_capture_slot, GLXVideoCaptureDeviceNV device); -typedef GLXContext (GLAD_API_PTR *PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC)(Display * dpy, GLXFBConfigSGIX config, int render_type, GLXContext share_list, Bool direct); -typedef unsigned int * (GLAD_API_PTR *PFNGLXENUMERATEVIDEODEVICESNVPROC)(Display * dpy, int screen, int * nelements); -typedef int (GLAD_API_PTR *PFNGLXHYPERPIPEATTRIBSGIXPROC)(Display * dpy, int timeSlice, int attrib, int size, void * attribList); -typedef void (GLAD_API_PTR *PFNGLXDESTROYPBUFFERPROC)(Display * dpy, GLXPbuffer pbuf); -typedef void (GLAD_API_PTR *PFNGLXNAMEDCOPYBUFFERSUBDATANVPROC)(Display * dpy, GLXContext readCtx, GLXContext writeCtx, GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); -typedef GLXPbuffer (GLAD_API_PTR *PFNGLXCREATEPBUFFERPROC)(Display * dpy, GLXFBConfig config, const int * attrib_list); -typedef const char * (GLAD_API_PTR *PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC)(int attribute); -typedef int (GLAD_API_PTR *PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC)(Display * dpy, int timeSlice, int attrib, int size, void * attribList, void * returnAttribList); -typedef int (GLAD_API_PTR *PFNGLXGETFBCONFIGATTRIBSGIXPROC)(Display * dpy, GLXFBConfigSGIX config, int attribute, int * value); -typedef const char * (GLAD_API_PTR *PFNGLXQUERYEXTENSIONSSTRINGPROC)(Display * dpy, int screen); -typedef int (GLAD_API_PTR *PFNGLXBINDVIDEODEVICENVPROC)(Display * dpy, unsigned int video_slot, unsigned int video_device, const int * attrib_list); -typedef GLXContext (GLAD_API_PTR *PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC)(unsigned int id, GLXContext share_list); -typedef int (GLAD_API_PTR *PFNGLXQUERYCONTEXTINFOEXTPROC)(Display * dpy, GLXContext context, int attribute, int * value); -typedef void (GLAD_API_PTR *PFNGLXGETSELECTEDEVENTPROC)(Display * dpy, GLXDrawable draw, unsigned long * event_mask); -typedef Display * (GLAD_API_PTR *PFNGLXGETCURRENTDISPLAYPROC)(void); -typedef void (GLAD_API_PTR *PFNGLXDESTROYPIXMAPPROC)(Display * dpy, GLXPixmap pixmap); -typedef void (GLAD_API_PTR *PFNGLXGETSELECTEDEVENTSGIXPROC)(Display * dpy, GLXDrawable drawable, unsigned long * mask); -typedef void (GLAD_API_PTR *PFNGLXRELEASETEXIMAGEEXTPROC)(Display * dpy, GLXDrawable drawable, int buffer); -typedef void (GLAD_API_PTR *PFNGLXUSEXFONTPROC)(Font font, int first, int count, int list); -typedef Bool (GLAD_API_PTR *PFNGLXGETSYNCVALUESOMLPROC)(Display * dpy, GLXDrawable drawable, int64_t * ust, int64_t * msc, int64_t * sbc); -typedef Bool (GLAD_API_PTR *PFNGLXJOINSWAPGROUPNVPROC)(Display * dpy, GLXDrawable drawable, GLuint group); -typedef void (GLAD_API_PTR *PFNGLXSWAPBUFFERSPROC)(Display * dpy, GLXDrawable drawable); -typedef Bool (GLAD_API_PTR *PFNGLXDELAYBEFORESWAPNVPROC)(Display * dpy, GLXDrawable drawable, GLfloat seconds); -typedef int (GLAD_API_PTR *PFNGLXBINDHYPERPIPESGIXPROC)(Display * dpy, int hpId); -typedef void (GLAD_API_PTR *PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC)(Display * dpy, GLXVideoCaptureDeviceNV device); -typedef Display * (GLAD_API_PTR *PFNGLXGETCURRENTDISPLAYEXTPROC)(void); -typedef GLXFBConfig * (GLAD_API_PTR *PFNGLXGETFBCONFIGSPROC)(Display * dpy, int screen, int * nelements); -typedef GLXDrawable (GLAD_API_PTR *PFNGLXGETCURRENTREADDRAWABLEPROC)(void); -typedef int (GLAD_API_PTR *PFNGLXRELEASEVIDEOIMAGENVPROC)(Display * dpy, GLXPbuffer pbuf); -typedef Bool (GLAD_API_PTR *PFNGLXQUERYEXTENSIONPROC)(Display * dpy, int * errorb, int * event); -typedef Bool (GLAD_API_PTR *PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC)(GLXContext ctx); -typedef XVisualInfo * (GLAD_API_PTR *PFNGLXCHOOSEVISUALPROC)(Display * dpy, int screen, int * attribList); -typedef void (GLAD_API_PTR *PFNGLXDESTROYCONTEXTPROC)(Display * dpy, GLXContext ctx); -typedef const char * (GLAD_API_PTR *PFNGLXGETCLIENTSTRINGPROC)(Display * dpy, int name); -typedef void (GLAD_API_PTR *PFNGLXDESTROYGLXPIXMAPPROC)(Display * dpy, GLXPixmap pixmap); -typedef Bool (GLAD_API_PTR *PFNGLXRESETFRAMECOUNTNVPROC)(Display * dpy, int screen); -typedef int (GLAD_API_PTR *PFNGLXRELEASEVIDEODEVICENVPROC)(Display * dpy, int screen, GLXVideoDeviceNV VideoDevice); -typedef GLXFBConfigSGIX (GLAD_API_PTR *PFNGLXGETFBCONFIGFROMVISUALSGIXPROC)(Display * dpy, XVisualInfo * vis); -typedef GLXContext (GLAD_API_PTR *PFNGLXCREATENEWCONTEXTPROC)(Display * dpy, GLXFBConfig config, int render_type, GLXContext share_list, Bool direct); -typedef Bool (GLAD_API_PTR *PFNGLXMAKECONTEXTCURRENTPROC)(Display * dpy, GLXDrawable draw, GLXDrawable read, GLXContext ctx); -typedef Bool (GLAD_API_PTR *PFNGLXQUERYMAXSWAPGROUPSNVPROC)(Display * dpy, int screen, GLuint * maxGroups, GLuint * maxBarriers); -typedef XVisualInfo * (GLAD_API_PTR *PFNGLXGETVISUALFROMFBCONFIGSGIXPROC)(Display * dpy, GLXFBConfigSGIX config); -typedef GLXDrawable (GLAD_API_PTR *PFNGLXGETCURRENTDRAWABLEPROC)(void); -typedef GLXDrawable (GLAD_API_PTR *PFNGLXGETCURRENTREADDRAWABLESGIPROC)(void); -typedef Bool (GLAD_API_PTR *PFNGLXQUERYFRAMECOUNTNVPROC)(Display * dpy, int screen, GLuint * count); -typedef unsigned int (GLAD_API_PTR *PFNGLXGETCONTEXTGPUIDAMDPROC)(GLXContext ctx); -typedef void (GLAD_API_PTR *PFNGLXBINDSWAPBARRIERSGIXPROC)(Display * dpy, GLXDrawable drawable, int barrier); -typedef Bool (GLAD_API_PTR *PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC)(Display * dpy, int screen, int * max); -typedef GLXPixmap (GLAD_API_PTR *PFNGLXCREATEGLXPIXMAPMESAPROC)(Display * dpy, XVisualInfo * visual, Pixmap pixmap, Colormap cmap); -typedef Bool (GLAD_API_PTR *PFNGLXMAKECURRENTPROC)(Display * dpy, GLXDrawable drawable, GLXContext ctx); -typedef void (GLAD_API_PTR *PFNGLXDESTROYWINDOWPROC)(Display * dpy, GLXWindow win); -typedef int (GLAD_API_PTR *PFNGLXBINDVIDEOIMAGENVPROC)(Display * dpy, GLXVideoDeviceNV VideoDevice, GLXPbuffer pbuf, int iVideoBuffer); -typedef int (GLAD_API_PTR *PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC)(Display * dpy, GLXVideoCaptureDeviceNV device, int attribute, int * value); -typedef int (GLAD_API_PTR *PFNGLXQUERYCHANNELDELTASSGIXPROC)(Display * display, int screen, int channel, int * x, int * y, int * w, int * h); -typedef GLXVideoCaptureDeviceNV * (GLAD_API_PTR *PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC)(Display * dpy, int screen, int * nelements); -typedef GLXContext (GLAD_API_PTR *PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC)(unsigned int id, GLXContext share_context, const int * attribList); -typedef GLXContext (GLAD_API_PTR *PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC)(void); -typedef int (GLAD_API_PTR *PFNGLXQUERYCHANNELRECTSGIXPROC)(Display * display, int screen, int channel, int * dx, int * dy, int * dw, int * dh); -typedef GLXContext (GLAD_API_PTR *PFNGLXCREATECONTEXTPROC)(Display * dpy, XVisualInfo * vis, GLXContext shareList, Bool direct); -typedef void (GLAD_API_PTR *PFNGLXFREECONTEXTEXTPROC)(Display * dpy, GLXContext context); -typedef GLXContextID (GLAD_API_PTR *PFNGLXGETCONTEXTIDEXTPROC)(const GLXContext context); -typedef Bool (GLAD_API_PTR *PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC)(int attribute, unsigned int * value); -typedef GLXFBConfig * (GLAD_API_PTR *PFNGLXCHOOSEFBCONFIGPROC)(Display * dpy, int screen, const int * attrib_list, int * nelements); -typedef int (GLAD_API_PTR *PFNGLXBINDCHANNELTOWINDOWSGIXPROC)(Display * display, int screen, int channel, Window window); -typedef int (GLAD_API_PTR *PFNGLXCHANNELRECTSYNCSGIXPROC)(Display * display, int screen, int channel, GLenum synctype); -typedef GLXContext (GLAD_API_PTR *PFNGLXIMPORTCONTEXTEXTPROC)(Display * dpy, GLXContextID contextID); -typedef Bool (GLAD_API_PTR *PFNGLXRELEASEBUFFERSMESAPROC)(Display * dpy, GLXDrawable drawable); -typedef GLXPixmap (GLAD_API_PTR *PFNGLXCREATEPIXMAPPROC)(Display * dpy, GLXFBConfig config, Pixmap pixmap, const int * attrib_list); -typedef unsigned int (GLAD_API_PTR *PFNGLXGETAGPOFFSETMESAPROC)(const void * pointer); - -GLAD_API_CALL PFNGLXCUSHIONSGIPROC glad_glXCushionSGI; + GLAD_API_CALL PFNGLXCUSHIONSGIPROC glad_glXCushionSGI; #define glXCushionSGI glad_glXCushionSGI -GLAD_API_CALL PFNGLXDESTROYGLXPBUFFERSGIXPROC glad_glXDestroyGLXPbufferSGIX; + GLAD_API_CALL PFNGLXDESTROYGLXPBUFFERSGIXPROC glad_glXDestroyGLXPbufferSGIX; #define glXDestroyGLXPbufferSGIX glad_glXDestroyGLXPbufferSGIX -GLAD_API_CALL PFNGLXSENDPBUFFERTOVIDEONVPROC glad_glXSendPbufferToVideoNV; + GLAD_API_CALL PFNGLXSENDPBUFFERTOVIDEONVPROC glad_glXSendPbufferToVideoNV; #define glXSendPbufferToVideoNV glad_glXSendPbufferToVideoNV -GLAD_API_CALL PFNGLXGETPROCADDRESSARBPROC glad_glXGetProcAddressARB; + GLAD_API_CALL PFNGLXGETPROCADDRESSARBPROC glad_glXGetProcAddressARB; #define glXGetProcAddressARB glad_glXGetProcAddressARB -GLAD_API_CALL PFNGLXCREATECONTEXTATTRIBSARBPROC glad_glXCreateContextAttribsARB; + GLAD_API_CALL PFNGLXCREATECONTEXTATTRIBSARBPROC glad_glXCreateContextAttribsARB; #define glXCreateContextAttribsARB glad_glXCreateContextAttribsARB -GLAD_API_CALL PFNGLXJOINSWAPGROUPSGIXPROC glad_glXJoinSwapGroupSGIX; + GLAD_API_CALL PFNGLXJOINSWAPGROUPSGIXPROC glad_glXJoinSwapGroupSGIX; #define glXJoinSwapGroupSGIX glad_glXJoinSwapGroupSGIX -GLAD_API_CALL PFNGLXSWAPINTERVALEXTPROC glad_glXSwapIntervalEXT; + GLAD_API_CALL PFNGLXSWAPINTERVALEXTPROC glad_glXSwapIntervalEXT; #define glXSwapIntervalEXT glad_glXSwapIntervalEXT -GLAD_API_CALL PFNGLXQUERYHYPERPIPECONFIGSGIXPROC glad_glXQueryHyperpipeConfigSGIX; + GLAD_API_CALL PFNGLXQUERYHYPERPIPECONFIGSGIXPROC glad_glXQueryHyperpipeConfigSGIX; #define glXQueryHyperpipeConfigSGIX glad_glXQueryHyperpipeConfigSGIX -GLAD_API_CALL PFNGLXGETGPUINFOAMDPROC glad_glXGetGPUInfoAMD; + GLAD_API_CALL PFNGLXGETGPUINFOAMDPROC glad_glXGetGPUInfoAMD; #define glXGetGPUInfoAMD glad_glXGetGPUInfoAMD -GLAD_API_CALL PFNGLXGETTRANSPARENTINDEXSUNPROC glad_glXGetTransparentIndexSUN; + GLAD_API_CALL PFNGLXGETTRANSPARENTINDEXSUNPROC glad_glXGetTransparentIndexSUN; #define glXGetTransparentIndexSUN glad_glXGetTransparentIndexSUN -GLAD_API_CALL PFNGLXQUERYHYPERPIPENETWORKSGIXPROC glad_glXQueryHyperpipeNetworkSGIX; + GLAD_API_CALL PFNGLXQUERYHYPERPIPENETWORKSGIXPROC glad_glXQueryHyperpipeNetworkSGIX; #define glXQueryHyperpipeNetworkSGIX glad_glXQueryHyperpipeNetworkSGIX -GLAD_API_CALL PFNGLXQUERYGLXPBUFFERSGIXPROC glad_glXQueryGLXPbufferSGIX; + GLAD_API_CALL PFNGLXQUERYGLXPBUFFERSGIXPROC glad_glXQueryGLXPbufferSGIX; #define glXQueryGLXPbufferSGIX glad_glXQueryGLXPbufferSGIX -GLAD_API_CALL PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC glad_glXCreateGLXPixmapWithConfigSGIX; + GLAD_API_CALL PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC glad_glXCreateGLXPixmapWithConfigSGIX; #define glXCreateGLXPixmapWithConfigSGIX glad_glXCreateGLXPixmapWithConfigSGIX -GLAD_API_CALL PFNGLXCOPYCONTEXTPROC glad_glXCopyContext; + GLAD_API_CALL PFNGLXCOPYCONTEXTPROC glad_glXCopyContext; #define glXCopyContext glad_glXCopyContext -GLAD_API_CALL PFNGLXCREATEGLXPBUFFERSGIXPROC glad_glXCreateGLXPbufferSGIX; + GLAD_API_CALL PFNGLXCREATEGLXPBUFFERSGIXPROC glad_glXCreateGLXPbufferSGIX; #define glXCreateGLXPbufferSGIX glad_glXCreateGLXPbufferSGIX -GLAD_API_CALL PFNGLXGETGPUIDSAMDPROC glad_glXGetGPUIDsAMD; + GLAD_API_CALL PFNGLXGETGPUIDSAMDPROC glad_glXGetGPUIDsAMD; #define glXGetGPUIDsAMD glad_glXGetGPUIDsAMD -GLAD_API_CALL PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC glad_glXDeleteAssociatedContextAMD; + GLAD_API_CALL PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC glad_glXDeleteAssociatedContextAMD; #define glXDeleteAssociatedContextAMD glad_glXDeleteAssociatedContextAMD -GLAD_API_CALL PFNGLXGETVIDEODEVICENVPROC glad_glXGetVideoDeviceNV; + GLAD_API_CALL PFNGLXGETVIDEODEVICENVPROC glad_glXGetVideoDeviceNV; #define glXGetVideoDeviceNV glad_glXGetVideoDeviceNV -GLAD_API_CALL PFNGLXWAITGLPROC glad_glXWaitGL; + GLAD_API_CALL PFNGLXWAITGLPROC glad_glXWaitGL; #define glXWaitGL glad_glXWaitGL -GLAD_API_CALL PFNGLXGETVIDEOSYNCSGIPROC glad_glXGetVideoSyncSGI; + GLAD_API_CALL PFNGLXGETVIDEOSYNCSGIPROC glad_glXGetVideoSyncSGI; #define glXGetVideoSyncSGI glad_glXGetVideoSyncSGI -GLAD_API_CALL PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC glad_glXDestroyHyperpipeConfigSGIX; + GLAD_API_CALL PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC glad_glXDestroyHyperpipeConfigSGIX; #define glXDestroyHyperpipeConfigSGIX glad_glXDestroyHyperpipeConfigSGIX -GLAD_API_CALL PFNGLXHYPERPIPECONFIGSGIXPROC glad_glXHyperpipeConfigSGIX; + GLAD_API_CALL PFNGLXHYPERPIPECONFIGSGIXPROC glad_glXHyperpipeConfigSGIX; #define glXHyperpipeConfigSGIX glad_glXHyperpipeConfigSGIX -GLAD_API_CALL PFNGLXSWAPBUFFERSMSCOMLPROC glad_glXSwapBuffersMscOML; + GLAD_API_CALL PFNGLXSWAPBUFFERSMSCOMLPROC glad_glXSwapBuffersMscOML; #define glXSwapBuffersMscOML glad_glXSwapBuffersMscOML -GLAD_API_CALL PFNGLXCHOOSEFBCONFIGSGIXPROC glad_glXChooseFBConfigSGIX; + GLAD_API_CALL PFNGLXCHOOSEFBCONFIGSGIXPROC glad_glXChooseFBConfigSGIX; #define glXChooseFBConfigSGIX glad_glXChooseFBConfigSGIX -GLAD_API_CALL PFNGLXWAITVIDEOSYNCSGIPROC glad_glXWaitVideoSyncSGI; + GLAD_API_CALL PFNGLXWAITVIDEOSYNCSGIPROC glad_glXWaitVideoSyncSGI; #define glXWaitVideoSyncSGI glad_glXWaitVideoSyncSGI -GLAD_API_CALL PFNGLXWAITFORSBCOMLPROC glad_glXWaitForSbcOML; + GLAD_API_CALL PFNGLXWAITFORSBCOMLPROC glad_glXWaitForSbcOML; #define glXWaitForSbcOML glad_glXWaitForSbcOML -GLAD_API_CALL PFNGLXGETPROCADDRESSPROC glad_glXGetProcAddress; + GLAD_API_CALL PFNGLXGETPROCADDRESSPROC glad_glXGetProcAddress; #define glXGetProcAddress glad_glXGetProcAddress -GLAD_API_CALL PFNGLXGETSWAPINTERVALMESAPROC glad_glXGetSwapIntervalMESA; + GLAD_API_CALL PFNGLXGETSWAPINTERVALMESAPROC glad_glXGetSwapIntervalMESA; #define glXGetSwapIntervalMESA glad_glXGetSwapIntervalMESA -GLAD_API_CALL PFNGLXCHANNELRECTSGIXPROC glad_glXChannelRectSGIX; + GLAD_API_CALL PFNGLXCHANNELRECTSGIXPROC glad_glXChannelRectSGIX; #define glXChannelRectSGIX glad_glXChannelRectSGIX -GLAD_API_CALL PFNGLXWAITXPROC glad_glXWaitX; + GLAD_API_CALL PFNGLXWAITXPROC glad_glXWaitX; #define glXWaitX glad_glXWaitX -GLAD_API_CALL PFNGLXQUERYSERVERSTRINGPROC glad_glXQueryServerString; + GLAD_API_CALL PFNGLXQUERYSERVERSTRINGPROC glad_glXQueryServerString; #define glXQueryServerString glad_glXQueryServerString -GLAD_API_CALL PFNGLXCREATEGLXPIXMAPPROC glad_glXCreateGLXPixmap; + GLAD_API_CALL PFNGLXCREATEGLXPIXMAPPROC glad_glXCreateGLXPixmap; #define glXCreateGLXPixmap glad_glXCreateGLXPixmap -GLAD_API_CALL PFNGLXBINDSWAPBARRIERNVPROC glad_glXBindSwapBarrierNV; + GLAD_API_CALL PFNGLXBINDSWAPBARRIERNVPROC glad_glXBindSwapBarrierNV; #define glXBindSwapBarrierNV glad_glXBindSwapBarrierNV -GLAD_API_CALL PFNGLXQUERYRENDERERSTRINGMESAPROC glad_glXQueryRendererStringMESA; + GLAD_API_CALL PFNGLXQUERYRENDERERSTRINGMESAPROC glad_glXQueryRendererStringMESA; #define glXQueryRendererStringMESA glad_glXQueryRendererStringMESA -GLAD_API_CALL PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC glad_glXReleaseVideoCaptureDeviceNV; + GLAD_API_CALL PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC glad_glXReleaseVideoCaptureDeviceNV; #define glXReleaseVideoCaptureDeviceNV glad_glXReleaseVideoCaptureDeviceNV -GLAD_API_CALL PFNGLXWAITFORMSCOMLPROC glad_glXWaitForMscOML; + GLAD_API_CALL PFNGLXWAITFORMSCOMLPROC glad_glXWaitForMscOML; #define glXWaitForMscOML glad_glXWaitForMscOML -GLAD_API_CALL PFNGLXCOPYSUBBUFFERMESAPROC glad_glXCopySubBufferMESA; + GLAD_API_CALL PFNGLXCOPYSUBBUFFERMESAPROC glad_glXCopySubBufferMESA; #define glXCopySubBufferMESA glad_glXCopySubBufferMESA -GLAD_API_CALL PFNGLXGETCURRENTCONTEXTPROC glad_glXGetCurrentContext; + GLAD_API_CALL PFNGLXGETCURRENTCONTEXTPROC glad_glXGetCurrentContext; #define glXGetCurrentContext glad_glXGetCurrentContext -GLAD_API_CALL PFNGLXSELECTEVENTPROC glad_glXSelectEvent; + GLAD_API_CALL PFNGLXSELECTEVENTPROC glad_glXSelectEvent; #define glXSelectEvent glad_glXSelectEvent -GLAD_API_CALL PFNGLXSWAPINTERVALSGIPROC glad_glXSwapIntervalSGI; + GLAD_API_CALL PFNGLXSWAPINTERVALSGIPROC glad_glXSwapIntervalSGI; #define glXSwapIntervalSGI glad_glXSwapIntervalSGI -GLAD_API_CALL PFNGLXQUERYSWAPGROUPNVPROC glad_glXQuerySwapGroupNV; + GLAD_API_CALL PFNGLXQUERYSWAPGROUPNVPROC glad_glXQuerySwapGroupNV; #define glXQuerySwapGroupNV glad_glXQuerySwapGroupNV -GLAD_API_CALL PFNGLXMAKECURRENTREADSGIPROC glad_glXMakeCurrentReadSGI; + GLAD_API_CALL PFNGLXMAKECURRENTREADSGIPROC glad_glXMakeCurrentReadSGI; #define glXMakeCurrentReadSGI glad_glXMakeCurrentReadSGI -GLAD_API_CALL PFNGLXQUERYDRAWABLEPROC glad_glXQueryDrawable; + GLAD_API_CALL PFNGLXQUERYDRAWABLEPROC glad_glXQueryDrawable; #define glXQueryDrawable glad_glXQueryDrawable -GLAD_API_CALL PFNGLXCOPYBUFFERSUBDATANVPROC glad_glXCopyBufferSubDataNV; + GLAD_API_CALL PFNGLXCOPYBUFFERSUBDATANVPROC glad_glXCopyBufferSubDataNV; #define glXCopyBufferSubDataNV glad_glXCopyBufferSubDataNV -GLAD_API_CALL PFNGLXQUERYCONTEXTPROC glad_glXQueryContext; + GLAD_API_CALL PFNGLXQUERYCONTEXTPROC glad_glXQueryContext; #define glXQueryContext glad_glXQueryContext -GLAD_API_CALL PFNGLXGETCONFIGPROC glad_glXGetConfig; + GLAD_API_CALL PFNGLXGETCONFIGPROC glad_glXGetConfig; #define glXGetConfig glad_glXGetConfig -GLAD_API_CALL PFNGLXSET3DFXMODEMESAPROC glad_glXSet3DfxModeMESA; + GLAD_API_CALL PFNGLXSET3DFXMODEMESAPROC glad_glXSet3DfxModeMESA; #define glXSet3DfxModeMESA glad_glXSet3DfxModeMESA -GLAD_API_CALL PFNGLXGETVIDEOINFONVPROC glad_glXGetVideoInfoNV; + GLAD_API_CALL PFNGLXGETVIDEOINFONVPROC glad_glXGetVideoInfoNV; #define glXGetVideoInfoNV glad_glXGetVideoInfoNV -GLAD_API_CALL PFNGLXISDIRECTPROC glad_glXIsDirect; + GLAD_API_CALL PFNGLXISDIRECTPROC glad_glXIsDirect; #define glXIsDirect glad_glXIsDirect -GLAD_API_CALL PFNGLXGETFBCONFIGATTRIBPROC glad_glXGetFBConfigAttrib; + GLAD_API_CALL PFNGLXGETFBCONFIGATTRIBPROC glad_glXGetFBConfigAttrib; #define glXGetFBConfigAttrib glad_glXGetFBConfigAttrib -GLAD_API_CALL PFNGLXGETVISUALFROMFBCONFIGPROC glad_glXGetVisualFromFBConfig; + GLAD_API_CALL PFNGLXGETVISUALFROMFBCONFIGPROC glad_glXGetVisualFromFBConfig; #define glXGetVisualFromFBConfig glad_glXGetVisualFromFBConfig -GLAD_API_CALL PFNGLXBINDTEXIMAGEEXTPROC glad_glXBindTexImageEXT; + GLAD_API_CALL PFNGLXBINDTEXIMAGEEXTPROC glad_glXBindTexImageEXT; #define glXBindTexImageEXT glad_glXBindTexImageEXT -GLAD_API_CALL PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC glad_glXBlitContextFramebufferAMD; + GLAD_API_CALL PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC glad_glXBlitContextFramebufferAMD; #define glXBlitContextFramebufferAMD glad_glXBlitContextFramebufferAMD -GLAD_API_CALL PFNGLXQUERYVERSIONPROC glad_glXQueryVersion; + GLAD_API_CALL PFNGLXQUERYVERSIONPROC glad_glXQueryVersion; #define glXQueryVersion glad_glXQueryVersion -GLAD_API_CALL PFNGLXSELECTEVENTSGIXPROC glad_glXSelectEventSGIX; + GLAD_API_CALL PFNGLXSELECTEVENTSGIXPROC glad_glXSelectEventSGIX; #define glXSelectEventSGIX glad_glXSelectEventSGIX -GLAD_API_CALL PFNGLXGETMSCRATEOMLPROC glad_glXGetMscRateOML; + GLAD_API_CALL PFNGLXGETMSCRATEOMLPROC glad_glXGetMscRateOML; #define glXGetMscRateOML glad_glXGetMscRateOML -GLAD_API_CALL PFNGLXQUERYRENDERERINTEGERMESAPROC glad_glXQueryRendererIntegerMESA; + GLAD_API_CALL PFNGLXQUERYRENDERERINTEGERMESAPROC glad_glXQueryRendererIntegerMESA; #define glXQueryRendererIntegerMESA glad_glXQueryRendererIntegerMESA -GLAD_API_CALL PFNGLXCREATEWINDOWPROC glad_glXCreateWindow; + GLAD_API_CALL PFNGLXCREATEWINDOWPROC glad_glXCreateWindow; #define glXCreateWindow glad_glXCreateWindow -GLAD_API_CALL PFNGLXCOPYIMAGESUBDATANVPROC glad_glXCopyImageSubDataNV; + GLAD_API_CALL PFNGLXCOPYIMAGESUBDATANVPROC glad_glXCopyImageSubDataNV; #define glXCopyImageSubDataNV glad_glXCopyImageSubDataNV -GLAD_API_CALL PFNGLXSWAPINTERVALMESAPROC glad_glXSwapIntervalMESA; + GLAD_API_CALL PFNGLXSWAPINTERVALMESAPROC glad_glXSwapIntervalMESA; #define glXSwapIntervalMESA glad_glXSwapIntervalMESA -GLAD_API_CALL PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC glad_glXQueryHyperpipeAttribSGIX; + GLAD_API_CALL PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC glad_glXQueryHyperpipeAttribSGIX; #define glXQueryHyperpipeAttribSGIX glad_glXQueryHyperpipeAttribSGIX -GLAD_API_CALL PFNGLXBINDVIDEOCAPTUREDEVICENVPROC glad_glXBindVideoCaptureDeviceNV; + GLAD_API_CALL PFNGLXBINDVIDEOCAPTUREDEVICENVPROC glad_glXBindVideoCaptureDeviceNV; #define glXBindVideoCaptureDeviceNV glad_glXBindVideoCaptureDeviceNV -GLAD_API_CALL PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC glad_glXCreateContextWithConfigSGIX; + GLAD_API_CALL PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC glad_glXCreateContextWithConfigSGIX; #define glXCreateContextWithConfigSGIX glad_glXCreateContextWithConfigSGIX -GLAD_API_CALL PFNGLXENUMERATEVIDEODEVICESNVPROC glad_glXEnumerateVideoDevicesNV; + GLAD_API_CALL PFNGLXENUMERATEVIDEODEVICESNVPROC glad_glXEnumerateVideoDevicesNV; #define glXEnumerateVideoDevicesNV glad_glXEnumerateVideoDevicesNV -GLAD_API_CALL PFNGLXHYPERPIPEATTRIBSGIXPROC glad_glXHyperpipeAttribSGIX; + GLAD_API_CALL PFNGLXHYPERPIPEATTRIBSGIXPROC glad_glXHyperpipeAttribSGIX; #define glXHyperpipeAttribSGIX glad_glXHyperpipeAttribSGIX -GLAD_API_CALL PFNGLXDESTROYPBUFFERPROC glad_glXDestroyPbuffer; + GLAD_API_CALL PFNGLXDESTROYPBUFFERPROC glad_glXDestroyPbuffer; #define glXDestroyPbuffer glad_glXDestroyPbuffer -GLAD_API_CALL PFNGLXNAMEDCOPYBUFFERSUBDATANVPROC glad_glXNamedCopyBufferSubDataNV; + GLAD_API_CALL PFNGLXNAMEDCOPYBUFFERSUBDATANVPROC glad_glXNamedCopyBufferSubDataNV; #define glXNamedCopyBufferSubDataNV glad_glXNamedCopyBufferSubDataNV -GLAD_API_CALL PFNGLXCREATEPBUFFERPROC glad_glXCreatePbuffer; + GLAD_API_CALL PFNGLXCREATEPBUFFERPROC glad_glXCreatePbuffer; #define glXCreatePbuffer glad_glXCreatePbuffer -GLAD_API_CALL PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC glad_glXQueryCurrentRendererStringMESA; + GLAD_API_CALL PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC glad_glXQueryCurrentRendererStringMESA; #define glXQueryCurrentRendererStringMESA glad_glXQueryCurrentRendererStringMESA -GLAD_API_CALL PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC glad_glXQueryHyperpipeBestAttribSGIX; + GLAD_API_CALL PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC glad_glXQueryHyperpipeBestAttribSGIX; #define glXQueryHyperpipeBestAttribSGIX glad_glXQueryHyperpipeBestAttribSGIX -GLAD_API_CALL PFNGLXGETFBCONFIGATTRIBSGIXPROC glad_glXGetFBConfigAttribSGIX; + GLAD_API_CALL PFNGLXGETFBCONFIGATTRIBSGIXPROC glad_glXGetFBConfigAttribSGIX; #define glXGetFBConfigAttribSGIX glad_glXGetFBConfigAttribSGIX -GLAD_API_CALL PFNGLXQUERYEXTENSIONSSTRINGPROC glad_glXQueryExtensionsString; + GLAD_API_CALL PFNGLXQUERYEXTENSIONSSTRINGPROC glad_glXQueryExtensionsString; #define glXQueryExtensionsString glad_glXQueryExtensionsString -GLAD_API_CALL PFNGLXBINDVIDEODEVICENVPROC glad_glXBindVideoDeviceNV; + GLAD_API_CALL PFNGLXBINDVIDEODEVICENVPROC glad_glXBindVideoDeviceNV; #define glXBindVideoDeviceNV glad_glXBindVideoDeviceNV -GLAD_API_CALL PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC glad_glXCreateAssociatedContextAMD; + GLAD_API_CALL PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC glad_glXCreateAssociatedContextAMD; #define glXCreateAssociatedContextAMD glad_glXCreateAssociatedContextAMD -GLAD_API_CALL PFNGLXQUERYCONTEXTINFOEXTPROC glad_glXQueryContextInfoEXT; + GLAD_API_CALL PFNGLXQUERYCONTEXTINFOEXTPROC glad_glXQueryContextInfoEXT; #define glXQueryContextInfoEXT glad_glXQueryContextInfoEXT -GLAD_API_CALL PFNGLXGETSELECTEDEVENTPROC glad_glXGetSelectedEvent; + GLAD_API_CALL PFNGLXGETSELECTEDEVENTPROC glad_glXGetSelectedEvent; #define glXGetSelectedEvent glad_glXGetSelectedEvent -GLAD_API_CALL PFNGLXGETCURRENTDISPLAYPROC glad_glXGetCurrentDisplay; + GLAD_API_CALL PFNGLXGETCURRENTDISPLAYPROC glad_glXGetCurrentDisplay; #define glXGetCurrentDisplay glad_glXGetCurrentDisplay -GLAD_API_CALL PFNGLXDESTROYPIXMAPPROC glad_glXDestroyPixmap; + GLAD_API_CALL PFNGLXDESTROYPIXMAPPROC glad_glXDestroyPixmap; #define glXDestroyPixmap glad_glXDestroyPixmap -GLAD_API_CALL PFNGLXGETSELECTEDEVENTSGIXPROC glad_glXGetSelectedEventSGIX; + GLAD_API_CALL PFNGLXGETSELECTEDEVENTSGIXPROC glad_glXGetSelectedEventSGIX; #define glXGetSelectedEventSGIX glad_glXGetSelectedEventSGIX -GLAD_API_CALL PFNGLXRELEASETEXIMAGEEXTPROC glad_glXReleaseTexImageEXT; + GLAD_API_CALL PFNGLXRELEASETEXIMAGEEXTPROC glad_glXReleaseTexImageEXT; #define glXReleaseTexImageEXT glad_glXReleaseTexImageEXT -GLAD_API_CALL PFNGLXUSEXFONTPROC glad_glXUseXFont; + GLAD_API_CALL PFNGLXUSEXFONTPROC glad_glXUseXFont; #define glXUseXFont glad_glXUseXFont -GLAD_API_CALL PFNGLXGETSYNCVALUESOMLPROC glad_glXGetSyncValuesOML; + GLAD_API_CALL PFNGLXGETSYNCVALUESOMLPROC glad_glXGetSyncValuesOML; #define glXGetSyncValuesOML glad_glXGetSyncValuesOML -GLAD_API_CALL PFNGLXJOINSWAPGROUPNVPROC glad_glXJoinSwapGroupNV; + GLAD_API_CALL PFNGLXJOINSWAPGROUPNVPROC glad_glXJoinSwapGroupNV; #define glXJoinSwapGroupNV glad_glXJoinSwapGroupNV -GLAD_API_CALL PFNGLXSWAPBUFFERSPROC glad_glXSwapBuffers; + GLAD_API_CALL PFNGLXSWAPBUFFERSPROC glad_glXSwapBuffers; #define glXSwapBuffers glad_glXSwapBuffers -GLAD_API_CALL PFNGLXDELAYBEFORESWAPNVPROC glad_glXDelayBeforeSwapNV; + GLAD_API_CALL PFNGLXDELAYBEFORESWAPNVPROC glad_glXDelayBeforeSwapNV; #define glXDelayBeforeSwapNV glad_glXDelayBeforeSwapNV -GLAD_API_CALL PFNGLXBINDHYPERPIPESGIXPROC glad_glXBindHyperpipeSGIX; + GLAD_API_CALL PFNGLXBINDHYPERPIPESGIXPROC glad_glXBindHyperpipeSGIX; #define glXBindHyperpipeSGIX glad_glXBindHyperpipeSGIX -GLAD_API_CALL PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC glad_glXLockVideoCaptureDeviceNV; + GLAD_API_CALL PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC glad_glXLockVideoCaptureDeviceNV; #define glXLockVideoCaptureDeviceNV glad_glXLockVideoCaptureDeviceNV -GLAD_API_CALL PFNGLXGETCURRENTDISPLAYEXTPROC glad_glXGetCurrentDisplayEXT; + GLAD_API_CALL PFNGLXGETCURRENTDISPLAYEXTPROC glad_glXGetCurrentDisplayEXT; #define glXGetCurrentDisplayEXT glad_glXGetCurrentDisplayEXT -GLAD_API_CALL PFNGLXGETFBCONFIGSPROC glad_glXGetFBConfigs; + GLAD_API_CALL PFNGLXGETFBCONFIGSPROC glad_glXGetFBConfigs; #define glXGetFBConfigs glad_glXGetFBConfigs -GLAD_API_CALL PFNGLXGETCURRENTREADDRAWABLEPROC glad_glXGetCurrentReadDrawable; + GLAD_API_CALL PFNGLXGETCURRENTREADDRAWABLEPROC glad_glXGetCurrentReadDrawable; #define glXGetCurrentReadDrawable glad_glXGetCurrentReadDrawable -GLAD_API_CALL PFNGLXRELEASEVIDEOIMAGENVPROC glad_glXReleaseVideoImageNV; + GLAD_API_CALL PFNGLXRELEASEVIDEOIMAGENVPROC glad_glXReleaseVideoImageNV; #define glXReleaseVideoImageNV glad_glXReleaseVideoImageNV -GLAD_API_CALL PFNGLXQUERYEXTENSIONPROC glad_glXQueryExtension; + GLAD_API_CALL PFNGLXQUERYEXTENSIONPROC glad_glXQueryExtension; #define glXQueryExtension glad_glXQueryExtension -GLAD_API_CALL PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC glad_glXMakeAssociatedContextCurrentAMD; + GLAD_API_CALL PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC glad_glXMakeAssociatedContextCurrentAMD; #define glXMakeAssociatedContextCurrentAMD glad_glXMakeAssociatedContextCurrentAMD -GLAD_API_CALL PFNGLXCHOOSEVISUALPROC glad_glXChooseVisual; + GLAD_API_CALL PFNGLXCHOOSEVISUALPROC glad_glXChooseVisual; #define glXChooseVisual glad_glXChooseVisual -GLAD_API_CALL PFNGLXDESTROYCONTEXTPROC glad_glXDestroyContext; + GLAD_API_CALL PFNGLXDESTROYCONTEXTPROC glad_glXDestroyContext; #define glXDestroyContext glad_glXDestroyContext -GLAD_API_CALL PFNGLXGETCLIENTSTRINGPROC glad_glXGetClientString; + GLAD_API_CALL PFNGLXGETCLIENTSTRINGPROC glad_glXGetClientString; #define glXGetClientString glad_glXGetClientString -GLAD_API_CALL PFNGLXDESTROYGLXPIXMAPPROC glad_glXDestroyGLXPixmap; + GLAD_API_CALL PFNGLXDESTROYGLXPIXMAPPROC glad_glXDestroyGLXPixmap; #define glXDestroyGLXPixmap glad_glXDestroyGLXPixmap -GLAD_API_CALL PFNGLXRESETFRAMECOUNTNVPROC glad_glXResetFrameCountNV; + GLAD_API_CALL PFNGLXRESETFRAMECOUNTNVPROC glad_glXResetFrameCountNV; #define glXResetFrameCountNV glad_glXResetFrameCountNV -GLAD_API_CALL PFNGLXRELEASEVIDEODEVICENVPROC glad_glXReleaseVideoDeviceNV; + GLAD_API_CALL PFNGLXRELEASEVIDEODEVICENVPROC glad_glXReleaseVideoDeviceNV; #define glXReleaseVideoDeviceNV glad_glXReleaseVideoDeviceNV -GLAD_API_CALL PFNGLXGETFBCONFIGFROMVISUALSGIXPROC glad_glXGetFBConfigFromVisualSGIX; + GLAD_API_CALL PFNGLXGETFBCONFIGFROMVISUALSGIXPROC glad_glXGetFBConfigFromVisualSGIX; #define glXGetFBConfigFromVisualSGIX glad_glXGetFBConfigFromVisualSGIX -GLAD_API_CALL PFNGLXCREATENEWCONTEXTPROC glad_glXCreateNewContext; + GLAD_API_CALL PFNGLXCREATENEWCONTEXTPROC glad_glXCreateNewContext; #define glXCreateNewContext glad_glXCreateNewContext -GLAD_API_CALL PFNGLXMAKECONTEXTCURRENTPROC glad_glXMakeContextCurrent; + GLAD_API_CALL PFNGLXMAKECONTEXTCURRENTPROC glad_glXMakeContextCurrent; #define glXMakeContextCurrent glad_glXMakeContextCurrent -GLAD_API_CALL PFNGLXQUERYMAXSWAPGROUPSNVPROC glad_glXQueryMaxSwapGroupsNV; + GLAD_API_CALL PFNGLXQUERYMAXSWAPGROUPSNVPROC glad_glXQueryMaxSwapGroupsNV; #define glXQueryMaxSwapGroupsNV glad_glXQueryMaxSwapGroupsNV -GLAD_API_CALL PFNGLXGETVISUALFROMFBCONFIGSGIXPROC glad_glXGetVisualFromFBConfigSGIX; + GLAD_API_CALL PFNGLXGETVISUALFROMFBCONFIGSGIXPROC glad_glXGetVisualFromFBConfigSGIX; #define glXGetVisualFromFBConfigSGIX glad_glXGetVisualFromFBConfigSGIX -GLAD_API_CALL PFNGLXGETCURRENTDRAWABLEPROC glad_glXGetCurrentDrawable; + GLAD_API_CALL PFNGLXGETCURRENTDRAWABLEPROC glad_glXGetCurrentDrawable; #define glXGetCurrentDrawable glad_glXGetCurrentDrawable -GLAD_API_CALL PFNGLXGETCURRENTREADDRAWABLESGIPROC glad_glXGetCurrentReadDrawableSGI; + GLAD_API_CALL PFNGLXGETCURRENTREADDRAWABLESGIPROC glad_glXGetCurrentReadDrawableSGI; #define glXGetCurrentReadDrawableSGI glad_glXGetCurrentReadDrawableSGI -GLAD_API_CALL PFNGLXQUERYFRAMECOUNTNVPROC glad_glXQueryFrameCountNV; + GLAD_API_CALL PFNGLXQUERYFRAMECOUNTNVPROC glad_glXQueryFrameCountNV; #define glXQueryFrameCountNV glad_glXQueryFrameCountNV -GLAD_API_CALL PFNGLXGETCONTEXTGPUIDAMDPROC glad_glXGetContextGPUIDAMD; + GLAD_API_CALL PFNGLXGETCONTEXTGPUIDAMDPROC glad_glXGetContextGPUIDAMD; #define glXGetContextGPUIDAMD glad_glXGetContextGPUIDAMD -GLAD_API_CALL PFNGLXBINDSWAPBARRIERSGIXPROC glad_glXBindSwapBarrierSGIX; + GLAD_API_CALL PFNGLXBINDSWAPBARRIERSGIXPROC glad_glXBindSwapBarrierSGIX; #define glXBindSwapBarrierSGIX glad_glXBindSwapBarrierSGIX -GLAD_API_CALL PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC glad_glXQueryMaxSwapBarriersSGIX; + GLAD_API_CALL PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC glad_glXQueryMaxSwapBarriersSGIX; #define glXQueryMaxSwapBarriersSGIX glad_glXQueryMaxSwapBarriersSGIX -GLAD_API_CALL PFNGLXCREATEGLXPIXMAPMESAPROC glad_glXCreateGLXPixmapMESA; + GLAD_API_CALL PFNGLXCREATEGLXPIXMAPMESAPROC glad_glXCreateGLXPixmapMESA; #define glXCreateGLXPixmapMESA glad_glXCreateGLXPixmapMESA -GLAD_API_CALL PFNGLXMAKECURRENTPROC glad_glXMakeCurrent; + GLAD_API_CALL PFNGLXMAKECURRENTPROC glad_glXMakeCurrent; #define glXMakeCurrent glad_glXMakeCurrent -GLAD_API_CALL PFNGLXDESTROYWINDOWPROC glad_glXDestroyWindow; + GLAD_API_CALL PFNGLXDESTROYWINDOWPROC glad_glXDestroyWindow; #define glXDestroyWindow glad_glXDestroyWindow -GLAD_API_CALL PFNGLXBINDVIDEOIMAGENVPROC glad_glXBindVideoImageNV; + GLAD_API_CALL PFNGLXBINDVIDEOIMAGENVPROC glad_glXBindVideoImageNV; #define glXBindVideoImageNV glad_glXBindVideoImageNV -GLAD_API_CALL PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC glad_glXQueryVideoCaptureDeviceNV; + GLAD_API_CALL PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC glad_glXQueryVideoCaptureDeviceNV; #define glXQueryVideoCaptureDeviceNV glad_glXQueryVideoCaptureDeviceNV -GLAD_API_CALL PFNGLXQUERYCHANNELDELTASSGIXPROC glad_glXQueryChannelDeltasSGIX; + GLAD_API_CALL PFNGLXQUERYCHANNELDELTASSGIXPROC glad_glXQueryChannelDeltasSGIX; #define glXQueryChannelDeltasSGIX glad_glXQueryChannelDeltasSGIX -GLAD_API_CALL PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC glad_glXEnumerateVideoCaptureDevicesNV; + GLAD_API_CALL PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC glad_glXEnumerateVideoCaptureDevicesNV; #define glXEnumerateVideoCaptureDevicesNV glad_glXEnumerateVideoCaptureDevicesNV -GLAD_API_CALL PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC glad_glXCreateAssociatedContextAttribsAMD; + GLAD_API_CALL PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC glad_glXCreateAssociatedContextAttribsAMD; #define glXCreateAssociatedContextAttribsAMD glad_glXCreateAssociatedContextAttribsAMD -GLAD_API_CALL PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC glad_glXGetCurrentAssociatedContextAMD; + GLAD_API_CALL PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC glad_glXGetCurrentAssociatedContextAMD; #define glXGetCurrentAssociatedContextAMD glad_glXGetCurrentAssociatedContextAMD -GLAD_API_CALL PFNGLXQUERYCHANNELRECTSGIXPROC glad_glXQueryChannelRectSGIX; + GLAD_API_CALL PFNGLXQUERYCHANNELRECTSGIXPROC glad_glXQueryChannelRectSGIX; #define glXQueryChannelRectSGIX glad_glXQueryChannelRectSGIX -GLAD_API_CALL PFNGLXCREATECONTEXTPROC glad_glXCreateContext; + GLAD_API_CALL PFNGLXCREATECONTEXTPROC glad_glXCreateContext; #define glXCreateContext glad_glXCreateContext -GLAD_API_CALL PFNGLXFREECONTEXTEXTPROC glad_glXFreeContextEXT; + GLAD_API_CALL PFNGLXFREECONTEXTEXTPROC glad_glXFreeContextEXT; #define glXFreeContextEXT glad_glXFreeContextEXT -GLAD_API_CALL PFNGLXGETCONTEXTIDEXTPROC glad_glXGetContextIDEXT; + GLAD_API_CALL PFNGLXGETCONTEXTIDEXTPROC glad_glXGetContextIDEXT; #define glXGetContextIDEXT glad_glXGetContextIDEXT -GLAD_API_CALL PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC glad_glXQueryCurrentRendererIntegerMESA; + GLAD_API_CALL PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC glad_glXQueryCurrentRendererIntegerMESA; #define glXQueryCurrentRendererIntegerMESA glad_glXQueryCurrentRendererIntegerMESA -GLAD_API_CALL PFNGLXCHOOSEFBCONFIGPROC glad_glXChooseFBConfig; + GLAD_API_CALL PFNGLXCHOOSEFBCONFIGPROC glad_glXChooseFBConfig; #define glXChooseFBConfig glad_glXChooseFBConfig -GLAD_API_CALL PFNGLXBINDCHANNELTOWINDOWSGIXPROC glad_glXBindChannelToWindowSGIX; + GLAD_API_CALL PFNGLXBINDCHANNELTOWINDOWSGIXPROC glad_glXBindChannelToWindowSGIX; #define glXBindChannelToWindowSGIX glad_glXBindChannelToWindowSGIX -GLAD_API_CALL PFNGLXCHANNELRECTSYNCSGIXPROC glad_glXChannelRectSyncSGIX; + GLAD_API_CALL PFNGLXCHANNELRECTSYNCSGIXPROC glad_glXChannelRectSyncSGIX; #define glXChannelRectSyncSGIX glad_glXChannelRectSyncSGIX -GLAD_API_CALL PFNGLXIMPORTCONTEXTEXTPROC glad_glXImportContextEXT; + GLAD_API_CALL PFNGLXIMPORTCONTEXTEXTPROC glad_glXImportContextEXT; #define glXImportContextEXT glad_glXImportContextEXT -GLAD_API_CALL PFNGLXRELEASEBUFFERSMESAPROC glad_glXReleaseBuffersMESA; + GLAD_API_CALL PFNGLXRELEASEBUFFERSMESAPROC glad_glXReleaseBuffersMESA; #define glXReleaseBuffersMESA glad_glXReleaseBuffersMESA -GLAD_API_CALL PFNGLXCREATEPIXMAPPROC glad_glXCreatePixmap; + GLAD_API_CALL PFNGLXCREATEPIXMAPPROC glad_glXCreatePixmap; #define glXCreatePixmap glad_glXCreatePixmap -GLAD_API_CALL PFNGLXGETAGPOFFSETMESAPROC glad_glXGetAGPOffsetMESA; + GLAD_API_CALL PFNGLXGETAGPOFFSETMESAPROC glad_glXGetAGPOffsetMESA; #define glXGetAGPOffsetMESA glad_glXGetAGPOffsetMESA - -GLAD_API_CALL int gladLoadGLXUserPtr(Display *display, int screen, GLADuserptrloadfunc load, void *userptr); -GLAD_API_CALL int gladLoadGLX(Display *display, int screen, GLADloadfunc load); - - - + GLAD_API_CALL int gladLoadGLXUserPtr(Display *display, int screen, GLADuserptrloadfunc load, void *userptr); + GLAD_API_CALL int gladLoadGLX(Display *display, int screen, GLADloadfunc load); #ifdef GLAD_GLX -GLAD_API_CALL int gladLoaderLoadGLX(Display *display, int screen); + GLAD_API_CALL int gladLoaderLoadGLX(Display *display, int screen); -GLAD_API_CALL void gladLoaderUnloadGLX(void); + GLAD_API_CALL void gladLoaderUnloadGLX(void); #endif #ifdef __cplusplus diff --git a/examples/ThirdPartyLibs/glad/glx.c b/examples/ThirdPartyLibs/glad/glx.c index 3333686d7..86eed1df2 100644 --- a/examples/ThirdPartyLibs/glad/glx.c +++ b/examples/ThirdPartyLibs/glad/glx.c @@ -6,35 +6,56 @@ #include #endif -typedef Display* (* PFNXOPENDISPLAY) (_Xconst char* a); -typedef Screen* (* PFNXDEFAULTSCREENOFDISPLAY) (Display*); -typedef int (* PFNXSCREENNUMBEROFSCREEN) (Screen*); +typedef Display* (*PFNXOPENDISPLAY)(_Xconst char* a); +typedef Screen* (*PFNXDEFAULTSCREENOFDISPLAY)(Display*); +typedef int (*PFNXSCREENNUMBEROFSCREEN)(Screen*); typedef struct { - void* library; - PFNXOPENDISPLAY XOpenDisplay; - PFNXDEFAULTSCREENOFDISPLAY XDefaultScreenOfDisplay; - PFNXSCREENNUMBEROFSCREEN XScreenNumberOfScreen; + void* library; + PFNXOPENDISPLAY XOpenDisplay; + PFNXDEFAULTSCREENOFDISPLAY XDefaultScreenOfDisplay; + PFNXSCREENNUMBEROFSCREEN XScreenNumberOfScreen; } X11Struct; #ifdef DYNAMIC_LOAD_X11_FUNCTIONS -void initX11Struct(X11Struct *x11) { - const char *X11_LIBRARY = "libX11.so.6"; - x11->library = dlopen(X11_LIBRARY, RTLD_LOCAL | RTLD_NOW); - if (!x11->library) { fprintf(stderr, "Error opening X11 library %s\n", X11_LIBRARY); exit(EXIT_FAILURE); } - int missingFunc = 0; - missingFunc = ((x11->XOpenDisplay = (PFNXOPENDISPLAY) dlsym(x11->library,"XOpenDisplay"))==NULL) | missingFunc; - if (missingFunc) { fprintf(stderr, "Error: missing func XOpenDisplay in %s, exiting!\n", X11_LIBRARY); exit(EXIT_FAILURE);} - missingFunc = ((x11->XDefaultScreenOfDisplay = (PFNXDEFAULTSCREENOFDISPLAY) dlsym(x11->library,"XDefaultScreenOfDisplay"))==NULL) | missingFunc; - if (missingFunc) { fprintf(stderr, "Error: missing func XScreenNumberOfScreen in %s, exiting!\n", X11_LIBRARY); exit(EXIT_FAILURE);} - missingFunc = ((x11->XScreenNumberOfScreen = (PFNXSCREENNUMBEROFSCREEN) dlsym(x11->library,"XScreenNumberOfScreen"))==NULL) | missingFunc; - if (missingFunc) { fprintf(stderr, "Error: missing func XScreenNumberOfScreen in %s, exiting!\n", X11_LIBRARY); exit(EXIT_FAILURE);} - if (!missingFunc) { printf("X11 functions dynamically loaded using dlopen/dlsym OK!\n");} +void initX11Struct(X11Struct* x11) +{ + const char* X11_LIBRARY = "libX11.so.6"; + x11->library = dlopen(X11_LIBRARY, RTLD_LOCAL | RTLD_NOW); + if (!x11->library) + { + fprintf(stderr, "Error opening X11 library %s\n", X11_LIBRARY); + exit(EXIT_FAILURE); + } + int missingFunc = 0; + missingFunc = ((x11->XOpenDisplay = (PFNXOPENDISPLAY)dlsym(x11->library, "XOpenDisplay")) == NULL) | missingFunc; + if (missingFunc) + { + fprintf(stderr, "Error: missing func XOpenDisplay in %s, exiting!\n", X11_LIBRARY); + exit(EXIT_FAILURE); + } + missingFunc = ((x11->XDefaultScreenOfDisplay = (PFNXDEFAULTSCREENOFDISPLAY)dlsym(x11->library, "XDefaultScreenOfDisplay")) == NULL) | missingFunc; + if (missingFunc) + { + fprintf(stderr, "Error: missing func XScreenNumberOfScreen in %s, exiting!\n", X11_LIBRARY); + exit(EXIT_FAILURE); + } + missingFunc = ((x11->XScreenNumberOfScreen = (PFNXSCREENNUMBEROFSCREEN)dlsym(x11->library, "XScreenNumberOfScreen")) == NULL) | missingFunc; + if (missingFunc) + { + fprintf(stderr, "Error: missing func XScreenNumberOfScreen in %s, exiting!\n", X11_LIBRARY); + exit(EXIT_FAILURE); + } + if (!missingFunc) + { + printf("X11 functions dynamically loaded using dlopen/dlsym OK!\n"); + } } #else -void initX11Struct(X11Struct *x11) { - x11->XOpenDisplay = XOpenDisplay; - x11->XDefaultScreenOfDisplay = XDefaultScreenOfDisplay; - x11->XScreenNumberOfScreen = XScreenNumberOfScreen; +void initX11Struct(X11Struct* x11) +{ + x11->XOpenDisplay = XOpenDisplay; + x11->XDefaultScreenOfDisplay = XDefaultScreenOfDisplay; + x11->XScreenNumberOfScreen = XScreenNumberOfScreen; } #endif // DYNAMIC_LOAD_X11_FUNCTIONS @@ -42,7 +63,7 @@ void initX11Struct(X11Struct *x11) { #define GLAD_IMPL_UTIL_C_ #if _MSC_VER >= 1400 -#define GLAD_IMPL_UTIL_STRNCPY(dest, source, len) strncpy_s(dest, len, source, len-1); +#define GLAD_IMPL_UTIL_STRNCPY(dest, source, len) strncpy_s(dest, len, source, len - 1); #else #define GLAD_IMPL_UTIL_STRNCPY(dest, source, len) strncpy(dest, source, len); #endif @@ -55,9 +76,6 @@ void initX11Struct(X11Struct *x11) { #endif /* GLAD_IMPL_UTIL_C_ */ - - - int GLAD_GLX_VERSION_1_0; int GLAD_GLX_VERSION_1_1; int GLAD_GLX_VERSION_1_2; @@ -127,8 +145,6 @@ int GLAD_GLX_SGIX_swap_group; int GLAD_GLX_ARB_vertex_buffer_object; int GLAD_GLX_NV_multisample_coverage; - - PFNGLXCUSHIONSGIPROC glad_glXCushionSGI; PFNGLXDESTROYGLXPBUFFERSGIXPROC glad_glXDestroyGLXPbufferSGIX; PFNGLXSENDPBUFFERTOVIDEONVPROC glad_glXSendPbufferToVideoNV; @@ -261,427 +277,469 @@ PFNGLXRELEASEBUFFERSMESAPROC glad_glXReleaseBuffersMESA; PFNGLXCREATEPIXMAPPROC glad_glXCreatePixmap; PFNGLXGETAGPOFFSETMESAPROC glad_glXGetAGPOffsetMESA; - -static void load_GLX_VERSION_1_0( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_VERSION_1_0) return; - glXWaitGL = (PFNGLXWAITGLPROC) load("glXWaitGL", userptr); - glXWaitX = (PFNGLXWAITXPROC) load("glXWaitX", userptr); - glXGetConfig = (PFNGLXGETCONFIGPROC) load("glXGetConfig", userptr); - glXQueryVersion = (PFNGLXQUERYVERSIONPROC) load("glXQueryVersion", userptr); - glXCreateContext = (PFNGLXCREATECONTEXTPROC) load("glXCreateContext", userptr); - glXQueryExtension = (PFNGLXQUERYEXTENSIONPROC) load("glXQueryExtension", userptr); - glXGetCurrentContext = (PFNGLXGETCURRENTCONTEXTPROC) load("glXGetCurrentContext", userptr); - glXMakeCurrent = (PFNGLXMAKECURRENTPROC) load("glXMakeCurrent", userptr); - glXCopyContext = (PFNGLXCOPYCONTEXTPROC) load("glXCopyContext", userptr); - glXIsDirect = (PFNGLXISDIRECTPROC) load("glXIsDirect", userptr); - glXCreateGLXPixmap = (PFNGLXCREATEGLXPIXMAPPROC) load("glXCreateGLXPixmap", userptr); - glXGetCurrentDrawable = (PFNGLXGETCURRENTDRAWABLEPROC) load("glXGetCurrentDrawable", userptr); - glXUseXFont = (PFNGLXUSEXFONTPROC) load("glXUseXFont", userptr); - glXChooseVisual = (PFNGLXCHOOSEVISUALPROC) load("glXChooseVisual", userptr); - glXDestroyContext = (PFNGLXDESTROYCONTEXTPROC) load("glXDestroyContext", userptr); - glXDestroyGLXPixmap = (PFNGLXDESTROYGLXPIXMAPPROC) load("glXDestroyGLXPixmap", userptr); - glXSwapBuffers = (PFNGLXSWAPBUFFERSPROC) load("glXSwapBuffers", userptr); +static void load_GLX_VERSION_1_0(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_VERSION_1_0) return; + glXWaitGL = (PFNGLXWAITGLPROC)load("glXWaitGL", userptr); + glXWaitX = (PFNGLXWAITXPROC)load("glXWaitX", userptr); + glXGetConfig = (PFNGLXGETCONFIGPROC)load("glXGetConfig", userptr); + glXQueryVersion = (PFNGLXQUERYVERSIONPROC)load("glXQueryVersion", userptr); + glXCreateContext = (PFNGLXCREATECONTEXTPROC)load("glXCreateContext", userptr); + glXQueryExtension = (PFNGLXQUERYEXTENSIONPROC)load("glXQueryExtension", userptr); + glXGetCurrentContext = (PFNGLXGETCURRENTCONTEXTPROC)load("glXGetCurrentContext", userptr); + glXMakeCurrent = (PFNGLXMAKECURRENTPROC)load("glXMakeCurrent", userptr); + glXCopyContext = (PFNGLXCOPYCONTEXTPROC)load("glXCopyContext", userptr); + glXIsDirect = (PFNGLXISDIRECTPROC)load("glXIsDirect", userptr); + glXCreateGLXPixmap = (PFNGLXCREATEGLXPIXMAPPROC)load("glXCreateGLXPixmap", userptr); + glXGetCurrentDrawable = (PFNGLXGETCURRENTDRAWABLEPROC)load("glXGetCurrentDrawable", userptr); + glXUseXFont = (PFNGLXUSEXFONTPROC)load("glXUseXFont", userptr); + glXChooseVisual = (PFNGLXCHOOSEVISUALPROC)load("glXChooseVisual", userptr); + glXDestroyContext = (PFNGLXDESTROYCONTEXTPROC)load("glXDestroyContext", userptr); + glXDestroyGLXPixmap = (PFNGLXDESTROYGLXPIXMAPPROC)load("glXDestroyGLXPixmap", userptr); + glXSwapBuffers = (PFNGLXSWAPBUFFERSPROC)load("glXSwapBuffers", userptr); } -static void load_GLX_VERSION_1_1( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_VERSION_1_1) return; - glXQueryServerString = (PFNGLXQUERYSERVERSTRINGPROC) load("glXQueryServerString", userptr); - glXGetClientString = (PFNGLXGETCLIENTSTRINGPROC) load("glXGetClientString", userptr); - glXQueryExtensionsString = (PFNGLXQUERYEXTENSIONSSTRINGPROC) load("glXQueryExtensionsString", userptr); +static void load_GLX_VERSION_1_1(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_VERSION_1_1) return; + glXQueryServerString = (PFNGLXQUERYSERVERSTRINGPROC)load("glXQueryServerString", userptr); + glXGetClientString = (PFNGLXGETCLIENTSTRINGPROC)load("glXGetClientString", userptr); + glXQueryExtensionsString = (PFNGLXQUERYEXTENSIONSSTRINGPROC)load("glXQueryExtensionsString", userptr); } -static void load_GLX_VERSION_1_2( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_VERSION_1_2) return; - glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC) load("glXGetCurrentDisplay", userptr); +static void load_GLX_VERSION_1_2(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_VERSION_1_2) return; + glXGetCurrentDisplay = (PFNGLXGETCURRENTDISPLAYPROC)load("glXGetCurrentDisplay", userptr); } -static void load_GLX_VERSION_1_3( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_VERSION_1_3) return; - glXQueryContext = (PFNGLXQUERYCONTEXTPROC) load("glXQueryContext", userptr); - glXGetFBConfigs = (PFNGLXGETFBCONFIGSPROC) load("glXGetFBConfigs", userptr); - glXDestroyPixmap = (PFNGLXDESTROYPIXMAPPROC) load("glXDestroyPixmap", userptr); - glXCreateNewContext = (PFNGLXCREATENEWCONTEXTPROC) load("glXCreateNewContext", userptr); - glXGetCurrentReadDrawable = (PFNGLXGETCURRENTREADDRAWABLEPROC) load("glXGetCurrentReadDrawable", userptr); - glXMakeContextCurrent = (PFNGLXMAKECONTEXTCURRENTPROC) load("glXMakeContextCurrent", userptr); - glXDestroyWindow = (PFNGLXDESTROYWINDOWPROC) load("glXDestroyWindow", userptr); - glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC) load("glXChooseFBConfig", userptr); - glXCreatePixmap = (PFNGLXCREATEPIXMAPPROC) load("glXCreatePixmap", userptr); - glXSelectEvent = (PFNGLXSELECTEVENTPROC) load("glXSelectEvent", userptr); - glXGetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC) load("glXGetFBConfigAttrib", userptr); - glXDestroyPbuffer = (PFNGLXDESTROYPBUFFERPROC) load("glXDestroyPbuffer", userptr); - glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC) load("glXCreatePbuffer", userptr); - glXCreateWindow = (PFNGLXCREATEWINDOWPROC) load("glXCreateWindow", userptr); - glXGetSelectedEvent = (PFNGLXGETSELECTEDEVENTPROC) load("glXGetSelectedEvent", userptr); - glXQueryDrawable = (PFNGLXQUERYDRAWABLEPROC) load("glXQueryDrawable", userptr); - glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC) load("glXGetVisualFromFBConfig", userptr); +static void load_GLX_VERSION_1_3(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_VERSION_1_3) return; + glXQueryContext = (PFNGLXQUERYCONTEXTPROC)load("glXQueryContext", userptr); + glXGetFBConfigs = (PFNGLXGETFBCONFIGSPROC)load("glXGetFBConfigs", userptr); + glXDestroyPixmap = (PFNGLXDESTROYPIXMAPPROC)load("glXDestroyPixmap", userptr); + glXCreateNewContext = (PFNGLXCREATENEWCONTEXTPROC)load("glXCreateNewContext", userptr); + glXGetCurrentReadDrawable = (PFNGLXGETCURRENTREADDRAWABLEPROC)load("glXGetCurrentReadDrawable", userptr); + glXMakeContextCurrent = (PFNGLXMAKECONTEXTCURRENTPROC)load("glXMakeContextCurrent", userptr); + glXDestroyWindow = (PFNGLXDESTROYWINDOWPROC)load("glXDestroyWindow", userptr); + glXChooseFBConfig = (PFNGLXCHOOSEFBCONFIGPROC)load("glXChooseFBConfig", userptr); + glXCreatePixmap = (PFNGLXCREATEPIXMAPPROC)load("glXCreatePixmap", userptr); + glXSelectEvent = (PFNGLXSELECTEVENTPROC)load("glXSelectEvent", userptr); + glXGetFBConfigAttrib = (PFNGLXGETFBCONFIGATTRIBPROC)load("glXGetFBConfigAttrib", userptr); + glXDestroyPbuffer = (PFNGLXDESTROYPBUFFERPROC)load("glXDestroyPbuffer", userptr); + glXCreatePbuffer = (PFNGLXCREATEPBUFFERPROC)load("glXCreatePbuffer", userptr); + glXCreateWindow = (PFNGLXCREATEWINDOWPROC)load("glXCreateWindow", userptr); + glXGetSelectedEvent = (PFNGLXGETSELECTEDEVENTPROC)load("glXGetSelectedEvent", userptr); + glXQueryDrawable = (PFNGLXQUERYDRAWABLEPROC)load("glXQueryDrawable", userptr); + glXGetVisualFromFBConfig = (PFNGLXGETVISUALFROMFBCONFIGPROC)load("glXGetVisualFromFBConfig", userptr); } -static void load_GLX_VERSION_1_4( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_VERSION_1_4) return; - glXGetProcAddress = (PFNGLXGETPROCADDRESSPROC) load("glXGetProcAddress", userptr); +static void load_GLX_VERSION_1_4(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_VERSION_1_4) return; + glXGetProcAddress = (PFNGLXGETPROCADDRESSPROC)load("glXGetProcAddress", userptr); } -static void load_GLX_MESA_copy_sub_buffer( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_MESA_copy_sub_buffer) return; - glXCopySubBufferMESA = (PFNGLXCOPYSUBBUFFERMESAPROC) load("glXCopySubBufferMESA", userptr); +static void load_GLX_MESA_copy_sub_buffer(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_MESA_copy_sub_buffer) return; + glXCopySubBufferMESA = (PFNGLXCOPYSUBBUFFERMESAPROC)load("glXCopySubBufferMESA", userptr); } -static void load_GLX_SGIX_pbuffer( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_SGIX_pbuffer) return; - glXDestroyGLXPbufferSGIX = (PFNGLXDESTROYGLXPBUFFERSGIXPROC) load("glXDestroyGLXPbufferSGIX", userptr); - glXQueryGLXPbufferSGIX = (PFNGLXQUERYGLXPBUFFERSGIXPROC) load("glXQueryGLXPbufferSGIX", userptr); - glXCreateGLXPbufferSGIX = (PFNGLXCREATEGLXPBUFFERSGIXPROC) load("glXCreateGLXPbufferSGIX", userptr); - glXGetSelectedEventSGIX = (PFNGLXGETSELECTEDEVENTSGIXPROC) load("glXGetSelectedEventSGIX", userptr); - glXSelectEventSGIX = (PFNGLXSELECTEVENTSGIXPROC) load("glXSelectEventSGIX", userptr); +static void load_GLX_SGIX_pbuffer(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_SGIX_pbuffer) return; + glXDestroyGLXPbufferSGIX = (PFNGLXDESTROYGLXPBUFFERSGIXPROC)load("glXDestroyGLXPbufferSGIX", userptr); + glXQueryGLXPbufferSGIX = (PFNGLXQUERYGLXPBUFFERSGIXPROC)load("glXQueryGLXPbufferSGIX", userptr); + glXCreateGLXPbufferSGIX = (PFNGLXCREATEGLXPBUFFERSGIXPROC)load("glXCreateGLXPbufferSGIX", userptr); + glXGetSelectedEventSGIX = (PFNGLXGETSELECTEDEVENTSGIXPROC)load("glXGetSelectedEventSGIX", userptr); + glXSelectEventSGIX = (PFNGLXSELECTEVENTSGIXPROC)load("glXSelectEventSGIX", userptr); } -static void load_GLX_SGI_make_current_read( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_SGI_make_current_read) return; - glXGetCurrentReadDrawableSGI = (PFNGLXGETCURRENTREADDRAWABLESGIPROC) load("glXGetCurrentReadDrawableSGI", userptr); - glXMakeCurrentReadSGI = (PFNGLXMAKECURRENTREADSGIPROC) load("glXMakeCurrentReadSGI", userptr); +static void load_GLX_SGI_make_current_read(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_SGI_make_current_read) return; + glXGetCurrentReadDrawableSGI = (PFNGLXGETCURRENTREADDRAWABLESGIPROC)load("glXGetCurrentReadDrawableSGI", userptr); + glXMakeCurrentReadSGI = (PFNGLXMAKECURRENTREADSGIPROC)load("glXMakeCurrentReadSGI", userptr); } -static void load_GLX_OML_sync_control( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_OML_sync_control) return; - glXWaitForMscOML = (PFNGLXWAITFORMSCOMLPROC) load("glXWaitForMscOML", userptr); - glXGetSyncValuesOML = (PFNGLXGETSYNCVALUESOMLPROC) load("glXGetSyncValuesOML", userptr); - glXWaitForSbcOML = (PFNGLXWAITFORSBCOMLPROC) load("glXWaitForSbcOML", userptr); - glXSwapBuffersMscOML = (PFNGLXSWAPBUFFERSMSCOMLPROC) load("glXSwapBuffersMscOML", userptr); - glXGetMscRateOML = (PFNGLXGETMSCRATEOMLPROC) load("glXGetMscRateOML", userptr); +static void load_GLX_OML_sync_control(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_OML_sync_control) return; + glXWaitForMscOML = (PFNGLXWAITFORMSCOMLPROC)load("glXWaitForMscOML", userptr); + glXGetSyncValuesOML = (PFNGLXGETSYNCVALUESOMLPROC)load("glXGetSyncValuesOML", userptr); + glXWaitForSbcOML = (PFNGLXWAITFORSBCOMLPROC)load("glXWaitForSbcOML", userptr); + glXSwapBuffersMscOML = (PFNGLXSWAPBUFFERSMSCOMLPROC)load("glXSwapBuffersMscOML", userptr); + glXGetMscRateOML = (PFNGLXGETMSCRATEOMLPROC)load("glXGetMscRateOML", userptr); } -static void load_GLX_SGIX_hyperpipe( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_SGIX_hyperpipe) return; - glXQueryHyperpipeBestAttribSGIX = (PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC) load("glXQueryHyperpipeBestAttribSGIX", userptr); - glXQueryHyperpipeAttribSGIX = (PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC) load("glXQueryHyperpipeAttribSGIX", userptr); - glXDestroyHyperpipeConfigSGIX = (PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC) load("glXDestroyHyperpipeConfigSGIX", userptr); - glXHyperpipeConfigSGIX = (PFNGLXHYPERPIPECONFIGSGIXPROC) load("glXHyperpipeConfigSGIX", userptr); - glXHyperpipeAttribSGIX = (PFNGLXHYPERPIPEATTRIBSGIXPROC) load("glXHyperpipeAttribSGIX", userptr); - glXQueryHyperpipeConfigSGIX = (PFNGLXQUERYHYPERPIPECONFIGSGIXPROC) load("glXQueryHyperpipeConfigSGIX", userptr); - glXQueryHyperpipeNetworkSGIX = (PFNGLXQUERYHYPERPIPENETWORKSGIXPROC) load("glXQueryHyperpipeNetworkSGIX", userptr); - glXBindHyperpipeSGIX = (PFNGLXBINDHYPERPIPESGIXPROC) load("glXBindHyperpipeSGIX", userptr); +static void load_GLX_SGIX_hyperpipe(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_SGIX_hyperpipe) return; + glXQueryHyperpipeBestAttribSGIX = (PFNGLXQUERYHYPERPIPEBESTATTRIBSGIXPROC)load("glXQueryHyperpipeBestAttribSGIX", userptr); + glXQueryHyperpipeAttribSGIX = (PFNGLXQUERYHYPERPIPEATTRIBSGIXPROC)load("glXQueryHyperpipeAttribSGIX", userptr); + glXDestroyHyperpipeConfigSGIX = (PFNGLXDESTROYHYPERPIPECONFIGSGIXPROC)load("glXDestroyHyperpipeConfigSGIX", userptr); + glXHyperpipeConfigSGIX = (PFNGLXHYPERPIPECONFIGSGIXPROC)load("glXHyperpipeConfigSGIX", userptr); + glXHyperpipeAttribSGIX = (PFNGLXHYPERPIPEATTRIBSGIXPROC)load("glXHyperpipeAttribSGIX", userptr); + glXQueryHyperpipeConfigSGIX = (PFNGLXQUERYHYPERPIPECONFIGSGIXPROC)load("glXQueryHyperpipeConfigSGIX", userptr); + glXQueryHyperpipeNetworkSGIX = (PFNGLXQUERYHYPERPIPENETWORKSGIXPROC)load("glXQueryHyperpipeNetworkSGIX", userptr); + glXBindHyperpipeSGIX = (PFNGLXBINDHYPERPIPESGIXPROC)load("glXBindHyperpipeSGIX", userptr); } -static void load_GLX_EXT_swap_control( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_EXT_swap_control) return; - glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC) load("glXSwapIntervalEXT", userptr); +static void load_GLX_EXT_swap_control(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_EXT_swap_control) return; + glXSwapIntervalEXT = (PFNGLXSWAPINTERVALEXTPROC)load("glXSwapIntervalEXT", userptr); } -static void load_GLX_MESA_pixmap_colormap( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_MESA_pixmap_colormap) return; - glXCreateGLXPixmapMESA = (PFNGLXCREATEGLXPIXMAPMESAPROC) load("glXCreateGLXPixmapMESA", userptr); +static void load_GLX_MESA_pixmap_colormap(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_MESA_pixmap_colormap) return; + glXCreateGLXPixmapMESA = (PFNGLXCREATEGLXPIXMAPMESAPROC)load("glXCreateGLXPixmapMESA", userptr); } -static void load_GLX_NV_video_capture( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_NV_video_capture) return; - glXQueryVideoCaptureDeviceNV = (PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC) load("glXQueryVideoCaptureDeviceNV", userptr); - glXEnumerateVideoCaptureDevicesNV = (PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC) load("glXEnumerateVideoCaptureDevicesNV", userptr); - glXBindVideoCaptureDeviceNV = (PFNGLXBINDVIDEOCAPTUREDEVICENVPROC) load("glXBindVideoCaptureDeviceNV", userptr); - glXLockVideoCaptureDeviceNV = (PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC) load("glXLockVideoCaptureDeviceNV", userptr); - glXReleaseVideoCaptureDeviceNV = (PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC) load("glXReleaseVideoCaptureDeviceNV", userptr); +static void load_GLX_NV_video_capture(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_NV_video_capture) return; + glXQueryVideoCaptureDeviceNV = (PFNGLXQUERYVIDEOCAPTUREDEVICENVPROC)load("glXQueryVideoCaptureDeviceNV", userptr); + glXEnumerateVideoCaptureDevicesNV = (PFNGLXENUMERATEVIDEOCAPTUREDEVICESNVPROC)load("glXEnumerateVideoCaptureDevicesNV", userptr); + glXBindVideoCaptureDeviceNV = (PFNGLXBINDVIDEOCAPTUREDEVICENVPROC)load("glXBindVideoCaptureDeviceNV", userptr); + glXLockVideoCaptureDeviceNV = (PFNGLXLOCKVIDEOCAPTUREDEVICENVPROC)load("glXLockVideoCaptureDeviceNV", userptr); + glXReleaseVideoCaptureDeviceNV = (PFNGLXRELEASEVIDEOCAPTUREDEVICENVPROC)load("glXReleaseVideoCaptureDeviceNV", userptr); } -static void load_GLX_NV_swap_group( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_NV_swap_group) return; - glXQueryFrameCountNV = (PFNGLXQUERYFRAMECOUNTNVPROC) load("glXQueryFrameCountNV", userptr); - glXQueryMaxSwapGroupsNV = (PFNGLXQUERYMAXSWAPGROUPSNVPROC) load("glXQueryMaxSwapGroupsNV", userptr); - glXResetFrameCountNV = (PFNGLXRESETFRAMECOUNTNVPROC) load("glXResetFrameCountNV", userptr); - glXJoinSwapGroupNV = (PFNGLXJOINSWAPGROUPNVPROC) load("glXJoinSwapGroupNV", userptr); - glXBindSwapBarrierNV = (PFNGLXBINDSWAPBARRIERNVPROC) load("glXBindSwapBarrierNV", userptr); - glXQuerySwapGroupNV = (PFNGLXQUERYSWAPGROUPNVPROC) load("glXQuerySwapGroupNV", userptr); +static void load_GLX_NV_swap_group(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_NV_swap_group) return; + glXQueryFrameCountNV = (PFNGLXQUERYFRAMECOUNTNVPROC)load("glXQueryFrameCountNV", userptr); + glXQueryMaxSwapGroupsNV = (PFNGLXQUERYMAXSWAPGROUPSNVPROC)load("glXQueryMaxSwapGroupsNV", userptr); + glXResetFrameCountNV = (PFNGLXRESETFRAMECOUNTNVPROC)load("glXResetFrameCountNV", userptr); + glXJoinSwapGroupNV = (PFNGLXJOINSWAPGROUPNVPROC)load("glXJoinSwapGroupNV", userptr); + glXBindSwapBarrierNV = (PFNGLXBINDSWAPBARRIERNVPROC)load("glXBindSwapBarrierNV", userptr); + glXQuerySwapGroupNV = (PFNGLXQUERYSWAPGROUPNVPROC)load("glXQuerySwapGroupNV", userptr); } -static void load_GLX_EXT_texture_from_pixmap( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_EXT_texture_from_pixmap) return; - glXReleaseTexImageEXT = (PFNGLXRELEASETEXIMAGEEXTPROC) load("glXReleaseTexImageEXT", userptr); - glXBindTexImageEXT = (PFNGLXBINDTEXIMAGEEXTPROC) load("glXBindTexImageEXT", userptr); +static void load_GLX_EXT_texture_from_pixmap(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_EXT_texture_from_pixmap) return; + glXReleaseTexImageEXT = (PFNGLXRELEASETEXIMAGEEXTPROC)load("glXReleaseTexImageEXT", userptr); + glXBindTexImageEXT = (PFNGLXBINDTEXIMAGEEXTPROC)load("glXBindTexImageEXT", userptr); } -static void load_GLX_SUN_get_transparent_index( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_SUN_get_transparent_index) return; - glXGetTransparentIndexSUN = (PFNGLXGETTRANSPARENTINDEXSUNPROC) load("glXGetTransparentIndexSUN", userptr); +static void load_GLX_SUN_get_transparent_index(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_SUN_get_transparent_index) return; + glXGetTransparentIndexSUN = (PFNGLXGETTRANSPARENTINDEXSUNPROC)load("glXGetTransparentIndexSUN", userptr); } -static void load_GLX_MESA_release_buffers( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_MESA_release_buffers) return; - glXReleaseBuffersMESA = (PFNGLXRELEASEBUFFERSMESAPROC) load("glXReleaseBuffersMESA", userptr); +static void load_GLX_MESA_release_buffers(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_MESA_release_buffers) return; + glXReleaseBuffersMESA = (PFNGLXRELEASEBUFFERSMESAPROC)load("glXReleaseBuffersMESA", userptr); } -static void load_GLX_NV_delay_before_swap( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_NV_delay_before_swap) return; - glXDelayBeforeSwapNV = (PFNGLXDELAYBEFORESWAPNVPROC) load("glXDelayBeforeSwapNV", userptr); +static void load_GLX_NV_delay_before_swap(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_NV_delay_before_swap) return; + glXDelayBeforeSwapNV = (PFNGLXDELAYBEFORESWAPNVPROC)load("glXDelayBeforeSwapNV", userptr); } -static void load_GLX_MESA_agp_offset( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_MESA_agp_offset) return; - glXGetAGPOffsetMESA = (PFNGLXGETAGPOFFSETMESAPROC) load("glXGetAGPOffsetMESA", userptr); +static void load_GLX_MESA_agp_offset(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_MESA_agp_offset) return; + glXGetAGPOffsetMESA = (PFNGLXGETAGPOFFSETMESAPROC)load("glXGetAGPOffsetMESA", userptr); } -static void load_GLX_SGI_swap_control( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_SGI_swap_control) return; - glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC) load("glXSwapIntervalSGI", userptr); +static void load_GLX_SGI_swap_control(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_SGI_swap_control) return; + glXSwapIntervalSGI = (PFNGLXSWAPINTERVALSGIPROC)load("glXSwapIntervalSGI", userptr); } -static void load_GLX_EXT_import_context( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_EXT_import_context) return; - glXGetCurrentDisplayEXT = (PFNGLXGETCURRENTDISPLAYEXTPROC) load("glXGetCurrentDisplayEXT", userptr); - glXImportContextEXT = (PFNGLXIMPORTCONTEXTEXTPROC) load("glXImportContextEXT", userptr); - glXFreeContextEXT = (PFNGLXFREECONTEXTEXTPROC) load("glXFreeContextEXT", userptr); - glXGetContextIDEXT = (PFNGLXGETCONTEXTIDEXTPROC) load("glXGetContextIDEXT", userptr); - glXQueryContextInfoEXT = (PFNGLXQUERYCONTEXTINFOEXTPROC) load("glXQueryContextInfoEXT", userptr); +static void load_GLX_EXT_import_context(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_EXT_import_context) return; + glXGetCurrentDisplayEXT = (PFNGLXGETCURRENTDISPLAYEXTPROC)load("glXGetCurrentDisplayEXT", userptr); + glXImportContextEXT = (PFNGLXIMPORTCONTEXTEXTPROC)load("glXImportContextEXT", userptr); + glXFreeContextEXT = (PFNGLXFREECONTEXTEXTPROC)load("glXFreeContextEXT", userptr); + glXGetContextIDEXT = (PFNGLXGETCONTEXTIDEXTPROC)load("glXGetContextIDEXT", userptr); + glXQueryContextInfoEXT = (PFNGLXQUERYCONTEXTINFOEXTPROC)load("glXQueryContextInfoEXT", userptr); } -static void load_GLX_SGI_video_sync( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_SGI_video_sync) return; - glXGetVideoSyncSGI = (PFNGLXGETVIDEOSYNCSGIPROC) load("glXGetVideoSyncSGI", userptr); - glXWaitVideoSyncSGI = (PFNGLXWAITVIDEOSYNCSGIPROC) load("glXWaitVideoSyncSGI", userptr); +static void load_GLX_SGI_video_sync(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_SGI_video_sync) return; + glXGetVideoSyncSGI = (PFNGLXGETVIDEOSYNCSGIPROC)load("glXGetVideoSyncSGI", userptr); + glXWaitVideoSyncSGI = (PFNGLXWAITVIDEOSYNCSGIPROC)load("glXWaitVideoSyncSGI", userptr); } -static void load_GLX_SGI_cushion( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_SGI_cushion) return; - glXCushionSGI = (PFNGLXCUSHIONSGIPROC) load("glXCushionSGI", userptr); +static void load_GLX_SGI_cushion(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_SGI_cushion) return; + glXCushionSGI = (PFNGLXCUSHIONSGIPROC)load("glXCushionSGI", userptr); } -static void load_GLX_SGIX_fbconfig( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_SGIX_fbconfig) return; - glXGetFBConfigAttribSGIX = (PFNGLXGETFBCONFIGATTRIBSGIXPROC) load("glXGetFBConfigAttribSGIX", userptr); - glXCreateGLXPixmapWithConfigSGIX = (PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC) load("glXCreateGLXPixmapWithConfigSGIX", userptr); - glXCreateContextWithConfigSGIX = (PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC) load("glXCreateContextWithConfigSGIX", userptr); - glXGetVisualFromFBConfigSGIX = (PFNGLXGETVISUALFROMFBCONFIGSGIXPROC) load("glXGetVisualFromFBConfigSGIX", userptr); - glXChooseFBConfigSGIX = (PFNGLXCHOOSEFBCONFIGSGIXPROC) load("glXChooseFBConfigSGIX", userptr); - glXGetFBConfigFromVisualSGIX = (PFNGLXGETFBCONFIGFROMVISUALSGIXPROC) load("glXGetFBConfigFromVisualSGIX", userptr); +static void load_GLX_SGIX_fbconfig(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_SGIX_fbconfig) return; + glXGetFBConfigAttribSGIX = (PFNGLXGETFBCONFIGATTRIBSGIXPROC)load("glXGetFBConfigAttribSGIX", userptr); + glXCreateGLXPixmapWithConfigSGIX = (PFNGLXCREATEGLXPIXMAPWITHCONFIGSGIXPROC)load("glXCreateGLXPixmapWithConfigSGIX", userptr); + glXCreateContextWithConfigSGIX = (PFNGLXCREATECONTEXTWITHCONFIGSGIXPROC)load("glXCreateContextWithConfigSGIX", userptr); + glXGetVisualFromFBConfigSGIX = (PFNGLXGETVISUALFROMFBCONFIGSGIXPROC)load("glXGetVisualFromFBConfigSGIX", userptr); + glXChooseFBConfigSGIX = (PFNGLXCHOOSEFBCONFIGSGIXPROC)load("glXChooseFBConfigSGIX", userptr); + glXGetFBConfigFromVisualSGIX = (PFNGLXGETFBCONFIGFROMVISUALSGIXPROC)load("glXGetFBConfigFromVisualSGIX", userptr); } -static void load_GLX_NV_copy_buffer( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_NV_copy_buffer) return; - glXNamedCopyBufferSubDataNV = (PFNGLXNAMEDCOPYBUFFERSUBDATANVPROC) load("glXNamedCopyBufferSubDataNV", userptr); - glXCopyBufferSubDataNV = (PFNGLXCOPYBUFFERSUBDATANVPROC) load("glXCopyBufferSubDataNV", userptr); +static void load_GLX_NV_copy_buffer(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_NV_copy_buffer) return; + glXNamedCopyBufferSubDataNV = (PFNGLXNAMEDCOPYBUFFERSUBDATANVPROC)load("glXNamedCopyBufferSubDataNV", userptr); + glXCopyBufferSubDataNV = (PFNGLXCOPYBUFFERSUBDATANVPROC)load("glXCopyBufferSubDataNV", userptr); } -static void load_GLX_ARB_create_context( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_ARB_create_context) return; - glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC) load("glXCreateContextAttribsARB", userptr); +static void load_GLX_ARB_create_context(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_ARB_create_context) return; + glXCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)load("glXCreateContextAttribsARB", userptr); } -static void load_GLX_AMD_gpu_association( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_AMD_gpu_association) return; - glXCreateAssociatedContextAttribsAMD = (PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) load("glXCreateAssociatedContextAttribsAMD", userptr); - glXBlitContextFramebufferAMD = (PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC) load("glXBlitContextFramebufferAMD", userptr); - glXGetCurrentAssociatedContextAMD = (PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC) load("glXGetCurrentAssociatedContextAMD", userptr); - glXGetContextGPUIDAMD = (PFNGLXGETCONTEXTGPUIDAMDPROC) load("glXGetContextGPUIDAMD", userptr); - glXMakeAssociatedContextCurrentAMD = (PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) load("glXMakeAssociatedContextCurrentAMD", userptr); - glXGetGPUIDsAMD = (PFNGLXGETGPUIDSAMDPROC) load("glXGetGPUIDsAMD", userptr); - glXCreateAssociatedContextAMD = (PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC) load("glXCreateAssociatedContextAMD", userptr); - glXDeleteAssociatedContextAMD = (PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC) load("glXDeleteAssociatedContextAMD", userptr); - glXGetGPUInfoAMD = (PFNGLXGETGPUINFOAMDPROC) load("glXGetGPUInfoAMD", userptr); +static void load_GLX_AMD_gpu_association(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_AMD_gpu_association) return; + glXCreateAssociatedContextAttribsAMD = (PFNGLXCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC)load("glXCreateAssociatedContextAttribsAMD", userptr); + glXBlitContextFramebufferAMD = (PFNGLXBLITCONTEXTFRAMEBUFFERAMDPROC)load("glXBlitContextFramebufferAMD", userptr); + glXGetCurrentAssociatedContextAMD = (PFNGLXGETCURRENTASSOCIATEDCONTEXTAMDPROC)load("glXGetCurrentAssociatedContextAMD", userptr); + glXGetContextGPUIDAMD = (PFNGLXGETCONTEXTGPUIDAMDPROC)load("glXGetContextGPUIDAMD", userptr); + glXMakeAssociatedContextCurrentAMD = (PFNGLXMAKEASSOCIATEDCONTEXTCURRENTAMDPROC)load("glXMakeAssociatedContextCurrentAMD", userptr); + glXGetGPUIDsAMD = (PFNGLXGETGPUIDSAMDPROC)load("glXGetGPUIDsAMD", userptr); + glXCreateAssociatedContextAMD = (PFNGLXCREATEASSOCIATEDCONTEXTAMDPROC)load("glXCreateAssociatedContextAMD", userptr); + glXDeleteAssociatedContextAMD = (PFNGLXDELETEASSOCIATEDCONTEXTAMDPROC)load("glXDeleteAssociatedContextAMD", userptr); + glXGetGPUInfoAMD = (PFNGLXGETGPUINFOAMDPROC)load("glXGetGPUInfoAMD", userptr); } -static void load_GLX_MESA_query_renderer( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_MESA_query_renderer) return; - glXQueryCurrentRendererStringMESA = (PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC) load("glXQueryCurrentRendererStringMESA", userptr); - glXQueryCurrentRendererIntegerMESA = (PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC) load("glXQueryCurrentRendererIntegerMESA", userptr); - glXQueryRendererStringMESA = (PFNGLXQUERYRENDERERSTRINGMESAPROC) load("glXQueryRendererStringMESA", userptr); - glXQueryRendererIntegerMESA = (PFNGLXQUERYRENDERERINTEGERMESAPROC) load("glXQueryRendererIntegerMESA", userptr); +static void load_GLX_MESA_query_renderer(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_MESA_query_renderer) return; + glXQueryCurrentRendererStringMESA = (PFNGLXQUERYCURRENTRENDERERSTRINGMESAPROC)load("glXQueryCurrentRendererStringMESA", userptr); + glXQueryCurrentRendererIntegerMESA = (PFNGLXQUERYCURRENTRENDERERINTEGERMESAPROC)load("glXQueryCurrentRendererIntegerMESA", userptr); + glXQueryRendererStringMESA = (PFNGLXQUERYRENDERERSTRINGMESAPROC)load("glXQueryRendererStringMESA", userptr); + glXQueryRendererIntegerMESA = (PFNGLXQUERYRENDERERINTEGERMESAPROC)load("glXQueryRendererIntegerMESA", userptr); } -static void load_GLX_MESA_swap_control( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_MESA_swap_control) return; - glXGetSwapIntervalMESA = (PFNGLXGETSWAPINTERVALMESAPROC) load("glXGetSwapIntervalMESA", userptr); - glXSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC) load("glXSwapIntervalMESA", userptr); +static void load_GLX_MESA_swap_control(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_MESA_swap_control) return; + glXGetSwapIntervalMESA = (PFNGLXGETSWAPINTERVALMESAPROC)load("glXGetSwapIntervalMESA", userptr); + glXSwapIntervalMESA = (PFNGLXSWAPINTERVALMESAPROC)load("glXSwapIntervalMESA", userptr); } -static void load_GLX_SGIX_video_resize( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_SGIX_video_resize) return; - glXBindChannelToWindowSGIX = (PFNGLXBINDCHANNELTOWINDOWSGIXPROC) load("glXBindChannelToWindowSGIX", userptr); - glXChannelRectSyncSGIX = (PFNGLXCHANNELRECTSYNCSGIXPROC) load("glXChannelRectSyncSGIX", userptr); - glXQueryChannelDeltasSGIX = (PFNGLXQUERYCHANNELDELTASSGIXPROC) load("glXQueryChannelDeltasSGIX", userptr); - glXQueryChannelRectSGIX = (PFNGLXQUERYCHANNELRECTSGIXPROC) load("glXQueryChannelRectSGIX", userptr); - glXChannelRectSGIX = (PFNGLXCHANNELRECTSGIXPROC) load("glXChannelRectSGIX", userptr); +static void load_GLX_SGIX_video_resize(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_SGIX_video_resize) return; + glXBindChannelToWindowSGIX = (PFNGLXBINDCHANNELTOWINDOWSGIXPROC)load("glXBindChannelToWindowSGIX", userptr); + glXChannelRectSyncSGIX = (PFNGLXCHANNELRECTSYNCSGIXPROC)load("glXChannelRectSyncSGIX", userptr); + glXQueryChannelDeltasSGIX = (PFNGLXQUERYCHANNELDELTASSGIXPROC)load("glXQueryChannelDeltasSGIX", userptr); + glXQueryChannelRectSGIX = (PFNGLXQUERYCHANNELRECTSGIXPROC)load("glXQueryChannelRectSGIX", userptr); + glXChannelRectSGIX = (PFNGLXCHANNELRECTSGIXPROC)load("glXChannelRectSGIX", userptr); } -static void load_GLX_NV_video_out( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_NV_video_out) return; - glXGetVideoInfoNV = (PFNGLXGETVIDEOINFONVPROC) load("glXGetVideoInfoNV", userptr); - glXSendPbufferToVideoNV = (PFNGLXSENDPBUFFERTOVIDEONVPROC) load("glXSendPbufferToVideoNV", userptr); - glXReleaseVideoImageNV = (PFNGLXRELEASEVIDEOIMAGENVPROC) load("glXReleaseVideoImageNV", userptr); - glXBindVideoImageNV = (PFNGLXBINDVIDEOIMAGENVPROC) load("glXBindVideoImageNV", userptr); - glXReleaseVideoDeviceNV = (PFNGLXRELEASEVIDEODEVICENVPROC) load("glXReleaseVideoDeviceNV", userptr); - glXGetVideoDeviceNV = (PFNGLXGETVIDEODEVICENVPROC) load("glXGetVideoDeviceNV", userptr); +static void load_GLX_NV_video_out(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_NV_video_out) return; + glXGetVideoInfoNV = (PFNGLXGETVIDEOINFONVPROC)load("glXGetVideoInfoNV", userptr); + glXSendPbufferToVideoNV = (PFNGLXSENDPBUFFERTOVIDEONVPROC)load("glXSendPbufferToVideoNV", userptr); + glXReleaseVideoImageNV = (PFNGLXRELEASEVIDEOIMAGENVPROC)load("glXReleaseVideoImageNV", userptr); + glXBindVideoImageNV = (PFNGLXBINDVIDEOIMAGENVPROC)load("glXBindVideoImageNV", userptr); + glXReleaseVideoDeviceNV = (PFNGLXRELEASEVIDEODEVICENVPROC)load("glXReleaseVideoDeviceNV", userptr); + glXGetVideoDeviceNV = (PFNGLXGETVIDEODEVICENVPROC)load("glXGetVideoDeviceNV", userptr); } -static void load_GLX_MESA_set_3dfx_mode( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_MESA_set_3dfx_mode) return; - glXSet3DfxModeMESA = (PFNGLXSET3DFXMODEMESAPROC) load("glXSet3DfxModeMESA", userptr); +static void load_GLX_MESA_set_3dfx_mode(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_MESA_set_3dfx_mode) return; + glXSet3DfxModeMESA = (PFNGLXSET3DFXMODEMESAPROC)load("glXSet3DfxModeMESA", userptr); } -static void load_GLX_ARB_get_proc_address( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_ARB_get_proc_address) return; - glXGetProcAddressARB = (PFNGLXGETPROCADDRESSARBPROC) load("glXGetProcAddressARB", userptr); +static void load_GLX_ARB_get_proc_address(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_ARB_get_proc_address) return; + glXGetProcAddressARB = (PFNGLXGETPROCADDRESSARBPROC)load("glXGetProcAddressARB", userptr); } -static void load_GLX_NV_copy_image( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_NV_copy_image) return; - glXCopyImageSubDataNV = (PFNGLXCOPYIMAGESUBDATANVPROC) load("glXCopyImageSubDataNV", userptr); +static void load_GLX_NV_copy_image(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_NV_copy_image) return; + glXCopyImageSubDataNV = (PFNGLXCOPYIMAGESUBDATANVPROC)load("glXCopyImageSubDataNV", userptr); } -static void load_GLX_NV_present_video( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_NV_present_video) return; - glXBindVideoDeviceNV = (PFNGLXBINDVIDEODEVICENVPROC) load("glXBindVideoDeviceNV", userptr); - glXEnumerateVideoDevicesNV = (PFNGLXENUMERATEVIDEODEVICESNVPROC) load("glXEnumerateVideoDevicesNV", userptr); +static void load_GLX_NV_present_video(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_NV_present_video) return; + glXBindVideoDeviceNV = (PFNGLXBINDVIDEODEVICENVPROC)load("glXBindVideoDeviceNV", userptr); + glXEnumerateVideoDevicesNV = (PFNGLXENUMERATEVIDEODEVICESNVPROC)load("glXEnumerateVideoDevicesNV", userptr); } -static void load_GLX_SGIX_swap_barrier( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_SGIX_swap_barrier) return; - glXBindSwapBarrierSGIX = (PFNGLXBINDSWAPBARRIERSGIXPROC) load("glXBindSwapBarrierSGIX", userptr); - glXQueryMaxSwapBarriersSGIX = (PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC) load("glXQueryMaxSwapBarriersSGIX", userptr); +static void load_GLX_SGIX_swap_barrier(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_SGIX_swap_barrier) return; + glXBindSwapBarrierSGIX = (PFNGLXBINDSWAPBARRIERSGIXPROC)load("glXBindSwapBarrierSGIX", userptr); + glXQueryMaxSwapBarriersSGIX = (PFNGLXQUERYMAXSWAPBARRIERSSGIXPROC)load("glXQueryMaxSwapBarriersSGIX", userptr); } -static void load_GLX_SGIX_swap_group( GLADuserptrloadfunc load, void* userptr) { - if(!GLAD_GLX_SGIX_swap_group) return; - glXJoinSwapGroupSGIX = (PFNGLXJOINSWAPGROUPSGIXPROC) load("glXJoinSwapGroupSGIX", userptr); +static void load_GLX_SGIX_swap_group(GLADuserptrloadfunc load, void* userptr) +{ + if (!GLAD_GLX_SGIX_swap_group) return; + glXJoinSwapGroupSGIX = (PFNGLXJOINSWAPGROUPSGIXPROC)load("glXJoinSwapGroupSGIX", userptr); } +static int has_ext(Display* display, int screen, const char* ext) +{ + const char* terminator; + const char* loc; + const char* extensions; + if (!GLAD_GLX_VERSION_1_1) + return 0; -static int has_ext(Display *display, int screen, const char *ext) { - const char *terminator; - const char *loc; - const char *extensions; + extensions = glXQueryExtensionsString(display, screen); - if(!GLAD_GLX_VERSION_1_1) - return 0; + if (extensions == NULL || ext == NULL) + return 0; - extensions = glXQueryExtensionsString(display, screen); + while (1) + { + loc = strstr(extensions, ext); + if (loc == NULL) + break; - if(extensions == NULL || ext == NULL) - return 0; + terminator = loc + strlen(ext); + if ((loc == extensions || *(loc - 1) == ' ') && + (*terminator == ' ' || *terminator == '\0')) + { + return 1; + } + extensions = terminator; + } - while(1) { - loc = strstr(extensions, ext); - if(loc == NULL) - break; - - terminator = loc + strlen(ext); - if((loc == extensions || *(loc - 1) == ' ') && - (*terminator == ' ' || *terminator == '\0')) - { - return 1; - } - extensions = terminator; - } - - return 0; + return 0; } -static GLADapiproc glad_glx_get_proc_from_userptr(const char* name, void *userptr) { - return (GLAD_GNUC_EXTENSION (GLADapiproc (*)(const char *name)) userptr)(name); +static GLADapiproc glad_glx_get_proc_from_userptr(const char* name, void* userptr) +{ + return (GLAD_GNUC_EXTENSION(GLADapiproc(*)(const char* name)) userptr)(name); } -static int find_extensionsGLX(Display *display, int screen) { - GLAD_GLX_MESA_copy_sub_buffer = has_ext(display, screen, "GLX_MESA_copy_sub_buffer"); - GLAD_GLX_EXT_create_context_es_profile = has_ext(display, screen, "GLX_EXT_create_context_es_profile"); - GLAD_GLX_SGIX_pbuffer = has_ext(display, screen, "GLX_SGIX_pbuffer"); - GLAD_GLX_SGI_make_current_read = has_ext(display, screen, "GLX_SGI_make_current_read"); - GLAD_GLX_OML_sync_control = has_ext(display, screen, "GLX_OML_sync_control"); - GLAD_GLX_SGIX_hyperpipe = has_ext(display, screen, "GLX_SGIX_hyperpipe"); - GLAD_GLX_INTEL_swap_event = has_ext(display, screen, "GLX_INTEL_swap_event"); - GLAD_GLX_EXT_swap_control = has_ext(display, screen, "GLX_EXT_swap_control"); - GLAD_GLX_NV_robustness_video_memory_purge = has_ext(display, screen, "GLX_NV_robustness_video_memory_purge"); - GLAD_GLX_MESA_pixmap_colormap = has_ext(display, screen, "GLX_MESA_pixmap_colormap"); - GLAD_GLX_ARB_fbconfig_float = has_ext(display, screen, "GLX_ARB_fbconfig_float"); - GLAD_GLX_EXT_fbconfig_packed_float = has_ext(display, screen, "GLX_EXT_fbconfig_packed_float"); - GLAD_GLX_OML_swap_method = has_ext(display, screen, "GLX_OML_swap_method"); - GLAD_GLX_NV_video_capture = has_ext(display, screen, "GLX_NV_video_capture"); - GLAD_GLX_ARB_robustness_application_isolation = has_ext(display, screen, "GLX_ARB_robustness_application_isolation"); - GLAD_GLX_ARB_create_context_robustness = has_ext(display, screen, "GLX_ARB_create_context_robustness"); - GLAD_GLX_EXT_visual_rating = has_ext(display, screen, "GLX_EXT_visual_rating"); - GLAD_GLX_NV_swap_group = has_ext(display, screen, "GLX_NV_swap_group"); - GLAD_GLX_EXT_texture_from_pixmap = has_ext(display, screen, "GLX_EXT_texture_from_pixmap"); - GLAD_GLX_SUN_get_transparent_index = has_ext(display, screen, "GLX_SUN_get_transparent_index"); - GLAD_GLX_MESA_release_buffers = has_ext(display, screen, "GLX_MESA_release_buffers"); - GLAD_GLX_NV_delay_before_swap = has_ext(display, screen, "GLX_NV_delay_before_swap"); - GLAD_GLX_EXT_buffer_age = has_ext(display, screen, "GLX_EXT_buffer_age"); - GLAD_GLX_MESA_agp_offset = has_ext(display, screen, "GLX_MESA_agp_offset"); - GLAD_GLX_EXT_visual_info = has_ext(display, screen, "GLX_EXT_visual_info"); - GLAD_GLX_SGI_swap_control = has_ext(display, screen, "GLX_SGI_swap_control"); - GLAD_GLX_EXT_import_context = has_ext(display, screen, "GLX_EXT_import_context"); - GLAD_GLX_SGI_video_sync = has_ext(display, screen, "GLX_SGI_video_sync"); - GLAD_GLX_3DFX_multisample = has_ext(display, screen, "GLX_3DFX_multisample"); - GLAD_GLX_ARB_multisample = has_ext(display, screen, "GLX_ARB_multisample"); - GLAD_GLX_EXT_framebuffer_sRGB = has_ext(display, screen, "GLX_EXT_framebuffer_sRGB"); - GLAD_GLX_SGI_cushion = has_ext(display, screen, "GLX_SGI_cushion"); - GLAD_GLX_ARB_robustness_share_group_isolation = has_ext(display, screen, "GLX_ARB_robustness_share_group_isolation"); - GLAD_GLX_SGIX_fbconfig = has_ext(display, screen, "GLX_SGIX_fbconfig"); - GLAD_GLX_NV_copy_buffer = has_ext(display, screen, "GLX_NV_copy_buffer"); - GLAD_GLX_SGIX_visual_select_group = has_ext(display, screen, "GLX_SGIX_visual_select_group"); - GLAD_GLX_EXT_swap_control_tear = has_ext(display, screen, "GLX_EXT_swap_control_tear"); - GLAD_GLX_ARB_create_context = has_ext(display, screen, "GLX_ARB_create_context"); - GLAD_GLX_AMD_gpu_association = has_ext(display, screen, "GLX_AMD_gpu_association"); - GLAD_GLX_MESA_query_renderer = has_ext(display, screen, "GLX_MESA_query_renderer"); - GLAD_GLX_EXT_create_context_es2_profile = has_ext(display, screen, "GLX_EXT_create_context_es2_profile"); - GLAD_GLX_MESA_swap_control = has_ext(display, screen, "GLX_MESA_swap_control"); - GLAD_GLX_SGIX_video_resize = has_ext(display, screen, "GLX_SGIX_video_resize"); - GLAD_GLX_ARB_context_flush_control = has_ext(display, screen, "GLX_ARB_context_flush_control"); - GLAD_GLX_NV_video_out = has_ext(display, screen, "GLX_NV_video_out"); - GLAD_GLX_EXT_no_config_context = has_ext(display, screen, "GLX_EXT_no_config_context"); - GLAD_GLX_SGIS_blended_overlay = has_ext(display, screen, "GLX_SGIS_blended_overlay"); - GLAD_GLX_EXT_stereo_tree = has_ext(display, screen, "GLX_EXT_stereo_tree"); - GLAD_GLX_ARB_create_context_no_error = has_ext(display, screen, "GLX_ARB_create_context_no_error"); - GLAD_GLX_EXT_libglvnd = has_ext(display, screen, "GLX_EXT_libglvnd"); - GLAD_GLX_ARB_create_context_profile = has_ext(display, screen, "GLX_ARB_create_context_profile"); - GLAD_GLX_NV_float_buffer = has_ext(display, screen, "GLX_NV_float_buffer"); - GLAD_GLX_MESA_set_3dfx_mode = has_ext(display, screen, "GLX_MESA_set_3dfx_mode"); - GLAD_GLX_ARB_framebuffer_sRGB = has_ext(display, screen, "GLX_ARB_framebuffer_sRGB"); - GLAD_GLX_ARB_get_proc_address = has_ext(display, screen, "GLX_ARB_get_proc_address"); - GLAD_GLX_SGIS_shared_multisample = has_ext(display, screen, "GLX_SGIS_shared_multisample"); - GLAD_GLX_NV_copy_image = has_ext(display, screen, "GLX_NV_copy_image"); - GLAD_GLX_NV_present_video = has_ext(display, screen, "GLX_NV_present_video"); - GLAD_GLX_SGIX_swap_barrier = has_ext(display, screen, "GLX_SGIX_swap_barrier"); - GLAD_GLX_SGIS_multisample = has_ext(display, screen, "GLX_SGIS_multisample"); - GLAD_GLX_SGIX_swap_group = has_ext(display, screen, "GLX_SGIX_swap_group"); - GLAD_GLX_ARB_vertex_buffer_object = has_ext(display, screen, "GLX_ARB_vertex_buffer_object"); - GLAD_GLX_NV_multisample_coverage = has_ext(display, screen, "GLX_NV_multisample_coverage"); - return 1; +static int find_extensionsGLX(Display* display, int screen) +{ + GLAD_GLX_MESA_copy_sub_buffer = has_ext(display, screen, "GLX_MESA_copy_sub_buffer"); + GLAD_GLX_EXT_create_context_es_profile = has_ext(display, screen, "GLX_EXT_create_context_es_profile"); + GLAD_GLX_SGIX_pbuffer = has_ext(display, screen, "GLX_SGIX_pbuffer"); + GLAD_GLX_SGI_make_current_read = has_ext(display, screen, "GLX_SGI_make_current_read"); + GLAD_GLX_OML_sync_control = has_ext(display, screen, "GLX_OML_sync_control"); + GLAD_GLX_SGIX_hyperpipe = has_ext(display, screen, "GLX_SGIX_hyperpipe"); + GLAD_GLX_INTEL_swap_event = has_ext(display, screen, "GLX_INTEL_swap_event"); + GLAD_GLX_EXT_swap_control = has_ext(display, screen, "GLX_EXT_swap_control"); + GLAD_GLX_NV_robustness_video_memory_purge = has_ext(display, screen, "GLX_NV_robustness_video_memory_purge"); + GLAD_GLX_MESA_pixmap_colormap = has_ext(display, screen, "GLX_MESA_pixmap_colormap"); + GLAD_GLX_ARB_fbconfig_float = has_ext(display, screen, "GLX_ARB_fbconfig_float"); + GLAD_GLX_EXT_fbconfig_packed_float = has_ext(display, screen, "GLX_EXT_fbconfig_packed_float"); + GLAD_GLX_OML_swap_method = has_ext(display, screen, "GLX_OML_swap_method"); + GLAD_GLX_NV_video_capture = has_ext(display, screen, "GLX_NV_video_capture"); + GLAD_GLX_ARB_robustness_application_isolation = has_ext(display, screen, "GLX_ARB_robustness_application_isolation"); + GLAD_GLX_ARB_create_context_robustness = has_ext(display, screen, "GLX_ARB_create_context_robustness"); + GLAD_GLX_EXT_visual_rating = has_ext(display, screen, "GLX_EXT_visual_rating"); + GLAD_GLX_NV_swap_group = has_ext(display, screen, "GLX_NV_swap_group"); + GLAD_GLX_EXT_texture_from_pixmap = has_ext(display, screen, "GLX_EXT_texture_from_pixmap"); + GLAD_GLX_SUN_get_transparent_index = has_ext(display, screen, "GLX_SUN_get_transparent_index"); + GLAD_GLX_MESA_release_buffers = has_ext(display, screen, "GLX_MESA_release_buffers"); + GLAD_GLX_NV_delay_before_swap = has_ext(display, screen, "GLX_NV_delay_before_swap"); + GLAD_GLX_EXT_buffer_age = has_ext(display, screen, "GLX_EXT_buffer_age"); + GLAD_GLX_MESA_agp_offset = has_ext(display, screen, "GLX_MESA_agp_offset"); + GLAD_GLX_EXT_visual_info = has_ext(display, screen, "GLX_EXT_visual_info"); + GLAD_GLX_SGI_swap_control = has_ext(display, screen, "GLX_SGI_swap_control"); + GLAD_GLX_EXT_import_context = has_ext(display, screen, "GLX_EXT_import_context"); + GLAD_GLX_SGI_video_sync = has_ext(display, screen, "GLX_SGI_video_sync"); + GLAD_GLX_3DFX_multisample = has_ext(display, screen, "GLX_3DFX_multisample"); + GLAD_GLX_ARB_multisample = has_ext(display, screen, "GLX_ARB_multisample"); + GLAD_GLX_EXT_framebuffer_sRGB = has_ext(display, screen, "GLX_EXT_framebuffer_sRGB"); + GLAD_GLX_SGI_cushion = has_ext(display, screen, "GLX_SGI_cushion"); + GLAD_GLX_ARB_robustness_share_group_isolation = has_ext(display, screen, "GLX_ARB_robustness_share_group_isolation"); + GLAD_GLX_SGIX_fbconfig = has_ext(display, screen, "GLX_SGIX_fbconfig"); + GLAD_GLX_NV_copy_buffer = has_ext(display, screen, "GLX_NV_copy_buffer"); + GLAD_GLX_SGIX_visual_select_group = has_ext(display, screen, "GLX_SGIX_visual_select_group"); + GLAD_GLX_EXT_swap_control_tear = has_ext(display, screen, "GLX_EXT_swap_control_tear"); + GLAD_GLX_ARB_create_context = has_ext(display, screen, "GLX_ARB_create_context"); + GLAD_GLX_AMD_gpu_association = has_ext(display, screen, "GLX_AMD_gpu_association"); + GLAD_GLX_MESA_query_renderer = has_ext(display, screen, "GLX_MESA_query_renderer"); + GLAD_GLX_EXT_create_context_es2_profile = has_ext(display, screen, "GLX_EXT_create_context_es2_profile"); + GLAD_GLX_MESA_swap_control = has_ext(display, screen, "GLX_MESA_swap_control"); + GLAD_GLX_SGIX_video_resize = has_ext(display, screen, "GLX_SGIX_video_resize"); + GLAD_GLX_ARB_context_flush_control = has_ext(display, screen, "GLX_ARB_context_flush_control"); + GLAD_GLX_NV_video_out = has_ext(display, screen, "GLX_NV_video_out"); + GLAD_GLX_EXT_no_config_context = has_ext(display, screen, "GLX_EXT_no_config_context"); + GLAD_GLX_SGIS_blended_overlay = has_ext(display, screen, "GLX_SGIS_blended_overlay"); + GLAD_GLX_EXT_stereo_tree = has_ext(display, screen, "GLX_EXT_stereo_tree"); + GLAD_GLX_ARB_create_context_no_error = has_ext(display, screen, "GLX_ARB_create_context_no_error"); + GLAD_GLX_EXT_libglvnd = has_ext(display, screen, "GLX_EXT_libglvnd"); + GLAD_GLX_ARB_create_context_profile = has_ext(display, screen, "GLX_ARB_create_context_profile"); + GLAD_GLX_NV_float_buffer = has_ext(display, screen, "GLX_NV_float_buffer"); + GLAD_GLX_MESA_set_3dfx_mode = has_ext(display, screen, "GLX_MESA_set_3dfx_mode"); + GLAD_GLX_ARB_framebuffer_sRGB = has_ext(display, screen, "GLX_ARB_framebuffer_sRGB"); + GLAD_GLX_ARB_get_proc_address = has_ext(display, screen, "GLX_ARB_get_proc_address"); + GLAD_GLX_SGIS_shared_multisample = has_ext(display, screen, "GLX_SGIS_shared_multisample"); + GLAD_GLX_NV_copy_image = has_ext(display, screen, "GLX_NV_copy_image"); + GLAD_GLX_NV_present_video = has_ext(display, screen, "GLX_NV_present_video"); + GLAD_GLX_SGIX_swap_barrier = has_ext(display, screen, "GLX_SGIX_swap_barrier"); + GLAD_GLX_SGIS_multisample = has_ext(display, screen, "GLX_SGIS_multisample"); + GLAD_GLX_SGIX_swap_group = has_ext(display, screen, "GLX_SGIX_swap_group"); + GLAD_GLX_ARB_vertex_buffer_object = has_ext(display, screen, "GLX_ARB_vertex_buffer_object"); + GLAD_GLX_NV_multisample_coverage = has_ext(display, screen, "GLX_NV_multisample_coverage"); + return 1; } -static int find_coreGLX(Display **display, int *screen) { - X11Struct x11; - initX11Struct(&x11); - int major = 0, minor = 0; - if(*display == NULL) { - *display = x11.XOpenDisplay(0); - if (*display == NULL) { - return 0; - } - *screen = x11.XScreenNumberOfScreen(x11.XDefaultScreenOfDisplay(*display)); - } - glXQueryVersion(*display, &major, &minor); - GLAD_GLX_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; - GLAD_GLX_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; - GLAD_GLX_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; - GLAD_GLX_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; - GLAD_GLX_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; - return GLAD_MAKE_VERSION(major, minor); +static int find_coreGLX(Display** display, int* screen) +{ + X11Struct x11; + initX11Struct(&x11); + int major = 0, minor = 0; + if (*display == NULL) + { + *display = x11.XOpenDisplay(0); + if (*display == NULL) + { + return 0; + } + *screen = x11.XScreenNumberOfScreen(x11.XDefaultScreenOfDisplay(*display)); + } + glXQueryVersion(*display, &major, &minor); + GLAD_GLX_VERSION_1_0 = (major == 1 && minor >= 0) || major > 1; + GLAD_GLX_VERSION_1_1 = (major == 1 && minor >= 1) || major > 1; + GLAD_GLX_VERSION_1_2 = (major == 1 && minor >= 2) || major > 1; + GLAD_GLX_VERSION_1_3 = (major == 1 && minor >= 3) || major > 1; + GLAD_GLX_VERSION_1_4 = (major == 1 && minor >= 4) || major > 1; + return GLAD_MAKE_VERSION(major, minor); } -int gladLoadGLXUserPtr(Display *display, int screen, GLADuserptrloadfunc load, void *userptr) { - int version; - glXQueryVersion = (PFNGLXQUERYVERSIONPROC) load("glXQueryVersion", userptr); - if(glXQueryVersion == NULL) return 0; - version = find_coreGLX(&display, &screen); +int gladLoadGLXUserPtr(Display* display, int screen, GLADuserptrloadfunc load, void* userptr) +{ + int version; + glXQueryVersion = (PFNGLXQUERYVERSIONPROC)load("glXQueryVersion", userptr); + if (glXQueryVersion == NULL) return 0; + version = find_coreGLX(&display, &screen); - load_GLX_VERSION_1_0(load, userptr); - load_GLX_VERSION_1_1(load, userptr); - load_GLX_VERSION_1_2(load, userptr); - load_GLX_VERSION_1_3(load, userptr); - load_GLX_VERSION_1_4(load, userptr); + load_GLX_VERSION_1_0(load, userptr); + load_GLX_VERSION_1_1(load, userptr); + load_GLX_VERSION_1_2(load, userptr); + load_GLX_VERSION_1_3(load, userptr); + load_GLX_VERSION_1_4(load, userptr); - if (!find_extensionsGLX(display, screen)) return 0; - load_GLX_MESA_copy_sub_buffer(load, userptr); - load_GLX_SGIX_pbuffer(load, userptr); - load_GLX_SGI_make_current_read(load, userptr); - load_GLX_OML_sync_control(load, userptr); - load_GLX_SGIX_hyperpipe(load, userptr); - load_GLX_EXT_swap_control(load, userptr); - load_GLX_MESA_pixmap_colormap(load, userptr); - load_GLX_NV_video_capture(load, userptr); - load_GLX_NV_swap_group(load, userptr); - load_GLX_EXT_texture_from_pixmap(load, userptr); - load_GLX_SUN_get_transparent_index(load, userptr); - load_GLX_MESA_release_buffers(load, userptr); - load_GLX_NV_delay_before_swap(load, userptr); - load_GLX_MESA_agp_offset(load, userptr); - load_GLX_SGI_swap_control(load, userptr); - load_GLX_EXT_import_context(load, userptr); - load_GLX_SGI_video_sync(load, userptr); - load_GLX_SGI_cushion(load, userptr); - load_GLX_SGIX_fbconfig(load, userptr); - load_GLX_NV_copy_buffer(load, userptr); - load_GLX_ARB_create_context(load, userptr); - load_GLX_AMD_gpu_association(load, userptr); - load_GLX_MESA_query_renderer(load, userptr); - load_GLX_MESA_swap_control(load, userptr); - load_GLX_SGIX_video_resize(load, userptr); - load_GLX_NV_video_out(load, userptr); - load_GLX_MESA_set_3dfx_mode(load, userptr); - load_GLX_ARB_get_proc_address(load, userptr); - load_GLX_NV_copy_image(load, userptr); - load_GLX_NV_present_video(load, userptr); - load_GLX_SGIX_swap_barrier(load, userptr); - load_GLX_SGIX_swap_group(load, userptr); + if (!find_extensionsGLX(display, screen)) return 0; + load_GLX_MESA_copy_sub_buffer(load, userptr); + load_GLX_SGIX_pbuffer(load, userptr); + load_GLX_SGI_make_current_read(load, userptr); + load_GLX_OML_sync_control(load, userptr); + load_GLX_SGIX_hyperpipe(load, userptr); + load_GLX_EXT_swap_control(load, userptr); + load_GLX_MESA_pixmap_colormap(load, userptr); + load_GLX_NV_video_capture(load, userptr); + load_GLX_NV_swap_group(load, userptr); + load_GLX_EXT_texture_from_pixmap(load, userptr); + load_GLX_SUN_get_transparent_index(load, userptr); + load_GLX_MESA_release_buffers(load, userptr); + load_GLX_NV_delay_before_swap(load, userptr); + load_GLX_MESA_agp_offset(load, userptr); + load_GLX_SGI_swap_control(load, userptr); + load_GLX_EXT_import_context(load, userptr); + load_GLX_SGI_video_sync(load, userptr); + load_GLX_SGI_cushion(load, userptr); + load_GLX_SGIX_fbconfig(load, userptr); + load_GLX_NV_copy_buffer(load, userptr); + load_GLX_ARB_create_context(load, userptr); + load_GLX_AMD_gpu_association(load, userptr); + load_GLX_MESA_query_renderer(load, userptr); + load_GLX_MESA_swap_control(load, userptr); + load_GLX_SGIX_video_resize(load, userptr); + load_GLX_NV_video_out(load, userptr); + load_GLX_MESA_set_3dfx_mode(load, userptr); + load_GLX_ARB_get_proc_address(load, userptr); + load_GLX_NV_copy_image(load, userptr); + load_GLX_NV_present_video(load, userptr); + load_GLX_SGIX_swap_barrier(load, userptr); + load_GLX_SGIX_swap_group(load, userptr); - return version; + return version; } -int gladLoadGLX(Display *display, int screen, GLADloadfunc load) { - return gladLoadGLXUserPtr(display, screen, glad_glx_get_proc_from_userptr, GLAD_GNUC_EXTENSION (void*) load); +int gladLoadGLX(Display* display, int screen, GLADloadfunc load) +{ + return gladLoadGLXUserPtr(display, screen, glad_glx_get_proc_from_userptr, GLAD_GNUC_EXTENSION(void*) load); } - #ifdef GLAD_GLX #ifndef GLAD_LOADER_LIBRARY_C_ @@ -696,107 +754,123 @@ int gladLoadGLX(Display *display, int screen, GLADloadfunc load) { #include #endif +static void* glad_get_dlopen_handle(const char* lib_names[], int length) +{ + void* handle = NULL; + int i; -static void* glad_get_dlopen_handle(const char *lib_names[], int length) { - void *handle = NULL; - int i; - - for (i = 0; i < length; ++i) { + for (i = 0; i < length; ++i) + { #if GLAD_PLATFORM_WIN32 - #if GLAD_PLATFORM_UWP - size_t buffer_size = (strlen(lib_names[i]) + 1) * sizeof(WCHAR); - LPWSTR buffer = (LPWSTR) malloc(buffer_size); - if (buffer != NULL) { - int ret = MultiByteToWideChar(CP_ACP, 0, lib_names[i], -1, buffer, buffer_size); - if (ret != 0) { - handle = (void*) LoadPackagedLibrary(buffer, 0); - } - free((void*) buffer); - } - #else - handle = (void*) LoadLibraryA(lib_names[i]); - #endif +#if GLAD_PLATFORM_UWP + size_t buffer_size = (strlen(lib_names[i]) + 1) * sizeof(WCHAR); + LPWSTR buffer = (LPWSTR)malloc(buffer_size); + if (buffer != NULL) + { + int ret = MultiByteToWideChar(CP_ACP, 0, lib_names[i], -1, buffer, buffer_size); + if (ret != 0) + { + handle = (void*)LoadPackagedLibrary(buffer, 0); + } + free((void*)buffer); + } #else - handle = dlopen(lib_names[i], RTLD_LAZY | RTLD_LOCAL); + handle = (void*)LoadLibraryA(lib_names[i]); #endif - if (handle != NULL) { - return handle; - } - } +#else + handle = dlopen(lib_names[i], RTLD_LAZY | RTLD_LOCAL); +#endif + if (handle != NULL) + { + return handle; + } + } - return NULL; + return NULL; } -static void glad_close_dlopen_handle(void* handle) { - if (handle != NULL) { +static void glad_close_dlopen_handle(void* handle) +{ + if (handle != NULL) + { #if GLAD_PLATFORM_WIN32 - FreeLibrary((HMODULE) handle); + FreeLibrary((HMODULE)handle); #else - dlclose(handle); + dlclose(handle); #endif - } + } } -static GLADapiproc glad_dlsym_handle(void* handle, const char *name) { - if (handle == NULL) { - return NULL; - } +static GLADapiproc glad_dlsym_handle(void* handle, const char* name) +{ + if (handle == NULL) + { + return NULL; + } #if GLAD_PLATFORM_WIN32 - return (GLADapiproc) GetProcAddress((HMODULE) handle, name); + return (GLADapiproc)GetProcAddress((HMODULE)handle, name); #else - return GLAD_GNUC_EXTENSION (GLADapiproc) dlsym(handle, name); + return GLAD_GNUC_EXTENSION(GLADapiproc) dlsym(handle, name); #endif } #endif /* GLAD_LOADER_LIBRARY_C_ */ -typedef void* (GLAD_API_PTR *GLADglxprocaddrfunc)(const char*); +typedef void*(GLAD_API_PTR* GLADglxprocaddrfunc)(const char*); -static GLADapiproc glad_glx_get_proc(const char *name, void *userptr) { - return GLAD_GNUC_EXTENSION ((GLADapiproc (*)(const char *name)) userptr)(name); +static GLADapiproc glad_glx_get_proc(const char* name, void* userptr) +{ + return GLAD_GNUC_EXTENSION((GLADapiproc(*)(const char* name))userptr)(name); } static void* _glx_handle; -int gladLoaderLoadGLX(Display *display, int screen) { - static const char *NAMES[] = { +int gladLoaderLoadGLX(Display* display, int screen) +{ + static const char* NAMES[] = { #if defined __CYGWIN__ - "libGL-1.so", + "libGL-1.so", #endif - "libGL.so.1", - "libGL.so" - }; + "libGL.so.1", + "libGL.so" + }; - int version = 0; - int did_load = 0; - GLADglxprocaddrfunc loader; + int version = 0; + int did_load = 0; + GLADglxprocaddrfunc loader; - if (_glx_handle == NULL) { - _glx_handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0])); - did_load = _glx_handle != NULL; - } + if (_glx_handle == NULL) + { + _glx_handle = glad_get_dlopen_handle(NAMES, sizeof(NAMES) / sizeof(NAMES[0])); + did_load = _glx_handle != NULL; + } - if (_glx_handle != NULL) { - loader = (GLADglxprocaddrfunc) glad_dlsym_handle(_glx_handle, "glXGetProcAddressARB"); - if (loader != NULL) { - version = gladLoadGLXUserPtr(display, screen, glad_glx_get_proc, GLAD_GNUC_EXTENSION (void*) loader); - } + if (_glx_handle != NULL) + { + loader = (GLADglxprocaddrfunc)glad_dlsym_handle(_glx_handle, "glXGetProcAddressARB"); + if (loader != NULL) + { + version = gladLoadGLXUserPtr(display, screen, glad_glx_get_proc, GLAD_GNUC_EXTENSION(void*) loader); + } - if (!version && did_load) { - glad_close_dlopen_handle(_glx_handle); - _glx_handle = NULL; - } - } + if (!version && did_load) + { + glad_close_dlopen_handle(_glx_handle); + _glx_handle = NULL; + } + } - return version; + return version; } -void gladLoaderUnloadGLX() { - if (_glx_handle != NULL) { - glad_close_dlopen_handle(_glx_handle); - _glx_handle = NULL; - } +void gladLoaderUnloadGLX() +{ + if (_glx_handle != NULL) + { + glad_close_dlopen_handle(_glx_handle); + _glx_handle = NULL; + } } #endif /* GLAD_GLX */ diff --git a/examples/ThirdPartyLibs/glad/linmath.h b/examples/ThirdPartyLibs/glad/linmath.h index 9c2e2a0ab..ef3e7968d 100644 --- a/examples/ThirdPartyLibs/glad/linmath.h +++ b/examples/ThirdPartyLibs/glad/linmath.h @@ -7,43 +7,43 @@ #define inline __inline #endif -#define LINMATH_H_DEFINE_VEC(n) \ -typedef float vec##n[n]; \ -static inline void vec##n##_add(vec##n r, vec##n const a, vec##n const b) \ -{ \ - int i; \ - for(i=0; i 1e-4) { + if (vec3_len(u) > 1e-4) + { mat4x4 T, C, S = {{0}}; vec3_norm(u, u); mat4x4_from_vec3_mul_outer(T, u, u); - S[1][2] = u[0]; + S[1][2] = u[0]; S[2][1] = -u[0]; - S[2][0] = u[1]; + S[2][0] = u[1]; S[0][2] = -u[1]; - S[0][1] = u[2]; + S[0][1] = u[2]; S[1][0] = -u[2]; mat4x4_scale(S, S, s); @@ -216,7 +223,9 @@ static inline void mat4x4_rotate(mat4x4 R, mat4x4 M, float x, float y, float z, T[3][3] = 1.; mat4x4_mul(R, M, T); - } else { + } + else + { mat4x4_dup(R, M); } } @@ -226,10 +235,9 @@ static inline void mat4x4_rotate_X(mat4x4 Q, mat4x4 M, float angle) float c = cosf(angle); mat4x4 R = { {1.f, 0.f, 0.f, 0.f}, - {0.f, c, s, 0.f}, - {0.f, -s, c, 0.f}, - {0.f, 0.f, 0.f, 1.f} - }; + {0.f, c, s, 0.f}, + {0.f, -s, c, 0.f}, + {0.f, 0.f, 0.f, 1.f}}; mat4x4_mul(Q, M, R); } static inline void mat4x4_rotate_Y(mat4x4 Q, mat4x4 M, float angle) @@ -237,11 +245,10 @@ static inline void mat4x4_rotate_Y(mat4x4 Q, mat4x4 M, float angle) float s = sinf(angle); float c = cosf(angle); mat4x4 R = { - { c, 0.f, s, 0.f}, - { 0.f, 1.f, 0.f, 0.f}, - { -s, 0.f, c, 0.f}, - { 0.f, 0.f, 0.f, 1.f} - }; + {c, 0.f, s, 0.f}, + {0.f, 1.f, 0.f, 0.f}, + {-s, 0.f, c, 0.f}, + {0.f, 0.f, 0.f, 1.f}}; mat4x4_mul(Q, M, R); } static inline void mat4x4_rotate_Z(mat4x4 Q, mat4x4 M, float angle) @@ -249,11 +256,10 @@ static inline void mat4x4_rotate_Z(mat4x4 Q, mat4x4 M, float angle) float s = sinf(angle); float c = cosf(angle); mat4x4 R = { - { c, s, 0.f, 0.f}, - { -s, c, 0.f, 0.f}, - { 0.f, 0.f, 1.f, 0.f}, - { 0.f, 0.f, 0.f, 1.f} - }; + {c, s, 0.f, 0.f}, + {-s, c, 0.f, 0.f}, + {0.f, 0.f, 1.f, 0.f}, + {0.f, 0.f, 0.f, 1.f}}; mat4x4_mul(Q, M, R); } static inline void mat4x4_invert(mat4x4 T, mat4x4 M) @@ -261,42 +267,42 @@ static inline void mat4x4_invert(mat4x4 T, mat4x4 M) float idet; float s[6]; float c[6]; - s[0] = M[0][0]*M[1][1] - M[1][0]*M[0][1]; - s[1] = M[0][0]*M[1][2] - M[1][0]*M[0][2]; - s[2] = M[0][0]*M[1][3] - M[1][0]*M[0][3]; - s[3] = M[0][1]*M[1][2] - M[1][1]*M[0][2]; - s[4] = M[0][1]*M[1][3] - M[1][1]*M[0][3]; - s[5] = M[0][2]*M[1][3] - M[1][2]*M[0][3]; + s[0] = M[0][0] * M[1][1] - M[1][0] * M[0][1]; + s[1] = M[0][0] * M[1][2] - M[1][0] * M[0][2]; + s[2] = M[0][0] * M[1][3] - M[1][0] * M[0][3]; + s[3] = M[0][1] * M[1][2] - M[1][1] * M[0][2]; + s[4] = M[0][1] * M[1][3] - M[1][1] * M[0][3]; + s[5] = M[0][2] * M[1][3] - M[1][2] * M[0][3]; - c[0] = M[2][0]*M[3][1] - M[3][0]*M[2][1]; - c[1] = M[2][0]*M[3][2] - M[3][0]*M[2][2]; - c[2] = M[2][0]*M[3][3] - M[3][0]*M[2][3]; - c[3] = M[2][1]*M[3][2] - M[3][1]*M[2][2]; - c[4] = M[2][1]*M[3][3] - M[3][1]*M[2][3]; - c[5] = M[2][2]*M[3][3] - M[3][2]*M[2][3]; + c[0] = M[2][0] * M[3][1] - M[3][0] * M[2][1]; + c[1] = M[2][0] * M[3][2] - M[3][0] * M[2][2]; + c[2] = M[2][0] * M[3][3] - M[3][0] * M[2][3]; + c[3] = M[2][1] * M[3][2] - M[3][1] * M[2][2]; + c[4] = M[2][1] * M[3][3] - M[3][1] * M[2][3]; + c[5] = M[2][2] * M[3][3] - M[3][2] * M[2][3]; /* Assumes it is invertible */ - idet = 1.0f/( s[0]*c[5]-s[1]*c[4]+s[2]*c[3]+s[3]*c[2]-s[4]*c[1]+s[5]*c[0] ); + idet = 1.0f / (s[0] * c[5] - s[1] * c[4] + s[2] * c[3] + s[3] * c[2] - s[4] * c[1] + s[5] * c[0]); - T[0][0] = ( M[1][1] * c[5] - M[1][2] * c[4] + M[1][3] * c[3]) * idet; + T[0][0] = (M[1][1] * c[5] - M[1][2] * c[4] + M[1][3] * c[3]) * idet; T[0][1] = (-M[0][1] * c[5] + M[0][2] * c[4] - M[0][3] * c[3]) * idet; - T[0][2] = ( M[3][1] * s[5] - M[3][2] * s[4] + M[3][3] * s[3]) * idet; + T[0][2] = (M[3][1] * s[5] - M[3][2] * s[4] + M[3][3] * s[3]) * idet; T[0][3] = (-M[2][1] * s[5] + M[2][2] * s[4] - M[2][3] * s[3]) * idet; T[1][0] = (-M[1][0] * c[5] + M[1][2] * c[2] - M[1][3] * c[1]) * idet; - T[1][1] = ( M[0][0] * c[5] - M[0][2] * c[2] + M[0][3] * c[1]) * idet; + T[1][1] = (M[0][0] * c[5] - M[0][2] * c[2] + M[0][3] * c[1]) * idet; T[1][2] = (-M[3][0] * s[5] + M[3][2] * s[2] - M[3][3] * s[1]) * idet; - T[1][3] = ( M[2][0] * s[5] - M[2][2] * s[2] + M[2][3] * s[1]) * idet; + T[1][3] = (M[2][0] * s[5] - M[2][2] * s[2] + M[2][3] * s[1]) * idet; - T[2][0] = ( M[1][0] * c[4] - M[1][1] * c[2] + M[1][3] * c[0]) * idet; + T[2][0] = (M[1][0] * c[4] - M[1][1] * c[2] + M[1][3] * c[0]) * idet; T[2][1] = (-M[0][0] * c[4] + M[0][1] * c[2] - M[0][3] * c[0]) * idet; - T[2][2] = ( M[3][0] * s[4] - M[3][1] * s[2] + M[3][3] * s[0]) * idet; + T[2][2] = (M[3][0] * s[4] - M[3][1] * s[2] + M[3][3] * s[0]) * idet; T[2][3] = (-M[2][0] * s[4] + M[2][1] * s[2] - M[2][3] * s[0]) * idet; T[3][0] = (-M[1][0] * c[3] + M[1][1] * c[1] - M[1][2] * c[0]) * idet; - T[3][1] = ( M[0][0] * c[3] - M[0][1] * c[1] + M[0][2] * c[0]) * idet; + T[3][1] = (M[0][0] * c[3] - M[0][1] * c[1] + M[0][2] * c[0]) * idet; T[3][2] = (-M[3][0] * s[3] + M[3][1] * s[1] - M[3][2] * s[0]) * idet; - T[3][3] = ( M[2][0] * s[3] - M[2][1] * s[1] + M[2][2] * s[0]) * idet; + T[3][3] = (M[2][0] * s[3] - M[2][1] * s[1] + M[2][2] * s[0]) * idet; } static inline void mat4x4_orthonormalize(mat4x4 R, mat4x4 M) { @@ -324,41 +330,41 @@ static inline void mat4x4_orthonormalize(mat4x4 R, mat4x4 M) static inline void mat4x4_frustum(mat4x4 M, float l, float r, float b, float t, float n, float f) { - M[0][0] = 2.f*n/(r-l); + M[0][0] = 2.f * n / (r - l); M[0][1] = M[0][2] = M[0][3] = 0.f; - M[1][1] = 2.f*n/(t-b); + M[1][1] = 2.f * n / (t - b); M[1][0] = M[1][2] = M[1][3] = 0.f; - M[2][0] = (r+l)/(r-l); - M[2][1] = (t+b)/(t-b); - M[2][2] = -(f+n)/(f-n); + M[2][0] = (r + l) / (r - l); + M[2][1] = (t + b) / (t - b); + M[2][2] = -(f + n) / (f - n); M[2][3] = -1.f; - M[3][2] = -2.f*(f*n)/(f-n); + M[3][2] = -2.f * (f * n) / (f - n); M[3][0] = M[3][1] = M[3][3] = 0.f; } static inline void mat4x4_ortho(mat4x4 M, float l, float r, float b, float t, float n, float f) { - M[0][0] = 2.f/(r-l); + M[0][0] = 2.f / (r - l); M[0][1] = M[0][2] = M[0][3] = 0.f; - M[1][1] = 2.f/(t-b); + M[1][1] = 2.f / (t - b); M[1][0] = M[1][2] = M[1][3] = 0.f; - M[2][2] = -2.f/(f-n); + M[2][2] = -2.f / (f - n); M[2][0] = M[2][1] = M[2][3] = 0.f; - M[3][0] = -(r+l)/(r-l); - M[3][1] = -(t+b)/(t-b); - M[3][2] = -(f+n)/(f-n); + M[3][0] = -(r + l) / (r - l); + M[3][1] = -(t + b) / (t - b); + M[3][2] = -(f + n) / (f - n); M[3][3] = 1.f; } static inline void mat4x4_perspective(mat4x4 m, float y_fov, float aspect, float n, float f) { /* NOTE: Degrees are an unhandy unit to work with. * linmath.h uses radians for everything! */ - float const a = 1.f / (float) tan(y_fov / 2.f); + float const a = 1.f / (float)tan(y_fov / 2.f); m[0][0] = a / aspect; m[0][1] = 0.f; @@ -400,25 +406,25 @@ static inline void mat4x4_look_at(mat4x4 m, vec3 eye, vec3 center, vec3 up) vec3_mul_cross(t, s, f); - m[0][0] = s[0]; - m[0][1] = t[0]; + m[0][0] = s[0]; + m[0][1] = t[0]; m[0][2] = -f[0]; - m[0][3] = 0.f; + m[0][3] = 0.f; - m[1][0] = s[1]; - m[1][1] = t[1]; + m[1][0] = s[1]; + m[1][1] = t[1]; m[1][2] = -f[1]; - m[1][3] = 0.f; + m[1][3] = 0.f; - m[2][0] = s[2]; - m[2][1] = t[2]; + m[2][0] = s[2]; + m[2][1] = t[2]; m[2][2] = -f[2]; - m[2][3] = 0.f; + m[2][3] = 0.f; - m[3][0] = 0.f; - m[3][1] = 0.f; - m[3][2] = 0.f; - m[3][3] = 1.f; + m[3][0] = 0.f; + m[3][1] = 0.f; + m[3][2] = 0.f; + m[3][3] = 1.f; mat4x4_translate_in_place(m, -eye[0], -eye[1], -eye[2]); } @@ -432,13 +438,13 @@ static inline void quat_identity(quat q) static inline void quat_add(quat r, quat a, quat b) { int i; - for(i=0; i<4; ++i) + for (i = 0; i < 4; ++i) r[i] = a[i] + b[i]; } static inline void quat_sub(quat r, quat a, quat b) { int i; - for(i=0; i<4; ++i) + for (i = 0; i < 4; ++i) r[i] = a[i] - b[i]; } static inline void quat_mul(quat r, quat p, quat q) @@ -449,41 +455,42 @@ static inline void quat_mul(quat r, quat p, quat q) vec3_add(r, r, w); vec3_scale(w, q, p[3]); vec3_add(r, r, w); - r[3] = p[3]*q[3] - vec3_mul_inner(p, q); + r[3] = p[3] * q[3] - vec3_mul_inner(p, q); } static inline void quat_scale(quat r, quat v, float s) { int i; - for(i=0; i<4; ++i) + for (i = 0; i < 4; ++i) r[i] = v[i] * s; } static inline float quat_inner_product(quat a, quat b) { float p = 0.f; int i; - for(i=0; i<4; ++i) - p += b[i]*a[i]; + for (i = 0; i < 4; ++i) + p += b[i] * a[i]; return p; } static inline void quat_conj(quat r, quat q) { int i; - for(i=0; i<3; ++i) + for (i = 0; i < 3; ++i) r[i] = -q[i]; r[3] = q[3]; } -static inline void quat_rotate(quat r, float angle, vec3 axis) { +static inline void quat_rotate(quat r, float angle, vec3 axis) +{ int i; vec3 v; vec3_scale(v, axis, sinf(angle / 2)); - for(i=0; i<3; ++i) + for (i = 0; i < 3; ++i) r[i] = v[i]; r[3] = cosf(angle / 2); } #define quat_norm vec4_norm static inline void quat_mul_vec3(vec3 r, quat q, vec3 v) { -/* + /* * Method by Fabian 'ryg' Giessen (of Farbrausch) t = 2 * cross(q.xyz, v) v' = v + q.w * t + cross(q.xyz, t) @@ -506,23 +513,23 @@ static inline void mat4x4_from_quat(mat4x4 M, quat q) float b = q[0]; float c = q[1]; float d = q[2]; - float a2 = a*a; - float b2 = b*b; - float c2 = c*c; - float d2 = d*d; + float a2 = a * a; + float b2 = b * b; + float c2 = c * c; + float d2 = d * d; M[0][0] = a2 + b2 - c2 - d2; - M[0][1] = 2.f*(b*c + a*d); - M[0][2] = 2.f*(b*d - a*c); + M[0][1] = 2.f * (b * c + a * d); + M[0][2] = 2.f * (b * d - a * c); M[0][3] = 0.f; - M[1][0] = 2*(b*c - a*d); + M[1][0] = 2 * (b * c - a * d); M[1][1] = a2 - b2 + c2 - d2; - M[1][2] = 2.f*(c*d + a*b); + M[1][2] = 2.f * (c * d + a * b); M[1][3] = 0.f; - M[2][0] = 2.f*(b*d + a*c); - M[2][1] = 2.f*(c*d - a*b); + M[2][0] = 2.f * (b * d + a * c); + M[2][1] = 2.f * (c * d - a * b); M[2][2] = a2 - b2 - c2 + d2; M[2][3] = 0.f; @@ -532,8 +539,8 @@ static inline void mat4x4_from_quat(mat4x4 M, quat q) static inline void mat4x4o_mul_quat(mat4x4 R, mat4x4 M, quat q) { -/* XXX: The way this is written only works for othogonal matrices. */ -/* TODO: Take care of non-orthogonal case. */ + /* XXX: The way this is written only works for othogonal matrices. */ + /* TODO: Take care of non-orthogonal case. */ quat_mul_vec3(R[0], q, M[0]); quat_mul_vec3(R[1], q, M[1]); quat_mul_vec3(R[2], q, M[2]); @@ -543,32 +550,34 @@ static inline void mat4x4o_mul_quat(mat4x4 R, mat4x4 M, quat q) } static inline void quat_from_mat4x4(quat q, mat4x4 M) { - float r=0.f; + float r = 0.f; int i; - int perm[] = { 0, 1, 2, 0, 1 }; + int perm[] = {0, 1, 2, 0, 1}; int *p = perm; - for(i = 0; i<3; i++) { + for (i = 0; i < 3; i++) + { float m = M[i][i]; - if( m < r ) + if (m < r) continue; m = r; p = &perm[i]; } - r = (float) sqrt(1.f + M[p[0]][p[0]] - M[p[1]][p[1]] - M[p[2]][p[2]] ); + r = (float)sqrt(1.f + M[p[0]][p[0]] - M[p[1]][p[1]] - M[p[2]][p[2]]); - if(r < 1e-6) { + if (r < 1e-6) + { q[0] = 1.f; q[1] = q[2] = q[3] = 0.f; return; } - q[0] = r/2.f; - q[1] = (M[p[0]][p[1]] - M[p[1]][p[0]])/(2.f*r); - q[2] = (M[p[2]][p[0]] - M[p[0]][p[2]])/(2.f*r); - q[3] = (M[p[2]][p[1]] - M[p[1]][p[2]])/(2.f*r); + q[0] = r / 2.f; + q[1] = (M[p[0]][p[1]] - M[p[1]][p[0]]) / (2.f * r); + q[2] = (M[p[2]][p[0]] - M[p[0]][p[2]]) / (2.f * r); + q[3] = (M[p[2]][p[1]] - M[p[1]][p[2]]) / (2.f * r); } #endif diff --git a/examples/ThirdPartyLibs/imgui/imconfig.h b/examples/ThirdPartyLibs/imgui/imconfig.h index afa54914c..c033aedd4 100644 --- a/examples/ThirdPartyLibs/imgui/imconfig.h +++ b/examples/ThirdPartyLibs/imgui/imconfig.h @@ -3,7 +3,7 @@ // Most options (memory allocation, clipboard callbacks, etc.) can be set at runtime via the ImGuiIO structure - ImGui::GetIO(). //----------------------------------------------------------------------------- // A) You may edit imconfig.h (and not overwrite it when updating imgui, or maintain a patch/branch with your modifications to imconfig.h) -// B) or add configuration directives in your own file and compile with #define IMGUI_USER_CONFIG "myfilename.h" +// B) or add configuration directives in your own file and compile with #define IMGUI_USER_CONFIG "myfilename.h" // Note that options such as IMGUI_API, IM_VEC2_CLASS_EXTRA or ImDrawIdx needs to be defined consistently everywhere you include imgui.h, not only for the imgui*.cpp compilation units. //----------------------------------------------------------------------------- diff --git a/examples/ThirdPartyLibs/imgui/imgui.cpp b/examples/ThirdPartyLibs/imgui/imgui.cpp index 5d4c87c1d..27a102b76 100644 --- a/examples/ThirdPartyLibs/imgui/imgui.cpp +++ b/examples/ThirdPartyLibs/imgui/imgui.cpp @@ -650,45 +650,45 @@ #define IMGUI_DEFINE_MATH_OPERATORS #include "imgui_internal.h" -#include // toupper, isprint -#include // NULL, malloc, free, qsort, atoi -#include // vsnprintf, sscanf, printf -#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier -#include // intptr_t +#include // toupper, isprint +#include // NULL, malloc, free, qsort, atoi +#include // vsnprintf, sscanf, printf +#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier +#include // intptr_t #else -#include // intptr_t +#include // intptr_t #endif -#define IMGUI_DEBUG_NAV_SCORING 0 -#define IMGUI_DEBUG_NAV_RECTS 0 +#define IMGUI_DEBUG_NAV_SCORING 0 +#define IMGUI_DEBUG_NAV_RECTS 0 // Visual Studio warnings #ifdef _MSC_VER -#pragma warning (disable: 4127) // condition expression is constant -#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff) -#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen +#pragma warning(disable : 4127) // condition expression is constant +#pragma warning(disable : 4505) // unreferenced local function has been removed (stb stuff) +#pragma warning(disable : 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen #endif // Clang warnings with -Weverything #ifdef __clang__ -#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning : unknown warning group '-Wformat-pedantic *' // not all warnings are known by all clang versions.. so ignoring warnings triggers new warnings on some configuration. great! -#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse. -#pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok. -#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning : format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code. -#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning : declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals. -#pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference it. -#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // -#pragma clang diagnostic ignored "-Wformat-pedantic" // warning : format specifies type 'void *' but the argument has type 'xxxx *' // unreasonable, would lead to casting every %p arg to void*. probably enabled by -pedantic. -#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int' // +#pragma clang diagnostic ignored "-Wunknown-pragmas" // warning : unknown warning group '-Wformat-pedantic *' // not all warnings are known by all clang versions.. so ignoring warnings triggers new warnings on some configuration. great! +#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse. +#pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants (typically 0.0f) is ok. +#pragma clang diagnostic ignored "-Wformat-nonliteral" // warning : format string is not a string literal // passing non-literal to vsnformat(). yes, user passing incorrect format strings can crash the code. +#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning : declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals. +#pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference it. +#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // +#pragma clang diagnostic ignored "-Wformat-pedantic" // warning : format specifies type 'void *' but the argument has type 'xxxx *' // unreasonable, would lead to casting every %p arg to void*. probably enabled by -pedantic. +#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int' // #elif defined(__GNUC__) -#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used -#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size -#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'void*', but argument 6 has type 'ImGuiWindow*' -#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function -#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value -#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'xxxx' to type 'xxxx' casts away qualifiers -#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked -#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when assuming that (X - c) > X is always false +#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used +#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size +#pragma GCC diagnostic ignored "-Wformat" // warning: format '%p' expects argument of type 'void*', but argument 6 has type 'ImGuiWindow*' +#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function +#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value +#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'xxxx' to type 'xxxx' casts away qualifiers +#pragma GCC diagnostic ignored "-Wformat-nonliteral" // warning: format not a string literal, format string not checked +#pragma GCC diagnostic ignored "-Wstrict-overflow" // warning: assuming signed overflow does not occur when assuming that (X - c) > X is always false #endif // Enforce cdecl calling convention for functions called by the standard library, in case compilation settings changed the default to e.g. __vectorcall @@ -702,94 +702,113 @@ // Forward Declarations //------------------------------------------------------------------------- -static bool IsKeyPressedMap(ImGuiKey key, bool repeat = true); +static bool IsKeyPressedMap(ImGuiKey key, bool repeat = true); -static ImFont* GetDefaultFont(); -static void SetCurrentWindow(ImGuiWindow* window); -static void SetWindowScrollX(ImGuiWindow* window, float new_scroll_x); -static void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y); -static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond); -static void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond); -static void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond); -static ImGuiWindow* FindHoveredWindow(); -static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags); -static void CheckStacksSize(ImGuiWindow* window, bool write); -static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window); +static ImFont* GetDefaultFont(); +static void SetCurrentWindow(ImGuiWindow* window); +static void SetWindowScrollX(ImGuiWindow* window, float new_scroll_x); +static void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y); +static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond); +static void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond); +static void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond); +static ImGuiWindow* FindHoveredWindow(); +static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags); +static void CheckStacksSize(ImGuiWindow* window, bool write); +static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window); -static void AddDrawListToDrawData(ImVector* out_list, ImDrawList* draw_list); -static void AddWindowToDrawData(ImVector* out_list, ImGuiWindow* window); -static void AddWindowToSortedBuffer(ImVector* out_sorted_windows, ImGuiWindow* window); +static void AddDrawListToDrawData(ImVector* out_list, ImDrawList* draw_list); +static void AddWindowToDrawData(ImVector* out_list, ImGuiWindow* window); +static void AddWindowToSortedBuffer(ImVector* out_sorted_windows, ImGuiWindow* window); static ImGuiWindowSettings* AddWindowSettings(const char* name); -static void LoadIniSettingsFromDisk(const char* ini_filename); -static void LoadIniSettingsFromMemory(const char* buf); -static void SaveIniSettingsToDisk(const char* ini_filename); -static void SaveIniSettingsToMemory(ImVector& out_buf); -static void MarkIniSettingsDirty(ImGuiWindow* window); +static void LoadIniSettingsFromDisk(const char* ini_filename); +static void LoadIniSettingsFromMemory(const char* buf); +static void SaveIniSettingsToDisk(const char* ini_filename); +static void SaveIniSettingsToMemory(ImVector& out_buf); +static void MarkIniSettingsDirty(ImGuiWindow* window); -static ImRect GetViewportRect(); +static ImRect GetViewportRect(); -static void ClosePopupToLevel(int remaining); -static ImGuiWindow* GetFrontMostModalRootWindow(); +static void ClosePopupToLevel(int remaining); +static ImGuiWindow* GetFrontMostModalRootWindow(); -static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data); -static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end); -static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false); +static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data); +static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end); +static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining = NULL, ImVec2* out_offset = NULL, bool stop_on_new_line = false); -static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, const char* display_format, char* buf, int buf_size); -static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, int decimal_precision, char* buf, int buf_size); -static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* value1, const void* value2); -static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* scalar_format); +static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, const char* display_format, char* buf, int buf_size); +static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, int decimal_precision, char* buf, int buf_size); +static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* value1, const void* value2); +static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* scalar_format); namespace ImGui { -static void NavUpdate(); -static void NavUpdateWindowing(); -static void NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, const ImGuiID id); +static void NavUpdate(); +static void NavUpdateWindowing(); +static void NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, const ImGuiID id); -static void UpdateMovingWindow(); -static void UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]); -static void FocusFrontMostActiveWindow(ImGuiWindow* ignore_window); -} +static void UpdateMovingWindow(); +static void UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]); +static void FocusFrontMostActiveWindow(ImGuiWindow* ignore_window); +} // namespace ImGui //----------------------------------------------------------------------------- // Platform dependent default implementations //----------------------------------------------------------------------------- -static const char* GetClipboardTextFn_DefaultImpl(void* user_data); -static void SetClipboardTextFn_DefaultImpl(void* user_data, const char* text); -static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y); +static const char* GetClipboardTextFn_DefaultImpl(void* user_data); +static void SetClipboardTextFn_DefaultImpl(void* user_data, const char* text); +static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y); //----------------------------------------------------------------------------- // Context //----------------------------------------------------------------------------- -// Current context pointer. Implicitely used by all ImGui functions. Always assumed to be != NULL. -// CreateContext() will automatically set this pointer if it is NULL. Change to a different context by calling ImGui::SetCurrentContext(). -// If you use DLL hotreloading you might need to call SetCurrentContext() after reloading code from this file. +// Current context pointer. Implicitely used by all ImGui functions. Always assumed to be != NULL. +// CreateContext() will automatically set this pointer if it is NULL. Change to a different context by calling ImGui::SetCurrentContext(). +// If you use DLL hotreloading you might need to call SetCurrentContext() after reloading code from this file. // ImGui functions are not thread-safe because of this pointer. If you want thread-safety to allow N threads to access N different contexts, you can: // - Change this variable to use thread local storage. You may #define GImGui in imconfig.h for that purpose. Future development aim to make this context pointer explicit to all calls. Also read https://github.com/ocornut/imgui/issues/586 // - Having multiple instances of the ImGui code compiled inside different namespace (easiest/safest, if you have a finite number of contexts) #ifndef GImGui -ImGuiContext* GImGui = NULL; +ImGuiContext* GImGui = NULL; #endif // Memory Allocator functions. Use SetAllocatorFunctions() to change them. -// If you use DLL hotreloading you might need to call SetAllocatorFunctions() after reloading code from this file. +// If you use DLL hotreloading you might need to call SetAllocatorFunctions() after reloading code from this file. // Otherwise, you probably don't want to modify them mid-program, and if you use global/static e.g. ImVector<> instances you may need to keep them accessible during program destruction. #ifndef IMGUI_DISABLE_DEFAULT_ALLOCATORS -static void* MallocWrapper(size_t size, void* user_data) { (void)user_data; return malloc(size); } -static void FreeWrapper(void* ptr, void* user_data) { (void)user_data; free(ptr); } +static void* MallocWrapper(size_t size, void* user_data) +{ + (void)user_data; + return malloc(size); +} +static void FreeWrapper(void* ptr, void* user_data) +{ + (void)user_data; + free(ptr); +} #else -static void* MallocWrapper(size_t size, void* user_data) { (void)user_data; (void)size; IM_ASSERT(0); return NULL; } -static void FreeWrapper(void* ptr, void* user_data) { (void)user_data; (void)ptr; IM_ASSERT(0); } +static void* MallocWrapper(size_t size, void* user_data) +{ + (void)user_data; + (void)size; + IM_ASSERT(0); + return NULL; +} +static void FreeWrapper(void* ptr, void* user_data) +{ + (void)user_data; + (void)ptr; + IM_ASSERT(0); +} #endif -static void* (*GImAllocatorAllocFunc)(size_t size, void* user_data) = MallocWrapper; -static void (*GImAllocatorFreeFunc)(void* ptr, void* user_data) = FreeWrapper; -static void* GImAllocatorUserData = NULL; -static size_t GImAllocatorActiveAllocationsCount = 0; +static void* (*GImAllocatorAllocFunc)(size_t size, void* user_data) = MallocWrapper; +static void (*GImAllocatorFreeFunc)(void* ptr, void* user_data) = FreeWrapper; +static void* GImAllocatorUserData = NULL; +static size_t GImAllocatorActiveAllocationsCount = 0; //----------------------------------------------------------------------------- // User facing structures @@ -797,117 +816,117 @@ static size_t GImAllocatorActiveAllocationsCount = 0; ImGuiStyle::ImGuiStyle() { - Alpha = 1.0f; // Global alpha applies to everything in ImGui - WindowPadding = ImVec2(8,8); // Padding within a window - WindowRounding = 7.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows - WindowBorderSize = 1.0f; // Thickness of border around windows. Generally set to 0.0f or 1.0f. Other values not well tested. - WindowMinSize = ImVec2(32,32); // Minimum window size - WindowTitleAlign = ImVec2(0.0f,0.5f);// Alignment for title bar text - ChildRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular child windows - ChildBorderSize = 1.0f; // Thickness of border around child windows. Generally set to 0.0f or 1.0f. Other values not well tested. - PopupRounding = 0.0f; // Radius of popup window corners rounding. Set to 0.0f to have rectangular child windows - PopupBorderSize = 1.0f; // Thickness of border around popup or tooltip windows. Generally set to 0.0f or 1.0f. Other values not well tested. - FramePadding = ImVec2(4,3); // Padding within a framed rectangle (used by most widgets) - FrameRounding = 0.0f; // Radius of frame corners rounding. Set to 0.0f to have rectangular frames (used by most widgets). - FrameBorderSize = 0.0f; // Thickness of border around frames. Generally set to 0.0f or 1.0f. Other values not well tested. - ItemSpacing = ImVec2(8,4); // Horizontal and vertical spacing between widgets/lines - ItemInnerSpacing = ImVec2(4,4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) - TouchExtraPadding = ImVec2(0,0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! - IndentSpacing = 21.0f; // Horizontal spacing when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2). - ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns - ScrollbarSize = 16.0f; // Width of the vertical scrollbar, Height of the horizontal scrollbar - ScrollbarRounding = 9.0f; // Radius of grab corners rounding for scrollbar - GrabMinSize = 10.0f; // Minimum width/height of a grab box for slider/scrollbar - GrabRounding = 0.0f; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. - ButtonTextAlign = ImVec2(0.5f,0.5f);// Alignment of button text when button is larger than text. - DisplayWindowPadding = ImVec2(22,22); // Window positions are clamped to be visible within the display area by at least this amount. Only covers regular windows. - DisplaySafeAreaPadding = ImVec2(4,4); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. - MouseCursorScale = 1.0f; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later. - AntiAliasedLines = true; // Enable anti-aliasing on lines/borders. Disable if you are really short on CPU/GPU. - AntiAliasedFill = true; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) - CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. + Alpha = 1.0f; // Global alpha applies to everything in ImGui + WindowPadding = ImVec2(8, 8); // Padding within a window + WindowRounding = 7.0f; // Radius of window corners rounding. Set to 0.0f to have rectangular windows + WindowBorderSize = 1.0f; // Thickness of border around windows. Generally set to 0.0f or 1.0f. Other values not well tested. + WindowMinSize = ImVec2(32, 32); // Minimum window size + WindowTitleAlign = ImVec2(0.0f, 0.5f); // Alignment for title bar text + ChildRounding = 0.0f; // Radius of child window corners rounding. Set to 0.0f to have rectangular child windows + ChildBorderSize = 1.0f; // Thickness of border around child windows. Generally set to 0.0f or 1.0f. Other values not well tested. + PopupRounding = 0.0f; // Radius of popup window corners rounding. Set to 0.0f to have rectangular child windows + PopupBorderSize = 1.0f; // Thickness of border around popup or tooltip windows. Generally set to 0.0f or 1.0f. Other values not well tested. + FramePadding = ImVec2(4, 3); // Padding within a framed rectangle (used by most widgets) + FrameRounding = 0.0f; // Radius of frame corners rounding. Set to 0.0f to have rectangular frames (used by most widgets). + FrameBorderSize = 0.0f; // Thickness of border around frames. Generally set to 0.0f or 1.0f. Other values not well tested. + ItemSpacing = ImVec2(8, 4); // Horizontal and vertical spacing between widgets/lines + ItemInnerSpacing = ImVec2(4, 4); // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label) + TouchExtraPadding = ImVec2(0, 0); // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! + IndentSpacing = 21.0f; // Horizontal spacing when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2). + ColumnsMinSpacing = 6.0f; // Minimum horizontal spacing between two columns + ScrollbarSize = 16.0f; // Width of the vertical scrollbar, Height of the horizontal scrollbar + ScrollbarRounding = 9.0f; // Radius of grab corners rounding for scrollbar + GrabMinSize = 10.0f; // Minimum width/height of a grab box for slider/scrollbar + GrabRounding = 0.0f; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. + ButtonTextAlign = ImVec2(0.5f, 0.5f); // Alignment of button text when button is larger than text. + DisplayWindowPadding = ImVec2(22, 22); // Window positions are clamped to be visible within the display area by at least this amount. Only covers regular windows. + DisplaySafeAreaPadding = ImVec2(4, 4); // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. + MouseCursorScale = 1.0f; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later. + AntiAliasedLines = true; // Enable anti-aliasing on lines/borders. Disable if you are really short on CPU/GPU. + AntiAliasedFill = true; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) + CurveTessellationTol = 1.25f; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. - ImGui::StyleColorsClassic(this); + ImGui::StyleColorsClassic(this); } // To scale your entire UI (e.g. if you want your app to use High DPI or generally be DPI aware) you may use this helper function. Scaling the fonts is done separately and is up to you. // Important: This operation is lossy because we round all sizes to integer. If you need to change your scale multiples, call this over a freshly initialized ImGuiStyle structure rather than scaling multiple times. void ImGuiStyle::ScaleAllSizes(float scale_factor) { - WindowPadding = ImFloor(WindowPadding * scale_factor); - WindowRounding = ImFloor(WindowRounding * scale_factor); - WindowMinSize = ImFloor(WindowMinSize * scale_factor); - ChildRounding = ImFloor(ChildRounding * scale_factor); - PopupRounding = ImFloor(PopupRounding * scale_factor); - FramePadding = ImFloor(FramePadding * scale_factor); - FrameRounding = ImFloor(FrameRounding * scale_factor); - ItemSpacing = ImFloor(ItemSpacing * scale_factor); - ItemInnerSpacing = ImFloor(ItemInnerSpacing * scale_factor); - TouchExtraPadding = ImFloor(TouchExtraPadding * scale_factor); - IndentSpacing = ImFloor(IndentSpacing * scale_factor); - ColumnsMinSpacing = ImFloor(ColumnsMinSpacing * scale_factor); - ScrollbarSize = ImFloor(ScrollbarSize * scale_factor); - ScrollbarRounding = ImFloor(ScrollbarRounding * scale_factor); - GrabMinSize = ImFloor(GrabMinSize * scale_factor); - GrabRounding = ImFloor(GrabRounding * scale_factor); - DisplayWindowPadding = ImFloor(DisplayWindowPadding * scale_factor); - DisplaySafeAreaPadding = ImFloor(DisplaySafeAreaPadding * scale_factor); - MouseCursorScale = ImFloor(MouseCursorScale * scale_factor); + WindowPadding = ImFloor(WindowPadding * scale_factor); + WindowRounding = ImFloor(WindowRounding * scale_factor); + WindowMinSize = ImFloor(WindowMinSize * scale_factor); + ChildRounding = ImFloor(ChildRounding * scale_factor); + PopupRounding = ImFloor(PopupRounding * scale_factor); + FramePadding = ImFloor(FramePadding * scale_factor); + FrameRounding = ImFloor(FrameRounding * scale_factor); + ItemSpacing = ImFloor(ItemSpacing * scale_factor); + ItemInnerSpacing = ImFloor(ItemInnerSpacing * scale_factor); + TouchExtraPadding = ImFloor(TouchExtraPadding * scale_factor); + IndentSpacing = ImFloor(IndentSpacing * scale_factor); + ColumnsMinSpacing = ImFloor(ColumnsMinSpacing * scale_factor); + ScrollbarSize = ImFloor(ScrollbarSize * scale_factor); + ScrollbarRounding = ImFloor(ScrollbarRounding * scale_factor); + GrabMinSize = ImFloor(GrabMinSize * scale_factor); + GrabRounding = ImFloor(GrabRounding * scale_factor); + DisplayWindowPadding = ImFloor(DisplayWindowPadding * scale_factor); + DisplaySafeAreaPadding = ImFloor(DisplaySafeAreaPadding * scale_factor); + MouseCursorScale = ImFloor(MouseCursorScale * scale_factor); } ImGuiIO::ImGuiIO() { - // Most fields are initialized with zero - memset(this, 0, sizeof(*this)); + // Most fields are initialized with zero + memset(this, 0, sizeof(*this)); - // Settings - DisplaySize = ImVec2(-1.0f, -1.0f); - DeltaTime = 1.0f/60.0f; - NavFlags = 0x00; - IniSavingRate = 5.0f; - IniFilename = "imgui.ini"; - LogFilename = "imgui_log.txt"; - MouseDoubleClickTime = 0.30f; - MouseDoubleClickMaxDist = 6.0f; - for (int i = 0; i < ImGuiKey_COUNT; i++) - KeyMap[i] = -1; - KeyRepeatDelay = 0.250f; - KeyRepeatRate = 0.050f; - UserData = NULL; + // Settings + DisplaySize = ImVec2(-1.0f, -1.0f); + DeltaTime = 1.0f / 60.0f; + NavFlags = 0x00; + IniSavingRate = 5.0f; + IniFilename = "imgui.ini"; + LogFilename = "imgui_log.txt"; + MouseDoubleClickTime = 0.30f; + MouseDoubleClickMaxDist = 6.0f; + for (int i = 0; i < ImGuiKey_COUNT; i++) + KeyMap[i] = -1; + KeyRepeatDelay = 0.250f; + KeyRepeatRate = 0.050f; + UserData = NULL; - Fonts = NULL; - FontGlobalScale = 1.0f; - FontDefault = NULL; - FontAllowUserScaling = false; - DisplayFramebufferScale = ImVec2(1.0f, 1.0f); - DisplayVisibleMin = DisplayVisibleMax = ImVec2(0.0f, 0.0f); + Fonts = NULL; + FontGlobalScale = 1.0f; + FontDefault = NULL; + FontAllowUserScaling = false; + DisplayFramebufferScale = ImVec2(1.0f, 1.0f); + DisplayVisibleMin = DisplayVisibleMax = ImVec2(0.0f, 0.0f); - // Advanced/subtle behaviors + // Advanced/subtle behaviors #ifdef __APPLE__ - OptMacOSXBehaviors = true; // Set Mac OS X style defaults based on __APPLE__ compile time flag + OptMacOSXBehaviors = true; // Set Mac OS X style defaults based on __APPLE__ compile time flag #else - OptMacOSXBehaviors = false; + OptMacOSXBehaviors = false; #endif - OptCursorBlink = true; + OptCursorBlink = true; - // Settings (User Functions) - GetClipboardTextFn = GetClipboardTextFn_DefaultImpl; // Platform dependent default implementations - SetClipboardTextFn = SetClipboardTextFn_DefaultImpl; - ClipboardUserData = NULL; - ImeSetInputScreenPosFn = ImeSetInputScreenPosFn_DefaultImpl; - ImeWindowHandle = NULL; + // Settings (User Functions) + GetClipboardTextFn = GetClipboardTextFn_DefaultImpl; // Platform dependent default implementations + SetClipboardTextFn = SetClipboardTextFn_DefaultImpl; + ClipboardUserData = NULL; + ImeSetInputScreenPosFn = ImeSetInputScreenPosFn_DefaultImpl; + ImeWindowHandle = NULL; #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - RenderDrawListsFn = NULL; + RenderDrawListsFn = NULL; #endif - // Input (NB: we already have memset zero the entire structure) - MousePos = ImVec2(-FLT_MAX, -FLT_MAX); - MousePosPrev = ImVec2(-FLT_MAX, -FLT_MAX); - MouseDragThreshold = 6.0f; - for (int i = 0; i < IM_ARRAYSIZE(MouseDownDuration); i++) MouseDownDuration[i] = MouseDownDurationPrev[i] = -1.0f; - for (int i = 0; i < IM_ARRAYSIZE(KeysDownDuration); i++) KeysDownDuration[i] = KeysDownDurationPrev[i] = -1.0f; - for (int i = 0; i < IM_ARRAYSIZE(NavInputsDownDuration); i++) NavInputsDownDuration[i] = -1.0f; + // Input (NB: we already have memset zero the entire structure) + MousePos = ImVec2(-FLT_MAX, -FLT_MAX); + MousePosPrev = ImVec2(-FLT_MAX, -FLT_MAX); + MouseDragThreshold = 6.0f; + for (int i = 0; i < IM_ARRAYSIZE(MouseDownDuration); i++) MouseDownDuration[i] = MouseDownDurationPrev[i] = -1.0f; + for (int i = 0; i < IM_ARRAYSIZE(KeysDownDuration); i++) KeysDownDuration[i] = KeysDownDurationPrev[i] = -1.0f; + for (int i = 0; i < IM_ARRAYSIZE(NavInputsDownDuration); i++) NavInputsDownDuration[i] = -1.0f; } // Pass in translated ASCII characters for text input. @@ -915,30 +934,30 @@ ImGuiIO::ImGuiIO() // - on Windows you can get those using ToAscii+keyboard state, or via the WM_CHAR message void ImGuiIO::AddInputCharacter(ImWchar c) { - const int n = ImStrlenW(InputCharacters); - if (n + 1 < IM_ARRAYSIZE(InputCharacters)) - { - InputCharacters[n] = c; - InputCharacters[n+1] = '\0'; - } + const int n = ImStrlenW(InputCharacters); + if (n + 1 < IM_ARRAYSIZE(InputCharacters)) + { + InputCharacters[n] = c; + InputCharacters[n + 1] = '\0'; + } } void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars) { - // We can't pass more wchars than ImGuiIO::InputCharacters[] can hold so don't convert more - const int wchars_buf_len = sizeof(ImGuiIO::InputCharacters) / sizeof(ImWchar); - ImWchar wchars[wchars_buf_len]; - ImTextStrFromUtf8(wchars, wchars_buf_len, utf8_chars, NULL); - for (int i = 0; i < wchars_buf_len && wchars[i] != 0; i++) - AddInputCharacter(wchars[i]); + // We can't pass more wchars than ImGuiIO::InputCharacters[] can hold so don't convert more + const int wchars_buf_len = sizeof(ImGuiIO::InputCharacters) / sizeof(ImWchar); + ImWchar wchars[wchars_buf_len]; + ImTextStrFromUtf8(wchars, wchars_buf_len, utf8_chars, NULL); + for (int i = 0; i < wchars_buf_len && wchars[i] != 0; i++) + AddInputCharacter(wchars[i]); } //----------------------------------------------------------------------------- // HELPERS //----------------------------------------------------------------------------- -#define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose -#define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255 +#define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL)*255.0f + ((_VAL) >= 0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose +#define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255 // Play it nice with Windows users. Notepad in 2015 still doesn't display text data with Unix-style \n. #ifdef _WIN32 @@ -949,208 +968,224 @@ void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars) ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p) { - ImVec2 ap = p - a; - ImVec2 ab_dir = b - a; - float dot = ap.x * ab_dir.x + ap.y * ab_dir.y; - if (dot < 0.0f) - return a; - float ab_len_sqr = ab_dir.x * ab_dir.x + ab_dir.y * ab_dir.y; - if (dot > ab_len_sqr) - return b; - return a + ab_dir * dot / ab_len_sqr; + ImVec2 ap = p - a; + ImVec2 ab_dir = b - a; + float dot = ap.x * ab_dir.x + ap.y * ab_dir.y; + if (dot < 0.0f) + return a; + float ab_len_sqr = ab_dir.x * ab_dir.x + ab_dir.y * ab_dir.y; + if (dot > ab_len_sqr) + return b; + return a + ab_dir * dot / ab_len_sqr; } bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p) { - bool b1 = ((p.x - b.x) * (a.y - b.y) - (p.y - b.y) * (a.x - b.x)) < 0.0f; - bool b2 = ((p.x - c.x) * (b.y - c.y) - (p.y - c.y) * (b.x - c.x)) < 0.0f; - bool b3 = ((p.x - a.x) * (c.y - a.y) - (p.y - a.y) * (c.x - a.x)) < 0.0f; - return ((b1 == b2) && (b2 == b3)); + bool b1 = ((p.x - b.x) * (a.y - b.y) - (p.y - b.y) * (a.x - b.x)) < 0.0f; + bool b2 = ((p.x - c.x) * (b.y - c.y) - (p.y - c.y) * (b.x - c.x)) < 0.0f; + bool b3 = ((p.x - a.x) * (c.y - a.y) - (p.y - a.y) * (c.x - a.x)) < 0.0f; + return ((b1 == b2) && (b2 == b3)); } void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p, float& out_u, float& out_v, float& out_w) { - ImVec2 v0 = b - a; - ImVec2 v1 = c - a; - ImVec2 v2 = p - a; - const float denom = v0.x * v1.y - v1.x * v0.y; - out_v = (v2.x * v1.y - v1.x * v2.y) / denom; - out_w = (v0.x * v2.y - v2.x * v0.y) / denom; - out_u = 1.0f - out_v - out_w; + ImVec2 v0 = b - a; + ImVec2 v1 = c - a; + ImVec2 v2 = p - a; + const float denom = v0.x * v1.y - v1.x * v0.y; + out_v = (v2.x * v1.y - v1.x * v2.y) / denom; + out_w = (v0.x * v2.y - v2.x * v0.y) / denom; + out_u = 1.0f - out_v - out_w; } ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p) { - ImVec2 proj_ab = ImLineClosestPoint(a, b, p); - ImVec2 proj_bc = ImLineClosestPoint(b, c, p); - ImVec2 proj_ca = ImLineClosestPoint(c, a, p); - float dist2_ab = ImLengthSqr(p - proj_ab); - float dist2_bc = ImLengthSqr(p - proj_bc); - float dist2_ca = ImLengthSqr(p - proj_ca); - float m = ImMin(dist2_ab, ImMin(dist2_bc, dist2_ca)); - if (m == dist2_ab) - return proj_ab; - if (m == dist2_bc) - return proj_bc; - return proj_ca; + ImVec2 proj_ab = ImLineClosestPoint(a, b, p); + ImVec2 proj_bc = ImLineClosestPoint(b, c, p); + ImVec2 proj_ca = ImLineClosestPoint(c, a, p); + float dist2_ab = ImLengthSqr(p - proj_ab); + float dist2_bc = ImLengthSqr(p - proj_bc); + float dist2_ca = ImLengthSqr(p - proj_ca); + float m = ImMin(dist2_ab, ImMin(dist2_bc, dist2_ca)); + if (m == dist2_ab) + return proj_ab; + if (m == dist2_bc) + return proj_bc; + return proj_ca; } int ImStricmp(const char* str1, const char* str2) { - int d; - while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; } - return d; + int d; + while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) + { + str1++; + str2++; + } + return d; } int ImStrnicmp(const char* str1, const char* str2, size_t count) { - int d = 0; - while (count > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; count--; } - return d; + int d = 0; + while (count > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) + { + str1++; + str2++; + count--; + } + return d; } void ImStrncpy(char* dst, const char* src, size_t count) { - if (count < 1) return; - strncpy(dst, src, count); - dst[count-1] = 0; + if (count < 1) return; + strncpy(dst, src, count); + dst[count - 1] = 0; } -char* ImStrdup(const char *str) +char* ImStrdup(const char* str) { - size_t len = strlen(str) + 1; - void* buf = ImGui::MemAlloc(len); - return (char*)memcpy(buf, (const void*)str, len); + size_t len = strlen(str) + 1; + void* buf = ImGui::MemAlloc(len); + return (char*)memcpy(buf, (const void*)str, len); } char* ImStrchrRange(const char* str, const char* str_end, char c) { - for ( ; str < str_end; str++) - if (*str == c) - return (char*)str; - return NULL; + for (; str < str_end; str++) + if (*str == c) + return (char*)str; + return NULL; } int ImStrlenW(const ImWchar* str) { - int n = 0; - while (*str++) n++; - return n; + int n = 0; + while (*str++) n++; + return n; } -const ImWchar* ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin) // find beginning-of-line +const ImWchar* ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin) // find beginning-of-line { - while (buf_mid_line > buf_begin && buf_mid_line[-1] != '\n') - buf_mid_line--; - return buf_mid_line; + while (buf_mid_line > buf_begin && buf_mid_line[-1] != '\n') + buf_mid_line--; + return buf_mid_line; } const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end) { - if (!needle_end) - needle_end = needle + strlen(needle); + if (!needle_end) + needle_end = needle + strlen(needle); - const char un0 = (char)toupper(*needle); - while ((!haystack_end && *haystack) || (haystack_end && haystack < haystack_end)) - { - if (toupper(*haystack) == un0) - { - const char* b = needle + 1; - for (const char* a = haystack + 1; b < needle_end; a++, b++) - if (toupper(*a) != toupper(*b)) - break; - if (b == needle_end) - return haystack; - } - haystack++; - } - return NULL; + const char un0 = (char)toupper(*needle); + while ((!haystack_end && *haystack) || (haystack_end && haystack < haystack_end)) + { + if (toupper(*haystack) == un0) + { + const char* b = needle + 1; + for (const char* a = haystack + 1; b < needle_end; a++, b++) + if (toupper(*a) != toupper(*b)) + break; + if (b == needle_end) + return haystack; + } + haystack++; + } + return NULL; } static const char* ImAtoi(const char* src, int* output) { - int negative = 0; - if (*src == '-') { negative = 1; src++; } - if (*src == '+') { src++; } - int v = 0; - while (*src >= '0' && *src <= '9') - v = (v * 10) + (*src++ - '0'); - *output = negative ? -v : v; - return src; + int negative = 0; + if (*src == '-') + { + negative = 1; + src++; + } + if (*src == '+') + { + src++; + } + int v = 0; + while (*src >= '0' && *src <= '9') + v = (v * 10) + (*src++ - '0'); + *output = negative ? -v : v; + return src; } -// A) MSVC version appears to return -1 on overflow, whereas glibc appears to return total count (which may be >= buf_size). +// A) MSVC version appears to return -1 on overflow, whereas glibc appears to return total count (which may be >= buf_size). // Ideally we would test for only one of those limits at runtime depending on the behavior the vsnprintf(), but trying to deduct it at compile time sounds like a pandora can of worm. // B) When buf==NULL vsnprintf() will return the output size. #ifndef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - int w = vsnprintf(buf, buf_size, fmt, args); - va_end(args); - if (buf == NULL) - return w; - if (w == -1 || w >= (int)buf_size) - w = (int)buf_size - 1; - buf[w] = 0; - return w; + va_list args; + va_start(args, fmt); + int w = vsnprintf(buf, buf_size, fmt, args); + va_end(args); + if (buf == NULL) + return w; + if (w == -1 || w >= (int)buf_size) + w = (int)buf_size - 1; + buf[w] = 0; + return w; } int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) { - int w = vsnprintf(buf, buf_size, fmt, args); - if (buf == NULL) - return w; - if (w == -1 || w >= (int)buf_size) - w = (int)buf_size - 1; - buf[w] = 0; - return w; + int w = vsnprintf(buf, buf_size, fmt, args); + if (buf == NULL) + return w; + if (w == -1 || w >= (int)buf_size) + w = (int)buf_size - 1; + buf[w] = 0; + return w; } -#endif // #ifdef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS +#endif // #ifdef IMGUI_DISABLE_FORMAT_STRING_FUNCTIONS // Pass data_size==0 for zero-terminated strings // FIXME-OPT: Replace with e.g. FNV1a hash? CRC32 pretty much randomly access 1KB. Need to do proper measurements. ImU32 ImHash(const void* data, int data_size, ImU32 seed) { - static ImU32 crc32_lut[256] = { 0 }; - if (!crc32_lut[1]) - { - const ImU32 polynomial = 0xEDB88320; - for (ImU32 i = 0; i < 256; i++) - { - ImU32 crc = i; - for (ImU32 j = 0; j < 8; j++) - crc = (crc >> 1) ^ (ImU32(-int(crc & 1)) & polynomial); - crc32_lut[i] = crc; - } - } + static ImU32 crc32_lut[256] = {0}; + if (!crc32_lut[1]) + { + const ImU32 polynomial = 0xEDB88320; + for (ImU32 i = 0; i < 256; i++) + { + ImU32 crc = i; + for (ImU32 j = 0; j < 8; j++) + crc = (crc >> 1) ^ (ImU32(-int(crc & 1)) & polynomial); + crc32_lut[i] = crc; + } + } - seed = ~seed; - ImU32 crc = seed; - const unsigned char* current = (const unsigned char*)data; + seed = ~seed; + ImU32 crc = seed; + const unsigned char* current = (const unsigned char*)data; - if (data_size > 0) - { - // Known size - while (data_size--) - crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ *current++]; - } - else - { - // Zero-terminated string - while (unsigned char c = *current++) - { - // We support a syntax of "label###id" where only "###id" is included in the hash, and only "label" gets displayed. - // Because this syntax is rarely used we are optimizing for the common case. - // - If we reach ### in the string we discard the hash so far and reset to the seed. - // - We don't do 'current += 2; continue;' after handling ### to keep the code smaller. - if (c == '#' && current[0] == '#' && current[1] == '#') - crc = seed; - crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c]; - } - } - return ~crc; + if (data_size > 0) + { + // Known size + while (data_size--) + crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ *current++]; + } + else + { + // Zero-terminated string + while (unsigned char c = *current++) + { + // We support a syntax of "label###id" where only "###id" is included in the hash, and only "label" gets displayed. + // Because this syntax is rarely used we are optimizing for the common case. + // - If we reach ### in the string we discard the hash so far and reset to the seed. + // - We don't do 'current += 2; continue;' after handling ### to keep the code smaller. + if (c == '#' && current[0] == '#' && current[1] == '#') + crc = seed; + crc = (crc >> 8) ^ crc32_lut[(crc & 0xFF) ^ c]; + } + } + return ~crc; } //----------------------------------------------------------------------------- @@ -1162,289 +1197,314 @@ ImU32 ImHash(const void* data, int data_size, ImU32 seed) // We handle UTF-8 decoding error by skipping forward. int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end) { - unsigned int c = (unsigned int)-1; - const unsigned char* str = (const unsigned char*)in_text; - if (!(*str & 0x80)) - { - c = (unsigned int)(*str++); - *out_char = c; - return 1; - } - if ((*str & 0xe0) == 0xc0) - { - *out_char = 0xFFFD; // will be invalid but not end of string - if (in_text_end && in_text_end - (const char*)str < 2) return 1; - if (*str < 0xc2) return 2; - c = (unsigned int)((*str++ & 0x1f) << 6); - if ((*str & 0xc0) != 0x80) return 2; - c += (*str++ & 0x3f); - *out_char = c; - return 2; - } - if ((*str & 0xf0) == 0xe0) - { - *out_char = 0xFFFD; // will be invalid but not end of string - if (in_text_end && in_text_end - (const char*)str < 3) return 1; - if (*str == 0xe0 && (str[1] < 0xa0 || str[1] > 0xbf)) return 3; - if (*str == 0xed && str[1] > 0x9f) return 3; // str[1] < 0x80 is checked below - c = (unsigned int)((*str++ & 0x0f) << 12); - if ((*str & 0xc0) != 0x80) return 3; - c += (unsigned int)((*str++ & 0x3f) << 6); - if ((*str & 0xc0) != 0x80) return 3; - c += (*str++ & 0x3f); - *out_char = c; - return 3; - } - if ((*str & 0xf8) == 0xf0) - { - *out_char = 0xFFFD; // will be invalid but not end of string - if (in_text_end && in_text_end - (const char*)str < 4) return 1; - if (*str > 0xf4) return 4; - if (*str == 0xf0 && (str[1] < 0x90 || str[1] > 0xbf)) return 4; - if (*str == 0xf4 && str[1] > 0x8f) return 4; // str[1] < 0x80 is checked below - c = (unsigned int)((*str++ & 0x07) << 18); - if ((*str & 0xc0) != 0x80) return 4; - c += (unsigned int)((*str++ & 0x3f) << 12); - if ((*str & 0xc0) != 0x80) return 4; - c += (unsigned int)((*str++ & 0x3f) << 6); - if ((*str & 0xc0) != 0x80) return 4; - c += (*str++ & 0x3f); - // utf-8 encodings of values used in surrogate pairs are invalid - if ((c & 0xFFFFF800) == 0xD800) return 4; - *out_char = c; - return 4; - } - *out_char = 0; - return 0; + unsigned int c = (unsigned int)-1; + const unsigned char* str = (const unsigned char*)in_text; + if (!(*str & 0x80)) + { + c = (unsigned int)(*str++); + *out_char = c; + return 1; + } + if ((*str & 0xe0) == 0xc0) + { + *out_char = 0xFFFD; // will be invalid but not end of string + if (in_text_end && in_text_end - (const char*)str < 2) return 1; + if (*str < 0xc2) return 2; + c = (unsigned int)((*str++ & 0x1f) << 6); + if ((*str & 0xc0) != 0x80) return 2; + c += (*str++ & 0x3f); + *out_char = c; + return 2; + } + if ((*str & 0xf0) == 0xe0) + { + *out_char = 0xFFFD; // will be invalid but not end of string + if (in_text_end && in_text_end - (const char*)str < 3) return 1; + if (*str == 0xe0 && (str[1] < 0xa0 || str[1] > 0xbf)) return 3; + if (*str == 0xed && str[1] > 0x9f) return 3; // str[1] < 0x80 is checked below + c = (unsigned int)((*str++ & 0x0f) << 12); + if ((*str & 0xc0) != 0x80) return 3; + c += (unsigned int)((*str++ & 0x3f) << 6); + if ((*str & 0xc0) != 0x80) return 3; + c += (*str++ & 0x3f); + *out_char = c; + return 3; + } + if ((*str & 0xf8) == 0xf0) + { + *out_char = 0xFFFD; // will be invalid but not end of string + if (in_text_end && in_text_end - (const char*)str < 4) return 1; + if (*str > 0xf4) return 4; + if (*str == 0xf0 && (str[1] < 0x90 || str[1] > 0xbf)) return 4; + if (*str == 0xf4 && str[1] > 0x8f) return 4; // str[1] < 0x80 is checked below + c = (unsigned int)((*str++ & 0x07) << 18); + if ((*str & 0xc0) != 0x80) return 4; + c += (unsigned int)((*str++ & 0x3f) << 12); + if ((*str & 0xc0) != 0x80) return 4; + c += (unsigned int)((*str++ & 0x3f) << 6); + if ((*str & 0xc0) != 0x80) return 4; + c += (*str++ & 0x3f); + // utf-8 encodings of values used in surrogate pairs are invalid + if ((c & 0xFFFFF800) == 0xD800) return 4; + *out_char = c; + return 4; + } + *out_char = 0; + return 0; } int ImTextStrFromUtf8(ImWchar* buf, int buf_size, const char* in_text, const char* in_text_end, const char** in_text_remaining) { - ImWchar* buf_out = buf; - ImWchar* buf_end = buf + buf_size; - while (buf_out < buf_end-1 && (!in_text_end || in_text < in_text_end) && *in_text) - { - unsigned int c; - in_text += ImTextCharFromUtf8(&c, in_text, in_text_end); - if (c == 0) - break; - if (c < 0x10000) // FIXME: Losing characters that don't fit in 2 bytes - *buf_out++ = (ImWchar)c; - } - *buf_out = 0; - if (in_text_remaining) - *in_text_remaining = in_text; - return (int)(buf_out - buf); + ImWchar* buf_out = buf; + ImWchar* buf_end = buf + buf_size; + while (buf_out < buf_end - 1 && (!in_text_end || in_text < in_text_end) && *in_text) + { + unsigned int c; + in_text += ImTextCharFromUtf8(&c, in_text, in_text_end); + if (c == 0) + break; + if (c < 0x10000) // FIXME: Losing characters that don't fit in 2 bytes + *buf_out++ = (ImWchar)c; + } + *buf_out = 0; + if (in_text_remaining) + *in_text_remaining = in_text; + return (int)(buf_out - buf); } int ImTextCountCharsFromUtf8(const char* in_text, const char* in_text_end) { - int char_count = 0; - while ((!in_text_end || in_text < in_text_end) && *in_text) - { - unsigned int c; - in_text += ImTextCharFromUtf8(&c, in_text, in_text_end); - if (c == 0) - break; - if (c < 0x10000) - char_count++; - } - return char_count; + int char_count = 0; + while ((!in_text_end || in_text < in_text_end) && *in_text) + { + unsigned int c; + in_text += ImTextCharFromUtf8(&c, in_text, in_text_end); + if (c == 0) + break; + if (c < 0x10000) + char_count++; + } + return char_count; } // Based on stb_to_utf8() from github.com/nothings/stb/ static inline int ImTextCharToUtf8(char* buf, int buf_size, unsigned int c) { - if (c < 0x80) - { - buf[0] = (char)c; - return 1; - } - if (c < 0x800) - { - if (buf_size < 2) return 0; - buf[0] = (char)(0xc0 + (c >> 6)); - buf[1] = (char)(0x80 + (c & 0x3f)); - return 2; - } - if (c >= 0xdc00 && c < 0xe000) - { - return 0; - } - if (c >= 0xd800 && c < 0xdc00) - { - if (buf_size < 4) return 0; - buf[0] = (char)(0xf0 + (c >> 18)); - buf[1] = (char)(0x80 + ((c >> 12) & 0x3f)); - buf[2] = (char)(0x80 + ((c >> 6) & 0x3f)); - buf[3] = (char)(0x80 + ((c ) & 0x3f)); - return 4; - } - //else if (c < 0x10000) - { - if (buf_size < 3) return 0; - buf[0] = (char)(0xe0 + (c >> 12)); - buf[1] = (char)(0x80 + ((c>> 6) & 0x3f)); - buf[2] = (char)(0x80 + ((c ) & 0x3f)); - return 3; - } + if (c < 0x80) + { + buf[0] = (char)c; + return 1; + } + if (c < 0x800) + { + if (buf_size < 2) return 0; + buf[0] = (char)(0xc0 + (c >> 6)); + buf[1] = (char)(0x80 + (c & 0x3f)); + return 2; + } + if (c >= 0xdc00 && c < 0xe000) + { + return 0; + } + if (c >= 0xd800 && c < 0xdc00) + { + if (buf_size < 4) return 0; + buf[0] = (char)(0xf0 + (c >> 18)); + buf[1] = (char)(0x80 + ((c >> 12) & 0x3f)); + buf[2] = (char)(0x80 + ((c >> 6) & 0x3f)); + buf[3] = (char)(0x80 + ((c)&0x3f)); + return 4; + } + //else if (c < 0x10000) + { + if (buf_size < 3) return 0; + buf[0] = (char)(0xe0 + (c >> 12)); + buf[1] = (char)(0x80 + ((c >> 6) & 0x3f)); + buf[2] = (char)(0x80 + ((c)&0x3f)); + return 3; + } } static inline int ImTextCountUtf8BytesFromChar(unsigned int c) { - if (c < 0x80) return 1; - if (c < 0x800) return 2; - if (c >= 0xdc00 && c < 0xe000) return 0; - if (c >= 0xd800 && c < 0xdc00) return 4; - return 3; + if (c < 0x80) return 1; + if (c < 0x800) return 2; + if (c >= 0xdc00 && c < 0xe000) return 0; + if (c >= 0xd800 && c < 0xdc00) return 4; + return 3; } int ImTextStrToUtf8(char* buf, int buf_size, const ImWchar* in_text, const ImWchar* in_text_end) { - char* buf_out = buf; - const char* buf_end = buf + buf_size; - while (buf_out < buf_end-1 && (!in_text_end || in_text < in_text_end) && *in_text) - { - unsigned int c = (unsigned int)(*in_text++); - if (c < 0x80) - *buf_out++ = (char)c; - else - buf_out += ImTextCharToUtf8(buf_out, (int)(buf_end-buf_out-1), c); - } - *buf_out = 0; - return (int)(buf_out - buf); + char* buf_out = buf; + const char* buf_end = buf + buf_size; + while (buf_out < buf_end - 1 && (!in_text_end || in_text < in_text_end) && *in_text) + { + unsigned int c = (unsigned int)(*in_text++); + if (c < 0x80) + *buf_out++ = (char)c; + else + buf_out += ImTextCharToUtf8(buf_out, (int)(buf_end - buf_out - 1), c); + } + *buf_out = 0; + return (int)(buf_out - buf); } int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end) { - int bytes_count = 0; - while ((!in_text_end || in_text < in_text_end) && *in_text) - { - unsigned int c = (unsigned int)(*in_text++); - if (c < 0x80) - bytes_count++; - else - bytes_count += ImTextCountUtf8BytesFromChar(c); - } - return bytes_count; + int bytes_count = 0; + while ((!in_text_end || in_text < in_text_end) && *in_text) + { + unsigned int c = (unsigned int)(*in_text++); + if (c < 0x80) + bytes_count++; + else + bytes_count += ImTextCountUtf8BytesFromChar(c); + } + return bytes_count; } ImVec4 ImGui::ColorConvertU32ToFloat4(ImU32 in) { - float s = 1.0f/255.0f; - return ImVec4( - ((in >> IM_COL32_R_SHIFT) & 0xFF) * s, - ((in >> IM_COL32_G_SHIFT) & 0xFF) * s, - ((in >> IM_COL32_B_SHIFT) & 0xFF) * s, - ((in >> IM_COL32_A_SHIFT) & 0xFF) * s); + float s = 1.0f / 255.0f; + return ImVec4( + ((in >> IM_COL32_R_SHIFT) & 0xFF) * s, + ((in >> IM_COL32_G_SHIFT) & 0xFF) * s, + ((in >> IM_COL32_B_SHIFT) & 0xFF) * s, + ((in >> IM_COL32_A_SHIFT) & 0xFF) * s); } ImU32 ImGui::ColorConvertFloat4ToU32(const ImVec4& in) { - ImU32 out; - out = ((ImU32)IM_F32_TO_INT8_SAT(in.x)) << IM_COL32_R_SHIFT; - out |= ((ImU32)IM_F32_TO_INT8_SAT(in.y)) << IM_COL32_G_SHIFT; - out |= ((ImU32)IM_F32_TO_INT8_SAT(in.z)) << IM_COL32_B_SHIFT; - out |= ((ImU32)IM_F32_TO_INT8_SAT(in.w)) << IM_COL32_A_SHIFT; - return out; + ImU32 out; + out = ((ImU32)IM_F32_TO_INT8_SAT(in.x)) << IM_COL32_R_SHIFT; + out |= ((ImU32)IM_F32_TO_INT8_SAT(in.y)) << IM_COL32_G_SHIFT; + out |= ((ImU32)IM_F32_TO_INT8_SAT(in.z)) << IM_COL32_B_SHIFT; + out |= ((ImU32)IM_F32_TO_INT8_SAT(in.w)) << IM_COL32_A_SHIFT; + return out; } -ImU32 ImGui::GetColorU32(ImGuiCol idx, float alpha_mul) -{ - ImGuiStyle& style = GImGui->Style; - ImVec4 c = style.Colors[idx]; - c.w *= style.Alpha * alpha_mul; - return ColorConvertFloat4ToU32(c); +ImU32 ImGui::GetColorU32(ImGuiCol idx, float alpha_mul) +{ + ImGuiStyle& style = GImGui->Style; + ImVec4 c = style.Colors[idx]; + c.w *= style.Alpha * alpha_mul; + return ColorConvertFloat4ToU32(c); } ImU32 ImGui::GetColorU32(const ImVec4& col) -{ - ImGuiStyle& style = GImGui->Style; - ImVec4 c = col; - c.w *= style.Alpha; - return ColorConvertFloat4ToU32(c); +{ + ImGuiStyle& style = GImGui->Style; + ImVec4 c = col; + c.w *= style.Alpha; + return ColorConvertFloat4ToU32(c); } const ImVec4& ImGui::GetStyleColorVec4(ImGuiCol idx) -{ - ImGuiStyle& style = GImGui->Style; - return style.Colors[idx]; +{ + ImGuiStyle& style = GImGui->Style; + return style.Colors[idx]; } ImU32 ImGui::GetColorU32(ImU32 col) -{ - float style_alpha = GImGui->Style.Alpha; - if (style_alpha >= 1.0f) - return col; - int a = (col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT; - a = (int)(a * style_alpha); // We don't need to clamp 0..255 because Style.Alpha is in 0..1 range. - return (col & ~IM_COL32_A_MASK) | (a << IM_COL32_A_SHIFT); +{ + float style_alpha = GImGui->Style.Alpha; + if (style_alpha >= 1.0f) + return col; + int a = (col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT; + a = (int)(a * style_alpha); // We don't need to clamp 0..255 because Style.Alpha is in 0..1 range. + return (col & ~IM_COL32_A_MASK) | (a << IM_COL32_A_SHIFT); } // Convert rgb floats ([0-1],[0-1],[0-1]) to hsv floats ([0-1],[0-1],[0-1]), from Foley & van Dam p592 // Optimized http://lolengine.net/blog/2013/01/13/fast-rgb-to-hsv void ImGui::ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v) { - float K = 0.f; - if (g < b) - { - ImSwap(g, b); - K = -1.f; - } - if (r < g) - { - ImSwap(r, g); - K = -2.f / 6.f - K; - } + float K = 0.f; + if (g < b) + { + ImSwap(g, b); + K = -1.f; + } + if (r < g) + { + ImSwap(r, g); + K = -2.f / 6.f - K; + } - const float chroma = r - (g < b ? g : b); - out_h = fabsf(K + (g - b) / (6.f * chroma + 1e-20f)); - out_s = chroma / (r + 1e-20f); - out_v = r; + const float chroma = r - (g < b ? g : b); + out_h = fabsf(K + (g - b) / (6.f * chroma + 1e-20f)); + out_s = chroma / (r + 1e-20f); + out_v = r; } // Convert hsv floats ([0-1],[0-1],[0-1]) to rgb floats ([0-1],[0-1],[0-1]), from Foley & van Dam p593 // also http://en.wikipedia.org/wiki/HSL_and_HSV void ImGui::ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b) { - if (s == 0.0f) - { - // gray - out_r = out_g = out_b = v; - return; - } + if (s == 0.0f) + { + // gray + out_r = out_g = out_b = v; + return; + } - h = fmodf(h, 1.0f) / (60.0f/360.0f); - int i = (int)h; - float f = h - (float)i; - float p = v * (1.0f - s); - float q = v * (1.0f - s * f); - float t = v * (1.0f - s * (1.0f - f)); + h = fmodf(h, 1.0f) / (60.0f / 360.0f); + int i = (int)h; + float f = h - (float)i; + float p = v * (1.0f - s); + float q = v * (1.0f - s * f); + float t = v * (1.0f - s * (1.0f - f)); - switch (i) - { - case 0: out_r = v; out_g = t; out_b = p; break; - case 1: out_r = q; out_g = v; out_b = p; break; - case 2: out_r = p; out_g = v; out_b = t; break; - case 3: out_r = p; out_g = q; out_b = v; break; - case 4: out_r = t; out_g = p; out_b = v; break; - case 5: default: out_r = v; out_g = p; out_b = q; break; - } + switch (i) + { + case 0: + out_r = v; + out_g = t; + out_b = p; + break; + case 1: + out_r = q; + out_g = v; + out_b = p; + break; + case 2: + out_r = p; + out_g = v; + out_b = t; + break; + case 3: + out_r = p; + out_g = q; + out_b = v; + break; + case 4: + out_r = t; + out_g = p; + out_b = v; + break; + case 5: + default: + out_r = v; + out_g = p; + out_b = q; + break; + } } FILE* ImFileOpen(const char* filename, const char* mode) { #if defined(_WIN32) && !defined(__CYGWIN__) - // We need a fopen() wrapper because MSVC/Windows fopen doesn't handle UTF-8 filenames. Converting both strings from UTF-8 to wchar format (using a single allocation, because we can) - const int filename_wsize = ImTextCountCharsFromUtf8(filename, NULL) + 1; - const int mode_wsize = ImTextCountCharsFromUtf8(mode, NULL) + 1; - ImVector buf; - buf.resize(filename_wsize + mode_wsize); - ImTextStrFromUtf8(&buf[0], filename_wsize, filename, NULL); - ImTextStrFromUtf8(&buf[filename_wsize], mode_wsize, mode, NULL); - return _wfopen((wchar_t*)&buf[0], (wchar_t*)&buf[filename_wsize]); + // We need a fopen() wrapper because MSVC/Windows fopen doesn't handle UTF-8 filenames. Converting both strings from UTF-8 to wchar format (using a single allocation, because we can) + const int filename_wsize = ImTextCountCharsFromUtf8(filename, NULL) + 1; + const int mode_wsize = ImTextCountCharsFromUtf8(mode, NULL) + 1; + ImVector buf; + buf.resize(filename_wsize + mode_wsize); + ImTextStrFromUtf8(&buf[0], filename_wsize, filename, NULL); + ImTextStrFromUtf8(&buf[filename_wsize], mode_wsize, mode, NULL); + return _wfopen((wchar_t*)&buf[0], (wchar_t*)&buf[filename_wsize]); #else - return fopen(filename, mode); + return fopen(filename, mode); #endif } @@ -1452,42 +1512,42 @@ FILE* ImFileOpen(const char* filename, const char* mode) // Memory allocated with ImGui::MemAlloc(), must be freed by user using ImGui::MemFree() void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, int* out_file_size, int padding_bytes) { - IM_ASSERT(filename && file_open_mode); - if (out_file_size) - *out_file_size = 0; + IM_ASSERT(filename && file_open_mode); + if (out_file_size) + *out_file_size = 0; - FILE* f; - if ((f = ImFileOpen(filename, file_open_mode)) == NULL) - return NULL; + FILE* f; + if ((f = ImFileOpen(filename, file_open_mode)) == NULL) + return NULL; - long file_size_signed; - if (fseek(f, 0, SEEK_END) || (file_size_signed = ftell(f)) == -1 || fseek(f, 0, SEEK_SET)) - { - fclose(f); - return NULL; - } + long file_size_signed; + if (fseek(f, 0, SEEK_END) || (file_size_signed = ftell(f)) == -1 || fseek(f, 0, SEEK_SET)) + { + fclose(f); + return NULL; + } - int file_size = (int)file_size_signed; - void* file_data = ImGui::MemAlloc(file_size + padding_bytes); - if (file_data == NULL) - { - fclose(f); - return NULL; - } - if (fread(file_data, 1, (size_t)file_size, f) != (size_t)file_size) - { - fclose(f); - ImGui::MemFree(file_data); - return NULL; - } - if (padding_bytes > 0) - memset((void *)(((char*)file_data) + file_size), 0, padding_bytes); + int file_size = (int)file_size_signed; + void* file_data = ImGui::MemAlloc(file_size + padding_bytes); + if (file_data == NULL) + { + fclose(f); + return NULL; + } + if (fread(file_data, 1, (size_t)file_size, f) != (size_t)file_size) + { + fclose(f); + ImGui::MemFree(file_data); + return NULL; + } + if (padding_bytes > 0) + memset((void*)(((char*)file_data) + file_size), 0, padding_bytes); - fclose(f); - if (out_file_size) - *out_file_size = file_size; + fclose(f); + if (out_file_size) + *out_file_size = file_size; - return file_data; + return file_data; } //----------------------------------------------------------------------------- @@ -1498,145 +1558,145 @@ void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, int* // std::lower_bound but without the bullshit static ImVector::iterator LowerBound(ImVector& data, ImGuiID key) { - ImVector::iterator first = data.begin(); - ImVector::iterator last = data.end(); - size_t count = (size_t)(last - first); - while (count > 0) - { - size_t count2 = count >> 1; - ImVector::iterator mid = first + count2; - if (mid->key < key) - { - first = ++mid; - count -= count2 + 1; - } - else - { - count = count2; - } - } - return first; + ImVector::iterator first = data.begin(); + ImVector::iterator last = data.end(); + size_t count = (size_t)(last - first); + while (count > 0) + { + size_t count2 = count >> 1; + ImVector::iterator mid = first + count2; + if (mid->key < key) + { + first = ++mid; + count -= count2 + 1; + } + else + { + count = count2; + } + } + return first; } // For quicker full rebuild of a storage (instead of an incremental one), you may add all your contents and then sort once. void ImGuiStorage::BuildSortByKey() { - struct StaticFunc - { - static int IMGUI_CDECL PairCompareByID(const void* lhs, const void* rhs) - { - // We can't just do a subtraction because qsort uses signed integers and subtracting our ID doesn't play well with that. - if (((const Pair*)lhs)->key > ((const Pair*)rhs)->key) return +1; - if (((const Pair*)lhs)->key < ((const Pair*)rhs)->key) return -1; - return 0; - } - }; - if (Data.Size > 1) - qsort(Data.Data, (size_t)Data.Size, sizeof(Pair), StaticFunc::PairCompareByID); + struct StaticFunc + { + static int IMGUI_CDECL PairCompareByID(const void* lhs, const void* rhs) + { + // We can't just do a subtraction because qsort uses signed integers and subtracting our ID doesn't play well with that. + if (((const Pair*)lhs)->key > ((const Pair*)rhs)->key) return +1; + if (((const Pair*)lhs)->key < ((const Pair*)rhs)->key) return -1; + return 0; + } + }; + if (Data.Size > 1) + qsort(Data.Data, (size_t)Data.Size, sizeof(Pair), StaticFunc::PairCompareByID); } int ImGuiStorage::GetInt(ImGuiID key, int default_val) const { - ImVector::iterator it = LowerBound(const_cast&>(Data), key); - if (it == Data.end() || it->key != key) - return default_val; - return it->val_i; + ImVector::iterator it = LowerBound(const_cast&>(Data), key); + if (it == Data.end() || it->key != key) + return default_val; + return it->val_i; } bool ImGuiStorage::GetBool(ImGuiID key, bool default_val) const { - return GetInt(key, default_val ? 1 : 0) != 0; + return GetInt(key, default_val ? 1 : 0) != 0; } float ImGuiStorage::GetFloat(ImGuiID key, float default_val) const { - ImVector::iterator it = LowerBound(const_cast&>(Data), key); - if (it == Data.end() || it->key != key) - return default_val; - return it->val_f; + ImVector::iterator it = LowerBound(const_cast&>(Data), key); + if (it == Data.end() || it->key != key) + return default_val; + return it->val_f; } void* ImGuiStorage::GetVoidPtr(ImGuiID key) const { - ImVector::iterator it = LowerBound(const_cast&>(Data), key); - if (it == Data.end() || it->key != key) - return NULL; - return it->val_p; + ImVector::iterator it = LowerBound(const_cast&>(Data), key); + if (it == Data.end() || it->key != key) + return NULL; + return it->val_p; } // References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer. int* ImGuiStorage::GetIntRef(ImGuiID key, int default_val) { - ImVector::iterator it = LowerBound(Data, key); - if (it == Data.end() || it->key != key) - it = Data.insert(it, Pair(key, default_val)); - return &it->val_i; + ImVector::iterator it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + it = Data.insert(it, Pair(key, default_val)); + return &it->val_i; } bool* ImGuiStorage::GetBoolRef(ImGuiID key, bool default_val) { - return (bool*)GetIntRef(key, default_val ? 1 : 0); + return (bool*)GetIntRef(key, default_val ? 1 : 0); } float* ImGuiStorage::GetFloatRef(ImGuiID key, float default_val) { - ImVector::iterator it = LowerBound(Data, key); - if (it == Data.end() || it->key != key) - it = Data.insert(it, Pair(key, default_val)); - return &it->val_f; + ImVector::iterator it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + it = Data.insert(it, Pair(key, default_val)); + return &it->val_f; } void** ImGuiStorage::GetVoidPtrRef(ImGuiID key, void* default_val) { - ImVector::iterator it = LowerBound(Data, key); - if (it == Data.end() || it->key != key) - it = Data.insert(it, Pair(key, default_val)); - return &it->val_p; + ImVector::iterator it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + it = Data.insert(it, Pair(key, default_val)); + return &it->val_p; } // FIXME-OPT: Need a way to reuse the result of lower_bound when doing GetInt()/SetInt() - not too bad because it only happens on explicit interaction (maximum one a frame) void ImGuiStorage::SetInt(ImGuiID key, int val) { - ImVector::iterator it = LowerBound(Data, key); - if (it == Data.end() || it->key != key) - { - Data.insert(it, Pair(key, val)); - return; - } - it->val_i = val; + ImVector::iterator it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + { + Data.insert(it, Pair(key, val)); + return; + } + it->val_i = val; } void ImGuiStorage::SetBool(ImGuiID key, bool val) { - SetInt(key, val ? 1 : 0); + SetInt(key, val ? 1 : 0); } void ImGuiStorage::SetFloat(ImGuiID key, float val) { - ImVector::iterator it = LowerBound(Data, key); - if (it == Data.end() || it->key != key) - { - Data.insert(it, Pair(key, val)); - return; - } - it->val_f = val; + ImVector::iterator it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + { + Data.insert(it, Pair(key, val)); + return; + } + it->val_f = val; } void ImGuiStorage::SetVoidPtr(ImGuiID key, void* val) { - ImVector::iterator it = LowerBound(Data, key); - if (it == Data.end() || it->key != key) - { - Data.insert(it, Pair(key, val)); - return; - } - it->val_p = val; + ImVector::iterator it = LowerBound(Data, key); + if (it == Data.end() || it->key != key) + { + Data.insert(it, Pair(key, val)); + return; + } + it->val_p = val; } void ImGuiStorage::SetAllInt(int v) { - for (int i = 0; i < Data.Size; i++) - Data[i].val_i = v; + for (int i = 0; i < Data.Size; i++) + Data[i].val_i = v; } //----------------------------------------------------------------------------- @@ -1646,97 +1706,97 @@ void ImGuiStorage::SetAllInt(int v) // Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" ImGuiTextFilter::ImGuiTextFilter(const char* default_filter) { - if (default_filter) - { - ImStrncpy(InputBuf, default_filter, IM_ARRAYSIZE(InputBuf)); - Build(); - } - else - { - InputBuf[0] = 0; - CountGrep = 0; - } + if (default_filter) + { + ImStrncpy(InputBuf, default_filter, IM_ARRAYSIZE(InputBuf)); + Build(); + } + else + { + InputBuf[0] = 0; + CountGrep = 0; + } } bool ImGuiTextFilter::Draw(const char* label, float width) { - if (width != 0.0f) - ImGui::PushItemWidth(width); - bool value_changed = ImGui::InputText(label, InputBuf, IM_ARRAYSIZE(InputBuf)); - if (width != 0.0f) - ImGui::PopItemWidth(); - if (value_changed) - Build(); - return value_changed; + if (width != 0.0f) + ImGui::PushItemWidth(width); + bool value_changed = ImGui::InputText(label, InputBuf, IM_ARRAYSIZE(InputBuf)); + if (width != 0.0f) + ImGui::PopItemWidth(); + if (value_changed) + Build(); + return value_changed; } void ImGuiTextFilter::TextRange::split(char separator, ImVector& out) { - out.resize(0); - const char* wb = b; - const char* we = wb; - while (we < e) - { - if (*we == separator) - { - out.push_back(TextRange(wb, we)); - wb = we + 1; - } - we++; - } - if (wb != we) - out.push_back(TextRange(wb, we)); + out.resize(0); + const char* wb = b; + const char* we = wb; + while (we < e) + { + if (*we == separator) + { + out.push_back(TextRange(wb, we)); + wb = we + 1; + } + we++; + } + if (wb != we) + out.push_back(TextRange(wb, we)); } void ImGuiTextFilter::Build() { - Filters.resize(0); - TextRange input_range(InputBuf, InputBuf+strlen(InputBuf)); - input_range.split(',', Filters); + Filters.resize(0); + TextRange input_range(InputBuf, InputBuf + strlen(InputBuf)); + input_range.split(',', Filters); - CountGrep = 0; - for (int i = 0; i != Filters.Size; i++) - { - Filters[i].trim_blanks(); - if (Filters[i].empty()) - continue; - if (Filters[i].front() != '-') - CountGrep += 1; - } + CountGrep = 0; + for (int i = 0; i != Filters.Size; i++) + { + Filters[i].trim_blanks(); + if (Filters[i].empty()) + continue; + if (Filters[i].front() != '-') + CountGrep += 1; + } } bool ImGuiTextFilter::PassFilter(const char* text, const char* text_end) const { - if (Filters.empty()) - return true; + if (Filters.empty()) + return true; - if (text == NULL) - text = ""; + if (text == NULL) + text = ""; - for (int i = 0; i != Filters.Size; i++) - { - const TextRange& f = Filters[i]; - if (f.empty()) - continue; - if (f.front() == '-') - { - // Subtract - if (ImStristr(text, text_end, f.begin()+1, f.end()) != NULL) - return false; - } - else - { - // Grep - if (ImStristr(text, text_end, f.begin(), f.end()) != NULL) - return true; - } - } + for (int i = 0; i != Filters.Size; i++) + { + const TextRange& f = Filters[i]; + if (f.empty()) + continue; + if (f.front() == '-') + { + // Subtract + if (ImStristr(text, text_end, f.begin() + 1, f.end()) != NULL) + return false; + } + else + { + // Grep + if (ImStristr(text, text_end, f.begin(), f.end()) != NULL) + return true; + } + } - // Implicit * grep - if (CountGrep == 0) - return true; + // Implicit * grep + if (CountGrep == 0) + return true; - return false; + return false; } //----------------------------------------------------------------------------- @@ -1752,31 +1812,31 @@ bool ImGuiTextFilter::PassFilter(const char* text, const char* text_end) const // Helper: Text buffer for logging/accumulating text void ImGuiTextBuffer::appendfv(const char* fmt, va_list args) { - va_list args_copy; - va_copy(args_copy, args); + va_list args_copy; + va_copy(args_copy, args); - int len = ImFormatStringV(NULL, 0, fmt, args); // FIXME-OPT: could do a first pass write attempt, likely successful on first pass. - if (len <= 0) - return; + int len = ImFormatStringV(NULL, 0, fmt, args); // FIXME-OPT: could do a first pass write attempt, likely successful on first pass. + if (len <= 0) + return; - const int write_off = Buf.Size; - const int needed_sz = write_off + len; - if (write_off + len >= Buf.Capacity) - { - int double_capacity = Buf.Capacity * 2; - Buf.reserve(needed_sz > double_capacity ? needed_sz : double_capacity); - } + const int write_off = Buf.Size; + const int needed_sz = write_off + len; + if (write_off + len >= Buf.Capacity) + { + int double_capacity = Buf.Capacity * 2; + Buf.reserve(needed_sz > double_capacity ? needed_sz : double_capacity); + } - Buf.resize(needed_sz); - ImFormatStringV(&Buf[write_off - 1], len + 1, fmt, args_copy); + Buf.resize(needed_sz); + ImFormatStringV(&Buf[write_off - 1], len + 1, fmt, args_copy); } void ImGuiTextBuffer::appendf(const char* fmt, ...) { - va_list args; - va_start(args, fmt); - appendfv(fmt, args); - va_end(args); + va_list args; + va_start(args, fmt); + appendfv(fmt, args); + va_end(args); } //----------------------------------------------------------------------------- @@ -1785,43 +1845,43 @@ void ImGuiTextBuffer::appendf(const char* fmt, ...) ImGuiMenuColumns::ImGuiMenuColumns() { - Count = 0; - Spacing = Width = NextWidth = 0.0f; - memset(Pos, 0, sizeof(Pos)); - memset(NextWidths, 0, sizeof(NextWidths)); + Count = 0; + Spacing = Width = NextWidth = 0.0f; + memset(Pos, 0, sizeof(Pos)); + memset(NextWidths, 0, sizeof(NextWidths)); } void ImGuiMenuColumns::Update(int count, float spacing, bool clear) { - IM_ASSERT(Count <= IM_ARRAYSIZE(Pos)); - Count = count; - Width = NextWidth = 0.0f; - Spacing = spacing; - if (clear) memset(NextWidths, 0, sizeof(NextWidths)); - for (int i = 0; i < Count; i++) - { - if (i > 0 && NextWidths[i] > 0.0f) - Width += Spacing; - Pos[i] = (float)(int)Width; - Width += NextWidths[i]; - NextWidths[i] = 0.0f; - } + IM_ASSERT(Count <= IM_ARRAYSIZE(Pos)); + Count = count; + Width = NextWidth = 0.0f; + Spacing = spacing; + if (clear) memset(NextWidths, 0, sizeof(NextWidths)); + for (int i = 0; i < Count; i++) + { + if (i > 0 && NextWidths[i] > 0.0f) + Width += Spacing; + Pos[i] = (float)(int)Width; + Width += NextWidths[i]; + NextWidths[i] = 0.0f; + } } -float ImGuiMenuColumns::DeclColumns(float w0, float w1, float w2) // not using va_arg because they promote float to double +float ImGuiMenuColumns::DeclColumns(float w0, float w1, float w2) // not using va_arg because they promote float to double { - NextWidth = 0.0f; - NextWidths[0] = ImMax(NextWidths[0], w0); - NextWidths[1] = ImMax(NextWidths[1], w1); - NextWidths[2] = ImMax(NextWidths[2], w2); - for (int i = 0; i < 3; i++) - NextWidth += NextWidths[i] + ((i > 0 && NextWidths[i] > 0.0f) ? Spacing : 0.0f); - return ImMax(Width, NextWidth); + NextWidth = 0.0f; + NextWidths[0] = ImMax(NextWidths[0], w0); + NextWidths[1] = ImMax(NextWidths[1], w1); + NextWidths[2] = ImMax(NextWidths[2], w2); + for (int i = 0; i < 3; i++) + NextWidth += NextWidths[i] + ((i > 0 && NextWidths[i] > 0.0f) ? Spacing : 0.0f); + return ImMax(Width, NextWidth); } float ImGuiMenuColumns::CalcExtraSpace(float avail_w) { - return ImMax(0.0f, avail_w - Width); + return ImMax(0.0f, avail_w - Width); } //----------------------------------------------------------------------------- @@ -1830,14 +1890,14 @@ float ImGuiMenuColumns::CalcExtraSpace(float avail_w) static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height) { - // Set cursor position and a few other things so that SetScrollHere() and Columns() can work when seeking cursor. - // FIXME: It is problematic that we have to do that here, because custom/equivalent end-user code would stumble on the same issue. Consider moving within SetCursorXXX functions? - ImGui::SetCursorPosY(pos_y); - ImGuiWindow* window = ImGui::GetCurrentWindow(); - window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; // Setting those fields so that SetScrollHere() can properly function after the end of our clipper usage. - window->DC.PrevLineHeight = (line_height - GImGui->Style.ItemSpacing.y); // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list. - if (window->DC.ColumnsSet) - window->DC.ColumnsSet->CellMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly + // Set cursor position and a few other things so that SetScrollHere() and Columns() can work when seeking cursor. + // FIXME: It is problematic that we have to do that here, because custom/equivalent end-user code would stumble on the same issue. Consider moving within SetCursorXXX functions? + ImGui::SetCursorPosY(pos_y); + ImGuiWindow* window = ImGui::GetCurrentWindow(); + window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; // Setting those fields so that SetScrollHere() can properly function after the end of our clipper usage. + window->DC.PrevLineHeight = (line_height - GImGui->Style.ItemSpacing.y); // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list. + if (window->DC.ColumnsSet) + window->DC.ColumnsSet->CellMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly } // Use case A: Begin() called from constructor with items_height<0, then called again from Sync() in StepNo 1 @@ -1845,66 +1905,70 @@ static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height) // FIXME-LEGACY: Ideally we should remove the Begin/End functions but they are part of the legacy API we still support. This is why some of the code in Step() calling Begin() and reassign some fields, spaghetti style. void ImGuiListClipper::Begin(int count, float items_height) { - StartPosY = ImGui::GetCursorPosY(); - ItemsHeight = items_height; - ItemsCount = count; - StepNo = 0; - DisplayEnd = DisplayStart = -1; - if (ItemsHeight > 0.0f) - { - ImGui::CalcListClipping(ItemsCount, ItemsHeight, &DisplayStart, &DisplayEnd); // calculate how many to clip/display - if (DisplayStart > 0) - SetCursorPosYAndSetupDummyPrevLine(StartPosY + DisplayStart * ItemsHeight, ItemsHeight); // advance cursor - StepNo = 2; - } + StartPosY = ImGui::GetCursorPosY(); + ItemsHeight = items_height; + ItemsCount = count; + StepNo = 0; + DisplayEnd = DisplayStart = -1; + if (ItemsHeight > 0.0f) + { + ImGui::CalcListClipping(ItemsCount, ItemsHeight, &DisplayStart, &DisplayEnd); // calculate how many to clip/display + if (DisplayStart > 0) + SetCursorPosYAndSetupDummyPrevLine(StartPosY + DisplayStart * ItemsHeight, ItemsHeight); // advance cursor + StepNo = 2; + } } void ImGuiListClipper::End() { - if (ItemsCount < 0) - return; - // In theory here we should assert that ImGui::GetCursorPosY() == StartPosY + DisplayEnd * ItemsHeight, but it feels saner to just seek at the end and not assert/crash the user. - if (ItemsCount < INT_MAX) - SetCursorPosYAndSetupDummyPrevLine(StartPosY + ItemsCount * ItemsHeight, ItemsHeight); // advance cursor - ItemsCount = -1; - StepNo = 3; + if (ItemsCount < 0) + return; + // In theory here we should assert that ImGui::GetCursorPosY() == StartPosY + DisplayEnd * ItemsHeight, but it feels saner to just seek at the end and not assert/crash the user. + if (ItemsCount < INT_MAX) + SetCursorPosYAndSetupDummyPrevLine(StartPosY + ItemsCount * ItemsHeight, ItemsHeight); // advance cursor + ItemsCount = -1; + StepNo = 3; } bool ImGuiListClipper::Step() { - if (ItemsCount == 0 || ImGui::GetCurrentWindowRead()->SkipItems) - { - ItemsCount = -1; - return false; - } - if (StepNo == 0) // Step 0: the clipper let you process the first element, regardless of it being visible or not, so we can measure the element height. - { - DisplayStart = 0; - DisplayEnd = 1; - StartPosY = ImGui::GetCursorPosY(); - StepNo = 1; - return true; - } - if (StepNo == 1) // Step 1: the clipper infer height from first element, calculate the actual range of elements to display, and position the cursor before the first element. - { - if (ItemsCount == 1) { ItemsCount = -1; return false; } - float items_height = ImGui::GetCursorPosY() - StartPosY; - IM_ASSERT(items_height > 0.0f); // If this triggers, it means Item 0 hasn't moved the cursor vertically - Begin(ItemsCount-1, items_height); - DisplayStart++; - DisplayEnd++; - StepNo = 3; - return true; - } - if (StepNo == 2) // Step 2: dummy step only required if an explicit items_height was passed to constructor or Begin() and user still call Step(). Does nothing and switch to Step 3. - { - IM_ASSERT(DisplayStart >= 0 && DisplayEnd >= 0); - StepNo = 3; - return true; - } - if (StepNo == 3) // Step 3: the clipper validate that we have reached the expected Y position (corresponding to element DisplayEnd), advance the cursor to the end of the list and then returns 'false' to end the loop. - End(); - return false; + if (ItemsCount == 0 || ImGui::GetCurrentWindowRead()->SkipItems) + { + ItemsCount = -1; + return false; + } + if (StepNo == 0) // Step 0: the clipper let you process the first element, regardless of it being visible or not, so we can measure the element height. + { + DisplayStart = 0; + DisplayEnd = 1; + StartPosY = ImGui::GetCursorPosY(); + StepNo = 1; + return true; + } + if (StepNo == 1) // Step 1: the clipper infer height from first element, calculate the actual range of elements to display, and position the cursor before the first element. + { + if (ItemsCount == 1) + { + ItemsCount = -1; + return false; + } + float items_height = ImGui::GetCursorPosY() - StartPosY; + IM_ASSERT(items_height > 0.0f); // If this triggers, it means Item 0 hasn't moved the cursor vertically + Begin(ItemsCount - 1, items_height); + DisplayStart++; + DisplayEnd++; + StepNo = 3; + return true; + } + if (StepNo == 2) // Step 2: dummy step only required if an explicit items_height was passed to constructor or Begin() and user still call Step(). Does nothing and switch to Step 3. + { + IM_ASSERT(DisplayStart >= 0 && DisplayEnd >= 0); + StepNo = 3; + return true; + } + if (StepNo == 3) // Step 3: the clipper validate that we have reached the expected Y position (corresponding to element DisplayEnd), advance the cursor to the end of the list and then returns 'false' to end the loop. + End(); + return false; } //----------------------------------------------------------------------------- @@ -1913,101 +1977,101 @@ bool ImGuiListClipper::Step() ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) { - Name = ImStrdup(name); - ID = ImHash(name, 0); - IDStack.push_back(ID); - Flags = 0; - PosFloat = Pos = ImVec2(0.0f, 0.0f); - Size = SizeFull = ImVec2(0.0f, 0.0f); - SizeContents = SizeContentsExplicit = ImVec2(0.0f, 0.0f); - WindowPadding = ImVec2(0.0f, 0.0f); - WindowRounding = 0.0f; - WindowBorderSize = 0.0f; - MoveId = GetID("#MOVE"); - ChildId = 0; - Scroll = ImVec2(0.0f, 0.0f); - ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); - ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f); - ScrollbarX = ScrollbarY = false; - ScrollbarSizes = ImVec2(0.0f, 0.0f); - Active = WasActive = false; - WriteAccessed = false; - Collapsed = false; - CollapseToggleWanted = false; - SkipItems = false; - Appearing = false; - CloseButton = false; - BeginOrderWithinParent = -1; - BeginOrderWithinContext = -1; - BeginCount = 0; - PopupId = 0; - AutoFitFramesX = AutoFitFramesY = -1; - AutoFitOnlyGrows = false; - AutoFitChildAxises = 0x00; - AutoPosLastDirection = ImGuiDir_None; - HiddenFrames = 0; - SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing; - SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX); + Name = ImStrdup(name); + ID = ImHash(name, 0); + IDStack.push_back(ID); + Flags = 0; + PosFloat = Pos = ImVec2(0.0f, 0.0f); + Size = SizeFull = ImVec2(0.0f, 0.0f); + SizeContents = SizeContentsExplicit = ImVec2(0.0f, 0.0f); + WindowPadding = ImVec2(0.0f, 0.0f); + WindowRounding = 0.0f; + WindowBorderSize = 0.0f; + MoveId = GetID("#MOVE"); + ChildId = 0; + Scroll = ImVec2(0.0f, 0.0f); + ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); + ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f); + ScrollbarX = ScrollbarY = false; + ScrollbarSizes = ImVec2(0.0f, 0.0f); + Active = WasActive = false; + WriteAccessed = false; + Collapsed = false; + CollapseToggleWanted = false; + SkipItems = false; + Appearing = false; + CloseButton = false; + BeginOrderWithinParent = -1; + BeginOrderWithinContext = -1; + BeginCount = 0; + PopupId = 0; + AutoFitFramesX = AutoFitFramesY = -1; + AutoFitOnlyGrows = false; + AutoFitChildAxises = 0x00; + AutoPosLastDirection = ImGuiDir_None; + HiddenFrames = 0; + SetWindowPosAllowFlags = SetWindowSizeAllowFlags = SetWindowCollapsedAllowFlags = ImGuiCond_Always | ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing; + SetWindowPosVal = SetWindowPosPivot = ImVec2(FLT_MAX, FLT_MAX); - LastFrameActive = -1; - ItemWidthDefault = 0.0f; - FontWindowScale = 1.0f; + LastFrameActive = -1; + ItemWidthDefault = 0.0f; + FontWindowScale = 1.0f; - DrawList = IM_NEW(ImDrawList)(&context->DrawListSharedData); - DrawList->_OwnerName = Name; - ParentWindow = NULL; - RootWindow = NULL; - RootWindowForTitleBarHighlight = NULL; - RootWindowForTabbing = NULL; - RootWindowForNav = NULL; + DrawList = IM_NEW(ImDrawList)(&context->DrawListSharedData); + DrawList->_OwnerName = Name; + ParentWindow = NULL; + RootWindow = NULL; + RootWindowForTitleBarHighlight = NULL; + RootWindowForTabbing = NULL; + RootWindowForNav = NULL; - NavLastIds[0] = NavLastIds[1] = 0; - NavRectRel[0] = NavRectRel[1] = ImRect(); - NavLastChildNavWindow = NULL; + NavLastIds[0] = NavLastIds[1] = 0; + NavRectRel[0] = NavRectRel[1] = ImRect(); + NavLastChildNavWindow = NULL; - FocusIdxAllCounter = FocusIdxTabCounter = -1; - FocusIdxAllRequestCurrent = FocusIdxTabRequestCurrent = INT_MAX; - FocusIdxAllRequestNext = FocusIdxTabRequestNext = INT_MAX; + FocusIdxAllCounter = FocusIdxTabCounter = -1; + FocusIdxAllRequestCurrent = FocusIdxTabRequestCurrent = INT_MAX; + FocusIdxAllRequestNext = FocusIdxTabRequestNext = INT_MAX; } ImGuiWindow::~ImGuiWindow() { - IM_DELETE(DrawList); - IM_DELETE(Name); - for (int i = 0; i != ColumnsStorage.Size; i++) - ColumnsStorage[i].~ImGuiColumnsSet(); + IM_DELETE(DrawList); + IM_DELETE(Name); + for (int i = 0; i != ColumnsStorage.Size; i++) + ColumnsStorage[i].~ImGuiColumnsSet(); } ImGuiID ImGuiWindow::GetID(const char* str, const char* str_end) { - ImGuiID seed = IDStack.back(); - ImGuiID id = ImHash(str, str_end ? (int)(str_end - str) : 0, seed); - ImGui::KeepAliveID(id); - return id; + ImGuiID seed = IDStack.back(); + ImGuiID id = ImHash(str, str_end ? (int)(str_end - str) : 0, seed); + ImGui::KeepAliveID(id); + return id; } ImGuiID ImGuiWindow::GetID(const void* ptr) { - ImGuiID seed = IDStack.back(); - ImGuiID id = ImHash(&ptr, sizeof(void*), seed); - ImGui::KeepAliveID(id); - return id; + ImGuiID seed = IDStack.back(); + ImGuiID id = ImHash(&ptr, sizeof(void*), seed); + ImGui::KeepAliveID(id); + return id; } ImGuiID ImGuiWindow::GetIDNoKeepAlive(const char* str, const char* str_end) { - ImGuiID seed = IDStack.back(); - return ImHash(str, str_end ? (int)(str_end - str) : 0, seed); + ImGuiID seed = IDStack.back(); + return ImHash(str, str_end ? (int)(str_end - str) : 0, seed); } // This is only used in rare/specific situations to manufacture an ID out of nowhere. ImGuiID ImGuiWindow::GetIDFromRectangle(const ImRect& r_abs) { - ImGuiID seed = IDStack.back(); - const int r_rel[4] = { (int)(r_abs.Min.x - Pos.x), (int)(r_abs.Min.y - Pos.y), (int)(r_abs.Max.x - Pos.x), (int)(r_abs.Max.y - Pos.y) }; - ImGuiID id = ImHash(&r_rel, sizeof(r_rel), seed); - ImGui::KeepAliveID(id); - return id; + ImGuiID seed = IDStack.back(); + const int r_rel[4] = {(int)(r_abs.Min.x - Pos.x), (int)(r_abs.Min.y - Pos.y), (int)(r_abs.Max.x - Pos.x), (int)(r_abs.Max.y - Pos.y)}; + ImGuiID id = ImHash(&r_rel, sizeof(r_rel), seed); + ImGui::KeepAliveID(id); + return id; } //----------------------------------------------------------------------------- @@ -2016,399 +2080,403 @@ ImGuiID ImGuiWindow::GetIDFromRectangle(const ImRect& r_abs) static void SetCurrentWindow(ImGuiWindow* window) { - ImGuiContext& g = *GImGui; - g.CurrentWindow = window; - if (window) - g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize(); + ImGuiContext& g = *GImGui; + g.CurrentWindow = window; + if (window) + g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize(); } static void SetNavID(ImGuiID id, int nav_layer) { - ImGuiContext& g = *GImGui; - IM_ASSERT(g.NavWindow); - IM_ASSERT(nav_layer == 0 || nav_layer == 1); - g.NavId = id; - g.NavWindow->NavLastIds[nav_layer] = id; + ImGuiContext& g = *GImGui; + IM_ASSERT(g.NavWindow); + IM_ASSERT(nav_layer == 0 || nav_layer == 1); + g.NavId = id; + g.NavWindow->NavLastIds[nav_layer] = id; } static void SetNavIDAndMoveMouse(ImGuiID id, int nav_layer, const ImRect& rect_rel) { - ImGuiContext& g = *GImGui; - SetNavID(id, nav_layer); - g.NavWindow->NavRectRel[nav_layer] = rect_rel; - g.NavMousePosDirty = true; - g.NavDisableHighlight = false; - g.NavDisableMouseHover = true; + ImGuiContext& g = *GImGui; + SetNavID(id, nav_layer); + g.NavWindow->NavRectRel[nav_layer] = rect_rel; + g.NavMousePosDirty = true; + g.NavDisableHighlight = false; + g.NavDisableMouseHover = true; } void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window) { - ImGuiContext& g = *GImGui; - g.ActiveIdIsJustActivated = (g.ActiveId != id); - if (g.ActiveIdIsJustActivated) - g.ActiveIdTimer = 0.0f; - g.ActiveId = id; - g.ActiveIdAllowNavDirFlags = 0; - g.ActiveIdAllowOverlap = false; - g.ActiveIdWindow = window; - if (id) - { - g.ActiveIdIsAlive = true; - g.ActiveIdSource = (g.NavActivateId == id || g.NavInputId == id || g.NavJustTabbedId == id || g.NavJustMovedToId == id) ? ImGuiInputSource_Nav : ImGuiInputSource_Mouse; - } + ImGuiContext& g = *GImGui; + g.ActiveIdIsJustActivated = (g.ActiveId != id); + if (g.ActiveIdIsJustActivated) + g.ActiveIdTimer = 0.0f; + g.ActiveId = id; + g.ActiveIdAllowNavDirFlags = 0; + g.ActiveIdAllowOverlap = false; + g.ActiveIdWindow = window; + if (id) + { + g.ActiveIdIsAlive = true; + g.ActiveIdSource = (g.NavActivateId == id || g.NavInputId == id || g.NavJustTabbedId == id || g.NavJustMovedToId == id) ? ImGuiInputSource_Nav : ImGuiInputSource_Mouse; + } } ImGuiID ImGui::GetActiveID() { - ImGuiContext& g = *GImGui; - return g.ActiveId; + ImGuiContext& g = *GImGui; + return g.ActiveId; } void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window) { - ImGuiContext& g = *GImGui; - IM_ASSERT(id != 0); + ImGuiContext& g = *GImGui; + IM_ASSERT(id != 0); - // Assume that SetFocusID() is called in the context where its NavLayer is the current layer, which is the case everywhere we call it. - const int nav_layer = window->DC.NavLayerCurrent; - if (g.NavWindow != window) - g.NavInitRequest = false; - g.NavId = id; - g.NavWindow = window; - g.NavLayer = nav_layer; - window->NavLastIds[nav_layer] = id; - if (window->DC.LastItemId == id) - window->NavRectRel[nav_layer] = ImRect(window->DC.LastItemRect.Min - window->Pos, window->DC.LastItemRect.Max - window->Pos); + // Assume that SetFocusID() is called in the context where its NavLayer is the current layer, which is the case everywhere we call it. + const int nav_layer = window->DC.NavLayerCurrent; + if (g.NavWindow != window) + g.NavInitRequest = false; + g.NavId = id; + g.NavWindow = window; + g.NavLayer = nav_layer; + window->NavLastIds[nav_layer] = id; + if (window->DC.LastItemId == id) + window->NavRectRel[nav_layer] = ImRect(window->DC.LastItemRect.Min - window->Pos, window->DC.LastItemRect.Max - window->Pos); - if (g.ActiveIdSource == ImGuiInputSource_Nav) - g.NavDisableMouseHover = true; - else - g.NavDisableHighlight = true; + if (g.ActiveIdSource == ImGuiInputSource_Nav) + g.NavDisableMouseHover = true; + else + g.NavDisableHighlight = true; } void ImGui::ClearActiveID() { - SetActiveID(0, NULL); + SetActiveID(0, NULL); } void ImGui::SetHoveredID(ImGuiID id) { - ImGuiContext& g = *GImGui; - g.HoveredId = id; - g.HoveredIdAllowOverlap = false; - g.HoveredIdTimer = (id != 0 && g.HoveredIdPreviousFrame == id) ? (g.HoveredIdTimer + g.IO.DeltaTime) : 0.0f; + ImGuiContext& g = *GImGui; + g.HoveredId = id; + g.HoveredIdAllowOverlap = false; + g.HoveredIdTimer = (id != 0 && g.HoveredIdPreviousFrame == id) ? (g.HoveredIdTimer + g.IO.DeltaTime) : 0.0f; } ImGuiID ImGui::GetHoveredID() { - ImGuiContext& g = *GImGui; - return g.HoveredId ? g.HoveredId : g.HoveredIdPreviousFrame; + ImGuiContext& g = *GImGui; + return g.HoveredId ? g.HoveredId : g.HoveredIdPreviousFrame; } void ImGui::KeepAliveID(ImGuiID id) { - ImGuiContext& g = *GImGui; - if (g.ActiveId == id) - g.ActiveIdIsAlive = true; + ImGuiContext& g = *GImGui; + if (g.ActiveId == id) + g.ActiveIdIsAlive = true; } static inline bool IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flags) { - // An active popup disable hovering on other windows (apart from its own children) - // FIXME-OPT: This could be cached/stored within the window. - ImGuiContext& g = *GImGui; - if (g.NavWindow) - if (ImGuiWindow* focused_root_window = g.NavWindow->RootWindow) - if (focused_root_window->WasActive && focused_root_window != window->RootWindow) - { - // For the purpose of those flags we differentiate "standard popup" from "modal popup" - // NB: The order of those two tests is important because Modal windows are also Popups. - if (focused_root_window->Flags & ImGuiWindowFlags_Modal) - return false; - if ((focused_root_window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiHoveredFlags_AllowWhenBlockedByPopup)) - return false; - } + // An active popup disable hovering on other windows (apart from its own children) + // FIXME-OPT: This could be cached/stored within the window. + ImGuiContext& g = *GImGui; + if (g.NavWindow) + if (ImGuiWindow* focused_root_window = g.NavWindow->RootWindow) + if (focused_root_window->WasActive && focused_root_window != window->RootWindow) + { + // For the purpose of those flags we differentiate "standard popup" from "modal popup" + // NB: The order of those two tests is important because Modal windows are also Popups. + if (focused_root_window->Flags & ImGuiWindowFlags_Modal) + return false; + if ((focused_root_window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiHoveredFlags_AllowWhenBlockedByPopup)) + return false; + } - return true; + return true; } // Advance cursor given item size for layout. void ImGui::ItemSize(const ImVec2& size, float text_offset_y) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - if (window->SkipItems) - return; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (window->SkipItems) + return; - // Always align ourselves on pixel boundaries - const float line_height = ImMax(window->DC.CurrentLineHeight, size.y); - const float text_base_offset = ImMax(window->DC.CurrentLineTextBaseOffset, text_offset_y); - //if (g.IO.KeyAlt) window->DrawList->AddRect(window->DC.CursorPos, window->DC.CursorPos + ImVec2(size.x, line_height), IM_COL32(255,0,0,200)); // [DEBUG] - window->DC.CursorPosPrevLine = ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y); - window->DC.CursorPos = ImVec2((float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX), (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y)); - window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x); - window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y - g.Style.ItemSpacing.y); - //if (g.IO.KeyAlt) window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // [DEBUG] + // Always align ourselves on pixel boundaries + const float line_height = ImMax(window->DC.CurrentLineHeight, size.y); + const float text_base_offset = ImMax(window->DC.CurrentLineTextBaseOffset, text_offset_y); + //if (g.IO.KeyAlt) window->DrawList->AddRect(window->DC.CursorPos, window->DC.CursorPos + ImVec2(size.x, line_height), IM_COL32(255,0,0,200)); // [DEBUG] + window->DC.CursorPosPrevLine = ImVec2(window->DC.CursorPos.x + size.x, window->DC.CursorPos.y); + window->DC.CursorPos = ImVec2((float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX), (float)(int)(window->DC.CursorPos.y + line_height + g.Style.ItemSpacing.y)); + window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPosPrevLine.x); + window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y - g.Style.ItemSpacing.y); + //if (g.IO.KeyAlt) window->DrawList->AddCircle(window->DC.CursorMaxPos, 3.0f, IM_COL32(255,0,0,255), 4); // [DEBUG] - window->DC.PrevLineHeight = line_height; - window->DC.PrevLineTextBaseOffset = text_base_offset; - window->DC.CurrentLineHeight = window->DC.CurrentLineTextBaseOffset = 0.0f; + window->DC.PrevLineHeight = line_height; + window->DC.PrevLineTextBaseOffset = text_base_offset; + window->DC.CurrentLineHeight = window->DC.CurrentLineTextBaseOffset = 0.0f; - // Horizontal layout mode - if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) - SameLine(); + // Horizontal layout mode + if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) + SameLine(); } void ImGui::ItemSize(const ImRect& bb, float text_offset_y) { - ItemSize(bb.GetSize(), text_offset_y); + ItemSize(bb.GetSize(), text_offset_y); } static ImGuiDir NavScoreItemGetQuadrant(float dx, float dy) { - if (fabsf(dx) > fabsf(dy)) - return (dx > 0.0f) ? ImGuiDir_Right : ImGuiDir_Left; - return (dy > 0.0f) ? ImGuiDir_Down : ImGuiDir_Up; + if (fabsf(dx) > fabsf(dy)) + return (dx > 0.0f) ? ImGuiDir_Right : ImGuiDir_Left; + return (dy > 0.0f) ? ImGuiDir_Down : ImGuiDir_Up; } static float NavScoreItemDistInterval(float a0, float a1, float b0, float b1) { - if (a1 < b0) - return a1 - b0; - if (b1 < a0) - return a0 - b1; - return 0.0f; + if (a1 < b0) + return a1 - b0; + if (b1 < a0) + return a0 - b1; + return 0.0f; } // Scoring function for directional navigation. Based on https://gist.github.com/rygorous/6981057 static bool NavScoreItem(ImGuiNavMoveResult* result, ImRect cand) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - if (g.NavLayer != window->DC.NavLayerCurrent) - return false; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (g.NavLayer != window->DC.NavLayerCurrent) + return false; - const ImRect& curr = g.NavScoringRectScreen; // Current modified source rect (NB: we've applied Max.x = Min.x in NavUpdate() to inhibit the effect of having varied item width) - g.NavScoringCount++; + const ImRect& curr = g.NavScoringRectScreen; // Current modified source rect (NB: we've applied Max.x = Min.x in NavUpdate() to inhibit the effect of having varied item width) + g.NavScoringCount++; - // We perform scoring on items bounding box clipped by their parent window on the other axis (clipping on our movement axis would give us equal scores for all clipped items) - if (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right) - { - cand.Min.y = ImClamp(cand.Min.y, window->ClipRect.Min.y, window->ClipRect.Max.y); - cand.Max.y = ImClamp(cand.Max.y, window->ClipRect.Min.y, window->ClipRect.Max.y); - } - else - { - cand.Min.x = ImClamp(cand.Min.x, window->ClipRect.Min.x, window->ClipRect.Max.x); - cand.Max.x = ImClamp(cand.Max.x, window->ClipRect.Min.x, window->ClipRect.Max.x); - } + // We perform scoring on items bounding box clipped by their parent window on the other axis (clipping on our movement axis would give us equal scores for all clipped items) + if (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right) + { + cand.Min.y = ImClamp(cand.Min.y, window->ClipRect.Min.y, window->ClipRect.Max.y); + cand.Max.y = ImClamp(cand.Max.y, window->ClipRect.Min.y, window->ClipRect.Max.y); + } + else + { + cand.Min.x = ImClamp(cand.Min.x, window->ClipRect.Min.x, window->ClipRect.Max.x); + cand.Max.x = ImClamp(cand.Max.x, window->ClipRect.Min.x, window->ClipRect.Max.x); + } - // Compute distance between boxes - // FIXME-NAV: Introducing biases for vertical navigation, needs to be removed. - float dbx = NavScoreItemDistInterval(cand.Min.x, cand.Max.x, curr.Min.x, curr.Max.x); - float dby = NavScoreItemDistInterval(ImLerp(cand.Min.y, cand.Max.y, 0.2f), ImLerp(cand.Min.y, cand.Max.y, 0.8f), ImLerp(curr.Min.y, curr.Max.y, 0.2f), ImLerp(curr.Min.y, curr.Max.y, 0.8f)); // Scale down on Y to keep using box-distance for vertically touching items - if (dby != 0.0f && dbx != 0.0f) - dbx = (dbx/1000.0f) + ((dbx > 0.0f) ? +1.0f : -1.0f); - float dist_box = fabsf(dbx) + fabsf(dby); + // Compute distance between boxes + // FIXME-NAV: Introducing biases for vertical navigation, needs to be removed. + float dbx = NavScoreItemDistInterval(cand.Min.x, cand.Max.x, curr.Min.x, curr.Max.x); + float dby = NavScoreItemDistInterval(ImLerp(cand.Min.y, cand.Max.y, 0.2f), ImLerp(cand.Min.y, cand.Max.y, 0.8f), ImLerp(curr.Min.y, curr.Max.y, 0.2f), ImLerp(curr.Min.y, curr.Max.y, 0.8f)); // Scale down on Y to keep using box-distance for vertically touching items + if (dby != 0.0f && dbx != 0.0f) + dbx = (dbx / 1000.0f) + ((dbx > 0.0f) ? +1.0f : -1.0f); + float dist_box = fabsf(dbx) + fabsf(dby); - // Compute distance between centers (this is off by a factor of 2, but we only compare center distances with each other so it doesn't matter) - float dcx = (cand.Min.x + cand.Max.x) - (curr.Min.x + curr.Max.x); - float dcy = (cand.Min.y + cand.Max.y) - (curr.Min.y + curr.Max.y); - float dist_center = fabsf(dcx) + fabsf(dcy); // L1 metric (need this for our connectedness guarantee) + // Compute distance between centers (this is off by a factor of 2, but we only compare center distances with each other so it doesn't matter) + float dcx = (cand.Min.x + cand.Max.x) - (curr.Min.x + curr.Max.x); + float dcy = (cand.Min.y + cand.Max.y) - (curr.Min.y + curr.Max.y); + float dist_center = fabsf(dcx) + fabsf(dcy); // L1 metric (need this for our connectedness guarantee) - // Determine which quadrant of 'curr' our candidate item 'cand' lies in based on distance - ImGuiDir quadrant; - float dax = 0.0f, day = 0.0f, dist_axial = 0.0f; - if (dbx != 0.0f || dby != 0.0f) - { - // For non-overlapping boxes, use distance between boxes - dax = dbx; - day = dby; - dist_axial = dist_box; - quadrant = NavScoreItemGetQuadrant(dbx, dby); - } - else if (dcx != 0.0f || dcy != 0.0f) - { - // For overlapping boxes with different centers, use distance between centers - dax = dcx; - day = dcy; - dist_axial = dist_center; - quadrant = NavScoreItemGetQuadrant(dcx, dcy); - } - else - { - // Degenerate case: two overlapping buttons with same center, break ties arbitrarily (note that LastItemId here is really the _previous_ item order, but it doesn't matter) - quadrant = (window->DC.LastItemId < g.NavId) ? ImGuiDir_Left : ImGuiDir_Right; - } + // Determine which quadrant of 'curr' our candidate item 'cand' lies in based on distance + ImGuiDir quadrant; + float dax = 0.0f, day = 0.0f, dist_axial = 0.0f; + if (dbx != 0.0f || dby != 0.0f) + { + // For non-overlapping boxes, use distance between boxes + dax = dbx; + day = dby; + dist_axial = dist_box; + quadrant = NavScoreItemGetQuadrant(dbx, dby); + } + else if (dcx != 0.0f || dcy != 0.0f) + { + // For overlapping boxes with different centers, use distance between centers + dax = dcx; + day = dcy; + dist_axial = dist_center; + quadrant = NavScoreItemGetQuadrant(dcx, dcy); + } + else + { + // Degenerate case: two overlapping buttons with same center, break ties arbitrarily (note that LastItemId here is really the _previous_ item order, but it doesn't matter) + quadrant = (window->DC.LastItemId < g.NavId) ? ImGuiDir_Left : ImGuiDir_Right; + } #if IMGUI_DEBUG_NAV_SCORING - char buf[128]; - if (ImGui::IsMouseHoveringRect(cand.Min, cand.Max)) - { - ImFormatString(buf, IM_ARRAYSIZE(buf), "dbox (%.2f,%.2f->%.4f)\ndcen (%.2f,%.2f->%.4f)\nd (%.2f,%.2f->%.4f)\nnav %c, quadrant %c", dbx, dby, dist_box, dcx, dcy, dist_center, dax, day, dist_axial, "WENS"[g.NavMoveDir], "WENS"[quadrant]); - g.OverlayDrawList.AddRect(curr.Min, curr.Max, IM_COL32(255, 200, 0, 100)); - g.OverlayDrawList.AddRect(cand.Min, cand.Max, IM_COL32(255,255,0,200)); - g.OverlayDrawList.AddRectFilled(cand.Max-ImVec2(4,4), cand.Max+ImGui::CalcTextSize(buf)+ImVec2(4,4), IM_COL32(40,0,0,150)); - g.OverlayDrawList.AddText(g.IO.FontDefault, 13.0f, cand.Max, ~0U, buf); - } - else if (g.IO.KeyCtrl) // Hold to preview score in matching quadrant. Press C to rotate. - { - if (IsKeyPressedMap(ImGuiKey_C)) { g.NavMoveDirLast = (ImGuiDir)((g.NavMoveDirLast + 1) & 3); g.IO.KeysDownDuration[g.IO.KeyMap[ImGuiKey_C]] = 0.01f; } - if (quadrant == g.NavMoveDir) - { - ImFormatString(buf, IM_ARRAYSIZE(buf), "%.0f/%.0f", dist_box, dist_center); - g.OverlayDrawList.AddRectFilled(cand.Min, cand.Max, IM_COL32(255, 0, 0, 200)); - g.OverlayDrawList.AddText(g.IO.FontDefault, 13.0f, cand.Min, IM_COL32(255, 255, 255, 255), buf); - } - } - #endif + char buf[128]; + if (ImGui::IsMouseHoveringRect(cand.Min, cand.Max)) + { + ImFormatString(buf, IM_ARRAYSIZE(buf), "dbox (%.2f,%.2f->%.4f)\ndcen (%.2f,%.2f->%.4f)\nd (%.2f,%.2f->%.4f)\nnav %c, quadrant %c", dbx, dby, dist_box, dcx, dcy, dist_center, dax, day, dist_axial, "WENS"[g.NavMoveDir], "WENS"[quadrant]); + g.OverlayDrawList.AddRect(curr.Min, curr.Max, IM_COL32(255, 200, 0, 100)); + g.OverlayDrawList.AddRect(cand.Min, cand.Max, IM_COL32(255, 255, 0, 200)); + g.OverlayDrawList.AddRectFilled(cand.Max - ImVec2(4, 4), cand.Max + ImGui::CalcTextSize(buf) + ImVec2(4, 4), IM_COL32(40, 0, 0, 150)); + g.OverlayDrawList.AddText(g.IO.FontDefault, 13.0f, cand.Max, ~0U, buf); + } + else if (g.IO.KeyCtrl) // Hold to preview score in matching quadrant. Press C to rotate. + { + if (IsKeyPressedMap(ImGuiKey_C)) + { + g.NavMoveDirLast = (ImGuiDir)((g.NavMoveDirLast + 1) & 3); + g.IO.KeysDownDuration[g.IO.KeyMap[ImGuiKey_C]] = 0.01f; + } + if (quadrant == g.NavMoveDir) + { + ImFormatString(buf, IM_ARRAYSIZE(buf), "%.0f/%.0f", dist_box, dist_center); + g.OverlayDrawList.AddRectFilled(cand.Min, cand.Max, IM_COL32(255, 0, 0, 200)); + g.OverlayDrawList.AddText(g.IO.FontDefault, 13.0f, cand.Min, IM_COL32(255, 255, 255, 255), buf); + } + } +#endif - // Is it in the quadrant we're interesting in moving to? - bool new_best = false; - if (quadrant == g.NavMoveDir) - { - // Does it beat the current best candidate? - if (dist_box < result->DistBox) - { - result->DistBox = dist_box; - result->DistCenter = dist_center; - return true; - } - if (dist_box == result->DistBox) - { - // Try using distance between center points to break ties - if (dist_center < result->DistCenter) - { - result->DistCenter = dist_center; - new_best = true; - } - else if (dist_center == result->DistCenter) - { - // Still tied! we need to be extra-careful to make sure everything gets linked properly. We consistently break ties by symbolically moving "later" items - // (with higher index) to the right/downwards by an infinitesimal amount since we the current "best" button already (so it must have a lower index), - // this is fairly easy. This rule ensures that all buttons with dx==dy==0 will end up being linked in order of appearance along the x axis. - if (((g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down) ? dby : dbx) < 0.0f) // moving bj to the right/down decreases distance - new_best = true; - } - } - } + // Is it in the quadrant we're interesting in moving to? + bool new_best = false; + if (quadrant == g.NavMoveDir) + { + // Does it beat the current best candidate? + if (dist_box < result->DistBox) + { + result->DistBox = dist_box; + result->DistCenter = dist_center; + return true; + } + if (dist_box == result->DistBox) + { + // Try using distance between center points to break ties + if (dist_center < result->DistCenter) + { + result->DistCenter = dist_center; + new_best = true; + } + else if (dist_center == result->DistCenter) + { + // Still tied! we need to be extra-careful to make sure everything gets linked properly. We consistently break ties by symbolically moving "later" items + // (with higher index) to the right/downwards by an infinitesimal amount since we the current "best" button already (so it must have a lower index), + // this is fairly easy. This rule ensures that all buttons with dx==dy==0 will end up being linked in order of appearance along the x axis. + if (((g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down) ? dby : dbx) < 0.0f) // moving bj to the right/down decreases distance + new_best = true; + } + } + } - // Axial check: if 'curr' has no link at all in some direction and 'cand' lies roughly in that direction, add a tentative link. This will only be kept if no "real" matches - // are found, so it only augments the graph produced by the above method using extra links. (important, since it doesn't guarantee strong connectedness) - // This is just to avoid buttons having no links in a particular direction when there's a suitable neighbor. you get good graphs without this too. - // 2017/09/29: FIXME: This now currently only enabled inside menu bars, ideally we'd disable it everywhere. Menus in particular need to catch failure. For general navigation it feels awkward. - // Disabling it may however lead to disconnected graphs when nodes are very spaced out on different axis. Perhaps consider offering this as an option? - if (result->DistBox == FLT_MAX && dist_axial < result->DistAxial) // Check axial match - if (g.NavLayer == 1 && !(g.NavWindow->Flags & ImGuiWindowFlags_ChildMenu)) - if ((g.NavMoveDir == ImGuiDir_Left && dax < 0.0f) || (g.NavMoveDir == ImGuiDir_Right && dax > 0.0f) || (g.NavMoveDir == ImGuiDir_Up && day < 0.0f) || (g.NavMoveDir == ImGuiDir_Down && day > 0.0f)) - { - result->DistAxial = dist_axial; - new_best = true; - } + // Axial check: if 'curr' has no link at all in some direction and 'cand' lies roughly in that direction, add a tentative link. This will only be kept if no "real" matches + // are found, so it only augments the graph produced by the above method using extra links. (important, since it doesn't guarantee strong connectedness) + // This is just to avoid buttons having no links in a particular direction when there's a suitable neighbor. you get good graphs without this too. + // 2017/09/29: FIXME: This now currently only enabled inside menu bars, ideally we'd disable it everywhere. Menus in particular need to catch failure. For general navigation it feels awkward. + // Disabling it may however lead to disconnected graphs when nodes are very spaced out on different axis. Perhaps consider offering this as an option? + if (result->DistBox == FLT_MAX && dist_axial < result->DistAxial) // Check axial match + if (g.NavLayer == 1 && !(g.NavWindow->Flags & ImGuiWindowFlags_ChildMenu)) + if ((g.NavMoveDir == ImGuiDir_Left && dax < 0.0f) || (g.NavMoveDir == ImGuiDir_Right && dax > 0.0f) || (g.NavMoveDir == ImGuiDir_Up && day < 0.0f) || (g.NavMoveDir == ImGuiDir_Down && day > 0.0f)) + { + result->DistAxial = dist_axial; + new_best = true; + } - return new_best; + return new_best; } static void NavSaveLastChildNavWindow(ImGuiWindow* child_window) { - ImGuiWindow* parent_window = child_window; - while (parent_window && (parent_window->Flags & ImGuiWindowFlags_ChildWindow) != 0 && (parent_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0) - parent_window = parent_window->ParentWindow; - if (parent_window && parent_window != child_window) - parent_window->NavLastChildNavWindow = child_window; + ImGuiWindow* parent_window = child_window; + while (parent_window && (parent_window->Flags & ImGuiWindowFlags_ChildWindow) != 0 && (parent_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0) + parent_window = parent_window->ParentWindow; + if (parent_window && parent_window != child_window) + parent_window->NavLastChildNavWindow = child_window; } // Call when we are expected to land on Layer 0 after FocusWindow() static ImGuiWindow* NavRestoreLastChildNavWindow(ImGuiWindow* window) { - return window->NavLastChildNavWindow ? window->NavLastChildNavWindow : window; + return window->NavLastChildNavWindow ? window->NavLastChildNavWindow : window; } static void NavRestoreLayer(int layer) { - ImGuiContext& g = *GImGui; - g.NavLayer = layer; - if (layer == 0) - g.NavWindow = NavRestoreLastChildNavWindow(g.NavWindow); - if (layer == 0 && g.NavWindow->NavLastIds[0] != 0) - SetNavIDAndMoveMouse(g.NavWindow->NavLastIds[0], layer, g.NavWindow->NavRectRel[0]); - else - ImGui::NavInitWindow(g.NavWindow, true); + ImGuiContext& g = *GImGui; + g.NavLayer = layer; + if (layer == 0) + g.NavWindow = NavRestoreLastChildNavWindow(g.NavWindow); + if (layer == 0 && g.NavWindow->NavLastIds[0] != 0) + SetNavIDAndMoveMouse(g.NavWindow->NavLastIds[0], layer, g.NavWindow->NavRectRel[0]); + else + ImGui::NavInitWindow(g.NavWindow, true); } static inline void NavUpdateAnyRequestFlag() { - ImGuiContext& g = *GImGui; - g.NavAnyRequest = g.NavMoveRequest || g.NavInitRequest || IMGUI_DEBUG_NAV_SCORING; + ImGuiContext& g = *GImGui; + g.NavAnyRequest = g.NavMoveRequest || g.NavInitRequest || IMGUI_DEBUG_NAV_SCORING; } static bool NavMoveRequestButNoResultYet() { - ImGuiContext& g = *GImGui; - return g.NavMoveRequest && g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0; + ImGuiContext& g = *GImGui; + return g.NavMoveRequest && g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0; } void ImGui::NavMoveRequestCancel() { - ImGuiContext& g = *GImGui; - g.NavMoveRequest = false; - NavUpdateAnyRequestFlag(); + ImGuiContext& g = *GImGui; + g.NavMoveRequest = false; + NavUpdateAnyRequestFlag(); } // We get there when either NavId == id, or when g.NavAnyRequest is set (which is updated by NavUpdateAnyRequestFlag above) static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, const ImGuiID id) { - ImGuiContext& g = *GImGui; - //if (!g.IO.NavActive) // [2017/10/06] Removed this possibly redundant test but I am not sure of all the side-effects yet. Some of the feature here will need to work regardless of using a _NoNavInputs flag. - // return; + ImGuiContext& g = *GImGui; + //if (!g.IO.NavActive) // [2017/10/06] Removed this possibly redundant test but I am not sure of all the side-effects yet. Some of the feature here will need to work regardless of using a _NoNavInputs flag. + // return; - const ImGuiItemFlags item_flags = window->DC.ItemFlags; - const ImRect nav_bb_rel(nav_bb.Min - window->Pos, nav_bb.Max - window->Pos); - if (g.NavInitRequest && g.NavLayer == window->DC.NavLayerCurrent) - { - // Even if 'ImGuiItemFlags_NoNavDefaultFocus' is on (typically collapse/close button) we record the first ResultId so they can be used as a fallback - if (!(item_flags & ImGuiItemFlags_NoNavDefaultFocus) || g.NavInitResultId == 0) - { - g.NavInitResultId = id; - g.NavInitResultRectRel = nav_bb_rel; - } - if (!(item_flags & ImGuiItemFlags_NoNavDefaultFocus)) - { - g.NavInitRequest = false; // Found a match, clear request - NavUpdateAnyRequestFlag(); - } - } + const ImGuiItemFlags item_flags = window->DC.ItemFlags; + const ImRect nav_bb_rel(nav_bb.Min - window->Pos, nav_bb.Max - window->Pos); + if (g.NavInitRequest && g.NavLayer == window->DC.NavLayerCurrent) + { + // Even if 'ImGuiItemFlags_NoNavDefaultFocus' is on (typically collapse/close button) we record the first ResultId so they can be used as a fallback + if (!(item_flags & ImGuiItemFlags_NoNavDefaultFocus) || g.NavInitResultId == 0) + { + g.NavInitResultId = id; + g.NavInitResultRectRel = nav_bb_rel; + } + if (!(item_flags & ImGuiItemFlags_NoNavDefaultFocus)) + { + g.NavInitRequest = false; // Found a match, clear request + NavUpdateAnyRequestFlag(); + } + } - // Scoring for navigation - if (g.NavId != id && !(item_flags & ImGuiItemFlags_NoNav)) - { - ImGuiNavMoveResult* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther; + // Scoring for navigation + if (g.NavId != id && !(item_flags & ImGuiItemFlags_NoNav)) + { + ImGuiNavMoveResult* result = (window == g.NavWindow) ? &g.NavMoveResultLocal : &g.NavMoveResultOther; #if IMGUI_DEBUG_NAV_SCORING - // [DEBUG] Score all items in NavWindow at all times - if (!g.NavMoveRequest) - g.NavMoveDir = g.NavMoveDirLast; - bool new_best = NavScoreItem(result, nav_bb) && g.NavMoveRequest; + // [DEBUG] Score all items in NavWindow at all times + if (!g.NavMoveRequest) + g.NavMoveDir = g.NavMoveDirLast; + bool new_best = NavScoreItem(result, nav_bb) && g.NavMoveRequest; #else - bool new_best = g.NavMoveRequest && NavScoreItem(result, nav_bb); + bool new_best = g.NavMoveRequest && NavScoreItem(result, nav_bb); #endif - if (new_best) - { - result->ID = id; - result->ParentID = window->IDStack.back(); - result->Window = window; - result->RectRel = nav_bb_rel; - } - } + if (new_best) + { + result->ID = id; + result->ParentID = window->IDStack.back(); + result->Window = window; + result->RectRel = nav_bb_rel; + } + } - // Update window-relative bounding box of navigated item - if (g.NavId == id) - { - g.NavWindow = window; // Always refresh g.NavWindow, because some operations such as FocusItem() don't have a window. - g.NavLayer = window->DC.NavLayerCurrent; - g.NavIdIsAlive = true; - g.NavIdTabCounter = window->FocusIdxTabCounter; - window->NavRectRel[window->DC.NavLayerCurrent] = nav_bb_rel; // Store item bounding box (relative to window position) - } + // Update window-relative bounding box of navigated item + if (g.NavId == id) + { + g.NavWindow = window; // Always refresh g.NavWindow, because some operations such as FocusItem() don't have a window. + g.NavLayer = window->DC.NavLayerCurrent; + g.NavIdIsAlive = true; + g.NavIdTabCounter = window->FocusIdxTabCounter; + window->NavRectRel[window->DC.NavLayerCurrent] = nav_bb_rel; // Store item bounding box (relative to window position) + } } // Declare item bounding box for clipping and interaction. @@ -2416,37 +2484,37 @@ static void ImGui::NavProcessItem(ImGuiWindow* window, const ImRect& nav_bb, con // declare their minimum size requirement to ItemSize() and then use a larger region for drawing/interaction, which is passed to ItemAdd(). bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; - if (id != 0) - { - // Navigation processing runs prior to clipping early-out - // (a) So that NavInitRequest can be honored, for newly opened windows to select a default widget - // (b) So that we can scroll up/down past clipped items. This adds a small O(N) cost to regular navigation requests unfortunately, but it is still limited to one window. - // it may not scale very well for windows with ten of thousands of item, but at least NavMoveRequest is only set on user interaction, aka maximum once a frame. - // We could early out with "if (is_clipped && !g.NavInitRequest) return false;" but when we wouldn't be able to reach unclipped widgets. This would work if user had explicit scrolling control (e.g. mapped on a stick) - window->DC.NavLayerActiveMaskNext |= window->DC.NavLayerCurrentMask; - if (g.NavId == id || g.NavAnyRequest) - if (g.NavWindow->RootWindowForNav == window->RootWindowForNav) - if (window == g.NavWindow || ((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened)) - NavProcessItem(window, nav_bb_arg ? *nav_bb_arg : bb, id); - } + if (id != 0) + { + // Navigation processing runs prior to clipping early-out + // (a) So that NavInitRequest can be honored, for newly opened windows to select a default widget + // (b) So that we can scroll up/down past clipped items. This adds a small O(N) cost to regular navigation requests unfortunately, but it is still limited to one window. + // it may not scale very well for windows with ten of thousands of item, but at least NavMoveRequest is only set on user interaction, aka maximum once a frame. + // We could early out with "if (is_clipped && !g.NavInitRequest) return false;" but when we wouldn't be able to reach unclipped widgets. This would work if user had explicit scrolling control (e.g. mapped on a stick) + window->DC.NavLayerActiveMaskNext |= window->DC.NavLayerCurrentMask; + if (g.NavId == id || g.NavAnyRequest) + if (g.NavWindow->RootWindowForNav == window->RootWindowForNav) + if (window == g.NavWindow || ((window->Flags | g.NavWindow->Flags) & ImGuiWindowFlags_NavFlattened)) + NavProcessItem(window, nav_bb_arg ? *nav_bb_arg : bb, id); + } - window->DC.LastItemId = id; - window->DC.LastItemRect = bb; - window->DC.LastItemStatusFlags = 0; + window->DC.LastItemId = id; + window->DC.LastItemRect = bb; + window->DC.LastItemStatusFlags = 0; - // Clipping test - const bool is_clipped = IsClippedEx(bb, id, false); - if (is_clipped) - return false; - //if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG] + // Clipping test + const bool is_clipped = IsClippedEx(bb, id, false); + if (is_clipped) + return false; + //if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG] - // We need to calculate this now to take account of the current clipping rectangle (as items like Selectable may change them) - if (IsMouseHoveringRect(bb.Min, bb.Max)) - window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_HoveredRect; - return true; + // We need to calculate this now to take account of the current clipping rectangle (as items like Selectable may change them) + if (IsMouseHoveringRect(bb.Min, bb.Max)) + window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_HoveredRect; + return true; } // This is roughly matching the behavior of internal-facing ItemHoverable() @@ -2454,1971 +2522,1986 @@ bool ImGui::ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb_arg) // - this should work even for non-interactive items that have no ID, so we cannot use LastItemId bool ImGui::IsItemHovered(ImGuiHoveredFlags flags) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - if (g.NavDisableMouseHover && !g.NavDisableHighlight) - return IsItemFocused(); + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (g.NavDisableMouseHover && !g.NavDisableHighlight) + return IsItemFocused(); - // Test for bounding box overlap, as updated as ItemAdd() - if (!(window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HoveredRect)) - return false; - IM_ASSERT((flags & (ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows)) == 0); // Flags not supported by this function + // Test for bounding box overlap, as updated as ItemAdd() + if (!(window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HoveredRect)) + return false; + IM_ASSERT((flags & (ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows)) == 0); // Flags not supported by this function - // Test if we are hovering the right window (our window could be behind another window) - // [2017/10/16] Reverted commit 344d48be3 and testing RootWindow instead. I believe it is correct to NOT test for RootWindow but this leaves us unable to use IsItemHovered() after EndChild() itself. - // Until a solution is found I believe reverting to the test from 2017/09/27 is safe since this was the test that has been running for a long while. - //if (g.HoveredWindow != window) - // return false; - if (g.HoveredRootWindow != window->RootWindow && !(flags & ImGuiHoveredFlags_AllowWhenOverlapped)) - return false; + // Test if we are hovering the right window (our window could be behind another window) + // [2017/10/16] Reverted commit 344d48be3 and testing RootWindow instead. I believe it is correct to NOT test for RootWindow but this leaves us unable to use IsItemHovered() after EndChild() itself. + // Until a solution is found I believe reverting to the test from 2017/09/27 is safe since this was the test that has been running for a long while. + //if (g.HoveredWindow != window) + // return false; + if (g.HoveredRootWindow != window->RootWindow && !(flags & ImGuiHoveredFlags_AllowWhenOverlapped)) + return false; - // Test if another item is active (e.g. being dragged) - if (!(flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) - if (g.ActiveId != 0 && g.ActiveId != window->DC.LastItemId && !g.ActiveIdAllowOverlap && g.ActiveId != window->MoveId) - return false; + // Test if another item is active (e.g. being dragged) + if (!(flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) + if (g.ActiveId != 0 && g.ActiveId != window->DC.LastItemId && !g.ActiveIdAllowOverlap && g.ActiveId != window->MoveId) + return false; - // Test if interactions on this window are blocked by an active popup or modal - if (!IsWindowContentHoverable(window, flags)) - return false; + // Test if interactions on this window are blocked by an active popup or modal + if (!IsWindowContentHoverable(window, flags)) + return false; - // Test if the item is disabled - if (window->DC.ItemFlags & ImGuiItemFlags_Disabled) - return false; - - // Special handling for the 1st item after Begin() which represent the title bar. When the window is collapsed (SkipItems==true) that last item will never be overwritten so we need to detect tht case. - if (window->DC.LastItemId == window->MoveId && window->WriteAccessed) - return false; - return true; + // Test if the item is disabled + if (window->DC.ItemFlags & ImGuiItemFlags_Disabled) + return false; + + // Special handling for the 1st item after Begin() which represent the title bar. When the window is collapsed (SkipItems==true) that last item will never be overwritten so we need to detect tht case. + if (window->DC.LastItemId == window->MoveId && window->WriteAccessed) + return false; + return true; } // Internal facing ItemHoverable() used when submitting widgets. Differs slightly from IsItemHovered(). bool ImGui::ItemHoverable(const ImRect& bb, ImGuiID id) { - ImGuiContext& g = *GImGui; - if (g.HoveredId != 0 && g.HoveredId != id && !g.HoveredIdAllowOverlap) - return false; + ImGuiContext& g = *GImGui; + if (g.HoveredId != 0 && g.HoveredId != id && !g.HoveredIdAllowOverlap) + return false; - ImGuiWindow* window = g.CurrentWindow; - if (g.HoveredWindow != window) - return false; - if (g.ActiveId != 0 && g.ActiveId != id && !g.ActiveIdAllowOverlap) - return false; - if (!IsMouseHoveringRect(bb.Min, bb.Max)) - return false; - if (g.NavDisableMouseHover || !IsWindowContentHoverable(window, ImGuiHoveredFlags_Default)) - return false; - if (window->DC.ItemFlags & ImGuiItemFlags_Disabled) - return false; + ImGuiWindow* window = g.CurrentWindow; + if (g.HoveredWindow != window) + return false; + if (g.ActiveId != 0 && g.ActiveId != id && !g.ActiveIdAllowOverlap) + return false; + if (!IsMouseHoveringRect(bb.Min, bb.Max)) + return false; + if (g.NavDisableMouseHover || !IsWindowContentHoverable(window, ImGuiHoveredFlags_Default)) + return false; + if (window->DC.ItemFlags & ImGuiItemFlags_Disabled) + return false; - SetHoveredID(id); - return true; + SetHoveredID(id); + return true; } bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - if (!bb.Overlaps(window->ClipRect)) - if (id == 0 || id != g.ActiveId) - if (clip_even_when_logged || !g.LogEnabled) - return true; - return false; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (!bb.Overlaps(window->ClipRect)) + if (id == 0 || id != g.ActiveId) + if (clip_even_when_logged || !g.LogEnabled) + return true; + return false; } bool ImGui::FocusableItemRegister(ImGuiWindow* window, ImGuiID id, bool tab_stop) { - ImGuiContext& g = *GImGui; + ImGuiContext& g = *GImGui; - const bool allow_keyboard_focus = (window->DC.ItemFlags & (ImGuiItemFlags_AllowKeyboardFocus | ImGuiItemFlags_Disabled)) == ImGuiItemFlags_AllowKeyboardFocus; - window->FocusIdxAllCounter++; - if (allow_keyboard_focus) - window->FocusIdxTabCounter++; + const bool allow_keyboard_focus = (window->DC.ItemFlags & (ImGuiItemFlags_AllowKeyboardFocus | ImGuiItemFlags_Disabled)) == ImGuiItemFlags_AllowKeyboardFocus; + window->FocusIdxAllCounter++; + if (allow_keyboard_focus) + window->FocusIdxTabCounter++; - // Process keyboard input at this point: TAB/Shift-TAB to tab out of the currently focused item. - // Note that we can always TAB out of a widget that doesn't allow tabbing in. - if (tab_stop && (g.ActiveId == id) && window->FocusIdxAllRequestNext == INT_MAX && window->FocusIdxTabRequestNext == INT_MAX && !g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab)) - window->FocusIdxTabRequestNext = window->FocusIdxTabCounter + (g.IO.KeyShift ? (allow_keyboard_focus ? -1 : 0) : +1); // Modulo on index will be applied at the end of frame once we've got the total counter of items. + // Process keyboard input at this point: TAB/Shift-TAB to tab out of the currently focused item. + // Note that we can always TAB out of a widget that doesn't allow tabbing in. + if (tab_stop && (g.ActiveId == id) && window->FocusIdxAllRequestNext == INT_MAX && window->FocusIdxTabRequestNext == INT_MAX && !g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab)) + window->FocusIdxTabRequestNext = window->FocusIdxTabCounter + (g.IO.KeyShift ? (allow_keyboard_focus ? -1 : 0) : +1); // Modulo on index will be applied at the end of frame once we've got the total counter of items. - if (window->FocusIdxAllCounter == window->FocusIdxAllRequestCurrent) - return true; - if (allow_keyboard_focus && window->FocusIdxTabCounter == window->FocusIdxTabRequestCurrent) - { - g.NavJustTabbedId = id; - return true; - } + if (window->FocusIdxAllCounter == window->FocusIdxAllRequestCurrent) + return true; + if (allow_keyboard_focus && window->FocusIdxTabCounter == window->FocusIdxTabRequestCurrent) + { + g.NavJustTabbedId = id; + return true; + } - return false; + return false; } void ImGui::FocusableItemUnregister(ImGuiWindow* window) { - window->FocusIdxAllCounter--; - window->FocusIdxTabCounter--; + window->FocusIdxAllCounter--; + window->FocusIdxTabCounter--; } ImVec2 ImGui::CalcItemSize(ImVec2 size, float default_x, float default_y) { - ImGuiContext& g = *GImGui; - ImVec2 content_max; - if (size.x < 0.0f || size.y < 0.0f) - content_max = g.CurrentWindow->Pos + GetContentRegionMax(); - if (size.x <= 0.0f) - size.x = (size.x == 0.0f) ? default_x : ImMax(content_max.x - g.CurrentWindow->DC.CursorPos.x, 4.0f) + size.x; - if (size.y <= 0.0f) - size.y = (size.y == 0.0f) ? default_y : ImMax(content_max.y - g.CurrentWindow->DC.CursorPos.y, 4.0f) + size.y; - return size; + ImGuiContext& g = *GImGui; + ImVec2 content_max; + if (size.x < 0.0f || size.y < 0.0f) + content_max = g.CurrentWindow->Pos + GetContentRegionMax(); + if (size.x <= 0.0f) + size.x = (size.x == 0.0f) ? default_x : ImMax(content_max.x - g.CurrentWindow->DC.CursorPos.x, 4.0f) + size.x; + if (size.y <= 0.0f) + size.y = (size.y == 0.0f) ? default_y : ImMax(content_max.y - g.CurrentWindow->DC.CursorPos.y, 4.0f) + size.y; + return size; } float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x) { - if (wrap_pos_x < 0.0f) - return 0.0f; + if (wrap_pos_x < 0.0f) + return 0.0f; - ImGuiWindow* window = GetCurrentWindowRead(); - if (wrap_pos_x == 0.0f) - wrap_pos_x = GetContentRegionMax().x + window->Pos.x; - else if (wrap_pos_x > 0.0f) - wrap_pos_x += window->Pos.x - window->Scroll.x; // wrap_pos_x is provided is window local space + ImGuiWindow* window = GetCurrentWindowRead(); + if (wrap_pos_x == 0.0f) + wrap_pos_x = GetContentRegionMax().x + window->Pos.x; + else if (wrap_pos_x > 0.0f) + wrap_pos_x += window->Pos.x - window->Scroll.x; // wrap_pos_x is provided is window local space - return ImMax(wrap_pos_x - pos.x, 1.0f); + return ImMax(wrap_pos_x - pos.x, 1.0f); } //----------------------------------------------------------------------------- void* ImGui::MemAlloc(size_t sz) { - GImAllocatorActiveAllocationsCount++; - return GImAllocatorAllocFunc(sz, GImAllocatorUserData); + GImAllocatorActiveAllocationsCount++; + return GImAllocatorAllocFunc(sz, GImAllocatorUserData); } void ImGui::MemFree(void* ptr) { - if (ptr) GImAllocatorActiveAllocationsCount--; - return GImAllocatorFreeFunc(ptr, GImAllocatorUserData); + if (ptr) GImAllocatorActiveAllocationsCount--; + return GImAllocatorFreeFunc(ptr, GImAllocatorUserData); } const char* ImGui::GetClipboardText() { - return GImGui->IO.GetClipboardTextFn ? GImGui->IO.GetClipboardTextFn(GImGui->IO.ClipboardUserData) : ""; + return GImGui->IO.GetClipboardTextFn ? GImGui->IO.GetClipboardTextFn(GImGui->IO.ClipboardUserData) : ""; } void ImGui::SetClipboardText(const char* text) { - if (GImGui->IO.SetClipboardTextFn) - GImGui->IO.SetClipboardTextFn(GImGui->IO.ClipboardUserData, text); + if (GImGui->IO.SetClipboardTextFn) + GImGui->IO.SetClipboardTextFn(GImGui->IO.ClipboardUserData, text); } const char* ImGui::GetVersion() { - return IMGUI_VERSION; + return IMGUI_VERSION; } // Internal state access - if you want to share ImGui state between modules (e.g. DLL) or allocate it yourself // Note that we still point to some static data and members (such as GFontAtlas), so the state instance you end up using will point to the static data within its module ImGuiContext* ImGui::GetCurrentContext() { - return GImGui; + return GImGui; } void ImGui::SetCurrentContext(ImGuiContext* ctx) { #ifdef IMGUI_SET_CURRENT_CONTEXT_FUNC - IMGUI_SET_CURRENT_CONTEXT_FUNC(ctx); // For custom thread-based hackery you may want to have control over this. + IMGUI_SET_CURRENT_CONTEXT_FUNC(ctx); // For custom thread-based hackery you may want to have control over this. #else - GImGui = ctx; + GImGui = ctx; #endif } -void ImGui::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void(*free_func)(void* ptr, void* user_data), void* user_data) +void ImGui::SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data) { - GImAllocatorAllocFunc = alloc_func; - GImAllocatorFreeFunc = free_func; - GImAllocatorUserData = user_data; + GImAllocatorAllocFunc = alloc_func; + GImAllocatorFreeFunc = free_func; + GImAllocatorUserData = user_data; } ImGuiContext* ImGui::CreateContext(ImFontAtlas* shared_font_atlas) { - ImGuiContext* ctx = IM_NEW(ImGuiContext)(shared_font_atlas); - if (GImGui == NULL) - SetCurrentContext(ctx); - Initialize(ctx); - return ctx; + ImGuiContext* ctx = IM_NEW(ImGuiContext)(shared_font_atlas); + if (GImGui == NULL) + SetCurrentContext(ctx); + Initialize(ctx); + return ctx; } void ImGui::DestroyContext(ImGuiContext* ctx) { - if (ctx == NULL) - ctx = GImGui; - Shutdown(ctx); - if (GImGui == ctx) - SetCurrentContext(NULL); - IM_DELETE(ctx); + if (ctx == NULL) + ctx = GImGui; + Shutdown(ctx); + if (GImGui == ctx) + SetCurrentContext(NULL); + IM_DELETE(ctx); } ImGuiIO& ImGui::GetIO() { - IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() or ImGui::SetCurrentContext()?"); - return GImGui->IO; + IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() or ImGui::SetCurrentContext()?"); + return GImGui->IO; } ImGuiStyle& ImGui::GetStyle() { - IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() or ImGui::SetCurrentContext()?"); - return GImGui->Style; + IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() or ImGui::SetCurrentContext()?"); + return GImGui->Style; } // Same value as passed to the old io.RenderDrawListsFn function. Valid after Render() and until the next call to NewFrame() ImDrawData* ImGui::GetDrawData() { - ImGuiContext& g = *GImGui; - return g.DrawData.Valid ? &g.DrawData : NULL; + ImGuiContext& g = *GImGui; + return g.DrawData.Valid ? &g.DrawData : NULL; } float ImGui::GetTime() { - return GImGui->Time; + return GImGui->Time; } int ImGui::GetFrameCount() { - return GImGui->FrameCount; + return GImGui->FrameCount; } ImDrawList* ImGui::GetOverlayDrawList() { - return &GImGui->OverlayDrawList; + return &GImGui->OverlayDrawList; } ImDrawListSharedData* ImGui::GetDrawListSharedData() { - return &GImGui->DrawListSharedData; + return &GImGui->DrawListSharedData; } // This needs to be called before we submit any widget (aka in or before Begin) void ImGui::NavInitWindow(ImGuiWindow* window, bool force_reinit) { - ImGuiContext& g = *GImGui; - IM_ASSERT(window == g.NavWindow); - bool init_for_nav = false; - if (!(window->Flags & ImGuiWindowFlags_NoNavInputs)) - if (!(window->Flags & ImGuiWindowFlags_ChildWindow) || (window->Flags & ImGuiWindowFlags_Popup) || (window->NavLastIds[0] == 0) || force_reinit) - init_for_nav = true; - if (init_for_nav) - { - SetNavID(0, g.NavLayer); - g.NavInitRequest = true; - g.NavInitRequestFromMove = false; - g.NavInitResultId = 0; - g.NavInitResultRectRel = ImRect(); - NavUpdateAnyRequestFlag(); - } - else - { - g.NavId = window->NavLastIds[0]; - } + ImGuiContext& g = *GImGui; + IM_ASSERT(window == g.NavWindow); + bool init_for_nav = false; + if (!(window->Flags & ImGuiWindowFlags_NoNavInputs)) + if (!(window->Flags & ImGuiWindowFlags_ChildWindow) || (window->Flags & ImGuiWindowFlags_Popup) || (window->NavLastIds[0] == 0) || force_reinit) + init_for_nav = true; + if (init_for_nav) + { + SetNavID(0, g.NavLayer); + g.NavInitRequest = true; + g.NavInitRequestFromMove = false; + g.NavInitResultId = 0; + g.NavInitResultRectRel = ImRect(); + NavUpdateAnyRequestFlag(); + } + else + { + g.NavId = window->NavLastIds[0]; + } } static ImVec2 NavCalcPreferredMousePos() { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.NavWindow; - if (!window) - return g.IO.MousePos; - const ImRect& rect_rel = window->NavRectRel[g.NavLayer]; - ImVec2 pos = g.NavWindow->Pos + ImVec2(rect_rel.Min.x + ImMin(g.Style.FramePadding.x*4, rect_rel.GetWidth()), rect_rel.Max.y - ImMin(g.Style.FramePadding.y, rect_rel.GetHeight())); - ImRect visible_rect = GetViewportRect(); - return ImFloor(ImClamp(pos, visible_rect.Min, visible_rect.Max)); // ImFloor() is important because non-integer mouse position application in back-end might be lossy and result in undesirable non-zero delta. + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.NavWindow; + if (!window) + return g.IO.MousePos; + const ImRect& rect_rel = window->NavRectRel[g.NavLayer]; + ImVec2 pos = g.NavWindow->Pos + ImVec2(rect_rel.Min.x + ImMin(g.Style.FramePadding.x * 4, rect_rel.GetWidth()), rect_rel.Max.y - ImMin(g.Style.FramePadding.y, rect_rel.GetHeight())); + ImRect visible_rect = GetViewportRect(); + return ImFloor(ImClamp(pos, visible_rect.Min, visible_rect.Max)); // ImFloor() is important because non-integer mouse position application in back-end might be lossy and result in undesirable non-zero delta. } -static int FindWindowIndex(ImGuiWindow* window) // FIXME-OPT O(N) +static int FindWindowIndex(ImGuiWindow* window) // FIXME-OPT O(N) { - ImGuiContext& g = *GImGui; - for (int i = g.Windows.Size-1; i >= 0; i--) - if (g.Windows[i] == window) - return i; - return -1; + ImGuiContext& g = *GImGui; + for (int i = g.Windows.Size - 1; i >= 0; i--) + if (g.Windows[i] == window) + return i; + return -1; } -static ImGuiWindow* FindWindowNavigable(int i_start, int i_stop, int dir) // FIXME-OPT O(N) +static ImGuiWindow* FindWindowNavigable(int i_start, int i_stop, int dir) // FIXME-OPT O(N) { - ImGuiContext& g = *GImGui; - for (int i = i_start; i >= 0 && i < g.Windows.Size && i != i_stop; i += dir) - if (ImGui::IsWindowNavFocusable(g.Windows[i])) - return g.Windows[i]; - return NULL; + ImGuiContext& g = *GImGui; + for (int i = i_start; i >= 0 && i < g.Windows.Size && i != i_stop; i += dir) + if (ImGui::IsWindowNavFocusable(g.Windows[i])) + return g.Windows[i]; + return NULL; } float ImGui::GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode) { - ImGuiContext& g = *GImGui; - if (mode == ImGuiInputReadMode_Down) - return g.IO.NavInputs[n]; // Instant, read analog input (0.0f..1.0f, as provided by user) + ImGuiContext& g = *GImGui; + if (mode == ImGuiInputReadMode_Down) + return g.IO.NavInputs[n]; // Instant, read analog input (0.0f..1.0f, as provided by user) - const float t = g.IO.NavInputsDownDuration[n]; - if (t < 0.0f && mode == ImGuiInputReadMode_Released) // Return 1.0f when just released, no repeat, ignore analog input. - return (g.IO.NavInputsDownDurationPrev[n] >= 0.0f ? 1.0f : 0.0f); - if (t < 0.0f) - return 0.0f; - if (mode == ImGuiInputReadMode_Pressed) // Return 1.0f when just pressed, no repeat, ignore analog input. - return (t == 0.0f) ? 1.0f : 0.0f; - if (mode == ImGuiInputReadMode_Repeat) - return (float)CalcTypematicPressedRepeatAmount(t, t - g.IO.DeltaTime, g.IO.KeyRepeatDelay * 0.80f, g.IO.KeyRepeatRate * 0.80f); - if (mode == ImGuiInputReadMode_RepeatSlow) - return (float)CalcTypematicPressedRepeatAmount(t, t - g.IO.DeltaTime, g.IO.KeyRepeatDelay * 1.00f, g.IO.KeyRepeatRate * 2.00f); - if (mode == ImGuiInputReadMode_RepeatFast) - return (float)CalcTypematicPressedRepeatAmount(t, t - g.IO.DeltaTime, g.IO.KeyRepeatDelay * 0.80f, g.IO.KeyRepeatRate * 0.30f); - return 0.0f; + const float t = g.IO.NavInputsDownDuration[n]; + if (t < 0.0f && mode == ImGuiInputReadMode_Released) // Return 1.0f when just released, no repeat, ignore analog input. + return (g.IO.NavInputsDownDurationPrev[n] >= 0.0f ? 1.0f : 0.0f); + if (t < 0.0f) + return 0.0f; + if (mode == ImGuiInputReadMode_Pressed) // Return 1.0f when just pressed, no repeat, ignore analog input. + return (t == 0.0f) ? 1.0f : 0.0f; + if (mode == ImGuiInputReadMode_Repeat) + return (float)CalcTypematicPressedRepeatAmount(t, t - g.IO.DeltaTime, g.IO.KeyRepeatDelay * 0.80f, g.IO.KeyRepeatRate * 0.80f); + if (mode == ImGuiInputReadMode_RepeatSlow) + return (float)CalcTypematicPressedRepeatAmount(t, t - g.IO.DeltaTime, g.IO.KeyRepeatDelay * 1.00f, g.IO.KeyRepeatRate * 2.00f); + if (mode == ImGuiInputReadMode_RepeatFast) + return (float)CalcTypematicPressedRepeatAmount(t, t - g.IO.DeltaTime, g.IO.KeyRepeatDelay * 0.80f, g.IO.KeyRepeatRate * 0.30f); + return 0.0f; } // Equivalent of IsKeyDown() for NavInputs[] static bool IsNavInputDown(ImGuiNavInput n) { - return GImGui->IO.NavInputs[n] > 0.0f; + return GImGui->IO.NavInputs[n] > 0.0f; } // Equivalent of IsKeyPressed() for NavInputs[] static bool IsNavInputPressed(ImGuiNavInput n, ImGuiInputReadMode mode) { - return ImGui::GetNavInputAmount(n, mode) > 0.0f; + return ImGui::GetNavInputAmount(n, mode) > 0.0f; } static bool IsNavInputPressedAnyOfTwo(ImGuiNavInput n1, ImGuiNavInput n2, ImGuiInputReadMode mode) { - return (ImGui::GetNavInputAmount(n1, mode) + ImGui::GetNavInputAmount(n2, mode)) > 0.0f; + return (ImGui::GetNavInputAmount(n1, mode) + ImGui::GetNavInputAmount(n2, mode)) > 0.0f; } ImVec2 ImGui::GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor, float fast_factor) { - ImVec2 delta(0.0f, 0.0f); - if (dir_sources & ImGuiNavDirSourceFlags_Keyboard) - delta += ImVec2(GetNavInputAmount(ImGuiNavInput_KeyRight_, mode) - GetNavInputAmount(ImGuiNavInput_KeyLeft_, mode), GetNavInputAmount(ImGuiNavInput_KeyDown_, mode) - GetNavInputAmount(ImGuiNavInput_KeyUp_, mode)); - if (dir_sources & ImGuiNavDirSourceFlags_PadDPad) - delta += ImVec2(GetNavInputAmount(ImGuiNavInput_DpadRight, mode) - GetNavInputAmount(ImGuiNavInput_DpadLeft, mode), GetNavInputAmount(ImGuiNavInput_DpadDown, mode) - GetNavInputAmount(ImGuiNavInput_DpadUp, mode)); - if (dir_sources & ImGuiNavDirSourceFlags_PadLStick) - delta += ImVec2(GetNavInputAmount(ImGuiNavInput_LStickRight, mode) - GetNavInputAmount(ImGuiNavInput_LStickLeft, mode), GetNavInputAmount(ImGuiNavInput_LStickDown, mode) - GetNavInputAmount(ImGuiNavInput_LStickUp, mode)); - if (slow_factor != 0.0f && IsNavInputDown(ImGuiNavInput_TweakSlow)) - delta *= slow_factor; - if (fast_factor != 0.0f && IsNavInputDown(ImGuiNavInput_TweakFast)) - delta *= fast_factor; - return delta; + ImVec2 delta(0.0f, 0.0f); + if (dir_sources & ImGuiNavDirSourceFlags_Keyboard) + delta += ImVec2(GetNavInputAmount(ImGuiNavInput_KeyRight_, mode) - GetNavInputAmount(ImGuiNavInput_KeyLeft_, mode), GetNavInputAmount(ImGuiNavInput_KeyDown_, mode) - GetNavInputAmount(ImGuiNavInput_KeyUp_, mode)); + if (dir_sources & ImGuiNavDirSourceFlags_PadDPad) + delta += ImVec2(GetNavInputAmount(ImGuiNavInput_DpadRight, mode) - GetNavInputAmount(ImGuiNavInput_DpadLeft, mode), GetNavInputAmount(ImGuiNavInput_DpadDown, mode) - GetNavInputAmount(ImGuiNavInput_DpadUp, mode)); + if (dir_sources & ImGuiNavDirSourceFlags_PadLStick) + delta += ImVec2(GetNavInputAmount(ImGuiNavInput_LStickRight, mode) - GetNavInputAmount(ImGuiNavInput_LStickLeft, mode), GetNavInputAmount(ImGuiNavInput_LStickDown, mode) - GetNavInputAmount(ImGuiNavInput_LStickUp, mode)); + if (slow_factor != 0.0f && IsNavInputDown(ImGuiNavInput_TweakSlow)) + delta *= slow_factor; + if (fast_factor != 0.0f && IsNavInputDown(ImGuiNavInput_TweakFast)) + delta *= fast_factor; + return delta; } static void NavUpdateWindowingHighlightWindow(int focus_change_dir) { - ImGuiContext& g = *GImGui; - IM_ASSERT(g.NavWindowingTarget); - if (g.NavWindowingTarget->Flags & ImGuiWindowFlags_Modal) - return; + ImGuiContext& g = *GImGui; + IM_ASSERT(g.NavWindowingTarget); + if (g.NavWindowingTarget->Flags & ImGuiWindowFlags_Modal) + return; - const int i_current = FindWindowIndex(g.NavWindowingTarget); - ImGuiWindow* window_target = FindWindowNavigable(i_current + focus_change_dir, -INT_MAX, focus_change_dir); - if (!window_target) - window_target = FindWindowNavigable((focus_change_dir < 0) ? (g.Windows.Size - 1) : 0, i_current, focus_change_dir); - g.NavWindowingTarget = window_target; - g.NavWindowingToggleLayer = false; + const int i_current = FindWindowIndex(g.NavWindowingTarget); + ImGuiWindow* window_target = FindWindowNavigable(i_current + focus_change_dir, -INT_MAX, focus_change_dir); + if (!window_target) + window_target = FindWindowNavigable((focus_change_dir < 0) ? (g.Windows.Size - 1) : 0, i_current, focus_change_dir); + g.NavWindowingTarget = window_target; + g.NavWindowingToggleLayer = false; } // Window management mode (hold to: change focus/move/resize, tap to: toggle menu layer) static void ImGui::NavUpdateWindowing() { - ImGuiContext& g = *GImGui; - ImGuiWindow* apply_focus_window = NULL; - bool apply_toggle_layer = false; + ImGuiContext& g = *GImGui; + ImGuiWindow* apply_focus_window = NULL; + bool apply_toggle_layer = false; - bool start_windowing_with_gamepad = !g.NavWindowingTarget && IsNavInputPressed(ImGuiNavInput_Menu, ImGuiInputReadMode_Pressed); - bool start_windowing_with_keyboard = !g.NavWindowingTarget && g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab) && (g.IO.NavFlags & ImGuiNavFlags_EnableKeyboard); - if (start_windowing_with_gamepad || start_windowing_with_keyboard) - if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavigable(g.Windows.Size - 1, -INT_MAX, -1)) - { - g.NavWindowingTarget = window->RootWindowForTabbing; - g.NavWindowingHighlightTimer = g.NavWindowingHighlightAlpha = 0.0f; - g.NavWindowingToggleLayer = start_windowing_with_keyboard ? false : true; - g.NavWindowingInputSource = start_windowing_with_keyboard ? ImGuiInputSource_NavKeyboard : ImGuiInputSource_NavGamepad; - } + bool start_windowing_with_gamepad = !g.NavWindowingTarget && IsNavInputPressed(ImGuiNavInput_Menu, ImGuiInputReadMode_Pressed); + bool start_windowing_with_keyboard = !g.NavWindowingTarget && g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab) && (g.IO.NavFlags & ImGuiNavFlags_EnableKeyboard); + if (start_windowing_with_gamepad || start_windowing_with_keyboard) + if (ImGuiWindow* window = g.NavWindow ? g.NavWindow : FindWindowNavigable(g.Windows.Size - 1, -INT_MAX, -1)) + { + g.NavWindowingTarget = window->RootWindowForTabbing; + g.NavWindowingHighlightTimer = g.NavWindowingHighlightAlpha = 0.0f; + g.NavWindowingToggleLayer = start_windowing_with_keyboard ? false : true; + g.NavWindowingInputSource = start_windowing_with_keyboard ? ImGuiInputSource_NavKeyboard : ImGuiInputSource_NavGamepad; + } - // Gamepad update - g.NavWindowingHighlightTimer += g.IO.DeltaTime; - if (g.NavWindowingTarget && g.NavWindowingInputSource == ImGuiInputSource_NavGamepad) - { - // Highlight only appears after a brief time holding the button, so that a fast tap on PadMenu (to toggle NavLayer) doesn't add visual noise - g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha, ImSaturate((g.NavWindowingHighlightTimer - 0.20f) / 0.05f)); + // Gamepad update + g.NavWindowingHighlightTimer += g.IO.DeltaTime; + if (g.NavWindowingTarget && g.NavWindowingInputSource == ImGuiInputSource_NavGamepad) + { + // Highlight only appears after a brief time holding the button, so that a fast tap on PadMenu (to toggle NavLayer) doesn't add visual noise + g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha, ImSaturate((g.NavWindowingHighlightTimer - 0.20f) / 0.05f)); - // Select window to focus - const int focus_change_dir = (int)IsNavInputPressed(ImGuiNavInput_FocusPrev, ImGuiInputReadMode_RepeatSlow) - (int)IsNavInputPressed(ImGuiNavInput_FocusNext, ImGuiInputReadMode_RepeatSlow); - if (focus_change_dir != 0) - { - NavUpdateWindowingHighlightWindow(focus_change_dir); - g.NavWindowingHighlightAlpha = 1.0f; - } + // Select window to focus + const int focus_change_dir = (int)IsNavInputPressed(ImGuiNavInput_FocusPrev, ImGuiInputReadMode_RepeatSlow) - (int)IsNavInputPressed(ImGuiNavInput_FocusNext, ImGuiInputReadMode_RepeatSlow); + if (focus_change_dir != 0) + { + NavUpdateWindowingHighlightWindow(focus_change_dir); + g.NavWindowingHighlightAlpha = 1.0f; + } - // Single press toggles NavLayer, long press with L/R apply actual focus on release (until then the window was merely rendered front-most) - if (!IsNavInputDown(ImGuiNavInput_Menu)) - { - g.NavWindowingToggleLayer &= (g.NavWindowingHighlightAlpha < 1.0f); // Once button was held long enough we don't consider it a tap-to-toggle-layer press anymore. - if (g.NavWindowingToggleLayer && g.NavWindow) - apply_toggle_layer = true; - else if (!g.NavWindowingToggleLayer) - apply_focus_window = g.NavWindowingTarget; - g.NavWindowingTarget = NULL; - } - } + // Single press toggles NavLayer, long press with L/R apply actual focus on release (until then the window was merely rendered front-most) + if (!IsNavInputDown(ImGuiNavInput_Menu)) + { + g.NavWindowingToggleLayer &= (g.NavWindowingHighlightAlpha < 1.0f); // Once button was held long enough we don't consider it a tap-to-toggle-layer press anymore. + if (g.NavWindowingToggleLayer && g.NavWindow) + apply_toggle_layer = true; + else if (!g.NavWindowingToggleLayer) + apply_focus_window = g.NavWindowingTarget; + g.NavWindowingTarget = NULL; + } + } - // Keyboard: Focus - if (g.NavWindowingTarget && g.NavWindowingInputSource == ImGuiInputSource_NavKeyboard) - { - // Visuals only appears after a brief time after pressing TAB the first time, so that a fast CTRL+TAB doesn't add visual noise - g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha, ImSaturate((g.NavWindowingHighlightTimer - 0.15f) / 0.04f)); // 1.0f - if (IsKeyPressedMap(ImGuiKey_Tab, true)) - NavUpdateWindowingHighlightWindow(g.IO.KeyShift ? +1 : -1); - if (!g.IO.KeyCtrl) - apply_focus_window = g.NavWindowingTarget; - } + // Keyboard: Focus + if (g.NavWindowingTarget && g.NavWindowingInputSource == ImGuiInputSource_NavKeyboard) + { + // Visuals only appears after a brief time after pressing TAB the first time, so that a fast CTRL+TAB doesn't add visual noise + g.NavWindowingHighlightAlpha = ImMax(g.NavWindowingHighlightAlpha, ImSaturate((g.NavWindowingHighlightTimer - 0.15f) / 0.04f)); // 1.0f + if (IsKeyPressedMap(ImGuiKey_Tab, true)) + NavUpdateWindowingHighlightWindow(g.IO.KeyShift ? +1 : -1); + if (!g.IO.KeyCtrl) + apply_focus_window = g.NavWindowingTarget; + } - // Keyboard: Press and Release ALT to toggle menu layer - // FIXME: We lack an explicit IO variable for "is the imgui window focused", so compare mouse validity to detect the common case of back-end clearing releases all keys on ALT-TAB - if ((g.ActiveId == 0 || g.ActiveIdAllowOverlap) && IsNavInputPressed(ImGuiNavInput_KeyMenu_, ImGuiInputReadMode_Released)) - if (IsMousePosValid(&g.IO.MousePos) == IsMousePosValid(&g.IO.MousePosPrev)) - apply_toggle_layer = true; + // Keyboard: Press and Release ALT to toggle menu layer + // FIXME: We lack an explicit IO variable for "is the imgui window focused", so compare mouse validity to detect the common case of back-end clearing releases all keys on ALT-TAB + if ((g.ActiveId == 0 || g.ActiveIdAllowOverlap) && IsNavInputPressed(ImGuiNavInput_KeyMenu_, ImGuiInputReadMode_Released)) + if (IsMousePosValid(&g.IO.MousePos) == IsMousePosValid(&g.IO.MousePosPrev)) + apply_toggle_layer = true; - // Move window - if (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoMove)) - { - ImVec2 move_delta; - if (g.NavWindowingInputSource == ImGuiInputSource_NavKeyboard && !g.IO.KeyShift) - move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard, ImGuiInputReadMode_Down); - if (g.NavWindowingInputSource == ImGuiInputSource_NavGamepad) - move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadLStick, ImGuiInputReadMode_Down); - if (move_delta.x != 0.0f || move_delta.y != 0.0f) - { - const float NAV_MOVE_SPEED = 800.0f; - const float move_speed = ImFloor(NAV_MOVE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y)); - g.NavWindowingTarget->PosFloat += move_delta * move_speed; - g.NavDisableMouseHover = true; - MarkIniSettingsDirty(g.NavWindowingTarget); - } - } + // Move window + if (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoMove)) + { + ImVec2 move_delta; + if (g.NavWindowingInputSource == ImGuiInputSource_NavKeyboard && !g.IO.KeyShift) + move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard, ImGuiInputReadMode_Down); + if (g.NavWindowingInputSource == ImGuiInputSource_NavGamepad) + move_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadLStick, ImGuiInputReadMode_Down); + if (move_delta.x != 0.0f || move_delta.y != 0.0f) + { + const float NAV_MOVE_SPEED = 800.0f; + const float move_speed = ImFloor(NAV_MOVE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y)); + g.NavWindowingTarget->PosFloat += move_delta * move_speed; + g.NavDisableMouseHover = true; + MarkIniSettingsDirty(g.NavWindowingTarget); + } + } - // Apply final focus - if (apply_focus_window && (g.NavWindow == NULL || apply_focus_window != g.NavWindow->RootWindowForTabbing)) - { - g.NavDisableHighlight = false; - g.NavDisableMouseHover = true; - apply_focus_window = NavRestoreLastChildNavWindow(apply_focus_window); - ClosePopupsOverWindow(apply_focus_window); - FocusWindow(apply_focus_window); - if (apply_focus_window->NavLastIds[0] == 0) - NavInitWindow(apply_focus_window, false); + // Apply final focus + if (apply_focus_window && (g.NavWindow == NULL || apply_focus_window != g.NavWindow->RootWindowForTabbing)) + { + g.NavDisableHighlight = false; + g.NavDisableMouseHover = true; + apply_focus_window = NavRestoreLastChildNavWindow(apply_focus_window); + ClosePopupsOverWindow(apply_focus_window); + FocusWindow(apply_focus_window); + if (apply_focus_window->NavLastIds[0] == 0) + NavInitWindow(apply_focus_window, false); - // If the window only has a menu layer, select it directly - if (apply_focus_window->DC.NavLayerActiveMask == (1 << 1)) - g.NavLayer = 1; - } - if (apply_focus_window) - g.NavWindowingTarget = NULL; + // If the window only has a menu layer, select it directly + if (apply_focus_window->DC.NavLayerActiveMask == (1 << 1)) + g.NavLayer = 1; + } + if (apply_focus_window) + g.NavWindowingTarget = NULL; - // Apply menu/layer toggle - if (apply_toggle_layer && g.NavWindow) - { - ImGuiWindow* new_nav_window = g.NavWindow; - while ((new_nav_window->DC.NavLayerActiveMask & (1 << 1)) == 0 && (new_nav_window->Flags & ImGuiWindowFlags_ChildWindow) != 0 && (new_nav_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0) - new_nav_window = new_nav_window->ParentWindow; - if (new_nav_window != g.NavWindow) - { - ImGuiWindow* old_nav_window = g.NavWindow; - FocusWindow(new_nav_window); - new_nav_window->NavLastChildNavWindow = old_nav_window; - } - g.NavDisableHighlight = false; - g.NavDisableMouseHover = true; - NavRestoreLayer((g.NavWindow->DC.NavLayerActiveMask & (1 << 1)) ? (g.NavLayer ^ 1) : 0); - } + // Apply menu/layer toggle + if (apply_toggle_layer && g.NavWindow) + { + ImGuiWindow* new_nav_window = g.NavWindow; + while ((new_nav_window->DC.NavLayerActiveMask & (1 << 1)) == 0 && (new_nav_window->Flags & ImGuiWindowFlags_ChildWindow) != 0 && (new_nav_window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) == 0) + new_nav_window = new_nav_window->ParentWindow; + if (new_nav_window != g.NavWindow) + { + ImGuiWindow* old_nav_window = g.NavWindow; + FocusWindow(new_nav_window); + new_nav_window->NavLastChildNavWindow = old_nav_window; + } + g.NavDisableHighlight = false; + g.NavDisableMouseHover = true; + NavRestoreLayer((g.NavWindow->DC.NavLayerActiveMask & (1 << 1)) ? (g.NavLayer ^ 1) : 0); + } } // NB: We modify rect_rel by the amount we scrolled for, so it is immediately updated. static void NavScrollToBringItemIntoView(ImGuiWindow* window, ImRect& item_rect_rel) { - // Scroll to keep newly navigated item fully into view - ImRect window_rect_rel(window->InnerRect.Min - window->Pos - ImVec2(1, 1), window->InnerRect.Max - window->Pos + ImVec2(1, 1)); - //g.OverlayDrawList.AddRect(window->Pos + window_rect_rel.Min, window->Pos + window_rect_rel.Max, IM_COL32_WHITE); // [DEBUG] - if (window_rect_rel.Contains(item_rect_rel)) - return; + // Scroll to keep newly navigated item fully into view + ImRect window_rect_rel(window->InnerRect.Min - window->Pos - ImVec2(1, 1), window->InnerRect.Max - window->Pos + ImVec2(1, 1)); + //g.OverlayDrawList.AddRect(window->Pos + window_rect_rel.Min, window->Pos + window_rect_rel.Max, IM_COL32_WHITE); // [DEBUG] + if (window_rect_rel.Contains(item_rect_rel)) + return; - ImGuiContext& g = *GImGui; - if (window->ScrollbarX && item_rect_rel.Min.x < window_rect_rel.Min.x) - { - window->ScrollTarget.x = item_rect_rel.Min.x + window->Scroll.x - g.Style.ItemSpacing.x; - window->ScrollTargetCenterRatio.x = 0.0f; - } - else if (window->ScrollbarX && item_rect_rel.Max.x >= window_rect_rel.Max.x) - { - window->ScrollTarget.x = item_rect_rel.Max.x + window->Scroll.x + g.Style.ItemSpacing.x; - window->ScrollTargetCenterRatio.x = 1.0f; - } - if (item_rect_rel.Min.y < window_rect_rel.Min.y) - { - window->ScrollTarget.y = item_rect_rel.Min.y + window->Scroll.y - g.Style.ItemSpacing.y; - window->ScrollTargetCenterRatio.y = 0.0f; - } - else if (item_rect_rel.Max.y >= window_rect_rel.Max.y) - { - window->ScrollTarget.y = item_rect_rel.Max.y + window->Scroll.y + g.Style.ItemSpacing.y; - window->ScrollTargetCenterRatio.y = 1.0f; - } + ImGuiContext& g = *GImGui; + if (window->ScrollbarX && item_rect_rel.Min.x < window_rect_rel.Min.x) + { + window->ScrollTarget.x = item_rect_rel.Min.x + window->Scroll.x - g.Style.ItemSpacing.x; + window->ScrollTargetCenterRatio.x = 0.0f; + } + else if (window->ScrollbarX && item_rect_rel.Max.x >= window_rect_rel.Max.x) + { + window->ScrollTarget.x = item_rect_rel.Max.x + window->Scroll.x + g.Style.ItemSpacing.x; + window->ScrollTargetCenterRatio.x = 1.0f; + } + if (item_rect_rel.Min.y < window_rect_rel.Min.y) + { + window->ScrollTarget.y = item_rect_rel.Min.y + window->Scroll.y - g.Style.ItemSpacing.y; + window->ScrollTargetCenterRatio.y = 0.0f; + } + else if (item_rect_rel.Max.y >= window_rect_rel.Max.y) + { + window->ScrollTarget.y = item_rect_rel.Max.y + window->Scroll.y + g.Style.ItemSpacing.y; + window->ScrollTargetCenterRatio.y = 1.0f; + } - // Estimate upcoming scroll so we can offset our relative mouse position so mouse position can be applied immediately (under this block) - ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window); - item_rect_rel.Translate(window->Scroll - next_scroll); + // Estimate upcoming scroll so we can offset our relative mouse position so mouse position can be applied immediately (under this block) + ImVec2 next_scroll = CalcNextScrollFromScrollTargetAndClamp(window); + item_rect_rel.Translate(window->Scroll - next_scroll); } static void ImGui::NavUpdate() { - ImGuiContext& g = *GImGui; - g.IO.WantMoveMouse = false; + ImGuiContext& g = *GImGui; + g.IO.WantMoveMouse = false; #if 0 if (g.NavScoringCount > 0) printf("[%05d] NavScoringCount %d for '%s' layer %d (Init:%d, Move:%d)\n", g.FrameCount, g.NavScoringCount, g.NavWindow ? g.NavWindow->Name : "NULL", g.NavLayer, g.NavInitRequest || g.NavInitResultId != 0, g.NavMoveRequest); #endif - // Update Keyboard->Nav inputs mapping - memset(g.IO.NavInputs + ImGuiNavInput_InternalStart_, 0, (ImGuiNavInput_COUNT - ImGuiNavInput_InternalStart_) * sizeof(g.IO.NavInputs[0])); - if (g.IO.NavFlags & ImGuiNavFlags_EnableKeyboard) - { - #define NAV_MAP_KEY(_KEY, _NAV_INPUT) if (g.IO.KeyMap[_KEY] != -1 && IsKeyDown(g.IO.KeyMap[_KEY])) g.IO.NavInputs[_NAV_INPUT] = 1.0f; - NAV_MAP_KEY(ImGuiKey_Space, ImGuiNavInput_Activate ); - NAV_MAP_KEY(ImGuiKey_Enter, ImGuiNavInput_Input ); - NAV_MAP_KEY(ImGuiKey_Escape, ImGuiNavInput_Cancel ); - NAV_MAP_KEY(ImGuiKey_LeftArrow, ImGuiNavInput_KeyLeft_ ); - NAV_MAP_KEY(ImGuiKey_RightArrow,ImGuiNavInput_KeyRight_); - NAV_MAP_KEY(ImGuiKey_UpArrow, ImGuiNavInput_KeyUp_ ); - NAV_MAP_KEY(ImGuiKey_DownArrow, ImGuiNavInput_KeyDown_ ); - if (g.IO.KeyCtrl) g.IO.NavInputs[ImGuiNavInput_TweakSlow] = 1.0f; - if (g.IO.KeyShift) g.IO.NavInputs[ImGuiNavInput_TweakFast] = 1.0f; - if (g.IO.KeyAlt) g.IO.NavInputs[ImGuiNavInput_KeyMenu_] = 1.0f; + // Update Keyboard->Nav inputs mapping + memset(g.IO.NavInputs + ImGuiNavInput_InternalStart_, 0, (ImGuiNavInput_COUNT - ImGuiNavInput_InternalStart_) * sizeof(g.IO.NavInputs[0])); + if (g.IO.NavFlags & ImGuiNavFlags_EnableKeyboard) + { +#define NAV_MAP_KEY(_KEY, _NAV_INPUT) \ + if (g.IO.KeyMap[_KEY] != -1 && IsKeyDown(g.IO.KeyMap[_KEY])) g.IO.NavInputs[_NAV_INPUT] = 1.0f; + NAV_MAP_KEY(ImGuiKey_Space, ImGuiNavInput_Activate); + NAV_MAP_KEY(ImGuiKey_Enter, ImGuiNavInput_Input); + NAV_MAP_KEY(ImGuiKey_Escape, ImGuiNavInput_Cancel); + NAV_MAP_KEY(ImGuiKey_LeftArrow, ImGuiNavInput_KeyLeft_); + NAV_MAP_KEY(ImGuiKey_RightArrow, ImGuiNavInput_KeyRight_); + NAV_MAP_KEY(ImGuiKey_UpArrow, ImGuiNavInput_KeyUp_); + NAV_MAP_KEY(ImGuiKey_DownArrow, ImGuiNavInput_KeyDown_); + if (g.IO.KeyCtrl) g.IO.NavInputs[ImGuiNavInput_TweakSlow] = 1.0f; + if (g.IO.KeyShift) g.IO.NavInputs[ImGuiNavInput_TweakFast] = 1.0f; + if (g.IO.KeyAlt) g.IO.NavInputs[ImGuiNavInput_KeyMenu_] = 1.0f; #undef NAV_MAP_KEY - } + } - memcpy(g.IO.NavInputsDownDurationPrev, g.IO.NavInputsDownDuration, sizeof(g.IO.NavInputsDownDuration)); - for (int i = 0; i < IM_ARRAYSIZE(g.IO.NavInputs); i++) - g.IO.NavInputsDownDuration[i] = (g.IO.NavInputs[i] > 0.0f) ? (g.IO.NavInputsDownDuration[i] < 0.0f ? 0.0f : g.IO.NavInputsDownDuration[i] + g.IO.DeltaTime) : -1.0f; + memcpy(g.IO.NavInputsDownDurationPrev, g.IO.NavInputsDownDuration, sizeof(g.IO.NavInputsDownDuration)); + for (int i = 0; i < IM_ARRAYSIZE(g.IO.NavInputs); i++) + g.IO.NavInputsDownDuration[i] = (g.IO.NavInputs[i] > 0.0f) ? (g.IO.NavInputsDownDuration[i] < 0.0f ? 0.0f : g.IO.NavInputsDownDuration[i] + g.IO.DeltaTime) : -1.0f; - // Process navigation init request (select first/default focus) - if (g.NavInitResultId != 0 && (!g.NavDisableHighlight || g.NavInitRequestFromMove)) - { - // Apply result from previous navigation init request (will typically select the first item, unless SetItemDefaultFocus() has been called) - IM_ASSERT(g.NavWindow); - if (g.NavInitRequestFromMove) - SetNavIDAndMoveMouse(g.NavInitResultId, g.NavLayer, g.NavInitResultRectRel); - else - SetNavID(g.NavInitResultId, g.NavLayer); - g.NavWindow->NavRectRel[g.NavLayer] = g.NavInitResultRectRel; - } - g.NavInitRequest = false; - g.NavInitRequestFromMove = false; - g.NavInitResultId = 0; - g.NavJustMovedToId = 0; + // Process navigation init request (select first/default focus) + if (g.NavInitResultId != 0 && (!g.NavDisableHighlight || g.NavInitRequestFromMove)) + { + // Apply result from previous navigation init request (will typically select the first item, unless SetItemDefaultFocus() has been called) + IM_ASSERT(g.NavWindow); + if (g.NavInitRequestFromMove) + SetNavIDAndMoveMouse(g.NavInitResultId, g.NavLayer, g.NavInitResultRectRel); + else + SetNavID(g.NavInitResultId, g.NavLayer); + g.NavWindow->NavRectRel[g.NavLayer] = g.NavInitResultRectRel; + } + g.NavInitRequest = false; + g.NavInitRequestFromMove = false; + g.NavInitResultId = 0; + g.NavJustMovedToId = 0; - // Process navigation move request - if (g.NavMoveRequest && (g.NavMoveResultLocal.ID != 0 || g.NavMoveResultOther.ID != 0)) - { - // Select which result to use - ImGuiNavMoveResult* result = (g.NavMoveResultLocal.ID != 0) ? &g.NavMoveResultLocal : &g.NavMoveResultOther; - if (g.NavMoveResultOther.ID != 0 && g.NavMoveResultOther.Window->ParentWindow == g.NavWindow) // Maybe entering a flattened child? In this case solve the tie using the regular scoring rules - if ((g.NavMoveResultOther.DistBox < g.NavMoveResultLocal.DistBox) || (g.NavMoveResultOther.DistBox == g.NavMoveResultLocal.DistBox && g.NavMoveResultOther.DistCenter < g.NavMoveResultLocal.DistCenter)) - result = &g.NavMoveResultOther; + // Process navigation move request + if (g.NavMoveRequest && (g.NavMoveResultLocal.ID != 0 || g.NavMoveResultOther.ID != 0)) + { + // Select which result to use + ImGuiNavMoveResult* result = (g.NavMoveResultLocal.ID != 0) ? &g.NavMoveResultLocal : &g.NavMoveResultOther; + if (g.NavMoveResultOther.ID != 0 && g.NavMoveResultOther.Window->ParentWindow == g.NavWindow) // Maybe entering a flattened child? In this case solve the tie using the regular scoring rules + if ((g.NavMoveResultOther.DistBox < g.NavMoveResultLocal.DistBox) || (g.NavMoveResultOther.DistBox == g.NavMoveResultLocal.DistBox && g.NavMoveResultOther.DistCenter < g.NavMoveResultLocal.DistCenter)) + result = &g.NavMoveResultOther; - IM_ASSERT(g.NavWindow && result->Window); + IM_ASSERT(g.NavWindow && result->Window); - // Scroll to keep newly navigated item fully into view - if (g.NavLayer == 0) - NavScrollToBringItemIntoView(result->Window, result->RectRel); + // Scroll to keep newly navigated item fully into view + if (g.NavLayer == 0) + NavScrollToBringItemIntoView(result->Window, result->RectRel); - // Apply result from previous frame navigation directional move request - ClearActiveID(); - g.NavWindow = result->Window; - SetNavIDAndMoveMouse(result->ID, g.NavLayer, result->RectRel); - g.NavJustMovedToId = result->ID; - g.NavMoveFromClampedRefRect = false; - } + // Apply result from previous frame navigation directional move request + ClearActiveID(); + g.NavWindow = result->Window; + SetNavIDAndMoveMouse(result->ID, g.NavLayer, result->RectRel); + g.NavJustMovedToId = result->ID; + g.NavMoveFromClampedRefRect = false; + } - // When a forwarded move request failed, we restore the highlight that we disabled during the forward frame - if (g.NavMoveRequestForward == ImGuiNavForward_ForwardActive) - { - IM_ASSERT(g.NavMoveRequest); - if (g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0) - g.NavDisableHighlight = false; - g.NavMoveRequestForward = ImGuiNavForward_None; - } + // When a forwarded move request failed, we restore the highlight that we disabled during the forward frame + if (g.NavMoveRequestForward == ImGuiNavForward_ForwardActive) + { + IM_ASSERT(g.NavMoveRequest); + if (g.NavMoveResultLocal.ID == 0 && g.NavMoveResultOther.ID == 0) + g.NavDisableHighlight = false; + g.NavMoveRequestForward = ImGuiNavForward_None; + } - // Apply application mouse position movement, after we had a chance to process move request result. - if (g.NavMousePosDirty && g.NavIdIsAlive) - { - // Set mouse position given our knowledge of the nav widget position from last frame - if (g.IO.NavFlags & ImGuiNavFlags_MoveMouse) - { - g.IO.MousePos = g.IO.MousePosPrev = NavCalcPreferredMousePos(); - g.IO.WantMoveMouse = true; - } - g.NavMousePosDirty = false; - } - g.NavIdIsAlive = false; - g.NavJustTabbedId = 0; - IM_ASSERT(g.NavLayer == 0 || g.NavLayer == 1); + // Apply application mouse position movement, after we had a chance to process move request result. + if (g.NavMousePosDirty && g.NavIdIsAlive) + { + // Set mouse position given our knowledge of the nav widget position from last frame + if (g.IO.NavFlags & ImGuiNavFlags_MoveMouse) + { + g.IO.MousePos = g.IO.MousePosPrev = NavCalcPreferredMousePos(); + g.IO.WantMoveMouse = true; + } + g.NavMousePosDirty = false; + } + g.NavIdIsAlive = false; + g.NavJustTabbedId = 0; + IM_ASSERT(g.NavLayer == 0 || g.NavLayer == 1); - // Store our return window (for returning from Layer 1 to Layer 0) and clear it as soon as we step back in our own Layer 0 - if (g.NavWindow) - NavSaveLastChildNavWindow(g.NavWindow); - if (g.NavWindow && g.NavWindow->NavLastChildNavWindow != NULL && g.NavLayer == 0) - g.NavWindow->NavLastChildNavWindow = NULL; + // Store our return window (for returning from Layer 1 to Layer 0) and clear it as soon as we step back in our own Layer 0 + if (g.NavWindow) + NavSaveLastChildNavWindow(g.NavWindow); + if (g.NavWindow && g.NavWindow->NavLastChildNavWindow != NULL && g.NavLayer == 0) + g.NavWindow->NavLastChildNavWindow = NULL; - NavUpdateWindowing(); + NavUpdateWindowing(); - // Set output flags for user application - g.IO.NavActive = (g.IO.NavFlags & (ImGuiNavFlags_EnableGamepad | ImGuiNavFlags_EnableKeyboard)) && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs); - g.IO.NavVisible = (g.IO.NavActive && g.NavId != 0 && !g.NavDisableHighlight) || (g.NavWindowingTarget != NULL) || g.NavInitRequest; + // Set output flags for user application + g.IO.NavActive = (g.IO.NavFlags & (ImGuiNavFlags_EnableGamepad | ImGuiNavFlags_EnableKeyboard)) && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs); + g.IO.NavVisible = (g.IO.NavActive && g.NavId != 0 && !g.NavDisableHighlight) || (g.NavWindowingTarget != NULL) || g.NavInitRequest; - // Process NavCancel input (to close a popup, get back to parent, clear focus) - if (IsNavInputPressed(ImGuiNavInput_Cancel, ImGuiInputReadMode_Pressed)) - { - if (g.ActiveId != 0) - { - ClearActiveID(); - } - else if (g.NavWindow && (g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow) && !(g.NavWindow->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->ParentWindow) - { - // Exit child window - ImGuiWindow* child_window = g.NavWindow; - ImGuiWindow* parent_window = g.NavWindow->ParentWindow; - IM_ASSERT(child_window->ChildId != 0); - FocusWindow(parent_window); - SetNavID(child_window->ChildId, 0); - g.NavIdIsAlive = false; - if (g.NavDisableMouseHover) - g.NavMousePosDirty = true; - } - else if (g.OpenPopupStack.Size > 0) - { - // Close open popup/menu - if (!(g.OpenPopupStack.back().Window->Flags & ImGuiWindowFlags_Modal)) - ClosePopupToLevel(g.OpenPopupStack.Size - 1); - } - else if (g.NavLayer != 0) - { - // Leave the "menu" layer - NavRestoreLayer(0); - } - else - { - // Clear NavLastId for popups but keep it for regular child window so we can leave one and come back where we were - if (g.NavWindow && ((g.NavWindow->Flags & ImGuiWindowFlags_Popup) || !(g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow))) - g.NavWindow->NavLastIds[0] = 0; - g.NavId = 0; - } - } + // Process NavCancel input (to close a popup, get back to parent, clear focus) + if (IsNavInputPressed(ImGuiNavInput_Cancel, ImGuiInputReadMode_Pressed)) + { + if (g.ActiveId != 0) + { + ClearActiveID(); + } + else if (g.NavWindow && (g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow) && !(g.NavWindow->Flags & ImGuiWindowFlags_Popup) && g.NavWindow->ParentWindow) + { + // Exit child window + ImGuiWindow* child_window = g.NavWindow; + ImGuiWindow* parent_window = g.NavWindow->ParentWindow; + IM_ASSERT(child_window->ChildId != 0); + FocusWindow(parent_window); + SetNavID(child_window->ChildId, 0); + g.NavIdIsAlive = false; + if (g.NavDisableMouseHover) + g.NavMousePosDirty = true; + } + else if (g.OpenPopupStack.Size > 0) + { + // Close open popup/menu + if (!(g.OpenPopupStack.back().Window->Flags & ImGuiWindowFlags_Modal)) + ClosePopupToLevel(g.OpenPopupStack.Size - 1); + } + else if (g.NavLayer != 0) + { + // Leave the "menu" layer + NavRestoreLayer(0); + } + else + { + // Clear NavLastId for popups but keep it for regular child window so we can leave one and come back where we were + if (g.NavWindow && ((g.NavWindow->Flags & ImGuiWindowFlags_Popup) || !(g.NavWindow->Flags & ImGuiWindowFlags_ChildWindow))) + g.NavWindow->NavLastIds[0] = 0; + g.NavId = 0; + } + } - // Process manual activation request - g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = 0; - if (g.NavId != 0 && !g.NavDisableHighlight && !g.NavWindowingTarget && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs)) - { - bool activate_down = IsNavInputDown(ImGuiNavInput_Activate); - bool activate_pressed = activate_down && IsNavInputPressed(ImGuiNavInput_Activate, ImGuiInputReadMode_Pressed); - if (g.ActiveId == 0 && activate_pressed) - g.NavActivateId = g.NavId; - if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && activate_down) - g.NavActivateDownId = g.NavId; - if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && activate_pressed) - g.NavActivatePressedId = g.NavId; - if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && IsNavInputPressed(ImGuiNavInput_Input, ImGuiInputReadMode_Pressed)) - g.NavInputId = g.NavId; - } - if (g.NavWindow && (g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs)) - g.NavDisableHighlight = true; - if (g.NavActivateId != 0) - IM_ASSERT(g.NavActivateDownId == g.NavActivateId); - g.NavMoveRequest = false; + // Process manual activation request + g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = 0; + if (g.NavId != 0 && !g.NavDisableHighlight && !g.NavWindowingTarget && g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs)) + { + bool activate_down = IsNavInputDown(ImGuiNavInput_Activate); + bool activate_pressed = activate_down && IsNavInputPressed(ImGuiNavInput_Activate, ImGuiInputReadMode_Pressed); + if (g.ActiveId == 0 && activate_pressed) + g.NavActivateId = g.NavId; + if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && activate_down) + g.NavActivateDownId = g.NavId; + if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && activate_pressed) + g.NavActivatePressedId = g.NavId; + if ((g.ActiveId == 0 || g.ActiveId == g.NavId) && IsNavInputPressed(ImGuiNavInput_Input, ImGuiInputReadMode_Pressed)) + g.NavInputId = g.NavId; + } + if (g.NavWindow && (g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs)) + g.NavDisableHighlight = true; + if (g.NavActivateId != 0) + IM_ASSERT(g.NavActivateDownId == g.NavActivateId); + g.NavMoveRequest = false; - // Process programmatic activation request - if (g.NavNextActivateId != 0) - g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = g.NavNextActivateId; - g.NavNextActivateId = 0; + // Process programmatic activation request + if (g.NavNextActivateId != 0) + g.NavActivateId = g.NavActivateDownId = g.NavActivatePressedId = g.NavInputId = g.NavNextActivateId; + g.NavNextActivateId = 0; - // Initiate directional inputs request - const int allowed_dir_flags = (g.ActiveId == 0) ? ~0 : g.ActiveIdAllowNavDirFlags; - if (g.NavMoveRequestForward == ImGuiNavForward_None) - { - g.NavMoveDir = ImGuiDir_None; - if (g.NavWindow && !g.NavWindowingTarget && allowed_dir_flags && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs)) - { - if ((allowed_dir_flags & (1<Flags & ImGuiWindowFlags_NoNavInputs)) + { + if ((allowed_dir_flags & (1 << ImGuiDir_Left)) && IsNavInputPressedAnyOfTwo(ImGuiNavInput_DpadLeft, ImGuiNavInput_KeyLeft_, ImGuiInputReadMode_Repeat)) g.NavMoveDir = ImGuiDir_Left; + if ((allowed_dir_flags & (1 << ImGuiDir_Right)) && IsNavInputPressedAnyOfTwo(ImGuiNavInput_DpadRight, ImGuiNavInput_KeyRight_, ImGuiInputReadMode_Repeat)) g.NavMoveDir = ImGuiDir_Right; + if ((allowed_dir_flags & (1 << ImGuiDir_Up)) && IsNavInputPressedAnyOfTwo(ImGuiNavInput_DpadUp, ImGuiNavInput_KeyUp_, ImGuiInputReadMode_Repeat)) g.NavMoveDir = ImGuiDir_Up; + if ((allowed_dir_flags & (1 << ImGuiDir_Down)) && IsNavInputPressedAnyOfTwo(ImGuiNavInput_DpadDown, ImGuiNavInput_KeyDown_, ImGuiInputReadMode_Repeat)) g.NavMoveDir = ImGuiDir_Down; + } + } + else + { + // Forwarding previous request (which has been modified, e.g. wrap around menus rewrite the requests with a starting rectangle at the other side of the window) + IM_ASSERT(g.NavMoveDir != ImGuiDir_None); + IM_ASSERT(g.NavMoveRequestForward == ImGuiNavForward_ForwardQueued); + g.NavMoveRequestForward = ImGuiNavForward_ForwardActive; + } - if (g.NavMoveDir != ImGuiDir_None) - { - g.NavMoveRequest = true; - g.NavMoveDirLast = g.NavMoveDir; - } + if (g.NavMoveDir != ImGuiDir_None) + { + g.NavMoveRequest = true; + g.NavMoveDirLast = g.NavMoveDir; + } - // If we initiate a movement request and have no current NavId, we initiate a InitDefautRequest that will be used as a fallback if the direction fails to find a match - if (g.NavMoveRequest && g.NavId == 0) - { - g.NavInitRequest = g.NavInitRequestFromMove = true; - g.NavInitResultId = 0; - g.NavDisableHighlight = false; - } + // If we initiate a movement request and have no current NavId, we initiate a InitDefautRequest that will be used as a fallback if the direction fails to find a match + if (g.NavMoveRequest && g.NavId == 0) + { + g.NavInitRequest = g.NavInitRequestFromMove = true; + g.NavInitResultId = 0; + g.NavDisableHighlight = false; + } - NavUpdateAnyRequestFlag(); + NavUpdateAnyRequestFlag(); - // Scrolling - if (g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.NavWindowingTarget) - { - // *Fallback* manual-scroll with NavUp/NavDown when window has no navigable item - ImGuiWindow* window = g.NavWindow; - const float scroll_speed = ImFloor(window->CalcFontSize() * 100 * g.IO.DeltaTime + 0.5f); // We need round the scrolling speed because sub-pixel scroll isn't reliably supported. - if (window->DC.NavLayerActiveMask == 0x00 && window->DC.NavHasScroll && g.NavMoveRequest) - { - if (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right) - SetWindowScrollX(window, ImFloor(window->Scroll.x + ((g.NavMoveDir == ImGuiDir_Left) ? -1.0f : +1.0f) * scroll_speed)); - if (g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down) - SetWindowScrollY(window, ImFloor(window->Scroll.y + ((g.NavMoveDir == ImGuiDir_Up) ? -1.0f : +1.0f) * scroll_speed)); - } + // Scrolling + if (g.NavWindow && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.NavWindowingTarget) + { + // *Fallback* manual-scroll with NavUp/NavDown when window has no navigable item + ImGuiWindow* window = g.NavWindow; + const float scroll_speed = ImFloor(window->CalcFontSize() * 100 * g.IO.DeltaTime + 0.5f); // We need round the scrolling speed because sub-pixel scroll isn't reliably supported. + if (window->DC.NavLayerActiveMask == 0x00 && window->DC.NavHasScroll && g.NavMoveRequest) + { + if (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right) + SetWindowScrollX(window, ImFloor(window->Scroll.x + ((g.NavMoveDir == ImGuiDir_Left) ? -1.0f : +1.0f) * scroll_speed)); + if (g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down) + SetWindowScrollY(window, ImFloor(window->Scroll.y + ((g.NavMoveDir == ImGuiDir_Up) ? -1.0f : +1.0f) * scroll_speed)); + } - // *Normal* Manual scroll with NavScrollXXX keys - // Next movement request will clamp the NavId reference rectangle to the visible area, so navigation will resume within those bounds. - ImVec2 scroll_dir = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadLStick, ImGuiInputReadMode_Down, 1.0f/10.0f, 10.0f); - if (scroll_dir.x != 0.0f && window->ScrollbarX) - { - SetWindowScrollX(window, ImFloor(window->Scroll.x + scroll_dir.x * scroll_speed)); - g.NavMoveFromClampedRefRect = true; - } - if (scroll_dir.y != 0.0f) - { - SetWindowScrollY(window, ImFloor(window->Scroll.y + scroll_dir.y * scroll_speed)); - g.NavMoveFromClampedRefRect = true; - } - } + // *Normal* Manual scroll with NavScrollXXX keys + // Next movement request will clamp the NavId reference rectangle to the visible area, so navigation will resume within those bounds. + ImVec2 scroll_dir = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadLStick, ImGuiInputReadMode_Down, 1.0f / 10.0f, 10.0f); + if (scroll_dir.x != 0.0f && window->ScrollbarX) + { + SetWindowScrollX(window, ImFloor(window->Scroll.x + scroll_dir.x * scroll_speed)); + g.NavMoveFromClampedRefRect = true; + } + if (scroll_dir.y != 0.0f) + { + SetWindowScrollY(window, ImFloor(window->Scroll.y + scroll_dir.y * scroll_speed)); + g.NavMoveFromClampedRefRect = true; + } + } - // Reset search results - g.NavMoveResultLocal.Clear(); - g.NavMoveResultOther.Clear(); + // Reset search results + g.NavMoveResultLocal.Clear(); + g.NavMoveResultOther.Clear(); - // When we have manually scrolled (without using navigation) and NavId becomes out of bounds, we project its bounding box to the visible area to restart navigation within visible items - if (g.NavMoveRequest && g.NavMoveFromClampedRefRect && g.NavLayer == 0) - { - ImGuiWindow* window = g.NavWindow; - ImRect window_rect_rel(window->InnerRect.Min - window->Pos - ImVec2(1,1), window->InnerRect.Max - window->Pos + ImVec2(1,1)); - if (!window_rect_rel.Contains(window->NavRectRel[g.NavLayer])) - { - float pad = window->CalcFontSize() * 0.5f; - window_rect_rel.Expand(ImVec2(-ImMin(window_rect_rel.GetWidth(), pad), -ImMin(window_rect_rel.GetHeight(), pad))); // Terrible approximation for the intent of starting navigation from first fully visible item - window->NavRectRel[g.NavLayer].ClipWith(window_rect_rel); - g.NavId = 0; - } - g.NavMoveFromClampedRefRect = false; - } + // When we have manually scrolled (without using navigation) and NavId becomes out of bounds, we project its bounding box to the visible area to restart navigation within visible items + if (g.NavMoveRequest && g.NavMoveFromClampedRefRect && g.NavLayer == 0) + { + ImGuiWindow* window = g.NavWindow; + ImRect window_rect_rel(window->InnerRect.Min - window->Pos - ImVec2(1, 1), window->InnerRect.Max - window->Pos + ImVec2(1, 1)); + if (!window_rect_rel.Contains(window->NavRectRel[g.NavLayer])) + { + float pad = window->CalcFontSize() * 0.5f; + window_rect_rel.Expand(ImVec2(-ImMin(window_rect_rel.GetWidth(), pad), -ImMin(window_rect_rel.GetHeight(), pad))); // Terrible approximation for the intent of starting navigation from first fully visible item + window->NavRectRel[g.NavLayer].ClipWith(window_rect_rel); + g.NavId = 0; + } + g.NavMoveFromClampedRefRect = false; + } - // For scoring we use a single segment on the left side our current item bounding box (not touching the edge to avoid box overlap with zero-spaced items) - ImRect nav_rect_rel = (g.NavWindow && g.NavWindow->NavRectRel[g.NavLayer].IsFinite()) ? g.NavWindow->NavRectRel[g.NavLayer] : ImRect(0,0,0,0); - g.NavScoringRectScreen = g.NavWindow ? ImRect(g.NavWindow->Pos + nav_rect_rel.Min, g.NavWindow->Pos + nav_rect_rel.Max) : GetViewportRect(); - g.NavScoringRectScreen.Min.x = ImMin(g.NavScoringRectScreen.Min.x + 1.0f, g.NavScoringRectScreen.Max.x); - g.NavScoringRectScreen.Max.x = g.NavScoringRectScreen.Min.x; - IM_ASSERT(!g.NavScoringRectScreen.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allows us to remove extraneous fabsf() calls in NavScoreItem(). - //g.OverlayDrawList.AddRect(g.NavScoringRectScreen.Min, g.NavScoringRectScreen.Max, IM_COL32(255,200,0,255)); // [DEBUG] - g.NavScoringCount = 0; + // For scoring we use a single segment on the left side our current item bounding box (not touching the edge to avoid box overlap with zero-spaced items) + ImRect nav_rect_rel = (g.NavWindow && g.NavWindow->NavRectRel[g.NavLayer].IsFinite()) ? g.NavWindow->NavRectRel[g.NavLayer] : ImRect(0, 0, 0, 0); + g.NavScoringRectScreen = g.NavWindow ? ImRect(g.NavWindow->Pos + nav_rect_rel.Min, g.NavWindow->Pos + nav_rect_rel.Max) : GetViewportRect(); + g.NavScoringRectScreen.Min.x = ImMin(g.NavScoringRectScreen.Min.x + 1.0f, g.NavScoringRectScreen.Max.x); + g.NavScoringRectScreen.Max.x = g.NavScoringRectScreen.Min.x; + IM_ASSERT(!g.NavScoringRectScreen.IsInverted()); // Ensure if we have a finite, non-inverted bounding box here will allows us to remove extraneous fabsf() calls in NavScoreItem(). + //g.OverlayDrawList.AddRect(g.NavScoringRectScreen.Min, g.NavScoringRectScreen.Max, IM_COL32(255,200,0,255)); // [DEBUG] + g.NavScoringCount = 0; #if IMGUI_DEBUG_NAV_RECTS - if (g.NavWindow) { for (int layer = 0; layer < 2; layer++) g.OverlayDrawList.AddRect(g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Min, g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Max, IM_COL32(255,200,0,255)); } // [DEBUG] - if (g.NavWindow) { ImU32 col = (g.NavWindow->HiddenFrames <= 0) ? IM_COL32(255,0,255,255) : IM_COL32(255,0,0,255); ImVec2 p = NavCalcPreferredMousePos(); char buf[32]; ImFormatString(buf, 32, "%d", g.NavLayer); g.OverlayDrawList.AddCircleFilled(p, 3.0f, col); g.OverlayDrawList.AddText(NULL, 13.0f, p + ImVec2(8,-4), col, buf); } + if (g.NavWindow) + { + for (int layer = 0; layer < 2; layer++) g.OverlayDrawList.AddRect(g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Min, g.NavWindow->Pos + g.NavWindow->NavRectRel[layer].Max, IM_COL32(255, 200, 0, 255)); + } // [DEBUG] + if (g.NavWindow) + { + ImU32 col = (g.NavWindow->HiddenFrames <= 0) ? IM_COL32(255, 0, 255, 255) : IM_COL32(255, 0, 0, 255); + ImVec2 p = NavCalcPreferredMousePos(); + char buf[32]; + ImFormatString(buf, 32, "%d", g.NavLayer); + g.OverlayDrawList.AddCircleFilled(p, 3.0f, col); + g.OverlayDrawList.AddText(NULL, 13.0f, p + ImVec2(8, -4), col, buf); + } #endif } static void ImGui::UpdateMovingWindow() { - ImGuiContext& g = *GImGui; - if (g.MovingWindow && g.MovingWindow->MoveId == g.ActiveId && g.ActiveIdSource == ImGuiInputSource_Mouse) - { - // We actually want to move the root window. g.MovingWindow == window we clicked on (could be a child window). - // We track it to preserve Focus and so that ActiveIdWindow == MovingWindow and ActiveId == MovingWindow->MoveId for consistency. - KeepAliveID(g.ActiveId); - IM_ASSERT(g.MovingWindow && g.MovingWindow->RootWindow); - ImGuiWindow* moving_window = g.MovingWindow->RootWindow; - if (g.IO.MouseDown[0]) - { - ImVec2 pos = g.IO.MousePos - g.ActiveIdClickOffset; - if (moving_window->PosFloat.x != pos.x || moving_window->PosFloat.y != pos.y) - { - MarkIniSettingsDirty(moving_window); - moving_window->PosFloat = pos; - } - FocusWindow(g.MovingWindow); - } - else - { - ClearActiveID(); - g.MovingWindow = NULL; - } - } - else - { - // When clicking/dragging from a window that has the _NoMove flag, we still set the ActiveId in order to prevent hovering others. - if (g.ActiveIdWindow && g.ActiveIdWindow->MoveId == g.ActiveId) - { - KeepAliveID(g.ActiveId); - if (!g.IO.MouseDown[0]) - ClearActiveID(); - } - g.MovingWindow = NULL; - } + ImGuiContext& g = *GImGui; + if (g.MovingWindow && g.MovingWindow->MoveId == g.ActiveId && g.ActiveIdSource == ImGuiInputSource_Mouse) + { + // We actually want to move the root window. g.MovingWindow == window we clicked on (could be a child window). + // We track it to preserve Focus and so that ActiveIdWindow == MovingWindow and ActiveId == MovingWindow->MoveId for consistency. + KeepAliveID(g.ActiveId); + IM_ASSERT(g.MovingWindow && g.MovingWindow->RootWindow); + ImGuiWindow* moving_window = g.MovingWindow->RootWindow; + if (g.IO.MouseDown[0]) + { + ImVec2 pos = g.IO.MousePos - g.ActiveIdClickOffset; + if (moving_window->PosFloat.x != pos.x || moving_window->PosFloat.y != pos.y) + { + MarkIniSettingsDirty(moving_window); + moving_window->PosFloat = pos; + } + FocusWindow(g.MovingWindow); + } + else + { + ClearActiveID(); + g.MovingWindow = NULL; + } + } + else + { + // When clicking/dragging from a window that has the _NoMove flag, we still set the ActiveId in order to prevent hovering others. + if (g.ActiveIdWindow && g.ActiveIdWindow->MoveId == g.ActiveId) + { + KeepAliveID(g.ActiveId); + if (!g.IO.MouseDown[0]) + ClearActiveID(); + } + g.MovingWindow = NULL; + } } void ImGui::NewFrame() { - IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() or ImGui::SetCurrentContext()?"); - ImGuiContext& g = *GImGui; + IM_ASSERT(GImGui != NULL && "No current context. Did you call ImGui::CreateContext() or ImGui::SetCurrentContext()?"); + ImGuiContext& g = *GImGui; - // Check user data - // (We pass an error message in the assert expression as a trick to get it visible to programmers who are not using a debugger, as most assert handlers display their argument) - IM_ASSERT(g.Initialized); - IM_ASSERT(g.IO.DeltaTime >= 0.0f && "Need a positive DeltaTime (zero is tolerated but will cause some timing issues)"); - IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f && "Invalid DisplaySize value"); - IM_ASSERT(g.IO.Fonts->Fonts.Size > 0 && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8() ?"); - IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded() && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8() ?"); - IM_ASSERT(g.Style.CurveTessellationTol > 0.0f && "Invalid style setting"); - IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f && "Invalid style setting. Alpha cannot be negative (allows us to avoid a few clamps in color computations)"); - IM_ASSERT((g.FrameCount == 0 || g.FrameCountEnded == g.FrameCount) && "Forgot to call Render() or EndFrame() at the end of the previous frame?"); - for (int n = 0; n < ImGuiKey_COUNT; n++) - IM_ASSERT(g.IO.KeyMap[n] >= -1 && g.IO.KeyMap[n] < IM_ARRAYSIZE(g.IO.KeysDown) && "io.KeyMap[] contains an out of bound value (need to be 0..512, or -1 for unmapped key)"); + // Check user data + // (We pass an error message in the assert expression as a trick to get it visible to programmers who are not using a debugger, as most assert handlers display their argument) + IM_ASSERT(g.Initialized); + IM_ASSERT(g.IO.DeltaTime >= 0.0f && "Need a positive DeltaTime (zero is tolerated but will cause some timing issues)"); + IM_ASSERT(g.IO.DisplaySize.x >= 0.0f && g.IO.DisplaySize.y >= 0.0f && "Invalid DisplaySize value"); + IM_ASSERT(g.IO.Fonts->Fonts.Size > 0 && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8() ?"); + IM_ASSERT(g.IO.Fonts->Fonts[0]->IsLoaded() && "Font Atlas not built. Did you call io.Fonts->GetTexDataAsRGBA32() / GetTexDataAsAlpha8() ?"); + IM_ASSERT(g.Style.CurveTessellationTol > 0.0f && "Invalid style setting"); + IM_ASSERT(g.Style.Alpha >= 0.0f && g.Style.Alpha <= 1.0f && "Invalid style setting. Alpha cannot be negative (allows us to avoid a few clamps in color computations)"); + IM_ASSERT((g.FrameCount == 0 || g.FrameCountEnded == g.FrameCount) && "Forgot to call Render() or EndFrame() at the end of the previous frame?"); + for (int n = 0; n < ImGuiKey_COUNT; n++) + IM_ASSERT(g.IO.KeyMap[n] >= -1 && g.IO.KeyMap[n] < IM_ARRAYSIZE(g.IO.KeysDown) && "io.KeyMap[] contains an out of bound value (need to be 0..512, or -1 for unmapped key)"); - // Do a simple check for required key mapping (we intentionally do NOT check all keys to not pressure user into setting up everything, but Space is required and was super recently added in 1.60 WIP) - if (g.IO.NavFlags & ImGuiNavFlags_EnableKeyboard) - IM_ASSERT(g.IO.KeyMap[ImGuiKey_Space] != -1 && "ImGuiKey_Space is not mapped, required for keyboard navigation."); + // Do a simple check for required key mapping (we intentionally do NOT check all keys to not pressure user into setting up everything, but Space is required and was super recently added in 1.60 WIP) + if (g.IO.NavFlags & ImGuiNavFlags_EnableKeyboard) + IM_ASSERT(g.IO.KeyMap[ImGuiKey_Space] != -1 && "ImGuiKey_Space is not mapped, required for keyboard navigation."); - // Load settings on first frame - if (!g.SettingsLoaded) - { - IM_ASSERT(g.SettingsWindows.empty()); - LoadIniSettingsFromDisk(g.IO.IniFilename); - g.SettingsLoaded = true; - } + // Load settings on first frame + if (!g.SettingsLoaded) + { + IM_ASSERT(g.SettingsWindows.empty()); + LoadIniSettingsFromDisk(g.IO.IniFilename); + g.SettingsLoaded = true; + } - g.Time += g.IO.DeltaTime; - g.FrameCount += 1; - g.TooltipOverrideCount = 0; - g.WindowsActiveCount = 0; + g.Time += g.IO.DeltaTime; + g.FrameCount += 1; + g.TooltipOverrideCount = 0; + g.WindowsActiveCount = 0; - SetCurrentFont(GetDefaultFont()); - IM_ASSERT(g.Font->IsLoaded()); - g.DrawListSharedData.ClipRectFullscreen = ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y); - g.DrawListSharedData.CurveTessellationTol = g.Style.CurveTessellationTol; + SetCurrentFont(GetDefaultFont()); + IM_ASSERT(g.Font->IsLoaded()); + g.DrawListSharedData.ClipRectFullscreen = ImVec4(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y); + g.DrawListSharedData.CurveTessellationTol = g.Style.CurveTessellationTol; - g.OverlayDrawList.Clear(); - g.OverlayDrawList.PushTextureID(g.IO.Fonts->TexID); - g.OverlayDrawList.PushClipRectFullScreen(); - g.OverlayDrawList.Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0); + g.OverlayDrawList.Clear(); + g.OverlayDrawList.PushTextureID(g.IO.Fonts->TexID); + g.OverlayDrawList.PushClipRectFullScreen(); + g.OverlayDrawList.Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0); - // Mark rendering data as invalid to prevent user who may have a handle on it to use it - g.DrawData.Clear(); + // Mark rendering data as invalid to prevent user who may have a handle on it to use it + g.DrawData.Clear(); - // Clear reference to active widget if the widget isn't alive anymore - if (!g.HoveredIdPreviousFrame) - g.HoveredIdTimer = 0.0f; - g.HoveredIdPreviousFrame = g.HoveredId; - g.HoveredId = 0; - g.HoveredIdAllowOverlap = false; - if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0) - ClearActiveID(); - if (g.ActiveId) - g.ActiveIdTimer += g.IO.DeltaTime; - g.ActiveIdPreviousFrame = g.ActiveId; - g.ActiveIdIsAlive = false; - g.ActiveIdIsJustActivated = false; - if (g.ScalarAsInputTextId && g.ActiveId != g.ScalarAsInputTextId) - g.ScalarAsInputTextId = 0; + // Clear reference to active widget if the widget isn't alive anymore + if (!g.HoveredIdPreviousFrame) + g.HoveredIdTimer = 0.0f; + g.HoveredIdPreviousFrame = g.HoveredId; + g.HoveredId = 0; + g.HoveredIdAllowOverlap = false; + if (!g.ActiveIdIsAlive && g.ActiveIdPreviousFrame == g.ActiveId && g.ActiveId != 0) + ClearActiveID(); + if (g.ActiveId) + g.ActiveIdTimer += g.IO.DeltaTime; + g.ActiveIdPreviousFrame = g.ActiveId; + g.ActiveIdIsAlive = false; + g.ActiveIdIsJustActivated = false; + if (g.ScalarAsInputTextId && g.ActiveId != g.ScalarAsInputTextId) + g.ScalarAsInputTextId = 0; - // Elapse drag & drop payload - if (g.DragDropActive && g.DragDropPayload.DataFrameCount + 1 < g.FrameCount) - { - ClearDragDrop(); - g.DragDropPayloadBufHeap.clear(); - memset(&g.DragDropPayloadBufLocal, 0, sizeof(g.DragDropPayloadBufLocal)); - } - g.DragDropAcceptIdPrev = g.DragDropAcceptIdCurr; - g.DragDropAcceptIdCurr = 0; - g.DragDropAcceptIdCurrRectSurface = FLT_MAX; + // Elapse drag & drop payload + if (g.DragDropActive && g.DragDropPayload.DataFrameCount + 1 < g.FrameCount) + { + ClearDragDrop(); + g.DragDropPayloadBufHeap.clear(); + memset(&g.DragDropPayloadBufLocal, 0, sizeof(g.DragDropPayloadBufLocal)); + } + g.DragDropAcceptIdPrev = g.DragDropAcceptIdCurr; + g.DragDropAcceptIdCurr = 0; + g.DragDropAcceptIdCurrRectSurface = FLT_MAX; - // Update keyboard input state - memcpy(g.IO.KeysDownDurationPrev, g.IO.KeysDownDuration, sizeof(g.IO.KeysDownDuration)); - for (int i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++) - g.IO.KeysDownDuration[i] = g.IO.KeysDown[i] ? (g.IO.KeysDownDuration[i] < 0.0f ? 0.0f : g.IO.KeysDownDuration[i] + g.IO.DeltaTime) : -1.0f; + // Update keyboard input state + memcpy(g.IO.KeysDownDurationPrev, g.IO.KeysDownDuration, sizeof(g.IO.KeysDownDuration)); + for (int i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++) + g.IO.KeysDownDuration[i] = g.IO.KeysDown[i] ? (g.IO.KeysDownDuration[i] < 0.0f ? 0.0f : g.IO.KeysDownDuration[i] + g.IO.DeltaTime) : -1.0f; - // Update gamepad/keyboard directional navigation - NavUpdate(); + // Update gamepad/keyboard directional navigation + NavUpdate(); - // Update mouse input state - // If mouse just appeared or disappeared (usually denoted by -FLT_MAX component, but in reality we test for -256000.0f) we cancel out movement in MouseDelta - if (IsMousePosValid(&g.IO.MousePos) && IsMousePosValid(&g.IO.MousePosPrev)) - g.IO.MouseDelta = g.IO.MousePos - g.IO.MousePosPrev; - else - g.IO.MouseDelta = ImVec2(0.0f, 0.0f); - if (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f) - g.NavDisableMouseHover = false; + // Update mouse input state + // If mouse just appeared or disappeared (usually denoted by -FLT_MAX component, but in reality we test for -256000.0f) we cancel out movement in MouseDelta + if (IsMousePosValid(&g.IO.MousePos) && IsMousePosValid(&g.IO.MousePosPrev)) + g.IO.MouseDelta = g.IO.MousePos - g.IO.MousePosPrev; + else + g.IO.MouseDelta = ImVec2(0.0f, 0.0f); + if (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f) + g.NavDisableMouseHover = false; - g.IO.MousePosPrev = g.IO.MousePos; - for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++) - { - g.IO.MouseClicked[i] = g.IO.MouseDown[i] && g.IO.MouseDownDuration[i] < 0.0f; - g.IO.MouseReleased[i] = !g.IO.MouseDown[i] && g.IO.MouseDownDuration[i] >= 0.0f; - g.IO.MouseDownDurationPrev[i] = g.IO.MouseDownDuration[i]; - g.IO.MouseDownDuration[i] = g.IO.MouseDown[i] ? (g.IO.MouseDownDuration[i] < 0.0f ? 0.0f : g.IO.MouseDownDuration[i] + g.IO.DeltaTime) : -1.0f; - g.IO.MouseDoubleClicked[i] = false; - if (g.IO.MouseClicked[i]) - { - if (g.Time - g.IO.MouseClickedTime[i] < g.IO.MouseDoubleClickTime) - { - if (ImLengthSqr(g.IO.MousePos - g.IO.MouseClickedPos[i]) < g.IO.MouseDoubleClickMaxDist * g.IO.MouseDoubleClickMaxDist) - g.IO.MouseDoubleClicked[i] = true; - g.IO.MouseClickedTime[i] = -FLT_MAX; // so the third click isn't turned into a double-click - } - else - { - g.IO.MouseClickedTime[i] = g.Time; - } - g.IO.MouseClickedPos[i] = g.IO.MousePos; - g.IO.MouseDragMaxDistanceAbs[i] = ImVec2(0.0f, 0.0f); - g.IO.MouseDragMaxDistanceSqr[i] = 0.0f; - } - else if (g.IO.MouseDown[i]) - { - ImVec2 mouse_delta = g.IO.MousePos - g.IO.MouseClickedPos[i]; - g.IO.MouseDragMaxDistanceAbs[i].x = ImMax(g.IO.MouseDragMaxDistanceAbs[i].x, mouse_delta.x < 0.0f ? -mouse_delta.x : mouse_delta.x); - g.IO.MouseDragMaxDistanceAbs[i].y = ImMax(g.IO.MouseDragMaxDistanceAbs[i].y, mouse_delta.y < 0.0f ? -mouse_delta.y : mouse_delta.y); - g.IO.MouseDragMaxDistanceSqr[i] = ImMax(g.IO.MouseDragMaxDistanceSqr[i], ImLengthSqr(mouse_delta)); - } - if (g.IO.MouseClicked[i]) // Clicking any mouse button reactivate mouse hovering which may have been deactivated by gamepad/keyboard navigation - g.NavDisableMouseHover = false; - } + g.IO.MousePosPrev = g.IO.MousePos; + for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++) + { + g.IO.MouseClicked[i] = g.IO.MouseDown[i] && g.IO.MouseDownDuration[i] < 0.0f; + g.IO.MouseReleased[i] = !g.IO.MouseDown[i] && g.IO.MouseDownDuration[i] >= 0.0f; + g.IO.MouseDownDurationPrev[i] = g.IO.MouseDownDuration[i]; + g.IO.MouseDownDuration[i] = g.IO.MouseDown[i] ? (g.IO.MouseDownDuration[i] < 0.0f ? 0.0f : g.IO.MouseDownDuration[i] + g.IO.DeltaTime) : -1.0f; + g.IO.MouseDoubleClicked[i] = false; + if (g.IO.MouseClicked[i]) + { + if (g.Time - g.IO.MouseClickedTime[i] < g.IO.MouseDoubleClickTime) + { + if (ImLengthSqr(g.IO.MousePos - g.IO.MouseClickedPos[i]) < g.IO.MouseDoubleClickMaxDist * g.IO.MouseDoubleClickMaxDist) + g.IO.MouseDoubleClicked[i] = true; + g.IO.MouseClickedTime[i] = -FLT_MAX; // so the third click isn't turned into a double-click + } + else + { + g.IO.MouseClickedTime[i] = g.Time; + } + g.IO.MouseClickedPos[i] = g.IO.MousePos; + g.IO.MouseDragMaxDistanceAbs[i] = ImVec2(0.0f, 0.0f); + g.IO.MouseDragMaxDistanceSqr[i] = 0.0f; + } + else if (g.IO.MouseDown[i]) + { + ImVec2 mouse_delta = g.IO.MousePos - g.IO.MouseClickedPos[i]; + g.IO.MouseDragMaxDistanceAbs[i].x = ImMax(g.IO.MouseDragMaxDistanceAbs[i].x, mouse_delta.x < 0.0f ? -mouse_delta.x : mouse_delta.x); + g.IO.MouseDragMaxDistanceAbs[i].y = ImMax(g.IO.MouseDragMaxDistanceAbs[i].y, mouse_delta.y < 0.0f ? -mouse_delta.y : mouse_delta.y); + g.IO.MouseDragMaxDistanceSqr[i] = ImMax(g.IO.MouseDragMaxDistanceSqr[i], ImLengthSqr(mouse_delta)); + } + if (g.IO.MouseClicked[i]) // Clicking any mouse button reactivate mouse hovering which may have been deactivated by gamepad/keyboard navigation + g.NavDisableMouseHover = false; + } - // Calculate frame-rate for the user, as a purely luxurious feature - g.FramerateSecPerFrameAccum += g.IO.DeltaTime - g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx]; - g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx] = g.IO.DeltaTime; - g.FramerateSecPerFrameIdx = (g.FramerateSecPerFrameIdx + 1) % IM_ARRAYSIZE(g.FramerateSecPerFrame); - g.IO.Framerate = 1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame)); + // Calculate frame-rate for the user, as a purely luxurious feature + g.FramerateSecPerFrameAccum += g.IO.DeltaTime - g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx]; + g.FramerateSecPerFrame[g.FramerateSecPerFrameIdx] = g.IO.DeltaTime; + g.FramerateSecPerFrameIdx = (g.FramerateSecPerFrameIdx + 1) % IM_ARRAYSIZE(g.FramerateSecPerFrame); + g.IO.Framerate = 1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame)); - // Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering) - UpdateMovingWindow(); + // Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering) + UpdateMovingWindow(); - // Delay saving settings so we don't spam disk too much - if (g.SettingsDirtyTimer > 0.0f) - { - g.SettingsDirtyTimer -= g.IO.DeltaTime; - if (g.SettingsDirtyTimer <= 0.0f) - SaveIniSettingsToDisk(g.IO.IniFilename); - } + // Delay saving settings so we don't spam disk too much + if (g.SettingsDirtyTimer > 0.0f) + { + g.SettingsDirtyTimer -= g.IO.DeltaTime; + if (g.SettingsDirtyTimer <= 0.0f) + SaveIniSettingsToDisk(g.IO.IniFilename); + } - // Find the window we are hovering - // - Child windows can extend beyond the limit of their parent so we need to derive HoveredRootWindow from HoveredWindow. - // - When moving a window we can skip the search, which also conveniently bypasses the fact that window->WindowRectClipped is lagging as this point. - // - We also support the moved window toggling the NoInputs flag after moving has started in order to be able to detect windows below it, which is useful for e.g. docking mechanisms. - g.HoveredWindow = (g.MovingWindow && !(g.MovingWindow->Flags & ImGuiWindowFlags_NoInputs)) ? g.MovingWindow : FindHoveredWindow(); - g.HoveredRootWindow = g.HoveredWindow ? g.HoveredWindow->RootWindow : NULL; + // Find the window we are hovering + // - Child windows can extend beyond the limit of their parent so we need to derive HoveredRootWindow from HoveredWindow. + // - When moving a window we can skip the search, which also conveniently bypasses the fact that window->WindowRectClipped is lagging as this point. + // - We also support the moved window toggling the NoInputs flag after moving has started in order to be able to detect windows below it, which is useful for e.g. docking mechanisms. + g.HoveredWindow = (g.MovingWindow && !(g.MovingWindow->Flags & ImGuiWindowFlags_NoInputs)) ? g.MovingWindow : FindHoveredWindow(); + g.HoveredRootWindow = g.HoveredWindow ? g.HoveredWindow->RootWindow : NULL; - ImGuiWindow* modal_window = GetFrontMostModalRootWindow(); - if (modal_window != NULL) - { - g.ModalWindowDarkeningRatio = ImMin(g.ModalWindowDarkeningRatio + g.IO.DeltaTime * 6.0f, 1.0f); - if (g.HoveredRootWindow && !IsWindowChildOf(g.HoveredRootWindow, modal_window)) - g.HoveredRootWindow = g.HoveredWindow = NULL; - } - else - { - g.ModalWindowDarkeningRatio = 0.0f; - } + ImGuiWindow* modal_window = GetFrontMostModalRootWindow(); + if (modal_window != NULL) + { + g.ModalWindowDarkeningRatio = ImMin(g.ModalWindowDarkeningRatio + g.IO.DeltaTime * 6.0f, 1.0f); + if (g.HoveredRootWindow && !IsWindowChildOf(g.HoveredRootWindow, modal_window)) + g.HoveredRootWindow = g.HoveredWindow = NULL; + } + else + { + g.ModalWindowDarkeningRatio = 0.0f; + } - // Update the WantCaptureMouse/WantCaptureKeyboard flags, so user can capture/discard the inputs away from the rest of their application. - // When clicking outside of a window we assume the click is owned by the application and won't request capture. We need to track click ownership. - int mouse_earliest_button_down = -1; - bool mouse_any_down = false; - for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++) - { - if (g.IO.MouseClicked[i]) - g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (!g.OpenPopupStack.empty()); - mouse_any_down |= g.IO.MouseDown[i]; - if (g.IO.MouseDown[i]) - if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[i] < g.IO.MouseClickedTime[mouse_earliest_button_down]) - mouse_earliest_button_down = i; - } - bool mouse_avail_to_imgui = (mouse_earliest_button_down == -1) || g.IO.MouseDownOwned[mouse_earliest_button_down]; - if (g.WantCaptureMouseNextFrame != -1) - g.IO.WantCaptureMouse = (g.WantCaptureMouseNextFrame != 0); - else - g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (!g.OpenPopupStack.empty()); + // Update the WantCaptureMouse/WantCaptureKeyboard flags, so user can capture/discard the inputs away from the rest of their application. + // When clicking outside of a window we assume the click is owned by the application and won't request capture. We need to track click ownership. + int mouse_earliest_button_down = -1; + bool mouse_any_down = false; + for (int i = 0; i < IM_ARRAYSIZE(g.IO.MouseDown); i++) + { + if (g.IO.MouseClicked[i]) + g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (!g.OpenPopupStack.empty()); + mouse_any_down |= g.IO.MouseDown[i]; + if (g.IO.MouseDown[i]) + if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[i] < g.IO.MouseClickedTime[mouse_earliest_button_down]) + mouse_earliest_button_down = i; + } + bool mouse_avail_to_imgui = (mouse_earliest_button_down == -1) || g.IO.MouseDownOwned[mouse_earliest_button_down]; + if (g.WantCaptureMouseNextFrame != -1) + g.IO.WantCaptureMouse = (g.WantCaptureMouseNextFrame != 0); + else + g.IO.WantCaptureMouse = (mouse_avail_to_imgui && (g.HoveredWindow != NULL || mouse_any_down)) || (!g.OpenPopupStack.empty()); - if (g.WantCaptureKeyboardNextFrame != -1) - g.IO.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != 0); - else - g.IO.WantCaptureKeyboard = (g.ActiveId != 0) || (modal_window != NULL); - if (g.IO.NavActive && (g.IO.NavFlags & ImGuiNavFlags_EnableKeyboard) && !(g.IO.NavFlags & ImGuiNavFlags_NoCaptureKeyboard)) - g.IO.WantCaptureKeyboard = true; + if (g.WantCaptureKeyboardNextFrame != -1) + g.IO.WantCaptureKeyboard = (g.WantCaptureKeyboardNextFrame != 0); + else + g.IO.WantCaptureKeyboard = (g.ActiveId != 0) || (modal_window != NULL); + if (g.IO.NavActive && (g.IO.NavFlags & ImGuiNavFlags_EnableKeyboard) && !(g.IO.NavFlags & ImGuiNavFlags_NoCaptureKeyboard)) + g.IO.WantCaptureKeyboard = true; - g.IO.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : 0; - g.MouseCursor = ImGuiMouseCursor_Arrow; - g.WantCaptureMouseNextFrame = g.WantCaptureKeyboardNextFrame = g.WantTextInputNextFrame = -1; - g.OsImePosRequest = ImVec2(1.0f, 1.0f); // OS Input Method Editor showing on top-left of our window by default + g.IO.WantTextInput = (g.WantTextInputNextFrame != -1) ? (g.WantTextInputNextFrame != 0) : 0; + g.MouseCursor = ImGuiMouseCursor_Arrow; + g.WantCaptureMouseNextFrame = g.WantCaptureKeyboardNextFrame = g.WantTextInputNextFrame = -1; + g.OsImePosRequest = ImVec2(1.0f, 1.0f); // OS Input Method Editor showing on top-left of our window by default - // If mouse was first clicked outside of ImGui bounds we also cancel out hovering. - // FIXME: For patterns of drag and drop across OS windows, we may need to rework/remove this test (first committed 311c0ca9 on 2015/02) - bool mouse_dragging_extern_payload = g.DragDropActive && (g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) != 0; - if (!mouse_avail_to_imgui && !mouse_dragging_extern_payload) - g.HoveredWindow = g.HoveredRootWindow = NULL; + // If mouse was first clicked outside of ImGui bounds we also cancel out hovering. + // FIXME: For patterns of drag and drop across OS windows, we may need to rework/remove this test (first committed 311c0ca9 on 2015/02) + bool mouse_dragging_extern_payload = g.DragDropActive && (g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) != 0; + if (!mouse_avail_to_imgui && !mouse_dragging_extern_payload) + g.HoveredWindow = g.HoveredRootWindow = NULL; - // Mouse wheel scrolling, scale - if (g.HoveredWindow && !g.HoveredWindow->Collapsed && (g.IO.MouseWheel != 0.0f || g.IO.MouseWheelH != 0.0f)) - { - // If a child window has the ImGuiWindowFlags_NoScrollWithMouse flag, we give a chance to scroll its parent (unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set). - ImGuiWindow* window = g.HoveredWindow; - ImGuiWindow* scroll_window = window; - while ((scroll_window->Flags & ImGuiWindowFlags_ChildWindow) && (scroll_window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(scroll_window->Flags & ImGuiWindowFlags_NoScrollbar) && !(scroll_window->Flags & ImGuiWindowFlags_NoInputs) && scroll_window->ParentWindow) - scroll_window = scroll_window->ParentWindow; - const bool scroll_allowed = !(scroll_window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(scroll_window->Flags & ImGuiWindowFlags_NoInputs); + // Mouse wheel scrolling, scale + if (g.HoveredWindow && !g.HoveredWindow->Collapsed && (g.IO.MouseWheel != 0.0f || g.IO.MouseWheelH != 0.0f)) + { + // If a child window has the ImGuiWindowFlags_NoScrollWithMouse flag, we give a chance to scroll its parent (unless either ImGuiWindowFlags_NoInputs or ImGuiWindowFlags_NoScrollbar are also set). + ImGuiWindow* window = g.HoveredWindow; + ImGuiWindow* scroll_window = window; + while ((scroll_window->Flags & ImGuiWindowFlags_ChildWindow) && (scroll_window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(scroll_window->Flags & ImGuiWindowFlags_NoScrollbar) && !(scroll_window->Flags & ImGuiWindowFlags_NoInputs) && scroll_window->ParentWindow) + scroll_window = scroll_window->ParentWindow; + const bool scroll_allowed = !(scroll_window->Flags & ImGuiWindowFlags_NoScrollWithMouse) && !(scroll_window->Flags & ImGuiWindowFlags_NoInputs); - if (g.IO.MouseWheel != 0.0f) - { - if (g.IO.KeyCtrl && g.IO.FontAllowUserScaling) - { - // Zoom / Scale window - const float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f); - const float scale = new_font_scale / window->FontWindowScale; - window->FontWindowScale = new_font_scale; + if (g.IO.MouseWheel != 0.0f) + { + if (g.IO.KeyCtrl && g.IO.FontAllowUserScaling) + { + // Zoom / Scale window + const float new_font_scale = ImClamp(window->FontWindowScale + g.IO.MouseWheel * 0.10f, 0.50f, 2.50f); + const float scale = new_font_scale / window->FontWindowScale; + window->FontWindowScale = new_font_scale; - const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size; - window->Pos += offset; - window->PosFloat += offset; - window->Size *= scale; - window->SizeFull *= scale; - } - else if (!g.IO.KeyCtrl && scroll_allowed) - { - // Mouse wheel vertical scrolling - float scroll_amount = 5 * scroll_window->CalcFontSize(); - scroll_amount = (float)(int)ImMin(scroll_amount, (scroll_window->ContentsRegionRect.GetHeight() + scroll_window->WindowPadding.y * 2.0f) * 0.67f); - SetWindowScrollY(scroll_window, scroll_window->Scroll.y - g.IO.MouseWheel * scroll_amount); - } - } - if (g.IO.MouseWheelH != 0.0f && scroll_allowed) - { - // Mouse wheel horizontal scrolling (for hardware that supports it) - float scroll_amount = scroll_window->CalcFontSize(); - if (!g.IO.KeyCtrl && !(window->Flags & ImGuiWindowFlags_NoScrollWithMouse)) - SetWindowScrollX(window, window->Scroll.x - g.IO.MouseWheelH * scroll_amount); - } - } + const ImVec2 offset = window->Size * (1.0f - scale) * (g.IO.MousePos - window->Pos) / window->Size; + window->Pos += offset; + window->PosFloat += offset; + window->Size *= scale; + window->SizeFull *= scale; + } + else if (!g.IO.KeyCtrl && scroll_allowed) + { + // Mouse wheel vertical scrolling + float scroll_amount = 5 * scroll_window->CalcFontSize(); + scroll_amount = (float)(int)ImMin(scroll_amount, (scroll_window->ContentsRegionRect.GetHeight() + scroll_window->WindowPadding.y * 2.0f) * 0.67f); + SetWindowScrollY(scroll_window, scroll_window->Scroll.y - g.IO.MouseWheel * scroll_amount); + } + } + if (g.IO.MouseWheelH != 0.0f && scroll_allowed) + { + // Mouse wheel horizontal scrolling (for hardware that supports it) + float scroll_amount = scroll_window->CalcFontSize(); + if (!g.IO.KeyCtrl && !(window->Flags & ImGuiWindowFlags_NoScrollWithMouse)) + SetWindowScrollX(window, window->Scroll.x - g.IO.MouseWheelH * scroll_amount); + } + } - // Pressing TAB activate widget focus - if (g.ActiveId == 0 && g.NavWindow != NULL && g.NavWindow->Active && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab, false)) - { - if (g.NavId != 0 && g.NavIdTabCounter != INT_MAX) - g.NavWindow->FocusIdxTabRequestNext = g.NavIdTabCounter + 1 + (g.IO.KeyShift ? -1 : 1); - else - g.NavWindow->FocusIdxTabRequestNext = g.IO.KeyShift ? -1 : 0; - } - g.NavIdTabCounter = INT_MAX; + // Pressing TAB activate widget focus + if (g.ActiveId == 0 && g.NavWindow != NULL && g.NavWindow->Active && !(g.NavWindow->Flags & ImGuiWindowFlags_NoNavInputs) && !g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_Tab, false)) + { + if (g.NavId != 0 && g.NavIdTabCounter != INT_MAX) + g.NavWindow->FocusIdxTabRequestNext = g.NavIdTabCounter + 1 + (g.IO.KeyShift ? -1 : 1); + else + g.NavWindow->FocusIdxTabRequestNext = g.IO.KeyShift ? -1 : 0; + } + g.NavIdTabCounter = INT_MAX; - // Mark all windows as not visible - for (int i = 0; i != g.Windows.Size; i++) - { - ImGuiWindow* window = g.Windows[i]; - window->WasActive = window->Active; - window->Active = false; - window->WriteAccessed = false; - } + // Mark all windows as not visible + for (int i = 0; i != g.Windows.Size; i++) + { + ImGuiWindow* window = g.Windows[i]; + window->WasActive = window->Active; + window->Active = false; + window->WriteAccessed = false; + } - // Closing the focused window restore focus to the first active root window in descending z-order - if (g.NavWindow && !g.NavWindow->WasActive) - FocusFrontMostActiveWindow(NULL); + // Closing the focused window restore focus to the first active root window in descending z-order + if (g.NavWindow && !g.NavWindow->WasActive) + FocusFrontMostActiveWindow(NULL); - // No window should be open at the beginning of the frame. - // But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear. - g.CurrentWindowStack.resize(0); - g.CurrentPopupStack.resize(0); - ClosePopupsOverWindow(g.NavWindow); + // No window should be open at the beginning of the frame. + // But in order to allow the user to call NewFrame() multiple times without calling Render(), we are doing an explicit clear. + g.CurrentWindowStack.resize(0); + g.CurrentPopupStack.resize(0); + ClosePopupsOverWindow(g.NavWindow); - // Create implicit window - we will only render it if the user has added something to it. - // We don't use "Debug" to avoid colliding with user trying to create a "Debug" window with custom flags. - SetNextWindowSize(ImVec2(400,400), ImGuiCond_FirstUseEver); - Begin("Debug##Default"); + // Create implicit window - we will only render it if the user has added something to it. + // We don't use "Debug" to avoid colliding with user trying to create a "Debug" window with custom flags. + SetNextWindowSize(ImVec2(400, 400), ImGuiCond_FirstUseEver); + Begin("Debug##Default"); } static void* SettingsHandlerWindow_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name) { - ImGuiWindowSettings* settings = ImGui::FindWindowSettings(ImHash(name, 0)); - if (!settings) - settings = AddWindowSettings(name); - return (void*)settings; + ImGuiWindowSettings* settings = ImGui::FindWindowSettings(ImHash(name, 0)); + if (!settings) + settings = AddWindowSettings(name); + return (void*)settings; } static void SettingsHandlerWindow_ReadLine(ImGuiContext*, ImGuiSettingsHandler*, void* entry, const char* line) { - ImGuiWindowSettings* settings = (ImGuiWindowSettings*)entry; - float x, y; - int i; - if (sscanf(line, "Pos=%f,%f", &x, &y) == 2) settings->Pos = ImVec2(x, y); - else if (sscanf(line, "Size=%f,%f", &x, &y) == 2) settings->Size = ImMax(ImVec2(x, y), GImGui->Style.WindowMinSize); - else if (sscanf(line, "Collapsed=%d", &i) == 1) settings->Collapsed = (i != 0); + ImGuiWindowSettings* settings = (ImGuiWindowSettings*)entry; + float x, y; + int i; + if (sscanf(line, "Pos=%f,%f", &x, &y) == 2) + settings->Pos = ImVec2(x, y); + else if (sscanf(line, "Size=%f,%f", &x, &y) == 2) + settings->Size = ImMax(ImVec2(x, y), GImGui->Style.WindowMinSize); + else if (sscanf(line, "Collapsed=%d", &i) == 1) + settings->Collapsed = (i != 0); } static void SettingsHandlerWindow_WriteAll(ImGuiContext* imgui_ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* buf) { - // Gather data from windows that were active during this session - ImGuiContext& g = *imgui_ctx; - for (int i = 0; i != g.Windows.Size; i++) - { - ImGuiWindow* window = g.Windows[i]; - if (window->Flags & ImGuiWindowFlags_NoSavedSettings) - continue; - ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID); - if (!settings) - settings = AddWindowSettings(window->Name); - settings->Pos = window->Pos; - settings->Size = window->SizeFull; - settings->Collapsed = window->Collapsed; - } + // Gather data from windows that were active during this session + ImGuiContext& g = *imgui_ctx; + for (int i = 0; i != g.Windows.Size; i++) + { + ImGuiWindow* window = g.Windows[i]; + if (window->Flags & ImGuiWindowFlags_NoSavedSettings) + continue; + ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID); + if (!settings) + settings = AddWindowSettings(window->Name); + settings->Pos = window->Pos; + settings->Size = window->SizeFull; + settings->Collapsed = window->Collapsed; + } - // Write a buffer - // If a window wasn't opened in this session we preserve its settings - buf->reserve(buf->size() + g.SettingsWindows.Size * 96); // ballpark reserve - for (int i = 0; i != g.SettingsWindows.Size; i++) - { - const ImGuiWindowSettings* settings = &g.SettingsWindows[i]; - if (settings->Pos.x == FLT_MAX) - continue; - const char* name = settings->Name; - if (const char* p = strstr(name, "###")) // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID() - name = p; - buf->appendf("[%s][%s]\n", handler->TypeName, name); - buf->appendf("Pos=%d,%d\n", (int)settings->Pos.x, (int)settings->Pos.y); - buf->appendf("Size=%d,%d\n", (int)settings->Size.x, (int)settings->Size.y); - buf->appendf("Collapsed=%d\n", settings->Collapsed); - buf->appendf("\n"); - } + // Write a buffer + // If a window wasn't opened in this session we preserve its settings + buf->reserve(buf->size() + g.SettingsWindows.Size * 96); // ballpark reserve + for (int i = 0; i != g.SettingsWindows.Size; i++) + { + const ImGuiWindowSettings* settings = &g.SettingsWindows[i]; + if (settings->Pos.x == FLT_MAX) + continue; + const char* name = settings->Name; + if (const char* p = strstr(name, "###")) // Skip to the "###" marker if any. We don't skip past to match the behavior of GetID() + name = p; + buf->appendf("[%s][%s]\n", handler->TypeName, name); + buf->appendf("Pos=%d,%d\n", (int)settings->Pos.x, (int)settings->Pos.y); + buf->appendf("Size=%d,%d\n", (int)settings->Size.x, (int)settings->Size.y); + buf->appendf("Collapsed=%d\n", settings->Collapsed); + buf->appendf("\n"); + } } void ImGui::Initialize(ImGuiContext* context) { - ImGuiContext& g = *context; - IM_ASSERT(!g.Initialized && !g.SettingsLoaded); - g.LogClipboard = IM_NEW(ImGuiTextBuffer)(); + ImGuiContext& g = *context; + IM_ASSERT(!g.Initialized && !g.SettingsLoaded); + g.LogClipboard = IM_NEW(ImGuiTextBuffer)(); - // Add .ini handle for ImGuiWindow type - ImGuiSettingsHandler ini_handler; - ini_handler.TypeName = "Window"; - ini_handler.TypeHash = ImHash("Window", 0, 0); - ini_handler.ReadOpenFn = SettingsHandlerWindow_ReadOpen; - ini_handler.ReadLineFn = SettingsHandlerWindow_ReadLine; - ini_handler.WriteAllFn = SettingsHandlerWindow_WriteAll; - g.SettingsHandlers.push_front(ini_handler); + // Add .ini handle for ImGuiWindow type + ImGuiSettingsHandler ini_handler; + ini_handler.TypeName = "Window"; + ini_handler.TypeHash = ImHash("Window", 0, 0); + ini_handler.ReadOpenFn = SettingsHandlerWindow_ReadOpen; + ini_handler.ReadLineFn = SettingsHandlerWindow_ReadLine; + ini_handler.WriteAllFn = SettingsHandlerWindow_WriteAll; + g.SettingsHandlers.push_front(ini_handler); - g.Initialized = true; + g.Initialized = true; } // This function is merely here to free heap allocations. void ImGui::Shutdown(ImGuiContext* context) { - ImGuiContext& g = *context; + ImGuiContext& g = *context; - // The fonts atlas can be used prior to calling NewFrame(), so we clear it even if g.Initialized is FALSE (which would happen if we never called NewFrame) - if (g.IO.Fonts && g.FontAtlasOwnedByContext) - IM_DELETE(g.IO.Fonts); + // The fonts atlas can be used prior to calling NewFrame(), so we clear it even if g.Initialized is FALSE (which would happen if we never called NewFrame) + if (g.IO.Fonts && g.FontAtlasOwnedByContext) + IM_DELETE(g.IO.Fonts); - // Cleanup of other data are conditional on actually having initialize ImGui. - if (!g.Initialized) - return; + // Cleanup of other data are conditional on actually having initialize ImGui. + if (!g.Initialized) + return; - SaveIniSettingsToDisk(g.IO.IniFilename); + SaveIniSettingsToDisk(g.IO.IniFilename); - // Clear everything else - for (int i = 0; i < g.Windows.Size; i++) - IM_DELETE(g.Windows[i]); - g.Windows.clear(); - g.WindowsSortBuffer.clear(); - g.CurrentWindow = NULL; - g.CurrentWindowStack.clear(); - g.WindowsById.Clear(); - g.NavWindow = NULL; - g.HoveredWindow = NULL; - g.HoveredRootWindow = NULL; - g.ActiveIdWindow = NULL; - g.MovingWindow = NULL; - for (int i = 0; i < g.SettingsWindows.Size; i++) - IM_DELETE(g.SettingsWindows[i].Name); - g.ColorModifiers.clear(); - g.StyleModifiers.clear(); - g.FontStack.clear(); - g.OpenPopupStack.clear(); - g.CurrentPopupStack.clear(); - g.DrawDataBuilder.ClearFreeMemory(); - g.OverlayDrawList.ClearFreeMemory(); - g.PrivateClipboard.clear(); - g.InputTextState.Text.clear(); - g.InputTextState.InitialText.clear(); - g.InputTextState.TempTextBuffer.clear(); + // Clear everything else + for (int i = 0; i < g.Windows.Size; i++) + IM_DELETE(g.Windows[i]); + g.Windows.clear(); + g.WindowsSortBuffer.clear(); + g.CurrentWindow = NULL; + g.CurrentWindowStack.clear(); + g.WindowsById.Clear(); + g.NavWindow = NULL; + g.HoveredWindow = NULL; + g.HoveredRootWindow = NULL; + g.ActiveIdWindow = NULL; + g.MovingWindow = NULL; + for (int i = 0; i < g.SettingsWindows.Size; i++) + IM_DELETE(g.SettingsWindows[i].Name); + g.ColorModifiers.clear(); + g.StyleModifiers.clear(); + g.FontStack.clear(); + g.OpenPopupStack.clear(); + g.CurrentPopupStack.clear(); + g.DrawDataBuilder.ClearFreeMemory(); + g.OverlayDrawList.ClearFreeMemory(); + g.PrivateClipboard.clear(); + g.InputTextState.Text.clear(); + g.InputTextState.InitialText.clear(); + g.InputTextState.TempTextBuffer.clear(); - g.SettingsWindows.clear(); - g.SettingsHandlers.clear(); + g.SettingsWindows.clear(); + g.SettingsHandlers.clear(); - if (g.LogFile && g.LogFile != stdout) - { - fclose(g.LogFile); - g.LogFile = NULL; - } - if (g.LogClipboard) - IM_DELETE(g.LogClipboard); + if (g.LogFile && g.LogFile != stdout) + { + fclose(g.LogFile); + g.LogFile = NULL; + } + if (g.LogClipboard) + IM_DELETE(g.LogClipboard); - g.Initialized = false; + g.Initialized = false; } ImGuiWindowSettings* ImGui::FindWindowSettings(ImGuiID id) { - ImGuiContext& g = *GImGui; - for (int i = 0; i != g.SettingsWindows.Size; i++) - if (g.SettingsWindows[i].Id == id) - return &g.SettingsWindows[i]; - return NULL; + ImGuiContext& g = *GImGui; + for (int i = 0; i != g.SettingsWindows.Size; i++) + if (g.SettingsWindows[i].Id == id) + return &g.SettingsWindows[i]; + return NULL; } static ImGuiWindowSettings* AddWindowSettings(const char* name) { - ImGuiContext& g = *GImGui; - g.SettingsWindows.push_back(ImGuiWindowSettings()); - ImGuiWindowSettings* settings = &g.SettingsWindows.back(); - settings->Name = ImStrdup(name); - settings->Id = ImHash(name, 0); - return settings; + ImGuiContext& g = *GImGui; + g.SettingsWindows.push_back(ImGuiWindowSettings()); + ImGuiWindowSettings* settings = &g.SettingsWindows.back(); + settings->Name = ImStrdup(name); + settings->Id = ImHash(name, 0); + return settings; } static void LoadIniSettingsFromDisk(const char* ini_filename) { - if (!ini_filename) - return; - char* file_data = (char*)ImFileLoadToMemory(ini_filename, "rb", NULL, +1); - if (!file_data) - return; - LoadIniSettingsFromMemory(file_data); - ImGui::MemFree(file_data); + if (!ini_filename) + return; + char* file_data = (char*)ImFileLoadToMemory(ini_filename, "rb", NULL, +1); + if (!file_data) + return; + LoadIniSettingsFromMemory(file_data); + ImGui::MemFree(file_data); } ImGuiSettingsHandler* ImGui::FindSettingsHandler(const char* type_name) { - ImGuiContext& g = *GImGui; - const ImGuiID type_hash = ImHash(type_name, 0, 0); - for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++) - if (g.SettingsHandlers[handler_n].TypeHash == type_hash) - return &g.SettingsHandlers[handler_n]; - return NULL; + ImGuiContext& g = *GImGui; + const ImGuiID type_hash = ImHash(type_name, 0, 0); + for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++) + if (g.SettingsHandlers[handler_n].TypeHash == type_hash) + return &g.SettingsHandlers[handler_n]; + return NULL; } // Zero-tolerance, no error reporting, cheap .ini parsing static void LoadIniSettingsFromMemory(const char* buf_readonly) { - // For convenience and to make the code simpler, we'll write zero terminators inside the buffer. So let's create a writable copy. - char* buf = ImStrdup(buf_readonly); - char* buf_end = buf + strlen(buf); + // For convenience and to make the code simpler, we'll write zero terminators inside the buffer. So let's create a writable copy. + char* buf = ImStrdup(buf_readonly); + char* buf_end = buf + strlen(buf); - ImGuiContext& g = *GImGui; - void* entry_data = NULL; - ImGuiSettingsHandler* entry_handler = NULL; + ImGuiContext& g = *GImGui; + void* entry_data = NULL; + ImGuiSettingsHandler* entry_handler = NULL; - char* line_end = NULL; - for (char* line = buf; line < buf_end; line = line_end + 1) - { - // Skip new lines markers, then find end of the line - while (*line == '\n' || *line == '\r') - line++; - line_end = line; - while (line_end < buf_end && *line_end != '\n' && *line_end != '\r') - line_end++; - line_end[0] = 0; + char* line_end = NULL; + for (char* line = buf; line < buf_end; line = line_end + 1) + { + // Skip new lines markers, then find end of the line + while (*line == '\n' || *line == '\r') + line++; + line_end = line; + while (line_end < buf_end && *line_end != '\n' && *line_end != '\r') + line_end++; + line_end[0] = 0; - if (line[0] == '[' && line_end > line && line_end[-1] == ']') - { - // Parse "[Type][Name]". Note that 'Name' can itself contains [] characters, which is acceptable with the current format and parsing code. - line_end[-1] = 0; - const char* name_end = line_end - 1; - const char* type_start = line + 1; - char* type_end = ImStrchrRange(type_start, name_end, ']'); - const char* name_start = type_end ? ImStrchrRange(type_end + 1, name_end, '[') : NULL; - if (!type_end || !name_start) - { - name_start = type_start; // Import legacy entries that have no type - type_start = "Window"; - } - else - { - *type_end = 0; // Overwrite first ']' - name_start++; // Skip second '[' - } - entry_handler = ImGui::FindSettingsHandler(type_start); - entry_data = entry_handler ? entry_handler->ReadOpenFn(&g, entry_handler, name_start) : NULL; - } - else if (entry_handler != NULL && entry_data != NULL) - { - // Let type handler parse the line - entry_handler->ReadLineFn(&g, entry_handler, entry_data, line); - } - } - ImGui::MemFree(buf); - g.SettingsLoaded = true; + if (line[0] == '[' && line_end > line && line_end[-1] == ']') + { + // Parse "[Type][Name]". Note that 'Name' can itself contains [] characters, which is acceptable with the current format and parsing code. + line_end[-1] = 0; + const char* name_end = line_end - 1; + const char* type_start = line + 1; + char* type_end = ImStrchrRange(type_start, name_end, ']'); + const char* name_start = type_end ? ImStrchrRange(type_end + 1, name_end, '[') : NULL; + if (!type_end || !name_start) + { + name_start = type_start; // Import legacy entries that have no type + type_start = "Window"; + } + else + { + *type_end = 0; // Overwrite first ']' + name_start++; // Skip second '[' + } + entry_handler = ImGui::FindSettingsHandler(type_start); + entry_data = entry_handler ? entry_handler->ReadOpenFn(&g, entry_handler, name_start) : NULL; + } + else if (entry_handler != NULL && entry_data != NULL) + { + // Let type handler parse the line + entry_handler->ReadLineFn(&g, entry_handler, entry_data, line); + } + } + ImGui::MemFree(buf); + g.SettingsLoaded = true; } static void SaveIniSettingsToDisk(const char* ini_filename) { - ImGuiContext& g = *GImGui; - g.SettingsDirtyTimer = 0.0f; - if (!ini_filename) - return; + ImGuiContext& g = *GImGui; + g.SettingsDirtyTimer = 0.0f; + if (!ini_filename) + return; - ImVector buf; - SaveIniSettingsToMemory(buf); + ImVector buf; + SaveIniSettingsToMemory(buf); - FILE* f = ImFileOpen(ini_filename, "wt"); - if (!f) - return; - fwrite(buf.Data, sizeof(char), (size_t)buf.Size, f); - fclose(f); + FILE* f = ImFileOpen(ini_filename, "wt"); + if (!f) + return; + fwrite(buf.Data, sizeof(char), (size_t)buf.Size, f); + fclose(f); } static void SaveIniSettingsToMemory(ImVector& out_buf) { - ImGuiContext& g = *GImGui; - g.SettingsDirtyTimer = 0.0f; + ImGuiContext& g = *GImGui; + g.SettingsDirtyTimer = 0.0f; - ImGuiTextBuffer buf; - for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++) - { - ImGuiSettingsHandler* handler = &g.SettingsHandlers[handler_n]; - handler->WriteAllFn(&g, handler, &buf); - } + ImGuiTextBuffer buf; + for (int handler_n = 0; handler_n < g.SettingsHandlers.Size; handler_n++) + { + ImGuiSettingsHandler* handler = &g.SettingsHandlers[handler_n]; + handler->WriteAllFn(&g, handler, &buf); + } - buf.Buf.pop_back(); // Remove extra zero-terminator used by ImGuiTextBuffer - out_buf.swap(buf.Buf); + buf.Buf.pop_back(); // Remove extra zero-terminator used by ImGuiTextBuffer + out_buf.swap(buf.Buf); } void ImGui::MarkIniSettingsDirty() { - ImGuiContext& g = *GImGui; - if (g.SettingsDirtyTimer <= 0.0f) - g.SettingsDirtyTimer = g.IO.IniSavingRate; + ImGuiContext& g = *GImGui; + if (g.SettingsDirtyTimer <= 0.0f) + g.SettingsDirtyTimer = g.IO.IniSavingRate; } static void MarkIniSettingsDirty(ImGuiWindow* window) { - ImGuiContext& g = *GImGui; - if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) - if (g.SettingsDirtyTimer <= 0.0f) - g.SettingsDirtyTimer = g.IO.IniSavingRate; + ImGuiContext& g = *GImGui; + if (!(window->Flags & ImGuiWindowFlags_NoSavedSettings)) + if (g.SettingsDirtyTimer <= 0.0f) + g.SettingsDirtyTimer = g.IO.IniSavingRate; } // FIXME: Add a more explicit sort order in the window structure. static int IMGUI_CDECL ChildWindowComparer(const void* lhs, const void* rhs) { - const ImGuiWindow* a = *(const ImGuiWindow**)lhs; - const ImGuiWindow* b = *(const ImGuiWindow**)rhs; - if (int d = (a->Flags & ImGuiWindowFlags_Popup) - (b->Flags & ImGuiWindowFlags_Popup)) - return d; - if (int d = (a->Flags & ImGuiWindowFlags_Tooltip) - (b->Flags & ImGuiWindowFlags_Tooltip)) - return d; - return (a->BeginOrderWithinParent - b->BeginOrderWithinParent); + const ImGuiWindow* a = *(const ImGuiWindow**)lhs; + const ImGuiWindow* b = *(const ImGuiWindow**)rhs; + if (int d = (a->Flags & ImGuiWindowFlags_Popup) - (b->Flags & ImGuiWindowFlags_Popup)) + return d; + if (int d = (a->Flags & ImGuiWindowFlags_Tooltip) - (b->Flags & ImGuiWindowFlags_Tooltip)) + return d; + return (a->BeginOrderWithinParent - b->BeginOrderWithinParent); } static void AddWindowToSortedBuffer(ImVector* out_sorted_windows, ImGuiWindow* window) { - out_sorted_windows->push_back(window); - if (window->Active) - { - int count = window->DC.ChildWindows.Size; - if (count > 1) - qsort(window->DC.ChildWindows.begin(), (size_t)count, sizeof(ImGuiWindow*), ChildWindowComparer); - for (int i = 0; i < count; i++) - { - ImGuiWindow* child = window->DC.ChildWindows[i]; - if (child->Active) - AddWindowToSortedBuffer(out_sorted_windows, child); - } - } + out_sorted_windows->push_back(window); + if (window->Active) + { + int count = window->DC.ChildWindows.Size; + if (count > 1) + qsort(window->DC.ChildWindows.begin(), (size_t)count, sizeof(ImGuiWindow*), ChildWindowComparer); + for (int i = 0; i < count; i++) + { + ImGuiWindow* child = window->DC.ChildWindows[i]; + if (child->Active) + AddWindowToSortedBuffer(out_sorted_windows, child); + } + } } static void AddDrawListToDrawData(ImVector* out_render_list, ImDrawList* draw_list) { - if (draw_list->CmdBuffer.empty()) - return; + if (draw_list->CmdBuffer.empty()) + return; - // Remove trailing command if unused - ImDrawCmd& last_cmd = draw_list->CmdBuffer.back(); - if (last_cmd.ElemCount == 0 && last_cmd.UserCallback == NULL) - { - draw_list->CmdBuffer.pop_back(); - if (draw_list->CmdBuffer.empty()) - return; - } + // Remove trailing command if unused + ImDrawCmd& last_cmd = draw_list->CmdBuffer.back(); + if (last_cmd.ElemCount == 0 && last_cmd.UserCallback == NULL) + { + draw_list->CmdBuffer.pop_back(); + if (draw_list->CmdBuffer.empty()) + return; + } - // Draw list sanity check. Detect mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc. May trigger for you if you are using PrimXXX functions incorrectly. - IM_ASSERT(draw_list->VtxBuffer.Size == 0 || draw_list->_VtxWritePtr == draw_list->VtxBuffer.Data + draw_list->VtxBuffer.Size); - IM_ASSERT(draw_list->IdxBuffer.Size == 0 || draw_list->_IdxWritePtr == draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size); - IM_ASSERT((int)draw_list->_VtxCurrentIdx == draw_list->VtxBuffer.Size); + // Draw list sanity check. Detect mismatch between PrimReserve() calls and incrementing _VtxCurrentIdx, _VtxWritePtr etc. May trigger for you if you are using PrimXXX functions incorrectly. + IM_ASSERT(draw_list->VtxBuffer.Size == 0 || draw_list->_VtxWritePtr == draw_list->VtxBuffer.Data + draw_list->VtxBuffer.Size); + IM_ASSERT(draw_list->IdxBuffer.Size == 0 || draw_list->_IdxWritePtr == draw_list->IdxBuffer.Data + draw_list->IdxBuffer.Size); + IM_ASSERT((int)draw_list->_VtxCurrentIdx == draw_list->VtxBuffer.Size); - // Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = unsigned short = 2 bytes = 64K vertices per ImDrawList = per window) - // If this assert triggers because you are drawing lots of stuff manually: - // A) Make sure you are coarse clipping, because ImDrawList let all your vertices pass. You can use the Metrics window to inspect draw list contents. - // B) If you need/want meshes with more than 64K vertices, uncomment the '#define ImDrawIdx unsigned int' line in imconfig.h to set the index size to 4 bytes. - // You'll need to handle the 4-bytes indices to your renderer. For example, the OpenGL example code detect index size at compile-time by doing: - // glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); - // Your own engine or render API may use different parameters or function calls to specify index sizes. 2 and 4 bytes indices are generally supported by most API. - // C) If for some reason you cannot use 4 bytes indices or don't want to, a workaround is to call BeginChild()/EndChild() before reaching the 64K limit to split your draw commands in multiple draw lists. - if (sizeof(ImDrawIdx) == 2) - IM_ASSERT(draw_list->_VtxCurrentIdx < (1 << 16) && "Too many vertices in ImDrawList using 16-bit indices. Read comment above"); + // Check that draw_list doesn't use more vertices than indexable (default ImDrawIdx = unsigned short = 2 bytes = 64K vertices per ImDrawList = per window) + // If this assert triggers because you are drawing lots of stuff manually: + // A) Make sure you are coarse clipping, because ImDrawList let all your vertices pass. You can use the Metrics window to inspect draw list contents. + // B) If you need/want meshes with more than 64K vertices, uncomment the '#define ImDrawIdx unsigned int' line in imconfig.h to set the index size to 4 bytes. + // You'll need to handle the 4-bytes indices to your renderer. For example, the OpenGL example code detect index size at compile-time by doing: + // glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer_offset); + // Your own engine or render API may use different parameters or function calls to specify index sizes. 2 and 4 bytes indices are generally supported by most API. + // C) If for some reason you cannot use 4 bytes indices or don't want to, a workaround is to call BeginChild()/EndChild() before reaching the 64K limit to split your draw commands in multiple draw lists. + if (sizeof(ImDrawIdx) == 2) + IM_ASSERT(draw_list->_VtxCurrentIdx < (1 << 16) && "Too many vertices in ImDrawList using 16-bit indices. Read comment above"); - out_render_list->push_back(draw_list); + out_render_list->push_back(draw_list); } static void AddWindowToDrawData(ImVector* out_render_list, ImGuiWindow* window) { - AddDrawListToDrawData(out_render_list, window->DrawList); - for (int i = 0; i < window->DC.ChildWindows.Size; i++) - { - ImGuiWindow* child = window->DC.ChildWindows[i]; - if (child->Active && child->HiddenFrames <= 0) // clipped children may have been marked not active - AddWindowToDrawData(out_render_list, child); - } + AddDrawListToDrawData(out_render_list, window->DrawList); + for (int i = 0; i < window->DC.ChildWindows.Size; i++) + { + ImGuiWindow* child = window->DC.ChildWindows[i]; + if (child->Active && child->HiddenFrames <= 0) // clipped children may have been marked not active + AddWindowToDrawData(out_render_list, child); + } } static void AddWindowToDrawDataSelectLayer(ImGuiWindow* window) { - ImGuiContext& g = *GImGui; - g.IO.MetricsActiveWindows++; - if (window->Flags & ImGuiWindowFlags_Tooltip) - AddWindowToDrawData(&g.DrawDataBuilder.Layers[1], window); - else - AddWindowToDrawData(&g.DrawDataBuilder.Layers[0], window); + ImGuiContext& g = *GImGui; + g.IO.MetricsActiveWindows++; + if (window->Flags & ImGuiWindowFlags_Tooltip) + AddWindowToDrawData(&g.DrawDataBuilder.Layers[1], window); + else + AddWindowToDrawData(&g.DrawDataBuilder.Layers[0], window); } void ImDrawDataBuilder::FlattenIntoSingleLayer() { - int n = Layers[0].Size; - int size = n; - for (int i = 1; i < IM_ARRAYSIZE(Layers); i++) - size += Layers[i].Size; - Layers[0].resize(size); - for (int layer_n = 1; layer_n < IM_ARRAYSIZE(Layers); layer_n++) - { - ImVector& layer = Layers[layer_n]; - if (layer.empty()) - continue; - memcpy(&Layers[0][n], &layer[0], layer.Size * sizeof(ImDrawList*)); - n += layer.Size; - layer.resize(0); - } + int n = Layers[0].Size; + int size = n; + for (int i = 1; i < IM_ARRAYSIZE(Layers); i++) + size += Layers[i].Size; + Layers[0].resize(size); + for (int layer_n = 1; layer_n < IM_ARRAYSIZE(Layers); layer_n++) + { + ImVector& layer = Layers[layer_n]; + if (layer.empty()) + continue; + memcpy(&Layers[0][n], &layer[0], layer.Size * sizeof(ImDrawList*)); + n += layer.Size; + layer.resize(0); + } } static void SetupDrawData(ImVector* draw_lists, ImDrawData* out_draw_data) { - out_draw_data->Valid = true; - out_draw_data->CmdLists = (draw_lists->Size > 0) ? draw_lists->Data : NULL; - out_draw_data->CmdListsCount = draw_lists->Size; - out_draw_data->TotalVtxCount = out_draw_data->TotalIdxCount = 0; - for (int n = 0; n < draw_lists->Size; n++) - { - out_draw_data->TotalVtxCount += draw_lists->Data[n]->VtxBuffer.Size; - out_draw_data->TotalIdxCount += draw_lists->Data[n]->IdxBuffer.Size; - } + out_draw_data->Valid = true; + out_draw_data->CmdLists = (draw_lists->Size > 0) ? draw_lists->Data : NULL; + out_draw_data->CmdListsCount = draw_lists->Size; + out_draw_data->TotalVtxCount = out_draw_data->TotalIdxCount = 0; + for (int n = 0; n < draw_lists->Size; n++) + { + out_draw_data->TotalVtxCount += draw_lists->Data[n]->VtxBuffer.Size; + out_draw_data->TotalIdxCount += draw_lists->Data[n]->IdxBuffer.Size; + } } // When using this function it is sane to ensure that float are perfectly rounded to integer values, to that e.g. (int)(max.x-min.x) in user's render produce correct result. void ImGui::PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect) { - ImGuiWindow* window = GetCurrentWindow(); - window->DrawList->PushClipRect(clip_rect_min, clip_rect_max, intersect_with_current_clip_rect); - window->ClipRect = window->DrawList->_ClipRectStack.back(); + ImGuiWindow* window = GetCurrentWindow(); + window->DrawList->PushClipRect(clip_rect_min, clip_rect_max, intersect_with_current_clip_rect); + window->ClipRect = window->DrawList->_ClipRectStack.back(); } void ImGui::PopClipRect() { - ImGuiWindow* window = GetCurrentWindow(); - window->DrawList->PopClipRect(); - window->ClipRect = window->DrawList->_ClipRectStack.back(); + ImGuiWindow* window = GetCurrentWindow(); + window->DrawList->PopClipRect(); + window->ClipRect = window->DrawList->_ClipRectStack.back(); } // This is normally called by Render(). You may want to call it directly if you want to avoid calling Render() but the gain will be very minimal. void ImGui::EndFrame() { - ImGuiContext& g = *GImGui; - IM_ASSERT(g.Initialized); // Forgot to call ImGui::NewFrame() - if (g.FrameCountEnded == g.FrameCount) // Don't process EndFrame() multiple times. - return; + ImGuiContext& g = *GImGui; + IM_ASSERT(g.Initialized); // Forgot to call ImGui::NewFrame() + if (g.FrameCountEnded == g.FrameCount) // Don't process EndFrame() multiple times. + return; - // Notify OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME) - if (g.IO.ImeSetInputScreenPosFn && ImLengthSqr(g.OsImePosRequest - g.OsImePosSet) > 0.0001f) - { - g.IO.ImeSetInputScreenPosFn((int)g.OsImePosRequest.x, (int)g.OsImePosRequest.y); - g.OsImePosSet = g.OsImePosRequest; - } + // Notify OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME) + if (g.IO.ImeSetInputScreenPosFn && ImLengthSqr(g.OsImePosRequest - g.OsImePosSet) > 0.0001f) + { + g.IO.ImeSetInputScreenPosFn((int)g.OsImePosRequest.x, (int)g.OsImePosRequest.y); + g.OsImePosSet = g.OsImePosRequest; + } - // Hide implicit "Debug" window if it hasn't been used - IM_ASSERT(g.CurrentWindowStack.Size == 1); // Mismatched Begin()/End() calls - if (g.CurrentWindow && !g.CurrentWindow->WriteAccessed) - g.CurrentWindow->Active = false; - End(); + // Hide implicit "Debug" window if it hasn't been used + IM_ASSERT(g.CurrentWindowStack.Size == 1); // Mismatched Begin()/End() calls + if (g.CurrentWindow && !g.CurrentWindow->WriteAccessed) + g.CurrentWindow->Active = false; + End(); - if (g.ActiveId == 0 && g.HoveredId == 0) - { - if (!g.NavWindow || !g.NavWindow->Appearing) // Unless we just made a window/popup appear - { - // Click to focus window and start moving (after we're done with all our widgets) - if (g.IO.MouseClicked[0]) - { - if (g.HoveredRootWindow != NULL) - { - // Set ActiveId even if the _NoMove flag is set, without it dragging away from a window with _NoMove would activate hover on other windows. - FocusWindow(g.HoveredWindow); - SetActiveID(g.HoveredWindow->MoveId, g.HoveredWindow); - g.NavDisableHighlight = true; - g.ActiveIdClickOffset = g.IO.MousePos - g.HoveredRootWindow->Pos; - if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove) && !(g.HoveredRootWindow->Flags & ImGuiWindowFlags_NoMove)) - g.MovingWindow = g.HoveredWindow; - } - else if (g.NavWindow != NULL && GetFrontMostModalRootWindow() == NULL) - { - // Clicking on void disable focus - FocusWindow(NULL); - } - } + if (g.ActiveId == 0 && g.HoveredId == 0) + { + if (!g.NavWindow || !g.NavWindow->Appearing) // Unless we just made a window/popup appear + { + // Click to focus window and start moving (after we're done with all our widgets) + if (g.IO.MouseClicked[0]) + { + if (g.HoveredRootWindow != NULL) + { + // Set ActiveId even if the _NoMove flag is set, without it dragging away from a window with _NoMove would activate hover on other windows. + FocusWindow(g.HoveredWindow); + SetActiveID(g.HoveredWindow->MoveId, g.HoveredWindow); + g.NavDisableHighlight = true; + g.ActiveIdClickOffset = g.IO.MousePos - g.HoveredRootWindow->Pos; + if (!(g.HoveredWindow->Flags & ImGuiWindowFlags_NoMove) && !(g.HoveredRootWindow->Flags & ImGuiWindowFlags_NoMove)) + g.MovingWindow = g.HoveredWindow; + } + else if (g.NavWindow != NULL && GetFrontMostModalRootWindow() == NULL) + { + // Clicking on void disable focus + FocusWindow(NULL); + } + } - // With right mouse button we close popups without changing focus - // (The left mouse button path calls FocusWindow which will lead NewFrame->ClosePopupsOverWindow to trigger) - if (g.IO.MouseClicked[1]) - { - // Find the top-most window between HoveredWindow and the front most Modal Window. - // This is where we can trim the popup stack. - ImGuiWindow* modal = GetFrontMostModalRootWindow(); - bool hovered_window_above_modal = false; - if (modal == NULL) - hovered_window_above_modal = true; - for (int i = g.Windows.Size - 1; i >= 0 && hovered_window_above_modal == false; i--) - { - ImGuiWindow* window = g.Windows[i]; - if (window == modal) - break; - if (window == g.HoveredWindow) - hovered_window_above_modal = true; - } - ClosePopupsOverWindow(hovered_window_above_modal ? g.HoveredWindow : modal); - } - } - } + // With right mouse button we close popups without changing focus + // (The left mouse button path calls FocusWindow which will lead NewFrame->ClosePopupsOverWindow to trigger) + if (g.IO.MouseClicked[1]) + { + // Find the top-most window between HoveredWindow and the front most Modal Window. + // This is where we can trim the popup stack. + ImGuiWindow* modal = GetFrontMostModalRootWindow(); + bool hovered_window_above_modal = false; + if (modal == NULL) + hovered_window_above_modal = true; + for (int i = g.Windows.Size - 1; i >= 0 && hovered_window_above_modal == false; i--) + { + ImGuiWindow* window = g.Windows[i]; + if (window == modal) + break; + if (window == g.HoveredWindow) + hovered_window_above_modal = true; + } + ClosePopupsOverWindow(hovered_window_above_modal ? g.HoveredWindow : modal); + } + } + } - // Sort the window list so that all child windows are after their parent - // We cannot do that on FocusWindow() because childs may not exist yet - g.WindowsSortBuffer.resize(0); - g.WindowsSortBuffer.reserve(g.Windows.Size); - for (int i = 0; i != g.Windows.Size; i++) - { - ImGuiWindow* window = g.Windows[i]; - if (window->Active && (window->Flags & ImGuiWindowFlags_ChildWindow)) // if a child is active its parent will add it - continue; - AddWindowToSortedBuffer(&g.WindowsSortBuffer, window); - } + // Sort the window list so that all child windows are after their parent + // We cannot do that on FocusWindow() because childs may not exist yet + g.WindowsSortBuffer.resize(0); + g.WindowsSortBuffer.reserve(g.Windows.Size); + for (int i = 0; i != g.Windows.Size; i++) + { + ImGuiWindow* window = g.Windows[i]; + if (window->Active && (window->Flags & ImGuiWindowFlags_ChildWindow)) // if a child is active its parent will add it + continue; + AddWindowToSortedBuffer(&g.WindowsSortBuffer, window); + } - IM_ASSERT(g.Windows.Size == g.WindowsSortBuffer.Size); // we done something wrong - g.Windows.swap(g.WindowsSortBuffer); + IM_ASSERT(g.Windows.Size == g.WindowsSortBuffer.Size); // we done something wrong + g.Windows.swap(g.WindowsSortBuffer); - // Clear Input data for next frame - g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f; - memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters)); - memset(g.IO.NavInputs, 0, sizeof(g.IO.NavInputs)); + // Clear Input data for next frame + g.IO.MouseWheel = g.IO.MouseWheelH = 0.0f; + memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters)); + memset(g.IO.NavInputs, 0, sizeof(g.IO.NavInputs)); - g.FrameCountEnded = g.FrameCount; + g.FrameCountEnded = g.FrameCount; } void ImGui::Render() { - ImGuiContext& g = *GImGui; - IM_ASSERT(g.Initialized); // Forgot to call ImGui::NewFrame() + ImGuiContext& g = *GImGui; + IM_ASSERT(g.Initialized); // Forgot to call ImGui::NewFrame() - if (g.FrameCountEnded != g.FrameCount) - ImGui::EndFrame(); - g.FrameCountRendered = g.FrameCount; + if (g.FrameCountEnded != g.FrameCount) + ImGui::EndFrame(); + g.FrameCountRendered = g.FrameCount; - // Skip render altogether if alpha is 0.0 - // Note that vertex buffers have been created and are wasted, so it is best practice that you don't create windows in the first place, or consistently respond to Begin() returning false. - if (g.Style.Alpha > 0.0f) - { - // Gather windows to render - g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = g.IO.MetricsActiveWindows = 0; - g.DrawDataBuilder.Clear(); - ImGuiWindow* window_to_render_front_most = (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) ? g.NavWindowingTarget : NULL; - for (int n = 0; n != g.Windows.Size; n++) - { - ImGuiWindow* window = g.Windows[n]; - if (window->Active && window->HiddenFrames <= 0 && (window->Flags & (ImGuiWindowFlags_ChildWindow)) == 0 && window != window_to_render_front_most) - AddWindowToDrawDataSelectLayer(window); - } - if (window_to_render_front_most && window_to_render_front_most->Active && window_to_render_front_most->HiddenFrames <= 0) // NavWindowingTarget is always temporarily displayed as the front-most window - AddWindowToDrawDataSelectLayer(window_to_render_front_most); - g.DrawDataBuilder.FlattenIntoSingleLayer(); + // Skip render altogether if alpha is 0.0 + // Note that vertex buffers have been created and are wasted, so it is best practice that you don't create windows in the first place, or consistently respond to Begin() returning false. + if (g.Style.Alpha > 0.0f) + { + // Gather windows to render + g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = g.IO.MetricsActiveWindows = 0; + g.DrawDataBuilder.Clear(); + ImGuiWindow* window_to_render_front_most = (g.NavWindowingTarget && !(g.NavWindowingTarget->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) ? g.NavWindowingTarget : NULL; + for (int n = 0; n != g.Windows.Size; n++) + { + ImGuiWindow* window = g.Windows[n]; + if (window->Active && window->HiddenFrames <= 0 && (window->Flags & (ImGuiWindowFlags_ChildWindow)) == 0 && window != window_to_render_front_most) + AddWindowToDrawDataSelectLayer(window); + } + if (window_to_render_front_most && window_to_render_front_most->Active && window_to_render_front_most->HiddenFrames <= 0) // NavWindowingTarget is always temporarily displayed as the front-most window + AddWindowToDrawDataSelectLayer(window_to_render_front_most); + g.DrawDataBuilder.FlattenIntoSingleLayer(); - // Draw software mouse cursor if requested - ImVec2 offset, size, uv[4]; - if (g.IO.MouseDrawCursor && g.IO.Fonts->GetMouseCursorTexData(g.MouseCursor, &offset, &size, &uv[0], &uv[2])) - { - const ImVec2 pos = g.IO.MousePos - offset; - const ImTextureID tex_id = g.IO.Fonts->TexID; - const float sc = g.Style.MouseCursorScale; - g.OverlayDrawList.PushTextureID(tex_id); - g.OverlayDrawList.AddImage(tex_id, pos + ImVec2(1,0)*sc, pos+ImVec2(1,0)*sc + size*sc, uv[2], uv[3], IM_COL32(0,0,0,48)); // Shadow - g.OverlayDrawList.AddImage(tex_id, pos + ImVec2(2,0)*sc, pos+ImVec2(2,0)*sc + size*sc, uv[2], uv[3], IM_COL32(0,0,0,48)); // Shadow - g.OverlayDrawList.AddImage(tex_id, pos, pos + size*sc, uv[2], uv[3], IM_COL32(0,0,0,255)); // Black border - g.OverlayDrawList.AddImage(tex_id, pos, pos + size*sc, uv[0], uv[1], IM_COL32(255,255,255,255)); // White fill - g.OverlayDrawList.PopTextureID(); - } - if (!g.OverlayDrawList.VtxBuffer.empty()) - AddDrawListToDrawData(&g.DrawDataBuilder.Layers[0], &g.OverlayDrawList); + // Draw software mouse cursor if requested + ImVec2 offset, size, uv[4]; + if (g.IO.MouseDrawCursor && g.IO.Fonts->GetMouseCursorTexData(g.MouseCursor, &offset, &size, &uv[0], &uv[2])) + { + const ImVec2 pos = g.IO.MousePos - offset; + const ImTextureID tex_id = g.IO.Fonts->TexID; + const float sc = g.Style.MouseCursorScale; + g.OverlayDrawList.PushTextureID(tex_id); + g.OverlayDrawList.AddImage(tex_id, pos + ImVec2(1, 0) * sc, pos + ImVec2(1, 0) * sc + size * sc, uv[2], uv[3], IM_COL32(0, 0, 0, 48)); // Shadow + g.OverlayDrawList.AddImage(tex_id, pos + ImVec2(2, 0) * sc, pos + ImVec2(2, 0) * sc + size * sc, uv[2], uv[3], IM_COL32(0, 0, 0, 48)); // Shadow + g.OverlayDrawList.AddImage(tex_id, pos, pos + size * sc, uv[2], uv[3], IM_COL32(0, 0, 0, 255)); // Black border + g.OverlayDrawList.AddImage(tex_id, pos, pos + size * sc, uv[0], uv[1], IM_COL32(255, 255, 255, 255)); // White fill + g.OverlayDrawList.PopTextureID(); + } + if (!g.OverlayDrawList.VtxBuffer.empty()) + AddDrawListToDrawData(&g.DrawDataBuilder.Layers[0], &g.OverlayDrawList); - // Setup ImDrawData structure for end-user - SetupDrawData(&g.DrawDataBuilder.Layers[0], &g.DrawData); - g.IO.MetricsRenderVertices = g.DrawData.TotalVtxCount; - g.IO.MetricsRenderIndices = g.DrawData.TotalIdxCount; + // Setup ImDrawData structure for end-user + SetupDrawData(&g.DrawDataBuilder.Layers[0], &g.DrawData); + g.IO.MetricsRenderVertices = g.DrawData.TotalVtxCount; + g.IO.MetricsRenderIndices = g.DrawData.TotalIdxCount; - // Render. If user hasn't set a callback then they may retrieve the draw data via GetDrawData() + // Render. If user hasn't set a callback then they may retrieve the draw data via GetDrawData() #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - if (g.DrawData.CmdListsCount > 0 && g.IO.RenderDrawListsFn != NULL) - g.IO.RenderDrawListsFn(&g.DrawData); + if (g.DrawData.CmdListsCount > 0 && g.IO.RenderDrawListsFn != NULL) + g.IO.RenderDrawListsFn(&g.DrawData); #endif - } + } } const char* ImGui::FindRenderedTextEnd(const char* text, const char* text_end) { - const char* text_display_end = text; - if (!text_end) - text_end = (const char*)-1; + const char* text_display_end = text; + if (!text_end) + text_end = (const char*)-1; - while (text_display_end < text_end && *text_display_end != '\0' && (text_display_end[0] != '#' || text_display_end[1] != '#')) - text_display_end++; - return text_display_end; + while (text_display_end < text_end && *text_display_end != '\0' && (text_display_end[0] != '#' || text_display_end[1] != '#')) + text_display_end++; + return text_display_end; } // Pass text data straight to log (without being displayed) void ImGui::LogText(const char* fmt, ...) { - ImGuiContext& g = *GImGui; - if (!g.LogEnabled) - return; + ImGuiContext& g = *GImGui; + if (!g.LogEnabled) + return; - va_list args; - va_start(args, fmt); - if (g.LogFile) - { - vfprintf(g.LogFile, fmt, args); - } - else - { - g.LogClipboard->appendfv(fmt, args); - } - va_end(args); + va_list args; + va_start(args, fmt); + if (g.LogFile) + { + vfprintf(g.LogFile, fmt, args); + } + else + { + g.LogClipboard->appendfv(fmt, args); + } + va_end(args); } // Internal version that takes a position to decide on newline placement and pad items according to their depth. // We split text into individual lines to add current tree level padding static void LogRenderedText(const ImVec2* ref_pos, const char* text, const char* text_end = NULL) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; - if (!text_end) - text_end = ImGui::FindRenderedTextEnd(text, text_end); + if (!text_end) + text_end = ImGui::FindRenderedTextEnd(text, text_end); - const bool log_new_line = ref_pos && (ref_pos->y > window->DC.LogLinePosY + 1); - if (ref_pos) - window->DC.LogLinePosY = ref_pos->y; + const bool log_new_line = ref_pos && (ref_pos->y > window->DC.LogLinePosY + 1); + if (ref_pos) + window->DC.LogLinePosY = ref_pos->y; - const char* text_remaining = text; - if (g.LogStartDepth > window->DC.TreeDepth) // Re-adjust padding if we have popped out of our starting depth - g.LogStartDepth = window->DC.TreeDepth; - const int tree_depth = (window->DC.TreeDepth - g.LogStartDepth); - for (;;) - { - // Split the string. Each new line (after a '\n') is followed by spacing corresponding to the current depth of our log entry. - const char* line_end = text_remaining; - while (line_end < text_end) - if (*line_end == '\n') - break; - else - line_end++; - if (line_end >= text_end) - line_end = NULL; + const char* text_remaining = text; + if (g.LogStartDepth > window->DC.TreeDepth) // Re-adjust padding if we have popped out of our starting depth + g.LogStartDepth = window->DC.TreeDepth; + const int tree_depth = (window->DC.TreeDepth - g.LogStartDepth); + for (;;) + { + // Split the string. Each new line (after a '\n') is followed by spacing corresponding to the current depth of our log entry. + const char* line_end = text_remaining; + while (line_end < text_end) + if (*line_end == '\n') + break; + else + line_end++; + if (line_end >= text_end) + line_end = NULL; - const bool is_first_line = (text == text_remaining); - bool is_last_line = false; - if (line_end == NULL) - { - is_last_line = true; - line_end = text_end; - } - if (line_end != NULL && !(is_last_line && (line_end - text_remaining)==0)) - { - const int char_count = (int)(line_end - text_remaining); - if (log_new_line || !is_first_line) - ImGui::LogText(IM_NEWLINE "%*s%.*s", tree_depth*4, "", char_count, text_remaining); - else - ImGui::LogText(" %.*s", char_count, text_remaining); - } + const bool is_first_line = (text == text_remaining); + bool is_last_line = false; + if (line_end == NULL) + { + is_last_line = true; + line_end = text_end; + } + if (line_end != NULL && !(is_last_line && (line_end - text_remaining) == 0)) + { + const int char_count = (int)(line_end - text_remaining); + if (log_new_line || !is_first_line) + ImGui::LogText(IM_NEWLINE "%*s%.*s", tree_depth * 4, "", char_count, text_remaining); + else + ImGui::LogText(" %.*s", char_count, text_remaining); + } - if (is_last_line) - break; - text_remaining = line_end + 1; - } + if (is_last_line) + break; + text_remaining = line_end + 1; + } } // Internal ImGui functions to render text // RenderText***() functions calls ImDrawList::AddText() calls ImBitmapFont::RenderText() void ImGui::RenderText(ImVec2 pos, const char* text, const char* text_end, bool hide_text_after_hash) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; - // Hide anything after a '##' string - const char* text_display_end; - if (hide_text_after_hash) - { - text_display_end = FindRenderedTextEnd(text, text_end); - } - else - { - if (!text_end) - text_end = text + strlen(text); // FIXME-OPT - text_display_end = text_end; - } + // Hide anything after a '##' string + const char* text_display_end; + if (hide_text_after_hash) + { + text_display_end = FindRenderedTextEnd(text, text_end); + } + else + { + if (!text_end) + text_end = text + strlen(text); // FIXME-OPT + text_display_end = text_end; + } - const int text_len = (int)(text_display_end - text); - if (text_len > 0) - { - window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end); - if (g.LogEnabled) - LogRenderedText(&pos, text, text_display_end); - } + const int text_len = (int)(text_display_end - text); + if (text_len > 0) + { + window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end); + if (g.LogEnabled) + LogRenderedText(&pos, text, text_display_end); + } } void ImGui::RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; - if (!text_end) - text_end = text + strlen(text); // FIXME-OPT + if (!text_end) + text_end = text + strlen(text); // FIXME-OPT - const int text_len = (int)(text_end - text); - if (text_len > 0) - { - window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_end, wrap_width); - if (g.LogEnabled) - LogRenderedText(&pos, text, text_end); - } + const int text_len = (int)(text_end - text); + if (text_len > 0) + { + window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_end, wrap_width); + if (g.LogEnabled) + LogRenderedText(&pos, text, text_end); + } } // Default clip_rect uses (pos_min,pos_max) // Handle clipping on CPU immediately (vs typically let the GPU clip the triangles that are overlapping the clipping rectangle edges) void ImGui::RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align, const ImRect* clip_rect) { - // Hide anything after a '##' string - const char* text_display_end = FindRenderedTextEnd(text, text_end); - const int text_len = (int)(text_display_end - text); - if (text_len == 0) - return; + // Hide anything after a '##' string + const char* text_display_end = FindRenderedTextEnd(text, text_end); + const int text_len = (int)(text_display_end - text); + if (text_len == 0) + return; - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; - // Perform CPU side clipping for single clipped element to avoid using scissor state - ImVec2 pos = pos_min; - const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_display_end, false, 0.0f); + // Perform CPU side clipping for single clipped element to avoid using scissor state + ImVec2 pos = pos_min; + const ImVec2 text_size = text_size_if_known ? *text_size_if_known : CalcTextSize(text, text_display_end, false, 0.0f); - const ImVec2* clip_min = clip_rect ? &clip_rect->Min : &pos_min; - const ImVec2* clip_max = clip_rect ? &clip_rect->Max : &pos_max; - bool need_clipping = (pos.x + text_size.x >= clip_max->x) || (pos.y + text_size.y >= clip_max->y); - if (clip_rect) // If we had no explicit clipping rectangle then pos==clip_min - need_clipping |= (pos.x < clip_min->x) || (pos.y < clip_min->y); + const ImVec2* clip_min = clip_rect ? &clip_rect->Min : &pos_min; + const ImVec2* clip_max = clip_rect ? &clip_rect->Max : &pos_max; + bool need_clipping = (pos.x + text_size.x >= clip_max->x) || (pos.y + text_size.y >= clip_max->y); + if (clip_rect) // If we had no explicit clipping rectangle then pos==clip_min + need_clipping |= (pos.x < clip_min->x) || (pos.y < clip_min->y); - // Align whole block. We should defer that to the better rendering function when we'll have support for individual line alignment. - if (align.x > 0.0f) pos.x = ImMax(pos.x, pos.x + (pos_max.x - pos.x - text_size.x) * align.x); - if (align.y > 0.0f) pos.y = ImMax(pos.y, pos.y + (pos_max.y - pos.y - text_size.y) * align.y); + // Align whole block. We should defer that to the better rendering function when we'll have support for individual line alignment. + if (align.x > 0.0f) pos.x = ImMax(pos.x, pos.x + (pos_max.x - pos.x - text_size.x) * align.x); + if (align.y > 0.0f) pos.y = ImMax(pos.y, pos.y + (pos_max.y - pos.y - text_size.y) * align.y); - // Render - if (need_clipping) - { - ImVec4 fine_clip_rect(clip_min->x, clip_min->y, clip_max->x, clip_max->y); - window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, &fine_clip_rect); - } - else - { - window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, NULL); - } - if (g.LogEnabled) - LogRenderedText(&pos, text, text_display_end); + // Render + if (need_clipping) + { + ImVec4 fine_clip_rect(clip_min->x, clip_min->y, clip_max->x, clip_max->y); + window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, &fine_clip_rect); + } + else + { + window->DrawList->AddText(g.Font, g.FontSize, pos, GetColorU32(ImGuiCol_Text), text, text_display_end, 0.0f, NULL); + } + if (g.LogEnabled) + LogRenderedText(&pos, text, text_display_end); } // Render a rectangle shaped with optional rounding and borders void ImGui::RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border, float rounding) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - window->DrawList->AddRectFilled(p_min, p_max, fill_col, rounding); - const float border_size = g.Style.FrameBorderSize; - if (border && border_size > 0.0f) - { - window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ImDrawCornerFlags_All, border_size); - window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size); - } + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + window->DrawList->AddRectFilled(p_min, p_max, fill_col, rounding); + const float border_size = g.Style.FrameBorderSize; + if (border && border_size > 0.0f) + { + window->DrawList->AddRect(p_min + ImVec2(1, 1), p_max + ImVec2(1, 1), GetColorU32(ImGuiCol_BorderShadow), rounding, ImDrawCornerFlags_All, border_size); + window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size); + } } void ImGui::RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - const float border_size = g.Style.FrameBorderSize; - if (border_size > 0.0f) - { - window->DrawList->AddRect(p_min+ImVec2(1,1), p_max+ImVec2(1,1), GetColorU32(ImGuiCol_BorderShadow), rounding, ImDrawCornerFlags_All, border_size); - window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size); - } + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + const float border_size = g.Style.FrameBorderSize; + if (border_size > 0.0f) + { + window->DrawList->AddRect(p_min + ImVec2(1, 1), p_max + ImVec2(1, 1), GetColorU32(ImGuiCol_BorderShadow), rounding, ImDrawCornerFlags_All, border_size); + window->DrawList->AddRect(p_min, p_max, GetColorU32(ImGuiCol_Border), rounding, ImDrawCornerFlags_All, border_size); + } } // Render a triangle to denote expanded/collapsed state void ImGui::RenderTriangle(ImVec2 p_min, ImGuiDir dir, float scale) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; - const float h = g.FontSize * 1.00f; - float r = h * 0.40f * scale; - ImVec2 center = p_min + ImVec2(h * 0.50f, h * 0.50f * scale); + const float h = g.FontSize * 1.00f; + float r = h * 0.40f * scale; + ImVec2 center = p_min + ImVec2(h * 0.50f, h * 0.50f * scale); - ImVec2 a, b, c; - switch (dir) - { - case ImGuiDir_Up: - case ImGuiDir_Down: - if (dir == ImGuiDir_Up) r = -r; - center.y -= r * 0.25f; - a = ImVec2(0,1) * r; - b = ImVec2(-0.866f,-0.5f) * r; - c = ImVec2(+0.866f,-0.5f) * r; - break; - case ImGuiDir_Left: - case ImGuiDir_Right: - if (dir == ImGuiDir_Left) r = -r; - center.x -= r * 0.25f; - a = ImVec2(1,0) * r; - b = ImVec2(-0.500f,+0.866f) * r; - c = ImVec2(-0.500f,-0.866f) * r; - break; - case ImGuiDir_None: - case ImGuiDir_Count_: - IM_ASSERT(0); - break; - } + ImVec2 a, b, c; + switch (dir) + { + case ImGuiDir_Up: + case ImGuiDir_Down: + if (dir == ImGuiDir_Up) r = -r; + center.y -= r * 0.25f; + a = ImVec2(0, 1) * r; + b = ImVec2(-0.866f, -0.5f) * r; + c = ImVec2(+0.866f, -0.5f) * r; + break; + case ImGuiDir_Left: + case ImGuiDir_Right: + if (dir == ImGuiDir_Left) r = -r; + center.x -= r * 0.25f; + a = ImVec2(1, 0) * r; + b = ImVec2(-0.500f, +0.866f) * r; + c = ImVec2(-0.500f, -0.866f) * r; + break; + case ImGuiDir_None: + case ImGuiDir_Count_: + IM_ASSERT(0); + break; + } - window->DrawList->AddTriangleFilled(center + a, center + b, center + c, GetColorU32(ImGuiCol_Text)); + window->DrawList->AddTriangleFilled(center + a, center + b, center + c, GetColorU32(ImGuiCol_Text)); } void ImGui::RenderBullet(ImVec2 pos) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - window->DrawList->AddCircleFilled(pos, GImGui->FontSize*0.20f, GetColorU32(ImGuiCol_Text), 8); + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + window->DrawList->AddCircleFilled(pos, GImGui->FontSize * 0.20f, GetColorU32(ImGuiCol_Text), 8); } void ImGui::RenderCheckMark(ImVec2 pos, ImU32 col, float sz) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; - float thickness = ImMax(sz / 5.0f, 1.0f); - sz -= thickness*0.5f; - pos += ImVec2(thickness*0.25f, thickness*0.25f); + float thickness = ImMax(sz / 5.0f, 1.0f); + sz -= thickness * 0.5f; + pos += ImVec2(thickness * 0.25f, thickness * 0.25f); - float third = sz / 3.0f; - float bx = pos.x + third; - float by = pos.y + sz - third*0.5f; - window->DrawList->PathLineTo(ImVec2(bx - third, by - third)); - window->DrawList->PathLineTo(ImVec2(bx, by)); - window->DrawList->PathLineTo(ImVec2(bx + third*2, by - third*2)); - window->DrawList->PathStroke(col, false, thickness); + float third = sz / 3.0f; + float bx = pos.x + third; + float by = pos.y + sz - third * 0.5f; + window->DrawList->PathLineTo(ImVec2(bx - third, by - third)); + window->DrawList->PathLineTo(ImVec2(bx, by)); + window->DrawList->PathLineTo(ImVec2(bx + third * 2, by - third * 2)); + window->DrawList->PathStroke(col, false, thickness); } void ImGui::RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags) { - ImGuiContext& g = *GImGui; - if (id != g.NavId) - return; - if (g.NavDisableHighlight && !(flags & ImGuiNavHighlightFlags_AlwaysDraw)) - return; - ImGuiWindow* window = ImGui::GetCurrentWindow(); - if (window->DC.NavHideHighlightOneFrame) - return; + ImGuiContext& g = *GImGui; + if (id != g.NavId) + return; + if (g.NavDisableHighlight && !(flags & ImGuiNavHighlightFlags_AlwaysDraw)) + return; + ImGuiWindow* window = ImGui::GetCurrentWindow(); + if (window->DC.NavHideHighlightOneFrame) + return; - float rounding = (flags & ImGuiNavHighlightFlags_NoRounding) ? 0.0f : g.Style.FrameRounding; - ImRect display_rect = bb; - display_rect.ClipWith(window->ClipRect); - if (flags & ImGuiNavHighlightFlags_TypeDefault) - { - const float THICKNESS = 2.0f; - const float DISTANCE = 3.0f + THICKNESS * 0.5f; - display_rect.Expand(ImVec2(DISTANCE,DISTANCE)); - bool fully_visible = window->ClipRect.Contains(display_rect); - if (!fully_visible) - window->DrawList->PushClipRect(display_rect.Min, display_rect.Max); - window->DrawList->AddRect(display_rect.Min + ImVec2(THICKNESS*0.5f,THICKNESS*0.5f), display_rect.Max - ImVec2(THICKNESS*0.5f,THICKNESS*0.5f), GetColorU32(ImGuiCol_NavHighlight), rounding, ImDrawCornerFlags_All, THICKNESS); - if (!fully_visible) - window->DrawList->PopClipRect(); - } - if (flags & ImGuiNavHighlightFlags_TypeThin) - { - window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavHighlight), rounding, ~0, 1.0f); - } + float rounding = (flags & ImGuiNavHighlightFlags_NoRounding) ? 0.0f : g.Style.FrameRounding; + ImRect display_rect = bb; + display_rect.ClipWith(window->ClipRect); + if (flags & ImGuiNavHighlightFlags_TypeDefault) + { + const float THICKNESS = 2.0f; + const float DISTANCE = 3.0f + THICKNESS * 0.5f; + display_rect.Expand(ImVec2(DISTANCE, DISTANCE)); + bool fully_visible = window->ClipRect.Contains(display_rect); + if (!fully_visible) + window->DrawList->PushClipRect(display_rect.Min, display_rect.Max); + window->DrawList->AddRect(display_rect.Min + ImVec2(THICKNESS * 0.5f, THICKNESS * 0.5f), display_rect.Max - ImVec2(THICKNESS * 0.5f, THICKNESS * 0.5f), GetColorU32(ImGuiCol_NavHighlight), rounding, ImDrawCornerFlags_All, THICKNESS); + if (!fully_visible) + window->DrawList->PopClipRect(); + } + if (flags & ImGuiNavHighlightFlags_TypeThin) + { + window->DrawList->AddRect(display_rect.Min, display_rect.Max, GetColorU32(ImGuiCol_NavHighlight), rounding, ~0, 1.0f); + } } // Calculate text size. Text can be multi-line. Optionally ignore text after a ## marker. // CalcTextSize("") should return ImVec2(0.0f, GImGui->FontSize) ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_text_after_double_hash, float wrap_width) { - ImGuiContext& g = *GImGui; + ImGuiContext& g = *GImGui; - const char* text_display_end; - if (hide_text_after_double_hash) - text_display_end = FindRenderedTextEnd(text, text_end); // Hide anything after a '##' string - else - text_display_end = text_end; + const char* text_display_end; + if (hide_text_after_double_hash) + text_display_end = FindRenderedTextEnd(text, text_end); // Hide anything after a '##' string + else + text_display_end = text_end; - ImFont* font = g.Font; - const float font_size = g.FontSize; - if (text == text_display_end) - return ImVec2(0.0f, font_size); - ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL); + ImFont* font = g.Font; + const float font_size = g.FontSize; + if (text == text_display_end) + return ImVec2(0.0f, font_size); + ImVec2 text_size = font->CalcTextSizeA(font_size, FLT_MAX, wrap_width, text, text_display_end, NULL); - // Cancel out character spacing for the last character of a line (it is baked into glyph->AdvanceX field) - const float font_scale = font_size / font->FontSize; - const float character_spacing_x = 1.0f * font_scale; - if (text_size.x > 0.0f) - text_size.x -= character_spacing_x; - text_size.x = (float)(int)(text_size.x + 0.95f); + // Cancel out character spacing for the last character of a line (it is baked into glyph->AdvanceX field) + const float font_scale = font_size / font->FontSize; + const float character_spacing_x = 1.0f * font_scale; + if (text_size.x > 0.0f) + text_size.x -= character_spacing_x; + text_size.x = (float)(int)(text_size.x + 0.95f); - return text_size; + return text_size; } // Helper to calculate coarse clipping of large list of evenly sized items. @@ -4426,54 +4509,54 @@ ImVec2 ImGui::CalcTextSize(const char* text, const char* text_end, bool hide_tex // NB: 'items_count' is only used to clamp the result, if you don't know your count you can use INT_MAX void ImGui::CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - if (g.LogEnabled) - { - // If logging is active, do not perform any clipping - *out_items_display_start = 0; - *out_items_display_end = items_count; - return; - } - if (window->SkipItems) - { - *out_items_display_start = *out_items_display_end = 0; - return; - } + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (g.LogEnabled) + { + // If logging is active, do not perform any clipping + *out_items_display_start = 0; + *out_items_display_end = items_count; + return; + } + if (window->SkipItems) + { + *out_items_display_start = *out_items_display_end = 0; + return; + } - const ImVec2 pos = window->DC.CursorPos; - int start = (int)((window->ClipRect.Min.y - pos.y) / items_height); - int end = (int)((window->ClipRect.Max.y - pos.y) / items_height); - if (g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Up) // When performing a navigation request, ensure we have one item extra in the direction we are moving to - start--; - if (g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Down) - end++; + const ImVec2 pos = window->DC.CursorPos; + int start = (int)((window->ClipRect.Min.y - pos.y) / items_height); + int end = (int)((window->ClipRect.Max.y - pos.y) / items_height); + if (g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Up) // When performing a navigation request, ensure we have one item extra in the direction we are moving to + start--; + if (g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Down) + end++; - start = ImClamp(start, 0, items_count); - end = ImClamp(end + 1, start, items_count); - *out_items_display_start = start; - *out_items_display_end = end; + start = ImClamp(start, 0, items_count); + end = ImClamp(end + 1, start, items_count); + *out_items_display_start = start; + *out_items_display_end = end; } // Find window given position, search front-to-back // FIXME: Note that we have a lag here because WindowRectClipped is updated in Begin() so windows moved by user via SetWindowPos() and not SetNextWindowPos() will have that rectangle lagging by a frame at the time FindHoveredWindow() is called, aka before the next Begin(). Moving window thankfully isn't affected. static ImGuiWindow* FindHoveredWindow() { - ImGuiContext& g = *GImGui; - for (int i = g.Windows.Size - 1; i >= 0; i--) - { - ImGuiWindow* window = g.Windows[i]; - if (!window->Active) - continue; - if (window->Flags & ImGuiWindowFlags_NoInputs) - continue; + ImGuiContext& g = *GImGui; + for (int i = g.Windows.Size - 1; i >= 0; i--) + { + ImGuiWindow* window = g.Windows[i]; + if (!window->Active) + continue; + if (window->Flags & ImGuiWindowFlags_NoInputs) + continue; - // Using the clipped AABB, a child window will typically be clipped by its parent (not always) - ImRect bb(window->WindowRectClipped.Min - g.Style.TouchExtraPadding, window->WindowRectClipped.Max + g.Style.TouchExtraPadding); - if (bb.Contains(g.IO.MousePos)) - return window; - } - return NULL; + // Using the clipped AABB, a child window will typically be clipped by its parent (not always) + ImRect bb(window->WindowRectClipped.Min - g.Style.TouchExtraPadding, window->WindowRectClipped.Max + g.Style.TouchExtraPadding); + if (bb.Contains(g.IO.MousePos)) + return window; + } + return NULL; } // Test if mouse cursor is hovering given rectangle @@ -4481,326 +4564,326 @@ static ImGuiWindow* FindHoveredWindow() // NB- Expand the rectangle to be generous on imprecise inputs systems (g.Style.TouchExtraPadding) bool ImGui::IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; - // Clip - ImRect rect_clipped(r_min, r_max); - if (clip) - rect_clipped.ClipWith(window->ClipRect); + // Clip + ImRect rect_clipped(r_min, r_max); + if (clip) + rect_clipped.ClipWith(window->ClipRect); - // Expand for touch input - const ImRect rect_for_touch(rect_clipped.Min - g.Style.TouchExtraPadding, rect_clipped.Max + g.Style.TouchExtraPadding); - return rect_for_touch.Contains(g.IO.MousePos); + // Expand for touch input + const ImRect rect_for_touch(rect_clipped.Min - g.Style.TouchExtraPadding, rect_clipped.Max + g.Style.TouchExtraPadding); + return rect_for_touch.Contains(g.IO.MousePos); } static bool IsKeyPressedMap(ImGuiKey key, bool repeat) { - const int key_index = GImGui->IO.KeyMap[key]; - return (key_index >= 0) ? ImGui::IsKeyPressed(key_index, repeat) : false; + const int key_index = GImGui->IO.KeyMap[key]; + return (key_index >= 0) ? ImGui::IsKeyPressed(key_index, repeat) : false; } int ImGui::GetKeyIndex(ImGuiKey imgui_key) { - IM_ASSERT(imgui_key >= 0 && imgui_key < ImGuiKey_COUNT); - return GImGui->IO.KeyMap[imgui_key]; + IM_ASSERT(imgui_key >= 0 && imgui_key < ImGuiKey_COUNT); + return GImGui->IO.KeyMap[imgui_key]; } // Note that imgui doesn't know the semantic of each entry of io.KeyDown[]. Use your own indices/enums according to how your back-end/engine stored them into KeyDown[]! bool ImGui::IsKeyDown(int user_key_index) { - if (user_key_index < 0) return false; - IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(GImGui->IO.KeysDown)); - return GImGui->IO.KeysDown[user_key_index]; + if (user_key_index < 0) return false; + IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(GImGui->IO.KeysDown)); + return GImGui->IO.KeysDown[user_key_index]; } int ImGui::CalcTypematicPressedRepeatAmount(float t, float t_prev, float repeat_delay, float repeat_rate) { - if (t == 0.0f) - return 1; - if (t <= repeat_delay || repeat_rate <= 0.0f) - return 0; - const int count = (int)((t - repeat_delay) / repeat_rate) - (int)((t_prev - repeat_delay) / repeat_rate); - return (count > 0) ? count : 0; + if (t == 0.0f) + return 1; + if (t <= repeat_delay || repeat_rate <= 0.0f) + return 0; + const int count = (int)((t - repeat_delay) / repeat_rate) - (int)((t_prev - repeat_delay) / repeat_rate); + return (count > 0) ? count : 0; } int ImGui::GetKeyPressedAmount(int key_index, float repeat_delay, float repeat_rate) { - ImGuiContext& g = *GImGui; - if (key_index < 0) return false; - IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(g.IO.KeysDown)); - const float t = g.IO.KeysDownDuration[key_index]; - return CalcTypematicPressedRepeatAmount(t, t - g.IO.DeltaTime, repeat_delay, repeat_rate); + ImGuiContext& g = *GImGui; + if (key_index < 0) return false; + IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(g.IO.KeysDown)); + const float t = g.IO.KeysDownDuration[key_index]; + return CalcTypematicPressedRepeatAmount(t, t - g.IO.DeltaTime, repeat_delay, repeat_rate); } bool ImGui::IsKeyPressed(int user_key_index, bool repeat) { - ImGuiContext& g = *GImGui; - if (user_key_index < 0) return false; - IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(g.IO.KeysDown)); - const float t = g.IO.KeysDownDuration[user_key_index]; - if (t == 0.0f) - return true; - if (repeat && t > g.IO.KeyRepeatDelay) - return GetKeyPressedAmount(user_key_index, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate) > 0; - return false; + ImGuiContext& g = *GImGui; + if (user_key_index < 0) return false; + IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(g.IO.KeysDown)); + const float t = g.IO.KeysDownDuration[user_key_index]; + if (t == 0.0f) + return true; + if (repeat && t > g.IO.KeyRepeatDelay) + return GetKeyPressedAmount(user_key_index, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate) > 0; + return false; } bool ImGui::IsKeyReleased(int user_key_index) { - ImGuiContext& g = *GImGui; - if (user_key_index < 0) return false; - IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(g.IO.KeysDown)); - return g.IO.KeysDownDurationPrev[user_key_index] >= 0.0f && !g.IO.KeysDown[user_key_index]; + ImGuiContext& g = *GImGui; + if (user_key_index < 0) return false; + IM_ASSERT(user_key_index >= 0 && user_key_index < IM_ARRAYSIZE(g.IO.KeysDown)); + return g.IO.KeysDownDurationPrev[user_key_index] >= 0.0f && !g.IO.KeysDown[user_key_index]; } bool ImGui::IsMouseDown(int button) { - ImGuiContext& g = *GImGui; - IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); - return g.IO.MouseDown[button]; + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + return g.IO.MouseDown[button]; } bool ImGui::IsAnyMouseDown() { - ImGuiContext& g = *GImGui; - for (int n = 0; n < IM_ARRAYSIZE(g.IO.MouseDown); n++) - if (g.IO.MouseDown[n]) - return true; - return false; + ImGuiContext& g = *GImGui; + for (int n = 0; n < IM_ARRAYSIZE(g.IO.MouseDown); n++) + if (g.IO.MouseDown[n]) + return true; + return false; } bool ImGui::IsMouseClicked(int button, bool repeat) { - ImGuiContext& g = *GImGui; - IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); - const float t = g.IO.MouseDownDuration[button]; - if (t == 0.0f) - return true; + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + const float t = g.IO.MouseDownDuration[button]; + if (t == 0.0f) + return true; - if (repeat && t > g.IO.KeyRepeatDelay) - { - float delay = g.IO.KeyRepeatDelay, rate = g.IO.KeyRepeatRate; - if ((fmodf(t - delay, rate) > rate*0.5f) != (fmodf(t - delay - g.IO.DeltaTime, rate) > rate*0.5f)) - return true; - } + if (repeat && t > g.IO.KeyRepeatDelay) + { + float delay = g.IO.KeyRepeatDelay, rate = g.IO.KeyRepeatRate; + if ((fmodf(t - delay, rate) > rate * 0.5f) != (fmodf(t - delay - g.IO.DeltaTime, rate) > rate * 0.5f)) + return true; + } - return false; + return false; } bool ImGui::IsMouseReleased(int button) { - ImGuiContext& g = *GImGui; - IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); - return g.IO.MouseReleased[button]; + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + return g.IO.MouseReleased[button]; } bool ImGui::IsMouseDoubleClicked(int button) { - ImGuiContext& g = *GImGui; - IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); - return g.IO.MouseDoubleClicked[button]; + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + return g.IO.MouseDoubleClicked[button]; } bool ImGui::IsMouseDragging(int button, float lock_threshold) { - ImGuiContext& g = *GImGui; - IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); - if (!g.IO.MouseDown[button]) - return false; - if (lock_threshold < 0.0f) - lock_threshold = g.IO.MouseDragThreshold; - return g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold; + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + if (!g.IO.MouseDown[button]) + return false; + if (lock_threshold < 0.0f) + lock_threshold = g.IO.MouseDragThreshold; + return g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold; } ImVec2 ImGui::GetMousePos() { - return GImGui->IO.MousePos; + return GImGui->IO.MousePos; } // NB: prefer to call right after BeginPopup(). At the time Selectable/MenuItem is activated, the popup is already closed! ImVec2 ImGui::GetMousePosOnOpeningCurrentPopup() { - ImGuiContext& g = *GImGui; - if (g.CurrentPopupStack.Size > 0) - return g.OpenPopupStack[g.CurrentPopupStack.Size-1].OpenMousePos; - return g.IO.MousePos; + ImGuiContext& g = *GImGui; + if (g.CurrentPopupStack.Size > 0) + return g.OpenPopupStack[g.CurrentPopupStack.Size - 1].OpenMousePos; + return g.IO.MousePos; } // We typically use ImVec2(-FLT_MAX,-FLT_MAX) to denote an invalid mouse position bool ImGui::IsMousePosValid(const ImVec2* mouse_pos) { - if (mouse_pos == NULL) - mouse_pos = &GImGui->IO.MousePos; - const float MOUSE_INVALID = -256000.0f; - return mouse_pos->x >= MOUSE_INVALID && mouse_pos->y >= MOUSE_INVALID; + if (mouse_pos == NULL) + mouse_pos = &GImGui->IO.MousePos; + const float MOUSE_INVALID = -256000.0f; + return mouse_pos->x >= MOUSE_INVALID && mouse_pos->y >= MOUSE_INVALID; } // NB: This is only valid if IsMousePosValid(). Back-ends in theory should always keep mouse position valid when dragging even outside the client window. ImVec2 ImGui::GetMouseDragDelta(int button, float lock_threshold) { - ImGuiContext& g = *GImGui; - IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); - if (lock_threshold < 0.0f) - lock_threshold = g.IO.MouseDragThreshold; - if (g.IO.MouseDown[button]) - if (g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold) - return g.IO.MousePos - g.IO.MouseClickedPos[button]; // Assume we can only get active with left-mouse button (at the moment). - return ImVec2(0.0f, 0.0f); + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + if (lock_threshold < 0.0f) + lock_threshold = g.IO.MouseDragThreshold; + if (g.IO.MouseDown[button]) + if (g.IO.MouseDragMaxDistanceSqr[button] >= lock_threshold * lock_threshold) + return g.IO.MousePos - g.IO.MouseClickedPos[button]; // Assume we can only get active with left-mouse button (at the moment). + return ImVec2(0.0f, 0.0f); } void ImGui::ResetMouseDragDelta(int button) { - ImGuiContext& g = *GImGui; - IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); - // NB: We don't need to reset g.IO.MouseDragMaxDistanceSqr - g.IO.MouseClickedPos[button] = g.IO.MousePos; + ImGuiContext& g = *GImGui; + IM_ASSERT(button >= 0 && button < IM_ARRAYSIZE(g.IO.MouseDown)); + // NB: We don't need to reset g.IO.MouseDragMaxDistanceSqr + g.IO.MouseClickedPos[button] = g.IO.MousePos; } ImGuiMouseCursor ImGui::GetMouseCursor() { - return GImGui->MouseCursor; + return GImGui->MouseCursor; } void ImGui::SetMouseCursor(ImGuiMouseCursor cursor_type) { - GImGui->MouseCursor = cursor_type; + GImGui->MouseCursor = cursor_type; } void ImGui::CaptureKeyboardFromApp(bool capture) { - GImGui->WantCaptureKeyboardNextFrame = capture ? 1 : 0; + GImGui->WantCaptureKeyboardNextFrame = capture ? 1 : 0; } void ImGui::CaptureMouseFromApp(bool capture) { - GImGui->WantCaptureMouseNextFrame = capture ? 1 : 0; + GImGui->WantCaptureMouseNextFrame = capture ? 1 : 0; } bool ImGui::IsItemActive() { - ImGuiContext& g = *GImGui; - if (g.ActiveId) - { - ImGuiWindow* window = g.CurrentWindow; - return g.ActiveId == window->DC.LastItemId; - } - return false; + ImGuiContext& g = *GImGui; + if (g.ActiveId) + { + ImGuiWindow* window = g.CurrentWindow; + return g.ActiveId == window->DC.LastItemId; + } + return false; } bool ImGui::IsItemFocused() { - ImGuiContext& g = *GImGui; - return g.NavId && !g.NavDisableHighlight && g.NavId == g.CurrentWindow->DC.LastItemId; + ImGuiContext& g = *GImGui; + return g.NavId && !g.NavDisableHighlight && g.NavId == g.CurrentWindow->DC.LastItemId; } bool ImGui::IsItemClicked(int mouse_button) { - return IsMouseClicked(mouse_button) && IsItemHovered(ImGuiHoveredFlags_Default); + return IsMouseClicked(mouse_button) && IsItemHovered(ImGuiHoveredFlags_Default); } bool ImGui::IsAnyItemHovered() { - ImGuiContext& g = *GImGui; - return g.HoveredId != 0 || g.HoveredIdPreviousFrame != 0; + ImGuiContext& g = *GImGui; + return g.HoveredId != 0 || g.HoveredIdPreviousFrame != 0; } bool ImGui::IsAnyItemActive() { - ImGuiContext& g = *GImGui; - return g.ActiveId != 0; + ImGuiContext& g = *GImGui; + return g.ActiveId != 0; } bool ImGui::IsAnyItemFocused() { - ImGuiContext& g = *GImGui; - return g.NavId != 0 && !g.NavDisableHighlight; + ImGuiContext& g = *GImGui; + return g.NavId != 0 && !g.NavDisableHighlight; } bool ImGui::IsItemVisible() { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->ClipRect.Overlaps(window->DC.LastItemRect); + ImGuiWindow* window = GetCurrentWindowRead(); + return window->ClipRect.Overlaps(window->DC.LastItemRect); } // Allow last item to be overlapped by a subsequent item. Both may be activated during the same frame before the later one takes priority. void ImGui::SetItemAllowOverlap() { - ImGuiContext& g = *GImGui; - if (g.HoveredId == g.CurrentWindow->DC.LastItemId) - g.HoveredIdAllowOverlap = true; - if (g.ActiveId == g.CurrentWindow->DC.LastItemId) - g.ActiveIdAllowOverlap = true; + ImGuiContext& g = *GImGui; + if (g.HoveredId == g.CurrentWindow->DC.LastItemId) + g.HoveredIdAllowOverlap = true; + if (g.ActiveId == g.CurrentWindow->DC.LastItemId) + g.ActiveIdAllowOverlap = true; } ImVec2 ImGui::GetItemRectMin() { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.LastItemRect.Min; + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.LastItemRect.Min; } ImVec2 ImGui::GetItemRectMax() { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.LastItemRect.Max; + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.LastItemRect.Max; } ImVec2 ImGui::GetItemRectSize() { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.LastItemRect.GetSize(); + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.LastItemRect.GetSize(); } static ImRect GetViewportRect() { - ImGuiContext& g = *GImGui; - if (g.IO.DisplayVisibleMin.x != g.IO.DisplayVisibleMax.x && g.IO.DisplayVisibleMin.y != g.IO.DisplayVisibleMax.y) - return ImRect(g.IO.DisplayVisibleMin, g.IO.DisplayVisibleMax); - return ImRect(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y); + ImGuiContext& g = *GImGui; + if (g.IO.DisplayVisibleMin.x != g.IO.DisplayVisibleMax.x && g.IO.DisplayVisibleMin.y != g.IO.DisplayVisibleMax.y) + return ImRect(g.IO.DisplayVisibleMin, g.IO.DisplayVisibleMax); + return ImRect(0.0f, 0.0f, g.IO.DisplaySize.x, g.IO.DisplaySize.y); } // Not exposed publicly as BeginTooltip() because bool parameters are evil. Let's see if other needs arise first. void ImGui::BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_tooltip) { - ImGuiContext& g = *GImGui; - char window_name[16]; - ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip_%02d", g.TooltipOverrideCount); - if (override_previous_tooltip) - if (ImGuiWindow* window = FindWindowByName(window_name)) - if (window->Active) - { - // Hide previous tooltips. We can't easily "reset" the content of a window so we create a new one. - window->HiddenFrames = 1; - ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip_%02d", ++g.TooltipOverrideCount); - } - ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip|ImGuiWindowFlags_NoInputs|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoNav; - Begin(window_name, NULL, flags | extra_flags); + ImGuiContext& g = *GImGui; + char window_name[16]; + ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip_%02d", g.TooltipOverrideCount); + if (override_previous_tooltip) + if (ImGuiWindow* window = FindWindowByName(window_name)) + if (window->Active) + { + // Hide previous tooltips. We can't easily "reset" the content of a window so we create a new one. + window->HiddenFrames = 1; + ImFormatString(window_name, IM_ARRAYSIZE(window_name), "##Tooltip_%02d", ++g.TooltipOverrideCount); + } + ImGuiWindowFlags flags = ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoNav; + Begin(window_name, NULL, flags | extra_flags); } void ImGui::SetTooltipV(const char* fmt, va_list args) { - BeginTooltipEx(0, true); - TextV(fmt, args); - EndTooltip(); + BeginTooltipEx(0, true); + TextV(fmt, args); + EndTooltip(); } void ImGui::SetTooltip(const char* fmt, ...) { - va_list args; - va_start(args, fmt); - SetTooltipV(fmt, args); - va_end(args); + va_list args; + va_start(args, fmt); + SetTooltipV(fmt, args); + va_end(args); } void ImGui::BeginTooltip() { - BeginTooltipEx(0, false); + BeginTooltipEx(0, false); } void ImGui::EndTooltip() { - IM_ASSERT(GetCurrentWindowRead()->Flags & ImGuiWindowFlags_Tooltip); // Mismatched BeginTooltip()/EndTooltip() calls - End(); + IM_ASSERT(GetCurrentWindowRead()->Flags & ImGuiWindowFlags_Tooltip); // Mismatched BeginTooltip()/EndTooltip() calls + End(); } // Mark popup as open (toggle toward open state). @@ -4809,230 +4892,231 @@ void ImGui::EndTooltip() // One open popup per level of the popup hierarchy (NB: when assigning we reset the Window member of ImGuiPopupRef to NULL) void ImGui::OpenPopupEx(ImGuiID id) { - ImGuiContext& g = *GImGui; - ImGuiWindow* parent_window = g.CurrentWindow; - int current_stack_size = g.CurrentPopupStack.Size; - ImGuiPopupRef popup_ref; // Tagged as new ref as Window will be set back to NULL if we write this into OpenPopupStack. - popup_ref.PopupId = id; - popup_ref.Window = NULL; - popup_ref.ParentWindow = parent_window; - popup_ref.OpenFrameCount = g.FrameCount; - popup_ref.OpenParentId = parent_window->IDStack.back(); - popup_ref.OpenMousePos = g.IO.MousePos; - popup_ref.OpenPopupPos = (!g.NavDisableHighlight && g.NavDisableMouseHover) ? NavCalcPreferredMousePos() : g.IO.MousePos; + ImGuiContext& g = *GImGui; + ImGuiWindow* parent_window = g.CurrentWindow; + int current_stack_size = g.CurrentPopupStack.Size; + ImGuiPopupRef popup_ref; // Tagged as new ref as Window will be set back to NULL if we write this into OpenPopupStack. + popup_ref.PopupId = id; + popup_ref.Window = NULL; + popup_ref.ParentWindow = parent_window; + popup_ref.OpenFrameCount = g.FrameCount; + popup_ref.OpenParentId = parent_window->IDStack.back(); + popup_ref.OpenMousePos = g.IO.MousePos; + popup_ref.OpenPopupPos = (!g.NavDisableHighlight && g.NavDisableMouseHover) ? NavCalcPreferredMousePos() : g.IO.MousePos; - if (g.OpenPopupStack.Size < current_stack_size + 1) - { - g.OpenPopupStack.push_back(popup_ref); - } - else - { - // Close child popups if any - g.OpenPopupStack.resize(current_stack_size + 1); + if (g.OpenPopupStack.Size < current_stack_size + 1) + { + g.OpenPopupStack.push_back(popup_ref); + } + else + { + // Close child popups if any + g.OpenPopupStack.resize(current_stack_size + 1); - // Gently handle the user mistakenly calling OpenPopup() every frame. It is a programming mistake! However, if we were to run the regular code path, the ui - // would become completely unusable because the popup will always be in hidden-while-calculating-size state _while_ claiming focus. Which would be a very confusing - // situation for the programmer. Instead, we silently allow the popup to proceed, it will keep reappearing and the programming error will be more obvious to understand. - if (g.OpenPopupStack[current_stack_size].PopupId == id && g.OpenPopupStack[current_stack_size].OpenFrameCount == g.FrameCount - 1) - g.OpenPopupStack[current_stack_size].OpenFrameCount = popup_ref.OpenFrameCount; - else - g.OpenPopupStack[current_stack_size] = popup_ref; + // Gently handle the user mistakenly calling OpenPopup() every frame. It is a programming mistake! However, if we were to run the regular code path, the ui + // would become completely unusable because the popup will always be in hidden-while-calculating-size state _while_ claiming focus. Which would be a very confusing + // situation for the programmer. Instead, we silently allow the popup to proceed, it will keep reappearing and the programming error will be more obvious to understand. + if (g.OpenPopupStack[current_stack_size].PopupId == id && g.OpenPopupStack[current_stack_size].OpenFrameCount == g.FrameCount - 1) + g.OpenPopupStack[current_stack_size].OpenFrameCount = popup_ref.OpenFrameCount; + else + g.OpenPopupStack[current_stack_size] = popup_ref; - // When reopening a popup we first refocus its parent, otherwise if its parent is itself a popup it would get closed by ClosePopupsOverWindow(). - // This is equivalent to what ClosePopupToLevel() does. - //if (g.OpenPopupStack[current_stack_size].PopupId == id) - // FocusWindow(parent_window); - } + // When reopening a popup we first refocus its parent, otherwise if its parent is itself a popup it would get closed by ClosePopupsOverWindow(). + // This is equivalent to what ClosePopupToLevel() does. + //if (g.OpenPopupStack[current_stack_size].PopupId == id) + // FocusWindow(parent_window); + } } void ImGui::OpenPopup(const char* str_id) { - ImGuiContext& g = *GImGui; - OpenPopupEx(g.CurrentWindow->GetID(str_id)); + ImGuiContext& g = *GImGui; + OpenPopupEx(g.CurrentWindow->GetID(str_id)); } void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window) { - ImGuiContext& g = *GImGui; - if (g.OpenPopupStack.empty()) - return; + ImGuiContext& g = *GImGui; + if (g.OpenPopupStack.empty()) + return; - // When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it. - // Don't close our own child popup windows. - int n = 0; - if (ref_window) - { - for (n = 0; n < g.OpenPopupStack.Size; n++) - { - ImGuiPopupRef& popup = g.OpenPopupStack[n]; - if (!popup.Window) - continue; - IM_ASSERT((popup.Window->Flags & ImGuiWindowFlags_Popup) != 0); - if (popup.Window->Flags & ImGuiWindowFlags_ChildWindow) - continue; + // When popups are stacked, clicking on a lower level popups puts focus back to it and close popups above it. + // Don't close our own child popup windows. + int n = 0; + if (ref_window) + { + for (n = 0; n < g.OpenPopupStack.Size; n++) + { + ImGuiPopupRef& popup = g.OpenPopupStack[n]; + if (!popup.Window) + continue; + IM_ASSERT((popup.Window->Flags & ImGuiWindowFlags_Popup) != 0); + if (popup.Window->Flags & ImGuiWindowFlags_ChildWindow) + continue; - // Trim the stack if popups are not direct descendant of the reference window (which is often the NavWindow) - bool has_focus = false; - for (int m = n; m < g.OpenPopupStack.Size && !has_focus; m++) - has_focus = (g.OpenPopupStack[m].Window && g.OpenPopupStack[m].Window->RootWindow == ref_window->RootWindow); - if (!has_focus) - break; - } - } - if (n < g.OpenPopupStack.Size) // This test is not required but it allows to set a convenient breakpoint on the block below - ClosePopupToLevel(n); + // Trim the stack if popups are not direct descendant of the reference window (which is often the NavWindow) + bool has_focus = false; + for (int m = n; m < g.OpenPopupStack.Size && !has_focus; m++) + has_focus = (g.OpenPopupStack[m].Window && g.OpenPopupStack[m].Window->RootWindow == ref_window->RootWindow); + if (!has_focus) + break; + } + } + if (n < g.OpenPopupStack.Size) // This test is not required but it allows to set a convenient breakpoint on the block below + ClosePopupToLevel(n); } static ImGuiWindow* GetFrontMostModalRootWindow() { - ImGuiContext& g = *GImGui; - for (int n = g.OpenPopupStack.Size-1; n >= 0; n--) - if (ImGuiWindow* popup = g.OpenPopupStack.Data[n].Window) - if (popup->Flags & ImGuiWindowFlags_Modal) - return popup; - return NULL; + ImGuiContext& g = *GImGui; + for (int n = g.OpenPopupStack.Size - 1; n >= 0; n--) + if (ImGuiWindow* popup = g.OpenPopupStack.Data[n].Window) + if (popup->Flags & ImGuiWindowFlags_Modal) + return popup; + return NULL; } static void ClosePopupToLevel(int remaining) { - IM_ASSERT(remaining >= 0); - ImGuiContext& g = *GImGui; - ImGuiWindow* focus_window = (remaining > 0) ? g.OpenPopupStack[remaining-1].Window : g.OpenPopupStack[0].ParentWindow; - if (g.NavLayer == 0) - focus_window = NavRestoreLastChildNavWindow(focus_window); - ImGui::FocusWindow(focus_window); - focus_window->DC.NavHideHighlightOneFrame = true; - g.OpenPopupStack.resize(remaining); + IM_ASSERT(remaining >= 0); + ImGuiContext& g = *GImGui; + ImGuiWindow* focus_window = (remaining > 0) ? g.OpenPopupStack[remaining - 1].Window : g.OpenPopupStack[0].ParentWindow; + if (g.NavLayer == 0) + focus_window = NavRestoreLastChildNavWindow(focus_window); + ImGui::FocusWindow(focus_window); + focus_window->DC.NavHideHighlightOneFrame = true; + g.OpenPopupStack.resize(remaining); } void ImGui::ClosePopup(ImGuiID id) { - if (!IsPopupOpen(id)) - return; - ImGuiContext& g = *GImGui; - ClosePopupToLevel(g.OpenPopupStack.Size - 1); + if (!IsPopupOpen(id)) + return; + ImGuiContext& g = *GImGui; + ClosePopupToLevel(g.OpenPopupStack.Size - 1); } // Close the popup we have begin-ed into. void ImGui::CloseCurrentPopup() { - ImGuiContext& g = *GImGui; - int popup_idx = g.CurrentPopupStack.Size - 1; - if (popup_idx < 0 || popup_idx >= g.OpenPopupStack.Size || g.CurrentPopupStack[popup_idx].PopupId != g.OpenPopupStack[popup_idx].PopupId) - return; - while (popup_idx > 0 && g.OpenPopupStack[popup_idx].Window && (g.OpenPopupStack[popup_idx].Window->Flags & ImGuiWindowFlags_ChildMenu)) - popup_idx--; - ClosePopupToLevel(popup_idx); + ImGuiContext& g = *GImGui; + int popup_idx = g.CurrentPopupStack.Size - 1; + if (popup_idx < 0 || popup_idx >= g.OpenPopupStack.Size || g.CurrentPopupStack[popup_idx].PopupId != g.OpenPopupStack[popup_idx].PopupId) + return; + while (popup_idx > 0 && g.OpenPopupStack[popup_idx].Window && (g.OpenPopupStack[popup_idx].Window->Flags & ImGuiWindowFlags_ChildMenu)) + popup_idx--; + ClosePopupToLevel(popup_idx); } bool ImGui::BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags) { - ImGuiContext& g = *GImGui; - if (!IsPopupOpen(id)) - { - g.NextWindowData.Clear(); // We behave like Begin() and need to consume those values - return false; - } + ImGuiContext& g = *GImGui; + if (!IsPopupOpen(id)) + { + g.NextWindowData.Clear(); // We behave like Begin() and need to consume those values + return false; + } - char name[20]; - if (extra_flags & ImGuiWindowFlags_ChildMenu) - ImFormatString(name, IM_ARRAYSIZE(name), "##Menu_%02d", g.CurrentPopupStack.Size); // Recycle windows based on depth - else - ImFormatString(name, IM_ARRAYSIZE(name), "##Popup_%08x", id); // Not recycling, so we can close/open during the same frame + char name[20]; + if (extra_flags & ImGuiWindowFlags_ChildMenu) + ImFormatString(name, IM_ARRAYSIZE(name), "##Menu_%02d", g.CurrentPopupStack.Size); // Recycle windows based on depth + else + ImFormatString(name, IM_ARRAYSIZE(name), "##Popup_%08x", id); // Not recycling, so we can close/open during the same frame - bool is_open = Begin(name, NULL, extra_flags | ImGuiWindowFlags_Popup); - if (!is_open) // NB: Begin can return false when the popup is completely clipped (e.g. zero size display) - EndPopup(); + bool is_open = Begin(name, NULL, extra_flags | ImGuiWindowFlags_Popup); + if (!is_open) // NB: Begin can return false when the popup is completely clipped (e.g. zero size display) + EndPopup(); - return is_open; + return is_open; } bool ImGui::BeginPopup(const char* str_id, ImGuiWindowFlags flags) { - ImGuiContext& g = *GImGui; - if (g.OpenPopupStack.Size <= g.CurrentPopupStack.Size) // Early out for performance - { - g.NextWindowData.Clear(); // We behave like Begin() and need to consume those values - return false; - } - return BeginPopupEx(g.CurrentWindow->GetID(str_id), flags|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); + ImGuiContext& g = *GImGui; + if (g.OpenPopupStack.Size <= g.CurrentPopupStack.Size) // Early out for performance + { + g.NextWindowData.Clear(); // We behave like Begin() and need to consume those values + return false; + } + return BeginPopupEx(g.CurrentWindow->GetID(str_id), flags | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings); } bool ImGui::IsPopupOpen(ImGuiID id) { - ImGuiContext& g = *GImGui; - return g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].PopupId == id; + ImGuiContext& g = *GImGui; + return g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].PopupId == id; } bool ImGui::IsPopupOpen(const char* str_id) { - ImGuiContext& g = *GImGui; - return g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].PopupId == g.CurrentWindow->GetID(str_id); + ImGuiContext& g = *GImGui; + return g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].PopupId == g.CurrentWindow->GetID(str_id); } bool ImGui::BeginPopupModal(const char* name, bool* p_open, ImGuiWindowFlags flags) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - const ImGuiID id = window->GetID(name); - if (!IsPopupOpen(id)) - { - g.NextWindowData.Clear(); // We behave like Begin() and need to consume those values - return false; - } + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + const ImGuiID id = window->GetID(name); + if (!IsPopupOpen(id)) + { + g.NextWindowData.Clear(); // We behave like Begin() and need to consume those values + return false; + } - // Center modal windows by default - // FIXME: Should test for (PosCond & window->SetWindowPosAllowFlags) with the upcoming window. - if (g.NextWindowData.PosCond == 0) - SetNextWindowPos(g.IO.DisplaySize * 0.5f, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); + // Center modal windows by default + // FIXME: Should test for (PosCond & window->SetWindowPosAllowFlags) with the upcoming window. + if (g.NextWindowData.PosCond == 0) + SetNextWindowPos(g.IO.DisplaySize * 0.5f, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); - bool is_open = Begin(name, p_open, flags | ImGuiWindowFlags_Popup | ImGuiWindowFlags_Modal | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings); - if (!is_open || (p_open && !*p_open)) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display) - { - EndPopup(); - if (is_open) - ClosePopup(id); - return false; - } + bool is_open = Begin(name, p_open, flags | ImGuiWindowFlags_Popup | ImGuiWindowFlags_Modal | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoSavedSettings); + if (!is_open || (p_open && !*p_open)) // NB: is_open can be 'false' when the popup is completely clipped (e.g. zero size display) + { + EndPopup(); + if (is_open) + ClosePopup(id); + return false; + } - return is_open; + return is_open; } static void NavProcessMoveRequestWrapAround(ImGuiWindow* window) { - ImGuiContext& g = *GImGui; - if (g.NavWindow == window && NavMoveRequestButNoResultYet()) - if ((g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down) && g.NavMoveRequestForward == ImGuiNavForward_None && g.NavLayer == 0) - { - g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued; - ImGui::NavMoveRequestCancel(); - g.NavWindow->NavRectRel[0].Min.y = g.NavWindow->NavRectRel[0].Max.y = ((g.NavMoveDir == ImGuiDir_Up) ? ImMax(window->SizeFull.y, window->SizeContents.y) : 0.0f) - window->Scroll.y; - } + ImGuiContext& g = *GImGui; + if (g.NavWindow == window && NavMoveRequestButNoResultYet()) + if ((g.NavMoveDir == ImGuiDir_Up || g.NavMoveDir == ImGuiDir_Down) && g.NavMoveRequestForward == ImGuiNavForward_None && g.NavLayer == 0) + { + g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued; + ImGui::NavMoveRequestCancel(); + g.NavWindow->NavRectRel[0].Min.y = g.NavWindow->NavRectRel[0].Max.y = ((g.NavMoveDir == ImGuiDir_Up) ? ImMax(window->SizeFull.y, window->SizeContents.y) : 0.0f) - window->Scroll.y; + } } void ImGui::EndPopup() { - ImGuiContext& g = *GImGui; (void)g; - IM_ASSERT(g.CurrentWindow->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginPopup()/EndPopup() calls - IM_ASSERT(g.CurrentPopupStack.Size > 0); + ImGuiContext& g = *GImGui; + (void)g; + IM_ASSERT(g.CurrentWindow->Flags & ImGuiWindowFlags_Popup); // Mismatched BeginPopup()/EndPopup() calls + IM_ASSERT(g.CurrentPopupStack.Size > 0); - // Make all menus and popups wrap around for now, may need to expose that policy. - NavProcessMoveRequestWrapAround(g.CurrentWindow); - - End(); + // Make all menus and popups wrap around for now, may need to expose that policy. + NavProcessMoveRequestWrapAround(g.CurrentWindow); + + End(); } bool ImGui::OpenPopupOnItemClick(const char* str_id, int mouse_button) { - ImGuiWindow* window = GImGui->CurrentWindow; - if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) - { - ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! - IM_ASSERT(id != 0); // However, you cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) - OpenPopupEx(id); - return true; - } - return false; + ImGuiWindow* window = GImGui->CurrentWindow; + if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) + { + ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! + IM_ASSERT(id != 0); // However, you cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) + OpenPopupEx(id); + return true; + } + return false; } // This is a helper to handle the simplest case of associating one named popup to one given widget. @@ -5040,539 +5124,597 @@ bool ImGui::OpenPopupOnItemClick(const char* str_id, int mouse_button) // You can pass a NULL str_id to use the identifier of the last item. bool ImGui::BeginPopupContextItem(const char* str_id, int mouse_button) { - ImGuiWindow* window = GImGui->CurrentWindow; - ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! - IM_ASSERT(id != 0); // However, you cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) - if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) - OpenPopupEx(id); - return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); + ImGuiWindow* window = GImGui->CurrentWindow; + ImGuiID id = str_id ? window->GetID(str_id) : window->DC.LastItemId; // If user hasn't passed an ID, we can use the LastItemID. Using LastItemID as a Popup ID won't conflict! + IM_ASSERT(id != 0); // However, you cannot pass a NULL str_id if the last item has no identifier (e.g. a Text() item) + if (IsMouseReleased(mouse_button) && IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) + OpenPopupEx(id); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings); } bool ImGui::BeginPopupContextWindow(const char* str_id, int mouse_button, bool also_over_items) { - if (!str_id) - str_id = "window_context"; - ImGuiID id = GImGui->CurrentWindow->GetID(str_id); - if (IsMouseReleased(mouse_button) && IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) - if (also_over_items || !IsAnyItemHovered()) - OpenPopupEx(id); - return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); + if (!str_id) + str_id = "window_context"; + ImGuiID id = GImGui->CurrentWindow->GetID(str_id); + if (IsMouseReleased(mouse_button) && IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup)) + if (also_over_items || !IsAnyItemHovered()) + OpenPopupEx(id); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings); } bool ImGui::BeginPopupContextVoid(const char* str_id, int mouse_button) { - if (!str_id) - str_id = "void_context"; - ImGuiID id = GImGui->CurrentWindow->GetID(str_id); - if (IsMouseReleased(mouse_button) && !IsWindowHovered(ImGuiHoveredFlags_AnyWindow)) - OpenPopupEx(id); - return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoSavedSettings); + if (!str_id) + str_id = "void_context"; + ImGuiID id = GImGui->CurrentWindow->GetID(str_id); + if (IsMouseReleased(mouse_button) && !IsWindowHovered(ImGuiHoveredFlags_AnyWindow)) + OpenPopupEx(id); + return BeginPopupEx(id, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings); } static bool BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags) { - ImGuiContext& g = *GImGui; - ImGuiWindow* parent_window = ImGui::GetCurrentWindow(); - ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_ChildWindow; - flags |= (parent_window->Flags & ImGuiWindowFlags_NoMove); // Inherit the NoMove flag + ImGuiContext& g = *GImGui; + ImGuiWindow* parent_window = ImGui::GetCurrentWindow(); + ImGuiWindowFlags flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_ChildWindow; + flags |= (parent_window->Flags & ImGuiWindowFlags_NoMove); // Inherit the NoMove flag - const ImVec2 content_avail = ImGui::GetContentRegionAvail(); - ImVec2 size = ImFloor(size_arg); - const int auto_fit_axises = ((size.x == 0.0f) ? (1 << ImGuiAxis_X) : 0x00) | ((size.y == 0.0f) ? (1 << ImGuiAxis_Y) : 0x00); - if (size.x <= 0.0f) - size.x = ImMax(content_avail.x + size.x, 4.0f); // Arbitrary minimum child size (0.0f causing too much issues) - if (size.y <= 0.0f) - size.y = ImMax(content_avail.y + size.y, 4.0f); + const ImVec2 content_avail = ImGui::GetContentRegionAvail(); + ImVec2 size = ImFloor(size_arg); + const int auto_fit_axises = ((size.x == 0.0f) ? (1 << ImGuiAxis_X) : 0x00) | ((size.y == 0.0f) ? (1 << ImGuiAxis_Y) : 0x00); + if (size.x <= 0.0f) + size.x = ImMax(content_avail.x + size.x, 4.0f); // Arbitrary minimum child size (0.0f causing too much issues) + if (size.y <= 0.0f) + size.y = ImMax(content_avail.y + size.y, 4.0f); - const float backup_border_size = g.Style.ChildBorderSize; - if (!border) - g.Style.ChildBorderSize = 0.0f; - flags |= extra_flags; + const float backup_border_size = g.Style.ChildBorderSize; + if (!border) + g.Style.ChildBorderSize = 0.0f; + flags |= extra_flags; - char title[256]; - if (name) - ImFormatString(title, IM_ARRAYSIZE(title), "%s/%s_%08X", parent_window->Name, name, id); - else - ImFormatString(title, IM_ARRAYSIZE(title), "%s/%08X", parent_window->Name, id); + char title[256]; + if (name) + ImFormatString(title, IM_ARRAYSIZE(title), "%s/%s_%08X", parent_window->Name, name, id); + else + ImFormatString(title, IM_ARRAYSIZE(title), "%s/%08X", parent_window->Name, id); - ImGui::SetNextWindowSize(size); - bool ret = ImGui::Begin(title, NULL, flags); - ImGuiWindow* child_window = ImGui::GetCurrentWindow(); - child_window->ChildId = id; - child_window->AutoFitChildAxises = auto_fit_axises; - g.Style.ChildBorderSize = backup_border_size; + ImGui::SetNextWindowSize(size); + bool ret = ImGui::Begin(title, NULL, flags); + ImGuiWindow* child_window = ImGui::GetCurrentWindow(); + child_window->ChildId = id; + child_window->AutoFitChildAxises = auto_fit_axises; + g.Style.ChildBorderSize = backup_border_size; - // Process navigation-in immediately so NavInit can run on first frame - if (!(flags & ImGuiWindowFlags_NavFlattened) && (child_window->DC.NavLayerActiveMask != 0 || child_window->DC.NavHasScroll) && g.NavActivateId == id) - { - ImGui::FocusWindow(child_window); - ImGui::NavInitWindow(child_window, false); - ImGui::SetActiveID(id+1, child_window); // Steal ActiveId with a dummy id so that key-press won't activate child item - g.ActiveIdSource = ImGuiInputSource_Nav; - } + // Process navigation-in immediately so NavInit can run on first frame + if (!(flags & ImGuiWindowFlags_NavFlattened) && (child_window->DC.NavLayerActiveMask != 0 || child_window->DC.NavHasScroll) && g.NavActivateId == id) + { + ImGui::FocusWindow(child_window); + ImGui::NavInitWindow(child_window, false); + ImGui::SetActiveID(id + 1, child_window); // Steal ActiveId with a dummy id so that key-press won't activate child item + g.ActiveIdSource = ImGuiInputSource_Nav; + } - return ret; + return ret; } bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags) { - ImGuiWindow* window = GetCurrentWindow(); - return BeginChildEx(str_id, window->GetID(str_id), size_arg, border, extra_flags); + ImGuiWindow* window = GetCurrentWindow(); + return BeginChildEx(str_id, window->GetID(str_id), size_arg, border, extra_flags); } bool ImGui::BeginChild(ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags) { - IM_ASSERT(id != 0); - return BeginChildEx(NULL, id, size_arg, border, extra_flags); + IM_ASSERT(id != 0); + return BeginChildEx(NULL, id, size_arg, border, extra_flags); } void ImGui::EndChild() { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; - IM_ASSERT(window->Flags & ImGuiWindowFlags_ChildWindow); // Mismatched BeginChild()/EndChild() callss - if (window->BeginCount > 1) - { - End(); - } - else - { - // When using auto-filling child window, we don't provide full width/height to ItemSize so that it doesn't feed back into automatic size-fitting. - ImVec2 sz = GetWindowSize(); - if (window->AutoFitChildAxises & (1 << ImGuiAxis_X)) // Arbitrary minimum zero-ish child size of 4.0f causes less trouble than a 0.0f - sz.x = ImMax(4.0f, sz.x); - if (window->AutoFitChildAxises & (1 << ImGuiAxis_Y)) - sz.y = ImMax(4.0f, sz.y); - End(); + IM_ASSERT(window->Flags & ImGuiWindowFlags_ChildWindow); // Mismatched BeginChild()/EndChild() callss + if (window->BeginCount > 1) + { + End(); + } + else + { + // When using auto-filling child window, we don't provide full width/height to ItemSize so that it doesn't feed back into automatic size-fitting. + ImVec2 sz = GetWindowSize(); + if (window->AutoFitChildAxises & (1 << ImGuiAxis_X)) // Arbitrary minimum zero-ish child size of 4.0f causes less trouble than a 0.0f + sz.x = ImMax(4.0f, sz.x); + if (window->AutoFitChildAxises & (1 << ImGuiAxis_Y)) + sz.y = ImMax(4.0f, sz.y); + End(); - ImGuiWindow* parent_window = g.CurrentWindow; - ImRect bb(parent_window->DC.CursorPos, parent_window->DC.CursorPos + sz); - ItemSize(sz); - if ((window->DC.NavLayerActiveMask != 0 || window->DC.NavHasScroll) && !(window->Flags & ImGuiWindowFlags_NavFlattened)) - { - ItemAdd(bb, window->ChildId); - RenderNavHighlight(bb, window->ChildId); + ImGuiWindow* parent_window = g.CurrentWindow; + ImRect bb(parent_window->DC.CursorPos, parent_window->DC.CursorPos + sz); + ItemSize(sz); + if ((window->DC.NavLayerActiveMask != 0 || window->DC.NavHasScroll) && !(window->Flags & ImGuiWindowFlags_NavFlattened)) + { + ItemAdd(bb, window->ChildId); + RenderNavHighlight(bb, window->ChildId); - // When browsing a window that has no activable items (scroll only) we keep a highlight on the child - if (window->DC.NavLayerActiveMask == 0 && window == g.NavWindow) - RenderNavHighlight(ImRect(bb.Min - ImVec2(2,2), bb.Max + ImVec2(2,2)), g.NavId, ImGuiNavHighlightFlags_TypeThin); - } - else - { - // Not navigable into - ItemAdd(bb, 0); - } - } + // When browsing a window that has no activable items (scroll only) we keep a highlight on the child + if (window->DC.NavLayerActiveMask == 0 && window == g.NavWindow) + RenderNavHighlight(ImRect(bb.Min - ImVec2(2, 2), bb.Max + ImVec2(2, 2)), g.NavId, ImGuiNavHighlightFlags_TypeThin); + } + else + { + // Not navigable into + ItemAdd(bb, 0); + } + } } // Helper to create a child window / scrolling region that looks like a normal widget frame. bool ImGui::BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags extra_flags) { - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; - PushStyleColor(ImGuiCol_ChildBg, style.Colors[ImGuiCol_FrameBg]); - PushStyleVar(ImGuiStyleVar_ChildRounding, style.FrameRounding); - PushStyleVar(ImGuiStyleVar_ChildBorderSize, style.FrameBorderSize); - PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); - return BeginChild(id, size, true, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | extra_flags); + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + PushStyleColor(ImGuiCol_ChildBg, style.Colors[ImGuiCol_FrameBg]); + PushStyleVar(ImGuiStyleVar_ChildRounding, style.FrameRounding); + PushStyleVar(ImGuiStyleVar_ChildBorderSize, style.FrameBorderSize); + PushStyleVar(ImGuiStyleVar_WindowPadding, style.FramePadding); + return BeginChild(id, size, true, ImGuiWindowFlags_NoMove | ImGuiWindowFlags_AlwaysUseWindowPadding | extra_flags); } void ImGui::EndChildFrame() { - EndChild(); - PopStyleVar(3); - PopStyleColor(); + EndChild(); + PopStyleVar(3); + PopStyleColor(); } // Save and compare stack sizes on Begin()/End() to detect usage errors static void CheckStacksSize(ImGuiWindow* window, bool write) { - // NOT checking: DC.ItemWidth, DC.AllowKeyboardFocus, DC.ButtonRepeat, DC.TextWrapPos (per window) to allow user to conveniently push once and not pop (they are cleared on Begin) - ImGuiContext& g = *GImGui; - int* p_backup = &window->DC.StackSizesBackup[0]; - { int current = window->IDStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushID/PopID or TreeNode/TreePop Mismatch!"); p_backup++; } // Too few or too many PopID()/TreePop() - { int current = window->DC.GroupStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "BeginGroup/EndGroup Mismatch!"); p_backup++; } // Too few or too many EndGroup() - { int current = g.CurrentPopupStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "BeginMenu/EndMenu or BeginPopup/EndPopup Mismatch"); p_backup++;}// Too few or too many EndMenu()/EndPopup() - { int current = g.ColorModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushStyleColor/PopStyleColor Mismatch!"); p_backup++; } // Too few or too many PopStyleColor() - { int current = g.StyleModifiers.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushStyleVar/PopStyleVar Mismatch!"); p_backup++; } // Too few or too many PopStyleVar() - { int current = g.FontStack.Size; if (write) *p_backup = current; else IM_ASSERT(*p_backup == current && "PushFont/PopFont Mismatch!"); p_backup++; } // Too few or too many PopFont() - IM_ASSERT(p_backup == window->DC.StackSizesBackup + IM_ARRAYSIZE(window->DC.StackSizesBackup)); + // NOT checking: DC.ItemWidth, DC.AllowKeyboardFocus, DC.ButtonRepeat, DC.TextWrapPos (per window) to allow user to conveniently push once and not pop (they are cleared on Begin) + ImGuiContext& g = *GImGui; + int* p_backup = &window->DC.StackSizesBackup[0]; + { + int current = window->IDStack.Size; + if (write) + *p_backup = current; + else + IM_ASSERT(*p_backup == current && "PushID/PopID or TreeNode/TreePop Mismatch!"); + p_backup++; + } // Too few or too many PopID()/TreePop() + { + int current = window->DC.GroupStack.Size; + if (write) + *p_backup = current; + else + IM_ASSERT(*p_backup == current && "BeginGroup/EndGroup Mismatch!"); + p_backup++; + } // Too few or too many EndGroup() + { + int current = g.CurrentPopupStack.Size; + if (write) + *p_backup = current; + else + IM_ASSERT(*p_backup == current && "BeginMenu/EndMenu or BeginPopup/EndPopup Mismatch"); + p_backup++; + } // Too few or too many EndMenu()/EndPopup() + { + int current = g.ColorModifiers.Size; + if (write) + *p_backup = current; + else + IM_ASSERT(*p_backup == current && "PushStyleColor/PopStyleColor Mismatch!"); + p_backup++; + } // Too few or too many PopStyleColor() + { + int current = g.StyleModifiers.Size; + if (write) + *p_backup = current; + else + IM_ASSERT(*p_backup == current && "PushStyleVar/PopStyleVar Mismatch!"); + p_backup++; + } // Too few or too many PopStyleVar() + { + int current = g.FontStack.Size; + if (write) + *p_backup = current; + else + IM_ASSERT(*p_backup == current && "PushFont/PopFont Mismatch!"); + p_backup++; + } // Too few or too many PopFont() + IM_ASSERT(p_backup == window->DC.StackSizesBackup + IM_ARRAYSIZE(window->DC.StackSizesBackup)); } enum ImGuiPopupPositionPolicy { - ImGuiPopupPositionPolicy_Default, - ImGuiPopupPositionPolicy_ComboBox + ImGuiPopupPositionPolicy_Default, + ImGuiPopupPositionPolicy_ComboBox }; static ImVec2 FindBestWindowPosForPopup(const ImVec2& ref_pos, const ImVec2& size, ImGuiDir* last_dir, const ImRect& r_avoid, ImGuiPopupPositionPolicy policy = ImGuiPopupPositionPolicy_Default) { - const ImGuiStyle& style = GImGui->Style; + const ImGuiStyle& style = GImGui->Style; - // r_avoid = the rectangle to avoid (e.g. for tooltip it is a rectangle around the mouse cursor which we want to avoid. for popups it's a small point around the cursor.) - // r_outer = the visible area rectangle, minus safe area padding. If our popup size won't fit because of safe area padding we ignore it. - ImVec2 safe_padding = style.DisplaySafeAreaPadding; - ImRect r_outer(GetViewportRect()); - r_outer.Expand(ImVec2((size.x - r_outer.GetWidth() > safe_padding.x*2) ? -safe_padding.x : 0.0f, (size.y - r_outer.GetHeight() > safe_padding.y*2) ? -safe_padding.y : 0.0f)); - ImVec2 base_pos_clamped = ImClamp(ref_pos, r_outer.Min, r_outer.Max - size); - //GImGui->OverlayDrawList.AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255,0,0,255)); - //GImGui->OverlayDrawList.AddRect(r_outer.Min, r_outer.Max, IM_COL32(0,255,0,255)); + // r_avoid = the rectangle to avoid (e.g. for tooltip it is a rectangle around the mouse cursor which we want to avoid. for popups it's a small point around the cursor.) + // r_outer = the visible area rectangle, minus safe area padding. If our popup size won't fit because of safe area padding we ignore it. + ImVec2 safe_padding = style.DisplaySafeAreaPadding; + ImRect r_outer(GetViewportRect()); + r_outer.Expand(ImVec2((size.x - r_outer.GetWidth() > safe_padding.x * 2) ? -safe_padding.x : 0.0f, (size.y - r_outer.GetHeight() > safe_padding.y * 2) ? -safe_padding.y : 0.0f)); + ImVec2 base_pos_clamped = ImClamp(ref_pos, r_outer.Min, r_outer.Max - size); + //GImGui->OverlayDrawList.AddRect(r_avoid.Min, r_avoid.Max, IM_COL32(255,0,0,255)); + //GImGui->OverlayDrawList.AddRect(r_outer.Min, r_outer.Max, IM_COL32(0,255,0,255)); - // Combo Box policy (we want a connecting edge) - if (policy == ImGuiPopupPositionPolicy_ComboBox) - { - const ImGuiDir dir_prefered_order[ImGuiDir_Count_] = { ImGuiDir_Down, ImGuiDir_Right, ImGuiDir_Left, ImGuiDir_Up }; - for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_Count_; n++) - { - const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n]; - if (n != -1 && dir == *last_dir) // Already tried this direction? - continue; - ImVec2 pos; - if (dir == ImGuiDir_Down) pos = ImVec2(r_avoid.Min.x, r_avoid.Max.y); // Below, Toward Right (default) - if (dir == ImGuiDir_Right) pos = ImVec2(r_avoid.Min.x, r_avoid.Min.y - size.y); // Above, Toward Right - if (dir == ImGuiDir_Left) pos = ImVec2(r_avoid.Max.x - size.x, r_avoid.Max.y); // Below, Toward Left - if (dir == ImGuiDir_Up) pos = ImVec2(r_avoid.Max.x - size.x, r_avoid.Min.y - size.y); // Above, Toward Left - if (!r_outer.Contains(ImRect(pos, pos + size))) - continue; - *last_dir = dir; - return pos; - } - } + // Combo Box policy (we want a connecting edge) + if (policy == ImGuiPopupPositionPolicy_ComboBox) + { + const ImGuiDir dir_prefered_order[ImGuiDir_Count_] = {ImGuiDir_Down, ImGuiDir_Right, ImGuiDir_Left, ImGuiDir_Up}; + for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_Count_; n++) + { + const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n]; + if (n != -1 && dir == *last_dir) // Already tried this direction? + continue; + ImVec2 pos; + if (dir == ImGuiDir_Down) pos = ImVec2(r_avoid.Min.x, r_avoid.Max.y); // Below, Toward Right (default) + if (dir == ImGuiDir_Right) pos = ImVec2(r_avoid.Min.x, r_avoid.Min.y - size.y); // Above, Toward Right + if (dir == ImGuiDir_Left) pos = ImVec2(r_avoid.Max.x - size.x, r_avoid.Max.y); // Below, Toward Left + if (dir == ImGuiDir_Up) pos = ImVec2(r_avoid.Max.x - size.x, r_avoid.Min.y - size.y); // Above, Toward Left + if (!r_outer.Contains(ImRect(pos, pos + size))) + continue; + *last_dir = dir; + return pos; + } + } - // Default popup policy - const ImGuiDir dir_prefered_order[ImGuiDir_Count_] = { ImGuiDir_Right, ImGuiDir_Down, ImGuiDir_Up, ImGuiDir_Left }; - for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_Count_; n++) - { - const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n]; - if (n != -1 && dir == *last_dir) // Already tried this direction? - continue; - float avail_w = (dir == ImGuiDir_Left ? r_avoid.Min.x : r_outer.Max.x) - (dir == ImGuiDir_Right ? r_avoid.Max.x : r_outer.Min.x); - float avail_h = (dir == ImGuiDir_Up ? r_avoid.Min.y : r_outer.Max.y) - (dir == ImGuiDir_Down ? r_avoid.Max.y : r_outer.Min.y); - if (avail_w < size.x || avail_h < size.y) - continue; - ImVec2 pos; - pos.x = (dir == ImGuiDir_Left) ? r_avoid.Min.x - size.x : (dir == ImGuiDir_Right) ? r_avoid.Max.x : base_pos_clamped.x; - pos.y = (dir == ImGuiDir_Up) ? r_avoid.Min.y - size.y : (dir == ImGuiDir_Down) ? r_avoid.Max.y : base_pos_clamped.y; - *last_dir = dir; - return pos; - } + // Default popup policy + const ImGuiDir dir_prefered_order[ImGuiDir_Count_] = {ImGuiDir_Right, ImGuiDir_Down, ImGuiDir_Up, ImGuiDir_Left}; + for (int n = (*last_dir != ImGuiDir_None) ? -1 : 0; n < ImGuiDir_Count_; n++) + { + const ImGuiDir dir = (n == -1) ? *last_dir : dir_prefered_order[n]; + if (n != -1 && dir == *last_dir) // Already tried this direction? + continue; + float avail_w = (dir == ImGuiDir_Left ? r_avoid.Min.x : r_outer.Max.x) - (dir == ImGuiDir_Right ? r_avoid.Max.x : r_outer.Min.x); + float avail_h = (dir == ImGuiDir_Up ? r_avoid.Min.y : r_outer.Max.y) - (dir == ImGuiDir_Down ? r_avoid.Max.y : r_outer.Min.y); + if (avail_w < size.x || avail_h < size.y) + continue; + ImVec2 pos; + pos.x = (dir == ImGuiDir_Left) ? r_avoid.Min.x - size.x : (dir == ImGuiDir_Right) ? r_avoid.Max.x : base_pos_clamped.x; + pos.y = (dir == ImGuiDir_Up) ? r_avoid.Min.y - size.y : (dir == ImGuiDir_Down) ? r_avoid.Max.y : base_pos_clamped.y; + *last_dir = dir; + return pos; + } - // Fallback, try to keep within display - *last_dir = ImGuiDir_None; - ImVec2 pos = ref_pos; - pos.x = ImMax(ImMin(pos.x + size.x, r_outer.Max.x) - size.x, r_outer.Min.x); - pos.y = ImMax(ImMin(pos.y + size.y, r_outer.Max.y) - size.y, r_outer.Min.y); - return pos; + // Fallback, try to keep within display + *last_dir = ImGuiDir_None; + ImVec2 pos = ref_pos; + pos.x = ImMax(ImMin(pos.x + size.x, r_outer.Max.x) - size.x, r_outer.Min.x); + pos.y = ImMax(ImMin(pos.y + size.y, r_outer.Max.y) - size.y, r_outer.Min.y); + return pos; } static void SetWindowConditionAllowFlags(ImGuiWindow* window, ImGuiCond flags, bool enabled) { - window->SetWindowPosAllowFlags = enabled ? (window->SetWindowPosAllowFlags | flags) : (window->SetWindowPosAllowFlags & ~flags); - window->SetWindowSizeAllowFlags = enabled ? (window->SetWindowSizeAllowFlags | flags) : (window->SetWindowSizeAllowFlags & ~flags); - window->SetWindowCollapsedAllowFlags = enabled ? (window->SetWindowCollapsedAllowFlags | flags) : (window->SetWindowCollapsedAllowFlags & ~flags); + window->SetWindowPosAllowFlags = enabled ? (window->SetWindowPosAllowFlags | flags) : (window->SetWindowPosAllowFlags & ~flags); + window->SetWindowSizeAllowFlags = enabled ? (window->SetWindowSizeAllowFlags | flags) : (window->SetWindowSizeAllowFlags & ~flags); + window->SetWindowCollapsedAllowFlags = enabled ? (window->SetWindowCollapsedAllowFlags | flags) : (window->SetWindowCollapsedAllowFlags & ~flags); } ImGuiWindow* ImGui::FindWindowByName(const char* name) { - ImGuiContext& g = *GImGui; - ImGuiID id = ImHash(name, 0); - return (ImGuiWindow*)g.WindowsById.GetVoidPtr(id); + ImGuiContext& g = *GImGui; + ImGuiID id = ImHash(name, 0); + return (ImGuiWindow*)g.WindowsById.GetVoidPtr(id); } static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFlags flags) { - ImGuiContext& g = *GImGui; + ImGuiContext& g = *GImGui; - // Create window the first time - ImGuiWindow* window = IM_NEW(ImGuiWindow)(&g, name); - window->Flags = flags; - g.WindowsById.SetVoidPtr(window->ID, window); + // Create window the first time + ImGuiWindow* window = IM_NEW(ImGuiWindow)(&g, name); + window->Flags = flags; + g.WindowsById.SetVoidPtr(window->ID, window); - // User can disable loading and saving of settings. Tooltip and child windows also don't store settings. - if (!(flags & ImGuiWindowFlags_NoSavedSettings)) - { - // Retrieve settings from .ini file - // Use SetWindowPos() or SetNextWindowPos() with the appropriate condition flag to change the initial position of a window. - window->Pos = window->PosFloat = ImVec2(60, 60); + // User can disable loading and saving of settings. Tooltip and child windows also don't store settings. + if (!(flags & ImGuiWindowFlags_NoSavedSettings)) + { + // Retrieve settings from .ini file + // Use SetWindowPos() or SetNextWindowPos() with the appropriate condition flag to change the initial position of a window. + window->Pos = window->PosFloat = ImVec2(60, 60); - if (ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID)) - { - SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false); - window->PosFloat = settings->Pos; - window->Pos = ImFloor(window->PosFloat); - window->Collapsed = settings->Collapsed; - if (ImLengthSqr(settings->Size) > 0.00001f) - size = settings->Size; - } - } - window->Size = window->SizeFull = window->SizeFullAtLastBegin = size; + if (ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID)) + { + SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false); + window->PosFloat = settings->Pos; + window->Pos = ImFloor(window->PosFloat); + window->Collapsed = settings->Collapsed; + if (ImLengthSqr(settings->Size) > 0.00001f) + size = settings->Size; + } + } + window->Size = window->SizeFull = window->SizeFullAtLastBegin = size; - if ((flags & ImGuiWindowFlags_AlwaysAutoResize) != 0) - { - window->AutoFitFramesX = window->AutoFitFramesY = 2; - window->AutoFitOnlyGrows = false; - } - else - { - if (window->Size.x <= 0.0f) - window->AutoFitFramesX = 2; - if (window->Size.y <= 0.0f) - window->AutoFitFramesY = 2; - window->AutoFitOnlyGrows = (window->AutoFitFramesX > 0) || (window->AutoFitFramesY > 0); - } + if ((flags & ImGuiWindowFlags_AlwaysAutoResize) != 0) + { + window->AutoFitFramesX = window->AutoFitFramesY = 2; + window->AutoFitOnlyGrows = false; + } + else + { + if (window->Size.x <= 0.0f) + window->AutoFitFramesX = 2; + if (window->Size.y <= 0.0f) + window->AutoFitFramesY = 2; + window->AutoFitOnlyGrows = (window->AutoFitFramesX > 0) || (window->AutoFitFramesY > 0); + } - if (flags & ImGuiWindowFlags_NoBringToFrontOnFocus) - g.Windows.insert(g.Windows.begin(), window); // Quite slow but rare and only once - else - g.Windows.push_back(window); - return window; + if (flags & ImGuiWindowFlags_NoBringToFrontOnFocus) + g.Windows.insert(g.Windows.begin(), window); // Quite slow but rare and only once + else + g.Windows.push_back(window); + return window; } static ImVec2 CalcSizeAfterConstraint(ImGuiWindow* window, ImVec2 new_size) { - ImGuiContext& g = *GImGui; - if (g.NextWindowData.SizeConstraintCond != 0) - { - // Using -1,-1 on either X/Y axis to preserve the current size. - ImRect cr = g.NextWindowData.SizeConstraintRect; - new_size.x = (cr.Min.x >= 0 && cr.Max.x >= 0) ? ImClamp(new_size.x, cr.Min.x, cr.Max.x) : window->SizeFull.x; - new_size.y = (cr.Min.y >= 0 && cr.Max.y >= 0) ? ImClamp(new_size.y, cr.Min.y, cr.Max.y) : window->SizeFull.y; - if (g.NextWindowData.SizeCallback) - { - ImGuiSizeCallbackData data; - data.UserData = g.NextWindowData.SizeCallbackUserData; - data.Pos = window->Pos; - data.CurrentSize = window->SizeFull; - data.DesiredSize = new_size; - g.NextWindowData.SizeCallback(&data); - new_size = data.DesiredSize; - } - } + ImGuiContext& g = *GImGui; + if (g.NextWindowData.SizeConstraintCond != 0) + { + // Using -1,-1 on either X/Y axis to preserve the current size. + ImRect cr = g.NextWindowData.SizeConstraintRect; + new_size.x = (cr.Min.x >= 0 && cr.Max.x >= 0) ? ImClamp(new_size.x, cr.Min.x, cr.Max.x) : window->SizeFull.x; + new_size.y = (cr.Min.y >= 0 && cr.Max.y >= 0) ? ImClamp(new_size.y, cr.Min.y, cr.Max.y) : window->SizeFull.y; + if (g.NextWindowData.SizeCallback) + { + ImGuiSizeCallbackData data; + data.UserData = g.NextWindowData.SizeCallbackUserData; + data.Pos = window->Pos; + data.CurrentSize = window->SizeFull; + data.DesiredSize = new_size; + g.NextWindowData.SizeCallback(&data); + new_size = data.DesiredSize; + } + } - // Minimum size - if (!(window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_AlwaysAutoResize))) - { - new_size = ImMax(new_size, g.Style.WindowMinSize); - new_size.y = ImMax(new_size.y, window->TitleBarHeight() + window->MenuBarHeight() + ImMax(0.0f, g.Style.WindowRounding - 1.0f)); // Reduce artifacts with very small windows - } - return new_size; + // Minimum size + if (!(window->Flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_AlwaysAutoResize))) + { + new_size = ImMax(new_size, g.Style.WindowMinSize); + new_size.y = ImMax(new_size.y, window->TitleBarHeight() + window->MenuBarHeight() + ImMax(0.0f, g.Style.WindowRounding - 1.0f)); // Reduce artifacts with very small windows + } + return new_size; } static ImVec2 CalcSizeContents(ImGuiWindow* window) { - ImVec2 sz; - sz.x = (float)(int)((window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : (window->DC.CursorMaxPos.x - window->Pos.x + window->Scroll.x)); - sz.y = (float)(int)((window->SizeContentsExplicit.y != 0.0f) ? window->SizeContentsExplicit.y : (window->DC.CursorMaxPos.y - window->Pos.y + window->Scroll.y)); - return sz + window->WindowPadding; + ImVec2 sz; + sz.x = (float)(int)((window->SizeContentsExplicit.x != 0.0f) ? window->SizeContentsExplicit.x : (window->DC.CursorMaxPos.x - window->Pos.x + window->Scroll.x)); + sz.y = (float)(int)((window->SizeContentsExplicit.y != 0.0f) ? window->SizeContentsExplicit.y : (window->DC.CursorMaxPos.y - window->Pos.y + window->Scroll.y)); + return sz + window->WindowPadding; } static ImVec2 CalcSizeAutoFit(ImGuiWindow* window, const ImVec2& size_contents) { - ImGuiContext& g = *GImGui; - ImGuiStyle& style = g.Style; - ImGuiWindowFlags flags = window->Flags; - ImVec2 size_auto_fit; - if ((flags & ImGuiWindowFlags_Tooltip) != 0) - { - // Tooltip always resize. We keep the spacing symmetric on both axises for aesthetic purpose. - size_auto_fit = size_contents; - } - else - { - // When the window cannot fit all contents (either because of constraints, either because screen is too small): we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than DisplaySize-WindowPadding. - size_auto_fit = ImClamp(size_contents, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - g.Style.DisplaySafeAreaPadding)); - ImVec2 size_auto_fit_after_constraint = CalcSizeAfterConstraint(window, size_auto_fit); - if (size_auto_fit_after_constraint.x < size_contents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)) - size_auto_fit.y += style.ScrollbarSize; - if (size_auto_fit_after_constraint.y < size_contents.y && !(flags & ImGuiWindowFlags_NoScrollbar)) - size_auto_fit.x += style.ScrollbarSize; - } - return size_auto_fit; + ImGuiContext& g = *GImGui; + ImGuiStyle& style = g.Style; + ImGuiWindowFlags flags = window->Flags; + ImVec2 size_auto_fit; + if ((flags & ImGuiWindowFlags_Tooltip) != 0) + { + // Tooltip always resize. We keep the spacing symmetric on both axises for aesthetic purpose. + size_auto_fit = size_contents; + } + else + { + // When the window cannot fit all contents (either because of constraints, either because screen is too small): we are growing the size on the other axis to compensate for expected scrollbar. FIXME: Might turn bigger than DisplaySize-WindowPadding. + size_auto_fit = ImClamp(size_contents, style.WindowMinSize, ImMax(style.WindowMinSize, g.IO.DisplaySize - g.Style.DisplaySafeAreaPadding)); + ImVec2 size_auto_fit_after_constraint = CalcSizeAfterConstraint(window, size_auto_fit); + if (size_auto_fit_after_constraint.x < size_contents.x && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)) + size_auto_fit.y += style.ScrollbarSize; + if (size_auto_fit_after_constraint.y < size_contents.y && !(flags & ImGuiWindowFlags_NoScrollbar)) + size_auto_fit.x += style.ScrollbarSize; + } + return size_auto_fit; } static float GetScrollMaxX(ImGuiWindow* window) { - return ImMax(0.0f, window->SizeContents.x - (window->SizeFull.x - window->ScrollbarSizes.x)); + return ImMax(0.0f, window->SizeContents.x - (window->SizeFull.x - window->ScrollbarSizes.x)); } static float GetScrollMaxY(ImGuiWindow* window) { - return ImMax(0.0f, window->SizeContents.y - (window->SizeFull.y - window->ScrollbarSizes.y)); + return ImMax(0.0f, window->SizeContents.y - (window->SizeFull.y - window->ScrollbarSizes.y)); } static ImVec2 CalcNextScrollFromScrollTargetAndClamp(ImGuiWindow* window) { - ImVec2 scroll = window->Scroll; - float cr_x = window->ScrollTargetCenterRatio.x; - float cr_y = window->ScrollTargetCenterRatio.y; - if (window->ScrollTarget.x < FLT_MAX) - scroll.x = window->ScrollTarget.x - cr_x * (window->SizeFull.x - window->ScrollbarSizes.x); - if (window->ScrollTarget.y < FLT_MAX) - scroll.y = window->ScrollTarget.y - (1.0f - cr_y) * (window->TitleBarHeight() + window->MenuBarHeight()) - cr_y * (window->SizeFull.y - window->ScrollbarSizes.y); - scroll = ImMax(scroll, ImVec2(0.0f, 0.0f)); - if (!window->Collapsed && !window->SkipItems) - { - scroll.x = ImMin(scroll.x, GetScrollMaxX(window)); - scroll.y = ImMin(scroll.y, GetScrollMaxY(window)); - } - return scroll; + ImVec2 scroll = window->Scroll; + float cr_x = window->ScrollTargetCenterRatio.x; + float cr_y = window->ScrollTargetCenterRatio.y; + if (window->ScrollTarget.x < FLT_MAX) + scroll.x = window->ScrollTarget.x - cr_x * (window->SizeFull.x - window->ScrollbarSizes.x); + if (window->ScrollTarget.y < FLT_MAX) + scroll.y = window->ScrollTarget.y - (1.0f - cr_y) * (window->TitleBarHeight() + window->MenuBarHeight()) - cr_y * (window->SizeFull.y - window->ScrollbarSizes.y); + scroll = ImMax(scroll, ImVec2(0.0f, 0.0f)); + if (!window->Collapsed && !window->SkipItems) + { + scroll.x = ImMin(scroll.x, GetScrollMaxX(window)); + scroll.y = ImMin(scroll.y, GetScrollMaxY(window)); + } + return scroll; } static ImGuiCol GetWindowBgColorIdxFromFlags(ImGuiWindowFlags flags) { - if (flags & (ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) - return ImGuiCol_PopupBg; - if (flags & ImGuiWindowFlags_ChildWindow) - return ImGuiCol_ChildBg; - return ImGuiCol_WindowBg; + if (flags & (ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) + return ImGuiCol_PopupBg; + if (flags & ImGuiWindowFlags_ChildWindow) + return ImGuiCol_ChildBg; + return ImGuiCol_WindowBg; } static void CalcResizePosSizeFromAnyCorner(ImGuiWindow* window, const ImVec2& corner_target, const ImVec2& corner_norm, ImVec2* out_pos, ImVec2* out_size) { - ImVec2 pos_min = ImLerp(corner_target, window->Pos, corner_norm); // Expected window upper-left - ImVec2 pos_max = ImLerp(window->Pos + window->Size, corner_target, corner_norm); // Expected window lower-right - ImVec2 size_expected = pos_max - pos_min; - ImVec2 size_constrained = CalcSizeAfterConstraint(window, size_expected); - *out_pos = pos_min; - if (corner_norm.x == 0.0f) - out_pos->x -= (size_constrained.x - size_expected.x); - if (corner_norm.y == 0.0f) - out_pos->y -= (size_constrained.y - size_expected.y); - *out_size = size_constrained; + ImVec2 pos_min = ImLerp(corner_target, window->Pos, corner_norm); // Expected window upper-left + ImVec2 pos_max = ImLerp(window->Pos + window->Size, corner_target, corner_norm); // Expected window lower-right + ImVec2 size_expected = pos_max - pos_min; + ImVec2 size_constrained = CalcSizeAfterConstraint(window, size_expected); + *out_pos = pos_min; + if (corner_norm.x == 0.0f) + out_pos->x -= (size_constrained.x - size_expected.x); + if (corner_norm.y == 0.0f) + out_pos->y -= (size_constrained.y - size_expected.y); + *out_size = size_constrained; } struct ImGuiResizeGripDef { - ImVec2 CornerPos; - ImVec2 InnerDir; - int AngleMin12, AngleMax12; + ImVec2 CornerPos; + ImVec2 InnerDir; + int AngleMin12, AngleMax12; }; const ImGuiResizeGripDef resize_grip_def[4] = -{ - { ImVec2(1,1), ImVec2(-1,-1), 0, 3 }, // Lower right - { ImVec2(0,1), ImVec2(+1,-1), 3, 6 }, // Lower left - { ImVec2(0,0), ImVec2(+1,+1), 6, 9 }, // Upper left - { ImVec2(1,0), ImVec2(-1,+1), 9,12 }, // Upper right + { + {ImVec2(1, 1), ImVec2(-1, -1), 0, 3}, // Lower right + {ImVec2(0, 1), ImVec2(+1, -1), 3, 6}, // Lower left + {ImVec2(0, 0), ImVec2(+1, +1), 6, 9}, // Upper left + {ImVec2(1, 0), ImVec2(-1, +1), 9, 12}, // Upper right }; static ImRect GetBorderRect(ImGuiWindow* window, int border_n, float perp_padding, float thickness) { - ImRect rect = window->Rect(); - if (thickness == 0.0f) rect.Max -= ImVec2(1,1); - if (border_n == 0) return ImRect(rect.Min.x + perp_padding, rect.Min.y, rect.Max.x - perp_padding, rect.Min.y + thickness); - if (border_n == 1) return ImRect(rect.Max.x - thickness, rect.Min.y + perp_padding, rect.Max.x, rect.Max.y - perp_padding); - if (border_n == 2) return ImRect(rect.Min.x + perp_padding, rect.Max.y - thickness, rect.Max.x - perp_padding, rect.Max.y); - if (border_n == 3) return ImRect(rect.Min.x, rect.Min.y + perp_padding, rect.Min.x + thickness, rect.Max.y - perp_padding); - IM_ASSERT(0); - return ImRect(); + ImRect rect = window->Rect(); + if (thickness == 0.0f) rect.Max -= ImVec2(1, 1); + if (border_n == 0) return ImRect(rect.Min.x + perp_padding, rect.Min.y, rect.Max.x - perp_padding, rect.Min.y + thickness); + if (border_n == 1) return ImRect(rect.Max.x - thickness, rect.Min.y + perp_padding, rect.Max.x, rect.Max.y - perp_padding); + if (border_n == 2) return ImRect(rect.Min.x + perp_padding, rect.Max.y - thickness, rect.Max.x - perp_padding, rect.Max.y); + if (border_n == 3) return ImRect(rect.Min.x, rect.Min.y + perp_padding, rect.Min.x + thickness, rect.Max.y - perp_padding); + IM_ASSERT(0); + return ImRect(); } // Handle resize for: Resize Grips, Borders, Gamepad static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_auto_fit, int* border_held, int resize_grip_count, ImU32 resize_grip_col[4]) { - ImGuiContext& g = *GImGui; - ImGuiWindowFlags flags = window->Flags; - if ((flags & ImGuiWindowFlags_NoResize) || (flags & ImGuiWindowFlags_AlwaysAutoResize) || window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) - return; + ImGuiContext& g = *GImGui; + ImGuiWindowFlags flags = window->Flags; + if ((flags & ImGuiWindowFlags_NoResize) || (flags & ImGuiWindowFlags_AlwaysAutoResize) || window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) + return; - const int resize_border_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 4 : 0; - const float grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f); - const float grip_hover_size = (float)(int)(grip_draw_size * 0.75f); + const int resize_border_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 4 : 0; + const float grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f); + const float grip_hover_size = (float)(int)(grip_draw_size * 0.75f); - ImVec2 pos_target(FLT_MAX, FLT_MAX); - ImVec2 size_target(FLT_MAX, FLT_MAX); + ImVec2 pos_target(FLT_MAX, FLT_MAX); + ImVec2 size_target(FLT_MAX, FLT_MAX); - // Manual resize grips - PushID("#RESIZE"); - for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++) - { - const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n]; - const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPos); + // Manual resize grips + PushID("#RESIZE"); + for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++) + { + const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n]; + const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPos); - // Using the FlattenChilds button flag we make the resize button accessible even if we are hovering over a child window - ImRect resize_rect(corner, corner + grip.InnerDir * grip_hover_size); - resize_rect.FixInverted(); - bool hovered, held; - ButtonBehavior(resize_rect, window->GetID((void*)(intptr_t)resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus); - if (hovered || held) - g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE; + // Using the FlattenChilds button flag we make the resize button accessible even if we are hovering over a child window + ImRect resize_rect(corner, corner + grip.InnerDir * grip_hover_size); + resize_rect.FixInverted(); + bool hovered, held; + ButtonBehavior(resize_rect, window->GetID((void*)(intptr_t)resize_grip_n), &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_NoNavFocus); + if (hovered || held) + g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE; - if (g.HoveredWindow == window && held && g.IO.MouseDoubleClicked[0] && resize_grip_n == 0) - { - // Manual auto-fit when double-clicking - size_target = CalcSizeAfterConstraint(window, size_auto_fit); - ClearActiveID(); - } - else if (held) - { - // Resize from any of the four corners - // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position - ImVec2 corner_target = g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize() * grip.CornerPos; // Corner of the window corresponding to our corner grip - CalcResizePosSizeFromAnyCorner(window, corner_target, grip.CornerPos, &pos_target, &size_target); - } - if (resize_grip_n == 0 || held || hovered) - resize_grip_col[resize_grip_n] = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip); - } - for (int border_n = 0; border_n < resize_border_count; border_n++) - { - const float BORDER_SIZE = 5.0f; // FIXME: Only works _inside_ window because of HoveredWindow check. - const float BORDER_APPEAR_TIMER = 0.05f; // Reduce visual noise - bool hovered, held; - ImRect border_rect = GetBorderRect(window, border_n, grip_hover_size, BORDER_SIZE); - ButtonBehavior(border_rect, window->GetID((void*)(intptr_t)(border_n + 4)), &hovered, &held, ImGuiButtonFlags_FlattenChildren); - if ((hovered && g.HoveredIdTimer > BORDER_APPEAR_TIMER) || held) - { - g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS; - if (held) *border_held = border_n; - } - if (held) - { - ImVec2 border_target = window->Pos; - ImVec2 border_posn; - if (border_n == 0) { border_posn = ImVec2(0, 0); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y); } - if (border_n == 1) { border_posn = ImVec2(1, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + BORDER_SIZE); } - if (border_n == 2) { border_posn = ImVec2(0, 1); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y + BORDER_SIZE); } - if (border_n == 3) { border_posn = ImVec2(0, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x); } - CalcResizePosSizeFromAnyCorner(window, border_target, border_posn, &pos_target, &size_target); - } - } - PopID(); + if (g.HoveredWindow == window && held && g.IO.MouseDoubleClicked[0] && resize_grip_n == 0) + { + // Manual auto-fit when double-clicking + size_target = CalcSizeAfterConstraint(window, size_auto_fit); + ClearActiveID(); + } + else if (held) + { + // Resize from any of the four corners + // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position + ImVec2 corner_target = g.IO.MousePos - g.ActiveIdClickOffset + resize_rect.GetSize() * grip.CornerPos; // Corner of the window corresponding to our corner grip + CalcResizePosSizeFromAnyCorner(window, corner_target, grip.CornerPos, &pos_target, &size_target); + } + if (resize_grip_n == 0 || held || hovered) + resize_grip_col[resize_grip_n] = GetColorU32(held ? ImGuiCol_ResizeGripActive : hovered ? ImGuiCol_ResizeGripHovered : ImGuiCol_ResizeGrip); + } + for (int border_n = 0; border_n < resize_border_count; border_n++) + { + const float BORDER_SIZE = 5.0f; // FIXME: Only works _inside_ window because of HoveredWindow check. + const float BORDER_APPEAR_TIMER = 0.05f; // Reduce visual noise + bool hovered, held; + ImRect border_rect = GetBorderRect(window, border_n, grip_hover_size, BORDER_SIZE); + ButtonBehavior(border_rect, window->GetID((void*)(intptr_t)(border_n + 4)), &hovered, &held, ImGuiButtonFlags_FlattenChildren); + if ((hovered && g.HoveredIdTimer > BORDER_APPEAR_TIMER) || held) + { + g.MouseCursor = (border_n & 1) ? ImGuiMouseCursor_ResizeEW : ImGuiMouseCursor_ResizeNS; + if (held) *border_held = border_n; + } + if (held) + { + ImVec2 border_target = window->Pos; + ImVec2 border_posn; + if (border_n == 0) + { + border_posn = ImVec2(0, 0); + border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y); + } + if (border_n == 1) + { + border_posn = ImVec2(1, 0); + border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + BORDER_SIZE); + } + if (border_n == 2) + { + border_posn = ImVec2(0, 1); + border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y + BORDER_SIZE); + } + if (border_n == 3) + { + border_posn = ImVec2(0, 0); + border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x); + } + CalcResizePosSizeFromAnyCorner(window, border_target, border_posn, &pos_target, &size_target); + } + } + PopID(); - // Navigation/gamepad resize - if (g.NavWindowingTarget == window) - { - ImVec2 nav_resize_delta; - if (g.NavWindowingInputSource == ImGuiInputSource_NavKeyboard && g.IO.KeyShift) - nav_resize_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard, ImGuiInputReadMode_Down); - if (g.NavWindowingInputSource == ImGuiInputSource_NavGamepad) - nav_resize_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_Down); - if (nav_resize_delta.x != 0.0f || nav_resize_delta.y != 0.0f) - { - const float NAV_RESIZE_SPEED = 600.0f; - nav_resize_delta *= ImFloor(NAV_RESIZE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y)); - g.NavWindowingToggleLayer = false; - g.NavDisableMouseHover = true; - resize_grip_col[0] = GetColorU32(ImGuiCol_ResizeGripActive); - // FIXME-NAV: Should store and accumulate into a separate size buffer to handle sizing constraints properly, right now a constraint will make us stuck. - size_target = CalcSizeAfterConstraint(window, window->SizeFull + nav_resize_delta); - } - } + // Navigation/gamepad resize + if (g.NavWindowingTarget == window) + { + ImVec2 nav_resize_delta; + if (g.NavWindowingInputSource == ImGuiInputSource_NavKeyboard && g.IO.KeyShift) + nav_resize_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard, ImGuiInputReadMode_Down); + if (g.NavWindowingInputSource == ImGuiInputSource_NavGamepad) + nav_resize_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_Down); + if (nav_resize_delta.x != 0.0f || nav_resize_delta.y != 0.0f) + { + const float NAV_RESIZE_SPEED = 600.0f; + nav_resize_delta *= ImFloor(NAV_RESIZE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y)); + g.NavWindowingToggleLayer = false; + g.NavDisableMouseHover = true; + resize_grip_col[0] = GetColorU32(ImGuiCol_ResizeGripActive); + // FIXME-NAV: Should store and accumulate into a separate size buffer to handle sizing constraints properly, right now a constraint will make us stuck. + size_target = CalcSizeAfterConstraint(window, window->SizeFull + nav_resize_delta); + } + } - // Apply back modified position/size to window - if (size_target.x != FLT_MAX) - { - window->SizeFull = size_target; - MarkIniSettingsDirty(window); - } - if (pos_target.x != FLT_MAX) - { - window->Pos = window->PosFloat = ImFloor(pos_target); - MarkIniSettingsDirty(window); - } + // Apply back modified position/size to window + if (size_target.x != FLT_MAX) + { + window->SizeFull = size_target; + MarkIniSettingsDirty(window); + } + if (pos_target.x != FLT_MAX) + { + window->Pos = window->PosFloat = ImFloor(pos_target); + MarkIniSettingsDirty(window); + } - window->Size = window->SizeFull; + window->Size = window->SizeFull; } // Push a new ImGui window to add widgets to. @@ -5584,655 +5726,655 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au // - Passing 'bool* p_open' displays a Close button on the upper-right corner of the window, the pointed value will be set to false when the button is pressed. bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; - IM_ASSERT(name != NULL); // Window name required - IM_ASSERT(g.Initialized); // Forgot to call ImGui::NewFrame() - IM_ASSERT(g.FrameCountEnded != g.FrameCount); // Called ImGui::Render() or ImGui::EndFrame() and haven't called ImGui::NewFrame() again yet + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + IM_ASSERT(name != NULL); // Window name required + IM_ASSERT(g.Initialized); // Forgot to call ImGui::NewFrame() + IM_ASSERT(g.FrameCountEnded != g.FrameCount); // Called ImGui::Render() or ImGui::EndFrame() and haven't called ImGui::NewFrame() again yet - // Find or create - ImGuiWindow* window = FindWindowByName(name); - if (!window) - { - ImVec2 size_on_first_use = (g.NextWindowData.SizeCond != 0) ? g.NextWindowData.SizeVal : ImVec2(0.0f, 0.0f); // Any condition flag will do since we are creating a new window here. - window = CreateNewWindow(name, size_on_first_use, flags); - } + // Find or create + ImGuiWindow* window = FindWindowByName(name); + if (!window) + { + ImVec2 size_on_first_use = (g.NextWindowData.SizeCond != 0) ? g.NextWindowData.SizeVal : ImVec2(0.0f, 0.0f); // Any condition flag will do since we are creating a new window here. + window = CreateNewWindow(name, size_on_first_use, flags); + } - // Automatically disable manual moving/resizing when NoInputs is set - if (flags & ImGuiWindowFlags_NoInputs) - flags |= ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize; - - if (flags & ImGuiWindowFlags_NavFlattened) - IM_ASSERT(flags & ImGuiWindowFlags_ChildWindow); + // Automatically disable manual moving/resizing when NoInputs is set + if (flags & ImGuiWindowFlags_NoInputs) + flags |= ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoResize; - const int current_frame = g.FrameCount; - const bool first_begin_of_the_frame = (window->LastFrameActive != current_frame); - if (first_begin_of_the_frame) - window->Flags = (ImGuiWindowFlags)flags; - else - flags = window->Flags; + if (flags & ImGuiWindowFlags_NavFlattened) + IM_ASSERT(flags & ImGuiWindowFlags_ChildWindow); - // Update the Appearing flag - bool window_just_activated_by_user = (window->LastFrameActive < current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on - const bool window_just_appearing_after_hidden_for_resize = (window->HiddenFrames == 1); - if (flags & ImGuiWindowFlags_Popup) - { - ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.CurrentPopupStack.Size]; - window_just_activated_by_user |= (window->PopupId != popup_ref.PopupId); // We recycle popups so treat window as activated if popup id changed - window_just_activated_by_user |= (window != popup_ref.Window); - } - window->Appearing = (window_just_activated_by_user || window_just_appearing_after_hidden_for_resize); - window->CloseButton = (p_open != NULL); - if (window->Appearing) - SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, true); + const int current_frame = g.FrameCount; + const bool first_begin_of_the_frame = (window->LastFrameActive != current_frame); + if (first_begin_of_the_frame) + window->Flags = (ImGuiWindowFlags)flags; + else + flags = window->Flags; - // Parent window is latched only on the first call to Begin() of the frame, so further append-calls can be done from a different window stack - ImGuiWindow* parent_window_in_stack = g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back(); - ImGuiWindow* parent_window = first_begin_of_the_frame ? ((flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)) ? parent_window_in_stack : NULL) : window->ParentWindow; - IM_ASSERT(parent_window != NULL || !(flags & ImGuiWindowFlags_ChildWindow)); + // Update the Appearing flag + bool window_just_activated_by_user = (window->LastFrameActive < current_frame - 1); // Not using !WasActive because the implicit "Debug" window would always toggle off->on + const bool window_just_appearing_after_hidden_for_resize = (window->HiddenFrames == 1); + if (flags & ImGuiWindowFlags_Popup) + { + ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.CurrentPopupStack.Size]; + window_just_activated_by_user |= (window->PopupId != popup_ref.PopupId); // We recycle popups so treat window as activated if popup id changed + window_just_activated_by_user |= (window != popup_ref.Window); + } + window->Appearing = (window_just_activated_by_user || window_just_appearing_after_hidden_for_resize); + window->CloseButton = (p_open != NULL); + if (window->Appearing) + SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, true); - // Add to stack - g.CurrentWindowStack.push_back(window); - SetCurrentWindow(window); - CheckStacksSize(window, true); - if (flags & ImGuiWindowFlags_Popup) - { - ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.CurrentPopupStack.Size]; - popup_ref.Window = window; - g.CurrentPopupStack.push_back(popup_ref); - window->PopupId = popup_ref.PopupId; - } + // Parent window is latched only on the first call to Begin() of the frame, so further append-calls can be done from a different window stack + ImGuiWindow* parent_window_in_stack = g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back(); + ImGuiWindow* parent_window = first_begin_of_the_frame ? ((flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup)) ? parent_window_in_stack : NULL) : window->ParentWindow; + IM_ASSERT(parent_window != NULL || !(flags & ImGuiWindowFlags_ChildWindow)); - if (window_just_appearing_after_hidden_for_resize && !(flags & ImGuiWindowFlags_ChildWindow)) - window->NavLastIds[0] = 0; + // Add to stack + g.CurrentWindowStack.push_back(window); + SetCurrentWindow(window); + CheckStacksSize(window, true); + if (flags & ImGuiWindowFlags_Popup) + { + ImGuiPopupRef& popup_ref = g.OpenPopupStack[g.CurrentPopupStack.Size]; + popup_ref.Window = window; + g.CurrentPopupStack.push_back(popup_ref); + window->PopupId = popup_ref.PopupId; + } - // Process SetNextWindow***() calls - bool window_pos_set_by_api = false; - bool window_size_x_set_by_api = false, window_size_y_set_by_api = false; - if (g.NextWindowData.PosCond) - { - window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.NextWindowData.PosCond) != 0; - if (window_pos_set_by_api && ImLengthSqr(g.NextWindowData.PosPivotVal) > 0.00001f) - { - // May be processed on the next frame if this is our first frame and we are measuring size - // FIXME: Look into removing the branch so everything can go through this same code path for consistency. - window->SetWindowPosVal = g.NextWindowData.PosVal; - window->SetWindowPosPivot = g.NextWindowData.PosPivotVal; - window->SetWindowPosAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); - } - else - { - SetWindowPos(window, g.NextWindowData.PosVal, g.NextWindowData.PosCond); - } - g.NextWindowData.PosCond = 0; - } - if (g.NextWindowData.SizeCond) - { - window_size_x_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindowData.SizeCond) != 0 && (g.NextWindowData.SizeVal.x > 0.0f); - window_size_y_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindowData.SizeCond) != 0 && (g.NextWindowData.SizeVal.y > 0.0f); - SetWindowSize(window, g.NextWindowData.SizeVal, g.NextWindowData.SizeCond); - g.NextWindowData.SizeCond = 0; - } - if (g.NextWindowData.ContentSizeCond) - { - // Adjust passed "client size" to become a "window size" - window->SizeContentsExplicit = g.NextWindowData.ContentSizeVal; - if (window->SizeContentsExplicit.y != 0.0f) - window->SizeContentsExplicit.y += window->TitleBarHeight() + window->MenuBarHeight(); - g.NextWindowData.ContentSizeCond = 0; - } - else if (first_begin_of_the_frame) - { - window->SizeContentsExplicit = ImVec2(0.0f, 0.0f); - } - if (g.NextWindowData.CollapsedCond) - { - SetWindowCollapsed(window, g.NextWindowData.CollapsedVal, g.NextWindowData.CollapsedCond); - g.NextWindowData.CollapsedCond = 0; - } - if (g.NextWindowData.FocusCond) - { - SetWindowFocus(); - g.NextWindowData.FocusCond = 0; - } - if (window->Appearing) - SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, false); + if (window_just_appearing_after_hidden_for_resize && !(flags & ImGuiWindowFlags_ChildWindow)) + window->NavLastIds[0] = 0; - // When reusing window again multiple times a frame, just append content (don't need to setup again) - if (first_begin_of_the_frame) - { - const bool window_is_child_tooltip = (flags & ImGuiWindowFlags_ChildWindow) && (flags & ImGuiWindowFlags_Tooltip); // FIXME-WIP: Undocumented behavior of Child+Tooltip for pinned tooltip (#1345) + // Process SetNextWindow***() calls + bool window_pos_set_by_api = false; + bool window_size_x_set_by_api = false, window_size_y_set_by_api = false; + if (g.NextWindowData.PosCond) + { + window_pos_set_by_api = (window->SetWindowPosAllowFlags & g.NextWindowData.PosCond) != 0; + if (window_pos_set_by_api && ImLengthSqr(g.NextWindowData.PosPivotVal) > 0.00001f) + { + // May be processed on the next frame if this is our first frame and we are measuring size + // FIXME: Look into removing the branch so everything can go through this same code path for consistency. + window->SetWindowPosVal = g.NextWindowData.PosVal; + window->SetWindowPosPivot = g.NextWindowData.PosPivotVal; + window->SetWindowPosAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); + } + else + { + SetWindowPos(window, g.NextWindowData.PosVal, g.NextWindowData.PosCond); + } + g.NextWindowData.PosCond = 0; + } + if (g.NextWindowData.SizeCond) + { + window_size_x_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindowData.SizeCond) != 0 && (g.NextWindowData.SizeVal.x > 0.0f); + window_size_y_set_by_api = (window->SetWindowSizeAllowFlags & g.NextWindowData.SizeCond) != 0 && (g.NextWindowData.SizeVal.y > 0.0f); + SetWindowSize(window, g.NextWindowData.SizeVal, g.NextWindowData.SizeCond); + g.NextWindowData.SizeCond = 0; + } + if (g.NextWindowData.ContentSizeCond) + { + // Adjust passed "client size" to become a "window size" + window->SizeContentsExplicit = g.NextWindowData.ContentSizeVal; + if (window->SizeContentsExplicit.y != 0.0f) + window->SizeContentsExplicit.y += window->TitleBarHeight() + window->MenuBarHeight(); + g.NextWindowData.ContentSizeCond = 0; + } + else if (first_begin_of_the_frame) + { + window->SizeContentsExplicit = ImVec2(0.0f, 0.0f); + } + if (g.NextWindowData.CollapsedCond) + { + SetWindowCollapsed(window, g.NextWindowData.CollapsedVal, g.NextWindowData.CollapsedCond); + g.NextWindowData.CollapsedCond = 0; + } + if (g.NextWindowData.FocusCond) + { + SetWindowFocus(); + g.NextWindowData.FocusCond = 0; + } + if (window->Appearing) + SetWindowConditionAllowFlags(window, ImGuiCond_Appearing, false); - // Initialize - window->ParentWindow = parent_window; - window->RootWindow = window->RootWindowForTitleBarHighlight = window->RootWindowForTabbing = window->RootWindowForNav = window; - if (parent_window && (flags & ImGuiWindowFlags_ChildWindow) && !window_is_child_tooltip) - window->RootWindow = parent_window->RootWindow; - if (parent_window && !(flags & ImGuiWindowFlags_Modal) && (flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup))) - window->RootWindowForTitleBarHighlight = window->RootWindowForTabbing = parent_window->RootWindowForTitleBarHighlight; // Same value in master branch, will differ for docking - while (window->RootWindowForNav->Flags & ImGuiWindowFlags_NavFlattened) - window->RootWindowForNav = window->RootWindowForNav->ParentWindow; + // When reusing window again multiple times a frame, just append content (don't need to setup again) + if (first_begin_of_the_frame) + { + const bool window_is_child_tooltip = (flags & ImGuiWindowFlags_ChildWindow) && (flags & ImGuiWindowFlags_Tooltip); // FIXME-WIP: Undocumented behavior of Child+Tooltip for pinned tooltip (#1345) - window->Active = true; - window->BeginOrderWithinParent = 0; - window->BeginOrderWithinContext = g.WindowsActiveCount++; - window->BeginCount = 0; - window->ClipRect = ImVec4(-FLT_MAX,-FLT_MAX,+FLT_MAX,+FLT_MAX); - window->LastFrameActive = current_frame; - window->IDStack.resize(1); + // Initialize + window->ParentWindow = parent_window; + window->RootWindow = window->RootWindowForTitleBarHighlight = window->RootWindowForTabbing = window->RootWindowForNav = window; + if (parent_window && (flags & ImGuiWindowFlags_ChildWindow) && !window_is_child_tooltip) + window->RootWindow = parent_window->RootWindow; + if (parent_window && !(flags & ImGuiWindowFlags_Modal) && (flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Popup))) + window->RootWindowForTitleBarHighlight = window->RootWindowForTabbing = parent_window->RootWindowForTitleBarHighlight; // Same value in master branch, will differ for docking + while (window->RootWindowForNav->Flags & ImGuiWindowFlags_NavFlattened) + window->RootWindowForNav = window->RootWindowForNav->ParentWindow; - // Lock window rounding, border size and rounding so that altering the border sizes for children doesn't have side-effects. - window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding; - window->WindowBorderSize = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildBorderSize : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupBorderSize : style.WindowBorderSize; - window->WindowPadding = style.WindowPadding; - if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_Popup)) && window->WindowBorderSize == 0.0f) - window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); + window->Active = true; + window->BeginOrderWithinParent = 0; + window->BeginOrderWithinContext = g.WindowsActiveCount++; + window->BeginCount = 0; + window->ClipRect = ImVec4(-FLT_MAX, -FLT_MAX, +FLT_MAX, +FLT_MAX); + window->LastFrameActive = current_frame; + window->IDStack.resize(1); - // Collapse window by double-clicking on title bar - // At this point we don't have a clipping rectangle setup yet, so we can use the title bar area for hit detection and drawing - if (!(flags & ImGuiWindowFlags_NoTitleBar) && !(flags & ImGuiWindowFlags_NoCollapse)) - { - ImRect title_bar_rect = window->TitleBarRect(); - if (window->CollapseToggleWanted || (g.HoveredWindow == window && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max) && g.IO.MouseDoubleClicked[0])) - { - window->Collapsed = !window->Collapsed; - MarkIniSettingsDirty(window); - FocusWindow(window); - } - } - else - { - window->Collapsed = false; - } - window->CollapseToggleWanted = false; + // Lock window rounding, border size and rounding so that altering the border sizes for children doesn't have side-effects. + window->WindowRounding = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildRounding : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupRounding : style.WindowRounding; + window->WindowBorderSize = (flags & ImGuiWindowFlags_ChildWindow) ? style.ChildBorderSize : ((flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiWindowFlags_Modal)) ? style.PopupBorderSize : style.WindowBorderSize; + window->WindowPadding = style.WindowPadding; + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & (ImGuiWindowFlags_AlwaysUseWindowPadding | ImGuiWindowFlags_Popup)) && window->WindowBorderSize == 0.0f) + window->WindowPadding = ImVec2(0.0f, (flags & ImGuiWindowFlags_MenuBar) ? style.WindowPadding.y : 0.0f); - // SIZE + // Collapse window by double-clicking on title bar + // At this point we don't have a clipping rectangle setup yet, so we can use the title bar area for hit detection and drawing + if (!(flags & ImGuiWindowFlags_NoTitleBar) && !(flags & ImGuiWindowFlags_NoCollapse)) + { + ImRect title_bar_rect = window->TitleBarRect(); + if (window->CollapseToggleWanted || (g.HoveredWindow == window && IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max) && g.IO.MouseDoubleClicked[0])) + { + window->Collapsed = !window->Collapsed; + MarkIniSettingsDirty(window); + FocusWindow(window); + } + } + else + { + window->Collapsed = false; + } + window->CollapseToggleWanted = false; - // Update contents size from last frame for auto-fitting (unless explicitly specified) - window->SizeContents = CalcSizeContents(window); + // SIZE - // Hide popup/tooltip window when re-opening while we measure size (because we recycle the windows) - if (window->HiddenFrames > 0) - window->HiddenFrames--; - if ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0 && window_just_activated_by_user) - { - window->HiddenFrames = 1; - if (flags & ImGuiWindowFlags_AlwaysAutoResize) - { - if (!window_size_x_set_by_api) - window->Size.x = window->SizeFull.x = 0.f; - if (!window_size_y_set_by_api) - window->Size.y = window->SizeFull.y = 0.f; - window->SizeContents = ImVec2(0.f, 0.f); - } - } + // Update contents size from last frame for auto-fitting (unless explicitly specified) + window->SizeContents = CalcSizeContents(window); - // Calculate auto-fit size, handle automatic resize - const ImVec2 size_auto_fit = CalcSizeAutoFit(window, window->SizeContents); - ImVec2 size_full_modified(FLT_MAX, FLT_MAX); - if (flags & ImGuiWindowFlags_AlwaysAutoResize && !window->Collapsed) - { - // Using SetNextWindowSize() overrides ImGuiWindowFlags_AlwaysAutoResize, so it can be used on tooltips/popups, etc. - if (!window_size_x_set_by_api) - window->SizeFull.x = size_full_modified.x = size_auto_fit.x; - if (!window_size_y_set_by_api) - window->SizeFull.y = size_full_modified.y = size_auto_fit.y; - } - else if (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) - { - // Auto-fit only grows during the first few frames - // We still process initial auto-fit on collapsed windows to get a window width, but otherwise don't honor ImGuiWindowFlags_AlwaysAutoResize when collapsed. - if (!window_size_x_set_by_api && window->AutoFitFramesX > 0) - window->SizeFull.x = size_full_modified.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; - if (!window_size_y_set_by_api && window->AutoFitFramesY > 0) - window->SizeFull.y = size_full_modified.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; - if (!window->Collapsed) - MarkIniSettingsDirty(window); - } + // Hide popup/tooltip window when re-opening while we measure size (because we recycle the windows) + if (window->HiddenFrames > 0) + window->HiddenFrames--; + if ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip)) != 0 && window_just_activated_by_user) + { + window->HiddenFrames = 1; + if (flags & ImGuiWindowFlags_AlwaysAutoResize) + { + if (!window_size_x_set_by_api) + window->Size.x = window->SizeFull.x = 0.f; + if (!window_size_y_set_by_api) + window->Size.y = window->SizeFull.y = 0.f; + window->SizeContents = ImVec2(0.f, 0.f); + } + } - // Apply minimum/maximum window size constraints and final size - window->SizeFull = CalcSizeAfterConstraint(window, window->SizeFull); - window->Size = window->Collapsed && !(flags & ImGuiWindowFlags_ChildWindow) ? window->TitleBarRect().GetSize() : window->SizeFull; + // Calculate auto-fit size, handle automatic resize + const ImVec2 size_auto_fit = CalcSizeAutoFit(window, window->SizeContents); + ImVec2 size_full_modified(FLT_MAX, FLT_MAX); + if (flags & ImGuiWindowFlags_AlwaysAutoResize && !window->Collapsed) + { + // Using SetNextWindowSize() overrides ImGuiWindowFlags_AlwaysAutoResize, so it can be used on tooltips/popups, etc. + if (!window_size_x_set_by_api) + window->SizeFull.x = size_full_modified.x = size_auto_fit.x; + if (!window_size_y_set_by_api) + window->SizeFull.y = size_full_modified.y = size_auto_fit.y; + } + else if (window->AutoFitFramesX > 0 || window->AutoFitFramesY > 0) + { + // Auto-fit only grows during the first few frames + // We still process initial auto-fit on collapsed windows to get a window width, but otherwise don't honor ImGuiWindowFlags_AlwaysAutoResize when collapsed. + if (!window_size_x_set_by_api && window->AutoFitFramesX > 0) + window->SizeFull.x = size_full_modified.x = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.x, size_auto_fit.x) : size_auto_fit.x; + if (!window_size_y_set_by_api && window->AutoFitFramesY > 0) + window->SizeFull.y = size_full_modified.y = window->AutoFitOnlyGrows ? ImMax(window->SizeFull.y, size_auto_fit.y) : size_auto_fit.y; + if (!window->Collapsed) + MarkIniSettingsDirty(window); + } - // SCROLLBAR STATUS + // Apply minimum/maximum window size constraints and final size + window->SizeFull = CalcSizeAfterConstraint(window, window->SizeFull); + window->Size = window->Collapsed && !(flags & ImGuiWindowFlags_ChildWindow) ? window->TitleBarRect().GetSize() : window->SizeFull; - // Update scrollbar status (based on the Size that was effective during last frame or the auto-resized Size). - if (!window->Collapsed) - { - // When reading the current size we need to read it after size constraints have been applied - float size_x_for_scrollbars = size_full_modified.x != FLT_MAX ? window->SizeFull.x : window->SizeFullAtLastBegin.x; - float size_y_for_scrollbars = size_full_modified.y != FLT_MAX ? window->SizeFull.y : window->SizeFullAtLastBegin.y; - window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > size_y_for_scrollbars) && !(flags & ImGuiWindowFlags_NoScrollbar)); - window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > size_x_for_scrollbars - (window->ScrollbarY ? style.ScrollbarSize : 0.0f)) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); - if (window->ScrollbarX && !window->ScrollbarY) - window->ScrollbarY = (window->SizeContents.y > size_y_for_scrollbars - style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); - window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); - } + // SCROLLBAR STATUS - // POSITION + // Update scrollbar status (based on the Size that was effective during last frame or the auto-resized Size). + if (!window->Collapsed) + { + // When reading the current size we need to read it after size constraints have been applied + float size_x_for_scrollbars = size_full_modified.x != FLT_MAX ? window->SizeFull.x : window->SizeFullAtLastBegin.x; + float size_y_for_scrollbars = size_full_modified.y != FLT_MAX ? window->SizeFull.y : window->SizeFullAtLastBegin.y; + window->ScrollbarY = (flags & ImGuiWindowFlags_AlwaysVerticalScrollbar) || ((window->SizeContents.y > size_y_for_scrollbars) && !(flags & ImGuiWindowFlags_NoScrollbar)); + window->ScrollbarX = (flags & ImGuiWindowFlags_AlwaysHorizontalScrollbar) || ((window->SizeContents.x > size_x_for_scrollbars - (window->ScrollbarY ? style.ScrollbarSize : 0.0f)) && !(flags & ImGuiWindowFlags_NoScrollbar) && (flags & ImGuiWindowFlags_HorizontalScrollbar)); + if (window->ScrollbarX && !window->ScrollbarY) + window->ScrollbarY = (window->SizeContents.y > size_y_for_scrollbars - style.ScrollbarSize) && !(flags & ImGuiWindowFlags_NoScrollbar); + window->ScrollbarSizes = ImVec2(window->ScrollbarY ? style.ScrollbarSize : 0.0f, window->ScrollbarX ? style.ScrollbarSize : 0.0f); + } - // Popup latch its initial position, will position itself when it appears next frame - if (window_just_activated_by_user) - { - window->AutoPosLastDirection = ImGuiDir_None; - if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api) - window->Pos = window->PosFloat = g.CurrentPopupStack.back().OpenPopupPos; - } + // POSITION - // Position child window - if (flags & ImGuiWindowFlags_ChildWindow) - { - window->BeginOrderWithinParent = parent_window->DC.ChildWindows.Size; - parent_window->DC.ChildWindows.push_back(window); - if (!(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api && !window_is_child_tooltip) - window->Pos = window->PosFloat = parent_window->DC.CursorPos; - } + // Popup latch its initial position, will position itself when it appears next frame + if (window_just_activated_by_user) + { + window->AutoPosLastDirection = ImGuiDir_None; + if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api) + window->Pos = window->PosFloat = g.CurrentPopupStack.back().OpenPopupPos; + } - const bool window_pos_with_pivot = (window->SetWindowPosVal.x != FLT_MAX && window->HiddenFrames == 0); - if (window_pos_with_pivot) - { - // Position given a pivot (e.g. for centering) - SetWindowPos(window, ImMax(style.DisplaySafeAreaPadding, window->SetWindowPosVal - window->SizeFull * window->SetWindowPosPivot), 0); - } - else if (flags & ImGuiWindowFlags_ChildMenu) - { - // Child menus typically request _any_ position within the parent menu item, and then our FindBestPopupWindowPos() function will move the new menu outside the parent bounds. - // This is how we end up with child menus appearing (most-commonly) on the right of the parent menu. - IM_ASSERT(window_pos_set_by_api); - float horizontal_overlap = style.ItemSpacing.x; // We want some overlap to convey the relative depth of each popup (currently the amount of overlap it is hard-coded to style.ItemSpacing.x, may need to introduce another style value). - ImGuiWindow* parent_menu = parent_window_in_stack; - ImRect rect_to_avoid; - if (parent_menu->DC.MenuBarAppending) - rect_to_avoid = ImRect(-FLT_MAX, parent_menu->Pos.y + parent_menu->TitleBarHeight(), FLT_MAX, parent_menu->Pos.y + parent_menu->TitleBarHeight() + parent_menu->MenuBarHeight()); - else - rect_to_avoid = ImRect(parent_menu->Pos.x + horizontal_overlap, -FLT_MAX, parent_menu->Pos.x + parent_menu->Size.x - horizontal_overlap - parent_menu->ScrollbarSizes.x, FLT_MAX); - window->PosFloat = FindBestWindowPosForPopup(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); - } - else if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api && window_just_appearing_after_hidden_for_resize) - { - ImRect rect_to_avoid(window->PosFloat.x - 1, window->PosFloat.y - 1, window->PosFloat.x + 1, window->PosFloat.y + 1); - window->PosFloat = FindBestWindowPosForPopup(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); - } + // Position child window + if (flags & ImGuiWindowFlags_ChildWindow) + { + window->BeginOrderWithinParent = parent_window->DC.ChildWindows.Size; + parent_window->DC.ChildWindows.push_back(window); + if (!(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api && !window_is_child_tooltip) + window->Pos = window->PosFloat = parent_window->DC.CursorPos; + } - // Position tooltip (always follows mouse) - if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api && !window_is_child_tooltip) - { - float sc = g.Style.MouseCursorScale; - ImVec2 ref_pos = (!g.NavDisableHighlight && g.NavDisableMouseHover) ? NavCalcPreferredMousePos() : g.IO.MousePos; - ImRect rect_to_avoid; - if (!g.NavDisableHighlight && g.NavDisableMouseHover && !(g.IO.NavFlags & ImGuiNavFlags_MoveMouse)) - rect_to_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 16, ref_pos.y + 8); - else - rect_to_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24 * sc, ref_pos.y + 24 * sc); // FIXME: Hard-coded based on mouse cursor shape expectation. Exact dimension not very important. - window->PosFloat = FindBestWindowPosForPopup(ref_pos, window->Size, &window->AutoPosLastDirection, rect_to_avoid); - if (window->AutoPosLastDirection == ImGuiDir_None) - window->PosFloat = ref_pos + ImVec2(2,2); // If there's not enough room, for tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible. - } + const bool window_pos_with_pivot = (window->SetWindowPosVal.x != FLT_MAX && window->HiddenFrames == 0); + if (window_pos_with_pivot) + { + // Position given a pivot (e.g. for centering) + SetWindowPos(window, ImMax(style.DisplaySafeAreaPadding, window->SetWindowPosVal - window->SizeFull * window->SetWindowPosPivot), 0); + } + else if (flags & ImGuiWindowFlags_ChildMenu) + { + // Child menus typically request _any_ position within the parent menu item, and then our FindBestPopupWindowPos() function will move the new menu outside the parent bounds. + // This is how we end up with child menus appearing (most-commonly) on the right of the parent menu. + IM_ASSERT(window_pos_set_by_api); + float horizontal_overlap = style.ItemSpacing.x; // We want some overlap to convey the relative depth of each popup (currently the amount of overlap it is hard-coded to style.ItemSpacing.x, may need to introduce another style value). + ImGuiWindow* parent_menu = parent_window_in_stack; + ImRect rect_to_avoid; + if (parent_menu->DC.MenuBarAppending) + rect_to_avoid = ImRect(-FLT_MAX, parent_menu->Pos.y + parent_menu->TitleBarHeight(), FLT_MAX, parent_menu->Pos.y + parent_menu->TitleBarHeight() + parent_menu->MenuBarHeight()); + else + rect_to_avoid = ImRect(parent_menu->Pos.x + horizontal_overlap, -FLT_MAX, parent_menu->Pos.x + parent_menu->Size.x - horizontal_overlap - parent_menu->ScrollbarSizes.x, FLT_MAX); + window->PosFloat = FindBestWindowPosForPopup(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); + } + else if ((flags & ImGuiWindowFlags_Popup) != 0 && !window_pos_set_by_api && window_just_appearing_after_hidden_for_resize) + { + ImRect rect_to_avoid(window->PosFloat.x - 1, window->PosFloat.y - 1, window->PosFloat.x + 1, window->PosFloat.y + 1); + window->PosFloat = FindBestWindowPosForPopup(window->PosFloat, window->Size, &window->AutoPosLastDirection, rect_to_avoid); + } - // Clamp position so it stays visible - if (!(flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Tooltip)) - { - if (!window_pos_set_by_api && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0 && g.IO.DisplaySize.x > 0.0f && g.IO.DisplaySize.y > 0.0f) // Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing. - { - ImVec2 padding = ImMax(style.DisplayWindowPadding, style.DisplaySafeAreaPadding); - window->PosFloat = ImMax(window->PosFloat + window->Size, padding) - window->Size; - window->PosFloat = ImMin(window->PosFloat, g.IO.DisplaySize - padding); - } - } - window->Pos = ImFloor(window->PosFloat); + // Position tooltip (always follows mouse) + if ((flags & ImGuiWindowFlags_Tooltip) != 0 && !window_pos_set_by_api && !window_is_child_tooltip) + { + float sc = g.Style.MouseCursorScale; + ImVec2 ref_pos = (!g.NavDisableHighlight && g.NavDisableMouseHover) ? NavCalcPreferredMousePos() : g.IO.MousePos; + ImRect rect_to_avoid; + if (!g.NavDisableHighlight && g.NavDisableMouseHover && !(g.IO.NavFlags & ImGuiNavFlags_MoveMouse)) + rect_to_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 16, ref_pos.y + 8); + else + rect_to_avoid = ImRect(ref_pos.x - 16, ref_pos.y - 8, ref_pos.x + 24 * sc, ref_pos.y + 24 * sc); // FIXME: Hard-coded based on mouse cursor shape expectation. Exact dimension not very important. + window->PosFloat = FindBestWindowPosForPopup(ref_pos, window->Size, &window->AutoPosLastDirection, rect_to_avoid); + if (window->AutoPosLastDirection == ImGuiDir_None) + window->PosFloat = ref_pos + ImVec2(2, 2); // If there's not enough room, for tooltip we prefer avoiding the cursor at all cost even if it means that part of the tooltip won't be visible. + } - // Default item width. Make it proportional to window size if window manually resizes - if (window->Size.x > 0.0f && !(flags & ImGuiWindowFlags_Tooltip) && !(flags & ImGuiWindowFlags_AlwaysAutoResize)) - window->ItemWidthDefault = (float)(int)(window->Size.x * 0.65f); - else - window->ItemWidthDefault = (float)(int)(g.FontSize * 16.0f); + // Clamp position so it stays visible + if (!(flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Tooltip)) + { + if (!window_pos_set_by_api && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0 && g.IO.DisplaySize.x > 0.0f && g.IO.DisplaySize.y > 0.0f) // Ignore zero-sized display explicitly to avoid losing positions if a window manager reports zero-sized window when initializing or minimizing. + { + ImVec2 padding = ImMax(style.DisplayWindowPadding, style.DisplaySafeAreaPadding); + window->PosFloat = ImMax(window->PosFloat + window->Size, padding) - window->Size; + window->PosFloat = ImMin(window->PosFloat, g.IO.DisplaySize - padding); + } + } + window->Pos = ImFloor(window->PosFloat); - // Prepare for focus requests - window->FocusIdxAllRequestCurrent = (window->FocusIdxAllRequestNext == INT_MAX || window->FocusIdxAllCounter == -1) ? INT_MAX : (window->FocusIdxAllRequestNext + (window->FocusIdxAllCounter+1)) % (window->FocusIdxAllCounter+1); - window->FocusIdxTabRequestCurrent = (window->FocusIdxTabRequestNext == INT_MAX || window->FocusIdxTabCounter == -1) ? INT_MAX : (window->FocusIdxTabRequestNext + (window->FocusIdxTabCounter+1)) % (window->FocusIdxTabCounter+1); - window->FocusIdxAllCounter = window->FocusIdxTabCounter = -1; - window->FocusIdxAllRequestNext = window->FocusIdxTabRequestNext = INT_MAX; + // Default item width. Make it proportional to window size if window manually resizes + if (window->Size.x > 0.0f && !(flags & ImGuiWindowFlags_Tooltip) && !(flags & ImGuiWindowFlags_AlwaysAutoResize)) + window->ItemWidthDefault = (float)(int)(window->Size.x * 0.65f); + else + window->ItemWidthDefault = (float)(int)(g.FontSize * 16.0f); - // Apply scrolling - window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window); - window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); + // Prepare for focus requests + window->FocusIdxAllRequestCurrent = (window->FocusIdxAllRequestNext == INT_MAX || window->FocusIdxAllCounter == -1) ? INT_MAX : (window->FocusIdxAllRequestNext + (window->FocusIdxAllCounter + 1)) % (window->FocusIdxAllCounter + 1); + window->FocusIdxTabRequestCurrent = (window->FocusIdxTabRequestNext == INT_MAX || window->FocusIdxTabCounter == -1) ? INT_MAX : (window->FocusIdxTabRequestNext + (window->FocusIdxTabCounter + 1)) % (window->FocusIdxTabCounter + 1); + window->FocusIdxAllCounter = window->FocusIdxTabCounter = -1; + window->FocusIdxAllRequestNext = window->FocusIdxTabRequestNext = INT_MAX; - // Apply focus, new windows appears in front - bool want_focus = false; - if (window_just_activated_by_user && !(flags & ImGuiWindowFlags_NoFocusOnAppearing)) - if (!(flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip)) || (flags & ImGuiWindowFlags_Popup)) - want_focus = true; + // Apply scrolling + window->Scroll = CalcNextScrollFromScrollTargetAndClamp(window); + window->ScrollTarget = ImVec2(FLT_MAX, FLT_MAX); - // Handle manual resize: Resize Grips, Borders, Gamepad - int border_held = -1; - ImU32 resize_grip_col[4] = { 0 }; - const int resize_grip_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 2 : 1; // 4 - const float grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f); - if (!window->Collapsed) - UpdateManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0]); + // Apply focus, new windows appears in front + bool want_focus = false; + if (window_just_activated_by_user && !(flags & ImGuiWindowFlags_NoFocusOnAppearing)) + if (!(flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip)) || (flags & ImGuiWindowFlags_Popup)) + want_focus = true; - // DRAWING + // Handle manual resize: Resize Grips, Borders, Gamepad + int border_held = -1; + ImU32 resize_grip_col[4] = {0}; + const int resize_grip_count = (flags & ImGuiWindowFlags_ResizeFromAnySide) ? 2 : 1; // 4 + const float grip_draw_size = (float)(int)ImMax(g.FontSize * 1.35f, window->WindowRounding + 1.0f + g.FontSize * 0.2f); + if (!window->Collapsed) + UpdateManualResize(window, size_auto_fit, &border_held, resize_grip_count, &resize_grip_col[0]); - // Setup draw list and outer clipping rectangle - window->DrawList->Clear(); - window->DrawList->Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0); - window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); - ImRect viewport_rect(GetViewportRect()); - if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_is_child_tooltip) - PushClipRect(parent_window->ClipRect.Min, parent_window->ClipRect.Max, true); - else - PushClipRect(viewport_rect.Min, viewport_rect.Max, true); + // DRAWING - // Draw modal window background (darkens what is behind them) - if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostModalRootWindow()) - window->DrawList->AddRectFilled(viewport_rect.Min, viewport_rect.Max, GetColorU32(ImGuiCol_ModalWindowDarkening, g.ModalWindowDarkeningRatio)); + // Setup draw list and outer clipping rectangle + window->DrawList->Clear(); + window->DrawList->Flags = (g.Style.AntiAliasedLines ? ImDrawListFlags_AntiAliasedLines : 0) | (g.Style.AntiAliasedFill ? ImDrawListFlags_AntiAliasedFill : 0); + window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID); + ImRect viewport_rect(GetViewportRect()); + if ((flags & ImGuiWindowFlags_ChildWindow) && !(flags & ImGuiWindowFlags_Popup) && !window_is_child_tooltip) + PushClipRect(parent_window->ClipRect.Min, parent_window->ClipRect.Max, true); + else + PushClipRect(viewport_rect.Min, viewport_rect.Max, true); - // Draw navigation selection/windowing rectangle background - if (g.NavWindowingTarget == window) - { - ImRect bb = window->Rect(); - bb.Expand(g.FontSize); - if (!bb.Contains(viewport_rect)) // Avoid drawing if the window covers all the viewport anyway - window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha * 0.25f), g.Style.WindowRounding); - } + // Draw modal window background (darkens what is behind them) + if ((flags & ImGuiWindowFlags_Modal) != 0 && window == GetFrontMostModalRootWindow()) + window->DrawList->AddRectFilled(viewport_rect.Min, viewport_rect.Max, GetColorU32(ImGuiCol_ModalWindowDarkening, g.ModalWindowDarkeningRatio)); - // Draw window + handle manual resize - const float window_rounding = window->WindowRounding; - const float window_border_size = window->WindowBorderSize; - const bool title_bar_is_highlight = want_focus || (g.NavWindow && window->RootWindowForTitleBarHighlight == g.NavWindow->RootWindowForTitleBarHighlight); - const ImRect title_bar_rect = window->TitleBarRect(); - if (window->Collapsed) - { - // Title bar only - float backup_border_size = style.FrameBorderSize; - g.Style.FrameBorderSize = window->WindowBorderSize; - ImU32 title_bar_col = GetColorU32((title_bar_is_highlight && !g.NavDisableHighlight) ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBgCollapsed); - RenderFrame(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, true, window_rounding); - g.Style.FrameBorderSize = backup_border_size; - } - else - { - // Window background - ImU32 bg_col = GetColorU32(GetWindowBgColorIdxFromFlags(flags)); - if (g.NextWindowData.BgAlphaCond != 0) - { - bg_col = (bg_col & ~IM_COL32_A_MASK) | (IM_F32_TO_INT8_SAT(g.NextWindowData.BgAlphaVal) << IM_COL32_A_SHIFT); - g.NextWindowData.BgAlphaCond = 0; - } - window->DrawList->AddRectFilled(window->Pos+ImVec2(0,window->TitleBarHeight()), window->Pos+window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Bot); + // Draw navigation selection/windowing rectangle background + if (g.NavWindowingTarget == window) + { + ImRect bb = window->Rect(); + bb.Expand(g.FontSize); + if (!bb.Contains(viewport_rect)) // Avoid drawing if the window covers all the viewport anyway + window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha * 0.25f), g.Style.WindowRounding); + } - // Title bar - ImU32 title_bar_col = GetColorU32(window->Collapsed ? ImGuiCol_TitleBgCollapsed : title_bar_is_highlight ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg); - if (!(flags & ImGuiWindowFlags_NoTitleBar)) - window->DrawList->AddRectFilled(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, window_rounding, ImDrawCornerFlags_Top); + // Draw window + handle manual resize + const float window_rounding = window->WindowRounding; + const float window_border_size = window->WindowBorderSize; + const bool title_bar_is_highlight = want_focus || (g.NavWindow && window->RootWindowForTitleBarHighlight == g.NavWindow->RootWindowForTitleBarHighlight); + const ImRect title_bar_rect = window->TitleBarRect(); + if (window->Collapsed) + { + // Title bar only + float backup_border_size = style.FrameBorderSize; + g.Style.FrameBorderSize = window->WindowBorderSize; + ImU32 title_bar_col = GetColorU32((title_bar_is_highlight && !g.NavDisableHighlight) ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBgCollapsed); + RenderFrame(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, true, window_rounding); + g.Style.FrameBorderSize = backup_border_size; + } + else + { + // Window background + ImU32 bg_col = GetColorU32(GetWindowBgColorIdxFromFlags(flags)); + if (g.NextWindowData.BgAlphaCond != 0) + { + bg_col = (bg_col & ~IM_COL32_A_MASK) | (IM_F32_TO_INT8_SAT(g.NextWindowData.BgAlphaVal) << IM_COL32_A_SHIFT); + g.NextWindowData.BgAlphaCond = 0; + } + window->DrawList->AddRectFilled(window->Pos + ImVec2(0, window->TitleBarHeight()), window->Pos + window->Size, bg_col, window_rounding, (flags & ImGuiWindowFlags_NoTitleBar) ? ImDrawCornerFlags_All : ImDrawCornerFlags_Bot); - // Menu bar - if (flags & ImGuiWindowFlags_MenuBar) - { - ImRect menu_bar_rect = window->MenuBarRect(); - menu_bar_rect.ClipWith(window->Rect()); // Soft clipping, in particular child window don't have minimum size covering the menu bar so this is useful for them. - window->DrawList->AddRectFilled(menu_bar_rect.Min, menu_bar_rect.Max, GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawCornerFlags_Top); - if (style.FrameBorderSize > 0.0f && menu_bar_rect.Max.y < window->Pos.y + window->Size.y) - window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); - } + // Title bar + ImU32 title_bar_col = GetColorU32(window->Collapsed ? ImGuiCol_TitleBgCollapsed : title_bar_is_highlight ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg); + if (!(flags & ImGuiWindowFlags_NoTitleBar)) + window->DrawList->AddRectFilled(title_bar_rect.Min, title_bar_rect.Max, title_bar_col, window_rounding, ImDrawCornerFlags_Top); - // Scrollbars - if (window->ScrollbarX) - Scrollbar(ImGuiLayoutType_Horizontal); - if (window->ScrollbarY) - Scrollbar(ImGuiLayoutType_Vertical); + // Menu bar + if (flags & ImGuiWindowFlags_MenuBar) + { + ImRect menu_bar_rect = window->MenuBarRect(); + menu_bar_rect.ClipWith(window->Rect()); // Soft clipping, in particular child window don't have minimum size covering the menu bar so this is useful for them. + window->DrawList->AddRectFilled(menu_bar_rect.Min, menu_bar_rect.Max, GetColorU32(ImGuiCol_MenuBarBg), (flags & ImGuiWindowFlags_NoTitleBar) ? window_rounding : 0.0f, ImDrawCornerFlags_Top); + if (style.FrameBorderSize > 0.0f && menu_bar_rect.Max.y < window->Pos.y + window->Size.y) + window->DrawList->AddLine(menu_bar_rect.GetBL(), menu_bar_rect.GetBR(), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); + } - // Render resize grips (after their input handling so we don't have a frame of latency) - if (!(flags & ImGuiWindowFlags_NoResize)) - { - for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++) - { - const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n]; - const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPos); - window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(window_border_size, grip_draw_size) : ImVec2(grip_draw_size, window_border_size))); - window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(grip_draw_size, window_border_size) : ImVec2(window_border_size, grip_draw_size))); - window->DrawList->PathArcToFast(ImVec2(corner.x + grip.InnerDir.x * (window_rounding + window_border_size), corner.y + grip.InnerDir.y * (window_rounding + window_border_size)), window_rounding, grip.AngleMin12, grip.AngleMax12); - window->DrawList->PathFillConvex(resize_grip_col[resize_grip_n]); - } - } + // Scrollbars + if (window->ScrollbarX) + Scrollbar(ImGuiLayoutType_Horizontal); + if (window->ScrollbarY) + Scrollbar(ImGuiLayoutType_Vertical); - // Borders - if (window_border_size > 0.0f) - window->DrawList->AddRect(window->Pos, window->Pos+window->Size, GetColorU32(ImGuiCol_Border), window_rounding, ImDrawCornerFlags_All, window_border_size); - if (border_held != -1) - { - ImRect border = GetBorderRect(window, border_held, grip_draw_size, 0.0f); - window->DrawList->AddLine(border.Min, border.Max, GetColorU32(ImGuiCol_SeparatorActive), ImMax(1.0f, window_border_size)); - } - if (style.FrameBorderSize > 0 && !(flags & ImGuiWindowFlags_NoTitleBar)) - window->DrawList->AddLine(title_bar_rect.GetBL() + ImVec2(style.WindowBorderSize, -1), title_bar_rect.GetBR() + ImVec2(-style.WindowBorderSize,-1), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); - } + // Render resize grips (after their input handling so we don't have a frame of latency) + if (!(flags & ImGuiWindowFlags_NoResize)) + { + for (int resize_grip_n = 0; resize_grip_n < resize_grip_count; resize_grip_n++) + { + const ImGuiResizeGripDef& grip = resize_grip_def[resize_grip_n]; + const ImVec2 corner = ImLerp(window->Pos, window->Pos + window->Size, grip.CornerPos); + window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(window_border_size, grip_draw_size) : ImVec2(grip_draw_size, window_border_size))); + window->DrawList->PathLineTo(corner + grip.InnerDir * ((resize_grip_n & 1) ? ImVec2(grip_draw_size, window_border_size) : ImVec2(window_border_size, grip_draw_size))); + window->DrawList->PathArcToFast(ImVec2(corner.x + grip.InnerDir.x * (window_rounding + window_border_size), corner.y + grip.InnerDir.y * (window_rounding + window_border_size)), window_rounding, grip.AngleMin12, grip.AngleMax12); + window->DrawList->PathFillConvex(resize_grip_col[resize_grip_n]); + } + } - // Draw navigation selection/windowing rectangle border - if (g.NavWindowingTarget == window) - { - float rounding = ImMax(window->WindowRounding, g.Style.WindowRounding); - ImRect bb = window->Rect(); - bb.Expand(g.FontSize); - if (bb.Contains(viewport_rect)) // If a window fits the entire viewport, adjust its highlight inward - { - bb.Expand(-g.FontSize - 1.0f); - rounding = window->WindowRounding; - } - window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), rounding, ~0, 3.0f); - } + // Borders + if (window_border_size > 0.0f) + window->DrawList->AddRect(window->Pos, window->Pos + window->Size, GetColorU32(ImGuiCol_Border), window_rounding, ImDrawCornerFlags_All, window_border_size); + if (border_held != -1) + { + ImRect border = GetBorderRect(window, border_held, grip_draw_size, 0.0f); + window->DrawList->AddLine(border.Min, border.Max, GetColorU32(ImGuiCol_SeparatorActive), ImMax(1.0f, window_border_size)); + } + if (style.FrameBorderSize > 0 && !(flags & ImGuiWindowFlags_NoTitleBar)) + window->DrawList->AddLine(title_bar_rect.GetBL() + ImVec2(style.WindowBorderSize, -1), title_bar_rect.GetBR() + ImVec2(-style.WindowBorderSize, -1), GetColorU32(ImGuiCol_Border), style.FrameBorderSize); + } - // Store a backup of SizeFull which we will use next frame to decide if we need scrollbars. - window->SizeFullAtLastBegin = window->SizeFull; + // Draw navigation selection/windowing rectangle border + if (g.NavWindowingTarget == window) + { + float rounding = ImMax(window->WindowRounding, g.Style.WindowRounding); + ImRect bb = window->Rect(); + bb.Expand(g.FontSize); + if (bb.Contains(viewport_rect)) // If a window fits the entire viewport, adjust its highlight inward + { + bb.Expand(-g.FontSize - 1.0f); + rounding = window->WindowRounding; + } + window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), rounding, ~0, 3.0f); + } - // Update ContentsRegionMax. All the variable it depends on are set above in this function. - window->ContentsRegionRect.Min.x = -window->Scroll.x + window->WindowPadding.x; - window->ContentsRegionRect.Min.y = -window->Scroll.y + window->WindowPadding.y + window->TitleBarHeight() + window->MenuBarHeight(); - window->ContentsRegionRect.Max.x = -window->Scroll.x - window->WindowPadding.x + (window->SizeContentsExplicit.x != 0.0f ? window->SizeContentsExplicit.x : (window->Size.x - window->ScrollbarSizes.x)); - window->ContentsRegionRect.Max.y = -window->Scroll.y - window->WindowPadding.y + (window->SizeContentsExplicit.y != 0.0f ? window->SizeContentsExplicit.y : (window->Size.y - window->ScrollbarSizes.y)); + // Store a backup of SizeFull which we will use next frame to decide if we need scrollbars. + window->SizeFullAtLastBegin = window->SizeFull; - // Setup drawing context - // (NB: That term "drawing context / DC" lost its meaning a long time ago. Initially was meant to hold transient data only. Nowadays difference between window-> and window->DC-> is dubious.) - window->DC.IndentX = 0.0f + window->WindowPadding.x - window->Scroll.x; - window->DC.GroupOffsetX = 0.0f; - window->DC.ColumnsOffsetX = 0.0f; - window->DC.CursorStartPos = window->Pos + ImVec2(window->DC.IndentX + window->DC.ColumnsOffsetX, window->TitleBarHeight() + window->MenuBarHeight() + window->WindowPadding.y - window->Scroll.y); - window->DC.CursorPos = window->DC.CursorStartPos; - window->DC.CursorPosPrevLine = window->DC.CursorPos; - window->DC.CursorMaxPos = window->DC.CursorStartPos; - window->DC.CurrentLineHeight = window->DC.PrevLineHeight = 0.0f; - window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset = 0.0f; - window->DC.NavHideHighlightOneFrame = false; - window->DC.NavHasScroll = (GetScrollMaxY() > 0.0f); - window->DC.NavLayerActiveMask = window->DC.NavLayerActiveMaskNext; - window->DC.NavLayerActiveMaskNext = 0x00; - window->DC.MenuBarAppending = false; - window->DC.MenuBarOffsetX = ImMax(window->WindowPadding.x, style.ItemSpacing.x); - window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; - window->DC.ChildWindows.resize(0); - window->DC.LayoutType = ImGuiLayoutType_Vertical; - window->DC.ParentLayoutType = parent_window ? parent_window->DC.LayoutType : ImGuiLayoutType_Vertical; - window->DC.ItemFlags = ImGuiItemFlags_Default_; - window->DC.ItemWidth = window->ItemWidthDefault; - window->DC.TextWrapPos = -1.0f; // disabled - window->DC.ItemFlagsStack.resize(0); - window->DC.ItemWidthStack.resize(0); - window->DC.TextWrapPosStack.resize(0); - window->DC.ColumnsSet = NULL; - window->DC.TreeDepth = 0; - window->DC.TreeDepthMayCloseOnPop = 0x00; - window->DC.StateStorage = &window->StateStorage; - window->DC.GroupStack.resize(0); - window->MenuColumns.Update(3, style.ItemSpacing.x, window_just_activated_by_user); + // Update ContentsRegionMax. All the variable it depends on are set above in this function. + window->ContentsRegionRect.Min.x = -window->Scroll.x + window->WindowPadding.x; + window->ContentsRegionRect.Min.y = -window->Scroll.y + window->WindowPadding.y + window->TitleBarHeight() + window->MenuBarHeight(); + window->ContentsRegionRect.Max.x = -window->Scroll.x - window->WindowPadding.x + (window->SizeContentsExplicit.x != 0.0f ? window->SizeContentsExplicit.x : (window->Size.x - window->ScrollbarSizes.x)); + window->ContentsRegionRect.Max.y = -window->Scroll.y - window->WindowPadding.y + (window->SizeContentsExplicit.y != 0.0f ? window->SizeContentsExplicit.y : (window->Size.y - window->ScrollbarSizes.y)); - if ((flags & ImGuiWindowFlags_ChildWindow) && (window->DC.ItemFlags != parent_window->DC.ItemFlags)) - { - window->DC.ItemFlags = parent_window->DC.ItemFlags; - window->DC.ItemFlagsStack.push_back(window->DC.ItemFlags); - } + // Setup drawing context + // (NB: That term "drawing context / DC" lost its meaning a long time ago. Initially was meant to hold transient data only. Nowadays difference between window-> and window->DC-> is dubious.) + window->DC.IndentX = 0.0f + window->WindowPadding.x - window->Scroll.x; + window->DC.GroupOffsetX = 0.0f; + window->DC.ColumnsOffsetX = 0.0f; + window->DC.CursorStartPos = window->Pos + ImVec2(window->DC.IndentX + window->DC.ColumnsOffsetX, window->TitleBarHeight() + window->MenuBarHeight() + window->WindowPadding.y - window->Scroll.y); + window->DC.CursorPos = window->DC.CursorStartPos; + window->DC.CursorPosPrevLine = window->DC.CursorPos; + window->DC.CursorMaxPos = window->DC.CursorStartPos; + window->DC.CurrentLineHeight = window->DC.PrevLineHeight = 0.0f; + window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset = 0.0f; + window->DC.NavHideHighlightOneFrame = false; + window->DC.NavHasScroll = (GetScrollMaxY() > 0.0f); + window->DC.NavLayerActiveMask = window->DC.NavLayerActiveMaskNext; + window->DC.NavLayerActiveMaskNext = 0x00; + window->DC.MenuBarAppending = false; + window->DC.MenuBarOffsetX = ImMax(window->WindowPadding.x, style.ItemSpacing.x); + window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; + window->DC.ChildWindows.resize(0); + window->DC.LayoutType = ImGuiLayoutType_Vertical; + window->DC.ParentLayoutType = parent_window ? parent_window->DC.LayoutType : ImGuiLayoutType_Vertical; + window->DC.ItemFlags = ImGuiItemFlags_Default_; + window->DC.ItemWidth = window->ItemWidthDefault; + window->DC.TextWrapPos = -1.0f; // disabled + window->DC.ItemFlagsStack.resize(0); + window->DC.ItemWidthStack.resize(0); + window->DC.TextWrapPosStack.resize(0); + window->DC.ColumnsSet = NULL; + window->DC.TreeDepth = 0; + window->DC.TreeDepthMayCloseOnPop = 0x00; + window->DC.StateStorage = &window->StateStorage; + window->DC.GroupStack.resize(0); + window->MenuColumns.Update(3, style.ItemSpacing.x, window_just_activated_by_user); - if (window->AutoFitFramesX > 0) - window->AutoFitFramesX--; - if (window->AutoFitFramesY > 0) - window->AutoFitFramesY--; + if ((flags & ImGuiWindowFlags_ChildWindow) && (window->DC.ItemFlags != parent_window->DC.ItemFlags)) + { + window->DC.ItemFlags = parent_window->DC.ItemFlags; + window->DC.ItemFlagsStack.push_back(window->DC.ItemFlags); + } - // Apply focus (we need to call FocusWindow() AFTER setting DC.CursorStartPos so our initial navigation reference rectangle can start around there) - if (want_focus) - { - FocusWindow(window); - NavInitWindow(window, false); - } + if (window->AutoFitFramesX > 0) + window->AutoFitFramesX--; + if (window->AutoFitFramesY > 0) + window->AutoFitFramesY--; - // Title bar - if (!(flags & ImGuiWindowFlags_NoTitleBar)) - { - // Close & collapse button are on layer 1 (same as menus) and don't default focus - const ImGuiItemFlags item_flags_backup = window->DC.ItemFlags; - window->DC.ItemFlags |= ImGuiItemFlags_NoNavDefaultFocus; - window->DC.NavLayerCurrent++; - window->DC.NavLayerCurrentMask <<= 1; + // Apply focus (we need to call FocusWindow() AFTER setting DC.CursorStartPos so our initial navigation reference rectangle can start around there) + if (want_focus) + { + FocusWindow(window); + NavInitWindow(window, false); + } - // Collapse button - if (!(flags & ImGuiWindowFlags_NoCollapse)) - { - ImGuiID id = window->GetID("#COLLAPSE"); - ImRect bb(window->Pos + style.FramePadding + ImVec2(1,1), window->Pos + style.FramePadding + ImVec2(g.FontSize,g.FontSize) - ImVec2(1,1)); - ItemAdd(bb, id); // To allow navigation - if (ButtonBehavior(bb, id, NULL, NULL)) - window->CollapseToggleWanted = true; // Defer collapsing to next frame as we are too far in the Begin() function - RenderNavHighlight(bb, id); - RenderTriangle(window->Pos + style.FramePadding, window->Collapsed ? ImGuiDir_Right : ImGuiDir_Down, 1.0f); - } + // Title bar + if (!(flags & ImGuiWindowFlags_NoTitleBar)) + { + // Close & collapse button are on layer 1 (same as menus) and don't default focus + const ImGuiItemFlags item_flags_backup = window->DC.ItemFlags; + window->DC.ItemFlags |= ImGuiItemFlags_NoNavDefaultFocus; + window->DC.NavLayerCurrent++; + window->DC.NavLayerCurrentMask <<= 1; - // Close button - if (p_open != NULL) - { - const float PAD = 2.0f; - const float rad = (window->TitleBarHeight() - PAD*2.0f) * 0.5f; - if (CloseButton(window->GetID("#CLOSE"), window->Rect().GetTR() + ImVec2(-PAD - rad, PAD + rad), rad)) - *p_open = false; - } + // Collapse button + if (!(flags & ImGuiWindowFlags_NoCollapse)) + { + ImGuiID id = window->GetID("#COLLAPSE"); + ImRect bb(window->Pos + style.FramePadding + ImVec2(1, 1), window->Pos + style.FramePadding + ImVec2(g.FontSize, g.FontSize) - ImVec2(1, 1)); + ItemAdd(bb, id); // To allow navigation + if (ButtonBehavior(bb, id, NULL, NULL)) + window->CollapseToggleWanted = true; // Defer collapsing to next frame as we are too far in the Begin() function + RenderNavHighlight(bb, id); + RenderTriangle(window->Pos + style.FramePadding, window->Collapsed ? ImGuiDir_Right : ImGuiDir_Down, 1.0f); + } - window->DC.NavLayerCurrent--; - window->DC.NavLayerCurrentMask >>= 1; - window->DC.ItemFlags = item_flags_backup; + // Close button + if (p_open != NULL) + { + const float PAD = 2.0f; + const float rad = (window->TitleBarHeight() - PAD * 2.0f) * 0.5f; + if (CloseButton(window->GetID("#CLOSE"), window->Rect().GetTR() + ImVec2(-PAD - rad, PAD + rad), rad)) + *p_open = false; + } - // Title text (FIXME: refactor text alignment facilities along with RenderText helpers) - ImVec2 text_size = CalcTextSize(name, NULL, true); - ImRect text_r = title_bar_rect; - float pad_left = (flags & ImGuiWindowFlags_NoCollapse) == 0 ? (style.FramePadding.x + g.FontSize + style.ItemInnerSpacing.x) : style.FramePadding.x; - float pad_right = (p_open != NULL) ? (style.FramePadding.x + g.FontSize + style.ItemInnerSpacing.x) : style.FramePadding.x; - if (style.WindowTitleAlign.x > 0.0f) pad_right = ImLerp(pad_right, pad_left, style.WindowTitleAlign.x); - text_r.Min.x += pad_left; - text_r.Max.x -= pad_right; - ImRect clip_rect = text_r; - clip_rect.Max.x = window->Pos.x + window->Size.x - (p_open ? title_bar_rect.GetHeight() - 3 : style.FramePadding.x); // Match the size of CloseButton() - RenderTextClipped(text_r.Min, text_r.Max, name, NULL, &text_size, style.WindowTitleAlign, &clip_rect); - } + window->DC.NavLayerCurrent--; + window->DC.NavLayerCurrentMask >>= 1; + window->DC.ItemFlags = item_flags_backup; - // Save clipped aabb so we can access it in constant-time in FindHoveredWindow() - window->WindowRectClipped = window->Rect(); - window->WindowRectClipped.ClipWith(window->ClipRect); + // Title text (FIXME: refactor text alignment facilities along with RenderText helpers) + ImVec2 text_size = CalcTextSize(name, NULL, true); + ImRect text_r = title_bar_rect; + float pad_left = (flags & ImGuiWindowFlags_NoCollapse) == 0 ? (style.FramePadding.x + g.FontSize + style.ItemInnerSpacing.x) : style.FramePadding.x; + float pad_right = (p_open != NULL) ? (style.FramePadding.x + g.FontSize + style.ItemInnerSpacing.x) : style.FramePadding.x; + if (style.WindowTitleAlign.x > 0.0f) pad_right = ImLerp(pad_right, pad_left, style.WindowTitleAlign.x); + text_r.Min.x += pad_left; + text_r.Max.x -= pad_right; + ImRect clip_rect = text_r; + clip_rect.Max.x = window->Pos.x + window->Size.x - (p_open ? title_bar_rect.GetHeight() - 3 : style.FramePadding.x); // Match the size of CloseButton() + RenderTextClipped(text_r.Min, text_r.Max, name, NULL, &text_size, style.WindowTitleAlign, &clip_rect); + } - // Pressing CTRL+C while holding on a window copy its content to the clipboard - // This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope. - // Maybe we can support CTRL+C on every element? - /* + // Save clipped aabb so we can access it in constant-time in FindHoveredWindow() + window->WindowRectClipped = window->Rect(); + window->WindowRectClipped.ClipWith(window->ClipRect); + + // Pressing CTRL+C while holding on a window copy its content to the clipboard + // This works but 1. doesn't handle multiple Begin/End pairs, 2. recursing into another Begin/End pair - so we need to work that out and add better logging scope. + // Maybe we can support CTRL+C on every element? + /* if (g.ActiveId == move_id) if (g.IO.KeyCtrl && IsKeyPressedMap(ImGuiKey_C)) ImGui::LogToClipboard(); */ - // Inner rectangle - // We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame - // Note that if our window is collapsed we will end up with a null clipping rectangle which is the correct behavior. - window->InnerRect.Min.x = title_bar_rect.Min.x + window->WindowBorderSize; - window->InnerRect.Min.y = title_bar_rect.Max.y + window->MenuBarHeight() + (((flags & ImGuiWindowFlags_MenuBar) || !(flags & ImGuiWindowFlags_NoTitleBar)) ? style.FrameBorderSize : window->WindowBorderSize); - window->InnerRect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x - window->WindowBorderSize; - window->InnerRect.Max.y = window->Pos.y + window->Size.y - window->ScrollbarSizes.y - window->WindowBorderSize; - //window->DrawList->AddRect(window->InnerRect.Min, window->InnerRect.Max, IM_COL32_WHITE); + // Inner rectangle + // We set this up after processing the resize grip so that our clip rectangle doesn't lag by a frame + // Note that if our window is collapsed we will end up with a null clipping rectangle which is the correct behavior. + window->InnerRect.Min.x = title_bar_rect.Min.x + window->WindowBorderSize; + window->InnerRect.Min.y = title_bar_rect.Max.y + window->MenuBarHeight() + (((flags & ImGuiWindowFlags_MenuBar) || !(flags & ImGuiWindowFlags_NoTitleBar)) ? style.FrameBorderSize : window->WindowBorderSize); + window->InnerRect.Max.x = window->Pos.x + window->Size.x - window->ScrollbarSizes.x - window->WindowBorderSize; + window->InnerRect.Max.y = window->Pos.y + window->Size.y - window->ScrollbarSizes.y - window->WindowBorderSize; + //window->DrawList->AddRect(window->InnerRect.Min, window->InnerRect.Max, IM_COL32_WHITE); - // After Begin() we fill the last item / hovered data using the title bar data. Make that a standard behavior (to allow usage of context menus on title bar only, etc.). - window->DC.LastItemId = window->MoveId; - window->DC.LastItemStatusFlags = IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0; - window->DC.LastItemRect = title_bar_rect; - } + // After Begin() we fill the last item / hovered data using the title bar data. Make that a standard behavior (to allow usage of context menus on title bar only, etc.). + window->DC.LastItemId = window->MoveId; + window->DC.LastItemStatusFlags = IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0; + window->DC.LastItemRect = title_bar_rect; + } - // Inner clipping rectangle - // Force round operator last to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. - const float border_size = window->WindowBorderSize; - ImRect clip_rect; - clip_rect.Min.x = ImFloor(0.5f + window->InnerRect.Min.x + ImMax(0.0f, ImFloor(window->WindowPadding.x*0.5f - border_size))); - clip_rect.Min.y = ImFloor(0.5f + window->InnerRect.Min.y); - clip_rect.Max.x = ImFloor(0.5f + window->InnerRect.Max.x - ImMax(0.0f, ImFloor(window->WindowPadding.x*0.5f - border_size))); - clip_rect.Max.y = ImFloor(0.5f + window->InnerRect.Max.y); - PushClipRect(clip_rect.Min, clip_rect.Max, true); + // Inner clipping rectangle + // Force round operator last to ensure that e.g. (int)(max.x-min.x) in user's render code produce correct result. + const float border_size = window->WindowBorderSize; + ImRect clip_rect; + clip_rect.Min.x = ImFloor(0.5f + window->InnerRect.Min.x + ImMax(0.0f, ImFloor(window->WindowPadding.x * 0.5f - border_size))); + clip_rect.Min.y = ImFloor(0.5f + window->InnerRect.Min.y); + clip_rect.Max.x = ImFloor(0.5f + window->InnerRect.Max.x - ImMax(0.0f, ImFloor(window->WindowPadding.x * 0.5f - border_size))); + clip_rect.Max.y = ImFloor(0.5f + window->InnerRect.Max.y); + PushClipRect(clip_rect.Min, clip_rect.Max, true); - // Clear 'accessed' flag last thing (After PushClipRect which will set the flag. We want the flag to stay false when the default "Debug" window is unused) - if (first_begin_of_the_frame) - window->WriteAccessed = false; + // Clear 'accessed' flag last thing (After PushClipRect which will set the flag. We want the flag to stay false when the default "Debug" window is unused) + if (first_begin_of_the_frame) + window->WriteAccessed = false; - window->BeginCount++; - g.NextWindowData.SizeConstraintCond = 0; + window->BeginCount++; + g.NextWindowData.SizeConstraintCond = 0; - // Child window can be out of sight and have "negative" clip windows. - // Mark them as collapsed so commands are skipped earlier (we can't manually collapse because they have no title bar). - if (flags & ImGuiWindowFlags_ChildWindow) - { - IM_ASSERT((flags & ImGuiWindowFlags_NoTitleBar) != 0); - window->Collapsed = parent_window && parent_window->Collapsed; + // Child window can be out of sight and have "negative" clip windows. + // Mark them as collapsed so commands are skipped earlier (we can't manually collapse because they have no title bar). + if (flags & ImGuiWindowFlags_ChildWindow) + { + IM_ASSERT((flags & ImGuiWindowFlags_NoTitleBar) != 0); + window->Collapsed = parent_window && parent_window->Collapsed; - if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0) - window->Collapsed |= (window->WindowRectClipped.Min.x >= window->WindowRectClipped.Max.x || window->WindowRectClipped.Min.y >= window->WindowRectClipped.Max.y); + if (!(flags & ImGuiWindowFlags_AlwaysAutoResize) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0) + window->Collapsed |= (window->WindowRectClipped.Min.x >= window->WindowRectClipped.Max.x || window->WindowRectClipped.Min.y >= window->WindowRectClipped.Max.y); - // We also hide the window from rendering because we've already added its border to the command list. - // (we could perform the check earlier in the function but it is simpler at this point) - if (window->Collapsed) - window->Active = false; - } - if (style.Alpha <= 0.0f) - window->Active = false; + // We also hide the window from rendering because we've already added its border to the command list. + // (we could perform the check earlier in the function but it is simpler at this point) + if (window->Collapsed) + window->Active = false; + } + if (style.Alpha <= 0.0f) + window->Active = false; - // Return false if we don't intend to display anything to allow user to perform an early out optimization - window->SkipItems = (window->Collapsed || !window->Active) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0; - return !window->SkipItems; + // Return false if we don't intend to display anything to allow user to perform an early out optimization + window->SkipItems = (window->Collapsed || !window->Active) && window->AutoFitFramesX <= 0 && window->AutoFitFramesY <= 0; + return !window->SkipItems; } // Old Begin() API with 5 parameters, avoid calling this version directly! Use SetNextWindowSize()/SetNextWindowBgAlpha() + Begin() instead. #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS bool ImGui::Begin(const char* name, bool* p_open, const ImVec2& size_first_use, float bg_alpha_override, ImGuiWindowFlags flags) { - // Old API feature: we could pass the initial window size as a parameter. This was misleading because it only had an effect if the window didn't have data in the .ini file. - if (size_first_use.x != 0.0f || size_first_use.y != 0.0f) - ImGui::SetNextWindowSize(size_first_use, ImGuiCond_FirstUseEver); + // Old API feature: we could pass the initial window size as a parameter. This was misleading because it only had an effect if the window didn't have data in the .ini file. + if (size_first_use.x != 0.0f || size_first_use.y != 0.0f) + ImGui::SetNextWindowSize(size_first_use, ImGuiCond_FirstUseEver); - // Old API feature: override the window background alpha with a parameter. - if (bg_alpha_override >= 0.0f) - ImGui::SetNextWindowBgAlpha(bg_alpha_override); + // Old API feature: override the window background alpha with a parameter. + if (bg_alpha_override >= 0.0f) + ImGui::SetNextWindowBgAlpha(bg_alpha_override); - return ImGui::Begin(name, p_open, flags); + return ImGui::Begin(name, p_open, flags); } -#endif // IMGUI_DISABLE_OBSOLETE_FUNCTIONS +#endif // IMGUI_DISABLE_OBSOLETE_FUNCTIONS void ImGui::End() { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; - if (window->DC.ColumnsSet != NULL) - EndColumns(); - PopClipRect(); // Inner window clip rectangle + if (window->DC.ColumnsSet != NULL) + EndColumns(); + PopClipRect(); // Inner window clip rectangle - // Stop logging - if (!(window->Flags & ImGuiWindowFlags_ChildWindow)) // FIXME: add more options for scope of logging - LogFinish(); + // Stop logging + if (!(window->Flags & ImGuiWindowFlags_ChildWindow)) // FIXME: add more options for scope of logging + LogFinish(); - // Pop from window stack - g.CurrentWindowStack.pop_back(); - if (window->Flags & ImGuiWindowFlags_Popup) - g.CurrentPopupStack.pop_back(); - CheckStacksSize(window, false); - SetCurrentWindow(g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back()); + // Pop from window stack + g.CurrentWindowStack.pop_back(); + if (window->Flags & ImGuiWindowFlags_Popup) + g.CurrentPopupStack.pop_back(); + CheckStacksSize(window, false); + SetCurrentWindow(g.CurrentWindowStack.empty() ? NULL : g.CurrentWindowStack.back()); } // Vertical scrollbar @@ -6242,1549 +6384,1597 @@ void ImGui::End() // - We handle both horizontal and vertical scrollbars, which makes the terminology not ideal. void ImGui::Scrollbar(ImGuiLayoutType direction) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; - const bool horizontal = (direction == ImGuiLayoutType_Horizontal); - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(horizontal ? "#SCROLLX" : "#SCROLLY"); + const bool horizontal = (direction == ImGuiLayoutType_Horizontal); + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(horizontal ? "#SCROLLX" : "#SCROLLY"); - // Render background - bool other_scrollbar = (horizontal ? window->ScrollbarY : window->ScrollbarX); - float other_scrollbar_size_w = other_scrollbar ? style.ScrollbarSize : 0.0f; - const ImRect window_rect = window->Rect(); - const float border_size = window->WindowBorderSize; - ImRect bb = horizontal - ? ImRect(window->Pos.x + border_size, window_rect.Max.y - style.ScrollbarSize, window_rect.Max.x - other_scrollbar_size_w - border_size, window_rect.Max.y - border_size) - : ImRect(window_rect.Max.x - style.ScrollbarSize, window->Pos.y + border_size, window_rect.Max.x - border_size, window_rect.Max.y - other_scrollbar_size_w - border_size); - if (!horizontal) - bb.Min.y += window->TitleBarHeight() + ((window->Flags & ImGuiWindowFlags_MenuBar) ? window->MenuBarHeight() : 0.0f); - if (bb.GetWidth() <= 0.0f || bb.GetHeight() <= 0.0f) - return; + // Render background + bool other_scrollbar = (horizontal ? window->ScrollbarY : window->ScrollbarX); + float other_scrollbar_size_w = other_scrollbar ? style.ScrollbarSize : 0.0f; + const ImRect window_rect = window->Rect(); + const float border_size = window->WindowBorderSize; + ImRect bb = horizontal + ? ImRect(window->Pos.x + border_size, window_rect.Max.y - style.ScrollbarSize, window_rect.Max.x - other_scrollbar_size_w - border_size, window_rect.Max.y - border_size) + : ImRect(window_rect.Max.x - style.ScrollbarSize, window->Pos.y + border_size, window_rect.Max.x - border_size, window_rect.Max.y - other_scrollbar_size_w - border_size); + if (!horizontal) + bb.Min.y += window->TitleBarHeight() + ((window->Flags & ImGuiWindowFlags_MenuBar) ? window->MenuBarHeight() : 0.0f); + if (bb.GetWidth() <= 0.0f || bb.GetHeight() <= 0.0f) + return; - int window_rounding_corners; - if (horizontal) - window_rounding_corners = ImDrawCornerFlags_BotLeft | (other_scrollbar ? 0 : ImDrawCornerFlags_BotRight); - else - window_rounding_corners = (((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImDrawCornerFlags_TopRight : 0) | (other_scrollbar ? 0 : ImDrawCornerFlags_BotRight); - window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_ScrollbarBg), window->WindowRounding, window_rounding_corners); - bb.Expand(ImVec2(-ImClamp((float)(int)((bb.Max.x - bb.Min.x - 2.0f) * 0.5f), 0.0f, 3.0f), -ImClamp((float)(int)((bb.Max.y - bb.Min.y - 2.0f) * 0.5f), 0.0f, 3.0f))); + int window_rounding_corners; + if (horizontal) + window_rounding_corners = ImDrawCornerFlags_BotLeft | (other_scrollbar ? 0 : ImDrawCornerFlags_BotRight); + else + window_rounding_corners = (((window->Flags & ImGuiWindowFlags_NoTitleBar) && !(window->Flags & ImGuiWindowFlags_MenuBar)) ? ImDrawCornerFlags_TopRight : 0) | (other_scrollbar ? 0 : ImDrawCornerFlags_BotRight); + window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_ScrollbarBg), window->WindowRounding, window_rounding_corners); + bb.Expand(ImVec2(-ImClamp((float)(int)((bb.Max.x - bb.Min.x - 2.0f) * 0.5f), 0.0f, 3.0f), -ImClamp((float)(int)((bb.Max.y - bb.Min.y - 2.0f) * 0.5f), 0.0f, 3.0f))); - // V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar) - float scrollbar_size_v = horizontal ? bb.GetWidth() : bb.GetHeight(); - float scroll_v = horizontal ? window->Scroll.x : window->Scroll.y; - float win_size_avail_v = (horizontal ? window->SizeFull.x : window->SizeFull.y) - other_scrollbar_size_w; - float win_size_contents_v = horizontal ? window->SizeContents.x : window->SizeContents.y; + // V denote the main, longer axis of the scrollbar (= height for a vertical scrollbar) + float scrollbar_size_v = horizontal ? bb.GetWidth() : bb.GetHeight(); + float scroll_v = horizontal ? window->Scroll.x : window->Scroll.y; + float win_size_avail_v = (horizontal ? window->SizeFull.x : window->SizeFull.y) - other_scrollbar_size_w; + float win_size_contents_v = horizontal ? window->SizeContents.x : window->SizeContents.y; - // Calculate the height of our grabbable box. It generally represent the amount visible (vs the total scrollable amount) - // But we maintain a minimum size in pixel to allow for the user to still aim inside. - IM_ASSERT(ImMax(win_size_contents_v, win_size_avail_v) > 0.0f); // Adding this assert to check if the ImMax(XXX,1.0f) is still needed. PLEASE CONTACT ME if this triggers. - const float win_size_v = ImMax(ImMax(win_size_contents_v, win_size_avail_v), 1.0f); - const float grab_h_pixels = ImClamp(scrollbar_size_v * (win_size_avail_v / win_size_v), style.GrabMinSize, scrollbar_size_v); - const float grab_h_norm = grab_h_pixels / scrollbar_size_v; + // Calculate the height of our grabbable box. It generally represent the amount visible (vs the total scrollable amount) + // But we maintain a minimum size in pixel to allow for the user to still aim inside. + IM_ASSERT(ImMax(win_size_contents_v, win_size_avail_v) > 0.0f); // Adding this assert to check if the ImMax(XXX,1.0f) is still needed. PLEASE CONTACT ME if this triggers. + const float win_size_v = ImMax(ImMax(win_size_contents_v, win_size_avail_v), 1.0f); + const float grab_h_pixels = ImClamp(scrollbar_size_v * (win_size_avail_v / win_size_v), style.GrabMinSize, scrollbar_size_v); + const float grab_h_norm = grab_h_pixels / scrollbar_size_v; - // Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar(). - bool held = false; - bool hovered = false; - const bool previously_held = (g.ActiveId == id); - ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_NoNavFocus); + // Handle input right away. None of the code of Begin() is relying on scrolling position before calling Scrollbar(). + bool held = false; + bool hovered = false; + const bool previously_held = (g.ActiveId == id); + ButtonBehavior(bb, id, &hovered, &held, ImGuiButtonFlags_NoNavFocus); - float scroll_max = ImMax(1.0f, win_size_contents_v - win_size_avail_v); - float scroll_ratio = ImSaturate(scroll_v / scroll_max); - float grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v; - if (held && grab_h_norm < 1.0f) - { - float scrollbar_pos_v = horizontal ? bb.Min.x : bb.Min.y; - float mouse_pos_v = horizontal ? g.IO.MousePos.x : g.IO.MousePos.y; - float* click_delta_to_grab_center_v = horizontal ? &g.ScrollbarClickDeltaToGrabCenter.x : &g.ScrollbarClickDeltaToGrabCenter.y; + float scroll_max = ImMax(1.0f, win_size_contents_v - win_size_avail_v); + float scroll_ratio = ImSaturate(scroll_v / scroll_max); + float grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v; + if (held && grab_h_norm < 1.0f) + { + float scrollbar_pos_v = horizontal ? bb.Min.x : bb.Min.y; + float mouse_pos_v = horizontal ? g.IO.MousePos.x : g.IO.MousePos.y; + float* click_delta_to_grab_center_v = horizontal ? &g.ScrollbarClickDeltaToGrabCenter.x : &g.ScrollbarClickDeltaToGrabCenter.y; - // Click position in scrollbar normalized space (0.0f->1.0f) - const float clicked_v_norm = ImSaturate((mouse_pos_v - scrollbar_pos_v) / scrollbar_size_v); - SetHoveredID(id); + // Click position in scrollbar normalized space (0.0f->1.0f) + const float clicked_v_norm = ImSaturate((mouse_pos_v - scrollbar_pos_v) / scrollbar_size_v); + SetHoveredID(id); - bool seek_absolute = false; - if (!previously_held) - { - // On initial click calculate the distance between mouse and the center of the grab - if (clicked_v_norm >= grab_v_norm && clicked_v_norm <= grab_v_norm + grab_h_norm) - { - *click_delta_to_grab_center_v = clicked_v_norm - grab_v_norm - grab_h_norm*0.5f; - } - else - { - seek_absolute = true; - *click_delta_to_grab_center_v = 0.0f; - } - } + bool seek_absolute = false; + if (!previously_held) + { + // On initial click calculate the distance between mouse and the center of the grab + if (clicked_v_norm >= grab_v_norm && clicked_v_norm <= grab_v_norm + grab_h_norm) + { + *click_delta_to_grab_center_v = clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f; + } + else + { + seek_absolute = true; + *click_delta_to_grab_center_v = 0.0f; + } + } - // Apply scroll - // It is ok to modify Scroll here because we are being called in Begin() after the calculation of SizeContents and before setting up our starting position - const float scroll_v_norm = ImSaturate((clicked_v_norm - *click_delta_to_grab_center_v - grab_h_norm*0.5f) / (1.0f - grab_h_norm)); - scroll_v = (float)(int)(0.5f + scroll_v_norm * scroll_max);//(win_size_contents_v - win_size_v)); - if (horizontal) - window->Scroll.x = scroll_v; - else - window->Scroll.y = scroll_v; + // Apply scroll + // It is ok to modify Scroll here because we are being called in Begin() after the calculation of SizeContents and before setting up our starting position + const float scroll_v_norm = ImSaturate((clicked_v_norm - *click_delta_to_grab_center_v - grab_h_norm * 0.5f) / (1.0f - grab_h_norm)); + scroll_v = (float)(int)(0.5f + scroll_v_norm * scroll_max); //(win_size_contents_v - win_size_v)); + if (horizontal) + window->Scroll.x = scroll_v; + else + window->Scroll.y = scroll_v; - // Update values for rendering - scroll_ratio = ImSaturate(scroll_v / scroll_max); - grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v; + // Update values for rendering + scroll_ratio = ImSaturate(scroll_v / scroll_max); + grab_v_norm = scroll_ratio * (scrollbar_size_v - grab_h_pixels) / scrollbar_size_v; - // Update distance to grab now that we have seeked and saturated - if (seek_absolute) - *click_delta_to_grab_center_v = clicked_v_norm - grab_v_norm - grab_h_norm*0.5f; - } + // Update distance to grab now that we have seeked and saturated + if (seek_absolute) + *click_delta_to_grab_center_v = clicked_v_norm - grab_v_norm - grab_h_norm * 0.5f; + } - // Render - const ImU32 grab_col = GetColorU32(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab); - ImRect grab_rect; - if (horizontal) - grab_rect = ImRect(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm), bb.Min.y, ImMin(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm) + grab_h_pixels, window_rect.Max.x), bb.Max.y); - else - grab_rect = ImRect(bb.Min.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm), bb.Max.x, ImMin(ImLerp(bb.Min.y, bb.Max.y, grab_v_norm) + grab_h_pixels, window_rect.Max.y)); - window->DrawList->AddRectFilled(grab_rect.Min, grab_rect.Max, grab_col, style.ScrollbarRounding); + // Render + const ImU32 grab_col = GetColorU32(held ? ImGuiCol_ScrollbarGrabActive : hovered ? ImGuiCol_ScrollbarGrabHovered : ImGuiCol_ScrollbarGrab); + ImRect grab_rect; + if (horizontal) + grab_rect = ImRect(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm), bb.Min.y, ImMin(ImLerp(bb.Min.x, bb.Max.x, grab_v_norm) + grab_h_pixels, window_rect.Max.x), bb.Max.y); + else + grab_rect = ImRect(bb.Min.x, ImLerp(bb.Min.y, bb.Max.y, grab_v_norm), bb.Max.x, ImMin(ImLerp(bb.Min.y, bb.Max.y, grab_v_norm) + grab_h_pixels, window_rect.Max.y)); + window->DrawList->AddRectFilled(grab_rect.Min, grab_rect.Max, grab_col, style.ScrollbarRounding); } void ImGui::BringWindowToFront(ImGuiWindow* window) { - ImGuiContext& g = *GImGui; - ImGuiWindow* current_front_window = g.Windows.back(); - if (current_front_window == window || current_front_window->RootWindow == window) - return; - for (int i = g.Windows.Size - 2; i >= 0; i--) // We can ignore the front most window - if (g.Windows[i] == window) - { - g.Windows.erase(g.Windows.Data + i); - g.Windows.push_back(window); - break; - } + ImGuiContext& g = *GImGui; + ImGuiWindow* current_front_window = g.Windows.back(); + if (current_front_window == window || current_front_window->RootWindow == window) + return; + for (int i = g.Windows.Size - 2; i >= 0; i--) // We can ignore the front most window + if (g.Windows[i] == window) + { + g.Windows.erase(g.Windows.Data + i); + g.Windows.push_back(window); + break; + } } void ImGui::BringWindowToBack(ImGuiWindow* window) { - ImGuiContext& g = *GImGui; - if (g.Windows[0] == window) - return; - for (int i = 0; i < g.Windows.Size; i++) - if (g.Windows[i] == window) - { - memmove(&g.Windows[1], &g.Windows[0], (size_t)i * sizeof(ImGuiWindow*)); - g.Windows[0] = window; - break; - } + ImGuiContext& g = *GImGui; + if (g.Windows[0] == window) + return; + for (int i = 0; i < g.Windows.Size; i++) + if (g.Windows[i] == window) + { + memmove(&g.Windows[1], &g.Windows[0], (size_t)i * sizeof(ImGuiWindow*)); + g.Windows[0] = window; + break; + } } // Moving window to front of display and set focus (which happens to be back of our sorted list) void ImGui::FocusWindow(ImGuiWindow* window) { - ImGuiContext& g = *GImGui; + ImGuiContext& g = *GImGui; - if (g.NavWindow != window) - { - g.NavWindow = window; - if (window && g.NavDisableMouseHover) - g.NavMousePosDirty = true; - g.NavInitRequest = false; - g.NavId = window ? window->NavLastIds[0] : 0; // Restore NavId - g.NavIdIsAlive = false; - g.NavLayer = 0; - } + if (g.NavWindow != window) + { + g.NavWindow = window; + if (window && g.NavDisableMouseHover) + g.NavMousePosDirty = true; + g.NavInitRequest = false; + g.NavId = window ? window->NavLastIds[0] : 0; // Restore NavId + g.NavIdIsAlive = false; + g.NavLayer = 0; + } - // Passing NULL allow to disable keyboard focus - if (!window) - return; + // Passing NULL allow to disable keyboard focus + if (!window) + return; - // Move the root window to the top of the pile - if (window->RootWindow) - window = window->RootWindow; + // Move the root window to the top of the pile + if (window->RootWindow) + window = window->RootWindow; - // Steal focus on active widgets - if (window->Flags & ImGuiWindowFlags_Popup) // FIXME: This statement should be unnecessary. Need further testing before removing it.. - if (g.ActiveId != 0 && g.ActiveIdWindow && g.ActiveIdWindow->RootWindow != window) - ClearActiveID(); + // Steal focus on active widgets + if (window->Flags & ImGuiWindowFlags_Popup) // FIXME: This statement should be unnecessary. Need further testing before removing it.. + if (g.ActiveId != 0 && g.ActiveIdWindow && g.ActiveIdWindow->RootWindow != window) + ClearActiveID(); - // Bring to front - if (!(window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) - BringWindowToFront(window); + // Bring to front + if (!(window->Flags & ImGuiWindowFlags_NoBringToFrontOnFocus)) + BringWindowToFront(window); } void ImGui::FocusFrontMostActiveWindow(ImGuiWindow* ignore_window) { - ImGuiContext& g = *GImGui; - for (int i = g.Windows.Size - 1; i >= 0; i--) - if (g.Windows[i] != ignore_window && g.Windows[i]->WasActive && !(g.Windows[i]->Flags & ImGuiWindowFlags_ChildWindow)) - { - ImGuiWindow* focus_window = NavRestoreLastChildNavWindow(g.Windows[i]); - FocusWindow(focus_window); - return; - } + ImGuiContext& g = *GImGui; + for (int i = g.Windows.Size - 1; i >= 0; i--) + if (g.Windows[i] != ignore_window && g.Windows[i]->WasActive && !(g.Windows[i]->Flags & ImGuiWindowFlags_ChildWindow)) + { + ImGuiWindow* focus_window = NavRestoreLastChildNavWindow(g.Windows[i]); + FocusWindow(focus_window); + return; + } } void ImGui::PushItemWidth(float item_width) { - ImGuiWindow* window = GetCurrentWindow(); - window->DC.ItemWidth = (item_width == 0.0f ? window->ItemWidthDefault : item_width); - window->DC.ItemWidthStack.push_back(window->DC.ItemWidth); + ImGuiWindow* window = GetCurrentWindow(); + window->DC.ItemWidth = (item_width == 0.0f ? window->ItemWidthDefault : item_width); + window->DC.ItemWidthStack.push_back(window->DC.ItemWidth); } void ImGui::PushMultiItemsWidths(int components, float w_full) { - ImGuiWindow* window = GetCurrentWindow(); - const ImGuiStyle& style = GImGui->Style; - if (w_full <= 0.0f) - w_full = CalcItemWidth(); - const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.ItemInnerSpacing.x) * (components-1)) / (float)components)); - const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.ItemInnerSpacing.x) * (components-1))); - window->DC.ItemWidthStack.push_back(w_item_last); - for (int i = 0; i < components-1; i++) - window->DC.ItemWidthStack.push_back(w_item_one); - window->DC.ItemWidth = window->DC.ItemWidthStack.back(); + ImGuiWindow* window = GetCurrentWindow(); + const ImGuiStyle& style = GImGui->Style; + if (w_full <= 0.0f) + w_full = CalcItemWidth(); + const float w_item_one = ImMax(1.0f, (float)(int)((w_full - (style.ItemInnerSpacing.x) * (components - 1)) / (float)components)); + const float w_item_last = ImMax(1.0f, (float)(int)(w_full - (w_item_one + style.ItemInnerSpacing.x) * (components - 1))); + window->DC.ItemWidthStack.push_back(w_item_last); + for (int i = 0; i < components - 1; i++) + window->DC.ItemWidthStack.push_back(w_item_one); + window->DC.ItemWidth = window->DC.ItemWidthStack.back(); } void ImGui::PopItemWidth() { - ImGuiWindow* window = GetCurrentWindow(); - window->DC.ItemWidthStack.pop_back(); - window->DC.ItemWidth = window->DC.ItemWidthStack.empty() ? window->ItemWidthDefault : window->DC.ItemWidthStack.back(); + ImGuiWindow* window = GetCurrentWindow(); + window->DC.ItemWidthStack.pop_back(); + window->DC.ItemWidth = window->DC.ItemWidthStack.empty() ? window->ItemWidthDefault : window->DC.ItemWidthStack.back(); } float ImGui::CalcItemWidth() { - ImGuiWindow* window = GetCurrentWindowRead(); - float w = window->DC.ItemWidth; - if (w < 0.0f) - { - // Align to a right-side limit. We include 1 frame padding in the calculation because this is how the width is always used (we add 2 frame padding to it), but we could move that responsibility to the widget as well. - float width_to_right_edge = GetContentRegionAvail().x; - w = ImMax(1.0f, width_to_right_edge + w); - } - w = (float)(int)w; - return w; + ImGuiWindow* window = GetCurrentWindowRead(); + float w = window->DC.ItemWidth; + if (w < 0.0f) + { + // Align to a right-side limit. We include 1 frame padding in the calculation because this is how the width is always used (we add 2 frame padding to it), but we could move that responsibility to the widget as well. + float width_to_right_edge = GetContentRegionAvail().x; + w = ImMax(1.0f, width_to_right_edge + w); + } + w = (float)(int)w; + return w; } static ImFont* GetDefaultFont() { - ImGuiContext& g = *GImGui; - return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; + ImGuiContext& g = *GImGui; + return g.IO.FontDefault ? g.IO.FontDefault : g.IO.Fonts->Fonts[0]; } void ImGui::SetCurrentFont(ImFont* font) { - ImGuiContext& g = *GImGui; - IM_ASSERT(font && font->IsLoaded()); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ? - IM_ASSERT(font->Scale > 0.0f); - g.Font = font; - g.FontBaseSize = g.IO.FontGlobalScale * g.Font->FontSize * g.Font->Scale; - g.FontSize = g.CurrentWindow ? g.CurrentWindow->CalcFontSize() : 0.0f; + ImGuiContext& g = *GImGui; + IM_ASSERT(font && font->IsLoaded()); // Font Atlas not created. Did you call io.Fonts->GetTexDataAsRGBA32 / GetTexDataAsAlpha8 ? + IM_ASSERT(font->Scale > 0.0f); + g.Font = font; + g.FontBaseSize = g.IO.FontGlobalScale * g.Font->FontSize * g.Font->Scale; + g.FontSize = g.CurrentWindow ? g.CurrentWindow->CalcFontSize() : 0.0f; - ImFontAtlas* atlas = g.Font->ContainerAtlas; - g.DrawListSharedData.TexUvWhitePixel = atlas->TexUvWhitePixel; - g.DrawListSharedData.Font = g.Font; - g.DrawListSharedData.FontSize = g.FontSize; + ImFontAtlas* atlas = g.Font->ContainerAtlas; + g.DrawListSharedData.TexUvWhitePixel = atlas->TexUvWhitePixel; + g.DrawListSharedData.Font = g.Font; + g.DrawListSharedData.FontSize = g.FontSize; } void ImGui::PushFont(ImFont* font) { - ImGuiContext& g = *GImGui; - if (!font) - font = GetDefaultFont(); - SetCurrentFont(font); - g.FontStack.push_back(font); - g.CurrentWindow->DrawList->PushTextureID(font->ContainerAtlas->TexID); + ImGuiContext& g = *GImGui; + if (!font) + font = GetDefaultFont(); + SetCurrentFont(font); + g.FontStack.push_back(font); + g.CurrentWindow->DrawList->PushTextureID(font->ContainerAtlas->TexID); } -void ImGui::PopFont() +void ImGui::PopFont() { - ImGuiContext& g = *GImGui; - g.CurrentWindow->DrawList->PopTextureID(); - g.FontStack.pop_back(); - SetCurrentFont(g.FontStack.empty() ? GetDefaultFont() : g.FontStack.back()); + ImGuiContext& g = *GImGui; + g.CurrentWindow->DrawList->PopTextureID(); + g.FontStack.pop_back(); + SetCurrentFont(g.FontStack.empty() ? GetDefaultFont() : g.FontStack.back()); } void ImGui::PushItemFlag(ImGuiItemFlags option, bool enabled) { - ImGuiWindow* window = GetCurrentWindow(); - if (enabled) - window->DC.ItemFlags |= option; - else - window->DC.ItemFlags &= ~option; - window->DC.ItemFlagsStack.push_back(window->DC.ItemFlags); + ImGuiWindow* window = GetCurrentWindow(); + if (enabled) + window->DC.ItemFlags |= option; + else + window->DC.ItemFlags &= ~option; + window->DC.ItemFlagsStack.push_back(window->DC.ItemFlags); } void ImGui::PopItemFlag() { - ImGuiWindow* window = GetCurrentWindow(); - window->DC.ItemFlagsStack.pop_back(); - window->DC.ItemFlags = window->DC.ItemFlagsStack.empty() ? ImGuiItemFlags_Default_ : window->DC.ItemFlagsStack.back(); + ImGuiWindow* window = GetCurrentWindow(); + window->DC.ItemFlagsStack.pop_back(); + window->DC.ItemFlags = window->DC.ItemFlagsStack.empty() ? ImGuiItemFlags_Default_ : window->DC.ItemFlagsStack.back(); } void ImGui::PushAllowKeyboardFocus(bool allow_keyboard_focus) { - PushItemFlag(ImGuiItemFlags_AllowKeyboardFocus, allow_keyboard_focus); + PushItemFlag(ImGuiItemFlags_AllowKeyboardFocus, allow_keyboard_focus); } void ImGui::PopAllowKeyboardFocus() { - PopItemFlag(); + PopItemFlag(); } void ImGui::PushButtonRepeat(bool repeat) { - PushItemFlag(ImGuiItemFlags_ButtonRepeat, repeat); + PushItemFlag(ImGuiItemFlags_ButtonRepeat, repeat); } void ImGui::PopButtonRepeat() { - PopItemFlag(); + PopItemFlag(); } void ImGui::PushTextWrapPos(float wrap_pos_x) { - ImGuiWindow* window = GetCurrentWindow(); - window->DC.TextWrapPos = wrap_pos_x; - window->DC.TextWrapPosStack.push_back(wrap_pos_x); + ImGuiWindow* window = GetCurrentWindow(); + window->DC.TextWrapPos = wrap_pos_x; + window->DC.TextWrapPosStack.push_back(wrap_pos_x); } void ImGui::PopTextWrapPos() { - ImGuiWindow* window = GetCurrentWindow(); - window->DC.TextWrapPosStack.pop_back(); - window->DC.TextWrapPos = window->DC.TextWrapPosStack.empty() ? -1.0f : window->DC.TextWrapPosStack.back(); + ImGuiWindow* window = GetCurrentWindow(); + window->DC.TextWrapPosStack.pop_back(); + window->DC.TextWrapPos = window->DC.TextWrapPosStack.empty() ? -1.0f : window->DC.TextWrapPosStack.back(); } // FIXME: This may incur a round-trip (if the end user got their data from a float4) but eventually we aim to store the in-flight colors as ImU32 void ImGui::PushStyleColor(ImGuiCol idx, ImU32 col) { - ImGuiContext& g = *GImGui; - ImGuiColMod backup; - backup.Col = idx; - backup.BackupValue = g.Style.Colors[idx]; - g.ColorModifiers.push_back(backup); - g.Style.Colors[idx] = ColorConvertU32ToFloat4(col); + ImGuiContext& g = *GImGui; + ImGuiColMod backup; + backup.Col = idx; + backup.BackupValue = g.Style.Colors[idx]; + g.ColorModifiers.push_back(backup); + g.Style.Colors[idx] = ColorConvertU32ToFloat4(col); } void ImGui::PushStyleColor(ImGuiCol idx, const ImVec4& col) { - ImGuiContext& g = *GImGui; - ImGuiColMod backup; - backup.Col = idx; - backup.BackupValue = g.Style.Colors[idx]; - g.ColorModifiers.push_back(backup); - g.Style.Colors[idx] = col; + ImGuiContext& g = *GImGui; + ImGuiColMod backup; + backup.Col = idx; + backup.BackupValue = g.Style.Colors[idx]; + g.ColorModifiers.push_back(backup); + g.Style.Colors[idx] = col; } void ImGui::PopStyleColor(int count) { - ImGuiContext& g = *GImGui; - while (count > 0) - { - ImGuiColMod& backup = g.ColorModifiers.back(); - g.Style.Colors[backup.Col] = backup.BackupValue; - g.ColorModifiers.pop_back(); - count--; - } + ImGuiContext& g = *GImGui; + while (count > 0) + { + ImGuiColMod& backup = g.ColorModifiers.back(); + g.Style.Colors[backup.Col] = backup.BackupValue; + g.ColorModifiers.pop_back(); + count--; + } } struct ImGuiStyleVarInfo { - ImGuiDataType Type; - ImU32 Offset; - void* GetVarPtr(ImGuiStyle* style) const { return (void*)((unsigned char*)style + Offset); } + ImGuiDataType Type; + ImU32 Offset; + void* GetVarPtr(ImGuiStyle* style) const { return (void*)((unsigned char*)style + Offset); } }; static const ImGuiStyleVarInfo GStyleVarInfo[] = -{ - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha) }, // ImGuiStyleVar_Alpha - { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding) }, // ImGuiStyleVar_WindowPadding - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding) }, // ImGuiStyleVar_WindowRounding - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowBorderSize) }, // ImGuiStyleVar_WindowBorderSize - { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowMinSize) }, // ImGuiStyleVar_WindowMinSize - { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowTitleAlign) }, // ImGuiStyleVar_WindowTitleAlign - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildRounding) }, // ImGuiStyleVar_ChildRounding - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildBorderSize) }, // ImGuiStyleVar_ChildBorderSize - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupRounding) }, // ImGuiStyleVar_PopupRounding - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupBorderSize) }, // ImGuiStyleVar_PopupBorderSize - { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, FramePadding) }, // ImGuiStyleVar_FramePadding - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameRounding) }, // ImGuiStyleVar_FrameRounding - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameBorderSize) }, // ImGuiStyleVar_FrameBorderSize - { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemSpacing) }, // ImGuiStyleVar_ItemSpacing - { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemInnerSpacing) }, // ImGuiStyleVar_ItemInnerSpacing - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, IndentSpacing) }, // ImGuiStyleVar_IndentSpacing - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarSize) }, // ImGuiStyleVar_ScrollbarSize - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarRounding) }, // ImGuiStyleVar_ScrollbarRounding - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabMinSize) }, // ImGuiStyleVar_GrabMinSize - { ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabRounding) }, // ImGuiStyleVar_GrabRounding - { ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign + { + {ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, Alpha)}, // ImGuiStyleVar_Alpha + {ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowPadding)}, // ImGuiStyleVar_WindowPadding + {ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowRounding)}, // ImGuiStyleVar_WindowRounding + {ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowBorderSize)}, // ImGuiStyleVar_WindowBorderSize + {ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowMinSize)}, // ImGuiStyleVar_WindowMinSize + {ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, WindowTitleAlign)}, // ImGuiStyleVar_WindowTitleAlign + {ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildRounding)}, // ImGuiStyleVar_ChildRounding + {ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ChildBorderSize)}, // ImGuiStyleVar_ChildBorderSize + {ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupRounding)}, // ImGuiStyleVar_PopupRounding + {ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, PopupBorderSize)}, // ImGuiStyleVar_PopupBorderSize + {ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, FramePadding)}, // ImGuiStyleVar_FramePadding + {ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameRounding)}, // ImGuiStyleVar_FrameRounding + {ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, FrameBorderSize)}, // ImGuiStyleVar_FrameBorderSize + {ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemSpacing)}, // ImGuiStyleVar_ItemSpacing + {ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ItemInnerSpacing)}, // ImGuiStyleVar_ItemInnerSpacing + {ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, IndentSpacing)}, // ImGuiStyleVar_IndentSpacing + {ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarSize)}, // ImGuiStyleVar_ScrollbarSize + {ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, ScrollbarRounding)}, // ImGuiStyleVar_ScrollbarRounding + {ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabMinSize)}, // ImGuiStyleVar_GrabMinSize + {ImGuiDataType_Float, (ImU32)IM_OFFSETOF(ImGuiStyle, GrabRounding)}, // ImGuiStyleVar_GrabRounding + {ImGuiDataType_Float2, (ImU32)IM_OFFSETOF(ImGuiStyle, ButtonTextAlign)}, // ImGuiStyleVar_ButtonTextAlign }; static const ImGuiStyleVarInfo* GetStyleVarInfo(ImGuiStyleVar idx) { - IM_ASSERT(idx >= 0 && idx < ImGuiStyleVar_Count_); - IM_ASSERT(IM_ARRAYSIZE(GStyleVarInfo) == ImGuiStyleVar_Count_); - return &GStyleVarInfo[idx]; + IM_ASSERT(idx >= 0 && idx < ImGuiStyleVar_Count_); + IM_ASSERT(IM_ARRAYSIZE(GStyleVarInfo) == ImGuiStyleVar_Count_); + return &GStyleVarInfo[idx]; } void ImGui::PushStyleVar(ImGuiStyleVar idx, float val) { - const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx); - if (var_info->Type == ImGuiDataType_Float) - { - ImGuiContext& g = *GImGui; - float* pvar = (float*)var_info->GetVarPtr(&g.Style); - g.StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar)); - *pvar = val; - return; - } - IM_ASSERT(0); // Called function with wrong-type? Variable is not a float. + const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx); + if (var_info->Type == ImGuiDataType_Float) + { + ImGuiContext& g = *GImGui; + float* pvar = (float*)var_info->GetVarPtr(&g.Style); + g.StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar)); + *pvar = val; + return; + } + IM_ASSERT(0); // Called function with wrong-type? Variable is not a float. } void ImGui::PushStyleVar(ImGuiStyleVar idx, const ImVec2& val) { - const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx); - if (var_info->Type == ImGuiDataType_Float2) - { - ImGuiContext& g = *GImGui; - ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(&g.Style); - g.StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar)); - *pvar = val; - return; - } - IM_ASSERT(0); // Called function with wrong-type? Variable is not a ImVec2. + const ImGuiStyleVarInfo* var_info = GetStyleVarInfo(idx); + if (var_info->Type == ImGuiDataType_Float2) + { + ImGuiContext& g = *GImGui; + ImVec2* pvar = (ImVec2*)var_info->GetVarPtr(&g.Style); + g.StyleModifiers.push_back(ImGuiStyleMod(idx, *pvar)); + *pvar = val; + return; + } + IM_ASSERT(0); // Called function with wrong-type? Variable is not a ImVec2. } void ImGui::PopStyleVar(int count) { - ImGuiContext& g = *GImGui; - while (count > 0) - { - ImGuiStyleMod& backup = g.StyleModifiers.back(); - const ImGuiStyleVarInfo* info = GetStyleVarInfo(backup.VarIdx); - if (info->Type == ImGuiDataType_Float) (*(float*)info->GetVarPtr(&g.Style)) = backup.BackupFloat[0]; - else if (info->Type == ImGuiDataType_Float2) (*(ImVec2*)info->GetVarPtr(&g.Style)) = ImVec2(backup.BackupFloat[0], backup.BackupFloat[1]); - else if (info->Type == ImGuiDataType_Int) (*(int*)info->GetVarPtr(&g.Style)) = backup.BackupInt[0]; - g.StyleModifiers.pop_back(); - count--; - } + ImGuiContext& g = *GImGui; + while (count > 0) + { + ImGuiStyleMod& backup = g.StyleModifiers.back(); + const ImGuiStyleVarInfo* info = GetStyleVarInfo(backup.VarIdx); + if (info->Type == ImGuiDataType_Float) + (*(float*)info->GetVarPtr(&g.Style)) = backup.BackupFloat[0]; + else if (info->Type == ImGuiDataType_Float2) + (*(ImVec2*)info->GetVarPtr(&g.Style)) = ImVec2(backup.BackupFloat[0], backup.BackupFloat[1]); + else if (info->Type == ImGuiDataType_Int) + (*(int*)info->GetVarPtr(&g.Style)) = backup.BackupInt[0]; + g.StyleModifiers.pop_back(); + count--; + } } const char* ImGui::GetStyleColorName(ImGuiCol idx) { - // Create switch-case from enum with regexp: ImGuiCol_{.*}, --> case ImGuiCol_\1: return "\1"; - switch (idx) - { - case ImGuiCol_Text: return "Text"; - case ImGuiCol_TextDisabled: return "TextDisabled"; - case ImGuiCol_WindowBg: return "WindowBg"; - case ImGuiCol_ChildBg: return "ChildBg"; - case ImGuiCol_PopupBg: return "PopupBg"; - case ImGuiCol_Border: return "Border"; - case ImGuiCol_BorderShadow: return "BorderShadow"; - case ImGuiCol_FrameBg: return "FrameBg"; - case ImGuiCol_FrameBgHovered: return "FrameBgHovered"; - case ImGuiCol_FrameBgActive: return "FrameBgActive"; - case ImGuiCol_TitleBg: return "TitleBg"; - case ImGuiCol_TitleBgActive: return "TitleBgActive"; - case ImGuiCol_TitleBgCollapsed: return "TitleBgCollapsed"; - case ImGuiCol_MenuBarBg: return "MenuBarBg"; - case ImGuiCol_ScrollbarBg: return "ScrollbarBg"; - case ImGuiCol_ScrollbarGrab: return "ScrollbarGrab"; - case ImGuiCol_ScrollbarGrabHovered: return "ScrollbarGrabHovered"; - case ImGuiCol_ScrollbarGrabActive: return "ScrollbarGrabActive"; - case ImGuiCol_CheckMark: return "CheckMark"; - case ImGuiCol_SliderGrab: return "SliderGrab"; - case ImGuiCol_SliderGrabActive: return "SliderGrabActive"; - case ImGuiCol_Button: return "Button"; - case ImGuiCol_ButtonHovered: return "ButtonHovered"; - case ImGuiCol_ButtonActive: return "ButtonActive"; - case ImGuiCol_Header: return "Header"; - case ImGuiCol_HeaderHovered: return "HeaderHovered"; - case ImGuiCol_HeaderActive: return "HeaderActive"; - case ImGuiCol_Separator: return "Separator"; - case ImGuiCol_SeparatorHovered: return "SeparatorHovered"; - case ImGuiCol_SeparatorActive: return "SeparatorActive"; - case ImGuiCol_ResizeGrip: return "ResizeGrip"; - case ImGuiCol_ResizeGripHovered: return "ResizeGripHovered"; - case ImGuiCol_ResizeGripActive: return "ResizeGripActive"; - case ImGuiCol_CloseButton: return "CloseButton"; - case ImGuiCol_CloseButtonHovered: return "CloseButtonHovered"; - case ImGuiCol_CloseButtonActive: return "CloseButtonActive"; - case ImGuiCol_PlotLines: return "PlotLines"; - case ImGuiCol_PlotLinesHovered: return "PlotLinesHovered"; - case ImGuiCol_PlotHistogram: return "PlotHistogram"; - case ImGuiCol_PlotHistogramHovered: return "PlotHistogramHovered"; - case ImGuiCol_TextSelectedBg: return "TextSelectedBg"; - case ImGuiCol_ModalWindowDarkening: return "ModalWindowDarkening"; - case ImGuiCol_DragDropTarget: return "DragDropTarget"; - case ImGuiCol_NavHighlight: return "NavHighlight"; - case ImGuiCol_NavWindowingHighlight: return "NavWindowingHighlight"; - } - IM_ASSERT(0); - return "Unknown"; + // Create switch-case from enum with regexp: ImGuiCol_{.*}, --> case ImGuiCol_\1: return "\1"; + switch (idx) + { + case ImGuiCol_Text: + return "Text"; + case ImGuiCol_TextDisabled: + return "TextDisabled"; + case ImGuiCol_WindowBg: + return "WindowBg"; + case ImGuiCol_ChildBg: + return "ChildBg"; + case ImGuiCol_PopupBg: + return "PopupBg"; + case ImGuiCol_Border: + return "Border"; + case ImGuiCol_BorderShadow: + return "BorderShadow"; + case ImGuiCol_FrameBg: + return "FrameBg"; + case ImGuiCol_FrameBgHovered: + return "FrameBgHovered"; + case ImGuiCol_FrameBgActive: + return "FrameBgActive"; + case ImGuiCol_TitleBg: + return "TitleBg"; + case ImGuiCol_TitleBgActive: + return "TitleBgActive"; + case ImGuiCol_TitleBgCollapsed: + return "TitleBgCollapsed"; + case ImGuiCol_MenuBarBg: + return "MenuBarBg"; + case ImGuiCol_ScrollbarBg: + return "ScrollbarBg"; + case ImGuiCol_ScrollbarGrab: + return "ScrollbarGrab"; + case ImGuiCol_ScrollbarGrabHovered: + return "ScrollbarGrabHovered"; + case ImGuiCol_ScrollbarGrabActive: + return "ScrollbarGrabActive"; + case ImGuiCol_CheckMark: + return "CheckMark"; + case ImGuiCol_SliderGrab: + return "SliderGrab"; + case ImGuiCol_SliderGrabActive: + return "SliderGrabActive"; + case ImGuiCol_Button: + return "Button"; + case ImGuiCol_ButtonHovered: + return "ButtonHovered"; + case ImGuiCol_ButtonActive: + return "ButtonActive"; + case ImGuiCol_Header: + return "Header"; + case ImGuiCol_HeaderHovered: + return "HeaderHovered"; + case ImGuiCol_HeaderActive: + return "HeaderActive"; + case ImGuiCol_Separator: + return "Separator"; + case ImGuiCol_SeparatorHovered: + return "SeparatorHovered"; + case ImGuiCol_SeparatorActive: + return "SeparatorActive"; + case ImGuiCol_ResizeGrip: + return "ResizeGrip"; + case ImGuiCol_ResizeGripHovered: + return "ResizeGripHovered"; + case ImGuiCol_ResizeGripActive: + return "ResizeGripActive"; + case ImGuiCol_CloseButton: + return "CloseButton"; + case ImGuiCol_CloseButtonHovered: + return "CloseButtonHovered"; + case ImGuiCol_CloseButtonActive: + return "CloseButtonActive"; + case ImGuiCol_PlotLines: + return "PlotLines"; + case ImGuiCol_PlotLinesHovered: + return "PlotLinesHovered"; + case ImGuiCol_PlotHistogram: + return "PlotHistogram"; + case ImGuiCol_PlotHistogramHovered: + return "PlotHistogramHovered"; + case ImGuiCol_TextSelectedBg: + return "TextSelectedBg"; + case ImGuiCol_ModalWindowDarkening: + return "ModalWindowDarkening"; + case ImGuiCol_DragDropTarget: + return "DragDropTarget"; + case ImGuiCol_NavHighlight: + return "NavHighlight"; + case ImGuiCol_NavWindowingHighlight: + return "NavWindowingHighlight"; + } + IM_ASSERT(0); + return "Unknown"; } bool ImGui::IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent) { - if (window->RootWindow == potential_parent) - return true; - while (window != NULL) - { - if (window == potential_parent) - return true; - window = window->ParentWindow; - } - return false; + if (window->RootWindow == potential_parent) + return true; + while (window != NULL) + { + if (window == potential_parent) + return true; + window = window->ParentWindow; + } + return false; } bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags) { - IM_ASSERT((flags & ImGuiHoveredFlags_AllowWhenOverlapped) == 0); // Flags not supported by this function - ImGuiContext& g = *GImGui; + IM_ASSERT((flags & ImGuiHoveredFlags_AllowWhenOverlapped) == 0); // Flags not supported by this function + ImGuiContext& g = *GImGui; - if (flags & ImGuiHoveredFlags_AnyWindow) - { - if (g.HoveredWindow == NULL) - return false; - } - else - { - switch (flags & (ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows)) - { - case ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows: - if (g.HoveredRootWindow != g.CurrentWindow->RootWindow) - return false; - break; - case ImGuiHoveredFlags_RootWindow: - if (g.HoveredWindow != g.CurrentWindow->RootWindow) - return false; - break; - case ImGuiHoveredFlags_ChildWindows: - if (g.HoveredWindow == NULL || !IsWindowChildOf(g.HoveredWindow, g.CurrentWindow)) - return false; - break; - default: - if (g.HoveredWindow != g.CurrentWindow) - return false; - break; - } - } + if (flags & ImGuiHoveredFlags_AnyWindow) + { + if (g.HoveredWindow == NULL) + return false; + } + else + { + switch (flags & (ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows)) + { + case ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows: + if (g.HoveredRootWindow != g.CurrentWindow->RootWindow) + return false; + break; + case ImGuiHoveredFlags_RootWindow: + if (g.HoveredWindow != g.CurrentWindow->RootWindow) + return false; + break; + case ImGuiHoveredFlags_ChildWindows: + if (g.HoveredWindow == NULL || !IsWindowChildOf(g.HoveredWindow, g.CurrentWindow)) + return false; + break; + default: + if (g.HoveredWindow != g.CurrentWindow) + return false; + break; + } + } - if (!IsWindowContentHoverable(g.HoveredRootWindow, flags)) - return false; - if (!(flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) - if (g.ActiveId != 0 && !g.ActiveIdAllowOverlap && g.ActiveId != g.HoveredWindow->MoveId) - return false; - return true; + if (!IsWindowContentHoverable(g.HoveredRootWindow, flags)) + return false; + if (!(flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) + if (g.ActiveId != 0 && !g.ActiveIdAllowOverlap && g.ActiveId != g.HoveredWindow->MoveId) + return false; + return true; } bool ImGui::IsWindowFocused(ImGuiFocusedFlags flags) { - ImGuiContext& g = *GImGui; - IM_ASSERT(g.CurrentWindow); // Not inside a Begin()/End() + ImGuiContext& g = *GImGui; + IM_ASSERT(g.CurrentWindow); // Not inside a Begin()/End() - if (flags & ImGuiFocusedFlags_AnyWindow) - return g.NavWindow != NULL; + if (flags & ImGuiFocusedFlags_AnyWindow) + return g.NavWindow != NULL; - switch (flags & (ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows)) - { - case ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows: - return g.NavWindow && g.NavWindow->RootWindow == g.CurrentWindow->RootWindow; - case ImGuiFocusedFlags_RootWindow: - return g.NavWindow == g.CurrentWindow->RootWindow; - case ImGuiFocusedFlags_ChildWindows: - return g.NavWindow && IsWindowChildOf(g.NavWindow, g.CurrentWindow); - default: - return g.NavWindow == g.CurrentWindow; - } + switch (flags & (ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows)) + { + case ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows: + return g.NavWindow && g.NavWindow->RootWindow == g.CurrentWindow->RootWindow; + case ImGuiFocusedFlags_RootWindow: + return g.NavWindow == g.CurrentWindow->RootWindow; + case ImGuiFocusedFlags_ChildWindows: + return g.NavWindow && IsWindowChildOf(g.NavWindow, g.CurrentWindow); + default: + return g.NavWindow == g.CurrentWindow; + } } // Can we focus this window with CTRL+TAB (or PadMenu + PadFocusPrev/PadFocusNext) bool ImGui::IsWindowNavFocusable(ImGuiWindow* window) { - ImGuiContext& g = *GImGui; - return window->Active && window == window->RootWindowForTabbing && (!(window->Flags & ImGuiWindowFlags_NoNavFocus) || window == g.NavWindow); + ImGuiContext& g = *GImGui; + return window->Active && window == window->RootWindowForTabbing && (!(window->Flags & ImGuiWindowFlags_NoNavFocus) || window == g.NavWindow); } float ImGui::GetWindowWidth() { - ImGuiWindow* window = GImGui->CurrentWindow; - return window->Size.x; + ImGuiWindow* window = GImGui->CurrentWindow; + return window->Size.x; } float ImGui::GetWindowHeight() { - ImGuiWindow* window = GImGui->CurrentWindow; - return window->Size.y; + ImGuiWindow* window = GImGui->CurrentWindow; + return window->Size.y; } ImVec2 ImGui::GetWindowPos() { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - return window->Pos; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + return window->Pos; } static void SetWindowScrollX(ImGuiWindow* window, float new_scroll_x) { - window->DC.CursorMaxPos.x += window->Scroll.x; // SizeContents is generally computed based on CursorMaxPos which is affected by scroll position, so we need to apply our change to it. - window->Scroll.x = new_scroll_x; - window->DC.CursorMaxPos.x -= window->Scroll.x; + window->DC.CursorMaxPos.x += window->Scroll.x; // SizeContents is generally computed based on CursorMaxPos which is affected by scroll position, so we need to apply our change to it. + window->Scroll.x = new_scroll_x; + window->DC.CursorMaxPos.x -= window->Scroll.x; } static void SetWindowScrollY(ImGuiWindow* window, float new_scroll_y) { - window->DC.CursorMaxPos.y += window->Scroll.y; // SizeContents is generally computed based on CursorMaxPos which is affected by scroll position, so we need to apply our change to it. - window->Scroll.y = new_scroll_y; - window->DC.CursorMaxPos.y -= window->Scroll.y; + window->DC.CursorMaxPos.y += window->Scroll.y; // SizeContents is generally computed based on CursorMaxPos which is affected by scroll position, so we need to apply our change to it. + window->Scroll.y = new_scroll_y; + window->DC.CursorMaxPos.y -= window->Scroll.y; } static void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond) { - // Test condition (NB: bit 0 is always true) and clear flags for next time - if (cond && (window->SetWindowPosAllowFlags & cond) == 0) - return; - window->SetWindowPosAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); - window->SetWindowPosVal = ImVec2(FLT_MAX, FLT_MAX); + // Test condition (NB: bit 0 is always true) and clear flags for next time + if (cond && (window->SetWindowPosAllowFlags & cond) == 0) + return; + window->SetWindowPosAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); + window->SetWindowPosVal = ImVec2(FLT_MAX, FLT_MAX); - // Set - const ImVec2 old_pos = window->Pos; - window->PosFloat = pos; - window->Pos = ImFloor(pos); - window->DC.CursorPos += (window->Pos - old_pos); // As we happen to move the window while it is being appended to (which is a bad idea - will smear) let's at least offset the cursor - window->DC.CursorMaxPos += (window->Pos - old_pos); // And more importantly we need to adjust this so size calculation doesn't get affected. + // Set + const ImVec2 old_pos = window->Pos; + window->PosFloat = pos; + window->Pos = ImFloor(pos); + window->DC.CursorPos += (window->Pos - old_pos); // As we happen to move the window while it is being appended to (which is a bad idea - will smear) let's at least offset the cursor + window->DC.CursorMaxPos += (window->Pos - old_pos); // And more importantly we need to adjust this so size calculation doesn't get affected. } void ImGui::SetWindowPos(const ImVec2& pos, ImGuiCond cond) { - ImGuiWindow* window = GetCurrentWindowRead(); - SetWindowPos(window, pos, cond); + ImGuiWindow* window = GetCurrentWindowRead(); + SetWindowPos(window, pos, cond); } void ImGui::SetWindowPos(const char* name, const ImVec2& pos, ImGuiCond cond) { - if (ImGuiWindow* window = FindWindowByName(name)) - SetWindowPos(window, pos, cond); + if (ImGuiWindow* window = FindWindowByName(name)) + SetWindowPos(window, pos, cond); } ImVec2 ImGui::GetWindowSize() { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->Size; + ImGuiWindow* window = GetCurrentWindowRead(); + return window->Size; } static void SetWindowSize(ImGuiWindow* window, const ImVec2& size, ImGuiCond cond) { - // Test condition (NB: bit 0 is always true) and clear flags for next time - if (cond && (window->SetWindowSizeAllowFlags & cond) == 0) - return; - window->SetWindowSizeAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); + // Test condition (NB: bit 0 is always true) and clear flags for next time + if (cond && (window->SetWindowSizeAllowFlags & cond) == 0) + return; + window->SetWindowSizeAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); - // Set - if (size.x > 0.0f) - { - window->AutoFitFramesX = 0; - window->SizeFull.x = size.x; - } - else - { - window->AutoFitFramesX = 2; - window->AutoFitOnlyGrows = false; - } - if (size.y > 0.0f) - { - window->AutoFitFramesY = 0; - window->SizeFull.y = size.y; - } - else - { - window->AutoFitFramesY = 2; - window->AutoFitOnlyGrows = false; - } + // Set + if (size.x > 0.0f) + { + window->AutoFitFramesX = 0; + window->SizeFull.x = size.x; + } + else + { + window->AutoFitFramesX = 2; + window->AutoFitOnlyGrows = false; + } + if (size.y > 0.0f) + { + window->AutoFitFramesY = 0; + window->SizeFull.y = size.y; + } + else + { + window->AutoFitFramesY = 2; + window->AutoFitOnlyGrows = false; + } } void ImGui::SetWindowSize(const ImVec2& size, ImGuiCond cond) { - SetWindowSize(GImGui->CurrentWindow, size, cond); + SetWindowSize(GImGui->CurrentWindow, size, cond); } void ImGui::SetWindowSize(const char* name, const ImVec2& size, ImGuiCond cond) { - if (ImGuiWindow* window = FindWindowByName(name)) - SetWindowSize(window, size, cond); + if (ImGuiWindow* window = FindWindowByName(name)) + SetWindowSize(window, size, cond); } static void SetWindowCollapsed(ImGuiWindow* window, bool collapsed, ImGuiCond cond) { - // Test condition (NB: bit 0 is always true) and clear flags for next time - if (cond && (window->SetWindowCollapsedAllowFlags & cond) == 0) - return; - window->SetWindowCollapsedAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); + // Test condition (NB: bit 0 is always true) and clear flags for next time + if (cond && (window->SetWindowCollapsedAllowFlags & cond) == 0) + return; + window->SetWindowCollapsedAllowFlags &= ~(ImGuiCond_Once | ImGuiCond_FirstUseEver | ImGuiCond_Appearing); - // Set - window->Collapsed = collapsed; + // Set + window->Collapsed = collapsed; } void ImGui::SetWindowCollapsed(bool collapsed, ImGuiCond cond) { - SetWindowCollapsed(GImGui->CurrentWindow, collapsed, cond); + SetWindowCollapsed(GImGui->CurrentWindow, collapsed, cond); } bool ImGui::IsWindowCollapsed() { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->Collapsed; + ImGuiWindow* window = GetCurrentWindowRead(); + return window->Collapsed; } bool ImGui::IsWindowAppearing() { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->Appearing; + ImGuiWindow* window = GetCurrentWindowRead(); + return window->Appearing; } void ImGui::SetWindowCollapsed(const char* name, bool collapsed, ImGuiCond cond) { - if (ImGuiWindow* window = FindWindowByName(name)) - SetWindowCollapsed(window, collapsed, cond); + if (ImGuiWindow* window = FindWindowByName(name)) + SetWindowCollapsed(window, collapsed, cond); } void ImGui::SetWindowFocus() { - FocusWindow(GImGui->CurrentWindow); + FocusWindow(GImGui->CurrentWindow); } void ImGui::SetWindowFocus(const char* name) { - if (name) - { - if (ImGuiWindow* window = FindWindowByName(name)) - FocusWindow(window); - } - else - { - FocusWindow(NULL); - } + if (name) + { + if (ImGuiWindow* window = FindWindowByName(name)) + FocusWindow(window); + } + else + { + FocusWindow(NULL); + } } void ImGui::SetNextWindowPos(const ImVec2& pos, ImGuiCond cond, const ImVec2& pivot) { - ImGuiContext& g = *GImGui; - g.NextWindowData.PosVal = pos; - g.NextWindowData.PosPivotVal = pivot; - g.NextWindowData.PosCond = cond ? cond : ImGuiCond_Always; + ImGuiContext& g = *GImGui; + g.NextWindowData.PosVal = pos; + g.NextWindowData.PosPivotVal = pivot; + g.NextWindowData.PosCond = cond ? cond : ImGuiCond_Always; } void ImGui::SetNextWindowSize(const ImVec2& size, ImGuiCond cond) { - ImGuiContext& g = *GImGui; - g.NextWindowData.SizeVal = size; - g.NextWindowData.SizeCond = cond ? cond : ImGuiCond_Always; + ImGuiContext& g = *GImGui; + g.NextWindowData.SizeVal = size; + g.NextWindowData.SizeCond = cond ? cond : ImGuiCond_Always; } void ImGui::SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback, void* custom_callback_user_data) { - ImGuiContext& g = *GImGui; - g.NextWindowData.SizeConstraintCond = ImGuiCond_Always; - g.NextWindowData.SizeConstraintRect = ImRect(size_min, size_max); - g.NextWindowData.SizeCallback = custom_callback; - g.NextWindowData.SizeCallbackUserData = custom_callback_user_data; + ImGuiContext& g = *GImGui; + g.NextWindowData.SizeConstraintCond = ImGuiCond_Always; + g.NextWindowData.SizeConstraintRect = ImRect(size_min, size_max); + g.NextWindowData.SizeCallback = custom_callback; + g.NextWindowData.SizeCallbackUserData = custom_callback_user_data; } void ImGui::SetNextWindowContentSize(const ImVec2& size) { - ImGuiContext& g = *GImGui; - g.NextWindowData.ContentSizeVal = size; // In Begin() we will add the size of window decorations (title bar, menu etc.) to that to form a SizeContents value. - g.NextWindowData.ContentSizeCond = ImGuiCond_Always; + ImGuiContext& g = *GImGui; + g.NextWindowData.ContentSizeVal = size; // In Begin() we will add the size of window decorations (title bar, menu etc.) to that to form a SizeContents value. + g.NextWindowData.ContentSizeCond = ImGuiCond_Always; } void ImGui::SetNextWindowCollapsed(bool collapsed, ImGuiCond cond) { - ImGuiContext& g = *GImGui; - g.NextWindowData.CollapsedVal = collapsed; - g.NextWindowData.CollapsedCond = cond ? cond : ImGuiCond_Always; + ImGuiContext& g = *GImGui; + g.NextWindowData.CollapsedVal = collapsed; + g.NextWindowData.CollapsedCond = cond ? cond : ImGuiCond_Always; } void ImGui::SetNextWindowFocus() { - ImGuiContext& g = *GImGui; - g.NextWindowData.FocusCond = ImGuiCond_Always; // Using a Cond member for consistency (may transition all of them to single flag set for fast Clear() op) + ImGuiContext& g = *GImGui; + g.NextWindowData.FocusCond = ImGuiCond_Always; // Using a Cond member for consistency (may transition all of them to single flag set for fast Clear() op) } void ImGui::SetNextWindowBgAlpha(float alpha) { - ImGuiContext& g = *GImGui; - g.NextWindowData.BgAlphaVal = alpha; - g.NextWindowData.BgAlphaCond = ImGuiCond_Always; // Using a Cond member for consistency (may transition all of them to single flag set for fast Clear() op) + ImGuiContext& g = *GImGui; + g.NextWindowData.BgAlphaVal = alpha; + g.NextWindowData.BgAlphaCond = ImGuiCond_Always; // Using a Cond member for consistency (may transition all of them to single flag set for fast Clear() op) } // In window space (not screen space!) ImVec2 ImGui::GetContentRegionMax() { - ImGuiWindow* window = GetCurrentWindowRead(); - ImVec2 mx = window->ContentsRegionRect.Max; - if (window->DC.ColumnsSet) - mx.x = GetColumnOffset(window->DC.ColumnsSet->Current + 1) - window->WindowPadding.x; - return mx; + ImGuiWindow* window = GetCurrentWindowRead(); + ImVec2 mx = window->ContentsRegionRect.Max; + if (window->DC.ColumnsSet) + mx.x = GetColumnOffset(window->DC.ColumnsSet->Current + 1) - window->WindowPadding.x; + return mx; } ImVec2 ImGui::GetContentRegionAvail() { - ImGuiWindow* window = GetCurrentWindowRead(); - return GetContentRegionMax() - (window->DC.CursorPos - window->Pos); + ImGuiWindow* window = GetCurrentWindowRead(); + return GetContentRegionMax() - (window->DC.CursorPos - window->Pos); } float ImGui::GetContentRegionAvailWidth() { - return GetContentRegionAvail().x; + return GetContentRegionAvail().x; } // In window space (not screen space!) ImVec2 ImGui::GetWindowContentRegionMin() { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->ContentsRegionRect.Min; + ImGuiWindow* window = GetCurrentWindowRead(); + return window->ContentsRegionRect.Min; } ImVec2 ImGui::GetWindowContentRegionMax() { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->ContentsRegionRect.Max; + ImGuiWindow* window = GetCurrentWindowRead(); + return window->ContentsRegionRect.Max; } float ImGui::GetWindowContentRegionWidth() { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->ContentsRegionRect.Max.x - window->ContentsRegionRect.Min.x; + ImGuiWindow* window = GetCurrentWindowRead(); + return window->ContentsRegionRect.Max.x - window->ContentsRegionRect.Min.x; } float ImGui::GetTextLineHeight() { - ImGuiContext& g = *GImGui; - return g.FontSize; + ImGuiContext& g = *GImGui; + return g.FontSize; } float ImGui::GetTextLineHeightWithSpacing() { - ImGuiContext& g = *GImGui; - return g.FontSize + g.Style.ItemSpacing.y; + ImGuiContext& g = *GImGui; + return g.FontSize + g.Style.ItemSpacing.y; } float ImGui::GetFrameHeight() { - ImGuiContext& g = *GImGui; - return g.FontSize + g.Style.FramePadding.y * 2.0f; + ImGuiContext& g = *GImGui; + return g.FontSize + g.Style.FramePadding.y * 2.0f; } float ImGui::GetFrameHeightWithSpacing() { - ImGuiContext& g = *GImGui; - return g.FontSize + g.Style.FramePadding.y * 2.0f + g.Style.ItemSpacing.y; + ImGuiContext& g = *GImGui; + return g.FontSize + g.Style.FramePadding.y * 2.0f + g.Style.ItemSpacing.y; } ImDrawList* ImGui::GetWindowDrawList() { - ImGuiWindow* window = GetCurrentWindow(); - return window->DrawList; + ImGuiWindow* window = GetCurrentWindow(); + return window->DrawList; } ImFont* ImGui::GetFont() { - return GImGui->Font; + return GImGui->Font; } float ImGui::GetFontSize() { - return GImGui->FontSize; + return GImGui->FontSize; } ImVec2 ImGui::GetFontTexUvWhitePixel() { - return GImGui->DrawListSharedData.TexUvWhitePixel; + return GImGui->DrawListSharedData.TexUvWhitePixel; } void ImGui::SetWindowFontScale(float scale) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - window->FontWindowScale = scale; - g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize(); + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + window->FontWindowScale = scale; + g.FontSize = g.DrawListSharedData.FontSize = window->CalcFontSize(); } // User generally sees positions in window coordinates. Internally we store CursorPos in absolute screen coordinates because it is more convenient. // Conversion happens as we pass the value to user, but it makes our naming convention confusing because GetCursorPos() == (DC.CursorPos - window.Pos). May want to rename 'DC.CursorPos'. ImVec2 ImGui::GetCursorPos() { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.CursorPos - window->Pos + window->Scroll; + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.CursorPos - window->Pos + window->Scroll; } float ImGui::GetCursorPosX() { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.CursorPos.x - window->Pos.x + window->Scroll.x; + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.CursorPos.x - window->Pos.x + window->Scroll.x; } float ImGui::GetCursorPosY() { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.CursorPos.y - window->Pos.y + window->Scroll.y; + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.CursorPos.y - window->Pos.y + window->Scroll.y; } void ImGui::SetCursorPos(const ImVec2& local_pos) { - ImGuiWindow* window = GetCurrentWindow(); - window->DC.CursorPos = window->Pos - window->Scroll + local_pos; - window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos); + ImGuiWindow* window = GetCurrentWindow(); + window->DC.CursorPos = window->Pos - window->Scroll + local_pos; + window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos); } void ImGui::SetCursorPosX(float x) { - ImGuiWindow* window = GetCurrentWindow(); - window->DC.CursorPos.x = window->Pos.x - window->Scroll.x + x; - window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPos.x); + ImGuiWindow* window = GetCurrentWindow(); + window->DC.CursorPos.x = window->Pos.x - window->Scroll.x + x; + window->DC.CursorMaxPos.x = ImMax(window->DC.CursorMaxPos.x, window->DC.CursorPos.x); } void ImGui::SetCursorPosY(float y) { - ImGuiWindow* window = GetCurrentWindow(); - window->DC.CursorPos.y = window->Pos.y - window->Scroll.y + y; - window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y); + ImGuiWindow* window = GetCurrentWindow(); + window->DC.CursorPos.y = window->Pos.y - window->Scroll.y + y; + window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, window->DC.CursorPos.y); } ImVec2 ImGui::GetCursorStartPos() { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.CursorStartPos - window->Pos; + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.CursorStartPos - window->Pos; } ImVec2 ImGui::GetCursorScreenPos() { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.CursorPos; + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.CursorPos; } void ImGui::SetCursorScreenPos(const ImVec2& screen_pos) { - ImGuiWindow* window = GetCurrentWindow(); - window->DC.CursorPos = screen_pos; - window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos); + ImGuiWindow* window = GetCurrentWindow(); + window->DC.CursorPos = screen_pos; + window->DC.CursorMaxPos = ImMax(window->DC.CursorMaxPos, window->DC.CursorPos); } float ImGui::GetScrollX() { - return GImGui->CurrentWindow->Scroll.x; + return GImGui->CurrentWindow->Scroll.x; } float ImGui::GetScrollY() { - return GImGui->CurrentWindow->Scroll.y; + return GImGui->CurrentWindow->Scroll.y; } float ImGui::GetScrollMaxX() { - return GetScrollMaxX(GImGui->CurrentWindow); + return GetScrollMaxX(GImGui->CurrentWindow); } float ImGui::GetScrollMaxY() { - return GetScrollMaxY(GImGui->CurrentWindow); + return GetScrollMaxY(GImGui->CurrentWindow); } void ImGui::SetScrollX(float scroll_x) { - ImGuiWindow* window = GetCurrentWindow(); - window->ScrollTarget.x = scroll_x; - window->ScrollTargetCenterRatio.x = 0.0f; + ImGuiWindow* window = GetCurrentWindow(); + window->ScrollTarget.x = scroll_x; + window->ScrollTargetCenterRatio.x = 0.0f; } void ImGui::SetScrollY(float scroll_y) { - ImGuiWindow* window = GetCurrentWindow(); - window->ScrollTarget.y = scroll_y + window->TitleBarHeight() + window->MenuBarHeight(); // title bar height canceled out when using ScrollTargetRelY - window->ScrollTargetCenterRatio.y = 0.0f; + ImGuiWindow* window = GetCurrentWindow(); + window->ScrollTarget.y = scroll_y + window->TitleBarHeight() + window->MenuBarHeight(); // title bar height canceled out when using ScrollTargetRelY + window->ScrollTargetCenterRatio.y = 0.0f; } void ImGui::SetScrollFromPosY(float pos_y, float center_y_ratio) { - // We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size - ImGuiWindow* window = GetCurrentWindow(); - IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f); - window->ScrollTarget.y = (float)(int)(pos_y + window->Scroll.y); - window->ScrollTargetCenterRatio.y = center_y_ratio; + // We store a target position so centering can occur on the next frame when we are guaranteed to have a known window size + ImGuiWindow* window = GetCurrentWindow(); + IM_ASSERT(center_y_ratio >= 0.0f && center_y_ratio <= 1.0f); + window->ScrollTarget.y = (float)(int)(pos_y + window->Scroll.y); + window->ScrollTargetCenterRatio.y = center_y_ratio; - // Minor hack to to make scrolling to top/bottom of window take account of WindowPadding, it looks more right to the user this way - if (center_y_ratio <= 0.0f && window->ScrollTarget.y <= window->WindowPadding.y) - window->ScrollTarget.y = 0.0f; - else if (center_y_ratio >= 1.0f && window->ScrollTarget.y >= window->SizeContents.y - window->WindowPadding.y + GImGui->Style.ItemSpacing.y) - window->ScrollTarget.y = window->SizeContents.y; + // Minor hack to to make scrolling to top/bottom of window take account of WindowPadding, it looks more right to the user this way + if (center_y_ratio <= 0.0f && window->ScrollTarget.y <= window->WindowPadding.y) + window->ScrollTarget.y = 0.0f; + else if (center_y_ratio >= 1.0f && window->ScrollTarget.y >= window->SizeContents.y - window->WindowPadding.y + GImGui->Style.ItemSpacing.y) + window->ScrollTarget.y = window->SizeContents.y; } // center_y_ratio: 0.0f top of last item, 0.5f vertical center of last item, 1.0f bottom of last item. void ImGui::SetScrollHere(float center_y_ratio) { - ImGuiWindow* window = GetCurrentWindow(); - float target_y = window->DC.CursorPosPrevLine.y - window->Pos.y; // Top of last item, in window space - target_y += (window->DC.PrevLineHeight * center_y_ratio) + (GImGui->Style.ItemSpacing.y * (center_y_ratio - 0.5f) * 2.0f); // Precisely aim above, in the middle or below the last line. - SetScrollFromPosY(target_y, center_y_ratio); + ImGuiWindow* window = GetCurrentWindow(); + float target_y = window->DC.CursorPosPrevLine.y - window->Pos.y; // Top of last item, in window space + target_y += (window->DC.PrevLineHeight * center_y_ratio) + (GImGui->Style.ItemSpacing.y * (center_y_ratio - 0.5f) * 2.0f); // Precisely aim above, in the middle or below the last line. + SetScrollFromPosY(target_y, center_y_ratio); } void ImGui::ActivateItem(ImGuiID id) { - ImGuiContext& g = *GImGui; - g.NavNextActivateId = id; + ImGuiContext& g = *GImGui; + g.NavNextActivateId = id; } void ImGui::SetKeyboardFocusHere(int offset) { - IM_ASSERT(offset >= -1); // -1 is allowed but not below - ImGuiWindow* window = GetCurrentWindow(); - window->FocusIdxAllRequestNext = window->FocusIdxAllCounter + 1 + offset; - window->FocusIdxTabRequestNext = INT_MAX; + IM_ASSERT(offset >= -1); // -1 is allowed but not below + ImGuiWindow* window = GetCurrentWindow(); + window->FocusIdxAllRequestNext = window->FocusIdxAllCounter + 1 + offset; + window->FocusIdxTabRequestNext = INT_MAX; } void ImGui::SetItemDefaultFocus() { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - if (!window->Appearing) - return; - if (g.NavWindow == window->RootWindowForNav && (g.NavInitRequest || g.NavInitResultId != 0) && g.NavLayer == g.NavWindow->DC.NavLayerCurrent) - { - g.NavInitRequest = false; - g.NavInitResultId = g.NavWindow->DC.LastItemId; - g.NavInitResultRectRel = ImRect(g.NavWindow->DC.LastItemRect.Min - g.NavWindow->Pos, g.NavWindow->DC.LastItemRect.Max - g.NavWindow->Pos); - NavUpdateAnyRequestFlag(); - if (!IsItemVisible()) - SetScrollHere(); - } + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (!window->Appearing) + return; + if (g.NavWindow == window->RootWindowForNav && (g.NavInitRequest || g.NavInitResultId != 0) && g.NavLayer == g.NavWindow->DC.NavLayerCurrent) + { + g.NavInitRequest = false; + g.NavInitResultId = g.NavWindow->DC.LastItemId; + g.NavInitResultRectRel = ImRect(g.NavWindow->DC.LastItemRect.Min - g.NavWindow->Pos, g.NavWindow->DC.LastItemRect.Max - g.NavWindow->Pos); + NavUpdateAnyRequestFlag(); + if (!IsItemVisible()) + SetScrollHere(); + } } void ImGui::SetStateStorage(ImGuiStorage* tree) { - ImGuiWindow* window = GetCurrentWindow(); - window->DC.StateStorage = tree ? tree : &window->StateStorage; + ImGuiWindow* window = GetCurrentWindow(); + window->DC.StateStorage = tree ? tree : &window->StateStorage; } ImGuiStorage* ImGui::GetStateStorage() { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.StateStorage; + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.StateStorage; } void ImGui::TextV(const char* fmt, va_list args) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; - ImGuiContext& g = *GImGui; - const char* text_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); - TextUnformatted(g.TempBuffer, text_end); + ImGuiContext& g = *GImGui; + const char* text_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + TextUnformatted(g.TempBuffer, text_end); } void ImGui::Text(const char* fmt, ...) { - va_list args; - va_start(args, fmt); - TextV(fmt, args); - va_end(args); + va_list args; + va_start(args, fmt); + TextV(fmt, args); + va_end(args); } void ImGui::TextColoredV(const ImVec4& col, const char* fmt, va_list args) { - PushStyleColor(ImGuiCol_Text, col); - TextV(fmt, args); - PopStyleColor(); + PushStyleColor(ImGuiCol_Text, col); + TextV(fmt, args); + PopStyleColor(); } void ImGui::TextColored(const ImVec4& col, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - TextColoredV(col, fmt, args); - va_end(args); + va_list args; + va_start(args, fmt); + TextColoredV(col, fmt, args); + va_end(args); } void ImGui::TextDisabledV(const char* fmt, va_list args) { - PushStyleColor(ImGuiCol_Text, GImGui->Style.Colors[ImGuiCol_TextDisabled]); - TextV(fmt, args); - PopStyleColor(); + PushStyleColor(ImGuiCol_Text, GImGui->Style.Colors[ImGuiCol_TextDisabled]); + TextV(fmt, args); + PopStyleColor(); } void ImGui::TextDisabled(const char* fmt, ...) { - va_list args; - va_start(args, fmt); - TextDisabledV(fmt, args); - va_end(args); + va_list args; + va_start(args, fmt); + TextDisabledV(fmt, args); + va_end(args); } void ImGui::TextWrappedV(const char* fmt, va_list args) { - bool need_wrap = (GImGui->CurrentWindow->DC.TextWrapPos < 0.0f); // Keep existing wrap position is one ia already set - if (need_wrap) PushTextWrapPos(0.0f); - TextV(fmt, args); - if (need_wrap) PopTextWrapPos(); + bool need_wrap = (GImGui->CurrentWindow->DC.TextWrapPos < 0.0f); // Keep existing wrap position is one ia already set + if (need_wrap) PushTextWrapPos(0.0f); + TextV(fmt, args); + if (need_wrap) PopTextWrapPos(); } void ImGui::TextWrapped(const char* fmt, ...) { - va_list args; - va_start(args, fmt); - TextWrappedV(fmt, args); - va_end(args); + va_list args; + va_start(args, fmt); + TextWrappedV(fmt, args); + va_end(args); } void ImGui::TextUnformatted(const char* text, const char* text_end) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; - ImGuiContext& g = *GImGui; - IM_ASSERT(text != NULL); - const char* text_begin = text; - if (text_end == NULL) - text_end = text + strlen(text); // FIXME-OPT + ImGuiContext& g = *GImGui; + IM_ASSERT(text != NULL); + const char* text_begin = text; + if (text_end == NULL) + text_end = text + strlen(text); // FIXME-OPT - const ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrentLineTextBaseOffset); - const float wrap_pos_x = window->DC.TextWrapPos; - const bool wrap_enabled = wrap_pos_x >= 0.0f; - if (text_end - text > 2000 && !wrap_enabled) - { - // Long text! - // Perform manual coarse clipping to optimize for long multi-line text - // From this point we will only compute the width of lines that are visible. Optimization only available when word-wrapping is disabled. - // We also don't vertically center the text within the line full height, which is unlikely to matter because we are likely the biggest and only item on the line. - const char* line = text; - const float line_height = GetTextLineHeight(); - const ImRect clip_rect = window->ClipRect; - ImVec2 text_size(0,0); + const ImVec2 text_pos(window->DC.CursorPos.x, window->DC.CursorPos.y + window->DC.CurrentLineTextBaseOffset); + const float wrap_pos_x = window->DC.TextWrapPos; + const bool wrap_enabled = wrap_pos_x >= 0.0f; + if (text_end - text > 2000 && !wrap_enabled) + { + // Long text! + // Perform manual coarse clipping to optimize for long multi-line text + // From this point we will only compute the width of lines that are visible. Optimization only available when word-wrapping is disabled. + // We also don't vertically center the text within the line full height, which is unlikely to matter because we are likely the biggest and only item on the line. + const char* line = text; + const float line_height = GetTextLineHeight(); + const ImRect clip_rect = window->ClipRect; + ImVec2 text_size(0, 0); - if (text_pos.y <= clip_rect.Max.y) - { - ImVec2 pos = text_pos; + if (text_pos.y <= clip_rect.Max.y) + { + ImVec2 pos = text_pos; - // Lines to skip (can't skip when logging text) - if (!g.LogEnabled) - { - int lines_skippable = (int)((clip_rect.Min.y - text_pos.y) / line_height); - if (lines_skippable > 0) - { - int lines_skipped = 0; - while (line < text_end && lines_skipped < lines_skippable) - { - const char* line_end = strchr(line, '\n'); - if (!line_end) - line_end = text_end; - line = line_end + 1; - lines_skipped++; - } - pos.y += lines_skipped * line_height; - } - } + // Lines to skip (can't skip when logging text) + if (!g.LogEnabled) + { + int lines_skippable = (int)((clip_rect.Min.y - text_pos.y) / line_height); + if (lines_skippable > 0) + { + int lines_skipped = 0; + while (line < text_end && lines_skipped < lines_skippable) + { + const char* line_end = strchr(line, '\n'); + if (!line_end) + line_end = text_end; + line = line_end + 1; + lines_skipped++; + } + pos.y += lines_skipped * line_height; + } + } - // Lines to render - if (line < text_end) - { - ImRect line_rect(pos, pos + ImVec2(FLT_MAX, line_height)); - while (line < text_end) - { - const char* line_end = strchr(line, '\n'); - if (IsClippedEx(line_rect, 0, false)) - break; + // Lines to render + if (line < text_end) + { + ImRect line_rect(pos, pos + ImVec2(FLT_MAX, line_height)); + while (line < text_end) + { + const char* line_end = strchr(line, '\n'); + if (IsClippedEx(line_rect, 0, false)) + break; - const ImVec2 line_size = CalcTextSize(line, line_end, false); - text_size.x = ImMax(text_size.x, line_size.x); - RenderText(pos, line, line_end, false); - if (!line_end) - line_end = text_end; - line = line_end + 1; - line_rect.Min.y += line_height; - line_rect.Max.y += line_height; - pos.y += line_height; - } + const ImVec2 line_size = CalcTextSize(line, line_end, false); + text_size.x = ImMax(text_size.x, line_size.x); + RenderText(pos, line, line_end, false); + if (!line_end) + line_end = text_end; + line = line_end + 1; + line_rect.Min.y += line_height; + line_rect.Max.y += line_height; + pos.y += line_height; + } - // Count remaining lines - int lines_skipped = 0; - while (line < text_end) - { - const char* line_end = strchr(line, '\n'); - if (!line_end) - line_end = text_end; - line = line_end + 1; - lines_skipped++; - } - pos.y += lines_skipped * line_height; - } + // Count remaining lines + int lines_skipped = 0; + while (line < text_end) + { + const char* line_end = strchr(line, '\n'); + if (!line_end) + line_end = text_end; + line = line_end + 1; + lines_skipped++; + } + pos.y += lines_skipped * line_height; + } - text_size.y += (pos - text_pos).y; - } + text_size.y += (pos - text_pos).y; + } - ImRect bb(text_pos, text_pos + text_size); - ItemSize(bb); - ItemAdd(bb, 0); - } - else - { - const float wrap_width = wrap_enabled ? CalcWrapWidthForPos(window->DC.CursorPos, wrap_pos_x) : 0.0f; - const ImVec2 text_size = CalcTextSize(text_begin, text_end, false, wrap_width); + ImRect bb(text_pos, text_pos + text_size); + ItemSize(bb); + ItemAdd(bb, 0); + } + else + { + const float wrap_width = wrap_enabled ? CalcWrapWidthForPos(window->DC.CursorPos, wrap_pos_x) : 0.0f; + const ImVec2 text_size = CalcTextSize(text_begin, text_end, false, wrap_width); - // Account of baseline offset - ImRect bb(text_pos, text_pos + text_size); - ItemSize(text_size); - if (!ItemAdd(bb, 0)) - return; + // Account of baseline offset + ImRect bb(text_pos, text_pos + text_size); + ItemSize(text_size); + if (!ItemAdd(bb, 0)) + return; - // Render (we don't hide text after ## in this end-user function) - RenderTextWrapped(bb.Min, text_begin, text_end, wrap_width); - } + // Render (we don't hide text after ## in this end-user function) + RenderTextWrapped(bb.Min, text_begin, text_end, wrap_width); + } } void ImGui::AlignTextToFramePadding() { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; - ImGuiContext& g = *GImGui; - window->DC.CurrentLineHeight = ImMax(window->DC.CurrentLineHeight, g.FontSize + g.Style.FramePadding.y * 2); - window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, g.Style.FramePadding.y); + ImGuiContext& g = *GImGui; + window->DC.CurrentLineHeight = ImMax(window->DC.CurrentLineHeight, g.FontSize + g.Style.FramePadding.y * 2); + window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.CurrentLineTextBaseOffset, g.Style.FramePadding.y); } // Add a label+text combo aligned to other label+value widgets void ImGui::LabelTextV(const char* label, const char* fmt, va_list args) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; - const float w = CalcItemWidth(); + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const float w = CalcItemWidth(); - const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImRect value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2)); - const ImRect total_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + (label_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), style.FramePadding.y*2) + label_size); - ItemSize(total_bb, style.FramePadding.y); - if (!ItemAdd(total_bb, 0)) - return; + const ImVec2 label_size = CalcTextSize(label, NULL, true); + const ImRect value_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2)); + const ImRect total_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w + (label_size.x > 0.0f ? style.ItemInnerSpacing.x : 0.0f), style.FramePadding.y * 2) + label_size); + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, 0)) + return; - // Render - const char* value_text_begin = &g.TempBuffer[0]; - const char* value_text_end = value_text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); - RenderTextClipped(value_bb.Min, value_bb.Max, value_text_begin, value_text_end, NULL, ImVec2(0.0f,0.5f)); - if (label_size.x > 0.0f) - RenderText(ImVec2(value_bb.Max.x + style.ItemInnerSpacing.x, value_bb.Min.y + style.FramePadding.y), label); + // Render + const char* value_text_begin = &g.TempBuffer[0]; + const char* value_text_end = value_text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + RenderTextClipped(value_bb.Min, value_bb.Max, value_text_begin, value_text_end, NULL, ImVec2(0.0f, 0.5f)); + if (label_size.x > 0.0f) + RenderText(ImVec2(value_bb.Max.x + style.ItemInnerSpacing.x, value_bb.Min.y + style.FramePadding.y), label); } void ImGui::LabelText(const char* label, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - LabelTextV(label, fmt, args); - va_end(args); + va_list args; + va_start(args, fmt); + LabelTextV(label, fmt, args); + va_end(args); } bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); - if (flags & ImGuiButtonFlags_Disabled) - { - if (out_hovered) *out_hovered = false; - if (out_held) *out_held = false; - if (g.ActiveId == id) ClearActiveID(); - return false; - } + if (flags & ImGuiButtonFlags_Disabled) + { + if (out_hovered) *out_hovered = false; + if (out_held) *out_held = false; + if (g.ActiveId == id) ClearActiveID(); + return false; + } - // Default behavior requires click+release on same spot - if ((flags & (ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick)) == 0) - flags |= ImGuiButtonFlags_PressedOnClickRelease; + // Default behavior requires click+release on same spot + if ((flags & (ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_PressedOnRelease | ImGuiButtonFlags_PressedOnDoubleClick)) == 0) + flags |= ImGuiButtonFlags_PressedOnClickRelease; - ImGuiWindow* backup_hovered_window = g.HoveredWindow; - if ((flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredRootWindow == window) - g.HoveredWindow = window; + ImGuiWindow* backup_hovered_window = g.HoveredWindow; + if ((flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredRootWindow == window) + g.HoveredWindow = window; - bool pressed = false; - bool hovered = ItemHoverable(bb, id); + bool pressed = false; + bool hovered = ItemHoverable(bb, id); - // Special mode for Drag and Drop where holding button pressed for a long time while dragging another item triggers the button - if ((flags & ImGuiButtonFlags_PressedOnDragDropHold) && g.DragDropActive && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoHoldToOpenOthers)) - if (IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) - { - hovered = true; - SetHoveredID(id); - if (CalcTypematicPressedRepeatAmount(g.HoveredIdTimer + 0.0001f, g.HoveredIdTimer + 0.0001f - g.IO.DeltaTime, 0.01f, 0.70f)) // FIXME: Our formula for CalcTypematicPressedRepeatAmount() is fishy - { - pressed = true; - FocusWindow(window); - } - } + // Special mode for Drag and Drop where holding button pressed for a long time while dragging another item triggers the button + if ((flags & ImGuiButtonFlags_PressedOnDragDropHold) && g.DragDropActive && !(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoHoldToOpenOthers)) + if (IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem)) + { + hovered = true; + SetHoveredID(id); + if (CalcTypematicPressedRepeatAmount(g.HoveredIdTimer + 0.0001f, g.HoveredIdTimer + 0.0001f - g.IO.DeltaTime, 0.01f, 0.70f)) // FIXME: Our formula for CalcTypematicPressedRepeatAmount() is fishy + { + pressed = true; + FocusWindow(window); + } + } - if ((flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredRootWindow == window) - g.HoveredWindow = backup_hovered_window; + if ((flags & ImGuiButtonFlags_FlattenChildren) && g.HoveredRootWindow == window) + g.HoveredWindow = backup_hovered_window; - // AllowOverlap mode (rarely used) requires previous frame HoveredId to be null or to match. This allows using patterns where a later submitted widget overlaps a previous one. - if (hovered && (flags & ImGuiButtonFlags_AllowItemOverlap) && (g.HoveredIdPreviousFrame != id && g.HoveredIdPreviousFrame != 0)) - hovered = false; + // AllowOverlap mode (rarely used) requires previous frame HoveredId to be null or to match. This allows using patterns where a later submitted widget overlaps a previous one. + if (hovered && (flags & ImGuiButtonFlags_AllowItemOverlap) && (g.HoveredIdPreviousFrame != id && g.HoveredIdPreviousFrame != 0)) + hovered = false; - // Mouse - if (hovered) - { - if (!(flags & ImGuiButtonFlags_NoKeyModifiers) || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt)) - { - // | CLICKING | HOLDING with ImGuiButtonFlags_Repeat - // PressedOnClickRelease | * | .. (NOT on release) <-- MOST COMMON! (*) only if both click/release were over bounds - // PressedOnClick | | .. - // PressedOnRelease | | .. (NOT on release) - // PressedOnDoubleClick | | .. - // FIXME-NAV: We don't honor those different behaviors. - if ((flags & ImGuiButtonFlags_PressedOnClickRelease) && g.IO.MouseClicked[0]) - { - SetActiveID(id, window); - if (!(flags & ImGuiButtonFlags_NoNavFocus)) - SetFocusID(id, window); - FocusWindow(window); - } - if (((flags & ImGuiButtonFlags_PressedOnClick) && g.IO.MouseClicked[0]) || ((flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseDoubleClicked[0])) - { - pressed = true; - if (flags & ImGuiButtonFlags_NoHoldingActiveID) - ClearActiveID(); - else - SetActiveID(id, window); // Hold on ID - FocusWindow(window); - } - if ((flags & ImGuiButtonFlags_PressedOnRelease) && g.IO.MouseReleased[0]) - { - if (!((flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[0] >= g.IO.KeyRepeatDelay)) // Repeat mode trumps - pressed = true; - ClearActiveID(); - } + // Mouse + if (hovered) + { + if (!(flags & ImGuiButtonFlags_NoKeyModifiers) || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt)) + { + // | CLICKING | HOLDING with ImGuiButtonFlags_Repeat + // PressedOnClickRelease | * | .. (NOT on release) <-- MOST COMMON! (*) only if both click/release were over bounds + // PressedOnClick | | .. + // PressedOnRelease | | .. (NOT on release) + // PressedOnDoubleClick | | .. + // FIXME-NAV: We don't honor those different behaviors. + if ((flags & ImGuiButtonFlags_PressedOnClickRelease) && g.IO.MouseClicked[0]) + { + SetActiveID(id, window); + if (!(flags & ImGuiButtonFlags_NoNavFocus)) + SetFocusID(id, window); + FocusWindow(window); + } + if (((flags & ImGuiButtonFlags_PressedOnClick) && g.IO.MouseClicked[0]) || ((flags & ImGuiButtonFlags_PressedOnDoubleClick) && g.IO.MouseDoubleClicked[0])) + { + pressed = true; + if (flags & ImGuiButtonFlags_NoHoldingActiveID) + ClearActiveID(); + else + SetActiveID(id, window); // Hold on ID + FocusWindow(window); + } + if ((flags & ImGuiButtonFlags_PressedOnRelease) && g.IO.MouseReleased[0]) + { + if (!((flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[0] >= g.IO.KeyRepeatDelay)) // Repeat mode trumps + pressed = true; + ClearActiveID(); + } - // 'Repeat' mode acts when held regardless of _PressedOn flags (see table above). - // Relies on repeat logic of IsMouseClicked() but we may as well do it ourselves if we end up exposing finer RepeatDelay/RepeatRate settings. - if ((flags & ImGuiButtonFlags_Repeat) && g.ActiveId == id && g.IO.MouseDownDuration[0] > 0.0f && IsMouseClicked(0, true)) - pressed = true; - } + // 'Repeat' mode acts when held regardless of _PressedOn flags (see table above). + // Relies on repeat logic of IsMouseClicked() but we may as well do it ourselves if we end up exposing finer RepeatDelay/RepeatRate settings. + if ((flags & ImGuiButtonFlags_Repeat) && g.ActiveId == id && g.IO.MouseDownDuration[0] > 0.0f && IsMouseClicked(0, true)) + pressed = true; + } - if (pressed) - g.NavDisableHighlight = true; - } + if (pressed) + g.NavDisableHighlight = true; + } - // Gamepad/Keyboard navigation - // We report navigated item as hovered but we don't set g.HoveredId to not interfere with mouse. - if (g.NavId == id && !g.NavDisableHighlight && g.NavDisableMouseHover && (g.ActiveId == 0 || g.ActiveId == id || g.ActiveId == window->MoveId)) - hovered = true; + // Gamepad/Keyboard navigation + // We report navigated item as hovered but we don't set g.HoveredId to not interfere with mouse. + if (g.NavId == id && !g.NavDisableHighlight && g.NavDisableMouseHover && (g.ActiveId == 0 || g.ActiveId == id || g.ActiveId == window->MoveId)) + hovered = true; - if (g.NavActivateDownId == id) - { - bool nav_activated_by_code = (g.NavActivateId == id); - bool nav_activated_by_inputs = IsNavInputPressed(ImGuiNavInput_Activate, (flags & ImGuiButtonFlags_Repeat) ? ImGuiInputReadMode_Repeat : ImGuiInputReadMode_Pressed); - if (nav_activated_by_code || nav_activated_by_inputs) - pressed = true; - if (nav_activated_by_code || nav_activated_by_inputs || g.ActiveId == id) - { - // Set active id so it can be queried by user via IsItemActive(), equivalent of holding the mouse button. - g.NavActivateId = id; // This is so SetActiveId assign a Nav source - SetActiveID(id, window); - if (!(flags & ImGuiButtonFlags_NoNavFocus)) - SetFocusID(id, window); - g.ActiveIdAllowNavDirFlags = (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right) | (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down); - } - } + if (g.NavActivateDownId == id) + { + bool nav_activated_by_code = (g.NavActivateId == id); + bool nav_activated_by_inputs = IsNavInputPressed(ImGuiNavInput_Activate, (flags & ImGuiButtonFlags_Repeat) ? ImGuiInputReadMode_Repeat : ImGuiInputReadMode_Pressed); + if (nav_activated_by_code || nav_activated_by_inputs) + pressed = true; + if (nav_activated_by_code || nav_activated_by_inputs || g.ActiveId == id) + { + // Set active id so it can be queried by user via IsItemActive(), equivalent of holding the mouse button. + g.NavActivateId = id; // This is so SetActiveId assign a Nav source + SetActiveID(id, window); + if (!(flags & ImGuiButtonFlags_NoNavFocus)) + SetFocusID(id, window); + g.ActiveIdAllowNavDirFlags = (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right) | (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down); + } + } - bool held = false; - if (g.ActiveId == id) - { - if (g.ActiveIdSource == ImGuiInputSource_Mouse) - { - if (g.ActiveIdIsJustActivated) - g.ActiveIdClickOffset = g.IO.MousePos - bb.Min; - if (g.IO.MouseDown[0]) - { - held = true; - } - else - { - if (hovered && (flags & ImGuiButtonFlags_PressedOnClickRelease)) - if (!((flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[0] >= g.IO.KeyRepeatDelay)) // Repeat mode trumps - if (!g.DragDropActive) - pressed = true; - ClearActiveID(); - } - if (!(flags & ImGuiButtonFlags_NoNavFocus)) - g.NavDisableHighlight = true; - } - else if (g.ActiveIdSource == ImGuiInputSource_Nav) - { - if (g.NavActivateDownId != id) - ClearActiveID(); - } - } + bool held = false; + if (g.ActiveId == id) + { + if (g.ActiveIdSource == ImGuiInputSource_Mouse) + { + if (g.ActiveIdIsJustActivated) + g.ActiveIdClickOffset = g.IO.MousePos - bb.Min; + if (g.IO.MouseDown[0]) + { + held = true; + } + else + { + if (hovered && (flags & ImGuiButtonFlags_PressedOnClickRelease)) + if (!((flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[0] >= g.IO.KeyRepeatDelay)) // Repeat mode trumps + if (!g.DragDropActive) + pressed = true; + ClearActiveID(); + } + if (!(flags & ImGuiButtonFlags_NoNavFocus)) + g.NavDisableHighlight = true; + } + else if (g.ActiveIdSource == ImGuiInputSource_Nav) + { + if (g.NavActivateDownId != id) + ClearActiveID(); + } + } - if (out_hovered) *out_hovered = hovered; - if (out_held) *out_held = held; + if (out_hovered) *out_hovered = hovered; + if (out_held) *out_held = held; - return pressed; + return pressed; } bool ImGui::ButtonEx(const char* label, const ImVec2& size_arg, ImGuiButtonFlags flags) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); - const ImVec2 label_size = CalcTextSize(label, NULL, true); + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const ImVec2 label_size = CalcTextSize(label, NULL, true); - ImVec2 pos = window->DC.CursorPos; - if ((flags & ImGuiButtonFlags_AlignTextBaseLine) && style.FramePadding.y < window->DC.CurrentLineTextBaseOffset) // Try to vertically align buttons that are smaller/have no padding so that text baseline matches (bit hacky, since it shouldn't be a flag) - pos.y += window->DC.CurrentLineTextBaseOffset - style.FramePadding.y; - ImVec2 size = CalcItemSize(size_arg, label_size.x + style.FramePadding.x * 2.0f, label_size.y + style.FramePadding.y * 2.0f); + ImVec2 pos = window->DC.CursorPos; + if ((flags & ImGuiButtonFlags_AlignTextBaseLine) && style.FramePadding.y < window->DC.CurrentLineTextBaseOffset) // Try to vertically align buttons that are smaller/have no padding so that text baseline matches (bit hacky, since it shouldn't be a flag) + pos.y += window->DC.CurrentLineTextBaseOffset - style.FramePadding.y; + ImVec2 size = CalcItemSize(size_arg, label_size.x + style.FramePadding.x * 2.0f, label_size.y + style.FramePadding.y * 2.0f); - const ImRect bb(pos, pos + size); - ItemSize(bb, style.FramePadding.y); - if (!ItemAdd(bb, id)) - return false; + const ImRect bb(pos, pos + size); + ItemSize(bb, style.FramePadding.y); + if (!ItemAdd(bb, id)) + return false; - if (window->DC.ItemFlags & ImGuiItemFlags_ButtonRepeat) - flags |= ImGuiButtonFlags_Repeat; - bool hovered, held; - bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); + if (window->DC.ItemFlags & ImGuiItemFlags_ButtonRepeat) + flags |= ImGuiButtonFlags_Repeat; + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); - // Render - const ImU32 col = GetColorU32((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); - RenderNavHighlight(bb, id); - RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); - RenderTextClipped(bb.Min + style.FramePadding, bb.Max - style.FramePadding, label, NULL, &label_size, style.ButtonTextAlign, &bb); + // Render + const ImU32 col = GetColorU32((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); + RenderNavHighlight(bb, id); + RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); + RenderTextClipped(bb.Min + style.FramePadding, bb.Max - style.FramePadding, label, NULL, &label_size, style.ButtonTextAlign, &bb); - // Automatically close popups - //if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup)) - // CloseCurrentPopup(); + // Automatically close popups + //if (pressed && !(flags & ImGuiButtonFlags_DontClosePopups) && (window->Flags & ImGuiWindowFlags_Popup)) + // CloseCurrentPopup(); - return pressed; + return pressed; } bool ImGui::Button(const char* label, const ImVec2& size_arg) { - return ButtonEx(label, size_arg, 0); + return ButtonEx(label, size_arg, 0); } // Small buttons fits within text without additional vertical spacing. bool ImGui::SmallButton(const char* label) { - ImGuiContext& g = *GImGui; - float backup_padding_y = g.Style.FramePadding.y; - g.Style.FramePadding.y = 0.0f; - bool pressed = ButtonEx(label, ImVec2(0,0), ImGuiButtonFlags_AlignTextBaseLine); - g.Style.FramePadding.y = backup_padding_y; - return pressed; + ImGuiContext& g = *GImGui; + float backup_padding_y = g.Style.FramePadding.y; + g.Style.FramePadding.y = 0.0f; + bool pressed = ButtonEx(label, ImVec2(0, 0), ImGuiButtonFlags_AlignTextBaseLine); + g.Style.FramePadding.y = backup_padding_y; + return pressed; } // Tip: use ImGui::PushID()/PopID() to push indices or pointers in the ID stack. // Then you can keep 'str_id' empty or the same for all your buttons (instead of creating a string based on a non-string id) bool ImGui::InvisibleButton(const char* str_id, const ImVec2& size_arg) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - const ImGuiID id = window->GetID(str_id); - ImVec2 size = CalcItemSize(size_arg, 0.0f, 0.0f); - const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); - ItemSize(bb); - if (!ItemAdd(bb, id)) - return false; + const ImGuiID id = window->GetID(str_id); + ImVec2 size = CalcItemSize(size_arg, 0.0f, 0.0f); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); + ItemSize(bb); + if (!ItemAdd(bb, id)) + return false; - bool hovered, held; - bool pressed = ButtonBehavior(bb, id, &hovered, &held); + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held); - return pressed; + return pressed; } // Button to close a window bool ImGui::CloseButton(ImGuiID id, const ImVec2& pos, float radius) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; - // We intentionally allow interaction when clipped so that a mechanical Alt,Right,Validate sequence close a window. - // (this isn't the regular behavior of buttons, but it doesn't affect the user much because navigation tends to keep items visible). - const ImRect bb(pos - ImVec2(radius,radius), pos + ImVec2(radius,radius)); - bool is_clipped = !ItemAdd(bb, id); + // We intentionally allow interaction when clipped so that a mechanical Alt,Right,Validate sequence close a window. + // (this isn't the regular behavior of buttons, but it doesn't affect the user much because navigation tends to keep items visible). + const ImRect bb(pos - ImVec2(radius, radius), pos + ImVec2(radius, radius)); + bool is_clipped = !ItemAdd(bb, id); - bool hovered, held; - bool pressed = ButtonBehavior(bb, id, &hovered, &held); - if (is_clipped) - return pressed; + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held); + if (is_clipped) + return pressed; - // Render - const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_CloseButtonActive : hovered ? ImGuiCol_CloseButtonHovered : ImGuiCol_CloseButton); - ImVec2 center = bb.GetCenter(); - window->DrawList->AddCircleFilled(center, ImMax(2.0f, radius), col, 12); + // Render + const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_CloseButtonActive : hovered ? ImGuiCol_CloseButtonHovered : ImGuiCol_CloseButton); + ImVec2 center = bb.GetCenter(); + window->DrawList->AddCircleFilled(center, ImMax(2.0f, radius), col, 12); - const float cross_extent = (radius * 0.7071f) - 1.0f; - if (hovered) - { - center -= ImVec2(0.5f, 0.5f); - window->DrawList->AddLine(center + ImVec2(+cross_extent,+cross_extent), center + ImVec2(-cross_extent,-cross_extent), GetColorU32(ImGuiCol_Text)); - window->DrawList->AddLine(center + ImVec2(+cross_extent,-cross_extent), center + ImVec2(-cross_extent,+cross_extent), GetColorU32(ImGuiCol_Text)); - } - return pressed; + const float cross_extent = (radius * 0.7071f) - 1.0f; + if (hovered) + { + center -= ImVec2(0.5f, 0.5f); + window->DrawList->AddLine(center + ImVec2(+cross_extent, +cross_extent), center + ImVec2(-cross_extent, -cross_extent), GetColorU32(ImGuiCol_Text)); + window->DrawList->AddLine(center + ImVec2(+cross_extent, -cross_extent), center + ImVec2(-cross_extent, +cross_extent), GetColorU32(ImGuiCol_Text)); + } + return pressed; } // [Internal] bool ImGui::ArrowButton(ImGuiID id, ImGuiDir dir, ImVec2 padding, ImGuiButtonFlags flags) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - if (window->SkipItems) - return false; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (window->SkipItems) + return false; - const ImGuiStyle& style = g.Style; + const ImGuiStyle& style = g.Style; - const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize + padding.x * 2.0f, g.FontSize + padding.y * 2.0f)); - ItemSize(bb, style.FramePadding.y); - if (!ItemAdd(bb, id)) - return false; + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize + padding.x * 2.0f, g.FontSize + padding.y * 2.0f)); + ItemSize(bb, style.FramePadding.y); + if (!ItemAdd(bb, id)) + return false; - bool hovered, held; - bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held, flags); - const ImU32 col = GetColorU32((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); - RenderNavHighlight(bb, id); - RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); - RenderTriangle(bb.Min + padding, dir, 1.0f); + const ImU32 col = GetColorU32((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); + RenderNavHighlight(bb, id); + RenderFrame(bb.Min, bb.Max, col, true, style.FrameRounding); + RenderTriangle(bb.Min + padding, dir, 1.0f); - return pressed; + return pressed; } void ImGui::Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, const ImVec4& tint_col, const ImVec4& border_col) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; - ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); - if (border_col.w > 0.0f) - bb.Max += ImVec2(2,2); - ItemSize(bb); - if (!ItemAdd(bb, 0)) - return; + ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); + if (border_col.w > 0.0f) + bb.Max += ImVec2(2, 2); + ItemSize(bb); + if (!ItemAdd(bb, 0)) + return; - if (border_col.w > 0.0f) - { - window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(border_col), 0.0f); - window->DrawList->AddImage(user_texture_id, bb.Min+ImVec2(1,1), bb.Max-ImVec2(1,1), uv0, uv1, GetColorU32(tint_col)); - } - else - { - window->DrawList->AddImage(user_texture_id, bb.Min, bb.Max, uv0, uv1, GetColorU32(tint_col)); - } + if (border_col.w > 0.0f) + { + window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(border_col), 0.0f); + window->DrawList->AddImage(user_texture_id, bb.Min + ImVec2(1, 1), bb.Max - ImVec2(1, 1), uv0, uv1, GetColorU32(tint_col)); + } + else + { + window->DrawList->AddImage(user_texture_id, bb.Min, bb.Max, uv0, uv1, GetColorU32(tint_col)); + } } // frame_padding < 0: uses FramePadding from style (default) @@ -7793,939 +7983,970 @@ void ImGui::Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& // The color used are the button colors. bool ImGui::ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0, const ImVec2& uv1, int frame_padding, const ImVec4& bg_col, const ImVec4& tint_col) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; - // Default to using texture ID as ID. User can still push string/integer prefixes. - // We could hash the size/uv to create a unique ID but that would prevent the user from animating UV. - PushID((void *)user_texture_id); - const ImGuiID id = window->GetID("#image"); - PopID(); + // Default to using texture ID as ID. User can still push string/integer prefixes. + // We could hash the size/uv to create a unique ID but that would prevent the user from animating UV. + PushID((void*)user_texture_id); + const ImGuiID id = window->GetID("#image"); + PopID(); - const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float)frame_padding, (float)frame_padding) : style.FramePadding; - const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size + padding*2); - const ImRect image_bb(window->DC.CursorPos + padding, window->DC.CursorPos + padding + size); - ItemSize(bb); - if (!ItemAdd(bb, id)) - return false; + const ImVec2 padding = (frame_padding >= 0) ? ImVec2((float)frame_padding, (float)frame_padding) : style.FramePadding; + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size + padding * 2); + const ImRect image_bb(window->DC.CursorPos + padding, window->DC.CursorPos + padding + size); + ItemSize(bb); + if (!ItemAdd(bb, id)) + return false; - bool hovered, held; - bool pressed = ButtonBehavior(bb, id, &hovered, &held); + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held); - // Render - const ImU32 col = GetColorU32((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); - RenderNavHighlight(bb, id); - RenderFrame(bb.Min, bb.Max, col, true, ImClamp((float)ImMin(padding.x, padding.y), 0.0f, style.FrameRounding)); - if (bg_col.w > 0.0f) - window->DrawList->AddRectFilled(image_bb.Min, image_bb.Max, GetColorU32(bg_col)); - window->DrawList->AddImage(user_texture_id, image_bb.Min, image_bb.Max, uv0, uv1, GetColorU32(tint_col)); + // Render + const ImU32 col = GetColorU32((hovered && held) ? ImGuiCol_ButtonActive : hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button); + RenderNavHighlight(bb, id); + RenderFrame(bb.Min, bb.Max, col, true, ImClamp((float)ImMin(padding.x, padding.y), 0.0f, style.FrameRounding)); + if (bg_col.w > 0.0f) + window->DrawList->AddRectFilled(image_bb.Min, image_bb.Max, GetColorU32(bg_col)); + window->DrawList->AddImage(user_texture_id, image_bb.Min, image_bb.Max, uv0, uv1, GetColorU32(tint_col)); - return pressed; + return pressed; } // Start logging ImGui output to TTY void ImGui::LogToTTY(int max_depth) { - ImGuiContext& g = *GImGui; - if (g.LogEnabled) - return; - ImGuiWindow* window = g.CurrentWindow; + ImGuiContext& g = *GImGui; + if (g.LogEnabled) + return; + ImGuiWindow* window = g.CurrentWindow; - IM_ASSERT(g.LogFile == NULL); - g.LogFile = stdout; - g.LogEnabled = true; - g.LogStartDepth = window->DC.TreeDepth; - if (max_depth >= 0) - g.LogAutoExpandMaxDepth = max_depth; + IM_ASSERT(g.LogFile == NULL); + g.LogFile = stdout; + g.LogEnabled = true; + g.LogStartDepth = window->DC.TreeDepth; + if (max_depth >= 0) + g.LogAutoExpandMaxDepth = max_depth; } // Start logging ImGui output to given file void ImGui::LogToFile(int max_depth, const char* filename) { - ImGuiContext& g = *GImGui; - if (g.LogEnabled) - return; - ImGuiWindow* window = g.CurrentWindow; + ImGuiContext& g = *GImGui; + if (g.LogEnabled) + return; + ImGuiWindow* window = g.CurrentWindow; - if (!filename) - { - filename = g.IO.LogFilename; - if (!filename) - return; - } + if (!filename) + { + filename = g.IO.LogFilename; + if (!filename) + return; + } - IM_ASSERT(g.LogFile == NULL); - g.LogFile = ImFileOpen(filename, "ab"); - if (!g.LogFile) - { - IM_ASSERT(g.LogFile != NULL); // Consider this an error - return; - } - g.LogEnabled = true; - g.LogStartDepth = window->DC.TreeDepth; - if (max_depth >= 0) - g.LogAutoExpandMaxDepth = max_depth; + IM_ASSERT(g.LogFile == NULL); + g.LogFile = ImFileOpen(filename, "ab"); + if (!g.LogFile) + { + IM_ASSERT(g.LogFile != NULL); // Consider this an error + return; + } + g.LogEnabled = true; + g.LogStartDepth = window->DC.TreeDepth; + if (max_depth >= 0) + g.LogAutoExpandMaxDepth = max_depth; } // Start logging ImGui output to clipboard void ImGui::LogToClipboard(int max_depth) { - ImGuiContext& g = *GImGui; - if (g.LogEnabled) - return; - ImGuiWindow* window = g.CurrentWindow; + ImGuiContext& g = *GImGui; + if (g.LogEnabled) + return; + ImGuiWindow* window = g.CurrentWindow; - IM_ASSERT(g.LogFile == NULL); - g.LogFile = NULL; - g.LogEnabled = true; - g.LogStartDepth = window->DC.TreeDepth; - if (max_depth >= 0) - g.LogAutoExpandMaxDepth = max_depth; + IM_ASSERT(g.LogFile == NULL); + g.LogFile = NULL; + g.LogEnabled = true; + g.LogStartDepth = window->DC.TreeDepth; + if (max_depth >= 0) + g.LogAutoExpandMaxDepth = max_depth; } void ImGui::LogFinish() { - ImGuiContext& g = *GImGui; - if (!g.LogEnabled) - return; + ImGuiContext& g = *GImGui; + if (!g.LogEnabled) + return; - LogText(IM_NEWLINE); - if (g.LogFile != NULL) - { - if (g.LogFile == stdout) - fflush(g.LogFile); - else - fclose(g.LogFile); - g.LogFile = NULL; - } - if (g.LogClipboard->size() > 1) - { - SetClipboardText(g.LogClipboard->begin()); - g.LogClipboard->clear(); - } - g.LogEnabled = false; + LogText(IM_NEWLINE); + if (g.LogFile != NULL) + { + if (g.LogFile == stdout) + fflush(g.LogFile); + else + fclose(g.LogFile); + g.LogFile = NULL; + } + if (g.LogClipboard->size() > 1) + { + SetClipboardText(g.LogClipboard->begin()); + g.LogClipboard->clear(); + } + g.LogEnabled = false; } // Helper to display logging buttons void ImGui::LogButtons() { - ImGuiContext& g = *GImGui; + ImGuiContext& g = *GImGui; - PushID("LogButtons"); - const bool log_to_tty = Button("Log To TTY"); SameLine(); - const bool log_to_file = Button("Log To File"); SameLine(); - const bool log_to_clipboard = Button("Log To Clipboard"); SameLine(); - PushItemWidth(80.0f); - PushAllowKeyboardFocus(false); - SliderInt("Depth", &g.LogAutoExpandMaxDepth, 0, 9, NULL); - PopAllowKeyboardFocus(); - PopItemWidth(); - PopID(); + PushID("LogButtons"); + const bool log_to_tty = Button("Log To TTY"); + SameLine(); + const bool log_to_file = Button("Log To File"); + SameLine(); + const bool log_to_clipboard = Button("Log To Clipboard"); + SameLine(); + PushItemWidth(80.0f); + PushAllowKeyboardFocus(false); + SliderInt("Depth", &g.LogAutoExpandMaxDepth, 0, 9, NULL); + PopAllowKeyboardFocus(); + PopItemWidth(); + PopID(); - // Start logging at the end of the function so that the buttons don't appear in the log - if (log_to_tty) - LogToTTY(g.LogAutoExpandMaxDepth); - if (log_to_file) - LogToFile(g.LogAutoExpandMaxDepth, g.IO.LogFilename); - if (log_to_clipboard) - LogToClipboard(g.LogAutoExpandMaxDepth); + // Start logging at the end of the function so that the buttons don't appear in the log + if (log_to_tty) + LogToTTY(g.LogAutoExpandMaxDepth); + if (log_to_file) + LogToFile(g.LogAutoExpandMaxDepth, g.IO.LogFilename); + if (log_to_clipboard) + LogToClipboard(g.LogAutoExpandMaxDepth); } bool ImGui::TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags) { - if (flags & ImGuiTreeNodeFlags_Leaf) - return true; + if (flags & ImGuiTreeNodeFlags_Leaf) + return true; - // We only write to the tree storage if the user clicks (or explicitely use SetNextTreeNode*** functions) - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - ImGuiStorage* storage = window->DC.StateStorage; + // We only write to the tree storage if the user clicks (or explicitely use SetNextTreeNode*** functions) + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiStorage* storage = window->DC.StateStorage; - bool is_open; - if (g.NextTreeNodeOpenCond != 0) - { - if (g.NextTreeNodeOpenCond & ImGuiCond_Always) - { - is_open = g.NextTreeNodeOpenVal; - storage->SetInt(id, is_open); - } - else - { - // We treat ImGuiCond_Once and ImGuiCond_FirstUseEver the same because tree node state are not saved persistently. - const int stored_value = storage->GetInt(id, -1); - if (stored_value == -1) - { - is_open = g.NextTreeNodeOpenVal; - storage->SetInt(id, is_open); - } - else - { - is_open = stored_value != 0; - } - } - g.NextTreeNodeOpenCond = 0; - } - else - { - is_open = storage->GetInt(id, (flags & ImGuiTreeNodeFlags_DefaultOpen) ? 1 : 0) != 0; - } + bool is_open; + if (g.NextTreeNodeOpenCond != 0) + { + if (g.NextTreeNodeOpenCond & ImGuiCond_Always) + { + is_open = g.NextTreeNodeOpenVal; + storage->SetInt(id, is_open); + } + else + { + // We treat ImGuiCond_Once and ImGuiCond_FirstUseEver the same because tree node state are not saved persistently. + const int stored_value = storage->GetInt(id, -1); + if (stored_value == -1) + { + is_open = g.NextTreeNodeOpenVal; + storage->SetInt(id, is_open); + } + else + { + is_open = stored_value != 0; + } + } + g.NextTreeNodeOpenCond = 0; + } + else + { + is_open = storage->GetInt(id, (flags & ImGuiTreeNodeFlags_DefaultOpen) ? 1 : 0) != 0; + } - // When logging is enabled, we automatically expand tree nodes (but *NOT* collapsing headers.. seems like sensible behavior). - // NB- If we are above max depth we still allow manually opened nodes to be logged. - if (g.LogEnabled && !(flags & ImGuiTreeNodeFlags_NoAutoOpenOnLog) && window->DC.TreeDepth < g.LogAutoExpandMaxDepth) - is_open = true; + // When logging is enabled, we automatically expand tree nodes (but *NOT* collapsing headers.. seems like sensible behavior). + // NB- If we are above max depth we still allow manually opened nodes to be logged. + if (g.LogEnabled && !(flags & ImGuiTreeNodeFlags_NoAutoOpenOnLog) && window->DC.TreeDepth < g.LogAutoExpandMaxDepth) + is_open = true; - return is_open; + return is_open; } bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; - const bool display_frame = (flags & ImGuiTreeNodeFlags_Framed) != 0; - const ImVec2 padding = (display_frame || (flags & ImGuiTreeNodeFlags_FramePadding)) ? style.FramePadding : ImVec2(style.FramePadding.x, 0.0f); + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const bool display_frame = (flags & ImGuiTreeNodeFlags_Framed) != 0; + const ImVec2 padding = (display_frame || (flags & ImGuiTreeNodeFlags_FramePadding)) ? style.FramePadding : ImVec2(style.FramePadding.x, 0.0f); - if (!label_end) - label_end = FindRenderedTextEnd(label); - const ImVec2 label_size = CalcTextSize(label, label_end, false); + if (!label_end) + label_end = FindRenderedTextEnd(label); + const ImVec2 label_size = CalcTextSize(label, label_end, false); - // We vertically grow up to current line height up the typical widget height. - const float text_base_offset_y = ImMax(padding.y, window->DC.CurrentLineTextBaseOffset); // Latch before ItemSize changes it - const float frame_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + style.FramePadding.y*2), label_size.y + padding.y*2); - ImRect frame_bb = ImRect(window->DC.CursorPos, ImVec2(window->Pos.x + GetContentRegionMax().x, window->DC.CursorPos.y + frame_height)); - if (display_frame) - { - // Framed header expand a little outside the default padding - frame_bb.Min.x -= (float)(int)(window->WindowPadding.x*0.5f) - 1; - frame_bb.Max.x += (float)(int)(window->WindowPadding.x*0.5f) - 1; - } + // We vertically grow up to current line height up the typical widget height. + const float text_base_offset_y = ImMax(padding.y, window->DC.CurrentLineTextBaseOffset); // Latch before ItemSize changes it + const float frame_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + style.FramePadding.y * 2), label_size.y + padding.y * 2); + ImRect frame_bb = ImRect(window->DC.CursorPos, ImVec2(window->Pos.x + GetContentRegionMax().x, window->DC.CursorPos.y + frame_height)); + if (display_frame) + { + // Framed header expand a little outside the default padding + frame_bb.Min.x -= (float)(int)(window->WindowPadding.x * 0.5f) - 1; + frame_bb.Max.x += (float)(int)(window->WindowPadding.x * 0.5f) - 1; + } - const float text_offset_x = (g.FontSize + (display_frame ? padding.x*3 : padding.x*2)); // Collapser arrow width + Spacing - const float text_width = g.FontSize + (label_size.x > 0.0f ? label_size.x + padding.x*2 : 0.0f); // Include collapser - ItemSize(ImVec2(text_width, frame_height), text_base_offset_y); + const float text_offset_x = (g.FontSize + (display_frame ? padding.x * 3 : padding.x * 2)); // Collapser arrow width + Spacing + const float text_width = g.FontSize + (label_size.x > 0.0f ? label_size.x + padding.x * 2 : 0.0f); // Include collapser + ItemSize(ImVec2(text_width, frame_height), text_base_offset_y); - // For regular tree nodes, we arbitrary allow to click past 2 worth of ItemSpacing - // (Ideally we'd want to add a flag for the user to specify if we want the hit test to be done up to the right side of the content or not) - const ImRect interact_bb = display_frame ? frame_bb : ImRect(frame_bb.Min.x, frame_bb.Min.y, frame_bb.Min.x + text_width + style.ItemSpacing.x*2, frame_bb.Max.y); - bool is_open = TreeNodeBehaviorIsOpen(id, flags); + // For regular tree nodes, we arbitrary allow to click past 2 worth of ItemSpacing + // (Ideally we'd want to add a flag for the user to specify if we want the hit test to be done up to the right side of the content or not) + const ImRect interact_bb = display_frame ? frame_bb : ImRect(frame_bb.Min.x, frame_bb.Min.y, frame_bb.Min.x + text_width + style.ItemSpacing.x * 2, frame_bb.Max.y); + bool is_open = TreeNodeBehaviorIsOpen(id, flags); - // Store a flag for the current depth to tell if we will allow closing this node when navigating one of its child. - // For this purpose we essentially compare if g.NavIdIsAlive went from 0 to 1 between TreeNode() and TreePop(). - // This is currently only support 32 level deep and we are fine with (1 << Depth) overflowing into a zero. - if (is_open && !g.NavIdIsAlive && (flags & ImGuiTreeNodeFlags_NavCloseFromChild) && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)) - window->DC.TreeDepthMayCloseOnPop |= (1 << window->DC.TreeDepth); + // Store a flag for the current depth to tell if we will allow closing this node when navigating one of its child. + // For this purpose we essentially compare if g.NavIdIsAlive went from 0 to 1 between TreeNode() and TreePop(). + // This is currently only support 32 level deep and we are fine with (1 << Depth) overflowing into a zero. + if (is_open && !g.NavIdIsAlive && (flags & ImGuiTreeNodeFlags_NavCloseFromChild) && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)) + window->DC.TreeDepthMayCloseOnPop |= (1 << window->DC.TreeDepth); - bool item_add = ItemAdd(interact_bb, id); - window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_HasDisplayRect; - window->DC.LastItemDisplayRect = frame_bb; + bool item_add = ItemAdd(interact_bb, id); + window->DC.LastItemStatusFlags |= ImGuiItemStatusFlags_HasDisplayRect; + window->DC.LastItemDisplayRect = frame_bb; - if (!item_add) - { - if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)) - TreePushRawID(id); - return is_open; - } + if (!item_add) + { + if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)) + TreePushRawID(id); + return is_open; + } - // Flags that affects opening behavior: - // - 0(default) ..................... single-click anywhere to open - // - OpenOnDoubleClick .............. double-click anywhere to open - // - OpenOnArrow .................... single-click on arrow to open - // - OpenOnDoubleClick|OpenOnArrow .. single-click on arrow or double-click anywhere to open - ImGuiButtonFlags button_flags = ImGuiButtonFlags_NoKeyModifiers | ((flags & ImGuiTreeNodeFlags_AllowItemOverlap) ? ImGuiButtonFlags_AllowItemOverlap : 0); - if (!(flags & ImGuiTreeNodeFlags_Leaf)) - button_flags |= ImGuiButtonFlags_PressedOnDragDropHold; - if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) - button_flags |= ImGuiButtonFlags_PressedOnDoubleClick | ((flags & ImGuiTreeNodeFlags_OpenOnArrow) ? ImGuiButtonFlags_PressedOnClickRelease : 0); + // Flags that affects opening behavior: + // - 0(default) ..................... single-click anywhere to open + // - OpenOnDoubleClick .............. double-click anywhere to open + // - OpenOnArrow .................... single-click on arrow to open + // - OpenOnDoubleClick|OpenOnArrow .. single-click on arrow or double-click anywhere to open + ImGuiButtonFlags button_flags = ImGuiButtonFlags_NoKeyModifiers | ((flags & ImGuiTreeNodeFlags_AllowItemOverlap) ? ImGuiButtonFlags_AllowItemOverlap : 0); + if (!(flags & ImGuiTreeNodeFlags_Leaf)) + button_flags |= ImGuiButtonFlags_PressedOnDragDropHold; + if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) + button_flags |= ImGuiButtonFlags_PressedOnDoubleClick | ((flags & ImGuiTreeNodeFlags_OpenOnArrow) ? ImGuiButtonFlags_PressedOnClickRelease : 0); - bool hovered, held, pressed = ButtonBehavior(interact_bb, id, &hovered, &held, button_flags); - if (!(flags & ImGuiTreeNodeFlags_Leaf)) - { - bool toggled = false; - if (pressed) - { - toggled = !(flags & (ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick)) || (g.NavActivateId == id); - if (flags & ImGuiTreeNodeFlags_OpenOnArrow) - toggled |= IsMouseHoveringRect(interact_bb.Min, ImVec2(interact_bb.Min.x + text_offset_x, interact_bb.Max.y)) && (!g.NavDisableMouseHover); - if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) - toggled |= g.IO.MouseDoubleClicked[0]; - if (g.DragDropActive && is_open) // When using Drag and Drop "hold to open" we keep the node highlighted after opening, but never close it again. - toggled = false; - } + bool hovered, held, pressed = ButtonBehavior(interact_bb, id, &hovered, &held, button_flags); + if (!(flags & ImGuiTreeNodeFlags_Leaf)) + { + bool toggled = false; + if (pressed) + { + toggled = !(flags & (ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick)) || (g.NavActivateId == id); + if (flags & ImGuiTreeNodeFlags_OpenOnArrow) + toggled |= IsMouseHoveringRect(interact_bb.Min, ImVec2(interact_bb.Min.x + text_offset_x, interact_bb.Max.y)) && (!g.NavDisableMouseHover); + if (flags & ImGuiTreeNodeFlags_OpenOnDoubleClick) + toggled |= g.IO.MouseDoubleClicked[0]; + if (g.DragDropActive && is_open) // When using Drag and Drop "hold to open" we keep the node highlighted after opening, but never close it again. + toggled = false; + } - if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Left && is_open) - { - toggled = true; - NavMoveRequestCancel(); - } - if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Right && !is_open) // If there's something upcoming on the line we may want to give it the priority? - { - toggled = true; - NavMoveRequestCancel(); - } + if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Left && is_open) + { + toggled = true; + NavMoveRequestCancel(); + } + if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Right && !is_open) // If there's something upcoming on the line we may want to give it the priority? + { + toggled = true; + NavMoveRequestCancel(); + } - if (toggled) - { - is_open = !is_open; - window->DC.StateStorage->SetInt(id, is_open); - } - } - if (flags & ImGuiTreeNodeFlags_AllowItemOverlap) - SetItemAllowOverlap(); + if (toggled) + { + is_open = !is_open; + window->DC.StateStorage->SetInt(id, is_open); + } + } + if (flags & ImGuiTreeNodeFlags_AllowItemOverlap) + SetItemAllowOverlap(); - // Render - const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); - const ImVec2 text_pos = frame_bb.Min + ImVec2(text_offset_x, text_base_offset_y); - if (display_frame) - { - // Framed type - RenderFrame(frame_bb.Min, frame_bb.Max, col, true, style.FrameRounding); - RenderNavHighlight(frame_bb, id, ImGuiNavHighlightFlags_TypeThin); - RenderTriangle(frame_bb.Min + ImVec2(padding.x, text_base_offset_y), is_open ? ImGuiDir_Down : ImGuiDir_Right, 1.0f); - if (g.LogEnabled) - { - // NB: '##' is normally used to hide text (as a library-wide feature), so we need to specify the text range to make sure the ## aren't stripped out here. - const char log_prefix[] = "\n##"; - const char log_suffix[] = "##"; - LogRenderedText(&text_pos, log_prefix, log_prefix+3); - RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size); - LogRenderedText(&text_pos, log_suffix+1, log_suffix+3); - } - else - { - RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size); - } - } - else - { - // Unframed typed for tree nodes - if (hovered || (flags & ImGuiTreeNodeFlags_Selected)) - { - RenderFrame(frame_bb.Min, frame_bb.Max, col, false); - RenderNavHighlight(frame_bb, id, ImGuiNavHighlightFlags_TypeThin); - } + // Render + const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); + const ImVec2 text_pos = frame_bb.Min + ImVec2(text_offset_x, text_base_offset_y); + if (display_frame) + { + // Framed type + RenderFrame(frame_bb.Min, frame_bb.Max, col, true, style.FrameRounding); + RenderNavHighlight(frame_bb, id, ImGuiNavHighlightFlags_TypeThin); + RenderTriangle(frame_bb.Min + ImVec2(padding.x, text_base_offset_y), is_open ? ImGuiDir_Down : ImGuiDir_Right, 1.0f); + if (g.LogEnabled) + { + // NB: '##' is normally used to hide text (as a library-wide feature), so we need to specify the text range to make sure the ## aren't stripped out here. + const char log_prefix[] = "\n##"; + const char log_suffix[] = "##"; + LogRenderedText(&text_pos, log_prefix, log_prefix + 3); + RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size); + LogRenderedText(&text_pos, log_suffix + 1, log_suffix + 3); + } + else + { + RenderTextClipped(text_pos, frame_bb.Max, label, label_end, &label_size); + } + } + else + { + // Unframed typed for tree nodes + if (hovered || (flags & ImGuiTreeNodeFlags_Selected)) + { + RenderFrame(frame_bb.Min, frame_bb.Max, col, false); + RenderNavHighlight(frame_bb, id, ImGuiNavHighlightFlags_TypeThin); + } - if (flags & ImGuiTreeNodeFlags_Bullet) - RenderBullet(frame_bb.Min + ImVec2(text_offset_x * 0.5f, g.FontSize*0.50f + text_base_offset_y)); - else if (!(flags & ImGuiTreeNodeFlags_Leaf)) - RenderTriangle(frame_bb.Min + ImVec2(padding.x, g.FontSize*0.15f + text_base_offset_y), is_open ? ImGuiDir_Down : ImGuiDir_Right, 0.70f); - if (g.LogEnabled) - LogRenderedText(&text_pos, ">"); - RenderText(text_pos, label, label_end, false); - } + if (flags & ImGuiTreeNodeFlags_Bullet) + RenderBullet(frame_bb.Min + ImVec2(text_offset_x * 0.5f, g.FontSize * 0.50f + text_base_offset_y)); + else if (!(flags & ImGuiTreeNodeFlags_Leaf)) + RenderTriangle(frame_bb.Min + ImVec2(padding.x, g.FontSize * 0.15f + text_base_offset_y), is_open ? ImGuiDir_Down : ImGuiDir_Right, 0.70f); + if (g.LogEnabled) + LogRenderedText(&text_pos, ">"); + RenderText(text_pos, label, label_end, false); + } - if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)) - TreePushRawID(id); - return is_open; + if (is_open && !(flags & ImGuiTreeNodeFlags_NoTreePushOnOpen)) + TreePushRawID(id); + return is_open; } // CollapsingHeader returns true when opened but do not indent nor push into the ID stack (because of the ImGuiTreeNodeFlags_NoTreePushOnOpen flag). // This is basically the same as calling TreeNodeEx(label, ImGuiTreeNodeFlags_CollapsingHeader | ImGuiTreeNodeFlags_NoTreePushOnOpen). You can remove the _NoTreePushOnOpen flag if you want behavior closer to normal TreeNode(). bool ImGui::CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - return TreeNodeBehavior(window->GetID(label), flags | ImGuiTreeNodeFlags_CollapsingHeader | ImGuiTreeNodeFlags_NoTreePushOnOpen, label); + return TreeNodeBehavior(window->GetID(label), flags | ImGuiTreeNodeFlags_CollapsingHeader | ImGuiTreeNodeFlags_NoTreePushOnOpen, label); } bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - if (p_open && !*p_open) - return false; + if (p_open && !*p_open) + return false; - ImGuiID id = window->GetID(label); - bool is_open = TreeNodeBehavior(id, flags | ImGuiTreeNodeFlags_CollapsingHeader | ImGuiTreeNodeFlags_NoTreePushOnOpen | (p_open ? ImGuiTreeNodeFlags_AllowItemOverlap : 0), label); - if (p_open) - { - // Create a small overlapping close button // FIXME: We can evolve this into user accessible helpers to add extra buttons on title bars, headers, etc. - ImGuiContext& g = *GImGui; - float button_sz = g.FontSize * 0.5f; - ImGuiItemHoveredDataBackup last_item_backup; - if (CloseButton(window->GetID((void*)(intptr_t)(id+1)), ImVec2(ImMin(window->DC.LastItemRect.Max.x, window->ClipRect.Max.x) - g.Style.FramePadding.x - button_sz, window->DC.LastItemRect.Min.y + g.Style.FramePadding.y + button_sz), button_sz)) - *p_open = false; - last_item_backup.Restore(); - } + ImGuiID id = window->GetID(label); + bool is_open = TreeNodeBehavior(id, flags | ImGuiTreeNodeFlags_CollapsingHeader | ImGuiTreeNodeFlags_NoTreePushOnOpen | (p_open ? ImGuiTreeNodeFlags_AllowItemOverlap : 0), label); + if (p_open) + { + // Create a small overlapping close button // FIXME: We can evolve this into user accessible helpers to add extra buttons on title bars, headers, etc. + ImGuiContext& g = *GImGui; + float button_sz = g.FontSize * 0.5f; + ImGuiItemHoveredDataBackup last_item_backup; + if (CloseButton(window->GetID((void*)(intptr_t)(id + 1)), ImVec2(ImMin(window->DC.LastItemRect.Max.x, window->ClipRect.Max.x) - g.Style.FramePadding.x - button_sz, window->DC.LastItemRect.Min.y + g.Style.FramePadding.y + button_sz), button_sz)) + *p_open = false; + last_item_backup.Restore(); + } - return is_open; + return is_open; } bool ImGui::TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - return TreeNodeBehavior(window->GetID(label), flags, label, NULL); + return TreeNodeBehavior(window->GetID(label), flags, label, NULL); } bool ImGui::TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); - return TreeNodeBehavior(window->GetID(str_id), flags, g.TempBuffer, label_end); + ImGuiContext& g = *GImGui; + const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + return TreeNodeBehavior(window->GetID(str_id), flags, g.TempBuffer, label_end); } bool ImGui::TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); - return TreeNodeBehavior(window->GetID(ptr_id), flags, g.TempBuffer, label_end); + ImGuiContext& g = *GImGui; + const char* label_end = g.TempBuffer + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + return TreeNodeBehavior(window->GetID(ptr_id), flags, g.TempBuffer, label_end); } bool ImGui::TreeNodeV(const char* str_id, const char* fmt, va_list args) { - return TreeNodeExV(str_id, 0, fmt, args); + return TreeNodeExV(str_id, 0, fmt, args); } bool ImGui::TreeNodeV(const void* ptr_id, const char* fmt, va_list args) { - return TreeNodeExV(ptr_id, 0, fmt, args); + return TreeNodeExV(ptr_id, 0, fmt, args); } bool ImGui::TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - bool is_open = TreeNodeExV(str_id, flags, fmt, args); - va_end(args); - return is_open; + va_list args; + va_start(args, fmt); + bool is_open = TreeNodeExV(str_id, flags, fmt, args); + va_end(args); + return is_open; } bool ImGui::TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - bool is_open = TreeNodeExV(ptr_id, flags, fmt, args); - va_end(args); - return is_open; + va_list args; + va_start(args, fmt); + bool is_open = TreeNodeExV(ptr_id, flags, fmt, args); + va_end(args); + return is_open; } bool ImGui::TreeNode(const char* str_id, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - bool is_open = TreeNodeExV(str_id, 0, fmt, args); - va_end(args); - return is_open; + va_list args; + va_start(args, fmt); + bool is_open = TreeNodeExV(str_id, 0, fmt, args); + va_end(args); + return is_open; } bool ImGui::TreeNode(const void* ptr_id, const char* fmt, ...) { - va_list args; - va_start(args, fmt); - bool is_open = TreeNodeExV(ptr_id, 0, fmt, args); - va_end(args); - return is_open; + va_list args; + va_start(args, fmt); + bool is_open = TreeNodeExV(ptr_id, 0, fmt, args); + va_end(args); + return is_open; } bool ImGui::TreeNode(const char* label) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - return TreeNodeBehavior(window->GetID(label), 0, label, NULL); + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + return TreeNodeBehavior(window->GetID(label), 0, label, NULL); } void ImGui::TreeAdvanceToLabelPos() { - ImGuiContext& g = *GImGui; - g.CurrentWindow->DC.CursorPos.x += GetTreeNodeToLabelSpacing(); + ImGuiContext& g = *GImGui; + g.CurrentWindow->DC.CursorPos.x += GetTreeNodeToLabelSpacing(); } // Horizontal distance preceding label when using TreeNode() or Bullet() float ImGui::GetTreeNodeToLabelSpacing() { - ImGuiContext& g = *GImGui; - return g.FontSize + (g.Style.FramePadding.x * 2.0f); + ImGuiContext& g = *GImGui; + return g.FontSize + (g.Style.FramePadding.x * 2.0f); } void ImGui::SetNextTreeNodeOpen(bool is_open, ImGuiCond cond) { - ImGuiContext& g = *GImGui; - if (g.CurrentWindow->SkipItems) - return; - g.NextTreeNodeOpenVal = is_open; - g.NextTreeNodeOpenCond = cond ? cond : ImGuiCond_Always; + ImGuiContext& g = *GImGui; + if (g.CurrentWindow->SkipItems) + return; + g.NextTreeNodeOpenVal = is_open; + g.NextTreeNodeOpenCond = cond ? cond : ImGuiCond_Always; } void ImGui::PushID(const char* str_id) { - ImGuiWindow* window = GetCurrentWindowRead(); - window->IDStack.push_back(window->GetID(str_id)); + ImGuiWindow* window = GetCurrentWindowRead(); + window->IDStack.push_back(window->GetID(str_id)); } void ImGui::PushID(const char* str_id_begin, const char* str_id_end) { - ImGuiWindow* window = GetCurrentWindowRead(); - window->IDStack.push_back(window->GetID(str_id_begin, str_id_end)); + ImGuiWindow* window = GetCurrentWindowRead(); + window->IDStack.push_back(window->GetID(str_id_begin, str_id_end)); } void ImGui::PushID(const void* ptr_id) { - ImGuiWindow* window = GetCurrentWindowRead(); - window->IDStack.push_back(window->GetID(ptr_id)); + ImGuiWindow* window = GetCurrentWindowRead(); + window->IDStack.push_back(window->GetID(ptr_id)); } void ImGui::PushID(int int_id) { - const void* ptr_id = (void*)(intptr_t)int_id; - ImGuiWindow* window = GetCurrentWindowRead(); - window->IDStack.push_back(window->GetID(ptr_id)); + const void* ptr_id = (void*)(intptr_t)int_id; + ImGuiWindow* window = GetCurrentWindowRead(); + window->IDStack.push_back(window->GetID(ptr_id)); } void ImGui::PopID() { - ImGuiWindow* window = GetCurrentWindowRead(); - window->IDStack.pop_back(); + ImGuiWindow* window = GetCurrentWindowRead(); + window->IDStack.pop_back(); } ImGuiID ImGui::GetID(const char* str_id) { - return GImGui->CurrentWindow->GetID(str_id); + return GImGui->CurrentWindow->GetID(str_id); } ImGuiID ImGui::GetID(const char* str_id_begin, const char* str_id_end) { - return GImGui->CurrentWindow->GetID(str_id_begin, str_id_end); + return GImGui->CurrentWindow->GetID(str_id_begin, str_id_end); } ImGuiID ImGui::GetID(const void* ptr_id) { - return GImGui->CurrentWindow->GetID(ptr_id); + return GImGui->CurrentWindow->GetID(ptr_id); } void ImGui::Bullet() { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; - const float line_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + g.Style.FramePadding.y*2), g.FontSize); - const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize, line_height)); - ItemSize(bb); - if (!ItemAdd(bb, 0)) - { - SameLine(0, style.FramePadding.x*2); - return; - } + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const float line_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + g.Style.FramePadding.y * 2), g.FontSize); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize, line_height)); + ItemSize(bb); + if (!ItemAdd(bb, 0)) + { + SameLine(0, style.FramePadding.x * 2); + return; + } - // Render and stay on same line - RenderBullet(bb.Min + ImVec2(style.FramePadding.x + g.FontSize*0.5f, line_height*0.5f)); - SameLine(0, style.FramePadding.x*2); + // Render and stay on same line + RenderBullet(bb.Min + ImVec2(style.FramePadding.x + g.FontSize * 0.5f, line_height * 0.5f)); + SameLine(0, style.FramePadding.x * 2); } // Text with a little bullet aligned to the typical tree node. void ImGui::BulletTextV(const char* fmt, va_list args) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; - const char* text_begin = g.TempBuffer; - const char* text_end = text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); - const ImVec2 label_size = CalcTextSize(text_begin, text_end, false); - const float text_base_offset_y = ImMax(0.0f, window->DC.CurrentLineTextBaseOffset); // Latch before ItemSize changes it - const float line_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + g.Style.FramePadding.y*2), g.FontSize); - const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize + (label_size.x > 0.0f ? (label_size.x + style.FramePadding.x*2) : 0.0f), ImMax(line_height, label_size.y))); // Empty text doesn't add padding - ItemSize(bb); - if (!ItemAdd(bb, 0)) - return; + const char* text_begin = g.TempBuffer; + const char* text_end = text_begin + ImFormatStringV(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), fmt, args); + const ImVec2 label_size = CalcTextSize(text_begin, text_end, false); + const float text_base_offset_y = ImMax(0.0f, window->DC.CurrentLineTextBaseOffset); // Latch before ItemSize changes it + const float line_height = ImMax(ImMin(window->DC.CurrentLineHeight, g.FontSize + g.Style.FramePadding.y * 2), g.FontSize); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(g.FontSize + (label_size.x > 0.0f ? (label_size.x + style.FramePadding.x * 2) : 0.0f), ImMax(line_height, label_size.y))); // Empty text doesn't add padding + ItemSize(bb); + if (!ItemAdd(bb, 0)) + return; - // Render - RenderBullet(bb.Min + ImVec2(style.FramePadding.x + g.FontSize*0.5f, line_height*0.5f)); - RenderText(bb.Min+ImVec2(g.FontSize + style.FramePadding.x*2, text_base_offset_y), text_begin, text_end, false); + // Render + RenderBullet(bb.Min + ImVec2(style.FramePadding.x + g.FontSize * 0.5f, line_height * 0.5f)); + RenderText(bb.Min + ImVec2(g.FontSize + style.FramePadding.x * 2, text_base_offset_y), text_begin, text_end, false); } void ImGui::BulletText(const char* fmt, ...) { - va_list args; - va_start(args, fmt); - BulletTextV(fmt, args); - va_end(args); + va_list args; + va_start(args, fmt); + BulletTextV(fmt, args); + va_end(args); } static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, const char* display_format, char* buf, int buf_size) { - if (data_type == ImGuiDataType_Int) - ImFormatString(buf, buf_size, display_format, *(int*)data_ptr); - else if (data_type == ImGuiDataType_Float) - ImFormatString(buf, buf_size, display_format, *(float*)data_ptr); + if (data_type == ImGuiDataType_Int) + ImFormatString(buf, buf_size, display_format, *(int*)data_ptr); + else if (data_type == ImGuiDataType_Float) + ImFormatString(buf, buf_size, display_format, *(float*)data_ptr); } static inline void DataTypeFormatString(ImGuiDataType data_type, void* data_ptr, int decimal_precision, char* buf, int buf_size) { - if (data_type == ImGuiDataType_Int) - { - if (decimal_precision < 0) - ImFormatString(buf, buf_size, "%d", *(int*)data_ptr); - else - ImFormatString(buf, buf_size, "%.*d", decimal_precision, *(int*)data_ptr); - } - else if (data_type == ImGuiDataType_Float) - { - if (decimal_precision < 0) - ImFormatString(buf, buf_size, "%f", *(float*)data_ptr); // Ideally we'd have a minimum decimal precision of 1 to visually denote that it is a float, while hiding non-significant digits? - else - ImFormatString(buf, buf_size, "%.*f", decimal_precision, *(float*)data_ptr); - } + if (data_type == ImGuiDataType_Int) + { + if (decimal_precision < 0) + ImFormatString(buf, buf_size, "%d", *(int*)data_ptr); + else + ImFormatString(buf, buf_size, "%.*d", decimal_precision, *(int*)data_ptr); + } + else if (data_type == ImGuiDataType_Float) + { + if (decimal_precision < 0) + ImFormatString(buf, buf_size, "%f", *(float*)data_ptr); // Ideally we'd have a minimum decimal precision of 1 to visually denote that it is a float, while hiding non-significant digits? + else + ImFormatString(buf, buf_size, "%.*f", decimal_precision, *(float*)data_ptr); + } } -static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* value1, const void* value2)// Store into value1 +static void DataTypeApplyOp(ImGuiDataType data_type, int op, void* value1, const void* value2) // Store into value1 { - if (data_type == ImGuiDataType_Int) - { - if (op == '+') - *(int*)value1 = *(int*)value1 + *(const int*)value2; - else if (op == '-') - *(int*)value1 = *(int*)value1 - *(const int*)value2; - } - else if (data_type == ImGuiDataType_Float) - { - if (op == '+') - *(float*)value1 = *(float*)value1 + *(const float*)value2; - else if (op == '-') - *(float*)value1 = *(float*)value1 - *(const float*)value2; - } + if (data_type == ImGuiDataType_Int) + { + if (op == '+') + *(int*)value1 = *(int*)value1 + *(const int*)value2; + else if (op == '-') + *(int*)value1 = *(int*)value1 - *(const int*)value2; + } + else if (data_type == ImGuiDataType_Float) + { + if (op == '+') + *(float*)value1 = *(float*)value1 + *(const float*)value2; + else if (op == '-') + *(float*)value1 = *(float*)value1 - *(const float*)value2; + } } // User can input math operators (e.g. +100) to edit a numerical values. static bool DataTypeApplyOpFromText(const char* buf, const char* initial_value_buf, ImGuiDataType data_type, void* data_ptr, const char* scalar_format) { - while (ImCharIsSpace(*buf)) - buf++; + while (ImCharIsSpace(*buf)) + buf++; - // We don't support '-' op because it would conflict with inputing negative value. - // Instead you can use +-100 to subtract from an existing value - char op = buf[0]; - if (op == '+' || op == '*' || op == '/') - { - buf++; - while (ImCharIsSpace(*buf)) - buf++; - } - else - { - op = 0; - } - if (!buf[0]) - return false; + // We don't support '-' op because it would conflict with inputing negative value. + // Instead you can use +-100 to subtract from an existing value + char op = buf[0]; + if (op == '+' || op == '*' || op == '/') + { + buf++; + while (ImCharIsSpace(*buf)) + buf++; + } + else + { + op = 0; + } + if (!buf[0]) + return false; - if (data_type == ImGuiDataType_Int) - { - if (!scalar_format) - scalar_format = "%d"; - int* v = (int*)data_ptr; - const int old_v = *v; - int arg0i = *v; - if (op && sscanf(initial_value_buf, scalar_format, &arg0i) < 1) - return false; + if (data_type == ImGuiDataType_Int) + { + if (!scalar_format) + scalar_format = "%d"; + int* v = (int*)data_ptr; + const int old_v = *v; + int arg0i = *v; + if (op && sscanf(initial_value_buf, scalar_format, &arg0i) < 1) + return false; - // Store operand in a float so we can use fractional value for multipliers (*1.1), but constant always parsed as integer so we can fit big integers (e.g. 2000000003) past float precision - float arg1f = 0.0f; - if (op == '+') { if (sscanf(buf, "%f", &arg1f) == 1) *v = (int)(arg0i + arg1f); } // Add (use "+-" to subtract) - else if (op == '*') { if (sscanf(buf, "%f", &arg1f) == 1) *v = (int)(arg0i * arg1f); } // Multiply - else if (op == '/') { if (sscanf(buf, "%f", &arg1f) == 1 && arg1f != 0.0f) *v = (int)(arg0i / arg1f); }// Divide - else { if (sscanf(buf, scalar_format, &arg0i) == 1) *v = arg0i; } // Assign constant (read as integer so big values are not lossy) - return (old_v != *v); - } - else if (data_type == ImGuiDataType_Float) - { - // For floats we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in - scalar_format = "%f"; - float* v = (float*)data_ptr; - const float old_v = *v; - float arg0f = *v; - if (op && sscanf(initial_value_buf, scalar_format, &arg0f) < 1) - return false; + // Store operand in a float so we can use fractional value for multipliers (*1.1), but constant always parsed as integer so we can fit big integers (e.g. 2000000003) past float precision + float arg1f = 0.0f; + if (op == '+') + { + if (sscanf(buf, "%f", &arg1f) == 1) *v = (int)(arg0i + arg1f); + } // Add (use "+-" to subtract) + else if (op == '*') + { + if (sscanf(buf, "%f", &arg1f) == 1) *v = (int)(arg0i * arg1f); + } // Multiply + else if (op == '/') + { + if (sscanf(buf, "%f", &arg1f) == 1 && arg1f != 0.0f) *v = (int)(arg0i / arg1f); + } // Divide + else + { + if (sscanf(buf, scalar_format, &arg0i) == 1) *v = arg0i; + } // Assign constant (read as integer so big values are not lossy) + return (old_v != *v); + } + else if (data_type == ImGuiDataType_Float) + { + // For floats we have to ignore format with precision (e.g. "%.2f") because sscanf doesn't take them in + scalar_format = "%f"; + float* v = (float*)data_ptr; + const float old_v = *v; + float arg0f = *v; + if (op && sscanf(initial_value_buf, scalar_format, &arg0f) < 1) + return false; - float arg1f = 0.0f; - if (sscanf(buf, scalar_format, &arg1f) < 1) - return false; - if (op == '+') { *v = arg0f + arg1f; } // Add (use "+-" to subtract) - else if (op == '*') { *v = arg0f * arg1f; } // Multiply - else if (op == '/') { if (arg1f != 0.0f) *v = arg0f / arg1f; } // Divide - else { *v = arg1f; } // Assign constant - return (old_v != *v); - } + float arg1f = 0.0f; + if (sscanf(buf, scalar_format, &arg1f) < 1) + return false; + if (op == '+') + { + *v = arg0f + arg1f; + } // Add (use "+-" to subtract) + else if (op == '*') + { + *v = arg0f * arg1f; + } // Multiply + else if (op == '/') + { + if (arg1f != 0.0f) *v = arg0f / arg1f; + } // Divide + else + { + *v = arg1f; + } // Assign constant + return (old_v != *v); + } - return false; + return false; } // Create text input in place of a slider (when CTRL+Clicking on slider) // FIXME: Logic is messy and confusing. bool ImGui::InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); - // Our replacement widget will override the focus ID (registered previously to allow for a TAB focus to happen) - // On the first frame, g.ScalarAsInputTextId == 0, then on subsequent frames it becomes == id - SetActiveID(g.ScalarAsInputTextId, window); - g.ActiveIdAllowNavDirFlags = (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down); - SetHoveredID(0); - FocusableItemUnregister(window); + // Our replacement widget will override the focus ID (registered previously to allow for a TAB focus to happen) + // On the first frame, g.ScalarAsInputTextId == 0, then on subsequent frames it becomes == id + SetActiveID(g.ScalarAsInputTextId, window); + g.ActiveIdAllowNavDirFlags = (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down); + SetHoveredID(0); + FocusableItemUnregister(window); - char buf[32]; - DataTypeFormatString(data_type, data_ptr, decimal_precision, buf, IM_ARRAYSIZE(buf)); - bool text_value_changed = InputTextEx(label, buf, IM_ARRAYSIZE(buf), aabb.GetSize(), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll); - if (g.ScalarAsInputTextId == 0) // First frame we started displaying the InputText widget - { - IM_ASSERT(g.ActiveId == id); // InputText ID expected to match the Slider ID (else we'd need to store them both, which is also possible) - g.ScalarAsInputTextId = g.ActiveId; - SetHoveredID(id); - } - if (text_value_changed) - return DataTypeApplyOpFromText(buf, GImGui->InputTextState.InitialText.begin(), data_type, data_ptr, NULL); - return false; + char buf[32]; + DataTypeFormatString(data_type, data_ptr, decimal_precision, buf, IM_ARRAYSIZE(buf)); + bool text_value_changed = InputTextEx(label, buf, IM_ARRAYSIZE(buf), aabb.GetSize(), ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_AutoSelectAll); + if (g.ScalarAsInputTextId == 0) // First frame we started displaying the InputText widget + { + IM_ASSERT(g.ActiveId == id); // InputText ID expected to match the Slider ID (else we'd need to store them both, which is also possible) + g.ScalarAsInputTextId = g.ActiveId; + SetHoveredID(id); + } + if (text_value_changed) + return DataTypeApplyOpFromText(buf, GImGui->InputTextState.InitialText.begin(), data_type, data_ptr, NULL); + return false; } // Parse display precision back from the display format string int ImGui::ParseFormatPrecision(const char* fmt, int default_precision) { - int precision = default_precision; - while ((fmt = strchr(fmt, '%')) != NULL) - { - fmt++; - if (fmt[0] == '%') { fmt++; continue; } // Ignore "%%" - while (*fmt >= '0' && *fmt <= '9') - fmt++; - if (*fmt == '.') - { - fmt = ImAtoi(fmt + 1, &precision); - if (precision < 0 || precision > 10) - precision = default_precision; - } - if (*fmt == 'e' || *fmt == 'E') // Maximum precision with scientific notation - precision = -1; - break; - } - return precision; + int precision = default_precision; + while ((fmt = strchr(fmt, '%')) != NULL) + { + fmt++; + if (fmt[0] == '%') + { + fmt++; + continue; + } // Ignore "%%" + while (*fmt >= '0' && *fmt <= '9') + fmt++; + if (*fmt == '.') + { + fmt = ImAtoi(fmt + 1, &precision); + if (precision < 0 || precision > 10) + precision = default_precision; + } + if (*fmt == 'e' || *fmt == 'E') // Maximum precision with scientific notation + precision = -1; + break; + } + return precision; } static float GetMinimumStepAtDecimalPrecision(int decimal_precision) { - static const float min_steps[10] = { 1.0f, 0.1f, 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f, 0.0000001f, 0.00000001f, 0.000000001f }; - return (decimal_precision >= 0 && decimal_precision < 10) ? min_steps[decimal_precision] : powf(10.0f, (float)-decimal_precision); + static const float min_steps[10] = {1.0f, 0.1f, 0.01f, 0.001f, 0.0001f, 0.00001f, 0.000001f, 0.0000001f, 0.00000001f, 0.000000001f}; + return (decimal_precision >= 0 && decimal_precision < 10) ? min_steps[decimal_precision] : powf(10.0f, (float)-decimal_precision); } float ImGui::RoundScalar(float value, int decimal_precision) { - // Round past decimal precision - // So when our value is 1.99999 with a precision of 0.001 we'll end up rounding to 2.0 - // FIXME: Investigate better rounding methods - if (decimal_precision < 0) - return value; - const float min_step = GetMinimumStepAtDecimalPrecision(decimal_precision); - bool negative = value < 0.0f; - value = fabsf(value); - float remainder = fmodf(value, min_step); - if (remainder <= min_step*0.5f) - value -= remainder; - else - value += (min_step - remainder); - return negative ? -value : value; + // Round past decimal precision + // So when our value is 1.99999 with a precision of 0.001 we'll end up rounding to 2.0 + // FIXME: Investigate better rounding methods + if (decimal_precision < 0) + return value; + const float min_step = GetMinimumStepAtDecimalPrecision(decimal_precision); + bool negative = value < 0.0f; + value = fabsf(value); + float remainder = fmodf(value, min_step); + if (remainder <= min_step * 0.5f) + value -= remainder; + else + value += (min_step - remainder); + return negative ? -value : value; } static inline float SliderBehaviorCalcRatioFromValue(float v, float v_min, float v_max, float power, float linear_zero_pos) { - if (v_min == v_max) - return 0.0f; + if (v_min == v_max) + return 0.0f; - const bool is_non_linear = (power < 1.0f-0.00001f) || (power > 1.0f+0.00001f); - const float v_clamped = (v_min < v_max) ? ImClamp(v, v_min, v_max) : ImClamp(v, v_max, v_min); - if (is_non_linear) - { - if (v_clamped < 0.0f) - { - const float f = 1.0f - (v_clamped - v_min) / (ImMin(0.0f,v_max) - v_min); - return (1.0f - powf(f, 1.0f/power)) * linear_zero_pos; - } - else - { - const float f = (v_clamped - ImMax(0.0f,v_min)) / (v_max - ImMax(0.0f,v_min)); - return linear_zero_pos + powf(f, 1.0f/power) * (1.0f - linear_zero_pos); - } - } + const bool is_non_linear = (power < 1.0f - 0.00001f) || (power > 1.0f + 0.00001f); + const float v_clamped = (v_min < v_max) ? ImClamp(v, v_min, v_max) : ImClamp(v, v_max, v_min); + if (is_non_linear) + { + if (v_clamped < 0.0f) + { + const float f = 1.0f - (v_clamped - v_min) / (ImMin(0.0f, v_max) - v_min); + return (1.0f - powf(f, 1.0f / power)) * linear_zero_pos; + } + else + { + const float f = (v_clamped - ImMax(0.0f, v_min)) / (v_max - ImMax(0.0f, v_min)); + return linear_zero_pos + powf(f, 1.0f / power) * (1.0f - linear_zero_pos); + } + } - // Linear slider - return (v_clamped - v_min) / (v_max - v_min); + // Linear slider + return (v_clamped - v_min) / (v_max - v_min); } bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, ImGuiSliderFlags flags) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - const ImGuiStyle& style = g.Style; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + const ImGuiStyle& style = g.Style; - // Draw frame - const ImU32 frame_col = GetColorU32((g.ActiveId == id && g.ActiveIdSource == ImGuiInputSource_Nav) ? ImGuiCol_FrameBgActive : ImGuiCol_FrameBg); - RenderNavHighlight(frame_bb, id); - RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, style.FrameRounding); + // Draw frame + const ImU32 frame_col = GetColorU32((g.ActiveId == id && g.ActiveIdSource == ImGuiInputSource_Nav) ? ImGuiCol_FrameBgActive : ImGuiCol_FrameBg); + RenderNavHighlight(frame_bb, id); + RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, style.FrameRounding); - const bool is_non_linear = (power < 1.0f-0.00001f) || (power > 1.0f+0.00001f); - const bool is_horizontal = (flags & ImGuiSliderFlags_Vertical) == 0; + const bool is_non_linear = (power < 1.0f - 0.00001f) || (power > 1.0f + 0.00001f); + const bool is_horizontal = (flags & ImGuiSliderFlags_Vertical) == 0; - const float grab_padding = 2.0f; - const float slider_sz = is_horizontal ? (frame_bb.GetWidth() - grab_padding * 2.0f) : (frame_bb.GetHeight() - grab_padding * 2.0f); - float grab_sz; - if (decimal_precision != 0) - grab_sz = ImMin(style.GrabMinSize, slider_sz); - else - grab_sz = ImMin(ImMax(1.0f * (slider_sz / ((v_min < v_max ? v_max - v_min : v_min - v_max) + 1.0f)), style.GrabMinSize), slider_sz); // Integer sliders, if possible have the grab size represent 1 unit - const float slider_usable_sz = slider_sz - grab_sz; - const float slider_usable_pos_min = (is_horizontal ? frame_bb.Min.x : frame_bb.Min.y) + grab_padding + grab_sz*0.5f; - const float slider_usable_pos_max = (is_horizontal ? frame_bb.Max.x : frame_bb.Max.y) - grab_padding - grab_sz*0.5f; + const float grab_padding = 2.0f; + const float slider_sz = is_horizontal ? (frame_bb.GetWidth() - grab_padding * 2.0f) : (frame_bb.GetHeight() - grab_padding * 2.0f); + float grab_sz; + if (decimal_precision != 0) + grab_sz = ImMin(style.GrabMinSize, slider_sz); + else + grab_sz = ImMin(ImMax(1.0f * (slider_sz / ((v_min < v_max ? v_max - v_min : v_min - v_max) + 1.0f)), style.GrabMinSize), slider_sz); // Integer sliders, if possible have the grab size represent 1 unit + const float slider_usable_sz = slider_sz - grab_sz; + const float slider_usable_pos_min = (is_horizontal ? frame_bb.Min.x : frame_bb.Min.y) + grab_padding + grab_sz * 0.5f; + const float slider_usable_pos_max = (is_horizontal ? frame_bb.Max.x : frame_bb.Max.y) - grab_padding - grab_sz * 0.5f; - // For logarithmic sliders that cross over sign boundary we want the exponential increase to be symmetric around 0.0f - float linear_zero_pos = 0.0f; // 0.0->1.0f - if (v_min * v_max < 0.0f) - { - // Different sign - const float linear_dist_min_to_0 = powf(fabsf(0.0f - v_min), 1.0f/power); - const float linear_dist_max_to_0 = powf(fabsf(v_max - 0.0f), 1.0f/power); - linear_zero_pos = linear_dist_min_to_0 / (linear_dist_min_to_0+linear_dist_max_to_0); - } - else - { - // Same sign - linear_zero_pos = v_min < 0.0f ? 1.0f : 0.0f; - } + // For logarithmic sliders that cross over sign boundary we want the exponential increase to be symmetric around 0.0f + float linear_zero_pos = 0.0f; // 0.0->1.0f + if (v_min * v_max < 0.0f) + { + // Different sign + const float linear_dist_min_to_0 = powf(fabsf(0.0f - v_min), 1.0f / power); + const float linear_dist_max_to_0 = powf(fabsf(v_max - 0.0f), 1.0f / power); + linear_zero_pos = linear_dist_min_to_0 / (linear_dist_min_to_0 + linear_dist_max_to_0); + } + else + { + // Same sign + linear_zero_pos = v_min < 0.0f ? 1.0f : 0.0f; + } - // Process interacting with the slider - bool value_changed = false; - if (g.ActiveId == id) - { - bool set_new_value = false; - float clicked_t = 0.0f; - if (g.ActiveIdSource == ImGuiInputSource_Mouse) - { - if (!g.IO.MouseDown[0]) - { - ClearActiveID(); - } - else - { - const float mouse_abs_pos = is_horizontal ? g.IO.MousePos.x : g.IO.MousePos.y; - clicked_t = (slider_usable_sz > 0.0f) ? ImClamp((mouse_abs_pos - slider_usable_pos_min) / slider_usable_sz, 0.0f, 1.0f) : 0.0f; - if (!is_horizontal) - clicked_t = 1.0f - clicked_t; - set_new_value = true; - } - } - else if (g.ActiveIdSource == ImGuiInputSource_Nav) - { - const ImVec2 delta2 = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard | ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 0.0f, 0.0f); - float delta = is_horizontal ? delta2.x : -delta2.y; - if (g.NavActivatePressedId == id && !g.ActiveIdIsJustActivated) - { - ClearActiveID(); - } - else if (delta != 0.0f) - { - clicked_t = SliderBehaviorCalcRatioFromValue(*v, v_min, v_max, power, linear_zero_pos); - if (decimal_precision == 0 && !is_non_linear) - { - if (fabsf(v_max - v_min) <= 100.0f || IsNavInputDown(ImGuiNavInput_TweakSlow)) - delta = ((delta < 0.0f) ? -1.0f : +1.0f) / (v_max - v_min); // Gamepad/keyboard tweak speeds in integer steps - else - delta /= 100.0f; - } - else - { - delta /= 100.0f; // Gamepad/keyboard tweak speeds in % of slider bounds - if (IsNavInputDown(ImGuiNavInput_TweakSlow)) - delta /= 10.0f; - } - if (IsNavInputDown(ImGuiNavInput_TweakFast)) - delta *= 10.0f; - set_new_value = true; - if ((clicked_t >= 1.0f && delta > 0.0f) || (clicked_t <= 0.0f && delta < 0.0f)) // This is to avoid applying the saturation when already past the limits - set_new_value = false; - else - clicked_t = ImSaturate(clicked_t + delta); - } - } + // Process interacting with the slider + bool value_changed = false; + if (g.ActiveId == id) + { + bool set_new_value = false; + float clicked_t = 0.0f; + if (g.ActiveIdSource == ImGuiInputSource_Mouse) + { + if (!g.IO.MouseDown[0]) + { + ClearActiveID(); + } + else + { + const float mouse_abs_pos = is_horizontal ? g.IO.MousePos.x : g.IO.MousePos.y; + clicked_t = (slider_usable_sz > 0.0f) ? ImClamp((mouse_abs_pos - slider_usable_pos_min) / slider_usable_sz, 0.0f, 1.0f) : 0.0f; + if (!is_horizontal) + clicked_t = 1.0f - clicked_t; + set_new_value = true; + } + } + else if (g.ActiveIdSource == ImGuiInputSource_Nav) + { + const ImVec2 delta2 = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard | ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 0.0f, 0.0f); + float delta = is_horizontal ? delta2.x : -delta2.y; + if (g.NavActivatePressedId == id && !g.ActiveIdIsJustActivated) + { + ClearActiveID(); + } + else if (delta != 0.0f) + { + clicked_t = SliderBehaviorCalcRatioFromValue(*v, v_min, v_max, power, linear_zero_pos); + if (decimal_precision == 0 && !is_non_linear) + { + if (fabsf(v_max - v_min) <= 100.0f || IsNavInputDown(ImGuiNavInput_TweakSlow)) + delta = ((delta < 0.0f) ? -1.0f : +1.0f) / (v_max - v_min); // Gamepad/keyboard tweak speeds in integer steps + else + delta /= 100.0f; + } + else + { + delta /= 100.0f; // Gamepad/keyboard tweak speeds in % of slider bounds + if (IsNavInputDown(ImGuiNavInput_TweakSlow)) + delta /= 10.0f; + } + if (IsNavInputDown(ImGuiNavInput_TweakFast)) + delta *= 10.0f; + set_new_value = true; + if ((clicked_t >= 1.0f && delta > 0.0f) || (clicked_t <= 0.0f && delta < 0.0f)) // This is to avoid applying the saturation when already past the limits + set_new_value = false; + else + clicked_t = ImSaturate(clicked_t + delta); + } + } - if (set_new_value) - { - float new_value; - if (is_non_linear) - { - // Account for logarithmic scale on both sides of the zero - if (clicked_t < linear_zero_pos) - { - // Negative: rescale to the negative range before powering - float a = 1.0f - (clicked_t / linear_zero_pos); - a = powf(a, power); - new_value = ImLerp(ImMin(v_max,0.0f), v_min, a); - } - else - { - // Positive: rescale to the positive range before powering - float a; - if (fabsf(linear_zero_pos - 1.0f) > 1.e-6f) - a = (clicked_t - linear_zero_pos) / (1.0f - linear_zero_pos); - else - a = clicked_t; - a = powf(a, power); - new_value = ImLerp(ImMax(v_min,0.0f), v_max, a); - } - } - else - { - // Linear slider - new_value = ImLerp(v_min, v_max, clicked_t); - } + if (set_new_value) + { + float new_value; + if (is_non_linear) + { + // Account for logarithmic scale on both sides of the zero + if (clicked_t < linear_zero_pos) + { + // Negative: rescale to the negative range before powering + float a = 1.0f - (clicked_t / linear_zero_pos); + a = powf(a, power); + new_value = ImLerp(ImMin(v_max, 0.0f), v_min, a); + } + else + { + // Positive: rescale to the positive range before powering + float a; + if (fabsf(linear_zero_pos - 1.0f) > 1.e-6f) + a = (clicked_t - linear_zero_pos) / (1.0f - linear_zero_pos); + else + a = clicked_t; + a = powf(a, power); + new_value = ImLerp(ImMax(v_min, 0.0f), v_max, a); + } + } + else + { + // Linear slider + new_value = ImLerp(v_min, v_max, clicked_t); + } - // Round past decimal precision - new_value = RoundScalar(new_value, decimal_precision); - if (*v != new_value) - { - *v = new_value; - value_changed = true; - } - } - } + // Round past decimal precision + new_value = RoundScalar(new_value, decimal_precision); + if (*v != new_value) + { + *v = new_value; + value_changed = true; + } + } + } - // Draw - float grab_t = SliderBehaviorCalcRatioFromValue(*v, v_min, v_max, power, linear_zero_pos); - if (!is_horizontal) - grab_t = 1.0f - grab_t; - const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t); - ImRect grab_bb; - if (is_horizontal) - grab_bb = ImRect(ImVec2(grab_pos - grab_sz*0.5f, frame_bb.Min.y + grab_padding), ImVec2(grab_pos + grab_sz*0.5f, frame_bb.Max.y - grab_padding)); - else - grab_bb = ImRect(ImVec2(frame_bb.Min.x + grab_padding, grab_pos - grab_sz*0.5f), ImVec2(frame_bb.Max.x - grab_padding, grab_pos + grab_sz*0.5f)); - window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, GetColorU32(g.ActiveId == id ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding); + // Draw + float grab_t = SliderBehaviorCalcRatioFromValue(*v, v_min, v_max, power, linear_zero_pos); + if (!is_horizontal) + grab_t = 1.0f - grab_t; + const float grab_pos = ImLerp(slider_usable_pos_min, slider_usable_pos_max, grab_t); + ImRect grab_bb; + if (is_horizontal) + grab_bb = ImRect(ImVec2(grab_pos - grab_sz * 0.5f, frame_bb.Min.y + grab_padding), ImVec2(grab_pos + grab_sz * 0.5f, frame_bb.Max.y - grab_padding)); + else + grab_bb = ImRect(ImVec2(frame_bb.Min.x + grab_padding, grab_pos - grab_sz * 0.5f), ImVec2(frame_bb.Max.x - grab_padding, grab_pos + grab_sz * 0.5f)); + window->DrawList->AddRectFilled(grab_bb.Min, grab_bb.Max, GetColorU32(g.ActiveId == id ? ImGuiCol_SliderGrabActive : ImGuiCol_SliderGrab), style.GrabRounding); - return value_changed; + return value_changed; } // Use power!=1.0 for logarithmic sliders. @@ -8735,988 +8956,1016 @@ bool ImGui::SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v // "Gold: %.0f" Gold: 1 bool ImGui::SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format, float power) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); - const float w = CalcItemWidth(); + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const float w = CalcItemWidth(); - const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2.0f)); - const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f)); + const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); - // NB- we don't call ItemSize() yet because we may turn into a text edit box below - if (!ItemAdd(total_bb, id, &frame_bb)) - { - ItemSize(total_bb, style.FramePadding.y); - return false; - } - const bool hovered = ItemHoverable(frame_bb, id); + // NB- we don't call ItemSize() yet because we may turn into a text edit box below + if (!ItemAdd(total_bb, id, &frame_bb)) + { + ItemSize(total_bb, style.FramePadding.y); + return false; + } + const bool hovered = ItemHoverable(frame_bb, id); - if (!display_format) - display_format = "%.3f"; - int decimal_precision = ParseFormatPrecision(display_format, 3); + if (!display_format) + display_format = "%.3f"; + int decimal_precision = ParseFormatPrecision(display_format, 3); - // Tabbing or CTRL-clicking on Slider turns it into an input box - bool start_text_input = false; - const bool tab_focus_requested = FocusableItemRegister(window, id); - if (tab_focus_requested || (hovered && g.IO.MouseClicked[0]) || g.NavActivateId == id || (g.NavInputId == id && g.ScalarAsInputTextId != id)) - { - SetActiveID(id, window); - SetFocusID(id, window); - FocusWindow(window); - g.ActiveIdAllowNavDirFlags = (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down); - if (tab_focus_requested || g.IO.KeyCtrl || g.NavInputId == id) - { - start_text_input = true; - g.ScalarAsInputTextId = 0; - } - } - if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id)) - return InputScalarAsWidgetReplacement(frame_bb, label, ImGuiDataType_Float, v, id, decimal_precision); + // Tabbing or CTRL-clicking on Slider turns it into an input box + bool start_text_input = false; + const bool tab_focus_requested = FocusableItemRegister(window, id); + if (tab_focus_requested || (hovered && g.IO.MouseClicked[0]) || g.NavActivateId == id || (g.NavInputId == id && g.ScalarAsInputTextId != id)) + { + SetActiveID(id, window); + SetFocusID(id, window); + FocusWindow(window); + g.ActiveIdAllowNavDirFlags = (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down); + if (tab_focus_requested || g.IO.KeyCtrl || g.NavInputId == id) + { + start_text_input = true; + g.ScalarAsInputTextId = 0; + } + } + if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id)) + return InputScalarAsWidgetReplacement(frame_bb, label, ImGuiDataType_Float, v, id, decimal_precision); - // Actual slider behavior + render grab - ItemSize(total_bb, style.FramePadding.y); - const bool value_changed = SliderBehavior(frame_bb, id, v, v_min, v_max, power, decimal_precision); + // Actual slider behavior + render grab + ItemSize(total_bb, style.FramePadding.y); + const bool value_changed = SliderBehavior(frame_bb, id, v, v_min, v_max, power, decimal_precision); - // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. - char value_buf[64]; - const char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); - RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f,0.5f)); + // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. + char value_buf[64]; + const char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); + RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f)); - if (label_size.x > 0.0f) - RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); + if (label_size.x > 0.0f) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); - return value_changed; + return value_changed; } bool ImGui::VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* display_format, float power) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); - const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + size); - const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + size); + const ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); - ItemSize(bb, style.FramePadding.y); - if (!ItemAdd(frame_bb, id)) - return false; - const bool hovered = ItemHoverable(frame_bb, id); + ItemSize(bb, style.FramePadding.y); + if (!ItemAdd(frame_bb, id)) + return false; + const bool hovered = ItemHoverable(frame_bb, id); - if (!display_format) - display_format = "%.3f"; - int decimal_precision = ParseFormatPrecision(display_format, 3); + if (!display_format) + display_format = "%.3f"; + int decimal_precision = ParseFormatPrecision(display_format, 3); - if ((hovered && g.IO.MouseClicked[0]) || g.NavActivateId == id || g.NavInputId == id) - { - SetActiveID(id, window); - SetFocusID(id, window); - FocusWindow(window); - g.ActiveIdAllowNavDirFlags = (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right); - } + if ((hovered && g.IO.MouseClicked[0]) || g.NavActivateId == id || g.NavInputId == id) + { + SetActiveID(id, window); + SetFocusID(id, window); + FocusWindow(window); + g.ActiveIdAllowNavDirFlags = (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right); + } - // Actual slider behavior + render grab - bool value_changed = SliderBehavior(frame_bb, id, v, v_min, v_max, power, decimal_precision, ImGuiSliderFlags_Vertical); + // Actual slider behavior + render grab + bool value_changed = SliderBehavior(frame_bb, id, v, v_min, v_max, power, decimal_precision, ImGuiSliderFlags_Vertical); - // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. - // For the vertical slider we allow centered text to overlap the frame padding - char value_buf[64]; - char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); - RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f,0.0f)); - if (label_size.x > 0.0f) - RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); + // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. + // For the vertical slider we allow centered text to overlap the frame padding + char value_buf[64]; + char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); + RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.0f)); + if (label_size.x > 0.0f) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); - return value_changed; + return value_changed; } bool ImGui::SliderAngle(const char* label, float* v_rad, float v_degrees_min, float v_degrees_max) { - float v_deg = (*v_rad) * 360.0f / (2*IM_PI); - bool value_changed = SliderFloat(label, &v_deg, v_degrees_min, v_degrees_max, "%.0f deg", 1.0f); - *v_rad = v_deg * (2*IM_PI) / 360.0f; - return value_changed; + float v_deg = (*v_rad) * 360.0f / (2 * IM_PI); + bool value_changed = SliderFloat(label, &v_deg, v_degrees_min, v_degrees_max, "%.0f deg", 1.0f); + *v_rad = v_deg * (2 * IM_PI) / 360.0f; + return value_changed; } bool ImGui::SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format) { - if (!display_format) - display_format = "%.0f"; - float v_f = (float)*v; - bool value_changed = SliderFloat(label, &v_f, (float)v_min, (float)v_max, display_format, 1.0f); - *v = (int)v_f; - return value_changed; + if (!display_format) + display_format = "%.0f"; + float v_f = (float)*v; + bool value_changed = SliderFloat(label, &v_f, (float)v_min, (float)v_max, display_format, 1.0f); + *v = (int)v_f; + return value_changed; } bool ImGui::VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format) { - if (!display_format) - display_format = "%.0f"; - float v_f = (float)*v; - bool value_changed = VSliderFloat(label, size, &v_f, (float)v_min, (float)v_max, display_format, 1.0f); - *v = (int)v_f; - return value_changed; + if (!display_format) + display_format = "%.0f"; + float v_f = (float)*v; + bool value_changed = VSliderFloat(label, size, &v_f, (float)v_min, (float)v_max, display_format, 1.0f); + *v = (int)v_f; + return value_changed; } // Add multiple sliders on 1 line for compact edition of multiple components bool ImGui::SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* display_format, float power) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - bool value_changed = false; - BeginGroup(); - PushID(label); - PushMultiItemsWidths(components); - for (int i = 0; i < components; i++) - { - PushID(i); - value_changed |= SliderFloat("##v", &v[i], v_min, v_max, display_format, power); - SameLine(0, g.Style.ItemInnerSpacing.x); - PopID(); - PopItemWidth(); - } - PopID(); + ImGuiContext& g = *GImGui; + bool value_changed = false; + BeginGroup(); + PushID(label); + PushMultiItemsWidths(components); + for (int i = 0; i < components; i++) + { + PushID(i); + value_changed |= SliderFloat("##v", &v[i], v_min, v_max, display_format, power); + SameLine(0, g.Style.ItemInnerSpacing.x); + PopID(); + PopItemWidth(); + } + PopID(); - TextUnformatted(label, FindRenderedTextEnd(label)); - EndGroup(); + TextUnformatted(label, FindRenderedTextEnd(label)); + EndGroup(); - return value_changed; + return value_changed; } bool ImGui::SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format, float power) { - return SliderFloatN(label, v, 2, v_min, v_max, display_format, power); + return SliderFloatN(label, v, 2, v_min, v_max, display_format, power); } bool ImGui::SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format, float power) { - return SliderFloatN(label, v, 3, v_min, v_max, display_format, power); + return SliderFloatN(label, v, 3, v_min, v_max, display_format, power); } bool ImGui::SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format, float power) { - return SliderFloatN(label, v, 4, v_min, v_max, display_format, power); + return SliderFloatN(label, v, 4, v_min, v_max, display_format, power); } bool ImGui::SliderIntN(const char* label, int* v, int components, int v_min, int v_max, const char* display_format) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - bool value_changed = false; - BeginGroup(); - PushID(label); - PushMultiItemsWidths(components); - for (int i = 0; i < components; i++) - { - PushID(i); - value_changed |= SliderInt("##v", &v[i], v_min, v_max, display_format); - SameLine(0, g.Style.ItemInnerSpacing.x); - PopID(); - PopItemWidth(); - } - PopID(); + ImGuiContext& g = *GImGui; + bool value_changed = false; + BeginGroup(); + PushID(label); + PushMultiItemsWidths(components); + for (int i = 0; i < components; i++) + { + PushID(i); + value_changed |= SliderInt("##v", &v[i], v_min, v_max, display_format); + SameLine(0, g.Style.ItemInnerSpacing.x); + PopID(); + PopItemWidth(); + } + PopID(); - TextUnformatted(label, FindRenderedTextEnd(label)); - EndGroup(); + TextUnformatted(label, FindRenderedTextEnd(label)); + EndGroup(); - return value_changed; + return value_changed; } bool ImGui::SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* display_format) { - return SliderIntN(label, v, 2, v_min, v_max, display_format); + return SliderIntN(label, v, 2, v_min, v_max, display_format); } bool ImGui::SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* display_format) { - return SliderIntN(label, v, 3, v_min, v_max, display_format); + return SliderIntN(label, v, 3, v_min, v_max, display_format); } bool ImGui::SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* display_format) { - return SliderIntN(label, v, 4, v_min, v_max, display_format); + return SliderIntN(label, v, 4, v_min, v_max, display_format); } bool ImGui::DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_speed, float v_min, float v_max, int decimal_precision, float power) { - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; - // Draw frame - const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg); - RenderNavHighlight(frame_bb, id); - RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, style.FrameRounding); + // Draw frame + const ImU32 frame_col = GetColorU32(g.ActiveId == id ? ImGuiCol_FrameBgActive : g.HoveredId == id ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg); + RenderNavHighlight(frame_bb, id); + RenderFrame(frame_bb.Min, frame_bb.Max, frame_col, true, style.FrameRounding); - bool value_changed = false; + bool value_changed = false; - // Process interacting with the drag - if (g.ActiveId == id) - { - if (g.ActiveIdSource == ImGuiInputSource_Mouse && !g.IO.MouseDown[0]) - ClearActiveID(); - else if (g.ActiveIdSource == ImGuiInputSource_Nav && g.NavActivatePressedId == id && !g.ActiveIdIsJustActivated) - ClearActiveID(); - } - if (g.ActiveId == id) - { - if (g.ActiveIdIsJustActivated) - { - // Lock current value on click - g.DragCurrentValue = *v; - g.DragLastMouseDelta = ImVec2(0.f, 0.f); - } + // Process interacting with the drag + if (g.ActiveId == id) + { + if (g.ActiveIdSource == ImGuiInputSource_Mouse && !g.IO.MouseDown[0]) + ClearActiveID(); + else if (g.ActiveIdSource == ImGuiInputSource_Nav && g.NavActivatePressedId == id && !g.ActiveIdIsJustActivated) + ClearActiveID(); + } + if (g.ActiveId == id) + { + if (g.ActiveIdIsJustActivated) + { + // Lock current value on click + g.DragCurrentValue = *v; + g.DragLastMouseDelta = ImVec2(0.f, 0.f); + } - if (v_speed == 0.0f && (v_max - v_min) != 0.0f && (v_max - v_min) < FLT_MAX) - v_speed = (v_max - v_min) * g.DragSpeedDefaultRatio; + if (v_speed == 0.0f && (v_max - v_min) != 0.0f && (v_max - v_min) < FLT_MAX) + v_speed = (v_max - v_min) * g.DragSpeedDefaultRatio; - float v_cur = g.DragCurrentValue; - const ImVec2 mouse_drag_delta = GetMouseDragDelta(0, 1.0f); - float adjust_delta = 0.0f; - if (g.ActiveIdSource == ImGuiInputSource_Mouse && IsMousePosValid()) - { - adjust_delta = mouse_drag_delta.x - g.DragLastMouseDelta.x; - if (g.IO.KeyShift && g.DragSpeedScaleFast >= 0.0f) - adjust_delta *= g.DragSpeedScaleFast; - if (g.IO.KeyAlt && g.DragSpeedScaleSlow >= 0.0f) - adjust_delta *= g.DragSpeedScaleSlow; - g.DragLastMouseDelta.x = mouse_drag_delta.x; - } - if (g.ActiveIdSource == ImGuiInputSource_Nav) - { - adjust_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard|ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 1.0f/10.0f, 10.0f).x; - if (v_min < v_max && ((v_cur >= v_max && adjust_delta > 0.0f) || (v_cur <= v_min && adjust_delta < 0.0f))) // This is to avoid applying the saturation when already past the limits - adjust_delta = 0.0f; - v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision)); - } - adjust_delta *= v_speed; + float v_cur = g.DragCurrentValue; + const ImVec2 mouse_drag_delta = GetMouseDragDelta(0, 1.0f); + float adjust_delta = 0.0f; + if (g.ActiveIdSource == ImGuiInputSource_Mouse && IsMousePosValid()) + { + adjust_delta = mouse_drag_delta.x - g.DragLastMouseDelta.x; + if (g.IO.KeyShift && g.DragSpeedScaleFast >= 0.0f) + adjust_delta *= g.DragSpeedScaleFast; + if (g.IO.KeyAlt && g.DragSpeedScaleSlow >= 0.0f) + adjust_delta *= g.DragSpeedScaleSlow; + g.DragLastMouseDelta.x = mouse_drag_delta.x; + } + if (g.ActiveIdSource == ImGuiInputSource_Nav) + { + adjust_delta = GetNavInputAmount2d(ImGuiNavDirSourceFlags_Keyboard | ImGuiNavDirSourceFlags_PadDPad, ImGuiInputReadMode_RepeatFast, 1.0f / 10.0f, 10.0f).x; + if (v_min < v_max && ((v_cur >= v_max && adjust_delta > 0.0f) || (v_cur <= v_min && adjust_delta < 0.0f))) // This is to avoid applying the saturation when already past the limits + adjust_delta = 0.0f; + v_speed = ImMax(v_speed, GetMinimumStepAtDecimalPrecision(decimal_precision)); + } + adjust_delta *= v_speed; - if (fabsf(adjust_delta) > 0.0f) - { - if (fabsf(power - 1.0f) > 0.001f) - { - // Logarithmic curve on both side of 0.0 - float v0_abs = v_cur >= 0.0f ? v_cur : -v_cur; - float v0_sign = v_cur >= 0.0f ? 1.0f : -1.0f; - float v1 = powf(v0_abs, 1.0f / power) + (adjust_delta * v0_sign); - float v1_abs = v1 >= 0.0f ? v1 : -v1; - float v1_sign = v1 >= 0.0f ? 1.0f : -1.0f; // Crossed sign line - v_cur = powf(v1_abs, power) * v0_sign * v1_sign; // Reapply sign - } - else - { - v_cur += adjust_delta; - } + if (fabsf(adjust_delta) > 0.0f) + { + if (fabsf(power - 1.0f) > 0.001f) + { + // Logarithmic curve on both side of 0.0 + float v0_abs = v_cur >= 0.0f ? v_cur : -v_cur; + float v0_sign = v_cur >= 0.0f ? 1.0f : -1.0f; + float v1 = powf(v0_abs, 1.0f / power) + (adjust_delta * v0_sign); + float v1_abs = v1 >= 0.0f ? v1 : -v1; + float v1_sign = v1 >= 0.0f ? 1.0f : -1.0f; // Crossed sign line + v_cur = powf(v1_abs, power) * v0_sign * v1_sign; // Reapply sign + } + else + { + v_cur += adjust_delta; + } - // Clamp - if (v_min < v_max) - v_cur = ImClamp(v_cur, v_min, v_max); - g.DragCurrentValue = v_cur; - } + // Clamp + if (v_min < v_max) + v_cur = ImClamp(v_cur, v_min, v_max); + g.DragCurrentValue = v_cur; + } - // Round to user desired precision, then apply - v_cur = RoundScalar(v_cur, decimal_precision); - if (*v != v_cur) - { - *v = v_cur; - value_changed = true; - } - } + // Round to user desired precision, then apply + v_cur = RoundScalar(v_cur, decimal_precision); + if (*v != v_cur) + { + *v = v_cur; + value_changed = true; + } + } - return value_changed; + return value_changed; } bool ImGui::DragFloat(const char* label, float* v, float v_speed, float v_min, float v_max, const char* display_format, float power) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); - const float w = CalcItemWidth(); + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const float w = CalcItemWidth(); - const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2.0f)); - const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); - const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f)); + const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); + const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); - // NB- we don't call ItemSize() yet because we may turn into a text edit box below - if (!ItemAdd(total_bb, id, &frame_bb)) - { - ItemSize(total_bb, style.FramePadding.y); - return false; - } - const bool hovered = ItemHoverable(frame_bb, id); + // NB- we don't call ItemSize() yet because we may turn into a text edit box below + if (!ItemAdd(total_bb, id, &frame_bb)) + { + ItemSize(total_bb, style.FramePadding.y); + return false; + } + const bool hovered = ItemHoverable(frame_bb, id); - if (!display_format) - display_format = "%.3f"; - int decimal_precision = ParseFormatPrecision(display_format, 3); + if (!display_format) + display_format = "%.3f"; + int decimal_precision = ParseFormatPrecision(display_format, 3); - // Tabbing or CTRL-clicking on Drag turns it into an input box - bool start_text_input = false; - const bool tab_focus_requested = FocusableItemRegister(window, id); - if (tab_focus_requested || (hovered && (g.IO.MouseClicked[0] || g.IO.MouseDoubleClicked[0])) || g.NavActivateId == id || (g.NavInputId == id && g.ScalarAsInputTextId != id)) - { - SetActiveID(id, window); - SetFocusID(id, window); - FocusWindow(window); - g.ActiveIdAllowNavDirFlags = (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down); - if (tab_focus_requested || g.IO.KeyCtrl || g.IO.MouseDoubleClicked[0] || g.NavInputId == id) - { - start_text_input = true; - g.ScalarAsInputTextId = 0; - } - } - if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id)) - return InputScalarAsWidgetReplacement(frame_bb, label, ImGuiDataType_Float, v, id, decimal_precision); + // Tabbing or CTRL-clicking on Drag turns it into an input box + bool start_text_input = false; + const bool tab_focus_requested = FocusableItemRegister(window, id); + if (tab_focus_requested || (hovered && (g.IO.MouseClicked[0] || g.IO.MouseDoubleClicked[0])) || g.NavActivateId == id || (g.NavInputId == id && g.ScalarAsInputTextId != id)) + { + SetActiveID(id, window); + SetFocusID(id, window); + FocusWindow(window); + g.ActiveIdAllowNavDirFlags = (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down); + if (tab_focus_requested || g.IO.KeyCtrl || g.IO.MouseDoubleClicked[0] || g.NavInputId == id) + { + start_text_input = true; + g.ScalarAsInputTextId = 0; + } + } + if (start_text_input || (g.ActiveId == id && g.ScalarAsInputTextId == id)) + return InputScalarAsWidgetReplacement(frame_bb, label, ImGuiDataType_Float, v, id, decimal_precision); - // Actual drag behavior - ItemSize(total_bb, style.FramePadding.y); - const bool value_changed = DragBehavior(frame_bb, id, v, v_speed, v_min, v_max, decimal_precision, power); + // Actual drag behavior + ItemSize(total_bb, style.FramePadding.y); + const bool value_changed = DragBehavior(frame_bb, id, v, v_speed, v_min, v_max, decimal_precision, power); - // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. - char value_buf[64]; - const char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); - RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f,0.5f)); + // Display value using user-provided display format so user can add prefix/suffix/decorations to the value. + char value_buf[64]; + const char* value_buf_end = value_buf + ImFormatString(value_buf, IM_ARRAYSIZE(value_buf), display_format, *v); + RenderTextClipped(frame_bb.Min, frame_bb.Max, value_buf, value_buf_end, NULL, ImVec2(0.5f, 0.5f)); - if (label_size.x > 0.0f) - RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label); + if (label_size.x > 0.0f) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label); - return value_changed; + return value_changed; } bool ImGui::DragFloatN(const char* label, float* v, int components, float v_speed, float v_min, float v_max, const char* display_format, float power) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - bool value_changed = false; - BeginGroup(); - PushID(label); - PushMultiItemsWidths(components); - for (int i = 0; i < components; i++) - { - PushID(i); - value_changed |= DragFloat("##v", &v[i], v_speed, v_min, v_max, display_format, power); - SameLine(0, g.Style.ItemInnerSpacing.x); - PopID(); - PopItemWidth(); - } - PopID(); + ImGuiContext& g = *GImGui; + bool value_changed = false; + BeginGroup(); + PushID(label); + PushMultiItemsWidths(components); + for (int i = 0; i < components; i++) + { + PushID(i); + value_changed |= DragFloat("##v", &v[i], v_speed, v_min, v_max, display_format, power); + SameLine(0, g.Style.ItemInnerSpacing.x); + PopID(); + PopItemWidth(); + } + PopID(); - TextUnformatted(label, FindRenderedTextEnd(label)); - EndGroup(); + TextUnformatted(label, FindRenderedTextEnd(label)); + EndGroup(); - return value_changed; + return value_changed; } bool ImGui::DragFloat2(const char* label, float v[2], float v_speed, float v_min, float v_max, const char* display_format, float power) { - return DragFloatN(label, v, 2, v_speed, v_min, v_max, display_format, power); + return DragFloatN(label, v, 2, v_speed, v_min, v_max, display_format, power); } bool ImGui::DragFloat3(const char* label, float v[3], float v_speed, float v_min, float v_max, const char* display_format, float power) { - return DragFloatN(label, v, 3, v_speed, v_min, v_max, display_format, power); + return DragFloatN(label, v, 3, v_speed, v_min, v_max, display_format, power); } bool ImGui::DragFloat4(const char* label, float v[4], float v_speed, float v_min, float v_max, const char* display_format, float power) { - return DragFloatN(label, v, 4, v_speed, v_min, v_max, display_format, power); + return DragFloatN(label, v, 4, v_speed, v_min, v_max, display_format, power); } bool ImGui::DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed, float v_min, float v_max, const char* display_format, const char* display_format_max, float power) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - PushID(label); - BeginGroup(); - PushMultiItemsWidths(2); + ImGuiContext& g = *GImGui; + PushID(label); + BeginGroup(); + PushMultiItemsWidths(2); - bool value_changed = DragFloat("##min", v_current_min, v_speed, (v_min >= v_max) ? -FLT_MAX : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), display_format, power); - PopItemWidth(); - SameLine(0, g.Style.ItemInnerSpacing.x); - value_changed |= DragFloat("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? FLT_MAX : v_max, display_format_max ? display_format_max : display_format, power); - PopItemWidth(); - SameLine(0, g.Style.ItemInnerSpacing.x); + bool value_changed = DragFloat("##min", v_current_min, v_speed, (v_min >= v_max) ? -FLT_MAX : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), display_format, power); + PopItemWidth(); + SameLine(0, g.Style.ItemInnerSpacing.x); + value_changed |= DragFloat("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? FLT_MAX : v_max, display_format_max ? display_format_max : display_format, power); + PopItemWidth(); + SameLine(0, g.Style.ItemInnerSpacing.x); - TextUnformatted(label, FindRenderedTextEnd(label)); - EndGroup(); - PopID(); + TextUnformatted(label, FindRenderedTextEnd(label)); + EndGroup(); + PopID(); - return value_changed; + return value_changed; } // NB: v_speed is float to allow adjusting the drag speed with more precision bool ImGui::DragInt(const char* label, int* v, float v_speed, int v_min, int v_max, const char* display_format) { - if (!display_format) - display_format = "%.0f"; - float v_f = (float)*v; - bool value_changed = DragFloat(label, &v_f, v_speed, (float)v_min, (float)v_max, display_format); - *v = (int)v_f; - return value_changed; + if (!display_format) + display_format = "%.0f"; + float v_f = (float)*v; + bool value_changed = DragFloat(label, &v_f, v_speed, (float)v_min, (float)v_max, display_format); + *v = (int)v_f; + return value_changed; } bool ImGui::DragIntN(const char* label, int* v, int components, float v_speed, int v_min, int v_max, const char* display_format) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - bool value_changed = false; - BeginGroup(); - PushID(label); - PushMultiItemsWidths(components); - for (int i = 0; i < components; i++) - { - PushID(i); - value_changed |= DragInt("##v", &v[i], v_speed, v_min, v_max, display_format); - SameLine(0, g.Style.ItemInnerSpacing.x); - PopID(); - PopItemWidth(); - } - PopID(); + ImGuiContext& g = *GImGui; + bool value_changed = false; + BeginGroup(); + PushID(label); + PushMultiItemsWidths(components); + for (int i = 0; i < components; i++) + { + PushID(i); + value_changed |= DragInt("##v", &v[i], v_speed, v_min, v_max, display_format); + SameLine(0, g.Style.ItemInnerSpacing.x); + PopID(); + PopItemWidth(); + } + PopID(); - TextUnformatted(label, FindRenderedTextEnd(label)); - EndGroup(); + TextUnformatted(label, FindRenderedTextEnd(label)); + EndGroup(); - return value_changed; + return value_changed; } bool ImGui::DragInt2(const char* label, int v[2], float v_speed, int v_min, int v_max, const char* display_format) { - return DragIntN(label, v, 2, v_speed, v_min, v_max, display_format); + return DragIntN(label, v, 2, v_speed, v_min, v_max, display_format); } bool ImGui::DragInt3(const char* label, int v[3], float v_speed, int v_min, int v_max, const char* display_format) { - return DragIntN(label, v, 3, v_speed, v_min, v_max, display_format); + return DragIntN(label, v, 3, v_speed, v_min, v_max, display_format); } bool ImGui::DragInt4(const char* label, int v[4], float v_speed, int v_min, int v_max, const char* display_format) { - return DragIntN(label, v, 4, v_speed, v_min, v_max, display_format); + return DragIntN(label, v, 4, v_speed, v_min, v_max, display_format); } bool ImGui::DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed, int v_min, int v_max, const char* display_format, const char* display_format_max) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - PushID(label); - BeginGroup(); - PushMultiItemsWidths(2); + ImGuiContext& g = *GImGui; + PushID(label); + BeginGroup(); + PushMultiItemsWidths(2); - bool value_changed = DragInt("##min", v_current_min, v_speed, (v_min >= v_max) ? INT_MIN : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), display_format); - PopItemWidth(); - SameLine(0, g.Style.ItemInnerSpacing.x); - value_changed |= DragInt("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? INT_MAX : v_max, display_format_max ? display_format_max : display_format); - PopItemWidth(); - SameLine(0, g.Style.ItemInnerSpacing.x); + bool value_changed = DragInt("##min", v_current_min, v_speed, (v_min >= v_max) ? INT_MIN : v_min, (v_min >= v_max) ? *v_current_max : ImMin(v_max, *v_current_max), display_format); + PopItemWidth(); + SameLine(0, g.Style.ItemInnerSpacing.x); + value_changed |= DragInt("##max", v_current_max, v_speed, (v_min >= v_max) ? *v_current_min : ImMax(v_min, *v_current_min), (v_min >= v_max) ? INT_MAX : v_max, display_format_max ? display_format_max : display_format); + PopItemWidth(); + SameLine(0, g.Style.ItemInnerSpacing.x); - TextUnformatted(label, FindRenderedTextEnd(label)); - EndGroup(); - PopID(); + TextUnformatted(label, FindRenderedTextEnd(label)); + EndGroup(); + PopID(); - return value_changed; + return value_changed; } void ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; - const ImVec2 label_size = CalcTextSize(label, NULL, true); - if (graph_size.x == 0.0f) - graph_size.x = CalcItemWidth(); - if (graph_size.y == 0.0f) - graph_size.y = label_size.y + (style.FramePadding.y * 2); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + if (graph_size.x == 0.0f) + graph_size.x = CalcItemWidth(); + if (graph_size.y == 0.0f) + graph_size.y = label_size.y + (style.FramePadding.y * 2); - const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(graph_size.x, graph_size.y)); - const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); - const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0)); - ItemSize(total_bb, style.FramePadding.y); - if (!ItemAdd(total_bb, 0, &frame_bb)) - return; - const bool hovered = ItemHoverable(inner_bb, 0); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(graph_size.x, graph_size.y)); + const ImRect inner_bb(frame_bb.Min + style.FramePadding, frame_bb.Max - style.FramePadding); + const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0)); + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, 0, &frame_bb)) + return; + const bool hovered = ItemHoverable(inner_bb, 0); - // Determine scale from values if not specified - if (scale_min == FLT_MAX || scale_max == FLT_MAX) - { - float v_min = FLT_MAX; - float v_max = -FLT_MAX; - for (int i = 0; i < values_count; i++) - { - const float v = values_getter(data, i); - v_min = ImMin(v_min, v); - v_max = ImMax(v_max, v); - } - if (scale_min == FLT_MAX) - scale_min = v_min; - if (scale_max == FLT_MAX) - scale_max = v_max; - } + // Determine scale from values if not specified + if (scale_min == FLT_MAX || scale_max == FLT_MAX) + { + float v_min = FLT_MAX; + float v_max = -FLT_MAX; + for (int i = 0; i < values_count; i++) + { + const float v = values_getter(data, i); + v_min = ImMin(v_min, v); + v_max = ImMax(v_max, v); + } + if (scale_min == FLT_MAX) + scale_min = v_min; + if (scale_max == FLT_MAX) + scale_max = v_max; + } - RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); + RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); - if (values_count > 0) - { - int res_w = ImMin((int)graph_size.x, values_count) + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0); - int item_count = values_count + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0); + if (values_count > 0) + { + int res_w = ImMin((int)graph_size.x, values_count) + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0); + int item_count = values_count + ((plot_type == ImGuiPlotType_Lines) ? -1 : 0); - // Tooltip on hover - int v_hovered = -1; - if (hovered) - { - const float t = ImClamp((g.IO.MousePos.x - inner_bb.Min.x) / (inner_bb.Max.x - inner_bb.Min.x), 0.0f, 0.9999f); - const int v_idx = (int)(t * item_count); - IM_ASSERT(v_idx >= 0 && v_idx < values_count); + // Tooltip on hover + int v_hovered = -1; + if (hovered) + { + const float t = ImClamp((g.IO.MousePos.x - inner_bb.Min.x) / (inner_bb.Max.x - inner_bb.Min.x), 0.0f, 0.9999f); + const int v_idx = (int)(t * item_count); + IM_ASSERT(v_idx >= 0 && v_idx < values_count); - const float v0 = values_getter(data, (v_idx + values_offset) % values_count); - const float v1 = values_getter(data, (v_idx + 1 + values_offset) % values_count); - if (plot_type == ImGuiPlotType_Lines) - SetTooltip("%d: %8.4g\n%d: %8.4g", v_idx, v0, v_idx+1, v1); - else if (plot_type == ImGuiPlotType_Histogram) - SetTooltip("%d: %8.4g", v_idx, v0); - v_hovered = v_idx; - } + const float v0 = values_getter(data, (v_idx + values_offset) % values_count); + const float v1 = values_getter(data, (v_idx + 1 + values_offset) % values_count); + if (plot_type == ImGuiPlotType_Lines) + SetTooltip("%d: %8.4g\n%d: %8.4g", v_idx, v0, v_idx + 1, v1); + else if (plot_type == ImGuiPlotType_Histogram) + SetTooltip("%d: %8.4g", v_idx, v0); + v_hovered = v_idx; + } - const float t_step = 1.0f / (float)res_w; - const float inv_scale = (scale_min == scale_max) ? 0.0f : (1.0f / (scale_max - scale_min)); + const float t_step = 1.0f / (float)res_w; + const float inv_scale = (scale_min == scale_max) ? 0.0f : (1.0f / (scale_max - scale_min)); - float v0 = values_getter(data, (0 + values_offset) % values_count); - float t0 = 0.0f; - ImVec2 tp0 = ImVec2( t0, 1.0f - ImSaturate((v0 - scale_min) * inv_scale) ); // Point in the normalized space of our target rectangle - float histogram_zero_line_t = (scale_min * scale_max < 0.0f) ? (-scale_min * inv_scale) : (scale_min < 0.0f ? 0.0f : 1.0f); // Where does the zero line stands + float v0 = values_getter(data, (0 + values_offset) % values_count); + float t0 = 0.0f; + ImVec2 tp0 = ImVec2(t0, 1.0f - ImSaturate((v0 - scale_min) * inv_scale)); // Point in the normalized space of our target rectangle + float histogram_zero_line_t = (scale_min * scale_max < 0.0f) ? (-scale_min * inv_scale) : (scale_min < 0.0f ? 0.0f : 1.0f); // Where does the zero line stands - const ImU32 col_base = GetColorU32((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLines : ImGuiCol_PlotHistogram); - const ImU32 col_hovered = GetColorU32((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLinesHovered : ImGuiCol_PlotHistogramHovered); + const ImU32 col_base = GetColorU32((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLines : ImGuiCol_PlotHistogram); + const ImU32 col_hovered = GetColorU32((plot_type == ImGuiPlotType_Lines) ? ImGuiCol_PlotLinesHovered : ImGuiCol_PlotHistogramHovered); - for (int n = 0; n < res_w; n++) - { - const float t1 = t0 + t_step; - const int v1_idx = (int)(t0 * item_count + 0.5f); - IM_ASSERT(v1_idx >= 0 && v1_idx < values_count); - const float v1 = values_getter(data, (v1_idx + values_offset + 1) % values_count); - const ImVec2 tp1 = ImVec2( t1, 1.0f - ImSaturate((v1 - scale_min) * inv_scale) ); + for (int n = 0; n < res_w; n++) + { + const float t1 = t0 + t_step; + const int v1_idx = (int)(t0 * item_count + 0.5f); + IM_ASSERT(v1_idx >= 0 && v1_idx < values_count); + const float v1 = values_getter(data, (v1_idx + values_offset + 1) % values_count); + const ImVec2 tp1 = ImVec2(t1, 1.0f - ImSaturate((v1 - scale_min) * inv_scale)); - // NB: Draw calls are merged together by the DrawList system. Still, we should render our batch are lower level to save a bit of CPU. - ImVec2 pos0 = ImLerp(inner_bb.Min, inner_bb.Max, tp0); - ImVec2 pos1 = ImLerp(inner_bb.Min, inner_bb.Max, (plot_type == ImGuiPlotType_Lines) ? tp1 : ImVec2(tp1.x, histogram_zero_line_t)); - if (plot_type == ImGuiPlotType_Lines) - { - window->DrawList->AddLine(pos0, pos1, v_hovered == v1_idx ? col_hovered : col_base); - } - else if (plot_type == ImGuiPlotType_Histogram) - { - if (pos1.x >= pos0.x + 2.0f) - pos1.x -= 1.0f; - window->DrawList->AddRectFilled(pos0, pos1, v_hovered == v1_idx ? col_hovered : col_base); - } + // NB: Draw calls are merged together by the DrawList system. Still, we should render our batch are lower level to save a bit of CPU. + ImVec2 pos0 = ImLerp(inner_bb.Min, inner_bb.Max, tp0); + ImVec2 pos1 = ImLerp(inner_bb.Min, inner_bb.Max, (plot_type == ImGuiPlotType_Lines) ? tp1 : ImVec2(tp1.x, histogram_zero_line_t)); + if (plot_type == ImGuiPlotType_Lines) + { + window->DrawList->AddLine(pos0, pos1, v_hovered == v1_idx ? col_hovered : col_base); + } + else if (plot_type == ImGuiPlotType_Histogram) + { + if (pos1.x >= pos0.x + 2.0f) + pos1.x -= 1.0f; + window->DrawList->AddRectFilled(pos0, pos1, v_hovered == v1_idx ? col_hovered : col_base); + } - t0 = t1; - tp0 = tp1; - } - } + t0 = t1; + tp0 = tp1; + } + } - // Text overlay - if (overlay_text) - RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, overlay_text, NULL, NULL, ImVec2(0.5f,0.0f)); + // Text overlay + if (overlay_text) + RenderTextClipped(ImVec2(frame_bb.Min.x, frame_bb.Min.y + style.FramePadding.y), frame_bb.Max, overlay_text, NULL, NULL, ImVec2(0.5f, 0.0f)); - if (label_size.x > 0.0f) - RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label); + if (label_size.x > 0.0f) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, inner_bb.Min.y), label); } struct ImGuiPlotArrayGetterData { - const float* Values; - int Stride; + const float* Values; + int Stride; - ImGuiPlotArrayGetterData(const float* values, int stride) { Values = values; Stride = stride; } + ImGuiPlotArrayGetterData(const float* values, int stride) + { + Values = values; + Stride = stride; + } }; static float Plot_ArrayGetter(void* data, int idx) { - ImGuiPlotArrayGetterData* plot_data = (ImGuiPlotArrayGetterData*)data; - const float v = *(float*)(void*)((unsigned char*)plot_data->Values + (size_t)idx * plot_data->Stride); - return v; + ImGuiPlotArrayGetterData* plot_data = (ImGuiPlotArrayGetterData*)data; + const float v = *(float*)(void*)((unsigned char*)plot_data->Values + (size_t)idx * plot_data->Stride); + return v; } void ImGui::PlotLines(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, int stride) { - ImGuiPlotArrayGetterData data(values, stride); - PlotEx(ImGuiPlotType_Lines, label, &Plot_ArrayGetter, (void*)&data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); + ImGuiPlotArrayGetterData data(values, stride); + PlotEx(ImGuiPlotType_Lines, label, &Plot_ArrayGetter, (void*)&data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); } void ImGui::PlotLines(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) { - PlotEx(ImGuiPlotType_Lines, label, values_getter, data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); + PlotEx(ImGuiPlotType_Lines, label, values_getter, data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); } void ImGui::PlotHistogram(const char* label, const float* values, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size, int stride) { - ImGuiPlotArrayGetterData data(values, stride); - PlotEx(ImGuiPlotType_Histogram, label, &Plot_ArrayGetter, (void*)&data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); + ImGuiPlotArrayGetterData data(values, stride); + PlotEx(ImGuiPlotType_Histogram, label, &Plot_ArrayGetter, (void*)&data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); } void ImGui::PlotHistogram(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size) { - PlotEx(ImGuiPlotType_Histogram, label, values_getter, data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); + PlotEx(ImGuiPlotType_Histogram, label, values_getter, data, values_count, values_offset, overlay_text, scale_min, scale_max, graph_size); } // size_arg (for each axis) < 0.0f: align to end, 0.0f: auto, > 0.0f: specified size void ImGui::ProgressBar(float fraction, const ImVec2& size_arg, const char* overlay) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; - ImVec2 pos = window->DC.CursorPos; - ImRect bb(pos, pos + CalcItemSize(size_arg, CalcItemWidth(), g.FontSize + style.FramePadding.y*2.0f)); - ItemSize(bb, style.FramePadding.y); - if (!ItemAdd(bb, 0)) - return; + ImVec2 pos = window->DC.CursorPos; + ImRect bb(pos, pos + CalcItemSize(size_arg, CalcItemWidth(), g.FontSize + style.FramePadding.y * 2.0f)); + ItemSize(bb, style.FramePadding.y); + if (!ItemAdd(bb, 0)) + return; - // Render - fraction = ImSaturate(fraction); - RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); - bb.Expand(ImVec2(-style.FrameBorderSize, -style.FrameBorderSize)); - const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction), bb.Max.y); - RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), 0.0f, fraction, style.FrameRounding); + // Render + fraction = ImSaturate(fraction); + RenderFrame(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); + bb.Expand(ImVec2(-style.FrameBorderSize, -style.FrameBorderSize)); + const ImVec2 fill_br = ImVec2(ImLerp(bb.Min.x, bb.Max.x, fraction), bb.Max.y); + RenderRectFilledRangeH(window->DrawList, bb, GetColorU32(ImGuiCol_PlotHistogram), 0.0f, fraction, style.FrameRounding); - // Default displaying the fraction as percentage string, but user can override it - char overlay_buf[32]; - if (!overlay) - { - ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%.0f%%", fraction*100+0.01f); - overlay = overlay_buf; - } + // Default displaying the fraction as percentage string, but user can override it + char overlay_buf[32]; + if (!overlay) + { + ImFormatString(overlay_buf, IM_ARRAYSIZE(overlay_buf), "%.0f%%", fraction * 100 + 0.01f); + overlay = overlay_buf; + } - ImVec2 overlay_size = CalcTextSize(overlay, NULL); - if (overlay_size.x > 0.0f) - RenderTextClipped(ImVec2(ImClamp(fill_br.x + style.ItemSpacing.x, bb.Min.x, bb.Max.x - overlay_size.x - style.ItemInnerSpacing.x), bb.Min.y), bb.Max, overlay, NULL, &overlay_size, ImVec2(0.0f,0.5f), &bb); + ImVec2 overlay_size = CalcTextSize(overlay, NULL); + if (overlay_size.x > 0.0f) + RenderTextClipped(ImVec2(ImClamp(fill_br.x + style.ItemSpacing.x, bb.Min.x, bb.Max.x - overlay_size.x - style.ItemInnerSpacing.x), bb.Min.y), bb.Max, overlay, NULL, &overlay_size, ImVec2(0.0f, 0.5f), &bb); } bool ImGui::Checkbox(const char* label, bool* v) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); - const ImVec2 label_size = CalcTextSize(label, NULL, true); + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImRect check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y*2, label_size.y + style.FramePadding.y*2)); // We want a square shape to we use Y twice - ItemSize(check_bb, style.FramePadding.y); + const ImRect check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y * 2, label_size.y + style.FramePadding.y * 2)); // We want a square shape to we use Y twice + ItemSize(check_bb, style.FramePadding.y); - ImRect total_bb = check_bb; - if (label_size.x > 0) - SameLine(0, style.ItemInnerSpacing.x); - const ImRect text_bb(window->DC.CursorPos + ImVec2(0,style.FramePadding.y), window->DC.CursorPos + ImVec2(0,style.FramePadding.y) + label_size); - if (label_size.x > 0) - { - ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()), style.FramePadding.y); - total_bb = ImRect(ImMin(check_bb.Min, text_bb.Min), ImMax(check_bb.Max, text_bb.Max)); - } + ImRect total_bb = check_bb; + if (label_size.x > 0) + SameLine(0, style.ItemInnerSpacing.x); + const ImRect text_bb(window->DC.CursorPos + ImVec2(0, style.FramePadding.y), window->DC.CursorPos + ImVec2(0, style.FramePadding.y) + label_size); + if (label_size.x > 0) + { + ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()), style.FramePadding.y); + total_bb = ImRect(ImMin(check_bb.Min, text_bb.Min), ImMax(check_bb.Max, text_bb.Max)); + } - if (!ItemAdd(total_bb, id)) - return false; + if (!ItemAdd(total_bb, id)) + return false; - bool hovered, held; - bool pressed = ButtonBehavior(total_bb, id, &hovered, &held); - if (pressed) - *v = !(*v); + bool hovered, held; + bool pressed = ButtonBehavior(total_bb, id, &hovered, &held); + if (pressed) + *v = !(*v); - RenderNavHighlight(total_bb, id); - RenderFrame(check_bb.Min, check_bb.Max, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding); - if (*v) - { - const float check_sz = ImMin(check_bb.GetWidth(), check_bb.GetHeight()); - const float pad = ImMax(1.0f, (float)(int)(check_sz / 6.0f)); - RenderCheckMark(check_bb.Min + ImVec2(pad,pad), GetColorU32(ImGuiCol_CheckMark), check_bb.GetWidth() - pad*2.0f); - } + RenderNavHighlight(total_bb, id); + RenderFrame(check_bb.Min, check_bb.Max, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), true, style.FrameRounding); + if (*v) + { + const float check_sz = ImMin(check_bb.GetWidth(), check_bb.GetHeight()); + const float pad = ImMax(1.0f, (float)(int)(check_sz / 6.0f)); + RenderCheckMark(check_bb.Min + ImVec2(pad, pad), GetColorU32(ImGuiCol_CheckMark), check_bb.GetWidth() - pad * 2.0f); + } - if (g.LogEnabled) - LogRenderedText(&text_bb.Min, *v ? "[x]" : "[ ]"); - if (label_size.x > 0.0f) - RenderText(text_bb.Min, label); + if (g.LogEnabled) + LogRenderedText(&text_bb.Min, *v ? "[x]" : "[ ]"); + if (label_size.x > 0.0f) + RenderText(text_bb.Min, label); - return pressed; + return pressed; } bool ImGui::CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value) { - bool v = ((*flags & flags_value) == flags_value); - bool pressed = Checkbox(label, &v); - if (pressed) - { - if (v) - *flags |= flags_value; - else - *flags &= ~flags_value; - } + bool v = ((*flags & flags_value) == flags_value); + bool pressed = Checkbox(label, &v); + if (pressed) + { + if (v) + *flags |= flags_value; + else + *flags &= ~flags_value; + } - return pressed; + return pressed; } bool ImGui::RadioButton(const char* label, bool active) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); - const ImVec2 label_size = CalcTextSize(label, NULL, true); + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImRect check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y*2-1, label_size.y + style.FramePadding.y*2-1)); - ItemSize(check_bb, style.FramePadding.y); + const ImRect check_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(label_size.y + style.FramePadding.y * 2 - 1, label_size.y + style.FramePadding.y * 2 - 1)); + ItemSize(check_bb, style.FramePadding.y); - ImRect total_bb = check_bb; - if (label_size.x > 0) - SameLine(0, style.ItemInnerSpacing.x); - const ImRect text_bb(window->DC.CursorPos + ImVec2(0, style.FramePadding.y), window->DC.CursorPos + ImVec2(0, style.FramePadding.y) + label_size); - if (label_size.x > 0) - { - ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()), style.FramePadding.y); - total_bb.Add(text_bb); - } + ImRect total_bb = check_bb; + if (label_size.x > 0) + SameLine(0, style.ItemInnerSpacing.x); + const ImRect text_bb(window->DC.CursorPos + ImVec2(0, style.FramePadding.y), window->DC.CursorPos + ImVec2(0, style.FramePadding.y) + label_size); + if (label_size.x > 0) + { + ItemSize(ImVec2(text_bb.GetWidth(), check_bb.GetHeight()), style.FramePadding.y); + total_bb.Add(text_bb); + } - if (!ItemAdd(total_bb, id)) - return false; + if (!ItemAdd(total_bb, id)) + return false; - ImVec2 center = check_bb.GetCenter(); - center.x = (float)(int)center.x + 0.5f; - center.y = (float)(int)center.y + 0.5f; - const float radius = check_bb.GetHeight() * 0.5f; + ImVec2 center = check_bb.GetCenter(); + center.x = (float)(int)center.x + 0.5f; + center.y = (float)(int)center.y + 0.5f; + const float radius = check_bb.GetHeight() * 0.5f; - bool hovered, held; - bool pressed = ButtonBehavior(total_bb, id, &hovered, &held); + bool hovered, held; + bool pressed = ButtonBehavior(total_bb, id, &hovered, &held); - RenderNavHighlight(total_bb, id); - window->DrawList->AddCircleFilled(center, radius, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), 16); - if (active) - { - const float check_sz = ImMin(check_bb.GetWidth(), check_bb.GetHeight()); - const float pad = ImMax(1.0f, (float)(int)(check_sz / 6.0f)); - window->DrawList->AddCircleFilled(center, radius-pad, GetColorU32(ImGuiCol_CheckMark), 16); - } + RenderNavHighlight(total_bb, id); + window->DrawList->AddCircleFilled(center, radius, GetColorU32((held && hovered) ? ImGuiCol_FrameBgActive : hovered ? ImGuiCol_FrameBgHovered : ImGuiCol_FrameBg), 16); + if (active) + { + const float check_sz = ImMin(check_bb.GetWidth(), check_bb.GetHeight()); + const float pad = ImMax(1.0f, (float)(int)(check_sz / 6.0f)); + window->DrawList->AddCircleFilled(center, radius - pad, GetColorU32(ImGuiCol_CheckMark), 16); + } - if (style.FrameBorderSize > 0.0f) - { - window->DrawList->AddCircle(center+ImVec2(1,1), radius, GetColorU32(ImGuiCol_BorderShadow), 16, style.FrameBorderSize); - window->DrawList->AddCircle(center, radius, GetColorU32(ImGuiCol_Border), 16, style.FrameBorderSize); - } + if (style.FrameBorderSize > 0.0f) + { + window->DrawList->AddCircle(center + ImVec2(1, 1), radius, GetColorU32(ImGuiCol_BorderShadow), 16, style.FrameBorderSize); + window->DrawList->AddCircle(center, radius, GetColorU32(ImGuiCol_Border), 16, style.FrameBorderSize); + } - if (g.LogEnabled) - LogRenderedText(&text_bb.Min, active ? "(x)" : "( )"); - if (label_size.x > 0.0f) - RenderText(text_bb.Min, label); + if (g.LogEnabled) + LogRenderedText(&text_bb.Min, active ? "(x)" : "( )"); + if (label_size.x > 0.0f) + RenderText(text_bb.Min, label); - return pressed; + return pressed; } bool ImGui::RadioButton(const char* label, int* v, int v_button) { - const bool pressed = RadioButton(label, *v == v_button); - if (pressed) - { - *v = v_button; - } - return pressed; + const bool pressed = RadioButton(label, *v == v_button); + if (pressed) + { + *v = v_button; + } + return pressed; } static int InputTextCalcTextLenAndLineCount(const char* text_begin, const char** out_text_end) { - int line_count = 0; - const char* s = text_begin; - while (char c = *s++) // We are only matching for \n so we can ignore UTF-8 decoding - if (c == '\n') - line_count++; - s--; - if (s[0] != '\n' && s[0] != '\r') - line_count++; - *out_text_end = s; - return line_count; + int line_count = 0; + const char* s = text_begin; + while (char c = *s++) // We are only matching for \n so we can ignore UTF-8 decoding + if (c == '\n') + line_count++; + s--; + if (s[0] != '\n' && s[0] != '\r') + line_count++; + *out_text_end = s; + return line_count; } static ImVec2 InputTextCalcTextSizeW(const ImWchar* text_begin, const ImWchar* text_end, const ImWchar** remaining, ImVec2* out_offset, bool stop_on_new_line) { - ImFont* font = GImGui->Font; - const float line_height = GImGui->FontSize; - const float scale = line_height / font->FontSize; + ImFont* font = GImGui->Font; + const float line_height = GImGui->FontSize; + const float scale = line_height / font->FontSize; - ImVec2 text_size = ImVec2(0,0); - float line_width = 0.0f; + ImVec2 text_size = ImVec2(0, 0); + float line_width = 0.0f; - const ImWchar* s = text_begin; - while (s < text_end) - { - unsigned int c = (unsigned int)(*s++); - if (c == '\n') - { - text_size.x = ImMax(text_size.x, line_width); - text_size.y += line_height; - line_width = 0.0f; - if (stop_on_new_line) - break; - continue; - } - if (c == '\r') - continue; + const ImWchar* s = text_begin; + while (s < text_end) + { + unsigned int c = (unsigned int)(*s++); + if (c == '\n') + { + text_size.x = ImMax(text_size.x, line_width); + text_size.y += line_height; + line_width = 0.0f; + if (stop_on_new_line) + break; + continue; + } + if (c == '\r') + continue; - const float char_width = font->GetCharAdvance((unsigned short)c) * scale; - line_width += char_width; - } + const float char_width = font->GetCharAdvance((unsigned short)c) * scale; + line_width += char_width; + } - if (text_size.x < line_width) - text_size.x = line_width; + if (text_size.x < line_width) + text_size.x = line_width; - if (out_offset) - *out_offset = ImVec2(line_width, text_size.y + line_height); // offset allow for the possibility of sitting after a trailing \n + if (out_offset) + *out_offset = ImVec2(line_width, text_size.y + line_height); // offset allow for the possibility of sitting after a trailing \n - if (line_width > 0 || text_size.y == 0.0f) // whereas size.y will ignore the trailing \n - text_size.y += line_height; + if (line_width > 0 || text_size.y == 0.0f) // whereas size.y will ignore the trailing \n + text_size.y += line_height; - if (remaining) - *remaining = s; + if (remaining) + *remaining = s; - return text_size; + return text_size; } // Wrapper for stb_textedit.h to edit text (our wrapper is for: statically sized buffer, single-line, wchar characters. InputText converts between UTF-8 and wchar) namespace ImGuiStb { - -static int STB_TEXTEDIT_STRINGLEN(const STB_TEXTEDIT_STRING* obj) { return obj->CurLenW; } -static ImWchar STB_TEXTEDIT_GETCHAR(const STB_TEXTEDIT_STRING* obj, int idx) { return obj->Text[idx]; } -static float STB_TEXTEDIT_GETWIDTH(STB_TEXTEDIT_STRING* obj, int line_start_idx, int char_idx) { ImWchar c = obj->Text[line_start_idx+char_idx]; if (c == '\n') return STB_TEXTEDIT_GETWIDTH_NEWLINE; return GImGui->Font->GetCharAdvance(c) * (GImGui->FontSize / GImGui->Font->FontSize); } -static int STB_TEXTEDIT_KEYTOTEXT(int key) { return key >= 0x10000 ? 0 : key; } -static ImWchar STB_TEXTEDIT_NEWLINE = '\n'; -static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, STB_TEXTEDIT_STRING* obj, int line_start_idx) +static int STB_TEXTEDIT_STRINGLEN(const STB_TEXTEDIT_STRING* obj) { return obj->CurLenW; } +static ImWchar STB_TEXTEDIT_GETCHAR(const STB_TEXTEDIT_STRING* obj, int idx) { return obj->Text[idx]; } +static float STB_TEXTEDIT_GETWIDTH(STB_TEXTEDIT_STRING* obj, int line_start_idx, int char_idx) { - const ImWchar* text = obj->Text.Data; - const ImWchar* text_remaining = NULL; - const ImVec2 size = InputTextCalcTextSizeW(text + line_start_idx, text + obj->CurLenW, &text_remaining, NULL, true); - r->x0 = 0.0f; - r->x1 = size.x; - r->baseline_y_delta = size.y; - r->ymin = 0.0f; - r->ymax = size.y; - r->num_chars = (int)(text_remaining - (text + line_start_idx)); + ImWchar c = obj->Text[line_start_idx + char_idx]; + if (c == '\n') return STB_TEXTEDIT_GETWIDTH_NEWLINE; + return GImGui->Font->GetCharAdvance(c) * (GImGui->FontSize / GImGui->Font->FontSize); +} +static int STB_TEXTEDIT_KEYTOTEXT(int key) { return key >= 0x10000 ? 0 : key; } +static ImWchar STB_TEXTEDIT_NEWLINE = '\n'; +static void STB_TEXTEDIT_LAYOUTROW(StbTexteditRow* r, STB_TEXTEDIT_STRING* obj, int line_start_idx) +{ + const ImWchar* text = obj->Text.Data; + const ImWchar* text_remaining = NULL; + const ImVec2 size = InputTextCalcTextSizeW(text + line_start_idx, text + obj->CurLenW, &text_remaining, NULL, true); + r->x0 = 0.0f; + r->x1 = size.x; + r->baseline_y_delta = size.y; + r->ymin = 0.0f; + r->ymax = size.y; + r->num_chars = (int)(text_remaining - (text + line_start_idx)); } -static bool is_separator(unsigned int c) { return ImCharIsSpace(c) || c==',' || c==';' || c=='(' || c==')' || c=='{' || c=='}' || c=='[' || c==']' || c=='|'; } -static int is_word_boundary_from_right(STB_TEXTEDIT_STRING* obj, int idx) { return idx > 0 ? (is_separator( obj->Text[idx-1] ) && !is_separator( obj->Text[idx] ) ) : 1; } -static int STB_TEXTEDIT_MOVEWORDLEFT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { idx--; while (idx >= 0 && !is_word_boundary_from_right(obj, idx)) idx--; return idx < 0 ? 0 : idx; } -#ifdef __APPLE__ // FIXME: Move setting to IO structure -static int is_word_boundary_from_left(STB_TEXTEDIT_STRING* obj, int idx) { return idx > 0 ? (!is_separator( obj->Text[idx-1] ) && is_separator( obj->Text[idx] ) ) : 1; } -static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_left(obj, idx)) idx++; return idx > len ? len : idx; } +static bool is_separator(unsigned int c) { return ImCharIsSpace(c) || c == ',' || c == ';' || c == '(' || c == ')' || c == '{' || c == '}' || c == '[' || c == ']' || c == '|'; } +static int is_word_boundary_from_right(STB_TEXTEDIT_STRING* obj, int idx) { return idx > 0 ? (is_separator(obj->Text[idx - 1]) && !is_separator(obj->Text[idx])) : 1; } +static int STB_TEXTEDIT_MOVEWORDLEFT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) +{ + idx--; + while (idx >= 0 && !is_word_boundary_from_right(obj, idx)) idx--; + return idx < 0 ? 0 : idx; +} +#ifdef __APPLE__ // FIXME: Move setting to IO structure +static int is_word_boundary_from_left(STB_TEXTEDIT_STRING* obj, int idx) +{ + return idx > 0 ? (!is_separator(obj->Text[idx - 1]) && is_separator(obj->Text[idx])) : 1; +} +static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) +{ + idx++; + int len = obj->CurLenW; + while (idx < len && !is_word_boundary_from_left(obj, idx)) idx++; + return idx > len ? len : idx; +} #else -static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) { idx++; int len = obj->CurLenW; while (idx < len && !is_word_boundary_from_right(obj, idx)) idx++; return idx > len ? len : idx; } +static int STB_TEXTEDIT_MOVEWORDRIGHT_IMPL(STB_TEXTEDIT_STRING* obj, int idx) +{ + idx++; + int len = obj->CurLenW; + while (idx < len && !is_word_boundary_from_right(obj, idx)) idx++; + return idx > len ? len : idx; +} #endif -#define STB_TEXTEDIT_MOVEWORDLEFT STB_TEXTEDIT_MOVEWORDLEFT_IMPL // They need to be #define for stb_textedit.h -#define STB_TEXTEDIT_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_IMPL +#define STB_TEXTEDIT_MOVEWORDLEFT STB_TEXTEDIT_MOVEWORDLEFT_IMPL // They need to be #define for stb_textedit.h +#define STB_TEXTEDIT_MOVEWORDRIGHT STB_TEXTEDIT_MOVEWORDRIGHT_IMPL static void STB_TEXTEDIT_DELETECHARS(STB_TEXTEDIT_STRING* obj, int pos, int n) { - ImWchar* dst = obj->Text.Data + pos; + ImWchar* dst = obj->Text.Data + pos; - // We maintain our buffer length in both UTF-8 and wchar formats - obj->CurLenA -= ImTextCountUtf8BytesFromStr(dst, dst + n); - obj->CurLenW -= n; + // We maintain our buffer length in both UTF-8 and wchar formats + obj->CurLenA -= ImTextCountUtf8BytesFromStr(dst, dst + n); + obj->CurLenW -= n; - // Offset remaining text - const ImWchar* src = obj->Text.Data + pos + n; - while (ImWchar c = *src++) - *dst++ = c; - *dst = '\0'; + // Offset remaining text + const ImWchar* src = obj->Text.Data + pos + n; + while (ImWchar c = *src++) + *dst++ = c; + *dst = '\0'; } static bool STB_TEXTEDIT_INSERTCHARS(STB_TEXTEDIT_STRING* obj, int pos, const ImWchar* new_text, int new_text_len) { - const int text_len = obj->CurLenW; - IM_ASSERT(pos <= text_len); - if (new_text_len + text_len + 1 > obj->Text.Size) - return false; + const int text_len = obj->CurLenW; + IM_ASSERT(pos <= text_len); + if (new_text_len + text_len + 1 > obj->Text.Size) + return false; - const int new_text_len_utf8 = ImTextCountUtf8BytesFromStr(new_text, new_text + new_text_len); - if (new_text_len_utf8 + obj->CurLenA + 1 > obj->BufSizeA) - return false; + const int new_text_len_utf8 = ImTextCountUtf8BytesFromStr(new_text, new_text + new_text_len); + if (new_text_len_utf8 + obj->CurLenA + 1 > obj->BufSizeA) + return false; - ImWchar* text = obj->Text.Data; - if (pos != text_len) - memmove(text + pos + new_text_len, text + pos, (size_t)(text_len - pos) * sizeof(ImWchar)); - memcpy(text + pos, new_text, (size_t)new_text_len * sizeof(ImWchar)); + ImWchar* text = obj->Text.Data; + if (pos != text_len) + memmove(text + pos + new_text_len, text + pos, (size_t)(text_len - pos) * sizeof(ImWchar)); + memcpy(text + pos, new_text, (size_t)new_text_len * sizeof(ImWchar)); - obj->CurLenW += new_text_len; - obj->CurLenA += new_text_len_utf8; - obj->Text[obj->CurLenW] = '\0'; + obj->CurLenW += new_text_len; + obj->CurLenA += new_text_len_utf8; + obj->Text[obj->CurLenW] = '\0'; - return true; + return true; } // We don't use an enum so we can build even with conflicting symbols (if another user of stb_textedit.h leak their STB_TEXTEDIT_K_* symbols) -#define STB_TEXTEDIT_K_LEFT 0x10000 // keyboard input to move cursor left -#define STB_TEXTEDIT_K_RIGHT 0x10001 // keyboard input to move cursor right -#define STB_TEXTEDIT_K_UP 0x10002 // keyboard input to move cursor up -#define STB_TEXTEDIT_K_DOWN 0x10003 // keyboard input to move cursor down -#define STB_TEXTEDIT_K_LINESTART 0x10004 // keyboard input to move cursor to start of line -#define STB_TEXTEDIT_K_LINEEND 0x10005 // keyboard input to move cursor to end of line -#define STB_TEXTEDIT_K_TEXTSTART 0x10006 // keyboard input to move cursor to start of text -#define STB_TEXTEDIT_K_TEXTEND 0x10007 // keyboard input to move cursor to end of text -#define STB_TEXTEDIT_K_DELETE 0x10008 // keyboard input to delete selection or character under cursor -#define STB_TEXTEDIT_K_BACKSPACE 0x10009 // keyboard input to delete selection or character left of cursor -#define STB_TEXTEDIT_K_UNDO 0x1000A // keyboard input to perform undo -#define STB_TEXTEDIT_K_REDO 0x1000B // keyboard input to perform redo -#define STB_TEXTEDIT_K_WORDLEFT 0x1000C // keyboard input to move cursor left one word -#define STB_TEXTEDIT_K_WORDRIGHT 0x1000D // keyboard input to move cursor right one word -#define STB_TEXTEDIT_K_SHIFT 0x20000 +#define STB_TEXTEDIT_K_LEFT 0x10000 // keyboard input to move cursor left +#define STB_TEXTEDIT_K_RIGHT 0x10001 // keyboard input to move cursor right +#define STB_TEXTEDIT_K_UP 0x10002 // keyboard input to move cursor up +#define STB_TEXTEDIT_K_DOWN 0x10003 // keyboard input to move cursor down +#define STB_TEXTEDIT_K_LINESTART 0x10004 // keyboard input to move cursor to start of line +#define STB_TEXTEDIT_K_LINEEND 0x10005 // keyboard input to move cursor to end of line +#define STB_TEXTEDIT_K_TEXTSTART 0x10006 // keyboard input to move cursor to start of text +#define STB_TEXTEDIT_K_TEXTEND 0x10007 // keyboard input to move cursor to end of text +#define STB_TEXTEDIT_K_DELETE 0x10008 // keyboard input to delete selection or character under cursor +#define STB_TEXTEDIT_K_BACKSPACE 0x10009 // keyboard input to delete selection or character left of cursor +#define STB_TEXTEDIT_K_UNDO 0x1000A // keyboard input to perform undo +#define STB_TEXTEDIT_K_REDO 0x1000B // keyboard input to perform redo +#define STB_TEXTEDIT_K_WORDLEFT 0x1000C // keyboard input to move cursor left one word +#define STB_TEXTEDIT_K_WORDRIGHT 0x1000D // keyboard input to move cursor right one word +#define STB_TEXTEDIT_K_SHIFT 0x20000 #define STB_TEXTEDIT_IMPLEMENTATION #include "stb_textedit.h" -} +} // namespace ImGuiStb void ImGuiTextEditState::OnKeyPressed(int key) { - stb_textedit_key(this, &StbState, key); - CursorFollow = true; - CursorAnimReset(); + stb_textedit_key(this, &StbState, key); + CursorFollow = true; + CursorAnimReset(); } // Public API to manipulate UTF-8 text @@ -9724,92 +9973,92 @@ void ImGuiTextEditState::OnKeyPressed(int key) // FIXME: The existence of this rarely exercised code path is a bit of a nuisance. void ImGuiTextEditCallbackData::DeleteChars(int pos, int bytes_count) { - IM_ASSERT(pos + bytes_count <= BufTextLen); - char* dst = Buf + pos; - const char* src = Buf + pos + bytes_count; - while (char c = *src++) - *dst++ = c; - *dst = '\0'; + IM_ASSERT(pos + bytes_count <= BufTextLen); + char* dst = Buf + pos; + const char* src = Buf + pos + bytes_count; + while (char c = *src++) + *dst++ = c; + *dst = '\0'; - if (CursorPos + bytes_count >= pos) - CursorPos -= bytes_count; - else if (CursorPos >= pos) - CursorPos = pos; - SelectionStart = SelectionEnd = CursorPos; - BufDirty = true; - BufTextLen -= bytes_count; + if (CursorPos + bytes_count >= pos) + CursorPos -= bytes_count; + else if (CursorPos >= pos) + CursorPos = pos; + SelectionStart = SelectionEnd = CursorPos; + BufDirty = true; + BufTextLen -= bytes_count; } void ImGuiTextEditCallbackData::InsertChars(int pos, const char* new_text, const char* new_text_end) { - const int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)strlen(new_text); - if (new_text_len + BufTextLen + 1 >= BufSize) - return; + const int new_text_len = new_text_end ? (int)(new_text_end - new_text) : (int)strlen(new_text); + if (new_text_len + BufTextLen + 1 >= BufSize) + return; - if (BufTextLen != pos) - memmove(Buf + pos + new_text_len, Buf + pos, (size_t)(BufTextLen - pos)); - memcpy(Buf + pos, new_text, (size_t)new_text_len * sizeof(char)); - Buf[BufTextLen + new_text_len] = '\0'; + if (BufTextLen != pos) + memmove(Buf + pos + new_text_len, Buf + pos, (size_t)(BufTextLen - pos)); + memcpy(Buf + pos, new_text, (size_t)new_text_len * sizeof(char)); + Buf[BufTextLen + new_text_len] = '\0'; - if (CursorPos >= pos) - CursorPos += new_text_len; - SelectionStart = SelectionEnd = CursorPos; - BufDirty = true; - BufTextLen += new_text_len; + if (CursorPos >= pos) + CursorPos += new_text_len; + SelectionStart = SelectionEnd = CursorPos; + BufDirty = true; + BufTextLen += new_text_len; } // Return false to discard a character. static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data) { - unsigned int c = *p_char; + unsigned int c = *p_char; - if (c < 128 && c != ' ' && !isprint((int)(c & 0xFF))) - { - bool pass = false; - pass |= (c == '\n' && (flags & ImGuiInputTextFlags_Multiline)); - pass |= (c == '\t' && (flags & ImGuiInputTextFlags_AllowTabInput)); - if (!pass) - return false; - } + if (c < 128 && c != ' ' && !isprint((int)(c & 0xFF))) + { + bool pass = false; + pass |= (c == '\n' && (flags & ImGuiInputTextFlags_Multiline)); + pass |= (c == '\t' && (flags & ImGuiInputTextFlags_AllowTabInput)); + if (!pass) + return false; + } - if (c >= 0xE000 && c <= 0xF8FF) // Filter private Unicode range. I don't imagine anybody would want to input them. GLFW on OSX seems to send private characters for special keys like arrow keys. - return false; + if (c >= 0xE000 && c <= 0xF8FF) // Filter private Unicode range. I don't imagine anybody would want to input them. GLFW on OSX seems to send private characters for special keys like arrow keys. + return false; - if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank)) - { - if (flags & ImGuiInputTextFlags_CharsDecimal) - if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/')) - return false; + if (flags & (ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase | ImGuiInputTextFlags_CharsNoBlank)) + { + if (flags & ImGuiInputTextFlags_CharsDecimal) + if (!(c >= '0' && c <= '9') && (c != '.') && (c != '-') && (c != '+') && (c != '*') && (c != '/')) + return false; - if (flags & ImGuiInputTextFlags_CharsHexadecimal) - if (!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F')) - return false; + if (flags & ImGuiInputTextFlags_CharsHexadecimal) + if (!(c >= '0' && c <= '9') && !(c >= 'a' && c <= 'f') && !(c >= 'A' && c <= 'F')) + return false; - if (flags & ImGuiInputTextFlags_CharsUppercase) - if (c >= 'a' && c <= 'z') - *p_char = (c += (unsigned int)('A'-'a')); + if (flags & ImGuiInputTextFlags_CharsUppercase) + if (c >= 'a' && c <= 'z') + *p_char = (c += (unsigned int)('A' - 'a')); - if (flags & ImGuiInputTextFlags_CharsNoBlank) - if (ImCharIsSpace(c)) - return false; - } + if (flags & ImGuiInputTextFlags_CharsNoBlank) + if (ImCharIsSpace(c)) + return false; + } - if (flags & ImGuiInputTextFlags_CallbackCharFilter) - { - ImGuiTextEditCallbackData callback_data; - memset(&callback_data, 0, sizeof(ImGuiTextEditCallbackData)); - callback_data.EventFlag = ImGuiInputTextFlags_CallbackCharFilter; - callback_data.EventChar = (ImWchar)c; - callback_data.Flags = flags; - callback_data.UserData = user_data; - if (callback(&callback_data) != 0) - return false; - *p_char = callback_data.EventChar; - if (!callback_data.EventChar) - return false; - } + if (flags & ImGuiInputTextFlags_CallbackCharFilter) + { + ImGuiTextEditCallbackData callback_data; + memset(&callback_data, 0, sizeof(ImGuiTextEditCallbackData)); + callback_data.EventFlag = ImGuiInputTextFlags_CallbackCharFilter; + callback_data.EventChar = (ImWchar)c; + callback_data.Flags = flags; + callback_data.UserData = user_data; + if (callback(&callback_data) != 0) + return false; + *p_char = callback_data.EventChar; + if (!callback_data.EventChar) + return false; + } - return true; + return true; } // Edit a string of text @@ -9817,1549 +10066,1612 @@ static bool InputTextFilterCharacter(unsigned int* p_char, ImGuiInputTextFlags f // FIXME: Rather messy function partly because we are doing UTF8 > u16 > UTF8 conversions on the go to more easily handle stb_textedit calls. Ideally we should stay in UTF-8 all the time. See https://github.com/nothings/stb/issues/188 bool ImGui::InputTextEx(const char* label, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - IM_ASSERT(!((flags & ImGuiInputTextFlags_CallbackHistory) && (flags & ImGuiInputTextFlags_Multiline))); // Can't use both together (they both use up/down keys) - IM_ASSERT(!((flags & ImGuiInputTextFlags_CallbackCompletion) && (flags & ImGuiInputTextFlags_AllowTabInput))); // Can't use both together (they both use tab key) + IM_ASSERT(!((flags & ImGuiInputTextFlags_CallbackHistory) && (flags & ImGuiInputTextFlags_Multiline))); // Can't use both together (they both use up/down keys) + IM_ASSERT(!((flags & ImGuiInputTextFlags_CallbackCompletion) && (flags & ImGuiInputTextFlags_AllowTabInput))); // Can't use both together (they both use tab key) - ImGuiContext& g = *GImGui; - const ImGuiIO& io = g.IO; - const ImGuiStyle& style = g.Style; + ImGuiContext& g = *GImGui; + const ImGuiIO& io = g.IO; + const ImGuiStyle& style = g.Style; - const bool is_multiline = (flags & ImGuiInputTextFlags_Multiline) != 0; - const bool is_editable = (flags & ImGuiInputTextFlags_ReadOnly) == 0; - const bool is_password = (flags & ImGuiInputTextFlags_Password) != 0; - const bool is_undoable = (flags & ImGuiInputTextFlags_NoUndoRedo) == 0; + const bool is_multiline = (flags & ImGuiInputTextFlags_Multiline) != 0; + const bool is_editable = (flags & ImGuiInputTextFlags_ReadOnly) == 0; + const bool is_password = (flags & ImGuiInputTextFlags_Password) != 0; + const bool is_undoable = (flags & ImGuiInputTextFlags_NoUndoRedo) == 0; - if (is_multiline) // Open group before calling GetID() because groups tracks id created during their spawn - BeginGroup(); - const ImGuiID id = window->GetID(label); - const ImVec2 label_size = CalcTextSize(label, NULL, true); - ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), (is_multiline ? GetTextLineHeight() * 8.0f : label_size.y) + style.FramePadding.y*2.0f); // Arbitrary default of 8 lines high for multi-line - const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + size); - const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? (style.ItemInnerSpacing.x + label_size.x) : 0.0f, 0.0f)); + if (is_multiline) // Open group before calling GetID() because groups tracks id created during their spawn + BeginGroup(); + const ImGuiID id = window->GetID(label); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), (is_multiline ? GetTextLineHeight() * 8.0f : label_size.y) + style.FramePadding.y * 2.0f); // Arbitrary default of 8 lines high for multi-line + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + size); + const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? (style.ItemInnerSpacing.x + label_size.x) : 0.0f, 0.0f)); - ImGuiWindow* draw_window = window; - if (is_multiline) - { - ItemAdd(total_bb, id, &frame_bb); - if (!BeginChildFrame(id, frame_bb.GetSize())) - { - EndChildFrame(); - EndGroup(); - return false; - } - draw_window = GetCurrentWindow(); - size.x -= draw_window->ScrollbarSizes.x; - } - else - { - ItemSize(total_bb, style.FramePadding.y); - if (!ItemAdd(total_bb, id, &frame_bb)) - return false; - } - const bool hovered = ItemHoverable(frame_bb, id); - if (hovered) - g.MouseCursor = ImGuiMouseCursor_TextInput; + ImGuiWindow* draw_window = window; + if (is_multiline) + { + ItemAdd(total_bb, id, &frame_bb); + if (!BeginChildFrame(id, frame_bb.GetSize())) + { + EndChildFrame(); + EndGroup(); + return false; + } + draw_window = GetCurrentWindow(); + size.x -= draw_window->ScrollbarSizes.x; + } + else + { + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, id, &frame_bb)) + return false; + } + const bool hovered = ItemHoverable(frame_bb, id); + if (hovered) + g.MouseCursor = ImGuiMouseCursor_TextInput; - // Password pushes a temporary font with only a fallback glyph - if (is_password) - { - const ImFontGlyph* glyph = g.Font->FindGlyph('*'); - ImFont* password_font = &g.InputTextPasswordFont; - password_font->FontSize = g.Font->FontSize; - password_font->Scale = g.Font->Scale; - password_font->DisplayOffset = g.Font->DisplayOffset; - password_font->Ascent = g.Font->Ascent; - password_font->Descent = g.Font->Descent; - password_font->ContainerAtlas = g.Font->ContainerAtlas; - password_font->FallbackGlyph = glyph; - password_font->FallbackAdvanceX = glyph->AdvanceX; - IM_ASSERT(password_font->Glyphs.empty() && password_font->IndexAdvanceX.empty() && password_font->IndexLookup.empty()); - PushFont(password_font); - } + // Password pushes a temporary font with only a fallback glyph + if (is_password) + { + const ImFontGlyph* glyph = g.Font->FindGlyph('*'); + ImFont* password_font = &g.InputTextPasswordFont; + password_font->FontSize = g.Font->FontSize; + password_font->Scale = g.Font->Scale; + password_font->DisplayOffset = g.Font->DisplayOffset; + password_font->Ascent = g.Font->Ascent; + password_font->Descent = g.Font->Descent; + password_font->ContainerAtlas = g.Font->ContainerAtlas; + password_font->FallbackGlyph = glyph; + password_font->FallbackAdvanceX = glyph->AdvanceX; + IM_ASSERT(password_font->Glyphs.empty() && password_font->IndexAdvanceX.empty() && password_font->IndexLookup.empty()); + PushFont(password_font); + } - // NB: we are only allowed to access 'edit_state' if we are the active widget. - ImGuiTextEditState& edit_state = g.InputTextState; + // NB: we are only allowed to access 'edit_state' if we are the active widget. + ImGuiTextEditState& edit_state = g.InputTextState; - const bool focus_requested = FocusableItemRegister(window, id, (flags & (ImGuiInputTextFlags_CallbackCompletion|ImGuiInputTextFlags_AllowTabInput)) == 0); // Using completion callback disable keyboard tabbing - const bool focus_requested_by_code = focus_requested && (window->FocusIdxAllCounter == window->FocusIdxAllRequestCurrent); - const bool focus_requested_by_tab = focus_requested && !focus_requested_by_code; + const bool focus_requested = FocusableItemRegister(window, id, (flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_AllowTabInput)) == 0); // Using completion callback disable keyboard tabbing + const bool focus_requested_by_code = focus_requested && (window->FocusIdxAllCounter == window->FocusIdxAllRequestCurrent); + const bool focus_requested_by_tab = focus_requested && !focus_requested_by_code; - const bool user_clicked = hovered && io.MouseClicked[0]; - const bool user_scrolled = is_multiline && g.ActiveId == 0 && edit_state.Id == id && g.ActiveIdPreviousFrame == draw_window->GetIDNoKeepAlive("#SCROLLY"); + const bool user_clicked = hovered && io.MouseClicked[0]; + const bool user_scrolled = is_multiline && g.ActiveId == 0 && edit_state.Id == id && g.ActiveIdPreviousFrame == draw_window->GetIDNoKeepAlive("#SCROLLY"); - bool clear_active_id = false; + bool clear_active_id = false; - bool select_all = (g.ActiveId != id) && (((flags & ImGuiInputTextFlags_AutoSelectAll) != 0) || (g.NavInputId == id)) && (!is_multiline); - if (focus_requested || user_clicked || user_scrolled || g.NavInputId == id) - { - if (g.ActiveId != id) - { - // Start edition - // Take a copy of the initial buffer value (both in original UTF-8 format and converted to wchar) - // From the moment we focused we are ignoring the content of 'buf' (unless we are in read-only mode) - const int prev_len_w = edit_state.CurLenW; - edit_state.Text.resize(buf_size+1); // wchar count <= UTF-8 count. we use +1 to make sure that .Data isn't NULL so it doesn't crash. - edit_state.InitialText.resize(buf_size+1); // UTF-8. we use +1 to make sure that .Data isn't NULL so it doesn't crash. - ImStrncpy(edit_state.InitialText.Data, buf, edit_state.InitialText.Size); - const char* buf_end = NULL; - edit_state.CurLenW = ImTextStrFromUtf8(edit_state.Text.Data, edit_state.Text.Size, buf, NULL, &buf_end); - edit_state.CurLenA = (int)(buf_end - buf); // We can't get the result from ImFormatString() above because it is not UTF-8 aware. Here we'll cut off malformed UTF-8. - edit_state.CursorAnimReset(); + bool select_all = (g.ActiveId != id) && (((flags & ImGuiInputTextFlags_AutoSelectAll) != 0) || (g.NavInputId == id)) && (!is_multiline); + if (focus_requested || user_clicked || user_scrolled || g.NavInputId == id) + { + if (g.ActiveId != id) + { + // Start edition + // Take a copy of the initial buffer value (both in original UTF-8 format and converted to wchar) + // From the moment we focused we are ignoring the content of 'buf' (unless we are in read-only mode) + const int prev_len_w = edit_state.CurLenW; + edit_state.Text.resize(buf_size + 1); // wchar count <= UTF-8 count. we use +1 to make sure that .Data isn't NULL so it doesn't crash. + edit_state.InitialText.resize(buf_size + 1); // UTF-8. we use +1 to make sure that .Data isn't NULL so it doesn't crash. + ImStrncpy(edit_state.InitialText.Data, buf, edit_state.InitialText.Size); + const char* buf_end = NULL; + edit_state.CurLenW = ImTextStrFromUtf8(edit_state.Text.Data, edit_state.Text.Size, buf, NULL, &buf_end); + edit_state.CurLenA = (int)(buf_end - buf); // We can't get the result from ImFormatString() above because it is not UTF-8 aware. Here we'll cut off malformed UTF-8. + edit_state.CursorAnimReset(); - // Preserve cursor position and undo/redo stack if we come back to same widget - // FIXME: We should probably compare the whole buffer to be on the safety side. Comparing buf (utf8) and edit_state.Text (wchar). - const bool recycle_state = (edit_state.Id == id) && (prev_len_w == edit_state.CurLenW); - if (recycle_state) - { - // Recycle existing cursor/selection/undo stack but clamp position - // Note a single mouse click will override the cursor/position immediately by calling stb_textedit_click handler. - edit_state.CursorClamp(); - } - else - { - edit_state.Id = id; - edit_state.ScrollX = 0.0f; - stb_textedit_initialize_state(&edit_state.StbState, !is_multiline); - if (!is_multiline && focus_requested_by_code) - select_all = true; - } - if (flags & ImGuiInputTextFlags_AlwaysInsertMode) - edit_state.StbState.insert_mode = true; - if (!is_multiline && (focus_requested_by_tab || (user_clicked && io.KeyCtrl))) - select_all = true; - } - SetActiveID(id, window); - SetFocusID(id, window); - FocusWindow(window); - if (!is_multiline && !(flags & ImGuiInputTextFlags_CallbackHistory)) - g.ActiveIdAllowNavDirFlags |= ((1 << ImGuiDir_Up) | (1 << ImGuiDir_Down)); - } - else if (io.MouseClicked[0]) - { - // Release focus when we click outside - clear_active_id = true; - } + // Preserve cursor position and undo/redo stack if we come back to same widget + // FIXME: We should probably compare the whole buffer to be on the safety side. Comparing buf (utf8) and edit_state.Text (wchar). + const bool recycle_state = (edit_state.Id == id) && (prev_len_w == edit_state.CurLenW); + if (recycle_state) + { + // Recycle existing cursor/selection/undo stack but clamp position + // Note a single mouse click will override the cursor/position immediately by calling stb_textedit_click handler. + edit_state.CursorClamp(); + } + else + { + edit_state.Id = id; + edit_state.ScrollX = 0.0f; + stb_textedit_initialize_state(&edit_state.StbState, !is_multiline); + if (!is_multiline && focus_requested_by_code) + select_all = true; + } + if (flags & ImGuiInputTextFlags_AlwaysInsertMode) + edit_state.StbState.insert_mode = true; + if (!is_multiline && (focus_requested_by_tab || (user_clicked && io.KeyCtrl))) + select_all = true; + } + SetActiveID(id, window); + SetFocusID(id, window); + FocusWindow(window); + if (!is_multiline && !(flags & ImGuiInputTextFlags_CallbackHistory)) + g.ActiveIdAllowNavDirFlags |= ((1 << ImGuiDir_Up) | (1 << ImGuiDir_Down)); + } + else if (io.MouseClicked[0]) + { + // Release focus when we click outside + clear_active_id = true; + } - bool value_changed = false; - bool enter_pressed = false; + bool value_changed = false; + bool enter_pressed = false; - if (g.ActiveId == id) - { - if (!is_editable && !g.ActiveIdIsJustActivated) - { - // When read-only we always use the live data passed to the function - edit_state.Text.resize(buf_size+1); - const char* buf_end = NULL; - edit_state.CurLenW = ImTextStrFromUtf8(edit_state.Text.Data, edit_state.Text.Size, buf, NULL, &buf_end); - edit_state.CurLenA = (int)(buf_end - buf); - edit_state.CursorClamp(); - } + if (g.ActiveId == id) + { + if (!is_editable && !g.ActiveIdIsJustActivated) + { + // When read-only we always use the live data passed to the function + edit_state.Text.resize(buf_size + 1); + const char* buf_end = NULL; + edit_state.CurLenW = ImTextStrFromUtf8(edit_state.Text.Data, edit_state.Text.Size, buf, NULL, &buf_end); + edit_state.CurLenA = (int)(buf_end - buf); + edit_state.CursorClamp(); + } - edit_state.BufSizeA = buf_size; + edit_state.BufSizeA = buf_size; - // Although we are active we don't prevent mouse from hovering other elements unless we are interacting right now with the widget. - // Down the line we should have a cleaner library-wide concept of Selected vs Active. - g.ActiveIdAllowOverlap = !io.MouseDown[0]; - g.WantTextInputNextFrame = 1; + // Although we are active we don't prevent mouse from hovering other elements unless we are interacting right now with the widget. + // Down the line we should have a cleaner library-wide concept of Selected vs Active. + g.ActiveIdAllowOverlap = !io.MouseDown[0]; + g.WantTextInputNextFrame = 1; - // Edit in progress - const float mouse_x = (io.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + edit_state.ScrollX; - const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y - style.FramePadding.y) : (g.FontSize*0.5f)); + // Edit in progress + const float mouse_x = (io.MousePos.x - frame_bb.Min.x - style.FramePadding.x) + edit_state.ScrollX; + const float mouse_y = (is_multiline ? (io.MousePos.y - draw_window->DC.CursorPos.y - style.FramePadding.y) : (g.FontSize * 0.5f)); - const bool osx_double_click_selects_words = io.OptMacOSXBehaviors; // OS X style: Double click selects by word instead of selecting whole text - if (select_all || (hovered && !osx_double_click_selects_words && io.MouseDoubleClicked[0])) - { - edit_state.SelectAll(); - edit_state.SelectedAllMouseLock = true; - } - else if (hovered && osx_double_click_selects_words && io.MouseDoubleClicked[0]) - { - // Select a word only, OS X style (by simulating keystrokes) - edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT); - edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT); - } - else if (io.MouseClicked[0] && !edit_state.SelectedAllMouseLock) - { - if (hovered) - { - stb_textedit_click(&edit_state, &edit_state.StbState, mouse_x, mouse_y); - edit_state.CursorAnimReset(); - } - } - else if (io.MouseDown[0] && !edit_state.SelectedAllMouseLock && (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f)) - { - stb_textedit_drag(&edit_state, &edit_state.StbState, mouse_x, mouse_y); - edit_state.CursorAnimReset(); - edit_state.CursorFollow = true; - } - if (edit_state.SelectedAllMouseLock && !io.MouseDown[0]) - edit_state.SelectedAllMouseLock = false; + const bool osx_double_click_selects_words = io.OptMacOSXBehaviors; // OS X style: Double click selects by word instead of selecting whole text + if (select_all || (hovered && !osx_double_click_selects_words && io.MouseDoubleClicked[0])) + { + edit_state.SelectAll(); + edit_state.SelectedAllMouseLock = true; + } + else if (hovered && osx_double_click_selects_words && io.MouseDoubleClicked[0]) + { + // Select a word only, OS X style (by simulating keystrokes) + edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT); + edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT); + } + else if (io.MouseClicked[0] && !edit_state.SelectedAllMouseLock) + { + if (hovered) + { + stb_textedit_click(&edit_state, &edit_state.StbState, mouse_x, mouse_y); + edit_state.CursorAnimReset(); + } + } + else if (io.MouseDown[0] && !edit_state.SelectedAllMouseLock && (io.MouseDelta.x != 0.0f || io.MouseDelta.y != 0.0f)) + { + stb_textedit_drag(&edit_state, &edit_state.StbState, mouse_x, mouse_y); + edit_state.CursorAnimReset(); + edit_state.CursorFollow = true; + } + if (edit_state.SelectedAllMouseLock && !io.MouseDown[0]) + edit_state.SelectedAllMouseLock = false; - if (io.InputCharacters[0]) - { - // Process text input (before we check for Return because using some IME will effectively send a Return?) - // We ignore CTRL inputs, but need to allow CTRL+ALT as some keyboards (e.g. German) use AltGR - which is Alt+Ctrl - to input certain characters. - if (!(io.KeyCtrl && !io.KeyAlt) && is_editable) - { - for (int n = 0; n < IM_ARRAYSIZE(io.InputCharacters) && io.InputCharacters[n]; n++) - if (unsigned int c = (unsigned int)io.InputCharacters[n]) - { - // Insert character if they pass filtering - if (!InputTextFilterCharacter(&c, flags, callback, user_data)) - continue; - edit_state.OnKeyPressed((int)c); - } - } + if (io.InputCharacters[0]) + { + // Process text input (before we check for Return because using some IME will effectively send a Return?) + // We ignore CTRL inputs, but need to allow CTRL+ALT as some keyboards (e.g. German) use AltGR - which is Alt+Ctrl - to input certain characters. + if (!(io.KeyCtrl && !io.KeyAlt) && is_editable) + { + for (int n = 0; n < IM_ARRAYSIZE(io.InputCharacters) && io.InputCharacters[n]; n++) + if (unsigned int c = (unsigned int)io.InputCharacters[n]) + { + // Insert character if they pass filtering + if (!InputTextFilterCharacter(&c, flags, callback, user_data)) + continue; + edit_state.OnKeyPressed((int)c); + } + } - // Consume characters - memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters)); - } - } + // Consume characters + memset(g.IO.InputCharacters, 0, sizeof(g.IO.InputCharacters)); + } + } - bool cancel_edit = false; - if (g.ActiveId == id && !g.ActiveIdIsJustActivated && !clear_active_id) - { - // Handle key-presses - const int k_mask = (io.KeyShift ? STB_TEXTEDIT_K_SHIFT : 0); - const bool is_shortcut_key_only = (io.OptMacOSXBehaviors ? (io.KeySuper && !io.KeyCtrl) : (io.KeyCtrl && !io.KeySuper)) && !io.KeyAlt && !io.KeyShift; // OS X style: Shortcuts using Cmd/Super instead of Ctrl - const bool is_wordmove_key_down = io.OptMacOSXBehaviors ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl - const bool is_startend_key_down = io.OptMacOSXBehaviors && io.KeySuper && !io.KeyCtrl && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End - const bool is_ctrl_key_only = io.KeyCtrl && !io.KeyShift && !io.KeyAlt && !io.KeySuper; - const bool is_shift_key_only = io.KeyShift && !io.KeyCtrl && !io.KeyAlt && !io.KeySuper; + bool cancel_edit = false; + if (g.ActiveId == id && !g.ActiveIdIsJustActivated && !clear_active_id) + { + // Handle key-presses + const int k_mask = (io.KeyShift ? STB_TEXTEDIT_K_SHIFT : 0); + const bool is_shortcut_key_only = (io.OptMacOSXBehaviors ? (io.KeySuper && !io.KeyCtrl) : (io.KeyCtrl && !io.KeySuper)) && !io.KeyAlt && !io.KeyShift; // OS X style: Shortcuts using Cmd/Super instead of Ctrl + const bool is_wordmove_key_down = io.OptMacOSXBehaviors ? io.KeyAlt : io.KeyCtrl; // OS X style: Text editing cursor movement using Alt instead of Ctrl + const bool is_startend_key_down = io.OptMacOSXBehaviors && io.KeySuper && !io.KeyCtrl && !io.KeyAlt; // OS X style: Line/Text Start and End using Cmd+Arrows instead of Home/End + const bool is_ctrl_key_only = io.KeyCtrl && !io.KeyShift && !io.KeyAlt && !io.KeySuper; + const bool is_shift_key_only = io.KeyShift && !io.KeyCtrl && !io.KeyAlt && !io.KeySuper; - const bool is_cut = ((is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_X)) || (is_shift_key_only && IsKeyPressedMap(ImGuiKey_Delete))) && is_editable && !is_password && (!is_multiline || edit_state.HasSelection()); - const bool is_copy = ((is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_C)) || (is_ctrl_key_only && IsKeyPressedMap(ImGuiKey_Insert))) && !is_password && (!is_multiline || edit_state.HasSelection()); - const bool is_paste = ((is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_V)) || (is_shift_key_only && IsKeyPressedMap(ImGuiKey_Insert))) && is_editable; + const bool is_cut = ((is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_X)) || (is_shift_key_only && IsKeyPressedMap(ImGuiKey_Delete))) && is_editable && !is_password && (!is_multiline || edit_state.HasSelection()); + const bool is_copy = ((is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_C)) || (is_ctrl_key_only && IsKeyPressedMap(ImGuiKey_Insert))) && !is_password && (!is_multiline || edit_state.HasSelection()); + const bool is_paste = ((is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_V)) || (is_shift_key_only && IsKeyPressedMap(ImGuiKey_Insert))) && is_editable; - if (IsKeyPressedMap(ImGuiKey_LeftArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_RightArrow)) { edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_UpArrow) && is_multiline) { if (io.KeyCtrl) SetWindowScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); else edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_DownArrow) && is_multiline) { if (io.KeyCtrl) SetWindowScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); else edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_Home)) { edit_state.OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_End)) { edit_state.OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_Delete) && is_editable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); } - else if (IsKeyPressedMap(ImGuiKey_Backspace) && is_editable) - { - if (!edit_state.HasSelection()) - { - if (is_wordmove_key_down) edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT|STB_TEXTEDIT_K_SHIFT); - else if (io.OptMacOSXBehaviors && io.KeySuper && !io.KeyAlt && !io.KeyCtrl) edit_state.OnKeyPressed(STB_TEXTEDIT_K_LINESTART|STB_TEXTEDIT_K_SHIFT); - } - edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); - } - else if (IsKeyPressedMap(ImGuiKey_Enter)) - { - bool ctrl_enter_for_new_line = (flags & ImGuiInputTextFlags_CtrlEnterForNewLine) != 0; - if (!is_multiline || (ctrl_enter_for_new_line && !io.KeyCtrl) || (!ctrl_enter_for_new_line && io.KeyCtrl)) - { - enter_pressed = clear_active_id = true; - } - else if (is_editable) - { - unsigned int c = '\n'; // Insert new line - if (InputTextFilterCharacter(&c, flags, callback, user_data)) - edit_state.OnKeyPressed((int)c); - } - } - else if ((flags & ImGuiInputTextFlags_AllowTabInput) && IsKeyPressedMap(ImGuiKey_Tab) && !io.KeyCtrl && !io.KeyShift && !io.KeyAlt && is_editable) - { - unsigned int c = '\t'; // Insert TAB - if (InputTextFilterCharacter(&c, flags, callback, user_data)) - edit_state.OnKeyPressed((int)c); - } - else if (IsKeyPressedMap(ImGuiKey_Escape)) { clear_active_id = cancel_edit = true; } - else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Z) && is_editable && is_undoable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); edit_state.ClearSelection(); } - else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Y) && is_editable && is_undoable) { edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); edit_state.ClearSelection(); } - else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_A)) { edit_state.SelectAll(); edit_state.CursorFollow = true; } - else if (is_cut || is_copy) - { - // Cut, Copy - if (io.SetClipboardTextFn) - { - const int ib = edit_state.HasSelection() ? ImMin(edit_state.StbState.select_start, edit_state.StbState.select_end) : 0; - const int ie = edit_state.HasSelection() ? ImMax(edit_state.StbState.select_start, edit_state.StbState.select_end) : edit_state.CurLenW; - edit_state.TempTextBuffer.resize((ie-ib) * 4 + 1); - ImTextStrToUtf8(edit_state.TempTextBuffer.Data, edit_state.TempTextBuffer.Size, edit_state.Text.Data+ib, edit_state.Text.Data+ie); - SetClipboardText(edit_state.TempTextBuffer.Data); - } + if (IsKeyPressedMap(ImGuiKey_LeftArrow)) + { + edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINESTART : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDLEFT : STB_TEXTEDIT_K_LEFT) | k_mask); + } + else if (IsKeyPressedMap(ImGuiKey_RightArrow)) + { + edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_LINEEND : is_wordmove_key_down ? STB_TEXTEDIT_K_WORDRIGHT : STB_TEXTEDIT_K_RIGHT) | k_mask); + } + else if (IsKeyPressedMap(ImGuiKey_UpArrow) && is_multiline) + { + if (io.KeyCtrl) + SetWindowScrollY(draw_window, ImMax(draw_window->Scroll.y - g.FontSize, 0.0f)); + else + edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTSTART : STB_TEXTEDIT_K_UP) | k_mask); + } + else if (IsKeyPressedMap(ImGuiKey_DownArrow) && is_multiline) + { + if (io.KeyCtrl) + SetWindowScrollY(draw_window, ImMin(draw_window->Scroll.y + g.FontSize, GetScrollMaxY())); + else + edit_state.OnKeyPressed((is_startend_key_down ? STB_TEXTEDIT_K_TEXTEND : STB_TEXTEDIT_K_DOWN) | k_mask); + } + else if (IsKeyPressedMap(ImGuiKey_Home)) + { + edit_state.OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTSTART | k_mask : STB_TEXTEDIT_K_LINESTART | k_mask); + } + else if (IsKeyPressedMap(ImGuiKey_End)) + { + edit_state.OnKeyPressed(io.KeyCtrl ? STB_TEXTEDIT_K_TEXTEND | k_mask : STB_TEXTEDIT_K_LINEEND | k_mask); + } + else if (IsKeyPressedMap(ImGuiKey_Delete) && is_editable) + { + edit_state.OnKeyPressed(STB_TEXTEDIT_K_DELETE | k_mask); + } + else if (IsKeyPressedMap(ImGuiKey_Backspace) && is_editable) + { + if (!edit_state.HasSelection()) + { + if (is_wordmove_key_down) + edit_state.OnKeyPressed(STB_TEXTEDIT_K_WORDLEFT | STB_TEXTEDIT_K_SHIFT); + else if (io.OptMacOSXBehaviors && io.KeySuper && !io.KeyAlt && !io.KeyCtrl) + edit_state.OnKeyPressed(STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT); + } + edit_state.OnKeyPressed(STB_TEXTEDIT_K_BACKSPACE | k_mask); + } + else if (IsKeyPressedMap(ImGuiKey_Enter)) + { + bool ctrl_enter_for_new_line = (flags & ImGuiInputTextFlags_CtrlEnterForNewLine) != 0; + if (!is_multiline || (ctrl_enter_for_new_line && !io.KeyCtrl) || (!ctrl_enter_for_new_line && io.KeyCtrl)) + { + enter_pressed = clear_active_id = true; + } + else if (is_editable) + { + unsigned int c = '\n'; // Insert new line + if (InputTextFilterCharacter(&c, flags, callback, user_data)) + edit_state.OnKeyPressed((int)c); + } + } + else if ((flags & ImGuiInputTextFlags_AllowTabInput) && IsKeyPressedMap(ImGuiKey_Tab) && !io.KeyCtrl && !io.KeyShift && !io.KeyAlt && is_editable) + { + unsigned int c = '\t'; // Insert TAB + if (InputTextFilterCharacter(&c, flags, callback, user_data)) + edit_state.OnKeyPressed((int)c); + } + else if (IsKeyPressedMap(ImGuiKey_Escape)) + { + clear_active_id = cancel_edit = true; + } + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Z) && is_editable && is_undoable) + { + edit_state.OnKeyPressed(STB_TEXTEDIT_K_UNDO); + edit_state.ClearSelection(); + } + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_Y) && is_editable && is_undoable) + { + edit_state.OnKeyPressed(STB_TEXTEDIT_K_REDO); + edit_state.ClearSelection(); + } + else if (is_shortcut_key_only && IsKeyPressedMap(ImGuiKey_A)) + { + edit_state.SelectAll(); + edit_state.CursorFollow = true; + } + else if (is_cut || is_copy) + { + // Cut, Copy + if (io.SetClipboardTextFn) + { + const int ib = edit_state.HasSelection() ? ImMin(edit_state.StbState.select_start, edit_state.StbState.select_end) : 0; + const int ie = edit_state.HasSelection() ? ImMax(edit_state.StbState.select_start, edit_state.StbState.select_end) : edit_state.CurLenW; + edit_state.TempTextBuffer.resize((ie - ib) * 4 + 1); + ImTextStrToUtf8(edit_state.TempTextBuffer.Data, edit_state.TempTextBuffer.Size, edit_state.Text.Data + ib, edit_state.Text.Data + ie); + SetClipboardText(edit_state.TempTextBuffer.Data); + } - if (is_cut) - { - if (!edit_state.HasSelection()) - edit_state.SelectAll(); - edit_state.CursorFollow = true; - stb_textedit_cut(&edit_state, &edit_state.StbState); - } - } - else if (is_paste) - { - // Paste - if (const char* clipboard = GetClipboardText()) - { - // Filter pasted buffer - const int clipboard_len = (int)strlen(clipboard); - ImWchar* clipboard_filtered = (ImWchar*)ImGui::MemAlloc((clipboard_len+1) * sizeof(ImWchar)); - int clipboard_filtered_len = 0; - for (const char* s = clipboard; *s; ) - { - unsigned int c; - s += ImTextCharFromUtf8(&c, s, NULL); - if (c == 0) - break; - if (c >= 0x10000 || !InputTextFilterCharacter(&c, flags, callback, user_data)) - continue; - clipboard_filtered[clipboard_filtered_len++] = (ImWchar)c; - } - clipboard_filtered[clipboard_filtered_len] = 0; - if (clipboard_filtered_len > 0) // If everything was filtered, ignore the pasting operation - { - stb_textedit_paste(&edit_state, &edit_state.StbState, clipboard_filtered, clipboard_filtered_len); - edit_state.CursorFollow = true; - } - ImGui::MemFree(clipboard_filtered); - } - } - } + if (is_cut) + { + if (!edit_state.HasSelection()) + edit_state.SelectAll(); + edit_state.CursorFollow = true; + stb_textedit_cut(&edit_state, &edit_state.StbState); + } + } + else if (is_paste) + { + // Paste + if (const char* clipboard = GetClipboardText()) + { + // Filter pasted buffer + const int clipboard_len = (int)strlen(clipboard); + ImWchar* clipboard_filtered = (ImWchar*)ImGui::MemAlloc((clipboard_len + 1) * sizeof(ImWchar)); + int clipboard_filtered_len = 0; + for (const char* s = clipboard; *s;) + { + unsigned int c; + s += ImTextCharFromUtf8(&c, s, NULL); + if (c == 0) + break; + if (c >= 0x10000 || !InputTextFilterCharacter(&c, flags, callback, user_data)) + continue; + clipboard_filtered[clipboard_filtered_len++] = (ImWchar)c; + } + clipboard_filtered[clipboard_filtered_len] = 0; + if (clipboard_filtered_len > 0) // If everything was filtered, ignore the pasting operation + { + stb_textedit_paste(&edit_state, &edit_state.StbState, clipboard_filtered, clipboard_filtered_len); + edit_state.CursorFollow = true; + } + ImGui::MemFree(clipboard_filtered); + } + } + } - if (g.ActiveId == id) - { - if (cancel_edit) - { - // Restore initial value - if (is_editable) - { - ImStrncpy(buf, edit_state.InitialText.Data, buf_size); - value_changed = true; - } - } + if (g.ActiveId == id) + { + if (cancel_edit) + { + // Restore initial value + if (is_editable) + { + ImStrncpy(buf, edit_state.InitialText.Data, buf_size); + value_changed = true; + } + } - // When using 'ImGuiInputTextFlags_EnterReturnsTrue' as a special case we reapply the live buffer back to the input buffer before clearing ActiveId, even though strictly speaking it wasn't modified on this frame. - // If we didn't do that, code like InputInt() with ImGuiInputTextFlags_EnterReturnsTrue would fail. Also this allows the user to use InputText() with ImGuiInputTextFlags_EnterReturnsTrue without maintaining any user-side storage. - bool apply_edit_back_to_user_buffer = !cancel_edit || (enter_pressed && (flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0); - if (apply_edit_back_to_user_buffer) - { - // Apply new value immediately - copy modified buffer back - // Note that as soon as the input box is active, the in-widget value gets priority over any underlying modification of the input buffer - // FIXME: We actually always render 'buf' when calling DrawList->AddText, making the comment above incorrect. - // FIXME-OPT: CPU waste to do this every time the widget is active, should mark dirty state from the stb_textedit callbacks. - if (is_editable) - { - edit_state.TempTextBuffer.resize(edit_state.Text.Size * 4); - ImTextStrToUtf8(edit_state.TempTextBuffer.Data, edit_state.TempTextBuffer.Size, edit_state.Text.Data, NULL); - } + // When using 'ImGuiInputTextFlags_EnterReturnsTrue' as a special case we reapply the live buffer back to the input buffer before clearing ActiveId, even though strictly speaking it wasn't modified on this frame. + // If we didn't do that, code like InputInt() with ImGuiInputTextFlags_EnterReturnsTrue would fail. Also this allows the user to use InputText() with ImGuiInputTextFlags_EnterReturnsTrue without maintaining any user-side storage. + bool apply_edit_back_to_user_buffer = !cancel_edit || (enter_pressed && (flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0); + if (apply_edit_back_to_user_buffer) + { + // Apply new value immediately - copy modified buffer back + // Note that as soon as the input box is active, the in-widget value gets priority over any underlying modification of the input buffer + // FIXME: We actually always render 'buf' when calling DrawList->AddText, making the comment above incorrect. + // FIXME-OPT: CPU waste to do this every time the widget is active, should mark dirty state from the stb_textedit callbacks. + if (is_editable) + { + edit_state.TempTextBuffer.resize(edit_state.Text.Size * 4); + ImTextStrToUtf8(edit_state.TempTextBuffer.Data, edit_state.TempTextBuffer.Size, edit_state.Text.Data, NULL); + } - // User callback - if ((flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory | ImGuiInputTextFlags_CallbackAlways)) != 0) - { - IM_ASSERT(callback != NULL); + // User callback + if ((flags & (ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory | ImGuiInputTextFlags_CallbackAlways)) != 0) + { + IM_ASSERT(callback != NULL); - // The reason we specify the usage semantic (Completion/History) is that Completion needs to disable keyboard TABBING at the moment. - ImGuiInputTextFlags event_flag = 0; - ImGuiKey event_key = ImGuiKey_COUNT; - if ((flags & ImGuiInputTextFlags_CallbackCompletion) != 0 && IsKeyPressedMap(ImGuiKey_Tab)) - { - event_flag = ImGuiInputTextFlags_CallbackCompletion; - event_key = ImGuiKey_Tab; - } - else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressedMap(ImGuiKey_UpArrow)) - { - event_flag = ImGuiInputTextFlags_CallbackHistory; - event_key = ImGuiKey_UpArrow; - } - else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressedMap(ImGuiKey_DownArrow)) - { - event_flag = ImGuiInputTextFlags_CallbackHistory; - event_key = ImGuiKey_DownArrow; - } - else if (flags & ImGuiInputTextFlags_CallbackAlways) - event_flag = ImGuiInputTextFlags_CallbackAlways; + // The reason we specify the usage semantic (Completion/History) is that Completion needs to disable keyboard TABBING at the moment. + ImGuiInputTextFlags event_flag = 0; + ImGuiKey event_key = ImGuiKey_COUNT; + if ((flags & ImGuiInputTextFlags_CallbackCompletion) != 0 && IsKeyPressedMap(ImGuiKey_Tab)) + { + event_flag = ImGuiInputTextFlags_CallbackCompletion; + event_key = ImGuiKey_Tab; + } + else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressedMap(ImGuiKey_UpArrow)) + { + event_flag = ImGuiInputTextFlags_CallbackHistory; + event_key = ImGuiKey_UpArrow; + } + else if ((flags & ImGuiInputTextFlags_CallbackHistory) != 0 && IsKeyPressedMap(ImGuiKey_DownArrow)) + { + event_flag = ImGuiInputTextFlags_CallbackHistory; + event_key = ImGuiKey_DownArrow; + } + else if (flags & ImGuiInputTextFlags_CallbackAlways) + event_flag = ImGuiInputTextFlags_CallbackAlways; - if (event_flag) - { - ImGuiTextEditCallbackData callback_data; - memset(&callback_data, 0, sizeof(ImGuiTextEditCallbackData)); - callback_data.EventFlag = event_flag; - callback_data.Flags = flags; - callback_data.UserData = user_data; - callback_data.ReadOnly = !is_editable; + if (event_flag) + { + ImGuiTextEditCallbackData callback_data; + memset(&callback_data, 0, sizeof(ImGuiTextEditCallbackData)); + callback_data.EventFlag = event_flag; + callback_data.Flags = flags; + callback_data.UserData = user_data; + callback_data.ReadOnly = !is_editable; - callback_data.EventKey = event_key; - callback_data.Buf = edit_state.TempTextBuffer.Data; - callback_data.BufTextLen = edit_state.CurLenA; - callback_data.BufSize = edit_state.BufSizeA; - callback_data.BufDirty = false; + callback_data.EventKey = event_key; + callback_data.Buf = edit_state.TempTextBuffer.Data; + callback_data.BufTextLen = edit_state.CurLenA; + callback_data.BufSize = edit_state.BufSizeA; + callback_data.BufDirty = false; - // We have to convert from wchar-positions to UTF-8-positions, which can be pretty slow (an incentive to ditch the ImWchar buffer, see https://github.com/nothings/stb/issues/188) - ImWchar* text = edit_state.Text.Data; - const int utf8_cursor_pos = callback_data.CursorPos = ImTextCountUtf8BytesFromStr(text, text + edit_state.StbState.cursor); - const int utf8_selection_start = callback_data.SelectionStart = ImTextCountUtf8BytesFromStr(text, text + edit_state.StbState.select_start); - const int utf8_selection_end = callback_data.SelectionEnd = ImTextCountUtf8BytesFromStr(text, text + edit_state.StbState.select_end); + // We have to convert from wchar-positions to UTF-8-positions, which can be pretty slow (an incentive to ditch the ImWchar buffer, see https://github.com/nothings/stb/issues/188) + ImWchar* text = edit_state.Text.Data; + const int utf8_cursor_pos = callback_data.CursorPos = ImTextCountUtf8BytesFromStr(text, text + edit_state.StbState.cursor); + const int utf8_selection_start = callback_data.SelectionStart = ImTextCountUtf8BytesFromStr(text, text + edit_state.StbState.select_start); + const int utf8_selection_end = callback_data.SelectionEnd = ImTextCountUtf8BytesFromStr(text, text + edit_state.StbState.select_end); - // Call user code - callback(&callback_data); + // Call user code + callback(&callback_data); - // Read back what user may have modified - IM_ASSERT(callback_data.Buf == edit_state.TempTextBuffer.Data); // Invalid to modify those fields - IM_ASSERT(callback_data.BufSize == edit_state.BufSizeA); - IM_ASSERT(callback_data.Flags == flags); - if (callback_data.CursorPos != utf8_cursor_pos) edit_state.StbState.cursor = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.CursorPos); - if (callback_data.SelectionStart != utf8_selection_start) edit_state.StbState.select_start = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionStart); - if (callback_data.SelectionEnd != utf8_selection_end) edit_state.StbState.select_end = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionEnd); - if (callback_data.BufDirty) - { - IM_ASSERT(callback_data.BufTextLen == (int)strlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text! - edit_state.CurLenW = ImTextStrFromUtf8(edit_state.Text.Data, edit_state.Text.Size, callback_data.Buf, NULL); - edit_state.CurLenA = callback_data.BufTextLen; // Assume correct length and valid UTF-8 from user, saves us an extra strlen() - edit_state.CursorAnimReset(); - } - } - } + // Read back what user may have modified + IM_ASSERT(callback_data.Buf == edit_state.TempTextBuffer.Data); // Invalid to modify those fields + IM_ASSERT(callback_data.BufSize == edit_state.BufSizeA); + IM_ASSERT(callback_data.Flags == flags); + if (callback_data.CursorPos != utf8_cursor_pos) edit_state.StbState.cursor = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.CursorPos); + if (callback_data.SelectionStart != utf8_selection_start) edit_state.StbState.select_start = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionStart); + if (callback_data.SelectionEnd != utf8_selection_end) edit_state.StbState.select_end = ImTextCountCharsFromUtf8(callback_data.Buf, callback_data.Buf + callback_data.SelectionEnd); + if (callback_data.BufDirty) + { + IM_ASSERT(callback_data.BufTextLen == (int)strlen(callback_data.Buf)); // You need to maintain BufTextLen if you change the text! + edit_state.CurLenW = ImTextStrFromUtf8(edit_state.Text.Data, edit_state.Text.Size, callback_data.Buf, NULL); + edit_state.CurLenA = callback_data.BufTextLen; // Assume correct length and valid UTF-8 from user, saves us an extra strlen() + edit_state.CursorAnimReset(); + } + } + } - // Copy back to user buffer - if (is_editable && strcmp(edit_state.TempTextBuffer.Data, buf) != 0) - { - ImStrncpy(buf, edit_state.TempTextBuffer.Data, buf_size); - value_changed = true; - } - } - } + // Copy back to user buffer + if (is_editable && strcmp(edit_state.TempTextBuffer.Data, buf) != 0) + { + ImStrncpy(buf, edit_state.TempTextBuffer.Data, buf_size); + value_changed = true; + } + } + } - // Release active ID at the end of the function (so e.g. pressing Return still does a final application of the value) - if (clear_active_id && g.ActiveId == id) - ClearActiveID(); + // Release active ID at the end of the function (so e.g. pressing Return still does a final application of the value) + if (clear_active_id && g.ActiveId == id) + ClearActiveID(); - // Render - // Select which buffer we are going to display. When ImGuiInputTextFlags_NoLiveEdit is set 'buf' might still be the old value. We set buf to NULL to prevent accidental usage from now on. - const char* buf_display = (g.ActiveId == id && is_editable) ? edit_state.TempTextBuffer.Data : buf; buf = NULL; + // Render + // Select which buffer we are going to display. When ImGuiInputTextFlags_NoLiveEdit is set 'buf' might still be the old value. We set buf to NULL to prevent accidental usage from now on. + const char* buf_display = (g.ActiveId == id && is_editable) ? edit_state.TempTextBuffer.Data : buf; + buf = NULL; - RenderNavHighlight(frame_bb, id); - if (!is_multiline) - RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); + RenderNavHighlight(frame_bb, id); + if (!is_multiline) + RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); - const ImVec4 clip_rect(frame_bb.Min.x, frame_bb.Min.y, frame_bb.Min.x + size.x, frame_bb.Min.y + size.y); // Not using frame_bb.Max because we have adjusted size - ImVec2 render_pos = is_multiline ? draw_window->DC.CursorPos : frame_bb.Min + style.FramePadding; - ImVec2 text_size(0.f, 0.f); - const bool is_currently_scrolling = (edit_state.Id == id && is_multiline && g.ActiveId == draw_window->GetIDNoKeepAlive("#SCROLLY")); - if (g.ActiveId == id || is_currently_scrolling) - { - edit_state.CursorAnim += io.DeltaTime; + const ImVec4 clip_rect(frame_bb.Min.x, frame_bb.Min.y, frame_bb.Min.x + size.x, frame_bb.Min.y + size.y); // Not using frame_bb.Max because we have adjusted size + ImVec2 render_pos = is_multiline ? draw_window->DC.CursorPos : frame_bb.Min + style.FramePadding; + ImVec2 text_size(0.f, 0.f); + const bool is_currently_scrolling = (edit_state.Id == id && is_multiline && g.ActiveId == draw_window->GetIDNoKeepAlive("#SCROLLY")); + if (g.ActiveId == id || is_currently_scrolling) + { + edit_state.CursorAnim += io.DeltaTime; - // This is going to be messy. We need to: - // - Display the text (this alone can be more easily clipped) - // - Handle scrolling, highlight selection, display cursor (those all requires some form of 1d->2d cursor position calculation) - // - Measure text height (for scrollbar) - // We are attempting to do most of that in **one main pass** to minimize the computation cost (non-negligible for large amount of text) + 2nd pass for selection rendering (we could merge them by an extra refactoring effort) - // FIXME: This should occur on buf_display but we'd need to maintain cursor/select_start/select_end for UTF-8. - const ImWchar* text_begin = edit_state.Text.Data; - ImVec2 cursor_offset, select_start_offset; + // This is going to be messy. We need to: + // - Display the text (this alone can be more easily clipped) + // - Handle scrolling, highlight selection, display cursor (those all requires some form of 1d->2d cursor position calculation) + // - Measure text height (for scrollbar) + // We are attempting to do most of that in **one main pass** to minimize the computation cost (non-negligible for large amount of text) + 2nd pass for selection rendering (we could merge them by an extra refactoring effort) + // FIXME: This should occur on buf_display but we'd need to maintain cursor/select_start/select_end for UTF-8. + const ImWchar* text_begin = edit_state.Text.Data; + ImVec2 cursor_offset, select_start_offset; - { - // Count lines + find lines numbers straddling 'cursor' and 'select_start' position. - const ImWchar* searches_input_ptr[2]; - searches_input_ptr[0] = text_begin + edit_state.StbState.cursor; - searches_input_ptr[1] = NULL; - int searches_remaining = 1; - int searches_result_line_number[2] = { -1, -999 }; - if (edit_state.StbState.select_start != edit_state.StbState.select_end) - { - searches_input_ptr[1] = text_begin + ImMin(edit_state.StbState.select_start, edit_state.StbState.select_end); - searches_result_line_number[1] = -1; - searches_remaining++; - } + { + // Count lines + find lines numbers straddling 'cursor' and 'select_start' position. + const ImWchar* searches_input_ptr[2]; + searches_input_ptr[0] = text_begin + edit_state.StbState.cursor; + searches_input_ptr[1] = NULL; + int searches_remaining = 1; + int searches_result_line_number[2] = {-1, -999}; + if (edit_state.StbState.select_start != edit_state.StbState.select_end) + { + searches_input_ptr[1] = text_begin + ImMin(edit_state.StbState.select_start, edit_state.StbState.select_end); + searches_result_line_number[1] = -1; + searches_remaining++; + } - // Iterate all lines to find our line numbers - // In multi-line mode, we never exit the loop until all lines are counted, so add one extra to the searches_remaining counter. - searches_remaining += is_multiline ? 1 : 0; - int line_count = 0; - for (const ImWchar* s = text_begin; *s != 0; s++) - if (*s == '\n') - { - line_count++; - if (searches_result_line_number[0] == -1 && s >= searches_input_ptr[0]) { searches_result_line_number[0] = line_count; if (--searches_remaining <= 0) break; } - if (searches_result_line_number[1] == -1 && s >= searches_input_ptr[1]) { searches_result_line_number[1] = line_count; if (--searches_remaining <= 0) break; } - } - line_count++; - if (searches_result_line_number[0] == -1) searches_result_line_number[0] = line_count; - if (searches_result_line_number[1] == -1) searches_result_line_number[1] = line_count; + // Iterate all lines to find our line numbers + // In multi-line mode, we never exit the loop until all lines are counted, so add one extra to the searches_remaining counter. + searches_remaining += is_multiline ? 1 : 0; + int line_count = 0; + for (const ImWchar* s = text_begin; *s != 0; s++) + if (*s == '\n') + { + line_count++; + if (searches_result_line_number[0] == -1 && s >= searches_input_ptr[0]) + { + searches_result_line_number[0] = line_count; + if (--searches_remaining <= 0) break; + } + if (searches_result_line_number[1] == -1 && s >= searches_input_ptr[1]) + { + searches_result_line_number[1] = line_count; + if (--searches_remaining <= 0) break; + } + } + line_count++; + if (searches_result_line_number[0] == -1) searches_result_line_number[0] = line_count; + if (searches_result_line_number[1] == -1) searches_result_line_number[1] = line_count; - // Calculate 2d position by finding the beginning of the line and measuring distance - cursor_offset.x = InputTextCalcTextSizeW(ImStrbolW(searches_input_ptr[0], text_begin), searches_input_ptr[0]).x; - cursor_offset.y = searches_result_line_number[0] * g.FontSize; - if (searches_result_line_number[1] >= 0) - { - select_start_offset.x = InputTextCalcTextSizeW(ImStrbolW(searches_input_ptr[1], text_begin), searches_input_ptr[1]).x; - select_start_offset.y = searches_result_line_number[1] * g.FontSize; - } + // Calculate 2d position by finding the beginning of the line and measuring distance + cursor_offset.x = InputTextCalcTextSizeW(ImStrbolW(searches_input_ptr[0], text_begin), searches_input_ptr[0]).x; + cursor_offset.y = searches_result_line_number[0] * g.FontSize; + if (searches_result_line_number[1] >= 0) + { + select_start_offset.x = InputTextCalcTextSizeW(ImStrbolW(searches_input_ptr[1], text_begin), searches_input_ptr[1]).x; + select_start_offset.y = searches_result_line_number[1] * g.FontSize; + } - // Store text height (note that we haven't calculated text width at all, see GitHub issues #383, #1224) - if (is_multiline) - text_size = ImVec2(size.x, line_count * g.FontSize); - } + // Store text height (note that we haven't calculated text width at all, see GitHub issues #383, #1224) + if (is_multiline) + text_size = ImVec2(size.x, line_count * g.FontSize); + } - // Scroll - if (edit_state.CursorFollow) - { - // Horizontal scroll in chunks of quarter width - if (!(flags & ImGuiInputTextFlags_NoHorizontalScroll)) - { - const float scroll_increment_x = size.x * 0.25f; - if (cursor_offset.x < edit_state.ScrollX) - edit_state.ScrollX = (float)(int)ImMax(0.0f, cursor_offset.x - scroll_increment_x); - else if (cursor_offset.x - size.x >= edit_state.ScrollX) - edit_state.ScrollX = (float)(int)(cursor_offset.x - size.x + scroll_increment_x); - } - else - { - edit_state.ScrollX = 0.0f; - } + // Scroll + if (edit_state.CursorFollow) + { + // Horizontal scroll in chunks of quarter width + if (!(flags & ImGuiInputTextFlags_NoHorizontalScroll)) + { + const float scroll_increment_x = size.x * 0.25f; + if (cursor_offset.x < edit_state.ScrollX) + edit_state.ScrollX = (float)(int)ImMax(0.0f, cursor_offset.x - scroll_increment_x); + else if (cursor_offset.x - size.x >= edit_state.ScrollX) + edit_state.ScrollX = (float)(int)(cursor_offset.x - size.x + scroll_increment_x); + } + else + { + edit_state.ScrollX = 0.0f; + } - // Vertical scroll - if (is_multiline) - { - float scroll_y = draw_window->Scroll.y; - if (cursor_offset.y - g.FontSize < scroll_y) - scroll_y = ImMax(0.0f, cursor_offset.y - g.FontSize); - else if (cursor_offset.y - size.y >= scroll_y) - scroll_y = cursor_offset.y - size.y; - draw_window->DC.CursorPos.y += (draw_window->Scroll.y - scroll_y); // To avoid a frame of lag - draw_window->Scroll.y = scroll_y; - render_pos.y = draw_window->DC.CursorPos.y; - } - } - edit_state.CursorFollow = false; - const ImVec2 render_scroll = ImVec2(edit_state.ScrollX, 0.0f); + // Vertical scroll + if (is_multiline) + { + float scroll_y = draw_window->Scroll.y; + if (cursor_offset.y - g.FontSize < scroll_y) + scroll_y = ImMax(0.0f, cursor_offset.y - g.FontSize); + else if (cursor_offset.y - size.y >= scroll_y) + scroll_y = cursor_offset.y - size.y; + draw_window->DC.CursorPos.y += (draw_window->Scroll.y - scroll_y); // To avoid a frame of lag + draw_window->Scroll.y = scroll_y; + render_pos.y = draw_window->DC.CursorPos.y; + } + } + edit_state.CursorFollow = false; + const ImVec2 render_scroll = ImVec2(edit_state.ScrollX, 0.0f); - // Draw selection - if (edit_state.StbState.select_start != edit_state.StbState.select_end) - { - const ImWchar* text_selected_begin = text_begin + ImMin(edit_state.StbState.select_start, edit_state.StbState.select_end); - const ImWchar* text_selected_end = text_begin + ImMax(edit_state.StbState.select_start, edit_state.StbState.select_end); + // Draw selection + if (edit_state.StbState.select_start != edit_state.StbState.select_end) + { + const ImWchar* text_selected_begin = text_begin + ImMin(edit_state.StbState.select_start, edit_state.StbState.select_end); + const ImWchar* text_selected_end = text_begin + ImMax(edit_state.StbState.select_start, edit_state.StbState.select_end); - float bg_offy_up = is_multiline ? 0.0f : -1.0f; // FIXME: those offsets should be part of the style? they don't play so well with multi-line selection. - float bg_offy_dn = is_multiline ? 0.0f : 2.0f; - ImU32 bg_color = GetColorU32(ImGuiCol_TextSelectedBg); - ImVec2 rect_pos = render_pos + select_start_offset - render_scroll; - for (const ImWchar* p = text_selected_begin; p < text_selected_end; ) - { - if (rect_pos.y > clip_rect.w + g.FontSize) - break; - if (rect_pos.y < clip_rect.y) - { - while (p < text_selected_end) - if (*p++ == '\n') - break; - } - else - { - ImVec2 rect_size = InputTextCalcTextSizeW(p, text_selected_end, &p, NULL, true); - if (rect_size.x <= 0.0f) rect_size.x = (float)(int)(g.Font->GetCharAdvance((unsigned short)' ') * 0.50f); // So we can see selected empty lines - ImRect rect(rect_pos + ImVec2(0.0f, bg_offy_up - g.FontSize), rect_pos +ImVec2(rect_size.x, bg_offy_dn)); - rect.ClipWith(clip_rect); - if (rect.Overlaps(clip_rect)) - draw_window->DrawList->AddRectFilled(rect.Min, rect.Max, bg_color); - } - rect_pos.x = render_pos.x - render_scroll.x; - rect_pos.y += g.FontSize; - } - } + float bg_offy_up = is_multiline ? 0.0f : -1.0f; // FIXME: those offsets should be part of the style? they don't play so well with multi-line selection. + float bg_offy_dn = is_multiline ? 0.0f : 2.0f; + ImU32 bg_color = GetColorU32(ImGuiCol_TextSelectedBg); + ImVec2 rect_pos = render_pos + select_start_offset - render_scroll; + for (const ImWchar* p = text_selected_begin; p < text_selected_end;) + { + if (rect_pos.y > clip_rect.w + g.FontSize) + break; + if (rect_pos.y < clip_rect.y) + { + while (p < text_selected_end) + if (*p++ == '\n') + break; + } + else + { + ImVec2 rect_size = InputTextCalcTextSizeW(p, text_selected_end, &p, NULL, true); + if (rect_size.x <= 0.0f) rect_size.x = (float)(int)(g.Font->GetCharAdvance((unsigned short)' ') * 0.50f); // So we can see selected empty lines + ImRect rect(rect_pos + ImVec2(0.0f, bg_offy_up - g.FontSize), rect_pos + ImVec2(rect_size.x, bg_offy_dn)); + rect.ClipWith(clip_rect); + if (rect.Overlaps(clip_rect)) + draw_window->DrawList->AddRectFilled(rect.Min, rect.Max, bg_color); + } + rect_pos.x = render_pos.x - render_scroll.x; + rect_pos.y += g.FontSize; + } + } - draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos - render_scroll, GetColorU32(ImGuiCol_Text), buf_display, buf_display + edit_state.CurLenA, 0.0f, is_multiline ? NULL : &clip_rect); + draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos - render_scroll, GetColorU32(ImGuiCol_Text), buf_display, buf_display + edit_state.CurLenA, 0.0f, is_multiline ? NULL : &clip_rect); - // Draw blinking cursor - bool cursor_is_visible = (!g.IO.OptCursorBlink) || (g.InputTextState.CursorAnim <= 0.0f) || fmodf(g.InputTextState.CursorAnim, 1.20f) <= 0.80f; - ImVec2 cursor_screen_pos = render_pos + cursor_offset - render_scroll; - ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y-g.FontSize+0.5f, cursor_screen_pos.x+1.0f, cursor_screen_pos.y-1.5f); - if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect)) - draw_window->DrawList->AddLine(cursor_screen_rect.Min, cursor_screen_rect.GetBL(), GetColorU32(ImGuiCol_Text)); + // Draw blinking cursor + bool cursor_is_visible = (!g.IO.OptCursorBlink) || (g.InputTextState.CursorAnim <= 0.0f) || fmodf(g.InputTextState.CursorAnim, 1.20f) <= 0.80f; + ImVec2 cursor_screen_pos = render_pos + cursor_offset - render_scroll; + ImRect cursor_screen_rect(cursor_screen_pos.x, cursor_screen_pos.y - g.FontSize + 0.5f, cursor_screen_pos.x + 1.0f, cursor_screen_pos.y - 1.5f); + if (cursor_is_visible && cursor_screen_rect.Overlaps(clip_rect)) + draw_window->DrawList->AddLine(cursor_screen_rect.Min, cursor_screen_rect.GetBL(), GetColorU32(ImGuiCol_Text)); - // Notify OS of text input position for advanced IME (-1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.) - if (is_editable) - g.OsImePosRequest = ImVec2(cursor_screen_pos.x - 1, cursor_screen_pos.y - g.FontSize); - } - else - { - // Render text only - const char* buf_end = NULL; - if (is_multiline) - text_size = ImVec2(size.x, InputTextCalcTextLenAndLineCount(buf_display, &buf_end) * g.FontSize); // We don't need width - draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos, GetColorU32(ImGuiCol_Text), buf_display, buf_end, 0.0f, is_multiline ? NULL : &clip_rect); - } + // Notify OS of text input position for advanced IME (-1 x offset so that Windows IME can cover our cursor. Bit of an extra nicety.) + if (is_editable) + g.OsImePosRequest = ImVec2(cursor_screen_pos.x - 1, cursor_screen_pos.y - g.FontSize); + } + else + { + // Render text only + const char* buf_end = NULL; + if (is_multiline) + text_size = ImVec2(size.x, InputTextCalcTextLenAndLineCount(buf_display, &buf_end) * g.FontSize); // We don't need width + draw_window->DrawList->AddText(g.Font, g.FontSize, render_pos, GetColorU32(ImGuiCol_Text), buf_display, buf_end, 0.0f, is_multiline ? NULL : &clip_rect); + } - if (is_multiline) - { - Dummy(text_size + ImVec2(0.0f, g.FontSize)); // Always add room to scroll an extra line - EndChildFrame(); - EndGroup(); - } + if (is_multiline) + { + Dummy(text_size + ImVec2(0.0f, g.FontSize)); // Always add room to scroll an extra line + EndChildFrame(); + EndGroup(); + } - if (is_password) - PopFont(); + if (is_password) + PopFont(); - // Log as text - if (g.LogEnabled && !is_password) - LogRenderedText(&render_pos, buf_display, NULL); + // Log as text + if (g.LogEnabled && !is_password) + LogRenderedText(&render_pos, buf_display, NULL); - if (label_size.x > 0) - RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); + if (label_size.x > 0) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); - if ((flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0) - return enter_pressed; - else - return value_changed; + if ((flags & ImGuiInputTextFlags_EnterReturnsTrue) != 0) + return enter_pressed; + else + return value_changed; } bool ImGui::InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data) { - IM_ASSERT(!(flags & ImGuiInputTextFlags_Multiline)); // call InputTextMultiline() - return InputTextEx(label, buf, (int)buf_size, ImVec2(0,0), flags, callback, user_data); + IM_ASSERT(!(flags & ImGuiInputTextFlags_Multiline)); // call InputTextMultiline() + return InputTextEx(label, buf, (int)buf_size, ImVec2(0, 0), flags, callback, user_data); } bool ImGui::InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback, void* user_data) { - return InputTextEx(label, buf, (int)buf_size, size, flags | ImGuiInputTextFlags_Multiline, callback, user_data); + return InputTextEx(label, buf, (int)buf_size, size, flags | ImGuiInputTextFlags_Multiline, callback, user_data); } // NB: scalar_format here must be a simple "%xx" format string with no prefix/suffix (unlike the Drag/Slider functions "display_format" argument) bool ImGui::InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; - const ImVec2 label_size = CalcTextSize(label, NULL, true); + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImVec2 label_size = CalcTextSize(label, NULL, true); - BeginGroup(); - PushID(label); - const ImVec2 button_sz = ImVec2(GetFrameHeight(), GetFrameHeight()); - if (step_ptr) - PushItemWidth(ImMax(1.0f, CalcItemWidth() - (button_sz.x + style.ItemInnerSpacing.x)*2)); + BeginGroup(); + PushID(label); + const ImVec2 button_sz = ImVec2(GetFrameHeight(), GetFrameHeight()); + if (step_ptr) + PushItemWidth(ImMax(1.0f, CalcItemWidth() - (button_sz.x + style.ItemInnerSpacing.x) * 2)); - char buf[64]; - DataTypeFormatString(data_type, data_ptr, scalar_format, buf, IM_ARRAYSIZE(buf)); + char buf[64]; + DataTypeFormatString(data_type, data_ptr, scalar_format, buf, IM_ARRAYSIZE(buf)); - bool value_changed = false; - if (!(extra_flags & ImGuiInputTextFlags_CharsHexadecimal)) - extra_flags |= ImGuiInputTextFlags_CharsDecimal; - extra_flags |= ImGuiInputTextFlags_AutoSelectAll; - if (InputText("", buf, IM_ARRAYSIZE(buf), extra_flags)) // PushId(label) + "" gives us the expected ID from outside point of view - value_changed = DataTypeApplyOpFromText(buf, GImGui->InputTextState.InitialText.begin(), data_type, data_ptr, scalar_format); + bool value_changed = false; + if (!(extra_flags & ImGuiInputTextFlags_CharsHexadecimal)) + extra_flags |= ImGuiInputTextFlags_CharsDecimal; + extra_flags |= ImGuiInputTextFlags_AutoSelectAll; + if (InputText("", buf, IM_ARRAYSIZE(buf), extra_flags)) // PushId(label) + "" gives us the expected ID from outside point of view + value_changed = DataTypeApplyOpFromText(buf, GImGui->InputTextState.InitialText.begin(), data_type, data_ptr, scalar_format); - // Step buttons - if (step_ptr) - { - PopItemWidth(); - SameLine(0, style.ItemInnerSpacing.x); - if (ButtonEx("-", button_sz, ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups)) - { - DataTypeApplyOp(data_type, '-', data_ptr, g.IO.KeyCtrl && step_fast_ptr ? step_fast_ptr : step_ptr); - value_changed = true; - } - SameLine(0, style.ItemInnerSpacing.x); - if (ButtonEx("+", button_sz, ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups)) - { - DataTypeApplyOp(data_type, '+', data_ptr, g.IO.KeyCtrl && step_fast_ptr ? step_fast_ptr : step_ptr); - value_changed = true; - } - } - PopID(); + // Step buttons + if (step_ptr) + { + PopItemWidth(); + SameLine(0, style.ItemInnerSpacing.x); + if (ButtonEx("-", button_sz, ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups)) + { + DataTypeApplyOp(data_type, '-', data_ptr, g.IO.KeyCtrl && step_fast_ptr ? step_fast_ptr : step_ptr); + value_changed = true; + } + SameLine(0, style.ItemInnerSpacing.x); + if (ButtonEx("+", button_sz, ImGuiButtonFlags_Repeat | ImGuiButtonFlags_DontClosePopups)) + { + DataTypeApplyOp(data_type, '+', data_ptr, g.IO.KeyCtrl && step_fast_ptr ? step_fast_ptr : step_ptr); + value_changed = true; + } + } + PopID(); - if (label_size.x > 0) - { - SameLine(0, style.ItemInnerSpacing.x); - RenderText(ImVec2(window->DC.CursorPos.x, window->DC.CursorPos.y + style.FramePadding.y), label); - ItemSize(label_size, style.FramePadding.y); - } - EndGroup(); + if (label_size.x > 0) + { + SameLine(0, style.ItemInnerSpacing.x); + RenderText(ImVec2(window->DC.CursorPos.x, window->DC.CursorPos.y + style.FramePadding.y), label); + ItemSize(label_size, style.FramePadding.y); + } + EndGroup(); - return value_changed; + return value_changed; } bool ImGui::InputFloat(const char* label, float* v, float step, float step_fast, int decimal_precision, ImGuiInputTextFlags extra_flags) { - char display_format[16]; - if (decimal_precision < 0) - strcpy(display_format, "%f"); // Ideally we'd have a minimum decimal precision of 1 to visually denote that this is a float, while hiding non-significant digits? %f doesn't have a minimum of 1 - else - ImFormatString(display_format, IM_ARRAYSIZE(display_format), "%%.%df", decimal_precision); - return InputScalarEx(label, ImGuiDataType_Float, (void*)v, (void*)(step>0.0f ? &step : NULL), (void*)(step_fast>0.0f ? &step_fast : NULL), display_format, extra_flags); + char display_format[16]; + if (decimal_precision < 0) + strcpy(display_format, "%f"); // Ideally we'd have a minimum decimal precision of 1 to visually denote that this is a float, while hiding non-significant digits? %f doesn't have a minimum of 1 + else + ImFormatString(display_format, IM_ARRAYSIZE(display_format), "%%.%df", decimal_precision); + return InputScalarEx(label, ImGuiDataType_Float, (void*)v, (void*)(step > 0.0f ? &step : NULL), (void*)(step_fast > 0.0f ? &step_fast : NULL), display_format, extra_flags); } bool ImGui::InputInt(const char* label, int* v, int step, int step_fast, ImGuiInputTextFlags extra_flags) { - // Hexadecimal input provided as a convenience but the flag name is awkward. Typically you'd use InputText() to parse your own data, if you want to handle prefixes. - const char* scalar_format = (extra_flags & ImGuiInputTextFlags_CharsHexadecimal) ? "%08X" : "%d"; - return InputScalarEx(label, ImGuiDataType_Int, (void*)v, (void*)(step>0.0f ? &step : NULL), (void*)(step_fast>0.0f ? &step_fast : NULL), scalar_format, extra_flags); + // Hexadecimal input provided as a convenience but the flag name is awkward. Typically you'd use InputText() to parse your own data, if you want to handle prefixes. + const char* scalar_format = (extra_flags & ImGuiInputTextFlags_CharsHexadecimal) ? "%08X" : "%d"; + return InputScalarEx(label, ImGuiDataType_Int, (void*)v, (void*)(step > 0.0f ? &step : NULL), (void*)(step_fast > 0.0f ? &step_fast : NULL), scalar_format, extra_flags); } bool ImGui::InputFloatN(const char* label, float* v, int components, int decimal_precision, ImGuiInputTextFlags extra_flags) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - bool value_changed = false; - BeginGroup(); - PushID(label); - PushMultiItemsWidths(components); - for (int i = 0; i < components; i++) - { - PushID(i); - value_changed |= InputFloat("##v", &v[i], 0, 0, decimal_precision, extra_flags); - SameLine(0, g.Style.ItemInnerSpacing.x); - PopID(); - PopItemWidth(); - } - PopID(); + ImGuiContext& g = *GImGui; + bool value_changed = false; + BeginGroup(); + PushID(label); + PushMultiItemsWidths(components); + for (int i = 0; i < components; i++) + { + PushID(i); + value_changed |= InputFloat("##v", &v[i], 0, 0, decimal_precision, extra_flags); + SameLine(0, g.Style.ItemInnerSpacing.x); + PopID(); + PopItemWidth(); + } + PopID(); - TextUnformatted(label, FindRenderedTextEnd(label)); - EndGroup(); + TextUnformatted(label, FindRenderedTextEnd(label)); + EndGroup(); - return value_changed; + return value_changed; } bool ImGui::InputFloat2(const char* label, float v[2], int decimal_precision, ImGuiInputTextFlags extra_flags) { - return InputFloatN(label, v, 2, decimal_precision, extra_flags); + return InputFloatN(label, v, 2, decimal_precision, extra_flags); } bool ImGui::InputFloat3(const char* label, float v[3], int decimal_precision, ImGuiInputTextFlags extra_flags) { - return InputFloatN(label, v, 3, decimal_precision, extra_flags); + return InputFloatN(label, v, 3, decimal_precision, extra_flags); } bool ImGui::InputFloat4(const char* label, float v[4], int decimal_precision, ImGuiInputTextFlags extra_flags) { - return InputFloatN(label, v, 4, decimal_precision, extra_flags); + return InputFloatN(label, v, 4, decimal_precision, extra_flags); } bool ImGui::InputIntN(const char* label, int* v, int components, ImGuiInputTextFlags extra_flags) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - bool value_changed = false; - BeginGroup(); - PushID(label); - PushMultiItemsWidths(components); - for (int i = 0; i < components; i++) - { - PushID(i); - value_changed |= InputInt("##v", &v[i], 0, 0, extra_flags); - SameLine(0, g.Style.ItemInnerSpacing.x); - PopID(); - PopItemWidth(); - } - PopID(); + ImGuiContext& g = *GImGui; + bool value_changed = false; + BeginGroup(); + PushID(label); + PushMultiItemsWidths(components); + for (int i = 0; i < components; i++) + { + PushID(i); + value_changed |= InputInt("##v", &v[i], 0, 0, extra_flags); + SameLine(0, g.Style.ItemInnerSpacing.x); + PopID(); + PopItemWidth(); + } + PopID(); - TextUnformatted(label, FindRenderedTextEnd(label)); - EndGroup(); + TextUnformatted(label, FindRenderedTextEnd(label)); + EndGroup(); - return value_changed; + return value_changed; } bool ImGui::InputInt2(const char* label, int v[2], ImGuiInputTextFlags extra_flags) { - return InputIntN(label, v, 2, extra_flags); + return InputIntN(label, v, 2, extra_flags); } bool ImGui::InputInt3(const char* label, int v[3], ImGuiInputTextFlags extra_flags) { - return InputIntN(label, v, 3, extra_flags); + return InputIntN(label, v, 3, extra_flags); } bool ImGui::InputInt4(const char* label, int v[4], ImGuiInputTextFlags extra_flags) { - return InputIntN(label, v, 4, extra_flags); + return InputIntN(label, v, 4, extra_flags); } static float CalcMaxPopupHeightFromItemCount(int items_count) { - ImGuiContext& g = *GImGui; - if (items_count <= 0) - return FLT_MAX; - return (g.FontSize + g.Style.ItemSpacing.y) * items_count - g.Style.ItemSpacing.y + (g.Style.WindowPadding.y * 2); + ImGuiContext& g = *GImGui; + if (items_count <= 0) + return FLT_MAX; + return (g.FontSize + g.Style.ItemSpacing.y) * items_count - g.Style.ItemSpacing.y + (g.Style.WindowPadding.y * 2); } bool ImGui::BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags) { - // Always consume the SetNextWindowSizeConstraint() call in our early return paths - ImGuiContext& g = *GImGui; - ImGuiCond backup_next_window_size_constraint = g.NextWindowData.SizeConstraintCond; - g.NextWindowData.SizeConstraintCond = 0; - - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + // Always consume the SetNextWindowSizeConstraint() call in our early return paths + ImGuiContext& g = *GImGui; + ImGuiCond backup_next_window_size_constraint = g.NextWindowData.SizeConstraintCond; + g.NextWindowData.SizeConstraintCond = 0; - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); - const float w = CalcItemWidth(); + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - const ImVec2 label_size = CalcTextSize(label, NULL, true); - const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y*2.0f)); - const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); - ItemSize(total_bb, style.FramePadding.y); - if (!ItemAdd(total_bb, id, &frame_bb)) - return false; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); + const float w = CalcItemWidth(); - bool hovered, held; - bool pressed = ButtonBehavior(frame_bb, id, &hovered, &held); - bool popup_open = IsPopupOpen(id); + const ImVec2 label_size = CalcTextSize(label, NULL, true); + const ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + ImVec2(w, label_size.y + style.FramePadding.y * 2.0f)); + const ImRect total_bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); + ItemSize(total_bb, style.FramePadding.y); + if (!ItemAdd(total_bb, id, &frame_bb)) + return false; - const float arrow_size = GetFrameHeight(); - const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f)); - RenderNavHighlight(frame_bb, id); - RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); - RenderFrame(ImVec2(frame_bb.Max.x-arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32(popup_open || hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING - RenderTriangle(ImVec2(frame_bb.Max.x - arrow_size + style.FramePadding.y, frame_bb.Min.y + style.FramePadding.y), ImGuiDir_Down); - if (preview_value != NULL) - RenderTextClipped(frame_bb.Min + style.FramePadding, value_bb.Max, preview_value, NULL, NULL, ImVec2(0.0f,0.0f)); - if (label_size.x > 0) - RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); + bool hovered, held; + bool pressed = ButtonBehavior(frame_bb, id, &hovered, &held); + bool popup_open = IsPopupOpen(id); - if ((pressed || g.NavActivateId == id) && !popup_open) - { - if (window->DC.NavLayerCurrent == 0) - window->NavLastIds[0] = id; - OpenPopupEx(id); - popup_open = true; - } + const float arrow_size = GetFrameHeight(); + const ImRect value_bb(frame_bb.Min, frame_bb.Max - ImVec2(arrow_size, 0.0f)); + RenderNavHighlight(frame_bb, id); + RenderFrame(frame_bb.Min, frame_bb.Max, GetColorU32(ImGuiCol_FrameBg), true, style.FrameRounding); + RenderFrame(ImVec2(frame_bb.Max.x - arrow_size, frame_bb.Min.y), frame_bb.Max, GetColorU32(popup_open || hovered ? ImGuiCol_ButtonHovered : ImGuiCol_Button), true, style.FrameRounding); // FIXME-ROUNDING + RenderTriangle(ImVec2(frame_bb.Max.x - arrow_size + style.FramePadding.y, frame_bb.Min.y + style.FramePadding.y), ImGuiDir_Down); + if (preview_value != NULL) + RenderTextClipped(frame_bb.Min + style.FramePadding, value_bb.Max, preview_value, NULL, NULL, ImVec2(0.0f, 0.0f)); + if (label_size.x > 0) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); - if (!popup_open) - return false; + if ((pressed || g.NavActivateId == id) && !popup_open) + { + if (window->DC.NavLayerCurrent == 0) + window->NavLastIds[0] = id; + OpenPopupEx(id); + popup_open = true; + } - if (backup_next_window_size_constraint) - { - g.NextWindowData.SizeConstraintCond = backup_next_window_size_constraint; - g.NextWindowData.SizeConstraintRect.Min.x = ImMax(g.NextWindowData.SizeConstraintRect.Min.x, w); - } - else - { - if ((flags & ImGuiComboFlags_HeightMask_) == 0) - flags |= ImGuiComboFlags_HeightRegular; - IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiComboFlags_HeightMask_)); // Only one - int popup_max_height_in_items = -1; - if (flags & ImGuiComboFlags_HeightRegular) popup_max_height_in_items = 8; - else if (flags & ImGuiComboFlags_HeightSmall) popup_max_height_in_items = 4; - else if (flags & ImGuiComboFlags_HeightLarge) popup_max_height_in_items = 20; - SetNextWindowSizeConstraints(ImVec2(w, 0.0f), ImVec2(FLT_MAX, CalcMaxPopupHeightFromItemCount(popup_max_height_in_items))); - } + if (!popup_open) + return false; - char name[16]; - ImFormatString(name, IM_ARRAYSIZE(name), "##Combo_%02d", g.CurrentPopupStack.Size); // Recycle windows based on depth + if (backup_next_window_size_constraint) + { + g.NextWindowData.SizeConstraintCond = backup_next_window_size_constraint; + g.NextWindowData.SizeConstraintRect.Min.x = ImMax(g.NextWindowData.SizeConstraintRect.Min.x, w); + } + else + { + if ((flags & ImGuiComboFlags_HeightMask_) == 0) + flags |= ImGuiComboFlags_HeightRegular; + IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiComboFlags_HeightMask_)); // Only one + int popup_max_height_in_items = -1; + if (flags & ImGuiComboFlags_HeightRegular) + popup_max_height_in_items = 8; + else if (flags & ImGuiComboFlags_HeightSmall) + popup_max_height_in_items = 4; + else if (flags & ImGuiComboFlags_HeightLarge) + popup_max_height_in_items = 20; + SetNextWindowSizeConstraints(ImVec2(w, 0.0f), ImVec2(FLT_MAX, CalcMaxPopupHeightFromItemCount(popup_max_height_in_items))); + } - // Peak into expected window size so we can position it - if (ImGuiWindow* popup_window = FindWindowByName(name)) - if (popup_window->WasActive) - { - ImVec2 size_contents = CalcSizeContents(popup_window); - ImVec2 size_expected = CalcSizeAfterConstraint(popup_window, CalcSizeAutoFit(popup_window, size_contents)); - if (flags & ImGuiComboFlags_PopupAlignLeft) - popup_window->AutoPosLastDirection = ImGuiDir_Left; - ImVec2 pos = FindBestWindowPosForPopup(frame_bb.GetBL(), size_expected, &popup_window->AutoPosLastDirection, frame_bb, ImGuiPopupPositionPolicy_ComboBox); - SetNextWindowPos(pos); - } + char name[16]; + ImFormatString(name, IM_ARRAYSIZE(name), "##Combo_%02d", g.CurrentPopupStack.Size); // Recycle windows based on depth - ImGuiWindowFlags window_flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_Popup | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings; - if (!Begin(name, NULL, window_flags)) - { - EndPopup(); - IM_ASSERT(0); // This should never happen as we tested for IsPopupOpen() above - return false; - } + // Peak into expected window size so we can position it + if (ImGuiWindow* popup_window = FindWindowByName(name)) + if (popup_window->WasActive) + { + ImVec2 size_contents = CalcSizeContents(popup_window); + ImVec2 size_expected = CalcSizeAfterConstraint(popup_window, CalcSizeAutoFit(popup_window, size_contents)); + if (flags & ImGuiComboFlags_PopupAlignLeft) + popup_window->AutoPosLastDirection = ImGuiDir_Left; + ImVec2 pos = FindBestWindowPosForPopup(frame_bb.GetBL(), size_expected, &popup_window->AutoPosLastDirection, frame_bb, ImGuiPopupPositionPolicy_ComboBox); + SetNextWindowPos(pos); + } - // Horizontally align ourselves with the framed text - if (style.FramePadding.x != style.WindowPadding.x) - Indent(style.FramePadding.x - style.WindowPadding.x); + ImGuiWindowFlags window_flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_Popup | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings; + if (!Begin(name, NULL, window_flags)) + { + EndPopup(); + IM_ASSERT(0); // This should never happen as we tested for IsPopupOpen() above + return false; + } - return true; + // Horizontally align ourselves with the framed text + if (style.FramePadding.x != style.WindowPadding.x) + Indent(style.FramePadding.x - style.WindowPadding.x); + + return true; } void ImGui::EndCombo() { - const ImGuiStyle& style = GImGui->Style; - if (style.FramePadding.x != style.WindowPadding.x) - Unindent(style.FramePadding.x - style.WindowPadding.x); - EndPopup(); + const ImGuiStyle& style = GImGui->Style; + if (style.FramePadding.x != style.WindowPadding.x) + Unindent(style.FramePadding.x - style.WindowPadding.x); + EndPopup(); } // Old API, prefer using BeginCombo() nowadays if you can. bool ImGui::Combo(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int popup_max_height_in_items) { - ImGuiContext& g = *GImGui; + ImGuiContext& g = *GImGui; - const char* preview_text = NULL; - if (*current_item >= 0 && *current_item < items_count) - items_getter(data, *current_item, &preview_text); + const char* preview_text = NULL; + if (*current_item >= 0 && *current_item < items_count) + items_getter(data, *current_item, &preview_text); - // The old Combo() API exposed "popup_max_height_in_items", however the new more general BeginCombo() API doesn't, so we emulate it here. - if (popup_max_height_in_items != -1 && !g.NextWindowData.SizeConstraintCond) - { - float popup_max_height = CalcMaxPopupHeightFromItemCount(popup_max_height_in_items); - SetNextWindowSizeConstraints(ImVec2(0,0), ImVec2(FLT_MAX, popup_max_height)); - } + // The old Combo() API exposed "popup_max_height_in_items", however the new more general BeginCombo() API doesn't, so we emulate it here. + if (popup_max_height_in_items != -1 && !g.NextWindowData.SizeConstraintCond) + { + float popup_max_height = CalcMaxPopupHeightFromItemCount(popup_max_height_in_items); + SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, popup_max_height)); + } - if (!BeginCombo(label, preview_text, 0)) - return false; + if (!BeginCombo(label, preview_text, 0)) + return false; - // Display items - // FIXME-OPT: Use clipper (but we need to disable it on the appearing frame to make sure our call to SetItemDefaultFocus() is processed) - bool value_changed = false; - for (int i = 0; i < items_count; i++) - { - PushID((void*)(intptr_t)i); - const bool item_selected = (i == *current_item); - const char* item_text; - if (!items_getter(data, i, &item_text)) - item_text = "*Unknown item*"; - if (Selectable(item_text, item_selected)) - { - value_changed = true; - *current_item = i; - } - if (item_selected) - SetItemDefaultFocus(); - PopID(); - } + // Display items + // FIXME-OPT: Use clipper (but we need to disable it on the appearing frame to make sure our call to SetItemDefaultFocus() is processed) + bool value_changed = false; + for (int i = 0; i < items_count; i++) + { + PushID((void*)(intptr_t)i); + const bool item_selected = (i == *current_item); + const char* item_text; + if (!items_getter(data, i, &item_text)) + item_text = "*Unknown item*"; + if (Selectable(item_text, item_selected)) + { + value_changed = true; + *current_item = i; + } + if (item_selected) + SetItemDefaultFocus(); + PopID(); + } - EndCombo(); - return value_changed; + EndCombo(); + return value_changed; } static bool Items_ArrayGetter(void* data, int idx, const char** out_text) { - const char* const* items = (const char* const*)data; - if (out_text) - *out_text = items[idx]; - return true; + const char* const* items = (const char* const*)data; + if (out_text) + *out_text = items[idx]; + return true; } static bool Items_SingleStringGetter(void* data, int idx, const char** out_text) { - // FIXME-OPT: we could pre-compute the indices to fasten this. But only 1 active combo means the waste is limited. - const char* items_separated_by_zeros = (const char*)data; - int items_count = 0; - const char* p = items_separated_by_zeros; - while (*p) - { - if (idx == items_count) - break; - p += strlen(p) + 1; - items_count++; - } - if (!*p) - return false; - if (out_text) - *out_text = p; - return true; + // FIXME-OPT: we could pre-compute the indices to fasten this. But only 1 active combo means the waste is limited. + const char* items_separated_by_zeros = (const char*)data; + int items_count = 0; + const char* p = items_separated_by_zeros; + while (*p) + { + if (idx == items_count) + break; + p += strlen(p) + 1; + items_count++; + } + if (!*p) + return false; + if (out_text) + *out_text = p; + return true; } // Combo box helper allowing to pass an array of strings. bool ImGui::Combo(const char* label, int* current_item, const char* const items[], int items_count, int height_in_items) { - const bool value_changed = Combo(label, current_item, Items_ArrayGetter, (void*)items, items_count, height_in_items); - return value_changed; + const bool value_changed = Combo(label, current_item, Items_ArrayGetter, (void*)items, items_count, height_in_items); + return value_changed; } // Combo box helper allowing to pass all items in a single string. bool ImGui::Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int height_in_items) { - int items_count = 0; - const char* p = items_separated_by_zeros; // FIXME-OPT: Avoid computing this, or at least only when combo is open - while (*p) - { - p += strlen(p) + 1; - items_count++; - } - bool value_changed = Combo(label, current_item, Items_SingleStringGetter, (void*)items_separated_by_zeros, items_count, height_in_items); - return value_changed; + int items_count = 0; + const char* p = items_separated_by_zeros; // FIXME-OPT: Avoid computing this, or at least only when combo is open + while (*p) + { + p += strlen(p) + 1; + items_count++; + } + bool value_changed = Combo(label, current_item, Items_SingleStringGetter, (void*)items_separated_by_zeros, items_count, height_in_items); + return value_changed; } // Tip: pass an empty label (e.g. "##dummy") then you can use the space to draw other text or image. // But you need to make sure the ID is unique, e.g. enclose calls in PushID/PopID. bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags flags, const ImVec2& size_arg) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; - if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet) // FIXME-OPT: Avoid if vertically clipped. - PopClipRect(); + if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet) // FIXME-OPT: Avoid if vertically clipped. + PopClipRect(); - ImGuiID id = window->GetID(label); - ImVec2 label_size = CalcTextSize(label, NULL, true); - ImVec2 size(size_arg.x != 0.0f ? size_arg.x : label_size.x, size_arg.y != 0.0f ? size_arg.y : label_size.y); - ImVec2 pos = window->DC.CursorPos; - pos.y += window->DC.CurrentLineTextBaseOffset; - ImRect bb(pos, pos + size); - ItemSize(bb); + ImGuiID id = window->GetID(label); + ImVec2 label_size = CalcTextSize(label, NULL, true); + ImVec2 size(size_arg.x != 0.0f ? size_arg.x : label_size.x, size_arg.y != 0.0f ? size_arg.y : label_size.y); + ImVec2 pos = window->DC.CursorPos; + pos.y += window->DC.CurrentLineTextBaseOffset; + ImRect bb(pos, pos + size); + ItemSize(bb); - // Fill horizontal space. - ImVec2 window_padding = window->WindowPadding; - float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? GetWindowContentRegionMax().x : GetContentRegionMax().x; - float w_draw = ImMax(label_size.x, window->Pos.x + max_x - window_padding.x - window->DC.CursorPos.x); - ImVec2 size_draw((size_arg.x != 0 && !(flags & ImGuiSelectableFlags_DrawFillAvailWidth)) ? size_arg.x : w_draw, size_arg.y != 0.0f ? size_arg.y : size.y); - ImRect bb_with_spacing(pos, pos + size_draw); - if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_DrawFillAvailWidth)) - bb_with_spacing.Max.x += window_padding.x; + // Fill horizontal space. + ImVec2 window_padding = window->WindowPadding; + float max_x = (flags & ImGuiSelectableFlags_SpanAllColumns) ? GetWindowContentRegionMax().x : GetContentRegionMax().x; + float w_draw = ImMax(label_size.x, window->Pos.x + max_x - window_padding.x - window->DC.CursorPos.x); + ImVec2 size_draw((size_arg.x != 0 && !(flags & ImGuiSelectableFlags_DrawFillAvailWidth)) ? size_arg.x : w_draw, size_arg.y != 0.0f ? size_arg.y : size.y); + ImRect bb_with_spacing(pos, pos + size_draw); + if (size_arg.x == 0.0f || (flags & ImGuiSelectableFlags_DrawFillAvailWidth)) + bb_with_spacing.Max.x += window_padding.x; - // Selectables are tightly packed together, we extend the box to cover spacing between selectable. - float spacing_L = (float)(int)(style.ItemSpacing.x * 0.5f); - float spacing_U = (float)(int)(style.ItemSpacing.y * 0.5f); - float spacing_R = style.ItemSpacing.x - spacing_L; - float spacing_D = style.ItemSpacing.y - spacing_U; - bb_with_spacing.Min.x -= spacing_L; - bb_with_spacing.Min.y -= spacing_U; - bb_with_spacing.Max.x += spacing_R; - bb_with_spacing.Max.y += spacing_D; - if (!ItemAdd(bb_with_spacing, (flags & ImGuiSelectableFlags_Disabled) ? 0 : id)) - { - if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet) - PushColumnClipRect(); - return false; - } + // Selectables are tightly packed together, we extend the box to cover spacing between selectable. + float spacing_L = (float)(int)(style.ItemSpacing.x * 0.5f); + float spacing_U = (float)(int)(style.ItemSpacing.y * 0.5f); + float spacing_R = style.ItemSpacing.x - spacing_L; + float spacing_D = style.ItemSpacing.y - spacing_U; + bb_with_spacing.Min.x -= spacing_L; + bb_with_spacing.Min.y -= spacing_U; + bb_with_spacing.Max.x += spacing_R; + bb_with_spacing.Max.y += spacing_D; + if (!ItemAdd(bb_with_spacing, (flags & ImGuiSelectableFlags_Disabled) ? 0 : id)) + { + if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet) + PushColumnClipRect(); + return false; + } - ImGuiButtonFlags button_flags = 0; - if (flags & ImGuiSelectableFlags_Menu) button_flags |= ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_NoHoldingActiveID; - if (flags & ImGuiSelectableFlags_MenuItem) button_flags |= ImGuiButtonFlags_PressedOnRelease; - if (flags & ImGuiSelectableFlags_Disabled) button_flags |= ImGuiButtonFlags_Disabled; - if (flags & ImGuiSelectableFlags_AllowDoubleClick) button_flags |= ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnDoubleClick; - bool hovered, held; - bool pressed = ButtonBehavior(bb_with_spacing, id, &hovered, &held, button_flags); - if (flags & ImGuiSelectableFlags_Disabled) - selected = false; + ImGuiButtonFlags button_flags = 0; + if (flags & ImGuiSelectableFlags_Menu) button_flags |= ImGuiButtonFlags_PressedOnClick | ImGuiButtonFlags_NoHoldingActiveID; + if (flags & ImGuiSelectableFlags_MenuItem) button_flags |= ImGuiButtonFlags_PressedOnRelease; + if (flags & ImGuiSelectableFlags_Disabled) button_flags |= ImGuiButtonFlags_Disabled; + if (flags & ImGuiSelectableFlags_AllowDoubleClick) button_flags |= ImGuiButtonFlags_PressedOnClickRelease | ImGuiButtonFlags_PressedOnDoubleClick; + bool hovered, held; + bool pressed = ButtonBehavior(bb_with_spacing, id, &hovered, &held, button_flags); + if (flags & ImGuiSelectableFlags_Disabled) + selected = false; - // Hovering selectable with mouse updates NavId accordingly so navigation can be resumed with gamepad/keyboard (this doesn't happen on most widgets) - if (pressed || hovered)// && (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f)) - if (!g.NavDisableMouseHover && g.NavWindow == window && g.NavLayer == window->DC.NavLayerActiveMask) - { - g.NavDisableHighlight = true; - SetNavID(id, window->DC.NavLayerCurrent); - } + // Hovering selectable with mouse updates NavId accordingly so navigation can be resumed with gamepad/keyboard (this doesn't happen on most widgets) + if (pressed || hovered) // && (g.IO.MouseDelta.x != 0.0f || g.IO.MouseDelta.y != 0.0f)) + if (!g.NavDisableMouseHover && g.NavWindow == window && g.NavLayer == window->DC.NavLayerActiveMask) + { + g.NavDisableHighlight = true; + SetNavID(id, window->DC.NavLayerCurrent); + } - // Render - if (hovered || selected) - { - const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); - RenderFrame(bb_with_spacing.Min, bb_with_spacing.Max, col, false, 0.0f); - RenderNavHighlight(bb_with_spacing, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding); - } + // Render + if (hovered || selected) + { + const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); + RenderFrame(bb_with_spacing.Min, bb_with_spacing.Max, col, false, 0.0f); + RenderNavHighlight(bb_with_spacing, id, ImGuiNavHighlightFlags_TypeThin | ImGuiNavHighlightFlags_NoRounding); + } - if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet) - { - PushColumnClipRect(); - bb_with_spacing.Max.x -= (GetContentRegionMax().x - max_x); - } + if ((flags & ImGuiSelectableFlags_SpanAllColumns) && window->DC.ColumnsSet) + { + PushColumnClipRect(); + bb_with_spacing.Max.x -= (GetContentRegionMax().x - max_x); + } - if (flags & ImGuiSelectableFlags_Disabled) PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); - RenderTextClipped(bb.Min, bb_with_spacing.Max, label, NULL, &label_size, ImVec2(0.0f,0.0f)); - if (flags & ImGuiSelectableFlags_Disabled) PopStyleColor(); + if (flags & ImGuiSelectableFlags_Disabled) PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); + RenderTextClipped(bb.Min, bb_with_spacing.Max, label, NULL, &label_size, ImVec2(0.0f, 0.0f)); + if (flags & ImGuiSelectableFlags_Disabled) PopStyleColor(); - // Automatically close popups - if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_DontClosePopups) && !(window->DC.ItemFlags & ImGuiItemFlags_SelectableDontClosePopup)) - CloseCurrentPopup(); - return pressed; + // Automatically close popups + if (pressed && (window->Flags & ImGuiWindowFlags_Popup) && !(flags & ImGuiSelectableFlags_DontClosePopups) && !(window->DC.ItemFlags & ImGuiItemFlags_SelectableDontClosePopup)) + CloseCurrentPopup(); + return pressed; } bool ImGui::Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags, const ImVec2& size_arg) { - if (Selectable(label, *p_selected, flags, size_arg)) - { - *p_selected = !*p_selected; - return true; - } - return false; + if (Selectable(label, *p_selected, flags, size_arg)) + { + *p_selected = !*p_selected; + return true; + } + return false; } // Helper to calculate the size of a listbox and display a label on the right. // Tip: To have a list filling the entire window width, PushItemWidth(-1) and pass an empty label "##empty" bool ImGui::ListBoxHeader(const char* label, const ImVec2& size_arg) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - const ImGuiStyle& style = GetStyle(); - const ImGuiID id = GetID(label); - const ImVec2 label_size = CalcTextSize(label, NULL, true); + const ImGuiStyle& style = GetStyle(); + const ImGuiID id = GetID(label); + const ImVec2 label_size = CalcTextSize(label, NULL, true); - // Size default to hold ~7 items. Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar. - ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), GetTextLineHeightWithSpacing() * 7.4f + style.ItemSpacing.y); - ImVec2 frame_size = ImVec2(size.x, ImMax(size.y, label_size.y)); - ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size); - ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); - window->DC.LastItemRect = bb; // Forward storage for ListBoxFooter.. dodgy. + // Size default to hold ~7 items. Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar. + ImVec2 size = CalcItemSize(size_arg, CalcItemWidth(), GetTextLineHeightWithSpacing() * 7.4f + style.ItemSpacing.y); + ImVec2 frame_size = ImVec2(size.x, ImMax(size.y, label_size.y)); + ImRect frame_bb(window->DC.CursorPos, window->DC.CursorPos + frame_size); + ImRect bb(frame_bb.Min, frame_bb.Max + ImVec2(label_size.x > 0.0f ? style.ItemInnerSpacing.x + label_size.x : 0.0f, 0.0f)); + window->DC.LastItemRect = bb; // Forward storage for ListBoxFooter.. dodgy. - BeginGroup(); - if (label_size.x > 0) - RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); + BeginGroup(); + if (label_size.x > 0) + RenderText(ImVec2(frame_bb.Max.x + style.ItemInnerSpacing.x, frame_bb.Min.y + style.FramePadding.y), label); - BeginChildFrame(id, frame_bb.GetSize()); - return true; + BeginChildFrame(id, frame_bb.GetSize()); + return true; } bool ImGui::ListBoxHeader(const char* label, int items_count, int height_in_items) { - // Size default to hold ~7 items. Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar. - // However we don't add +0.40f if items_count <= height_in_items. It is slightly dodgy, because it means a dynamic list of items will make the widget resize occasionally when it crosses that size. - // I am expecting that someone will come and complain about this behavior in a remote future, then we can advise on a better solution. - if (height_in_items < 0) - height_in_items = ImMin(items_count, 7); - float height_in_items_f = height_in_items < items_count ? (height_in_items + 0.40f) : (height_in_items + 0.00f); + // Size default to hold ~7 items. Fractional number of items helps seeing that we can scroll down/up without looking at scrollbar. + // However we don't add +0.40f if items_count <= height_in_items. It is slightly dodgy, because it means a dynamic list of items will make the widget resize occasionally when it crosses that size. + // I am expecting that someone will come and complain about this behavior in a remote future, then we can advise on a better solution. + if (height_in_items < 0) + height_in_items = ImMin(items_count, 7); + float height_in_items_f = height_in_items < items_count ? (height_in_items + 0.40f) : (height_in_items + 0.00f); - // We include ItemSpacing.y so that a list sized for the exact number of items doesn't make a scrollbar appears. We could also enforce that by passing a flag to BeginChild(). - ImVec2 size; - size.x = 0.0f; - size.y = GetTextLineHeightWithSpacing() * height_in_items_f + GetStyle().ItemSpacing.y; - return ListBoxHeader(label, size); + // We include ItemSpacing.y so that a list sized for the exact number of items doesn't make a scrollbar appears. We could also enforce that by passing a flag to BeginChild(). + ImVec2 size; + size.x = 0.0f; + size.y = GetTextLineHeightWithSpacing() * height_in_items_f + GetStyle().ItemSpacing.y; + return ListBoxHeader(label, size); } void ImGui::ListBoxFooter() { - ImGuiWindow* parent_window = GetCurrentWindow()->ParentWindow; - const ImRect bb = parent_window->DC.LastItemRect; - const ImGuiStyle& style = GetStyle(); + ImGuiWindow* parent_window = GetCurrentWindow()->ParentWindow; + const ImRect bb = parent_window->DC.LastItemRect; + const ImGuiStyle& style = GetStyle(); - EndChildFrame(); + EndChildFrame(); - // Redeclare item size so that it includes the label (we have stored the full size in LastItemRect) - // We call SameLine() to restore DC.CurrentLine* data - SameLine(); - parent_window->DC.CursorPos = bb.Min; - ItemSize(bb, style.FramePadding.y); - EndGroup(); + // Redeclare item size so that it includes the label (we have stored the full size in LastItemRect) + // We call SameLine() to restore DC.CurrentLine* data + SameLine(); + parent_window->DC.CursorPos = bb.Min; + ItemSize(bb, style.FramePadding.y); + EndGroup(); } bool ImGui::ListBox(const char* label, int* current_item, const char* const items[], int items_count, int height_items) { - const bool value_changed = ListBox(label, current_item, Items_ArrayGetter, (void*)items, items_count, height_items); - return value_changed; + const bool value_changed = ListBox(label, current_item, Items_ArrayGetter, (void*)items, items_count, height_items); + return value_changed; } bool ImGui::ListBox(const char* label, int* current_item, bool (*items_getter)(void*, int, const char**), void* data, int items_count, int height_in_items) { - if (!ListBoxHeader(label, items_count, height_in_items)) - return false; + if (!ListBoxHeader(label, items_count, height_in_items)) + return false; - // Assume all items have even height (= 1 line of text). If you need items of different or variable sizes you can create a custom version of ListBox() in your code without using the clipper. - bool value_changed = false; - ImGuiListClipper clipper(items_count, GetTextLineHeightWithSpacing()); // We know exactly our line height here so we pass it as a minor optimization, but generally you don't need to. - while (clipper.Step()) - for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) - { - const bool item_selected = (i == *current_item); - const char* item_text; - if (!items_getter(data, i, &item_text)) - item_text = "*Unknown item*"; + // Assume all items have even height (= 1 line of text). If you need items of different or variable sizes you can create a custom version of ListBox() in your code without using the clipper. + bool value_changed = false; + ImGuiListClipper clipper(items_count, GetTextLineHeightWithSpacing()); // We know exactly our line height here so we pass it as a minor optimization, but generally you don't need to. + while (clipper.Step()) + for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) + { + const bool item_selected = (i == *current_item); + const char* item_text; + if (!items_getter(data, i, &item_text)) + item_text = "*Unknown item*"; - PushID(i); - if (Selectable(item_text, item_selected)) - { - *current_item = i; - value_changed = true; - } - if (item_selected) - SetItemDefaultFocus(); - PopID(); - } - ListBoxFooter(); - return value_changed; + PushID(i); + if (Selectable(item_text, item_selected)) + { + *current_item = i; + value_changed = true; + } + if (item_selected) + SetItemDefaultFocus(); + PopID(); + } + ListBoxFooter(); + return value_changed; } bool ImGui::MenuItem(const char* label, const char* shortcut, bool selected, bool enabled) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - ImGuiStyle& style = g.Style; - ImVec2 pos = window->DC.CursorPos; - ImVec2 label_size = CalcTextSize(label, NULL, true); + ImGuiContext& g = *GImGui; + ImGuiStyle& style = g.Style; + ImVec2 pos = window->DC.CursorPos; + ImVec2 label_size = CalcTextSize(label, NULL, true); - ImGuiSelectableFlags flags = ImGuiSelectableFlags_MenuItem | (enabled ? 0 : ImGuiSelectableFlags_Disabled); - bool pressed; - if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) - { - // Mimic the exact layout spacing of BeginMenu() to allow MenuItem() inside a menu bar, which is a little misleading but may be useful - // Note that in this situation we render neither the shortcut neither the selected tick mark - float w = label_size.x; - window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); - PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f); - pressed = Selectable(label, false, flags, ImVec2(w, 0.0f)); - PopStyleVar(); - window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar(). - } - else - { - ImVec2 shortcut_size = shortcut ? CalcTextSize(shortcut, NULL) : ImVec2(0.0f, 0.0f); - float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame - float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); - pressed = Selectable(label, false, flags | ImGuiSelectableFlags_DrawFillAvailWidth, ImVec2(w, 0.0f)); - if (shortcut_size.x > 0.0f) - { - PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); - RenderText(pos + ImVec2(window->MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false); - PopStyleColor(); - } - if (selected) - RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled), g.FontSize * 0.866f); - } - return pressed; + ImGuiSelectableFlags flags = ImGuiSelectableFlags_MenuItem | (enabled ? 0 : ImGuiSelectableFlags_Disabled); + bool pressed; + if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) + { + // Mimic the exact layout spacing of BeginMenu() to allow MenuItem() inside a menu bar, which is a little misleading but may be useful + // Note that in this situation we render neither the shortcut neither the selected tick mark + float w = label_size.x; + window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); + PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f); + pressed = Selectable(label, false, flags, ImVec2(w, 0.0f)); + PopStyleVar(); + window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar(). + } + else + { + ImVec2 shortcut_size = shortcut ? CalcTextSize(shortcut, NULL) : ImVec2(0.0f, 0.0f); + float w = window->MenuColumns.DeclColumns(label_size.x, shortcut_size.x, (float)(int)(g.FontSize * 1.20f)); // Feedback for next frame + float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); + pressed = Selectable(label, false, flags | ImGuiSelectableFlags_DrawFillAvailWidth, ImVec2(w, 0.0f)); + if (shortcut_size.x > 0.0f) + { + PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); + RenderText(pos + ImVec2(window->MenuColumns.Pos[1] + extra_w, 0.0f), shortcut, NULL, false); + PopStyleColor(); + } + if (selected) + RenderCheckMark(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.40f, g.FontSize * 0.134f * 0.5f), GetColorU32(enabled ? ImGuiCol_Text : ImGuiCol_TextDisabled), g.FontSize * 0.866f); + } + return pressed; } bool ImGui::MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled) { - if (MenuItem(label, shortcut, p_selected ? *p_selected : false, enabled)) - { - if (p_selected) - *p_selected = !*p_selected; - return true; - } - return false; + if (MenuItem(label, shortcut, p_selected ? *p_selected : false, enabled)) + { + if (p_selected) + *p_selected = !*p_selected; + return true; + } + return false; } bool ImGui::BeginMainMenuBar() { - ImGuiContext& g = *GImGui; - SetNextWindowPos(ImVec2(0.0f, 0.0f)); - SetNextWindowSize(ImVec2(g.IO.DisplaySize.x, g.FontBaseSize + g.Style.FramePadding.y * 2.0f)); - PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); - PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0,0)); - if (!Begin("##MainMenuBar", NULL, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoScrollbar|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_MenuBar) - || !BeginMenuBar()) - { - End(); - PopStyleVar(2); - return false; - } - g.CurrentWindow->DC.MenuBarOffsetX += g.Style.DisplaySafeAreaPadding.x; - return true; + ImGuiContext& g = *GImGui; + SetNextWindowPos(ImVec2(0.0f, 0.0f)); + SetNextWindowSize(ImVec2(g.IO.DisplaySize.x, g.FontBaseSize + g.Style.FramePadding.y * 2.0f)); + PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f); + PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0, 0)); + if (!Begin("##MainMenuBar", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_MenuBar) || !BeginMenuBar()) + { + End(); + PopStyleVar(2); + return false; + } + g.CurrentWindow->DC.MenuBarOffsetX += g.Style.DisplaySafeAreaPadding.x; + return true; } void ImGui::EndMainMenuBar() { - EndMenuBar(); + EndMenuBar(); - // When the user has left the menu layer (typically: closed menus through activation of an item), we restore focus to the previous window - ImGuiContext& g = *GImGui; - if (g.CurrentWindow == g.NavWindow && g.NavLayer == 0) - FocusFrontMostActiveWindow(g.NavWindow); + // When the user has left the menu layer (typically: closed menus through activation of an item), we restore focus to the previous window + ImGuiContext& g = *GImGui; + if (g.CurrentWindow == g.NavWindow && g.NavLayer == 0) + FocusFrontMostActiveWindow(g.NavWindow); - End(); - PopStyleVar(2); + End(); + PopStyleVar(2); } bool ImGui::BeginMenuBar() { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; - if (!(window->Flags & ImGuiWindowFlags_MenuBar)) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; + if (!(window->Flags & ImGuiWindowFlags_MenuBar)) + return false; - IM_ASSERT(!window->DC.MenuBarAppending); - BeginGroup(); // Save position - PushID("##menubar"); - - // We don't clip with regular window clipping rectangle as it is already set to the area below. However we clip with window full rect. - // We remove 1 worth of rounding to Max.x to that text in long menus don't tend to display over the lower-right rounded area, which looks particularly glitchy. - ImRect bar_rect = window->MenuBarRect(); - ImRect clip_rect(ImFloor(bar_rect.Min.x + 0.5f), ImFloor(bar_rect.Min.y + window->WindowBorderSize + 0.5f), ImFloor(ImMax(bar_rect.Min.x, bar_rect.Max.x - window->WindowRounding) + 0.5f), ImFloor(bar_rect.Max.y + 0.5f)); - clip_rect.ClipWith(window->WindowRectClipped); - PushClipRect(clip_rect.Min, clip_rect.Max, false); + IM_ASSERT(!window->DC.MenuBarAppending); + BeginGroup(); // Save position + PushID("##menubar"); - window->DC.CursorPos = ImVec2(bar_rect.Min.x + window->DC.MenuBarOffsetX, bar_rect.Min.y);// + g.Style.FramePadding.y); - window->DC.LayoutType = ImGuiLayoutType_Horizontal; - window->DC.NavLayerCurrent++; - window->DC.NavLayerCurrentMask <<= 1; - window->DC.MenuBarAppending = true; - AlignTextToFramePadding(); - return true; + // We don't clip with regular window clipping rectangle as it is already set to the area below. However we clip with window full rect. + // We remove 1 worth of rounding to Max.x to that text in long menus don't tend to display over the lower-right rounded area, which looks particularly glitchy. + ImRect bar_rect = window->MenuBarRect(); + ImRect clip_rect(ImFloor(bar_rect.Min.x + 0.5f), ImFloor(bar_rect.Min.y + window->WindowBorderSize + 0.5f), ImFloor(ImMax(bar_rect.Min.x, bar_rect.Max.x - window->WindowRounding) + 0.5f), ImFloor(bar_rect.Max.y + 0.5f)); + clip_rect.ClipWith(window->WindowRectClipped); + PushClipRect(clip_rect.Min, clip_rect.Max, false); + + window->DC.CursorPos = ImVec2(bar_rect.Min.x + window->DC.MenuBarOffsetX, bar_rect.Min.y); // + g.Style.FramePadding.y); + window->DC.LayoutType = ImGuiLayoutType_Horizontal; + window->DC.NavLayerCurrent++; + window->DC.NavLayerCurrentMask <<= 1; + window->DC.MenuBarAppending = true; + AlignTextToFramePadding(); + return true; } void ImGui::EndMenuBar() { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; - ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + ImGuiContext& g = *GImGui; - // Nav: When a move request within one of our child menu failed, capture the request to navigate among our siblings. - if (NavMoveRequestButNoResultYet() && (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right) && (g.NavWindow->Flags & ImGuiWindowFlags_ChildMenu)) - { - ImGuiWindow* nav_earliest_child = g.NavWindow; - while (nav_earliest_child->ParentWindow && (nav_earliest_child->ParentWindow->Flags & ImGuiWindowFlags_ChildMenu)) - nav_earliest_child = nav_earliest_child->ParentWindow; - if (nav_earliest_child->ParentWindow == window && nav_earliest_child->DC.ParentLayoutType == ImGuiLayoutType_Horizontal && g.NavMoveRequestForward == ImGuiNavForward_None) - { - // To do so we claim focus back, restore NavId and then process the movement request for yet another frame. - // This involve a one-frame delay which isn't very problematic in this situation. We could remove it by scoring in advance for multiple window (probably not worth the hassle/cost) - IM_ASSERT(window->DC.NavLayerActiveMaskNext & 0x02); // Sanity check - FocusWindow(window); - SetNavIDAndMoveMouse(window->NavLastIds[1], 1, window->NavRectRel[1]); - g.NavLayer = 1; - g.NavDisableHighlight = true; // Hide highlight for the current frame so we don't see the intermediary selection. - g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued; - NavMoveRequestCancel(); - } - } + // Nav: When a move request within one of our child menu failed, capture the request to navigate among our siblings. + if (NavMoveRequestButNoResultYet() && (g.NavMoveDir == ImGuiDir_Left || g.NavMoveDir == ImGuiDir_Right) && (g.NavWindow->Flags & ImGuiWindowFlags_ChildMenu)) + { + ImGuiWindow* nav_earliest_child = g.NavWindow; + while (nav_earliest_child->ParentWindow && (nav_earliest_child->ParentWindow->Flags & ImGuiWindowFlags_ChildMenu)) + nav_earliest_child = nav_earliest_child->ParentWindow; + if (nav_earliest_child->ParentWindow == window && nav_earliest_child->DC.ParentLayoutType == ImGuiLayoutType_Horizontal && g.NavMoveRequestForward == ImGuiNavForward_None) + { + // To do so we claim focus back, restore NavId and then process the movement request for yet another frame. + // This involve a one-frame delay which isn't very problematic in this situation. We could remove it by scoring in advance for multiple window (probably not worth the hassle/cost) + IM_ASSERT(window->DC.NavLayerActiveMaskNext & 0x02); // Sanity check + FocusWindow(window); + SetNavIDAndMoveMouse(window->NavLastIds[1], 1, window->NavRectRel[1]); + g.NavLayer = 1; + g.NavDisableHighlight = true; // Hide highlight for the current frame so we don't see the intermediary selection. + g.NavMoveRequestForward = ImGuiNavForward_ForwardQueued; + NavMoveRequestCancel(); + } + } - IM_ASSERT(window->Flags & ImGuiWindowFlags_MenuBar); - IM_ASSERT(window->DC.MenuBarAppending); - PopClipRect(); - PopID(); - window->DC.MenuBarOffsetX = window->DC.CursorPos.x - window->MenuBarRect().Min.x; - window->DC.GroupStack.back().AdvanceCursor = false; - EndGroup(); - window->DC.LayoutType = ImGuiLayoutType_Vertical; - window->DC.NavLayerCurrent--; - window->DC.NavLayerCurrentMask >>= 1; - window->DC.MenuBarAppending = false; + IM_ASSERT(window->Flags & ImGuiWindowFlags_MenuBar); + IM_ASSERT(window->DC.MenuBarAppending); + PopClipRect(); + PopID(); + window->DC.MenuBarOffsetX = window->DC.CursorPos.x - window->MenuBarRect().Min.x; + window->DC.GroupStack.back().AdvanceCursor = false; + EndGroup(); + window->DC.LayoutType = ImGuiLayoutType_Vertical; + window->DC.NavLayerCurrent--; + window->DC.NavLayerCurrentMask >>= 1; + window->DC.MenuBarAppending = false; } bool ImGui::BeginMenu(const char* label, bool enabled) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; - const ImGuiID id = window->GetID(label); + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const ImGuiID id = window->GetID(label); - ImVec2 label_size = CalcTextSize(label, NULL, true); + ImVec2 label_size = CalcTextSize(label, NULL, true); - bool pressed; - bool menu_is_open = IsPopupOpen(id); - bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].OpenParentId == window->IDStack.back()); - ImGuiWindow* backed_nav_window = g.NavWindow; - if (menuset_is_open) - g.NavWindow = window; // Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent) + bool pressed; + bool menu_is_open = IsPopupOpen(id); + bool menuset_is_open = !(window->Flags & ImGuiWindowFlags_Popup) && (g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].OpenParentId == window->IDStack.back()); + ImGuiWindow* backed_nav_window = g.NavWindow; + if (menuset_is_open) + g.NavWindow = window; // Odd hack to allow hovering across menus of a same menu-set (otherwise we wouldn't be able to hover parent) - // The reference position stored in popup_pos will be used by Begin() to find a suitable position for the child menu (using FindBestPopupWindowPos). - ImVec2 popup_pos, pos = window->DC.CursorPos; - if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) - { - // Menu inside an horizontal menu bar - // Selectable extend their highlight by half ItemSpacing in each direction. - // For ChildMenu, the popup position will be overwritten by the call to FindBestPopupWindowPos() in Begin() - popup_pos = ImVec2(pos.x - window->WindowPadding.x, pos.y - style.FramePadding.y + window->MenuBarHeight()); - window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); - PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f); - float w = label_size.x; - pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_Menu | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f)); - PopStyleVar(); - window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar(). - } - else - { - // Menu inside a menu - popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y); - float w = window->MenuColumns.DeclColumns(label_size.x, 0.0f, (float)(int)(g.FontSize * 1.20f)); // Feedback to next frame - float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); - pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_Menu | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f)); - if (!enabled) PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); - RenderTriangle(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.30f, 0.0f), ImGuiDir_Right); - if (!enabled) PopStyleColor(); - } + // The reference position stored in popup_pos will be used by Begin() to find a suitable position for the child menu (using FindBestPopupWindowPos). + ImVec2 popup_pos, pos = window->DC.CursorPos; + if (window->DC.LayoutType == ImGuiLayoutType_Horizontal) + { + // Menu inside an horizontal menu bar + // Selectable extend their highlight by half ItemSpacing in each direction. + // For ChildMenu, the popup position will be overwritten by the call to FindBestPopupWindowPos() in Begin() + popup_pos = ImVec2(pos.x - window->WindowPadding.x, pos.y - style.FramePadding.y + window->MenuBarHeight()); + window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * 0.5f); + PushStyleVar(ImGuiStyleVar_ItemSpacing, style.ItemSpacing * 2.0f); + float w = label_size.x; + pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_Menu | ImGuiSelectableFlags_DontClosePopups | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f)); + PopStyleVar(); + window->DC.CursorPos.x += (float)(int)(style.ItemSpacing.x * (-1.0f + 0.5f)); // -1 spacing to compensate the spacing added when Selectable() did a SameLine(). It would also work to call SameLine() ourselves after the PopStyleVar(). + } + else + { + // Menu inside a menu + popup_pos = ImVec2(pos.x, pos.y - style.WindowPadding.y); + float w = window->MenuColumns.DeclColumns(label_size.x, 0.0f, (float)(int)(g.FontSize * 1.20f)); // Feedback to next frame + float extra_w = ImMax(0.0f, GetContentRegionAvail().x - w); + pressed = Selectable(label, menu_is_open, ImGuiSelectableFlags_Menu | ImGuiSelectableFlags_DontClosePopups | ImGuiSelectableFlags_DrawFillAvailWidth | (!enabled ? ImGuiSelectableFlags_Disabled : 0), ImVec2(w, 0.0f)); + if (!enabled) PushStyleColor(ImGuiCol_Text, g.Style.Colors[ImGuiCol_TextDisabled]); + RenderTriangle(pos + ImVec2(window->MenuColumns.Pos[2] + extra_w + g.FontSize * 0.30f, 0.0f), ImGuiDir_Right); + if (!enabled) PopStyleColor(); + } - const bool hovered = enabled && ItemHoverable(window->DC.LastItemRect, id); - if (menuset_is_open) - g.NavWindow = backed_nav_window; + const bool hovered = enabled && ItemHoverable(window->DC.LastItemRect, id); + if (menuset_is_open) + g.NavWindow = backed_nav_window; - bool want_open = false, want_close = false; - if (window->DC.LayoutType == ImGuiLayoutType_Vertical) // (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) - { - // Implement http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown to avoid using timers, so menus feels more reactive. - bool moving_within_opened_triangle = false; - if (g.HoveredWindow == window && g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].ParentWindow == window && !(window->Flags & ImGuiWindowFlags_MenuBar)) - { - if (ImGuiWindow* next_window = g.OpenPopupStack[g.CurrentPopupStack.Size].Window) - { - ImRect next_window_rect = next_window->Rect(); - ImVec2 ta = g.IO.MousePos - g.IO.MouseDelta; - ImVec2 tb = (window->Pos.x < next_window->Pos.x) ? next_window_rect.GetTL() : next_window_rect.GetTR(); - ImVec2 tc = (window->Pos.x < next_window->Pos.x) ? next_window_rect.GetBL() : next_window_rect.GetBR(); - float extra = ImClamp(fabsf(ta.x - tb.x) * 0.30f, 5.0f, 30.0f); // add a bit of extra slack. - ta.x += (window->Pos.x < next_window->Pos.x) ? -0.5f : +0.5f; // to avoid numerical issues - tb.y = ta.y + ImMax((tb.y - extra) - ta.y, -100.0f); // triangle is maximum 200 high to limit the slope and the bias toward large sub-menus // FIXME: Multiply by fb_scale? - tc.y = ta.y + ImMin((tc.y + extra) - ta.y, +100.0f); - moving_within_opened_triangle = ImTriangleContainsPoint(ta, tb, tc, g.IO.MousePos); - //window->DrawList->PushClipRectFullScreen(); window->DrawList->AddTriangleFilled(ta, tb, tc, moving_within_opened_triangle ? IM_COL32(0,128,0,128) : IM_COL32(128,0,0,128)); window->DrawList->PopClipRect(); // Debug - } - } + bool want_open = false, want_close = false; + if (window->DC.LayoutType == ImGuiLayoutType_Vertical) // (window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) + { + // Implement http://bjk5.com/post/44698559168/breaking-down-amazons-mega-dropdown to avoid using timers, so menus feels more reactive. + bool moving_within_opened_triangle = false; + if (g.HoveredWindow == window && g.OpenPopupStack.Size > g.CurrentPopupStack.Size && g.OpenPopupStack[g.CurrentPopupStack.Size].ParentWindow == window && !(window->Flags & ImGuiWindowFlags_MenuBar)) + { + if (ImGuiWindow* next_window = g.OpenPopupStack[g.CurrentPopupStack.Size].Window) + { + ImRect next_window_rect = next_window->Rect(); + ImVec2 ta = g.IO.MousePos - g.IO.MouseDelta; + ImVec2 tb = (window->Pos.x < next_window->Pos.x) ? next_window_rect.GetTL() : next_window_rect.GetTR(); + ImVec2 tc = (window->Pos.x < next_window->Pos.x) ? next_window_rect.GetBL() : next_window_rect.GetBR(); + float extra = ImClamp(fabsf(ta.x - tb.x) * 0.30f, 5.0f, 30.0f); // add a bit of extra slack. + ta.x += (window->Pos.x < next_window->Pos.x) ? -0.5f : +0.5f; // to avoid numerical issues + tb.y = ta.y + ImMax((tb.y - extra) - ta.y, -100.0f); // triangle is maximum 200 high to limit the slope and the bias toward large sub-menus // FIXME: Multiply by fb_scale? + tc.y = ta.y + ImMin((tc.y + extra) - ta.y, +100.0f); + moving_within_opened_triangle = ImTriangleContainsPoint(ta, tb, tc, g.IO.MousePos); + //window->DrawList->PushClipRectFullScreen(); window->DrawList->AddTriangleFilled(ta, tb, tc, moving_within_opened_triangle ? IM_COL32(0,128,0,128) : IM_COL32(128,0,0,128)); window->DrawList->PopClipRect(); // Debug + } + } - want_close = (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_within_opened_triangle); - want_open = (!menu_is_open && hovered && !moving_within_opened_triangle) || (!menu_is_open && hovered && pressed); + want_close = (menu_is_open && !hovered && g.HoveredWindow == window && g.HoveredIdPreviousFrame != 0 && g.HoveredIdPreviousFrame != id && !moving_within_opened_triangle); + want_open = (!menu_is_open && hovered && !moving_within_opened_triangle) || (!menu_is_open && hovered && pressed); - if (g.NavActivateId == id) - { - want_close = menu_is_open; - want_open = !menu_is_open; - } - if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Right) // Nav-Right to open - { - want_open = true; - NavMoveRequestCancel(); - } - } - else - { - // Menu bar - if (menu_is_open && pressed && menuset_is_open) // Click an open menu again to close it - { - want_close = true; - want_open = menu_is_open = false; - } - else if (pressed || (hovered && menuset_is_open && !menu_is_open)) // First click to open, then hover to open others - { - want_open = true; - } - else if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Down) // Nav-Down to open - { - want_open = true; - NavMoveRequestCancel(); - } - } + if (g.NavActivateId == id) + { + want_close = menu_is_open; + want_open = !menu_is_open; + } + if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Right) // Nav-Right to open + { + want_open = true; + NavMoveRequestCancel(); + } + } + else + { + // Menu bar + if (menu_is_open && pressed && menuset_is_open) // Click an open menu again to close it + { + want_close = true; + want_open = menu_is_open = false; + } + else if (pressed || (hovered && menuset_is_open && !menu_is_open)) // First click to open, then hover to open others + { + want_open = true; + } + else if (g.NavId == id && g.NavMoveRequest && g.NavMoveDir == ImGuiDir_Down) // Nav-Down to open + { + want_open = true; + NavMoveRequestCancel(); + } + } - if (!enabled) // explicitly close if an open menu becomes disabled, facilitate users code a lot in pattern such as 'if (BeginMenu("options", has_object)) { ..use object.. }' - want_close = true; - if (want_close && IsPopupOpen(id)) - ClosePopupToLevel(g.CurrentPopupStack.Size); + if (!enabled) // explicitly close if an open menu becomes disabled, facilitate users code a lot in pattern such as 'if (BeginMenu("options", has_object)) { ..use object.. }' + want_close = true; + if (want_close && IsPopupOpen(id)) + ClosePopupToLevel(g.CurrentPopupStack.Size); - if (!menu_is_open && want_open && g.OpenPopupStack.Size > g.CurrentPopupStack.Size) - { - // Don't recycle same menu level in the same frame, first close the other menu and yield for a frame. - OpenPopup(label); - return false; - } + if (!menu_is_open && want_open && g.OpenPopupStack.Size > g.CurrentPopupStack.Size) + { + // Don't recycle same menu level in the same frame, first close the other menu and yield for a frame. + OpenPopup(label); + return false; + } - menu_is_open |= want_open; - if (want_open) - OpenPopup(label); + menu_is_open |= want_open; + if (want_open) + OpenPopup(label); - if (menu_is_open) - { - SetNextWindowPos(popup_pos, ImGuiCond_Always); - ImGuiWindowFlags flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ((window->Flags & (ImGuiWindowFlags_Popup|ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu|ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); - menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) - } + if (menu_is_open) + { + SetNextWindowPos(popup_pos, ImGuiCond_Always); + ImGuiWindowFlags flags = ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoSavedSettings | ((window->Flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_ChildMenu)) ? ImGuiWindowFlags_ChildMenu | ImGuiWindowFlags_ChildWindow : ImGuiWindowFlags_ChildMenu); + menu_is_open = BeginPopupEx(id, flags); // menu_is_open can be 'false' when the popup is completely clipped (e.g. zero size display) + } - return menu_is_open; + return menu_is_open; } void ImGui::EndMenu() { - // Nav: When a left move request _within our child menu_ failed, close the menu. - // A menu doesn't close itself because EndMenuBar() wants the catch the last Left<>Right inputs. - // However it means that with the current code, a BeginMenu() from outside another menu or a menu-bar won't be closable with the Left direction. - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - if (g.NavWindow && g.NavWindow->ParentWindow == window && g.NavMoveDir == ImGuiDir_Left && NavMoveRequestButNoResultYet() && window->DC.LayoutType == ImGuiLayoutType_Vertical) - { - ClosePopupToLevel(g.OpenPopupStack.Size - 1); - NavMoveRequestCancel(); - } + // Nav: When a left move request _within our child menu_ failed, close the menu. + // A menu doesn't close itself because EndMenuBar() wants the catch the last Left<>Right inputs. + // However it means that with the current code, a BeginMenu() from outside another menu or a menu-bar won't be closable with the Left direction. + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + if (g.NavWindow && g.NavWindow->ParentWindow == window && g.NavMoveDir == ImGuiDir_Left && NavMoveRequestButNoResultYet() && window->DC.LayoutType == ImGuiLayoutType_Vertical) + { + ClosePopupToLevel(g.OpenPopupStack.Size - 1); + NavMoveRequestCancel(); + } - EndPopup(); + EndPopup(); } // Note: only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set. void ImGui::ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags) { - ImGuiContext& g = *GImGui; + ImGuiContext& g = *GImGui; - int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]); - BeginTooltipEx(0, true); - - const char* text_end = text ? FindRenderedTextEnd(text, NULL) : text; - if (text_end > text) - { - TextUnformatted(text, text_end); - Separator(); - } + int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]); + BeginTooltipEx(0, true); - ImVec2 sz(g.FontSize * 3 + g.Style.FramePadding.y * 2, g.FontSize * 3 + g.Style.FramePadding.y * 2); - ColorButton("##preview", ImVec4(col[0], col[1], col[2], col[3]), (flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)) | ImGuiColorEditFlags_NoTooltip, sz); - SameLine(); - if (flags & ImGuiColorEditFlags_NoAlpha) - Text("#%02X%02X%02X\nR: %d, G: %d, B: %d\n(%.3f, %.3f, %.3f)", cr, cg, cb, cr, cg, cb, col[0], col[1], col[2]); - else - Text("#%02X%02X%02X%02X\nR:%d, G:%d, B:%d, A:%d\n(%.3f, %.3f, %.3f, %.3f)", cr, cg, cb, ca, cr, cg, cb, ca, col[0], col[1], col[2], col[3]); - EndTooltip(); + const char* text_end = text ? FindRenderedTextEnd(text, NULL) : text; + if (text_end > text) + { + TextUnformatted(text, text_end); + Separator(); + } + + ImVec2 sz(g.FontSize * 3 + g.Style.FramePadding.y * 2, g.FontSize * 3 + g.Style.FramePadding.y * 2); + ColorButton("##preview", ImVec4(col[0], col[1], col[2], col[3]), (flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)) | ImGuiColorEditFlags_NoTooltip, sz); + SameLine(); + if (flags & ImGuiColorEditFlags_NoAlpha) + Text("#%02X%02X%02X\nR: %d, G: %d, B: %d\n(%.3f, %.3f, %.3f)", cr, cg, cb, cr, cg, cb, col[0], col[1], col[2]); + else + Text("#%02X%02X%02X%02X\nR:%d, G:%d, B:%d, A:%d\n(%.3f, %.3f, %.3f, %.3f)", cr, cg, cb, ca, cr, cg, cb, ca, col[0], col[1], col[2], col[3]); + EndTooltip(); } static inline ImU32 ImAlphaBlendColor(ImU32 col_a, ImU32 col_b) { - float t = ((col_b >> IM_COL32_A_SHIFT) & 0xFF) / 255.f; - int r = ImLerp((int)(col_a >> IM_COL32_R_SHIFT) & 0xFF, (int)(col_b >> IM_COL32_R_SHIFT) & 0xFF, t); - int g = ImLerp((int)(col_a >> IM_COL32_G_SHIFT) & 0xFF, (int)(col_b >> IM_COL32_G_SHIFT) & 0xFF, t); - int b = ImLerp((int)(col_a >> IM_COL32_B_SHIFT) & 0xFF, (int)(col_b >> IM_COL32_B_SHIFT) & 0xFF, t); - return IM_COL32(r, g, b, 0xFF); + float t = ((col_b >> IM_COL32_A_SHIFT) & 0xFF) / 255.f; + int r = ImLerp((int)(col_a >> IM_COL32_R_SHIFT) & 0xFF, (int)(col_b >> IM_COL32_R_SHIFT) & 0xFF, t); + int g = ImLerp((int)(col_a >> IM_COL32_G_SHIFT) & 0xFF, (int)(col_b >> IM_COL32_G_SHIFT) & 0xFF, t); + int b = ImLerp((int)(col_a >> IM_COL32_B_SHIFT) & 0xFF, (int)(col_b >> IM_COL32_B_SHIFT) & 0xFF, t); + return IM_COL32(r, g, b, 0xFF); } // NB: This is rather brittle and will show artifact when rounding this enabled if rounded corners overlap multiple cells. Caller currently responsible for avoiding that. // I spent a non reasonable amount of time trying to getting this right for ColorButton with rounding+anti-aliasing+ImGuiColorEditFlags_HalfAlphaPreview flag + various grid sizes and offsets, and eventually gave up... probably more reasonable to disable rounding alltogether. void ImGui::RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU32 col, float grid_step, ImVec2 grid_off, float rounding, int rounding_corners_flags) { - ImGuiWindow* window = GetCurrentWindow(); - if (((col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT) < 0xFF) - { - ImU32 col_bg1 = GetColorU32(ImAlphaBlendColor(IM_COL32(204,204,204,255), col)); - ImU32 col_bg2 = GetColorU32(ImAlphaBlendColor(IM_COL32(128,128,128,255), col)); - window->DrawList->AddRectFilled(p_min, p_max, col_bg1, rounding, rounding_corners_flags); + ImGuiWindow* window = GetCurrentWindow(); + if (((col & IM_COL32_A_MASK) >> IM_COL32_A_SHIFT) < 0xFF) + { + ImU32 col_bg1 = GetColorU32(ImAlphaBlendColor(IM_COL32(204, 204, 204, 255), col)); + ImU32 col_bg2 = GetColorU32(ImAlphaBlendColor(IM_COL32(128, 128, 128, 255), col)); + window->DrawList->AddRectFilled(p_min, p_max, col_bg1, rounding, rounding_corners_flags); - int yi = 0; - for (float y = p_min.y + grid_off.y; y < p_max.y; y += grid_step, yi++) - { - float y1 = ImClamp(y, p_min.y, p_max.y), y2 = ImMin(y + grid_step, p_max.y); - if (y2 <= y1) - continue; - for (float x = p_min.x + grid_off.x + (yi & 1) * grid_step; x < p_max.x; x += grid_step * 2.0f) - { - float x1 = ImClamp(x, p_min.x, p_max.x), x2 = ImMin(x + grid_step, p_max.x); - if (x2 <= x1) - continue; - int rounding_corners_flags_cell = 0; - if (y1 <= p_min.y) { if (x1 <= p_min.x) rounding_corners_flags_cell |= ImDrawCornerFlags_TopLeft; if (x2 >= p_max.x) rounding_corners_flags_cell |= ImDrawCornerFlags_TopRight; } - if (y2 >= p_max.y) { if (x1 <= p_min.x) rounding_corners_flags_cell |= ImDrawCornerFlags_BotLeft; if (x2 >= p_max.x) rounding_corners_flags_cell |= ImDrawCornerFlags_BotRight; } - rounding_corners_flags_cell &= rounding_corners_flags; - window->DrawList->AddRectFilled(ImVec2(x1,y1), ImVec2(x2,y2), col_bg2, rounding_corners_flags_cell ? rounding : 0.0f, rounding_corners_flags_cell); - } - } - } - else - { - window->DrawList->AddRectFilled(p_min, p_max, col, rounding, rounding_corners_flags); - } + int yi = 0; + for (float y = p_min.y + grid_off.y; y < p_max.y; y += grid_step, yi++) + { + float y1 = ImClamp(y, p_min.y, p_max.y), y2 = ImMin(y + grid_step, p_max.y); + if (y2 <= y1) + continue; + for (float x = p_min.x + grid_off.x + (yi & 1) * grid_step; x < p_max.x; x += grid_step * 2.0f) + { + float x1 = ImClamp(x, p_min.x, p_max.x), x2 = ImMin(x + grid_step, p_max.x); + if (x2 <= x1) + continue; + int rounding_corners_flags_cell = 0; + if (y1 <= p_min.y) + { + if (x1 <= p_min.x) rounding_corners_flags_cell |= ImDrawCornerFlags_TopLeft; + if (x2 >= p_max.x) rounding_corners_flags_cell |= ImDrawCornerFlags_TopRight; + } + if (y2 >= p_max.y) + { + if (x1 <= p_min.x) rounding_corners_flags_cell |= ImDrawCornerFlags_BotLeft; + if (x2 >= p_max.x) rounding_corners_flags_cell |= ImDrawCornerFlags_BotRight; + } + rounding_corners_flags_cell &= rounding_corners_flags; + window->DrawList->AddRectFilled(ImVec2(x1, y1), ImVec2(x2, y2), col_bg2, rounding_corners_flags_cell ? rounding : 0.0f, rounding_corners_flags_cell); + } + } + } + else + { + window->DrawList->AddRectFilled(p_min, p_max, col, rounding, rounding_corners_flags); + } } void ImGui::SetColorEditOptions(ImGuiColorEditFlags flags) { - ImGuiContext& g = *GImGui; - if ((flags & ImGuiColorEditFlags__InputsMask) == 0) - flags |= ImGuiColorEditFlags__OptionsDefault & ImGuiColorEditFlags__InputsMask; - if ((flags & ImGuiColorEditFlags__DataTypeMask) == 0) - flags |= ImGuiColorEditFlags__OptionsDefault & ImGuiColorEditFlags__DataTypeMask; - if ((flags & ImGuiColorEditFlags__PickerMask) == 0) - flags |= ImGuiColorEditFlags__OptionsDefault & ImGuiColorEditFlags__PickerMask; - IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags__InputsMask))); // Check only 1 option is selected - IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags__DataTypeMask))); // Check only 1 option is selected - IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags__PickerMask))); // Check only 1 option is selected - g.ColorEditOptions = flags; + ImGuiContext& g = *GImGui; + if ((flags & ImGuiColorEditFlags__InputsMask) == 0) + flags |= ImGuiColorEditFlags__OptionsDefault & ImGuiColorEditFlags__InputsMask; + if ((flags & ImGuiColorEditFlags__DataTypeMask) == 0) + flags |= ImGuiColorEditFlags__OptionsDefault & ImGuiColorEditFlags__DataTypeMask; + if ((flags & ImGuiColorEditFlags__PickerMask) == 0) + flags |= ImGuiColorEditFlags__OptionsDefault & ImGuiColorEditFlags__PickerMask; + IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags__InputsMask))); // Check only 1 option is selected + IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags__DataTypeMask))); // Check only 1 option is selected + IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags__PickerMask))); // Check only 1 option is selected + g.ColorEditOptions = flags; } // A little colored square. Return true when clicked. @@ -11367,900 +11679,913 @@ void ImGui::SetColorEditOptions(ImGuiColorEditFlags flags) // 'desc_id' is not called 'label' because we don't display it next to the button, but only in the tooltip. bool ImGui::ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags, ImVec2 size) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - const ImGuiID id = window->GetID(desc_id); - float default_size = GetFrameHeight(); - if (size.x == 0.0f) - size.x = default_size; - if (size.y == 0.0f) - size.y = default_size; - const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); - ItemSize(bb, (size.y >= default_size) ? g.Style.FramePadding.y : 0.0f); - if (!ItemAdd(bb, id)) - return false; + ImGuiContext& g = *GImGui; + const ImGuiID id = window->GetID(desc_id); + float default_size = GetFrameHeight(); + if (size.x == 0.0f) + size.x = default_size; + if (size.y == 0.0f) + size.y = default_size; + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); + ItemSize(bb, (size.y >= default_size) ? g.Style.FramePadding.y : 0.0f); + if (!ItemAdd(bb, id)) + return false; - bool hovered, held; - bool pressed = ButtonBehavior(bb, id, &hovered, &held); + bool hovered, held; + bool pressed = ButtonBehavior(bb, id, &hovered, &held); - if (flags & ImGuiColorEditFlags_NoAlpha) - flags &= ~(ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf); - - ImVec4 col_without_alpha(col.x, col.y, col.z, 1.0f); - float grid_step = ImMin(size.x, size.y) / 2.99f; - float rounding = ImMin(g.Style.FrameRounding, grid_step * 0.5f); - ImRect bb_inner = bb; - float off = -0.75f; // The border (using Col_FrameBg) tends to look off when color is near-opaque and rounding is enabled. This offset seemed like a good middle ground to reduce those artifacts. - bb_inner.Expand(off); - if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col.w < 1.0f) - { - float mid_x = (float)(int)((bb_inner.Min.x + bb_inner.Max.x) * 0.5f + 0.5f); - RenderColorRectWithAlphaCheckerboard(ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col), grid_step, ImVec2(-grid_step + off, off), rounding, ImDrawCornerFlags_TopRight| ImDrawCornerFlags_BotRight); - window->DrawList->AddRectFilled(bb_inner.Min, ImVec2(mid_x, bb_inner.Max.y), GetColorU32(col_without_alpha), rounding, ImDrawCornerFlags_TopLeft|ImDrawCornerFlags_BotLeft); - } - else - { - // Because GetColorU32() multiplies by the global style Alpha and we don't want to display a checkerboard if the source code had no alpha - ImVec4 col_source = (flags & ImGuiColorEditFlags_AlphaPreview) ? col : col_without_alpha; - if (col_source.w < 1.0f) - RenderColorRectWithAlphaCheckerboard(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), grid_step, ImVec2(off, off), rounding); - else - window->DrawList->AddRectFilled(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), rounding, ImDrawCornerFlags_All); - } - RenderNavHighlight(bb, id); - if (g.Style.FrameBorderSize > 0.0f) - RenderFrameBorder(bb.Min, bb.Max, rounding); - else - window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color button are often in need of some sort of border + if (flags & ImGuiColorEditFlags_NoAlpha) + flags &= ~(ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf); - // Drag and Drop Source - if (g.ActiveId == id && BeginDragDropSource()) // NB: The ActiveId test is merely an optional micro-optimization - { - if (flags & ImGuiColorEditFlags_NoAlpha) - SetDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F, &col, sizeof(float) * 3, ImGuiCond_Once); - else - SetDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F, &col, sizeof(float) * 4, ImGuiCond_Once); - ColorButton(desc_id, col, flags); - SameLine(); - TextUnformatted("Color"); - EndDragDropSource(); - hovered = false; - } + ImVec4 col_without_alpha(col.x, col.y, col.z, 1.0f); + float grid_step = ImMin(size.x, size.y) / 2.99f; + float rounding = ImMin(g.Style.FrameRounding, grid_step * 0.5f); + ImRect bb_inner = bb; + float off = -0.75f; // The border (using Col_FrameBg) tends to look off when color is near-opaque and rounding is enabled. This offset seemed like a good middle ground to reduce those artifacts. + bb_inner.Expand(off); + if ((flags & ImGuiColorEditFlags_AlphaPreviewHalf) && col.w < 1.0f) + { + float mid_x = (float)(int)((bb_inner.Min.x + bb_inner.Max.x) * 0.5f + 0.5f); + RenderColorRectWithAlphaCheckerboard(ImVec2(bb_inner.Min.x + grid_step, bb_inner.Min.y), bb_inner.Max, GetColorU32(col), grid_step, ImVec2(-grid_step + off, off), rounding, ImDrawCornerFlags_TopRight | ImDrawCornerFlags_BotRight); + window->DrawList->AddRectFilled(bb_inner.Min, ImVec2(mid_x, bb_inner.Max.y), GetColorU32(col_without_alpha), rounding, ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotLeft); + } + else + { + // Because GetColorU32() multiplies by the global style Alpha and we don't want to display a checkerboard if the source code had no alpha + ImVec4 col_source = (flags & ImGuiColorEditFlags_AlphaPreview) ? col : col_without_alpha; + if (col_source.w < 1.0f) + RenderColorRectWithAlphaCheckerboard(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), grid_step, ImVec2(off, off), rounding); + else + window->DrawList->AddRectFilled(bb_inner.Min, bb_inner.Max, GetColorU32(col_source), rounding, ImDrawCornerFlags_All); + } + RenderNavHighlight(bb, id); + if (g.Style.FrameBorderSize > 0.0f) + RenderFrameBorder(bb.Min, bb.Max, rounding); + else + window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_FrameBg), rounding); // Color button are often in need of some sort of border - // Tooltip - if (!(flags & ImGuiColorEditFlags_NoTooltip) && hovered) - ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)); + // Drag and Drop Source + if (g.ActiveId == id && BeginDragDropSource()) // NB: The ActiveId test is merely an optional micro-optimization + { + if (flags & ImGuiColorEditFlags_NoAlpha) + SetDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F, &col, sizeof(float) * 3, ImGuiCond_Once); + else + SetDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F, &col, sizeof(float) * 4, ImGuiCond_Once); + ColorButton(desc_id, col, flags); + SameLine(); + TextUnformatted("Color"); + EndDragDropSource(); + hovered = false; + } - return pressed; + // Tooltip + if (!(flags & ImGuiColorEditFlags_NoTooltip) && hovered) + ColorTooltip(desc_id, &col.x, flags & (ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf)); + + return pressed; } bool ImGui::ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags) { - return ColorEdit4(label, col, flags | ImGuiColorEditFlags_NoAlpha); + return ColorEdit4(label, col, flags | ImGuiColorEditFlags_NoAlpha); } void ImGui::ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags) { - bool allow_opt_inputs = !(flags & ImGuiColorEditFlags__InputsMask); - bool allow_opt_datatype = !(flags & ImGuiColorEditFlags__DataTypeMask); - if ((!allow_opt_inputs && !allow_opt_datatype) || !BeginPopup("context")) - return; - ImGuiContext& g = *GImGui; - ImGuiColorEditFlags opts = g.ColorEditOptions; - if (allow_opt_inputs) - { - if (RadioButton("RGB", (opts & ImGuiColorEditFlags_RGB) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_RGB; - if (RadioButton("HSV", (opts & ImGuiColorEditFlags_HSV) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_HSV; - if (RadioButton("HEX", (opts & ImGuiColorEditFlags_HEX) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_HEX; - } - if (allow_opt_datatype) - { - if (allow_opt_inputs) Separator(); - if (RadioButton("0..255", (opts & ImGuiColorEditFlags_Uint8) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__DataTypeMask) | ImGuiColorEditFlags_Uint8; - if (RadioButton("0.00..1.00", (opts & ImGuiColorEditFlags_Float) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__DataTypeMask) | ImGuiColorEditFlags_Float; - } + bool allow_opt_inputs = !(flags & ImGuiColorEditFlags__InputsMask); + bool allow_opt_datatype = !(flags & ImGuiColorEditFlags__DataTypeMask); + if ((!allow_opt_inputs && !allow_opt_datatype) || !BeginPopup("context")) + return; + ImGuiContext& g = *GImGui; + ImGuiColorEditFlags opts = g.ColorEditOptions; + if (allow_opt_inputs) + { + if (RadioButton("RGB", (opts & ImGuiColorEditFlags_RGB) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_RGB; + if (RadioButton("HSV", (opts & ImGuiColorEditFlags_HSV) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_HSV; + if (RadioButton("HEX", (opts & ImGuiColorEditFlags_HEX) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__InputsMask) | ImGuiColorEditFlags_HEX; + } + if (allow_opt_datatype) + { + if (allow_opt_inputs) Separator(); + if (RadioButton("0..255", (opts & ImGuiColorEditFlags_Uint8) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__DataTypeMask) | ImGuiColorEditFlags_Uint8; + if (RadioButton("0.00..1.00", (opts & ImGuiColorEditFlags_Float) ? 1 : 0)) opts = (opts & ~ImGuiColorEditFlags__DataTypeMask) | ImGuiColorEditFlags_Float; + } - if (allow_opt_inputs || allow_opt_datatype) - Separator(); - if (Button("Copy as..", ImVec2(-1,0))) - OpenPopup("Copy"); - if (BeginPopup("Copy")) - { - int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]); - char buf[64]; - ImFormatString(buf, IM_ARRAYSIZE(buf), "(%.3ff, %.3ff, %.3ff, %.3ff)", col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]); - if (Selectable(buf)) - SetClipboardText(buf); - ImFormatString(buf, IM_ARRAYSIZE(buf), "(%d,%d,%d,%d)", cr, cg, cb, ca); - if (Selectable(buf)) - SetClipboardText(buf); - if (flags & ImGuiColorEditFlags_NoAlpha) - ImFormatString(buf, IM_ARRAYSIZE(buf), "0x%02X%02X%02X", cr, cg, cb); - else - ImFormatString(buf, IM_ARRAYSIZE(buf), "0x%02X%02X%02X%02X", cr, cg, cb, ca); - if (Selectable(buf)) - SetClipboardText(buf); - EndPopup(); - } + if (allow_opt_inputs || allow_opt_datatype) + Separator(); + if (Button("Copy as..", ImVec2(-1, 0))) + OpenPopup("Copy"); + if (BeginPopup("Copy")) + { + int cr = IM_F32_TO_INT8_SAT(col[0]), cg = IM_F32_TO_INT8_SAT(col[1]), cb = IM_F32_TO_INT8_SAT(col[2]), ca = (flags & ImGuiColorEditFlags_NoAlpha) ? 255 : IM_F32_TO_INT8_SAT(col[3]); + char buf[64]; + ImFormatString(buf, IM_ARRAYSIZE(buf), "(%.3ff, %.3ff, %.3ff, %.3ff)", col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]); + if (Selectable(buf)) + SetClipboardText(buf); + ImFormatString(buf, IM_ARRAYSIZE(buf), "(%d,%d,%d,%d)", cr, cg, cb, ca); + if (Selectable(buf)) + SetClipboardText(buf); + if (flags & ImGuiColorEditFlags_NoAlpha) + ImFormatString(buf, IM_ARRAYSIZE(buf), "0x%02X%02X%02X", cr, cg, cb); + else + ImFormatString(buf, IM_ARRAYSIZE(buf), "0x%02X%02X%02X%02X", cr, cg, cb, ca); + if (Selectable(buf)) + SetClipboardText(buf); + EndPopup(); + } - g.ColorEditOptions = opts; - EndPopup(); + g.ColorEditOptions = opts; + EndPopup(); } static void ColorPickerOptionsPopup(ImGuiColorEditFlags flags, const float* ref_col) { - bool allow_opt_picker = !(flags & ImGuiColorEditFlags__PickerMask); - bool allow_opt_alpha_bar = !(flags & ImGuiColorEditFlags_NoAlpha) && !(flags & ImGuiColorEditFlags_AlphaBar); - if ((!allow_opt_picker && !allow_opt_alpha_bar) || !ImGui::BeginPopup("context")) - return; - ImGuiContext& g = *GImGui; - if (allow_opt_picker) - { - ImVec2 picker_size(g.FontSize * 8, ImMax(g.FontSize * 8 - (ImGui::GetFrameHeight() + g.Style.ItemInnerSpacing.x), 1.0f)); // FIXME: Picker size copied from main picker function - ImGui::PushItemWidth(picker_size.x); - for (int picker_type = 0; picker_type < 2; picker_type++) - { - // Draw small/thumbnail version of each picker type (over an invisible button for selection) - if (picker_type > 0) ImGui::Separator(); - ImGui::PushID(picker_type); - ImGuiColorEditFlags picker_flags = ImGuiColorEditFlags_NoInputs|ImGuiColorEditFlags_NoOptions|ImGuiColorEditFlags_NoLabel|ImGuiColorEditFlags_NoSidePreview|(flags & ImGuiColorEditFlags_NoAlpha); - if (picker_type == 0) picker_flags |= ImGuiColorEditFlags_PickerHueBar; - if (picker_type == 1) picker_flags |= ImGuiColorEditFlags_PickerHueWheel; - ImVec2 backup_pos = ImGui::GetCursorScreenPos(); - if (ImGui::Selectable("##selectable", false, 0, picker_size)) // By default, Selectable() is closing popup - g.ColorEditOptions = (g.ColorEditOptions & ~ImGuiColorEditFlags__PickerMask) | (picker_flags & ImGuiColorEditFlags__PickerMask); - ImGui::SetCursorScreenPos(backup_pos); - ImVec4 dummy_ref_col; - memcpy(&dummy_ref_col.x, ref_col, sizeof(float) * (picker_flags & ImGuiColorEditFlags_NoAlpha ? 3 : 4)); - ImGui::ColorPicker4("##dummypicker", &dummy_ref_col.x, picker_flags); - ImGui::PopID(); - } - ImGui::PopItemWidth(); - } - if (allow_opt_alpha_bar) - { - if (allow_opt_picker) ImGui::Separator(); - ImGui::CheckboxFlags("Alpha Bar", (unsigned int*)&g.ColorEditOptions, ImGuiColorEditFlags_AlphaBar); - } - ImGui::EndPopup(); + bool allow_opt_picker = !(flags & ImGuiColorEditFlags__PickerMask); + bool allow_opt_alpha_bar = !(flags & ImGuiColorEditFlags_NoAlpha) && !(flags & ImGuiColorEditFlags_AlphaBar); + if ((!allow_opt_picker && !allow_opt_alpha_bar) || !ImGui::BeginPopup("context")) + return; + ImGuiContext& g = *GImGui; + if (allow_opt_picker) + { + ImVec2 picker_size(g.FontSize * 8, ImMax(g.FontSize * 8 - (ImGui::GetFrameHeight() + g.Style.ItemInnerSpacing.x), 1.0f)); // FIXME: Picker size copied from main picker function + ImGui::PushItemWidth(picker_size.x); + for (int picker_type = 0; picker_type < 2; picker_type++) + { + // Draw small/thumbnail version of each picker type (over an invisible button for selection) + if (picker_type > 0) ImGui::Separator(); + ImGui::PushID(picker_type); + ImGuiColorEditFlags picker_flags = ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_NoSidePreview | (flags & ImGuiColorEditFlags_NoAlpha); + if (picker_type == 0) picker_flags |= ImGuiColorEditFlags_PickerHueBar; + if (picker_type == 1) picker_flags |= ImGuiColorEditFlags_PickerHueWheel; + ImVec2 backup_pos = ImGui::GetCursorScreenPos(); + if (ImGui::Selectable("##selectable", false, 0, picker_size)) // By default, Selectable() is closing popup + g.ColorEditOptions = (g.ColorEditOptions & ~ImGuiColorEditFlags__PickerMask) | (picker_flags & ImGuiColorEditFlags__PickerMask); + ImGui::SetCursorScreenPos(backup_pos); + ImVec4 dummy_ref_col; + memcpy(&dummy_ref_col.x, ref_col, sizeof(float) * (picker_flags & ImGuiColorEditFlags_NoAlpha ? 3 : 4)); + ImGui::ColorPicker4("##dummypicker", &dummy_ref_col.x, picker_flags); + ImGui::PopID(); + } + ImGui::PopItemWidth(); + } + if (allow_opt_alpha_bar) + { + if (allow_opt_picker) ImGui::Separator(); + ImGui::CheckboxFlags("Alpha Bar", (unsigned int*)&g.ColorEditOptions, ImGuiColorEditFlags_AlphaBar); + } + ImGui::EndPopup(); } -// Edit colors components (each component in 0.0f..1.0f range). +// Edit colors components (each component in 0.0f..1.0f range). // See enum ImGuiColorEditFlags_ for available options. e.g. Only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set. // With typical options: Left-click on colored square to open color picker. Right-click to open option menu. CTRL-Click over input fields to edit them and TAB to go to next item. bool ImGui::ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return false; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return false; - ImGuiContext& g = *GImGui; - const ImGuiStyle& style = g.Style; - const float square_sz = GetFrameHeight(); - const float w_extra = (flags & ImGuiColorEditFlags_NoSmallPreview) ? 0.0f : (square_sz + style.ItemInnerSpacing.x); - const float w_items_all = CalcItemWidth() - w_extra; - const char* label_display_end = FindRenderedTextEnd(label); + ImGuiContext& g = *GImGui; + const ImGuiStyle& style = g.Style; + const float square_sz = GetFrameHeight(); + const float w_extra = (flags & ImGuiColorEditFlags_NoSmallPreview) ? 0.0f : (square_sz + style.ItemInnerSpacing.x); + const float w_items_all = CalcItemWidth() - w_extra; + const char* label_display_end = FindRenderedTextEnd(label); - const bool alpha = (flags & ImGuiColorEditFlags_NoAlpha) == 0; - const bool hdr = (flags & ImGuiColorEditFlags_HDR) != 0; - const int components = alpha ? 4 : 3; - const ImGuiColorEditFlags flags_untouched = flags; + const bool alpha = (flags & ImGuiColorEditFlags_NoAlpha) == 0; + const bool hdr = (flags & ImGuiColorEditFlags_HDR) != 0; + const int components = alpha ? 4 : 3; + const ImGuiColorEditFlags flags_untouched = flags; - BeginGroup(); - PushID(label); + BeginGroup(); + PushID(label); - // If we're not showing any slider there's no point in doing any HSV conversions - if (flags & ImGuiColorEditFlags_NoInputs) - flags = (flags & (~ImGuiColorEditFlags__InputsMask)) | ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_NoOptions; + // If we're not showing any slider there's no point in doing any HSV conversions + if (flags & ImGuiColorEditFlags_NoInputs) + flags = (flags & (~ImGuiColorEditFlags__InputsMask)) | ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_NoOptions; - // Context menu: display and modify options (before defaults are applied) - if (!(flags & ImGuiColorEditFlags_NoOptions)) - ColorEditOptionsPopup(col, flags); - - // Read stored options - if (!(flags & ImGuiColorEditFlags__InputsMask)) - flags |= (g.ColorEditOptions & ImGuiColorEditFlags__InputsMask); - if (!(flags & ImGuiColorEditFlags__DataTypeMask)) - flags |= (g.ColorEditOptions & ImGuiColorEditFlags__DataTypeMask); - if (!(flags & ImGuiColorEditFlags__PickerMask)) - flags |= (g.ColorEditOptions & ImGuiColorEditFlags__PickerMask); - flags |= (g.ColorEditOptions & ~(ImGuiColorEditFlags__InputsMask | ImGuiColorEditFlags__DataTypeMask | ImGuiColorEditFlags__PickerMask)); + // Context menu: display and modify options (before defaults are applied) + if (!(flags & ImGuiColorEditFlags_NoOptions)) + ColorEditOptionsPopup(col, flags); - // Convert to the formats we need - float f[4] = { col[0], col[1], col[2], alpha ? col[3] : 1.0f }; - if (flags & ImGuiColorEditFlags_HSV) - ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]); - int i[4] = { IM_F32_TO_INT8_UNBOUND(f[0]), IM_F32_TO_INT8_UNBOUND(f[1]), IM_F32_TO_INT8_UNBOUND(f[2]), IM_F32_TO_INT8_UNBOUND(f[3]) }; + // Read stored options + if (!(flags & ImGuiColorEditFlags__InputsMask)) + flags |= (g.ColorEditOptions & ImGuiColorEditFlags__InputsMask); + if (!(flags & ImGuiColorEditFlags__DataTypeMask)) + flags |= (g.ColorEditOptions & ImGuiColorEditFlags__DataTypeMask); + if (!(flags & ImGuiColorEditFlags__PickerMask)) + flags |= (g.ColorEditOptions & ImGuiColorEditFlags__PickerMask); + flags |= (g.ColorEditOptions & ~(ImGuiColorEditFlags__InputsMask | ImGuiColorEditFlags__DataTypeMask | ImGuiColorEditFlags__PickerMask)); - bool value_changed = false; - bool value_changed_as_float = false; + // Convert to the formats we need + float f[4] = {col[0], col[1], col[2], alpha ? col[3] : 1.0f}; + if (flags & ImGuiColorEditFlags_HSV) + ColorConvertRGBtoHSV(f[0], f[1], f[2], f[0], f[1], f[2]); + int i[4] = {IM_F32_TO_INT8_UNBOUND(f[0]), IM_F32_TO_INT8_UNBOUND(f[1]), IM_F32_TO_INT8_UNBOUND(f[2]), IM_F32_TO_INT8_UNBOUND(f[3])}; - if ((flags & (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV)) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0) - { - // RGB/HSV 0..255 Sliders - const float w_item_one = ImMax(1.0f, (float)(int)((w_items_all - (style.ItemInnerSpacing.x) * (components-1)) / (float)components)); - const float w_item_last = ImMax(1.0f, (float)(int)(w_items_all - (w_item_one + style.ItemInnerSpacing.x) * (components-1))); + bool value_changed = false; + bool value_changed_as_float = false; - const bool hide_prefix = (w_item_one <= CalcTextSize((flags & ImGuiColorEditFlags_Float) ? "M:0.000" : "M:000").x); - const char* ids[4] = { "##X", "##Y", "##Z", "##W" }; - const char* fmt_table_int[3][4] = - { - { "%3.0f", "%3.0f", "%3.0f", "%3.0f" }, // Short display - { "R:%3.0f", "G:%3.0f", "B:%3.0f", "A:%3.0f" }, // Long display for RGBA - { "H:%3.0f", "S:%3.0f", "V:%3.0f", "A:%3.0f" } // Long display for HSVA - }; - const char* fmt_table_float[3][4] = - { - { "%0.3f", "%0.3f", "%0.3f", "%0.3f" }, // Short display - { "R:%0.3f", "G:%0.3f", "B:%0.3f", "A:%0.3f" }, // Long display for RGBA - { "H:%0.3f", "S:%0.3f", "V:%0.3f", "A:%0.3f" } // Long display for HSVA - }; - const int fmt_idx = hide_prefix ? 0 : (flags & ImGuiColorEditFlags_HSV) ? 2 : 1; + if ((flags & (ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV)) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0) + { + // RGB/HSV 0..255 Sliders + const float w_item_one = ImMax(1.0f, (float)(int)((w_items_all - (style.ItemInnerSpacing.x) * (components - 1)) / (float)components)); + const float w_item_last = ImMax(1.0f, (float)(int)(w_items_all - (w_item_one + style.ItemInnerSpacing.x) * (components - 1))); - PushItemWidth(w_item_one); - for (int n = 0; n < components; n++) - { - if (n > 0) - SameLine(0, style.ItemInnerSpacing.x); - if (n + 1 == components) - PushItemWidth(w_item_last); - if (flags & ImGuiColorEditFlags_Float) - value_changed = value_changed_as_float = value_changed | DragFloat(ids[n], &f[n], 1.0f/255.0f, 0.0f, hdr ? 0.0f : 1.0f, fmt_table_float[fmt_idx][n]); - else - value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, hdr ? 0 : 255, fmt_table_int[fmt_idx][n]); - if (!(flags & ImGuiColorEditFlags_NoOptions)) - OpenPopupOnItemClick("context"); - } - PopItemWidth(); - PopItemWidth(); - } - else if ((flags & ImGuiColorEditFlags_HEX) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0) - { - // RGB Hexadecimal Input - char buf[64]; - if (alpha) - ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", ImClamp(i[0],0,255), ImClamp(i[1],0,255), ImClamp(i[2],0,255), ImClamp(i[3],0,255)); - else - ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", ImClamp(i[0],0,255), ImClamp(i[1],0,255), ImClamp(i[2],0,255)); - PushItemWidth(w_items_all); - if (InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase)) - { - value_changed = true; - char* p = buf; - while (*p == '#' || ImCharIsSpace(*p)) - p++; - i[0] = i[1] = i[2] = i[3] = 0; - if (alpha) - sscanf(p, "%02X%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2], (unsigned int*)&i[3]); // Treat at unsigned (%X is unsigned) - else - sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2]); - } - if (!(flags & ImGuiColorEditFlags_NoOptions)) - OpenPopupOnItemClick("context"); - PopItemWidth(); - } + const bool hide_prefix = (w_item_one <= CalcTextSize((flags & ImGuiColorEditFlags_Float) ? "M:0.000" : "M:000").x); + const char* ids[4] = {"##X", "##Y", "##Z", "##W"}; + const char* fmt_table_int[3][4] = + { + {"%3.0f", "%3.0f", "%3.0f", "%3.0f"}, // Short display + {"R:%3.0f", "G:%3.0f", "B:%3.0f", "A:%3.0f"}, // Long display for RGBA + {"H:%3.0f", "S:%3.0f", "V:%3.0f", "A:%3.0f"} // Long display for HSVA + }; + const char* fmt_table_float[3][4] = + { + {"%0.3f", "%0.3f", "%0.3f", "%0.3f"}, // Short display + {"R:%0.3f", "G:%0.3f", "B:%0.3f", "A:%0.3f"}, // Long display for RGBA + {"H:%0.3f", "S:%0.3f", "V:%0.3f", "A:%0.3f"} // Long display for HSVA + }; + const int fmt_idx = hide_prefix ? 0 : (flags & ImGuiColorEditFlags_HSV) ? 2 : 1; - ImGuiWindow* picker_active_window = NULL; - if (!(flags & ImGuiColorEditFlags_NoSmallPreview)) - { - if (!(flags & ImGuiColorEditFlags_NoInputs)) - SameLine(0, style.ItemInnerSpacing.x); + PushItemWidth(w_item_one); + for (int n = 0; n < components; n++) + { + if (n > 0) + SameLine(0, style.ItemInnerSpacing.x); + if (n + 1 == components) + PushItemWidth(w_item_last); + if (flags & ImGuiColorEditFlags_Float) + value_changed = value_changed_as_float = value_changed | DragFloat(ids[n], &f[n], 1.0f / 255.0f, 0.0f, hdr ? 0.0f : 1.0f, fmt_table_float[fmt_idx][n]); + else + value_changed |= DragInt(ids[n], &i[n], 1.0f, 0, hdr ? 0 : 255, fmt_table_int[fmt_idx][n]); + if (!(flags & ImGuiColorEditFlags_NoOptions)) + OpenPopupOnItemClick("context"); + } + PopItemWidth(); + PopItemWidth(); + } + else if ((flags & ImGuiColorEditFlags_HEX) != 0 && (flags & ImGuiColorEditFlags_NoInputs) == 0) + { + // RGB Hexadecimal Input + char buf[64]; + if (alpha) + ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X%02X", ImClamp(i[0], 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255), ImClamp(i[3], 0, 255)); + else + ImFormatString(buf, IM_ARRAYSIZE(buf), "#%02X%02X%02X", ImClamp(i[0], 0, 255), ImClamp(i[1], 0, 255), ImClamp(i[2], 0, 255)); + PushItemWidth(w_items_all); + if (InputText("##Text", buf, IM_ARRAYSIZE(buf), ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase)) + { + value_changed = true; + char* p = buf; + while (*p == '#' || ImCharIsSpace(*p)) + p++; + i[0] = i[1] = i[2] = i[3] = 0; + if (alpha) + sscanf(p, "%02X%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2], (unsigned int*)&i[3]); // Treat at unsigned (%X is unsigned) + else + sscanf(p, "%02X%02X%02X", (unsigned int*)&i[0], (unsigned int*)&i[1], (unsigned int*)&i[2]); + } + if (!(flags & ImGuiColorEditFlags_NoOptions)) + OpenPopupOnItemClick("context"); + PopItemWidth(); + } - const ImVec4 col_v4(col[0], col[1], col[2], alpha ? col[3] : 1.0f); - if (ColorButton("##ColorButton", col_v4, flags)) - { - if (!(flags & ImGuiColorEditFlags_NoPicker)) - { - // Store current color and open a picker - g.ColorPickerRef = col_v4; - OpenPopup("picker"); - SetNextWindowPos(window->DC.LastItemRect.GetBL() + ImVec2(-1,style.ItemSpacing.y)); - } - } - if (!(flags & ImGuiColorEditFlags_NoOptions)) - OpenPopupOnItemClick("context"); - - if (BeginPopup("picker")) - { - picker_active_window = g.CurrentWindow; - if (label != label_display_end) - { - TextUnformatted(label, label_display_end); - Separator(); - } - ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags__DataTypeMask | ImGuiColorEditFlags__PickerMask | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaBar; - ImGuiColorEditFlags picker_flags = (flags_untouched & picker_flags_to_forward) | ImGuiColorEditFlags__InputsMask | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_AlphaPreviewHalf; - PushItemWidth(square_sz * 12.0f); // Use 256 + bar sizes? - value_changed |= ColorPicker4("##picker", col, picker_flags, &g.ColorPickerRef.x); - PopItemWidth(); - EndPopup(); - } - } + ImGuiWindow* picker_active_window = NULL; + if (!(flags & ImGuiColorEditFlags_NoSmallPreview)) + { + if (!(flags & ImGuiColorEditFlags_NoInputs)) + SameLine(0, style.ItemInnerSpacing.x); - if (label != label_display_end && !(flags & ImGuiColorEditFlags_NoLabel)) - { - SameLine(0, style.ItemInnerSpacing.x); - TextUnformatted(label, label_display_end); - } + const ImVec4 col_v4(col[0], col[1], col[2], alpha ? col[3] : 1.0f); + if (ColorButton("##ColorButton", col_v4, flags)) + { + if (!(flags & ImGuiColorEditFlags_NoPicker)) + { + // Store current color and open a picker + g.ColorPickerRef = col_v4; + OpenPopup("picker"); + SetNextWindowPos(window->DC.LastItemRect.GetBL() + ImVec2(-1, style.ItemSpacing.y)); + } + } + if (!(flags & ImGuiColorEditFlags_NoOptions)) + OpenPopupOnItemClick("context"); - // Convert back - if (picker_active_window == NULL) - { - if (!value_changed_as_float) - for (int n = 0; n < 4; n++) - f[n] = i[n] / 255.0f; - if (flags & ImGuiColorEditFlags_HSV) - ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]); - if (value_changed) - { - col[0] = f[0]; - col[1] = f[1]; - col[2] = f[2]; - if (alpha) - col[3] = f[3]; - } - } + if (BeginPopup("picker")) + { + picker_active_window = g.CurrentWindow; + if (label != label_display_end) + { + TextUnformatted(label, label_display_end); + Separator(); + } + ImGuiColorEditFlags picker_flags_to_forward = ImGuiColorEditFlags__DataTypeMask | ImGuiColorEditFlags__PickerMask | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_AlphaBar; + ImGuiColorEditFlags picker_flags = (flags_untouched & picker_flags_to_forward) | ImGuiColorEditFlags__InputsMask | ImGuiColorEditFlags_NoLabel | ImGuiColorEditFlags_AlphaPreviewHalf; + PushItemWidth(square_sz * 12.0f); // Use 256 + bar sizes? + value_changed |= ColorPicker4("##picker", col, picker_flags, &g.ColorPickerRef.x); + PopItemWidth(); + EndPopup(); + } + } - PopID(); - EndGroup(); + if (label != label_display_end && !(flags & ImGuiColorEditFlags_NoLabel)) + { + SameLine(0, style.ItemInnerSpacing.x); + TextUnformatted(label, label_display_end); + } - // Drag and Drop Target - if ((window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HoveredRect) && BeginDragDropTarget()) // NB: The flag test is merely an optional micro-optimization, BeginDragDropTarget() does the same test. - { - if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F)) - { - memcpy((float*)col, payload->Data, sizeof(float) * 3); - value_changed = true; - } - if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F)) - { - memcpy((float*)col, payload->Data, sizeof(float) * components); - value_changed = true; - } - EndDragDropTarget(); - } + // Convert back + if (picker_active_window == NULL) + { + if (!value_changed_as_float) + for (int n = 0; n < 4; n++) + f[n] = i[n] / 255.0f; + if (flags & ImGuiColorEditFlags_HSV) + ColorConvertHSVtoRGB(f[0], f[1], f[2], f[0], f[1], f[2]); + if (value_changed) + { + col[0] = f[0]; + col[1] = f[1]; + col[2] = f[2]; + if (alpha) + col[3] = f[3]; + } + } - // When picker is being actively used, use its active id so IsItemActive() will function on ColorEdit4(). - if (picker_active_window && g.ActiveId != 0 && g.ActiveIdWindow == picker_active_window) - window->DC.LastItemId = g.ActiveId; + PopID(); + EndGroup(); - return value_changed; + // Drag and Drop Target + if ((window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HoveredRect) && BeginDragDropTarget()) // NB: The flag test is merely an optional micro-optimization, BeginDragDropTarget() does the same test. + { + if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F)) + { + memcpy((float*)col, payload->Data, sizeof(float) * 3); + value_changed = true; + } + if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F)) + { + memcpy((float*)col, payload->Data, sizeof(float) * components); + value_changed = true; + } + EndDragDropTarget(); + } + + // When picker is being actively used, use its active id so IsItemActive() will function on ColorEdit4(). + if (picker_active_window && g.ActiveId != 0 && g.ActiveIdWindow == picker_active_window) + window->DC.LastItemId = g.ActiveId; + + return value_changed; } bool ImGui::ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags) { - float col4[4] = { col[0], col[1], col[2], 1.0f }; - if (!ColorPicker4(label, col4, flags | ImGuiColorEditFlags_NoAlpha)) - return false; - col[0] = col4[0]; col[1] = col4[1]; col[2] = col4[2]; - return true; + float col4[4] = {col[0], col[1], col[2], 1.0f}; + if (!ColorPicker4(label, col4, flags | ImGuiColorEditFlags_NoAlpha)) + return false; + col[0] = col4[0]; + col[1] = col4[1]; + col[2] = col4[2]; + return true; } // 'pos' is position of the arrow tip. half_sz.x is length from base to tip. half_sz.y is length on each side. static void RenderArrow(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, ImGuiDir direction, ImU32 col) { - switch (direction) - { - case ImGuiDir_Left: draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), pos, col); return; - case ImGuiDir_Right: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), pos, col); return; - case ImGuiDir_Up: draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), pos, col); return; - case ImGuiDir_Down: draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), pos, col); return; - case ImGuiDir_None: case ImGuiDir_Count_: break; // Fix warnings - } + switch (direction) + { + case ImGuiDir_Left: + draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), pos, col); + return; + case ImGuiDir_Right: + draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), pos, col); + return; + case ImGuiDir_Up: + draw_list->AddTriangleFilled(ImVec2(pos.x + half_sz.x, pos.y + half_sz.y), ImVec2(pos.x - half_sz.x, pos.y + half_sz.y), pos, col); + return; + case ImGuiDir_Down: + draw_list->AddTriangleFilled(ImVec2(pos.x - half_sz.x, pos.y - half_sz.y), ImVec2(pos.x + half_sz.x, pos.y - half_sz.y), pos, col); + return; + case ImGuiDir_None: + case ImGuiDir_Count_: + break; // Fix warnings + } } static void RenderArrowsForVerticalBar(ImDrawList* draw_list, ImVec2 pos, ImVec2 half_sz, float bar_w) { - RenderArrow(draw_list, ImVec2(pos.x + half_sz.x + 1, pos.y), ImVec2(half_sz.x + 2, half_sz.y + 1), ImGuiDir_Right, IM_COL32_BLACK); - RenderArrow(draw_list, ImVec2(pos.x + half_sz.x, pos.y), half_sz, ImGuiDir_Right, IM_COL32_WHITE); - RenderArrow(draw_list, ImVec2(pos.x + bar_w - half_sz.x - 1, pos.y), ImVec2(half_sz.x + 2, half_sz.y + 1), ImGuiDir_Left, IM_COL32_BLACK); - RenderArrow(draw_list, ImVec2(pos.x + bar_w - half_sz.x, pos.y), half_sz, ImGuiDir_Left, IM_COL32_WHITE); + RenderArrow(draw_list, ImVec2(pos.x + half_sz.x + 1, pos.y), ImVec2(half_sz.x + 2, half_sz.y + 1), ImGuiDir_Right, IM_COL32_BLACK); + RenderArrow(draw_list, ImVec2(pos.x + half_sz.x, pos.y), half_sz, ImGuiDir_Right, IM_COL32_WHITE); + RenderArrow(draw_list, ImVec2(pos.x + bar_w - half_sz.x - 1, pos.y), ImVec2(half_sz.x + 2, half_sz.y + 1), ImGuiDir_Left, IM_COL32_BLACK); + RenderArrow(draw_list, ImVec2(pos.x + bar_w - half_sz.x, pos.y), half_sz, ImGuiDir_Left, IM_COL32_WHITE); } // ColorPicker // Note: only access 3 floats if ImGuiColorEditFlags_NoAlpha flag is set. -// FIXME: we adjust the big color square height based on item width, which may cause a flickering feedback loop (if automatic height makes a vertical scrollbar appears, affecting automatic width..) +// FIXME: we adjust the big color square height based on item width, which may cause a flickering feedback loop (if automatic height makes a vertical scrollbar appears, affecting automatic width..) bool ImGui::ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags, const float* ref_col) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - ImDrawList* draw_list = window->DrawList; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + ImDrawList* draw_list = window->DrawList; - ImGuiStyle& style = g.Style; - ImGuiIO& io = g.IO; + ImGuiStyle& style = g.Style; + ImGuiIO& io = g.IO; - PushID(label); - BeginGroup(); + PushID(label); + BeginGroup(); - if (!(flags & ImGuiColorEditFlags_NoSidePreview)) - flags |= ImGuiColorEditFlags_NoSmallPreview; + if (!(flags & ImGuiColorEditFlags_NoSidePreview)) + flags |= ImGuiColorEditFlags_NoSmallPreview; - // Context menu: display and store options. - if (!(flags & ImGuiColorEditFlags_NoOptions)) - ColorPickerOptionsPopup(flags, col); + // Context menu: display and store options. + if (!(flags & ImGuiColorEditFlags_NoOptions)) + ColorPickerOptionsPopup(flags, col); - // Read stored options - if (!(flags & ImGuiColorEditFlags__PickerMask)) - flags |= ((g.ColorEditOptions & ImGuiColorEditFlags__PickerMask) ? g.ColorEditOptions : ImGuiColorEditFlags__OptionsDefault) & ImGuiColorEditFlags__PickerMask; - IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags__PickerMask))); // Check that only 1 is selected - if (!(flags & ImGuiColorEditFlags_NoOptions)) - flags |= (g.ColorEditOptions & ImGuiColorEditFlags_AlphaBar); + // Read stored options + if (!(flags & ImGuiColorEditFlags__PickerMask)) + flags |= ((g.ColorEditOptions & ImGuiColorEditFlags__PickerMask) ? g.ColorEditOptions : ImGuiColorEditFlags__OptionsDefault) & ImGuiColorEditFlags__PickerMask; + IM_ASSERT(ImIsPowerOfTwo((int)(flags & ImGuiColorEditFlags__PickerMask))); // Check that only 1 is selected + if (!(flags & ImGuiColorEditFlags_NoOptions)) + flags |= (g.ColorEditOptions & ImGuiColorEditFlags_AlphaBar); - // Setup - int components = (flags & ImGuiColorEditFlags_NoAlpha) ? 3 : 4; - bool alpha_bar = (flags & ImGuiColorEditFlags_AlphaBar) && !(flags & ImGuiColorEditFlags_NoAlpha); - ImVec2 picker_pos = window->DC.CursorPos; - float square_sz = GetFrameHeight(); - float bars_width = square_sz; // Arbitrary smallish width of Hue/Alpha picking bars - float sv_picker_size = ImMax(bars_width * 1, CalcItemWidth() - (alpha_bar ? 2 : 1) * (bars_width + style.ItemInnerSpacing.x)); // Saturation/Value picking box - float bar0_pos_x = picker_pos.x + sv_picker_size + style.ItemInnerSpacing.x; - float bar1_pos_x = bar0_pos_x + bars_width + style.ItemInnerSpacing.x; - float bars_triangles_half_sz = (float)(int)(bars_width * 0.20f); + // Setup + int components = (flags & ImGuiColorEditFlags_NoAlpha) ? 3 : 4; + bool alpha_bar = (flags & ImGuiColorEditFlags_AlphaBar) && !(flags & ImGuiColorEditFlags_NoAlpha); + ImVec2 picker_pos = window->DC.CursorPos; + float square_sz = GetFrameHeight(); + float bars_width = square_sz; // Arbitrary smallish width of Hue/Alpha picking bars + float sv_picker_size = ImMax(bars_width * 1, CalcItemWidth() - (alpha_bar ? 2 : 1) * (bars_width + style.ItemInnerSpacing.x)); // Saturation/Value picking box + float bar0_pos_x = picker_pos.x + sv_picker_size + style.ItemInnerSpacing.x; + float bar1_pos_x = bar0_pos_x + bars_width + style.ItemInnerSpacing.x; + float bars_triangles_half_sz = (float)(int)(bars_width * 0.20f); - float backup_initial_col[4]; - memcpy(backup_initial_col, col, components * sizeof(float)); + float backup_initial_col[4]; + memcpy(backup_initial_col, col, components * sizeof(float)); - float wheel_thickness = sv_picker_size * 0.08f; - float wheel_r_outer = sv_picker_size * 0.50f; - float wheel_r_inner = wheel_r_outer - wheel_thickness; - ImVec2 wheel_center(picker_pos.x + (sv_picker_size + bars_width)*0.5f, picker_pos.y + sv_picker_size*0.5f); - - // Note: the triangle is displayed rotated with triangle_pa pointing to Hue, but most coordinates stays unrotated for logic. - float triangle_r = wheel_r_inner - (int)(sv_picker_size * 0.027f); - ImVec2 triangle_pa = ImVec2(triangle_r, 0.0f); // Hue point. - ImVec2 triangle_pb = ImVec2(triangle_r * -0.5f, triangle_r * -0.866025f); // Black point. - ImVec2 triangle_pc = ImVec2(triangle_r * -0.5f, triangle_r * +0.866025f); // White point. + float wheel_thickness = sv_picker_size * 0.08f; + float wheel_r_outer = sv_picker_size * 0.50f; + float wheel_r_inner = wheel_r_outer - wheel_thickness; + ImVec2 wheel_center(picker_pos.x + (sv_picker_size + bars_width) * 0.5f, picker_pos.y + sv_picker_size * 0.5f); - float H,S,V; - ColorConvertRGBtoHSV(col[0], col[1], col[2], H, S, V); + // Note: the triangle is displayed rotated with triangle_pa pointing to Hue, but most coordinates stays unrotated for logic. + float triangle_r = wheel_r_inner - (int)(sv_picker_size * 0.027f); + ImVec2 triangle_pa = ImVec2(triangle_r, 0.0f); // Hue point. + ImVec2 triangle_pb = ImVec2(triangle_r * -0.5f, triangle_r * -0.866025f); // Black point. + ImVec2 triangle_pc = ImVec2(triangle_r * -0.5f, triangle_r * +0.866025f); // White point. - bool value_changed = false, value_changed_h = false, value_changed_sv = false; + float H, S, V; + ColorConvertRGBtoHSV(col[0], col[1], col[2], H, S, V); - PushItemFlag(ImGuiItemFlags_NoNav, true); - if (flags & ImGuiColorEditFlags_PickerHueWheel) - { - // Hue wheel + SV triangle logic - InvisibleButton("hsv", ImVec2(sv_picker_size + style.ItemInnerSpacing.x + bars_width, sv_picker_size)); - if (IsItemActive()) - { - ImVec2 initial_off = g.IO.MouseClickedPos[0] - wheel_center; - ImVec2 current_off = g.IO.MousePos - wheel_center; - float initial_dist2 = ImLengthSqr(initial_off); - if (initial_dist2 >= (wheel_r_inner-1)*(wheel_r_inner-1) && initial_dist2 <= (wheel_r_outer+1)*(wheel_r_outer+1)) - { - // Interactive with Hue wheel - H = atan2f(current_off.y, current_off.x) / IM_PI*0.5f; - if (H < 0.0f) - H += 1.0f; - value_changed = value_changed_h = true; - } - float cos_hue_angle = cosf(-H * 2.0f * IM_PI); - float sin_hue_angle = sinf(-H * 2.0f * IM_PI); - if (ImTriangleContainsPoint(triangle_pa, triangle_pb, triangle_pc, ImRotate(initial_off, cos_hue_angle, sin_hue_angle))) - { - // Interacting with SV triangle - ImVec2 current_off_unrotated = ImRotate(current_off, cos_hue_angle, sin_hue_angle); - if (!ImTriangleContainsPoint(triangle_pa, triangle_pb, triangle_pc, current_off_unrotated)) - current_off_unrotated = ImTriangleClosestPoint(triangle_pa, triangle_pb, triangle_pc, current_off_unrotated); - float uu, vv, ww; - ImTriangleBarycentricCoords(triangle_pa, triangle_pb, triangle_pc, current_off_unrotated, uu, vv, ww); - V = ImClamp(1.0f - vv, 0.0001f, 1.0f); - S = ImClamp(uu / V, 0.0001f, 1.0f); - value_changed = value_changed_sv = true; - } - } - if (!(flags & ImGuiColorEditFlags_NoOptions)) - OpenPopupOnItemClick("context"); - } - else if (flags & ImGuiColorEditFlags_PickerHueBar) - { - // SV rectangle logic - InvisibleButton("sv", ImVec2(sv_picker_size, sv_picker_size)); - if (IsItemActive()) - { - S = ImSaturate((io.MousePos.x - picker_pos.x) / (sv_picker_size-1)); - V = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size-1)); - value_changed = value_changed_sv = true; - } - if (!(flags & ImGuiColorEditFlags_NoOptions)) - OpenPopupOnItemClick("context"); + bool value_changed = false, value_changed_h = false, value_changed_sv = false; - // Hue bar logic - SetCursorScreenPos(ImVec2(bar0_pos_x, picker_pos.y)); - InvisibleButton("hue", ImVec2(bars_width, sv_picker_size)); - if (IsItemActive()) - { - H = ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size-1)); - value_changed = value_changed_h = true; - } - } + PushItemFlag(ImGuiItemFlags_NoNav, true); + if (flags & ImGuiColorEditFlags_PickerHueWheel) + { + // Hue wheel + SV triangle logic + InvisibleButton("hsv", ImVec2(sv_picker_size + style.ItemInnerSpacing.x + bars_width, sv_picker_size)); + if (IsItemActive()) + { + ImVec2 initial_off = g.IO.MouseClickedPos[0] - wheel_center; + ImVec2 current_off = g.IO.MousePos - wheel_center; + float initial_dist2 = ImLengthSqr(initial_off); + if (initial_dist2 >= (wheel_r_inner - 1) * (wheel_r_inner - 1) && initial_dist2 <= (wheel_r_outer + 1) * (wheel_r_outer + 1)) + { + // Interactive with Hue wheel + H = atan2f(current_off.y, current_off.x) / IM_PI * 0.5f; + if (H < 0.0f) + H += 1.0f; + value_changed = value_changed_h = true; + } + float cos_hue_angle = cosf(-H * 2.0f * IM_PI); + float sin_hue_angle = sinf(-H * 2.0f * IM_PI); + if (ImTriangleContainsPoint(triangle_pa, triangle_pb, triangle_pc, ImRotate(initial_off, cos_hue_angle, sin_hue_angle))) + { + // Interacting with SV triangle + ImVec2 current_off_unrotated = ImRotate(current_off, cos_hue_angle, sin_hue_angle); + if (!ImTriangleContainsPoint(triangle_pa, triangle_pb, triangle_pc, current_off_unrotated)) + current_off_unrotated = ImTriangleClosestPoint(triangle_pa, triangle_pb, triangle_pc, current_off_unrotated); + float uu, vv, ww; + ImTriangleBarycentricCoords(triangle_pa, triangle_pb, triangle_pc, current_off_unrotated, uu, vv, ww); + V = ImClamp(1.0f - vv, 0.0001f, 1.0f); + S = ImClamp(uu / V, 0.0001f, 1.0f); + value_changed = value_changed_sv = true; + } + } + if (!(flags & ImGuiColorEditFlags_NoOptions)) + OpenPopupOnItemClick("context"); + } + else if (flags & ImGuiColorEditFlags_PickerHueBar) + { + // SV rectangle logic + InvisibleButton("sv", ImVec2(sv_picker_size, sv_picker_size)); + if (IsItemActive()) + { + S = ImSaturate((io.MousePos.x - picker_pos.x) / (sv_picker_size - 1)); + V = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size - 1)); + value_changed = value_changed_sv = true; + } + if (!(flags & ImGuiColorEditFlags_NoOptions)) + OpenPopupOnItemClick("context"); - // Alpha bar logic - if (alpha_bar) - { - SetCursorScreenPos(ImVec2(bar1_pos_x, picker_pos.y)); - InvisibleButton("alpha", ImVec2(bars_width, sv_picker_size)); - if (IsItemActive()) - { - col[3] = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size-1)); - value_changed = true; - } - } - PopItemFlag(); // ImGuiItemFlags_NoNav + // Hue bar logic + SetCursorScreenPos(ImVec2(bar0_pos_x, picker_pos.y)); + InvisibleButton("hue", ImVec2(bars_width, sv_picker_size)); + if (IsItemActive()) + { + H = ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size - 1)); + value_changed = value_changed_h = true; + } + } - if (!(flags & ImGuiColorEditFlags_NoSidePreview)) - { - SameLine(0, style.ItemInnerSpacing.x); - BeginGroup(); - } + // Alpha bar logic + if (alpha_bar) + { + SetCursorScreenPos(ImVec2(bar1_pos_x, picker_pos.y)); + InvisibleButton("alpha", ImVec2(bars_width, sv_picker_size)); + if (IsItemActive()) + { + col[3] = 1.0f - ImSaturate((io.MousePos.y - picker_pos.y) / (sv_picker_size - 1)); + value_changed = true; + } + } + PopItemFlag(); // ImGuiItemFlags_NoNav - if (!(flags & ImGuiColorEditFlags_NoLabel)) - { - const char* label_display_end = FindRenderedTextEnd(label); - if (label != label_display_end) - { - if ((flags & ImGuiColorEditFlags_NoSidePreview)) - SameLine(0, style.ItemInnerSpacing.x); - TextUnformatted(label, label_display_end); - } - } + if (!(flags & ImGuiColorEditFlags_NoSidePreview)) + { + SameLine(0, style.ItemInnerSpacing.x); + BeginGroup(); + } - if (!(flags & ImGuiColorEditFlags_NoSidePreview)) - { - PushItemFlag(ImGuiItemFlags_NoNavDefaultFocus, true); - ImVec4 col_v4(col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]); - if ((flags & ImGuiColorEditFlags_NoLabel)) - Text("Current"); - ColorButton("##current", col_v4, (flags & (ImGuiColorEditFlags_HDR|ImGuiColorEditFlags_AlphaPreview|ImGuiColorEditFlags_AlphaPreviewHalf|ImGuiColorEditFlags_NoTooltip)), ImVec2(square_sz * 3, square_sz * 2)); - if (ref_col != NULL) - { - Text("Original"); - ImVec4 ref_col_v4(ref_col[0], ref_col[1], ref_col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : ref_col[3]); - if (ColorButton("##original", ref_col_v4, (flags & (ImGuiColorEditFlags_HDR|ImGuiColorEditFlags_AlphaPreview|ImGuiColorEditFlags_AlphaPreviewHalf|ImGuiColorEditFlags_NoTooltip)), ImVec2(square_sz * 3, square_sz * 2))) - { - memcpy(col, ref_col, components * sizeof(float)); - value_changed = true; - } - } - PopItemFlag(); - EndGroup(); - } + if (!(flags & ImGuiColorEditFlags_NoLabel)) + { + const char* label_display_end = FindRenderedTextEnd(label); + if (label != label_display_end) + { + if ((flags & ImGuiColorEditFlags_NoSidePreview)) + SameLine(0, style.ItemInnerSpacing.x); + TextUnformatted(label, label_display_end); + } + } - // Convert back color to RGB - if (value_changed_h || value_changed_sv) - ColorConvertHSVtoRGB(H >= 1.0f ? H - 10 * 1e-6f : H, S > 0.0f ? S : 10*1e-6f, V > 0.0f ? V : 1e-6f, col[0], col[1], col[2]); + if (!(flags & ImGuiColorEditFlags_NoSidePreview)) + { + PushItemFlag(ImGuiItemFlags_NoNavDefaultFocus, true); + ImVec4 col_v4(col[0], col[1], col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : col[3]); + if ((flags & ImGuiColorEditFlags_NoLabel)) + Text("Current"); + ColorButton("##current", col_v4, (flags & (ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf | ImGuiColorEditFlags_NoTooltip)), ImVec2(square_sz * 3, square_sz * 2)); + if (ref_col != NULL) + { + Text("Original"); + ImVec4 ref_col_v4(ref_col[0], ref_col[1], ref_col[2], (flags & ImGuiColorEditFlags_NoAlpha) ? 1.0f : ref_col[3]); + if (ColorButton("##original", ref_col_v4, (flags & (ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf | ImGuiColorEditFlags_NoTooltip)), ImVec2(square_sz * 3, square_sz * 2))) + { + memcpy(col, ref_col, components * sizeof(float)); + value_changed = true; + } + } + PopItemFlag(); + EndGroup(); + } - // R,G,B and H,S,V slider color editor - if ((flags & ImGuiColorEditFlags_NoInputs) == 0) - { - PushItemWidth((alpha_bar ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x); - ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags__DataTypeMask | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoSmallPreview | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; - ImGuiColorEditFlags sub_flags = (flags & sub_flags_to_forward) | ImGuiColorEditFlags_NoPicker; - if (flags & ImGuiColorEditFlags_RGB || (flags & ImGuiColorEditFlags__InputsMask) == 0) - value_changed |= ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_RGB); - if (flags & ImGuiColorEditFlags_HSV || (flags & ImGuiColorEditFlags__InputsMask) == 0) - value_changed |= ColorEdit4("##hsv", col, sub_flags | ImGuiColorEditFlags_HSV); - if (flags & ImGuiColorEditFlags_HEX || (flags & ImGuiColorEditFlags__InputsMask) == 0) - value_changed |= ColorEdit4("##hex", col, sub_flags | ImGuiColorEditFlags_HEX); - PopItemWidth(); - } + // Convert back color to RGB + if (value_changed_h || value_changed_sv) + ColorConvertHSVtoRGB(H >= 1.0f ? H - 10 * 1e-6f : H, S > 0.0f ? S : 10 * 1e-6f, V > 0.0f ? V : 1e-6f, col[0], col[1], col[2]); - // Try to cancel hue wrap (after ColorEdit), if any - if (value_changed) - { - float new_H, new_S, new_V; - ColorConvertRGBtoHSV(col[0], col[1], col[2], new_H, new_S, new_V); - if (new_H <= 0 && H > 0) - { - if (new_V <= 0 && V != new_V) - ColorConvertHSVtoRGB(H, S, new_V <= 0 ? V * 0.5f : new_V, col[0], col[1], col[2]); - else if (new_S <= 0) - ColorConvertHSVtoRGB(H, new_S <= 0 ? S * 0.5f : new_S, new_V, col[0], col[1], col[2]); - } - } + // R,G,B and H,S,V slider color editor + if ((flags & ImGuiColorEditFlags_NoInputs) == 0) + { + PushItemWidth((alpha_bar ? bar1_pos_x : bar0_pos_x) + bars_width - picker_pos.x); + ImGuiColorEditFlags sub_flags_to_forward = ImGuiColorEditFlags__DataTypeMask | ImGuiColorEditFlags_HDR | ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoOptions | ImGuiColorEditFlags_NoSmallPreview | ImGuiColorEditFlags_AlphaPreview | ImGuiColorEditFlags_AlphaPreviewHalf; + ImGuiColorEditFlags sub_flags = (flags & sub_flags_to_forward) | ImGuiColorEditFlags_NoPicker; + if (flags & ImGuiColorEditFlags_RGB || (flags & ImGuiColorEditFlags__InputsMask) == 0) + value_changed |= ColorEdit4("##rgb", col, sub_flags | ImGuiColorEditFlags_RGB); + if (flags & ImGuiColorEditFlags_HSV || (flags & ImGuiColorEditFlags__InputsMask) == 0) + value_changed |= ColorEdit4("##hsv", col, sub_flags | ImGuiColorEditFlags_HSV); + if (flags & ImGuiColorEditFlags_HEX || (flags & ImGuiColorEditFlags__InputsMask) == 0) + value_changed |= ColorEdit4("##hex", col, sub_flags | ImGuiColorEditFlags_HEX); + PopItemWidth(); + } - ImVec4 hue_color_f(1, 1, 1, 1); ColorConvertHSVtoRGB(H, 1, 1, hue_color_f.x, hue_color_f.y, hue_color_f.z); - ImU32 hue_color32 = ColorConvertFloat4ToU32(hue_color_f); - ImU32 col32_no_alpha = ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 1.0f)); + // Try to cancel hue wrap (after ColorEdit), if any + if (value_changed) + { + float new_H, new_S, new_V; + ColorConvertRGBtoHSV(col[0], col[1], col[2], new_H, new_S, new_V); + if (new_H <= 0 && H > 0) + { + if (new_V <= 0 && V != new_V) + ColorConvertHSVtoRGB(H, S, new_V <= 0 ? V * 0.5f : new_V, col[0], col[1], col[2]); + else if (new_S <= 0) + ColorConvertHSVtoRGB(H, new_S <= 0 ? S * 0.5f : new_S, new_V, col[0], col[1], col[2]); + } + } - const ImU32 hue_colors[6+1] = { IM_COL32(255,0,0,255), IM_COL32(255,255,0,255), IM_COL32(0,255,0,255), IM_COL32(0,255,255,255), IM_COL32(0,0,255,255), IM_COL32(255,0,255,255), IM_COL32(255,0,0,255) }; - ImVec2 sv_cursor_pos; - - if (flags & ImGuiColorEditFlags_PickerHueWheel) - { - // Render Hue Wheel - const float aeps = 1.5f / wheel_r_outer; // Half a pixel arc length in radians (2pi cancels out). - const int segment_per_arc = ImMax(4, (int)wheel_r_outer / 12); - for (int n = 0; n < 6; n++) - { - const float a0 = (n) /6.0f * 2.0f * IM_PI - aeps; - const float a1 = (n+1.0f)/6.0f * 2.0f * IM_PI + aeps; - const int vert_start_idx = draw_list->VtxBuffer.Size; - draw_list->PathArcTo(wheel_center, (wheel_r_inner + wheel_r_outer)*0.5f, a0, a1, segment_per_arc); - draw_list->PathStroke(IM_COL32_WHITE, false, wheel_thickness); - const int vert_end_idx = draw_list->VtxBuffer.Size; + ImVec4 hue_color_f(1, 1, 1, 1); + ColorConvertHSVtoRGB(H, 1, 1, hue_color_f.x, hue_color_f.y, hue_color_f.z); + ImU32 hue_color32 = ColorConvertFloat4ToU32(hue_color_f); + ImU32 col32_no_alpha = ColorConvertFloat4ToU32(ImVec4(col[0], col[1], col[2], 1.0f)); - // Paint colors over existing vertices - ImVec2 gradient_p0(wheel_center.x + cosf(a0) * wheel_r_inner, wheel_center.y + sinf(a0) * wheel_r_inner); - ImVec2 gradient_p1(wheel_center.x + cosf(a1) * wheel_r_inner, wheel_center.y + sinf(a1) * wheel_r_inner); - ShadeVertsLinearColorGradientKeepAlpha(draw_list->VtxBuffer.Data + vert_start_idx, draw_list->VtxBuffer.Data + vert_end_idx, gradient_p0, gradient_p1, hue_colors[n], hue_colors[n+1]); - } + const ImU32 hue_colors[6 + 1] = {IM_COL32(255, 0, 0, 255), IM_COL32(255, 255, 0, 255), IM_COL32(0, 255, 0, 255), IM_COL32(0, 255, 255, 255), IM_COL32(0, 0, 255, 255), IM_COL32(255, 0, 255, 255), IM_COL32(255, 0, 0, 255)}; + ImVec2 sv_cursor_pos; - // Render Cursor + preview on Hue Wheel - float cos_hue_angle = cosf(H * 2.0f * IM_PI); - float sin_hue_angle = sinf(H * 2.0f * IM_PI); - ImVec2 hue_cursor_pos(wheel_center.x + cos_hue_angle * (wheel_r_inner+wheel_r_outer)*0.5f, wheel_center.y + sin_hue_angle * (wheel_r_inner+wheel_r_outer)*0.5f); - float hue_cursor_rad = value_changed_h ? wheel_thickness * 0.65f : wheel_thickness * 0.55f; - int hue_cursor_segments = ImClamp((int)(hue_cursor_rad / 1.4f), 9, 32); - draw_list->AddCircleFilled(hue_cursor_pos, hue_cursor_rad, hue_color32, hue_cursor_segments); - draw_list->AddCircle(hue_cursor_pos, hue_cursor_rad+1, IM_COL32(128,128,128,255), hue_cursor_segments); - draw_list->AddCircle(hue_cursor_pos, hue_cursor_rad, IM_COL32_WHITE, hue_cursor_segments); + if (flags & ImGuiColorEditFlags_PickerHueWheel) + { + // Render Hue Wheel + const float aeps = 1.5f / wheel_r_outer; // Half a pixel arc length in radians (2pi cancels out). + const int segment_per_arc = ImMax(4, (int)wheel_r_outer / 12); + for (int n = 0; n < 6; n++) + { + const float a0 = (n) / 6.0f * 2.0f * IM_PI - aeps; + const float a1 = (n + 1.0f) / 6.0f * 2.0f * IM_PI + aeps; + const int vert_start_idx = draw_list->VtxBuffer.Size; + draw_list->PathArcTo(wheel_center, (wheel_r_inner + wheel_r_outer) * 0.5f, a0, a1, segment_per_arc); + draw_list->PathStroke(IM_COL32_WHITE, false, wheel_thickness); + const int vert_end_idx = draw_list->VtxBuffer.Size; - // Render SV triangle (rotated according to hue) - ImVec2 tra = wheel_center + ImRotate(triangle_pa, cos_hue_angle, sin_hue_angle); - ImVec2 trb = wheel_center + ImRotate(triangle_pb, cos_hue_angle, sin_hue_angle); - ImVec2 trc = wheel_center + ImRotate(triangle_pc, cos_hue_angle, sin_hue_angle); - ImVec2 uv_white = GetFontTexUvWhitePixel(); - draw_list->PrimReserve(6, 6); - draw_list->PrimVtx(tra, uv_white, hue_color32); - draw_list->PrimVtx(trb, uv_white, hue_color32); - draw_list->PrimVtx(trc, uv_white, IM_COL32_WHITE); - draw_list->PrimVtx(tra, uv_white, IM_COL32_BLACK_TRANS); - draw_list->PrimVtx(trb, uv_white, IM_COL32_BLACK); - draw_list->PrimVtx(trc, uv_white, IM_COL32_BLACK_TRANS); - draw_list->AddTriangle(tra, trb, trc, IM_COL32(128,128,128,255), 1.5f); - sv_cursor_pos = ImLerp(ImLerp(trc, tra, ImSaturate(S)), trb, ImSaturate(1 - V)); - } - else if (flags & ImGuiColorEditFlags_PickerHueBar) - { - // Render SV Square - draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), IM_COL32_WHITE, hue_color32, hue_color32, IM_COL32_WHITE); - draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), IM_COL32_BLACK_TRANS, IM_COL32_BLACK_TRANS, IM_COL32_BLACK, IM_COL32_BLACK); - RenderFrameBorder(picker_pos, picker_pos + ImVec2(sv_picker_size,sv_picker_size), 0.0f); - sv_cursor_pos.x = ImClamp((float)(int)(picker_pos.x + ImSaturate(S) * sv_picker_size + 0.5f), picker_pos.x + 2, picker_pos.x + sv_picker_size - 2); // Sneakily prevent the circle to stick out too much - sv_cursor_pos.y = ImClamp((float)(int)(picker_pos.y + ImSaturate(1 - V) * sv_picker_size + 0.5f), picker_pos.y + 2, picker_pos.y + sv_picker_size - 2); + // Paint colors over existing vertices + ImVec2 gradient_p0(wheel_center.x + cosf(a0) * wheel_r_inner, wheel_center.y + sinf(a0) * wheel_r_inner); + ImVec2 gradient_p1(wheel_center.x + cosf(a1) * wheel_r_inner, wheel_center.y + sinf(a1) * wheel_r_inner); + ShadeVertsLinearColorGradientKeepAlpha(draw_list->VtxBuffer.Data + vert_start_idx, draw_list->VtxBuffer.Data + vert_end_idx, gradient_p0, gradient_p1, hue_colors[n], hue_colors[n + 1]); + } - // Render Hue Bar - for (int i = 0; i < 6; ++i) - draw_list->AddRectFilledMultiColor(ImVec2(bar0_pos_x, picker_pos.y + i * (sv_picker_size / 6)), ImVec2(bar0_pos_x + bars_width, picker_pos.y + (i + 1) * (sv_picker_size / 6)), hue_colors[i], hue_colors[i], hue_colors[i + 1], hue_colors[i + 1]); - float bar0_line_y = (float)(int)(picker_pos.y + H * sv_picker_size + 0.5f); - RenderFrameBorder(ImVec2(bar0_pos_x, picker_pos.y), ImVec2(bar0_pos_x + bars_width, picker_pos.y + sv_picker_size), 0.0f); - RenderArrowsForVerticalBar(draw_list, ImVec2(bar0_pos_x - 1, bar0_line_y), ImVec2(bars_triangles_half_sz + 1, bars_triangles_half_sz), bars_width + 2.0f); - } + // Render Cursor + preview on Hue Wheel + float cos_hue_angle = cosf(H * 2.0f * IM_PI); + float sin_hue_angle = sinf(H * 2.0f * IM_PI); + ImVec2 hue_cursor_pos(wheel_center.x + cos_hue_angle * (wheel_r_inner + wheel_r_outer) * 0.5f, wheel_center.y + sin_hue_angle * (wheel_r_inner + wheel_r_outer) * 0.5f); + float hue_cursor_rad = value_changed_h ? wheel_thickness * 0.65f : wheel_thickness * 0.55f; + int hue_cursor_segments = ImClamp((int)(hue_cursor_rad / 1.4f), 9, 32); + draw_list->AddCircleFilled(hue_cursor_pos, hue_cursor_rad, hue_color32, hue_cursor_segments); + draw_list->AddCircle(hue_cursor_pos, hue_cursor_rad + 1, IM_COL32(128, 128, 128, 255), hue_cursor_segments); + draw_list->AddCircle(hue_cursor_pos, hue_cursor_rad, IM_COL32_WHITE, hue_cursor_segments); - // Render cursor/preview circle (clamp S/V within 0..1 range because floating points colors may lead HSV values to be out of range) - float sv_cursor_rad = value_changed_sv ? 10.0f : 6.0f; - draw_list->AddCircleFilled(sv_cursor_pos, sv_cursor_rad, col32_no_alpha, 12); - draw_list->AddCircle(sv_cursor_pos, sv_cursor_rad+1, IM_COL32(128,128,128,255), 12); - draw_list->AddCircle(sv_cursor_pos, sv_cursor_rad, IM_COL32_WHITE, 12); + // Render SV triangle (rotated according to hue) + ImVec2 tra = wheel_center + ImRotate(triangle_pa, cos_hue_angle, sin_hue_angle); + ImVec2 trb = wheel_center + ImRotate(triangle_pb, cos_hue_angle, sin_hue_angle); + ImVec2 trc = wheel_center + ImRotate(triangle_pc, cos_hue_angle, sin_hue_angle); + ImVec2 uv_white = GetFontTexUvWhitePixel(); + draw_list->PrimReserve(6, 6); + draw_list->PrimVtx(tra, uv_white, hue_color32); + draw_list->PrimVtx(trb, uv_white, hue_color32); + draw_list->PrimVtx(trc, uv_white, IM_COL32_WHITE); + draw_list->PrimVtx(tra, uv_white, IM_COL32_BLACK_TRANS); + draw_list->PrimVtx(trb, uv_white, IM_COL32_BLACK); + draw_list->PrimVtx(trc, uv_white, IM_COL32_BLACK_TRANS); + draw_list->AddTriangle(tra, trb, trc, IM_COL32(128, 128, 128, 255), 1.5f); + sv_cursor_pos = ImLerp(ImLerp(trc, tra, ImSaturate(S)), trb, ImSaturate(1 - V)); + } + else if (flags & ImGuiColorEditFlags_PickerHueBar) + { + // Render SV Square + draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size, sv_picker_size), IM_COL32_WHITE, hue_color32, hue_color32, IM_COL32_WHITE); + draw_list->AddRectFilledMultiColor(picker_pos, picker_pos + ImVec2(sv_picker_size, sv_picker_size), IM_COL32_BLACK_TRANS, IM_COL32_BLACK_TRANS, IM_COL32_BLACK, IM_COL32_BLACK); + RenderFrameBorder(picker_pos, picker_pos + ImVec2(sv_picker_size, sv_picker_size), 0.0f); + sv_cursor_pos.x = ImClamp((float)(int)(picker_pos.x + ImSaturate(S) * sv_picker_size + 0.5f), picker_pos.x + 2, picker_pos.x + sv_picker_size - 2); // Sneakily prevent the circle to stick out too much + sv_cursor_pos.y = ImClamp((float)(int)(picker_pos.y + ImSaturate(1 - V) * sv_picker_size + 0.5f), picker_pos.y + 2, picker_pos.y + sv_picker_size - 2); - // Render alpha bar - if (alpha_bar) - { - float alpha = ImSaturate(col[3]); - ImRect bar1_bb(bar1_pos_x, picker_pos.y, bar1_pos_x + bars_width, picker_pos.y + sv_picker_size); - RenderColorRectWithAlphaCheckerboard(bar1_bb.Min, bar1_bb.Max, IM_COL32(0,0,0,0), bar1_bb.GetWidth() / 2.0f, ImVec2(0.0f, 0.0f)); - draw_list->AddRectFilledMultiColor(bar1_bb.Min, bar1_bb.Max, col32_no_alpha, col32_no_alpha, col32_no_alpha & ~IM_COL32_A_MASK, col32_no_alpha & ~IM_COL32_A_MASK); - float bar1_line_y = (float)(int)(picker_pos.y + (1.0f - alpha) * sv_picker_size + 0.5f); - RenderFrameBorder(bar1_bb.Min, bar1_bb.Max, 0.0f); - RenderArrowsForVerticalBar(draw_list, ImVec2(bar1_pos_x - 1, bar1_line_y), ImVec2(bars_triangles_half_sz + 1, bars_triangles_half_sz), bars_width + 2.0f); - } + // Render Hue Bar + for (int i = 0; i < 6; ++i) + draw_list->AddRectFilledMultiColor(ImVec2(bar0_pos_x, picker_pos.y + i * (sv_picker_size / 6)), ImVec2(bar0_pos_x + bars_width, picker_pos.y + (i + 1) * (sv_picker_size / 6)), hue_colors[i], hue_colors[i], hue_colors[i + 1], hue_colors[i + 1]); + float bar0_line_y = (float)(int)(picker_pos.y + H * sv_picker_size + 0.5f); + RenderFrameBorder(ImVec2(bar0_pos_x, picker_pos.y), ImVec2(bar0_pos_x + bars_width, picker_pos.y + sv_picker_size), 0.0f); + RenderArrowsForVerticalBar(draw_list, ImVec2(bar0_pos_x - 1, bar0_line_y), ImVec2(bars_triangles_half_sz + 1, bars_triangles_half_sz), bars_width + 2.0f); + } - EndGroup(); - PopID(); + // Render cursor/preview circle (clamp S/V within 0..1 range because floating points colors may lead HSV values to be out of range) + float sv_cursor_rad = value_changed_sv ? 10.0f : 6.0f; + draw_list->AddCircleFilled(sv_cursor_pos, sv_cursor_rad, col32_no_alpha, 12); + draw_list->AddCircle(sv_cursor_pos, sv_cursor_rad + 1, IM_COL32(128, 128, 128, 255), 12); + draw_list->AddCircle(sv_cursor_pos, sv_cursor_rad, IM_COL32_WHITE, 12); - return value_changed && memcmp(backup_initial_col, col, components * sizeof(float)); + // Render alpha bar + if (alpha_bar) + { + float alpha = ImSaturate(col[3]); + ImRect bar1_bb(bar1_pos_x, picker_pos.y, bar1_pos_x + bars_width, picker_pos.y + sv_picker_size); + RenderColorRectWithAlphaCheckerboard(bar1_bb.Min, bar1_bb.Max, IM_COL32(0, 0, 0, 0), bar1_bb.GetWidth() / 2.0f, ImVec2(0.0f, 0.0f)); + draw_list->AddRectFilledMultiColor(bar1_bb.Min, bar1_bb.Max, col32_no_alpha, col32_no_alpha, col32_no_alpha & ~IM_COL32_A_MASK, col32_no_alpha & ~IM_COL32_A_MASK); + float bar1_line_y = (float)(int)(picker_pos.y + (1.0f - alpha) * sv_picker_size + 0.5f); + RenderFrameBorder(bar1_bb.Min, bar1_bb.Max, 0.0f); + RenderArrowsForVerticalBar(draw_list, ImVec2(bar1_pos_x - 1, bar1_line_y), ImVec2(bars_triangles_half_sz + 1, bars_triangles_half_sz), bars_width + 2.0f); + } + + EndGroup(); + PopID(); + + return value_changed && memcmp(backup_initial_col, col, components * sizeof(float)); } // Horizontal separating line. void ImGui::Separator() { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; - ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + ImGuiContext& g = *GImGui; - ImGuiWindowFlags flags = 0; - if ((flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical)) == 0) - flags |= (window->DC.LayoutType == ImGuiLayoutType_Horizontal) ? ImGuiSeparatorFlags_Vertical : ImGuiSeparatorFlags_Horizontal; - IM_ASSERT(ImIsPowerOfTwo((int)(flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical)))); // Check that only 1 option is selected - if (flags & ImGuiSeparatorFlags_Vertical) - { - VerticalSeparator(); - return; - } + ImGuiWindowFlags flags = 0; + if ((flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical)) == 0) + flags |= (window->DC.LayoutType == ImGuiLayoutType_Horizontal) ? ImGuiSeparatorFlags_Vertical : ImGuiSeparatorFlags_Horizontal; + IM_ASSERT(ImIsPowerOfTwo((int)(flags & (ImGuiSeparatorFlags_Horizontal | ImGuiSeparatorFlags_Vertical)))); // Check that only 1 option is selected + if (flags & ImGuiSeparatorFlags_Vertical) + { + VerticalSeparator(); + return; + } - // Horizontal Separator - if (window->DC.ColumnsSet) - PopClipRect(); + // Horizontal Separator + if (window->DC.ColumnsSet) + PopClipRect(); - float x1 = window->Pos.x; - float x2 = window->Pos.x + window->Size.x; - if (!window->DC.GroupStack.empty()) - x1 += window->DC.IndentX; + float x1 = window->Pos.x; + float x2 = window->Pos.x + window->Size.x; + if (!window->DC.GroupStack.empty()) + x1 += window->DC.IndentX; - const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y+1.0f)); - ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit, we don't provide height to not alter layout. - if (!ItemAdd(bb, 0)) - { - if (window->DC.ColumnsSet) - PushColumnClipRect(); - return; - } + const ImRect bb(ImVec2(x1, window->DC.CursorPos.y), ImVec2(x2, window->DC.CursorPos.y + 1.0f)); + ItemSize(ImVec2(0.0f, 0.0f)); // NB: we don't provide our width so that it doesn't get feed back into AutoFit, we don't provide height to not alter layout. + if (!ItemAdd(bb, 0)) + { + if (window->DC.ColumnsSet) + PushColumnClipRect(); + return; + } - window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x,bb.Min.y), GetColorU32(ImGuiCol_Separator)); + window->DrawList->AddLine(bb.Min, ImVec2(bb.Max.x, bb.Min.y), GetColorU32(ImGuiCol_Separator)); - if (g.LogEnabled) - LogRenderedText(NULL, IM_NEWLINE "--------------------------------"); + if (g.LogEnabled) + LogRenderedText(NULL, IM_NEWLINE "--------------------------------"); - if (window->DC.ColumnsSet) - { - PushColumnClipRect(); - window->DC.ColumnsSet->CellMinY = window->DC.CursorPos.y; - } + if (window->DC.ColumnsSet) + { + PushColumnClipRect(); + window->DC.ColumnsSet->CellMinY = window->DC.CursorPos.y; + } } void ImGui::VerticalSeparator() { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; - ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + ImGuiContext& g = *GImGui; - float y1 = window->DC.CursorPos.y; - float y2 = window->DC.CursorPos.y + window->DC.CurrentLineHeight; - const ImRect bb(ImVec2(window->DC.CursorPos.x, y1), ImVec2(window->DC.CursorPos.x + 1.0f, y2)); - ItemSize(ImVec2(bb.GetWidth(), 0.0f)); - if (!ItemAdd(bb, 0)) - return; + float y1 = window->DC.CursorPos.y; + float y2 = window->DC.CursorPos.y + window->DC.CurrentLineHeight; + const ImRect bb(ImVec2(window->DC.CursorPos.x, y1), ImVec2(window->DC.CursorPos.x + 1.0f, y2)); + ItemSize(ImVec2(bb.GetWidth(), 0.0f)); + if (!ItemAdd(bb, 0)) + return; - window->DrawList->AddLine(ImVec2(bb.Min.x, bb.Min.y), ImVec2(bb.Min.x, bb.Max.y), GetColorU32(ImGuiCol_Separator)); - if (g.LogEnabled) - LogText(" |"); + window->DrawList->AddLine(ImVec2(bb.Min.x, bb.Min.y), ImVec2(bb.Min.x, bb.Max.y), GetColorU32(ImGuiCol_Separator)); + if (g.LogEnabled) + LogText(" |"); } bool ImGui::SplitterBehavior(ImGuiID id, const ImRect& bb, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; - const ImGuiItemFlags item_flags_backup = window->DC.ItemFlags; - window->DC.ItemFlags |= ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus; - bool item_add = ItemAdd(bb, id); - window->DC.ItemFlags = item_flags_backup; - if (!item_add) - return false; + const ImGuiItemFlags item_flags_backup = window->DC.ItemFlags; + window->DC.ItemFlags |= ImGuiItemFlags_NoNav | ImGuiItemFlags_NoNavDefaultFocus; + bool item_add = ItemAdd(bb, id); + window->DC.ItemFlags = item_flags_backup; + if (!item_add) + return false; - bool hovered, held; - ImRect bb_interact = bb; - bb_interact.Expand(axis == ImGuiAxis_Y ? ImVec2(0.0f, hover_extend) : ImVec2(hover_extend, 0.0f)); - ButtonBehavior(bb_interact, id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap); - if (g.ActiveId != id) - SetItemAllowOverlap(); + bool hovered, held; + ImRect bb_interact = bb; + bb_interact.Expand(axis == ImGuiAxis_Y ? ImVec2(0.0f, hover_extend) : ImVec2(hover_extend, 0.0f)); + ButtonBehavior(bb_interact, id, &hovered, &held, ImGuiButtonFlags_FlattenChildren | ImGuiButtonFlags_AllowItemOverlap); + if (g.ActiveId != id) + SetItemAllowOverlap(); - if (held || (g.HoveredId == id && g.HoveredIdPreviousFrame == id)) - SetMouseCursor(axis == ImGuiAxis_Y ? ImGuiMouseCursor_ResizeNS : ImGuiMouseCursor_ResizeEW); + if (held || (g.HoveredId == id && g.HoveredIdPreviousFrame == id)) + SetMouseCursor(axis == ImGuiAxis_Y ? ImGuiMouseCursor_ResizeNS : ImGuiMouseCursor_ResizeEW); - ImRect bb_render = bb; - if (held) - { - ImVec2 mouse_delta_2d = g.IO.MousePos - g.ActiveIdClickOffset - bb_interact.Min; - float mouse_delta = (axis == ImGuiAxis_Y) ? mouse_delta_2d.y : mouse_delta_2d.x; + ImRect bb_render = bb; + if (held) + { + ImVec2 mouse_delta_2d = g.IO.MousePos - g.ActiveIdClickOffset - bb_interact.Min; + float mouse_delta = (axis == ImGuiAxis_Y) ? mouse_delta_2d.y : mouse_delta_2d.x; - // Minimum pane size - if (mouse_delta < min_size1 - *size1) - mouse_delta = min_size1 - *size1; - if (mouse_delta > *size2 - min_size2) - mouse_delta = *size2 - min_size2; + // Minimum pane size + if (mouse_delta < min_size1 - *size1) + mouse_delta = min_size1 - *size1; + if (mouse_delta > *size2 - min_size2) + mouse_delta = *size2 - min_size2; - // Apply resize - *size1 += mouse_delta; - *size2 -= mouse_delta; - bb_render.Translate((axis == ImGuiAxis_X) ? ImVec2(mouse_delta, 0.0f) : ImVec2(0.0f, mouse_delta)); - } + // Apply resize + *size1 += mouse_delta; + *size2 -= mouse_delta; + bb_render.Translate((axis == ImGuiAxis_X) ? ImVec2(mouse_delta, 0.0f) : ImVec2(0.0f, mouse_delta)); + } - // Render - const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator); - window->DrawList->AddRectFilled(bb_render.Min, bb_render.Max, col, g.Style.FrameRounding); + // Render + const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator); + window->DrawList->AddRectFilled(bb_render.Min, bb_render.Max, col, g.Style.FrameRounding); - return held; + return held; } void ImGui::Spacing() { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; - ItemSize(ImVec2(0,0)); + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; + ItemSize(ImVec2(0, 0)); } void ImGui::Dummy(const ImVec2& size) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; - const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); - ItemSize(bb); - ItemAdd(bb, 0); + const ImRect bb(window->DC.CursorPos, window->DC.CursorPos + size); + ItemSize(bb); + ItemAdd(bb, 0); } bool ImGui::IsRectVisible(const ImVec2& size) { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->ClipRect.Overlaps(ImRect(window->DC.CursorPos, window->DC.CursorPos + size)); + ImGuiWindow* window = GetCurrentWindowRead(); + return window->ClipRect.Overlaps(ImRect(window->DC.CursorPos, window->DC.CursorPos + size)); } bool ImGui::IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max) { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->ClipRect.Overlaps(ImRect(rect_min, rect_max)); + ImGuiWindow* window = GetCurrentWindowRead(); + return window->ClipRect.Overlaps(ImRect(rect_min, rect_max)); } // Lock horizontal starting position + capture group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.) void ImGui::BeginGroup() { - ImGuiWindow* window = GetCurrentWindow(); + ImGuiWindow* window = GetCurrentWindow(); - window->DC.GroupStack.resize(window->DC.GroupStack.Size + 1); - ImGuiGroupData& group_data = window->DC.GroupStack.back(); - group_data.BackupCursorPos = window->DC.CursorPos; - group_data.BackupCursorMaxPos = window->DC.CursorMaxPos; - group_data.BackupIndentX = window->DC.IndentX; - group_data.BackupGroupOffsetX = window->DC.GroupOffsetX; - group_data.BackupCurrentLineHeight = window->DC.CurrentLineHeight; - group_data.BackupCurrentLineTextBaseOffset = window->DC.CurrentLineTextBaseOffset; - group_data.BackupLogLinePosY = window->DC.LogLinePosY; - group_data.BackupActiveIdIsAlive = GImGui->ActiveIdIsAlive; - group_data.AdvanceCursor = true; + window->DC.GroupStack.resize(window->DC.GroupStack.Size + 1); + ImGuiGroupData& group_data = window->DC.GroupStack.back(); + group_data.BackupCursorPos = window->DC.CursorPos; + group_data.BackupCursorMaxPos = window->DC.CursorMaxPos; + group_data.BackupIndentX = window->DC.IndentX; + group_data.BackupGroupOffsetX = window->DC.GroupOffsetX; + group_data.BackupCurrentLineHeight = window->DC.CurrentLineHeight; + group_data.BackupCurrentLineTextBaseOffset = window->DC.CurrentLineTextBaseOffset; + group_data.BackupLogLinePosY = window->DC.LogLinePosY; + group_data.BackupActiveIdIsAlive = GImGui->ActiveIdIsAlive; + group_data.AdvanceCursor = true; - window->DC.GroupOffsetX = window->DC.CursorPos.x - window->Pos.x - window->DC.ColumnsOffsetX; - window->DC.IndentX = window->DC.GroupOffsetX; - window->DC.CursorMaxPos = window->DC.CursorPos; - window->DC.CurrentLineHeight = 0.0f; - window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; + window->DC.GroupOffsetX = window->DC.CursorPos.x - window->Pos.x - window->DC.ColumnsOffsetX; + window->DC.IndentX = window->DC.GroupOffsetX; + window->DC.CursorMaxPos = window->DC.CursorPos; + window->DC.CurrentLineHeight = 0.0f; + window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; } void ImGui::EndGroup() { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); - IM_ASSERT(!window->DC.GroupStack.empty()); // Mismatched BeginGroup()/EndGroup() calls + IM_ASSERT(!window->DC.GroupStack.empty()); // Mismatched BeginGroup()/EndGroup() calls - ImGuiGroupData& group_data = window->DC.GroupStack.back(); + ImGuiGroupData& group_data = window->DC.GroupStack.back(); - ImRect group_bb(group_data.BackupCursorPos, window->DC.CursorMaxPos); - group_bb.Max = ImMax(group_bb.Min, group_bb.Max); + ImRect group_bb(group_data.BackupCursorPos, window->DC.CursorMaxPos); + group_bb.Max = ImMax(group_bb.Min, group_bb.Max); - window->DC.CursorPos = group_data.BackupCursorPos; - window->DC.CursorMaxPos = ImMax(group_data.BackupCursorMaxPos, window->DC.CursorMaxPos); - window->DC.CurrentLineHeight = group_data.BackupCurrentLineHeight; - window->DC.CurrentLineTextBaseOffset = group_data.BackupCurrentLineTextBaseOffset; - window->DC.IndentX = group_data.BackupIndentX; - window->DC.GroupOffsetX = group_data.BackupGroupOffsetX; - window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; + window->DC.CursorPos = group_data.BackupCursorPos; + window->DC.CursorMaxPos = ImMax(group_data.BackupCursorMaxPos, window->DC.CursorMaxPos); + window->DC.CurrentLineHeight = group_data.BackupCurrentLineHeight; + window->DC.CurrentLineTextBaseOffset = group_data.BackupCurrentLineTextBaseOffset; + window->DC.IndentX = group_data.BackupIndentX; + window->DC.GroupOffsetX = group_data.BackupGroupOffsetX; + window->DC.LogLinePosY = window->DC.CursorPos.y - 9999.0f; - if (group_data.AdvanceCursor) - { - window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.PrevLineTextBaseOffset, group_data.BackupCurrentLineTextBaseOffset); // FIXME: Incorrect, we should grab the base offset from the *first line* of the group but it is hard to obtain now. - ItemSize(group_bb.GetSize(), group_data.BackupCurrentLineTextBaseOffset); - ItemAdd(group_bb, 0); - } + if (group_data.AdvanceCursor) + { + window->DC.CurrentLineTextBaseOffset = ImMax(window->DC.PrevLineTextBaseOffset, group_data.BackupCurrentLineTextBaseOffset); // FIXME: Incorrect, we should grab the base offset from the *first line* of the group but it is hard to obtain now. + ItemSize(group_bb.GetSize(), group_data.BackupCurrentLineTextBaseOffset); + ItemAdd(group_bb, 0); + } - // If the current ActiveId was declared within the boundary of our group, we copy it to LastItemId so IsItemActive() will be functional on the entire group. - // It would be be neater if we replaced window.DC.LastItemId by e.g. 'bool LastItemIsActive', but if you search for LastItemId you'll notice it is only used in that context. - const bool active_id_within_group = (!group_data.BackupActiveIdIsAlive && g.ActiveIdIsAlive && g.ActiveId && g.ActiveIdWindow->RootWindow == window->RootWindow); - if (active_id_within_group) - window->DC.LastItemId = g.ActiveId; - window->DC.LastItemRect = group_bb; + // If the current ActiveId was declared within the boundary of our group, we copy it to LastItemId so IsItemActive() will be functional on the entire group. + // It would be be neater if we replaced window.DC.LastItemId by e.g. 'bool LastItemIsActive', but if you search for LastItemId you'll notice it is only used in that context. + const bool active_id_within_group = (!group_data.BackupActiveIdIsAlive && g.ActiveIdIsAlive && g.ActiveId && g.ActiveIdWindow->RootWindow == window->RootWindow); + if (active_id_within_group) + window->DC.LastItemId = g.ActiveId; + window->DC.LastItemRect = group_bb; - window->DC.GroupStack.pop_back(); + window->DC.GroupStack.pop_back(); - //window->DrawList->AddRect(group_bb.Min, group_bb.Max, IM_COL32(255,0,255,255)); // [Debug] + //window->DrawList->AddRect(group_bb.Min, group_bb.Max, IM_COL32(255,0,255,255)); // [Debug] } // Gets back to previous line and continue with horizontal layout @@ -12270,129 +12595,129 @@ void ImGui::EndGroup() // spacing_w >= 0 : enforce spacing amount void ImGui::SameLine(float pos_x, float spacing_w) { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; - ImGuiContext& g = *GImGui; - if (pos_x != 0.0f) - { - if (spacing_w < 0.0f) spacing_w = 0.0f; - window->DC.CursorPos.x = window->Pos.x - window->Scroll.x + pos_x + spacing_w + window->DC.GroupOffsetX + window->DC.ColumnsOffsetX; - window->DC.CursorPos.y = window->DC.CursorPosPrevLine.y; - } - else - { - if (spacing_w < 0.0f) spacing_w = g.Style.ItemSpacing.x; - window->DC.CursorPos.x = window->DC.CursorPosPrevLine.x + spacing_w; - window->DC.CursorPos.y = window->DC.CursorPosPrevLine.y; - } - window->DC.CurrentLineHeight = window->DC.PrevLineHeight; - window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset; + ImGuiContext& g = *GImGui; + if (pos_x != 0.0f) + { + if (spacing_w < 0.0f) spacing_w = 0.0f; + window->DC.CursorPos.x = window->Pos.x - window->Scroll.x + pos_x + spacing_w + window->DC.GroupOffsetX + window->DC.ColumnsOffsetX; + window->DC.CursorPos.y = window->DC.CursorPosPrevLine.y; + } + else + { + if (spacing_w < 0.0f) spacing_w = g.Style.ItemSpacing.x; + window->DC.CursorPos.x = window->DC.CursorPosPrevLine.x + spacing_w; + window->DC.CursorPos.y = window->DC.CursorPosPrevLine.y; + } + window->DC.CurrentLineHeight = window->DC.PrevLineHeight; + window->DC.CurrentLineTextBaseOffset = window->DC.PrevLineTextBaseOffset; } void ImGui::NewLine() { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems) - return; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems) + return; - ImGuiContext& g = *GImGui; - const ImGuiLayoutType backup_layout_type = window->DC.LayoutType; - window->DC.LayoutType = ImGuiLayoutType_Vertical; - if (window->DC.CurrentLineHeight > 0.0f) // In the event that we are on a line with items that is smaller that FontSize high, we will preserve its height. - ItemSize(ImVec2(0,0)); - else - ItemSize(ImVec2(0.0f, g.FontSize)); - window->DC.LayoutType = backup_layout_type; + ImGuiContext& g = *GImGui; + const ImGuiLayoutType backup_layout_type = window->DC.LayoutType; + window->DC.LayoutType = ImGuiLayoutType_Vertical; + if (window->DC.CurrentLineHeight > 0.0f) // In the event that we are on a line with items that is smaller that FontSize high, we will preserve its height. + ItemSize(ImVec2(0, 0)); + else + ItemSize(ImVec2(0.0f, g.FontSize)); + window->DC.LayoutType = backup_layout_type; } void ImGui::NextColumn() { - ImGuiWindow* window = GetCurrentWindow(); - if (window->SkipItems || window->DC.ColumnsSet == NULL) - return; + ImGuiWindow* window = GetCurrentWindow(); + if (window->SkipItems || window->DC.ColumnsSet == NULL) + return; - ImGuiContext& g = *GImGui; - PopItemWidth(); - PopClipRect(); + ImGuiContext& g = *GImGui; + PopItemWidth(); + PopClipRect(); - ImGuiColumnsSet* columns = window->DC.ColumnsSet; - columns->CellMaxY = ImMax(columns->CellMaxY, window->DC.CursorPos.y); - if (++columns->Current < columns->Count) - { - // Columns 1+ cancel out IndentX - window->DC.ColumnsOffsetX = GetColumnOffset(columns->Current) - window->DC.IndentX + g.Style.ItemSpacing.x; - window->DrawList->ChannelsSetCurrent(columns->Current); - } - else - { - window->DC.ColumnsOffsetX = 0.0f; - window->DrawList->ChannelsSetCurrent(0); - columns->Current = 0; - columns->CellMinY = columns->CellMaxY; - } - window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); - window->DC.CursorPos.y = columns->CellMinY; - window->DC.CurrentLineHeight = 0.0f; - window->DC.CurrentLineTextBaseOffset = 0.0f; + ImGuiColumnsSet* columns = window->DC.ColumnsSet; + columns->CellMaxY = ImMax(columns->CellMaxY, window->DC.CursorPos.y); + if (++columns->Current < columns->Count) + { + // Columns 1+ cancel out IndentX + window->DC.ColumnsOffsetX = GetColumnOffset(columns->Current) - window->DC.IndentX + g.Style.ItemSpacing.x; + window->DrawList->ChannelsSetCurrent(columns->Current); + } + else + { + window->DC.ColumnsOffsetX = 0.0f; + window->DrawList->ChannelsSetCurrent(0); + columns->Current = 0; + columns->CellMinY = columns->CellMaxY; + } + window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); + window->DC.CursorPos.y = columns->CellMinY; + window->DC.CurrentLineHeight = 0.0f; + window->DC.CurrentLineTextBaseOffset = 0.0f; - PushColumnClipRect(); - PushItemWidth(GetColumnWidth() * 0.65f); // FIXME: Move on columns setup + PushColumnClipRect(); + PushItemWidth(GetColumnWidth() * 0.65f); // FIXME: Move on columns setup } int ImGui::GetColumnIndex() { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.ColumnsSet ? window->DC.ColumnsSet->Current : 0; + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.ColumnsSet ? window->DC.ColumnsSet->Current : 0; } int ImGui::GetColumnsCount() { - ImGuiWindow* window = GetCurrentWindowRead(); - return window->DC.ColumnsSet ? window->DC.ColumnsSet->Count : 1; + ImGuiWindow* window = GetCurrentWindowRead(); + return window->DC.ColumnsSet ? window->DC.ColumnsSet->Count : 1; } static float OffsetNormToPixels(const ImGuiColumnsSet* columns, float offset_norm) { - return offset_norm * (columns->MaxX - columns->MinX); + return offset_norm * (columns->MaxX - columns->MinX); } static float PixelsToOffsetNorm(const ImGuiColumnsSet* columns, float offset) { - return offset / (columns->MaxX - columns->MinX); + return offset / (columns->MaxX - columns->MinX); } static inline float GetColumnsRectHalfWidth() { return 4.0f; } static float GetDraggedColumnOffset(ImGuiColumnsSet* columns, int column_index) { - // Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing - // window creates a feedback loop because we store normalized positions. So while dragging we enforce absolute positioning. - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - IM_ASSERT(column_index > 0); // We cannot drag column 0. If you get this assert you may have a conflict between the ID of your columns and another widgets. - IM_ASSERT(g.ActiveId == columns->ID + ImGuiID(column_index)); + // Active (dragged) column always follow mouse. The reason we need this is that dragging a column to the right edge of an auto-resizing + // window creates a feedback loop because we store normalized positions. So while dragging we enforce absolute positioning. + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + IM_ASSERT(column_index > 0); // We cannot drag column 0. If you get this assert you may have a conflict between the ID of your columns and another widgets. + IM_ASSERT(g.ActiveId == columns->ID + ImGuiID(column_index)); - float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x + GetColumnsRectHalfWidth() - window->Pos.x; - x = ImMax(x, ImGui::GetColumnOffset(column_index - 1) + g.Style.ColumnsMinSpacing); - if ((columns->Flags & ImGuiColumnsFlags_NoPreserveWidths)) - x = ImMin(x, ImGui::GetColumnOffset(column_index + 1) - g.Style.ColumnsMinSpacing); + float x = g.IO.MousePos.x - g.ActiveIdClickOffset.x + GetColumnsRectHalfWidth() - window->Pos.x; + x = ImMax(x, ImGui::GetColumnOffset(column_index - 1) + g.Style.ColumnsMinSpacing); + if ((columns->Flags & ImGuiColumnsFlags_NoPreserveWidths)) + x = ImMin(x, ImGui::GetColumnOffset(column_index + 1) - g.Style.ColumnsMinSpacing); - return x; + return x; } float ImGui::GetColumnOffset(int column_index) { - ImGuiWindow* window = GetCurrentWindowRead(); - ImGuiColumnsSet* columns = window->DC.ColumnsSet; - IM_ASSERT(columns != NULL); + ImGuiWindow* window = GetCurrentWindowRead(); + ImGuiColumnsSet* columns = window->DC.ColumnsSet; + IM_ASSERT(columns != NULL); - if (column_index < 0) - column_index = columns->Current; - IM_ASSERT(column_index < columns->Columns.Size); + if (column_index < 0) + column_index = columns->Current; + IM_ASSERT(column_index < columns->Columns.Size); - /* + /* if (g.ActiveId) { ImGuiContext& g = *GImGui; @@ -12402,330 +12727,330 @@ float ImGui::GetColumnOffset(int column_index) } */ - const float t = columns->Columns[column_index].OffsetNorm; - const float x_offset = ImLerp(columns->MinX, columns->MaxX, t); - return x_offset; + const float t = columns->Columns[column_index].OffsetNorm; + const float x_offset = ImLerp(columns->MinX, columns->MaxX, t); + return x_offset; } static float GetColumnWidthEx(ImGuiColumnsSet* columns, int column_index, bool before_resize = false) { - if (column_index < 0) - column_index = columns->Current; + if (column_index < 0) + column_index = columns->Current; - float offset_norm; - if (before_resize) - offset_norm = columns->Columns[column_index + 1].OffsetNormBeforeResize - columns->Columns[column_index].OffsetNormBeforeResize; - else - offset_norm = columns->Columns[column_index + 1].OffsetNorm - columns->Columns[column_index].OffsetNorm; - return OffsetNormToPixels(columns, offset_norm); + float offset_norm; + if (before_resize) + offset_norm = columns->Columns[column_index + 1].OffsetNormBeforeResize - columns->Columns[column_index].OffsetNormBeforeResize; + else + offset_norm = columns->Columns[column_index + 1].OffsetNorm - columns->Columns[column_index].OffsetNorm; + return OffsetNormToPixels(columns, offset_norm); } float ImGui::GetColumnWidth(int column_index) { - ImGuiWindow* window = GetCurrentWindowRead(); - ImGuiColumnsSet* columns = window->DC.ColumnsSet; - IM_ASSERT(columns != NULL); + ImGuiWindow* window = GetCurrentWindowRead(); + ImGuiColumnsSet* columns = window->DC.ColumnsSet; + IM_ASSERT(columns != NULL); - if (column_index < 0) - column_index = columns->Current; - return OffsetNormToPixels(columns, columns->Columns[column_index + 1].OffsetNorm - columns->Columns[column_index].OffsetNorm); + if (column_index < 0) + column_index = columns->Current; + return OffsetNormToPixels(columns, columns->Columns[column_index + 1].OffsetNorm - columns->Columns[column_index].OffsetNorm); } void ImGui::SetColumnOffset(int column_index, float offset) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - ImGuiColumnsSet* columns = window->DC.ColumnsSet; - IM_ASSERT(columns != NULL); + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiColumnsSet* columns = window->DC.ColumnsSet; + IM_ASSERT(columns != NULL); - if (column_index < 0) - column_index = columns->Current; - IM_ASSERT(column_index < columns->Columns.Size); + if (column_index < 0) + column_index = columns->Current; + IM_ASSERT(column_index < columns->Columns.Size); - const bool preserve_width = !(columns->Flags & ImGuiColumnsFlags_NoPreserveWidths) && (column_index < columns->Count-1); - const float width = preserve_width ? GetColumnWidthEx(columns, column_index, columns->IsBeingResized) : 0.0f; + const bool preserve_width = !(columns->Flags & ImGuiColumnsFlags_NoPreserveWidths) && (column_index < columns->Count - 1); + const float width = preserve_width ? GetColumnWidthEx(columns, column_index, columns->IsBeingResized) : 0.0f; - if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow)) - offset = ImMin(offset, columns->MaxX - g.Style.ColumnsMinSpacing * (columns->Count - column_index)); - columns->Columns[column_index].OffsetNorm = PixelsToOffsetNorm(columns, offset - columns->MinX); + if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow)) + offset = ImMin(offset, columns->MaxX - g.Style.ColumnsMinSpacing * (columns->Count - column_index)); + columns->Columns[column_index].OffsetNorm = PixelsToOffsetNorm(columns, offset - columns->MinX); - if (preserve_width) - SetColumnOffset(column_index + 1, offset + ImMax(g.Style.ColumnsMinSpacing, width)); + if (preserve_width) + SetColumnOffset(column_index + 1, offset + ImMax(g.Style.ColumnsMinSpacing, width)); } void ImGui::SetColumnWidth(int column_index, float width) { - ImGuiWindow* window = GetCurrentWindowRead(); - ImGuiColumnsSet* columns = window->DC.ColumnsSet; - IM_ASSERT(columns != NULL); + ImGuiWindow* window = GetCurrentWindowRead(); + ImGuiColumnsSet* columns = window->DC.ColumnsSet; + IM_ASSERT(columns != NULL); - if (column_index < 0) - column_index = columns->Current; - SetColumnOffset(column_index + 1, GetColumnOffset(column_index) + width); + if (column_index < 0) + column_index = columns->Current; + SetColumnOffset(column_index + 1, GetColumnOffset(column_index) + width); } void ImGui::PushColumnClipRect(int column_index) { - ImGuiWindow* window = GetCurrentWindowRead(); - ImGuiColumnsSet* columns = window->DC.ColumnsSet; - if (column_index < 0) - column_index = columns->Current; + ImGuiWindow* window = GetCurrentWindowRead(); + ImGuiColumnsSet* columns = window->DC.ColumnsSet; + if (column_index < 0) + column_index = columns->Current; - PushClipRect(columns->Columns[column_index].ClipRect.Min, columns->Columns[column_index].ClipRect.Max, false); + PushClipRect(columns->Columns[column_index].ClipRect.Min, columns->Columns[column_index].ClipRect.Max, false); } static ImGuiColumnsSet* FindOrAddColumnsSet(ImGuiWindow* window, ImGuiID id) { - for (int n = 0; n < window->ColumnsStorage.Size; n++) - if (window->ColumnsStorage[n].ID == id) - return &window->ColumnsStorage[n]; + for (int n = 0; n < window->ColumnsStorage.Size; n++) + if (window->ColumnsStorage[n].ID == id) + return &window->ColumnsStorage[n]; - window->ColumnsStorage.push_back(ImGuiColumnsSet()); - ImGuiColumnsSet* columns = &window->ColumnsStorage.back(); - columns->ID = id; - return columns; + window->ColumnsStorage.push_back(ImGuiColumnsSet()); + ImGuiColumnsSet* columns = &window->ColumnsStorage.back(); + columns->ID = id; + return columns; } void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlags flags) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); - IM_ASSERT(columns_count > 1); - IM_ASSERT(window->DC.ColumnsSet == NULL); // Nested columns are currently not supported + IM_ASSERT(columns_count > 1); + IM_ASSERT(window->DC.ColumnsSet == NULL); // Nested columns are currently not supported - // Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget. - // In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer. - PushID(0x11223347 + (str_id ? 0 : columns_count)); - ImGuiID id = window->GetID(str_id ? str_id : "columns"); - PopID(); + // Differentiate column ID with an arbitrary prefix for cases where users name their columns set the same as another widget. + // In addition, when an identifier isn't explicitly provided we include the number of columns in the hash to make it uniquer. + PushID(0x11223347 + (str_id ? 0 : columns_count)); + ImGuiID id = window->GetID(str_id ? str_id : "columns"); + PopID(); - // Acquire storage for the columns set - ImGuiColumnsSet* columns = FindOrAddColumnsSet(window, id); - IM_ASSERT(columns->ID == id); - columns->Current = 0; - columns->Count = columns_count; - columns->Flags = flags; - window->DC.ColumnsSet = columns; + // Acquire storage for the columns set + ImGuiColumnsSet* columns = FindOrAddColumnsSet(window, id); + IM_ASSERT(columns->ID == id); + columns->Current = 0; + columns->Count = columns_count; + columns->Flags = flags; + window->DC.ColumnsSet = columns; - // Set state for first column - const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->Size.x -window->ScrollbarSizes.x); - columns->MinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range - //column->MaxX = content_region_width - window->Scroll.x - ((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x; - columns->MaxX = content_region_width - window->Scroll.x; - columns->StartPosY = window->DC.CursorPos.y; - columns->StartMaxPosX = window->DC.CursorMaxPos.x; - columns->CellMinY = columns->CellMaxY = window->DC.CursorPos.y; - window->DC.ColumnsOffsetX = 0.0f; - window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); + // Set state for first column + const float content_region_width = (window->SizeContentsExplicit.x != 0.0f) ? (window->SizeContentsExplicit.x) : (window->Size.x - window->ScrollbarSizes.x); + columns->MinX = window->DC.IndentX - g.Style.ItemSpacing.x; // Lock our horizontal range + //column->MaxX = content_region_width - window->Scroll.x - ((window->Flags & ImGuiWindowFlags_NoScrollbar) ? 0 : g.Style.ScrollbarSize);// - window->WindowPadding().x; + columns->MaxX = content_region_width - window->Scroll.x; + columns->StartPosY = window->DC.CursorPos.y; + columns->StartMaxPosX = window->DC.CursorMaxPos.x; + columns->CellMinY = columns->CellMaxY = window->DC.CursorPos.y; + window->DC.ColumnsOffsetX = 0.0f; + window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); - // Clear data if columns count changed - if (columns->Columns.Size != 0 && columns->Columns.Size != columns_count + 1) - columns->Columns.resize(0); + // Clear data if columns count changed + if (columns->Columns.Size != 0 && columns->Columns.Size != columns_count + 1) + columns->Columns.resize(0); - // Initialize defaults - columns->IsFirstFrame = (columns->Columns.Size == 0); - if (columns->Columns.Size == 0) - { - columns->Columns.reserve(columns_count + 1); - for (int n = 0; n < columns_count + 1; n++) - { - ImGuiColumnData column; - column.OffsetNorm = n / (float)columns_count; - columns->Columns.push_back(column); - } - } + // Initialize defaults + columns->IsFirstFrame = (columns->Columns.Size == 0); + if (columns->Columns.Size == 0) + { + columns->Columns.reserve(columns_count + 1); + for (int n = 0; n < columns_count + 1; n++) + { + ImGuiColumnData column; + column.OffsetNorm = n / (float)columns_count; + columns->Columns.push_back(column); + } + } - for (int n = 0; n < columns_count + 1; n++) - { - // Clamp position - ImGuiColumnData* column = &columns->Columns[n]; - float t = column->OffsetNorm; - if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow)) - t = ImMin(t, PixelsToOffsetNorm(columns, (columns->MaxX - columns->MinX) - g.Style.ColumnsMinSpacing * (columns->Count - n))); - column->OffsetNorm = t; + for (int n = 0; n < columns_count + 1; n++) + { + // Clamp position + ImGuiColumnData* column = &columns->Columns[n]; + float t = column->OffsetNorm; + if (!(columns->Flags & ImGuiColumnsFlags_NoForceWithinWindow)) + t = ImMin(t, PixelsToOffsetNorm(columns, (columns->MaxX - columns->MinX) - g.Style.ColumnsMinSpacing * (columns->Count - n))); + column->OffsetNorm = t; - if (n == columns_count) - continue; + if (n == columns_count) + continue; - // Compute clipping rectangle - float clip_x1 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(n) - 1.0f); - float clip_x2 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(n + 1) - 1.0f); - column->ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX); - column->ClipRect.ClipWith(window->ClipRect); - } + // Compute clipping rectangle + float clip_x1 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(n) - 1.0f); + float clip_x2 = ImFloor(0.5f + window->Pos.x + GetColumnOffset(n + 1) - 1.0f); + column->ClipRect = ImRect(clip_x1, -FLT_MAX, clip_x2, +FLT_MAX); + column->ClipRect.ClipWith(window->ClipRect); + } - window->DrawList->ChannelsSplit(columns->Count); - PushColumnClipRect(); - PushItemWidth(GetColumnWidth() * 0.65f); + window->DrawList->ChannelsSplit(columns->Count); + PushColumnClipRect(); + PushItemWidth(GetColumnWidth() * 0.65f); } void ImGui::EndColumns() { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - ImGuiColumnsSet* columns = window->DC.ColumnsSet; - IM_ASSERT(columns != NULL); + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + ImGuiColumnsSet* columns = window->DC.ColumnsSet; + IM_ASSERT(columns != NULL); - PopItemWidth(); - PopClipRect(); - window->DrawList->ChannelsMerge(); + PopItemWidth(); + PopClipRect(); + window->DrawList->ChannelsMerge(); - columns->CellMaxY = ImMax(columns->CellMaxY, window->DC.CursorPos.y); - window->DC.CursorPos.y = columns->CellMaxY; - if (!(columns->Flags & ImGuiColumnsFlags_GrowParentContentsSize)) - window->DC.CursorMaxPos.x = ImMax(columns->StartMaxPosX, columns->MaxX); // Restore cursor max pos, as columns don't grow parent + columns->CellMaxY = ImMax(columns->CellMaxY, window->DC.CursorPos.y); + window->DC.CursorPos.y = columns->CellMaxY; + if (!(columns->Flags & ImGuiColumnsFlags_GrowParentContentsSize)) + window->DC.CursorMaxPos.x = ImMax(columns->StartMaxPosX, columns->MaxX); // Restore cursor max pos, as columns don't grow parent - // Draw columns borders and handle resize - bool is_being_resized = false; - if (!(columns->Flags & ImGuiColumnsFlags_NoBorder) && !window->SkipItems) - { - const float y1 = columns->StartPosY; - const float y2 = window->DC.CursorPos.y; - int dragging_column = -1; - for (int n = 1; n < columns->Count; n++) - { - float x = window->Pos.x + GetColumnOffset(n); - const ImGuiID column_id = columns->ID + ImGuiID(n); - const float column_hw = GetColumnsRectHalfWidth(); // Half-width for interaction - const ImRect column_rect(ImVec2(x - column_hw, y1), ImVec2(x + column_hw, y2)); - KeepAliveID(column_id); - if (IsClippedEx(column_rect, column_id, false)) - continue; - - bool hovered = false, held = false; - if (!(columns->Flags & ImGuiColumnsFlags_NoResize)) - { - ButtonBehavior(column_rect, column_id, &hovered, &held); - if (hovered || held) - g.MouseCursor = ImGuiMouseCursor_ResizeEW; - if (held && !(columns->Columns[n].Flags & ImGuiColumnsFlags_NoResize)) - dragging_column = n; - } + // Draw columns borders and handle resize + bool is_being_resized = false; + if (!(columns->Flags & ImGuiColumnsFlags_NoBorder) && !window->SkipItems) + { + const float y1 = columns->StartPosY; + const float y2 = window->DC.CursorPos.y; + int dragging_column = -1; + for (int n = 1; n < columns->Count; n++) + { + float x = window->Pos.x + GetColumnOffset(n); + const ImGuiID column_id = columns->ID + ImGuiID(n); + const float column_hw = GetColumnsRectHalfWidth(); // Half-width for interaction + const ImRect column_rect(ImVec2(x - column_hw, y1), ImVec2(x + column_hw, y2)); + KeepAliveID(column_id); + if (IsClippedEx(column_rect, column_id, false)) + continue; - // Draw column (we clip the Y boundaries CPU side because very long triangles are mishandled by some GPU drivers.) - const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator); - const float xi = (float)(int)x; - window->DrawList->AddLine(ImVec2(xi, ImMax(y1 + 1.0f, window->ClipRect.Min.y)), ImVec2(xi, ImMin(y2, window->ClipRect.Max.y)), col); - } + bool hovered = false, held = false; + if (!(columns->Flags & ImGuiColumnsFlags_NoResize)) + { + ButtonBehavior(column_rect, column_id, &hovered, &held); + if (hovered || held) + g.MouseCursor = ImGuiMouseCursor_ResizeEW; + if (held && !(columns->Columns[n].Flags & ImGuiColumnsFlags_NoResize)) + dragging_column = n; + } - // Apply dragging after drawing the column lines, so our rendered lines are in sync with how items were displayed during the frame. - if (dragging_column != -1) - { - if (!columns->IsBeingResized) - for (int n = 0; n < columns->Count + 1; n++) - columns->Columns[n].OffsetNormBeforeResize = columns->Columns[n].OffsetNorm; - columns->IsBeingResized = is_being_resized = true; - float x = GetDraggedColumnOffset(columns, dragging_column); - SetColumnOffset(dragging_column, x); - } - } - columns->IsBeingResized = is_being_resized; + // Draw column (we clip the Y boundaries CPU side because very long triangles are mishandled by some GPU drivers.) + const ImU32 col = GetColorU32(held ? ImGuiCol_SeparatorActive : hovered ? ImGuiCol_SeparatorHovered : ImGuiCol_Separator); + const float xi = (float)(int)x; + window->DrawList->AddLine(ImVec2(xi, ImMax(y1 + 1.0f, window->ClipRect.Min.y)), ImVec2(xi, ImMin(y2, window->ClipRect.Max.y)), col); + } - window->DC.ColumnsSet = NULL; - window->DC.ColumnsOffsetX = 0.0f; - window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); + // Apply dragging after drawing the column lines, so our rendered lines are in sync with how items were displayed during the frame. + if (dragging_column != -1) + { + if (!columns->IsBeingResized) + for (int n = 0; n < columns->Count + 1; n++) + columns->Columns[n].OffsetNormBeforeResize = columns->Columns[n].OffsetNorm; + columns->IsBeingResized = is_being_resized = true; + float x = GetDraggedColumnOffset(columns, dragging_column); + SetColumnOffset(dragging_column, x); + } + } + columns->IsBeingResized = is_being_resized; + + window->DC.ColumnsSet = NULL; + window->DC.ColumnsOffsetX = 0.0f; + window->DC.CursorPos.x = (float)(int)(window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX); } // [2017/12: This is currently the only public API, while we are working on making BeginColumns/EndColumns user-facing] void ImGui::Columns(int columns_count, const char* id, bool border) { - ImGuiWindow* window = GetCurrentWindow(); - IM_ASSERT(columns_count >= 1); - if (window->DC.ColumnsSet != NULL && window->DC.ColumnsSet->Count != columns_count) - EndColumns(); - - ImGuiColumnsFlags flags = (border ? 0 : ImGuiColumnsFlags_NoBorder); - //flags |= ImGuiColumnsFlags_NoPreserveWidths; // NB: Legacy behavior - if (columns_count != 1) - BeginColumns(id, columns_count, flags); + ImGuiWindow* window = GetCurrentWindow(); + IM_ASSERT(columns_count >= 1); + if (window->DC.ColumnsSet != NULL && window->DC.ColumnsSet->Count != columns_count) + EndColumns(); + + ImGuiColumnsFlags flags = (border ? 0 : ImGuiColumnsFlags_NoBorder); + //flags |= ImGuiColumnsFlags_NoPreserveWidths; // NB: Legacy behavior + if (columns_count != 1) + BeginColumns(id, columns_count, flags); } void ImGui::Indent(float indent_w) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - window->DC.IndentX += (indent_w != 0.0f) ? indent_w : g.Style.IndentSpacing; - window->DC.CursorPos.x = window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + window->DC.IndentX += (indent_w != 0.0f) ? indent_w : g.Style.IndentSpacing; + window->DC.CursorPos.x = window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX; } void ImGui::Unindent(float indent_w) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = GetCurrentWindow(); - window->DC.IndentX -= (indent_w != 0.0f) ? indent_w : g.Style.IndentSpacing; - window->DC.CursorPos.x = window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = GetCurrentWindow(); + window->DC.IndentX -= (indent_w != 0.0f) ? indent_w : g.Style.IndentSpacing; + window->DC.CursorPos.x = window->Pos.x + window->DC.IndentX + window->DC.ColumnsOffsetX; } void ImGui::TreePush(const char* str_id) { - ImGuiWindow* window = GetCurrentWindow(); - Indent(); - window->DC.TreeDepth++; - PushID(str_id ? str_id : "#TreePush"); + ImGuiWindow* window = GetCurrentWindow(); + Indent(); + window->DC.TreeDepth++; + PushID(str_id ? str_id : "#TreePush"); } void ImGui::TreePush(const void* ptr_id) { - ImGuiWindow* window = GetCurrentWindow(); - Indent(); - window->DC.TreeDepth++; - PushID(ptr_id ? ptr_id : (const void*)"#TreePush"); + ImGuiWindow* window = GetCurrentWindow(); + Indent(); + window->DC.TreeDepth++; + PushID(ptr_id ? ptr_id : (const void*)"#TreePush"); } void ImGui::TreePushRawID(ImGuiID id) { - ImGuiWindow* window = GetCurrentWindow(); - Indent(); - window->DC.TreeDepth++; - window->IDStack.push_back(id); + ImGuiWindow* window = GetCurrentWindow(); + Indent(); + window->DC.TreeDepth++; + window->IDStack.push_back(id); } void ImGui::TreePop() { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - Unindent(); + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + Unindent(); - window->DC.TreeDepth--; - if (g.NavMoveDir == ImGuiDir_Left && g.NavWindow == window && NavMoveRequestButNoResultYet()) - if (g.NavIdIsAlive && (window->DC.TreeDepthMayCloseOnPop & (1 << window->DC.TreeDepth))) - { - SetNavID(window->IDStack.back(), g.NavLayer); - NavMoveRequestCancel(); - } - window->DC.TreeDepthMayCloseOnPop &= (1 << window->DC.TreeDepth) - 1; + window->DC.TreeDepth--; + if (g.NavMoveDir == ImGuiDir_Left && g.NavWindow == window && NavMoveRequestButNoResultYet()) + if (g.NavIdIsAlive && (window->DC.TreeDepthMayCloseOnPop & (1 << window->DC.TreeDepth))) + { + SetNavID(window->IDStack.back(), g.NavLayer); + NavMoveRequestCancel(); + } + window->DC.TreeDepthMayCloseOnPop &= (1 << window->DC.TreeDepth) - 1; - PopID(); + PopID(); } void ImGui::Value(const char* prefix, bool b) { - Text("%s: %s", prefix, (b ? "true" : "false")); + Text("%s: %s", prefix, (b ? "true" : "false")); } void ImGui::Value(const char* prefix, int v) { - Text("%s: %d", prefix, v); + Text("%s: %d", prefix, v); } void ImGui::Value(const char* prefix, unsigned int v) { - Text("%s: %d", prefix, v); + Text("%s: %d", prefix, v); } void ImGui::Value(const char* prefix, float v, const char* float_format) { - if (float_format) - { - char fmt[64]; - ImFormatString(fmt, IM_ARRAYSIZE(fmt), "%%s: %s", float_format); - Text(fmt, prefix, v); - } - else - { - Text("%s: %.3f", prefix, v); - } + if (float_format) + { + char fmt[64]; + ImFormatString(fmt, IM_ARRAYSIZE(fmt), "%%s: %s", float_format); + Text(fmt, prefix, v); + } + else + { + Text("%s: %.3f", prefix, v); + } } //----------------------------------------------------------------------------- @@ -12734,182 +13059,182 @@ void ImGui::Value(const char* prefix, float v, const char* float_format) void ImGui::ClearDragDrop() { - ImGuiContext& g = *GImGui; - g.DragDropActive = false; - g.DragDropPayload.Clear(); - g.DragDropAcceptIdCurr = g.DragDropAcceptIdPrev = 0; - g.DragDropAcceptIdCurrRectSurface = FLT_MAX; - g.DragDropAcceptFrameCount = -1; + ImGuiContext& g = *GImGui; + g.DragDropActive = false; + g.DragDropPayload.Clear(); + g.DragDropAcceptIdCurr = g.DragDropAcceptIdPrev = 0; + g.DragDropAcceptIdCurrRectSurface = FLT_MAX; + g.DragDropAcceptFrameCount = -1; } -// Call when current ID is active. +// Call when current ID is active. // When this returns true you need to: a) call SetDragDropPayload() exactly once, b) you may render the payload visual/description, c) call EndDragDropSource() bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; - bool source_drag_active = false; - ImGuiID source_id = 0; - ImGuiID source_parent_id = 0; - int mouse_button = 0; - if (!(flags & ImGuiDragDropFlags_SourceExtern)) - { - source_id = window->DC.LastItemId; - if (source_id != 0 && g.ActiveId != source_id) // Early out for most common case - return false; - if (g.IO.MouseDown[mouse_button] == false) - return false; + bool source_drag_active = false; + ImGuiID source_id = 0; + ImGuiID source_parent_id = 0; + int mouse_button = 0; + if (!(flags & ImGuiDragDropFlags_SourceExtern)) + { + source_id = window->DC.LastItemId; + if (source_id != 0 && g.ActiveId != source_id) // Early out for most common case + return false; + if (g.IO.MouseDown[mouse_button] == false) + return false; - if (source_id == 0) - { - // If you want to use BeginDragDropSource() on an item with no unique identifier for interaction, such as Text() or Image(), you need to: - // A) Read the explanation below, B) Use the ImGuiDragDropFlags_SourceAllowNullID flag, C) Swallow your programmer pride. - if (!(flags & ImGuiDragDropFlags_SourceAllowNullID)) - { - IM_ASSERT(0); - return false; - } + if (source_id == 0) + { + // If you want to use BeginDragDropSource() on an item with no unique identifier for interaction, such as Text() or Image(), you need to: + // A) Read the explanation below, B) Use the ImGuiDragDropFlags_SourceAllowNullID flag, C) Swallow your programmer pride. + if (!(flags & ImGuiDragDropFlags_SourceAllowNullID)) + { + IM_ASSERT(0); + return false; + } - // Magic fallback (=somehow reprehensible) to handle items with no assigned ID, e.g. Text(), Image() - // We build a throwaway ID based on current ID stack + relative AABB of items in window. - // THE IDENTIFIER WON'T SURVIVE ANY REPOSITIONING OF THE WIDGET, so if your widget moves your dragging operation will be canceled. - // We don't need to maintain/call ClearActiveID() as releasing the button will early out this function and trigger !ActiveIdIsAlive. - bool is_hovered = (window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HoveredRect) != 0; - if (!is_hovered && (g.ActiveId == 0 || g.ActiveIdWindow != window)) - return false; - source_id = window->DC.LastItemId = window->GetIDFromRectangle(window->DC.LastItemRect); - if (is_hovered) - SetHoveredID(source_id); - if (is_hovered && g.IO.MouseClicked[mouse_button]) - { - SetActiveID(source_id, window); - FocusWindow(window); - } - if (g.ActiveId == source_id) // Allow the underlying widget to display/return hovered during the mouse release frame, else we would get a flicker. - g.ActiveIdAllowOverlap = is_hovered; - } - if (g.ActiveId != source_id) - return false; - source_parent_id = window->IDStack.back(); - source_drag_active = IsMouseDragging(mouse_button); - } - else - { - window = NULL; - source_id = ImHash("#SourceExtern", 0); - source_drag_active = true; - } + // Magic fallback (=somehow reprehensible) to handle items with no assigned ID, e.g. Text(), Image() + // We build a throwaway ID based on current ID stack + relative AABB of items in window. + // THE IDENTIFIER WON'T SURVIVE ANY REPOSITIONING OF THE WIDGET, so if your widget moves your dragging operation will be canceled. + // We don't need to maintain/call ClearActiveID() as releasing the button will early out this function and trigger !ActiveIdIsAlive. + bool is_hovered = (window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HoveredRect) != 0; + if (!is_hovered && (g.ActiveId == 0 || g.ActiveIdWindow != window)) + return false; + source_id = window->DC.LastItemId = window->GetIDFromRectangle(window->DC.LastItemRect); + if (is_hovered) + SetHoveredID(source_id); + if (is_hovered && g.IO.MouseClicked[mouse_button]) + { + SetActiveID(source_id, window); + FocusWindow(window); + } + if (g.ActiveId == source_id) // Allow the underlying widget to display/return hovered during the mouse release frame, else we would get a flicker. + g.ActiveIdAllowOverlap = is_hovered; + } + if (g.ActiveId != source_id) + return false; + source_parent_id = window->IDStack.back(); + source_drag_active = IsMouseDragging(mouse_button); + } + else + { + window = NULL; + source_id = ImHash("#SourceExtern", 0); + source_drag_active = true; + } - if (source_drag_active) - { - if (!g.DragDropActive) - { - IM_ASSERT(source_id != 0); - ClearDragDrop(); - ImGuiPayload& payload = g.DragDropPayload; - payload.SourceId = source_id; - payload.SourceParentId = source_parent_id; - g.DragDropActive = true; - g.DragDropSourceFlags = flags; - g.DragDropMouseButton = mouse_button; - } + if (source_drag_active) + { + if (!g.DragDropActive) + { + IM_ASSERT(source_id != 0); + ClearDragDrop(); + ImGuiPayload& payload = g.DragDropPayload; + payload.SourceId = source_id; + payload.SourceParentId = source_parent_id; + g.DragDropActive = true; + g.DragDropSourceFlags = flags; + g.DragDropMouseButton = mouse_button; + } - if (!(flags & ImGuiDragDropFlags_SourceNoPreviewTooltip)) - { - // FIXME-DRAG - //SetNextWindowPos(g.IO.MousePos - g.ActiveIdClickOffset - g.Style.WindowPadding); - //PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * 0.60f); // This is better but e.g ColorButton with checkboard has issue with transparent colors :( - SetNextWindowPos(g.IO.MousePos); - PushStyleColor(ImGuiCol_PopupBg, GetStyleColorVec4(ImGuiCol_PopupBg) * ImVec4(1.0f, 1.0f, 1.0f, 0.6f)); - BeginTooltip(); - } + if (!(flags & ImGuiDragDropFlags_SourceNoPreviewTooltip)) + { + // FIXME-DRAG + //SetNextWindowPos(g.IO.MousePos - g.ActiveIdClickOffset - g.Style.WindowPadding); + //PushStyleVar(ImGuiStyleVar_Alpha, g.Style.Alpha * 0.60f); // This is better but e.g ColorButton with checkboard has issue with transparent colors :( + SetNextWindowPos(g.IO.MousePos); + PushStyleColor(ImGuiCol_PopupBg, GetStyleColorVec4(ImGuiCol_PopupBg) * ImVec4(1.0f, 1.0f, 1.0f, 0.6f)); + BeginTooltip(); + } - if (!(flags & ImGuiDragDropFlags_SourceNoDisableHover) && !(flags & ImGuiDragDropFlags_SourceExtern)) - window->DC.LastItemStatusFlags &= ~ImGuiItemStatusFlags_HoveredRect; + if (!(flags & ImGuiDragDropFlags_SourceNoDisableHover) && !(flags & ImGuiDragDropFlags_SourceExtern)) + window->DC.LastItemStatusFlags &= ~ImGuiItemStatusFlags_HoveredRect; - return true; - } - return false; + return true; + } + return false; } void ImGui::EndDragDropSource() { - ImGuiContext& g = *GImGui; - IM_ASSERT(g.DragDropActive); + ImGuiContext& g = *GImGui; + IM_ASSERT(g.DragDropActive); - if (!(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoPreviewTooltip)) - { - EndTooltip(); - PopStyleColor(); - //PopStyleVar(); - } + if (!(g.DragDropSourceFlags & ImGuiDragDropFlags_SourceNoPreviewTooltip)) + { + EndTooltip(); + PopStyleColor(); + //PopStyleVar(); + } - // Discard the drag if have not called SetDragDropPayload() - if (g.DragDropPayload.DataFrameCount == -1) - ClearDragDrop(); + // Discard the drag if have not called SetDragDropPayload() + if (g.DragDropPayload.DataFrameCount == -1) + ClearDragDrop(); } // Use 'cond' to choose to submit payload on drag start or every frame bool ImGui::SetDragDropPayload(const char* type, const void* data, size_t data_size, ImGuiCond cond) { - ImGuiContext& g = *GImGui; - ImGuiPayload& payload = g.DragDropPayload; - if (cond == 0) - cond = ImGuiCond_Always; + ImGuiContext& g = *GImGui; + ImGuiPayload& payload = g.DragDropPayload; + if (cond == 0) + cond = ImGuiCond_Always; - IM_ASSERT(type != NULL); - IM_ASSERT(strlen(type) < IM_ARRAYSIZE(payload.DataType) && "Payload type can be at most 12 characters long"); - IM_ASSERT((data != NULL && data_size > 0) || (data == NULL && data_size == 0)); - IM_ASSERT(cond == ImGuiCond_Always || cond == ImGuiCond_Once); - IM_ASSERT(payload.SourceId != 0); // Not called between BeginDragDropSource() and EndDragDropSource() + IM_ASSERT(type != NULL); + IM_ASSERT(strlen(type) < IM_ARRAYSIZE(payload.DataType) && "Payload type can be at most 12 characters long"); + IM_ASSERT((data != NULL && data_size > 0) || (data == NULL && data_size == 0)); + IM_ASSERT(cond == ImGuiCond_Always || cond == ImGuiCond_Once); + IM_ASSERT(payload.SourceId != 0); // Not called between BeginDragDropSource() and EndDragDropSource() - if (cond == ImGuiCond_Always || payload.DataFrameCount == -1) - { - // Copy payload - ImStrncpy(payload.DataType, type, IM_ARRAYSIZE(payload.DataType)); - g.DragDropPayloadBufHeap.resize(0); - if (data_size > sizeof(g.DragDropPayloadBufLocal)) - { - // Store in heap - g.DragDropPayloadBufHeap.resize((int)data_size); - payload.Data = g.DragDropPayloadBufHeap.Data; - memcpy((void*)payload.Data, data, data_size); - } - else if (data_size > 0) - { - // Store locally - memset(&g.DragDropPayloadBufLocal, 0, sizeof(g.DragDropPayloadBufLocal)); - payload.Data = g.DragDropPayloadBufLocal; - memcpy((void*)payload.Data, data, data_size); - } - else - { - payload.Data = NULL; - } - payload.DataSize = (int)data_size; - } - payload.DataFrameCount = g.FrameCount; + if (cond == ImGuiCond_Always || payload.DataFrameCount == -1) + { + // Copy payload + ImStrncpy(payload.DataType, type, IM_ARRAYSIZE(payload.DataType)); + g.DragDropPayloadBufHeap.resize(0); + if (data_size > sizeof(g.DragDropPayloadBufLocal)) + { + // Store in heap + g.DragDropPayloadBufHeap.resize((int)data_size); + payload.Data = g.DragDropPayloadBufHeap.Data; + memcpy((void*)payload.Data, data, data_size); + } + else if (data_size > 0) + { + // Store locally + memset(&g.DragDropPayloadBufLocal, 0, sizeof(g.DragDropPayloadBufLocal)); + payload.Data = g.DragDropPayloadBufLocal; + memcpy((void*)payload.Data, data, data_size); + } + else + { + payload.Data = NULL; + } + payload.DataSize = (int)data_size; + } + payload.DataFrameCount = g.FrameCount; - return (g.DragDropAcceptFrameCount == g.FrameCount) || (g.DragDropAcceptFrameCount == g.FrameCount - 1); + return (g.DragDropAcceptFrameCount == g.FrameCount) || (g.DragDropAcceptFrameCount == g.FrameCount - 1); } bool ImGui::BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id) { - ImGuiContext& g = *GImGui; - if (!g.DragDropActive) - return false; + ImGuiContext& g = *GImGui; + if (!g.DragDropActive) + return false; - ImGuiWindow* window = g.CurrentWindow; - if (g.HoveredWindow == NULL || window->RootWindow != g.HoveredWindow->RootWindow) - return false; - IM_ASSERT(id != 0); - if (!IsMouseHoveringRect(bb.Min, bb.Max) || (id == g.DragDropPayload.SourceId)) - return false; + ImGuiWindow* window = g.CurrentWindow; + if (g.HoveredWindow == NULL || window->RootWindow != g.HoveredWindow->RootWindow) + return false; + IM_ASSERT(id != 0); + if (!IsMouseHoveringRect(bb.Min, bb.Max) || (id == g.DragDropPayload.SourceId)) + return false; - g.DragDropTargetRect = bb; - g.DragDropTargetId = id; - return true; + g.DragDropTargetRect = bb; + g.DragDropTargetId = id; + return true; } // We don't use BeginDragDropTargetCustom() and duplicate its code because: @@ -12918,81 +13243,82 @@ bool ImGui::BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id) // Also note how the HoveredWindow test is positioned differently in both functions (in both functions we optimize for the cheapest early out case) bool ImGui::BeginDragDropTarget() { - ImGuiContext& g = *GImGui; - if (!g.DragDropActive) - return false; + ImGuiContext& g = *GImGui; + if (!g.DragDropActive) + return false; - ImGuiWindow* window = g.CurrentWindow; - if (!(window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HoveredRect)) - return false; - if (g.HoveredWindow == NULL || window->RootWindow != g.HoveredWindow->RootWindow) - return false; + ImGuiWindow* window = g.CurrentWindow; + if (!(window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HoveredRect)) + return false; + if (g.HoveredWindow == NULL || window->RootWindow != g.HoveredWindow->RootWindow) + return false; - const ImRect& display_rect = (window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HasDisplayRect) ? window->DC.LastItemDisplayRect : window->DC.LastItemRect; - ImGuiID id = window->DC.LastItemId; - if (id == 0) - id = window->GetIDFromRectangle(display_rect); - if (g.DragDropPayload.SourceId == id) - return false; + const ImRect& display_rect = (window->DC.LastItemStatusFlags & ImGuiItemStatusFlags_HasDisplayRect) ? window->DC.LastItemDisplayRect : window->DC.LastItemRect; + ImGuiID id = window->DC.LastItemId; + if (id == 0) + id = window->GetIDFromRectangle(display_rect); + if (g.DragDropPayload.SourceId == id) + return false; - g.DragDropTargetRect = display_rect; - g.DragDropTargetId = id; - return true; + g.DragDropTargetRect = display_rect; + g.DragDropTargetId = id; + return true; } bool ImGui::IsDragDropPayloadBeingAccepted() { - ImGuiContext& g = *GImGui; - return g.DragDropActive && g.DragDropAcceptIdPrev != 0; + ImGuiContext& g = *GImGui; + return g.DragDropActive && g.DragDropAcceptIdPrev != 0; } const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags) { - ImGuiContext& g = *GImGui; - ImGuiWindow* window = g.CurrentWindow; - ImGuiPayload& payload = g.DragDropPayload; - IM_ASSERT(g.DragDropActive); // Not called between BeginDragDropTarget() and EndDragDropTarget() ? - IM_ASSERT(payload.DataFrameCount != -1); // Forgot to call EndDragDropTarget() ? - if (type != NULL && !payload.IsDataType(type)) - return NULL; + ImGuiContext& g = *GImGui; + ImGuiWindow* window = g.CurrentWindow; + ImGuiPayload& payload = g.DragDropPayload; + IM_ASSERT(g.DragDropActive); // Not called between BeginDragDropTarget() and EndDragDropTarget() ? + IM_ASSERT(payload.DataFrameCount != -1); // Forgot to call EndDragDropTarget() ? + if (type != NULL && !payload.IsDataType(type)) + return NULL; - // Accept smallest drag target bounding box, this allows us to nest drag targets conveniently without ordering constraints. - // NB: We currently accept NULL id as target. However, overlapping targets requires a unique ID to function! - const bool was_accepted_previously = (g.DragDropAcceptIdPrev == g.DragDropTargetId); - ImRect r = g.DragDropTargetRect; - float r_surface = r.GetWidth() * r.GetHeight(); - if (r_surface < g.DragDropAcceptIdCurrRectSurface) - { - g.DragDropAcceptIdCurr = g.DragDropTargetId; - g.DragDropAcceptIdCurrRectSurface = r_surface; - } + // Accept smallest drag target bounding box, this allows us to nest drag targets conveniently without ordering constraints. + // NB: We currently accept NULL id as target. However, overlapping targets requires a unique ID to function! + const bool was_accepted_previously = (g.DragDropAcceptIdPrev == g.DragDropTargetId); + ImRect r = g.DragDropTargetRect; + float r_surface = r.GetWidth() * r.GetHeight(); + if (r_surface < g.DragDropAcceptIdCurrRectSurface) + { + g.DragDropAcceptIdCurr = g.DragDropTargetId; + g.DragDropAcceptIdCurrRectSurface = r_surface; + } - // Render default drop visuals - payload.Preview = was_accepted_previously; - flags |= (g.DragDropSourceFlags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect); // Source can also inhibit the preview (useful for external sources that lives for 1 frame) - if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && payload.Preview) - { - // FIXME-DRAG: Settle on a proper default visuals for drop target. - r.Expand(3.5f); - bool push_clip_rect = !window->ClipRect.Contains(r); - if (push_clip_rect) window->DrawList->PushClipRectFullScreen(); - window->DrawList->AddRect(r.Min, r.Max, GetColorU32(ImGuiCol_DragDropTarget), 0.0f, ~0, 2.0f); - if (push_clip_rect) window->DrawList->PopClipRect(); - } + // Render default drop visuals + payload.Preview = was_accepted_previously; + flags |= (g.DragDropSourceFlags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect); // Source can also inhibit the preview (useful for external sources that lives for 1 frame) + if (!(flags & ImGuiDragDropFlags_AcceptNoDrawDefaultRect) && payload.Preview) + { + // FIXME-DRAG: Settle on a proper default visuals for drop target. + r.Expand(3.5f); + bool push_clip_rect = !window->ClipRect.Contains(r); + if (push_clip_rect) window->DrawList->PushClipRectFullScreen(); + window->DrawList->AddRect(r.Min, r.Max, GetColorU32(ImGuiCol_DragDropTarget), 0.0f, ~0, 2.0f); + if (push_clip_rect) window->DrawList->PopClipRect(); + } - g.DragDropAcceptFrameCount = g.FrameCount; - payload.Delivery = was_accepted_previously && !IsMouseDown(g.DragDropMouseButton); // For extern drag sources affecting os window focus, it's easier to just test !IsMouseDown() instead of IsMouseReleased() - if (!payload.Delivery && !(flags & ImGuiDragDropFlags_AcceptBeforeDelivery)) - return NULL; + g.DragDropAcceptFrameCount = g.FrameCount; + payload.Delivery = was_accepted_previously && !IsMouseDown(g.DragDropMouseButton); // For extern drag sources affecting os window focus, it's easier to just test !IsMouseDown() instead of IsMouseReleased() + if (!payload.Delivery && !(flags & ImGuiDragDropFlags_AcceptBeforeDelivery)) + return NULL; - return &payload; + return &payload; } // We don't really use/need this now, but added it for the sake of consistency and because we might need it later. void ImGui::EndDragDropTarget() { - ImGuiContext& g = *GImGui; (void)g; - IM_ASSERT(g.DragDropActive); + ImGuiContext& g = *GImGui; + (void)g; + IM_ASSERT(g.DragDropActive); } //----------------------------------------------------------------------------- @@ -13018,44 +13344,44 @@ void ImGui::EndDragDropTarget() static const char* GetClipboardTextFn_DefaultImpl(void*) { - static ImVector buf_local; - buf_local.clear(); - if (!OpenClipboard(NULL)) - return NULL; - HANDLE wbuf_handle = GetClipboardData(CF_UNICODETEXT); - if (wbuf_handle == NULL) - { - CloseClipboard(); - return NULL; - } - if (ImWchar* wbuf_global = (ImWchar*)GlobalLock(wbuf_handle)) - { - int buf_len = ImTextCountUtf8BytesFromStr(wbuf_global, NULL) + 1; - buf_local.resize(buf_len); - ImTextStrToUtf8(buf_local.Data, buf_len, wbuf_global, NULL); - } - GlobalUnlock(wbuf_handle); - CloseClipboard(); - return buf_local.Data; + static ImVector buf_local; + buf_local.clear(); + if (!OpenClipboard(NULL)) + return NULL; + HANDLE wbuf_handle = GetClipboardData(CF_UNICODETEXT); + if (wbuf_handle == NULL) + { + CloseClipboard(); + return NULL; + } + if (ImWchar* wbuf_global = (ImWchar*)GlobalLock(wbuf_handle)) + { + int buf_len = ImTextCountUtf8BytesFromStr(wbuf_global, NULL) + 1; + buf_local.resize(buf_len); + ImTextStrToUtf8(buf_local.Data, buf_len, wbuf_global, NULL); + } + GlobalUnlock(wbuf_handle); + CloseClipboard(); + return buf_local.Data; } static void SetClipboardTextFn_DefaultImpl(void*, const char* text) { - if (!OpenClipboard(NULL)) - return; - const int wbuf_length = ImTextCountCharsFromUtf8(text, NULL) + 1; - HGLOBAL wbuf_handle = GlobalAlloc(GMEM_MOVEABLE, (SIZE_T)wbuf_length * sizeof(ImWchar)); - if (wbuf_handle == NULL) - { - CloseClipboard(); - return; - } - ImWchar* wbuf_global = (ImWchar*)GlobalLock(wbuf_handle); - ImTextStrFromUtf8(wbuf_global, wbuf_length, text, NULL); - GlobalUnlock(wbuf_handle); - EmptyClipboard(); - SetClipboardData(CF_UNICODETEXT, wbuf_handle); - CloseClipboard(); + if (!OpenClipboard(NULL)) + return; + const int wbuf_length = ImTextCountCharsFromUtf8(text, NULL) + 1; + HGLOBAL wbuf_handle = GlobalAlloc(GMEM_MOVEABLE, (SIZE_T)wbuf_length * sizeof(ImWchar)); + if (wbuf_handle == NULL) + { + CloseClipboard(); + return; + } + ImWchar* wbuf_global = (ImWchar*)GlobalLock(wbuf_handle); + ImTextStrFromUtf8(wbuf_global, wbuf_length, text, NULL); + GlobalUnlock(wbuf_handle); + EmptyClipboard(); + SetClipboardData(CF_UNICODETEXT, wbuf_handle); + CloseClipboard(); } #else @@ -13063,19 +13389,19 @@ static void SetClipboardTextFn_DefaultImpl(void*, const char* text) // Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers static const char* GetClipboardTextFn_DefaultImpl(void*) { - ImGuiContext& g = *GImGui; - return g.PrivateClipboard.empty() ? NULL : g.PrivateClipboard.begin(); + ImGuiContext& g = *GImGui; + return g.PrivateClipboard.empty() ? NULL : g.PrivateClipboard.begin(); } // Local ImGui-only clipboard implementation, if user hasn't defined better clipboard handlers static void SetClipboardTextFn_DefaultImpl(void*, const char* text) { - ImGuiContext& g = *GImGui; - g.PrivateClipboard.clear(); - const char* text_end = text + strlen(text); - g.PrivateClipboard.resize((int)(text_end - text) + 1); - memcpy(&g.PrivateClipboard[0], text, (size_t)(text_end - text)); - g.PrivateClipboard[(int)(text_end - text)] = 0; + ImGuiContext& g = *GImGui; + g.PrivateClipboard.clear(); + const char* text_end = text + strlen(text); + g.PrivateClipboard.resize((int)(text_end - text) + 1); + memcpy(&g.PrivateClipboard[0], text, (size_t)(text_end - text)); + g.PrivateClipboard[(int)(text_end - text)] = 0; } #endif @@ -13090,21 +13416,23 @@ static void SetClipboardTextFn_DefaultImpl(void*, const char* text) static void ImeSetInputScreenPosFn_DefaultImpl(int x, int y) { - // Notify OS Input Method Editor of text input position - if (HWND hwnd = (HWND)GImGui->IO.ImeWindowHandle) - if (HIMC himc = ImmGetContext(hwnd)) - { - COMPOSITIONFORM cf; - cf.ptCurrentPos.x = x; - cf.ptCurrentPos.y = y; - cf.dwStyle = CFS_FORCE_POSITION; - ImmSetCompositionWindow(himc, &cf); - } + // Notify OS Input Method Editor of text input position + if (HWND hwnd = (HWND)GImGui->IO.ImeWindowHandle) + if (HIMC himc = ImmGetContext(hwnd)) + { + COMPOSITIONFORM cf; + cf.ptCurrentPos.x = x; + cf.ptCurrentPos.y = y; + cf.dwStyle = CFS_FORCE_POSITION; + ImmSetCompositionWindow(himc, &cf); + } } #else -static void ImeSetInputScreenPosFn_DefaultImpl(int, int) {} +static void ImeSetInputScreenPosFn_DefaultImpl(int, int) +{ +} #endif @@ -13114,157 +13442,160 @@ static void ImeSetInputScreenPosFn_DefaultImpl(int, int) {} void ImGui::ShowMetricsWindow(bool* p_open) { - if (ImGui::Begin("ImGui Metrics", p_open)) - { - ImGui::Text("Dear ImGui %s", ImGui::GetVersion()); - ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); - ImGui::Text("%d vertices, %d indices (%d triangles)", ImGui::GetIO().MetricsRenderVertices, ImGui::GetIO().MetricsRenderIndices, ImGui::GetIO().MetricsRenderIndices / 3); - ImGui::Text("%d allocations", (int)GImAllocatorActiveAllocationsCount); - static bool show_clip_rects = true; - ImGui::Checkbox("Show clipping rectangles when hovering draw commands", &show_clip_rects); - ImGui::Separator(); + if (ImGui::Begin("ImGui Metrics", p_open)) + { + ImGui::Text("Dear ImGui %s", ImGui::GetVersion()); + ImGui::Text("Application average %.3f ms/frame (%.1f FPS)", 1000.0f / ImGui::GetIO().Framerate, ImGui::GetIO().Framerate); + ImGui::Text("%d vertices, %d indices (%d triangles)", ImGui::GetIO().MetricsRenderVertices, ImGui::GetIO().MetricsRenderIndices, ImGui::GetIO().MetricsRenderIndices / 3); + ImGui::Text("%d allocations", (int)GImAllocatorActiveAllocationsCount); + static bool show_clip_rects = true; + ImGui::Checkbox("Show clipping rectangles when hovering draw commands", &show_clip_rects); + ImGui::Separator(); - struct Funcs - { - static void NodeDrawList(ImGuiWindow* window, ImDrawList* draw_list, const char* label) - { - bool node_open = ImGui::TreeNode(draw_list, "%s: '%s' %d vtx, %d indices, %d cmds", label, draw_list->_OwnerName ? draw_list->_OwnerName : "", draw_list->VtxBuffer.Size, draw_list->IdxBuffer.Size, draw_list->CmdBuffer.Size); - if (draw_list == ImGui::GetWindowDrawList()) - { - ImGui::SameLine(); - ImGui::TextColored(ImColor(255,100,100), "CURRENTLY APPENDING"); // Can't display stats for active draw list! (we don't have the data double-buffered) - if (node_open) ImGui::TreePop(); - return; - } + struct Funcs + { + static void NodeDrawList(ImGuiWindow* window, ImDrawList* draw_list, const char* label) + { + bool node_open = ImGui::TreeNode(draw_list, "%s: '%s' %d vtx, %d indices, %d cmds", label, draw_list->_OwnerName ? draw_list->_OwnerName : "", draw_list->VtxBuffer.Size, draw_list->IdxBuffer.Size, draw_list->CmdBuffer.Size); + if (draw_list == ImGui::GetWindowDrawList()) + { + ImGui::SameLine(); + ImGui::TextColored(ImColor(255, 100, 100), "CURRENTLY APPENDING"); // Can't display stats for active draw list! (we don't have the data double-buffered) + if (node_open) ImGui::TreePop(); + return; + } - ImDrawList* overlay_draw_list = ImGui::GetOverlayDrawList(); // Render additional visuals into the top-most draw list - if (window && ImGui::IsItemHovered()) - overlay_draw_list->AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255, 255, 0, 255)); - if (!node_open) - return; + ImDrawList* overlay_draw_list = ImGui::GetOverlayDrawList(); // Render additional visuals into the top-most draw list + if (window && ImGui::IsItemHovered()) + overlay_draw_list->AddRect(window->Pos, window->Pos + window->Size, IM_COL32(255, 255, 0, 255)); + if (!node_open) + return; - int elem_offset = 0; - for (const ImDrawCmd* pcmd = draw_list->CmdBuffer.begin(); pcmd < draw_list->CmdBuffer.end(); elem_offset += pcmd->ElemCount, pcmd++) - { - if (pcmd->UserCallback == NULL && pcmd->ElemCount == 0) - continue; - if (pcmd->UserCallback) - { - ImGui::BulletText("Callback %p, user_data %p", pcmd->UserCallback, pcmd->UserCallbackData); - continue; - } - ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL; - bool pcmd_node_open = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "Draw %4d %s vtx, tex 0x%p, clip_rect (%4.0f,%4.0f)-(%4.0f,%4.0f)", pcmd->ElemCount, draw_list->IdxBuffer.Size > 0 ? "indexed" : "non-indexed", pcmd->TextureId, pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w); - if (show_clip_rects && ImGui::IsItemHovered()) - { - ImRect clip_rect = pcmd->ClipRect; - ImRect vtxs_rect; - for (int i = elem_offset; i < elem_offset + (int)pcmd->ElemCount; i++) - vtxs_rect.Add(draw_list->VtxBuffer[idx_buffer ? idx_buffer[i] : i].pos); - clip_rect.Floor(); overlay_draw_list->AddRect(clip_rect.Min, clip_rect.Max, IM_COL32(255,255,0,255)); - vtxs_rect.Floor(); overlay_draw_list->AddRect(vtxs_rect.Min, vtxs_rect.Max, IM_COL32(255,0,255,255)); - } - if (!pcmd_node_open) - continue; + int elem_offset = 0; + for (const ImDrawCmd* pcmd = draw_list->CmdBuffer.begin(); pcmd < draw_list->CmdBuffer.end(); elem_offset += pcmd->ElemCount, pcmd++) + { + if (pcmd->UserCallback == NULL && pcmd->ElemCount == 0) + continue; + if (pcmd->UserCallback) + { + ImGui::BulletText("Callback %p, user_data %p", pcmd->UserCallback, pcmd->UserCallbackData); + continue; + } + ImDrawIdx* idx_buffer = (draw_list->IdxBuffer.Size > 0) ? draw_list->IdxBuffer.Data : NULL; + bool pcmd_node_open = ImGui::TreeNode((void*)(pcmd - draw_list->CmdBuffer.begin()), "Draw %4d %s vtx, tex 0x%p, clip_rect (%4.0f,%4.0f)-(%4.0f,%4.0f)", pcmd->ElemCount, draw_list->IdxBuffer.Size > 0 ? "indexed" : "non-indexed", pcmd->TextureId, pcmd->ClipRect.x, pcmd->ClipRect.y, pcmd->ClipRect.z, pcmd->ClipRect.w); + if (show_clip_rects && ImGui::IsItemHovered()) + { + ImRect clip_rect = pcmd->ClipRect; + ImRect vtxs_rect; + for (int i = elem_offset; i < elem_offset + (int)pcmd->ElemCount; i++) + vtxs_rect.Add(draw_list->VtxBuffer[idx_buffer ? idx_buffer[i] : i].pos); + clip_rect.Floor(); + overlay_draw_list->AddRect(clip_rect.Min, clip_rect.Max, IM_COL32(255, 255, 0, 255)); + vtxs_rect.Floor(); + overlay_draw_list->AddRect(vtxs_rect.Min, vtxs_rect.Max, IM_COL32(255, 0, 255, 255)); + } + if (!pcmd_node_open) + continue; - // Display individual triangles/vertices. Hover on to get the corresponding triangle highlighted. - ImGuiListClipper clipper(pcmd->ElemCount/3); // Manually coarse clip our print out of individual vertices to save CPU, only items that may be visible. - while (clipper.Step()) - for (int prim = clipper.DisplayStart, vtx_i = elem_offset + clipper.DisplayStart*3; prim < clipper.DisplayEnd; prim++) - { - char buf[300]; - char *buf_p = buf, *buf_end = buf + IM_ARRAYSIZE(buf); - ImVec2 triangles_pos[3]; - for (int n = 0; n < 3; n++, vtx_i++) - { - ImDrawVert& v = draw_list->VtxBuffer[idx_buffer ? idx_buffer[vtx_i] : vtx_i]; - triangles_pos[n] = v.pos; - buf_p += ImFormatString(buf_p, (int)(buf_end - buf_p), "%s %04d: pos (%8.2f,%8.2f), uv (%.6f,%.6f), col %08X\n", (n == 0) ? "vtx" : " ", vtx_i, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col); - } - ImGui::Selectable(buf, false); - if (ImGui::IsItemHovered()) - { - ImDrawListFlags backup_flags = overlay_draw_list->Flags; - overlay_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines at is more readable for very large and thin triangles. - overlay_draw_list->AddPolyline(triangles_pos, 3, IM_COL32(255,255,0,255), true, 1.0f); - overlay_draw_list->Flags = backup_flags; - } - } - ImGui::TreePop(); - } - ImGui::TreePop(); - } + // Display individual triangles/vertices. Hover on to get the corresponding triangle highlighted. + ImGuiListClipper clipper(pcmd->ElemCount / 3); // Manually coarse clip our print out of individual vertices to save CPU, only items that may be visible. + while (clipper.Step()) + for (int prim = clipper.DisplayStart, vtx_i = elem_offset + clipper.DisplayStart * 3; prim < clipper.DisplayEnd; prim++) + { + char buf[300]; + char *buf_p = buf, *buf_end = buf + IM_ARRAYSIZE(buf); + ImVec2 triangles_pos[3]; + for (int n = 0; n < 3; n++, vtx_i++) + { + ImDrawVert& v = draw_list->VtxBuffer[idx_buffer ? idx_buffer[vtx_i] : vtx_i]; + triangles_pos[n] = v.pos; + buf_p += ImFormatString(buf_p, (int)(buf_end - buf_p), "%s %04d: pos (%8.2f,%8.2f), uv (%.6f,%.6f), col %08X\n", (n == 0) ? "vtx" : " ", vtx_i, v.pos.x, v.pos.y, v.uv.x, v.uv.y, v.col); + } + ImGui::Selectable(buf, false); + if (ImGui::IsItemHovered()) + { + ImDrawListFlags backup_flags = overlay_draw_list->Flags; + overlay_draw_list->Flags &= ~ImDrawListFlags_AntiAliasedLines; // Disable AA on triangle outlines at is more readable for very large and thin triangles. + overlay_draw_list->AddPolyline(triangles_pos, 3, IM_COL32(255, 255, 0, 255), true, 1.0f); + overlay_draw_list->Flags = backup_flags; + } + } + ImGui::TreePop(); + } + ImGui::TreePop(); + } - static void NodeWindows(ImVector& windows, const char* label) - { - if (!ImGui::TreeNode(label, "%s (%d)", label, windows.Size)) - return; - for (int i = 0; i < windows.Size; i++) - Funcs::NodeWindow(windows[i], "Window"); - ImGui::TreePop(); - } + static void NodeWindows(ImVector& windows, const char* label) + { + if (!ImGui::TreeNode(label, "%s (%d)", label, windows.Size)) + return; + for (int i = 0; i < windows.Size; i++) + Funcs::NodeWindow(windows[i], "Window"); + ImGui::TreePop(); + } - static void NodeWindow(ImGuiWindow* window, const char* label) - { - if (!ImGui::TreeNode(window, "%s '%s', %d @ 0x%p", label, window->Name, window->Active || window->WasActive, window)) - return; - ImGuiWindowFlags flags = window->Flags; - NodeDrawList(window, window->DrawList, "DrawList"); - ImGui::BulletText("Pos: (%.1f,%.1f), Size: (%.1f,%.1f), SizeContents (%.1f,%.1f)", window->Pos.x, window->Pos.y, window->Size.x, window->Size.y, window->SizeContents.x, window->SizeContents.y); - ImGui::BulletText("Flags: 0x%08X (%s%s%s%s%s%s..)", flags, - (flags & ImGuiWindowFlags_ChildWindow) ? "Child " : "", (flags & ImGuiWindowFlags_Tooltip) ? "Tooltip " : "", (flags & ImGuiWindowFlags_Popup) ? "Popup " : "", - (flags & ImGuiWindowFlags_Modal) ? "Modal " : "", (flags & ImGuiWindowFlags_ChildMenu) ? "ChildMenu " : "", (flags & ImGuiWindowFlags_NoSavedSettings) ? "NoSavedSettings " : ""); - ImGui::BulletText("Scroll: (%.2f/%.2f,%.2f/%.2f)", window->Scroll.x, GetScrollMaxX(window), window->Scroll.y, GetScrollMaxY(window)); - ImGui::BulletText("Active: %d, WriteAccessed: %d", window->Active, window->WriteAccessed); - ImGui::BulletText("NavLastIds: 0x%08X,0x%08X, NavLayerActiveMask: %X", window->NavLastIds[0], window->NavLastIds[1], window->DC.NavLayerActiveMask); - ImGui::BulletText("NavLastChildNavWindow: %s", window->NavLastChildNavWindow ? window->NavLastChildNavWindow->Name : "NULL"); - if (window->NavRectRel[0].IsFinite()) - ImGui::BulletText("NavRectRel[0]: (%.1f,%.1f)(%.1f,%.1f)", window->NavRectRel[0].Min.x, window->NavRectRel[0].Min.y, window->NavRectRel[0].Max.x, window->NavRectRel[0].Max.y); - else - ImGui::BulletText("NavRectRel[0]: "); - if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow"); - if (window->DC.ChildWindows.Size > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows"); - ImGui::BulletText("Storage: %d bytes", window->StateStorage.Data.Size * (int)sizeof(ImGuiStorage::Pair)); - ImGui::TreePop(); - } - }; + static void NodeWindow(ImGuiWindow* window, const char* label) + { + if (!ImGui::TreeNode(window, "%s '%s', %d @ 0x%p", label, window->Name, window->Active || window->WasActive, window)) + return; + ImGuiWindowFlags flags = window->Flags; + NodeDrawList(window, window->DrawList, "DrawList"); + ImGui::BulletText("Pos: (%.1f,%.1f), Size: (%.1f,%.1f), SizeContents (%.1f,%.1f)", window->Pos.x, window->Pos.y, window->Size.x, window->Size.y, window->SizeContents.x, window->SizeContents.y); + ImGui::BulletText("Flags: 0x%08X (%s%s%s%s%s%s..)", flags, + (flags & ImGuiWindowFlags_ChildWindow) ? "Child " : "", (flags & ImGuiWindowFlags_Tooltip) ? "Tooltip " : "", (flags & ImGuiWindowFlags_Popup) ? "Popup " : "", + (flags & ImGuiWindowFlags_Modal) ? "Modal " : "", (flags & ImGuiWindowFlags_ChildMenu) ? "ChildMenu " : "", (flags & ImGuiWindowFlags_NoSavedSettings) ? "NoSavedSettings " : ""); + ImGui::BulletText("Scroll: (%.2f/%.2f,%.2f/%.2f)", window->Scroll.x, GetScrollMaxX(window), window->Scroll.y, GetScrollMaxY(window)); + ImGui::BulletText("Active: %d, WriteAccessed: %d", window->Active, window->WriteAccessed); + ImGui::BulletText("NavLastIds: 0x%08X,0x%08X, NavLayerActiveMask: %X", window->NavLastIds[0], window->NavLastIds[1], window->DC.NavLayerActiveMask); + ImGui::BulletText("NavLastChildNavWindow: %s", window->NavLastChildNavWindow ? window->NavLastChildNavWindow->Name : "NULL"); + if (window->NavRectRel[0].IsFinite()) + ImGui::BulletText("NavRectRel[0]: (%.1f,%.1f)(%.1f,%.1f)", window->NavRectRel[0].Min.x, window->NavRectRel[0].Min.y, window->NavRectRel[0].Max.x, window->NavRectRel[0].Max.y); + else + ImGui::BulletText("NavRectRel[0]: "); + if (window->RootWindow != window) NodeWindow(window->RootWindow, "RootWindow"); + if (window->DC.ChildWindows.Size > 0) NodeWindows(window->DC.ChildWindows, "ChildWindows"); + ImGui::BulletText("Storage: %d bytes", window->StateStorage.Data.Size * (int)sizeof(ImGuiStorage::Pair)); + ImGui::TreePop(); + } + }; - // Access private state, we are going to display the draw lists from last frame - ImGuiContext& g = *GImGui; - Funcs::NodeWindows(g.Windows, "Windows"); - if (ImGui::TreeNode("DrawList", "Active DrawLists (%d)", g.DrawDataBuilder.Layers[0].Size)) - { - for (int i = 0; i < g.DrawDataBuilder.Layers[0].Size; i++) - Funcs::NodeDrawList(NULL, g.DrawDataBuilder.Layers[0][i], "DrawList"); - ImGui::TreePop(); - } - if (ImGui::TreeNode("Popups", "Open Popups Stack (%d)", g.OpenPopupStack.Size)) - { - for (int i = 0; i < g.OpenPopupStack.Size; i++) - { - ImGuiWindow* window = g.OpenPopupStack[i].Window; - ImGui::BulletText("PopupID: %08x, Window: '%s'%s%s", g.OpenPopupStack[i].PopupId, window ? window->Name : "NULL", window && (window->Flags & ImGuiWindowFlags_ChildWindow) ? " ChildWindow" : "", window && (window->Flags & ImGuiWindowFlags_ChildMenu) ? " ChildMenu" : ""); - } - ImGui::TreePop(); - } - if (ImGui::TreeNode("Internal state")) - { - const char* input_source_names[] = { "None", "Mouse", "Nav", "NavGamepad", "NavKeyboard" }; IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_Count_); - ImGui::Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL"); - ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL"); - ImGui::Text("HoveredId: 0x%08X/0x%08X (%.2f sec)", g.HoveredId, g.HoveredIdPreviousFrame, g.HoveredIdTimer); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not - ImGui::Text("ActiveId: 0x%08X/0x%08X (%.2f sec), ActiveIdSource: %s", g.ActiveId, g.ActiveIdPreviousFrame, g.ActiveIdTimer, input_source_names[g.ActiveIdSource]); - ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL"); - ImGui::Text("NavWindow: '%s'", g.NavWindow ? g.NavWindow->Name : "NULL"); - ImGui::Text("NavId: 0x%08X, NavLayer: %d", g.NavId, g.NavLayer); - ImGui::Text("NavActive: %d, NavVisible: %d", g.IO.NavActive, g.IO.NavVisible); - ImGui::Text("NavActivateId: 0x%08X, NavInputId: 0x%08X", g.NavActivateId, g.NavInputId); - ImGui::Text("NavDisableHighlight: %d, NavDisableMouseHover: %d", g.NavDisableHighlight, g.NavDisableMouseHover); - ImGui::Text("DragDrop: %d, SourceId = 0x%08X, Payload \"%s\" (%d bytes)", g.DragDropActive, g.DragDropPayload.SourceId, g.DragDropPayload.DataType, g.DragDropPayload.DataSize); - ImGui::TreePop(); - } - } - ImGui::End(); + // Access private state, we are going to display the draw lists from last frame + ImGuiContext& g = *GImGui; + Funcs::NodeWindows(g.Windows, "Windows"); + if (ImGui::TreeNode("DrawList", "Active DrawLists (%d)", g.DrawDataBuilder.Layers[0].Size)) + { + for (int i = 0; i < g.DrawDataBuilder.Layers[0].Size; i++) + Funcs::NodeDrawList(NULL, g.DrawDataBuilder.Layers[0][i], "DrawList"); + ImGui::TreePop(); + } + if (ImGui::TreeNode("Popups", "Open Popups Stack (%d)", g.OpenPopupStack.Size)) + { + for (int i = 0; i < g.OpenPopupStack.Size; i++) + { + ImGuiWindow* window = g.OpenPopupStack[i].Window; + ImGui::BulletText("PopupID: %08x, Window: '%s'%s%s", g.OpenPopupStack[i].PopupId, window ? window->Name : "NULL", window && (window->Flags & ImGuiWindowFlags_ChildWindow) ? " ChildWindow" : "", window && (window->Flags & ImGuiWindowFlags_ChildMenu) ? " ChildMenu" : ""); + } + ImGui::TreePop(); + } + if (ImGui::TreeNode("Internal state")) + { + const char* input_source_names[] = {"None", "Mouse", "Nav", "NavGamepad", "NavKeyboard"}; + IM_ASSERT(IM_ARRAYSIZE(input_source_names) == ImGuiInputSource_Count_); + ImGui::Text("HoveredWindow: '%s'", g.HoveredWindow ? g.HoveredWindow->Name : "NULL"); + ImGui::Text("HoveredRootWindow: '%s'", g.HoveredRootWindow ? g.HoveredRootWindow->Name : "NULL"); + ImGui::Text("HoveredId: 0x%08X/0x%08X (%.2f sec)", g.HoveredId, g.HoveredIdPreviousFrame, g.HoveredIdTimer); // Data is "in-flight" so depending on when the Metrics window is called we may see current frame information or not + ImGui::Text("ActiveId: 0x%08X/0x%08X (%.2f sec), ActiveIdSource: %s", g.ActiveId, g.ActiveIdPreviousFrame, g.ActiveIdTimer, input_source_names[g.ActiveIdSource]); + ImGui::Text("ActiveIdWindow: '%s'", g.ActiveIdWindow ? g.ActiveIdWindow->Name : "NULL"); + ImGui::Text("NavWindow: '%s'", g.NavWindow ? g.NavWindow->Name : "NULL"); + ImGui::Text("NavId: 0x%08X, NavLayer: %d", g.NavId, g.NavLayer); + ImGui::Text("NavActive: %d, NavVisible: %d", g.IO.NavActive, g.IO.NavVisible); + ImGui::Text("NavActivateId: 0x%08X, NavInputId: 0x%08X", g.NavActivateId, g.NavInputId); + ImGui::Text("NavDisableHighlight: %d, NavDisableMouseHover: %d", g.NavDisableHighlight, g.NavDisableMouseHover); + ImGui::Text("DragDrop: %d, SourceId = 0x%08X, Payload \"%s\" (%d bytes)", g.DragDropActive, g.DragDropPayload.SourceId, g.DragDropPayload.DataType, g.DragDropPayload.DataSize); + ImGui::TreePop(); + } + } + ImGui::End(); } //----------------------------------------------------------------------------- diff --git a/examples/ThirdPartyLibs/imgui/imgui.h b/examples/ThirdPartyLibs/imgui/imgui.h index 2f874c6fc..94c923744 100644 --- a/examples/ThirdPartyLibs/imgui/imgui.h +++ b/examples/ThirdPartyLibs/imgui/imgui.h @@ -16,12 +16,12 @@ #include "imconfig.h" #endif -#include // FLT_MAX -#include // va_list -#include // ptrdiff_t, NULL -#include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp +#include // FLT_MAX +#include // va_list +#include // ptrdiff_t, NULL +#include // memset, memmove, memcpy, strlen, strchr, strcpy, strcmp -#define IMGUI_VERSION "1.60 WIP" +#define IMGUI_VERSION "1.60 WIP" // Define attributes of all API symbols declarations, e.g. for DLL under Windows. #ifndef IMGUI_API @@ -31,20 +31,20 @@ // Define assertion handler. #ifndef IM_ASSERT #include -#define IM_ASSERT(_EXPR) assert(_EXPR) +#define IM_ASSERT(_EXPR) assert(_EXPR) #endif // Helpers // Some compilers support applying printf-style warnings to user functions. #if defined(__clang__) || defined(__GNUC__) -#define IM_FMTARGS(FMT) __attribute__((format(printf, FMT, FMT+1))) -#define IM_FMTLIST(FMT) __attribute__((format(printf, FMT, 0))) +#define IM_FMTARGS(FMT) __attribute__((format(printf, FMT, FMT + 1))) +#define IM_FMTLIST(FMT) __attribute__((format(printf, FMT, 0))) #else #define IM_FMTARGS(FMT) #define IM_FMTLIST(FMT) #endif -#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR))) -#define IM_OFFSETOF(_TYPE,_MEMBER) ((size_t)&(((_TYPE*)0)->_MEMBER)) // Offset of _MEMBER within _TYPE. Standardized as offsetof() in modern C++. +#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR) / sizeof(*_ARR))) +#define IM_OFFSETOF(_TYPE, _MEMBER) ((size_t) & (((_TYPE*)0)->_MEMBER)) // Offset of _MEMBER within _TYPE. Standardized as offsetof() in modern C++. #if defined(__clang__) #pragma clang diagnostic push @@ -52,60 +52,60 @@ #endif // Forward declarations -struct ImDrawChannel; // Temporary storage for outputting drawing commands out of order, used by ImDrawList::ChannelsSplit() -struct ImDrawCmd; // A single draw command within a parent ImDrawList (generally maps to 1 GPU draw call) -struct ImDrawData; // All draw command lists required to render the frame -struct ImDrawList; // A single draw command list (generally one per window) -struct ImDrawListSharedData; // Data shared among multiple draw lists (typically owned by parent ImGui context, but you may create one yourself) -struct ImDrawVert; // A single vertex (20 bytes by default, override layout with IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT) -struct ImFont; // Runtime data for a single font within a parent ImFontAtlas -struct ImFontAtlas; // Runtime data for multiple fonts, bake multiple fonts into a single texture, TTF/OTF font loader -struct ImFontConfig; // Configuration data when adding a font or merging fonts -struct ImColor; // Helper functions to create a color that can be converted to either u32 or float4 -struct ImGuiIO; // Main configuration and I/O between your application and ImGui -struct ImGuiOnceUponAFrame; // Simple helper for running a block of code not more than once a frame, used by IMGUI_ONCE_UPON_A_FRAME macro -struct ImGuiStorage; // Simple custom key value storage -struct ImGuiStyle; // Runtime data for styling/colors -struct ImGuiTextFilter; // Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" -struct ImGuiTextBuffer; // Text buffer for logging/accumulating text -struct ImGuiTextEditCallbackData; // Shared state of ImGui::InputText() when using custom ImGuiTextEditCallback (rare/advanced use) -struct ImGuiSizeCallbackData; // Structure used to constraint window size in custom ways when using custom ImGuiSizeCallback (rare/advanced use) -struct ImGuiListClipper; // Helper to manually clip large list of items -struct ImGuiPayload; // User data payload for drag and drop operations -struct ImGuiContext; // ImGui context (opaque) +struct ImDrawChannel; // Temporary storage for outputting drawing commands out of order, used by ImDrawList::ChannelsSplit() +struct ImDrawCmd; // A single draw command within a parent ImDrawList (generally maps to 1 GPU draw call) +struct ImDrawData; // All draw command lists required to render the frame +struct ImDrawList; // A single draw command list (generally one per window) +struct ImDrawListSharedData; // Data shared among multiple draw lists (typically owned by parent ImGui context, but you may create one yourself) +struct ImDrawVert; // A single vertex (20 bytes by default, override layout with IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT) +struct ImFont; // Runtime data for a single font within a parent ImFontAtlas +struct ImFontAtlas; // Runtime data for multiple fonts, bake multiple fonts into a single texture, TTF/OTF font loader +struct ImFontConfig; // Configuration data when adding a font or merging fonts +struct ImColor; // Helper functions to create a color that can be converted to either u32 or float4 +struct ImGuiIO; // Main configuration and I/O between your application and ImGui +struct ImGuiOnceUponAFrame; // Simple helper for running a block of code not more than once a frame, used by IMGUI_ONCE_UPON_A_FRAME macro +struct ImGuiStorage; // Simple custom key value storage +struct ImGuiStyle; // Runtime data for styling/colors +struct ImGuiTextFilter; // Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" +struct ImGuiTextBuffer; // Text buffer for logging/accumulating text +struct ImGuiTextEditCallbackData; // Shared state of ImGui::InputText() when using custom ImGuiTextEditCallback (rare/advanced use) +struct ImGuiSizeCallbackData; // Structure used to constraint window size in custom ways when using custom ImGuiSizeCallback (rare/advanced use) +struct ImGuiListClipper; // Helper to manually clip large list of items +struct ImGuiPayload; // User data payload for drag and drop operations +struct ImGuiContext; // ImGui context (opaque) // Typedefs and Enumerations (declared as int for compatibility and to not pollute the top of this file) -typedef unsigned int ImU32; // 32-bit unsigned integer (typically used to store packed colors) -typedef unsigned int ImGuiID; // unique ID used by widgets (typically hashed from a stack of string) -typedef unsigned short ImWchar; // character for keyboard input/display -typedef void* ImTextureID; // user data to identify a texture (this is whatever to you want it to be! read the FAQ about ImTextureID in imgui.cpp) -typedef int ImGuiCol; // enum: a color identifier for styling // enum ImGuiCol_ -typedef int ImGuiCond; // enum: a condition for Set*() // enum ImGuiCond_ -typedef int ImGuiKey; // enum: a key identifier (ImGui-side enum) // enum ImGuiKey_ -typedef int ImGuiNavInput; // enum: an input identifier for navigation // enum ImGuiNavInput_ -typedef int ImGuiMouseCursor; // enum: a mouse cursor identifier // enum ImGuiMouseCursor_ -typedef int ImGuiStyleVar; // enum: a variable identifier for styling // enum ImGuiStyleVar_ -typedef int ImDrawCornerFlags; // flags: for ImDrawList::AddRect*() etc. // enum ImDrawCornerFlags_ -typedef int ImDrawListFlags; // flags: for ImDrawList // enum ImDrawListFlags_ -typedef int ImFontAtlasFlags; // flags: for ImFontAtlas // enum ImFontAtlasFlags_ -typedef int ImGuiColorEditFlags; // flags: for ColorEdit*(), ColorPicker*() // enum ImGuiColorEditFlags_ -typedef int ImGuiColumnsFlags; // flags: for *Columns*() // enum ImGuiColumnsFlags_ -typedef int ImGuiDragDropFlags; // flags: for *DragDrop*() // enum ImGuiDragDropFlags_ -typedef int ImGuiComboFlags; // flags: for BeginCombo() // enum ImGuiComboFlags_ -typedef int ImGuiFocusedFlags; // flags: for IsWindowFocused() // enum ImGuiFocusedFlags_ -typedef int ImGuiHoveredFlags; // flags: for IsItemHovered() etc. // enum ImGuiHoveredFlags_ -typedef int ImGuiInputTextFlags; // flags: for InputText*() // enum ImGuiInputTextFlags_ -typedef int ImGuiNavFlags; // flags: for io.NavFlags // enum ImGuiNavFlags_ -typedef int ImGuiSelectableFlags; // flags: for Selectable() // enum ImGuiSelectableFlags_ -typedef int ImGuiTreeNodeFlags; // flags: for TreeNode*(),CollapsingHeader()// enum ImGuiTreeNodeFlags_ -typedef int ImGuiWindowFlags; // flags: for Begin*() // enum ImGuiWindowFlags_ -typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData *data); +typedef unsigned int ImU32; // 32-bit unsigned integer (typically used to store packed colors) +typedef unsigned int ImGuiID; // unique ID used by widgets (typically hashed from a stack of string) +typedef unsigned short ImWchar; // character for keyboard input/display +typedef void* ImTextureID; // user data to identify a texture (this is whatever to you want it to be! read the FAQ about ImTextureID in imgui.cpp) +typedef int ImGuiCol; // enum: a color identifier for styling // enum ImGuiCol_ +typedef int ImGuiCond; // enum: a condition for Set*() // enum ImGuiCond_ +typedef int ImGuiKey; // enum: a key identifier (ImGui-side enum) // enum ImGuiKey_ +typedef int ImGuiNavInput; // enum: an input identifier for navigation // enum ImGuiNavInput_ +typedef int ImGuiMouseCursor; // enum: a mouse cursor identifier // enum ImGuiMouseCursor_ +typedef int ImGuiStyleVar; // enum: a variable identifier for styling // enum ImGuiStyleVar_ +typedef int ImDrawCornerFlags; // flags: for ImDrawList::AddRect*() etc. // enum ImDrawCornerFlags_ +typedef int ImDrawListFlags; // flags: for ImDrawList // enum ImDrawListFlags_ +typedef int ImFontAtlasFlags; // flags: for ImFontAtlas // enum ImFontAtlasFlags_ +typedef int ImGuiColorEditFlags; // flags: for ColorEdit*(), ColorPicker*() // enum ImGuiColorEditFlags_ +typedef int ImGuiColumnsFlags; // flags: for *Columns*() // enum ImGuiColumnsFlags_ +typedef int ImGuiDragDropFlags; // flags: for *DragDrop*() // enum ImGuiDragDropFlags_ +typedef int ImGuiComboFlags; // flags: for BeginCombo() // enum ImGuiComboFlags_ +typedef int ImGuiFocusedFlags; // flags: for IsWindowFocused() // enum ImGuiFocusedFlags_ +typedef int ImGuiHoveredFlags; // flags: for IsItemHovered() etc. // enum ImGuiHoveredFlags_ +typedef int ImGuiInputTextFlags; // flags: for InputText*() // enum ImGuiInputTextFlags_ +typedef int ImGuiNavFlags; // flags: for io.NavFlags // enum ImGuiNavFlags_ +typedef int ImGuiSelectableFlags; // flags: for Selectable() // enum ImGuiSelectableFlags_ +typedef int ImGuiTreeNodeFlags; // flags: for TreeNode*(),CollapsingHeader()// enum ImGuiTreeNodeFlags_ +typedef int ImGuiWindowFlags; // flags: for Begin*() // enum ImGuiWindowFlags_ +typedef int (*ImGuiTextEditCallback)(ImGuiTextEditCallbackData* data); typedef void (*ImGuiSizeCallback)(ImGuiSizeCallbackData* data); #if defined(_MSC_VER) && !defined(__clang__) -typedef unsigned __int64 ImU64; // 64-bit unsigned integer +typedef unsigned __int64 ImU64; // 64-bit unsigned integer #else -typedef unsigned long long ImU64; // 64-bit unsigned integer -#endif +typedef unsigned long long ImU64; // 64-bit unsigned integer +#endif // Others helpers at bottom of the file: // class ImVector<> // Lightweight std::vector like class. @@ -113,22 +113,36 @@ typedef unsigned long long ImU64; // 64-bit unsigned integer struct ImVec2 { - float x, y; - ImVec2() { x = y = 0.0f; } - ImVec2(float _x, float _y) { x = _x; y = _y; } - float operator[] (size_t idx) const { IM_ASSERT(idx == 0 || idx == 1); return (&x)[idx]; } // We very rarely use this [] operator, thus an assert is fine. -#ifdef IM_VEC2_CLASS_EXTRA // Define constructor and implicit cast operators in imconfig.h to convert back<>forth from your math types and ImVec2. - IM_VEC2_CLASS_EXTRA + float x, y; + ImVec2() { x = y = 0.0f; } + ImVec2(float _x, float _y) + { + x = _x; + y = _y; + } + float operator[](size_t idx) const + { + IM_ASSERT(idx == 0 || idx == 1); + return (&x)[idx]; + } // We very rarely use this [] operator, thus an assert is fine. +#ifdef IM_VEC2_CLASS_EXTRA // Define constructor and implicit cast operators in imconfig.h to convert back<>forth from your math types and ImVec2. + IM_VEC2_CLASS_EXTRA #endif }; struct ImVec4 { - float x, y, z, w; - ImVec4() { x = y = z = w = 0.0f; } - ImVec4(float _x, float _y, float _z, float _w) { x = _x; y = _y; z = _z; w = _w; } -#ifdef IM_VEC4_CLASS_EXTRA // Define constructor and implicit cast operators in imconfig.h to convert back<>forth from your math types and ImVec4. - IM_VEC4_CLASS_EXTRA + float x, y, z, w; + ImVec4() { x = y = z = w = 0.0f; } + ImVec4(float _x, float _y, float _z, float _w) + { + x = _x; + y = _y; + z = _z; + w = _w; + } +#ifdef IM_VEC4_CLASS_EXTRA // Define constructor and implicit cast operators in imconfig.h to convert back<>forth from your math types and ImVec4. + IM_VEC4_CLASS_EXTRA #endif }; @@ -136,577 +150,578 @@ struct ImVec4 // In a namespace so that user can add extra functions in a separate file (e.g. Value() helpers for your vector or common types) namespace ImGui { - // Context creation and access, if you want to use multiple context, share context between modules (e.g. DLL). - // All contexts share a same ImFontAtlas by default. If you want different font atlas, you can new() them and overwrite the GetIO().Fonts variable of an ImGui context. - // All those functions are not reliant on the current context. - IMGUI_API ImGuiContext* CreateContext(ImFontAtlas* shared_font_atlas = NULL); - IMGUI_API void DestroyContext(ImGuiContext* ctx = NULL); // NULL = Destroy current context - IMGUI_API ImGuiContext* GetCurrentContext(); - IMGUI_API void SetCurrentContext(ImGuiContext* ctx); +// Context creation and access, if you want to use multiple context, share context between modules (e.g. DLL). +// All contexts share a same ImFontAtlas by default. If you want different font atlas, you can new() them and overwrite the GetIO().Fonts variable of an ImGui context. +// All those functions are not reliant on the current context. +IMGUI_API ImGuiContext* CreateContext(ImFontAtlas* shared_font_atlas = NULL); +IMGUI_API void DestroyContext(ImGuiContext* ctx = NULL); // NULL = Destroy current context +IMGUI_API ImGuiContext* GetCurrentContext(); +IMGUI_API void SetCurrentContext(ImGuiContext* ctx); - // Main - IMGUI_API ImGuiIO& GetIO(); - IMGUI_API ImGuiStyle& GetStyle(); - IMGUI_API void NewFrame(); // start a new ImGui frame, you can submit any command from this point until Render()/EndFrame(). - IMGUI_API void Render(); // ends the ImGui frame, finalize the draw data. (Obsolete: optionally call io.RenderDrawListsFn if set. Nowadays, prefer calling your render function yourself.) - IMGUI_API ImDrawData* GetDrawData(); // valid after Render() and until the next call to NewFrame(). this is what you have to render. (Obsolete: this used to be passed to your io.RenderDrawListsFn() function.) - IMGUI_API void EndFrame(); // ends the ImGui frame. automatically called by Render(), so most likely don't need to ever call that yourself directly. If you don't need to render you may call EndFrame() but you'll have wasted CPU already. If you don't need to render, better to not create any imgui windows instead! +// Main +IMGUI_API ImGuiIO& GetIO(); +IMGUI_API ImGuiStyle& GetStyle(); +IMGUI_API void NewFrame(); // start a new ImGui frame, you can submit any command from this point until Render()/EndFrame(). +IMGUI_API void Render(); // ends the ImGui frame, finalize the draw data. (Obsolete: optionally call io.RenderDrawListsFn if set. Nowadays, prefer calling your render function yourself.) +IMGUI_API ImDrawData* GetDrawData(); // valid after Render() and until the next call to NewFrame(). this is what you have to render. (Obsolete: this used to be passed to your io.RenderDrawListsFn() function.) +IMGUI_API void EndFrame(); // ends the ImGui frame. automatically called by Render(), so most likely don't need to ever call that yourself directly. If you don't need to render you may call EndFrame() but you'll have wasted CPU already. If you don't need to render, better to not create any imgui windows instead! - // Demo, Debug, Informations - IMGUI_API void ShowDemoWindow(bool* p_open = NULL); // create demo/test window (previously called ShowTestWindow). demonstrate most ImGui features. call this to learn about the library! try to make it always available in your application! - IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // create metrics window. display ImGui internals: draw commands (with individual draw calls and vertices), window list, basic internal state, etc. - IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // add style editor block (not a window). you can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it uses the default style) - IMGUI_API bool ShowStyleSelector(const char* label); - IMGUI_API void ShowFontSelector(const char* label); - IMGUI_API void ShowUserGuide(); // add basic help/info block (not a window): how to manipulate ImGui as a end-user (mouse/keyboard controls). - IMGUI_API const char* GetVersion(); +// Demo, Debug, Informations +IMGUI_API void ShowDemoWindow(bool* p_open = NULL); // create demo/test window (previously called ShowTestWindow). demonstrate most ImGui features. call this to learn about the library! try to make it always available in your application! +IMGUI_API void ShowMetricsWindow(bool* p_open = NULL); // create metrics window. display ImGui internals: draw commands (with individual draw calls and vertices), window list, basic internal state, etc. +IMGUI_API void ShowStyleEditor(ImGuiStyle* ref = NULL); // add style editor block (not a window). you can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it uses the default style) +IMGUI_API bool ShowStyleSelector(const char* label); +IMGUI_API void ShowFontSelector(const char* label); +IMGUI_API void ShowUserGuide(); // add basic help/info block (not a window): how to manipulate ImGui as a end-user (mouse/keyboard controls). +IMGUI_API const char* GetVersion(); - // Styles - IMGUI_API void StyleColorsDark(ImGuiStyle* dst = NULL); // New, recommended style - IMGUI_API void StyleColorsClassic(ImGuiStyle* dst = NULL); // Classic imgui style (default) - IMGUI_API void StyleColorsLight(ImGuiStyle* dst = NULL); // Best used with borders and a custom, thicker font +// Styles +IMGUI_API void StyleColorsDark(ImGuiStyle* dst = NULL); // New, recommended style +IMGUI_API void StyleColorsClassic(ImGuiStyle* dst = NULL); // Classic imgui style (default) +IMGUI_API void StyleColorsLight(ImGuiStyle* dst = NULL); // Best used with borders and a custom, thicker font - // Window - IMGUI_API bool Begin(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // push window to the stack and start appending to it. see .cpp for details. return false when window is collapsed (so you can early out in your code) but you always need to call End() regardless. 'bool* p_open' creates a widget on the upper-right to close the window (which sets your bool to false). - IMGUI_API void End(); // always call even if Begin() return false (which indicates a collapsed window)! finish appending to current window, pop it off the window stack. - IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags flags = 0); // begin a scrolling region. size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). size>0.0f: fixed size. each axis can use a different mode, e.g. ImVec2(0,400). - IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0,0), bool border = false, ImGuiWindowFlags flags = 0); // " - IMGUI_API void EndChild(); // always call even if BeginChild() return false (which indicates a collapsed or clipping child window) - IMGUI_API ImVec2 GetContentRegionMax(); // current content boundaries (typically window boundaries including scrolling, or current column boundaries), in windows coordinates - IMGUI_API ImVec2 GetContentRegionAvail(); // == GetContentRegionMax() - GetCursorPos() - IMGUI_API float GetContentRegionAvailWidth(); // - IMGUI_API ImVec2 GetWindowContentRegionMin(); // content boundaries min (roughly (0,0)-Scroll), in window coordinates - IMGUI_API ImVec2 GetWindowContentRegionMax(); // content boundaries max (roughly (0,0)+Size-Scroll) where Size can be override with SetNextWindowContentSize(), in window coordinates - IMGUI_API float GetWindowContentRegionWidth(); // - IMGUI_API ImDrawList* GetWindowDrawList(); // get rendering command-list if you want to append your own draw primitives - IMGUI_API ImVec2 GetWindowPos(); // get current window position in screen space (useful if you want to do your own drawing via the DrawList api) - IMGUI_API ImVec2 GetWindowSize(); // get current window size - IMGUI_API float GetWindowWidth(); - IMGUI_API float GetWindowHeight(); - IMGUI_API bool IsWindowCollapsed(); - IMGUI_API bool IsWindowAppearing(); - IMGUI_API void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontGlobalScale if you want to scale all windows +// Window +IMGUI_API bool Begin(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // push window to the stack and start appending to it. see .cpp for details. return false when window is collapsed (so you can early out in your code) but you always need to call End() regardless. 'bool* p_open' creates a widget on the upper-right to close the window (which sets your bool to false). +IMGUI_API void End(); // always call even if Begin() return false (which indicates a collapsed window)! finish appending to current window, pop it off the window stack. +IMGUI_API bool BeginChild(const char* str_id, const ImVec2& size = ImVec2(0, 0), bool border = false, ImGuiWindowFlags flags = 0); // begin a scrolling region. size==0.0f: use remaining window size, size<0.0f: use remaining window size minus abs(size). size>0.0f: fixed size. each axis can use a different mode, e.g. ImVec2(0,400). +IMGUI_API bool BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0, 0), bool border = false, ImGuiWindowFlags flags = 0); // " +IMGUI_API void EndChild(); // always call even if BeginChild() return false (which indicates a collapsed or clipping child window) +IMGUI_API ImVec2 GetContentRegionMax(); // current content boundaries (typically window boundaries including scrolling, or current column boundaries), in windows coordinates +IMGUI_API ImVec2 GetContentRegionAvail(); // == GetContentRegionMax() - GetCursorPos() +IMGUI_API float GetContentRegionAvailWidth(); // +IMGUI_API ImVec2 GetWindowContentRegionMin(); // content boundaries min (roughly (0,0)-Scroll), in window coordinates +IMGUI_API ImVec2 GetWindowContentRegionMax(); // content boundaries max (roughly (0,0)+Size-Scroll) where Size can be override with SetNextWindowContentSize(), in window coordinates +IMGUI_API float GetWindowContentRegionWidth(); // +IMGUI_API ImDrawList* GetWindowDrawList(); // get rendering command-list if you want to append your own draw primitives +IMGUI_API ImVec2 GetWindowPos(); // get current window position in screen space (useful if you want to do your own drawing via the DrawList api) +IMGUI_API ImVec2 GetWindowSize(); // get current window size +IMGUI_API float GetWindowWidth(); +IMGUI_API float GetWindowHeight(); +IMGUI_API bool IsWindowCollapsed(); +IMGUI_API bool IsWindowAppearing(); +IMGUI_API void SetWindowFontScale(float scale); // per-window font scale. Adjust IO.FontGlobalScale if you want to scale all windows - IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0, const ImVec2& pivot = ImVec2(0,0)); // set next window position. call before Begin(). use pivot=(0.5f,0.5f) to center on given point, etc. - IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin() - IMGUI_API void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback = NULL, void* custom_callback_data = NULL); // set next window size limits. use -1,-1 on either X/Y axis to preserve the current size. Use callback to apply non-trivial programmatic constraints. - IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (~ enforce the range of scrollbars). not including window decorations (title bar, menu bar, etc.). set an axis to 0.0f to leave it automatic. call before Begin() - IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // set next window collapsed state. call before Begin() - IMGUI_API void SetNextWindowFocus(); // set next window to be focused / front-most. call before Begin() - IMGUI_API void SetNextWindowBgAlpha(float alpha); // set next window background color alpha. helper to easily modify ImGuiCol_WindowBg/ChildBg/PopupBg. - IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiCond cond = 0); // (not recommended) set current window position - call within Begin()/End(). prefer using SetNextWindowPos(), as this may incur tearing and side-effects. - IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiCond cond = 0); // (not recommended) set current window size - call within Begin()/End(). set to ImVec2(0,0) to force an auto-fit. prefer using SetNextWindowSize(), as this may incur tearing and minor side-effects. - IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // (not recommended) set current window collapsed state. prefer using SetNextWindowCollapsed(). - IMGUI_API void SetWindowFocus(); // (not recommended) set current window to be focused / front-most. prefer using SetNextWindowFocus(). - IMGUI_API void SetWindowPos(const char* name, const ImVec2& pos, ImGuiCond cond = 0); // set named window position. - IMGUI_API void SetWindowSize(const char* name, const ImVec2& size, ImGuiCond cond = 0); // set named window size. set axis to 0.0f to force an auto-fit on this axis. - IMGUI_API void SetWindowCollapsed(const char* name, bool collapsed, ImGuiCond cond = 0); // set named window collapsed state - IMGUI_API void SetWindowFocus(const char* name); // set named window to be focused / front-most. use NULL to remove focus. +IMGUI_API void SetNextWindowPos(const ImVec2& pos, ImGuiCond cond = 0, const ImVec2& pivot = ImVec2(0, 0)); // set next window position. call before Begin(). use pivot=(0.5f,0.5f) to center on given point, etc. +IMGUI_API void SetNextWindowSize(const ImVec2& size, ImGuiCond cond = 0); // set next window size. set axis to 0.0f to force an auto-fit on this axis. call before Begin() +IMGUI_API void SetNextWindowSizeConstraints(const ImVec2& size_min, const ImVec2& size_max, ImGuiSizeCallback custom_callback = NULL, void* custom_callback_data = NULL); // set next window size limits. use -1,-1 on either X/Y axis to preserve the current size. Use callback to apply non-trivial programmatic constraints. +IMGUI_API void SetNextWindowContentSize(const ImVec2& size); // set next window content size (~ enforce the range of scrollbars). not including window decorations (title bar, menu bar, etc.). set an axis to 0.0f to leave it automatic. call before Begin() +IMGUI_API void SetNextWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // set next window collapsed state. call before Begin() +IMGUI_API void SetNextWindowFocus(); // set next window to be focused / front-most. call before Begin() +IMGUI_API void SetNextWindowBgAlpha(float alpha); // set next window background color alpha. helper to easily modify ImGuiCol_WindowBg/ChildBg/PopupBg. +IMGUI_API void SetWindowPos(const ImVec2& pos, ImGuiCond cond = 0); // (not recommended) set current window position - call within Begin()/End(). prefer using SetNextWindowPos(), as this may incur tearing and side-effects. +IMGUI_API void SetWindowSize(const ImVec2& size, ImGuiCond cond = 0); // (not recommended) set current window size - call within Begin()/End(). set to ImVec2(0,0) to force an auto-fit. prefer using SetNextWindowSize(), as this may incur tearing and minor side-effects. +IMGUI_API void SetWindowCollapsed(bool collapsed, ImGuiCond cond = 0); // (not recommended) set current window collapsed state. prefer using SetNextWindowCollapsed(). +IMGUI_API void SetWindowFocus(); // (not recommended) set current window to be focused / front-most. prefer using SetNextWindowFocus(). +IMGUI_API void SetWindowPos(const char* name, const ImVec2& pos, ImGuiCond cond = 0); // set named window position. +IMGUI_API void SetWindowSize(const char* name, const ImVec2& size, ImGuiCond cond = 0); // set named window size. set axis to 0.0f to force an auto-fit on this axis. +IMGUI_API void SetWindowCollapsed(const char* name, bool collapsed, ImGuiCond cond = 0); // set named window collapsed state +IMGUI_API void SetWindowFocus(const char* name); // set named window to be focused / front-most. use NULL to remove focus. - IMGUI_API float GetScrollX(); // get scrolling amount [0..GetScrollMaxX()] - IMGUI_API float GetScrollY(); // get scrolling amount [0..GetScrollMaxY()] - IMGUI_API float GetScrollMaxX(); // get maximum scrolling amount ~~ ContentSize.X - WindowSize.X - IMGUI_API float GetScrollMaxY(); // get maximum scrolling amount ~~ ContentSize.Y - WindowSize.Y - IMGUI_API void SetScrollX(float scroll_x); // set scrolling amount [0..GetScrollMaxX()] - IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0..GetScrollMaxY()] - IMGUI_API void SetScrollHere(float center_y_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_y_ratio=0.0: top, 0.5: center, 1.0: bottom. When using to make a "default/current item" visible, consider using SetItemDefaultFocus() instead. - IMGUI_API void SetScrollFromPosY(float pos_y, float center_y_ratio = 0.5f); // adjust scrolling amount to make given position valid. use GetCursorPos() or GetCursorStartPos()+offset to get valid positions. - IMGUI_API void SetStateStorage(ImGuiStorage* tree); // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it) - IMGUI_API ImGuiStorage* GetStateStorage(); +IMGUI_API float GetScrollX(); // get scrolling amount [0..GetScrollMaxX()] +IMGUI_API float GetScrollY(); // get scrolling amount [0..GetScrollMaxY()] +IMGUI_API float GetScrollMaxX(); // get maximum scrolling amount ~~ ContentSize.X - WindowSize.X +IMGUI_API float GetScrollMaxY(); // get maximum scrolling amount ~~ ContentSize.Y - WindowSize.Y +IMGUI_API void SetScrollX(float scroll_x); // set scrolling amount [0..GetScrollMaxX()] +IMGUI_API void SetScrollY(float scroll_y); // set scrolling amount [0..GetScrollMaxY()] +IMGUI_API void SetScrollHere(float center_y_ratio = 0.5f); // adjust scrolling amount to make current cursor position visible. center_y_ratio=0.0: top, 0.5: center, 1.0: bottom. When using to make a "default/current item" visible, consider using SetItemDefaultFocus() instead. +IMGUI_API void SetScrollFromPosY(float pos_y, float center_y_ratio = 0.5f); // adjust scrolling amount to make given position valid. use GetCursorPos() or GetCursorStartPos()+offset to get valid positions. +IMGUI_API void SetStateStorage(ImGuiStorage* tree); // replace tree state storage with our own (if you want to manipulate it yourself, typically clear subsection of it) +IMGUI_API ImGuiStorage* GetStateStorage(); - // Parameters stacks (shared) - IMGUI_API void PushFont(ImFont* font); // use NULL as a shortcut to push default font - IMGUI_API void PopFont(); - IMGUI_API void PushStyleColor(ImGuiCol idx, ImU32 col); - IMGUI_API void PushStyleColor(ImGuiCol idx, const ImVec4& col); - IMGUI_API void PopStyleColor(int count = 1); - IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val); - IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val); - IMGUI_API void PopStyleVar(int count = 1); - IMGUI_API const ImVec4& GetStyleColorVec4(ImGuiCol idx); // retrieve style color as stored in ImGuiStyle structure. use to feed back into PushStyleColor(), otherwhise use GetColorU32() to get style color + style alpha. - IMGUI_API ImFont* GetFont(); // get current font - IMGUI_API float GetFontSize(); // get current font size (= height in pixels) of current font with current scale applied - IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a while pixel, useful to draw custom shapes via the ImDrawList API - IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul = 1.0f); // retrieve given style color with style alpha applied and optional extra alpha multiplier - IMGUI_API ImU32 GetColorU32(const ImVec4& col); // retrieve given color with style alpha applied - IMGUI_API ImU32 GetColorU32(ImU32 col); // retrieve given color with style alpha applied +// Parameters stacks (shared) +IMGUI_API void PushFont(ImFont* font); // use NULL as a shortcut to push default font +IMGUI_API void PopFont(); +IMGUI_API void PushStyleColor(ImGuiCol idx, ImU32 col); +IMGUI_API void PushStyleColor(ImGuiCol idx, const ImVec4& col); +IMGUI_API void PopStyleColor(int count = 1); +IMGUI_API void PushStyleVar(ImGuiStyleVar idx, float val); +IMGUI_API void PushStyleVar(ImGuiStyleVar idx, const ImVec2& val); +IMGUI_API void PopStyleVar(int count = 1); +IMGUI_API const ImVec4& GetStyleColorVec4(ImGuiCol idx); // retrieve style color as stored in ImGuiStyle structure. use to feed back into PushStyleColor(), otherwhise use GetColorU32() to get style color + style alpha. +IMGUI_API ImFont* GetFont(); // get current font +IMGUI_API float GetFontSize(); // get current font size (= height in pixels) of current font with current scale applied +IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a while pixel, useful to draw custom shapes via the ImDrawList API +IMGUI_API ImU32 GetColorU32(ImGuiCol idx, float alpha_mul = 1.0f); // retrieve given style color with style alpha applied and optional extra alpha multiplier +IMGUI_API ImU32 GetColorU32(const ImVec4& col); // retrieve given color with style alpha applied +IMGUI_API ImU32 GetColorU32(ImU32 col); // retrieve given color with style alpha applied - // Parameters stacks (current window) - IMGUI_API void PushItemWidth(float item_width); // width of items for the common item+label case, pixels. 0.0f = default to ~2/3 of windows width, >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -1.0f always align width to the right side) - IMGUI_API void PopItemWidth(); - IMGUI_API float CalcItemWidth(); // width of item given pushed settings and current cursor position - IMGUI_API void PushTextWrapPos(float wrap_pos_x = 0.0f); // word-wrapping for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space - IMGUI_API void PopTextWrapPos(); - IMGUI_API void PushAllowKeyboardFocus(bool allow_keyboard_focus); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets - IMGUI_API void PopAllowKeyboardFocus(); - IMGUI_API void PushButtonRepeat(bool repeat); // in 'repeat' mode, Button*() functions return repeated true in a typematic manner (using io.KeyRepeatDelay/io.KeyRepeatRate setting). Note that you can call IsItemActive() after any Button() to tell if the button is held in the current frame. - IMGUI_API void PopButtonRepeat(); +// Parameters stacks (current window) +IMGUI_API void PushItemWidth(float item_width); // width of items for the common item+label case, pixels. 0.0f = default to ~2/3 of windows width, >0.0f: width in pixels, <0.0f align xx pixels to the right of window (so -1.0f always align width to the right side) +IMGUI_API void PopItemWidth(); +IMGUI_API float CalcItemWidth(); // width of item given pushed settings and current cursor position +IMGUI_API void PushTextWrapPos(float wrap_pos_x = 0.0f); // word-wrapping for Text*() commands. < 0.0f: no wrapping; 0.0f: wrap to end of window (or column); > 0.0f: wrap at 'wrap_pos_x' position in window local space +IMGUI_API void PopTextWrapPos(); +IMGUI_API void PushAllowKeyboardFocus(bool allow_keyboard_focus); // allow focusing using TAB/Shift-TAB, enabled by default but you can disable it for certain widgets +IMGUI_API void PopAllowKeyboardFocus(); +IMGUI_API void PushButtonRepeat(bool repeat); // in 'repeat' mode, Button*() functions return repeated true in a typematic manner (using io.KeyRepeatDelay/io.KeyRepeatRate setting). Note that you can call IsItemActive() after any Button() to tell if the button is held in the current frame. +IMGUI_API void PopButtonRepeat(); - // Cursor / Layout - IMGUI_API void Separator(); // separator, generally horizontal. inside a menu bar or in horizontal layout mode, this becomes a vertical separator. - IMGUI_API void SameLine(float pos_x = 0.0f, float spacing_w = -1.0f); // call between widgets or groups to layout them horizontally - IMGUI_API void NewLine(); // undo a SameLine() - IMGUI_API void Spacing(); // add vertical spacing - IMGUI_API void Dummy(const ImVec2& size); // add a dummy item of given size - IMGUI_API void Indent(float indent_w = 0.0f); // move content position toward the right, by style.IndentSpacing or indent_w if != 0 - IMGUI_API void Unindent(float indent_w = 0.0f); // move content position back to the left, by style.IndentSpacing or indent_w if != 0 - IMGUI_API void BeginGroup(); // lock horizontal starting position + capture group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.) - IMGUI_API void EndGroup(); - IMGUI_API ImVec2 GetCursorPos(); // cursor position is relative to window position - IMGUI_API float GetCursorPosX(); // " - IMGUI_API float GetCursorPosY(); // " - IMGUI_API void SetCursorPos(const ImVec2& local_pos); // " - IMGUI_API void SetCursorPosX(float x); // " - IMGUI_API void SetCursorPosY(float y); // " - IMGUI_API ImVec2 GetCursorStartPos(); // initial cursor position - IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position in absolute screen coordinates [0..io.DisplaySize] (useful to work with ImDrawList API) - IMGUI_API void SetCursorScreenPos(const ImVec2& pos); // cursor position in absolute screen coordinates [0..io.DisplaySize] - IMGUI_API void AlignTextToFramePadding(); // vertically align/lower upcoming text to FramePadding.y so that it will aligns to upcoming widgets (call if you have text on a line before regular widgets) - IMGUI_API float GetTextLineHeight(); // ~ FontSize - IMGUI_API float GetTextLineHeightWithSpacing(); // ~ FontSize + style.ItemSpacing.y (distance in pixels between 2 consecutive lines of text) - IMGUI_API float GetFrameHeight(); // ~ FontSize + style.FramePadding.y * 2 - IMGUI_API float GetFrameHeightWithSpacing(); // ~ FontSize + style.FramePadding.y * 2 + style.ItemSpacing.y (distance in pixels between 2 consecutive lines of framed widgets) +// Cursor / Layout +IMGUI_API void Separator(); // separator, generally horizontal. inside a menu bar or in horizontal layout mode, this becomes a vertical separator. +IMGUI_API void SameLine(float pos_x = 0.0f, float spacing_w = -1.0f); // call between widgets or groups to layout them horizontally +IMGUI_API void NewLine(); // undo a SameLine() +IMGUI_API void Spacing(); // add vertical spacing +IMGUI_API void Dummy(const ImVec2& size); // add a dummy item of given size +IMGUI_API void Indent(float indent_w = 0.0f); // move content position toward the right, by style.IndentSpacing or indent_w if != 0 +IMGUI_API void Unindent(float indent_w = 0.0f); // move content position back to the left, by style.IndentSpacing or indent_w if != 0 +IMGUI_API void BeginGroup(); // lock horizontal starting position + capture group bounding box into one "item" (so you can use IsItemHovered() or layout primitives such as SameLine() on whole group, etc.) +IMGUI_API void EndGroup(); +IMGUI_API ImVec2 GetCursorPos(); // cursor position is relative to window position +IMGUI_API float GetCursorPosX(); // " +IMGUI_API float GetCursorPosY(); // " +IMGUI_API void SetCursorPos(const ImVec2& local_pos); // " +IMGUI_API void SetCursorPosX(float x); // " +IMGUI_API void SetCursorPosY(float y); // " +IMGUI_API ImVec2 GetCursorStartPos(); // initial cursor position +IMGUI_API ImVec2 GetCursorScreenPos(); // cursor position in absolute screen coordinates [0..io.DisplaySize] (useful to work with ImDrawList API) +IMGUI_API void SetCursorScreenPos(const ImVec2& pos); // cursor position in absolute screen coordinates [0..io.DisplaySize] +IMGUI_API void AlignTextToFramePadding(); // vertically align/lower upcoming text to FramePadding.y so that it will aligns to upcoming widgets (call if you have text on a line before regular widgets) +IMGUI_API float GetTextLineHeight(); // ~ FontSize +IMGUI_API float GetTextLineHeightWithSpacing(); // ~ FontSize + style.ItemSpacing.y (distance in pixels between 2 consecutive lines of text) +IMGUI_API float GetFrameHeight(); // ~ FontSize + style.FramePadding.y * 2 +IMGUI_API float GetFrameHeightWithSpacing(); // ~ FontSize + style.FramePadding.y * 2 + style.ItemSpacing.y (distance in pixels between 2 consecutive lines of framed widgets) - // Columns - // You can also use SameLine(pos_x) for simplified columns. The columns API is still work-in-progress and rather lacking. - IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true); - IMGUI_API void NextColumn(); // next column, defaults to current row or next row if the current row is finished - IMGUI_API int GetColumnIndex(); // get current column index - IMGUI_API float GetColumnWidth(int column_index = -1); // get column width (in pixels). pass -1 to use current column - IMGUI_API void SetColumnWidth(int column_index, float width); // set column width (in pixels). pass -1 to use current column - IMGUI_API float GetColumnOffset(int column_index = -1); // get position of column line (in pixels, from the left side of the contents region). pass -1 to use current column, otherwise 0..GetColumnsCount() inclusive. column 0 is typically 0.0f - IMGUI_API void SetColumnOffset(int column_index, float offset_x); // set position of column line (in pixels, from the left side of the contents region). pass -1 to use current column - IMGUI_API int GetColumnsCount(); +// Columns +// You can also use SameLine(pos_x) for simplified columns. The columns API is still work-in-progress and rather lacking. +IMGUI_API void Columns(int count = 1, const char* id = NULL, bool border = true); +IMGUI_API void NextColumn(); // next column, defaults to current row or next row if the current row is finished +IMGUI_API int GetColumnIndex(); // get current column index +IMGUI_API float GetColumnWidth(int column_index = -1); // get column width (in pixels). pass -1 to use current column +IMGUI_API void SetColumnWidth(int column_index, float width); // set column width (in pixels). pass -1 to use current column +IMGUI_API float GetColumnOffset(int column_index = -1); // get position of column line (in pixels, from the left side of the contents region). pass -1 to use current column, otherwise 0..GetColumnsCount() inclusive. column 0 is typically 0.0f +IMGUI_API void SetColumnOffset(int column_index, float offset_x); // set position of column line (in pixels, from the left side of the contents region). pass -1 to use current column +IMGUI_API int GetColumnsCount(); - // ID scopes - // If you are creating widgets in a loop you most likely want to push a unique identifier (e.g. object pointer, loop index) so ImGui can differentiate them. - // You can also use the "##foobar" syntax within widget label to distinguish them from each others. Read "A primer on the use of labels/IDs" in the FAQ for more details. - IMGUI_API void PushID(const char* str_id); // push identifier into the ID stack. IDs are hash of the entire stack! - IMGUI_API void PushID(const char* str_id_begin, const char* str_id_end); - IMGUI_API void PushID(const void* ptr_id); - IMGUI_API void PushID(int int_id); - IMGUI_API void PopID(); - IMGUI_API ImGuiID GetID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). e.g. if you want to query into ImGuiStorage yourself - IMGUI_API ImGuiID GetID(const char* str_id_begin, const char* str_id_end); - IMGUI_API ImGuiID GetID(const void* ptr_id); +// ID scopes +// If you are creating widgets in a loop you most likely want to push a unique identifier (e.g. object pointer, loop index) so ImGui can differentiate them. +// You can also use the "##foobar" syntax within widget label to distinguish them from each others. Read "A primer on the use of labels/IDs" in the FAQ for more details. +IMGUI_API void PushID(const char* str_id); // push identifier into the ID stack. IDs are hash of the entire stack! +IMGUI_API void PushID(const char* str_id_begin, const char* str_id_end); +IMGUI_API void PushID(const void* ptr_id); +IMGUI_API void PushID(int int_id); +IMGUI_API void PopID(); +IMGUI_API ImGuiID GetID(const char* str_id); // calculate unique ID (hash of whole ID stack + given parameter). e.g. if you want to query into ImGuiStorage yourself +IMGUI_API ImGuiID GetID(const char* str_id_begin, const char* str_id_end); +IMGUI_API ImGuiID GetID(const void* ptr_id); - // Widgets: Text - IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // raw text without formatting. Roughly equivalent to Text("%s", text) but: A) doesn't require null terminated string if 'text_end' is specified, B) it's faster, no memory copy is done, no buffer size limits, recommended for long chunks of text. - IMGUI_API void Text(const char* fmt, ...) IM_FMTARGS(1); // simple formatted text - IMGUI_API void TextV(const char* fmt, va_list args) IM_FMTLIST(1); - IMGUI_API void TextColored(const ImVec4& col, const char* fmt, ...) IM_FMTARGS(2); // shortcut for PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor(); - IMGUI_API void TextColoredV(const ImVec4& col, const char* fmt, va_list args) IM_FMTLIST(2); - IMGUI_API void TextDisabled(const char* fmt, ...) IM_FMTARGS(1); // shortcut for PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]); Text(fmt, ...); PopStyleColor(); - IMGUI_API void TextDisabledV(const char* fmt, va_list args) IM_FMTLIST(1); - IMGUI_API void TextWrapped(const char* fmt, ...) IM_FMTARGS(1); // shortcut for PushTextWrapPos(0.0f); Text(fmt, ...); PopTextWrapPos();. Note that this won't work on an auto-resizing window if there's no other widgets to extend the window width, yoy may need to set a size using SetNextWindowSize(). - IMGUI_API void TextWrappedV(const char* fmt, va_list args) IM_FMTLIST(1); - IMGUI_API void LabelText(const char* label, const char* fmt, ...) IM_FMTARGS(2); // display text+label aligned the same way as value+label widgets - IMGUI_API void LabelTextV(const char* label, const char* fmt, va_list args) IM_FMTLIST(2); - IMGUI_API void BulletText(const char* fmt, ...) IM_FMTARGS(1); // shortcut for Bullet()+Text() - IMGUI_API void BulletTextV(const char* fmt, va_list args) IM_FMTLIST(1); - IMGUI_API void Bullet(); // draw a small circle and keep the cursor on the same line. advance cursor x position by GetTreeNodeToLabelSpacing(), same distance that TreeNode() uses +// Widgets: Text +IMGUI_API void TextUnformatted(const char* text, const char* text_end = NULL); // raw text without formatting. Roughly equivalent to Text("%s", text) but: A) doesn't require null terminated string if 'text_end' is specified, B) it's faster, no memory copy is done, no buffer size limits, recommended for long chunks of text. +IMGUI_API void Text(const char* fmt, ...) IM_FMTARGS(1); // simple formatted text +IMGUI_API void TextV(const char* fmt, va_list args) IM_FMTLIST(1); +IMGUI_API void TextColored(const ImVec4& col, const char* fmt, ...) IM_FMTARGS(2); // shortcut for PushStyleColor(ImGuiCol_Text, col); Text(fmt, ...); PopStyleColor(); +IMGUI_API void TextColoredV(const ImVec4& col, const char* fmt, va_list args) IM_FMTLIST(2); +IMGUI_API void TextDisabled(const char* fmt, ...) IM_FMTARGS(1); // shortcut for PushStyleColor(ImGuiCol_Text, style.Colors[ImGuiCol_TextDisabled]); Text(fmt, ...); PopStyleColor(); +IMGUI_API void TextDisabledV(const char* fmt, va_list args) IM_FMTLIST(1); +IMGUI_API void TextWrapped(const char* fmt, ...) IM_FMTARGS(1); // shortcut for PushTextWrapPos(0.0f); Text(fmt, ...); PopTextWrapPos();. Note that this won't work on an auto-resizing window if there's no other widgets to extend the window width, yoy may need to set a size using SetNextWindowSize(). +IMGUI_API void TextWrappedV(const char* fmt, va_list args) IM_FMTLIST(1); +IMGUI_API void LabelText(const char* label, const char* fmt, ...) IM_FMTARGS(2); // display text+label aligned the same way as value+label widgets +IMGUI_API void LabelTextV(const char* label, const char* fmt, va_list args) IM_FMTLIST(2); +IMGUI_API void BulletText(const char* fmt, ...) IM_FMTARGS(1); // shortcut for Bullet()+Text() +IMGUI_API void BulletTextV(const char* fmt, va_list args) IM_FMTLIST(1); +IMGUI_API void Bullet(); // draw a small circle and keep the cursor on the same line. advance cursor x position by GetTreeNodeToLabelSpacing(), same distance that TreeNode() uses - // Widgets: Main - IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0,0)); // button - IMGUI_API bool SmallButton(const char* label); // button with FramePadding=(0,0) to easily embed within text - IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size); // button behavior without the visuals, useful to build custom behaviors using the public api (along with IsItemActive, IsItemHovered, etc.) - IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), const ImVec4& tint_col = ImVec4(1,1,1,1), const ImVec4& border_col = ImVec4(0,0,0,0)); - IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0,0), const ImVec2& uv1 = ImVec2(1,1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0,0,0,0), const ImVec4& tint_col = ImVec4(1,1,1,1)); // <0 frame_padding uses default frame padding settings. 0 for no padding - IMGUI_API bool Checkbox(const char* label, bool* v); - IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value); - IMGUI_API bool RadioButton(const char* label, bool active); - IMGUI_API bool RadioButton(const char* label, int* v, int v_button); - IMGUI_API void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), int stride = sizeof(float)); - IMGUI_API void PlotLines(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0)); - IMGUI_API void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0), int stride = sizeof(float)); - IMGUI_API void PlotHistogram(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0,0)); - IMGUI_API void ProgressBar(float fraction, const ImVec2& size_arg = ImVec2(-1,0), const char* overlay = NULL); +// Widgets: Main +IMGUI_API bool Button(const char* label, const ImVec2& size = ImVec2(0, 0)); // button +IMGUI_API bool SmallButton(const char* label); // button with FramePadding=(0,0) to easily embed within text +IMGUI_API bool InvisibleButton(const char* str_id, const ImVec2& size); // button behavior without the visuals, useful to build custom behaviors using the public api (along with IsItemActive, IsItemHovered, etc.) +IMGUI_API void Image(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), const ImVec4& tint_col = ImVec4(1, 1, 1, 1), const ImVec4& border_col = ImVec4(0, 0, 0, 0)); +IMGUI_API bool ImageButton(ImTextureID user_texture_id, const ImVec2& size, const ImVec2& uv0 = ImVec2(0, 0), const ImVec2& uv1 = ImVec2(1, 1), int frame_padding = -1, const ImVec4& bg_col = ImVec4(0, 0, 0, 0), const ImVec4& tint_col = ImVec4(1, 1, 1, 1)); // <0 frame_padding uses default frame padding settings. 0 for no padding +IMGUI_API bool Checkbox(const char* label, bool* v); +IMGUI_API bool CheckboxFlags(const char* label, unsigned int* flags, unsigned int flags_value); +IMGUI_API bool RadioButton(const char* label, bool active); +IMGUI_API bool RadioButton(const char* label, int* v, int v_button); +IMGUI_API void PlotLines(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float)); +IMGUI_API void PlotLines(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0)); +IMGUI_API void PlotHistogram(const char* label, const float* values, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0), int stride = sizeof(float)); +IMGUI_API void PlotHistogram(const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset = 0, const char* overlay_text = NULL, float scale_min = FLT_MAX, float scale_max = FLT_MAX, ImVec2 graph_size = ImVec2(0, 0)); +IMGUI_API void ProgressBar(float fraction, const ImVec2& size_arg = ImVec2(-1, 0), const char* overlay = NULL); - // Widgets: Combo Box - // The new BeginCombo()/EndCombo() api allows you to manage your contents and selection state however you want it. - // The old Combo() api are helpers over BeginCombo()/EndCombo() which are kept available for convenience purpose. - IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0); - IMGUI_API void EndCombo(); // only call EndCombo() if BeginCombo() returns true! - IMGUI_API bool Combo(const char* label, int* current_item, const char* const items[], int items_count, int popup_max_height_in_items = -1); - IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_max_height_in_items = -1); // Separate items with \0 within a string, end item-list with \0\0. e.g. "One\0Two\0Three\0" - IMGUI_API bool Combo(const char* label, int* current_item, bool(*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int popup_max_height_in_items = -1); +// Widgets: Combo Box +// The new BeginCombo()/EndCombo() api allows you to manage your contents and selection state however you want it. +// The old Combo() api are helpers over BeginCombo()/EndCombo() which are kept available for convenience purpose. +IMGUI_API bool BeginCombo(const char* label, const char* preview_value, ImGuiComboFlags flags = 0); +IMGUI_API void EndCombo(); // only call EndCombo() if BeginCombo() returns true! +IMGUI_API bool Combo(const char* label, int* current_item, const char* const items[], int items_count, int popup_max_height_in_items = -1); +IMGUI_API bool Combo(const char* label, int* current_item, const char* items_separated_by_zeros, int popup_max_height_in_items = -1); // Separate items with \0 within a string, end item-list with \0\0. e.g. "One\0Two\0Three\0" +IMGUI_API bool Combo(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int popup_max_height_in_items = -1); - // Widgets: Drags (tip: ctrl+click on a drag box to input with keyboard. manually input values aren't clamped, can go off-bounds) - // For all the Float2/Float3/Float4/Int2/Int3/Int4 versions of every functions, note that a 'float v[X]' function argument is the same as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible. You can pass address of your first element out of a contiguous set, e.g. &myvector.x - // Speed are per-pixel of mouse movement (v_speed=0.2f: mouse needs to move by 5 pixels to increase value by 1). For gamepad/keyboard navigation, minimum speed is Max(v_speed, minimum_step_at_given_precision). - IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); // If v_min >= v_max we have no bound - IMGUI_API bool DragFloat2(const char* label, float v[2], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool DragFloat3(const char* label, float v[3], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool DragFloat4(const char* label, float v[4], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", const char* display_format_max = NULL, float power = 1.0f); - IMGUI_API bool DragInt(const char* label, int* v, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); // If v_min >= v_max we have no bound - IMGUI_API bool DragInt2(const char* label, int v[2], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); - IMGUI_API bool DragInt3(const char* label, int v[3], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); - IMGUI_API bool DragInt4(const char* label, int v[4], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); - IMGUI_API bool DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f", const char* display_format_max = NULL); +// Widgets: Drags (tip: ctrl+click on a drag box to input with keyboard. manually input values aren't clamped, can go off-bounds) +// For all the Float2/Float3/Float4/Int2/Int3/Int4 versions of every functions, note that a 'float v[X]' function argument is the same as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible. You can pass address of your first element out of a contiguous set, e.g. &myvector.x +// Speed are per-pixel of mouse movement (v_speed=0.2f: mouse needs to move by 5 pixels to increase value by 1). For gamepad/keyboard navigation, minimum speed is Max(v_speed, minimum_step_at_given_precision). +IMGUI_API bool DragFloat(const char* label, float* v, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); // If v_min >= v_max we have no bound +IMGUI_API bool DragFloat2(const char* label, float v[2], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); +IMGUI_API bool DragFloat3(const char* label, float v[3], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); +IMGUI_API bool DragFloat4(const char* label, float v[4], float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", float power = 1.0f); +IMGUI_API bool DragFloatRange2(const char* label, float* v_current_min, float* v_current_max, float v_speed = 1.0f, float v_min = 0.0f, float v_max = 0.0f, const char* display_format = "%.3f", const char* display_format_max = NULL, float power = 1.0f); +IMGUI_API bool DragInt(const char* label, int* v, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); // If v_min >= v_max we have no bound +IMGUI_API bool DragInt2(const char* label, int v[2], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); +IMGUI_API bool DragInt3(const char* label, int v[3], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); +IMGUI_API bool DragInt4(const char* label, int v[4], float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f"); +IMGUI_API bool DragIntRange2(const char* label, int* v_current_min, int* v_current_max, float v_speed = 1.0f, int v_min = 0, int v_max = 0, const char* display_format = "%.0f", const char* display_format_max = NULL); - // Widgets: Input with Keyboard - IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL); - IMGUI_API bool InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size = ImVec2(0,0), ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL); - IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0); - IMGUI_API bool InputFloat2(const char* label, float v[2], int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0); - IMGUI_API bool InputFloat3(const char* label, float v[3], int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0); - IMGUI_API bool InputFloat4(const char* label, float v[4], int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0); - IMGUI_API bool InputInt(const char* label, int* v, int step = 1, int step_fast = 100, ImGuiInputTextFlags extra_flags = 0); - IMGUI_API bool InputInt2(const char* label, int v[2], ImGuiInputTextFlags extra_flags = 0); - IMGUI_API bool InputInt3(const char* label, int v[3], ImGuiInputTextFlags extra_flags = 0); - IMGUI_API bool InputInt4(const char* label, int v[4], ImGuiInputTextFlags extra_flags = 0); +// Widgets: Input with Keyboard +IMGUI_API bool InputText(const char* label, char* buf, size_t buf_size, ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL); +IMGUI_API bool InputTextMultiline(const char* label, char* buf, size_t buf_size, const ImVec2& size = ImVec2(0, 0), ImGuiInputTextFlags flags = 0, ImGuiTextEditCallback callback = NULL, void* user_data = NULL); +IMGUI_API bool InputFloat(const char* label, float* v, float step = 0.0f, float step_fast = 0.0f, int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0); +IMGUI_API bool InputFloat2(const char* label, float v[2], int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0); +IMGUI_API bool InputFloat3(const char* label, float v[3], int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0); +IMGUI_API bool InputFloat4(const char* label, float v[4], int decimal_precision = -1, ImGuiInputTextFlags extra_flags = 0); +IMGUI_API bool InputInt(const char* label, int* v, int step = 1, int step_fast = 100, ImGuiInputTextFlags extra_flags = 0); +IMGUI_API bool InputInt2(const char* label, int v[2], ImGuiInputTextFlags extra_flags = 0); +IMGUI_API bool InputInt3(const char* label, int v[3], ImGuiInputTextFlags extra_flags = 0); +IMGUI_API bool InputInt4(const char* label, int v[4], ImGuiInputTextFlags extra_flags = 0); - // Widgets: Sliders (tip: ctrl+click on a slider to input with keyboard. manually input values aren't clamped, can go off-bounds) - IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); // adjust display_format to decorate the value with a prefix or a suffix for in-slider labels or unit display. Use power!=1.0 for logarithmic sliders - IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool SliderAngle(const char* label, float* v_rad, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f); - IMGUI_API bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format = "%.0f"); - IMGUI_API bool SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* display_format = "%.0f"); - IMGUI_API bool SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* display_format = "%.0f"); - IMGUI_API bool SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* display_format = "%.0f"); - IMGUI_API bool VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); - IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format = "%.0f"); +// Widgets: Sliders (tip: ctrl+click on a slider to input with keyboard. manually input values aren't clamped, can go off-bounds) +IMGUI_API bool SliderFloat(const char* label, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); // adjust display_format to decorate the value with a prefix or a suffix for in-slider labels or unit display. Use power!=1.0 for logarithmic sliders +IMGUI_API bool SliderFloat2(const char* label, float v[2], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); +IMGUI_API bool SliderFloat3(const char* label, float v[3], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); +IMGUI_API bool SliderFloat4(const char* label, float v[4], float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); +IMGUI_API bool SliderAngle(const char* label, float* v_rad, float v_degrees_min = -360.0f, float v_degrees_max = +360.0f); +IMGUI_API bool SliderInt(const char* label, int* v, int v_min, int v_max, const char* display_format = "%.0f"); +IMGUI_API bool SliderInt2(const char* label, int v[2], int v_min, int v_max, const char* display_format = "%.0f"); +IMGUI_API bool SliderInt3(const char* label, int v[3], int v_min, int v_max, const char* display_format = "%.0f"); +IMGUI_API bool SliderInt4(const char* label, int v[4], int v_min, int v_max, const char* display_format = "%.0f"); +IMGUI_API bool VSliderFloat(const char* label, const ImVec2& size, float* v, float v_min, float v_max, const char* display_format = "%.3f", float power = 1.0f); +IMGUI_API bool VSliderInt(const char* label, const ImVec2& size, int* v, int v_min, int v_max, const char* display_format = "%.0f"); - // Widgets: Color Editor/Picker (tip: the ColorEdit* functions have a little colored preview square that can be left-clicked to open a picker, and right-clicked to open an option menu.) - // Note that a 'float v[X]' function argument is the same as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible. You can the pass the address of a first float element out of a contiguous structure, e.g. &myvector.x - IMGUI_API bool ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); - IMGUI_API bool ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0); - IMGUI_API bool ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); - IMGUI_API bool ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags = 0, const float* ref_col = NULL); - IMGUI_API bool ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0,0)); // display a colored square/button, hover for details, return true when pressed. - IMGUI_API void SetColorEditOptions(ImGuiColorEditFlags flags); // initialize current options (generally on application startup) if you want to select a default format, picker type, etc. User will be able to change many settings, unless you pass the _NoOptions flag to your calls. +// Widgets: Color Editor/Picker (tip: the ColorEdit* functions have a little colored preview square that can be left-clicked to open a picker, and right-clicked to open an option menu.) +// Note that a 'float v[X]' function argument is the same as 'float* v', the array syntax is just a way to document the number of elements that are expected to be accessible. You can the pass the address of a first float element out of a contiguous structure, e.g. &myvector.x +IMGUI_API bool ColorEdit3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); +IMGUI_API bool ColorEdit4(const char* label, float col[4], ImGuiColorEditFlags flags = 0); +IMGUI_API bool ColorPicker3(const char* label, float col[3], ImGuiColorEditFlags flags = 0); +IMGUI_API bool ColorPicker4(const char* label, float col[4], ImGuiColorEditFlags flags = 0, const float* ref_col = NULL); +IMGUI_API bool ColorButton(const char* desc_id, const ImVec4& col, ImGuiColorEditFlags flags = 0, ImVec2 size = ImVec2(0, 0)); // display a colored square/button, hover for details, return true when pressed. +IMGUI_API void SetColorEditOptions(ImGuiColorEditFlags flags); // initialize current options (generally on application startup) if you want to select a default format, picker type, etc. User will be able to change many settings, unless you pass the _NoOptions flag to your calls. - // Widgets: Trees - IMGUI_API bool TreeNode(const char* label); // if returning 'true' the node is open and the tree id is pushed into the id stack. user is responsible for calling TreePop(). - IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...) IM_FMTARGS(2); // read the FAQ about why and how to use ID. to align arbitrary text at the same level as a TreeNode() you can use Bullet(). - IMGUI_API bool TreeNode(const void* ptr_id, const char* fmt, ...) IM_FMTARGS(2); // " - IMGUI_API bool TreeNodeV(const char* str_id, const char* fmt, va_list args) IM_FMTLIST(2); - IMGUI_API bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args) IM_FMTLIST(2); - IMGUI_API bool TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags = 0); - IMGUI_API bool TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_FMTARGS(3); - IMGUI_API bool TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_FMTARGS(3); - IMGUI_API bool TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(3); - IMGUI_API bool TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(3); - IMGUI_API void TreePush(const char* str_id); // ~ Indent()+PushId(). Already called by TreeNode() when returning true, but you can call Push/Pop yourself for layout purpose - IMGUI_API void TreePush(const void* ptr_id = NULL); // " - IMGUI_API void TreePop(); // ~ Unindent()+PopId() - IMGUI_API void TreeAdvanceToLabelPos(); // advance cursor x position by GetTreeNodeToLabelSpacing() - IMGUI_API float GetTreeNodeToLabelSpacing(); // horizontal distance preceding label when using TreeNode*() or Bullet() == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode - IMGUI_API void SetNextTreeNodeOpen(bool is_open, ImGuiCond cond = 0); // set next TreeNode/CollapsingHeader open state. - IMGUI_API bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0); // if returning 'true' the header is open. doesn't indent nor push on ID stack. user doesn't have to call TreePop(). - IMGUI_API bool CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags = 0); // when 'p_open' isn't NULL, display an additional small close button on upper right of the header +// Widgets: Trees +IMGUI_API bool TreeNode(const char* label); // if returning 'true' the node is open and the tree id is pushed into the id stack. user is responsible for calling TreePop(). +IMGUI_API bool TreeNode(const char* str_id, const char* fmt, ...) IM_FMTARGS(2); // read the FAQ about why and how to use ID. to align arbitrary text at the same level as a TreeNode() you can use Bullet(). +IMGUI_API bool TreeNode(const void* ptr_id, const char* fmt, ...) IM_FMTARGS(2); // " +IMGUI_API bool TreeNodeV(const char* str_id, const char* fmt, va_list args) IM_FMTLIST(2); +IMGUI_API bool TreeNodeV(const void* ptr_id, const char* fmt, va_list args) IM_FMTLIST(2); +IMGUI_API bool TreeNodeEx(const char* label, ImGuiTreeNodeFlags flags = 0); +IMGUI_API bool TreeNodeEx(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_FMTARGS(3); +IMGUI_API bool TreeNodeEx(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, ...) IM_FMTARGS(3); +IMGUI_API bool TreeNodeExV(const char* str_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(3); +IMGUI_API bool TreeNodeExV(const void* ptr_id, ImGuiTreeNodeFlags flags, const char* fmt, va_list args) IM_FMTLIST(3); +IMGUI_API void TreePush(const char* str_id); // ~ Indent()+PushId(). Already called by TreeNode() when returning true, but you can call Push/Pop yourself for layout purpose +IMGUI_API void TreePush(const void* ptr_id = NULL); // " +IMGUI_API void TreePop(); // ~ Unindent()+PopId() +IMGUI_API void TreeAdvanceToLabelPos(); // advance cursor x position by GetTreeNodeToLabelSpacing() +IMGUI_API float GetTreeNodeToLabelSpacing(); // horizontal distance preceding label when using TreeNode*() or Bullet() == (g.FontSize + style.FramePadding.x*2) for a regular unframed TreeNode +IMGUI_API void SetNextTreeNodeOpen(bool is_open, ImGuiCond cond = 0); // set next TreeNode/CollapsingHeader open state. +IMGUI_API bool CollapsingHeader(const char* label, ImGuiTreeNodeFlags flags = 0); // if returning 'true' the header is open. doesn't indent nor push on ID stack. user doesn't have to call TreePop(). +IMGUI_API bool CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags flags = 0); // when 'p_open' isn't NULL, display an additional small close button on upper right of the header - // Widgets: Selectable / Lists - IMGUI_API bool Selectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); // "bool selected" carry the selection state (read-only). Selectable() is clicked is returns true so you can modify your selection state. size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height - IMGUI_API bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0,0)); // "bool* p_selected" point to the selection state (read-write), as a convenient helper. - IMGUI_API bool ListBox(const char* label, int* current_item, const char* const items[], int items_count, int height_in_items = -1); - IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); - IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0,0)); // use if you want to reimplement ListBox() will custom data or interactions. make sure to call ListBoxFooter() afterwards. - IMGUI_API bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // " - IMGUI_API void ListBoxFooter(); // terminate the scrolling region +// Widgets: Selectable / Lists +IMGUI_API bool Selectable(const char* label, bool selected = false, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0, 0)); // "bool selected" carry the selection state (read-only). Selectable() is clicked is returns true so you can modify your selection state. size.x==0.0: use remaining width, size.x>0.0: specify width. size.y==0.0: use label height, size.y>0.0: specify height +IMGUI_API bool Selectable(const char* label, bool* p_selected, ImGuiSelectableFlags flags = 0, const ImVec2& size = ImVec2(0, 0)); // "bool* p_selected" point to the selection state (read-write), as a convenient helper. +IMGUI_API bool ListBox(const char* label, int* current_item, const char* const items[], int items_count, int height_in_items = -1); +IMGUI_API bool ListBox(const char* label, int* current_item, bool (*items_getter)(void* data, int idx, const char** out_text), void* data, int items_count, int height_in_items = -1); +IMGUI_API bool ListBoxHeader(const char* label, const ImVec2& size = ImVec2(0, 0)); // use if you want to reimplement ListBox() will custom data or interactions. make sure to call ListBoxFooter() afterwards. +IMGUI_API bool ListBoxHeader(const char* label, int items_count, int height_in_items = -1); // " +IMGUI_API void ListBoxFooter(); // terminate the scrolling region - // Widgets: Value() Helpers. Output single value in "name: value" format (tip: freely declare more in your code to handle your types. you can add functions to the ImGui namespace) - IMGUI_API void Value(const char* prefix, bool b); - IMGUI_API void Value(const char* prefix, int v); - IMGUI_API void Value(const char* prefix, unsigned int v); - IMGUI_API void Value(const char* prefix, float v, const char* float_format = NULL); +// Widgets: Value() Helpers. Output single value in "name: value" format (tip: freely declare more in your code to handle your types. you can add functions to the ImGui namespace) +IMGUI_API void Value(const char* prefix, bool b); +IMGUI_API void Value(const char* prefix, int v); +IMGUI_API void Value(const char* prefix, unsigned int v); +IMGUI_API void Value(const char* prefix, float v, const char* float_format = NULL); - // Tooltips - IMGUI_API void SetTooltip(const char* fmt, ...) IM_FMTARGS(1); // set text tooltip under mouse-cursor, typically use with ImGui::IsItemHovered(). overidde any previous call to SetTooltip(). - IMGUI_API void SetTooltipV(const char* fmt, va_list args) IM_FMTLIST(1); - IMGUI_API void BeginTooltip(); // begin/append a tooltip window. to create full-featured tooltip (with any kind of contents). - IMGUI_API void EndTooltip(); +// Tooltips +IMGUI_API void SetTooltip(const char* fmt, ...) IM_FMTARGS(1); // set text tooltip under mouse-cursor, typically use with ImGui::IsItemHovered(). overidde any previous call to SetTooltip(). +IMGUI_API void SetTooltipV(const char* fmt, va_list args) IM_FMTLIST(1); +IMGUI_API void BeginTooltip(); // begin/append a tooltip window. to create full-featured tooltip (with any kind of contents). +IMGUI_API void EndTooltip(); - // Menus - IMGUI_API bool BeginMainMenuBar(); // create and append to a full screen menu-bar. - IMGUI_API void EndMainMenuBar(); // only call EndMainMenuBar() if BeginMainMenuBar() returns true! - IMGUI_API bool BeginMenuBar(); // append to menu-bar of current window (requires ImGuiWindowFlags_MenuBar flag set on parent window). - IMGUI_API void EndMenuBar(); // only call EndMenuBar() if BeginMenuBar() returns true! - IMGUI_API bool BeginMenu(const char* label, bool enabled = true); // create a sub-menu entry. only call EndMenu() if this returns true! - IMGUI_API void EndMenu(); // only call EndBegin() if BeginMenu() returns true! - IMGUI_API bool MenuItem(const char* label, const char* shortcut = NULL, bool selected = false, bool enabled = true); // return true when activated. shortcuts are displayed for convenience but not processed by ImGui at the moment - IMGUI_API bool MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled = true); // return true when activated + toggle (*p_selected) if p_selected != NULL +// Menus +IMGUI_API bool BeginMainMenuBar(); // create and append to a full screen menu-bar. +IMGUI_API void EndMainMenuBar(); // only call EndMainMenuBar() if BeginMainMenuBar() returns true! +IMGUI_API bool BeginMenuBar(); // append to menu-bar of current window (requires ImGuiWindowFlags_MenuBar flag set on parent window). +IMGUI_API void EndMenuBar(); // only call EndMenuBar() if BeginMenuBar() returns true! +IMGUI_API bool BeginMenu(const char* label, bool enabled = true); // create a sub-menu entry. only call EndMenu() if this returns true! +IMGUI_API void EndMenu(); // only call EndBegin() if BeginMenu() returns true! +IMGUI_API bool MenuItem(const char* label, const char* shortcut = NULL, bool selected = false, bool enabled = true); // return true when activated. shortcuts are displayed for convenience but not processed by ImGui at the moment +IMGUI_API bool MenuItem(const char* label, const char* shortcut, bool* p_selected, bool enabled = true); // return true when activated + toggle (*p_selected) if p_selected != NULL - // Popups - IMGUI_API void OpenPopup(const char* str_id); // call to mark popup as open (don't call every frame!). popups are closed when user click outside, or if CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. By default, Selectable()/MenuItem() are calling CloseCurrentPopup(). Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). - IMGUI_API bool BeginPopup(const char* str_id, ImGuiWindowFlags flags = 0); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returns true! - IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked on last item. if you can pass a NULL str_id only if the previous item had an id. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp! - IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, int mouse_button = 1, bool also_over_items = true); // helper to open and begin popup when clicked on current window. - IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked in void (where there are no imgui windows). - IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // modal dialog (regular window with title bar, block interactions behind the modal window, can't close the modal window by clicking outside) - IMGUI_API void EndPopup(); // only call EndPopup() if BeginPopupXXX() returns true! - IMGUI_API bool OpenPopupOnItemClick(const char* str_id = NULL, int mouse_button = 1); // helper to open popup when clicked on last item. return true when just opened. - IMGUI_API bool IsPopupOpen(const char* str_id); // return true if the popup is open - IMGUI_API void CloseCurrentPopup(); // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup. +// Popups +IMGUI_API void OpenPopup(const char* str_id); // call to mark popup as open (don't call every frame!). popups are closed when user click outside, or if CloseCurrentPopup() is called within a BeginPopup()/EndPopup() block. By default, Selectable()/MenuItem() are calling CloseCurrentPopup(). Popup identifiers are relative to the current ID-stack (so OpenPopup and BeginPopup needs to be at the same level). +IMGUI_API bool BeginPopup(const char* str_id, ImGuiWindowFlags flags = 0); // return true if the popup is open, and you can start outputting to it. only call EndPopup() if BeginPopup() returns true! +IMGUI_API bool BeginPopupContextItem(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked on last item. if you can pass a NULL str_id only if the previous item had an id. If you want to use that on a non-interactive item such as Text() you need to pass in an explicit ID here. read comments in .cpp! +IMGUI_API bool BeginPopupContextWindow(const char* str_id = NULL, int mouse_button = 1, bool also_over_items = true); // helper to open and begin popup when clicked on current window. +IMGUI_API bool BeginPopupContextVoid(const char* str_id = NULL, int mouse_button = 1); // helper to open and begin popup when clicked in void (where there are no imgui windows). +IMGUI_API bool BeginPopupModal(const char* name, bool* p_open = NULL, ImGuiWindowFlags flags = 0); // modal dialog (regular window with title bar, block interactions behind the modal window, can't close the modal window by clicking outside) +IMGUI_API void EndPopup(); // only call EndPopup() if BeginPopupXXX() returns true! +IMGUI_API bool OpenPopupOnItemClick(const char* str_id = NULL, int mouse_button = 1); // helper to open popup when clicked on last item. return true when just opened. +IMGUI_API bool IsPopupOpen(const char* str_id); // return true if the popup is open +IMGUI_API void CloseCurrentPopup(); // close the popup we have begin-ed into. clicking on a MenuItem or Selectable automatically close the current popup. - // Logging/Capture: all text output from interface is captured to tty/file/clipboard. By default, tree nodes are automatically opened during logging. - IMGUI_API void LogToTTY(int max_depth = -1); // start logging to tty - IMGUI_API void LogToFile(int max_depth = -1, const char* filename = NULL); // start logging to file - IMGUI_API void LogToClipboard(int max_depth = -1); // start logging to OS clipboard - IMGUI_API void LogFinish(); // stop logging (close file, etc.) - IMGUI_API void LogButtons(); // helper to display buttons for logging to tty/file/clipboard - IMGUI_API void LogText(const char* fmt, ...) IM_FMTARGS(1); // pass text data straight to log (without being displayed) +// Logging/Capture: all text output from interface is captured to tty/file/clipboard. By default, tree nodes are automatically opened during logging. +IMGUI_API void LogToTTY(int max_depth = -1); // start logging to tty +IMGUI_API void LogToFile(int max_depth = -1, const char* filename = NULL); // start logging to file +IMGUI_API void LogToClipboard(int max_depth = -1); // start logging to OS clipboard +IMGUI_API void LogFinish(); // stop logging (close file, etc.) +IMGUI_API void LogButtons(); // helper to display buttons for logging to tty/file/clipboard +IMGUI_API void LogText(const char* fmt, ...) IM_FMTARGS(1); // pass text data straight to log (without being displayed) - // Drag and Drop - // [BETA API] Missing Demo code. API may evolve. - IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0); // call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource() - IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t size, ImGuiCond cond = 0);// type is a user defined string of maximum 12 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. - IMGUI_API void EndDragDropSource(); // only call EndDragDropSource() if BeginDragDropSource() returns true! - IMGUI_API bool BeginDragDropTarget(); // call after submitting an item that may receive an item. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget() - IMGUI_API const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags = 0); // accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released. - IMGUI_API void EndDragDropTarget(); // only call EndDragDropTarget() if BeginDragDropTarget() returns true! +// Drag and Drop +// [BETA API] Missing Demo code. API may evolve. +IMGUI_API bool BeginDragDropSource(ImGuiDragDropFlags flags = 0); // call when the current item is active. If this return true, you can call SetDragDropPayload() + EndDragDropSource() +IMGUI_API bool SetDragDropPayload(const char* type, const void* data, size_t size, ImGuiCond cond = 0); // type is a user defined string of maximum 12 characters. Strings starting with '_' are reserved for dear imgui internal types. Data is copied and held by imgui. +IMGUI_API void EndDragDropSource(); // only call EndDragDropSource() if BeginDragDropSource() returns true! +IMGUI_API bool BeginDragDropTarget(); // call after submitting an item that may receive an item. If this returns true, you can call AcceptDragDropPayload() + EndDragDropTarget() +IMGUI_API const ImGuiPayload* AcceptDragDropPayload(const char* type, ImGuiDragDropFlags flags = 0); // accept contents of a given type. If ImGuiDragDropFlags_AcceptBeforeDelivery is set you can peek into the payload before the mouse button is released. +IMGUI_API void EndDragDropTarget(); // only call EndDragDropTarget() if BeginDragDropTarget() returns true! - // Clipping - IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect); - IMGUI_API void PopClipRect(); +// Clipping +IMGUI_API void PushClipRect(const ImVec2& clip_rect_min, const ImVec2& clip_rect_max, bool intersect_with_current_clip_rect); +IMGUI_API void PopClipRect(); - // Focus, Activation - // (Prefer using "SetItemDefaultFocus()" over "if (IsWindowAppearing()) SetScrollHere()" when applicable, to make your code more forward compatible when navigation branch is merged) - IMGUI_API void SetItemDefaultFocus(); // make last item the default focused item of a window. Please use instead of "if (IsWindowAppearing()) SetScrollHere()" to signify "default item". - IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget. +// Focus, Activation +// (Prefer using "SetItemDefaultFocus()" over "if (IsWindowAppearing()) SetScrollHere()" when applicable, to make your code more forward compatible when navigation branch is merged) +IMGUI_API void SetItemDefaultFocus(); // make last item the default focused item of a window. Please use instead of "if (IsWindowAppearing()) SetScrollHere()" to signify "default item". +IMGUI_API void SetKeyboardFocusHere(int offset = 0); // focus keyboard on the next widget. Use positive 'offset' to access sub components of a multiple component widget. Use -1 to access previous widget. - // Utilities - IMGUI_API bool IsItemHovered(ImGuiHoveredFlags flags = 0); // is the last item hovered? (and usable, aka not blocked by a popup, etc.). See ImGuiHoveredFlags for more options. - IMGUI_API bool IsItemActive(); // is the last item active? (e.g. button being held, text field being edited- items that don't interact will always return false) - IMGUI_API bool IsItemFocused(); // is the last item focused for keyboard/gamepad navigation? - IMGUI_API bool IsItemClicked(int mouse_button = 0); // is the last item clicked? (e.g. button/node just clicked on) - IMGUI_API bool IsItemVisible(); // is the last item visible? (aka not out of sight due to clipping/scrolling.) - IMGUI_API bool IsAnyItemHovered(); - IMGUI_API bool IsAnyItemActive(); - IMGUI_API bool IsAnyItemFocused(); - IMGUI_API ImVec2 GetItemRectMin(); // get bounding rectangle of last item, in screen space - IMGUI_API ImVec2 GetItemRectMax(); // " - IMGUI_API ImVec2 GetItemRectSize(); // get size of last item, in screen space - IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area. - IMGUI_API bool IsWindowFocused(ImGuiFocusedFlags flags = 0); // is current window focused? or its root/child, depending on flags. see flags for options. - IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags = 0); // is current window hovered (and typically: not blocked by a popup/modal)? see flags for options. - IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped. - IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. - IMGUI_API float GetTime(); - IMGUI_API int GetFrameCount(); - IMGUI_API ImDrawList* GetOverlayDrawList(); // this draw list will be the last rendered one, useful to quickly draw overlays shapes/text - IMGUI_API ImDrawListSharedData* GetDrawListSharedData(); - IMGUI_API const char* GetStyleColorName(ImGuiCol idx); - IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f); - IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // calculate coarse clipping for large list of evenly sized items. Prefer using the ImGuiListClipper higher-level helper if you can. +// Utilities +IMGUI_API bool IsItemHovered(ImGuiHoveredFlags flags = 0); // is the last item hovered? (and usable, aka not blocked by a popup, etc.). See ImGuiHoveredFlags for more options. +IMGUI_API bool IsItemActive(); // is the last item active? (e.g. button being held, text field being edited- items that don't interact will always return false) +IMGUI_API bool IsItemFocused(); // is the last item focused for keyboard/gamepad navigation? +IMGUI_API bool IsItemClicked(int mouse_button = 0); // is the last item clicked? (e.g. button/node just clicked on) +IMGUI_API bool IsItemVisible(); // is the last item visible? (aka not out of sight due to clipping/scrolling.) +IMGUI_API bool IsAnyItemHovered(); +IMGUI_API bool IsAnyItemActive(); +IMGUI_API bool IsAnyItemFocused(); +IMGUI_API ImVec2 GetItemRectMin(); // get bounding rectangle of last item, in screen space +IMGUI_API ImVec2 GetItemRectMax(); // " +IMGUI_API ImVec2 GetItemRectSize(); // get size of last item, in screen space +IMGUI_API void SetItemAllowOverlap(); // allow last item to be overlapped by a subsequent item. sometimes useful with invisible buttons, selectables, etc. to catch unused area. +IMGUI_API bool IsWindowFocused(ImGuiFocusedFlags flags = 0); // is current window focused? or its root/child, depending on flags. see flags for options. +IMGUI_API bool IsWindowHovered(ImGuiHoveredFlags flags = 0); // is current window hovered (and typically: not blocked by a popup/modal)? see flags for options. +IMGUI_API bool IsRectVisible(const ImVec2& size); // test if rectangle (of given size, starting from cursor position) is visible / not clipped. +IMGUI_API bool IsRectVisible(const ImVec2& rect_min, const ImVec2& rect_max); // test if rectangle (in screen space) is visible / not clipped. to perform coarse clipping on user's side. +IMGUI_API float GetTime(); +IMGUI_API int GetFrameCount(); +IMGUI_API ImDrawList* GetOverlayDrawList(); // this draw list will be the last rendered one, useful to quickly draw overlays shapes/text +IMGUI_API ImDrawListSharedData* GetDrawListSharedData(); +IMGUI_API const char* GetStyleColorName(ImGuiCol idx); +IMGUI_API ImVec2 CalcTextSize(const char* text, const char* text_end = NULL, bool hide_text_after_double_hash = false, float wrap_width = -1.0f); +IMGUI_API void CalcListClipping(int items_count, float items_height, int* out_items_display_start, int* out_items_display_end); // calculate coarse clipping for large list of evenly sized items. Prefer using the ImGuiListClipper higher-level helper if you can. - IMGUI_API bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags flags = 0); // helper to create a child window / scrolling region that looks like a normal widget frame - IMGUI_API void EndChildFrame(); // always call EndChildFrame() regardless of BeginChildFrame() return values (which indicates a collapsed/clipped window) +IMGUI_API bool BeginChildFrame(ImGuiID id, const ImVec2& size, ImGuiWindowFlags flags = 0); // helper to create a child window / scrolling region that looks like a normal widget frame +IMGUI_API void EndChildFrame(); // always call EndChildFrame() regardless of BeginChildFrame() return values (which indicates a collapsed/clipped window) - IMGUI_API ImVec4 ColorConvertU32ToFloat4(ImU32 in); - IMGUI_API ImU32 ColorConvertFloat4ToU32(const ImVec4& in); - IMGUI_API void ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v); - IMGUI_API void ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b); +IMGUI_API ImVec4 ColorConvertU32ToFloat4(ImU32 in); +IMGUI_API ImU32 ColorConvertFloat4ToU32(const ImVec4& in); +IMGUI_API void ColorConvertRGBtoHSV(float r, float g, float b, float& out_h, float& out_s, float& out_v); +IMGUI_API void ColorConvertHSVtoRGB(float h, float s, float v, float& out_r, float& out_g, float& out_b); - // Inputs - IMGUI_API int GetKeyIndex(ImGuiKey imgui_key); // map ImGuiKey_* values into user's key index. == io.KeyMap[key] - IMGUI_API bool IsKeyDown(int user_key_index); // is key being held. == io.KeysDown[user_key_index]. note that imgui doesn't know the semantic of each entry of io.KeyDown[]. Use your own indices/enums according to how your backend/engine stored them into KeyDown[]! - IMGUI_API bool IsKeyPressed(int user_key_index, bool repeat = true); // was key pressed (went from !Down to Down). if repeat=true, uses io.KeyRepeatDelay / KeyRepeatRate - IMGUI_API bool IsKeyReleased(int user_key_index); // was key released (went from Down to !Down).. - IMGUI_API int GetKeyPressedAmount(int key_index, float repeat_delay, float rate); // uses provided repeat rate/delay. return a count, most often 0 or 1 but might be >1 if RepeatRate is small enough that DeltaTime > RepeatRate - IMGUI_API bool IsMouseDown(int button); // is mouse button held - IMGUI_API bool IsAnyMouseDown(); // is any mouse button held - IMGUI_API bool IsMouseClicked(int button, bool repeat = false); // did mouse button clicked (went from !Down to Down) - IMGUI_API bool IsMouseDoubleClicked(int button); // did mouse button double-clicked. a double-click returns false in IsMouseClicked(). uses io.MouseDoubleClickTime. - IMGUI_API bool IsMouseReleased(int button); // did mouse button released (went from Down to !Down) - IMGUI_API bool IsMouseDragging(int button = 0, float lock_threshold = -1.0f); // is mouse dragging. if lock_threshold < -1.0f uses io.MouseDraggingThreshold - IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true); // is mouse hovering given bounding rect (in screen space). clipped by current clipping settings. disregarding of consideration of focus/window ordering/blocked by a popup. - IMGUI_API bool IsMousePosValid(const ImVec2* mouse_pos = NULL); // - IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls - IMGUI_API ImVec2 GetMousePosOnOpeningCurrentPopup(); // retrieve backup of mouse positioning at the time of opening popup we have BeginPopup() into - IMGUI_API ImVec2 GetMouseDragDelta(int button = 0, float lock_threshold = -1.0f); // dragging amount since clicking. if lock_threshold < -1.0f uses io.MouseDraggingThreshold - IMGUI_API void ResetMouseDragDelta(int button = 0); // - IMGUI_API ImGuiMouseCursor GetMouseCursor(); // get desired cursor type, reset in ImGui::NewFrame(), this is updated during the frame. valid before Render(). If you use software rendering by setting io.MouseDrawCursor ImGui will render those for you - IMGUI_API void SetMouseCursor(ImGuiMouseCursor type); // set desired cursor type - IMGUI_API void CaptureKeyboardFromApp(bool capture = true); // manually override io.WantCaptureKeyboard flag next frame (said flag is entirely left for your application handle). e.g. force capture keyboard when your widget is being hovered. - IMGUI_API void CaptureMouseFromApp(bool capture = true); // manually override io.WantCaptureMouse flag next frame (said flag is entirely left for your application handle). +// Inputs +IMGUI_API int GetKeyIndex(ImGuiKey imgui_key); // map ImGuiKey_* values into user's key index. == io.KeyMap[key] +IMGUI_API bool IsKeyDown(int user_key_index); // is key being held. == io.KeysDown[user_key_index]. note that imgui doesn't know the semantic of each entry of io.KeyDown[]. Use your own indices/enums according to how your backend/engine stored them into KeyDown[]! +IMGUI_API bool IsKeyPressed(int user_key_index, bool repeat = true); // was key pressed (went from !Down to Down). if repeat=true, uses io.KeyRepeatDelay / KeyRepeatRate +IMGUI_API bool IsKeyReleased(int user_key_index); // was key released (went from Down to !Down).. +IMGUI_API int GetKeyPressedAmount(int key_index, float repeat_delay, float rate); // uses provided repeat rate/delay. return a count, most often 0 or 1 but might be >1 if RepeatRate is small enough that DeltaTime > RepeatRate +IMGUI_API bool IsMouseDown(int button); // is mouse button held +IMGUI_API bool IsAnyMouseDown(); // is any mouse button held +IMGUI_API bool IsMouseClicked(int button, bool repeat = false); // did mouse button clicked (went from !Down to Down) +IMGUI_API bool IsMouseDoubleClicked(int button); // did mouse button double-clicked. a double-click returns false in IsMouseClicked(). uses io.MouseDoubleClickTime. +IMGUI_API bool IsMouseReleased(int button); // did mouse button released (went from Down to !Down) +IMGUI_API bool IsMouseDragging(int button = 0, float lock_threshold = -1.0f); // is mouse dragging. if lock_threshold < -1.0f uses io.MouseDraggingThreshold +IMGUI_API bool IsMouseHoveringRect(const ImVec2& r_min, const ImVec2& r_max, bool clip = true); // is mouse hovering given bounding rect (in screen space). clipped by current clipping settings. disregarding of consideration of focus/window ordering/blocked by a popup. +IMGUI_API bool IsMousePosValid(const ImVec2* mouse_pos = NULL); // +IMGUI_API ImVec2 GetMousePos(); // shortcut to ImGui::GetIO().MousePos provided by user, to be consistent with other calls +IMGUI_API ImVec2 GetMousePosOnOpeningCurrentPopup(); // retrieve backup of mouse positioning at the time of opening popup we have BeginPopup() into +IMGUI_API ImVec2 GetMouseDragDelta(int button = 0, float lock_threshold = -1.0f); // dragging amount since clicking. if lock_threshold < -1.0f uses io.MouseDraggingThreshold +IMGUI_API void ResetMouseDragDelta(int button = 0); // +IMGUI_API ImGuiMouseCursor GetMouseCursor(); // get desired cursor type, reset in ImGui::NewFrame(), this is updated during the frame. valid before Render(). If you use software rendering by setting io.MouseDrawCursor ImGui will render those for you +IMGUI_API void SetMouseCursor(ImGuiMouseCursor type); // set desired cursor type +IMGUI_API void CaptureKeyboardFromApp(bool capture = true); // manually override io.WantCaptureKeyboard flag next frame (said flag is entirely left for your application handle). e.g. force capture keyboard when your widget is being hovered. +IMGUI_API void CaptureMouseFromApp(bool capture = true); // manually override io.WantCaptureMouse flag next frame (said flag is entirely left for your application handle). - // Clipboard Utilities (also see the LogToClipboard() function to capture or output text data to the clipboard) - IMGUI_API const char* GetClipboardText(); - IMGUI_API void SetClipboardText(const char* text); +// Clipboard Utilities (also see the LogToClipboard() function to capture or output text data to the clipboard) +IMGUI_API const char* GetClipboardText(); +IMGUI_API void SetClipboardText(const char* text); - // Memory Utilities - // All those functions are not reliant on the current context. - // If you reload the contents of imgui.cpp at runtime, you may need to call SetCurrentContext() + SetAllocatorFunctions() again. - IMGUI_API void SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void(*free_func)(void* ptr, void* user_data), void* user_data = NULL); - IMGUI_API void* MemAlloc(size_t size); - IMGUI_API void MemFree(void* ptr); +// Memory Utilities +// All those functions are not reliant on the current context. +// If you reload the contents of imgui.cpp at runtime, you may need to call SetCurrentContext() + SetAllocatorFunctions() again. +IMGUI_API void SetAllocatorFunctions(void* (*alloc_func)(size_t sz, void* user_data), void (*free_func)(void* ptr, void* user_data), void* user_data = NULL); +IMGUI_API void* MemAlloc(size_t size); +IMGUI_API void MemFree(void* ptr); -} // namespace ImGui +} // namespace ImGui // Flags for ImGui::Begin() enum ImGuiWindowFlags_ { - ImGuiWindowFlags_NoTitleBar = 1 << 0, // Disable title-bar - ImGuiWindowFlags_NoResize = 1 << 1, // Disable user resizing with the lower-right grip - ImGuiWindowFlags_NoMove = 1 << 2, // Disable user moving the window - ImGuiWindowFlags_NoScrollbar = 1 << 3, // Disable scrollbars (window can still scroll with mouse or programatically) - ImGuiWindowFlags_NoScrollWithMouse = 1 << 4, // Disable user vertically scrolling with mouse wheel. On child window, mouse wheel will be forwarded to the parent unless NoScrollbar is also set. - ImGuiWindowFlags_NoCollapse = 1 << 5, // Disable user collapsing window by double-clicking on it - ImGuiWindowFlags_AlwaysAutoResize = 1 << 6, // Resize every window to its content every frame - //ImGuiWindowFlags_ShowBorders = 1 << 7, // Show borders around windows and items (OBSOLETE! Use e.g. style.FrameBorderSize=1.0f to enable borders). - ImGuiWindowFlags_NoSavedSettings = 1 << 8, // Never load/save settings in .ini file - ImGuiWindowFlags_NoInputs = 1 << 9, // Disable catching mouse or keyboard inputs, hovering test with pass through. - ImGuiWindowFlags_MenuBar = 1 << 10, // Has a menu-bar - ImGuiWindowFlags_HorizontalScrollbar = 1 << 11, // Allow horizontal scrollbar to appear (off by default). You may use SetNextWindowContentSize(ImVec2(width,0.0f)); prior to calling Begin() to specify width. Read code in imgui_demo in the "Horizontal Scrolling" section. - ImGuiWindowFlags_NoFocusOnAppearing = 1 << 12, // Disable taking focus when transitioning from hidden to visible state - ImGuiWindowFlags_NoBringToFrontOnFocus = 1 << 13, // Disable bringing window to front when taking focus (e.g. clicking on it or programatically giving it focus) - ImGuiWindowFlags_AlwaysVerticalScrollbar= 1 << 14, // Always show vertical scrollbar (even if ContentSize.y < Size.y) - ImGuiWindowFlags_AlwaysHorizontalScrollbar=1<< 15, // Always show horizontal scrollbar (even if ContentSize.x < Size.x) - ImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 16, // Ensure child windows without border uses style.WindowPadding (ignored by default for non-bordered child windows, because more convenient) - ImGuiWindowFlags_ResizeFromAnySide = 1 << 17, // (WIP) Enable resize from any corners and borders. Your back-end needs to honor the different values of io.MouseCursor set by imgui. - ImGuiWindowFlags_NoNavInputs = 1 << 18, // No gamepad/keyboard navigation within the window - ImGuiWindowFlags_NoNavFocus = 1 << 19, // No focusing toward this window with gamepad/keyboard navigation (e.g. skipped by CTRL+TAB) - ImGuiWindowFlags_NoNav = ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus, + ImGuiWindowFlags_NoTitleBar = 1 << 0, // Disable title-bar + ImGuiWindowFlags_NoResize = 1 << 1, // Disable user resizing with the lower-right grip + ImGuiWindowFlags_NoMove = 1 << 2, // Disable user moving the window + ImGuiWindowFlags_NoScrollbar = 1 << 3, // Disable scrollbars (window can still scroll with mouse or programatically) + ImGuiWindowFlags_NoScrollWithMouse = 1 << 4, // Disable user vertically scrolling with mouse wheel. On child window, mouse wheel will be forwarded to the parent unless NoScrollbar is also set. + ImGuiWindowFlags_NoCollapse = 1 << 5, // Disable user collapsing window by double-clicking on it + ImGuiWindowFlags_AlwaysAutoResize = 1 << 6, // Resize every window to its content every frame + //ImGuiWindowFlags_ShowBorders = 1 << 7, // Show borders around windows and items (OBSOLETE! Use e.g. style.FrameBorderSize=1.0f to enable borders). + ImGuiWindowFlags_NoSavedSettings = 1 << 8, // Never load/save settings in .ini file + ImGuiWindowFlags_NoInputs = 1 << 9, // Disable catching mouse or keyboard inputs, hovering test with pass through. + ImGuiWindowFlags_MenuBar = 1 << 10, // Has a menu-bar + ImGuiWindowFlags_HorizontalScrollbar = 1 << 11, // Allow horizontal scrollbar to appear (off by default). You may use SetNextWindowContentSize(ImVec2(width,0.0f)); prior to calling Begin() to specify width. Read code in imgui_demo in the "Horizontal Scrolling" section. + ImGuiWindowFlags_NoFocusOnAppearing = 1 << 12, // Disable taking focus when transitioning from hidden to visible state + ImGuiWindowFlags_NoBringToFrontOnFocus = 1 << 13, // Disable bringing window to front when taking focus (e.g. clicking on it or programatically giving it focus) + ImGuiWindowFlags_AlwaysVerticalScrollbar = 1 << 14, // Always show vertical scrollbar (even if ContentSize.y < Size.y) + ImGuiWindowFlags_AlwaysHorizontalScrollbar = 1 << 15, // Always show horizontal scrollbar (even if ContentSize.x < Size.x) + ImGuiWindowFlags_AlwaysUseWindowPadding = 1 << 16, // Ensure child windows without border uses style.WindowPadding (ignored by default for non-bordered child windows, because more convenient) + ImGuiWindowFlags_ResizeFromAnySide = 1 << 17, // (WIP) Enable resize from any corners and borders. Your back-end needs to honor the different values of io.MouseCursor set by imgui. + ImGuiWindowFlags_NoNavInputs = 1 << 18, // No gamepad/keyboard navigation within the window + ImGuiWindowFlags_NoNavFocus = 1 << 19, // No focusing toward this window with gamepad/keyboard navigation (e.g. skipped by CTRL+TAB) + ImGuiWindowFlags_NoNav = ImGuiWindowFlags_NoNavInputs | ImGuiWindowFlags_NoNavFocus, - // [Internal] - ImGuiWindowFlags_NavFlattened = 1 << 23, // (WIP) Allow gamepad/keyboard navigation to cross over parent border to this child (only use on child that have no scrolling!) - ImGuiWindowFlags_ChildWindow = 1 << 24, // Don't use! For internal use by BeginChild() - ImGuiWindowFlags_Tooltip = 1 << 25, // Don't use! For internal use by BeginTooltip() - ImGuiWindowFlags_Popup = 1 << 26, // Don't use! For internal use by BeginPopup() - ImGuiWindowFlags_Modal = 1 << 27, // Don't use! For internal use by BeginPopupModal() - ImGuiWindowFlags_ChildMenu = 1 << 28 // Don't use! For internal use by BeginMenu() + // [Internal] + ImGuiWindowFlags_NavFlattened = 1 << 23, // (WIP) Allow gamepad/keyboard navigation to cross over parent border to this child (only use on child that have no scrolling!) + ImGuiWindowFlags_ChildWindow = 1 << 24, // Don't use! For internal use by BeginChild() + ImGuiWindowFlags_Tooltip = 1 << 25, // Don't use! For internal use by BeginTooltip() + ImGuiWindowFlags_Popup = 1 << 26, // Don't use! For internal use by BeginPopup() + ImGuiWindowFlags_Modal = 1 << 27, // Don't use! For internal use by BeginPopupModal() + ImGuiWindowFlags_ChildMenu = 1 << 28 // Don't use! For internal use by BeginMenu() }; // Flags for ImGui::InputText() enum ImGuiInputTextFlags_ { - ImGuiInputTextFlags_CharsDecimal = 1 << 0, // Allow 0123456789.+-*/ - ImGuiInputTextFlags_CharsHexadecimal = 1 << 1, // Allow 0123456789ABCDEFabcdef - ImGuiInputTextFlags_CharsUppercase = 1 << 2, // Turn a..z into A..Z - ImGuiInputTextFlags_CharsNoBlank = 1 << 3, // Filter out spaces, tabs - ImGuiInputTextFlags_AutoSelectAll = 1 << 4, // Select entire text when first taking mouse focus - ImGuiInputTextFlags_EnterReturnsTrue = 1 << 5, // Return 'true' when Enter is pressed (as opposed to when the value was modified) - ImGuiInputTextFlags_CallbackCompletion = 1 << 6, // Call user function on pressing TAB (for completion handling) - ImGuiInputTextFlags_CallbackHistory = 1 << 7, // Call user function on pressing Up/Down arrows (for history handling) - ImGuiInputTextFlags_CallbackAlways = 1 << 8, // Call user function every time. User code may query cursor position, modify text buffer. - ImGuiInputTextFlags_CallbackCharFilter = 1 << 9, // Call user function to filter character. Modify data->EventChar to replace/filter input, or return 1 to discard character. - ImGuiInputTextFlags_AllowTabInput = 1 << 10, // Pressing TAB input a '\t' character into the text field - ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 11, // In multi-line mode, unfocus with Enter, add new line with Ctrl+Enter (default is opposite: unfocus with Ctrl+Enter, add line with Enter). - ImGuiInputTextFlags_NoHorizontalScroll = 1 << 12, // Disable following the cursor horizontally - ImGuiInputTextFlags_AlwaysInsertMode = 1 << 13, // Insert mode - ImGuiInputTextFlags_ReadOnly = 1 << 14, // Read-only mode - ImGuiInputTextFlags_Password = 1 << 15, // Password mode, display all characters as '*' - ImGuiInputTextFlags_NoUndoRedo = 1 << 16, // Disable undo/redo. Note that input text owns the text data while active, if you want to provide your own undo/redo stack you need e.g. to call ClearActiveID(). - // [Internal] - ImGuiInputTextFlags_Multiline = 1 << 20 // For internal use by InputTextMultiline() + ImGuiInputTextFlags_CharsDecimal = 1 << 0, // Allow 0123456789.+-*/ + ImGuiInputTextFlags_CharsHexadecimal = 1 << 1, // Allow 0123456789ABCDEFabcdef + ImGuiInputTextFlags_CharsUppercase = 1 << 2, // Turn a..z into A..Z + ImGuiInputTextFlags_CharsNoBlank = 1 << 3, // Filter out spaces, tabs + ImGuiInputTextFlags_AutoSelectAll = 1 << 4, // Select entire text when first taking mouse focus + ImGuiInputTextFlags_EnterReturnsTrue = 1 << 5, // Return 'true' when Enter is pressed (as opposed to when the value was modified) + ImGuiInputTextFlags_CallbackCompletion = 1 << 6, // Call user function on pressing TAB (for completion handling) + ImGuiInputTextFlags_CallbackHistory = 1 << 7, // Call user function on pressing Up/Down arrows (for history handling) + ImGuiInputTextFlags_CallbackAlways = 1 << 8, // Call user function every time. User code may query cursor position, modify text buffer. + ImGuiInputTextFlags_CallbackCharFilter = 1 << 9, // Call user function to filter character. Modify data->EventChar to replace/filter input, or return 1 to discard character. + ImGuiInputTextFlags_AllowTabInput = 1 << 10, // Pressing TAB input a '\t' character into the text field + ImGuiInputTextFlags_CtrlEnterForNewLine = 1 << 11, // In multi-line mode, unfocus with Enter, add new line with Ctrl+Enter (default is opposite: unfocus with Ctrl+Enter, add line with Enter). + ImGuiInputTextFlags_NoHorizontalScroll = 1 << 12, // Disable following the cursor horizontally + ImGuiInputTextFlags_AlwaysInsertMode = 1 << 13, // Insert mode + ImGuiInputTextFlags_ReadOnly = 1 << 14, // Read-only mode + ImGuiInputTextFlags_Password = 1 << 15, // Password mode, display all characters as '*' + ImGuiInputTextFlags_NoUndoRedo = 1 << 16, // Disable undo/redo. Note that input text owns the text data while active, if you want to provide your own undo/redo stack you need e.g. to call ClearActiveID(). + // [Internal] + ImGuiInputTextFlags_Multiline = 1 << 20 // For internal use by InputTextMultiline() }; // Flags for ImGui::TreeNodeEx(), ImGui::CollapsingHeader*() enum ImGuiTreeNodeFlags_ { - ImGuiTreeNodeFlags_Selected = 1 << 0, // Draw as selected - ImGuiTreeNodeFlags_Framed = 1 << 1, // Full colored frame (e.g. for CollapsingHeader) - ImGuiTreeNodeFlags_AllowItemOverlap = 1 << 2, // Hit testing to allow subsequent widgets to overlap this one - ImGuiTreeNodeFlags_NoTreePushOnOpen = 1 << 3, // Don't do a TreePush() when open (e.g. for CollapsingHeader) = no extra indent nor pushing on ID stack - ImGuiTreeNodeFlags_NoAutoOpenOnLog = 1 << 4, // Don't automatically and temporarily open node when Logging is active (by default logging will automatically open tree nodes) - ImGuiTreeNodeFlags_DefaultOpen = 1 << 5, // Default node to be open - ImGuiTreeNodeFlags_OpenOnDoubleClick = 1 << 6, // Need double-click to open node - ImGuiTreeNodeFlags_OpenOnArrow = 1 << 7, // Only open when clicking on the arrow part. If ImGuiTreeNodeFlags_OpenOnDoubleClick is also set, single-click arrow or double-click all box to open. - ImGuiTreeNodeFlags_Leaf = 1 << 8, // No collapsing, no arrow (use as a convenience for leaf nodes). - ImGuiTreeNodeFlags_Bullet = 1 << 9, // Display a bullet instead of arrow - ImGuiTreeNodeFlags_FramePadding = 1 << 10, // Use FramePadding (even for an unframed text node) to vertically align text baseline to regular widget height. Equivalent to calling AlignTextToFramePadding(). - //ImGuITreeNodeFlags_SpanAllAvailWidth = 1 << 11, // FIXME: TODO: Extend hit box horizontally even if not framed - //ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 12, // FIXME: TODO: Disable automatic scroll on TreePop() if node got just open and contents is not visible - ImGuiTreeNodeFlags_NavCloseFromChild = 1 << 13, // (WIP) Nav: left direction may close this TreeNode() when focusing on any child (items submitted between TreeNode and TreePop) - ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoAutoOpenOnLog + ImGuiTreeNodeFlags_Selected = 1 << 0, // Draw as selected + ImGuiTreeNodeFlags_Framed = 1 << 1, // Full colored frame (e.g. for CollapsingHeader) + ImGuiTreeNodeFlags_AllowItemOverlap = 1 << 2, // Hit testing to allow subsequent widgets to overlap this one + ImGuiTreeNodeFlags_NoTreePushOnOpen = 1 << 3, // Don't do a TreePush() when open (e.g. for CollapsingHeader) = no extra indent nor pushing on ID stack + ImGuiTreeNodeFlags_NoAutoOpenOnLog = 1 << 4, // Don't automatically and temporarily open node when Logging is active (by default logging will automatically open tree nodes) + ImGuiTreeNodeFlags_DefaultOpen = 1 << 5, // Default node to be open + ImGuiTreeNodeFlags_OpenOnDoubleClick = 1 << 6, // Need double-click to open node + ImGuiTreeNodeFlags_OpenOnArrow = 1 << 7, // Only open when clicking on the arrow part. If ImGuiTreeNodeFlags_OpenOnDoubleClick is also set, single-click arrow or double-click all box to open. + ImGuiTreeNodeFlags_Leaf = 1 << 8, // No collapsing, no arrow (use as a convenience for leaf nodes). + ImGuiTreeNodeFlags_Bullet = 1 << 9, // Display a bullet instead of arrow + ImGuiTreeNodeFlags_FramePadding = 1 << 10, // Use FramePadding (even for an unframed text node) to vertically align text baseline to regular widget height. Equivalent to calling AlignTextToFramePadding(). + //ImGuITreeNodeFlags_SpanAllAvailWidth = 1 << 11, // FIXME: TODO: Extend hit box horizontally even if not framed + //ImGuiTreeNodeFlags_NoScrollOnOpen = 1 << 12, // FIXME: TODO: Disable automatic scroll on TreePop() if node got just open and contents is not visible + ImGuiTreeNodeFlags_NavCloseFromChild = 1 << 13, // (WIP) Nav: left direction may close this TreeNode() when focusing on any child (items submitted between TreeNode and TreePop) + ImGuiTreeNodeFlags_CollapsingHeader = ImGuiTreeNodeFlags_Framed | ImGuiTreeNodeFlags_NoAutoOpenOnLog - // Obsolete names (will be removed) +// Obsolete names (will be removed) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - , ImGuiTreeNodeFlags_AllowOverlapMode = ImGuiTreeNodeFlags_AllowItemOverlap + , + ImGuiTreeNodeFlags_AllowOverlapMode = ImGuiTreeNodeFlags_AllowItemOverlap #endif }; // Flags for ImGui::Selectable() enum ImGuiSelectableFlags_ { - ImGuiSelectableFlags_DontClosePopups = 1 << 0, // Clicking this don't close parent popup window - ImGuiSelectableFlags_SpanAllColumns = 1 << 1, // Selectable frame can span all columns (text will still fit in current column) - ImGuiSelectableFlags_AllowDoubleClick = 1 << 2 // Generate press events on double clicks too + ImGuiSelectableFlags_DontClosePopups = 1 << 0, // Clicking this don't close parent popup window + ImGuiSelectableFlags_SpanAllColumns = 1 << 1, // Selectable frame can span all columns (text will still fit in current column) + ImGuiSelectableFlags_AllowDoubleClick = 1 << 2 // Generate press events on double clicks too }; // Flags for ImGui::BeginCombo() enum ImGuiComboFlags_ { - ImGuiComboFlags_PopupAlignLeft = 1 << 0, // Align the popup toward the left by default - ImGuiComboFlags_HeightSmall = 1 << 1, // Max ~4 items visible. Tip: If you want your combo popup to be a specific size you can use SetNextWindowSizeConstraints() prior to calling BeginCombo() - ImGuiComboFlags_HeightRegular = 1 << 2, // Max ~8 items visible (default) - ImGuiComboFlags_HeightLarge = 1 << 3, // Max ~20 items visible - ImGuiComboFlags_HeightLargest = 1 << 4, // As many fitting items as possible - ImGuiComboFlags_HeightMask_ = ImGuiComboFlags_HeightSmall | ImGuiComboFlags_HeightRegular | ImGuiComboFlags_HeightLarge | ImGuiComboFlags_HeightLargest + ImGuiComboFlags_PopupAlignLeft = 1 << 0, // Align the popup toward the left by default + ImGuiComboFlags_HeightSmall = 1 << 1, // Max ~4 items visible. Tip: If you want your combo popup to be a specific size you can use SetNextWindowSizeConstraints() prior to calling BeginCombo() + ImGuiComboFlags_HeightRegular = 1 << 2, // Max ~8 items visible (default) + ImGuiComboFlags_HeightLarge = 1 << 3, // Max ~20 items visible + ImGuiComboFlags_HeightLargest = 1 << 4, // As many fitting items as possible + ImGuiComboFlags_HeightMask_ = ImGuiComboFlags_HeightSmall | ImGuiComboFlags_HeightRegular | ImGuiComboFlags_HeightLarge | ImGuiComboFlags_HeightLargest }; // Flags for ImGui::IsWindowFocused() enum ImGuiFocusedFlags_ { - ImGuiFocusedFlags_ChildWindows = 1 << 0, // IsWindowFocused(): Return true if any children of the window is focused - ImGuiFocusedFlags_RootWindow = 1 << 1, // IsWindowFocused(): Test from root window (top most parent of the current hierarchy) - ImGuiFocusedFlags_AnyWindow = 1 << 2, // IsWindowFocused(): Return true if any window is focused - ImGuiFocusedFlags_RootAndChildWindows = ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows + ImGuiFocusedFlags_ChildWindows = 1 << 0, // IsWindowFocused(): Return true if any children of the window is focused + ImGuiFocusedFlags_RootWindow = 1 << 1, // IsWindowFocused(): Test from root window (top most parent of the current hierarchy) + ImGuiFocusedFlags_AnyWindow = 1 << 2, // IsWindowFocused(): Return true if any window is focused + ImGuiFocusedFlags_RootAndChildWindows = ImGuiFocusedFlags_RootWindow | ImGuiFocusedFlags_ChildWindows }; // Flags for ImGui::IsItemHovered(), ImGui::IsWindowHovered() enum ImGuiHoveredFlags_ { - ImGuiHoveredFlags_Default = 0, // Return true if directly over the item/window, not obstructed by another window, not obstructed by an active popup or modal blocking inputs under them. - ImGuiHoveredFlags_ChildWindows = 1 << 0, // IsWindowHovered() only: Return true if any children of the window is hovered - ImGuiHoveredFlags_RootWindow = 1 << 1, // IsWindowHovered() only: Test from root window (top most parent of the current hierarchy) - ImGuiHoveredFlags_AnyWindow = 1 << 2, // IsWindowHovered() only: Return true if any window is hovered - ImGuiHoveredFlags_AllowWhenBlockedByPopup = 1 << 3, // Return true even if a popup window is normally blocking access to this item/window - //ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 4, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet. - ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 5, // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns. - ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 6, // Return true even if the position is overlapped by another window - ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped, - ImGuiHoveredFlags_RootAndChildWindows = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows + ImGuiHoveredFlags_Default = 0, // Return true if directly over the item/window, not obstructed by another window, not obstructed by an active popup or modal blocking inputs under them. + ImGuiHoveredFlags_ChildWindows = 1 << 0, // IsWindowHovered() only: Return true if any children of the window is hovered + ImGuiHoveredFlags_RootWindow = 1 << 1, // IsWindowHovered() only: Test from root window (top most parent of the current hierarchy) + ImGuiHoveredFlags_AnyWindow = 1 << 2, // IsWindowHovered() only: Return true if any window is hovered + ImGuiHoveredFlags_AllowWhenBlockedByPopup = 1 << 3, // Return true even if a popup window is normally blocking access to this item/window + //ImGuiHoveredFlags_AllowWhenBlockedByModal = 1 << 4, // Return true even if a modal popup window is normally blocking access to this item/window. FIXME-TODO: Unavailable yet. + ImGuiHoveredFlags_AllowWhenBlockedByActiveItem = 1 << 5, // Return true even if an active item is blocking access to this item/window. Useful for Drag and Drop patterns. + ImGuiHoveredFlags_AllowWhenOverlapped = 1 << 6, // Return true even if the position is overlapped by another window + ImGuiHoveredFlags_RectOnly = ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem | ImGuiHoveredFlags_AllowWhenOverlapped, + ImGuiHoveredFlags_RootAndChildWindows = ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows }; // Flags for ImGui::BeginDragDropSource(), ImGui::AcceptDragDropPayload() enum ImGuiDragDropFlags_ { - // BeginDragDropSource() flags - ImGuiDragDropFlags_SourceNoPreviewTooltip = 1 << 0, // By default, a successful call to BeginDragDropSource opens a tooltip so you can display a preview or description of the source contents. This flag disable this behavior. - ImGuiDragDropFlags_SourceNoDisableHover = 1 << 1, // By default, when dragging we clear data so that IsItemHovered() will return true, to avoid subsequent user code submitting tooltips. This flag disable this behavior so you can still call IsItemHovered() on the source item. - ImGuiDragDropFlags_SourceNoHoldToOpenOthers = 1 << 2, // Disable the behavior that allows to open tree nodes and collapsing header by holding over them while dragging a source item. - ImGuiDragDropFlags_SourceAllowNullID = 1 << 3, // Allow items such as Text(), Image() that have no unique identifier to be used as drag source, by manufacturing a temporary identifier based on their window-relative position. This is extremely unusual within the dear imgui ecosystem and so we made it explicit. - ImGuiDragDropFlags_SourceExtern = 1 << 4, // External source (from outside of imgui), won't attempt to read current item/window info. Will always return true. Only one Extern source can be active simultaneously. - // AcceptDragDropPayload() flags - ImGuiDragDropFlags_AcceptBeforeDelivery = 1 << 10, // AcceptDragDropPayload() will returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered. - ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 1 << 11, // Do not draw the default highlight rectangle when hovering over target. - ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect // For peeking ahead and inspecting the payload before delivery. + // BeginDragDropSource() flags + ImGuiDragDropFlags_SourceNoPreviewTooltip = 1 << 0, // By default, a successful call to BeginDragDropSource opens a tooltip so you can display a preview or description of the source contents. This flag disable this behavior. + ImGuiDragDropFlags_SourceNoDisableHover = 1 << 1, // By default, when dragging we clear data so that IsItemHovered() will return true, to avoid subsequent user code submitting tooltips. This flag disable this behavior so you can still call IsItemHovered() on the source item. + ImGuiDragDropFlags_SourceNoHoldToOpenOthers = 1 << 2, // Disable the behavior that allows to open tree nodes and collapsing header by holding over them while dragging a source item. + ImGuiDragDropFlags_SourceAllowNullID = 1 << 3, // Allow items such as Text(), Image() that have no unique identifier to be used as drag source, by manufacturing a temporary identifier based on their window-relative position. This is extremely unusual within the dear imgui ecosystem and so we made it explicit. + ImGuiDragDropFlags_SourceExtern = 1 << 4, // External source (from outside of imgui), won't attempt to read current item/window info. Will always return true. Only one Extern source can be active simultaneously. + // AcceptDragDropPayload() flags + ImGuiDragDropFlags_AcceptBeforeDelivery = 1 << 10, // AcceptDragDropPayload() will returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered. + ImGuiDragDropFlags_AcceptNoDrawDefaultRect = 1 << 11, // Do not draw the default highlight rectangle when hovering over target. + ImGuiDragDropFlags_AcceptPeekOnly = ImGuiDragDropFlags_AcceptBeforeDelivery | ImGuiDragDropFlags_AcceptNoDrawDefaultRect // For peeking ahead and inspecting the payload before delivery. }; // Standard Drag and Drop payload types. You can define you own payload types using 12-characters long strings. Types starting with '_' are defined by Dear ImGui. -#define IMGUI_PAYLOAD_TYPE_COLOR_3F "_COL3F" // float[3] // Standard type for colors, without alpha. User code may use this type. -#define IMGUI_PAYLOAD_TYPE_COLOR_4F "_COL4F" // float[4] // Standard type for colors. User code may use this type. +#define IMGUI_PAYLOAD_TYPE_COLOR_3F "_COL3F" // float[3] // Standard type for colors, without alpha. User code may use this type. +#define IMGUI_PAYLOAD_TYPE_COLOR_4F "_COL4F" // float[4] // Standard type for colors. User code may use this type. // User fill ImGuiIO.KeyMap[] array with indices into the ImGuiIO.KeysDown[512] array enum ImGuiKey_ { - ImGuiKey_Tab, - ImGuiKey_LeftArrow, - ImGuiKey_RightArrow, - ImGuiKey_UpArrow, - ImGuiKey_DownArrow, - ImGuiKey_PageUp, - ImGuiKey_PageDown, - ImGuiKey_Home, - ImGuiKey_End, - ImGuiKey_Insert, - ImGuiKey_Delete, - ImGuiKey_Backspace, - ImGuiKey_Space, - ImGuiKey_Enter, - ImGuiKey_Escape, - ImGuiKey_A, // for text edit CTRL+A: select all - ImGuiKey_C, // for text edit CTRL+C: copy - ImGuiKey_V, // for text edit CTRL+V: paste - ImGuiKey_X, // for text edit CTRL+X: cut - ImGuiKey_Y, // for text edit CTRL+Y: redo - ImGuiKey_Z, // for text edit CTRL+Z: undo - ImGuiKey_COUNT + ImGuiKey_Tab, + ImGuiKey_LeftArrow, + ImGuiKey_RightArrow, + ImGuiKey_UpArrow, + ImGuiKey_DownArrow, + ImGuiKey_PageUp, + ImGuiKey_PageDown, + ImGuiKey_Home, + ImGuiKey_End, + ImGuiKey_Insert, + ImGuiKey_Delete, + ImGuiKey_Backspace, + ImGuiKey_Space, + ImGuiKey_Enter, + ImGuiKey_Escape, + ImGuiKey_A, // for text edit CTRL+A: select all + ImGuiKey_C, // for text edit CTRL+C: copy + ImGuiKey_V, // for text edit CTRL+V: paste + ImGuiKey_X, // for text edit CTRL+X: cut + ImGuiKey_Y, // for text edit CTRL+Y: redo + ImGuiKey_Z, // for text edit CTRL+Z: undo + ImGuiKey_COUNT }; // [BETA] Gamepad/Keyboard directional navigation @@ -715,98 +730,102 @@ enum ImGuiKey_ // Read instructions in imgui.cpp for more details. enum ImGuiNavInput_ { - // Gamepad Mapping - ImGuiNavInput_Activate, // activate / open / toggle / tweak value // e.g. Circle (PS4), A (Xbox), B (Switch), Space (Keyboard) - ImGuiNavInput_Cancel, // cancel / close / exit // e.g. Cross (PS4), B (Xbox), A (Switch), Escape (Keyboard) - ImGuiNavInput_Input, // text input / on-screen keyboard // e.g. Triang.(PS4), Y (Xbox), X (Switch), Return (Keyboard) - ImGuiNavInput_Menu, // tap: toggle menu / hold: focus, move, resize // e.g. Square (PS4), X (Xbox), Y (Switch), Alt (Keyboard) - ImGuiNavInput_DpadLeft, // move / tweak / resize window (w/ PadMenu) // e.g. D-pad Left/Right/Up/Down (Gamepads), Arrow keys (Keyboard) - ImGuiNavInput_DpadRight, // - ImGuiNavInput_DpadUp, // - ImGuiNavInput_DpadDown, // - ImGuiNavInput_LStickLeft, // scroll / move window (w/ PadMenu) // e.g. Left Analog Stick Left/Right/Up/Down - ImGuiNavInput_LStickRight, // - ImGuiNavInput_LStickUp, // - ImGuiNavInput_LStickDown, // - ImGuiNavInput_FocusPrev, // next window (w/ PadMenu) // e.g. L1 or L2 (PS4), LB or LT (Xbox), L or ZL (Switch) - ImGuiNavInput_FocusNext, // prev window (w/ PadMenu) // e.g. R1 or R2 (PS4), RB or RT (Xbox), R or ZL (Switch) - ImGuiNavInput_TweakSlow, // slower tweaks // e.g. L1 or L2 (PS4), LB or LT (Xbox), L or ZL (Switch) - ImGuiNavInput_TweakFast, // faster tweaks // e.g. R1 or R2 (PS4), RB or RT (Xbox), R or ZL (Switch) + // Gamepad Mapping + ImGuiNavInput_Activate, // activate / open / toggle / tweak value // e.g. Circle (PS4), A (Xbox), B (Switch), Space (Keyboard) + ImGuiNavInput_Cancel, // cancel / close / exit // e.g. Cross (PS4), B (Xbox), A (Switch), Escape (Keyboard) + ImGuiNavInput_Input, // text input / on-screen keyboard // e.g. Triang.(PS4), Y (Xbox), X (Switch), Return (Keyboard) + ImGuiNavInput_Menu, // tap: toggle menu / hold: focus, move, resize // e.g. Square (PS4), X (Xbox), Y (Switch), Alt (Keyboard) + ImGuiNavInput_DpadLeft, // move / tweak / resize window (w/ PadMenu) // e.g. D-pad Left/Right/Up/Down (Gamepads), Arrow keys (Keyboard) + ImGuiNavInput_DpadRight, // + ImGuiNavInput_DpadUp, // + ImGuiNavInput_DpadDown, // + ImGuiNavInput_LStickLeft, // scroll / move window (w/ PadMenu) // e.g. Left Analog Stick Left/Right/Up/Down + ImGuiNavInput_LStickRight, // + ImGuiNavInput_LStickUp, // + ImGuiNavInput_LStickDown, // + ImGuiNavInput_FocusPrev, // next window (w/ PadMenu) // e.g. L1 or L2 (PS4), LB or LT (Xbox), L or ZL (Switch) + ImGuiNavInput_FocusNext, // prev window (w/ PadMenu) // e.g. R1 or R2 (PS4), RB or RT (Xbox), R or ZL (Switch) + ImGuiNavInput_TweakSlow, // slower tweaks // e.g. L1 or L2 (PS4), LB or LT (Xbox), L or ZL (Switch) + ImGuiNavInput_TweakFast, // faster tweaks // e.g. R1 or R2 (PS4), RB or RT (Xbox), R or ZL (Switch) - // [Internal] Don't use directly! This is used internally to differentiate keyboard from gamepad inputs for behaviors that require to differentiate them. - // Keyboard behavior that have no corresponding gamepad mapping (e.g. CTRL+TAB) may be directly reading from io.KeyDown[] instead of io.NavInputs[]. - ImGuiNavInput_KeyMenu_, // toggle menu // = io.KeyAlt - ImGuiNavInput_KeyLeft_, // move left // = Arrow keys - ImGuiNavInput_KeyRight_, // move right - ImGuiNavInput_KeyUp_, // move up - ImGuiNavInput_KeyDown_, // move down - ImGuiNavInput_COUNT, - ImGuiNavInput_InternalStart_ = ImGuiNavInput_KeyMenu_ + // [Internal] Don't use directly! This is used internally to differentiate keyboard from gamepad inputs for behaviors that require to differentiate them. + // Keyboard behavior that have no corresponding gamepad mapping (e.g. CTRL+TAB) may be directly reading from io.KeyDown[] instead of io.NavInputs[]. + ImGuiNavInput_KeyMenu_, // toggle menu // = io.KeyAlt + ImGuiNavInput_KeyLeft_, // move left // = Arrow keys + ImGuiNavInput_KeyRight_, // move right + ImGuiNavInput_KeyUp_, // move up + ImGuiNavInput_KeyDown_, // move down + ImGuiNavInput_COUNT, + ImGuiNavInput_InternalStart_ = ImGuiNavInput_KeyMenu_ }; // [BETA] Gamepad/Keyboard directional navigation flags, stored in io.NavFlags enum ImGuiNavFlags_ { - ImGuiNavFlags_EnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. NewFrame() will automatically fill io.NavInputs[] based on io.KeyDown[]. - ImGuiNavFlags_EnableGamepad = 1 << 1, // Master gamepad navigation enable flag. This is mostly to instruct your imgui back-end to fill io.NavInputs[]. - ImGuiNavFlags_MoveMouse = 1 << 2, // Request navigation to allow moving the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is awkward. Will update io.MousePos and set io.WantMoveMouse=true. If enabled you MUST honor io.WantMoveMouse requests in your binding, otherwise ImGui will react as if the mouse is jumping around back and forth. - ImGuiNavFlags_NoCaptureKeyboard = 1 << 3 // Do not set the io.WantCaptureKeyboard flag with io.NavActive is set. + ImGuiNavFlags_EnableKeyboard = 1 << 0, // Master keyboard navigation enable flag. NewFrame() will automatically fill io.NavInputs[] based on io.KeyDown[]. + ImGuiNavFlags_EnableGamepad = 1 << 1, // Master gamepad navigation enable flag. This is mostly to instruct your imgui back-end to fill io.NavInputs[]. + ImGuiNavFlags_MoveMouse = 1 << 2, // Request navigation to allow moving the mouse cursor. May be useful on TV/console systems where moving a virtual mouse is awkward. Will update io.MousePos and set io.WantMoveMouse=true. If enabled you MUST honor io.WantMoveMouse requests in your binding, otherwise ImGui will react as if the mouse is jumping around back and forth. + ImGuiNavFlags_NoCaptureKeyboard = 1 << 3 // Do not set the io.WantCaptureKeyboard flag with io.NavActive is set. }; // Enumeration for PushStyleColor() / PopStyleColor() enum ImGuiCol_ { - ImGuiCol_Text, - ImGuiCol_TextDisabled, - ImGuiCol_WindowBg, // Background of normal windows - ImGuiCol_ChildBg, // Background of child windows - ImGuiCol_PopupBg, // Background of popups, menus, tooltips windows - ImGuiCol_Border, - ImGuiCol_BorderShadow, - ImGuiCol_FrameBg, // Background of checkbox, radio button, plot, slider, text input - ImGuiCol_FrameBgHovered, - ImGuiCol_FrameBgActive, - ImGuiCol_TitleBg, - ImGuiCol_TitleBgActive, - ImGuiCol_TitleBgCollapsed, - ImGuiCol_MenuBarBg, - ImGuiCol_ScrollbarBg, - ImGuiCol_ScrollbarGrab, - ImGuiCol_ScrollbarGrabHovered, - ImGuiCol_ScrollbarGrabActive, - ImGuiCol_CheckMark, - ImGuiCol_SliderGrab, - ImGuiCol_SliderGrabActive, - ImGuiCol_Button, - ImGuiCol_ButtonHovered, - ImGuiCol_ButtonActive, - ImGuiCol_Header, - ImGuiCol_HeaderHovered, - ImGuiCol_HeaderActive, - ImGuiCol_Separator, - ImGuiCol_SeparatorHovered, - ImGuiCol_SeparatorActive, - ImGuiCol_ResizeGrip, - ImGuiCol_ResizeGripHovered, - ImGuiCol_ResizeGripActive, - ImGuiCol_CloseButton, - ImGuiCol_CloseButtonHovered, - ImGuiCol_CloseButtonActive, - ImGuiCol_PlotLines, - ImGuiCol_PlotLinesHovered, - ImGuiCol_PlotHistogram, - ImGuiCol_PlotHistogramHovered, - ImGuiCol_TextSelectedBg, - ImGuiCol_ModalWindowDarkening, // darken entire screen when a modal window is active - ImGuiCol_DragDropTarget, - ImGuiCol_NavHighlight, // gamepad/keyboard: current highlighted item - ImGuiCol_NavWindowingHighlight, // gamepad/keyboard: when holding NavMenu to focus/move/resize windows - ImGuiCol_COUNT + ImGuiCol_Text, + ImGuiCol_TextDisabled, + ImGuiCol_WindowBg, // Background of normal windows + ImGuiCol_ChildBg, // Background of child windows + ImGuiCol_PopupBg, // Background of popups, menus, tooltips windows + ImGuiCol_Border, + ImGuiCol_BorderShadow, + ImGuiCol_FrameBg, // Background of checkbox, radio button, plot, slider, text input + ImGuiCol_FrameBgHovered, + ImGuiCol_FrameBgActive, + ImGuiCol_TitleBg, + ImGuiCol_TitleBgActive, + ImGuiCol_TitleBgCollapsed, + ImGuiCol_MenuBarBg, + ImGuiCol_ScrollbarBg, + ImGuiCol_ScrollbarGrab, + ImGuiCol_ScrollbarGrabHovered, + ImGuiCol_ScrollbarGrabActive, + ImGuiCol_CheckMark, + ImGuiCol_SliderGrab, + ImGuiCol_SliderGrabActive, + ImGuiCol_Button, + ImGuiCol_ButtonHovered, + ImGuiCol_ButtonActive, + ImGuiCol_Header, + ImGuiCol_HeaderHovered, + ImGuiCol_HeaderActive, + ImGuiCol_Separator, + ImGuiCol_SeparatorHovered, + ImGuiCol_SeparatorActive, + ImGuiCol_ResizeGrip, + ImGuiCol_ResizeGripHovered, + ImGuiCol_ResizeGripActive, + ImGuiCol_CloseButton, + ImGuiCol_CloseButtonHovered, + ImGuiCol_CloseButtonActive, + ImGuiCol_PlotLines, + ImGuiCol_PlotLinesHovered, + ImGuiCol_PlotHistogram, + ImGuiCol_PlotHistogramHovered, + ImGuiCol_TextSelectedBg, + ImGuiCol_ModalWindowDarkening, // darken entire screen when a modal window is active + ImGuiCol_DragDropTarget, + ImGuiCol_NavHighlight, // gamepad/keyboard: current highlighted item + ImGuiCol_NavWindowingHighlight, // gamepad/keyboard: when holding NavMenu to focus/move/resize windows + ImGuiCol_COUNT - // Obsolete names (will be removed) +// Obsolete names (will be removed) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - //, ImGuiCol_ComboBg = ImGuiCol_PopupBg // ComboBg has been merged with PopupBg, so a redirect isn't accurate. - , ImGuiCol_ChildWindowBg = ImGuiCol_ChildBg, ImGuiCol_Column = ImGuiCol_Separator, ImGuiCol_ColumnHovered = ImGuiCol_SeparatorHovered, ImGuiCol_ColumnActive = ImGuiCol_SeparatorActive + //, ImGuiCol_ComboBg = ImGuiCol_PopupBg // ComboBg has been merged with PopupBg, so a redirect isn't accurate. + , + ImGuiCol_ChildWindowBg = ImGuiCol_ChildBg, + ImGuiCol_Column = ImGuiCol_Separator, + ImGuiCol_ColumnHovered = ImGuiCol_SeparatorHovered, + ImGuiCol_ColumnActive = ImGuiCol_SeparatorActive #endif }; @@ -815,92 +834,97 @@ enum ImGuiCol_ // NB: if changing this enum, you need to update the associated internal table GStyleVarInfo[] accordingly. This is where we link enum values to members offset/type. enum ImGuiStyleVar_ { - // Enum name ......................// Member in ImGuiStyle structure (see ImGuiStyle for descriptions) - ImGuiStyleVar_Alpha, // float Alpha - ImGuiStyleVar_WindowPadding, // ImVec2 WindowPadding - ImGuiStyleVar_WindowRounding, // float WindowRounding - ImGuiStyleVar_WindowBorderSize, // float WindowBorderSize - ImGuiStyleVar_WindowMinSize, // ImVec2 WindowMinSize - ImGuiStyleVar_WindowTitleAlign, // ImVec2 WindowTitleAlign - ImGuiStyleVar_ChildRounding, // float ChildRounding - ImGuiStyleVar_ChildBorderSize, // float ChildBorderSize - ImGuiStyleVar_PopupRounding, // float PopupRounding - ImGuiStyleVar_PopupBorderSize, // float PopupBorderSize - ImGuiStyleVar_FramePadding, // ImVec2 FramePadding - ImGuiStyleVar_FrameRounding, // float FrameRounding - ImGuiStyleVar_FrameBorderSize, // float FrameBorderSize - ImGuiStyleVar_ItemSpacing, // ImVec2 ItemSpacing - ImGuiStyleVar_ItemInnerSpacing, // ImVec2 ItemInnerSpacing - ImGuiStyleVar_IndentSpacing, // float IndentSpacing - ImGuiStyleVar_ScrollbarSize, // float ScrollbarSize - ImGuiStyleVar_ScrollbarRounding, // float ScrollbarRounding - ImGuiStyleVar_GrabMinSize, // float GrabMinSize - ImGuiStyleVar_GrabRounding, // float GrabRounding - ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign - ImGuiStyleVar_Count_ + // Enum name ......................// Member in ImGuiStyle structure (see ImGuiStyle for descriptions) + ImGuiStyleVar_Alpha, // float Alpha + ImGuiStyleVar_WindowPadding, // ImVec2 WindowPadding + ImGuiStyleVar_WindowRounding, // float WindowRounding + ImGuiStyleVar_WindowBorderSize, // float WindowBorderSize + ImGuiStyleVar_WindowMinSize, // ImVec2 WindowMinSize + ImGuiStyleVar_WindowTitleAlign, // ImVec2 WindowTitleAlign + ImGuiStyleVar_ChildRounding, // float ChildRounding + ImGuiStyleVar_ChildBorderSize, // float ChildBorderSize + ImGuiStyleVar_PopupRounding, // float PopupRounding + ImGuiStyleVar_PopupBorderSize, // float PopupBorderSize + ImGuiStyleVar_FramePadding, // ImVec2 FramePadding + ImGuiStyleVar_FrameRounding, // float FrameRounding + ImGuiStyleVar_FrameBorderSize, // float FrameBorderSize + ImGuiStyleVar_ItemSpacing, // ImVec2 ItemSpacing + ImGuiStyleVar_ItemInnerSpacing, // ImVec2 ItemInnerSpacing + ImGuiStyleVar_IndentSpacing, // float IndentSpacing + ImGuiStyleVar_ScrollbarSize, // float ScrollbarSize + ImGuiStyleVar_ScrollbarRounding, // float ScrollbarRounding + ImGuiStyleVar_GrabMinSize, // float GrabMinSize + ImGuiStyleVar_GrabRounding, // float GrabRounding + ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign + ImGuiStyleVar_Count_ - // Obsolete names (will be removed) +// Obsolete names (will be removed) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - , ImGuiStyleVar_ChildWindowRounding = ImGuiStyleVar_ChildRounding + , + ImGuiStyleVar_ChildWindowRounding = ImGuiStyleVar_ChildRounding #endif }; // Enumeration for ColorEdit3() / ColorEdit4() / ColorPicker3() / ColorPicker4() / ColorButton() enum ImGuiColorEditFlags_ { - ImGuiColorEditFlags_NoAlpha = 1 << 1, // // ColorEdit, ColorPicker, ColorButton: ignore Alpha component (read 3 components from the input pointer). - ImGuiColorEditFlags_NoPicker = 1 << 2, // // ColorEdit: disable picker when clicking on colored square. - ImGuiColorEditFlags_NoOptions = 1 << 3, // // ColorEdit: disable toggling options menu when right-clicking on inputs/small preview. - ImGuiColorEditFlags_NoSmallPreview = 1 << 4, // // ColorEdit, ColorPicker: disable colored square preview next to the inputs. (e.g. to show only the inputs) - ImGuiColorEditFlags_NoInputs = 1 << 5, // // ColorEdit, ColorPicker: disable inputs sliders/text widgets (e.g. to show only the small preview colored square). - ImGuiColorEditFlags_NoTooltip = 1 << 6, // // ColorEdit, ColorPicker, ColorButton: disable tooltip when hovering the preview. - ImGuiColorEditFlags_NoLabel = 1 << 7, // // ColorEdit, ColorPicker: disable display of inline text label (the label is still forwarded to the tooltip and picker). - ImGuiColorEditFlags_NoSidePreview = 1 << 8, // // ColorPicker: disable bigger color preview on right side of the picker, use small colored square preview instead. - // User Options (right-click on widget to change some of them). You can set application defaults using SetColorEditOptions(). The idea is that you probably don't want to override them in most of your calls, let the user choose and/or call SetColorEditOptions() during startup. - ImGuiColorEditFlags_AlphaBar = 1 << 9, // // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker. - ImGuiColorEditFlags_AlphaPreview = 1 << 10, // // ColorEdit, ColorPicker, ColorButton: display preview as a transparent color over a checkerboard, instead of opaque. - ImGuiColorEditFlags_AlphaPreviewHalf= 1 << 11, // // ColorEdit, ColorPicker, ColorButton: display half opaque / half checkerboard, instead of opaque. - ImGuiColorEditFlags_HDR = 1 << 12, // // (WIP) ColorEdit: Currently only disable 0.0f..1.0f limits in RGBA edition (note: you probably want to use ImGuiColorEditFlags_Float flag as well). - ImGuiColorEditFlags_RGB = 1 << 13, // [Inputs] // ColorEdit: choose one among RGB/HSV/HEX. ColorPicker: choose any combination using RGB/HSV/HEX. - ImGuiColorEditFlags_HSV = 1 << 14, // [Inputs] // " - ImGuiColorEditFlags_HEX = 1 << 15, // [Inputs] // " - ImGuiColorEditFlags_Uint8 = 1 << 16, // [DataType] // ColorEdit, ColorPicker, ColorButton: _display_ values formatted as 0..255. - ImGuiColorEditFlags_Float = 1 << 17, // [DataType] // ColorEdit, ColorPicker, ColorButton: _display_ values formatted as 0.0f..1.0f floats instead of 0..255 integers. No round-trip of value via integers. - ImGuiColorEditFlags_PickerHueBar = 1 << 18, // [PickerMode] // ColorPicker: bar for Hue, rectangle for Sat/Value. - ImGuiColorEditFlags_PickerHueWheel = 1 << 19, // [PickerMode] // ColorPicker: wheel for Hue, triangle for Sat/Value. - // Internals/Masks - ImGuiColorEditFlags__InputsMask = ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_HSV|ImGuiColorEditFlags_HEX, - ImGuiColorEditFlags__DataTypeMask = ImGuiColorEditFlags_Uint8|ImGuiColorEditFlags_Float, - ImGuiColorEditFlags__PickerMask = ImGuiColorEditFlags_PickerHueWheel|ImGuiColorEditFlags_PickerHueBar, - ImGuiColorEditFlags__OptionsDefault = ImGuiColorEditFlags_Uint8|ImGuiColorEditFlags_RGB|ImGuiColorEditFlags_PickerHueBar // Change application default using SetColorEditOptions() + ImGuiColorEditFlags_NoAlpha = 1 << 1, // // ColorEdit, ColorPicker, ColorButton: ignore Alpha component (read 3 components from the input pointer). + ImGuiColorEditFlags_NoPicker = 1 << 2, // // ColorEdit: disable picker when clicking on colored square. + ImGuiColorEditFlags_NoOptions = 1 << 3, // // ColorEdit: disable toggling options menu when right-clicking on inputs/small preview. + ImGuiColorEditFlags_NoSmallPreview = 1 << 4, // // ColorEdit, ColorPicker: disable colored square preview next to the inputs. (e.g. to show only the inputs) + ImGuiColorEditFlags_NoInputs = 1 << 5, // // ColorEdit, ColorPicker: disable inputs sliders/text widgets (e.g. to show only the small preview colored square). + ImGuiColorEditFlags_NoTooltip = 1 << 6, // // ColorEdit, ColorPicker, ColorButton: disable tooltip when hovering the preview. + ImGuiColorEditFlags_NoLabel = 1 << 7, // // ColorEdit, ColorPicker: disable display of inline text label (the label is still forwarded to the tooltip and picker). + ImGuiColorEditFlags_NoSidePreview = 1 << 8, // // ColorPicker: disable bigger color preview on right side of the picker, use small colored square preview instead. + // User Options (right-click on widget to change some of them). You can set application defaults using SetColorEditOptions(). The idea is that you probably don't want to override them in most of your calls, let the user choose and/or call SetColorEditOptions() during startup. + ImGuiColorEditFlags_AlphaBar = 1 << 9, // // ColorEdit, ColorPicker: show vertical alpha bar/gradient in picker. + ImGuiColorEditFlags_AlphaPreview = 1 << 10, // // ColorEdit, ColorPicker, ColorButton: display preview as a transparent color over a checkerboard, instead of opaque. + ImGuiColorEditFlags_AlphaPreviewHalf = 1 << 11, // // ColorEdit, ColorPicker, ColorButton: display half opaque / half checkerboard, instead of opaque. + ImGuiColorEditFlags_HDR = 1 << 12, // // (WIP) ColorEdit: Currently only disable 0.0f..1.0f limits in RGBA edition (note: you probably want to use ImGuiColorEditFlags_Float flag as well). + ImGuiColorEditFlags_RGB = 1 << 13, // [Inputs] // ColorEdit: choose one among RGB/HSV/HEX. ColorPicker: choose any combination using RGB/HSV/HEX. + ImGuiColorEditFlags_HSV = 1 << 14, // [Inputs] // " + ImGuiColorEditFlags_HEX = 1 << 15, // [Inputs] // " + ImGuiColorEditFlags_Uint8 = 1 << 16, // [DataType] // ColorEdit, ColorPicker, ColorButton: _display_ values formatted as 0..255. + ImGuiColorEditFlags_Float = 1 << 17, // [DataType] // ColorEdit, ColorPicker, ColorButton: _display_ values formatted as 0.0f..1.0f floats instead of 0..255 integers. No round-trip of value via integers. + ImGuiColorEditFlags_PickerHueBar = 1 << 18, // [PickerMode] // ColorPicker: bar for Hue, rectangle for Sat/Value. + ImGuiColorEditFlags_PickerHueWheel = 1 << 19, // [PickerMode] // ColorPicker: wheel for Hue, triangle for Sat/Value. + // Internals/Masks + ImGuiColorEditFlags__InputsMask = ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_HSV | ImGuiColorEditFlags_HEX, + ImGuiColorEditFlags__DataTypeMask = ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_Float, + ImGuiColorEditFlags__PickerMask = ImGuiColorEditFlags_PickerHueWheel | ImGuiColorEditFlags_PickerHueBar, + ImGuiColorEditFlags__OptionsDefault = ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_RGB | ImGuiColorEditFlags_PickerHueBar // Change application default using SetColorEditOptions() }; // Enumeration for GetMouseCursor() enum ImGuiMouseCursor_ { - ImGuiMouseCursor_None = -1, - ImGuiMouseCursor_Arrow = 0, - ImGuiMouseCursor_TextInput, // When hovering over InputText, etc. - ImGuiMouseCursor_ResizeAll, // Unused - ImGuiMouseCursor_ResizeNS, // When hovering over an horizontal border - ImGuiMouseCursor_ResizeEW, // When hovering over a vertical border or a column - ImGuiMouseCursor_ResizeNESW, // When hovering over the bottom-left corner of a window - ImGuiMouseCursor_ResizeNWSE, // When hovering over the bottom-right corner of a window - ImGuiMouseCursor_Count_ + ImGuiMouseCursor_None = -1, + ImGuiMouseCursor_Arrow = 0, + ImGuiMouseCursor_TextInput, // When hovering over InputText, etc. + ImGuiMouseCursor_ResizeAll, // Unused + ImGuiMouseCursor_ResizeNS, // When hovering over an horizontal border + ImGuiMouseCursor_ResizeEW, // When hovering over a vertical border or a column + ImGuiMouseCursor_ResizeNESW, // When hovering over the bottom-left corner of a window + ImGuiMouseCursor_ResizeNWSE, // When hovering over the bottom-right corner of a window + ImGuiMouseCursor_Count_ }; // Condition for ImGui::SetWindow***(), SetNextWindow***(), SetNextTreeNode***() functions // All those functions treat 0 as a shortcut to ImGuiCond_Always. From the point of view of the user use this as an enum (don't combine multiple values into flags). enum ImGuiCond_ { - ImGuiCond_Always = 1 << 0, // Set the variable - ImGuiCond_Once = 1 << 1, // Set the variable once per runtime session (only the first call with succeed) - ImGuiCond_FirstUseEver = 1 << 2, // Set the variable if the window has no saved data (if doesn't exist in the .ini file) - ImGuiCond_Appearing = 1 << 3 // Set the variable if the window is appearing after being hidden/inactive (or the first time) + ImGuiCond_Always = 1 << 0, // Set the variable + ImGuiCond_Once = 1 << 1, // Set the variable once per runtime session (only the first call with succeed) + ImGuiCond_FirstUseEver = 1 << 2, // Set the variable if the window has no saved data (if doesn't exist in the .ini file) + ImGuiCond_Appearing = 1 << 3 // Set the variable if the window is appearing after being hidden/inactive (or the first time) - // Obsolete names (will be removed) +// Obsolete names (will be removed) #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - , ImGuiSetCond_Always = ImGuiCond_Always, ImGuiSetCond_Once = ImGuiCond_Once, ImGuiSetCond_FirstUseEver = ImGuiCond_FirstUseEver, ImGuiSetCond_Appearing = ImGuiCond_Appearing + , + ImGuiSetCond_Always = ImGuiCond_Always, + ImGuiSetCond_Once = ImGuiCond_Once, + ImGuiSetCond_FirstUseEver = ImGuiCond_FirstUseEver, + ImGuiSetCond_Appearing = ImGuiCond_Appearing #endif }; @@ -908,155 +932,155 @@ enum ImGuiCond_ // During the frame, prefer using ImGui::PushStyleVar(ImGuiStyleVar_XXXX)/PopStyleVar() to alter the main style values, and ImGui::PushStyleColor(ImGuiCol_XXX)/PopStyleColor() for colors. struct ImGuiStyle { - float Alpha; // Global alpha applies to everything in ImGui. - ImVec2 WindowPadding; // Padding within a window. - float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows. - float WindowBorderSize; // Thickness of border around windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly). - ImVec2 WindowMinSize; // Minimum window size. This is a global setting. If you want to constraint individual windows, use SetNextWindowSizeConstraints(). - ImVec2 WindowTitleAlign; // Alignment for title bar text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered. - float ChildRounding; // Radius of child window corners rounding. Set to 0.0f to have rectangular windows. - float ChildBorderSize; // Thickness of border around child windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly). - float PopupRounding; // Radius of popup window corners rounding. - float PopupBorderSize; // Thickness of border around popup windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly). - ImVec2 FramePadding; // Padding within a framed rectangle (used by most widgets). - float FrameRounding; // Radius of frame corners rounding. Set to 0.0f to have rectangular frame (used by most widgets). - float FrameBorderSize; // Thickness of border around frames. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly). - ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines. - ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label). - ImVec2 TouchExtraPadding; // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! - float IndentSpacing; // Horizontal indentation when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2). - float ColumnsMinSpacing; // Minimum horizontal spacing between two columns. - float ScrollbarSize; // Width of the vertical scrollbar, Height of the horizontal scrollbar. - float ScrollbarRounding; // Radius of grab corners for scrollbar. - float GrabMinSize; // Minimum width/height of a grab box for slider/scrollbar. - float GrabRounding; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. - ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f,0.5f) for horizontally+vertically centered. - ImVec2 DisplayWindowPadding; // Window positions are clamped to be visible within the display area by at least this amount. Only covers regular windows. - ImVec2 DisplaySafeAreaPadding; // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. - float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later. - bool AntiAliasedLines; // Enable anti-aliasing on lines/borders. Disable if you are really tight on CPU/GPU. - bool AntiAliasedFill; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) - float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. - ImVec4 Colors[ImGuiCol_COUNT]; + float Alpha; // Global alpha applies to everything in ImGui. + ImVec2 WindowPadding; // Padding within a window. + float WindowRounding; // Radius of window corners rounding. Set to 0.0f to have rectangular windows. + float WindowBorderSize; // Thickness of border around windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly). + ImVec2 WindowMinSize; // Minimum window size. This is a global setting. If you want to constraint individual windows, use SetNextWindowSizeConstraints(). + ImVec2 WindowTitleAlign; // Alignment for title bar text. Defaults to (0.0f,0.5f) for left-aligned,vertically centered. + float ChildRounding; // Radius of child window corners rounding. Set to 0.0f to have rectangular windows. + float ChildBorderSize; // Thickness of border around child windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly). + float PopupRounding; // Radius of popup window corners rounding. + float PopupBorderSize; // Thickness of border around popup windows. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly). + ImVec2 FramePadding; // Padding within a framed rectangle (used by most widgets). + float FrameRounding; // Radius of frame corners rounding. Set to 0.0f to have rectangular frame (used by most widgets). + float FrameBorderSize; // Thickness of border around frames. Generally set to 0.0f or 1.0f. (Other values are not well tested and more CPU/GPU costly). + ImVec2 ItemSpacing; // Horizontal and vertical spacing between widgets/lines. + ImVec2 ItemInnerSpacing; // Horizontal and vertical spacing between within elements of a composed widget (e.g. a slider and its label). + ImVec2 TouchExtraPadding; // Expand reactive bounding box for touch-based system where touch position is not accurate enough. Unfortunately we don't sort widgets so priority on overlap will always be given to the first widget. So don't grow this too much! + float IndentSpacing; // Horizontal indentation when e.g. entering a tree node. Generally == (FontSize + FramePadding.x*2). + float ColumnsMinSpacing; // Minimum horizontal spacing between two columns. + float ScrollbarSize; // Width of the vertical scrollbar, Height of the horizontal scrollbar. + float ScrollbarRounding; // Radius of grab corners for scrollbar. + float GrabMinSize; // Minimum width/height of a grab box for slider/scrollbar. + float GrabRounding; // Radius of grabs corners rounding. Set to 0.0f to have rectangular slider grabs. + ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f,0.5f) for horizontally+vertically centered. + ImVec2 DisplayWindowPadding; // Window positions are clamped to be visible within the display area by at least this amount. Only covers regular windows. + ImVec2 DisplaySafeAreaPadding; // If you cannot see the edge of your screen (e.g. on a TV) increase the safe area padding. Covers popups/tooltips as well regular windows. + float MouseCursorScale; // Scale software rendered mouse cursor (when io.MouseDrawCursor is enabled). May be removed later. + bool AntiAliasedLines; // Enable anti-aliasing on lines/borders. Disable if you are really tight on CPU/GPU. + bool AntiAliasedFill; // Enable anti-aliasing on filled shapes (rounded rectangles, circles, etc.) + float CurveTessellationTol; // Tessellation tolerance when using PathBezierCurveTo() without a specific number of segments. Decrease for highly tessellated curves (higher quality, more polygons), increase to reduce quality. + ImVec4 Colors[ImGuiCol_COUNT]; - IMGUI_API ImGuiStyle(); - IMGUI_API void ScaleAllSizes(float scale_factor); + IMGUI_API ImGuiStyle(); + IMGUI_API void ScaleAllSizes(float scale_factor); }; // This is where your app communicate with ImGui. Access via ImGui::GetIO(). // Read 'Programmer guide' section in .cpp file for general usage. struct ImGuiIO { - //------------------------------------------------------------------ - // Settings (fill once) // Default value: - //------------------------------------------------------------------ + //------------------------------------------------------------------ + // Settings (fill once) // Default value: + //------------------------------------------------------------------ - ImVec2 DisplaySize; // // Display size, in pixels. For clamping windows positions. - float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds. - ImGuiNavFlags NavFlags; // = 0x00 // See ImGuiNavFlags_. Gamepad/keyboard navigation options. - float IniSavingRate; // = 5.0f // Maximum time between saving positions/sizes to .ini file, in seconds. - const char* IniFilename; // = "imgui.ini" // Path to .ini file. NULL to disable .ini saving. - const char* LogFilename; // = "imgui_log.txt" // Path to .log file (default parameter to ImGui::LogToFile when no file is specified). - float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds. - float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels. - float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging. - int KeyMap[ImGuiKey_COUNT]; // // Map of indices into the KeysDown[512] entries array which represent your "native" keyboard state. - float KeyRepeatDelay; // = 0.250f // When holding a key/button, time before it starts repeating, in seconds (for buttons in Repeat mode, etc.). - float KeyRepeatRate; // = 0.050f // When holding a key/button, rate at which it repeats, in seconds. - void* UserData; // = NULL // Store your own data for retrieval by callbacks. + ImVec2 DisplaySize; // // Display size, in pixels. For clamping windows positions. + float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds. + ImGuiNavFlags NavFlags; // = 0x00 // See ImGuiNavFlags_. Gamepad/keyboard navigation options. + float IniSavingRate; // = 5.0f // Maximum time between saving positions/sizes to .ini file, in seconds. + const char* IniFilename; // = "imgui.ini" // Path to .ini file. NULL to disable .ini saving. + const char* LogFilename; // = "imgui_log.txt" // Path to .log file (default parameter to ImGui::LogToFile when no file is specified). + float MouseDoubleClickTime; // = 0.30f // Time for a double-click, in seconds. + float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels. + float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging. + int KeyMap[ImGuiKey_COUNT]; // // Map of indices into the KeysDown[512] entries array which represent your "native" keyboard state. + float KeyRepeatDelay; // = 0.250f // When holding a key/button, time before it starts repeating, in seconds (for buttons in Repeat mode, etc.). + float KeyRepeatRate; // = 0.050f // When holding a key/button, rate at which it repeats, in seconds. + void* UserData; // = NULL // Store your own data for retrieval by callbacks. - ImFontAtlas* Fonts; // // Load and assemble one or more fonts into a single tightly packed texture. Output to Fonts array. - float FontGlobalScale; // = 1.0f // Global scale all fonts - bool FontAllowUserScaling; // = false // Allow user scaling text of individual window with CTRL+Wheel. - ImFont* FontDefault; // = NULL // Font to use on NewFrame(). Use NULL to uses Fonts->Fonts[0]. - ImVec2 DisplayFramebufferScale; // = (1.0f,1.0f) // For retina display or other situations where window coordinates are different from framebuffer coordinates. User storage only, presently not used by ImGui. - ImVec2 DisplayVisibleMin; // (0.0f,0.0f) // If you use DisplaySize as a virtual space larger than your screen, set DisplayVisibleMin/Max to the visible area. - ImVec2 DisplayVisibleMax; // (0.0f,0.0f) // If the values are the same, we defaults to Min=(0.0f) and Max=DisplaySize + ImFontAtlas* Fonts; // // Load and assemble one or more fonts into a single tightly packed texture. Output to Fonts array. + float FontGlobalScale; // = 1.0f // Global scale all fonts + bool FontAllowUserScaling; // = false // Allow user scaling text of individual window with CTRL+Wheel. + ImFont* FontDefault; // = NULL // Font to use on NewFrame(). Use NULL to uses Fonts->Fonts[0]. + ImVec2 DisplayFramebufferScale; // = (1.0f,1.0f) // For retina display or other situations where window coordinates are different from framebuffer coordinates. User storage only, presently not used by ImGui. + ImVec2 DisplayVisibleMin; // (0.0f,0.0f) // If you use DisplaySize as a virtual space larger than your screen, set DisplayVisibleMin/Max to the visible area. + ImVec2 DisplayVisibleMax; // (0.0f,0.0f) // If the values are the same, we defaults to Min=(0.0f) and Max=DisplaySize - // Advanced/subtle behaviors - bool OptMacOSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl - bool OptCursorBlink; // = true // Enable blinking cursor, for users who consider it annoying. + // Advanced/subtle behaviors + bool OptMacOSXBehaviors; // = defined(__APPLE__) // OS X style: Text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl + bool OptCursorBlink; // = true // Enable blinking cursor, for users who consider it annoying. - //------------------------------------------------------------------ - // Settings (User Functions) - //------------------------------------------------------------------ + //------------------------------------------------------------------ + // Settings (User Functions) + //------------------------------------------------------------------ - // Optional: access OS clipboard - // (default to use native Win32 clipboard on Windows, otherwise uses a private clipboard. Override to access OS clipboard on other architectures) - const char* (*GetClipboardTextFn)(void* user_data); - void (*SetClipboardTextFn)(void* user_data, const char* text); - void* ClipboardUserData; + // Optional: access OS clipboard + // (default to use native Win32 clipboard on Windows, otherwise uses a private clipboard. Override to access OS clipboard on other architectures) + const char* (*GetClipboardTextFn)(void* user_data); + void (*SetClipboardTextFn)(void* user_data, const char* text); + void* ClipboardUserData; - // Optional: notify OS Input Method Editor of the screen position of your cursor for text input position (e.g. when using Japanese/Chinese IME in Windows) - // (default to use native imm32 api on Windows) - void (*ImeSetInputScreenPosFn)(int x, int y); - void* ImeWindowHandle; // (Windows) Set this to your HWND to get automatic IME cursor positioning. + // Optional: notify OS Input Method Editor of the screen position of your cursor for text input position (e.g. when using Japanese/Chinese IME in Windows) + // (default to use native imm32 api on Windows) + void (*ImeSetInputScreenPosFn)(int x, int y); + void* ImeWindowHandle; // (Windows) Set this to your HWND to get automatic IME cursor positioning. #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - // [OBSOLETE] Rendering function, will be automatically called in Render(). Please call your rendering function yourself now! You can obtain the ImDrawData* by calling ImGui::GetDrawData() after Render(). - // See example applications if you are unsure of how to implement this. - void (*RenderDrawListsFn)(ImDrawData* data); + // [OBSOLETE] Rendering function, will be automatically called in Render(). Please call your rendering function yourself now! You can obtain the ImDrawData* by calling ImGui::GetDrawData() after Render(). + // See example applications if you are unsure of how to implement this. + void (*RenderDrawListsFn)(ImDrawData* data); #endif - //------------------------------------------------------------------ - // Input - Fill before calling NewFrame() - //------------------------------------------------------------------ + //------------------------------------------------------------------ + // Input - Fill before calling NewFrame() + //------------------------------------------------------------------ - ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX,-FLT_MAX) if mouse is unavailable (on another screen, etc.) - bool MouseDown[5]; // Mouse buttons: left, right, middle + extras. ImGui itself mostly only uses left button (BeginPopupContext** are using right button). Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. - float MouseWheel; // Mouse wheel: 1 unit scrolls about 5 lines text. - float MouseWheelH; // Mouse wheel (Horizontal). Most users don't have a mouse with an horizontal wheel, may not be filled by all back-ends. - bool MouseDrawCursor; // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). - bool KeyCtrl; // Keyboard modifier pressed: Control - bool KeyShift; // Keyboard modifier pressed: Shift - bool KeyAlt; // Keyboard modifier pressed: Alt - bool KeySuper; // Keyboard modifier pressed: Cmd/Super/Windows - bool KeysDown[512]; // Keyboard keys that are pressed (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). - ImWchar InputCharacters[16+1]; // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper. - float NavInputs[ImGuiNavInput_COUNT]; // Gamepad inputs (keyboard keys will be auto-mapped and be written here by ImGui::NewFrame) + ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX,-FLT_MAX) if mouse is unavailable (on another screen, etc.) + bool MouseDown[5]; // Mouse buttons: left, right, middle + extras. ImGui itself mostly only uses left button (BeginPopupContext** are using right button). Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. + float MouseWheel; // Mouse wheel: 1 unit scrolls about 5 lines text. + float MouseWheelH; // Mouse wheel (Horizontal). Most users don't have a mouse with an horizontal wheel, may not be filled by all back-ends. + bool MouseDrawCursor; // Request ImGui to draw a mouse cursor for you (if you are on a platform without a mouse cursor). + bool KeyCtrl; // Keyboard modifier pressed: Control + bool KeyShift; // Keyboard modifier pressed: Shift + bool KeyAlt; // Keyboard modifier pressed: Alt + bool KeySuper; // Keyboard modifier pressed: Cmd/Super/Windows + bool KeysDown[512]; // Keyboard keys that are pressed (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). + ImWchar InputCharacters[16 + 1]; // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper. + float NavInputs[ImGuiNavInput_COUNT]; // Gamepad inputs (keyboard keys will be auto-mapped and be written here by ImGui::NewFrame) - // Functions - IMGUI_API void AddInputCharacter(ImWchar c); // Add new character into InputCharacters[] - IMGUI_API void AddInputCharactersUTF8(const char* utf8_chars); // Add new characters into InputCharacters[] from an UTF-8 string - inline void ClearInputCharacters() { InputCharacters[0] = 0; } // Clear the text input buffer manually + // Functions + IMGUI_API void AddInputCharacter(ImWchar c); // Add new character into InputCharacters[] + IMGUI_API void AddInputCharactersUTF8(const char* utf8_chars); // Add new characters into InputCharacters[] from an UTF-8 string + inline void ClearInputCharacters() { InputCharacters[0] = 0; } // Clear the text input buffer manually - //------------------------------------------------------------------ - // Output - Retrieve after calling NewFrame() - //------------------------------------------------------------------ + //------------------------------------------------------------------ + // Output - Retrieve after calling NewFrame() + //------------------------------------------------------------------ - bool WantCaptureMouse; // When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. This is set by ImGui when it wants to use your mouse (e.g. unclicked mouse is hovering a window, or a widget is active). - bool WantCaptureKeyboard; // When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. This is set by ImGui when it wants to use your keyboard inputs. - bool WantTextInput; // Mobile/console: when io.WantTextInput is true, you may display an on-screen keyboard. This is set by ImGui when it wants textual keyboard input to happen (e.g. when a InputText widget is active). - bool WantMoveMouse; // MousePos has been altered, back-end should reposition mouse on next frame. Set only when ImGuiNavFlags_MoveMouse flag is enabled in io.NavFlags. - bool NavActive; // Directional navigation is currently allowed (will handle ImGuiKey_NavXXX events) = a window is focused and it doesn't use the ImGuiWindowFlags_NoNavInputs flag. - bool NavVisible; // Directional navigation is visible and allowed (will handle ImGuiKey_NavXXX events). - float Framerate; // Application framerate estimation, in frame per second. Solely for convenience. Rolling average estimation based on IO.DeltaTime over 120 frames - int MetricsRenderVertices; // Vertices output during last call to Render() - int MetricsRenderIndices; // Indices output during last call to Render() = number of triangles * 3 - int MetricsActiveWindows; // Number of visible root windows (exclude child windows) - ImVec2 MouseDelta; // Mouse delta. Note that this is zero if either current or previous position are invalid (-FLT_MAX,-FLT_MAX), so a disappearing/reappearing mouse won't have a huge delta. + bool WantCaptureMouse; // When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. This is set by ImGui when it wants to use your mouse (e.g. unclicked mouse is hovering a window, or a widget is active). + bool WantCaptureKeyboard; // When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. This is set by ImGui when it wants to use your keyboard inputs. + bool WantTextInput; // Mobile/console: when io.WantTextInput is true, you may display an on-screen keyboard. This is set by ImGui when it wants textual keyboard input to happen (e.g. when a InputText widget is active). + bool WantMoveMouse; // MousePos has been altered, back-end should reposition mouse on next frame. Set only when ImGuiNavFlags_MoveMouse flag is enabled in io.NavFlags. + bool NavActive; // Directional navigation is currently allowed (will handle ImGuiKey_NavXXX events) = a window is focused and it doesn't use the ImGuiWindowFlags_NoNavInputs flag. + bool NavVisible; // Directional navigation is visible and allowed (will handle ImGuiKey_NavXXX events). + float Framerate; // Application framerate estimation, in frame per second. Solely for convenience. Rolling average estimation based on IO.DeltaTime over 120 frames + int MetricsRenderVertices; // Vertices output during last call to Render() + int MetricsRenderIndices; // Indices output during last call to Render() = number of triangles * 3 + int MetricsActiveWindows; // Number of visible root windows (exclude child windows) + ImVec2 MouseDelta; // Mouse delta. Note that this is zero if either current or previous position are invalid (-FLT_MAX,-FLT_MAX), so a disappearing/reappearing mouse won't have a huge delta. - //------------------------------------------------------------------ - // [Internal] ImGui will maintain those fields. Forward compatibility not guaranteed! - //------------------------------------------------------------------ + //------------------------------------------------------------------ + // [Internal] ImGui will maintain those fields. Forward compatibility not guaranteed! + //------------------------------------------------------------------ - ImVec2 MousePosPrev; // Previous mouse position temporary storage (nb: not for public use, set to MousePos in NewFrame()) - ImVec2 MouseClickedPos[5]; // Position at time of clicking - float MouseClickedTime[5]; // Time of last click (used to figure out double-click) - bool MouseClicked[5]; // Mouse button went from !Down to Down - bool MouseDoubleClicked[5]; // Has mouse button been double-clicked? - bool MouseReleased[5]; // Mouse button went from Down to !Down - bool MouseDownOwned[5]; // Track if button was clicked inside a window. We don't request mouse capture from the application if click started outside ImGui bounds. - float MouseDownDuration[5]; // Duration the mouse button has been down (0.0f == just clicked) - float MouseDownDurationPrev[5]; // Previous time the mouse button has been down - ImVec2 MouseDragMaxDistanceAbs[5]; // Maximum distance, absolute, on each axis, of how much mouse has traveled from the clicking point - float MouseDragMaxDistanceSqr[5]; // Squared maximum distance of how much mouse has traveled from the clicking point - float KeysDownDuration[512]; // Duration the keyboard key has been down (0.0f == just pressed) - float KeysDownDurationPrev[512]; // Previous duration the key has been down - float NavInputsDownDuration[ImGuiNavInput_COUNT]; - float NavInputsDownDurationPrev[ImGuiNavInput_COUNT]; + ImVec2 MousePosPrev; // Previous mouse position temporary storage (nb: not for public use, set to MousePos in NewFrame()) + ImVec2 MouseClickedPos[5]; // Position at time of clicking + float MouseClickedTime[5]; // Time of last click (used to figure out double-click) + bool MouseClicked[5]; // Mouse button went from !Down to Down + bool MouseDoubleClicked[5]; // Has mouse button been double-clicked? + bool MouseReleased[5]; // Mouse button went from Down to !Down + bool MouseDownOwned[5]; // Track if button was clicked inside a window. We don't request mouse capture from the application if click started outside ImGui bounds. + float MouseDownDuration[5]; // Duration the mouse button has been down (0.0f == just clicked) + float MouseDownDurationPrev[5]; // Previous time the mouse button has been down + ImVec2 MouseDragMaxDistanceAbs[5]; // Maximum distance, absolute, on each axis, of how much mouse has traveled from the clicking point + float MouseDragMaxDistanceSqr[5]; // Squared maximum distance of how much mouse has traveled from the clicking point + float KeysDownDuration[512]; // Duration the keyboard key has been down (0.0f == just pressed) + float KeysDownDurationPrev[512]; // Previous duration the key has been down + float NavInputsDownDuration[ImGuiNavInput_COUNT]; + float NavInputsDownDurationPrev[ImGuiNavInput_COUNT]; - IMGUI_API ImGuiIO(); + IMGUI_API ImGuiIO(); }; //----------------------------------------------------------------------------- @@ -1066,29 +1090,49 @@ struct ImGuiIO #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS namespace ImGui { - // OBSOLETED in 1.60 (from Dec 2017) - static inline bool IsAnyWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_AnyWindow); } - static inline bool IsAnyWindowHovered() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); } - static inline ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = 0.f) { (void)on_edge; (void)outward; IM_ASSERT(0); return pos; } - // OBSOLETED in 1.53 (between Oct 2017 and Dec 2017) - static inline void ShowTestWindow() { return ShowDemoWindow(); } - static inline bool IsRootWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootWindow); } - static inline bool IsRootWindowOrAnyChildFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows); } - static inline void SetNextWindowContentWidth(float w) { SetNextWindowContentSize(ImVec2(w, 0.0f)); } - static inline float GetItemsLineHeightWithSpacing() { return GetFrameHeightWithSpacing(); } - // OBSOLETED in 1.52 (between Aug 2017 and Oct 2017) - bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override = -1.0f, ImGuiWindowFlags flags = 0); // Use SetNextWindowSize(size, ImGuiCond_FirstUseEver) + SetNextWindowBgAlpha() instead. - static inline bool IsRootWindowOrAnyChildHovered() { return IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows); } - static inline void AlignFirstTextHeightToWidgets() { AlignTextToFramePadding(); } - static inline void SetNextWindowPosCenter(ImGuiCond c=0) { ImGuiIO& io = GetIO(); SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f), c, ImVec2(0.5f, 0.5f)); } - // OBSOLETED in 1.51 (between Jun 2017 and Aug 2017) - static inline bool IsItemHoveredRect() { return IsItemHovered(ImGuiHoveredFlags_RectOnly); } - static inline bool IsPosHoveringAnyWindow(const ImVec2&) { IM_ASSERT(0); return false; } // This was misleading and partly broken. You probably want to use the ImGui::GetIO().WantCaptureMouse flag instead. - static inline bool IsMouseHoveringAnyWindow() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); } - static inline bool IsMouseHoveringWindow() { return IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem); } - // OBSOLETED IN 1.49 (between Apr 2016 and May 2016) - static inline bool CollapsingHeader(const char* label, const char* str_id, bool framed = true, bool default_open = false) { (void)str_id; (void)framed; ImGuiTreeNodeFlags default_open_flags = 1 << 5; return CollapsingHeader(label, (default_open ? default_open_flags : 0)); } +// OBSOLETED in 1.60 (from Dec 2017) +static inline bool IsAnyWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_AnyWindow); } +static inline bool IsAnyWindowHovered() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); } +static inline ImVec2 CalcItemRectClosestPoint(const ImVec2& pos, bool on_edge = false, float outward = 0.f) +{ + (void)on_edge; + (void)outward; + IM_ASSERT(0); + return pos; } +// OBSOLETED in 1.53 (between Oct 2017 and Dec 2017) +static inline void ShowTestWindow() { return ShowDemoWindow(); } +static inline bool IsRootWindowFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootWindow); } +static inline bool IsRootWindowOrAnyChildFocused() { return IsWindowFocused(ImGuiFocusedFlags_RootAndChildWindows); } +static inline void SetNextWindowContentWidth(float w) { SetNextWindowContentSize(ImVec2(w, 0.0f)); } +static inline float GetItemsLineHeightWithSpacing() { return GetFrameHeightWithSpacing(); } +// OBSOLETED in 1.52 (between Aug 2017 and Oct 2017) +bool Begin(const char* name, bool* p_open, const ImVec2& size_on_first_use, float bg_alpha_override = -1.0f, ImGuiWindowFlags flags = 0); // Use SetNextWindowSize(size, ImGuiCond_FirstUseEver) + SetNextWindowBgAlpha() instead. +static inline bool IsRootWindowOrAnyChildHovered() { return IsWindowHovered(ImGuiHoveredFlags_RootAndChildWindows); } +static inline void AlignFirstTextHeightToWidgets() { AlignTextToFramePadding(); } +static inline void SetNextWindowPosCenter(ImGuiCond c = 0) +{ + ImGuiIO& io = GetIO(); + SetNextWindowPos(ImVec2(io.DisplaySize.x * 0.5f, io.DisplaySize.y * 0.5f), c, ImVec2(0.5f, 0.5f)); +} +// OBSOLETED in 1.51 (between Jun 2017 and Aug 2017) +static inline bool IsItemHoveredRect() { return IsItemHovered(ImGuiHoveredFlags_RectOnly); } +static inline bool IsPosHoveringAnyWindow(const ImVec2&) +{ + IM_ASSERT(0); + return false; +} // This was misleading and partly broken. You probably want to use the ImGui::GetIO().WantCaptureMouse flag instead. +static inline bool IsMouseHoveringAnyWindow() { return IsWindowHovered(ImGuiHoveredFlags_AnyWindow); } +static inline bool IsMouseHoveringWindow() { return IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup | ImGuiHoveredFlags_AllowWhenBlockedByActiveItem); } +// OBSOLETED IN 1.49 (between Apr 2016 and May 2016) +static inline bool CollapsingHeader(const char* label, const char* str_id, bool framed = true, bool default_open = false) +{ + (void)str_id; + (void)framed; + ImGuiTreeNodeFlags default_open_flags = 1 << 5; + return CollapsingHeader(label, (default_open ? default_open_flags : 0)); +} +} // namespace ImGui #endif //----------------------------------------------------------------------------- @@ -1097,63 +1141,164 @@ namespace ImGui // Lightweight std::vector<> like class to avoid dragging dependencies (also: windows implementation of STL with debug enabled is absurdly slow, so let's bypass it so our code runs fast in debug). // Our implementation does NOT call C++ constructors/destructors. This is intentional and we do not require it. Do not use this class as a straight std::vector replacement in your code! -template +template class ImVector { public: - int Size; - int Capacity; - T* Data; + int Size; + int Capacity; + T* Data; - typedef T value_type; - typedef value_type* iterator; - typedef const value_type* const_iterator; + typedef T value_type; + typedef value_type* iterator; + typedef const value_type* const_iterator; - inline ImVector() { Size = Capacity = 0; Data = NULL; } - inline ~ImVector() { if (Data) ImGui::MemFree(Data); } + inline ImVector() + { + Size = Capacity = 0; + Data = NULL; + } + inline ~ImVector() + { + if (Data) ImGui::MemFree(Data); + } - inline bool empty() const { return Size == 0; } - inline int size() const { return Size; } - inline int capacity() const { return Capacity; } + inline bool empty() const { return Size == 0; } + inline int size() const { return Size; } + inline int capacity() const { return Capacity; } - inline value_type& operator[](int i) { IM_ASSERT(i < Size); return Data[i]; } - inline const value_type& operator[](int i) const { IM_ASSERT(i < Size); return Data[i]; } + inline value_type& operator[](int i) + { + IM_ASSERT(i < Size); + return Data[i]; + } + inline const value_type& operator[](int i) const + { + IM_ASSERT(i < Size); + return Data[i]; + } - inline void clear() { if (Data) { Size = Capacity = 0; ImGui::MemFree(Data); Data = NULL; } } - inline iterator begin() { return Data; } - inline const_iterator begin() const { return Data; } - inline iterator end() { return Data + Size; } - inline const_iterator end() const { return Data + Size; } - inline value_type& front() { IM_ASSERT(Size > 0); return Data[0]; } - inline const value_type& front() const { IM_ASSERT(Size > 0); return Data[0]; } - inline value_type& back() { IM_ASSERT(Size > 0); return Data[Size - 1]; } - inline const value_type& back() const { IM_ASSERT(Size > 0); return Data[Size - 1]; } - inline void swap(ImVector& rhs) { int rhs_size = rhs.Size; rhs.Size = Size; Size = rhs_size; int rhs_cap = rhs.Capacity; rhs.Capacity = Capacity; Capacity = rhs_cap; value_type* rhs_data = rhs.Data; rhs.Data = Data; Data = rhs_data; } + inline void clear() + { + if (Data) + { + Size = Capacity = 0; + ImGui::MemFree(Data); + Data = NULL; + } + } + inline iterator begin() { return Data; } + inline const_iterator begin() const { return Data; } + inline iterator end() { return Data + Size; } + inline const_iterator end() const { return Data + Size; } + inline value_type& front() + { + IM_ASSERT(Size > 0); + return Data[0]; + } + inline const value_type& front() const + { + IM_ASSERT(Size > 0); + return Data[0]; + } + inline value_type& back() + { + IM_ASSERT(Size > 0); + return Data[Size - 1]; + } + inline const value_type& back() const + { + IM_ASSERT(Size > 0); + return Data[Size - 1]; + } + inline void swap(ImVector& rhs) + { + int rhs_size = rhs.Size; + rhs.Size = Size; + Size = rhs_size; + int rhs_cap = rhs.Capacity; + rhs.Capacity = Capacity; + Capacity = rhs_cap; + value_type* rhs_data = rhs.Data; + rhs.Data = Data; + Data = rhs_data; + } - inline int _grow_capacity(int sz) const { int new_capacity = Capacity ? (Capacity + Capacity/2) : 8; return new_capacity > sz ? new_capacity : sz; } + inline int _grow_capacity(int sz) const + { + int new_capacity = Capacity ? (Capacity + Capacity / 2) : 8; + return new_capacity > sz ? new_capacity : sz; + } - inline void resize(int new_size) { if (new_size > Capacity) reserve(_grow_capacity(new_size)); Size = new_size; } - inline void resize(int new_size, const T& v){ if (new_size > Capacity) reserve(_grow_capacity(new_size)); if (new_size > Size) for (int n = Size; n < new_size; n++) Data[n] = v; Size = new_size; } - inline void reserve(int new_capacity) - { - if (new_capacity <= Capacity) - return; - T* new_data = (value_type*)ImGui::MemAlloc((size_t)new_capacity * sizeof(T)); - if (Data) - memcpy(new_data, Data, (size_t)Size * sizeof(T)); - ImGui::MemFree(Data); - Data = new_data; - Capacity = new_capacity; - } + inline void resize(int new_size) + { + if (new_size > Capacity) reserve(_grow_capacity(new_size)); + Size = new_size; + } + inline void resize(int new_size, const T& v) + { + if (new_size > Capacity) reserve(_grow_capacity(new_size)); + if (new_size > Size) + for (int n = Size; n < new_size; n++) Data[n] = v; + Size = new_size; + } + inline void reserve(int new_capacity) + { + if (new_capacity <= Capacity) + return; + T* new_data = (value_type*)ImGui::MemAlloc((size_t)new_capacity * sizeof(T)); + if (Data) + memcpy(new_data, Data, (size_t)Size * sizeof(T)); + ImGui::MemFree(Data); + Data = new_data; + Capacity = new_capacity; + } - // NB: &v cannot be pointing inside the ImVector Data itself! e.g. v.push_back(v[10]) is forbidden. - inline void push_back(const value_type& v) { if (Size == Capacity) reserve(_grow_capacity(Size + 1)); Data[Size++] = v; } - inline void pop_back() { IM_ASSERT(Size > 0); Size--; } - inline void push_front(const value_type& v) { if (Size == 0) push_back(v); else insert(Data, v); } + // NB: &v cannot be pointing inside the ImVector Data itself! e.g. v.push_back(v[10]) is forbidden. + inline void push_back(const value_type& v) + { + if (Size == Capacity) reserve(_grow_capacity(Size + 1)); + Data[Size++] = v; + } + inline void pop_back() + { + IM_ASSERT(Size > 0); + Size--; + } + inline void push_front(const value_type& v) + { + if (Size == 0) + push_back(v); + else + insert(Data, v); + } - inline iterator erase(const_iterator it) { IM_ASSERT(it >= Data && it < Data+Size); const ptrdiff_t off = it - Data; memmove(Data + off, Data + off + 1, ((size_t)Size - (size_t)off - 1) * sizeof(value_type)); Size--; return Data + off; } - inline iterator insert(const_iterator it, const value_type& v) { IM_ASSERT(it >= Data && it <= Data+Size); const ptrdiff_t off = it - Data; if (Size == Capacity) reserve(_grow_capacity(Size + 1)); if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(value_type)); Data[off] = v; Size++; return Data + off; } - inline bool contains(const value_type& v) const { const T* data = Data; const T* data_end = Data + Size; while (data < data_end) if (*data++ == v) return true; return false; } + inline iterator erase(const_iterator it) + { + IM_ASSERT(it >= Data && it < Data + Size); + const ptrdiff_t off = it - Data; + memmove(Data + off, Data + off + 1, ((size_t)Size - (size_t)off - 1) * sizeof(value_type)); + Size--; + return Data + off; + } + inline iterator insert(const_iterator it, const value_type& v) + { + IM_ASSERT(it >= Data && it <= Data + Size); + const ptrdiff_t off = it - Data; + if (Size == Capacity) reserve(_grow_capacity(Size + 1)); + if (off < (int)Size) memmove(Data + off + 1, Data + off, ((size_t)Size - (size_t)off) * sizeof(value_type)); + Data[off] = v; + Size++; + return Data + off; + } + inline bool contains(const value_type& v) const + { + const T* data = Data; + const T* data_end = Data + Size; + while (data < data_end) + if (*data++ == v) return true; + return false; + } }; // Helper: execute a block of code at maximum once a frame. Convenient if you want to quickly create an UI within deep-nested code that runs multiple times every frame. @@ -1163,68 +1308,92 @@ public: // ImGui::Text("This will be called only once per frame"); struct ImGuiOnceUponAFrame { - ImGuiOnceUponAFrame() { RefFrame = -1; } - mutable int RefFrame; - operator bool() const { int current_frame = ImGui::GetFrameCount(); if (RefFrame == current_frame) return false; RefFrame = current_frame; return true; } + ImGuiOnceUponAFrame() { RefFrame = -1; } + mutable int RefFrame; + operator bool() const + { + int current_frame = ImGui::GetFrameCount(); + if (RefFrame == current_frame) return false; + RefFrame = current_frame; + return true; + } }; // Helper macro for ImGuiOnceUponAFrame. Attention: The macro expands into 2 statement so make sure you don't use it within e.g. an if() statement without curly braces. -#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS // Will obsolete -#define IMGUI_ONCE_UPON_A_FRAME static ImGuiOnceUponAFrame imgui_oaf; if (imgui_oaf) +#ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS // Will obsolete +#define IMGUI_ONCE_UPON_A_FRAME \ + static ImGuiOnceUponAFrame imgui_oaf; \ + if (imgui_oaf) #endif // Helper: Parse and apply text filters. In format "aaaaa[,bbbb][,ccccc]" struct ImGuiTextFilter { - struct TextRange - { - const char* b; - const char* e; + struct TextRange + { + const char* b; + const char* e; - TextRange() { b = e = NULL; } - TextRange(const char* _b, const char* _e) { b = _b; e = _e; } - const char* begin() const { return b; } - const char* end() const { return e; } - bool empty() const { return b == e; } - char front() const { return *b; } - static bool is_blank(char c) { return c == ' ' || c == '\t'; } - void trim_blanks() { while (b < e && is_blank(*b)) b++; while (e > b && is_blank(*(e-1))) e--; } - IMGUI_API void split(char separator, ImVector& out); - }; + TextRange() { b = e = NULL; } + TextRange(const char* _b, const char* _e) + { + b = _b; + e = _e; + } + const char* begin() const { return b; } + const char* end() const { return e; } + bool empty() const { return b == e; } + char front() const { return *b; } + static bool is_blank(char c) { return c == ' ' || c == '\t'; } + void trim_blanks() + { + while (b < e && is_blank(*b)) b++; + while (e > b && is_blank(*(e - 1))) e--; + } + IMGUI_API void split(char separator, ImVector& out); + }; - char InputBuf[256]; - ImVector Filters; - int CountGrep; + char InputBuf[256]; + ImVector Filters; + int CountGrep; - IMGUI_API ImGuiTextFilter(const char* default_filter = ""); - IMGUI_API bool Draw(const char* label = "Filter (inc,-exc)", float width = 0.0f); // Helper calling InputText+Build - IMGUI_API bool PassFilter(const char* text, const char* text_end = NULL) const; - IMGUI_API void Build(); - void Clear() { InputBuf[0] = 0; Build(); } - bool IsActive() const { return !Filters.empty(); } + IMGUI_API ImGuiTextFilter(const char* default_filter = ""); + IMGUI_API bool Draw(const char* label = "Filter (inc,-exc)", float width = 0.0f); // Helper calling InputText+Build + IMGUI_API bool PassFilter(const char* text, const char* text_end = NULL) const; + IMGUI_API void Build(); + void Clear() + { + InputBuf[0] = 0; + Build(); + } + bool IsActive() const { return !Filters.empty(); } }; // Helper: Text buffer for logging/accumulating text struct ImGuiTextBuffer { - ImVector Buf; + ImVector Buf; - ImGuiTextBuffer() { Buf.push_back(0); } - inline char operator[](int i) { return Buf.Data[i]; } - const char* begin() const { return &Buf.front(); } - const char* end() const { return &Buf.back(); } // Buf is zero-terminated, so end() will point on the zero-terminator - int size() const { return Buf.Size - 1; } - bool empty() { return Buf.Size <= 1; } - void clear() { Buf.clear(); Buf.push_back(0); } - void reserve(int capacity) { Buf.reserve(capacity); } - const char* c_str() const { return Buf.Data; } - IMGUI_API void appendf(const char* fmt, ...) IM_FMTARGS(2); - IMGUI_API void appendfv(const char* fmt, va_list args) IM_FMTLIST(2); + ImGuiTextBuffer() { Buf.push_back(0); } + inline char operator[](int i) { return Buf.Data[i]; } + const char* begin() const { return &Buf.front(); } + const char* end() const { return &Buf.back(); } // Buf is zero-terminated, so end() will point on the zero-terminator + int size() const { return Buf.Size - 1; } + bool empty() { return Buf.Size <= 1; } + void clear() + { + Buf.clear(); + Buf.push_back(0); + } + void reserve(int capacity) { Buf.reserve(capacity); } + const char* c_str() const { return Buf.Data; } + IMGUI_API void appendf(const char* fmt, ...) IM_FMTARGS(2); + IMGUI_API void appendfv(const char* fmt, va_list args) IM_FMTLIST(2); }; // Helper: Simple Key->value storage // Typically you don't have to worry about this since a storage is held within each Window. -// We use it to e.g. store collapse state for a tree (Int 0/1), store color edit options. +// We use it to e.g. store collapse state for a tree (Int 0/1), store color edit options. // This is optimized for efficient reading (dichotomy into a contiguous buffer), rare writing (typically tied to user interactions) // You can use it as custom user storage for temporary values. Declare your own storage if, for example: // - You want to manipulate the open/close state of a particular sub-tree in your interface (tree node uses Int 0/1 to store their state). @@ -1232,123 +1401,147 @@ struct ImGuiTextBuffer // Types are NOT stored, so it is up to you to make sure your Key don't collide with different types. struct ImGuiStorage { - struct Pair - { - ImGuiID key; - union { int val_i; float val_f; void* val_p; }; - Pair(ImGuiID _key, int _val_i) { key = _key; val_i = _val_i; } - Pair(ImGuiID _key, float _val_f) { key = _key; val_f = _val_f; } - Pair(ImGuiID _key, void* _val_p) { key = _key; val_p = _val_p; } - }; - ImVector Data; + struct Pair + { + ImGuiID key; + union { + int val_i; + float val_f; + void* val_p; + }; + Pair(ImGuiID _key, int _val_i) + { + key = _key; + val_i = _val_i; + } + Pair(ImGuiID _key, float _val_f) + { + key = _key; + val_f = _val_f; + } + Pair(ImGuiID _key, void* _val_p) + { + key = _key; + val_p = _val_p; + } + }; + ImVector Data; - // - Get***() functions find pair, never add/allocate. Pairs are sorted so a query is O(log N) - // - Set***() functions find pair, insertion on demand if missing. - // - Sorted insertion is costly, paid once. A typical frame shouldn't need to insert any new pair. - void Clear() { Data.clear(); } - IMGUI_API int GetInt(ImGuiID key, int default_val = 0) const; - IMGUI_API void SetInt(ImGuiID key, int val); - IMGUI_API bool GetBool(ImGuiID key, bool default_val = false) const; - IMGUI_API void SetBool(ImGuiID key, bool val); - IMGUI_API float GetFloat(ImGuiID key, float default_val = 0.0f) const; - IMGUI_API void SetFloat(ImGuiID key, float val); - IMGUI_API void* GetVoidPtr(ImGuiID key) const; // default_val is NULL - IMGUI_API void SetVoidPtr(ImGuiID key, void* val); + // - Get***() functions find pair, never add/allocate. Pairs are sorted so a query is O(log N) + // - Set***() functions find pair, insertion on demand if missing. + // - Sorted insertion is costly, paid once. A typical frame shouldn't need to insert any new pair. + void Clear() { Data.clear(); } + IMGUI_API int GetInt(ImGuiID key, int default_val = 0) const; + IMGUI_API void SetInt(ImGuiID key, int val); + IMGUI_API bool GetBool(ImGuiID key, bool default_val = false) const; + IMGUI_API void SetBool(ImGuiID key, bool val); + IMGUI_API float GetFloat(ImGuiID key, float default_val = 0.0f) const; + IMGUI_API void SetFloat(ImGuiID key, float val); + IMGUI_API void* GetVoidPtr(ImGuiID key) const; // default_val is NULL + IMGUI_API void SetVoidPtr(ImGuiID key, void* val); - // - Get***Ref() functions finds pair, insert on demand if missing, return pointer. Useful if you intend to do Get+Set. - // - References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer. - // - A typical use case where this is convenient for quick hacking (e.g. add storage during a live Edit&Continue session if you can't modify existing struct) - // float* pvar = ImGui::GetFloatRef(key); ImGui::SliderFloat("var", pvar, 0, 100.0f); some_var += *pvar; - IMGUI_API int* GetIntRef(ImGuiID key, int default_val = 0); - IMGUI_API bool* GetBoolRef(ImGuiID key, bool default_val = false); - IMGUI_API float* GetFloatRef(ImGuiID key, float default_val = 0.0f); - IMGUI_API void** GetVoidPtrRef(ImGuiID key, void* default_val = NULL); + // - Get***Ref() functions finds pair, insert on demand if missing, return pointer. Useful if you intend to do Get+Set. + // - References are only valid until a new value is added to the storage. Calling a Set***() function or a Get***Ref() function invalidates the pointer. + // - A typical use case where this is convenient for quick hacking (e.g. add storage during a live Edit&Continue session if you can't modify existing struct) + // float* pvar = ImGui::GetFloatRef(key); ImGui::SliderFloat("var", pvar, 0, 100.0f); some_var += *pvar; + IMGUI_API int* GetIntRef(ImGuiID key, int default_val = 0); + IMGUI_API bool* GetBoolRef(ImGuiID key, bool default_val = false); + IMGUI_API float* GetFloatRef(ImGuiID key, float default_val = 0.0f); + IMGUI_API void** GetVoidPtrRef(ImGuiID key, void* default_val = NULL); - // Use on your own storage if you know only integer are being stored (open/close all tree nodes) - IMGUI_API void SetAllInt(int val); + // Use on your own storage if you know only integer are being stored (open/close all tree nodes) + IMGUI_API void SetAllInt(int val); - // For quicker full rebuild of a storage (instead of an incremental one), you may add all your contents and then sort once. - IMGUI_API void BuildSortByKey(); + // For quicker full rebuild of a storage (instead of an incremental one), you may add all your contents and then sort once. + IMGUI_API void BuildSortByKey(); }; // Shared state of InputText(), passed to callback when a ImGuiInputTextFlags_Callback* flag is used and the corresponding callback is triggered. struct ImGuiTextEditCallbackData { - ImGuiInputTextFlags EventFlag; // One of ImGuiInputTextFlags_Callback* // Read-only - ImGuiInputTextFlags Flags; // What user passed to InputText() // Read-only - void* UserData; // What user passed to InputText() // Read-only - bool ReadOnly; // Read-only mode // Read-only + ImGuiInputTextFlags EventFlag; // One of ImGuiInputTextFlags_Callback* // Read-only + ImGuiInputTextFlags Flags; // What user passed to InputText() // Read-only + void* UserData; // What user passed to InputText() // Read-only + bool ReadOnly; // Read-only mode // Read-only - // CharFilter event: - ImWchar EventChar; // Character input // Read-write (replace character or set to zero) + // CharFilter event: + ImWchar EventChar; // Character input // Read-write (replace character or set to zero) - // Completion,History,Always events: - // If you modify the buffer contents make sure you update 'BufTextLen' and set 'BufDirty' to true. - ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only - char* Buf; // Current text buffer // Read-write (pointed data only, can't replace the actual pointer) - int BufTextLen; // Current text length in bytes // Read-write - int BufSize; // Maximum text length in bytes // Read-only - bool BufDirty; // Set if you modify Buf/BufTextLen!! // Write - int CursorPos; // // Read-write - int SelectionStart; // // Read-write (== to SelectionEnd when no selection) - int SelectionEnd; // // Read-write + // Completion,History,Always events: + // If you modify the buffer contents make sure you update 'BufTextLen' and set 'BufDirty' to true. + ImGuiKey EventKey; // Key pressed (Up/Down/TAB) // Read-only + char* Buf; // Current text buffer // Read-write (pointed data only, can't replace the actual pointer) + int BufTextLen; // Current text length in bytes // Read-write + int BufSize; // Maximum text length in bytes // Read-only + bool BufDirty; // Set if you modify Buf/BufTextLen!! // Write + int CursorPos; // // Read-write + int SelectionStart; // // Read-write (== to SelectionEnd when no selection) + int SelectionEnd; // // Read-write - // NB: Helper functions for text manipulation. Calling those function loses selection. - IMGUI_API void DeleteChars(int pos, int bytes_count); - IMGUI_API void InsertChars(int pos, const char* text, const char* text_end = NULL); - bool HasSelection() const { return SelectionStart != SelectionEnd; } + // NB: Helper functions for text manipulation. Calling those function loses selection. + IMGUI_API void DeleteChars(int pos, int bytes_count); + IMGUI_API void InsertChars(int pos, const char* text, const char* text_end = NULL); + bool HasSelection() const { return SelectionStart != SelectionEnd; } }; // Resizing callback data to apply custom constraint. As enabled by SetNextWindowSizeConstraints(). Callback is called during the next Begin(). // NB: For basic min/max size constraint on each axis you don't need to use the callback! The SetNextWindowSizeConstraints() parameters are enough. struct ImGuiSizeCallbackData { - void* UserData; // Read-only. What user passed to SetNextWindowSizeConstraints() - ImVec2 Pos; // Read-only. Window position, for reference. - ImVec2 CurrentSize; // Read-only. Current window size. - ImVec2 DesiredSize; // Read-write. Desired size, based on user's mouse position. Write to this field to restrain resizing. + void* UserData; // Read-only. What user passed to SetNextWindowSizeConstraints() + ImVec2 Pos; // Read-only. Window position, for reference. + ImVec2 CurrentSize; // Read-only. Current window size. + ImVec2 DesiredSize; // Read-write. Desired size, based on user's mouse position. Write to this field to restrain resizing. }; // Data payload for Drag and Drop operations struct ImGuiPayload { - // Members - const void* Data; // Data (copied and owned by dear imgui) - int DataSize; // Data size + // Members + const void* Data; // Data (copied and owned by dear imgui) + int DataSize; // Data size - // [Internal] - ImGuiID SourceId; // Source item id - ImGuiID SourceParentId; // Source parent id (if available) - int DataFrameCount; // Data timestamp - char DataType[12 + 1]; // Data type tag (short user-supplied string, 12 characters max) - bool Preview; // Set when AcceptDragDropPayload() was called and mouse has been hovering the target item (nb: handle overlapping drag targets) - bool Delivery; // Set when AcceptDragDropPayload() was called and mouse button is released over the target item. + // [Internal] + ImGuiID SourceId; // Source item id + ImGuiID SourceParentId; // Source parent id (if available) + int DataFrameCount; // Data timestamp + char DataType[12 + 1]; // Data type tag (short user-supplied string, 12 characters max) + bool Preview; // Set when AcceptDragDropPayload() was called and mouse has been hovering the target item (nb: handle overlapping drag targets) + bool Delivery; // Set when AcceptDragDropPayload() was called and mouse button is released over the target item. - ImGuiPayload() { Clear(); } - void Clear() { SourceId = SourceParentId = 0; Data = NULL; DataSize = 0; memset(DataType, 0, sizeof(DataType)); DataFrameCount = -1; Preview = Delivery = false; } - bool IsDataType(const char* type) const { return DataFrameCount != -1 && strcmp(type, DataType) == 0; } - bool IsPreview() const { return Preview; } - bool IsDelivery() const { return Delivery; } + ImGuiPayload() { Clear(); } + void Clear() + { + SourceId = SourceParentId = 0; + Data = NULL; + DataSize = 0; + memset(DataType, 0, sizeof(DataType)); + DataFrameCount = -1; + Preview = Delivery = false; + } + bool IsDataType(const char* type) const { return DataFrameCount != -1 && strcmp(type, DataType) == 0; } + bool IsPreview() const { return Preview; } + bool IsDelivery() const { return Delivery; } }; // Helpers macros to generate 32-bits encoded colors #ifdef IMGUI_USE_BGRA_PACKED_COLOR -#define IM_COL32_R_SHIFT 16 -#define IM_COL32_G_SHIFT 8 -#define IM_COL32_B_SHIFT 0 -#define IM_COL32_A_SHIFT 24 -#define IM_COL32_A_MASK 0xFF000000 +#define IM_COL32_R_SHIFT 16 +#define IM_COL32_G_SHIFT 8 +#define IM_COL32_B_SHIFT 0 +#define IM_COL32_A_SHIFT 24 +#define IM_COL32_A_MASK 0xFF000000 #else -#define IM_COL32_R_SHIFT 0 -#define IM_COL32_G_SHIFT 8 -#define IM_COL32_B_SHIFT 16 -#define IM_COL32_A_SHIFT 24 -#define IM_COL32_A_MASK 0xFF000000 +#define IM_COL32_R_SHIFT 0 +#define IM_COL32_G_SHIFT 8 +#define IM_COL32_B_SHIFT 16 +#define IM_COL32_A_SHIFT 24 +#define IM_COL32_A_MASK 0xFF000000 #endif -#define IM_COL32(R,G,B,A) (((ImU32)(A)<>IM_COL32_R_SHIFT)&0xFF) * sc; Value.y = (float)((rgba>>IM_COL32_G_SHIFT)&0xFF) * sc; Value.z = (float)((rgba>>IM_COL32_B_SHIFT)&0xFF) * sc; Value.w = (float)((rgba>>IM_COL32_A_SHIFT)&0xFF) * sc; } - ImColor(float r, float g, float b, float a = 1.0f) { Value.x = r; Value.y = g; Value.z = b; Value.w = a; } - ImColor(const ImVec4& col) { Value = col; } - inline operator ImU32() const { return ImGui::ColorConvertFloat4ToU32(Value); } - inline operator ImVec4() const { return Value; } + ImColor() { Value.x = Value.y = Value.z = Value.w = 0.0f; } + ImColor(int r, int g, int b, int a = 255) + { + float sc = 1.0f / 255.0f; + Value.x = (float)r * sc; + Value.y = (float)g * sc; + Value.z = (float)b * sc; + Value.w = (float)a * sc; + } + ImColor(ImU32 rgba) + { + float sc = 1.0f / 255.0f; + Value.x = (float)((rgba >> IM_COL32_R_SHIFT) & 0xFF) * sc; + Value.y = (float)((rgba >> IM_COL32_G_SHIFT) & 0xFF) * sc; + Value.z = (float)((rgba >> IM_COL32_B_SHIFT) & 0xFF) * sc; + Value.w = (float)((rgba >> IM_COL32_A_SHIFT) & 0xFF) * sc; + } + ImColor(float r, float g, float b, float a = 1.0f) + { + Value.x = r; + Value.y = g; + Value.z = b; + Value.w = a; + } + ImColor(const ImVec4& col) { Value = col; } + inline operator ImU32() const { return ImGui::ColorConvertFloat4ToU32(Value); } + inline operator ImVec4() const { return Value; } - // FIXME-OBSOLETE: May need to obsolete/cleanup those helpers. - inline void SetHSV(float h, float s, float v, float a = 1.0f){ ImGui::ColorConvertHSVtoRGB(h, s, v, Value.x, Value.y, Value.z); Value.w = a; } - static ImColor HSV(float h, float s, float v, float a = 1.0f) { float r,g,b; ImGui::ColorConvertHSVtoRGB(h, s, v, r, g, b); return ImColor(r,g,b,a); } + // FIXME-OBSOLETE: May need to obsolete/cleanup those helpers. + inline void SetHSV(float h, float s, float v, float a = 1.0f) + { + ImGui::ColorConvertHSVtoRGB(h, s, v, Value.x, Value.y, Value.z); + Value.w = a; + } + static ImColor HSV(float h, float s, float v, float a = 1.0f) + { + float r, g, b; + ImGui::ColorConvertHSVtoRGB(h, s, v, r, g, b); + return ImColor(r, g, b, a); + } }; // Helper: Manually clip large list of items. // If you are submitting lots of evenly spaced items and you have a random access to the list, you can perform coarse clipping based on visibility to save yourself from processing those items at all. -// The clipper calculates the range of visible items and advance the cursor to compensate for the non-visible items we have skipped. +// The clipper calculates the range of visible items and advance the cursor to compensate for the non-visible items we have skipped. // ImGui already clip items based on their bounds but it needs to measure text size to do so. Coarse clipping before submission makes this cost and your own data fetching/submission cost null. // Usage: // ImGuiListClipper clipper(1000); // we have 1000 elements, evenly spaced. @@ -1386,19 +1608,19 @@ struct ImColor // - Step 3: the clipper validate that we have reached the expected Y position (corresponding to element DisplayEnd), advance the cursor to the end of the list and then returns 'false' to end the loop. struct ImGuiListClipper { - float StartPosY; - float ItemsHeight; - int ItemsCount, StepNo, DisplayStart, DisplayEnd; + float StartPosY; + float ItemsHeight; + int ItemsCount, StepNo, DisplayStart, DisplayEnd; - // items_count: Use -1 to ignore (you can call Begin later). Use INT_MAX if you don't know how many items you have (in which case the cursor won't be advanced in the final step). - // items_height: Use -1.0f to be calculated automatically on first step. Otherwise pass in the distance between your items, typically GetTextLineHeightWithSpacing() or GetFrameHeightWithSpacing(). - // If you don't specify an items_height, you NEED to call Step(). If you specify items_height you may call the old Begin()/End() api directly, but prefer calling Step(). - ImGuiListClipper(int items_count = -1, float items_height = -1.0f) { Begin(items_count, items_height); } // NB: Begin() initialize every fields (as we allow user to call Begin/End multiple times on a same instance if they want). - ~ImGuiListClipper() { IM_ASSERT(ItemsCount == -1); } // Assert if user forgot to call End() or Step() until false. + // items_count: Use -1 to ignore (you can call Begin later). Use INT_MAX if you don't know how many items you have (in which case the cursor won't be advanced in the final step). + // items_height: Use -1.0f to be calculated automatically on first step. Otherwise pass in the distance between your items, typically GetTextLineHeightWithSpacing() or GetFrameHeightWithSpacing(). + // If you don't specify an items_height, you NEED to call Step(). If you specify items_height you may call the old Begin()/End() api directly, but prefer calling Step(). + ImGuiListClipper(int items_count = -1, float items_height = -1.0f) { Begin(items_count, items_height); } // NB: Begin() initialize every fields (as we allow user to call Begin/End multiple times on a same instance if they want). + ~ImGuiListClipper() { IM_ASSERT(ItemsCount == -1); } // Assert if user forgot to call End() or Step() until false. - IMGUI_API bool Step(); // Call until it returns false. The DisplayStart/DisplayEnd fields will be set and you can process/draw those items. - IMGUI_API void Begin(int items_count, float items_height = -1.0f); // Automatically called by constructor if you passed 'items_count' or by Step() in Step 1. - IMGUI_API void End(); // Automatically called on the last call of Step() that returns false. + IMGUI_API bool Step(); // Call until it returns false. The DisplayStart/DisplayEnd fields will be set and you can process/draw those items. + IMGUI_API void Begin(int items_count, float items_height = -1.0f); // Automatically called by constructor if you passed 'items_count' or by Step() in Step 1. + IMGUI_API void End(); // Automatically called on the last call of Step() that returns false. }; //----------------------------------------------------------------------------- @@ -1415,13 +1637,20 @@ typedef void (*ImDrawCallback)(const ImDrawList* parent_list, const ImDrawCmd* c // Typically, 1 command = 1 GPU draw call (unless command is a callback) struct ImDrawCmd { - unsigned int ElemCount; // Number of indices (multiple of 3) to be rendered as triangles. Vertices are stored in the callee ImDrawList's vtx_buffer[] array, indices in idx_buffer[]. - ImVec4 ClipRect; // Clipping rectangle (x1, y1, x2, y2) - ImTextureID TextureId; // User-provided texture ID. Set by user in ImfontAtlas::SetTexID() for fonts or passed to Image*() functions. Ignore if never using images or multiple fonts atlas. - ImDrawCallback UserCallback; // If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally. - void* UserCallbackData; // The draw callback code can access this. + unsigned int ElemCount; // Number of indices (multiple of 3) to be rendered as triangles. Vertices are stored in the callee ImDrawList's vtx_buffer[] array, indices in idx_buffer[]. + ImVec4 ClipRect; // Clipping rectangle (x1, y1, x2, y2) + ImTextureID TextureId; // User-provided texture ID. Set by user in ImfontAtlas::SetTexID() for fonts or passed to Image*() functions. Ignore if never using images or multiple fonts atlas. + ImDrawCallback UserCallback; // If != NULL, call the function instead of rendering the vertices. clip_rect and texture_id will be set normally. + void* UserCallbackData; // The draw callback code can access this. - ImDrawCmd() { ElemCount = 0; ClipRect.x = ClipRect.y = ClipRect.z = ClipRect.w = 0.0f; TextureId = NULL; UserCallback = NULL; UserCallbackData = NULL; } + ImDrawCmd() + { + ElemCount = 0; + ClipRect.x = ClipRect.y = ClipRect.z = ClipRect.w = 0.0f; + TextureId = NULL; + UserCallback = NULL; + UserCallbackData = NULL; + } }; // Vertex index (override with '#define ImDrawIdx unsigned int' inside in imconfig.h) @@ -1433,15 +1662,15 @@ typedef unsigned short ImDrawIdx; #ifndef IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT struct ImDrawVert { - ImVec2 pos; - ImVec2 uv; - ImU32 col; + ImVec2 pos; + ImVec2 uv; + ImU32 col; }; #else // You can override the vertex format layout by defining IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT in imconfig.h // The code expect ImVec2 pos (8 bytes), ImVec2 uv (8 bytes), ImU32 col (4 bytes), but you can re-order them or add other fields as needed to simplify integration in your engine. // The type has to be described within the macro (you can either declare the struct or use a typedef) -// NOTE: IMGUI DOESN'T CLEAR THE STRUCTURE AND DOESN'T CALL A CONSTRUCTOR SO ANY CUSTOM FIELD WILL BE UNINITIALIZED. IF YOU ADD EXTRA FIELDS (SUCH AS A 'Z' COORDINATES) YOU WILL NEED TO CLEAR THEM DURING RENDER OR TO IGNORE THEM. +// NOTE: IMGUI DOESN'T CLEAR THE STRUCTURE AND DOESN'T CALL A CONSTRUCTOR SO ANY CUSTOM FIELD WILL BE UNINITIALIZED. IF YOU ADD EXTRA FIELDS (SUCH AS A 'Z' COORDINATES) YOU WILL NEED TO CLEAR THEM DURING RENDER OR TO IGNORE THEM. IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT; #endif @@ -1449,27 +1678,27 @@ IMGUI_OVERRIDE_DRAWVERT_STRUCT_LAYOUT; // You can also use them to simulate drawing layers and submit primitives in a different order than how they will be rendered. struct ImDrawChannel { - ImVector CmdBuffer; - ImVector IdxBuffer; + ImVector CmdBuffer; + ImVector IdxBuffer; }; enum ImDrawCornerFlags_ { - ImDrawCornerFlags_TopLeft = 1 << 0, // 0x1 - ImDrawCornerFlags_TopRight = 1 << 1, // 0x2 - ImDrawCornerFlags_BotLeft = 1 << 2, // 0x4 - ImDrawCornerFlags_BotRight = 1 << 3, // 0x8 - ImDrawCornerFlags_Top = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_TopRight, // 0x3 - ImDrawCornerFlags_Bot = ImDrawCornerFlags_BotLeft | ImDrawCornerFlags_BotRight, // 0xC - ImDrawCornerFlags_Left = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotLeft, // 0x5 - ImDrawCornerFlags_Right = ImDrawCornerFlags_TopRight | ImDrawCornerFlags_BotRight, // 0xA - ImDrawCornerFlags_All = 0xF // In your function calls you may use ~0 (= all bits sets) instead of ImDrawCornerFlags_All, as a convenience + ImDrawCornerFlags_TopLeft = 1 << 0, // 0x1 + ImDrawCornerFlags_TopRight = 1 << 1, // 0x2 + ImDrawCornerFlags_BotLeft = 1 << 2, // 0x4 + ImDrawCornerFlags_BotRight = 1 << 3, // 0x8 + ImDrawCornerFlags_Top = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_TopRight, // 0x3 + ImDrawCornerFlags_Bot = ImDrawCornerFlags_BotLeft | ImDrawCornerFlags_BotRight, // 0xC + ImDrawCornerFlags_Left = ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotLeft, // 0x5 + ImDrawCornerFlags_Right = ImDrawCornerFlags_TopRight | ImDrawCornerFlags_BotRight, // 0xA + ImDrawCornerFlags_All = 0xF // In your function calls you may use ~0 (= all bits sets) instead of ImDrawCornerFlags_All, as a convenience }; enum ImDrawListFlags_ { - ImDrawListFlags_AntiAliasedLines = 1 << 0, - ImDrawListFlags_AntiAliasedFill = 1 << 1 + ImDrawListFlags_AntiAliasedLines = 1 << 0, + ImDrawListFlags_AntiAliasedFill = 1 << 1 }; // Draw command list @@ -1480,144 +1709,188 @@ enum ImDrawListFlags_ // Important: Primitives are always added to the list and not culled (culling is done at higher-level by ImGui:: functions), if you use this API a lot consider coarse culling your drawn objects. struct ImDrawList { - // This is what you have to render - ImVector CmdBuffer; // Draw commands. Typically 1 command = 1 GPU draw call, unless the command is a callback. - ImVector IdxBuffer; // Index buffer. Each command consume ImDrawCmd::ElemCount of those - ImVector VtxBuffer; // Vertex buffer. + // This is what you have to render + ImVector CmdBuffer; // Draw commands. Typically 1 command = 1 GPU draw call, unless the command is a callback. + ImVector IdxBuffer; // Index buffer. Each command consume ImDrawCmd::ElemCount of those + ImVector VtxBuffer; // Vertex buffer. - // [Internal, used while building lists] - ImDrawListFlags Flags; // Flags, you may poke into these to adjust anti-aliasing settings per-primitive. - const ImDrawListSharedData* _Data; // Pointer to shared draw data (you can use ImGui::GetDrawListSharedData() to get the one from current ImGui context) - const char* _OwnerName; // Pointer to owner window's name for debugging - unsigned int _VtxCurrentIdx; // [Internal] == VtxBuffer.Size - ImDrawVert* _VtxWritePtr; // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much) - ImDrawIdx* _IdxWritePtr; // [Internal] point within IdxBuffer.Data after each add command (to avoid using the ImVector<> operators too much) - ImVector _ClipRectStack; // [Internal] - ImVector _TextureIdStack; // [Internal] - ImVector _Path; // [Internal] current path building - int _ChannelsCurrent; // [Internal] current channel number (0) - int _ChannelsCount; // [Internal] number of active channels (1+) - ImVector _Channels; // [Internal] draw channels for columns API (not resized down so _ChannelsCount may be smaller than _Channels.Size) + // [Internal, used while building lists] + ImDrawListFlags Flags; // Flags, you may poke into these to adjust anti-aliasing settings per-primitive. + const ImDrawListSharedData* _Data; // Pointer to shared draw data (you can use ImGui::GetDrawListSharedData() to get the one from current ImGui context) + const char* _OwnerName; // Pointer to owner window's name for debugging + unsigned int _VtxCurrentIdx; // [Internal] == VtxBuffer.Size + ImDrawVert* _VtxWritePtr; // [Internal] point within VtxBuffer.Data after each add command (to avoid using the ImVector<> operators too much) + ImDrawIdx* _IdxWritePtr; // [Internal] point within IdxBuffer.Data after each add command (to avoid using the ImVector<> operators too much) + ImVector _ClipRectStack; // [Internal] + ImVector _TextureIdStack; // [Internal] + ImVector _Path; // [Internal] current path building + int _ChannelsCurrent; // [Internal] current channel number (0) + int _ChannelsCount; // [Internal] number of active channels (1+) + ImVector _Channels; // [Internal] draw channels for columns API (not resized down so _ChannelsCount may be smaller than _Channels.Size) - // If you want to create ImDrawList instances, pass them ImGui::GetDrawListSharedData() or create and use your own ImDrawListSharedData (so you can use ImDrawList without ImGui) - ImDrawList(const ImDrawListSharedData* shared_data) { _Data = shared_data; _OwnerName = NULL; Clear(); } - ~ImDrawList() { ClearFreeMemory(); } - IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) - IMGUI_API void PushClipRectFullScreen(); - IMGUI_API void PopClipRect(); - IMGUI_API void PushTextureID(ImTextureID texture_id); - IMGUI_API void PopTextureID(); - inline ImVec2 GetClipRectMin() const { const ImVec4& cr = _ClipRectStack.back(); return ImVec2(cr.x, cr.y); } - inline ImVec2 GetClipRectMax() const { const ImVec4& cr = _ClipRectStack.back(); return ImVec2(cr.z, cr.w); } + // If you want to create ImDrawList instances, pass them ImGui::GetDrawListSharedData() or create and use your own ImDrawListSharedData (so you can use ImDrawList without ImGui) + ImDrawList(const ImDrawListSharedData* shared_data) + { + _Data = shared_data; + _OwnerName = NULL; + Clear(); + } + ~ImDrawList() { ClearFreeMemory(); } + IMGUI_API void PushClipRect(ImVec2 clip_rect_min, ImVec2 clip_rect_max, bool intersect_with_current_clip_rect = false); // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) + IMGUI_API void PushClipRectFullScreen(); + IMGUI_API void PopClipRect(); + IMGUI_API void PushTextureID(ImTextureID texture_id); + IMGUI_API void PopTextureID(); + inline ImVec2 GetClipRectMin() const + { + const ImVec4& cr = _ClipRectStack.back(); + return ImVec2(cr.x, cr.y); + } + inline ImVec2 GetClipRectMax() const + { + const ImVec4& cr = _ClipRectStack.back(); + return ImVec2(cr.z, cr.w); + } - // Primitives - IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f); - IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners_flags = ImDrawCornerFlags_All, float thickness = 1.0f); // a: upper-left, b: lower-right, rounding_corners_flags: 4-bits corresponding to which corner to round - IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners_flags = ImDrawCornerFlags_All); // a: upper-left, b: lower-right - IMGUI_API void AddRectFilledMultiColor(const ImVec2& a, const ImVec2& b, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left); - IMGUI_API void AddQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col, float thickness = 1.0f); - IMGUI_API void AddQuadFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col); - IMGUI_API void AddTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col, float thickness = 1.0f); - IMGUI_API void AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col); - IMGUI_API void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12, float thickness = 1.0f); - IMGUI_API void AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); - IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL); - IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL); - IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,1), ImU32 col = 0xFFFFFFFF); - IMGUI_API void AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a = ImVec2(0,0), const ImVec2& uv_b = ImVec2(1,0), const ImVec2& uv_c = ImVec2(1,1), const ImVec2& uv_d = ImVec2(0,1), ImU32 col = 0xFFFFFFFF); - IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, float rounding, int rounding_corners = ImDrawCornerFlags_All); - IMGUI_API void AddPolyline(const ImVec2* points, const int num_points, ImU32 col, bool closed, float thickness); - IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col); - IMGUI_API void AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0); + // Primitives + IMGUI_API void AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness = 1.0f); + IMGUI_API void AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners_flags = ImDrawCornerFlags_All, float thickness = 1.0f); // a: upper-left, b: lower-right, rounding_corners_flags: 4-bits corresponding to which corner to round + IMGUI_API void AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding = 0.0f, int rounding_corners_flags = ImDrawCornerFlags_All); // a: upper-left, b: lower-right + IMGUI_API void AddRectFilledMultiColor(const ImVec2& a, const ImVec2& b, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left); + IMGUI_API void AddQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col, float thickness = 1.0f); + IMGUI_API void AddQuadFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col); + IMGUI_API void AddTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col, float thickness = 1.0f); + IMGUI_API void AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col); + IMGUI_API void AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12, float thickness = 1.0f); + IMGUI_API void AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments = 12); + IMGUI_API void AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL); + IMGUI_API void AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end = NULL, float wrap_width = 0.0f, const ImVec4* cpu_fine_clip_rect = NULL); + IMGUI_API void AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a = ImVec2(0, 0), const ImVec2& uv_b = ImVec2(1, 1), ImU32 col = 0xFFFFFFFF); + IMGUI_API void AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a = ImVec2(0, 0), const ImVec2& uv_b = ImVec2(1, 0), const ImVec2& uv_c = ImVec2(1, 1), const ImVec2& uv_d = ImVec2(0, 1), ImU32 col = 0xFFFFFFFF); + IMGUI_API void AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, float rounding, int rounding_corners = ImDrawCornerFlags_All); + IMGUI_API void AddPolyline(const ImVec2* points, const int num_points, ImU32 col, bool closed, float thickness); + IMGUI_API void AddConvexPolyFilled(const ImVec2* points, const int num_points, ImU32 col); + IMGUI_API void AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments = 0); - // Stateful path API, add points then finish with PathFill() or PathStroke() - inline void PathClear() { _Path.resize(0); } - inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); } - inline void PathLineToMergeDuplicate(const ImVec2& pos) { if (_Path.Size == 0 || memcmp(&_Path[_Path.Size-1], &pos, 8) != 0) _Path.push_back(pos); } - inline void PathFillConvex(ImU32 col) { AddConvexPolyFilled(_Path.Data, _Path.Size, col); PathClear(); } - inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) { AddPolyline(_Path.Data, _Path.Size, col, closed, thickness); PathClear(); } - IMGUI_API void PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10); - IMGUI_API void PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle - IMGUI_API void PathBezierCurveTo(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, int num_segments = 0); - IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, int rounding_corners_flags = ImDrawCornerFlags_All); + // Stateful path API, add points then finish with PathFill() or PathStroke() + inline void PathClear() { _Path.resize(0); } + inline void PathLineTo(const ImVec2& pos) { _Path.push_back(pos); } + inline void PathLineToMergeDuplicate(const ImVec2& pos) + { + if (_Path.Size == 0 || memcmp(&_Path[_Path.Size - 1], &pos, 8) != 0) _Path.push_back(pos); + } + inline void PathFillConvex(ImU32 col) + { + AddConvexPolyFilled(_Path.Data, _Path.Size, col); + PathClear(); + } + inline void PathStroke(ImU32 col, bool closed, float thickness = 1.0f) + { + AddPolyline(_Path.Data, _Path.Size, col, closed, thickness); + PathClear(); + } + IMGUI_API void PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments = 10); + IMGUI_API void PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12); // Use precomputed angles for a 12 steps circle + IMGUI_API void PathBezierCurveTo(const ImVec2& p1, const ImVec2& p2, const ImVec2& p3, int num_segments = 0); + IMGUI_API void PathRect(const ImVec2& rect_min, const ImVec2& rect_max, float rounding = 0.0f, int rounding_corners_flags = ImDrawCornerFlags_All); - // Channels - // - Use to simulate layers. By switching channels to can render out-of-order (e.g. submit foreground primitives before background primitives) - // - Use to minimize draw calls (e.g. if going back-and-forth between multiple non-overlapping clipping rectangles, prefer to append into separate channels then merge at the end) - IMGUI_API void ChannelsSplit(int channels_count); - IMGUI_API void ChannelsMerge(); - IMGUI_API void ChannelsSetCurrent(int channel_index); + // Channels + // - Use to simulate layers. By switching channels to can render out-of-order (e.g. submit foreground primitives before background primitives) + // - Use to minimize draw calls (e.g. if going back-and-forth between multiple non-overlapping clipping rectangles, prefer to append into separate channels then merge at the end) + IMGUI_API void ChannelsSplit(int channels_count); + IMGUI_API void ChannelsMerge(); + IMGUI_API void ChannelsSetCurrent(int channel_index); - // Advanced - IMGUI_API void AddCallback(ImDrawCallback callback, void* callback_data); // Your rendering function must check for 'UserCallback' in ImDrawCmd and call the function instead of rendering triangles. - IMGUI_API void AddDrawCmd(); // This is useful if you need to forcefully create a new draw call (to allow for dependent rendering / blending). Otherwise primitives are merged into the same draw-call as much as possible + // Advanced + IMGUI_API void AddCallback(ImDrawCallback callback, void* callback_data); // Your rendering function must check for 'UserCallback' in ImDrawCmd and call the function instead of rendering triangles. + IMGUI_API void AddDrawCmd(); // This is useful if you need to forcefully create a new draw call (to allow for dependent rendering / blending). Otherwise primitives are merged into the same draw-call as much as possible - // Internal helpers - // NB: all primitives needs to be reserved via PrimReserve() beforehand! - IMGUI_API void Clear(); - IMGUI_API void ClearFreeMemory(); - IMGUI_API void PrimReserve(int idx_count, int vtx_count); - IMGUI_API void PrimRect(const ImVec2& a, const ImVec2& b, ImU32 col); // Axis aligned rectangle (composed of two triangles) - IMGUI_API void PrimRectUV(const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col); - IMGUI_API void PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a, const ImVec2& uv_b, const ImVec2& uv_c, const ImVec2& uv_d, ImU32 col); - inline void PrimWriteVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col){ _VtxWritePtr->pos = pos; _VtxWritePtr->uv = uv; _VtxWritePtr->col = col; _VtxWritePtr++; _VtxCurrentIdx++; } - inline void PrimWriteIdx(ImDrawIdx idx) { *_IdxWritePtr = idx; _IdxWritePtr++; } - inline void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) { PrimWriteIdx((ImDrawIdx)_VtxCurrentIdx); PrimWriteVtx(pos, uv, col); } - IMGUI_API void UpdateClipRect(); - IMGUI_API void UpdateTextureID(); + // Internal helpers + // NB: all primitives needs to be reserved via PrimReserve() beforehand! + IMGUI_API void Clear(); + IMGUI_API void ClearFreeMemory(); + IMGUI_API void PrimReserve(int idx_count, int vtx_count); + IMGUI_API void PrimRect(const ImVec2& a, const ImVec2& b, ImU32 col); // Axis aligned rectangle (composed of two triangles) + IMGUI_API void PrimRectUV(const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col); + IMGUI_API void PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a, const ImVec2& uv_b, const ImVec2& uv_c, const ImVec2& uv_d, ImU32 col); + inline void PrimWriteVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) + { + _VtxWritePtr->pos = pos; + _VtxWritePtr->uv = uv; + _VtxWritePtr->col = col; + _VtxWritePtr++; + _VtxCurrentIdx++; + } + inline void PrimWriteIdx(ImDrawIdx idx) + { + *_IdxWritePtr = idx; + _IdxWritePtr++; + } + inline void PrimVtx(const ImVec2& pos, const ImVec2& uv, ImU32 col) + { + PrimWriteIdx((ImDrawIdx)_VtxCurrentIdx); + PrimWriteVtx(pos, uv, col); + } + IMGUI_API void UpdateClipRect(); + IMGUI_API void UpdateTextureID(); }; // All draw data to render an ImGui frame struct ImDrawData { - bool Valid; // Only valid after Render() is called and before the next NewFrame() is called. - ImDrawList** CmdLists; - int CmdListsCount; - int TotalVtxCount; // For convenience, sum of all cmd_lists vtx_buffer.Size - int TotalIdxCount; // For convenience, sum of all cmd_lists idx_buffer.Size + bool Valid; // Only valid after Render() is called and before the next NewFrame() is called. + ImDrawList** CmdLists; + int CmdListsCount; + int TotalVtxCount; // For convenience, sum of all cmd_lists vtx_buffer.Size + int TotalIdxCount; // For convenience, sum of all cmd_lists idx_buffer.Size - // Functions - ImDrawData() { Clear(); } - void Clear() { Valid = false; CmdLists = NULL; CmdListsCount = TotalVtxCount = TotalIdxCount = 0; } // Draw lists are owned by the ImGuiContext and only pointed to here. - IMGUI_API void DeIndexAllBuffers(); // For backward compatibility or convenience: convert all buffers from indexed to de-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering! - IMGUI_API void ScaleClipRects(const ImVec2& sc); // Helper to scale the ClipRect field of each ImDrawCmd. Use if your final output buffer is at a different scale than ImGui expects, or if there is a difference between your window resolution and framebuffer resolution. + // Functions + ImDrawData() { Clear(); } + void Clear() + { + Valid = false; + CmdLists = NULL; + CmdListsCount = TotalVtxCount = TotalIdxCount = 0; + } // Draw lists are owned by the ImGuiContext and only pointed to here. + IMGUI_API void DeIndexAllBuffers(); // For backward compatibility or convenience: convert all buffers from indexed to de-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering! + IMGUI_API void ScaleClipRects(const ImVec2& sc); // Helper to scale the ClipRect field of each ImDrawCmd. Use if your final output buffer is at a different scale than ImGui expects, or if there is a difference between your window resolution and framebuffer resolution. }; struct ImFontConfig { - void* FontData; // // TTF/OTF data - int FontDataSize; // // TTF/OTF data size - bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself). - int FontNo; // 0 // Index of font within TTF/OTF file - float SizePixels; // // Size in pixels for rasterizer. - int OversampleH, OversampleV; // 3, 1 // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis. - bool PixelSnapH; // false // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1. - ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs. Only X axis is supported for now. - ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input. - const ImWchar* GlyphRanges; // NULL // Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. - bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights. - unsigned int RasterizerFlags; // 0x00 // Settings for custom font rasterizer (e.g. ImGuiFreeType). Leave as zero if you aren't using one. - float RasterizerMultiply; // 1.0f // Brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable. + void* FontData; // // TTF/OTF data + int FontDataSize; // // TTF/OTF data size + bool FontDataOwnedByAtlas; // true // TTF/OTF data ownership taken by the container ImFontAtlas (will delete memory itself). + int FontNo; // 0 // Index of font within TTF/OTF file + float SizePixels; // // Size in pixels for rasterizer. + int OversampleH, OversampleV; // 3, 1 // Rasterize at higher quality for sub-pixel positioning. We don't use sub-pixel positions on the Y axis. + bool PixelSnapH; // false // Align every glyph to pixel boundary. Useful e.g. if you are merging a non-pixel aligned font with the default font. If enabled, you can set OversampleH/V to 1. + ImVec2 GlyphExtraSpacing; // 0, 0 // Extra spacing (in pixels) between glyphs. Only X axis is supported for now. + ImVec2 GlyphOffset; // 0, 0 // Offset all glyphs from this font input. + const ImWchar* GlyphRanges; // NULL // Pointer to a user-provided list of Unicode range (2 value per range, values are inclusive, zero-terminated list). THE ARRAY DATA NEEDS TO PERSIST AS LONG AS THE FONT IS ALIVE. + bool MergeMode; // false // Merge into previous ImFont, so you can combine multiple inputs font into one ImFont (e.g. ASCII font + icons + Japanese glyphs). You may want to use GlyphOffset.y when merge font of different heights. + unsigned int RasterizerFlags; // 0x00 // Settings for custom font rasterizer (e.g. ImGuiFreeType). Leave as zero if you aren't using one. + float RasterizerMultiply; // 1.0f // Brighten (>1.0f) or darken (<1.0f) font output. Brightening small fonts may be a good workaround to make them more readable. - // [Internal] - char Name[32]; // Name (strictly to ease debugging) - ImFont* DstFont; + // [Internal] + char Name[32]; // Name (strictly to ease debugging) + ImFont* DstFont; - IMGUI_API ImFontConfig(); + IMGUI_API ImFontConfig(); }; struct ImFontGlyph { - ImWchar Codepoint; // 0x0000..0xFFFF - float AdvanceX; // Distance to next character (= data from font + ImFontConfig::GlyphExtraSpacing.x baked in) - float X0, Y0, X1, Y1; // Glyph corners - float U0, V0, U1, V1; // Texture coordinates + ImWchar Codepoint; // 0x0000..0xFFFF + float AdvanceX; // Distance to next character (= data from font + ImFontConfig::GlyphExtraSpacing.x baked in) + float X0, Y0, X1, Y1; // Glyph corners + float U0, V0, U1, V1; // Texture coordinates }; enum ImFontAtlasFlags_ { - ImFontAtlasFlags_NoPowerOfTwoHeight = 1 << 0, // Don't round the height to next power of two - ImFontAtlasFlags_NoMouseCursors = 1 << 1 // Don't build software mouse cursors into the atlas + ImFontAtlasFlags_NoPowerOfTwoHeight = 1 << 0, // Don't round the height to next power of two + ImFontAtlasFlags_NoMouseCursors = 1 << 1 // Don't build software mouse cursors into the atlas }; // Load and rasterize multiple TTF/OTF fonts into a same texture. @@ -1630,150 +1903,166 @@ enum ImFontAtlasFlags_ // IMPORTANT: If you pass a 'glyph_ranges' array to AddFont*** functions, you need to make sure that your array persist up until the ImFont is build (when calling GetTextData*** or Build()). We only copy the pointer, not the data. struct ImFontAtlas { - IMGUI_API ImFontAtlas(); - IMGUI_API ~ImFontAtlas(); - IMGUI_API ImFont* AddFont(const ImFontConfig* font_cfg); - IMGUI_API ImFont* AddFontDefault(const ImFontConfig* font_cfg = NULL); - IMGUI_API ImFont* AddFontFromFileTTF(const char* filename, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); - IMGUI_API ImFont* AddFontFromMemoryTTF(void* font_data, int font_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // Note: Transfer ownership of 'ttf_data' to ImFontAtlas! Will be deleted after Build(). Set font_cfg->FontDataOwnedByAtlas to false to keep ownership. - IMGUI_API ImFont* AddFontFromMemoryCompressedTTF(const void* compressed_font_data, int compressed_font_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data' still owned by caller. Compress with binary_to_compressed_c.cpp. - IMGUI_API ImFont* AddFontFromMemoryCompressedBase85TTF(const char* compressed_font_data_base85, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data_base85' still owned by caller. Compress with binary_to_compressed_c.cpp with -base85 parameter. - IMGUI_API void ClearTexData(); // Clear the CPU-side texture data. Saves RAM once the texture has been copied to graphics memory. - IMGUI_API void ClearInputData(); // Clear the input TTF data (inc sizes, glyph ranges) - IMGUI_API void ClearFonts(); // Clear the ImGui-side font data (glyphs storage, UV coordinates) - IMGUI_API void Clear(); // Clear all + IMGUI_API ImFontAtlas(); + IMGUI_API ~ImFontAtlas(); + IMGUI_API ImFont* AddFont(const ImFontConfig* font_cfg); + IMGUI_API ImFont* AddFontDefault(const ImFontConfig* font_cfg = NULL); + IMGUI_API ImFont* AddFontFromFileTTF(const char* filename, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); + IMGUI_API ImFont* AddFontFromMemoryTTF(void* font_data, int font_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // Note: Transfer ownership of 'ttf_data' to ImFontAtlas! Will be deleted after Build(). Set font_cfg->FontDataOwnedByAtlas to false to keep ownership. + IMGUI_API ImFont* AddFontFromMemoryCompressedTTF(const void* compressed_font_data, int compressed_font_size, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data' still owned by caller. Compress with binary_to_compressed_c.cpp. + IMGUI_API ImFont* AddFontFromMemoryCompressedBase85TTF(const char* compressed_font_data_base85, float size_pixels, const ImFontConfig* font_cfg = NULL, const ImWchar* glyph_ranges = NULL); // 'compressed_font_data_base85' still owned by caller. Compress with binary_to_compressed_c.cpp with -base85 parameter. + IMGUI_API void ClearTexData(); // Clear the CPU-side texture data. Saves RAM once the texture has been copied to graphics memory. + IMGUI_API void ClearInputData(); // Clear the input TTF data (inc sizes, glyph ranges) + IMGUI_API void ClearFonts(); // Clear the ImGui-side font data (glyphs storage, UV coordinates) + IMGUI_API void Clear(); // Clear all - // Build atlas, retrieve pixel data. - // User is in charge of copying the pixels into graphics memory (e.g. create a texture with your engine). Then store your texture handle with SetTexID(). - // RGBA32 format is provided for convenience and compatibility, but note that unless you use CustomRect to draw color data, the RGB pixels emitted from Fonts will all be white (~75% of waste). - // Pitch = Width * BytesPerPixels - IMGUI_API bool Build(); // Build pixels data. This is called automatically for you by the GetTexData*** functions. - IMGUI_API void GetTexDataAsAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 1 byte per-pixel - IMGUI_API void GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 4 bytes-per-pixel - void SetTexID(ImTextureID id) { TexID = id; } + // Build atlas, retrieve pixel data. + // User is in charge of copying the pixels into graphics memory (e.g. create a texture with your engine). Then store your texture handle with SetTexID(). + // RGBA32 format is provided for convenience and compatibility, but note that unless you use CustomRect to draw color data, the RGB pixels emitted from Fonts will all be white (~75% of waste). + // Pitch = Width * BytesPerPixels + IMGUI_API bool Build(); // Build pixels data. This is called automatically for you by the GetTexData*** functions. + IMGUI_API void GetTexDataAsAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 1 byte per-pixel + IMGUI_API void GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel = NULL); // 4 bytes-per-pixel + void SetTexID(ImTextureID id) { TexID = id; } - //------------------------------------------- - // Glyph Ranges - //------------------------------------------- + //------------------------------------------- + // Glyph Ranges + //------------------------------------------- - // Helpers to retrieve list of common Unicode ranges (2 value per range, values are inclusive, zero-terminated list) - // NB: Make sure that your string are UTF-8 and NOT in your local code page. In C++11, you can create UTF-8 string literal using the u8"Hello world" syntax. See FAQ for details. - IMGUI_API const ImWchar* GetGlyphRangesDefault(); // Basic Latin, Extended Latin - IMGUI_API const ImWchar* GetGlyphRangesKorean(); // Default + Korean characters - IMGUI_API const ImWchar* GetGlyphRangesJapanese(); // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs - IMGUI_API const ImWchar* GetGlyphRangesChinese(); // Default + Japanese + full set of about 21000 CJK Unified Ideographs - IMGUI_API const ImWchar* GetGlyphRangesCyrillic(); // Default + about 400 Cyrillic characters - IMGUI_API const ImWchar* GetGlyphRangesThai(); // Default + Thai characters + // Helpers to retrieve list of common Unicode ranges (2 value per range, values are inclusive, zero-terminated list) + // NB: Make sure that your string are UTF-8 and NOT in your local code page. In C++11, you can create UTF-8 string literal using the u8"Hello world" syntax. See FAQ for details. + IMGUI_API const ImWchar* GetGlyphRangesDefault(); // Basic Latin, Extended Latin + IMGUI_API const ImWchar* GetGlyphRangesKorean(); // Default + Korean characters + IMGUI_API const ImWchar* GetGlyphRangesJapanese(); // Default + Hiragana, Katakana, Half-Width, Selection of 1946 Ideographs + IMGUI_API const ImWchar* GetGlyphRangesChinese(); // Default + Japanese + full set of about 21000 CJK Unified Ideographs + IMGUI_API const ImWchar* GetGlyphRangesCyrillic(); // Default + about 400 Cyrillic characters + IMGUI_API const ImWchar* GetGlyphRangesThai(); // Default + Thai characters - // Helpers to build glyph ranges from text data. Feed your application strings/characters to it then call BuildRanges(). - struct GlyphRangesBuilder - { - ImVector UsedChars; // Store 1-bit per Unicode code point (0=unused, 1=used) - GlyphRangesBuilder() { UsedChars.resize(0x10000 / 8); memset(UsedChars.Data, 0, 0x10000 / 8); } - bool GetBit(int n) { return (UsedChars[n >> 3] & (1 << (n & 7))) != 0; } - void SetBit(int n) { UsedChars[n >> 3] |= 1 << (n & 7); } // Set bit 'c' in the array - void AddChar(ImWchar c) { SetBit(c); } // Add character - IMGUI_API void AddText(const char* text, const char* text_end = NULL); // Add string (each character of the UTF-8 string are added) - IMGUI_API void AddRanges(const ImWchar* ranges); // Add ranges, e.g. builder.AddRanges(ImFontAtlas::GetGlyphRangesDefault) to force add all of ASCII/Latin+Ext - IMGUI_API void BuildRanges(ImVector* out_ranges); // Output new ranges - }; + // Helpers to build glyph ranges from text data. Feed your application strings/characters to it then call BuildRanges(). + struct GlyphRangesBuilder + { + ImVector UsedChars; // Store 1-bit per Unicode code point (0=unused, 1=used) + GlyphRangesBuilder() + { + UsedChars.resize(0x10000 / 8); + memset(UsedChars.Data, 0, 0x10000 / 8); + } + bool GetBit(int n) { return (UsedChars[n >> 3] & (1 << (n & 7))) != 0; } + void SetBit(int n) { UsedChars[n >> 3] |= 1 << (n & 7); } // Set bit 'c' in the array + void AddChar(ImWchar c) { SetBit(c); } // Add character + IMGUI_API void AddText(const char* text, const char* text_end = NULL); // Add string (each character of the UTF-8 string are added) + IMGUI_API void AddRanges(const ImWchar* ranges); // Add ranges, e.g. builder.AddRanges(ImFontAtlas::GetGlyphRangesDefault) to force add all of ASCII/Latin+Ext + IMGUI_API void BuildRanges(ImVector* out_ranges); // Output new ranges + }; - //------------------------------------------- - // Custom Rectangles/Glyphs API - //------------------------------------------- + //------------------------------------------- + // Custom Rectangles/Glyphs API + //------------------------------------------- - // You can request arbitrary rectangles to be packed into the atlas, for your own purposes. After calling Build(), you can query the rectangle position and render your pixels. - // You can also request your rectangles to be mapped as font glyph (given a font + Unicode point), so you can render e.g. custom colorful icons and use them as regular glyphs. - struct CustomRect - { - unsigned int ID; // Input // User ID. Use <0x10000 to map into a font glyph, >=0x10000 for other/internal/custom texture data. - unsigned short Width, Height; // Input // Desired rectangle dimension - unsigned short X, Y; // Output // Packed position in Atlas - float GlyphAdvanceX; // Input // For custom font glyphs only (ID<0x10000): glyph xadvance - ImVec2 GlyphOffset; // Input // For custom font glyphs only (ID<0x10000): glyph display offset - ImFont* Font; // Input // For custom font glyphs only (ID<0x10000): target font - CustomRect() { ID = 0xFFFFFFFF; Width = Height = 0; X = Y = 0xFFFF; GlyphAdvanceX = 0.0f; GlyphOffset = ImVec2(0,0); Font = NULL; } - bool IsPacked() const { return X != 0xFFFF; } - }; + // You can request arbitrary rectangles to be packed into the atlas, for your own purposes. After calling Build(), you can query the rectangle position and render your pixels. + // You can also request your rectangles to be mapped as font glyph (given a font + Unicode point), so you can render e.g. custom colorful icons and use them as regular glyphs. + struct CustomRect + { + unsigned int ID; // Input // User ID. Use <0x10000 to map into a font glyph, >=0x10000 for other/internal/custom texture data. + unsigned short Width, Height; // Input // Desired rectangle dimension + unsigned short X, Y; // Output // Packed position in Atlas + float GlyphAdvanceX; // Input // For custom font glyphs only (ID<0x10000): glyph xadvance + ImVec2 GlyphOffset; // Input // For custom font glyphs only (ID<0x10000): glyph display offset + ImFont* Font; // Input // For custom font glyphs only (ID<0x10000): target font + CustomRect() + { + ID = 0xFFFFFFFF; + Width = Height = 0; + X = Y = 0xFFFF; + GlyphAdvanceX = 0.0f; + GlyphOffset = ImVec2(0, 0); + Font = NULL; + } + bool IsPacked() const { return X != 0xFFFF; } + }; - IMGUI_API int AddCustomRectRegular(unsigned int id, int width, int height); // Id needs to be >= 0x10000. Id >= 0x80000000 are reserved for ImGui and ImDrawList - IMGUI_API int AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset = ImVec2(0,0)); // Id needs to be < 0x10000 to register a rectangle to map into a specific font. - const CustomRect* GetCustomRectByIndex(int index) const { if (index < 0) return NULL; return &CustomRects[index]; } + IMGUI_API int AddCustomRectRegular(unsigned int id, int width, int height); // Id needs to be >= 0x10000. Id >= 0x80000000 are reserved for ImGui and ImDrawList + IMGUI_API int AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset = ImVec2(0, 0)); // Id needs to be < 0x10000 to register a rectangle to map into a specific font. + const CustomRect* GetCustomRectByIndex(int index) const + { + if (index < 0) return NULL; + return &CustomRects[index]; + } - // Internals - IMGUI_API void CalcCustomRectUV(const CustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max); - IMGUI_API bool GetMouseCursorTexData(ImGuiMouseCursor cursor, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2]); + // Internals + IMGUI_API void CalcCustomRectUV(const CustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max); + IMGUI_API bool GetMouseCursorTexData(ImGuiMouseCursor cursor, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2]); - //------------------------------------------- - // Members - //------------------------------------------- + //------------------------------------------- + // Members + //------------------------------------------- - ImFontAtlasFlags Flags; // Build flags (see ImFontAtlasFlags_) - ImTextureID TexID; // User data to refer to the texture once it has been uploaded to user's graphic systems. It is passed back to you during rendering via the ImDrawCmd structure. - int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height. - int TexGlyphPadding; // Padding between glyphs within texture in pixels. Defaults to 1. + ImFontAtlasFlags Flags; // Build flags (see ImFontAtlasFlags_) + ImTextureID TexID; // User data to refer to the texture once it has been uploaded to user's graphic systems. It is passed back to you during rendering via the ImDrawCmd structure. + int TexDesiredWidth; // Texture width desired by user before Build(). Must be a power-of-two. If have many glyphs your graphics API have texture size restrictions you may want to increase texture width to decrease height. + int TexGlyphPadding; // Padding between glyphs within texture in pixels. Defaults to 1. - // [Internal] - // NB: Access texture data via GetTexData*() calls! Which will setup a default font for you. - unsigned char* TexPixelsAlpha8; // 1 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight - unsigned int* TexPixelsRGBA32; // 4 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight * 4 - int TexWidth; // Texture width calculated during Build(). - int TexHeight; // Texture height calculated during Build(). - ImVec2 TexUvScale; // = (1.0f/TexWidth, 1.0f/TexHeight) - ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel - ImVector Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font. - ImVector CustomRects; // Rectangles for packing custom texture data into the atlas. - ImVector ConfigData; // Internal data - int CustomRectIds[1]; // Identifiers of custom texture rectangle used by ImFontAtlas/ImDrawList + // [Internal] + // NB: Access texture data via GetTexData*() calls! Which will setup a default font for you. + unsigned char* TexPixelsAlpha8; // 1 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight + unsigned int* TexPixelsRGBA32; // 4 component per pixel, each component is unsigned 8-bit. Total size = TexWidth * TexHeight * 4 + int TexWidth; // Texture width calculated during Build(). + int TexHeight; // Texture height calculated during Build(). + ImVec2 TexUvScale; // = (1.0f/TexWidth, 1.0f/TexHeight) + ImVec2 TexUvWhitePixel; // Texture coordinates to a white pixel + ImVector Fonts; // Hold all the fonts returned by AddFont*. Fonts[0] is the default font upon calling ImGui::NewFrame(), use ImGui::PushFont()/PopFont() to change the current font. + ImVector CustomRects; // Rectangles for packing custom texture data into the atlas. + ImVector ConfigData; // Internal data + int CustomRectIds[1]; // Identifiers of custom texture rectangle used by ImFontAtlas/ImDrawList }; // Font runtime data and rendering // ImFontAtlas automatically loads a default embedded font for you when you call GetTexDataAsAlpha8() or GetTexDataAsRGBA32(). struct ImFont { - // Members: Hot ~62/78 bytes - float FontSize; // // Height of characters, set during loading (don't change after loading) - float Scale; // = 1.f // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale() - ImVec2 DisplayOffset; // = (0.f,1.f) // Offset font rendering by xx pixels - ImVector Glyphs; // // All glyphs. - ImVector IndexAdvanceX; // // Sparse. Glyphs->AdvanceX in a directly indexable way (more cache-friendly, for CalcTextSize functions which are often bottleneck in large UI). - ImVector IndexLookup; // // Sparse. Index glyphs by Unicode code-point. - const ImFontGlyph* FallbackGlyph; // == FindGlyph(FontFallbackChar) - float FallbackAdvanceX; // == FallbackGlyph->AdvanceX - ImWchar FallbackChar; // = '?' // Replacement glyph if one isn't found. Only set via SetFallbackChar() + // Members: Hot ~62/78 bytes + float FontSize; // // Height of characters, set during loading (don't change after loading) + float Scale; // = 1.f // Base font scale, multiplied by the per-window font scale which you can adjust with SetFontScale() + ImVec2 DisplayOffset; // = (0.f,1.f) // Offset font rendering by xx pixels + ImVector Glyphs; // // All glyphs. + ImVector IndexAdvanceX; // // Sparse. Glyphs->AdvanceX in a directly indexable way (more cache-friendly, for CalcTextSize functions which are often bottleneck in large UI). + ImVector IndexLookup; // // Sparse. Index glyphs by Unicode code-point. + const ImFontGlyph* FallbackGlyph; // == FindGlyph(FontFallbackChar) + float FallbackAdvanceX; // == FallbackGlyph->AdvanceX + ImWchar FallbackChar; // = '?' // Replacement glyph if one isn't found. Only set via SetFallbackChar() - // Members: Cold ~18/26 bytes - short ConfigDataCount; // ~ 1 // Number of ImFontConfig involved in creating this font. Bigger than 1 when merging multiple font sources into one ImFont. - ImFontConfig* ConfigData; // // Pointer within ContainerAtlas->ConfigData - ImFontAtlas* ContainerAtlas; // // What we has been loaded into - float Ascent, Descent; // // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize] - int MetricsTotalSurface;// // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs) + // Members: Cold ~18/26 bytes + short ConfigDataCount; // ~ 1 // Number of ImFontConfig involved in creating this font. Bigger than 1 when merging multiple font sources into one ImFont. + ImFontConfig* ConfigData; // // Pointer within ContainerAtlas->ConfigData + ImFontAtlas* ContainerAtlas; // // What we has been loaded into + float Ascent, Descent; // // Ascent: distance from top to bottom of e.g. 'A' [0..FontSize] + int MetricsTotalSurface; // // Total surface in pixels to get an idea of the font rasterization/texture cost (not exact, we approximate the cost of padding between glyphs) - // Methods - IMGUI_API ImFont(); - IMGUI_API ~ImFont(); - IMGUI_API void ClearOutputData(); - IMGUI_API void BuildLookupTable(); - IMGUI_API const ImFontGlyph*FindGlyph(ImWchar c) const; - IMGUI_API void SetFallbackChar(ImWchar c); - float GetCharAdvance(ImWchar c) const { return ((int)c < IndexAdvanceX.Size) ? IndexAdvanceX[(int)c] : FallbackAdvanceX; } - bool IsLoaded() const { return ContainerAtlas != NULL; } - const char* GetDebugName() const { return ConfigData ? ConfigData->Name : ""; } + // Methods + IMGUI_API ImFont(); + IMGUI_API ~ImFont(); + IMGUI_API void ClearOutputData(); + IMGUI_API void BuildLookupTable(); + IMGUI_API const ImFontGlyph* FindGlyph(ImWchar c) const; + IMGUI_API void SetFallbackChar(ImWchar c); + float GetCharAdvance(ImWchar c) const { return ((int)c < IndexAdvanceX.Size) ? IndexAdvanceX[(int)c] : FallbackAdvanceX; } + bool IsLoaded() const { return ContainerAtlas != NULL; } + const char* GetDebugName() const { return ConfigData ? ConfigData->Name : ""; } - // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable. - // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable. - IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8 - IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const; - IMGUI_API void RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, unsigned short c) const; - IMGUI_API void RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const; + // 'max_width' stops rendering after a certain width (could be turned into a 2d size). FLT_MAX to disable. + // 'wrap_width' enable automatic word-wrapping across multiple lines to fit into given width. 0.0f to disable. + IMGUI_API ImVec2 CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end = NULL, const char** remaining = NULL) const; // utf8 + IMGUI_API const char* CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const; + IMGUI_API void RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, unsigned short c) const; + IMGUI_API void RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width = 0.0f, bool cpu_fine_clip = false) const; - // [Internal] - IMGUI_API void GrowIndex(int new_size); - IMGUI_API void AddGlyph(ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x); - IMGUI_API void AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built. + // [Internal] + IMGUI_API void GrowIndex(int new_size); + IMGUI_API void AddGlyph(ImWchar c, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x); + IMGUI_API void AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst = true); // Makes 'dst' character/glyph points to 'src' character/glyph. Currently needs to be called AFTER fonts have been built. #ifndef IMGUI_DISABLE_OBSOLETE_FUNCTIONS - typedef ImFontGlyph Glyph; // OBSOLETE 1.52+ + typedef ImFontGlyph Glyph; // OBSOLETE 1.52+ #endif }; diff --git a/examples/ThirdPartyLibs/imgui/imgui_demo.cpp b/examples/ThirdPartyLibs/imgui/imgui_demo.cpp index 2a1972781..632df680f 100644 --- a/examples/ThirdPartyLibs/imgui/imgui_demo.cpp +++ b/examples/ThirdPartyLibs/imgui/imgui_demo.cpp @@ -12,9 +12,9 @@ // Thank you, // -Your beloved friend, imgui_demo.cpp (that you won't delete) -// Message to beginner C/C++ programmers. About the meaning of 'static': in this demo code, we frequently we use 'static' variables inside functions. -// We do this as a way to gather code and data in the same place, just to make the demo code faster to read, faster to write, and use less code. -// A static variable persist across calls, so it is essentially like a global variable but declared inside the scope of the function. +// Message to beginner C/C++ programmers. About the meaning of 'static': in this demo code, we frequently we use 'static' variables inside functions. +// We do this as a way to gather code and data in the same place, just to make the demo code faster to read, faster to write, and use less code. +// A static variable persist across calls, so it is essentially like a global variable but declared inside the scope of the function. // It also happens to be a convenient way of storing simple UI related information as long as your function doesn't need to be reentrant or used in threads. // This might be a pattern you occasionally want to use in your code, but most of the real data you would be editing is likely to be stored outside your function. @@ -23,36 +23,36 @@ #endif #include "imgui.h" -#include // toupper, isprint -#include // sqrtf, powf, cosf, sinf, floorf, ceilf -#include // vsnprintf, sscanf, printf -#include // NULL, malloc, free, atoi -#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier -#include // intptr_t +#include // toupper, isprint +#include // sqrtf, powf, cosf, sinf, floorf, ceilf +#include // vsnprintf, sscanf, printf +#include // NULL, malloc, free, atoi +#if defined(_MSC_VER) && _MSC_VER <= 1500 // MSVC 2008 or earlier +#include // intptr_t #else -#include // intptr_t +#include // intptr_t #endif #ifdef _MSC_VER -#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen +#pragma warning(disable : 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen #define snprintf _snprintf #endif #ifdef __clang__ -#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse. -#pragma clang diagnostic ignored "-Wdeprecated-declarations" // warning : 'xx' is deprecated: The POSIX name for this item.. // for strdup used in demo code (so user can copy & paste the code) -#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int' -#pragma clang diagnostic ignored "-Wformat-security" // warning : warning: format string is not a string literal -#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning : declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals. +#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse. +#pragma clang diagnostic ignored "-Wdeprecated-declarations" // warning : 'xx' is deprecated: The POSIX name for this item.. // for strdup used in demo code (so user can copy & paste the code) +#pragma clang diagnostic ignored "-Wint-to-void-pointer-cast" // warning : cast to 'void *' from smaller integer type 'int' +#pragma clang diagnostic ignored "-Wformat-security" // warning : warning: format string is not a string literal +#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning : declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals. #if __has_warning("-Wreserved-id-macro") -#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning : macro name is a reserved identifier // +#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning : macro name is a reserved identifier // #endif #elif defined(__GNUC__) -#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size -#pragma GCC diagnostic ignored "-Wformat-security" // warning : format string is not a string literal (potentially insecure) -#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function -#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value +#pragma GCC diagnostic ignored "-Wint-to-pointer-cast" // warning: cast to pointer from integer of different size +#pragma GCC diagnostic ignored "-Wformat-security" // warning : format string is not a string literal (potentially insecure) +#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function +#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value #if (__GNUC__ >= 6) -#pragma GCC diagnostic ignored "-Wmisleading-indentation" // warning: this 'if' clause does not guard this statement // GCC 6.0+ only. See #883 on GitHub. +#pragma GCC diagnostic ignored "-Wmisleading-indentation" // warning: this 'if' clause does not guard this statement // GCC 6.0+ only. See #883 on GitHub. #endif #endif @@ -63,13 +63,13 @@ #define IM_NEWLINE "\n" #endif -#define IM_MAX(_A,_B) (((_A) >= (_B)) ? (_A) : (_B)) +#define IM_MAX(_A, _B) (((_A) >= (_B)) ? (_A) : (_B)) //----------------------------------------------------------------------------- // DEMO CODE //----------------------------------------------------------------------------- -#if !defined(IMGUI_DISABLE_OBSOLETE_FUNCTIONS) && defined(IMGUI_DISABLE_TEST_WINDOWS) && !defined(IMGUI_DISABLE_DEMO_WINDOWS) // Obsolete name since 1.53, TEST->DEMO +#if !defined(IMGUI_DISABLE_OBSOLETE_FUNCTIONS) && defined(IMGUI_DISABLE_TEST_WINDOWS) && !defined(IMGUI_DISABLE_DEMO_WINDOWS) // Obsolete name since 1.53, TEST->DEMO #define IMGUI_DISABLE_DEMO_WINDOWS #endif @@ -90,1635 +90,1806 @@ static void ShowExampleMenuFile(); static void ShowHelpMarker(const char* desc) { - ImGui::TextDisabled("(?)"); - if (ImGui::IsItemHovered()) - { - ImGui::BeginTooltip(); - ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f); - ImGui::TextUnformatted(desc); - ImGui::PopTextWrapPos(); - ImGui::EndTooltip(); - } + ImGui::TextDisabled("(?)"); + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::PushTextWrapPos(ImGui::GetFontSize() * 35.0f); + ImGui::TextUnformatted(desc); + ImGui::PopTextWrapPos(); + ImGui::EndTooltip(); + } } void ImGui::ShowUserGuide() { - ImGui::BulletText("Double-click on title bar to collapse window."); - ImGui::BulletText("Click and drag on lower right corner to resize window\n(double-click to auto fit window to its contents)."); - ImGui::BulletText("Click and drag on any empty space to move window."); - ImGui::BulletText("TAB/SHIFT+TAB to cycle through keyboard editable fields."); - ImGui::BulletText("CTRL+Click on a slider or drag box to input value as text."); - if (ImGui::GetIO().FontAllowUserScaling) - ImGui::BulletText("CTRL+Mouse Wheel to zoom window contents."); - ImGui::BulletText("Mouse Wheel to scroll."); - ImGui::BulletText("While editing text:\n"); - ImGui::Indent(); - ImGui::BulletText("Hold SHIFT or use mouse to select text."); - ImGui::BulletText("CTRL+Left/Right to word jump."); - ImGui::BulletText("CTRL+A or double-click to select all."); - ImGui::BulletText("CTRL+X,CTRL+C,CTRL+V to use clipboard."); - ImGui::BulletText("CTRL+Z,CTRL+Y to undo/redo."); - ImGui::BulletText("ESCAPE to revert."); - ImGui::BulletText("You can apply arithmetic operators +,*,/ on numerical values.\nUse +- to subtract."); - ImGui::Unindent(); + ImGui::BulletText("Double-click on title bar to collapse window."); + ImGui::BulletText("Click and drag on lower right corner to resize window\n(double-click to auto fit window to its contents)."); + ImGui::BulletText("Click and drag on any empty space to move window."); + ImGui::BulletText("TAB/SHIFT+TAB to cycle through keyboard editable fields."); + ImGui::BulletText("CTRL+Click on a slider or drag box to input value as text."); + if (ImGui::GetIO().FontAllowUserScaling) + ImGui::BulletText("CTRL+Mouse Wheel to zoom window contents."); + ImGui::BulletText("Mouse Wheel to scroll."); + ImGui::BulletText("While editing text:\n"); + ImGui::Indent(); + ImGui::BulletText("Hold SHIFT or use mouse to select text."); + ImGui::BulletText("CTRL+Left/Right to word jump."); + ImGui::BulletText("CTRL+A or double-click to select all."); + ImGui::BulletText("CTRL+X,CTRL+C,CTRL+V to use clipboard."); + ImGui::BulletText("CTRL+Z,CTRL+Y to undo/redo."); + ImGui::BulletText("ESCAPE to revert."); + ImGui::BulletText("You can apply arithmetic operators +,*,/ on numerical values.\nUse +- to subtract."); + ImGui::Unindent(); } // Demonstrate most ImGui features (big function!) void ImGui::ShowDemoWindow(bool* p_open) { - // Examples apps - static bool show_app_main_menu_bar = false; - static bool show_app_console = false; - static bool show_app_log = false; - static bool show_app_layout = false; - static bool show_app_property_editor = false; - static bool show_app_long_text = false; - static bool show_app_auto_resize = false; - static bool show_app_constrained_resize = false; - static bool show_app_fixed_overlay = false; - static bool show_app_window_titles = false; - static bool show_app_custom_rendering = false; - static bool show_app_style_editor = false; - - static bool show_app_metrics = false; - static bool show_app_about = false; - - if (show_app_main_menu_bar) ShowExampleAppMainMenuBar(); - if (show_app_console) ShowExampleAppConsole(&show_app_console); - if (show_app_log) ShowExampleAppLog(&show_app_log); - if (show_app_layout) ShowExampleAppLayout(&show_app_layout); - if (show_app_property_editor) ShowExampleAppPropertyEditor(&show_app_property_editor); - if (show_app_long_text) ShowExampleAppLongText(&show_app_long_text); - if (show_app_auto_resize) ShowExampleAppAutoResize(&show_app_auto_resize); - if (show_app_constrained_resize) ShowExampleAppConstrainedResize(&show_app_constrained_resize); - if (show_app_fixed_overlay) ShowExampleAppFixedOverlay(&show_app_fixed_overlay); - if (show_app_window_titles) ShowExampleAppWindowTitles(&show_app_window_titles); - if (show_app_custom_rendering) ShowExampleAppCustomRendering(&show_app_custom_rendering); - - if (show_app_metrics) { ImGui::ShowMetricsWindow(&show_app_metrics); } - if (show_app_style_editor) { ImGui::Begin("Style Editor", &show_app_style_editor); ImGui::ShowStyleEditor(); ImGui::End(); } - if (show_app_about) - { - ImGui::Begin("About Dear ImGui", &show_app_about, ImGuiWindowFlags_AlwaysAutoResize); - ImGui::Text("Dear ImGui, %s", ImGui::GetVersion()); - ImGui::Separator(); - ImGui::Text("By Omar Cornut and all dear imgui contributors."); - ImGui::Text("Dear ImGui is licensed under the MIT License, see LICENSE for more information."); - ImGui::End(); - } - - static bool no_titlebar = false; - static bool no_scrollbar = false; - static bool no_menu = false; - static bool no_move = false; - static bool no_resize = false; - static bool no_collapse = false; - static bool no_close = false; - static bool no_nav = false; - - // Demonstrate the various window flags. Typically you would just use the default. - ImGuiWindowFlags window_flags = 0; - if (no_titlebar) window_flags |= ImGuiWindowFlags_NoTitleBar; - if (no_scrollbar) window_flags |= ImGuiWindowFlags_NoScrollbar; - if (!no_menu) window_flags |= ImGuiWindowFlags_MenuBar; - if (no_move) window_flags |= ImGuiWindowFlags_NoMove; - if (no_resize) window_flags |= ImGuiWindowFlags_NoResize; - if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse; - if (no_nav) window_flags |= ImGuiWindowFlags_NoNav; - if (no_close) p_open = NULL; // Don't pass our bool* to Begin - - ImGui::SetNextWindowSize(ImVec2(550,680), ImGuiCond_FirstUseEver); - if (!ImGui::Begin("ImGui Demo", p_open, window_flags)) - { - // Early out if the window is collapsed, as an optimization. - ImGui::End(); - return; - } - - //ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f); // 2/3 of the space for widget and 1/3 for labels - ImGui::PushItemWidth(-140); // Right align, keep 140 pixels for labels - - ImGui::Text("dear imgui says hello. (%s)", IMGUI_VERSION); - - // Menu - if (ImGui::BeginMenuBar()) - { - if (ImGui::BeginMenu("Menu")) - { - ShowExampleMenuFile(); - ImGui::EndMenu(); - } - if (ImGui::BeginMenu("Examples")) - { - ImGui::MenuItem("Main menu bar", NULL, &show_app_main_menu_bar); - ImGui::MenuItem("Console", NULL, &show_app_console); - ImGui::MenuItem("Log", NULL, &show_app_log); - ImGui::MenuItem("Simple layout", NULL, &show_app_layout); - ImGui::MenuItem("Property editor", NULL, &show_app_property_editor); - ImGui::MenuItem("Long text display", NULL, &show_app_long_text); - ImGui::MenuItem("Auto-resizing window", NULL, &show_app_auto_resize); - ImGui::MenuItem("Constrained-resizing window", NULL, &show_app_constrained_resize); - ImGui::MenuItem("Simple overlay", NULL, &show_app_fixed_overlay); - ImGui::MenuItem("Manipulating window titles", NULL, &show_app_window_titles); - ImGui::MenuItem("Custom rendering", NULL, &show_app_custom_rendering); - ImGui::EndMenu(); - } - if (ImGui::BeginMenu("Help")) - { - ImGui::MenuItem("Metrics", NULL, &show_app_metrics); - ImGui::MenuItem("Style Editor", NULL, &show_app_style_editor); - ImGui::MenuItem("About Dear ImGui", NULL, &show_app_about); - ImGui::EndMenu(); - } - ImGui::EndMenuBar(); - } - - ImGui::Spacing(); - if (ImGui::CollapsingHeader("Help")) - { - ImGui::TextWrapped("This window is being created by the ShowDemoWindow() function. Please refer to the code in imgui_demo.cpp for reference.\n\n"); - ImGui::Text("USER GUIDE:"); - ImGui::ShowUserGuide(); - } - - if (ImGui::CollapsingHeader("Window options")) - { - ImGui::Checkbox("No titlebar", &no_titlebar); ImGui::SameLine(150); - ImGui::Checkbox("No scrollbar", &no_scrollbar); ImGui::SameLine(300); - ImGui::Checkbox("No menu", &no_menu); - ImGui::Checkbox("No move", &no_move); ImGui::SameLine(150); - ImGui::Checkbox("No resize", &no_resize); ImGui::SameLine(300); - ImGui::Checkbox("No collapse", &no_collapse); - ImGui::Checkbox("No close", &no_close); ImGui::SameLine(150); - ImGui::Checkbox("No nav", &no_nav); - - if (ImGui::TreeNode("Style")) - { - ImGui::ShowStyleEditor(); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Capture/Logging")) - { - ImGui::TextWrapped("The logging API redirects all text output so you can easily capture the content of a window or a block. Tree nodes can be automatically expanded. You can also call ImGui::LogText() to output directly to the log without a visual output."); - ImGui::LogButtons(); - ImGui::TreePop(); - } - } - - if (ImGui::CollapsingHeader("Widgets")) - { - if (ImGui::TreeNode("Basic")) - { - static int clicked = 0; - if (ImGui::Button("Button")) - clicked++; - if (clicked & 1) - { - ImGui::SameLine(); - ImGui::Text("Thanks for clicking me!"); - } - - static bool check = true; - ImGui::Checkbox("checkbox", &check); - - static int e = 0; - ImGui::RadioButton("radio a", &e, 0); ImGui::SameLine(); - ImGui::RadioButton("radio b", &e, 1); ImGui::SameLine(); - ImGui::RadioButton("radio c", &e, 2); - - // Color buttons, demonstrate using PushID() to add unique identifier in the ID stack, and changing style. - for (int i = 0; i < 7; i++) - { - if (i > 0) ImGui::SameLine(); - ImGui::PushID(i); - ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(i/7.0f, 0.6f, 0.6f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, (ImVec4)ImColor::HSV(i/7.0f, 0.7f, 0.7f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, (ImVec4)ImColor::HSV(i/7.0f, 0.8f, 0.8f)); - ImGui::Button("Click"); - ImGui::PopStyleColor(3); - ImGui::PopID(); - } - - ImGui::Text("Hover over me"); - if (ImGui::IsItemHovered()) - ImGui::SetTooltip("I am a tooltip"); - - ImGui::SameLine(); - ImGui::Text("- or me"); - if (ImGui::IsItemHovered()) - { - ImGui::BeginTooltip(); - ImGui::Text("I am a fancy tooltip"); - static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; - ImGui::PlotLines("Curve", arr, IM_ARRAYSIZE(arr)); - ImGui::EndTooltip(); - } - - // Testing ImGuiOnceUponAFrame helper. - //static ImGuiOnceUponAFrame once; - //for (int i = 0; i < 5; i++) - // if (once) - // ImGui::Text("This will be displayed only once."); - - ImGui::Separator(); - - ImGui::LabelText("label", "Value"); - - { - // Simplified one-liner Combo() API, using values packed in a single constant string - static int current_item_1 = 1; - ImGui::Combo("combo", ¤t_item_1, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); - //ImGui::Combo("combo w/ array of char*", ¤t_item_2_idx, items, IM_ARRAYSIZE(items)); // Combo using proper array. You can also pass a callback to retrieve array value, no need to create/copy an array just for that. - - // General BeginCombo() API, you have full control over your selection data and display type - const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO", "PPPP", "QQQQQQQQQQ", "RRR", "SSSS" }; - static const char* current_item_2 = NULL; - if (ImGui::BeginCombo("combo 2", current_item_2)) // The second parameter is the label previewed before opening the combo. - { - for (int n = 0; n < IM_ARRAYSIZE(items); n++) - { - bool is_selected = (current_item_2 == items[n]); // You can store your selection however you want, outside or inside your objects - if (ImGui::Selectable(items[n], is_selected)) - current_item_2 = items[n]; - if (is_selected) - ImGui::SetItemDefaultFocus(); // Set the initial focus when opening the combo (scrolling + for keyboard navigation support in the upcoming navigation branch) - } - ImGui::EndCombo(); - } - } - - { - static char str0[128] = "Hello, world!"; - static int i0=123; - static float f0=0.001f; - ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0)); - ImGui::SameLine(); ShowHelpMarker("Hold SHIFT or use mouse to select text.\n" "CTRL+Left/Right to word jump.\n" "CTRL+A or double-click to select all.\n" "CTRL+X,CTRL+C,CTRL+V clipboard.\n" "CTRL+Z,CTRL+Y undo/redo.\n" "ESCAPE to revert.\n"); - - ImGui::InputInt("input int", &i0); - ImGui::SameLine(); ShowHelpMarker("You can apply arithmetic operators +,*,/ on numerical values.\n e.g. [ 100 ], input \'*2\', result becomes [ 200 ]\nUse +- to subtract.\n"); - - ImGui::InputFloat("input float", &f0, 0.01f, 1.0f); - - static float vec4a[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; - ImGui::InputFloat3("input float3", vec4a); - } - - { - static int i1=50, i2=42; - ImGui::DragInt("drag int", &i1, 1); - ImGui::SameLine(); ShowHelpMarker("Click and drag to edit value.\nHold SHIFT/ALT for faster/slower edit.\nDouble-click or CTRL+click to input value."); - - ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%.0f%%"); - - static float f1=1.00f, f2=0.0067f; - ImGui::DragFloat("drag float", &f1, 0.005f); - ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f ns"); - } - - { - static int i1=0; - ImGui::SliderInt("slider int", &i1, -1, 3); - ImGui::SameLine(); ShowHelpMarker("CTRL+click to input value."); - - static float f1=0.123f, f2=0.0f; - ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f"); - ImGui::SliderFloat("slider log float", &f2, -10.0f, 10.0f, "%.4f", 3.0f); - static float angle = 0.0f; - ImGui::SliderAngle("slider angle", &angle); - } - - static float col1[3] = { 1.0f,0.0f,0.2f }; - static float col2[4] = { 0.4f,0.7f,0.0f,0.5f }; - ImGui::ColorEdit3("color 1", col1); - ImGui::SameLine(); ShowHelpMarker("Click on the colored square to open a color picker.\nRight-click on the colored square to show options.\nCTRL+click on individual component to input value.\n"); - - ImGui::ColorEdit4("color 2", col2); - - const char* listbox_items[] = { "Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pineapple", "Strawberry", "Watermelon" }; - static int listbox_item_current = 1; - ImGui::ListBox("listbox\n(single select)", &listbox_item_current, listbox_items, IM_ARRAYSIZE(listbox_items), 4); - - //static int listbox_item_current2 = 2; - //ImGui::PushItemWidth(-1); - //ImGui::ListBox("##listbox2", &listbox_item_current2, listbox_items, IM_ARRAYSIZE(listbox_items), 4); - //ImGui::PopItemWidth(); - - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Trees")) - { - if (ImGui::TreeNode("Basic trees")) - { - for (int i = 0; i < 5; i++) - if (ImGui::TreeNode((void*)(intptr_t)i, "Child %d", i)) - { - ImGui::Text("blah blah"); - ImGui::SameLine(); - if (ImGui::SmallButton("button")) { }; - ImGui::TreePop(); - } - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Advanced, with Selectable nodes")) - { - ShowHelpMarker("This is a more standard looking tree with selectable nodes.\nClick to select, CTRL+Click to toggle, click on arrows or double-click to open."); - static bool align_label_with_current_x_position = false; - ImGui::Checkbox("Align label with current X position)", &align_label_with_current_x_position); - ImGui::Text("Hello!"); - if (align_label_with_current_x_position) - ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing()); - - static int selection_mask = (1 << 2); // Dumb representation of what may be user-side selection state. You may carry selection state inside or outside your objects in whatever format you see fit. - int node_clicked = -1; // Temporary storage of what node we have clicked to process selection at the end of the loop. May be a pointer to your own node type, etc. - ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, ImGui::GetFontSize()*3); // Increase spacing to differentiate leaves from expanded contents. - for (int i = 0; i < 6; i++) - { - // Disable the default open on single-click behavior and pass in Selected flag according to our selection state. - ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ((selection_mask & (1 << i)) ? ImGuiTreeNodeFlags_Selected : 0); - if (i < 3) - { - // Node - bool node_open = ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Node %d", i); - if (ImGui::IsItemClicked()) - node_clicked = i; - if (node_open) - { - ImGui::Text("Blah blah\nBlah Blah"); - ImGui::TreePop(); - } - } - else - { - // Leaf: The only reason we have a TreeNode at all is to allow selection of the leaf. Otherwise we can use BulletText() or TreeAdvanceToLabelPos()+Text(). - node_flags |= ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; // ImGuiTreeNodeFlags_Bullet - ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Leaf %d", i); - if (ImGui::IsItemClicked()) - node_clicked = i; - } - } - if (node_clicked != -1) - { - // Update selection state. Process outside of tree loop to avoid visual inconsistencies during the clicking-frame. - if (ImGui::GetIO().KeyCtrl) - selection_mask ^= (1 << node_clicked); // CTRL+click to toggle - else //if (!(selection_mask & (1 << node_clicked))) // Depending on selection behavior you want, this commented bit preserve selection when clicking on item that is part of the selection - selection_mask = (1 << node_clicked); // Click to single-select - } - ImGui::PopStyleVar(); - if (align_label_with_current_x_position) - ImGui::Indent(ImGui::GetTreeNodeToLabelSpacing()); - ImGui::TreePop(); - } - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Collapsing Headers")) - { - static bool closable_group = true; - ImGui::Checkbox("Enable extra group", &closable_group); - if (ImGui::CollapsingHeader("Header")) - { - ImGui::Text("IsItemHovered: %d", IsItemHovered()); - for (int i = 0; i < 5; i++) - ImGui::Text("Some content %d", i); - } - if (ImGui::CollapsingHeader("Header with a close button", &closable_group)) - { - ImGui::Text("IsItemHovered: %d", IsItemHovered()); - for (int i = 0; i < 5; i++) - ImGui::Text("More content %d", i); - } - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Bullets")) - { - ImGui::BulletText("Bullet point 1"); - ImGui::BulletText("Bullet point 2\nOn multiple lines"); - ImGui::Bullet(); ImGui::Text("Bullet point 3 (two calls)"); - ImGui::Bullet(); ImGui::SmallButton("Button"); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Text")) - { - if (ImGui::TreeNode("Colored Text")) - { - // Using shortcut. You can use PushStyleColor()/PopStyleColor() for more flexibility. - ImGui::TextColored(ImVec4(1.0f,0.0f,1.0f,1.0f), "Pink"); - ImGui::TextColored(ImVec4(1.0f,1.0f,0.0f,1.0f), "Yellow"); - ImGui::TextDisabled("Disabled"); - ImGui::SameLine(); ShowHelpMarker("The TextDisabled color is stored in ImGuiStyle."); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Word Wrapping")) - { - // Using shortcut. You can use PushTextWrapPos()/PopTextWrapPos() for more flexibility. - ImGui::TextWrapped("This text should automatically wrap on the edge of the window. The current implementation for text wrapping follows simple rules suitable for English and possibly other languages."); - ImGui::Spacing(); - - static float wrap_width = 200.0f; - ImGui::SliderFloat("Wrap width", &wrap_width, -20, 600, "%.0f"); - - ImGui::Text("Test paragraph 1:"); - ImVec2 pos = ImGui::GetCursorScreenPos(); - ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(pos.x + wrap_width, pos.y), ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight()), IM_COL32(255,0,255,255)); - ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width); - ImGui::Text("The lazy dog is a good dog. This paragraph is made to fit within %.0f pixels. Testing a 1 character word. The quick brown fox jumps over the lazy dog.", wrap_width); - ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255,255,0,255)); - ImGui::PopTextWrapPos(); - - ImGui::Text("Test paragraph 2:"); - pos = ImGui::GetCursorScreenPos(); - ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(pos.x + wrap_width, pos.y), ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight()), IM_COL32(255,0,255,255)); - ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width); - ImGui::Text("aaaaaaaa bbbbbbbb, c cccccccc,dddddddd. d eeeeeeee ffffffff. gggggggg!hhhhhhhh"); - ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255,255,0,255)); - ImGui::PopTextWrapPos(); - - ImGui::TreePop(); - } - - if (ImGui::TreeNode("UTF-8 Text")) - { - // UTF-8 test with Japanese characters - // (needs a suitable font, try Arial Unicode or M+ fonts http://mplus-fonts.sourceforge.jp/mplus-outline-fonts/index-en.html) - // - From C++11 you can use the u8"my text" syntax to encode literal strings as UTF-8 - // - For earlier compiler, you may be able to encode your sources as UTF-8 (e.g. Visual Studio save your file as 'UTF-8 without signature') - // - HOWEVER, FOR THIS DEMO FILE, BECAUSE WE WANT TO SUPPORT COMPILER, WE ARE *NOT* INCLUDING RAW UTF-8 CHARACTERS IN THIS SOURCE FILE. - // Instead we are encoding a few string with hexadecimal constants. Don't do this in your application! - // Note that characters values are preserved even by InputText() if the font cannot be displayed, so you can safely copy & paste garbled characters into another application. - ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges."); - ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)"); - ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)"); - static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"; // "nihongo" - ImGui::InputText("UTF-8 input", buf, IM_ARRAYSIZE(buf)); - ImGui::TreePop(); - } - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Images")) - { - ImGui::TextWrapped("Below we are displaying the font texture (which is the only texture we have access to in this demo). Use the 'ImTextureID' type as storage to pass pointers or identifier to your own texture data. Hover the texture for a zoomed view!"); - ImGuiIO& io = ImGui::GetIO(); - - // Here we are grabbing the font texture because that's the only one we have access to inside the demo code. - // Remember that ImTextureID is just storage for whatever you want it to be, it is essentially a value that will be passed to the render function inside the ImDrawCmd structure. - // If you use one of the default imgui_impl_XXXX.cpp renderer, they all have comments at the top of their file to specify what they expect to be stored in ImTextureID. - // (for example, the imgui_impl_dx11.cpp renderer expect a 'ID3D11ShaderResourceView*' pointer. The imgui_impl_glfw_gl3.cpp renderer expect a GLuint OpenGL texture identifier etc.) - // If you decided that ImTextureID = MyEngineTexture*, then you can pass your MyEngineTexture* pointers to ImGui::Image(), and gather width/height through your own functions, etc. - // Using ShowMetricsWindow() as a "debugger" to inspect the draw data that are being passed to your render will help you debug issues if you are confused about this. - // Consider using the lower-level ImDrawList::AddImage() API, via ImGui::GetWindowDrawList()->AddImage(). - ImTextureID my_tex_id = io.Fonts->TexID; - float my_tex_w = (float)io.Fonts->TexWidth; - float my_tex_h = (float)io.Fonts->TexHeight; - - ImGui::Text("%.0fx%.0f", my_tex_w, my_tex_h); - ImVec2 pos = ImGui::GetCursorScreenPos(); - ImGui::Image(my_tex_id, ImVec2(my_tex_w, my_tex_h), ImVec2(0,0), ImVec2(1,1), ImColor(255,255,255,255), ImColor(255,255,255,128)); - if (ImGui::IsItemHovered()) - { - ImGui::BeginTooltip(); - float focus_sz = 32.0f; - float focus_x = io.MousePos.x - pos.x - focus_sz * 0.5f; if (focus_x < 0.0f) focus_x = 0.0f; else if (focus_x > my_tex_w - focus_sz) focus_x = my_tex_w - focus_sz; - float focus_y = io.MousePos.y - pos.y - focus_sz * 0.5f; if (focus_y < 0.0f) focus_y = 0.0f; else if (focus_y > my_tex_h - focus_sz) focus_y = my_tex_h - focus_sz; - ImGui::Text("Min: (%.2f, %.2f)", focus_x, focus_y); - ImGui::Text("Max: (%.2f, %.2f)", focus_x + focus_sz, focus_y + focus_sz); - ImVec2 uv0 = ImVec2((focus_x) / my_tex_w, (focus_y) / my_tex_h); - ImVec2 uv1 = ImVec2((focus_x + focus_sz) / my_tex_w, (focus_y + focus_sz) / my_tex_h); - ImGui::Image(my_tex_id, ImVec2(128,128), uv0, uv1, ImColor(255,255,255,255), ImColor(255,255,255,128)); - ImGui::EndTooltip(); - } - ImGui::TextWrapped("And now some textured buttons.."); - static int pressed_count = 0; - for (int i = 0; i < 8; i++) - { - ImGui::PushID(i); - int frame_padding = -1 + i; // -1 = uses default padding - if (ImGui::ImageButton(my_tex_id, ImVec2(32,32), ImVec2(0,0), ImVec2(32.0f/my_tex_w,32/my_tex_h), frame_padding, ImColor(0,0,0,255))) - pressed_count += 1; - ImGui::PopID(); - ImGui::SameLine(); - } - ImGui::NewLine(); - ImGui::Text("Pressed %d times.", pressed_count); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Selectables")) - { - // Selectable() has 2 overloads: - // - The one taking "bool selected" as a read-only selection information. When Selectable() has been clicked is returns true and you can alter selection state accordingly. - // - The one taking "bool* p_selected" as a read-write selection information (convenient in some cases) - // The earlier is more flexible, as in real application your selection may be stored in a different manner (in flags within objects, as an external list, etc). - if (ImGui::TreeNode("Basic")) - { - static bool selection[5] = { false, true, false, false, false }; - ImGui::Selectable("1. I am selectable", &selection[0]); - ImGui::Selectable("2. I am selectable", &selection[1]); - ImGui::Text("3. I am not selectable"); - ImGui::Selectable("4. I am selectable", &selection[3]); - if (ImGui::Selectable("5. I am double clickable", selection[4], ImGuiSelectableFlags_AllowDoubleClick)) - if (ImGui::IsMouseDoubleClicked(0)) - selection[4] = !selection[4]; - ImGui::TreePop(); - } - if (ImGui::TreeNode("Selection State: Single Selection")) - { - static int selected = -1; - for (int n = 0; n < 5; n++) - { - char buf[32]; - sprintf(buf, "Object %d", n); - if (ImGui::Selectable(buf, selected == n)) - selected = n; - } - ImGui::TreePop(); - } - if (ImGui::TreeNode("Selection State: Multiple Selection")) - { - ShowHelpMarker("Hold CTRL and click to select multiple items."); - static bool selection[5] = { false, false, false, false, false }; - for (int n = 0; n < 5; n++) - { - char buf[32]; - sprintf(buf, "Object %d", n); - if (ImGui::Selectable(buf, selection[n])) - { - if (!ImGui::GetIO().KeyCtrl) // Clear selection when CTRL is not held - memset(selection, 0, sizeof(selection)); - selection[n] ^= 1; - } - } - ImGui::TreePop(); - } - if (ImGui::TreeNode("Rendering more text into the same line")) - { - // Using the Selectable() override that takes "bool* p_selected" parameter and toggle your booleans automatically. - static bool selected[3] = { false, false, false }; - ImGui::Selectable("main.c", &selected[0]); ImGui::SameLine(300); ImGui::Text(" 2,345 bytes"); - ImGui::Selectable("Hello.cpp", &selected[1]); ImGui::SameLine(300); ImGui::Text("12,345 bytes"); - ImGui::Selectable("Hello.h", &selected[2]); ImGui::SameLine(300); ImGui::Text(" 2,345 bytes"); - ImGui::TreePop(); - } - if (ImGui::TreeNode("In columns")) - { - ImGui::Columns(3, NULL, false); - static bool selected[16] = { 0 }; - for (int i = 0; i < 16; i++) - { - char label[32]; sprintf(label, "Item %d", i); - if (ImGui::Selectable(label, &selected[i])) {} - ImGui::NextColumn(); - } - ImGui::Columns(1); - ImGui::TreePop(); - } - if (ImGui::TreeNode("Grid")) - { - static bool selected[16] = { true, false, false, false, false, true, false, false, false, false, true, false, false, false, false, true }; - for (int i = 0; i < 16; i++) - { - ImGui::PushID(i); - if (ImGui::Selectable("Sailor", &selected[i], 0, ImVec2(50,50))) - { - int x = i % 4, y = i / 4; - if (x > 0) selected[i - 1] ^= 1; - if (x < 3) selected[i + 1] ^= 1; - if (y > 0) selected[i - 4] ^= 1; - if (y < 3) selected[i + 4] ^= 1; - } - if ((i % 4) < 3) ImGui::SameLine(); - ImGui::PopID(); - } - ImGui::TreePop(); - } - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Filtered Text Input")) - { - static char buf1[64] = ""; ImGui::InputText("default", buf1, 64); - static char buf2[64] = ""; ImGui::InputText("decimal", buf2, 64, ImGuiInputTextFlags_CharsDecimal); - static char buf3[64] = ""; ImGui::InputText("hexadecimal", buf3, 64, ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase); - static char buf4[64] = ""; ImGui::InputText("uppercase", buf4, 64, ImGuiInputTextFlags_CharsUppercase); - static char buf5[64] = ""; ImGui::InputText("no blank", buf5, 64, ImGuiInputTextFlags_CharsNoBlank); - struct TextFilters { static int FilterImGuiLetters(ImGuiTextEditCallbackData* data) { if (data->EventChar < 256 && strchr("imgui", (char)data->EventChar)) return 0; return 1; } }; - static char buf6[64] = ""; ImGui::InputText("\"imgui\" letters", buf6, 64, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterImGuiLetters); - - ImGui::Text("Password input"); - static char bufpass[64] = "password123"; - ImGui::InputText("password", bufpass, 64, ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank); - ImGui::SameLine(); ShowHelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n"); - ImGui::InputText("password (clear)", bufpass, 64, ImGuiInputTextFlags_CharsNoBlank); - - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Multi-line Text Input")) - { - static bool read_only = false; - static char text[1024*16] = - "/*\n" - " The Pentium F00F bug, shorthand for F0 0F C7 C8,\n" - " the hexadecimal encoding of one offending instruction,\n" - " more formally, the invalid operand with locked CMPXCHG8B\n" - " instruction bug, is a design flaw in the majority of\n" - " Intel Pentium, Pentium MMX, and Pentium OverDrive\n" - " processors (all in the P5 microarchitecture).\n" - "*/\n\n" - "label:\n" - "\tlock cmpxchg8b eax\n"; - - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0)); - ImGui::Checkbox("Read-only", &read_only); - ImGui::PopStyleVar(); - ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-1.0f, ImGui::GetTextLineHeight() * 16), ImGuiInputTextFlags_AllowTabInput | (read_only ? ImGuiInputTextFlags_ReadOnly : 0)); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Plots widgets")) - { - static bool animate = true; - ImGui::Checkbox("Animate", &animate); - - static float arr[] = { 0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f }; - ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr)); - - // Create a dummy array of contiguous float values to plot - // Tip: If your float aren't contiguous but part of a structure, you can pass a pointer to your first float and the sizeof() of your structure in the Stride parameter. - static float values[90] = { 0 }; - static int values_offset = 0; - static float refresh_time = 0.0f; - if (!animate || refresh_time == 0.0f) - refresh_time = ImGui::GetTime(); - while (refresh_time < ImGui::GetTime()) // Create dummy data at fixed 60 hz rate for the demo - { - static float phase = 0.0f; - values[values_offset] = cosf(phase); - values_offset = (values_offset+1) % IM_ARRAYSIZE(values); - phase += 0.10f*values_offset; - refresh_time += 1.0f/60.0f; - } - ImGui::PlotLines("Lines", values, IM_ARRAYSIZE(values), values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0,80)); - ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0,80)); - - // Use functions to generate output - // FIXME: This is rather awkward because current plot API only pass in indices. We probably want an API passing floats and user provide sample rate/count. - struct Funcs - { - static float Sin(void*, int i) { return sinf(i * 0.1f); } - static float Saw(void*, int i) { return (i & 1) ? 1.0f : -1.0f; } - }; - static int func_type = 0, display_count = 70; - ImGui::Separator(); - ImGui::PushItemWidth(100); ImGui::Combo("func", &func_type, "Sin\0Saw\0"); ImGui::PopItemWidth(); - ImGui::SameLine(); - ImGui::SliderInt("Sample count", &display_count, 1, 400); - float (*func)(void*, int) = (func_type == 0) ? Funcs::Sin : Funcs::Saw; - ImGui::PlotLines("Lines", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0,80)); - ImGui::PlotHistogram("Histogram", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0,80)); - ImGui::Separator(); - - // Animate a simple progress bar - static float progress = 0.0f, progress_dir = 1.0f; - if (animate) - { - progress += progress_dir * 0.4f * ImGui::GetIO().DeltaTime; - if (progress >= +1.1f) { progress = +1.1f; progress_dir *= -1.0f; } - if (progress <= -0.1f) { progress = -0.1f; progress_dir *= -1.0f; } - } - - // Typically we would use ImVec2(-1.0f,0.0f) to use all available width, or ImVec2(width,0.0f) for a specified width. ImVec2(0.0f,0.0f) uses ItemWidth. - ImGui::ProgressBar(progress, ImVec2(0.0f,0.0f)); - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); - ImGui::Text("Progress Bar"); - - float progress_saturated = (progress < 0.0f) ? 0.0f : (progress > 1.0f) ? 1.0f : progress; - char buf[32]; - sprintf(buf, "%d/%d", (int)(progress_saturated*1753), 1753); - ImGui::ProgressBar(progress, ImVec2(0.f,0.f), buf); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Color/Picker Widgets")) - { - static ImVec4 color = ImColor(114, 144, 154, 200); - - static bool alpha_preview = true; - static bool alpha_half_preview = false; - static bool options_menu = true; - static bool hdr = false; - ImGui::Checkbox("With Alpha Preview", &alpha_preview); - ImGui::Checkbox("With Half Alpha Preview", &alpha_half_preview); - ImGui::Checkbox("With Options Menu", &options_menu); ImGui::SameLine(); ShowHelpMarker("Right-click on the individual color widget to show options."); - ImGui::Checkbox("With HDR", &hdr); ImGui::SameLine(); ShowHelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets."); - int misc_flags = (hdr ? ImGuiColorEditFlags_HDR : 0) | (alpha_half_preview ? ImGuiColorEditFlags_AlphaPreviewHalf : (alpha_preview ? ImGuiColorEditFlags_AlphaPreview : 0)) | (options_menu ? 0 : ImGuiColorEditFlags_NoOptions); - - ImGui::Text("Color widget:"); - ImGui::SameLine(); ShowHelpMarker("Click on the colored square to open a color picker.\nCTRL+click on individual component to input value.\n"); - ImGui::ColorEdit3("MyColor##1", (float*)&color, misc_flags); - - ImGui::Text("Color widget HSV with Alpha:"); - ImGui::ColorEdit4("MyColor##2", (float*)&color, ImGuiColorEditFlags_HSV | misc_flags); - - ImGui::Text("Color widget with Float Display:"); - ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | misc_flags); - - ImGui::Text("Color button with Picker:"); - ImGui::SameLine(); ShowHelpMarker("With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\nWith the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only be used for the tooltip and picker popup."); - ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | misc_flags); - - ImGui::Text("Color button with Custom Picker Popup:"); - - // Generate a dummy palette - static bool saved_palette_inited = false; - static ImVec4 saved_palette[32]; - if (!saved_palette_inited) - for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++) - { - ImGui::ColorConvertHSVtoRGB(n / 31.0f, 0.8f, 0.8f, saved_palette[n].x, saved_palette[n].y, saved_palette[n].z); - saved_palette[n].w = 1.0f; // Alpha - } - saved_palette_inited = true; - - static ImVec4 backup_color; - bool open_popup = ImGui::ColorButton("MyColor##3b", color, misc_flags); - ImGui::SameLine(); - open_popup |= ImGui::Button("Palette"); - if (open_popup) - { - ImGui::OpenPopup("mypicker"); - backup_color = color; - } - if (ImGui::BeginPopup("mypicker")) - { - // FIXME: Adding a drag and drop example here would be perfect! - ImGui::Text("MY CUSTOM COLOR PICKER WITH AN AMAZING PALETTE!"); - ImGui::Separator(); - ImGui::ColorPicker4("##picker", (float*)&color, misc_flags | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoSmallPreview); - ImGui::SameLine(); - ImGui::BeginGroup(); - ImGui::Text("Current"); - ImGui::ColorButton("##current", color, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(60,40)); - ImGui::Text("Previous"); - if (ImGui::ColorButton("##previous", backup_color, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(60,40))) - color = backup_color; - ImGui::Separator(); - ImGui::Text("Palette"); - for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++) - { - ImGui::PushID(n); - if ((n % 8) != 0) - ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y); - if (ImGui::ColorButton("##palette", saved_palette[n], ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoTooltip, ImVec2(20,20))) - color = ImVec4(saved_palette[n].x, saved_palette[n].y, saved_palette[n].z, color.w); // Preserve alpha! - - if (ImGui::BeginDragDropTarget()) - { - if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F)) - memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 3); - if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F)) - memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 4); - EndDragDropTarget(); - } - - ImGui::PopID(); - } - ImGui::EndGroup(); - ImGui::EndPopup(); - } - - ImGui::Text("Color button only:"); - ImGui::ColorButton("MyColor##3c", *(ImVec4*)&color, misc_flags, ImVec2(80,80)); - - ImGui::Text("Color picker:"); - static bool alpha = true; - static bool alpha_bar = true; - static bool side_preview = true; - static bool ref_color = false; - static ImVec4 ref_color_v(1.0f,0.0f,1.0f,0.5f); - static int inputs_mode = 2; - static int picker_mode = 0; - ImGui::Checkbox("With Alpha", &alpha); - ImGui::Checkbox("With Alpha Bar", &alpha_bar); - ImGui::Checkbox("With Side Preview", &side_preview); - if (side_preview) - { - ImGui::SameLine(); - ImGui::Checkbox("With Ref Color", &ref_color); - if (ref_color) - { - ImGui::SameLine(); - ImGui::ColorEdit4("##RefColor", &ref_color_v.x, ImGuiColorEditFlags_NoInputs | misc_flags); - } - } - ImGui::Combo("Inputs Mode", &inputs_mode, "All Inputs\0No Inputs\0RGB Input\0HSV Input\0HEX Input\0"); - ImGui::Combo("Picker Mode", &picker_mode, "Auto/Current\0Hue bar + SV rect\0Hue wheel + SV triangle\0"); - ImGui::SameLine(); ShowHelpMarker("User can right-click the picker to change mode."); - ImGuiColorEditFlags flags = misc_flags; - if (!alpha) flags |= ImGuiColorEditFlags_NoAlpha; // This is by default if you call ColorPicker3() instead of ColorPicker4() - if (alpha_bar) flags |= ImGuiColorEditFlags_AlphaBar; - if (!side_preview) flags |= ImGuiColorEditFlags_NoSidePreview; - if (picker_mode == 1) flags |= ImGuiColorEditFlags_PickerHueBar; - if (picker_mode == 2) flags |= ImGuiColorEditFlags_PickerHueWheel; - if (inputs_mode == 1) flags |= ImGuiColorEditFlags_NoInputs; - if (inputs_mode == 2) flags |= ImGuiColorEditFlags_RGB; - if (inputs_mode == 3) flags |= ImGuiColorEditFlags_HSV; - if (inputs_mode == 4) flags |= ImGuiColorEditFlags_HEX; - ImGui::ColorPicker4("MyColor##4", (float*)&color, flags, ref_color ? &ref_color_v.x : NULL); - - ImGui::Text("Programmatically set defaults/options:"); - ImGui::SameLine(); ShowHelpMarker("SetColorEditOptions() is designed to allow you to set boot-time default.\nWe don't have Push/Pop functions because you can force options on a per-widget basis if needed, and the user can change non-forced ones with the options menu.\nWe don't have a getter to avoid encouraging you to persistently save values that aren't forward-compatible."); - if (ImGui::Button("Uint8 + HSV")) - ImGui::SetColorEditOptions(ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_HSV); - ImGui::SameLine(); - if (ImGui::Button("Float + HDR")) - ImGui::SetColorEditOptions(ImGuiColorEditFlags_Float | ImGuiColorEditFlags_RGB); - - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Range Widgets")) - { - static float begin = 10, end = 90; - static int begin_i = 100, end_i = 1000; - ImGui::DragFloatRange2("range", &begin, &end, 0.25f, 0.0f, 100.0f, "Min: %.1f %%", "Max: %.1f %%"); - ImGui::DragIntRange2("range int (no bounds)", &begin_i, &end_i, 5, 0, 0, "Min: %.0f units", "Max: %.0f units"); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Multi-component Widgets")) - { - static float vec4f[4] = { 0.10f, 0.20f, 0.30f, 0.44f }; - static int vec4i[4] = { 1, 5, 100, 255 }; - - ImGui::InputFloat2("input float2", vec4f); - ImGui::DragFloat2("drag float2", vec4f, 0.01f, 0.0f, 1.0f); - ImGui::SliderFloat2("slider float2", vec4f, 0.0f, 1.0f); - ImGui::DragInt2("drag int2", vec4i, 1, 0, 255); - ImGui::InputInt2("input int2", vec4i); - ImGui::SliderInt2("slider int2", vec4i, 0, 255); - ImGui::Spacing(); - - ImGui::InputFloat3("input float3", vec4f); - ImGui::DragFloat3("drag float3", vec4f, 0.01f, 0.0f, 1.0f); - ImGui::SliderFloat3("slider float3", vec4f, 0.0f, 1.0f); - ImGui::DragInt3("drag int3", vec4i, 1, 0, 255); - ImGui::InputInt3("input int3", vec4i); - ImGui::SliderInt3("slider int3", vec4i, 0, 255); - ImGui::Spacing(); - - ImGui::InputFloat4("input float4", vec4f); - ImGui::DragFloat4("drag float4", vec4f, 0.01f, 0.0f, 1.0f); - ImGui::SliderFloat4("slider float4", vec4f, 0.0f, 1.0f); - ImGui::InputInt4("input int4", vec4i); - ImGui::DragInt4("drag int4", vec4i, 1, 0, 255); - ImGui::SliderInt4("slider int4", vec4i, 0, 255); - - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Vertical Sliders")) - { - const float spacing = 4; - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(spacing, spacing)); - - static int int_value = 0; - ImGui::VSliderInt("##int", ImVec2(18,160), &int_value, 0, 5); - ImGui::SameLine(); - - static float values[7] = { 0.0f, 0.60f, 0.35f, 0.9f, 0.70f, 0.20f, 0.0f }; - ImGui::PushID("set1"); - for (int i = 0; i < 7; i++) - { - if (i > 0) ImGui::SameLine(); - ImGui::PushID(i); - ImGui::PushStyleColor(ImGuiCol_FrameBg, (ImVec4)ImColor::HSV(i/7.0f, 0.5f, 0.5f)); - ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, (ImVec4)ImColor::HSV(i/7.0f, 0.6f, 0.5f)); - ImGui::PushStyleColor(ImGuiCol_FrameBgActive, (ImVec4)ImColor::HSV(i/7.0f, 0.7f, 0.5f)); - ImGui::PushStyleColor(ImGuiCol_SliderGrab, (ImVec4)ImColor::HSV(i/7.0f, 0.9f, 0.9f)); - ImGui::VSliderFloat("##v", ImVec2(18,160), &values[i], 0.0f, 1.0f, ""); - if (ImGui::IsItemActive() || ImGui::IsItemHovered()) - ImGui::SetTooltip("%.3f", values[i]); - ImGui::PopStyleColor(4); - ImGui::PopID(); - } - ImGui::PopID(); - - ImGui::SameLine(); - ImGui::PushID("set2"); - static float values2[4] = { 0.20f, 0.80f, 0.40f, 0.25f }; - const int rows = 3; - const ImVec2 small_slider_size(18, (160.0f-(rows-1)*spacing)/rows); - for (int nx = 0; nx < 4; nx++) - { - if (nx > 0) ImGui::SameLine(); - ImGui::BeginGroup(); - for (int ny = 0; ny < rows; ny++) - { - ImGui::PushID(nx*rows+ny); - ImGui::VSliderFloat("##v", small_slider_size, &values2[nx], 0.0f, 1.0f, ""); - if (ImGui::IsItemActive() || ImGui::IsItemHovered()) - ImGui::SetTooltip("%.3f", values2[nx]); - ImGui::PopID(); - } - ImGui::EndGroup(); - } - ImGui::PopID(); - - ImGui::SameLine(); - ImGui::PushID("set3"); - for (int i = 0; i < 4; i++) - { - if (i > 0) ImGui::SameLine(); - ImGui::PushID(i); - ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, 40); - ImGui::VSliderFloat("##v", ImVec2(40,160), &values[i], 0.0f, 1.0f, "%.2f\nsec"); - ImGui::PopStyleVar(); - ImGui::PopID(); - } - ImGui::PopID(); - ImGui::PopStyleVar(); - ImGui::TreePop(); - } - } - - if (ImGui::CollapsingHeader("Layout")) - { - if (ImGui::TreeNode("Child regions")) - { - static bool disable_mouse_wheel = false; - static bool disable_menu = false; - ImGui::Checkbox("Disable Mouse Wheel", &disable_mouse_wheel); - ImGui::Checkbox("Disable Menu", &disable_menu); - - static int line = 50; - bool goto_line = ImGui::Button("Goto"); - ImGui::SameLine(); - ImGui::PushItemWidth(100); - goto_line |= ImGui::InputInt("##Line", &line, 0, 0, ImGuiInputTextFlags_EnterReturnsTrue); - ImGui::PopItemWidth(); - - // Child 1: no border, enable horizontal scrollbar - { - ImGui::BeginChild("Child1", ImVec2(ImGui::GetWindowContentRegionWidth() * 0.5f, 300), false, ImGuiWindowFlags_HorizontalScrollbar | (disable_mouse_wheel ? ImGuiWindowFlags_NoScrollWithMouse : 0)); - for (int i = 0; i < 100; i++) - { - ImGui::Text("%04d: scrollable region", i); - if (goto_line && line == i) - ImGui::SetScrollHere(); - } - if (goto_line && line >= 100) - ImGui::SetScrollHere(); - ImGui::EndChild(); - } - - ImGui::SameLine(); - - // Child 2: rounded border - { - ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 5.0f); - ImGui::BeginChild("Child2", ImVec2(0,300), true, (disable_mouse_wheel ? ImGuiWindowFlags_NoScrollWithMouse : 0) | (disable_menu ? 0 : ImGuiWindowFlags_MenuBar)); - if (!disable_menu && ImGui::BeginMenuBar()) - { - if (ImGui::BeginMenu("Menu")) - { - ShowExampleMenuFile(); - ImGui::EndMenu(); - } - ImGui::EndMenuBar(); - } - ImGui::Columns(2); - for (int i = 0; i < 100; i++) - { - if (i == 50) - ImGui::NextColumn(); - char buf[32]; - sprintf(buf, "%08x", i*5731); - ImGui::Button(buf, ImVec2(-1.0f, 0.0f)); - } - ImGui::EndChild(); - ImGui::PopStyleVar(); - } - - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Widgets Width")) - { - static float f = 0.0f; - ImGui::Text("PushItemWidth(100)"); - ImGui::SameLine(); ShowHelpMarker("Fixed width."); - ImGui::PushItemWidth(100); - ImGui::DragFloat("float##1", &f); - ImGui::PopItemWidth(); - - ImGui::Text("PushItemWidth(GetWindowWidth() * 0.5f)"); - ImGui::SameLine(); ShowHelpMarker("Half of window width."); - ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f); - ImGui::DragFloat("float##2", &f); - ImGui::PopItemWidth(); - - ImGui::Text("PushItemWidth(GetContentRegionAvailWidth() * 0.5f)"); - ImGui::SameLine(); ShowHelpMarker("Half of available width.\n(~ right-cursor_pos)\n(works within a column set)"); - ImGui::PushItemWidth(ImGui::GetContentRegionAvailWidth() * 0.5f); - ImGui::DragFloat("float##3", &f); - ImGui::PopItemWidth(); - - ImGui::Text("PushItemWidth(-100)"); - ImGui::SameLine(); ShowHelpMarker("Align to right edge minus 100"); - ImGui::PushItemWidth(-100); - ImGui::DragFloat("float##4", &f); - ImGui::PopItemWidth(); - - ImGui::Text("PushItemWidth(-1)"); - ImGui::SameLine(); ShowHelpMarker("Align to right edge"); - ImGui::PushItemWidth(-1); - ImGui::DragFloat("float##5", &f); - ImGui::PopItemWidth(); - - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Basic Horizontal Layout")) - { - ImGui::TextWrapped("(Use ImGui::SameLine() to keep adding items to the right of the preceding item)"); - - // Text - ImGui::Text("Two items: Hello"); ImGui::SameLine(); - ImGui::TextColored(ImVec4(1,1,0,1), "Sailor"); - - // Adjust spacing - ImGui::Text("More spacing: Hello"); ImGui::SameLine(0, 20); - ImGui::TextColored(ImVec4(1,1,0,1), "Sailor"); - - // Button - ImGui::AlignTextToFramePadding(); - ImGui::Text("Normal buttons"); ImGui::SameLine(); - ImGui::Button("Banana"); ImGui::SameLine(); - ImGui::Button("Apple"); ImGui::SameLine(); - ImGui::Button("Corniflower"); - - // Button - ImGui::Text("Small buttons"); ImGui::SameLine(); - ImGui::SmallButton("Like this one"); ImGui::SameLine(); - ImGui::Text("can fit within a text block."); - - // Aligned to arbitrary position. Easy/cheap column. - ImGui::Text("Aligned"); - ImGui::SameLine(150); ImGui::Text("x=150"); - ImGui::SameLine(300); ImGui::Text("x=300"); - ImGui::Text("Aligned"); - ImGui::SameLine(150); ImGui::SmallButton("x=150"); - ImGui::SameLine(300); ImGui::SmallButton("x=300"); - - // Checkbox - static bool c1=false,c2=false,c3=false,c4=false; - ImGui::Checkbox("My", &c1); ImGui::SameLine(); - ImGui::Checkbox("Tailor", &c2); ImGui::SameLine(); - ImGui::Checkbox("Is", &c3); ImGui::SameLine(); - ImGui::Checkbox("Rich", &c4); - - // Various - static float f0=1.0f, f1=2.0f, f2=3.0f; - ImGui::PushItemWidth(80); - const char* items[] = { "AAAA", "BBBB", "CCCC", "DDDD" }; - static int item = -1; - ImGui::Combo("Combo", &item, items, IM_ARRAYSIZE(items)); ImGui::SameLine(); - ImGui::SliderFloat("X", &f0, 0.0f,5.0f); ImGui::SameLine(); - ImGui::SliderFloat("Y", &f1, 0.0f,5.0f); ImGui::SameLine(); - ImGui::SliderFloat("Z", &f2, 0.0f,5.0f); - ImGui::PopItemWidth(); - - ImGui::PushItemWidth(80); - ImGui::Text("Lists:"); - static int selection[4] = { 0, 1, 2, 3 }; - for (int i = 0; i < 4; i++) - { - if (i > 0) ImGui::SameLine(); - ImGui::PushID(i); - ImGui::ListBox("", &selection[i], items, IM_ARRAYSIZE(items)); - ImGui::PopID(); - //if (ImGui::IsItemHovered()) ImGui::SetTooltip("ListBox %d hovered", i); - } - ImGui::PopItemWidth(); - - // Dummy - ImVec2 sz(30,30); - ImGui::Button("A", sz); ImGui::SameLine(); - ImGui::Dummy(sz); ImGui::SameLine(); - ImGui::Button("B", sz); - - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Groups")) - { - ImGui::TextWrapped("(Using ImGui::BeginGroup()/EndGroup() to layout items. BeginGroup() basically locks the horizontal position. EndGroup() bundles the whole group so that you can use functions such as IsItemHovered() on it.)"); - ImGui::BeginGroup(); - { - ImGui::BeginGroup(); - ImGui::Button("AAA"); - ImGui::SameLine(); - ImGui::Button("BBB"); - ImGui::SameLine(); - ImGui::BeginGroup(); - ImGui::Button("CCC"); - ImGui::Button("DDD"); - ImGui::EndGroup(); - ImGui::SameLine(); - ImGui::Button("EEE"); - ImGui::EndGroup(); - if (ImGui::IsItemHovered()) - ImGui::SetTooltip("First group hovered"); - } - // Capture the group size and create widgets using the same size - ImVec2 size = ImGui::GetItemRectSize(); - const float values[5] = { 0.5f, 0.20f, 0.80f, 0.60f, 0.25f }; - ImGui::PlotHistogram("##values", values, IM_ARRAYSIZE(values), 0, NULL, 0.0f, 1.0f, size); - - ImGui::Button("ACTION", ImVec2((size.x - ImGui::GetStyle().ItemSpacing.x)*0.5f,size.y)); - ImGui::SameLine(); - ImGui::Button("REACTION", ImVec2((size.x - ImGui::GetStyle().ItemSpacing.x)*0.5f,size.y)); - ImGui::EndGroup(); - ImGui::SameLine(); - - ImGui::Button("LEVERAGE\nBUZZWORD", size); - ImGui::SameLine(); - - ImGui::ListBoxHeader("List", size); - ImGui::Selectable("Selected", true); - ImGui::Selectable("Not Selected", false); - ImGui::ListBoxFooter(); - - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Text Baseline Alignment")) - { - ImGui::TextWrapped("(This is testing the vertical alignment that occurs on text to keep it at the same baseline as widgets. Lines only composed of text or \"small\" widgets fit in less vertical spaces than lines with normal widgets)"); - - ImGui::Text("One\nTwo\nThree"); ImGui::SameLine(); - ImGui::Text("Hello\nWorld"); ImGui::SameLine(); - ImGui::Text("Banana"); - - ImGui::Text("Banana"); ImGui::SameLine(); - ImGui::Text("Hello\nWorld"); ImGui::SameLine(); - ImGui::Text("One\nTwo\nThree"); - - ImGui::Button("HOP##1"); ImGui::SameLine(); - ImGui::Text("Banana"); ImGui::SameLine(); - ImGui::Text("Hello\nWorld"); ImGui::SameLine(); - ImGui::Text("Banana"); - - ImGui::Button("HOP##2"); ImGui::SameLine(); - ImGui::Text("Hello\nWorld"); ImGui::SameLine(); - ImGui::Text("Banana"); - - ImGui::Button("TEST##1"); ImGui::SameLine(); - ImGui::Text("TEST"); ImGui::SameLine(); - ImGui::SmallButton("TEST##2"); - - ImGui::AlignTextToFramePadding(); // If your line starts with text, call this to align it to upcoming widgets. - ImGui::Text("Text aligned to Widget"); ImGui::SameLine(); - ImGui::Button("Widget##1"); ImGui::SameLine(); - ImGui::Text("Widget"); ImGui::SameLine(); - ImGui::SmallButton("Widget##2"); ImGui::SameLine(); - ImGui::Button("Widget##3"); - - // Tree - const float spacing = ImGui::GetStyle().ItemInnerSpacing.x; - ImGui::Button("Button##1"); - ImGui::SameLine(0.0f, spacing); - if (ImGui::TreeNode("Node##1")) { for (int i = 0; i < 6; i++) ImGui::BulletText("Item %d..", i); ImGui::TreePop(); } // Dummy tree data - - ImGui::AlignTextToFramePadding(); // Vertically align text node a bit lower so it'll be vertically centered with upcoming widget. Otherwise you can use SmallButton (smaller fit). - bool node_open = ImGui::TreeNode("Node##2"); // Common mistake to avoid: if we want to SameLine after TreeNode we need to do it before we add child content. - ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##2"); - if (node_open) { for (int i = 0; i < 6; i++) ImGui::BulletText("Item %d..", i); ImGui::TreePop(); } // Dummy tree data - - // Bullet - ImGui::Button("Button##3"); - ImGui::SameLine(0.0f, spacing); - ImGui::BulletText("Bullet text"); - - ImGui::AlignTextToFramePadding(); - ImGui::BulletText("Node"); - ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##4"); - - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Scrolling")) - { - ImGui::TextWrapped("(Use SetScrollHere() or SetScrollFromPosY() to scroll to a given position.)"); - static bool track = true; - static int track_line = 50, scroll_to_px = 200; - ImGui::Checkbox("Track", &track); - ImGui::PushItemWidth(100); - ImGui::SameLine(130); track |= ImGui::DragInt("##line", &track_line, 0.25f, 0, 99, "Line = %.0f"); - bool scroll_to = ImGui::Button("Scroll To Pos"); - ImGui::SameLine(130); scroll_to |= ImGui::DragInt("##pos_y", &scroll_to_px, 1.00f, 0, 9999, "Y = %.0f px"); - ImGui::PopItemWidth(); - if (scroll_to) track = false; - - for (int i = 0; i < 5; i++) - { - if (i > 0) ImGui::SameLine(); - ImGui::BeginGroup(); - ImGui::Text("%s", i == 0 ? "Top" : i == 1 ? "25%" : i == 2 ? "Center" : i == 3 ? "75%" : "Bottom"); - ImGui::BeginChild(ImGui::GetID((void*)(intptr_t)i), ImVec2(ImGui::GetWindowWidth() * 0.17f, 200.0f), true); - if (scroll_to) - ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + scroll_to_px, i * 0.25f); - for (int line = 0; line < 100; line++) - { - if (track && line == track_line) - { - ImGui::TextColored(ImColor(255,255,0), "Line %d", line); - ImGui::SetScrollHere(i * 0.25f); // 0.0f:top, 0.5f:center, 1.0f:bottom - } - else - { - ImGui::Text("Line %d", line); - } - } - float scroll_y = ImGui::GetScrollY(), scroll_max_y = ImGui::GetScrollMaxY(); - ImGui::EndChild(); - ImGui::Text("%.0f/%0.f", scroll_y, scroll_max_y); - ImGui::EndGroup(); - } - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Horizontal Scrolling")) - { - ImGui::Bullet(); ImGui::TextWrapped("Horizontal scrolling for a window has to be enabled explicitly via the ImGuiWindowFlags_HorizontalScrollbar flag."); - ImGui::Bullet(); ImGui::TextWrapped("You may want to explicitly specify content width by calling SetNextWindowContentWidth() before Begin()."); - static int lines = 7; - ImGui::SliderInt("Lines", &lines, 1, 15); - ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2.0f, 1.0f)); - ImGui::BeginChild("scrolling", ImVec2(0, ImGui::GetFrameHeightWithSpacing()*7 + 30), true, ImGuiWindowFlags_HorizontalScrollbar); - for (int line = 0; line < lines; line++) - { - // Display random stuff (for the sake of this trivial demo we are using basic Button+SameLine. If you want to create your own time line for a real application you may be better off - // manipulating the cursor position yourself, aka using SetCursorPos/SetCursorScreenPos to position the widgets yourself. You may also want to use the lower-level ImDrawList API) - int num_buttons = 10 + ((line & 1) ? line * 9 : line * 3); - for (int n = 0; n < num_buttons; n++) - { - if (n > 0) ImGui::SameLine(); - ImGui::PushID(n + line * 1000); - char num_buf[16]; - sprintf(num_buf, "%d", n); - const char* label = (!(n%15)) ? "FizzBuzz" : (!(n%3)) ? "Fizz" : (!(n%5)) ? "Buzz" : num_buf; - float hue = n*0.05f; - ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(hue, 0.6f, 0.6f)); - ImGui::PushStyleColor(ImGuiCol_ButtonHovered, (ImVec4)ImColor::HSV(hue, 0.7f, 0.7f)); - ImGui::PushStyleColor(ImGuiCol_ButtonActive, (ImVec4)ImColor::HSV(hue, 0.8f, 0.8f)); - ImGui::Button(label, ImVec2(40.0f + sinf((float)(line + n)) * 20.0f, 0.0f)); - ImGui::PopStyleColor(3); - ImGui::PopID(); - } - } - float scroll_x = ImGui::GetScrollX(), scroll_max_x = ImGui::GetScrollMaxX(); - ImGui::EndChild(); - ImGui::PopStyleVar(2); - float scroll_x_delta = 0.0f; - ImGui::SmallButton("<<"); if (ImGui::IsItemActive()) scroll_x_delta = -ImGui::GetIO().DeltaTime * 1000.0f; ImGui::SameLine(); - ImGui::Text("Scroll from code"); ImGui::SameLine(); - ImGui::SmallButton(">>"); if (ImGui::IsItemActive()) scroll_x_delta = +ImGui::GetIO().DeltaTime * 1000.0f; ImGui::SameLine(); - ImGui::Text("%.0f/%.0f", scroll_x, scroll_max_x); - if (scroll_x_delta != 0.0f) - { - ImGui::BeginChild("scrolling"); // Demonstrate a trick: you can use Begin to set yourself in the context of another window (here we are already out of your child window) - ImGui::SetScrollX(ImGui::GetScrollX() + scroll_x_delta); - ImGui::End(); - } - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Clipping")) - { - static ImVec2 size(100, 100), offset(50, 20); - ImGui::TextWrapped("On a per-widget basis we are occasionally clipping text CPU-side if it won't fit in its frame. Otherwise we are doing coarser clipping + passing a scissor rectangle to the renderer. The system is designed to try minimizing both execution and CPU/GPU rendering cost."); - ImGui::DragFloat2("size", (float*)&size, 0.5f, 0.0f, 200.0f, "%.0f"); - ImGui::TextWrapped("(Click and drag)"); - ImVec2 pos = ImGui::GetCursorScreenPos(); - ImVec4 clip_rect(pos.x, pos.y, pos.x+size.x, pos.y+size.y); - ImGui::InvisibleButton("##dummy", size); - if (ImGui::IsItemActive() && ImGui::IsMouseDragging()) { offset.x += ImGui::GetIO().MouseDelta.x; offset.y += ImGui::GetIO().MouseDelta.y; } - ImGui::GetWindowDrawList()->AddRectFilled(pos, ImVec2(pos.x+size.x,pos.y+size.y), IM_COL32(90,90,120,255)); - ImGui::GetWindowDrawList()->AddText(ImGui::GetFont(), ImGui::GetFontSize()*2.0f, ImVec2(pos.x+offset.x,pos.y+offset.y), IM_COL32(255,255,255,255), "Line 1 hello\nLine 2 clip me!", NULL, 0.0f, &clip_rect); - ImGui::TreePop(); - } - } - - if (ImGui::CollapsingHeader("Popups & Modal windows")) - { - if (ImGui::TreeNode("Popups")) - { - ImGui::TextWrapped("When a popup is active, it inhibits interacting with windows that are behind the popup. Clicking outside the popup closes it."); - - static int selected_fish = -1; - const char* names[] = { "Bream", "Haddock", "Mackerel", "Pollock", "Tilefish" }; - static bool toggles[] = { true, false, false, false, false }; - - // Simple selection popup - // (If you want to show the current selection inside the Button itself, you may want to build a string using the "###" operator to preserve a constant ID with a variable label) - if (ImGui::Button("Select..")) - ImGui::OpenPopup("select"); - ImGui::SameLine(); - ImGui::TextUnformatted(selected_fish == -1 ? "" : names[selected_fish]); - if (ImGui::BeginPopup("select")) - { - ImGui::Text("Aquarium"); - ImGui::Separator(); - for (int i = 0; i < IM_ARRAYSIZE(names); i++) - if (ImGui::Selectable(names[i])) - selected_fish = i; - ImGui::EndPopup(); - } - - // Showing a menu with toggles - if (ImGui::Button("Toggle..")) - ImGui::OpenPopup("toggle"); - if (ImGui::BeginPopup("toggle")) - { - for (int i = 0; i < IM_ARRAYSIZE(names); i++) - ImGui::MenuItem(names[i], "", &toggles[i]); - if (ImGui::BeginMenu("Sub-menu")) - { - ImGui::MenuItem("Click me"); - ImGui::EndMenu(); - } - - ImGui::Separator(); - ImGui::Text("Tooltip here"); - if (ImGui::IsItemHovered()) - ImGui::SetTooltip("I am a tooltip over a popup"); - - if (ImGui::Button("Stacked Popup")) - ImGui::OpenPopup("another popup"); - if (ImGui::BeginPopup("another popup")) - { - for (int i = 0; i < IM_ARRAYSIZE(names); i++) - ImGui::MenuItem(names[i], "", &toggles[i]); - if (ImGui::BeginMenu("Sub-menu")) - { - ImGui::MenuItem("Click me"); - ImGui::EndMenu(); - } - ImGui::EndPopup(); - } - ImGui::EndPopup(); - } - - if (ImGui::Button("Popup Menu..")) - ImGui::OpenPopup("FilePopup"); - if (ImGui::BeginPopup("FilePopup")) - { - ShowExampleMenuFile(); - ImGui::EndPopup(); - } - - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Context menus")) - { - // BeginPopupContextItem() is a helper to provide common/simple popup behavior of essentially doing: - // if (IsItemHovered() && IsMouseClicked(0)) - // OpenPopup(id); - // return BeginPopup(id); - // For more advanced uses you may want to replicate and cuztomize this code. This the comments inside BeginPopupContextItem() implementation. - static float value = 0.5f; - ImGui::Text("Value = %.3f (<-- right-click here)", value); - if (ImGui::BeginPopupContextItem("item context menu")) - { - if (ImGui::Selectable("Set to zero")) value = 0.0f; - if (ImGui::Selectable("Set to PI")) value = 3.1415f; - ImGui::PushItemWidth(-1); - ImGui::DragFloat("##Value", &value, 0.1f, 0.0f, 0.0f); - ImGui::PopItemWidth(); - ImGui::EndPopup(); - } - - static char name[32] = "Label1"; - char buf[64]; sprintf(buf, "Button: %s###Button", name); // ### operator override ID ignoring the preceding label - ImGui::Button(buf); - if (ImGui::BeginPopupContextItem()) // When used after an item that has an ID (here the Button), we can skip providing an ID to BeginPopupContextItem(). - { - ImGui::Text("Edit name:"); - ImGui::InputText("##edit", name, IM_ARRAYSIZE(name)); - if (ImGui::Button("Close")) - ImGui::CloseCurrentPopup(); - ImGui::EndPopup(); - } - ImGui::SameLine(); ImGui::Text("(<-- right-click here)"); - - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Modals")) - { - ImGui::TextWrapped("Modal windows are like popups but the user cannot close them by clicking outside the window."); - - if (ImGui::Button("Delete..")) - ImGui::OpenPopup("Delete?"); - if (ImGui::BeginPopupModal("Delete?", NULL, ImGuiWindowFlags_AlwaysAutoResize)) - { - ImGui::Text("All those beautiful files will be deleted.\nThis operation cannot be undone!\n\n"); - ImGui::Separator(); - - //static int dummy_i = 0; - //ImGui::Combo("Combo", &dummy_i, "Delete\0Delete harder\0"); - - static bool dont_ask_me_next_time = false; - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0)); - ImGui::Checkbox("Don't ask me next time", &dont_ask_me_next_time); - ImGui::PopStyleVar(); - - if (ImGui::Button("OK", ImVec2(120,0))) { ImGui::CloseCurrentPopup(); } - ImGui::SetItemDefaultFocus(); - ImGui::SameLine(); - if (ImGui::Button("Cancel", ImVec2(120,0))) { ImGui::CloseCurrentPopup(); } - ImGui::EndPopup(); - } - - if (ImGui::Button("Stacked modals..")) - ImGui::OpenPopup("Stacked 1"); - if (ImGui::BeginPopupModal("Stacked 1")) - { - ImGui::Text("Hello from Stacked The First\nUsing style.Colors[ImGuiCol_ModalWindowDarkening] for darkening."); - static int item = 1; - ImGui::Combo("Combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); - static float color[4] = { 0.4f,0.7f,0.0f,0.5f }; - ImGui::ColorEdit4("color", color); // This is to test behavior of stacked regular popups over a modal - - if (ImGui::Button("Add another modal..")) - ImGui::OpenPopup("Stacked 2"); - if (ImGui::BeginPopupModal("Stacked 2")) - { - ImGui::Text("Hello from Stacked The Second!"); - if (ImGui::Button("Close")) - ImGui::CloseCurrentPopup(); - ImGui::EndPopup(); - } - - if (ImGui::Button("Close")) - ImGui::CloseCurrentPopup(); - ImGui::EndPopup(); - } - - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Menus inside a regular window")) - { - ImGui::TextWrapped("Below we are testing adding menu items to a regular window. It's rather unusual but should work!"); - ImGui::Separator(); - // NB: As a quirk in this very specific example, we want to differentiate the parent of this menu from the parent of the various popup menus above. - // To do so we are encloding the items in a PushID()/PopID() block to make them two different menusets. If we don't, opening any popup above and hovering our menu here - // would open it. This is because once a menu is active, we allow to switch to a sibling menu by just hovering on it, which is the desired behavior for regular menus. - ImGui::PushID("foo"); - ImGui::MenuItem("Menu item", "CTRL+M"); - if (ImGui::BeginMenu("Menu inside a regular window")) - { - ShowExampleMenuFile(); - ImGui::EndMenu(); - } - ImGui::PopID(); - ImGui::Separator(); - ImGui::TreePop(); - } - } - - if (ImGui::CollapsingHeader("Columns")) - { - ImGui::PushID("Columns"); - - // Basic columns - if (ImGui::TreeNode("Basic")) - { - ImGui::Text("Without border:"); - ImGui::Columns(3, "mycolumns3", false); // 3-ways, no border - ImGui::Separator(); - for (int n = 0; n < 14; n++) - { - char label[32]; - sprintf(label, "Item %d", n); - if (ImGui::Selectable(label)) {} - //if (ImGui::Button(label, ImVec2(-1,0))) {} - ImGui::NextColumn(); - } - ImGui::Columns(1); - ImGui::Separator(); - - ImGui::Text("With border:"); - ImGui::Columns(4, "mycolumns"); // 4-ways, with border - ImGui::Separator(); - ImGui::Text("ID"); ImGui::NextColumn(); - ImGui::Text("Name"); ImGui::NextColumn(); - ImGui::Text("Path"); ImGui::NextColumn(); - ImGui::Text("Hovered"); ImGui::NextColumn(); - ImGui::Separator(); - const char* names[3] = { "One", "Two", "Three" }; - const char* paths[3] = { "/path/one", "/path/two", "/path/three" }; - static int selected = -1; - for (int i = 0; i < 3; i++) - { - char label[32]; - sprintf(label, "%04d", i); - if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SpanAllColumns)) - selected = i; - bool hovered = ImGui::IsItemHovered(); - ImGui::NextColumn(); - ImGui::Text(names[i]); ImGui::NextColumn(); - ImGui::Text(paths[i]); ImGui::NextColumn(); - ImGui::Text("%d", hovered); ImGui::NextColumn(); - } - ImGui::Columns(1); - ImGui::Separator(); - ImGui::TreePop(); - } - - // Create multiple items in a same cell before switching to next column - if (ImGui::TreeNode("Mixed items")) - { - ImGui::Columns(3, "mixed"); - ImGui::Separator(); - - ImGui::Text("Hello"); - ImGui::Button("Banana"); - ImGui::NextColumn(); - - ImGui::Text("ImGui"); - ImGui::Button("Apple"); - static float foo = 1.0f; - ImGui::InputFloat("red", &foo, 0.05f, 0, 3); - ImGui::Text("An extra line here."); - ImGui::NextColumn(); - - ImGui::Text("Sailor"); - ImGui::Button("Corniflower"); - static float bar = 1.0f; - ImGui::InputFloat("blue", &bar, 0.05f, 0, 3); - ImGui::NextColumn(); - - if (ImGui::CollapsingHeader("Category A")) { ImGui::Text("Blah blah blah"); } ImGui::NextColumn(); - if (ImGui::CollapsingHeader("Category B")) { ImGui::Text("Blah blah blah"); } ImGui::NextColumn(); - if (ImGui::CollapsingHeader("Category C")) { ImGui::Text("Blah blah blah"); } ImGui::NextColumn(); - ImGui::Columns(1); - ImGui::Separator(); - ImGui::TreePop(); - } - - // Word wrapping - if (ImGui::TreeNode("Word-wrapping")) - { - ImGui::Columns(2, "word-wrapping"); - ImGui::Separator(); - ImGui::TextWrapped("The quick brown fox jumps over the lazy dog."); - ImGui::TextWrapped("Hello Left"); - ImGui::NextColumn(); - ImGui::TextWrapped("The quick brown fox jumps over the lazy dog."); - ImGui::TextWrapped("Hello Right"); - ImGui::Columns(1); - ImGui::Separator(); - ImGui::TreePop(); - } - - if (ImGui::TreeNode("Borders")) - { - // NB: Future columns API should allow automatic horizontal borders. - static bool h_borders = true; - static bool v_borders = true; - ImGui::Checkbox("horizontal", &h_borders); - ImGui::SameLine(); - ImGui::Checkbox("vertical", &v_borders); - ImGui::Columns(4, NULL, v_borders); - for (int i = 0; i < 4*3; i++) - { - if (h_borders && ImGui::GetColumnIndex() == 0) - ImGui::Separator(); - ImGui::Text("%c%c%c", 'a'+i, 'a'+i, 'a'+i); - ImGui::Text("Width %.2f\nOffset %.2f", ImGui::GetColumnWidth(), ImGui::GetColumnOffset()); - ImGui::NextColumn(); - } - ImGui::Columns(1); - if (h_borders) - ImGui::Separator(); - ImGui::TreePop(); - } - - // Scrolling columns - /* + // Examples apps + static bool show_app_main_menu_bar = false; + static bool show_app_console = false; + static bool show_app_log = false; + static bool show_app_layout = false; + static bool show_app_property_editor = false; + static bool show_app_long_text = false; + static bool show_app_auto_resize = false; + static bool show_app_constrained_resize = false; + static bool show_app_fixed_overlay = false; + static bool show_app_window_titles = false; + static bool show_app_custom_rendering = false; + static bool show_app_style_editor = false; + + static bool show_app_metrics = false; + static bool show_app_about = false; + + if (show_app_main_menu_bar) ShowExampleAppMainMenuBar(); + if (show_app_console) ShowExampleAppConsole(&show_app_console); + if (show_app_log) ShowExampleAppLog(&show_app_log); + if (show_app_layout) ShowExampleAppLayout(&show_app_layout); + if (show_app_property_editor) ShowExampleAppPropertyEditor(&show_app_property_editor); + if (show_app_long_text) ShowExampleAppLongText(&show_app_long_text); + if (show_app_auto_resize) ShowExampleAppAutoResize(&show_app_auto_resize); + if (show_app_constrained_resize) ShowExampleAppConstrainedResize(&show_app_constrained_resize); + if (show_app_fixed_overlay) ShowExampleAppFixedOverlay(&show_app_fixed_overlay); + if (show_app_window_titles) ShowExampleAppWindowTitles(&show_app_window_titles); + if (show_app_custom_rendering) ShowExampleAppCustomRendering(&show_app_custom_rendering); + + if (show_app_metrics) + { + ImGui::ShowMetricsWindow(&show_app_metrics); + } + if (show_app_style_editor) + { + ImGui::Begin("Style Editor", &show_app_style_editor); + ImGui::ShowStyleEditor(); + ImGui::End(); + } + if (show_app_about) + { + ImGui::Begin("About Dear ImGui", &show_app_about, ImGuiWindowFlags_AlwaysAutoResize); + ImGui::Text("Dear ImGui, %s", ImGui::GetVersion()); + ImGui::Separator(); + ImGui::Text("By Omar Cornut and all dear imgui contributors."); + ImGui::Text("Dear ImGui is licensed under the MIT License, see LICENSE for more information."); + ImGui::End(); + } + + static bool no_titlebar = false; + static bool no_scrollbar = false; + static bool no_menu = false; + static bool no_move = false; + static bool no_resize = false; + static bool no_collapse = false; + static bool no_close = false; + static bool no_nav = false; + + // Demonstrate the various window flags. Typically you would just use the default. + ImGuiWindowFlags window_flags = 0; + if (no_titlebar) window_flags |= ImGuiWindowFlags_NoTitleBar; + if (no_scrollbar) window_flags |= ImGuiWindowFlags_NoScrollbar; + if (!no_menu) window_flags |= ImGuiWindowFlags_MenuBar; + if (no_move) window_flags |= ImGuiWindowFlags_NoMove; + if (no_resize) window_flags |= ImGuiWindowFlags_NoResize; + if (no_collapse) window_flags |= ImGuiWindowFlags_NoCollapse; + if (no_nav) window_flags |= ImGuiWindowFlags_NoNav; + if (no_close) p_open = NULL; // Don't pass our bool* to Begin + + ImGui::SetNextWindowSize(ImVec2(550, 680), ImGuiCond_FirstUseEver); + if (!ImGui::Begin("ImGui Demo", p_open, window_flags)) + { + // Early out if the window is collapsed, as an optimization. + ImGui::End(); + return; + } + + //ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.65f); // 2/3 of the space for widget and 1/3 for labels + ImGui::PushItemWidth(-140); // Right align, keep 140 pixels for labels + + ImGui::Text("dear imgui says hello. (%s)", IMGUI_VERSION); + + // Menu + if (ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("Menu")) + { + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Examples")) + { + ImGui::MenuItem("Main menu bar", NULL, &show_app_main_menu_bar); + ImGui::MenuItem("Console", NULL, &show_app_console); + ImGui::MenuItem("Log", NULL, &show_app_log); + ImGui::MenuItem("Simple layout", NULL, &show_app_layout); + ImGui::MenuItem("Property editor", NULL, &show_app_property_editor); + ImGui::MenuItem("Long text display", NULL, &show_app_long_text); + ImGui::MenuItem("Auto-resizing window", NULL, &show_app_auto_resize); + ImGui::MenuItem("Constrained-resizing window", NULL, &show_app_constrained_resize); + ImGui::MenuItem("Simple overlay", NULL, &show_app_fixed_overlay); + ImGui::MenuItem("Manipulating window titles", NULL, &show_app_window_titles); + ImGui::MenuItem("Custom rendering", NULL, &show_app_custom_rendering); + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Help")) + { + ImGui::MenuItem("Metrics", NULL, &show_app_metrics); + ImGui::MenuItem("Style Editor", NULL, &show_app_style_editor); + ImGui::MenuItem("About Dear ImGui", NULL, &show_app_about); + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); + } + + ImGui::Spacing(); + if (ImGui::CollapsingHeader("Help")) + { + ImGui::TextWrapped("This window is being created by the ShowDemoWindow() function. Please refer to the code in imgui_demo.cpp for reference.\n\n"); + ImGui::Text("USER GUIDE:"); + ImGui::ShowUserGuide(); + } + + if (ImGui::CollapsingHeader("Window options")) + { + ImGui::Checkbox("No titlebar", &no_titlebar); + ImGui::SameLine(150); + ImGui::Checkbox("No scrollbar", &no_scrollbar); + ImGui::SameLine(300); + ImGui::Checkbox("No menu", &no_menu); + ImGui::Checkbox("No move", &no_move); + ImGui::SameLine(150); + ImGui::Checkbox("No resize", &no_resize); + ImGui::SameLine(300); + ImGui::Checkbox("No collapse", &no_collapse); + ImGui::Checkbox("No close", &no_close); + ImGui::SameLine(150); + ImGui::Checkbox("No nav", &no_nav); + + if (ImGui::TreeNode("Style")) + { + ImGui::ShowStyleEditor(); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Capture/Logging")) + { + ImGui::TextWrapped("The logging API redirects all text output so you can easily capture the content of a window or a block. Tree nodes can be automatically expanded. You can also call ImGui::LogText() to output directly to the log without a visual output."); + ImGui::LogButtons(); + ImGui::TreePop(); + } + } + + if (ImGui::CollapsingHeader("Widgets")) + { + if (ImGui::TreeNode("Basic")) + { + static int clicked = 0; + if (ImGui::Button("Button")) + clicked++; + if (clicked & 1) + { + ImGui::SameLine(); + ImGui::Text("Thanks for clicking me!"); + } + + static bool check = true; + ImGui::Checkbox("checkbox", &check); + + static int e = 0; + ImGui::RadioButton("radio a", &e, 0); + ImGui::SameLine(); + ImGui::RadioButton("radio b", &e, 1); + ImGui::SameLine(); + ImGui::RadioButton("radio c", &e, 2); + + // Color buttons, demonstrate using PushID() to add unique identifier in the ID stack, and changing style. + for (int i = 0; i < 7; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::PushID(i); + ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(i / 7.0f, 0.6f, 0.6f)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, (ImVec4)ImColor::HSV(i / 7.0f, 0.7f, 0.7f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, (ImVec4)ImColor::HSV(i / 7.0f, 0.8f, 0.8f)); + ImGui::Button("Click"); + ImGui::PopStyleColor(3); + ImGui::PopID(); + } + + ImGui::Text("Hover over me"); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("I am a tooltip"); + + ImGui::SameLine(); + ImGui::Text("- or me"); + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + ImGui::Text("I am a fancy tooltip"); + static float arr[] = {0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f}; + ImGui::PlotLines("Curve", arr, IM_ARRAYSIZE(arr)); + ImGui::EndTooltip(); + } + + // Testing ImGuiOnceUponAFrame helper. + //static ImGuiOnceUponAFrame once; + //for (int i = 0; i < 5; i++) + // if (once) + // ImGui::Text("This will be displayed only once."); + + ImGui::Separator(); + + ImGui::LabelText("label", "Value"); + + { + // Simplified one-liner Combo() API, using values packed in a single constant string + static int current_item_1 = 1; + ImGui::Combo("combo", ¤t_item_1, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); + //ImGui::Combo("combo w/ array of char*", ¤t_item_2_idx, items, IM_ARRAYSIZE(items)); // Combo using proper array. You can also pass a callback to retrieve array value, no need to create/copy an array just for that. + + // General BeginCombo() API, you have full control over your selection data and display type + const char* items[] = {"AAAA", "BBBB", "CCCC", "DDDD", "EEEE", "FFFF", "GGGG", "HHHH", "IIII", "JJJJ", "KKKK", "LLLLLLL", "MMMM", "OOOOOOO", "PPPP", "QQQQQQQQQQ", "RRR", "SSSS"}; + static const char* current_item_2 = NULL; + if (ImGui::BeginCombo("combo 2", current_item_2)) // The second parameter is the label previewed before opening the combo. + { + for (int n = 0; n < IM_ARRAYSIZE(items); n++) + { + bool is_selected = (current_item_2 == items[n]); // You can store your selection however you want, outside or inside your objects + if (ImGui::Selectable(items[n], is_selected)) + current_item_2 = items[n]; + if (is_selected) + ImGui::SetItemDefaultFocus(); // Set the initial focus when opening the combo (scrolling + for keyboard navigation support in the upcoming navigation branch) + } + ImGui::EndCombo(); + } + } + + { + static char str0[128] = "Hello, world!"; + static int i0 = 123; + static float f0 = 0.001f; + ImGui::InputText("input text", str0, IM_ARRAYSIZE(str0)); + ImGui::SameLine(); + ShowHelpMarker( + "Hold SHIFT or use mouse to select text.\n" + "CTRL+Left/Right to word jump.\n" + "CTRL+A or double-click to select all.\n" + "CTRL+X,CTRL+C,CTRL+V clipboard.\n" + "CTRL+Z,CTRL+Y undo/redo.\n" + "ESCAPE to revert.\n"); + + ImGui::InputInt("input int", &i0); + ImGui::SameLine(); + ShowHelpMarker("You can apply arithmetic operators +,*,/ on numerical values.\n e.g. [ 100 ], input \'*2\', result becomes [ 200 ]\nUse +- to subtract.\n"); + + ImGui::InputFloat("input float", &f0, 0.01f, 1.0f); + + static float vec4a[4] = {0.10f, 0.20f, 0.30f, 0.44f}; + ImGui::InputFloat3("input float3", vec4a); + } + + { + static int i1 = 50, i2 = 42; + ImGui::DragInt("drag int", &i1, 1); + ImGui::SameLine(); + ShowHelpMarker("Click and drag to edit value.\nHold SHIFT/ALT for faster/slower edit.\nDouble-click or CTRL+click to input value."); + + ImGui::DragInt("drag int 0..100", &i2, 1, 0, 100, "%.0f%%"); + + static float f1 = 1.00f, f2 = 0.0067f; + ImGui::DragFloat("drag float", &f1, 0.005f); + ImGui::DragFloat("drag small float", &f2, 0.0001f, 0.0f, 0.0f, "%.06f ns"); + } + + { + static int i1 = 0; + ImGui::SliderInt("slider int", &i1, -1, 3); + ImGui::SameLine(); + ShowHelpMarker("CTRL+click to input value."); + + static float f1 = 0.123f, f2 = 0.0f; + ImGui::SliderFloat("slider float", &f1, 0.0f, 1.0f, "ratio = %.3f"); + ImGui::SliderFloat("slider log float", &f2, -10.0f, 10.0f, "%.4f", 3.0f); + static float angle = 0.0f; + ImGui::SliderAngle("slider angle", &angle); + } + + static float col1[3] = {1.0f, 0.0f, 0.2f}; + static float col2[4] = {0.4f, 0.7f, 0.0f, 0.5f}; + ImGui::ColorEdit3("color 1", col1); + ImGui::SameLine(); + ShowHelpMarker("Click on the colored square to open a color picker.\nRight-click on the colored square to show options.\nCTRL+click on individual component to input value.\n"); + + ImGui::ColorEdit4("color 2", col2); + + const char* listbox_items[] = {"Apple", "Banana", "Cherry", "Kiwi", "Mango", "Orange", "Pineapple", "Strawberry", "Watermelon"}; + static int listbox_item_current = 1; + ImGui::ListBox("listbox\n(single select)", &listbox_item_current, listbox_items, IM_ARRAYSIZE(listbox_items), 4); + + //static int listbox_item_current2 = 2; + //ImGui::PushItemWidth(-1); + //ImGui::ListBox("##listbox2", &listbox_item_current2, listbox_items, IM_ARRAYSIZE(listbox_items), 4); + //ImGui::PopItemWidth(); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Trees")) + { + if (ImGui::TreeNode("Basic trees")) + { + for (int i = 0; i < 5; i++) + if (ImGui::TreeNode((void*)(intptr_t)i, "Child %d", i)) + { + ImGui::Text("blah blah"); + ImGui::SameLine(); + if (ImGui::SmallButton("button")) + { + }; + ImGui::TreePop(); + } + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Advanced, with Selectable nodes")) + { + ShowHelpMarker("This is a more standard looking tree with selectable nodes.\nClick to select, CTRL+Click to toggle, click on arrows or double-click to open."); + static bool align_label_with_current_x_position = false; + ImGui::Checkbox("Align label with current X position)", &align_label_with_current_x_position); + ImGui::Text("Hello!"); + if (align_label_with_current_x_position) + ImGui::Unindent(ImGui::GetTreeNodeToLabelSpacing()); + + static int selection_mask = (1 << 2); // Dumb representation of what may be user-side selection state. You may carry selection state inside or outside your objects in whatever format you see fit. + int node_clicked = -1; // Temporary storage of what node we have clicked to process selection at the end of the loop. May be a pointer to your own node type, etc. + ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, ImGui::GetFontSize() * 3); // Increase spacing to differentiate leaves from expanded contents. + for (int i = 0; i < 6; i++) + { + // Disable the default open on single-click behavior and pass in Selected flag according to our selection state. + ImGuiTreeNodeFlags node_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ((selection_mask & (1 << i)) ? ImGuiTreeNodeFlags_Selected : 0); + if (i < 3) + { + // Node + bool node_open = ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Node %d", i); + if (ImGui::IsItemClicked()) + node_clicked = i; + if (node_open) + { + ImGui::Text("Blah blah\nBlah Blah"); + ImGui::TreePop(); + } + } + else + { + // Leaf: The only reason we have a TreeNode at all is to allow selection of the leaf. Otherwise we can use BulletText() or TreeAdvanceToLabelPos()+Text(). + node_flags |= ImGuiTreeNodeFlags_Leaf | ImGuiTreeNodeFlags_NoTreePushOnOpen; // ImGuiTreeNodeFlags_Bullet + ImGui::TreeNodeEx((void*)(intptr_t)i, node_flags, "Selectable Leaf %d", i); + if (ImGui::IsItemClicked()) + node_clicked = i; + } + } + if (node_clicked != -1) + { + // Update selection state. Process outside of tree loop to avoid visual inconsistencies during the clicking-frame. + if (ImGui::GetIO().KeyCtrl) + selection_mask ^= (1 << node_clicked); // CTRL+click to toggle + else //if (!(selection_mask & (1 << node_clicked))) // Depending on selection behavior you want, this commented bit preserve selection when clicking on item that is part of the selection + selection_mask = (1 << node_clicked); // Click to single-select + } + ImGui::PopStyleVar(); + if (align_label_with_current_x_position) + ImGui::Indent(ImGui::GetTreeNodeToLabelSpacing()); + ImGui::TreePop(); + } + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Collapsing Headers")) + { + static bool closable_group = true; + ImGui::Checkbox("Enable extra group", &closable_group); + if (ImGui::CollapsingHeader("Header")) + { + ImGui::Text("IsItemHovered: %d", IsItemHovered()); + for (int i = 0; i < 5; i++) + ImGui::Text("Some content %d", i); + } + if (ImGui::CollapsingHeader("Header with a close button", &closable_group)) + { + ImGui::Text("IsItemHovered: %d", IsItemHovered()); + for (int i = 0; i < 5; i++) + ImGui::Text("More content %d", i); + } + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Bullets")) + { + ImGui::BulletText("Bullet point 1"); + ImGui::BulletText("Bullet point 2\nOn multiple lines"); + ImGui::Bullet(); + ImGui::Text("Bullet point 3 (two calls)"); + ImGui::Bullet(); + ImGui::SmallButton("Button"); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Text")) + { + if (ImGui::TreeNode("Colored Text")) + { + // Using shortcut. You can use PushStyleColor()/PopStyleColor() for more flexibility. + ImGui::TextColored(ImVec4(1.0f, 0.0f, 1.0f, 1.0f), "Pink"); + ImGui::TextColored(ImVec4(1.0f, 1.0f, 0.0f, 1.0f), "Yellow"); + ImGui::TextDisabled("Disabled"); + ImGui::SameLine(); + ShowHelpMarker("The TextDisabled color is stored in ImGuiStyle."); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Word Wrapping")) + { + // Using shortcut. You can use PushTextWrapPos()/PopTextWrapPos() for more flexibility. + ImGui::TextWrapped("This text should automatically wrap on the edge of the window. The current implementation for text wrapping follows simple rules suitable for English and possibly other languages."); + ImGui::Spacing(); + + static float wrap_width = 200.0f; + ImGui::SliderFloat("Wrap width", &wrap_width, -20, 600, "%.0f"); + + ImGui::Text("Test paragraph 1:"); + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(pos.x + wrap_width, pos.y), ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight()), IM_COL32(255, 0, 255, 255)); + ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width); + ImGui::Text("The lazy dog is a good dog. This paragraph is made to fit within %.0f pixels. Testing a 1 character word. The quick brown fox jumps over the lazy dog.", wrap_width); + ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255, 255, 0, 255)); + ImGui::PopTextWrapPos(); + + ImGui::Text("Test paragraph 2:"); + pos = ImGui::GetCursorScreenPos(); + ImGui::GetWindowDrawList()->AddRectFilled(ImVec2(pos.x + wrap_width, pos.y), ImVec2(pos.x + wrap_width + 10, pos.y + ImGui::GetTextLineHeight()), IM_COL32(255, 0, 255, 255)); + ImGui::PushTextWrapPos(ImGui::GetCursorPos().x + wrap_width); + ImGui::Text("aaaaaaaa bbbbbbbb, c cccccccc,dddddddd. d eeeeeeee ffffffff. gggggggg!hhhhhhhh"); + ImGui::GetWindowDrawList()->AddRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax(), IM_COL32(255, 255, 0, 255)); + ImGui::PopTextWrapPos(); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("UTF-8 Text")) + { + // UTF-8 test with Japanese characters + // (needs a suitable font, try Arial Unicode or M+ fonts http://mplus-fonts.sourceforge.jp/mplus-outline-fonts/index-en.html) + // - From C++11 you can use the u8"my text" syntax to encode literal strings as UTF-8 + // - For earlier compiler, you may be able to encode your sources as UTF-8 (e.g. Visual Studio save your file as 'UTF-8 without signature') + // - HOWEVER, FOR THIS DEMO FILE, BECAUSE WE WANT TO SUPPORT COMPILER, WE ARE *NOT* INCLUDING RAW UTF-8 CHARACTERS IN THIS SOURCE FILE. + // Instead we are encoding a few string with hexadecimal constants. Don't do this in your application! + // Note that characters values are preserved even by InputText() if the font cannot be displayed, so you can safely copy & paste garbled characters into another application. + ImGui::TextWrapped("CJK text will only appears if the font was loaded with the appropriate CJK character ranges. Call io.Font->LoadFromFileTTF() manually to load extra character ranges."); + ImGui::Text("Hiragana: \xe3\x81\x8b\xe3\x81\x8d\xe3\x81\x8f\xe3\x81\x91\xe3\x81\x93 (kakikukeko)"); + ImGui::Text("Kanjis: \xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e (nihongo)"); + static char buf[32] = "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e"; // "nihongo" + ImGui::InputText("UTF-8 input", buf, IM_ARRAYSIZE(buf)); + ImGui::TreePop(); + } + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Images")) + { + ImGui::TextWrapped("Below we are displaying the font texture (which is the only texture we have access to in this demo). Use the 'ImTextureID' type as storage to pass pointers or identifier to your own texture data. Hover the texture for a zoomed view!"); + ImGuiIO& io = ImGui::GetIO(); + + // Here we are grabbing the font texture because that's the only one we have access to inside the demo code. + // Remember that ImTextureID is just storage for whatever you want it to be, it is essentially a value that will be passed to the render function inside the ImDrawCmd structure. + // If you use one of the default imgui_impl_XXXX.cpp renderer, they all have comments at the top of their file to specify what they expect to be stored in ImTextureID. + // (for example, the imgui_impl_dx11.cpp renderer expect a 'ID3D11ShaderResourceView*' pointer. The imgui_impl_glfw_gl3.cpp renderer expect a GLuint OpenGL texture identifier etc.) + // If you decided that ImTextureID = MyEngineTexture*, then you can pass your MyEngineTexture* pointers to ImGui::Image(), and gather width/height through your own functions, etc. + // Using ShowMetricsWindow() as a "debugger" to inspect the draw data that are being passed to your render will help you debug issues if you are confused about this. + // Consider using the lower-level ImDrawList::AddImage() API, via ImGui::GetWindowDrawList()->AddImage(). + ImTextureID my_tex_id = io.Fonts->TexID; + float my_tex_w = (float)io.Fonts->TexWidth; + float my_tex_h = (float)io.Fonts->TexHeight; + + ImGui::Text("%.0fx%.0f", my_tex_w, my_tex_h); + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImGui::Image(my_tex_id, ImVec2(my_tex_w, my_tex_h), ImVec2(0, 0), ImVec2(1, 1), ImColor(255, 255, 255, 255), ImColor(255, 255, 255, 128)); + if (ImGui::IsItemHovered()) + { + ImGui::BeginTooltip(); + float focus_sz = 32.0f; + float focus_x = io.MousePos.x - pos.x - focus_sz * 0.5f; + if (focus_x < 0.0f) + focus_x = 0.0f; + else if (focus_x > my_tex_w - focus_sz) + focus_x = my_tex_w - focus_sz; + float focus_y = io.MousePos.y - pos.y - focus_sz * 0.5f; + if (focus_y < 0.0f) + focus_y = 0.0f; + else if (focus_y > my_tex_h - focus_sz) + focus_y = my_tex_h - focus_sz; + ImGui::Text("Min: (%.2f, %.2f)", focus_x, focus_y); + ImGui::Text("Max: (%.2f, %.2f)", focus_x + focus_sz, focus_y + focus_sz); + ImVec2 uv0 = ImVec2((focus_x) / my_tex_w, (focus_y) / my_tex_h); + ImVec2 uv1 = ImVec2((focus_x + focus_sz) / my_tex_w, (focus_y + focus_sz) / my_tex_h); + ImGui::Image(my_tex_id, ImVec2(128, 128), uv0, uv1, ImColor(255, 255, 255, 255), ImColor(255, 255, 255, 128)); + ImGui::EndTooltip(); + } + ImGui::TextWrapped("And now some textured buttons.."); + static int pressed_count = 0; + for (int i = 0; i < 8; i++) + { + ImGui::PushID(i); + int frame_padding = -1 + i; // -1 = uses default padding + if (ImGui::ImageButton(my_tex_id, ImVec2(32, 32), ImVec2(0, 0), ImVec2(32.0f / my_tex_w, 32 / my_tex_h), frame_padding, ImColor(0, 0, 0, 255))) + pressed_count += 1; + ImGui::PopID(); + ImGui::SameLine(); + } + ImGui::NewLine(); + ImGui::Text("Pressed %d times.", pressed_count); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Selectables")) + { + // Selectable() has 2 overloads: + // - The one taking "bool selected" as a read-only selection information. When Selectable() has been clicked is returns true and you can alter selection state accordingly. + // - The one taking "bool* p_selected" as a read-write selection information (convenient in some cases) + // The earlier is more flexible, as in real application your selection may be stored in a different manner (in flags within objects, as an external list, etc). + if (ImGui::TreeNode("Basic")) + { + static bool selection[5] = {false, true, false, false, false}; + ImGui::Selectable("1. I am selectable", &selection[0]); + ImGui::Selectable("2. I am selectable", &selection[1]); + ImGui::Text("3. I am not selectable"); + ImGui::Selectable("4. I am selectable", &selection[3]); + if (ImGui::Selectable("5. I am double clickable", selection[4], ImGuiSelectableFlags_AllowDoubleClick)) + if (ImGui::IsMouseDoubleClicked(0)) + selection[4] = !selection[4]; + ImGui::TreePop(); + } + if (ImGui::TreeNode("Selection State: Single Selection")) + { + static int selected = -1; + for (int n = 0; n < 5; n++) + { + char buf[32]; + sprintf(buf, "Object %d", n); + if (ImGui::Selectable(buf, selected == n)) + selected = n; + } + ImGui::TreePop(); + } + if (ImGui::TreeNode("Selection State: Multiple Selection")) + { + ShowHelpMarker("Hold CTRL and click to select multiple items."); + static bool selection[5] = {false, false, false, false, false}; + for (int n = 0; n < 5; n++) + { + char buf[32]; + sprintf(buf, "Object %d", n); + if (ImGui::Selectable(buf, selection[n])) + { + if (!ImGui::GetIO().KeyCtrl) // Clear selection when CTRL is not held + memset(selection, 0, sizeof(selection)); + selection[n] ^= 1; + } + } + ImGui::TreePop(); + } + if (ImGui::TreeNode("Rendering more text into the same line")) + { + // Using the Selectable() override that takes "bool* p_selected" parameter and toggle your booleans automatically. + static bool selected[3] = {false, false, false}; + ImGui::Selectable("main.c", &selected[0]); + ImGui::SameLine(300); + ImGui::Text(" 2,345 bytes"); + ImGui::Selectable("Hello.cpp", &selected[1]); + ImGui::SameLine(300); + ImGui::Text("12,345 bytes"); + ImGui::Selectable("Hello.h", &selected[2]); + ImGui::SameLine(300); + ImGui::Text(" 2,345 bytes"); + ImGui::TreePop(); + } + if (ImGui::TreeNode("In columns")) + { + ImGui::Columns(3, NULL, false); + static bool selected[16] = {0}; + for (int i = 0; i < 16; i++) + { + char label[32]; + sprintf(label, "Item %d", i); + if (ImGui::Selectable(label, &selected[i])) + { + } + ImGui::NextColumn(); + } + ImGui::Columns(1); + ImGui::TreePop(); + } + if (ImGui::TreeNode("Grid")) + { + static bool selected[16] = {true, false, false, false, false, true, false, false, false, false, true, false, false, false, false, true}; + for (int i = 0; i < 16; i++) + { + ImGui::PushID(i); + if (ImGui::Selectable("Sailor", &selected[i], 0, ImVec2(50, 50))) + { + int x = i % 4, y = i / 4; + if (x > 0) selected[i - 1] ^= 1; + if (x < 3) selected[i + 1] ^= 1; + if (y > 0) selected[i - 4] ^= 1; + if (y < 3) selected[i + 4] ^= 1; + } + if ((i % 4) < 3) ImGui::SameLine(); + ImGui::PopID(); + } + ImGui::TreePop(); + } + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Filtered Text Input")) + { + static char buf1[64] = ""; + ImGui::InputText("default", buf1, 64); + static char buf2[64] = ""; + ImGui::InputText("decimal", buf2, 64, ImGuiInputTextFlags_CharsDecimal); + static char buf3[64] = ""; + ImGui::InputText("hexadecimal", buf3, 64, ImGuiInputTextFlags_CharsHexadecimal | ImGuiInputTextFlags_CharsUppercase); + static char buf4[64] = ""; + ImGui::InputText("uppercase", buf4, 64, ImGuiInputTextFlags_CharsUppercase); + static char buf5[64] = ""; + ImGui::InputText("no blank", buf5, 64, ImGuiInputTextFlags_CharsNoBlank); + struct TextFilters + { + static int FilterImGuiLetters(ImGuiTextEditCallbackData* data) + { + if (data->EventChar < 256 && strchr("imgui", (char)data->EventChar)) return 0; + return 1; + } + }; + static char buf6[64] = ""; + ImGui::InputText("\"imgui\" letters", buf6, 64, ImGuiInputTextFlags_CallbackCharFilter, TextFilters::FilterImGuiLetters); + + ImGui::Text("Password input"); + static char bufpass[64] = "password123"; + ImGui::InputText("password", bufpass, 64, ImGuiInputTextFlags_Password | ImGuiInputTextFlags_CharsNoBlank); + ImGui::SameLine(); + ShowHelpMarker("Display all characters as '*'.\nDisable clipboard cut and copy.\nDisable logging.\n"); + ImGui::InputText("password (clear)", bufpass, 64, ImGuiInputTextFlags_CharsNoBlank); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Multi-line Text Input")) + { + static bool read_only = false; + static char text[1024 * 16] = + "/*\n" + " The Pentium F00F bug, shorthand for F0 0F C7 C8,\n" + " the hexadecimal encoding of one offending instruction,\n" + " more formally, the invalid operand with locked CMPXCHG8B\n" + " instruction bug, is a design flaw in the majority of\n" + " Intel Pentium, Pentium MMX, and Pentium OverDrive\n" + " processors (all in the P5 microarchitecture).\n" + "*/\n\n" + "label:\n" + "\tlock cmpxchg8b eax\n"; + + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); + ImGui::Checkbox("Read-only", &read_only); + ImGui::PopStyleVar(); + ImGui::InputTextMultiline("##source", text, IM_ARRAYSIZE(text), ImVec2(-1.0f, ImGui::GetTextLineHeight() * 16), ImGuiInputTextFlags_AllowTabInput | (read_only ? ImGuiInputTextFlags_ReadOnly : 0)); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Plots widgets")) + { + static bool animate = true; + ImGui::Checkbox("Animate", &animate); + + static float arr[] = {0.6f, 0.1f, 1.0f, 0.5f, 0.92f, 0.1f, 0.2f}; + ImGui::PlotLines("Frame Times", arr, IM_ARRAYSIZE(arr)); + + // Create a dummy array of contiguous float values to plot + // Tip: If your float aren't contiguous but part of a structure, you can pass a pointer to your first float and the sizeof() of your structure in the Stride parameter. + static float values[90] = {0}; + static int values_offset = 0; + static float refresh_time = 0.0f; + if (!animate || refresh_time == 0.0f) + refresh_time = ImGui::GetTime(); + while (refresh_time < ImGui::GetTime()) // Create dummy data at fixed 60 hz rate for the demo + { + static float phase = 0.0f; + values[values_offset] = cosf(phase); + values_offset = (values_offset + 1) % IM_ARRAYSIZE(values); + phase += 0.10f * values_offset; + refresh_time += 1.0f / 60.0f; + } + ImGui::PlotLines("Lines", values, IM_ARRAYSIZE(values), values_offset, "avg 0.0", -1.0f, 1.0f, ImVec2(0, 80)); + ImGui::PlotHistogram("Histogram", arr, IM_ARRAYSIZE(arr), 0, NULL, 0.0f, 1.0f, ImVec2(0, 80)); + + // Use functions to generate output + // FIXME: This is rather awkward because current plot API only pass in indices. We probably want an API passing floats and user provide sample rate/count. + struct Funcs + { + static float Sin(void*, int i) { return sinf(i * 0.1f); } + static float Saw(void*, int i) { return (i & 1) ? 1.0f : -1.0f; } + }; + static int func_type = 0, display_count = 70; + ImGui::Separator(); + ImGui::PushItemWidth(100); + ImGui::Combo("func", &func_type, "Sin\0Saw\0"); + ImGui::PopItemWidth(); + ImGui::SameLine(); + ImGui::SliderInt("Sample count", &display_count, 1, 400); + float (*func)(void*, int) = (func_type == 0) ? Funcs::Sin : Funcs::Saw; + ImGui::PlotLines("Lines", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0, 80)); + ImGui::PlotHistogram("Histogram", func, NULL, display_count, 0, NULL, -1.0f, 1.0f, ImVec2(0, 80)); + ImGui::Separator(); + + // Animate a simple progress bar + static float progress = 0.0f, progress_dir = 1.0f; + if (animate) + { + progress += progress_dir * 0.4f * ImGui::GetIO().DeltaTime; + if (progress >= +1.1f) + { + progress = +1.1f; + progress_dir *= -1.0f; + } + if (progress <= -0.1f) + { + progress = -0.1f; + progress_dir *= -1.0f; + } + } + + // Typically we would use ImVec2(-1.0f,0.0f) to use all available width, or ImVec2(width,0.0f) for a specified width. ImVec2(0.0f,0.0f) uses ItemWidth. + ImGui::ProgressBar(progress, ImVec2(0.0f, 0.0f)); + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemInnerSpacing.x); + ImGui::Text("Progress Bar"); + + float progress_saturated = (progress < 0.0f) ? 0.0f : (progress > 1.0f) ? 1.0f : progress; + char buf[32]; + sprintf(buf, "%d/%d", (int)(progress_saturated * 1753), 1753); + ImGui::ProgressBar(progress, ImVec2(0.f, 0.f), buf); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Color/Picker Widgets")) + { + static ImVec4 color = ImColor(114, 144, 154, 200); + + static bool alpha_preview = true; + static bool alpha_half_preview = false; + static bool options_menu = true; + static bool hdr = false; + ImGui::Checkbox("With Alpha Preview", &alpha_preview); + ImGui::Checkbox("With Half Alpha Preview", &alpha_half_preview); + ImGui::Checkbox("With Options Menu", &options_menu); + ImGui::SameLine(); + ShowHelpMarker("Right-click on the individual color widget to show options."); + ImGui::Checkbox("With HDR", &hdr); + ImGui::SameLine(); + ShowHelpMarker("Currently all this does is to lift the 0..1 limits on dragging widgets."); + int misc_flags = (hdr ? ImGuiColorEditFlags_HDR : 0) | (alpha_half_preview ? ImGuiColorEditFlags_AlphaPreviewHalf : (alpha_preview ? ImGuiColorEditFlags_AlphaPreview : 0)) | (options_menu ? 0 : ImGuiColorEditFlags_NoOptions); + + ImGui::Text("Color widget:"); + ImGui::SameLine(); + ShowHelpMarker("Click on the colored square to open a color picker.\nCTRL+click on individual component to input value.\n"); + ImGui::ColorEdit3("MyColor##1", (float*)&color, misc_flags); + + ImGui::Text("Color widget HSV with Alpha:"); + ImGui::ColorEdit4("MyColor##2", (float*)&color, ImGuiColorEditFlags_HSV | misc_flags); + + ImGui::Text("Color widget with Float Display:"); + ImGui::ColorEdit4("MyColor##2f", (float*)&color, ImGuiColorEditFlags_Float | misc_flags); + + ImGui::Text("Color button with Picker:"); + ImGui::SameLine(); + ShowHelpMarker("With the ImGuiColorEditFlags_NoInputs flag you can hide all the slider/text inputs.\nWith the ImGuiColorEditFlags_NoLabel flag you can pass a non-empty label which will only be used for the tooltip and picker popup."); + ImGui::ColorEdit4("MyColor##3", (float*)&color, ImGuiColorEditFlags_NoInputs | ImGuiColorEditFlags_NoLabel | misc_flags); + + ImGui::Text("Color button with Custom Picker Popup:"); + + // Generate a dummy palette + static bool saved_palette_inited = false; + static ImVec4 saved_palette[32]; + if (!saved_palette_inited) + for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++) + { + ImGui::ColorConvertHSVtoRGB(n / 31.0f, 0.8f, 0.8f, saved_palette[n].x, saved_palette[n].y, saved_palette[n].z); + saved_palette[n].w = 1.0f; // Alpha + } + saved_palette_inited = true; + + static ImVec4 backup_color; + bool open_popup = ImGui::ColorButton("MyColor##3b", color, misc_flags); + ImGui::SameLine(); + open_popup |= ImGui::Button("Palette"); + if (open_popup) + { + ImGui::OpenPopup("mypicker"); + backup_color = color; + } + if (ImGui::BeginPopup("mypicker")) + { + // FIXME: Adding a drag and drop example here would be perfect! + ImGui::Text("MY CUSTOM COLOR PICKER WITH AN AMAZING PALETTE!"); + ImGui::Separator(); + ImGui::ColorPicker4("##picker", (float*)&color, misc_flags | ImGuiColorEditFlags_NoSidePreview | ImGuiColorEditFlags_NoSmallPreview); + ImGui::SameLine(); + ImGui::BeginGroup(); + ImGui::Text("Current"); + ImGui::ColorButton("##current", color, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(60, 40)); + ImGui::Text("Previous"); + if (ImGui::ColorButton("##previous", backup_color, ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_AlphaPreviewHalf, ImVec2(60, 40))) + color = backup_color; + ImGui::Separator(); + ImGui::Text("Palette"); + for (int n = 0; n < IM_ARRAYSIZE(saved_palette); n++) + { + ImGui::PushID(n); + if ((n % 8) != 0) + ImGui::SameLine(0.0f, ImGui::GetStyle().ItemSpacing.y); + if (ImGui::ColorButton("##palette", saved_palette[n], ImGuiColorEditFlags_NoAlpha | ImGuiColorEditFlags_NoPicker | ImGuiColorEditFlags_NoTooltip, ImVec2(20, 20))) + color = ImVec4(saved_palette[n].x, saved_palette[n].y, saved_palette[n].z, color.w); // Preserve alpha! + + if (ImGui::BeginDragDropTarget()) + { + if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_3F)) + memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 3); + if (const ImGuiPayload* payload = AcceptDragDropPayload(IMGUI_PAYLOAD_TYPE_COLOR_4F)) + memcpy((float*)&saved_palette[n], payload->Data, sizeof(float) * 4); + EndDragDropTarget(); + } + + ImGui::PopID(); + } + ImGui::EndGroup(); + ImGui::EndPopup(); + } + + ImGui::Text("Color button only:"); + ImGui::ColorButton("MyColor##3c", *(ImVec4*)&color, misc_flags, ImVec2(80, 80)); + + ImGui::Text("Color picker:"); + static bool alpha = true; + static bool alpha_bar = true; + static bool side_preview = true; + static bool ref_color = false; + static ImVec4 ref_color_v(1.0f, 0.0f, 1.0f, 0.5f); + static int inputs_mode = 2; + static int picker_mode = 0; + ImGui::Checkbox("With Alpha", &alpha); + ImGui::Checkbox("With Alpha Bar", &alpha_bar); + ImGui::Checkbox("With Side Preview", &side_preview); + if (side_preview) + { + ImGui::SameLine(); + ImGui::Checkbox("With Ref Color", &ref_color); + if (ref_color) + { + ImGui::SameLine(); + ImGui::ColorEdit4("##RefColor", &ref_color_v.x, ImGuiColorEditFlags_NoInputs | misc_flags); + } + } + ImGui::Combo("Inputs Mode", &inputs_mode, "All Inputs\0No Inputs\0RGB Input\0HSV Input\0HEX Input\0"); + ImGui::Combo("Picker Mode", &picker_mode, "Auto/Current\0Hue bar + SV rect\0Hue wheel + SV triangle\0"); + ImGui::SameLine(); + ShowHelpMarker("User can right-click the picker to change mode."); + ImGuiColorEditFlags flags = misc_flags; + if (!alpha) flags |= ImGuiColorEditFlags_NoAlpha; // This is by default if you call ColorPicker3() instead of ColorPicker4() + if (alpha_bar) flags |= ImGuiColorEditFlags_AlphaBar; + if (!side_preview) flags |= ImGuiColorEditFlags_NoSidePreview; + if (picker_mode == 1) flags |= ImGuiColorEditFlags_PickerHueBar; + if (picker_mode == 2) flags |= ImGuiColorEditFlags_PickerHueWheel; + if (inputs_mode == 1) flags |= ImGuiColorEditFlags_NoInputs; + if (inputs_mode == 2) flags |= ImGuiColorEditFlags_RGB; + if (inputs_mode == 3) flags |= ImGuiColorEditFlags_HSV; + if (inputs_mode == 4) flags |= ImGuiColorEditFlags_HEX; + ImGui::ColorPicker4("MyColor##4", (float*)&color, flags, ref_color ? &ref_color_v.x : NULL); + + ImGui::Text("Programmatically set defaults/options:"); + ImGui::SameLine(); + ShowHelpMarker("SetColorEditOptions() is designed to allow you to set boot-time default.\nWe don't have Push/Pop functions because you can force options on a per-widget basis if needed, and the user can change non-forced ones with the options menu.\nWe don't have a getter to avoid encouraging you to persistently save values that aren't forward-compatible."); + if (ImGui::Button("Uint8 + HSV")) + ImGui::SetColorEditOptions(ImGuiColorEditFlags_Uint8 | ImGuiColorEditFlags_HSV); + ImGui::SameLine(); + if (ImGui::Button("Float + HDR")) + ImGui::SetColorEditOptions(ImGuiColorEditFlags_Float | ImGuiColorEditFlags_RGB); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Range Widgets")) + { + static float begin = 10, end = 90; + static int begin_i = 100, end_i = 1000; + ImGui::DragFloatRange2("range", &begin, &end, 0.25f, 0.0f, 100.0f, "Min: %.1f %%", "Max: %.1f %%"); + ImGui::DragIntRange2("range int (no bounds)", &begin_i, &end_i, 5, 0, 0, "Min: %.0f units", "Max: %.0f units"); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Multi-component Widgets")) + { + static float vec4f[4] = {0.10f, 0.20f, 0.30f, 0.44f}; + static int vec4i[4] = {1, 5, 100, 255}; + + ImGui::InputFloat2("input float2", vec4f); + ImGui::DragFloat2("drag float2", vec4f, 0.01f, 0.0f, 1.0f); + ImGui::SliderFloat2("slider float2", vec4f, 0.0f, 1.0f); + ImGui::DragInt2("drag int2", vec4i, 1, 0, 255); + ImGui::InputInt2("input int2", vec4i); + ImGui::SliderInt2("slider int2", vec4i, 0, 255); + ImGui::Spacing(); + + ImGui::InputFloat3("input float3", vec4f); + ImGui::DragFloat3("drag float3", vec4f, 0.01f, 0.0f, 1.0f); + ImGui::SliderFloat3("slider float3", vec4f, 0.0f, 1.0f); + ImGui::DragInt3("drag int3", vec4i, 1, 0, 255); + ImGui::InputInt3("input int3", vec4i); + ImGui::SliderInt3("slider int3", vec4i, 0, 255); + ImGui::Spacing(); + + ImGui::InputFloat4("input float4", vec4f); + ImGui::DragFloat4("drag float4", vec4f, 0.01f, 0.0f, 1.0f); + ImGui::SliderFloat4("slider float4", vec4f, 0.0f, 1.0f); + ImGui::InputInt4("input int4", vec4i); + ImGui::DragInt4("drag int4", vec4i, 1, 0, 255); + ImGui::SliderInt4("slider int4", vec4i, 0, 255); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Vertical Sliders")) + { + const float spacing = 4; + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(spacing, spacing)); + + static int int_value = 0; + ImGui::VSliderInt("##int", ImVec2(18, 160), &int_value, 0, 5); + ImGui::SameLine(); + + static float values[7] = {0.0f, 0.60f, 0.35f, 0.9f, 0.70f, 0.20f, 0.0f}; + ImGui::PushID("set1"); + for (int i = 0; i < 7; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::PushID(i); + ImGui::PushStyleColor(ImGuiCol_FrameBg, (ImVec4)ImColor::HSV(i / 7.0f, 0.5f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_FrameBgHovered, (ImVec4)ImColor::HSV(i / 7.0f, 0.6f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_FrameBgActive, (ImVec4)ImColor::HSV(i / 7.0f, 0.7f, 0.5f)); + ImGui::PushStyleColor(ImGuiCol_SliderGrab, (ImVec4)ImColor::HSV(i / 7.0f, 0.9f, 0.9f)); + ImGui::VSliderFloat("##v", ImVec2(18, 160), &values[i], 0.0f, 1.0f, ""); + if (ImGui::IsItemActive() || ImGui::IsItemHovered()) + ImGui::SetTooltip("%.3f", values[i]); + ImGui::PopStyleColor(4); + ImGui::PopID(); + } + ImGui::PopID(); + + ImGui::SameLine(); + ImGui::PushID("set2"); + static float values2[4] = {0.20f, 0.80f, 0.40f, 0.25f}; + const int rows = 3; + const ImVec2 small_slider_size(18, (160.0f - (rows - 1) * spacing) / rows); + for (int nx = 0; nx < 4; nx++) + { + if (nx > 0) ImGui::SameLine(); + ImGui::BeginGroup(); + for (int ny = 0; ny < rows; ny++) + { + ImGui::PushID(nx * rows + ny); + ImGui::VSliderFloat("##v", small_slider_size, &values2[nx], 0.0f, 1.0f, ""); + if (ImGui::IsItemActive() || ImGui::IsItemHovered()) + ImGui::SetTooltip("%.3f", values2[nx]); + ImGui::PopID(); + } + ImGui::EndGroup(); + } + ImGui::PopID(); + + ImGui::SameLine(); + ImGui::PushID("set3"); + for (int i = 0; i < 4; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::PushID(i); + ImGui::PushStyleVar(ImGuiStyleVar_GrabMinSize, 40); + ImGui::VSliderFloat("##v", ImVec2(40, 160), &values[i], 0.0f, 1.0f, "%.2f\nsec"); + ImGui::PopStyleVar(); + ImGui::PopID(); + } + ImGui::PopID(); + ImGui::PopStyleVar(); + ImGui::TreePop(); + } + } + + if (ImGui::CollapsingHeader("Layout")) + { + if (ImGui::TreeNode("Child regions")) + { + static bool disable_mouse_wheel = false; + static bool disable_menu = false; + ImGui::Checkbox("Disable Mouse Wheel", &disable_mouse_wheel); + ImGui::Checkbox("Disable Menu", &disable_menu); + + static int line = 50; + bool goto_line = ImGui::Button("Goto"); + ImGui::SameLine(); + ImGui::PushItemWidth(100); + goto_line |= ImGui::InputInt("##Line", &line, 0, 0, ImGuiInputTextFlags_EnterReturnsTrue); + ImGui::PopItemWidth(); + + // Child 1: no border, enable horizontal scrollbar + { + ImGui::BeginChild("Child1", ImVec2(ImGui::GetWindowContentRegionWidth() * 0.5f, 300), false, ImGuiWindowFlags_HorizontalScrollbar | (disable_mouse_wheel ? ImGuiWindowFlags_NoScrollWithMouse : 0)); + for (int i = 0; i < 100; i++) + { + ImGui::Text("%04d: scrollable region", i); + if (goto_line && line == i) + ImGui::SetScrollHere(); + } + if (goto_line && line >= 100) + ImGui::SetScrollHere(); + ImGui::EndChild(); + } + + ImGui::SameLine(); + + // Child 2: rounded border + { + ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 5.0f); + ImGui::BeginChild("Child2", ImVec2(0, 300), true, (disable_mouse_wheel ? ImGuiWindowFlags_NoScrollWithMouse : 0) | (disable_menu ? 0 : ImGuiWindowFlags_MenuBar)); + if (!disable_menu && ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("Menu")) + { + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); + } + ImGui::Columns(2); + for (int i = 0; i < 100; i++) + { + if (i == 50) + ImGui::NextColumn(); + char buf[32]; + sprintf(buf, "%08x", i * 5731); + ImGui::Button(buf, ImVec2(-1.0f, 0.0f)); + } + ImGui::EndChild(); + ImGui::PopStyleVar(); + } + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Widgets Width")) + { + static float f = 0.0f; + ImGui::Text("PushItemWidth(100)"); + ImGui::SameLine(); + ShowHelpMarker("Fixed width."); + ImGui::PushItemWidth(100); + ImGui::DragFloat("float##1", &f); + ImGui::PopItemWidth(); + + ImGui::Text("PushItemWidth(GetWindowWidth() * 0.5f)"); + ImGui::SameLine(); + ShowHelpMarker("Half of window width."); + ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.5f); + ImGui::DragFloat("float##2", &f); + ImGui::PopItemWidth(); + + ImGui::Text("PushItemWidth(GetContentRegionAvailWidth() * 0.5f)"); + ImGui::SameLine(); + ShowHelpMarker("Half of available width.\n(~ right-cursor_pos)\n(works within a column set)"); + ImGui::PushItemWidth(ImGui::GetContentRegionAvailWidth() * 0.5f); + ImGui::DragFloat("float##3", &f); + ImGui::PopItemWidth(); + + ImGui::Text("PushItemWidth(-100)"); + ImGui::SameLine(); + ShowHelpMarker("Align to right edge minus 100"); + ImGui::PushItemWidth(-100); + ImGui::DragFloat("float##4", &f); + ImGui::PopItemWidth(); + + ImGui::Text("PushItemWidth(-1)"); + ImGui::SameLine(); + ShowHelpMarker("Align to right edge"); + ImGui::PushItemWidth(-1); + ImGui::DragFloat("float##5", &f); + ImGui::PopItemWidth(); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Basic Horizontal Layout")) + { + ImGui::TextWrapped("(Use ImGui::SameLine() to keep adding items to the right of the preceding item)"); + + // Text + ImGui::Text("Two items: Hello"); + ImGui::SameLine(); + ImGui::TextColored(ImVec4(1, 1, 0, 1), "Sailor"); + + // Adjust spacing + ImGui::Text("More spacing: Hello"); + ImGui::SameLine(0, 20); + ImGui::TextColored(ImVec4(1, 1, 0, 1), "Sailor"); + + // Button + ImGui::AlignTextToFramePadding(); + ImGui::Text("Normal buttons"); + ImGui::SameLine(); + ImGui::Button("Banana"); + ImGui::SameLine(); + ImGui::Button("Apple"); + ImGui::SameLine(); + ImGui::Button("Corniflower"); + + // Button + ImGui::Text("Small buttons"); + ImGui::SameLine(); + ImGui::SmallButton("Like this one"); + ImGui::SameLine(); + ImGui::Text("can fit within a text block."); + + // Aligned to arbitrary position. Easy/cheap column. + ImGui::Text("Aligned"); + ImGui::SameLine(150); + ImGui::Text("x=150"); + ImGui::SameLine(300); + ImGui::Text("x=300"); + ImGui::Text("Aligned"); + ImGui::SameLine(150); + ImGui::SmallButton("x=150"); + ImGui::SameLine(300); + ImGui::SmallButton("x=300"); + + // Checkbox + static bool c1 = false, c2 = false, c3 = false, c4 = false; + ImGui::Checkbox("My", &c1); + ImGui::SameLine(); + ImGui::Checkbox("Tailor", &c2); + ImGui::SameLine(); + ImGui::Checkbox("Is", &c3); + ImGui::SameLine(); + ImGui::Checkbox("Rich", &c4); + + // Various + static float f0 = 1.0f, f1 = 2.0f, f2 = 3.0f; + ImGui::PushItemWidth(80); + const char* items[] = {"AAAA", "BBBB", "CCCC", "DDDD"}; + static int item = -1; + ImGui::Combo("Combo", &item, items, IM_ARRAYSIZE(items)); + ImGui::SameLine(); + ImGui::SliderFloat("X", &f0, 0.0f, 5.0f); + ImGui::SameLine(); + ImGui::SliderFloat("Y", &f1, 0.0f, 5.0f); + ImGui::SameLine(); + ImGui::SliderFloat("Z", &f2, 0.0f, 5.0f); + ImGui::PopItemWidth(); + + ImGui::PushItemWidth(80); + ImGui::Text("Lists:"); + static int selection[4] = {0, 1, 2, 3}; + for (int i = 0; i < 4; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::PushID(i); + ImGui::ListBox("", &selection[i], items, IM_ARRAYSIZE(items)); + ImGui::PopID(); + //if (ImGui::IsItemHovered()) ImGui::SetTooltip("ListBox %d hovered", i); + } + ImGui::PopItemWidth(); + + // Dummy + ImVec2 sz(30, 30); + ImGui::Button("A", sz); + ImGui::SameLine(); + ImGui::Dummy(sz); + ImGui::SameLine(); + ImGui::Button("B", sz); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Groups")) + { + ImGui::TextWrapped("(Using ImGui::BeginGroup()/EndGroup() to layout items. BeginGroup() basically locks the horizontal position. EndGroup() bundles the whole group so that you can use functions such as IsItemHovered() on it.)"); + ImGui::BeginGroup(); + { + ImGui::BeginGroup(); + ImGui::Button("AAA"); + ImGui::SameLine(); + ImGui::Button("BBB"); + ImGui::SameLine(); + ImGui::BeginGroup(); + ImGui::Button("CCC"); + ImGui::Button("DDD"); + ImGui::EndGroup(); + ImGui::SameLine(); + ImGui::Button("EEE"); + ImGui::EndGroup(); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("First group hovered"); + } + // Capture the group size and create widgets using the same size + ImVec2 size = ImGui::GetItemRectSize(); + const float values[5] = {0.5f, 0.20f, 0.80f, 0.60f, 0.25f}; + ImGui::PlotHistogram("##values", values, IM_ARRAYSIZE(values), 0, NULL, 0.0f, 1.0f, size); + + ImGui::Button("ACTION", ImVec2((size.x - ImGui::GetStyle().ItemSpacing.x) * 0.5f, size.y)); + ImGui::SameLine(); + ImGui::Button("REACTION", ImVec2((size.x - ImGui::GetStyle().ItemSpacing.x) * 0.5f, size.y)); + ImGui::EndGroup(); + ImGui::SameLine(); + + ImGui::Button("LEVERAGE\nBUZZWORD", size); + ImGui::SameLine(); + + ImGui::ListBoxHeader("List", size); + ImGui::Selectable("Selected", true); + ImGui::Selectable("Not Selected", false); + ImGui::ListBoxFooter(); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Text Baseline Alignment")) + { + ImGui::TextWrapped("(This is testing the vertical alignment that occurs on text to keep it at the same baseline as widgets. Lines only composed of text or \"small\" widgets fit in less vertical spaces than lines with normal widgets)"); + + ImGui::Text("One\nTwo\nThree"); + ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); + ImGui::SameLine(); + ImGui::Text("Banana"); + + ImGui::Text("Banana"); + ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); + ImGui::SameLine(); + ImGui::Text("One\nTwo\nThree"); + + ImGui::Button("HOP##1"); + ImGui::SameLine(); + ImGui::Text("Banana"); + ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); + ImGui::SameLine(); + ImGui::Text("Banana"); + + ImGui::Button("HOP##2"); + ImGui::SameLine(); + ImGui::Text("Hello\nWorld"); + ImGui::SameLine(); + ImGui::Text("Banana"); + + ImGui::Button("TEST##1"); + ImGui::SameLine(); + ImGui::Text("TEST"); + ImGui::SameLine(); + ImGui::SmallButton("TEST##2"); + + ImGui::AlignTextToFramePadding(); // If your line starts with text, call this to align it to upcoming widgets. + ImGui::Text("Text aligned to Widget"); + ImGui::SameLine(); + ImGui::Button("Widget##1"); + ImGui::SameLine(); + ImGui::Text("Widget"); + ImGui::SameLine(); + ImGui::SmallButton("Widget##2"); + ImGui::SameLine(); + ImGui::Button("Widget##3"); + + // Tree + const float spacing = ImGui::GetStyle().ItemInnerSpacing.x; + ImGui::Button("Button##1"); + ImGui::SameLine(0.0f, spacing); + if (ImGui::TreeNode("Node##1")) + { + for (int i = 0; i < 6; i++) ImGui::BulletText("Item %d..", i); + ImGui::TreePop(); + } // Dummy tree data + + ImGui::AlignTextToFramePadding(); // Vertically align text node a bit lower so it'll be vertically centered with upcoming widget. Otherwise you can use SmallButton (smaller fit). + bool node_open = ImGui::TreeNode("Node##2"); // Common mistake to avoid: if we want to SameLine after TreeNode we need to do it before we add child content. + ImGui::SameLine(0.0f, spacing); + ImGui::Button("Button##2"); + if (node_open) + { + for (int i = 0; i < 6; i++) ImGui::BulletText("Item %d..", i); + ImGui::TreePop(); + } // Dummy tree data + + // Bullet + ImGui::Button("Button##3"); + ImGui::SameLine(0.0f, spacing); + ImGui::BulletText("Bullet text"); + + ImGui::AlignTextToFramePadding(); + ImGui::BulletText("Node"); + ImGui::SameLine(0.0f, spacing); + ImGui::Button("Button##4"); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Scrolling")) + { + ImGui::TextWrapped("(Use SetScrollHere() or SetScrollFromPosY() to scroll to a given position.)"); + static bool track = true; + static int track_line = 50, scroll_to_px = 200; + ImGui::Checkbox("Track", &track); + ImGui::PushItemWidth(100); + ImGui::SameLine(130); + track |= ImGui::DragInt("##line", &track_line, 0.25f, 0, 99, "Line = %.0f"); + bool scroll_to = ImGui::Button("Scroll To Pos"); + ImGui::SameLine(130); + scroll_to |= ImGui::DragInt("##pos_y", &scroll_to_px, 1.00f, 0, 9999, "Y = %.0f px"); + ImGui::PopItemWidth(); + if (scroll_to) track = false; + + for (int i = 0; i < 5; i++) + { + if (i > 0) ImGui::SameLine(); + ImGui::BeginGroup(); + ImGui::Text("%s", i == 0 ? "Top" : i == 1 ? "25%" : i == 2 ? "Center" : i == 3 ? "75%" : "Bottom"); + ImGui::BeginChild(ImGui::GetID((void*)(intptr_t)i), ImVec2(ImGui::GetWindowWidth() * 0.17f, 200.0f), true); + if (scroll_to) + ImGui::SetScrollFromPosY(ImGui::GetCursorStartPos().y + scroll_to_px, i * 0.25f); + for (int line = 0; line < 100; line++) + { + if (track && line == track_line) + { + ImGui::TextColored(ImColor(255, 255, 0), "Line %d", line); + ImGui::SetScrollHere(i * 0.25f); // 0.0f:top, 0.5f:center, 1.0f:bottom + } + else + { + ImGui::Text("Line %d", line); + } + } + float scroll_y = ImGui::GetScrollY(), scroll_max_y = ImGui::GetScrollMaxY(); + ImGui::EndChild(); + ImGui::Text("%.0f/%0.f", scroll_y, scroll_max_y); + ImGui::EndGroup(); + } + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Horizontal Scrolling")) + { + ImGui::Bullet(); + ImGui::TextWrapped("Horizontal scrolling for a window has to be enabled explicitly via the ImGuiWindowFlags_HorizontalScrollbar flag."); + ImGui::Bullet(); + ImGui::TextWrapped("You may want to explicitly specify content width by calling SetNextWindowContentWidth() before Begin()."); + static int lines = 7; + ImGui::SliderInt("Lines", &lines, 1, 15); + ImGui::PushStyleVar(ImGuiStyleVar_FrameRounding, 3.0f); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2.0f, 1.0f)); + ImGui::BeginChild("scrolling", ImVec2(0, ImGui::GetFrameHeightWithSpacing() * 7 + 30), true, ImGuiWindowFlags_HorizontalScrollbar); + for (int line = 0; line < lines; line++) + { + // Display random stuff (for the sake of this trivial demo we are using basic Button+SameLine. If you want to create your own time line for a real application you may be better off + // manipulating the cursor position yourself, aka using SetCursorPos/SetCursorScreenPos to position the widgets yourself. You may also want to use the lower-level ImDrawList API) + int num_buttons = 10 + ((line & 1) ? line * 9 : line * 3); + for (int n = 0; n < num_buttons; n++) + { + if (n > 0) ImGui::SameLine(); + ImGui::PushID(n + line * 1000); + char num_buf[16]; + sprintf(num_buf, "%d", n); + const char* label = (!(n % 15)) ? "FizzBuzz" : (!(n % 3)) ? "Fizz" : (!(n % 5)) ? "Buzz" : num_buf; + float hue = n * 0.05f; + ImGui::PushStyleColor(ImGuiCol_Button, (ImVec4)ImColor::HSV(hue, 0.6f, 0.6f)); + ImGui::PushStyleColor(ImGuiCol_ButtonHovered, (ImVec4)ImColor::HSV(hue, 0.7f, 0.7f)); + ImGui::PushStyleColor(ImGuiCol_ButtonActive, (ImVec4)ImColor::HSV(hue, 0.8f, 0.8f)); + ImGui::Button(label, ImVec2(40.0f + sinf((float)(line + n)) * 20.0f, 0.0f)); + ImGui::PopStyleColor(3); + ImGui::PopID(); + } + } + float scroll_x = ImGui::GetScrollX(), scroll_max_x = ImGui::GetScrollMaxX(); + ImGui::EndChild(); + ImGui::PopStyleVar(2); + float scroll_x_delta = 0.0f; + ImGui::SmallButton("<<"); + if (ImGui::IsItemActive()) scroll_x_delta = -ImGui::GetIO().DeltaTime * 1000.0f; + ImGui::SameLine(); + ImGui::Text("Scroll from code"); + ImGui::SameLine(); + ImGui::SmallButton(">>"); + if (ImGui::IsItemActive()) scroll_x_delta = +ImGui::GetIO().DeltaTime * 1000.0f; + ImGui::SameLine(); + ImGui::Text("%.0f/%.0f", scroll_x, scroll_max_x); + if (scroll_x_delta != 0.0f) + { + ImGui::BeginChild("scrolling"); // Demonstrate a trick: you can use Begin to set yourself in the context of another window (here we are already out of your child window) + ImGui::SetScrollX(ImGui::GetScrollX() + scroll_x_delta); + ImGui::End(); + } + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Clipping")) + { + static ImVec2 size(100, 100), offset(50, 20); + ImGui::TextWrapped("On a per-widget basis we are occasionally clipping text CPU-side if it won't fit in its frame. Otherwise we are doing coarser clipping + passing a scissor rectangle to the renderer. The system is designed to try minimizing both execution and CPU/GPU rendering cost."); + ImGui::DragFloat2("size", (float*)&size, 0.5f, 0.0f, 200.0f, "%.0f"); + ImGui::TextWrapped("(Click and drag)"); + ImVec2 pos = ImGui::GetCursorScreenPos(); + ImVec4 clip_rect(pos.x, pos.y, pos.x + size.x, pos.y + size.y); + ImGui::InvisibleButton("##dummy", size); + if (ImGui::IsItemActive() && ImGui::IsMouseDragging()) + { + offset.x += ImGui::GetIO().MouseDelta.x; + offset.y += ImGui::GetIO().MouseDelta.y; + } + ImGui::GetWindowDrawList()->AddRectFilled(pos, ImVec2(pos.x + size.x, pos.y + size.y), IM_COL32(90, 90, 120, 255)); + ImGui::GetWindowDrawList()->AddText(ImGui::GetFont(), ImGui::GetFontSize() * 2.0f, ImVec2(pos.x + offset.x, pos.y + offset.y), IM_COL32(255, 255, 255, 255), "Line 1 hello\nLine 2 clip me!", NULL, 0.0f, &clip_rect); + ImGui::TreePop(); + } + } + + if (ImGui::CollapsingHeader("Popups & Modal windows")) + { + if (ImGui::TreeNode("Popups")) + { + ImGui::TextWrapped("When a popup is active, it inhibits interacting with windows that are behind the popup. Clicking outside the popup closes it."); + + static int selected_fish = -1; + const char* names[] = {"Bream", "Haddock", "Mackerel", "Pollock", "Tilefish"}; + static bool toggles[] = {true, false, false, false, false}; + + // Simple selection popup + // (If you want to show the current selection inside the Button itself, you may want to build a string using the "###" operator to preserve a constant ID with a variable label) + if (ImGui::Button("Select..")) + ImGui::OpenPopup("select"); + ImGui::SameLine(); + ImGui::TextUnformatted(selected_fish == -1 ? "" : names[selected_fish]); + if (ImGui::BeginPopup("select")) + { + ImGui::Text("Aquarium"); + ImGui::Separator(); + for (int i = 0; i < IM_ARRAYSIZE(names); i++) + if (ImGui::Selectable(names[i])) + selected_fish = i; + ImGui::EndPopup(); + } + + // Showing a menu with toggles + if (ImGui::Button("Toggle..")) + ImGui::OpenPopup("toggle"); + if (ImGui::BeginPopup("toggle")) + { + for (int i = 0; i < IM_ARRAYSIZE(names); i++) + ImGui::MenuItem(names[i], "", &toggles[i]); + if (ImGui::BeginMenu("Sub-menu")) + { + ImGui::MenuItem("Click me"); + ImGui::EndMenu(); + } + + ImGui::Separator(); + ImGui::Text("Tooltip here"); + if (ImGui::IsItemHovered()) + ImGui::SetTooltip("I am a tooltip over a popup"); + + if (ImGui::Button("Stacked Popup")) + ImGui::OpenPopup("another popup"); + if (ImGui::BeginPopup("another popup")) + { + for (int i = 0; i < IM_ARRAYSIZE(names); i++) + ImGui::MenuItem(names[i], "", &toggles[i]); + if (ImGui::BeginMenu("Sub-menu")) + { + ImGui::MenuItem("Click me"); + ImGui::EndMenu(); + } + ImGui::EndPopup(); + } + ImGui::EndPopup(); + } + + if (ImGui::Button("Popup Menu..")) + ImGui::OpenPopup("FilePopup"); + if (ImGui::BeginPopup("FilePopup")) + { + ShowExampleMenuFile(); + ImGui::EndPopup(); + } + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Context menus")) + { + // BeginPopupContextItem() is a helper to provide common/simple popup behavior of essentially doing: + // if (IsItemHovered() && IsMouseClicked(0)) + // OpenPopup(id); + // return BeginPopup(id); + // For more advanced uses you may want to replicate and cuztomize this code. This the comments inside BeginPopupContextItem() implementation. + static float value = 0.5f; + ImGui::Text("Value = %.3f (<-- right-click here)", value); + if (ImGui::BeginPopupContextItem("item context menu")) + { + if (ImGui::Selectable("Set to zero")) value = 0.0f; + if (ImGui::Selectable("Set to PI")) value = 3.1415f; + ImGui::PushItemWidth(-1); + ImGui::DragFloat("##Value", &value, 0.1f, 0.0f, 0.0f); + ImGui::PopItemWidth(); + ImGui::EndPopup(); + } + + static char name[32] = "Label1"; + char buf[64]; + sprintf(buf, "Button: %s###Button", name); // ### operator override ID ignoring the preceding label + ImGui::Button(buf); + if (ImGui::BeginPopupContextItem()) // When used after an item that has an ID (here the Button), we can skip providing an ID to BeginPopupContextItem(). + { + ImGui::Text("Edit name:"); + ImGui::InputText("##edit", name, IM_ARRAYSIZE(name)); + if (ImGui::Button("Close")) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + ImGui::SameLine(); + ImGui::Text("(<-- right-click here)"); + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Modals")) + { + ImGui::TextWrapped("Modal windows are like popups but the user cannot close them by clicking outside the window."); + + if (ImGui::Button("Delete..")) + ImGui::OpenPopup("Delete?"); + if (ImGui::BeginPopupModal("Delete?", NULL, ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::Text("All those beautiful files will be deleted.\nThis operation cannot be undone!\n\n"); + ImGui::Separator(); + + //static int dummy_i = 0; + //ImGui::Combo("Combo", &dummy_i, "Delete\0Delete harder\0"); + + static bool dont_ask_me_next_time = false; + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); + ImGui::Checkbox("Don't ask me next time", &dont_ask_me_next_time); + ImGui::PopStyleVar(); + + if (ImGui::Button("OK", ImVec2(120, 0))) + { + ImGui::CloseCurrentPopup(); + } + ImGui::SetItemDefaultFocus(); + ImGui::SameLine(); + if (ImGui::Button("Cancel", ImVec2(120, 0))) + { + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + + if (ImGui::Button("Stacked modals..")) + ImGui::OpenPopup("Stacked 1"); + if (ImGui::BeginPopupModal("Stacked 1")) + { + ImGui::Text("Hello from Stacked The First\nUsing style.Colors[ImGuiCol_ModalWindowDarkening] for darkening."); + static int item = 1; + ImGui::Combo("Combo", &item, "aaaa\0bbbb\0cccc\0dddd\0eeee\0\0"); + static float color[4] = {0.4f, 0.7f, 0.0f, 0.5f}; + ImGui::ColorEdit4("color", color); // This is to test behavior of stacked regular popups over a modal + + if (ImGui::Button("Add another modal..")) + ImGui::OpenPopup("Stacked 2"); + if (ImGui::BeginPopupModal("Stacked 2")) + { + ImGui::Text("Hello from Stacked The Second!"); + if (ImGui::Button("Close")) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + + if (ImGui::Button("Close")) + ImGui::CloseCurrentPopup(); + ImGui::EndPopup(); + } + + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Menus inside a regular window")) + { + ImGui::TextWrapped("Below we are testing adding menu items to a regular window. It's rather unusual but should work!"); + ImGui::Separator(); + // NB: As a quirk in this very specific example, we want to differentiate the parent of this menu from the parent of the various popup menus above. + // To do so we are encloding the items in a PushID()/PopID() block to make them two different menusets. If we don't, opening any popup above and hovering our menu here + // would open it. This is because once a menu is active, we allow to switch to a sibling menu by just hovering on it, which is the desired behavior for regular menus. + ImGui::PushID("foo"); + ImGui::MenuItem("Menu item", "CTRL+M"); + if (ImGui::BeginMenu("Menu inside a regular window")) + { + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + ImGui::PopID(); + ImGui::Separator(); + ImGui::TreePop(); + } + } + + if (ImGui::CollapsingHeader("Columns")) + { + ImGui::PushID("Columns"); + + // Basic columns + if (ImGui::TreeNode("Basic")) + { + ImGui::Text("Without border:"); + ImGui::Columns(3, "mycolumns3", false); // 3-ways, no border + ImGui::Separator(); + for (int n = 0; n < 14; n++) + { + char label[32]; + sprintf(label, "Item %d", n); + if (ImGui::Selectable(label)) + { + } + //if (ImGui::Button(label, ImVec2(-1,0))) {} + ImGui::NextColumn(); + } + ImGui::Columns(1); + ImGui::Separator(); + + ImGui::Text("With border:"); + ImGui::Columns(4, "mycolumns"); // 4-ways, with border + ImGui::Separator(); + ImGui::Text("ID"); + ImGui::NextColumn(); + ImGui::Text("Name"); + ImGui::NextColumn(); + ImGui::Text("Path"); + ImGui::NextColumn(); + ImGui::Text("Hovered"); + ImGui::NextColumn(); + ImGui::Separator(); + const char* names[3] = {"One", "Two", "Three"}; + const char* paths[3] = {"/path/one", "/path/two", "/path/three"}; + static int selected = -1; + for (int i = 0; i < 3; i++) + { + char label[32]; + sprintf(label, "%04d", i); + if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SpanAllColumns)) + selected = i; + bool hovered = ImGui::IsItemHovered(); + ImGui::NextColumn(); + ImGui::Text(names[i]); + ImGui::NextColumn(); + ImGui::Text(paths[i]); + ImGui::NextColumn(); + ImGui::Text("%d", hovered); + ImGui::NextColumn(); + } + ImGui::Columns(1); + ImGui::Separator(); + ImGui::TreePop(); + } + + // Create multiple items in a same cell before switching to next column + if (ImGui::TreeNode("Mixed items")) + { + ImGui::Columns(3, "mixed"); + ImGui::Separator(); + + ImGui::Text("Hello"); + ImGui::Button("Banana"); + ImGui::NextColumn(); + + ImGui::Text("ImGui"); + ImGui::Button("Apple"); + static float foo = 1.0f; + ImGui::InputFloat("red", &foo, 0.05f, 0, 3); + ImGui::Text("An extra line here."); + ImGui::NextColumn(); + + ImGui::Text("Sailor"); + ImGui::Button("Corniflower"); + static float bar = 1.0f; + ImGui::InputFloat("blue", &bar, 0.05f, 0, 3); + ImGui::NextColumn(); + + if (ImGui::CollapsingHeader("Category A")) + { + ImGui::Text("Blah blah blah"); + } + ImGui::NextColumn(); + if (ImGui::CollapsingHeader("Category B")) + { + ImGui::Text("Blah blah blah"); + } + ImGui::NextColumn(); + if (ImGui::CollapsingHeader("Category C")) + { + ImGui::Text("Blah blah blah"); + } + ImGui::NextColumn(); + ImGui::Columns(1); + ImGui::Separator(); + ImGui::TreePop(); + } + + // Word wrapping + if (ImGui::TreeNode("Word-wrapping")) + { + ImGui::Columns(2, "word-wrapping"); + ImGui::Separator(); + ImGui::TextWrapped("The quick brown fox jumps over the lazy dog."); + ImGui::TextWrapped("Hello Left"); + ImGui::NextColumn(); + ImGui::TextWrapped("The quick brown fox jumps over the lazy dog."); + ImGui::TextWrapped("Hello Right"); + ImGui::Columns(1); + ImGui::Separator(); + ImGui::TreePop(); + } + + if (ImGui::TreeNode("Borders")) + { + // NB: Future columns API should allow automatic horizontal borders. + static bool h_borders = true; + static bool v_borders = true; + ImGui::Checkbox("horizontal", &h_borders); + ImGui::SameLine(); + ImGui::Checkbox("vertical", &v_borders); + ImGui::Columns(4, NULL, v_borders); + for (int i = 0; i < 4 * 3; i++) + { + if (h_borders && ImGui::GetColumnIndex() == 0) + ImGui::Separator(); + ImGui::Text("%c%c%c", 'a' + i, 'a' + i, 'a' + i); + ImGui::Text("Width %.2f\nOffset %.2f", ImGui::GetColumnWidth(), ImGui::GetColumnOffset()); + ImGui::NextColumn(); + } + ImGui::Columns(1); + if (h_borders) + ImGui::Separator(); + ImGui::TreePop(); + } + + // Scrolling columns + /* if (ImGui::TreeNode("Vertical Scrolling")) { ImGui::BeginChild("##header", ImVec2(0, ImGui::GetTextLineHeightWithSpacing()+ImGui::GetStyle().ItemSpacing.y)); @@ -1743,1148 +1914,1362 @@ void ImGui::ShowDemoWindow(bool* p_open) } */ - if (ImGui::TreeNode("Horizontal Scrolling")) - { - ImGui::SetNextWindowContentSize(ImVec2(1500.0f, 0.0f)); - ImGui::BeginChild("##ScrollingRegion", ImVec2(0, ImGui::GetFontSize() * 20), false, ImGuiWindowFlags_HorizontalScrollbar); - ImGui::Columns(10); - int ITEMS_COUNT = 2000; - ImGuiListClipper clipper(ITEMS_COUNT); // Also demonstrate using the clipper for large list - while (clipper.Step()) - { - for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) - for (int j = 0; j < 10; j++) - { - ImGui::Text("Line %d Column %d...", i, j); - ImGui::NextColumn(); - } - } - ImGui::Columns(1); - ImGui::EndChild(); - ImGui::TreePop(); - } + if (ImGui::TreeNode("Horizontal Scrolling")) + { + ImGui::SetNextWindowContentSize(ImVec2(1500.0f, 0.0f)); + ImGui::BeginChild("##ScrollingRegion", ImVec2(0, ImGui::GetFontSize() * 20), false, ImGuiWindowFlags_HorizontalScrollbar); + ImGui::Columns(10); + int ITEMS_COUNT = 2000; + ImGuiListClipper clipper(ITEMS_COUNT); // Also demonstrate using the clipper for large list + while (clipper.Step()) + { + for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) + for (int j = 0; j < 10; j++) + { + ImGui::Text("Line %d Column %d...", i, j); + ImGui::NextColumn(); + } + } + ImGui::Columns(1); + ImGui::EndChild(); + ImGui::TreePop(); + } - bool node_open = ImGui::TreeNode("Tree within single cell"); - ImGui::SameLine(); ShowHelpMarker("NB: Tree node must be poped before ending the cell. There's no storage of state per-cell."); - if (node_open) - { - ImGui::Columns(2, "tree items"); - ImGui::Separator(); - if (ImGui::TreeNode("Hello")) { ImGui::BulletText("Sailor"); ImGui::TreePop(); } ImGui::NextColumn(); - if (ImGui::TreeNode("Bonjour")) { ImGui::BulletText("Marin"); ImGui::TreePop(); } ImGui::NextColumn(); - ImGui::Columns(1); - ImGui::Separator(); - ImGui::TreePop(); - } - ImGui::PopID(); - } + bool node_open = ImGui::TreeNode("Tree within single cell"); + ImGui::SameLine(); + ShowHelpMarker("NB: Tree node must be poped before ending the cell. There's no storage of state per-cell."); + if (node_open) + { + ImGui::Columns(2, "tree items"); + ImGui::Separator(); + if (ImGui::TreeNode("Hello")) + { + ImGui::BulletText("Sailor"); + ImGui::TreePop(); + } + ImGui::NextColumn(); + if (ImGui::TreeNode("Bonjour")) + { + ImGui::BulletText("Marin"); + ImGui::TreePop(); + } + ImGui::NextColumn(); + ImGui::Columns(1); + ImGui::Separator(); + ImGui::TreePop(); + } + ImGui::PopID(); + } - if (ImGui::CollapsingHeader("Filtering")) - { - static ImGuiTextFilter filter; - ImGui::Text("Filter usage:\n" - " \"\" display all lines\n" - " \"xxx\" display lines containing \"xxx\"\n" - " \"xxx,yyy\" display lines containing \"xxx\" or \"yyy\"\n" - " \"-xxx\" hide lines containing \"xxx\""); - filter.Draw(); - const char* lines[] = { "aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world" }; - for (int i = 0; i < IM_ARRAYSIZE(lines); i++) - if (filter.PassFilter(lines[i])) - ImGui::BulletText("%s", lines[i]); - } + if (ImGui::CollapsingHeader("Filtering")) + { + static ImGuiTextFilter filter; + ImGui::Text( + "Filter usage:\n" + " \"\" display all lines\n" + " \"xxx\" display lines containing \"xxx\"\n" + " \"xxx,yyy\" display lines containing \"xxx\" or \"yyy\"\n" + " \"-xxx\" hide lines containing \"xxx\""); + filter.Draw(); + const char* lines[] = {"aaa1.c", "bbb1.c", "ccc1.c", "aaa2.cpp", "bbb2.cpp", "ccc2.cpp", "abc.h", "hello, world"}; + for (int i = 0; i < IM_ARRAYSIZE(lines); i++) + if (filter.PassFilter(lines[i])) + ImGui::BulletText("%s", lines[i]); + } - if (ImGui::CollapsingHeader("Inputs, Navigation & Focus")) - { - ImGuiIO& io = ImGui::GetIO(); + if (ImGui::CollapsingHeader("Inputs, Navigation & Focus")) + { + ImGuiIO& io = ImGui::GetIO(); - ImGui::Text("WantCaptureMouse: %d", io.WantCaptureMouse); - ImGui::Text("WantCaptureKeyboard: %d", io.WantCaptureKeyboard); - ImGui::Text("WantTextInput: %d", io.WantTextInput); - ImGui::Text("WantMoveMouse: %d", io.WantMoveMouse); - ImGui::Text("NavActive: %d, NavVisible: %d", io.NavActive, io.NavVisible); + ImGui::Text("WantCaptureMouse: %d", io.WantCaptureMouse); + ImGui::Text("WantCaptureKeyboard: %d", io.WantCaptureKeyboard); + ImGui::Text("WantTextInput: %d", io.WantTextInput); + ImGui::Text("WantMoveMouse: %d", io.WantMoveMouse); + ImGui::Text("NavActive: %d, NavVisible: %d", io.NavActive, io.NavVisible); - ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor); - ImGui::SameLine(); ShowHelpMarker("Request ImGui to render a mouse cursor for you in software. Note that a mouse cursor rendered via your application GPU rendering path will feel more laggy than hardware cursor, but will be more in sync with your other visuals.\n\nSome desktop applications may use both kinds of cursors (e.g. enable software cursor only when resizing/dragging something)."); - ImGui::CheckboxFlags("io.NavFlags: EnableGamepad", (unsigned int *)&io.NavFlags, ImGuiNavFlags_EnableGamepad); - ImGui::CheckboxFlags("io.NavFlags: EnableKeyboard", (unsigned int *)&io.NavFlags, ImGuiNavFlags_EnableKeyboard); - ImGui::CheckboxFlags("io.NavFlags: MoveMouse", (unsigned int *)&io.NavFlags, ImGuiNavFlags_MoveMouse); - ImGui::SameLine(); ShowHelpMarker("Request ImGui to move your move cursor when using gamepad/keyboard navigation. NewFrame() will change io.MousePos and set the io.WantMoveMouse flag, your backend will need to apply the new mouse position."); + ImGui::Checkbox("io.MouseDrawCursor", &io.MouseDrawCursor); + ImGui::SameLine(); + ShowHelpMarker("Request ImGui to render a mouse cursor for you in software. Note that a mouse cursor rendered via your application GPU rendering path will feel more laggy than hardware cursor, but will be more in sync with your other visuals.\n\nSome desktop applications may use both kinds of cursors (e.g. enable software cursor only when resizing/dragging something)."); + ImGui::CheckboxFlags("io.NavFlags: EnableGamepad", (unsigned int*)&io.NavFlags, ImGuiNavFlags_EnableGamepad); + ImGui::CheckboxFlags("io.NavFlags: EnableKeyboard", (unsigned int*)&io.NavFlags, ImGuiNavFlags_EnableKeyboard); + ImGui::CheckboxFlags("io.NavFlags: MoveMouse", (unsigned int*)&io.NavFlags, ImGuiNavFlags_MoveMouse); + ImGui::SameLine(); + ShowHelpMarker("Request ImGui to move your move cursor when using gamepad/keyboard navigation. NewFrame() will change io.MousePos and set the io.WantMoveMouse flag, your backend will need to apply the new mouse position."); - if (ImGui::TreeNode("Keyboard, Mouse & Navigation State")) - { - if (ImGui::IsMousePosValid()) - ImGui::Text("Mouse pos: (%g, %g)", io.MousePos.x, io.MousePos.y); - else - ImGui::Text("Mouse pos: "); - ImGui::Text("Mouse down:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (io.MouseDownDuration[i] >= 0.0f) { ImGui::SameLine(); ImGui::Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); } - ImGui::Text("Mouse clicked:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } - ImGui::Text("Mouse dbl-clicked:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseDoubleClicked(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } - ImGui::Text("Mouse released:"); for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) if (ImGui::IsMouseReleased(i)) { ImGui::SameLine(); ImGui::Text("b%d", i); } - ImGui::Text("Mouse wheel: %.1f", io.MouseWheel); + if (ImGui::TreeNode("Keyboard, Mouse & Navigation State")) + { + if (ImGui::IsMousePosValid()) + ImGui::Text("Mouse pos: (%g, %g)", io.MousePos.x, io.MousePos.y); + else + ImGui::Text("Mouse pos: "); + ImGui::Text("Mouse down:"); + for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) + if (io.MouseDownDuration[i] >= 0.0f) + { + ImGui::SameLine(); + ImGui::Text("b%d (%.02f secs)", i, io.MouseDownDuration[i]); + } + ImGui::Text("Mouse clicked:"); + for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) + if (ImGui::IsMouseClicked(i)) + { + ImGui::SameLine(); + ImGui::Text("b%d", i); + } + ImGui::Text("Mouse dbl-clicked:"); + for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) + if (ImGui::IsMouseDoubleClicked(i)) + { + ImGui::SameLine(); + ImGui::Text("b%d", i); + } + ImGui::Text("Mouse released:"); + for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) + if (ImGui::IsMouseReleased(i)) + { + ImGui::SameLine(); + ImGui::Text("b%d", i); + } + ImGui::Text("Mouse wheel: %.1f", io.MouseWheel); - ImGui::Text("Keys down:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (io.KeysDownDuration[i] >= 0.0f) { ImGui::SameLine(); ImGui::Text("%d (%.02f secs)", i, io.KeysDownDuration[i]); } - ImGui::Text("Keys pressed:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyPressed(i)) { ImGui::SameLine(); ImGui::Text("%d", i); } - ImGui::Text("Keys release:"); for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) if (ImGui::IsKeyReleased(i)) { ImGui::SameLine(); ImGui::Text("%d", i); } - ImGui::Text("Keys mods: %s%s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "", io.KeySuper ? "SUPER " : ""); + ImGui::Text("Keys down:"); + for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) + if (io.KeysDownDuration[i] >= 0.0f) + { + ImGui::SameLine(); + ImGui::Text("%d (%.02f secs)", i, io.KeysDownDuration[i]); + } + ImGui::Text("Keys pressed:"); + for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) + if (ImGui::IsKeyPressed(i)) + { + ImGui::SameLine(); + ImGui::Text("%d", i); + } + ImGui::Text("Keys release:"); + for (int i = 0; i < IM_ARRAYSIZE(io.KeysDown); i++) + if (ImGui::IsKeyReleased(i)) + { + ImGui::SameLine(); + ImGui::Text("%d", i); + } + ImGui::Text("Keys mods: %s%s%s%s", io.KeyCtrl ? "CTRL " : "", io.KeyShift ? "SHIFT " : "", io.KeyAlt ? "ALT " : "", io.KeySuper ? "SUPER " : ""); - ImGui::Text("NavInputs down:"); for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++) if (io.NavInputs[i] > 0.0f) { ImGui::SameLine(); ImGui::Text("[%d] %.2f", i, io.NavInputs[i]); } - ImGui::Text("NavInputs pressed:"); for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++) if (io.NavInputsDownDuration[i] == 0.0f) { ImGui::SameLine(); ImGui::Text("[%d]", i); } - ImGui::Text("NavInputs duration:"); for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++) if (io.NavInputsDownDuration[i] >= 0.0f) { ImGui::SameLine(); ImGui::Text("[%d] %.2f", i, io.NavInputsDownDuration[i]); } + ImGui::Text("NavInputs down:"); + for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++) + if (io.NavInputs[i] > 0.0f) + { + ImGui::SameLine(); + ImGui::Text("[%d] %.2f", i, io.NavInputs[i]); + } + ImGui::Text("NavInputs pressed:"); + for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++) + if (io.NavInputsDownDuration[i] == 0.0f) + { + ImGui::SameLine(); + ImGui::Text("[%d]", i); + } + ImGui::Text("NavInputs duration:"); + for (int i = 0; i < IM_ARRAYSIZE(io.NavInputs); i++) + if (io.NavInputsDownDuration[i] >= 0.0f) + { + ImGui::SameLine(); + ImGui::Text("[%d] %.2f", i, io.NavInputsDownDuration[i]); + } - ImGui::Button("Hovering me sets the\nkeyboard capture flag"); - if (ImGui::IsItemHovered()) - ImGui::CaptureKeyboardFromApp(true); - ImGui::SameLine(); - ImGui::Button("Holding me clears the\nthe keyboard capture flag"); - if (ImGui::IsItemActive()) - ImGui::CaptureKeyboardFromApp(false); + ImGui::Button("Hovering me sets the\nkeyboard capture flag"); + if (ImGui::IsItemHovered()) + ImGui::CaptureKeyboardFromApp(true); + ImGui::SameLine(); + ImGui::Button("Holding me clears the\nthe keyboard capture flag"); + if (ImGui::IsItemActive()) + ImGui::CaptureKeyboardFromApp(false); - ImGui::TreePop(); - } + ImGui::TreePop(); + } - if (ImGui::TreeNode("Tabbing")) - { - ImGui::Text("Use TAB/SHIFT+TAB to cycle through keyboard editable fields."); - static char buf[32] = "dummy"; - ImGui::InputText("1", buf, IM_ARRAYSIZE(buf)); - ImGui::InputText("2", buf, IM_ARRAYSIZE(buf)); - ImGui::InputText("3", buf, IM_ARRAYSIZE(buf)); - ImGui::PushAllowKeyboardFocus(false); - ImGui::InputText("4 (tab skip)", buf, IM_ARRAYSIZE(buf)); - //ImGui::SameLine(); ShowHelperMarker("Use ImGui::PushAllowKeyboardFocus(bool)\nto disable tabbing through certain widgets."); - ImGui::PopAllowKeyboardFocus(); - ImGui::InputText("5", buf, IM_ARRAYSIZE(buf)); - ImGui::TreePop(); - } + if (ImGui::TreeNode("Tabbing")) + { + ImGui::Text("Use TAB/SHIFT+TAB to cycle through keyboard editable fields."); + static char buf[32] = "dummy"; + ImGui::InputText("1", buf, IM_ARRAYSIZE(buf)); + ImGui::InputText("2", buf, IM_ARRAYSIZE(buf)); + ImGui::InputText("3", buf, IM_ARRAYSIZE(buf)); + ImGui::PushAllowKeyboardFocus(false); + ImGui::InputText("4 (tab skip)", buf, IM_ARRAYSIZE(buf)); + //ImGui::SameLine(); ShowHelperMarker("Use ImGui::PushAllowKeyboardFocus(bool)\nto disable tabbing through certain widgets."); + ImGui::PopAllowKeyboardFocus(); + ImGui::InputText("5", buf, IM_ARRAYSIZE(buf)); + ImGui::TreePop(); + } - if (ImGui::TreeNode("Focus from code")) - { - bool focus_1 = ImGui::Button("Focus on 1"); ImGui::SameLine(); - bool focus_2 = ImGui::Button("Focus on 2"); ImGui::SameLine(); - bool focus_3 = ImGui::Button("Focus on 3"); - int has_focus = 0; - static char buf[128] = "click on a button to set focus"; + if (ImGui::TreeNode("Focus from code")) + { + bool focus_1 = ImGui::Button("Focus on 1"); + ImGui::SameLine(); + bool focus_2 = ImGui::Button("Focus on 2"); + ImGui::SameLine(); + bool focus_3 = ImGui::Button("Focus on 3"); + int has_focus = 0; + static char buf[128] = "click on a button to set focus"; - if (focus_1) ImGui::SetKeyboardFocusHere(); - ImGui::InputText("1", buf, IM_ARRAYSIZE(buf)); - if (ImGui::IsItemActive()) has_focus = 1; + if (focus_1) ImGui::SetKeyboardFocusHere(); + ImGui::InputText("1", buf, IM_ARRAYSIZE(buf)); + if (ImGui::IsItemActive()) has_focus = 1; - if (focus_2) ImGui::SetKeyboardFocusHere(); - ImGui::InputText("2", buf, IM_ARRAYSIZE(buf)); - if (ImGui::IsItemActive()) has_focus = 2; + if (focus_2) ImGui::SetKeyboardFocusHere(); + ImGui::InputText("2", buf, IM_ARRAYSIZE(buf)); + if (ImGui::IsItemActive()) has_focus = 2; - ImGui::PushAllowKeyboardFocus(false); - if (focus_3) ImGui::SetKeyboardFocusHere(); - ImGui::InputText("3 (tab skip)", buf, IM_ARRAYSIZE(buf)); - if (ImGui::IsItemActive()) has_focus = 3; - ImGui::PopAllowKeyboardFocus(); + ImGui::PushAllowKeyboardFocus(false); + if (focus_3) ImGui::SetKeyboardFocusHere(); + ImGui::InputText("3 (tab skip)", buf, IM_ARRAYSIZE(buf)); + if (ImGui::IsItemActive()) has_focus = 3; + ImGui::PopAllowKeyboardFocus(); - if (has_focus) - ImGui::Text("Item with focus: %d", has_focus); - else - ImGui::Text("Item with focus: "); + if (has_focus) + ImGui::Text("Item with focus: %d", has_focus); + else + ImGui::Text("Item with focus: "); - // Use >= 0 parameter to SetKeyboardFocusHere() to focus an upcoming item - static float f3[3] = { 0.0f, 0.0f, 0.0f }; - int focus_ahead = -1; - if (ImGui::Button("Focus on X")) focus_ahead = 0; ImGui::SameLine(); - if (ImGui::Button("Focus on Y")) focus_ahead = 1; ImGui::SameLine(); - if (ImGui::Button("Focus on Z")) focus_ahead = 2; - if (focus_ahead != -1) ImGui::SetKeyboardFocusHere(focus_ahead); - ImGui::SliderFloat3("Float3", &f3[0], 0.0f, 1.0f); + // Use >= 0 parameter to SetKeyboardFocusHere() to focus an upcoming item + static float f3[3] = {0.0f, 0.0f, 0.0f}; + int focus_ahead = -1; + if (ImGui::Button("Focus on X")) focus_ahead = 0; + ImGui::SameLine(); + if (ImGui::Button("Focus on Y")) focus_ahead = 1; + ImGui::SameLine(); + if (ImGui::Button("Focus on Z")) focus_ahead = 2; + if (focus_ahead != -1) ImGui::SetKeyboardFocusHere(focus_ahead); + ImGui::SliderFloat3("Float3", &f3[0], 0.0f, 1.0f); - ImGui::TextWrapped("NB: Cursor & selection are preserved when refocusing last used item in code."); - ImGui::TreePop(); - } + ImGui::TextWrapped("NB: Cursor & selection are preserved when refocusing last used item in code."); + ImGui::TreePop(); + } - if (ImGui::TreeNode("Focused & Hovered Test")) - { - static bool embed_all_inside_a_child_window = false; - ImGui::Checkbox("Embed everything inside a child window (for additional testing)", &embed_all_inside_a_child_window); - if (embed_all_inside_a_child_window) - ImGui::BeginChild("embeddingchild", ImVec2(0, ImGui::GetFontSize() * 25), true); + if (ImGui::TreeNode("Focused & Hovered Test")) + { + static bool embed_all_inside_a_child_window = false; + ImGui::Checkbox("Embed everything inside a child window (for additional testing)", &embed_all_inside_a_child_window); + if (embed_all_inside_a_child_window) + ImGui::BeginChild("embeddingchild", ImVec2(0, ImGui::GetFontSize() * 25), true); - // Testing IsWindowFocused() function with its various flags (note that the flags can be combined) - ImGui::BulletText( - "IsWindowFocused() = %d\n" - "IsWindowFocused(_ChildWindows) = %d\n" - "IsWindowFocused(_ChildWindows|_RootWindow) = %d\n" - "IsWindowFocused(_RootWindow) = %d\n" - "IsWindowFocused(_AnyWindow) = %d\n", - ImGui::IsWindowFocused(), - ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows), - ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_RootWindow), - ImGui::IsWindowFocused(ImGuiFocusedFlags_RootWindow), - ImGui::IsWindowFocused(ImGuiFocusedFlags_AnyWindow)); + // Testing IsWindowFocused() function with its various flags (note that the flags can be combined) + ImGui::BulletText( + "IsWindowFocused() = %d\n" + "IsWindowFocused(_ChildWindows) = %d\n" + "IsWindowFocused(_ChildWindows|_RootWindow) = %d\n" + "IsWindowFocused(_RootWindow) = %d\n" + "IsWindowFocused(_AnyWindow) = %d\n", + ImGui::IsWindowFocused(), + ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows), + ImGui::IsWindowFocused(ImGuiFocusedFlags_ChildWindows | ImGuiFocusedFlags_RootWindow), + ImGui::IsWindowFocused(ImGuiFocusedFlags_RootWindow), + ImGui::IsWindowFocused(ImGuiFocusedFlags_AnyWindow)); - // Testing IsWindowHovered() function with its various flags (note that the flags can be combined) - ImGui::BulletText( - "IsWindowHovered() = %d\n" - "IsWindowHovered(_AllowWhenBlockedByPopup) = %d\n" - "IsWindowHovered(_AllowWhenBlockedByActiveItem) = %d\n" - "IsWindowHovered(_ChildWindows) = %d\n" - "IsWindowHovered(_ChildWindows|_RootWindow) = %d\n" - "IsWindowHovered(_RootWindow) = %d\n" - "IsWindowHovered(_AnyWindow) = %d\n", - ImGui::IsWindowHovered(), - ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup), - ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem), - ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows), - ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow), - ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow), - ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow)); + // Testing IsWindowHovered() function with its various flags (note that the flags can be combined) + ImGui::BulletText( + "IsWindowHovered() = %d\n" + "IsWindowHovered(_AllowWhenBlockedByPopup) = %d\n" + "IsWindowHovered(_AllowWhenBlockedByActiveItem) = %d\n" + "IsWindowHovered(_ChildWindows) = %d\n" + "IsWindowHovered(_ChildWindows|_RootWindow) = %d\n" + "IsWindowHovered(_RootWindow) = %d\n" + "IsWindowHovered(_AnyWindow) = %d\n", + ImGui::IsWindowHovered(), + ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup), + ImGui::IsWindowHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem), + ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows), + ImGui::IsWindowHovered(ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_RootWindow), + ImGui::IsWindowHovered(ImGuiHoveredFlags_RootWindow), + ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow)); - // Testing IsItemHovered() function (because BulletText is an item itself and that would affect the output of IsItemHovered, we pass all lines in a single items to shorten the code) - ImGui::Button("ITEM"); - ImGui::BulletText( - "IsItemHovered() = %d\n" - "IsItemHovered(_AllowWhenBlockedByPopup) = %d\n" - "IsItemHovered(_AllowWhenBlockedByActiveItem) = %d\n" - "IsItemHovered(_AllowWhenOverlapped) = %d\n" - "IsItemhovered(_RectOnly) = %d\n", - ImGui::IsItemHovered(), - ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup), - ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem), - ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlapped), - ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly)); + // Testing IsItemHovered() function (because BulletText is an item itself and that would affect the output of IsItemHovered, we pass all lines in a single items to shorten the code) + ImGui::Button("ITEM"); + ImGui::BulletText( + "IsItemHovered() = %d\n" + "IsItemHovered(_AllowWhenBlockedByPopup) = %d\n" + "IsItemHovered(_AllowWhenBlockedByActiveItem) = %d\n" + "IsItemHovered(_AllowWhenOverlapped) = %d\n" + "IsItemhovered(_RectOnly) = %d\n", + ImGui::IsItemHovered(), + ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByPopup), + ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenBlockedByActiveItem), + ImGui::IsItemHovered(ImGuiHoveredFlags_AllowWhenOverlapped), + ImGui::IsItemHovered(ImGuiHoveredFlags_RectOnly)); - ImGui::BeginChild("child", ImVec2(0,50), true); - ImGui::Text("This is another child window for testing IsWindowHovered() flags."); - ImGui::EndChild(); + ImGui::BeginChild("child", ImVec2(0, 50), true); + ImGui::Text("This is another child window for testing IsWindowHovered() flags."); + ImGui::EndChild(); - if (embed_all_inside_a_child_window) - EndChild(); + if (embed_all_inside_a_child_window) + EndChild(); - ImGui::TreePop(); - } + ImGui::TreePop(); + } - if (ImGui::TreeNode("Dragging")) - { - ImGui::TextWrapped("You can use ImGui::GetMouseDragDelta(0) to query for the dragged amount on any widget."); - for (int button = 0; button < 3; button++) - ImGui::Text("IsMouseDragging(%d):\n w/ default threshold: %d,\n w/ zero threshold: %d\n w/ large threshold: %d", - button, ImGui::IsMouseDragging(button), ImGui::IsMouseDragging(button, 0.0f), ImGui::IsMouseDragging(button, 20.0f)); - ImGui::Button("Drag Me"); - if (ImGui::IsItemActive()) - { - // Draw a line between the button and the mouse cursor - ImDrawList* draw_list = ImGui::GetWindowDrawList(); - draw_list->PushClipRectFullScreen(); - draw_list->AddLine(io.MouseClickedPos[0], io.MousePos, ImGui::GetColorU32(ImGuiCol_Button), 4.0f); - draw_list->PopClipRect(); + if (ImGui::TreeNode("Dragging")) + { + ImGui::TextWrapped("You can use ImGui::GetMouseDragDelta(0) to query for the dragged amount on any widget."); + for (int button = 0; button < 3; button++) + ImGui::Text("IsMouseDragging(%d):\n w/ default threshold: %d,\n w/ zero threshold: %d\n w/ large threshold: %d", + button, ImGui::IsMouseDragging(button), ImGui::IsMouseDragging(button, 0.0f), ImGui::IsMouseDragging(button, 20.0f)); + ImGui::Button("Drag Me"); + if (ImGui::IsItemActive()) + { + // Draw a line between the button and the mouse cursor + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + draw_list->PushClipRectFullScreen(); + draw_list->AddLine(io.MouseClickedPos[0], io.MousePos, ImGui::GetColorU32(ImGuiCol_Button), 4.0f); + draw_list->PopClipRect(); - // Drag operations gets "unlocked" when the mouse has moved past a certain threshold (the default threshold is stored in io.MouseDragThreshold) - // You can request a lower or higher threshold using the second parameter of IsMouseDragging() and GetMouseDragDelta() - ImVec2 value_raw = ImGui::GetMouseDragDelta(0, 0.0f); - ImVec2 value_with_lock_threshold = ImGui::GetMouseDragDelta(0); - ImVec2 mouse_delta = io.MouseDelta; - ImGui::SameLine(); ImGui::Text("Raw (%.1f, %.1f), WithLockThresold (%.1f, %.1f), MouseDelta (%.1f, %.1f)", value_raw.x, value_raw.y, value_with_lock_threshold.x, value_with_lock_threshold.y, mouse_delta.x, mouse_delta.y); - } - ImGui::TreePop(); - } + // Drag operations gets "unlocked" when the mouse has moved past a certain threshold (the default threshold is stored in io.MouseDragThreshold) + // You can request a lower or higher threshold using the second parameter of IsMouseDragging() and GetMouseDragDelta() + ImVec2 value_raw = ImGui::GetMouseDragDelta(0, 0.0f); + ImVec2 value_with_lock_threshold = ImGui::GetMouseDragDelta(0); + ImVec2 mouse_delta = io.MouseDelta; + ImGui::SameLine(); + ImGui::Text("Raw (%.1f, %.1f), WithLockThresold (%.1f, %.1f), MouseDelta (%.1f, %.1f)", value_raw.x, value_raw.y, value_with_lock_threshold.x, value_with_lock_threshold.y, mouse_delta.x, mouse_delta.y); + } + ImGui::TreePop(); + } - if (ImGui::TreeNode("Mouse cursors")) - { - const char* mouse_cursors_names[] = { "Arrow", "TextInput", "Move", "ResizeNS", "ResizeEW", "ResizeNESW", "ResizeNWSE" }; - IM_ASSERT(IM_ARRAYSIZE(mouse_cursors_names) == ImGuiMouseCursor_Count_); + if (ImGui::TreeNode("Mouse cursors")) + { + const char* mouse_cursors_names[] = {"Arrow", "TextInput", "Move", "ResizeNS", "ResizeEW", "ResizeNESW", "ResizeNWSE"}; + IM_ASSERT(IM_ARRAYSIZE(mouse_cursors_names) == ImGuiMouseCursor_Count_); - ImGui::Text("Current mouse cursor = %d: %s", ImGui::GetMouseCursor(), mouse_cursors_names[ImGui::GetMouseCursor()]); - ImGui::Text("Hover to see mouse cursors:"); - ImGui::SameLine(); ShowHelpMarker("Your application can render a different mouse cursor based on what ImGui::GetMouseCursor() returns. If software cursor rendering (io.MouseDrawCursor) is set ImGui will draw the right cursor for you, otherwise your backend needs to handle it."); - for (int i = 0; i < ImGuiMouseCursor_Count_; i++) - { - char label[32]; - sprintf(label, "Mouse cursor %d: %s", i, mouse_cursors_names[i]); - ImGui::Bullet(); ImGui::Selectable(label, false); - if (ImGui::IsItemHovered() || ImGui::IsItemFocused()) - ImGui::SetMouseCursor(i); - } - ImGui::TreePop(); - } - } + ImGui::Text("Current mouse cursor = %d: %s", ImGui::GetMouseCursor(), mouse_cursors_names[ImGui::GetMouseCursor()]); + ImGui::Text("Hover to see mouse cursors:"); + ImGui::SameLine(); + ShowHelpMarker("Your application can render a different mouse cursor based on what ImGui::GetMouseCursor() returns. If software cursor rendering (io.MouseDrawCursor) is set ImGui will draw the right cursor for you, otherwise your backend needs to handle it."); + for (int i = 0; i < ImGuiMouseCursor_Count_; i++) + { + char label[32]; + sprintf(label, "Mouse cursor %d: %s", i, mouse_cursors_names[i]); + ImGui::Bullet(); + ImGui::Selectable(label, false); + if (ImGui::IsItemHovered() || ImGui::IsItemFocused()) + ImGui::SetMouseCursor(i); + } + ImGui::TreePop(); + } + } - ImGui::End(); + ImGui::End(); } // Demo helper function to select among default colors. See ShowStyleEditor() for more advanced options. // Here we use the simplified Combo() api that packs items into a single literal string. Useful for quick combo boxes where the choices are known locally. bool ImGui::ShowStyleSelector(const char* label) { - static int style_idx = -1; - if (ImGui::Combo(label, &style_idx, "Classic\0Dark\0Light\0")) - { - switch (style_idx) - { - case 0: ImGui::StyleColorsClassic(); break; - case 1: ImGui::StyleColorsDark(); break; - case 2: ImGui::StyleColorsLight(); break; - } - return true; - } - return false; + static int style_idx = -1; + if (ImGui::Combo(label, &style_idx, "Classic\0Dark\0Light\0")) + { + switch (style_idx) + { + case 0: + ImGui::StyleColorsClassic(); + break; + case 1: + ImGui::StyleColorsDark(); + break; + case 2: + ImGui::StyleColorsLight(); + break; + } + return true; + } + return false; } // Demo helper function to select among loaded fonts. // Here we use the regular BeginCombo()/EndCombo() api which is more the more flexible one. void ImGui::ShowFontSelector(const char* label) { - ImGuiIO& io = ImGui::GetIO(); - ImFont* font_current = ImGui::GetFont(); - if (ImGui::BeginCombo(label, font_current->GetDebugName())) - { - for (int n = 0; n < io.Fonts->Fonts.Size; n++) - if (ImGui::Selectable(io.Fonts->Fonts[n]->GetDebugName(), io.Fonts->Fonts[n] == font_current)) - io.FontDefault = io.Fonts->Fonts[n]; - ImGui::EndCombo(); - } - ImGui::SameLine(); - ShowHelpMarker( - "- Load additional fonts with io.Fonts->AddFontFromFileTTF().\n" - "- The font atlas is built when calling io.Fonts->GetTexDataAsXXXX() or io.Fonts->Build().\n" - "- Read FAQ and documentation in misc/fonts/ for more details.\n" - "- If you need to add/remove fonts at runtime (e.g. for DPI change), do it before calling NewFrame()."); + ImGuiIO& io = ImGui::GetIO(); + ImFont* font_current = ImGui::GetFont(); + if (ImGui::BeginCombo(label, font_current->GetDebugName())) + { + for (int n = 0; n < io.Fonts->Fonts.Size; n++) + if (ImGui::Selectable(io.Fonts->Fonts[n]->GetDebugName(), io.Fonts->Fonts[n] == font_current)) + io.FontDefault = io.Fonts->Fonts[n]; + ImGui::EndCombo(); + } + ImGui::SameLine(); + ShowHelpMarker( + "- Load additional fonts with io.Fonts->AddFontFromFileTTF().\n" + "- The font atlas is built when calling io.Fonts->GetTexDataAsXXXX() or io.Fonts->Build().\n" + "- Read FAQ and documentation in misc/fonts/ for more details.\n" + "- If you need to add/remove fonts at runtime (e.g. for DPI change), do it before calling NewFrame()."); } void ImGui::ShowStyleEditor(ImGuiStyle* ref) { - // You can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it compares to an internally stored reference) - ImGuiStyle& style = ImGui::GetStyle(); - static ImGuiStyle ref_saved_style; + // You can pass in a reference ImGuiStyle structure to compare to, revert to and save to (else it compares to an internally stored reference) + ImGuiStyle& style = ImGui::GetStyle(); + static ImGuiStyle ref_saved_style; - // Default to using internal storage as reference - static bool init = true; - if (init && ref == NULL) - ref_saved_style = style; - init = false; - if (ref == NULL) - ref = &ref_saved_style; + // Default to using internal storage as reference + static bool init = true; + if (init && ref == NULL) + ref_saved_style = style; + init = false; + if (ref == NULL) + ref = &ref_saved_style; - ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.50f); + ImGui::PushItemWidth(ImGui::GetWindowWidth() * 0.50f); - if (ImGui::ShowStyleSelector("Colors##Selector")) - ref_saved_style = style; - ImGui::ShowFontSelector("Fonts##Selector"); + if (ImGui::ShowStyleSelector("Colors##Selector")) + ref_saved_style = style; + ImGui::ShowFontSelector("Fonts##Selector"); - // Simplified Settings - if (ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f")) - style.GrabRounding = style.FrameRounding; // Make GrabRounding always the same value as FrameRounding - { bool window_border = (style.WindowBorderSize > 0.0f); if (ImGui::Checkbox("WindowBorder", &window_border)) style.WindowBorderSize = window_border ? 1.0f : 0.0f; } - ImGui::SameLine(); - { bool frame_border = (style.FrameBorderSize > 0.0f); if (ImGui::Checkbox("FrameBorder", &frame_border)) style.FrameBorderSize = frame_border ? 1.0f : 0.0f; } - ImGui::SameLine(); - { bool popup_border = (style.PopupBorderSize > 0.0f); if (ImGui::Checkbox("PopupBorder", &popup_border)) style.PopupBorderSize = popup_border ? 1.0f : 0.0f; } + // Simplified Settings + if (ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f")) + style.GrabRounding = style.FrameRounding; // Make GrabRounding always the same value as FrameRounding + { + bool window_border = (style.WindowBorderSize > 0.0f); + if (ImGui::Checkbox("WindowBorder", &window_border)) style.WindowBorderSize = window_border ? 1.0f : 0.0f; + } + ImGui::SameLine(); + { + bool frame_border = (style.FrameBorderSize > 0.0f); + if (ImGui::Checkbox("FrameBorder", &frame_border)) style.FrameBorderSize = frame_border ? 1.0f : 0.0f; + } + ImGui::SameLine(); + { + bool popup_border = (style.PopupBorderSize > 0.0f); + if (ImGui::Checkbox("PopupBorder", &popup_border)) style.PopupBorderSize = popup_border ? 1.0f : 0.0f; + } - // Save/Revert button - if (ImGui::Button("Save Ref")) - *ref = ref_saved_style = style; - ImGui::SameLine(); - if (ImGui::Button("Revert Ref")) - style = *ref; - ImGui::SameLine(); - ShowHelpMarker("Save/Revert in local non-persistent storage. Default Colors definition are not affected. Use \"Export Colors\" below to save them somewhere."); + // Save/Revert button + if (ImGui::Button("Save Ref")) + *ref = ref_saved_style = style; + ImGui::SameLine(); + if (ImGui::Button("Revert Ref")) + style = *ref; + ImGui::SameLine(); + ShowHelpMarker("Save/Revert in local non-persistent storage. Default Colors definition are not affected. Use \"Export Colors\" below to save them somewhere."); - if (ImGui::TreeNode("Rendering")) - { - ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines); ImGui::SameLine(); ShowHelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well."); - ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill); - ImGui::PushItemWidth(100); - ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, FLT_MAX, NULL, 2.0f); - if (style.CurveTessellationTol < 0.0f) style.CurveTessellationTol = 0.10f; - ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero. - ImGui::PopItemWidth(); - ImGui::TreePop(); - } + if (ImGui::TreeNode("Rendering")) + { + ImGui::Checkbox("Anti-aliased lines", &style.AntiAliasedLines); + ImGui::SameLine(); + ShowHelpMarker("When disabling anti-aliasing lines, you'll probably want to disable borders in your style as well."); + ImGui::Checkbox("Anti-aliased fill", &style.AntiAliasedFill); + ImGui::PushItemWidth(100); + ImGui::DragFloat("Curve Tessellation Tolerance", &style.CurveTessellationTol, 0.02f, 0.10f, FLT_MAX, NULL, 2.0f); + if (style.CurveTessellationTol < 0.0f) style.CurveTessellationTol = 0.10f; + ImGui::DragFloat("Global Alpha", &style.Alpha, 0.005f, 0.20f, 1.0f, "%.2f"); // Not exposing zero here so user doesn't "lose" the UI (zero alpha clips all widgets). But application code could have a toggle to switch between zero and non-zero. + ImGui::PopItemWidth(); + ImGui::TreePop(); + } - if (ImGui::TreeNode("Settings")) - { - ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f, 20.0f, "%.0f"); - ImGui::SliderFloat("PopupRounding", &style.PopupRounding, 0.0f, 16.0f, "%.0f"); - ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f, 20.0f, "%.0f"); - ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f, 20.0f, "%.0f"); - ImGui::SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing, 0.0f, 20.0f, "%.0f"); - ImGui::SliderFloat2("TouchExtraPadding", (float*)&style.TouchExtraPadding, 0.0f, 10.0f, "%.0f"); - ImGui::SliderFloat("IndentSpacing", &style.IndentSpacing, 0.0f, 30.0f, "%.0f"); - ImGui::SliderFloat("ScrollbarSize", &style.ScrollbarSize, 1.0f, 20.0f, "%.0f"); - ImGui::SliderFloat("GrabMinSize", &style.GrabMinSize, 1.0f, 20.0f, "%.0f"); - ImGui::Text("BorderSize"); - ImGui::SliderFloat("WindowBorderSize", &style.WindowBorderSize, 0.0f, 1.0f, "%.0f"); - ImGui::SliderFloat("ChildBorderSize", &style.ChildBorderSize, 0.0f, 1.0f, "%.0f"); - ImGui::SliderFloat("PopupBorderSize", &style.PopupBorderSize, 0.0f, 1.0f, "%.0f"); - ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f, "%.0f"); - ImGui::Text("Rounding"); - ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 14.0f, "%.0f"); - ImGui::SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 16.0f, "%.0f"); - ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f"); - ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f, 12.0f, "%.0f"); - ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 12.0f, "%.0f"); - ImGui::Text("Alignment"); - ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f"); - ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign, 0.0f, 1.0f, "%.2f"); ImGui::SameLine(); ShowHelpMarker("Alignment applies when a button is larger than its text content."); - ImGui::TreePop(); - } + if (ImGui::TreeNode("Settings")) + { + ImGui::SliderFloat2("WindowPadding", (float*)&style.WindowPadding, 0.0f, 20.0f, "%.0f"); + ImGui::SliderFloat("PopupRounding", &style.PopupRounding, 0.0f, 16.0f, "%.0f"); + ImGui::SliderFloat2("FramePadding", (float*)&style.FramePadding, 0.0f, 20.0f, "%.0f"); + ImGui::SliderFloat2("ItemSpacing", (float*)&style.ItemSpacing, 0.0f, 20.0f, "%.0f"); + ImGui::SliderFloat2("ItemInnerSpacing", (float*)&style.ItemInnerSpacing, 0.0f, 20.0f, "%.0f"); + ImGui::SliderFloat2("TouchExtraPadding", (float*)&style.TouchExtraPadding, 0.0f, 10.0f, "%.0f"); + ImGui::SliderFloat("IndentSpacing", &style.IndentSpacing, 0.0f, 30.0f, "%.0f"); + ImGui::SliderFloat("ScrollbarSize", &style.ScrollbarSize, 1.0f, 20.0f, "%.0f"); + ImGui::SliderFloat("GrabMinSize", &style.GrabMinSize, 1.0f, 20.0f, "%.0f"); + ImGui::Text("BorderSize"); + ImGui::SliderFloat("WindowBorderSize", &style.WindowBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::SliderFloat("ChildBorderSize", &style.ChildBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::SliderFloat("PopupBorderSize", &style.PopupBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::SliderFloat("FrameBorderSize", &style.FrameBorderSize, 0.0f, 1.0f, "%.0f"); + ImGui::Text("Rounding"); + ImGui::SliderFloat("WindowRounding", &style.WindowRounding, 0.0f, 14.0f, "%.0f"); + ImGui::SliderFloat("ChildRounding", &style.ChildRounding, 0.0f, 16.0f, "%.0f"); + ImGui::SliderFloat("FrameRounding", &style.FrameRounding, 0.0f, 12.0f, "%.0f"); + ImGui::SliderFloat("ScrollbarRounding", &style.ScrollbarRounding, 0.0f, 12.0f, "%.0f"); + ImGui::SliderFloat("GrabRounding", &style.GrabRounding, 0.0f, 12.0f, "%.0f"); + ImGui::Text("Alignment"); + ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f"); + ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign, 0.0f, 1.0f, "%.2f"); + ImGui::SameLine(); + ShowHelpMarker("Alignment applies when a button is larger than its text content."); + ImGui::TreePop(); + } - if (ImGui::TreeNode("Colors")) - { - static int output_dest = 0; - static bool output_only_modified = true; - if (ImGui::Button("Export Unsaved")) - { - if (output_dest == 0) - ImGui::LogToClipboard(); - else - ImGui::LogToTTY(); - ImGui::LogText("ImVec4* colors = ImGui::GetStyle().Colors;" IM_NEWLINE); - for (int i = 0; i < ImGuiCol_COUNT; i++) - { - const ImVec4& col = style.Colors[i]; - const char* name = ImGui::GetStyleColorName(i); - if (!output_only_modified || memcmp(&col, &ref->Colors[i], sizeof(ImVec4)) != 0) - ImGui::LogText("colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, %.2ff);" IM_NEWLINE, name, 23-(int)strlen(name), "", col.x, col.y, col.z, col.w); - } - ImGui::LogFinish(); - } - ImGui::SameLine(); ImGui::PushItemWidth(120); ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY\0"); ImGui::PopItemWidth(); - ImGui::SameLine(); ImGui::Checkbox("Only Modified Colors", &output_only_modified); + if (ImGui::TreeNode("Colors")) + { + static int output_dest = 0; + static bool output_only_modified = true; + if (ImGui::Button("Export Unsaved")) + { + if (output_dest == 0) + ImGui::LogToClipboard(); + else + ImGui::LogToTTY(); + ImGui::LogText("ImVec4* colors = ImGui::GetStyle().Colors;" IM_NEWLINE); + for (int i = 0; i < ImGuiCol_COUNT; i++) + { + const ImVec4& col = style.Colors[i]; + const char* name = ImGui::GetStyleColorName(i); + if (!output_only_modified || memcmp(&col, &ref->Colors[i], sizeof(ImVec4)) != 0) + ImGui::LogText("colors[ImGuiCol_%s]%*s= ImVec4(%.2ff, %.2ff, %.2ff, %.2ff);" IM_NEWLINE, name, 23 - (int)strlen(name), "", col.x, col.y, col.z, col.w); + } + ImGui::LogFinish(); + } + ImGui::SameLine(); + ImGui::PushItemWidth(120); + ImGui::Combo("##output_type", &output_dest, "To Clipboard\0To TTY\0"); + ImGui::PopItemWidth(); + ImGui::SameLine(); + ImGui::Checkbox("Only Modified Colors", &output_only_modified); - ImGui::Text("Tip: Left-click on colored square to open color picker,\nRight-click to open edit options menu."); + ImGui::Text("Tip: Left-click on colored square to open color picker,\nRight-click to open edit options menu."); - static ImGuiTextFilter filter; - filter.Draw("Filter colors", 200); + static ImGuiTextFilter filter; + filter.Draw("Filter colors", 200); - static ImGuiColorEditFlags alpha_flags = 0; - ImGui::RadioButton("Opaque", &alpha_flags, 0); ImGui::SameLine(); - ImGui::RadioButton("Alpha", &alpha_flags, ImGuiColorEditFlags_AlphaPreview); ImGui::SameLine(); - ImGui::RadioButton("Both", &alpha_flags, ImGuiColorEditFlags_AlphaPreviewHalf); + static ImGuiColorEditFlags alpha_flags = 0; + ImGui::RadioButton("Opaque", &alpha_flags, 0); + ImGui::SameLine(); + ImGui::RadioButton("Alpha", &alpha_flags, ImGuiColorEditFlags_AlphaPreview); + ImGui::SameLine(); + ImGui::RadioButton("Both", &alpha_flags, ImGuiColorEditFlags_AlphaPreviewHalf); - ImGui::BeginChild("#colors", ImVec2(0, 300), true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NavFlattened); - ImGui::PushItemWidth(-160); - for (int i = 0; i < ImGuiCol_COUNT; i++) - { - const char* name = ImGui::GetStyleColorName(i); - if (!filter.PassFilter(name)) - continue; - ImGui::PushID(i); - ImGui::ColorEdit4("##color", (float*)&style.Colors[i], ImGuiColorEditFlags_AlphaBar | alpha_flags); - if (memcmp(&style.Colors[i], &ref->Colors[i], sizeof(ImVec4)) != 0) - { - // Tips: in a real user application, you may want to merge and use an icon font into the main font, so instead of "Save"/"Revert" you'd use icons. - // Read the FAQ and misc/fonts/README.txt about using icon fonts. It's really easy and super convenient! - ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); if (ImGui::Button("Save")) ref->Colors[i] = style.Colors[i]; - ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); if (ImGui::Button("Revert")) style.Colors[i] = ref->Colors[i]; - } - ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); - ImGui::TextUnformatted(name); - ImGui::PopID(); - } - ImGui::PopItemWidth(); - ImGui::EndChild(); + ImGui::BeginChild("#colors", ImVec2(0, 300), true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NavFlattened); + ImGui::PushItemWidth(-160); + for (int i = 0; i < ImGuiCol_COUNT; i++) + { + const char* name = ImGui::GetStyleColorName(i); + if (!filter.PassFilter(name)) + continue; + ImGui::PushID(i); + ImGui::ColorEdit4("##color", (float*)&style.Colors[i], ImGuiColorEditFlags_AlphaBar | alpha_flags); + if (memcmp(&style.Colors[i], &ref->Colors[i], sizeof(ImVec4)) != 0) + { + // Tips: in a real user application, you may want to merge and use an icon font into the main font, so instead of "Save"/"Revert" you'd use icons. + // Read the FAQ and misc/fonts/README.txt about using icon fonts. It's really easy and super convenient! + ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); + if (ImGui::Button("Save")) ref->Colors[i] = style.Colors[i]; + ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); + if (ImGui::Button("Revert")) style.Colors[i] = ref->Colors[i]; + } + ImGui::SameLine(0.0f, style.ItemInnerSpacing.x); + ImGui::TextUnformatted(name); + ImGui::PopID(); + } + ImGui::PopItemWidth(); + ImGui::EndChild(); - ImGui::TreePop(); - } + ImGui::TreePop(); + } - bool fonts_opened = ImGui::TreeNode("Fonts", "Fonts (%d)", ImGui::GetIO().Fonts->Fonts.Size); - if (fonts_opened) - { - ImFontAtlas* atlas = ImGui::GetIO().Fonts; - if (ImGui::TreeNode("Atlas texture", "Atlas texture (%dx%d pixels)", atlas->TexWidth, atlas->TexHeight)) - { - ImGui::Image(atlas->TexID, ImVec2((float)atlas->TexWidth, (float)atlas->TexHeight), ImVec2(0,0), ImVec2(1,1), ImColor(255,255,255,255), ImColor(255,255,255,128)); - ImGui::TreePop(); - } - ImGui::PushItemWidth(100); - for (int i = 0; i < atlas->Fonts.Size; i++) - { - ImFont* font = atlas->Fonts[i]; - ImGui::PushID(font); - bool font_details_opened = ImGui::TreeNode(font, "Font %d: \'%s\', %.2f px, %d glyphs", i, font->ConfigData ? font->ConfigData[0].Name : "", font->FontSize, font->Glyphs.Size); - ImGui::SameLine(); if (ImGui::SmallButton("Set as default")) ImGui::GetIO().FontDefault = font; - if (font_details_opened) - { - ImGui::PushFont(font); - ImGui::Text("The quick brown fox jumps over the lazy dog"); - ImGui::PopFont(); - ImGui::DragFloat("Font scale", &font->Scale, 0.005f, 0.3f, 2.0f, "%.1f"); // Scale only this font - ImGui::InputFloat("Font offset", &font->DisplayOffset.y, 1, 1, 0); - ImGui::SameLine(); ShowHelpMarker("Note than the default embedded font is NOT meant to be scaled.\n\nFont are currently rendered into bitmaps at a given size at the time of building the atlas. You may oversample them to get some flexibility with scaling. You can also render at multiple sizes and select which one to use at runtime.\n\n(Glimmer of hope: the atlas system should hopefully be rewritten in the future to make scaling more natural and automatic.)"); - ImGui::Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent); - ImGui::Text("Fallback character: '%c' (%d)", font->FallbackChar, font->FallbackChar); - ImGui::Text("Texture surface: %d pixels (approx) ~ %dx%d", font->MetricsTotalSurface, (int)sqrtf((float)font->MetricsTotalSurface), (int)sqrtf((float)font->MetricsTotalSurface)); - for (int config_i = 0; config_i < font->ConfigDataCount; config_i++) - { - ImFontConfig* cfg = &font->ConfigData[config_i]; - ImGui::BulletText("Input %d: \'%s\', Oversample: (%d,%d), PixelSnapH: %d", config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH); - } - if (ImGui::TreeNode("Glyphs", "Glyphs (%d)", font->Glyphs.Size)) - { - // Display all glyphs of the fonts in separate pages of 256 characters - const ImFontGlyph* glyph_fallback = font->FallbackGlyph; // Forcefully/dodgily make FindGlyph() return NULL on fallback, which isn't the default behavior. - font->FallbackGlyph = NULL; - for (int base = 0; base < 0x10000; base += 256) - { - int count = 0; - for (int n = 0; n < 256; n++) - count += font->FindGlyph((ImWchar)(base + n)) ? 1 : 0; - if (count > 0 && ImGui::TreeNode((void*)(intptr_t)base, "U+%04X..U+%04X (%d %s)", base, base+255, count, count > 1 ? "glyphs" : "glyph")) - { - float cell_spacing = style.ItemSpacing.y; - ImVec2 cell_size(font->FontSize * 1, font->FontSize * 1); - ImVec2 base_pos = ImGui::GetCursorScreenPos(); - ImDrawList* draw_list = ImGui::GetWindowDrawList(); - for (int n = 0; n < 256; n++) - { - ImVec2 cell_p1(base_pos.x + (n % 16) * (cell_size.x + cell_spacing), base_pos.y + (n / 16) * (cell_size.y + cell_spacing)); - ImVec2 cell_p2(cell_p1.x + cell_size.x, cell_p1.y + cell_size.y); - const ImFontGlyph* glyph = font->FindGlyph((ImWchar)(base+n));; - draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255,255,255,100) : IM_COL32(255,255,255,50)); - font->RenderChar(draw_list, cell_size.x, cell_p1, ImGui::GetColorU32(ImGuiCol_Text), (ImWchar)(base+n)); // We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions available to generate a string. - if (glyph && ImGui::IsMouseHoveringRect(cell_p1, cell_p2)) - { - ImGui::BeginTooltip(); - ImGui::Text("Codepoint: U+%04X", base+n); - ImGui::Separator(); - ImGui::Text("AdvanceX: %.1f", glyph->AdvanceX); - ImGui::Text("Pos: (%.2f,%.2f)->(%.2f,%.2f)", glyph->X0, glyph->Y0, glyph->X1, glyph->Y1); - ImGui::Text("UV: (%.3f,%.3f)->(%.3f,%.3f)", glyph->U0, glyph->V0, glyph->U1, glyph->V1); - ImGui::EndTooltip(); - } - } - ImGui::Dummy(ImVec2((cell_size.x + cell_spacing) * 16, (cell_size.y + cell_spacing) * 16)); - ImGui::TreePop(); - } - } - font->FallbackGlyph = glyph_fallback; - ImGui::TreePop(); - } - ImGui::TreePop(); - } - ImGui::PopID(); - } - static float window_scale = 1.0f; - ImGui::DragFloat("this window scale", &window_scale, 0.005f, 0.3f, 2.0f, "%.1f"); // scale only this window - ImGui::DragFloat("global scale", &ImGui::GetIO().FontGlobalScale, 0.005f, 0.3f, 2.0f, "%.1f"); // scale everything - ImGui::PopItemWidth(); - ImGui::SetWindowFontScale(window_scale); - ImGui::TreePop(); - } + bool fonts_opened = ImGui::TreeNode("Fonts", "Fonts (%d)", ImGui::GetIO().Fonts->Fonts.Size); + if (fonts_opened) + { + ImFontAtlas* atlas = ImGui::GetIO().Fonts; + if (ImGui::TreeNode("Atlas texture", "Atlas texture (%dx%d pixels)", atlas->TexWidth, atlas->TexHeight)) + { + ImGui::Image(atlas->TexID, ImVec2((float)atlas->TexWidth, (float)atlas->TexHeight), ImVec2(0, 0), ImVec2(1, 1), ImColor(255, 255, 255, 255), ImColor(255, 255, 255, 128)); + ImGui::TreePop(); + } + ImGui::PushItemWidth(100); + for (int i = 0; i < atlas->Fonts.Size; i++) + { + ImFont* font = atlas->Fonts[i]; + ImGui::PushID(font); + bool font_details_opened = ImGui::TreeNode(font, "Font %d: \'%s\', %.2f px, %d glyphs", i, font->ConfigData ? font->ConfigData[0].Name : "", font->FontSize, font->Glyphs.Size); + ImGui::SameLine(); + if (ImGui::SmallButton("Set as default")) ImGui::GetIO().FontDefault = font; + if (font_details_opened) + { + ImGui::PushFont(font); + ImGui::Text("The quick brown fox jumps over the lazy dog"); + ImGui::PopFont(); + ImGui::DragFloat("Font scale", &font->Scale, 0.005f, 0.3f, 2.0f, "%.1f"); // Scale only this font + ImGui::InputFloat("Font offset", &font->DisplayOffset.y, 1, 1, 0); + ImGui::SameLine(); + ShowHelpMarker("Note than the default embedded font is NOT meant to be scaled.\n\nFont are currently rendered into bitmaps at a given size at the time of building the atlas. You may oversample them to get some flexibility with scaling. You can also render at multiple sizes and select which one to use at runtime.\n\n(Glimmer of hope: the atlas system should hopefully be rewritten in the future to make scaling more natural and automatic.)"); + ImGui::Text("Ascent: %f, Descent: %f, Height: %f", font->Ascent, font->Descent, font->Ascent - font->Descent); + ImGui::Text("Fallback character: '%c' (%d)", font->FallbackChar, font->FallbackChar); + ImGui::Text("Texture surface: %d pixels (approx) ~ %dx%d", font->MetricsTotalSurface, (int)sqrtf((float)font->MetricsTotalSurface), (int)sqrtf((float)font->MetricsTotalSurface)); + for (int config_i = 0; config_i < font->ConfigDataCount; config_i++) + { + ImFontConfig* cfg = &font->ConfigData[config_i]; + ImGui::BulletText("Input %d: \'%s\', Oversample: (%d,%d), PixelSnapH: %d", config_i, cfg->Name, cfg->OversampleH, cfg->OversampleV, cfg->PixelSnapH); + } + if (ImGui::TreeNode("Glyphs", "Glyphs (%d)", font->Glyphs.Size)) + { + // Display all glyphs of the fonts in separate pages of 256 characters + const ImFontGlyph* glyph_fallback = font->FallbackGlyph; // Forcefully/dodgily make FindGlyph() return NULL on fallback, which isn't the default behavior. + font->FallbackGlyph = NULL; + for (int base = 0; base < 0x10000; base += 256) + { + int count = 0; + for (int n = 0; n < 256; n++) + count += font->FindGlyph((ImWchar)(base + n)) ? 1 : 0; + if (count > 0 && ImGui::TreeNode((void*)(intptr_t)base, "U+%04X..U+%04X (%d %s)", base, base + 255, count, count > 1 ? "glyphs" : "glyph")) + { + float cell_spacing = style.ItemSpacing.y; + ImVec2 cell_size(font->FontSize * 1, font->FontSize * 1); + ImVec2 base_pos = ImGui::GetCursorScreenPos(); + ImDrawList* draw_list = ImGui::GetWindowDrawList(); + for (int n = 0; n < 256; n++) + { + ImVec2 cell_p1(base_pos.x + (n % 16) * (cell_size.x + cell_spacing), base_pos.y + (n / 16) * (cell_size.y + cell_spacing)); + ImVec2 cell_p2(cell_p1.x + cell_size.x, cell_p1.y + cell_size.y); + const ImFontGlyph* glyph = font->FindGlyph((ImWchar)(base + n)); + ; + draw_list->AddRect(cell_p1, cell_p2, glyph ? IM_COL32(255, 255, 255, 100) : IM_COL32(255, 255, 255, 50)); + font->RenderChar(draw_list, cell_size.x, cell_p1, ImGui::GetColorU32(ImGuiCol_Text), (ImWchar)(base + n)); // We use ImFont::RenderChar as a shortcut because we don't have UTF-8 conversion functions available to generate a string. + if (glyph && ImGui::IsMouseHoveringRect(cell_p1, cell_p2)) + { + ImGui::BeginTooltip(); + ImGui::Text("Codepoint: U+%04X", base + n); + ImGui::Separator(); + ImGui::Text("AdvanceX: %.1f", glyph->AdvanceX); + ImGui::Text("Pos: (%.2f,%.2f)->(%.2f,%.2f)", glyph->X0, glyph->Y0, glyph->X1, glyph->Y1); + ImGui::Text("UV: (%.3f,%.3f)->(%.3f,%.3f)", glyph->U0, glyph->V0, glyph->U1, glyph->V1); + ImGui::EndTooltip(); + } + } + ImGui::Dummy(ImVec2((cell_size.x + cell_spacing) * 16, (cell_size.y + cell_spacing) * 16)); + ImGui::TreePop(); + } + } + font->FallbackGlyph = glyph_fallback; + ImGui::TreePop(); + } + ImGui::TreePop(); + } + ImGui::PopID(); + } + static float window_scale = 1.0f; + ImGui::DragFloat("this window scale", &window_scale, 0.005f, 0.3f, 2.0f, "%.1f"); // scale only this window + ImGui::DragFloat("global scale", &ImGui::GetIO().FontGlobalScale, 0.005f, 0.3f, 2.0f, "%.1f"); // scale everything + ImGui::PopItemWidth(); + ImGui::SetWindowFontScale(window_scale); + ImGui::TreePop(); + } - ImGui::PopItemWidth(); + ImGui::PopItemWidth(); } // Demonstrate creating a fullscreen menu bar and populating it. static void ShowExampleAppMainMenuBar() { - if (ImGui::BeginMainMenuBar()) - { - if (ImGui::BeginMenu("File")) - { - ShowExampleMenuFile(); - ImGui::EndMenu(); - } - if (ImGui::BeginMenu("Edit")) - { - if (ImGui::MenuItem("Undo", "CTRL+Z")) {} - if (ImGui::MenuItem("Redo", "CTRL+Y", false, false)) {} // Disabled item - ImGui::Separator(); - if (ImGui::MenuItem("Cut", "CTRL+X")) {} - if (ImGui::MenuItem("Copy", "CTRL+C")) {} - if (ImGui::MenuItem("Paste", "CTRL+V")) {} - ImGui::EndMenu(); - } - ImGui::EndMainMenuBar(); - } + if (ImGui::BeginMainMenuBar()) + { + if (ImGui::BeginMenu("File")) + { + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Edit")) + { + if (ImGui::MenuItem("Undo", "CTRL+Z")) + { + } + if (ImGui::MenuItem("Redo", "CTRL+Y", false, false)) + { + } // Disabled item + ImGui::Separator(); + if (ImGui::MenuItem("Cut", "CTRL+X")) + { + } + if (ImGui::MenuItem("Copy", "CTRL+C")) + { + } + if (ImGui::MenuItem("Paste", "CTRL+V")) + { + } + ImGui::EndMenu(); + } + ImGui::EndMainMenuBar(); + } } static void ShowExampleMenuFile() { - ImGui::MenuItem("(dummy menu)", NULL, false, false); - if (ImGui::MenuItem("New")) {} - if (ImGui::MenuItem("Open", "Ctrl+O")) {} - if (ImGui::BeginMenu("Open Recent")) - { - ImGui::MenuItem("fish_hat.c"); - ImGui::MenuItem("fish_hat.inl"); - ImGui::MenuItem("fish_hat.h"); - if (ImGui::BeginMenu("More..")) - { - ImGui::MenuItem("Hello"); - ImGui::MenuItem("Sailor"); - if (ImGui::BeginMenu("Recurse..")) - { - ShowExampleMenuFile(); - ImGui::EndMenu(); - } - ImGui::EndMenu(); - } - ImGui::EndMenu(); - } - if (ImGui::MenuItem("Save", "Ctrl+S")) {} - if (ImGui::MenuItem("Save As..")) {} - ImGui::Separator(); - if (ImGui::BeginMenu("Options")) - { - static bool enabled = true; - ImGui::MenuItem("Enabled", "", &enabled); - ImGui::BeginChild("child", ImVec2(0, 60), true); - for (int i = 0; i < 10; i++) - ImGui::Text("Scrolling Text %d", i); - ImGui::EndChild(); - static float f = 0.5f; - static int n = 0; - static bool b = true; - ImGui::SliderFloat("Value", &f, 0.0f, 1.0f); - ImGui::InputFloat("Input", &f, 0.1f); - ImGui::Combo("Combo", &n, "Yes\0No\0Maybe\0\0"); - ImGui::Checkbox("Check", &b); - ImGui::EndMenu(); - } - if (ImGui::BeginMenu("Colors")) - { - float sz = ImGui::GetTextLineHeight(); - for (int i = 0; i < ImGuiCol_COUNT; i++) - { - const char* name = ImGui::GetStyleColorName((ImGuiCol)i); - ImVec2 p = ImGui::GetCursorScreenPos(); - ImGui::GetWindowDrawList()->AddRectFilled(p, ImVec2(p.x+sz, p.y+sz), ImGui::GetColorU32((ImGuiCol)i)); - ImGui::Dummy(ImVec2(sz, sz)); - ImGui::SameLine(); - ImGui::MenuItem(name); - } - ImGui::EndMenu(); - } - if (ImGui::BeginMenu("Disabled", false)) // Disabled - { - IM_ASSERT(0); - } - if (ImGui::MenuItem("Checked", NULL, true)) {} - if (ImGui::MenuItem("Quit", "Alt+F4")) {} + ImGui::MenuItem("(dummy menu)", NULL, false, false); + if (ImGui::MenuItem("New")) + { + } + if (ImGui::MenuItem("Open", "Ctrl+O")) + { + } + if (ImGui::BeginMenu("Open Recent")) + { + ImGui::MenuItem("fish_hat.c"); + ImGui::MenuItem("fish_hat.inl"); + ImGui::MenuItem("fish_hat.h"); + if (ImGui::BeginMenu("More..")) + { + ImGui::MenuItem("Hello"); + ImGui::MenuItem("Sailor"); + if (ImGui::BeginMenu("Recurse..")) + { + ShowExampleMenuFile(); + ImGui::EndMenu(); + } + ImGui::EndMenu(); + } + ImGui::EndMenu(); + } + if (ImGui::MenuItem("Save", "Ctrl+S")) + { + } + if (ImGui::MenuItem("Save As..")) + { + } + ImGui::Separator(); + if (ImGui::BeginMenu("Options")) + { + static bool enabled = true; + ImGui::MenuItem("Enabled", "", &enabled); + ImGui::BeginChild("child", ImVec2(0, 60), true); + for (int i = 0; i < 10; i++) + ImGui::Text("Scrolling Text %d", i); + ImGui::EndChild(); + static float f = 0.5f; + static int n = 0; + static bool b = true; + ImGui::SliderFloat("Value", &f, 0.0f, 1.0f); + ImGui::InputFloat("Input", &f, 0.1f); + ImGui::Combo("Combo", &n, "Yes\0No\0Maybe\0\0"); + ImGui::Checkbox("Check", &b); + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Colors")) + { + float sz = ImGui::GetTextLineHeight(); + for (int i = 0; i < ImGuiCol_COUNT; i++) + { + const char* name = ImGui::GetStyleColorName((ImGuiCol)i); + ImVec2 p = ImGui::GetCursorScreenPos(); + ImGui::GetWindowDrawList()->AddRectFilled(p, ImVec2(p.x + sz, p.y + sz), ImGui::GetColorU32((ImGuiCol)i)); + ImGui::Dummy(ImVec2(sz, sz)); + ImGui::SameLine(); + ImGui::MenuItem(name); + } + ImGui::EndMenu(); + } + if (ImGui::BeginMenu("Disabled", false)) // Disabled + { + IM_ASSERT(0); + } + if (ImGui::MenuItem("Checked", NULL, true)) + { + } + if (ImGui::MenuItem("Quit", "Alt+F4")) + { + } } // Demonstrate creating a window which gets auto-resized according to its content. static void ShowExampleAppAutoResize(bool* p_open) { - if (!ImGui::Begin("Example: Auto-resizing window", p_open, ImGuiWindowFlags_AlwaysAutoResize)) - { - ImGui::End(); - return; - } + if (!ImGui::Begin("Example: Auto-resizing window", p_open, ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::End(); + return; + } - static int lines = 10; - ImGui::Text("Window will resize every-frame to the size of its content.\nNote that you probably don't want to query the window size to\noutput your content because that would create a feedback loop."); - ImGui::SliderInt("Number of lines", &lines, 1, 20); - for (int i = 0; i < lines; i++) - ImGui::Text("%*sThis is line %d", i*4, "", i); // Pad with space to extend size horizontally - ImGui::End(); + static int lines = 10; + ImGui::Text("Window will resize every-frame to the size of its content.\nNote that you probably don't want to query the window size to\noutput your content because that would create a feedback loop."); + ImGui::SliderInt("Number of lines", &lines, 1, 20); + for (int i = 0; i < lines; i++) + ImGui::Text("%*sThis is line %d", i * 4, "", i); // Pad with space to extend size horizontally + ImGui::End(); } // Demonstrate creating a window with custom resize constraints. static void ShowExampleAppConstrainedResize(bool* p_open) { - struct CustomConstraints // Helper functions to demonstrate programmatic constraints - { - static void Square(ImGuiSizeCallbackData* data) { data->DesiredSize = ImVec2(IM_MAX(data->DesiredSize.x, data->DesiredSize.y), IM_MAX(data->DesiredSize.x, data->DesiredSize.y)); } - static void Step(ImGuiSizeCallbackData* data) { float step = (float)(int)(intptr_t)data->UserData; data->DesiredSize = ImVec2((int)(data->DesiredSize.x / step + 0.5f) * step, (int)(data->DesiredSize.y / step + 0.5f) * step); } - }; + struct CustomConstraints // Helper functions to demonstrate programmatic constraints + { + static void Square(ImGuiSizeCallbackData* data) { data->DesiredSize = ImVec2(IM_MAX(data->DesiredSize.x, data->DesiredSize.y), IM_MAX(data->DesiredSize.x, data->DesiredSize.y)); } + static void Step(ImGuiSizeCallbackData* data) + { + float step = (float)(int)(intptr_t)data->UserData; + data->DesiredSize = ImVec2((int)(data->DesiredSize.x / step + 0.5f) * step, (int)(data->DesiredSize.y / step + 0.5f) * step); + } + }; - static bool auto_resize = false; - static int type = 0; - static int display_lines = 10; - if (type == 0) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 0), ImVec2(-1, FLT_MAX)); // Vertical only - if (type == 1) ImGui::SetNextWindowSizeConstraints(ImVec2(0, -1), ImVec2(FLT_MAX, -1)); // Horizontal only - if (type == 2) ImGui::SetNextWindowSizeConstraints(ImVec2(100, 100), ImVec2(FLT_MAX, FLT_MAX)); // Width > 100, Height > 100 - if (type == 3) ImGui::SetNextWindowSizeConstraints(ImVec2(400, -1), ImVec2(500, -1)); // Width 400-500 - if (type == 4) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 400), ImVec2(-1, 500)); // Height 400-500 - if (type == 5) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Square); // Always Square - if (type == 6) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Step, (void*)100);// Fixed Step + static bool auto_resize = false; + static int type = 0; + static int display_lines = 10; + if (type == 0) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 0), ImVec2(-1, FLT_MAX)); // Vertical only + if (type == 1) ImGui::SetNextWindowSizeConstraints(ImVec2(0, -1), ImVec2(FLT_MAX, -1)); // Horizontal only + if (type == 2) ImGui::SetNextWindowSizeConstraints(ImVec2(100, 100), ImVec2(FLT_MAX, FLT_MAX)); // Width > 100, Height > 100 + if (type == 3) ImGui::SetNextWindowSizeConstraints(ImVec2(400, -1), ImVec2(500, -1)); // Width 400-500 + if (type == 4) ImGui::SetNextWindowSizeConstraints(ImVec2(-1, 400), ImVec2(-1, 500)); // Height 400-500 + if (type == 5) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Square); // Always Square + if (type == 6) ImGui::SetNextWindowSizeConstraints(ImVec2(0, 0), ImVec2(FLT_MAX, FLT_MAX), CustomConstraints::Step, (void*)100); // Fixed Step - ImGuiWindowFlags flags = auto_resize ? ImGuiWindowFlags_AlwaysAutoResize : 0; - if (ImGui::Begin("Example: Constrained Resize", p_open, flags)) - { - const char* desc[] = - { - "Resize vertical only", - "Resize horizontal only", - "Width > 100, Height > 100", - "Width 400-500", - "Height 400-500", - "Custom: Always Square", - "Custom: Fixed Steps (100)", - }; - if (ImGui::Button("200x200")) { ImGui::SetWindowSize(ImVec2(200, 200)); } ImGui::SameLine(); - if (ImGui::Button("500x500")) { ImGui::SetWindowSize(ImVec2(500, 500)); } ImGui::SameLine(); - if (ImGui::Button("800x200")) { ImGui::SetWindowSize(ImVec2(800, 200)); } - ImGui::PushItemWidth(200); - ImGui::Combo("Constraint", &type, desc, IM_ARRAYSIZE(desc)); - ImGui::DragInt("Lines", &display_lines, 0.2f, 1, 100); - ImGui::PopItemWidth(); - ImGui::Checkbox("Auto-resize", &auto_resize); - for (int i = 0; i < display_lines; i++) - ImGui::Text("%*sHello, sailor! Making this line long enough for the example.", i * 4, ""); - } - ImGui::End(); + ImGuiWindowFlags flags = auto_resize ? ImGuiWindowFlags_AlwaysAutoResize : 0; + if (ImGui::Begin("Example: Constrained Resize", p_open, flags)) + { + const char* desc[] = + { + "Resize vertical only", + "Resize horizontal only", + "Width > 100, Height > 100", + "Width 400-500", + "Height 400-500", + "Custom: Always Square", + "Custom: Fixed Steps (100)", + }; + if (ImGui::Button("200x200")) + { + ImGui::SetWindowSize(ImVec2(200, 200)); + } + ImGui::SameLine(); + if (ImGui::Button("500x500")) + { + ImGui::SetWindowSize(ImVec2(500, 500)); + } + ImGui::SameLine(); + if (ImGui::Button("800x200")) + { + ImGui::SetWindowSize(ImVec2(800, 200)); + } + ImGui::PushItemWidth(200); + ImGui::Combo("Constraint", &type, desc, IM_ARRAYSIZE(desc)); + ImGui::DragInt("Lines", &display_lines, 0.2f, 1, 100); + ImGui::PopItemWidth(); + ImGui::Checkbox("Auto-resize", &auto_resize); + for (int i = 0; i < display_lines; i++) + ImGui::Text("%*sHello, sailor! Making this line long enough for the example.", i * 4, ""); + } + ImGui::End(); } // Demonstrate creating a simple static window with no decoration + a context-menu to choose which corner of the screen to use. static void ShowExampleAppFixedOverlay(bool* p_open) { - const float DISTANCE = 10.0f; - static int corner = 0; - ImVec2 window_pos = ImVec2((corner & 1) ? ImGui::GetIO().DisplaySize.x - DISTANCE : DISTANCE, (corner & 2) ? ImGui::GetIO().DisplaySize.y - DISTANCE : DISTANCE); - ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f); - ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot); - ImGui::SetNextWindowBgAlpha(0.3f); // Transparent background - if (ImGui::Begin("Example: Fixed Overlay", p_open, ImGuiWindowFlags_NoTitleBar|ImGuiWindowFlags_NoResize|ImGuiWindowFlags_AlwaysAutoResize|ImGuiWindowFlags_NoMove|ImGuiWindowFlags_NoSavedSettings|ImGuiWindowFlags_NoFocusOnAppearing|ImGuiWindowFlags_NoNav)) - { - ImGui::Text("Simple overlay\nin the corner of the screen.\n(right-click to change position)"); - ImGui::Separator(); - ImGui::Text("Mouse Position: (%.1f,%.1f)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y); - if (ImGui::BeginPopupContextWindow()) - { - if (ImGui::MenuItem("Top-left", NULL, corner == 0)) corner = 0; - if (ImGui::MenuItem("Top-right", NULL, corner == 1)) corner = 1; - if (ImGui::MenuItem("Bottom-left", NULL, corner == 2)) corner = 2; - if (ImGui::MenuItem("Bottom-right", NULL, corner == 3)) corner = 3; - if (p_open && ImGui::MenuItem("Close")) *p_open = false; - ImGui::EndPopup(); - } - ImGui::End(); - } + const float DISTANCE = 10.0f; + static int corner = 0; + ImVec2 window_pos = ImVec2((corner & 1) ? ImGui::GetIO().DisplaySize.x - DISTANCE : DISTANCE, (corner & 2) ? ImGui::GetIO().DisplaySize.y - DISTANCE : DISTANCE); + ImVec2 window_pos_pivot = ImVec2((corner & 1) ? 1.0f : 0.0f, (corner & 2) ? 1.0f : 0.0f); + ImGui::SetNextWindowPos(window_pos, ImGuiCond_Always, window_pos_pivot); + ImGui::SetNextWindowBgAlpha(0.3f); // Transparent background + if (ImGui::Begin("Example: Fixed Overlay", p_open, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav)) + { + ImGui::Text("Simple overlay\nin the corner of the screen.\n(right-click to change position)"); + ImGui::Separator(); + ImGui::Text("Mouse Position: (%.1f,%.1f)", ImGui::GetIO().MousePos.x, ImGui::GetIO().MousePos.y); + if (ImGui::BeginPopupContextWindow()) + { + if (ImGui::MenuItem("Top-left", NULL, corner == 0)) corner = 0; + if (ImGui::MenuItem("Top-right", NULL, corner == 1)) corner = 1; + if (ImGui::MenuItem("Bottom-left", NULL, corner == 2)) corner = 2; + if (ImGui::MenuItem("Bottom-right", NULL, corner == 3)) corner = 3; + if (p_open && ImGui::MenuItem("Close")) *p_open = false; + ImGui::EndPopup(); + } + ImGui::End(); + } } // Demonstrate using "##" and "###" in identifiers to manipulate ID generation. // This apply to regular items as well. Read FAQ section "How can I have multiple widgets with the same label? Can I have widget without a label? (Yes). A primer on the purpose of labels/IDs." for details. static void ShowExampleAppWindowTitles(bool*) { - // By default, Windows are uniquely identified by their title. - // You can use the "##" and "###" markers to manipulate the display/ID. + // By default, Windows are uniquely identified by their title. + // You can use the "##" and "###" markers to manipulate the display/ID. - // Using "##" to display same title but have unique identifier. - ImGui::SetNextWindowPos(ImVec2(100,100), ImGuiCond_FirstUseEver); - ImGui::Begin("Same title as another window##1"); - ImGui::Text("This is window 1.\nMy title is the same as window 2, but my identifier is unique."); - ImGui::End(); + // Using "##" to display same title but have unique identifier. + ImGui::SetNextWindowPos(ImVec2(100, 100), ImGuiCond_FirstUseEver); + ImGui::Begin("Same title as another window##1"); + ImGui::Text("This is window 1.\nMy title is the same as window 2, but my identifier is unique."); + ImGui::End(); - ImGui::SetNextWindowPos(ImVec2(100,200), ImGuiCond_FirstUseEver); - ImGui::Begin("Same title as another window##2"); - ImGui::Text("This is window 2.\nMy title is the same as window 1, but my identifier is unique."); - ImGui::End(); + ImGui::SetNextWindowPos(ImVec2(100, 200), ImGuiCond_FirstUseEver); + ImGui::Begin("Same title as another window##2"); + ImGui::Text("This is window 2.\nMy title is the same as window 1, but my identifier is unique."); + ImGui::End(); - // Using "###" to display a changing title but keep a static identifier "AnimatedTitle" - char buf[128]; - sprintf(buf, "Animated title %c %d###AnimatedTitle", "|/-\\"[(int)(ImGui::GetTime()/0.25f)&3], ImGui::GetFrameCount()); - ImGui::SetNextWindowPos(ImVec2(100,300), ImGuiCond_FirstUseEver); - ImGui::Begin(buf); - ImGui::Text("This window has a changing title."); - ImGui::End(); + // Using "###" to display a changing title but keep a static identifier "AnimatedTitle" + char buf[128]; + sprintf(buf, "Animated title %c %d###AnimatedTitle", "|/-\\"[(int)(ImGui::GetTime() / 0.25f) & 3], ImGui::GetFrameCount()); + ImGui::SetNextWindowPos(ImVec2(100, 300), ImGuiCond_FirstUseEver); + ImGui::Begin(buf); + ImGui::Text("This window has a changing title."); + ImGui::End(); } -// Demonstrate using the low-level ImDrawList to draw custom shapes. +// Demonstrate using the low-level ImDrawList to draw custom shapes. static void ShowExampleAppCustomRendering(bool* p_open) { - ImGui::SetNextWindowSize(ImVec2(350,560), ImGuiCond_FirstUseEver); - if (!ImGui::Begin("Example: Custom rendering", p_open)) - { - ImGui::End(); - return; - } + ImGui::SetNextWindowSize(ImVec2(350, 560), ImGuiCond_FirstUseEver); + if (!ImGui::Begin("Example: Custom rendering", p_open)) + { + ImGui::End(); + return; + } - // Tip: If you do a lot of custom rendering, you probably want to use your own geometrical types and benefit of overloaded operators, etc. - // Define IM_VEC2_CLASS_EXTRA in imconfig.h to create implicit conversions between your types and ImVec2/ImVec4. - // ImGui defines overloaded operators but they are internal to imgui.cpp and not exposed outside (to avoid messing with your types) - // In this example we are not using the maths operators! - ImDrawList* draw_list = ImGui::GetWindowDrawList(); + // Tip: If you do a lot of custom rendering, you probably want to use your own geometrical types and benefit of overloaded operators, etc. + // Define IM_VEC2_CLASS_EXTRA in imconfig.h to create implicit conversions between your types and ImVec2/ImVec4. + // ImGui defines overloaded operators but they are internal to imgui.cpp and not exposed outside (to avoid messing with your types) + // In this example we are not using the maths operators! + ImDrawList* draw_list = ImGui::GetWindowDrawList(); - // Primitives - ImGui::Text("Primitives"); - static float sz = 36.0f; - static ImVec4 col = ImVec4(1.0f,1.0f,0.4f,1.0f); - ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 72.0f, "%.0f"); - ImGui::ColorEdit3("Color", &col.x); - { - const ImVec2 p = ImGui::GetCursorScreenPos(); - const ImU32 col32 = ImColor(col); - float x = p.x + 4.0f, y = p.y + 4.0f, spacing = 8.0f; - for (int n = 0; n < 2; n++) - { - float thickness = (n == 0) ? 1.0f : 4.0f; - draw_list->AddCircle(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 20, thickness); x += sz+spacing; - draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 0.0f, ImDrawCornerFlags_All, thickness); x += sz+spacing; - draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_All, thickness); x += sz+spacing; - draw_list->AddRect(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_TopLeft|ImDrawCornerFlags_BotRight, thickness); x += sz+spacing; - draw_list->AddTriangle(ImVec2(x+sz*0.5f, y), ImVec2(x+sz,y+sz-0.5f), ImVec2(x,y+sz-0.5f), col32, thickness); x += sz+spacing; - draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y ), col32, thickness); x += sz+spacing; - draw_list->AddLine(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, thickness); x += sz+spacing; - draw_list->AddLine(ImVec2(x, y), ImVec2(x, y+sz), col32, thickness); x += spacing; - draw_list->AddBezierCurve(ImVec2(x, y), ImVec2(x+sz*1.3f,y+sz*0.3f), ImVec2(x+sz-sz*1.3f,y+sz-sz*0.3f), ImVec2(x+sz, y+sz), col32, thickness); - x = p.x + 4; - y += sz+spacing; - } - draw_list->AddCircleFilled(ImVec2(x+sz*0.5f, y+sz*0.5f), sz*0.5f, col32, 32); x += sz+spacing; - draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32); x += sz+spacing; - draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f); x += sz+spacing; - draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x+sz, y+sz), col32, 10.0f, ImDrawCornerFlags_TopLeft|ImDrawCornerFlags_BotRight); x += sz+spacing; - draw_list->AddTriangleFilled(ImVec2(x+sz*0.5f, y), ImVec2(x+sz,y+sz-0.5f), ImVec2(x,y+sz-0.5f), col32); x += sz+spacing; - draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x+sz, y+sz), IM_COL32(0,0,0,255), IM_COL32(255,0,0,255), IM_COL32(255,255,0,255), IM_COL32(0,255,0,255)); - ImGui::Dummy(ImVec2((sz+spacing)*8, (sz+spacing)*3)); - } - ImGui::Separator(); - { - static ImVector points; - static bool adding_line = false; - ImGui::Text("Canvas example"); - if (ImGui::Button("Clear")) points.clear(); - if (points.Size >= 2) { ImGui::SameLine(); if (ImGui::Button("Undo")) { points.pop_back(); points.pop_back(); } } - ImGui::Text("Left-click and drag to add lines,\nRight-click to undo"); + // Primitives + ImGui::Text("Primitives"); + static float sz = 36.0f; + static ImVec4 col = ImVec4(1.0f, 1.0f, 0.4f, 1.0f); + ImGui::DragFloat("Size", &sz, 0.2f, 2.0f, 72.0f, "%.0f"); + ImGui::ColorEdit3("Color", &col.x); + { + const ImVec2 p = ImGui::GetCursorScreenPos(); + const ImU32 col32 = ImColor(col); + float x = p.x + 4.0f, y = p.y + 4.0f, spacing = 8.0f; + for (int n = 0; n < 2; n++) + { + float thickness = (n == 0) ? 1.0f : 4.0f; + draw_list->AddCircle(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz * 0.5f, col32, 20, thickness); + x += sz + spacing; + draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col32, 0.0f, ImDrawCornerFlags_All, thickness); + x += sz + spacing; + draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col32, 10.0f, ImDrawCornerFlags_All, thickness); + x += sz + spacing; + draw_list->AddRect(ImVec2(x, y), ImVec2(x + sz, y + sz), col32, 10.0f, ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotRight, thickness); + x += sz + spacing; + draw_list->AddTriangle(ImVec2(x + sz * 0.5f, y), ImVec2(x + sz, y + sz - 0.5f), ImVec2(x, y + sz - 0.5f), col32, thickness); + x += sz + spacing; + draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y), col32, thickness); + x += sz + spacing; + draw_list->AddLine(ImVec2(x, y), ImVec2(x + sz, y + sz), col32, thickness); + x += sz + spacing; + draw_list->AddLine(ImVec2(x, y), ImVec2(x, y + sz), col32, thickness); + x += spacing; + draw_list->AddBezierCurve(ImVec2(x, y), ImVec2(x + sz * 1.3f, y + sz * 0.3f), ImVec2(x + sz - sz * 1.3f, y + sz - sz * 0.3f), ImVec2(x + sz, y + sz), col32, thickness); + x = p.x + 4; + y += sz + spacing; + } + draw_list->AddCircleFilled(ImVec2(x + sz * 0.5f, y + sz * 0.5f), sz * 0.5f, col32, 32); + x += sz + spacing; + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col32); + x += sz + spacing; + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col32, 10.0f); + x += sz + spacing; + draw_list->AddRectFilled(ImVec2(x, y), ImVec2(x + sz, y + sz), col32, 10.0f, ImDrawCornerFlags_TopLeft | ImDrawCornerFlags_BotRight); + x += sz + spacing; + draw_list->AddTriangleFilled(ImVec2(x + sz * 0.5f, y), ImVec2(x + sz, y + sz - 0.5f), ImVec2(x, y + sz - 0.5f), col32); + x += sz + spacing; + draw_list->AddRectFilledMultiColor(ImVec2(x, y), ImVec2(x + sz, y + sz), IM_COL32(0, 0, 0, 255), IM_COL32(255, 0, 0, 255), IM_COL32(255, 255, 0, 255), IM_COL32(0, 255, 0, 255)); + ImGui::Dummy(ImVec2((sz + spacing) * 8, (sz + spacing) * 3)); + } + ImGui::Separator(); + { + static ImVector points; + static bool adding_line = false; + ImGui::Text("Canvas example"); + if (ImGui::Button("Clear")) points.clear(); + if (points.Size >= 2) + { + ImGui::SameLine(); + if (ImGui::Button("Undo")) + { + points.pop_back(); + points.pop_back(); + } + } + ImGui::Text("Left-click and drag to add lines,\nRight-click to undo"); - // Here we are using InvisibleButton() as a convenience to 1) advance the cursor and 2) allows us to use IsItemHovered() - // However you can draw directly and poll mouse/keyboard by yourself. You can manipulate the cursor using GetCursorPos() and SetCursorPos(). - // If you only use the ImDrawList API, you can notify the owner window of its extends by using SetCursorPos(max). - ImVec2 canvas_pos = ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates! - ImVec2 canvas_size = ImGui::GetContentRegionAvail(); // Resize canvas to what's available - if (canvas_size.x < 50.0f) canvas_size.x = 50.0f; - if (canvas_size.y < 50.0f) canvas_size.y = 50.0f; - draw_list->AddRectFilledMultiColor(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), IM_COL32(50,50,50,255), IM_COL32(50,50,60,255), IM_COL32(60,60,70,255), IM_COL32(50,50,60,255)); - draw_list->AddRect(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), IM_COL32(255,255,255,255)); + // Here we are using InvisibleButton() as a convenience to 1) advance the cursor and 2) allows us to use IsItemHovered() + // However you can draw directly and poll mouse/keyboard by yourself. You can manipulate the cursor using GetCursorPos() and SetCursorPos(). + // If you only use the ImDrawList API, you can notify the owner window of its extends by using SetCursorPos(max). + ImVec2 canvas_pos = ImGui::GetCursorScreenPos(); // ImDrawList API uses screen coordinates! + ImVec2 canvas_size = ImGui::GetContentRegionAvail(); // Resize canvas to what's available + if (canvas_size.x < 50.0f) canvas_size.x = 50.0f; + if (canvas_size.y < 50.0f) canvas_size.y = 50.0f; + draw_list->AddRectFilledMultiColor(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), IM_COL32(50, 50, 50, 255), IM_COL32(50, 50, 60, 255), IM_COL32(60, 60, 70, 255), IM_COL32(50, 50, 60, 255)); + draw_list->AddRect(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), IM_COL32(255, 255, 255, 255)); - bool adding_preview = false; - ImGui::InvisibleButton("canvas", canvas_size); - ImVec2 mouse_pos_in_canvas = ImVec2(ImGui::GetIO().MousePos.x - canvas_pos.x, ImGui::GetIO().MousePos.y - canvas_pos.y); - if (adding_line) - { - adding_preview = true; - points.push_back(mouse_pos_in_canvas); - if (!ImGui::IsMouseDown(0)) - adding_line = adding_preview = false; - } - if (ImGui::IsItemHovered()) - { - if (!adding_line && ImGui::IsMouseClicked(0)) - { - points.push_back(mouse_pos_in_canvas); - adding_line = true; - } - if (ImGui::IsMouseClicked(1) && !points.empty()) - { - adding_line = adding_preview = false; - points.pop_back(); - points.pop_back(); - } - } - draw_list->PushClipRect(canvas_pos, ImVec2(canvas_pos.x+canvas_size.x, canvas_pos.y+canvas_size.y), true); // clip lines within the canvas (if we resize it, etc.) - for (int i = 0; i < points.Size - 1; i += 2) - draw_list->AddLine(ImVec2(canvas_pos.x + points[i].x, canvas_pos.y + points[i].y), ImVec2(canvas_pos.x + points[i+1].x, canvas_pos.y + points[i+1].y), IM_COL32(255,255,0,255), 2.0f); - draw_list->PopClipRect(); - if (adding_preview) - points.pop_back(); - } - ImGui::End(); + bool adding_preview = false; + ImGui::InvisibleButton("canvas", canvas_size); + ImVec2 mouse_pos_in_canvas = ImVec2(ImGui::GetIO().MousePos.x - canvas_pos.x, ImGui::GetIO().MousePos.y - canvas_pos.y); + if (adding_line) + { + adding_preview = true; + points.push_back(mouse_pos_in_canvas); + if (!ImGui::IsMouseDown(0)) + adding_line = adding_preview = false; + } + if (ImGui::IsItemHovered()) + { + if (!adding_line && ImGui::IsMouseClicked(0)) + { + points.push_back(mouse_pos_in_canvas); + adding_line = true; + } + if (ImGui::IsMouseClicked(1) && !points.empty()) + { + adding_line = adding_preview = false; + points.pop_back(); + points.pop_back(); + } + } + draw_list->PushClipRect(canvas_pos, ImVec2(canvas_pos.x + canvas_size.x, canvas_pos.y + canvas_size.y), true); // clip lines within the canvas (if we resize it, etc.) + for (int i = 0; i < points.Size - 1; i += 2) + draw_list->AddLine(ImVec2(canvas_pos.x + points[i].x, canvas_pos.y + points[i].y), ImVec2(canvas_pos.x + points[i + 1].x, canvas_pos.y + points[i + 1].y), IM_COL32(255, 255, 0, 255), 2.0f); + draw_list->PopClipRect(); + if (adding_preview) + points.pop_back(); + } + ImGui::End(); } // Demonstrating creating a simple console window, with scrolling, filtering, completion and history. // For the console example, here we are using a more C++ like approach of declaring a class to hold the data and the functions. struct ExampleAppConsole { - char InputBuf[256]; - ImVector Items; - bool ScrollToBottom; - ImVector History; - int HistoryPos; // -1: new line, 0..History.Size-1 browsing history. - ImVector Commands; + char InputBuf[256]; + ImVector Items; + bool ScrollToBottom; + ImVector History; + int HistoryPos; // -1: new line, 0..History.Size-1 browsing history. + ImVector Commands; - ExampleAppConsole() - { - ClearLog(); - memset(InputBuf, 0, sizeof(InputBuf)); - HistoryPos = -1; - Commands.push_back("HELP"); - Commands.push_back("HISTORY"); - Commands.push_back("CLEAR"); - Commands.push_back("CLASSIFY"); // "classify" is here to provide an example of "C"+[tab] completing to "CL" and displaying matches. - AddLog("Welcome to ImGui!"); - } - ~ExampleAppConsole() - { - ClearLog(); - for (int i = 0; i < History.Size; i++) - free(History[i]); - } + ExampleAppConsole() + { + ClearLog(); + memset(InputBuf, 0, sizeof(InputBuf)); + HistoryPos = -1; + Commands.push_back("HELP"); + Commands.push_back("HISTORY"); + Commands.push_back("CLEAR"); + Commands.push_back("CLASSIFY"); // "classify" is here to provide an example of "C"+[tab] completing to "CL" and displaying matches. + AddLog("Welcome to ImGui!"); + } + ~ExampleAppConsole() + { + ClearLog(); + for (int i = 0; i < History.Size; i++) + free(History[i]); + } - // Portable helpers - static int Stricmp(const char* str1, const char* str2) { int d; while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; } return d; } - static int Strnicmp(const char* str1, const char* str2, int n) { int d = 0; while (n > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) { str1++; str2++; n--; } return d; } - static char* Strdup(const char *str) { size_t len = strlen(str) + 1; void* buff = malloc(len); return (char*)memcpy(buff, (const void*)str, len); } + // Portable helpers + static int Stricmp(const char* str1, const char* str2) + { + int d; + while ((d = toupper(*str2) - toupper(*str1)) == 0 && *str1) + { + str1++; + str2++; + } + return d; + } + static int Strnicmp(const char* str1, const char* str2, int n) + { + int d = 0; + while (n > 0 && (d = toupper(*str2) - toupper(*str1)) == 0 && *str1) + { + str1++; + str2++; + n--; + } + return d; + } + static char* Strdup(const char* str) + { + size_t len = strlen(str) + 1; + void* buff = malloc(len); + return (char*)memcpy(buff, (const void*)str, len); + } - void ClearLog() - { - for (int i = 0; i < Items.Size; i++) - free(Items[i]); - Items.clear(); - ScrollToBottom = true; - } + void ClearLog() + { + for (int i = 0; i < Items.Size; i++) + free(Items[i]); + Items.clear(); + ScrollToBottom = true; + } - void AddLog(const char* fmt, ...) IM_FMTARGS(2) - { - // FIXME-OPT - char buf[1024]; - va_list args; - va_start(args, fmt); - vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args); - buf[IM_ARRAYSIZE(buf)-1] = 0; - va_end(args); - Items.push_back(Strdup(buf)); - ScrollToBottom = true; - } + void AddLog(const char* fmt, ...) IM_FMTARGS(2) + { + // FIXME-OPT + char buf[1024]; + va_list args; + va_start(args, fmt); + vsnprintf(buf, IM_ARRAYSIZE(buf), fmt, args); + buf[IM_ARRAYSIZE(buf) - 1] = 0; + va_end(args); + Items.push_back(Strdup(buf)); + ScrollToBottom = true; + } - void Draw(const char* title, bool* p_open) - { - ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiCond_FirstUseEver); - if (!ImGui::Begin(title, p_open)) - { - ImGui::End(); - return; - } + void Draw(const char* title, bool* p_open) + { + ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); + if (!ImGui::Begin(title, p_open)) + { + ImGui::End(); + return; + } - // As a specific feature guaranteed by the library, after calling Begin() the last Item represent the title bar. So e.g. IsItemHovered() will return true when hovering the title bar. - // Here we create a context menu only available from the title bar. - if (ImGui::BeginPopupContextItem()) - { - if (ImGui::MenuItem("Close")) - *p_open = false; - ImGui::EndPopup(); - } + // As a specific feature guaranteed by the library, after calling Begin() the last Item represent the title bar. So e.g. IsItemHovered() will return true when hovering the title bar. + // Here we create a context menu only available from the title bar. + if (ImGui::BeginPopupContextItem()) + { + if (ImGui::MenuItem("Close")) + *p_open = false; + ImGui::EndPopup(); + } - ImGui::TextWrapped("This example implements a console with basic coloring, completion and history. A more elaborate implementation may want to store entries along with extra data such as timestamp, emitter, etc."); - ImGui::TextWrapped("Enter 'HELP' for help, press TAB to use text completion."); + ImGui::TextWrapped("This example implements a console with basic coloring, completion and history. A more elaborate implementation may want to store entries along with extra data such as timestamp, emitter, etc."); + ImGui::TextWrapped("Enter 'HELP' for help, press TAB to use text completion."); - // TODO: display items starting from the bottom + // TODO: display items starting from the bottom - if (ImGui::SmallButton("Add Dummy Text")) { AddLog("%d some text", Items.Size); AddLog("some more text"); AddLog("display very important message here!"); } ImGui::SameLine(); - if (ImGui::SmallButton("Add Dummy Error")) { AddLog("[error] something went wrong"); } ImGui::SameLine(); - if (ImGui::SmallButton("Clear")) { ClearLog(); } ImGui::SameLine(); - bool copy_to_clipboard = ImGui::SmallButton("Copy"); ImGui::SameLine(); - if (ImGui::SmallButton("Scroll to bottom")) ScrollToBottom = true; - //static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); } + if (ImGui::SmallButton("Add Dummy Text")) + { + AddLog("%d some text", Items.Size); + AddLog("some more text"); + AddLog("display very important message here!"); + } + ImGui::SameLine(); + if (ImGui::SmallButton("Add Dummy Error")) + { + AddLog("[error] something went wrong"); + } + ImGui::SameLine(); + if (ImGui::SmallButton("Clear")) + { + ClearLog(); + } + ImGui::SameLine(); + bool copy_to_clipboard = ImGui::SmallButton("Copy"); + ImGui::SameLine(); + if (ImGui::SmallButton("Scroll to bottom")) ScrollToBottom = true; + //static float t = 0.0f; if (ImGui::GetTime() - t > 0.02f) { t = ImGui::GetTime(); AddLog("Spam %f", t); } - ImGui::Separator(); + ImGui::Separator(); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0,0)); - static ImGuiTextFilter filter; - filter.Draw("Filter (\"incl,-excl\") (\"error\")", 180); - ImGui::PopStyleVar(); - ImGui::Separator(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(0, 0)); + static ImGuiTextFilter filter; + filter.Draw("Filter (\"incl,-excl\") (\"error\")", 180); + ImGui::PopStyleVar(); + ImGui::Separator(); - const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing(); // 1 separator, 1 input text - ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), false, ImGuiWindowFlags_HorizontalScrollbar); // Leave room for 1 separator + 1 InputText - if (ImGui::BeginPopupContextWindow()) - { - if (ImGui::Selectable("Clear")) ClearLog(); - ImGui::EndPopup(); - } + const float footer_height_to_reserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing(); // 1 separator, 1 input text + ImGui::BeginChild("ScrollingRegion", ImVec2(0, -footer_height_to_reserve), false, ImGuiWindowFlags_HorizontalScrollbar); // Leave room for 1 separator + 1 InputText + if (ImGui::BeginPopupContextWindow()) + { + if (ImGui::Selectable("Clear")) ClearLog(); + ImGui::EndPopup(); + } - // Display every line as a separate entry so we can change their color or add custom widgets. If you only want raw text you can use ImGui::TextUnformatted(log.begin(), log.end()); - // NB- if you have thousands of entries this approach may be too inefficient and may require user-side clipping to only process visible items. - // You can seek and display only the lines that are visible using the ImGuiListClipper helper, if your elements are evenly spaced and you have cheap random access to the elements. - // To use the clipper we could replace the 'for (int i = 0; i < Items.Size; i++)' loop with: - // ImGuiListClipper clipper(Items.Size); - // while (clipper.Step()) - // for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) - // However take note that you can not use this code as is if a filter is active because it breaks the 'cheap random-access' property. We would need random-access on the post-filtered list. - // A typical application wanting coarse clipping and filtering may want to pre-compute an array of indices that passed the filtering test, recomputing this array when user changes the filter, - // and appending newly elements as they are inserted. This is left as a task to the user until we can manage to improve this example code! - // If your items are of variable size you may want to implement code similar to what ImGuiListClipper does. Or split your data into fixed height items to allow random-seeking into your list. - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4,1)); // Tighten spacing - if (copy_to_clipboard) - ImGui::LogToClipboard(); - ImVec4 col_default_text = ImGui::GetStyleColorVec4(ImGuiCol_Text); - for (int i = 0; i < Items.Size; i++) - { - const char* item = Items[i]; - if (!filter.PassFilter(item)) - continue; - ImVec4 col = col_default_text; - if (strstr(item, "[error]")) col = ImColor(1.0f,0.4f,0.4f,1.0f); - else if (strncmp(item, "# ", 2) == 0) col = ImColor(1.0f,0.78f,0.58f,1.0f); - ImGui::PushStyleColor(ImGuiCol_Text, col); - ImGui::TextUnformatted(item); - ImGui::PopStyleColor(); - } - if (copy_to_clipboard) - ImGui::LogFinish(); - if (ScrollToBottom) - ImGui::SetScrollHere(); - ScrollToBottom = false; - ImGui::PopStyleVar(); - ImGui::EndChild(); - ImGui::Separator(); + // Display every line as a separate entry so we can change their color or add custom widgets. If you only want raw text you can use ImGui::TextUnformatted(log.begin(), log.end()); + // NB- if you have thousands of entries this approach may be too inefficient and may require user-side clipping to only process visible items. + // You can seek and display only the lines that are visible using the ImGuiListClipper helper, if your elements are evenly spaced and you have cheap random access to the elements. + // To use the clipper we could replace the 'for (int i = 0; i < Items.Size; i++)' loop with: + // ImGuiListClipper clipper(Items.Size); + // while (clipper.Step()) + // for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) + // However take note that you can not use this code as is if a filter is active because it breaks the 'cheap random-access' property. We would need random-access on the post-filtered list. + // A typical application wanting coarse clipping and filtering may want to pre-compute an array of indices that passed the filtering test, recomputing this array when user changes the filter, + // and appending newly elements as they are inserted. This is left as a task to the user until we can manage to improve this example code! + // If your items are of variable size you may want to implement code similar to what ImGuiListClipper does. Or split your data into fixed height items to allow random-seeking into your list. + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(4, 1)); // Tighten spacing + if (copy_to_clipboard) + ImGui::LogToClipboard(); + ImVec4 col_default_text = ImGui::GetStyleColorVec4(ImGuiCol_Text); + for (int i = 0; i < Items.Size; i++) + { + const char* item = Items[i]; + if (!filter.PassFilter(item)) + continue; + ImVec4 col = col_default_text; + if (strstr(item, "[error]")) + col = ImColor(1.0f, 0.4f, 0.4f, 1.0f); + else if (strncmp(item, "# ", 2) == 0) + col = ImColor(1.0f, 0.78f, 0.58f, 1.0f); + ImGui::PushStyleColor(ImGuiCol_Text, col); + ImGui::TextUnformatted(item); + ImGui::PopStyleColor(); + } + if (copy_to_clipboard) + ImGui::LogFinish(); + if (ScrollToBottom) + ImGui::SetScrollHere(); + ScrollToBottom = false; + ImGui::PopStyleVar(); + ImGui::EndChild(); + ImGui::Separator(); - // Command-line - bool reclaim_focus = false; - if (ImGui::InputText("Input", InputBuf, IM_ARRAYSIZE(InputBuf), ImGuiInputTextFlags_EnterReturnsTrue|ImGuiInputTextFlags_CallbackCompletion|ImGuiInputTextFlags_CallbackHistory, &TextEditCallbackStub, (void*)this)) - { - char* input_end = InputBuf+strlen(InputBuf); - while (input_end > InputBuf && input_end[-1] == ' ') { input_end--; } *input_end = 0; - if (InputBuf[0]) - ExecCommand(InputBuf); - strcpy(InputBuf, ""); - reclaim_focus = true; - } + // Command-line + bool reclaim_focus = false; + if (ImGui::InputText("Input", InputBuf, IM_ARRAYSIZE(InputBuf), ImGuiInputTextFlags_EnterReturnsTrue | ImGuiInputTextFlags_CallbackCompletion | ImGuiInputTextFlags_CallbackHistory, &TextEditCallbackStub, (void*)this)) + { + char* input_end = InputBuf + strlen(InputBuf); + while (input_end > InputBuf && input_end[-1] == ' ') + { + input_end--; + } + *input_end = 0; + if (InputBuf[0]) + ExecCommand(InputBuf); + strcpy(InputBuf, ""); + reclaim_focus = true; + } - // Demonstrate keeping focus on the input box - ImGui::SetItemDefaultFocus(); - if (reclaim_focus) - ImGui::SetKeyboardFocusHere(-1); // Auto focus previous widget + // Demonstrate keeping focus on the input box + ImGui::SetItemDefaultFocus(); + if (reclaim_focus) + ImGui::SetKeyboardFocusHere(-1); // Auto focus previous widget - ImGui::End(); - } + ImGui::End(); + } - void ExecCommand(const char* command_line) - { - AddLog("# %s\n", command_line); + void ExecCommand(const char* command_line) + { + AddLog("# %s\n", command_line); - // Insert into history. First find match and delete it so it can be pushed to the back. This isn't trying to be smart or optimal. - HistoryPos = -1; - for (int i = History.Size-1; i >= 0; i--) - if (Stricmp(History[i], command_line) == 0) - { - free(History[i]); - History.erase(History.begin() + i); - break; - } - History.push_back(Strdup(command_line)); + // Insert into history. First find match and delete it so it can be pushed to the back. This isn't trying to be smart or optimal. + HistoryPos = -1; + for (int i = History.Size - 1; i >= 0; i--) + if (Stricmp(History[i], command_line) == 0) + { + free(History[i]); + History.erase(History.begin() + i); + break; + } + History.push_back(Strdup(command_line)); - // Process command - if (Stricmp(command_line, "CLEAR") == 0) - { - ClearLog(); - } - else if (Stricmp(command_line, "HELP") == 0) - { - AddLog("Commands:"); - for (int i = 0; i < Commands.Size; i++) - AddLog("- %s", Commands[i]); - } - else if (Stricmp(command_line, "HISTORY") == 0) - { - int first = History.Size - 10; - for (int i = first > 0 ? first : 0; i < History.Size; i++) - AddLog("%3d: %s\n", i, History[i]); - } - else - { - AddLog("Unknown command: '%s'\n", command_line); - } - } + // Process command + if (Stricmp(command_line, "CLEAR") == 0) + { + ClearLog(); + } + else if (Stricmp(command_line, "HELP") == 0) + { + AddLog("Commands:"); + for (int i = 0; i < Commands.Size; i++) + AddLog("- %s", Commands[i]); + } + else if (Stricmp(command_line, "HISTORY") == 0) + { + int first = History.Size - 10; + for (int i = first > 0 ? first : 0; i < History.Size; i++) + AddLog("%3d: %s\n", i, History[i]); + } + else + { + AddLog("Unknown command: '%s'\n", command_line); + } + } - static int TextEditCallbackStub(ImGuiTextEditCallbackData* data) // In C++11 you are better off using lambdas for this sort of forwarding callbacks - { - ExampleAppConsole* console = (ExampleAppConsole*)data->UserData; - return console->TextEditCallback(data); - } + static int TextEditCallbackStub(ImGuiTextEditCallbackData* data) // In C++11 you are better off using lambdas for this sort of forwarding callbacks + { + ExampleAppConsole* console = (ExampleAppConsole*)data->UserData; + return console->TextEditCallback(data); + } - int TextEditCallback(ImGuiTextEditCallbackData* data) - { - //AddLog("cursor: %d, selection: %d-%d", data->CursorPos, data->SelectionStart, data->SelectionEnd); - switch (data->EventFlag) - { - case ImGuiInputTextFlags_CallbackCompletion: - { - // Example of TEXT COMPLETION + int TextEditCallback(ImGuiTextEditCallbackData* data) + { + //AddLog("cursor: %d, selection: %d-%d", data->CursorPos, data->SelectionStart, data->SelectionEnd); + switch (data->EventFlag) + { + case ImGuiInputTextFlags_CallbackCompletion: + { + // Example of TEXT COMPLETION - // Locate beginning of current word - const char* word_end = data->Buf + data->CursorPos; - const char* word_start = word_end; - while (word_start > data->Buf) - { - const char c = word_start[-1]; - if (c == ' ' || c == '\t' || c == ',' || c == ';') - break; - word_start--; - } + // Locate beginning of current word + const char* word_end = data->Buf + data->CursorPos; + const char* word_start = word_end; + while (word_start > data->Buf) + { + const char c = word_start[-1]; + if (c == ' ' || c == '\t' || c == ',' || c == ';') + break; + word_start--; + } - // Build a list of candidates - ImVector candidates; - for (int i = 0; i < Commands.Size; i++) - if (Strnicmp(Commands[i], word_start, (int)(word_end-word_start)) == 0) - candidates.push_back(Commands[i]); + // Build a list of candidates + ImVector candidates; + for (int i = 0; i < Commands.Size; i++) + if (Strnicmp(Commands[i], word_start, (int)(word_end - word_start)) == 0) + candidates.push_back(Commands[i]); - if (candidates.Size == 0) - { - // No match - AddLog("No match for \"%.*s\"!\n", (int)(word_end-word_start), word_start); - } - else if (candidates.Size == 1) - { - // Single match. Delete the beginning of the word and replace it entirely so we've got nice casing - data->DeleteChars((int)(word_start-data->Buf), (int)(word_end-word_start)); - data->InsertChars(data->CursorPos, candidates[0]); - data->InsertChars(data->CursorPos, " "); - } - else - { - // Multiple matches. Complete as much as we can, so inputing "C" will complete to "CL" and display "CLEAR" and "CLASSIFY" - int match_len = (int)(word_end - word_start); - for (;;) - { - int c = 0; - bool all_candidates_matches = true; - for (int i = 0; i < candidates.Size && all_candidates_matches; i++) - if (i == 0) - c = toupper(candidates[i][match_len]); - else if (c == 0 || c != toupper(candidates[i][match_len])) - all_candidates_matches = false; - if (!all_candidates_matches) - break; - match_len++; - } + if (candidates.Size == 0) + { + // No match + AddLog("No match for \"%.*s\"!\n", (int)(word_end - word_start), word_start); + } + else if (candidates.Size == 1) + { + // Single match. Delete the beginning of the word and replace it entirely so we've got nice casing + data->DeleteChars((int)(word_start - data->Buf), (int)(word_end - word_start)); + data->InsertChars(data->CursorPos, candidates[0]); + data->InsertChars(data->CursorPos, " "); + } + else + { + // Multiple matches. Complete as much as we can, so inputing "C" will complete to "CL" and display "CLEAR" and "CLASSIFY" + int match_len = (int)(word_end - word_start); + for (;;) + { + int c = 0; + bool all_candidates_matches = true; + for (int i = 0; i < candidates.Size && all_candidates_matches; i++) + if (i == 0) + c = toupper(candidates[i][match_len]); + else if (c == 0 || c != toupper(candidates[i][match_len])) + all_candidates_matches = false; + if (!all_candidates_matches) + break; + match_len++; + } - if (match_len > 0) - { - data->DeleteChars((int)(word_start - data->Buf), (int)(word_end-word_start)); - data->InsertChars(data->CursorPos, candidates[0], candidates[0] + match_len); - } + if (match_len > 0) + { + data->DeleteChars((int)(word_start - data->Buf), (int)(word_end - word_start)); + data->InsertChars(data->CursorPos, candidates[0], candidates[0] + match_len); + } - // List matches - AddLog("Possible matches:\n"); - for (int i = 0; i < candidates.Size; i++) - AddLog("- %s\n", candidates[i]); - } + // List matches + AddLog("Possible matches:\n"); + for (int i = 0; i < candidates.Size; i++) + AddLog("- %s\n", candidates[i]); + } - break; - } - case ImGuiInputTextFlags_CallbackHistory: - { - // Example of HISTORY - const int prev_history_pos = HistoryPos; - if (data->EventKey == ImGuiKey_UpArrow) - { - if (HistoryPos == -1) - HistoryPos = History.Size - 1; - else if (HistoryPos > 0) - HistoryPos--; - } - else if (data->EventKey == ImGuiKey_DownArrow) - { - if (HistoryPos != -1) - if (++HistoryPos >= History.Size) - HistoryPos = -1; - } + break; + } + case ImGuiInputTextFlags_CallbackHistory: + { + // Example of HISTORY + const int prev_history_pos = HistoryPos; + if (data->EventKey == ImGuiKey_UpArrow) + { + if (HistoryPos == -1) + HistoryPos = History.Size - 1; + else if (HistoryPos > 0) + HistoryPos--; + } + else if (data->EventKey == ImGuiKey_DownArrow) + { + if (HistoryPos != -1) + if (++HistoryPos >= History.Size) + HistoryPos = -1; + } - // A better implementation would preserve the data on the current input line along with cursor position. - if (prev_history_pos != HistoryPos) - { - data->CursorPos = data->SelectionStart = data->SelectionEnd = data->BufTextLen = (int)snprintf(data->Buf, (size_t)data->BufSize, "%s", (HistoryPos >= 0) ? History[HistoryPos] : ""); - data->BufDirty = true; - } - } - } - return 0; - } + // A better implementation would preserve the data on the current input line along with cursor position. + if (prev_history_pos != HistoryPos) + { + data->CursorPos = data->SelectionStart = data->SelectionEnd = data->BufTextLen = (int)snprintf(data->Buf, (size_t)data->BufSize, "%s", (HistoryPos >= 0) ? History[HistoryPos] : ""); + data->BufDirty = true; + } + } + } + return 0; + } }; static void ShowExampleAppConsole(bool* p_open) { - static ExampleAppConsole console; - console.Draw("Example: Console", p_open); + static ExampleAppConsole console; + console.Draw("Example: Console", p_open); } // Usage: @@ -2893,251 +3278,263 @@ static void ShowExampleAppConsole(bool* p_open) // my_log.Draw("title"); struct ExampleAppLog { - ImGuiTextBuffer Buf; - ImGuiTextFilter Filter; - ImVector LineOffsets; // Index to lines offset - bool ScrollToBottom; + ImGuiTextBuffer Buf; + ImGuiTextFilter Filter; + ImVector LineOffsets; // Index to lines offset + bool ScrollToBottom; - void Clear() { Buf.clear(); LineOffsets.clear(); } + void Clear() + { + Buf.clear(); + LineOffsets.clear(); + } - void AddLog(const char* fmt, ...) IM_FMTARGS(2) - { - int old_size = Buf.size(); - va_list args; - va_start(args, fmt); - Buf.appendfv(fmt, args); - va_end(args); - for (int new_size = Buf.size(); old_size < new_size; old_size++) - if (Buf[old_size] == '\n') - LineOffsets.push_back(old_size); - ScrollToBottom = true; - } + void AddLog(const char* fmt, ...) IM_FMTARGS(2) + { + int old_size = Buf.size(); + va_list args; + va_start(args, fmt); + Buf.appendfv(fmt, args); + va_end(args); + for (int new_size = Buf.size(); old_size < new_size; old_size++) + if (Buf[old_size] == '\n') + LineOffsets.push_back(old_size); + ScrollToBottom = true; + } - void Draw(const char* title, bool* p_open = NULL) - { - ImGui::SetNextWindowSize(ImVec2(500,400), ImGuiCond_FirstUseEver); - ImGui::Begin(title, p_open); - if (ImGui::Button("Clear")) Clear(); - ImGui::SameLine(); - bool copy = ImGui::Button("Copy"); - ImGui::SameLine(); - Filter.Draw("Filter", -100.0f); - ImGui::Separator(); - ImGui::BeginChild("scrolling", ImVec2(0,0), false, ImGuiWindowFlags_HorizontalScrollbar); - if (copy) ImGui::LogToClipboard(); + void Draw(const char* title, bool* p_open = NULL) + { + ImGui::SetNextWindowSize(ImVec2(500, 400), ImGuiCond_FirstUseEver); + ImGui::Begin(title, p_open); + if (ImGui::Button("Clear")) Clear(); + ImGui::SameLine(); + bool copy = ImGui::Button("Copy"); + ImGui::SameLine(); + Filter.Draw("Filter", -100.0f); + ImGui::Separator(); + ImGui::BeginChild("scrolling", ImVec2(0, 0), false, ImGuiWindowFlags_HorizontalScrollbar); + if (copy) ImGui::LogToClipboard(); - if (Filter.IsActive()) - { - const char* buf_begin = Buf.begin(); - const char* line = buf_begin; - for (int line_no = 0; line != NULL; line_no++) - { - const char* line_end = (line_no < LineOffsets.Size) ? buf_begin + LineOffsets[line_no] : NULL; - if (Filter.PassFilter(line, line_end)) - ImGui::TextUnformatted(line, line_end); - line = line_end && line_end[1] ? line_end + 1 : NULL; - } - } - else - { - ImGui::TextUnformatted(Buf.begin()); - } + if (Filter.IsActive()) + { + const char* buf_begin = Buf.begin(); + const char* line = buf_begin; + for (int line_no = 0; line != NULL; line_no++) + { + const char* line_end = (line_no < LineOffsets.Size) ? buf_begin + LineOffsets[line_no] : NULL; + if (Filter.PassFilter(line, line_end)) + ImGui::TextUnformatted(line, line_end); + line = line_end && line_end[1] ? line_end + 1 : NULL; + } + } + else + { + ImGui::TextUnformatted(Buf.begin()); + } - if (ScrollToBottom) - ImGui::SetScrollHere(1.0f); - ScrollToBottom = false; - ImGui::EndChild(); - ImGui::End(); - } + if (ScrollToBottom) + ImGui::SetScrollHere(1.0f); + ScrollToBottom = false; + ImGui::EndChild(); + ImGui::End(); + } }; // Demonstrate creating a simple log window with basic filtering. static void ShowExampleAppLog(bool* p_open) { - static ExampleAppLog log; + static ExampleAppLog log; - // Demo: add random items (unless Ctrl is held) - static float last_time = -1.0f; - float time = ImGui::GetTime(); - if (time - last_time >= 0.20f && !ImGui::GetIO().KeyCtrl) - { - const char* random_words[] = { "system", "info", "warning", "error", "fatal", "notice", "log" }; - log.AddLog("[%s] Hello, time is %.1f, frame count is %d\n", random_words[rand() % IM_ARRAYSIZE(random_words)], time, ImGui::GetFrameCount()); - last_time = time; - } + // Demo: add random items (unless Ctrl is held) + static float last_time = -1.0f; + float time = ImGui::GetTime(); + if (time - last_time >= 0.20f && !ImGui::GetIO().KeyCtrl) + { + const char* random_words[] = {"system", "info", "warning", "error", "fatal", "notice", "log"}; + log.AddLog("[%s] Hello, time is %.1f, frame count is %d\n", random_words[rand() % IM_ARRAYSIZE(random_words)], time, ImGui::GetFrameCount()); + last_time = time; + } - log.Draw("Example: Log", p_open); + log.Draw("Example: Log", p_open); } // Demonstrate create a window with multiple child windows. static void ShowExampleAppLayout(bool* p_open) { - ImGui::SetNextWindowSize(ImVec2(500, 440), ImGuiCond_FirstUseEver); - if (ImGui::Begin("Example: Layout", p_open, ImGuiWindowFlags_MenuBar)) - { - if (ImGui::BeginMenuBar()) - { - if (ImGui::BeginMenu("File")) - { - if (ImGui::MenuItem("Close")) *p_open = false; - ImGui::EndMenu(); - } - ImGui::EndMenuBar(); - } + ImGui::SetNextWindowSize(ImVec2(500, 440), ImGuiCond_FirstUseEver); + if (ImGui::Begin("Example: Layout", p_open, ImGuiWindowFlags_MenuBar)) + { + if (ImGui::BeginMenuBar()) + { + if (ImGui::BeginMenu("File")) + { + if (ImGui::MenuItem("Close")) *p_open = false; + ImGui::EndMenu(); + } + ImGui::EndMenuBar(); + } - // left - static int selected = 0; - ImGui::BeginChild("left pane", ImVec2(150, 0), true); - for (int i = 0; i < 100; i++) - { - char label[128]; - sprintf(label, "MyObject %d", i); - if (ImGui::Selectable(label, selected == i)) - selected = i; - } - ImGui::EndChild(); - ImGui::SameLine(); + // left + static int selected = 0; + ImGui::BeginChild("left pane", ImVec2(150, 0), true); + for (int i = 0; i < 100; i++) + { + char label[128]; + sprintf(label, "MyObject %d", i); + if (ImGui::Selectable(label, selected == i)) + selected = i; + } + ImGui::EndChild(); + ImGui::SameLine(); - // right - ImGui::BeginGroup(); - ImGui::BeginChild("item view", ImVec2(0, -ImGui::GetFrameHeightWithSpacing())); // Leave room for 1 line below us - ImGui::Text("MyObject: %d", selected); - ImGui::Separator(); - ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "); - ImGui::EndChild(); - if (ImGui::Button("Revert")) {} - ImGui::SameLine(); - if (ImGui::Button("Save")) {} - ImGui::EndGroup(); - } - ImGui::End(); + // right + ImGui::BeginGroup(); + ImGui::BeginChild("item view", ImVec2(0, -ImGui::GetFrameHeightWithSpacing())); // Leave room for 1 line below us + ImGui::Text("MyObject: %d", selected); + ImGui::Separator(); + ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. "); + ImGui::EndChild(); + if (ImGui::Button("Revert")) + { + } + ImGui::SameLine(); + if (ImGui::Button("Save")) + { + } + ImGui::EndGroup(); + } + ImGui::End(); } // Demonstrate create a simple property editor. static void ShowExampleAppPropertyEditor(bool* p_open) { - ImGui::SetNextWindowSize(ImVec2(430,450), ImGuiCond_FirstUseEver); - if (!ImGui::Begin("Example: Property editor", p_open)) - { - ImGui::End(); - return; - } + ImGui::SetNextWindowSize(ImVec2(430, 450), ImGuiCond_FirstUseEver); + if (!ImGui::Begin("Example: Property editor", p_open)) + { + ImGui::End(); + return; + } - ShowHelpMarker("This example shows how you may implement a property editor using two columns.\nAll objects/fields data are dummies here.\nRemember that in many simple cases, you can use ImGui::SameLine(xxx) to position\nyour cursor horizontally instead of using the Columns() API."); + ShowHelpMarker("This example shows how you may implement a property editor using two columns.\nAll objects/fields data are dummies here.\nRemember that in many simple cases, you can use ImGui::SameLine(xxx) to position\nyour cursor horizontally instead of using the Columns() API."); - ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2,2)); - ImGui::Columns(2); - ImGui::Separator(); + ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2(2, 2)); + ImGui::Columns(2); + ImGui::Separator(); - struct funcs - { - static void ShowDummyObject(const char* prefix, int uid) - { - ImGui::PushID(uid); // Use object uid as identifier. Most commonly you could also use the object pointer as a base ID. - ImGui::AlignTextToFramePadding(); // Text and Tree nodes are less high than regular widgets, here we add vertical spacing to make the tree lines equal high. - bool node_open = ImGui::TreeNode("Object", "%s_%u", prefix, uid); - ImGui::NextColumn(); - ImGui::AlignTextToFramePadding(); - ImGui::Text("my sailor is rich"); - ImGui::NextColumn(); - if (node_open) - { - static float dummy_members[8] = { 0.0f,0.0f,1.0f,3.1416f,100.0f,999.0f }; - for (int i = 0; i < 8; i++) - { - ImGui::PushID(i); // Use field index as identifier. - if (i < 2) - { - ShowDummyObject("Child", 424242); - } - else - { - ImGui::AlignTextToFramePadding(); - // Here we use a Selectable (instead of Text) to highlight on hover - //ImGui::Text("Field_%d", i); - char label[32]; - sprintf(label, "Field_%d", i); - ImGui::Bullet(); - ImGui::Selectable(label); - ImGui::NextColumn(); - ImGui::PushItemWidth(-1); - if (i >= 5) - ImGui::InputFloat("##value", &dummy_members[i], 1.0f); - else - ImGui::DragFloat("##value", &dummy_members[i], 0.01f); - ImGui::PopItemWidth(); - ImGui::NextColumn(); - } - ImGui::PopID(); - } - ImGui::TreePop(); - } - ImGui::PopID(); - } - }; + struct funcs + { + static void ShowDummyObject(const char* prefix, int uid) + { + ImGui::PushID(uid); // Use object uid as identifier. Most commonly you could also use the object pointer as a base ID. + ImGui::AlignTextToFramePadding(); // Text and Tree nodes are less high than regular widgets, here we add vertical spacing to make the tree lines equal high. + bool node_open = ImGui::TreeNode("Object", "%s_%u", prefix, uid); + ImGui::NextColumn(); + ImGui::AlignTextToFramePadding(); + ImGui::Text("my sailor is rich"); + ImGui::NextColumn(); + if (node_open) + { + static float dummy_members[8] = {0.0f, 0.0f, 1.0f, 3.1416f, 100.0f, 999.0f}; + for (int i = 0; i < 8; i++) + { + ImGui::PushID(i); // Use field index as identifier. + if (i < 2) + { + ShowDummyObject("Child", 424242); + } + else + { + ImGui::AlignTextToFramePadding(); + // Here we use a Selectable (instead of Text) to highlight on hover + //ImGui::Text("Field_%d", i); + char label[32]; + sprintf(label, "Field_%d", i); + ImGui::Bullet(); + ImGui::Selectable(label); + ImGui::NextColumn(); + ImGui::PushItemWidth(-1); + if (i >= 5) + ImGui::InputFloat("##value", &dummy_members[i], 1.0f); + else + ImGui::DragFloat("##value", &dummy_members[i], 0.01f); + ImGui::PopItemWidth(); + ImGui::NextColumn(); + } + ImGui::PopID(); + } + ImGui::TreePop(); + } + ImGui::PopID(); + } + }; - // Iterate dummy objects with dummy members (all the same data) - for (int obj_i = 0; obj_i < 3; obj_i++) - funcs::ShowDummyObject("Object", obj_i); + // Iterate dummy objects with dummy members (all the same data) + for (int obj_i = 0; obj_i < 3; obj_i++) + funcs::ShowDummyObject("Object", obj_i); - ImGui::Columns(1); - ImGui::Separator(); - ImGui::PopStyleVar(); - ImGui::End(); + ImGui::Columns(1); + ImGui::Separator(); + ImGui::PopStyleVar(); + ImGui::End(); } // Demonstrate/test rendering huge amount of text, and the incidence of clipping. static void ShowExampleAppLongText(bool* p_open) { - ImGui::SetNextWindowSize(ImVec2(520,600), ImGuiCond_FirstUseEver); - if (!ImGui::Begin("Example: Long text display", p_open)) - { - ImGui::End(); - return; - } + ImGui::SetNextWindowSize(ImVec2(520, 600), ImGuiCond_FirstUseEver); + if (!ImGui::Begin("Example: Long text display", p_open)) + { + ImGui::End(); + return; + } - static int test_type = 0; - static ImGuiTextBuffer log; - static int lines = 0; - ImGui::Text("Printing unusually long amount of text."); - ImGui::Combo("Test type", &test_type, "Single call to TextUnformatted()\0Multiple calls to Text(), clipped manually\0Multiple calls to Text(), not clipped (slow)\0"); - ImGui::Text("Buffer contents: %d lines, %d bytes", lines, log.size()); - if (ImGui::Button("Clear")) { log.clear(); lines = 0; } - ImGui::SameLine(); - if (ImGui::Button("Add 1000 lines")) - { - for (int i = 0; i < 1000; i++) - log.appendf("%i The quick brown fox jumps over the lazy dog\n", lines+i); - lines += 1000; - } - ImGui::BeginChild("Log"); - switch (test_type) - { - case 0: - // Single call to TextUnformatted() with a big buffer - ImGui::TextUnformatted(log.begin(), log.end()); - break; - case 1: - { - // Multiple calls to Text(), manually coarsely clipped - demonstrate how to use the ImGuiListClipper helper. - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0)); - ImGuiListClipper clipper(lines); - while (clipper.Step()) - for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) - ImGui::Text("%i The quick brown fox jumps over the lazy dog", i); - ImGui::PopStyleVar(); - break; - } - case 2: - // Multiple calls to Text(), not clipped (slow) - ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0,0)); - for (int i = 0; i < lines; i++) - ImGui::Text("%i The quick brown fox jumps over the lazy dog", i); - ImGui::PopStyleVar(); - break; - } - ImGui::EndChild(); - ImGui::End(); + static int test_type = 0; + static ImGuiTextBuffer log; + static int lines = 0; + ImGui::Text("Printing unusually long amount of text."); + ImGui::Combo("Test type", &test_type, "Single call to TextUnformatted()\0Multiple calls to Text(), clipped manually\0Multiple calls to Text(), not clipped (slow)\0"); + ImGui::Text("Buffer contents: %d lines, %d bytes", lines, log.size()); + if (ImGui::Button("Clear")) + { + log.clear(); + lines = 0; + } + ImGui::SameLine(); + if (ImGui::Button("Add 1000 lines")) + { + for (int i = 0; i < 1000; i++) + log.appendf("%i The quick brown fox jumps over the lazy dog\n", lines + i); + lines += 1000; + } + ImGui::BeginChild("Log"); + switch (test_type) + { + case 0: + // Single call to TextUnformatted() with a big buffer + ImGui::TextUnformatted(log.begin(), log.end()); + break; + case 1: + { + // Multiple calls to Text(), manually coarsely clipped - demonstrate how to use the ImGuiListClipper helper. + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); + ImGuiListClipper clipper(lines); + while (clipper.Step()) + for (int i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) + ImGui::Text("%i The quick brown fox jumps over the lazy dog", i); + ImGui::PopStyleVar(); + break; + } + case 2: + // Multiple calls to Text(), not clipped (slow) + ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0, 0)); + for (int i = 0; i < lines; i++) + ImGui::Text("%i The quick brown fox jumps over the lazy dog", i); + ImGui::PopStyleVar(); + break; + } + ImGui::EndChild(); + ImGui::End(); } // End of Demo code diff --git a/examples/ThirdPartyLibs/imgui/imgui_draw.cpp b/examples/ThirdPartyLibs/imgui/imgui_draw.cpp index 7a38af8bb..948efd21a 100644 --- a/examples/ThirdPartyLibs/imgui/imgui_draw.cpp +++ b/examples/ThirdPartyLibs/imgui/imgui_draw.cpp @@ -17,45 +17,45 @@ #define IMGUI_DEFINE_MATH_OPERATORS #include "imgui_internal.h" -#include // vsnprintf, sscanf, printf +#include // vsnprintf, sscanf, printf #if !defined(alloca) #ifdef _WIN32 -#include // alloca +#include // alloca #if !defined(alloca) #define alloca _alloca // for clang with MS Codegen #endif #elif defined(__GLIBC__) || defined(__sun) -#include // alloca +#include // alloca #else -#include // alloca +#include // alloca #endif #endif #ifdef _MSC_VER -#pragma warning (disable: 4505) // unreferenced local function has been removed (stb stuff) -#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen +#pragma warning(disable : 4505) // unreferenced local function has been removed (stb stuff) +#pragma warning(disable : 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen #define snprintf _snprintf #endif #ifdef __clang__ -#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse. -#pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants ok. -#pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference it. -#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // +#pragma clang diagnostic ignored "-Wold-style-cast" // warning : use of old-style cast // yes, they are more terse. +#pragma clang diagnostic ignored "-Wfloat-equal" // warning : comparing floating point with == or != is unsafe // storing and comparing against same constants ok. +#pragma clang diagnostic ignored "-Wglobal-constructors" // warning : declaration requires a global destructor // similar to above, not sure what the exact difference it. +#pragma clang diagnostic ignored "-Wsign-conversion" // warning : implicit conversion changes signedness // #if __has_warning("-Wcomma") -#pragma clang diagnostic ignored "-Wcomma" // warning : possible misuse of comma operator here // +#pragma clang diagnostic ignored "-Wcomma" // warning : possible misuse of comma operator here // #endif #if __has_warning("-Wreserved-id-macro") -#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning : macro name is a reserved identifier // +#pragma clang diagnostic ignored "-Wreserved-id-macro" // warning : macro name is a reserved identifier // #endif #if __has_warning("-Wdouble-promotion") -#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function +#pragma clang diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function #endif #elif defined(__GNUC__) -#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used -#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function -#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value -#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'xxxx' to type 'xxxx' casts away qualifiers +#pragma GCC diagnostic ignored "-Wunused-function" // warning: 'xxxx' defined but not used +#pragma GCC diagnostic ignored "-Wdouble-promotion" // warning: implicit conversion from 'float' to 'double' when passing argument to function +#pragma GCC diagnostic ignored "-Wconversion" // warning: conversion to 'xxxx' from 'xxxx' may alter its value +#pragma GCC diagnostic ignored "-Wcast-qual" // warning: cast from type 'xxxx' to type 'xxxx' casts away qualifiers #endif //------------------------------------------------------------------------- @@ -72,8 +72,8 @@ namespace IMGUI_STB_NAMESPACE #endif #ifdef _MSC_VER -#pragma warning (push) -#pragma warning (disable: 4456) // declaration of 'xx' hides previous local declaration +#pragma warning(push) +#pragma warning(disable : 4456) // declaration of 'xx' hides previous local declaration #endif #ifdef __clang__ @@ -85,19 +85,19 @@ namespace IMGUI_STB_NAMESPACE #ifdef __GNUC__ #pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wtype-limits" // warning: comparison is always true due to limited range of data type [-Wtype-limits] +#pragma GCC diagnostic ignored "-Wtype-limits" // warning: comparison is always true due to limited range of data type [-Wtype-limits] #endif -#define STBRP_ASSERT(x) IM_ASSERT(x) +#define STBRP_ASSERT(x) IM_ASSERT(x) #ifndef IMGUI_DISABLE_STB_RECT_PACK_IMPLEMENTATION #define STBRP_STATIC #define STB_RECT_PACK_IMPLEMENTATION #endif #include "stb_rect_pack.h" -#define STBTT_malloc(x,u) ((void)(u), ImGui::MemAlloc(x)) -#define STBTT_free(x,u) ((void)(u), ImGui::MemFree(x)) -#define STBTT_assert(x) IM_ASSERT(x) +#define STBTT_malloc(x, u) ((void)(u), ImGui::MemAlloc(x)) +#define STBTT_free(x, u) ((void)(u), ImGui::MemFree(x)) +#define STBTT_assert(x) IM_ASSERT(x) #ifndef IMGUI_DISABLE_STB_TRUETYPE_IMPLEMENTATION #define STBTT_STATIC #define STB_TRUETYPE_IMPLEMENTATION @@ -115,11 +115,11 @@ namespace IMGUI_STB_NAMESPACE #endif #ifdef _MSC_VER -#pragma warning (pop) +#pragma warning(pop) #endif #ifdef IMGUI_STB_NAMESPACE -} // namespace ImGuiStb +} // namespace ImGuiStb using namespace IMGUI_STB_NAMESPACE; #endif @@ -129,161 +129,161 @@ using namespace IMGUI_STB_NAMESPACE; void ImGui::StyleColorsDark(ImGuiStyle* dst) { - ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); - ImVec4* colors = style->Colors; + ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); + ImVec4* colors = style->Colors; - colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); - colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); - colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.06f, 0.06f, 0.94f); - colors[ImGuiCol_ChildBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.00f); - colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f); - colors[ImGuiCol_Border] = ImVec4(0.43f, 0.43f, 0.50f, 0.50f); - colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_FrameBg] = ImVec4(0.16f, 0.29f, 0.48f, 0.54f); - colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); - colors[ImGuiCol_FrameBgActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); - colors[ImGuiCol_TitleBg] = ImVec4(0.04f, 0.04f, 0.04f, 1.00f); - colors[ImGuiCol_TitleBgActive] = ImVec4(0.16f, 0.29f, 0.48f, 1.00f); - colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f); - colors[ImGuiCol_MenuBarBg] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f); - colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.53f); - colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.31f, 0.31f, 0.31f, 1.00f); - colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f); - colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.51f, 0.51f, 0.51f, 1.00f); - colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); - colors[ImGuiCol_SliderGrab] = ImVec4(0.24f, 0.52f, 0.88f, 1.00f); - colors[ImGuiCol_SliderGrabActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); - colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); - colors[ImGuiCol_ButtonHovered] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); - colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f); - colors[ImGuiCol_Header] = ImVec4(0.26f, 0.59f, 0.98f, 0.31f); - colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); - colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); - colors[ImGuiCol_Separator] = colors[ImGuiCol_Border]; - colors[ImGuiCol_SeparatorHovered] = ImVec4(0.10f, 0.40f, 0.75f, 0.78f); - colors[ImGuiCol_SeparatorActive] = ImVec4(0.10f, 0.40f, 0.75f, 1.00f); - colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.25f); - colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); - colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); - colors[ImGuiCol_CloseButton] = ImVec4(0.41f, 0.41f, 0.41f, 0.50f); - colors[ImGuiCol_CloseButtonHovered] = ImVec4(0.98f, 0.39f, 0.36f, 1.00f); - colors[ImGuiCol_CloseButtonActive] = ImVec4(0.98f, 0.39f, 0.36f, 1.00f); - colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); - colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); - colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); - colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); - colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); - colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f); - colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); - colors[ImGuiCol_NavHighlight] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); - colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); + colors[ImGuiCol_Text] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); + colors[ImGuiCol_WindowBg] = ImVec4(0.06f, 0.06f, 0.06f, 0.94f); + colors[ImGuiCol_ChildBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.00f); + colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f); + colors[ImGuiCol_Border] = ImVec4(0.43f, 0.43f, 0.50f, 0.50f); + colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_FrameBg] = ImVec4(0.16f, 0.29f, 0.48f, 0.54f); + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + colors[ImGuiCol_TitleBg] = ImVec4(0.04f, 0.04f, 0.04f, 1.00f); + colors[ImGuiCol_TitleBgActive] = ImVec4(0.16f, 0.29f, 0.48f, 1.00f); + colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f); + colors[ImGuiCol_MenuBarBg] = ImVec4(0.14f, 0.14f, 0.14f, 1.00f); + colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.53f); + colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.31f, 0.31f, 0.31f, 1.00f); + colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.41f, 0.41f, 0.41f, 1.00f); + colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.51f, 0.51f, 0.51f, 1.00f); + colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_SliderGrab] = ImVec4(0.24f, 0.52f, 0.88f, 1.00f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f); + colors[ImGuiCol_Header] = ImVec4(0.26f, 0.59f, 0.98f, 0.31f); + colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); + colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_Separator] = colors[ImGuiCol_Border]; + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.10f, 0.40f, 0.75f, 0.78f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.10f, 0.40f, 0.75f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.25f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); + colors[ImGuiCol_CloseButton] = ImVec4(0.41f, 0.41f, 0.41f, 0.50f); + colors[ImGuiCol_CloseButtonHovered] = ImVec4(0.98f, 0.39f, 0.36f, 1.00f); + colors[ImGuiCol_CloseButtonActive] = ImVec4(0.98f, 0.39f, 0.36f, 1.00f); + colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); + colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); + colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f); + colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); + colors[ImGuiCol_NavHighlight] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); } void ImGui::StyleColorsClassic(ImGuiStyle* dst) { - ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); - ImVec4* colors = style->Colors; + ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); + ImVec4* colors = style->Colors; - colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); - colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); - colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.70f); - colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_PopupBg] = ImVec4(0.11f, 0.11f, 0.14f, 0.92f); - colors[ImGuiCol_Border] = ImVec4(0.50f, 0.50f, 0.50f, 0.50f); - colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_FrameBg] = ImVec4(0.43f, 0.43f, 0.43f, 0.39f); - colors[ImGuiCol_FrameBgHovered] = ImVec4(0.47f, 0.47f, 0.69f, 0.40f); - colors[ImGuiCol_FrameBgActive] = ImVec4(0.42f, 0.41f, 0.64f, 0.69f); - colors[ImGuiCol_TitleBg] = ImVec4(0.27f, 0.27f, 0.54f, 0.83f); - colors[ImGuiCol_TitleBgActive] = ImVec4(0.32f, 0.32f, 0.63f, 0.87f); - colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.40f, 0.40f, 0.80f, 0.20f); - colors[ImGuiCol_MenuBarBg] = ImVec4(0.40f, 0.40f, 0.55f, 0.80f); - colors[ImGuiCol_ScrollbarBg] = ImVec4(0.20f, 0.25f, 0.30f, 0.60f); - colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.40f, 0.40f, 0.80f, 0.30f); - colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.80f, 0.40f); - colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.41f, 0.39f, 0.80f, 0.60f); - colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f); - colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); - colors[ImGuiCol_SliderGrabActive] = ImVec4(0.41f, 0.39f, 0.80f, 0.60f); - colors[ImGuiCol_Button] = ImVec4(0.35f, 0.40f, 0.61f, 0.62f); - colors[ImGuiCol_ButtonHovered] = ImVec4(0.40f, 0.48f, 0.71f, 0.79f); - colors[ImGuiCol_ButtonActive] = ImVec4(0.46f, 0.54f, 0.80f, 1.00f); - colors[ImGuiCol_Header] = ImVec4(0.40f, 0.40f, 0.90f, 0.45f); - colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.90f, 0.80f); - colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.87f, 0.80f); - colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); - colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f); - colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f); - colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.16f); - colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.78f, 0.82f, 1.00f, 0.60f); - colors[ImGuiCol_ResizeGripActive] = ImVec4(0.78f, 0.82f, 1.00f, 0.90f); - colors[ImGuiCol_CloseButton] = ImVec4(0.50f, 0.50f, 0.90f, 0.50f); - colors[ImGuiCol_CloseButtonHovered] = ImVec4(0.70f, 0.70f, 0.90f, 0.60f); - colors[ImGuiCol_CloseButtonActive] = ImVec4(0.70f, 0.70f, 0.70f, 1.00f); - colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); - colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); - colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); - colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); - colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f); - colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); - colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); - colors[ImGuiCol_NavHighlight] = colors[ImGuiCol_HeaderHovered]; - colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); + colors[ImGuiCol_Text] = ImVec4(0.90f, 0.90f, 0.90f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); + colors[ImGuiCol_WindowBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.70f); + colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_PopupBg] = ImVec4(0.11f, 0.11f, 0.14f, 0.92f); + colors[ImGuiCol_Border] = ImVec4(0.50f, 0.50f, 0.50f, 0.50f); + colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_FrameBg] = ImVec4(0.43f, 0.43f, 0.43f, 0.39f); + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.47f, 0.47f, 0.69f, 0.40f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.42f, 0.41f, 0.64f, 0.69f); + colors[ImGuiCol_TitleBg] = ImVec4(0.27f, 0.27f, 0.54f, 0.83f); + colors[ImGuiCol_TitleBgActive] = ImVec4(0.32f, 0.32f, 0.63f, 0.87f); + colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.40f, 0.40f, 0.80f, 0.20f); + colors[ImGuiCol_MenuBarBg] = ImVec4(0.40f, 0.40f, 0.55f, 0.80f); + colors[ImGuiCol_ScrollbarBg] = ImVec4(0.20f, 0.25f, 0.30f, 0.60f); + colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.40f, 0.40f, 0.80f, 0.30f); + colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.40f, 0.40f, 0.80f, 0.40f); + colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.41f, 0.39f, 0.80f, 0.60f); + colors[ImGuiCol_CheckMark] = ImVec4(0.90f, 0.90f, 0.90f, 0.50f); + colors[ImGuiCol_SliderGrab] = ImVec4(1.00f, 1.00f, 1.00f, 0.30f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(0.41f, 0.39f, 0.80f, 0.60f); + colors[ImGuiCol_Button] = ImVec4(0.35f, 0.40f, 0.61f, 0.62f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.40f, 0.48f, 0.71f, 0.79f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.46f, 0.54f, 0.80f, 1.00f); + colors[ImGuiCol_Header] = ImVec4(0.40f, 0.40f, 0.90f, 0.45f); + colors[ImGuiCol_HeaderHovered] = ImVec4(0.45f, 0.45f, 0.90f, 0.80f); + colors[ImGuiCol_HeaderActive] = ImVec4(0.53f, 0.53f, 0.87f, 0.80f); + colors[ImGuiCol_Separator] = ImVec4(0.50f, 0.50f, 0.50f, 1.00f); + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.60f, 0.60f, 0.70f, 1.00f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.70f, 0.70f, 0.90f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(1.00f, 1.00f, 1.00f, 0.16f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.78f, 0.82f, 1.00f, 0.60f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(0.78f, 0.82f, 1.00f, 0.90f); + colors[ImGuiCol_CloseButton] = ImVec4(0.50f, 0.50f, 0.90f, 0.50f); + colors[ImGuiCol_CloseButtonHovered] = ImVec4(0.70f, 0.70f, 0.90f, 0.60f); + colors[ImGuiCol_CloseButtonActive] = ImVec4(0.70f, 0.70f, 0.70f, 1.00f); + colors[ImGuiCol_PlotLines] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.60f, 0.00f, 1.00f); + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.00f, 0.00f, 1.00f, 0.35f); + colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); + colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f); + colors[ImGuiCol_NavHighlight] = colors[ImGuiCol_HeaderHovered]; + colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f); } // Those light colors are better suited with a thicker font than the default one + FrameBorder void ImGui::StyleColorsLight(ImGuiStyle* dst) { - ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); - ImVec4* colors = style->Colors; + ImGuiStyle* style = dst ? dst : &ImGui::GetStyle(); + ImVec4* colors = style->Colors; - colors[ImGuiCol_Text] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); - colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); - //colors[ImGuiCol_TextHovered] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); - //colors[ImGuiCol_TextActive] = ImVec4(1.00f, 1.00f, 0.00f, 1.00f); - colors[ImGuiCol_WindowBg] = ImVec4(0.94f, 0.94f, 0.94f, 1.00f); - colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_PopupBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.98f); - colors[ImGuiCol_Border] = ImVec4(0.00f, 0.00f, 0.00f, 0.30f); - colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); - colors[ImGuiCol_FrameBg] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); - colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); - colors[ImGuiCol_FrameBgActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); - colors[ImGuiCol_TitleBg] = ImVec4(0.96f, 0.96f, 0.96f, 1.00f); - colors[ImGuiCol_TitleBgActive] = ImVec4(0.82f, 0.82f, 0.82f, 1.00f); - colors[ImGuiCol_TitleBgCollapsed] = ImVec4(1.00f, 1.00f, 1.00f, 0.51f); - colors[ImGuiCol_MenuBarBg] = ImVec4(0.86f, 0.86f, 0.86f, 1.00f); - colors[ImGuiCol_ScrollbarBg] = ImVec4(0.98f, 0.98f, 0.98f, 0.53f); - colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.69f, 0.69f, 0.69f, 0.80f); - colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.49f, 0.49f, 0.49f, 0.80f); - colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.49f, 0.49f, 0.49f, 1.00f); - colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); - colors[ImGuiCol_SliderGrab] = ImVec4(0.26f, 0.59f, 0.98f, 0.78f); - colors[ImGuiCol_SliderGrabActive] = ImVec4(0.46f, 0.54f, 0.80f, 0.60f); - colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); - colors[ImGuiCol_ButtonHovered] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); - colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f); - colors[ImGuiCol_Header] = ImVec4(0.26f, 0.59f, 0.98f, 0.31f); - colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); - colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); - colors[ImGuiCol_Separator] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); - colors[ImGuiCol_SeparatorHovered] = ImVec4(0.14f, 0.44f, 0.80f, 0.78f); - colors[ImGuiCol_SeparatorActive] = ImVec4(0.14f, 0.44f, 0.80f, 1.00f); - colors[ImGuiCol_ResizeGrip] = ImVec4(0.80f, 0.80f, 0.80f, 0.56f); - colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); - colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); - colors[ImGuiCol_CloseButton] = ImVec4(0.59f, 0.59f, 0.59f, 0.50f); - colors[ImGuiCol_CloseButtonHovered] = ImVec4(0.98f, 0.39f, 0.36f, 1.00f); - colors[ImGuiCol_CloseButtonActive] = ImVec4(0.98f, 0.39f, 0.36f, 1.00f); - colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); - colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); - colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); - colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.45f, 0.00f, 1.00f); - colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); - colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); - colors[ImGuiCol_DragDropTarget] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); - colors[ImGuiCol_NavHighlight] = colors[ImGuiCol_HeaderHovered]; - colors[ImGuiCol_NavWindowingHighlight] = ImVec4(0.70f, 0.70f, 0.70f, 0.70f); + colors[ImGuiCol_Text] = ImVec4(0.00f, 0.00f, 0.00f, 1.00f); + colors[ImGuiCol_TextDisabled] = ImVec4(0.60f, 0.60f, 0.60f, 1.00f); + //colors[ImGuiCol_TextHovered] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + //colors[ImGuiCol_TextActive] = ImVec4(1.00f, 1.00f, 0.00f, 1.00f); + colors[ImGuiCol_WindowBg] = ImVec4(0.94f, 0.94f, 0.94f, 1.00f); + colors[ImGuiCol_ChildBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_PopupBg] = ImVec4(1.00f, 1.00f, 1.00f, 0.98f); + colors[ImGuiCol_Border] = ImVec4(0.00f, 0.00f, 0.00f, 0.30f); + colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f); + colors[ImGuiCol_FrameBg] = ImVec4(1.00f, 1.00f, 1.00f, 1.00f); + colors[ImGuiCol_FrameBgHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); + colors[ImGuiCol_FrameBgActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + colors[ImGuiCol_TitleBg] = ImVec4(0.96f, 0.96f, 0.96f, 1.00f); + colors[ImGuiCol_TitleBgActive] = ImVec4(0.82f, 0.82f, 0.82f, 1.00f); + colors[ImGuiCol_TitleBgCollapsed] = ImVec4(1.00f, 1.00f, 1.00f, 0.51f); + colors[ImGuiCol_MenuBarBg] = ImVec4(0.86f, 0.86f, 0.86f, 1.00f); + colors[ImGuiCol_ScrollbarBg] = ImVec4(0.98f, 0.98f, 0.98f, 0.53f); + colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.69f, 0.69f, 0.69f, 0.80f); + colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.49f, 0.49f, 0.49f, 0.80f); + colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.49f, 0.49f, 0.49f, 1.00f); + colors[ImGuiCol_CheckMark] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_SliderGrab] = ImVec4(0.26f, 0.59f, 0.98f, 0.78f); + colors[ImGuiCol_SliderGrabActive] = ImVec4(0.46f, 0.54f, 0.80f, 0.60f); + colors[ImGuiCol_Button] = ImVec4(0.26f, 0.59f, 0.98f, 0.40f); + colors[ImGuiCol_ButtonHovered] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f); + colors[ImGuiCol_Header] = ImVec4(0.26f, 0.59f, 0.98f, 0.31f); + colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f); + colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f); + colors[ImGuiCol_Separator] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); + colors[ImGuiCol_SeparatorHovered] = ImVec4(0.14f, 0.44f, 0.80f, 0.78f); + colors[ImGuiCol_SeparatorActive] = ImVec4(0.14f, 0.44f, 0.80f, 1.00f); + colors[ImGuiCol_ResizeGrip] = ImVec4(0.80f, 0.80f, 0.80f, 0.56f); + colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f); + colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); + colors[ImGuiCol_CloseButton] = ImVec4(0.59f, 0.59f, 0.59f, 0.50f); + colors[ImGuiCol_CloseButtonHovered] = ImVec4(0.98f, 0.39f, 0.36f, 1.00f); + colors[ImGuiCol_CloseButtonActive] = ImVec4(0.98f, 0.39f, 0.36f, 1.00f); + colors[ImGuiCol_PlotLines] = ImVec4(0.39f, 0.39f, 0.39f, 1.00f); + colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f); + colors[ImGuiCol_PlotHistogram] = ImVec4(0.90f, 0.70f, 0.00f, 1.00f); + colors[ImGuiCol_PlotHistogramHovered] = ImVec4(1.00f, 0.45f, 0.00f, 1.00f); + colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f); + colors[ImGuiCol_ModalWindowDarkening] = ImVec4(0.20f, 0.20f, 0.20f, 0.35f); + colors[ImGuiCol_DragDropTarget] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f); + colors[ImGuiCol_NavHighlight] = colors[ImGuiCol_HeaderHovered]; + colors[ImGuiCol_NavWindowingHighlight] = ImVec4(0.70f, 0.70f, 0.70f, 0.70f); } //----------------------------------------------------------------------------- @@ -292,17 +292,17 @@ void ImGui::StyleColorsLight(ImGuiStyle* dst) ImDrawListSharedData::ImDrawListSharedData() { - Font = NULL; - FontSize = 0.0f; - CurveTessellationTol = 0.0f; - ClipRectFullscreen = ImVec4(-8192.0f, -8192.0f, +8192.0f, +8192.0f); - - // Const data - for (int i = 0; i < IM_ARRAYSIZE(CircleVtx12); i++) - { - const float a = ((float)i * 2 * IM_PI) / (float)IM_ARRAYSIZE(CircleVtx12); - CircleVtx12[i] = ImVec2(cosf(a), sinf(a)); - } + Font = NULL; + FontSize = 0.0f; + CurveTessellationTol = 0.0f; + ClipRectFullscreen = ImVec4(-8192.0f, -8192.0f, +8192.0f, +8192.0f); + + // Const data + for (int i = 0; i < IM_ARRAYSIZE(CircleVtx12); i++) + { + const float a = ((float)i * 2 * IM_PI) / (float)IM_ARRAYSIZE(CircleVtx12); + CircleVtx12[i] = ImVec2(cosf(a), sinf(a)); + } } //----------------------------------------------------------------------------- @@ -311,109 +311,109 @@ ImDrawListSharedData::ImDrawListSharedData() void ImDrawList::Clear() { - CmdBuffer.resize(0); - IdxBuffer.resize(0); - VtxBuffer.resize(0); - Flags = ImDrawListFlags_AntiAliasedLines | ImDrawListFlags_AntiAliasedFill; - _VtxCurrentIdx = 0; - _VtxWritePtr = NULL; - _IdxWritePtr = NULL; - _ClipRectStack.resize(0); - _TextureIdStack.resize(0); - _Path.resize(0); - _ChannelsCurrent = 0; - _ChannelsCount = 1; - // NB: Do not clear channels so our allocations are re-used after the first frame. + CmdBuffer.resize(0); + IdxBuffer.resize(0); + VtxBuffer.resize(0); + Flags = ImDrawListFlags_AntiAliasedLines | ImDrawListFlags_AntiAliasedFill; + _VtxCurrentIdx = 0; + _VtxWritePtr = NULL; + _IdxWritePtr = NULL; + _ClipRectStack.resize(0); + _TextureIdStack.resize(0); + _Path.resize(0); + _ChannelsCurrent = 0; + _ChannelsCount = 1; + // NB: Do not clear channels so our allocations are re-used after the first frame. } void ImDrawList::ClearFreeMemory() { - CmdBuffer.clear(); - IdxBuffer.clear(); - VtxBuffer.clear(); - _VtxCurrentIdx = 0; - _VtxWritePtr = NULL; - _IdxWritePtr = NULL; - _ClipRectStack.clear(); - _TextureIdStack.clear(); - _Path.clear(); - _ChannelsCurrent = 0; - _ChannelsCount = 1; - for (int i = 0; i < _Channels.Size; i++) - { - if (i == 0) memset(&_Channels[0], 0, sizeof(_Channels[0])); // channel 0 is a copy of CmdBuffer/IdxBuffer, don't destruct again - _Channels[i].CmdBuffer.clear(); - _Channels[i].IdxBuffer.clear(); - } - _Channels.clear(); + CmdBuffer.clear(); + IdxBuffer.clear(); + VtxBuffer.clear(); + _VtxCurrentIdx = 0; + _VtxWritePtr = NULL; + _IdxWritePtr = NULL; + _ClipRectStack.clear(); + _TextureIdStack.clear(); + _Path.clear(); + _ChannelsCurrent = 0; + _ChannelsCount = 1; + for (int i = 0; i < _Channels.Size; i++) + { + if (i == 0) memset(&_Channels[0], 0, sizeof(_Channels[0])); // channel 0 is a copy of CmdBuffer/IdxBuffer, don't destruct again + _Channels[i].CmdBuffer.clear(); + _Channels[i].IdxBuffer.clear(); + } + _Channels.clear(); } // Using macros because C++ is a terrible language, we want guaranteed inline, no code in header, and no overhead in Debug builds -#define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size-1] : _Data->ClipRectFullscreen) -#define GetCurrentTextureId() (_TextureIdStack.Size ? _TextureIdStack.Data[_TextureIdStack.Size-1] : NULL) +#define GetCurrentClipRect() (_ClipRectStack.Size ? _ClipRectStack.Data[_ClipRectStack.Size - 1] : _Data->ClipRectFullscreen) +#define GetCurrentTextureId() (_TextureIdStack.Size ? _TextureIdStack.Data[_TextureIdStack.Size - 1] : NULL) void ImDrawList::AddDrawCmd() { - ImDrawCmd draw_cmd; - draw_cmd.ClipRect = GetCurrentClipRect(); - draw_cmd.TextureId = GetCurrentTextureId(); + ImDrawCmd draw_cmd; + draw_cmd.ClipRect = GetCurrentClipRect(); + draw_cmd.TextureId = GetCurrentTextureId(); - IM_ASSERT(draw_cmd.ClipRect.x <= draw_cmd.ClipRect.z && draw_cmd.ClipRect.y <= draw_cmd.ClipRect.w); - CmdBuffer.push_back(draw_cmd); + IM_ASSERT(draw_cmd.ClipRect.x <= draw_cmd.ClipRect.z && draw_cmd.ClipRect.y <= draw_cmd.ClipRect.w); + CmdBuffer.push_back(draw_cmd); } void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data) { - ImDrawCmd* current_cmd = CmdBuffer.Size ? &CmdBuffer.back() : NULL; - if (!current_cmd || current_cmd->ElemCount != 0 || current_cmd->UserCallback != NULL) - { - AddDrawCmd(); - current_cmd = &CmdBuffer.back(); - } - current_cmd->UserCallback = callback; - current_cmd->UserCallbackData = callback_data; + ImDrawCmd* current_cmd = CmdBuffer.Size ? &CmdBuffer.back() : NULL; + if (!current_cmd || current_cmd->ElemCount != 0 || current_cmd->UserCallback != NULL) + { + AddDrawCmd(); + current_cmd = &CmdBuffer.back(); + } + current_cmd->UserCallback = callback; + current_cmd->UserCallbackData = callback_data; - AddDrawCmd(); // Force a new command after us (see comment below) + AddDrawCmd(); // Force a new command after us (see comment below) } // Our scheme may appears a bit unusual, basically we want the most-common calls AddLine AddRect etc. to not have to perform any check so we always have a command ready in the stack. // The cost of figuring out if a new command has to be added or if we can merge is paid in those Update** functions only. void ImDrawList::UpdateClipRect() { - // If current command is used with different settings we need to add a new command - const ImVec4 curr_clip_rect = GetCurrentClipRect(); - ImDrawCmd* curr_cmd = CmdBuffer.Size > 0 ? &CmdBuffer.Data[CmdBuffer.Size-1] : NULL; - if (!curr_cmd || (curr_cmd->ElemCount != 0 && memcmp(&curr_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) != 0) || curr_cmd->UserCallback != NULL) - { - AddDrawCmd(); - return; - } + // If current command is used with different settings we need to add a new command + const ImVec4 curr_clip_rect = GetCurrentClipRect(); + ImDrawCmd* curr_cmd = CmdBuffer.Size > 0 ? &CmdBuffer.Data[CmdBuffer.Size - 1] : NULL; + if (!curr_cmd || (curr_cmd->ElemCount != 0 && memcmp(&curr_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) != 0) || curr_cmd->UserCallback != NULL) + { + AddDrawCmd(); + return; + } - // Try to merge with previous command if it matches, else use current command - ImDrawCmd* prev_cmd = CmdBuffer.Size > 1 ? curr_cmd - 1 : NULL; - if (curr_cmd->ElemCount == 0 && prev_cmd && memcmp(&prev_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) == 0 && prev_cmd->TextureId == GetCurrentTextureId() && prev_cmd->UserCallback == NULL) - CmdBuffer.pop_back(); - else - curr_cmd->ClipRect = curr_clip_rect; + // Try to merge with previous command if it matches, else use current command + ImDrawCmd* prev_cmd = CmdBuffer.Size > 1 ? curr_cmd - 1 : NULL; + if (curr_cmd->ElemCount == 0 && prev_cmd && memcmp(&prev_cmd->ClipRect, &curr_clip_rect, sizeof(ImVec4)) == 0 && prev_cmd->TextureId == GetCurrentTextureId() && prev_cmd->UserCallback == NULL) + CmdBuffer.pop_back(); + else + curr_cmd->ClipRect = curr_clip_rect; } void ImDrawList::UpdateTextureID() { - // If current command is used with different settings we need to add a new command - const ImTextureID curr_texture_id = GetCurrentTextureId(); - ImDrawCmd* curr_cmd = CmdBuffer.Size ? &CmdBuffer.back() : NULL; - if (!curr_cmd || (curr_cmd->ElemCount != 0 && curr_cmd->TextureId != curr_texture_id) || curr_cmd->UserCallback != NULL) - { - AddDrawCmd(); - return; - } + // If current command is used with different settings we need to add a new command + const ImTextureID curr_texture_id = GetCurrentTextureId(); + ImDrawCmd* curr_cmd = CmdBuffer.Size ? &CmdBuffer.back() : NULL; + if (!curr_cmd || (curr_cmd->ElemCount != 0 && curr_cmd->TextureId != curr_texture_id) || curr_cmd->UserCallback != NULL) + { + AddDrawCmd(); + return; + } - // Try to merge with previous command if it matches, else use current command - ImDrawCmd* prev_cmd = CmdBuffer.Size > 1 ? curr_cmd - 1 : NULL; - if (curr_cmd->ElemCount == 0 && prev_cmd && prev_cmd->TextureId == curr_texture_id && memcmp(&prev_cmd->ClipRect, &GetCurrentClipRect(), sizeof(ImVec4)) == 0 && prev_cmd->UserCallback == NULL) - CmdBuffer.pop_back(); - else - curr_cmd->TextureId = curr_texture_id; + // Try to merge with previous command if it matches, else use current command + ImDrawCmd* prev_cmd = CmdBuffer.Size > 1 ? curr_cmd - 1 : NULL; + if (curr_cmd->ElemCount == 0 && prev_cmd && prev_cmd->TextureId == curr_texture_id && memcmp(&prev_cmd->ClipRect, &GetCurrentClipRect(), sizeof(ImVec4)) == 0 && prev_cmd->UserCallback == NULL) + CmdBuffer.pop_back(); + else + curr_cmd->TextureId = curr_texture_id; } #undef GetCurrentClipRect @@ -422,766 +422,879 @@ void ImDrawList::UpdateTextureID() // Render-level scissoring. This is passed down to your render function but not used for CPU-side coarse clipping. Prefer using higher-level ImGui::PushClipRect() to affect logic (hit-testing and widget culling) void ImDrawList::PushClipRect(ImVec2 cr_min, ImVec2 cr_max, bool intersect_with_current_clip_rect) { - ImVec4 cr(cr_min.x, cr_min.y, cr_max.x, cr_max.y); - if (intersect_with_current_clip_rect && _ClipRectStack.Size) - { - ImVec4 current = _ClipRectStack.Data[_ClipRectStack.Size-1]; - if (cr.x < current.x) cr.x = current.x; - if (cr.y < current.y) cr.y = current.y; - if (cr.z > current.z) cr.z = current.z; - if (cr.w > current.w) cr.w = current.w; - } - cr.z = ImMax(cr.x, cr.z); - cr.w = ImMax(cr.y, cr.w); + ImVec4 cr(cr_min.x, cr_min.y, cr_max.x, cr_max.y); + if (intersect_with_current_clip_rect && _ClipRectStack.Size) + { + ImVec4 current = _ClipRectStack.Data[_ClipRectStack.Size - 1]; + if (cr.x < current.x) cr.x = current.x; + if (cr.y < current.y) cr.y = current.y; + if (cr.z > current.z) cr.z = current.z; + if (cr.w > current.w) cr.w = current.w; + } + cr.z = ImMax(cr.x, cr.z); + cr.w = ImMax(cr.y, cr.w); - _ClipRectStack.push_back(cr); - UpdateClipRect(); + _ClipRectStack.push_back(cr); + UpdateClipRect(); } void ImDrawList::PushClipRectFullScreen() { - PushClipRect(ImVec2(_Data->ClipRectFullscreen.x, _Data->ClipRectFullscreen.y), ImVec2(_Data->ClipRectFullscreen.z, _Data->ClipRectFullscreen.w)); + PushClipRect(ImVec2(_Data->ClipRectFullscreen.x, _Data->ClipRectFullscreen.y), ImVec2(_Data->ClipRectFullscreen.z, _Data->ClipRectFullscreen.w)); } void ImDrawList::PopClipRect() { - IM_ASSERT(_ClipRectStack.Size > 0); - _ClipRectStack.pop_back(); - UpdateClipRect(); + IM_ASSERT(_ClipRectStack.Size > 0); + _ClipRectStack.pop_back(); + UpdateClipRect(); } void ImDrawList::PushTextureID(ImTextureID texture_id) { - _TextureIdStack.push_back(texture_id); - UpdateTextureID(); + _TextureIdStack.push_back(texture_id); + UpdateTextureID(); } void ImDrawList::PopTextureID() { - IM_ASSERT(_TextureIdStack.Size > 0); - _TextureIdStack.pop_back(); - UpdateTextureID(); + IM_ASSERT(_TextureIdStack.Size > 0); + _TextureIdStack.pop_back(); + UpdateTextureID(); } void ImDrawList::ChannelsSplit(int channels_count) { - IM_ASSERT(_ChannelsCurrent == 0 && _ChannelsCount == 1); - int old_channels_count = _Channels.Size; - if (old_channels_count < channels_count) - _Channels.resize(channels_count); - _ChannelsCount = channels_count; + IM_ASSERT(_ChannelsCurrent == 0 && _ChannelsCount == 1); + int old_channels_count = _Channels.Size; + if (old_channels_count < channels_count) + _Channels.resize(channels_count); + _ChannelsCount = channels_count; - // _Channels[] (24/32 bytes each) hold storage that we'll swap with this->_CmdBuffer/_IdxBuffer - // The content of _Channels[0] at this point doesn't matter. We clear it to make state tidy in a debugger but we don't strictly need to. - // When we switch to the next channel, we'll copy _CmdBuffer/_IdxBuffer into _Channels[0] and then _Channels[1] into _CmdBuffer/_IdxBuffer - memset(&_Channels[0], 0, sizeof(ImDrawChannel)); - for (int i = 1; i < channels_count; i++) - { - if (i >= old_channels_count) - { - IM_PLACEMENT_NEW(&_Channels[i]) ImDrawChannel(); - } - else - { - _Channels[i].CmdBuffer.resize(0); - _Channels[i].IdxBuffer.resize(0); - } - if (_Channels[i].CmdBuffer.Size == 0) - { - ImDrawCmd draw_cmd; - draw_cmd.ClipRect = _ClipRectStack.back(); - draw_cmd.TextureId = _TextureIdStack.back(); - _Channels[i].CmdBuffer.push_back(draw_cmd); - } - } + // _Channels[] (24/32 bytes each) hold storage that we'll swap with this->_CmdBuffer/_IdxBuffer + // The content of _Channels[0] at this point doesn't matter. We clear it to make state tidy in a debugger but we don't strictly need to. + // When we switch to the next channel, we'll copy _CmdBuffer/_IdxBuffer into _Channels[0] and then _Channels[1] into _CmdBuffer/_IdxBuffer + memset(&_Channels[0], 0, sizeof(ImDrawChannel)); + for (int i = 1; i < channels_count; i++) + { + if (i >= old_channels_count) + { + IM_PLACEMENT_NEW(&_Channels[i]) + ImDrawChannel(); + } + else + { + _Channels[i].CmdBuffer.resize(0); + _Channels[i].IdxBuffer.resize(0); + } + if (_Channels[i].CmdBuffer.Size == 0) + { + ImDrawCmd draw_cmd; + draw_cmd.ClipRect = _ClipRectStack.back(); + draw_cmd.TextureId = _TextureIdStack.back(); + _Channels[i].CmdBuffer.push_back(draw_cmd); + } + } } void ImDrawList::ChannelsMerge() { - // Note that we never use or rely on channels.Size because it is merely a buffer that we never shrink back to 0 to keep all sub-buffers ready for use. - if (_ChannelsCount <= 1) - return; + // Note that we never use or rely on channels.Size because it is merely a buffer that we never shrink back to 0 to keep all sub-buffers ready for use. + if (_ChannelsCount <= 1) + return; - ChannelsSetCurrent(0); - if (CmdBuffer.Size && CmdBuffer.back().ElemCount == 0) - CmdBuffer.pop_back(); + ChannelsSetCurrent(0); + if (CmdBuffer.Size && CmdBuffer.back().ElemCount == 0) + CmdBuffer.pop_back(); - int new_cmd_buffer_count = 0, new_idx_buffer_count = 0; - for (int i = 1; i < _ChannelsCount; i++) - { - ImDrawChannel& ch = _Channels[i]; - if (ch.CmdBuffer.Size && ch.CmdBuffer.back().ElemCount == 0) - ch.CmdBuffer.pop_back(); - new_cmd_buffer_count += ch.CmdBuffer.Size; - new_idx_buffer_count += ch.IdxBuffer.Size; - } - CmdBuffer.resize(CmdBuffer.Size + new_cmd_buffer_count); - IdxBuffer.resize(IdxBuffer.Size + new_idx_buffer_count); + int new_cmd_buffer_count = 0, new_idx_buffer_count = 0; + for (int i = 1; i < _ChannelsCount; i++) + { + ImDrawChannel& ch = _Channels[i]; + if (ch.CmdBuffer.Size && ch.CmdBuffer.back().ElemCount == 0) + ch.CmdBuffer.pop_back(); + new_cmd_buffer_count += ch.CmdBuffer.Size; + new_idx_buffer_count += ch.IdxBuffer.Size; + } + CmdBuffer.resize(CmdBuffer.Size + new_cmd_buffer_count); + IdxBuffer.resize(IdxBuffer.Size + new_idx_buffer_count); - ImDrawCmd* cmd_write = CmdBuffer.Data + CmdBuffer.Size - new_cmd_buffer_count; - _IdxWritePtr = IdxBuffer.Data + IdxBuffer.Size - new_idx_buffer_count; - for (int i = 1; i < _ChannelsCount; i++) - { - ImDrawChannel& ch = _Channels[i]; - if (int sz = ch.CmdBuffer.Size) { memcpy(cmd_write, ch.CmdBuffer.Data, sz * sizeof(ImDrawCmd)); cmd_write += sz; } - if (int sz = ch.IdxBuffer.Size) { memcpy(_IdxWritePtr, ch.IdxBuffer.Data, sz * sizeof(ImDrawIdx)); _IdxWritePtr += sz; } - } - UpdateClipRect(); // We call this instead of AddDrawCmd(), so that empty channels won't produce an extra draw call. - _ChannelsCount = 1; + ImDrawCmd* cmd_write = CmdBuffer.Data + CmdBuffer.Size - new_cmd_buffer_count; + _IdxWritePtr = IdxBuffer.Data + IdxBuffer.Size - new_idx_buffer_count; + for (int i = 1; i < _ChannelsCount; i++) + { + ImDrawChannel& ch = _Channels[i]; + if (int sz = ch.CmdBuffer.Size) + { + memcpy(cmd_write, ch.CmdBuffer.Data, sz * sizeof(ImDrawCmd)); + cmd_write += sz; + } + if (int sz = ch.IdxBuffer.Size) + { + memcpy(_IdxWritePtr, ch.IdxBuffer.Data, sz * sizeof(ImDrawIdx)); + _IdxWritePtr += sz; + } + } + UpdateClipRect(); // We call this instead of AddDrawCmd(), so that empty channels won't produce an extra draw call. + _ChannelsCount = 1; } void ImDrawList::ChannelsSetCurrent(int idx) { - IM_ASSERT(idx < _ChannelsCount); - if (_ChannelsCurrent == idx) return; - memcpy(&_Channels.Data[_ChannelsCurrent].CmdBuffer, &CmdBuffer, sizeof(CmdBuffer)); // copy 12 bytes, four times - memcpy(&_Channels.Data[_ChannelsCurrent].IdxBuffer, &IdxBuffer, sizeof(IdxBuffer)); - _ChannelsCurrent = idx; - memcpy(&CmdBuffer, &_Channels.Data[_ChannelsCurrent].CmdBuffer, sizeof(CmdBuffer)); - memcpy(&IdxBuffer, &_Channels.Data[_ChannelsCurrent].IdxBuffer, sizeof(IdxBuffer)); - _IdxWritePtr = IdxBuffer.Data + IdxBuffer.Size; + IM_ASSERT(idx < _ChannelsCount); + if (_ChannelsCurrent == idx) return; + memcpy(&_Channels.Data[_ChannelsCurrent].CmdBuffer, &CmdBuffer, sizeof(CmdBuffer)); // copy 12 bytes, four times + memcpy(&_Channels.Data[_ChannelsCurrent].IdxBuffer, &IdxBuffer, sizeof(IdxBuffer)); + _ChannelsCurrent = idx; + memcpy(&CmdBuffer, &_Channels.Data[_ChannelsCurrent].CmdBuffer, sizeof(CmdBuffer)); + memcpy(&IdxBuffer, &_Channels.Data[_ChannelsCurrent].IdxBuffer, sizeof(IdxBuffer)); + _IdxWritePtr = IdxBuffer.Data + IdxBuffer.Size; } // NB: this can be called with negative count for removing primitives (as long as the result does not underflow) void ImDrawList::PrimReserve(int idx_count, int vtx_count) { - ImDrawCmd& draw_cmd = CmdBuffer.Data[CmdBuffer.Size-1]; - draw_cmd.ElemCount += idx_count; + ImDrawCmd& draw_cmd = CmdBuffer.Data[CmdBuffer.Size - 1]; + draw_cmd.ElemCount += idx_count; - int vtx_buffer_old_size = VtxBuffer.Size; - VtxBuffer.resize(vtx_buffer_old_size + vtx_count); - _VtxWritePtr = VtxBuffer.Data + vtx_buffer_old_size; + int vtx_buffer_old_size = VtxBuffer.Size; + VtxBuffer.resize(vtx_buffer_old_size + vtx_count); + _VtxWritePtr = VtxBuffer.Data + vtx_buffer_old_size; - int idx_buffer_old_size = IdxBuffer.Size; - IdxBuffer.resize(idx_buffer_old_size + idx_count); - _IdxWritePtr = IdxBuffer.Data + idx_buffer_old_size; + int idx_buffer_old_size = IdxBuffer.Size; + IdxBuffer.resize(idx_buffer_old_size + idx_count); + _IdxWritePtr = IdxBuffer.Data + idx_buffer_old_size; } // Fully unrolled with inline call to keep our debug builds decently fast. void ImDrawList::PrimRect(const ImVec2& a, const ImVec2& c, ImU32 col) { - ImVec2 b(c.x, a.y), d(a.x, c.y), uv(_Data->TexUvWhitePixel); - ImDrawIdx idx = (ImDrawIdx)_VtxCurrentIdx; - _IdxWritePtr[0] = idx; _IdxWritePtr[1] = (ImDrawIdx)(idx+1); _IdxWritePtr[2] = (ImDrawIdx)(idx+2); - _IdxWritePtr[3] = idx; _IdxWritePtr[4] = (ImDrawIdx)(idx+2); _IdxWritePtr[5] = (ImDrawIdx)(idx+3); - _VtxWritePtr[0].pos = a; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; - _VtxWritePtr[1].pos = b; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col; - _VtxWritePtr[2].pos = c; _VtxWritePtr[2].uv = uv; _VtxWritePtr[2].col = col; - _VtxWritePtr[3].pos = d; _VtxWritePtr[3].uv = uv; _VtxWritePtr[3].col = col; - _VtxWritePtr += 4; - _VtxCurrentIdx += 4; - _IdxWritePtr += 6; + ImVec2 b(c.x, a.y), d(a.x, c.y), uv(_Data->TexUvWhitePixel); + ImDrawIdx idx = (ImDrawIdx)_VtxCurrentIdx; + _IdxWritePtr[0] = idx; + _IdxWritePtr[1] = (ImDrawIdx)(idx + 1); + _IdxWritePtr[2] = (ImDrawIdx)(idx + 2); + _IdxWritePtr[3] = idx; + _IdxWritePtr[4] = (ImDrawIdx)(idx + 2); + _IdxWritePtr[5] = (ImDrawIdx)(idx + 3); + _VtxWritePtr[0].pos = a; + _VtxWritePtr[0].uv = uv; + _VtxWritePtr[0].col = col; + _VtxWritePtr[1].pos = b; + _VtxWritePtr[1].uv = uv; + _VtxWritePtr[1].col = col; + _VtxWritePtr[2].pos = c; + _VtxWritePtr[2].uv = uv; + _VtxWritePtr[2].col = col; + _VtxWritePtr[3].pos = d; + _VtxWritePtr[3].uv = uv; + _VtxWritePtr[3].col = col; + _VtxWritePtr += 4; + _VtxCurrentIdx += 4; + _IdxWritePtr += 6; } void ImDrawList::PrimRectUV(const ImVec2& a, const ImVec2& c, const ImVec2& uv_a, const ImVec2& uv_c, ImU32 col) { - ImVec2 b(c.x, a.y), d(a.x, c.y), uv_b(uv_c.x, uv_a.y), uv_d(uv_a.x, uv_c.y); - ImDrawIdx idx = (ImDrawIdx)_VtxCurrentIdx; - _IdxWritePtr[0] = idx; _IdxWritePtr[1] = (ImDrawIdx)(idx+1); _IdxWritePtr[2] = (ImDrawIdx)(idx+2); - _IdxWritePtr[3] = idx; _IdxWritePtr[4] = (ImDrawIdx)(idx+2); _IdxWritePtr[5] = (ImDrawIdx)(idx+3); - _VtxWritePtr[0].pos = a; _VtxWritePtr[0].uv = uv_a; _VtxWritePtr[0].col = col; - _VtxWritePtr[1].pos = b; _VtxWritePtr[1].uv = uv_b; _VtxWritePtr[1].col = col; - _VtxWritePtr[2].pos = c; _VtxWritePtr[2].uv = uv_c; _VtxWritePtr[2].col = col; - _VtxWritePtr[3].pos = d; _VtxWritePtr[3].uv = uv_d; _VtxWritePtr[3].col = col; - _VtxWritePtr += 4; - _VtxCurrentIdx += 4; - _IdxWritePtr += 6; + ImVec2 b(c.x, a.y), d(a.x, c.y), uv_b(uv_c.x, uv_a.y), uv_d(uv_a.x, uv_c.y); + ImDrawIdx idx = (ImDrawIdx)_VtxCurrentIdx; + _IdxWritePtr[0] = idx; + _IdxWritePtr[1] = (ImDrawIdx)(idx + 1); + _IdxWritePtr[2] = (ImDrawIdx)(idx + 2); + _IdxWritePtr[3] = idx; + _IdxWritePtr[4] = (ImDrawIdx)(idx + 2); + _IdxWritePtr[5] = (ImDrawIdx)(idx + 3); + _VtxWritePtr[0].pos = a; + _VtxWritePtr[0].uv = uv_a; + _VtxWritePtr[0].col = col; + _VtxWritePtr[1].pos = b; + _VtxWritePtr[1].uv = uv_b; + _VtxWritePtr[1].col = col; + _VtxWritePtr[2].pos = c; + _VtxWritePtr[2].uv = uv_c; + _VtxWritePtr[2].col = col; + _VtxWritePtr[3].pos = d; + _VtxWritePtr[3].uv = uv_d; + _VtxWritePtr[3].col = col; + _VtxWritePtr += 4; + _VtxCurrentIdx += 4; + _IdxWritePtr += 6; } void ImDrawList::PrimQuadUV(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a, const ImVec2& uv_b, const ImVec2& uv_c, const ImVec2& uv_d, ImU32 col) { - ImDrawIdx idx = (ImDrawIdx)_VtxCurrentIdx; - _IdxWritePtr[0] = idx; _IdxWritePtr[1] = (ImDrawIdx)(idx+1); _IdxWritePtr[2] = (ImDrawIdx)(idx+2); - _IdxWritePtr[3] = idx; _IdxWritePtr[4] = (ImDrawIdx)(idx+2); _IdxWritePtr[5] = (ImDrawIdx)(idx+3); - _VtxWritePtr[0].pos = a; _VtxWritePtr[0].uv = uv_a; _VtxWritePtr[0].col = col; - _VtxWritePtr[1].pos = b; _VtxWritePtr[1].uv = uv_b; _VtxWritePtr[1].col = col; - _VtxWritePtr[2].pos = c; _VtxWritePtr[2].uv = uv_c; _VtxWritePtr[2].col = col; - _VtxWritePtr[3].pos = d; _VtxWritePtr[3].uv = uv_d; _VtxWritePtr[3].col = col; - _VtxWritePtr += 4; - _VtxCurrentIdx += 4; - _IdxWritePtr += 6; + ImDrawIdx idx = (ImDrawIdx)_VtxCurrentIdx; + _IdxWritePtr[0] = idx; + _IdxWritePtr[1] = (ImDrawIdx)(idx + 1); + _IdxWritePtr[2] = (ImDrawIdx)(idx + 2); + _IdxWritePtr[3] = idx; + _IdxWritePtr[4] = (ImDrawIdx)(idx + 2); + _IdxWritePtr[5] = (ImDrawIdx)(idx + 3); + _VtxWritePtr[0].pos = a; + _VtxWritePtr[0].uv = uv_a; + _VtxWritePtr[0].col = col; + _VtxWritePtr[1].pos = b; + _VtxWritePtr[1].uv = uv_b; + _VtxWritePtr[1].col = col; + _VtxWritePtr[2].pos = c; + _VtxWritePtr[2].uv = uv_c; + _VtxWritePtr[2].col = col; + _VtxWritePtr[3].pos = d; + _VtxWritePtr[3].uv = uv_d; + _VtxWritePtr[3].col = col; + _VtxWritePtr += 4; + _VtxCurrentIdx += 4; + _IdxWritePtr += 6; } // TODO: Thickness anti-aliased lines cap are missing their AA fringe. void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 col, bool closed, float thickness) { - if (points_count < 2) - return; + if (points_count < 2) + return; - const ImVec2 uv = _Data->TexUvWhitePixel; + const ImVec2 uv = _Data->TexUvWhitePixel; - int count = points_count; - if (!closed) - count = points_count-1; + int count = points_count; + if (!closed) + count = points_count - 1; - const bool thick_line = thickness > 1.0f; - if (Flags & ImDrawListFlags_AntiAliasedLines) - { - // Anti-aliased stroke - const float AA_SIZE = 1.0f; - const ImU32 col_trans = col & ~IM_COL32_A_MASK; + const bool thick_line = thickness > 1.0f; + if (Flags & ImDrawListFlags_AntiAliasedLines) + { + // Anti-aliased stroke + const float AA_SIZE = 1.0f; + const ImU32 col_trans = col & ~IM_COL32_A_MASK; - const int idx_count = thick_line ? count*18 : count*12; - const int vtx_count = thick_line ? points_count*4 : points_count*3; - PrimReserve(idx_count, vtx_count); + const int idx_count = thick_line ? count * 18 : count * 12; + const int vtx_count = thick_line ? points_count * 4 : points_count * 3; + PrimReserve(idx_count, vtx_count); - // Temporary buffer - ImVec2* temp_normals = (ImVec2*)alloca(points_count * (thick_line ? 5 : 3) * sizeof(ImVec2)); - ImVec2* temp_points = temp_normals + points_count; + // Temporary buffer + ImVec2* temp_normals = (ImVec2*)alloca(points_count * (thick_line ? 5 : 3) * sizeof(ImVec2)); + ImVec2* temp_points = temp_normals + points_count; - for (int i1 = 0; i1 < count; i1++) - { - const int i2 = (i1+1) == points_count ? 0 : i1+1; - ImVec2 diff = points[i2] - points[i1]; - diff *= ImInvLength(diff, 1.0f); - temp_normals[i1].x = diff.y; - temp_normals[i1].y = -diff.x; - } - if (!closed) - temp_normals[points_count-1] = temp_normals[points_count-2]; + for (int i1 = 0; i1 < count; i1++) + { + const int i2 = (i1 + 1) == points_count ? 0 : i1 + 1; + ImVec2 diff = points[i2] - points[i1]; + diff *= ImInvLength(diff, 1.0f); + temp_normals[i1].x = diff.y; + temp_normals[i1].y = -diff.x; + } + if (!closed) + temp_normals[points_count - 1] = temp_normals[points_count - 2]; - if (!thick_line) - { - if (!closed) - { - temp_points[0] = points[0] + temp_normals[0] * AA_SIZE; - temp_points[1] = points[0] - temp_normals[0] * AA_SIZE; - temp_points[(points_count-1)*2+0] = points[points_count-1] + temp_normals[points_count-1] * AA_SIZE; - temp_points[(points_count-1)*2+1] = points[points_count-1] - temp_normals[points_count-1] * AA_SIZE; - } + if (!thick_line) + { + if (!closed) + { + temp_points[0] = points[0] + temp_normals[0] * AA_SIZE; + temp_points[1] = points[0] - temp_normals[0] * AA_SIZE; + temp_points[(points_count - 1) * 2 + 0] = points[points_count - 1] + temp_normals[points_count - 1] * AA_SIZE; + temp_points[(points_count - 1) * 2 + 1] = points[points_count - 1] - temp_normals[points_count - 1] * AA_SIZE; + } - // FIXME-OPT: Merge the different loops, possibly remove the temporary buffer. - unsigned int idx1 = _VtxCurrentIdx; - for (int i1 = 0; i1 < count; i1++) - { - const int i2 = (i1+1) == points_count ? 0 : i1+1; - unsigned int idx2 = (i1+1) == points_count ? _VtxCurrentIdx : idx1+3; + // FIXME-OPT: Merge the different loops, possibly remove the temporary buffer. + unsigned int idx1 = _VtxCurrentIdx; + for (int i1 = 0; i1 < count; i1++) + { + const int i2 = (i1 + 1) == points_count ? 0 : i1 + 1; + unsigned int idx2 = (i1 + 1) == points_count ? _VtxCurrentIdx : idx1 + 3; - // Average normals - ImVec2 dm = (temp_normals[i1] + temp_normals[i2]) * 0.5f; - float dmr2 = dm.x*dm.x + dm.y*dm.y; - if (dmr2 > 0.000001f) - { - float scale = 1.0f / dmr2; - if (scale > 100.0f) scale = 100.0f; - dm *= scale; - } - dm *= AA_SIZE; - temp_points[i2*2+0] = points[i2] + dm; - temp_points[i2*2+1] = points[i2] - dm; + // Average normals + ImVec2 dm = (temp_normals[i1] + temp_normals[i2]) * 0.5f; + float dmr2 = dm.x * dm.x + dm.y * dm.y; + if (dmr2 > 0.000001f) + { + float scale = 1.0f / dmr2; + if (scale > 100.0f) scale = 100.0f; + dm *= scale; + } + dm *= AA_SIZE; + temp_points[i2 * 2 + 0] = points[i2] + dm; + temp_points[i2 * 2 + 1] = points[i2] - dm; - // Add indexes - _IdxWritePtr[0] = (ImDrawIdx)(idx2+0); _IdxWritePtr[1] = (ImDrawIdx)(idx1+0); _IdxWritePtr[2] = (ImDrawIdx)(idx1+2); - _IdxWritePtr[3] = (ImDrawIdx)(idx1+2); _IdxWritePtr[4] = (ImDrawIdx)(idx2+2); _IdxWritePtr[5] = (ImDrawIdx)(idx2+0); - _IdxWritePtr[6] = (ImDrawIdx)(idx2+1); _IdxWritePtr[7] = (ImDrawIdx)(idx1+1); _IdxWritePtr[8] = (ImDrawIdx)(idx1+0); - _IdxWritePtr[9] = (ImDrawIdx)(idx1+0); _IdxWritePtr[10]= (ImDrawIdx)(idx2+0); _IdxWritePtr[11]= (ImDrawIdx)(idx2+1); - _IdxWritePtr += 12; + // Add indexes + _IdxWritePtr[0] = (ImDrawIdx)(idx2 + 0); + _IdxWritePtr[1] = (ImDrawIdx)(idx1 + 0); + _IdxWritePtr[2] = (ImDrawIdx)(idx1 + 2); + _IdxWritePtr[3] = (ImDrawIdx)(idx1 + 2); + _IdxWritePtr[4] = (ImDrawIdx)(idx2 + 2); + _IdxWritePtr[5] = (ImDrawIdx)(idx2 + 0); + _IdxWritePtr[6] = (ImDrawIdx)(idx2 + 1); + _IdxWritePtr[7] = (ImDrawIdx)(idx1 + 1); + _IdxWritePtr[8] = (ImDrawIdx)(idx1 + 0); + _IdxWritePtr[9] = (ImDrawIdx)(idx1 + 0); + _IdxWritePtr[10] = (ImDrawIdx)(idx2 + 0); + _IdxWritePtr[11] = (ImDrawIdx)(idx2 + 1); + _IdxWritePtr += 12; - idx1 = idx2; - } + idx1 = idx2; + } - // Add vertexes - for (int i = 0; i < points_count; i++) - { - _VtxWritePtr[0].pos = points[i]; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; - _VtxWritePtr[1].pos = temp_points[i*2+0]; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col_trans; - _VtxWritePtr[2].pos = temp_points[i*2+1]; _VtxWritePtr[2].uv = uv; _VtxWritePtr[2].col = col_trans; - _VtxWritePtr += 3; - } - } - else - { - const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f; - if (!closed) - { - temp_points[0] = points[0] + temp_normals[0] * (half_inner_thickness + AA_SIZE); - temp_points[1] = points[0] + temp_normals[0] * (half_inner_thickness); - temp_points[2] = points[0] - temp_normals[0] * (half_inner_thickness); - temp_points[3] = points[0] - temp_normals[0] * (half_inner_thickness + AA_SIZE); - temp_points[(points_count-1)*4+0] = points[points_count-1] + temp_normals[points_count-1] * (half_inner_thickness + AA_SIZE); - temp_points[(points_count-1)*4+1] = points[points_count-1] + temp_normals[points_count-1] * (half_inner_thickness); - temp_points[(points_count-1)*4+2] = points[points_count-1] - temp_normals[points_count-1] * (half_inner_thickness); - temp_points[(points_count-1)*4+3] = points[points_count-1] - temp_normals[points_count-1] * (half_inner_thickness + AA_SIZE); - } + // Add vertexes + for (int i = 0; i < points_count; i++) + { + _VtxWritePtr[0].pos = points[i]; + _VtxWritePtr[0].uv = uv; + _VtxWritePtr[0].col = col; + _VtxWritePtr[1].pos = temp_points[i * 2 + 0]; + _VtxWritePtr[1].uv = uv; + _VtxWritePtr[1].col = col_trans; + _VtxWritePtr[2].pos = temp_points[i * 2 + 1]; + _VtxWritePtr[2].uv = uv; + _VtxWritePtr[2].col = col_trans; + _VtxWritePtr += 3; + } + } + else + { + const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f; + if (!closed) + { + temp_points[0] = points[0] + temp_normals[0] * (half_inner_thickness + AA_SIZE); + temp_points[1] = points[0] + temp_normals[0] * (half_inner_thickness); + temp_points[2] = points[0] - temp_normals[0] * (half_inner_thickness); + temp_points[3] = points[0] - temp_normals[0] * (half_inner_thickness + AA_SIZE); + temp_points[(points_count - 1) * 4 + 0] = points[points_count - 1] + temp_normals[points_count - 1] * (half_inner_thickness + AA_SIZE); + temp_points[(points_count - 1) * 4 + 1] = points[points_count - 1] + temp_normals[points_count - 1] * (half_inner_thickness); + temp_points[(points_count - 1) * 4 + 2] = points[points_count - 1] - temp_normals[points_count - 1] * (half_inner_thickness); + temp_points[(points_count - 1) * 4 + 3] = points[points_count - 1] - temp_normals[points_count - 1] * (half_inner_thickness + AA_SIZE); + } - // FIXME-OPT: Merge the different loops, possibly remove the temporary buffer. - unsigned int idx1 = _VtxCurrentIdx; - for (int i1 = 0; i1 < count; i1++) - { - const int i2 = (i1+1) == points_count ? 0 : i1+1; - unsigned int idx2 = (i1+1) == points_count ? _VtxCurrentIdx : idx1+4; + // FIXME-OPT: Merge the different loops, possibly remove the temporary buffer. + unsigned int idx1 = _VtxCurrentIdx; + for (int i1 = 0; i1 < count; i1++) + { + const int i2 = (i1 + 1) == points_count ? 0 : i1 + 1; + unsigned int idx2 = (i1 + 1) == points_count ? _VtxCurrentIdx : idx1 + 4; - // Average normals - ImVec2 dm = (temp_normals[i1] + temp_normals[i2]) * 0.5f; - float dmr2 = dm.x*dm.x + dm.y*dm.y; - if (dmr2 > 0.000001f) - { - float scale = 1.0f / dmr2; - if (scale > 100.0f) scale = 100.0f; - dm *= scale; - } - ImVec2 dm_out = dm * (half_inner_thickness + AA_SIZE); - ImVec2 dm_in = dm * half_inner_thickness; - temp_points[i2*4+0] = points[i2] + dm_out; - temp_points[i2*4+1] = points[i2] + dm_in; - temp_points[i2*4+2] = points[i2] - dm_in; - temp_points[i2*4+3] = points[i2] - dm_out; + // Average normals + ImVec2 dm = (temp_normals[i1] + temp_normals[i2]) * 0.5f; + float dmr2 = dm.x * dm.x + dm.y * dm.y; + if (dmr2 > 0.000001f) + { + float scale = 1.0f / dmr2; + if (scale > 100.0f) scale = 100.0f; + dm *= scale; + } + ImVec2 dm_out = dm * (half_inner_thickness + AA_SIZE); + ImVec2 dm_in = dm * half_inner_thickness; + temp_points[i2 * 4 + 0] = points[i2] + dm_out; + temp_points[i2 * 4 + 1] = points[i2] + dm_in; + temp_points[i2 * 4 + 2] = points[i2] - dm_in; + temp_points[i2 * 4 + 3] = points[i2] - dm_out; - // Add indexes - _IdxWritePtr[0] = (ImDrawIdx)(idx2+1); _IdxWritePtr[1] = (ImDrawIdx)(idx1+1); _IdxWritePtr[2] = (ImDrawIdx)(idx1+2); - _IdxWritePtr[3] = (ImDrawIdx)(idx1+2); _IdxWritePtr[4] = (ImDrawIdx)(idx2+2); _IdxWritePtr[5] = (ImDrawIdx)(idx2+1); - _IdxWritePtr[6] = (ImDrawIdx)(idx2+1); _IdxWritePtr[7] = (ImDrawIdx)(idx1+1); _IdxWritePtr[8] = (ImDrawIdx)(idx1+0); - _IdxWritePtr[9] = (ImDrawIdx)(idx1+0); _IdxWritePtr[10] = (ImDrawIdx)(idx2+0); _IdxWritePtr[11] = (ImDrawIdx)(idx2+1); - _IdxWritePtr[12] = (ImDrawIdx)(idx2+2); _IdxWritePtr[13] = (ImDrawIdx)(idx1+2); _IdxWritePtr[14] = (ImDrawIdx)(idx1+3); - _IdxWritePtr[15] = (ImDrawIdx)(idx1+3); _IdxWritePtr[16] = (ImDrawIdx)(idx2+3); _IdxWritePtr[17] = (ImDrawIdx)(idx2+2); - _IdxWritePtr += 18; + // Add indexes + _IdxWritePtr[0] = (ImDrawIdx)(idx2 + 1); + _IdxWritePtr[1] = (ImDrawIdx)(idx1 + 1); + _IdxWritePtr[2] = (ImDrawIdx)(idx1 + 2); + _IdxWritePtr[3] = (ImDrawIdx)(idx1 + 2); + _IdxWritePtr[4] = (ImDrawIdx)(idx2 + 2); + _IdxWritePtr[5] = (ImDrawIdx)(idx2 + 1); + _IdxWritePtr[6] = (ImDrawIdx)(idx2 + 1); + _IdxWritePtr[7] = (ImDrawIdx)(idx1 + 1); + _IdxWritePtr[8] = (ImDrawIdx)(idx1 + 0); + _IdxWritePtr[9] = (ImDrawIdx)(idx1 + 0); + _IdxWritePtr[10] = (ImDrawIdx)(idx2 + 0); + _IdxWritePtr[11] = (ImDrawIdx)(idx2 + 1); + _IdxWritePtr[12] = (ImDrawIdx)(idx2 + 2); + _IdxWritePtr[13] = (ImDrawIdx)(idx1 + 2); + _IdxWritePtr[14] = (ImDrawIdx)(idx1 + 3); + _IdxWritePtr[15] = (ImDrawIdx)(idx1 + 3); + _IdxWritePtr[16] = (ImDrawIdx)(idx2 + 3); + _IdxWritePtr[17] = (ImDrawIdx)(idx2 + 2); + _IdxWritePtr += 18; - idx1 = idx2; - } + idx1 = idx2; + } - // Add vertexes - for (int i = 0; i < points_count; i++) - { - _VtxWritePtr[0].pos = temp_points[i*4+0]; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col_trans; - _VtxWritePtr[1].pos = temp_points[i*4+1]; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col; - _VtxWritePtr[2].pos = temp_points[i*4+2]; _VtxWritePtr[2].uv = uv; _VtxWritePtr[2].col = col; - _VtxWritePtr[3].pos = temp_points[i*4+3]; _VtxWritePtr[3].uv = uv; _VtxWritePtr[3].col = col_trans; - _VtxWritePtr += 4; - } - } - _VtxCurrentIdx += (ImDrawIdx)vtx_count; - } - else - { - // Non Anti-aliased Stroke - const int idx_count = count*6; - const int vtx_count = count*4; // FIXME-OPT: Not sharing edges - PrimReserve(idx_count, vtx_count); + // Add vertexes + for (int i = 0; i < points_count; i++) + { + _VtxWritePtr[0].pos = temp_points[i * 4 + 0]; + _VtxWritePtr[0].uv = uv; + _VtxWritePtr[0].col = col_trans; + _VtxWritePtr[1].pos = temp_points[i * 4 + 1]; + _VtxWritePtr[1].uv = uv; + _VtxWritePtr[1].col = col; + _VtxWritePtr[2].pos = temp_points[i * 4 + 2]; + _VtxWritePtr[2].uv = uv; + _VtxWritePtr[2].col = col; + _VtxWritePtr[3].pos = temp_points[i * 4 + 3]; + _VtxWritePtr[3].uv = uv; + _VtxWritePtr[3].col = col_trans; + _VtxWritePtr += 4; + } + } + _VtxCurrentIdx += (ImDrawIdx)vtx_count; + } + else + { + // Non Anti-aliased Stroke + const int idx_count = count * 6; + const int vtx_count = count * 4; // FIXME-OPT: Not sharing edges + PrimReserve(idx_count, vtx_count); - for (int i1 = 0; i1 < count; i1++) - { - const int i2 = (i1+1) == points_count ? 0 : i1+1; - const ImVec2& p1 = points[i1]; - const ImVec2& p2 = points[i2]; - ImVec2 diff = p2 - p1; - diff *= ImInvLength(diff, 1.0f); + for (int i1 = 0; i1 < count; i1++) + { + const int i2 = (i1 + 1) == points_count ? 0 : i1 + 1; + const ImVec2& p1 = points[i1]; + const ImVec2& p2 = points[i2]; + ImVec2 diff = p2 - p1; + diff *= ImInvLength(diff, 1.0f); - const float dx = diff.x * (thickness * 0.5f); - const float dy = diff.y * (thickness * 0.5f); - _VtxWritePtr[0].pos.x = p1.x + dy; _VtxWritePtr[0].pos.y = p1.y - dx; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; - _VtxWritePtr[1].pos.x = p2.x + dy; _VtxWritePtr[1].pos.y = p2.y - dx; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col; - _VtxWritePtr[2].pos.x = p2.x - dy; _VtxWritePtr[2].pos.y = p2.y + dx; _VtxWritePtr[2].uv = uv; _VtxWritePtr[2].col = col; - _VtxWritePtr[3].pos.x = p1.x - dy; _VtxWritePtr[3].pos.y = p1.y + dx; _VtxWritePtr[3].uv = uv; _VtxWritePtr[3].col = col; - _VtxWritePtr += 4; + const float dx = diff.x * (thickness * 0.5f); + const float dy = diff.y * (thickness * 0.5f); + _VtxWritePtr[0].pos.x = p1.x + dy; + _VtxWritePtr[0].pos.y = p1.y - dx; + _VtxWritePtr[0].uv = uv; + _VtxWritePtr[0].col = col; + _VtxWritePtr[1].pos.x = p2.x + dy; + _VtxWritePtr[1].pos.y = p2.y - dx; + _VtxWritePtr[1].uv = uv; + _VtxWritePtr[1].col = col; + _VtxWritePtr[2].pos.x = p2.x - dy; + _VtxWritePtr[2].pos.y = p2.y + dx; + _VtxWritePtr[2].uv = uv; + _VtxWritePtr[2].col = col; + _VtxWritePtr[3].pos.x = p1.x - dy; + _VtxWritePtr[3].pos.y = p1.y + dx; + _VtxWritePtr[3].uv = uv; + _VtxWritePtr[3].col = col; + _VtxWritePtr += 4; - _IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx+1); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx+2); - _IdxWritePtr[3] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[4] = (ImDrawIdx)(_VtxCurrentIdx+2); _IdxWritePtr[5] = (ImDrawIdx)(_VtxCurrentIdx+3); - _IdxWritePtr += 6; - _VtxCurrentIdx += 4; - } - } + _IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx); + _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx + 1); + _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx + 2); + _IdxWritePtr[3] = (ImDrawIdx)(_VtxCurrentIdx); + _IdxWritePtr[4] = (ImDrawIdx)(_VtxCurrentIdx + 2); + _IdxWritePtr[5] = (ImDrawIdx)(_VtxCurrentIdx + 3); + _IdxWritePtr += 6; + _VtxCurrentIdx += 4; + } + } } void ImDrawList::AddConvexPolyFilled(const ImVec2* points, const int points_count, ImU32 col) { - const ImVec2 uv = _Data->TexUvWhitePixel; + const ImVec2 uv = _Data->TexUvWhitePixel; - if (Flags & ImDrawListFlags_AntiAliasedFill) - { - // Anti-aliased Fill - const float AA_SIZE = 1.0f; - const ImU32 col_trans = col & ~IM_COL32_A_MASK; - const int idx_count = (points_count-2)*3 + points_count*6; - const int vtx_count = (points_count*2); - PrimReserve(idx_count, vtx_count); + if (Flags & ImDrawListFlags_AntiAliasedFill) + { + // Anti-aliased Fill + const float AA_SIZE = 1.0f; + const ImU32 col_trans = col & ~IM_COL32_A_MASK; + const int idx_count = (points_count - 2) * 3 + points_count * 6; + const int vtx_count = (points_count * 2); + PrimReserve(idx_count, vtx_count); - // Add indexes for fill - unsigned int vtx_inner_idx = _VtxCurrentIdx; - unsigned int vtx_outer_idx = _VtxCurrentIdx+1; - for (int i = 2; i < points_count; i++) - { - _IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx+((i-1)<<1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_inner_idx+(i<<1)); - _IdxWritePtr += 3; - } + // Add indexes for fill + unsigned int vtx_inner_idx = _VtxCurrentIdx; + unsigned int vtx_outer_idx = _VtxCurrentIdx + 1; + for (int i = 2; i < points_count; i++) + { + _IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx); + _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx + ((i - 1) << 1)); + _IdxWritePtr[2] = (ImDrawIdx)(vtx_inner_idx + (i << 1)); + _IdxWritePtr += 3; + } - // Compute normals - ImVec2* temp_normals = (ImVec2*)alloca(points_count * sizeof(ImVec2)); - for (int i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) - { - const ImVec2& p0 = points[i0]; - const ImVec2& p1 = points[i1]; - ImVec2 diff = p1 - p0; - diff *= ImInvLength(diff, 1.0f); - temp_normals[i0].x = diff.y; - temp_normals[i0].y = -diff.x; - } + // Compute normals + ImVec2* temp_normals = (ImVec2*)alloca(points_count * sizeof(ImVec2)); + for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++) + { + const ImVec2& p0 = points[i0]; + const ImVec2& p1 = points[i1]; + ImVec2 diff = p1 - p0; + diff *= ImInvLength(diff, 1.0f); + temp_normals[i0].x = diff.y; + temp_normals[i0].y = -diff.x; + } - for (int i0 = points_count-1, i1 = 0; i1 < points_count; i0 = i1++) - { - // Average normals - const ImVec2& n0 = temp_normals[i0]; - const ImVec2& n1 = temp_normals[i1]; - ImVec2 dm = (n0 + n1) * 0.5f; - float dmr2 = dm.x*dm.x + dm.y*dm.y; - if (dmr2 > 0.000001f) - { - float scale = 1.0f / dmr2; - if (scale > 100.0f) scale = 100.0f; - dm *= scale; - } - dm *= AA_SIZE * 0.5f; + for (int i0 = points_count - 1, i1 = 0; i1 < points_count; i0 = i1++) + { + // Average normals + const ImVec2& n0 = temp_normals[i0]; + const ImVec2& n1 = temp_normals[i1]; + ImVec2 dm = (n0 + n1) * 0.5f; + float dmr2 = dm.x * dm.x + dm.y * dm.y; + if (dmr2 > 0.000001f) + { + float scale = 1.0f / dmr2; + if (scale > 100.0f) scale = 100.0f; + dm *= scale; + } + dm *= AA_SIZE * 0.5f; - // Add vertices - _VtxWritePtr[0].pos = (points[i1] - dm); _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; // Inner - _VtxWritePtr[1].pos = (points[i1] + dm); _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col_trans; // Outer - _VtxWritePtr += 2; + // Add vertices + _VtxWritePtr[0].pos = (points[i1] - dm); + _VtxWritePtr[0].uv = uv; + _VtxWritePtr[0].col = col; // Inner + _VtxWritePtr[1].pos = (points[i1] + dm); + _VtxWritePtr[1].uv = uv; + _VtxWritePtr[1].col = col_trans; // Outer + _VtxWritePtr += 2; - // Add indexes for fringes - _IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx+(i1<<1)); _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx+(i0<<1)); _IdxWritePtr[2] = (ImDrawIdx)(vtx_outer_idx+(i0<<1)); - _IdxWritePtr[3] = (ImDrawIdx)(vtx_outer_idx+(i0<<1)); _IdxWritePtr[4] = (ImDrawIdx)(vtx_outer_idx+(i1<<1)); _IdxWritePtr[5] = (ImDrawIdx)(vtx_inner_idx+(i1<<1)); - _IdxWritePtr += 6; - } - _VtxCurrentIdx += (ImDrawIdx)vtx_count; - } - else - { - // Non Anti-aliased Fill - const int idx_count = (points_count-2)*3; - const int vtx_count = points_count; - PrimReserve(idx_count, vtx_count); - for (int i = 0; i < vtx_count; i++) - { - _VtxWritePtr[0].pos = points[i]; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; - _VtxWritePtr++; - } - for (int i = 2; i < points_count; i++) - { - _IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx+i-1); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx+i); - _IdxWritePtr += 3; - } - _VtxCurrentIdx += (ImDrawIdx)vtx_count; - } + // Add indexes for fringes + _IdxWritePtr[0] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1)); + _IdxWritePtr[1] = (ImDrawIdx)(vtx_inner_idx + (i0 << 1)); + _IdxWritePtr[2] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1)); + _IdxWritePtr[3] = (ImDrawIdx)(vtx_outer_idx + (i0 << 1)); + _IdxWritePtr[4] = (ImDrawIdx)(vtx_outer_idx + (i1 << 1)); + _IdxWritePtr[5] = (ImDrawIdx)(vtx_inner_idx + (i1 << 1)); + _IdxWritePtr += 6; + } + _VtxCurrentIdx += (ImDrawIdx)vtx_count; + } + else + { + // Non Anti-aliased Fill + const int idx_count = (points_count - 2) * 3; + const int vtx_count = points_count; + PrimReserve(idx_count, vtx_count); + for (int i = 0; i < vtx_count; i++) + { + _VtxWritePtr[0].pos = points[i]; + _VtxWritePtr[0].uv = uv; + _VtxWritePtr[0].col = col; + _VtxWritePtr++; + } + for (int i = 2; i < points_count; i++) + { + _IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx); + _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx + i - 1); + _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx + i); + _IdxWritePtr += 3; + } + _VtxCurrentIdx += (ImDrawIdx)vtx_count; + } } void ImDrawList::PathArcToFast(const ImVec2& centre, float radius, int a_min_of_12, int a_max_of_12) { - if (radius == 0.0f || a_min_of_12 > a_max_of_12) - { - _Path.push_back(centre); - return; - } - _Path.reserve(_Path.Size + (a_max_of_12 - a_min_of_12 + 1)); - for (int a = a_min_of_12; a <= a_max_of_12; a++) - { - const ImVec2& c = _Data->CircleVtx12[a % IM_ARRAYSIZE(_Data->CircleVtx12)]; - _Path.push_back(ImVec2(centre.x + c.x * radius, centre.y + c.y * radius)); - } + if (radius == 0.0f || a_min_of_12 > a_max_of_12) + { + _Path.push_back(centre); + return; + } + _Path.reserve(_Path.Size + (a_max_of_12 - a_min_of_12 + 1)); + for (int a = a_min_of_12; a <= a_max_of_12; a++) + { + const ImVec2& c = _Data->CircleVtx12[a % IM_ARRAYSIZE(_Data->CircleVtx12)]; + _Path.push_back(ImVec2(centre.x + c.x * radius, centre.y + c.y * radius)); + } } void ImDrawList::PathArcTo(const ImVec2& centre, float radius, float a_min, float a_max, int num_segments) { - if (radius == 0.0f) - { - _Path.push_back(centre); - return; - } - _Path.reserve(_Path.Size + (num_segments + 1)); - for (int i = 0; i <= num_segments; i++) - { - const float a = a_min + ((float)i / (float)num_segments) * (a_max - a_min); - _Path.push_back(ImVec2(centre.x + cosf(a) * radius, centre.y + sinf(a) * radius)); - } + if (radius == 0.0f) + { + _Path.push_back(centre); + return; + } + _Path.reserve(_Path.Size + (num_segments + 1)); + for (int i = 0; i <= num_segments; i++) + { + const float a = a_min + ((float)i / (float)num_segments) * (a_max - a_min); + _Path.push_back(ImVec2(centre.x + cosf(a) * radius, centre.y + sinf(a) * radius)); + } } static void PathBezierToCasteljau(ImVector* path, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float tess_tol, int level) { - float dx = x4 - x1; - float dy = y4 - y1; - float d2 = ((x2 - x4) * dy - (y2 - y4) * dx); - float d3 = ((x3 - x4) * dy - (y3 - y4) * dx); - d2 = (d2 >= 0) ? d2 : -d2; - d3 = (d3 >= 0) ? d3 : -d3; - if ((d2+d3) * (d2+d3) < tess_tol * (dx*dx + dy*dy)) - { - path->push_back(ImVec2(x4, y4)); - } - else if (level < 10) - { - float x12 = (x1+x2)*0.5f, y12 = (y1+y2)*0.5f; - float x23 = (x2+x3)*0.5f, y23 = (y2+y3)*0.5f; - float x34 = (x3+x4)*0.5f, y34 = (y3+y4)*0.5f; - float x123 = (x12+x23)*0.5f, y123 = (y12+y23)*0.5f; - float x234 = (x23+x34)*0.5f, y234 = (y23+y34)*0.5f; - float x1234 = (x123+x234)*0.5f, y1234 = (y123+y234)*0.5f; + float dx = x4 - x1; + float dy = y4 - y1; + float d2 = ((x2 - x4) * dy - (y2 - y4) * dx); + float d3 = ((x3 - x4) * dy - (y3 - y4) * dx); + d2 = (d2 >= 0) ? d2 : -d2; + d3 = (d3 >= 0) ? d3 : -d3; + if ((d2 + d3) * (d2 + d3) < tess_tol * (dx * dx + dy * dy)) + { + path->push_back(ImVec2(x4, y4)); + } + else if (level < 10) + { + float x12 = (x1 + x2) * 0.5f, y12 = (y1 + y2) * 0.5f; + float x23 = (x2 + x3) * 0.5f, y23 = (y2 + y3) * 0.5f; + float x34 = (x3 + x4) * 0.5f, y34 = (y3 + y4) * 0.5f; + float x123 = (x12 + x23) * 0.5f, y123 = (y12 + y23) * 0.5f; + float x234 = (x23 + x34) * 0.5f, y234 = (y23 + y34) * 0.5f; + float x1234 = (x123 + x234) * 0.5f, y1234 = (y123 + y234) * 0.5f; - PathBezierToCasteljau(path, x1,y1, x12,y12, x123,y123, x1234,y1234, tess_tol, level+1); - PathBezierToCasteljau(path, x1234,y1234, x234,y234, x34,y34, x4,y4, tess_tol, level+1); - } + PathBezierToCasteljau(path, x1, y1, x12, y12, x123, y123, x1234, y1234, tess_tol, level + 1); + PathBezierToCasteljau(path, x1234, y1234, x234, y234, x34, y34, x4, y4, tess_tol, level + 1); + } } void ImDrawList::PathBezierCurveTo(const ImVec2& p2, const ImVec2& p3, const ImVec2& p4, int num_segments) { - ImVec2 p1 = _Path.back(); - if (num_segments == 0) - { - // Auto-tessellated - PathBezierToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, _Data->CurveTessellationTol, 0); - } - else - { - float t_step = 1.0f / (float)num_segments; - for (int i_step = 1; i_step <= num_segments; i_step++) - { - float t = t_step * i_step; - float u = 1.0f - t; - float w1 = u*u*u; - float w2 = 3*u*u*t; - float w3 = 3*u*t*t; - float w4 = t*t*t; - _Path.push_back(ImVec2(w1*p1.x + w2*p2.x + w3*p3.x + w4*p4.x, w1*p1.y + w2*p2.y + w3*p3.y + w4*p4.y)); - } - } + ImVec2 p1 = _Path.back(); + if (num_segments == 0) + { + // Auto-tessellated + PathBezierToCasteljau(&_Path, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y, p4.x, p4.y, _Data->CurveTessellationTol, 0); + } + else + { + float t_step = 1.0f / (float)num_segments; + for (int i_step = 1; i_step <= num_segments; i_step++) + { + float t = t_step * i_step; + float u = 1.0f - t; + float w1 = u * u * u; + float w2 = 3 * u * u * t; + float w3 = 3 * u * t * t; + float w4 = t * t * t; + _Path.push_back(ImVec2(w1 * p1.x + w2 * p2.x + w3 * p3.x + w4 * p4.x, w1 * p1.y + w2 * p2.y + w3 * p3.y + w4 * p4.y)); + } + } } void ImDrawList::PathRect(const ImVec2& a, const ImVec2& b, float rounding, int rounding_corners) { - rounding = ImMin(rounding, fabsf(b.x - a.x) * ( ((rounding_corners & ImDrawCornerFlags_Top) == ImDrawCornerFlags_Top) || ((rounding_corners & ImDrawCornerFlags_Bot) == ImDrawCornerFlags_Bot) ? 0.5f : 1.0f ) - 1.0f); - rounding = ImMin(rounding, fabsf(b.y - a.y) * ( ((rounding_corners & ImDrawCornerFlags_Left) == ImDrawCornerFlags_Left) || ((rounding_corners & ImDrawCornerFlags_Right) == ImDrawCornerFlags_Right) ? 0.5f : 1.0f ) - 1.0f); + rounding = ImMin(rounding, fabsf(b.x - a.x) * (((rounding_corners & ImDrawCornerFlags_Top) == ImDrawCornerFlags_Top) || ((rounding_corners & ImDrawCornerFlags_Bot) == ImDrawCornerFlags_Bot) ? 0.5f : 1.0f) - 1.0f); + rounding = ImMin(rounding, fabsf(b.y - a.y) * (((rounding_corners & ImDrawCornerFlags_Left) == ImDrawCornerFlags_Left) || ((rounding_corners & ImDrawCornerFlags_Right) == ImDrawCornerFlags_Right) ? 0.5f : 1.0f) - 1.0f); - if (rounding <= 0.0f || rounding_corners == 0) - { - PathLineTo(a); - PathLineTo(ImVec2(b.x, a.y)); - PathLineTo(b); - PathLineTo(ImVec2(a.x, b.y)); - } - else - { - const float rounding_tl = (rounding_corners & ImDrawCornerFlags_TopLeft) ? rounding : 0.0f; - const float rounding_tr = (rounding_corners & ImDrawCornerFlags_TopRight) ? rounding : 0.0f; - const float rounding_br = (rounding_corners & ImDrawCornerFlags_BotRight) ? rounding : 0.0f; - const float rounding_bl = (rounding_corners & ImDrawCornerFlags_BotLeft) ? rounding : 0.0f; - PathArcToFast(ImVec2(a.x + rounding_tl, a.y + rounding_tl), rounding_tl, 6, 9); - PathArcToFast(ImVec2(b.x - rounding_tr, a.y + rounding_tr), rounding_tr, 9, 12); - PathArcToFast(ImVec2(b.x - rounding_br, b.y - rounding_br), rounding_br, 0, 3); - PathArcToFast(ImVec2(a.x + rounding_bl, b.y - rounding_bl), rounding_bl, 3, 6); - } + if (rounding <= 0.0f || rounding_corners == 0) + { + PathLineTo(a); + PathLineTo(ImVec2(b.x, a.y)); + PathLineTo(b); + PathLineTo(ImVec2(a.x, b.y)); + } + else + { + const float rounding_tl = (rounding_corners & ImDrawCornerFlags_TopLeft) ? rounding : 0.0f; + const float rounding_tr = (rounding_corners & ImDrawCornerFlags_TopRight) ? rounding : 0.0f; + const float rounding_br = (rounding_corners & ImDrawCornerFlags_BotRight) ? rounding : 0.0f; + const float rounding_bl = (rounding_corners & ImDrawCornerFlags_BotLeft) ? rounding : 0.0f; + PathArcToFast(ImVec2(a.x + rounding_tl, a.y + rounding_tl), rounding_tl, 6, 9); + PathArcToFast(ImVec2(b.x - rounding_tr, a.y + rounding_tr), rounding_tr, 9, 12); + PathArcToFast(ImVec2(b.x - rounding_br, b.y - rounding_br), rounding_br, 0, 3); + PathArcToFast(ImVec2(a.x + rounding_bl, b.y - rounding_bl), rounding_bl, 3, 6); + } } void ImDrawList::AddLine(const ImVec2& a, const ImVec2& b, ImU32 col, float thickness) { - if ((col & IM_COL32_A_MASK) == 0) - return; - PathLineTo(a + ImVec2(0.5f,0.5f)); - PathLineTo(b + ImVec2(0.5f,0.5f)); - PathStroke(col, false, thickness); + if ((col & IM_COL32_A_MASK) == 0) + return; + PathLineTo(a + ImVec2(0.5f, 0.5f)); + PathLineTo(b + ImVec2(0.5f, 0.5f)); + PathStroke(col, false, thickness); } // a: upper-left, b: lower-right. we don't render 1 px sized rectangles properly. void ImDrawList::AddRect(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners_flags, float thickness) { - if ((col & IM_COL32_A_MASK) == 0) - return; - PathRect(a + ImVec2(0.5f,0.5f), b - ImVec2(0.5f,0.5f), rounding, rounding_corners_flags); - PathStroke(col, true, thickness); + if ((col & IM_COL32_A_MASK) == 0) + return; + PathRect(a + ImVec2(0.5f, 0.5f), b - ImVec2(0.5f, 0.5f), rounding, rounding_corners_flags); + PathStroke(col, true, thickness); } void ImDrawList::AddRectFilled(const ImVec2& a, const ImVec2& b, ImU32 col, float rounding, int rounding_corners_flags) { - if ((col & IM_COL32_A_MASK) == 0) - return; - if (rounding > 0.0f) - { - PathRect(a, b, rounding, rounding_corners_flags); - PathFillConvex(col); - } - else - { - PrimReserve(6, 4); - PrimRect(a, b, col); - } + if ((col & IM_COL32_A_MASK) == 0) + return; + if (rounding > 0.0f) + { + PathRect(a, b, rounding, rounding_corners_flags); + PathFillConvex(col); + } + else + { + PrimReserve(6, 4); + PrimRect(a, b, col); + } } void ImDrawList::AddRectFilledMultiColor(const ImVec2& a, const ImVec2& c, ImU32 col_upr_left, ImU32 col_upr_right, ImU32 col_bot_right, ImU32 col_bot_left) { - if (((col_upr_left | col_upr_right | col_bot_right | col_bot_left) & IM_COL32_A_MASK) == 0) - return; + if (((col_upr_left | col_upr_right | col_bot_right | col_bot_left) & IM_COL32_A_MASK) == 0) + return; - const ImVec2 uv = _Data->TexUvWhitePixel; - PrimReserve(6, 4); - PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+1)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+2)); - PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+2)); PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx+3)); - PrimWriteVtx(a, uv, col_upr_left); - PrimWriteVtx(ImVec2(c.x, a.y), uv, col_upr_right); - PrimWriteVtx(c, uv, col_bot_right); - PrimWriteVtx(ImVec2(a.x, c.y), uv, col_bot_left); + const ImVec2 uv = _Data->TexUvWhitePixel; + PrimReserve(6, 4); + PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx)); + PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx + 1)); + PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx + 2)); + PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx)); + PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx + 2)); + PrimWriteIdx((ImDrawIdx)(_VtxCurrentIdx + 3)); + PrimWriteVtx(a, uv, col_upr_left); + PrimWriteVtx(ImVec2(c.x, a.y), uv, col_upr_right); + PrimWriteVtx(c, uv, col_bot_right); + PrimWriteVtx(ImVec2(a.x, c.y), uv, col_bot_left); } void ImDrawList::AddQuad(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col, float thickness) { - if ((col & IM_COL32_A_MASK) == 0) - return; + if ((col & IM_COL32_A_MASK) == 0) + return; - PathLineTo(a); - PathLineTo(b); - PathLineTo(c); - PathLineTo(d); - PathStroke(col, true, thickness); + PathLineTo(a); + PathLineTo(b); + PathLineTo(c); + PathLineTo(d); + PathStroke(col, true, thickness); } void ImDrawList::AddQuadFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, ImU32 col) { - if ((col & IM_COL32_A_MASK) == 0) - return; + if ((col & IM_COL32_A_MASK) == 0) + return; - PathLineTo(a); - PathLineTo(b); - PathLineTo(c); - PathLineTo(d); - PathFillConvex(col); + PathLineTo(a); + PathLineTo(b); + PathLineTo(c); + PathLineTo(d); + PathFillConvex(col); } void ImDrawList::AddTriangle(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col, float thickness) { - if ((col & IM_COL32_A_MASK) == 0) - return; + if ((col & IM_COL32_A_MASK) == 0) + return; - PathLineTo(a); - PathLineTo(b); - PathLineTo(c); - PathStroke(col, true, thickness); + PathLineTo(a); + PathLineTo(b); + PathLineTo(c); + PathStroke(col, true, thickness); } void ImDrawList::AddTriangleFilled(const ImVec2& a, const ImVec2& b, const ImVec2& c, ImU32 col) { - if ((col & IM_COL32_A_MASK) == 0) - return; + if ((col & IM_COL32_A_MASK) == 0) + return; - PathLineTo(a); - PathLineTo(b); - PathLineTo(c); - PathFillConvex(col); + PathLineTo(a); + PathLineTo(b); + PathLineTo(c); + PathFillConvex(col); } void ImDrawList::AddCircle(const ImVec2& centre, float radius, ImU32 col, int num_segments, float thickness) { - if ((col & IM_COL32_A_MASK) == 0) - return; + if ((col & IM_COL32_A_MASK) == 0) + return; - const float a_max = IM_PI*2.0f * ((float)num_segments - 1.0f) / (float)num_segments; - PathArcTo(centre, radius-0.5f, 0.0f, a_max, num_segments); - PathStroke(col, true, thickness); + const float a_max = IM_PI * 2.0f * ((float)num_segments - 1.0f) / (float)num_segments; + PathArcTo(centre, radius - 0.5f, 0.0f, a_max, num_segments); + PathStroke(col, true, thickness); } void ImDrawList::AddCircleFilled(const ImVec2& centre, float radius, ImU32 col, int num_segments) { - if ((col & IM_COL32_A_MASK) == 0) - return; + if ((col & IM_COL32_A_MASK) == 0) + return; - const float a_max = IM_PI*2.0f * ((float)num_segments - 1.0f) / (float)num_segments; - PathArcTo(centre, radius, 0.0f, a_max, num_segments); - PathFillConvex(col); + const float a_max = IM_PI * 2.0f * ((float)num_segments - 1.0f) / (float)num_segments; + PathArcTo(centre, radius, 0.0f, a_max, num_segments); + PathFillConvex(col); } void ImDrawList::AddBezierCurve(const ImVec2& pos0, const ImVec2& cp0, const ImVec2& cp1, const ImVec2& pos1, ImU32 col, float thickness, int num_segments) { - if ((col & IM_COL32_A_MASK) == 0) - return; + if ((col & IM_COL32_A_MASK) == 0) + return; - PathLineTo(pos0); - PathBezierCurveTo(cp0, cp1, pos1, num_segments); - PathStroke(col, false, thickness); + PathLineTo(pos0); + PathBezierCurveTo(cp0, cp1, pos1, num_segments); + PathStroke(col, false, thickness); } void ImDrawList::AddText(const ImFont* font, float font_size, const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end, float wrap_width, const ImVec4* cpu_fine_clip_rect) { - if ((col & IM_COL32_A_MASK) == 0) - return; + if ((col & IM_COL32_A_MASK) == 0) + return; - if (text_end == NULL) - text_end = text_begin + strlen(text_begin); - if (text_begin == text_end) - return; + if (text_end == NULL) + text_end = text_begin + strlen(text_begin); + if (text_begin == text_end) + return; - // Pull default font/size from the shared ImDrawListSharedData instance - if (font == NULL) - font = _Data->Font; - if (font_size == 0.0f) - font_size = _Data->FontSize; + // Pull default font/size from the shared ImDrawListSharedData instance + if (font == NULL) + font = _Data->Font; + if (font_size == 0.0f) + font_size = _Data->FontSize; - IM_ASSERT(font->ContainerAtlas->TexID == _TextureIdStack.back()); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font. + IM_ASSERT(font->ContainerAtlas->TexID == _TextureIdStack.back()); // Use high-level ImGui::PushFont() or low-level ImDrawList::PushTextureId() to change font. - ImVec4 clip_rect = _ClipRectStack.back(); - if (cpu_fine_clip_rect) - { - clip_rect.x = ImMax(clip_rect.x, cpu_fine_clip_rect->x); - clip_rect.y = ImMax(clip_rect.y, cpu_fine_clip_rect->y); - clip_rect.z = ImMin(clip_rect.z, cpu_fine_clip_rect->z); - clip_rect.w = ImMin(clip_rect.w, cpu_fine_clip_rect->w); - } - font->RenderText(this, font_size, pos, col, clip_rect, text_begin, text_end, wrap_width, cpu_fine_clip_rect != NULL); + ImVec4 clip_rect = _ClipRectStack.back(); + if (cpu_fine_clip_rect) + { + clip_rect.x = ImMax(clip_rect.x, cpu_fine_clip_rect->x); + clip_rect.y = ImMax(clip_rect.y, cpu_fine_clip_rect->y); + clip_rect.z = ImMin(clip_rect.z, cpu_fine_clip_rect->z); + clip_rect.w = ImMin(clip_rect.w, cpu_fine_clip_rect->w); + } + font->RenderText(this, font_size, pos, col, clip_rect, text_begin, text_end, wrap_width, cpu_fine_clip_rect != NULL); } void ImDrawList::AddText(const ImVec2& pos, ImU32 col, const char* text_begin, const char* text_end) { - AddText(NULL, 0.0f, pos, col, text_begin, text_end); + AddText(NULL, 0.0f, pos, col, text_begin, text_end); } void ImDrawList::AddImage(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col) { - if ((col & IM_COL32_A_MASK) == 0) - return; + if ((col & IM_COL32_A_MASK) == 0) + return; - const bool push_texture_id = _TextureIdStack.empty() || user_texture_id != _TextureIdStack.back(); - if (push_texture_id) - PushTextureID(user_texture_id); + const bool push_texture_id = _TextureIdStack.empty() || user_texture_id != _TextureIdStack.back(); + if (push_texture_id) + PushTextureID(user_texture_id); - PrimReserve(6, 4); - PrimRectUV(a, b, uv_a, uv_b, col); + PrimReserve(6, 4); + PrimRectUV(a, b, uv_a, uv_b, col); - if (push_texture_id) - PopTextureID(); + if (push_texture_id) + PopTextureID(); } void ImDrawList::AddImageQuad(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& d, const ImVec2& uv_a, const ImVec2& uv_b, const ImVec2& uv_c, const ImVec2& uv_d, ImU32 col) { - if ((col & IM_COL32_A_MASK) == 0) - return; + if ((col & IM_COL32_A_MASK) == 0) + return; - const bool push_texture_id = _TextureIdStack.empty() || user_texture_id != _TextureIdStack.back(); - if (push_texture_id) - PushTextureID(user_texture_id); + const bool push_texture_id = _TextureIdStack.empty() || user_texture_id != _TextureIdStack.back(); + if (push_texture_id) + PushTextureID(user_texture_id); - PrimReserve(6, 4); - PrimQuadUV(a, b, c, d, uv_a, uv_b, uv_c, uv_d, col); + PrimReserve(6, 4); + PrimQuadUV(a, b, c, d, uv_a, uv_b, uv_c, uv_d, col); - if (push_texture_id) - PopTextureID(); + if (push_texture_id) + PopTextureID(); } void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, ImU32 col, float rounding, int rounding_corners) { - if ((col & IM_COL32_A_MASK) == 0) - return; + if ((col & IM_COL32_A_MASK) == 0) + return; - if (rounding <= 0.0f || (rounding_corners & ImDrawCornerFlags_All) == 0) - { - AddImage(user_texture_id, a, b, uv_a, uv_b, col); - return; - } + if (rounding <= 0.0f || (rounding_corners & ImDrawCornerFlags_All) == 0) + { + AddImage(user_texture_id, a, b, uv_a, uv_b, col); + return; + } - const bool push_texture_id = _TextureIdStack.empty() || user_texture_id != _TextureIdStack.back(); - if (push_texture_id) - PushTextureID(user_texture_id); + const bool push_texture_id = _TextureIdStack.empty() || user_texture_id != _TextureIdStack.back(); + if (push_texture_id) + PushTextureID(user_texture_id); - int vert_start_idx = VtxBuffer.Size; - PathRect(a, b, rounding, rounding_corners); - PathFillConvex(col); - int vert_end_idx = VtxBuffer.Size; - ImGui::ShadeVertsLinearUV(VtxBuffer.Data + vert_start_idx, VtxBuffer.Data + vert_end_idx, a, b, uv_a, uv_b, true); + int vert_start_idx = VtxBuffer.Size; + PathRect(a, b, rounding, rounding_corners); + PathFillConvex(col); + int vert_end_idx = VtxBuffer.Size; + ImGui::ShadeVertsLinearUV(VtxBuffer.Data + vert_start_idx, VtxBuffer.Data + vert_end_idx, a, b, uv_a, uv_b, true); - if (push_texture_id) - PopTextureID(); + if (push_texture_id) + PopTextureID(); } //----------------------------------------------------------------------------- @@ -1191,34 +1304,34 @@ void ImDrawList::AddImageRounded(ImTextureID user_texture_id, const ImVec2& a, c // For backward compatibility: convert all buffers from indexed to de-indexed, in case you cannot render indexed. Note: this is slow and most likely a waste of resources. Always prefer indexed rendering! void ImDrawData::DeIndexAllBuffers() { - ImVector new_vtx_buffer; - TotalVtxCount = TotalIdxCount = 0; - for (int i = 0; i < CmdListsCount; i++) - { - ImDrawList* cmd_list = CmdLists[i]; - if (cmd_list->IdxBuffer.empty()) - continue; - new_vtx_buffer.resize(cmd_list->IdxBuffer.Size); - for (int j = 0; j < cmd_list->IdxBuffer.Size; j++) - new_vtx_buffer[j] = cmd_list->VtxBuffer[cmd_list->IdxBuffer[j]]; - cmd_list->VtxBuffer.swap(new_vtx_buffer); - cmd_list->IdxBuffer.resize(0); - TotalVtxCount += cmd_list->VtxBuffer.Size; - } + ImVector new_vtx_buffer; + TotalVtxCount = TotalIdxCount = 0; + for (int i = 0; i < CmdListsCount; i++) + { + ImDrawList* cmd_list = CmdLists[i]; + if (cmd_list->IdxBuffer.empty()) + continue; + new_vtx_buffer.resize(cmd_list->IdxBuffer.Size); + for (int j = 0; j < cmd_list->IdxBuffer.Size; j++) + new_vtx_buffer[j] = cmd_list->VtxBuffer[cmd_list->IdxBuffer[j]]; + cmd_list->VtxBuffer.swap(new_vtx_buffer); + cmd_list->IdxBuffer.resize(0); + TotalVtxCount += cmd_list->VtxBuffer.Size; + } } // Helper to scale the ClipRect field of each ImDrawCmd. Use if your final output buffer is at a different scale than ImGui expects, or if there is a difference between your window resolution and framebuffer resolution. void ImDrawData::ScaleClipRects(const ImVec2& scale) { - for (int i = 0; i < CmdListsCount; i++) - { - ImDrawList* cmd_list = CmdLists[i]; - for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) - { - ImDrawCmd* cmd = &cmd_list->CmdBuffer[cmd_i]; - cmd->ClipRect = ImVec4(cmd->ClipRect.x * scale.x, cmd->ClipRect.y * scale.y, cmd->ClipRect.z * scale.x, cmd->ClipRect.w * scale.y); - } - } + for (int i = 0; i < CmdListsCount; i++) + { + ImDrawList* cmd_list = CmdLists[i]; + for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) + { + ImDrawCmd* cmd = &cmd_list->CmdBuffer[cmd_i]; + cmd->ClipRect = ImVec4(cmd->ClipRect.x * scale.x, cmd->ClipRect.y * scale.y, cmd->ClipRect.z * scale.x, cmd->ClipRect.w * scale.y); + } + } } //----------------------------------------------------------------------------- @@ -1228,58 +1341,58 @@ void ImDrawData::ScaleClipRects(const ImVec2& scale) // Generic linear color gradient, write to RGB fields, leave A untouched. void ImGui::ShadeVertsLinearColorGradientKeepAlpha(ImDrawVert* vert_start, ImDrawVert* vert_end, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1) { - ImVec2 gradient_extent = gradient_p1 - gradient_p0; - float gradient_inv_length2 = 1.0f / ImLengthSqr(gradient_extent); - for (ImDrawVert* vert = vert_start; vert < vert_end; vert++) - { - float d = ImDot(vert->pos - gradient_p0, gradient_extent); - float t = ImClamp(d * gradient_inv_length2, 0.0f, 1.0f); - int r = ImLerp((int)(col0 >> IM_COL32_R_SHIFT) & 0xFF, (int)(col1 >> IM_COL32_R_SHIFT) & 0xFF, t); - int g = ImLerp((int)(col0 >> IM_COL32_G_SHIFT) & 0xFF, (int)(col1 >> IM_COL32_G_SHIFT) & 0xFF, t); - int b = ImLerp((int)(col0 >> IM_COL32_B_SHIFT) & 0xFF, (int)(col1 >> IM_COL32_B_SHIFT) & 0xFF, t); - vert->col = (r << IM_COL32_R_SHIFT) | (g << IM_COL32_G_SHIFT) | (b << IM_COL32_B_SHIFT) | (vert->col & IM_COL32_A_MASK); - } + ImVec2 gradient_extent = gradient_p1 - gradient_p0; + float gradient_inv_length2 = 1.0f / ImLengthSqr(gradient_extent); + for (ImDrawVert* vert = vert_start; vert < vert_end; vert++) + { + float d = ImDot(vert->pos - gradient_p0, gradient_extent); + float t = ImClamp(d * gradient_inv_length2, 0.0f, 1.0f); + int r = ImLerp((int)(col0 >> IM_COL32_R_SHIFT) & 0xFF, (int)(col1 >> IM_COL32_R_SHIFT) & 0xFF, t); + int g = ImLerp((int)(col0 >> IM_COL32_G_SHIFT) & 0xFF, (int)(col1 >> IM_COL32_G_SHIFT) & 0xFF, t); + int b = ImLerp((int)(col0 >> IM_COL32_B_SHIFT) & 0xFF, (int)(col1 >> IM_COL32_B_SHIFT) & 0xFF, t); + vert->col = (r << IM_COL32_R_SHIFT) | (g << IM_COL32_G_SHIFT) | (b << IM_COL32_B_SHIFT) | (vert->col & IM_COL32_A_MASK); + } } // Scan and shade backward from the end of given vertices. Assume vertices are text only (= vert_start..vert_end going left to right) so we can break as soon as we are out the gradient bounds. void ImGui::ShadeVertsLinearAlphaGradientForLeftToRightText(ImDrawVert* vert_start, ImDrawVert* vert_end, float gradient_p0_x, float gradient_p1_x) { - float gradient_extent_x = gradient_p1_x - gradient_p0_x; - float gradient_inv_length2 = 1.0f / (gradient_extent_x * gradient_extent_x); - int full_alpha_count = 0; - for (ImDrawVert* vert = vert_end - 1; vert >= vert_start; vert--) - { - float d = (vert->pos.x - gradient_p0_x) * (gradient_extent_x); - float alpha_mul = 1.0f - ImClamp(d * gradient_inv_length2, 0.0f, 1.0f); - if (alpha_mul >= 1.0f && ++full_alpha_count > 2) - return; // Early out - int a = (int)(((vert->col >> IM_COL32_A_SHIFT) & 0xFF) * alpha_mul); - vert->col = (vert->col & ~IM_COL32_A_MASK) | (a << IM_COL32_A_SHIFT); - } + float gradient_extent_x = gradient_p1_x - gradient_p0_x; + float gradient_inv_length2 = 1.0f / (gradient_extent_x * gradient_extent_x); + int full_alpha_count = 0; + for (ImDrawVert* vert = vert_end - 1; vert >= vert_start; vert--) + { + float d = (vert->pos.x - gradient_p0_x) * (gradient_extent_x); + float alpha_mul = 1.0f - ImClamp(d * gradient_inv_length2, 0.0f, 1.0f); + if (alpha_mul >= 1.0f && ++full_alpha_count > 2) + return; // Early out + int a = (int)(((vert->col >> IM_COL32_A_SHIFT) & 0xFF) * alpha_mul); + vert->col = (vert->col & ~IM_COL32_A_MASK) | (a << IM_COL32_A_SHIFT); + } } // Distribute UV over (a, b) rectangle void ImGui::ShadeVertsLinearUV(ImDrawVert* vert_start, ImDrawVert* vert_end, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, bool clamp) { - const ImVec2 size = b - a; - const ImVec2 uv_size = uv_b - uv_a; - const ImVec2 scale = ImVec2( - size.x != 0.0f ? (uv_size.x / size.x) : 0.0f, - size.y != 0.0f ? (uv_size.y / size.y) : 0.0f); + const ImVec2 size = b - a; + const ImVec2 uv_size = uv_b - uv_a; + const ImVec2 scale = ImVec2( + size.x != 0.0f ? (uv_size.x / size.x) : 0.0f, + size.y != 0.0f ? (uv_size.y / size.y) : 0.0f); - if (clamp) - { - const ImVec2 min = ImMin(uv_a, uv_b); - const ImVec2 max = ImMax(uv_a, uv_b); + if (clamp) + { + const ImVec2 min = ImMin(uv_a, uv_b); + const ImVec2 max = ImMax(uv_a, uv_b); - for (ImDrawVert* vertex = vert_start; vertex < vert_end; ++vertex) - vertex->uv = ImClamp(uv_a + ImMul(ImVec2(vertex->pos.x, vertex->pos.y) - a, scale), min, max); - } - else - { - for (ImDrawVert* vertex = vert_start; vertex < vert_end; ++vertex) - vertex->uv = uv_a + ImMul(ImVec2(vertex->pos.x, vertex->pos.y) - a, scale); - } + for (ImDrawVert* vertex = vert_start; vertex < vert_end; ++vertex) + vertex->uv = ImClamp(uv_a + ImMul(ImVec2(vertex->pos.x, vertex->pos.y) - a, scale), min, max); + } + else + { + for (ImDrawVert* vertex = vert_start; vertex < vert_end; ++vertex) + vertex->uv = uv_a + ImMul(ImVec2(vertex->pos.x, vertex->pos.y) - a, scale); + } } //----------------------------------------------------------------------------- @@ -1288,22 +1401,22 @@ void ImGui::ShadeVertsLinearUV(ImDrawVert* vert_start, ImDrawVert* vert_end, con ImFontConfig::ImFontConfig() { - FontData = NULL; - FontDataSize = 0; - FontDataOwnedByAtlas = true; - FontNo = 0; - SizePixels = 0.0f; - OversampleH = 3; - OversampleV = 1; - PixelSnapH = false; - GlyphExtraSpacing = ImVec2(0.0f, 0.0f); - GlyphOffset = ImVec2(0.0f, 0.0f); - GlyphRanges = NULL; - MergeMode = false; - RasterizerFlags = 0x00; - RasterizerMultiply = 1.0f; - memset(Name, 0, sizeof(Name)); - DstFont = NULL; + FontData = NULL; + FontDataSize = 0; + FontDataOwnedByAtlas = true; + FontNo = 0; + SizePixels = 0.0f; + OversampleH = 3; + OversampleV = 1; + PixelSnapH = false; + GlyphExtraSpacing = ImVec2(0.0f, 0.0f); + GlyphOffset = ImVec2(0.0f, 0.0f); + GlyphRanges = NULL; + MergeMode = false; + RasterizerFlags = 0x00; + RasterizerMultiply = 1.0f; + memset(Name, 0, sizeof(Name)); + DstFont = NULL; } //----------------------------------------------------------------------------- @@ -1313,778 +1426,2713 @@ ImFontConfig::ImFontConfig() // A work of art lies ahead! (. = white layer, X = black layer, others are blank) // The white texels on the top left are the ones we'll use everywhere in ImGui to render filled shapes. const int FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF = 90; -const int FONT_ATLAS_DEFAULT_TEX_DATA_H = 27; +const int FONT_ATLAS_DEFAULT_TEX_DATA_H = 27; const unsigned int FONT_ATLAS_DEFAULT_TEX_DATA_ID = 0x80000000; static const char FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * FONT_ATLAS_DEFAULT_TEX_DATA_H + 1] = -{ - "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX" - "..- -X.....X- X.X - X.X -X.....X - X.....X" - "--- -XXX.XXX- X...X - X...X -X....X - X....X" - "X - X.X - X.....X - X.....X -X...X - X...X" - "XX - X.X -X.......X- X.......X -X..X.X - X.X..X" - "X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X" - "X..X - X.X - X.X - X.X -XX X.X - X.X XX" - "X...X - X.X - X.X - XX X.X XX - X.X - X.X " - "X....X - X.X - X.X - X.X X.X X.X - X.X - X.X " - "X.....X - X.X - X.X - X..X X.X X..X - X.X - X.X " - "X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.X " - "X.......X - X.X - X.X -X.....................X- X.X X.X-X.X X.X " - "X........X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X..X-X..X.X " - "X.........X -XXX.XXX- X.X - X..X X.X X..X - X...X-X...X " - "X..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X " - "X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X " - "X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX " - "X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------" - "X.X X..X - -X.......X- X.......X - XX XX - " - "XX X..X - - X.....X - X.....X - X.X X.X - " - " X..X - X...X - X...X - X..X X..X - " - " XX - X.X - X.X - X...XXXXXXXXXXXXX...X - " - "------------ - X - X -X.....................X- " - " ----------------------------------- X...XXXXXXXXXXXXX...X - " - " - X..X X..X - " - " - X.X X.X - " - " - XX XX - " -}; + { + "..- -XXXXXXX- X - X -XXXXXXX - XXXXXXX" + "..- -X.....X- X.X - X.X -X.....X - X.....X" + "--- -XXX.XXX- X...X - X...X -X....X - X....X" + "X - X.X - X.....X - X.....X -X...X - X...X" + "XX - X.X -X.......X- X.......X -X..X.X - X.X..X" + "X.X - X.X -XXXX.XXXX- XXXX.XXXX -X.X X.X - X.X X.X" + "X..X - X.X - X.X - X.X -XX X.X - X.X XX" + "X...X - X.X - X.X - XX X.X XX - X.X - X.X " + "X....X - X.X - X.X - X.X X.X X.X - X.X - X.X " + "X.....X - X.X - X.X - X..X X.X X..X - X.X - X.X " + "X......X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X XX-XX X.X " + "X.......X - X.X - X.X -X.....................X- X.X X.X-X.X X.X " + "X........X - X.X - X.X - X...XXXXXX.XXXXXX...X - X.X..X-X..X.X " + "X.........X -XXX.XXX- X.X - X..X X.X X..X - X...X-X...X " + "X..........X-X.....X- X.X - X.X X.X X.X - X....X-X....X " + "X......XXXXX-XXXXXXX- X.X - XX X.X XX - X.....X-X.....X " + "X...X..X --------- X.X - X.X - XXXXXXX-XXXXXXX " + "X..X X..X - -XXXX.XXXX- XXXX.XXXX ------------------------------------" + "X.X X..X - -X.......X- X.......X - XX XX - " + "XX X..X - - X.....X - X.....X - X.X X.X - " + " X..X - X...X - X...X - X..X X..X - " + " XX - X.X - X.X - X...XXXXXXXXXXXXX...X - " + "------------ - X - X -X.....................X- " + " ----------------------------------- X...XXXXXXXXXXXXX...X - " + " - X..X X..X - " + " - X.X X.X - " + " - XX XX - "}; static const ImVec2 FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[ImGuiMouseCursor_Count_][3] = -{ - // Pos ........ Size ......... Offset ...... - { ImVec2(0,3), ImVec2(12,19), ImVec2( 0, 0) }, // ImGuiMouseCursor_Arrow - { ImVec2(13,0), ImVec2(7,16), ImVec2( 4, 8) }, // ImGuiMouseCursor_TextInput - { ImVec2(31,0), ImVec2(23,23), ImVec2(11,11) }, // ImGuiMouseCursor_ResizeAll - { ImVec2(21,0), ImVec2( 9,23), ImVec2( 5,11) }, // ImGuiMouseCursor_ResizeNS - { ImVec2(55,18),ImVec2(23, 9), ImVec2(11, 5) }, // ImGuiMouseCursor_ResizeEW - { ImVec2(73,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNESW - { ImVec2(55,0), ImVec2(17,17), ImVec2( 9, 9) }, // ImGuiMouseCursor_ResizeNWSE + { + // Pos ........ Size ......... Offset ...... + {ImVec2(0, 3), ImVec2(12, 19), ImVec2(0, 0)}, // ImGuiMouseCursor_Arrow + {ImVec2(13, 0), ImVec2(7, 16), ImVec2(4, 8)}, // ImGuiMouseCursor_TextInput + {ImVec2(31, 0), ImVec2(23, 23), ImVec2(11, 11)}, // ImGuiMouseCursor_ResizeAll + {ImVec2(21, 0), ImVec2(9, 23), ImVec2(5, 11)}, // ImGuiMouseCursor_ResizeNS + {ImVec2(55, 18), ImVec2(23, 9), ImVec2(11, 5)}, // ImGuiMouseCursor_ResizeEW + {ImVec2(73, 0), ImVec2(17, 17), ImVec2(9, 9)}, // ImGuiMouseCursor_ResizeNESW + {ImVec2(55, 0), ImVec2(17, 17), ImVec2(9, 9)}, // ImGuiMouseCursor_ResizeNWSE }; ImFontAtlas::ImFontAtlas() { - Flags = 0x00; - TexID = NULL; - TexDesiredWidth = 0; - TexGlyphPadding = 1; + Flags = 0x00; + TexID = NULL; + TexDesiredWidth = 0; + TexGlyphPadding = 1; - TexPixelsAlpha8 = NULL; - TexPixelsRGBA32 = NULL; - TexWidth = TexHeight = 0; - TexUvScale = ImVec2(0.0f, 0.0f); - TexUvWhitePixel = ImVec2(0.0f, 0.0f); - for (int n = 0; n < IM_ARRAYSIZE(CustomRectIds); n++) - CustomRectIds[n] = -1; + TexPixelsAlpha8 = NULL; + TexPixelsRGBA32 = NULL; + TexWidth = TexHeight = 0; + TexUvScale = ImVec2(0.0f, 0.0f); + TexUvWhitePixel = ImVec2(0.0f, 0.0f); + for (int n = 0; n < IM_ARRAYSIZE(CustomRectIds); n++) + CustomRectIds[n] = -1; } ImFontAtlas::~ImFontAtlas() { - Clear(); + Clear(); } -void ImFontAtlas::ClearInputData() +void ImFontAtlas::ClearInputData() { - for (int i = 0; i < ConfigData.Size; i++) - if (ConfigData[i].FontData && ConfigData[i].FontDataOwnedByAtlas) - { - ImGui::MemFree(ConfigData[i].FontData); - ConfigData[i].FontData = NULL; - } + for (int i = 0; i < ConfigData.Size; i++) + if (ConfigData[i].FontData && ConfigData[i].FontDataOwnedByAtlas) + { + ImGui::MemFree(ConfigData[i].FontData); + ConfigData[i].FontData = NULL; + } - // When clearing this we lose access to the font name and other information used to build the font. - for (int i = 0; i < Fonts.Size; i++) - if (Fonts[i]->ConfigData >= ConfigData.Data && Fonts[i]->ConfigData < ConfigData.Data + ConfigData.Size) - { - Fonts[i]->ConfigData = NULL; - Fonts[i]->ConfigDataCount = 0; - } - ConfigData.clear(); - CustomRects.clear(); - for (int n = 0; n < IM_ARRAYSIZE(CustomRectIds); n++) - CustomRectIds[n] = -1; + // When clearing this we lose access to the font name and other information used to build the font. + for (int i = 0; i < Fonts.Size; i++) + if (Fonts[i]->ConfigData >= ConfigData.Data && Fonts[i]->ConfigData < ConfigData.Data + ConfigData.Size) + { + Fonts[i]->ConfigData = NULL; + Fonts[i]->ConfigDataCount = 0; + } + ConfigData.clear(); + CustomRects.clear(); + for (int n = 0; n < IM_ARRAYSIZE(CustomRectIds); n++) + CustomRectIds[n] = -1; } -void ImFontAtlas::ClearTexData() +void ImFontAtlas::ClearTexData() { - if (TexPixelsAlpha8) - ImGui::MemFree(TexPixelsAlpha8); - if (TexPixelsRGBA32) - ImGui::MemFree(TexPixelsRGBA32); - TexPixelsAlpha8 = NULL; - TexPixelsRGBA32 = NULL; + if (TexPixelsAlpha8) + ImGui::MemFree(TexPixelsAlpha8); + if (TexPixelsRGBA32) + ImGui::MemFree(TexPixelsRGBA32); + TexPixelsAlpha8 = NULL; + TexPixelsRGBA32 = NULL; } -void ImFontAtlas::ClearFonts() +void ImFontAtlas::ClearFonts() { - for (int i = 0; i < Fonts.Size; i++) - IM_DELETE(Fonts[i]); - Fonts.clear(); + for (int i = 0; i < Fonts.Size; i++) + IM_DELETE(Fonts[i]); + Fonts.clear(); } -void ImFontAtlas::Clear() +void ImFontAtlas::Clear() { - ClearInputData(); - ClearTexData(); - ClearFonts(); + ClearInputData(); + ClearTexData(); + ClearFonts(); } -void ImFontAtlas::GetTexDataAsAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel) +void ImFontAtlas::GetTexDataAsAlpha8(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel) { - // Build atlas on demand - if (TexPixelsAlpha8 == NULL) - { - if (ConfigData.empty()) - AddFontDefault(); - Build(); - } + // Build atlas on demand + if (TexPixelsAlpha8 == NULL) + { + if (ConfigData.empty()) + AddFontDefault(); + Build(); + } - *out_pixels = TexPixelsAlpha8; - if (out_width) *out_width = TexWidth; - if (out_height) *out_height = TexHeight; - if (out_bytes_per_pixel) *out_bytes_per_pixel = 1; + *out_pixels = TexPixelsAlpha8; + if (out_width) *out_width = TexWidth; + if (out_height) *out_height = TexHeight; + if (out_bytes_per_pixel) *out_bytes_per_pixel = 1; } -void ImFontAtlas::GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel) +void ImFontAtlas::GetTexDataAsRGBA32(unsigned char** out_pixels, int* out_width, int* out_height, int* out_bytes_per_pixel) { - // Convert to RGBA32 format on demand - // Although it is likely to be the most commonly used format, our font rendering is 1 channel / 8 bpp - if (!TexPixelsRGBA32) - { - unsigned char* pixels = NULL; - GetTexDataAsAlpha8(&pixels, NULL, NULL); - if (pixels) - { - TexPixelsRGBA32 = (unsigned int*)ImGui::MemAlloc((size_t)(TexWidth * TexHeight * 4)); - const unsigned char* src = pixels; - unsigned int* dst = TexPixelsRGBA32; - for (int n = TexWidth * TexHeight; n > 0; n--) - *dst++ = IM_COL32(255, 255, 255, (unsigned int)(*src++)); - } - } + // Convert to RGBA32 format on demand + // Although it is likely to be the most commonly used format, our font rendering is 1 channel / 8 bpp + if (!TexPixelsRGBA32) + { + unsigned char* pixels = NULL; + GetTexDataAsAlpha8(&pixels, NULL, NULL); + if (pixels) + { + TexPixelsRGBA32 = (unsigned int*)ImGui::MemAlloc((size_t)(TexWidth * TexHeight * 4)); + const unsigned char* src = pixels; + unsigned int* dst = TexPixelsRGBA32; + for (int n = TexWidth * TexHeight; n > 0; n--) + *dst++ = IM_COL32(255, 255, 255, (unsigned int)(*src++)); + } + } - *out_pixels = (unsigned char*)TexPixelsRGBA32; - if (out_width) *out_width = TexWidth; - if (out_height) *out_height = TexHeight; - if (out_bytes_per_pixel) *out_bytes_per_pixel = 4; + *out_pixels = (unsigned char*)TexPixelsRGBA32; + if (out_width) *out_width = TexWidth; + if (out_height) *out_height = TexHeight; + if (out_bytes_per_pixel) *out_bytes_per_pixel = 4; } ImFont* ImFontAtlas::AddFont(const ImFontConfig* font_cfg) { - IM_ASSERT(font_cfg->FontData != NULL && font_cfg->FontDataSize > 0); - IM_ASSERT(font_cfg->SizePixels > 0.0f); + IM_ASSERT(font_cfg->FontData != NULL && font_cfg->FontDataSize > 0); + IM_ASSERT(font_cfg->SizePixels > 0.0f); - // Create new font - if (!font_cfg->MergeMode) - Fonts.push_back(IM_NEW(ImFont)); - else - IM_ASSERT(!Fonts.empty()); // When using MergeMode make sure that a font has already been added before. You can use ImGui::GetIO().Fonts->AddFontDefault() to add the default imgui font. + // Create new font + if (!font_cfg->MergeMode) + Fonts.push_back(IM_NEW(ImFont)); + else + IM_ASSERT(!Fonts.empty()); // When using MergeMode make sure that a font has already been added before. You can use ImGui::GetIO().Fonts->AddFontDefault() to add the default imgui font. - ConfigData.push_back(*font_cfg); - ImFontConfig& new_font_cfg = ConfigData.back(); - if (!new_font_cfg.DstFont) - new_font_cfg.DstFont = Fonts.back(); - if (!new_font_cfg.FontDataOwnedByAtlas) - { - new_font_cfg.FontData = ImGui::MemAlloc(new_font_cfg.FontDataSize); - new_font_cfg.FontDataOwnedByAtlas = true; - memcpy(new_font_cfg.FontData, font_cfg->FontData, (size_t)new_font_cfg.FontDataSize); - } + ConfigData.push_back(*font_cfg); + ImFontConfig& new_font_cfg = ConfigData.back(); + if (!new_font_cfg.DstFont) + new_font_cfg.DstFont = Fonts.back(); + if (!new_font_cfg.FontDataOwnedByAtlas) + { + new_font_cfg.FontData = ImGui::MemAlloc(new_font_cfg.FontDataSize); + new_font_cfg.FontDataOwnedByAtlas = true; + memcpy(new_font_cfg.FontData, font_cfg->FontData, (size_t)new_font_cfg.FontDataSize); + } - // Invalidate texture - ClearTexData(); - return new_font_cfg.DstFont; + // Invalidate texture + ClearTexData(); + return new_font_cfg.DstFont; } // Default font TTF is compressed with stb_compress then base85 encoded (see misc/fonts/binary_to_compressed_c.cpp for encoder) -static unsigned int stb_decompress_length(unsigned char *input); -static unsigned int stb_decompress(unsigned char *output, unsigned char *i, unsigned int length); -static const char* GetDefaultCompressedFontDataTTFBase85(); -static unsigned int Decode85Byte(char c) { return c >= '\\' ? c-36 : c-35; } -static void Decode85(const unsigned char* src, unsigned char* dst) +static unsigned int stb_decompress_length(unsigned char* input); +static unsigned int stb_decompress(unsigned char* output, unsigned char* i, unsigned int length); +static const char* GetDefaultCompressedFontDataTTFBase85(); +static unsigned int Decode85Byte(char c) { return c >= '\\' ? c - 36 : c - 35; } +static void Decode85(const unsigned char* src, unsigned char* dst) { - while (*src) - { - unsigned int tmp = Decode85Byte(src[0]) + 85*(Decode85Byte(src[1]) + 85*(Decode85Byte(src[2]) + 85*(Decode85Byte(src[3]) + 85*Decode85Byte(src[4])))); - dst[0] = ((tmp >> 0) & 0xFF); dst[1] = ((tmp >> 8) & 0xFF); dst[2] = ((tmp >> 16) & 0xFF); dst[3] = ((tmp >> 24) & 0xFF); // We can't assume little-endianness. - src += 5; - dst += 4; - } + while (*src) + { + unsigned int tmp = Decode85Byte(src[0]) + 85 * (Decode85Byte(src[1]) + 85 * (Decode85Byte(src[2]) + 85 * (Decode85Byte(src[3]) + 85 * Decode85Byte(src[4])))); + dst[0] = ((tmp >> 0) & 0xFF); + dst[1] = ((tmp >> 8) & 0xFF); + dst[2] = ((tmp >> 16) & 0xFF); + dst[3] = ((tmp >> 24) & 0xFF); // We can't assume little-endianness. + src += 5; + dst += 4; + } } // Load embedded ProggyClean.ttf at size 13, disable oversampling ImFont* ImFontAtlas::AddFontDefault(const ImFontConfig* font_cfg_template) { - ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); - if (!font_cfg_template) - { - font_cfg.OversampleH = font_cfg.OversampleV = 1; - font_cfg.PixelSnapH = true; - } - if (font_cfg.Name[0] == '\0') strcpy(font_cfg.Name, "ProggyClean.ttf, 13px"); - if (font_cfg.SizePixels <= 0.0f) font_cfg.SizePixels = 13.0f; + ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); + if (!font_cfg_template) + { + font_cfg.OversampleH = font_cfg.OversampleV = 1; + font_cfg.PixelSnapH = true; + } + if (font_cfg.Name[0] == '\0') strcpy(font_cfg.Name, "ProggyClean.ttf, 13px"); + if (font_cfg.SizePixels <= 0.0f) font_cfg.SizePixels = 13.0f; - const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85(); - ImFont* font = AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, font_cfg.SizePixels, &font_cfg, GetGlyphRangesDefault()); - return font; + const char* ttf_compressed_base85 = GetDefaultCompressedFontDataTTFBase85(); + ImFont* font = AddFontFromMemoryCompressedBase85TTF(ttf_compressed_base85, font_cfg.SizePixels, &font_cfg, GetGlyphRangesDefault()); + return font; } ImFont* ImFontAtlas::AddFontFromFileTTF(const char* filename, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges) { - int data_size = 0; - void* data = ImFileLoadToMemory(filename, "rb", &data_size, 0); - if (!data) - { - IM_ASSERT(0); // Could not load file. - return NULL; - } - ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); - if (font_cfg.Name[0] == '\0') - { - // Store a short copy of filename into into the font name for convenience - const char* p; - for (p = filename + strlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) {} - snprintf(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "%s, %.0fpx", p, size_pixels); - } - return AddFontFromMemoryTTF(data, data_size, size_pixels, &font_cfg, glyph_ranges); + int data_size = 0; + void* data = ImFileLoadToMemory(filename, "rb", &data_size, 0); + if (!data) + { + IM_ASSERT(0); // Could not load file. + return NULL; + } + ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); + if (font_cfg.Name[0] == '\0') + { + // Store a short copy of filename into into the font name for convenience + const char* p; + for (p = filename + strlen(filename); p > filename && p[-1] != '/' && p[-1] != '\\'; p--) + { + } + snprintf(font_cfg.Name, IM_ARRAYSIZE(font_cfg.Name), "%s, %.0fpx", p, size_pixels); + } + return AddFontFromMemoryTTF(data, data_size, size_pixels, &font_cfg, glyph_ranges); } // NB: Transfer ownership of 'ttf_data' to ImFontAtlas, unless font_cfg_template->FontDataOwnedByAtlas == false. Owned TTF buffer will be deleted after Build(). ImFont* ImFontAtlas::AddFontFromMemoryTTF(void* ttf_data, int ttf_size, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges) { - ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); - IM_ASSERT(font_cfg.FontData == NULL); - font_cfg.FontData = ttf_data; - font_cfg.FontDataSize = ttf_size; - font_cfg.SizePixels = size_pixels; - if (glyph_ranges) - font_cfg.GlyphRanges = glyph_ranges; - return AddFont(&font_cfg); + ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); + IM_ASSERT(font_cfg.FontData == NULL); + font_cfg.FontData = ttf_data; + font_cfg.FontDataSize = ttf_size; + font_cfg.SizePixels = size_pixels; + if (glyph_ranges) + font_cfg.GlyphRanges = glyph_ranges; + return AddFont(&font_cfg); } ImFont* ImFontAtlas::AddFontFromMemoryCompressedTTF(const void* compressed_ttf_data, int compressed_ttf_size, float size_pixels, const ImFontConfig* font_cfg_template, const ImWchar* glyph_ranges) { - const unsigned int buf_decompressed_size = stb_decompress_length((unsigned char*)compressed_ttf_data); - unsigned char* buf_decompressed_data = (unsigned char *)ImGui::MemAlloc(buf_decompressed_size); - stb_decompress(buf_decompressed_data, (unsigned char*)compressed_ttf_data, (unsigned int)compressed_ttf_size); + const unsigned int buf_decompressed_size = stb_decompress_length((unsigned char*)compressed_ttf_data); + unsigned char* buf_decompressed_data = (unsigned char*)ImGui::MemAlloc(buf_decompressed_size); + stb_decompress(buf_decompressed_data, (unsigned char*)compressed_ttf_data, (unsigned int)compressed_ttf_size); - ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); - IM_ASSERT(font_cfg.FontData == NULL); - font_cfg.FontDataOwnedByAtlas = true; - return AddFontFromMemoryTTF(buf_decompressed_data, (int)buf_decompressed_size, size_pixels, &font_cfg, glyph_ranges); + ImFontConfig font_cfg = font_cfg_template ? *font_cfg_template : ImFontConfig(); + IM_ASSERT(font_cfg.FontData == NULL); + font_cfg.FontDataOwnedByAtlas = true; + return AddFontFromMemoryTTF(buf_decompressed_data, (int)buf_decompressed_size, size_pixels, &font_cfg, glyph_ranges); } ImFont* ImFontAtlas::AddFontFromMemoryCompressedBase85TTF(const char* compressed_ttf_data_base85, float size_pixels, const ImFontConfig* font_cfg, const ImWchar* glyph_ranges) { - int compressed_ttf_size = (((int)strlen(compressed_ttf_data_base85) + 4) / 5) * 4; - void* compressed_ttf = ImGui::MemAlloc((size_t)compressed_ttf_size); - Decode85((const unsigned char*)compressed_ttf_data_base85, (unsigned char*)compressed_ttf); - ImFont* font = AddFontFromMemoryCompressedTTF(compressed_ttf, compressed_ttf_size, size_pixels, font_cfg, glyph_ranges); - ImGui::MemFree(compressed_ttf); - return font; + int compressed_ttf_size = (((int)strlen(compressed_ttf_data_base85) + 4) / 5) * 4; + void* compressed_ttf = ImGui::MemAlloc((size_t)compressed_ttf_size); + Decode85((const unsigned char*)compressed_ttf_data_base85, (unsigned char*)compressed_ttf); + ImFont* font = AddFontFromMemoryCompressedTTF(compressed_ttf, compressed_ttf_size, size_pixels, font_cfg, glyph_ranges); + ImGui::MemFree(compressed_ttf); + return font; } int ImFontAtlas::AddCustomRectRegular(unsigned int id, int width, int height) { - IM_ASSERT(id >= 0x10000); - IM_ASSERT(width > 0 && width <= 0xFFFF); - IM_ASSERT(height > 0 && height <= 0xFFFF); - CustomRect r; - r.ID = id; - r.Width = (unsigned short)width; - r.Height = (unsigned short)height; - CustomRects.push_back(r); - return CustomRects.Size - 1; // Return index + IM_ASSERT(id >= 0x10000); + IM_ASSERT(width > 0 && width <= 0xFFFF); + IM_ASSERT(height > 0 && height <= 0xFFFF); + CustomRect r; + r.ID = id; + r.Width = (unsigned short)width; + r.Height = (unsigned short)height; + CustomRects.push_back(r); + return CustomRects.Size - 1; // Return index } int ImFontAtlas::AddCustomRectFontGlyph(ImFont* font, ImWchar id, int width, int height, float advance_x, const ImVec2& offset) { - IM_ASSERT(font != NULL); - IM_ASSERT(width > 0 && width <= 0xFFFF); - IM_ASSERT(height > 0 && height <= 0xFFFF); - CustomRect r; - r.ID = id; - r.Width = (unsigned short)width; - r.Height = (unsigned short)height; - r.GlyphAdvanceX = advance_x; - r.GlyphOffset = offset; - r.Font = font; - CustomRects.push_back(r); - return CustomRects.Size - 1; // Return index + IM_ASSERT(font != NULL); + IM_ASSERT(width > 0 && width <= 0xFFFF); + IM_ASSERT(height > 0 && height <= 0xFFFF); + CustomRect r; + r.ID = id; + r.Width = (unsigned short)width; + r.Height = (unsigned short)height; + r.GlyphAdvanceX = advance_x; + r.GlyphOffset = offset; + r.Font = font; + CustomRects.push_back(r); + return CustomRects.Size - 1; // Return index } void ImFontAtlas::CalcCustomRectUV(const CustomRect* rect, ImVec2* out_uv_min, ImVec2* out_uv_max) { - IM_ASSERT(TexWidth > 0 && TexHeight > 0); // Font atlas needs to be built before we can calculate UV coordinates - IM_ASSERT(rect->IsPacked()); // Make sure the rectangle has been packed - *out_uv_min = ImVec2((float)rect->X * TexUvScale.x, (float)rect->Y * TexUvScale.y); - *out_uv_max = ImVec2((float)(rect->X + rect->Width) * TexUvScale.x, (float)(rect->Y + rect->Height) * TexUvScale.y); + IM_ASSERT(TexWidth > 0 && TexHeight > 0); // Font atlas needs to be built before we can calculate UV coordinates + IM_ASSERT(rect->IsPacked()); // Make sure the rectangle has been packed + *out_uv_min = ImVec2((float)rect->X * TexUvScale.x, (float)rect->Y * TexUvScale.y); + *out_uv_max = ImVec2((float)(rect->X + rect->Width) * TexUvScale.x, (float)(rect->Y + rect->Height) * TexUvScale.y); } bool ImFontAtlas::GetMouseCursorTexData(ImGuiMouseCursor cursor_type, ImVec2* out_offset, ImVec2* out_size, ImVec2 out_uv_border[2], ImVec2 out_uv_fill[2]) { - if (cursor_type <= ImGuiMouseCursor_None || cursor_type >= ImGuiMouseCursor_Count_) - return false; - if (Flags & ImFontAtlasFlags_NoMouseCursors) - return false; + if (cursor_type <= ImGuiMouseCursor_None || cursor_type >= ImGuiMouseCursor_Count_) + return false; + if (Flags & ImFontAtlasFlags_NoMouseCursors) + return false; - ImFontAtlas::CustomRect& r = CustomRects[CustomRectIds[0]]; - IM_ASSERT(r.ID == FONT_ATLAS_DEFAULT_TEX_DATA_ID); - ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][0] + ImVec2((float)r.X, (float)r.Y); - ImVec2 size = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][1]; - *out_size = size; - *out_offset = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][2]; - out_uv_border[0] = (pos) * TexUvScale; - out_uv_border[1] = (pos + size) * TexUvScale; - pos.x += FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF + 1; - out_uv_fill[0] = (pos) * TexUvScale; - out_uv_fill[1] = (pos + size) * TexUvScale; - return true; + ImFontAtlas::CustomRect& r = CustomRects[CustomRectIds[0]]; + IM_ASSERT(r.ID == FONT_ATLAS_DEFAULT_TEX_DATA_ID); + ImVec2 pos = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][0] + ImVec2((float)r.X, (float)r.Y); + ImVec2 size = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][1]; + *out_size = size; + *out_offset = FONT_ATLAS_DEFAULT_TEX_CURSOR_DATA[cursor_type][2]; + out_uv_border[0] = (pos)*TexUvScale; + out_uv_border[1] = (pos + size) * TexUvScale; + pos.x += FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF + 1; + out_uv_fill[0] = (pos)*TexUvScale; + out_uv_fill[1] = (pos + size) * TexUvScale; + return true; } -bool ImFontAtlas::Build() +bool ImFontAtlas::Build() { - return ImFontAtlasBuildWithStbTruetype(this); + return ImFontAtlasBuildWithStbTruetype(this); } -void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_brighten_factor) +void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_brighten_factor) { - for (unsigned int i = 0; i < 256; i++) - { - unsigned int value = (unsigned int)(i * in_brighten_factor); - out_table[i] = value > 255 ? 255 : (value & 0xFF); - } + for (unsigned int i = 0; i < 256; i++) + { + unsigned int value = (unsigned int)(i * in_brighten_factor); + out_table[i] = value > 255 ? 255 : (value & 0xFF); + } } -void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride) +void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride) { - unsigned char* data = pixels + x + y * stride; - for (int j = h; j > 0; j--, data += stride) - for (int i = 0; i < w; i++) - data[i] = table[data[i]]; + unsigned char* data = pixels + x + y * stride; + for (int j = h; j > 0; j--, data += stride) + for (int i = 0; i < w; i++) + data[i] = table[data[i]]; } -bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) +bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas) { - IM_ASSERT(atlas->ConfigData.Size > 0); + IM_ASSERT(atlas->ConfigData.Size > 0); - ImFontAtlasBuildRegisterDefaultCustomRects(atlas); + ImFontAtlasBuildRegisterDefaultCustomRects(atlas); - atlas->TexID = NULL; - atlas->TexWidth = atlas->TexHeight = 0; - atlas->TexUvScale = ImVec2(0.0f, 0.0f); - atlas->TexUvWhitePixel = ImVec2(0.0f, 0.0f); - atlas->ClearTexData(); + atlas->TexID = NULL; + atlas->TexWidth = atlas->TexHeight = 0; + atlas->TexUvScale = ImVec2(0.0f, 0.0f); + atlas->TexUvWhitePixel = ImVec2(0.0f, 0.0f); + atlas->ClearTexData(); - // Count glyphs/ranges - int total_glyphs_count = 0; - int total_ranges_count = 0; - for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++) - { - ImFontConfig& cfg = atlas->ConfigData[input_i]; - if (!cfg.GlyphRanges) - cfg.GlyphRanges = atlas->GetGlyphRangesDefault(); - for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2, total_ranges_count++) - total_glyphs_count += (in_range[1] - in_range[0]) + 1; - } + // Count glyphs/ranges + int total_glyphs_count = 0; + int total_ranges_count = 0; + for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++) + { + ImFontConfig& cfg = atlas->ConfigData[input_i]; + if (!cfg.GlyphRanges) + cfg.GlyphRanges = atlas->GetGlyphRangesDefault(); + for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2, total_ranges_count++) + total_glyphs_count += (in_range[1] - in_range[0]) + 1; + } - // We need a width for the skyline algorithm. Using a dumb heuristic here to decide of width. User can override TexDesiredWidth and TexGlyphPadding if they wish. - // Width doesn't really matter much, but some API/GPU have texture size limitations and increasing width can decrease height. - atlas->TexWidth = (atlas->TexDesiredWidth > 0) ? atlas->TexDesiredWidth : (total_glyphs_count > 4000) ? 4096 : (total_glyphs_count > 2000) ? 2048 : (total_glyphs_count > 1000) ? 1024 : 512; - atlas->TexHeight = 0; + // We need a width for the skyline algorithm. Using a dumb heuristic here to decide of width. User can override TexDesiredWidth and TexGlyphPadding if they wish. + // Width doesn't really matter much, but some API/GPU have texture size limitations and increasing width can decrease height. + atlas->TexWidth = (atlas->TexDesiredWidth > 0) ? atlas->TexDesiredWidth : (total_glyphs_count > 4000) ? 4096 : (total_glyphs_count > 2000) ? 2048 : (total_glyphs_count > 1000) ? 1024 : 512; + atlas->TexHeight = 0; - // Start packing - const int max_tex_height = 1024*32; - stbtt_pack_context spc = {}; - if (!stbtt_PackBegin(&spc, NULL, atlas->TexWidth, max_tex_height, 0, atlas->TexGlyphPadding, NULL)) - return false; - stbtt_PackSetOversampling(&spc, 1, 1); + // Start packing + const int max_tex_height = 1024 * 32; + stbtt_pack_context spc = {}; + if (!stbtt_PackBegin(&spc, NULL, atlas->TexWidth, max_tex_height, 0, atlas->TexGlyphPadding, NULL)) + return false; + stbtt_PackSetOversampling(&spc, 1, 1); - // Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values). - ImFontAtlasBuildPackCustomRects(atlas, spc.pack_info); + // Pack our extra data rectangles first, so it will be on the upper-left corner of our texture (UV will have small values). + ImFontAtlasBuildPackCustomRects(atlas, spc.pack_info); - // Initialize font information (so we can error without any cleanup) - struct ImFontTempBuildData - { - stbtt_fontinfo FontInfo; - stbrp_rect* Rects; - int RectsCount; - stbtt_pack_range* Ranges; - int RangesCount; - }; - ImFontTempBuildData* tmp_array = (ImFontTempBuildData*)ImGui::MemAlloc((size_t)atlas->ConfigData.Size * sizeof(ImFontTempBuildData)); - for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++) - { - ImFontConfig& cfg = atlas->ConfigData[input_i]; - ImFontTempBuildData& tmp = tmp_array[input_i]; - IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas)); + // Initialize font information (so we can error without any cleanup) + struct ImFontTempBuildData + { + stbtt_fontinfo FontInfo; + stbrp_rect* Rects; + int RectsCount; + stbtt_pack_range* Ranges; + int RangesCount; + }; + ImFontTempBuildData* tmp_array = (ImFontTempBuildData*)ImGui::MemAlloc((size_t)atlas->ConfigData.Size * sizeof(ImFontTempBuildData)); + for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++) + { + ImFontConfig& cfg = atlas->ConfigData[input_i]; + ImFontTempBuildData& tmp = tmp_array[input_i]; + IM_ASSERT(cfg.DstFont && (!cfg.DstFont->IsLoaded() || cfg.DstFont->ContainerAtlas == atlas)); - const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo); - IM_ASSERT(font_offset >= 0); - if (!stbtt_InitFont(&tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset)) - { - atlas->TexWidth = atlas->TexHeight = 0; // Reset output on failure - ImGui::MemFree(tmp_array); - return false; - } - } + const int font_offset = stbtt_GetFontOffsetForIndex((unsigned char*)cfg.FontData, cfg.FontNo); + IM_ASSERT(font_offset >= 0); + if (!stbtt_InitFont(&tmp.FontInfo, (unsigned char*)cfg.FontData, font_offset)) + { + atlas->TexWidth = atlas->TexHeight = 0; // Reset output on failure + ImGui::MemFree(tmp_array); + return false; + } + } - // Allocate packing character data and flag packed characters buffer as non-packed (x0=y0=x1=y1=0) - int buf_packedchars_n = 0, buf_rects_n = 0, buf_ranges_n = 0; - stbtt_packedchar* buf_packedchars = (stbtt_packedchar*)ImGui::MemAlloc(total_glyphs_count * sizeof(stbtt_packedchar)); - stbrp_rect* buf_rects = (stbrp_rect*)ImGui::MemAlloc(total_glyphs_count * sizeof(stbrp_rect)); - stbtt_pack_range* buf_ranges = (stbtt_pack_range*)ImGui::MemAlloc(total_ranges_count * sizeof(stbtt_pack_range)); - memset(buf_packedchars, 0, total_glyphs_count * sizeof(stbtt_packedchar)); - memset(buf_rects, 0, total_glyphs_count * sizeof(stbrp_rect)); // Unnecessary but let's clear this for the sake of sanity. - memset(buf_ranges, 0, total_ranges_count * sizeof(stbtt_pack_range)); + // Allocate packing character data and flag packed characters buffer as non-packed (x0=y0=x1=y1=0) + int buf_packedchars_n = 0, buf_rects_n = 0, buf_ranges_n = 0; + stbtt_packedchar* buf_packedchars = (stbtt_packedchar*)ImGui::MemAlloc(total_glyphs_count * sizeof(stbtt_packedchar)); + stbrp_rect* buf_rects = (stbrp_rect*)ImGui::MemAlloc(total_glyphs_count * sizeof(stbrp_rect)); + stbtt_pack_range* buf_ranges = (stbtt_pack_range*)ImGui::MemAlloc(total_ranges_count * sizeof(stbtt_pack_range)); + memset(buf_packedchars, 0, total_glyphs_count * sizeof(stbtt_packedchar)); + memset(buf_rects, 0, total_glyphs_count * sizeof(stbrp_rect)); // Unnecessary but let's clear this for the sake of sanity. + memset(buf_ranges, 0, total_ranges_count * sizeof(stbtt_pack_range)); - // First font pass: pack all glyphs (no rendering at this point, we are working with rectangles in an infinitely tall texture at this point) - for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++) - { - ImFontConfig& cfg = atlas->ConfigData[input_i]; - ImFontTempBuildData& tmp = tmp_array[input_i]; + // First font pass: pack all glyphs (no rendering at this point, we are working with rectangles in an infinitely tall texture at this point) + for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++) + { + ImFontConfig& cfg = atlas->ConfigData[input_i]; + ImFontTempBuildData& tmp = tmp_array[input_i]; - // Setup ranges - int font_glyphs_count = 0; - int font_ranges_count = 0; - for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2, font_ranges_count++) - font_glyphs_count += (in_range[1] - in_range[0]) + 1; - tmp.Ranges = buf_ranges + buf_ranges_n; - tmp.RangesCount = font_ranges_count; - buf_ranges_n += font_ranges_count; - for (int i = 0; i < font_ranges_count; i++) - { - const ImWchar* in_range = &cfg.GlyphRanges[i * 2]; - stbtt_pack_range& range = tmp.Ranges[i]; - range.font_size = cfg.SizePixels; - range.first_unicode_codepoint_in_range = in_range[0]; - range.num_chars = (in_range[1] - in_range[0]) + 1; - range.chardata_for_range = buf_packedchars + buf_packedchars_n; - buf_packedchars_n += range.num_chars; - } + // Setup ranges + int font_glyphs_count = 0; + int font_ranges_count = 0; + for (const ImWchar* in_range = cfg.GlyphRanges; in_range[0] && in_range[1]; in_range += 2, font_ranges_count++) + font_glyphs_count += (in_range[1] - in_range[0]) + 1; + tmp.Ranges = buf_ranges + buf_ranges_n; + tmp.RangesCount = font_ranges_count; + buf_ranges_n += font_ranges_count; + for (int i = 0; i < font_ranges_count; i++) + { + const ImWchar* in_range = &cfg.GlyphRanges[i * 2]; + stbtt_pack_range& range = tmp.Ranges[i]; + range.font_size = cfg.SizePixels; + range.first_unicode_codepoint_in_range = in_range[0]; + range.num_chars = (in_range[1] - in_range[0]) + 1; + range.chardata_for_range = buf_packedchars + buf_packedchars_n; + buf_packedchars_n += range.num_chars; + } - // Pack - tmp.Rects = buf_rects + buf_rects_n; - tmp.RectsCount = font_glyphs_count; - buf_rects_n += font_glyphs_count; - stbtt_PackSetOversampling(&spc, cfg.OversampleH, cfg.OversampleV); - int n = stbtt_PackFontRangesGatherRects(&spc, &tmp.FontInfo, tmp.Ranges, tmp.RangesCount, tmp.Rects); - IM_ASSERT(n == font_glyphs_count); - stbrp_pack_rects((stbrp_context*)spc.pack_info, tmp.Rects, n); + // Pack + tmp.Rects = buf_rects + buf_rects_n; + tmp.RectsCount = font_glyphs_count; + buf_rects_n += font_glyphs_count; + stbtt_PackSetOversampling(&spc, cfg.OversampleH, cfg.OversampleV); + int n = stbtt_PackFontRangesGatherRects(&spc, &tmp.FontInfo, tmp.Ranges, tmp.RangesCount, tmp.Rects); + IM_ASSERT(n == font_glyphs_count); + stbrp_pack_rects((stbrp_context*)spc.pack_info, tmp.Rects, n); - // Extend texture height - for (int i = 0; i < n; i++) - if (tmp.Rects[i].was_packed) - atlas->TexHeight = ImMax(atlas->TexHeight, tmp.Rects[i].y + tmp.Rects[i].h); - } - IM_ASSERT(buf_rects_n == total_glyphs_count); - IM_ASSERT(buf_packedchars_n == total_glyphs_count); - IM_ASSERT(buf_ranges_n == total_ranges_count); + // Extend texture height + for (int i = 0; i < n; i++) + if (tmp.Rects[i].was_packed) + atlas->TexHeight = ImMax(atlas->TexHeight, tmp.Rects[i].y + tmp.Rects[i].h); + } + IM_ASSERT(buf_rects_n == total_glyphs_count); + IM_ASSERT(buf_packedchars_n == total_glyphs_count); + IM_ASSERT(buf_ranges_n == total_ranges_count); - // Create texture - atlas->TexHeight = (atlas->Flags & ImFontAtlasFlags_NoPowerOfTwoHeight) ? (atlas->TexHeight + 1) : ImUpperPowerOfTwo(atlas->TexHeight); - atlas->TexUvScale = ImVec2(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight); - atlas->TexPixelsAlpha8 = (unsigned char*)ImGui::MemAlloc(atlas->TexWidth * atlas->TexHeight); - memset(atlas->TexPixelsAlpha8, 0, atlas->TexWidth * atlas->TexHeight); - spc.pixels = atlas->TexPixelsAlpha8; - spc.height = atlas->TexHeight; + // Create texture + atlas->TexHeight = (atlas->Flags & ImFontAtlasFlags_NoPowerOfTwoHeight) ? (atlas->TexHeight + 1) : ImUpperPowerOfTwo(atlas->TexHeight); + atlas->TexUvScale = ImVec2(1.0f / atlas->TexWidth, 1.0f / atlas->TexHeight); + atlas->TexPixelsAlpha8 = (unsigned char*)ImGui::MemAlloc(atlas->TexWidth * atlas->TexHeight); + memset(atlas->TexPixelsAlpha8, 0, atlas->TexWidth * atlas->TexHeight); + spc.pixels = atlas->TexPixelsAlpha8; + spc.height = atlas->TexHeight; - // Second pass: render font characters - for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++) - { - ImFontConfig& cfg = atlas->ConfigData[input_i]; - ImFontTempBuildData& tmp = tmp_array[input_i]; - stbtt_PackSetOversampling(&spc, cfg.OversampleH, cfg.OversampleV); - stbtt_PackFontRangesRenderIntoRects(&spc, &tmp.FontInfo, tmp.Ranges, tmp.RangesCount, tmp.Rects); - if (cfg.RasterizerMultiply != 1.0f) - { - unsigned char multiply_table[256]; - ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, cfg.RasterizerMultiply); - for (const stbrp_rect* r = tmp.Rects; r != tmp.Rects + tmp.RectsCount; r++) - if (r->was_packed) - ImFontAtlasBuildMultiplyRectAlpha8(multiply_table, spc.pixels, r->x, r->y, r->w, r->h, spc.stride_in_bytes); - } - tmp.Rects = NULL; - } + // Second pass: render font characters + for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++) + { + ImFontConfig& cfg = atlas->ConfigData[input_i]; + ImFontTempBuildData& tmp = tmp_array[input_i]; + stbtt_PackSetOversampling(&spc, cfg.OversampleH, cfg.OversampleV); + stbtt_PackFontRangesRenderIntoRects(&spc, &tmp.FontInfo, tmp.Ranges, tmp.RangesCount, tmp.Rects); + if (cfg.RasterizerMultiply != 1.0f) + { + unsigned char multiply_table[256]; + ImFontAtlasBuildMultiplyCalcLookupTable(multiply_table, cfg.RasterizerMultiply); + for (const stbrp_rect* r = tmp.Rects; r != tmp.Rects + tmp.RectsCount; r++) + if (r->was_packed) + ImFontAtlasBuildMultiplyRectAlpha8(multiply_table, spc.pixels, r->x, r->y, r->w, r->h, spc.stride_in_bytes); + } + tmp.Rects = NULL; + } - // End packing - stbtt_PackEnd(&spc); - ImGui::MemFree(buf_rects); - buf_rects = NULL; + // End packing + stbtt_PackEnd(&spc); + ImGui::MemFree(buf_rects); + buf_rects = NULL; - // Third pass: setup ImFont and glyphs for runtime - for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++) - { - ImFontConfig& cfg = atlas->ConfigData[input_i]; - ImFontTempBuildData& tmp = tmp_array[input_i]; - ImFont* dst_font = cfg.DstFont; // We can have multiple input fonts writing into a same destination font (when using MergeMode=true) + // Third pass: setup ImFont and glyphs for runtime + for (int input_i = 0; input_i < atlas->ConfigData.Size; input_i++) + { + ImFontConfig& cfg = atlas->ConfigData[input_i]; + ImFontTempBuildData& tmp = tmp_array[input_i]; + ImFont* dst_font = cfg.DstFont; // We can have multiple input fonts writing into a same destination font (when using MergeMode=true) - const float font_scale = stbtt_ScaleForPixelHeight(&tmp.FontInfo, cfg.SizePixels); - int unscaled_ascent, unscaled_descent, unscaled_line_gap; - stbtt_GetFontVMetrics(&tmp.FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap); + const float font_scale = stbtt_ScaleForPixelHeight(&tmp.FontInfo, cfg.SizePixels); + int unscaled_ascent, unscaled_descent, unscaled_line_gap; + stbtt_GetFontVMetrics(&tmp.FontInfo, &unscaled_ascent, &unscaled_descent, &unscaled_line_gap); - const float ascent = unscaled_ascent * font_scale; - const float descent = unscaled_descent * font_scale; - ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent); - const float off_x = cfg.GlyphOffset.x; - const float off_y = cfg.GlyphOffset.y + (float)(int)(dst_font->Ascent + 0.5f); + const float ascent = unscaled_ascent * font_scale; + const float descent = unscaled_descent * font_scale; + ImFontAtlasBuildSetupFont(atlas, dst_font, &cfg, ascent, descent); + const float off_x = cfg.GlyphOffset.x; + const float off_y = cfg.GlyphOffset.y + (float)(int)(dst_font->Ascent + 0.5f); - for (int i = 0; i < tmp.RangesCount; i++) - { - stbtt_pack_range& range = tmp.Ranges[i]; - for (int char_idx = 0; char_idx < range.num_chars; char_idx += 1) - { - const stbtt_packedchar& pc = range.chardata_for_range[char_idx]; - if (!pc.x0 && !pc.x1 && !pc.y0 && !pc.y1) - continue; + for (int i = 0; i < tmp.RangesCount; i++) + { + stbtt_pack_range& range = tmp.Ranges[i]; + for (int char_idx = 0; char_idx < range.num_chars; char_idx += 1) + { + const stbtt_packedchar& pc = range.chardata_for_range[char_idx]; + if (!pc.x0 && !pc.x1 && !pc.y0 && !pc.y1) + continue; - const int codepoint = range.first_unicode_codepoint_in_range + char_idx; - if (cfg.MergeMode && dst_font->FindGlyph((unsigned short)codepoint)) - continue; + const int codepoint = range.first_unicode_codepoint_in_range + char_idx; + if (cfg.MergeMode && dst_font->FindGlyph((unsigned short)codepoint)) + continue; - stbtt_aligned_quad q; - float dummy_x = 0.0f, dummy_y = 0.0f; - stbtt_GetPackedQuad(range.chardata_for_range, atlas->TexWidth, atlas->TexHeight, char_idx, &dummy_x, &dummy_y, &q, 0); - dst_font->AddGlyph((ImWchar)codepoint, q.x0 + off_x, q.y0 + off_y, q.x1 + off_x, q.y1 + off_y, q.s0, q.t0, q.s1, q.t1, pc.xadvance); - } - } - } + stbtt_aligned_quad q; + float dummy_x = 0.0f, dummy_y = 0.0f; + stbtt_GetPackedQuad(range.chardata_for_range, atlas->TexWidth, atlas->TexHeight, char_idx, &dummy_x, &dummy_y, &q, 0); + dst_font->AddGlyph((ImWchar)codepoint, q.x0 + off_x, q.y0 + off_y, q.x1 + off_x, q.y1 + off_y, q.s0, q.t0, q.s1, q.t1, pc.xadvance); + } + } + } - // Cleanup temporaries - ImGui::MemFree(buf_packedchars); - ImGui::MemFree(buf_ranges); - ImGui::MemFree(tmp_array); + // Cleanup temporaries + ImGui::MemFree(buf_packedchars); + ImGui::MemFree(buf_ranges); + ImGui::MemFree(tmp_array); - ImFontAtlasBuildFinish(atlas); + ImFontAtlasBuildFinish(atlas); - return true; + return true; } void ImFontAtlasBuildRegisterDefaultCustomRects(ImFontAtlas* atlas) { - if (atlas->CustomRectIds[0] >= 0) - return; - if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors)) - atlas->CustomRectIds[0] = atlas->AddCustomRectRegular(FONT_ATLAS_DEFAULT_TEX_DATA_ID, FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF*2+1, FONT_ATLAS_DEFAULT_TEX_DATA_H); - else - atlas->CustomRectIds[0] = atlas->AddCustomRectRegular(FONT_ATLAS_DEFAULT_TEX_DATA_ID, 2, 2); + if (atlas->CustomRectIds[0] >= 0) + return; + if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors)) + atlas->CustomRectIds[0] = atlas->AddCustomRectRegular(FONT_ATLAS_DEFAULT_TEX_DATA_ID, FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * 2 + 1, FONT_ATLAS_DEFAULT_TEX_DATA_H); + else + atlas->CustomRectIds[0] = atlas->AddCustomRectRegular(FONT_ATLAS_DEFAULT_TEX_DATA_ID, 2, 2); } void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent) { - if (!font_config->MergeMode) - { - font->ClearOutputData(); - font->FontSize = font_config->SizePixels; - font->ConfigData = font_config; - font->ContainerAtlas = atlas; - font->Ascent = ascent; - font->Descent = descent; - } - font->ConfigDataCount++; + if (!font_config->MergeMode) + { + font->ClearOutputData(); + font->FontSize = font_config->SizePixels; + font->ConfigData = font_config; + font->ContainerAtlas = atlas; + font->Ascent = ascent; + font->Descent = descent; + } + font->ConfigDataCount++; } void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* pack_context_opaque) { - stbrp_context* pack_context = (stbrp_context*)pack_context_opaque; + stbrp_context* pack_context = (stbrp_context*)pack_context_opaque; - ImVector& user_rects = atlas->CustomRects; - IM_ASSERT(user_rects.Size >= 1); // We expect at least the default custom rects to be registered, else something went wrong. + ImVector& user_rects = atlas->CustomRects; + IM_ASSERT(user_rects.Size >= 1); // We expect at least the default custom rects to be registered, else something went wrong. - ImVector pack_rects; - pack_rects.resize(user_rects.Size); - memset(pack_rects.Data, 0, sizeof(stbrp_rect) * user_rects.Size); - for (int i = 0; i < user_rects.Size; i++) - { - pack_rects[i].w = user_rects[i].Width; - pack_rects[i].h = user_rects[i].Height; - } - stbrp_pack_rects(pack_context, &pack_rects[0], pack_rects.Size); - for (int i = 0; i < pack_rects.Size; i++) - if (pack_rects[i].was_packed) - { - user_rects[i].X = pack_rects[i].x; - user_rects[i].Y = pack_rects[i].y; - IM_ASSERT(pack_rects[i].w == user_rects[i].Width && pack_rects[i].h == user_rects[i].Height); - atlas->TexHeight = ImMax(atlas->TexHeight, pack_rects[i].y + pack_rects[i].h); - } + ImVector pack_rects; + pack_rects.resize(user_rects.Size); + memset(pack_rects.Data, 0, sizeof(stbrp_rect) * user_rects.Size); + for (int i = 0; i < user_rects.Size; i++) + { + pack_rects[i].w = user_rects[i].Width; + pack_rects[i].h = user_rects[i].Height; + } + stbrp_pack_rects(pack_context, &pack_rects[0], pack_rects.Size); + for (int i = 0; i < pack_rects.Size; i++) + if (pack_rects[i].was_packed) + { + user_rects[i].X = pack_rects[i].x; + user_rects[i].Y = pack_rects[i].y; + IM_ASSERT(pack_rects[i].w == user_rects[i].Width && pack_rects[i].h == user_rects[i].Height); + atlas->TexHeight = ImMax(atlas->TexHeight, pack_rects[i].y + pack_rects[i].h); + } } static void ImFontAtlasBuildRenderDefaultTexData(ImFontAtlas* atlas) { - IM_ASSERT(atlas->CustomRectIds[0] >= 0); - IM_ASSERT(atlas->TexPixelsAlpha8 != NULL); - ImFontAtlas::CustomRect& r = atlas->CustomRects[atlas->CustomRectIds[0]]; - IM_ASSERT(r.ID == FONT_ATLAS_DEFAULT_TEX_DATA_ID); - IM_ASSERT(r.IsPacked()); + IM_ASSERT(atlas->CustomRectIds[0] >= 0); + IM_ASSERT(atlas->TexPixelsAlpha8 != NULL); + ImFontAtlas::CustomRect& r = atlas->CustomRects[atlas->CustomRectIds[0]]; + IM_ASSERT(r.ID == FONT_ATLAS_DEFAULT_TEX_DATA_ID); + IM_ASSERT(r.IsPacked()); - const int w = atlas->TexWidth; - if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors)) - { - // Render/copy pixels - IM_ASSERT(r.Width == FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * 2 + 1 && r.Height == FONT_ATLAS_DEFAULT_TEX_DATA_H); - for (int y = 0, n = 0; y < FONT_ATLAS_DEFAULT_TEX_DATA_H; y++) - for (int x = 0; x < FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF; x++, n++) - { - const int offset0 = (int)(r.X + x) + (int)(r.Y + y) * w; - const int offset1 = offset0 + FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF + 1; - atlas->TexPixelsAlpha8[offset0] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == '.' ? 0xFF : 0x00; - atlas->TexPixelsAlpha8[offset1] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == 'X' ? 0xFF : 0x00; - } - } - else - { - IM_ASSERT(r.Width == 2 && r.Height == 2); - const int offset = (int)(r.X) + (int)(r.Y) * w; - atlas->TexPixelsAlpha8[offset] = atlas->TexPixelsAlpha8[offset + 1] = atlas->TexPixelsAlpha8[offset + w] = atlas->TexPixelsAlpha8[offset + w + 1] = 0xFF; - } - atlas->TexUvWhitePixel = ImVec2((r.X + 0.5f) * atlas->TexUvScale.x, (r.Y + 0.5f) * atlas->TexUvScale.y); + const int w = atlas->TexWidth; + if (!(atlas->Flags & ImFontAtlasFlags_NoMouseCursors)) + { + // Render/copy pixels + IM_ASSERT(r.Width == FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF * 2 + 1 && r.Height == FONT_ATLAS_DEFAULT_TEX_DATA_H); + for (int y = 0, n = 0; y < FONT_ATLAS_DEFAULT_TEX_DATA_H; y++) + for (int x = 0; x < FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF; x++, n++) + { + const int offset0 = (int)(r.X + x) + (int)(r.Y + y) * w; + const int offset1 = offset0 + FONT_ATLAS_DEFAULT_TEX_DATA_W_HALF + 1; + atlas->TexPixelsAlpha8[offset0] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == '.' ? 0xFF : 0x00; + atlas->TexPixelsAlpha8[offset1] = FONT_ATLAS_DEFAULT_TEX_DATA_PIXELS[n] == 'X' ? 0xFF : 0x00; + } + } + else + { + IM_ASSERT(r.Width == 2 && r.Height == 2); + const int offset = (int)(r.X) + (int)(r.Y) * w; + atlas->TexPixelsAlpha8[offset] = atlas->TexPixelsAlpha8[offset + 1] = atlas->TexPixelsAlpha8[offset + w] = atlas->TexPixelsAlpha8[offset + w + 1] = 0xFF; + } + atlas->TexUvWhitePixel = ImVec2((r.X + 0.5f) * atlas->TexUvScale.x, (r.Y + 0.5f) * atlas->TexUvScale.y); } void ImFontAtlasBuildFinish(ImFontAtlas* atlas) { - // Render into our custom data block - ImFontAtlasBuildRenderDefaultTexData(atlas); + // Render into our custom data block + ImFontAtlasBuildRenderDefaultTexData(atlas); - // Register custom rectangle glyphs - for (int i = 0; i < atlas->CustomRects.Size; i++) - { - const ImFontAtlas::CustomRect& r = atlas->CustomRects[i]; - if (r.Font == NULL || r.ID > 0x10000) - continue; + // Register custom rectangle glyphs + for (int i = 0; i < atlas->CustomRects.Size; i++) + { + const ImFontAtlas::CustomRect& r = atlas->CustomRects[i]; + if (r.Font == NULL || r.ID > 0x10000) + continue; - IM_ASSERT(r.Font->ContainerAtlas == atlas); - ImVec2 uv0, uv1; - atlas->CalcCustomRectUV(&r, &uv0, &uv1); - r.Font->AddGlyph((ImWchar)r.ID, r.GlyphOffset.x, r.GlyphOffset.y, r.GlyphOffset.x + r.Width, r.GlyphOffset.y + r.Height, uv0.x, uv0.y, uv1.x, uv1.y, r.GlyphAdvanceX); - } + IM_ASSERT(r.Font->ContainerAtlas == atlas); + ImVec2 uv0, uv1; + atlas->CalcCustomRectUV(&r, &uv0, &uv1); + r.Font->AddGlyph((ImWchar)r.ID, r.GlyphOffset.x, r.GlyphOffset.y, r.GlyphOffset.x + r.Width, r.GlyphOffset.y + r.Height, uv0.x, uv0.y, uv1.x, uv1.y, r.GlyphAdvanceX); + } - // Build all fonts lookup tables - for (int i = 0; i < atlas->Fonts.Size; i++) - atlas->Fonts[i]->BuildLookupTable(); + // Build all fonts lookup tables + for (int i = 0; i < atlas->Fonts.Size; i++) + atlas->Fonts[i]->BuildLookupTable(); } // Retrieve list of range (2 int per range, values are inclusive) -const ImWchar* ImFontAtlas::GetGlyphRangesDefault() +const ImWchar* ImFontAtlas::GetGlyphRangesDefault() { - static const ImWchar ranges[] = - { - 0x0020, 0x00FF, // Basic Latin + Latin Supplement - 0, - }; - return &ranges[0]; + static const ImWchar ranges[] = + { + 0x0020, + 0x00FF, // Basic Latin + Latin Supplement + 0, + }; + return &ranges[0]; } -const ImWchar* ImFontAtlas::GetGlyphRangesKorean() +const ImWchar* ImFontAtlas::GetGlyphRangesKorean() { - static const ImWchar ranges[] = - { - 0x0020, 0x00FF, // Basic Latin + Latin Supplement - 0x3131, 0x3163, // Korean alphabets - 0xAC00, 0xD79D, // Korean characters - 0, - }; - return &ranges[0]; + static const ImWchar ranges[] = + { + 0x0020, + 0x00FF, // Basic Latin + Latin Supplement + 0x3131, + 0x3163, // Korean alphabets + 0xAC00, + 0xD79D, // Korean characters + 0, + }; + return &ranges[0]; } -const ImWchar* ImFontAtlas::GetGlyphRangesChinese() +const ImWchar* ImFontAtlas::GetGlyphRangesChinese() { - static const ImWchar ranges[] = - { - 0x0020, 0x00FF, // Basic Latin + Latin Supplement - 0x3000, 0x30FF, // Punctuations, Hiragana, Katakana - 0x31F0, 0x31FF, // Katakana Phonetic Extensions - 0xFF00, 0xFFEF, // Half-width characters - 0x4e00, 0x9FAF, // CJK Ideograms - 0, - }; - return &ranges[0]; + static const ImWchar ranges[] = + { + 0x0020, + 0x00FF, // Basic Latin + Latin Supplement + 0x3000, + 0x30FF, // Punctuations, Hiragana, Katakana + 0x31F0, + 0x31FF, // Katakana Phonetic Extensions + 0xFF00, + 0xFFEF, // Half-width characters + 0x4e00, + 0x9FAF, // CJK Ideograms + 0, + }; + return &ranges[0]; } -const ImWchar* ImFontAtlas::GetGlyphRangesJapanese() +const ImWchar* ImFontAtlas::GetGlyphRangesJapanese() { - // Store the 1946 ideograms code points as successive offsets from the initial unicode codepoint 0x4E00. Each offset has an implicit +1. - // This encoding is designed to helps us reduce the source code size. - // FIXME: Source a list of the revised 2136 joyo kanji list from 2010 and rebuild this. - // The current list was sourced from http://theinstructionlimit.com/author/renaudbedardrenaudbedard/page/3 - // Note that you may use ImFontAtlas::GlyphRangesBuilder to create your own ranges, by merging existing ranges or adding new characters. - static const short offsets_from_0x4E00[] = - { - -1,0,1,3,0,0,0,0,1,0,5,1,1,0,7,4,6,10,0,1,9,9,7,1,3,19,1,10,7,1,0,1,0,5,1,0,6,4,2,6,0,0,12,6,8,0,3,5,0,1,0,9,0,0,8,1,1,3,4,5,13,0,0,8,2,17, - 4,3,1,1,9,6,0,0,0,2,1,3,2,22,1,9,11,1,13,1,3,12,0,5,9,2,0,6,12,5,3,12,4,1,2,16,1,1,4,6,5,3,0,6,13,15,5,12,8,14,0,0,6,15,3,6,0,18,8,1,6,14,1, - 5,4,12,24,3,13,12,10,24,0,0,0,1,0,1,1,2,9,10,2,2,0,0,3,3,1,0,3,8,0,3,2,4,4,1,6,11,10,14,6,15,3,4,15,1,0,0,5,2,2,0,0,1,6,5,5,6,0,3,6,5,0,0,1,0, - 11,2,2,8,4,7,0,10,0,1,2,17,19,3,0,2,5,0,6,2,4,4,6,1,1,11,2,0,3,1,2,1,2,10,7,6,3,16,0,8,24,0,0,3,1,1,3,0,1,6,0,0,0,2,0,1,5,15,0,1,0,0,2,11,19, - 1,4,19,7,6,5,1,0,0,0,0,5,1,0,1,9,0,0,5,0,2,0,1,0,3,0,11,3,0,2,0,0,0,0,0,9,3,6,4,12,0,14,0,0,29,10,8,0,14,37,13,0,31,16,19,0,8,30,1,20,8,3,48, - 21,1,0,12,0,10,44,34,42,54,11,18,82,0,2,1,2,12,1,0,6,2,17,2,12,7,0,7,17,4,2,6,24,23,8,23,39,2,16,23,1,0,5,1,2,15,14,5,6,2,11,0,8,6,2,2,2,14, - 20,4,15,3,4,11,10,10,2,5,2,1,30,2,1,0,0,22,5,5,0,3,1,5,4,1,0,0,2,2,21,1,5,1,2,16,2,1,3,4,0,8,4,0,0,5,14,11,2,16,1,13,1,7,0,22,15,3,1,22,7,14, - 22,19,11,24,18,46,10,20,64,45,3,2,0,4,5,0,1,4,25,1,0,0,2,10,0,0,0,1,0,1,2,0,0,9,1,2,0,0,0,2,5,2,1,1,5,5,8,1,1,1,5,1,4,9,1,3,0,1,0,1,1,2,0,0, - 2,0,1,8,22,8,1,0,0,0,0,4,2,1,0,9,8,5,0,9,1,30,24,2,6,4,39,0,14,5,16,6,26,179,0,2,1,1,0,0,0,5,2,9,6,0,2,5,16,7,5,1,1,0,2,4,4,7,15,13,14,0,0, - 3,0,1,0,0,0,2,1,6,4,5,1,4,9,0,3,1,8,0,0,10,5,0,43,0,2,6,8,4,0,2,0,0,9,6,0,9,3,1,6,20,14,6,1,4,0,7,2,3,0,2,0,5,0,3,1,0,3,9,7,0,3,4,0,4,9,1,6,0, - 9,0,0,2,3,10,9,28,3,6,2,4,1,2,32,4,1,18,2,0,3,1,5,30,10,0,2,2,2,0,7,9,8,11,10,11,7,2,13,7,5,10,0,3,40,2,0,1,6,12,0,4,5,1,5,11,11,21,4,8,3,7, - 8,8,33,5,23,0,0,19,8,8,2,3,0,6,1,1,1,5,1,27,4,2,5,0,3,5,6,3,1,0,3,1,12,5,3,3,2,0,7,7,2,1,0,4,0,1,1,2,0,10,10,6,2,5,9,7,5,15,15,21,6,11,5,20, - 4,3,5,5,2,5,0,2,1,0,1,7,28,0,9,0,5,12,5,5,18,30,0,12,3,3,21,16,25,32,9,3,14,11,24,5,66,9,1,2,0,5,9,1,5,1,8,0,8,3,3,0,1,15,1,4,8,1,2,7,0,7,2, - 8,3,7,5,3,7,10,2,1,0,0,2,25,0,6,4,0,10,0,4,2,4,1,12,5,38,4,0,4,1,10,5,9,4,0,14,4,2,5,18,20,21,1,3,0,5,0,7,0,3,7,1,3,1,1,8,1,0,0,0,3,2,5,2,11, - 6,0,13,1,3,9,1,12,0,16,6,2,1,0,2,1,12,6,13,11,2,0,28,1,7,8,14,13,8,13,0,2,0,5,4,8,10,2,37,42,19,6,6,7,4,14,11,18,14,80,7,6,0,4,72,12,36,27, - 7,7,0,14,17,19,164,27,0,5,10,7,3,13,6,14,0,2,2,5,3,0,6,13,0,0,10,29,0,4,0,3,13,0,3,1,6,51,1,5,28,2,0,8,0,20,2,4,0,25,2,10,13,10,0,16,4,0,1,0, - 2,1,7,0,1,8,11,0,0,1,2,7,2,23,11,6,6,4,16,2,2,2,0,22,9,3,3,5,2,0,15,16,21,2,9,20,15,15,5,3,9,1,0,0,1,7,7,5,4,2,2,2,38,24,14,0,0,15,5,6,24,14, - 5,5,11,0,21,12,0,3,8,4,11,1,8,0,11,27,7,2,4,9,21,59,0,1,39,3,60,62,3,0,12,11,0,3,30,11,0,13,88,4,15,5,28,13,1,4,48,17,17,4,28,32,46,0,16,0, - 18,11,1,8,6,38,11,2,6,11,38,2,0,45,3,11,2,7,8,4,30,14,17,2,1,1,65,18,12,16,4,2,45,123,12,56,33,1,4,3,4,7,0,0,0,3,2,0,16,4,2,4,2,0,7,4,5,2,26, - 2,25,6,11,6,1,16,2,6,17,77,15,3,35,0,1,0,5,1,0,38,16,6,3,12,3,3,3,0,9,3,1,3,5,2,9,0,18,0,25,1,3,32,1,72,46,6,2,7,1,3,14,17,0,28,1,40,13,0,20, - 15,40,6,38,24,12,43,1,1,9,0,12,6,0,6,2,4,19,3,7,1,48,0,9,5,0,5,6,9,6,10,15,2,11,19,3,9,2,0,1,10,1,27,8,1,3,6,1,14,0,26,0,27,16,3,4,9,6,2,23, - 9,10,5,25,2,1,6,1,1,48,15,9,15,14,3,4,26,60,29,13,37,21,1,6,4,0,2,11,22,23,16,16,2,2,1,3,0,5,1,6,4,0,0,4,0,0,8,3,0,2,5,0,7,1,7,3,13,2,4,10, - 3,0,2,31,0,18,3,0,12,10,4,1,0,7,5,7,0,5,4,12,2,22,10,4,2,15,2,8,9,0,23,2,197,51,3,1,1,4,13,4,3,21,4,19,3,10,5,40,0,4,1,1,10,4,1,27,34,7,21, - 2,17,2,9,6,4,2,3,0,4,2,7,8,2,5,1,15,21,3,4,4,2,2,17,22,1,5,22,4,26,7,0,32,1,11,42,15,4,1,2,5,0,19,3,1,8,6,0,10,1,9,2,13,30,8,2,24,17,19,1,4, - 4,25,13,0,10,16,11,39,18,8,5,30,82,1,6,8,18,77,11,13,20,75,11,112,78,33,3,0,0,60,17,84,9,1,1,12,30,10,49,5,32,158,178,5,5,6,3,3,1,3,1,4,7,6, - 19,31,21,0,2,9,5,6,27,4,9,8,1,76,18,12,1,4,0,3,3,6,3,12,2,8,30,16,2,25,1,5,5,4,3,0,6,10,2,3,1,0,5,1,19,3,0,8,1,5,2,6,0,0,0,19,1,2,0,5,1,2,5, - 1,3,7,0,4,12,7,3,10,22,0,9,5,1,0,2,20,1,1,3,23,30,3,9,9,1,4,191,14,3,15,6,8,50,0,1,0,0,4,0,0,1,0,2,4,2,0,2,3,0,2,0,2,2,8,7,0,1,1,1,3,3,17,11, - 91,1,9,3,2,13,4,24,15,41,3,13,3,1,20,4,125,29,30,1,0,4,12,2,21,4,5,5,19,11,0,13,11,86,2,18,0,7,1,8,8,2,2,22,1,2,6,5,2,0,1,2,8,0,2,0,5,2,1,0, - 2,10,2,0,5,9,2,1,2,0,1,0,4,0,0,10,2,5,3,0,6,1,0,1,4,4,33,3,13,17,3,18,6,4,7,1,5,78,0,4,1,13,7,1,8,1,0,35,27,15,3,0,0,0,1,11,5,41,38,15,22,6, - 14,14,2,1,11,6,20,63,5,8,27,7,11,2,2,40,58,23,50,54,56,293,8,8,1,5,1,14,0,1,12,37,89,8,8,8,2,10,6,0,0,0,4,5,2,1,0,1,1,2,7,0,3,3,0,4,6,0,3,2, - 19,3,8,0,0,0,4,4,16,0,4,1,5,1,3,0,3,4,6,2,17,10,10,31,6,4,3,6,10,126,7,3,2,2,0,9,0,0,5,20,13,0,15,0,6,0,2,5,8,64,50,3,2,12,2,9,0,0,11,8,20, - 109,2,18,23,0,0,9,61,3,0,28,41,77,27,19,17,81,5,2,14,5,83,57,252,14,154,263,14,20,8,13,6,57,39,38, - }; - static ImWchar base_ranges[] = - { - 0x0020, 0x00FF, // Basic Latin + Latin Supplement - 0x3000, 0x30FF, // Punctuations, Hiragana, Katakana - 0x31F0, 0x31FF, // Katakana Phonetic Extensions - 0xFF00, 0xFFEF, // Half-width characters - }; - static bool full_ranges_unpacked = false; - static ImWchar full_ranges[IM_ARRAYSIZE(base_ranges) + IM_ARRAYSIZE(offsets_from_0x4E00)*2 + 1]; - if (!full_ranges_unpacked) - { - // Unpack - int codepoint = 0x4e00; - memcpy(full_ranges, base_ranges, sizeof(base_ranges)); - ImWchar* dst = full_ranges + IM_ARRAYSIZE(base_ranges);; - for (int n = 0; n < IM_ARRAYSIZE(offsets_from_0x4E00); n++, dst += 2) - dst[0] = dst[1] = (ImWchar)(codepoint += (offsets_from_0x4E00[n] + 1)); - dst[0] = 0; - full_ranges_unpacked = true; - } - return &full_ranges[0]; + // Store the 1946 ideograms code points as successive offsets from the initial unicode codepoint 0x4E00. Each offset has an implicit +1. + // This encoding is designed to helps us reduce the source code size. + // FIXME: Source a list of the revised 2136 joyo kanji list from 2010 and rebuild this. + // The current list was sourced from http://theinstructionlimit.com/author/renaudbedardrenaudbedard/page/3 + // Note that you may use ImFontAtlas::GlyphRangesBuilder to create your own ranges, by merging existing ranges or adding new characters. + static const short offsets_from_0x4E00[] = + { + -1, + 0, + 1, + 3, + 0, + 0, + 0, + 0, + 1, + 0, + 5, + 1, + 1, + 0, + 7, + 4, + 6, + 10, + 0, + 1, + 9, + 9, + 7, + 1, + 3, + 19, + 1, + 10, + 7, + 1, + 0, + 1, + 0, + 5, + 1, + 0, + 6, + 4, + 2, + 6, + 0, + 0, + 12, + 6, + 8, + 0, + 3, + 5, + 0, + 1, + 0, + 9, + 0, + 0, + 8, + 1, + 1, + 3, + 4, + 5, + 13, + 0, + 0, + 8, + 2, + 17, + 4, + 3, + 1, + 1, + 9, + 6, + 0, + 0, + 0, + 2, + 1, + 3, + 2, + 22, + 1, + 9, + 11, + 1, + 13, + 1, + 3, + 12, + 0, + 5, + 9, + 2, + 0, + 6, + 12, + 5, + 3, + 12, + 4, + 1, + 2, + 16, + 1, + 1, + 4, + 6, + 5, + 3, + 0, + 6, + 13, + 15, + 5, + 12, + 8, + 14, + 0, + 0, + 6, + 15, + 3, + 6, + 0, + 18, + 8, + 1, + 6, + 14, + 1, + 5, + 4, + 12, + 24, + 3, + 13, + 12, + 10, + 24, + 0, + 0, + 0, + 1, + 0, + 1, + 1, + 2, + 9, + 10, + 2, + 2, + 0, + 0, + 3, + 3, + 1, + 0, + 3, + 8, + 0, + 3, + 2, + 4, + 4, + 1, + 6, + 11, + 10, + 14, + 6, + 15, + 3, + 4, + 15, + 1, + 0, + 0, + 5, + 2, + 2, + 0, + 0, + 1, + 6, + 5, + 5, + 6, + 0, + 3, + 6, + 5, + 0, + 0, + 1, + 0, + 11, + 2, + 2, + 8, + 4, + 7, + 0, + 10, + 0, + 1, + 2, + 17, + 19, + 3, + 0, + 2, + 5, + 0, + 6, + 2, + 4, + 4, + 6, + 1, + 1, + 11, + 2, + 0, + 3, + 1, + 2, + 1, + 2, + 10, + 7, + 6, + 3, + 16, + 0, + 8, + 24, + 0, + 0, + 3, + 1, + 1, + 3, + 0, + 1, + 6, + 0, + 0, + 0, + 2, + 0, + 1, + 5, + 15, + 0, + 1, + 0, + 0, + 2, + 11, + 19, + 1, + 4, + 19, + 7, + 6, + 5, + 1, + 0, + 0, + 0, + 0, + 5, + 1, + 0, + 1, + 9, + 0, + 0, + 5, + 0, + 2, + 0, + 1, + 0, + 3, + 0, + 11, + 3, + 0, + 2, + 0, + 0, + 0, + 0, + 0, + 9, + 3, + 6, + 4, + 12, + 0, + 14, + 0, + 0, + 29, + 10, + 8, + 0, + 14, + 37, + 13, + 0, + 31, + 16, + 19, + 0, + 8, + 30, + 1, + 20, + 8, + 3, + 48, + 21, + 1, + 0, + 12, + 0, + 10, + 44, + 34, + 42, + 54, + 11, + 18, + 82, + 0, + 2, + 1, + 2, + 12, + 1, + 0, + 6, + 2, + 17, + 2, + 12, + 7, + 0, + 7, + 17, + 4, + 2, + 6, + 24, + 23, + 8, + 23, + 39, + 2, + 16, + 23, + 1, + 0, + 5, + 1, + 2, + 15, + 14, + 5, + 6, + 2, + 11, + 0, + 8, + 6, + 2, + 2, + 2, + 14, + 20, + 4, + 15, + 3, + 4, + 11, + 10, + 10, + 2, + 5, + 2, + 1, + 30, + 2, + 1, + 0, + 0, + 22, + 5, + 5, + 0, + 3, + 1, + 5, + 4, + 1, + 0, + 0, + 2, + 2, + 21, + 1, + 5, + 1, + 2, + 16, + 2, + 1, + 3, + 4, + 0, + 8, + 4, + 0, + 0, + 5, + 14, + 11, + 2, + 16, + 1, + 13, + 1, + 7, + 0, + 22, + 15, + 3, + 1, + 22, + 7, + 14, + 22, + 19, + 11, + 24, + 18, + 46, + 10, + 20, + 64, + 45, + 3, + 2, + 0, + 4, + 5, + 0, + 1, + 4, + 25, + 1, + 0, + 0, + 2, + 10, + 0, + 0, + 0, + 1, + 0, + 1, + 2, + 0, + 0, + 9, + 1, + 2, + 0, + 0, + 0, + 2, + 5, + 2, + 1, + 1, + 5, + 5, + 8, + 1, + 1, + 1, + 5, + 1, + 4, + 9, + 1, + 3, + 0, + 1, + 0, + 1, + 1, + 2, + 0, + 0, + 2, + 0, + 1, + 8, + 22, + 8, + 1, + 0, + 0, + 0, + 0, + 4, + 2, + 1, + 0, + 9, + 8, + 5, + 0, + 9, + 1, + 30, + 24, + 2, + 6, + 4, + 39, + 0, + 14, + 5, + 16, + 6, + 26, + 179, + 0, + 2, + 1, + 1, + 0, + 0, + 0, + 5, + 2, + 9, + 6, + 0, + 2, + 5, + 16, + 7, + 5, + 1, + 1, + 0, + 2, + 4, + 4, + 7, + 15, + 13, + 14, + 0, + 0, + 3, + 0, + 1, + 0, + 0, + 0, + 2, + 1, + 6, + 4, + 5, + 1, + 4, + 9, + 0, + 3, + 1, + 8, + 0, + 0, + 10, + 5, + 0, + 43, + 0, + 2, + 6, + 8, + 4, + 0, + 2, + 0, + 0, + 9, + 6, + 0, + 9, + 3, + 1, + 6, + 20, + 14, + 6, + 1, + 4, + 0, + 7, + 2, + 3, + 0, + 2, + 0, + 5, + 0, + 3, + 1, + 0, + 3, + 9, + 7, + 0, + 3, + 4, + 0, + 4, + 9, + 1, + 6, + 0, + 9, + 0, + 0, + 2, + 3, + 10, + 9, + 28, + 3, + 6, + 2, + 4, + 1, + 2, + 32, + 4, + 1, + 18, + 2, + 0, + 3, + 1, + 5, + 30, + 10, + 0, + 2, + 2, + 2, + 0, + 7, + 9, + 8, + 11, + 10, + 11, + 7, + 2, + 13, + 7, + 5, + 10, + 0, + 3, + 40, + 2, + 0, + 1, + 6, + 12, + 0, + 4, + 5, + 1, + 5, + 11, + 11, + 21, + 4, + 8, + 3, + 7, + 8, + 8, + 33, + 5, + 23, + 0, + 0, + 19, + 8, + 8, + 2, + 3, + 0, + 6, + 1, + 1, + 1, + 5, + 1, + 27, + 4, + 2, + 5, + 0, + 3, + 5, + 6, + 3, + 1, + 0, + 3, + 1, + 12, + 5, + 3, + 3, + 2, + 0, + 7, + 7, + 2, + 1, + 0, + 4, + 0, + 1, + 1, + 2, + 0, + 10, + 10, + 6, + 2, + 5, + 9, + 7, + 5, + 15, + 15, + 21, + 6, + 11, + 5, + 20, + 4, + 3, + 5, + 5, + 2, + 5, + 0, + 2, + 1, + 0, + 1, + 7, + 28, + 0, + 9, + 0, + 5, + 12, + 5, + 5, + 18, + 30, + 0, + 12, + 3, + 3, + 21, + 16, + 25, + 32, + 9, + 3, + 14, + 11, + 24, + 5, + 66, + 9, + 1, + 2, + 0, + 5, + 9, + 1, + 5, + 1, + 8, + 0, + 8, + 3, + 3, + 0, + 1, + 15, + 1, + 4, + 8, + 1, + 2, + 7, + 0, + 7, + 2, + 8, + 3, + 7, + 5, + 3, + 7, + 10, + 2, + 1, + 0, + 0, + 2, + 25, + 0, + 6, + 4, + 0, + 10, + 0, + 4, + 2, + 4, + 1, + 12, + 5, + 38, + 4, + 0, + 4, + 1, + 10, + 5, + 9, + 4, + 0, + 14, + 4, + 2, + 5, + 18, + 20, + 21, + 1, + 3, + 0, + 5, + 0, + 7, + 0, + 3, + 7, + 1, + 3, + 1, + 1, + 8, + 1, + 0, + 0, + 0, + 3, + 2, + 5, + 2, + 11, + 6, + 0, + 13, + 1, + 3, + 9, + 1, + 12, + 0, + 16, + 6, + 2, + 1, + 0, + 2, + 1, + 12, + 6, + 13, + 11, + 2, + 0, + 28, + 1, + 7, + 8, + 14, + 13, + 8, + 13, + 0, + 2, + 0, + 5, + 4, + 8, + 10, + 2, + 37, + 42, + 19, + 6, + 6, + 7, + 4, + 14, + 11, + 18, + 14, + 80, + 7, + 6, + 0, + 4, + 72, + 12, + 36, + 27, + 7, + 7, + 0, + 14, + 17, + 19, + 164, + 27, + 0, + 5, + 10, + 7, + 3, + 13, + 6, + 14, + 0, + 2, + 2, + 5, + 3, + 0, + 6, + 13, + 0, + 0, + 10, + 29, + 0, + 4, + 0, + 3, + 13, + 0, + 3, + 1, + 6, + 51, + 1, + 5, + 28, + 2, + 0, + 8, + 0, + 20, + 2, + 4, + 0, + 25, + 2, + 10, + 13, + 10, + 0, + 16, + 4, + 0, + 1, + 0, + 2, + 1, + 7, + 0, + 1, + 8, + 11, + 0, + 0, + 1, + 2, + 7, + 2, + 23, + 11, + 6, + 6, + 4, + 16, + 2, + 2, + 2, + 0, + 22, + 9, + 3, + 3, + 5, + 2, + 0, + 15, + 16, + 21, + 2, + 9, + 20, + 15, + 15, + 5, + 3, + 9, + 1, + 0, + 0, + 1, + 7, + 7, + 5, + 4, + 2, + 2, + 2, + 38, + 24, + 14, + 0, + 0, + 15, + 5, + 6, + 24, + 14, + 5, + 5, + 11, + 0, + 21, + 12, + 0, + 3, + 8, + 4, + 11, + 1, + 8, + 0, + 11, + 27, + 7, + 2, + 4, + 9, + 21, + 59, + 0, + 1, + 39, + 3, + 60, + 62, + 3, + 0, + 12, + 11, + 0, + 3, + 30, + 11, + 0, + 13, + 88, + 4, + 15, + 5, + 28, + 13, + 1, + 4, + 48, + 17, + 17, + 4, + 28, + 32, + 46, + 0, + 16, + 0, + 18, + 11, + 1, + 8, + 6, + 38, + 11, + 2, + 6, + 11, + 38, + 2, + 0, + 45, + 3, + 11, + 2, + 7, + 8, + 4, + 30, + 14, + 17, + 2, + 1, + 1, + 65, + 18, + 12, + 16, + 4, + 2, + 45, + 123, + 12, + 56, + 33, + 1, + 4, + 3, + 4, + 7, + 0, + 0, + 0, + 3, + 2, + 0, + 16, + 4, + 2, + 4, + 2, + 0, + 7, + 4, + 5, + 2, + 26, + 2, + 25, + 6, + 11, + 6, + 1, + 16, + 2, + 6, + 17, + 77, + 15, + 3, + 35, + 0, + 1, + 0, + 5, + 1, + 0, + 38, + 16, + 6, + 3, + 12, + 3, + 3, + 3, + 0, + 9, + 3, + 1, + 3, + 5, + 2, + 9, + 0, + 18, + 0, + 25, + 1, + 3, + 32, + 1, + 72, + 46, + 6, + 2, + 7, + 1, + 3, + 14, + 17, + 0, + 28, + 1, + 40, + 13, + 0, + 20, + 15, + 40, + 6, + 38, + 24, + 12, + 43, + 1, + 1, + 9, + 0, + 12, + 6, + 0, + 6, + 2, + 4, + 19, + 3, + 7, + 1, + 48, + 0, + 9, + 5, + 0, + 5, + 6, + 9, + 6, + 10, + 15, + 2, + 11, + 19, + 3, + 9, + 2, + 0, + 1, + 10, + 1, + 27, + 8, + 1, + 3, + 6, + 1, + 14, + 0, + 26, + 0, + 27, + 16, + 3, + 4, + 9, + 6, + 2, + 23, + 9, + 10, + 5, + 25, + 2, + 1, + 6, + 1, + 1, + 48, + 15, + 9, + 15, + 14, + 3, + 4, + 26, + 60, + 29, + 13, + 37, + 21, + 1, + 6, + 4, + 0, + 2, + 11, + 22, + 23, + 16, + 16, + 2, + 2, + 1, + 3, + 0, + 5, + 1, + 6, + 4, + 0, + 0, + 4, + 0, + 0, + 8, + 3, + 0, + 2, + 5, + 0, + 7, + 1, + 7, + 3, + 13, + 2, + 4, + 10, + 3, + 0, + 2, + 31, + 0, + 18, + 3, + 0, + 12, + 10, + 4, + 1, + 0, + 7, + 5, + 7, + 0, + 5, + 4, + 12, + 2, + 22, + 10, + 4, + 2, + 15, + 2, + 8, + 9, + 0, + 23, + 2, + 197, + 51, + 3, + 1, + 1, + 4, + 13, + 4, + 3, + 21, + 4, + 19, + 3, + 10, + 5, + 40, + 0, + 4, + 1, + 1, + 10, + 4, + 1, + 27, + 34, + 7, + 21, + 2, + 17, + 2, + 9, + 6, + 4, + 2, + 3, + 0, + 4, + 2, + 7, + 8, + 2, + 5, + 1, + 15, + 21, + 3, + 4, + 4, + 2, + 2, + 17, + 22, + 1, + 5, + 22, + 4, + 26, + 7, + 0, + 32, + 1, + 11, + 42, + 15, + 4, + 1, + 2, + 5, + 0, + 19, + 3, + 1, + 8, + 6, + 0, + 10, + 1, + 9, + 2, + 13, + 30, + 8, + 2, + 24, + 17, + 19, + 1, + 4, + 4, + 25, + 13, + 0, + 10, + 16, + 11, + 39, + 18, + 8, + 5, + 30, + 82, + 1, + 6, + 8, + 18, + 77, + 11, + 13, + 20, + 75, + 11, + 112, + 78, + 33, + 3, + 0, + 0, + 60, + 17, + 84, + 9, + 1, + 1, + 12, + 30, + 10, + 49, + 5, + 32, + 158, + 178, + 5, + 5, + 6, + 3, + 3, + 1, + 3, + 1, + 4, + 7, + 6, + 19, + 31, + 21, + 0, + 2, + 9, + 5, + 6, + 27, + 4, + 9, + 8, + 1, + 76, + 18, + 12, + 1, + 4, + 0, + 3, + 3, + 6, + 3, + 12, + 2, + 8, + 30, + 16, + 2, + 25, + 1, + 5, + 5, + 4, + 3, + 0, + 6, + 10, + 2, + 3, + 1, + 0, + 5, + 1, + 19, + 3, + 0, + 8, + 1, + 5, + 2, + 6, + 0, + 0, + 0, + 19, + 1, + 2, + 0, + 5, + 1, + 2, + 5, + 1, + 3, + 7, + 0, + 4, + 12, + 7, + 3, + 10, + 22, + 0, + 9, + 5, + 1, + 0, + 2, + 20, + 1, + 1, + 3, + 23, + 30, + 3, + 9, + 9, + 1, + 4, + 191, + 14, + 3, + 15, + 6, + 8, + 50, + 0, + 1, + 0, + 0, + 4, + 0, + 0, + 1, + 0, + 2, + 4, + 2, + 0, + 2, + 3, + 0, + 2, + 0, + 2, + 2, + 8, + 7, + 0, + 1, + 1, + 1, + 3, + 3, + 17, + 11, + 91, + 1, + 9, + 3, + 2, + 13, + 4, + 24, + 15, + 41, + 3, + 13, + 3, + 1, + 20, + 4, + 125, + 29, + 30, + 1, + 0, + 4, + 12, + 2, + 21, + 4, + 5, + 5, + 19, + 11, + 0, + 13, + 11, + 86, + 2, + 18, + 0, + 7, + 1, + 8, + 8, + 2, + 2, + 22, + 1, + 2, + 6, + 5, + 2, + 0, + 1, + 2, + 8, + 0, + 2, + 0, + 5, + 2, + 1, + 0, + 2, + 10, + 2, + 0, + 5, + 9, + 2, + 1, + 2, + 0, + 1, + 0, + 4, + 0, + 0, + 10, + 2, + 5, + 3, + 0, + 6, + 1, + 0, + 1, + 4, + 4, + 33, + 3, + 13, + 17, + 3, + 18, + 6, + 4, + 7, + 1, + 5, + 78, + 0, + 4, + 1, + 13, + 7, + 1, + 8, + 1, + 0, + 35, + 27, + 15, + 3, + 0, + 0, + 0, + 1, + 11, + 5, + 41, + 38, + 15, + 22, + 6, + 14, + 14, + 2, + 1, + 11, + 6, + 20, + 63, + 5, + 8, + 27, + 7, + 11, + 2, + 2, + 40, + 58, + 23, + 50, + 54, + 56, + 293, + 8, + 8, + 1, + 5, + 1, + 14, + 0, + 1, + 12, + 37, + 89, + 8, + 8, + 8, + 2, + 10, + 6, + 0, + 0, + 0, + 4, + 5, + 2, + 1, + 0, + 1, + 1, + 2, + 7, + 0, + 3, + 3, + 0, + 4, + 6, + 0, + 3, + 2, + 19, + 3, + 8, + 0, + 0, + 0, + 4, + 4, + 16, + 0, + 4, + 1, + 5, + 1, + 3, + 0, + 3, + 4, + 6, + 2, + 17, + 10, + 10, + 31, + 6, + 4, + 3, + 6, + 10, + 126, + 7, + 3, + 2, + 2, + 0, + 9, + 0, + 0, + 5, + 20, + 13, + 0, + 15, + 0, + 6, + 0, + 2, + 5, + 8, + 64, + 50, + 3, + 2, + 12, + 2, + 9, + 0, + 0, + 11, + 8, + 20, + 109, + 2, + 18, + 23, + 0, + 0, + 9, + 61, + 3, + 0, + 28, + 41, + 77, + 27, + 19, + 17, + 81, + 5, + 2, + 14, + 5, + 83, + 57, + 252, + 14, + 154, + 263, + 14, + 20, + 8, + 13, + 6, + 57, + 39, + 38, + }; + static ImWchar base_ranges[] = + { + 0x0020, 0x00FF, // Basic Latin + Latin Supplement + 0x3000, 0x30FF, // Punctuations, Hiragana, Katakana + 0x31F0, 0x31FF, // Katakana Phonetic Extensions + 0xFF00, 0xFFEF, // Half-width characters + }; + static bool full_ranges_unpacked = false; + static ImWchar full_ranges[IM_ARRAYSIZE(base_ranges) + IM_ARRAYSIZE(offsets_from_0x4E00) * 2 + 1]; + if (!full_ranges_unpacked) + { + // Unpack + int codepoint = 0x4e00; + memcpy(full_ranges, base_ranges, sizeof(base_ranges)); + ImWchar* dst = full_ranges + IM_ARRAYSIZE(base_ranges); + ; + for (int n = 0; n < IM_ARRAYSIZE(offsets_from_0x4E00); n++, dst += 2) + dst[0] = dst[1] = (ImWchar)(codepoint += (offsets_from_0x4E00[n] + 1)); + dst[0] = 0; + full_ranges_unpacked = true; + } + return &full_ranges[0]; } -const ImWchar* ImFontAtlas::GetGlyphRangesCyrillic() +const ImWchar* ImFontAtlas::GetGlyphRangesCyrillic() { - static const ImWchar ranges[] = - { - 0x0020, 0x00FF, // Basic Latin + Latin Supplement - 0x0400, 0x052F, // Cyrillic + Cyrillic Supplement - 0x2DE0, 0x2DFF, // Cyrillic Extended-A - 0xA640, 0xA69F, // Cyrillic Extended-B - 0, - }; - return &ranges[0]; + static const ImWchar ranges[] = + { + 0x0020, + 0x00FF, // Basic Latin + Latin Supplement + 0x0400, + 0x052F, // Cyrillic + Cyrillic Supplement + 0x2DE0, + 0x2DFF, // Cyrillic Extended-A + 0xA640, + 0xA69F, // Cyrillic Extended-B + 0, + }; + return &ranges[0]; } -const ImWchar* ImFontAtlas::GetGlyphRangesThai() +const ImWchar* ImFontAtlas::GetGlyphRangesThai() { - static const ImWchar ranges[] = - { - 0x0020, 0x00FF, // Basic Latin - 0x2010, 0x205E, // Punctuations - 0x0E00, 0x0E7F, // Thai - 0, - }; - return &ranges[0]; + static const ImWchar ranges[] = + { + 0x0020, + 0x00FF, // Basic Latin + 0x2010, + 0x205E, // Punctuations + 0x0E00, + 0x0E7F, // Thai + 0, + }; + return &ranges[0]; } //----------------------------------------------------------------------------- @@ -2093,36 +4141,36 @@ const ImWchar* ImFontAtlas::GetGlyphRangesThai() void ImFontAtlas::GlyphRangesBuilder::AddText(const char* text, const char* text_end) { - while (text_end ? (text < text_end) : *text) - { - unsigned int c = 0; - int c_len = ImTextCharFromUtf8(&c, text, text_end); - text += c_len; - if (c_len == 0) - break; - if (c < 0x10000) - AddChar((ImWchar)c); - } + while (text_end ? (text < text_end) : *text) + { + unsigned int c = 0; + int c_len = ImTextCharFromUtf8(&c, text, text_end); + text += c_len; + if (c_len == 0) + break; + if (c < 0x10000) + AddChar((ImWchar)c); + } } void ImFontAtlas::GlyphRangesBuilder::AddRanges(const ImWchar* ranges) { - for (; ranges[0]; ranges += 2) - for (ImWchar c = ranges[0]; c <= ranges[1]; c++) - AddChar(c); + for (; ranges[0]; ranges += 2) + for (ImWchar c = ranges[0]; c <= ranges[1]; c++) + AddChar(c); } void ImFontAtlas::GlyphRangesBuilder::BuildRanges(ImVector* out_ranges) { - for (int n = 0; n < 0x10000; n++) - if (GetBit(n)) - { - out_ranges->push_back((ImWchar)n); - while (n < 0x10000 && GetBit(n + 1)) - n++; - out_ranges->push_back((ImWchar)n); - } - out_ranges->push_back(0); + for (int n = 0; n < 0x10000; n++) + if (GetBit(n)) + { + out_ranges->push_back((ImWchar)n); + while (n < 0x10000 && GetBit(n + 1)) + n++; + out_ranges->push_back((ImWchar)n); + } + out_ranges->push_back(0); } //----------------------------------------------------------------------------- @@ -2131,519 +4179,563 @@ void ImFontAtlas::GlyphRangesBuilder::BuildRanges(ImVector* out_ranges) ImFont::ImFont() { - Scale = 1.0f; - FallbackChar = (ImWchar)'?'; - DisplayOffset = ImVec2(0.0f, 1.0f); - ClearOutputData(); + Scale = 1.0f; + FallbackChar = (ImWchar)'?'; + DisplayOffset = ImVec2(0.0f, 1.0f); + ClearOutputData(); } ImFont::~ImFont() { - // Invalidate active font so that the user gets a clear crash instead of a dangling pointer. - // If you want to delete fonts you need to do it between Render() and NewFrame(). - // FIXME-CLEANUP - /* + // Invalidate active font so that the user gets a clear crash instead of a dangling pointer. + // If you want to delete fonts you need to do it between Render() and NewFrame(). + // FIXME-CLEANUP + /* ImGuiContext& g = *GImGui; if (g.Font == this) g.Font = NULL; */ - ClearOutputData(); + ClearOutputData(); } -void ImFont::ClearOutputData() +void ImFont::ClearOutputData() { - FontSize = 0.0f; - Glyphs.clear(); - IndexAdvanceX.clear(); - IndexLookup.clear(); - FallbackGlyph = NULL; - FallbackAdvanceX = 0.0f; - ConfigDataCount = 0; - ConfigData = NULL; - ContainerAtlas = NULL; - Ascent = Descent = 0.0f; - MetricsTotalSurface = 0; + FontSize = 0.0f; + Glyphs.clear(); + IndexAdvanceX.clear(); + IndexLookup.clear(); + FallbackGlyph = NULL; + FallbackAdvanceX = 0.0f; + ConfigDataCount = 0; + ConfigData = NULL; + ContainerAtlas = NULL; + Ascent = Descent = 0.0f; + MetricsTotalSurface = 0; } void ImFont::BuildLookupTable() { - int max_codepoint = 0; - for (int i = 0; i != Glyphs.Size; i++) - max_codepoint = ImMax(max_codepoint, (int)Glyphs[i].Codepoint); + int max_codepoint = 0; + for (int i = 0; i != Glyphs.Size; i++) + max_codepoint = ImMax(max_codepoint, (int)Glyphs[i].Codepoint); - IM_ASSERT(Glyphs.Size < 0xFFFF); // -1 is reserved - IndexAdvanceX.clear(); - IndexLookup.clear(); - GrowIndex(max_codepoint + 1); - for (int i = 0; i < Glyphs.Size; i++) - { - int codepoint = (int)Glyphs[i].Codepoint; - IndexAdvanceX[codepoint] = Glyphs[i].AdvanceX; - IndexLookup[codepoint] = (unsigned short)i; - } + IM_ASSERT(Glyphs.Size < 0xFFFF); // -1 is reserved + IndexAdvanceX.clear(); + IndexLookup.clear(); + GrowIndex(max_codepoint + 1); + for (int i = 0; i < Glyphs.Size; i++) + { + int codepoint = (int)Glyphs[i].Codepoint; + IndexAdvanceX[codepoint] = Glyphs[i].AdvanceX; + IndexLookup[codepoint] = (unsigned short)i; + } - // Create a glyph to handle TAB - // FIXME: Needs proper TAB handling but it needs to be contextualized (or we could arbitrary say that each string starts at "column 0" ?) - if (FindGlyph((unsigned short)' ')) - { - if (Glyphs.back().Codepoint != '\t') // So we can call this function multiple times - Glyphs.resize(Glyphs.Size + 1); - ImFontGlyph& tab_glyph = Glyphs.back(); - tab_glyph = *FindGlyph((unsigned short)' '); - tab_glyph.Codepoint = '\t'; - tab_glyph.AdvanceX *= 4; - IndexAdvanceX[(int)tab_glyph.Codepoint] = (float)tab_glyph.AdvanceX; - IndexLookup[(int)tab_glyph.Codepoint] = (unsigned short)(Glyphs.Size-1); - } + // Create a glyph to handle TAB + // FIXME: Needs proper TAB handling but it needs to be contextualized (or we could arbitrary say that each string starts at "column 0" ?) + if (FindGlyph((unsigned short)' ')) + { + if (Glyphs.back().Codepoint != '\t') // So we can call this function multiple times + Glyphs.resize(Glyphs.Size + 1); + ImFontGlyph& tab_glyph = Glyphs.back(); + tab_glyph = *FindGlyph((unsigned short)' '); + tab_glyph.Codepoint = '\t'; + tab_glyph.AdvanceX *= 4; + IndexAdvanceX[(int)tab_glyph.Codepoint] = (float)tab_glyph.AdvanceX; + IndexLookup[(int)tab_glyph.Codepoint] = (unsigned short)(Glyphs.Size - 1); + } - FallbackGlyph = NULL; - FallbackGlyph = FindGlyph(FallbackChar); - FallbackAdvanceX = FallbackGlyph ? FallbackGlyph->AdvanceX : 0.0f; - for (int i = 0; i < max_codepoint + 1; i++) - if (IndexAdvanceX[i] < 0.0f) - IndexAdvanceX[i] = FallbackAdvanceX; + FallbackGlyph = NULL; + FallbackGlyph = FindGlyph(FallbackChar); + FallbackAdvanceX = FallbackGlyph ? FallbackGlyph->AdvanceX : 0.0f; + for (int i = 0; i < max_codepoint + 1; i++) + if (IndexAdvanceX[i] < 0.0f) + IndexAdvanceX[i] = FallbackAdvanceX; } void ImFont::SetFallbackChar(ImWchar c) { - FallbackChar = c; - BuildLookupTable(); + FallbackChar = c; + BuildLookupTable(); } void ImFont::GrowIndex(int new_size) { - IM_ASSERT(IndexAdvanceX.Size == IndexLookup.Size); - if (new_size <= IndexLookup.Size) - return; - IndexAdvanceX.resize(new_size, -1.0f); - IndexLookup.resize(new_size, (unsigned short)-1); + IM_ASSERT(IndexAdvanceX.Size == IndexLookup.Size); + if (new_size <= IndexLookup.Size) + return; + IndexAdvanceX.resize(new_size, -1.0f); + IndexLookup.resize(new_size, (unsigned short)-1); } void ImFont::AddGlyph(ImWchar codepoint, float x0, float y0, float x1, float y1, float u0, float v0, float u1, float v1, float advance_x) { - Glyphs.resize(Glyphs.Size + 1); - ImFontGlyph& glyph = Glyphs.back(); - glyph.Codepoint = (ImWchar)codepoint; - glyph.X0 = x0; - glyph.Y0 = y0; - glyph.X1 = x1; - glyph.Y1 = y1; - glyph.U0 = u0; - glyph.V0 = v0; - glyph.U1 = u1; - glyph.V1 = v1; - glyph.AdvanceX = advance_x + ConfigData->GlyphExtraSpacing.x; // Bake spacing into AdvanceX + Glyphs.resize(Glyphs.Size + 1); + ImFontGlyph& glyph = Glyphs.back(); + glyph.Codepoint = (ImWchar)codepoint; + glyph.X0 = x0; + glyph.Y0 = y0; + glyph.X1 = x1; + glyph.Y1 = y1; + glyph.U0 = u0; + glyph.V0 = v0; + glyph.U1 = u1; + glyph.V1 = v1; + glyph.AdvanceX = advance_x + ConfigData->GlyphExtraSpacing.x; // Bake spacing into AdvanceX - if (ConfigData->PixelSnapH) - glyph.AdvanceX = (float)(int)(glyph.AdvanceX + 0.5f); - - // Compute rough surface usage metrics (+1 to account for average padding, +0.99 to round) - MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * ContainerAtlas->TexWidth + 1.99f) * (int)((glyph.V1 - glyph.V0) * ContainerAtlas->TexHeight + 1.99f); + if (ConfigData->PixelSnapH) + glyph.AdvanceX = (float)(int)(glyph.AdvanceX + 0.5f); + + // Compute rough surface usage metrics (+1 to account for average padding, +0.99 to round) + MetricsTotalSurface += (int)((glyph.U1 - glyph.U0) * ContainerAtlas->TexWidth + 1.99f) * (int)((glyph.V1 - glyph.V0) * ContainerAtlas->TexHeight + 1.99f); } void ImFont::AddRemapChar(ImWchar dst, ImWchar src, bool overwrite_dst) { - IM_ASSERT(IndexLookup.Size > 0); // Currently this can only be called AFTER the font has been built, aka after calling ImFontAtlas::GetTexDataAs*() function. - int index_size = IndexLookup.Size; + IM_ASSERT(IndexLookup.Size > 0); // Currently this can only be called AFTER the font has been built, aka after calling ImFontAtlas::GetTexDataAs*() function. + int index_size = IndexLookup.Size; - if (dst < index_size && IndexLookup.Data[dst] == (unsigned short)-1 && !overwrite_dst) // 'dst' already exists - return; - if (src >= index_size && dst >= index_size) // both 'dst' and 'src' don't exist -> no-op - return; + if (dst < index_size && IndexLookup.Data[dst] == (unsigned short)-1 && !overwrite_dst) // 'dst' already exists + return; + if (src >= index_size && dst >= index_size) // both 'dst' and 'src' don't exist -> no-op + return; - GrowIndex(dst + 1); - IndexLookup[dst] = (src < index_size) ? IndexLookup.Data[src] : (unsigned short)-1; - IndexAdvanceX[dst] = (src < index_size) ? IndexAdvanceX.Data[src] : 1.0f; + GrowIndex(dst + 1); + IndexLookup[dst] = (src < index_size) ? IndexLookup.Data[src] : (unsigned short)-1; + IndexAdvanceX[dst] = (src < index_size) ? IndexAdvanceX.Data[src] : 1.0f; } const ImFontGlyph* ImFont::FindGlyph(ImWchar c) const { - if (c < IndexLookup.Size) - { - const unsigned short i = IndexLookup[c]; - if (i != (unsigned short)-1) - return &Glyphs.Data[i]; - } - return FallbackGlyph; + if (c < IndexLookup.Size) + { + const unsigned short i = IndexLookup[c]; + if (i != (unsigned short)-1) + return &Glyphs.Data[i]; + } + return FallbackGlyph; } const char* ImFont::CalcWordWrapPositionA(float scale, const char* text, const char* text_end, float wrap_width) const { - // Simple word-wrapping for English, not full-featured. Please submit failing cases! - // FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.) + // Simple word-wrapping for English, not full-featured. Please submit failing cases! + // FIXME: Much possible improvements (don't cut things like "word !", "word!!!" but cut within "word,,,,", more sensible support for punctuations, support for Unicode punctuations, etc.) - // For references, possible wrap point marked with ^ - // "aaa bbb, ccc,ddd. eee fff. ggg!" - // ^ ^ ^ ^ ^__ ^ ^ + // For references, possible wrap point marked with ^ + // "aaa bbb, ccc,ddd. eee fff. ggg!" + // ^ ^ ^ ^ ^__ ^ ^ - // List of hardcoded separators: .,;!?'" + // List of hardcoded separators: .,;!?'" - // Skip extra blanks after a line returns (that includes not counting them in width computation) - // e.g. "Hello world" --> "Hello" "World" + // Skip extra blanks after a line returns (that includes not counting them in width computation) + // e.g. "Hello world" --> "Hello" "World" - // Cut words that cannot possibly fit within one line. - // e.g.: "The tropical fish" with ~5 characters worth of width --> "The tr" "opical" "fish" + // Cut words that cannot possibly fit within one line. + // e.g.: "The tropical fish" with ~5 characters worth of width --> "The tr" "opical" "fish" - float line_width = 0.0f; - float word_width = 0.0f; - float blank_width = 0.0f; - wrap_width /= scale; // We work with unscaled widths to avoid scaling every characters + float line_width = 0.0f; + float word_width = 0.0f; + float blank_width = 0.0f; + wrap_width /= scale; // We work with unscaled widths to avoid scaling every characters - const char* word_end = text; - const char* prev_word_end = NULL; - bool inside_word = true; + const char* word_end = text; + const char* prev_word_end = NULL; + bool inside_word = true; - const char* s = text; - while (s < text_end) - { - unsigned int c = (unsigned int)*s; - const char* next_s; - if (c < 0x80) - next_s = s + 1; - else - next_s = s + ImTextCharFromUtf8(&c, s, text_end); - if (c == 0) - break; + const char* s = text; + while (s < text_end) + { + unsigned int c = (unsigned int)*s; + const char* next_s; + if (c < 0x80) + next_s = s + 1; + else + next_s = s + ImTextCharFromUtf8(&c, s, text_end); + if (c == 0) + break; - if (c < 32) - { - if (c == '\n') - { - line_width = word_width = blank_width = 0.0f; - inside_word = true; - s = next_s; - continue; - } - if (c == '\r') - { - s = next_s; - continue; - } - } + if (c < 32) + { + if (c == '\n') + { + line_width = word_width = blank_width = 0.0f; + inside_word = true; + s = next_s; + continue; + } + if (c == '\r') + { + s = next_s; + continue; + } + } - const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX[(int)c] : FallbackAdvanceX); - if (ImCharIsSpace(c)) - { - if (inside_word) - { - line_width += blank_width; - blank_width = 0.0f; - word_end = s; - } - blank_width += char_width; - inside_word = false; - } - else - { - word_width += char_width; - if (inside_word) - { - word_end = next_s; - } - else - { - prev_word_end = word_end; - line_width += word_width + blank_width; - word_width = blank_width = 0.0f; - } + const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX[(int)c] : FallbackAdvanceX); + if (ImCharIsSpace(c)) + { + if (inside_word) + { + line_width += blank_width; + blank_width = 0.0f; + word_end = s; + } + blank_width += char_width; + inside_word = false; + } + else + { + word_width += char_width; + if (inside_word) + { + word_end = next_s; + } + else + { + prev_word_end = word_end; + line_width += word_width + blank_width; + word_width = blank_width = 0.0f; + } - // Allow wrapping after punctuation. - inside_word = !(c == '.' || c == ',' || c == ';' || c == '!' || c == '?' || c == '\"'); - } + // Allow wrapping after punctuation. + inside_word = !(c == '.' || c == ',' || c == ';' || c == '!' || c == '?' || c == '\"'); + } - // We ignore blank width at the end of the line (they can be skipped) - if (line_width + word_width >= wrap_width) - { - // Words that cannot possibly fit within an entire line will be cut anywhere. - if (word_width < wrap_width) - s = prev_word_end ? prev_word_end : word_end; - break; - } + // We ignore blank width at the end of the line (they can be skipped) + if (line_width + word_width >= wrap_width) + { + // Words that cannot possibly fit within an entire line will be cut anywhere. + if (word_width < wrap_width) + s = prev_word_end ? prev_word_end : word_end; + break; + } - s = next_s; - } + s = next_s; + } - return s; + return s; } ImVec2 ImFont::CalcTextSizeA(float size, float max_width, float wrap_width, const char* text_begin, const char* text_end, const char** remaining) const { - if (!text_end) - text_end = text_begin + strlen(text_begin); // FIXME-OPT: Need to avoid this. + if (!text_end) + text_end = text_begin + strlen(text_begin); // FIXME-OPT: Need to avoid this. - const float line_height = size; - const float scale = size / FontSize; + const float line_height = size; + const float scale = size / FontSize; - ImVec2 text_size = ImVec2(0,0); - float line_width = 0.0f; + ImVec2 text_size = ImVec2(0, 0); + float line_width = 0.0f; - const bool word_wrap_enabled = (wrap_width > 0.0f); - const char* word_wrap_eol = NULL; + const bool word_wrap_enabled = (wrap_width > 0.0f); + const char* word_wrap_eol = NULL; - const char* s = text_begin; - while (s < text_end) - { - if (word_wrap_enabled) - { - // Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature. - if (!word_wrap_eol) - { - word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - line_width); - if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity. - word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below - } + const char* s = text_begin; + while (s < text_end) + { + if (word_wrap_enabled) + { + // Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature. + if (!word_wrap_eol) + { + word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - line_width); + if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity. + word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below + } - if (s >= word_wrap_eol) - { - if (text_size.x < line_width) - text_size.x = line_width; - text_size.y += line_height; - line_width = 0.0f; - word_wrap_eol = NULL; + if (s >= word_wrap_eol) + { + if (text_size.x < line_width) + text_size.x = line_width; + text_size.y += line_height; + line_width = 0.0f; + word_wrap_eol = NULL; - // Wrapping skips upcoming blanks - while (s < text_end) - { - const char c = *s; - if (ImCharIsSpace(c)) { s++; } else if (c == '\n') { s++; break; } else { break; } - } - continue; - } - } + // Wrapping skips upcoming blanks + while (s < text_end) + { + const char c = *s; + if (ImCharIsSpace(c)) + { + s++; + } + else if (c == '\n') + { + s++; + break; + } + else + { + break; + } + } + continue; + } + } - // Decode and advance source - const char* prev_s = s; - unsigned int c = (unsigned int)*s; - if (c < 0x80) - { - s += 1; - } - else - { - s += ImTextCharFromUtf8(&c, s, text_end); - if (c == 0) // Malformed UTF-8? - break; - } + // Decode and advance source + const char* prev_s = s; + unsigned int c = (unsigned int)*s; + if (c < 0x80) + { + s += 1; + } + else + { + s += ImTextCharFromUtf8(&c, s, text_end); + if (c == 0) // Malformed UTF-8? + break; + } - if (c < 32) - { - if (c == '\n') - { - text_size.x = ImMax(text_size.x, line_width); - text_size.y += line_height; - line_width = 0.0f; - continue; - } - if (c == '\r') - continue; - } + if (c < 32) + { + if (c == '\n') + { + text_size.x = ImMax(text_size.x, line_width); + text_size.y += line_height; + line_width = 0.0f; + continue; + } + if (c == '\r') + continue; + } - const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX[(int)c] : FallbackAdvanceX) * scale; - if (line_width + char_width >= max_width) - { - s = prev_s; - break; - } + const float char_width = ((int)c < IndexAdvanceX.Size ? IndexAdvanceX[(int)c] : FallbackAdvanceX) * scale; + if (line_width + char_width >= max_width) + { + s = prev_s; + break; + } - line_width += char_width; - } + line_width += char_width; + } - if (text_size.x < line_width) - text_size.x = line_width; + if (text_size.x < line_width) + text_size.x = line_width; - if (line_width > 0 || text_size.y == 0.0f) - text_size.y += line_height; + if (line_width > 0 || text_size.y == 0.0f) + text_size.y += line_height; - if (remaining) - *remaining = s; + if (remaining) + *remaining = s; - return text_size; + return text_size; } void ImFont::RenderChar(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, unsigned short c) const { - if (c == ' ' || c == '\t' || c == '\n' || c == '\r') // Match behavior of RenderText(), those 4 codepoints are hard-coded. - return; - if (const ImFontGlyph* glyph = FindGlyph(c)) - { - float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f; - pos.x = (float)(int)pos.x + DisplayOffset.x; - pos.y = (float)(int)pos.y + DisplayOffset.y; - draw_list->PrimReserve(6, 4); - draw_list->PrimRectUV(ImVec2(pos.x + glyph->X0 * scale, pos.y + glyph->Y0 * scale), ImVec2(pos.x + glyph->X1 * scale, pos.y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col); - } + if (c == ' ' || c == '\t' || c == '\n' || c == '\r') // Match behavior of RenderText(), those 4 codepoints are hard-coded. + return; + if (const ImFontGlyph* glyph = FindGlyph(c)) + { + float scale = (size >= 0.0f) ? (size / FontSize) : 1.0f; + pos.x = (float)(int)pos.x + DisplayOffset.x; + pos.y = (float)(int)pos.y + DisplayOffset.y; + draw_list->PrimReserve(6, 4); + draw_list->PrimRectUV(ImVec2(pos.x + glyph->X0 * scale, pos.y + glyph->Y0 * scale), ImVec2(pos.x + glyph->X1 * scale, pos.y + glyph->Y1 * scale), ImVec2(glyph->U0, glyph->V0), ImVec2(glyph->U1, glyph->V1), col); + } } void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col, const ImVec4& clip_rect, const char* text_begin, const char* text_end, float wrap_width, bool cpu_fine_clip) const { - if (!text_end) - text_end = text_begin + strlen(text_begin); // ImGui functions generally already provides a valid text_end, so this is merely to handle direct calls. + if (!text_end) + text_end = text_begin + strlen(text_begin); // ImGui functions generally already provides a valid text_end, so this is merely to handle direct calls. - // Align to be pixel perfect - pos.x = (float)(int)pos.x + DisplayOffset.x; - pos.y = (float)(int)pos.y + DisplayOffset.y; - float x = pos.x; - float y = pos.y; - if (y > clip_rect.w) - return; + // Align to be pixel perfect + pos.x = (float)(int)pos.x + DisplayOffset.x; + pos.y = (float)(int)pos.y + DisplayOffset.y; + float x = pos.x; + float y = pos.y; + if (y > clip_rect.w) + return; - const float scale = size / FontSize; - const float line_height = FontSize * scale; - const bool word_wrap_enabled = (wrap_width > 0.0f); - const char* word_wrap_eol = NULL; + const float scale = size / FontSize; + const float line_height = FontSize * scale; + const bool word_wrap_enabled = (wrap_width > 0.0f); + const char* word_wrap_eol = NULL; - // Skip non-visible lines - const char* s = text_begin; - if (!word_wrap_enabled && y + line_height < clip_rect.y) - while (s < text_end && *s != '\n') // Fast-forward to next line - s++; + // Skip non-visible lines + const char* s = text_begin; + if (!word_wrap_enabled && y + line_height < clip_rect.y) + while (s < text_end && *s != '\n') // Fast-forward to next line + s++; - // Reserve vertices for remaining worse case (over-reserving is useful and easily amortized) - const int vtx_count_max = (int)(text_end - s) * 4; - const int idx_count_max = (int)(text_end - s) * 6; - const int idx_expected_size = draw_list->IdxBuffer.Size + idx_count_max; - draw_list->PrimReserve(idx_count_max, vtx_count_max); + // Reserve vertices for remaining worse case (over-reserving is useful and easily amortized) + const int vtx_count_max = (int)(text_end - s) * 4; + const int idx_count_max = (int)(text_end - s) * 6; + const int idx_expected_size = draw_list->IdxBuffer.Size + idx_count_max; + draw_list->PrimReserve(idx_count_max, vtx_count_max); - ImDrawVert* vtx_write = draw_list->_VtxWritePtr; - ImDrawIdx* idx_write = draw_list->_IdxWritePtr; - unsigned int vtx_current_idx = draw_list->_VtxCurrentIdx; + ImDrawVert* vtx_write = draw_list->_VtxWritePtr; + ImDrawIdx* idx_write = draw_list->_IdxWritePtr; + unsigned int vtx_current_idx = draw_list->_VtxCurrentIdx; - while (s < text_end) - { - if (word_wrap_enabled) - { - // Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature. - if (!word_wrap_eol) - { - word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - (x - pos.x)); - if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity. - word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below - } + while (s < text_end) + { + if (word_wrap_enabled) + { + // Calculate how far we can render. Requires two passes on the string data but keeps the code simple and not intrusive for what's essentially an uncommon feature. + if (!word_wrap_eol) + { + word_wrap_eol = CalcWordWrapPositionA(scale, s, text_end, wrap_width - (x - pos.x)); + if (word_wrap_eol == s) // Wrap_width is too small to fit anything. Force displaying 1 character to minimize the height discontinuity. + word_wrap_eol++; // +1 may not be a character start point in UTF-8 but it's ok because we use s >= word_wrap_eol below + } - if (s >= word_wrap_eol) - { - x = pos.x; - y += line_height; - word_wrap_eol = NULL; + if (s >= word_wrap_eol) + { + x = pos.x; + y += line_height; + word_wrap_eol = NULL; - // Wrapping skips upcoming blanks - while (s < text_end) - { - const char c = *s; - if (ImCharIsSpace(c)) { s++; } else if (c == '\n') { s++; break; } else { break; } - } - continue; - } - } + // Wrapping skips upcoming blanks + while (s < text_end) + { + const char c = *s; + if (ImCharIsSpace(c)) + { + s++; + } + else if (c == '\n') + { + s++; + break; + } + else + { + break; + } + } + continue; + } + } - // Decode and advance source - unsigned int c = (unsigned int)*s; - if (c < 0x80) - { - s += 1; - } - else - { - s += ImTextCharFromUtf8(&c, s, text_end); - if (c == 0) // Malformed UTF-8? - break; - } + // Decode and advance source + unsigned int c = (unsigned int)*s; + if (c < 0x80) + { + s += 1; + } + else + { + s += ImTextCharFromUtf8(&c, s, text_end); + if (c == 0) // Malformed UTF-8? + break; + } - if (c < 32) - { - if (c == '\n') - { - x = pos.x; - y += line_height; + if (c < 32) + { + if (c == '\n') + { + x = pos.x; + y += line_height; - if (y > clip_rect.w) - break; - if (!word_wrap_enabled && y + line_height < clip_rect.y) - while (s < text_end && *s != '\n') // Fast-forward to next line - s++; - continue; - } - if (c == '\r') - continue; - } + if (y > clip_rect.w) + break; + if (!word_wrap_enabled && y + line_height < clip_rect.y) + while (s < text_end && *s != '\n') // Fast-forward to next line + s++; + continue; + } + if (c == '\r') + continue; + } - float char_width = 0.0f; - if (const ImFontGlyph* glyph = FindGlyph((unsigned short)c)) - { - char_width = glyph->AdvanceX * scale; + float char_width = 0.0f; + if (const ImFontGlyph* glyph = FindGlyph((unsigned short)c)) + { + char_width = glyph->AdvanceX * scale; - // Arbitrarily assume that both space and tabs are empty glyphs as an optimization - if (c != ' ' && c != '\t') - { - // We don't do a second finer clipping test on the Y axis as we've already skipped anything before clip_rect.y and exit once we pass clip_rect.w - float x1 = x + glyph->X0 * scale; - float x2 = x + glyph->X1 * scale; - float y1 = y + glyph->Y0 * scale; - float y2 = y + glyph->Y1 * scale; - if (x1 <= clip_rect.z && x2 >= clip_rect.x) - { - // Render a character - float u1 = glyph->U0; - float v1 = glyph->V0; - float u2 = glyph->U1; - float v2 = glyph->V1; + // Arbitrarily assume that both space and tabs are empty glyphs as an optimization + if (c != ' ' && c != '\t') + { + // We don't do a second finer clipping test on the Y axis as we've already skipped anything before clip_rect.y and exit once we pass clip_rect.w + float x1 = x + glyph->X0 * scale; + float x2 = x + glyph->X1 * scale; + float y1 = y + glyph->Y0 * scale; + float y2 = y + glyph->Y1 * scale; + if (x1 <= clip_rect.z && x2 >= clip_rect.x) + { + // Render a character + float u1 = glyph->U0; + float v1 = glyph->V0; + float u2 = glyph->U1; + float v2 = glyph->V1; - // CPU side clipping used to fit text in their frame when the frame is too small. Only does clipping for axis aligned quads. - if (cpu_fine_clip) - { - if (x1 < clip_rect.x) - { - u1 = u1 + (1.0f - (x2 - clip_rect.x) / (x2 - x1)) * (u2 - u1); - x1 = clip_rect.x; - } - if (y1 < clip_rect.y) - { - v1 = v1 + (1.0f - (y2 - clip_rect.y) / (y2 - y1)) * (v2 - v1); - y1 = clip_rect.y; - } - if (x2 > clip_rect.z) - { - u2 = u1 + ((clip_rect.z - x1) / (x2 - x1)) * (u2 - u1); - x2 = clip_rect.z; - } - if (y2 > clip_rect.w) - { - v2 = v1 + ((clip_rect.w - y1) / (y2 - y1)) * (v2 - v1); - y2 = clip_rect.w; - } - if (y1 >= y2) - { - x += char_width; - continue; - } - } + // CPU side clipping used to fit text in their frame when the frame is too small. Only does clipping for axis aligned quads. + if (cpu_fine_clip) + { + if (x1 < clip_rect.x) + { + u1 = u1 + (1.0f - (x2 - clip_rect.x) / (x2 - x1)) * (u2 - u1); + x1 = clip_rect.x; + } + if (y1 < clip_rect.y) + { + v1 = v1 + (1.0f - (y2 - clip_rect.y) / (y2 - y1)) * (v2 - v1); + y1 = clip_rect.y; + } + if (x2 > clip_rect.z) + { + u2 = u1 + ((clip_rect.z - x1) / (x2 - x1)) * (u2 - u1); + x2 = clip_rect.z; + } + if (y2 > clip_rect.w) + { + v2 = v1 + ((clip_rect.w - y1) / (y2 - y1)) * (v2 - v1); + y2 = clip_rect.w; + } + if (y1 >= y2) + { + x += char_width; + continue; + } + } - // We are NOT calling PrimRectUV() here because non-inlined causes too much overhead in a debug builds. Inlined here: - { - idx_write[0] = (ImDrawIdx)(vtx_current_idx); idx_write[1] = (ImDrawIdx)(vtx_current_idx+1); idx_write[2] = (ImDrawIdx)(vtx_current_idx+2); - idx_write[3] = (ImDrawIdx)(vtx_current_idx); idx_write[4] = (ImDrawIdx)(vtx_current_idx+2); idx_write[5] = (ImDrawIdx)(vtx_current_idx+3); - vtx_write[0].pos.x = x1; vtx_write[0].pos.y = y1; vtx_write[0].col = col; vtx_write[0].uv.x = u1; vtx_write[0].uv.y = v1; - vtx_write[1].pos.x = x2; vtx_write[1].pos.y = y1; vtx_write[1].col = col; vtx_write[1].uv.x = u2; vtx_write[1].uv.y = v1; - vtx_write[2].pos.x = x2; vtx_write[2].pos.y = y2; vtx_write[2].col = col; vtx_write[2].uv.x = u2; vtx_write[2].uv.y = v2; - vtx_write[3].pos.x = x1; vtx_write[3].pos.y = y2; vtx_write[3].col = col; vtx_write[3].uv.x = u1; vtx_write[3].uv.y = v2; - vtx_write += 4; - vtx_current_idx += 4; - idx_write += 6; - } - } - } - } + // We are NOT calling PrimRectUV() here because non-inlined causes too much overhead in a debug builds. Inlined here: + { + idx_write[0] = (ImDrawIdx)(vtx_current_idx); + idx_write[1] = (ImDrawIdx)(vtx_current_idx + 1); + idx_write[2] = (ImDrawIdx)(vtx_current_idx + 2); + idx_write[3] = (ImDrawIdx)(vtx_current_idx); + idx_write[4] = (ImDrawIdx)(vtx_current_idx + 2); + idx_write[5] = (ImDrawIdx)(vtx_current_idx + 3); + vtx_write[0].pos.x = x1; + vtx_write[0].pos.y = y1; + vtx_write[0].col = col; + vtx_write[0].uv.x = u1; + vtx_write[0].uv.y = v1; + vtx_write[1].pos.x = x2; + vtx_write[1].pos.y = y1; + vtx_write[1].col = col; + vtx_write[1].uv.x = u2; + vtx_write[1].uv.y = v1; + vtx_write[2].pos.x = x2; + vtx_write[2].pos.y = y2; + vtx_write[2].col = col; + vtx_write[2].uv.x = u2; + vtx_write[2].uv.y = v2; + vtx_write[3].pos.x = x1; + vtx_write[3].pos.y = y2; + vtx_write[3].col = col; + vtx_write[3].uv.x = u1; + vtx_write[3].uv.y = v2; + vtx_write += 4; + vtx_current_idx += 4; + idx_write += 6; + } + } + } + } - x += char_width; - } + x += char_width; + } - // Give back unused vertices - draw_list->VtxBuffer.resize((int)(vtx_write - draw_list->VtxBuffer.Data)); - draw_list->IdxBuffer.resize((int)(idx_write - draw_list->IdxBuffer.Data)); - draw_list->CmdBuffer[draw_list->CmdBuffer.Size-1].ElemCount -= (idx_expected_size - draw_list->IdxBuffer.Size); - draw_list->_VtxWritePtr = vtx_write; - draw_list->_IdxWritePtr = idx_write; - draw_list->_VtxCurrentIdx = (unsigned int)draw_list->VtxBuffer.Size; + // Give back unused vertices + draw_list->VtxBuffer.resize((int)(vtx_write - draw_list->VtxBuffer.Data)); + draw_list->IdxBuffer.resize((int)(idx_write - draw_list->IdxBuffer.Data)); + draw_list->CmdBuffer[draw_list->CmdBuffer.Size - 1].ElemCount -= (idx_expected_size - draw_list->IdxBuffer.Size); + draw_list->_VtxWritePtr = vtx_write; + draw_list->_IdxWritePtr = idx_write; + draw_list->_VtxCurrentIdx = (unsigned int)draw_list->VtxBuffer.Size; } //----------------------------------------------------------------------------- @@ -2652,70 +4744,70 @@ void ImFont::RenderText(ImDrawList* draw_list, float size, ImVec2 pos, ImU32 col static inline float ImAcos01(float x) { - if (x <= 0.0f) return IM_PI * 0.5f; - if (x >= 1.0f) return 0.0f; - return acosf(x); - //return (-0.69813170079773212f * x * x - 0.87266462599716477f) * x + 1.5707963267948966f; // Cheap approximation, may be enough for what we do. + if (x <= 0.0f) return IM_PI * 0.5f; + if (x >= 1.0f) return 0.0f; + return acosf(x); + //return (-0.69813170079773212f * x * x - 0.87266462599716477f) * x + 1.5707963267948966f; // Cheap approximation, may be enough for what we do. } // FIXME: Cleanup and move code to ImDrawList. void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding) { - if (x_end_norm == x_start_norm) - return; - if (x_start_norm > x_end_norm) - ImSwap(x_start_norm, x_end_norm); + if (x_end_norm == x_start_norm) + return; + if (x_start_norm > x_end_norm) + ImSwap(x_start_norm, x_end_norm); - ImVec2 p0 = ImVec2(ImLerp(rect.Min.x, rect.Max.x, x_start_norm), rect.Min.y); - ImVec2 p1 = ImVec2(ImLerp(rect.Min.x, rect.Max.x, x_end_norm), rect.Max.y); - if (rounding == 0.0f) - { - draw_list->AddRectFilled(p0, p1, col, 0.0f); - return; - } + ImVec2 p0 = ImVec2(ImLerp(rect.Min.x, rect.Max.x, x_start_norm), rect.Min.y); + ImVec2 p1 = ImVec2(ImLerp(rect.Min.x, rect.Max.x, x_end_norm), rect.Max.y); + if (rounding == 0.0f) + { + draw_list->AddRectFilled(p0, p1, col, 0.0f); + return; + } - rounding = ImClamp(ImMin((rect.Max.x - rect.Min.x) * 0.5f, (rect.Max.y - rect.Min.y) * 0.5f) - 1.0f, 0.0f, rounding); - const float inv_rounding = 1.0f / rounding; - const float arc0_b = ImAcos01(1.0f - (p0.x - rect.Min.x) * inv_rounding); - const float arc0_e = ImAcos01(1.0f - (p1.x - rect.Min.x) * inv_rounding); - const float x0 = ImMax(p0.x, rect.Min.x + rounding); - if (arc0_b == arc0_e) - { - draw_list->PathLineTo(ImVec2(x0, p1.y)); - draw_list->PathLineTo(ImVec2(x0, p0.y)); - } - else if (arc0_b == 0.0f && arc0_e == IM_PI*0.5f) - { - draw_list->PathArcToFast(ImVec2(x0, p1.y - rounding), rounding, 3, 6); // BL - draw_list->PathArcToFast(ImVec2(x0, p0.y + rounding), rounding, 6, 9); // TR - } - else - { - draw_list->PathArcTo(ImVec2(x0, p1.y - rounding), rounding, IM_PI - arc0_e, IM_PI - arc0_b, 3); // BL - draw_list->PathArcTo(ImVec2(x0, p0.y + rounding), rounding, IM_PI + arc0_b, IM_PI + arc0_e, 3); // TR - } - if (p1.x > rect.Min.x + rounding) - { - const float arc1_b = ImAcos01(1.0f - (rect.Max.x - p1.x) * inv_rounding); - const float arc1_e = ImAcos01(1.0f - (rect.Max.x - p0.x) * inv_rounding); - const float x1 = ImMin(p1.x, rect.Max.x - rounding); - if (arc1_b == arc1_e) - { - draw_list->PathLineTo(ImVec2(x1, p0.y)); - draw_list->PathLineTo(ImVec2(x1, p1.y)); - } - else if (arc1_b == 0.0f && arc1_e == IM_PI*0.5f) - { - draw_list->PathArcToFast(ImVec2(x1, p0.y + rounding), rounding, 9, 12); // TR - draw_list->PathArcToFast(ImVec2(x1, p1.y - rounding), rounding, 0, 3); // BR - } - else - { - draw_list->PathArcTo(ImVec2(x1, p0.y + rounding), rounding, -arc1_e, -arc1_b, 3); // TR - draw_list->PathArcTo(ImVec2(x1, p1.y - rounding), rounding, +arc1_b, +arc1_e, 3); // BR - } - } - draw_list->PathFillConvex(col); + rounding = ImClamp(ImMin((rect.Max.x - rect.Min.x) * 0.5f, (rect.Max.y - rect.Min.y) * 0.5f) - 1.0f, 0.0f, rounding); + const float inv_rounding = 1.0f / rounding; + const float arc0_b = ImAcos01(1.0f - (p0.x - rect.Min.x) * inv_rounding); + const float arc0_e = ImAcos01(1.0f - (p1.x - rect.Min.x) * inv_rounding); + const float x0 = ImMax(p0.x, rect.Min.x + rounding); + if (arc0_b == arc0_e) + { + draw_list->PathLineTo(ImVec2(x0, p1.y)); + draw_list->PathLineTo(ImVec2(x0, p0.y)); + } + else if (arc0_b == 0.0f && arc0_e == IM_PI * 0.5f) + { + draw_list->PathArcToFast(ImVec2(x0, p1.y - rounding), rounding, 3, 6); // BL + draw_list->PathArcToFast(ImVec2(x0, p0.y + rounding), rounding, 6, 9); // TR + } + else + { + draw_list->PathArcTo(ImVec2(x0, p1.y - rounding), rounding, IM_PI - arc0_e, IM_PI - arc0_b, 3); // BL + draw_list->PathArcTo(ImVec2(x0, p0.y + rounding), rounding, IM_PI + arc0_b, IM_PI + arc0_e, 3); // TR + } + if (p1.x > rect.Min.x + rounding) + { + const float arc1_b = ImAcos01(1.0f - (rect.Max.x - p1.x) * inv_rounding); + const float arc1_e = ImAcos01(1.0f - (rect.Max.x - p0.x) * inv_rounding); + const float x1 = ImMin(p1.x, rect.Max.x - rounding); + if (arc1_b == arc1_e) + { + draw_list->PathLineTo(ImVec2(x1, p0.y)); + draw_list->PathLineTo(ImVec2(x1, p1.y)); + } + else if (arc1_b == 0.0f && arc1_e == IM_PI * 0.5f) + { + draw_list->PathArcToFast(ImVec2(x1, p0.y + rounding), rounding, 9, 12); // TR + draw_list->PathArcToFast(ImVec2(x1, p1.y - rounding), rounding, 0, 3); // BR + } + else + { + draw_list->PathArcTo(ImVec2(x1, p0.y + rounding), rounding, -arc1_e, -arc1_b, 3); // TR + draw_list->PathArcTo(ImVec2(x1, p1.y - rounding), rounding, +arc1_b, +arc1_e, 3); // BR + } + } + draw_list->PathFillConvex(col); } //----------------------------------------------------------------------------- @@ -2726,115 +4818,150 @@ void ImGui::RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, Im // Decompression from stb.h (public domain) by Sean Barrett https://github.com/nothings/stb/blob/master/stb.h //----------------------------------------------------------------------------- -static unsigned int stb_decompress_length(unsigned char *input) +static unsigned int stb_decompress_length(unsigned char* input) { - return (input[8] << 24) + (input[9] << 16) + (input[10] << 8) + input[11]; + return (input[8] << 24) + (input[9] << 16) + (input[10] << 8) + input[11]; } static unsigned char *stb__barrier, *stb__barrier2, *stb__barrier3, *stb__barrier4; -static unsigned char *stb__dout; -static void stb__match(unsigned char *data, unsigned int length) +static unsigned char* stb__dout; +static void stb__match(unsigned char* data, unsigned int length) { - // INVERSE of memmove... write each byte before copying the next... - IM_ASSERT (stb__dout + length <= stb__barrier); - if (stb__dout + length > stb__barrier) { stb__dout += length; return; } - if (data < stb__barrier4) { stb__dout = stb__barrier+1; return; } - while (length--) *stb__dout++ = *data++; + // INVERSE of memmove... write each byte before copying the next... + IM_ASSERT(stb__dout + length <= stb__barrier); + if (stb__dout + length > stb__barrier) + { + stb__dout += length; + return; + } + if (data < stb__barrier4) + { + stb__dout = stb__barrier + 1; + return; + } + while (length--) *stb__dout++ = *data++; } -static void stb__lit(unsigned char *data, unsigned int length) +static void stb__lit(unsigned char* data, unsigned int length) { - IM_ASSERT (stb__dout + length <= stb__barrier); - if (stb__dout + length > stb__barrier) { stb__dout += length; return; } - if (data < stb__barrier2) { stb__dout = stb__barrier+1; return; } - memcpy(stb__dout, data, length); - stb__dout += length; + IM_ASSERT(stb__dout + length <= stb__barrier); + if (stb__dout + length > stb__barrier) + { + stb__dout += length; + return; + } + if (data < stb__barrier2) + { + stb__dout = stb__barrier + 1; + return; + } + memcpy(stb__dout, data, length); + stb__dout += length; } -#define stb__in2(x) ((i[x] << 8) + i[(x)+1]) -#define stb__in3(x) ((i[x] << 16) + stb__in2((x)+1)) -#define stb__in4(x) ((i[x] << 24) + stb__in3((x)+1)) +#define stb__in2(x) ((i[x] << 8) + i[(x) + 1]) +#define stb__in3(x) ((i[x] << 16) + stb__in2((x) + 1)) +#define stb__in4(x) ((i[x] << 24) + stb__in3((x) + 1)) -static unsigned char *stb_decompress_token(unsigned char *i) +static unsigned char* stb_decompress_token(unsigned char* i) { - if (*i >= 0x20) { // use fewer if's for cases that expand small - if (*i >= 0x80) stb__match(stb__dout-i[1]-1, i[0] - 0x80 + 1), i += 2; - else if (*i >= 0x40) stb__match(stb__dout-(stb__in2(0) - 0x4000 + 1), i[2]+1), i += 3; - else /* *i >= 0x20 */ stb__lit(i+1, i[0] - 0x20 + 1), i += 1 + (i[0] - 0x20 + 1); - } else { // more ifs for cases that expand large, since overhead is amortized - if (*i >= 0x18) stb__match(stb__dout-(stb__in3(0) - 0x180000 + 1), i[3]+1), i += 4; - else if (*i >= 0x10) stb__match(stb__dout-(stb__in3(0) - 0x100000 + 1), stb__in2(3)+1), i += 5; - else if (*i >= 0x08) stb__lit(i+2, stb__in2(0) - 0x0800 + 1), i += 2 + (stb__in2(0) - 0x0800 + 1); - else if (*i == 0x07) stb__lit(i+3, stb__in2(1) + 1), i += 3 + (stb__in2(1) + 1); - else if (*i == 0x06) stb__match(stb__dout-(stb__in3(1)+1), i[4]+1), i += 5; - else if (*i == 0x04) stb__match(stb__dout-(stb__in3(1)+1), stb__in2(4)+1), i += 6; - } - return i; + if (*i >= 0x20) + { // use fewer if's for cases that expand small + if (*i >= 0x80) + stb__match(stb__dout - i[1] - 1, i[0] - 0x80 + 1), i += 2; + else if (*i >= 0x40) + stb__match(stb__dout - (stb__in2(0) - 0x4000 + 1), i[2] + 1), i += 3; + else /* *i >= 0x20 */ + stb__lit(i + 1, i[0] - 0x20 + 1), i += 1 + (i[0] - 0x20 + 1); + } + else + { // more ifs for cases that expand large, since overhead is amortized + if (*i >= 0x18) + stb__match(stb__dout - (stb__in3(0) - 0x180000 + 1), i[3] + 1), i += 4; + else if (*i >= 0x10) + stb__match(stb__dout - (stb__in3(0) - 0x100000 + 1), stb__in2(3) + 1), i += 5; + else if (*i >= 0x08) + stb__lit(i + 2, stb__in2(0) - 0x0800 + 1), i += 2 + (stb__in2(0) - 0x0800 + 1); + else if (*i == 0x07) + stb__lit(i + 3, stb__in2(1) + 1), i += 3 + (stb__in2(1) + 1); + else if (*i == 0x06) + stb__match(stb__dout - (stb__in3(1) + 1), i[4] + 1), i += 5; + else if (*i == 0x04) + stb__match(stb__dout - (stb__in3(1) + 1), stb__in2(4) + 1), i += 6; + } + return i; } -static unsigned int stb_adler32(unsigned int adler32, unsigned char *buffer, unsigned int buflen) +static unsigned int stb_adler32(unsigned int adler32, unsigned char* buffer, unsigned int buflen) { - const unsigned long ADLER_MOD = 65521; - unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16; - unsigned long blocklen, i; + const unsigned long ADLER_MOD = 65521; + unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16; + unsigned long blocklen, i; - blocklen = buflen % 5552; - while (buflen) { - for (i=0; i + 7 < blocklen; i += 8) { - s1 += buffer[0], s2 += s1; - s1 += buffer[1], s2 += s1; - s1 += buffer[2], s2 += s1; - s1 += buffer[3], s2 += s1; - s1 += buffer[4], s2 += s1; - s1 += buffer[5], s2 += s1; - s1 += buffer[6], s2 += s1; - s1 += buffer[7], s2 += s1; + blocklen = buflen % 5552; + while (buflen) + { + for (i = 0; i + 7 < blocklen; i += 8) + { + s1 += buffer[0], s2 += s1; + s1 += buffer[1], s2 += s1; + s1 += buffer[2], s2 += s1; + s1 += buffer[3], s2 += s1; + s1 += buffer[4], s2 += s1; + s1 += buffer[5], s2 += s1; + s1 += buffer[6], s2 += s1; + s1 += buffer[7], s2 += s1; - buffer += 8; - } + buffer += 8; + } - for (; i < blocklen; ++i) - s1 += *buffer++, s2 += s1; + for (; i < blocklen; ++i) + s1 += *buffer++, s2 += s1; - s1 %= ADLER_MOD, s2 %= ADLER_MOD; - buflen -= blocklen; - blocklen = 5552; - } - return (unsigned int)(s2 << 16) + (unsigned int)s1; + s1 %= ADLER_MOD, s2 %= ADLER_MOD; + buflen -= blocklen; + blocklen = 5552; + } + return (unsigned int)(s2 << 16) + (unsigned int)s1; } -static unsigned int stb_decompress(unsigned char *output, unsigned char *i, unsigned int length) +static unsigned int stb_decompress(unsigned char* output, unsigned char* i, unsigned int length) { - unsigned int olen; - if (stb__in4(0) != 0x57bC0000) return 0; - if (stb__in4(4) != 0) return 0; // error! stream is > 4GB - olen = stb_decompress_length(i); - stb__barrier2 = i; - stb__barrier3 = i+length; - stb__barrier = output + olen; - stb__barrier4 = output; - i += 16; + unsigned int olen; + if (stb__in4(0) != 0x57bC0000) return 0; + if (stb__in4(4) != 0) return 0; // error! stream is > 4GB + olen = stb_decompress_length(i); + stb__barrier2 = i; + stb__barrier3 = i + length; + stb__barrier = output + olen; + stb__barrier4 = output; + i += 16; - stb__dout = output; - for (;;) { - unsigned char *old_i = i; - i = stb_decompress_token(i); - if (i == old_i) { - if (*i == 0x05 && i[1] == 0xfa) { - IM_ASSERT(stb__dout == output + olen); - if (stb__dout != output + olen) return 0; - if (stb_adler32(1, output, olen) != (unsigned int) stb__in4(2)) - return 0; - return olen; - } else { - IM_ASSERT(0); /* NOTREACHED */ - return 0; - } - } - IM_ASSERT(stb__dout <= output + olen); - if (stb__dout > output + olen) - return 0; - } + stb__dout = output; + for (;;) + { + unsigned char* old_i = i; + i = stb_decompress_token(i); + if (i == old_i) + { + if (*i == 0x05 && i[1] == 0xfa) + { + IM_ASSERT(stb__dout == output + olen); + if (stb__dout != output + olen) return 0; + if (stb_adler32(1, output, olen) != (unsigned int)stb__in4(2)) + return 0; + return olen; + } + else + { + IM_ASSERT(0); /* NOTREACHED */ + return 0; + } + } + IM_ASSERT(stb__dout <= output + olen); + if (stb__dout > output + olen) + return 0; + } } //----------------------------------------------------------------------------- @@ -2846,95 +4973,95 @@ static unsigned int stb_decompress(unsigned char *output, unsigned char *i, unsi // File: 'ProggyClean.ttf' (41208 bytes) // Exported using binary_to_compressed_c.cpp //----------------------------------------------------------------------------- -static const char proggy_clean_ttf_compressed_data_base85[11980+1] = - "7])#######hV0qs'/###[),##/l:$#Q6>##5[n42>c-TH`->>#/e>11NNV=Bv(*:.F?uu#(gRU.o0XGH`$vhLG1hxt9?W`#,5LsCp#-i>.r$<$6pD>Lb';9Crc6tgXmKVeU2cD4Eo3R/" - "2*>]b(MC;$jPfY.;h^`IWM9Qo#t'X#(v#Y9w0#1D$CIf;W'#pWUPXOuxXuU(H9M(1=Ke$$'5F%)]0^#0X@U.a$FBjVQTSDgEKnIS7EM9>ZY9w0#L;>>#Mx&4Mvt//L[MkA#W@lK.N'[0#7RL_&#w+F%HtG9M#XL`N&.,GM4Pg;--VsM.M0rJfLH2eTM`*oJMHRC`N" - "kfimM2J,W-jXS:)r0wK#@Fge$U>`w'N7G#$#fB#$E^$#:9:hk+eOe--6x)F7*E%?76%^GMHePW-Z5l'&GiF#$956:rS?dA#fiK:)Yr+`�j@'DbG&#^$PG.Ll+DNa&VZ>1i%h1S9u5o@YaaW$e+bROPOpxTO7Stwi1::iB1q)C_=dV26J;2,]7op$]uQr@_V7$q^%lQwtuHY]=DX,n3L#0PHDO4f9>dC@O>HBuKPpP*E,N+b3L#lpR/MrTEH.IAQk.a>D[.e;mc." - "x]Ip.PH^'/aqUO/$1WxLoW0[iLAw=4h(9.`G" - "CRUxHPeR`5Mjol(dUWxZa(>STrPkrJiWx`5U7F#.g*jrohGg`cg:lSTvEY/EV_7H4Q9[Z%cnv;JQYZ5q.l7Zeas:HOIZOB?Ggv:[7MI2k).'2($5FNP&EQ(,)" - "U]W]+fh18.vsai00);D3@4ku5P?DP8aJt+;qUM]=+b'8@;mViBKx0DE[-auGl8:PJ&Dj+M6OC]O^((##]`0i)drT;-7X`=-H3[igUnPG-NZlo.#k@h#=Ork$m>a>$-?Tm$UV(?#P6YY#" - "'/###xe7q.73rI3*pP/$1>s9)W,JrM7SN]'/4C#v$U`0#V.[0>xQsH$fEmPMgY2u7Kh(G%siIfLSoS+MK2eTM$=5,M8p`A.;_R%#u[K#$x4AG8.kK/HSB==-'Ie/QTtG?-.*^N-4B/ZM" - "_3YlQC7(p7q)&](`6_c)$/*JL(L-^(]$wIM`dPtOdGA,U3:w2M-0+WomX2u7lqM2iEumMTcsF?-aT=Z-97UEnXglEn1K-bnEO`gu" - "Ft(c%=;Am_Qs@jLooI&NX;]0#j4#F14;gl8-GQpgwhrq8'=l_f-b49'UOqkLu7-##oDY2L(te+Mch&gLYtJ,MEtJfLh'x'M=$CS-ZZ%P]8bZ>#S?YY#%Q&q'3^Fw&?D)UDNrocM3A76/" - "/oL?#h7gl85[qW/NDOk%16ij;+:1a'iNIdb-ou8.P*w,v5#EI$TWS>Pot-R*H'-SEpA:g)f+O$%%`kA#G=8RMmG1&O`>to8bC]T&$,n.LoO>29sp3dt-52U%VM#q7'DHpg+#Z9%H[Ket`e;)f#Km8&+DC$I46>#Kr]]u-[=99tts1.qb#q72g1WJO81q+eN'03'eM>&1XxY-caEnO" - "j%2n8)),?ILR5^.Ibn<-X-Mq7[a82Lq:F&#ce+S9wsCK*x`569E8ew'He]h:sI[2LM$[guka3ZRd6:t%IG:;$%YiJ:Nq=?eAw;/:nnDq0(CYcMpG)qLN4$##&J-XTt,%OVU4)S1+R-#dg0/Nn?Ku1^0f$B*P:Rowwm-`0PKjYDDM'3]d39VZHEl4,.j']Pk-M.h^&:0FACm$maq-&sgw0t7/6(^xtk%" - "LuH88Fj-ekm>GA#_>568x6(OFRl-IZp`&b,_P'$MhLbxfc$mj`,O;&%W2m`Zh:/)Uetw:aJ%]K9h:TcF]u_-Sj9,VK3M.*'&0D[Ca]J9gp8,kAW]" - "%(?A%R$f<->Zts'^kn=-^@c4%-pY6qI%J%1IGxfLU9CP8cbPlXv);C=b),<2mOvP8up,UVf3839acAWAW-W?#ao/^#%KYo8fRULNd2.>%m]UK:n%r$'sw]J;5pAoO_#2mO3n,'=H5(et" - "Hg*`+RLgv>=4U8guD$I%D:W>-r5V*%j*W:Kvej.Lp$'?;++O'>()jLR-^u68PHm8ZFWe+ej8h:9r6L*0//c&iH&R8pRbA#Kjm%upV1g:" - "a_#Ur7FuA#(tRh#.Y5K+@?3<-8m0$PEn;J:rh6?I6uG<-`wMU'ircp0LaE_OtlMb&1#6T.#FDKu#1Lw%u%+GM+X'e?YLfjM[VO0MbuFp7;>Q&#WIo)0@F%q7c#4XAXN-U&VBpqB>0ie&jhZ[?iLR@@_AvA-iQC(=ksRZRVp7`.=+NpBC%rh&3]R:8XDmE5^V8O(x<-+k?'(^](H.aREZSi,#1:[IXaZFOm<-ui#qUq2$##Ri;u75OK#(RtaW-K-F`S+cF]uN`-KMQ%rP/Xri.LRcB##=YL3BgM/3M" - "D?@f&1'BW-)Ju#bmmWCMkk&#TR`C,5d>g)F;t,4:@_l8G/5h4vUd%&%950:VXD'QdWoY-F$BtUwmfe$YqL'8(PWX(" - "P?^@Po3$##`MSs?DWBZ/S>+4%>fX,VWv/w'KD`LP5IbH;rTV>n3cEK8U#bX]l-/V+^lj3;vlMb&[5YQ8#pekX9JP3XUC72L,,?+Ni&co7ApnO*5NK,((W-i:$,kp'UDAO(G0Sq7MVjJs" - "bIu)'Z,*[>br5fX^:FPAWr-m2KgLQ_nN6'8uTGT5g)uLv:873UpTLgH+#FgpH'_o1780Ph8KmxQJ8#H72L4@768@Tm&Q" - "h4CB/5OvmA&,Q&QbUoi$a_%3M01H)4x7I^&KQVgtFnV+;[Pc>[m4k//,]1?#`VY[Jr*3&&slRfLiVZJ:]?=K3Sw=[$=uRB?3xk48@aege0jT6'N#(q%.O=?2S]u*(m<-" - "V8J'(1)G][68hW$5'q[GC&5j`TE?m'esFGNRM)j,ffZ?-qx8;->g4t*:CIP/[Qap7/9'#(1sao7w-.qNUdkJ)tCF&#B^;xGvn2r9FEPFFFcL@.iFNkTve$m%#QvQS8U@)2Z+3K:AKM5i" - "sZ88+dKQ)W6>J%CL`.d*(B`-n8D9oK-XV1q['-5k'cAZ69e;D_?$ZPP&s^+7])$*$#@QYi9,5P r+$%CE=68>K8r0=dSC%%(@p7" - ".m7jilQ02'0-VWAgTlGW'b)Tq7VT9q^*^$$.:&N@@" - "$&)WHtPm*5_rO0&e%K&#-30j(E4#'Zb.o/(Tpm$>K'f@[PvFl,hfINTNU6u'0pao7%XUp9]5.>%h`8_=VYbxuel.NTSsJfLacFu3B'lQSu/m6-Oqem8T+oE--$0a/k]uj9EwsG>%veR*" - "hv^BFpQj:K'#SJ,sB-'#](j.Lg92rTw-*n%@/;39rrJF,l#qV%OrtBeC6/,;qB3ebNW[?,Hqj2L.1NP&GjUR=1D8QaS3Up&@*9wP?+lo7b?@%'k4`p0Z$22%K3+iCZj?XJN4Nm&+YF]u" - "@-W$U%VEQ/,,>>#)D#%8cY#YZ?=,`Wdxu/ae&#" - "w6)R89tI#6@s'(6Bf7a&?S=^ZI_kS&ai`&=tE72L_D,;^R)7[$so8lKN%5/$(vdfq7+ebA#" - "u1p]ovUKW&Y%q]'>$1@-[xfn$7ZTp7mM,G,Ko7a&Gu%G[RMxJs[0MM%wci.LFDK)(%:_i2B5CsR8&9Z&#=mPEnm0f`<&c)QL5uJ#%u%lJj+D-r;BoFDoS97h5g)E#o:&S4weDF,9^Hoe`h*L+_a*NrLW-1pG_&2UdB8" - "6e%B/:=>)N4xeW.*wft-;$'58-ESqr#U`'6AQ]m&6/`Z>#S?YY#Vc;r7U2&326d=w&H####?TZ`*4?&.MK?LP8Vxg>$[QXc%QJv92.(Db*B)gb*BM9dM*hJMAo*c&#" - "b0v=Pjer]$gG&JXDf->'StvU7505l9$AFvgYRI^&<^b68?j#q9QX4SM'RO#&sL1IM.rJfLUAj221]d##DW=m83u5;'bYx,*Sl0hL(W;;$doB&O/TQ:(Z^xBdLjLV#*8U_72Lh+2Q8Cj0i:6hp&$C/:p(HK>T8Y[gHQ4`4)'$Ab(Nof%V'8hL&#SfD07&6D@M.*J:;$-rv29'M]8qMv-tLp,'886iaC=Hb*YJoKJ,(j%K=H`K.v9HggqBIiZu'QvBT.#=)0ukruV&.)3=(^1`o*Pj4<-#MJ+gLq9-##@HuZPN0]u:h7.T..G:;$/Usj(T7`Q8tT72LnYl<-qx8;-HV7Q-&Xdx%1a,hC=0u+HlsV>nuIQL-5" - "_>@kXQtMacfD.m-VAb8;IReM3$wf0''hra*so568'Ip&vRs849'MRYSp%:t:h5qSgwpEr$B>Q,;s(C#$)`svQuF$##-D,##,g68@2[T;.XSdN9Qe)rpt._K-#5wF)sP'##p#C0c%-Gb%" - "hd+<-j'Ai*x&&HMkT]C'OSl##5RG[JXaHN;d'uA#x._U;.`PU@(Z3dt4r152@:v,'R.Sj'w#0<-;kPI)FfJ&#AYJ&#//)>-k=m=*XnK$>=)72L]0I%>.G690a:$##<,);?;72#?x9+d;" - "^V'9;jY@;)br#q^YQpx:X#Te$Z^'=-=bGhLf:D6&bNwZ9-ZD#n^9HhLMr5G;']d&6'wYmTFmLq9wI>P(9mI[>kC-ekLC/R&CH+s'B;K-M6$EB%is00:" - "+A4[7xks.LrNk0&E)wILYF@2L'0Nb$+pv<(2.768/FrY&h$^3i&@+G%JT'<-,v`3;_)I9M^AE]CN?Cl2AZg+%4iTpT3$U4O]GKx'm9)b@p7YsvK3w^YR-" - "CdQ*:Ir<($u&)#(&?L9Rg3H)4fiEp^iI9O8KnTj,]H?D*r7'M;PwZ9K0E^k&-cpI;.p/6_vwoFMV<->#%Xi.LxVnrU(4&8/P+:hLSKj$#U%]49t'I:rgMi'FL@a:0Y-uA[39',(vbma*" - "hU%<-SRF`Tt:542R_VV$p@[p8DV[A,?1839FWdFTi1O*H&#(AL8[_P%.M>v^-))qOT*F5Cq0`Ye%+$B6i:7@0IXSsDiWP,##P`%/L-" - "S(qw%sf/@%#B6;/U7K]uZbi^Oc^2n%t<)'mEVE''n`WnJra$^TKvX5B>;_aSEK',(hwa0:i4G?.Bci.(X[?b*($,=-n<.Q%`(X=?+@Am*Js0&=3bh8K]mL69=Lb,OcZV/);TTm8VI;?%OtJ<(b4mq7M6:u?KRdFl*:xP?Yb.5)%w_I?7uk5JC+FS(m#i'k.'a0i)9<7b'fs'59hq$*5Uhv##pi^8+hIEBF`nvo`;'l0.^S1<-wUK2/Coh58KKhLj" - "M=SO*rfO`+qC`W-On.=AJ56>>i2@2LH6A:&5q`?9I3@@'04&p2/LVa*T-4<-i3;M9UvZd+N7>b*eIwg:CC)c<>nO&#$(>.Z-I&J(Q0Hd5Q%7Co-b`-cP)hI;*_F]u`Rb[.j8_Q/<&>uu+VsH$sM9TA%?)(vmJ80),P7E>)tjD%2L=-t#fK[%`v=Q8WlA2);Sa" - ">gXm8YB`1d@K#n]76-a$U,mF%Ul:#/'xoFM9QX-$.QN'>" - "[%$Z$uF6pA6Ki2O5:8w*vP1<-1`[G,)-m#>0`P&#eb#.3i)rtB61(o'$?X3B2Qft^ae_5tKL9MUe9b*sLEQ95C&`=G?@Mj=wh*'3E>=-<)Gt*Iw)'QG:`@I" - "wOf7&]1i'S01B+Ev/Nac#9S;=;YQpg_6U`*kVY39xK,[/6Aj7:'1Bm-_1EYfa1+o&o4hp7KN_Q(OlIo@S%;jVdn0'1h19w,WQhLI)3S#f$2(eb,jr*b;3Vw]*7NH%$c4Vs,eD9>XW8?N]o+(*pgC%/72LV-uW%iewS8W6m2rtCpo'RS1R84=@paTKt)>=%&1[)*vp'u+x,VrwN;&]kuO9JDbg=pO$J*.jVe;u'm0dr9l,<*wMK*Oe=g8lV_KEBFkO'oU]^=[-792#ok,)" - "i]lR8qQ2oA8wcRCZ^7w/Njh;?.stX?Q1>S1q4Bn$)K1<-rGdO'$Wr.Lc.CG)$/*JL4tNR/,SVO3,aUw'DJN:)Ss;wGn9A32ijw%FL+Z0Fn.U9;reSq)bmI32U==5ALuG&#Vf1398/pVo" - "1*c-(aY168o<`JsSbk-,1N;$>0:OUas(3:8Z972LSfF8eb=c-;>SPw7.6hn3m`9^Xkn(r.qS[0;T%&Qc=+STRxX'q1BNk3&*eu2;&8q$&x>Q#Q7^Tf+6<(d%ZVmj2bDi%.3L2n+4W'$P" - "iDDG)g,r%+?,$@?uou5tSe2aN_AQU*'IAO" - "URQ##V^Fv-XFbGM7Fl(N<3DhLGF%q.1rC$#:T__&Pi68%0xi_&[qFJ(77j_&JWoF.V735&T,[R*:xFR*K5>>#`bW-?4Ne_&6Ne_&6Ne_&n`kr-#GJcM6X;uM6X;uM(.a..^2TkL%oR(#" - ";u.T%fAr%4tJ8&><1=GHZ_+m9/#H1F^R#SC#*N=BA9(D?v[UiFY>>^8p,KKF.W]L29uLkLlu/+4T" - "w$)F./^n3+rlo+DB;5sIYGNk+i1t-69Jg--0pao7Sm#K)pdHW&;LuDNH@H>#/X-TI(;P>#,Gc>#0Su>#4`1?#8lC?#xL$#B.`$#F:r$#JF.%#NR@%#R_R%#Vke%#Zww%#_-4^Rh%Sflr-k'MS.o?.5/sWel/wpEM0%3'/1)K^f1-d>G21&v(35>V`39V7A4=onx4" - "A1OY5EI0;6Ibgr6M$HS7Q<)58C5w,;WoA*#[%T*#`1g*#d=#+#hI5+#lUG+#pbY+#tnl+#x$),#&1;,#*=M,#.I`,#2Ur,#6b.-#;w[H#iQtA#m^0B#qjBB#uvTB##-hB#'9$C#+E6C#" - "/QHC#3^ZC#7jmC#;v)D#?,)4kMYD4lVu`4m`:&5niUA5@(A5BA1]PBB:xlBCC=2CDLXMCEUtiCf&0g2'tN?PGT4CPGT4CPGT4CPGT4CPGT4CPGT4CPGT4CP" - "GT4CPGT4CPGT4CPGT4CPGT4CPGT4CP-qekC`.9kEg^+F$kwViFJTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5o,^<-28ZI'O?;xp" - "O?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xp;7q-#lLYI:xvD=#"; +static const char proggy_clean_ttf_compressed_data_base85[11980 + 1] = + "7])#######hV0qs'/###[),##/l:$#Q6>##5[n42>c-TH`->>#/e>11NNV=Bv(*:.F?uu#(gRU.o0XGH`$vhLG1hxt9?W`#,5LsCp#-i>.r$<$6pD>Lb';9Crc6tgXmKVeU2cD4Eo3R/" + "2*>]b(MC;$jPfY.;h^`IWM9Qo#t'X#(v#Y9w0#1D$CIf;W'#pWUPXOuxXuU(H9M(1=Ke$$'5F%)]0^#0X@U.a$FBjVQTSDgEKnIS7EM9>ZY9w0#L;>>#Mx&4Mvt//L[MkA#W@lK.N'[0#7RL_&#w+F%HtG9M#XL`N&.,GM4Pg;--VsM.M0rJfLH2eTM`*oJMHRC`N" + "kfimM2J,W-jXS:)r0wK#@Fge$U>`w'N7G#$#fB#$E^$#:9:hk+eOe--6x)F7*E%?76%^GMHePW-Z5l'&GiF#$956:rS?dA#fiK:)Yr+`�j@'DbG&#^$PG.Ll+DNa&VZ>1i%h1S9u5o@YaaW$e+bROPOpxTO7Stwi1::iB1q)C_=dV26J;2,]7op$]uQr@_V7$q^%lQwtuHY]=DX,n3L#0PHDO4f9>dC@O>HBuKPpP*E,N+b3L#lpR/MrTEH.IAQk.a>D[.e;mc." + "x]Ip.PH^'/aqUO/$1WxLoW0[iLAw=4h(9.`G" + "CRUxHPeR`5Mjol(dUWxZa(>STrPkrJiWx`5U7F#.g*jrohGg`cg:lSTvEY/EV_7H4Q9[Z%cnv;JQYZ5q.l7Zeas:HOIZOB?Ggv:[7MI2k).'2($5FNP&EQ(,)" + "U]W]+fh18.vsai00);D3@4ku5P?DP8aJt+;qUM]=+b'8@;mViBKx0DE[-auGl8:PJ&Dj+M6OC]O^((##]`0i)drT;-7X`=-H3[igUnPG-NZlo.#k@h#=Ork$m>a>$-?Tm$UV(?#P6YY#" + "'/###xe7q.73rI3*pP/$1>s9)W,JrM7SN]'/4C#v$U`0#V.[0>xQsH$fEmPMgY2u7Kh(G%siIfLSoS+MK2eTM$=5,M8p`A.;_R%#u[K#$x4AG8.kK/HSB==-'Ie/QTtG?-.*^N-4B/ZM" + "_3YlQC7(p7q)&](`6_c)$/*JL(L-^(]$wIM`dPtOdGA,U3:w2M-0+WomX2u7lqM2iEumMTcsF?-aT=Z-97UEnXglEn1K-bnEO`gu" + "Ft(c%=;Am_Qs@jLooI&NX;]0#j4#F14;gl8-GQpgwhrq8'=l_f-b49'UOqkLu7-##oDY2L(te+Mch&gLYtJ,MEtJfLh'x'M=$CS-ZZ%P]8bZ>#S?YY#%Q&q'3^Fw&?D)UDNrocM3A76/" + "/oL?#h7gl85[qW/NDOk%16ij;+:1a'iNIdb-ou8.P*w,v5#EI$TWS>Pot-R*H'-SEpA:g)f+O$%%`kA#G=8RMmG1&O`>to8bC]T&$,n.LoO>29sp3dt-52U%VM#q7'DHpg+#Z9%H[Ket`e;)f#Km8&+DC$I46>#Kr]]u-[=99tts1.qb#q72g1WJO81q+eN'03'eM>&1XxY-caEnO" + "j%2n8)),?ILR5^.Ibn<-X-Mq7[a82Lq:F&#ce+S9wsCK*x`569E8ew'He]h:sI[2LM$[guka3ZRd6:t%IG:;$%YiJ:Nq=?eAw;/:nnDq0(CYcMpG)qLN4$##&J-XTt,%OVU4)S1+R-#dg0/Nn?Ku1^0f$B*P:Rowwm-`0PKjYDDM'3]d39VZHEl4,.j']Pk-M.h^&:0FACm$maq-&sgw0t7/6(^xtk%" + "LuH88Fj-ekm>GA#_>568x6(OFRl-IZp`&b,_P'$MhLbxfc$mj`,O;&%W2m`Zh:/)Uetw:aJ%]K9h:TcF]u_-Sj9,VK3M.*'&0D[Ca]J9gp8,kAW]" + "%(?A%R$f<->Zts'^kn=-^@c4%-pY6qI%J%1IGxfLU9CP8cbPlXv);C=b),<2mOvP8up,UVf3839acAWAW-W?#ao/^#%KYo8fRULNd2.>%m]UK:n%r$'sw]J;5pAoO_#2mO3n,'=H5(et" + "Hg*`+RLgv>=4U8guD$I%D:W>-r5V*%j*W:Kvej.Lp$'?;++O'>()jLR-^u68PHm8ZFWe+ej8h:9r6L*0//c&iH&R8pRbA#Kjm%upV1g:" + "a_#Ur7FuA#(tRh#.Y5K+@?3<-8m0$PEn;J:rh6?I6uG<-`wMU'ircp0LaE_OtlMb&1#6T.#FDKu#1Lw%u%+GM+X'e?YLfjM[VO0MbuFp7;>Q&#WIo)0@F%q7c#4XAXN-U&VBpqB>0ie&jhZ[?iLR@@_AvA-iQC(=ksRZRVp7`.=+NpBC%rh&3]R:8XDmE5^V8O(x<-+k?'(^](H.aREZSi,#1:[IXaZFOm<-ui#qUq2$##Ri;u75OK#(RtaW-K-F`S+cF]uN`-KMQ%rP/Xri.LRcB##=YL3BgM/3M" + "D?@f&1'BW-)Ju#bmmWCMkk&#TR`C,5d>g)F;t,4:@_l8G/5h4vUd%&%950:VXD'QdWoY-F$BtUwmfe$YqL'8(PWX(" + "P?^@Po3$##`MSs?DWBZ/S>+4%>fX,VWv/w'KD`LP5IbH;rTV>n3cEK8U#bX]l-/V+^lj3;vlMb&[5YQ8#pekX9JP3XUC72L,,?+Ni&co7ApnO*5NK,((W-i:$,kp'UDAO(G0Sq7MVjJs" + "bIu)'Z,*[>br5fX^:FPAWr-m2KgLQ_nN6'8uTGT5g)uLv:873UpTLgH+#FgpH'_o1780Ph8KmxQJ8#H72L4@768@Tm&Q" + "h4CB/5OvmA&,Q&QbUoi$a_%3M01H)4x7I^&KQVgtFnV+;[Pc>[m4k//,]1?#`VY[Jr*3&&slRfLiVZJ:]?=K3Sw=[$=uRB?3xk48@aege0jT6'N#(q%.O=?2S]u*(m<-" + "V8J'(1)G][68hW$5'q[GC&5j`TE?m'esFGNRM)j,ffZ?-qx8;->g4t*:CIP/[Qap7/9'#(1sao7w-.qNUdkJ)tCF&#B^;xGvn2r9FEPFFFcL@.iFNkTve$m%#QvQS8U@)2Z+3K:AKM5i" + "sZ88+dKQ)W6>J%CL`.d*(B`-n8D9oK-XV1q['-5k'cAZ69e;D_?$ZPP&s^+7])$*$#@QYi9,5P r+$%CE=68>K8r0=dSC%%(@p7" + ".m7jilQ02'0-VWAgTlGW'b)Tq7VT9q^*^$$.:&N@@" + "$&)WHtPm*5_rO0&e%K&#-30j(E4#'Zb.o/(Tpm$>K'f@[PvFl,hfINTNU6u'0pao7%XUp9]5.>%h`8_=VYbxuel.NTSsJfLacFu3B'lQSu/m6-Oqem8T+oE--$0a/k]uj9EwsG>%veR*" + "hv^BFpQj:K'#SJ,sB-'#](j.Lg92rTw-*n%@/;39rrJF,l#qV%OrtBeC6/,;qB3ebNW[?,Hqj2L.1NP&GjUR=1D8QaS3Up&@*9wP?+lo7b?@%'k4`p0Z$22%K3+iCZj?XJN4Nm&+YF]u" + "@-W$U%VEQ/,,>>#)D#%8cY#YZ?=,`Wdxu/ae&#" + "w6)R89tI#6@s'(6Bf7a&?S=^ZI_kS&ai`&=tE72L_D,;^R)7[$so8lKN%5/$(vdfq7+ebA#" + "u1p]ovUKW&Y%q]'>$1@-[xfn$7ZTp7mM,G,Ko7a&Gu%G[RMxJs[0MM%wci.LFDK)(%:_i2B5CsR8&9Z&#=mPEnm0f`<&c)QL5uJ#%u%lJj+D-r;BoFDoS97h5g)E#o:&S4weDF,9^Hoe`h*L+_a*NrLW-1pG_&2UdB8" + "6e%B/:=>)N4xeW.*wft-;$'58-ESqr#U`'6AQ]m&6/`Z>#S?YY#Vc;r7U2&326d=w&H####?TZ`*4?&.MK?LP8Vxg>$[QXc%QJv92.(Db*B)gb*BM9dM*hJMAo*c&#" + "b0v=Pjer]$gG&JXDf->'StvU7505l9$AFvgYRI^&<^b68?j#q9QX4SM'RO#&sL1IM.rJfLUAj221]d##DW=m83u5;'bYx,*Sl0hL(W;;$doB&O/TQ:(Z^xBdLjLV#*8U_72Lh+2Q8Cj0i:6hp&$C/:p(HK>T8Y[gHQ4`4)'$Ab(Nof%V'8hL&#SfD07&6D@M.*J:;$-rv29'M]8qMv-tLp,'886iaC=Hb*YJoKJ,(j%K=H`K.v9HggqBIiZu'QvBT.#=)0ukruV&.)3=(^1`o*Pj4<-#MJ+gLq9-##@HuZPN0]u:h7.T..G:;$/Usj(T7`Q8tT72LnYl<-qx8;-HV7Q-&Xdx%1a,hC=0u+HlsV>nuIQL-5" + "_>@kXQtMacfD.m-VAb8;IReM3$wf0''hra*so568'Ip&vRs849'MRYSp%:t:h5qSgwpEr$B>Q,;s(C#$)`svQuF$##-D,##,g68@2[T;.XSdN9Qe)rpt._K-#5wF)sP'##p#C0c%-Gb%" + "hd+<-j'Ai*x&&HMkT]C'OSl##5RG[JXaHN;d'uA#x._U;.`PU@(Z3dt4r152@:v,'R.Sj'w#0<-;kPI)FfJ&#AYJ&#//)>-k=m=*XnK$>=)72L]0I%>.G690a:$##<,);?;72#?x9+d;" + "^V'9;jY@;)br#q^YQpx:X#Te$Z^'=-=bGhLf:D6&bNwZ9-ZD#n^9HhLMr5G;']d&6'wYmTFmLq9wI>P(9mI[>kC-ekLC/R&CH+s'B;K-M6$EB%is00:" + "+A4[7xks.LrNk0&E)wILYF@2L'0Nb$+pv<(2.768/FrY&h$^3i&@+G%JT'<-,v`3;_)I9M^AE]CN?Cl2AZg+%4iTpT3$U4O]GKx'm9)b@p7YsvK3w^YR-" + "CdQ*:Ir<($u&)#(&?L9Rg3H)4fiEp^iI9O8KnTj,]H?D*r7'M;PwZ9K0E^k&-cpI;.p/6_vwoFMV<->#%Xi.LxVnrU(4&8/P+:hLSKj$#U%]49t'I:rgMi'FL@a:0Y-uA[39',(vbma*" + "hU%<-SRF`Tt:542R_VV$p@[p8DV[A,?1839FWdFTi1O*H&#(AL8[_P%.M>v^-))qOT*F5Cq0`Ye%+$B6i:7@0IXSsDiWP,##P`%/L-" + "S(qw%sf/@%#B6;/U7K]uZbi^Oc^2n%t<)'mEVE''n`WnJra$^TKvX5B>;_aSEK',(hwa0:i4G?.Bci.(X[?b*($,=-n<.Q%`(X=?+@Am*Js0&=3bh8K]mL69=Lb,OcZV/);TTm8VI;?%OtJ<(b4mq7M6:u?KRdFl*:xP?Yb.5)%w_I?7uk5JC+FS(m#i'k.'a0i)9<7b'fs'59hq$*5Uhv##pi^8+hIEBF`nvo`;'l0.^S1<-wUK2/Coh58KKhLj" + "M=SO*rfO`+qC`W-On.=AJ56>>i2@2LH6A:&5q`?9I3@@'04&p2/LVa*T-4<-i3;M9UvZd+N7>b*eIwg:CC)c<>nO&#$(>.Z-I&J(Q0Hd5Q%7Co-b`-cP)hI;*_F]u`Rb[.j8_Q/<&>uu+VsH$sM9TA%?)(vmJ80),P7E>)tjD%2L=-t#fK[%`v=Q8WlA2);Sa" + ">gXm8YB`1d@K#n]76-a$U,mF%Ul:#/'xoFM9QX-$.QN'>" + "[%$Z$uF6pA6Ki2O5:8w*vP1<-1`[G,)-m#>0`P&#eb#.3i)rtB61(o'$?X3B2Qft^ae_5tKL9MUe9b*sLEQ95C&`=G?@Mj=wh*'3E>=-<)Gt*Iw)'QG:`@I" + "wOf7&]1i'S01B+Ev/Nac#9S;=;YQpg_6U`*kVY39xK,[/6Aj7:'1Bm-_1EYfa1+o&o4hp7KN_Q(OlIo@S%;jVdn0'1h19w,WQhLI)3S#f$2(eb,jr*b;3Vw]*7NH%$c4Vs,eD9>XW8?N]o+(*pgC%/72LV-uW%iewS8W6m2rtCpo'RS1R84=@paTKt)>=%&1[)*vp'u+x,VrwN;&]kuO9JDbg=pO$J*.jVe;u'm0dr9l,<*wMK*Oe=g8lV_KEBFkO'oU]^=[-792#ok,)" + "i]lR8qQ2oA8wcRCZ^7w/Njh;?.stX?Q1>S1q4Bn$)K1<-rGdO'$Wr.Lc.CG)$/*JL4tNR/,SVO3,aUw'DJN:)Ss;wGn9A32ijw%FL+Z0Fn.U9;reSq)bmI32U==5ALuG&#Vf1398/pVo" + "1*c-(aY168o<`JsSbk-,1N;$>0:OUas(3:8Z972LSfF8eb=c-;>SPw7.6hn3m`9^Xkn(r.qS[0;T%&Qc=+STRxX'q1BNk3&*eu2;&8q$&x>Q#Q7^Tf+6<(d%ZVmj2bDi%.3L2n+4W'$P" + "iDDG)g,r%+?,$@?uou5tSe2aN_AQU*'IAO" + "URQ##V^Fv-XFbGM7Fl(N<3DhLGF%q.1rC$#:T__&Pi68%0xi_&[qFJ(77j_&JWoF.V735&T,[R*:xFR*K5>>#`bW-?4Ne_&6Ne_&6Ne_&n`kr-#GJcM6X;uM6X;uM(.a..^2TkL%oR(#" + ";u.T%fAr%4tJ8&><1=GHZ_+m9/#H1F^R#SC#*N=BA9(D?v[UiFY>>^8p,KKF.W]L29uLkLlu/+4T" + "w$)F./^n3+rlo+DB;5sIYGNk+i1t-69Jg--0pao7Sm#K)pdHW&;LuDNH@H>#/X-TI(;P>#,Gc>#0Su>#4`1?#8lC?#xL$#B.`$#F:r$#JF.%#NR@%#R_R%#Vke%#Zww%#_-4^Rh%Sflr-k'MS.o?.5/sWel/wpEM0%3'/1)K^f1-d>G21&v(35>V`39V7A4=onx4" + "A1OY5EI0;6Ibgr6M$HS7Q<)58C5w,;WoA*#[%T*#`1g*#d=#+#hI5+#lUG+#pbY+#tnl+#x$),#&1;,#*=M,#.I`,#2Ur,#6b.-#;w[H#iQtA#m^0B#qjBB#uvTB##-hB#'9$C#+E6C#" + "/QHC#3^ZC#7jmC#;v)D#?,)4kMYD4lVu`4m`:&5niUA5@(A5BA1]PBB:xlBCC=2CDLXMCEUtiCf&0g2'tN?PGT4CPGT4CPGT4CPGT4CPGT4CPGT4CPGT4CP" + "GT4CPGT4CPGT4CPGT4CPGT4CPGT4CP-qekC`.9kEg^+F$kwViFJTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5KTB&5o,^<-28ZI'O?;xp" + "O?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xpO?;xp;7q-#lLYI:xvD=#"; static const char* GetDefaultCompressedFontDataTTFBase85() { - return proggy_clean_ttf_compressed_data_base85; + return proggy_clean_ttf_compressed_data_base85; } diff --git a/examples/ThirdPartyLibs/imgui/imgui_internal.h b/examples/ThirdPartyLibs/imgui/imgui_internal.h index c2c055504..d2f535576 100644 --- a/examples/ThirdPartyLibs/imgui/imgui_internal.h +++ b/examples/ThirdPartyLibs/imgui/imgui_internal.h @@ -12,19 +12,19 @@ #error Must include imgui.h before imgui_internal.h #endif -#include // FILE* -#include // sqrtf, fabsf, fmodf, powf, floorf, ceilf, cosf, sinf -#include // INT_MIN, INT_MAX +#include // FILE* +#include // sqrtf, fabsf, fmodf, powf, floorf, ceilf, cosf, sinf +#include // INT_MIN, INT_MAX #ifdef _MSC_VER -#pragma warning (push) -#pragma warning (disable: 4251) // class 'xxx' needs to have dll-interface to be used by clients of struct 'xxx' // when IMGUI_API is set to__declspec(dllexport) +#pragma warning(push) +#pragma warning(disable : 4251) // class 'xxx' needs to have dll-interface to be used by clients of struct 'xxx' // when IMGUI_API is set to__declspec(dllexport) #endif #ifdef __clang__ #pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wunused-function" // for stb_textedit.h -#pragma clang diagnostic ignored "-Wmissing-prototypes" // for stb_textedit.h +#pragma clang diagnostic ignored "-Wunused-function" // for stb_textedit.h +#pragma clang diagnostic ignored "-Wmissing-prototypes" // for stb_textedit.h #pragma clang diagnostic ignored "-Wold-style-cast" #endif @@ -43,14 +43,14 @@ struct ImGuiPopupRef; struct ImGuiWindow; struct ImGuiWindowSettings; -typedef int ImGuiLayoutType; // enum: horizontal or vertical // enum ImGuiLayoutType_ -typedef int ImGuiButtonFlags; // flags: for ButtonEx(), ButtonBehavior() // enum ImGuiButtonFlags_ -typedef int ImGuiItemFlags; // flags: for PushItemFlag() // enum ImGuiItemFlags_ -typedef int ImGuiItemStatusFlags; // flags: storage for DC.LastItemXXX // enum ImGuiItemStatusFlags_ -typedef int ImGuiNavHighlightFlags; // flags: for RenderNavHighlight() // enum ImGuiNavHighlightFlags_ -typedef int ImGuiNavDirSourceFlags; // flags: for GetNavInputAmount2d() // enum ImGuiNavDirSourceFlags_ -typedef int ImGuiSeparatorFlags; // flags: for Separator() - internal // enum ImGuiSeparatorFlags_ -typedef int ImGuiSliderFlags; // flags: for SliderBehavior() // enum ImGuiSliderFlags_ +typedef int ImGuiLayoutType; // enum: horizontal or vertical // enum ImGuiLayoutType_ +typedef int ImGuiButtonFlags; // flags: for ButtonEx(), ButtonBehavior() // enum ImGuiButtonFlags_ +typedef int ImGuiItemFlags; // flags: for PushItemFlag() // enum ImGuiItemFlags_ +typedef int ImGuiItemStatusFlags; // flags: storage for DC.LastItemXXX // enum ImGuiItemStatusFlags_ +typedef int ImGuiNavHighlightFlags; // flags: for RenderNavHighlight() // enum ImGuiNavHighlightFlags_ +typedef int ImGuiNavDirSourceFlags; // flags: for GetNavInputAmount2d() // enum ImGuiNavDirSourceFlags_ +typedef int ImGuiSeparatorFlags; // flags: for Separator() - internal // enum ImGuiSeparatorFlags_ +typedef int ImGuiSliderFlags; // flags: for SliderBehavior() // enum ImGuiSliderFlags_ //------------------------------------------------------------------------- // STB libraries @@ -58,15 +58,14 @@ typedef int ImGuiSliderFlags; // flags: for SliderBehavior() namespace ImGuiStb { - #undef STB_TEXTEDIT_STRING #undef STB_TEXTEDIT_CHARTYPE -#define STB_TEXTEDIT_STRING ImGuiTextEditState -#define STB_TEXTEDIT_CHARTYPE ImWchar -#define STB_TEXTEDIT_GETWIDTH_NEWLINE -1.0f +#define STB_TEXTEDIT_STRING ImGuiTextEditState +#define STB_TEXTEDIT_CHARTYPE ImWchar +#define STB_TEXTEDIT_GETWIDTH_NEWLINE -1.0f #include "stb_textedit.h" -} // namespace ImGuiStb +} // namespace ImGuiStb //----------------------------------------------------------------------------- // Context @@ -80,94 +79,161 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit ImGui context pointe // Helpers //----------------------------------------------------------------------------- -#define IM_PI 3.14159265358979323846f +#define IM_PI 3.14159265358979323846f // Helpers: UTF-8 <> wchar -IMGUI_API int ImTextStrToUtf8(char* buf, int buf_size, const ImWchar* in_text, const ImWchar* in_text_end); // return output UTF-8 bytes count -IMGUI_API int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end); // return input UTF-8 bytes count -IMGUI_API int ImTextStrFromUtf8(ImWchar* buf, int buf_size, const char* in_text, const char* in_text_end, const char** in_remaining = NULL); // return input UTF-8 bytes count -IMGUI_API int ImTextCountCharsFromUtf8(const char* in_text, const char* in_text_end); // return number of UTF-8 code-points (NOT bytes count) -IMGUI_API int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end); // return number of bytes to express string as UTF-8 code-points +IMGUI_API int ImTextStrToUtf8(char* buf, int buf_size, const ImWchar* in_text, const ImWchar* in_text_end); // return output UTF-8 bytes count +IMGUI_API int ImTextCharFromUtf8(unsigned int* out_char, const char* in_text, const char* in_text_end); // return input UTF-8 bytes count +IMGUI_API int ImTextStrFromUtf8(ImWchar* buf, int buf_size, const char* in_text, const char* in_text_end, const char** in_remaining = NULL); // return input UTF-8 bytes count +IMGUI_API int ImTextCountCharsFromUtf8(const char* in_text, const char* in_text_end); // return number of UTF-8 code-points (NOT bytes count) +IMGUI_API int ImTextCountUtf8BytesFromStr(const ImWchar* in_text, const ImWchar* in_text_end); // return number of bytes to express string as UTF-8 code-points // Helpers: Misc -IMGUI_API ImU32 ImHash(const void* data, int data_size, ImU32 seed = 0); // Pass data_size==0 for zero-terminated strings -IMGUI_API void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, int* out_file_size = NULL, int padding_bytes = 0); -IMGUI_API FILE* ImFileOpen(const char* filename, const char* file_open_mode); -static inline bool ImCharIsSpace(int c) { return c == ' ' || c == '\t' || c == 0x3000; } -static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; } -static inline int ImUpperPowerOfTwo(int v) { v--; v |= v >> 1; v |= v >> 2; v |= v >> 4; v |= v >> 8; v |= v >> 16; v++; return v; } +IMGUI_API ImU32 ImHash(const void* data, int data_size, ImU32 seed = 0); // Pass data_size==0 for zero-terminated strings +IMGUI_API void* ImFileLoadToMemory(const char* filename, const char* file_open_mode, int* out_file_size = NULL, int padding_bytes = 0); +IMGUI_API FILE* ImFileOpen(const char* filename, const char* file_open_mode); +static inline bool ImCharIsSpace(int c) { return c == ' ' || c == '\t' || c == 0x3000; } +static inline bool ImIsPowerOfTwo(int v) { return v != 0 && (v & (v - 1)) == 0; } +static inline int ImUpperPowerOfTwo(int v) +{ + v--; + v |= v >> 1; + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + v++; + return v; +} // Helpers: Geometry -IMGUI_API ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p); -IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); -IMGUI_API ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); -IMGUI_API void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p, float& out_u, float& out_v, float& out_w); +IMGUI_API ImVec2 ImLineClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& p); +IMGUI_API bool ImTriangleContainsPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); +IMGUI_API ImVec2 ImTriangleClosestPoint(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p); +IMGUI_API void ImTriangleBarycentricCoords(const ImVec2& a, const ImVec2& b, const ImVec2& c, const ImVec2& p, float& out_u, float& out_v, float& out_w); // Helpers: String -IMGUI_API int ImStricmp(const char* str1, const char* str2); -IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count); -IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count); -IMGUI_API char* ImStrdup(const char* str); -IMGUI_API char* ImStrchrRange(const char* str_begin, const char* str_end, char c); -IMGUI_API int ImStrlenW(const ImWchar* str); -IMGUI_API const ImWchar*ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line -IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end); -IMGUI_API int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) IM_FMTARGS(3); -IMGUI_API int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) IM_FMTLIST(3); +IMGUI_API int ImStricmp(const char* str1, const char* str2); +IMGUI_API int ImStrnicmp(const char* str1, const char* str2, size_t count); +IMGUI_API void ImStrncpy(char* dst, const char* src, size_t count); +IMGUI_API char* ImStrdup(const char* str); +IMGUI_API char* ImStrchrRange(const char* str_begin, const char* str_end, char c); +IMGUI_API int ImStrlenW(const ImWchar* str); +IMGUI_API const ImWchar* ImStrbolW(const ImWchar* buf_mid_line, const ImWchar* buf_begin); // Find beginning-of-line +IMGUI_API const char* ImStristr(const char* haystack, const char* haystack_end, const char* needle, const char* needle_end); +IMGUI_API int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...) IM_FMTARGS(3); +IMGUI_API int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args) IM_FMTLIST(3); // Helpers: Math // We are keeping those not leaking to the user by default, in the case the user has implicit cast operators between ImVec2 and its own types (when IM_VEC2_CLASS_EXTRA is defined) #ifdef IMGUI_DEFINE_MATH_OPERATORS -static inline ImVec2 operator*(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x*rhs, lhs.y*rhs); } -static inline ImVec2 operator/(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x/rhs, lhs.y/rhs); } -static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x+rhs.x, lhs.y+rhs.y); } -static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x-rhs.x, lhs.y-rhs.y); } -static inline ImVec2 operator*(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x*rhs.x, lhs.y*rhs.y); } -static inline ImVec2 operator/(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x/rhs.x, lhs.y/rhs.y); } -static inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs) { lhs.x += rhs.x; lhs.y += rhs.y; return lhs; } -static inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) { lhs.x -= rhs.x; lhs.y -= rhs.y; return lhs; } -static inline ImVec2& operator*=(ImVec2& lhs, const float rhs) { lhs.x *= rhs; lhs.y *= rhs; return lhs; } -static inline ImVec2& operator/=(ImVec2& lhs, const float rhs) { lhs.x /= rhs; lhs.y /= rhs; return lhs; } -static inline ImVec4 operator+(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x+rhs.x, lhs.y+rhs.y, lhs.z+rhs.z, lhs.w+rhs.w); } -static inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x-rhs.x, lhs.y-rhs.y, lhs.z-rhs.z, lhs.w-rhs.w); } -static inline ImVec4 operator*(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x*rhs.x, lhs.y*rhs.y, lhs.z*rhs.z, lhs.w*rhs.w); } +static inline ImVec2 operator*(const ImVec2& lhs, const float rhs) +{ + return ImVec2(lhs.x * rhs, lhs.y * rhs); +} +static inline ImVec2 operator/(const ImVec2& lhs, const float rhs) { return ImVec2(lhs.x / rhs, lhs.y / rhs); } +static inline ImVec2 operator+(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x + rhs.x, lhs.y + rhs.y); } +static inline ImVec2 operator-(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x - rhs.x, lhs.y - rhs.y); } +static inline ImVec2 operator*(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } +static inline ImVec2 operator/(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x / rhs.x, lhs.y / rhs.y); } +static inline ImVec2& operator+=(ImVec2& lhs, const ImVec2& rhs) +{ + lhs.x += rhs.x; + lhs.y += rhs.y; + return lhs; +} +static inline ImVec2& operator-=(ImVec2& lhs, const ImVec2& rhs) +{ + lhs.x -= rhs.x; + lhs.y -= rhs.y; + return lhs; +} +static inline ImVec2& operator*=(ImVec2& lhs, const float rhs) +{ + lhs.x *= rhs; + lhs.y *= rhs; + return lhs; +} +static inline ImVec2& operator/=(ImVec2& lhs, const float rhs) +{ + lhs.x /= rhs; + lhs.y /= rhs; + return lhs; +} +static inline ImVec4 operator+(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w); } +static inline ImVec4 operator-(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w); } +static inline ImVec4 operator*(const ImVec4& lhs, const ImVec4& rhs) { return ImVec4(lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w); } #endif -static inline int ImMin(int lhs, int rhs) { return lhs < rhs ? lhs : rhs; } -static inline int ImMax(int lhs, int rhs) { return lhs >= rhs ? lhs : rhs; } -static inline float ImMin(float lhs, float rhs) { return lhs < rhs ? lhs : rhs; } -static inline float ImMax(float lhs, float rhs) { return lhs >= rhs ? lhs : rhs; } -static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x < rhs.x ? lhs.x : rhs.x, lhs.y < rhs.y ? lhs.y : rhs.y); } -static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x >= rhs.x ? lhs.x : rhs.x, lhs.y >= rhs.y ? lhs.y : rhs.y); } -static inline int ImClamp(int v, int mn, int mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } -static inline float ImClamp(float v, float mn, float mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } -static inline ImVec2 ImClamp(const ImVec2& f, const ImVec2& mn, ImVec2 mx) { return ImVec2(ImClamp(f.x,mn.x,mx.x), ImClamp(f.y,mn.y,mx.y)); } -static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; } -static inline void ImSwap(int& a, int& b) { int tmp = a; a = b; b = tmp; } -static inline void ImSwap(float& a, float& b) { float tmp = a; a = b; b = tmp; } -static inline int ImLerp(int a, int b, float t) { return (int)(a + (b - a) * t); } -static inline float ImLerp(float a, float b, float t) { return a + (b - a) * t; } -static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t) { return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t); } -static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); } -static inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t) { return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t); } -static inline float ImLengthSqr(const ImVec2& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y; } -static inline float ImLengthSqr(const ImVec4& lhs) { return lhs.x*lhs.x + lhs.y*lhs.y + lhs.z*lhs.z + lhs.w*lhs.w; } -static inline float ImInvLength(const ImVec2& lhs, float fail_value) { float d = lhs.x*lhs.x + lhs.y*lhs.y; if (d > 0.0f) return 1.0f / sqrtf(d); return fail_value; } -static inline float ImFloor(float f) { return (float)(int)f; } -static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)v.x, (float)(int)v.y); } -static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; } -static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); } -static inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; } -static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } +static inline int ImMin(int lhs, int rhs) +{ + return lhs < rhs ? lhs : rhs; +} +static inline int ImMax(int lhs, int rhs) { return lhs >= rhs ? lhs : rhs; } +static inline float ImMin(float lhs, float rhs) { return lhs < rhs ? lhs : rhs; } +static inline float ImMax(float lhs, float rhs) { return lhs >= rhs ? lhs : rhs; } +static inline ImVec2 ImMin(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x < rhs.x ? lhs.x : rhs.x, lhs.y < rhs.y ? lhs.y : rhs.y); } +static inline ImVec2 ImMax(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x >= rhs.x ? lhs.x : rhs.x, lhs.y >= rhs.y ? lhs.y : rhs.y); } +static inline int ImClamp(int v, int mn, int mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } +static inline float ImClamp(float v, float mn, float mx) { return (v < mn) ? mn : (v > mx) ? mx : v; } +static inline ImVec2 ImClamp(const ImVec2& f, const ImVec2& mn, ImVec2 mx) { return ImVec2(ImClamp(f.x, mn.x, mx.x), ImClamp(f.y, mn.y, mx.y)); } +static inline float ImSaturate(float f) { return (f < 0.0f) ? 0.0f : (f > 1.0f) ? 1.0f : f; } +static inline void ImSwap(int& a, int& b) +{ + int tmp = a; + a = b; + b = tmp; +} +static inline void ImSwap(float& a, float& b) +{ + float tmp = a; + a = b; + b = tmp; +} +static inline int ImLerp(int a, int b, float t) { return (int)(a + (b - a) * t); } +static inline float ImLerp(float a, float b, float t) { return a + (b - a) * t; } +static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, float t) { return ImVec2(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t); } +static inline ImVec2 ImLerp(const ImVec2& a, const ImVec2& b, const ImVec2& t) { return ImVec2(a.x + (b.x - a.x) * t.x, a.y + (b.y - a.y) * t.y); } +static inline ImVec4 ImLerp(const ImVec4& a, const ImVec4& b, float t) { return ImVec4(a.x + (b.x - a.x) * t, a.y + (b.y - a.y) * t, a.z + (b.z - a.z) * t, a.w + (b.w - a.w) * t); } +static inline float ImLengthSqr(const ImVec2& lhs) { return lhs.x * lhs.x + lhs.y * lhs.y; } +static inline float ImLengthSqr(const ImVec4& lhs) { return lhs.x * lhs.x + lhs.y * lhs.y + lhs.z * lhs.z + lhs.w * lhs.w; } +static inline float ImInvLength(const ImVec2& lhs, float fail_value) +{ + float d = lhs.x * lhs.x + lhs.y * lhs.y; + if (d > 0.0f) return 1.0f / sqrtf(d); + return fail_value; +} +static inline float ImFloor(float f) { return (float)(int)f; } +static inline ImVec2 ImFloor(const ImVec2& v) { return ImVec2((float)(int)v.x, (float)(int)v.y); } +static inline float ImDot(const ImVec2& a, const ImVec2& b) { return a.x * b.x + a.y * b.y; } +static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); } +static inline float ImLinearSweep(float current, float target, float speed) +{ + if (current < target) return ImMin(current + speed, target); + if (current > target) return ImMax(current - speed, target); + return current; +} +static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } // We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax. // Defining a custom placement new() with a dummy parameter allows us to bypass including which on some platforms complains when user has disabled exceptions. -struct ImNewPlacementDummy {}; -inline void* operator new(size_t, ImNewPlacementDummy, void* ptr) { return ptr; } -inline void operator delete(void*, ImNewPlacementDummy, void*) {} // This is only required so we can use the symetrical new() -#define IM_PLACEMENT_NEW(_PTR) new(ImNewPlacementDummy(), _PTR) -#define IM_NEW(_TYPE) new(ImNewPlacementDummy(), ImGui::MemAlloc(sizeof(_TYPE))) _TYPE -template void IM_DELETE(T*& p) { if (p) { p->~T(); ImGui::MemFree(p); p = NULL; } } +struct ImNewPlacementDummy +{ +}; +inline void* operator new(size_t, ImNewPlacementDummy, void* ptr) { return ptr; } +inline void operator delete(void*, ImNewPlacementDummy, void*) {} // This is only required so we can use the symetrical new() +#define IM_PLACEMENT_NEW(_PTR) new (ImNewPlacementDummy(), _PTR) +#define IM_NEW(_TYPE) new (ImNewPlacementDummy(), ImGui::MemAlloc(sizeof(_TYPE))) _TYPE +template +void IM_DELETE(T*& p) +{ + if (p) + { + p->~T(); + ImGui::MemFree(p); + p = NULL; + } +} //----------------------------------------------------------------------------- // Types @@ -175,837 +241,951 @@ template void IM_DELETE(T*& p) { if (p) { p->~T(); ImGui::MemFree(p enum ImGuiButtonFlags_ { - ImGuiButtonFlags_Repeat = 1 << 0, // hold to repeat - ImGuiButtonFlags_PressedOnClickRelease = 1 << 1, // return true on click + release on same item [DEFAULT if no PressedOn* flag is set] - ImGuiButtonFlags_PressedOnClick = 1 << 2, // return true on click (default requires click+release) - ImGuiButtonFlags_PressedOnRelease = 1 << 3, // return true on release (default requires click+release) - ImGuiButtonFlags_PressedOnDoubleClick = 1 << 4, // return true on double-click (default requires click+release) - ImGuiButtonFlags_FlattenChildren = 1 << 5, // allow interactions even if a child window is overlapping - ImGuiButtonFlags_AllowItemOverlap = 1 << 6, // require previous frame HoveredId to either match id or be null before being usable, use along with SetItemAllowOverlap() - ImGuiButtonFlags_DontClosePopups = 1 << 7, // disable automatically closing parent popup on press // [UNUSED] - ImGuiButtonFlags_Disabled = 1 << 8, // disable interactions - ImGuiButtonFlags_AlignTextBaseLine = 1 << 9, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine - ImGuiButtonFlags_NoKeyModifiers = 1 << 10, // disable interaction if a key modifier is held - ImGuiButtonFlags_NoHoldingActiveID = 1 << 11, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only) - ImGuiButtonFlags_PressedOnDragDropHold = 1 << 12, // press when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers) - ImGuiButtonFlags_NoNavFocus = 1 << 13 // don't override navigation focus when activated + ImGuiButtonFlags_Repeat = 1 << 0, // hold to repeat + ImGuiButtonFlags_PressedOnClickRelease = 1 << 1, // return true on click + release on same item [DEFAULT if no PressedOn* flag is set] + ImGuiButtonFlags_PressedOnClick = 1 << 2, // return true on click (default requires click+release) + ImGuiButtonFlags_PressedOnRelease = 1 << 3, // return true on release (default requires click+release) + ImGuiButtonFlags_PressedOnDoubleClick = 1 << 4, // return true on double-click (default requires click+release) + ImGuiButtonFlags_FlattenChildren = 1 << 5, // allow interactions even if a child window is overlapping + ImGuiButtonFlags_AllowItemOverlap = 1 << 6, // require previous frame HoveredId to either match id or be null before being usable, use along with SetItemAllowOverlap() + ImGuiButtonFlags_DontClosePopups = 1 << 7, // disable automatically closing parent popup on press // [UNUSED] + ImGuiButtonFlags_Disabled = 1 << 8, // disable interactions + ImGuiButtonFlags_AlignTextBaseLine = 1 << 9, // vertically align button to match text baseline - ButtonEx() only // FIXME: Should be removed and handled by SmallButton(), not possible currently because of DC.CursorPosPrevLine + ImGuiButtonFlags_NoKeyModifiers = 1 << 10, // disable interaction if a key modifier is held + ImGuiButtonFlags_NoHoldingActiveID = 1 << 11, // don't set ActiveId while holding the mouse (ImGuiButtonFlags_PressedOnClick only) + ImGuiButtonFlags_PressedOnDragDropHold = 1 << 12, // press when held into while we are drag and dropping another item (used by e.g. tree nodes, collapsing headers) + ImGuiButtonFlags_NoNavFocus = 1 << 13 // don't override navigation focus when activated }; enum ImGuiSliderFlags_ { - ImGuiSliderFlags_Vertical = 1 << 0 + ImGuiSliderFlags_Vertical = 1 << 0 }; enum ImGuiColumnsFlags_ { - // Default: 0 - ImGuiColumnsFlags_NoBorder = 1 << 0, // Disable column dividers - ImGuiColumnsFlags_NoResize = 1 << 1, // Disable resizing columns when clicking on the dividers - ImGuiColumnsFlags_NoPreserveWidths = 1 << 2, // Disable column width preservation when adjusting columns - ImGuiColumnsFlags_NoForceWithinWindow = 1 << 3, // Disable forcing columns to fit within window - ImGuiColumnsFlags_GrowParentContentsSize= 1 << 4 // (WIP) Restore pre-1.51 behavior of extending the parent window contents size but _without affecting the columns width at all_. Will eventually remove. + // Default: 0 + ImGuiColumnsFlags_NoBorder = 1 << 0, // Disable column dividers + ImGuiColumnsFlags_NoResize = 1 << 1, // Disable resizing columns when clicking on the dividers + ImGuiColumnsFlags_NoPreserveWidths = 1 << 2, // Disable column width preservation when adjusting columns + ImGuiColumnsFlags_NoForceWithinWindow = 1 << 3, // Disable forcing columns to fit within window + ImGuiColumnsFlags_GrowParentContentsSize = 1 << 4 // (WIP) Restore pre-1.51 behavior of extending the parent window contents size but _without affecting the columns width at all_. Will eventually remove. }; enum ImGuiSelectableFlagsPrivate_ { - // NB: need to be in sync with last value of ImGuiSelectableFlags_ - ImGuiSelectableFlags_Menu = 1 << 3, // -> PressedOnClick - ImGuiSelectableFlags_MenuItem = 1 << 4, // -> PressedOnRelease - ImGuiSelectableFlags_Disabled = 1 << 5, - ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 6 + // NB: need to be in sync with last value of ImGuiSelectableFlags_ + ImGuiSelectableFlags_Menu = 1 << 3, // -> PressedOnClick + ImGuiSelectableFlags_MenuItem = 1 << 4, // -> PressedOnRelease + ImGuiSelectableFlags_Disabled = 1 << 5, + ImGuiSelectableFlags_DrawFillAvailWidth = 1 << 6 }; enum ImGuiSeparatorFlags_ { - ImGuiSeparatorFlags_Horizontal = 1 << 0, // Axis default to current layout type, so generally Horizontal unless e.g. in a menu bar - ImGuiSeparatorFlags_Vertical = 1 << 1 + ImGuiSeparatorFlags_Horizontal = 1 << 0, // Axis default to current layout type, so generally Horizontal unless e.g. in a menu bar + ImGuiSeparatorFlags_Vertical = 1 << 1 }; // Storage for LastItem data enum ImGuiItemStatusFlags_ { - ImGuiItemStatusFlags_HoveredRect = 1 << 0, - ImGuiItemStatusFlags_HasDisplayRect = 1 << 1 + ImGuiItemStatusFlags_HoveredRect = 1 << 0, + ImGuiItemStatusFlags_HasDisplayRect = 1 << 1 }; // FIXME: this is in development, not exposed/functional as a generic feature yet. enum ImGuiLayoutType_ { - ImGuiLayoutType_Vertical, - ImGuiLayoutType_Horizontal + ImGuiLayoutType_Vertical, + ImGuiLayoutType_Horizontal }; enum ImGuiAxis { - ImGuiAxis_None = -1, - ImGuiAxis_X = 0, - ImGuiAxis_Y = 1 + ImGuiAxis_None = -1, + ImGuiAxis_X = 0, + ImGuiAxis_Y = 1 }; enum ImGuiPlotType { - ImGuiPlotType_Lines, - ImGuiPlotType_Histogram + ImGuiPlotType_Lines, + ImGuiPlotType_Histogram }; enum ImGuiDataType { - ImGuiDataType_Int, - ImGuiDataType_Float, - ImGuiDataType_Float2 + ImGuiDataType_Int, + ImGuiDataType_Float, + ImGuiDataType_Float2 }; enum ImGuiDir { - ImGuiDir_None = -1, - ImGuiDir_Left = 0, - ImGuiDir_Right = 1, - ImGuiDir_Up = 2, - ImGuiDir_Down = 3, - ImGuiDir_Count_ + ImGuiDir_None = -1, + ImGuiDir_Left = 0, + ImGuiDir_Right = 1, + ImGuiDir_Up = 2, + ImGuiDir_Down = 3, + ImGuiDir_Count_ }; enum ImGuiInputSource { - ImGuiInputSource_None = 0, - ImGuiInputSource_Mouse, - ImGuiInputSource_Nav, - ImGuiInputSource_NavKeyboard, // Only used occasionally for storage, not tested/handled by most code - ImGuiInputSource_NavGamepad, // " - ImGuiInputSource_Count_, + ImGuiInputSource_None = 0, + ImGuiInputSource_Mouse, + ImGuiInputSource_Nav, + ImGuiInputSource_NavKeyboard, // Only used occasionally for storage, not tested/handled by most code + ImGuiInputSource_NavGamepad, // " + ImGuiInputSource_Count_, }; // FIXME-NAV: Clarify/expose various repeat delay/rate enum ImGuiInputReadMode { - ImGuiInputReadMode_Down, - ImGuiInputReadMode_Pressed, - ImGuiInputReadMode_Released, - ImGuiInputReadMode_Repeat, - ImGuiInputReadMode_RepeatSlow, - ImGuiInputReadMode_RepeatFast + ImGuiInputReadMode_Down, + ImGuiInputReadMode_Pressed, + ImGuiInputReadMode_Released, + ImGuiInputReadMode_Repeat, + ImGuiInputReadMode_RepeatSlow, + ImGuiInputReadMode_RepeatFast }; enum ImGuiNavHighlightFlags_ { - ImGuiNavHighlightFlags_TypeDefault = 1 << 0, - ImGuiNavHighlightFlags_TypeThin = 1 << 1, - ImGuiNavHighlightFlags_AlwaysDraw = 1 << 2, - ImGuiNavHighlightFlags_NoRounding = 1 << 3 + ImGuiNavHighlightFlags_TypeDefault = 1 << 0, + ImGuiNavHighlightFlags_TypeThin = 1 << 1, + ImGuiNavHighlightFlags_AlwaysDraw = 1 << 2, + ImGuiNavHighlightFlags_NoRounding = 1 << 3 }; enum ImGuiNavDirSourceFlags_ { - ImGuiNavDirSourceFlags_Keyboard = 1 << 0, - ImGuiNavDirSourceFlags_PadDPad = 1 << 1, - ImGuiNavDirSourceFlags_PadLStick = 1 << 2 + ImGuiNavDirSourceFlags_Keyboard = 1 << 0, + ImGuiNavDirSourceFlags_PadDPad = 1 << 1, + ImGuiNavDirSourceFlags_PadLStick = 1 << 2 }; enum ImGuiNavForward { - ImGuiNavForward_None, - ImGuiNavForward_ForwardQueued, - ImGuiNavForward_ForwardActive + ImGuiNavForward_None, + ImGuiNavForward_ForwardQueued, + ImGuiNavForward_ForwardActive }; // 2D axis aligned bounding-box // NB: we can't rely on ImVec2 math operators being available here struct IMGUI_API ImRect { - ImVec2 Min; // Upper-left - ImVec2 Max; // Lower-right + ImVec2 Min; // Upper-left + ImVec2 Max; // Lower-right - ImRect() : Min(FLT_MAX,FLT_MAX), Max(-FLT_MAX,-FLT_MAX) {} - ImRect(const ImVec2& min, const ImVec2& max) : Min(min), Max(max) {} - ImRect(const ImVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {} - ImRect(float x1, float y1, float x2, float y2) : Min(x1, y1), Max(x2, y2) {} + ImRect() : Min(FLT_MAX, FLT_MAX), Max(-FLT_MAX, -FLT_MAX) {} + ImRect(const ImVec2& min, const ImVec2& max) : Min(min), Max(max) {} + ImRect(const ImVec4& v) : Min(v.x, v.y), Max(v.z, v.w) {} + ImRect(float x1, float y1, float x2, float y2) : Min(x1, y1), Max(x2, y2) {} - ImVec2 GetCenter() const { return ImVec2((Min.x + Max.x) * 0.5f, (Min.y + Max.y) * 0.5f); } - ImVec2 GetSize() const { return ImVec2(Max.x - Min.x, Max.y - Min.y); } - float GetWidth() const { return Max.x - Min.x; } - float GetHeight() const { return Max.y - Min.y; } - ImVec2 GetTL() const { return Min; } // Top-left - ImVec2 GetTR() const { return ImVec2(Max.x, Min.y); } // Top-right - ImVec2 GetBL() const { return ImVec2(Min.x, Max.y); } // Bottom-left - ImVec2 GetBR() const { return Max; } // Bottom-right - bool Contains(const ImVec2& p) const { return p.x >= Min.x && p.y >= Min.y && p.x < Max.x && p.y < Max.y; } - bool Contains(const ImRect& r) const { return r.Min.x >= Min.x && r.Min.y >= Min.y && r.Max.x <= Max.x && r.Max.y <= Max.y; } - bool Overlaps(const ImRect& r) const { return r.Min.y < Max.y && r.Max.y > Min.y && r.Min.x < Max.x && r.Max.x > Min.x; } - void Add(const ImVec2& p) { if (Min.x > p.x) Min.x = p.x; if (Min.y > p.y) Min.y = p.y; if (Max.x < p.x) Max.x = p.x; if (Max.y < p.y) Max.y = p.y; } - void Add(const ImRect& r) { if (Min.x > r.Min.x) Min.x = r.Min.x; if (Min.y > r.Min.y) Min.y = r.Min.y; if (Max.x < r.Max.x) Max.x = r.Max.x; if (Max.y < r.Max.y) Max.y = r.Max.y; } - void Expand(const float amount) { Min.x -= amount; Min.y -= amount; Max.x += amount; Max.y += amount; } - void Expand(const ImVec2& amount) { Min.x -= amount.x; Min.y -= amount.y; Max.x += amount.x; Max.y += amount.y; } - void Translate(const ImVec2& v) { Min.x += v.x; Min.y += v.y; Max.x += v.x; Max.y += v.y; } - void ClipWith(const ImRect& r) { Min = ImMax(Min, r.Min); Max = ImMin(Max, r.Max); } // Simple version, may lead to an inverted rectangle, which is fine for Contains/Overlaps test but not for display. - void ClipWithFull(const ImRect& r) { Min = ImClamp(Min, r.Min, r.Max); Max = ImClamp(Max, r.Min, r.Max); } // Full version, ensure both points are fully clipped. - void Floor() { Min.x = (float)(int)Min.x; Min.y = (float)(int)Min.y; Max.x = (float)(int)Max.x; Max.y = (float)(int)Max.y; } - void FixInverted() { if (Min.x > Max.x) ImSwap(Min.x, Max.x); if (Min.y > Max.y) ImSwap(Min.y, Max.y); } - bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; } - bool IsFinite() const { return Min.x != FLT_MAX; } + ImVec2 GetCenter() const { return ImVec2((Min.x + Max.x) * 0.5f, (Min.y + Max.y) * 0.5f); } + ImVec2 GetSize() const { return ImVec2(Max.x - Min.x, Max.y - Min.y); } + float GetWidth() const { return Max.x - Min.x; } + float GetHeight() const { return Max.y - Min.y; } + ImVec2 GetTL() const { return Min; } // Top-left + ImVec2 GetTR() const { return ImVec2(Max.x, Min.y); } // Top-right + ImVec2 GetBL() const { return ImVec2(Min.x, Max.y); } // Bottom-left + ImVec2 GetBR() const { return Max; } // Bottom-right + bool Contains(const ImVec2& p) const { return p.x >= Min.x && p.y >= Min.y && p.x < Max.x && p.y < Max.y; } + bool Contains(const ImRect& r) const { return r.Min.x >= Min.x && r.Min.y >= Min.y && r.Max.x <= Max.x && r.Max.y <= Max.y; } + bool Overlaps(const ImRect& r) const { return r.Min.y < Max.y && r.Max.y > Min.y && r.Min.x < Max.x && r.Max.x > Min.x; } + void Add(const ImVec2& p) + { + if (Min.x > p.x) Min.x = p.x; + if (Min.y > p.y) Min.y = p.y; + if (Max.x < p.x) Max.x = p.x; + if (Max.y < p.y) Max.y = p.y; + } + void Add(const ImRect& r) + { + if (Min.x > r.Min.x) Min.x = r.Min.x; + if (Min.y > r.Min.y) Min.y = r.Min.y; + if (Max.x < r.Max.x) Max.x = r.Max.x; + if (Max.y < r.Max.y) Max.y = r.Max.y; + } + void Expand(const float amount) + { + Min.x -= amount; + Min.y -= amount; + Max.x += amount; + Max.y += amount; + } + void Expand(const ImVec2& amount) + { + Min.x -= amount.x; + Min.y -= amount.y; + Max.x += amount.x; + Max.y += amount.y; + } + void Translate(const ImVec2& v) + { + Min.x += v.x; + Min.y += v.y; + Max.x += v.x; + Max.y += v.y; + } + void ClipWith(const ImRect& r) + { + Min = ImMax(Min, r.Min); + Max = ImMin(Max, r.Max); + } // Simple version, may lead to an inverted rectangle, which is fine for Contains/Overlaps test but not for display. + void ClipWithFull(const ImRect& r) + { + Min = ImClamp(Min, r.Min, r.Max); + Max = ImClamp(Max, r.Min, r.Max); + } // Full version, ensure both points are fully clipped. + void Floor() + { + Min.x = (float)(int)Min.x; + Min.y = (float)(int)Min.y; + Max.x = (float)(int)Max.x; + Max.y = (float)(int)Max.y; + } + void FixInverted() + { + if (Min.x > Max.x) ImSwap(Min.x, Max.x); + if (Min.y > Max.y) ImSwap(Min.y, Max.y); + } + bool IsInverted() const { return Min.x > Max.x || Min.y > Max.y; } + bool IsFinite() const { return Min.x != FLT_MAX; } }; // Stacked color modifier, backup of modified data so we can restore it struct ImGuiColMod { - ImGuiCol Col; - ImVec4 BackupValue; + ImGuiCol Col; + ImVec4 BackupValue; }; // Stacked style modifier, backup of modified data so we can restore it. Data type inferred from the variable. struct ImGuiStyleMod { - ImGuiStyleVar VarIdx; - union { int BackupInt[2]; float BackupFloat[2]; }; - ImGuiStyleMod(ImGuiStyleVar idx, int v) { VarIdx = idx; BackupInt[0] = v; } - ImGuiStyleMod(ImGuiStyleVar idx, float v) { VarIdx = idx; BackupFloat[0] = v; } - ImGuiStyleMod(ImGuiStyleVar idx, ImVec2 v) { VarIdx = idx; BackupFloat[0] = v.x; BackupFloat[1] = v.y; } + ImGuiStyleVar VarIdx; + union { + int BackupInt[2]; + float BackupFloat[2]; + }; + ImGuiStyleMod(ImGuiStyleVar idx, int v) + { + VarIdx = idx; + BackupInt[0] = v; + } + ImGuiStyleMod(ImGuiStyleVar idx, float v) + { + VarIdx = idx; + BackupFloat[0] = v; + } + ImGuiStyleMod(ImGuiStyleVar idx, ImVec2 v) + { + VarIdx = idx; + BackupFloat[0] = v.x; + BackupFloat[1] = v.y; + } }; // Stacked data for BeginGroup()/EndGroup() struct ImGuiGroupData { - ImVec2 BackupCursorPos; - ImVec2 BackupCursorMaxPos; - float BackupIndentX; - float BackupGroupOffsetX; - float BackupCurrentLineHeight; - float BackupCurrentLineTextBaseOffset; - float BackupLogLinePosY; - bool BackupActiveIdIsAlive; - bool AdvanceCursor; + ImVec2 BackupCursorPos; + ImVec2 BackupCursorMaxPos; + float BackupIndentX; + float BackupGroupOffsetX; + float BackupCurrentLineHeight; + float BackupCurrentLineTextBaseOffset; + float BackupLogLinePosY; + bool BackupActiveIdIsAlive; + bool AdvanceCursor; }; // Simple column measurement currently used for MenuItem() only. This is very short-sighted/throw-away code and NOT a generic helper. struct IMGUI_API ImGuiMenuColumns { - int Count; - float Spacing; - float Width, NextWidth; - float Pos[4], NextWidths[4]; + int Count; + float Spacing; + float Width, NextWidth; + float Pos[4], NextWidths[4]; - ImGuiMenuColumns(); - void Update(int count, float spacing, bool clear); - float DeclColumns(float w0, float w1, float w2); - float CalcExtraSpace(float avail_w); + ImGuiMenuColumns(); + void Update(int count, float spacing, bool clear); + float DeclColumns(float w0, float w1, float w2); + float CalcExtraSpace(float avail_w); }; // Internal state of the currently focused/edited text input box struct IMGUI_API ImGuiTextEditState { - ImGuiID Id; // widget id owning the text state - ImVector Text; // edit buffer, we need to persist but can't guarantee the persistence of the user-provided buffer. so we copy into own buffer. - ImVector InitialText; // backup of end-user buffer at the time of focus (in UTF-8, unaltered) - ImVector TempTextBuffer; - int CurLenA, CurLenW; // we need to maintain our buffer length in both UTF-8 and wchar format. - int BufSizeA; // end-user buffer size - float ScrollX; - ImGuiStb::STB_TexteditState StbState; - float CursorAnim; - bool CursorFollow; - bool SelectedAllMouseLock; + ImGuiID Id; // widget id owning the text state + ImVector Text; // edit buffer, we need to persist but can't guarantee the persistence of the user-provided buffer. so we copy into own buffer. + ImVector InitialText; // backup of end-user buffer at the time of focus (in UTF-8, unaltered) + ImVector TempTextBuffer; + int CurLenA, CurLenW; // we need to maintain our buffer length in both UTF-8 and wchar format. + int BufSizeA; // end-user buffer size + float ScrollX; + ImGuiStb::STB_TexteditState StbState; + float CursorAnim; + bool CursorFollow; + bool SelectedAllMouseLock; - ImGuiTextEditState() { memset(this, 0, sizeof(*this)); } - void CursorAnimReset() { CursorAnim = -0.30f; } // After a user-input the cursor stays on for a while without blinking - void CursorClamp() { StbState.cursor = ImMin(StbState.cursor, CurLenW); StbState.select_start = ImMin(StbState.select_start, CurLenW); StbState.select_end = ImMin(StbState.select_end, CurLenW); } - bool HasSelection() const { return StbState.select_start != StbState.select_end; } - void ClearSelection() { StbState.select_start = StbState.select_end = StbState.cursor; } - void SelectAll() { StbState.select_start = 0; StbState.cursor = StbState.select_end = CurLenW; StbState.has_preferred_x = false; } - void OnKeyPressed(int key); + ImGuiTextEditState() { memset(this, 0, sizeof(*this)); } + void CursorAnimReset() { CursorAnim = -0.30f; } // After a user-input the cursor stays on for a while without blinking + void CursorClamp() + { + StbState.cursor = ImMin(StbState.cursor, CurLenW); + StbState.select_start = ImMin(StbState.select_start, CurLenW); + StbState.select_end = ImMin(StbState.select_end, CurLenW); + } + bool HasSelection() const { return StbState.select_start != StbState.select_end; } + void ClearSelection() { StbState.select_start = StbState.select_end = StbState.cursor; } + void SelectAll() + { + StbState.select_start = 0; + StbState.cursor = StbState.select_end = CurLenW; + StbState.has_preferred_x = false; + } + void OnKeyPressed(int key); }; // Data saved in imgui.ini file struct ImGuiWindowSettings { - char* Name; - ImGuiID Id; - ImVec2 Pos; - ImVec2 Size; - bool Collapsed; + char* Name; + ImGuiID Id; + ImVec2 Pos; + ImVec2 Size; + bool Collapsed; - ImGuiWindowSettings() { Name = NULL; Id = 0; Pos = Size = ImVec2(0,0); Collapsed = false; } + ImGuiWindowSettings() + { + Name = NULL; + Id = 0; + Pos = Size = ImVec2(0, 0); + Collapsed = false; + } }; struct ImGuiSettingsHandler { - const char* TypeName; // Short description stored in .ini file. Disallowed characters: '[' ']' - ImGuiID TypeHash; // == ImHash(TypeName, 0, 0) - void* (*ReadOpenFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, const char* name); - void (*ReadLineFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, void* entry, const char* line); - void (*WriteAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* out_buf); - void* UserData; + const char* TypeName; // Short description stored in .ini file. Disallowed characters: '[' ']' + ImGuiID TypeHash; // == ImHash(TypeName, 0, 0) + void* (*ReadOpenFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, const char* name); + void (*ReadLineFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, void* entry, const char* line); + void (*WriteAllFn)(ImGuiContext* ctx, ImGuiSettingsHandler* handler, ImGuiTextBuffer* out_buf); + void* UserData; - ImGuiSettingsHandler() { memset(this, 0, sizeof(*this)); } + ImGuiSettingsHandler() { memset(this, 0, sizeof(*this)); } }; // Storage for current popup stack struct ImGuiPopupRef { - ImGuiID PopupId; // Set on OpenPopup() - ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup() - ImGuiWindow* ParentWindow; // Set on OpenPopup() - int OpenFrameCount; // Set on OpenPopup() - ImGuiID OpenParentId; // Set on OpenPopup(), we need this to differenciate multiple menu sets from each others (e.g. inside menu bar vs loose menu items) - ImVec2 OpenPopupPos; // Set on OpenPopup(), preferred popup position (typically == OpenMousePos when using mouse) - ImVec2 OpenMousePos; // Set on OpenPopup(), copy of mouse position at the time of opening popup + ImGuiID PopupId; // Set on OpenPopup() + ImGuiWindow* Window; // Resolved on BeginPopup() - may stay unresolved if user never calls OpenPopup() + ImGuiWindow* ParentWindow; // Set on OpenPopup() + int OpenFrameCount; // Set on OpenPopup() + ImGuiID OpenParentId; // Set on OpenPopup(), we need this to differenciate multiple menu sets from each others (e.g. inside menu bar vs loose menu items) + ImVec2 OpenPopupPos; // Set on OpenPopup(), preferred popup position (typically == OpenMousePos when using mouse) + ImVec2 OpenMousePos; // Set on OpenPopup(), copy of mouse position at the time of opening popup }; struct ImGuiColumnData { - float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) - float OffsetNormBeforeResize; - ImGuiColumnsFlags Flags; // Not exposed - ImRect ClipRect; + float OffsetNorm; // Column start offset, normalized 0.0 (far left) -> 1.0 (far right) + float OffsetNormBeforeResize; + ImGuiColumnsFlags Flags; // Not exposed + ImRect ClipRect; - ImGuiColumnData() { OffsetNorm = OffsetNormBeforeResize = 0.0f; Flags = 0; } + ImGuiColumnData() + { + OffsetNorm = OffsetNormBeforeResize = 0.0f; + Flags = 0; + } }; struct ImGuiColumnsSet { - ImGuiID ID; - ImGuiColumnsFlags Flags; - bool IsFirstFrame; - bool IsBeingResized; - int Current; - int Count; - float MinX, MaxX; - float StartPosY; - float StartMaxPosX; // Backup of CursorMaxPos - float CellMinY, CellMaxY; - ImVector Columns; + ImGuiID ID; + ImGuiColumnsFlags Flags; + bool IsFirstFrame; + bool IsBeingResized; + int Current; + int Count; + float MinX, MaxX; + float StartPosY; + float StartMaxPosX; // Backup of CursorMaxPos + float CellMinY, CellMaxY; + ImVector Columns; - ImGuiColumnsSet() { Clear(); } - void Clear() - { - ID = 0; - Flags = 0; - IsFirstFrame = false; - IsBeingResized = false; - Current = 0; - Count = 1; - MinX = MaxX = 0.0f; - StartPosY = 0.0f; - StartMaxPosX = 0.0f; - CellMinY = CellMaxY = 0.0f; - Columns.clear(); - } + ImGuiColumnsSet() { Clear(); } + void Clear() + { + ID = 0; + Flags = 0; + IsFirstFrame = false; + IsBeingResized = false; + Current = 0; + Count = 1; + MinX = MaxX = 0.0f; + StartPosY = 0.0f; + StartMaxPosX = 0.0f; + CellMinY = CellMaxY = 0.0f; + Columns.clear(); + } }; struct IMGUI_API ImDrawListSharedData { - ImVec2 TexUvWhitePixel; // UV of white pixel in the atlas - ImFont* Font; // Current/default font (optional, for simplified AddText overload) - float FontSize; // Current/default font size (optional, for simplified AddText overload) - float CurveTessellationTol; - ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen() + ImVec2 TexUvWhitePixel; // UV of white pixel in the atlas + ImFont* Font; // Current/default font (optional, for simplified AddText overload) + float FontSize; // Current/default font size (optional, for simplified AddText overload) + float CurveTessellationTol; + ImVec4 ClipRectFullscreen; // Value for PushClipRectFullscreen() - // Const data - // FIXME: Bake rounded corners fill/borders in atlas - ImVec2 CircleVtx12[12]; + // Const data + // FIXME: Bake rounded corners fill/borders in atlas + ImVec2 CircleVtx12[12]; - ImDrawListSharedData(); + ImDrawListSharedData(); }; struct ImDrawDataBuilder { - ImVector Layers[2]; // Global layers for: regular, tooltip + ImVector Layers[2]; // Global layers for: regular, tooltip - void Clear() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].resize(0); } - void ClearFreeMemory() { for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].clear(); } - IMGUI_API void FlattenIntoSingleLayer(); + void Clear() + { + for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].resize(0); + } + void ClearFreeMemory() + { + for (int n = 0; n < IM_ARRAYSIZE(Layers); n++) Layers[n].clear(); + } + IMGUI_API void FlattenIntoSingleLayer(); }; struct ImGuiNavMoveResult { - ImGuiID ID; // Best candidate - ImGuiID ParentID; // Best candidate window->IDStack.back() - to compare context - ImGuiWindow* Window; // Best candidate window - float DistBox; // Best candidate box distance to current NavId - float DistCenter; // Best candidate center distance to current NavId - float DistAxial; - ImRect RectRel; // Best candidate bounding box in window relative space + ImGuiID ID; // Best candidate + ImGuiID ParentID; // Best candidate window->IDStack.back() - to compare context + ImGuiWindow* Window; // Best candidate window + float DistBox; // Best candidate box distance to current NavId + float DistCenter; // Best candidate center distance to current NavId + float DistAxial; + ImRect RectRel; // Best candidate bounding box in window relative space - ImGuiNavMoveResult() { Clear(); } - void Clear() { ID = ParentID = 0; Window = NULL; DistBox = DistCenter = DistAxial = FLT_MAX; RectRel = ImRect(); } + ImGuiNavMoveResult() { Clear(); } + void Clear() + { + ID = ParentID = 0; + Window = NULL; + DistBox = DistCenter = DistAxial = FLT_MAX; + RectRel = ImRect(); + } }; // Storage for SetNexWindow** functions struct ImGuiNextWindowData { - ImGuiCond PosCond; - ImGuiCond SizeCond; - ImGuiCond ContentSizeCond; - ImGuiCond CollapsedCond; - ImGuiCond SizeConstraintCond; - ImGuiCond FocusCond; - ImGuiCond BgAlphaCond; - ImVec2 PosVal; - ImVec2 PosPivotVal; - ImVec2 SizeVal; - ImVec2 ContentSizeVal; - bool CollapsedVal; - ImRect SizeConstraintRect; // Valid if 'SetNextWindowSizeConstraint' is true - ImGuiSizeCallback SizeCallback; - void* SizeCallbackUserData; - float BgAlphaVal; + ImGuiCond PosCond; + ImGuiCond SizeCond; + ImGuiCond ContentSizeCond; + ImGuiCond CollapsedCond; + ImGuiCond SizeConstraintCond; + ImGuiCond FocusCond; + ImGuiCond BgAlphaCond; + ImVec2 PosVal; + ImVec2 PosPivotVal; + ImVec2 SizeVal; + ImVec2 ContentSizeVal; + bool CollapsedVal; + ImRect SizeConstraintRect; // Valid if 'SetNextWindowSizeConstraint' is true + ImGuiSizeCallback SizeCallback; + void* SizeCallbackUserData; + float BgAlphaVal; - ImGuiNextWindowData() - { - PosCond = SizeCond = ContentSizeCond = CollapsedCond = SizeConstraintCond = FocusCond = BgAlphaCond = 0; - PosVal = PosPivotVal = SizeVal = ImVec2(0.0f, 0.0f); - ContentSizeVal = ImVec2(0.0f, 0.0f); - CollapsedVal = false; - SizeConstraintRect = ImRect(); - SizeCallback = NULL; - SizeCallbackUserData = NULL; - BgAlphaVal = FLT_MAX; - } + ImGuiNextWindowData() + { + PosCond = SizeCond = ContentSizeCond = CollapsedCond = SizeConstraintCond = FocusCond = BgAlphaCond = 0; + PosVal = PosPivotVal = SizeVal = ImVec2(0.0f, 0.0f); + ContentSizeVal = ImVec2(0.0f, 0.0f); + CollapsedVal = false; + SizeConstraintRect = ImRect(); + SizeCallback = NULL; + SizeCallbackUserData = NULL; + BgAlphaVal = FLT_MAX; + } - void Clear() - { - PosCond = SizeCond = ContentSizeCond = CollapsedCond = SizeConstraintCond = FocusCond = BgAlphaCond = 0; - } + void Clear() + { + PosCond = SizeCond = ContentSizeCond = CollapsedCond = SizeConstraintCond = FocusCond = BgAlphaCond = 0; + } }; // Main state for ImGui struct ImGuiContext { - bool Initialized; - bool FontAtlasOwnedByContext; // Io.Fonts-> is owned by the ImGuiContext and will be destructed along with it. - ImGuiIO IO; - ImGuiStyle Style; - ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() - float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window. - float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height. - ImDrawListSharedData DrawListSharedData; + bool Initialized; + bool FontAtlasOwnedByContext; // Io.Fonts-> is owned by the ImGuiContext and will be destructed along with it. + ImGuiIO IO; + ImGuiStyle Style; + ImFont* Font; // (Shortcut) == FontStack.empty() ? IO.Font : FontStack.back() + float FontSize; // (Shortcut) == FontBaseSize * g.CurrentWindow->FontWindowScale == window->FontSize(). Text height for current window. + float FontBaseSize; // (Shortcut) == IO.FontGlobalScale * Font->Scale * Font->FontSize. Base text height. + ImDrawListSharedData DrawListSharedData; - float Time; - int FrameCount; - int FrameCountEnded; - int FrameCountRendered; - ImVector Windows; - ImVector WindowsSortBuffer; - ImVector CurrentWindowStack; - ImGuiStorage WindowsById; - int WindowsActiveCount; - ImGuiWindow* CurrentWindow; // Being drawn into - ImGuiWindow* HoveredWindow; // Will catch mouse inputs - ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only) - ImGuiID HoveredId; // Hovered widget - bool HoveredIdAllowOverlap; - ImGuiID HoveredIdPreviousFrame; - float HoveredIdTimer; - ImGuiID ActiveId; // Active widget - ImGuiID ActiveIdPreviousFrame; - float ActiveIdTimer; - bool ActiveIdIsAlive; // Active widget has been seen this frame - bool ActiveIdIsJustActivated; // Set at the time of activation for one frame - bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always) - int ActiveIdAllowNavDirFlags; // Active widget allows using directional navigation (e.g. can activate a button and move away from it) - ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior) - ImGuiWindow* ActiveIdWindow; - ImGuiInputSource ActiveIdSource; // Activating with mouse or nav (gamepad/keyboard) - ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actually window that is moved is generally MovingWindow->RootWindow. - ImVector ColorModifiers; // Stack for PushStyleColor()/PopStyleColor() - ImVector StyleModifiers; // Stack for PushStyleVar()/PopStyleVar() - ImVector FontStack; // Stack for PushFont()/PopFont() - ImVector OpenPopupStack; // Which popups are open (persistent) - ImVector CurrentPopupStack; // Which level of BeginPopup() we are in (reset every frame) - ImGuiNextWindowData NextWindowData; // Storage for SetNextWindow** functions - bool NextTreeNodeOpenVal; // Storage for SetNextTreeNode** functions - ImGuiCond NextTreeNodeOpenCond; + float Time; + int FrameCount; + int FrameCountEnded; + int FrameCountRendered; + ImVector Windows; + ImVector WindowsSortBuffer; + ImVector CurrentWindowStack; + ImGuiStorage WindowsById; + int WindowsActiveCount; + ImGuiWindow* CurrentWindow; // Being drawn into + ImGuiWindow* HoveredWindow; // Will catch mouse inputs + ImGuiWindow* HoveredRootWindow; // Will catch mouse inputs (for focus/move only) + ImGuiID HoveredId; // Hovered widget + bool HoveredIdAllowOverlap; + ImGuiID HoveredIdPreviousFrame; + float HoveredIdTimer; + ImGuiID ActiveId; // Active widget + ImGuiID ActiveIdPreviousFrame; + float ActiveIdTimer; + bool ActiveIdIsAlive; // Active widget has been seen this frame + bool ActiveIdIsJustActivated; // Set at the time of activation for one frame + bool ActiveIdAllowOverlap; // Active widget allows another widget to steal active id (generally for overlapping widgets, but not always) + int ActiveIdAllowNavDirFlags; // Active widget allows using directional navigation (e.g. can activate a button and move away from it) + ImVec2 ActiveIdClickOffset; // Clicked offset from upper-left corner, if applicable (currently only set by ButtonBehavior) + ImGuiWindow* ActiveIdWindow; + ImGuiInputSource ActiveIdSource; // Activating with mouse or nav (gamepad/keyboard) + ImGuiWindow* MovingWindow; // Track the window we clicked on (in order to preserve focus). The actually window that is moved is generally MovingWindow->RootWindow. + ImVector ColorModifiers; // Stack for PushStyleColor()/PopStyleColor() + ImVector StyleModifiers; // Stack for PushStyleVar()/PopStyleVar() + ImVector FontStack; // Stack for PushFont()/PopFont() + ImVector OpenPopupStack; // Which popups are open (persistent) + ImVector CurrentPopupStack; // Which level of BeginPopup() we are in (reset every frame) + ImGuiNextWindowData NextWindowData; // Storage for SetNextWindow** functions + bool NextTreeNodeOpenVal; // Storage for SetNextTreeNode** functions + ImGuiCond NextTreeNodeOpenCond; - // Navigation data (for gamepad/keyboard) - ImGuiWindow* NavWindow; // Focused window for navigation. Could be called 'FocusWindow' - ImGuiID NavId; // Focused item for navigation - ImGuiID NavActivateId; // ~~ (g.ActiveId == 0) && IsNavInputPressed(ImGuiNavInput_Activate) ? NavId : 0, also set when calling ActivateItem() - ImGuiID NavActivateDownId; // ~~ IsNavInputDown(ImGuiNavInput_Activate) ? NavId : 0 - ImGuiID NavActivatePressedId; // ~~ IsNavInputPressed(ImGuiNavInput_Activate) ? NavId : 0 - ImGuiID NavInputId; // ~~ IsNavInputPressed(ImGuiNavInput_Input) ? NavId : 0 - ImGuiID NavJustTabbedId; // Just tabbed to this id. - ImGuiID NavNextActivateId; // Set by ActivateItem(), queued until next frame - ImGuiID NavJustMovedToId; // Just navigated to this id (result of a successfully MoveRequest) - ImRect NavScoringRectScreen; // Rectangle used for scoring, in screen space. Based of window->DC.NavRefRectRel[], modified for directional navigation scoring. - int NavScoringCount; // Metrics for debugging - ImGuiWindow* NavWindowingTarget; // When selecting a window (holding Menu+FocusPrev/Next, or equivalent of CTRL-TAB) this window is temporarily displayed front-most. - float NavWindowingHighlightTimer; - float NavWindowingHighlightAlpha; - bool NavWindowingToggleLayer; - ImGuiInputSource NavWindowingInputSource; // Gamepad or keyboard mode - int NavLayer; // Layer we are navigating on. For now the system is hard-coded for 0=main contents and 1=menu/title bar, may expose layers later. - int NavIdTabCounter; // == NavWindow->DC.FocusIdxTabCounter at time of NavId processing - bool NavIdIsAlive; // Nav widget has been seen this frame ~~ NavRefRectRel is valid - bool NavMousePosDirty; // When set we will update mouse position if (NavFlags & ImGuiNavFlags_MoveMouse) if set (NB: this not enabled by default) - bool NavDisableHighlight; // When user starts using mouse, we hide gamepad/keyboard highlight (nb: but they are still available, which is why NavDisableHighlight isn't always != NavDisableMouseHover) - bool NavDisableMouseHover; // When user starts using gamepad/keyboard, we hide mouse hovering highlight until mouse is touched again. - bool NavAnyRequest; // ~~ NavMoveRequest || NavInitRequest - bool NavInitRequest; // Init request for appearing window to select first item - bool NavInitRequestFromMove; - ImGuiID NavInitResultId; - ImRect NavInitResultRectRel; - bool NavMoveFromClampedRefRect; // Set by manual scrolling, if we scroll to a point where NavId isn't visible we reset navigation from visible items - bool NavMoveRequest; // Move request for this frame - ImGuiNavForward NavMoveRequestForward; // None / ForwardQueued / ForwardActive (this is used to navigate sibling parent menus from a child menu) - ImGuiDir NavMoveDir, NavMoveDirLast; // Direction of the move request (left/right/up/down), direction of the previous move request - ImGuiNavMoveResult NavMoveResultLocal; // Best move request candidate within NavWindow - ImGuiNavMoveResult NavMoveResultOther; // Best move request candidate within NavWindow's flattened hierarchy (when using the NavFlattened flag) + // Navigation data (for gamepad/keyboard) + ImGuiWindow* NavWindow; // Focused window for navigation. Could be called 'FocusWindow' + ImGuiID NavId; // Focused item for navigation + ImGuiID NavActivateId; // ~~ (g.ActiveId == 0) && IsNavInputPressed(ImGuiNavInput_Activate) ? NavId : 0, also set when calling ActivateItem() + ImGuiID NavActivateDownId; // ~~ IsNavInputDown(ImGuiNavInput_Activate) ? NavId : 0 + ImGuiID NavActivatePressedId; // ~~ IsNavInputPressed(ImGuiNavInput_Activate) ? NavId : 0 + ImGuiID NavInputId; // ~~ IsNavInputPressed(ImGuiNavInput_Input) ? NavId : 0 + ImGuiID NavJustTabbedId; // Just tabbed to this id. + ImGuiID NavNextActivateId; // Set by ActivateItem(), queued until next frame + ImGuiID NavJustMovedToId; // Just navigated to this id (result of a successfully MoveRequest) + ImRect NavScoringRectScreen; // Rectangle used for scoring, in screen space. Based of window->DC.NavRefRectRel[], modified for directional navigation scoring. + int NavScoringCount; // Metrics for debugging + ImGuiWindow* NavWindowingTarget; // When selecting a window (holding Menu+FocusPrev/Next, or equivalent of CTRL-TAB) this window is temporarily displayed front-most. + float NavWindowingHighlightTimer; + float NavWindowingHighlightAlpha; + bool NavWindowingToggleLayer; + ImGuiInputSource NavWindowingInputSource; // Gamepad or keyboard mode + int NavLayer; // Layer we are navigating on. For now the system is hard-coded for 0=main contents and 1=menu/title bar, may expose layers later. + int NavIdTabCounter; // == NavWindow->DC.FocusIdxTabCounter at time of NavId processing + bool NavIdIsAlive; // Nav widget has been seen this frame ~~ NavRefRectRel is valid + bool NavMousePosDirty; // When set we will update mouse position if (NavFlags & ImGuiNavFlags_MoveMouse) if set (NB: this not enabled by default) + bool NavDisableHighlight; // When user starts using mouse, we hide gamepad/keyboard highlight (nb: but they are still available, which is why NavDisableHighlight isn't always != NavDisableMouseHover) + bool NavDisableMouseHover; // When user starts using gamepad/keyboard, we hide mouse hovering highlight until mouse is touched again. + bool NavAnyRequest; // ~~ NavMoveRequest || NavInitRequest + bool NavInitRequest; // Init request for appearing window to select first item + bool NavInitRequestFromMove; + ImGuiID NavInitResultId; + ImRect NavInitResultRectRel; + bool NavMoveFromClampedRefRect; // Set by manual scrolling, if we scroll to a point where NavId isn't visible we reset navigation from visible items + bool NavMoveRequest; // Move request for this frame + ImGuiNavForward NavMoveRequestForward; // None / ForwardQueued / ForwardActive (this is used to navigate sibling parent menus from a child menu) + ImGuiDir NavMoveDir, NavMoveDirLast; // Direction of the move request (left/right/up/down), direction of the previous move request + ImGuiNavMoveResult NavMoveResultLocal; // Best move request candidate within NavWindow + ImGuiNavMoveResult NavMoveResultOther; // Best move request candidate within NavWindow's flattened hierarchy (when using the NavFlattened flag) - // Render - ImDrawData DrawData; // Main ImDrawData instance to pass render information to the user - ImDrawDataBuilder DrawDataBuilder; - float ModalWindowDarkeningRatio; - ImDrawList OverlayDrawList; // Optional software render of mouse cursors, if io.MouseDrawCursor is set + a few debug overlays - ImGuiMouseCursor MouseCursor; + // Render + ImDrawData DrawData; // Main ImDrawData instance to pass render information to the user + ImDrawDataBuilder DrawDataBuilder; + float ModalWindowDarkeningRatio; + ImDrawList OverlayDrawList; // Optional software render of mouse cursors, if io.MouseDrawCursor is set + a few debug overlays + ImGuiMouseCursor MouseCursor; - // Drag and Drop - bool DragDropActive; - ImGuiDragDropFlags DragDropSourceFlags; - int DragDropMouseButton; - ImGuiPayload DragDropPayload; - ImRect DragDropTargetRect; - ImGuiID DragDropTargetId; - float DragDropAcceptIdCurrRectSurface; - ImGuiID DragDropAcceptIdCurr; // Target item id (set at the time of accepting the payload) - ImGuiID DragDropAcceptIdPrev; // Target item id from previous frame (we need to store this to allow for overlapping drag and drop targets) - int DragDropAcceptFrameCount; // Last time a target expressed a desire to accept the source - ImVector DragDropPayloadBufHeap; // We don't expose the ImVector<> directly - unsigned char DragDropPayloadBufLocal[8]; + // Drag and Drop + bool DragDropActive; + ImGuiDragDropFlags DragDropSourceFlags; + int DragDropMouseButton; + ImGuiPayload DragDropPayload; + ImRect DragDropTargetRect; + ImGuiID DragDropTargetId; + float DragDropAcceptIdCurrRectSurface; + ImGuiID DragDropAcceptIdCurr; // Target item id (set at the time of accepting the payload) + ImGuiID DragDropAcceptIdPrev; // Target item id from previous frame (we need to store this to allow for overlapping drag and drop targets) + int DragDropAcceptFrameCount; // Last time a target expressed a desire to accept the source + ImVector DragDropPayloadBufHeap; // We don't expose the ImVector<> directly + unsigned char DragDropPayloadBufLocal[8]; - // Widget state - ImGuiTextEditState InputTextState; - ImFont InputTextPasswordFont; - ImGuiID ScalarAsInputTextId; // Temporary text input when CTRL+clicking on a slider, etc. - ImGuiColorEditFlags ColorEditOptions; // Store user options for color edit widgets - ImVec4 ColorPickerRef; - float DragCurrentValue; // Currently dragged value, always float, not rounded by end-user precision settings - ImVec2 DragLastMouseDelta; - float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio - float DragSpeedScaleSlow; - float DragSpeedScaleFast; - ImVec2 ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage? - int TooltipOverrideCount; - ImVector PrivateClipboard; // If no custom clipboard handler is defined - ImVec2 OsImePosRequest, OsImePosSet; // Cursor position request & last passed to the OS Input Method Editor + // Widget state + ImGuiTextEditState InputTextState; + ImFont InputTextPasswordFont; + ImGuiID ScalarAsInputTextId; // Temporary text input when CTRL+clicking on a slider, etc. + ImGuiColorEditFlags ColorEditOptions; // Store user options for color edit widgets + ImVec4 ColorPickerRef; + float DragCurrentValue; // Currently dragged value, always float, not rounded by end-user precision settings + ImVec2 DragLastMouseDelta; + float DragSpeedDefaultRatio; // If speed == 0.0f, uses (max-min) * DragSpeedDefaultRatio + float DragSpeedScaleSlow; + float DragSpeedScaleFast; + ImVec2 ScrollbarClickDeltaToGrabCenter; // Distance between mouse and center of grab box, normalized in parent space. Use storage? + int TooltipOverrideCount; + ImVector PrivateClipboard; // If no custom clipboard handler is defined + ImVec2 OsImePosRequest, OsImePosSet; // Cursor position request & last passed to the OS Input Method Editor - // Settings - bool SettingsLoaded; - float SettingsDirtyTimer; // Save .ini Settings on disk when time reaches zero - ImVector SettingsWindows; // .ini settings for ImGuiWindow - ImVector SettingsHandlers; // List of .ini settings handlers + // Settings + bool SettingsLoaded; + float SettingsDirtyTimer; // Save .ini Settings on disk when time reaches zero + ImVector SettingsWindows; // .ini settings for ImGuiWindow + ImVector SettingsHandlers; // List of .ini settings handlers - // Logging - bool LogEnabled; - FILE* LogFile; // If != NULL log to stdout/ file - ImGuiTextBuffer* LogClipboard; // Else log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators. - int LogStartDepth; - int LogAutoExpandMaxDepth; + // Logging + bool LogEnabled; + FILE* LogFile; // If != NULL log to stdout/ file + ImGuiTextBuffer* LogClipboard; // Else log to clipboard. This is pointer so our GImGui static constructor doesn't call heap allocators. + int LogStartDepth; + int LogAutoExpandMaxDepth; - // Misc - float FramerateSecPerFrame[120]; // calculate estimate of framerate for user - int FramerateSecPerFrameIdx; - float FramerateSecPerFrameAccum; - int WantCaptureMouseNextFrame; // explicit capture via CaptureInputs() sets those flags - int WantCaptureKeyboardNextFrame; - int WantTextInputNextFrame; - char TempBuffer[1024*3+1]; // temporary text buffer + // Misc + float FramerateSecPerFrame[120]; // calculate estimate of framerate for user + int FramerateSecPerFrameIdx; + float FramerateSecPerFrameAccum; + int WantCaptureMouseNextFrame; // explicit capture via CaptureInputs() sets those flags + int WantCaptureKeyboardNextFrame; + int WantTextInputNextFrame; + char TempBuffer[1024 * 3 + 1]; // temporary text buffer - ImGuiContext(ImFontAtlas* shared_font_atlas) : OverlayDrawList(NULL) - { - Initialized = false; - Font = NULL; - FontSize = FontBaseSize = 0.0f; - FontAtlasOwnedByContext = shared_font_atlas ? false : true; - IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)(); + ImGuiContext(ImFontAtlas* shared_font_atlas) : OverlayDrawList(NULL) + { + Initialized = false; + Font = NULL; + FontSize = FontBaseSize = 0.0f; + FontAtlasOwnedByContext = shared_font_atlas ? false : true; + IO.Fonts = shared_font_atlas ? shared_font_atlas : IM_NEW(ImFontAtlas)(); - Time = 0.0f; - FrameCount = 0; - FrameCountEnded = FrameCountRendered = -1; - WindowsActiveCount = 0; - CurrentWindow = NULL; - HoveredWindow = NULL; - HoveredRootWindow = NULL; - HoveredId = 0; - HoveredIdAllowOverlap = false; - HoveredIdPreviousFrame = 0; - HoveredIdTimer = 0.0f; - ActiveId = 0; - ActiveIdPreviousFrame = 0; - ActiveIdTimer = 0.0f; - ActiveIdIsAlive = false; - ActiveIdIsJustActivated = false; - ActiveIdAllowOverlap = false; - ActiveIdAllowNavDirFlags = 0; - ActiveIdClickOffset = ImVec2(-1,-1); - ActiveIdWindow = NULL; - ActiveIdSource = ImGuiInputSource_None; - MovingWindow = NULL; - NextTreeNodeOpenVal = false; - NextTreeNodeOpenCond = 0; + Time = 0.0f; + FrameCount = 0; + FrameCountEnded = FrameCountRendered = -1; + WindowsActiveCount = 0; + CurrentWindow = NULL; + HoveredWindow = NULL; + HoveredRootWindow = NULL; + HoveredId = 0; + HoveredIdAllowOverlap = false; + HoveredIdPreviousFrame = 0; + HoveredIdTimer = 0.0f; + ActiveId = 0; + ActiveIdPreviousFrame = 0; + ActiveIdTimer = 0.0f; + ActiveIdIsAlive = false; + ActiveIdIsJustActivated = false; + ActiveIdAllowOverlap = false; + ActiveIdAllowNavDirFlags = 0; + ActiveIdClickOffset = ImVec2(-1, -1); + ActiveIdWindow = NULL; + ActiveIdSource = ImGuiInputSource_None; + MovingWindow = NULL; + NextTreeNodeOpenVal = false; + NextTreeNodeOpenCond = 0; - NavWindow = NULL; - NavId = NavActivateId = NavActivateDownId = NavActivatePressedId = NavInputId = 0; - NavJustTabbedId = NavJustMovedToId = NavNextActivateId = 0; - NavScoringRectScreen = ImRect(); - NavScoringCount = 0; - NavWindowingTarget = NULL; - NavWindowingHighlightTimer = NavWindowingHighlightAlpha = 0.0f; - NavWindowingToggleLayer = false; - NavWindowingInputSource = ImGuiInputSource_None; - NavLayer = 0; - NavIdTabCounter = INT_MAX; - NavIdIsAlive = false; - NavMousePosDirty = false; - NavDisableHighlight = true; - NavDisableMouseHover = false; - NavAnyRequest = false; - NavInitRequest = false; - NavInitRequestFromMove = false; - NavInitResultId = 0; - NavMoveFromClampedRefRect = false; - NavMoveRequest = false; - NavMoveRequestForward = ImGuiNavForward_None; - NavMoveDir = NavMoveDirLast = ImGuiDir_None; + NavWindow = NULL; + NavId = NavActivateId = NavActivateDownId = NavActivatePressedId = NavInputId = 0; + NavJustTabbedId = NavJustMovedToId = NavNextActivateId = 0; + NavScoringRectScreen = ImRect(); + NavScoringCount = 0; + NavWindowingTarget = NULL; + NavWindowingHighlightTimer = NavWindowingHighlightAlpha = 0.0f; + NavWindowingToggleLayer = false; + NavWindowingInputSource = ImGuiInputSource_None; + NavLayer = 0; + NavIdTabCounter = INT_MAX; + NavIdIsAlive = false; + NavMousePosDirty = false; + NavDisableHighlight = true; + NavDisableMouseHover = false; + NavAnyRequest = false; + NavInitRequest = false; + NavInitRequestFromMove = false; + NavInitResultId = 0; + NavMoveFromClampedRefRect = false; + NavMoveRequest = false; + NavMoveRequestForward = ImGuiNavForward_None; + NavMoveDir = NavMoveDirLast = ImGuiDir_None; - ModalWindowDarkeningRatio = 0.0f; - OverlayDrawList._Data = &DrawListSharedData; - OverlayDrawList._OwnerName = "##Overlay"; // Give it a name for debugging - MouseCursor = ImGuiMouseCursor_Arrow; + ModalWindowDarkeningRatio = 0.0f; + OverlayDrawList._Data = &DrawListSharedData; + OverlayDrawList._OwnerName = "##Overlay"; // Give it a name for debugging + MouseCursor = ImGuiMouseCursor_Arrow; - DragDropActive = false; - DragDropSourceFlags = 0; - DragDropMouseButton = -1; - DragDropTargetId = 0; - DragDropAcceptIdCurrRectSurface = 0.0f; - DragDropAcceptIdPrev = DragDropAcceptIdCurr = 0; - DragDropAcceptFrameCount = -1; - memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal)); + DragDropActive = false; + DragDropSourceFlags = 0; + DragDropMouseButton = -1; + DragDropTargetId = 0; + DragDropAcceptIdCurrRectSurface = 0.0f; + DragDropAcceptIdPrev = DragDropAcceptIdCurr = 0; + DragDropAcceptFrameCount = -1; + memset(DragDropPayloadBufLocal, 0, sizeof(DragDropPayloadBufLocal)); - ScalarAsInputTextId = 0; - ColorEditOptions = ImGuiColorEditFlags__OptionsDefault; - DragCurrentValue = 0.0f; - DragLastMouseDelta = ImVec2(0.0f, 0.0f); - DragSpeedDefaultRatio = 1.0f / 100.0f; - DragSpeedScaleSlow = 1.0f / 100.0f; - DragSpeedScaleFast = 10.0f; - ScrollbarClickDeltaToGrabCenter = ImVec2(0.0f, 0.0f); - TooltipOverrideCount = 0; - OsImePosRequest = OsImePosSet = ImVec2(-1.0f, -1.0f); + ScalarAsInputTextId = 0; + ColorEditOptions = ImGuiColorEditFlags__OptionsDefault; + DragCurrentValue = 0.0f; + DragLastMouseDelta = ImVec2(0.0f, 0.0f); + DragSpeedDefaultRatio = 1.0f / 100.0f; + DragSpeedScaleSlow = 1.0f / 100.0f; + DragSpeedScaleFast = 10.0f; + ScrollbarClickDeltaToGrabCenter = ImVec2(0.0f, 0.0f); + TooltipOverrideCount = 0; + OsImePosRequest = OsImePosSet = ImVec2(-1.0f, -1.0f); - SettingsLoaded = false; - SettingsDirtyTimer = 0.0f; + SettingsLoaded = false; + SettingsDirtyTimer = 0.0f; - LogEnabled = false; - LogFile = NULL; - LogClipboard = NULL; - LogStartDepth = 0; - LogAutoExpandMaxDepth = 2; + LogEnabled = false; + LogFile = NULL; + LogClipboard = NULL; + LogStartDepth = 0; + LogAutoExpandMaxDepth = 2; - memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame)); - FramerateSecPerFrameIdx = 0; - FramerateSecPerFrameAccum = 0.0f; - WantCaptureMouseNextFrame = WantCaptureKeyboardNextFrame = WantTextInputNextFrame = -1; - memset(TempBuffer, 0, sizeof(TempBuffer)); - } + memset(FramerateSecPerFrame, 0, sizeof(FramerateSecPerFrame)); + FramerateSecPerFrameIdx = 0; + FramerateSecPerFrameAccum = 0.0f; + WantCaptureMouseNextFrame = WantCaptureKeyboardNextFrame = WantTextInputNextFrame = -1; + memset(TempBuffer, 0, sizeof(TempBuffer)); + } }; // Transient per-window flags, reset at the beginning of the frame. For child window, inherited from parent on first Begin(). // This is going to be exposed in imgui.h when stabilized enough. enum ImGuiItemFlags_ { - ImGuiItemFlags_AllowKeyboardFocus = 1 << 0, // true - ImGuiItemFlags_ButtonRepeat = 1 << 1, // false // Button() will return true multiple times based on io.KeyRepeatDelay and io.KeyRepeatRate settings. - ImGuiItemFlags_Disabled = 1 << 2, // false // FIXME-WIP: Disable interactions but doesn't affect visuals. Should be: grey out and disable interactions with widgets that affect data + view widgets (WIP) - ImGuiItemFlags_NoNav = 1 << 3, // false - ImGuiItemFlags_NoNavDefaultFocus = 1 << 4, // false - ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // MenuItem/Selectable() automatically closes current Popup window - ImGuiItemFlags_Default_ = ImGuiItemFlags_AllowKeyboardFocus + ImGuiItemFlags_AllowKeyboardFocus = 1 << 0, // true + ImGuiItemFlags_ButtonRepeat = 1 << 1, // false // Button() will return true multiple times based on io.KeyRepeatDelay and io.KeyRepeatRate settings. + ImGuiItemFlags_Disabled = 1 << 2, // false // FIXME-WIP: Disable interactions but doesn't affect visuals. Should be: grey out and disable interactions with widgets that affect data + view widgets (WIP) + ImGuiItemFlags_NoNav = 1 << 3, // false + ImGuiItemFlags_NoNavDefaultFocus = 1 << 4, // false + ImGuiItemFlags_SelectableDontClosePopup = 1 << 5, // false // MenuItem/Selectable() automatically closes current Popup window + ImGuiItemFlags_Default_ = ImGuiItemFlags_AllowKeyboardFocus }; // Transient per-window data, reset at the beginning of the frame // FIXME: That's theory, in practice the delimitation between ImGuiWindow and ImGuiDrawContext is quite tenuous and could be reconsidered. struct IMGUI_API ImGuiDrawContext { - ImVec2 CursorPos; - ImVec2 CursorPosPrevLine; - ImVec2 CursorStartPos; - ImVec2 CursorMaxPos; // Used to implicitly calculate the size of our contents, always growing during the frame. Turned into window->SizeContents at the beginning of next frame - float CurrentLineHeight; - float CurrentLineTextBaseOffset; - float PrevLineHeight; - float PrevLineTextBaseOffset; - float LogLinePosY; - int TreeDepth; - ImU32 TreeDepthMayCloseOnPop; // Store a copy of !g.NavIdIsAlive for TreeDepth 0..31 - ImGuiID LastItemId; - ImGuiItemStatusFlags LastItemStatusFlags; - ImRect LastItemRect; // Interaction rect - ImRect LastItemDisplayRect; // End-user display rect (only valid if LastItemStatusFlags & ImGuiItemStatusFlags_HasDisplayRect) - bool NavHideHighlightOneFrame; - bool NavHasScroll; // Set when scrolling can be used (ScrollMax > 0.0f) - int NavLayerCurrent; // Current layer, 0..31 (we currently only use 0..1) - int NavLayerCurrentMask; // = (1 << NavLayerCurrent) used by ItemAdd prior to clipping. - int NavLayerActiveMask; // Which layer have been written to (result from previous frame) - int NavLayerActiveMaskNext; // Which layer have been written to (buffer for current frame) - bool MenuBarAppending; // FIXME: Remove this - float MenuBarOffsetX; - ImVector ChildWindows; - ImGuiStorage* StateStorage; - ImGuiLayoutType LayoutType; - ImGuiLayoutType ParentLayoutType; // Layout type of parent window at the time of Begin() + ImVec2 CursorPos; + ImVec2 CursorPosPrevLine; + ImVec2 CursorStartPos; + ImVec2 CursorMaxPos; // Used to implicitly calculate the size of our contents, always growing during the frame. Turned into window->SizeContents at the beginning of next frame + float CurrentLineHeight; + float CurrentLineTextBaseOffset; + float PrevLineHeight; + float PrevLineTextBaseOffset; + float LogLinePosY; + int TreeDepth; + ImU32 TreeDepthMayCloseOnPop; // Store a copy of !g.NavIdIsAlive for TreeDepth 0..31 + ImGuiID LastItemId; + ImGuiItemStatusFlags LastItemStatusFlags; + ImRect LastItemRect; // Interaction rect + ImRect LastItemDisplayRect; // End-user display rect (only valid if LastItemStatusFlags & ImGuiItemStatusFlags_HasDisplayRect) + bool NavHideHighlightOneFrame; + bool NavHasScroll; // Set when scrolling can be used (ScrollMax > 0.0f) + int NavLayerCurrent; // Current layer, 0..31 (we currently only use 0..1) + int NavLayerCurrentMask; // = (1 << NavLayerCurrent) used by ItemAdd prior to clipping. + int NavLayerActiveMask; // Which layer have been written to (result from previous frame) + int NavLayerActiveMaskNext; // Which layer have been written to (buffer for current frame) + bool MenuBarAppending; // FIXME: Remove this + float MenuBarOffsetX; + ImVector ChildWindows; + ImGuiStorage* StateStorage; + ImGuiLayoutType LayoutType; + ImGuiLayoutType ParentLayoutType; // Layout type of parent window at the time of Begin() - // We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings. - ImGuiItemFlags ItemFlags; // == ItemFlagsStack.back() [empty == ImGuiItemFlags_Default] - float ItemWidth; // == ItemWidthStack.back(). 0.0: default, >0.0: width in pixels, <0.0: align xx pixels to the right of window - float TextWrapPos; // == TextWrapPosStack.back() [empty == -1.0f] - ImVectorItemFlagsStack; - ImVector ItemWidthStack; - ImVector TextWrapPosStack; - ImVectorGroupStack; - int StackSizesBackup[6]; // Store size of various stacks for asserting + // We store the current settings outside of the vectors to increase memory locality (reduce cache misses). The vectors are rarely modified. Also it allows us to not heap allocate for short-lived windows which are not using those settings. + ImGuiItemFlags ItemFlags; // == ItemFlagsStack.back() [empty == ImGuiItemFlags_Default] + float ItemWidth; // == ItemWidthStack.back(). 0.0: default, >0.0: width in pixels, <0.0: align xx pixels to the right of window + float TextWrapPos; // == TextWrapPosStack.back() [empty == -1.0f] + ImVector ItemFlagsStack; + ImVector ItemWidthStack; + ImVector TextWrapPosStack; + ImVector GroupStack; + int StackSizesBackup[6]; // Store size of various stacks for asserting - float IndentX; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.) - float GroupOffsetX; - float ColumnsOffsetX; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API. - ImGuiColumnsSet* ColumnsSet; // Current columns set + float IndentX; // Indentation / start position from left of window (increased by TreePush/TreePop, etc.) + float GroupOffsetX; + float ColumnsOffsetX; // Offset to the current column (if ColumnsCurrent > 0). FIXME: This and the above should be a stack to allow use cases like Tree->Column->Tree. Need revamp columns API. + ImGuiColumnsSet* ColumnsSet; // Current columns set - ImGuiDrawContext() - { - CursorPos = CursorPosPrevLine = CursorStartPos = CursorMaxPos = ImVec2(0.0f, 0.0f); - CurrentLineHeight = PrevLineHeight = 0.0f; - CurrentLineTextBaseOffset = PrevLineTextBaseOffset = 0.0f; - LogLinePosY = -1.0f; - TreeDepth = 0; - TreeDepthMayCloseOnPop = 0x00; - LastItemId = 0; - LastItemStatusFlags = 0; - LastItemRect = LastItemDisplayRect = ImRect(); - NavHideHighlightOneFrame = false; - NavHasScroll = false; - NavLayerActiveMask = NavLayerActiveMaskNext = 0x00; - NavLayerCurrent = 0; - NavLayerCurrentMask = 1 << 0; - MenuBarAppending = false; - MenuBarOffsetX = 0.0f; - StateStorage = NULL; - LayoutType = ParentLayoutType = ImGuiLayoutType_Vertical; - ItemWidth = 0.0f; - ItemFlags = ImGuiItemFlags_Default_; - TextWrapPos = -1.0f; - memset(StackSizesBackup, 0, sizeof(StackSizesBackup)); + ImGuiDrawContext() + { + CursorPos = CursorPosPrevLine = CursorStartPos = CursorMaxPos = ImVec2(0.0f, 0.0f); + CurrentLineHeight = PrevLineHeight = 0.0f; + CurrentLineTextBaseOffset = PrevLineTextBaseOffset = 0.0f; + LogLinePosY = -1.0f; + TreeDepth = 0; + TreeDepthMayCloseOnPop = 0x00; + LastItemId = 0; + LastItemStatusFlags = 0; + LastItemRect = LastItemDisplayRect = ImRect(); + NavHideHighlightOneFrame = false; + NavHasScroll = false; + NavLayerActiveMask = NavLayerActiveMaskNext = 0x00; + NavLayerCurrent = 0; + NavLayerCurrentMask = 1 << 0; + MenuBarAppending = false; + MenuBarOffsetX = 0.0f; + StateStorage = NULL; + LayoutType = ParentLayoutType = ImGuiLayoutType_Vertical; + ItemWidth = 0.0f; + ItemFlags = ImGuiItemFlags_Default_; + TextWrapPos = -1.0f; + memset(StackSizesBackup, 0, sizeof(StackSizesBackup)); - IndentX = 0.0f; - GroupOffsetX = 0.0f; - ColumnsOffsetX = 0.0f; - ColumnsSet = NULL; - } + IndentX = 0.0f; + GroupOffsetX = 0.0f; + ColumnsOffsetX = 0.0f; + ColumnsSet = NULL; + } }; // Windows data struct IMGUI_API ImGuiWindow { - char* Name; - ImGuiID ID; // == ImHash(Name) - ImGuiWindowFlags Flags; // See enum ImGuiWindowFlags_ - ImVec2 PosFloat; - ImVec2 Pos; // Position rounded-up to nearest pixel - ImVec2 Size; // Current size (==SizeFull or collapsed title bar size) - ImVec2 SizeFull; // Size when non collapsed - ImVec2 SizeFullAtLastBegin; // Copy of SizeFull at the end of Begin. This is the reference value we'll use on the next frame to decide if we need scrollbars. - ImVec2 SizeContents; // Size of contents (== extents reach of the drawing cursor) from previous frame. Include decoration, window title, border, menu, etc. - ImVec2 SizeContentsExplicit; // Size of contents explicitly set by the user via SetNextWindowContentSize() - ImRect ContentsRegionRect; // Maximum visible content position in window coordinates. ~~ (SizeContentsExplicit ? SizeContentsExplicit : Size - ScrollbarSizes) - CursorStartPos, per axis - ImVec2 WindowPadding; // Window padding at the time of begin. - float WindowRounding; // Window rounding at the time of begin. - float WindowBorderSize; // Window border size at the time of begin. - ImGuiID MoveId; // == window->GetID("#MOVE") - ImGuiID ChildId; // Id of corresponding item in parent window (for child windows) - ImVec2 Scroll; - ImVec2 ScrollTarget; // target scroll position. stored as cursor position with scrolling canceled out, so the highest point is always 0.0f. (FLT_MAX for no change) - ImVec2 ScrollTargetCenterRatio; // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered - bool ScrollbarX, ScrollbarY; - ImVec2 ScrollbarSizes; - bool Active; // Set to true on Begin(), unless Collapsed - bool WasActive; - bool WriteAccessed; // Set to true when any widget access the current window - bool Collapsed; // Set when collapsing window to become only title-bar - bool CollapseToggleWanted; - bool SkipItems; // Set when items can safely be all clipped (e.g. window not visible or collapsed) - bool Appearing; // Set during the frame where the window is appearing (or re-appearing) - bool CloseButton; // Set when the window has a close button (p_open != NULL) - int BeginOrderWithinParent; // Order within immediate parent window, if we are a child window. Otherwise 0. - int BeginOrderWithinContext; // Order within entire imgui context. This is mostly used for debugging submission order related issues. - int BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs) - ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling) - int AutoFitFramesX, AutoFitFramesY; - bool AutoFitOnlyGrows; - int AutoFitChildAxises; - ImGuiDir AutoPosLastDirection; - int HiddenFrames; - ImGuiCond SetWindowPosAllowFlags; // store condition flags for next SetWindowPos() call. - ImGuiCond SetWindowSizeAllowFlags; // store condition flags for next SetWindowSize() call. - ImGuiCond SetWindowCollapsedAllowFlags; // store condition flags for next SetWindowCollapsed() call. - ImVec2 SetWindowPosVal; // store window position when using a non-zero Pivot (position set needs to be processed when we know the window size) - ImVec2 SetWindowPosPivot; // store window pivot for positioning. ImVec2(0,0) when positioning from top-left corner; ImVec2(0.5f,0.5f) for centering; ImVec2(1,1) for bottom right. + char* Name; + ImGuiID ID; // == ImHash(Name) + ImGuiWindowFlags Flags; // See enum ImGuiWindowFlags_ + ImVec2 PosFloat; + ImVec2 Pos; // Position rounded-up to nearest pixel + ImVec2 Size; // Current size (==SizeFull or collapsed title bar size) + ImVec2 SizeFull; // Size when non collapsed + ImVec2 SizeFullAtLastBegin; // Copy of SizeFull at the end of Begin. This is the reference value we'll use on the next frame to decide if we need scrollbars. + ImVec2 SizeContents; // Size of contents (== extents reach of the drawing cursor) from previous frame. Include decoration, window title, border, menu, etc. + ImVec2 SizeContentsExplicit; // Size of contents explicitly set by the user via SetNextWindowContentSize() + ImRect ContentsRegionRect; // Maximum visible content position in window coordinates. ~~ (SizeContentsExplicit ? SizeContentsExplicit : Size - ScrollbarSizes) - CursorStartPos, per axis + ImVec2 WindowPadding; // Window padding at the time of begin. + float WindowRounding; // Window rounding at the time of begin. + float WindowBorderSize; // Window border size at the time of begin. + ImGuiID MoveId; // == window->GetID("#MOVE") + ImGuiID ChildId; // Id of corresponding item in parent window (for child windows) + ImVec2 Scroll; + ImVec2 ScrollTarget; // target scroll position. stored as cursor position with scrolling canceled out, so the highest point is always 0.0f. (FLT_MAX for no change) + ImVec2 ScrollTargetCenterRatio; // 0.0f = scroll so that target position is at top, 0.5f = scroll so that target position is centered + bool ScrollbarX, ScrollbarY; + ImVec2 ScrollbarSizes; + bool Active; // Set to true on Begin(), unless Collapsed + bool WasActive; + bool WriteAccessed; // Set to true when any widget access the current window + bool Collapsed; // Set when collapsing window to become only title-bar + bool CollapseToggleWanted; + bool SkipItems; // Set when items can safely be all clipped (e.g. window not visible or collapsed) + bool Appearing; // Set during the frame where the window is appearing (or re-appearing) + bool CloseButton; // Set when the window has a close button (p_open != NULL) + int BeginOrderWithinParent; // Order within immediate parent window, if we are a child window. Otherwise 0. + int BeginOrderWithinContext; // Order within entire imgui context. This is mostly used for debugging submission order related issues. + int BeginCount; // Number of Begin() during the current frame (generally 0 or 1, 1+ if appending via multiple Begin/End pairs) + ImGuiID PopupId; // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling) + int AutoFitFramesX, AutoFitFramesY; + bool AutoFitOnlyGrows; + int AutoFitChildAxises; + ImGuiDir AutoPosLastDirection; + int HiddenFrames; + ImGuiCond SetWindowPosAllowFlags; // store condition flags for next SetWindowPos() call. + ImGuiCond SetWindowSizeAllowFlags; // store condition flags for next SetWindowSize() call. + ImGuiCond SetWindowCollapsedAllowFlags; // store condition flags for next SetWindowCollapsed() call. + ImVec2 SetWindowPosVal; // store window position when using a non-zero Pivot (position set needs to be processed when we know the window size) + ImVec2 SetWindowPosPivot; // store window pivot for positioning. ImVec2(0,0) when positioning from top-left corner; ImVec2(0.5f,0.5f) for centering; ImVec2(1,1) for bottom right. - ImGuiDrawContext DC; // Temporary per-window data, reset at the beginning of the frame - ImVector IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack - ImRect ClipRect; // = DrawList->clip_rect_stack.back(). Scissoring / clipping rectangle. x1, y1, x2, y2. - ImRect WindowRectClipped; // = WindowRect just after setup in Begin(). == window->Rect() for root window. - ImRect InnerRect; - int LastFrameActive; - float ItemWidthDefault; - ImGuiMenuColumns MenuColumns; // Simplified columns storage for menu items - ImGuiStorage StateStorage; - ImVector ColumnsStorage; - float FontWindowScale; // Scale multiplier per-window - ImDrawList* DrawList; - ImGuiWindow* ParentWindow; // If we are a child _or_ popup window, this is pointing to our parent. Otherwise NULL. - ImGuiWindow* RootWindow; // Point to ourself or first ancestor that is not a child window. - ImGuiWindow* RootWindowForTitleBarHighlight; // Point to ourself or first ancestor which will display TitleBgActive color when this window is active. - ImGuiWindow* RootWindowForTabbing; // Point to ourself or first ancestor which can be CTRL-Tabbed into. - ImGuiWindow* RootWindowForNav; // Point to ourself or first ancestor which doesn't have the NavFlattened flag. + ImGuiDrawContext DC; // Temporary per-window data, reset at the beginning of the frame + ImVector IDStack; // ID stack. ID are hashes seeded with the value at the top of the stack + ImRect ClipRect; // = DrawList->clip_rect_stack.back(). Scissoring / clipping rectangle. x1, y1, x2, y2. + ImRect WindowRectClipped; // = WindowRect just after setup in Begin(). == window->Rect() for root window. + ImRect InnerRect; + int LastFrameActive; + float ItemWidthDefault; + ImGuiMenuColumns MenuColumns; // Simplified columns storage for menu items + ImGuiStorage StateStorage; + ImVector ColumnsStorage; + float FontWindowScale; // Scale multiplier per-window + ImDrawList* DrawList; + ImGuiWindow* ParentWindow; // If we are a child _or_ popup window, this is pointing to our parent. Otherwise NULL. + ImGuiWindow* RootWindow; // Point to ourself or first ancestor that is not a child window. + ImGuiWindow* RootWindowForTitleBarHighlight; // Point to ourself or first ancestor which will display TitleBgActive color when this window is active. + ImGuiWindow* RootWindowForTabbing; // Point to ourself or first ancestor which can be CTRL-Tabbed into. + ImGuiWindow* RootWindowForNav; // Point to ourself or first ancestor which doesn't have the NavFlattened flag. - ImGuiWindow* NavLastChildNavWindow; // When going to the menu bar, we remember the child window we came from. (This could probably be made implicit if we kept g.Windows sorted by last focused including child window.) - ImGuiID NavLastIds[2]; // Last known NavId for this window, per layer (0/1) - ImRect NavRectRel[2]; // Reference rectangle, in window relative space + ImGuiWindow* NavLastChildNavWindow; // When going to the menu bar, we remember the child window we came from. (This could probably be made implicit if we kept g.Windows sorted by last focused including child window.) + ImGuiID NavLastIds[2]; // Last known NavId for this window, per layer (0/1) + ImRect NavRectRel[2]; // Reference rectangle, in window relative space - // Navigation / Focus - // FIXME-NAV: Merge all this with the new Nav system, at least the request variables should be moved to ImGuiContext - int FocusIdxAllCounter; // Start at -1 and increase as assigned via FocusItemRegister() - int FocusIdxTabCounter; // (same, but only count widgets which you can Tab through) - int FocusIdxAllRequestCurrent; // Item being requested for focus - int FocusIdxTabRequestCurrent; // Tab-able item being requested for focus - int FocusIdxAllRequestNext; // Item being requested for focus, for next update (relies on layout to be stable between the frame pressing TAB and the next frame) - int FocusIdxTabRequestNext; // " + // Navigation / Focus + // FIXME-NAV: Merge all this with the new Nav system, at least the request variables should be moved to ImGuiContext + int FocusIdxAllCounter; // Start at -1 and increase as assigned via FocusItemRegister() + int FocusIdxTabCounter; // (same, but only count widgets which you can Tab through) + int FocusIdxAllRequestCurrent; // Item being requested for focus + int FocusIdxTabRequestCurrent; // Tab-able item being requested for focus + int FocusIdxAllRequestNext; // Item being requested for focus, for next update (relies on layout to be stable between the frame pressing TAB and the next frame) + int FocusIdxTabRequestNext; // " public: - ImGuiWindow(ImGuiContext* context, const char* name); - ~ImGuiWindow(); + ImGuiWindow(ImGuiContext* context, const char* name); + ~ImGuiWindow(); - ImGuiID GetID(const char* str, const char* str_end = NULL); - ImGuiID GetID(const void* ptr); - ImGuiID GetIDNoKeepAlive(const char* str, const char* str_end = NULL); - ImGuiID GetIDFromRectangle(const ImRect& r_abs); + ImGuiID GetID(const char* str, const char* str_end = NULL); + ImGuiID GetID(const void* ptr); + ImGuiID GetIDNoKeepAlive(const char* str, const char* str_end = NULL); + ImGuiID GetIDFromRectangle(const ImRect& r_abs); - // We don't use g.FontSize because the window may be != g.CurrentWidow. - ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x+Size.x, Pos.y+Size.y); } - float CalcFontSize() const { return GImGui->FontBaseSize * FontWindowScale; } - float TitleBarHeight() const { return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f; } - ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight())); } - float MenuBarHeight() const { return (Flags & ImGuiWindowFlags_MenuBar) ? CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f : 0.0f; } - ImRect MenuBarRect() const { float y1 = Pos.y + TitleBarHeight(); return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight()); } + // We don't use g.FontSize because the window may be != g.CurrentWidow. + ImRect Rect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); } + float CalcFontSize() const { return GImGui->FontBaseSize * FontWindowScale; } + float TitleBarHeight() const { return (Flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f; } + ImRect TitleBarRect() const { return ImRect(Pos, ImVec2(Pos.x + SizeFull.x, Pos.y + TitleBarHeight())); } + float MenuBarHeight() const { return (Flags & ImGuiWindowFlags_MenuBar) ? CalcFontSize() + GImGui->Style.FramePadding.y * 2.0f : 0.0f; } + ImRect MenuBarRect() const + { + float y1 = Pos.y + TitleBarHeight(); + return ImRect(Pos.x, y1, Pos.x + SizeFull.x, y1 + MenuBarHeight()); + } }; -// Backup and restore just enough data to be able to use IsItemHovered() on item A after another B in the same window has overwritten the data. +// Backup and restore just enough data to be able to use IsItemHovered() on item A after another B in the same window has overwritten the data. struct ImGuiItemHoveredDataBackup { - ImGuiID LastItemId; - ImGuiItemStatusFlags LastItemStatusFlags; - ImRect LastItemRect; - ImRect LastItemDisplayRect; + ImGuiID LastItemId; + ImGuiItemStatusFlags LastItemStatusFlags; + ImRect LastItemRect; + ImRect LastItemDisplayRect; - ImGuiItemHoveredDataBackup() { Backup(); } - void Backup() { ImGuiWindow* window = GImGui->CurrentWindow; LastItemId = window->DC.LastItemId; LastItemStatusFlags = window->DC.LastItemStatusFlags; LastItemRect = window->DC.LastItemRect; LastItemDisplayRect = window->DC.LastItemDisplayRect; } - void Restore() const { ImGuiWindow* window = GImGui->CurrentWindow; window->DC.LastItemId = LastItemId; window->DC.LastItemStatusFlags = LastItemStatusFlags; window->DC.LastItemRect = LastItemRect; window->DC.LastItemDisplayRect = LastItemDisplayRect; } + ImGuiItemHoveredDataBackup() { Backup(); } + void Backup() + { + ImGuiWindow* window = GImGui->CurrentWindow; + LastItemId = window->DC.LastItemId; + LastItemStatusFlags = window->DC.LastItemStatusFlags; + LastItemRect = window->DC.LastItemRect; + LastItemDisplayRect = window->DC.LastItemDisplayRect; + } + void Restore() const + { + ImGuiWindow* window = GImGui->CurrentWindow; + window->DC.LastItemId = LastItemId; + window->DC.LastItemStatusFlags = LastItemStatusFlags; + window->DC.LastItemRect = LastItemRect; + window->DC.LastItemDisplayRect = LastItemDisplayRect; + } }; //----------------------------------------------------------------------------- @@ -1015,143 +1195,152 @@ struct ImGuiItemHoveredDataBackup namespace ImGui { - // We should always have a CurrentWindow in the stack (there is an implicit "Debug" window) - // If this ever crash because g.CurrentWindow is NULL it means that either - // - ImGui::NewFrame() has never been called, which is illegal. - // - You are calling ImGui functions after ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal. - inline ImGuiWindow* GetCurrentWindowRead() { ImGuiContext& g = *GImGui; return g.CurrentWindow; } - inline ImGuiWindow* GetCurrentWindow() { ImGuiContext& g = *GImGui; g.CurrentWindow->WriteAccessed = true; return g.CurrentWindow; } - IMGUI_API ImGuiWindow* FindWindowByName(const char* name); - IMGUI_API void FocusWindow(ImGuiWindow* window); - IMGUI_API void BringWindowToFront(ImGuiWindow* window); - IMGUI_API void BringWindowToBack(ImGuiWindow* window); - IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent); - IMGUI_API bool IsWindowNavFocusable(ImGuiWindow* window); +// We should always have a CurrentWindow in the stack (there is an implicit "Debug" window) +// If this ever crash because g.CurrentWindow is NULL it means that either +// - ImGui::NewFrame() has never been called, which is illegal. +// - You are calling ImGui functions after ImGui::Render() and before the next ImGui::NewFrame(), which is also illegal. +inline ImGuiWindow* GetCurrentWindowRead() +{ + ImGuiContext& g = *GImGui; + return g.CurrentWindow; +} +inline ImGuiWindow* GetCurrentWindow() +{ + ImGuiContext& g = *GImGui; + g.CurrentWindow->WriteAccessed = true; + return g.CurrentWindow; +} +IMGUI_API ImGuiWindow* FindWindowByName(const char* name); +IMGUI_API void FocusWindow(ImGuiWindow* window); +IMGUI_API void BringWindowToFront(ImGuiWindow* window); +IMGUI_API void BringWindowToBack(ImGuiWindow* window); +IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent); +IMGUI_API bool IsWindowNavFocusable(ImGuiWindow* window); - IMGUI_API void Initialize(ImGuiContext* context); - IMGUI_API void Shutdown(ImGuiContext* context); // Since 1.60 this is a _private_ function. You can call DestroyContext() to destroy the context created by CreateContext(). +IMGUI_API void Initialize(ImGuiContext* context); +IMGUI_API void Shutdown(ImGuiContext* context); // Since 1.60 this is a _private_ function. You can call DestroyContext() to destroy the context created by CreateContext(). - IMGUI_API void MarkIniSettingsDirty(); - IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name); - IMGUI_API ImGuiWindowSettings* FindWindowSettings(ImGuiID id); +IMGUI_API void MarkIniSettingsDirty(); +IMGUI_API ImGuiSettingsHandler* FindSettingsHandler(const char* type_name); +IMGUI_API ImGuiWindowSettings* FindWindowSettings(ImGuiID id); - IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window); - IMGUI_API ImGuiID GetActiveID(); - IMGUI_API void SetFocusID(ImGuiID id, ImGuiWindow* window); - IMGUI_API void ClearActiveID(); - IMGUI_API void SetHoveredID(ImGuiID id); - IMGUI_API ImGuiID GetHoveredID(); - IMGUI_API void KeepAliveID(ImGuiID id); +IMGUI_API void SetActiveID(ImGuiID id, ImGuiWindow* window); +IMGUI_API ImGuiID GetActiveID(); +IMGUI_API void SetFocusID(ImGuiID id, ImGuiWindow* window); +IMGUI_API void ClearActiveID(); +IMGUI_API void SetHoveredID(ImGuiID id); +IMGUI_API ImGuiID GetHoveredID(); +IMGUI_API void KeepAliveID(ImGuiID id); - IMGUI_API void ItemSize(const ImVec2& size, float text_offset_y = 0.0f); - IMGUI_API void ItemSize(const ImRect& bb, float text_offset_y = 0.0f); - IMGUI_API bool ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb = NULL); - IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id); - IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged); - IMGUI_API bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id, bool tab_stop = true); // Return true if focus is requested - IMGUI_API void FocusableItemUnregister(ImGuiWindow* window); - IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_x, float default_y); - IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x); - IMGUI_API void PushMultiItemsWidths(int components, float width_full = 0.0f); - IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); - IMGUI_API void PopItemFlag(); +IMGUI_API void ItemSize(const ImVec2& size, float text_offset_y = 0.0f); +IMGUI_API void ItemSize(const ImRect& bb, float text_offset_y = 0.0f); +IMGUI_API bool ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb = NULL); +IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id); +IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id, bool clip_even_when_logged); +IMGUI_API bool FocusableItemRegister(ImGuiWindow* window, ImGuiID id, bool tab_stop = true); // Return true if focus is requested +IMGUI_API void FocusableItemUnregister(ImGuiWindow* window); +IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_x, float default_y); +IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x); +IMGUI_API void PushMultiItemsWidths(int components, float width_full = 0.0f); +IMGUI_API void PushItemFlag(ImGuiItemFlags option, bool enabled); +IMGUI_API void PopItemFlag(); - IMGUI_API void SetCurrentFont(ImFont* font); +IMGUI_API void SetCurrentFont(ImFont* font); - IMGUI_API void OpenPopupEx(ImGuiID id); - IMGUI_API void ClosePopup(ImGuiID id); - IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window); - IMGUI_API bool IsPopupOpen(ImGuiID id); - IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); - IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_tooltip = true); +IMGUI_API void OpenPopupEx(ImGuiID id); +IMGUI_API void ClosePopup(ImGuiID id); +IMGUI_API void ClosePopupsOverWindow(ImGuiWindow* ref_window); +IMGUI_API bool IsPopupOpen(ImGuiID id); +IMGUI_API bool BeginPopupEx(ImGuiID id, ImGuiWindowFlags extra_flags); +IMGUI_API void BeginTooltipEx(ImGuiWindowFlags extra_flags, bool override_previous_tooltip = true); - IMGUI_API void NavInitWindow(ImGuiWindow* window, bool force_reinit); - IMGUI_API void NavMoveRequestCancel(); - IMGUI_API void ActivateItem(ImGuiID id); // Remotely activate a button, checkbox, tree node etc. given its unique ID. activation is queued and processed on the next frame when the item is encountered again. +IMGUI_API void NavInitWindow(ImGuiWindow* window, bool force_reinit); +IMGUI_API void NavMoveRequestCancel(); +IMGUI_API void ActivateItem(ImGuiID id); // Remotely activate a button, checkbox, tree node etc. given its unique ID. activation is queued and processed on the next frame when the item is encountered again. - IMGUI_API float GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode); - IMGUI_API ImVec2 GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor = 0.0f, float fast_factor = 0.0f); - IMGUI_API int CalcTypematicPressedRepeatAmount(float t, float t_prev, float repeat_delay, float repeat_rate); +IMGUI_API float GetNavInputAmount(ImGuiNavInput n, ImGuiInputReadMode mode); +IMGUI_API ImVec2 GetNavInputAmount2d(ImGuiNavDirSourceFlags dir_sources, ImGuiInputReadMode mode, float slow_factor = 0.0f, float fast_factor = 0.0f); +IMGUI_API int CalcTypematicPressedRepeatAmount(float t, float t_prev, float repeat_delay, float repeat_rate); - IMGUI_API void Scrollbar(ImGuiLayoutType direction); - IMGUI_API void VerticalSeparator(); // Vertical separator, for menu bars (use current line height). not exposed because it is misleading what it doesn't have an effect on regular layout. - IMGUI_API bool SplitterBehavior(ImGuiID id, const ImRect& bb, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend = 0.0f); +IMGUI_API void Scrollbar(ImGuiLayoutType direction); +IMGUI_API void VerticalSeparator(); // Vertical separator, for menu bars (use current line height). not exposed because it is misleading what it doesn't have an effect on regular layout. +IMGUI_API bool SplitterBehavior(ImGuiID id, const ImRect& bb, ImGuiAxis axis, float* size1, float* size2, float min_size1, float min_size2, float hover_extend = 0.0f); - IMGUI_API bool BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id); - IMGUI_API void ClearDragDrop(); - IMGUI_API bool IsDragDropPayloadBeingAccepted(); +IMGUI_API bool BeginDragDropTargetCustom(const ImRect& bb, ImGuiID id); +IMGUI_API void ClearDragDrop(); +IMGUI_API bool IsDragDropPayloadBeingAccepted(); - // FIXME-WIP: New Columns API - IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). - IMGUI_API void EndColumns(); // close columns - IMGUI_API void PushColumnClipRect(int column_index = -1); +// FIXME-WIP: New Columns API +IMGUI_API void BeginColumns(const char* str_id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). +IMGUI_API void EndColumns(); // close columns +IMGUI_API void PushColumnClipRect(int column_index = -1); - // NB: All position are in absolute pixels coordinates (never using window coordinates internally) - // AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. THOSE FUNCTIONS ARE A MESS. THEIR SIGNATURE AND BEHAVIOR WILL CHANGE, THEY NEED TO BE REFACTORED INTO SOMETHING DECENT. - IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); - IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width); - IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0,0), const ImRect* clip_rect = NULL); - IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); - IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f); - IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, int rounding_corners_flags = ~0); - IMGUI_API void RenderTriangle(ImVec2 pos, ImGuiDir dir, float scale = 1.0f); - IMGUI_API void RenderBullet(ImVec2 pos); - IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col, float sz); - IMGUI_API void RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags = ImGuiNavHighlightFlags_TypeDefault); // Navigation highlight - IMGUI_API void RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding); - IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text. +// NB: All position are in absolute pixels coordinates (never using window coordinates internally) +// AVOID USING OUTSIDE OF IMGUI.CPP! NOT FOR PUBLIC CONSUMPTION. THOSE FUNCTIONS ARE A MESS. THEIR SIGNATURE AND BEHAVIOR WILL CHANGE, THEY NEED TO BE REFACTORED INTO SOMETHING DECENT. +IMGUI_API void RenderText(ImVec2 pos, const char* text, const char* text_end = NULL, bool hide_text_after_hash = true); +IMGUI_API void RenderTextWrapped(ImVec2 pos, const char* text, const char* text_end, float wrap_width); +IMGUI_API void RenderTextClipped(const ImVec2& pos_min, const ImVec2& pos_max, const char* text, const char* text_end, const ImVec2* text_size_if_known, const ImVec2& align = ImVec2(0, 0), const ImRect* clip_rect = NULL); +IMGUI_API void RenderFrame(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, bool border = true, float rounding = 0.0f); +IMGUI_API void RenderFrameBorder(ImVec2 p_min, ImVec2 p_max, float rounding = 0.0f); +IMGUI_API void RenderColorRectWithAlphaCheckerboard(ImVec2 p_min, ImVec2 p_max, ImU32 fill_col, float grid_step, ImVec2 grid_off, float rounding = 0.0f, int rounding_corners_flags = ~0); +IMGUI_API void RenderTriangle(ImVec2 pos, ImGuiDir dir, float scale = 1.0f); +IMGUI_API void RenderBullet(ImVec2 pos); +IMGUI_API void RenderCheckMark(ImVec2 pos, ImU32 col, float sz); +IMGUI_API void RenderNavHighlight(const ImRect& bb, ImGuiID id, ImGuiNavHighlightFlags flags = ImGuiNavHighlightFlags_TypeDefault); // Navigation highlight +IMGUI_API void RenderRectFilledRangeH(ImDrawList* draw_list, const ImRect& rect, ImU32 col, float x_start_norm, float x_end_norm, float rounding); +IMGUI_API const char* FindRenderedTextEnd(const char* text, const char* text_end = NULL); // Find the optional ## from which we stop displaying text. - IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0); - IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0,0), ImGuiButtonFlags flags = 0); - IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos, float radius); - IMGUI_API bool ArrowButton(ImGuiID id, ImGuiDir dir, ImVec2 padding, ImGuiButtonFlags flags = 0); +IMGUI_API bool ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool* out_held, ImGuiButtonFlags flags = 0); +IMGUI_API bool ButtonEx(const char* label, const ImVec2& size_arg = ImVec2(0, 0), ImGuiButtonFlags flags = 0); +IMGUI_API bool CloseButton(ImGuiID id, const ImVec2& pos, float radius); +IMGUI_API bool ArrowButton(ImGuiID id, ImGuiDir dir, ImVec2 padding, ImGuiButtonFlags flags = 0); - IMGUI_API bool SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, ImGuiSliderFlags flags = 0); - IMGUI_API bool SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* display_format, float power); - IMGUI_API bool SliderIntN(const char* label, int* v, int components, int v_min, int v_max, const char* display_format); +IMGUI_API bool SliderBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_min, float v_max, float power, int decimal_precision, ImGuiSliderFlags flags = 0); +IMGUI_API bool SliderFloatN(const char* label, float* v, int components, float v_min, float v_max, const char* display_format, float power); +IMGUI_API bool SliderIntN(const char* label, int* v, int components, int v_min, int v_max, const char* display_format); - IMGUI_API bool DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_speed, float v_min, float v_max, int decimal_precision, float power); - IMGUI_API bool DragFloatN(const char* label, float* v, int components, float v_speed, float v_min, float v_max, const char* display_format, float power); - IMGUI_API bool DragIntN(const char* label, int* v, int components, float v_speed, int v_min, int v_max, const char* display_format); +IMGUI_API bool DragBehavior(const ImRect& frame_bb, ImGuiID id, float* v, float v_speed, float v_min, float v_max, int decimal_precision, float power); +IMGUI_API bool DragFloatN(const char* label, float* v, int components, float v_speed, float v_min, float v_max, const char* display_format, float power); +IMGUI_API bool DragIntN(const char* label, int* v, int components, float v_speed, int v_min, int v_max, const char* display_format); - IMGUI_API bool InputTextEx(const char* label, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback = NULL, void* user_data = NULL); - IMGUI_API bool InputFloatN(const char* label, float* v, int components, int decimal_precision, ImGuiInputTextFlags extra_flags); - IMGUI_API bool InputIntN(const char* label, int* v, int components, ImGuiInputTextFlags extra_flags); - IMGUI_API bool InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags); - IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision); +IMGUI_API bool InputTextEx(const char* label, char* buf, int buf_size, const ImVec2& size_arg, ImGuiInputTextFlags flags, ImGuiTextEditCallback callback = NULL, void* user_data = NULL); +IMGUI_API bool InputFloatN(const char* label, float* v, int components, int decimal_precision, ImGuiInputTextFlags extra_flags); +IMGUI_API bool InputIntN(const char* label, int* v, int components, ImGuiInputTextFlags extra_flags); +IMGUI_API bool InputScalarEx(const char* label, ImGuiDataType data_type, void* data_ptr, void* step_ptr, void* step_fast_ptr, const char* scalar_format, ImGuiInputTextFlags extra_flags); +IMGUI_API bool InputScalarAsWidgetReplacement(const ImRect& aabb, const char* label, ImGuiDataType data_type, void* data_ptr, ImGuiID id, int decimal_precision); - IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags); - IMGUI_API void ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags); +IMGUI_API void ColorTooltip(const char* text, const float* col, ImGuiColorEditFlags flags); +IMGUI_API void ColorEditOptionsPopup(const float* col, ImGuiColorEditFlags flags); - IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL); - IMGUI_API bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextTreeNodeOpened() data, if any. May return true when logging - IMGUI_API void TreePushRawID(ImGuiID id); +IMGUI_API bool TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL); +IMGUI_API bool TreeNodeBehaviorIsOpen(ImGuiID id, ImGuiTreeNodeFlags flags = 0); // Consume previous SetNextTreeNodeOpened() data, if any. May return true when logging +IMGUI_API void TreePushRawID(ImGuiID id); - IMGUI_API void PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size); +IMGUI_API void PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_getter)(void* data, int idx), void* data, int values_count, int values_offset, const char* overlay_text, float scale_min, float scale_max, ImVec2 graph_size); - IMGUI_API int ParseFormatPrecision(const char* fmt, int default_value); - IMGUI_API float RoundScalar(float value, int decimal_precision); +IMGUI_API int ParseFormatPrecision(const char* fmt, int default_value); +IMGUI_API float RoundScalar(float value, int decimal_precision); - // Shade functions - IMGUI_API void ShadeVertsLinearColorGradientKeepAlpha(ImDrawVert* vert_start, ImDrawVert* vert_end, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1); - IMGUI_API void ShadeVertsLinearAlphaGradientForLeftToRightText(ImDrawVert* vert_start, ImDrawVert* vert_end, float gradient_p0_x, float gradient_p1_x); - IMGUI_API void ShadeVertsLinearUV(ImDrawVert* vert_start, ImDrawVert* vert_end, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, bool clamp); +// Shade functions +IMGUI_API void ShadeVertsLinearColorGradientKeepAlpha(ImDrawVert* vert_start, ImDrawVert* vert_end, ImVec2 gradient_p0, ImVec2 gradient_p1, ImU32 col0, ImU32 col1); +IMGUI_API void ShadeVertsLinearAlphaGradientForLeftToRightText(ImDrawVert* vert_start, ImDrawVert* vert_end, float gradient_p0_x, float gradient_p1_x); +IMGUI_API void ShadeVertsLinearUV(ImDrawVert* vert_start, ImDrawVert* vert_end, const ImVec2& a, const ImVec2& b, const ImVec2& uv_a, const ImVec2& uv_b, bool clamp); -} // namespace ImGui +} // namespace ImGui // ImFontAtlas internals -IMGUI_API bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas); -IMGUI_API void ImFontAtlasBuildRegisterDefaultCustomRects(ImFontAtlas* atlas); -IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent); -IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* spc); -IMGUI_API void ImFontAtlasBuildFinish(ImFontAtlas* atlas); -IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor); -IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride); +IMGUI_API bool ImFontAtlasBuildWithStbTruetype(ImFontAtlas* atlas); +IMGUI_API void ImFontAtlasBuildRegisterDefaultCustomRects(ImFontAtlas* atlas); +IMGUI_API void ImFontAtlasBuildSetupFont(ImFontAtlas* atlas, ImFont* font, ImFontConfig* font_config, float ascent, float descent); +IMGUI_API void ImFontAtlasBuildPackCustomRects(ImFontAtlas* atlas, void* spc); +IMGUI_API void ImFontAtlasBuildFinish(ImFontAtlas* atlas); +IMGUI_API void ImFontAtlasBuildMultiplyCalcLookupTable(unsigned char out_table[256], float in_multiply_factor); +IMGUI_API void ImFontAtlasBuildMultiplyRectAlpha8(const unsigned char table[256], unsigned char* pixels, int x, int y, int w, int h, int stride); #ifdef __clang__ #pragma clang diagnostic pop #endif #ifdef _MSC_VER -#pragma warning (pop) +#pragma warning(pop) #endif diff --git a/examples/ThirdPartyLibs/imgui/stb_rect_pack.h b/examples/ThirdPartyLibs/imgui/stb_rect_pack.h index 2b07dcc82..95146ae5b 100644 --- a/examples/ThirdPartyLibs/imgui/stb_rect_pack.h +++ b/examples/ThirdPartyLibs/imgui/stb_rect_pack.h @@ -28,7 +28,7 @@ // Minor features // Martins Mozeiko // github:IntellectualKitty -// +// // Bugfixes / warning fixes // Jeremy Jaussaud // @@ -56,7 +56,7 @@ #ifndef STB_INCLUDE_STB_RECT_PACK_H #define STB_INCLUDE_STB_RECT_PACK_H -#define STB_RECT_PACK_VERSION 1 +#define STB_RECT_PACK_VERSION 1 #ifdef STBRP_STATIC #define STBRP_DEF static @@ -65,122 +65,120 @@ #endif #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -typedef struct stbrp_context stbrp_context; -typedef struct stbrp_node stbrp_node; -typedef struct stbrp_rect stbrp_rect; + typedef struct stbrp_context stbrp_context; + typedef struct stbrp_node stbrp_node; + typedef struct stbrp_rect stbrp_rect; #ifdef STBRP_LARGE_RECTS -typedef int stbrp_coord; + typedef int stbrp_coord; #else typedef unsigned short stbrp_coord; #endif -STBRP_DEF int stbrp_pack_rects (stbrp_context *context, stbrp_rect *rects, int num_rects); -// Assign packed locations to rectangles. The rectangles are of type -// 'stbrp_rect' defined below, stored in the array 'rects', and there -// are 'num_rects' many of them. -// -// Rectangles which are successfully packed have the 'was_packed' flag -// set to a non-zero value and 'x' and 'y' store the minimum location -// on each axis (i.e. bottom-left in cartesian coordinates, top-left -// if you imagine y increasing downwards). Rectangles which do not fit -// have the 'was_packed' flag set to 0. -// -// You should not try to access the 'rects' array from another thread -// while this function is running, as the function temporarily reorders -// the array while it executes. -// -// To pack into another rectangle, you need to call stbrp_init_target -// again. To continue packing into the same rectangle, you can call -// this function again. Calling this multiple times with multiple rect -// arrays will probably produce worse packing results than calling it -// a single time with the full rectangle array, but the option is -// available. -// -// The function returns 1 if all of the rectangles were successfully -// packed and 0 otherwise. + STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects); + // Assign packed locations to rectangles. The rectangles are of type + // 'stbrp_rect' defined below, stored in the array 'rects', and there + // are 'num_rects' many of them. + // + // Rectangles which are successfully packed have the 'was_packed' flag + // set to a non-zero value and 'x' and 'y' store the minimum location + // on each axis (i.e. bottom-left in cartesian coordinates, top-left + // if you imagine y increasing downwards). Rectangles which do not fit + // have the 'was_packed' flag set to 0. + // + // You should not try to access the 'rects' array from another thread + // while this function is running, as the function temporarily reorders + // the array while it executes. + // + // To pack into another rectangle, you need to call stbrp_init_target + // again. To continue packing into the same rectangle, you can call + // this function again. Calling this multiple times with multiple rect + // arrays will probably produce worse packing results than calling it + // a single time with the full rectangle array, but the option is + // available. + // + // The function returns 1 if all of the rectangles were successfully + // packed and 0 otherwise. -struct stbrp_rect -{ - // reserved for your use: - int id; + struct stbrp_rect + { + // reserved for your use: + int id; - // input: - stbrp_coord w, h; + // input: + stbrp_coord w, h; - // output: - stbrp_coord x, y; - int was_packed; // non-zero if valid packing + // output: + stbrp_coord x, y; + int was_packed; // non-zero if valid packing -}; // 16 bytes, nominally + }; // 16 bytes, nominally + STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes); + // Initialize a rectangle packer to: + // pack a rectangle that is 'width' by 'height' in dimensions + // using temporary storage provided by the array 'nodes', which is 'num_nodes' long + // + // You must call this function every time you start packing into a new target. + // + // There is no "shutdown" function. The 'nodes' memory must stay valid for + // the following stbrp_pack_rects() call (or calls), but can be freed after + // the call (or calls) finish. + // + // Note: to guarantee best results, either: + // 1. make sure 'num_nodes' >= 'width' + // or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1' + // + // If you don't do either of the above things, widths will be quantized to multiples + // of small integers to guarantee the algorithm doesn't run out of temporary storage. + // + // If you do #2, then the non-quantized algorithm will be used, but the algorithm + // may run out of temporary storage and be unable to pack some rectangles. -STBRP_DEF void stbrp_init_target (stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes); -// Initialize a rectangle packer to: -// pack a rectangle that is 'width' by 'height' in dimensions -// using temporary storage provided by the array 'nodes', which is 'num_nodes' long -// -// You must call this function every time you start packing into a new target. -// -// There is no "shutdown" function. The 'nodes' memory must stay valid for -// the following stbrp_pack_rects() call (or calls), but can be freed after -// the call (or calls) finish. -// -// Note: to guarantee best results, either: -// 1. make sure 'num_nodes' >= 'width' -// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1' -// -// If you don't do either of the above things, widths will be quantized to multiples -// of small integers to guarantee the algorithm doesn't run out of temporary storage. -// -// If you do #2, then the non-quantized algorithm will be used, but the algorithm -// may run out of temporary storage and be unable to pack some rectangles. + STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem); + // Optionally call this function after init but before doing any packing to + // change the handling of the out-of-temp-memory scenario, described above. + // If you call init again, this will be reset to the default (false). -STBRP_DEF void stbrp_setup_allow_out_of_mem (stbrp_context *context, int allow_out_of_mem); -// Optionally call this function after init but before doing any packing to -// change the handling of the out-of-temp-memory scenario, described above. -// If you call init again, this will be reset to the default (false). + STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic); + // Optionally select which packing heuristic the library should use. Different + // heuristics will produce better/worse results for different data sets. + // If you call init again, this will be reset to the default. + enum + { + STBRP_HEURISTIC_Skyline_default = 0, + STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default, + STBRP_HEURISTIC_Skyline_BF_sortHeight + }; -STBRP_DEF void stbrp_setup_heuristic (stbrp_context *context, int heuristic); -// Optionally select which packing heuristic the library should use. Different -// heuristics will produce better/worse results for different data sets. -// If you call init again, this will be reset to the default. + ////////////////////////////////////////////////////////////////////////////// + // + // the details of the following structures don't matter to you, but they must + // be visible so you can handle the memory allocations for them -enum -{ - STBRP_HEURISTIC_Skyline_default=0, - STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default, - STBRP_HEURISTIC_Skyline_BF_sortHeight -}; + struct stbrp_node + { + stbrp_coord x, y; + stbrp_node *next; + }; - -////////////////////////////////////////////////////////////////////////////// -// -// the details of the following structures don't matter to you, but they must -// be visible so you can handle the memory allocations for them - -struct stbrp_node -{ - stbrp_coord x,y; - stbrp_node *next; -}; - -struct stbrp_context -{ - int width; - int height; - int align; - int init_mode; - int heuristic; - int num_nodes; - stbrp_node *active_head; - stbrp_node *free_head; - stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' -}; + struct stbrp_context + { + int width; + int height; + int align; + int init_mode; + int heuristic; + int num_nodes; + stbrp_node *active_head; + stbrp_node *free_head; + stbrp_node extra[2]; // we allocate two extra nodes so optimal user-node-count is 'width' not 'width+2' + }; #ifdef __cplusplus } @@ -205,378 +203,414 @@ struct stbrp_context #endif #ifdef _MSC_VER -#define STBRP__NOTUSED(v) (void)(v) +#define STBRP__NOTUSED(v) (void)(v) #define STBRP__CDECL __cdecl #else -#define STBRP__NOTUSED(v) (void)sizeof(v) +#define STBRP__NOTUSED(v) (void)sizeof(v) #define STBRP__CDECL #endif enum { - STBRP__INIT_skyline = 1 + STBRP__INIT_skyline = 1 }; STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic) { - switch (context->init_mode) { - case STBRP__INIT_skyline: - STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight); - context->heuristic = heuristic; - break; - default: - STBRP_ASSERT(0); - } + switch (context->init_mode) + { + case STBRP__INIT_skyline: + STBRP_ASSERT(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight || heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight); + context->heuristic = heuristic; + break; + default: + STBRP_ASSERT(0); + } } STBRP_DEF void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem) { - if (allow_out_of_mem) - // if it's ok to run out of memory, then don't bother aligning them; - // this gives better packing, but may fail due to OOM (even though - // the rectangles easily fit). @TODO a smarter approach would be to only - // quantize once we've hit OOM, then we could get rid of this parameter. - context->align = 1; - else { - // if it's not ok to run out of memory, then quantize the widths - // so that num_nodes is always enough nodes. - // - // I.e. num_nodes * align >= width - // align >= width / num_nodes - // align = ceil(width/num_nodes) + if (allow_out_of_mem) + // if it's ok to run out of memory, then don't bother aligning them; + // this gives better packing, but may fail due to OOM (even though + // the rectangles easily fit). @TODO a smarter approach would be to only + // quantize once we've hit OOM, then we could get rid of this parameter. + context->align = 1; + else + { + // if it's not ok to run out of memory, then quantize the widths + // so that num_nodes is always enough nodes. + // + // I.e. num_nodes * align >= width + // align >= width / num_nodes + // align = ceil(width/num_nodes) - context->align = (context->width + context->num_nodes-1) / context->num_nodes; - } + context->align = (context->width + context->num_nodes - 1) / context->num_nodes; + } } STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes) { - int i; + int i; #ifndef STBRP_LARGE_RECTS - STBRP_ASSERT(width <= 0xffff && height <= 0xffff); + STBRP_ASSERT(width <= 0xffff && height <= 0xffff); #endif - for (i=0; i < num_nodes-1; ++i) - nodes[i].next = &nodes[i+1]; - nodes[i].next = NULL; - context->init_mode = STBRP__INIT_skyline; - context->heuristic = STBRP_HEURISTIC_Skyline_default; - context->free_head = &nodes[0]; - context->active_head = &context->extra[0]; - context->width = width; - context->height = height; - context->num_nodes = num_nodes; - stbrp_setup_allow_out_of_mem(context, 0); + for (i = 0; i < num_nodes - 1; ++i) + nodes[i].next = &nodes[i + 1]; + nodes[i].next = NULL; + context->init_mode = STBRP__INIT_skyline; + context->heuristic = STBRP_HEURISTIC_Skyline_default; + context->free_head = &nodes[0]; + context->active_head = &context->extra[0]; + context->width = width; + context->height = height; + context->num_nodes = num_nodes; + stbrp_setup_allow_out_of_mem(context, 0); - // node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) - context->extra[0].x = 0; - context->extra[0].y = 0; - context->extra[0].next = &context->extra[1]; - context->extra[1].x = (stbrp_coord) width; + // node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly) + context->extra[0].x = 0; + context->extra[0].y = 0; + context->extra[0].next = &context->extra[1]; + context->extra[1].x = (stbrp_coord)width; #ifdef STBRP_LARGE_RECTS - context->extra[1].y = (1<<30); + context->extra[1].y = (1 << 30); #else - context->extra[1].y = 65535; + context->extra[1].y = 65535; #endif - context->extra[1].next = NULL; + context->extra[1].next = NULL; } // find minimum y position if it starts at x1 static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste) { - stbrp_node *node = first; - int x1 = x0 + width; - int min_y, visited_width, waste_area; + stbrp_node *node = first; + int x1 = x0 + width; + int min_y, visited_width, waste_area; - STBRP__NOTUSED(c); + STBRP__NOTUSED(c); - STBRP_ASSERT(first->x <= x0); + STBRP_ASSERT(first->x <= x0); - #if 0 +#if 0 // skip in case we're past the node while (node->next->x <= x0) ++node; - #else - STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency - #endif +#else + STBRP_ASSERT(node->next->x > x0); // we ended up handling this in the caller for efficiency +#endif - STBRP_ASSERT(node->x <= x0); + STBRP_ASSERT(node->x <= x0); - min_y = 0; - waste_area = 0; - visited_width = 0; - while (node->x < x1) { - if (node->y > min_y) { - // raise min_y higher. - // we've accounted for all waste up to min_y, - // but we'll now add more waste for everything we've visted - waste_area += visited_width * (node->y - min_y); - min_y = node->y; - // the first time through, visited_width might be reduced - if (node->x < x0) - visited_width += node->next->x - x0; - else - visited_width += node->next->x - node->x; - } else { - // add waste area - int under_width = node->next->x - node->x; - if (under_width + visited_width > width) - under_width = width - visited_width; - waste_area += under_width * (min_y - node->y); - visited_width += under_width; - } - node = node->next; - } + min_y = 0; + waste_area = 0; + visited_width = 0; + while (node->x < x1) + { + if (node->y > min_y) + { + // raise min_y higher. + // we've accounted for all waste up to min_y, + // but we'll now add more waste for everything we've visted + waste_area += visited_width * (node->y - min_y); + min_y = node->y; + // the first time through, visited_width might be reduced + if (node->x < x0) + visited_width += node->next->x - x0; + else + visited_width += node->next->x - node->x; + } + else + { + // add waste area + int under_width = node->next->x - node->x; + if (under_width + visited_width > width) + under_width = width - visited_width; + waste_area += under_width * (min_y - node->y); + visited_width += under_width; + } + node = node->next; + } - *pwaste = waste_area; - return min_y; + *pwaste = waste_area; + return min_y; } typedef struct { - int x,y; - stbrp_node **prev_link; + int x, y; + stbrp_node **prev_link; } stbrp__findresult; static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height) { - int best_waste = (1<<30), best_x, best_y = (1 << 30); - stbrp__findresult fr; - stbrp_node **prev, *node, *tail, **best = NULL; + int best_waste = (1 << 30), best_x, best_y = (1 << 30); + stbrp__findresult fr; + stbrp_node **prev, *node, *tail, **best = NULL; - // align to multiple of c->align - width = (width + c->align - 1); - width -= width % c->align; - STBRP_ASSERT(width % c->align == 0); + // align to multiple of c->align + width = (width + c->align - 1); + width -= width % c->align; + STBRP_ASSERT(width % c->align == 0); - node = c->active_head; - prev = &c->active_head; - while (node->x + width <= c->width) { - int y,waste; - y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste); - if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL - // bottom left - if (y < best_y) { - best_y = y; - best = prev; - } - } else { - // best-fit - if (y + height <= c->height) { - // can only use it if it first vertically - if (y < best_y || (y == best_y && waste < best_waste)) { - best_y = y; - best_waste = waste; - best = prev; - } - } - } - prev = &node->next; - node = node->next; - } + node = c->active_head; + prev = &c->active_head; + while (node->x + width <= c->width) + { + int y, waste; + y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste); + if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) + { // actually just want to test BL + // bottom left + if (y < best_y) + { + best_y = y; + best = prev; + } + } + else + { + // best-fit + if (y + height <= c->height) + { + // can only use it if it first vertically + if (y < best_y || (y == best_y && waste < best_waste)) + { + best_y = y; + best_waste = waste; + best = prev; + } + } + } + prev = &node->next; + node = node->next; + } - best_x = (best == NULL) ? 0 : (*best)->x; + best_x = (best == NULL) ? 0 : (*best)->x; - // if doing best-fit (BF), we also have to try aligning right edge to each node position - // - // e.g, if fitting - // - // ____________________ - // |____________________| - // - // into - // - // | | - // | ____________| - // |____________| - // - // then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned - // - // This makes BF take about 2x the time + // if doing best-fit (BF), we also have to try aligning right edge to each node position + // + // e.g, if fitting + // + // ____________________ + // |____________________| + // + // into + // + // | | + // | ____________| + // |____________| + // + // then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned + // + // This makes BF take about 2x the time - if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) { - tail = c->active_head; - node = c->active_head; - prev = &c->active_head; - // find first node that's admissible - while (tail->x < width) - tail = tail->next; - while (tail) { - int xpos = tail->x - width; - int y,waste; - STBRP_ASSERT(xpos >= 0); - // find the left position that matches this - while (node->next->x <= xpos) { - prev = &node->next; - node = node->next; - } - STBRP_ASSERT(node->next->x > xpos && node->x <= xpos); - y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste); - if (y + height < c->height) { - if (y <= best_y) { - if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) { - best_x = xpos; - STBRP_ASSERT(y <= best_y); - best_y = y; - best_waste = waste; - best = prev; - } - } - } - tail = tail->next; - } - } + if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) + { + tail = c->active_head; + node = c->active_head; + prev = &c->active_head; + // find first node that's admissible + while (tail->x < width) + tail = tail->next; + while (tail) + { + int xpos = tail->x - width; + int y, waste; + STBRP_ASSERT(xpos >= 0); + // find the left position that matches this + while (node->next->x <= xpos) + { + prev = &node->next; + node = node->next; + } + STBRP_ASSERT(node->next->x > xpos && node->x <= xpos); + y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste); + if (y + height < c->height) + { + if (y <= best_y) + { + if (y < best_y || waste < best_waste || (waste == best_waste && xpos < best_x)) + { + best_x = xpos; + STBRP_ASSERT(y <= best_y); + best_y = y; + best_waste = waste; + best = prev; + } + } + } + tail = tail->next; + } + } - fr.prev_link = best; - fr.x = best_x; - fr.y = best_y; - return fr; + fr.prev_link = best; + fr.x = best_x; + fr.y = best_y; + return fr; } static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height) { - // find best position according to heuristic - stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height); - stbrp_node *node, *cur; + // find best position according to heuristic + stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height); + stbrp_node *node, *cur; - // bail if: - // 1. it failed - // 2. the best node doesn't fit (we don't always check this) - // 3. we're out of memory - if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) { - res.prev_link = NULL; - return res; - } + // bail if: + // 1. it failed + // 2. the best node doesn't fit (we don't always check this) + // 3. we're out of memory + if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) + { + res.prev_link = NULL; + return res; + } - // on success, create new node - node = context->free_head; - node->x = (stbrp_coord) res.x; - node->y = (stbrp_coord) (res.y + height); + // on success, create new node + node = context->free_head; + node->x = (stbrp_coord)res.x; + node->y = (stbrp_coord)(res.y + height); - context->free_head = node->next; + context->free_head = node->next; - // insert the new node into the right starting point, and - // let 'cur' point to the remaining nodes needing to be - // stiched back in + // insert the new node into the right starting point, and + // let 'cur' point to the remaining nodes needing to be + // stiched back in - cur = *res.prev_link; - if (cur->x < res.x) { - // preserve the existing one, so start testing with the next one - stbrp_node *next = cur->next; - cur->next = node; - cur = next; - } else { - *res.prev_link = node; - } + cur = *res.prev_link; + if (cur->x < res.x) + { + // preserve the existing one, so start testing with the next one + stbrp_node *next = cur->next; + cur->next = node; + cur = next; + } + else + { + *res.prev_link = node; + } - // from here, traverse cur and free the nodes, until we get to one - // that shouldn't be freed - while (cur->next && cur->next->x <= res.x + width) { - stbrp_node *next = cur->next; - // move the current node to the free list - cur->next = context->free_head; - context->free_head = cur; - cur = next; - } + // from here, traverse cur and free the nodes, until we get to one + // that shouldn't be freed + while (cur->next && cur->next->x <= res.x + width) + { + stbrp_node *next = cur->next; + // move the current node to the free list + cur->next = context->free_head; + context->free_head = cur; + cur = next; + } - // stitch the list back in - node->next = cur; + // stitch the list back in + node->next = cur; - if (cur->x < res.x + width) - cur->x = (stbrp_coord) (res.x + width); + if (cur->x < res.x + width) + cur->x = (stbrp_coord)(res.x + width); #ifdef _DEBUG - cur = context->active_head; - while (cur->x < context->width) { - STBRP_ASSERT(cur->x < cur->next->x); - cur = cur->next; - } - STBRP_ASSERT(cur->next == NULL); + cur = context->active_head; + while (cur->x < context->width) + { + STBRP_ASSERT(cur->x < cur->next->x); + cur = cur->next; + } + STBRP_ASSERT(cur->next == NULL); - { - int count=0; - cur = context->active_head; - while (cur) { - cur = cur->next; - ++count; - } - cur = context->free_head; - while (cur) { - cur = cur->next; - ++count; - } - STBRP_ASSERT(count == context->num_nodes+2); - } + { + int count = 0; + cur = context->active_head; + while (cur) + { + cur = cur->next; + ++count; + } + cur = context->free_head; + while (cur) + { + cur = cur->next; + ++count; + } + STBRP_ASSERT(count == context->num_nodes + 2); + } #endif - return res; + return res; } static int STBRP__CDECL rect_height_compare(const void *a, const void *b) { - const stbrp_rect *p = (const stbrp_rect *) a; - const stbrp_rect *q = (const stbrp_rect *) b; - if (p->h > q->h) - return -1; - if (p->h < q->h) - return 1; - return (p->w > q->w) ? -1 : (p->w < q->w); + const stbrp_rect *p = (const stbrp_rect *)a; + const stbrp_rect *q = (const stbrp_rect *)b; + if (p->h > q->h) + return -1; + if (p->h < q->h) + return 1; + return (p->w > q->w) ? -1 : (p->w < q->w); } static int STBRP__CDECL rect_original_order(const void *a, const void *b) { - const stbrp_rect *p = (const stbrp_rect *) a; - const stbrp_rect *q = (const stbrp_rect *) b; - return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed); + const stbrp_rect *p = (const stbrp_rect *)a; + const stbrp_rect *q = (const stbrp_rect *)b; + return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed); } #ifdef STBRP_LARGE_RECTS -#define STBRP__MAXVAL 0xffffffff +#define STBRP__MAXVAL 0xffffffff #else -#define STBRP__MAXVAL 0xffff +#define STBRP__MAXVAL 0xffff #endif STBRP_DEF int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects) { - int i, all_rects_packed = 1; + int i, all_rects_packed = 1; - // we use the 'was_packed' field internally to allow sorting/unsorting - for (i=0; i < num_rects; ++i) { - rects[i].was_packed = i; - #ifndef STBRP_LARGE_RECTS - STBRP_ASSERT(rects[i].w <= 0xffff && rects[i].h <= 0xffff); - #endif - } + // we use the 'was_packed' field internally to allow sorting/unsorting + for (i = 0; i < num_rects; ++i) + { + rects[i].was_packed = i; +#ifndef STBRP_LARGE_RECTS + STBRP_ASSERT(rects[i].w <= 0xffff && rects[i].h <= 0xffff); +#endif + } - // sort according to heuristic - STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare); + // sort according to heuristic + STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare); - for (i=0; i < num_rects; ++i) { - if (rects[i].w == 0 || rects[i].h == 0) { - rects[i].x = rects[i].y = 0; // empty rect needs no space - } else { - stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h); - if (fr.prev_link) { - rects[i].x = (stbrp_coord) fr.x; - rects[i].y = (stbrp_coord) fr.y; - } else { - rects[i].x = rects[i].y = STBRP__MAXVAL; - } - } - } + for (i = 0; i < num_rects; ++i) + { + if (rects[i].w == 0 || rects[i].h == 0) + { + rects[i].x = rects[i].y = 0; // empty rect needs no space + } + else + { + stbrp__findresult fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h); + if (fr.prev_link) + { + rects[i].x = (stbrp_coord)fr.x; + rects[i].y = (stbrp_coord)fr.y; + } + else + { + rects[i].x = rects[i].y = STBRP__MAXVAL; + } + } + } - // unsort - STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order); + // unsort + STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order); - // set was_packed flags and all_rects_packed status - for (i=0; i < num_rects; ++i) { - rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL); - if (!rects[i].was_packed) - all_rects_packed = 0; - } + // set was_packed flags and all_rects_packed status + for (i = 0; i < num_rects; ++i) + { + rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL); + if (!rects[i].was_packed) + all_rects_packed = 0; + } - // return the all_rects_packed status - return all_rects_packed; + // return the all_rects_packed status + return all_rects_packed; } #endif diff --git a/examples/ThirdPartyLibs/imgui/stb_textedit.h b/examples/ThirdPartyLibs/imgui/stb_textedit.h index 4b731a0c2..a2d76901a 100644 --- a/examples/ThirdPartyLibs/imgui/stb_textedit.h +++ b/examples/ThirdPartyLibs/imgui/stb_textedit.h @@ -19,7 +19,7 @@ // texts, as its performance does not scale and it has limited undo). // // Non-trivial behaviors are modelled after Windows text controls. -// +// // // LICENSE // @@ -216,20 +216,20 @@ // call this with the mouse x,y on a mouse down; it will update the cursor // and reset the selection start/end to the cursor point. the x,y must // be relative to the text widget, with (0,0) being the top left. -// +// // drag: // call this with the mouse x,y on a mouse drag/up; it will update the // cursor and the selection end point -// +// // cut: // call this to delete the current selection; returns true if there was // one. you should FIRST copy the current selection to the system paste buffer. // (To copy, just copy the current selection out of the string yourself.) -// +// // paste: // call this to paste text at the current cursor point or over the current // selection if there is one. -// +// // key: // call this for keyboard inputs sent to the textfield. you can use it // for "key down" events or for "translated" key events. if you need to @@ -238,7 +238,7 @@ // various definitions like STB_TEXTEDIT_K_LEFT have the is-key-event bit // set, and make STB_TEXTEDIT_KEYTOCHAR check that the is-key-event bit is // clear. -// +// // When rendering, you can read the cursor position and selection state from // the STB_TexteditState. // @@ -260,7 +260,6 @@ // efficient, but it's not horrible on modern computers. But you wouldn't // want to edit million-line files with it. - //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// //// @@ -281,71 +280,70 @@ // #ifndef STB_TEXTEDIT_UNDOSTATECOUNT -#define STB_TEXTEDIT_UNDOSTATECOUNT 99 +#define STB_TEXTEDIT_UNDOSTATECOUNT 99 #endif #ifndef STB_TEXTEDIT_UNDOCHARCOUNT -#define STB_TEXTEDIT_UNDOCHARCOUNT 999 +#define STB_TEXTEDIT_UNDOCHARCOUNT 999 #endif #ifndef STB_TEXTEDIT_CHARTYPE -#define STB_TEXTEDIT_CHARTYPE int +#define STB_TEXTEDIT_CHARTYPE int #endif #ifndef STB_TEXTEDIT_POSITIONTYPE -#define STB_TEXTEDIT_POSITIONTYPE int +#define STB_TEXTEDIT_POSITIONTYPE int #endif typedef struct { - // private data - STB_TEXTEDIT_POSITIONTYPE where; - short insert_length; - short delete_length; - short char_storage; + // private data + STB_TEXTEDIT_POSITIONTYPE where; + short insert_length; + short delete_length; + short char_storage; } StbUndoRecord; typedef struct { - // private data - StbUndoRecord undo_rec [STB_TEXTEDIT_UNDOSTATECOUNT]; - STB_TEXTEDIT_CHARTYPE undo_char[STB_TEXTEDIT_UNDOCHARCOUNT]; - short undo_point, redo_point; - short undo_char_point, redo_char_point; + // private data + StbUndoRecord undo_rec[STB_TEXTEDIT_UNDOSTATECOUNT]; + STB_TEXTEDIT_CHARTYPE undo_char[STB_TEXTEDIT_UNDOCHARCOUNT]; + short undo_point, redo_point; + short undo_char_point, redo_char_point; } StbUndoState; typedef struct { - ///////////////////// - // - // public data - // + ///////////////////// + // + // public data + // - int cursor; - // position of the text cursor within the string + int cursor; + // position of the text cursor within the string - int select_start; // selection start point - int select_end; - // selection start and end point in characters; if equal, no selection. - // note that start may be less than or greater than end (e.g. when - // dragging the mouse, start is where the initial click was, and you - // can drag in either direction) + int select_start; // selection start point + int select_end; + // selection start and end point in characters; if equal, no selection. + // note that start may be less than or greater than end (e.g. when + // dragging the mouse, start is where the initial click was, and you + // can drag in either direction) - unsigned char insert_mode; - // each textfield keeps its own insert mode state. to keep an app-wide - // insert mode, copy this value in/out of the app state + unsigned char insert_mode; + // each textfield keeps its own insert mode state. to keep an app-wide + // insert mode, copy this value in/out of the app state - ///////////////////// - // - // private data - // - unsigned char cursor_at_end_of_line; // not implemented yet - unsigned char initialized; - unsigned char has_preferred_x; - unsigned char single_line; - unsigned char padding1, padding2, padding3; - float preferred_x; // this determines where the cursor up/down tries to seek to along x - StbUndoState undostate; + ///////////////////// + // + // private data + // + unsigned char cursor_at_end_of_line; // not implemented yet + unsigned char initialized; + unsigned char has_preferred_x; + unsigned char single_line; + unsigned char padding1, padding2, padding3; + float preferred_x; // this determines where the cursor up/down tries to seek to along x + StbUndoState undostate; } STB_TexteditState; - //////////////////////////////////////////////////////////////////////// // // StbTexteditRow @@ -356,13 +354,12 @@ typedef struct // result of layout query typedef struct { - float x0,x1; // starting x location, end x location (allows for align=right, etc) - float baseline_y_delta; // position of baseline relative to previous row's baseline - float ymin,ymax; // height of row above and below baseline - int num_chars; + float x0, x1; // starting x location, end x location (allows for align=right, etc) + float baseline_y_delta; // position of baseline relative to previous row's baseline + float ymin, ymax; // height of row above and below baseline + int num_chars; } StbTexteditRow; -#endif //INCLUDE_STB_TEXTEDIT_H - +#endif //INCLUDE_STB_TEXTEDIT_H //////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////// @@ -371,7 +368,6 @@ typedef struct //// //// - // implementation isn't include-guarded, since it might have indirectly // included just the "header" portion #ifdef STB_TEXTEDIT_IMPLEMENTATION @@ -381,7 +377,6 @@ typedef struct #define STB_TEXTEDIT_memmove memmove #endif - ///////////////////////////////////////////////////////////////////////////// // // Mouse input handling @@ -390,79 +385,83 @@ typedef struct // traverse the layout to locate the nearest character to a display position static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y) { - StbTexteditRow r; - int n = STB_TEXTEDIT_STRINGLEN(str); - float base_y = 0, prev_x; - int i=0, k; + StbTexteditRow r; + int n = STB_TEXTEDIT_STRINGLEN(str); + float base_y = 0, prev_x; + int i = 0, k; - r.x0 = r.x1 = 0; - r.ymin = r.ymax = 0; - r.num_chars = 0; + r.x0 = r.x1 = 0; + r.ymin = r.ymax = 0; + r.num_chars = 0; - // search rows to find one that straddles 'y' - while (i < n) { - STB_TEXTEDIT_LAYOUTROW(&r, str, i); - if (r.num_chars <= 0) - return n; + // search rows to find one that straddles 'y' + while (i < n) + { + STB_TEXTEDIT_LAYOUTROW(&r, str, i); + if (r.num_chars <= 0) + return n; - if (i==0 && y < base_y + r.ymin) - return 0; + if (i == 0 && y < base_y + r.ymin) + return 0; - if (y < base_y + r.ymax) - break; + if (y < base_y + r.ymax) + break; - i += r.num_chars; - base_y += r.baseline_y_delta; - } + i += r.num_chars; + base_y += r.baseline_y_delta; + } - // below all text, return 'after' last character - if (i >= n) - return n; + // below all text, return 'after' last character + if (i >= n) + return n; - // check if it's before the beginning of the line - if (x < r.x0) - return i; + // check if it's before the beginning of the line + if (x < r.x0) + return i; - // check if it's before the end of the line - if (x < r.x1) { - // search characters in row for one that straddles 'x' - prev_x = r.x0; - for (k=0; k < r.num_chars; ++k) { - float w = STB_TEXTEDIT_GETWIDTH(str, i, k); - if (x < prev_x+w) { - if (x < prev_x+w/2) - return k+i; - else - return k+i+1; - } - prev_x += w; - } - // shouldn't happen, but if it does, fall through to end-of-line case - } + // check if it's before the end of the line + if (x < r.x1) + { + // search characters in row for one that straddles 'x' + prev_x = r.x0; + for (k = 0; k < r.num_chars; ++k) + { + float w = STB_TEXTEDIT_GETWIDTH(str, i, k); + if (x < prev_x + w) + { + if (x < prev_x + w / 2) + return k + i; + else + return k + i + 1; + } + prev_x += w; + } + // shouldn't happen, but if it does, fall through to end-of-line case + } - // if the last character is a newline, return that. otherwise return 'after' the last character - if (STB_TEXTEDIT_GETCHAR(str, i+r.num_chars-1) == STB_TEXTEDIT_NEWLINE) - return i+r.num_chars-1; - else - return i+r.num_chars; + // if the last character is a newline, return that. otherwise return 'after' the last character + if (STB_TEXTEDIT_GETCHAR(str, i + r.num_chars - 1) == STB_TEXTEDIT_NEWLINE) + return i + r.num_chars - 1; + else + return i + r.num_chars; } // API click: on mouse down, move the cursor to the clicked location, and reset the selection static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) { - state->cursor = stb_text_locate_coord(str, x, y); - state->select_start = state->cursor; - state->select_end = state->cursor; - state->has_preferred_x = 0; + state->cursor = stb_text_locate_coord(str, x, y); + state->select_start = state->cursor; + state->select_end = state->cursor; + state->has_preferred_x = 0; } // API drag: on mouse drag, move the cursor and selection endpoint to the clicked location static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y) { - int p = stb_text_locate_coord(str, x, y); - if (state->select_start == state->select_end) - state->select_start = state->cursor; - state->cursor = state->select_end = p; + int p = stb_text_locate_coord(str, x, y); + if (state->select_start == state->select_end) + state->select_start = state->cursor; + state->cursor = state->select_end = p; } ///////////////////////////////////////////////////////////////////////////// @@ -479,177 +478,191 @@ static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditStat typedef struct { - float x,y; // position of n'th character - float height; // height of line - int first_char, length; // first char of row, and length - int prev_first; // first char of previous row + float x, y; // position of n'th character + float height; // height of line + int first_char, length; // first char of row, and length + int prev_first; // first char of previous row } StbFindState; // find the x/y location of a character, and remember info about the previous row in // case we get a move-up event (for page up, we'll have to rescan) static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *str, int n, int single_line) { - StbTexteditRow r; - int prev_start = 0; - int z = STB_TEXTEDIT_STRINGLEN(str); - int i=0, first; + StbTexteditRow r; + int prev_start = 0; + int z = STB_TEXTEDIT_STRINGLEN(str); + int i = 0, first; - if (n == z) { - // if it's at the end, then find the last line -- simpler than trying to - // explicitly handle this case in the regular code - if (single_line) { - STB_TEXTEDIT_LAYOUTROW(&r, str, 0); - find->y = 0; - find->first_char = 0; - find->length = z; - find->height = r.ymax - r.ymin; - find->x = r.x1; - } else { - find->y = 0; - find->x = 0; - find->height = 1; - while (i < z) { - STB_TEXTEDIT_LAYOUTROW(&r, str, i); - prev_start = i; - i += r.num_chars; - } - find->first_char = i; - find->length = 0; - find->prev_first = prev_start; - } - return; - } + if (n == z) + { + // if it's at the end, then find the last line -- simpler than trying to + // explicitly handle this case in the regular code + if (single_line) + { + STB_TEXTEDIT_LAYOUTROW(&r, str, 0); + find->y = 0; + find->first_char = 0; + find->length = z; + find->height = r.ymax - r.ymin; + find->x = r.x1; + } + else + { + find->y = 0; + find->x = 0; + find->height = 1; + while (i < z) + { + STB_TEXTEDIT_LAYOUTROW(&r, str, i); + prev_start = i; + i += r.num_chars; + } + find->first_char = i; + find->length = 0; + find->prev_first = prev_start; + } + return; + } - // search rows to find the one that straddles character n - find->y = 0; + // search rows to find the one that straddles character n + find->y = 0; - for(;;) { - STB_TEXTEDIT_LAYOUTROW(&r, str, i); - if (n < i + r.num_chars) - break; - prev_start = i; - i += r.num_chars; - find->y += r.baseline_y_delta; - } + for (;;) + { + STB_TEXTEDIT_LAYOUTROW(&r, str, i); + if (n < i + r.num_chars) + break; + prev_start = i; + i += r.num_chars; + find->y += r.baseline_y_delta; + } - find->first_char = first = i; - find->length = r.num_chars; - find->height = r.ymax - r.ymin; - find->prev_first = prev_start; + find->first_char = first = i; + find->length = r.num_chars; + find->height = r.ymax - r.ymin; + find->prev_first = prev_start; - // now scan to find xpos - find->x = r.x0; - i = 0; - for (i=0; first+i < n; ++i) - find->x += STB_TEXTEDIT_GETWIDTH(str, first, i); + // now scan to find xpos + find->x = r.x0; + i = 0; + for (i = 0; first + i < n; ++i) + find->x += STB_TEXTEDIT_GETWIDTH(str, first, i); } -#define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end) +#define STB_TEXT_HAS_SELECTION(s) ((s)->select_start != (s)->select_end) // make the selection/cursor state valid if client altered the string static void stb_textedit_clamp(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) { - int n = STB_TEXTEDIT_STRINGLEN(str); - if (STB_TEXT_HAS_SELECTION(state)) { - if (state->select_start > n) state->select_start = n; - if (state->select_end > n) state->select_end = n; - // if clamping forced them to be equal, move the cursor to match - if (state->select_start == state->select_end) - state->cursor = state->select_start; - } - if (state->cursor > n) state->cursor = n; + int n = STB_TEXTEDIT_STRINGLEN(str); + if (STB_TEXT_HAS_SELECTION(state)) + { + if (state->select_start > n) state->select_start = n; + if (state->select_end > n) state->select_end = n; + // if clamping forced them to be equal, move the cursor to match + if (state->select_start == state->select_end) + state->cursor = state->select_start; + } + if (state->cursor > n) state->cursor = n; } // delete characters while updating undo static void stb_textedit_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int len) { - stb_text_makeundo_delete(str, state, where, len); - STB_TEXTEDIT_DELETECHARS(str, where, len); - state->has_preferred_x = 0; + stb_text_makeundo_delete(str, state, where, len); + STB_TEXTEDIT_DELETECHARS(str, where, len); + state->has_preferred_x = 0; } // delete the section static void stb_textedit_delete_selection(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) { - stb_textedit_clamp(str, state); - if (STB_TEXT_HAS_SELECTION(state)) { - if (state->select_start < state->select_end) { - stb_textedit_delete(str, state, state->select_start, state->select_end - state->select_start); - state->select_end = state->cursor = state->select_start; - } else { - stb_textedit_delete(str, state, state->select_end, state->select_start - state->select_end); - state->select_start = state->cursor = state->select_end; - } - state->has_preferred_x = 0; - } + stb_textedit_clamp(str, state); + if (STB_TEXT_HAS_SELECTION(state)) + { + if (state->select_start < state->select_end) + { + stb_textedit_delete(str, state, state->select_start, state->select_end - state->select_start); + state->select_end = state->cursor = state->select_start; + } + else + { + stb_textedit_delete(str, state, state->select_end, state->select_start - state->select_end); + state->select_start = state->cursor = state->select_end; + } + state->has_preferred_x = 0; + } } // canoncialize the selection so start <= end static void stb_textedit_sortselection(STB_TexteditState *state) { - if (state->select_end < state->select_start) { - int temp = state->select_end; - state->select_end = state->select_start; - state->select_start = temp; - } + if (state->select_end < state->select_start) + { + int temp = state->select_end; + state->select_end = state->select_start; + state->select_start = temp; + } } // move cursor to first character of selection static void stb_textedit_move_to_first(STB_TexteditState *state) { - if (STB_TEXT_HAS_SELECTION(state)) { - stb_textedit_sortselection(state); - state->cursor = state->select_start; - state->select_end = state->select_start; - state->has_preferred_x = 0; - } + if (STB_TEXT_HAS_SELECTION(state)) + { + stb_textedit_sortselection(state); + state->cursor = state->select_start; + state->select_end = state->select_start; + state->has_preferred_x = 0; + } } // move cursor to last character of selection static void stb_textedit_move_to_last(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) { - if (STB_TEXT_HAS_SELECTION(state)) { - stb_textedit_sortselection(state); - stb_textedit_clamp(str, state); - state->cursor = state->select_end; - state->select_start = state->select_end; - state->has_preferred_x = 0; - } + if (STB_TEXT_HAS_SELECTION(state)) + { + stb_textedit_sortselection(state); + stb_textedit_clamp(str, state); + state->cursor = state->select_end; + state->select_start = state->select_end; + state->has_preferred_x = 0; + } } #ifdef STB_TEXTEDIT_IS_SPACE -static int is_word_boundary( STB_TEXTEDIT_STRING *str, int idx ) +static int is_word_boundary(STB_TEXTEDIT_STRING *str, int idx) { - return idx > 0 ? (STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str,idx-1) ) && !STB_TEXTEDIT_IS_SPACE( STB_TEXTEDIT_GETCHAR(str, idx) ) ) : 1; + return idx > 0 ? (STB_TEXTEDIT_IS_SPACE(STB_TEXTEDIT_GETCHAR(str, idx - 1)) && !STB_TEXTEDIT_IS_SPACE(STB_TEXTEDIT_GETCHAR(str, idx))) : 1; } #ifndef STB_TEXTEDIT_MOVEWORDLEFT -static int stb_textedit_move_to_word_previous( STB_TEXTEDIT_STRING *str, int c ) +static int stb_textedit_move_to_word_previous(STB_TEXTEDIT_STRING *str, int c) { - --c; // always move at least one character - while( c >= 0 && !is_word_boundary( str, c ) ) - --c; + --c; // always move at least one character + while (c >= 0 && !is_word_boundary(str, c)) + --c; - if( c < 0 ) - c = 0; + if (c < 0) + c = 0; - return c; + return c; } #define STB_TEXTEDIT_MOVEWORDLEFT stb_textedit_move_to_word_previous #endif #ifndef STB_TEXTEDIT_MOVEWORDRIGHT -static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *str, int c ) +static int stb_textedit_move_to_word_next(STB_TEXTEDIT_STRING *str, int c) { - const int len = STB_TEXTEDIT_STRINGLEN(str); - ++c; // always move at least one character - while( c < len && !is_word_boundary( str, c ) ) - ++c; + const int len = STB_TEXTEDIT_STRINGLEN(str); + ++c; // always move at least one character + while (c < len && !is_word_boundary(str, c)) + ++c; - if( c > len ) - c = len; + if (c > len) + c = len; - return c; + return c; } #define STB_TEXTEDIT_MOVEWORDRIGHT stb_textedit_move_to_word_next #endif @@ -659,399 +672,426 @@ static int stb_textedit_move_to_word_next( STB_TEXTEDIT_STRING *str, int c ) // update selection and cursor to match each other static void stb_textedit_prep_selection_at_cursor(STB_TexteditState *state) { - if (!STB_TEXT_HAS_SELECTION(state)) - state->select_start = state->select_end = state->cursor; - else - state->cursor = state->select_end; + if (!STB_TEXT_HAS_SELECTION(state)) + state->select_start = state->select_end = state->cursor; + else + state->cursor = state->select_end; } // API cut: delete selection static int stb_textedit_cut(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) { - if (STB_TEXT_HAS_SELECTION(state)) { - stb_textedit_delete_selection(str,state); // implicity clamps - state->has_preferred_x = 0; - return 1; - } - return 0; + if (STB_TEXT_HAS_SELECTION(state)) + { + stb_textedit_delete_selection(str, state); // implicity clamps + state->has_preferred_x = 0; + return 1; + } + return 0; } // API paste: replace existing selection with passed-in text static int stb_textedit_paste(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, STB_TEXTEDIT_CHARTYPE const *ctext, int len) { - STB_TEXTEDIT_CHARTYPE *text = (STB_TEXTEDIT_CHARTYPE *) ctext; - // if there's a selection, the paste should delete it - stb_textedit_clamp(str, state); - stb_textedit_delete_selection(str,state); - // try to insert the characters - if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, len)) { - stb_text_makeundo_insert(state, state->cursor, len); - state->cursor += len; - state->has_preferred_x = 0; - return 1; - } - // remove the undo since we didn't actually insert the characters - if (state->undostate.undo_point) - --state->undostate.undo_point; - return 0; + STB_TEXTEDIT_CHARTYPE *text = (STB_TEXTEDIT_CHARTYPE *)ctext; + // if there's a selection, the paste should delete it + stb_textedit_clamp(str, state); + stb_textedit_delete_selection(str, state); + // try to insert the characters + if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, text, len)) + { + stb_text_makeundo_insert(state, state->cursor, len); + state->cursor += len; + state->has_preferred_x = 0; + return 1; + } + // remove the undo since we didn't actually insert the characters + if (state->undostate.undo_point) + --state->undostate.undo_point; + return 0; } // API key: process a keyboard input static void stb_textedit_key(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int key) { retry: - switch (key) { - default: { - int c = STB_TEXTEDIT_KEYTOTEXT(key); - if (c > 0) { - STB_TEXTEDIT_CHARTYPE ch = (STB_TEXTEDIT_CHARTYPE) c; + switch (key) + { + default: + { + int c = STB_TEXTEDIT_KEYTOTEXT(key); + if (c > 0) + { + STB_TEXTEDIT_CHARTYPE ch = (STB_TEXTEDIT_CHARTYPE)c; - // can't add newline in single-line mode - if (c == '\n' && state->single_line) - break; + // can't add newline in single-line mode + if (c == '\n' && state->single_line) + break; - if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) { - stb_text_makeundo_replace(str, state, state->cursor, 1, 1); - STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1); - if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) { - ++state->cursor; - state->has_preferred_x = 0; - } - } else { - stb_textedit_delete_selection(str,state); // implicity clamps - if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) { - stb_text_makeundo_insert(state, state->cursor, 1); - ++state->cursor; - state->has_preferred_x = 0; - } - } - } - break; - } + if (state->insert_mode && !STB_TEXT_HAS_SELECTION(state) && state->cursor < STB_TEXTEDIT_STRINGLEN(str)) + { + stb_text_makeundo_replace(str, state, state->cursor, 1, 1); + STB_TEXTEDIT_DELETECHARS(str, state->cursor, 1); + if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) + { + ++state->cursor; + state->has_preferred_x = 0; + } + } + else + { + stb_textedit_delete_selection(str, state); // implicity clamps + if (STB_TEXTEDIT_INSERTCHARS(str, state->cursor, &ch, 1)) + { + stb_text_makeundo_insert(state, state->cursor, 1); + ++state->cursor; + state->has_preferred_x = 0; + } + } + } + break; + } #ifdef STB_TEXTEDIT_K_INSERT - case STB_TEXTEDIT_K_INSERT: - state->insert_mode = !state->insert_mode; - break; + case STB_TEXTEDIT_K_INSERT: + state->insert_mode = !state->insert_mode; + break; #endif - - case STB_TEXTEDIT_K_UNDO: - stb_text_undo(str, state); - state->has_preferred_x = 0; - break; - case STB_TEXTEDIT_K_REDO: - stb_text_redo(str, state); - state->has_preferred_x = 0; - break; + case STB_TEXTEDIT_K_UNDO: + stb_text_undo(str, state); + state->has_preferred_x = 0; + break; - case STB_TEXTEDIT_K_LEFT: - // if currently there's a selection, move cursor to start of selection - if (STB_TEXT_HAS_SELECTION(state)) - stb_textedit_move_to_first(state); - else - if (state->cursor > 0) - --state->cursor; - state->has_preferred_x = 0; - break; + case STB_TEXTEDIT_K_REDO: + stb_text_redo(str, state); + state->has_preferred_x = 0; + break; - case STB_TEXTEDIT_K_RIGHT: - // if currently there's a selection, move cursor to end of selection - if (STB_TEXT_HAS_SELECTION(state)) - stb_textedit_move_to_last(str, state); - else - ++state->cursor; - stb_textedit_clamp(str, state); - state->has_preferred_x = 0; - break; + case STB_TEXTEDIT_K_LEFT: + // if currently there's a selection, move cursor to start of selection + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_first(state); + else if (state->cursor > 0) + --state->cursor; + state->has_preferred_x = 0; + break; - case STB_TEXTEDIT_K_LEFT | STB_TEXTEDIT_K_SHIFT: - stb_textedit_clamp(str, state); - stb_textedit_prep_selection_at_cursor(state); - // move selection left - if (state->select_end > 0) - --state->select_end; - state->cursor = state->select_end; - state->has_preferred_x = 0; - break; + case STB_TEXTEDIT_K_RIGHT: + // if currently there's a selection, move cursor to end of selection + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_last(str, state); + else + ++state->cursor; + stb_textedit_clamp(str, state); + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_LEFT | STB_TEXTEDIT_K_SHIFT: + stb_textedit_clamp(str, state); + stb_textedit_prep_selection_at_cursor(state); + // move selection left + if (state->select_end > 0) + --state->select_end; + state->cursor = state->select_end; + state->has_preferred_x = 0; + break; #ifdef STB_TEXTEDIT_MOVEWORDLEFT - case STB_TEXTEDIT_K_WORDLEFT: - if (STB_TEXT_HAS_SELECTION(state)) - stb_textedit_move_to_first(state); - else { - state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor); - stb_textedit_clamp( str, state ); - } - break; + case STB_TEXTEDIT_K_WORDLEFT: + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_first(state); + else + { + state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor); + stb_textedit_clamp(str, state); + } + break; - case STB_TEXTEDIT_K_WORDLEFT | STB_TEXTEDIT_K_SHIFT: - if( !STB_TEXT_HAS_SELECTION( state ) ) - stb_textedit_prep_selection_at_cursor(state); + case STB_TEXTEDIT_K_WORDLEFT | STB_TEXTEDIT_K_SHIFT: + if (!STB_TEXT_HAS_SELECTION(state)) + stb_textedit_prep_selection_at_cursor(state); - state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor); - state->select_end = state->cursor; + state->cursor = STB_TEXTEDIT_MOVEWORDLEFT(str, state->cursor); + state->select_end = state->cursor; - stb_textedit_clamp( str, state ); - break; + stb_textedit_clamp(str, state); + break; #endif #ifdef STB_TEXTEDIT_MOVEWORDRIGHT - case STB_TEXTEDIT_K_WORDRIGHT: - if (STB_TEXT_HAS_SELECTION(state)) - stb_textedit_move_to_last(str, state); - else { - state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor); - stb_textedit_clamp( str, state ); - } - break; + case STB_TEXTEDIT_K_WORDRIGHT: + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_last(str, state); + else + { + state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor); + stb_textedit_clamp(str, state); + } + break; - case STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT: - if( !STB_TEXT_HAS_SELECTION( state ) ) - stb_textedit_prep_selection_at_cursor(state); + case STB_TEXTEDIT_K_WORDRIGHT | STB_TEXTEDIT_K_SHIFT: + if (!STB_TEXT_HAS_SELECTION(state)) + stb_textedit_prep_selection_at_cursor(state); - state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor); - state->select_end = state->cursor; + state->cursor = STB_TEXTEDIT_MOVEWORDRIGHT(str, state->cursor); + state->select_end = state->cursor; - stb_textedit_clamp( str, state ); - break; + stb_textedit_clamp(str, state); + break; #endif - case STB_TEXTEDIT_K_RIGHT | STB_TEXTEDIT_K_SHIFT: - stb_textedit_prep_selection_at_cursor(state); - // move selection right - ++state->select_end; - stb_textedit_clamp(str, state); - state->cursor = state->select_end; - state->has_preferred_x = 0; - break; + case STB_TEXTEDIT_K_RIGHT | STB_TEXTEDIT_K_SHIFT: + stb_textedit_prep_selection_at_cursor(state); + // move selection right + ++state->select_end; + stb_textedit_clamp(str, state); + state->cursor = state->select_end; + state->has_preferred_x = 0; + break; - case STB_TEXTEDIT_K_DOWN: - case STB_TEXTEDIT_K_DOWN | STB_TEXTEDIT_K_SHIFT: { - StbFindState find; - StbTexteditRow row; - int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0; + case STB_TEXTEDIT_K_DOWN: + case STB_TEXTEDIT_K_DOWN | STB_TEXTEDIT_K_SHIFT: + { + StbFindState find; + StbTexteditRow row; + int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0; - if (state->single_line) { - // on windows, up&down in single-line behave like left&right - key = STB_TEXTEDIT_K_RIGHT | (key & STB_TEXTEDIT_K_SHIFT); - goto retry; - } + if (state->single_line) + { + // on windows, up&down in single-line behave like left&right + key = STB_TEXTEDIT_K_RIGHT | (key & STB_TEXTEDIT_K_SHIFT); + goto retry; + } - if (sel) - stb_textedit_prep_selection_at_cursor(state); - else if (STB_TEXT_HAS_SELECTION(state)) - stb_textedit_move_to_last(str,state); + if (sel) + stb_textedit_prep_selection_at_cursor(state); + else if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_last(str, state); - // compute current position of cursor point - stb_textedit_clamp(str, state); - stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); + // compute current position of cursor point + stb_textedit_clamp(str, state); + stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); - // now find character position down a row - if (find.length) { - float goal_x = state->has_preferred_x ? state->preferred_x : find.x; - float x; - int start = find.first_char + find.length; - state->cursor = start; - STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor); - x = row.x0; - for (i=0; i < row.num_chars; ++i) { - float dx = STB_TEXTEDIT_GETWIDTH(str, start, i); - #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE - if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE) - break; - #endif - x += dx; - if (x > goal_x) - break; - ++state->cursor; - } - stb_textedit_clamp(str, state); + // now find character position down a row + if (find.length) + { + float goal_x = state->has_preferred_x ? state->preferred_x : find.x; + float x; + int start = find.first_char + find.length; + state->cursor = start; + STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor); + x = row.x0; + for (i = 0; i < row.num_chars; ++i) + { + float dx = STB_TEXTEDIT_GETWIDTH(str, start, i); +#ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE + if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE) + break; +#endif + x += dx; + if (x > goal_x) + break; + ++state->cursor; + } + stb_textedit_clamp(str, state); - state->has_preferred_x = 1; - state->preferred_x = goal_x; + state->has_preferred_x = 1; + state->preferred_x = goal_x; - if (sel) - state->select_end = state->cursor; - } - break; - } - - case STB_TEXTEDIT_K_UP: - case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT: { - StbFindState find; - StbTexteditRow row; - int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0; + if (sel) + state->select_end = state->cursor; + } + break; + } - if (state->single_line) { - // on windows, up&down become left&right - key = STB_TEXTEDIT_K_LEFT | (key & STB_TEXTEDIT_K_SHIFT); - goto retry; - } + case STB_TEXTEDIT_K_UP: + case STB_TEXTEDIT_K_UP | STB_TEXTEDIT_K_SHIFT: + { + StbFindState find; + StbTexteditRow row; + int i, sel = (key & STB_TEXTEDIT_K_SHIFT) != 0; - if (sel) - stb_textedit_prep_selection_at_cursor(state); - else if (STB_TEXT_HAS_SELECTION(state)) - stb_textedit_move_to_first(state); + if (state->single_line) + { + // on windows, up&down become left&right + key = STB_TEXTEDIT_K_LEFT | (key & STB_TEXTEDIT_K_SHIFT); + goto retry; + } - // compute current position of cursor point - stb_textedit_clamp(str, state); - stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); + if (sel) + stb_textedit_prep_selection_at_cursor(state); + else if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_move_to_first(state); - // can only go up if there's a previous row - if (find.prev_first != find.first_char) { - // now find character position up a row - float goal_x = state->has_preferred_x ? state->preferred_x : find.x; - float x; - state->cursor = find.prev_first; - STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor); - x = row.x0; - for (i=0; i < row.num_chars; ++i) { - float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i); - #ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE - if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE) - break; - #endif - x += dx; - if (x > goal_x) - break; - ++state->cursor; - } - stb_textedit_clamp(str, state); + // compute current position of cursor point + stb_textedit_clamp(str, state); + stb_textedit_find_charpos(&find, str, state->cursor, state->single_line); - state->has_preferred_x = 1; - state->preferred_x = goal_x; + // can only go up if there's a previous row + if (find.prev_first != find.first_char) + { + // now find character position up a row + float goal_x = state->has_preferred_x ? state->preferred_x : find.x; + float x; + state->cursor = find.prev_first; + STB_TEXTEDIT_LAYOUTROW(&row, str, state->cursor); + x = row.x0; + for (i = 0; i < row.num_chars; ++i) + { + float dx = STB_TEXTEDIT_GETWIDTH(str, find.prev_first, i); +#ifdef STB_TEXTEDIT_GETWIDTH_NEWLINE + if (dx == STB_TEXTEDIT_GETWIDTH_NEWLINE) + break; +#endif + x += dx; + if (x > goal_x) + break; + ++state->cursor; + } + stb_textedit_clamp(str, state); - if (sel) - state->select_end = state->cursor; - } - break; - } + state->has_preferred_x = 1; + state->preferred_x = goal_x; - case STB_TEXTEDIT_K_DELETE: - case STB_TEXTEDIT_K_DELETE | STB_TEXTEDIT_K_SHIFT: - if (STB_TEXT_HAS_SELECTION(state)) - stb_textedit_delete_selection(str, state); - else { - int n = STB_TEXTEDIT_STRINGLEN(str); - if (state->cursor < n) - stb_textedit_delete(str, state, state->cursor, 1); - } - state->has_preferred_x = 0; - break; + if (sel) + state->select_end = state->cursor; + } + break; + } + + case STB_TEXTEDIT_K_DELETE: + case STB_TEXTEDIT_K_DELETE | STB_TEXTEDIT_K_SHIFT: + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_delete_selection(str, state); + else + { + int n = STB_TEXTEDIT_STRINGLEN(str); + if (state->cursor < n) + stb_textedit_delete(str, state, state->cursor, 1); + } + state->has_preferred_x = 0; + break; + + case STB_TEXTEDIT_K_BACKSPACE: + case STB_TEXTEDIT_K_BACKSPACE | STB_TEXTEDIT_K_SHIFT: + if (STB_TEXT_HAS_SELECTION(state)) + stb_textedit_delete_selection(str, state); + else + { + stb_textedit_clamp(str, state); + if (state->cursor > 0) + { + stb_textedit_delete(str, state, state->cursor - 1, 1); + --state->cursor; + } + } + state->has_preferred_x = 0; + break; - case STB_TEXTEDIT_K_BACKSPACE: - case STB_TEXTEDIT_K_BACKSPACE | STB_TEXTEDIT_K_SHIFT: - if (STB_TEXT_HAS_SELECTION(state)) - stb_textedit_delete_selection(str, state); - else { - stb_textedit_clamp(str, state); - if (state->cursor > 0) { - stb_textedit_delete(str, state, state->cursor-1, 1); - --state->cursor; - } - } - state->has_preferred_x = 0; - break; - #ifdef STB_TEXTEDIT_K_TEXTSTART2 - case STB_TEXTEDIT_K_TEXTSTART2: + case STB_TEXTEDIT_K_TEXTSTART2: #endif - case STB_TEXTEDIT_K_TEXTSTART: - state->cursor = state->select_start = state->select_end = 0; - state->has_preferred_x = 0; - break; + case STB_TEXTEDIT_K_TEXTSTART: + state->cursor = state->select_start = state->select_end = 0; + state->has_preferred_x = 0; + break; #ifdef STB_TEXTEDIT_K_TEXTEND2 - case STB_TEXTEDIT_K_TEXTEND2: + case STB_TEXTEDIT_K_TEXTEND2: #endif - case STB_TEXTEDIT_K_TEXTEND: - state->cursor = STB_TEXTEDIT_STRINGLEN(str); - state->select_start = state->select_end = 0; - state->has_preferred_x = 0; - break; - + case STB_TEXTEDIT_K_TEXTEND: + state->cursor = STB_TEXTEDIT_STRINGLEN(str); + state->select_start = state->select_end = 0; + state->has_preferred_x = 0; + break; + #ifdef STB_TEXTEDIT_K_TEXTSTART2 - case STB_TEXTEDIT_K_TEXTSTART2 | STB_TEXTEDIT_K_SHIFT: + case STB_TEXTEDIT_K_TEXTSTART2 | STB_TEXTEDIT_K_SHIFT: #endif - case STB_TEXTEDIT_K_TEXTSTART | STB_TEXTEDIT_K_SHIFT: - stb_textedit_prep_selection_at_cursor(state); - state->cursor = state->select_end = 0; - state->has_preferred_x = 0; - break; + case STB_TEXTEDIT_K_TEXTSTART | STB_TEXTEDIT_K_SHIFT: + stb_textedit_prep_selection_at_cursor(state); + state->cursor = state->select_end = 0; + state->has_preferred_x = 0; + break; #ifdef STB_TEXTEDIT_K_TEXTEND2 - case STB_TEXTEDIT_K_TEXTEND2 | STB_TEXTEDIT_K_SHIFT: + case STB_TEXTEDIT_K_TEXTEND2 | STB_TEXTEDIT_K_SHIFT: #endif - case STB_TEXTEDIT_K_TEXTEND | STB_TEXTEDIT_K_SHIFT: - stb_textedit_prep_selection_at_cursor(state); - state->cursor = state->select_end = STB_TEXTEDIT_STRINGLEN(str); - state->has_preferred_x = 0; - break; - + case STB_TEXTEDIT_K_TEXTEND | STB_TEXTEDIT_K_SHIFT: + stb_textedit_prep_selection_at_cursor(state); + state->cursor = state->select_end = STB_TEXTEDIT_STRINGLEN(str); + state->has_preferred_x = 0; + break; #ifdef STB_TEXTEDIT_K_LINESTART2 - case STB_TEXTEDIT_K_LINESTART2: + case STB_TEXTEDIT_K_LINESTART2: #endif - case STB_TEXTEDIT_K_LINESTART: - stb_textedit_clamp(str, state); - stb_textedit_move_to_first(state); - if (state->single_line) - state->cursor = 0; - else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE) - --state->cursor; - state->has_preferred_x = 0; - break; + case STB_TEXTEDIT_K_LINESTART: + stb_textedit_clamp(str, state); + stb_textedit_move_to_first(state); + if (state->single_line) + state->cursor = 0; + else + while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor - 1) != STB_TEXTEDIT_NEWLINE) + --state->cursor; + state->has_preferred_x = 0; + break; #ifdef STB_TEXTEDIT_K_LINEEND2 - case STB_TEXTEDIT_K_LINEEND2: + case STB_TEXTEDIT_K_LINEEND2: #endif - case STB_TEXTEDIT_K_LINEEND: { - int n = STB_TEXTEDIT_STRINGLEN(str); - stb_textedit_clamp(str, state); - stb_textedit_move_to_first(state); - if (state->single_line) - state->cursor = n; - else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE) - ++state->cursor; - state->has_preferred_x = 0; - break; - } + case STB_TEXTEDIT_K_LINEEND: + { + int n = STB_TEXTEDIT_STRINGLEN(str); + stb_textedit_clamp(str, state); + stb_textedit_move_to_first(state); + if (state->single_line) + state->cursor = n; + else + while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE) + ++state->cursor; + state->has_preferred_x = 0; + break; + } #ifdef STB_TEXTEDIT_K_LINESTART2 - case STB_TEXTEDIT_K_LINESTART2 | STB_TEXTEDIT_K_SHIFT: + case STB_TEXTEDIT_K_LINESTART2 | STB_TEXTEDIT_K_SHIFT: #endif - case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT: - stb_textedit_clamp(str, state); - stb_textedit_prep_selection_at_cursor(state); - if (state->single_line) - state->cursor = 0; - else while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) != STB_TEXTEDIT_NEWLINE) - --state->cursor; - state->select_end = state->cursor; - state->has_preferred_x = 0; - break; + case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT: + stb_textedit_clamp(str, state); + stb_textedit_prep_selection_at_cursor(state); + if (state->single_line) + state->cursor = 0; + else + while (state->cursor > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor - 1) != STB_TEXTEDIT_NEWLINE) + --state->cursor; + state->select_end = state->cursor; + state->has_preferred_x = 0; + break; #ifdef STB_TEXTEDIT_K_LINEEND2 - case STB_TEXTEDIT_K_LINEEND2 | STB_TEXTEDIT_K_SHIFT: + case STB_TEXTEDIT_K_LINEEND2 | STB_TEXTEDIT_K_SHIFT: #endif - case STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT: { - int n = STB_TEXTEDIT_STRINGLEN(str); - stb_textedit_clamp(str, state); - stb_textedit_prep_selection_at_cursor(state); - if (state->single_line) - state->cursor = n; - else while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE) - ++state->cursor; - state->select_end = state->cursor; - state->has_preferred_x = 0; - break; - } + case STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT: + { + int n = STB_TEXTEDIT_STRINGLEN(str); + stb_textedit_clamp(str, state); + stb_textedit_prep_selection_at_cursor(state); + if (state->single_line) + state->cursor = n; + else + while (state->cursor < n && STB_TEXTEDIT_GETCHAR(str, state->cursor) != STB_TEXTEDIT_NEWLINE) + ++state->cursor; + state->select_end = state->cursor; + state->has_preferred_x = 0; + break; + } -// @TODO: -// STB_TEXTEDIT_K_PGUP - move cursor up a page -// STB_TEXTEDIT_K_PGDOWN - move cursor down a page - } + // @TODO: + // STB_TEXTEDIT_K_PGUP - move cursor up a page + // STB_TEXTEDIT_K_PGDOWN - move cursor down a page + } } ///////////////////////////////////////////////////////////////////////////// @@ -1062,27 +1102,29 @@ retry: static void stb_textedit_flush_redo(StbUndoState *state) { - state->redo_point = STB_TEXTEDIT_UNDOSTATECOUNT; - state->redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT; + state->redo_point = STB_TEXTEDIT_UNDOSTATECOUNT; + state->redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT; } // discard the oldest entry in the undo list static void stb_textedit_discard_undo(StbUndoState *state) { - if (state->undo_point > 0) { - // if the 0th undo state has characters, clean those up - if (state->undo_rec[0].char_storage >= 0) { - int n = state->undo_rec[0].insert_length, i; - // delete n characters from all other records - state->undo_char_point = state->undo_char_point - (short) n; // vsnet05 - STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) ((size_t)state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE))); - for (i=0; i < state->undo_point; ++i) - if (state->undo_rec[i].char_storage >= 0) - state->undo_rec[i].char_storage = state->undo_rec[i].char_storage - (short) n; // vsnet05 // @OPTIMIZE: get rid of char_storage and infer it - } - --state->undo_point; - STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) ((size_t)state->undo_point*sizeof(state->undo_rec[0]))); - } + if (state->undo_point > 0) + { + // if the 0th undo state has characters, clean those up + if (state->undo_rec[0].char_storage >= 0) + { + int n = state->undo_rec[0].insert_length, i; + // delete n characters from all other records + state->undo_char_point = state->undo_char_point - (short)n; // vsnet05 + STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t)((size_t)state->undo_char_point * sizeof(STB_TEXTEDIT_CHARTYPE))); + for (i = 0; i < state->undo_point; ++i) + if (state->undo_rec[i].char_storage >= 0) + state->undo_rec[i].char_storage = state->undo_rec[i].char_storage - (short)n; // vsnet05 // @OPTIMIZE: get rid of char_storage and infer it + } + --state->undo_point; + STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec + 1, (size_t)((size_t)state->undo_point * sizeof(state->undo_rec[0]))); + } } // discard the oldest entry in the redo list--it's bad if this @@ -1091,232 +1133,251 @@ static void stb_textedit_discard_undo(StbUndoState *state) // fill up even though the undo buffer didn't static void stb_textedit_discard_redo(StbUndoState *state) { - int k = STB_TEXTEDIT_UNDOSTATECOUNT-1; + int k = STB_TEXTEDIT_UNDOSTATECOUNT - 1; - if (state->redo_point <= k) { - // if the k'th undo state has characters, clean those up - if (state->undo_rec[k].char_storage >= 0) { - int n = state->undo_rec[k].insert_length, i; - // delete n characters from all other records - state->redo_char_point = state->redo_char_point + (short) n; // vsnet05 - STB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((size_t)(STB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE))); - for (i=state->redo_point; i < k; ++i) - if (state->undo_rec[i].char_storage >= 0) - state->undo_rec[i].char_storage = state->undo_rec[i].char_storage + (short) n; // vsnet05 - } - STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point, state->undo_rec + state->redo_point-1, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0]))); - ++state->redo_point; - } + if (state->redo_point <= k) + { + // if the k'th undo state has characters, clean those up + if (state->undo_rec[k].char_storage >= 0) + { + int n = state->undo_rec[k].insert_length, i; + // delete n characters from all other records + state->redo_char_point = state->redo_char_point + (short)n; // vsnet05 + STB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point - n, (size_t)((size_t)(STB_TEXTEDIT_UNDOCHARCOUNT - state->redo_char_point) * sizeof(STB_TEXTEDIT_CHARTYPE))); + for (i = state->redo_point; i < k; ++i) + if (state->undo_rec[i].char_storage >= 0) + state->undo_rec[i].char_storage = state->undo_rec[i].char_storage + (short)n; // vsnet05 + } + STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point, state->undo_rec + state->redo_point - 1, (size_t)((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point) * sizeof(state->undo_rec[0]))); + ++state->redo_point; + } } static StbUndoRecord *stb_text_create_undo_record(StbUndoState *state, int numchars) { - // any time we create a new undo record, we discard redo - stb_textedit_flush_redo(state); + // any time we create a new undo record, we discard redo + stb_textedit_flush_redo(state); - // if we have no free records, we have to make room, by sliding the - // existing records down - if (state->undo_point == STB_TEXTEDIT_UNDOSTATECOUNT) - stb_textedit_discard_undo(state); + // if we have no free records, we have to make room, by sliding the + // existing records down + if (state->undo_point == STB_TEXTEDIT_UNDOSTATECOUNT) + stb_textedit_discard_undo(state); - // if the characters to store won't possibly fit in the buffer, we can't undo - if (numchars > STB_TEXTEDIT_UNDOCHARCOUNT) { - state->undo_point = 0; - state->undo_char_point = 0; - return NULL; - } + // if the characters to store won't possibly fit in the buffer, we can't undo + if (numchars > STB_TEXTEDIT_UNDOCHARCOUNT) + { + state->undo_point = 0; + state->undo_char_point = 0; + return NULL; + } - // if we don't have enough free characters in the buffer, we have to make room - while (state->undo_char_point + numchars > STB_TEXTEDIT_UNDOCHARCOUNT) - stb_textedit_discard_undo(state); + // if we don't have enough free characters in the buffer, we have to make room + while (state->undo_char_point + numchars > STB_TEXTEDIT_UNDOCHARCOUNT) + stb_textedit_discard_undo(state); - return &state->undo_rec[state->undo_point++]; + return &state->undo_rec[state->undo_point++]; } static STB_TEXTEDIT_CHARTYPE *stb_text_createundo(StbUndoState *state, int pos, int insert_len, int delete_len) { - StbUndoRecord *r = stb_text_create_undo_record(state, insert_len); - if (r == NULL) - return NULL; + StbUndoRecord *r = stb_text_create_undo_record(state, insert_len); + if (r == NULL) + return NULL; - r->where = pos; - r->insert_length = (short) insert_len; - r->delete_length = (short) delete_len; + r->where = pos; + r->insert_length = (short)insert_len; + r->delete_length = (short)delete_len; - if (insert_len == 0) { - r->char_storage = -1; - return NULL; - } else { - r->char_storage = state->undo_char_point; - state->undo_char_point = state->undo_char_point + (short) insert_len; - return &state->undo_char[r->char_storage]; - } + if (insert_len == 0) + { + r->char_storage = -1; + return NULL; + } + else + { + r->char_storage = state->undo_char_point; + state->undo_char_point = state->undo_char_point + (short)insert_len; + return &state->undo_char[r->char_storage]; + } } static void stb_text_undo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) { - StbUndoState *s = &state->undostate; - StbUndoRecord u, *r; - if (s->undo_point == 0) - return; + StbUndoState *s = &state->undostate; + StbUndoRecord u, *r; + if (s->undo_point == 0) + return; - // we need to do two things: apply the undo record, and create a redo record - u = s->undo_rec[s->undo_point-1]; - r = &s->undo_rec[s->redo_point-1]; - r->char_storage = -1; + // we need to do two things: apply the undo record, and create a redo record + u = s->undo_rec[s->undo_point - 1]; + r = &s->undo_rec[s->redo_point - 1]; + r->char_storage = -1; - r->insert_length = u.delete_length; - r->delete_length = u.insert_length; - r->where = u.where; + r->insert_length = u.delete_length; + r->delete_length = u.insert_length; + r->where = u.where; - if (u.delete_length) { - // if the undo record says to delete characters, then the redo record will - // need to re-insert the characters that get deleted, so we need to store - // them. + if (u.delete_length) + { + // if the undo record says to delete characters, then the redo record will + // need to re-insert the characters that get deleted, so we need to store + // them. - // there are three cases: - // there's enough room to store the characters - // characters stored for *redoing* don't leave room for redo - // characters stored for *undoing* don't leave room for redo - // if the last is true, we have to bail + // there are three cases: + // there's enough room to store the characters + // characters stored for *redoing* don't leave room for redo + // characters stored for *undoing* don't leave room for redo + // if the last is true, we have to bail - if (s->undo_char_point + u.delete_length >= STB_TEXTEDIT_UNDOCHARCOUNT) { - // the undo records take up too much character space; there's no space to store the redo characters - r->insert_length = 0; - } else { - int i; + if (s->undo_char_point + u.delete_length >= STB_TEXTEDIT_UNDOCHARCOUNT) + { + // the undo records take up too much character space; there's no space to store the redo characters + r->insert_length = 0; + } + else + { + int i; - // there's definitely room to store the characters eventually - while (s->undo_char_point + u.delete_length > s->redo_char_point) { - // there's currently not enough room, so discard a redo record - stb_textedit_discard_redo(s); - // should never happen: - if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT) - return; - } - r = &s->undo_rec[s->redo_point-1]; + // there's definitely room to store the characters eventually + while (s->undo_char_point + u.delete_length > s->redo_char_point) + { + // there's currently not enough room, so discard a redo record + stb_textedit_discard_redo(s); + // should never happen: + if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT) + return; + } + r = &s->undo_rec[s->redo_point - 1]; - r->char_storage = s->redo_char_point - u.delete_length; - s->redo_char_point = s->redo_char_point - (short) u.delete_length; + r->char_storage = s->redo_char_point - u.delete_length; + s->redo_char_point = s->redo_char_point - (short)u.delete_length; - // now save the characters - for (i=0; i < u.delete_length; ++i) - s->undo_char[r->char_storage + i] = STB_TEXTEDIT_GETCHAR(str, u.where + i); - } + // now save the characters + for (i = 0; i < u.delete_length; ++i) + s->undo_char[r->char_storage + i] = STB_TEXTEDIT_GETCHAR(str, u.where + i); + } - // now we can carry out the deletion - STB_TEXTEDIT_DELETECHARS(str, u.where, u.delete_length); - } + // now we can carry out the deletion + STB_TEXTEDIT_DELETECHARS(str, u.where, u.delete_length); + } - // check type of recorded action: - if (u.insert_length) { - // easy case: was a deletion, so we need to insert n characters - STB_TEXTEDIT_INSERTCHARS(str, u.where, &s->undo_char[u.char_storage], u.insert_length); - s->undo_char_point -= u.insert_length; - } + // check type of recorded action: + if (u.insert_length) + { + // easy case: was a deletion, so we need to insert n characters + STB_TEXTEDIT_INSERTCHARS(str, u.where, &s->undo_char[u.char_storage], u.insert_length); + s->undo_char_point -= u.insert_length; + } - state->cursor = u.where + u.insert_length; + state->cursor = u.where + u.insert_length; - s->undo_point--; - s->redo_point--; + s->undo_point--; + s->redo_point--; } static void stb_text_redo(STB_TEXTEDIT_STRING *str, STB_TexteditState *state) { - StbUndoState *s = &state->undostate; - StbUndoRecord *u, r; - if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT) - return; + StbUndoState *s = &state->undostate; + StbUndoRecord *u, r; + if (s->redo_point == STB_TEXTEDIT_UNDOSTATECOUNT) + return; - // we need to do two things: apply the redo record, and create an undo record - u = &s->undo_rec[s->undo_point]; - r = s->undo_rec[s->redo_point]; + // we need to do two things: apply the redo record, and create an undo record + u = &s->undo_rec[s->undo_point]; + r = s->undo_rec[s->redo_point]; - // we KNOW there must be room for the undo record, because the redo record - // was derived from an undo record + // we KNOW there must be room for the undo record, because the redo record + // was derived from an undo record - u->delete_length = r.insert_length; - u->insert_length = r.delete_length; - u->where = r.where; - u->char_storage = -1; + u->delete_length = r.insert_length; + u->insert_length = r.delete_length; + u->where = r.where; + u->char_storage = -1; - if (r.delete_length) { - // the redo record requires us to delete characters, so the undo record - // needs to store the characters + if (r.delete_length) + { + // the redo record requires us to delete characters, so the undo record + // needs to store the characters - if (s->undo_char_point + u->insert_length > s->redo_char_point) { - u->insert_length = 0; - u->delete_length = 0; - } else { - int i; - u->char_storage = s->undo_char_point; - s->undo_char_point = s->undo_char_point + u->insert_length; + if (s->undo_char_point + u->insert_length > s->redo_char_point) + { + u->insert_length = 0; + u->delete_length = 0; + } + else + { + int i; + u->char_storage = s->undo_char_point; + s->undo_char_point = s->undo_char_point + u->insert_length; - // now save the characters - for (i=0; i < u->insert_length; ++i) - s->undo_char[u->char_storage + i] = STB_TEXTEDIT_GETCHAR(str, u->where + i); - } + // now save the characters + for (i = 0; i < u->insert_length; ++i) + s->undo_char[u->char_storage + i] = STB_TEXTEDIT_GETCHAR(str, u->where + i); + } - STB_TEXTEDIT_DELETECHARS(str, r.where, r.delete_length); - } + STB_TEXTEDIT_DELETECHARS(str, r.where, r.delete_length); + } - if (r.insert_length) { - // easy case: need to insert n characters - STB_TEXTEDIT_INSERTCHARS(str, r.where, &s->undo_char[r.char_storage], r.insert_length); - s->redo_char_point += r.insert_length; - } + if (r.insert_length) + { + // easy case: need to insert n characters + STB_TEXTEDIT_INSERTCHARS(str, r.where, &s->undo_char[r.char_storage], r.insert_length); + s->redo_char_point += r.insert_length; + } - state->cursor = r.where + r.insert_length; + state->cursor = r.where + r.insert_length; - s->undo_point++; - s->redo_point++; + s->undo_point++; + s->redo_point++; } static void stb_text_makeundo_insert(STB_TexteditState *state, int where, int length) { - stb_text_createundo(&state->undostate, where, 0, length); + stb_text_createundo(&state->undostate, where, 0, length); } static void stb_text_makeundo_delete(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int length) { - int i; - STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0); - if (p) { - for (i=0; i < length; ++i) - p[i] = STB_TEXTEDIT_GETCHAR(str, where+i); - } + int i; + STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, length, 0); + if (p) + { + for (i = 0; i < length; ++i) + p[i] = STB_TEXTEDIT_GETCHAR(str, where + i); + } } static void stb_text_makeundo_replace(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, int where, int old_length, int new_length) { - int i; - STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length); - if (p) { - for (i=0; i < old_length; ++i) - p[i] = STB_TEXTEDIT_GETCHAR(str, where+i); - } + int i; + STB_TEXTEDIT_CHARTYPE *p = stb_text_createundo(&state->undostate, where, old_length, new_length); + if (p) + { + for (i = 0; i < old_length; ++i) + p[i] = STB_TEXTEDIT_GETCHAR(str, where + i); + } } // reset the state to default static void stb_textedit_clear_state(STB_TexteditState *state, int is_single_line) { - state->undostate.undo_point = 0; - state->undostate.undo_char_point = 0; - state->undostate.redo_point = STB_TEXTEDIT_UNDOSTATECOUNT; - state->undostate.redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT; - state->select_end = state->select_start = 0; - state->cursor = 0; - state->has_preferred_x = 0; - state->preferred_x = 0; - state->cursor_at_end_of_line = 0; - state->initialized = 1; - state->single_line = (unsigned char) is_single_line; - state->insert_mode = 0; + state->undostate.undo_point = 0; + state->undostate.undo_char_point = 0; + state->undostate.redo_point = STB_TEXTEDIT_UNDOSTATECOUNT; + state->undostate.redo_char_point = STB_TEXTEDIT_UNDOCHARCOUNT; + state->select_end = state->select_start = 0; + state->cursor = 0; + state->has_preferred_x = 0; + state->preferred_x = 0; + state->cursor_at_end_of_line = 0; + state->initialized = 1; + state->single_line = (unsigned char)is_single_line; + state->insert_mode = 0; } // API initialize static void stb_textedit_initialize_state(STB_TexteditState *state, int is_single_line) { - stb_textedit_clear_state(state, is_single_line); + stb_textedit_clear_state(state, is_single_line); } -#endif//STB_TEXTEDIT_IMPLEMENTATION +#endif //STB_TEXTEDIT_IMPLEMENTATION diff --git a/examples/ThirdPartyLibs/imgui/stb_truetype.h b/examples/ThirdPartyLibs/imgui/stb_truetype.h index f65deb503..2e8b093bb 100644 --- a/examples/ThirdPartyLibs/imgui/stb_truetype.h +++ b/examples/ThirdPartyLibs/imgui/stb_truetype.h @@ -46,7 +46,7 @@ // Rob Loach Cort Stratton // Kenney Phillis Jr. github:oyvindjam // Brian Costabile github:vassvik -// +// // VERSION HISTORY // // 1.19 (2018-02-11) GPOS kerning, STBTT_fmod @@ -206,7 +206,7 @@ // // Advancing for the next character: // Call GlyphHMetrics, and compute 'current_point += SF * advance'. -// +// // // ADVANCED USAGE // @@ -251,7 +251,7 @@ // Curve tesselation 120 LOC \__ 550 LOC Bitmap creation // Bitmap management 100 LOC / // Baked bitmap interface 70 LOC / -// Font name matching & access 150 LOC ---- 150 +// Font name matching & access 150 LOC ---- 150 // C runtime library abstraction 60 LOC ---- 60 // // @@ -344,7 +344,7 @@ int main(int argc, char **argv) } return 0; } -#endif +#endif // // Output: // @@ -358,9 +358,9 @@ int main(int argc, char **argv) // :@@. M@M // @@@o@@@@ // :M@@V:@@. -// +// ////////////////////////////////////////////////////////////////////////////// -// +// // Complete program: print "Hello World!" banner, with bugs // #if 0 @@ -407,7 +407,6 @@ int main(int arg, char **argv) } #endif - ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //// @@ -418,70 +417,70 @@ int main(int arg, char **argv) //// link with the C runtime library. #ifdef STB_TRUETYPE_IMPLEMENTATION - // #define your own (u)stbtt_int8/16/32 before including to override this - #ifndef stbtt_uint8 - typedef unsigned char stbtt_uint8; - typedef signed char stbtt_int8; - typedef unsigned short stbtt_uint16; - typedef signed short stbtt_int16; - typedef unsigned int stbtt_uint32; - typedef signed int stbtt_int32; - #endif +// #define your own (u)stbtt_int8/16/32 before including to override this +#ifndef stbtt_uint8 +typedef unsigned char stbtt_uint8; +typedef signed char stbtt_int8; +typedef unsigned short stbtt_uint16; +typedef signed short stbtt_int16; +typedef unsigned int stbtt_uint32; +typedef signed int stbtt_int32; +#endif - typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1]; - typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1]; +typedef char stbtt__check_size32[sizeof(stbtt_int32) == 4 ? 1 : -1]; +typedef char stbtt__check_size16[sizeof(stbtt_int16) == 2 ? 1 : -1]; - // e.g. #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h - #ifndef STBTT_ifloor - #include - #define STBTT_ifloor(x) ((int) floor(x)) - #define STBTT_iceil(x) ((int) ceil(x)) - #endif +// e.g. #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h +#ifndef STBTT_ifloor +#include +#define STBTT_ifloor(x) ((int)floor(x)) +#define STBTT_iceil(x) ((int)ceil(x)) +#endif - #ifndef STBTT_sqrt - #include - #define STBTT_sqrt(x) sqrt(x) - #define STBTT_pow(x,y) pow(x,y) - #endif +#ifndef STBTT_sqrt +#include +#define STBTT_sqrt(x) sqrt(x) +#define STBTT_pow(x, y) pow(x, y) +#endif - #ifndef STBTT_fmod - #include - #define STBTT_fmod(x,y) fmod(x,y) - #endif +#ifndef STBTT_fmod +#include +#define STBTT_fmod(x, y) fmod(x, y) +#endif - #ifndef STBTT_cos - #include - #define STBTT_cos(x) cos(x) - #define STBTT_acos(x) acos(x) - #endif +#ifndef STBTT_cos +#include +#define STBTT_cos(x) cos(x) +#define STBTT_acos(x) acos(x) +#endif - #ifndef STBTT_fabs - #include - #define STBTT_fabs(x) fabs(x) - #endif +#ifndef STBTT_fabs +#include +#define STBTT_fabs(x) fabs(x) +#endif - // #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h - #ifndef STBTT_malloc - #include - #define STBTT_malloc(x,u) ((void)(u),malloc(x)) - #define STBTT_free(x,u) ((void)(u),free(x)) - #endif +// #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h +#ifndef STBTT_malloc +#include +#define STBTT_malloc(x, u) ((void)(u), malloc(x)) +#define STBTT_free(x, u) ((void)(u), free(x)) +#endif - #ifndef STBTT_assert - #include - #define STBTT_assert(x) assert(x) - #endif +#ifndef STBTT_assert +#include +#define STBTT_assert(x) assert(x) +#endif - #ifndef STBTT_strlen - #include - #define STBTT_strlen(x) strlen(x) - #endif +#ifndef STBTT_strlen +#include +#define STBTT_strlen(x) strlen(x) +#endif - #ifndef STBTT_memcpy - #include - #define STBTT_memcpy memcpy - #define STBTT_memset memset - #endif +#ifndef STBTT_memcpy +#include +#define STBTT_memcpy memcpy +#define STBTT_memset memset +#endif #endif /////////////////////////////////////////////////////////////////////////////// @@ -501,567 +500,584 @@ int main(int arg, char **argv) #endif #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -// private structure -typedef struct -{ - unsigned char *data; - int cursor; - int size; -} stbtt__buf; + // private structure + typedef struct + { + unsigned char *data; + int cursor; + int size; + } stbtt__buf; -////////////////////////////////////////////////////////////////////////////// -// -// TEXTURE BAKING API -// -// If you use this API, you only have to call two functions ever. -// + ////////////////////////////////////////////////////////////////////////////// + // + // TEXTURE BAKING API + // + // If you use this API, you only have to call two functions ever. + // -typedef struct -{ - unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap - float xoff,yoff,xadvance; -} stbtt_bakedchar; + typedef struct + { + unsigned short x0, y0, x1, y1; // coordinates of bbox in bitmap + float xoff, yoff, xadvance; + } stbtt_bakedchar; -STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) - float pixel_height, // height of font in pixels - unsigned char *pixels, int pw, int ph, // bitmap to be filled in - int first_char, int num_chars, // characters to bake - stbtt_bakedchar *chardata); // you allocate this, it's num_chars long -// if return is positive, the first unused row of the bitmap -// if return is negative, returns the negative of the number of characters that fit -// if return is 0, no characters fit and no rows were used -// This uses a very crappy packing. + STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) + float pixel_height, // height of font in pixels + unsigned char *pixels, int pw, int ph, // bitmap to be filled in + int first_char, int num_chars, // characters to bake + stbtt_bakedchar *chardata); // you allocate this, it's num_chars long + // if return is positive, the first unused row of the bitmap + // if return is negative, returns the negative of the number of characters that fit + // if return is 0, no characters fit and no rows were used + // This uses a very crappy packing. -typedef struct -{ - float x0,y0,s0,t0; // top-left - float x1,y1,s1,t1; // bottom-right -} stbtt_aligned_quad; + typedef struct + { + float x0, y0, s0, t0; // top-left + float x1, y1, s1, t1; // bottom-right + } stbtt_aligned_quad; -STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, // same data as above - int char_index, // character to display - float *xpos, float *ypos, // pointers to current position in screen pixel space - stbtt_aligned_quad *q, // output: quad to draw - int opengl_fillrule); // true if opengl fill rule; false if DX9 or earlier -// Call GetBakedQuad with char_index = 'character - first_char', and it -// creates the quad you need to draw and advances the current position. -// -// The coordinate system used assumes y increases downwards. -// -// Characters will extend both above and below the current position; -// see discussion of "BASELINE" above. -// -// It's inefficient; you might want to c&p it and optimize it. + STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, // same data as above + int char_index, // character to display + float *xpos, float *ypos, // pointers to current position in screen pixel space + stbtt_aligned_quad *q, // output: quad to draw + int opengl_fillrule); // true if opengl fill rule; false if DX9 or earlier + // Call GetBakedQuad with char_index = 'character - first_char', and it + // creates the quad you need to draw and advances the current position. + // + // The coordinate system used assumes y increases downwards. + // + // Characters will extend both above and below the current position; + // see discussion of "BASELINE" above. + // + // It's inefficient; you might want to c&p it and optimize it. + ////////////////////////////////////////////////////////////////////////////// + // + // NEW TEXTURE BAKING API + // + // This provides options for packing multiple fonts into one atlas, not + // perfectly but better than nothing. + typedef struct + { + unsigned short x0, y0, x1, y1; // coordinates of bbox in bitmap + float xoff, yoff, xadvance; + float xoff2, yoff2; + } stbtt_packedchar; -////////////////////////////////////////////////////////////////////////////// -// -// NEW TEXTURE BAKING API -// -// This provides options for packing multiple fonts into one atlas, not -// perfectly but better than nothing. - -typedef struct -{ - unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap - float xoff,yoff,xadvance; - float xoff2,yoff2; -} stbtt_packedchar; - -typedef struct stbtt_pack_context stbtt_pack_context; -typedef struct stbtt_fontinfo stbtt_fontinfo; + typedef struct stbtt_pack_context stbtt_pack_context; + typedef struct stbtt_fontinfo stbtt_fontinfo; #ifndef STB_RECT_PACK_VERSION -typedef struct stbrp_rect stbrp_rect; + typedef struct stbrp_rect stbrp_rect; #endif -STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context); -// Initializes a packing context stored in the passed-in stbtt_pack_context. -// Future calls using this context will pack characters into the bitmap passed -// in here: a 1-channel bitmap that is width * height. stride_in_bytes is -// the distance from one row to the next (or 0 to mean they are packed tightly -// together). "padding" is the amount of padding to leave between each -// character (normally you want '1' for bitmaps you'll use as textures with -// bilinear filtering). -// -// Returns 0 on failure, 1 on success. + STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context); + // Initializes a packing context stored in the passed-in stbtt_pack_context. + // Future calls using this context will pack characters into the bitmap passed + // in here: a 1-channel bitmap that is width * height. stride_in_bytes is + // the distance from one row to the next (or 0 to mean they are packed tightly + // together). "padding" is the amount of padding to leave between each + // character (normally you want '1' for bitmaps you'll use as textures with + // bilinear filtering). + // + // Returns 0 on failure, 1 on success. -STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc); -// Cleans up the packing context and frees all memory. + STBTT_DEF void stbtt_PackEnd(stbtt_pack_context *spc); + // Cleans up the packing context and frees all memory. -#define STBTT_POINT_SIZE(x) (-(x)) +#define STBTT_POINT_SIZE(x) (-(x)) -STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, float font_size, - int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range); -// Creates character bitmaps from the font_index'th font found in fontdata (use -// font_index=0 if you don't know what that is). It creates num_chars_in_range -// bitmaps for characters with unicode values starting at first_unicode_char_in_range -// and increasing. Data for how to render them is stored in chardata_for_range; -// pass these to stbtt_GetPackedQuad to get back renderable quads. -// -// font_size is the full height of the character from ascender to descender, -// as computed by stbtt_ScaleForPixelHeight. To use a point size as computed -// by stbtt_ScaleForMappingEmToPixels, wrap the point size in STBTT_POINT_SIZE() -// and pass that result as 'font_size': -// ..., 20 , ... // font max minus min y is 20 pixels tall -// ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall + STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, float font_size, + int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range); + // Creates character bitmaps from the font_index'th font found in fontdata (use + // font_index=0 if you don't know what that is). It creates num_chars_in_range + // bitmaps for characters with unicode values starting at first_unicode_char_in_range + // and increasing. Data for how to render them is stored in chardata_for_range; + // pass these to stbtt_GetPackedQuad to get back renderable quads. + // + // font_size is the full height of the character from ascender to descender, + // as computed by stbtt_ScaleForPixelHeight. To use a point size as computed + // by stbtt_ScaleForMappingEmToPixels, wrap the point size in STBTT_POINT_SIZE() + // and pass that result as 'font_size': + // ..., 20 , ... // font max minus min y is 20 pixels tall + // ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall -typedef struct -{ - float font_size; - int first_unicode_codepoint_in_range; // if non-zero, then the chars are continuous, and this is the first codepoint - int *array_of_unicode_codepoints; // if non-zero, then this is an array of unicode codepoints - int num_chars; - stbtt_packedchar *chardata_for_range; // output - unsigned char h_oversample, v_oversample; // don't set these, they're used internally -} stbtt_pack_range; + typedef struct + { + float font_size; + int first_unicode_codepoint_in_range; // if non-zero, then the chars are continuous, and this is the first codepoint + int *array_of_unicode_codepoints; // if non-zero, then this is an array of unicode codepoints + int num_chars; + stbtt_packedchar *chardata_for_range; // output + unsigned char h_oversample, v_oversample; // don't set these, they're used internally + } stbtt_pack_range; -STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges); -// Creates character bitmaps from multiple ranges of characters stored in -// ranges. This will usually create a better-packed bitmap than multiple -// calls to stbtt_PackFontRange. Note that you can call this multiple -// times within a single PackBegin/PackEnd. + STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges); + // Creates character bitmaps from multiple ranges of characters stored in + // ranges. This will usually create a better-packed bitmap than multiple + // calls to stbtt_PackFontRange. Note that you can call this multiple + // times within a single PackBegin/PackEnd. -STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample); -// Oversampling a font increases the quality by allowing higher-quality subpixel -// positioning, and is especially valuable at smaller text sizes. -// -// This function sets the amount of oversampling for all following calls to -// stbtt_PackFontRange(s) or stbtt_PackFontRangesGatherRects for a given -// pack context. The default (no oversampling) is achieved by h_oversample=1 -// and v_oversample=1. The total number of pixels required is -// h_oversample*v_oversample larger than the default; for example, 2x2 -// oversampling requires 4x the storage of 1x1. For best results, render -// oversampled textures with bilinear filtering. Look at the readme in -// stb/tests/oversample for information about oversampled fonts -// -// To use with PackFontRangesGather etc., you must set it before calls -// call to PackFontRangesGatherRects. + STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample); + // Oversampling a font increases the quality by allowing higher-quality subpixel + // positioning, and is especially valuable at smaller text sizes. + // + // This function sets the amount of oversampling for all following calls to + // stbtt_PackFontRange(s) or stbtt_PackFontRangesGatherRects for a given + // pack context. The default (no oversampling) is achieved by h_oversample=1 + // and v_oversample=1. The total number of pixels required is + // h_oversample*v_oversample larger than the default; for example, 2x2 + // oversampling requires 4x the storage of 1x1. For best results, render + // oversampled textures with bilinear filtering. Look at the readme in + // stb/tests/oversample for information about oversampled fonts + // + // To use with PackFontRangesGather etc., you must set it before calls + // call to PackFontRangesGatherRects. -STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, // same data as above - int char_index, // character to display - float *xpos, float *ypos, // pointers to current position in screen pixel space - stbtt_aligned_quad *q, // output: quad to draw - int align_to_integer); + STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, // same data as above + int char_index, // character to display + float *xpos, float *ypos, // pointers to current position in screen pixel space + stbtt_aligned_quad *q, // output: quad to draw + int align_to_integer); -STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); -STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects); -STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); -// Calling these functions in sequence is roughly equivalent to calling -// stbtt_PackFontRanges(). If you more control over the packing of multiple -// fonts, or if you want to pack custom data into a font texture, take a look -// at the source to of stbtt_PackFontRanges() and create a custom version -// using these functions, e.g. call GatherRects multiple times, -// building up a single array of rects, then call PackRects once, -// then call RenderIntoRects repeatedly. This may result in a -// better packing than calling PackFontRanges multiple times -// (or it may not). + STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); + STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects); + STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects); + // Calling these functions in sequence is roughly equivalent to calling + // stbtt_PackFontRanges(). If you more control over the packing of multiple + // fonts, or if you want to pack custom data into a font texture, take a look + // at the source to of stbtt_PackFontRanges() and create a custom version + // using these functions, e.g. call GatherRects multiple times, + // building up a single array of rects, then call PackRects once, + // then call RenderIntoRects repeatedly. This may result in a + // better packing than calling PackFontRanges multiple times + // (or it may not). -// this is an opaque structure that you shouldn't mess with which holds -// all the context needed from PackBegin to PackEnd. -struct stbtt_pack_context { - void *user_allocator_context; - void *pack_info; - int width; - int height; - int stride_in_bytes; - int padding; - unsigned int h_oversample, v_oversample; - unsigned char *pixels; - void *nodes; -}; + // this is an opaque structure that you shouldn't mess with which holds + // all the context needed from PackBegin to PackEnd. + struct stbtt_pack_context + { + void *user_allocator_context; + void *pack_info; + int width; + int height; + int stride_in_bytes; + int padding; + unsigned int h_oversample, v_oversample; + unsigned char *pixels; + void *nodes; + }; -////////////////////////////////////////////////////////////////////////////// -// -// FONT LOADING -// -// + ////////////////////////////////////////////////////////////////////////////// + // + // FONT LOADING + // + // -STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data); -// This function will determine the number of fonts in a font file. TrueType -// collection (.ttc) files may contain multiple fonts, while TrueType font -// (.ttf) files only contain one font. The number of fonts can be used for -// indexing with the previous function where the index is between zero and one -// less than the total fonts. If an error occurs, -1 is returned. + STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data); + // This function will determine the number of fonts in a font file. TrueType + // collection (.ttc) files may contain multiple fonts, while TrueType font + // (.ttf) files only contain one font. The number of fonts can be used for + // indexing with the previous function where the index is between zero and one + // less than the total fonts. If an error occurs, -1 is returned. -STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index); -// Each .ttf/.ttc file may have more than one font. Each font has a sequential -// index number starting from 0. Call this function to get the font offset for -// a given index; it returns -1 if the index is out of range. A regular .ttf -// file will only define one font and it always be at offset 0, so it will -// return '0' for index 0, and -1 for all other indices. + STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index); + // Each .ttf/.ttc file may have more than one font. Each font has a sequential + // index number starting from 0. Call this function to get the font offset for + // a given index; it returns -1 if the index is out of range. A regular .ttf + // file will only define one font and it always be at offset 0, so it will + // return '0' for index 0, and -1 for all other indices. -// The following structure is defined publically so you can declare one on -// the stack or as a global or etc, but you should treat it as opaque. -struct stbtt_fontinfo -{ - void * userdata; - unsigned char * data; // pointer to .ttf file - int fontstart; // offset of start of font + // The following structure is defined publically so you can declare one on + // the stack or as a global or etc, but you should treat it as opaque. + struct stbtt_fontinfo + { + void *userdata; + unsigned char *data; // pointer to .ttf file + int fontstart; // offset of start of font - int numGlyphs; // number of glyphs, needed for range checking + int numGlyphs; // number of glyphs, needed for range checking - int loca,head,glyf,hhea,hmtx,kern,gpos; // table locations as offset from start of .ttf - int index_map; // a cmap mapping for our chosen character encoding - int indexToLocFormat; // format needed to map from glyph index to glyph + int loca, head, glyf, hhea, hmtx, kern, gpos; // table locations as offset from start of .ttf + int index_map; // a cmap mapping for our chosen character encoding + int indexToLocFormat; // format needed to map from glyph index to glyph - stbtt__buf cff; // cff font data - stbtt__buf charstrings; // the charstring index - stbtt__buf gsubrs; // global charstring subroutines index - stbtt__buf subrs; // private charstring subroutines index - stbtt__buf fontdicts; // array of font dicts - stbtt__buf fdselect; // map from glyph to fontdict -}; + stbtt__buf cff; // cff font data + stbtt__buf charstrings; // the charstring index + stbtt__buf gsubrs; // global charstring subroutines index + stbtt__buf subrs; // private charstring subroutines index + stbtt__buf fontdicts; // array of font dicts + stbtt__buf fdselect; // map from glyph to fontdict + }; -STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset); -// Given an offset into the file that defines a font, this function builds -// the necessary cached info for the rest of the system. You must allocate -// the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't -// need to do anything special to free it, because the contents are pure -// value data with no additional data structures. Returns 0 on failure. + STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset); + // Given an offset into the file that defines a font, this function builds + // the necessary cached info for the rest of the system. You must allocate + // the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't + // need to do anything special to free it, because the contents are pure + // value data with no additional data structures. Returns 0 on failure. + ////////////////////////////////////////////////////////////////////////////// + // + // CHARACTER TO GLYPH-INDEX CONVERSIOn -////////////////////////////////////////////////////////////////////////////// -// -// CHARACTER TO GLYPH-INDEX CONVERSIOn + STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint); + // If you're going to perform multiple operations on the same character + // and you want a speed-up, call this function with the character you're + // going to process, then use glyph-based functions instead of the + // codepoint-based functions. -STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint); -// If you're going to perform multiple operations on the same character -// and you want a speed-up, call this function with the character you're -// going to process, then use glyph-based functions instead of the -// codepoint-based functions. + ////////////////////////////////////////////////////////////////////////////// + // + // CHARACTER PROPERTIES + // + STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels); + // computes a scale factor to produce a font whose "height" is 'pixels' tall. + // Height is measured as the distance from the highest ascender to the lowest + // descender; in other words, it's equivalent to calling stbtt_GetFontVMetrics + // and computing: + // scale = pixels / (ascent - descent) + // so if you prefer to measure height by the ascent only, use a similar calculation. -////////////////////////////////////////////////////////////////////////////// -// -// CHARACTER PROPERTIES -// + STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels); + // computes a scale factor to produce a font whose EM size is mapped to + // 'pixels' tall. This is probably what traditional APIs compute, but + // I'm not positive. -STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels); -// computes a scale factor to produce a font whose "height" is 'pixels' tall. -// Height is measured as the distance from the highest ascender to the lowest -// descender; in other words, it's equivalent to calling stbtt_GetFontVMetrics -// and computing: -// scale = pixels / (ascent - descent) -// so if you prefer to measure height by the ascent only, use a similar calculation. + STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap); + // ascent is the coordinate above the baseline the font extends; descent + // is the coordinate below the baseline the font extends (i.e. it is typically negative) + // lineGap is the spacing between one row's descent and the next row's ascent... + // so you should advance the vertical position by "*ascent - *descent + *lineGap" + // these are expressed in unscaled coordinates, so you must multiply by + // the scale factor for a given size -STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels); -// computes a scale factor to produce a font whose EM size is mapped to -// 'pixels' tall. This is probably what traditional APIs compute, but -// I'm not positive. + STBTT_DEF int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap); + // analogous to GetFontVMetrics, but returns the "typographic" values from the OS/2 + // table (specific to MS/Windows TTF files). + // + // Returns 1 on success (table present), 0 on failure. -STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap); -// ascent is the coordinate above the baseline the font extends; descent -// is the coordinate below the baseline the font extends (i.e. it is typically negative) -// lineGap is the spacing between one row's descent and the next row's ascent... -// so you should advance the vertical position by "*ascent - *descent + *lineGap" -// these are expressed in unscaled coordinates, so you must multiply by -// the scale factor for a given size + STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1); + // the bounding box around all possible characters -STBTT_DEF int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap); -// analogous to GetFontVMetrics, but returns the "typographic" values from the OS/2 -// table (specific to MS/Windows TTF files). -// -// Returns 1 on success (table present), 0 on failure. + STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing); + // leftSideBearing is the offset from the current horizontal position to the left edge of the character + // advanceWidth is the offset from the current horizontal position to the next horizontal position + // these are expressed in unscaled coordinates -STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1); -// the bounding box around all possible characters + STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2); + // an additional amount to add to the 'advance' value between ch1 and ch2 -STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing); -// leftSideBearing is the offset from the current horizontal position to the left edge of the character -// advanceWidth is the offset from the current horizontal position to the next horizontal position -// these are expressed in unscaled coordinates + STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1); + // Gets the bounding box of the visible part of the glyph, in unscaled coordinates -STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2); -// an additional amount to add to the 'advance' value between ch1 and ch2 + STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing); + STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2); + STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); + // as above, but takes one or more glyph indices for greater efficiency -STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1); -// Gets the bounding box of the visible part of the glyph, in unscaled coordinates + ////////////////////////////////////////////////////////////////////////////// + // + // GLYPH SHAPES (you probably don't need these, but they have to go before + // the bitmaps for C declaration-order reasons) + // -STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing); -STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2); -STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); -// as above, but takes one or more glyph indices for greater efficiency - - -////////////////////////////////////////////////////////////////////////////// -// -// GLYPH SHAPES (you probably don't need these, but they have to go before -// the bitmaps for C declaration-order reasons) -// - -#ifndef STBTT_vmove // you can predefine these to use different values (but why?) - enum { - STBTT_vmove=1, - STBTT_vline, - STBTT_vcurve, - STBTT_vcubic - }; +#ifndef STBTT_vmove // you can predefine these to use different values (but why?) + enum + { + STBTT_vmove = 1, + STBTT_vline, + STBTT_vcurve, + STBTT_vcubic + }; #endif -#ifndef stbtt_vertex // you can predefine this to use different values - // (we share this with other code at RAD) - #define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file - typedef struct - { - stbtt_vertex_type x,y,cx,cy,cx1,cy1; - unsigned char type,padding; - } stbtt_vertex; +#ifndef stbtt_vertex // you can predefine this to use different values \ + // (we share this with other code at RAD) +#define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file + typedef struct + { + stbtt_vertex_type x, y, cx, cy, cx1, cy1; + unsigned char type, padding; + } stbtt_vertex; #endif -STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index); -// returns non-zero if nothing is drawn for this glyph + STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index); + // returns non-zero if nothing is drawn for this glyph -STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices); -STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices); -// returns # of vertices and fills *vertices with the pointer to them -// these are expressed in "unscaled" coordinates -// -// The shape is a series of countours. Each one starts with -// a STBTT_moveto, then consists of a series of mixed -// STBTT_lineto and STBTT_curveto segments. A lineto -// draws a line from previous endpoint to its x,y; a curveto -// draws a quadratic bezier from previous endpoint to -// its x,y, using cx,cy as the bezier control point. + STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices); + STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices); + // returns # of vertices and fills *vertices with the pointer to them + // these are expressed in "unscaled" coordinates + // + // The shape is a series of countours. Each one starts with + // a STBTT_moveto, then consists of a series of mixed + // STBTT_lineto and STBTT_curveto segments. A lineto + // draws a line from previous endpoint to its x,y; a curveto + // draws a quadratic bezier from previous endpoint to + // its x,y, using cx,cy as the bezier control point. -STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices); -// frees the data allocated above + STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices); + // frees the data allocated above -////////////////////////////////////////////////////////////////////////////// -// -// BITMAP RENDERING -// + ////////////////////////////////////////////////////////////////////////////// + // + // BITMAP RENDERING + // -STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata); -// frees the bitmap allocated below + STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata); + // frees the bitmap allocated below -STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff); -// allocates a large-enough single-channel 8bpp bitmap and renders the -// specified character/glyph at the specified scale into it, with -// antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque). -// *width & *height are filled out with the width & height of the bitmap, -// which is stored left-to-right, top-to-bottom. -// -// xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap + STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff); + // allocates a large-enough single-channel 8bpp bitmap and renders the + // specified character/glyph at the specified scale into it, with + // antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque). + // *width & *height are filled out with the width & height of the bitmap, + // which is stored left-to-right, top-to-bottom. + // + // xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap -STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff); -// the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel -// shift for the character + STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff); + // the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel + // shift for the character -STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint); -// the same as stbtt_GetCodepointBitmap, but you pass in storage for the bitmap -// in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap -// is clipped to out_w/out_h bytes. Call stbtt_GetCodepointBitmapBox to get the -// width and height and positioning info for it first. + STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint); + // the same as stbtt_GetCodepointBitmap, but you pass in storage for the bitmap + // in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap + // is clipped to out_w/out_h bytes. Call stbtt_GetCodepointBitmapBox to get the + // width and height and positioning info for it first. -STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint); -// same as stbtt_MakeCodepointBitmap, but you can specify a subpixel -// shift for the character + STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint); + // same as stbtt_MakeCodepointBitmap, but you can specify a subpixel + // shift for the character -STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int codepoint); -// same as stbtt_MakeCodepointBitmapSubpixel, but prefiltering -// is performed (see stbtt_PackSetOversampling) + STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int codepoint); + // same as stbtt_MakeCodepointBitmapSubpixel, but prefiltering + // is performed (see stbtt_PackSetOversampling) -STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); -// get the bbox of the bitmap centered around the glyph origin; so the -// bitmap width is ix1-ix0, height is iy1-iy0, and location to place -// the bitmap top left is (leftSideBearing*scale,iy0). -// (Note that the bitmap uses y-increases-down, but the shape uses -// y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.) + STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); + // get the bbox of the bitmap centered around the glyph origin; so the + // bitmap width is ix1-ix0, height is iy1-iy0, and location to place + // the bitmap top left is (leftSideBearing*scale,iy0). + // (Note that the bitmap uses y-increases-down, but the shape uses + // y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.) -STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); -// same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel -// shift for the character + STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); + // same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel + // shift for the character -// the following functions are equivalent to the above functions, but operate -// on glyph indices instead of Unicode codepoints (for efficiency) -STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff); -STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff); -STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph); -STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph); -STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int glyph); -STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); -STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); + // the following functions are equivalent to the above functions, but operate + // on glyph indices instead of Unicode codepoints (for efficiency) + STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff); + STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff); + STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph); + STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph); + STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int glyph); + STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); + STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); + // @TODO: don't expose this structure + typedef struct + { + int w, h, stride; + unsigned char *pixels; + } stbtt__bitmap; -// @TODO: don't expose this structure -typedef struct -{ - int w,h,stride; - unsigned char *pixels; -} stbtt__bitmap; + // rasterize a shape with quadratic beziers into a bitmap + STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, // 1-channel bitmap to draw into + float flatness_in_pixels, // allowable error of curve in pixels + stbtt_vertex *vertices, // array of vertices defining shape + int num_verts, // number of vertices in above array + float scale_x, float scale_y, // scale applied to input vertices + float shift_x, float shift_y, // translation applied to input vertices + int x_off, int y_off, // another translation applied to input + int invert, // if non-zero, vertically flip shape + void *userdata); // context for to STBTT_MALLOC -// rasterize a shape with quadratic beziers into a bitmap -STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, // 1-channel bitmap to draw into - float flatness_in_pixels, // allowable error of curve in pixels - stbtt_vertex *vertices, // array of vertices defining shape - int num_verts, // number of vertices in above array - float scale_x, float scale_y, // scale applied to input vertices - float shift_x, float shift_y, // translation applied to input vertices - int x_off, int y_off, // another translation applied to input - int invert, // if non-zero, vertically flip shape - void *userdata); // context for to STBTT_MALLOC + ////////////////////////////////////////////////////////////////////////////// + // + // Signed Distance Function (or Field) rendering -////////////////////////////////////////////////////////////////////////////// -// -// Signed Distance Function (or Field) rendering + STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata); + // frees the SDF bitmap allocated below -STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata); -// frees the SDF bitmap allocated below + STBTT_DEF unsigned char *stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float scale, int glyph, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff); + STBTT_DEF unsigned char *stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff); + // These functions compute a discretized SDF field for a single character, suitable for storing + // in a single-channel texture, sampling with bilinear filtering, and testing against + // larger than some threshhold to produce scalable fonts. + // info -- the font + // scale -- controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap + // glyph/codepoint -- the character to generate the SDF for + // padding -- extra "pixels" around the character which are filled with the distance to the character (not 0), + // which allows effects like bit outlines + // onedge_value -- value 0-255 to test the SDF against to reconstruct the character (i.e. the isocontour of the character) + // pixel_dist_scale -- what value the SDF should increase by when moving one SDF "pixel" away from the edge (on the 0..255 scale) + // if positive, > onedge_value is inside; if negative, < onedge_value is inside + // width,height -- output height & width of the SDF bitmap (including padding) + // xoff,yoff -- output origin of the character + // return value -- a 2D array of bytes 0..255, width*height in size + // + // pixel_dist_scale & onedge_value are a scale & bias that allows you to make + // optimal use of the limited 0..255 for your application, trading off precision + // and special effects. SDF values outside the range 0..255 are clamped to 0..255. + // + // Example: + // scale = stbtt_ScaleForPixelHeight(22) + // padding = 5 + // onedge_value = 180 + // pixel_dist_scale = 180/5.0 = 36.0 + // + // This will create an SDF bitmap in which the character is about 22 pixels + // high but the whole bitmap is about 22+5+5=32 pixels high. To produce a filled + // shape, sample the SDF at each pixel and fill the pixel if the SDF value + // is greater than or equal to 180/255. (You'll actually want to antialias, + // which is beyond the scope of this example.) Additionally, you can compute + // offset outlines (e.g. to stroke the character border inside & outside, + // or only outside). For example, to fill outside the character up to 3 SDF + // pixels, you would compare against (180-36.0*3)/255 = 72/255. The above + // choice of variables maps a range from 5 pixels outside the shape to + // 2 pixels inside the shape to 0..255; this is intended primarily for apply + // outside effects only (the interior range is needed to allow proper + // antialiasing of the font at *smaller* sizes) + // + // The function computes the SDF analytically at each SDF pixel, not by e.g. + // building a higher-res bitmap and approximating it. In theory the quality + // should be as high as possible for an SDF of this size & representation, but + // unclear if this is true in practice (perhaps building a higher-res bitmap + // and computing from that can allow drop-out prevention). + // + // The algorithm has not been optimized at all, so expect it to be slow + // if computing lots of characters or very large sizes. -STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float scale, int glyph, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff); -STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff); -// These functions compute a discretized SDF field for a single character, suitable for storing -// in a single-channel texture, sampling with bilinear filtering, and testing against -// larger than some threshhold to produce scalable fonts. -// info -- the font -// scale -- controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap -// glyph/codepoint -- the character to generate the SDF for -// padding -- extra "pixels" around the character which are filled with the distance to the character (not 0), -// which allows effects like bit outlines -// onedge_value -- value 0-255 to test the SDF against to reconstruct the character (i.e. the isocontour of the character) -// pixel_dist_scale -- what value the SDF should increase by when moving one SDF "pixel" away from the edge (on the 0..255 scale) -// if positive, > onedge_value is inside; if negative, < onedge_value is inside -// width,height -- output height & width of the SDF bitmap (including padding) -// xoff,yoff -- output origin of the character -// return value -- a 2D array of bytes 0..255, width*height in size -// -// pixel_dist_scale & onedge_value are a scale & bias that allows you to make -// optimal use of the limited 0..255 for your application, trading off precision -// and special effects. SDF values outside the range 0..255 are clamped to 0..255. -// -// Example: -// scale = stbtt_ScaleForPixelHeight(22) -// padding = 5 -// onedge_value = 180 -// pixel_dist_scale = 180/5.0 = 36.0 -// -// This will create an SDF bitmap in which the character is about 22 pixels -// high but the whole bitmap is about 22+5+5=32 pixels high. To produce a filled -// shape, sample the SDF at each pixel and fill the pixel if the SDF value -// is greater than or equal to 180/255. (You'll actually want to antialias, -// which is beyond the scope of this example.) Additionally, you can compute -// offset outlines (e.g. to stroke the character border inside & outside, -// or only outside). For example, to fill outside the character up to 3 SDF -// pixels, you would compare against (180-36.0*3)/255 = 72/255. The above -// choice of variables maps a range from 5 pixels outside the shape to -// 2 pixels inside the shape to 0..255; this is intended primarily for apply -// outside effects only (the interior range is needed to allow proper -// antialiasing of the font at *smaller* sizes) -// -// The function computes the SDF analytically at each SDF pixel, not by e.g. -// building a higher-res bitmap and approximating it. In theory the quality -// should be as high as possible for an SDF of this size & representation, but -// unclear if this is true in practice (perhaps building a higher-res bitmap -// and computing from that can allow drop-out prevention). -// -// The algorithm has not been optimized at all, so expect it to be slow -// if computing lots of characters or very large sizes. + ////////////////////////////////////////////////////////////////////////////// + // + // Finding the right font... + // + // You should really just solve this offline, keep your own tables + // of what font is what, and don't try to get it out of the .ttf file. + // That's because getting it out of the .ttf file is really hard, because + // the names in the file can appear in many possible encodings, in many + // possible languages, and e.g. if you need a case-insensitive comparison, + // the details of that depend on the encoding & language in a complex way + // (actually underspecified in truetype, but also gigantic). + // + // But you can use the provided functions in two possible ways: + // stbtt_FindMatchingFont() will use *case-sensitive* comparisons on + // unicode-encoded names to try to find the font you want; + // you can run this before calling stbtt_InitFont() + // + // stbtt_GetFontNameString() lets you get any of the various strings + // from the file yourself and do your own comparisons on them. + // You have to have called stbtt_InitFont() first. - - -////////////////////////////////////////////////////////////////////////////// -// -// Finding the right font... -// -// You should really just solve this offline, keep your own tables -// of what font is what, and don't try to get it out of the .ttf file. -// That's because getting it out of the .ttf file is really hard, because -// the names in the file can appear in many possible encodings, in many -// possible languages, and e.g. if you need a case-insensitive comparison, -// the details of that depend on the encoding & language in a complex way -// (actually underspecified in truetype, but also gigantic). -// -// But you can use the provided functions in two possible ways: -// stbtt_FindMatchingFont() will use *case-sensitive* comparisons on -// unicode-encoded names to try to find the font you want; -// you can run this before calling stbtt_InitFont() -// -// stbtt_GetFontNameString() lets you get any of the various strings -// from the file yourself and do your own comparisons on them. -// You have to have called stbtt_InitFont() first. - - -STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags); + STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags); // returns the offset (not index) of the font that matches, or -1 if none // if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold". // if you use any other flag, use a font name like "Arial"; this checks // the 'macStyle' header field; i don't know if fonts set this consistently -#define STBTT_MACSTYLE_DONTCARE 0 -#define STBTT_MACSTYLE_BOLD 1 -#define STBTT_MACSTYLE_ITALIC 2 -#define STBTT_MACSTYLE_UNDERSCORE 4 -#define STBTT_MACSTYLE_NONE 8 // <= not same as 0, this makes us check the bitfield is 0 +#define STBTT_MACSTYLE_DONTCARE 0 +#define STBTT_MACSTYLE_BOLD 1 +#define STBTT_MACSTYLE_ITALIC 2 +#define STBTT_MACSTYLE_UNDERSCORE 4 +#define STBTT_MACSTYLE_NONE 8 // <= not same as 0, this makes us check the bitfield is 0 -STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2); -// returns 1/0 whether the first string interpreted as utf8 is identical to -// the second string interpreted as big-endian utf16... useful for strings from next func + STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2); + // returns 1/0 whether the first string interpreted as utf8 is identical to + // the second string interpreted as big-endian utf16... useful for strings from next func -STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID); -// returns the string (which may be big-endian double byte, e.g. for unicode) -// and puts the length in bytes in *length. -// -// some of the values for the IDs are below; for more see the truetype spec: -// http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html -// http://www.microsoft.com/typography/otspec/name.htm + STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID); + // returns the string (which may be big-endian double byte, e.g. for unicode) + // and puts the length in bytes in *length. + // + // some of the values for the IDs are below; for more see the truetype spec: + // http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html + // http://www.microsoft.com/typography/otspec/name.htm -enum { // platformID - STBTT_PLATFORM_ID_UNICODE =0, - STBTT_PLATFORM_ID_MAC =1, - STBTT_PLATFORM_ID_ISO =2, - STBTT_PLATFORM_ID_MICROSOFT =3 -}; + enum + { // platformID + STBTT_PLATFORM_ID_UNICODE = 0, + STBTT_PLATFORM_ID_MAC = 1, + STBTT_PLATFORM_ID_ISO = 2, + STBTT_PLATFORM_ID_MICROSOFT = 3 + }; -enum { // encodingID for STBTT_PLATFORM_ID_UNICODE - STBTT_UNICODE_EID_UNICODE_1_0 =0, - STBTT_UNICODE_EID_UNICODE_1_1 =1, - STBTT_UNICODE_EID_ISO_10646 =2, - STBTT_UNICODE_EID_UNICODE_2_0_BMP=3, - STBTT_UNICODE_EID_UNICODE_2_0_FULL=4 -}; + enum + { // encodingID for STBTT_PLATFORM_ID_UNICODE + STBTT_UNICODE_EID_UNICODE_1_0 = 0, + STBTT_UNICODE_EID_UNICODE_1_1 = 1, + STBTT_UNICODE_EID_ISO_10646 = 2, + STBTT_UNICODE_EID_UNICODE_2_0_BMP = 3, + STBTT_UNICODE_EID_UNICODE_2_0_FULL = 4 + }; -enum { // encodingID for STBTT_PLATFORM_ID_MICROSOFT - STBTT_MS_EID_SYMBOL =0, - STBTT_MS_EID_UNICODE_BMP =1, - STBTT_MS_EID_SHIFTJIS =2, - STBTT_MS_EID_UNICODE_FULL =10 -}; + enum + { // encodingID for STBTT_PLATFORM_ID_MICROSOFT + STBTT_MS_EID_SYMBOL = 0, + STBTT_MS_EID_UNICODE_BMP = 1, + STBTT_MS_EID_SHIFTJIS = 2, + STBTT_MS_EID_UNICODE_FULL = 10 + }; -enum { // encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes - STBTT_MAC_EID_ROMAN =0, STBTT_MAC_EID_ARABIC =4, - STBTT_MAC_EID_JAPANESE =1, STBTT_MAC_EID_HEBREW =5, - STBTT_MAC_EID_CHINESE_TRAD =2, STBTT_MAC_EID_GREEK =6, - STBTT_MAC_EID_KOREAN =3, STBTT_MAC_EID_RUSSIAN =7 -}; + enum + { // encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes + STBTT_MAC_EID_ROMAN = 0, + STBTT_MAC_EID_ARABIC = 4, + STBTT_MAC_EID_JAPANESE = 1, + STBTT_MAC_EID_HEBREW = 5, + STBTT_MAC_EID_CHINESE_TRAD = 2, + STBTT_MAC_EID_GREEK = 6, + STBTT_MAC_EID_KOREAN = 3, + STBTT_MAC_EID_RUSSIAN = 7 + }; -enum { // languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID... - // problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs - STBTT_MS_LANG_ENGLISH =0x0409, STBTT_MS_LANG_ITALIAN =0x0410, - STBTT_MS_LANG_CHINESE =0x0804, STBTT_MS_LANG_JAPANESE =0x0411, - STBTT_MS_LANG_DUTCH =0x0413, STBTT_MS_LANG_KOREAN =0x0412, - STBTT_MS_LANG_FRENCH =0x040c, STBTT_MS_LANG_RUSSIAN =0x0419, - STBTT_MS_LANG_GERMAN =0x0407, STBTT_MS_LANG_SPANISH =0x0409, - STBTT_MS_LANG_HEBREW =0x040d, STBTT_MS_LANG_SWEDISH =0x041D -}; + enum + { // languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID... + // problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs + STBTT_MS_LANG_ENGLISH = 0x0409, + STBTT_MS_LANG_ITALIAN = 0x0410, + STBTT_MS_LANG_CHINESE = 0x0804, + STBTT_MS_LANG_JAPANESE = 0x0411, + STBTT_MS_LANG_DUTCH = 0x0413, + STBTT_MS_LANG_KOREAN = 0x0412, + STBTT_MS_LANG_FRENCH = 0x040c, + STBTT_MS_LANG_RUSSIAN = 0x0419, + STBTT_MS_LANG_GERMAN = 0x0407, + STBTT_MS_LANG_SPANISH = 0x0409, + STBTT_MS_LANG_HEBREW = 0x040d, + STBTT_MS_LANG_SWEDISH = 0x041D + }; -enum { // languageID for STBTT_PLATFORM_ID_MAC - STBTT_MAC_LANG_ENGLISH =0 , STBTT_MAC_LANG_JAPANESE =11, - STBTT_MAC_LANG_ARABIC =12, STBTT_MAC_LANG_KOREAN =23, - STBTT_MAC_LANG_DUTCH =4 , STBTT_MAC_LANG_RUSSIAN =32, - STBTT_MAC_LANG_FRENCH =1 , STBTT_MAC_LANG_SPANISH =6 , - STBTT_MAC_LANG_GERMAN =2 , STBTT_MAC_LANG_SWEDISH =5 , - STBTT_MAC_LANG_HEBREW =10, STBTT_MAC_LANG_CHINESE_SIMPLIFIED =33, - STBTT_MAC_LANG_ITALIAN =3 , STBTT_MAC_LANG_CHINESE_TRAD =19 -}; + enum + { // languageID for STBTT_PLATFORM_ID_MAC + STBTT_MAC_LANG_ENGLISH = 0, + STBTT_MAC_LANG_JAPANESE = 11, + STBTT_MAC_LANG_ARABIC = 12, + STBTT_MAC_LANG_KOREAN = 23, + STBTT_MAC_LANG_DUTCH = 4, + STBTT_MAC_LANG_RUSSIAN = 32, + STBTT_MAC_LANG_FRENCH = 1, + STBTT_MAC_LANG_SPANISH = 6, + STBTT_MAC_LANG_GERMAN = 2, + STBTT_MAC_LANG_SWEDISH = 5, + STBTT_MAC_LANG_HEBREW = 10, + STBTT_MAC_LANG_CHINESE_SIMPLIFIED = 33, + STBTT_MAC_LANG_ITALIAN = 3, + STBTT_MAC_LANG_CHINESE_TRAD = 19 + }; #ifdef __cplusplus } #endif -#endif // __STB_INCLUDE_STB_TRUETYPE_H__ +#endif // __STB_INCLUDE_STB_TRUETYPE_H__ /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// @@ -1073,23 +1089,23 @@ enum { // languageID for STBTT_PLATFORM_ID_MAC #ifdef STB_TRUETYPE_IMPLEMENTATION #ifndef STBTT_MAX_OVERSAMPLE -#define STBTT_MAX_OVERSAMPLE 8 +#define STBTT_MAX_OVERSAMPLE 8 #endif #if STBTT_MAX_OVERSAMPLE > 255 #error "STBTT_MAX_OVERSAMPLE cannot be > 255" #endif -typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE-1)) == 0 ? 1 : -1]; +typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE - 1)) == 0 ? 1 : -1]; #ifndef STBTT_RASTERIZER_VERSION #define STBTT_RASTERIZER_VERSION 2 #endif #ifdef _MSC_VER -#define STBTT__NOTUSED(v) (void)(v) +#define STBTT__NOTUSED(v) (void)(v) #else -#define STBTT__NOTUSED(v) (void)sizeof(v) +#define STBTT__NOTUSED(v) (void)sizeof(v) #endif ////////////////////////////////////////////////////////////////////////// @@ -1099,143 +1115,155 @@ typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERS static stbtt_uint8 stbtt__buf_get8(stbtt__buf *b) { - if (b->cursor >= b->size) - return 0; - return b->data[b->cursor++]; + if (b->cursor >= b->size) + return 0; + return b->data[b->cursor++]; } static stbtt_uint8 stbtt__buf_peek8(stbtt__buf *b) { - if (b->cursor >= b->size) - return 0; - return b->data[b->cursor]; + if (b->cursor >= b->size) + return 0; + return b->data[b->cursor]; } static void stbtt__buf_seek(stbtt__buf *b, int o) { - STBTT_assert(!(o > b->size || o < 0)); - b->cursor = (o > b->size || o < 0) ? b->size : o; + STBTT_assert(!(o > b->size || o < 0)); + b->cursor = (o > b->size || o < 0) ? b->size : o; } static void stbtt__buf_skip(stbtt__buf *b, int o) { - stbtt__buf_seek(b, b->cursor + o); + stbtt__buf_seek(b, b->cursor + o); } static stbtt_uint32 stbtt__buf_get(stbtt__buf *b, int n) { - stbtt_uint32 v = 0; - int i; - STBTT_assert(n >= 1 && n <= 4); - for (i = 0; i < n; i++) - v = (v << 8) | stbtt__buf_get8(b); - return v; + stbtt_uint32 v = 0; + int i; + STBTT_assert(n >= 1 && n <= 4); + for (i = 0; i < n; i++) + v = (v << 8) | stbtt__buf_get8(b); + return v; } static stbtt__buf stbtt__new_buf(const void *p, size_t size) { - stbtt__buf r; - STBTT_assert(size < 0x40000000); - r.data = (stbtt_uint8*) p; - r.size = (int) size; - r.cursor = 0; - return r; + stbtt__buf r; + STBTT_assert(size < 0x40000000); + r.data = (stbtt_uint8 *)p; + r.size = (int)size; + r.cursor = 0; + return r; } -#define stbtt__buf_get16(b) stbtt__buf_get((b), 2) -#define stbtt__buf_get32(b) stbtt__buf_get((b), 4) +#define stbtt__buf_get16(b) stbtt__buf_get((b), 2) +#define stbtt__buf_get32(b) stbtt__buf_get((b), 4) static stbtt__buf stbtt__buf_range(const stbtt__buf *b, int o, int s) { - stbtt__buf r = stbtt__new_buf(NULL, 0); - if (o < 0 || s < 0 || o > b->size || s > b->size - o) return r; - r.data = b->data + o; - r.size = s; - return r; + stbtt__buf r = stbtt__new_buf(NULL, 0); + if (o < 0 || s < 0 || o > b->size || s > b->size - o) return r; + r.data = b->data + o; + r.size = s; + return r; } static stbtt__buf stbtt__cff_get_index(stbtt__buf *b) { - int count, start, offsize; - start = b->cursor; - count = stbtt__buf_get16(b); - if (count) { - offsize = stbtt__buf_get8(b); - STBTT_assert(offsize >= 1 && offsize <= 4); - stbtt__buf_skip(b, offsize * count); - stbtt__buf_skip(b, stbtt__buf_get(b, offsize) - 1); - } - return stbtt__buf_range(b, start, b->cursor - start); + int count, start, offsize; + start = b->cursor; + count = stbtt__buf_get16(b); + if (count) + { + offsize = stbtt__buf_get8(b); + STBTT_assert(offsize >= 1 && offsize <= 4); + stbtt__buf_skip(b, offsize * count); + stbtt__buf_skip(b, stbtt__buf_get(b, offsize) - 1); + } + return stbtt__buf_range(b, start, b->cursor - start); } static stbtt_uint32 stbtt__cff_int(stbtt__buf *b) { - int b0 = stbtt__buf_get8(b); - if (b0 >= 32 && b0 <= 246) return b0 - 139; - else if (b0 >= 247 && b0 <= 250) return (b0 - 247)*256 + stbtt__buf_get8(b) + 108; - else if (b0 >= 251 && b0 <= 254) return -(b0 - 251)*256 - stbtt__buf_get8(b) - 108; - else if (b0 == 28) return stbtt__buf_get16(b); - else if (b0 == 29) return stbtt__buf_get32(b); - STBTT_assert(0); - return 0; + int b0 = stbtt__buf_get8(b); + if (b0 >= 32 && b0 <= 246) + return b0 - 139; + else if (b0 >= 247 && b0 <= 250) + return (b0 - 247) * 256 + stbtt__buf_get8(b) + 108; + else if (b0 >= 251 && b0 <= 254) + return -(b0 - 251) * 256 - stbtt__buf_get8(b) - 108; + else if (b0 == 28) + return stbtt__buf_get16(b); + else if (b0 == 29) + return stbtt__buf_get32(b); + STBTT_assert(0); + return 0; } -static void stbtt__cff_skip_operand(stbtt__buf *b) { - int v, b0 = stbtt__buf_peek8(b); - STBTT_assert(b0 >= 28); - if (b0 == 30) { - stbtt__buf_skip(b, 1); - while (b->cursor < b->size) { - v = stbtt__buf_get8(b); - if ((v & 0xF) == 0xF || (v >> 4) == 0xF) - break; - } - } else { - stbtt__cff_int(b); - } +static void stbtt__cff_skip_operand(stbtt__buf *b) +{ + int v, b0 = stbtt__buf_peek8(b); + STBTT_assert(b0 >= 28); + if (b0 == 30) + { + stbtt__buf_skip(b, 1); + while (b->cursor < b->size) + { + v = stbtt__buf_get8(b); + if ((v & 0xF) == 0xF || (v >> 4) == 0xF) + break; + } + } + else + { + stbtt__cff_int(b); + } } static stbtt__buf stbtt__dict_get(stbtt__buf *b, int key) { - stbtt__buf_seek(b, 0); - while (b->cursor < b->size) { - int start = b->cursor, end, op; - while (stbtt__buf_peek8(b) >= 28) - stbtt__cff_skip_operand(b); - end = b->cursor; - op = stbtt__buf_get8(b); - if (op == 12) op = stbtt__buf_get8(b) | 0x100; - if (op == key) return stbtt__buf_range(b, start, end-start); - } - return stbtt__buf_range(b, 0, 0); + stbtt__buf_seek(b, 0); + while (b->cursor < b->size) + { + int start = b->cursor, end, op; + while (stbtt__buf_peek8(b) >= 28) + stbtt__cff_skip_operand(b); + end = b->cursor; + op = stbtt__buf_get8(b); + if (op == 12) op = stbtt__buf_get8(b) | 0x100; + if (op == key) return stbtt__buf_range(b, start, end - start); + } + return stbtt__buf_range(b, 0, 0); } static void stbtt__dict_get_ints(stbtt__buf *b, int key, int outcount, stbtt_uint32 *out) { - int i; - stbtt__buf operands = stbtt__dict_get(b, key); - for (i = 0; i < outcount && operands.cursor < operands.size; i++) - out[i] = stbtt__cff_int(&operands); + int i; + stbtt__buf operands = stbtt__dict_get(b, key); + for (i = 0; i < outcount && operands.cursor < operands.size; i++) + out[i] = stbtt__cff_int(&operands); } static int stbtt__cff_index_count(stbtt__buf *b) { - stbtt__buf_seek(b, 0); - return stbtt__buf_get16(b); + stbtt__buf_seek(b, 0); + return stbtt__buf_get16(b); } static stbtt__buf stbtt__cff_index_get(stbtt__buf b, int i) { - int count, offsize, start, end; - stbtt__buf_seek(&b, 0); - count = stbtt__buf_get16(&b); - offsize = stbtt__buf_get8(&b); - STBTT_assert(i >= 0 && i < count); - STBTT_assert(offsize >= 1 && offsize <= 4); - stbtt__buf_skip(&b, i*offsize); - start = stbtt__buf_get(&b, offsize); - end = stbtt__buf_get(&b, offsize); - return stbtt__buf_range(&b, 2+(count+1)*offsize+start, end - start); + int count, offsize, start, end; + stbtt__buf_seek(&b, 0); + count = stbtt__buf_get16(&b); + offsize = stbtt__buf_get8(&b); + STBTT_assert(i >= 0 && i < count); + STBTT_assert(offsize >= 1 && offsize <= 4); + stbtt__buf_skip(&b, i * offsize); + start = stbtt__buf_get(&b, offsize); + end = stbtt__buf_get(&b, offsize); + return stbtt__buf_range(&b, 2 + (count + 1) * offsize + start, end - start); } ////////////////////////////////////////////////////////////////////////// @@ -1246,1361 +1274,1525 @@ static stbtt__buf stbtt__cff_index_get(stbtt__buf b, int i) // on platforms that don't allow misaligned reads, if we want to allow // truetype fonts that aren't padded to alignment, define ALLOW_UNALIGNED_TRUETYPE -#define ttBYTE(p) (* (stbtt_uint8 *) (p)) -#define ttCHAR(p) (* (stbtt_int8 *) (p)) -#define ttFixed(p) ttLONG(p) +#define ttBYTE(p) (*(stbtt_uint8 *)(p)) +#define ttCHAR(p) (*(stbtt_int8 *)(p)) +#define ttFixed(p) ttLONG(p) -static stbtt_uint16 ttUSHORT(stbtt_uint8 *p) { return p[0]*256 + p[1]; } -static stbtt_int16 ttSHORT(stbtt_uint8 *p) { return p[0]*256 + p[1]; } -static stbtt_uint32 ttULONG(stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } -static stbtt_int32 ttLONG(stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } +static stbtt_uint16 ttUSHORT(stbtt_uint8 *p) +{ + return p[0] * 256 + p[1]; +} +static stbtt_int16 ttSHORT(stbtt_uint8 *p) { return p[0] * 256 + p[1]; } +static stbtt_uint32 ttULONG(stbtt_uint8 *p) { return (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3]; } +static stbtt_int32 ttLONG(stbtt_uint8 *p) { return (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3]; } -#define stbtt_tag4(p,c0,c1,c2,c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3)) -#define stbtt_tag(p,str) stbtt_tag4(p,str[0],str[1],str[2],str[3]) +#define stbtt_tag4(p, c0, c1, c2, c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3)) +#define stbtt_tag(p, str) stbtt_tag4(p, str[0], str[1], str[2], str[3]) static int stbtt__isfont(stbtt_uint8 *font) { - // check the version number - if (stbtt_tag4(font, '1',0,0,0)) return 1; // TrueType 1 - if (stbtt_tag(font, "typ1")) return 1; // TrueType with type 1 font -- we don't support this! - if (stbtt_tag(font, "OTTO")) return 1; // OpenType with CFF - if (stbtt_tag4(font, 0,1,0,0)) return 1; // OpenType 1.0 - if (stbtt_tag(font, "true")) return 1; // Apple specification for TrueType fonts - return 0; + // check the version number + if (stbtt_tag4(font, '1', 0, 0, 0)) return 1; // TrueType 1 + if (stbtt_tag(font, "typ1")) return 1; // TrueType with type 1 font -- we don't support this! + if (stbtt_tag(font, "OTTO")) return 1; // OpenType with CFF + if (stbtt_tag4(font, 0, 1, 0, 0)) return 1; // OpenType 1.0 + if (stbtt_tag(font, "true")) return 1; // Apple specification for TrueType fonts + return 0; } // @OPTIMIZE: binary search static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, const char *tag) { - stbtt_int32 num_tables = ttUSHORT(data+fontstart+4); - stbtt_uint32 tabledir = fontstart + 12; - stbtt_int32 i; - for (i=0; i < num_tables; ++i) { - stbtt_uint32 loc = tabledir + 16*i; - if (stbtt_tag(data+loc+0, tag)) - return ttULONG(data+loc+8); - } - return 0; + stbtt_int32 num_tables = ttUSHORT(data + fontstart + 4); + stbtt_uint32 tabledir = fontstart + 12; + stbtt_int32 i; + for (i = 0; i < num_tables; ++i) + { + stbtt_uint32 loc = tabledir + 16 * i; + if (stbtt_tag(data + loc + 0, tag)) + return ttULONG(data + loc + 8); + } + return 0; } static int stbtt_GetFontOffsetForIndex_internal(unsigned char *font_collection, int index) { - // if it's just a font, there's only one valid index - if (stbtt__isfont(font_collection)) - return index == 0 ? 0 : -1; + // if it's just a font, there's only one valid index + if (stbtt__isfont(font_collection)) + return index == 0 ? 0 : -1; - // check if it's a TTC - if (stbtt_tag(font_collection, "ttcf")) { - // version 1? - if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) { - stbtt_int32 n = ttLONG(font_collection+8); - if (index >= n) - return -1; - return ttULONG(font_collection+12+index*4); - } - } - return -1; + // check if it's a TTC + if (stbtt_tag(font_collection, "ttcf")) + { + // version 1? + if (ttULONG(font_collection + 4) == 0x00010000 || ttULONG(font_collection + 4) == 0x00020000) + { + stbtt_int32 n = ttLONG(font_collection + 8); + if (index >= n) + return -1; + return ttULONG(font_collection + 12 + index * 4); + } + } + return -1; } static int stbtt_GetNumberOfFonts_internal(unsigned char *font_collection) { - // if it's just a font, there's only one valid font - if (stbtt__isfont(font_collection)) - return 1; + // if it's just a font, there's only one valid font + if (stbtt__isfont(font_collection)) + return 1; - // check if it's a TTC - if (stbtt_tag(font_collection, "ttcf")) { - // version 1? - if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) { - return ttLONG(font_collection+8); - } - } - return 0; + // check if it's a TTC + if (stbtt_tag(font_collection, "ttcf")) + { + // version 1? + if (ttULONG(font_collection + 4) == 0x00010000 || ttULONG(font_collection + 4) == 0x00020000) + { + return ttLONG(font_collection + 8); + } + } + return 0; } static stbtt__buf stbtt__get_subrs(stbtt__buf cff, stbtt__buf fontdict) { - stbtt_uint32 subrsoff = 0, private_loc[2] = { 0, 0 }; - stbtt__buf pdict; - stbtt__dict_get_ints(&fontdict, 18, 2, private_loc); - if (!private_loc[1] || !private_loc[0]) return stbtt__new_buf(NULL, 0); - pdict = stbtt__buf_range(&cff, private_loc[1], private_loc[0]); - stbtt__dict_get_ints(&pdict, 19, 1, &subrsoff); - if (!subrsoff) return stbtt__new_buf(NULL, 0); - stbtt__buf_seek(&cff, private_loc[1]+subrsoff); - return stbtt__cff_get_index(&cff); + stbtt_uint32 subrsoff = 0, private_loc[2] = {0, 0}; + stbtt__buf pdict; + stbtt__dict_get_ints(&fontdict, 18, 2, private_loc); + if (!private_loc[1] || !private_loc[0]) return stbtt__new_buf(NULL, 0); + pdict = stbtt__buf_range(&cff, private_loc[1], private_loc[0]); + stbtt__dict_get_ints(&pdict, 19, 1, &subrsoff); + if (!subrsoff) return stbtt__new_buf(NULL, 0); + stbtt__buf_seek(&cff, private_loc[1] + subrsoff); + return stbtt__cff_get_index(&cff); } static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, int fontstart) { - stbtt_uint32 cmap, t; - stbtt_int32 i,numTables; + stbtt_uint32 cmap, t; + stbtt_int32 i, numTables; - info->data = data; - info->fontstart = fontstart; - info->cff = stbtt__new_buf(NULL, 0); + info->data = data; + info->fontstart = fontstart; + info->cff = stbtt__new_buf(NULL, 0); - cmap = stbtt__find_table(data, fontstart, "cmap"); // required - info->loca = stbtt__find_table(data, fontstart, "loca"); // required - info->head = stbtt__find_table(data, fontstart, "head"); // required - info->glyf = stbtt__find_table(data, fontstart, "glyf"); // required - info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required - info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required - info->kern = stbtt__find_table(data, fontstart, "kern"); // not required - info->gpos = stbtt__find_table(data, fontstart, "GPOS"); // not required + cmap = stbtt__find_table(data, fontstart, "cmap"); // required + info->loca = stbtt__find_table(data, fontstart, "loca"); // required + info->head = stbtt__find_table(data, fontstart, "head"); // required + info->glyf = stbtt__find_table(data, fontstart, "glyf"); // required + info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required + info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required + info->kern = stbtt__find_table(data, fontstart, "kern"); // not required + info->gpos = stbtt__find_table(data, fontstart, "GPOS"); // not required - if (!cmap || !info->head || !info->hhea || !info->hmtx) - return 0; - if (info->glyf) { - // required for truetype - if (!info->loca) return 0; - } else { - // initialization for CFF / Type2 fonts (OTF) - stbtt__buf b, topdict, topdictidx; - stbtt_uint32 cstype = 2, charstrings = 0, fdarrayoff = 0, fdselectoff = 0; - stbtt_uint32 cff; + if (!cmap || !info->head || !info->hhea || !info->hmtx) + return 0; + if (info->glyf) + { + // required for truetype + if (!info->loca) return 0; + } + else + { + // initialization for CFF / Type2 fonts (OTF) + stbtt__buf b, topdict, topdictidx; + stbtt_uint32 cstype = 2, charstrings = 0, fdarrayoff = 0, fdselectoff = 0; + stbtt_uint32 cff; - cff = stbtt__find_table(data, fontstart, "CFF "); - if (!cff) return 0; + cff = stbtt__find_table(data, fontstart, "CFF "); + if (!cff) return 0; - info->fontdicts = stbtt__new_buf(NULL, 0); - info->fdselect = stbtt__new_buf(NULL, 0); + info->fontdicts = stbtt__new_buf(NULL, 0); + info->fdselect = stbtt__new_buf(NULL, 0); - // @TODO this should use size from table (not 512MB) - info->cff = stbtt__new_buf(data+cff, 512*1024*1024); - b = info->cff; + // @TODO this should use size from table (not 512MB) + info->cff = stbtt__new_buf(data + cff, 512 * 1024 * 1024); + b = info->cff; - // read the header - stbtt__buf_skip(&b, 2); - stbtt__buf_seek(&b, stbtt__buf_get8(&b)); // hdrsize + // read the header + stbtt__buf_skip(&b, 2); + stbtt__buf_seek(&b, stbtt__buf_get8(&b)); // hdrsize - // @TODO the name INDEX could list multiple fonts, - // but we just use the first one. - stbtt__cff_get_index(&b); // name INDEX - topdictidx = stbtt__cff_get_index(&b); - topdict = stbtt__cff_index_get(topdictidx, 0); - stbtt__cff_get_index(&b); // string INDEX - info->gsubrs = stbtt__cff_get_index(&b); + // @TODO the name INDEX could list multiple fonts, + // but we just use the first one. + stbtt__cff_get_index(&b); // name INDEX + topdictidx = stbtt__cff_get_index(&b); + topdict = stbtt__cff_index_get(topdictidx, 0); + stbtt__cff_get_index(&b); // string INDEX + info->gsubrs = stbtt__cff_get_index(&b); - stbtt__dict_get_ints(&topdict, 17, 1, &charstrings); - stbtt__dict_get_ints(&topdict, 0x100 | 6, 1, &cstype); - stbtt__dict_get_ints(&topdict, 0x100 | 36, 1, &fdarrayoff); - stbtt__dict_get_ints(&topdict, 0x100 | 37, 1, &fdselectoff); - info->subrs = stbtt__get_subrs(b, topdict); + stbtt__dict_get_ints(&topdict, 17, 1, &charstrings); + stbtt__dict_get_ints(&topdict, 0x100 | 6, 1, &cstype); + stbtt__dict_get_ints(&topdict, 0x100 | 36, 1, &fdarrayoff); + stbtt__dict_get_ints(&topdict, 0x100 | 37, 1, &fdselectoff); + info->subrs = stbtt__get_subrs(b, topdict); - // we only support Type 2 charstrings - if (cstype != 2) return 0; - if (charstrings == 0) return 0; + // we only support Type 2 charstrings + if (cstype != 2) return 0; + if (charstrings == 0) return 0; - if (fdarrayoff) { - // looks like a CID font - if (!fdselectoff) return 0; - stbtt__buf_seek(&b, fdarrayoff); - info->fontdicts = stbtt__cff_get_index(&b); - info->fdselect = stbtt__buf_range(&b, fdselectoff, b.size-fdselectoff); - } + if (fdarrayoff) + { + // looks like a CID font + if (!fdselectoff) return 0; + stbtt__buf_seek(&b, fdarrayoff); + info->fontdicts = stbtt__cff_get_index(&b); + info->fdselect = stbtt__buf_range(&b, fdselectoff, b.size - fdselectoff); + } - stbtt__buf_seek(&b, charstrings); - info->charstrings = stbtt__cff_get_index(&b); - } + stbtt__buf_seek(&b, charstrings); + info->charstrings = stbtt__cff_get_index(&b); + } - t = stbtt__find_table(data, fontstart, "maxp"); - if (t) - info->numGlyphs = ttUSHORT(data+t+4); - else - info->numGlyphs = 0xffff; + t = stbtt__find_table(data, fontstart, "maxp"); + if (t) + info->numGlyphs = ttUSHORT(data + t + 4); + else + info->numGlyphs = 0xffff; - // find a cmap encoding table we understand *now* to avoid searching - // later. (todo: could make this installable) - // the same regardless of glyph. - numTables = ttUSHORT(data + cmap + 2); - info->index_map = 0; - for (i=0; i < numTables; ++i) { - stbtt_uint32 encoding_record = cmap + 4 + 8 * i; - // find an encoding we understand: - switch(ttUSHORT(data+encoding_record)) { - case STBTT_PLATFORM_ID_MICROSOFT: - switch (ttUSHORT(data+encoding_record+2)) { - case STBTT_MS_EID_UNICODE_BMP: - case STBTT_MS_EID_UNICODE_FULL: - // MS/Unicode - info->index_map = cmap + ttULONG(data+encoding_record+4); - break; - } - break; - case STBTT_PLATFORM_ID_UNICODE: - // Mac/iOS has these - // all the encodingIDs are unicode, so we don't bother to check it - info->index_map = cmap + ttULONG(data+encoding_record+4); - break; - } - } - if (info->index_map == 0) - return 0; + // find a cmap encoding table we understand *now* to avoid searching + // later. (todo: could make this installable) + // the same regardless of glyph. + numTables = ttUSHORT(data + cmap + 2); + info->index_map = 0; + for (i = 0; i < numTables; ++i) + { + stbtt_uint32 encoding_record = cmap + 4 + 8 * i; + // find an encoding we understand: + switch (ttUSHORT(data + encoding_record)) + { + case STBTT_PLATFORM_ID_MICROSOFT: + switch (ttUSHORT(data + encoding_record + 2)) + { + case STBTT_MS_EID_UNICODE_BMP: + case STBTT_MS_EID_UNICODE_FULL: + // MS/Unicode + info->index_map = cmap + ttULONG(data + encoding_record + 4); + break; + } + break; + case STBTT_PLATFORM_ID_UNICODE: + // Mac/iOS has these + // all the encodingIDs are unicode, so we don't bother to check it + info->index_map = cmap + ttULONG(data + encoding_record + 4); + break; + } + } + if (info->index_map == 0) + return 0; - info->indexToLocFormat = ttUSHORT(data+info->head + 50); - return 1; + info->indexToLocFormat = ttUSHORT(data + info->head + 50); + return 1; } STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint) { - stbtt_uint8 *data = info->data; - stbtt_uint32 index_map = info->index_map; + stbtt_uint8 *data = info->data; + stbtt_uint32 index_map = info->index_map; - stbtt_uint16 format = ttUSHORT(data + index_map + 0); - if (format == 0) { // apple byte encoding - stbtt_int32 bytes = ttUSHORT(data + index_map + 2); - if (unicode_codepoint < bytes-6) - return ttBYTE(data + index_map + 6 + unicode_codepoint); - return 0; - } else if (format == 6) { - stbtt_uint32 first = ttUSHORT(data + index_map + 6); - stbtt_uint32 count = ttUSHORT(data + index_map + 8); - if ((stbtt_uint32) unicode_codepoint >= first && (stbtt_uint32) unicode_codepoint < first+count) - return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first)*2); - return 0; - } else if (format == 2) { - STBTT_assert(0); // @TODO: high-byte mapping for japanese/chinese/korean - return 0; - } else if (format == 4) { // standard mapping for windows fonts: binary search collection of ranges - stbtt_uint16 segcount = ttUSHORT(data+index_map+6) >> 1; - stbtt_uint16 searchRange = ttUSHORT(data+index_map+8) >> 1; - stbtt_uint16 entrySelector = ttUSHORT(data+index_map+10); - stbtt_uint16 rangeShift = ttUSHORT(data+index_map+12) >> 1; + stbtt_uint16 format = ttUSHORT(data + index_map + 0); + if (format == 0) + { // apple byte encoding + stbtt_int32 bytes = ttUSHORT(data + index_map + 2); + if (unicode_codepoint < bytes - 6) + return ttBYTE(data + index_map + 6 + unicode_codepoint); + return 0; + } + else if (format == 6) + { + stbtt_uint32 first = ttUSHORT(data + index_map + 6); + stbtt_uint32 count = ttUSHORT(data + index_map + 8); + if ((stbtt_uint32)unicode_codepoint >= first && (stbtt_uint32)unicode_codepoint < first + count) + return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first) * 2); + return 0; + } + else if (format == 2) + { + STBTT_assert(0); // @TODO: high-byte mapping for japanese/chinese/korean + return 0; + } + else if (format == 4) + { // standard mapping for windows fonts: binary search collection of ranges + stbtt_uint16 segcount = ttUSHORT(data + index_map + 6) >> 1; + stbtt_uint16 searchRange = ttUSHORT(data + index_map + 8) >> 1; + stbtt_uint16 entrySelector = ttUSHORT(data + index_map + 10); + stbtt_uint16 rangeShift = ttUSHORT(data + index_map + 12) >> 1; - // do a binary search of the segments - stbtt_uint32 endCount = index_map + 14; - stbtt_uint32 search = endCount; + // do a binary search of the segments + stbtt_uint32 endCount = index_map + 14; + stbtt_uint32 search = endCount; - if (unicode_codepoint > 0xffff) - return 0; + if (unicode_codepoint > 0xffff) + return 0; - // they lie from endCount .. endCount + segCount - // but searchRange is the nearest power of two, so... - if (unicode_codepoint >= ttUSHORT(data + search + rangeShift*2)) - search += rangeShift*2; + // they lie from endCount .. endCount + segCount + // but searchRange is the nearest power of two, so... + if (unicode_codepoint >= ttUSHORT(data + search + rangeShift * 2)) + search += rangeShift * 2; - // now decrement to bias correctly to find smallest - search -= 2; - while (entrySelector) { - stbtt_uint16 end; - searchRange >>= 1; - end = ttUSHORT(data + search + searchRange*2); - if (unicode_codepoint > end) - search += searchRange*2; - --entrySelector; - } - search += 2; + // now decrement to bias correctly to find smallest + search -= 2; + while (entrySelector) + { + stbtt_uint16 end; + searchRange >>= 1; + end = ttUSHORT(data + search + searchRange * 2); + if (unicode_codepoint > end) + search += searchRange * 2; + --entrySelector; + } + search += 2; - { - stbtt_uint16 offset, start; - stbtt_uint16 item = (stbtt_uint16) ((search - endCount) >> 1); + { + stbtt_uint16 offset, start; + stbtt_uint16 item = (stbtt_uint16)((search - endCount) >> 1); - STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2*item)); - start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item); - if (unicode_codepoint < start) - return 0; + STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2 * item)); + start = ttUSHORT(data + index_map + 14 + segcount * 2 + 2 + 2 * item); + if (unicode_codepoint < start) + return 0; - offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item); - if (offset == 0) - return (stbtt_uint16) (unicode_codepoint + ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item)); + offset = ttUSHORT(data + index_map + 14 + segcount * 6 + 2 + 2 * item); + if (offset == 0) + return (stbtt_uint16)(unicode_codepoint + ttSHORT(data + index_map + 14 + segcount * 4 + 2 + 2 * item)); - return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item); - } - } else if (format == 12 || format == 13) { - stbtt_uint32 ngroups = ttULONG(data+index_map+12); - stbtt_int32 low,high; - low = 0; high = (stbtt_int32)ngroups; - // Binary search the right group. - while (low < high) { - stbtt_int32 mid = low + ((high-low) >> 1); // rounds down, so low <= mid < high - stbtt_uint32 start_char = ttULONG(data+index_map+16+mid*12); - stbtt_uint32 end_char = ttULONG(data+index_map+16+mid*12+4); - if ((stbtt_uint32) unicode_codepoint < start_char) - high = mid; - else if ((stbtt_uint32) unicode_codepoint > end_char) - low = mid+1; - else { - stbtt_uint32 start_glyph = ttULONG(data+index_map+16+mid*12+8); - if (format == 12) - return start_glyph + unicode_codepoint-start_char; - else // format == 13 - return start_glyph; - } - } - return 0; // not found - } - // @TODO - STBTT_assert(0); - return 0; + return ttUSHORT(data + offset + (unicode_codepoint - start) * 2 + index_map + 14 + segcount * 6 + 2 + 2 * item); + } + } + else if (format == 12 || format == 13) + { + stbtt_uint32 ngroups = ttULONG(data + index_map + 12); + stbtt_int32 low, high; + low = 0; + high = (stbtt_int32)ngroups; + // Binary search the right group. + while (low < high) + { + stbtt_int32 mid = low + ((high - low) >> 1); // rounds down, so low <= mid < high + stbtt_uint32 start_char = ttULONG(data + index_map + 16 + mid * 12); + stbtt_uint32 end_char = ttULONG(data + index_map + 16 + mid * 12 + 4); + if ((stbtt_uint32)unicode_codepoint < start_char) + high = mid; + else if ((stbtt_uint32)unicode_codepoint > end_char) + low = mid + 1; + else + { + stbtt_uint32 start_glyph = ttULONG(data + index_map + 16 + mid * 12 + 8); + if (format == 12) + return start_glyph + unicode_codepoint - start_char; + else // format == 13 + return start_glyph; + } + } + return 0; // not found + } + // @TODO + STBTT_assert(0); + return 0; } STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices) { - return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices); + return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices); } static void stbtt_setvertex(stbtt_vertex *v, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy) { - v->type = type; - v->x = (stbtt_int16) x; - v->y = (stbtt_int16) y; - v->cx = (stbtt_int16) cx; - v->cy = (stbtt_int16) cy; + v->type = type; + v->x = (stbtt_int16)x; + v->y = (stbtt_int16)y; + v->cx = (stbtt_int16)cx; + v->cy = (stbtt_int16)cy; } static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index) { - int g1,g2; + int g1, g2; - STBTT_assert(!info->cff.size); + STBTT_assert(!info->cff.size); - if (glyph_index >= info->numGlyphs) return -1; // glyph index out of range - if (info->indexToLocFormat >= 2) return -1; // unknown index->glyph map format + if (glyph_index >= info->numGlyphs) return -1; // glyph index out of range + if (info->indexToLocFormat >= 2) return -1; // unknown index->glyph map format - if (info->indexToLocFormat == 0) { - g1 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2) * 2; - g2 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2; - } else { - g1 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4); - g2 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4 + 4); - } + if (info->indexToLocFormat == 0) + { + g1 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2) * 2; + g2 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2; + } + else + { + g1 = info->glyf + ttULONG(info->data + info->loca + glyph_index * 4); + g2 = info->glyf + ttULONG(info->data + info->loca + glyph_index * 4 + 4); + } - return g1==g2 ? -1 : g1; // if length is 0, return -1 + return g1 == g2 ? -1 : g1; // if length is 0, return -1 } static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) { - if (info->cff.size) { - stbtt__GetGlyphInfoT2(info, glyph_index, x0, y0, x1, y1); - } else { - int g = stbtt__GetGlyfOffset(info, glyph_index); - if (g < 0) return 0; + if (info->cff.size) + { + stbtt__GetGlyphInfoT2(info, glyph_index, x0, y0, x1, y1); + } + else + { + int g = stbtt__GetGlyfOffset(info, glyph_index); + if (g < 0) return 0; - if (x0) *x0 = ttSHORT(info->data + g + 2); - if (y0) *y0 = ttSHORT(info->data + g + 4); - if (x1) *x1 = ttSHORT(info->data + g + 6); - if (y1) *y1 = ttSHORT(info->data + g + 8); - } - return 1; + if (x0) *x0 = ttSHORT(info->data + g + 2); + if (y0) *y0 = ttSHORT(info->data + g + 4); + if (x1) *x1 = ttSHORT(info->data + g + 6); + if (y1) *y1 = ttSHORT(info->data + g + 8); + } + return 1; } STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1) { - return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info,codepoint), x0,y0,x1,y1); + return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info, codepoint), x0, y0, x1, y1); } STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index) { - stbtt_int16 numberOfContours; - int g; - if (info->cff.size) - return stbtt__GetGlyphInfoT2(info, glyph_index, NULL, NULL, NULL, NULL) == 0; - g = stbtt__GetGlyfOffset(info, glyph_index); - if (g < 0) return 1; - numberOfContours = ttSHORT(info->data + g); - return numberOfContours == 0; + stbtt_int16 numberOfContours; + int g; + if (info->cff.size) + return stbtt__GetGlyphInfoT2(info, glyph_index, NULL, NULL, NULL, NULL) == 0; + g = stbtt__GetGlyfOffset(info, glyph_index); + if (g < 0) return 1; + numberOfContours = ttSHORT(info->data + g); + return numberOfContours == 0; } static int stbtt__close_shape(stbtt_vertex *vertices, int num_vertices, int was_off, int start_off, - stbtt_int32 sx, stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy) + stbtt_int32 sx, stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy) { - if (start_off) { - if (was_off) - stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy); - stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx,sy,scx,scy); - } else { - if (was_off) - stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve,sx,sy,cx,cy); - else - stbtt_setvertex(&vertices[num_vertices++], STBTT_vline,sx,sy,0,0); - } - return num_vertices; + if (start_off) + { + if (was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx + scx) >> 1, (cy + scy) >> 1, cx, cy); + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx, sy, scx, scy); + } + else + { + if (was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx, sy, cx, cy); + else + stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, sx, sy, 0, 0); + } + return num_vertices; } static int stbtt__GetGlyphShapeTT(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) { - stbtt_int16 numberOfContours; - stbtt_uint8 *endPtsOfContours; - stbtt_uint8 *data = info->data; - stbtt_vertex *vertices=0; - int num_vertices=0; - int g = stbtt__GetGlyfOffset(info, glyph_index); + stbtt_int16 numberOfContours; + stbtt_uint8 *endPtsOfContours; + stbtt_uint8 *data = info->data; + stbtt_vertex *vertices = 0; + int num_vertices = 0; + int g = stbtt__GetGlyfOffset(info, glyph_index); - *pvertices = NULL; + *pvertices = NULL; - if (g < 0) return 0; + if (g < 0) return 0; - numberOfContours = ttSHORT(data + g); + numberOfContours = ttSHORT(data + g); - if (numberOfContours > 0) { - stbtt_uint8 flags=0,flagcount; - stbtt_int32 ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0; - stbtt_int32 x,y,cx,cy,sx,sy, scx,scy; - stbtt_uint8 *points; - endPtsOfContours = (data + g + 10); - ins = ttUSHORT(data + g + 10 + numberOfContours * 2); - points = data + g + 10 + numberOfContours * 2 + 2 + ins; + if (numberOfContours > 0) + { + stbtt_uint8 flags = 0, flagcount; + stbtt_int32 ins, i, j = 0, m, n, next_move, was_off = 0, off, start_off = 0; + stbtt_int32 x, y, cx, cy, sx, sy, scx, scy; + stbtt_uint8 *points; + endPtsOfContours = (data + g + 10); + ins = ttUSHORT(data + g + 10 + numberOfContours * 2); + points = data + g + 10 + numberOfContours * 2 + 2 + ins; - n = 1+ttUSHORT(endPtsOfContours + numberOfContours*2-2); + n = 1 + ttUSHORT(endPtsOfContours + numberOfContours * 2 - 2); - m = n + 2*numberOfContours; // a loose bound on how many vertices we might need - vertices = (stbtt_vertex *) STBTT_malloc(m * sizeof(vertices[0]), info->userdata); - if (vertices == 0) - return 0; + m = n + 2 * numberOfContours; // a loose bound on how many vertices we might need + vertices = (stbtt_vertex *)STBTT_malloc(m * sizeof(vertices[0]), info->userdata); + if (vertices == 0) + return 0; - next_move = 0; - flagcount=0; + next_move = 0; + flagcount = 0; - // in first pass, we load uninterpreted data into the allocated array - // above, shifted to the end of the array so we won't overwrite it when - // we create our final data starting from the front + // in first pass, we load uninterpreted data into the allocated array + // above, shifted to the end of the array so we won't overwrite it when + // we create our final data starting from the front - off = m - n; // starting offset for uninterpreted data, regardless of how m ends up being calculated + off = m - n; // starting offset for uninterpreted data, regardless of how m ends up being calculated - // first load flags + // first load flags - for (i=0; i < n; ++i) { - if (flagcount == 0) { - flags = *points++; - if (flags & 8) - flagcount = *points++; - } else - --flagcount; - vertices[off+i].type = flags; - } + for (i = 0; i < n; ++i) + { + if (flagcount == 0) + { + flags = *points++; + if (flags & 8) + flagcount = *points++; + } + else + --flagcount; + vertices[off + i].type = flags; + } - // now load x coordinates - x=0; - for (i=0; i < n; ++i) { - flags = vertices[off+i].type; - if (flags & 2) { - stbtt_int16 dx = *points++; - x += (flags & 16) ? dx : -dx; // ??? - } else { - if (!(flags & 16)) { - x = x + (stbtt_int16) (points[0]*256 + points[1]); - points += 2; - } - } - vertices[off+i].x = (stbtt_int16) x; - } + // now load x coordinates + x = 0; + for (i = 0; i < n; ++i) + { + flags = vertices[off + i].type; + if (flags & 2) + { + stbtt_int16 dx = *points++; + x += (flags & 16) ? dx : -dx; // ??? + } + else + { + if (!(flags & 16)) + { + x = x + (stbtt_int16)(points[0] * 256 + points[1]); + points += 2; + } + } + vertices[off + i].x = (stbtt_int16)x; + } - // now load y coordinates - y=0; - for (i=0; i < n; ++i) { - flags = vertices[off+i].type; - if (flags & 4) { - stbtt_int16 dy = *points++; - y += (flags & 32) ? dy : -dy; // ??? - } else { - if (!(flags & 32)) { - y = y + (stbtt_int16) (points[0]*256 + points[1]); - points += 2; - } - } - vertices[off+i].y = (stbtt_int16) y; - } + // now load y coordinates + y = 0; + for (i = 0; i < n; ++i) + { + flags = vertices[off + i].type; + if (flags & 4) + { + stbtt_int16 dy = *points++; + y += (flags & 32) ? dy : -dy; // ??? + } + else + { + if (!(flags & 32)) + { + y = y + (stbtt_int16)(points[0] * 256 + points[1]); + points += 2; + } + } + vertices[off + i].y = (stbtt_int16)y; + } - // now convert them to our format - num_vertices=0; - sx = sy = cx = cy = scx = scy = 0; - for (i=0; i < n; ++i) { - flags = vertices[off+i].type; - x = (stbtt_int16) vertices[off+i].x; - y = (stbtt_int16) vertices[off+i].y; + // now convert them to our format + num_vertices = 0; + sx = sy = cx = cy = scx = scy = 0; + for (i = 0; i < n; ++i) + { + flags = vertices[off + i].type; + x = (stbtt_int16)vertices[off + i].x; + y = (stbtt_int16)vertices[off + i].y; - if (next_move == i) { - if (i != 0) - num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); + if (next_move == i) + { + if (i != 0) + num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx, sy, scx, scy, cx, cy); - // now start the new one - start_off = !(flags & 1); - if (start_off) { - // if we start off with an off-curve point, then when we need to find a point on the curve - // where we can start, and we need to save some state for when we wraparound. - scx = x; - scy = y; - if (!(vertices[off+i+1].type & 1)) { - // next point is also a curve point, so interpolate an on-point curve - sx = (x + (stbtt_int32) vertices[off+i+1].x) >> 1; - sy = (y + (stbtt_int32) vertices[off+i+1].y) >> 1; - } else { - // otherwise just use the next point as our start point - sx = (stbtt_int32) vertices[off+i+1].x; - sy = (stbtt_int32) vertices[off+i+1].y; - ++i; // we're using point i+1 as the starting point, so skip it - } - } else { - sx = x; - sy = y; - } - stbtt_setvertex(&vertices[num_vertices++], STBTT_vmove,sx,sy,0,0); - was_off = 0; - next_move = 1 + ttUSHORT(endPtsOfContours+j*2); - ++j; - } else { - if (!(flags & 1)) { // if it's a curve - if (was_off) // two off-curve control points in a row means interpolate an on-curve midpoint - stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy); - cx = x; - cy = y; - was_off = 1; - } else { - if (was_off) - stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x,y, cx, cy); - else - stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, x,y,0,0); - was_off = 0; - } - } - } - num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); - } else if (numberOfContours == -1) { - // Compound shapes. - int more = 1; - stbtt_uint8 *comp = data + g + 10; - num_vertices = 0; - vertices = 0; - while (more) { - stbtt_uint16 flags, gidx; - int comp_num_verts = 0, i; - stbtt_vertex *comp_verts = 0, *tmp = 0; - float mtx[6] = {1,0,0,1,0,0}, m, n; - - flags = ttSHORT(comp); comp+=2; - gidx = ttSHORT(comp); comp+=2; + // now start the new one + start_off = !(flags & 1); + if (start_off) + { + // if we start off with an off-curve point, then when we need to find a point on the curve + // where we can start, and we need to save some state for when we wraparound. + scx = x; + scy = y; + if (!(vertices[off + i + 1].type & 1)) + { + // next point is also a curve point, so interpolate an on-point curve + sx = (x + (stbtt_int32)vertices[off + i + 1].x) >> 1; + sy = (y + (stbtt_int32)vertices[off + i + 1].y) >> 1; + } + else + { + // otherwise just use the next point as our start point + sx = (stbtt_int32)vertices[off + i + 1].x; + sy = (stbtt_int32)vertices[off + i + 1].y; + ++i; // we're using point i+1 as the starting point, so skip it + } + } + else + { + sx = x; + sy = y; + } + stbtt_setvertex(&vertices[num_vertices++], STBTT_vmove, sx, sy, 0, 0); + was_off = 0; + next_move = 1 + ttUSHORT(endPtsOfContours + j * 2); + ++j; + } + else + { + if (!(flags & 1)) + { // if it's a curve + if (was_off) // two off-curve control points in a row means interpolate an on-curve midpoint + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx + x) >> 1, (cy + y) >> 1, cx, cy); + cx = x; + cy = y; + was_off = 1; + } + else + { + if (was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x, y, cx, cy); + else + stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, x, y, 0, 0); + was_off = 0; + } + } + } + num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx, sy, scx, scy, cx, cy); + } + else if (numberOfContours == -1) + { + // Compound shapes. + int more = 1; + stbtt_uint8 *comp = data + g + 10; + num_vertices = 0; + vertices = 0; + while (more) + { + stbtt_uint16 flags, gidx; + int comp_num_verts = 0, i; + stbtt_vertex *comp_verts = 0, *tmp = 0; + float mtx[6] = {1, 0, 0, 1, 0, 0}, m, n; - if (flags & 2) { // XY values - if (flags & 1) { // shorts - mtx[4] = ttSHORT(comp); comp+=2; - mtx[5] = ttSHORT(comp); comp+=2; - } else { - mtx[4] = ttCHAR(comp); comp+=1; - mtx[5] = ttCHAR(comp); comp+=1; - } - } - else { - // @TODO handle matching point - STBTT_assert(0); - } - if (flags & (1<<3)) { // WE_HAVE_A_SCALE - mtx[0] = mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; - mtx[1] = mtx[2] = 0; - } else if (flags & (1<<6)) { // WE_HAVE_AN_X_AND_YSCALE - mtx[0] = ttSHORT(comp)/16384.0f; comp+=2; - mtx[1] = mtx[2] = 0; - mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; - } else if (flags & (1<<7)) { // WE_HAVE_A_TWO_BY_TWO - mtx[0] = ttSHORT(comp)/16384.0f; comp+=2; - mtx[1] = ttSHORT(comp)/16384.0f; comp+=2; - mtx[2] = ttSHORT(comp)/16384.0f; comp+=2; - mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; - } - - // Find transformation scales. - m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]); - n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]); + flags = ttSHORT(comp); + comp += 2; + gidx = ttSHORT(comp); + comp += 2; - // Get indexed glyph. - comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts); - if (comp_num_verts > 0) { - // Transform vertices. - for (i = 0; i < comp_num_verts; ++i) { - stbtt_vertex* v = &comp_verts[i]; - stbtt_vertex_type x,y; - x=v->x; y=v->y; - v->x = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4])); - v->y = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5])); - x=v->cx; y=v->cy; - v->cx = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4])); - v->cy = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5])); - } - // Append vertices. - tmp = (stbtt_vertex*)STBTT_malloc((num_vertices+comp_num_verts)*sizeof(stbtt_vertex), info->userdata); - if (!tmp) { - if (vertices) STBTT_free(vertices, info->userdata); - if (comp_verts) STBTT_free(comp_verts, info->userdata); - return 0; - } - if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex)); - STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex)); - if (vertices) STBTT_free(vertices, info->userdata); - vertices = tmp; - STBTT_free(comp_verts, info->userdata); - num_vertices += comp_num_verts; - } - // More components ? - more = flags & (1<<5); - } - } else if (numberOfContours < 0) { - // @TODO other compound variations? - STBTT_assert(0); - } else { - // numberOfCounters == 0, do nothing - } + if (flags & 2) + { // XY values + if (flags & 1) + { // shorts + mtx[4] = ttSHORT(comp); + comp += 2; + mtx[5] = ttSHORT(comp); + comp += 2; + } + else + { + mtx[4] = ttCHAR(comp); + comp += 1; + mtx[5] = ttCHAR(comp); + comp += 1; + } + } + else + { + // @TODO handle matching point + STBTT_assert(0); + } + if (flags & (1 << 3)) + { // WE_HAVE_A_SCALE + mtx[0] = mtx[3] = ttSHORT(comp) / 16384.0f; + comp += 2; + mtx[1] = mtx[2] = 0; + } + else if (flags & (1 << 6)) + { // WE_HAVE_AN_X_AND_YSCALE + mtx[0] = ttSHORT(comp) / 16384.0f; + comp += 2; + mtx[1] = mtx[2] = 0; + mtx[3] = ttSHORT(comp) / 16384.0f; + comp += 2; + } + else if (flags & (1 << 7)) + { // WE_HAVE_A_TWO_BY_TWO + mtx[0] = ttSHORT(comp) / 16384.0f; + comp += 2; + mtx[1] = ttSHORT(comp) / 16384.0f; + comp += 2; + mtx[2] = ttSHORT(comp) / 16384.0f; + comp += 2; + mtx[3] = ttSHORT(comp) / 16384.0f; + comp += 2; + } - *pvertices = vertices; - return num_vertices; + // Find transformation scales. + m = (float)STBTT_sqrt(mtx[0] * mtx[0] + mtx[1] * mtx[1]); + n = (float)STBTT_sqrt(mtx[2] * mtx[2] + mtx[3] * mtx[3]); + + // Get indexed glyph. + comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts); + if (comp_num_verts > 0) + { + // Transform vertices. + for (i = 0; i < comp_num_verts; ++i) + { + stbtt_vertex *v = &comp_verts[i]; + stbtt_vertex_type x, y; + x = v->x; + y = v->y; + v->x = (stbtt_vertex_type)(m * (mtx[0] * x + mtx[2] * y + mtx[4])); + v->y = (stbtt_vertex_type)(n * (mtx[1] * x + mtx[3] * y + mtx[5])); + x = v->cx; + y = v->cy; + v->cx = (stbtt_vertex_type)(m * (mtx[0] * x + mtx[2] * y + mtx[4])); + v->cy = (stbtt_vertex_type)(n * (mtx[1] * x + mtx[3] * y + mtx[5])); + } + // Append vertices. + tmp = (stbtt_vertex *)STBTT_malloc((num_vertices + comp_num_verts) * sizeof(stbtt_vertex), info->userdata); + if (!tmp) + { + if (vertices) STBTT_free(vertices, info->userdata); + if (comp_verts) STBTT_free(comp_verts, info->userdata); + return 0; + } + if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices * sizeof(stbtt_vertex)); + STBTT_memcpy(tmp + num_vertices, comp_verts, comp_num_verts * sizeof(stbtt_vertex)); + if (vertices) STBTT_free(vertices, info->userdata); + vertices = tmp; + STBTT_free(comp_verts, info->userdata); + num_vertices += comp_num_verts; + } + // More components ? + more = flags & (1 << 5); + } + } + else if (numberOfContours < 0) + { + // @TODO other compound variations? + STBTT_assert(0); + } + else + { + // numberOfCounters == 0, do nothing + } + + *pvertices = vertices; + return num_vertices; } typedef struct { - int bounds; - int started; - float first_x, first_y; - float x, y; - stbtt_int32 min_x, max_x, min_y, max_y; + int bounds; + int started; + float first_x, first_y; + float x, y; + stbtt_int32 min_x, max_x, min_y, max_y; - stbtt_vertex *pvertices; - int num_vertices; + stbtt_vertex *pvertices; + int num_vertices; } stbtt__csctx; -#define STBTT__CSCTX_INIT(bounds) {bounds,0, 0,0, 0,0, 0,0,0,0, NULL, 0} +#define STBTT__CSCTX_INIT(bounds) \ + { \ + bounds, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, 0 \ + } static void stbtt__track_vertex(stbtt__csctx *c, stbtt_int32 x, stbtt_int32 y) { - if (x > c->max_x || !c->started) c->max_x = x; - if (y > c->max_y || !c->started) c->max_y = y; - if (x < c->min_x || !c->started) c->min_x = x; - if (y < c->min_y || !c->started) c->min_y = y; - c->started = 1; + if (x > c->max_x || !c->started) c->max_x = x; + if (y > c->max_y || !c->started) c->max_y = y; + if (x < c->min_x || !c->started) c->min_x = x; + if (y < c->min_y || !c->started) c->min_y = y; + c->started = 1; } static void stbtt__csctx_v(stbtt__csctx *c, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy, stbtt_int32 cx1, stbtt_int32 cy1) { - if (c->bounds) { - stbtt__track_vertex(c, x, y); - if (type == STBTT_vcubic) { - stbtt__track_vertex(c, cx, cy); - stbtt__track_vertex(c, cx1, cy1); - } - } else { - stbtt_setvertex(&c->pvertices[c->num_vertices], type, x, y, cx, cy); - c->pvertices[c->num_vertices].cx1 = (stbtt_int16) cx1; - c->pvertices[c->num_vertices].cy1 = (stbtt_int16) cy1; - } - c->num_vertices++; + if (c->bounds) + { + stbtt__track_vertex(c, x, y); + if (type == STBTT_vcubic) + { + stbtt__track_vertex(c, cx, cy); + stbtt__track_vertex(c, cx1, cy1); + } + } + else + { + stbtt_setvertex(&c->pvertices[c->num_vertices], type, x, y, cx, cy); + c->pvertices[c->num_vertices].cx1 = (stbtt_int16)cx1; + c->pvertices[c->num_vertices].cy1 = (stbtt_int16)cy1; + } + c->num_vertices++; } static void stbtt__csctx_close_shape(stbtt__csctx *ctx) { - if (ctx->first_x != ctx->x || ctx->first_y != ctx->y) - stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->first_x, (int)ctx->first_y, 0, 0, 0, 0); + if (ctx->first_x != ctx->x || ctx->first_y != ctx->y) + stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->first_x, (int)ctx->first_y, 0, 0, 0, 0); } static void stbtt__csctx_rmove_to(stbtt__csctx *ctx, float dx, float dy) { - stbtt__csctx_close_shape(ctx); - ctx->first_x = ctx->x = ctx->x + dx; - ctx->first_y = ctx->y = ctx->y + dy; - stbtt__csctx_v(ctx, STBTT_vmove, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0); + stbtt__csctx_close_shape(ctx); + ctx->first_x = ctx->x = ctx->x + dx; + ctx->first_y = ctx->y = ctx->y + dy; + stbtt__csctx_v(ctx, STBTT_vmove, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0); } static void stbtt__csctx_rline_to(stbtt__csctx *ctx, float dx, float dy) { - ctx->x += dx; - ctx->y += dy; - stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0); + ctx->x += dx; + ctx->y += dy; + stbtt__csctx_v(ctx, STBTT_vline, (int)ctx->x, (int)ctx->y, 0, 0, 0, 0); } static void stbtt__csctx_rccurve_to(stbtt__csctx *ctx, float dx1, float dy1, float dx2, float dy2, float dx3, float dy3) { - float cx1 = ctx->x + dx1; - float cy1 = ctx->y + dy1; - float cx2 = cx1 + dx2; - float cy2 = cy1 + dy2; - ctx->x = cx2 + dx3; - ctx->y = cy2 + dy3; - stbtt__csctx_v(ctx, STBTT_vcubic, (int)ctx->x, (int)ctx->y, (int)cx1, (int)cy1, (int)cx2, (int)cy2); + float cx1 = ctx->x + dx1; + float cy1 = ctx->y + dy1; + float cx2 = cx1 + dx2; + float cy2 = cy1 + dy2; + ctx->x = cx2 + dx3; + ctx->y = cy2 + dy3; + stbtt__csctx_v(ctx, STBTT_vcubic, (int)ctx->x, (int)ctx->y, (int)cx1, (int)cy1, (int)cx2, (int)cy2); } static stbtt__buf stbtt__get_subr(stbtt__buf idx, int n) { - int count = stbtt__cff_index_count(&idx); - int bias = 107; - if (count >= 33900) - bias = 32768; - else if (count >= 1240) - bias = 1131; - n += bias; - if (n < 0 || n >= count) - return stbtt__new_buf(NULL, 0); - return stbtt__cff_index_get(idx, n); + int count = stbtt__cff_index_count(&idx); + int bias = 107; + if (count >= 33900) + bias = 32768; + else if (count >= 1240) + bias = 1131; + n += bias; + if (n < 0 || n >= count) + return stbtt__new_buf(NULL, 0); + return stbtt__cff_index_get(idx, n); } static stbtt__buf stbtt__cid_get_glyph_subrs(const stbtt_fontinfo *info, int glyph_index) { - stbtt__buf fdselect = info->fdselect; - int nranges, start, end, v, fmt, fdselector = -1, i; + stbtt__buf fdselect = info->fdselect; + int nranges, start, end, v, fmt, fdselector = -1, i; - stbtt__buf_seek(&fdselect, 0); - fmt = stbtt__buf_get8(&fdselect); - if (fmt == 0) { - // untested - stbtt__buf_skip(&fdselect, glyph_index); - fdselector = stbtt__buf_get8(&fdselect); - } else if (fmt == 3) { - nranges = stbtt__buf_get16(&fdselect); - start = stbtt__buf_get16(&fdselect); - for (i = 0; i < nranges; i++) { - v = stbtt__buf_get8(&fdselect); - end = stbtt__buf_get16(&fdselect); - if (glyph_index >= start && glyph_index < end) { - fdselector = v; - break; - } - start = end; - } - } - if (fdselector == -1) stbtt__new_buf(NULL, 0); - return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector)); + stbtt__buf_seek(&fdselect, 0); + fmt = stbtt__buf_get8(&fdselect); + if (fmt == 0) + { + // untested + stbtt__buf_skip(&fdselect, glyph_index); + fdselector = stbtt__buf_get8(&fdselect); + } + else if (fmt == 3) + { + nranges = stbtt__buf_get16(&fdselect); + start = stbtt__buf_get16(&fdselect); + for (i = 0; i < nranges; i++) + { + v = stbtt__buf_get8(&fdselect); + end = stbtt__buf_get16(&fdselect); + if (glyph_index >= start && glyph_index < end) + { + fdselector = v; + break; + } + start = end; + } + } + if (fdselector == -1) stbtt__new_buf(NULL, 0); + return stbtt__get_subrs(info->cff, stbtt__cff_index_get(info->fontdicts, fdselector)); } static int stbtt__run_charstring(const stbtt_fontinfo *info, int glyph_index, stbtt__csctx *c) { - int in_header = 1, maskbits = 0, subr_stack_height = 0, sp = 0, v, i, b0; - int has_subrs = 0, clear_stack; - float s[48]; - stbtt__buf subr_stack[10], subrs = info->subrs, b; - float f; + int in_header = 1, maskbits = 0, subr_stack_height = 0, sp = 0, v, i, b0; + int has_subrs = 0, clear_stack; + float s[48]; + stbtt__buf subr_stack[10], subrs = info->subrs, b; + float f; #define STBTT__CSERR(s) (0) - // this currently ignores the initial width value, which isn't needed if we have hmtx - b = stbtt__cff_index_get(info->charstrings, glyph_index); - while (b.cursor < b.size) { - i = 0; - clear_stack = 1; - b0 = stbtt__buf_get8(&b); - switch (b0) { - // @TODO implement hinting - case 0x13: // hintmask - case 0x14: // cntrmask - if (in_header) - maskbits += (sp / 2); // implicit "vstem" - in_header = 0; - stbtt__buf_skip(&b, (maskbits + 7) / 8); - break; + // this currently ignores the initial width value, which isn't needed if we have hmtx + b = stbtt__cff_index_get(info->charstrings, glyph_index); + while (b.cursor < b.size) + { + i = 0; + clear_stack = 1; + b0 = stbtt__buf_get8(&b); + switch (b0) + { + // @TODO implement hinting + case 0x13: // hintmask + case 0x14: // cntrmask + if (in_header) + maskbits += (sp / 2); // implicit "vstem" + in_header = 0; + stbtt__buf_skip(&b, (maskbits + 7) / 8); + break; - case 0x01: // hstem - case 0x03: // vstem - case 0x12: // hstemhm - case 0x17: // vstemhm - maskbits += (sp / 2); - break; + case 0x01: // hstem + case 0x03: // vstem + case 0x12: // hstemhm + case 0x17: // vstemhm + maskbits += (sp / 2); + break; - case 0x15: // rmoveto - in_header = 0; - if (sp < 2) return STBTT__CSERR("rmoveto stack"); - stbtt__csctx_rmove_to(c, s[sp-2], s[sp-1]); - break; - case 0x04: // vmoveto - in_header = 0; - if (sp < 1) return STBTT__CSERR("vmoveto stack"); - stbtt__csctx_rmove_to(c, 0, s[sp-1]); - break; - case 0x16: // hmoveto - in_header = 0; - if (sp < 1) return STBTT__CSERR("hmoveto stack"); - stbtt__csctx_rmove_to(c, s[sp-1], 0); - break; + case 0x15: // rmoveto + in_header = 0; + if (sp < 2) return STBTT__CSERR("rmoveto stack"); + stbtt__csctx_rmove_to(c, s[sp - 2], s[sp - 1]); + break; + case 0x04: // vmoveto + in_header = 0; + if (sp < 1) return STBTT__CSERR("vmoveto stack"); + stbtt__csctx_rmove_to(c, 0, s[sp - 1]); + break; + case 0x16: // hmoveto + in_header = 0; + if (sp < 1) return STBTT__CSERR("hmoveto stack"); + stbtt__csctx_rmove_to(c, s[sp - 1], 0); + break; - case 0x05: // rlineto - if (sp < 2) return STBTT__CSERR("rlineto stack"); - for (; i + 1 < sp; i += 2) - stbtt__csctx_rline_to(c, s[i], s[i+1]); - break; + case 0x05: // rlineto + if (sp < 2) return STBTT__CSERR("rlineto stack"); + for (; i + 1 < sp; i += 2) + stbtt__csctx_rline_to(c, s[i], s[i + 1]); + break; - // hlineto/vlineto and vhcurveto/hvcurveto alternate horizontal and vertical - // starting from a different place. + // hlineto/vlineto and vhcurveto/hvcurveto alternate horizontal and vertical + // starting from a different place. - case 0x07: // vlineto - if (sp < 1) return STBTT__CSERR("vlineto stack"); - goto vlineto; - case 0x06: // hlineto - if (sp < 1) return STBTT__CSERR("hlineto stack"); - for (;;) { - if (i >= sp) break; - stbtt__csctx_rline_to(c, s[i], 0); - i++; - vlineto: - if (i >= sp) break; - stbtt__csctx_rline_to(c, 0, s[i]); - i++; - } - break; + case 0x07: // vlineto + if (sp < 1) return STBTT__CSERR("vlineto stack"); + goto vlineto; + case 0x06: // hlineto + if (sp < 1) return STBTT__CSERR("hlineto stack"); + for (;;) + { + if (i >= sp) break; + stbtt__csctx_rline_to(c, s[i], 0); + i++; + vlineto: + if (i >= sp) break; + stbtt__csctx_rline_to(c, 0, s[i]); + i++; + } + break; - case 0x1F: // hvcurveto - if (sp < 4) return STBTT__CSERR("hvcurveto stack"); - goto hvcurveto; - case 0x1E: // vhcurveto - if (sp < 4) return STBTT__CSERR("vhcurveto stack"); - for (;;) { - if (i + 3 >= sp) break; - stbtt__csctx_rccurve_to(c, 0, s[i], s[i+1], s[i+2], s[i+3], (sp - i == 5) ? s[i + 4] : 0.0f); - i += 4; - hvcurveto: - if (i + 3 >= sp) break; - stbtt__csctx_rccurve_to(c, s[i], 0, s[i+1], s[i+2], (sp - i == 5) ? s[i+4] : 0.0f, s[i+3]); - i += 4; - } - break; + case 0x1F: // hvcurveto + if (sp < 4) return STBTT__CSERR("hvcurveto stack"); + goto hvcurveto; + case 0x1E: // vhcurveto + if (sp < 4) return STBTT__CSERR("vhcurveto stack"); + for (;;) + { + if (i + 3 >= sp) break; + stbtt__csctx_rccurve_to(c, 0, s[i], s[i + 1], s[i + 2], s[i + 3], (sp - i == 5) ? s[i + 4] : 0.0f); + i += 4; + hvcurveto: + if (i + 3 >= sp) break; + stbtt__csctx_rccurve_to(c, s[i], 0, s[i + 1], s[i + 2], (sp - i == 5) ? s[i + 4] : 0.0f, s[i + 3]); + i += 4; + } + break; - case 0x08: // rrcurveto - if (sp < 6) return STBTT__CSERR("rcurveline stack"); - for (; i + 5 < sp; i += 6) - stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]); - break; + case 0x08: // rrcurveto + if (sp < 6) return STBTT__CSERR("rcurveline stack"); + for (; i + 5 < sp; i += 6) + stbtt__csctx_rccurve_to(c, s[i], s[i + 1], s[i + 2], s[i + 3], s[i + 4], s[i + 5]); + break; - case 0x18: // rcurveline - if (sp < 8) return STBTT__CSERR("rcurveline stack"); - for (; i + 5 < sp - 2; i += 6) - stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]); - if (i + 1 >= sp) return STBTT__CSERR("rcurveline stack"); - stbtt__csctx_rline_to(c, s[i], s[i+1]); - break; + case 0x18: // rcurveline + if (sp < 8) return STBTT__CSERR("rcurveline stack"); + for (; i + 5 < sp - 2; i += 6) + stbtt__csctx_rccurve_to(c, s[i], s[i + 1], s[i + 2], s[i + 3], s[i + 4], s[i + 5]); + if (i + 1 >= sp) return STBTT__CSERR("rcurveline stack"); + stbtt__csctx_rline_to(c, s[i], s[i + 1]); + break; - case 0x19: // rlinecurve - if (sp < 8) return STBTT__CSERR("rlinecurve stack"); - for (; i + 1 < sp - 6; i += 2) - stbtt__csctx_rline_to(c, s[i], s[i+1]); - if (i + 5 >= sp) return STBTT__CSERR("rlinecurve stack"); - stbtt__csctx_rccurve_to(c, s[i], s[i+1], s[i+2], s[i+3], s[i+4], s[i+5]); - break; + case 0x19: // rlinecurve + if (sp < 8) return STBTT__CSERR("rlinecurve stack"); + for (; i + 1 < sp - 6; i += 2) + stbtt__csctx_rline_to(c, s[i], s[i + 1]); + if (i + 5 >= sp) return STBTT__CSERR("rlinecurve stack"); + stbtt__csctx_rccurve_to(c, s[i], s[i + 1], s[i + 2], s[i + 3], s[i + 4], s[i + 5]); + break; - case 0x1A: // vvcurveto - case 0x1B: // hhcurveto - if (sp < 4) return STBTT__CSERR("(vv|hh)curveto stack"); - f = 0.0; - if (sp & 1) { f = s[i]; i++; } - for (; i + 3 < sp; i += 4) { - if (b0 == 0x1B) - stbtt__csctx_rccurve_to(c, s[i], f, s[i+1], s[i+2], s[i+3], 0.0); - else - stbtt__csctx_rccurve_to(c, f, s[i], s[i+1], s[i+2], 0.0, s[i+3]); - f = 0.0; - } - break; + case 0x1A: // vvcurveto + case 0x1B: // hhcurveto + if (sp < 4) return STBTT__CSERR("(vv|hh)curveto stack"); + f = 0.0; + if (sp & 1) + { + f = s[i]; + i++; + } + for (; i + 3 < sp; i += 4) + { + if (b0 == 0x1B) + stbtt__csctx_rccurve_to(c, s[i], f, s[i + 1], s[i + 2], s[i + 3], 0.0); + else + stbtt__csctx_rccurve_to(c, f, s[i], s[i + 1], s[i + 2], 0.0, s[i + 3]); + f = 0.0; + } + break; - case 0x0A: // callsubr - if (!has_subrs) { - if (info->fdselect.size) - subrs = stbtt__cid_get_glyph_subrs(info, glyph_index); - has_subrs = 1; - } - // fallthrough - case 0x1D: // callgsubr - if (sp < 1) return STBTT__CSERR("call(g|)subr stack"); - v = (int) s[--sp]; - if (subr_stack_height >= 10) return STBTT__CSERR("recursion limit"); - subr_stack[subr_stack_height++] = b; - b = stbtt__get_subr(b0 == 0x0A ? subrs : info->gsubrs, v); - if (b.size == 0) return STBTT__CSERR("subr not found"); - b.cursor = 0; - clear_stack = 0; - break; + case 0x0A: // callsubr + if (!has_subrs) + { + if (info->fdselect.size) + subrs = stbtt__cid_get_glyph_subrs(info, glyph_index); + has_subrs = 1; + } + // fallthrough + case 0x1D: // callgsubr + if (sp < 1) return STBTT__CSERR("call(g|)subr stack"); + v = (int)s[--sp]; + if (subr_stack_height >= 10) return STBTT__CSERR("recursion limit"); + subr_stack[subr_stack_height++] = b; + b = stbtt__get_subr(b0 == 0x0A ? subrs : info->gsubrs, v); + if (b.size == 0) return STBTT__CSERR("subr not found"); + b.cursor = 0; + clear_stack = 0; + break; - case 0x0B: // return - if (subr_stack_height <= 0) return STBTT__CSERR("return outside subr"); - b = subr_stack[--subr_stack_height]; - clear_stack = 0; - break; + case 0x0B: // return + if (subr_stack_height <= 0) return STBTT__CSERR("return outside subr"); + b = subr_stack[--subr_stack_height]; + clear_stack = 0; + break; - case 0x0E: // endchar - stbtt__csctx_close_shape(c); - return 1; + case 0x0E: // endchar + stbtt__csctx_close_shape(c); + return 1; - case 0x0C: { // two-byte escape - float dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy3, dy4, dy5, dy6; - float dx, dy; - int b1 = stbtt__buf_get8(&b); - switch (b1) { - // @TODO These "flex" implementations ignore the flex-depth and resolution, - // and always draw beziers. - case 0x22: // hflex - if (sp < 7) return STBTT__CSERR("hflex stack"); - dx1 = s[0]; - dx2 = s[1]; - dy2 = s[2]; - dx3 = s[3]; - dx4 = s[4]; - dx5 = s[5]; - dx6 = s[6]; - stbtt__csctx_rccurve_to(c, dx1, 0, dx2, dy2, dx3, 0); - stbtt__csctx_rccurve_to(c, dx4, 0, dx5, -dy2, dx6, 0); - break; + case 0x0C: + { // two-byte escape + float dx1, dx2, dx3, dx4, dx5, dx6, dy1, dy2, dy3, dy4, dy5, dy6; + float dx, dy; + int b1 = stbtt__buf_get8(&b); + switch (b1) + { + // @TODO These "flex" implementations ignore the flex-depth and resolution, + // and always draw beziers. + case 0x22: // hflex + if (sp < 7) return STBTT__CSERR("hflex stack"); + dx1 = s[0]; + dx2 = s[1]; + dy2 = s[2]; + dx3 = s[3]; + dx4 = s[4]; + dx5 = s[5]; + dx6 = s[6]; + stbtt__csctx_rccurve_to(c, dx1, 0, dx2, dy2, dx3, 0); + stbtt__csctx_rccurve_to(c, dx4, 0, dx5, -dy2, dx6, 0); + break; - case 0x23: // flex - if (sp < 13) return STBTT__CSERR("flex stack"); - dx1 = s[0]; - dy1 = s[1]; - dx2 = s[2]; - dy2 = s[3]; - dx3 = s[4]; - dy3 = s[5]; - dx4 = s[6]; - dy4 = s[7]; - dx5 = s[8]; - dy5 = s[9]; - dx6 = s[10]; - dy6 = s[11]; - //fd is s[12] - stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3); - stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6); - break; + case 0x23: // flex + if (sp < 13) return STBTT__CSERR("flex stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dy3 = s[5]; + dx4 = s[6]; + dy4 = s[7]; + dx5 = s[8]; + dy5 = s[9]; + dx6 = s[10]; + dy6 = s[11]; + //fd is s[12] + stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3); + stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6); + break; - case 0x24: // hflex1 - if (sp < 9) return STBTT__CSERR("hflex1 stack"); - dx1 = s[0]; - dy1 = s[1]; - dx2 = s[2]; - dy2 = s[3]; - dx3 = s[4]; - dx4 = s[5]; - dx5 = s[6]; - dy5 = s[7]; - dx6 = s[8]; - stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, 0); - stbtt__csctx_rccurve_to(c, dx4, 0, dx5, dy5, dx6, -(dy1+dy2+dy5)); - break; + case 0x24: // hflex1 + if (sp < 9) return STBTT__CSERR("hflex1 stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dx4 = s[5]; + dx5 = s[6]; + dy5 = s[7]; + dx6 = s[8]; + stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, 0); + stbtt__csctx_rccurve_to(c, dx4, 0, dx5, dy5, dx6, -(dy1 + dy2 + dy5)); + break; - case 0x25: // flex1 - if (sp < 11) return STBTT__CSERR("flex1 stack"); - dx1 = s[0]; - dy1 = s[1]; - dx2 = s[2]; - dy2 = s[3]; - dx3 = s[4]; - dy3 = s[5]; - dx4 = s[6]; - dy4 = s[7]; - dx5 = s[8]; - dy5 = s[9]; - dx6 = dy6 = s[10]; - dx = dx1+dx2+dx3+dx4+dx5; - dy = dy1+dy2+dy3+dy4+dy5; - if (STBTT_fabs(dx) > STBTT_fabs(dy)) - dy6 = -dy; - else - dx6 = -dx; - stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3); - stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6); - break; + case 0x25: // flex1 + if (sp < 11) return STBTT__CSERR("flex1 stack"); + dx1 = s[0]; + dy1 = s[1]; + dx2 = s[2]; + dy2 = s[3]; + dx3 = s[4]; + dy3 = s[5]; + dx4 = s[6]; + dy4 = s[7]; + dx5 = s[8]; + dy5 = s[9]; + dx6 = dy6 = s[10]; + dx = dx1 + dx2 + dx3 + dx4 + dx5; + dy = dy1 + dy2 + dy3 + dy4 + dy5; + if (STBTT_fabs(dx) > STBTT_fabs(dy)) + dy6 = -dy; + else + dx6 = -dx; + stbtt__csctx_rccurve_to(c, dx1, dy1, dx2, dy2, dx3, dy3); + stbtt__csctx_rccurve_to(c, dx4, dy4, dx5, dy5, dx6, dy6); + break; - default: - return STBTT__CSERR("unimplemented"); - } - } break; + default: + return STBTT__CSERR("unimplemented"); + } + } + break; - default: - if (b0 != 255 && b0 != 28 && (b0 < 32 || b0 > 254)) - return STBTT__CSERR("reserved operator"); + default: + if (b0 != 255 && b0 != 28 && (b0 < 32 || b0 > 254)) + return STBTT__CSERR("reserved operator"); - // push immediate - if (b0 == 255) { - f = (float)(stbtt_int32)stbtt__buf_get32(&b) / 0x10000; - } else { - stbtt__buf_skip(&b, -1); - f = (float)(stbtt_int16)stbtt__cff_int(&b); - } - if (sp >= 48) return STBTT__CSERR("push stack overflow"); - s[sp++] = f; - clear_stack = 0; - break; - } - if (clear_stack) sp = 0; - } - return STBTT__CSERR("no endchar"); + // push immediate + if (b0 == 255) + { + f = (float)(stbtt_int32)stbtt__buf_get32(&b) / 0x10000; + } + else + { + stbtt__buf_skip(&b, -1); + f = (float)(stbtt_int16)stbtt__cff_int(&b); + } + if (sp >= 48) return STBTT__CSERR("push stack overflow"); + s[sp++] = f; + clear_stack = 0; + break; + } + if (clear_stack) sp = 0; + } + return STBTT__CSERR("no endchar"); #undef STBTT__CSERR } static int stbtt__GetGlyphShapeT2(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) { - // runs the charstring twice, once to count and once to output (to avoid realloc) - stbtt__csctx count_ctx = STBTT__CSCTX_INIT(1); - stbtt__csctx output_ctx = STBTT__CSCTX_INIT(0); - if (stbtt__run_charstring(info, glyph_index, &count_ctx)) { - *pvertices = (stbtt_vertex*)STBTT_malloc(count_ctx.num_vertices*sizeof(stbtt_vertex), info->userdata); - output_ctx.pvertices = *pvertices; - if (stbtt__run_charstring(info, glyph_index, &output_ctx)) { - STBTT_assert(output_ctx.num_vertices == count_ctx.num_vertices); - return output_ctx.num_vertices; - } - } - *pvertices = NULL; - return 0; + // runs the charstring twice, once to count and once to output (to avoid realloc) + stbtt__csctx count_ctx = STBTT__CSCTX_INIT(1); + stbtt__csctx output_ctx = STBTT__CSCTX_INIT(0); + if (stbtt__run_charstring(info, glyph_index, &count_ctx)) + { + *pvertices = (stbtt_vertex *)STBTT_malloc(count_ctx.num_vertices * sizeof(stbtt_vertex), info->userdata); + output_ctx.pvertices = *pvertices; + if (stbtt__run_charstring(info, glyph_index, &output_ctx)) + { + STBTT_assert(output_ctx.num_vertices == count_ctx.num_vertices); + return output_ctx.num_vertices; + } + } + *pvertices = NULL; + return 0; } static int stbtt__GetGlyphInfoT2(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) { - stbtt__csctx c = STBTT__CSCTX_INIT(1); - int r = stbtt__run_charstring(info, glyph_index, &c); - if (x0) *x0 = r ? c.min_x : 0; - if (y0) *y0 = r ? c.min_y : 0; - if (x1) *x1 = r ? c.max_x : 0; - if (y1) *y1 = r ? c.max_y : 0; - return r ? c.num_vertices : 0; + stbtt__csctx c = STBTT__CSCTX_INIT(1); + int r = stbtt__run_charstring(info, glyph_index, &c); + if (x0) *x0 = r ? c.min_x : 0; + if (y0) *y0 = r ? c.min_y : 0; + if (x1) *x1 = r ? c.max_x : 0; + if (y1) *y1 = r ? c.max_y : 0; + return r ? c.num_vertices : 0; } STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) { - if (!info->cff.size) - return stbtt__GetGlyphShapeTT(info, glyph_index, pvertices); - else - return stbtt__GetGlyphShapeT2(info, glyph_index, pvertices); + if (!info->cff.size) + return stbtt__GetGlyphShapeTT(info, glyph_index, pvertices); + else + return stbtt__GetGlyphShapeT2(info, glyph_index, pvertices); } STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing) { - stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data+info->hhea + 34); - if (glyph_index < numOfLongHorMetrics) { - if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*glyph_index); - if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*glyph_index + 2); - } else { - if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1)); - if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics)); - } + stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data + info->hhea + 34); + if (glyph_index < numOfLongHorMetrics) + { + if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4 * glyph_index); + if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4 * glyph_index + 2); + } + else + { + if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4 * (numOfLongHorMetrics - 1)); + if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4 * numOfLongHorMetrics + 2 * (glyph_index - numOfLongHorMetrics)); + } } -static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) +static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) { - stbtt_uint8 *data = info->data + info->kern; - stbtt_uint32 needle, straw; - int l, r, m; + stbtt_uint8 *data = info->data + info->kern; + stbtt_uint32 needle, straw; + int l, r, m; - // we only look at the first table. it must be 'horizontal' and format 0. - if (!info->kern) - return 0; - if (ttUSHORT(data+2) < 1) // number of tables, need at least 1 - return 0; - if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format - return 0; + // we only look at the first table. it must be 'horizontal' and format 0. + if (!info->kern) + return 0; + if (ttUSHORT(data + 2) < 1) // number of tables, need at least 1 + return 0; + if (ttUSHORT(data + 8) != 1) // horizontal flag must be set in format + return 0; - l = 0; - r = ttUSHORT(data+10) - 1; - needle = glyph1 << 16 | glyph2; - while (l <= r) { - m = (l + r) >> 1; - straw = ttULONG(data+18+(m*6)); // note: unaligned read - if (needle < straw) - r = m - 1; - else if (needle > straw) - l = m + 1; - else - return ttSHORT(data+22+(m*6)); - } - return 0; + l = 0; + r = ttUSHORT(data + 10) - 1; + needle = glyph1 << 16 | glyph2; + while (l <= r) + { + m = (l + r) >> 1; + straw = ttULONG(data + 18 + (m * 6)); // note: unaligned read + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else + return ttSHORT(data + 22 + (m * 6)); + } + return 0; } -static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyph) +static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyph) { - stbtt_uint16 coverageFormat = ttUSHORT(coverageTable); - switch(coverageFormat) { - case 1: { - stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2); + stbtt_uint16 coverageFormat = ttUSHORT(coverageTable); + switch (coverageFormat) + { + case 1: + { + stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2); - // Binary search. - stbtt_int32 l=0, r=glyphCount-1, m; - int straw, needle=glyph; - while (l <= r) { - stbtt_uint8 *glyphArray = coverageTable + 4; - stbtt_uint16 glyphID; - m = (l + r) >> 1; - glyphID = ttUSHORT(glyphArray + 2 * m); - straw = glyphID; - if (needle < straw) - r = m - 1; - else if (needle > straw) - l = m + 1; - else { - return m; - } - } - } break; + // Binary search. + stbtt_int32 l = 0, r = glyphCount - 1, m; + int straw, needle = glyph; + while (l <= r) + { + stbtt_uint8 *glyphArray = coverageTable + 4; + stbtt_uint16 glyphID; + m = (l + r) >> 1; + glyphID = ttUSHORT(glyphArray + 2 * m); + straw = glyphID; + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else + { + return m; + } + } + } + break; - case 2: { - stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2); - stbtt_uint8 *rangeArray = coverageTable + 4; + case 2: + { + stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2); + stbtt_uint8 *rangeArray = coverageTable + 4; - // Binary search. - stbtt_int32 l=0, r=rangeCount-1, m; - int strawStart, strawEnd, needle=glyph; - while (l <= r) { - stbtt_uint8 *rangeRecord; - m = (l + r) >> 1; - rangeRecord = rangeArray + 6 * m; - strawStart = ttUSHORT(rangeRecord); - strawEnd = ttUSHORT(rangeRecord + 2); - if (needle < strawStart) - r = m - 1; - else if (needle > strawEnd) - l = m + 1; - else { - stbtt_uint16 startCoverageIndex = ttUSHORT(rangeRecord + 4); - return startCoverageIndex + glyph - strawStart; - } - } - } break; + // Binary search. + stbtt_int32 l = 0, r = rangeCount - 1, m; + int strawStart, strawEnd, needle = glyph; + while (l <= r) + { + stbtt_uint8 *rangeRecord; + m = (l + r) >> 1; + rangeRecord = rangeArray + 6 * m; + strawStart = ttUSHORT(rangeRecord); + strawEnd = ttUSHORT(rangeRecord + 2); + if (needle < strawStart) + r = m - 1; + else if (needle > strawEnd) + l = m + 1; + else + { + stbtt_uint16 startCoverageIndex = ttUSHORT(rangeRecord + 4); + return startCoverageIndex + glyph - strawStart; + } + } + } + break; - default: { - // There are no other cases. - STBTT_assert(0); - } break; - } + default: + { + // There are no other cases. + STBTT_assert(0); + } + break; + } - return -1; + return -1; } -static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph) +static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph) { - stbtt_uint16 classDefFormat = ttUSHORT(classDefTable); - switch(classDefFormat) - { - case 1: { - stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2); - stbtt_uint16 glyphCount = ttUSHORT(classDefTable + 4); - stbtt_uint8 *classDef1ValueArray = classDefTable + 6; + stbtt_uint16 classDefFormat = ttUSHORT(classDefTable); + switch (classDefFormat) + { + case 1: + { + stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2); + stbtt_uint16 glyphCount = ttUSHORT(classDefTable + 4); + stbtt_uint8 *classDef1ValueArray = classDefTable + 6; - if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount) - return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID)); + if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount) + return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID)); - classDefTable = classDef1ValueArray + 2 * glyphCount; - } break; + classDefTable = classDef1ValueArray + 2 * glyphCount; + } + break; - case 2: { - stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2); - stbtt_uint8 *classRangeRecords = classDefTable + 4; + case 2: + { + stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2); + stbtt_uint8 *classRangeRecords = classDefTable + 4; - // Binary search. - stbtt_int32 l=0, r=classRangeCount-1, m; - int strawStart, strawEnd, needle=glyph; - while (l <= r) { - stbtt_uint8 *classRangeRecord; - m = (l + r) >> 1; - classRangeRecord = classRangeRecords + 6 * m; - strawStart = ttUSHORT(classRangeRecord); - strawEnd = ttUSHORT(classRangeRecord + 2); - if (needle < strawStart) - r = m - 1; - else if (needle > strawEnd) - l = m + 1; - else - return (stbtt_int32)ttUSHORT(classRangeRecord + 4); - } + // Binary search. + stbtt_int32 l = 0, r = classRangeCount - 1, m; + int strawStart, strawEnd, needle = glyph; + while (l <= r) + { + stbtt_uint8 *classRangeRecord; + m = (l + r) >> 1; + classRangeRecord = classRangeRecords + 6 * m; + strawStart = ttUSHORT(classRangeRecord); + strawEnd = ttUSHORT(classRangeRecord + 2); + if (needle < strawStart) + r = m - 1; + else if (needle > strawEnd) + l = m + 1; + else + return (stbtt_int32)ttUSHORT(classRangeRecord + 4); + } - classDefTable = classRangeRecords + 6 * classRangeCount; - } break; + classDefTable = classRangeRecords + 6 * classRangeCount; + } + break; - default: { - // There are no other cases. - STBTT_assert(0); - } break; - } + default: + { + // There are no other cases. + STBTT_assert(0); + } + break; + } - return -1; + return -1; } // Define to STBTT_assert(x) if you want to break on unimplemented formats. #define STBTT_GPOS_TODO_assert(x) -static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) +static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) { - stbtt_uint16 lookupListOffset; - stbtt_uint8 *lookupList; - stbtt_uint16 lookupCount; - stbtt_uint8 *data; - stbtt_int32 i; + stbtt_uint16 lookupListOffset; + stbtt_uint8 *lookupList; + stbtt_uint16 lookupCount; + stbtt_uint8 *data; + stbtt_int32 i; - if (!info->gpos) return 0; + if (!info->gpos) return 0; - data = info->data + info->gpos; + data = info->data + info->gpos; - if (ttUSHORT(data+0) != 1) return 0; // Major version 1 - if (ttUSHORT(data+2) != 0) return 0; // Minor version 0 + if (ttUSHORT(data + 0) != 1) return 0; // Major version 1 + if (ttUSHORT(data + 2) != 0) return 0; // Minor version 0 - lookupListOffset = ttUSHORT(data+8); - lookupList = data + lookupListOffset; - lookupCount = ttUSHORT(lookupList); + lookupListOffset = ttUSHORT(data + 8); + lookupList = data + lookupListOffset; + lookupCount = ttUSHORT(lookupList); - for (i=0; i> 1; - pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m; - secondGlyph = ttUSHORT(pairValue); - straw = secondGlyph; - if (needle < straw) - r = m - 1; - else if (needle > straw) - l = m + 1; - else { - stbtt_int16 xAdvance = ttSHORT(pairValue + 2); - return xAdvance; - } - } - } break; + // Binary search. + while (l <= r) + { + stbtt_uint16 secondGlyph; + stbtt_uint8 *pairValue; + m = (l + r) >> 1; + pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m; + secondGlyph = ttUSHORT(pairValue); + straw = secondGlyph; + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else + { + stbtt_int16 xAdvance = ttSHORT(pairValue + 2); + return xAdvance; + } + } + } + break; - case 2: { - stbtt_uint16 valueFormat1 = ttUSHORT(table + 4); - stbtt_uint16 valueFormat2 = ttUSHORT(table + 6); + case 2: + { + stbtt_uint16 valueFormat1 = ttUSHORT(table + 4); + stbtt_uint16 valueFormat2 = ttUSHORT(table + 6); - stbtt_uint16 classDef1Offset = ttUSHORT(table + 8); - stbtt_uint16 classDef2Offset = ttUSHORT(table + 10); - int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1); - int glyph2class = stbtt__GetGlyphClass(table + classDef2Offset, glyph2); + stbtt_uint16 classDef1Offset = ttUSHORT(table + 8); + stbtt_uint16 classDef2Offset = ttUSHORT(table + 10); + int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1); + int glyph2class = stbtt__GetGlyphClass(table + classDef2Offset, glyph2); - stbtt_uint16 class1Count = ttUSHORT(table + 12); - stbtt_uint16 class2Count = ttUSHORT(table + 14); - STBTT_assert(glyph1class < class1Count); - STBTT_assert(glyph2class < class2Count); + stbtt_uint16 class1Count = ttUSHORT(table + 12); + stbtt_uint16 class2Count = ttUSHORT(table + 14); + STBTT_assert(glyph1class < class1Count); + STBTT_assert(glyph2class < class2Count); - // TODO: Support more formats. - STBTT_GPOS_TODO_assert(valueFormat1 == 4); - if (valueFormat1 != 4) return 0; - STBTT_GPOS_TODO_assert(valueFormat2 == 0); - if (valueFormat2 != 0) return 0; + // TODO: Support more formats. + STBTT_GPOS_TODO_assert(valueFormat1 == 4); + if (valueFormat1 != 4) return 0; + STBTT_GPOS_TODO_assert(valueFormat2 == 0); + if (valueFormat2 != 0) return 0; - if (glyph1class >= 0 && glyph1class < class1Count && glyph2class >= 0 && glyph2class < class2Count) { - stbtt_uint8 *class1Records = table + 16; - stbtt_uint8 *class2Records = class1Records + 2 * (glyph1class * class2Count); - stbtt_int16 xAdvance = ttSHORT(class2Records + 2 * glyph2class); - return xAdvance; - } - } break; + if (glyph1class >= 0 && glyph1class < class1Count && glyph2class >= 0 && glyph2class < class2Count) + { + stbtt_uint8 *class1Records = table + 16; + stbtt_uint8 *class2Records = class1Records + 2 * (glyph1class * class2Count); + stbtt_int16 xAdvance = ttSHORT(class2Records + 2 * glyph2class); + return xAdvance; + } + } + break; - default: { - // There are no other cases. - STBTT_assert(0); - break; - }; - } - } - break; - }; + default: + { + // There are no other cases. + STBTT_assert(0); + break; + }; + } + } + break; + }; - default: - // TODO: Implement other stuff. - break; - } - } + default: + // TODO: Implement other stuff. + break; + } + } - return 0; + return 0; } -STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int g2) +STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int g2) { - int xAdvance = 0; + int xAdvance = 0; - if (info->gpos) - xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2); + if (info->gpos) + xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2); - if (info->kern) - xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2); + if (info->kern) + xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2); - return xAdvance; + return xAdvance; } -STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2) +STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2) { - if (!info->kern && !info->gpos) // if no kerning table, don't waste time looking up both codepoint->glyphs - return 0; - return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2)); + if (!info->kern && !info->gpos) // if no kerning table, don't waste time looking up both codepoint->glyphs + return 0; + return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info, ch1), stbtt_FindGlyphIndex(info, ch2)); } STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing) { - stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info,codepoint), advanceWidth, leftSideBearing); + stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info, codepoint), advanceWidth, leftSideBearing); } STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap) { - if (ascent ) *ascent = ttSHORT(info->data+info->hhea + 4); - if (descent) *descent = ttSHORT(info->data+info->hhea + 6); - if (lineGap) *lineGap = ttSHORT(info->data+info->hhea + 8); + if (ascent) *ascent = ttSHORT(info->data + info->hhea + 4); + if (descent) *descent = ttSHORT(info->data + info->hhea + 6); + if (lineGap) *lineGap = ttSHORT(info->data + info->hhea + 8); } -STBTT_DEF int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap) +STBTT_DEF int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *info, int *typoAscent, int *typoDescent, int *typoLineGap) { - int tab = stbtt__find_table(info->data, info->fontstart, "OS/2"); - if (!tab) - return 0; - if (typoAscent ) *typoAscent = ttSHORT(info->data+tab + 68); - if (typoDescent) *typoDescent = ttSHORT(info->data+tab + 70); - if (typoLineGap) *typoLineGap = ttSHORT(info->data+tab + 72); - return 1; + int tab = stbtt__find_table(info->data, info->fontstart, "OS/2"); + if (!tab) + return 0; + if (typoAscent) *typoAscent = ttSHORT(info->data + tab + 68); + if (typoDescent) *typoDescent = ttSHORT(info->data + tab + 70); + if (typoLineGap) *typoLineGap = ttSHORT(info->data + tab + 72); + return 1; } STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1) { - *x0 = ttSHORT(info->data + info->head + 36); - *y0 = ttSHORT(info->data + info->head + 38); - *x1 = ttSHORT(info->data + info->head + 40); - *y1 = ttSHORT(info->data + info->head + 42); + *x0 = ttSHORT(info->data + info->head + 36); + *y0 = ttSHORT(info->data + info->head + 38); + *x1 = ttSHORT(info->data + info->head + 40); + *y1 = ttSHORT(info->data + info->head + 42); } STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float height) { - int fheight = ttSHORT(info->data + info->hhea + 4) - ttSHORT(info->data + info->hhea + 6); - return (float) height / fheight; + int fheight = ttSHORT(info->data + info->hhea + 4) - ttSHORT(info->data + info->hhea + 6); + return (float)height / fheight; } STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels) { - int unitsPerEm = ttUSHORT(info->data + info->head + 18); - return pixels / unitsPerEm; + int unitsPerEm = ttUSHORT(info->data + info->head + 18); + return pixels / unitsPerEm; } STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v) { - STBTT_free(v, info->userdata); + STBTT_free(v, info->userdata); } ////////////////////////////////////////////////////////////////////////////// @@ -2608,37 +2800,40 @@ STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v) // antialiasing software rasterizer // -STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) +STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) { - int x0=0,y0=0,x1,y1; // =0 suppresses compiler warning - if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) { - // e.g. space character - if (ix0) *ix0 = 0; - if (iy0) *iy0 = 0; - if (ix1) *ix1 = 0; - if (iy1) *iy1 = 0; - } else { - // move to integral bboxes (treating pixels as little squares, what pixels get touched)? - if (ix0) *ix0 = STBTT_ifloor( x0 * scale_x + shift_x); - if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y); - if (ix1) *ix1 = STBTT_iceil ( x1 * scale_x + shift_x); - if (iy1) *iy1 = STBTT_iceil (-y0 * scale_y + shift_y); - } + int x0 = 0, y0 = 0, x1, y1; // =0 suppresses compiler warning + if (!stbtt_GetGlyphBox(font, glyph, &x0, &y0, &x1, &y1)) + { + // e.g. space character + if (ix0) *ix0 = 0; + if (iy0) *iy0 = 0; + if (ix1) *ix1 = 0; + if (iy1) *iy1 = 0; + } + else + { + // move to integral bboxes (treating pixels as little squares, what pixels get touched)? + if (ix0) *ix0 = STBTT_ifloor(x0 * scale_x + shift_x); + if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y); + if (ix1) *ix1 = STBTT_iceil(x1 * scale_x + shift_x); + if (iy1) *iy1 = STBTT_iceil(-y0 * scale_y + shift_y); + } } STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) { - stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1); + stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y, 0.0f, 0.0f, ix0, iy0, ix1, iy1); } STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) { - stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font,codepoint), scale_x, scale_y,shift_x,shift_y, ix0,iy0,ix1,iy1); + stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font, codepoint), scale_x, scale_y, shift_x, shift_y, ix0, iy0, ix1, iy1); } STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) { - stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y,0.0f,0.0f, ix0,iy0,ix1,iy1); + stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y, 0.0f, 0.0f, ix0, iy0, ix1, iy1); } ////////////////////////////////////////////////////////////////////////////// @@ -2647,119 +2842,124 @@ STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codep typedef struct stbtt__hheap_chunk { - struct stbtt__hheap_chunk *next; + struct stbtt__hheap_chunk *next; } stbtt__hheap_chunk; typedef struct stbtt__hheap { - struct stbtt__hheap_chunk *head; - void *first_free; - int num_remaining_in_head_chunk; + struct stbtt__hheap_chunk *head; + void *first_free; + int num_remaining_in_head_chunk; } stbtt__hheap; static void *stbtt__hheap_alloc(stbtt__hheap *hh, size_t size, void *userdata) { - if (hh->first_free) { - void *p = hh->first_free; - hh->first_free = * (void **) p; - return p; - } else { - if (hh->num_remaining_in_head_chunk == 0) { - int count = (size < 32 ? 2000 : size < 128 ? 800 : 100); - stbtt__hheap_chunk *c = (stbtt__hheap_chunk *) STBTT_malloc(sizeof(stbtt__hheap_chunk) + size * count, userdata); - if (c == NULL) - return NULL; - c->next = hh->head; - hh->head = c; - hh->num_remaining_in_head_chunk = count; - } - --hh->num_remaining_in_head_chunk; - return (char *) (hh->head) + sizeof(stbtt__hheap_chunk) + size * hh->num_remaining_in_head_chunk; - } + if (hh->first_free) + { + void *p = hh->first_free; + hh->first_free = *(void **)p; + return p; + } + else + { + if (hh->num_remaining_in_head_chunk == 0) + { + int count = (size < 32 ? 2000 : size < 128 ? 800 : 100); + stbtt__hheap_chunk *c = (stbtt__hheap_chunk *)STBTT_malloc(sizeof(stbtt__hheap_chunk) + size * count, userdata); + if (c == NULL) + return NULL; + c->next = hh->head; + hh->head = c; + hh->num_remaining_in_head_chunk = count; + } + --hh->num_remaining_in_head_chunk; + return (char *)(hh->head) + sizeof(stbtt__hheap_chunk) + size * hh->num_remaining_in_head_chunk; + } } static void stbtt__hheap_free(stbtt__hheap *hh, void *p) { - *(void **) p = hh->first_free; - hh->first_free = p; + *(void **)p = hh->first_free; + hh->first_free = p; } static void stbtt__hheap_cleanup(stbtt__hheap *hh, void *userdata) { - stbtt__hheap_chunk *c = hh->head; - while (c) { - stbtt__hheap_chunk *n = c->next; - STBTT_free(c, userdata); - c = n; - } + stbtt__hheap_chunk *c = hh->head; + while (c) + { + stbtt__hheap_chunk *n = c->next; + STBTT_free(c, userdata); + c = n; + } } -typedef struct stbtt__edge { - float x0,y0, x1,y1; - int invert; +typedef struct stbtt__edge +{ + float x0, y0, x1, y1; + int invert; } stbtt__edge; - typedef struct stbtt__active_edge { - struct stbtt__active_edge *next; - #if STBTT_RASTERIZER_VERSION==1 - int x,dx; - float ey; - int direction; - #elif STBTT_RASTERIZER_VERSION==2 - float fx,fdx,fdy; - float direction; - float sy; - float ey; - #else - #error "Unrecognized value of STBTT_RASTERIZER_VERSION" - #endif + struct stbtt__active_edge *next; +#if STBTT_RASTERIZER_VERSION == 1 + int x, dx; + float ey; + int direction; +#elif STBTT_RASTERIZER_VERSION == 2 + float fx, fdx, fdy; + float direction; + float sy; + float ey; +#else +#error "Unrecognized value of STBTT_RASTERIZER_VERSION" +#endif } stbtt__active_edge; #if STBTT_RASTERIZER_VERSION == 1 -#define STBTT_FIXSHIFT 10 -#define STBTT_FIX (1 << STBTT_FIXSHIFT) -#define STBTT_FIXMASK (STBTT_FIX-1) +#define STBTT_FIXSHIFT 10 +#define STBTT_FIX (1 << STBTT_FIXSHIFT) +#define STBTT_FIXMASK (STBTT_FIX - 1) static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata) { - stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata); - float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); - STBTT_assert(z != NULL); - if (!z) return z; - - // round dx down to avoid overshooting - if (dxdy < 0) - z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy); - else - z->dx = STBTT_ifloor(STBTT_FIX * dxdy); + stbtt__active_edge *z = (stbtt__active_edge *)stbtt__hheap_alloc(hh, sizeof(*z), userdata); + float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); + STBTT_assert(z != NULL); + if (!z) return z; - z->x = STBTT_ifloor(STBTT_FIX * e->x0 + z->dx * (start_point - e->y0)); // use z->dx so when we offset later it's by the same amount - z->x -= off_x * STBTT_FIX; + // round dx down to avoid overshooting + if (dxdy < 0) + z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy); + else + z->dx = STBTT_ifloor(STBTT_FIX * dxdy); - z->ey = e->y1; - z->next = 0; - z->direction = e->invert ? 1 : -1; - return z; + z->x = STBTT_ifloor(STBTT_FIX * e->x0 + z->dx * (start_point - e->y0)); // use z->dx so when we offset later it's by the same amount + z->x -= off_x * STBTT_FIX; + + z->ey = e->y1; + z->next = 0; + z->direction = e->invert ? 1 : -1; + return z; } #elif STBTT_RASTERIZER_VERSION == 2 static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata) { - stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata); - float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); - STBTT_assert(z != NULL); - //STBTT_assert(e->y0 <= start_point); - if (!z) return z; - z->fdx = dxdy; - z->fdy = dxdy != 0.0f ? (1.0f/dxdy) : 0.0f; - z->fx = e->x0 + dxdy * (start_point - e->y0); - z->fx -= off_x; - z->direction = e->invert ? 1.0f : -1.0f; - z->sy = e->y0; - z->ey = e->y1; - z->next = 0; - return z; + stbtt__active_edge *z = (stbtt__active_edge *)stbtt__hheap_alloc(hh, sizeof(*z), userdata); + float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); + STBTT_assert(z != NULL); + //STBTT_assert(e->y0 <= start_point); + if (!z) return z; + z->fdx = dxdy; + z->fdy = dxdy != 0.0f ? (1.0f / dxdy) : 0.0f; + z->fx = e->x0 + dxdy * (start_point - e->y0); + z->fx -= off_x; + z->direction = e->invert ? 1.0f : -1.0f; + z->sy = e->y0; + z->ey = e->y1; + z->next = 0; + return z; } #else #error "Unrecognized value of STBTT_RASTERIZER_VERSION" @@ -2771,144 +2971,170 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i // are wrong, or if the user supplies a too-small bitmap static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight) { - // non-zero winding fill - int x0=0, w=0; + // non-zero winding fill + int x0 = 0, w = 0; - while (e) { - if (w == 0) { - // if we're currently at zero, we need to record the edge start point - x0 = e->x; w += e->direction; - } else { - int x1 = e->x; w += e->direction; - // if we went to zero, we need to draw - if (w == 0) { - int i = x0 >> STBTT_FIXSHIFT; - int j = x1 >> STBTT_FIXSHIFT; + while (e) + { + if (w == 0) + { + // if we're currently at zero, we need to record the edge start point + x0 = e->x; + w += e->direction; + } + else + { + int x1 = e->x; + w += e->direction; + // if we went to zero, we need to draw + if (w == 0) + { + int i = x0 >> STBTT_FIXSHIFT; + int j = x1 >> STBTT_FIXSHIFT; - if (i < len && j >= 0) { - if (i == j) { - // x0,x1 are the same pixel, so compute combined coverage - scanline[i] = scanline[i] + (stbtt_uint8) ((x1 - x0) * max_weight >> STBTT_FIXSHIFT); - } else { - if (i >= 0) // add antialiasing for x0 - scanline[i] = scanline[i] + (stbtt_uint8) (((STBTT_FIX - (x0 & STBTT_FIXMASK)) * max_weight) >> STBTT_FIXSHIFT); - else - i = -1; // clip + if (i < len && j >= 0) + { + if (i == j) + { + // x0,x1 are the same pixel, so compute combined coverage + scanline[i] = scanline[i] + (stbtt_uint8)((x1 - x0) * max_weight >> STBTT_FIXSHIFT); + } + else + { + if (i >= 0) // add antialiasing for x0 + scanline[i] = scanline[i] + (stbtt_uint8)(((STBTT_FIX - (x0 & STBTT_FIXMASK)) * max_weight) >> STBTT_FIXSHIFT); + else + i = -1; // clip - if (j < len) // add antialiasing for x1 - scanline[j] = scanline[j] + (stbtt_uint8) (((x1 & STBTT_FIXMASK) * max_weight) >> STBTT_FIXSHIFT); - else - j = len; // clip + if (j < len) // add antialiasing for x1 + scanline[j] = scanline[j] + (stbtt_uint8)(((x1 & STBTT_FIXMASK) * max_weight) >> STBTT_FIXSHIFT); + else + j = len; // clip - for (++i; i < j; ++i) // fill pixels between x0 and x1 - scanline[i] = scanline[i] + (stbtt_uint8) max_weight; - } - } - } - } - - e = e->next; - } + for (++i; i < j; ++i) // fill pixels between x0 and x1 + scanline[i] = scanline[i] + (stbtt_uint8)max_weight; + } + } + } + } + + e = e->next; + } } static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata) { - stbtt__hheap hh = { 0, 0, 0 }; - stbtt__active_edge *active = NULL; - int y,j=0; - int max_weight = (255 / vsubsample); // weight per vertical scanline - int s; // vertical subsample index - unsigned char scanline_data[512], *scanline; + stbtt__hheap hh = {0, 0, 0}; + stbtt__active_edge *active = NULL; + int y, j = 0; + int max_weight = (255 / vsubsample); // weight per vertical scanline + int s; // vertical subsample index + unsigned char scanline_data[512], *scanline; - if (result->w > 512) - scanline = (unsigned char *) STBTT_malloc(result->w, userdata); - else - scanline = scanline_data; + if (result->w > 512) + scanline = (unsigned char *)STBTT_malloc(result->w, userdata); + else + scanline = scanline_data; - y = off_y * vsubsample; - e[n].y0 = (off_y + result->h) * (float) vsubsample + 1; + y = off_y * vsubsample; + e[n].y0 = (off_y + result->h) * (float)vsubsample + 1; - while (j < result->h) { - STBTT_memset(scanline, 0, result->w); - for (s=0; s < vsubsample; ++s) { - // find center of pixel for this scanline - float scan_y = y + 0.5f; - stbtt__active_edge **step = &active; + while (j < result->h) + { + STBTT_memset(scanline, 0, result->w); + for (s = 0; s < vsubsample; ++s) + { + // find center of pixel for this scanline + float scan_y = y + 0.5f; + stbtt__active_edge **step = &active; - // update all active edges; - // remove all active edges that terminate before the center of this scanline - while (*step) { - stbtt__active_edge * z = *step; - if (z->ey <= scan_y) { - *step = z->next; // delete from list - STBTT_assert(z->direction); - z->direction = 0; - stbtt__hheap_free(&hh, z); - } else { - z->x += z->dx; // advance to position for current scanline - step = &((*step)->next); // advance through list - } - } + // update all active edges; + // remove all active edges that terminate before the center of this scanline + while (*step) + { + stbtt__active_edge *z = *step; + if (z->ey <= scan_y) + { + *step = z->next; // delete from list + STBTT_assert(z->direction); + z->direction = 0; + stbtt__hheap_free(&hh, z); + } + else + { + z->x += z->dx; // advance to position for current scanline + step = &((*step)->next); // advance through list + } + } - // resort the list if needed - for(;;) { - int changed=0; - step = &active; - while (*step && (*step)->next) { - if ((*step)->x > (*step)->next->x) { - stbtt__active_edge *t = *step; - stbtt__active_edge *q = t->next; + // resort the list if needed + for (;;) + { + int changed = 0; + step = &active; + while (*step && (*step)->next) + { + if ((*step)->x > (*step)->next->x) + { + stbtt__active_edge *t = *step; + stbtt__active_edge *q = t->next; - t->next = q->next; - q->next = t; - *step = q; - changed = 1; - } - step = &(*step)->next; - } - if (!changed) break; - } + t->next = q->next; + q->next = t; + *step = q; + changed = 1; + } + step = &(*step)->next; + } + if (!changed) break; + } - // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline - while (e->y0 <= scan_y) { - if (e->y1 > scan_y) { - stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata); - if (z != NULL) { - // find insertion point - if (active == NULL) - active = z; - else if (z->x < active->x) { - // insert at front - z->next = active; - active = z; - } else { - // find thing to insert AFTER - stbtt__active_edge *p = active; - while (p->next && p->next->x < z->x) - p = p->next; - // at this point, p->next->x is NOT < z->x - z->next = p->next; - p->next = z; - } - } - } - ++e; - } + // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline + while (e->y0 <= scan_y) + { + if (e->y1 > scan_y) + { + stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata); + if (z != NULL) + { + // find insertion point + if (active == NULL) + active = z; + else if (z->x < active->x) + { + // insert at front + z->next = active; + active = z; + } + else + { + // find thing to insert AFTER + stbtt__active_edge *p = active; + while (p->next && p->next->x < z->x) + p = p->next; + // at this point, p->next->x is NOT < z->x + z->next = p->next; + p->next = z; + } + } + } + ++e; + } - // now process all active edges in XOR fashion - if (active) - stbtt__fill_active_edges(scanline, result->w, active, max_weight); + // now process all active edges in XOR fashion + if (active) + stbtt__fill_active_edges(scanline, result->w, active, max_weight); - ++y; - } - STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w); - ++j; - } + ++y; + } + STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w); + ++j; + } - stbtt__hheap_cleanup(&hh, userdata); + stbtt__hheap_cleanup(&hh, userdata); - if (scanline != scanline_data) - STBTT_free(scanline, userdata); + if (scanline != scanline_data) + STBTT_free(scanline, userdata); } #elif STBTT_RASTERIZER_VERSION == 2 @@ -2917,705 +3143,783 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, // (i.e. it has already been clipped to those) static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge *e, float x0, float y0, float x1, float y1) { - if (y0 == y1) return; - STBTT_assert(y0 < y1); - STBTT_assert(e->sy <= e->ey); - if (y0 > e->ey) return; - if (y1 < e->sy) return; - if (y0 < e->sy) { - x0 += (x1-x0) * (e->sy - y0) / (y1-y0); - y0 = e->sy; - } - if (y1 > e->ey) { - x1 += (x1-x0) * (e->ey - y1) / (y1-y0); - y1 = e->ey; - } + if (y0 == y1) return; + STBTT_assert(y0 < y1); + STBTT_assert(e->sy <= e->ey); + if (y0 > e->ey) return; + if (y1 < e->sy) return; + if (y0 < e->sy) + { + x0 += (x1 - x0) * (e->sy - y0) / (y1 - y0); + y0 = e->sy; + } + if (y1 > e->ey) + { + x1 += (x1 - x0) * (e->ey - y1) / (y1 - y0); + y1 = e->ey; + } - if (x0 == x) - STBTT_assert(x1 <= x+1); - else if (x0 == x+1) - STBTT_assert(x1 >= x); - else if (x0 <= x) - STBTT_assert(x1 <= x); - else if (x0 >= x+1) - STBTT_assert(x1 >= x+1); - else - STBTT_assert(x1 >= x && x1 <= x+1); + if (x0 == x) + STBTT_assert(x1 <= x + 1); + else if (x0 == x + 1) + STBTT_assert(x1 >= x); + else if (x0 <= x) + STBTT_assert(x1 <= x); + else if (x0 >= x + 1) + STBTT_assert(x1 >= x + 1); + else + STBTT_assert(x1 >= x && x1 <= x + 1); - if (x0 <= x && x1 <= x) - scanline[x] += e->direction * (y1-y0); - else if (x0 >= x+1 && x1 >= x+1) - ; - else { - STBTT_assert(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1); - scanline[x] += e->direction * (y1-y0) * (1-((x0-x)+(x1-x))/2); // coverage = 1 - average x position - } + if (x0 <= x && x1 <= x) + scanline[x] += e->direction * (y1 - y0); + else if (x0 >= x + 1 && x1 >= x + 1) + ; + else + { + STBTT_assert(x0 >= x && x0 <= x + 1 && x1 >= x && x1 <= x + 1); + scanline[x] += e->direction * (y1 - y0) * (1 - ((x0 - x) + (x1 - x)) / 2); // coverage = 1 - average x position + } } static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, int len, stbtt__active_edge *e, float y_top) { - float y_bottom = y_top+1; + float y_bottom = y_top + 1; - while (e) { - // brute force every pixel + while (e) + { + // brute force every pixel - // compute intersection points with top & bottom - STBTT_assert(e->ey >= y_top); + // compute intersection points with top & bottom + STBTT_assert(e->ey >= y_top); - if (e->fdx == 0) { - float x0 = e->fx; - if (x0 < len) { - if (x0 >= 0) { - stbtt__handle_clipped_edge(scanline,(int) x0,e, x0,y_top, x0,y_bottom); - stbtt__handle_clipped_edge(scanline_fill-1,(int) x0+1,e, x0,y_top, x0,y_bottom); - } else { - stbtt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom); - } - } - } else { - float x0 = e->fx; - float dx = e->fdx; - float xb = x0 + dx; - float x_top, x_bottom; - float sy0,sy1; - float dy = e->fdy; - STBTT_assert(e->sy <= y_bottom && e->ey >= y_top); + if (e->fdx == 0) + { + float x0 = e->fx; + if (x0 < len) + { + if (x0 >= 0) + { + stbtt__handle_clipped_edge(scanline, (int)x0, e, x0, y_top, x0, y_bottom); + stbtt__handle_clipped_edge(scanline_fill - 1, (int)x0 + 1, e, x0, y_top, x0, y_bottom); + } + else + { + stbtt__handle_clipped_edge(scanline_fill - 1, 0, e, x0, y_top, x0, y_bottom); + } + } + } + else + { + float x0 = e->fx; + float dx = e->fdx; + float xb = x0 + dx; + float x_top, x_bottom; + float sy0, sy1; + float dy = e->fdy; + STBTT_assert(e->sy <= y_bottom && e->ey >= y_top); - // compute endpoints of line segment clipped to this scanline (if the - // line segment starts on this scanline. x0 is the intersection of the - // line with y_top, but that may be off the line segment. - if (e->sy > y_top) { - x_top = x0 + dx * (e->sy - y_top); - sy0 = e->sy; - } else { - x_top = x0; - sy0 = y_top; - } - if (e->ey < y_bottom) { - x_bottom = x0 + dx * (e->ey - y_top); - sy1 = e->ey; - } else { - x_bottom = xb; - sy1 = y_bottom; - } + // compute endpoints of line segment clipped to this scanline (if the + // line segment starts on this scanline. x0 is the intersection of the + // line with y_top, but that may be off the line segment. + if (e->sy > y_top) + { + x_top = x0 + dx * (e->sy - y_top); + sy0 = e->sy; + } + else + { + x_top = x0; + sy0 = y_top; + } + if (e->ey < y_bottom) + { + x_bottom = x0 + dx * (e->ey - y_top); + sy1 = e->ey; + } + else + { + x_bottom = xb; + sy1 = y_bottom; + } - if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) { - // from here on, we don't have to range check x values + if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) + { + // from here on, we don't have to range check x values - if ((int) x_top == (int) x_bottom) { - float height; - // simple case, only spans one pixel - int x = (int) x_top; - height = sy1 - sy0; - STBTT_assert(x >= 0 && x < len); - scanline[x] += e->direction * (1-((x_top - x) + (x_bottom-x))/2) * height; - scanline_fill[x] += e->direction * height; // everything right of this pixel is filled - } else { - int x,x1,x2; - float y_crossing, step, sign, area; - // covers 2+ pixels - if (x_top > x_bottom) { - // flip scanline vertically; signed area is the same - float t; - sy0 = y_bottom - (sy0 - y_top); - sy1 = y_bottom - (sy1 - y_top); - t = sy0, sy0 = sy1, sy1 = t; - t = x_bottom, x_bottom = x_top, x_top = t; - dx = -dx; - dy = -dy; - t = x0, x0 = xb, xb = t; - } + if ((int)x_top == (int)x_bottom) + { + float height; + // simple case, only spans one pixel + int x = (int)x_top; + height = sy1 - sy0; + STBTT_assert(x >= 0 && x < len); + scanline[x] += e->direction * (1 - ((x_top - x) + (x_bottom - x)) / 2) * height; + scanline_fill[x] += e->direction * height; // everything right of this pixel is filled + } + else + { + int x, x1, x2; + float y_crossing, step, sign, area; + // covers 2+ pixels + if (x_top > x_bottom) + { + // flip scanline vertically; signed area is the same + float t; + sy0 = y_bottom - (sy0 - y_top); + sy1 = y_bottom - (sy1 - y_top); + t = sy0, sy0 = sy1, sy1 = t; + t = x_bottom, x_bottom = x_top, x_top = t; + dx = -dx; + dy = -dy; + t = x0, x0 = xb, xb = t; + } - x1 = (int) x_top; - x2 = (int) x_bottom; - // compute intersection with y axis at x1+1 - y_crossing = (x1+1 - x0) * dy + y_top; + x1 = (int)x_top; + x2 = (int)x_bottom; + // compute intersection with y axis at x1+1 + y_crossing = (x1 + 1 - x0) * dy + y_top; - sign = e->direction; - // area of the rectangle covered from y0..y_crossing - area = sign * (y_crossing-sy0); - // area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing) - scanline[x1] += area * (1-((x_top - x1)+(x1+1-x1))/2); + sign = e->direction; + // area of the rectangle covered from y0..y_crossing + area = sign * (y_crossing - sy0); + // area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing) + scanline[x1] += area * (1 - ((x_top - x1) + (x1 + 1 - x1)) / 2); - step = sign * dy; - for (x = x1+1; x < x2; ++x) { - scanline[x] += area + step/2; - area += step; - } - y_crossing += dy * (x2 - (x1+1)); + step = sign * dy; + for (x = x1 + 1; x < x2; ++x) + { + scanline[x] += area + step / 2; + area += step; + } + y_crossing += dy * (x2 - (x1 + 1)); - STBTT_assert(STBTT_fabs(area) <= 1.01f); + STBTT_assert(STBTT_fabs(area) <= 1.01f); - scanline[x2] += area + sign * (1-((x2-x2)+(x_bottom-x2))/2) * (sy1-y_crossing); + scanline[x2] += area + sign * (1 - ((x2 - x2) + (x_bottom - x2)) / 2) * (sy1 - y_crossing); - scanline_fill[x2] += sign * (sy1-sy0); - } - } else { - // if edge goes outside of box we're drawing, we require - // clipping logic. since this does not match the intended use - // of this library, we use a different, very slow brute - // force implementation - int x; - for (x=0; x < len; ++x) { - // cases: - // - // there can be up to two intersections with the pixel. any intersection - // with left or right edges can be handled by splitting into two (or three) - // regions. intersections with top & bottom do not necessitate case-wise logic. - // - // the old way of doing this found the intersections with the left & right edges, - // then used some simple logic to produce up to three segments in sorted order - // from top-to-bottom. however, this had a problem: if an x edge was epsilon - // across the x border, then the corresponding y position might not be distinct - // from the other y segment, and it might ignored as an empty segment. to avoid - // that, we need to explicitly produce segments based on x positions. + scanline_fill[x2] += sign * (sy1 - sy0); + } + } + else + { + // if edge goes outside of box we're drawing, we require + // clipping logic. since this does not match the intended use + // of this library, we use a different, very slow brute + // force implementation + int x; + for (x = 0; x < len; ++x) + { + // cases: + // + // there can be up to two intersections with the pixel. any intersection + // with left or right edges can be handled by splitting into two (or three) + // regions. intersections with top & bottom do not necessitate case-wise logic. + // + // the old way of doing this found the intersections with the left & right edges, + // then used some simple logic to produce up to three segments in sorted order + // from top-to-bottom. however, this had a problem: if an x edge was epsilon + // across the x border, then the corresponding y position might not be distinct + // from the other y segment, and it might ignored as an empty segment. to avoid + // that, we need to explicitly produce segments based on x positions. - // rename variables to clearly-defined pairs - float y0 = y_top; - float x1 = (float) (x); - float x2 = (float) (x+1); - float x3 = xb; - float y3 = y_bottom; + // rename variables to clearly-defined pairs + float y0 = y_top; + float x1 = (float)(x); + float x2 = (float)(x + 1); + float x3 = xb; + float y3 = y_bottom; - // x = e->x + e->dx * (y-y_top) - // (y-y_top) = (x - e->x) / e->dx - // y = (x - e->x) / e->dx + y_top - float y1 = (x - x0) / dx + y_top; - float y2 = (x+1 - x0) / dx + y_top; + // x = e->x + e->dx * (y-y_top) + // (y-y_top) = (x - e->x) / e->dx + // y = (x - e->x) / e->dx + y_top + float y1 = (x - x0) / dx + y_top; + float y2 = (x + 1 - x0) / dx + y_top; - if (x0 < x1 && x3 > x2) { // three segments descending down-right - stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1); - stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x2,y2); - stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); - } else if (x3 < x1 && x0 > x2) { // three segments descending down-left - stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2); - stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x1,y1); - stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3); - } else if (x0 < x1 && x3 > x1) { // two segments across x, down-right - stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1); - stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3); - } else if (x3 < x1 && x0 > x1) { // two segments across x, down-left - stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x1,y1); - stbtt__handle_clipped_edge(scanline,x,e, x1,y1, x3,y3); - } else if (x0 < x2 && x3 > x2) { // two segments across x+1, down-right - stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2); - stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); - } else if (x3 < x2 && x0 > x2) { // two segments across x+1, down-left - stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x2,y2); - stbtt__handle_clipped_edge(scanline,x,e, x2,y2, x3,y3); - } else { // one segment - stbtt__handle_clipped_edge(scanline,x,e, x0,y0, x3,y3); - } - } - } - } - e = e->next; - } + if (x0 < x1 && x3 > x2) + { // three segments descending down-right + stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x1, y1); + stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x2, y2); + stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x3, y3); + } + else if (x3 < x1 && x0 > x2) + { // three segments descending down-left + stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x2, y2); + stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x1, y1); + stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x3, y3); + } + else if (x0 < x1 && x3 > x1) + { // two segments across x, down-right + stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x1, y1); + stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x3, y3); + } + else if (x3 < x1 && x0 > x1) + { // two segments across x, down-left + stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x1, y1); + stbtt__handle_clipped_edge(scanline, x, e, x1, y1, x3, y3); + } + else if (x0 < x2 && x3 > x2) + { // two segments across x+1, down-right + stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x2, y2); + stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x3, y3); + } + else if (x3 < x2 && x0 > x2) + { // two segments across x+1, down-left + stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x2, y2); + stbtt__handle_clipped_edge(scanline, x, e, x2, y2, x3, y3); + } + else + { // one segment + stbtt__handle_clipped_edge(scanline, x, e, x0, y0, x3, y3); + } + } + } + } + e = e->next; + } } // directly AA rasterize edges w/o supersampling static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata) { - stbtt__hheap hh = { 0, 0, 0 }; - stbtt__active_edge *active = NULL; - int y,j=0, i; - float scanline_data[129], *scanline, *scanline2; + stbtt__hheap hh = {0, 0, 0}; + stbtt__active_edge *active = NULL; + int y, j = 0, i; + float scanline_data[129], *scanline, *scanline2; - STBTT__NOTUSED(vsubsample); + STBTT__NOTUSED(vsubsample); - if (result->w > 64) - scanline = (float *) STBTT_malloc((result->w*2+1) * sizeof(float), userdata); - else - scanline = scanline_data; + if (result->w > 64) + scanline = (float *)STBTT_malloc((result->w * 2 + 1) * sizeof(float), userdata); + else + scanline = scanline_data; - scanline2 = scanline + result->w; + scanline2 = scanline + result->w; - y = off_y; - e[n].y0 = (float) (off_y + result->h) + 1; + y = off_y; + e[n].y0 = (float)(off_y + result->h) + 1; - while (j < result->h) { - // find center of pixel for this scanline - float scan_y_top = y + 0.0f; - float scan_y_bottom = y + 1.0f; - stbtt__active_edge **step = &active; + while (j < result->h) + { + // find center of pixel for this scanline + float scan_y_top = y + 0.0f; + float scan_y_bottom = y + 1.0f; + stbtt__active_edge **step = &active; - STBTT_memset(scanline , 0, result->w*sizeof(scanline[0])); - STBTT_memset(scanline2, 0, (result->w+1)*sizeof(scanline[0])); + STBTT_memset(scanline, 0, result->w * sizeof(scanline[0])); + STBTT_memset(scanline2, 0, (result->w + 1) * sizeof(scanline[0])); - // update all active edges; - // remove all active edges that terminate before the top of this scanline - while (*step) { - stbtt__active_edge * z = *step; - if (z->ey <= scan_y_top) { - *step = z->next; // delete from list - STBTT_assert(z->direction); - z->direction = 0; - stbtt__hheap_free(&hh, z); - } else { - step = &((*step)->next); // advance through list - } - } + // update all active edges; + // remove all active edges that terminate before the top of this scanline + while (*step) + { + stbtt__active_edge *z = *step; + if (z->ey <= scan_y_top) + { + *step = z->next; // delete from list + STBTT_assert(z->direction); + z->direction = 0; + stbtt__hheap_free(&hh, z); + } + else + { + step = &((*step)->next); // advance through list + } + } - // insert all edges that start before the bottom of this scanline - while (e->y0 <= scan_y_bottom) { - if (e->y0 != e->y1) { - stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata); - if (z != NULL) { - STBTT_assert(z->ey >= scan_y_top); - // insert at front - z->next = active; - active = z; - } - } - ++e; - } + // insert all edges that start before the bottom of this scanline + while (e->y0 <= scan_y_bottom) + { + if (e->y0 != e->y1) + { + stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata); + if (z != NULL) + { + STBTT_assert(z->ey >= scan_y_top); + // insert at front + z->next = active; + active = z; + } + } + ++e; + } - // now process all active edges - if (active) - stbtt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top); + // now process all active edges + if (active) + stbtt__fill_active_edges_new(scanline, scanline2 + 1, result->w, active, scan_y_top); - { - float sum = 0; - for (i=0; i < result->w; ++i) { - float k; - int m; - sum += scanline2[i]; - k = scanline[i] + sum; - k = (float) STBTT_fabs(k)*255 + 0.5f; - m = (int) k; - if (m > 255) m = 255; - result->pixels[j*result->stride + i] = (unsigned char) m; - } - } - // advance all the edges - step = &active; - while (*step) { - stbtt__active_edge *z = *step; - z->fx += z->fdx; // advance to position for current scanline - step = &((*step)->next); // advance through list - } + { + float sum = 0; + for (i = 0; i < result->w; ++i) + { + float k; + int m; + sum += scanline2[i]; + k = scanline[i] + sum; + k = (float)STBTT_fabs(k) * 255 + 0.5f; + m = (int)k; + if (m > 255) m = 255; + result->pixels[j * result->stride + i] = (unsigned char)m; + } + } + // advance all the edges + step = &active; + while (*step) + { + stbtt__active_edge *z = *step; + z->fx += z->fdx; // advance to position for current scanline + step = &((*step)->next); // advance through list + } - ++y; - ++j; - } + ++y; + ++j; + } - stbtt__hheap_cleanup(&hh, userdata); + stbtt__hheap_cleanup(&hh, userdata); - if (scanline != scanline_data) - STBTT_free(scanline, userdata); + if (scanline != scanline_data) + STBTT_free(scanline, userdata); } #else #error "Unrecognized value of STBTT_RASTERIZER_VERSION" #endif -#define STBTT__COMPARE(a,b) ((a)->y0 < (b)->y0) +#define STBTT__COMPARE(a, b) ((a)->y0 < (b)->y0) static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n) { - int i,j; - for (i=1; i < n; ++i) { - stbtt__edge t = p[i], *a = &t; - j = i; - while (j > 0) { - stbtt__edge *b = &p[j-1]; - int c = STBTT__COMPARE(a,b); - if (!c) break; - p[j] = p[j-1]; - --j; - } - if (i != j) - p[j] = t; - } + int i, j; + for (i = 1; i < n; ++i) + { + stbtt__edge t = p[i], *a = &t; + j = i; + while (j > 0) + { + stbtt__edge *b = &p[j - 1]; + int c = STBTT__COMPARE(a, b); + if (!c) break; + p[j] = p[j - 1]; + --j; + } + if (i != j) + p[j] = t; + } } static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n) { - /* threshhold for transitioning to insertion sort */ - while (n > 12) { - stbtt__edge t; - int c01,c12,c,m,i,j; + /* threshhold for transitioning to insertion sort */ + while (n > 12) + { + stbtt__edge t; + int c01, c12, c, m, i, j; - /* compute median of three */ - m = n >> 1; - c01 = STBTT__COMPARE(&p[0],&p[m]); - c12 = STBTT__COMPARE(&p[m],&p[n-1]); - /* if 0 >= mid >= end, or 0 < mid < end, then use mid */ - if (c01 != c12) { - /* otherwise, we'll need to swap something else to middle */ - int z; - c = STBTT__COMPARE(&p[0],&p[n-1]); - /* 0>mid && midn => n; 0 0 */ - /* 0n: 0>n => 0; 0 n */ - z = (c == c12) ? 0 : n-1; - t = p[z]; - p[z] = p[m]; - p[m] = t; - } - /* now p[m] is the median-of-three */ - /* swap it to the beginning so it won't move around */ - t = p[0]; - p[0] = p[m]; - p[m] = t; + /* compute median of three */ + m = n >> 1; + c01 = STBTT__COMPARE(&p[0], &p[m]); + c12 = STBTT__COMPARE(&p[m], &p[n - 1]); + /* if 0 >= mid >= end, or 0 < mid < end, then use mid */ + if (c01 != c12) + { + /* otherwise, we'll need to swap something else to middle */ + int z; + c = STBTT__COMPARE(&p[0], &p[n - 1]); + /* 0>mid && midn => n; 0 0 */ + /* 0n: 0>n => 0; 0 n */ + z = (c == c12) ? 0 : n - 1; + t = p[z]; + p[z] = p[m]; + p[m] = t; + } + /* now p[m] is the median-of-three */ + /* swap it to the beginning so it won't move around */ + t = p[0]; + p[0] = p[m]; + p[m] = t; - /* partition loop */ - i=1; - j=n-1; - for(;;) { - /* handling of equality is crucial here */ - /* for sentinels & efficiency with duplicates */ - for (;;++i) { - if (!STBTT__COMPARE(&p[i], &p[0])) break; - } - for (;;--j) { - if (!STBTT__COMPARE(&p[0], &p[j])) break; - } - /* make sure we haven't crossed */ - if (i >= j) break; - t = p[i]; - p[i] = p[j]; - p[j] = t; + /* partition loop */ + i = 1; + j = n - 1; + for (;;) + { + /* handling of equality is crucial here */ + /* for sentinels & efficiency with duplicates */ + for (;; ++i) + { + if (!STBTT__COMPARE(&p[i], &p[0])) break; + } + for (;; --j) + { + if (!STBTT__COMPARE(&p[0], &p[j])) break; + } + /* make sure we haven't crossed */ + if (i >= j) break; + t = p[i]; + p[i] = p[j]; + p[j] = t; - ++i; - --j; - } - /* recurse on smaller side, iterate on larger */ - if (j < (n-i)) { - stbtt__sort_edges_quicksort(p,j); - p = p+i; - n = n-i; - } else { - stbtt__sort_edges_quicksort(p+i, n-i); - n = j; - } - } + ++i; + --j; + } + /* recurse on smaller side, iterate on larger */ + if (j < (n - i)) + { + stbtt__sort_edges_quicksort(p, j); + p = p + i; + n = n - i; + } + else + { + stbtt__sort_edges_quicksort(p + i, n - i); + n = j; + } + } } static void stbtt__sort_edges(stbtt__edge *p, int n) { - stbtt__sort_edges_quicksort(p, n); - stbtt__sort_edges_ins_sort(p, n); + stbtt__sort_edges_quicksort(p, n); + stbtt__sort_edges_ins_sort(p, n); } typedef struct { - float x,y; + float x, y; } stbtt__point; static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcount, int windings, float scale_x, float scale_y, float shift_x, float shift_y, int off_x, int off_y, int invert, void *userdata) { - float y_scale_inv = invert ? -scale_y : scale_y; - stbtt__edge *e; - int n,i,j,k,m; + float y_scale_inv = invert ? -scale_y : scale_y; + stbtt__edge *e; + int n, i, j, k, m; #if STBTT_RASTERIZER_VERSION == 1 - int vsubsample = result->h < 8 ? 15 : 5; + int vsubsample = result->h < 8 ? 15 : 5; #elif STBTT_RASTERIZER_VERSION == 2 - int vsubsample = 1; + int vsubsample = 1; #else - #error "Unrecognized value of STBTT_RASTERIZER_VERSION" +#error "Unrecognized value of STBTT_RASTERIZER_VERSION" #endif - // vsubsample should divide 255 evenly; otherwise we won't reach full opacity + // vsubsample should divide 255 evenly; otherwise we won't reach full opacity - // now we have to blow out the windings into explicit edge lists - n = 0; - for (i=0; i < windings; ++i) - n += wcount[i]; + // now we have to blow out the windings into explicit edge lists + n = 0; + for (i = 0; i < windings; ++i) + n += wcount[i]; - e = (stbtt__edge *) STBTT_malloc(sizeof(*e) * (n+1), userdata); // add an extra one as a sentinel - if (e == 0) return; - n = 0; + e = (stbtt__edge *)STBTT_malloc(sizeof(*e) * (n + 1), userdata); // add an extra one as a sentinel + if (e == 0) return; + n = 0; - m=0; - for (i=0; i < windings; ++i) { - stbtt__point *p = pts + m; - m += wcount[i]; - j = wcount[i]-1; - for (k=0; k < wcount[i]; j=k++) { - int a=k,b=j; - // skip the edge if horizontal - if (p[j].y == p[k].y) - continue; - // add edge from j to k to the list - e[n].invert = 0; - if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) { - e[n].invert = 1; - a=j,b=k; - } - e[n].x0 = p[a].x * scale_x + shift_x; - e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample; - e[n].x1 = p[b].x * scale_x + shift_x; - e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample; - ++n; - } - } + m = 0; + for (i = 0; i < windings; ++i) + { + stbtt__point *p = pts + m; + m += wcount[i]; + j = wcount[i] - 1; + for (k = 0; k < wcount[i]; j = k++) + { + int a = k, b = j; + // skip the edge if horizontal + if (p[j].y == p[k].y) + continue; + // add edge from j to k to the list + e[n].invert = 0; + if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) + { + e[n].invert = 1; + a = j, b = k; + } + e[n].x0 = p[a].x * scale_x + shift_x; + e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample; + e[n].x1 = p[b].x * scale_x + shift_x; + e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample; + ++n; + } + } - // now sort the edges by their highest point (should snap to integer, and then by x) - //STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare); - stbtt__sort_edges(e, n); + // now sort the edges by their highest point (should snap to integer, and then by x) + //STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare); + stbtt__sort_edges(e, n); - // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule - stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata); + // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule + stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata); - STBTT_free(e, userdata); + STBTT_free(e, userdata); } static void stbtt__add_point(stbtt__point *points, int n, float x, float y) { - if (!points) return; // during first pass, it's unallocated - points[n].x = x; - points[n].y = y; + if (!points) return; // during first pass, it's unallocated + points[n].x = x; + points[n].y = y; } // tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n) { - // midpoint - float mx = (x0 + 2*x1 + x2)/4; - float my = (y0 + 2*y1 + y2)/4; - // versus directly drawn line - float dx = (x0+x2)/2 - mx; - float dy = (y0+y2)/2 - my; - if (n > 16) // 65536 segments on one curve better be enough! - return 1; - if (dx*dx+dy*dy > objspace_flatness_squared) { // half-pixel error allowed... need to be smaller if AA - stbtt__tesselate_curve(points, num_points, x0,y0, (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1); - stbtt__tesselate_curve(points, num_points, mx,my, (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1); - } else { - stbtt__add_point(points, *num_points,x2,y2); - *num_points = *num_points+1; - } - return 1; + // midpoint + float mx = (x0 + 2 * x1 + x2) / 4; + float my = (y0 + 2 * y1 + y2) / 4; + // versus directly drawn line + float dx = (x0 + x2) / 2 - mx; + float dy = (y0 + y2) / 2 - my; + if (n > 16) // 65536 segments on one curve better be enough! + return 1; + if (dx * dx + dy * dy > objspace_flatness_squared) + { // half-pixel error allowed... need to be smaller if AA + stbtt__tesselate_curve(points, num_points, x0, y0, (x0 + x1) / 2.0f, (y0 + y1) / 2.0f, mx, my, objspace_flatness_squared, n + 1); + stbtt__tesselate_curve(points, num_points, mx, my, (x1 + x2) / 2.0f, (y1 + y2) / 2.0f, x2, y2, objspace_flatness_squared, n + 1); + } + else + { + stbtt__add_point(points, *num_points, x2, y2); + *num_points = *num_points + 1; + } + return 1; } static void stbtt__tesselate_cubic(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float objspace_flatness_squared, int n) { - // @TODO this "flatness" calculation is just made-up nonsense that seems to work well enough - float dx0 = x1-x0; - float dy0 = y1-y0; - float dx1 = x2-x1; - float dy1 = y2-y1; - float dx2 = x3-x2; - float dy2 = y3-y2; - float dx = x3-x0; - float dy = y3-y0; - float longlen = (float) (STBTT_sqrt(dx0*dx0+dy0*dy0)+STBTT_sqrt(dx1*dx1+dy1*dy1)+STBTT_sqrt(dx2*dx2+dy2*dy2)); - float shortlen = (float) STBTT_sqrt(dx*dx+dy*dy); - float flatness_squared = longlen*longlen-shortlen*shortlen; + // @TODO this "flatness" calculation is just made-up nonsense that seems to work well enough + float dx0 = x1 - x0; + float dy0 = y1 - y0; + float dx1 = x2 - x1; + float dy1 = y2 - y1; + float dx2 = x3 - x2; + float dy2 = y3 - y2; + float dx = x3 - x0; + float dy = y3 - y0; + float longlen = (float)(STBTT_sqrt(dx0 * dx0 + dy0 * dy0) + STBTT_sqrt(dx1 * dx1 + dy1 * dy1) + STBTT_sqrt(dx2 * dx2 + dy2 * dy2)); + float shortlen = (float)STBTT_sqrt(dx * dx + dy * dy); + float flatness_squared = longlen * longlen - shortlen * shortlen; - if (n > 16) // 65536 segments on one curve better be enough! - return; + if (n > 16) // 65536 segments on one curve better be enough! + return; - if (flatness_squared > objspace_flatness_squared) { - float x01 = (x0+x1)/2; - float y01 = (y0+y1)/2; - float x12 = (x1+x2)/2; - float y12 = (y1+y2)/2; - float x23 = (x2+x3)/2; - float y23 = (y2+y3)/2; + if (flatness_squared > objspace_flatness_squared) + { + float x01 = (x0 + x1) / 2; + float y01 = (y0 + y1) / 2; + float x12 = (x1 + x2) / 2; + float y12 = (y1 + y2) / 2; + float x23 = (x2 + x3) / 2; + float y23 = (y2 + y3) / 2; - float xa = (x01+x12)/2; - float ya = (y01+y12)/2; - float xb = (x12+x23)/2; - float yb = (y12+y23)/2; + float xa = (x01 + x12) / 2; + float ya = (y01 + y12) / 2; + float xb = (x12 + x23) / 2; + float yb = (y12 + y23) / 2; - float mx = (xa+xb)/2; - float my = (ya+yb)/2; + float mx = (xa + xb) / 2; + float my = (ya + yb) / 2; - stbtt__tesselate_cubic(points, num_points, x0,y0, x01,y01, xa,ya, mx,my, objspace_flatness_squared,n+1); - stbtt__tesselate_cubic(points, num_points, mx,my, xb,yb, x23,y23, x3,y3, objspace_flatness_squared,n+1); - } else { - stbtt__add_point(points, *num_points,x3,y3); - *num_points = *num_points+1; - } + stbtt__tesselate_cubic(points, num_points, x0, y0, x01, y01, xa, ya, mx, my, objspace_flatness_squared, n + 1); + stbtt__tesselate_cubic(points, num_points, mx, my, xb, yb, x23, y23, x3, y3, objspace_flatness_squared, n + 1); + } + else + { + stbtt__add_point(points, *num_points, x3, y3); + *num_points = *num_points + 1; + } } // returns number of contours static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata) { - stbtt__point *points=0; - int num_points=0; + stbtt__point *points = 0; + int num_points = 0; - float objspace_flatness_squared = objspace_flatness * objspace_flatness; - int i,n=0,start=0, pass; + float objspace_flatness_squared = objspace_flatness * objspace_flatness; + int i, n = 0, start = 0, pass; - // count how many "moves" there are to get the contour count - for (i=0; i < num_verts; ++i) - if (vertices[i].type == STBTT_vmove) - ++n; + // count how many "moves" there are to get the contour count + for (i = 0; i < num_verts; ++i) + if (vertices[i].type == STBTT_vmove) + ++n; - *num_contours = n; - if (n == 0) return 0; + *num_contours = n; + if (n == 0) return 0; - *contour_lengths = (int *) STBTT_malloc(sizeof(**contour_lengths) * n, userdata); + *contour_lengths = (int *)STBTT_malloc(sizeof(**contour_lengths) * n, userdata); - if (*contour_lengths == 0) { - *num_contours = 0; - return 0; - } + if (*contour_lengths == 0) + { + *num_contours = 0; + return 0; + } - // make two passes through the points so we don't need to realloc - for (pass=0; pass < 2; ++pass) { - float x=0,y=0; - if (pass == 1) { - points = (stbtt__point *) STBTT_malloc(num_points * sizeof(points[0]), userdata); - if (points == NULL) goto error; - } - num_points = 0; - n= -1; - for (i=0; i < num_verts; ++i) { - switch (vertices[i].type) { - case STBTT_vmove: - // start the next contour - if (n >= 0) - (*contour_lengths)[n] = num_points - start; - ++n; - start = num_points; + // make two passes through the points so we don't need to realloc + for (pass = 0; pass < 2; ++pass) + { + float x = 0, y = 0; + if (pass == 1) + { + points = (stbtt__point *)STBTT_malloc(num_points * sizeof(points[0]), userdata); + if (points == NULL) goto error; + } + num_points = 0; + n = -1; + for (i = 0; i < num_verts; ++i) + { + switch (vertices[i].type) + { + case STBTT_vmove: + // start the next contour + if (n >= 0) + (*contour_lengths)[n] = num_points - start; + ++n; + start = num_points; - x = vertices[i].x, y = vertices[i].y; - stbtt__add_point(points, num_points++, x,y); - break; - case STBTT_vline: - x = vertices[i].x, y = vertices[i].y; - stbtt__add_point(points, num_points++, x, y); - break; - case STBTT_vcurve: - stbtt__tesselate_curve(points, &num_points, x,y, - vertices[i].cx, vertices[i].cy, - vertices[i].x, vertices[i].y, - objspace_flatness_squared, 0); - x = vertices[i].x, y = vertices[i].y; - break; - case STBTT_vcubic: - stbtt__tesselate_cubic(points, &num_points, x,y, - vertices[i].cx, vertices[i].cy, - vertices[i].cx1, vertices[i].cy1, - vertices[i].x, vertices[i].y, - objspace_flatness_squared, 0); - x = vertices[i].x, y = vertices[i].y; - break; - } - } - (*contour_lengths)[n] = num_points - start; - } + x = vertices[i].x, y = vertices[i].y; + stbtt__add_point(points, num_points++, x, y); + break; + case STBTT_vline: + x = vertices[i].x, y = vertices[i].y; + stbtt__add_point(points, num_points++, x, y); + break; + case STBTT_vcurve: + stbtt__tesselate_curve(points, &num_points, x, y, + vertices[i].cx, vertices[i].cy, + vertices[i].x, vertices[i].y, + objspace_flatness_squared, 0); + x = vertices[i].x, y = vertices[i].y; + break; + case STBTT_vcubic: + stbtt__tesselate_cubic(points, &num_points, x, y, + vertices[i].cx, vertices[i].cy, + vertices[i].cx1, vertices[i].cy1, + vertices[i].x, vertices[i].y, + objspace_flatness_squared, 0); + x = vertices[i].x, y = vertices[i].y; + break; + } + } + (*contour_lengths)[n] = num_points - start; + } - return points; + return points; error: - STBTT_free(points, userdata); - STBTT_free(*contour_lengths, userdata); - *contour_lengths = 0; - *num_contours = 0; - return NULL; + STBTT_free(points, userdata); + STBTT_free(*contour_lengths, userdata); + *contour_lengths = 0; + *num_contours = 0; + return NULL; } STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata) { - float scale = scale_x > scale_y ? scale_y : scale_x; - int winding_count = 0; - int *winding_lengths = NULL; - stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata); - if (windings) { - stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata); - STBTT_free(winding_lengths, userdata); - STBTT_free(windings, userdata); - } + float scale = scale_x > scale_y ? scale_y : scale_x; + int winding_count = 0; + int *winding_lengths = NULL; + stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata); + if (windings) + { + stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata); + STBTT_free(winding_lengths, userdata); + STBTT_free(windings, userdata); + } } STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata) { - STBTT_free(bitmap, userdata); + STBTT_free(bitmap, userdata); } STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff) { - int ix0,iy0,ix1,iy1; - stbtt__bitmap gbm; - stbtt_vertex *vertices; - int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); + int ix0, iy0, ix1, iy1; + stbtt__bitmap gbm; + stbtt_vertex *vertices; + int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); - if (scale_x == 0) scale_x = scale_y; - if (scale_y == 0) { - if (scale_x == 0) { - STBTT_free(vertices, info->userdata); - return NULL; - } - scale_y = scale_x; - } + if (scale_x == 0) scale_x = scale_y; + if (scale_y == 0) + { + if (scale_x == 0) + { + STBTT_free(vertices, info->userdata); + return NULL; + } + scale_y = scale_x; + } - stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,&ix1,&iy1); + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0, &iy0, &ix1, &iy1); - // now we get the size - gbm.w = (ix1 - ix0); - gbm.h = (iy1 - iy0); - gbm.pixels = NULL; // in case we error + // now we get the size + gbm.w = (ix1 - ix0); + gbm.h = (iy1 - iy0); + gbm.pixels = NULL; // in case we error - if (width ) *width = gbm.w; - if (height) *height = gbm.h; - if (xoff ) *xoff = ix0; - if (yoff ) *yoff = iy0; - - if (gbm.w && gbm.h) { - gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata); - if (gbm.pixels) { - gbm.stride = gbm.w; + if (width) *width = gbm.w; + if (height) *height = gbm.h; + if (xoff) *xoff = ix0; + if (yoff) *yoff = iy0; - stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata); - } - } - STBTT_free(vertices, info->userdata); - return gbm.pixels; -} + if (gbm.w && gbm.h) + { + gbm.pixels = (unsigned char *)STBTT_malloc(gbm.w * gbm.h, info->userdata); + if (gbm.pixels) + { + gbm.stride = gbm.w; + + stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata); + } + } + STBTT_free(vertices, info->userdata); + return gbm.pixels; +} STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff) { - return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff); + return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff); } STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph) { - int ix0,iy0; - stbtt_vertex *vertices; - int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); - stbtt__bitmap gbm; + int ix0, iy0; + stbtt_vertex *vertices; + int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); + stbtt__bitmap gbm; - stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0); - gbm.pixels = output; - gbm.w = out_w; - gbm.h = out_h; - gbm.stride = out_stride; + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0, &iy0, 0, 0); + gbm.pixels = output; + gbm.w = out_w; + gbm.h = out_h; + gbm.stride = out_stride; - if (gbm.w && gbm.h) - stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0,iy0, 1, info->userdata); + if (gbm.w && gbm.h) + stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata); - STBTT_free(vertices, info->userdata); + STBTT_free(vertices, info->userdata); } STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph) { - stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, glyph); + stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f, 0.0f, glyph); } STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff) { - return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff); -} + return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info, codepoint), width, height, xoff, yoff); +} STBTT_DEF void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int oversample_x, int oversample_y, float *sub_x, float *sub_y, int codepoint) { - stbtt_MakeGlyphBitmapSubpixelPrefilter(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, oversample_x, oversample_y, sub_x, sub_y, stbtt_FindGlyphIndex(info,codepoint)); + stbtt_MakeGlyphBitmapSubpixelPrefilter(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, oversample_x, oversample_y, sub_x, sub_y, stbtt_FindGlyphIndex(info, codepoint)); } STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint) { - stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info,codepoint)); + stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info, codepoint)); } STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff) { - return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff); -} + return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, codepoint, width, height, xoff, yoff); +} STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint) { - stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, codepoint); + stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f, 0.0f, codepoint); } ////////////////////////////////////////////////////////////////////////////// @@ -3624,71 +3928,72 @@ STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned ch // // This is SUPER-CRAPPY packing to keep source code small -static int stbtt_BakeFontBitmap_internal(unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) - float pixel_height, // height of font in pixels - unsigned char *pixels, int pw, int ph, // bitmap to be filled in - int first_char, int num_chars, // characters to bake - stbtt_bakedchar *chardata) +static int stbtt_BakeFontBitmap_internal(unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) + float pixel_height, // height of font in pixels + unsigned char *pixels, int pw, int ph, // bitmap to be filled in + int first_char, int num_chars, // characters to bake + stbtt_bakedchar *chardata) { - float scale; - int x,y,bottom_y, i; - stbtt_fontinfo f; - f.userdata = NULL; - if (!stbtt_InitFont(&f, data, offset)) - return -1; - STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels - x=y=1; - bottom_y = 1; + float scale; + int x, y, bottom_y, i; + stbtt_fontinfo f; + f.userdata = NULL; + if (!stbtt_InitFont(&f, data, offset)) + return -1; + STBTT_memset(pixels, 0, pw * ph); // background of 0 around pixels + x = y = 1; + bottom_y = 1; - scale = stbtt_ScaleForPixelHeight(&f, pixel_height); + scale = stbtt_ScaleForPixelHeight(&f, pixel_height); - for (i=0; i < num_chars; ++i) { - int advance, lsb, x0,y0,x1,y1,gw,gh; - int g = stbtt_FindGlyphIndex(&f, first_char + i); - stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb); - stbtt_GetGlyphBitmapBox(&f, g, scale,scale, &x0,&y0,&x1,&y1); - gw = x1-x0; - gh = y1-y0; - if (x + gw + 1 >= pw) - y = bottom_y, x = 1; // advance to next row - if (y + gh + 1 >= ph) // check if it fits vertically AFTER potentially moving to next row - return -i; - STBTT_assert(x+gw < pw); - STBTT_assert(y+gh < ph); - stbtt_MakeGlyphBitmap(&f, pixels+x+y*pw, gw,gh,pw, scale,scale, g); - chardata[i].x0 = (stbtt_int16) x; - chardata[i].y0 = (stbtt_int16) y; - chardata[i].x1 = (stbtt_int16) (x + gw); - chardata[i].y1 = (stbtt_int16) (y + gh); - chardata[i].xadvance = scale * advance; - chardata[i].xoff = (float) x0; - chardata[i].yoff = (float) y0; - x = x + gw + 1; - if (y+gh+1 > bottom_y) - bottom_y = y+gh+1; - } - return bottom_y; + for (i = 0; i < num_chars; ++i) + { + int advance, lsb, x0, y0, x1, y1, gw, gh; + int g = stbtt_FindGlyphIndex(&f, first_char + i); + stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb); + stbtt_GetGlyphBitmapBox(&f, g, scale, scale, &x0, &y0, &x1, &y1); + gw = x1 - x0; + gh = y1 - y0; + if (x + gw + 1 >= pw) + y = bottom_y, x = 1; // advance to next row + if (y + gh + 1 >= ph) // check if it fits vertically AFTER potentially moving to next row + return -i; + STBTT_assert(x + gw < pw); + STBTT_assert(y + gh < ph); + stbtt_MakeGlyphBitmap(&f, pixels + x + y * pw, gw, gh, pw, scale, scale, g); + chardata[i].x0 = (stbtt_int16)x; + chardata[i].y0 = (stbtt_int16)y; + chardata[i].x1 = (stbtt_int16)(x + gw); + chardata[i].y1 = (stbtt_int16)(y + gh); + chardata[i].xadvance = scale * advance; + chardata[i].xoff = (float)x0; + chardata[i].yoff = (float)y0; + x = x + gw + 1; + if (y + gh + 1 > bottom_y) + bottom_y = y + gh + 1; + } + return bottom_y; } STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule) { - float d3d_bias = opengl_fillrule ? 0 : -0.5f; - float ipw = 1.0f / pw, iph = 1.0f / ph; - const stbtt_bakedchar *b = chardata + char_index; - int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f); - int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f); + float d3d_bias = opengl_fillrule ? 0 : -0.5f; + float ipw = 1.0f / pw, iph = 1.0f / ph; + const stbtt_bakedchar *b = chardata + char_index; + int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f); + int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f); - q->x0 = round_x + d3d_bias; - q->y0 = round_y + d3d_bias; - q->x1 = round_x + b->x1 - b->x0 + d3d_bias; - q->y1 = round_y + b->y1 - b->y0 + d3d_bias; + q->x0 = round_x + d3d_bias; + q->y0 = round_y + d3d_bias; + q->x1 = round_x + b->x1 - b->x0 + d3d_bias; + q->y1 = round_y + b->y1 - b->y0 + d3d_bias; - q->s0 = b->x0 * ipw; - q->t0 = b->y0 * iph; - q->s1 = b->x1 * ipw; - q->t1 = b->y1 * iph; + q->s0 = b->x0 * ipw; + q->t0 = b->y0 * iph; + q->s1 = b->x1 * ipw; + q->t1 = b->y1 * iph; - *xpos += b->xadvance; + *xpos += b->xadvance; } ////////////////////////////////////////////////////////////////////////////// @@ -3713,51 +4018,53 @@ typedef int stbrp_coord; typedef struct { - int width,height; - int x,y,bottom_y; + int width, height; + int x, y, bottom_y; } stbrp_context; typedef struct { - unsigned char x; + unsigned char x; } stbrp_node; struct stbrp_rect { - stbrp_coord x,y; - int id,w,h,was_packed; + stbrp_coord x, y; + int id, w, h, was_packed; }; static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *nodes, int num_nodes) { - con->width = pw; - con->height = ph; - con->x = 0; - con->y = 0; - con->bottom_y = 0; - STBTT__NOTUSED(nodes); - STBTT__NOTUSED(num_nodes); + con->width = pw; + con->height = ph; + con->x = 0; + con->y = 0; + con->bottom_y = 0; + STBTT__NOTUSED(nodes); + STBTT__NOTUSED(num_nodes); } static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects) { - int i; - for (i=0; i < num_rects; ++i) { - if (con->x + rects[i].w > con->width) { - con->x = 0; - con->y = con->bottom_y; - } - if (con->y + rects[i].h > con->height) - break; - rects[i].x = con->x; - rects[i].y = con->y; - rects[i].was_packed = 1; - con->x += rects[i].w; - if (con->y + rects[i].h > con->bottom_y) - con->bottom_y = con->y + rects[i].h; - } - for ( ; i < num_rects; ++i) - rects[i].was_packed = 0; + int i; + for (i = 0; i < num_rects; ++i) + { + if (con->x + rects[i].w > con->width) + { + con->x = 0; + con->y = con->bottom_y; + } + if (con->y + rects[i].h > con->height) + break; + rects[i].x = con->x; + rects[i].y = con->y; + rects[i].was_packed = 1; + con->x += rects[i].w; + if (con->y + rects[i].h > con->bottom_y) + con->bottom_y = con->y + rects[i].h; + } + for (; i < num_rects; ++i) + rects[i].was_packed = 0; } #endif @@ -3770,402 +4077,429 @@ static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rect STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int pw, int ph, int stride_in_bytes, int padding, void *alloc_context) { - stbrp_context *context = (stbrp_context *) STBTT_malloc(sizeof(*context) ,alloc_context); - int num_nodes = pw - padding; - stbrp_node *nodes = (stbrp_node *) STBTT_malloc(sizeof(*nodes ) * num_nodes,alloc_context); + stbrp_context *context = (stbrp_context *)STBTT_malloc(sizeof(*context), alloc_context); + int num_nodes = pw - padding; + stbrp_node *nodes = (stbrp_node *)STBTT_malloc(sizeof(*nodes) * num_nodes, alloc_context); - if (context == NULL || nodes == NULL) { - if (context != NULL) STBTT_free(context, alloc_context); - if (nodes != NULL) STBTT_free(nodes , alloc_context); - return 0; - } + if (context == NULL || nodes == NULL) + { + if (context != NULL) STBTT_free(context, alloc_context); + if (nodes != NULL) STBTT_free(nodes, alloc_context); + return 0; + } - spc->user_allocator_context = alloc_context; - spc->width = pw; - spc->height = ph; - spc->pixels = pixels; - spc->pack_info = context; - spc->nodes = nodes; - spc->padding = padding; - spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw; - spc->h_oversample = 1; - spc->v_oversample = 1; + spc->user_allocator_context = alloc_context; + spc->width = pw; + spc->height = ph; + spc->pixels = pixels; + spc->pack_info = context; + spc->nodes = nodes; + spc->padding = padding; + spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw; + spc->h_oversample = 1; + spc->v_oversample = 1; - stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes); + stbrp_init_target(context, pw - padding, ph - padding, nodes, num_nodes); - if (pixels) - STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels + if (pixels) + STBTT_memset(pixels, 0, pw * ph); // background of 0 around pixels - return 1; + return 1; } -STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc) +STBTT_DEF void stbtt_PackEnd(stbtt_pack_context *spc) { - STBTT_free(spc->nodes , spc->user_allocator_context); - STBTT_free(spc->pack_info, spc->user_allocator_context); + STBTT_free(spc->nodes, spc->user_allocator_context); + STBTT_free(spc->pack_info, spc->user_allocator_context); } STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample) { - STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE); - STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE); - if (h_oversample <= STBTT_MAX_OVERSAMPLE) - spc->h_oversample = h_oversample; - if (v_oversample <= STBTT_MAX_OVERSAMPLE) - spc->v_oversample = v_oversample; + STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE); + STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE); + if (h_oversample <= STBTT_MAX_OVERSAMPLE) + spc->h_oversample = h_oversample; + if (v_oversample <= STBTT_MAX_OVERSAMPLE) + spc->v_oversample = v_oversample; } -#define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1) +#define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE - 1) static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) { - unsigned char buffer[STBTT_MAX_OVERSAMPLE]; - int safe_w = w - kernel_width; - int j; - STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze - for (j=0; j < h; ++j) { - int i; - unsigned int total; - STBTT_memset(buffer, 0, kernel_width); + unsigned char buffer[STBTT_MAX_OVERSAMPLE]; + int safe_w = w - kernel_width; + int j; + STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze + for (j = 0; j < h; ++j) + { + int i; + unsigned int total; + STBTT_memset(buffer, 0, kernel_width); - total = 0; + total = 0; - // make kernel_width a constant in common cases so compiler can optimize out the divide - switch (kernel_width) { - case 2: - for (i=0; i <= safe_w; ++i) { - total += pixels[i] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char) (total / 2); - } - break; - case 3: - for (i=0; i <= safe_w; ++i) { - total += pixels[i] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char) (total / 3); - } - break; - case 4: - for (i=0; i <= safe_w; ++i) { - total += pixels[i] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char) (total / 4); - } - break; - case 5: - for (i=0; i <= safe_w; ++i) { - total += pixels[i] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char) (total / 5); - } - break; - default: - for (i=0; i <= safe_w; ++i) { - total += pixels[i] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char) (total / kernel_width); - } - break; - } + // make kernel_width a constant in common cases so compiler can optimize out the divide + switch (kernel_width) + { + case 2: + for (i = 0; i <= safe_w; ++i) + { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char)(total / 2); + } + break; + case 3: + for (i = 0; i <= safe_w; ++i) + { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char)(total / 3); + } + break; + case 4: + for (i = 0; i <= safe_w; ++i) + { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char)(total / 4); + } + break; + case 5: + for (i = 0; i <= safe_w; ++i) + { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char)(total / 5); + } + break; + default: + for (i = 0; i <= safe_w; ++i) + { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char)(total / kernel_width); + } + break; + } - for (; i < w; ++i) { - STBTT_assert(pixels[i] == 0); - total -= buffer[i & STBTT__OVER_MASK]; - pixels[i] = (unsigned char) (total / kernel_width); - } + for (; i < w; ++i) + { + STBTT_assert(pixels[i] == 0); + total -= buffer[i & STBTT__OVER_MASK]; + pixels[i] = (unsigned char)(total / kernel_width); + } - pixels += stride_in_bytes; - } + pixels += stride_in_bytes; + } } static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) { - unsigned char buffer[STBTT_MAX_OVERSAMPLE]; - int safe_h = h - kernel_width; - int j; - STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze - for (j=0; j < w; ++j) { - int i; - unsigned int total; - STBTT_memset(buffer, 0, kernel_width); + unsigned char buffer[STBTT_MAX_OVERSAMPLE]; + int safe_h = h - kernel_width; + int j; + STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze + for (j = 0; j < w; ++j) + { + int i; + unsigned int total; + STBTT_memset(buffer, 0, kernel_width); - total = 0; + total = 0; - // make kernel_width a constant in common cases so compiler can optimize out the divide - switch (kernel_width) { - case 2: - for (i=0; i <= safe_h; ++i) { - total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; - pixels[i*stride_in_bytes] = (unsigned char) (total / 2); - } - break; - case 3: - for (i=0; i <= safe_h; ++i) { - total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; - pixels[i*stride_in_bytes] = (unsigned char) (total / 3); - } - break; - case 4: - for (i=0; i <= safe_h; ++i) { - total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; - pixels[i*stride_in_bytes] = (unsigned char) (total / 4); - } - break; - case 5: - for (i=0; i <= safe_h; ++i) { - total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; - pixels[i*stride_in_bytes] = (unsigned char) (total / 5); - } - break; - default: - for (i=0; i <= safe_h; ++i) { - total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; - pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width); - } - break; - } + // make kernel_width a constant in common cases so compiler can optimize out the divide + switch (kernel_width) + { + case 2: + for (i = 0; i <= safe_h; ++i) + { + total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes]; + pixels[i * stride_in_bytes] = (unsigned char)(total / 2); + } + break; + case 3: + for (i = 0; i <= safe_h; ++i) + { + total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes]; + pixels[i * stride_in_bytes] = (unsigned char)(total / 3); + } + break; + case 4: + for (i = 0; i <= safe_h; ++i) + { + total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes]; + pixels[i * stride_in_bytes] = (unsigned char)(total / 4); + } + break; + case 5: + for (i = 0; i <= safe_h; ++i) + { + total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes]; + pixels[i * stride_in_bytes] = (unsigned char)(total / 5); + } + break; + default: + for (i = 0; i <= safe_h; ++i) + { + total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes]; + pixels[i * stride_in_bytes] = (unsigned char)(total / kernel_width); + } + break; + } - for (; i < h; ++i) { - STBTT_assert(pixels[i*stride_in_bytes] == 0); - total -= buffer[i & STBTT__OVER_MASK]; - pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width); - } + for (; i < h; ++i) + { + STBTT_assert(pixels[i * stride_in_bytes] == 0); + total -= buffer[i & STBTT__OVER_MASK]; + pixels[i * stride_in_bytes] = (unsigned char)(total / kernel_width); + } - pixels += 1; - } + pixels += 1; + } } static float stbtt__oversample_shift(int oversample) { - if (!oversample) - return 0.0f; + if (!oversample) + return 0.0f; - // The prefilter is a box filter of width "oversample", - // which shifts phase by (oversample - 1)/2 pixels in - // oversampled space. We want to shift in the opposite - // direction to counter this. - return (float)-(oversample - 1) / (2.0f * (float)oversample); + // The prefilter is a box filter of width "oversample", + // which shifts phase by (oversample - 1)/2 pixels in + // oversampled space. We want to shift in the opposite + // direction to counter this. + return (float)-(oversample - 1) / (2.0f * (float)oversample); } // rects array must be big enough to accommodate all characters in the given ranges STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) { - int i,j,k; + int i, j, k; - k=0; - for (i=0; i < num_ranges; ++i) { - float fh = ranges[i].font_size; - float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); - ranges[i].h_oversample = (unsigned char) spc->h_oversample; - ranges[i].v_oversample = (unsigned char) spc->v_oversample; - for (j=0; j < ranges[i].num_chars; ++j) { - int x0,y0,x1,y1; - int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; - int glyph = stbtt_FindGlyphIndex(info, codepoint); - stbtt_GetGlyphBitmapBoxSubpixel(info,glyph, - scale * spc->h_oversample, - scale * spc->v_oversample, - 0,0, - &x0,&y0,&x1,&y1); - rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1); - rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1); - ++k; - } - } + k = 0; + for (i = 0; i < num_ranges; ++i) + { + float fh = ranges[i].font_size; + float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); + ranges[i].h_oversample = (unsigned char)spc->h_oversample; + ranges[i].v_oversample = (unsigned char)spc->v_oversample; + for (j = 0; j < ranges[i].num_chars; ++j) + { + int x0, y0, x1, y1; + int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; + int glyph = stbtt_FindGlyphIndex(info, codepoint); + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, + scale * spc->h_oversample, + scale * spc->v_oversample, + 0, 0, + &x0, &y0, &x1, &y1); + rects[k].w = (stbrp_coord)(x1 - x0 + spc->padding + spc->h_oversample - 1); + rects[k].h = (stbrp_coord)(y1 - y0 + spc->padding + spc->v_oversample - 1); + ++k; + } + } - return k; + return k; } STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int prefilter_x, int prefilter_y, float *sub_x, float *sub_y, int glyph) { - stbtt_MakeGlyphBitmapSubpixel(info, - output, - out_w - (prefilter_x - 1), - out_h - (prefilter_y - 1), - out_stride, - scale_x, - scale_y, - shift_x, - shift_y, - glyph); + stbtt_MakeGlyphBitmapSubpixel(info, + output, + out_w - (prefilter_x - 1), + out_h - (prefilter_y - 1), + out_stride, + scale_x, + scale_y, + shift_x, + shift_y, + glyph); - if (prefilter_x > 1) - stbtt__h_prefilter(output, out_w, out_h, out_stride, prefilter_x); + if (prefilter_x > 1) + stbtt__h_prefilter(output, out_w, out_h, out_stride, prefilter_x); - if (prefilter_y > 1) - stbtt__v_prefilter(output, out_w, out_h, out_stride, prefilter_y); + if (prefilter_y > 1) + stbtt__v_prefilter(output, out_w, out_h, out_stride, prefilter_y); - *sub_x = stbtt__oversample_shift(prefilter_x); - *sub_y = stbtt__oversample_shift(prefilter_y); + *sub_x = stbtt__oversample_shift(prefilter_x); + *sub_y = stbtt__oversample_shift(prefilter_y); } // rects array must be big enough to accommodate all characters in the given ranges STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects) { - int i,j,k, return_value = 1; + int i, j, k, return_value = 1; - // save current values - int old_h_over = spc->h_oversample; - int old_v_over = spc->v_oversample; + // save current values + int old_h_over = spc->h_oversample; + int old_v_over = spc->v_oversample; - k = 0; - for (i=0; i < num_ranges; ++i) { - float fh = ranges[i].font_size; - float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); - float recip_h,recip_v,sub_x,sub_y; - spc->h_oversample = ranges[i].h_oversample; - spc->v_oversample = ranges[i].v_oversample; - recip_h = 1.0f / spc->h_oversample; - recip_v = 1.0f / spc->v_oversample; - sub_x = stbtt__oversample_shift(spc->h_oversample); - sub_y = stbtt__oversample_shift(spc->v_oversample); - for (j=0; j < ranges[i].num_chars; ++j) { - stbrp_rect *r = &rects[k]; - if (r->was_packed) { - stbtt_packedchar *bc = &ranges[i].chardata_for_range[j]; - int advance, lsb, x0,y0,x1,y1; - int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; - int glyph = stbtt_FindGlyphIndex(info, codepoint); - stbrp_coord pad = (stbrp_coord) spc->padding; + k = 0; + for (i = 0; i < num_ranges; ++i) + { + float fh = ranges[i].font_size; + float scale = fh > 0 ? stbtt_ScaleForPixelHeight(info, fh) : stbtt_ScaleForMappingEmToPixels(info, -fh); + float recip_h, recip_v, sub_x, sub_y; + spc->h_oversample = ranges[i].h_oversample; + spc->v_oversample = ranges[i].v_oversample; + recip_h = 1.0f / spc->h_oversample; + recip_v = 1.0f / spc->v_oversample; + sub_x = stbtt__oversample_shift(spc->h_oversample); + sub_y = stbtt__oversample_shift(spc->v_oversample); + for (j = 0; j < ranges[i].num_chars; ++j) + { + stbrp_rect *r = &rects[k]; + if (r->was_packed) + { + stbtt_packedchar *bc = &ranges[i].chardata_for_range[j]; + int advance, lsb, x0, y0, x1, y1; + int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j]; + int glyph = stbtt_FindGlyphIndex(info, codepoint); + stbrp_coord pad = (stbrp_coord)spc->padding; - // pad on left and top - r->x += pad; - r->y += pad; - r->w -= pad; - r->h -= pad; - stbtt_GetGlyphHMetrics(info, glyph, &advance, &lsb); - stbtt_GetGlyphBitmapBox(info, glyph, - scale * spc->h_oversample, - scale * spc->v_oversample, - &x0,&y0,&x1,&y1); - stbtt_MakeGlyphBitmapSubpixel(info, - spc->pixels + r->x + r->y*spc->stride_in_bytes, - r->w - spc->h_oversample+1, - r->h - spc->v_oversample+1, - spc->stride_in_bytes, - scale * spc->h_oversample, - scale * spc->v_oversample, - 0,0, - glyph); + // pad on left and top + r->x += pad; + r->y += pad; + r->w -= pad; + r->h -= pad; + stbtt_GetGlyphHMetrics(info, glyph, &advance, &lsb); + stbtt_GetGlyphBitmapBox(info, glyph, + scale * spc->h_oversample, + scale * spc->v_oversample, + &x0, &y0, &x1, &y1); + stbtt_MakeGlyphBitmapSubpixel(info, + spc->pixels + r->x + r->y * spc->stride_in_bytes, + r->w - spc->h_oversample + 1, + r->h - spc->v_oversample + 1, + spc->stride_in_bytes, + scale * spc->h_oversample, + scale * spc->v_oversample, + 0, 0, + glyph); - if (spc->h_oversample > 1) - stbtt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes, - r->w, r->h, spc->stride_in_bytes, - spc->h_oversample); + if (spc->h_oversample > 1) + stbtt__h_prefilter(spc->pixels + r->x + r->y * spc->stride_in_bytes, + r->w, r->h, spc->stride_in_bytes, + spc->h_oversample); - if (spc->v_oversample > 1) - stbtt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes, - r->w, r->h, spc->stride_in_bytes, - spc->v_oversample); + if (spc->v_oversample > 1) + stbtt__v_prefilter(spc->pixels + r->x + r->y * spc->stride_in_bytes, + r->w, r->h, spc->stride_in_bytes, + spc->v_oversample); - bc->x0 = (stbtt_int16) r->x; - bc->y0 = (stbtt_int16) r->y; - bc->x1 = (stbtt_int16) (r->x + r->w); - bc->y1 = (stbtt_int16) (r->y + r->h); - bc->xadvance = scale * advance; - bc->xoff = (float) x0 * recip_h + sub_x; - bc->yoff = (float) y0 * recip_v + sub_y; - bc->xoff2 = (x0 + r->w) * recip_h + sub_x; - bc->yoff2 = (y0 + r->h) * recip_v + sub_y; - } else { - return_value = 0; // if any fail, report failure - } + bc->x0 = (stbtt_int16)r->x; + bc->y0 = (stbtt_int16)r->y; + bc->x1 = (stbtt_int16)(r->x + r->w); + bc->y1 = (stbtt_int16)(r->y + r->h); + bc->xadvance = scale * advance; + bc->xoff = (float)x0 * recip_h + sub_x; + bc->yoff = (float)y0 * recip_v + sub_y; + bc->xoff2 = (x0 + r->w) * recip_h + sub_x; + bc->yoff2 = (y0 + r->h) * recip_v + sub_y; + } + else + { + return_value = 0; // if any fail, report failure + } - ++k; - } - } + ++k; + } + } - // restore original values - spc->h_oversample = old_h_over; - spc->v_oversample = old_v_over; + // restore original values + spc->h_oversample = old_h_over; + spc->v_oversample = old_v_over; - return return_value; + return return_value; } STBTT_DEF void stbtt_PackFontRangesPackRects(stbtt_pack_context *spc, stbrp_rect *rects, int num_rects) { - stbrp_pack_rects((stbrp_context *) spc->pack_info, rects, num_rects); + stbrp_pack_rects((stbrp_context *)spc->pack_info, rects, num_rects); } STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) { - stbtt_fontinfo info; - int i,j,n, return_value = 1; - //stbrp_context *context = (stbrp_context *) spc->pack_info; - stbrp_rect *rects; + stbtt_fontinfo info; + int i, j, n, return_value = 1; + //stbrp_context *context = (stbrp_context *) spc->pack_info; + stbrp_rect *rects; - // flag all characters as NOT packed - for (i=0; i < num_ranges; ++i) - for (j=0; j < ranges[i].num_chars; ++j) - ranges[i].chardata_for_range[j].x0 = - ranges[i].chardata_for_range[j].y0 = - ranges[i].chardata_for_range[j].x1 = - ranges[i].chardata_for_range[j].y1 = 0; + // flag all characters as NOT packed + for (i = 0; i < num_ranges; ++i) + for (j = 0; j < ranges[i].num_chars; ++j) + ranges[i].chardata_for_range[j].x0 = + ranges[i].chardata_for_range[j].y0 = + ranges[i].chardata_for_range[j].x1 = + ranges[i].chardata_for_range[j].y1 = 0; - n = 0; - for (i=0; i < num_ranges; ++i) - n += ranges[i].num_chars; - - rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context); - if (rects == NULL) - return 0; + n = 0; + for (i = 0; i < num_ranges; ++i) + n += ranges[i].num_chars; - info.userdata = spc->user_allocator_context; - stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index)); + rects = (stbrp_rect *)STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context); + if (rects == NULL) + return 0; - n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects); + info.userdata = spc->user_allocator_context; + stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, font_index)); - stbtt_PackFontRangesPackRects(spc, rects, n); - - return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects); + n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects); - STBTT_free(rects, spc->user_allocator_context); - return return_value; + stbtt_PackFontRangesPackRects(spc, rects, n); + + return_value = stbtt_PackFontRangesRenderIntoRects(spc, &info, ranges, num_ranges, rects); + + STBTT_free(rects, spc->user_allocator_context); + return return_value; } STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *fontdata, int font_index, float font_size, - int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range) + int first_unicode_codepoint_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range) { - stbtt_pack_range range; - range.first_unicode_codepoint_in_range = first_unicode_codepoint_in_range; - range.array_of_unicode_codepoints = NULL; - range.num_chars = num_chars_in_range; - range.chardata_for_range = chardata_for_range; - range.font_size = font_size; - return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1); + stbtt_pack_range range; + range.first_unicode_codepoint_in_range = first_unicode_codepoint_in_range; + range.array_of_unicode_codepoints = NULL; + range.num_chars = num_chars_in_range; + range.chardata_for_range = chardata_for_range; + range.font_size = font_size; + return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1); } STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer) { - float ipw = 1.0f / pw, iph = 1.0f / ph; - const stbtt_packedchar *b = chardata + char_index; + float ipw = 1.0f / pw, iph = 1.0f / ph; + const stbtt_packedchar *b = chardata + char_index; - if (align_to_integer) { - float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5f); - float y = (float) STBTT_ifloor((*ypos + b->yoff) + 0.5f); - q->x0 = x; - q->y0 = y; - q->x1 = x + b->xoff2 - b->xoff; - q->y1 = y + b->yoff2 - b->yoff; - } else { - q->x0 = *xpos + b->xoff; - q->y0 = *ypos + b->yoff; - q->x1 = *xpos + b->xoff2; - q->y1 = *ypos + b->yoff2; - } + if (align_to_integer) + { + float x = (float)STBTT_ifloor((*xpos + b->xoff) + 0.5f); + float y = (float)STBTT_ifloor((*ypos + b->yoff) + 0.5f); + q->x0 = x; + q->y0 = y; + q->x1 = x + b->xoff2 - b->xoff; + q->y1 = y + b->yoff2 - b->yoff; + } + else + { + q->x0 = *xpos + b->xoff; + q->y0 = *ypos + b->yoff; + q->x1 = *xpos + b->xoff2; + q->y1 = *ypos + b->yoff2; + } - q->s0 = b->x0 * ipw; - q->t0 = b->y0 * iph; - q->s1 = b->x1 * ipw; - q->t1 = b->y1 * iph; + q->s0 = b->x0 * ipw; + q->t0 = b->y0 * iph; + q->s1 = b->x1 * ipw; + q->t1 = b->y1 * iph; - *xpos += b->xadvance; + *xpos += b->xadvance; } ////////////////////////////////////////////////////////////////////////////// @@ -4173,381 +4507,427 @@ STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int // sdf computation // -#define STBTT_min(a,b) ((a) < (b) ? (a) : (b)) -#define STBTT_max(a,b) ((a) < (b) ? (b) : (a)) +#define STBTT_min(a, b) ((a) < (b) ? (a) : (b)) +#define STBTT_max(a, b) ((a) < (b) ? (b) : (a)) static int stbtt__ray_intersect_bezier(float orig[2], float ray[2], float q0[2], float q1[2], float q2[2], float hits[2][2]) { - float q0perp = q0[1]*ray[0] - q0[0]*ray[1]; - float q1perp = q1[1]*ray[0] - q1[0]*ray[1]; - float q2perp = q2[1]*ray[0] - q2[0]*ray[1]; - float roperp = orig[1]*ray[0] - orig[0]*ray[1]; + float q0perp = q0[1] * ray[0] - q0[0] * ray[1]; + float q1perp = q1[1] * ray[0] - q1[0] * ray[1]; + float q2perp = q2[1] * ray[0] - q2[0] * ray[1]; + float roperp = orig[1] * ray[0] - orig[0] * ray[1]; - float a = q0perp - 2*q1perp + q2perp; - float b = q1perp - q0perp; - float c = q0perp - roperp; + float a = q0perp - 2 * q1perp + q2perp; + float b = q1perp - q0perp; + float c = q0perp - roperp; - float s0 = 0., s1 = 0.; - int num_s = 0; + float s0 = 0., s1 = 0.; + int num_s = 0; - if (a != 0.0) { - float discr = b*b - a*c; - if (discr > 0.0) { - float rcpna = -1 / a; - float d = (float) STBTT_sqrt(discr); - s0 = (b+d) * rcpna; - s1 = (b-d) * rcpna; - if (s0 >= 0.0 && s0 <= 1.0) - num_s = 1; - if (d > 0.0 && s1 >= 0.0 && s1 <= 1.0) { - if (num_s == 0) s0 = s1; - ++num_s; - } - } - } else { - // 2*b*s + c = 0 - // s = -c / (2*b) - s0 = c / (-2 * b); - if (s0 >= 0.0 && s0 <= 1.0) - num_s = 1; - } + if (a != 0.0) + { + float discr = b * b - a * c; + if (discr > 0.0) + { + float rcpna = -1 / a; + float d = (float)STBTT_sqrt(discr); + s0 = (b + d) * rcpna; + s1 = (b - d) * rcpna; + if (s0 >= 0.0 && s0 <= 1.0) + num_s = 1; + if (d > 0.0 && s1 >= 0.0 && s1 <= 1.0) + { + if (num_s == 0) s0 = s1; + ++num_s; + } + } + } + else + { + // 2*b*s + c = 0 + // s = -c / (2*b) + s0 = c / (-2 * b); + if (s0 >= 0.0 && s0 <= 1.0) + num_s = 1; + } - if (num_s == 0) - return 0; - else { - float rcp_len2 = 1 / (ray[0]*ray[0] + ray[1]*ray[1]); - float rayn_x = ray[0] * rcp_len2, rayn_y = ray[1] * rcp_len2; + if (num_s == 0) + return 0; + else + { + float rcp_len2 = 1 / (ray[0] * ray[0] + ray[1] * ray[1]); + float rayn_x = ray[0] * rcp_len2, rayn_y = ray[1] * rcp_len2; - float q0d = q0[0]*rayn_x + q0[1]*rayn_y; - float q1d = q1[0]*rayn_x + q1[1]*rayn_y; - float q2d = q2[0]*rayn_x + q2[1]*rayn_y; - float rod = orig[0]*rayn_x + orig[1]*rayn_y; + float q0d = q0[0] * rayn_x + q0[1] * rayn_y; + float q1d = q1[0] * rayn_x + q1[1] * rayn_y; + float q2d = q2[0] * rayn_x + q2[1] * rayn_y; + float rod = orig[0] * rayn_x + orig[1] * rayn_y; - float q10d = q1d - q0d; - float q20d = q2d - q0d; - float q0rd = q0d - rod; + float q10d = q1d - q0d; + float q20d = q2d - q0d; + float q0rd = q0d - rod; - hits[0][0] = q0rd + s0*(2.0f - 2.0f*s0)*q10d + s0*s0*q20d; - hits[0][1] = a*s0+b; + hits[0][0] = q0rd + s0 * (2.0f - 2.0f * s0) * q10d + s0 * s0 * q20d; + hits[0][1] = a * s0 + b; - if (num_s > 1) { - hits[1][0] = q0rd + s1*(2.0f - 2.0f*s1)*q10d + s1*s1*q20d; - hits[1][1] = a*s1+b; - return 2; - } else { - return 1; - } - } + if (num_s > 1) + { + hits[1][0] = q0rd + s1 * (2.0f - 2.0f * s1) * q10d + s1 * s1 * q20d; + hits[1][1] = a * s1 + b; + return 2; + } + else + { + return 1; + } + } } static int equal(float *a, float *b) { - return (a[0] == b[0] && a[1] == b[1]); + return (a[0] == b[0] && a[1] == b[1]); } static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex *verts) { - int i; - float orig[2], ray[2] = { 1, 0 }; - float y_frac; - int winding = 0; + int i; + float orig[2], ray[2] = {1, 0}; + float y_frac; + int winding = 0; - orig[0] = x; - orig[1] = y; + orig[0] = x; + orig[1] = y; - // make sure y never passes through a vertex of the shape - y_frac = (float) STBTT_fmod(y, 1.0f); - if (y_frac < 0.01f) - y += 0.01f; - else if (y_frac > 0.99f) - y -= 0.01f; - orig[1] = y; + // make sure y never passes through a vertex of the shape + y_frac = (float)STBTT_fmod(y, 1.0f); + if (y_frac < 0.01f) + y += 0.01f; + else if (y_frac > 0.99f) + y -= 0.01f; + orig[1] = y; - // test a ray from (-infinity,y) to (x,y) - for (i=0; i < nverts; ++i) { - if (verts[i].type == STBTT_vline) { - int x0 = (int) verts[i-1].x, y0 = (int) verts[i-1].y; - int x1 = (int) verts[i ].x, y1 = (int) verts[i ].y; - if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) { - float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0; - if (x_inter < x) - winding += (y0 < y1) ? 1 : -1; - } - } - if (verts[i].type == STBTT_vcurve) { - int x0 = (int) verts[i-1].x , y0 = (int) verts[i-1].y ; - int x1 = (int) verts[i ].cx, y1 = (int) verts[i ].cy; - int x2 = (int) verts[i ].x , y2 = (int) verts[i ].y ; - int ax = STBTT_min(x0,STBTT_min(x1,x2)), ay = STBTT_min(y0,STBTT_min(y1,y2)); - int by = STBTT_max(y0,STBTT_max(y1,y2)); - if (y > ay && y < by && x > ax) { - float q0[2],q1[2],q2[2]; - float hits[2][2]; - q0[0] = (float)x0; - q0[1] = (float)y0; - q1[0] = (float)x1; - q1[1] = (float)y1; - q2[0] = (float)x2; - q2[1] = (float)y2; - if (equal(q0,q1) || equal(q1,q2)) { - x0 = (int)verts[i-1].x; - y0 = (int)verts[i-1].y; - x1 = (int)verts[i ].x; - y1 = (int)verts[i ].y; - if (y > STBTT_min(y0,y1) && y < STBTT_max(y0,y1) && x > STBTT_min(x0,x1)) { - float x_inter = (y - y0) / (y1 - y0) * (x1-x0) + x0; - if (x_inter < x) - winding += (y0 < y1) ? 1 : -1; - } - } else { - int num_hits = stbtt__ray_intersect_bezier(orig, ray, q0, q1, q2, hits); - if (num_hits >= 1) - if (hits[0][0] < 0) - winding += (hits[0][1] < 0 ? -1 : 1); - if (num_hits >= 2) - if (hits[1][0] < 0) - winding += (hits[1][1] < 0 ? -1 : 1); - } - } - } - } - return winding; + // test a ray from (-infinity,y) to (x,y) + for (i = 0; i < nverts; ++i) + { + if (verts[i].type == STBTT_vline) + { + int x0 = (int)verts[i - 1].x, y0 = (int)verts[i - 1].y; + int x1 = (int)verts[i].x, y1 = (int)verts[i].y; + if (y > STBTT_min(y0, y1) && y < STBTT_max(y0, y1) && x > STBTT_min(x0, x1)) + { + float x_inter = (y - y0) / (y1 - y0) * (x1 - x0) + x0; + if (x_inter < x) + winding += (y0 < y1) ? 1 : -1; + } + } + if (verts[i].type == STBTT_vcurve) + { + int x0 = (int)verts[i - 1].x, y0 = (int)verts[i - 1].y; + int x1 = (int)verts[i].cx, y1 = (int)verts[i].cy; + int x2 = (int)verts[i].x, y2 = (int)verts[i].y; + int ax = STBTT_min(x0, STBTT_min(x1, x2)), ay = STBTT_min(y0, STBTT_min(y1, y2)); + int by = STBTT_max(y0, STBTT_max(y1, y2)); + if (y > ay && y < by && x > ax) + { + float q0[2], q1[2], q2[2]; + float hits[2][2]; + q0[0] = (float)x0; + q0[1] = (float)y0; + q1[0] = (float)x1; + q1[1] = (float)y1; + q2[0] = (float)x2; + q2[1] = (float)y2; + if (equal(q0, q1) || equal(q1, q2)) + { + x0 = (int)verts[i - 1].x; + y0 = (int)verts[i - 1].y; + x1 = (int)verts[i].x; + y1 = (int)verts[i].y; + if (y > STBTT_min(y0, y1) && y < STBTT_max(y0, y1) && x > STBTT_min(x0, x1)) + { + float x_inter = (y - y0) / (y1 - y0) * (x1 - x0) + x0; + if (x_inter < x) + winding += (y0 < y1) ? 1 : -1; + } + } + else + { + int num_hits = stbtt__ray_intersect_bezier(orig, ray, q0, q1, q2, hits); + if (num_hits >= 1) + if (hits[0][0] < 0) + winding += (hits[0][1] < 0 ? -1 : 1); + if (num_hits >= 2) + if (hits[1][0] < 0) + winding += (hits[1][1] < 0 ? -1 : 1); + } + } + } + } + return winding; } -static float stbtt__cuberoot( float x ) +static float stbtt__cuberoot(float x) { - if (x<0) - return -(float) STBTT_pow(-x,1.0f/3.0f); - else - return (float) STBTT_pow( x,1.0f/3.0f); + if (x < 0) + return -(float)STBTT_pow(-x, 1.0f / 3.0f); + else + return (float)STBTT_pow(x, 1.0f / 3.0f); } // x^3 + c*x^2 + b*x + a = 0 -static int stbtt__solve_cubic(float a, float b, float c, float* r) +static int stbtt__solve_cubic(float a, float b, float c, float *r) { float s = -a / 3; - float p = b - a*a / 3; - float q = a * (2*a*a - 9*b) / 27 + c; - float p3 = p*p*p; - float d = q*q + 4*p3 / 27; - if (d >= 0) { - float z = (float) STBTT_sqrt(d); + float p = b - a * a / 3; + float q = a * (2 * a * a - 9 * b) / 27 + c; + float p3 = p * p * p; + float d = q * q + 4 * p3 / 27; + if (d >= 0) + { + float z = (float)STBTT_sqrt(d); float u = (-q + z) / 2; float v = (-q - z) / 2; u = stbtt__cuberoot(u); v = stbtt__cuberoot(v); r[0] = s + u + v; return 1; - } else { - float u = (float) STBTT_sqrt(-p/3); - float v = (float) STBTT_acos(-STBTT_sqrt(-27/p3) * q / 2) / 3; // p3 must be negative, since d is negative - float m = (float) STBTT_cos(v); - float n = (float) STBTT_cos(v-3.141592/2)*1.732050808f; - r[0] = s + u * 2 * m; - r[1] = s - u * (m + n); - r[2] = s - u * (m - n); + } + else + { + float u = (float)STBTT_sqrt(-p / 3); + float v = (float)STBTT_acos(-STBTT_sqrt(-27 / p3) * q / 2) / 3; // p3 must be negative, since d is negative + float m = (float)STBTT_cos(v); + float n = (float)STBTT_cos(v - 3.141592 / 2) * 1.732050808f; + r[0] = s + u * 2 * m; + r[1] = s - u * (m + n); + r[2] = s - u * (m - n); - //STBTT_assert( STBTT_fabs(((r[0]+a)*r[0]+b)*r[0]+c) < 0.05f); // these asserts may not be safe at all scales, though they're in bezier t parameter units so maybe? - //STBTT_assert( STBTT_fabs(((r[1]+a)*r[1]+b)*r[1]+c) < 0.05f); - //STBTT_assert( STBTT_fabs(((r[2]+a)*r[2]+b)*r[2]+c) < 0.05f); - return 3; - } + //STBTT_assert( STBTT_fabs(((r[0]+a)*r[0]+b)*r[0]+c) < 0.05f); // these asserts may not be safe at all scales, though they're in bezier t parameter units so maybe? + //STBTT_assert( STBTT_fabs(((r[1]+a)*r[1]+b)*r[1]+c) < 0.05f); + //STBTT_assert( STBTT_fabs(((r[2]+a)*r[2]+b)*r[2]+c) < 0.05f); + return 3; + } } -STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float scale, int glyph, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff) +STBTT_DEF unsigned char *stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float scale, int glyph, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff) { - float scale_x = scale, scale_y = scale; - int ix0,iy0,ix1,iy1; - int w,h; - unsigned char *data; + float scale_x = scale, scale_y = scale; + int ix0, iy0, ix1, iy1; + int w, h; + unsigned char *data; - // if one scale is 0, use same scale for both - if (scale_x == 0) scale_x = scale_y; - if (scale_y == 0) { - if (scale_x == 0) return NULL; // if both scales are 0, return NULL - scale_y = scale_x; - } + // if one scale is 0, use same scale for both + if (scale_x == 0) scale_x = scale_y; + if (scale_y == 0) + { + if (scale_x == 0) return NULL; // if both scales are 0, return NULL + scale_y = scale_x; + } - stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f,0.0f, &ix0,&iy0,&ix1,&iy1); + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f, 0.0f, &ix0, &iy0, &ix1, &iy1); - // if empty, return NULL - if (ix0 == ix1 || iy0 == iy1) - return NULL; + // if empty, return NULL + if (ix0 == ix1 || iy0 == iy1) + return NULL; - ix0 -= padding; - iy0 -= padding; - ix1 += padding; - iy1 += padding; + ix0 -= padding; + iy0 -= padding; + ix1 += padding; + iy1 += padding; - w = (ix1 - ix0); - h = (iy1 - iy0); + w = (ix1 - ix0); + h = (iy1 - iy0); - if (width ) *width = w; - if (height) *height = h; - if (xoff ) *xoff = ix0; - if (yoff ) *yoff = iy0; + if (width) *width = w; + if (height) *height = h; + if (xoff) *xoff = ix0; + if (yoff) *yoff = iy0; - // invert for y-downwards bitmaps - scale_y = -scale_y; - - { - int x,y,i,j; - float *precompute; - stbtt_vertex *verts; - int num_verts = stbtt_GetGlyphShape(info, glyph, &verts); - data = (unsigned char *) STBTT_malloc(w * h, info->userdata); - precompute = (float *) STBTT_malloc(num_verts * sizeof(float), info->userdata); + // invert for y-downwards bitmaps + scale_y = -scale_y; - for (i=0,j=num_verts-1; i < num_verts; j=i++) { - if (verts[i].type == STBTT_vline) { - float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y; - float x1 = verts[j].x*scale_x, y1 = verts[j].y*scale_y; - float dist = (float) STBTT_sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0)); - precompute[i] = (dist == 0) ? 0.0f : 1.0f / dist; - } else if (verts[i].type == STBTT_vcurve) { - float x2 = verts[j].x *scale_x, y2 = verts[j].y *scale_y; - float x1 = verts[i].cx*scale_x, y1 = verts[i].cy*scale_y; - float x0 = verts[i].x *scale_x, y0 = verts[i].y *scale_y; - float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2; - float len2 = bx*bx + by*by; - if (len2 != 0.0f) - precompute[i] = 1.0f / (bx*bx + by*by); - else - precompute[i] = 0.0f; - } else - precompute[i] = 0.0f; - } + { + int x, y, i, j; + float *precompute; + stbtt_vertex *verts; + int num_verts = stbtt_GetGlyphShape(info, glyph, &verts); + data = (unsigned char *)STBTT_malloc(w * h, info->userdata); + precompute = (float *)STBTT_malloc(num_verts * sizeof(float), info->userdata); - for (y=iy0; y < iy1; ++y) { - for (x=ix0; x < ix1; ++x) { - float val; - float min_dist = 999999.0f; - float sx = (float) x + 0.5f; - float sy = (float) y + 0.5f; - float x_gspace = (sx / scale_x); - float y_gspace = (sy / scale_y); + for (i = 0, j = num_verts - 1; i < num_verts; j = i++) + { + if (verts[i].type == STBTT_vline) + { + float x0 = verts[i].x * scale_x, y0 = verts[i].y * scale_y; + float x1 = verts[j].x * scale_x, y1 = verts[j].y * scale_y; + float dist = (float)STBTT_sqrt((x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0)); + precompute[i] = (dist == 0) ? 0.0f : 1.0f / dist; + } + else if (verts[i].type == STBTT_vcurve) + { + float x2 = verts[j].x * scale_x, y2 = verts[j].y * scale_y; + float x1 = verts[i].cx * scale_x, y1 = verts[i].cy * scale_y; + float x0 = verts[i].x * scale_x, y0 = verts[i].y * scale_y; + float bx = x0 - 2 * x1 + x2, by = y0 - 2 * y1 + y2; + float len2 = bx * bx + by * by; + if (len2 != 0.0f) + precompute[i] = 1.0f / (bx * bx + by * by); + else + precompute[i] = 0.0f; + } + else + precompute[i] = 0.0f; + } - int winding = stbtt__compute_crossings_x(x_gspace, y_gspace, num_verts, verts); // @OPTIMIZE: this could just be a rasterization, but needs to be line vs. non-tesselated curves so a new path + for (y = iy0; y < iy1; ++y) + { + for (x = ix0; x < ix1; ++x) + { + float val; + float min_dist = 999999.0f; + float sx = (float)x + 0.5f; + float sy = (float)y + 0.5f; + float x_gspace = (sx / scale_x); + float y_gspace = (sy / scale_y); - for (i=0; i < num_verts; ++i) { - float x0 = verts[i].x*scale_x, y0 = verts[i].y*scale_y; + int winding = stbtt__compute_crossings_x(x_gspace, y_gspace, num_verts, verts); // @OPTIMIZE: this could just be a rasterization, but needs to be line vs. non-tesselated curves so a new path - // check against every point here rather than inside line/curve primitives -- @TODO: wrong if multiple 'moves' in a row produce a garbage point, and given culling, probably more efficient to do within line/curve - float dist2 = (x0-sx)*(x0-sx) + (y0-sy)*(y0-sy); - if (dist2 < min_dist*min_dist) - min_dist = (float) STBTT_sqrt(dist2); + for (i = 0; i < num_verts; ++i) + { + float x0 = verts[i].x * scale_x, y0 = verts[i].y * scale_y; - if (verts[i].type == STBTT_vline) { - float x1 = verts[i-1].x*scale_x, y1 = verts[i-1].y*scale_y; + // check against every point here rather than inside line/curve primitives -- @TODO: wrong if multiple 'moves' in a row produce a garbage point, and given culling, probably more efficient to do within line/curve + float dist2 = (x0 - sx) * (x0 - sx) + (y0 - sy) * (y0 - sy); + if (dist2 < min_dist * min_dist) + min_dist = (float)STBTT_sqrt(dist2); - // coarse culling against bbox - //if (sx > STBTT_min(x0,x1)-min_dist && sx < STBTT_max(x0,x1)+min_dist && - // sy > STBTT_min(y0,y1)-min_dist && sy < STBTT_max(y0,y1)+min_dist) - float dist = (float) STBTT_fabs((x1-x0)*(y0-sy) - (y1-y0)*(x0-sx)) * precompute[i]; - STBTT_assert(i != 0); - if (dist < min_dist) { - // check position along line - // x' = x0 + t*(x1-x0), y' = y0 + t*(y1-y0) - // minimize (x'-sx)*(x'-sx)+(y'-sy)*(y'-sy) - float dx = x1-x0, dy = y1-y0; - float px = x0-sx, py = y0-sy; - // minimize (px+t*dx)^2 + (py+t*dy)^2 = px*px + 2*px*dx*t + t^2*dx*dx + py*py + 2*py*dy*t + t^2*dy*dy - // derivative: 2*px*dx + 2*py*dy + (2*dx*dx+2*dy*dy)*t, set to 0 and solve - float t = -(px*dx + py*dy) / (dx*dx + dy*dy); - if (t >= 0.0f && t <= 1.0f) - min_dist = dist; - } - } else if (verts[i].type == STBTT_vcurve) { - float x2 = verts[i-1].x *scale_x, y2 = verts[i-1].y *scale_y; - float x1 = verts[i ].cx*scale_x, y1 = verts[i ].cy*scale_y; - float box_x0 = STBTT_min(STBTT_min(x0,x1),x2); - float box_y0 = STBTT_min(STBTT_min(y0,y1),y2); - float box_x1 = STBTT_max(STBTT_max(x0,x1),x2); - float box_y1 = STBTT_max(STBTT_max(y0,y1),y2); - // coarse culling against bbox to avoid computing cubic unnecessarily - if (sx > box_x0-min_dist && sx < box_x1+min_dist && sy > box_y0-min_dist && sy < box_y1+min_dist) { - int num=0; - float ax = x1-x0, ay = y1-y0; - float bx = x0 - 2*x1 + x2, by = y0 - 2*y1 + y2; - float mx = x0 - sx, my = y0 - sy; - float res[3],px,py,t,it; - float a_inv = precompute[i]; - if (a_inv == 0.0) { // if a_inv is 0, it's 2nd degree so use quadratic formula - float a = 3*(ax*bx + ay*by); - float b = 2*(ax*ax + ay*ay) + (mx*bx+my*by); - float c = mx*ax+my*ay; - if (a == 0.0) { // if a is 0, it's linear - if (b != 0.0) { - res[num++] = -c/b; - } - } else { - float discriminant = b*b - 4*a*c; - if (discriminant < 0) - num = 0; - else { - float root = (float) STBTT_sqrt(discriminant); - res[0] = (-b - root)/(2*a); - res[1] = (-b + root)/(2*a); - num = 2; // don't bother distinguishing 1-solution case, as code below will still work - } - } - } else { - float b = 3*(ax*bx + ay*by) * a_inv; // could precompute this as it doesn't depend on sample point - float c = (2*(ax*ax + ay*ay) + (mx*bx+my*by)) * a_inv; - float d = (mx*ax+my*ay) * a_inv; - num = stbtt__solve_cubic(b, c, d, res); - } - if (num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) { - t = res[0], it = 1.0f - t; - px = it*it*x0 + 2*t*it*x1 + t*t*x2; - py = it*it*y0 + 2*t*it*y1 + t*t*y2; - dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy); - if (dist2 < min_dist * min_dist) - min_dist = (float) STBTT_sqrt(dist2); - } - if (num >= 2 && res[1] >= 0.0f && res[1] <= 1.0f) { - t = res[1], it = 1.0f - t; - px = it*it*x0 + 2*t*it*x1 + t*t*x2; - py = it*it*y0 + 2*t*it*y1 + t*t*y2; - dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy); - if (dist2 < min_dist * min_dist) - min_dist = (float) STBTT_sqrt(dist2); - } - if (num >= 3 && res[2] >= 0.0f && res[2] <= 1.0f) { - t = res[2], it = 1.0f - t; - px = it*it*x0 + 2*t*it*x1 + t*t*x2; - py = it*it*y0 + 2*t*it*y1 + t*t*y2; - dist2 = (px-sx)*(px-sx) + (py-sy)*(py-sy); - if (dist2 < min_dist * min_dist) - min_dist = (float) STBTT_sqrt(dist2); - } - } - } - } - if (winding == 0) - min_dist = -min_dist; // if outside the shape, value is negative - val = onedge_value + pixel_dist_scale * min_dist; - if (val < 0) - val = 0; - else if (val > 255) - val = 255; - data[(y-iy0)*w+(x-ix0)] = (unsigned char) val; - } - } - STBTT_free(precompute, info->userdata); - STBTT_free(verts, info->userdata); - } - return data; -} + if (verts[i].type == STBTT_vline) + { + float x1 = verts[i - 1].x * scale_x, y1 = verts[i - 1].y * scale_y; -STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff) + // coarse culling against bbox + //if (sx > STBTT_min(x0,x1)-min_dist && sx < STBTT_max(x0,x1)+min_dist && + // sy > STBTT_min(y0,y1)-min_dist && sy < STBTT_max(y0,y1)+min_dist) + float dist = (float)STBTT_fabs((x1 - x0) * (y0 - sy) - (y1 - y0) * (x0 - sx)) * precompute[i]; + STBTT_assert(i != 0); + if (dist < min_dist) + { + // check position along line + // x' = x0 + t*(x1-x0), y' = y0 + t*(y1-y0) + // minimize (x'-sx)*(x'-sx)+(y'-sy)*(y'-sy) + float dx = x1 - x0, dy = y1 - y0; + float px = x0 - sx, py = y0 - sy; + // minimize (px+t*dx)^2 + (py+t*dy)^2 = px*px + 2*px*dx*t + t^2*dx*dx + py*py + 2*py*dy*t + t^2*dy*dy + // derivative: 2*px*dx + 2*py*dy + (2*dx*dx+2*dy*dy)*t, set to 0 and solve + float t = -(px * dx + py * dy) / (dx * dx + dy * dy); + if (t >= 0.0f && t <= 1.0f) + min_dist = dist; + } + } + else if (verts[i].type == STBTT_vcurve) + { + float x2 = verts[i - 1].x * scale_x, y2 = verts[i - 1].y * scale_y; + float x1 = verts[i].cx * scale_x, y1 = verts[i].cy * scale_y; + float box_x0 = STBTT_min(STBTT_min(x0, x1), x2); + float box_y0 = STBTT_min(STBTT_min(y0, y1), y2); + float box_x1 = STBTT_max(STBTT_max(x0, x1), x2); + float box_y1 = STBTT_max(STBTT_max(y0, y1), y2); + // coarse culling against bbox to avoid computing cubic unnecessarily + if (sx > box_x0 - min_dist && sx < box_x1 + min_dist && sy > box_y0 - min_dist && sy < box_y1 + min_dist) + { + int num = 0; + float ax = x1 - x0, ay = y1 - y0; + float bx = x0 - 2 * x1 + x2, by = y0 - 2 * y1 + y2; + float mx = x0 - sx, my = y0 - sy; + float res[3], px, py, t, it; + float a_inv = precompute[i]; + if (a_inv == 0.0) + { // if a_inv is 0, it's 2nd degree so use quadratic formula + float a = 3 * (ax * bx + ay * by); + float b = 2 * (ax * ax + ay * ay) + (mx * bx + my * by); + float c = mx * ax + my * ay; + if (a == 0.0) + { // if a is 0, it's linear + if (b != 0.0) + { + res[num++] = -c / b; + } + } + else + { + float discriminant = b * b - 4 * a * c; + if (discriminant < 0) + num = 0; + else + { + float root = (float)STBTT_sqrt(discriminant); + res[0] = (-b - root) / (2 * a); + res[1] = (-b + root) / (2 * a); + num = 2; // don't bother distinguishing 1-solution case, as code below will still work + } + } + } + else + { + float b = 3 * (ax * bx + ay * by) * a_inv; // could precompute this as it doesn't depend on sample point + float c = (2 * (ax * ax + ay * ay) + (mx * bx + my * by)) * a_inv; + float d = (mx * ax + my * ay) * a_inv; + num = stbtt__solve_cubic(b, c, d, res); + } + if (num >= 1 && res[0] >= 0.0f && res[0] <= 1.0f) + { + t = res[0], it = 1.0f - t; + px = it * it * x0 + 2 * t * it * x1 + t * t * x2; + py = it * it * y0 + 2 * t * it * y1 + t * t * y2; + dist2 = (px - sx) * (px - sx) + (py - sy) * (py - sy); + if (dist2 < min_dist * min_dist) + min_dist = (float)STBTT_sqrt(dist2); + } + if (num >= 2 && res[1] >= 0.0f && res[1] <= 1.0f) + { + t = res[1], it = 1.0f - t; + px = it * it * x0 + 2 * t * it * x1 + t * t * x2; + py = it * it * y0 + 2 * t * it * y1 + t * t * y2; + dist2 = (px - sx) * (px - sx) + (py - sy) * (py - sy); + if (dist2 < min_dist * min_dist) + min_dist = (float)STBTT_sqrt(dist2); + } + if (num >= 3 && res[2] >= 0.0f && res[2] <= 1.0f) + { + t = res[2], it = 1.0f - t; + px = it * it * x0 + 2 * t * it * x1 + t * t * x2; + py = it * it * y0 + 2 * t * it * y1 + t * t * y2; + dist2 = (px - sx) * (px - sx) + (py - sy) * (py - sy); + if (dist2 < min_dist * min_dist) + min_dist = (float)STBTT_sqrt(dist2); + } + } + } + } + if (winding == 0) + min_dist = -min_dist; // if outside the shape, value is negative + val = onedge_value + pixel_dist_scale * min_dist; + if (val < 0) + val = 0; + else if (val > 255) + val = 255; + data[(y - iy0) * w + (x - ix0)] = (unsigned char)val; + } + } + STBTT_free(precompute, info->userdata); + STBTT_free(verts, info->userdata); + } + return data; +} + +STBTT_DEF unsigned char *stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff) { - return stbtt_GetGlyphSDF(info, scale, stbtt_FindGlyphIndex(info, codepoint), padding, onedge_value, pixel_dist_scale, width, height, xoff, yoff); + return stbtt_GetGlyphSDF(info, scale, stbtt_FindGlyphIndex(info, codepoint), padding, onedge_value, pixel_dist_scale, width, height, xoff, yoff); } STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata) { - STBTT_free(bitmap, userdata); + STBTT_free(bitmap, userdata); } ////////////////////////////////////////////////////////////////////////////// @@ -4556,158 +4936,184 @@ STBTT_DEF void stbtt_FreeSDF(unsigned char *bitmap, void *userdata) // // check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string -static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2) +static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(stbtt_uint8 *s1, stbtt_int32 len1, stbtt_uint8 *s2, stbtt_int32 len2) { - stbtt_int32 i=0; + stbtt_int32 i = 0; - // convert utf16 to utf8 and compare the results while converting - while (len2) { - stbtt_uint16 ch = s2[0]*256 + s2[1]; - if (ch < 0x80) { - if (i >= len1) return -1; - if (s1[i++] != ch) return -1; - } else if (ch < 0x800) { - if (i+1 >= len1) return -1; - if (s1[i++] != 0xc0 + (ch >> 6)) return -1; - if (s1[i++] != 0x80 + (ch & 0x3f)) return -1; - } else if (ch >= 0xd800 && ch < 0xdc00) { - stbtt_uint32 c; - stbtt_uint16 ch2 = s2[2]*256 + s2[3]; - if (i+3 >= len1) return -1; - c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000; - if (s1[i++] != 0xf0 + (c >> 18)) return -1; - if (s1[i++] != 0x80 + ((c >> 12) & 0x3f)) return -1; - if (s1[i++] != 0x80 + ((c >> 6) & 0x3f)) return -1; - if (s1[i++] != 0x80 + ((c ) & 0x3f)) return -1; - s2 += 2; // plus another 2 below - len2 -= 2; - } else if (ch >= 0xdc00 && ch < 0xe000) { - return -1; - } else { - if (i+2 >= len1) return -1; - if (s1[i++] != 0xe0 + (ch >> 12)) return -1; - if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f)) return -1; - if (s1[i++] != 0x80 + ((ch ) & 0x3f)) return -1; - } - s2 += 2; - len2 -= 2; - } - return i; + // convert utf16 to utf8 and compare the results while converting + while (len2) + { + stbtt_uint16 ch = s2[0] * 256 + s2[1]; + if (ch < 0x80) + { + if (i >= len1) return -1; + if (s1[i++] != ch) return -1; + } + else if (ch < 0x800) + { + if (i + 1 >= len1) return -1; + if (s1[i++] != 0xc0 + (ch >> 6)) return -1; + if (s1[i++] != 0x80 + (ch & 0x3f)) return -1; + } + else if (ch >= 0xd800 && ch < 0xdc00) + { + stbtt_uint32 c; + stbtt_uint16 ch2 = s2[2] * 256 + s2[3]; + if (i + 3 >= len1) return -1; + c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000; + if (s1[i++] != 0xf0 + (c >> 18)) return -1; + if (s1[i++] != 0x80 + ((c >> 12) & 0x3f)) return -1; + if (s1[i++] != 0x80 + ((c >> 6) & 0x3f)) return -1; + if (s1[i++] != 0x80 + ((c)&0x3f)) return -1; + s2 += 2; // plus another 2 below + len2 -= 2; + } + else if (ch >= 0xdc00 && ch < 0xe000) + { + return -1; + } + else + { + if (i + 2 >= len1) return -1; + if (s1[i++] != 0xe0 + (ch >> 12)) return -1; + if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f)) return -1; + if (s1[i++] != 0x80 + ((ch)&0x3f)) return -1; + } + s2 += 2; + len2 -= 2; + } + return i; } -static int stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int len1, char *s2, int len2) +static int stbtt_CompareUTF8toUTF16_bigendian_internal(char *s1, int len1, char *s2, int len2) { - return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8*) s1, len1, (stbtt_uint8*) s2, len2); + return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((stbtt_uint8 *)s1, len1, (stbtt_uint8 *)s2, len2); } // returns results in whatever encoding you request... but note that 2-byte encodings // will be BIG-ENDIAN... use stbtt_CompareUTF8toUTF16_bigendian() to compare STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID) { - stbtt_int32 i,count,stringOffset; - stbtt_uint8 *fc = font->data; - stbtt_uint32 offset = font->fontstart; - stbtt_uint32 nm = stbtt__find_table(fc, offset, "name"); - if (!nm) return NULL; + stbtt_int32 i, count, stringOffset; + stbtt_uint8 *fc = font->data; + stbtt_uint32 offset = font->fontstart; + stbtt_uint32 nm = stbtt__find_table(fc, offset, "name"); + if (!nm) return NULL; - count = ttUSHORT(fc+nm+2); - stringOffset = nm + ttUSHORT(fc+nm+4); - for (i=0; i < count; ++i) { - stbtt_uint32 loc = nm + 6 + 12 * i; - if (platformID == ttUSHORT(fc+loc+0) && encodingID == ttUSHORT(fc+loc+2) - && languageID == ttUSHORT(fc+loc+4) && nameID == ttUSHORT(fc+loc+6)) { - *length = ttUSHORT(fc+loc+8); - return (const char *) (fc+stringOffset+ttUSHORT(fc+loc+10)); - } - } - return NULL; + count = ttUSHORT(fc + nm + 2); + stringOffset = nm + ttUSHORT(fc + nm + 4); + for (i = 0; i < count; ++i) + { + stbtt_uint32 loc = nm + 6 + 12 * i; + if (platformID == ttUSHORT(fc + loc + 0) && encodingID == ttUSHORT(fc + loc + 2) && languageID == ttUSHORT(fc + loc + 4) && nameID == ttUSHORT(fc + loc + 6)) + { + *length = ttUSHORT(fc + loc + 8); + return (const char *)(fc + stringOffset + ttUSHORT(fc + loc + 10)); + } + } + return NULL; } static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 nlen, stbtt_int32 target_id, stbtt_int32 next_id) { - stbtt_int32 i; - stbtt_int32 count = ttUSHORT(fc+nm+2); - stbtt_int32 stringOffset = nm + ttUSHORT(fc+nm+4); + stbtt_int32 i; + stbtt_int32 count = ttUSHORT(fc + nm + 2); + stbtt_int32 stringOffset = nm + ttUSHORT(fc + nm + 4); - for (i=0; i < count; ++i) { - stbtt_uint32 loc = nm + 6 + 12 * i; - stbtt_int32 id = ttUSHORT(fc+loc+6); - if (id == target_id) { - // find the encoding - stbtt_int32 platform = ttUSHORT(fc+loc+0), encoding = ttUSHORT(fc+loc+2), language = ttUSHORT(fc+loc+4); + for (i = 0; i < count; ++i) + { + stbtt_uint32 loc = nm + 6 + 12 * i; + stbtt_int32 id = ttUSHORT(fc + loc + 6); + if (id == target_id) + { + // find the encoding + stbtt_int32 platform = ttUSHORT(fc + loc + 0), encoding = ttUSHORT(fc + loc + 2), language = ttUSHORT(fc + loc + 4); - // is this a Unicode encoding? - if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) { - stbtt_int32 slen = ttUSHORT(fc+loc+8); - stbtt_int32 off = ttUSHORT(fc+loc+10); + // is this a Unicode encoding? + if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) + { + stbtt_int32 slen = ttUSHORT(fc + loc + 8); + stbtt_int32 off = ttUSHORT(fc + loc + 10); - // check if there's a prefix match - stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen); - if (matchlen >= 0) { - // check for target_id+1 immediately following, with same encoding & language - if (i+1 < count && ttUSHORT(fc+loc+12+6) == next_id && ttUSHORT(fc+loc+12) == platform && ttUSHORT(fc+loc+12+2) == encoding && ttUSHORT(fc+loc+12+4) == language) { - slen = ttUSHORT(fc+loc+12+8); - off = ttUSHORT(fc+loc+12+10); - if (slen == 0) { - if (matchlen == nlen) - return 1; - } else if (matchlen < nlen && name[matchlen] == ' ') { - ++matchlen; - if (stbtt_CompareUTF8toUTF16_bigendian_internal((char*) (name+matchlen), nlen-matchlen, (char*)(fc+stringOffset+off),slen)) - return 1; - } - } else { - // if nothing immediately following - if (matchlen == nlen) - return 1; - } - } - } + // check if there's a prefix match + stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc + stringOffset + off, slen); + if (matchlen >= 0) + { + // check for target_id+1 immediately following, with same encoding & language + if (i + 1 < count && ttUSHORT(fc + loc + 12 + 6) == next_id && ttUSHORT(fc + loc + 12) == platform && ttUSHORT(fc + loc + 12 + 2) == encoding && ttUSHORT(fc + loc + 12 + 4) == language) + { + slen = ttUSHORT(fc + loc + 12 + 8); + off = ttUSHORT(fc + loc + 12 + 10); + if (slen == 0) + { + if (matchlen == nlen) + return 1; + } + else if (matchlen < nlen && name[matchlen] == ' ') + { + ++matchlen; + if (stbtt_CompareUTF8toUTF16_bigendian_internal((char *)(name + matchlen), nlen - matchlen, (char *)(fc + stringOffset + off), slen)) + return 1; + } + } + else + { + // if nothing immediately following + if (matchlen == nlen) + return 1; + } + } + } - // @TODO handle other encodings - } - } - return 0; + // @TODO handle other encodings + } + } + return 0; } static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *name, stbtt_int32 flags) { - stbtt_int32 nlen = (stbtt_int32) STBTT_strlen((char *) name); - stbtt_uint32 nm,hd; - if (!stbtt__isfont(fc+offset)) return 0; + stbtt_int32 nlen = (stbtt_int32)STBTT_strlen((char *)name); + stbtt_uint32 nm, hd; + if (!stbtt__isfont(fc + offset)) return 0; - // check italics/bold/underline flags in macStyle... - if (flags) { - hd = stbtt__find_table(fc, offset, "head"); - if ((ttUSHORT(fc+hd+44) & 7) != (flags & 7)) return 0; - } + // check italics/bold/underline flags in macStyle... + if (flags) + { + hd = stbtt__find_table(fc, offset, "head"); + if ((ttUSHORT(fc + hd + 44) & 7) != (flags & 7)) return 0; + } - nm = stbtt__find_table(fc, offset, "name"); - if (!nm) return 0; + nm = stbtt__find_table(fc, offset, "name"); + if (!nm) return 0; - if (flags) { - // if we checked the macStyle flags, then just check the family and ignore the subfamily - if (stbtt__matchpair(fc, nm, name, nlen, 16, -1)) return 1; - if (stbtt__matchpair(fc, nm, name, nlen, 1, -1)) return 1; - if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; - } else { - if (stbtt__matchpair(fc, nm, name, nlen, 16, 17)) return 1; - if (stbtt__matchpair(fc, nm, name, nlen, 1, 2)) return 1; - if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; - } + if (flags) + { + // if we checked the macStyle flags, then just check the family and ignore the subfamily + if (stbtt__matchpair(fc, nm, name, nlen, 16, -1)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 1, -1)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; + } + else + { + if (stbtt__matchpair(fc, nm, name, nlen, 16, 17)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 1, 2)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; + } - return 0; + return 0; } static int stbtt_FindMatchingFont_internal(unsigned char *font_collection, char *name_utf8, stbtt_int32 flags) { - stbtt_int32 i; - for (i=0;;++i) { - stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i); - if (off < 0) return off; - if (stbtt__matches((stbtt_uint8 *) font_collection, off, (stbtt_uint8*) name_utf8, flags)) - return off; - } + stbtt_int32 i; + for (i = 0;; ++i) + { + stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i); + if (off < 0) return off; + if (stbtt__matches((stbtt_uint8 *)font_collection, off, (stbtt_uint8 *)name_utf8, flags)) + return off; + } } #if defined(__GNUC__) || defined(__clang__) @@ -4716,43 +5122,42 @@ static int stbtt_FindMatchingFont_internal(unsigned char *font_collection, char #endif STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, - float pixel_height, unsigned char *pixels, int pw, int ph, - int first_char, int num_chars, stbtt_bakedchar *chardata) + float pixel_height, unsigned char *pixels, int pw, int ph, + int first_char, int num_chars, stbtt_bakedchar *chardata) { - return stbtt_BakeFontBitmap_internal((unsigned char *) data, offset, pixel_height, pixels, pw, ph, first_char, num_chars, chardata); + return stbtt_BakeFontBitmap_internal((unsigned char *)data, offset, pixel_height, pixels, pw, ph, first_char, num_chars, chardata); } STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index) { - return stbtt_GetFontOffsetForIndex_internal((unsigned char *) data, index); + return stbtt_GetFontOffsetForIndex_internal((unsigned char *)data, index); } STBTT_DEF int stbtt_GetNumberOfFonts(const unsigned char *data) { - return stbtt_GetNumberOfFonts_internal((unsigned char *) data); + return stbtt_GetNumberOfFonts_internal((unsigned char *)data); } STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset) { - return stbtt_InitFont_internal(info, (unsigned char *) data, offset); + return stbtt_InitFont_internal(info, (unsigned char *)data, offset); } STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags) { - return stbtt_FindMatchingFont_internal((unsigned char *) fontdata, (char *) name, flags); + return stbtt_FindMatchingFont_internal((unsigned char *)fontdata, (char *)name, flags); } STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2) { - return stbtt_CompareUTF8toUTF16_bigendian_internal((char *) s1, len1, (char *) s2, len2); + return stbtt_CompareUTF8toUTF16_bigendian_internal((char *)s1, len1, (char *)s2, len2); } #if defined(__GNUC__) || defined(__clang__) #pragma GCC diagnostic pop #endif -#endif // STB_TRUETYPE_IMPLEMENTATION - +#endif // STB_TRUETYPE_IMPLEMENTATION // FULL VERSION HISTORY // diff --git a/examples/ThirdPartyLibs/lua-5.2.3/lua_compiler/luac.c b/examples/ThirdPartyLibs/lua-5.2.3/lua_compiler/luac.c index 7409706ec..f5cd0d89f 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/lua_compiler/luac.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/lua_compiler/luac.c @@ -20,186 +20,188 @@ #include "lundump.h" static void PrintFunction(const Proto* f, int full); -#define luaU_print PrintFunction +#define luaU_print PrintFunction -#define PROGNAME "luac" /* default program name */ -#define OUTPUT PROGNAME ".out" /* default output file */ +#define PROGNAME "luac" /* default program name */ +#define OUTPUT PROGNAME ".out" /* default output file */ -static int listing=0; /* list bytecodes? */ -static int dumping=1; /* dump bytecodes? */ -static int stripping=0; /* strip debug information? */ -static char Output[]={ OUTPUT }; /* default output file name */ -static const char* output=Output; /* actual output file name */ -static const char* progname=PROGNAME; /* actual program name */ +static int listing = 0; /* list bytecodes? */ +static int dumping = 1; /* dump bytecodes? */ +static int stripping = 0; /* strip debug information? */ +static char Output[] = {OUTPUT}; /* default output file name */ +static const char* output = Output; /* actual output file name */ +static const char* progname = PROGNAME; /* actual program name */ static void fatal(const char* message) { - fprintf(stderr,"%s: %s\n",progname,message); - exit(EXIT_FAILURE); + fprintf(stderr, "%s: %s\n", progname, message); + exit(EXIT_FAILURE); } static void cannot(const char* what) { - fprintf(stderr,"%s: cannot %s %s: %s\n",progname,what,output,strerror(errno)); - exit(EXIT_FAILURE); + fprintf(stderr, "%s: cannot %s %s: %s\n", progname, what, output, strerror(errno)); + exit(EXIT_FAILURE); } static void usage(const char* message) { - if (*message=='-') - fprintf(stderr,"%s: unrecognized option " LUA_QS "\n",progname,message); - else - fprintf(stderr,"%s: %s\n",progname,message); - fprintf(stderr, - "usage: %s [options] [filenames]\n" - "Available options are:\n" - " -l list (use -l -l for full listing)\n" - " -o name output to file " LUA_QL("name") " (default is \"%s\")\n" - " -p parse only\n" - " -s strip debug information\n" - " -v show version information\n" - " -- stop handling options\n" - " - stop handling options and process stdin\n" - ,progname,Output); - exit(EXIT_FAILURE); + if (*message == '-') + fprintf(stderr, "%s: unrecognized option " LUA_QS "\n", progname, message); + else + fprintf(stderr, "%s: %s\n", progname, message); + fprintf(stderr, + "usage: %s [options] [filenames]\n" + "Available options are:\n" + " -l list (use -l -l for full listing)\n" + " -o name output to file " LUA_QL("name") + " (default is \"%s\")\n" + " -p parse only\n" + " -s strip debug information\n" + " -v show version information\n" + " -- stop handling options\n" + " - stop handling options and process stdin\n", + progname, Output); + exit(EXIT_FAILURE); } -#define IS(s) (strcmp(argv[i],s)==0) +#define IS(s) (strcmp(argv[i], s) == 0) static int doargs(int argc, char* argv[]) { - int i; - int version=0; - if (argv[0]!=NULL && *argv[0]!=0) progname=argv[0]; - for (i=1; itop+(i)) +#define toproto(L, i) getproto(L->top + (i)) static const Proto* combine(lua_State* L, int n) { - if (n==1) - return toproto(L,-1); - else - { - Proto* f; - int i=n; - if (lua_load(L,reader,&i,"=(" PROGNAME ")",NULL)!=LUA_OK) fatal(lua_tostring(L,-1)); - f=toproto(L,-1); - for (i=0; ip[i]=toproto(L,i-n-1); - if (f->p[i]->sizeupvalues>0) f->p[i]->upvalues[0].instack=0; - } - f->sizelineinfo=0; - return f; - } + if (n == 1) + return toproto(L, -1); + else + { + Proto* f; + int i = n; + if (lua_load(L, reader, &i, "=(" PROGNAME ")", NULL) != LUA_OK) fatal(lua_tostring(L, -1)); + f = toproto(L, -1); + for (i = 0; i < n; i++) + { + f->p[i] = toproto(L, i - n - 1); + if (f->p[i]->sizeupvalues > 0) f->p[i]->upvalues[0].instack = 0; + } + f->sizelineinfo = 0; + return f; + } } static int writer(lua_State* L, const void* p, size_t size, void* u) { - UNUSED(L); - return (fwrite(p,size,1,(FILE*)u)!=1) && (size!=0); + UNUSED(L); + return (fwrite(p, size, 1, (FILE*)u) != 1) && (size != 0); } static int pmain(lua_State* L) { - int argc=(int)lua_tointeger(L,1); - char** argv=(char**)lua_touserdata(L,2); - const Proto* f; - int i; - if (!lua_checkstack(L,argc)) fatal("too many input files"); - for (i=0; i1); - if (dumping) - { - FILE* D= (output==NULL) ? stdout : fopen(output,"wb"); - if (D==NULL) cannot("open"); - lua_lock(L); - luaU_dump(L,f,writer,D,stripping); - lua_unlock(L); - if (ferror(D)) cannot("write"); - if (fclose(D)) cannot("close"); - } - return 0; + int argc = (int)lua_tointeger(L, 1); + char** argv = (char**)lua_touserdata(L, 2); + const Proto* f; + int i; + if (!lua_checkstack(L, argc)) fatal("too many input files"); + for (i = 0; i < argc; i++) + { + const char* filename = IS("-") ? NULL : argv[i]; + if (luaL_loadfile(L, filename) != LUA_OK) fatal(lua_tostring(L, -1)); + } + f = combine(L, argc); + if (listing) luaU_print(f, listing > 1); + if (dumping) + { + FILE* D = (output == NULL) ? stdout : fopen(output, "wb"); + if (D == NULL) cannot("open"); + lua_lock(L); + luaU_dump(L, f, writer, D, stripping); + lua_unlock(L); + if (ferror(D)) cannot("write"); + if (fclose(D)) cannot("close"); + } + return 0; } int main(int argc, char* argv[]) { - lua_State* L; - int i=doargs(argc,argv); - argc-=i; argv+=i; - if (argc<=0) usage("no input files given"); - L=luaL_newstate(); - if (L==NULL) fatal("cannot create state: not enough memory"); - lua_pushcfunction(L,&pmain); - lua_pushinteger(L,argc); - lua_pushlightuserdata(L,argv); - if (lua_pcall(L,2,0,0)!=LUA_OK) fatal(lua_tostring(L,-1)); - lua_close(L); - return EXIT_SUCCESS; + lua_State* L; + int i = doargs(argc, argv); + argc -= i; + argv += i; + if (argc <= 0) usage("no input files given"); + L = luaL_newstate(); + if (L == NULL) fatal("cannot create state: not enough memory"); + lua_pushcfunction(L, &pmain); + lua_pushinteger(L, argc); + lua_pushlightuserdata(L, argv); + if (lua_pcall(L, 2, 0, 0) != LUA_OK) fatal(lua_tostring(L, -1)); + lua_close(L); + return EXIT_SUCCESS; } /* @@ -218,215 +220,264 @@ int main(int argc, char* argv[]) #include "lobject.h" #include "lopcodes.h" -#define VOID(p) ((const void*)(p)) +#define VOID(p) ((const void*)(p)) static void PrintString(const TString* ts) { - const char* s=getstr(ts); - size_t i,n=ts->tsv.len; - printf("%c",'"'); - for (i=0; itsv.len; + printf("%c", '"'); + for (i = 0; i < n; i++) + { + int c = (int)(unsigned char)s[i]; + switch (c) + { + case '"': + printf("\\\""); + break; + case '\\': + printf("\\\\"); + break; + case '\a': + printf("\\a"); + break; + case '\b': + printf("\\b"); + break; + case '\f': + printf("\\f"); + break; + case '\n': + printf("\\n"); + break; + case '\r': + printf("\\r"); + break; + case '\t': + printf("\\t"); + break; + case '\v': + printf("\\v"); + break; + default: + if (isprint(c)) + printf("%c", c); + else + printf("\\%03d", c); + } + } + printf("%c", '"'); } static void PrintConstant(const Proto* f, int i) { - const TValue* o=&f->k[i]; - switch (ttypenv(o)) - { - case LUA_TNIL: - printf("nil"); - break; - case LUA_TBOOLEAN: - printf(bvalue(o) ? "true" : "false"); - break; - case LUA_TNUMBER: - printf(LUA_NUMBER_FMT,nvalue(o)); - break; - case LUA_TSTRING: - PrintString(rawtsvalue(o)); - break; - default: /* cannot happen */ - printf("? type=%d",ttype(o)); - break; - } + const TValue* o = &f->k[i]; + switch (ttypenv(o)) + { + case LUA_TNIL: + printf("nil"); + break; + case LUA_TBOOLEAN: + printf(bvalue(o) ? "true" : "false"); + break; + case LUA_TNUMBER: + printf(LUA_NUMBER_FMT, nvalue(o)); + break; + case LUA_TSTRING: + PrintString(rawtsvalue(o)); + break; + default: /* cannot happen */ + printf("? type=%d", ttype(o)); + break; + } } #define UPVALNAME(x) ((f->upvalues[x].name) ? getstr(f->upvalues[x].name) : "-") -#define MYK(x) (-1-(x)) +#define MYK(x) (-1 - (x)) static void PrintCode(const Proto* f) { - const Instruction* code=f->code; - int pc,n=f->sizecode; - for (pc=0; pc0) printf("[%d]\t",line); else printf("[-]\t"); - printf("%-9s\t",luaP_opnames[o]); - switch (getOpMode(o)) - { - case iABC: - printf("%d",a); - if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (MYK(INDEXK(b))) : b); - if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (MYK(INDEXK(c))) : c); - break; - case iABx: - printf("%d",a); - if (getBMode(o)==OpArgK) printf(" %d",MYK(bx)); - if (getBMode(o)==OpArgU) printf(" %d",bx); - break; - case iAsBx: - printf("%d %d",a,sbx); - break; - case iAx: - printf("%d",MYK(ax)); - break; - } - switch (o) - { - case OP_LOADK: - printf("\t; "); PrintConstant(f,bx); - break; - case OP_GETUPVAL: - case OP_SETUPVAL: - printf("\t; %s",UPVALNAME(b)); - break; - case OP_GETTABUP: - printf("\t; %s",UPVALNAME(b)); - if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); } - break; - case OP_SETTABUP: - printf("\t; %s",UPVALNAME(a)); - if (ISK(b)) { printf(" "); PrintConstant(f,INDEXK(b)); } - if (ISK(c)) { printf(" "); PrintConstant(f,INDEXK(c)); } - break; - case OP_GETTABLE: - case OP_SELF: - if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); } - break; - case OP_SETTABLE: - case OP_ADD: - case OP_SUB: - case OP_MUL: - case OP_DIV: - case OP_POW: - case OP_EQ: - case OP_LT: - case OP_LE: - if (ISK(b) || ISK(c)) - { - printf("\t; "); - if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-"); - printf(" "); - if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-"); - } - break; - case OP_JMP: - case OP_FORLOOP: - case OP_FORPREP: - case OP_TFORLOOP: - printf("\t; to %d",sbx+pc+2); - break; - case OP_CLOSURE: - printf("\t; %p",VOID(f->p[bx])); - break; - case OP_SETLIST: - if (c==0) printf("\t; %d",(int)code[++pc]); else printf("\t; %d",c); - break; - case OP_EXTRAARG: - printf("\t; "); PrintConstant(f,ax); - break; - default: - break; - } - printf("\n"); - } + const Instruction* code = f->code; + int pc, n = f->sizecode; + for (pc = 0; pc < n; pc++) + { + Instruction i = code[pc]; + OpCode o = GET_OPCODE(i); + int a = GETARG_A(i); + int b = GETARG_B(i); + int c = GETARG_C(i); + int ax = GETARG_Ax(i); + int bx = GETARG_Bx(i); + int sbx = GETARG_sBx(i); + int line = getfuncline(f, pc); + printf("\t%d\t", pc + 1); + if (line > 0) + printf("[%d]\t", line); + else + printf("[-]\t"); + printf("%-9s\t", luaP_opnames[o]); + switch (getOpMode(o)) + { + case iABC: + printf("%d", a); + if (getBMode(o) != OpArgN) printf(" %d", ISK(b) ? (MYK(INDEXK(b))) : b); + if (getCMode(o) != OpArgN) printf(" %d", ISK(c) ? (MYK(INDEXK(c))) : c); + break; + case iABx: + printf("%d", a); + if (getBMode(o) == OpArgK) printf(" %d", MYK(bx)); + if (getBMode(o) == OpArgU) printf(" %d", bx); + break; + case iAsBx: + printf("%d %d", a, sbx); + break; + case iAx: + printf("%d", MYK(ax)); + break; + } + switch (o) + { + case OP_LOADK: + printf("\t; "); + PrintConstant(f, bx); + break; + case OP_GETUPVAL: + case OP_SETUPVAL: + printf("\t; %s", UPVALNAME(b)); + break; + case OP_GETTABUP: + printf("\t; %s", UPVALNAME(b)); + if (ISK(c)) + { + printf(" "); + PrintConstant(f, INDEXK(c)); + } + break; + case OP_SETTABUP: + printf("\t; %s", UPVALNAME(a)); + if (ISK(b)) + { + printf(" "); + PrintConstant(f, INDEXK(b)); + } + if (ISK(c)) + { + printf(" "); + PrintConstant(f, INDEXK(c)); + } + break; + case OP_GETTABLE: + case OP_SELF: + if (ISK(c)) + { + printf("\t; "); + PrintConstant(f, INDEXK(c)); + } + break; + case OP_SETTABLE: + case OP_ADD: + case OP_SUB: + case OP_MUL: + case OP_DIV: + case OP_POW: + case OP_EQ: + case OP_LT: + case OP_LE: + if (ISK(b) || ISK(c)) + { + printf("\t; "); + if (ISK(b)) + PrintConstant(f, INDEXK(b)); + else + printf("-"); + printf(" "); + if (ISK(c)) + PrintConstant(f, INDEXK(c)); + else + printf("-"); + } + break; + case OP_JMP: + case OP_FORLOOP: + case OP_FORPREP: + case OP_TFORLOOP: + printf("\t; to %d", sbx + pc + 2); + break; + case OP_CLOSURE: + printf("\t; %p", VOID(f->p[bx])); + break; + case OP_SETLIST: + if (c == 0) + printf("\t; %d", (int)code[++pc]); + else + printf("\t; %d", c); + break; + case OP_EXTRAARG: + printf("\t; "); + PrintConstant(f, ax); + break; + default: + break; + } + printf("\n"); + } } -#define SS(x) ((x==1)?"":"s") -#define S(x) (int)(x),SS(x) +#define SS(x) ((x == 1) ? "" : "s") +#define S(x) (int)(x), SS(x) static void PrintHeader(const Proto* f) { - const char* s=f->source ? getstr(f->source) : "=?"; - if (*s=='@' || *s=='=') - s++; - else if (*s==LUA_SIGNATURE[0]) - s="(bstring)"; - else - s="(string)"; - printf("\n%s <%s:%d,%d> (%d instruction%s at %p)\n", - (f->linedefined==0)?"main":"function",s, - f->linedefined,f->lastlinedefined, - S(f->sizecode),VOID(f)); - printf("%d%s param%s, %d slot%s, %d upvalue%s, ", - (int)(f->numparams),f->is_vararg?"+":"",SS(f->numparams), - S(f->maxstacksize),S(f->sizeupvalues)); - printf("%d local%s, %d constant%s, %d function%s\n", - S(f->sizelocvars),S(f->sizek),S(f->sizep)); + const char* s = f->source ? getstr(f->source) : "=?"; + if (*s == '@' || *s == '=') + s++; + else if (*s == LUA_SIGNATURE[0]) + s = "(bstring)"; + else + s = "(string)"; + printf("\n%s <%s:%d,%d> (%d instruction%s at %p)\n", + (f->linedefined == 0) ? "main" : "function", s, + f->linedefined, f->lastlinedefined, + S(f->sizecode), VOID(f)); + printf("%d%s param%s, %d slot%s, %d upvalue%s, ", + (int)(f->numparams), f->is_vararg ? "+" : "", SS(f->numparams), + S(f->maxstacksize), S(f->sizeupvalues)); + printf("%d local%s, %d constant%s, %d function%s\n", + S(f->sizelocvars), S(f->sizek), S(f->sizep)); } static void PrintDebug(const Proto* f) { - int i,n; - n=f->sizek; - printf("constants (%d) for %p:\n",n,VOID(f)); - for (i=0; isizelocvars; - printf("locals (%d) for %p:\n",n,VOID(f)); - for (i=0; ilocvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1); - } - n=f->sizeupvalues; - printf("upvalues (%d) for %p:\n",n,VOID(f)); - for (i=0; iupvalues[i].instack,f->upvalues[i].idx); - } + int i, n; + n = f->sizek; + printf("constants (%d) for %p:\n", n, VOID(f)); + for (i = 0; i < n; i++) + { + printf("\t%d\t", i + 1); + PrintConstant(f, i); + printf("\n"); + } + n = f->sizelocvars; + printf("locals (%d) for %p:\n", n, VOID(f)); + for (i = 0; i < n; i++) + { + printf("\t%d\t%s\t%d\t%d\n", + i, getstr(f->locvars[i].varname), f->locvars[i].startpc + 1, f->locvars[i].endpc + 1); + } + n = f->sizeupvalues; + printf("upvalues (%d) for %p:\n", n, VOID(f)); + for (i = 0; i < n; i++) + { + printf("\t%d\t%s\t%d\t%d\n", + i, UPVALNAME(i), f->upvalues[i].instack, f->upvalues[i].idx); + } } static void PrintFunction(const Proto* f, int full) { - int i,n=f->sizep; - PrintHeader(f); - PrintCode(f); - if (full) PrintDebug(f); - for (i=0; ip[i],full); + int i, n = f->sizep; + PrintHeader(f); + PrintCode(f); + if (full) PrintDebug(f); + for (i = 0; i < n; i++) PrintFunction(f->p[i], full); } diff --git a/examples/ThirdPartyLibs/lua-5.2.3/lua_standalone/lua.c b/examples/ThirdPartyLibs/lua-5.2.3/lua_standalone/lua.c index 4345e554e..8d9cd0bea 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/lua_standalone/lua.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/lua_standalone/lua.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #include #include #include @@ -17,44 +16,41 @@ #include "lauxlib.h" #include "lualib.h" - #if !defined(LUA_PROMPT) -#define LUA_PROMPT "> " -#define LUA_PROMPT2 ">> " +#define LUA_PROMPT "> " +#define LUA_PROMPT2 ">> " #endif #if !defined(LUA_PROGNAME) -#define LUA_PROGNAME "lua" +#define LUA_PROGNAME "lua" #endif #if !defined(LUA_MAXINPUT) -#define LUA_MAXINPUT 512 +#define LUA_MAXINPUT 512 #endif #if !defined(LUA_INIT) -#define LUA_INIT "LUA_INIT" +#define LUA_INIT "LUA_INIT" #endif -#define LUA_INITVERSION \ +#define LUA_INITVERSION \ LUA_INIT "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR - /* ** lua_stdin_is_tty detects whether the standard input is a 'tty' (that ** is, whether we're running lua interactively). */ #if defined(LUA_USE_ISATTY) #include -#define lua_stdin_is_tty() isatty(0) +#define lua_stdin_is_tty() isatty(0) #elif defined(LUA_WIN) #include #include -#define lua_stdin_is_tty() _isatty(_fileno(stdin)) +#define lua_stdin_is_tty() _isatty(_fileno(stdin)) #else -#define lua_stdin_is_tty() 1 /* assume stdin is a tty */ +#define lua_stdin_is_tty() 1 /* assume stdin is a tty */ #endif - /* ** lua_readline defines how to show a prompt and then read a line from ** the standard input. @@ -66,432 +62,464 @@ #include #include #include -#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL) -#define lua_saveline(L,idx) \ - if (lua_rawlen(L,idx) > 0) /* non-empty line? */ \ - add_history(lua_tostring(L, idx)); /* add it to history */ -#define lua_freeline(L,b) ((void)L, free(b)) +#define lua_readline(L, b, p) ((void)L, ((b) = readline(p)) != NULL) +#define lua_saveline(L, idx) \ + if (lua_rawlen(L, idx) > 0) /* non-empty line? */ \ + add_history(lua_tostring(L, idx)); /* add it to history */ +#define lua_freeline(L, b) ((void)L, free(b)) #elif !defined(lua_readline) -#define lua_readline(L,b,p) \ - ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ - fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ -#define lua_saveline(L,idx) { (void)L; (void)idx; } -#define lua_freeline(L,b) { (void)L; (void)b; } +#define lua_readline(L, b, p) \ + ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \ + fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */ +#define lua_saveline(L, idx) \ + { \ + (void)L; \ + (void)idx; \ + } +#define lua_freeline(L, b) \ + { \ + (void)L; \ + (void)b; \ + } #endif - - - static lua_State *globalL = NULL; static const char *progname = LUA_PROGNAME; - - -static void lstop (lua_State *L, lua_Debug *ar) { - (void)ar; /* unused arg. */ - lua_sethook(L, NULL, 0, 0); - luaL_error(L, "interrupted!"); +static void lstop(lua_State *L, lua_Debug *ar) +{ + (void)ar; /* unused arg. */ + lua_sethook(L, NULL, 0, 0); + luaL_error(L, "interrupted!"); } - -static void laction (int i) { - signal(i, SIG_DFL); /* if another SIGINT happens before lstop, +static void laction(int i) +{ + signal(i, SIG_DFL); /* if another SIGINT happens before lstop, terminate process (default action) */ - lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); + lua_sethook(globalL, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); } - -static void print_usage (const char *badoption) { - luai_writestringerror("%s: ", progname); - if (badoption[1] == 'e' || badoption[1] == 'l') - luai_writestringerror("'%s' needs argument\n", badoption); - else - luai_writestringerror("unrecognized option '%s'\n", badoption); - luai_writestringerror( - "usage: %s [options] [script [args]]\n" - "Available options are:\n" - " -e stat execute string " LUA_QL("stat") "\n" - " -i enter interactive mode after executing " LUA_QL("script") "\n" - " -l name require library " LUA_QL("name") "\n" - " -v show version information\n" - " -E ignore environment variables\n" - " -- stop handling options\n" - " - stop handling options and execute stdin\n" - , - progname); +static void print_usage(const char *badoption) +{ + luai_writestringerror("%s: ", progname); + if (badoption[1] == 'e' || badoption[1] == 'l') + luai_writestringerror("'%s' needs argument\n", badoption); + else + luai_writestringerror("unrecognized option '%s'\n", badoption); + luai_writestringerror( + "usage: %s [options] [script [args]]\n" + "Available options are:\n" + " -e stat execute string " LUA_QL("stat") + "\n" + " -i enter interactive mode after executing " LUA_QL("script") + "\n" + " -l name require library " LUA_QL("name") + "\n" + " -v show version information\n" + " -E ignore environment variables\n" + " -- stop handling options\n" + " - stop handling options and execute stdin\n", + progname); } - -static void l_message (const char *pname, const char *msg) { - if (pname) luai_writestringerror("%s: ", pname); - luai_writestringerror("%s\n", msg); +static void l_message(const char *pname, const char *msg) +{ + if (pname) luai_writestringerror("%s: ", pname); + luai_writestringerror("%s\n", msg); } - -static int report (lua_State *L, int status) { - if (status != LUA_OK && !lua_isnil(L, -1)) { - const char *msg = lua_tostring(L, -1); - if (msg == NULL) msg = "(error object is not a string)"; - l_message(progname, msg); - lua_pop(L, 1); - /* force a complete garbage collection in case of errors */ - lua_gc(L, LUA_GCCOLLECT, 0); - } - return status; +static int report(lua_State *L, int status) +{ + if (status != LUA_OK && !lua_isnil(L, -1)) + { + const char *msg = lua_tostring(L, -1); + if (msg == NULL) msg = "(error object is not a string)"; + l_message(progname, msg); + lua_pop(L, 1); + /* force a complete garbage collection in case of errors */ + lua_gc(L, LUA_GCCOLLECT, 0); + } + return status; } - /* the next function is called unprotected, so it must avoid errors */ -static void finalreport (lua_State *L, int status) { - if (status != LUA_OK) { - const char *msg = (lua_type(L, -1) == LUA_TSTRING) ? lua_tostring(L, -1) - : NULL; - if (msg == NULL) msg = "(error object is not a string)"; - l_message(progname, msg); - lua_pop(L, 1); - } +static void finalreport(lua_State *L, int status) +{ + if (status != LUA_OK) + { + const char *msg = (lua_type(L, -1) == LUA_TSTRING) ? lua_tostring(L, -1) + : NULL; + if (msg == NULL) msg = "(error object is not a string)"; + l_message(progname, msg); + lua_pop(L, 1); + } } - -static int traceback (lua_State *L) { - const char *msg = lua_tostring(L, 1); - if (msg) - luaL_traceback(L, L, msg, 1); - else if (!lua_isnoneornil(L, 1)) { /* is there an error object? */ - if (!luaL_callmeta(L, 1, "__tostring")) /* try its 'tostring' metamethod */ - lua_pushliteral(L, "(no error message)"); - } - return 1; +static int traceback(lua_State *L) +{ + const char *msg = lua_tostring(L, 1); + if (msg) + luaL_traceback(L, L, msg, 1); + else if (!lua_isnoneornil(L, 1)) + { /* is there an error object? */ + if (!luaL_callmeta(L, 1, "__tostring")) /* try its 'tostring' metamethod */ + lua_pushliteral(L, "(no error message)"); + } + return 1; } - -static int docall (lua_State *L, int narg, int nres) { - int status; - int base = lua_gettop(L) - narg; /* function index */ - lua_pushcfunction(L, traceback); /* push traceback function */ - lua_insert(L, base); /* put it under chunk and args */ - globalL = L; /* to be available to 'laction' */ - signal(SIGINT, laction); - status = lua_pcall(L, narg, nres, base); - signal(SIGINT, SIG_DFL); - lua_remove(L, base); /* remove traceback function */ - return status; +static int docall(lua_State *L, int narg, int nres) +{ + int status; + int base = lua_gettop(L) - narg; /* function index */ + lua_pushcfunction(L, traceback); /* push traceback function */ + lua_insert(L, base); /* put it under chunk and args */ + globalL = L; /* to be available to 'laction' */ + signal(SIGINT, laction); + status = lua_pcall(L, narg, nres, base); + signal(SIGINT, SIG_DFL); + lua_remove(L, base); /* remove traceback function */ + return status; } - -static void print_version (void) { - luai_writestring(LUA_COPYRIGHT, strlen(LUA_COPYRIGHT)); - luai_writeline(); +static void print_version(void) +{ + luai_writestring(LUA_COPYRIGHT, strlen(LUA_COPYRIGHT)); + luai_writeline(); } - -static int getargs (lua_State *L, char **argv, int n) { - int narg; - int i; - int argc = 0; - while (argv[argc]) argc++; /* count total number of arguments */ - narg = argc - (n + 1); /* number of arguments to the script */ - luaL_checkstack(L, narg + 3, "too many arguments to script"); - for (i=n+1; i < argc; i++) - lua_pushstring(L, argv[i]); - lua_createtable(L, narg, n + 1); - for (i=0; i < argc; i++) { - lua_pushstring(L, argv[i]); - lua_rawseti(L, -2, i - n); - } - return narg; +static int getargs(lua_State *L, char **argv, int n) +{ + int narg; + int i; + int argc = 0; + while (argv[argc]) argc++; /* count total number of arguments */ + narg = argc - (n + 1); /* number of arguments to the script */ + luaL_checkstack(L, narg + 3, "too many arguments to script"); + for (i = n + 1; i < argc; i++) + lua_pushstring(L, argv[i]); + lua_createtable(L, narg, n + 1); + for (i = 0; i < argc; i++) + { + lua_pushstring(L, argv[i]); + lua_rawseti(L, -2, i - n); + } + return narg; } - -static int dofile (lua_State *L, const char *name) { - int status = luaL_loadfile(L, name); - if (status == LUA_OK) status = docall(L, 0, 0); - return report(L, status); +static int dofile(lua_State *L, const char *name) +{ + int status = luaL_loadfile(L, name); + if (status == LUA_OK) status = docall(L, 0, 0); + return report(L, status); } - -static int dostring (lua_State *L, const char *s, const char *name) { - int status = luaL_loadbuffer(L, s, strlen(s), name); - if (status == LUA_OK) status = docall(L, 0, 0); - return report(L, status); +static int dostring(lua_State *L, const char *s, const char *name) +{ + int status = luaL_loadbuffer(L, s, strlen(s), name); + if (status == LUA_OK) status = docall(L, 0, 0); + return report(L, status); } - -static int dolibrary (lua_State *L, const char *name) { - int status; - lua_getglobal(L, "require"); - lua_pushstring(L, name); - status = docall(L, 1, 1); /* call 'require(name)' */ - if (status == LUA_OK) - lua_setglobal(L, name); /* global[name] = require return */ - return report(L, status); +static int dolibrary(lua_State *L, const char *name) +{ + int status; + lua_getglobal(L, "require"); + lua_pushstring(L, name); + status = docall(L, 1, 1); /* call 'require(name)' */ + if (status == LUA_OK) + lua_setglobal(L, name); /* global[name] = require return */ + return report(L, status); } - -static const char *get_prompt (lua_State *L, int firstline) { - const char *p; - lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2"); - p = lua_tostring(L, -1); - if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); - return p; +static const char *get_prompt(lua_State *L, int firstline) +{ + const char *p; + lua_getglobal(L, firstline ? "_PROMPT" : "_PROMPT2"); + p = lua_tostring(L, -1); + if (p == NULL) p = (firstline ? LUA_PROMPT : LUA_PROMPT2); + return p; } /* mark in error messages for incomplete statements */ -#define EOFMARK "" -#define marklen (sizeof(EOFMARK)/sizeof(char) - 1) +#define EOFMARK "" +#define marklen (sizeof(EOFMARK) / sizeof(char) - 1) -static int incomplete (lua_State *L, int status) { - if (status == LUA_ERRSYNTAX) { - size_t lmsg; - const char *msg = lua_tolstring(L, -1, &lmsg); - if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0) { - lua_pop(L, 1); - return 1; - } - } - return 0; /* else... */ +static int incomplete(lua_State *L, int status) +{ + if (status == LUA_ERRSYNTAX) + { + size_t lmsg; + const char *msg = lua_tolstring(L, -1, &lmsg); + if (lmsg >= marklen && strcmp(msg + lmsg - marklen, EOFMARK) == 0) + { + lua_pop(L, 1); + return 1; + } + } + return 0; /* else... */ } - -static int pushline (lua_State *L, int firstline) { - char buffer[LUA_MAXINPUT]; - char *b = buffer; - size_t l; - const char *prmt = get_prompt(L, firstline); - int readstatus = lua_readline(L, b, prmt); - lua_pop(L, 1); /* remove result from 'get_prompt' */ - if (readstatus == 0) - return 0; /* no input */ - l = strlen(b); - if (l > 0 && b[l-1] == '\n') /* line ends with newline? */ - b[l-1] = '\0'; /* remove it */ - if (firstline && b[0] == '=') /* first line starts with `=' ? */ - lua_pushfstring(L, "return %s", b+1); /* change it to `return' */ - else - lua_pushstring(L, b); - lua_freeline(L, b); - return 1; +static int pushline(lua_State *L, int firstline) +{ + char buffer[LUA_MAXINPUT]; + char *b = buffer; + size_t l; + const char *prmt = get_prompt(L, firstline); + int readstatus = lua_readline(L, b, prmt); + lua_pop(L, 1); /* remove result from 'get_prompt' */ + if (readstatus == 0) + return 0; /* no input */ + l = strlen(b); + if (l > 0 && b[l - 1] == '\n') /* line ends with newline? */ + b[l - 1] = '\0'; /* remove it */ + if (firstline && b[0] == '=') /* first line starts with `=' ? */ + lua_pushfstring(L, "return %s", b + 1); /* change it to `return' */ + else + lua_pushstring(L, b); + lua_freeline(L, b); + return 1; } - -static int loadline (lua_State *L) { - int status; - lua_settop(L, 0); - if (!pushline(L, 1)) - return -1; /* no input */ - for (;;) { /* repeat until gets a complete line */ - size_t l; - const char *line = lua_tolstring(L, 1, &l); - status = luaL_loadbuffer(L, line, l, "=stdin"); - if (!incomplete(L, status)) break; /* cannot try to add lines? */ - if (!pushline(L, 0)) /* no more input? */ - return -1; - lua_pushliteral(L, "\n"); /* add a new line... */ - lua_insert(L, -2); /* ...between the two lines */ - lua_concat(L, 3); /* join them */ - } - lua_saveline(L, 1); - lua_remove(L, 1); /* remove line */ - return status; +static int loadline(lua_State *L) +{ + int status; + lua_settop(L, 0); + if (!pushline(L, 1)) + return -1; /* no input */ + for (;;) + { /* repeat until gets a complete line */ + size_t l; + const char *line = lua_tolstring(L, 1, &l); + status = luaL_loadbuffer(L, line, l, "=stdin"); + if (!incomplete(L, status)) break; /* cannot try to add lines? */ + if (!pushline(L, 0)) /* no more input? */ + return -1; + lua_pushliteral(L, "\n"); /* add a new line... */ + lua_insert(L, -2); /* ...between the two lines */ + lua_concat(L, 3); /* join them */ + } + lua_saveline(L, 1); + lua_remove(L, 1); /* remove line */ + return status; } - -static void dotty (lua_State *L) { - int status; - const char *oldprogname = progname; - progname = NULL; - while ((status = loadline(L)) != -1) { - if (status == LUA_OK) status = docall(L, 0, LUA_MULTRET); - report(L, status); - if (status == LUA_OK && lua_gettop(L) > 0) { /* any result to print? */ - luaL_checkstack(L, LUA_MINSTACK, "too many results to print"); - lua_getglobal(L, "print"); - lua_insert(L, 1); - if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != LUA_OK) - l_message(progname, lua_pushfstring(L, - "error calling " LUA_QL("print") " (%s)", - lua_tostring(L, -1))); - } - } - lua_settop(L, 0); /* clear stack */ - luai_writeline(); - progname = oldprogname; +static void dotty(lua_State *L) +{ + int status; + const char *oldprogname = progname; + progname = NULL; + while ((status = loadline(L)) != -1) + { + if (status == LUA_OK) status = docall(L, 0, LUA_MULTRET); + report(L, status); + if (status == LUA_OK && lua_gettop(L) > 0) + { /* any result to print? */ + luaL_checkstack(L, LUA_MINSTACK, "too many results to print"); + lua_getglobal(L, "print"); + lua_insert(L, 1); + if (lua_pcall(L, lua_gettop(L) - 1, 0, 0) != LUA_OK) + l_message(progname, lua_pushfstring(L, + "error calling " LUA_QL("print") " (%s)", + lua_tostring(L, -1))); + } + } + lua_settop(L, 0); /* clear stack */ + luai_writeline(); + progname = oldprogname; } - -static int handle_script (lua_State *L, char **argv, int n) { - int status; - const char *fname; - int narg = getargs(L, argv, n); /* collect arguments */ - lua_setglobal(L, "arg"); - fname = argv[n]; - if (strcmp(fname, "-") == 0 && strcmp(argv[n-1], "--") != 0) - fname = NULL; /* stdin */ - status = luaL_loadfile(L, fname); - lua_insert(L, -(narg+1)); - if (status == LUA_OK) - status = docall(L, narg, LUA_MULTRET); - else - lua_pop(L, narg); - return report(L, status); +static int handle_script(lua_State *L, char **argv, int n) +{ + int status; + const char *fname; + int narg = getargs(L, argv, n); /* collect arguments */ + lua_setglobal(L, "arg"); + fname = argv[n]; + if (strcmp(fname, "-") == 0 && strcmp(argv[n - 1], "--") != 0) + fname = NULL; /* stdin */ + status = luaL_loadfile(L, fname); + lua_insert(L, -(narg + 1)); + if (status == LUA_OK) + status = docall(L, narg, LUA_MULTRET); + else + lua_pop(L, narg); + return report(L, status); } - /* check that argument has no extra characters at the end */ -#define noextrachars(x) {if ((x)[2] != '\0') return -1;} - +#define noextrachars(x) \ + { \ + if ((x)[2] != '\0') return -1; \ + } /* indices of various argument indicators in array args */ -#define has_i 0 /* -i */ -#define has_v 1 /* -v */ -#define has_e 2 /* -e */ -#define has_E 3 /* -E */ +#define has_i 0 /* -i */ +#define has_v 1 /* -v */ +#define has_e 2 /* -e */ +#define has_E 3 /* -E */ -#define num_has 4 /* number of 'has_*' */ +#define num_has 4 /* number of 'has_*' */ - -static int collectargs (char **argv, int *args) { - int i; - for (i = 1; argv[i] != NULL; i++) { - if (argv[i][0] != '-') /* not an option? */ - return i; - switch (argv[i][1]) { /* option */ - case '-': - noextrachars(argv[i]); - return (argv[i+1] != NULL ? i+1 : 0); - case '\0': - return i; - case 'E': - args[has_E] = 1; - break; - case 'i': - noextrachars(argv[i]); - args[has_i] = 1; /* go through */ - case 'v': - noextrachars(argv[i]); - args[has_v] = 1; - break; - case 'e': - args[has_e] = 1; /* go through */ - case 'l': /* both options need an argument */ - if (argv[i][2] == '\0') { /* no concatenated argument? */ - i++; /* try next 'argv' */ - if (argv[i] == NULL || argv[i][0] == '-') - return -(i - 1); /* no next argument or it is another option */ - } - break; - default: /* invalid option; return its index... */ - return -i; /* ...as a negative value */ - } - } - return 0; +static int collectargs(char **argv, int *args) +{ + int i; + for (i = 1; argv[i] != NULL; i++) + { + if (argv[i][0] != '-') /* not an option? */ + return i; + switch (argv[i][1]) + { /* option */ + case '-': + noextrachars(argv[i]); + return (argv[i + 1] != NULL ? i + 1 : 0); + case '\0': + return i; + case 'E': + args[has_E] = 1; + break; + case 'i': + noextrachars(argv[i]); + args[has_i] = 1; /* go through */ + case 'v': + noextrachars(argv[i]); + args[has_v] = 1; + break; + case 'e': + args[has_e] = 1; /* go through */ + case 'l': /* both options need an argument */ + if (argv[i][2] == '\0') + { /* no concatenated argument? */ + i++; /* try next 'argv' */ + if (argv[i] == NULL || argv[i][0] == '-') + return -(i - 1); /* no next argument or it is another option */ + } + break; + default: /* invalid option; return its index... */ + return -i; /* ...as a negative value */ + } + } + return 0; } - -static int runargs (lua_State *L, char **argv, int n) { - int i; - for (i = 1; i < n; i++) { - lua_assert(argv[i][0] == '-'); - switch (argv[i][1]) { /* option */ - case 'e': { - const char *chunk = argv[i] + 2; - if (*chunk == '\0') chunk = argv[++i]; - lua_assert(chunk != NULL); - if (dostring(L, chunk, "=(command line)") != LUA_OK) - return 0; - break; - } - case 'l': { - const char *filename = argv[i] + 2; - if (*filename == '\0') filename = argv[++i]; - lua_assert(filename != NULL); - if (dolibrary(L, filename) != LUA_OK) - return 0; /* stop if file fails */ - break; - } - default: break; - } - } - return 1; +static int runargs(lua_State *L, char **argv, int n) +{ + int i; + for (i = 1; i < n; i++) + { + lua_assert(argv[i][0] == '-'); + switch (argv[i][1]) + { /* option */ + case 'e': + { + const char *chunk = argv[i] + 2; + if (*chunk == '\0') chunk = argv[++i]; + lua_assert(chunk != NULL); + if (dostring(L, chunk, "=(command line)") != LUA_OK) + return 0; + break; + } + case 'l': + { + const char *filename = argv[i] + 2; + if (*filename == '\0') filename = argv[++i]; + lua_assert(filename != NULL); + if (dolibrary(L, filename) != LUA_OK) + return 0; /* stop if file fails */ + break; + } + default: + break; + } + } + return 1; } - -static int handle_luainit (lua_State *L) { - const char *name = "=" LUA_INITVERSION; - const char *init = getenv(name + 1); - if (init == NULL) { - name = "=" LUA_INIT; - init = getenv(name + 1); /* try alternative name */ - } - if (init == NULL) return LUA_OK; - else if (init[0] == '@') - return dofile(L, init+1); - else - return dostring(L, init, name); +static int handle_luainit(lua_State *L) +{ + const char *name = "=" LUA_INITVERSION; + const char *init = getenv(name + 1); + if (init == NULL) + { + name = "=" LUA_INIT; + init = getenv(name + 1); /* try alternative name */ + } + if (init == NULL) + return LUA_OK; + else if (init[0] == '@') + return dofile(L, init + 1); + else + return dostring(L, init, name); } - -static int pmain (lua_State *L) { - int argc = (int)lua_tointeger(L, 1); - char **argv = (char **)lua_touserdata(L, 2); - int script; - int args[num_has]; - args[has_i] = args[has_v] = args[has_e] = args[has_E] = 0; - if (argv[0] && argv[0][0]) progname = argv[0]; - script = collectargs(argv, args); - if (script < 0) { /* invalid arg? */ - print_usage(argv[-script]); - return 0; - } - if (args[has_v]) print_version(); - if (args[has_E]) { /* option '-E'? */ - lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */ - lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); - } - /* open standard libraries */ - luaL_checkversion(L); - lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ - luaL_openlibs(L); /* open libraries */ - lua_gc(L, LUA_GCRESTART, 0); - if (!args[has_E] && handle_luainit(L) != LUA_OK) - return 0; /* error running LUA_INIT */ - /* execute arguments -e and -l */ - if (!runargs(L, argv, (script > 0) ? script : argc)) return 0; - /* execute main script (if there is one) */ - if (script && handle_script(L, argv, script) != LUA_OK) return 0; - if (args[has_i]) /* -i option? */ - dotty(L); - else if (script == 0 && !args[has_e] && !args[has_v]) { /* no arguments? */ - if (lua_stdin_is_tty()) { - print_version(); - dotty(L); - } - else dofile(L, NULL); /* executes stdin as a file */ - } - lua_pushboolean(L, 1); /* signal no errors */ - return 1; +static int pmain(lua_State *L) +{ + int argc = (int)lua_tointeger(L, 1); + char **argv = (char **)lua_touserdata(L, 2); + int script; + int args[num_has]; + args[has_i] = args[has_v] = args[has_e] = args[has_E] = 0; + if (argv[0] && argv[0][0]) progname = argv[0]; + script = collectargs(argv, args); + if (script < 0) + { /* invalid arg? */ + print_usage(argv[-script]); + return 0; + } + if (args[has_v]) print_version(); + if (args[has_E]) + { /* option '-E'? */ + lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */ + lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); + } + /* open standard libraries */ + luaL_checkversion(L); + lua_gc(L, LUA_GCSTOP, 0); /* stop collector during initialization */ + luaL_openlibs(L); /* open libraries */ + lua_gc(L, LUA_GCRESTART, 0); + if (!args[has_E] && handle_luainit(L) != LUA_OK) + return 0; /* error running LUA_INIT */ + /* execute arguments -e and -l */ + if (!runargs(L, argv, (script > 0) ? script : argc)) return 0; + /* execute main script (if there is one) */ + if (script && handle_script(L, argv, script) != LUA_OK) return 0; + if (args[has_i]) /* -i option? */ + dotty(L); + else if (script == 0 && !args[has_e] && !args[has_v]) + { /* no arguments? */ + if (lua_stdin_is_tty()) + { + print_version(); + dotty(L); + } + else + dofile(L, NULL); /* executes stdin as a file */ + } + lua_pushboolean(L, 1); /* signal no errors */ + return 1; } - -int main (int argc, char **argv) { - int status, result; - lua_State *L = luaL_newstate(); /* create state */ - if (L == NULL) { - l_message(argv[0], "cannot create state: not enough memory"); - return EXIT_FAILURE; - } - /* call 'pmain' in protected mode */ - lua_pushcfunction(L, &pmain); - lua_pushinteger(L, argc); /* 1st argument */ - lua_pushlightuserdata(L, argv); /* 2nd argument */ - status = lua_pcall(L, 2, 1, 0); - result = lua_toboolean(L, -1); /* get result */ - finalreport(L, status); - lua_close(L); - return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE; +int main(int argc, char **argv) +{ + int status, result; + lua_State *L = luaL_newstate(); /* create state */ + if (L == NULL) + { + l_message(argv[0], "cannot create state: not enough memory"); + return EXIT_FAILURE; + } + /* call 'pmain' in protected mode */ + lua_pushcfunction(L, &pmain); + lua_pushinteger(L, argc); /* 1st argument */ + lua_pushlightuserdata(L, argv); /* 2nd argument */ + status = lua_pcall(L, 2, 1, 0); + result = lua_toboolean(L, -1); /* get result */ + finalreport(L, status); + lua_close(L); + return (result && status == LUA_OK) ? EXIT_SUCCESS : EXIT_FAILURE; } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lapi.c b/examples/ThirdPartyLibs/lua-5.2.3/src/lapi.c index d011431ea..e0f28119e 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lapi.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lapi.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #include #include @@ -27,1258 +26,1341 @@ #include "lundump.h" #include "lvm.h" - - const char lua_ident[] = - "$LuaVersion: " LUA_COPYRIGHT " $" - "$LuaAuthors: " LUA_AUTHORS " $"; - + "$LuaVersion: " LUA_COPYRIGHT + " $" + "$LuaAuthors: " LUA_AUTHORS " $"; /* value at a non-valid index */ -#define NONVALIDVALUE cast(TValue *, luaO_nilobject) +#define NONVALIDVALUE cast(TValue *, luaO_nilobject) /* corresponding test */ -#define isvalid(o) ((o) != luaO_nilobject) +#define isvalid(o) ((o) != luaO_nilobject) /* test for pseudo index */ -#define ispseudo(i) ((i) <= LUA_REGISTRYINDEX) +#define ispseudo(i) ((i) <= LUA_REGISTRYINDEX) /* test for valid but not pseudo index */ -#define isstackindex(i, o) (isvalid(o) && !ispseudo(i)) +#define isstackindex(i, o) (isvalid(o) && !ispseudo(i)) -#define api_checkvalidindex(L, o) api_check(L, isvalid(o), "invalid index") +#define api_checkvalidindex(L, o) api_check(L, isvalid(o), "invalid index") -#define api_checkstackindex(L, i, o) \ +#define api_checkstackindex(L, i, o) \ api_check(L, isstackindex(i, o), "index not in the stack") - -static TValue *index2addr (lua_State *L, int idx) { - CallInfo *ci = L->ci; - if (idx > 0) { - TValue *o = ci->func + idx; - api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index"); - if (o >= L->top) return NONVALIDVALUE; - else return o; - } - else if (!ispseudo(idx)) { /* negative index */ - api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); - return L->top + idx; - } - else if (idx == LUA_REGISTRYINDEX) - return &G(L)->l_registry; - else { /* upvalues */ - idx = LUA_REGISTRYINDEX - idx; - api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large"); - if (ttislcf(ci->func)) /* light C function? */ - return NONVALIDVALUE; /* it has no upvalues */ - else { - CClosure *func = clCvalue(ci->func); - return (idx <= func->nupvalues) ? &func->upvalue[idx-1] : NONVALIDVALUE; - } - } +static TValue *index2addr(lua_State *L, int idx) +{ + CallInfo *ci = L->ci; + if (idx > 0) + { + TValue *o = ci->func + idx; + api_check(L, idx <= ci->top - (ci->func + 1), "unacceptable index"); + if (o >= L->top) + return NONVALIDVALUE; + else + return o; + } + else if (!ispseudo(idx)) + { /* negative index */ + api_check(L, idx != 0 && -idx <= L->top - (ci->func + 1), "invalid index"); + return L->top + idx; + } + else if (idx == LUA_REGISTRYINDEX) + return &G(L)->l_registry; + else + { /* upvalues */ + idx = LUA_REGISTRYINDEX - idx; + api_check(L, idx <= MAXUPVAL + 1, "upvalue index too large"); + if (ttislcf(ci->func)) /* light C function? */ + return NONVALIDVALUE; /* it has no upvalues */ + else + { + CClosure *func = clCvalue(ci->func); + return (idx <= func->nupvalues) ? &func->upvalue[idx - 1] : NONVALIDVALUE; + } + } } - /* ** to be called by 'lua_checkstack' in protected mode, to grow stack ** capturing memory errors */ -static void growstack (lua_State *L, void *ud) { - int size = *(int *)ud; - luaD_growstack(L, size); +static void growstack(lua_State *L, void *ud) +{ + int size = *(int *)ud; + luaD_growstack(L, size); } - -LUA_API int lua_checkstack (lua_State *L, int size) { - int res; - CallInfo *ci = L->ci; - lua_lock(L); - if (L->stack_last - L->top > size) /* stack large enough? */ - res = 1; /* yes; check is OK */ - else { /* no; need to grow stack */ - int inuse = cast_int(L->top - L->stack) + EXTRA_STACK; - if (inuse > LUAI_MAXSTACK - size) /* can grow without overflow? */ - res = 0; /* no */ - else /* try to grow stack */ - res = (luaD_rawrunprotected(L, &growstack, &size) == LUA_OK); - } - if (res && ci->top < L->top + size) - ci->top = L->top + size; /* adjust frame top */ - lua_unlock(L); - return res; +LUA_API int lua_checkstack(lua_State *L, int size) +{ + int res; + CallInfo *ci = L->ci; + lua_lock(L); + if (L->stack_last - L->top > size) /* stack large enough? */ + res = 1; /* yes; check is OK */ + else + { /* no; need to grow stack */ + int inuse = cast_int(L->top - L->stack) + EXTRA_STACK; + if (inuse > LUAI_MAXSTACK - size) /* can grow without overflow? */ + res = 0; /* no */ + else /* try to grow stack */ + res = (luaD_rawrunprotected(L, &growstack, &size) == LUA_OK); + } + if (res && ci->top < L->top + size) + ci->top = L->top + size; /* adjust frame top */ + lua_unlock(L); + return res; } - -LUA_API void lua_xmove (lua_State *from, lua_State *to, int n) { - int i; - if (from == to) return; - lua_lock(to); - api_checknelems(from, n); - api_check(from, G(from) == G(to), "moving among independent states"); - api_check(from, to->ci->top - to->top >= n, "not enough elements to move"); - from->top -= n; - for (i = 0; i < n; i++) { - setobj2s(to, to->top++, from->top + i); - } - lua_unlock(to); +LUA_API void lua_xmove(lua_State *from, lua_State *to, int n) +{ + int i; + if (from == to) return; + lua_lock(to); + api_checknelems(from, n); + api_check(from, G(from) == G(to), "moving among independent states"); + api_check(from, to->ci->top - to->top >= n, "not enough elements to move"); + from->top -= n; + for (i = 0; i < n; i++) + { + setobj2s(to, to->top++, from->top + i); + } + lua_unlock(to); } - -LUA_API lua_CFunction lua_atpanic (lua_State *L, lua_CFunction panicf) { - lua_CFunction old; - lua_lock(L); - old = G(L)->panic; - G(L)->panic = panicf; - lua_unlock(L); - return old; +LUA_API lua_CFunction lua_atpanic(lua_State *L, lua_CFunction panicf) +{ + lua_CFunction old; + lua_lock(L); + old = G(L)->panic; + G(L)->panic = panicf; + lua_unlock(L); + return old; } - -LUA_API const lua_Number *lua_version (lua_State *L) { - static const lua_Number version = LUA_VERSION_NUM; - if (L == NULL) return &version; - else return G(L)->version; +LUA_API const lua_Number *lua_version(lua_State *L) +{ + static const lua_Number version = LUA_VERSION_NUM; + if (L == NULL) + return &version; + else + return G(L)->version; } - - /* ** basic stack manipulation */ - /* ** convert an acceptable stack index into an absolute index */ -LUA_API int lua_absindex (lua_State *L, int idx) { - return (idx > 0 || ispseudo(idx)) - ? idx - : cast_int(L->top - L->ci->func + idx); +LUA_API int lua_absindex(lua_State *L, int idx) +{ + return (idx > 0 || ispseudo(idx)) + ? idx + : cast_int(L->top - L->ci->func + idx); } - -LUA_API int lua_gettop (lua_State *L) { - return cast_int(L->top - (L->ci->func + 1)); +LUA_API int lua_gettop(lua_State *L) +{ + return cast_int(L->top - (L->ci->func + 1)); } - -LUA_API void lua_settop (lua_State *L, int idx) { - StkId func = L->ci->func; - lua_lock(L); - if (idx >= 0) { - api_check(L, idx <= L->stack_last - (func + 1), "new top too large"); - while (L->top < (func + 1) + idx) - setnilvalue(L->top++); - L->top = (func + 1) + idx; - } - else { - api_check(L, -(idx+1) <= (L->top - (func + 1)), "invalid new top"); - L->top += idx+1; /* `subtract' index (index is negative) */ - } - lua_unlock(L); +LUA_API void lua_settop(lua_State *L, int idx) +{ + StkId func = L->ci->func; + lua_lock(L); + if (idx >= 0) + { + api_check(L, idx <= L->stack_last - (func + 1), "new top too large"); + while (L->top < (func + 1) + idx) + setnilvalue(L->top++); + L->top = (func + 1) + idx; + } + else + { + api_check(L, -(idx + 1) <= (L->top - (func + 1)), "invalid new top"); + L->top += idx + 1; /* `subtract' index (index is negative) */ + } + lua_unlock(L); } - -LUA_API void lua_remove (lua_State *L, int idx) { - StkId p; - lua_lock(L); - p = index2addr(L, idx); - api_checkstackindex(L, idx, p); - while (++p < L->top) setobjs2s(L, p-1, p); - L->top--; - lua_unlock(L); +LUA_API void lua_remove(lua_State *L, int idx) +{ + StkId p; + lua_lock(L); + p = index2addr(L, idx); + api_checkstackindex(L, idx, p); + while (++p < L->top) setobjs2s(L, p - 1, p); + L->top--; + lua_unlock(L); } - -LUA_API void lua_insert (lua_State *L, int idx) { - StkId p; - StkId q; - lua_lock(L); - p = index2addr(L, idx); - api_checkstackindex(L, idx, p); - for (q = L->top; q > p; q--) /* use L->top as a temporary */ - setobjs2s(L, q, q - 1); - setobjs2s(L, p, L->top); - lua_unlock(L); +LUA_API void lua_insert(lua_State *L, int idx) +{ + StkId p; + StkId q; + lua_lock(L); + p = index2addr(L, idx); + api_checkstackindex(L, idx, p); + for (q = L->top; q > p; q--) /* use L->top as a temporary */ + setobjs2s(L, q, q - 1); + setobjs2s(L, p, L->top); + lua_unlock(L); } - -static void moveto (lua_State *L, TValue *fr, int idx) { - TValue *to = index2addr(L, idx); - api_checkvalidindex(L, to); - setobj(L, to, fr); - if (idx < LUA_REGISTRYINDEX) /* function upvalue? */ - luaC_barrier(L, clCvalue(L->ci->func), fr); - /* LUA_REGISTRYINDEX does not need gc barrier +static void moveto(lua_State *L, TValue *fr, int idx) +{ + TValue *to = index2addr(L, idx); + api_checkvalidindex(L, to); + setobj(L, to, fr); + if (idx < LUA_REGISTRYINDEX) /* function upvalue? */ + luaC_barrier(L, clCvalue(L->ci->func), fr); + /* LUA_REGISTRYINDEX does not need gc barrier (collector revisits it before finishing collection) */ } - -LUA_API void lua_replace (lua_State *L, int idx) { - lua_lock(L); - api_checknelems(L, 1); - moveto(L, L->top - 1, idx); - L->top--; - lua_unlock(L); +LUA_API void lua_replace(lua_State *L, int idx) +{ + lua_lock(L); + api_checknelems(L, 1); + moveto(L, L->top - 1, idx); + L->top--; + lua_unlock(L); } - -LUA_API void lua_copy (lua_State *L, int fromidx, int toidx) { - TValue *fr; - lua_lock(L); - fr = index2addr(L, fromidx); - moveto(L, fr, toidx); - lua_unlock(L); +LUA_API void lua_copy(lua_State *L, int fromidx, int toidx) +{ + TValue *fr; + lua_lock(L); + fr = index2addr(L, fromidx); + moveto(L, fr, toidx); + lua_unlock(L); } - -LUA_API void lua_pushvalue (lua_State *L, int idx) { - lua_lock(L); - setobj2s(L, L->top, index2addr(L, idx)); - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_pushvalue(lua_State *L, int idx) +{ + lua_lock(L); + setobj2s(L, L->top, index2addr(L, idx)); + api_incr_top(L); + lua_unlock(L); } - - /* ** access functions (stack -> C) */ - -LUA_API int lua_type (lua_State *L, int idx) { - StkId o = index2addr(L, idx); - return (isvalid(o) ? ttypenv(o) : LUA_TNONE); +LUA_API int lua_type(lua_State *L, int idx) +{ + StkId o = index2addr(L, idx); + return (isvalid(o) ? ttypenv(o) : LUA_TNONE); } - -LUA_API const char *lua_typename (lua_State *L, int t) { - UNUSED(L); - return ttypename(t); +LUA_API const char *lua_typename(lua_State *L, int t) +{ + UNUSED(L); + return ttypename(t); } - -LUA_API int lua_iscfunction (lua_State *L, int idx) { - StkId o = index2addr(L, idx); - return (ttislcf(o) || (ttisCclosure(o))); +LUA_API int lua_iscfunction(lua_State *L, int idx) +{ + StkId o = index2addr(L, idx); + return (ttislcf(o) || (ttisCclosure(o))); } - -LUA_API int lua_isnumber (lua_State *L, int idx) { - TValue n; - const TValue *o = index2addr(L, idx); - return tonumber(o, &n); +LUA_API int lua_isnumber(lua_State *L, int idx) +{ + TValue n; + const TValue *o = index2addr(L, idx); + return tonumber(o, &n); } - -LUA_API int lua_isstring (lua_State *L, int idx) { - int t = lua_type(L, idx); - return (t == LUA_TSTRING || t == LUA_TNUMBER); +LUA_API int lua_isstring(lua_State *L, int idx) +{ + int t = lua_type(L, idx); + return (t == LUA_TSTRING || t == LUA_TNUMBER); } - -LUA_API int lua_isuserdata (lua_State *L, int idx) { - const TValue *o = index2addr(L, idx); - return (ttisuserdata(o) || ttislightuserdata(o)); +LUA_API int lua_isuserdata(lua_State *L, int idx) +{ + const TValue *o = index2addr(L, idx); + return (ttisuserdata(o) || ttislightuserdata(o)); } - -LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { - StkId o1 = index2addr(L, index1); - StkId o2 = index2addr(L, index2); - return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0; +LUA_API int lua_rawequal(lua_State *L, int index1, int index2) +{ + StkId o1 = index2addr(L, index1); + StkId o2 = index2addr(L, index2); + return (isvalid(o1) && isvalid(o2)) ? luaV_rawequalobj(o1, o2) : 0; } - -LUA_API void lua_arith (lua_State *L, int op) { - StkId o1; /* 1st operand */ - StkId o2; /* 2nd operand */ - lua_lock(L); - if (op != LUA_OPUNM) /* all other operations expect two operands */ - api_checknelems(L, 2); - else { /* for unary minus, add fake 2nd operand */ - api_checknelems(L, 1); - setobjs2s(L, L->top, L->top - 1); - L->top++; - } - o1 = L->top - 2; - o2 = L->top - 1; - if (ttisnumber(o1) && ttisnumber(o2)) { - setnvalue(o1, luaO_arith(op, nvalue(o1), nvalue(o2))); - } - else - luaV_arith(L, o1, o1, o2, cast(TMS, op - LUA_OPADD + TM_ADD)); - L->top--; - lua_unlock(L); +LUA_API void lua_arith(lua_State *L, int op) +{ + StkId o1; /* 1st operand */ + StkId o2; /* 2nd operand */ + lua_lock(L); + if (op != LUA_OPUNM) /* all other operations expect two operands */ + api_checknelems(L, 2); + else + { /* for unary minus, add fake 2nd operand */ + api_checknelems(L, 1); + setobjs2s(L, L->top, L->top - 1); + L->top++; + } + o1 = L->top - 2; + o2 = L->top - 1; + if (ttisnumber(o1) && ttisnumber(o2)) + { + setnvalue(o1, luaO_arith(op, nvalue(o1), nvalue(o2))); + } + else + luaV_arith(L, o1, o1, o2, cast(TMS, op - LUA_OPADD + TM_ADD)); + L->top--; + lua_unlock(L); } - -LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) { - StkId o1, o2; - int i = 0; - lua_lock(L); /* may call tag method */ - o1 = index2addr(L, index1); - o2 = index2addr(L, index2); - if (isvalid(o1) && isvalid(o2)) { - switch (op) { - case LUA_OPEQ: i = equalobj(L, o1, o2); break; - case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break; - case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break; - default: api_check(L, 0, "invalid option"); - } - } - lua_unlock(L); - return i; +LUA_API int lua_compare(lua_State *L, int index1, int index2, int op) +{ + StkId o1, o2; + int i = 0; + lua_lock(L); /* may call tag method */ + o1 = index2addr(L, index1); + o2 = index2addr(L, index2); + if (isvalid(o1) && isvalid(o2)) + { + switch (op) + { + case LUA_OPEQ: + i = equalobj(L, o1, o2); + break; + case LUA_OPLT: + i = luaV_lessthan(L, o1, o2); + break; + case LUA_OPLE: + i = luaV_lessequal(L, o1, o2); + break; + default: + api_check(L, 0, "invalid option"); + } + } + lua_unlock(L); + return i; } - -LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum) { - TValue n; - const TValue *o = index2addr(L, idx); - if (tonumber(o, &n)) { - if (isnum) *isnum = 1; - return nvalue(o); - } - else { - if (isnum) *isnum = 0; - return 0; - } +LUA_API lua_Number lua_tonumberx(lua_State *L, int idx, int *isnum) +{ + TValue n; + const TValue *o = index2addr(L, idx); + if (tonumber(o, &n)) + { + if (isnum) *isnum = 1; + return nvalue(o); + } + else + { + if (isnum) *isnum = 0; + return 0; + } } - -LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) { - TValue n; - const TValue *o = index2addr(L, idx); - if (tonumber(o, &n)) { - lua_Integer res; - lua_Number num = nvalue(o); - lua_number2integer(res, num); - if (isnum) *isnum = 1; - return res; - } - else { - if (isnum) *isnum = 0; - return 0; - } +LUA_API lua_Integer lua_tointegerx(lua_State *L, int idx, int *isnum) +{ + TValue n; + const TValue *o = index2addr(L, idx); + if (tonumber(o, &n)) + { + lua_Integer res; + lua_Number num = nvalue(o); + lua_number2integer(res, num); + if (isnum) *isnum = 1; + return res; + } + else + { + if (isnum) *isnum = 0; + return 0; + } } - -LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *isnum) { - TValue n; - const TValue *o = index2addr(L, idx); - if (tonumber(o, &n)) { - lua_Unsigned res; - lua_Number num = nvalue(o); - lua_number2unsigned(res, num); - if (isnum) *isnum = 1; - return res; - } - else { - if (isnum) *isnum = 0; - return 0; - } +LUA_API lua_Unsigned lua_tounsignedx(lua_State *L, int idx, int *isnum) +{ + TValue n; + const TValue *o = index2addr(L, idx); + if (tonumber(o, &n)) + { + lua_Unsigned res; + lua_Number num = nvalue(o); + lua_number2unsigned(res, num); + if (isnum) *isnum = 1; + return res; + } + else + { + if (isnum) *isnum = 0; + return 0; + } } - -LUA_API int lua_toboolean (lua_State *L, int idx) { - const TValue *o = index2addr(L, idx); - return !l_isfalse(o); +LUA_API int lua_toboolean(lua_State *L, int idx) +{ + const TValue *o = index2addr(L, idx); + return !l_isfalse(o); } - -LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) { - StkId o = index2addr(L, idx); - if (!ttisstring(o)) { - lua_lock(L); /* `luaV_tostring' may create a new string */ - if (!luaV_tostring(L, o)) { /* conversion failed? */ - if (len != NULL) *len = 0; - lua_unlock(L); - return NULL; - } - luaC_checkGC(L); - o = index2addr(L, idx); /* previous call may reallocate the stack */ - lua_unlock(L); - } - if (len != NULL) *len = tsvalue(o)->len; - return svalue(o); +LUA_API const char *lua_tolstring(lua_State *L, int idx, size_t *len) +{ + StkId o = index2addr(L, idx); + if (!ttisstring(o)) + { + lua_lock(L); /* `luaV_tostring' may create a new string */ + if (!luaV_tostring(L, o)) + { /* conversion failed? */ + if (len != NULL) *len = 0; + lua_unlock(L); + return NULL; + } + luaC_checkGC(L); + o = index2addr(L, idx); /* previous call may reallocate the stack */ + lua_unlock(L); + } + if (len != NULL) *len = tsvalue(o)->len; + return svalue(o); } - -LUA_API size_t lua_rawlen (lua_State *L, int idx) { - StkId o = index2addr(L, idx); - switch (ttypenv(o)) { - case LUA_TSTRING: return tsvalue(o)->len; - case LUA_TUSERDATA: return uvalue(o)->len; - case LUA_TTABLE: return luaH_getn(hvalue(o)); - default: return 0; - } +LUA_API size_t lua_rawlen(lua_State *L, int idx) +{ + StkId o = index2addr(L, idx); + switch (ttypenv(o)) + { + case LUA_TSTRING: + return tsvalue(o)->len; + case LUA_TUSERDATA: + return uvalue(o)->len; + case LUA_TTABLE: + return luaH_getn(hvalue(o)); + default: + return 0; + } } - -LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) { - StkId o = index2addr(L, idx); - if (ttislcf(o)) return fvalue(o); - else if (ttisCclosure(o)) - return clCvalue(o)->f; - else return NULL; /* not a C function */ +LUA_API lua_CFunction lua_tocfunction(lua_State *L, int idx) +{ + StkId o = index2addr(L, idx); + if (ttislcf(o)) + return fvalue(o); + else if (ttisCclosure(o)) + return clCvalue(o)->f; + else + return NULL; /* not a C function */ } - -LUA_API void *lua_touserdata (lua_State *L, int idx) { - StkId o = index2addr(L, idx); - switch (ttypenv(o)) { - case LUA_TUSERDATA: return (rawuvalue(o) + 1); - case LUA_TLIGHTUSERDATA: return pvalue(o); - default: return NULL; - } +LUA_API void *lua_touserdata(lua_State *L, int idx) +{ + StkId o = index2addr(L, idx); + switch (ttypenv(o)) + { + case LUA_TUSERDATA: + return (rawuvalue(o) + 1); + case LUA_TLIGHTUSERDATA: + return pvalue(o); + default: + return NULL; + } } - -LUA_API lua_State *lua_tothread (lua_State *L, int idx) { - StkId o = index2addr(L, idx); - return (!ttisthread(o)) ? NULL : thvalue(o); +LUA_API lua_State *lua_tothread(lua_State *L, int idx) +{ + StkId o = index2addr(L, idx); + return (!ttisthread(o)) ? NULL : thvalue(o); } - -LUA_API const void *lua_topointer (lua_State *L, int idx) { - StkId o = index2addr(L, idx); - switch (ttype(o)) { - case LUA_TTABLE: return hvalue(o); - case LUA_TLCL: return clLvalue(o); - case LUA_TCCL: return clCvalue(o); - case LUA_TLCF: return cast(void *, cast(size_t, fvalue(o))); - case LUA_TTHREAD: return thvalue(o); - case LUA_TUSERDATA: - case LUA_TLIGHTUSERDATA: - return lua_touserdata(L, idx); - default: return NULL; - } +LUA_API const void *lua_topointer(lua_State *L, int idx) +{ + StkId o = index2addr(L, idx); + switch (ttype(o)) + { + case LUA_TTABLE: + return hvalue(o); + case LUA_TLCL: + return clLvalue(o); + case LUA_TCCL: + return clCvalue(o); + case LUA_TLCF: + return cast(void *, cast(size_t, fvalue(o))); + case LUA_TTHREAD: + return thvalue(o); + case LUA_TUSERDATA: + case LUA_TLIGHTUSERDATA: + return lua_touserdata(L, idx); + default: + return NULL; + } } - - /* ** push functions (C -> stack) */ - -LUA_API void lua_pushnil (lua_State *L) { - lua_lock(L); - setnilvalue(L->top); - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_pushnil(lua_State *L) +{ + lua_lock(L); + setnilvalue(L->top); + api_incr_top(L); + lua_unlock(L); } - -LUA_API void lua_pushnumber (lua_State *L, lua_Number n) { - lua_lock(L); - setnvalue(L->top, n); - luai_checknum(L, L->top, - luaG_runerror(L, "C API - attempt to push a signaling NaN")); - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_pushnumber(lua_State *L, lua_Number n) +{ + lua_lock(L); + setnvalue(L->top, n); + luai_checknum(L, L->top, + luaG_runerror(L, "C API - attempt to push a signaling NaN")); + api_incr_top(L); + lua_unlock(L); } - -LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) { - lua_lock(L); - setnvalue(L->top, cast_num(n)); - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_pushinteger(lua_State *L, lua_Integer n) +{ + lua_lock(L); + setnvalue(L->top, cast_num(n)); + api_incr_top(L); + lua_unlock(L); } - -LUA_API void lua_pushunsigned (lua_State *L, lua_Unsigned u) { - lua_Number n; - lua_lock(L); - n = lua_unsigned2number(u); - setnvalue(L->top, n); - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_pushunsigned(lua_State *L, lua_Unsigned u) +{ + lua_Number n; + lua_lock(L); + n = lua_unsigned2number(u); + setnvalue(L->top, n); + api_incr_top(L); + lua_unlock(L); } - -LUA_API const char *lua_pushlstring (lua_State *L, const char *s, size_t len) { - TString *ts; - lua_lock(L); - luaC_checkGC(L); - ts = luaS_newlstr(L, s, len); - setsvalue2s(L, L->top, ts); - api_incr_top(L); - lua_unlock(L); - return getstr(ts); +LUA_API const char *lua_pushlstring(lua_State *L, const char *s, size_t len) +{ + TString *ts; + lua_lock(L); + luaC_checkGC(L); + ts = luaS_newlstr(L, s, len); + setsvalue2s(L, L->top, ts); + api_incr_top(L); + lua_unlock(L); + return getstr(ts); } - -LUA_API const char *lua_pushstring (lua_State *L, const char *s) { - if (s == NULL) { - lua_pushnil(L); - return NULL; - } - else { - TString *ts; - lua_lock(L); - luaC_checkGC(L); - ts = luaS_new(L, s); - setsvalue2s(L, L->top, ts); - api_incr_top(L); - lua_unlock(L); - return getstr(ts); - } +LUA_API const char *lua_pushstring(lua_State *L, const char *s) +{ + if (s == NULL) + { + lua_pushnil(L); + return NULL; + } + else + { + TString *ts; + lua_lock(L); + luaC_checkGC(L); + ts = luaS_new(L, s); + setsvalue2s(L, L->top, ts); + api_incr_top(L); + lua_unlock(L); + return getstr(ts); + } } - -LUA_API const char *lua_pushvfstring (lua_State *L, const char *fmt, - va_list argp) { - const char *ret; - lua_lock(L); - luaC_checkGC(L); - ret = luaO_pushvfstring(L, fmt, argp); - lua_unlock(L); - return ret; +LUA_API const char *lua_pushvfstring(lua_State *L, const char *fmt, + va_list argp) +{ + const char *ret; + lua_lock(L); + luaC_checkGC(L); + ret = luaO_pushvfstring(L, fmt, argp); + lua_unlock(L); + return ret; } - -LUA_API const char *lua_pushfstring (lua_State *L, const char *fmt, ...) { - const char *ret; - va_list argp; - lua_lock(L); - luaC_checkGC(L); - va_start(argp, fmt); - ret = luaO_pushvfstring(L, fmt, argp); - va_end(argp); - lua_unlock(L); - return ret; +LUA_API const char *lua_pushfstring(lua_State *L, const char *fmt, ...) +{ + const char *ret; + va_list argp; + lua_lock(L); + luaC_checkGC(L); + va_start(argp, fmt); + ret = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + lua_unlock(L); + return ret; } - -LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { - lua_lock(L); - if (n == 0) { - setfvalue(L->top, fn); - } - else { - Closure *cl; - api_checknelems(L, n); - api_check(L, n <= MAXUPVAL, "upvalue index too large"); - luaC_checkGC(L); - cl = luaF_newCclosure(L, n); - cl->c.f = fn; - L->top -= n; - while (n--) - setobj2n(L, &cl->c.upvalue[n], L->top + n); - setclCvalue(L, L->top, cl); - } - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_pushcclosure(lua_State *L, lua_CFunction fn, int n) +{ + lua_lock(L); + if (n == 0) + { + setfvalue(L->top, fn); + } + else + { + Closure *cl; + api_checknelems(L, n); + api_check(L, n <= MAXUPVAL, "upvalue index too large"); + luaC_checkGC(L); + cl = luaF_newCclosure(L, n); + cl->c.f = fn; + L->top -= n; + while (n--) + setobj2n(L, &cl->c.upvalue[n], L->top + n); + setclCvalue(L, L->top, cl); + } + api_incr_top(L); + lua_unlock(L); } - -LUA_API void lua_pushboolean (lua_State *L, int b) { - lua_lock(L); - setbvalue(L->top, (b != 0)); /* ensure that true is 1 */ - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_pushboolean(lua_State *L, int b) +{ + lua_lock(L); + setbvalue(L->top, (b != 0)); /* ensure that true is 1 */ + api_incr_top(L); + lua_unlock(L); } - -LUA_API void lua_pushlightuserdata (lua_State *L, void *p) { - lua_lock(L); - setpvalue(L->top, p); - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_pushlightuserdata(lua_State *L, void *p) +{ + lua_lock(L); + setpvalue(L->top, p); + api_incr_top(L); + lua_unlock(L); } - -LUA_API int lua_pushthread (lua_State *L) { - lua_lock(L); - setthvalue(L, L->top, L); - api_incr_top(L); - lua_unlock(L); - return (G(L)->mainthread == L); +LUA_API int lua_pushthread(lua_State *L) +{ + lua_lock(L); + setthvalue(L, L->top, L); + api_incr_top(L); + lua_unlock(L); + return (G(L)->mainthread == L); } - - /* ** get functions (Lua -> stack) */ - -LUA_API void lua_getglobal (lua_State *L, const char *var) { - Table *reg = hvalue(&G(L)->l_registry); - const TValue *gt; /* global table */ - lua_lock(L); - gt = luaH_getint(reg, LUA_RIDX_GLOBALS); - setsvalue2s(L, L->top++, luaS_new(L, var)); - luaV_gettable(L, gt, L->top - 1, L->top - 1); - lua_unlock(L); +LUA_API void lua_getglobal(lua_State *L, const char *var) +{ + Table *reg = hvalue(&G(L)->l_registry); + const TValue *gt; /* global table */ + lua_lock(L); + gt = luaH_getint(reg, LUA_RIDX_GLOBALS); + setsvalue2s(L, L->top++, luaS_new(L, var)); + luaV_gettable(L, gt, L->top - 1, L->top - 1); + lua_unlock(L); } - -LUA_API void lua_gettable (lua_State *L, int idx) { - StkId t; - lua_lock(L); - t = index2addr(L, idx); - luaV_gettable(L, t, L->top - 1, L->top - 1); - lua_unlock(L); +LUA_API void lua_gettable(lua_State *L, int idx) +{ + StkId t; + lua_lock(L); + t = index2addr(L, idx); + luaV_gettable(L, t, L->top - 1, L->top - 1); + lua_unlock(L); } - -LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { - StkId t; - lua_lock(L); - t = index2addr(L, idx); - setsvalue2s(L, L->top, luaS_new(L, k)); - api_incr_top(L); - luaV_gettable(L, t, L->top - 1, L->top - 1); - lua_unlock(L); +LUA_API void lua_getfield(lua_State *L, int idx, const char *k) +{ + StkId t; + lua_lock(L); + t = index2addr(L, idx); + setsvalue2s(L, L->top, luaS_new(L, k)); + api_incr_top(L); + luaV_gettable(L, t, L->top - 1, L->top - 1); + lua_unlock(L); } - -LUA_API void lua_rawget (lua_State *L, int idx) { - StkId t; - lua_lock(L); - t = index2addr(L, idx); - api_check(L, ttistable(t), "table expected"); - setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); - lua_unlock(L); +LUA_API void lua_rawget(lua_State *L, int idx) +{ + StkId t; + lua_lock(L); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1)); + lua_unlock(L); } - -LUA_API void lua_rawgeti (lua_State *L, int idx, int n) { - StkId t; - lua_lock(L); - t = index2addr(L, idx); - api_check(L, ttistable(t), "table expected"); - setobj2s(L, L->top, luaH_getint(hvalue(t), n)); - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_rawgeti(lua_State *L, int idx, int n) +{ + StkId t; + lua_lock(L); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setobj2s(L, L->top, luaH_getint(hvalue(t), n)); + api_incr_top(L); + lua_unlock(L); } - -LUA_API void lua_rawgetp (lua_State *L, int idx, const void *p) { - StkId t; - TValue k; - lua_lock(L); - t = index2addr(L, idx); - api_check(L, ttistable(t), "table expected"); - setpvalue(&k, cast(void *, p)); - setobj2s(L, L->top, luaH_get(hvalue(t), &k)); - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_rawgetp(lua_State *L, int idx, const void *p) +{ + StkId t; + TValue k; + lua_lock(L); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setpvalue(&k, cast(void *, p)); + setobj2s(L, L->top, luaH_get(hvalue(t), &k)); + api_incr_top(L); + lua_unlock(L); } - -LUA_API void lua_createtable (lua_State *L, int narray, int nrec) { - Table *t; - lua_lock(L); - luaC_checkGC(L); - t = luaH_new(L); - sethvalue(L, L->top, t); - api_incr_top(L); - if (narray > 0 || nrec > 0) - luaH_resize(L, t, narray, nrec); - lua_unlock(L); +LUA_API void lua_createtable(lua_State *L, int narray, int nrec) +{ + Table *t; + lua_lock(L); + luaC_checkGC(L); + t = luaH_new(L); + sethvalue(L, L->top, t); + api_incr_top(L); + if (narray > 0 || nrec > 0) + luaH_resize(L, t, narray, nrec); + lua_unlock(L); } - -LUA_API int lua_getmetatable (lua_State *L, int objindex) { - const TValue *obj; - Table *mt = NULL; - int res; - lua_lock(L); - obj = index2addr(L, objindex); - switch (ttypenv(obj)) { - case LUA_TTABLE: - mt = hvalue(obj)->metatable; - break; - case LUA_TUSERDATA: - mt = uvalue(obj)->metatable; - break; - default: - mt = G(L)->mt[ttypenv(obj)]; - break; - } - if (mt == NULL) - res = 0; - else { - sethvalue(L, L->top, mt); - api_incr_top(L); - res = 1; - } - lua_unlock(L); - return res; +LUA_API int lua_getmetatable(lua_State *L, int objindex) +{ + const TValue *obj; + Table *mt = NULL; + int res; + lua_lock(L); + obj = index2addr(L, objindex); + switch (ttypenv(obj)) + { + case LUA_TTABLE: + mt = hvalue(obj)->metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(obj)->metatable; + break; + default: + mt = G(L)->mt[ttypenv(obj)]; + break; + } + if (mt == NULL) + res = 0; + else + { + sethvalue(L, L->top, mt); + api_incr_top(L); + res = 1; + } + lua_unlock(L); + return res; } - -LUA_API void lua_getuservalue (lua_State *L, int idx) { - StkId o; - lua_lock(L); - o = index2addr(L, idx); - api_check(L, ttisuserdata(o), "userdata expected"); - if (uvalue(o)->env) { - sethvalue(L, L->top, uvalue(o)->env); - } else - setnilvalue(L->top); - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_getuservalue(lua_State *L, int idx) +{ + StkId o; + lua_lock(L); + o = index2addr(L, idx); + api_check(L, ttisuserdata(o), "userdata expected"); + if (uvalue(o)->env) + { + sethvalue(L, L->top, uvalue(o)->env); + } + else + setnilvalue(L->top); + api_incr_top(L); + lua_unlock(L); } - /* ** set functions (stack -> Lua) */ - -LUA_API void lua_setglobal (lua_State *L, const char *var) { - Table *reg = hvalue(&G(L)->l_registry); - const TValue *gt; /* global table */ - lua_lock(L); - api_checknelems(L, 1); - gt = luaH_getint(reg, LUA_RIDX_GLOBALS); - setsvalue2s(L, L->top++, luaS_new(L, var)); - luaV_settable(L, gt, L->top - 1, L->top - 2); - L->top -= 2; /* pop value and key */ - lua_unlock(L); +LUA_API void lua_setglobal(lua_State *L, const char *var) +{ + Table *reg = hvalue(&G(L)->l_registry); + const TValue *gt; /* global table */ + lua_lock(L); + api_checknelems(L, 1); + gt = luaH_getint(reg, LUA_RIDX_GLOBALS); + setsvalue2s(L, L->top++, luaS_new(L, var)); + luaV_settable(L, gt, L->top - 1, L->top - 2); + L->top -= 2; /* pop value and key */ + lua_unlock(L); } - -LUA_API void lua_settable (lua_State *L, int idx) { - StkId t; - lua_lock(L); - api_checknelems(L, 2); - t = index2addr(L, idx); - luaV_settable(L, t, L->top - 2, L->top - 1); - L->top -= 2; /* pop index and value */ - lua_unlock(L); +LUA_API void lua_settable(lua_State *L, int idx) +{ + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = index2addr(L, idx); + luaV_settable(L, t, L->top - 2, L->top - 1); + L->top -= 2; /* pop index and value */ + lua_unlock(L); } - -LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { - StkId t; - lua_lock(L); - api_checknelems(L, 1); - t = index2addr(L, idx); - setsvalue2s(L, L->top++, luaS_new(L, k)); - luaV_settable(L, t, L->top - 1, L->top - 2); - L->top -= 2; /* pop value and key */ - lua_unlock(L); +LUA_API void lua_setfield(lua_State *L, int idx, const char *k) +{ + StkId t; + lua_lock(L); + api_checknelems(L, 1); + t = index2addr(L, idx); + setsvalue2s(L, L->top++, luaS_new(L, k)); + luaV_settable(L, t, L->top - 1, L->top - 2); + L->top -= 2; /* pop value and key */ + lua_unlock(L); } - -LUA_API void lua_rawset (lua_State *L, int idx) { - StkId t; - lua_lock(L); - api_checknelems(L, 2); - t = index2addr(L, idx); - api_check(L, ttistable(t), "table expected"); - setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1); - invalidateTMcache(hvalue(t)); - luaC_barrierback(L, gcvalue(t), L->top-1); - L->top -= 2; - lua_unlock(L); +LUA_API void lua_rawset(lua_State *L, int idx) +{ + StkId t; + lua_lock(L); + api_checknelems(L, 2); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setobj2t(L, luaH_set(L, hvalue(t), L->top - 2), L->top - 1); + invalidateTMcache(hvalue(t)); + luaC_barrierback(L, gcvalue(t), L->top - 1); + L->top -= 2; + lua_unlock(L); } - -LUA_API void lua_rawseti (lua_State *L, int idx, int n) { - StkId t; - lua_lock(L); - api_checknelems(L, 1); - t = index2addr(L, idx); - api_check(L, ttistable(t), "table expected"); - luaH_setint(L, hvalue(t), n, L->top - 1); - luaC_barrierback(L, gcvalue(t), L->top-1); - L->top--; - lua_unlock(L); +LUA_API void lua_rawseti(lua_State *L, int idx, int n) +{ + StkId t; + lua_lock(L); + api_checknelems(L, 1); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + luaH_setint(L, hvalue(t), n, L->top - 1); + luaC_barrierback(L, gcvalue(t), L->top - 1); + L->top--; + lua_unlock(L); } - -LUA_API void lua_rawsetp (lua_State *L, int idx, const void *p) { - StkId t; - TValue k; - lua_lock(L); - api_checknelems(L, 1); - t = index2addr(L, idx); - api_check(L, ttistable(t), "table expected"); - setpvalue(&k, cast(void *, p)); - setobj2t(L, luaH_set(L, hvalue(t), &k), L->top - 1); - luaC_barrierback(L, gcvalue(t), L->top - 1); - L->top--; - lua_unlock(L); +LUA_API void lua_rawsetp(lua_State *L, int idx, const void *p) +{ + StkId t; + TValue k; + lua_lock(L); + api_checknelems(L, 1); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + setpvalue(&k, cast(void *, p)); + setobj2t(L, luaH_set(L, hvalue(t), &k), L->top - 1); + luaC_barrierback(L, gcvalue(t), L->top - 1); + L->top--; + lua_unlock(L); } - -LUA_API int lua_setmetatable (lua_State *L, int objindex) { - TValue *obj; - Table *mt; - lua_lock(L); - api_checknelems(L, 1); - obj = index2addr(L, objindex); - if (ttisnil(L->top - 1)) - mt = NULL; - else { - api_check(L, ttistable(L->top - 1), "table expected"); - mt = hvalue(L->top - 1); - } - switch (ttypenv(obj)) { - case LUA_TTABLE: { - hvalue(obj)->metatable = mt; - if (mt) { - luaC_objbarrierback(L, gcvalue(obj), mt); - luaC_checkfinalizer(L, gcvalue(obj), mt); - } - break; - } - case LUA_TUSERDATA: { - uvalue(obj)->metatable = mt; - if (mt) { - luaC_objbarrier(L, rawuvalue(obj), mt); - luaC_checkfinalizer(L, gcvalue(obj), mt); - } - break; - } - default: { - G(L)->mt[ttypenv(obj)] = mt; - break; - } - } - L->top--; - lua_unlock(L); - return 1; +LUA_API int lua_setmetatable(lua_State *L, int objindex) +{ + TValue *obj; + Table *mt; + lua_lock(L); + api_checknelems(L, 1); + obj = index2addr(L, objindex); + if (ttisnil(L->top - 1)) + mt = NULL; + else + { + api_check(L, ttistable(L->top - 1), "table expected"); + mt = hvalue(L->top - 1); + } + switch (ttypenv(obj)) + { + case LUA_TTABLE: + { + hvalue(obj)->metatable = mt; + if (mt) + { + luaC_objbarrierback(L, gcvalue(obj), mt); + luaC_checkfinalizer(L, gcvalue(obj), mt); + } + break; + } + case LUA_TUSERDATA: + { + uvalue(obj)->metatable = mt; + if (mt) + { + luaC_objbarrier(L, rawuvalue(obj), mt); + luaC_checkfinalizer(L, gcvalue(obj), mt); + } + break; + } + default: + { + G(L)->mt[ttypenv(obj)] = mt; + break; + } + } + L->top--; + lua_unlock(L); + return 1; } - -LUA_API void lua_setuservalue (lua_State *L, int idx) { - StkId o; - lua_lock(L); - api_checknelems(L, 1); - o = index2addr(L, idx); - api_check(L, ttisuserdata(o), "userdata expected"); - if (ttisnil(L->top - 1)) - uvalue(o)->env = NULL; - else { - api_check(L, ttistable(L->top - 1), "table expected"); - uvalue(o)->env = hvalue(L->top - 1); - luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); - } - L->top--; - lua_unlock(L); +LUA_API void lua_setuservalue(lua_State *L, int idx) +{ + StkId o; + lua_lock(L); + api_checknelems(L, 1); + o = index2addr(L, idx); + api_check(L, ttisuserdata(o), "userdata expected"); + if (ttisnil(L->top - 1)) + uvalue(o)->env = NULL; + else + { + api_check(L, ttistable(L->top - 1), "table expected"); + uvalue(o)->env = hvalue(L->top - 1); + luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1)); + } + L->top--; + lua_unlock(L); } - /* ** `load' and `call' functions (run Lua code) */ +#define checkresults(L, na, nr) \ + api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \ + "results from function overflow current stack size") -#define checkresults(L,na,nr) \ - api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na)), \ - "results from function overflow current stack size") - - -LUA_API int lua_getctx (lua_State *L, int *ctx) { - if (L->ci->callstatus & CIST_YIELDED) { - if (ctx) *ctx = L->ci->u.c.ctx; - return L->ci->u.c.status; - } - else return LUA_OK; +LUA_API int lua_getctx(lua_State *L, int *ctx) +{ + if (L->ci->callstatus & CIST_YIELDED) + { + if (ctx) *ctx = L->ci->u.c.ctx; + return L->ci->u.c.status; + } + else + return LUA_OK; } - -LUA_API void lua_callk (lua_State *L, int nargs, int nresults, int ctx, - lua_CFunction k) { - StkId func; - lua_lock(L); - api_check(L, k == NULL || !isLua(L->ci), - "cannot use continuations inside hooks"); - api_checknelems(L, nargs+1); - api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); - checkresults(L, nargs, nresults); - func = L->top - (nargs+1); - if (k != NULL && L->nny == 0) { /* need to prepare continuation? */ - L->ci->u.c.k = k; /* save continuation */ - L->ci->u.c.ctx = ctx; /* save context */ - luaD_call(L, func, nresults, 1); /* do the call */ - } - else /* no continuation or no yieldable */ - luaD_call(L, func, nresults, 0); /* just do the call */ - adjustresults(L, nresults); - lua_unlock(L); +LUA_API void lua_callk(lua_State *L, int nargs, int nresults, int ctx, + lua_CFunction k) +{ + StkId func; + lua_lock(L); + api_check(L, k == NULL || !isLua(L->ci), + "cannot use continuations inside hooks"); + api_checknelems(L, nargs + 1); + api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); + checkresults(L, nargs, nresults); + func = L->top - (nargs + 1); + if (k != NULL && L->nny == 0) + { /* need to prepare continuation? */ + L->ci->u.c.k = k; /* save continuation */ + L->ci->u.c.ctx = ctx; /* save context */ + luaD_call(L, func, nresults, 1); /* do the call */ + } + else /* no continuation or no yieldable */ + luaD_call(L, func, nresults, 0); /* just do the call */ + adjustresults(L, nresults); + lua_unlock(L); } - - /* ** Execute a protected call. */ -struct CallS { /* data to `f_call' */ - StkId func; - int nresults; +struct CallS +{ /* data to `f_call' */ + StkId func; + int nresults; }; - -static void f_call (lua_State *L, void *ud) { - struct CallS *c = cast(struct CallS *, ud); - luaD_call(L, c->func, c->nresults, 0); +static void f_call(lua_State *L, void *ud) +{ + struct CallS *c = cast(struct CallS *, ud); + luaD_call(L, c->func, c->nresults, 0); } - - -LUA_API int lua_pcallk (lua_State *L, int nargs, int nresults, int errfunc, - int ctx, lua_CFunction k) { - struct CallS c; - int status; - ptrdiff_t func; - lua_lock(L); - api_check(L, k == NULL || !isLua(L->ci), - "cannot use continuations inside hooks"); - api_checknelems(L, nargs+1); - api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); - checkresults(L, nargs, nresults); - if (errfunc == 0) - func = 0; - else { - StkId o = index2addr(L, errfunc); - api_checkstackindex(L, errfunc, o); - func = savestack(L, o); - } - c.func = L->top - (nargs+1); /* function to be called */ - if (k == NULL || L->nny > 0) { /* no continuation or no yieldable? */ - c.nresults = nresults; /* do a 'conventional' protected call */ - status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); - } - else { /* prepare continuation (call is already protected by 'resume') */ - CallInfo *ci = L->ci; - ci->u.c.k = k; /* save continuation */ - ci->u.c.ctx = ctx; /* save context */ - /* save information for error recovery */ - ci->extra = savestack(L, c.func); - ci->u.c.old_allowhook = L->allowhook; - ci->u.c.old_errfunc = L->errfunc; - L->errfunc = func; - /* mark that function may do error recovery */ - ci->callstatus |= CIST_YPCALL; - luaD_call(L, c.func, nresults, 1); /* do the call */ - ci->callstatus &= ~CIST_YPCALL; - L->errfunc = ci->u.c.old_errfunc; - status = LUA_OK; /* if it is here, there were no errors */ - } - adjustresults(L, nresults); - lua_unlock(L); - return status; +LUA_API int lua_pcallk(lua_State *L, int nargs, int nresults, int errfunc, + int ctx, lua_CFunction k) +{ + struct CallS c; + int status; + ptrdiff_t func; + lua_lock(L); + api_check(L, k == NULL || !isLua(L->ci), + "cannot use continuations inside hooks"); + api_checknelems(L, nargs + 1); + api_check(L, L->status == LUA_OK, "cannot do calls on non-normal thread"); + checkresults(L, nargs, nresults); + if (errfunc == 0) + func = 0; + else + { + StkId o = index2addr(L, errfunc); + api_checkstackindex(L, errfunc, o); + func = savestack(L, o); + } + c.func = L->top - (nargs + 1); /* function to be called */ + if (k == NULL || L->nny > 0) + { /* no continuation or no yieldable? */ + c.nresults = nresults; /* do a 'conventional' protected call */ + status = luaD_pcall(L, f_call, &c, savestack(L, c.func), func); + } + else + { /* prepare continuation (call is already protected by 'resume') */ + CallInfo *ci = L->ci; + ci->u.c.k = k; /* save continuation */ + ci->u.c.ctx = ctx; /* save context */ + /* save information for error recovery */ + ci->extra = savestack(L, c.func); + ci->u.c.old_allowhook = L->allowhook; + ci->u.c.old_errfunc = L->errfunc; + L->errfunc = func; + /* mark that function may do error recovery */ + ci->callstatus |= CIST_YPCALL; + luaD_call(L, c.func, nresults, 1); /* do the call */ + ci->callstatus &= ~CIST_YPCALL; + L->errfunc = ci->u.c.old_errfunc; + status = LUA_OK; /* if it is here, there were no errors */ + } + adjustresults(L, nresults); + lua_unlock(L); + return status; } - -LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, - const char *chunkname, const char *mode) { - ZIO z; - int status; - lua_lock(L); - if (!chunkname) chunkname = "?"; - luaZ_init(L, &z, reader, data); - status = luaD_protectedparser(L, &z, chunkname, mode); - if (status == LUA_OK) { /* no errors? */ - LClosure *f = clLvalue(L->top - 1); /* get newly created function */ - if (f->nupvalues == 1) { /* does it have one upvalue? */ - /* get global table from registry */ - Table *reg = hvalue(&G(L)->l_registry); - const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS); - /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ - setobj(L, f->upvals[0]->v, gt); - luaC_barrier(L, f->upvals[0], gt); - } - } - lua_unlock(L); - return status; +LUA_API int lua_load(lua_State *L, lua_Reader reader, void *data, + const char *chunkname, const char *mode) +{ + ZIO z; + int status; + lua_lock(L); + if (!chunkname) chunkname = "?"; + luaZ_init(L, &z, reader, data); + status = luaD_protectedparser(L, &z, chunkname, mode); + if (status == LUA_OK) + { /* no errors? */ + LClosure *f = clLvalue(L->top - 1); /* get newly created function */ + if (f->nupvalues == 1) + { /* does it have one upvalue? */ + /* get global table from registry */ + Table *reg = hvalue(&G(L)->l_registry); + const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS); + /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ + setobj(L, f->upvals[0]->v, gt); + luaC_barrier(L, f->upvals[0], gt); + } + } + lua_unlock(L); + return status; } - -LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) { - int status; - TValue *o; - lua_lock(L); - api_checknelems(L, 1); - o = L->top - 1; - if (isLfunction(o)) - status = luaU_dump(L, getproto(o), writer, data, 0); - else - status = 1; - lua_unlock(L); - return status; +LUA_API int lua_dump(lua_State *L, lua_Writer writer, void *data) +{ + int status; + TValue *o; + lua_lock(L); + api_checknelems(L, 1); + o = L->top - 1; + if (isLfunction(o)) + status = luaU_dump(L, getproto(o), writer, data, 0); + else + status = 1; + lua_unlock(L); + return status; } - -LUA_API int lua_status (lua_State *L) { - return L->status; +LUA_API int lua_status(lua_State *L) +{ + return L->status; } - /* ** Garbage-collection function */ -LUA_API int lua_gc (lua_State *L, int what, int data) { - int res = 0; - global_State *g; - lua_lock(L); - g = G(L); - switch (what) { - case LUA_GCSTOP: { - g->gcrunning = 0; - break; - } - case LUA_GCRESTART: { - luaE_setdebt(g, 0); - g->gcrunning = 1; - break; - } - case LUA_GCCOLLECT: { - luaC_fullgc(L, 0); - break; - } - case LUA_GCCOUNT: { - /* GC values are expressed in Kbytes: #bytes/2^10 */ - res = cast_int(gettotalbytes(g) >> 10); - break; - } - case LUA_GCCOUNTB: { - res = cast_int(gettotalbytes(g) & 0x3ff); - break; - } - case LUA_GCSTEP: { - if (g->gckind == KGC_GEN) { /* generational mode? */ - res = (g->GCestimate == 0); /* true if it will do major collection */ - luaC_forcestep(L); /* do a single step */ - } - else { - lu_mem debt = cast(lu_mem, data) * 1024 - GCSTEPSIZE; - if (g->gcrunning) - debt += g->GCdebt; /* include current debt */ - luaE_setdebt(g, debt); - luaC_forcestep(L); - if (g->gcstate == GCSpause) /* end of cycle? */ - res = 1; /* signal it */ - } - break; - } - case LUA_GCSETPAUSE: { - res = g->gcpause; - g->gcpause = data; - break; - } - case LUA_GCSETMAJORINC: { - res = g->gcmajorinc; - g->gcmajorinc = data; - break; - } - case LUA_GCSETSTEPMUL: { - res = g->gcstepmul; - g->gcstepmul = data; - break; - } - case LUA_GCISRUNNING: { - res = g->gcrunning; - break; - } - case LUA_GCGEN: { /* change collector to generational mode */ - luaC_changemode(L, KGC_GEN); - break; - } - case LUA_GCINC: { /* change collector to incremental mode */ - luaC_changemode(L, KGC_NORMAL); - break; - } - default: res = -1; /* invalid option */ - } - lua_unlock(L); - return res; +LUA_API int lua_gc(lua_State *L, int what, int data) +{ + int res = 0; + global_State *g; + lua_lock(L); + g = G(L); + switch (what) + { + case LUA_GCSTOP: + { + g->gcrunning = 0; + break; + } + case LUA_GCRESTART: + { + luaE_setdebt(g, 0); + g->gcrunning = 1; + break; + } + case LUA_GCCOLLECT: + { + luaC_fullgc(L, 0); + break; + } + case LUA_GCCOUNT: + { + /* GC values are expressed in Kbytes: #bytes/2^10 */ + res = cast_int(gettotalbytes(g) >> 10); + break; + } + case LUA_GCCOUNTB: + { + res = cast_int(gettotalbytes(g) & 0x3ff); + break; + } + case LUA_GCSTEP: + { + if (g->gckind == KGC_GEN) + { /* generational mode? */ + res = (g->GCestimate == 0); /* true if it will do major collection */ + luaC_forcestep(L); /* do a single step */ + } + else + { + lu_mem debt = cast(lu_mem, data) * 1024 - GCSTEPSIZE; + if (g->gcrunning) + debt += g->GCdebt; /* include current debt */ + luaE_setdebt(g, debt); + luaC_forcestep(L); + if (g->gcstate == GCSpause) /* end of cycle? */ + res = 1; /* signal it */ + } + break; + } + case LUA_GCSETPAUSE: + { + res = g->gcpause; + g->gcpause = data; + break; + } + case LUA_GCSETMAJORINC: + { + res = g->gcmajorinc; + g->gcmajorinc = data; + break; + } + case LUA_GCSETSTEPMUL: + { + res = g->gcstepmul; + g->gcstepmul = data; + break; + } + case LUA_GCISRUNNING: + { + res = g->gcrunning; + break; + } + case LUA_GCGEN: + { /* change collector to generational mode */ + luaC_changemode(L, KGC_GEN); + break; + } + case LUA_GCINC: + { /* change collector to incremental mode */ + luaC_changemode(L, KGC_NORMAL); + break; + } + default: + res = -1; /* invalid option */ + } + lua_unlock(L); + return res; } - - /* ** miscellaneous functions */ - -LUA_API int lua_error (lua_State *L) { - lua_lock(L); - api_checknelems(L, 1); - luaG_errormsg(L); - /* code unreachable; will unlock when control actually leaves the kernel */ - return 0; /* to avoid warnings */ +LUA_API int lua_error(lua_State *L) +{ + lua_lock(L); + api_checknelems(L, 1); + luaG_errormsg(L); + /* code unreachable; will unlock when control actually leaves the kernel */ + return 0; /* to avoid warnings */ } - -LUA_API int lua_next (lua_State *L, int idx) { - StkId t; - int more; - lua_lock(L); - t = index2addr(L, idx); - api_check(L, ttistable(t), "table expected"); - more = luaH_next(L, hvalue(t), L->top - 1); - if (more) { - api_incr_top(L); - } - else /* no more elements */ - L->top -= 1; /* remove key */ - lua_unlock(L); - return more; +LUA_API int lua_next(lua_State *L, int idx) +{ + StkId t; + int more; + lua_lock(L); + t = index2addr(L, idx); + api_check(L, ttistable(t), "table expected"); + more = luaH_next(L, hvalue(t), L->top - 1); + if (more) + { + api_incr_top(L); + } + else /* no more elements */ + L->top -= 1; /* remove key */ + lua_unlock(L); + return more; } - -LUA_API void lua_concat (lua_State *L, int n) { - lua_lock(L); - api_checknelems(L, n); - if (n >= 2) { - luaC_checkGC(L); - luaV_concat(L, n); - } - else if (n == 0) { /* push empty string */ - setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); - api_incr_top(L); - } - /* else n == 1; nothing to do */ - lua_unlock(L); +LUA_API void lua_concat(lua_State *L, int n) +{ + lua_lock(L); + api_checknelems(L, n); + if (n >= 2) + { + luaC_checkGC(L); + luaV_concat(L, n); + } + else if (n == 0) + { /* push empty string */ + setsvalue2s(L, L->top, luaS_newlstr(L, "", 0)); + api_incr_top(L); + } + /* else n == 1; nothing to do */ + lua_unlock(L); } - -LUA_API void lua_len (lua_State *L, int idx) { - StkId t; - lua_lock(L); - t = index2addr(L, idx); - luaV_objlen(L, L->top, t); - api_incr_top(L); - lua_unlock(L); +LUA_API void lua_len(lua_State *L, int idx) +{ + StkId t; + lua_lock(L); + t = index2addr(L, idx); + luaV_objlen(L, L->top, t); + api_incr_top(L); + lua_unlock(L); } - -LUA_API lua_Alloc lua_getallocf (lua_State *L, void **ud) { - lua_Alloc f; - lua_lock(L); - if (ud) *ud = G(L)->ud; - f = G(L)->frealloc; - lua_unlock(L); - return f; +LUA_API lua_Alloc lua_getallocf(lua_State *L, void **ud) +{ + lua_Alloc f; + lua_lock(L); + if (ud) *ud = G(L)->ud; + f = G(L)->frealloc; + lua_unlock(L); + return f; } - -LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { - lua_lock(L); - G(L)->ud = ud; - G(L)->frealloc = f; - lua_unlock(L); +LUA_API void lua_setallocf(lua_State *L, lua_Alloc f, void *ud) +{ + lua_lock(L); + G(L)->ud = ud; + G(L)->frealloc = f; + lua_unlock(L); } - -LUA_API void *lua_newuserdata (lua_State *L, size_t size) { - Udata *u; - lua_lock(L); - luaC_checkGC(L); - u = luaS_newudata(L, size, NULL); - setuvalue(L, L->top, u); - api_incr_top(L); - lua_unlock(L); - return u + 1; +LUA_API void *lua_newuserdata(lua_State *L, size_t size) +{ + Udata *u; + lua_lock(L); + luaC_checkGC(L); + u = luaS_newudata(L, size, NULL); + setuvalue(L, L->top, u); + api_incr_top(L); + lua_unlock(L); + return u + 1; } - - -static const char *aux_upvalue (StkId fi, int n, TValue **val, - GCObject **owner) { - switch (ttype(fi)) { - case LUA_TCCL: { /* C closure */ - CClosure *f = clCvalue(fi); - if (!(1 <= n && n <= f->nupvalues)) return NULL; - *val = &f->upvalue[n-1]; - if (owner) *owner = obj2gco(f); - return ""; - } - case LUA_TLCL: { /* Lua closure */ - LClosure *f = clLvalue(fi); - TString *name; - Proto *p = f->p; - if (!(1 <= n && n <= p->sizeupvalues)) return NULL; - *val = f->upvals[n-1]->v; - if (owner) *owner = obj2gco(f->upvals[n - 1]); - name = p->upvalues[n-1].name; - return (name == NULL) ? "" : getstr(name); - } - default: return NULL; /* not a closure */ - } +static const char *aux_upvalue(StkId fi, int n, TValue **val, + GCObject **owner) +{ + switch (ttype(fi)) + { + case LUA_TCCL: + { /* C closure */ + CClosure *f = clCvalue(fi); + if (!(1 <= n && n <= f->nupvalues)) return NULL; + *val = &f->upvalue[n - 1]; + if (owner) *owner = obj2gco(f); + return ""; + } + case LUA_TLCL: + { /* Lua closure */ + LClosure *f = clLvalue(fi); + TString *name; + Proto *p = f->p; + if (!(1 <= n && n <= p->sizeupvalues)) return NULL; + *val = f->upvals[n - 1]->v; + if (owner) *owner = obj2gco(f->upvals[n - 1]); + name = p->upvalues[n - 1].name; + return (name == NULL) ? "" : getstr(name); + } + default: + return NULL; /* not a closure */ + } } - -LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { - const char *name; - TValue *val = NULL; /* to avoid warnings */ - lua_lock(L); - name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL); - if (name) { - setobj2s(L, L->top, val); - api_incr_top(L); - } - lua_unlock(L); - return name; +LUA_API const char *lua_getupvalue(lua_State *L, int funcindex, int n) +{ + const char *name; + TValue *val = NULL; /* to avoid warnings */ + lua_lock(L); + name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL); + if (name) + { + setobj2s(L, L->top, val); + api_incr_top(L); + } + lua_unlock(L); + return name; } - -LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { - const char *name; - TValue *val = NULL; /* to avoid warnings */ - GCObject *owner = NULL; /* to avoid warnings */ - StkId fi; - lua_lock(L); - fi = index2addr(L, funcindex); - api_checknelems(L, 1); - name = aux_upvalue(fi, n, &val, &owner); - if (name) { - L->top--; - setobj(L, val, L->top); - luaC_barrier(L, owner, L->top); - } - lua_unlock(L); - return name; +LUA_API const char *lua_setupvalue(lua_State *L, int funcindex, int n) +{ + const char *name; + TValue *val = NULL; /* to avoid warnings */ + GCObject *owner = NULL; /* to avoid warnings */ + StkId fi; + lua_lock(L); + fi = index2addr(L, funcindex); + api_checknelems(L, 1); + name = aux_upvalue(fi, n, &val, &owner); + if (name) + { + L->top--; + setobj(L, val, L->top); + luaC_barrier(L, owner, L->top); + } + lua_unlock(L); + return name; } - -static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { - LClosure *f; - StkId fi = index2addr(L, fidx); - api_check(L, ttisLclosure(fi), "Lua function expected"); - f = clLvalue(fi); - api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); - if (pf) *pf = f; - return &f->upvals[n - 1]; /* get its upvalue pointer */ +static UpVal **getupvalref(lua_State *L, int fidx, int n, LClosure **pf) +{ + LClosure *f; + StkId fi = index2addr(L, fidx); + api_check(L, ttisLclosure(fi), "Lua function expected"); + f = clLvalue(fi); + api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); + if (pf) *pf = f; + return &f->upvals[n - 1]; /* get its upvalue pointer */ } - -LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { - StkId fi = index2addr(L, fidx); - switch (ttype(fi)) { - case LUA_TLCL: { /* lua closure */ - return *getupvalref(L, fidx, n, NULL); - } - case LUA_TCCL: { /* C closure */ - CClosure *f = clCvalue(fi); - api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index"); - return &f->upvalue[n - 1]; - } - default: { - api_check(L, 0, "closure expected"); - return NULL; - } - } +LUA_API void *lua_upvalueid(lua_State *L, int fidx, int n) +{ + StkId fi = index2addr(L, fidx); + switch (ttype(fi)) + { + case LUA_TLCL: + { /* lua closure */ + return *getupvalref(L, fidx, n, NULL); + } + case LUA_TCCL: + { /* C closure */ + CClosure *f = clCvalue(fi); + api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index"); + return &f->upvalue[n - 1]; + } + default: + { + api_check(L, 0, "closure expected"); + return NULL; + } + } } - -LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, - int fidx2, int n2) { - LClosure *f1; - UpVal **up1 = getupvalref(L, fidx1, n1, &f1); - UpVal **up2 = getupvalref(L, fidx2, n2, NULL); - *up1 = *up2; - luaC_objbarrier(L, f1, *up2); +LUA_API void lua_upvaluejoin(lua_State *L, int fidx1, int n1, + int fidx2, int n2) +{ + LClosure *f1; + UpVal **up1 = getupvalref(L, fidx1, n1, &f1); + UpVal **up2 = getupvalref(L, fidx2, n2, NULL); + *up1 = *up2; + luaC_objbarrier(L, f1, *up2); } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lapi.h b/examples/ThirdPartyLibs/lua-5.2.3/src/lapi.h index c7d34ad84..bf13633b9 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lapi.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lapi.h @@ -7,18 +7,22 @@ #ifndef lapi_h #define lapi_h - #include "llimits.h" #include "lstate.h" -#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ - "stack overflow");} +#define api_incr_top(L) \ + { \ + L->top++; \ + api_check(L, L->top <= L->ci->top, \ + "stack overflow"); \ + } -#define adjustresults(L,nres) \ - { if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } - -#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ - "not enough elements in the stack") +#define adjustresults(L, nres) \ + { \ + if ((nres) == LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; \ + } +#define api_checknelems(L, n) api_check(L, (n) < (L->top - L->ci->func), \ + "not enough elements in the stack") #endif diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lauxlib.c b/examples/ThirdPartyLibs/lua-5.2.3/src/lauxlib.c index b00f8c709..7259a4084 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lauxlib.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lauxlib.c @@ -4,14 +4,12 @@ ** See Copyright Notice in lua.h */ - #include #include #include #include #include - /* This file uses only the official API of Lua. ** Any function declared here could be written as an application function. */ @@ -23,206 +21,225 @@ #include "lauxlib.h" - /* ** {====================================================== ** Traceback ** ======================================================= */ - -#define LEVELS1 12 /* size of the first part of the stack */ -#define LEVELS2 10 /* size of the second part of the stack */ - - +#define LEVELS1 12 /* size of the first part of the stack */ +#define LEVELS2 10 /* size of the second part of the stack */ /* ** search for 'objidx' in table at index -1. ** return 1 + string at top if find a good name. */ -static int findfield (lua_State *L, int objidx, int level) { - if (level == 0 || !lua_istable(L, -1)) - return 0; /* not found */ - lua_pushnil(L); /* start 'next' loop */ - while (lua_next(L, -2)) { /* for each pair in table */ - if (lua_type(L, -2) == LUA_TSTRING) { /* ignore non-string keys */ - if (lua_rawequal(L, objidx, -1)) { /* found object? */ - lua_pop(L, 1); /* remove value (but keep name) */ - return 1; - } - else if (findfield(L, objidx, level - 1)) { /* try recursively */ - lua_remove(L, -2); /* remove table (but keep name) */ - lua_pushliteral(L, "."); - lua_insert(L, -2); /* place '.' between the two names */ - lua_concat(L, 3); - return 1; - } - } - lua_pop(L, 1); /* remove value */ - } - return 0; /* not found */ +static int findfield(lua_State *L, int objidx, int level) +{ + if (level == 0 || !lua_istable(L, -1)) + return 0; /* not found */ + lua_pushnil(L); /* start 'next' loop */ + while (lua_next(L, -2)) + { /* for each pair in table */ + if (lua_type(L, -2) == LUA_TSTRING) + { /* ignore non-string keys */ + if (lua_rawequal(L, objidx, -1)) + { /* found object? */ + lua_pop(L, 1); /* remove value (but keep name) */ + return 1; + } + else if (findfield(L, objidx, level - 1)) + { /* try recursively */ + lua_remove(L, -2); /* remove table (but keep name) */ + lua_pushliteral(L, "."); + lua_insert(L, -2); /* place '.' between the two names */ + lua_concat(L, 3); + return 1; + } + } + lua_pop(L, 1); /* remove value */ + } + return 0; /* not found */ } - -static int pushglobalfuncname (lua_State *L, lua_Debug *ar) { - int top = lua_gettop(L); - lua_getinfo(L, "f", ar); /* push function */ - lua_pushglobaltable(L); - if (findfield(L, top + 1, 2)) { - lua_copy(L, -1, top + 1); /* move name to proper place */ - lua_pop(L, 2); /* remove pushed values */ - return 1; - } - else { - lua_settop(L, top); /* remove function and global table */ - return 0; - } +static int pushglobalfuncname(lua_State *L, lua_Debug *ar) +{ + int top = lua_gettop(L); + lua_getinfo(L, "f", ar); /* push function */ + lua_pushglobaltable(L); + if (findfield(L, top + 1, 2)) + { + lua_copy(L, -1, top + 1); /* move name to proper place */ + lua_pop(L, 2); /* remove pushed values */ + return 1; + } + else + { + lua_settop(L, top); /* remove function and global table */ + return 0; + } } - -static void pushfuncname (lua_State *L, lua_Debug *ar) { - if (*ar->namewhat != '\0') /* is there a name? */ - lua_pushfstring(L, "function " LUA_QS, ar->name); - else if (*ar->what == 'm') /* main? */ - lua_pushliteral(L, "main chunk"); - else if (*ar->what == 'C') { - if (pushglobalfuncname(L, ar)) { - lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1)); - lua_remove(L, -2); /* remove name */ - } - else - lua_pushliteral(L, "?"); - } - else - lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); +static void pushfuncname(lua_State *L, lua_Debug *ar) +{ + if (*ar->namewhat != '\0') /* is there a name? */ + lua_pushfstring(L, "function " LUA_QS, ar->name); + else if (*ar->what == 'm') /* main? */ + lua_pushliteral(L, "main chunk"); + else if (*ar->what == 'C') + { + if (pushglobalfuncname(L, ar)) + { + lua_pushfstring(L, "function " LUA_QS, lua_tostring(L, -1)); + lua_remove(L, -2); /* remove name */ + } + else + lua_pushliteral(L, "?"); + } + else + lua_pushfstring(L, "function <%s:%d>", ar->short_src, ar->linedefined); } - -static int countlevels (lua_State *L) { - lua_Debug ar; - int li = 1, le = 1; - /* find an upper bound */ - while (lua_getstack(L, le, &ar)) { li = le; le *= 2; } - /* do a binary search */ - while (li < le) { - int m = (li + le)/2; - if (lua_getstack(L, m, &ar)) li = m + 1; - else le = m; - } - return le - 1; +static int countlevels(lua_State *L) +{ + lua_Debug ar; + int li = 1, le = 1; + /* find an upper bound */ + while (lua_getstack(L, le, &ar)) + { + li = le; + le *= 2; + } + /* do a binary search */ + while (li < le) + { + int m = (li + le) / 2; + if (lua_getstack(L, m, &ar)) + li = m + 1; + else + le = m; + } + return le - 1; } - -LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, - const char *msg, int level) { - lua_Debug ar; - int top = lua_gettop(L); - int numlevels = countlevels(L1); - int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0; - if (msg) lua_pushfstring(L, "%s\n", msg); - lua_pushliteral(L, "stack traceback:"); - while (lua_getstack(L1, level++, &ar)) { - if (level == mark) { /* too many levels? */ - lua_pushliteral(L, "\n\t..."); /* add a '...' */ - level = numlevels - LEVELS2; /* and skip to last ones */ - } - else { - lua_getinfo(L1, "Slnt", &ar); - lua_pushfstring(L, "\n\t%s:", ar.short_src); - if (ar.currentline > 0) - lua_pushfstring(L, "%d:", ar.currentline); - lua_pushliteral(L, " in "); - pushfuncname(L, &ar); - if (ar.istailcall) - lua_pushliteral(L, "\n\t(...tail calls...)"); - lua_concat(L, lua_gettop(L) - top); - } - } - lua_concat(L, lua_gettop(L) - top); +LUALIB_API void luaL_traceback(lua_State *L, lua_State *L1, + const char *msg, int level) +{ + lua_Debug ar; + int top = lua_gettop(L); + int numlevels = countlevels(L1); + int mark = (numlevels > LEVELS1 + LEVELS2) ? LEVELS1 : 0; + if (msg) lua_pushfstring(L, "%s\n", msg); + lua_pushliteral(L, "stack traceback:"); + while (lua_getstack(L1, level++, &ar)) + { + if (level == mark) + { /* too many levels? */ + lua_pushliteral(L, "\n\t..."); /* add a '...' */ + level = numlevels - LEVELS2; /* and skip to last ones */ + } + else + { + lua_getinfo(L1, "Slnt", &ar); + lua_pushfstring(L, "\n\t%s:", ar.short_src); + if (ar.currentline > 0) + lua_pushfstring(L, "%d:", ar.currentline); + lua_pushliteral(L, " in "); + pushfuncname(L, &ar); + if (ar.istailcall) + lua_pushliteral(L, "\n\t(...tail calls...)"); + lua_concat(L, lua_gettop(L) - top); + } + } + lua_concat(L, lua_gettop(L) - top); } /* }====================================================== */ - /* ** {====================================================== ** Error-report functions ** ======================================================= */ -LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) { - lua_Debug ar; - if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ - return luaL_error(L, "bad argument #%d (%s)", narg, extramsg); - lua_getinfo(L, "n", &ar); - if (strcmp(ar.namewhat, "method") == 0) { - narg--; /* do not count `self' */ - if (narg == 0) /* error is in the self argument itself? */ - return luaL_error(L, "calling " LUA_QS " on bad self (%s)", - ar.name, extramsg); - } - if (ar.name == NULL) - ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?"; - return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", - narg, ar.name, extramsg); +LUALIB_API int luaL_argerror(lua_State *L, int narg, const char *extramsg) +{ + lua_Debug ar; + if (!lua_getstack(L, 0, &ar)) /* no stack frame? */ + return luaL_error(L, "bad argument #%d (%s)", narg, extramsg); + lua_getinfo(L, "n", &ar); + if (strcmp(ar.namewhat, "method") == 0) + { + narg--; /* do not count `self' */ + if (narg == 0) /* error is in the self argument itself? */ + return luaL_error(L, "calling " LUA_QS " on bad self (%s)", + ar.name, extramsg); + } + if (ar.name == NULL) + ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?"; + return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)", + narg, ar.name, extramsg); } - -static int typeerror (lua_State *L, int narg, const char *tname) { - const char *msg = lua_pushfstring(L, "%s expected, got %s", - tname, luaL_typename(L, narg)); - return luaL_argerror(L, narg, msg); +static int typeerror(lua_State *L, int narg, const char *tname) +{ + const char *msg = lua_pushfstring(L, "%s expected, got %s", + tname, luaL_typename(L, narg)); + return luaL_argerror(L, narg, msg); } - -static void tag_error (lua_State *L, int narg, int tag) { - typeerror(L, narg, lua_typename(L, tag)); +static void tag_error(lua_State *L, int narg, int tag) +{ + typeerror(L, narg, lua_typename(L, tag)); } - -LUALIB_API void luaL_where (lua_State *L, int level) { - lua_Debug ar; - if (lua_getstack(L, level, &ar)) { /* check function at level */ - lua_getinfo(L, "Sl", &ar); /* get info about it */ - if (ar.currentline > 0) { /* is there info? */ - lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); - return; - } - } - lua_pushliteral(L, ""); /* else, no information available... */ +LUALIB_API void luaL_where(lua_State *L, int level) +{ + lua_Debug ar; + if (lua_getstack(L, level, &ar)) + { /* check function at level */ + lua_getinfo(L, "Sl", &ar); /* get info about it */ + if (ar.currentline > 0) + { /* is there info? */ + lua_pushfstring(L, "%s:%d: ", ar.short_src, ar.currentline); + return; + } + } + lua_pushliteral(L, ""); /* else, no information available... */ } - -LUALIB_API int luaL_error (lua_State *L, const char *fmt, ...) { - va_list argp; - va_start(argp, fmt); - luaL_where(L, 1); - lua_pushvfstring(L, fmt, argp); - va_end(argp); - lua_concat(L, 2); - return lua_error(L); +LUALIB_API int luaL_error(lua_State *L, const char *fmt, ...) +{ + va_list argp; + va_start(argp, fmt); + luaL_where(L, 1); + lua_pushvfstring(L, fmt, argp); + va_end(argp); + lua_concat(L, 2); + return lua_error(L); } - -LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) { - int en = errno; /* calls to Lua API may change this value */ - if (stat) { - lua_pushboolean(L, 1); - return 1; - } - else { - lua_pushnil(L); - if (fname) - lua_pushfstring(L, "%s: %s", fname, strerror(en)); - else - lua_pushstring(L, strerror(en)); - lua_pushinteger(L, en); - return 3; - } +LUALIB_API int luaL_fileresult(lua_State *L, int stat, const char *fname) +{ + int en = errno; /* calls to Lua API may change this value */ + if (stat) + { + lua_pushboolean(L, 1); + return 1; + } + else + { + lua_pushnil(L); + if (fname) + lua_pushfstring(L, "%s: %s", fname, strerror(en)); + else + lua_pushstring(L, strerror(en)); + lua_pushinteger(L, en); + return 3; + } } - -#if !defined(inspectstat) /* { */ +#if !defined(inspectstat) /* { */ #if defined(LUA_USE_POSIX) @@ -231,193 +248,204 @@ LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) { /* ** use appropriate macros to interpret 'pclose' return status */ -#define inspectstat(stat,what) \ - if (WIFEXITED(stat)) { stat = WEXITSTATUS(stat); } \ - else if (WIFSIGNALED(stat)) { stat = WTERMSIG(stat); what = "signal"; } +#define inspectstat(stat, what) \ + if (WIFEXITED(stat)) \ + { \ + stat = WEXITSTATUS(stat); \ + } \ + else if (WIFSIGNALED(stat)) \ + { \ + stat = WTERMSIG(stat); \ + what = "signal"; \ + } #else -#define inspectstat(stat,what) /* no op */ +#define inspectstat(stat, what) /* no op */ #endif -#endif /* } */ +#endif /* } */ - -LUALIB_API int luaL_execresult (lua_State *L, int stat) { - const char *what = "exit"; /* type of termination */ - if (stat == -1) /* error? */ - return luaL_fileresult(L, 0, NULL); - else { - inspectstat(stat, what); /* interpret result */ - if (*what == 'e' && stat == 0) /* successful termination? */ - lua_pushboolean(L, 1); - else - lua_pushnil(L); - lua_pushstring(L, what); - lua_pushinteger(L, stat); - return 3; /* return true/nil,what,code */ - } +LUALIB_API int luaL_execresult(lua_State *L, int stat) +{ + const char *what = "exit"; /* type of termination */ + if (stat == -1) /* error? */ + return luaL_fileresult(L, 0, NULL); + else + { + inspectstat(stat, what); /* interpret result */ + if (*what == 'e' && stat == 0) /* successful termination? */ + lua_pushboolean(L, 1); + else + lua_pushnil(L); + lua_pushstring(L, what); + lua_pushinteger(L, stat); + return 3; /* return true/nil,what,code */ + } } /* }====================================================== */ - /* ** {====================================================== ** Userdata's metatable manipulation ** ======================================================= */ -LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { - luaL_getmetatable(L, tname); /* try to get metatable */ - if (!lua_isnil(L, -1)) /* name already in use? */ - return 0; /* leave previous value on top, but return 0 */ - lua_pop(L, 1); - lua_newtable(L); /* create metatable */ - lua_pushvalue(L, -1); - lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ - return 1; +LUALIB_API int luaL_newmetatable(lua_State *L, const char *tname) +{ + luaL_getmetatable(L, tname); /* try to get metatable */ + if (!lua_isnil(L, -1)) /* name already in use? */ + return 0; /* leave previous value on top, but return 0 */ + lua_pop(L, 1); + lua_newtable(L); /* create metatable */ + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */ + return 1; } - -LUALIB_API void luaL_setmetatable (lua_State *L, const char *tname) { - luaL_getmetatable(L, tname); - lua_setmetatable(L, -2); +LUALIB_API void luaL_setmetatable(lua_State *L, const char *tname) +{ + luaL_getmetatable(L, tname); + lua_setmetatable(L, -2); } - -LUALIB_API void *luaL_testudata (lua_State *L, int ud, const char *tname) { - void *p = lua_touserdata(L, ud); - if (p != NULL) { /* value is a userdata? */ - if (lua_getmetatable(L, ud)) { /* does it have a metatable? */ - luaL_getmetatable(L, tname); /* get correct metatable */ - if (!lua_rawequal(L, -1, -2)) /* not the same? */ - p = NULL; /* value is a userdata with wrong metatable */ - lua_pop(L, 2); /* remove both metatables */ - return p; - } - } - return NULL; /* value is not a userdata with a metatable */ +LUALIB_API void *luaL_testudata(lua_State *L, int ud, const char *tname) +{ + void *p = lua_touserdata(L, ud); + if (p != NULL) + { /* value is a userdata? */ + if (lua_getmetatable(L, ud)) + { /* does it have a metatable? */ + luaL_getmetatable(L, tname); /* get correct metatable */ + if (!lua_rawequal(L, -1, -2)) /* not the same? */ + p = NULL; /* value is a userdata with wrong metatable */ + lua_pop(L, 2); /* remove both metatables */ + return p; + } + } + return NULL; /* value is not a userdata with a metatable */ } - -LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { - void *p = luaL_testudata(L, ud, tname); - if (p == NULL) typeerror(L, ud, tname); - return p; +LUALIB_API void *luaL_checkudata(lua_State *L, int ud, const char *tname) +{ + void *p = luaL_testudata(L, ud, tname); + if (p == NULL) typeerror(L, ud, tname); + return p; } /* }====================================================== */ - /* ** {====================================================== ** Argument check functions ** ======================================================= */ -LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def, - const char *const lst[]) { - const char *name = (def) ? luaL_optstring(L, narg, def) : - luaL_checkstring(L, narg); - int i; - for (i=0; lst[i]; i++) - if (strcmp(lst[i], name) == 0) - return i; - return luaL_argerror(L, narg, - lua_pushfstring(L, "invalid option " LUA_QS, name)); +LUALIB_API int luaL_checkoption(lua_State *L, int narg, const char *def, + const char *const lst[]) +{ + const char *name = (def) ? luaL_optstring(L, narg, def) : luaL_checkstring(L, narg); + int i; + for (i = 0; lst[i]; i++) + if (strcmp(lst[i], name) == 0) + return i; + return luaL_argerror(L, narg, + lua_pushfstring(L, "invalid option " LUA_QS, name)); } - -LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) { - /* keep some extra space to run error routines, if needed */ - const int extra = LUA_MINSTACK; - if (!lua_checkstack(L, space + extra)) { - if (msg) - luaL_error(L, "stack overflow (%s)", msg); - else - luaL_error(L, "stack overflow"); - } +LUALIB_API void luaL_checkstack(lua_State *L, int space, const char *msg) +{ + /* keep some extra space to run error routines, if needed */ + const int extra = LUA_MINSTACK; + if (!lua_checkstack(L, space + extra)) + { + if (msg) + luaL_error(L, "stack overflow (%s)", msg); + else + luaL_error(L, "stack overflow"); + } } - -LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) { - if (lua_type(L, narg) != t) - tag_error(L, narg, t); +LUALIB_API void luaL_checktype(lua_State *L, int narg, int t) +{ + if (lua_type(L, narg) != t) + tag_error(L, narg, t); } - -LUALIB_API void luaL_checkany (lua_State *L, int narg) { - if (lua_type(L, narg) == LUA_TNONE) - luaL_argerror(L, narg, "value expected"); +LUALIB_API void luaL_checkany(lua_State *L, int narg) +{ + if (lua_type(L, narg) == LUA_TNONE) + luaL_argerror(L, narg, "value expected"); } - -LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) { - const char *s = lua_tolstring(L, narg, len); - if (!s) tag_error(L, narg, LUA_TSTRING); - return s; +LUALIB_API const char *luaL_checklstring(lua_State *L, int narg, size_t *len) +{ + const char *s = lua_tolstring(L, narg, len); + if (!s) tag_error(L, narg, LUA_TSTRING); + return s; } - -LUALIB_API const char *luaL_optlstring (lua_State *L, int narg, - const char *def, size_t *len) { - if (lua_isnoneornil(L, narg)) { - if (len) - *len = (def ? strlen(def) : 0); - return def; - } - else return luaL_checklstring(L, narg, len); +LUALIB_API const char *luaL_optlstring(lua_State *L, int narg, + const char *def, size_t *len) +{ + if (lua_isnoneornil(L, narg)) + { + if (len) + *len = (def ? strlen(def) : 0); + return def; + } + else + return luaL_checklstring(L, narg, len); } - -LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) { - int isnum; - lua_Number d = lua_tonumberx(L, narg, &isnum); - if (!isnum) - tag_error(L, narg, LUA_TNUMBER); - return d; +LUALIB_API lua_Number luaL_checknumber(lua_State *L, int narg) +{ + int isnum; + lua_Number d = lua_tonumberx(L, narg, &isnum); + if (!isnum) + tag_error(L, narg, LUA_TNUMBER); + return d; } - -LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) { - return luaL_opt(L, luaL_checknumber, narg, def); +LUALIB_API lua_Number luaL_optnumber(lua_State *L, int narg, lua_Number def) +{ + return luaL_opt(L, luaL_checknumber, narg, def); } - -LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) { - int isnum; - lua_Integer d = lua_tointegerx(L, narg, &isnum); - if (!isnum) - tag_error(L, narg, LUA_TNUMBER); - return d; +LUALIB_API lua_Integer luaL_checkinteger(lua_State *L, int narg) +{ + int isnum; + lua_Integer d = lua_tointegerx(L, narg, &isnum); + if (!isnum) + tag_error(L, narg, LUA_TNUMBER); + return d; } - -LUALIB_API lua_Unsigned luaL_checkunsigned (lua_State *L, int narg) { - int isnum; - lua_Unsigned d = lua_tounsignedx(L, narg, &isnum); - if (!isnum) - tag_error(L, narg, LUA_TNUMBER); - return d; +LUALIB_API lua_Unsigned luaL_checkunsigned(lua_State *L, int narg) +{ + int isnum; + lua_Unsigned d = lua_tounsignedx(L, narg, &isnum); + if (!isnum) + tag_error(L, narg, LUA_TNUMBER); + return d; } - -LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg, - lua_Integer def) { - return luaL_opt(L, luaL_checkinteger, narg, def); +LUALIB_API lua_Integer luaL_optinteger(lua_State *L, int narg, + lua_Integer def) +{ + return luaL_opt(L, luaL_checkinteger, narg, def); } - -LUALIB_API lua_Unsigned luaL_optunsigned (lua_State *L, int narg, - lua_Unsigned def) { - return luaL_opt(L, luaL_checkunsigned, narg, def); +LUALIB_API lua_Unsigned luaL_optunsigned(lua_State *L, int narg, + lua_Unsigned def) +{ + return luaL_opt(L, luaL_checkunsigned, narg, def); } /* }====================================================== */ - /* ** {====================================================== ** Generic Buffer manipulation @@ -428,87 +456,87 @@ LUALIB_API lua_Unsigned luaL_optunsigned (lua_State *L, int narg, ** check whether buffer is using a userdata on the stack as a temporary ** buffer */ -#define buffonstack(B) ((B)->b != (B)->initb) - +#define buffonstack(B) ((B)->b != (B)->initb) /* ** returns a pointer to a free area with at least 'sz' bytes */ -LUALIB_API char *luaL_prepbuffsize (luaL_Buffer *B, size_t sz) { - lua_State *L = B->L; - if (B->size - B->n < sz) { /* not enough space? */ - char *newbuff; - size_t newsize = B->size * 2; /* double buffer size */ - if (newsize - B->n < sz) /* not big enough? */ - newsize = B->n + sz; - if (newsize < B->n || newsize - B->n < sz) - luaL_error(L, "buffer too large"); - /* create larger buffer */ - newbuff = (char *)lua_newuserdata(L, newsize * sizeof(char)); - /* move content to new buffer */ - memcpy(newbuff, B->b, B->n * sizeof(char)); - if (buffonstack(B)) - lua_remove(L, -2); /* remove old buffer */ - B->b = newbuff; - B->size = newsize; - } - return &B->b[B->n]; +LUALIB_API char *luaL_prepbuffsize(luaL_Buffer *B, size_t sz) +{ + lua_State *L = B->L; + if (B->size - B->n < sz) + { /* not enough space? */ + char *newbuff; + size_t newsize = B->size * 2; /* double buffer size */ + if (newsize - B->n < sz) /* not big enough? */ + newsize = B->n + sz; + if (newsize < B->n || newsize - B->n < sz) + luaL_error(L, "buffer too large"); + /* create larger buffer */ + newbuff = (char *)lua_newuserdata(L, newsize * sizeof(char)); + /* move content to new buffer */ + memcpy(newbuff, B->b, B->n * sizeof(char)); + if (buffonstack(B)) + lua_remove(L, -2); /* remove old buffer */ + B->b = newbuff; + B->size = newsize; + } + return &B->b[B->n]; } - -LUALIB_API void luaL_addlstring (luaL_Buffer *B, const char *s, size_t l) { - char *b = luaL_prepbuffsize(B, l); - memcpy(b, s, l * sizeof(char)); - luaL_addsize(B, l); +LUALIB_API void luaL_addlstring(luaL_Buffer *B, const char *s, size_t l) +{ + char *b = luaL_prepbuffsize(B, l); + memcpy(b, s, l * sizeof(char)); + luaL_addsize(B, l); } - -LUALIB_API void luaL_addstring (luaL_Buffer *B, const char *s) { - luaL_addlstring(B, s, strlen(s)); +LUALIB_API void luaL_addstring(luaL_Buffer *B, const char *s) +{ + luaL_addlstring(B, s, strlen(s)); } - -LUALIB_API void luaL_pushresult (luaL_Buffer *B) { - lua_State *L = B->L; - lua_pushlstring(L, B->b, B->n); - if (buffonstack(B)) - lua_remove(L, -2); /* remove old buffer */ +LUALIB_API void luaL_pushresult(luaL_Buffer *B) +{ + lua_State *L = B->L; + lua_pushlstring(L, B->b, B->n); + if (buffonstack(B)) + lua_remove(L, -2); /* remove old buffer */ } - -LUALIB_API void luaL_pushresultsize (luaL_Buffer *B, size_t sz) { - luaL_addsize(B, sz); - luaL_pushresult(B); +LUALIB_API void luaL_pushresultsize(luaL_Buffer *B, size_t sz) +{ + luaL_addsize(B, sz); + luaL_pushresult(B); } - -LUALIB_API void luaL_addvalue (luaL_Buffer *B) { - lua_State *L = B->L; - size_t l; - const char *s = lua_tolstring(L, -1, &l); - if (buffonstack(B)) - lua_insert(L, -2); /* put value below buffer */ - luaL_addlstring(B, s, l); - lua_remove(L, (buffonstack(B)) ? -2 : -1); /* remove value */ +LUALIB_API void luaL_addvalue(luaL_Buffer *B) +{ + lua_State *L = B->L; + size_t l; + const char *s = lua_tolstring(L, -1, &l); + if (buffonstack(B)) + lua_insert(L, -2); /* put value below buffer */ + luaL_addlstring(B, s, l); + lua_remove(L, (buffonstack(B)) ? -2 : -1); /* remove value */ } - -LUALIB_API void luaL_buffinit (lua_State *L, luaL_Buffer *B) { - B->L = L; - B->b = B->initb; - B->n = 0; - B->size = LUAL_BUFFERSIZE; +LUALIB_API void luaL_buffinit(lua_State *L, luaL_Buffer *B) +{ + B->L = L; + B->b = B->initb; + B->n = 0; + B->size = LUAL_BUFFERSIZE; } - -LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) { - luaL_buffinit(L, B); - return luaL_prepbuffsize(B, sz); +LUALIB_API char *luaL_buffinitsize(lua_State *L, luaL_Buffer *B, size_t sz) +{ + luaL_buffinit(L, B); + return luaL_prepbuffsize(B, sz); } /* }====================================================== */ - /* ** {====================================================== ** Reference system @@ -516,97 +544,102 @@ LUALIB_API char *luaL_buffinitsize (lua_State *L, luaL_Buffer *B, size_t sz) { */ /* index of free-list header */ -#define freelist 0 +#define freelist 0 - -LUALIB_API int luaL_ref (lua_State *L, int t) { - int ref; - if (lua_isnil(L, -1)) { - lua_pop(L, 1); /* remove from stack */ - return LUA_REFNIL; /* `nil' has a unique fixed reference */ - } - t = lua_absindex(L, t); - lua_rawgeti(L, t, freelist); /* get first free element */ - ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */ - lua_pop(L, 1); /* remove it from stack */ - if (ref != 0) { /* any free element? */ - lua_rawgeti(L, t, ref); /* remove it from list */ - lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */ - } - else /* no free elements */ - ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */ - lua_rawseti(L, t, ref); - return ref; +LUALIB_API int luaL_ref(lua_State *L, int t) +{ + int ref; + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); /* remove from stack */ + return LUA_REFNIL; /* `nil' has a unique fixed reference */ + } + t = lua_absindex(L, t); + lua_rawgeti(L, t, freelist); /* get first free element */ + ref = (int)lua_tointeger(L, -1); /* ref = t[freelist] */ + lua_pop(L, 1); /* remove it from stack */ + if (ref != 0) + { /* any free element? */ + lua_rawgeti(L, t, ref); /* remove it from list */ + lua_rawseti(L, t, freelist); /* (t[freelist] = t[ref]) */ + } + else /* no free elements */ + ref = (int)lua_rawlen(L, t) + 1; /* get a new reference */ + lua_rawseti(L, t, ref); + return ref; } - -LUALIB_API void luaL_unref (lua_State *L, int t, int ref) { - if (ref >= 0) { - t = lua_absindex(L, t); - lua_rawgeti(L, t, freelist); - lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */ - lua_pushinteger(L, ref); - lua_rawseti(L, t, freelist); /* t[freelist] = ref */ - } +LUALIB_API void luaL_unref(lua_State *L, int t, int ref) +{ + if (ref >= 0) + { + t = lua_absindex(L, t); + lua_rawgeti(L, t, freelist); + lua_rawseti(L, t, ref); /* t[ref] = t[freelist] */ + lua_pushinteger(L, ref); + lua_rawseti(L, t, freelist); /* t[freelist] = ref */ + } } /* }====================================================== */ - /* ** {====================================================== ** Load functions ** ======================================================= */ -typedef struct LoadF { - int n; /* number of pre-read characters */ - FILE *f; /* file being read */ - char buff[LUAL_BUFFERSIZE]; /* area for reading file */ +typedef struct LoadF +{ + int n; /* number of pre-read characters */ + FILE *f; /* file being read */ + char buff[LUAL_BUFFERSIZE]; /* area for reading file */ } LoadF; - -static const char *getF (lua_State *L, void *ud, size_t *size) { - LoadF *lf = (LoadF *)ud; - (void)L; /* not used */ - if (lf->n > 0) { /* are there pre-read characters to be read? */ - *size = lf->n; /* return them (chars already in buffer) */ - lf->n = 0; /* no more pre-read characters */ - } - else { /* read a block from file */ - /* 'fread' can return > 0 *and* set the EOF flag. If next call to +static const char *getF(lua_State *L, void *ud, size_t *size) +{ + LoadF *lf = (LoadF *)ud; + (void)L; /* not used */ + if (lf->n > 0) + { /* are there pre-read characters to be read? */ + *size = lf->n; /* return them (chars already in buffer) */ + lf->n = 0; /* no more pre-read characters */ + } + else + { /* read a block from file */ + /* 'fread' can return > 0 *and* set the EOF flag. If next call to 'getF' called 'fread', it might still wait for user input. The next check avoids this problem. */ - if (feof(lf->f)) return NULL; - *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); /* read block */ - } - return lf->buff; + if (feof(lf->f)) return NULL; + *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f); /* read block */ + } + return lf->buff; } - -static int errfile (lua_State *L, const char *what, int fnameindex) { - const char *serr = strerror(errno); - const char *filename = lua_tostring(L, fnameindex) + 1; - lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); - lua_remove(L, fnameindex); - return LUA_ERRFILE; +static int errfile(lua_State *L, const char *what, int fnameindex) +{ + const char *serr = strerror(errno); + const char *filename = lua_tostring(L, fnameindex) + 1; + lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr); + lua_remove(L, fnameindex); + return LUA_ERRFILE; } - -static int skipBOM (LoadF *lf) { - const char *p = "\xEF\xBB\xBF"; /* Utf8 BOM mark */ - int c; - lf->n = 0; - do { - c = getc(lf->f); - if (c == EOF || c != *(const unsigned char *)p++) return c; - lf->buff[lf->n++] = c; /* to be read by the parser */ - } while (*p != '\0'); - lf->n = 0; /* prefix matched; discard it */ - return getc(lf->f); /* return next character */ +static int skipBOM(LoadF *lf) +{ + const char *p = "\xEF\xBB\xBF"; /* Utf8 BOM mark */ + int c; + lf->n = 0; + do + { + c = getc(lf->f); + if (c == EOF || c != *(const unsigned char *)p++) return c; + lf->buff[lf->n++] = c; /* to be read by the parser */ + } while (*p != '\0'); + lf->n = 0; /* prefix matched; discard it */ + return getc(lf->f); /* return next character */ } - /* ** reads the first character of file 'f' and skips an optional BOM mark ** in its beginning plus its first line if it starts with '#'. Returns @@ -614,149 +647,159 @@ static int skipBOM (LoadF *lf) { ** first "valid" character of the file (after the optional BOM and ** a first-line comment). */ -static int skipcomment (LoadF *lf, int *cp) { - int c = *cp = skipBOM(lf); - if (c == '#') { /* first line is a comment (Unix exec. file)? */ - do { /* skip first line */ - c = getc(lf->f); - } while (c != EOF && c != '\n') ; - *cp = getc(lf->f); /* skip end-of-line, if present */ - return 1; /* there was a comment */ - } - else return 0; /* no comment */ +static int skipcomment(LoadF *lf, int *cp) +{ + int c = *cp = skipBOM(lf); + if (c == '#') + { /* first line is a comment (Unix exec. file)? */ + do + { /* skip first line */ + c = getc(lf->f); + } while (c != EOF && c != '\n'); + *cp = getc(lf->f); /* skip end-of-line, if present */ + return 1; /* there was a comment */ + } + else + return 0; /* no comment */ } - -LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename, - const char *mode) { - LoadF lf; - int status, readstatus; - int c; - int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ - if (filename == NULL) { - lua_pushliteral(L, "=stdin"); - lf.f = stdin; - } - else { - lua_pushfstring(L, "@%s", filename); - lf.f = fopen(filename, "r"); - if (lf.f == NULL) return errfile(L, "open", fnameindex); - } - if (skipcomment(&lf, &c)) /* read initial portion */ - lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */ - if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */ - lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ - if (lf.f == NULL) return errfile(L, "reopen", fnameindex); - skipcomment(&lf, &c); /* re-read initial portion */ - } - if (c != EOF) - lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */ - status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode); - readstatus = ferror(lf.f); - if (filename) fclose(lf.f); /* close file (even in case of errors) */ - if (readstatus) { - lua_settop(L, fnameindex); /* ignore results from `lua_load' */ - return errfile(L, "read", fnameindex); - } - lua_remove(L, fnameindex); - return status; +LUALIB_API int luaL_loadfilex(lua_State *L, const char *filename, + const char *mode) +{ + LoadF lf; + int status, readstatus; + int c; + int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */ + if (filename == NULL) + { + lua_pushliteral(L, "=stdin"); + lf.f = stdin; + } + else + { + lua_pushfstring(L, "@%s", filename); + lf.f = fopen(filename, "r"); + if (lf.f == NULL) return errfile(L, "open", fnameindex); + } + if (skipcomment(&lf, &c)) /* read initial portion */ + lf.buff[lf.n++] = '\n'; /* add line to correct line numbers */ + if (c == LUA_SIGNATURE[0] && filename) + { /* binary file? */ + lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */ + if (lf.f == NULL) return errfile(L, "reopen", fnameindex); + skipcomment(&lf, &c); /* re-read initial portion */ + } + if (c != EOF) + lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */ + status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode); + readstatus = ferror(lf.f); + if (filename) fclose(lf.f); /* close file (even in case of errors) */ + if (readstatus) + { + lua_settop(L, fnameindex); /* ignore results from `lua_load' */ + return errfile(L, "read", fnameindex); + } + lua_remove(L, fnameindex); + return status; } - -typedef struct LoadS { - const char *s; - size_t size; +typedef struct LoadS +{ + const char *s; + size_t size; } LoadS; - -static const char *getS (lua_State *L, void *ud, size_t *size) { - LoadS *ls = (LoadS *)ud; - (void)L; /* not used */ - if (ls->size == 0) return NULL; - *size = ls->size; - ls->size = 0; - return ls->s; +static const char *getS(lua_State *L, void *ud, size_t *size) +{ + LoadS *ls = (LoadS *)ud; + (void)L; /* not used */ + if (ls->size == 0) return NULL; + *size = ls->size; + ls->size = 0; + return ls->s; } - -LUALIB_API int luaL_loadbufferx (lua_State *L, const char *buff, size_t size, - const char *name, const char *mode) { - LoadS ls; - ls.s = buff; - ls.size = size; - return lua_load(L, getS, &ls, name, mode); +LUALIB_API int luaL_loadbufferx(lua_State *L, const char *buff, size_t size, + const char *name, const char *mode) +{ + LoadS ls; + ls.s = buff; + ls.size = size; + return lua_load(L, getS, &ls, name, mode); } - -LUALIB_API int luaL_loadstring (lua_State *L, const char *s) { - return luaL_loadbuffer(L, s, strlen(s), s); +LUALIB_API int luaL_loadstring(lua_State *L, const char *s) +{ + return luaL_loadbuffer(L, s, strlen(s), s); } /* }====================================================== */ - - -LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { - if (!lua_getmetatable(L, obj)) /* no metatable? */ - return 0; - lua_pushstring(L, event); - lua_rawget(L, -2); - if (lua_isnil(L, -1)) { - lua_pop(L, 2); /* remove metatable and metafield */ - return 0; - } - else { - lua_remove(L, -2); /* remove only metatable */ - return 1; - } +LUALIB_API int luaL_getmetafield(lua_State *L, int obj, const char *event) +{ + if (!lua_getmetatable(L, obj)) /* no metatable? */ + return 0; + lua_pushstring(L, event); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) + { + lua_pop(L, 2); /* remove metatable and metafield */ + return 0; + } + else + { + lua_remove(L, -2); /* remove only metatable */ + return 1; + } } - -LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) { - obj = lua_absindex(L, obj); - if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ - return 0; - lua_pushvalue(L, obj); - lua_call(L, 1, 1); - return 1; +LUALIB_API int luaL_callmeta(lua_State *L, int obj, const char *event) +{ + obj = lua_absindex(L, obj); + if (!luaL_getmetafield(L, obj, event)) /* no metafield? */ + return 0; + lua_pushvalue(L, obj); + lua_call(L, 1, 1); + return 1; } - -LUALIB_API int luaL_len (lua_State *L, int idx) { - int l; - int isnum; - lua_len(L, idx); - l = (int)lua_tointegerx(L, -1, &isnum); - if (!isnum) - luaL_error(L, "object length is not a number"); - lua_pop(L, 1); /* remove object */ - return l; +LUALIB_API int luaL_len(lua_State *L, int idx) +{ + int l; + int isnum; + lua_len(L, idx); + l = (int)lua_tointegerx(L, -1, &isnum); + if (!isnum) + luaL_error(L, "object length is not a number"); + lua_pop(L, 1); /* remove object */ + return l; } - -LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { - if (!luaL_callmeta(L, idx, "__tostring")) { /* no metafield? */ - switch (lua_type(L, idx)) { - case LUA_TNUMBER: - case LUA_TSTRING: - lua_pushvalue(L, idx); - break; - case LUA_TBOOLEAN: - lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false")); - break; - case LUA_TNIL: - lua_pushliteral(L, "nil"); - break; - default: - lua_pushfstring(L, "%s: %p", luaL_typename(L, idx), - lua_topointer(L, idx)); - break; - } - } - return lua_tolstring(L, -1, len); +LUALIB_API const char *luaL_tolstring(lua_State *L, int idx, size_t *len) +{ + if (!luaL_callmeta(L, idx, "__tostring")) + { /* no metafield? */ + switch (lua_type(L, idx)) + { + case LUA_TNUMBER: + case LUA_TSTRING: + lua_pushvalue(L, idx); + break; + case LUA_TBOOLEAN: + lua_pushstring(L, (lua_toboolean(L, idx) ? "true" : "false")); + break; + case LUA_TNIL: + lua_pushliteral(L, "nil"); + break; + default: + lua_pushfstring(L, "%s: %p", luaL_typename(L, idx), + lua_topointer(L, idx)); + break; + } + } + return lua_tolstring(L, -1, len); } - /* ** {====================================================== ** Compatibility with 5.1 module functions @@ -764,77 +807,83 @@ LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { */ #if defined(LUA_COMPAT_MODULE) -static const char *luaL_findtable (lua_State *L, int idx, - const char *fname, int szhint) { - const char *e; - if (idx) lua_pushvalue(L, idx); - do { - e = strchr(fname, '.'); - if (e == NULL) e = fname + strlen(fname); - lua_pushlstring(L, fname, e - fname); - lua_rawget(L, -2); - if (lua_isnil(L, -1)) { /* no such field? */ - lua_pop(L, 1); /* remove this nil */ - lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */ - lua_pushlstring(L, fname, e - fname); - lua_pushvalue(L, -2); - lua_settable(L, -4); /* set new table into field */ - } - else if (!lua_istable(L, -1)) { /* field has a non-table value? */ - lua_pop(L, 2); /* remove table and value */ - return fname; /* return problematic part of the name */ - } - lua_remove(L, -2); /* remove previous table */ - fname = e + 1; - } while (*e == '.'); - return NULL; +static const char *luaL_findtable(lua_State *L, int idx, + const char *fname, int szhint) +{ + const char *e; + if (idx) lua_pushvalue(L, idx); + do + { + e = strchr(fname, '.'); + if (e == NULL) e = fname + strlen(fname); + lua_pushlstring(L, fname, e - fname); + lua_rawget(L, -2); + if (lua_isnil(L, -1)) + { /* no such field? */ + lua_pop(L, 1); /* remove this nil */ + lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */ + lua_pushlstring(L, fname, e - fname); + lua_pushvalue(L, -2); + lua_settable(L, -4); /* set new table into field */ + } + else if (!lua_istable(L, -1)) + { /* field has a non-table value? */ + lua_pop(L, 2); /* remove table and value */ + return fname; /* return problematic part of the name */ + } + lua_remove(L, -2); /* remove previous table */ + fname = e + 1; + } while (*e == '.'); + return NULL; } - /* ** Count number of elements in a luaL_Reg list. */ -static int libsize (const luaL_Reg *l) { - int size = 0; - for (; l && l->name; l++) size++; - return size; +static int libsize(const luaL_Reg *l) +{ + int size = 0; + for (; l && l->name; l++) size++; + return size; } - /* ** Find or create a module table with a given name. The function ** first looks at the _LOADED table and, if that fails, try a ** global variable with that name. In any case, leaves on the stack ** the module table. */ -LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname, - int sizehint) { - luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); /* get _LOADED table */ - lua_getfield(L, -1, modname); /* get _LOADED[modname] */ - if (!lua_istable(L, -1)) { /* not found? */ - lua_pop(L, 1); /* remove previous result */ - /* try global variable (and create one if it does not exist) */ - lua_pushglobaltable(L); - if (luaL_findtable(L, 0, modname, sizehint) != NULL) - luaL_error(L, "name conflict for module " LUA_QS, modname); - lua_pushvalue(L, -1); - lua_setfield(L, -3, modname); /* _LOADED[modname] = new table */ - } - lua_remove(L, -2); /* remove _LOADED table */ +LUALIB_API void luaL_pushmodule(lua_State *L, const char *modname, + int sizehint) +{ + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); /* get _LOADED table */ + lua_getfield(L, -1, modname); /* get _LOADED[modname] */ + if (!lua_istable(L, -1)) + { /* not found? */ + lua_pop(L, 1); /* remove previous result */ + /* try global variable (and create one if it does not exist) */ + lua_pushglobaltable(L); + if (luaL_findtable(L, 0, modname, sizehint) != NULL) + luaL_error(L, "name conflict for module " LUA_QS, modname); + lua_pushvalue(L, -1); + lua_setfield(L, -3, modname); /* _LOADED[modname] = new table */ + } + lua_remove(L, -2); /* remove _LOADED table */ } - -LUALIB_API void luaL_openlib (lua_State *L, const char *libname, - const luaL_Reg *l, int nup) { - luaL_checkversion(L); - if (libname) { - luaL_pushmodule(L, libname, libsize(l)); /* get/create library table */ - lua_insert(L, -(nup + 1)); /* move library table to below upvalues */ - } - if (l) - luaL_setfuncs(L, l, nup); - else - lua_pop(L, nup); /* remove upvalues */ +LUALIB_API void luaL_openlib(lua_State *L, const char *libname, + const luaL_Reg *l, int nup) +{ + luaL_checkversion(L); + if (libname) + { + luaL_pushmodule(L, libname, libsize(l)); /* get/create library table */ + lua_insert(L, -(nup + 1)); /* move library table to below upvalues */ + } + if (l) + luaL_setfuncs(L, l, nup); + else + lua_pop(L, nup); /* remove upvalues */ } #endif @@ -845,115 +894,123 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname, ** function gets the 'nup' elements at the top as upvalues. ** Returns with only the table at the stack. */ -LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { - luaL_checkversion(L); - luaL_checkstack(L, nup, "too many upvalues"); - for (; l->name != NULL; l++) { /* fill the table with given functions */ - int i; - for (i = 0; i < nup; i++) /* copy upvalues to the top */ - lua_pushvalue(L, -nup); - lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ - lua_setfield(L, -(nup + 2), l->name); - } - lua_pop(L, nup); /* remove upvalues */ +LUALIB_API void luaL_setfuncs(lua_State *L, const luaL_Reg *l, int nup) +{ + luaL_checkversion(L); + luaL_checkstack(L, nup, "too many upvalues"); + for (; l->name != NULL; l++) + { /* fill the table with given functions */ + int i; + for (i = 0; i < nup; i++) /* copy upvalues to the top */ + lua_pushvalue(L, -nup); + lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ + lua_setfield(L, -(nup + 2), l->name); + } + lua_pop(L, nup); /* remove upvalues */ } - /* ** ensure that stack[idx][fname] has a table and push that table ** into the stack */ -LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) { - lua_getfield(L, idx, fname); - if (lua_istable(L, -1)) return 1; /* table already there */ - else { - lua_pop(L, 1); /* remove previous result */ - idx = lua_absindex(L, idx); - lua_newtable(L); - lua_pushvalue(L, -1); /* copy to be left at top */ - lua_setfield(L, idx, fname); /* assign new table to field */ - return 0; /* false, because did not find table there */ - } +LUALIB_API int luaL_getsubtable(lua_State *L, int idx, const char *fname) +{ + lua_getfield(L, idx, fname); + if (lua_istable(L, -1)) + return 1; /* table already there */ + else + { + lua_pop(L, 1); /* remove previous result */ + idx = lua_absindex(L, idx); + lua_newtable(L); + lua_pushvalue(L, -1); /* copy to be left at top */ + lua_setfield(L, idx, fname); /* assign new table to field */ + return 0; /* false, because did not find table there */ + } } - /* ** stripped-down 'require'. Calls 'openf' to open a module, ** registers the result in 'package.loaded' table and, if 'glb' ** is true, also registers the result in the global table. ** Leaves resulting module on the top. */ -LUALIB_API void luaL_requiref (lua_State *L, const char *modname, - lua_CFunction openf, int glb) { - lua_pushcfunction(L, openf); - lua_pushstring(L, modname); /* argument to open function */ - lua_call(L, 1, 1); /* open module */ - luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); - lua_pushvalue(L, -2); /* make copy of module (call result) */ - lua_setfield(L, -2, modname); /* _LOADED[modname] = module */ - lua_pop(L, 1); /* remove _LOADED table */ - if (glb) { - lua_pushvalue(L, -1); /* copy of 'mod' */ - lua_setglobal(L, modname); /* _G[modname] = module */ - } +LUALIB_API void luaL_requiref(lua_State *L, const char *modname, + lua_CFunction openf, int glb) +{ + lua_pushcfunction(L, openf); + lua_pushstring(L, modname); /* argument to open function */ + lua_call(L, 1, 1); /* open module */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_pushvalue(L, -2); /* make copy of module (call result) */ + lua_setfield(L, -2, modname); /* _LOADED[modname] = module */ + lua_pop(L, 1); /* remove _LOADED table */ + if (glb) + { + lua_pushvalue(L, -1); /* copy of 'mod' */ + lua_setglobal(L, modname); /* _G[modname] = module */ + } } - -LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, - const char *r) { - const char *wild; - size_t l = strlen(p); - luaL_Buffer b; - luaL_buffinit(L, &b); - while ((wild = strstr(s, p)) != NULL) { - luaL_addlstring(&b, s, wild - s); /* push prefix */ - luaL_addstring(&b, r); /* push replacement in place of pattern */ - s = wild + l; /* continue after `p' */ - } - luaL_addstring(&b, s); /* push last suffix */ - luaL_pushresult(&b); - return lua_tostring(L, -1); +LUALIB_API const char *luaL_gsub(lua_State *L, const char *s, const char *p, + const char *r) +{ + const char *wild; + size_t l = strlen(p); + luaL_Buffer b; + luaL_buffinit(L, &b); + while ((wild = strstr(s, p)) != NULL) + { + luaL_addlstring(&b, s, wild - s); /* push prefix */ + luaL_addstring(&b, r); /* push replacement in place of pattern */ + s = wild + l; /* continue after `p' */ + } + luaL_addstring(&b, s); /* push last suffix */ + luaL_pushresult(&b); + return lua_tostring(L, -1); } - -static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { - (void)ud; (void)osize; /* not used */ - if (nsize == 0) { - free(ptr); - return NULL; - } - else - return realloc(ptr, nsize); +static void *l_alloc(void *ud, void *ptr, size_t osize, size_t nsize) +{ + (void)ud; + (void)osize; /* not used */ + if (nsize == 0) + { + free(ptr); + return NULL; + } + else + return realloc(ptr, nsize); } - -static int panic (lua_State *L) { - luai_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n", - lua_tostring(L, -1)); - return 0; /* return to Lua to abort */ +static int panic(lua_State *L) +{ + luai_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n", + lua_tostring(L, -1)); + return 0; /* return to Lua to abort */ } - -LUALIB_API lua_State *luaL_newstate (void) { - lua_State *L = lua_newstate(l_alloc, NULL); - if (L) lua_atpanic(L, &panic); - return L; +LUALIB_API lua_State *luaL_newstate(void) +{ + lua_State *L = lua_newstate(l_alloc, NULL); + if (L) lua_atpanic(L, &panic); + return L; } - -LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver) { - const lua_Number *v = lua_version(L); - if (v != lua_version(NULL)) - luaL_error(L, "multiple Lua VMs detected"); - else if (*v != ver) - luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f", - ver, *v); - /* check conversions number -> integer types */ - lua_pushnumber(L, -(lua_Number)0x1234); - if (lua_tointeger(L, -1) != -0x1234 || - lua_tounsigned(L, -1) != (lua_Unsigned)-0x1234) - luaL_error(L, "bad conversion number->int;" - " must recompile Lua with proper settings"); - lua_pop(L, 1); +LUALIB_API void luaL_checkversion_(lua_State *L, lua_Number ver) +{ + const lua_Number *v = lua_version(L); + if (v != lua_version(NULL)) + luaL_error(L, "multiple Lua VMs detected"); + else if (*v != ver) + luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f", + ver, *v); + /* check conversions number -> integer types */ + lua_pushnumber(L, -(lua_Number)0x1234); + if (lua_tointeger(L, -1) != -0x1234 || + lua_tounsigned(L, -1) != (lua_Unsigned)-0x1234) + luaL_error(L, + "bad conversion number->int;" + " must recompile Lua with proper settings"); + lua_pop(L, 1); } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lauxlib.h b/examples/ThirdPartyLibs/lua-5.2.3/src/lauxlib.h index 0fb023b8e..88339d433 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lauxlib.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lauxlib.h @@ -4,99 +4,94 @@ ** See Copyright Notice in lua.h */ - #ifndef lauxlib_h #define lauxlib_h - #include #include #include "lua.h" - - /* extra error code for `luaL_load' */ -#define LUA_ERRFILE (LUA_ERRERR+1) +#define LUA_ERRFILE (LUA_ERRERR + 1) - -typedef struct luaL_Reg { - const char *name; - lua_CFunction func; +typedef struct luaL_Reg +{ + const char *name; + lua_CFunction func; } luaL_Reg; +LUALIB_API void(luaL_checkversion_)(lua_State *L, lua_Number ver); +#define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM) -LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver); -#define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM) +LUALIB_API int(luaL_getmetafield)(lua_State *L, int obj, const char *e); +LUALIB_API int(luaL_callmeta)(lua_State *L, int obj, const char *e); +LUALIB_API const char *(luaL_tolstring)(lua_State *L, int idx, size_t *len); +LUALIB_API int(luaL_argerror)(lua_State *L, int numarg, const char *extramsg); +LUALIB_API const char *(luaL_checklstring)(lua_State *L, int numArg, + size_t *l); +LUALIB_API const char *(luaL_optlstring)(lua_State *L, int numArg, + const char *def, size_t *l); +LUALIB_API lua_Number(luaL_checknumber)(lua_State *L, int numArg); +LUALIB_API lua_Number(luaL_optnumber)(lua_State *L, int nArg, lua_Number def); -LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); -LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); -LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); -LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg); -LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg, - size_t *l); -LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg, - const char *def, size_t *l); -LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg); -LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def); +LUALIB_API lua_Integer(luaL_checkinteger)(lua_State *L, int numArg); +LUALIB_API lua_Integer(luaL_optinteger)(lua_State *L, int nArg, + lua_Integer def); +LUALIB_API lua_Unsigned(luaL_checkunsigned)(lua_State *L, int numArg); +LUALIB_API lua_Unsigned(luaL_optunsigned)(lua_State *L, int numArg, + lua_Unsigned def); -LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg); -LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg, - lua_Integer def); -LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int numArg); -LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int numArg, - lua_Unsigned def); +LUALIB_API void(luaL_checkstack)(lua_State *L, int sz, const char *msg); +LUALIB_API void(luaL_checktype)(lua_State *L, int narg, int t); +LUALIB_API void(luaL_checkany)(lua_State *L, int narg); -LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); -LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t); -LUALIB_API void (luaL_checkany) (lua_State *L, int narg); +LUALIB_API int(luaL_newmetatable)(lua_State *L, const char *tname); +LUALIB_API void(luaL_setmetatable)(lua_State *L, const char *tname); +LUALIB_API void *(luaL_testudata)(lua_State *L, int ud, const char *tname); +LUALIB_API void *(luaL_checkudata)(lua_State *L, int ud, const char *tname); -LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); -LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); -LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname); -LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); +LUALIB_API void(luaL_where)(lua_State *L, int lvl); +LUALIB_API int(luaL_error)(lua_State *L, const char *fmt, ...); -LUALIB_API void (luaL_where) (lua_State *L, int lvl); -LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); +LUALIB_API int(luaL_checkoption)(lua_State *L, int narg, const char *def, + const char *const lst[]); -LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def, - const char *const lst[]); - -LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); -LUALIB_API int (luaL_execresult) (lua_State *L, int stat); +LUALIB_API int(luaL_fileresult)(lua_State *L, int stat, const char *fname); +LUALIB_API int(luaL_execresult)(lua_State *L, int stat); /* pre-defined references */ -#define LUA_NOREF (-2) -#define LUA_REFNIL (-1) +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) -LUALIB_API int (luaL_ref) (lua_State *L, int t); -LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); +LUALIB_API int(luaL_ref)(lua_State *L, int t); +LUALIB_API void(luaL_unref)(lua_State *L, int t, int ref); -LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, - const char *mode); +LUALIB_API int(luaL_loadfilex)(lua_State *L, const char *filename, + const char *mode); -#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL) +#define luaL_loadfile(L, f) luaL_loadfilex(L, f, NULL) -LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, - const char *name, const char *mode); -LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); +LUALIB_API int(luaL_loadbufferx)(lua_State *L, const char *buff, size_t sz, + const char *name, const char *mode); +LUALIB_API int(luaL_loadstring)(lua_State *L, const char *s); -LUALIB_API lua_State *(luaL_newstate) (void); +LUALIB_API lua_State *(luaL_newstate)(void); -LUALIB_API int (luaL_len) (lua_State *L, int idx); +LUALIB_API int(luaL_len)(lua_State *L, int idx); -LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, - const char *r); +LUALIB_API const char *(luaL_gsub)(lua_State *L, const char *s, const char *p, + const char *r); -LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); +LUALIB_API void(luaL_setfuncs)(lua_State *L, const luaL_Reg *l, int nup); -LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname); +LUALIB_API int(luaL_getsubtable)(lua_State *L, int idx, const char *fname); -LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, - const char *msg, int level); +LUALIB_API void(luaL_traceback)(lua_State *L, lua_State *L1, + const char *msg, int level); -LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, - lua_CFunction openf, int glb); +LUALIB_API void(luaL_requiref)(lua_State *L, const char *modname, + lua_CFunction openf, int glb); /* ** =============================================================== @@ -104,22 +99,21 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, ** =============================================================== */ +#define luaL_newlibtable(L, l) \ + lua_createtable(L, 0, sizeof(l) / sizeof((l)[0]) - 1) -#define luaL_newlibtable(L,l) \ - lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) +#define luaL_newlib(L, l) (luaL_newlibtable(L, l), luaL_setfuncs(L, l, 0)) -#define luaL_newlib(L,l) (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) +#define luaL_argcheck(L, cond, numarg, extramsg) \ + ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) +#define luaL_checkstring(L, n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L, n, d) (luaL_optlstring(L, (n), (d), NULL)) +#define luaL_checkint(L, n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L, n, d) ((int)luaL_optinteger(L, (n), (d))) +#define luaL_checklong(L, n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L, n, d) ((long)luaL_optinteger(L, (n), (d))) -#define luaL_argcheck(L, cond,numarg,extramsg) \ - ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) -#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) -#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) -#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) -#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) -#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) -#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) - -#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) +#define luaL_typename(L, i) lua_typename(L, lua_type(L, (i))) #define luaL_dofile(L, fn) \ (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) @@ -127,12 +121,11 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, #define luaL_dostring(L, s) \ (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) -#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) +#define luaL_getmetatable(L, n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) -#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) - -#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) +#define luaL_opt(L, f, n, d) (lua_isnoneornil(L, (n)) ? (d) : f(L, (n))) +#define luaL_loadbuffer(L, s, sz, n) luaL_loadbufferx(L, s, sz, n, NULL) /* ** {====================================================== @@ -140,36 +133,34 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, ** ======================================================= */ -typedef struct luaL_Buffer { - char *b; /* buffer address */ - size_t size; /* buffer size */ - size_t n; /* number of characters in buffer */ - lua_State *L; - char initb[LUAL_BUFFERSIZE]; /* initial buffer */ +typedef struct luaL_Buffer +{ + char *b; /* buffer address */ + size_t size; /* buffer size */ + size_t n; /* number of characters in buffer */ + lua_State *L; + char initb[LUAL_BUFFERSIZE]; /* initial buffer */ } luaL_Buffer; +#define luaL_addchar(B, c) \ + ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \ + ((B)->b[(B)->n++] = (c))) -#define luaL_addchar(B,c) \ - ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \ - ((B)->b[(B)->n++] = (c))) +#define luaL_addsize(B, s) ((B)->n += (s)) -#define luaL_addsize(B,s) ((B)->n += (s)) +LUALIB_API void(luaL_buffinit)(lua_State *L, luaL_Buffer *B); +LUALIB_API char *(luaL_prepbuffsize)(luaL_Buffer *B, size_t sz); +LUALIB_API void(luaL_addlstring)(luaL_Buffer *B, const char *s, size_t l); +LUALIB_API void(luaL_addstring)(luaL_Buffer *B, const char *s); +LUALIB_API void(luaL_addvalue)(luaL_Buffer *B); +LUALIB_API void(luaL_pushresult)(luaL_Buffer *B); +LUALIB_API void(luaL_pushresultsize)(luaL_Buffer *B, size_t sz); +LUALIB_API char *(luaL_buffinitsize)(lua_State *L, luaL_Buffer *B, size_t sz); -LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); -LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); -LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); -LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); -LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); -LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); -LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz); -LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); - -#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) +#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) /* }====================================================== */ - - /* ** {====================================================== ** File handles for IO library @@ -182,31 +173,26 @@ LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); ** after that initial structure). */ -#define LUA_FILEHANDLE "FILE*" +#define LUA_FILEHANDLE "FILE*" - -typedef struct luaL_Stream { - FILE *f; /* stream (NULL for incompletely created streams) */ - lua_CFunction closef; /* to close stream (NULL for closed streams) */ +typedef struct luaL_Stream +{ + FILE *f; /* stream (NULL for incompletely created streams) */ + lua_CFunction closef; /* to close stream (NULL for closed streams) */ } luaL_Stream; /* }====================================================== */ - - /* compatibility with old module system */ #if defined(LUA_COMPAT_MODULE) -LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname, - int sizehint); -LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, - const luaL_Reg *l, int nup); +LUALIB_API void(luaL_pushmodule)(lua_State *L, const char *modname, + int sizehint); +LUALIB_API void(luaL_openlib)(lua_State *L, const char *libname, + const luaL_Reg *l, int nup); -#define luaL_register(L,n,l) (luaL_openlib(L,(n),(l),0)) +#define luaL_register(L, n, l) (luaL_openlib(L, (n), (l), 0)) #endif - #endif - - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lbaselib.c b/examples/ThirdPartyLibs/lua-5.2.3/src/lbaselib.c index 5255b3cd9..aa77c97b1 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lbaselib.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lbaselib.c @@ -4,8 +4,6 @@ ** See Copyright Notice in lua.h */ - - #include #include #include @@ -19,269 +17,294 @@ #include "lauxlib.h" #include "lualib.h" - -static int luaB_print (lua_State *L) { - int n = lua_gettop(L); /* number of arguments */ - int i; - lua_getglobal(L, "tostring"); - for (i=1; i<=n; i++) { - const char *s; - size_t l; - lua_pushvalue(L, -1); /* function to be called */ - lua_pushvalue(L, i); /* value to print */ - lua_call(L, 1, 1); - s = lua_tolstring(L, -1, &l); /* get result */ - if (s == NULL) - return luaL_error(L, - LUA_QL("tostring") " must return a string to " LUA_QL("print")); - if (i>1) luai_writestring("\t", 1); - luai_writestring(s, l); - lua_pop(L, 1); /* pop result */ - } - luai_writeline(); - return 0; +static int luaB_print(lua_State *L) +{ + int n = lua_gettop(L); /* number of arguments */ + int i; + lua_getglobal(L, "tostring"); + for (i = 1; i <= n; i++) + { + const char *s; + size_t l; + lua_pushvalue(L, -1); /* function to be called */ + lua_pushvalue(L, i); /* value to print */ + lua_call(L, 1, 1); + s = lua_tolstring(L, -1, &l); /* get result */ + if (s == NULL) + return luaL_error(L, + LUA_QL("tostring") " must return a string to " LUA_QL("print")); + if (i > 1) luai_writestring("\t", 1); + luai_writestring(s, l); + lua_pop(L, 1); /* pop result */ + } + luai_writeline(); + return 0; } +#define SPACECHARS " \f\n\r\t\v" -#define SPACECHARS " \f\n\r\t\v" - -static int luaB_tonumber (lua_State *L) { - if (lua_isnoneornil(L, 2)) { /* standard conversion */ - int isnum; - lua_Number n = lua_tonumberx(L, 1, &isnum); - if (isnum) { - lua_pushnumber(L, n); - return 1; - } /* else not a number; must be something */ - luaL_checkany(L, 1); - } - else { - size_t l; - const char *s = luaL_checklstring(L, 1, &l); - const char *e = s + l; /* end point for 's' */ - int base = luaL_checkint(L, 2); - int neg = 0; - luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); - s += strspn(s, SPACECHARS); /* skip initial spaces */ - if (*s == '-') { s++; neg = 1; } /* handle signal */ - else if (*s == '+') s++; - if (isalnum((unsigned char)*s)) { - lua_Number n = 0; - do { - int digit = (isdigit((unsigned char)*s)) ? *s - '0' - : toupper((unsigned char)*s) - 'A' + 10; - if (digit >= base) break; /* invalid numeral; force a fail */ - n = n * (lua_Number)base + (lua_Number)digit; - s++; - } while (isalnum((unsigned char)*s)); - s += strspn(s, SPACECHARS); /* skip trailing spaces */ - if (s == e) { /* no invalid trailing characters? */ - lua_pushnumber(L, (neg) ? -n : n); - return 1; - } /* else not a number */ - } /* else not a number */ - } - lua_pushnil(L); /* not a number */ - return 1; +static int luaB_tonumber(lua_State *L) +{ + if (lua_isnoneornil(L, 2)) + { /* standard conversion */ + int isnum; + lua_Number n = lua_tonumberx(L, 1, &isnum); + if (isnum) + { + lua_pushnumber(L, n); + return 1; + } /* else not a number; must be something */ + luaL_checkany(L, 1); + } + else + { + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + const char *e = s + l; /* end point for 's' */ + int base = luaL_checkint(L, 2); + int neg = 0; + luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range"); + s += strspn(s, SPACECHARS); /* skip initial spaces */ + if (*s == '-') + { + s++; + neg = 1; + } /* handle signal */ + else if (*s == '+') + s++; + if (isalnum((unsigned char)*s)) + { + lua_Number n = 0; + do + { + int digit = (isdigit((unsigned char)*s)) ? *s - '0' + : toupper((unsigned char)*s) - 'A' + 10; + if (digit >= base) break; /* invalid numeral; force a fail */ + n = n * (lua_Number)base + (lua_Number)digit; + s++; + } while (isalnum((unsigned char)*s)); + s += strspn(s, SPACECHARS); /* skip trailing spaces */ + if (s == e) + { /* no invalid trailing characters? */ + lua_pushnumber(L, (neg) ? -n : n); + return 1; + } /* else not a number */ + } /* else not a number */ + } + lua_pushnil(L); /* not a number */ + return 1; } - -static int luaB_error (lua_State *L) { - int level = luaL_optint(L, 2, 1); - lua_settop(L, 1); - if (lua_isstring(L, 1) && level > 0) { /* add extra information? */ - luaL_where(L, level); - lua_pushvalue(L, 1); - lua_concat(L, 2); - } - return lua_error(L); +static int luaB_error(lua_State *L) +{ + int level = luaL_optint(L, 2, 1); + lua_settop(L, 1); + if (lua_isstring(L, 1) && level > 0) + { /* add extra information? */ + luaL_where(L, level); + lua_pushvalue(L, 1); + lua_concat(L, 2); + } + return lua_error(L); } - -static int luaB_getmetatable (lua_State *L) { - luaL_checkany(L, 1); - if (!lua_getmetatable(L, 1)) { - lua_pushnil(L); - return 1; /* no metatable */ - } - luaL_getmetafield(L, 1, "__metatable"); - return 1; /* returns either __metatable field (if present) or metatable */ +static int luaB_getmetatable(lua_State *L) +{ + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) + { + lua_pushnil(L); + return 1; /* no metatable */ + } + luaL_getmetafield(L, 1, "__metatable"); + return 1; /* returns either __metatable field (if present) or metatable */ } - -static int luaB_setmetatable (lua_State *L) { - int t = lua_type(L, 2); - luaL_checktype(L, 1, LUA_TTABLE); - luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, - "nil or table expected"); - if (luaL_getmetafield(L, 1, "__metatable")) - return luaL_error(L, "cannot change a protected metatable"); - lua_settop(L, 2); - lua_setmetatable(L, 1); - return 1; +static int luaB_setmetatable(lua_State *L) +{ + int t = lua_type(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, + "nil or table expected"); + if (luaL_getmetafield(L, 1, "__metatable")) + return luaL_error(L, "cannot change a protected metatable"); + lua_settop(L, 2); + lua_setmetatable(L, 1); + return 1; } - -static int luaB_rawequal (lua_State *L) { - luaL_checkany(L, 1); - luaL_checkany(L, 2); - lua_pushboolean(L, lua_rawequal(L, 1, 2)); - return 1; +static int luaB_rawequal(lua_State *L) +{ + luaL_checkany(L, 1); + luaL_checkany(L, 2); + lua_pushboolean(L, lua_rawequal(L, 1, 2)); + return 1; } - -static int luaB_rawlen (lua_State *L) { - int t = lua_type(L, 1); - luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1, - "table or string expected"); - lua_pushinteger(L, lua_rawlen(L, 1)); - return 1; +static int luaB_rawlen(lua_State *L) +{ + int t = lua_type(L, 1); + luaL_argcheck(L, t == LUA_TTABLE || t == LUA_TSTRING, 1, + "table or string expected"); + lua_pushinteger(L, lua_rawlen(L, 1)); + return 1; } - -static int luaB_rawget (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - luaL_checkany(L, 2); - lua_settop(L, 2); - lua_rawget(L, 1); - return 1; +static int luaB_rawget(lua_State *L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + lua_settop(L, 2); + lua_rawget(L, 1); + return 1; } -static int luaB_rawset (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - luaL_checkany(L, 2); - luaL_checkany(L, 3); - lua_settop(L, 3); - lua_rawset(L, 1); - return 1; +static int luaB_rawset(lua_State *L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + luaL_checkany(L, 2); + luaL_checkany(L, 3); + lua_settop(L, 3); + lua_rawset(L, 1); + return 1; } - -static int luaB_collectgarbage (lua_State *L) { - static const char *const opts[] = {"stop", "restart", "collect", - "count", "step", "setpause", "setstepmul", - "setmajorinc", "isrunning", "generational", "incremental", NULL}; - static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, - LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, - LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC}; - int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; - int ex = luaL_optint(L, 2, 0); - int res = lua_gc(L, o, ex); - switch (o) { - case LUA_GCCOUNT: { - int b = lua_gc(L, LUA_GCCOUNTB, 0); - lua_pushnumber(L, res + ((lua_Number)b/1024)); - lua_pushinteger(L, b); - return 2; - } - case LUA_GCSTEP: case LUA_GCISRUNNING: { - lua_pushboolean(L, res); - return 1; - } - default: { - lua_pushinteger(L, res); - return 1; - } - } +static int luaB_collectgarbage(lua_State *L) +{ + static const char *const opts[] = {"stop", "restart", "collect", + "count", "step", "setpause", "setstepmul", + "setmajorinc", "isrunning", "generational", "incremental", NULL}; + static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT, + LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL, + LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC}; + int o = optsnum[luaL_checkoption(L, 1, "collect", opts)]; + int ex = luaL_optint(L, 2, 0); + int res = lua_gc(L, o, ex); + switch (o) + { + case LUA_GCCOUNT: + { + int b = lua_gc(L, LUA_GCCOUNTB, 0); + lua_pushnumber(L, res + ((lua_Number)b / 1024)); + lua_pushinteger(L, b); + return 2; + } + case LUA_GCSTEP: + case LUA_GCISRUNNING: + { + lua_pushboolean(L, res); + return 1; + } + default: + { + lua_pushinteger(L, res); + return 1; + } + } } - -static int luaB_type (lua_State *L) { - luaL_checkany(L, 1); - lua_pushstring(L, luaL_typename(L, 1)); - return 1; +static int luaB_type(lua_State *L) +{ + luaL_checkany(L, 1); + lua_pushstring(L, luaL_typename(L, 1)); + return 1; } - -static int pairsmeta (lua_State *L, const char *method, int iszero, - lua_CFunction iter) { - if (!luaL_getmetafield(L, 1, method)) { /* no metamethod? */ - luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */ - lua_pushcfunction(L, iter); /* will return generator, */ - lua_pushvalue(L, 1); /* state, */ - if (iszero) lua_pushinteger(L, 0); /* and initial value */ - else lua_pushnil(L); - } - else { - lua_pushvalue(L, 1); /* argument 'self' to metamethod */ - lua_call(L, 1, 3); /* get 3 values from metamethod */ - } - return 3; +static int pairsmeta(lua_State *L, const char *method, int iszero, + lua_CFunction iter) +{ + if (!luaL_getmetafield(L, 1, method)) + { /* no metamethod? */ + luaL_checktype(L, 1, LUA_TTABLE); /* argument must be a table */ + lua_pushcfunction(L, iter); /* will return generator, */ + lua_pushvalue(L, 1); /* state, */ + if (iszero) + lua_pushinteger(L, 0); /* and initial value */ + else + lua_pushnil(L); + } + else + { + lua_pushvalue(L, 1); /* argument 'self' to metamethod */ + lua_call(L, 1, 3); /* get 3 values from metamethod */ + } + return 3; } - -static int luaB_next (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - lua_settop(L, 2); /* create a 2nd argument if there isn't one */ - if (lua_next(L, 1)) - return 2; - else { - lua_pushnil(L); - return 1; - } +static int luaB_next(lua_State *L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 2); /* create a 2nd argument if there isn't one */ + if (lua_next(L, 1)) + return 2; + else + { + lua_pushnil(L); + return 1; + } } - -static int luaB_pairs (lua_State *L) { - return pairsmeta(L, "__pairs", 0, luaB_next); +static int luaB_pairs(lua_State *L) +{ + return pairsmeta(L, "__pairs", 0, luaB_next); } - -static int ipairsaux (lua_State *L) { - int i = luaL_checkint(L, 2); - luaL_checktype(L, 1, LUA_TTABLE); - i++; /* next value */ - lua_pushinteger(L, i); - lua_rawgeti(L, 1, i); - return (lua_isnil(L, -1)) ? 1 : 2; +static int ipairsaux(lua_State *L) +{ + int i = luaL_checkint(L, 2); + luaL_checktype(L, 1, LUA_TTABLE); + i++; /* next value */ + lua_pushinteger(L, i); + lua_rawgeti(L, 1, i); + return (lua_isnil(L, -1)) ? 1 : 2; } - -static int luaB_ipairs (lua_State *L) { - return pairsmeta(L, "__ipairs", 1, ipairsaux); +static int luaB_ipairs(lua_State *L) +{ + return pairsmeta(L, "__ipairs", 1, ipairsaux); } - -static int load_aux (lua_State *L, int status, int envidx) { - if (status == LUA_OK) { - if (envidx != 0) { /* 'env' parameter? */ - lua_pushvalue(L, envidx); /* environment for loaded function */ - if (!lua_setupvalue(L, -2, 1)) /* set it as 1st upvalue */ - lua_pop(L, 1); /* remove 'env' if not used by previous call */ - } - return 1; - } - else { /* error (message is on top of the stack) */ - lua_pushnil(L); - lua_insert(L, -2); /* put before error message */ - return 2; /* return nil plus error message */ - } +static int load_aux(lua_State *L, int status, int envidx) +{ + if (status == LUA_OK) + { + if (envidx != 0) + { /* 'env' parameter? */ + lua_pushvalue(L, envidx); /* environment for loaded function */ + if (!lua_setupvalue(L, -2, 1)) /* set it as 1st upvalue */ + lua_pop(L, 1); /* remove 'env' if not used by previous call */ + } + return 1; + } + else + { /* error (message is on top of the stack) */ + lua_pushnil(L); + lua_insert(L, -2); /* put before error message */ + return 2; /* return nil plus error message */ + } } - -static int luaB_loadfile (lua_State *L) { - const char *fname = luaL_optstring(L, 1, NULL); - const char *mode = luaL_optstring(L, 2, NULL); - int env = (!lua_isnone(L, 3) ? 3 : 0); /* 'env' index or 0 if no 'env' */ - int status = luaL_loadfilex(L, fname, mode); - return load_aux(L, status, env); +static int luaB_loadfile(lua_State *L) +{ + const char *fname = luaL_optstring(L, 1, NULL); + const char *mode = luaL_optstring(L, 2, NULL); + int env = (!lua_isnone(L, 3) ? 3 : 0); /* 'env' index or 0 if no 'env' */ + int status = luaL_loadfilex(L, fname, mode); + return load_aux(L, status, env); } - /* ** {====================================================== ** Generic Read function ** ======================================================= */ - /* ** reserved slot, above all arguments, to hold a copy of the returned ** string to avoid it being collected while parsed. 'load' has four ** optional arguments (chunk, source name, mode, and environment). */ -#define RESERVEDSLOT 5 - +#define RESERVEDSLOT 5 /* ** Reader for generic `load' function: `lua_load' uses the @@ -289,170 +312,176 @@ static int luaB_loadfile (lua_State *L) { ** stack top. Instead, it keeps its resulting string in a ** reserved slot inside the stack. */ -static const char *generic_reader (lua_State *L, void *ud, size_t *size) { - (void)(ud); /* not used */ - luaL_checkstack(L, 2, "too many nested functions"); - lua_pushvalue(L, 1); /* get function */ - lua_call(L, 0, 1); /* call it */ - if (lua_isnil(L, -1)) { - lua_pop(L, 1); /* pop result */ - *size = 0; - return NULL; - } - else if (!lua_isstring(L, -1)) - luaL_error(L, "reader function must return a string"); - lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */ - return lua_tolstring(L, RESERVEDSLOT, size); +static const char *generic_reader(lua_State *L, void *ud, size_t *size) +{ + (void)(ud); /* not used */ + luaL_checkstack(L, 2, "too many nested functions"); + lua_pushvalue(L, 1); /* get function */ + lua_call(L, 0, 1); /* call it */ + if (lua_isnil(L, -1)) + { + lua_pop(L, 1); /* pop result */ + *size = 0; + return NULL; + } + else if (!lua_isstring(L, -1)) + luaL_error(L, "reader function must return a string"); + lua_replace(L, RESERVEDSLOT); /* save string in reserved slot */ + return lua_tolstring(L, RESERVEDSLOT, size); } - -static int luaB_load (lua_State *L) { - int status; - size_t l; - const char *s = lua_tolstring(L, 1, &l); - const char *mode = luaL_optstring(L, 3, "bt"); - int env = (!lua_isnone(L, 4) ? 4 : 0); /* 'env' index or 0 if no 'env' */ - if (s != NULL) { /* loading a string? */ - const char *chunkname = luaL_optstring(L, 2, s); - status = luaL_loadbufferx(L, s, l, chunkname, mode); - } - else { /* loading from a reader function */ - const char *chunkname = luaL_optstring(L, 2, "=(load)"); - luaL_checktype(L, 1, LUA_TFUNCTION); - lua_settop(L, RESERVEDSLOT); /* create reserved slot */ - status = lua_load(L, generic_reader, NULL, chunkname, mode); - } - return load_aux(L, status, env); +static int luaB_load(lua_State *L) +{ + int status; + size_t l; + const char *s = lua_tolstring(L, 1, &l); + const char *mode = luaL_optstring(L, 3, "bt"); + int env = (!lua_isnone(L, 4) ? 4 : 0); /* 'env' index or 0 if no 'env' */ + if (s != NULL) + { /* loading a string? */ + const char *chunkname = luaL_optstring(L, 2, s); + status = luaL_loadbufferx(L, s, l, chunkname, mode); + } + else + { /* loading from a reader function */ + const char *chunkname = luaL_optstring(L, 2, "=(load)"); + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_settop(L, RESERVEDSLOT); /* create reserved slot */ + status = lua_load(L, generic_reader, NULL, chunkname, mode); + } + return load_aux(L, status, env); } /* }====================================================== */ - -static int dofilecont (lua_State *L) { - return lua_gettop(L) - 1; +static int dofilecont(lua_State *L) +{ + return lua_gettop(L) - 1; } - -static int luaB_dofile (lua_State *L) { - const char *fname = luaL_optstring(L, 1, NULL); - lua_settop(L, 1); - if (luaL_loadfile(L, fname) != LUA_OK) - return lua_error(L); - lua_callk(L, 0, LUA_MULTRET, 0, dofilecont); - return dofilecont(L); +static int luaB_dofile(lua_State *L) +{ + const char *fname = luaL_optstring(L, 1, NULL); + lua_settop(L, 1); + if (luaL_loadfile(L, fname) != LUA_OK) + return lua_error(L); + lua_callk(L, 0, LUA_MULTRET, 0, dofilecont); + return dofilecont(L); } - -static int luaB_assert (lua_State *L) { - if (!lua_toboolean(L, 1)) - return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); - return lua_gettop(L); +static int luaB_assert(lua_State *L) +{ + if (!lua_toboolean(L, 1)) + return luaL_error(L, "%s", luaL_optstring(L, 2, "assertion failed!")); + return lua_gettop(L); } - -static int luaB_select (lua_State *L) { - int n = lua_gettop(L); - if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') { - lua_pushinteger(L, n-1); - return 1; - } - else { - int i = luaL_checkint(L, 1); - if (i < 0) i = n + i; - else if (i > n) i = n; - luaL_argcheck(L, 1 <= i, 1, "index out of range"); - return n - i; - } +static int luaB_select(lua_State *L) +{ + int n = lua_gettop(L); + if (lua_type(L, 1) == LUA_TSTRING && *lua_tostring(L, 1) == '#') + { + lua_pushinteger(L, n - 1); + return 1; + } + else + { + int i = luaL_checkint(L, 1); + if (i < 0) + i = n + i; + else if (i > n) + i = n; + luaL_argcheck(L, 1 <= i, 1, "index out of range"); + return n - i; + } } - -static int finishpcall (lua_State *L, int status) { - if (!lua_checkstack(L, 1)) { /* no space for extra boolean? */ - lua_settop(L, 0); /* create space for return values */ - lua_pushboolean(L, 0); - lua_pushstring(L, "stack overflow"); - return 2; /* return false, msg */ - } - lua_pushboolean(L, status); /* first result (status) */ - lua_replace(L, 1); /* put first result in first slot */ - return lua_gettop(L); +static int finishpcall(lua_State *L, int status) +{ + if (!lua_checkstack(L, 1)) + { /* no space for extra boolean? */ + lua_settop(L, 0); /* create space for return values */ + lua_pushboolean(L, 0); + lua_pushstring(L, "stack overflow"); + return 2; /* return false, msg */ + } + lua_pushboolean(L, status); /* first result (status) */ + lua_replace(L, 1); /* put first result in first slot */ + return lua_gettop(L); } - -static int pcallcont (lua_State *L) { - int status = lua_getctx(L, NULL); - return finishpcall(L, (status == LUA_YIELD)); +static int pcallcont(lua_State *L) +{ + int status = lua_getctx(L, NULL); + return finishpcall(L, (status == LUA_YIELD)); } - -static int luaB_pcall (lua_State *L) { - int status; - luaL_checkany(L, 1); - lua_pushnil(L); - lua_insert(L, 1); /* create space for status result */ - status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, pcallcont); - return finishpcall(L, (status == LUA_OK)); +static int luaB_pcall(lua_State *L) +{ + int status; + luaL_checkany(L, 1); + lua_pushnil(L); + lua_insert(L, 1); /* create space for status result */ + status = lua_pcallk(L, lua_gettop(L) - 2, LUA_MULTRET, 0, 0, pcallcont); + return finishpcall(L, (status == LUA_OK)); } - -static int luaB_xpcall (lua_State *L) { - int status; - int n = lua_gettop(L); - luaL_argcheck(L, n >= 2, 2, "value expected"); - lua_pushvalue(L, 1); /* exchange function... */ - lua_copy(L, 2, 1); /* ...and error handler */ - lua_replace(L, 2); - status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 0, pcallcont); - return finishpcall(L, (status == LUA_OK)); +static int luaB_xpcall(lua_State *L) +{ + int status; + int n = lua_gettop(L); + luaL_argcheck(L, n >= 2, 2, "value expected"); + lua_pushvalue(L, 1); /* exchange function... */ + lua_copy(L, 2, 1); /* ...and error handler */ + lua_replace(L, 2); + status = lua_pcallk(L, n - 2, LUA_MULTRET, 1, 0, pcallcont); + return finishpcall(L, (status == LUA_OK)); } - -static int luaB_tostring (lua_State *L) { - luaL_checkany(L, 1); - luaL_tolstring(L, 1, NULL); - return 1; +static int luaB_tostring(lua_State *L) +{ + luaL_checkany(L, 1); + luaL_tolstring(L, 1, NULL); + return 1; } - static const luaL_Reg base_funcs[] = { - {"assert", luaB_assert}, - {"collectgarbage", luaB_collectgarbage}, - {"dofile", luaB_dofile}, - {"error", luaB_error}, - {"getmetatable", luaB_getmetatable}, - {"ipairs", luaB_ipairs}, - {"loadfile", luaB_loadfile}, - {"load", luaB_load}, + {"assert", luaB_assert}, + {"collectgarbage", luaB_collectgarbage}, + {"dofile", luaB_dofile}, + {"error", luaB_error}, + {"getmetatable", luaB_getmetatable}, + {"ipairs", luaB_ipairs}, + {"loadfile", luaB_loadfile}, + {"load", luaB_load}, #if defined(LUA_COMPAT_LOADSTRING) - {"loadstring", luaB_load}, + {"loadstring", luaB_load}, #endif - {"next", luaB_next}, - {"pairs", luaB_pairs}, - {"pcall", luaB_pcall}, - {"print", luaB_print}, - {"rawequal", luaB_rawequal}, - {"rawlen", luaB_rawlen}, - {"rawget", luaB_rawget}, - {"rawset", luaB_rawset}, - {"select", luaB_select}, - {"setmetatable", luaB_setmetatable}, - {"tonumber", luaB_tonumber}, - {"tostring", luaB_tostring}, - {"type", luaB_type}, - {"xpcall", luaB_xpcall}, - {NULL, NULL} -}; + {"next", luaB_next}, + {"pairs", luaB_pairs}, + {"pcall", luaB_pcall}, + {"print", luaB_print}, + {"rawequal", luaB_rawequal}, + {"rawlen", luaB_rawlen}, + {"rawget", luaB_rawget}, + {"rawset", luaB_rawset}, + {"select", luaB_select}, + {"setmetatable", luaB_setmetatable}, + {"tonumber", luaB_tonumber}, + {"tostring", luaB_tostring}, + {"type", luaB_type}, + {"xpcall", luaB_xpcall}, + {NULL, NULL}}; - -LUAMOD_API int luaopen_base (lua_State *L) { - /* set global _G */ - lua_pushglobaltable(L); - lua_pushglobaltable(L); - lua_setfield(L, -2, "_G"); - /* open lib into global table */ - luaL_setfuncs(L, base_funcs, 0); - lua_pushliteral(L, LUA_VERSION); - lua_setfield(L, -2, "_VERSION"); /* set global _VERSION */ - return 1; +LUAMOD_API int luaopen_base(lua_State *L) +{ + /* set global _G */ + lua_pushglobaltable(L); + lua_pushglobaltable(L); + lua_setfield(L, -2, "_G"); + /* open lib into global table */ + luaL_setfuncs(L, base_funcs, 0); + lua_pushliteral(L, LUA_VERSION); + lua_setfield(L, -2, "_VERSION"); /* set global _VERSION */ + return 1; } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lbitlib.c b/examples/ThirdPartyLibs/lua-5.2.3/src/lbitlib.c index 31c7b66f1..e506e1dee 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lbitlib.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lbitlib.c @@ -12,201 +12,200 @@ #include "lauxlib.h" #include "lualib.h" - /* number of bits to consider in a number */ #if !defined(LUA_NBITS) -#define LUA_NBITS 32 +#define LUA_NBITS 32 #endif - -#define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1)) +#define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1)) /* macro to trim extra bits */ -#define trim(x) ((x) & ALLONES) - +#define trim(x) ((x)&ALLONES) /* builds a number with 'n' ones (1 <= n <= LUA_NBITS) */ -#define mask(n) (~((ALLONES << 1) << ((n) - 1))) - +#define mask(n) (~((ALLONES << 1) << ((n)-1))) typedef lua_Unsigned b_uint; - - -static b_uint andaux (lua_State *L) { - int i, n = lua_gettop(L); - b_uint r = ~(b_uint)0; - for (i = 1; i <= n; i++) - r &= luaL_checkunsigned(L, i); - return trim(r); +static b_uint andaux(lua_State *L) +{ + int i, n = lua_gettop(L); + b_uint r = ~(b_uint)0; + for (i = 1; i <= n; i++) + r &= luaL_checkunsigned(L, i); + return trim(r); } - -static int b_and (lua_State *L) { - b_uint r = andaux(L); - lua_pushunsigned(L, r); - return 1; +static int b_and(lua_State *L) +{ + b_uint r = andaux(L); + lua_pushunsigned(L, r); + return 1; } - -static int b_test (lua_State *L) { - b_uint r = andaux(L); - lua_pushboolean(L, r != 0); - return 1; +static int b_test(lua_State *L) +{ + b_uint r = andaux(L); + lua_pushboolean(L, r != 0); + return 1; } - -static int b_or (lua_State *L) { - int i, n = lua_gettop(L); - b_uint r = 0; - for (i = 1; i <= n; i++) - r |= luaL_checkunsigned(L, i); - lua_pushunsigned(L, trim(r)); - return 1; +static int b_or(lua_State *L) +{ + int i, n = lua_gettop(L); + b_uint r = 0; + for (i = 1; i <= n; i++) + r |= luaL_checkunsigned(L, i); + lua_pushunsigned(L, trim(r)); + return 1; } - -static int b_xor (lua_State *L) { - int i, n = lua_gettop(L); - b_uint r = 0; - for (i = 1; i <= n; i++) - r ^= luaL_checkunsigned(L, i); - lua_pushunsigned(L, trim(r)); - return 1; +static int b_xor(lua_State *L) +{ + int i, n = lua_gettop(L); + b_uint r = 0; + for (i = 1; i <= n; i++) + r ^= luaL_checkunsigned(L, i); + lua_pushunsigned(L, trim(r)); + return 1; } - -static int b_not (lua_State *L) { - b_uint r = ~luaL_checkunsigned(L, 1); - lua_pushunsigned(L, trim(r)); - return 1; +static int b_not(lua_State *L) +{ + b_uint r = ~luaL_checkunsigned(L, 1); + lua_pushunsigned(L, trim(r)); + return 1; } - -static int b_shift (lua_State *L, b_uint r, int i) { - if (i < 0) { /* shift right? */ - i = -i; - r = trim(r); - if (i >= LUA_NBITS) r = 0; - else r >>= i; - } - else { /* shift left */ - if (i >= LUA_NBITS) r = 0; - else r <<= i; - r = trim(r); - } - lua_pushunsigned(L, r); - return 1; +static int b_shift(lua_State *L, b_uint r, int i) +{ + if (i < 0) + { /* shift right? */ + i = -i; + r = trim(r); + if (i >= LUA_NBITS) + r = 0; + else + r >>= i; + } + else + { /* shift left */ + if (i >= LUA_NBITS) + r = 0; + else + r <<= i; + r = trim(r); + } + lua_pushunsigned(L, r); + return 1; } - -static int b_lshift (lua_State *L) { - return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2)); +static int b_lshift(lua_State *L) +{ + return b_shift(L, luaL_checkunsigned(L, 1), luaL_checkint(L, 2)); } - -static int b_rshift (lua_State *L) { - return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2)); +static int b_rshift(lua_State *L) +{ + return b_shift(L, luaL_checkunsigned(L, 1), -luaL_checkint(L, 2)); } - -static int b_arshift (lua_State *L) { - b_uint r = luaL_checkunsigned(L, 1); - int i = luaL_checkint(L, 2); - if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1)))) - return b_shift(L, r, -i); - else { /* arithmetic shift for 'negative' number */ - if (i >= LUA_NBITS) r = ALLONES; - else - r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */ - lua_pushunsigned(L, r); - return 1; - } +static int b_arshift(lua_State *L) +{ + b_uint r = luaL_checkunsigned(L, 1); + int i = luaL_checkint(L, 2); + if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1)))) + return b_shift(L, r, -i); + else + { /* arithmetic shift for 'negative' number */ + if (i >= LUA_NBITS) + r = ALLONES; + else + r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */ + lua_pushunsigned(L, r); + return 1; + } } - -static int b_rot (lua_State *L, int i) { - b_uint r = luaL_checkunsigned(L, 1); - i &= (LUA_NBITS - 1); /* i = i % NBITS */ - r = trim(r); - if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */ - r = (r << i) | (r >> (LUA_NBITS - i)); - lua_pushunsigned(L, trim(r)); - return 1; +static int b_rot(lua_State *L, int i) +{ + b_uint r = luaL_checkunsigned(L, 1); + i &= (LUA_NBITS - 1); /* i = i % NBITS */ + r = trim(r); + if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */ + r = (r << i) | (r >> (LUA_NBITS - i)); + lua_pushunsigned(L, trim(r)); + return 1; } - -static int b_lrot (lua_State *L) { - return b_rot(L, luaL_checkint(L, 2)); +static int b_lrot(lua_State *L) +{ + return b_rot(L, luaL_checkint(L, 2)); } - -static int b_rrot (lua_State *L) { - return b_rot(L, -luaL_checkint(L, 2)); +static int b_rrot(lua_State *L) +{ + return b_rot(L, -luaL_checkint(L, 2)); } - /* ** get field and width arguments for field-manipulation functions, ** checking whether they are valid. ** ('luaL_error' called without 'return' to avoid later warnings about ** 'width' being used uninitialized.) */ -static int fieldargs (lua_State *L, int farg, int *width) { - int f = luaL_checkint(L, farg); - int w = luaL_optint(L, farg + 1, 1); - luaL_argcheck(L, 0 <= f, farg, "field cannot be negative"); - luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); - if (f + w > LUA_NBITS) - luaL_error(L, "trying to access non-existent bits"); - *width = w; - return f; +static int fieldargs(lua_State *L, int farg, int *width) +{ + int f = luaL_checkint(L, farg); + int w = luaL_optint(L, farg + 1, 1); + luaL_argcheck(L, 0 <= f, farg, "field cannot be negative"); + luaL_argcheck(L, 0 < w, farg + 1, "width must be positive"); + if (f + w > LUA_NBITS) + luaL_error(L, "trying to access non-existent bits"); + *width = w; + return f; } - -static int b_extract (lua_State *L) { - int w; - b_uint r = luaL_checkunsigned(L, 1); - int f = fieldargs(L, 2, &w); - r = (r >> f) & mask(w); - lua_pushunsigned(L, r); - return 1; +static int b_extract(lua_State *L) +{ + int w; + b_uint r = luaL_checkunsigned(L, 1); + int f = fieldargs(L, 2, &w); + r = (r >> f) & mask(w); + lua_pushunsigned(L, r); + return 1; } - -static int b_replace (lua_State *L) { - int w; - b_uint r = luaL_checkunsigned(L, 1); - b_uint v = luaL_checkunsigned(L, 2); - int f = fieldargs(L, 3, &w); - int m = mask(w); - v &= m; /* erase bits outside given width */ - r = (r & ~(m << f)) | (v << f); - lua_pushunsigned(L, r); - return 1; +static int b_replace(lua_State *L) +{ + int w; + b_uint r = luaL_checkunsigned(L, 1); + b_uint v = luaL_checkunsigned(L, 2); + int f = fieldargs(L, 3, &w); + int m = mask(w); + v &= m; /* erase bits outside given width */ + r = (r & ~(m << f)) | (v << f); + lua_pushunsigned(L, r); + return 1; } - static const luaL_Reg bitlib[] = { - {"arshift", b_arshift}, - {"band", b_and}, - {"bnot", b_not}, - {"bor", b_or}, - {"bxor", b_xor}, - {"btest", b_test}, - {"extract", b_extract}, - {"lrotate", b_lrot}, - {"lshift", b_lshift}, - {"replace", b_replace}, - {"rrotate", b_rrot}, - {"rshift", b_rshift}, - {NULL, NULL} -}; + {"arshift", b_arshift}, + {"band", b_and}, + {"bnot", b_not}, + {"bor", b_or}, + {"bxor", b_xor}, + {"btest", b_test}, + {"extract", b_extract}, + {"lrotate", b_lrot}, + {"lshift", b_lshift}, + {"replace", b_replace}, + {"rrotate", b_rrot}, + {"rshift", b_rshift}, + {NULL, NULL}}; - - -LUAMOD_API int luaopen_bit32 (lua_State *L) { - luaL_newlib(L, bitlib); - return 1; +LUAMOD_API int luaopen_bit32(lua_State *L) +{ + luaL_newlib(L, bitlib); + return 1; } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lcode.c b/examples/ThirdPartyLibs/lua-5.2.3/src/lcode.c index 820b95c0e..32390360f 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lcode.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lcode.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #include #define lcode_c @@ -25,857 +24,978 @@ #include "ltable.h" #include "lvm.h" +#define hasjumps(e) ((e)->t != (e)->f) -#define hasjumps(e) ((e)->t != (e)->f) - - -static int isnumeral(expdesc *e) { - return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP); +static int isnumeral(expdesc *e) +{ + return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP); } - -void luaK_nil (FuncState *fs, int from, int n) { - Instruction *previous; - int l = from + n - 1; /* last register to set nil */ - if (fs->pc > fs->lasttarget) { /* no jumps to current position? */ - previous = &fs->f->code[fs->pc-1]; - if (GET_OPCODE(*previous) == OP_LOADNIL) { - int pfrom = GETARG_A(*previous); - int pl = pfrom + GETARG_B(*previous); - if ((pfrom <= from && from <= pl + 1) || - (from <= pfrom && pfrom <= l + 1)) { /* can connect both? */ - if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */ - if (pl > l) l = pl; /* l = max(l, pl) */ - SETARG_A(*previous, from); - SETARG_B(*previous, l - from); - return; - } - } /* else go through */ - } - luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */ +void luaK_nil(FuncState *fs, int from, int n) +{ + Instruction *previous; + int l = from + n - 1; /* last register to set nil */ + if (fs->pc > fs->lasttarget) + { /* no jumps to current position? */ + previous = &fs->f->code[fs->pc - 1]; + if (GET_OPCODE(*previous) == OP_LOADNIL) + { + int pfrom = GETARG_A(*previous); + int pl = pfrom + GETARG_B(*previous); + if ((pfrom <= from && from <= pl + 1) || + (from <= pfrom && pfrom <= l + 1)) + { /* can connect both? */ + if (pfrom < from) from = pfrom; /* from = min(from, pfrom) */ + if (pl > l) l = pl; /* l = max(l, pl) */ + SETARG_A(*previous, from); + SETARG_B(*previous, l - from); + return; + } + } /* else go through */ + } + luaK_codeABC(fs, OP_LOADNIL, from, n - 1, 0); /* else no optimization */ } - -int luaK_jump (FuncState *fs) { - int jpc = fs->jpc; /* save list of jumps to here */ - int j; - fs->jpc = NO_JUMP; - j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); - luaK_concat(fs, &j, jpc); /* keep them on hold */ - return j; +int luaK_jump(FuncState *fs) +{ + int jpc = fs->jpc; /* save list of jumps to here */ + int j; + fs->jpc = NO_JUMP; + j = luaK_codeAsBx(fs, OP_JMP, 0, NO_JUMP); + luaK_concat(fs, &j, jpc); /* keep them on hold */ + return j; } - -void luaK_ret (FuncState *fs, int first, int nret) { - luaK_codeABC(fs, OP_RETURN, first, nret+1, 0); +void luaK_ret(FuncState *fs, int first, int nret) +{ + luaK_codeABC(fs, OP_RETURN, first, nret + 1, 0); } - -static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { - luaK_codeABC(fs, op, A, B, C); - return luaK_jump(fs); +static int condjump(FuncState *fs, OpCode op, int A, int B, int C) +{ + luaK_codeABC(fs, op, A, B, C); + return luaK_jump(fs); } - -static void fixjump (FuncState *fs, int pc, int dest) { - Instruction *jmp = &fs->f->code[pc]; - int offset = dest-(pc+1); - lua_assert(dest != NO_JUMP); - if (abs(offset) > MAXARG_sBx) - luaX_syntaxerror(fs->ls, "control structure too long"); - SETARG_sBx(*jmp, offset); +static void fixjump(FuncState *fs, int pc, int dest) +{ + Instruction *jmp = &fs->f->code[pc]; + int offset = dest - (pc + 1); + lua_assert(dest != NO_JUMP); + if (abs(offset) > MAXARG_sBx) + luaX_syntaxerror(fs->ls, "control structure too long"); + SETARG_sBx(*jmp, offset); } - /* ** returns current `pc' and marks it as a jump target (to avoid wrong ** optimizations with consecutive instructions not in the same basic block). */ -int luaK_getlabel (FuncState *fs) { - fs->lasttarget = fs->pc; - return fs->pc; +int luaK_getlabel(FuncState *fs) +{ + fs->lasttarget = fs->pc; + return fs->pc; } - -static int getjump (FuncState *fs, int pc) { - int offset = GETARG_sBx(fs->f->code[pc]); - if (offset == NO_JUMP) /* point to itself represents end of list */ - return NO_JUMP; /* end of list */ - else - return (pc+1)+offset; /* turn offset into absolute position */ +static int getjump(FuncState *fs, int pc) +{ + int offset = GETARG_sBx(fs->f->code[pc]); + if (offset == NO_JUMP) /* point to itself represents end of list */ + return NO_JUMP; /* end of list */ + else + return (pc + 1) + offset; /* turn offset into absolute position */ } - -static Instruction *getjumpcontrol (FuncState *fs, int pc) { - Instruction *pi = &fs->f->code[pc]; - if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) - return pi-1; - else - return pi; +static Instruction *getjumpcontrol(FuncState *fs, int pc) +{ + Instruction *pi = &fs->f->code[pc]; + if (pc >= 1 && testTMode(GET_OPCODE(*(pi - 1)))) + return pi - 1; + else + return pi; } - /* ** check whether list has any jump that do not produce a value ** (or produce an inverted value) */ -static int need_value (FuncState *fs, int list) { - for (; list != NO_JUMP; list = getjump(fs, list)) { - Instruction i = *getjumpcontrol(fs, list); - if (GET_OPCODE(i) != OP_TESTSET) return 1; - } - return 0; /* not found */ +static int need_value(FuncState *fs, int list) +{ + for (; list != NO_JUMP; list = getjump(fs, list)) + { + Instruction i = *getjumpcontrol(fs, list); + if (GET_OPCODE(i) != OP_TESTSET) return 1; + } + return 0; /* not found */ } +static int patchtestreg(FuncState *fs, int node, int reg) +{ + Instruction *i = getjumpcontrol(fs, node); + if (GET_OPCODE(*i) != OP_TESTSET) + return 0; /* cannot patch other instructions */ + if (reg != NO_REG && reg != GETARG_B(*i)) + SETARG_A(*i, reg); + else /* no register to put value or register already has the value */ + *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); -static int patchtestreg (FuncState *fs, int node, int reg) { - Instruction *i = getjumpcontrol(fs, node); - if (GET_OPCODE(*i) != OP_TESTSET) - return 0; /* cannot patch other instructions */ - if (reg != NO_REG && reg != GETARG_B(*i)) - SETARG_A(*i, reg); - else /* no register to put value or register already has the value */ - *i = CREATE_ABC(OP_TEST, GETARG_B(*i), 0, GETARG_C(*i)); - - return 1; + return 1; } - -static void removevalues (FuncState *fs, int list) { - for (; list != NO_JUMP; list = getjump(fs, list)) - patchtestreg(fs, list, NO_REG); +static void removevalues(FuncState *fs, int list) +{ + for (; list != NO_JUMP; list = getjump(fs, list)) + patchtestreg(fs, list, NO_REG); } - -static void patchlistaux (FuncState *fs, int list, int vtarget, int reg, - int dtarget) { - while (list != NO_JUMP) { - int next = getjump(fs, list); - if (patchtestreg(fs, list, reg)) - fixjump(fs, list, vtarget); - else - fixjump(fs, list, dtarget); /* jump to default target */ - list = next; - } +static void patchlistaux(FuncState *fs, int list, int vtarget, int reg, + int dtarget) +{ + while (list != NO_JUMP) + { + int next = getjump(fs, list); + if (patchtestreg(fs, list, reg)) + fixjump(fs, list, vtarget); + else + fixjump(fs, list, dtarget); /* jump to default target */ + list = next; + } } - -static void dischargejpc (FuncState *fs) { - patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); - fs->jpc = NO_JUMP; +static void dischargejpc(FuncState *fs) +{ + patchlistaux(fs, fs->jpc, fs->pc, NO_REG, fs->pc); + fs->jpc = NO_JUMP; } - -void luaK_patchlist (FuncState *fs, int list, int target) { - if (target == fs->pc) - luaK_patchtohere(fs, list); - else { - lua_assert(target < fs->pc); - patchlistaux(fs, list, target, NO_REG, target); - } +void luaK_patchlist(FuncState *fs, int list, int target) +{ + if (target == fs->pc) + luaK_patchtohere(fs, list); + else + { + lua_assert(target < fs->pc); + patchlistaux(fs, list, target, NO_REG, target); + } } - -LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level) { - level++; /* argument is +1 to reserve 0 as non-op */ - while (list != NO_JUMP) { - int next = getjump(fs, list); - lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP && - (GETARG_A(fs->f->code[list]) == 0 || - GETARG_A(fs->f->code[list]) >= level)); - SETARG_A(fs->f->code[list], level); - list = next; - } +LUAI_FUNC void luaK_patchclose(FuncState *fs, int list, int level) +{ + level++; /* argument is +1 to reserve 0 as non-op */ + while (list != NO_JUMP) + { + int next = getjump(fs, list); + lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP && + (GETARG_A(fs->f->code[list]) == 0 || + GETARG_A(fs->f->code[list]) >= level)); + SETARG_A(fs->f->code[list], level); + list = next; + } } - -void luaK_patchtohere (FuncState *fs, int list) { - luaK_getlabel(fs); - luaK_concat(fs, &fs->jpc, list); +void luaK_patchtohere(FuncState *fs, int list) +{ + luaK_getlabel(fs); + luaK_concat(fs, &fs->jpc, list); } - -void luaK_concat (FuncState *fs, int *l1, int l2) { - if (l2 == NO_JUMP) return; - else if (*l1 == NO_JUMP) - *l1 = l2; - else { - int list = *l1; - int next; - while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ - list = next; - fixjump(fs, list, l2); - } +void luaK_concat(FuncState *fs, int *l1, int l2) +{ + if (l2 == NO_JUMP) + return; + else if (*l1 == NO_JUMP) + *l1 = l2; + else + { + int list = *l1; + int next; + while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ + list = next; + fixjump(fs, list, l2); + } } - -static int luaK_code (FuncState *fs, Instruction i) { - Proto *f = fs->f; - dischargejpc(fs); /* `pc' will change */ - /* put new instruction in code array */ - luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, - MAX_INT, "opcodes"); - f->code[fs->pc] = i; - /* save corresponding line information */ - luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int, - MAX_INT, "opcodes"); - f->lineinfo[fs->pc] = fs->ls->lastline; - return fs->pc++; +static int luaK_code(FuncState *fs, Instruction i) +{ + Proto *f = fs->f; + dischargejpc(fs); /* `pc' will change */ + /* put new instruction in code array */ + luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, + MAX_INT, "opcodes"); + f->code[fs->pc] = i; + /* save corresponding line information */ + luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int, + MAX_INT, "opcodes"); + f->lineinfo[fs->pc] = fs->ls->lastline; + return fs->pc++; } - -int luaK_codeABC (FuncState *fs, OpCode o, int a, int b, int c) { - lua_assert(getOpMode(o) == iABC); - lua_assert(getBMode(o) != OpArgN || b == 0); - lua_assert(getCMode(o) != OpArgN || c == 0); - lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C); - return luaK_code(fs, CREATE_ABC(o, a, b, c)); +int luaK_codeABC(FuncState *fs, OpCode o, int a, int b, int c) +{ + lua_assert(getOpMode(o) == iABC); + lua_assert(getBMode(o) != OpArgN || b == 0); + lua_assert(getCMode(o) != OpArgN || c == 0); + lua_assert(a <= MAXARG_A && b <= MAXARG_B && c <= MAXARG_C); + return luaK_code(fs, CREATE_ABC(o, a, b, c)); } - -int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) { - lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); - lua_assert(getCMode(o) == OpArgN); - lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx); - return luaK_code(fs, CREATE_ABx(o, a, bc)); +int luaK_codeABx(FuncState *fs, OpCode o, int a, unsigned int bc) +{ + lua_assert(getOpMode(o) == iABx || getOpMode(o) == iAsBx); + lua_assert(getCMode(o) == OpArgN); + lua_assert(a <= MAXARG_A && bc <= MAXARG_Bx); + return luaK_code(fs, CREATE_ABx(o, a, bc)); } - -static int codeextraarg (FuncState *fs, int a) { - lua_assert(a <= MAXARG_Ax); - return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a)); +static int codeextraarg(FuncState *fs, int a) +{ + lua_assert(a <= MAXARG_Ax); + return luaK_code(fs, CREATE_Ax(OP_EXTRAARG, a)); } - -int luaK_codek (FuncState *fs, int reg, int k) { - if (k <= MAXARG_Bx) - return luaK_codeABx(fs, OP_LOADK, reg, k); - else { - int p = luaK_codeABx(fs, OP_LOADKX, reg, 0); - codeextraarg(fs, k); - return p; - } +int luaK_codek(FuncState *fs, int reg, int k) +{ + if (k <= MAXARG_Bx) + return luaK_codeABx(fs, OP_LOADK, reg, k); + else + { + int p = luaK_codeABx(fs, OP_LOADKX, reg, 0); + codeextraarg(fs, k); + return p; + } } - -void luaK_checkstack (FuncState *fs, int n) { - int newstack = fs->freereg + n; - if (newstack > fs->f->maxstacksize) { - if (newstack >= MAXSTACK) - luaX_syntaxerror(fs->ls, "function or expression too complex"); - fs->f->maxstacksize = cast_byte(newstack); - } +void luaK_checkstack(FuncState *fs, int n) +{ + int newstack = fs->freereg + n; + if (newstack > fs->f->maxstacksize) + { + if (newstack >= MAXSTACK) + luaX_syntaxerror(fs->ls, "function or expression too complex"); + fs->f->maxstacksize = cast_byte(newstack); + } } - -void luaK_reserveregs (FuncState *fs, int n) { - luaK_checkstack(fs, n); - fs->freereg += n; +void luaK_reserveregs(FuncState *fs, int n) +{ + luaK_checkstack(fs, n); + fs->freereg += n; } - -static void freereg (FuncState *fs, int reg) { - if (!ISK(reg) && reg >= fs->nactvar) { - fs->freereg--; - lua_assert(reg == fs->freereg); - } +static void freereg(FuncState *fs, int reg) +{ + if (!ISK(reg) && reg >= fs->nactvar) + { + fs->freereg--; + lua_assert(reg == fs->freereg); + } } - -static void freeexp (FuncState *fs, expdesc *e) { - if (e->k == VNONRELOC) - freereg(fs, e->u.info); +static void freeexp(FuncState *fs, expdesc *e) +{ + if (e->k == VNONRELOC) + freereg(fs, e->u.info); } - -static int addk (FuncState *fs, TValue *key, TValue *v) { - lua_State *L = fs->ls->L; - TValue *idx = luaH_set(L, fs->h, key); - Proto *f = fs->f; - int k, oldsize; - if (ttisnumber(idx)) { - lua_Number n = nvalue(idx); - lua_number2int(k, n); - if (luaV_rawequalobj(&f->k[k], v)) - return k; - /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0"); +static int addk(FuncState *fs, TValue *key, TValue *v) +{ + lua_State *L = fs->ls->L; + TValue *idx = luaH_set(L, fs->h, key); + Proto *f = fs->f; + int k, oldsize; + if (ttisnumber(idx)) + { + lua_Number n = nvalue(idx); + lua_number2int(k, n); + if (luaV_rawequalobj(&f->k[k], v)) + return k; + /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0"); go through and create a new entry for this value */ - } - /* constant not found; create a new entry */ - oldsize = f->sizek; - k = fs->nk; - /* numerical value does not need GC barrier; + } + /* constant not found; create a new entry */ + oldsize = f->sizek; + k = fs->nk; + /* numerical value does not need GC barrier; table has no metatable, so it does not need to invalidate cache */ - setnvalue(idx, cast_num(k)); - luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); - while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); - setobj(L, &f->k[k], v); - fs->nk++; - luaC_barrier(L, f, v); - return k; + setnvalue(idx, cast_num(k)); + luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); + while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); + setobj(L, &f->k[k], v); + fs->nk++; + luaC_barrier(L, f, v); + return k; } - -int luaK_stringK (FuncState *fs, TString *s) { - TValue o; - setsvalue(fs->ls->L, &o, s); - return addk(fs, &o, &o); +int luaK_stringK(FuncState *fs, TString *s) +{ + TValue o; + setsvalue(fs->ls->L, &o, s); + return addk(fs, &o, &o); } - -int luaK_numberK (FuncState *fs, lua_Number r) { - int n; - lua_State *L = fs->ls->L; - TValue o; - setnvalue(&o, r); - if (r == 0 || luai_numisnan(NULL, r)) { /* handle -0 and NaN */ - /* use raw representation as key to avoid numeric problems */ - setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r))); - n = addk(fs, L->top - 1, &o); - L->top--; - } - else - n = addk(fs, &o, &o); /* regular case */ - return n; +int luaK_numberK(FuncState *fs, lua_Number r) +{ + int n; + lua_State *L = fs->ls->L; + TValue o; + setnvalue(&o, r); + if (r == 0 || luai_numisnan(NULL, r)) + { /* handle -0 and NaN */ + /* use raw representation as key to avoid numeric problems */ + setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r))); + n = addk(fs, L->top - 1, &o); + L->top--; + } + else + n = addk(fs, &o, &o); /* regular case */ + return n; } - -static int boolK (FuncState *fs, int b) { - TValue o; - setbvalue(&o, b); - return addk(fs, &o, &o); +static int boolK(FuncState *fs, int b) +{ + TValue o; + setbvalue(&o, b); + return addk(fs, &o, &o); } - -static int nilK (FuncState *fs) { - TValue k, v; - setnilvalue(&v); - /* cannot use nil as key; instead use table itself to represent nil */ - sethvalue(fs->ls->L, &k, fs->h); - return addk(fs, &k, &v); +static int nilK(FuncState *fs) +{ + TValue k, v; + setnilvalue(&v); + /* cannot use nil as key; instead use table itself to represent nil */ + sethvalue(fs->ls->L, &k, fs->h); + return addk(fs, &k, &v); } - -void luaK_setreturns (FuncState *fs, expdesc *e, int nresults) { - if (e->k == VCALL) { /* expression is an open function call? */ - SETARG_C(getcode(fs, e), nresults+1); - } - else if (e->k == VVARARG) { - SETARG_B(getcode(fs, e), nresults+1); - SETARG_A(getcode(fs, e), fs->freereg); - luaK_reserveregs(fs, 1); - } +void luaK_setreturns(FuncState *fs, expdesc *e, int nresults) +{ + if (e->k == VCALL) + { /* expression is an open function call? */ + SETARG_C(getcode(fs, e), nresults + 1); + } + else if (e->k == VVARARG) + { + SETARG_B(getcode(fs, e), nresults + 1); + SETARG_A(getcode(fs, e), fs->freereg); + luaK_reserveregs(fs, 1); + } } - -void luaK_setoneret (FuncState *fs, expdesc *e) { - if (e->k == VCALL) { /* expression is an open function call? */ - e->k = VNONRELOC; - e->u.info = GETARG_A(getcode(fs, e)); - } - else if (e->k == VVARARG) { - SETARG_B(getcode(fs, e), 2); - e->k = VRELOCABLE; /* can relocate its simple result */ - } +void luaK_setoneret(FuncState *fs, expdesc *e) +{ + if (e->k == VCALL) + { /* expression is an open function call? */ + e->k = VNONRELOC; + e->u.info = GETARG_A(getcode(fs, e)); + } + else if (e->k == VVARARG) + { + SETARG_B(getcode(fs, e), 2); + e->k = VRELOCABLE; /* can relocate its simple result */ + } } - -void luaK_dischargevars (FuncState *fs, expdesc *e) { - switch (e->k) { - case VLOCAL: { - e->k = VNONRELOC; - break; - } - case VUPVAL: { - e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); - e->k = VRELOCABLE; - break; - } - case VINDEXED: { - OpCode op = OP_GETTABUP; /* assume 't' is in an upvalue */ - freereg(fs, e->u.ind.idx); - if (e->u.ind.vt == VLOCAL) { /* 't' is in a register? */ - freereg(fs, e->u.ind.t); - op = OP_GETTABLE; - } - e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx); - e->k = VRELOCABLE; - break; - } - case VVARARG: - case VCALL: { - luaK_setoneret(fs, e); - break; - } - default: break; /* there is one value available (somewhere) */ - } +void luaK_dischargevars(FuncState *fs, expdesc *e) +{ + switch (e->k) + { + case VLOCAL: + { + e->k = VNONRELOC; + break; + } + case VUPVAL: + { + e->u.info = luaK_codeABC(fs, OP_GETUPVAL, 0, e->u.info, 0); + e->k = VRELOCABLE; + break; + } + case VINDEXED: + { + OpCode op = OP_GETTABUP; /* assume 't' is in an upvalue */ + freereg(fs, e->u.ind.idx); + if (e->u.ind.vt == VLOCAL) + { /* 't' is in a register? */ + freereg(fs, e->u.ind.t); + op = OP_GETTABLE; + } + e->u.info = luaK_codeABC(fs, op, 0, e->u.ind.t, e->u.ind.idx); + e->k = VRELOCABLE; + break; + } + case VVARARG: + case VCALL: + { + luaK_setoneret(fs, e); + break; + } + default: + break; /* there is one value available (somewhere) */ + } } - -static int code_label (FuncState *fs, int A, int b, int jump) { - luaK_getlabel(fs); /* those instructions may be jump targets */ - return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); +static int code_label(FuncState *fs, int A, int b, int jump) +{ + luaK_getlabel(fs); /* those instructions may be jump targets */ + return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); } - -static void discharge2reg (FuncState *fs, expdesc *e, int reg) { - luaK_dischargevars(fs, e); - switch (e->k) { - case VNIL: { - luaK_nil(fs, reg, 1); - break; - } - case VFALSE: case VTRUE: { - luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); - break; - } - case VK: { - luaK_codek(fs, reg, e->u.info); - break; - } - case VKNUM: { - luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval)); - break; - } - case VRELOCABLE: { - Instruction *pc = &getcode(fs, e); - SETARG_A(*pc, reg); - break; - } - case VNONRELOC: { - if (reg != e->u.info) - luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0); - break; - } - default: { - lua_assert(e->k == VVOID || e->k == VJMP); - return; /* nothing to do... */ - } - } - e->u.info = reg; - e->k = VNONRELOC; +static void discharge2reg(FuncState *fs, expdesc *e, int reg) +{ + luaK_dischargevars(fs, e); + switch (e->k) + { + case VNIL: + { + luaK_nil(fs, reg, 1); + break; + } + case VFALSE: + case VTRUE: + { + luaK_codeABC(fs, OP_LOADBOOL, reg, e->k == VTRUE, 0); + break; + } + case VK: + { + luaK_codek(fs, reg, e->u.info); + break; + } + case VKNUM: + { + luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval)); + break; + } + case VRELOCABLE: + { + Instruction *pc = &getcode(fs, e); + SETARG_A(*pc, reg); + break; + } + case VNONRELOC: + { + if (reg != e->u.info) + luaK_codeABC(fs, OP_MOVE, reg, e->u.info, 0); + break; + } + default: + { + lua_assert(e->k == VVOID || e->k == VJMP); + return; /* nothing to do... */ + } + } + e->u.info = reg; + e->k = VNONRELOC; } - -static void discharge2anyreg (FuncState *fs, expdesc *e) { - if (e->k != VNONRELOC) { - luaK_reserveregs(fs, 1); - discharge2reg(fs, e, fs->freereg-1); - } +static void discharge2anyreg(FuncState *fs, expdesc *e) +{ + if (e->k != VNONRELOC) + { + luaK_reserveregs(fs, 1); + discharge2reg(fs, e, fs->freereg - 1); + } } - -static void exp2reg (FuncState *fs, expdesc *e, int reg) { - discharge2reg(fs, e, reg); - if (e->k == VJMP) - luaK_concat(fs, &e->t, e->u.info); /* put this jump in `t' list */ - if (hasjumps(e)) { - int final; /* position after whole expression */ - int p_f = NO_JUMP; /* position of an eventual LOAD false */ - int p_t = NO_JUMP; /* position of an eventual LOAD true */ - if (need_value(fs, e->t) || need_value(fs, e->f)) { - int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); - p_f = code_label(fs, reg, 0, 1); - p_t = code_label(fs, reg, 1, 0); - luaK_patchtohere(fs, fj); - } - final = luaK_getlabel(fs); - patchlistaux(fs, e->f, final, reg, p_f); - patchlistaux(fs, e->t, final, reg, p_t); - } - e->f = e->t = NO_JUMP; - e->u.info = reg; - e->k = VNONRELOC; +static void exp2reg(FuncState *fs, expdesc *e, int reg) +{ + discharge2reg(fs, e, reg); + if (e->k == VJMP) + luaK_concat(fs, &e->t, e->u.info); /* put this jump in `t' list */ + if (hasjumps(e)) + { + int final; /* position after whole expression */ + int p_f = NO_JUMP; /* position of an eventual LOAD false */ + int p_t = NO_JUMP; /* position of an eventual LOAD true */ + if (need_value(fs, e->t) || need_value(fs, e->f)) + { + int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); + p_f = code_label(fs, reg, 0, 1); + p_t = code_label(fs, reg, 1, 0); + luaK_patchtohere(fs, fj); + } + final = luaK_getlabel(fs); + patchlistaux(fs, e->f, final, reg, p_f); + patchlistaux(fs, e->t, final, reg, p_t); + } + e->f = e->t = NO_JUMP; + e->u.info = reg; + e->k = VNONRELOC; } - -void luaK_exp2nextreg (FuncState *fs, expdesc *e) { - luaK_dischargevars(fs, e); - freeexp(fs, e); - luaK_reserveregs(fs, 1); - exp2reg(fs, e, fs->freereg - 1); +void luaK_exp2nextreg(FuncState *fs, expdesc *e) +{ + luaK_dischargevars(fs, e); + freeexp(fs, e); + luaK_reserveregs(fs, 1); + exp2reg(fs, e, fs->freereg - 1); } - -int luaK_exp2anyreg (FuncState *fs, expdesc *e) { - luaK_dischargevars(fs, e); - if (e->k == VNONRELOC) { - if (!hasjumps(e)) return e->u.info; /* exp is already in a register */ - if (e->u.info >= fs->nactvar) { /* reg. is not a local? */ - exp2reg(fs, e, e->u.info); /* put value on it */ - return e->u.info; - } - } - luaK_exp2nextreg(fs, e); /* default */ - return e->u.info; +int luaK_exp2anyreg(FuncState *fs, expdesc *e) +{ + luaK_dischargevars(fs, e); + if (e->k == VNONRELOC) + { + if (!hasjumps(e)) return e->u.info; /* exp is already in a register */ + if (e->u.info >= fs->nactvar) + { /* reg. is not a local? */ + exp2reg(fs, e, e->u.info); /* put value on it */ + return e->u.info; + } + } + luaK_exp2nextreg(fs, e); /* default */ + return e->u.info; } - -void luaK_exp2anyregup (FuncState *fs, expdesc *e) { - if (e->k != VUPVAL || hasjumps(e)) - luaK_exp2anyreg(fs, e); +void luaK_exp2anyregup(FuncState *fs, expdesc *e) +{ + if (e->k != VUPVAL || hasjumps(e)) + luaK_exp2anyreg(fs, e); } - -void luaK_exp2val (FuncState *fs, expdesc *e) { - if (hasjumps(e)) - luaK_exp2anyreg(fs, e); - else - luaK_dischargevars(fs, e); +void luaK_exp2val(FuncState *fs, expdesc *e) +{ + if (hasjumps(e)) + luaK_exp2anyreg(fs, e); + else + luaK_dischargevars(fs, e); } - -int luaK_exp2RK (FuncState *fs, expdesc *e) { - luaK_exp2val(fs, e); - switch (e->k) { - case VTRUE: - case VFALSE: - case VNIL: { - if (fs->nk <= MAXINDEXRK) { /* constant fits in RK operand? */ - e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE)); - e->k = VK; - return RKASK(e->u.info); - } - else break; - } - case VKNUM: { - e->u.info = luaK_numberK(fs, e->u.nval); - e->k = VK; - /* go through */ - } - case VK: { - if (e->u.info <= MAXINDEXRK) /* constant fits in argC? */ - return RKASK(e->u.info); - else break; - } - default: break; - } - /* not a constant in the right range: put it in a register */ - return luaK_exp2anyreg(fs, e); +int luaK_exp2RK(FuncState *fs, expdesc *e) +{ + luaK_exp2val(fs, e); + switch (e->k) + { + case VTRUE: + case VFALSE: + case VNIL: + { + if (fs->nk <= MAXINDEXRK) + { /* constant fits in RK operand? */ + e->u.info = (e->k == VNIL) ? nilK(fs) : boolK(fs, (e->k == VTRUE)); + e->k = VK; + return RKASK(e->u.info); + } + else + break; + } + case VKNUM: + { + e->u.info = luaK_numberK(fs, e->u.nval); + e->k = VK; + /* go through */ + } + case VK: + { + if (e->u.info <= MAXINDEXRK) /* constant fits in argC? */ + return RKASK(e->u.info); + else + break; + } + default: + break; + } + /* not a constant in the right range: put it in a register */ + return luaK_exp2anyreg(fs, e); } - -void luaK_storevar (FuncState *fs, expdesc *var, expdesc *ex) { - switch (var->k) { - case VLOCAL: { - freeexp(fs, ex); - exp2reg(fs, ex, var->u.info); - return; - } - case VUPVAL: { - int e = luaK_exp2anyreg(fs, ex); - luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0); - break; - } - case VINDEXED: { - OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP; - int e = luaK_exp2RK(fs, ex); - luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e); - break; - } - default: { - lua_assert(0); /* invalid var kind to store */ - break; - } - } - freeexp(fs, ex); +void luaK_storevar(FuncState *fs, expdesc *var, expdesc *ex) +{ + switch (var->k) + { + case VLOCAL: + { + freeexp(fs, ex); + exp2reg(fs, ex, var->u.info); + return; + } + case VUPVAL: + { + int e = luaK_exp2anyreg(fs, ex); + luaK_codeABC(fs, OP_SETUPVAL, e, var->u.info, 0); + break; + } + case VINDEXED: + { + OpCode op = (var->u.ind.vt == VLOCAL) ? OP_SETTABLE : OP_SETTABUP; + int e = luaK_exp2RK(fs, ex); + luaK_codeABC(fs, op, var->u.ind.t, var->u.ind.idx, e); + break; + } + default: + { + lua_assert(0); /* invalid var kind to store */ + break; + } + } + freeexp(fs, ex); } - -void luaK_self (FuncState *fs, expdesc *e, expdesc *key) { - int ereg; - luaK_exp2anyreg(fs, e); - ereg = e->u.info; /* register where 'e' was placed */ - freeexp(fs, e); - e->u.info = fs->freereg; /* base register for op_self */ - e->k = VNONRELOC; - luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */ - luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key)); - freeexp(fs, key); +void luaK_self(FuncState *fs, expdesc *e, expdesc *key) +{ + int ereg; + luaK_exp2anyreg(fs, e); + ereg = e->u.info; /* register where 'e' was placed */ + freeexp(fs, e); + e->u.info = fs->freereg; /* base register for op_self */ + e->k = VNONRELOC; + luaK_reserveregs(fs, 2); /* function and 'self' produced by op_self */ + luaK_codeABC(fs, OP_SELF, e->u.info, ereg, luaK_exp2RK(fs, key)); + freeexp(fs, key); } - -static void invertjump (FuncState *fs, expdesc *e) { - Instruction *pc = getjumpcontrol(fs, e->u.info); - lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && - GET_OPCODE(*pc) != OP_TEST); - SETARG_A(*pc, !(GETARG_A(*pc))); +static void invertjump(FuncState *fs, expdesc *e) +{ + Instruction *pc = getjumpcontrol(fs, e->u.info); + lua_assert(testTMode(GET_OPCODE(*pc)) && GET_OPCODE(*pc) != OP_TESTSET && + GET_OPCODE(*pc) != OP_TEST); + SETARG_A(*pc, !(GETARG_A(*pc))); } - -static int jumponcond (FuncState *fs, expdesc *e, int cond) { - if (e->k == VRELOCABLE) { - Instruction ie = getcode(fs, e); - if (GET_OPCODE(ie) == OP_NOT) { - fs->pc--; /* remove previous OP_NOT */ - return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); - } - /* else go through */ - } - discharge2anyreg(fs, e); - freeexp(fs, e); - return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond); +static int jumponcond(FuncState *fs, expdesc *e, int cond) +{ + if (e->k == VRELOCABLE) + { + Instruction ie = getcode(fs, e); + if (GET_OPCODE(ie) == OP_NOT) + { + fs->pc--; /* remove previous OP_NOT */ + return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); + } + /* else go through */ + } + discharge2anyreg(fs, e); + freeexp(fs, e); + return condjump(fs, OP_TESTSET, NO_REG, e->u.info, cond); } - -void luaK_goiftrue (FuncState *fs, expdesc *e) { - int pc; /* pc of last jump */ - luaK_dischargevars(fs, e); - switch (e->k) { - case VJMP: { - invertjump(fs, e); - pc = e->u.info; - break; - } - case VK: case VKNUM: case VTRUE: { - pc = NO_JUMP; /* always true; do nothing */ - break; - } - default: { - pc = jumponcond(fs, e, 0); - break; - } - } - luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ - luaK_patchtohere(fs, e->t); - e->t = NO_JUMP; +void luaK_goiftrue(FuncState *fs, expdesc *e) +{ + int pc; /* pc of last jump */ + luaK_dischargevars(fs, e); + switch (e->k) + { + case VJMP: + { + invertjump(fs, e); + pc = e->u.info; + break; + } + case VK: + case VKNUM: + case VTRUE: + { + pc = NO_JUMP; /* always true; do nothing */ + break; + } + default: + { + pc = jumponcond(fs, e, 0); + break; + } + } + luaK_concat(fs, &e->f, pc); /* insert last jump in `f' list */ + luaK_patchtohere(fs, e->t); + e->t = NO_JUMP; } - -void luaK_goiffalse (FuncState *fs, expdesc *e) { - int pc; /* pc of last jump */ - luaK_dischargevars(fs, e); - switch (e->k) { - case VJMP: { - pc = e->u.info; - break; - } - case VNIL: case VFALSE: { - pc = NO_JUMP; /* always false; do nothing */ - break; - } - default: { - pc = jumponcond(fs, e, 1); - break; - } - } - luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ - luaK_patchtohere(fs, e->f); - e->f = NO_JUMP; +void luaK_goiffalse(FuncState *fs, expdesc *e) +{ + int pc; /* pc of last jump */ + luaK_dischargevars(fs, e); + switch (e->k) + { + case VJMP: + { + pc = e->u.info; + break; + } + case VNIL: + case VFALSE: + { + pc = NO_JUMP; /* always false; do nothing */ + break; + } + default: + { + pc = jumponcond(fs, e, 1); + break; + } + } + luaK_concat(fs, &e->t, pc); /* insert last jump in `t' list */ + luaK_patchtohere(fs, e->f); + e->f = NO_JUMP; } - -static void codenot (FuncState *fs, expdesc *e) { - luaK_dischargevars(fs, e); - switch (e->k) { - case VNIL: case VFALSE: { - e->k = VTRUE; - break; - } - case VK: case VKNUM: case VTRUE: { - e->k = VFALSE; - break; - } - case VJMP: { - invertjump(fs, e); - break; - } - case VRELOCABLE: - case VNONRELOC: { - discharge2anyreg(fs, e); - freeexp(fs, e); - e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0); - e->k = VRELOCABLE; - break; - } - default: { - lua_assert(0); /* cannot happen */ - break; - } - } - /* interchange true and false lists */ - { int temp = e->f; e->f = e->t; e->t = temp; } - removevalues(fs, e->f); - removevalues(fs, e->t); +static void codenot(FuncState *fs, expdesc *e) +{ + luaK_dischargevars(fs, e); + switch (e->k) + { + case VNIL: + case VFALSE: + { + e->k = VTRUE; + break; + } + case VK: + case VKNUM: + case VTRUE: + { + e->k = VFALSE; + break; + } + case VJMP: + { + invertjump(fs, e); + break; + } + case VRELOCABLE: + case VNONRELOC: + { + discharge2anyreg(fs, e); + freeexp(fs, e); + e->u.info = luaK_codeABC(fs, OP_NOT, 0, e->u.info, 0); + e->k = VRELOCABLE; + break; + } + default: + { + lua_assert(0); /* cannot happen */ + break; + } + } + /* interchange true and false lists */ + { + int temp = e->f; + e->f = e->t; + e->t = temp; + } + removevalues(fs, e->f); + removevalues(fs, e->t); } - -void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { - lua_assert(!hasjumps(t)); - t->u.ind.t = t->u.info; - t->u.ind.idx = luaK_exp2RK(fs, k); - t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL - : check_exp(vkisinreg(t->k), VLOCAL); - t->k = VINDEXED; +void luaK_indexed(FuncState *fs, expdesc *t, expdesc *k) +{ + lua_assert(!hasjumps(t)); + t->u.ind.t = t->u.info; + t->u.ind.idx = luaK_exp2RK(fs, k); + t->u.ind.vt = (t->k == VUPVAL) ? VUPVAL + : check_exp(vkisinreg(t->k), VLOCAL); + t->k = VINDEXED; } - -static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { - lua_Number r; - if (!isnumeral(e1) || !isnumeral(e2)) return 0; - if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0) - return 0; /* do not attempt to divide by 0 */ - r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval); - e1->u.nval = r; - return 1; +static int constfolding(OpCode op, expdesc *e1, expdesc *e2) +{ + lua_Number r; + if (!isnumeral(e1) || !isnumeral(e2)) return 0; + if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0) + return 0; /* do not attempt to divide by 0 */ + r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval); + e1->u.nval = r; + return 1; } - -static void codearith (FuncState *fs, OpCode op, - expdesc *e1, expdesc *e2, int line) { - if (constfolding(op, e1, e2)) - return; - else { - int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0; - int o1 = luaK_exp2RK(fs, e1); - if (o1 > o2) { - freeexp(fs, e1); - freeexp(fs, e2); - } - else { - freeexp(fs, e2); - freeexp(fs, e1); - } - e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); - e1->k = VRELOCABLE; - luaK_fixline(fs, line); - } +static void codearith(FuncState *fs, OpCode op, + expdesc *e1, expdesc *e2, int line) +{ + if (constfolding(op, e1, e2)) + return; + else + { + int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0; + int o1 = luaK_exp2RK(fs, e1); + if (o1 > o2) + { + freeexp(fs, e1); + freeexp(fs, e2); + } + else + { + freeexp(fs, e2); + freeexp(fs, e1); + } + e1->u.info = luaK_codeABC(fs, op, 0, o1, o2); + e1->k = VRELOCABLE; + luaK_fixline(fs, line); + } } - -static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, - expdesc *e2) { - int o1 = luaK_exp2RK(fs, e1); - int o2 = luaK_exp2RK(fs, e2); - freeexp(fs, e2); - freeexp(fs, e1); - if (cond == 0 && op != OP_EQ) { - int temp; /* exchange args to replace by `<' or `<=' */ - temp = o1; o1 = o2; o2 = temp; /* o1 <==> o2 */ - cond = 1; - } - e1->u.info = condjump(fs, op, cond, o1, o2); - e1->k = VJMP; +static void codecomp(FuncState *fs, OpCode op, int cond, expdesc *e1, + expdesc *e2) +{ + int o1 = luaK_exp2RK(fs, e1); + int o2 = luaK_exp2RK(fs, e2); + freeexp(fs, e2); + freeexp(fs, e1); + if (cond == 0 && op != OP_EQ) + { + int temp; /* exchange args to replace by `<' or `<=' */ + temp = o1; + o1 = o2; + o2 = temp; /* o1 <==> o2 */ + cond = 1; + } + e1->u.info = condjump(fs, op, cond, o1, o2); + e1->k = VJMP; } - -void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) { - expdesc e2; - e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0; - switch (op) { - case OPR_MINUS: { - if (isnumeral(e)) /* minus constant? */ - e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */ - else { - luaK_exp2anyreg(fs, e); - codearith(fs, OP_UNM, e, &e2, line); - } - break; - } - case OPR_NOT: codenot(fs, e); break; - case OPR_LEN: { - luaK_exp2anyreg(fs, e); /* cannot operate on constants */ - codearith(fs, OP_LEN, e, &e2, line); - break; - } - default: lua_assert(0); - } +void luaK_prefix(FuncState *fs, UnOpr op, expdesc *e, int line) +{ + expdesc e2; + e2.t = e2.f = NO_JUMP; + e2.k = VKNUM; + e2.u.nval = 0; + switch (op) + { + case OPR_MINUS: + { + if (isnumeral(e)) /* minus constant? */ + e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */ + else + { + luaK_exp2anyreg(fs, e); + codearith(fs, OP_UNM, e, &e2, line); + } + break; + } + case OPR_NOT: + codenot(fs, e); + break; + case OPR_LEN: + { + luaK_exp2anyreg(fs, e); /* cannot operate on constants */ + codearith(fs, OP_LEN, e, &e2, line); + break; + } + default: + lua_assert(0); + } } - -void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { - switch (op) { - case OPR_AND: { - luaK_goiftrue(fs, v); - break; - } - case OPR_OR: { - luaK_goiffalse(fs, v); - break; - } - case OPR_CONCAT: { - luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ - break; - } - case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: - case OPR_MOD: case OPR_POW: { - if (!isnumeral(v)) luaK_exp2RK(fs, v); - break; - } - default: { - luaK_exp2RK(fs, v); - break; - } - } +void luaK_infix(FuncState *fs, BinOpr op, expdesc *v) +{ + switch (op) + { + case OPR_AND: + { + luaK_goiftrue(fs, v); + break; + } + case OPR_OR: + { + luaK_goiffalse(fs, v); + break; + } + case OPR_CONCAT: + { + luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */ + break; + } + case OPR_ADD: + case OPR_SUB: + case OPR_MUL: + case OPR_DIV: + case OPR_MOD: + case OPR_POW: + { + if (!isnumeral(v)) luaK_exp2RK(fs, v); + break; + } + default: + { + luaK_exp2RK(fs, v); + break; + } + } } - -void luaK_posfix (FuncState *fs, BinOpr op, - expdesc *e1, expdesc *e2, int line) { - switch (op) { - case OPR_AND: { - lua_assert(e1->t == NO_JUMP); /* list must be closed */ - luaK_dischargevars(fs, e2); - luaK_concat(fs, &e2->f, e1->f); - *e1 = *e2; - break; - } - case OPR_OR: { - lua_assert(e1->f == NO_JUMP); /* list must be closed */ - luaK_dischargevars(fs, e2); - luaK_concat(fs, &e2->t, e1->t); - *e1 = *e2; - break; - } - case OPR_CONCAT: { - luaK_exp2val(fs, e2); - if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) { - lua_assert(e1->u.info == GETARG_B(getcode(fs, e2))-1); - freeexp(fs, e1); - SETARG_B(getcode(fs, e2), e1->u.info); - e1->k = VRELOCABLE; e1->u.info = e2->u.info; - } - else { - luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ - codearith(fs, OP_CONCAT, e1, e2, line); - } - break; - } - case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV: - case OPR_MOD: case OPR_POW: { - codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line); - break; - } - case OPR_EQ: case OPR_LT: case OPR_LE: { - codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2); - break; - } - case OPR_NE: case OPR_GT: case OPR_GE: { - codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2); - break; - } - default: lua_assert(0); - } +void luaK_posfix(FuncState *fs, BinOpr op, + expdesc *e1, expdesc *e2, int line) +{ + switch (op) + { + case OPR_AND: + { + lua_assert(e1->t == NO_JUMP); /* list must be closed */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e2->f, e1->f); + *e1 = *e2; + break; + } + case OPR_OR: + { + lua_assert(e1->f == NO_JUMP); /* list must be closed */ + luaK_dischargevars(fs, e2); + luaK_concat(fs, &e2->t, e1->t); + *e1 = *e2; + break; + } + case OPR_CONCAT: + { + luaK_exp2val(fs, e2); + if (e2->k == VRELOCABLE && GET_OPCODE(getcode(fs, e2)) == OP_CONCAT) + { + lua_assert(e1->u.info == GETARG_B(getcode(fs, e2)) - 1); + freeexp(fs, e1); + SETARG_B(getcode(fs, e2), e1->u.info); + e1->k = VRELOCABLE; + e1->u.info = e2->u.info; + } + else + { + luaK_exp2nextreg(fs, e2); /* operand must be on the 'stack' */ + codearith(fs, OP_CONCAT, e1, e2, line); + } + break; + } + case OPR_ADD: + case OPR_SUB: + case OPR_MUL: + case OPR_DIV: + case OPR_MOD: + case OPR_POW: + { + codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line); + break; + } + case OPR_EQ: + case OPR_LT: + case OPR_LE: + { + codecomp(fs, cast(OpCode, op - OPR_EQ + OP_EQ), 1, e1, e2); + break; + } + case OPR_NE: + case OPR_GT: + case OPR_GE: + { + codecomp(fs, cast(OpCode, op - OPR_NE + OP_EQ), 0, e1, e2); + break; + } + default: + lua_assert(0); + } } - -void luaK_fixline (FuncState *fs, int line) { - fs->f->lineinfo[fs->pc - 1] = line; +void luaK_fixline(FuncState *fs, int line) +{ + fs->f->lineinfo[fs->pc - 1] = line; } - -void luaK_setlist (FuncState *fs, int base, int nelems, int tostore) { - int c = (nelems - 1)/LFIELDS_PER_FLUSH + 1; - int b = (tostore == LUA_MULTRET) ? 0 : tostore; - lua_assert(tostore != 0); - if (c <= MAXARG_C) - luaK_codeABC(fs, OP_SETLIST, base, b, c); - else if (c <= MAXARG_Ax) { - luaK_codeABC(fs, OP_SETLIST, base, b, 0); - codeextraarg(fs, c); - } - else - luaX_syntaxerror(fs->ls, "constructor too long"); - fs->freereg = base + 1; /* free registers with list values */ +void luaK_setlist(FuncState *fs, int base, int nelems, int tostore) +{ + int c = (nelems - 1) / LFIELDS_PER_FLUSH + 1; + int b = (tostore == LUA_MULTRET) ? 0 : tostore; + lua_assert(tostore != 0); + if (c <= MAXARG_C) + luaK_codeABC(fs, OP_SETLIST, base, b, c); + else if (c <= MAXARG_Ax) + { + luaK_codeABC(fs, OP_SETLIST, base, b, 0); + codeextraarg(fs, c); + } + else + luaX_syntaxerror(fs->ls, "constructor too long"); + fs->freereg = base + 1; /* free registers with list values */ } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lcode.h b/examples/ThirdPartyLibs/lua-5.2.3/src/lcode.h index 6a1424cf5..6ac8c5480 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lcode.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lcode.h @@ -12,72 +12,84 @@ #include "lopcodes.h" #include "lparser.h" - /* ** Marks the end of a patch list. It is an invalid value both as an absolute ** address, and as a list link (would link an element to itself). */ #define NO_JUMP (-1) - /* ** grep "ORDER OPR" if you change these enums (ORDER OP) */ -typedef enum BinOpr { - OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW, - OPR_CONCAT, - OPR_EQ, OPR_LT, OPR_LE, - OPR_NE, OPR_GT, OPR_GE, - OPR_AND, OPR_OR, - OPR_NOBINOPR +typedef enum BinOpr +{ + OPR_ADD, + OPR_SUB, + OPR_MUL, + OPR_DIV, + OPR_MOD, + OPR_POW, + OPR_CONCAT, + OPR_EQ, + OPR_LT, + OPR_LE, + OPR_NE, + OPR_GT, + OPR_GE, + OPR_AND, + OPR_OR, + OPR_NOBINOPR } BinOpr; +typedef enum UnOpr +{ + OPR_MINUS, + OPR_NOT, + OPR_LEN, + OPR_NOUNOPR +} UnOpr; -typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; +#define getcode(fs, e) ((fs)->f->code[(e)->u.info]) +#define luaK_codeAsBx(fs, o, A, sBx) luaK_codeABx(fs, o, A, (sBx) + MAXARG_sBx) -#define getcode(fs,e) ((fs)->f->code[(e)->u.info]) +#define luaK_setmultret(fs, e) luaK_setreturns(fs, e, LUA_MULTRET) -#define luaK_codeAsBx(fs,o,A,sBx) luaK_codeABx(fs,o,A,(sBx)+MAXARG_sBx) - -#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) - -#define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) - -LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); -LUAI_FUNC int luaK_codeABC (FuncState *fs, OpCode o, int A, int B, int C); -LUAI_FUNC int luaK_codek (FuncState *fs, int reg, int k); -LUAI_FUNC void luaK_fixline (FuncState *fs, int line); -LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); -LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); -LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); -LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s); -LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r); -LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); -LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); -LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); -LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); -LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); -LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); -LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); -LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); -LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); -LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e); -LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); -LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); -LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); -LUAI_FUNC int luaK_jump (FuncState *fs); -LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); -LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); -LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); -LUAI_FUNC void luaK_patchclose (FuncState *fs, int list, int level); -LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); -LUAI_FUNC int luaK_getlabel (FuncState *fs); -LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); -LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); -LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, - expdesc *v2, int line); -LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); +#define luaK_jumpto(fs, t) luaK_patchlist(fs, luaK_jump(fs), t) +LUAI_FUNC int luaK_codeABx(FuncState *fs, OpCode o, int A, unsigned int Bx); +LUAI_FUNC int luaK_codeABC(FuncState *fs, OpCode o, int A, int B, int C); +LUAI_FUNC int luaK_codek(FuncState *fs, int reg, int k); +LUAI_FUNC void luaK_fixline(FuncState *fs, int line); +LUAI_FUNC void luaK_nil(FuncState *fs, int from, int n); +LUAI_FUNC void luaK_reserveregs(FuncState *fs, int n); +LUAI_FUNC void luaK_checkstack(FuncState *fs, int n); +LUAI_FUNC int luaK_stringK(FuncState *fs, TString *s); +LUAI_FUNC int luaK_numberK(FuncState *fs, lua_Number r); +LUAI_FUNC void luaK_dischargevars(FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2anyreg(FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2anyregup(FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2nextreg(FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2val(FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2RK(FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_self(FuncState *fs, expdesc *e, expdesc *key); +LUAI_FUNC void luaK_indexed(FuncState *fs, expdesc *t, expdesc *k); +LUAI_FUNC void luaK_goiftrue(FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_goiffalse(FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_storevar(FuncState *fs, expdesc *var, expdesc *e); +LUAI_FUNC void luaK_setreturns(FuncState *fs, expdesc *e, int nresults); +LUAI_FUNC void luaK_setoneret(FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_jump(FuncState *fs); +LUAI_FUNC void luaK_ret(FuncState *fs, int first, int nret); +LUAI_FUNC void luaK_patchlist(FuncState *fs, int list, int target); +LUAI_FUNC void luaK_patchtohere(FuncState *fs, int list); +LUAI_FUNC void luaK_patchclose(FuncState *fs, int list, int level); +LUAI_FUNC void luaK_concat(FuncState *fs, int *l1, int l2); +LUAI_FUNC int luaK_getlabel(FuncState *fs); +LUAI_FUNC void luaK_prefix(FuncState *fs, UnOpr op, expdesc *v, int line); +LUAI_FUNC void luaK_infix(FuncState *fs, BinOpr op, expdesc *v); +LUAI_FUNC void luaK_posfix(FuncState *fs, BinOpr op, expdesc *v1, + expdesc *v2, int line); +LUAI_FUNC void luaK_setlist(FuncState *fs, int base, int nelems, int tostore); #endif diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lcorolib.c b/examples/ThirdPartyLibs/lua-5.2.3/src/lcorolib.c index ce4f6ad42..8db2c643d 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lcorolib.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lcorolib.c @@ -4,10 +4,8 @@ ** See Copyright Notice in lua.h */ - #include - #define lcorolib_c #define LUA_LIB @@ -16,140 +14,149 @@ #include "lauxlib.h" #include "lualib.h" - -static int auxresume (lua_State *L, lua_State *co, int narg) { - int status; - if (!lua_checkstack(co, narg)) { - lua_pushliteral(L, "too many arguments to resume"); - return -1; /* error flag */ - } - if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) { - lua_pushliteral(L, "cannot resume dead coroutine"); - return -1; /* error flag */ - } - lua_xmove(L, co, narg); - status = lua_resume(co, L, narg); - if (status == LUA_OK || status == LUA_YIELD) { - int nres = lua_gettop(co); - if (!lua_checkstack(L, nres + 1)) { - lua_pop(co, nres); /* remove results anyway */ - lua_pushliteral(L, "too many results to resume"); - return -1; /* error flag */ - } - lua_xmove(co, L, nres); /* move yielded values */ - return nres; - } - else { - lua_xmove(co, L, 1); /* move error message */ - return -1; /* error flag */ - } +static int auxresume(lua_State *L, lua_State *co, int narg) +{ + int status; + if (!lua_checkstack(co, narg)) + { + lua_pushliteral(L, "too many arguments to resume"); + return -1; /* error flag */ + } + if (lua_status(co) == LUA_OK && lua_gettop(co) == 0) + { + lua_pushliteral(L, "cannot resume dead coroutine"); + return -1; /* error flag */ + } + lua_xmove(L, co, narg); + status = lua_resume(co, L, narg); + if (status == LUA_OK || status == LUA_YIELD) + { + int nres = lua_gettop(co); + if (!lua_checkstack(L, nres + 1)) + { + lua_pop(co, nres); /* remove results anyway */ + lua_pushliteral(L, "too many results to resume"); + return -1; /* error flag */ + } + lua_xmove(co, L, nres); /* move yielded values */ + return nres; + } + else + { + lua_xmove(co, L, 1); /* move error message */ + return -1; /* error flag */ + } } - -static int luaB_coresume (lua_State *L) { - lua_State *co = lua_tothread(L, 1); - int r; - luaL_argcheck(L, co, 1, "coroutine expected"); - r = auxresume(L, co, lua_gettop(L) - 1); - if (r < 0) { - lua_pushboolean(L, 0); - lua_insert(L, -2); - return 2; /* return false + error message */ - } - else { - lua_pushboolean(L, 1); - lua_insert(L, -(r + 1)); - return r + 1; /* return true + `resume' returns */ - } +static int luaB_coresume(lua_State *L) +{ + lua_State *co = lua_tothread(L, 1); + int r; + luaL_argcheck(L, co, 1, "coroutine expected"); + r = auxresume(L, co, lua_gettop(L) - 1); + if (r < 0) + { + lua_pushboolean(L, 0); + lua_insert(L, -2); + return 2; /* return false + error message */ + } + else + { + lua_pushboolean(L, 1); + lua_insert(L, -(r + 1)); + return r + 1; /* return true + `resume' returns */ + } } - -static int luaB_auxwrap (lua_State *L) { - lua_State *co = lua_tothread(L, lua_upvalueindex(1)); - int r = auxresume(L, co, lua_gettop(L)); - if (r < 0) { - if (lua_isstring(L, -1)) { /* error object is a string? */ - luaL_where(L, 1); /* add extra info */ - lua_insert(L, -2); - lua_concat(L, 2); - } - return lua_error(L); /* propagate error */ - } - return r; +static int luaB_auxwrap(lua_State *L) +{ + lua_State *co = lua_tothread(L, lua_upvalueindex(1)); + int r = auxresume(L, co, lua_gettop(L)); + if (r < 0) + { + if (lua_isstring(L, -1)) + { /* error object is a string? */ + luaL_where(L, 1); /* add extra info */ + lua_insert(L, -2); + lua_concat(L, 2); + } + return lua_error(L); /* propagate error */ + } + return r; } - -static int luaB_cocreate (lua_State *L) { - lua_State *NL; - luaL_checktype(L, 1, LUA_TFUNCTION); - NL = lua_newthread(L); - lua_pushvalue(L, 1); /* move function to top */ - lua_xmove(L, NL, 1); /* move function from L to NL */ - return 1; +static int luaB_cocreate(lua_State *L) +{ + lua_State *NL; + luaL_checktype(L, 1, LUA_TFUNCTION); + NL = lua_newthread(L); + lua_pushvalue(L, 1); /* move function to top */ + lua_xmove(L, NL, 1); /* move function from L to NL */ + return 1; } - -static int luaB_cowrap (lua_State *L) { - luaB_cocreate(L); - lua_pushcclosure(L, luaB_auxwrap, 1); - return 1; +static int luaB_cowrap(lua_State *L) +{ + luaB_cocreate(L); + lua_pushcclosure(L, luaB_auxwrap, 1); + return 1; } - -static int luaB_yield (lua_State *L) { - return lua_yield(L, lua_gettop(L)); +static int luaB_yield(lua_State *L) +{ + return lua_yield(L, lua_gettop(L)); } - -static int luaB_costatus (lua_State *L) { - lua_State *co = lua_tothread(L, 1); - luaL_argcheck(L, co, 1, "coroutine expected"); - if (L == co) lua_pushliteral(L, "running"); - else { - switch (lua_status(co)) { - case LUA_YIELD: - lua_pushliteral(L, "suspended"); - break; - case LUA_OK: { - lua_Debug ar; - if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ - lua_pushliteral(L, "normal"); /* it is running */ - else if (lua_gettop(co) == 0) - lua_pushliteral(L, "dead"); - else - lua_pushliteral(L, "suspended"); /* initial state */ - break; - } - default: /* some error occurred */ - lua_pushliteral(L, "dead"); - break; - } - } - return 1; +static int luaB_costatus(lua_State *L) +{ + lua_State *co = lua_tothread(L, 1); + luaL_argcheck(L, co, 1, "coroutine expected"); + if (L == co) + lua_pushliteral(L, "running"); + else + { + switch (lua_status(co)) + { + case LUA_YIELD: + lua_pushliteral(L, "suspended"); + break; + case LUA_OK: + { + lua_Debug ar; + if (lua_getstack(co, 0, &ar) > 0) /* does it have frames? */ + lua_pushliteral(L, "normal"); /* it is running */ + else if (lua_gettop(co) == 0) + lua_pushliteral(L, "dead"); + else + lua_pushliteral(L, "suspended"); /* initial state */ + break; + } + default: /* some error occurred */ + lua_pushliteral(L, "dead"); + break; + } + } + return 1; } - -static int luaB_corunning (lua_State *L) { - int ismain = lua_pushthread(L); - lua_pushboolean(L, ismain); - return 2; +static int luaB_corunning(lua_State *L) +{ + int ismain = lua_pushthread(L); + lua_pushboolean(L, ismain); + return 2; } - static const luaL_Reg co_funcs[] = { - {"create", luaB_cocreate}, - {"resume", luaB_coresume}, - {"running", luaB_corunning}, - {"status", luaB_costatus}, - {"wrap", luaB_cowrap}, - {"yield", luaB_yield}, - {NULL, NULL} -}; + {"create", luaB_cocreate}, + {"resume", luaB_coresume}, + {"running", luaB_corunning}, + {"status", luaB_costatus}, + {"wrap", luaB_cowrap}, + {"yield", luaB_yield}, + {NULL, NULL}}; - - -LUAMOD_API int luaopen_coroutine (lua_State *L) { - luaL_newlib(L, co_funcs); - return 1; +LUAMOD_API int luaopen_coroutine(lua_State *L) +{ + luaL_newlib(L, co_funcs); + return 1; } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lctype.c b/examples/ThirdPartyLibs/lua-5.2.3/src/lctype.c index 93f8cadc3..ba6ada2e6 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lctype.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lctype.c @@ -9,44 +9,268 @@ #include "lctype.h" -#if !LUA_USE_CTYPE /* { */ +#if !LUA_USE_CTYPE /* { */ #include LUAI_DDEF const lu_byte luai_ctype_[UCHAR_MAX + 2] = { - 0x00, /* EOZ */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0. */ - 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 1. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0c, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, /* 2. */ - 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, 0x16, /* 3. */ - 0x16, 0x16, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, - 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 4. */ - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 5. */ - 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x05, - 0x04, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x05, /* 6. */ - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, - 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, /* 7. */ - 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 8. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 9. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* a. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* b. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* c. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* d. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* e. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* f. */ - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, /* EOZ */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, /* 0. */ + 0x00, + 0x08, + 0x08, + 0x08, + 0x08, + 0x08, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, /* 1. */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x0c, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, /* 2. */ + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x16, + 0x16, + 0x16, + 0x16, + 0x16, + 0x16, + 0x16, + 0x16, /* 3. */ + 0x16, + 0x16, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x04, + 0x15, + 0x15, + 0x15, + 0x15, + 0x15, + 0x15, + 0x05, /* 4. */ + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, /* 5. */ + 0x05, + 0x05, + 0x05, + 0x04, + 0x04, + 0x04, + 0x04, + 0x05, + 0x04, + 0x15, + 0x15, + 0x15, + 0x15, + 0x15, + 0x15, + 0x05, /* 6. */ + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, + 0x05, /* 7. */ + 0x05, + 0x05, + 0x05, + 0x04, + 0x04, + 0x04, + 0x04, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, /* 8. */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, /* 9. */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, /* a. */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, /* b. */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, /* c. */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, /* d. */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, /* e. */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, /* f. */ + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, }; -#endif /* } */ +#endif /* } */ diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lctype.h b/examples/ThirdPartyLibs/lua-5.2.3/src/lctype.h index b09b21a33..10f34bb08 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lctype.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lctype.h @@ -9,7 +9,6 @@ #include "lua.h" - /* ** WARNING: the functions defined here do not necessarily correspond ** to the similar functions in the standard C ctype.h. They are @@ -20,58 +19,52 @@ #if 'A' == 65 && '0' == 48 /* ASCII case: can use its own tables; faster and fixed */ -#define LUA_USE_CTYPE 0 +#define LUA_USE_CTYPE 0 #else /* must use standard C ctype */ -#define LUA_USE_CTYPE 1 +#define LUA_USE_CTYPE 1 #endif #endif - -#if !LUA_USE_CTYPE /* { */ +#if !LUA_USE_CTYPE /* { */ #include #include "llimits.h" +#define ALPHABIT 0 +#define DIGITBIT 1 +#define PRINTBIT 2 +#define SPACEBIT 3 +#define XDIGITBIT 4 -#define ALPHABIT 0 -#define DIGITBIT 1 -#define PRINTBIT 2 -#define SPACEBIT 3 -#define XDIGITBIT 4 - - -#define MASK(B) (1 << (B)) - +#define MASK(B) (1 << (B)) /* ** add 1 to char to allow index -1 (EOZ) */ -#define testprop(c,p) (luai_ctype_[(c)+1] & (p)) +#define testprop(c, p) (luai_ctype_[(c) + 1] & (p)) /* ** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' */ -#define lislalpha(c) testprop(c, MASK(ALPHABIT)) -#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) -#define lisdigit(c) testprop(c, MASK(DIGITBIT)) -#define lisspace(c) testprop(c, MASK(SPACEBIT)) -#define lisprint(c) testprop(c, MASK(PRINTBIT)) -#define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) +#define lislalpha(c) testprop(c, MASK(ALPHABIT)) +#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) +#define lisdigit(c) testprop(c, MASK(DIGITBIT)) +#define lisspace(c) testprop(c, MASK(SPACEBIT)) +#define lisprint(c) testprop(c, MASK(PRINTBIT)) +#define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) /* ** this 'ltolower' only works for alphabetic characters */ -#define ltolower(c) ((c) | ('A' ^ 'a')) - +#define ltolower(c) ((c) | ('A' ^ 'a')) /* two more entries for 0 and -1 (EOZ) */ LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2]; - -#else /* }{ */ +#else /* }{ */ /* ** use standard C ctypes @@ -79,17 +72,15 @@ LUAI_DDEC const lu_byte luai_ctype_[UCHAR_MAX + 2]; #include +#define lislalpha(c) (isalpha(c) || (c) == '_') +#define lislalnum(c) (isalnum(c) || (c) == '_') +#define lisdigit(c) (isdigit(c)) +#define lisspace(c) (isspace(c)) +#define lisprint(c) (isprint(c)) +#define lisxdigit(c) (isxdigit(c)) -#define lislalpha(c) (isalpha(c) || (c) == '_') -#define lislalnum(c) (isalnum(c) || (c) == '_') -#define lisdigit(c) (isdigit(c)) -#define lisspace(c) (isspace(c)) -#define lisprint(c) (isprint(c)) -#define lisxdigit(c) (isxdigit(c)) +#define ltolower(c) (tolower(c)) -#define ltolower(c) (tolower(c)) - -#endif /* } */ +#endif /* } */ #endif - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/ldblib.c b/examples/ThirdPartyLibs/lua-5.2.3/src/ldblib.c index 84fe3c7d8..0b006ff15 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/ldblib.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/ldblib.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #include #include #include @@ -17,382 +16,403 @@ #include "lauxlib.h" #include "lualib.h" +#define HOOKKEY "_HKEY" -#define HOOKKEY "_HKEY" - - - -static int db_getregistry (lua_State *L) { - lua_pushvalue(L, LUA_REGISTRYINDEX); - return 1; +static int db_getregistry(lua_State *L) +{ + lua_pushvalue(L, LUA_REGISTRYINDEX); + return 1; } - -static int db_getmetatable (lua_State *L) { - luaL_checkany(L, 1); - if (!lua_getmetatable(L, 1)) { - lua_pushnil(L); /* no metatable */ - } - return 1; +static int db_getmetatable(lua_State *L) +{ + luaL_checkany(L, 1); + if (!lua_getmetatable(L, 1)) + { + lua_pushnil(L); /* no metatable */ + } + return 1; } - -static int db_setmetatable (lua_State *L) { - int t = lua_type(L, 2); - luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, - "nil or table expected"); - lua_settop(L, 2); - lua_setmetatable(L, 1); - return 1; /* return 1st argument */ +static int db_setmetatable(lua_State *L) +{ + int t = lua_type(L, 2); + luaL_argcheck(L, t == LUA_TNIL || t == LUA_TTABLE, 2, + "nil or table expected"); + lua_settop(L, 2); + lua_setmetatable(L, 1); + return 1; /* return 1st argument */ } - -static int db_getuservalue (lua_State *L) { - if (lua_type(L, 1) != LUA_TUSERDATA) - lua_pushnil(L); - else - lua_getuservalue(L, 1); - return 1; +static int db_getuservalue(lua_State *L) +{ + if (lua_type(L, 1) != LUA_TUSERDATA) + lua_pushnil(L); + else + lua_getuservalue(L, 1); + return 1; } - -static int db_setuservalue (lua_State *L) { - if (lua_type(L, 1) == LUA_TLIGHTUSERDATA) - luaL_argerror(L, 1, "full userdata expected, got light userdata"); - luaL_checktype(L, 1, LUA_TUSERDATA); - if (!lua_isnoneornil(L, 2)) - luaL_checktype(L, 2, LUA_TTABLE); - lua_settop(L, 2); - lua_setuservalue(L, 1); - return 1; +static int db_setuservalue(lua_State *L) +{ + if (lua_type(L, 1) == LUA_TLIGHTUSERDATA) + luaL_argerror(L, 1, "full userdata expected, got light userdata"); + luaL_checktype(L, 1, LUA_TUSERDATA); + if (!lua_isnoneornil(L, 2)) + luaL_checktype(L, 2, LUA_TTABLE); + lua_settop(L, 2); + lua_setuservalue(L, 1); + return 1; } - -static void settabss (lua_State *L, const char *i, const char *v) { - lua_pushstring(L, v); - lua_setfield(L, -2, i); +static void settabss(lua_State *L, const char *i, const char *v) +{ + lua_pushstring(L, v); + lua_setfield(L, -2, i); } - -static void settabsi (lua_State *L, const char *i, int v) { - lua_pushinteger(L, v); - lua_setfield(L, -2, i); +static void settabsi(lua_State *L, const char *i, int v) +{ + lua_pushinteger(L, v); + lua_setfield(L, -2, i); } - -static void settabsb (lua_State *L, const char *i, int v) { - lua_pushboolean(L, v); - lua_setfield(L, -2, i); +static void settabsb(lua_State *L, const char *i, int v) +{ + lua_pushboolean(L, v); + lua_setfield(L, -2, i); } - -static lua_State *getthread (lua_State *L, int *arg) { - if (lua_isthread(L, 1)) { - *arg = 1; - return lua_tothread(L, 1); - } - else { - *arg = 0; - return L; - } +static lua_State *getthread(lua_State *L, int *arg) +{ + if (lua_isthread(L, 1)) + { + *arg = 1; + return lua_tothread(L, 1); + } + else + { + *arg = 0; + return L; + } } - -static void treatstackoption (lua_State *L, lua_State *L1, const char *fname) { - if (L == L1) { - lua_pushvalue(L, -2); - lua_remove(L, -3); - } - else - lua_xmove(L1, L, 1); - lua_setfield(L, -2, fname); +static void treatstackoption(lua_State *L, lua_State *L1, const char *fname) +{ + if (L == L1) + { + lua_pushvalue(L, -2); + lua_remove(L, -3); + } + else + lua_xmove(L1, L, 1); + lua_setfield(L, -2, fname); } - -static int db_getinfo (lua_State *L) { - lua_Debug ar; - int arg; - lua_State *L1 = getthread(L, &arg); - const char *options = luaL_optstring(L, arg+2, "flnStu"); - if (lua_isnumber(L, arg+1)) { - if (!lua_getstack(L1, (int)lua_tointeger(L, arg+1), &ar)) { - lua_pushnil(L); /* level out of range */ - return 1; - } - } - else if (lua_isfunction(L, arg+1)) { - lua_pushfstring(L, ">%s", options); - options = lua_tostring(L, -1); - lua_pushvalue(L, arg+1); - lua_xmove(L, L1, 1); - } - else - return luaL_argerror(L, arg+1, "function or level expected"); - if (!lua_getinfo(L1, options, &ar)) - return luaL_argerror(L, arg+2, "invalid option"); - lua_createtable(L, 0, 2); - if (strchr(options, 'S')) { - settabss(L, "source", ar.source); - settabss(L, "short_src", ar.short_src); - settabsi(L, "linedefined", ar.linedefined); - settabsi(L, "lastlinedefined", ar.lastlinedefined); - settabss(L, "what", ar.what); - } - if (strchr(options, 'l')) - settabsi(L, "currentline", ar.currentline); - if (strchr(options, 'u')) { - settabsi(L, "nups", ar.nups); - settabsi(L, "nparams", ar.nparams); - settabsb(L, "isvararg", ar.isvararg); - } - if (strchr(options, 'n')) { - settabss(L, "name", ar.name); - settabss(L, "namewhat", ar.namewhat); - } - if (strchr(options, 't')) - settabsb(L, "istailcall", ar.istailcall); - if (strchr(options, 'L')) - treatstackoption(L, L1, "activelines"); - if (strchr(options, 'f')) - treatstackoption(L, L1, "func"); - return 1; /* return table */ +static int db_getinfo(lua_State *L) +{ + lua_Debug ar; + int arg; + lua_State *L1 = getthread(L, &arg); + const char *options = luaL_optstring(L, arg + 2, "flnStu"); + if (lua_isnumber(L, arg + 1)) + { + if (!lua_getstack(L1, (int)lua_tointeger(L, arg + 1), &ar)) + { + lua_pushnil(L); /* level out of range */ + return 1; + } + } + else if (lua_isfunction(L, arg + 1)) + { + lua_pushfstring(L, ">%s", options); + options = lua_tostring(L, -1); + lua_pushvalue(L, arg + 1); + lua_xmove(L, L1, 1); + } + else + return luaL_argerror(L, arg + 1, "function or level expected"); + if (!lua_getinfo(L1, options, &ar)) + return luaL_argerror(L, arg + 2, "invalid option"); + lua_createtable(L, 0, 2); + if (strchr(options, 'S')) + { + settabss(L, "source", ar.source); + settabss(L, "short_src", ar.short_src); + settabsi(L, "linedefined", ar.linedefined); + settabsi(L, "lastlinedefined", ar.lastlinedefined); + settabss(L, "what", ar.what); + } + if (strchr(options, 'l')) + settabsi(L, "currentline", ar.currentline); + if (strchr(options, 'u')) + { + settabsi(L, "nups", ar.nups); + settabsi(L, "nparams", ar.nparams); + settabsb(L, "isvararg", ar.isvararg); + } + if (strchr(options, 'n')) + { + settabss(L, "name", ar.name); + settabss(L, "namewhat", ar.namewhat); + } + if (strchr(options, 't')) + settabsb(L, "istailcall", ar.istailcall); + if (strchr(options, 'L')) + treatstackoption(L, L1, "activelines"); + if (strchr(options, 'f')) + treatstackoption(L, L1, "func"); + return 1; /* return table */ } - -static int db_getlocal (lua_State *L) { - int arg; - lua_State *L1 = getthread(L, &arg); - lua_Debug ar; - const char *name; - int nvar = luaL_checkint(L, arg+2); /* local-variable index */ - if (lua_isfunction(L, arg + 1)) { /* function argument? */ - lua_pushvalue(L, arg + 1); /* push function */ - lua_pushstring(L, lua_getlocal(L, NULL, nvar)); /* push local name */ - return 1; - } - else { /* stack-level argument */ - if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ - return luaL_argerror(L, arg+1, "level out of range"); - name = lua_getlocal(L1, &ar, nvar); - if (name) { - lua_xmove(L1, L, 1); /* push local value */ - lua_pushstring(L, name); /* push name */ - lua_pushvalue(L, -2); /* re-order */ - return 2; - } - else { - lua_pushnil(L); /* no name (nor value) */ - return 1; - } - } +static int db_getlocal(lua_State *L) +{ + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + const char *name; + int nvar = luaL_checkint(L, arg + 2); /* local-variable index */ + if (lua_isfunction(L, arg + 1)) + { /* function argument? */ + lua_pushvalue(L, arg + 1); /* push function */ + lua_pushstring(L, lua_getlocal(L, NULL, nvar)); /* push local name */ + return 1; + } + else + { /* stack-level argument */ + if (!lua_getstack(L1, luaL_checkint(L, arg + 1), &ar)) /* out of range? */ + return luaL_argerror(L, arg + 1, "level out of range"); + name = lua_getlocal(L1, &ar, nvar); + if (name) + { + lua_xmove(L1, L, 1); /* push local value */ + lua_pushstring(L, name); /* push name */ + lua_pushvalue(L, -2); /* re-order */ + return 2; + } + else + { + lua_pushnil(L); /* no name (nor value) */ + return 1; + } + } } - -static int db_setlocal (lua_State *L) { - int arg; - lua_State *L1 = getthread(L, &arg); - lua_Debug ar; - if (!lua_getstack(L1, luaL_checkint(L, arg+1), &ar)) /* out of range? */ - return luaL_argerror(L, arg+1, "level out of range"); - luaL_checkany(L, arg+3); - lua_settop(L, arg+3); - lua_xmove(L, L1, 1); - lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg+2))); - return 1; +static int db_setlocal(lua_State *L) +{ + int arg; + lua_State *L1 = getthread(L, &arg); + lua_Debug ar; + if (!lua_getstack(L1, luaL_checkint(L, arg + 1), &ar)) /* out of range? */ + return luaL_argerror(L, arg + 1, "level out of range"); + luaL_checkany(L, arg + 3); + lua_settop(L, arg + 3); + lua_xmove(L, L1, 1); + lua_pushstring(L, lua_setlocal(L1, &ar, luaL_checkint(L, arg + 2))); + return 1; } - -static int auxupvalue (lua_State *L, int get) { - const char *name; - int n = luaL_checkint(L, 2); - luaL_checktype(L, 1, LUA_TFUNCTION); - name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); - if (name == NULL) return 0; - lua_pushstring(L, name); - lua_insert(L, -(get+1)); - return get + 1; +static int auxupvalue(lua_State *L, int get) +{ + const char *name; + int n = luaL_checkint(L, 2); + luaL_checktype(L, 1, LUA_TFUNCTION); + name = get ? lua_getupvalue(L, 1, n) : lua_setupvalue(L, 1, n); + if (name == NULL) return 0; + lua_pushstring(L, name); + lua_insert(L, -(get + 1)); + return get + 1; } - -static int db_getupvalue (lua_State *L) { - return auxupvalue(L, 1); +static int db_getupvalue(lua_State *L) +{ + return auxupvalue(L, 1); } - -static int db_setupvalue (lua_State *L) { - luaL_checkany(L, 3); - return auxupvalue(L, 0); +static int db_setupvalue(lua_State *L) +{ + luaL_checkany(L, 3); + return auxupvalue(L, 0); } - -static int checkupval (lua_State *L, int argf, int argnup) { - lua_Debug ar; - int nup = luaL_checkint(L, argnup); - luaL_checktype(L, argf, LUA_TFUNCTION); - lua_pushvalue(L, argf); - lua_getinfo(L, ">u", &ar); - luaL_argcheck(L, 1 <= nup && nup <= ar.nups, argnup, "invalid upvalue index"); - return nup; +static int checkupval(lua_State *L, int argf, int argnup) +{ + lua_Debug ar; + int nup = luaL_checkint(L, argnup); + luaL_checktype(L, argf, LUA_TFUNCTION); + lua_pushvalue(L, argf); + lua_getinfo(L, ">u", &ar); + luaL_argcheck(L, 1 <= nup && nup <= ar.nups, argnup, "invalid upvalue index"); + return nup; } - -static int db_upvalueid (lua_State *L) { - int n = checkupval(L, 1, 2); - lua_pushlightuserdata(L, lua_upvalueid(L, 1, n)); - return 1; +static int db_upvalueid(lua_State *L) +{ + int n = checkupval(L, 1, 2); + lua_pushlightuserdata(L, lua_upvalueid(L, 1, n)); + return 1; } - -static int db_upvaluejoin (lua_State *L) { - int n1 = checkupval(L, 1, 2); - int n2 = checkupval(L, 3, 4); - luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected"); - luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected"); - lua_upvaluejoin(L, 1, n1, 3, n2); - return 0; +static int db_upvaluejoin(lua_State *L) +{ + int n1 = checkupval(L, 1, 2); + int n2 = checkupval(L, 3, 4); + luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected"); + luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected"); + lua_upvaluejoin(L, 1, n1, 3, n2); + return 0; } +#define gethooktable(L) luaL_getsubtable(L, LUA_REGISTRYINDEX, HOOKKEY) -#define gethooktable(L) luaL_getsubtable(L, LUA_REGISTRYINDEX, HOOKKEY) - - -static void hookf (lua_State *L, lua_Debug *ar) { - static const char *const hooknames[] = - {"call", "return", "line", "count", "tail call"}; - gethooktable(L); - lua_pushthread(L); - lua_rawget(L, -2); - if (lua_isfunction(L, -1)) { - lua_pushstring(L, hooknames[(int)ar->event]); - if (ar->currentline >= 0) - lua_pushinteger(L, ar->currentline); - else lua_pushnil(L); - lua_assert(lua_getinfo(L, "lS", ar)); - lua_call(L, 2, 0); - } +static void hookf(lua_State *L, lua_Debug *ar) +{ + static const char *const hooknames[] = + {"call", "return", "line", "count", "tail call"}; + gethooktable(L); + lua_pushthread(L); + lua_rawget(L, -2); + if (lua_isfunction(L, -1)) + { + lua_pushstring(L, hooknames[(int)ar->event]); + if (ar->currentline >= 0) + lua_pushinteger(L, ar->currentline); + else + lua_pushnil(L); + lua_assert(lua_getinfo(L, "lS", ar)); + lua_call(L, 2, 0); + } } - -static int makemask (const char *smask, int count) { - int mask = 0; - if (strchr(smask, 'c')) mask |= LUA_MASKCALL; - if (strchr(smask, 'r')) mask |= LUA_MASKRET; - if (strchr(smask, 'l')) mask |= LUA_MASKLINE; - if (count > 0) mask |= LUA_MASKCOUNT; - return mask; +static int makemask(const char *smask, int count) +{ + int mask = 0; + if (strchr(smask, 'c')) mask |= LUA_MASKCALL; + if (strchr(smask, 'r')) mask |= LUA_MASKRET; + if (strchr(smask, 'l')) mask |= LUA_MASKLINE; + if (count > 0) mask |= LUA_MASKCOUNT; + return mask; } - -static char *unmakemask (int mask, char *smask) { - int i = 0; - if (mask & LUA_MASKCALL) smask[i++] = 'c'; - if (mask & LUA_MASKRET) smask[i++] = 'r'; - if (mask & LUA_MASKLINE) smask[i++] = 'l'; - smask[i] = '\0'; - return smask; +static char *unmakemask(int mask, char *smask) +{ + int i = 0; + if (mask & LUA_MASKCALL) smask[i++] = 'c'; + if (mask & LUA_MASKRET) smask[i++] = 'r'; + if (mask & LUA_MASKLINE) smask[i++] = 'l'; + smask[i] = '\0'; + return smask; } - -static int db_sethook (lua_State *L) { - int arg, mask, count; - lua_Hook func; - lua_State *L1 = getthread(L, &arg); - if (lua_isnoneornil(L, arg+1)) { - lua_settop(L, arg+1); - func = NULL; mask = 0; count = 0; /* turn off hooks */ - } - else { - const char *smask = luaL_checkstring(L, arg+2); - luaL_checktype(L, arg+1, LUA_TFUNCTION); - count = luaL_optint(L, arg+3, 0); - func = hookf; mask = makemask(smask, count); - } - if (gethooktable(L) == 0) { /* creating hook table? */ - lua_pushstring(L, "k"); - lua_setfield(L, -2, "__mode"); /** hooktable.__mode = "k" */ - lua_pushvalue(L, -1); - lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */ - } - lua_pushthread(L1); lua_xmove(L1, L, 1); - lua_pushvalue(L, arg+1); - lua_rawset(L, -3); /* set new hook */ - lua_sethook(L1, func, mask, count); /* set hooks */ - return 0; +static int db_sethook(lua_State *L) +{ + int arg, mask, count; + lua_Hook func; + lua_State *L1 = getthread(L, &arg); + if (lua_isnoneornil(L, arg + 1)) + { + lua_settop(L, arg + 1); + func = NULL; + mask = 0; + count = 0; /* turn off hooks */ + } + else + { + const char *smask = luaL_checkstring(L, arg + 2); + luaL_checktype(L, arg + 1, LUA_TFUNCTION); + count = luaL_optint(L, arg + 3, 0); + func = hookf; + mask = makemask(smask, count); + } + if (gethooktable(L) == 0) + { /* creating hook table? */ + lua_pushstring(L, "k"); + lua_setfield(L, -2, "__mode"); /** hooktable.__mode = "k" */ + lua_pushvalue(L, -1); + lua_setmetatable(L, -2); /* setmetatable(hooktable) = hooktable */ + } + lua_pushthread(L1); + lua_xmove(L1, L, 1); + lua_pushvalue(L, arg + 1); + lua_rawset(L, -3); /* set new hook */ + lua_sethook(L1, func, mask, count); /* set hooks */ + return 0; } - -static int db_gethook (lua_State *L) { - int arg; - lua_State *L1 = getthread(L, &arg); - char buff[5]; - int mask = lua_gethookmask(L1); - lua_Hook hook = lua_gethook(L1); - if (hook != NULL && hook != hookf) /* external hook? */ - lua_pushliteral(L, "external hook"); - else { - gethooktable(L); - lua_pushthread(L1); lua_xmove(L1, L, 1); - lua_rawget(L, -2); /* get hook */ - lua_remove(L, -2); /* remove hook table */ - } - lua_pushstring(L, unmakemask(mask, buff)); - lua_pushinteger(L, lua_gethookcount(L1)); - return 3; +static int db_gethook(lua_State *L) +{ + int arg; + lua_State *L1 = getthread(L, &arg); + char buff[5]; + int mask = lua_gethookmask(L1); + lua_Hook hook = lua_gethook(L1); + if (hook != NULL && hook != hookf) /* external hook? */ + lua_pushliteral(L, "external hook"); + else + { + gethooktable(L); + lua_pushthread(L1); + lua_xmove(L1, L, 1); + lua_rawget(L, -2); /* get hook */ + lua_remove(L, -2); /* remove hook table */ + } + lua_pushstring(L, unmakemask(mask, buff)); + lua_pushinteger(L, lua_gethookcount(L1)); + return 3; } - -static int db_debug (lua_State *L) { - for (;;) { - char buffer[250]; - luai_writestringerror("%s", "lua_debug> "); - if (fgets(buffer, sizeof(buffer), stdin) == 0 || - strcmp(buffer, "cont\n") == 0) - return 0; - if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || - lua_pcall(L, 0, 0, 0)) - luai_writestringerror("%s\n", lua_tostring(L, -1)); - lua_settop(L, 0); /* remove eventual returns */ - } +static int db_debug(lua_State *L) +{ + for (;;) + { + char buffer[250]; + luai_writestringerror("%s", "lua_debug> "); + if (fgets(buffer, sizeof(buffer), stdin) == 0 || + strcmp(buffer, "cont\n") == 0) + return 0; + if (luaL_loadbuffer(L, buffer, strlen(buffer), "=(debug command)") || + lua_pcall(L, 0, 0, 0)) + luai_writestringerror("%s\n", lua_tostring(L, -1)); + lua_settop(L, 0); /* remove eventual returns */ + } } - -static int db_traceback (lua_State *L) { - int arg; - lua_State *L1 = getthread(L, &arg); - const char *msg = lua_tostring(L, arg + 1); - if (msg == NULL && !lua_isnoneornil(L, arg + 1)) /* non-string 'msg'? */ - lua_pushvalue(L, arg + 1); /* return it untouched */ - else { - int level = luaL_optint(L, arg + 2, (L == L1) ? 1 : 0); - luaL_traceback(L, L1, msg, level); - } - return 1; +static int db_traceback(lua_State *L) +{ + int arg; + lua_State *L1 = getthread(L, &arg); + const char *msg = lua_tostring(L, arg + 1); + if (msg == NULL && !lua_isnoneornil(L, arg + 1)) /* non-string 'msg'? */ + lua_pushvalue(L, arg + 1); /* return it untouched */ + else + { + int level = luaL_optint(L, arg + 2, (L == L1) ? 1 : 0); + luaL_traceback(L, L1, msg, level); + } + return 1; } - static const luaL_Reg dblib[] = { - {"debug", db_debug}, - {"getuservalue", db_getuservalue}, - {"gethook", db_gethook}, - {"getinfo", db_getinfo}, - {"getlocal", db_getlocal}, - {"getregistry", db_getregistry}, - {"getmetatable", db_getmetatable}, - {"getupvalue", db_getupvalue}, - {"upvaluejoin", db_upvaluejoin}, - {"upvalueid", db_upvalueid}, - {"setuservalue", db_setuservalue}, - {"sethook", db_sethook}, - {"setlocal", db_setlocal}, - {"setmetatable", db_setmetatable}, - {"setupvalue", db_setupvalue}, - {"traceback", db_traceback}, - {NULL, NULL} -}; + {"debug", db_debug}, + {"getuservalue", db_getuservalue}, + {"gethook", db_gethook}, + {"getinfo", db_getinfo}, + {"getlocal", db_getlocal}, + {"getregistry", db_getregistry}, + {"getmetatable", db_getmetatable}, + {"getupvalue", db_getupvalue}, + {"upvaluejoin", db_upvaluejoin}, + {"upvalueid", db_upvalueid}, + {"setuservalue", db_setuservalue}, + {"sethook", db_sethook}, + {"setlocal", db_setlocal}, + {"setmetatable", db_setmetatable}, + {"setupvalue", db_setupvalue}, + {"traceback", db_traceback}, + {NULL, NULL}}; - -LUAMOD_API int luaopen_debug (lua_State *L) { - luaL_newlib(L, dblib); - return 1; +LUAMOD_API int luaopen_debug(lua_State *L) +{ + luaL_newlib(L, dblib); + return 1; } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/ldebug.c b/examples/ThirdPartyLibs/lua-5.2.3/src/ldebug.c index 20d663eff..399398e8c 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/ldebug.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/ldebug.c @@ -4,12 +4,10 @@ ** See Copyright Notice in lua.h */ - #include #include #include - #define ldebug_c #define LUA_CORE @@ -28,566 +26,649 @@ #include "ltm.h" #include "lvm.h" +#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL) +static const char *getfuncname(lua_State *L, CallInfo *ci, const char **name); -#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_TCCL) - - -static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name); - - -static int currentpc (CallInfo *ci) { - lua_assert(isLua(ci)); - return pcRel(ci->u.l.savedpc, ci_func(ci)->p); +static int currentpc(CallInfo *ci) +{ + lua_assert(isLua(ci)); + return pcRel(ci->u.l.savedpc, ci_func(ci)->p); } - -static int currentline (CallInfo *ci) { - return getfuncline(ci_func(ci)->p, currentpc(ci)); +static int currentline(CallInfo *ci) +{ + return getfuncline(ci_func(ci)->p, currentpc(ci)); } - /* ** this function can be called asynchronous (e.g. during a signal) */ -LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { - if (func == NULL || mask == 0) { /* turn off hooks? */ - mask = 0; - func = NULL; - } - if (isLua(L->ci)) - L->oldpc = L->ci->u.l.savedpc; - L->hook = func; - L->basehookcount = count; - resethookcount(L); - L->hookmask = cast_byte(mask); - return 1; +LUA_API int lua_sethook(lua_State *L, lua_Hook func, int mask, int count) +{ + if (func == NULL || mask == 0) + { /* turn off hooks? */ + mask = 0; + func = NULL; + } + if (isLua(L->ci)) + L->oldpc = L->ci->u.l.savedpc; + L->hook = func; + L->basehookcount = count; + resethookcount(L); + L->hookmask = cast_byte(mask); + return 1; } - -LUA_API lua_Hook lua_gethook (lua_State *L) { - return L->hook; +LUA_API lua_Hook lua_gethook(lua_State *L) +{ + return L->hook; } - -LUA_API int lua_gethookmask (lua_State *L) { - return L->hookmask; +LUA_API int lua_gethookmask(lua_State *L) +{ + return L->hookmask; } - -LUA_API int lua_gethookcount (lua_State *L) { - return L->basehookcount; +LUA_API int lua_gethookcount(lua_State *L) +{ + return L->basehookcount; } - -LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar) { - int status; - CallInfo *ci; - if (level < 0) return 0; /* invalid (negative) level */ - lua_lock(L); - for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous) - level--; - if (level == 0 && ci != &L->base_ci) { /* level found? */ - status = 1; - ar->i_ci = ci; - } - else status = 0; /* no such level */ - lua_unlock(L); - return status; +LUA_API int lua_getstack(lua_State *L, int level, lua_Debug *ar) +{ + int status; + CallInfo *ci; + if (level < 0) return 0; /* invalid (negative) level */ + lua_lock(L); + for (ci = L->ci; level > 0 && ci != &L->base_ci; ci = ci->previous) + level--; + if (level == 0 && ci != &L->base_ci) + { /* level found? */ + status = 1; + ar->i_ci = ci; + } + else + status = 0; /* no such level */ + lua_unlock(L); + return status; } - -static const char *upvalname (Proto *p, int uv) { - TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name); - if (s == NULL) return "?"; - else return getstr(s); +static const char *upvalname(Proto *p, int uv) +{ + TString *s = check_exp(uv < p->sizeupvalues, p->upvalues[uv].name); + if (s == NULL) + return "?"; + else + return getstr(s); } - -static const char *findvararg (CallInfo *ci, int n, StkId *pos) { - int nparams = clLvalue(ci->func)->p->numparams; - if (n >= ci->u.l.base - ci->func - nparams) - return NULL; /* no such vararg */ - else { - *pos = ci->func + nparams + n; - return "(*vararg)"; /* generic name for any vararg */ - } +static const char *findvararg(CallInfo *ci, int n, StkId *pos) +{ + int nparams = clLvalue(ci->func)->p->numparams; + if (n >= ci->u.l.base - ci->func - nparams) + return NULL; /* no such vararg */ + else + { + *pos = ci->func + nparams + n; + return "(*vararg)"; /* generic name for any vararg */ + } } - -static const char *findlocal (lua_State *L, CallInfo *ci, int n, - StkId *pos) { - const char *name = NULL; - StkId base; - if (isLua(ci)) { - if (n < 0) /* access to vararg values? */ - return findvararg(ci, -n, pos); - else { - base = ci->u.l.base; - name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); - } - } - else - base = ci->func + 1; - if (name == NULL) { /* no 'standard' name? */ - StkId limit = (ci == L->ci) ? L->top : ci->next->func; - if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */ - name = "(*temporary)"; /* generic name for any valid slot */ - else - return NULL; /* no name */ - } - *pos = base + (n - 1); - return name; +static const char *findlocal(lua_State *L, CallInfo *ci, int n, + StkId *pos) +{ + const char *name = NULL; + StkId base; + if (isLua(ci)) + { + if (n < 0) /* access to vararg values? */ + return findvararg(ci, -n, pos); + else + { + base = ci->u.l.base; + name = luaF_getlocalname(ci_func(ci)->p, n, currentpc(ci)); + } + } + else + base = ci->func + 1; + if (name == NULL) + { /* no 'standard' name? */ + StkId limit = (ci == L->ci) ? L->top : ci->next->func; + if (limit - base >= n && n > 0) /* is 'n' inside 'ci' stack? */ + name = "(*temporary)"; /* generic name for any valid slot */ + else + return NULL; /* no name */ + } + *pos = base + (n - 1); + return name; } - -LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n) { - const char *name; - lua_lock(L); - if (ar == NULL) { /* information about non-active function? */ - if (!isLfunction(L->top - 1)) /* not a Lua function? */ - name = NULL; - else /* consider live variables at function start (parameters) */ - name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0); - } - else { /* active function; get information through 'ar' */ - StkId pos = 0; /* to avoid warnings */ - name = findlocal(L, ar->i_ci, n, &pos); - if (name) { - setobj2s(L, L->top, pos); - api_incr_top(L); - } - } - lua_unlock(L); - return name; +LUA_API const char *lua_getlocal(lua_State *L, const lua_Debug *ar, int n) +{ + const char *name; + lua_lock(L); + if (ar == NULL) + { /* information about non-active function? */ + if (!isLfunction(L->top - 1)) /* not a Lua function? */ + name = NULL; + else /* consider live variables at function start (parameters) */ + name = luaF_getlocalname(clLvalue(L->top - 1)->p, n, 0); + } + else + { /* active function; get information through 'ar' */ + StkId pos = 0; /* to avoid warnings */ + name = findlocal(L, ar->i_ci, n, &pos); + if (name) + { + setobj2s(L, L->top, pos); + api_incr_top(L); + } + } + lua_unlock(L); + return name; } - -LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) { - StkId pos = 0; /* to avoid warnings */ - const char *name = findlocal(L, ar->i_ci, n, &pos); - lua_lock(L); - if (name) - setobjs2s(L, pos, L->top - 1); - L->top--; /* pop value */ - lua_unlock(L); - return name; +LUA_API const char *lua_setlocal(lua_State *L, const lua_Debug *ar, int n) +{ + StkId pos = 0; /* to avoid warnings */ + const char *name = findlocal(L, ar->i_ci, n, &pos); + lua_lock(L); + if (name) + setobjs2s(L, pos, L->top - 1); + L->top--; /* pop value */ + lua_unlock(L); + return name; } - -static void funcinfo (lua_Debug *ar, Closure *cl) { - if (noLuaClosure(cl)) { - ar->source = "=[C]"; - ar->linedefined = -1; - ar->lastlinedefined = -1; - ar->what = "C"; - } - else { - Proto *p = cl->l.p; - ar->source = p->source ? getstr(p->source) : "=?"; - ar->linedefined = p->linedefined; - ar->lastlinedefined = p->lastlinedefined; - ar->what = (ar->linedefined == 0) ? "main" : "Lua"; - } - luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); +static void funcinfo(lua_Debug *ar, Closure *cl) +{ + if (noLuaClosure(cl)) + { + ar->source = "=[C]"; + ar->linedefined = -1; + ar->lastlinedefined = -1; + ar->what = "C"; + } + else + { + Proto *p = cl->l.p; + ar->source = p->source ? getstr(p->source) : "=?"; + ar->linedefined = p->linedefined; + ar->lastlinedefined = p->lastlinedefined; + ar->what = (ar->linedefined == 0) ? "main" : "Lua"; + } + luaO_chunkid(ar->short_src, ar->source, LUA_IDSIZE); } - -static void collectvalidlines (lua_State *L, Closure *f) { - if (noLuaClosure(f)) { - setnilvalue(L->top); - api_incr_top(L); - } - else { - int i; - TValue v; - int *lineinfo = f->l.p->lineinfo; - Table *t = luaH_new(L); /* new table to store active lines */ - sethvalue(L, L->top, t); /* push it on stack */ - api_incr_top(L); - setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */ - for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */ - luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */ - } +static void collectvalidlines(lua_State *L, Closure *f) +{ + if (noLuaClosure(f)) + { + setnilvalue(L->top); + api_incr_top(L); + } + else + { + int i; + TValue v; + int *lineinfo = f->l.p->lineinfo; + Table *t = luaH_new(L); /* new table to store active lines */ + sethvalue(L, L->top, t); /* push it on stack */ + api_incr_top(L); + setbvalue(&v, 1); /* boolean 'true' to be the value of all indices */ + for (i = 0; i < f->l.p->sizelineinfo; i++) /* for all lines with code */ + luaH_setint(L, t, lineinfo[i], &v); /* table[line] = true */ + } } - -static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar, - Closure *f, CallInfo *ci) { - int status = 1; - for (; *what; what++) { - switch (*what) { - case 'S': { - funcinfo(ar, f); - break; - } - case 'l': { - ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1; - break; - } - case 'u': { - ar->nups = (f == NULL) ? 0 : f->c.nupvalues; - if (noLuaClosure(f)) { - ar->isvararg = 1; - ar->nparams = 0; - } - else { - ar->isvararg = f->l.p->is_vararg; - ar->nparams = f->l.p->numparams; - } - break; - } - case 't': { - ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0; - break; - } - case 'n': { - /* calling function is a known Lua function? */ - if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous)) - ar->namewhat = getfuncname(L, ci->previous, &ar->name); - else - ar->namewhat = NULL; - if (ar->namewhat == NULL) { - ar->namewhat = ""; /* not found */ - ar->name = NULL; - } - break; - } - case 'L': - case 'f': /* handled by lua_getinfo */ - break; - default: status = 0; /* invalid option */ - } - } - return status; +static int auxgetinfo(lua_State *L, const char *what, lua_Debug *ar, + Closure *f, CallInfo *ci) +{ + int status = 1; + for (; *what; what++) + { + switch (*what) + { + case 'S': + { + funcinfo(ar, f); + break; + } + case 'l': + { + ar->currentline = (ci && isLua(ci)) ? currentline(ci) : -1; + break; + } + case 'u': + { + ar->nups = (f == NULL) ? 0 : f->c.nupvalues; + if (noLuaClosure(f)) + { + ar->isvararg = 1; + ar->nparams = 0; + } + else + { + ar->isvararg = f->l.p->is_vararg; + ar->nparams = f->l.p->numparams; + } + break; + } + case 't': + { + ar->istailcall = (ci) ? ci->callstatus & CIST_TAIL : 0; + break; + } + case 'n': + { + /* calling function is a known Lua function? */ + if (ci && !(ci->callstatus & CIST_TAIL) && isLua(ci->previous)) + ar->namewhat = getfuncname(L, ci->previous, &ar->name); + else + ar->namewhat = NULL; + if (ar->namewhat == NULL) + { + ar->namewhat = ""; /* not found */ + ar->name = NULL; + } + break; + } + case 'L': + case 'f': /* handled by lua_getinfo */ + break; + default: + status = 0; /* invalid option */ + } + } + return status; } - -LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { - int status; - Closure *cl; - CallInfo *ci; - StkId func; - lua_lock(L); - if (*what == '>') { - ci = NULL; - func = L->top - 1; - api_check(L, ttisfunction(func), "function expected"); - what++; /* skip the '>' */ - L->top--; /* pop function */ - } - else { - ci = ar->i_ci; - func = ci->func; - lua_assert(ttisfunction(ci->func)); - } - cl = ttisclosure(func) ? clvalue(func) : NULL; - status = auxgetinfo(L, what, ar, cl, ci); - if (strchr(what, 'f')) { - setobjs2s(L, L->top, func); - api_incr_top(L); - } - if (strchr(what, 'L')) - collectvalidlines(L, cl); - lua_unlock(L); - return status; +LUA_API int lua_getinfo(lua_State *L, const char *what, lua_Debug *ar) +{ + int status; + Closure *cl; + CallInfo *ci; + StkId func; + lua_lock(L); + if (*what == '>') + { + ci = NULL; + func = L->top - 1; + api_check(L, ttisfunction(func), "function expected"); + what++; /* skip the '>' */ + L->top--; /* pop function */ + } + else + { + ci = ar->i_ci; + func = ci->func; + lua_assert(ttisfunction(ci->func)); + } + cl = ttisclosure(func) ? clvalue(func) : NULL; + status = auxgetinfo(L, what, ar, cl, ci); + if (strchr(what, 'f')) + { + setobjs2s(L, L->top, func); + api_incr_top(L); + } + if (strchr(what, 'L')) + collectvalidlines(L, cl); + lua_unlock(L); + return status; } - /* ** {====================================================== ** Symbolic Execution ** ======================================================= */ -static const char *getobjname (Proto *p, int lastpc, int reg, - const char **name); - +static const char *getobjname(Proto *p, int lastpc, int reg, + const char **name); /* ** find a "name" for the RK value 'c' */ -static void kname (Proto *p, int pc, int c, const char **name) { - if (ISK(c)) { /* is 'c' a constant? */ - TValue *kvalue = &p->k[INDEXK(c)]; - if (ttisstring(kvalue)) { /* literal constant? */ - *name = svalue(kvalue); /* it is its own name */ - return; - } - /* else no reasonable name found */ - } - else { /* 'c' is a register */ - const char *what = getobjname(p, pc, c, name); /* search for 'c' */ - if (what && *what == 'c') { /* found a constant name? */ - return; /* 'name' already filled */ - } - /* else no reasonable name found */ - } - *name = "?"; /* no reasonable name found */ +static void kname(Proto *p, int pc, int c, const char **name) +{ + if (ISK(c)) + { /* is 'c' a constant? */ + TValue *kvalue = &p->k[INDEXK(c)]; + if (ttisstring(kvalue)) + { /* literal constant? */ + *name = svalue(kvalue); /* it is its own name */ + return; + } + /* else no reasonable name found */ + } + else + { /* 'c' is a register */ + const char *what = getobjname(p, pc, c, name); /* search for 'c' */ + if (what && *what == 'c') + { /* found a constant name? */ + return; /* 'name' already filled */ + } + /* else no reasonable name found */ + } + *name = "?"; /* no reasonable name found */ } - -static int filterpc (int pc, int jmptarget) { - if (pc < jmptarget) /* is code conditional (inside a jump)? */ - return -1; /* cannot know who sets that register */ - else return pc; /* current position sets that register */ +static int filterpc(int pc, int jmptarget) +{ + if (pc < jmptarget) /* is code conditional (inside a jump)? */ + return -1; /* cannot know who sets that register */ + else + return pc; /* current position sets that register */ } - /* ** try to find last instruction before 'lastpc' that modified register 'reg' */ -static int findsetreg (Proto *p, int lastpc, int reg) { - int pc; - int setreg = -1; /* keep last instruction that changed 'reg' */ - int jmptarget = 0; /* any code before this address is conditional */ - for (pc = 0; pc < lastpc; pc++) { - Instruction i = p->code[pc]; - OpCode op = GET_OPCODE(i); - int a = GETARG_A(i); - switch (op) { - case OP_LOADNIL: { - int b = GETARG_B(i); - if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */ - setreg = filterpc(pc, jmptarget); - break; - } - case OP_TFORCALL: { - if (reg >= a + 2) /* affect all regs above its base */ - setreg = filterpc(pc, jmptarget); - break; - } - case OP_CALL: - case OP_TAILCALL: { - if (reg >= a) /* affect all registers above base */ - setreg = filterpc(pc, jmptarget); - break; - } - case OP_JMP: { - int b = GETARG_sBx(i); - int dest = pc + 1 + b; - /* jump is forward and do not skip `lastpc'? */ - if (pc < dest && dest <= lastpc) { - if (dest > jmptarget) - jmptarget = dest; /* update 'jmptarget' */ - } - break; - } - case OP_TEST: { - if (reg == a) /* jumped code can change 'a' */ - setreg = filterpc(pc, jmptarget); - break; - } - default: - if (testAMode(op) && reg == a) /* any instruction that set A */ - setreg = filterpc(pc, jmptarget); - break; - } - } - return setreg; +static int findsetreg(Proto *p, int lastpc, int reg) +{ + int pc; + int setreg = -1; /* keep last instruction that changed 'reg' */ + int jmptarget = 0; /* any code before this address is conditional */ + for (pc = 0; pc < lastpc; pc++) + { + Instruction i = p->code[pc]; + OpCode op = GET_OPCODE(i); + int a = GETARG_A(i); + switch (op) + { + case OP_LOADNIL: + { + int b = GETARG_B(i); + if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */ + setreg = filterpc(pc, jmptarget); + break; + } + case OP_TFORCALL: + { + if (reg >= a + 2) /* affect all regs above its base */ + setreg = filterpc(pc, jmptarget); + break; + } + case OP_CALL: + case OP_TAILCALL: + { + if (reg >= a) /* affect all registers above base */ + setreg = filterpc(pc, jmptarget); + break; + } + case OP_JMP: + { + int b = GETARG_sBx(i); + int dest = pc + 1 + b; + /* jump is forward and do not skip `lastpc'? */ + if (pc < dest && dest <= lastpc) + { + if (dest > jmptarget) + jmptarget = dest; /* update 'jmptarget' */ + } + break; + } + case OP_TEST: + { + if (reg == a) /* jumped code can change 'a' */ + setreg = filterpc(pc, jmptarget); + break; + } + default: + if (testAMode(op) && reg == a) /* any instruction that set A */ + setreg = filterpc(pc, jmptarget); + break; + } + } + return setreg; } - -static const char *getobjname (Proto *p, int lastpc, int reg, - const char **name) { - int pc; - *name = luaF_getlocalname(p, reg + 1, lastpc); - if (*name) /* is a local? */ - return "local"; - /* else try symbolic execution */ - pc = findsetreg(p, lastpc, reg); - if (pc != -1) { /* could find instruction? */ - Instruction i = p->code[pc]; - OpCode op = GET_OPCODE(i); - switch (op) { - case OP_MOVE: { - int b = GETARG_B(i); /* move from 'b' to 'a' */ - if (b < GETARG_A(i)) - return getobjname(p, pc, b, name); /* get name for 'b' */ - break; - } - case OP_GETTABUP: - case OP_GETTABLE: { - int k = GETARG_C(i); /* key index */ - int t = GETARG_B(i); /* table index */ - const char *vn = (op == OP_GETTABLE) /* name of indexed variable */ - ? luaF_getlocalname(p, t + 1, pc) - : upvalname(p, t); - kname(p, pc, k, name); - return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field"; - } - case OP_GETUPVAL: { - *name = upvalname(p, GETARG_B(i)); - return "upvalue"; - } - case OP_LOADK: - case OP_LOADKX: { - int b = (op == OP_LOADK) ? GETARG_Bx(i) - : GETARG_Ax(p->code[pc + 1]); - if (ttisstring(&p->k[b])) { - *name = svalue(&p->k[b]); - return "constant"; - } - break; - } - case OP_SELF: { - int k = GETARG_C(i); /* key index */ - kname(p, pc, k, name); - return "method"; - } - default: break; /* go through to return NULL */ - } - } - return NULL; /* could not find reasonable name */ +static const char *getobjname(Proto *p, int lastpc, int reg, + const char **name) +{ + int pc; + *name = luaF_getlocalname(p, reg + 1, lastpc); + if (*name) /* is a local? */ + return "local"; + /* else try symbolic execution */ + pc = findsetreg(p, lastpc, reg); + if (pc != -1) + { /* could find instruction? */ + Instruction i = p->code[pc]; + OpCode op = GET_OPCODE(i); + switch (op) + { + case OP_MOVE: + { + int b = GETARG_B(i); /* move from 'b' to 'a' */ + if (b < GETARG_A(i)) + return getobjname(p, pc, b, name); /* get name for 'b' */ + break; + } + case OP_GETTABUP: + case OP_GETTABLE: + { + int k = GETARG_C(i); /* key index */ + int t = GETARG_B(i); /* table index */ + const char *vn = (op == OP_GETTABLE) /* name of indexed variable */ + ? luaF_getlocalname(p, t + 1, pc) + : upvalname(p, t); + kname(p, pc, k, name); + return (vn && strcmp(vn, LUA_ENV) == 0) ? "global" : "field"; + } + case OP_GETUPVAL: + { + *name = upvalname(p, GETARG_B(i)); + return "upvalue"; + } + case OP_LOADK: + case OP_LOADKX: + { + int b = (op == OP_LOADK) ? GETARG_Bx(i) + : GETARG_Ax(p->code[pc + 1]); + if (ttisstring(&p->k[b])) + { + *name = svalue(&p->k[b]); + return "constant"; + } + break; + } + case OP_SELF: + { + int k = GETARG_C(i); /* key index */ + kname(p, pc, k, name); + return "method"; + } + default: + break; /* go through to return NULL */ + } + } + return NULL; /* could not find reasonable name */ } - -static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { - TMS tm; - Proto *p = ci_func(ci)->p; /* calling function */ - int pc = currentpc(ci); /* calling instruction index */ - Instruction i = p->code[pc]; /* calling instruction */ - switch (GET_OPCODE(i)) { - case OP_CALL: - case OP_TAILCALL: /* get function name */ - return getobjname(p, pc, GETARG_A(i), name); - case OP_TFORCALL: { /* for iterator */ - *name = "for iterator"; - return "for iterator"; - } - /* all other instructions can call only through metamethods */ - case OP_SELF: - case OP_GETTABUP: - case OP_GETTABLE: tm = TM_INDEX; break; - case OP_SETTABUP: - case OP_SETTABLE: tm = TM_NEWINDEX; break; - case OP_EQ: tm = TM_EQ; break; - case OP_ADD: tm = TM_ADD; break; - case OP_SUB: tm = TM_SUB; break; - case OP_MUL: tm = TM_MUL; break; - case OP_DIV: tm = TM_DIV; break; - case OP_MOD: tm = TM_MOD; break; - case OP_POW: tm = TM_POW; break; - case OP_UNM: tm = TM_UNM; break; - case OP_LEN: tm = TM_LEN; break; - case OP_LT: tm = TM_LT; break; - case OP_LE: tm = TM_LE; break; - case OP_CONCAT: tm = TM_CONCAT; break; - default: - return NULL; /* else no useful name can be found */ - } - *name = getstr(G(L)->tmname[tm]); - return "metamethod"; +static const char *getfuncname(lua_State *L, CallInfo *ci, const char **name) +{ + TMS tm; + Proto *p = ci_func(ci)->p; /* calling function */ + int pc = currentpc(ci); /* calling instruction index */ + Instruction i = p->code[pc]; /* calling instruction */ + switch (GET_OPCODE(i)) + { + case OP_CALL: + case OP_TAILCALL: /* get function name */ + return getobjname(p, pc, GETARG_A(i), name); + case OP_TFORCALL: + { /* for iterator */ + *name = "for iterator"; + return "for iterator"; + } + /* all other instructions can call only through metamethods */ + case OP_SELF: + case OP_GETTABUP: + case OP_GETTABLE: + tm = TM_INDEX; + break; + case OP_SETTABUP: + case OP_SETTABLE: + tm = TM_NEWINDEX; + break; + case OP_EQ: + tm = TM_EQ; + break; + case OP_ADD: + tm = TM_ADD; + break; + case OP_SUB: + tm = TM_SUB; + break; + case OP_MUL: + tm = TM_MUL; + break; + case OP_DIV: + tm = TM_DIV; + break; + case OP_MOD: + tm = TM_MOD; + break; + case OP_POW: + tm = TM_POW; + break; + case OP_UNM: + tm = TM_UNM; + break; + case OP_LEN: + tm = TM_LEN; + break; + case OP_LT: + tm = TM_LT; + break; + case OP_LE: + tm = TM_LE; + break; + case OP_CONCAT: + tm = TM_CONCAT; + break; + default: + return NULL; /* else no useful name can be found */ + } + *name = getstr(G(L)->tmname[tm]); + return "metamethod"; } /* }====================================================== */ - - /* ** only ANSI way to check whether a pointer points to an array ** (used only for error messages, so efficiency is not a big concern) */ -static int isinstack (CallInfo *ci, const TValue *o) { - StkId p; - for (p = ci->u.l.base; p < ci->top; p++) - if (o == p) return 1; - return 0; +static int isinstack(CallInfo *ci, const TValue *o) +{ + StkId p; + for (p = ci->u.l.base; p < ci->top; p++) + if (o == p) return 1; + return 0; } - -static const char *getupvalname (CallInfo *ci, const TValue *o, - const char **name) { - LClosure *c = ci_func(ci); - int i; - for (i = 0; i < c->nupvalues; i++) { - if (c->upvals[i]->v == o) { - *name = upvalname(c->p, i); - return "upvalue"; - } - } - return NULL; +static const char *getupvalname(CallInfo *ci, const TValue *o, + const char **name) +{ + LClosure *c = ci_func(ci); + int i; + for (i = 0; i < c->nupvalues; i++) + { + if (c->upvals[i]->v == o) + { + *name = upvalname(c->p, i); + return "upvalue"; + } + } + return NULL; } - -l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) { - CallInfo *ci = L->ci; - const char *name = NULL; - const char *t = objtypename(o); - const char *kind = NULL; - if (isLua(ci)) { - kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ - if (!kind && isinstack(ci, o)) /* no? try a register */ - kind = getobjname(ci_func(ci)->p, currentpc(ci), - cast_int(o - ci->u.l.base), &name); - } - if (kind) - luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", - op, kind, name, t); - else - luaG_runerror(L, "attempt to %s a %s value", op, t); +l_noret luaG_typeerror(lua_State *L, const TValue *o, const char *op) +{ + CallInfo *ci = L->ci; + const char *name = NULL; + const char *t = objtypename(o); + const char *kind = NULL; + if (isLua(ci)) + { + kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */ + if (!kind && isinstack(ci, o)) /* no? try a register */ + kind = getobjname(ci_func(ci)->p, currentpc(ci), + cast_int(o - ci->u.l.base), &name); + } + if (kind) + luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)", + op, kind, name, t); + else + luaG_runerror(L, "attempt to %s a %s value", op, t); } - -l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2) { - if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; - lua_assert(!ttisstring(p1) && !ttisnumber(p1)); - luaG_typeerror(L, p1, "concatenate"); +l_noret luaG_concaterror(lua_State *L, StkId p1, StkId p2) +{ + if (ttisstring(p1) || ttisnumber(p1)) p1 = p2; + lua_assert(!ttisstring(p1) && !ttisnumber(p1)); + luaG_typeerror(L, p1, "concatenate"); } - -l_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) { - TValue temp; - if (luaV_tonumber(p1, &temp) == NULL) - p2 = p1; /* first operand is wrong */ - luaG_typeerror(L, p2, "perform arithmetic on"); +l_noret luaG_aritherror(lua_State *L, const TValue *p1, const TValue *p2) +{ + TValue temp; + if (luaV_tonumber(p1, &temp) == NULL) + p2 = p1; /* first operand is wrong */ + luaG_typeerror(L, p2, "perform arithmetic on"); } - -l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) { - const char *t1 = objtypename(p1); - const char *t2 = objtypename(p2); - if (t1 == t2) - luaG_runerror(L, "attempt to compare two %s values", t1); - else - luaG_runerror(L, "attempt to compare %s with %s", t1, t2); +l_noret luaG_ordererror(lua_State *L, const TValue *p1, const TValue *p2) +{ + const char *t1 = objtypename(p1); + const char *t2 = objtypename(p2); + if (t1 == t2) + luaG_runerror(L, "attempt to compare two %s values", t1); + else + luaG_runerror(L, "attempt to compare %s with %s", t1, t2); } - -static void addinfo (lua_State *L, const char *msg) { - CallInfo *ci = L->ci; - if (isLua(ci)) { /* is Lua code? */ - char buff[LUA_IDSIZE]; /* add file:line information */ - int line = currentline(ci); - TString *src = ci_func(ci)->p->source; - if (src) - luaO_chunkid(buff, getstr(src), LUA_IDSIZE); - else { /* no source available; use "?" instead */ - buff[0] = '?'; buff[1] = '\0'; - } - luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); - } +static void addinfo(lua_State *L, const char *msg) +{ + CallInfo *ci = L->ci; + if (isLua(ci)) + { /* is Lua code? */ + char buff[LUA_IDSIZE]; /* add file:line information */ + int line = currentline(ci); + TString *src = ci_func(ci)->p->source; + if (src) + luaO_chunkid(buff, getstr(src), LUA_IDSIZE); + else + { /* no source available; use "?" instead */ + buff[0] = '?'; + buff[1] = '\0'; + } + luaO_pushfstring(L, "%s:%d: %s", buff, line, msg); + } } - -l_noret luaG_errormsg (lua_State *L) { - if (L->errfunc != 0) { /* is there an error handling function? */ - StkId errfunc = restorestack(L, L->errfunc); - if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); - setobjs2s(L, L->top, L->top - 1); /* move argument */ - setobjs2s(L, L->top - 1, errfunc); /* push function */ - L->top++; - luaD_call(L, L->top - 2, 1, 0); /* call it */ - } - luaD_throw(L, LUA_ERRRUN); +l_noret luaG_errormsg(lua_State *L) +{ + if (L->errfunc != 0) + { /* is there an error handling function? */ + StkId errfunc = restorestack(L, L->errfunc); + if (!ttisfunction(errfunc)) luaD_throw(L, LUA_ERRERR); + setobjs2s(L, L->top, L->top - 1); /* move argument */ + setobjs2s(L, L->top - 1, errfunc); /* push function */ + L->top++; + luaD_call(L, L->top - 2, 1, 0); /* call it */ + } + luaD_throw(L, LUA_ERRRUN); } - -l_noret luaG_runerror (lua_State *L, const char *fmt, ...) { - va_list argp; - va_start(argp, fmt); - addinfo(L, luaO_pushvfstring(L, fmt, argp)); - va_end(argp); - luaG_errormsg(L); +l_noret luaG_runerror(lua_State *L, const char *fmt, ...) +{ + va_list argp; + va_start(argp, fmt); + addinfo(L, luaO_pushvfstring(L, fmt, argp)); + va_end(argp); + luaG_errormsg(L); } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/ldebug.h b/examples/ThirdPartyLibs/lua-5.2.3/src/ldebug.h index 6445c763e..9514ee120 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/ldebug.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/ldebug.h @@ -7,28 +7,25 @@ #ifndef ldebug_h #define ldebug_h - #include "lstate.h" +#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) -#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1) +#define getfuncline(f, pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) -#define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0) - -#define resethookcount(L) (L->hookcount = L->basehookcount) +#define resethookcount(L) (L->hookcount = L->basehookcount) /* Active Lua function (given call info) */ -#define ci_func(ci) (clLvalue((ci)->func)) +#define ci_func(ci) (clLvalue((ci)->func)) - -LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, - const char *opname); -LUAI_FUNC l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2); -LUAI_FUNC l_noret luaG_aritherror (lua_State *L, const TValue *p1, - const TValue *p2); -LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, - const TValue *p2); -LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); -LUAI_FUNC l_noret luaG_errormsg (lua_State *L); +LUAI_FUNC l_noret luaG_typeerror(lua_State *L, const TValue *o, + const char *opname); +LUAI_FUNC l_noret luaG_concaterror(lua_State *L, StkId p1, StkId p2); +LUAI_FUNC l_noret luaG_aritherror(lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC l_noret luaG_ordererror(lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC l_noret luaG_runerror(lua_State *L, const char *fmt, ...); +LUAI_FUNC l_noret luaG_errormsg(lua_State *L); #endif diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/ldo.c b/examples/ThirdPartyLibs/lua-5.2.3/src/ldo.c index e9dd5fa95..26f9d96c9 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/ldo.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/ldo.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #include #include #include @@ -31,9 +30,6 @@ #include "lvm.h" #include "lzio.h" - - - /* ** {====================================================== ** Error-recovery functions @@ -50,632 +46,688 @@ #if defined(__cplusplus) && !defined(LUA_USE_LONGJMP) /* C++ exceptions */ -#define LUAI_THROW(L,c) throw(c) -#define LUAI_TRY(L,c,a) \ - try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; } -#define luai_jmpbuf int /* dummy variable */ +#define LUAI_THROW(L, c) throw(c) +#define LUAI_TRY(L, c, a) \ + try \ + { \ + a \ + } \ + catch (...) \ + { \ + if ((c)->status == 0) (c)->status = -1; \ + } +#define luai_jmpbuf int /* dummy variable */ #elif defined(LUA_USE_ULONGJMP) /* in Unix, try _longjmp/_setjmp (more efficient) */ -#define LUAI_THROW(L,c) _longjmp((c)->b, 1) -#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a } -#define luai_jmpbuf jmp_buf +#define LUAI_THROW(L, c) _longjmp((c)->b, 1) +#define LUAI_TRY(L, c, a) \ + if (_setjmp((c)->b) == 0) \ + { \ + a \ + } +#define luai_jmpbuf jmp_buf #else /* default handling with long jumps */ -#define LUAI_THROW(L,c) longjmp((c)->b, 1) -#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a } -#define luai_jmpbuf jmp_buf +#define LUAI_THROW(L, c) longjmp((c)->b, 1) +#define LUAI_TRY(L, c, a) \ + if (setjmp((c)->b) == 0) \ + { \ + a \ + } +#define luai_jmpbuf jmp_buf #endif #endif - - /* chain list of long jump buffers */ -struct lua_longjmp { - struct lua_longjmp *previous; - luai_jmpbuf b; - volatile int status; /* error code */ +struct lua_longjmp +{ + struct lua_longjmp *previous; + luai_jmpbuf b; + volatile int status; /* error code */ }; - -static void seterrorobj (lua_State *L, int errcode, StkId oldtop) { - switch (errcode) { - case LUA_ERRMEM: { /* memory error? */ - setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */ - break; - } - case LUA_ERRERR: { - setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); - break; - } - default: { - setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ - break; - } - } - L->top = oldtop + 1; +static void seterrorobj(lua_State *L, int errcode, StkId oldtop) +{ + switch (errcode) + { + case LUA_ERRMEM: + { /* memory error? */ + setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */ + break; + } + case LUA_ERRERR: + { + setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); + break; + } + default: + { + setobjs2s(L, oldtop, L->top - 1); /* error message on current top */ + break; + } + } + L->top = oldtop + 1; } - -l_noret luaD_throw (lua_State *L, int errcode) { - if (L->errorJmp) { /* thread has an error handler? */ - L->errorJmp->status = errcode; /* set status */ - LUAI_THROW(L, L->errorJmp); /* jump to it */ - } - else { /* thread has no error handler */ - L->status = cast_byte(errcode); /* mark it as dead */ - if (G(L)->mainthread->errorJmp) { /* main thread has a handler? */ - setobjs2s(L, G(L)->mainthread->top++, L->top - 1); /* copy error obj. */ - luaD_throw(G(L)->mainthread, errcode); /* re-throw in main thread */ - } - else { /* no handler at all; abort */ - if (G(L)->panic) { /* panic function? */ - lua_unlock(L); - G(L)->panic(L); /* call it (last chance to jump out) */ - } - abort(); - } - } +l_noret luaD_throw(lua_State *L, int errcode) +{ + if (L->errorJmp) + { /* thread has an error handler? */ + L->errorJmp->status = errcode; /* set status */ + LUAI_THROW(L, L->errorJmp); /* jump to it */ + } + else + { /* thread has no error handler */ + L->status = cast_byte(errcode); /* mark it as dead */ + if (G(L)->mainthread->errorJmp) + { /* main thread has a handler? */ + setobjs2s(L, G(L)->mainthread->top++, L->top - 1); /* copy error obj. */ + luaD_throw(G(L)->mainthread, errcode); /* re-throw in main thread */ + } + else + { /* no handler at all; abort */ + if (G(L)->panic) + { /* panic function? */ + lua_unlock(L); + G(L)->panic(L); /* call it (last chance to jump out) */ + } + abort(); + } + } } - -int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { - unsigned short oldnCcalls = L->nCcalls; - struct lua_longjmp lj; - lj.status = LUA_OK; - lj.previous = L->errorJmp; /* chain new error handler */ - L->errorJmp = &lj; - LUAI_TRY(L, &lj, - (*f)(L, ud); - ); - L->errorJmp = lj.previous; /* restore old error handler */ - L->nCcalls = oldnCcalls; - return lj.status; +int luaD_rawrunprotected(lua_State *L, Pfunc f, void *ud) +{ + unsigned short oldnCcalls = L->nCcalls; + struct lua_longjmp lj; + lj.status = LUA_OK; + lj.previous = L->errorJmp; /* chain new error handler */ + L->errorJmp = &lj; + LUAI_TRY(L, &lj, + (*f)(L, ud);); + L->errorJmp = lj.previous; /* restore old error handler */ + L->nCcalls = oldnCcalls; + return lj.status; } /* }====================================================== */ - -static void correctstack (lua_State *L, TValue *oldstack) { - CallInfo *ci; - GCObject *up; - L->top = (L->top - oldstack) + L->stack; - for (up = L->openupval; up != NULL; up = up->gch.next) - gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; - for (ci = L->ci; ci != NULL; ci = ci->previous) { - ci->top = (ci->top - oldstack) + L->stack; - ci->func = (ci->func - oldstack) + L->stack; - if (isLua(ci)) - ci->u.l.base = (ci->u.l.base - oldstack) + L->stack; - } +static void correctstack(lua_State *L, TValue *oldstack) +{ + CallInfo *ci; + GCObject *up; + L->top = (L->top - oldstack) + L->stack; + for (up = L->openupval; up != NULL; up = up->gch.next) + gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack; + for (ci = L->ci; ci != NULL; ci = ci->previous) + { + ci->top = (ci->top - oldstack) + L->stack; + ci->func = (ci->func - oldstack) + L->stack; + if (isLua(ci)) + ci->u.l.base = (ci->u.l.base - oldstack) + L->stack; + } } - /* some space for error handling */ -#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200) +#define ERRORSTACKSIZE (LUAI_MAXSTACK + 200) - -void luaD_reallocstack (lua_State *L, int newsize) { - TValue *oldstack = L->stack; - int lim = L->stacksize; - lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); - lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK); - luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue); - for (; lim < newsize; lim++) - setnilvalue(L->stack + lim); /* erase new segment */ - L->stacksize = newsize; - L->stack_last = L->stack + newsize - EXTRA_STACK; - correctstack(L, oldstack); +void luaD_reallocstack(lua_State *L, int newsize) +{ + TValue *oldstack = L->stack; + int lim = L->stacksize; + lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); + lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK); + luaM_reallocvector(L, L->stack, L->stacksize, newsize, TValue); + for (; lim < newsize; lim++) + setnilvalue(L->stack + lim); /* erase new segment */ + L->stacksize = newsize; + L->stack_last = L->stack + newsize - EXTRA_STACK; + correctstack(L, oldstack); } - -void luaD_growstack (lua_State *L, int n) { - int size = L->stacksize; - if (size > LUAI_MAXSTACK) /* error after extra size? */ - luaD_throw(L, LUA_ERRERR); - else { - int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK; - int newsize = 2 * size; - if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK; - if (newsize < needed) newsize = needed; - if (newsize > LUAI_MAXSTACK) { /* stack overflow? */ - luaD_reallocstack(L, ERRORSTACKSIZE); - luaG_runerror(L, "stack overflow"); - } - else - luaD_reallocstack(L, newsize); - } +void luaD_growstack(lua_State *L, int n) +{ + int size = L->stacksize; + if (size > LUAI_MAXSTACK) /* error after extra size? */ + luaD_throw(L, LUA_ERRERR); + else + { + int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK; + int newsize = 2 * size; + if (newsize > LUAI_MAXSTACK) newsize = LUAI_MAXSTACK; + if (newsize < needed) newsize = needed; + if (newsize > LUAI_MAXSTACK) + { /* stack overflow? */ + luaD_reallocstack(L, ERRORSTACKSIZE); + luaG_runerror(L, "stack overflow"); + } + else + luaD_reallocstack(L, newsize); + } } - -static int stackinuse (lua_State *L) { - CallInfo *ci; - StkId lim = L->top; - for (ci = L->ci; ci != NULL; ci = ci->previous) { - lua_assert(ci->top <= L->stack_last); - if (lim < ci->top) lim = ci->top; - } - return cast_int(lim - L->stack) + 1; /* part of stack in use */ +static int stackinuse(lua_State *L) +{ + CallInfo *ci; + StkId lim = L->top; + for (ci = L->ci; ci != NULL; ci = ci->previous) + { + lua_assert(ci->top <= L->stack_last); + if (lim < ci->top) lim = ci->top; + } + return cast_int(lim - L->stack) + 1; /* part of stack in use */ } - -void luaD_shrinkstack (lua_State *L) { - int inuse = stackinuse(L); - int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK; - if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK; - if (inuse > LUAI_MAXSTACK || /* handling stack overflow? */ - goodsize >= L->stacksize) /* would grow instead of shrink? */ - condmovestack(L); /* don't change stack (change only for debugging) */ - else - luaD_reallocstack(L, goodsize); /* shrink it */ +void luaD_shrinkstack(lua_State *L) +{ + int inuse = stackinuse(L); + int goodsize = inuse + (inuse / 8) + 2 * EXTRA_STACK; + if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK; + if (inuse > LUAI_MAXSTACK || /* handling stack overflow? */ + goodsize >= L->stacksize) /* would grow instead of shrink? */ + condmovestack(L); /* don't change stack (change only for debugging) */ + else + luaD_reallocstack(L, goodsize); /* shrink it */ } - -void luaD_hook (lua_State *L, int event, int line) { - lua_Hook hook = L->hook; - if (hook && L->allowhook) { - CallInfo *ci = L->ci; - ptrdiff_t top = savestack(L, L->top); - ptrdiff_t ci_top = savestack(L, ci->top); - lua_Debug ar; - ar.event = event; - ar.currentline = line; - ar.i_ci = ci; - luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ - ci->top = L->top + LUA_MINSTACK; - lua_assert(ci->top <= L->stack_last); - L->allowhook = 0; /* cannot call hooks inside a hook */ - ci->callstatus |= CIST_HOOKED; - lua_unlock(L); - (*hook)(L, &ar); - lua_lock(L); - lua_assert(!L->allowhook); - L->allowhook = 1; - ci->top = restorestack(L, ci_top); - L->top = restorestack(L, top); - ci->callstatus &= ~CIST_HOOKED; - } +void luaD_hook(lua_State *L, int event, int line) +{ + lua_Hook hook = L->hook; + if (hook && L->allowhook) + { + CallInfo *ci = L->ci; + ptrdiff_t top = savestack(L, L->top); + ptrdiff_t ci_top = savestack(L, ci->top); + lua_Debug ar; + ar.event = event; + ar.currentline = line; + ar.i_ci = ci; + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + ci->top = L->top + LUA_MINSTACK; + lua_assert(ci->top <= L->stack_last); + L->allowhook = 0; /* cannot call hooks inside a hook */ + ci->callstatus |= CIST_HOOKED; + lua_unlock(L); + (*hook)(L, &ar); + lua_lock(L); + lua_assert(!L->allowhook); + L->allowhook = 1; + ci->top = restorestack(L, ci_top); + L->top = restorestack(L, top); + ci->callstatus &= ~CIST_HOOKED; + } } - -static void callhook (lua_State *L, CallInfo *ci) { - int hook = LUA_HOOKCALL; - ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ - if (isLua(ci->previous) && - GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) { - ci->callstatus |= CIST_TAIL; - hook = LUA_HOOKTAILCALL; - } - luaD_hook(L, hook, -1); - ci->u.l.savedpc--; /* correct 'pc' */ +static void callhook(lua_State *L, CallInfo *ci) +{ + int hook = LUA_HOOKCALL; + ci->u.l.savedpc++; /* hooks assume 'pc' is already incremented */ + if (isLua(ci->previous) && + GET_OPCODE(*(ci->previous->u.l.savedpc - 1)) == OP_TAILCALL) + { + ci->callstatus |= CIST_TAIL; + hook = LUA_HOOKTAILCALL; + } + luaD_hook(L, hook, -1); + ci->u.l.savedpc--; /* correct 'pc' */ } - -static StkId adjust_varargs (lua_State *L, Proto *p, int actual) { - int i; - int nfixargs = p->numparams; - StkId base, fixed; - lua_assert(actual >= nfixargs); - /* move fixed parameters to final position */ - luaD_checkstack(L, p->maxstacksize); /* check again for new 'base' */ - fixed = L->top - actual; /* first fixed argument */ - base = L->top; /* final position of first argument */ - for (i=0; itop++, fixed + i); - setnilvalue(fixed + i); - } - return base; +static StkId adjust_varargs(lua_State *L, Proto *p, int actual) +{ + int i; + int nfixargs = p->numparams; + StkId base, fixed; + lua_assert(actual >= nfixargs); + /* move fixed parameters to final position */ + luaD_checkstack(L, p->maxstacksize); /* check again for new 'base' */ + fixed = L->top - actual; /* first fixed argument */ + base = L->top; /* final position of first argument */ + for (i = 0; i < nfixargs; i++) + { + setobjs2s(L, L->top++, fixed + i); + setnilvalue(fixed + i); + } + return base; } - -static StkId tryfuncTM (lua_State *L, StkId func) { - const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); - StkId p; - ptrdiff_t funcr = savestack(L, func); - if (!ttisfunction(tm)) - luaG_typeerror(L, func, "call"); - /* Open a hole inside the stack at `func' */ - for (p = L->top; p > func; p--) setobjs2s(L, p, p-1); - incr_top(L); - func = restorestack(L, funcr); /* previous call may change stack */ - setobj2s(L, func, tm); /* tag method is the new function to be called */ - return func; +static StkId tryfuncTM(lua_State *L, StkId func) +{ + const TValue *tm = luaT_gettmbyobj(L, func, TM_CALL); + StkId p; + ptrdiff_t funcr = savestack(L, func); + if (!ttisfunction(tm)) + luaG_typeerror(L, func, "call"); + /* Open a hole inside the stack at `func' */ + for (p = L->top; p > func; p--) setobjs2s(L, p, p - 1); + incr_top(L); + func = restorestack(L, funcr); /* previous call may change stack */ + setobj2s(L, func, tm); /* tag method is the new function to be called */ + return func; } - - #define next_ci(L) (L->ci = (L->ci->next ? L->ci->next : luaE_extendCI(L))) - /* ** returns true if function has been executed (C function) */ -int luaD_precall (lua_State *L, StkId func, int nresults) { - lua_CFunction f; - CallInfo *ci; - int n; /* number of arguments (Lua) or returns (C) */ - ptrdiff_t funcr = savestack(L, func); - switch (ttype(func)) { - case LUA_TLCF: /* light C function */ - f = fvalue(func); - goto Cfunc; - case LUA_TCCL: { /* C closure */ - f = clCvalue(func)->f; - Cfunc: - luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ - ci = next_ci(L); /* now 'enter' new function */ - ci->nresults = nresults; - ci->func = restorestack(L, funcr); - ci->top = L->top + LUA_MINSTACK; - lua_assert(ci->top <= L->stack_last); - ci->callstatus = 0; - luaC_checkGC(L); /* stack grow uses memory */ - if (L->hookmask & LUA_MASKCALL) - luaD_hook(L, LUA_HOOKCALL, -1); - lua_unlock(L); - n = (*f)(L); /* do the actual call */ - lua_lock(L); - api_checknelems(L, n); - luaD_poscall(L, L->top - n); - return 1; - } - case LUA_TLCL: { /* Lua function: prepare its call */ - StkId base; - Proto *p = clLvalue(func)->p; - n = cast_int(L->top - func) - 1; /* number of real arguments */ - luaD_checkstack(L, p->maxstacksize); - for (; n < p->numparams; n++) - setnilvalue(L->top++); /* complete missing arguments */ - if (!p->is_vararg) { - func = restorestack(L, funcr); - base = func + 1; - } - else { - base = adjust_varargs(L, p, n); - func = restorestack(L, funcr); /* previous call can change stack */ - } - ci = next_ci(L); /* now 'enter' new function */ - ci->nresults = nresults; - ci->func = func; - ci->u.l.base = base; - ci->top = base + p->maxstacksize; - lua_assert(ci->top <= L->stack_last); - ci->u.l.savedpc = p->code; /* starting point */ - ci->callstatus = CIST_LUA; - L->top = ci->top; - luaC_checkGC(L); /* stack grow uses memory */ - if (L->hookmask & LUA_MASKCALL) - callhook(L, ci); - return 0; - } - default: { /* not a function */ - func = tryfuncTM(L, func); /* retry with 'function' tag method */ - return luaD_precall(L, func, nresults); /* now it must be a function */ - } - } +int luaD_precall(lua_State *L, StkId func, int nresults) +{ + lua_CFunction f; + CallInfo *ci; + int n; /* number of arguments (Lua) or returns (C) */ + ptrdiff_t funcr = savestack(L, func); + switch (ttype(func)) + { + case LUA_TLCF: /* light C function */ + f = fvalue(func); + goto Cfunc; + case LUA_TCCL: + { /* C closure */ + f = clCvalue(func)->f; + Cfunc: + luaD_checkstack(L, LUA_MINSTACK); /* ensure minimum stack size */ + ci = next_ci(L); /* now 'enter' new function */ + ci->nresults = nresults; + ci->func = restorestack(L, funcr); + ci->top = L->top + LUA_MINSTACK; + lua_assert(ci->top <= L->stack_last); + ci->callstatus = 0; + luaC_checkGC(L); /* stack grow uses memory */ + if (L->hookmask & LUA_MASKCALL) + luaD_hook(L, LUA_HOOKCALL, -1); + lua_unlock(L); + n = (*f)(L); /* do the actual call */ + lua_lock(L); + api_checknelems(L, n); + luaD_poscall(L, L->top - n); + return 1; + } + case LUA_TLCL: + { /* Lua function: prepare its call */ + StkId base; + Proto *p = clLvalue(func)->p; + n = cast_int(L->top - func) - 1; /* number of real arguments */ + luaD_checkstack(L, p->maxstacksize); + for (; n < p->numparams; n++) + setnilvalue(L->top++); /* complete missing arguments */ + if (!p->is_vararg) + { + func = restorestack(L, funcr); + base = func + 1; + } + else + { + base = adjust_varargs(L, p, n); + func = restorestack(L, funcr); /* previous call can change stack */ + } + ci = next_ci(L); /* now 'enter' new function */ + ci->nresults = nresults; + ci->func = func; + ci->u.l.base = base; + ci->top = base + p->maxstacksize; + lua_assert(ci->top <= L->stack_last); + ci->u.l.savedpc = p->code; /* starting point */ + ci->callstatus = CIST_LUA; + L->top = ci->top; + luaC_checkGC(L); /* stack grow uses memory */ + if (L->hookmask & LUA_MASKCALL) + callhook(L, ci); + return 0; + } + default: + { /* not a function */ + func = tryfuncTM(L, func); /* retry with 'function' tag method */ + return luaD_precall(L, func, nresults); /* now it must be a function */ + } + } } - -int luaD_poscall (lua_State *L, StkId firstResult) { - StkId res; - int wanted, i; - CallInfo *ci = L->ci; - if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) { - if (L->hookmask & LUA_MASKRET) { - ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ - luaD_hook(L, LUA_HOOKRET, -1); - firstResult = restorestack(L, fr); - } - L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */ - } - res = ci->func; /* res == final position of 1st result */ - wanted = ci->nresults; - L->ci = ci = ci->previous; /* back to caller */ - /* move results to correct place */ - for (i = wanted; i != 0 && firstResult < L->top; i--) - setobjs2s(L, res++, firstResult++); - while (i-- > 0) - setnilvalue(res++); - L->top = res; - return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ +int luaD_poscall(lua_State *L, StkId firstResult) +{ + StkId res; + int wanted, i; + CallInfo *ci = L->ci; + if (L->hookmask & (LUA_MASKRET | LUA_MASKLINE)) + { + if (L->hookmask & LUA_MASKRET) + { + ptrdiff_t fr = savestack(L, firstResult); /* hook may change stack */ + luaD_hook(L, LUA_HOOKRET, -1); + firstResult = restorestack(L, fr); + } + L->oldpc = ci->previous->u.l.savedpc; /* 'oldpc' for caller function */ + } + res = ci->func; /* res == final position of 1st result */ + wanted = ci->nresults; + L->ci = ci = ci->previous; /* back to caller */ + /* move results to correct place */ + for (i = wanted; i != 0 && firstResult < L->top; i--) + setobjs2s(L, res++, firstResult++); + while (i-- > 0) + setnilvalue(res++); + L->top = res; + return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */ } - /* ** Call a function (C or Lua). The function to be called is at *func. ** The arguments are on the stack, right after the function. ** When returns, all the results are on the stack, starting at the original ** function position. */ -void luaD_call (lua_State *L, StkId func, int nResults, int allowyield) { - if (++L->nCcalls >= LUAI_MAXCCALLS) { - if (L->nCcalls == LUAI_MAXCCALLS) - luaG_runerror(L, "C stack overflow"); - else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS>>3))) - luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ - } - if (!allowyield) L->nny++; - if (!luaD_precall(L, func, nResults)) /* is a Lua function? */ - luaV_execute(L); /* call it */ - if (!allowyield) L->nny--; - L->nCcalls--; +void luaD_call(lua_State *L, StkId func, int nResults, int allowyield) +{ + if (++L->nCcalls >= LUAI_MAXCCALLS) + { + if (L->nCcalls == LUAI_MAXCCALLS) + luaG_runerror(L, "C stack overflow"); + else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS >> 3))) + luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ + } + if (!allowyield) L->nny++; + if (!luaD_precall(L, func, nResults)) /* is a Lua function? */ + luaV_execute(L); /* call it */ + if (!allowyield) L->nny--; + L->nCcalls--; } - -static void finishCcall (lua_State *L) { - CallInfo *ci = L->ci; - int n; - lua_assert(ci->u.c.k != NULL); /* must have a continuation */ - lua_assert(L->nny == 0); - if (ci->callstatus & CIST_YPCALL) { /* was inside a pcall? */ - ci->callstatus &= ~CIST_YPCALL; /* finish 'lua_pcall' */ - L->errfunc = ci->u.c.old_errfunc; - } - /* finish 'lua_callk'/'lua_pcall' */ - adjustresults(L, ci->nresults); - /* call continuation function */ - if (!(ci->callstatus & CIST_STAT)) /* no call status? */ - ci->u.c.status = LUA_YIELD; /* 'default' status */ - lua_assert(ci->u.c.status != LUA_OK); - ci->callstatus = (ci->callstatus & ~(CIST_YPCALL | CIST_STAT)) | CIST_YIELDED; - lua_unlock(L); - n = (*ci->u.c.k)(L); - lua_lock(L); - api_checknelems(L, n); - /* finish 'luaD_precall' */ - luaD_poscall(L, L->top - n); +static void finishCcall(lua_State *L) +{ + CallInfo *ci = L->ci; + int n; + lua_assert(ci->u.c.k != NULL); /* must have a continuation */ + lua_assert(L->nny == 0); + if (ci->callstatus & CIST_YPCALL) + { /* was inside a pcall? */ + ci->callstatus &= ~CIST_YPCALL; /* finish 'lua_pcall' */ + L->errfunc = ci->u.c.old_errfunc; + } + /* finish 'lua_callk'/'lua_pcall' */ + adjustresults(L, ci->nresults); + /* call continuation function */ + if (!(ci->callstatus & CIST_STAT)) /* no call status? */ + ci->u.c.status = LUA_YIELD; /* 'default' status */ + lua_assert(ci->u.c.status != LUA_OK); + ci->callstatus = (ci->callstatus & ~(CIST_YPCALL | CIST_STAT)) | CIST_YIELDED; + lua_unlock(L); + n = (*ci->u.c.k)(L); + lua_lock(L); + api_checknelems(L, n); + /* finish 'luaD_precall' */ + luaD_poscall(L, L->top - n); } - -static void unroll (lua_State *L, void *ud) { - UNUSED(ud); - for (;;) { - if (L->ci == &L->base_ci) /* stack is empty? */ - return; /* coroutine finished normally */ - if (!isLua(L->ci)) /* C function? */ - finishCcall(L); - else { /* Lua function */ - luaV_finishOp(L); /* finish interrupted instruction */ - luaV_execute(L); /* execute down to higher C 'boundary' */ - } - } +static void unroll(lua_State *L, void *ud) +{ + UNUSED(ud); + for (;;) + { + if (L->ci == &L->base_ci) /* stack is empty? */ + return; /* coroutine finished normally */ + if (!isLua(L->ci)) /* C function? */ + finishCcall(L); + else + { /* Lua function */ + luaV_finishOp(L); /* finish interrupted instruction */ + luaV_execute(L); /* execute down to higher C 'boundary' */ + } + } } - /* ** check whether thread has a suspended protected call */ -static CallInfo *findpcall (lua_State *L) { - CallInfo *ci; - for (ci = L->ci; ci != NULL; ci = ci->previous) { /* search for a pcall */ - if (ci->callstatus & CIST_YPCALL) - return ci; - } - return NULL; /* no pending pcall */ +static CallInfo *findpcall(lua_State *L) +{ + CallInfo *ci; + for (ci = L->ci; ci != NULL; ci = ci->previous) + { /* search for a pcall */ + if (ci->callstatus & CIST_YPCALL) + return ci; + } + return NULL; /* no pending pcall */ } - -static int recover (lua_State *L, int status) { - StkId oldtop; - CallInfo *ci = findpcall(L); - if (ci == NULL) return 0; /* no recovery point */ - /* "finish" luaD_pcall */ - oldtop = restorestack(L, ci->extra); - luaF_close(L, oldtop); - seterrorobj(L, status, oldtop); - L->ci = ci; - L->allowhook = ci->u.c.old_allowhook; - L->nny = 0; /* should be zero to be yieldable */ - luaD_shrinkstack(L); - L->errfunc = ci->u.c.old_errfunc; - ci->callstatus |= CIST_STAT; /* call has error status */ - ci->u.c.status = status; /* (here it is) */ - return 1; /* continue running the coroutine */ +static int recover(lua_State *L, int status) +{ + StkId oldtop; + CallInfo *ci = findpcall(L); + if (ci == NULL) return 0; /* no recovery point */ + /* "finish" luaD_pcall */ + oldtop = restorestack(L, ci->extra); + luaF_close(L, oldtop); + seterrorobj(L, status, oldtop); + L->ci = ci; + L->allowhook = ci->u.c.old_allowhook; + L->nny = 0; /* should be zero to be yieldable */ + luaD_shrinkstack(L); + L->errfunc = ci->u.c.old_errfunc; + ci->callstatus |= CIST_STAT; /* call has error status */ + ci->u.c.status = status; /* (here it is) */ + return 1; /* continue running the coroutine */ } - /* ** signal an error in the call to 'resume', not in the execution of the ** coroutine itself. (Such errors should not be handled by any coroutine ** error handler and should not kill the coroutine.) */ -static l_noret resume_error (lua_State *L, const char *msg, StkId firstArg) { - L->top = firstArg; /* remove args from the stack */ - setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */ - api_incr_top(L); - luaD_throw(L, -1); /* jump back to 'lua_resume' */ +static l_noret resume_error(lua_State *L, const char *msg, StkId firstArg) +{ + L->top = firstArg; /* remove args from the stack */ + setsvalue2s(L, L->top, luaS_new(L, msg)); /* push error message */ + api_incr_top(L); + luaD_throw(L, -1); /* jump back to 'lua_resume' */ } - /* ** do the work for 'lua_resume' in protected mode */ -static void resume (lua_State *L, void *ud) { - int nCcalls = L->nCcalls; - StkId firstArg = cast(StkId, ud); - CallInfo *ci = L->ci; - if (nCcalls >= LUAI_MAXCCALLS) - resume_error(L, "C stack overflow", firstArg); - if (L->status == LUA_OK) { /* may be starting a coroutine */ - if (ci != &L->base_ci) /* not in base level? */ - resume_error(L, "cannot resume non-suspended coroutine", firstArg); - /* coroutine is in base level; start running it */ - if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ - luaV_execute(L); /* call it */ - } - else if (L->status != LUA_YIELD) - resume_error(L, "cannot resume dead coroutine", firstArg); - else { /* resuming from previous yield */ - L->status = LUA_OK; - ci->func = restorestack(L, ci->extra); - if (isLua(ci)) /* yielded inside a hook? */ - luaV_execute(L); /* just continue running Lua code */ - else { /* 'common' yield */ - if (ci->u.c.k != NULL) { /* does it have a continuation? */ - int n; - ci->u.c.status = LUA_YIELD; /* 'default' status */ - ci->callstatus |= CIST_YIELDED; - lua_unlock(L); - n = (*ci->u.c.k)(L); /* call continuation */ - lua_lock(L); - api_checknelems(L, n); - firstArg = L->top - n; /* yield results come from continuation */ - } - luaD_poscall(L, firstArg); /* finish 'luaD_precall' */ - } - unroll(L, NULL); - } - lua_assert(nCcalls == L->nCcalls); +static void resume(lua_State *L, void *ud) +{ + int nCcalls = L->nCcalls; + StkId firstArg = cast(StkId, ud); + CallInfo *ci = L->ci; + if (nCcalls >= LUAI_MAXCCALLS) + resume_error(L, "C stack overflow", firstArg); + if (L->status == LUA_OK) + { /* may be starting a coroutine */ + if (ci != &L->base_ci) /* not in base level? */ + resume_error(L, "cannot resume non-suspended coroutine", firstArg); + /* coroutine is in base level; start running it */ + if (!luaD_precall(L, firstArg - 1, LUA_MULTRET)) /* Lua function? */ + luaV_execute(L); /* call it */ + } + else if (L->status != LUA_YIELD) + resume_error(L, "cannot resume dead coroutine", firstArg); + else + { /* resuming from previous yield */ + L->status = LUA_OK; + ci->func = restorestack(L, ci->extra); + if (isLua(ci)) /* yielded inside a hook? */ + luaV_execute(L); /* just continue running Lua code */ + else + { /* 'common' yield */ + if (ci->u.c.k != NULL) + { /* does it have a continuation? */ + int n; + ci->u.c.status = LUA_YIELD; /* 'default' status */ + ci->callstatus |= CIST_YIELDED; + lua_unlock(L); + n = (*ci->u.c.k)(L); /* call continuation */ + lua_lock(L); + api_checknelems(L, n); + firstArg = L->top - n; /* yield results come from continuation */ + } + luaD_poscall(L, firstArg); /* finish 'luaD_precall' */ + } + unroll(L, NULL); + } + lua_assert(nCcalls == L->nCcalls); } - -LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) { - int status; - int oldnny = L->nny; /* save 'nny' */ - lua_lock(L); - luai_userstateresume(L, nargs); - L->nCcalls = (from) ? from->nCcalls + 1 : 1; - L->nny = 0; /* allow yields */ - api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); - status = luaD_rawrunprotected(L, resume, L->top - nargs); - if (status == -1) /* error calling 'lua_resume'? */ - status = LUA_ERRRUN; - else { /* yield or regular error */ - while (status != LUA_OK && status != LUA_YIELD) { /* error? */ - if (recover(L, status)) /* recover point? */ - status = luaD_rawrunprotected(L, unroll, NULL); /* run continuation */ - else { /* unrecoverable error */ - L->status = cast_byte(status); /* mark thread as `dead' */ - seterrorobj(L, status, L->top); - L->ci->top = L->top; - break; - } - } - lua_assert(status == L->status); - } - L->nny = oldnny; /* restore 'nny' */ - L->nCcalls--; - lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0)); - lua_unlock(L); - return status; +LUA_API int lua_resume(lua_State *L, lua_State *from, int nargs) +{ + int status; + int oldnny = L->nny; /* save 'nny' */ + lua_lock(L); + luai_userstateresume(L, nargs); + L->nCcalls = (from) ? from->nCcalls + 1 : 1; + L->nny = 0; /* allow yields */ + api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); + status = luaD_rawrunprotected(L, resume, L->top - nargs); + if (status == -1) /* error calling 'lua_resume'? */ + status = LUA_ERRRUN; + else + { /* yield or regular error */ + while (status != LUA_OK && status != LUA_YIELD) + { /* error? */ + if (recover(L, status)) /* recover point? */ + status = luaD_rawrunprotected(L, unroll, NULL); /* run continuation */ + else + { /* unrecoverable error */ + L->status = cast_byte(status); /* mark thread as `dead' */ + seterrorobj(L, status, L->top); + L->ci->top = L->top; + break; + } + } + lua_assert(status == L->status); + } + L->nny = oldnny; /* restore 'nny' */ + L->nCcalls--; + lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0)); + lua_unlock(L); + return status; } - -LUA_API int lua_yieldk (lua_State *L, int nresults, int ctx, lua_CFunction k) { - CallInfo *ci = L->ci; - luai_userstateyield(L, nresults); - lua_lock(L); - api_checknelems(L, nresults); - if (L->nny > 0) { - if (L != G(L)->mainthread) - luaG_runerror(L, "attempt to yield across a C-call boundary"); - else - luaG_runerror(L, "attempt to yield from outside a coroutine"); - } - L->status = LUA_YIELD; - ci->extra = savestack(L, ci->func); /* save current 'func' */ - if (isLua(ci)) { /* inside a hook? */ - api_check(L, k == NULL, "hooks cannot continue after yielding"); - } - else { - if ((ci->u.c.k = k) != NULL) /* is there a continuation? */ - ci->u.c.ctx = ctx; /* save context */ - ci->func = L->top - nresults - 1; /* protect stack below results */ - luaD_throw(L, LUA_YIELD); - } - lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */ - lua_unlock(L); - return 0; /* return to 'luaD_hook' */ +LUA_API int lua_yieldk(lua_State *L, int nresults, int ctx, lua_CFunction k) +{ + CallInfo *ci = L->ci; + luai_userstateyield(L, nresults); + lua_lock(L); + api_checknelems(L, nresults); + if (L->nny > 0) + { + if (L != G(L)->mainthread) + luaG_runerror(L, "attempt to yield across a C-call boundary"); + else + luaG_runerror(L, "attempt to yield from outside a coroutine"); + } + L->status = LUA_YIELD; + ci->extra = savestack(L, ci->func); /* save current 'func' */ + if (isLua(ci)) + { /* inside a hook? */ + api_check(L, k == NULL, "hooks cannot continue after yielding"); + } + else + { + if ((ci->u.c.k = k) != NULL) /* is there a continuation? */ + ci->u.c.ctx = ctx; /* save context */ + ci->func = L->top - nresults - 1; /* protect stack below results */ + luaD_throw(L, LUA_YIELD); + } + lua_assert(ci->callstatus & CIST_HOOKED); /* must be inside a hook */ + lua_unlock(L); + return 0; /* return to 'luaD_hook' */ } - -int luaD_pcall (lua_State *L, Pfunc func, void *u, - ptrdiff_t old_top, ptrdiff_t ef) { - int status; - CallInfo *old_ci = L->ci; - lu_byte old_allowhooks = L->allowhook; - unsigned short old_nny = L->nny; - ptrdiff_t old_errfunc = L->errfunc; - L->errfunc = ef; - status = luaD_rawrunprotected(L, func, u); - if (status != LUA_OK) { /* an error occurred? */ - StkId oldtop = restorestack(L, old_top); - luaF_close(L, oldtop); /* close possible pending closures */ - seterrorobj(L, status, oldtop); - L->ci = old_ci; - L->allowhook = old_allowhooks; - L->nny = old_nny; - luaD_shrinkstack(L); - } - L->errfunc = old_errfunc; - return status; +int luaD_pcall(lua_State *L, Pfunc func, void *u, + ptrdiff_t old_top, ptrdiff_t ef) +{ + int status; + CallInfo *old_ci = L->ci; + lu_byte old_allowhooks = L->allowhook; + unsigned short old_nny = L->nny; + ptrdiff_t old_errfunc = L->errfunc; + L->errfunc = ef; + status = luaD_rawrunprotected(L, func, u); + if (status != LUA_OK) + { /* an error occurred? */ + StkId oldtop = restorestack(L, old_top); + luaF_close(L, oldtop); /* close possible pending closures */ + seterrorobj(L, status, oldtop); + L->ci = old_ci; + L->allowhook = old_allowhooks; + L->nny = old_nny; + luaD_shrinkstack(L); + } + L->errfunc = old_errfunc; + return status; } - - /* ** Execute a protected parser. */ -struct SParser { /* data to `f_parser' */ - ZIO *z; - Mbuffer buff; /* dynamic structure used by the scanner */ - Dyndata dyd; /* dynamic structures used by the parser */ - const char *mode; - const char *name; +struct SParser +{ /* data to `f_parser' */ + ZIO *z; + Mbuffer buff; /* dynamic structure used by the scanner */ + Dyndata dyd; /* dynamic structures used by the parser */ + const char *mode; + const char *name; }; - -static void checkmode (lua_State *L, const char *mode, const char *x) { - if (mode && strchr(mode, x[0]) == NULL) { - luaO_pushfstring(L, - "attempt to load a %s chunk (mode is " LUA_QS ")", x, mode); - luaD_throw(L, LUA_ERRSYNTAX); - } +static void checkmode(lua_State *L, const char *mode, const char *x) +{ + if (mode && strchr(mode, x[0]) == NULL) + { + luaO_pushfstring(L, + "attempt to load a %s chunk (mode is " LUA_QS ")", x, mode); + luaD_throw(L, LUA_ERRSYNTAX); + } } - -static void f_parser (lua_State *L, void *ud) { - int i; - Closure *cl; - struct SParser *p = cast(struct SParser *, ud); - int c = zgetc(p->z); /* read first character */ - if (c == LUA_SIGNATURE[0]) { - checkmode(L, p->mode, "binary"); - cl = luaU_undump(L, p->z, &p->buff, p->name); - } - else { - checkmode(L, p->mode, "text"); - cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c); - } - lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues); - for (i = 0; i < cl->l.nupvalues; i++) { /* initialize upvalues */ - UpVal *up = luaF_newupval(L); - cl->l.upvals[i] = up; - luaC_objbarrier(L, cl, up); - } +static void f_parser(lua_State *L, void *ud) +{ + int i; + Closure *cl; + struct SParser *p = cast(struct SParser *, ud); + int c = zgetc(p->z); /* read first character */ + if (c == LUA_SIGNATURE[0]) + { + checkmode(L, p->mode, "binary"); + cl = luaU_undump(L, p->z, &p->buff, p->name); + } + else + { + checkmode(L, p->mode, "text"); + cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c); + } + lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues); + for (i = 0; i < cl->l.nupvalues; i++) + { /* initialize upvalues */ + UpVal *up = luaF_newupval(L); + cl->l.upvals[i] = up; + luaC_objbarrier(L, cl, up); + } } - -int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, - const char *mode) { - struct SParser p; - int status; - L->nny++; /* cannot yield during parsing */ - p.z = z; p.name = name; p.mode = mode; - p.dyd.actvar.arr = NULL; p.dyd.actvar.size = 0; - p.dyd.gt.arr = NULL; p.dyd.gt.size = 0; - p.dyd.label.arr = NULL; p.dyd.label.size = 0; - luaZ_initbuffer(L, &p.buff); - status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); - luaZ_freebuffer(L, &p.buff); - luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size); - luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size); - luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size); - L->nny--; - return status; +int luaD_protectedparser(lua_State *L, ZIO *z, const char *name, + const char *mode) +{ + struct SParser p; + int status; + L->nny++; /* cannot yield during parsing */ + p.z = z; + p.name = name; + p.mode = mode; + p.dyd.actvar.arr = NULL; + p.dyd.actvar.size = 0; + p.dyd.gt.arr = NULL; + p.dyd.gt.size = 0; + p.dyd.label.arr = NULL; + p.dyd.label.size = 0; + luaZ_initbuffer(L, &p.buff); + status = luaD_pcall(L, f_parser, &p, savestack(L, L->top), L->errfunc); + luaZ_freebuffer(L, &p.buff); + luaM_freearray(L, p.dyd.actvar.arr, p.dyd.actvar.size); + luaM_freearray(L, p.dyd.gt.arr, p.dyd.gt.size); + luaM_freearray(L, p.dyd.label.arr, p.dyd.label.size); + L->nny--; + return status; } - - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/ldo.h b/examples/ThirdPartyLibs/lua-5.2.3/src/ldo.h index d3d3082c9..09204d160 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/ldo.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/ldo.h @@ -7,40 +7,42 @@ #ifndef ldo_h #define ldo_h - #include "lobject.h" #include "lstate.h" #include "lzio.h" +#define luaD_checkstack(L, n) \ + if (L->stack_last - L->top <= (n)) \ + luaD_growstack(L, n); \ + else \ + condmovestack(L); -#define luaD_checkstack(L,n) if (L->stack_last - L->top <= (n)) \ - luaD_growstack(L, n); else condmovestack(L); - - -#define incr_top(L) {L->top++; luaD_checkstack(L,0);} - -#define savestack(L,p) ((char *)(p) - (char *)L->stack) -#define restorestack(L,n) ((TValue *)((char *)L->stack + (n))) +#define incr_top(L) \ + { \ + L->top++; \ + luaD_checkstack(L, 0); \ + } +#define savestack(L, p) ((char *)(p) - (char *)L->stack) +#define restorestack(L, n) ((TValue *)((char *)L->stack + (n))) /* type of protected functions, to be ran by `runprotected' */ -typedef void (*Pfunc) (lua_State *L, void *ud); +typedef void (*Pfunc)(lua_State *L, void *ud); -LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, - const char *mode); -LUAI_FUNC void luaD_hook (lua_State *L, int event, int line); -LUAI_FUNC int luaD_precall (lua_State *L, StkId func, int nresults); -LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults, - int allowyield); -LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, - ptrdiff_t oldtop, ptrdiff_t ef); -LUAI_FUNC int luaD_poscall (lua_State *L, StkId firstResult); -LUAI_FUNC void luaD_reallocstack (lua_State *L, int newsize); -LUAI_FUNC void luaD_growstack (lua_State *L, int n); -LUAI_FUNC void luaD_shrinkstack (lua_State *L); +LUAI_FUNC int luaD_protectedparser(lua_State *L, ZIO *z, const char *name, + const char *mode); +LUAI_FUNC void luaD_hook(lua_State *L, int event, int line); +LUAI_FUNC int luaD_precall(lua_State *L, StkId func, int nresults); +LUAI_FUNC void luaD_call(lua_State *L, StkId func, int nResults, + int allowyield); +LUAI_FUNC int luaD_pcall(lua_State *L, Pfunc func, void *u, + ptrdiff_t oldtop, ptrdiff_t ef); +LUAI_FUNC int luaD_poscall(lua_State *L, StkId firstResult); +LUAI_FUNC void luaD_reallocstack(lua_State *L, int newsize); +LUAI_FUNC void luaD_growstack(lua_State *L, int n); +LUAI_FUNC void luaD_shrinkstack(lua_State *L); -LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); -LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); +LUAI_FUNC l_noret luaD_throw(lua_State *L, int errcode); +LUAI_FUNC int luaD_rawrunprotected(lua_State *L, Pfunc f, void *ud); #endif - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/ldump.c b/examples/ThirdPartyLibs/lua-5.2.3/src/ldump.c index 61fa2cd89..e98e4fb03 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/ldump.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/ldump.c @@ -15,159 +15,161 @@ #include "lstate.h" #include "lundump.h" -typedef struct { - lua_State* L; - lua_Writer writer; - void* data; - int strip; - int status; +typedef struct +{ + lua_State* L; + lua_Writer writer; + void* data; + int strip; + int status; } DumpState; -#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D) -#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D) +#define DumpMem(b, n, size, D) DumpBlock(b, (n) * (size), D) +#define DumpVar(x, D) DumpMem(&x, 1, sizeof(x), D) static void DumpBlock(const void* b, size_t size, DumpState* D) { - if (D->status==0) - { - lua_unlock(D->L); - D->status=(*D->writer)(D->L,b,size,D->data); - lua_lock(D->L); - } + if (D->status == 0) + { + lua_unlock(D->L); + D->status = (*D->writer)(D->L, b, size, D->data); + lua_lock(D->L); + } } static void DumpChar(int y, DumpState* D) { - char x=(char)y; - DumpVar(x,D); + char x = (char)y; + DumpVar(x, D); } static void DumpInt(int x, DumpState* D) { - DumpVar(x,D); + DumpVar(x, D); } static void DumpNumber(lua_Number x, DumpState* D) { - DumpVar(x,D); + DumpVar(x, D); } static void DumpVector(const void* b, int n, size_t size, DumpState* D) { - DumpInt(n,D); - DumpMem(b,n,size,D); + DumpInt(n, D); + DumpMem(b, n, size, D); } static void DumpString(const TString* s, DumpState* D) { - if (s==NULL) - { - size_t size=0; - DumpVar(size,D); - } - else - { - size_t size=s->tsv.len+1; /* include trailing '\0' */ - DumpVar(size,D); - DumpBlock(getstr(s),size*sizeof(char),D); - } + if (s == NULL) + { + size_t size = 0; + DumpVar(size, D); + } + else + { + size_t size = s->tsv.len + 1; /* include trailing '\0' */ + DumpVar(size, D); + DumpBlock(getstr(s), size * sizeof(char), D); + } } -#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D) +#define DumpCode(f, D) DumpVector(f->code, f->sizecode, sizeof(Instruction), D) static void DumpFunction(const Proto* f, DumpState* D); static void DumpConstants(const Proto* f, DumpState* D) { - int i,n=f->sizek; - DumpInt(n,D); - for (i=0; ik[i]; - DumpChar(ttypenv(o),D); - switch (ttypenv(o)) - { - case LUA_TNIL: - break; - case LUA_TBOOLEAN: - DumpChar(bvalue(o),D); - break; - case LUA_TNUMBER: - DumpNumber(nvalue(o),D); - break; - case LUA_TSTRING: - DumpString(rawtsvalue(o),D); - break; - default: lua_assert(0); - } - } - n=f->sizep; - DumpInt(n,D); - for (i=0; ip[i],D); + int i, n = f->sizek; + DumpInt(n, D); + for (i = 0; i < n; i++) + { + const TValue* o = &f->k[i]; + DumpChar(ttypenv(o), D); + switch (ttypenv(o)) + { + case LUA_TNIL: + break; + case LUA_TBOOLEAN: + DumpChar(bvalue(o), D); + break; + case LUA_TNUMBER: + DumpNumber(nvalue(o), D); + break; + case LUA_TSTRING: + DumpString(rawtsvalue(o), D); + break; + default: + lua_assert(0); + } + } + n = f->sizep; + DumpInt(n, D); + for (i = 0; i < n; i++) DumpFunction(f->p[i], D); } static void DumpUpvalues(const Proto* f, DumpState* D) { - int i,n=f->sizeupvalues; - DumpInt(n,D); - for (i=0; iupvalues[i].instack,D); - DumpChar(f->upvalues[i].idx,D); - } + int i, n = f->sizeupvalues; + DumpInt(n, D); + for (i = 0; i < n; i++) + { + DumpChar(f->upvalues[i].instack, D); + DumpChar(f->upvalues[i].idx, D); + } } static void DumpDebug(const Proto* f, DumpState* D) { - int i,n; - DumpString((D->strip) ? NULL : f->source,D); - n= (D->strip) ? 0 : f->sizelineinfo; - DumpVector(f->lineinfo,n,sizeof(int),D); - n= (D->strip) ? 0 : f->sizelocvars; - DumpInt(n,D); - for (i=0; ilocvars[i].varname,D); - DumpInt(f->locvars[i].startpc,D); - DumpInt(f->locvars[i].endpc,D); - } - n= (D->strip) ? 0 : f->sizeupvalues; - DumpInt(n,D); - for (i=0; iupvalues[i].name,D); + int i, n; + DumpString((D->strip) ? NULL : f->source, D); + n = (D->strip) ? 0 : f->sizelineinfo; + DumpVector(f->lineinfo, n, sizeof(int), D); + n = (D->strip) ? 0 : f->sizelocvars; + DumpInt(n, D); + for (i = 0; i < n; i++) + { + DumpString(f->locvars[i].varname, D); + DumpInt(f->locvars[i].startpc, D); + DumpInt(f->locvars[i].endpc, D); + } + n = (D->strip) ? 0 : f->sizeupvalues; + DumpInt(n, D); + for (i = 0; i < n; i++) DumpString(f->upvalues[i].name, D); } static void DumpFunction(const Proto* f, DumpState* D) { - DumpInt(f->linedefined,D); - DumpInt(f->lastlinedefined,D); - DumpChar(f->numparams,D); - DumpChar(f->is_vararg,D); - DumpChar(f->maxstacksize,D); - DumpCode(f,D); - DumpConstants(f,D); - DumpUpvalues(f,D); - DumpDebug(f,D); + DumpInt(f->linedefined, D); + DumpInt(f->lastlinedefined, D); + DumpChar(f->numparams, D); + DumpChar(f->is_vararg, D); + DumpChar(f->maxstacksize, D); + DumpCode(f, D); + DumpConstants(f, D); + DumpUpvalues(f, D); + DumpDebug(f, D); } static void DumpHeader(DumpState* D) { - lu_byte h[LUAC_HEADERSIZE]; - luaU_header(h); - DumpBlock(h,LUAC_HEADERSIZE,D); + lu_byte h[LUAC_HEADERSIZE]; + luaU_header(h); + DumpBlock(h, LUAC_HEADERSIZE, D); } /* ** dump Lua function as precompiled chunk */ -int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) +int luaU_dump(lua_State* L, const Proto* f, lua_Writer w, void* data, int strip) { - DumpState D; - D.L=L; - D.writer=w; - D.data=data; - D.strip=strip; - D.status=0; - DumpHeader(&D); - DumpFunction(f,&D); - return D.status; + DumpState D; + D.L = L; + D.writer = w; + D.data = data; + D.strip = strip; + D.status = 0; + DumpHeader(&D); + DumpFunction(f, &D); + return D.status; } diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lfunc.c b/examples/ThirdPartyLibs/lua-5.2.3/src/lfunc.c index e90e1520c..38f48755c 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lfunc.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lfunc.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #include #define lfunc_c @@ -18,144 +17,148 @@ #include "lobject.h" #include "lstate.h" - - -Closure *luaF_newCclosure (lua_State *L, int n) { - Closure *c = &luaC_newobj(L, LUA_TCCL, sizeCclosure(n), NULL, 0)->cl; - c->c.nupvalues = cast_byte(n); - return c; +Closure *luaF_newCclosure(lua_State *L, int n) +{ + Closure *c = &luaC_newobj(L, LUA_TCCL, sizeCclosure(n), NULL, 0)->cl; + c->c.nupvalues = cast_byte(n); + return c; } - -Closure *luaF_newLclosure (lua_State *L, int n) { - Closure *c = &luaC_newobj(L, LUA_TLCL, sizeLclosure(n), NULL, 0)->cl; - c->l.p = NULL; - c->l.nupvalues = cast_byte(n); - while (n--) c->l.upvals[n] = NULL; - return c; +Closure *luaF_newLclosure(lua_State *L, int n) +{ + Closure *c = &luaC_newobj(L, LUA_TLCL, sizeLclosure(n), NULL, 0)->cl; + c->l.p = NULL; + c->l.nupvalues = cast_byte(n); + while (n--) c->l.upvals[n] = NULL; + return c; } - -UpVal *luaF_newupval (lua_State *L) { - UpVal *uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), NULL, 0)->uv; - uv->v = &uv->u.value; - setnilvalue(uv->v); - return uv; +UpVal *luaF_newupval(lua_State *L) +{ + UpVal *uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), NULL, 0)->uv; + uv->v = &uv->u.value; + setnilvalue(uv->v); + return uv; } - -UpVal *luaF_findupval (lua_State *L, StkId level) { - global_State *g = G(L); - GCObject **pp = &L->openupval; - UpVal *p; - UpVal *uv; - while (*pp != NULL && (p = gco2uv(*pp))->v >= level) { - GCObject *o = obj2gco(p); - lua_assert(p->v != &p->u.value); - lua_assert(!isold(o) || isold(obj2gco(L))); - if (p->v == level) { /* found a corresponding upvalue? */ - if (isdead(g, o)) /* is it dead? */ - changewhite(o); /* resurrect it */ - return p; - } - pp = &p->next; - } - /* not found: create a new one */ - uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), pp, 0)->uv; - uv->v = level; /* current value lives in the stack */ - uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ - uv->u.l.next = g->uvhead.u.l.next; - uv->u.l.next->u.l.prev = uv; - g->uvhead.u.l.next = uv; - lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); - return uv; +UpVal *luaF_findupval(lua_State *L, StkId level) +{ + global_State *g = G(L); + GCObject **pp = &L->openupval; + UpVal *p; + UpVal *uv; + while (*pp != NULL && (p = gco2uv(*pp))->v >= level) + { + GCObject *o = obj2gco(p); + lua_assert(p->v != &p->u.value); + lua_assert(!isold(o) || isold(obj2gco(L))); + if (p->v == level) + { /* found a corresponding upvalue? */ + if (isdead(g, o)) /* is it dead? */ + changewhite(o); /* resurrect it */ + return p; + } + pp = &p->next; + } + /* not found: create a new one */ + uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), pp, 0)->uv; + uv->v = level; /* current value lives in the stack */ + uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ + uv->u.l.next = g->uvhead.u.l.next; + uv->u.l.next->u.l.prev = uv; + g->uvhead.u.l.next = uv; + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + return uv; } - -static void unlinkupval (UpVal *uv) { - lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); - uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ - uv->u.l.prev->u.l.next = uv->u.l.next; +static void unlinkupval(UpVal *uv) +{ + lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); + uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ + uv->u.l.prev->u.l.next = uv->u.l.next; } - -void luaF_freeupval (lua_State *L, UpVal *uv) { - if (uv->v != &uv->u.value) /* is it open? */ - unlinkupval(uv); /* remove from open list */ - luaM_free(L, uv); /* free upvalue */ +void luaF_freeupval(lua_State *L, UpVal *uv) +{ + if (uv->v != &uv->u.value) /* is it open? */ + unlinkupval(uv); /* remove from open list */ + luaM_free(L, uv); /* free upvalue */ } - -void luaF_close (lua_State *L, StkId level) { - UpVal *uv; - global_State *g = G(L); - while (L->openupval != NULL && (uv = gco2uv(L->openupval))->v >= level) { - GCObject *o = obj2gco(uv); - lua_assert(!isblack(o) && uv->v != &uv->u.value); - L->openupval = uv->next; /* remove from `open' list */ - if (isdead(g, o)) - luaF_freeupval(L, uv); /* free upvalue */ - else { - unlinkupval(uv); /* remove upvalue from 'uvhead' list */ - setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ - uv->v = &uv->u.value; /* now current value lives here */ - gch(o)->next = g->allgc; /* link upvalue into 'allgc' list */ - g->allgc = o; - luaC_checkupvalcolor(g, uv); - } - } +void luaF_close(lua_State *L, StkId level) +{ + UpVal *uv; + global_State *g = G(L); + while (L->openupval != NULL && (uv = gco2uv(L->openupval))->v >= level) + { + GCObject *o = obj2gco(uv); + lua_assert(!isblack(o) && uv->v != &uv->u.value); + L->openupval = uv->next; /* remove from `open' list */ + if (isdead(g, o)) + luaF_freeupval(L, uv); /* free upvalue */ + else + { + unlinkupval(uv); /* remove upvalue from 'uvhead' list */ + setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */ + uv->v = &uv->u.value; /* now current value lives here */ + gch(o)->next = g->allgc; /* link upvalue into 'allgc' list */ + g->allgc = o; + luaC_checkupvalcolor(g, uv); + } + } } - -Proto *luaF_newproto (lua_State *L) { - Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto), NULL, 0)->p; - f->k = NULL; - f->sizek = 0; - f->p = NULL; - f->sizep = 0; - f->code = NULL; - f->cache = NULL; - f->sizecode = 0; - f->lineinfo = NULL; - f->sizelineinfo = 0; - f->upvalues = NULL; - f->sizeupvalues = 0; - f->numparams = 0; - f->is_vararg = 0; - f->maxstacksize = 0; - f->locvars = NULL; - f->sizelocvars = 0; - f->linedefined = 0; - f->lastlinedefined = 0; - f->source = NULL; - return f; +Proto *luaF_newproto(lua_State *L) +{ + Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto), NULL, 0)->p; + f->k = NULL; + f->sizek = 0; + f->p = NULL; + f->sizep = 0; + f->code = NULL; + f->cache = NULL; + f->sizecode = 0; + f->lineinfo = NULL; + f->sizelineinfo = 0; + f->upvalues = NULL; + f->sizeupvalues = 0; + f->numparams = 0; + f->is_vararg = 0; + f->maxstacksize = 0; + f->locvars = NULL; + f->sizelocvars = 0; + f->linedefined = 0; + f->lastlinedefined = 0; + f->source = NULL; + return f; } - -void luaF_freeproto (lua_State *L, Proto *f) { - luaM_freearray(L, f->code, f->sizecode); - luaM_freearray(L, f->p, f->sizep); - luaM_freearray(L, f->k, f->sizek); - luaM_freearray(L, f->lineinfo, f->sizelineinfo); - luaM_freearray(L, f->locvars, f->sizelocvars); - luaM_freearray(L, f->upvalues, f->sizeupvalues); - luaM_free(L, f); +void luaF_freeproto(lua_State *L, Proto *f) +{ + luaM_freearray(L, f->code, f->sizecode); + luaM_freearray(L, f->p, f->sizep); + luaM_freearray(L, f->k, f->sizek); + luaM_freearray(L, f->lineinfo, f->sizelineinfo); + luaM_freearray(L, f->locvars, f->sizelocvars); + luaM_freearray(L, f->upvalues, f->sizeupvalues); + luaM_free(L, f); } - /* ** Look for n-th local variable at line `line' in function `func'. ** Returns NULL if not found. */ -const char *luaF_getlocalname (const Proto *f, int local_number, int pc) { - int i; - for (i = 0; isizelocvars && f->locvars[i].startpc <= pc; i++) { - if (pc < f->locvars[i].endpc) { /* is variable active? */ - local_number--; - if (local_number == 0) - return getstr(f->locvars[i].varname); - } - } - return NULL; /* not found */ +const char *luaF_getlocalname(const Proto *f, int local_number, int pc) +{ + int i; + for (i = 0; i < f->sizelocvars && f->locvars[i].startpc <= pc; i++) + { + if (pc < f->locvars[i].endpc) + { /* is variable active? */ + local_number--; + if (local_number == 0) + return getstr(f->locvars[i].varname); + } + } + return NULL; /* not found */ } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lfunc.h b/examples/ThirdPartyLibs/lua-5.2.3/src/lfunc.h index ca0d3a3e0..d7d26e67f 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lfunc.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lfunc.h @@ -7,27 +7,23 @@ #ifndef lfunc_h #define lfunc_h - #include "lobject.h" +#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ + cast(int, sizeof(TValue) * ((n)-1))) -#define sizeCclosure(n) (cast(int, sizeof(CClosure)) + \ - cast(int, sizeof(TValue)*((n)-1))) - -#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ - cast(int, sizeof(TValue *)*((n)-1))) - - -LUAI_FUNC Proto *luaF_newproto (lua_State *L); -LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems); -LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems); -LUAI_FUNC UpVal *luaF_newupval (lua_State *L); -LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); -LUAI_FUNC void luaF_close (lua_State *L, StkId level); -LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); -LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv); -LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, - int pc); +#define sizeLclosure(n) (cast(int, sizeof(LClosure)) + \ + cast(int, sizeof(TValue *) * ((n)-1))) +LUAI_FUNC Proto *luaF_newproto(lua_State *L); +LUAI_FUNC Closure *luaF_newCclosure(lua_State *L, int nelems); +LUAI_FUNC Closure *luaF_newLclosure(lua_State *L, int nelems); +LUAI_FUNC UpVal *luaF_newupval(lua_State *L); +LUAI_FUNC UpVal *luaF_findupval(lua_State *L, StkId level); +LUAI_FUNC void luaF_close(lua_State *L, StkId level); +LUAI_FUNC void luaF_freeproto(lua_State *L, Proto *f); +LUAI_FUNC void luaF_freeupval(lua_State *L, UpVal *uv); +LUAI_FUNC const char *luaF_getlocalname(const Proto *func, int local_number, + int pc); #endif diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lgc.c b/examples/ThirdPartyLibs/lua-5.2.3/src/lgc.c index 52460dcdd..6dd4bd537 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lgc.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lgc.c @@ -22,64 +22,61 @@ #include "ltable.h" #include "ltm.h" - - /* ** cost of sweeping one element (the size of a small object divided ** by some adjust for the sweep speed) */ -#define GCSWEEPCOST ((sizeof(TString) + 4) / 4) +#define GCSWEEPCOST ((sizeof(TString) + 4) / 4) /* maximum number of elements to sweep in each single step */ -#define GCSWEEPMAX (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4)) +#define GCSWEEPMAX (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4)) /* maximum number of finalizers to call in each GC step */ -#define GCFINALIZENUM 4 - +#define GCFINALIZENUM 4 /* ** macro to adjust 'stepmul': 'stepmul' is actually used like ** 'stepmul / STEPMULADJ' (value chosen by tests) */ -#define STEPMULADJ 200 - +#define STEPMULADJ 200 /* ** macro to adjust 'pause': 'pause' is actually used like ** 'pause / PAUSEADJ' (value chosen by tests) */ -#define PAUSEADJ 100 - +#define PAUSEADJ 100 /* ** 'makewhite' erases all color bits plus the old bit and then ** sets only the current white bit */ -#define maskcolors (~(bit2mask(BLACKBIT, OLDBIT) | WHITEBITS)) -#define makewhite(g,x) \ - (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g))) +#define maskcolors (~(bit2mask(BLACKBIT, OLDBIT) | WHITEBITS)) +#define makewhite(g, x) \ + (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g))) -#define white2gray(x) resetbits(gch(x)->marked, WHITEBITS) -#define black2gray(x) resetbit(gch(x)->marked, BLACKBIT) +#define white2gray(x) resetbits(gch(x)->marked, WHITEBITS) +#define black2gray(x) resetbit(gch(x)->marked, BLACKBIT) +#define isfinalized(x) testbit(gch(x)->marked, FINALIZEDBIT) -#define isfinalized(x) testbit(gch(x)->marked, FINALIZEDBIT) +#define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n))) -#define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n))) +#define checkconsistency(obj) \ + lua_longassert(!iscollectable(obj) || righttt(obj)) +#define markvalue(g, o) \ + { \ + checkconsistency(o); \ + if (valiswhite(o)) reallymarkobject(g, gcvalue(o)); \ + } -#define checkconsistency(obj) \ - lua_longassert(!iscollectable(obj) || righttt(obj)) - - -#define markvalue(g,o) { checkconsistency(o); \ - if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } - -#define markobject(g,t) { if ((t) && iswhite(obj2gco(t))) \ - reallymarkobject(g, obj2gco(t)); } - -static void reallymarkobject (global_State *g, GCObject *o); +#define markobject(g, t) \ + { \ + if ((t) && iswhite(obj2gco(t))) \ + reallymarkobject(g, obj2gco(t)); \ + } +static void reallymarkobject(global_State *g, GCObject *o); /* ** {====================================================== @@ -87,30 +84,27 @@ static void reallymarkobject (global_State *g, GCObject *o); ** ======================================================= */ - /* ** one after last element in a hash array */ -#define gnodelast(h) gnode(h, cast(size_t, sizenode(h))) - +#define gnodelast(h) gnode(h, cast(size_t, sizenode(h))) /* ** link table 'h' into list pointed by 'p' */ -#define linktable(h,p) ((h)->gclist = *(p), *(p) = obj2gco(h)) - +#define linktable(h, p) ((h)->gclist = *(p), *(p) = obj2gco(h)) /* ** if key is not marked, mark its entry as dead (therefore removing it ** from the table) */ -static void removeentry (Node *n) { - lua_assert(ttisnil(gval(n))); - if (valiswhite(gkey(n))) - setdeadvalue(gkey(n)); /* unused and unmarked key; remove it */ +static void removeentry(Node *n) +{ + lua_assert(ttisnil(gval(n))); + if (valiswhite(gkey(n))) + setdeadvalue(gkey(n)); /* unused and unmarked key; remove it */ } - /* ** tells whether a key or value can be cleared from a weak ** table. Non-collectable objects are never removed from weak @@ -118,49 +112,53 @@ static void removeentry (Node *n) { ** other objects: if really collected, cannot keep them; for objects ** being finalized, keep them in keys, but not in values */ -static int iscleared (global_State *g, const TValue *o) { - if (!iscollectable(o)) return 0; - else if (ttisstring(o)) { - markobject(g, rawtsvalue(o)); /* strings are `values', so are never weak */ - return 0; - } - else return iswhite(gcvalue(o)); +static int iscleared(global_State *g, const TValue *o) +{ + if (!iscollectable(o)) + return 0; + else if (ttisstring(o)) + { + markobject(g, rawtsvalue(o)); /* strings are `values', so are never weak */ + return 0; + } + else + return iswhite(gcvalue(o)); } - /* ** barrier that moves collector forward, that is, mark the white object ** being pointed by a black object. */ -void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { - global_State *g = G(L); - lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); - lua_assert(g->gcstate != GCSpause); - lua_assert(gch(o)->tt != LUA_TTABLE); - if (keepinvariantout(g)) /* must keep invariant? */ - reallymarkobject(g, v); /* restore invariant */ - else { /* sweep phase */ - lua_assert(issweepphase(g)); - makewhite(g, o); /* mark main obj. as white to avoid other barriers */ - } +void luaC_barrier_(lua_State *L, GCObject *o, GCObject *v) +{ + global_State *g = G(L); + lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o)); + lua_assert(g->gcstate != GCSpause); + lua_assert(gch(o)->tt != LUA_TTABLE); + if (keepinvariantout(g)) /* must keep invariant? */ + reallymarkobject(g, v); /* restore invariant */ + else + { /* sweep phase */ + lua_assert(issweepphase(g)); + makewhite(g, o); /* mark main obj. as white to avoid other barriers */ + } } - /* ** barrier that moves collector backward, that is, mark the black object ** pointing to a white object as gray again. (Current implementation ** only works for tables; access to 'gclist' is not uniform across ** different types.) */ -void luaC_barrierback_ (lua_State *L, GCObject *o) { - global_State *g = G(L); - lua_assert(isblack(o) && !isdead(g, o) && gch(o)->tt == LUA_TTABLE); - black2gray(o); /* make object gray (again) */ - gco2t(o)->gclist = g->grayagain; - g->grayagain = o; +void luaC_barrierback_(lua_State *L, GCObject *o) +{ + global_State *g = G(L); + lua_assert(isblack(o) && !isdead(g, o) && gch(o)->tt == LUA_TTABLE); + black2gray(o); /* make object gray (again) */ + gco2t(o)->gclist = g->grayagain; + g->grayagain = o; } - /* ** barrier for prototypes. When creating first closure (cache is ** NULL), use a forward barrier; this may be the only closure of the @@ -169,409 +167,447 @@ void luaC_barrierback_ (lua_State *L, GCObject *o) { ** it again. Otherwise, use a backward barrier, to avoid marking all ** possible instances. */ -LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c) { - global_State *g = G(L); - lua_assert(isblack(obj2gco(p))); - if (p->cache == NULL) { /* first time? */ - luaC_objbarrier(L, p, c); - } - else { /* use a backward barrier */ - black2gray(obj2gco(p)); /* make prototype gray (again) */ - p->gclist = g->grayagain; - g->grayagain = obj2gco(p); - } +LUAI_FUNC void luaC_barrierproto_(lua_State *L, Proto *p, Closure *c) +{ + global_State *g = G(L); + lua_assert(isblack(obj2gco(p))); + if (p->cache == NULL) + { /* first time? */ + luaC_objbarrier(L, p, c); + } + else + { /* use a backward barrier */ + black2gray(obj2gco(p)); /* make prototype gray (again) */ + p->gclist = g->grayagain; + g->grayagain = obj2gco(p); + } } - /* ** check color (and invariants) for an upvalue that was closed, ** i.e., moved into the 'allgc' list */ -void luaC_checkupvalcolor (global_State *g, UpVal *uv) { - GCObject *o = obj2gco(uv); - lua_assert(!isblack(o)); /* open upvalues are never black */ - if (isgray(o)) { - if (keepinvariant(g)) { - resetoldbit(o); /* see MOVE OLD rule */ - gray2black(o); /* it is being visited now */ - markvalue(g, uv->v); - } - else { - lua_assert(issweepphase(g)); - makewhite(g, o); - } - } +void luaC_checkupvalcolor(global_State *g, UpVal *uv) +{ + GCObject *o = obj2gco(uv); + lua_assert(!isblack(o)); /* open upvalues are never black */ + if (isgray(o)) + { + if (keepinvariant(g)) + { + resetoldbit(o); /* see MOVE OLD rule */ + gray2black(o); /* it is being visited now */ + markvalue(g, uv->v); + } + else + { + lua_assert(issweepphase(g)); + makewhite(g, o); + } + } } - /* ** create a new collectable object (with given type and size) and link ** it to '*list'. 'offset' tells how many bytes to allocate before the ** object itself (used only by states). */ -GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list, - int offset) { - global_State *g = G(L); - char *raw = cast(char *, luaM_newobject(L, novariant(tt), sz)); - GCObject *o = obj2gco(raw + offset); - if (list == NULL) - list = &g->allgc; /* standard list for collectable objects */ - gch(o)->marked = luaC_white(g); - gch(o)->tt = tt; - gch(o)->next = *list; - *list = o; - return o; +GCObject *luaC_newobj(lua_State *L, int tt, size_t sz, GCObject **list, + int offset) +{ + global_State *g = G(L); + char *raw = cast(char *, luaM_newobject(L, novariant(tt), sz)); + GCObject *o = obj2gco(raw + offset); + if (list == NULL) + list = &g->allgc; /* standard list for collectable objects */ + gch(o)->marked = luaC_white(g); + gch(o)->tt = tt; + gch(o)->next = *list; + *list = o; + return o; } /* }====================================================== */ - - /* ** {====================================================== ** Mark functions ** ======================================================= */ - /* ** mark an object. Userdata, strings, and closed upvalues are visited ** and turned black here. Other objects are marked gray and added ** to appropriate list to be visited (and turned black) later. (Open ** upvalues are already linked in 'headuv' list.) */ -static void reallymarkobject (global_State *g, GCObject *o) { - lu_mem size; - white2gray(o); - switch (gch(o)->tt) { - case LUA_TSHRSTR: - case LUA_TLNGSTR: { - size = sizestring(gco2ts(o)); - break; /* nothing else to mark; make it black */ - } - case LUA_TUSERDATA: { - Table *mt = gco2u(o)->metatable; - markobject(g, mt); - markobject(g, gco2u(o)->env); - size = sizeudata(gco2u(o)); - break; - } - case LUA_TUPVAL: { - UpVal *uv = gco2uv(o); - markvalue(g, uv->v); - if (uv->v != &uv->u.value) /* open? */ - return; /* open upvalues remain gray */ - size = sizeof(UpVal); - break; - } - case LUA_TLCL: { - gco2lcl(o)->gclist = g->gray; - g->gray = o; - return; - } - case LUA_TCCL: { - gco2ccl(o)->gclist = g->gray; - g->gray = o; - return; - } - case LUA_TTABLE: { - linktable(gco2t(o), &g->gray); - return; - } - case LUA_TTHREAD: { - gco2th(o)->gclist = g->gray; - g->gray = o; - return; - } - case LUA_TPROTO: { - gco2p(o)->gclist = g->gray; - g->gray = o; - return; - } - default: lua_assert(0); return; - } - gray2black(o); - g->GCmemtrav += size; +static void reallymarkobject(global_State *g, GCObject *o) +{ + lu_mem size; + white2gray(o); + switch (gch(o)->tt) + { + case LUA_TSHRSTR: + case LUA_TLNGSTR: + { + size = sizestring(gco2ts(o)); + break; /* nothing else to mark; make it black */ + } + case LUA_TUSERDATA: + { + Table *mt = gco2u(o)->metatable; + markobject(g, mt); + markobject(g, gco2u(o)->env); + size = sizeudata(gco2u(o)); + break; + } + case LUA_TUPVAL: + { + UpVal *uv = gco2uv(o); + markvalue(g, uv->v); + if (uv->v != &uv->u.value) /* open? */ + return; /* open upvalues remain gray */ + size = sizeof(UpVal); + break; + } + case LUA_TLCL: + { + gco2lcl(o)->gclist = g->gray; + g->gray = o; + return; + } + case LUA_TCCL: + { + gco2ccl(o)->gclist = g->gray; + g->gray = o; + return; + } + case LUA_TTABLE: + { + linktable(gco2t(o), &g->gray); + return; + } + case LUA_TTHREAD: + { + gco2th(o)->gclist = g->gray; + g->gray = o; + return; + } + case LUA_TPROTO: + { + gco2p(o)->gclist = g->gray; + g->gray = o; + return; + } + default: + lua_assert(0); + return; + } + gray2black(o); + g->GCmemtrav += size; } - /* ** mark metamethods for basic types */ -static void markmt (global_State *g) { - int i; - for (i=0; i < LUA_NUMTAGS; i++) - markobject(g, g->mt[i]); +static void markmt(global_State *g) +{ + int i; + for (i = 0; i < LUA_NUMTAGS; i++) + markobject(g, g->mt[i]); } - /* ** mark all objects in list of being-finalized */ -static void markbeingfnz (global_State *g) { - GCObject *o; - for (o = g->tobefnz; o != NULL; o = gch(o)->next) { - makewhite(g, o); - reallymarkobject(g, o); - } +static void markbeingfnz(global_State *g) +{ + GCObject *o; + for (o = g->tobefnz; o != NULL; o = gch(o)->next) + { + makewhite(g, o); + reallymarkobject(g, o); + } } - /* ** mark all values stored in marked open upvalues. (See comment in ** 'lstate.h'.) */ -static void remarkupvals (global_State *g) { - UpVal *uv; - for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { - if (isgray(obj2gco(uv))) - markvalue(g, uv->v); - } +static void remarkupvals(global_State *g) +{ + UpVal *uv; + for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) + { + if (isgray(obj2gco(uv))) + markvalue(g, uv->v); + } } - /* ** mark root set and reset all gray lists, to start a new ** incremental (or full) collection */ -static void restartcollection (global_State *g) { - g->gray = g->grayagain = NULL; - g->weak = g->allweak = g->ephemeron = NULL; - markobject(g, g->mainthread); - markvalue(g, &g->l_registry); - markmt(g); - markbeingfnz(g); /* mark any finalizing object left from previous cycle */ +static void restartcollection(global_State *g) +{ + g->gray = g->grayagain = NULL; + g->weak = g->allweak = g->ephemeron = NULL; + markobject(g, g->mainthread); + markvalue(g, &g->l_registry); + markmt(g); + markbeingfnz(g); /* mark any finalizing object left from previous cycle */ } /* }====================================================== */ - /* ** {====================================================== ** Traverse functions ** ======================================================= */ -static void traverseweakvalue (global_State *g, Table *h) { - Node *n, *limit = gnodelast(h); - /* if there is array part, assume it may have white values (do not +static void traverseweakvalue(global_State *g, Table *h) +{ + Node *n, *limit = gnodelast(h); + /* if there is array part, assume it may have white values (do not traverse it just to check) */ - int hasclears = (h->sizearray > 0); - for (n = gnode(h, 0); n < limit; n++) { - checkdeadkey(n); - if (ttisnil(gval(n))) /* entry is empty? */ - removeentry(n); /* remove it */ - else { - lua_assert(!ttisnil(gkey(n))); - markvalue(g, gkey(n)); /* mark key */ - if (!hasclears && iscleared(g, gval(n))) /* is there a white value? */ - hasclears = 1; /* table will have to be cleared */ - } - } - if (hasclears) - linktable(h, &g->weak); /* has to be cleared later */ - else /* no white values */ - linktable(h, &g->grayagain); /* no need to clean */ + int hasclears = (h->sizearray > 0); + for (n = gnode(h, 0); n < limit; n++) + { + checkdeadkey(n); + if (ttisnil(gval(n))) /* entry is empty? */ + removeentry(n); /* remove it */ + else + { + lua_assert(!ttisnil(gkey(n))); + markvalue(g, gkey(n)); /* mark key */ + if (!hasclears && iscleared(g, gval(n))) /* is there a white value? */ + hasclears = 1; /* table will have to be cleared */ + } + } + if (hasclears) + linktable(h, &g->weak); /* has to be cleared later */ + else /* no white values */ + linktable(h, &g->grayagain); /* no need to clean */ } - -static int traverseephemeron (global_State *g, Table *h) { - int marked = 0; /* true if an object is marked in this traversal */ - int hasclears = 0; /* true if table has white keys */ - int prop = 0; /* true if table has entry "white-key -> white-value" */ - Node *n, *limit = gnodelast(h); - int i; - /* traverse array part (numeric keys are 'strong') */ - for (i = 0; i < h->sizearray; i++) { - if (valiswhite(&h->array[i])) { - marked = 1; - reallymarkobject(g, gcvalue(&h->array[i])); - } - } - /* traverse hash part */ - for (n = gnode(h, 0); n < limit; n++) { - checkdeadkey(n); - if (ttisnil(gval(n))) /* entry is empty? */ - removeentry(n); /* remove it */ - else if (iscleared(g, gkey(n))) { /* key is not marked (yet)? */ - hasclears = 1; /* table must be cleared */ - if (valiswhite(gval(n))) /* value not marked yet? */ - prop = 1; /* must propagate again */ - } - else if (valiswhite(gval(n))) { /* value not marked yet? */ - marked = 1; - reallymarkobject(g, gcvalue(gval(n))); /* mark it now */ - } - } - if (prop) - linktable(h, &g->ephemeron); /* have to propagate again */ - else if (hasclears) /* does table have white keys? */ - linktable(h, &g->allweak); /* may have to clean white keys */ - else /* no white keys */ - linktable(h, &g->grayagain); /* no need to clean */ - return marked; +static int traverseephemeron(global_State *g, Table *h) +{ + int marked = 0; /* true if an object is marked in this traversal */ + int hasclears = 0; /* true if table has white keys */ + int prop = 0; /* true if table has entry "white-key -> white-value" */ + Node *n, *limit = gnodelast(h); + int i; + /* traverse array part (numeric keys are 'strong') */ + for (i = 0; i < h->sizearray; i++) + { + if (valiswhite(&h->array[i])) + { + marked = 1; + reallymarkobject(g, gcvalue(&h->array[i])); + } + } + /* traverse hash part */ + for (n = gnode(h, 0); n < limit; n++) + { + checkdeadkey(n); + if (ttisnil(gval(n))) /* entry is empty? */ + removeentry(n); /* remove it */ + else if (iscleared(g, gkey(n))) + { /* key is not marked (yet)? */ + hasclears = 1; /* table must be cleared */ + if (valiswhite(gval(n))) /* value not marked yet? */ + prop = 1; /* must propagate again */ + } + else if (valiswhite(gval(n))) + { /* value not marked yet? */ + marked = 1; + reallymarkobject(g, gcvalue(gval(n))); /* mark it now */ + } + } + if (prop) + linktable(h, &g->ephemeron); /* have to propagate again */ + else if (hasclears) /* does table have white keys? */ + linktable(h, &g->allweak); /* may have to clean white keys */ + else /* no white keys */ + linktable(h, &g->grayagain); /* no need to clean */ + return marked; } - -static void traversestrongtable (global_State *g, Table *h) { - Node *n, *limit = gnodelast(h); - int i; - for (i = 0; i < h->sizearray; i++) /* traverse array part */ - markvalue(g, &h->array[i]); - for (n = gnode(h, 0); n < limit; n++) { /* traverse hash part */ - checkdeadkey(n); - if (ttisnil(gval(n))) /* entry is empty? */ - removeentry(n); /* remove it */ - else { - lua_assert(!ttisnil(gkey(n))); - markvalue(g, gkey(n)); /* mark key */ - markvalue(g, gval(n)); /* mark value */ - } - } +static void traversestrongtable(global_State *g, Table *h) +{ + Node *n, *limit = gnodelast(h); + int i; + for (i = 0; i < h->sizearray; i++) /* traverse array part */ + markvalue(g, &h->array[i]); + for (n = gnode(h, 0); n < limit; n++) + { /* traverse hash part */ + checkdeadkey(n); + if (ttisnil(gval(n))) /* entry is empty? */ + removeentry(n); /* remove it */ + else + { + lua_assert(!ttisnil(gkey(n))); + markvalue(g, gkey(n)); /* mark key */ + markvalue(g, gval(n)); /* mark value */ + } + } } - -static lu_mem traversetable (global_State *g, Table *h) { - const char *weakkey, *weakvalue; - const TValue *mode = gfasttm(g, h->metatable, TM_MODE); - markobject(g, h->metatable); - if (mode && ttisstring(mode) && /* is there a weak mode? */ - ((weakkey = strchr(svalue(mode), 'k')), - (weakvalue = strchr(svalue(mode), 'v')), - (weakkey || weakvalue))) { /* is really weak? */ - black2gray(obj2gco(h)); /* keep table gray */ - if (!weakkey) /* strong keys? */ - traverseweakvalue(g, h); - else if (!weakvalue) /* strong values? */ - traverseephemeron(g, h); - else /* all weak */ - linktable(h, &g->allweak); /* nothing to traverse now */ - } - else /* not weak */ - traversestrongtable(g, h); - return sizeof(Table) + sizeof(TValue) * h->sizearray + - sizeof(Node) * cast(size_t, sizenode(h)); +static lu_mem traversetable(global_State *g, Table *h) +{ + const char *weakkey, *weakvalue; + const TValue *mode = gfasttm(g, h->metatable, TM_MODE); + markobject(g, h->metatable); + if (mode && ttisstring(mode) && /* is there a weak mode? */ + ((weakkey = strchr(svalue(mode), 'k')), + (weakvalue = strchr(svalue(mode), 'v')), + (weakkey || weakvalue))) + { /* is really weak? */ + black2gray(obj2gco(h)); /* keep table gray */ + if (!weakkey) /* strong keys? */ + traverseweakvalue(g, h); + else if (!weakvalue) /* strong values? */ + traverseephemeron(g, h); + else /* all weak */ + linktable(h, &g->allweak); /* nothing to traverse now */ + } + else /* not weak */ + traversestrongtable(g, h); + return sizeof(Table) + sizeof(TValue) * h->sizearray + + sizeof(Node) * cast(size_t, sizenode(h)); } - -static int traverseproto (global_State *g, Proto *f) { - int i; - if (f->cache && iswhite(obj2gco(f->cache))) - f->cache = NULL; /* allow cache to be collected */ - markobject(g, f->source); - for (i = 0; i < f->sizek; i++) /* mark literals */ - markvalue(g, &f->k[i]); - for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ - markobject(g, f->upvalues[i].name); - for (i = 0; i < f->sizep; i++) /* mark nested protos */ - markobject(g, f->p[i]); - for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ - markobject(g, f->locvars[i].varname); - return sizeof(Proto) + sizeof(Instruction) * f->sizecode + - sizeof(Proto *) * f->sizep + - sizeof(TValue) * f->sizek + - sizeof(int) * f->sizelineinfo + - sizeof(LocVar) * f->sizelocvars + - sizeof(Upvaldesc) * f->sizeupvalues; +static int traverseproto(global_State *g, Proto *f) +{ + int i; + if (f->cache && iswhite(obj2gco(f->cache))) + f->cache = NULL; /* allow cache to be collected */ + markobject(g, f->source); + for (i = 0; i < f->sizek; i++) /* mark literals */ + markvalue(g, &f->k[i]); + for (i = 0; i < f->sizeupvalues; i++) /* mark upvalue names */ + markobject(g, f->upvalues[i].name); + for (i = 0; i < f->sizep; i++) /* mark nested protos */ + markobject(g, f->p[i]); + for (i = 0; i < f->sizelocvars; i++) /* mark local-variable names */ + markobject(g, f->locvars[i].varname); + return sizeof(Proto) + sizeof(Instruction) * f->sizecode + + sizeof(Proto *) * f->sizep + + sizeof(TValue) * f->sizek + + sizeof(int) * f->sizelineinfo + + sizeof(LocVar) * f->sizelocvars + + sizeof(Upvaldesc) * f->sizeupvalues; } - -static lu_mem traverseCclosure (global_State *g, CClosure *cl) { - int i; - for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ - markvalue(g, &cl->upvalue[i]); - return sizeCclosure(cl->nupvalues); +static lu_mem traverseCclosure(global_State *g, CClosure *cl) +{ + int i; + for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ + markvalue(g, &cl->upvalue[i]); + return sizeCclosure(cl->nupvalues); } -static lu_mem traverseLclosure (global_State *g, LClosure *cl) { - int i; - markobject(g, cl->p); /* mark its prototype */ - for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ - markobject(g, cl->upvals[i]); - return sizeLclosure(cl->nupvalues); +static lu_mem traverseLclosure(global_State *g, LClosure *cl) +{ + int i; + markobject(g, cl->p); /* mark its prototype */ + for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ + markobject(g, cl->upvals[i]); + return sizeLclosure(cl->nupvalues); } - -static lu_mem traversestack (global_State *g, lua_State *th) { - int n = 0; - StkId o = th->stack; - if (o == NULL) - return 1; /* stack not completely built yet */ - for (; o < th->top; o++) /* mark live elements in the stack */ - markvalue(g, o); - if (g->gcstate == GCSatomic) { /* final traversal? */ - StkId lim = th->stack + th->stacksize; /* real end of stack */ - for (; o < lim; o++) /* clear not-marked stack slice */ - setnilvalue(o); - } - else { /* count call infos to compute size */ - CallInfo *ci; - for (ci = &th->base_ci; ci != th->ci; ci = ci->next) - n++; - } - return sizeof(lua_State) + sizeof(TValue) * th->stacksize + - sizeof(CallInfo) * n; +static lu_mem traversestack(global_State *g, lua_State *th) +{ + int n = 0; + StkId o = th->stack; + if (o == NULL) + return 1; /* stack not completely built yet */ + for (; o < th->top; o++) /* mark live elements in the stack */ + markvalue(g, o); + if (g->gcstate == GCSatomic) + { /* final traversal? */ + StkId lim = th->stack + th->stacksize; /* real end of stack */ + for (; o < lim; o++) /* clear not-marked stack slice */ + setnilvalue(o); + } + else + { /* count call infos to compute size */ + CallInfo *ci; + for (ci = &th->base_ci; ci != th->ci; ci = ci->next) + n++; + } + return sizeof(lua_State) + sizeof(TValue) * th->stacksize + + sizeof(CallInfo) * n; } - /* ** traverse one gray object, turning it to black (except for threads, ** which are always gray). */ -static void propagatemark (global_State *g) { - lu_mem size; - GCObject *o = g->gray; - lua_assert(isgray(o)); - gray2black(o); - switch (gch(o)->tt) { - case LUA_TTABLE: { - Table *h = gco2t(o); - g->gray = h->gclist; /* remove from 'gray' list */ - size = traversetable(g, h); - break; - } - case LUA_TLCL: { - LClosure *cl = gco2lcl(o); - g->gray = cl->gclist; /* remove from 'gray' list */ - size = traverseLclosure(g, cl); - break; - } - case LUA_TCCL: { - CClosure *cl = gco2ccl(o); - g->gray = cl->gclist; /* remove from 'gray' list */ - size = traverseCclosure(g, cl); - break; - } - case LUA_TTHREAD: { - lua_State *th = gco2th(o); - g->gray = th->gclist; /* remove from 'gray' list */ - th->gclist = g->grayagain; - g->grayagain = o; /* insert into 'grayagain' list */ - black2gray(o); - size = traversestack(g, th); - break; - } - case LUA_TPROTO: { - Proto *p = gco2p(o); - g->gray = p->gclist; /* remove from 'gray' list */ - size = traverseproto(g, p); - break; - } - default: lua_assert(0); return; - } - g->GCmemtrav += size; +static void propagatemark(global_State *g) +{ + lu_mem size; + GCObject *o = g->gray; + lua_assert(isgray(o)); + gray2black(o); + switch (gch(o)->tt) + { + case LUA_TTABLE: + { + Table *h = gco2t(o); + g->gray = h->gclist; /* remove from 'gray' list */ + size = traversetable(g, h); + break; + } + case LUA_TLCL: + { + LClosure *cl = gco2lcl(o); + g->gray = cl->gclist; /* remove from 'gray' list */ + size = traverseLclosure(g, cl); + break; + } + case LUA_TCCL: + { + CClosure *cl = gco2ccl(o); + g->gray = cl->gclist; /* remove from 'gray' list */ + size = traverseCclosure(g, cl); + break; + } + case LUA_TTHREAD: + { + lua_State *th = gco2th(o); + g->gray = th->gclist; /* remove from 'gray' list */ + th->gclist = g->grayagain; + g->grayagain = o; /* insert into 'grayagain' list */ + black2gray(o); + size = traversestack(g, th); + break; + } + case LUA_TPROTO: + { + Proto *p = gco2p(o); + g->gray = p->gclist; /* remove from 'gray' list */ + size = traverseproto(g, p); + break; + } + default: + lua_assert(0); + return; + } + g->GCmemtrav += size; } - -static void propagateall (global_State *g) { - while (g->gray) propagatemark(g); +static void propagateall(global_State *g) +{ + while (g->gray) propagatemark(g); } - -static void propagatelist (global_State *g, GCObject *l) { - lua_assert(g->gray == NULL); /* no grays left */ - g->gray = l; - propagateall(g); /* traverse all elements from 'l' */ +static void propagatelist(global_State *g, GCObject *l) +{ + lua_assert(g->gray == NULL); /* no grays left */ + g->gray = l; + propagateall(g); /* traverse all elements from 'l' */ } /* @@ -579,132 +615,155 @@ static void propagatelist (global_State *g, GCObject *l) { ** lists when traversed, traverse the original lists to avoid traversing ** twice the same table (which is not wrong, but inefficient) */ -static void retraversegrays (global_State *g) { - GCObject *weak = g->weak; /* save original lists */ - GCObject *grayagain = g->grayagain; - GCObject *ephemeron = g->ephemeron; - g->weak = g->grayagain = g->ephemeron = NULL; - propagateall(g); /* traverse main gray list */ - propagatelist(g, grayagain); - propagatelist(g, weak); - propagatelist(g, ephemeron); +static void retraversegrays(global_State *g) +{ + GCObject *weak = g->weak; /* save original lists */ + GCObject *grayagain = g->grayagain; + GCObject *ephemeron = g->ephemeron; + g->weak = g->grayagain = g->ephemeron = NULL; + propagateall(g); /* traverse main gray list */ + propagatelist(g, grayagain); + propagatelist(g, weak); + propagatelist(g, ephemeron); } - -static void convergeephemerons (global_State *g) { - int changed; - do { - GCObject *w; - GCObject *next = g->ephemeron; /* get ephemeron list */ - g->ephemeron = NULL; /* tables will return to this list when traversed */ - changed = 0; - while ((w = next) != NULL) { - next = gco2t(w)->gclist; - if (traverseephemeron(g, gco2t(w))) { /* traverse marked some value? */ - propagateall(g); /* propagate changes */ - changed = 1; /* will have to revisit all ephemeron tables */ - } - } - } while (changed); +static void convergeephemerons(global_State *g) +{ + int changed; + do + { + GCObject *w; + GCObject *next = g->ephemeron; /* get ephemeron list */ + g->ephemeron = NULL; /* tables will return to this list when traversed */ + changed = 0; + while ((w = next) != NULL) + { + next = gco2t(w)->gclist; + if (traverseephemeron(g, gco2t(w))) + { /* traverse marked some value? */ + propagateall(g); /* propagate changes */ + changed = 1; /* will have to revisit all ephemeron tables */ + } + } + } while (changed); } /* }====================================================== */ - /* ** {====================================================== ** Sweep Functions ** ======================================================= */ - /* ** clear entries with unmarked keys from all weaktables in list 'l' up ** to element 'f' */ -static void clearkeys (global_State *g, GCObject *l, GCObject *f) { - for (; l != f; l = gco2t(l)->gclist) { - Table *h = gco2t(l); - Node *n, *limit = gnodelast(h); - for (n = gnode(h, 0); n < limit; n++) { - if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) { - setnilvalue(gval(n)); /* remove value ... */ - removeentry(n); /* and remove entry from table */ - } - } - } +static void clearkeys(global_State *g, GCObject *l, GCObject *f) +{ + for (; l != f; l = gco2t(l)->gclist) + { + Table *h = gco2t(l); + Node *n, *limit = gnodelast(h); + for (n = gnode(h, 0); n < limit; n++) + { + if (!ttisnil(gval(n)) && (iscleared(g, gkey(n)))) + { + setnilvalue(gval(n)); /* remove value ... */ + removeentry(n); /* and remove entry from table */ + } + } + } } - /* ** clear entries with unmarked values from all weaktables in list 'l' up ** to element 'f' */ -static void clearvalues (global_State *g, GCObject *l, GCObject *f) { - for (; l != f; l = gco2t(l)->gclist) { - Table *h = gco2t(l); - Node *n, *limit = gnodelast(h); - int i; - for (i = 0; i < h->sizearray; i++) { - TValue *o = &h->array[i]; - if (iscleared(g, o)) /* value was collected? */ - setnilvalue(o); /* remove value */ - } - for (n = gnode(h, 0); n < limit; n++) { - if (!ttisnil(gval(n)) && iscleared(g, gval(n))) { - setnilvalue(gval(n)); /* remove value ... */ - removeentry(n); /* and remove entry from table */ - } - } - } +static void clearvalues(global_State *g, GCObject *l, GCObject *f) +{ + for (; l != f; l = gco2t(l)->gclist) + { + Table *h = gco2t(l); + Node *n, *limit = gnodelast(h); + int i; + for (i = 0; i < h->sizearray; i++) + { + TValue *o = &h->array[i]; + if (iscleared(g, o)) /* value was collected? */ + setnilvalue(o); /* remove value */ + } + for (n = gnode(h, 0); n < limit; n++) + { + if (!ttisnil(gval(n)) && iscleared(g, gval(n))) + { + setnilvalue(gval(n)); /* remove value ... */ + removeentry(n); /* and remove entry from table */ + } + } + } } - -static void freeobj (lua_State *L, GCObject *o) { - switch (gch(o)->tt) { - case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; - case LUA_TLCL: { - luaM_freemem(L, o, sizeLclosure(gco2lcl(o)->nupvalues)); - break; - } - case LUA_TCCL: { - luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues)); - break; - } - case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; - case LUA_TTABLE: luaH_free(L, gco2t(o)); break; - case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break; - case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break; - case LUA_TSHRSTR: - G(L)->strt.nuse--; - /* go through */ - case LUA_TLNGSTR: { - luaM_freemem(L, o, sizestring(gco2ts(o))); - break; - } - default: lua_assert(0); - } +static void freeobj(lua_State *L, GCObject *o) +{ + switch (gch(o)->tt) + { + case LUA_TPROTO: + luaF_freeproto(L, gco2p(o)); + break; + case LUA_TLCL: + { + luaM_freemem(L, o, sizeLclosure(gco2lcl(o)->nupvalues)); + break; + } + case LUA_TCCL: + { + luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues)); + break; + } + case LUA_TUPVAL: + luaF_freeupval(L, gco2uv(o)); + break; + case LUA_TTABLE: + luaH_free(L, gco2t(o)); + break; + case LUA_TTHREAD: + luaE_freethread(L, gco2th(o)); + break; + case LUA_TUSERDATA: + luaM_freemem(L, o, sizeudata(gco2u(o))); + break; + case LUA_TSHRSTR: + G(L)->strt.nuse--; + /* go through */ + case LUA_TLNGSTR: + { + luaM_freemem(L, o, sizestring(gco2ts(o))); + break; + } + default: + lua_assert(0); + } } - -#define sweepwholelist(L,p) sweeplist(L,p,MAX_LUMEM) -static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count); - +#define sweepwholelist(L, p) sweeplist(L, p, MAX_LUMEM) +static GCObject **sweeplist(lua_State *L, GCObject **p, lu_mem count); /* ** sweep the (open) upvalues of a thread and resize its stack and ** list of call-info structures. */ -static void sweepthread (lua_State *L, lua_State *L1) { - if (L1->stack == NULL) return; /* stack not completely built yet */ - sweepwholelist(L, &L1->openupval); /* sweep open upvalues */ - luaE_freeCI(L1); /* free extra CallInfo slots */ - /* should not change the stack during an emergency gc cycle */ - if (G(L)->gckind != KGC_EMERGENCY) - luaD_shrinkstack(L1); +static void sweepthread(lua_State *L, lua_State *L1) +{ + if (L1->stack == NULL) return; /* stack not completely built yet */ + sweepwholelist(L, &L1->openupval); /* sweep open upvalues */ + luaE_freeCI(L1); /* free extra CallInfo slots */ + /* should not change the stack during an emergency gc cycle */ + if (G(L)->gckind != KGC_EMERGENCY) + luaD_shrinkstack(L1); } - /* ** sweep at most 'count' elements from a list of GCObjects erasing dead ** objects, where a dead (not alive) object is one marked with the "old" @@ -716,215 +775,229 @@ static void sweepthread (lua_State *L, lua_State *L1) { ** one will be old too. ** When object is a thread, sweep its list of open upvalues too. */ -static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { - global_State *g = G(L); - int ow = otherwhite(g); - int toclear, toset; /* bits to clear and to set in all live objects */ - int tostop; /* stop sweep when this is true */ - if (isgenerational(g)) { /* generational mode? */ - toclear = ~0; /* clear nothing */ - toset = bitmask(OLDBIT); /* set the old bit of all surviving objects */ - tostop = bitmask(OLDBIT); /* do not sweep old generation */ - } - else { /* normal mode */ - toclear = maskcolors; /* clear all color bits + old bit */ - toset = luaC_white(g); /* make object white */ - tostop = 0; /* do not stop */ - } - while (*p != NULL && count-- > 0) { - GCObject *curr = *p; - int marked = gch(curr)->marked; - if (isdeadm(ow, marked)) { /* is 'curr' dead? */ - *p = gch(curr)->next; /* remove 'curr' from list */ - freeobj(L, curr); /* erase 'curr' */ - } - else { - if (testbits(marked, tostop)) - return NULL; /* stop sweeping this list */ - if (gch(curr)->tt == LUA_TTHREAD) - sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */ - /* update marks */ - gch(curr)->marked = cast_byte((marked & toclear) | toset); - p = &gch(curr)->next; /* go to next element */ - } - } - return (*p == NULL) ? NULL : p; +static GCObject **sweeplist(lua_State *L, GCObject **p, lu_mem count) +{ + global_State *g = G(L); + int ow = otherwhite(g); + int toclear, toset; /* bits to clear and to set in all live objects */ + int tostop; /* stop sweep when this is true */ + if (isgenerational(g)) + { /* generational mode? */ + toclear = ~0; /* clear nothing */ + toset = bitmask(OLDBIT); /* set the old bit of all surviving objects */ + tostop = bitmask(OLDBIT); /* do not sweep old generation */ + } + else + { /* normal mode */ + toclear = maskcolors; /* clear all color bits + old bit */ + toset = luaC_white(g); /* make object white */ + tostop = 0; /* do not stop */ + } + while (*p != NULL && count-- > 0) + { + GCObject *curr = *p; + int marked = gch(curr)->marked; + if (isdeadm(ow, marked)) + { /* is 'curr' dead? */ + *p = gch(curr)->next; /* remove 'curr' from list */ + freeobj(L, curr); /* erase 'curr' */ + } + else + { + if (testbits(marked, tostop)) + return NULL; /* stop sweeping this list */ + if (gch(curr)->tt == LUA_TTHREAD) + sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */ + /* update marks */ + gch(curr)->marked = cast_byte((marked & toclear) | toset); + p = &gch(curr)->next; /* go to next element */ + } + } + return (*p == NULL) ? NULL : p; } - /* ** sweep a list until a live object (or end of list) */ -static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) { - GCObject ** old = p; - int i = 0; - do { - i++; - p = sweeplist(L, p, 1); - } while (p == old); - if (n) *n += i; - return p; +static GCObject **sweeptolive(lua_State *L, GCObject **p, int *n) +{ + GCObject **old = p; + int i = 0; + do + { + i++; + p = sweeplist(L, p, 1); + } while (p == old); + if (n) *n += i; + return p; } /* }====================================================== */ - /* ** {====================================================== ** Finalization ** ======================================================= */ -static void checkSizes (lua_State *L) { - global_State *g = G(L); - if (g->gckind != KGC_EMERGENCY) { /* do not change sizes in emergency */ - int hs = g->strt.size / 2; /* half the size of the string table */ - if (g->strt.nuse < cast(lu_int32, hs)) /* using less than that half? */ - luaS_resize(L, hs); /* halve its size */ - luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */ - } +static void checkSizes(lua_State *L) +{ + global_State *g = G(L); + if (g->gckind != KGC_EMERGENCY) + { /* do not change sizes in emergency */ + int hs = g->strt.size / 2; /* half the size of the string table */ + if (g->strt.nuse < cast(lu_int32, hs)) /* using less than that half? */ + luaS_resize(L, hs); /* halve its size */ + luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */ + } } - -static GCObject *udata2finalize (global_State *g) { - GCObject *o = g->tobefnz; /* get first element */ - lua_assert(isfinalized(o)); - g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */ - gch(o)->next = g->allgc; /* return it to 'allgc' list */ - g->allgc = o; - resetbit(gch(o)->marked, SEPARATED); /* mark that it is not in 'tobefnz' */ - lua_assert(!isold(o)); /* see MOVE OLD rule */ - if (!keepinvariantout(g)) /* not keeping invariant? */ - makewhite(g, o); /* "sweep" object */ - return o; +static GCObject *udata2finalize(global_State *g) +{ + GCObject *o = g->tobefnz; /* get first element */ + lua_assert(isfinalized(o)); + g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */ + gch(o)->next = g->allgc; /* return it to 'allgc' list */ + g->allgc = o; + resetbit(gch(o)->marked, SEPARATED); /* mark that it is not in 'tobefnz' */ + lua_assert(!isold(o)); /* see MOVE OLD rule */ + if (!keepinvariantout(g)) /* not keeping invariant? */ + makewhite(g, o); /* "sweep" object */ + return o; } - -static void dothecall (lua_State *L, void *ud) { - UNUSED(ud); - luaD_call(L, L->top - 2, 0, 0); +static void dothecall(lua_State *L, void *ud) +{ + UNUSED(ud); + luaD_call(L, L->top - 2, 0, 0); } - -static void GCTM (lua_State *L, int propagateerrors) { - global_State *g = G(L); - const TValue *tm; - TValue v; - setgcovalue(L, &v, udata2finalize(g)); - tm = luaT_gettmbyobj(L, &v, TM_GC); - if (tm != NULL && ttisfunction(tm)) { /* is there a finalizer? */ - int status; - lu_byte oldah = L->allowhook; - int running = g->gcrunning; - L->allowhook = 0; /* stop debug hooks during GC metamethod */ - g->gcrunning = 0; /* avoid GC steps */ - setobj2s(L, L->top, tm); /* push finalizer... */ - setobj2s(L, L->top + 1, &v); /* ... and its argument */ - L->top += 2; /* and (next line) call the finalizer */ - status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); - L->allowhook = oldah; /* restore hooks */ - g->gcrunning = running; /* restore state */ - if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ - if (status == LUA_ERRRUN) { /* is there an error object? */ - const char *msg = (ttisstring(L->top - 1)) - ? svalue(L->top - 1) - : "no message"; - luaO_pushfstring(L, "error in __gc metamethod (%s)", msg); - status = LUA_ERRGCMM; /* error in __gc metamethod */ - } - luaD_throw(L, status); /* re-throw error */ - } - } +static void GCTM(lua_State *L, int propagateerrors) +{ + global_State *g = G(L); + const TValue *tm; + TValue v; + setgcovalue(L, &v, udata2finalize(g)); + tm = luaT_gettmbyobj(L, &v, TM_GC); + if (tm != NULL && ttisfunction(tm)) + { /* is there a finalizer? */ + int status; + lu_byte oldah = L->allowhook; + int running = g->gcrunning; + L->allowhook = 0; /* stop debug hooks during GC metamethod */ + g->gcrunning = 0; /* avoid GC steps */ + setobj2s(L, L->top, tm); /* push finalizer... */ + setobj2s(L, L->top + 1, &v); /* ... and its argument */ + L->top += 2; /* and (next line) call the finalizer */ + status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); + L->allowhook = oldah; /* restore hooks */ + g->gcrunning = running; /* restore state */ + if (status != LUA_OK && propagateerrors) + { /* error while running __gc? */ + if (status == LUA_ERRRUN) + { /* is there an error object? */ + const char *msg = (ttisstring(L->top - 1)) + ? svalue(L->top - 1) + : "no message"; + luaO_pushfstring(L, "error in __gc metamethod (%s)", msg); + status = LUA_ERRGCMM; /* error in __gc metamethod */ + } + luaD_throw(L, status); /* re-throw error */ + } + } } - /* ** move all unreachable objects (or 'all' objects) that need ** finalization from list 'finobj' to list 'tobefnz' (to be finalized) */ -static void separatetobefnz (lua_State *L, int all) { - global_State *g = G(L); - GCObject **p = &g->finobj; - GCObject *curr; - GCObject **lastnext = &g->tobefnz; - /* find last 'next' field in 'tobefnz' list (to add elements in its end) */ - while (*lastnext != NULL) - lastnext = &gch(*lastnext)->next; - while ((curr = *p) != NULL) { /* traverse all finalizable objects */ - lua_assert(!isfinalized(curr)); - lua_assert(testbit(gch(curr)->marked, SEPARATED)); - if (!(iswhite(curr) || all)) /* not being collected? */ - p = &gch(curr)->next; /* don't bother with it */ - else { - l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ - *p = gch(curr)->next; /* remove 'curr' from 'finobj' list */ - gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */ - *lastnext = curr; - lastnext = &gch(curr)->next; - } - } +static void separatetobefnz(lua_State *L, int all) +{ + global_State *g = G(L); + GCObject **p = &g->finobj; + GCObject *curr; + GCObject **lastnext = &g->tobefnz; + /* find last 'next' field in 'tobefnz' list (to add elements in its end) */ + while (*lastnext != NULL) + lastnext = &gch(*lastnext)->next; + while ((curr = *p) != NULL) + { /* traverse all finalizable objects */ + lua_assert(!isfinalized(curr)); + lua_assert(testbit(gch(curr)->marked, SEPARATED)); + if (!(iswhite(curr) || all)) /* not being collected? */ + p = &gch(curr)->next; /* don't bother with it */ + else + { + l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */ + *p = gch(curr)->next; /* remove 'curr' from 'finobj' list */ + gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */ + *lastnext = curr; + lastnext = &gch(curr)->next; + } + } } - /* ** if object 'o' has a finalizer, remove it from 'allgc' list (must ** search the list to find it) and link it in 'finobj' list. */ -void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { - global_State *g = G(L); - if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */ - isfinalized(o) || /* ... or is finalized... */ - gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ - return; /* nothing to be done */ - else { /* move 'o' to 'finobj' list */ - GCObject **p; - GCheader *ho = gch(o); - if (g->sweepgc == &ho->next) { /* avoid removing current sweep object */ - lua_assert(issweepphase(g)); - g->sweepgc = sweeptolive(L, g->sweepgc, NULL); - } - /* search for pointer pointing to 'o' */ - for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ } - *p = ho->next; /* remove 'o' from root list */ - ho->next = g->finobj; /* link it in list 'finobj' */ - g->finobj = o; - l_setbit(ho->marked, SEPARATED); /* mark it as such */ - if (!keepinvariantout(g)) /* not keeping invariant? */ - makewhite(g, o); /* "sweep" object */ - else - resetoldbit(o); /* see MOVE OLD rule */ - } +void luaC_checkfinalizer(lua_State *L, GCObject *o, Table *mt) +{ + global_State *g = G(L); + if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */ + isfinalized(o) || /* ... or is finalized... */ + gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ + return; /* nothing to be done */ + else + { /* move 'o' to 'finobj' list */ + GCObject **p; + GCheader *ho = gch(o); + if (g->sweepgc == &ho->next) + { /* avoid removing current sweep object */ + lua_assert(issweepphase(g)); + g->sweepgc = sweeptolive(L, g->sweepgc, NULL); + } + /* search for pointer pointing to 'o' */ + for (p = &g->allgc; *p != o; p = &gch(*p)->next) + { /* empty */ + } + *p = ho->next; /* remove 'o' from root list */ + ho->next = g->finobj; /* link it in list 'finobj' */ + g->finobj = o; + l_setbit(ho->marked, SEPARATED); /* mark it as such */ + if (!keepinvariantout(g)) /* not keeping invariant? */ + makewhite(g, o); /* "sweep" object */ + else + resetoldbit(o); /* see MOVE OLD rule */ + } } /* }====================================================== */ - /* ** {====================================================== ** GC control ** ======================================================= */ - /* ** set a reasonable "time" to wait before starting a new GC cycle; ** cycle will start when memory use hits threshold */ -static void setpause (global_State *g, l_mem estimate) { - l_mem debt, threshold; - estimate = estimate / PAUSEADJ; /* adjust 'estimate' */ - threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */ - ? estimate * g->gcpause /* no overflow */ - : MAX_LMEM; /* overflow; truncate to maximum */ - debt = -cast(l_mem, threshold - gettotalbytes(g)); - luaE_setdebt(g, debt); +static void setpause(global_State *g, l_mem estimate) +{ + l_mem debt, threshold; + estimate = estimate / PAUSEADJ; /* adjust 'estimate' */ + threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */ + ? estimate * g->gcpause /* no overflow */ + : MAX_LMEM; /* overflow; truncate to maximum */ + debt = -cast(l_mem, threshold - gettotalbytes(g)); + luaE_setdebt(g, debt); } - -#define sweepphases \ +#define sweepphases \ (bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep)) - /* ** enter first sweep phase (strings) and prepare pointers for other ** sweep phases. The calls to 'sweeptolive' make pointers point to an @@ -933,288 +1006,315 @@ static void setpause (global_State *g, l_mem estimate) { ** of the real sweep. ** Returns how many objects it swept. */ -static int entersweep (lua_State *L) { - global_State *g = G(L); - int n = 0; - g->gcstate = GCSsweepstring; - lua_assert(g->sweepgc == NULL && g->sweepfin == NULL); - /* prepare to sweep strings, finalizable objects, and regular objects */ - g->sweepstrgc = 0; - g->sweepfin = sweeptolive(L, &g->finobj, &n); - g->sweepgc = sweeptolive(L, &g->allgc, &n); - return n; +static int entersweep(lua_State *L) +{ + global_State *g = G(L); + int n = 0; + g->gcstate = GCSsweepstring; + lua_assert(g->sweepgc == NULL && g->sweepfin == NULL); + /* prepare to sweep strings, finalizable objects, and regular objects */ + g->sweepstrgc = 0; + g->sweepfin = sweeptolive(L, &g->finobj, &n); + g->sweepgc = sweeptolive(L, &g->allgc, &n); + return n; } - /* ** change GC mode */ -void luaC_changemode (lua_State *L, int mode) { - global_State *g = G(L); - if (mode == g->gckind) return; /* nothing to change */ - if (mode == KGC_GEN) { /* change to generational mode */ - /* make sure gray lists are consistent */ - luaC_runtilstate(L, bitmask(GCSpropagate)); - g->GCestimate = gettotalbytes(g); - g->gckind = KGC_GEN; - } - else { /* change to incremental mode */ - /* sweep all objects to turn them back to white +void luaC_changemode(lua_State *L, int mode) +{ + global_State *g = G(L); + if (mode == g->gckind) return; /* nothing to change */ + if (mode == KGC_GEN) + { /* change to generational mode */ + /* make sure gray lists are consistent */ + luaC_runtilstate(L, bitmask(GCSpropagate)); + g->GCestimate = gettotalbytes(g); + g->gckind = KGC_GEN; + } + else + { /* change to incremental mode */ + /* sweep all objects to turn them back to white (as white has not changed, nothing extra will be collected) */ - g->gckind = KGC_NORMAL; - entersweep(L); - luaC_runtilstate(L, ~sweepphases); - } + g->gckind = KGC_NORMAL; + entersweep(L); + luaC_runtilstate(L, ~sweepphases); + } } - /* ** call all pending finalizers */ -static void callallpendingfinalizers (lua_State *L, int propagateerrors) { - global_State *g = G(L); - while (g->tobefnz) { - resetoldbit(g->tobefnz); - GCTM(L, propagateerrors); - } +static void callallpendingfinalizers(lua_State *L, int propagateerrors) +{ + global_State *g = G(L); + while (g->tobefnz) + { + resetoldbit(g->tobefnz); + GCTM(L, propagateerrors); + } } - -void luaC_freeallobjects (lua_State *L) { - global_State *g = G(L); - int i; - separatetobefnz(L, 1); /* separate all objects with finalizers */ - lua_assert(g->finobj == NULL); - callallpendingfinalizers(L, 0); - g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */ - g->gckind = KGC_NORMAL; - sweepwholelist(L, &g->finobj); /* finalizers can create objs. in 'finobj' */ - sweepwholelist(L, &g->allgc); - for (i = 0; i < g->strt.size; i++) /* free all string lists */ - sweepwholelist(L, &g->strt.hash[i]); - lua_assert(g->strt.nuse == 0); +void luaC_freeallobjects(lua_State *L) +{ + global_State *g = G(L); + int i; + separatetobefnz(L, 1); /* separate all objects with finalizers */ + lua_assert(g->finobj == NULL); + callallpendingfinalizers(L, 0); + g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */ + g->gckind = KGC_NORMAL; + sweepwholelist(L, &g->finobj); /* finalizers can create objs. in 'finobj' */ + sweepwholelist(L, &g->allgc); + for (i = 0; i < g->strt.size; i++) /* free all string lists */ + sweepwholelist(L, &g->strt.hash[i]); + lua_assert(g->strt.nuse == 0); } - -static l_mem atomic (lua_State *L) { - global_State *g = G(L); - l_mem work = -cast(l_mem, g->GCmemtrav); /* start counting work */ - GCObject *origweak, *origall; - lua_assert(!iswhite(obj2gco(g->mainthread))); - markobject(g, L); /* mark running thread */ - /* registry and global metatables may be changed by API */ - markvalue(g, &g->l_registry); - markmt(g); /* mark basic metatables */ - /* remark occasional upvalues of (maybe) dead threads */ - remarkupvals(g); - propagateall(g); /* propagate changes */ - work += g->GCmemtrav; /* stop counting (do not (re)count grays) */ - /* traverse objects caught by write barrier and by 'remarkupvals' */ - retraversegrays(g); - work -= g->GCmemtrav; /* restart counting */ - convergeephemerons(g); - /* at this point, all strongly accessible objects are marked. */ - /* clear values from weak tables, before checking finalizers */ - clearvalues(g, g->weak, NULL); - clearvalues(g, g->allweak, NULL); - origweak = g->weak; origall = g->allweak; - work += g->GCmemtrav; /* stop counting (objects being finalized) */ - separatetobefnz(L, 0); /* separate objects to be finalized */ - markbeingfnz(g); /* mark objects that will be finalized */ - propagateall(g); /* remark, to propagate `preserveness' */ - work -= g->GCmemtrav; /* restart counting */ - convergeephemerons(g); - /* at this point, all resurrected objects are marked. */ - /* remove dead objects from weak tables */ - clearkeys(g, g->ephemeron, NULL); /* clear keys from all ephemeron tables */ - clearkeys(g, g->allweak, NULL); /* clear keys from all allweak tables */ - /* clear values from resurrected weak tables */ - clearvalues(g, g->weak, origweak); - clearvalues(g, g->allweak, origall); - g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ - work += g->GCmemtrav; /* complete counting */ - return work; /* estimate of memory marked by 'atomic' */ +static l_mem atomic(lua_State *L) +{ + global_State *g = G(L); + l_mem work = -cast(l_mem, g->GCmemtrav); /* start counting work */ + GCObject *origweak, *origall; + lua_assert(!iswhite(obj2gco(g->mainthread))); + markobject(g, L); /* mark running thread */ + /* registry and global metatables may be changed by API */ + markvalue(g, &g->l_registry); + markmt(g); /* mark basic metatables */ + /* remark occasional upvalues of (maybe) dead threads */ + remarkupvals(g); + propagateall(g); /* propagate changes */ + work += g->GCmemtrav; /* stop counting (do not (re)count grays) */ + /* traverse objects caught by write barrier and by 'remarkupvals' */ + retraversegrays(g); + work -= g->GCmemtrav; /* restart counting */ + convergeephemerons(g); + /* at this point, all strongly accessible objects are marked. */ + /* clear values from weak tables, before checking finalizers */ + clearvalues(g, g->weak, NULL); + clearvalues(g, g->allweak, NULL); + origweak = g->weak; + origall = g->allweak; + work += g->GCmemtrav; /* stop counting (objects being finalized) */ + separatetobefnz(L, 0); /* separate objects to be finalized */ + markbeingfnz(g); /* mark objects that will be finalized */ + propagateall(g); /* remark, to propagate `preserveness' */ + work -= g->GCmemtrav; /* restart counting */ + convergeephemerons(g); + /* at this point, all resurrected objects are marked. */ + /* remove dead objects from weak tables */ + clearkeys(g, g->ephemeron, NULL); /* clear keys from all ephemeron tables */ + clearkeys(g, g->allweak, NULL); /* clear keys from all allweak tables */ + /* clear values from resurrected weak tables */ + clearvalues(g, g->weak, origweak); + clearvalues(g, g->allweak, origall); + g->currentwhite = cast_byte(otherwhite(g)); /* flip current white */ + work += g->GCmemtrav; /* complete counting */ + return work; /* estimate of memory marked by 'atomic' */ } - -static lu_mem singlestep (lua_State *L) { - global_State *g = G(L); - switch (g->gcstate) { - case GCSpause: { - /* start to count memory traversed */ - g->GCmemtrav = g->strt.size * sizeof(GCObject*); - lua_assert(!isgenerational(g)); - restartcollection(g); - g->gcstate = GCSpropagate; - return g->GCmemtrav; - } - case GCSpropagate: { - if (g->gray) { - lu_mem oldtrav = g->GCmemtrav; - propagatemark(g); - return g->GCmemtrav - oldtrav; /* memory traversed in this step */ - } - else { /* no more `gray' objects */ - lu_mem work; - int sw; - g->gcstate = GCSatomic; /* finish mark phase */ - g->GCestimate = g->GCmemtrav; /* save what was counted */; - work = atomic(L); /* add what was traversed by 'atomic' */ - g->GCestimate += work; /* estimate of total memory traversed */ - sw = entersweep(L); - return work + sw * GCSWEEPCOST; - } - } - case GCSsweepstring: { - int i; - for (i = 0; i < GCSWEEPMAX && g->sweepstrgc + i < g->strt.size; i++) - sweepwholelist(L, &g->strt.hash[g->sweepstrgc + i]); - g->sweepstrgc += i; - if (g->sweepstrgc >= g->strt.size) /* no more strings to sweep? */ - g->gcstate = GCSsweepudata; - return i * GCSWEEPCOST; - } - case GCSsweepudata: { - if (g->sweepfin) { - g->sweepfin = sweeplist(L, g->sweepfin, GCSWEEPMAX); - return GCSWEEPMAX*GCSWEEPCOST; - } - else { - g->gcstate = GCSsweep; - return 0; - } - } - case GCSsweep: { - if (g->sweepgc) { - g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); - return GCSWEEPMAX*GCSWEEPCOST; - } - else { - /* sweep main thread */ - GCObject *mt = obj2gco(g->mainthread); - sweeplist(L, &mt, 1); - checkSizes(L); - g->gcstate = GCSpause; /* finish collection */ - return GCSWEEPCOST; - } - } - default: lua_assert(0); return 0; - } +static lu_mem singlestep(lua_State *L) +{ + global_State *g = G(L); + switch (g->gcstate) + { + case GCSpause: + { + /* start to count memory traversed */ + g->GCmemtrav = g->strt.size * sizeof(GCObject *); + lua_assert(!isgenerational(g)); + restartcollection(g); + g->gcstate = GCSpropagate; + return g->GCmemtrav; + } + case GCSpropagate: + { + if (g->gray) + { + lu_mem oldtrav = g->GCmemtrav; + propagatemark(g); + return g->GCmemtrav - oldtrav; /* memory traversed in this step */ + } + else + { /* no more `gray' objects */ + lu_mem work; + int sw; + g->gcstate = GCSatomic; /* finish mark phase */ + g->GCestimate = g->GCmemtrav; /* save what was counted */ + ; + work = atomic(L); /* add what was traversed by 'atomic' */ + g->GCestimate += work; /* estimate of total memory traversed */ + sw = entersweep(L); + return work + sw * GCSWEEPCOST; + } + } + case GCSsweepstring: + { + int i; + for (i = 0; i < GCSWEEPMAX && g->sweepstrgc + i < g->strt.size; i++) + sweepwholelist(L, &g->strt.hash[g->sweepstrgc + i]); + g->sweepstrgc += i; + if (g->sweepstrgc >= g->strt.size) /* no more strings to sweep? */ + g->gcstate = GCSsweepudata; + return i * GCSWEEPCOST; + } + case GCSsweepudata: + { + if (g->sweepfin) + { + g->sweepfin = sweeplist(L, g->sweepfin, GCSWEEPMAX); + return GCSWEEPMAX * GCSWEEPCOST; + } + else + { + g->gcstate = GCSsweep; + return 0; + } + } + case GCSsweep: + { + if (g->sweepgc) + { + g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX); + return GCSWEEPMAX * GCSWEEPCOST; + } + else + { + /* sweep main thread */ + GCObject *mt = obj2gco(g->mainthread); + sweeplist(L, &mt, 1); + checkSizes(L); + g->gcstate = GCSpause; /* finish collection */ + return GCSWEEPCOST; + } + } + default: + lua_assert(0); + return 0; + } } - /* ** advances the garbage collector until it reaches a state allowed ** by 'statemask' */ -void luaC_runtilstate (lua_State *L, int statesmask) { - global_State *g = G(L); - while (!testbit(statesmask, g->gcstate)) - singlestep(L); +void luaC_runtilstate(lua_State *L, int statesmask) +{ + global_State *g = G(L); + while (!testbit(statesmask, g->gcstate)) + singlestep(L); } - -static void generationalcollection (lua_State *L) { - global_State *g = G(L); - lua_assert(g->gcstate == GCSpropagate); - if (g->GCestimate == 0) { /* signal for another major collection? */ - luaC_fullgc(L, 0); /* perform a full regular collection */ - g->GCestimate = gettotalbytes(g); /* update control */ - } - else { - lu_mem estimate = g->GCestimate; - luaC_runtilstate(L, bitmask(GCSpause)); /* run complete (minor) cycle */ - g->gcstate = GCSpropagate; /* skip restart */ - if (gettotalbytes(g) > (estimate / 100) * g->gcmajorinc) - g->GCestimate = 0; /* signal for a major collection */ - else - g->GCestimate = estimate; /* keep estimate from last major coll. */ - - } - setpause(g, gettotalbytes(g)); - lua_assert(g->gcstate == GCSpropagate); +static void generationalcollection(lua_State *L) +{ + global_State *g = G(L); + lua_assert(g->gcstate == GCSpropagate); + if (g->GCestimate == 0) + { /* signal for another major collection? */ + luaC_fullgc(L, 0); /* perform a full regular collection */ + g->GCestimate = gettotalbytes(g); /* update control */ + } + else + { + lu_mem estimate = g->GCestimate; + luaC_runtilstate(L, bitmask(GCSpause)); /* run complete (minor) cycle */ + g->gcstate = GCSpropagate; /* skip restart */ + if (gettotalbytes(g) > (estimate / 100) * g->gcmajorinc) + g->GCestimate = 0; /* signal for a major collection */ + else + g->GCestimate = estimate; /* keep estimate from last major coll. */ + } + setpause(g, gettotalbytes(g)); + lua_assert(g->gcstate == GCSpropagate); } - -static void incstep (lua_State *L) { - global_State *g = G(L); - l_mem debt = g->GCdebt; - int stepmul = g->gcstepmul; - if (stepmul < 40) stepmul = 40; /* avoid ridiculous low values (and 0) */ - /* convert debt from Kb to 'work units' (avoid zero debt and overflows) */ - debt = (debt / STEPMULADJ) + 1; - debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM; - do { /* always perform at least one single step */ - lu_mem work = singlestep(L); /* do some work */ - debt -= work; - } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause); - if (g->gcstate == GCSpause) - setpause(g, g->GCestimate); /* pause until next cycle */ - else { - debt = (debt / stepmul) * STEPMULADJ; /* convert 'work units' to Kb */ - luaE_setdebt(g, debt); - } +static void incstep(lua_State *L) +{ + global_State *g = G(L); + l_mem debt = g->GCdebt; + int stepmul = g->gcstepmul; + if (stepmul < 40) stepmul = 40; /* avoid ridiculous low values (and 0) */ + /* convert debt from Kb to 'work units' (avoid zero debt and overflows) */ + debt = (debt / STEPMULADJ) + 1; + debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM; + do + { /* always perform at least one single step */ + lu_mem work = singlestep(L); /* do some work */ + debt -= work; + } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause); + if (g->gcstate == GCSpause) + setpause(g, g->GCestimate); /* pause until next cycle */ + else + { + debt = (debt / stepmul) * STEPMULADJ; /* convert 'work units' to Kb */ + luaE_setdebt(g, debt); + } } - /* ** performs a basic GC step */ -void luaC_forcestep (lua_State *L) { - global_State *g = G(L); - int i; - if (isgenerational(g)) generationalcollection(L); - else incstep(L); - /* run a few finalizers (or all of them at the end of a collect cycle) */ - for (i = 0; g->tobefnz && (i < GCFINALIZENUM || g->gcstate == GCSpause); i++) - GCTM(L, 1); /* call one finalizer */ +void luaC_forcestep(lua_State *L) +{ + global_State *g = G(L); + int i; + if (isgenerational(g)) + generationalcollection(L); + else + incstep(L); + /* run a few finalizers (or all of them at the end of a collect cycle) */ + for (i = 0; g->tobefnz && (i < GCFINALIZENUM || g->gcstate == GCSpause); i++) + GCTM(L, 1); /* call one finalizer */ } - /* ** performs a basic GC step only if collector is running */ -void luaC_step (lua_State *L) { - global_State *g = G(L); - if (g->gcrunning) luaC_forcestep(L); - else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */ +void luaC_step(lua_State *L) +{ + global_State *g = G(L); + if (g->gcrunning) + luaC_forcestep(L); + else + luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */ } - - /* ** performs a full GC cycle; if "isemergency", does not call ** finalizers (which could change stack positions) */ -void luaC_fullgc (lua_State *L, int isemergency) { - global_State *g = G(L); - int origkind = g->gckind; - lua_assert(origkind != KGC_EMERGENCY); - if (isemergency) /* do not run finalizers during emergency GC */ - g->gckind = KGC_EMERGENCY; - else { - g->gckind = KGC_NORMAL; - callallpendingfinalizers(L, 1); - } - if (keepinvariant(g)) { /* may there be some black objects? */ - /* must sweep all objects to turn them back to white +void luaC_fullgc(lua_State *L, int isemergency) +{ + global_State *g = G(L); + int origkind = g->gckind; + lua_assert(origkind != KGC_EMERGENCY); + if (isemergency) /* do not run finalizers during emergency GC */ + g->gckind = KGC_EMERGENCY; + else + { + g->gckind = KGC_NORMAL; + callallpendingfinalizers(L, 1); + } + if (keepinvariant(g)) + { /* may there be some black objects? */ + /* must sweep all objects to turn them back to white (as white has not changed, nothing will be collected) */ - entersweep(L); - } - /* finish any pending sweep phase to start a new cycle */ - luaC_runtilstate(L, bitmask(GCSpause)); - luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */ - luaC_runtilstate(L, bitmask(GCSpause)); /* run entire collection */ - if (origkind == KGC_GEN) { /* generational mode? */ - /* generational mode must be kept in propagate phase */ - luaC_runtilstate(L, bitmask(GCSpropagate)); - } - g->gckind = origkind; - setpause(g, gettotalbytes(g)); - if (!isemergency) /* do not run finalizers during emergency GC */ - callallpendingfinalizers(L, 1); + entersweep(L); + } + /* finish any pending sweep phase to start a new cycle */ + luaC_runtilstate(L, bitmask(GCSpause)); + luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */ + luaC_runtilstate(L, bitmask(GCSpause)); /* run entire collection */ + if (origkind == KGC_GEN) + { /* generational mode? */ + /* generational mode must be kept in propagate phase */ + luaC_runtilstate(L, bitmask(GCSpropagate)); + } + g->gckind = origkind; + setpause(g, gettotalbytes(g)); + if (!isemergency) /* do not run finalizers during emergency GC */ + callallpendingfinalizers(L, 1); } /* }====================================================== */ - - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lgc.h b/examples/ThirdPartyLibs/lua-5.2.3/src/lgc.h index 84bb1cdf9..e2514f4e0 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lgc.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lgc.h @@ -7,7 +7,6 @@ #ifndef lgc_h #define lgc_h - #include "lobject.h" #include "lstate.h" @@ -24,30 +23,26 @@ ** is not being enforced (e.g., sweep phase). */ - - /* how much to allocate before next GC step */ #if !defined(GCSTEPSIZE) /* ~100 small strings */ -#define GCSTEPSIZE (cast_int(100 * sizeof(TString))) +#define GCSTEPSIZE (cast_int(100 * sizeof(TString))) #endif - /* ** Possible states of the Garbage Collector */ -#define GCSpropagate 0 -#define GCSatomic 1 -#define GCSsweepstring 2 -#define GCSsweepudata 3 -#define GCSsweep 4 -#define GCSpause 5 +#define GCSpropagate 0 +#define GCSatomic 1 +#define GCSsweepstring 2 +#define GCSsweepudata 3 +#define GCSsweep 4 +#define GCSpause 5 - -#define issweepphase(g) \ +#define issweepphase(g) \ (GCSsweepstring <= (g)->gcstate && (g)->gcstate <= GCSsweep) -#define isgenerational(g) ((g)->gckind == KGC_GEN) +#define isgenerational(g) ((g)->gckind == KGC_GEN) /* ** macros to tell when main invariant (white objects cannot point to black @@ -58,100 +53,112 @@ ** invariant must be kept all times. */ -#define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic) - +#define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic) /* ** Outside the collector, the state in generational mode is kept in ** 'propagate', so 'keepinvariant' is always true. */ -#define keepinvariantout(g) \ - check_exp(g->gcstate == GCSpropagate || !isgenerational(g), \ - g->gcstate <= GCSatomic) - +#define keepinvariantout(g) \ + check_exp(g->gcstate == GCSpropagate || !isgenerational(g), \ + g->gcstate <= GCSatomic) /* ** some useful bit tricks */ -#define resetbits(x,m) ((x) &= cast(lu_byte, ~(m))) -#define setbits(x,m) ((x) |= (m)) -#define testbits(x,m) ((x) & (m)) -#define bitmask(b) (1<<(b)) -#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) -#define l_setbit(x,b) setbits(x, bitmask(b)) -#define resetbit(x,b) resetbits(x, bitmask(b)) -#define testbit(x,b) testbits(x, bitmask(b)) - +#define resetbits(x, m) ((x) &= cast(lu_byte, ~(m))) +#define setbits(x, m) ((x) |= (m)) +#define testbits(x, m) ((x) & (m)) +#define bitmask(b) (1 << (b)) +#define bit2mask(b1, b2) (bitmask(b1) | bitmask(b2)) +#define l_setbit(x, b) setbits(x, bitmask(b)) +#define resetbit(x, b) resetbits(x, bitmask(b)) +#define testbit(x, b) testbits(x, bitmask(b)) /* Layout for bit use in `marked' field: */ -#define WHITE0BIT 0 /* object is white (type 0) */ -#define WHITE1BIT 1 /* object is white (type 1) */ -#define BLACKBIT 2 /* object is black */ -#define FINALIZEDBIT 3 /* object has been separated for finalization */ -#define SEPARATED 4 /* object is in 'finobj' list or in 'tobefnz' */ -#define FIXEDBIT 5 /* object is fixed (should not be collected) */ -#define OLDBIT 6 /* object is old (only in generational mode) */ +#define WHITE0BIT 0 /* object is white (type 0) */ +#define WHITE1BIT 1 /* object is white (type 1) */ +#define BLACKBIT 2 /* object is black */ +#define FINALIZEDBIT 3 /* object has been separated for finalization */ +#define SEPARATED 4 /* object is in 'finobj' list or in 'tobefnz' */ +#define FIXEDBIT 5 /* object is fixed (should not be collected) */ +#define OLDBIT 6 /* object is old (only in generational mode) */ /* bit 7 is currently used by tests (luaL_checkmemory) */ -#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) +#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) - -#define iswhite(x) testbits((x)->gch.marked, WHITEBITS) -#define isblack(x) testbit((x)->gch.marked, BLACKBIT) -#define isgray(x) /* neither white nor black */ \ +#define iswhite(x) testbits((x)->gch.marked, WHITEBITS) +#define isblack(x) testbit((x)->gch.marked, BLACKBIT) +#define isgray(x) /* neither white nor black */ \ (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT))) -#define isold(x) testbit((x)->gch.marked, OLDBIT) +#define isold(x) testbit((x)->gch.marked, OLDBIT) /* MOVE OLD rule: whenever an object is moved to the beginning of a GC list, its old bit must be cleared */ -#define resetoldbit(o) resetbit((o)->gch.marked, OLDBIT) +#define resetoldbit(o) resetbit((o)->gch.marked, OLDBIT) -#define otherwhite(g) (g->currentwhite ^ WHITEBITS) -#define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow))) -#define isdead(g,v) isdeadm(otherwhite(g), (v)->gch.marked) +#define otherwhite(g) (g->currentwhite ^ WHITEBITS) +#define isdeadm(ow, m) (!(((m) ^ WHITEBITS) & (ow))) +#define isdead(g, v) isdeadm(otherwhite(g), (v)->gch.marked) -#define changewhite(x) ((x)->gch.marked ^= WHITEBITS) -#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) +#define changewhite(x) ((x)->gch.marked ^= WHITEBITS) +#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) -#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) +#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x))) -#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) +#define luaC_white(g) cast(lu_byte, (g)->currentwhite &WHITEBITS) +#define luaC_condGC(L, c) \ + { \ + if (G(L)->GCdebt > 0) \ + { \ + c; \ + }; \ + condchangemem(L); \ + } +#define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);) -#define luaC_condGC(L,c) \ - {if (G(L)->GCdebt > 0) {c;}; condchangemem(L);} -#define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);) +#define luaC_barrier(L, p, v) \ + { \ + if (valiswhite(v) && isblack(obj2gco(p))) \ + luaC_barrier_(L, obj2gco(p), gcvalue(v)); \ + } +#define luaC_barrierback(L, p, v) \ + { \ + if (valiswhite(v) && isblack(obj2gco(p))) \ + luaC_barrierback_(L, p); \ + } -#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ - luaC_barrier_(L,obj2gco(p),gcvalue(v)); } +#define luaC_objbarrier(L, p, o) \ + { \ + if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ + luaC_barrier_(L, obj2gco(p), obj2gco(o)); \ + } -#define luaC_barrierback(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \ - luaC_barrierback_(L,p); } +#define luaC_objbarrierback(L, p, o) \ + { \ + if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) luaC_barrierback_(L, p); \ + } -#define luaC_objbarrier(L,p,o) \ - { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \ - luaC_barrier_(L,obj2gco(p),obj2gco(o)); } +#define luaC_barrierproto(L, p, c) \ + { \ + if (isblack(obj2gco(p))) luaC_barrierproto_(L, p, c); \ + } -#define luaC_objbarrierback(L,p,o) \ - { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) luaC_barrierback_(L,p); } - -#define luaC_barrierproto(L,p,c) \ - { if (isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); } - -LUAI_FUNC void luaC_freeallobjects (lua_State *L); -LUAI_FUNC void luaC_step (lua_State *L); -LUAI_FUNC void luaC_forcestep (lua_State *L); -LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); -LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); -LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, - GCObject **list, int offset); -LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); -LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); -LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c); -LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); -LUAI_FUNC void luaC_checkupvalcolor (global_State *g, UpVal *uv); -LUAI_FUNC void luaC_changemode (lua_State *L, int mode); +LUAI_FUNC void luaC_freeallobjects(lua_State *L); +LUAI_FUNC void luaC_step(lua_State *L); +LUAI_FUNC void luaC_forcestep(lua_State *L); +LUAI_FUNC void luaC_runtilstate(lua_State *L, int statesmask); +LUAI_FUNC void luaC_fullgc(lua_State *L, int isemergency); +LUAI_FUNC GCObject *luaC_newobj(lua_State *L, int tt, size_t sz, + GCObject **list, int offset); +LUAI_FUNC void luaC_barrier_(lua_State *L, GCObject *o, GCObject *v); +LUAI_FUNC void luaC_barrierback_(lua_State *L, GCObject *o); +LUAI_FUNC void luaC_barrierproto_(lua_State *L, Proto *p, Closure *c); +LUAI_FUNC void luaC_checkfinalizer(lua_State *L, GCObject *o, Table *mt); +LUAI_FUNC void luaC_checkupvalcolor(global_State *g, UpVal *uv); +LUAI_FUNC void luaC_changemode(lua_State *L, int mode); #endif diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/linit.c b/examples/ThirdPartyLibs/lua-5.2.3/src/linit.c index c1a383047..da47fe01a 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/linit.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/linit.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - /* ** If you embed Lua in your program and need to open the standard ** libraries, call luaL_openlibs in your program. If you need a @@ -12,7 +11,6 @@ ** it to suit your needs. */ - #define linit_c #define LUA_LIB @@ -21,47 +19,44 @@ #include "lualib.h" #include "lauxlib.h" - /* ** these libs are loaded by lua.c and are readily available to any Lua ** program */ static const luaL_Reg loadedlibs[] = { - {"_G", luaopen_base}, - {LUA_LOADLIBNAME, luaopen_package}, - {LUA_COLIBNAME, luaopen_coroutine}, - {LUA_TABLIBNAME, luaopen_table}, - {LUA_IOLIBNAME, luaopen_io}, - {LUA_OSLIBNAME, luaopen_os}, - {LUA_STRLIBNAME, luaopen_string}, - {LUA_BITLIBNAME, luaopen_bit32}, - {LUA_MATHLIBNAME, luaopen_math}, - {LUA_DBLIBNAME, luaopen_debug}, - {NULL, NULL} -}; - + {"_G", luaopen_base}, + {LUA_LOADLIBNAME, luaopen_package}, + {LUA_COLIBNAME, luaopen_coroutine}, + {LUA_TABLIBNAME, luaopen_table}, + {LUA_IOLIBNAME, luaopen_io}, + {LUA_OSLIBNAME, luaopen_os}, + {LUA_STRLIBNAME, luaopen_string}, + {LUA_BITLIBNAME, luaopen_bit32}, + {LUA_MATHLIBNAME, luaopen_math}, + {LUA_DBLIBNAME, luaopen_debug}, + {NULL, NULL}}; /* ** these libs are preloaded and must be required before used */ static const luaL_Reg preloadedlibs[] = { - {NULL, NULL} -}; + {NULL, NULL}}; - -LUALIB_API void luaL_openlibs (lua_State *L) { - const luaL_Reg *lib; - /* call open functions from 'loadedlibs' and set results to global table */ - for (lib = loadedlibs; lib->func; lib++) { - luaL_requiref(L, lib->name, lib->func, 1); - lua_pop(L, 1); /* remove lib */ - } - /* add open functions from 'preloadedlibs' into 'package.preload' table */ - luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); - for (lib = preloadedlibs; lib->func; lib++) { - lua_pushcfunction(L, lib->func); - lua_setfield(L, -2, lib->name); - } - lua_pop(L, 1); /* remove _PRELOAD table */ +LUALIB_API void luaL_openlibs(lua_State *L) +{ + const luaL_Reg *lib; + /* call open functions from 'loadedlibs' and set results to global table */ + for (lib = loadedlibs; lib->func; lib++) + { + luaL_requiref(L, lib->name, lib->func, 1); + lua_pop(L, 1); /* remove lib */ + } + /* add open functions from 'preloadedlibs' into 'package.preload' table */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); + for (lib = preloadedlibs; lib->func; lib++) + { + lua_pushcfunction(L, lib->func); + lua_setfield(L, -2, lib->name); + } + lua_pop(L, 1); /* remove _PRELOAD table */ } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/liolib.c b/examples/ThirdPartyLibs/lua-5.2.3/src/liolib.c index 2a4ec4aa3..d6b5e9a61 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/liolib.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/liolib.c @@ -4,17 +4,15 @@ ** See Copyright Notice in lua.h */ - /* ** This definition must come before the inclusion of 'stdio.h'; it ** should not affect non-POSIX systems */ #if !defined(_FILE_OFFSET_BITS) -#define _LARGEFILE_SOURCE 1 -#define _FILE_OFFSET_BITS 64 +#define _LARGEFILE_SOURCE 1 +#define _FILE_OFFSET_BITS 64 #endif - #include #include #include @@ -28,7 +26,6 @@ #include "lauxlib.h" #include "lualib.h" - #if !defined(lua_checkmode) /* @@ -36,11 +33,11 @@ ** Change this macro to accept other modes for 'fopen' besides ** the standard ones. */ -#define lua_checkmode(mode) \ - (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && \ - (*mode != '+' || ++mode) && /* skip if char is '+' */ \ - (*mode != 'b' || ++mode) && /* skip if char is 'b' */ \ - (*mode == '\0')) +#define lua_checkmode(mode) \ + (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && \ + (*mode != '+' || ++mode) && /* skip if char is '+' */ \ + (*mode != 'b' || ++mode) && /* skip if char is 'b' */ \ + (*mode == '\0')) #endif @@ -51,616 +48,628 @@ ** ======================================================= */ -#if !defined(lua_popen) /* { */ +#if !defined(lua_popen) /* { */ -#if defined(LUA_USE_POPEN) /* { */ +#if defined(LUA_USE_POPEN) /* { */ -#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m)) -#define lua_pclose(L,file) ((void)L, pclose(file)) +#define lua_popen(L, c, m) ((void)L, fflush(NULL), popen(c, m)) +#define lua_pclose(L, file) ((void)L, pclose(file)) -#elif defined(LUA_WIN) /* }{ */ +#elif defined(LUA_WIN) /* }{ */ -#define lua_popen(L,c,m) ((void)L, _popen(c,m)) -#define lua_pclose(L,file) ((void)L, _pclose(file)) +#define lua_popen(L, c, m) ((void)L, _popen(c, m)) +#define lua_pclose(L, file) ((void)L, _pclose(file)) +#else /* }{ */ -#else /* }{ */ +#define lua_popen(L, c, m) ((void)((void)c, m), \ + luaL_error(L, LUA_QL("popen") " not supported"), (FILE *)0) +#define lua_pclose(L, file) ((void)((void)L, file), -1) -#define lua_popen(L,c,m) ((void)((void)c, m), \ - luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0) -#define lua_pclose(L,file) ((void)((void)L, file), -1) +#endif /* } */ - -#endif /* } */ - -#endif /* } */ +#endif /* } */ /* }====================================================== */ - /* ** {====================================================== ** lua_fseek: configuration for longer offsets ** ======================================================= */ -#if !defined(lua_fseek) && !defined(LUA_ANSI) /* { */ +#if !defined(lua_fseek) && !defined(LUA_ANSI) /* { */ -#if defined(LUA_USE_POSIX) /* { */ +#if defined(LUA_USE_POSIX) /* { */ -#define l_fseek(f,o,w) fseeko(f,o,w) -#define l_ftell(f) ftello(f) -#define l_seeknum off_t +#define l_fseek(f, o, w) fseeko(f, o, w) +#define l_ftell(f) ftello(f) +#define l_seeknum off_t -#elif defined(LUA_WIN) && !defined(_CRTIMP_TYPEINFO) \ - && defined(_MSC_VER) && (_MSC_VER >= 1400) /* }{ */ +#elif defined(LUA_WIN) && !defined(_CRTIMP_TYPEINFO) && defined(_MSC_VER) && (_MSC_VER >= 1400) /* }{ */ /* Windows (but not DDK) and Visual C++ 2005 or higher */ -#define l_fseek(f,o,w) _fseeki64(f,o,w) -#define l_ftell(f) _ftelli64(f) -#define l_seeknum __int64 +#define l_fseek(f, o, w) _fseeki64(f, o, w) +#define l_ftell(f) _ftelli64(f) +#define l_seeknum __int64 -#endif /* } */ +#endif /* } */ -#endif /* } */ +#endif /* } */ - -#if !defined(l_fseek) /* default definitions */ -#define l_fseek(f,o,w) fseek(f,o,w) -#define l_ftell(f) ftell(f) -#define l_seeknum long +#if !defined(l_fseek) /* default definitions */ +#define l_fseek(f, o, w) fseek(f, o, w) +#define l_ftell(f) ftell(f) +#define l_seeknum long #endif /* }====================================================== */ - -#define IO_PREFIX "_IO_" -#define IO_INPUT (IO_PREFIX "input") -#define IO_OUTPUT (IO_PREFIX "output") - +#define IO_PREFIX "_IO_" +#define IO_INPUT (IO_PREFIX "input") +#define IO_OUTPUT (IO_PREFIX "output") typedef luaL_Stream LStream; +#define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE)) -#define tolstream(L) ((LStream *)luaL_checkudata(L, 1, LUA_FILEHANDLE)) +#define isclosed(p) ((p)->closef == NULL) -#define isclosed(p) ((p)->closef == NULL) - - -static int io_type (lua_State *L) { - LStream *p; - luaL_checkany(L, 1); - p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE); - if (p == NULL) - lua_pushnil(L); /* not a file */ - else if (isclosed(p)) - lua_pushliteral(L, "closed file"); - else - lua_pushliteral(L, "file"); - return 1; +static int io_type(lua_State *L) +{ + LStream *p; + luaL_checkany(L, 1); + p = (LStream *)luaL_testudata(L, 1, LUA_FILEHANDLE); + if (p == NULL) + lua_pushnil(L); /* not a file */ + else if (isclosed(p)) + lua_pushliteral(L, "closed file"); + else + lua_pushliteral(L, "file"); + return 1; } - -static int f_tostring (lua_State *L) { - LStream *p = tolstream(L); - if (isclosed(p)) - lua_pushliteral(L, "file (closed)"); - else - lua_pushfstring(L, "file (%p)", p->f); - return 1; +static int f_tostring(lua_State *L) +{ + LStream *p = tolstream(L); + if (isclosed(p)) + lua_pushliteral(L, "file (closed)"); + else + lua_pushfstring(L, "file (%p)", p->f); + return 1; } - -static FILE *tofile (lua_State *L) { - LStream *p = tolstream(L); - if (isclosed(p)) - luaL_error(L, "attempt to use a closed file"); - lua_assert(p->f); - return p->f; +static FILE *tofile(lua_State *L) +{ + LStream *p = tolstream(L); + if (isclosed(p)) + luaL_error(L, "attempt to use a closed file"); + lua_assert(p->f); + return p->f; } - /* ** When creating file handles, always creates a `closed' file handle ** before opening the actual file; so, if there is a memory error, the ** file is not left opened. */ -static LStream *newprefile (lua_State *L) { - LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream)); - p->closef = NULL; /* mark file handle as 'closed' */ - luaL_setmetatable(L, LUA_FILEHANDLE); - return p; +static LStream *newprefile(lua_State *L) +{ + LStream *p = (LStream *)lua_newuserdata(L, sizeof(LStream)); + p->closef = NULL; /* mark file handle as 'closed' */ + luaL_setmetatable(L, LUA_FILEHANDLE); + return p; } - -static int aux_close (lua_State *L) { - LStream *p = tolstream(L); - lua_CFunction cf = p->closef; - p->closef = NULL; /* mark stream as closed */ - return (*cf)(L); /* close it */ +static int aux_close(lua_State *L) +{ + LStream *p = tolstream(L); + lua_CFunction cf = p->closef; + p->closef = NULL; /* mark stream as closed */ + return (*cf)(L); /* close it */ } - -static int io_close (lua_State *L) { - if (lua_isnone(L, 1)) /* no argument? */ - lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */ - tofile(L); /* make sure argument is an open stream */ - return aux_close(L); +static int io_close(lua_State *L) +{ + if (lua_isnone(L, 1)) /* no argument? */ + lua_getfield(L, LUA_REGISTRYINDEX, IO_OUTPUT); /* use standard output */ + tofile(L); /* make sure argument is an open stream */ + return aux_close(L); } - -static int f_gc (lua_State *L) { - LStream *p = tolstream(L); - if (!isclosed(p) && p->f != NULL) - aux_close(L); /* ignore closed and incompletely open files */ - return 0; +static int f_gc(lua_State *L) +{ + LStream *p = tolstream(L); + if (!isclosed(p) && p->f != NULL) + aux_close(L); /* ignore closed and incompletely open files */ + return 0; } - /* ** function to close regular files */ -static int io_fclose (lua_State *L) { - LStream *p = tolstream(L); - int res = fclose(p->f); - return luaL_fileresult(L, (res == 0), NULL); +static int io_fclose(lua_State *L) +{ + LStream *p = tolstream(L); + int res = fclose(p->f); + return luaL_fileresult(L, (res == 0), NULL); } - -static LStream *newfile (lua_State *L) { - LStream *p = newprefile(L); - p->f = NULL; - p->closef = &io_fclose; - return p; +static LStream *newfile(lua_State *L) +{ + LStream *p = newprefile(L); + p->f = NULL; + p->closef = &io_fclose; + return p; } - -static void opencheck (lua_State *L, const char *fname, const char *mode) { - LStream *p = newfile(L); - p->f = fopen(fname, mode); - if (p->f == NULL) - luaL_error(L, "cannot open file " LUA_QS " (%s)", fname, strerror(errno)); +static void opencheck(lua_State *L, const char *fname, const char *mode) +{ + LStream *p = newfile(L); + p->f = fopen(fname, mode); + if (p->f == NULL) + luaL_error(L, "cannot open file " LUA_QS " (%s)", fname, strerror(errno)); } - -static int io_open (lua_State *L) { - const char *filename = luaL_checkstring(L, 1); - const char *mode = luaL_optstring(L, 2, "r"); - LStream *p = newfile(L); - const char *md = mode; /* to traverse/check mode */ - luaL_argcheck(L, lua_checkmode(md), 2, "invalid mode"); - p->f = fopen(filename, mode); - return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; +static int io_open(lua_State *L) +{ + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + LStream *p = newfile(L); + const char *md = mode; /* to traverse/check mode */ + luaL_argcheck(L, lua_checkmode(md), 2, "invalid mode"); + p->f = fopen(filename, mode); + return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; } - /* ** function to close 'popen' files */ -static int io_pclose (lua_State *L) { - LStream *p = tolstream(L); - return luaL_execresult(L, lua_pclose(L, p->f)); +static int io_pclose(lua_State *L) +{ + LStream *p = tolstream(L); + return luaL_execresult(L, lua_pclose(L, p->f)); } - -static int io_popen (lua_State *L) { - const char *filename = luaL_checkstring(L, 1); - const char *mode = luaL_optstring(L, 2, "r"); - LStream *p = newprefile(L); - p->f = lua_popen(L, filename, mode); - p->closef = &io_pclose; - return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; +static int io_popen(lua_State *L) +{ + const char *filename = luaL_checkstring(L, 1); + const char *mode = luaL_optstring(L, 2, "r"); + LStream *p = newprefile(L); + p->f = lua_popen(L, filename, mode); + p->closef = &io_pclose; + return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1; } - -static int io_tmpfile (lua_State *L) { - LStream *p = newfile(L); - p->f = tmpfile(); - return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1; +static int io_tmpfile(lua_State *L) +{ + LStream *p = newfile(L); + p->f = tmpfile(); + return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1; } - -static FILE *getiofile (lua_State *L, const char *findex) { - LStream *p; - lua_getfield(L, LUA_REGISTRYINDEX, findex); - p = (LStream *)lua_touserdata(L, -1); - if (isclosed(p)) - luaL_error(L, "standard %s file is closed", findex + strlen(IO_PREFIX)); - return p->f; +static FILE *getiofile(lua_State *L, const char *findex) +{ + LStream *p; + lua_getfield(L, LUA_REGISTRYINDEX, findex); + p = (LStream *)lua_touserdata(L, -1); + if (isclosed(p)) + luaL_error(L, "standard %s file is closed", findex + strlen(IO_PREFIX)); + return p->f; } - -static int g_iofile (lua_State *L, const char *f, const char *mode) { - if (!lua_isnoneornil(L, 1)) { - const char *filename = lua_tostring(L, 1); - if (filename) - opencheck(L, filename, mode); - else { - tofile(L); /* check that it's a valid file handle */ - lua_pushvalue(L, 1); - } - lua_setfield(L, LUA_REGISTRYINDEX, f); - } - /* return current value */ - lua_getfield(L, LUA_REGISTRYINDEX, f); - return 1; +static int g_iofile(lua_State *L, const char *f, const char *mode) +{ + if (!lua_isnoneornil(L, 1)) + { + const char *filename = lua_tostring(L, 1); + if (filename) + opencheck(L, filename, mode); + else + { + tofile(L); /* check that it's a valid file handle */ + lua_pushvalue(L, 1); + } + lua_setfield(L, LUA_REGISTRYINDEX, f); + } + /* return current value */ + lua_getfield(L, LUA_REGISTRYINDEX, f); + return 1; } - -static int io_input (lua_State *L) { - return g_iofile(L, IO_INPUT, "r"); +static int io_input(lua_State *L) +{ + return g_iofile(L, IO_INPUT, "r"); } - -static int io_output (lua_State *L) { - return g_iofile(L, IO_OUTPUT, "w"); +static int io_output(lua_State *L) +{ + return g_iofile(L, IO_OUTPUT, "w"); } +static int io_readline(lua_State *L); -static int io_readline (lua_State *L); - - -static void aux_lines (lua_State *L, int toclose) { - int i; - int n = lua_gettop(L) - 1; /* number of arguments to read */ - /* ensure that arguments will fit here and into 'io_readline' stack */ - luaL_argcheck(L, n <= LUA_MINSTACK - 3, LUA_MINSTACK - 3, "too many options"); - lua_pushvalue(L, 1); /* file handle */ - lua_pushinteger(L, n); /* number of arguments to read */ - lua_pushboolean(L, toclose); /* close/not close file when finished */ - for (i = 1; i <= n; i++) lua_pushvalue(L, i + 1); /* copy arguments */ - lua_pushcclosure(L, io_readline, 3 + n); +static void aux_lines(lua_State *L, int toclose) +{ + int i; + int n = lua_gettop(L) - 1; /* number of arguments to read */ + /* ensure that arguments will fit here and into 'io_readline' stack */ + luaL_argcheck(L, n <= LUA_MINSTACK - 3, LUA_MINSTACK - 3, "too many options"); + lua_pushvalue(L, 1); /* file handle */ + lua_pushinteger(L, n); /* number of arguments to read */ + lua_pushboolean(L, toclose); /* close/not close file when finished */ + for (i = 1; i <= n; i++) lua_pushvalue(L, i + 1); /* copy arguments */ + lua_pushcclosure(L, io_readline, 3 + n); } - -static int f_lines (lua_State *L) { - tofile(L); /* check that it's a valid file handle */ - aux_lines(L, 0); - return 1; +static int f_lines(lua_State *L) +{ + tofile(L); /* check that it's a valid file handle */ + aux_lines(L, 0); + return 1; } - -static int io_lines (lua_State *L) { - int toclose; - if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ - if (lua_isnil(L, 1)) { /* no file name? */ - lua_getfield(L, LUA_REGISTRYINDEX, IO_INPUT); /* get default input */ - lua_replace(L, 1); /* put it at index 1 */ - tofile(L); /* check that it's a valid file handle */ - toclose = 0; /* do not close it after iteration */ - } - else { /* open a new file */ - const char *filename = luaL_checkstring(L, 1); - opencheck(L, filename, "r"); - lua_replace(L, 1); /* put file at index 1 */ - toclose = 1; /* close it after iteration */ - } - aux_lines(L, toclose); - return 1; +static int io_lines(lua_State *L) +{ + int toclose; + if (lua_isnone(L, 1)) lua_pushnil(L); /* at least one argument */ + if (lua_isnil(L, 1)) + { /* no file name? */ + lua_getfield(L, LUA_REGISTRYINDEX, IO_INPUT); /* get default input */ + lua_replace(L, 1); /* put it at index 1 */ + tofile(L); /* check that it's a valid file handle */ + toclose = 0; /* do not close it after iteration */ + } + else + { /* open a new file */ + const char *filename = luaL_checkstring(L, 1); + opencheck(L, filename, "r"); + lua_replace(L, 1); /* put file at index 1 */ + toclose = 1; /* close it after iteration */ + } + aux_lines(L, toclose); + return 1; } - /* ** {====================================================== ** READ ** ======================================================= */ - -static int read_number (lua_State *L, FILE *f) { - lua_Number d; - if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) { - lua_pushnumber(L, d); - return 1; - } - else { - lua_pushnil(L); /* "result" to be removed */ - return 0; /* read fails */ - } +static int read_number(lua_State *L, FILE *f) +{ + lua_Number d; + if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) + { + lua_pushnumber(L, d); + return 1; + } + else + { + lua_pushnil(L); /* "result" to be removed */ + return 0; /* read fails */ + } } - -static int test_eof (lua_State *L, FILE *f) { - int c = getc(f); - ungetc(c, f); - lua_pushlstring(L, NULL, 0); - return (c != EOF); +static int test_eof(lua_State *L, FILE *f) +{ + int c = getc(f); + ungetc(c, f); + lua_pushlstring(L, NULL, 0); + return (c != EOF); } - -static int read_line (lua_State *L, FILE *f, int chop) { - luaL_Buffer b; - luaL_buffinit(L, &b); - for (;;) { - size_t l; - char *p = luaL_prepbuffer(&b); - if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */ - luaL_pushresult(&b); /* close buffer */ - return (lua_rawlen(L, -1) > 0); /* check whether read something */ - } - l = strlen(p); - if (l == 0 || p[l-1] != '\n') - luaL_addsize(&b, l); - else { - luaL_addsize(&b, l - chop); /* chop 'eol' if needed */ - luaL_pushresult(&b); /* close buffer */ - return 1; /* read at least an `eol' */ - } - } +static int read_line(lua_State *L, FILE *f, int chop) +{ + luaL_Buffer b; + luaL_buffinit(L, &b); + for (;;) + { + size_t l; + char *p = luaL_prepbuffer(&b); + if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) + { /* eof? */ + luaL_pushresult(&b); /* close buffer */ + return (lua_rawlen(L, -1) > 0); /* check whether read something */ + } + l = strlen(p); + if (l == 0 || p[l - 1] != '\n') + luaL_addsize(&b, l); + else + { + luaL_addsize(&b, l - chop); /* chop 'eol' if needed */ + luaL_pushresult(&b); /* close buffer */ + return 1; /* read at least an `eol' */ + } + } } +#define MAX_SIZE_T (~(size_t)0) -#define MAX_SIZE_T (~(size_t)0) - -static void read_all (lua_State *L, FILE *f) { - size_t rlen = LUAL_BUFFERSIZE; /* how much to read in each cycle */ - luaL_Buffer b; - luaL_buffinit(L, &b); - for (;;) { - char *p = luaL_prepbuffsize(&b, rlen); - size_t nr = fread(p, sizeof(char), rlen, f); - luaL_addsize(&b, nr); - if (nr < rlen) break; /* eof? */ - else if (rlen <= (MAX_SIZE_T / 4)) /* avoid buffers too large */ - rlen *= 2; /* double buffer size at each iteration */ - } - luaL_pushresult(&b); /* close buffer */ +static void read_all(lua_State *L, FILE *f) +{ + size_t rlen = LUAL_BUFFERSIZE; /* how much to read in each cycle */ + luaL_Buffer b; + luaL_buffinit(L, &b); + for (;;) + { + char *p = luaL_prepbuffsize(&b, rlen); + size_t nr = fread(p, sizeof(char), rlen, f); + luaL_addsize(&b, nr); + if (nr < rlen) + break; /* eof? */ + else if (rlen <= (MAX_SIZE_T / 4)) /* avoid buffers too large */ + rlen *= 2; /* double buffer size at each iteration */ + } + luaL_pushresult(&b); /* close buffer */ } - -static int read_chars (lua_State *L, FILE *f, size_t n) { - size_t nr; /* number of chars actually read */ - char *p; - luaL_Buffer b; - luaL_buffinit(L, &b); - p = luaL_prepbuffsize(&b, n); /* prepare buffer to read whole block */ - nr = fread(p, sizeof(char), n, f); /* try to read 'n' chars */ - luaL_addsize(&b, nr); - luaL_pushresult(&b); /* close buffer */ - return (nr > 0); /* true iff read something */ +static int read_chars(lua_State *L, FILE *f, size_t n) +{ + size_t nr; /* number of chars actually read */ + char *p; + luaL_Buffer b; + luaL_buffinit(L, &b); + p = luaL_prepbuffsize(&b, n); /* prepare buffer to read whole block */ + nr = fread(p, sizeof(char), n, f); /* try to read 'n' chars */ + luaL_addsize(&b, nr); + luaL_pushresult(&b); /* close buffer */ + return (nr > 0); /* true iff read something */ } - -static int g_read (lua_State *L, FILE *f, int first) { - int nargs = lua_gettop(L) - 1; - int success; - int n; - clearerr(f); - if (nargs == 0) { /* no arguments? */ - success = read_line(L, f, 1); - n = first+1; /* to return 1 result */ - } - else { /* ensure stack space for all results and for auxlib's buffer */ - luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments"); - success = 1; - for (n = first; nargs-- && success; n++) { - if (lua_type(L, n) == LUA_TNUMBER) { - size_t l = (size_t)lua_tointeger(L, n); - success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); - } - else { - const char *p = lua_tostring(L, n); - luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); - switch (p[1]) { - case 'n': /* number */ - success = read_number(L, f); - break; - case 'l': /* line */ - success = read_line(L, f, 1); - break; - case 'L': /* line with end-of-line */ - success = read_line(L, f, 0); - break; - case 'a': /* file */ - read_all(L, f); /* read entire file */ - success = 1; /* always success */ - break; - default: - return luaL_argerror(L, n, "invalid format"); - } - } - } - } - if (ferror(f)) - return luaL_fileresult(L, 0, NULL); - if (!success) { - lua_pop(L, 1); /* remove last result */ - lua_pushnil(L); /* push nil instead */ - } - return n - first; +static int g_read(lua_State *L, FILE *f, int first) +{ + int nargs = lua_gettop(L) - 1; + int success; + int n; + clearerr(f); + if (nargs == 0) + { /* no arguments? */ + success = read_line(L, f, 1); + n = first + 1; /* to return 1 result */ + } + else + { /* ensure stack space for all results and for auxlib's buffer */ + luaL_checkstack(L, nargs + LUA_MINSTACK, "too many arguments"); + success = 1; + for (n = first; nargs-- && success; n++) + { + if (lua_type(L, n) == LUA_TNUMBER) + { + size_t l = (size_t)lua_tointeger(L, n); + success = (l == 0) ? test_eof(L, f) : read_chars(L, f, l); + } + else + { + const char *p = lua_tostring(L, n); + luaL_argcheck(L, p && p[0] == '*', n, "invalid option"); + switch (p[1]) + { + case 'n': /* number */ + success = read_number(L, f); + break; + case 'l': /* line */ + success = read_line(L, f, 1); + break; + case 'L': /* line with end-of-line */ + success = read_line(L, f, 0); + break; + case 'a': /* file */ + read_all(L, f); /* read entire file */ + success = 1; /* always success */ + break; + default: + return luaL_argerror(L, n, "invalid format"); + } + } + } + } + if (ferror(f)) + return luaL_fileresult(L, 0, NULL); + if (!success) + { + lua_pop(L, 1); /* remove last result */ + lua_pushnil(L); /* push nil instead */ + } + return n - first; } - -static int io_read (lua_State *L) { - return g_read(L, getiofile(L, IO_INPUT), 1); +static int io_read(lua_State *L) +{ + return g_read(L, getiofile(L, IO_INPUT), 1); } - -static int f_read (lua_State *L) { - return g_read(L, tofile(L), 2); +static int f_read(lua_State *L) +{ + return g_read(L, tofile(L), 2); } - -static int io_readline (lua_State *L) { - LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1)); - int i; - int n = (int)lua_tointeger(L, lua_upvalueindex(2)); - if (isclosed(p)) /* file is already closed? */ - return luaL_error(L, "file is already closed"); - lua_settop(L , 1); - for (i = 1; i <= n; i++) /* push arguments to 'g_read' */ - lua_pushvalue(L, lua_upvalueindex(3 + i)); - n = g_read(L, p->f, 2); /* 'n' is number of results */ - lua_assert(n > 0); /* should return at least a nil */ - if (!lua_isnil(L, -n)) /* read at least one value? */ - return n; /* return them */ - else { /* first result is nil: EOF or error */ - if (n > 1) { /* is there error information? */ - /* 2nd result is error message */ - return luaL_error(L, "%s", lua_tostring(L, -n + 1)); - } - if (lua_toboolean(L, lua_upvalueindex(3))) { /* generator created file? */ - lua_settop(L, 0); - lua_pushvalue(L, lua_upvalueindex(1)); - aux_close(L); /* close it */ - } - return 0; - } +static int io_readline(lua_State *L) +{ + LStream *p = (LStream *)lua_touserdata(L, lua_upvalueindex(1)); + int i; + int n = (int)lua_tointeger(L, lua_upvalueindex(2)); + if (isclosed(p)) /* file is already closed? */ + return luaL_error(L, "file is already closed"); + lua_settop(L, 1); + for (i = 1; i <= n; i++) /* push arguments to 'g_read' */ + lua_pushvalue(L, lua_upvalueindex(3 + i)); + n = g_read(L, p->f, 2); /* 'n' is number of results */ + lua_assert(n > 0); /* should return at least a nil */ + if (!lua_isnil(L, -n)) /* read at least one value? */ + return n; /* return them */ + else + { /* first result is nil: EOF or error */ + if (n > 1) + { /* is there error information? */ + /* 2nd result is error message */ + return luaL_error(L, "%s", lua_tostring(L, -n + 1)); + } + if (lua_toboolean(L, lua_upvalueindex(3))) + { /* generator created file? */ + lua_settop(L, 0); + lua_pushvalue(L, lua_upvalueindex(1)); + aux_close(L); /* close it */ + } + return 0; + } } /* }====================================================== */ - -static int g_write (lua_State *L, FILE *f, int arg) { - int nargs = lua_gettop(L) - arg; - int status = 1; - for (; nargs--; arg++) { - if (lua_type(L, arg) == LUA_TNUMBER) { - /* optimization: could be done exactly as for strings */ - status = status && - fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; - } - else { - size_t l; - const char *s = luaL_checklstring(L, arg, &l); - status = status && (fwrite(s, sizeof(char), l, f) == l); - } - } - if (status) return 1; /* file handle already on stack top */ - else return luaL_fileresult(L, status, NULL); +static int g_write(lua_State *L, FILE *f, int arg) +{ + int nargs = lua_gettop(L) - arg; + int status = 1; + for (; nargs--; arg++) + { + if (lua_type(L, arg) == LUA_TNUMBER) + { + /* optimization: could be done exactly as for strings */ + status = status && + fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0; + } + else + { + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + status = status && (fwrite(s, sizeof(char), l, f) == l); + } + } + if (status) + return 1; /* file handle already on stack top */ + else + return luaL_fileresult(L, status, NULL); } - -static int io_write (lua_State *L) { - return g_write(L, getiofile(L, IO_OUTPUT), 1); +static int io_write(lua_State *L) +{ + return g_write(L, getiofile(L, IO_OUTPUT), 1); } - -static int f_write (lua_State *L) { - FILE *f = tofile(L); - lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */ - return g_write(L, f, 2); +static int f_write(lua_State *L) +{ + FILE *f = tofile(L); + lua_pushvalue(L, 1); /* push file at the stack top (to be returned) */ + return g_write(L, f, 2); } - -static int f_seek (lua_State *L) { - static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; - static const char *const modenames[] = {"set", "cur", "end", NULL}; - FILE *f = tofile(L); - int op = luaL_checkoption(L, 2, "cur", modenames); - lua_Number p3 = luaL_optnumber(L, 3, 0); - l_seeknum offset = (l_seeknum)p3; - luaL_argcheck(L, (lua_Number)offset == p3, 3, - "not an integer in proper range"); - op = l_fseek(f, offset, mode[op]); - if (op) - return luaL_fileresult(L, 0, NULL); /* error */ - else { - lua_pushnumber(L, (lua_Number)l_ftell(f)); - return 1; - } +static int f_seek(lua_State *L) +{ + static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END}; + static const char *const modenames[] = {"set", "cur", "end", NULL}; + FILE *f = tofile(L); + int op = luaL_checkoption(L, 2, "cur", modenames); + lua_Number p3 = luaL_optnumber(L, 3, 0); + l_seeknum offset = (l_seeknum)p3; + luaL_argcheck(L, (lua_Number)offset == p3, 3, + "not an integer in proper range"); + op = l_fseek(f, offset, mode[op]); + if (op) + return luaL_fileresult(L, 0, NULL); /* error */ + else + { + lua_pushnumber(L, (lua_Number)l_ftell(f)); + return 1; + } } - -static int f_setvbuf (lua_State *L) { - static const int mode[] = {_IONBF, _IOFBF, _IOLBF}; - static const char *const modenames[] = {"no", "full", "line", NULL}; - FILE *f = tofile(L); - int op = luaL_checkoption(L, 2, NULL, modenames); - lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); - int res = setvbuf(f, NULL, mode[op], sz); - return luaL_fileresult(L, res == 0, NULL); +static int f_setvbuf(lua_State *L) +{ + static const int mode[] = {_IONBF, _IOFBF, _IOLBF}; + static const char *const modenames[] = {"no", "full", "line", NULL}; + FILE *f = tofile(L); + int op = luaL_checkoption(L, 2, NULL, modenames); + lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE); + int res = setvbuf(f, NULL, mode[op], sz); + return luaL_fileresult(L, res == 0, NULL); } - - -static int io_flush (lua_State *L) { - return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); +static int io_flush(lua_State *L) +{ + return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL); } - -static int f_flush (lua_State *L) { - return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL); +static int f_flush(lua_State *L) +{ + return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL); } - /* ** functions for 'io' library */ static const luaL_Reg iolib[] = { - {"close", io_close}, - {"flush", io_flush}, - {"input", io_input}, - {"lines", io_lines}, - {"open", io_open}, - {"output", io_output}, - {"popen", io_popen}, - {"read", io_read}, - {"tmpfile", io_tmpfile}, - {"type", io_type}, - {"write", io_write}, - {NULL, NULL} -}; - + {"close", io_close}, + {"flush", io_flush}, + {"input", io_input}, + {"lines", io_lines}, + {"open", io_open}, + {"output", io_output}, + {"popen", io_popen}, + {"read", io_read}, + {"tmpfile", io_tmpfile}, + {"type", io_type}, + {"write", io_write}, + {NULL, NULL}}; /* ** methods for file handles */ static const luaL_Reg flib[] = { - {"close", io_close}, - {"flush", f_flush}, - {"lines", f_lines}, - {"read", f_read}, - {"seek", f_seek}, - {"setvbuf", f_setvbuf}, - {"write", f_write}, - {"__gc", f_gc}, - {"__tostring", f_tostring}, - {NULL, NULL} -}; + {"close", io_close}, + {"flush", f_flush}, + {"lines", f_lines}, + {"read", f_read}, + {"seek", f_seek}, + {"setvbuf", f_setvbuf}, + {"write", f_write}, + {"__gc", f_gc}, + {"__tostring", f_tostring}, + {NULL, NULL}}; - -static void createmeta (lua_State *L) { - luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ - lua_pushvalue(L, -1); /* push metatable */ - lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ - luaL_setfuncs(L, flib, 0); /* add file methods to new metatable */ - lua_pop(L, 1); /* pop new metatable */ +static void createmeta(lua_State *L) +{ + luaL_newmetatable(L, LUA_FILEHANDLE); /* create metatable for file handles */ + lua_pushvalue(L, -1); /* push metatable */ + lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ + luaL_setfuncs(L, flib, 0); /* add file methods to new metatable */ + lua_pop(L, 1); /* pop new metatable */ } - /* ** function to (not) close the standard files stdin, stdout, and stderr */ -static int io_noclose (lua_State *L) { - LStream *p = tolstream(L); - p->closef = &io_noclose; /* keep file opened */ - lua_pushnil(L); - lua_pushliteral(L, "cannot close standard file"); - return 2; +static int io_noclose(lua_State *L) +{ + LStream *p = tolstream(L); + p->closef = &io_noclose; /* keep file opened */ + lua_pushnil(L); + lua_pushliteral(L, "cannot close standard file"); + return 2; } - -static void createstdfile (lua_State *L, FILE *f, const char *k, - const char *fname) { - LStream *p = newprefile(L); - p->f = f; - p->closef = &io_noclose; - if (k != NULL) { - lua_pushvalue(L, -1); - lua_setfield(L, LUA_REGISTRYINDEX, k); /* add file to registry */ - } - lua_setfield(L, -2, fname); /* add file to module */ +static void createstdfile(lua_State *L, FILE *f, const char *k, + const char *fname) +{ + LStream *p = newprefile(L); + p->f = f; + p->closef = &io_noclose; + if (k != NULL) + { + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, k); /* add file to registry */ + } + lua_setfield(L, -2, fname); /* add file to module */ } - -LUAMOD_API int luaopen_io (lua_State *L) { - luaL_newlib(L, iolib); /* new module */ - createmeta(L); - /* create (and set) default files */ - createstdfile(L, stdin, IO_INPUT, "stdin"); - createstdfile(L, stdout, IO_OUTPUT, "stdout"); - createstdfile(L, stderr, NULL, "stderr"); - return 1; +LUAMOD_API int luaopen_io(lua_State *L) +{ + luaL_newlib(L, iolib); /* new module */ + createmeta(L); + /* create (and set) default files */ + createstdfile(L, stdin, IO_INPUT, "stdin"); + createstdfile(L, stdout, IO_OUTPUT, "stdout"); + createstdfile(L, stderr, NULL, "stderr"); + return 1; } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/llex.c b/examples/ThirdPartyLibs/lua-5.2.3/src/llex.c index c4b820e83..dbe69f6b9 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/llex.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/llex.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #include #include @@ -23,508 +22,618 @@ #include "ltable.h" #include "lzio.h" - - #define next(ls) (ls->current = zgetc(ls->z)) - - -#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') - +#define currIsNewline(ls) (ls->current == '\n' || ls->current == '\r') /* ORDER RESERVED */ -static const char *const luaX_tokens [] = { - "and", "break", "do", "else", "elseif", - "end", "false", "for", "function", "goto", "if", - "in", "local", "nil", "not", "or", "repeat", - "return", "then", "true", "until", "while", - "..", "...", "==", ">=", "<=", "~=", "::", "", - "", "", "" -}; - +static const char *const luaX_tokens[] = { + "and", "break", "do", "else", "elseif", + "end", "false", "for", "function", "goto", "if", + "in", "local", "nil", "not", "or", "repeat", + "return", "then", "true", "until", "while", + "..", "...", "==", ">=", "<=", "~=", "::", "", + "", "", ""}; #define save_and_next(ls) (save(ls, ls->current), next(ls)) +static l_noret lexerror(LexState *ls, const char *msg, int token); -static l_noret lexerror (LexState *ls, const char *msg, int token); - - -static void save (LexState *ls, int c) { - Mbuffer *b = ls->buff; - if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) { - size_t newsize; - if (luaZ_sizebuffer(b) >= MAX_SIZET/2) - lexerror(ls, "lexical element too long", 0); - newsize = luaZ_sizebuffer(b) * 2; - luaZ_resizebuffer(ls->L, b, newsize); - } - b->buffer[luaZ_bufflen(b)++] = cast(char, c); +static void save(LexState *ls, int c) +{ + Mbuffer *b = ls->buff; + if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) + { + size_t newsize; + if (luaZ_sizebuffer(b) >= MAX_SIZET / 2) + lexerror(ls, "lexical element too long", 0); + newsize = luaZ_sizebuffer(b) * 2; + luaZ_resizebuffer(ls->L, b, newsize); + } + b->buffer[luaZ_bufflen(b)++] = cast(char, c); } - -void luaX_init (lua_State *L) { - int i; - for (i=0; itsv.extra = cast_byte(i+1); /* reserved word */ - } +void luaX_init(lua_State *L) +{ + int i; + for (i = 0; i < NUM_RESERVED; i++) + { + TString *ts = luaS_new(L, luaX_tokens[i]); + luaS_fix(ts); /* reserved words are never collected */ + ts->tsv.extra = cast_byte(i + 1); /* reserved word */ + } } - -const char *luaX_token2str (LexState *ls, int token) { - if (token < FIRST_RESERVED) { /* single-byte symbols? */ - lua_assert(token == cast(unsigned char, token)); - return (lisprint(token)) ? luaO_pushfstring(ls->L, LUA_QL("%c"), token) : - luaO_pushfstring(ls->L, "char(%d)", token); - } - else { - const char *s = luaX_tokens[token - FIRST_RESERVED]; - if (token < TK_EOS) /* fixed format (symbols and reserved words)? */ - return luaO_pushfstring(ls->L, LUA_QS, s); - else /* names, strings, and numerals */ - return s; - } +const char *luaX_token2str(LexState *ls, int token) +{ + if (token < FIRST_RESERVED) + { /* single-byte symbols? */ + lua_assert(token == cast(unsigned char, token)); + return (lisprint(token)) ? luaO_pushfstring(ls->L, LUA_QL("%c"), token) : luaO_pushfstring(ls->L, "char(%d)", token); + } + else + { + const char *s = luaX_tokens[token - FIRST_RESERVED]; + if (token < TK_EOS) /* fixed format (symbols and reserved words)? */ + return luaO_pushfstring(ls->L, LUA_QS, s); + else /* names, strings, and numerals */ + return s; + } } - -static const char *txtToken (LexState *ls, int token) { - switch (token) { - case TK_NAME: - case TK_STRING: - case TK_NUMBER: - save(ls, '\0'); - return luaO_pushfstring(ls->L, LUA_QS, luaZ_buffer(ls->buff)); - default: - return luaX_token2str(ls, token); - } +static const char *txtToken(LexState *ls, int token) +{ + switch (token) + { + case TK_NAME: + case TK_STRING: + case TK_NUMBER: + save(ls, '\0'); + return luaO_pushfstring(ls->L, LUA_QS, luaZ_buffer(ls->buff)); + default: + return luaX_token2str(ls, token); + } } - -static l_noret lexerror (LexState *ls, const char *msg, int token) { - char buff[LUA_IDSIZE]; - luaO_chunkid(buff, getstr(ls->source), LUA_IDSIZE); - msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg); - if (token) - luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token)); - luaD_throw(ls->L, LUA_ERRSYNTAX); +static l_noret lexerror(LexState *ls, const char *msg, int token) +{ + char buff[LUA_IDSIZE]; + luaO_chunkid(buff, getstr(ls->source), LUA_IDSIZE); + msg = luaO_pushfstring(ls->L, "%s:%d: %s", buff, ls->linenumber, msg); + if (token) + luaO_pushfstring(ls->L, "%s near %s", msg, txtToken(ls, token)); + luaD_throw(ls->L, LUA_ERRSYNTAX); } - -l_noret luaX_syntaxerror (LexState *ls, const char *msg) { - lexerror(ls, msg, ls->t.token); +l_noret luaX_syntaxerror(LexState *ls, const char *msg) +{ + lexerror(ls, msg, ls->t.token); } - /* ** creates a new string and anchors it in function's table so that ** it will not be collected until the end of the function's compilation ** (by that time it should be anchored in function's prototype) */ -TString *luaX_newstring (LexState *ls, const char *str, size_t l) { - lua_State *L = ls->L; - TValue *o; /* entry for `str' */ - TString *ts = luaS_newlstr(L, str, l); /* create new string */ - setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ - o = luaH_set(L, ls->fs->h, L->top - 1); - if (ttisnil(o)) { /* not in use yet? (see 'addK') */ - /* boolean value does not need GC barrier; +TString *luaX_newstring(LexState *ls, const char *str, size_t l) +{ + lua_State *L = ls->L; + TValue *o; /* entry for `str' */ + TString *ts = luaS_newlstr(L, str, l); /* create new string */ + setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */ + o = luaH_set(L, ls->fs->h, L->top - 1); + if (ttisnil(o)) + { /* not in use yet? (see 'addK') */ + /* boolean value does not need GC barrier; table has no metatable, so it does not need to invalidate cache */ - setbvalue(o, 1); /* t[string] = true */ - luaC_checkGC(L); - } - else { /* string already present */ - ts = rawtsvalue(keyfromval(o)); /* re-use value previously stored */ - } - L->top--; /* remove string from stack */ - return ts; + setbvalue(o, 1); /* t[string] = true */ + luaC_checkGC(L); + } + else + { /* string already present */ + ts = rawtsvalue(keyfromval(o)); /* re-use value previously stored */ + } + L->top--; /* remove string from stack */ + return ts; } - /* ** increment line number and skips newline sequence (any of ** \n, \r, \n\r, or \r\n) */ -static void inclinenumber (LexState *ls) { - int old = ls->current; - lua_assert(currIsNewline(ls)); - next(ls); /* skip `\n' or `\r' */ - if (currIsNewline(ls) && ls->current != old) - next(ls); /* skip `\n\r' or `\r\n' */ - if (++ls->linenumber >= MAX_INT) - luaX_syntaxerror(ls, "chunk has too many lines"); +static void inclinenumber(LexState *ls) +{ + int old = ls->current; + lua_assert(currIsNewline(ls)); + next(ls); /* skip `\n' or `\r' */ + if (currIsNewline(ls) && ls->current != old) + next(ls); /* skip `\n\r' or `\r\n' */ + if (++ls->linenumber >= MAX_INT) + luaX_syntaxerror(ls, "chunk has too many lines"); } - -void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source, - int firstchar) { - ls->decpoint = '.'; - ls->L = L; - ls->current = firstchar; - ls->lookahead.token = TK_EOS; /* no look-ahead token */ - ls->z = z; - ls->fs = NULL; - ls->linenumber = 1; - ls->lastline = 1; - ls->source = source; - ls->envn = luaS_new(L, LUA_ENV); /* create env name */ - luaS_fix(ls->envn); /* never collect this name */ - luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ +void luaX_setinput(lua_State *L, LexState *ls, ZIO *z, TString *source, + int firstchar) +{ + ls->decpoint = '.'; + ls->L = L; + ls->current = firstchar; + ls->lookahead.token = TK_EOS; /* no look-ahead token */ + ls->z = z; + ls->fs = NULL; + ls->linenumber = 1; + ls->lastline = 1; + ls->source = source; + ls->envn = luaS_new(L, LUA_ENV); /* create env name */ + luaS_fix(ls->envn); /* never collect this name */ + luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */ } - - /* ** ======================================================= ** LEXICAL ANALYZER ** ======================================================= */ - - -static int check_next (LexState *ls, const char *set) { - if (ls->current == '\0' || !strchr(set, ls->current)) - return 0; - save_and_next(ls); - return 1; +static int check_next(LexState *ls, const char *set) +{ + if (ls->current == '\0' || !strchr(set, ls->current)) + return 0; + save_and_next(ls); + return 1; } - /* ** change all characters 'from' in buffer to 'to' */ -static void buffreplace (LexState *ls, char from, char to) { - size_t n = luaZ_bufflen(ls->buff); - char *p = luaZ_buffer(ls->buff); - while (n--) - if (p[n] == from) p[n] = to; +static void buffreplace(LexState *ls, char from, char to) +{ + size_t n = luaZ_bufflen(ls->buff); + char *p = luaZ_buffer(ls->buff); + while (n--) + if (p[n] == from) p[n] = to; } - #if !defined(getlocaledecpoint) -#define getlocaledecpoint() (localeconv()->decimal_point[0]) +#define getlocaledecpoint() (localeconv()->decimal_point[0]) #endif - -#define buff2d(b,e) luaO_str2d(luaZ_buffer(b), luaZ_bufflen(b) - 1, e) +#define buff2d(b, e) luaO_str2d(luaZ_buffer(b), luaZ_bufflen(b) - 1, e) /* ** in case of format error, try to change decimal point separator to ** the one defined in the current locale and check again */ -static void trydecpoint (LexState *ls, SemInfo *seminfo) { - char old = ls->decpoint; - ls->decpoint = getlocaledecpoint(); - buffreplace(ls, old, ls->decpoint); /* try new decimal separator */ - if (!buff2d(ls->buff, &seminfo->r)) { - /* format error with correct decimal point: no more options */ - buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ - lexerror(ls, "malformed number", TK_NUMBER); - } +static void trydecpoint(LexState *ls, SemInfo *seminfo) +{ + char old = ls->decpoint; + ls->decpoint = getlocaledecpoint(); + buffreplace(ls, old, ls->decpoint); /* try new decimal separator */ + if (!buff2d(ls->buff, &seminfo->r)) + { + /* format error with correct decimal point: no more options */ + buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */ + lexerror(ls, "malformed number", TK_NUMBER); + } } - /* LUA_NUMBER */ /* ** this function is quite liberal in what it accepts, as 'luaO_str2d' ** will reject ill-formed numerals. */ -static void read_numeral (LexState *ls, SemInfo *seminfo) { - const char *expo = "Ee"; - int first = ls->current; - lua_assert(lisdigit(ls->current)); - save_and_next(ls); - if (first == '0' && check_next(ls, "Xx")) /* hexadecimal? */ - expo = "Pp"; - for (;;) { - if (check_next(ls, expo)) /* exponent part? */ - check_next(ls, "+-"); /* optional exponent sign */ - if (lisxdigit(ls->current) || ls->current == '.') - save_and_next(ls); - else break; - } - save(ls, '\0'); - buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ - if (!buff2d(ls->buff, &seminfo->r)) /* format error? */ - trydecpoint(ls, seminfo); /* try to update decimal point separator */ +static void read_numeral(LexState *ls, SemInfo *seminfo) +{ + const char *expo = "Ee"; + int first = ls->current; + lua_assert(lisdigit(ls->current)); + save_and_next(ls); + if (first == '0' && check_next(ls, "Xx")) /* hexadecimal? */ + expo = "Pp"; + for (;;) + { + if (check_next(ls, expo)) /* exponent part? */ + check_next(ls, "+-"); /* optional exponent sign */ + if (lisxdigit(ls->current) || ls->current == '.') + save_and_next(ls); + else + break; + } + save(ls, '\0'); + buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */ + if (!buff2d(ls->buff, &seminfo->r)) /* format error? */ + trydecpoint(ls, seminfo); /* try to update decimal point separator */ } - /* ** skip a sequence '[=*[' or ']=*]' and return its number of '='s or ** -1 if sequence is malformed */ -static int skip_sep (LexState *ls) { - int count = 0; - int s = ls->current; - lua_assert(s == '[' || s == ']'); - save_and_next(ls); - while (ls->current == '=') { - save_and_next(ls); - count++; - } - return (ls->current == s) ? count : (-count) - 1; +static int skip_sep(LexState *ls) +{ + int count = 0; + int s = ls->current; + lua_assert(s == '[' || s == ']'); + save_and_next(ls); + while (ls->current == '=') + { + save_and_next(ls); + count++; + } + return (ls->current == s) ? count : (-count) - 1; } - -static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { - save_and_next(ls); /* skip 2nd `[' */ - if (currIsNewline(ls)) /* string starts with a newline? */ - inclinenumber(ls); /* skip it */ - for (;;) { - switch (ls->current) { - case EOZ: - lexerror(ls, (seminfo) ? "unfinished long string" : - "unfinished long comment", TK_EOS); - break; /* to avoid warnings */ - case ']': { - if (skip_sep(ls) == sep) { - save_and_next(ls); /* skip 2nd `]' */ - goto endloop; - } - break; - } - case '\n': case '\r': { - save(ls, '\n'); - inclinenumber(ls); - if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ - break; - } - default: { - if (seminfo) save_and_next(ls); - else next(ls); - } - } - } endloop: - if (seminfo) - seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), - luaZ_bufflen(ls->buff) - 2*(2 + sep)); +static void read_long_string(LexState *ls, SemInfo *seminfo, int sep) +{ + save_and_next(ls); /* skip 2nd `[' */ + if (currIsNewline(ls)) /* string starts with a newline? */ + inclinenumber(ls); /* skip it */ + for (;;) + { + switch (ls->current) + { + case EOZ: + lexerror(ls, (seminfo) ? "unfinished long string" : "unfinished long comment", TK_EOS); + break; /* to avoid warnings */ + case ']': + { + if (skip_sep(ls) == sep) + { + save_and_next(ls); /* skip 2nd `]' */ + goto endloop; + } + break; + } + case '\n': + case '\r': + { + save(ls, '\n'); + inclinenumber(ls); + if (!seminfo) luaZ_resetbuffer(ls->buff); /* avoid wasting space */ + break; + } + default: + { + if (seminfo) + save_and_next(ls); + else + next(ls); + } + } + } +endloop: + if (seminfo) + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + (2 + sep), + luaZ_bufflen(ls->buff) - 2 * (2 + sep)); } - -static void escerror (LexState *ls, int *c, int n, const char *msg) { - int i; - luaZ_resetbuffer(ls->buff); /* prepare error message */ - save(ls, '\\'); - for (i = 0; i < n && c[i] != EOZ; i++) - save(ls, c[i]); - lexerror(ls, msg, TK_STRING); +static void escerror(LexState *ls, int *c, int n, const char *msg) +{ + int i; + luaZ_resetbuffer(ls->buff); /* prepare error message */ + save(ls, '\\'); + for (i = 0; i < n && c[i] != EOZ; i++) + save(ls, c[i]); + lexerror(ls, msg, TK_STRING); } - -static int readhexaesc (LexState *ls) { - int c[3], i; /* keep input for error message */ - int r = 0; /* result accumulator */ - c[0] = 'x'; /* for error message */ - for (i = 1; i < 3; i++) { /* read two hexadecimal digits */ - c[i] = next(ls); - if (!lisxdigit(c[i])) - escerror(ls, c, i + 1, "hexadecimal digit expected"); - r = (r << 4) + luaO_hexavalue(c[i]); - } - return r; +static int readhexaesc(LexState *ls) +{ + int c[3], i; /* keep input for error message */ + int r = 0; /* result accumulator */ + c[0] = 'x'; /* for error message */ + for (i = 1; i < 3; i++) + { /* read two hexadecimal digits */ + c[i] = next(ls); + if (!lisxdigit(c[i])) + escerror(ls, c, i + 1, "hexadecimal digit expected"); + r = (r << 4) + luaO_hexavalue(c[i]); + } + return r; } - -static int readdecesc (LexState *ls) { - int c[3], i; - int r = 0; /* result accumulator */ - for (i = 0; i < 3 && lisdigit(ls->current); i++) { /* read up to 3 digits */ - c[i] = ls->current; - r = 10*r + c[i] - '0'; - next(ls); - } - if (r > UCHAR_MAX) - escerror(ls, c, i, "decimal escape too large"); - return r; +static int readdecesc(LexState *ls) +{ + int c[3], i; + int r = 0; /* result accumulator */ + for (i = 0; i < 3 && lisdigit(ls->current); i++) + { /* read up to 3 digits */ + c[i] = ls->current; + r = 10 * r + c[i] - '0'; + next(ls); + } + if (r > UCHAR_MAX) + escerror(ls, c, i, "decimal escape too large"); + return r; } - -static void read_string (LexState *ls, int del, SemInfo *seminfo) { - save_and_next(ls); /* keep delimiter (for error messages) */ - while (ls->current != del) { - switch (ls->current) { - case EOZ: - lexerror(ls, "unfinished string", TK_EOS); - break; /* to avoid warnings */ - case '\n': - case '\r': - lexerror(ls, "unfinished string", TK_STRING); - break; /* to avoid warnings */ - case '\\': { /* escape sequences */ - int c; /* final character to be saved */ - next(ls); /* do not save the `\' */ - switch (ls->current) { - case 'a': c = '\a'; goto read_save; - case 'b': c = '\b'; goto read_save; - case 'f': c = '\f'; goto read_save; - case 'n': c = '\n'; goto read_save; - case 'r': c = '\r'; goto read_save; - case 't': c = '\t'; goto read_save; - case 'v': c = '\v'; goto read_save; - case 'x': c = readhexaesc(ls); goto read_save; - case '\n': case '\r': - inclinenumber(ls); c = '\n'; goto only_save; - case '\\': case '\"': case '\'': - c = ls->current; goto read_save; - case EOZ: goto no_save; /* will raise an error next loop */ - case 'z': { /* zap following span of spaces */ - next(ls); /* skip the 'z' */ - while (lisspace(ls->current)) { - if (currIsNewline(ls)) inclinenumber(ls); - else next(ls); - } - goto no_save; - } - default: { - if (!lisdigit(ls->current)) - escerror(ls, &ls->current, 1, "invalid escape sequence"); - /* digital escape \ddd */ - c = readdecesc(ls); - goto only_save; - } - } - read_save: next(ls); /* read next character */ - only_save: save(ls, c); /* save 'c' */ - no_save: break; - } - default: - save_and_next(ls); - } - } - save_and_next(ls); /* skip delimiter */ - seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1, - luaZ_bufflen(ls->buff) - 2); +static void read_string(LexState *ls, int del, SemInfo *seminfo) +{ + save_and_next(ls); /* keep delimiter (for error messages) */ + while (ls->current != del) + { + switch (ls->current) + { + case EOZ: + lexerror(ls, "unfinished string", TK_EOS); + break; /* to avoid warnings */ + case '\n': + case '\r': + lexerror(ls, "unfinished string", TK_STRING); + break; /* to avoid warnings */ + case '\\': + { /* escape sequences */ + int c; /* final character to be saved */ + next(ls); /* do not save the `\' */ + switch (ls->current) + { + case 'a': + c = '\a'; + goto read_save; + case 'b': + c = '\b'; + goto read_save; + case 'f': + c = '\f'; + goto read_save; + case 'n': + c = '\n'; + goto read_save; + case 'r': + c = '\r'; + goto read_save; + case 't': + c = '\t'; + goto read_save; + case 'v': + c = '\v'; + goto read_save; + case 'x': + c = readhexaesc(ls); + goto read_save; + case '\n': + case '\r': + inclinenumber(ls); + c = '\n'; + goto only_save; + case '\\': + case '\"': + case '\'': + c = ls->current; + goto read_save; + case EOZ: + goto no_save; /* will raise an error next loop */ + case 'z': + { /* zap following span of spaces */ + next(ls); /* skip the 'z' */ + while (lisspace(ls->current)) + { + if (currIsNewline(ls)) + inclinenumber(ls); + else + next(ls); + } + goto no_save; + } + default: + { + if (!lisdigit(ls->current)) + escerror(ls, &ls->current, 1, "invalid escape sequence"); + /* digital escape \ddd */ + c = readdecesc(ls); + goto only_save; + } + } + read_save: + next(ls); /* read next character */ + only_save: + save(ls, c); /* save 'c' */ + no_save: + break; + } + default: + save_and_next(ls); + } + } + save_and_next(ls); /* skip delimiter */ + seminfo->ts = luaX_newstring(ls, luaZ_buffer(ls->buff) + 1, + luaZ_bufflen(ls->buff) - 2); } - -static int llex (LexState *ls, SemInfo *seminfo) { - luaZ_resetbuffer(ls->buff); - for (;;) { - switch (ls->current) { - case '\n': case '\r': { /* line breaks */ - inclinenumber(ls); - break; - } - case ' ': case '\f': case '\t': case '\v': { /* spaces */ - next(ls); - break; - } - case '-': { /* '-' or '--' (comment) */ - next(ls); - if (ls->current != '-') return '-'; - /* else is a comment */ - next(ls); - if (ls->current == '[') { /* long comment? */ - int sep = skip_sep(ls); - luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ - if (sep >= 0) { - read_long_string(ls, NULL, sep); /* skip long comment */ - luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */ - break; - } - } - /* else short comment */ - while (!currIsNewline(ls) && ls->current != EOZ) - next(ls); /* skip until end of line (or end of file) */ - break; - } - case '[': { /* long string or simply '[' */ - int sep = skip_sep(ls); - if (sep >= 0) { - read_long_string(ls, seminfo, sep); - return TK_STRING; - } - else if (sep == -1) return '['; - else lexerror(ls, "invalid long string delimiter", TK_STRING); - } - case '=': { - next(ls); - if (ls->current != '=') return '='; - else { next(ls); return TK_EQ; } - } - case '<': { - next(ls); - if (ls->current != '=') return '<'; - else { next(ls); return TK_LE; } - } - case '>': { - next(ls); - if (ls->current != '=') return '>'; - else { next(ls); return TK_GE; } - } - case '~': { - next(ls); - if (ls->current != '=') return '~'; - else { next(ls); return TK_NE; } - } - case ':': { - next(ls); - if (ls->current != ':') return ':'; - else { next(ls); return TK_DBCOLON; } - } - case '"': case '\'': { /* short literal strings */ - read_string(ls, ls->current, seminfo); - return TK_STRING; - } - case '.': { /* '.', '..', '...', or number */ - save_and_next(ls); - if (check_next(ls, ".")) { - if (check_next(ls, ".")) - return TK_DOTS; /* '...' */ - else return TK_CONCAT; /* '..' */ - } - else if (!lisdigit(ls->current)) return '.'; - /* else go through */ - } - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': { - read_numeral(ls, seminfo); - return TK_NUMBER; - } - case EOZ: { - return TK_EOS; - } - default: { - if (lislalpha(ls->current)) { /* identifier or reserved word? */ - TString *ts; - do { - save_and_next(ls); - } while (lislalnum(ls->current)); - ts = luaX_newstring(ls, luaZ_buffer(ls->buff), - luaZ_bufflen(ls->buff)); - seminfo->ts = ts; - if (isreserved(ts)) /* reserved word? */ - return ts->tsv.extra - 1 + FIRST_RESERVED; - else { - return TK_NAME; - } - } - else { /* single-char tokens (+ - / ...) */ - int c = ls->current; - next(ls); - return c; - } - } - } - } +static int llex(LexState *ls, SemInfo *seminfo) +{ + luaZ_resetbuffer(ls->buff); + for (;;) + { + switch (ls->current) + { + case '\n': + case '\r': + { /* line breaks */ + inclinenumber(ls); + break; + } + case ' ': + case '\f': + case '\t': + case '\v': + { /* spaces */ + next(ls); + break; + } + case '-': + { /* '-' or '--' (comment) */ + next(ls); + if (ls->current != '-') return '-'; + /* else is a comment */ + next(ls); + if (ls->current == '[') + { /* long comment? */ + int sep = skip_sep(ls); + luaZ_resetbuffer(ls->buff); /* `skip_sep' may dirty the buffer */ + if (sep >= 0) + { + read_long_string(ls, NULL, sep); /* skip long comment */ + luaZ_resetbuffer(ls->buff); /* previous call may dirty the buff. */ + break; + } + } + /* else short comment */ + while (!currIsNewline(ls) && ls->current != EOZ) + next(ls); /* skip until end of line (or end of file) */ + break; + } + case '[': + { /* long string or simply '[' */ + int sep = skip_sep(ls); + if (sep >= 0) + { + read_long_string(ls, seminfo, sep); + return TK_STRING; + } + else if (sep == -1) + return '['; + else + lexerror(ls, "invalid long string delimiter", TK_STRING); + } + case '=': + { + next(ls); + if (ls->current != '=') + return '='; + else + { + next(ls); + return TK_EQ; + } + } + case '<': + { + next(ls); + if (ls->current != '=') + return '<'; + else + { + next(ls); + return TK_LE; + } + } + case '>': + { + next(ls); + if (ls->current != '=') + return '>'; + else + { + next(ls); + return TK_GE; + } + } + case '~': + { + next(ls); + if (ls->current != '=') + return '~'; + else + { + next(ls); + return TK_NE; + } + } + case ':': + { + next(ls); + if (ls->current != ':') + return ':'; + else + { + next(ls); + return TK_DBCOLON; + } + } + case '"': + case '\'': + { /* short literal strings */ + read_string(ls, ls->current, seminfo); + return TK_STRING; + } + case '.': + { /* '.', '..', '...', or number */ + save_and_next(ls); + if (check_next(ls, ".")) + { + if (check_next(ls, ".")) + return TK_DOTS; /* '...' */ + else + return TK_CONCAT; /* '..' */ + } + else if (!lisdigit(ls->current)) + return '.'; + /* else go through */ + } + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { + read_numeral(ls, seminfo); + return TK_NUMBER; + } + case EOZ: + { + return TK_EOS; + } + default: + { + if (lislalpha(ls->current)) + { /* identifier or reserved word? */ + TString *ts; + do + { + save_and_next(ls); + } while (lislalnum(ls->current)); + ts = luaX_newstring(ls, luaZ_buffer(ls->buff), + luaZ_bufflen(ls->buff)); + seminfo->ts = ts; + if (isreserved(ts)) /* reserved word? */ + return ts->tsv.extra - 1 + FIRST_RESERVED; + else + { + return TK_NAME; + } + } + else + { /* single-char tokens (+ - / ...) */ + int c = ls->current; + next(ls); + return c; + } + } + } + } } - -void luaX_next (LexState *ls) { - ls->lastline = ls->linenumber; - if (ls->lookahead.token != TK_EOS) { /* is there a look-ahead token? */ - ls->t = ls->lookahead; /* use this one */ - ls->lookahead.token = TK_EOS; /* and discharge it */ - } - else - ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */ +void luaX_next(LexState *ls) +{ + ls->lastline = ls->linenumber; + if (ls->lookahead.token != TK_EOS) + { /* is there a look-ahead token? */ + ls->t = ls->lookahead; /* use this one */ + ls->lookahead.token = TK_EOS; /* and discharge it */ + } + else + ls->t.token = llex(ls, &ls->t.seminfo); /* read next token */ } - -int luaX_lookahead (LexState *ls) { - lua_assert(ls->lookahead.token == TK_EOS); - ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); - return ls->lookahead.token; +int luaX_lookahead(LexState *ls) +{ + lua_assert(ls->lookahead.token == TK_EOS); + ls->lookahead.token = llex(ls, &ls->lookahead.seminfo); + return ls->lookahead.token; } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/llex.h b/examples/ThirdPartyLibs/lua-5.2.3/src/llex.h index a4acdd302..29c50b8bc 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/llex.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/llex.h @@ -10,69 +10,91 @@ #include "lobject.h" #include "lzio.h" - -#define FIRST_RESERVED 257 - - +#define FIRST_RESERVED 257 /* * WARNING: if you change the order of this enumeration, * grep "ORDER RESERVED" */ -enum RESERVED { - /* terminal symbols denoted by reserved words */ - TK_AND = FIRST_RESERVED, TK_BREAK, - TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, - TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, - TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, - /* other terminal symbols */ - TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_DBCOLON, TK_EOS, - TK_NUMBER, TK_NAME, TK_STRING +enum RESERVED +{ + /* terminal symbols denoted by reserved words */ + TK_AND = FIRST_RESERVED, + TK_BREAK, + TK_DO, + TK_ELSE, + TK_ELSEIF, + TK_END, + TK_FALSE, + TK_FOR, + TK_FUNCTION, + TK_GOTO, + TK_IF, + TK_IN, + TK_LOCAL, + TK_NIL, + TK_NOT, + TK_OR, + TK_REPEAT, + TK_RETURN, + TK_THEN, + TK_TRUE, + TK_UNTIL, + TK_WHILE, + /* other terminal symbols */ + TK_CONCAT, + TK_DOTS, + TK_EQ, + TK_GE, + TK_LE, + TK_NE, + TK_DBCOLON, + TK_EOS, + TK_NUMBER, + TK_NAME, + TK_STRING }; /* number of reserved words */ -#define NUM_RESERVED (cast(int, TK_WHILE-FIRST_RESERVED+1)) - +#define NUM_RESERVED (cast(int, TK_WHILE - FIRST_RESERVED + 1)) typedef union { - lua_Number r; - TString *ts; -} SemInfo; /* semantics information */ + lua_Number r; + TString *ts; +} SemInfo; /* semantics information */ - -typedef struct Token { - int token; - SemInfo seminfo; +typedef struct Token +{ + int token; + SemInfo seminfo; } Token; - /* state of the lexer plus state of the parser when shared by all functions */ -typedef struct LexState { - int current; /* current character (charint) */ - int linenumber; /* input line counter */ - int lastline; /* line of last token `consumed' */ - Token t; /* current token */ - Token lookahead; /* look ahead token */ - struct FuncState *fs; /* current function (parser) */ - struct lua_State *L; - ZIO *z; /* input stream */ - Mbuffer *buff; /* buffer for tokens */ - struct Dyndata *dyd; /* dynamic structures used by the parser */ - TString *source; /* current source name */ - TString *envn; /* environment variable name */ - char decpoint; /* locale decimal point */ +typedef struct LexState +{ + int current; /* current character (charint) */ + int linenumber; /* input line counter */ + int lastline; /* line of last token `consumed' */ + Token t; /* current token */ + Token lookahead; /* look ahead token */ + struct FuncState *fs; /* current function (parser) */ + struct lua_State *L; + ZIO *z; /* input stream */ + Mbuffer *buff; /* buffer for tokens */ + struct Dyndata *dyd; /* dynamic structures used by the parser */ + TString *source; /* current source name */ + TString *envn; /* environment variable name */ + char decpoint; /* locale decimal point */ } LexState; - -LUAI_FUNC void luaX_init (lua_State *L); -LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, - TString *source, int firstchar); -LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); -LUAI_FUNC void luaX_next (LexState *ls); -LUAI_FUNC int luaX_lookahead (LexState *ls); -LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s); -LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); - +LUAI_FUNC void luaX_init(lua_State *L); +LUAI_FUNC void luaX_setinput(lua_State *L, LexState *ls, ZIO *z, + TString *source, int firstchar); +LUAI_FUNC TString *luaX_newstring(LexState *ls, const char *str, size_t l); +LUAI_FUNC void luaX_next(LexState *ls); +LUAI_FUNC int luaX_lookahead(LexState *ls); +LUAI_FUNC l_noret luaX_syntaxerror(LexState *ls, const char *s); +LUAI_FUNC const char *luaX_token2str(LexState *ls, int token); #endif diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/llimits.h b/examples/ThirdPartyLibs/lua-5.2.3/src/llimits.h index 152dd0551..3ecd7afe5 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/llimits.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/llimits.h @@ -7,65 +7,62 @@ #ifndef llimits_h #define llimits_h - #include #include - #include "lua.h" - typedef unsigned LUA_INT32 lu_int32; typedef LUAI_UMEM lu_mem; typedef LUAI_MEM l_mem; - - /* chars used as small naturals (so that `char' is reserved for characters) */ typedef unsigned char lu_byte; +#define MAX_SIZET ((size_t)(~(size_t)0) - 2) -#define MAX_SIZET ((size_t)(~(size_t)0)-2) +#define MAX_LUMEM ((lu_mem)(~(lu_mem)0) - 2) -#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2) +#define MAX_LMEM ((l_mem)((MAX_LUMEM >> 1) - 2)) -#define MAX_LMEM ((l_mem) ((MAX_LUMEM >> 1) - 2)) - - -#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */ +#define MAX_INT (INT_MAX - 2) /* maximum value of an int (-2 for safety) */ /* ** conversion of pointer to integer ** this is for hashing only; there is no problem if the integer ** cannot hold the whole pointer value */ -#define IntPoint(p) ((unsigned int)(lu_mem)(p)) - - +#define IntPoint(p) ((unsigned int)(lu_mem)(p)) /* type to ensure maximum alignment */ #if !defined(LUAI_USER_ALIGNMENT_T) -#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; } +#define LUAI_USER_ALIGNMENT_T \ + union { \ + double u; \ + void *s; \ + long l; \ + } #endif typedef LUAI_USER_ALIGNMENT_T L_Umaxalign; - /* result of a `usual argument conversion' over lua_Number */ typedef LUAI_UACNUMBER l_uacNumber; - /* internal assertions for in-house debugging */ #if defined(lua_assert) -#define check_exp(c,e) (lua_assert(c), (e)) +#define check_exp(c, e) (lua_assert(c), (e)) /* to avoid problems with conditions too long */ -#define lua_longassert(c) { if (!(c)) lua_assert(0); } +#define lua_longassert(c) \ + { \ + if (!(c)) lua_assert(0); \ + } #else -#define lua_assert(c) ((void)0) -#define check_exp(c,e) (e) -#define lua_longassert(c) ((void)0) +#define lua_assert(c) ((void)0) +#define check_exp(c, e) (e) +#define lua_longassert(c) ((void)0) #endif /* @@ -75,56 +72,50 @@ typedef LUAI_UACNUMBER l_uacNumber; #if defined(LUA_USE_APICHECK) #include -#define luai_apicheck(L,e) assert(e) +#define luai_apicheck(L, e) assert(e) #else -#define luai_apicheck(L,e) lua_assert(e) +#define luai_apicheck(L, e) lua_assert(e) #endif #endif -#define api_check(l,e,msg) luai_apicheck(l,(e) && msg) - +#define api_check(l, e, msg) luai_apicheck(l, (e) && msg) #if !defined(UNUSED) -#define UNUSED(x) ((void)(x)) /* to avoid warnings */ +#define UNUSED(x) ((void)(x)) /* to avoid warnings */ #endif +#define cast(t, exp) ((t)(exp)) -#define cast(t, exp) ((t)(exp)) - -#define cast_byte(i) cast(lu_byte, (i)) -#define cast_num(i) cast(lua_Number, (i)) -#define cast_int(i) cast(int, (i)) -#define cast_uchar(i) cast(unsigned char, (i)) - +#define cast_byte(i) cast(lu_byte, (i)) +#define cast_num(i) cast(lua_Number, (i)) +#define cast_int(i) cast(int, (i)) +#define cast_uchar(i) cast(unsigned char, (i)) /* ** non-return type */ #if defined(__GNUC__) -#define l_noret void __attribute__((noreturn)) +#define l_noret void __attribute__((noreturn)) #elif defined(_MSC_VER) -#define l_noret void __declspec(noreturn) +#define l_noret void __declspec(noreturn) #else -#define l_noret void +#define l_noret void #endif - - /* ** maximum depth for nested C calls and syntactical nested non-terminals ** in a program. (Value must fit in an unsigned short int.) */ #if !defined(LUAI_MAXCCALLS) -#define LUAI_MAXCCALLS 200 +#define LUAI_MAXCCALLS 200 #endif /* ** maximum number of upvalues in a closure (both C and Lua). (Value ** must fit in an unsigned char.) */ -#define MAXUPVAL UCHAR_MAX - +#define MAXUPVAL UCHAR_MAX /* ** type for virtual-machine instructions @@ -132,62 +123,59 @@ typedef LUAI_UACNUMBER l_uacNumber; */ typedef lu_int32 Instruction; - - /* maximum stack for a Lua function */ -#define MAXSTACK 250 - - +#define MAXSTACK 250 /* minimum size for the string table (must be power of 2) */ #if !defined(MINSTRTABSIZE) -#define MINSTRTABSIZE 32 +#define MINSTRTABSIZE 32 #endif - /* minimum size for string buffer */ #if !defined(LUA_MINBUFFER) -#define LUA_MINBUFFER 32 +#define LUA_MINBUFFER 32 #endif - #if !defined(lua_lock) -#define lua_lock(L) ((void) 0) -#define lua_unlock(L) ((void) 0) +#define lua_lock(L) ((void)0) +#define lua_unlock(L) ((void)0) #endif #if !defined(luai_threadyield) -#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} +#define luai_threadyield(L) \ + { \ + lua_unlock(L); \ + lua_lock(L); \ + } #endif - /* ** these macros allow user-specific actions on threads when you defined ** LUAI_EXTRASPACE and need to do something extra when a thread is ** created/deleted/resumed/yielded. */ #if !defined(luai_userstateopen) -#define luai_userstateopen(L) ((void)L) +#define luai_userstateopen(L) ((void)L) #endif #if !defined(luai_userstateclose) -#define luai_userstateclose(L) ((void)L) +#define luai_userstateclose(L) ((void)L) #endif #if !defined(luai_userstatethread) -#define luai_userstatethread(L,L1) ((void)L) +#define luai_userstatethread(L, L1) ((void)L) #endif #if !defined(luai_userstatefree) -#define luai_userstatefree(L,L1) ((void)L) +#define luai_userstatefree(L, L1) ((void)L) #endif #if !defined(luai_userstateresume) -#define luai_userstateresume(L,n) ((void)L) +#define luai_userstateresume(L, n) ((void)L) #endif #if !defined(luai_userstateyield) -#define luai_userstateyield(L,n) ((void)L) +#define luai_userstateyield(L, n) ((void)L) #endif /* @@ -200,109 +188,120 @@ typedef lu_int32 Instruction; ** both small and large values (outside the range of integers). */ -#if defined(MS_ASMTRICK) || defined(LUA_MSASMTRICK) /* { */ +#if defined(MS_ASMTRICK) || defined(LUA_MSASMTRICK) /* { */ /* trick with Microsoft assembler for X86 */ -#define lua_number2int(i,n) __asm {__asm fld n __asm fistp i} -#define lua_number2integer(i,n) lua_number2int(i, n) -#define lua_number2unsigned(i,n) \ - {__int64 l; __asm {__asm fld n __asm fistp l} i = (unsigned int)l;} +#define lua_number2int(i, n) __asm {__asm fld n __asm fistp i} +#define lua_number2integer(i, n) lua_number2int(i, n) +#define lua_number2unsigned(i, n) \ + { \ + __int64 l; \ + __asm {__asm fld n __asm fistp l} \ + i = (unsigned int)l; \ + } - -#elif defined(LUA_IEEE754TRICK) /* }{ */ +#elif defined(LUA_IEEE754TRICK) /* }{ */ /* the next trick should work on any machine using IEEE754 with a 32-bit int type */ -union luai_Cast { double l_d; LUA_INT32 l_p[2]; }; +union luai_Cast { + double l_d; + LUA_INT32 l_p[2]; +}; -#if !defined(LUA_IEEEENDIAN) /* { */ -#define LUAI_EXTRAIEEE \ - static const union luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)}; -#define LUA_IEEEENDIANLOC (ieeeendian.l_p[1] == 33) +#if !defined(LUA_IEEEENDIAN) /* { */ +#define LUAI_EXTRAIEEE \ + static const union luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)}; +#define LUA_IEEEENDIANLOC (ieeeendian.l_p[1] == 33) #else -#define LUA_IEEEENDIANLOC LUA_IEEEENDIAN -#define LUAI_EXTRAIEEE /* empty */ -#endif /* } */ +#define LUA_IEEEENDIANLOC LUA_IEEEENDIAN +#define LUAI_EXTRAIEEE /* empty */ +#endif /* } */ -#define lua_number2int32(i,n,t) \ - { LUAI_EXTRAIEEE \ - volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; \ - (i) = (t)u.l_p[LUA_IEEEENDIANLOC]; } +#define lua_number2int32(i, n, t) \ + { \ + LUAI_EXTRAIEEE \ + volatile union luai_Cast u; \ + u.l_d = (n) + 6755399441055744.0; \ + (i) = (t)u.l_p[LUA_IEEEENDIANLOC]; \ + } -#define luai_hashnum(i,n) \ - { volatile union luai_Cast u; u.l_d = (n) + 1.0; /* avoid -0 */ \ - (i) = u.l_p[0]; (i) += u.l_p[1]; } /* add double bits for his hash */ +#define luai_hashnum(i, n) \ + { \ + volatile union luai_Cast u; \ + u.l_d = (n) + 1.0; /* avoid -0 */ \ + (i) = u.l_p[0]; \ + (i) += u.l_p[1]; \ + } /* add double bits for his hash */ -#define lua_number2int(i,n) lua_number2int32(i, n, int) -#define lua_number2unsigned(i,n) lua_number2int32(i, n, lua_Unsigned) +#define lua_number2int(i, n) lua_number2int32(i, n, int) +#define lua_number2unsigned(i, n) lua_number2int32(i, n, lua_Unsigned) /* the trick can be expanded to lua_Integer when it is a 32-bit value */ #if defined(LUA_IEEELL) -#define lua_number2integer(i,n) lua_number2int32(i, n, lua_Integer) +#define lua_number2integer(i, n) lua_number2int32(i, n, lua_Integer) #endif -#endif /* } */ - +#endif /* } */ /* the following definitions always work, but may be slow */ #if !defined(lua_number2int) -#define lua_number2int(i,n) ((i)=(int)(n)) +#define lua_number2int(i, n) ((i) = (int)(n)) #endif #if !defined(lua_number2integer) -#define lua_number2integer(i,n) ((i)=(lua_Integer)(n)) +#define lua_number2integer(i, n) ((i) = (lua_Integer)(n)) #endif -#if !defined(lua_number2unsigned) /* { */ +#if !defined(lua_number2unsigned) /* { */ /* the following definition assures proper modulo behavior */ #if defined(LUA_NUMBER_DOUBLE) || defined(LUA_NUMBER_FLOAT) #include -#define SUPUNSIGNED ((lua_Number)(~(lua_Unsigned)0) + 1) -#define lua_number2unsigned(i,n) \ - ((i)=(lua_Unsigned)((n) - floor((n)/SUPUNSIGNED)*SUPUNSIGNED)) +#define SUPUNSIGNED ((lua_Number)(~(lua_Unsigned)0) + 1) +#define lua_number2unsigned(i, n) \ + ((i) = (lua_Unsigned)((n)-floor((n) / SUPUNSIGNED) * SUPUNSIGNED)) #else -#define lua_number2unsigned(i,n) ((i)=(lua_Unsigned)(n)) +#define lua_number2unsigned(i, n) ((i) = (lua_Unsigned)(n)) #endif -#endif /* } */ - +#endif /* } */ #if !defined(lua_unsigned2number) /* on several machines, coercion from unsigned to double is slow, so it may be worth to avoid */ -#define lua_unsigned2number(u) \ - (((u) <= (lua_Unsigned)INT_MAX) ? (lua_Number)(int)(u) : (lua_Number)(u)) +#define lua_unsigned2number(u) \ + (((u) <= (lua_Unsigned)INT_MAX) ? (lua_Number)(int)(u) : (lua_Number)(u)) #endif - - #if defined(ltable_c) && !defined(luai_hashnum) #include #include -#define luai_hashnum(i,n) { int e; \ - n = l_mathop(frexp)(n, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \ - lua_number2int(i, n); i += e; } +#define luai_hashnum(i, n) \ + { \ + int e; \ + n = l_mathop(frexp)(n, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \ + lua_number2int(i, n); \ + i += e; \ + } #endif - - /* ** macro to control inclusion of some hard tests on stack reallocation */ #if !defined(HARDSTACKTESTS) -#define condmovestack(L) ((void)0) +#define condmovestack(L) ((void)0) #else /* realloc stack keeping its size */ -#define condmovestack(L) luaD_reallocstack((L), (L)->stacksize) +#define condmovestack(L) luaD_reallocstack((L), (L)->stacksize) #endif #if !defined(HARDMEMTESTS) -#define condchangemem(L) condmovestack(L) +#define condchangemem(L) condmovestack(L) #else -#define condchangemem(L) \ +#define condchangemem(L) \ ((void)(!(G(L)->gcrunning) || (luaC_fullgc(L, 0), 1))) #endif diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lmathlib.c b/examples/ThirdPartyLibs/lua-5.2.3/src/lmathlib.c index fe9fc5423..501215f29 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lmathlib.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lmathlib.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #include #include @@ -16,264 +15,291 @@ #include "lauxlib.h" #include "lualib.h" - #undef PI -#define PI ((lua_Number)(3.1415926535897932384626433832795)) -#define RADIANS_PER_DEGREE ((lua_Number)(PI/180.0)) +#define PI ((lua_Number)(3.1415926535897932384626433832795)) +#define RADIANS_PER_DEGREE ((lua_Number)(PI / 180.0)) - - -static int math_abs (lua_State *L) { - lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1))); - return 1; +static int math_abs(lua_State *L) +{ + lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1))); + return 1; } -static int math_sin (lua_State *L) { - lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1))); - return 1; +static int math_sin(lua_State *L) +{ + lua_pushnumber(L, l_mathop(sin)(luaL_checknumber(L, 1))); + return 1; } -static int math_sinh (lua_State *L) { - lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1))); - return 1; +static int math_sinh(lua_State *L) +{ + lua_pushnumber(L, l_mathop(sinh)(luaL_checknumber(L, 1))); + return 1; } -static int math_cos (lua_State *L) { - lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1))); - return 1; +static int math_cos(lua_State *L) +{ + lua_pushnumber(L, l_mathop(cos)(luaL_checknumber(L, 1))); + return 1; } -static int math_cosh (lua_State *L) { - lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1))); - return 1; +static int math_cosh(lua_State *L) +{ + lua_pushnumber(L, l_mathop(cosh)(luaL_checknumber(L, 1))); + return 1; } -static int math_tan (lua_State *L) { - lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1))); - return 1; +static int math_tan(lua_State *L) +{ + lua_pushnumber(L, l_mathop(tan)(luaL_checknumber(L, 1))); + return 1; } -static int math_tanh (lua_State *L) { - lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1))); - return 1; +static int math_tanh(lua_State *L) +{ + lua_pushnumber(L, l_mathop(tanh)(luaL_checknumber(L, 1))); + return 1; } -static int math_asin (lua_State *L) { - lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1))); - return 1; +static int math_asin(lua_State *L) +{ + lua_pushnumber(L, l_mathop(asin)(luaL_checknumber(L, 1))); + return 1; } -static int math_acos (lua_State *L) { - lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1))); - return 1; +static int math_acos(lua_State *L) +{ + lua_pushnumber(L, l_mathop(acos)(luaL_checknumber(L, 1))); + return 1; } -static int math_atan (lua_State *L) { - lua_pushnumber(L, l_mathop(atan)(luaL_checknumber(L, 1))); - return 1; +static int math_atan(lua_State *L) +{ + lua_pushnumber(L, l_mathop(atan)(luaL_checknumber(L, 1))); + return 1; } -static int math_atan2 (lua_State *L) { - lua_pushnumber(L, l_mathop(atan2)(luaL_checknumber(L, 1), - luaL_checknumber(L, 2))); - return 1; +static int math_atan2(lua_State *L) +{ + lua_pushnumber(L, l_mathop(atan2)(luaL_checknumber(L, 1), + luaL_checknumber(L, 2))); + return 1; } -static int math_ceil (lua_State *L) { - lua_pushnumber(L, l_mathop(ceil)(luaL_checknumber(L, 1))); - return 1; +static int math_ceil(lua_State *L) +{ + lua_pushnumber(L, l_mathop(ceil)(luaL_checknumber(L, 1))); + return 1; } -static int math_floor (lua_State *L) { - lua_pushnumber(L, l_mathop(floor)(luaL_checknumber(L, 1))); - return 1; +static int math_floor(lua_State *L) +{ + lua_pushnumber(L, l_mathop(floor)(luaL_checknumber(L, 1))); + return 1; } -static int math_fmod (lua_State *L) { - lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1), - luaL_checknumber(L, 2))); - return 1; +static int math_fmod(lua_State *L) +{ + lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1), + luaL_checknumber(L, 2))); + return 1; } -static int math_modf (lua_State *L) { - lua_Number ip; - lua_Number fp = l_mathop(modf)(luaL_checknumber(L, 1), &ip); - lua_pushnumber(L, ip); - lua_pushnumber(L, fp); - return 2; +static int math_modf(lua_State *L) +{ + lua_Number ip; + lua_Number fp = l_mathop(modf)(luaL_checknumber(L, 1), &ip); + lua_pushnumber(L, ip); + lua_pushnumber(L, fp); + return 2; } -static int math_sqrt (lua_State *L) { - lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1))); - return 1; +static int math_sqrt(lua_State *L) +{ + lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1))); + return 1; } -static int math_pow (lua_State *L) { - lua_Number x = luaL_checknumber(L, 1); - lua_Number y = luaL_checknumber(L, 2); - lua_pushnumber(L, l_mathop(pow)(x, y)); - return 1; +static int math_pow(lua_State *L) +{ + lua_Number x = luaL_checknumber(L, 1); + lua_Number y = luaL_checknumber(L, 2); + lua_pushnumber(L, l_mathop(pow)(x, y)); + return 1; } -static int math_log (lua_State *L) { - lua_Number x = luaL_checknumber(L, 1); - lua_Number res; - if (lua_isnoneornil(L, 2)) - res = l_mathop(log)(x); - else { - lua_Number base = luaL_checknumber(L, 2); - if (base == (lua_Number)10.0) res = l_mathop(log10)(x); - else res = l_mathop(log)(x)/l_mathop(log)(base); - } - lua_pushnumber(L, res); - return 1; +static int math_log(lua_State *L) +{ + lua_Number x = luaL_checknumber(L, 1); + lua_Number res; + if (lua_isnoneornil(L, 2)) + res = l_mathop(log)(x); + else + { + lua_Number base = luaL_checknumber(L, 2); + if (base == (lua_Number)10.0) + res = l_mathop(log10)(x); + else + res = l_mathop(log)(x) / l_mathop(log)(base); + } + lua_pushnumber(L, res); + return 1; } #if defined(LUA_COMPAT_LOG10) -static int math_log10 (lua_State *L) { - lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1))); - return 1; +static int math_log10(lua_State *L) +{ + lua_pushnumber(L, l_mathop(log10)(luaL_checknumber(L, 1))); + return 1; } #endif -static int math_exp (lua_State *L) { - lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1))); - return 1; +static int math_exp(lua_State *L) +{ + lua_pushnumber(L, l_mathop(exp)(luaL_checknumber(L, 1))); + return 1; } -static int math_deg (lua_State *L) { - lua_pushnumber(L, luaL_checknumber(L, 1)/RADIANS_PER_DEGREE); - return 1; +static int math_deg(lua_State *L) +{ + lua_pushnumber(L, luaL_checknumber(L, 1) / RADIANS_PER_DEGREE); + return 1; } -static int math_rad (lua_State *L) { - lua_pushnumber(L, luaL_checknumber(L, 1)*RADIANS_PER_DEGREE); - return 1; +static int math_rad(lua_State *L) +{ + lua_pushnumber(L, luaL_checknumber(L, 1) * RADIANS_PER_DEGREE); + return 1; } -static int math_frexp (lua_State *L) { - int e; - lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e)); - lua_pushinteger(L, e); - return 2; +static int math_frexp(lua_State *L) +{ + int e; + lua_pushnumber(L, l_mathop(frexp)(luaL_checknumber(L, 1), &e)); + lua_pushinteger(L, e); + return 2; } -static int math_ldexp (lua_State *L) { - lua_Number x = luaL_checknumber(L, 1); - int ep = luaL_checkint(L, 2); - lua_pushnumber(L, l_mathop(ldexp)(x, ep)); - return 1; +static int math_ldexp(lua_State *L) +{ + lua_Number x = luaL_checknumber(L, 1); + int ep = luaL_checkint(L, 2); + lua_pushnumber(L, l_mathop(ldexp)(x, ep)); + return 1; } - - -static int math_min (lua_State *L) { - int n = lua_gettop(L); /* number of arguments */ - lua_Number dmin = luaL_checknumber(L, 1); - int i; - for (i=2; i<=n; i++) { - lua_Number d = luaL_checknumber(L, i); - if (d < dmin) - dmin = d; - } - lua_pushnumber(L, dmin); - return 1; +static int math_min(lua_State *L) +{ + int n = lua_gettop(L); /* number of arguments */ + lua_Number dmin = luaL_checknumber(L, 1); + int i; + for (i = 2; i <= n; i++) + { + lua_Number d = luaL_checknumber(L, i); + if (d < dmin) + dmin = d; + } + lua_pushnumber(L, dmin); + return 1; } - -static int math_max (lua_State *L) { - int n = lua_gettop(L); /* number of arguments */ - lua_Number dmax = luaL_checknumber(L, 1); - int i; - for (i=2; i<=n; i++) { - lua_Number d = luaL_checknumber(L, i); - if (d > dmax) - dmax = d; - } - lua_pushnumber(L, dmax); - return 1; +static int math_max(lua_State *L) +{ + int n = lua_gettop(L); /* number of arguments */ + lua_Number dmax = luaL_checknumber(L, 1); + int i; + for (i = 2; i <= n; i++) + { + lua_Number d = luaL_checknumber(L, i); + if (d > dmax) + dmax = d; + } + lua_pushnumber(L, dmax); + return 1; } - -static int math_random (lua_State *L) { - /* the `%' avoids the (rare) case of r==1, and is needed also because on +static int math_random(lua_State *L) +{ + /* the `%' avoids the (rare) case of r==1, and is needed also because on some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */ - lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX; - switch (lua_gettop(L)) { /* check number of arguments */ - case 0: { /* no arguments */ - lua_pushnumber(L, r); /* Number between 0 and 1 */ - break; - } - case 1: { /* only upper limit */ - lua_Number u = luaL_checknumber(L, 1); - luaL_argcheck(L, (lua_Number)1.0 <= u, 1, "interval is empty"); - lua_pushnumber(L, l_mathop(floor)(r*u) + (lua_Number)(1.0)); /* [1, u] */ - break; - } - case 2: { /* lower and upper limits */ - lua_Number l = luaL_checknumber(L, 1); - lua_Number u = luaL_checknumber(L, 2); - luaL_argcheck(L, l <= u, 2, "interval is empty"); - lua_pushnumber(L, l_mathop(floor)(r*(u-l+1)) + l); /* [l, u] */ - break; - } - default: return luaL_error(L, "wrong number of arguments"); - } - return 1; + lua_Number r = (lua_Number)(rand() % RAND_MAX) / (lua_Number)RAND_MAX; + switch (lua_gettop(L)) + { /* check number of arguments */ + case 0: + { /* no arguments */ + lua_pushnumber(L, r); /* Number between 0 and 1 */ + break; + } + case 1: + { /* only upper limit */ + lua_Number u = luaL_checknumber(L, 1); + luaL_argcheck(L, (lua_Number)1.0 <= u, 1, "interval is empty"); + lua_pushnumber(L, l_mathop(floor)(r * u) + (lua_Number)(1.0)); /* [1, u] */ + break; + } + case 2: + { /* lower and upper limits */ + lua_Number l = luaL_checknumber(L, 1); + lua_Number u = luaL_checknumber(L, 2); + luaL_argcheck(L, l <= u, 2, "interval is empty"); + lua_pushnumber(L, l_mathop(floor)(r * (u - l + 1)) + l); /* [l, u] */ + break; + } + default: + return luaL_error(L, "wrong number of arguments"); + } + return 1; } - -static int math_randomseed (lua_State *L) { - srand(luaL_checkunsigned(L, 1)); - (void)rand(); /* discard first value to avoid undesirable correlations */ - return 0; +static int math_randomseed(lua_State *L) +{ + srand(luaL_checkunsigned(L, 1)); + (void)rand(); /* discard first value to avoid undesirable correlations */ + return 0; } - static const luaL_Reg mathlib[] = { - {"abs", math_abs}, - {"acos", math_acos}, - {"asin", math_asin}, - {"atan2", math_atan2}, - {"atan", math_atan}, - {"ceil", math_ceil}, - {"cosh", math_cosh}, - {"cos", math_cos}, - {"deg", math_deg}, - {"exp", math_exp}, - {"floor", math_floor}, - {"fmod", math_fmod}, - {"frexp", math_frexp}, - {"ldexp", math_ldexp}, + {"abs", math_abs}, + {"acos", math_acos}, + {"asin", math_asin}, + {"atan2", math_atan2}, + {"atan", math_atan}, + {"ceil", math_ceil}, + {"cosh", math_cosh}, + {"cos", math_cos}, + {"deg", math_deg}, + {"exp", math_exp}, + {"floor", math_floor}, + {"fmod", math_fmod}, + {"frexp", math_frexp}, + {"ldexp", math_ldexp}, #if defined(LUA_COMPAT_LOG10) - {"log10", math_log10}, + {"log10", math_log10}, #endif - {"log", math_log}, - {"max", math_max}, - {"min", math_min}, - {"modf", math_modf}, - {"pow", math_pow}, - {"rad", math_rad}, - {"random", math_random}, - {"randomseed", math_randomseed}, - {"sinh", math_sinh}, - {"sin", math_sin}, - {"sqrt", math_sqrt}, - {"tanh", math_tanh}, - {"tan", math_tan}, - {NULL, NULL} -}; - + {"log", math_log}, + {"max", math_max}, + {"min", math_min}, + {"modf", math_modf}, + {"pow", math_pow}, + {"rad", math_rad}, + {"random", math_random}, + {"randomseed", math_randomseed}, + {"sinh", math_sinh}, + {"sin", math_sin}, + {"sqrt", math_sqrt}, + {"tanh", math_tanh}, + {"tan", math_tan}, + {NULL, NULL}}; /* ** Open math library */ -LUAMOD_API int luaopen_math (lua_State *L) { - luaL_newlib(L, mathlib); - lua_pushnumber(L, PI); - lua_setfield(L, -2, "pi"); - lua_pushnumber(L, HUGE_VAL); - lua_setfield(L, -2, "huge"); - return 1; +LUAMOD_API int luaopen_math(lua_State *L) +{ + luaL_newlib(L, mathlib); + lua_pushnumber(L, PI); + lua_setfield(L, -2, "pi"); + lua_pushnumber(L, HUGE_VAL); + lua_setfield(L, -2, "huge"); + return 1; } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lmem.c b/examples/ThirdPartyLibs/lua-5.2.3/src/lmem.c index ee343e3e0..5600f7165 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lmem.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lmem.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #include #define lmem_c @@ -19,8 +18,6 @@ #include "lobject.h" #include "lstate.h" - - /* ** About the realloc function: ** void * frealloc (void *ud, void *ptr, size_t osize, size_t nsize); @@ -38,62 +35,62 @@ ** (any reallocation to an equal or smaller size cannot fail!) */ +#define MINSIZEARRAY 4 - -#define MINSIZEARRAY 4 - - -void *luaM_growaux_ (lua_State *L, void *block, int *size, size_t size_elems, - int limit, const char *what) { - void *newblock; - int newsize; - if (*size >= limit/2) { /* cannot double it? */ - if (*size >= limit) /* cannot grow even a little? */ - luaG_runerror(L, "too many %s (limit is %d)", what, limit); - newsize = limit; /* still have at least one free place */ - } - else { - newsize = (*size)*2; - if (newsize < MINSIZEARRAY) - newsize = MINSIZEARRAY; /* minimum size */ - } - newblock = luaM_reallocv(L, block, *size, newsize, size_elems); - *size = newsize; /* update only when everything else is OK */ - return newblock; +void *luaM_growaux_(lua_State *L, void *block, int *size, size_t size_elems, + int limit, const char *what) +{ + void *newblock; + int newsize; + if (*size >= limit / 2) + { /* cannot double it? */ + if (*size >= limit) /* cannot grow even a little? */ + luaG_runerror(L, "too many %s (limit is %d)", what, limit); + newsize = limit; /* still have at least one free place */ + } + else + { + newsize = (*size) * 2; + if (newsize < MINSIZEARRAY) + newsize = MINSIZEARRAY; /* minimum size */ + } + newblock = luaM_reallocv(L, block, *size, newsize, size_elems); + *size = newsize; /* update only when everything else is OK */ + return newblock; } - -l_noret luaM_toobig (lua_State *L) { - luaG_runerror(L, "memory allocation error: block too big"); +l_noret luaM_toobig(lua_State *L) +{ + luaG_runerror(L, "memory allocation error: block too big"); } - - /* ** generic allocation routine. */ -void *luaM_realloc_ (lua_State *L, void *block, size_t osize, size_t nsize) { - void *newblock; - global_State *g = G(L); - size_t realosize = (block) ? osize : 0; - lua_assert((realosize == 0) == (block == NULL)); +void *luaM_realloc_(lua_State *L, void *block, size_t osize, size_t nsize) +{ + void *newblock; + global_State *g = G(L); + size_t realosize = (block) ? osize : 0; + lua_assert((realosize == 0) == (block == NULL)); #if defined(HARDMEMTESTS) - if (nsize > realosize && g->gcrunning) - luaC_fullgc(L, 1); /* force a GC whenever possible */ + if (nsize > realosize && g->gcrunning) + luaC_fullgc(L, 1); /* force a GC whenever possible */ #endif - newblock = (*g->frealloc)(g->ud, block, osize, nsize); - if (newblock == NULL && nsize > 0) { - api_check(L, nsize > realosize, - "realloc cannot fail when shrinking a block"); - if (g->gcrunning) { - luaC_fullgc(L, 1); /* try to free some memory... */ - newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ - } - if (newblock == NULL) - luaD_throw(L, LUA_ERRMEM); - } - lua_assert((nsize == 0) == (newblock == NULL)); - g->GCdebt = (g->GCdebt + nsize) - realosize; - return newblock; + newblock = (*g->frealloc)(g->ud, block, osize, nsize); + if (newblock == NULL && nsize > 0) + { + api_check(L, nsize > realosize, + "realloc cannot fail when shrinking a block"); + if (g->gcrunning) + { + luaC_fullgc(L, 1); /* try to free some memory... */ + newblock = (*g->frealloc)(g->ud, block, osize, nsize); /* try again */ + } + if (newblock == NULL) + luaD_throw(L, LUA_ERRMEM); + } + lua_assert((nsize == 0) == (newblock == NULL)); + g->GCdebt = (g->GCdebt + nsize) - realosize; + return newblock; } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lmem.h b/examples/ThirdPartyLibs/lua-5.2.3/src/lmem.h index bd4f4e072..6c176f99e 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lmem.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lmem.h @@ -7,13 +7,11 @@ #ifndef lmem_h #define lmem_h - #include #include "llimits.h" #include "lua.h" - /* ** This macro avoids the runtime division MAX_SIZET/(e), as 'e' is ** always constant. @@ -21,37 +19,36 @@ ** +1 avoids warnings of "comparison has constant result"; ** cast to 'void' avoids warnings of "value unused". */ -#define luaM_reallocv(L,b,on,n,e) \ - (cast(void, \ - (cast(size_t, (n)+1) > MAX_SIZET/(e)) ? (luaM_toobig(L), 0) : 0), \ - luaM_realloc_(L, (b), (on)*(e), (n)*(e))) +#define luaM_reallocv(L, b, on, n, e) \ + (cast(void, \ + (cast(size_t, (n) + 1) > MAX_SIZET / (e)) ? (luaM_toobig(L), 0) : 0), \ + luaM_realloc_(L, (b), (on) * (e), (n) * (e))) -#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) -#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) -#define luaM_freearray(L, b, n) luaM_reallocv(L, (b), n, 0, sizeof((b)[0])) +#define luaM_freemem(L, b, s) luaM_realloc_(L, (b), (s), 0) +#define luaM_free(L, b) luaM_realloc_(L, (b), sizeof(*(b)), 0) +#define luaM_freearray(L, b, n) luaM_reallocv(L, (b), n, 0, sizeof((b)[0])) -#define luaM_malloc(L,s) luaM_realloc_(L, NULL, 0, (s)) -#define luaM_new(L,t) cast(t *, luaM_malloc(L, sizeof(t))) -#define luaM_newvector(L,n,t) \ - cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) +#define luaM_malloc(L, s) luaM_realloc_(L, NULL, 0, (s)) +#define luaM_new(L, t) cast(t *, luaM_malloc(L, sizeof(t))) +#define luaM_newvector(L, n, t) \ + cast(t *, luaM_reallocv(L, NULL, 0, n, sizeof(t))) -#define luaM_newobject(L,tag,s) luaM_realloc_(L, NULL, tag, (s)) +#define luaM_newobject(L, tag, s) luaM_realloc_(L, NULL, tag, (s)) -#define luaM_growvector(L,v,nelems,size,t,limit,e) \ - if ((nelems)+1 > (size)) \ - ((v)=cast(t *, luaM_growaux_(L,v,&(size),sizeof(t),limit,e))) +#define luaM_growvector(L, v, nelems, size, t, limit, e) \ + if ((nelems) + 1 > (size)) \ + ((v) = cast(t *, luaM_growaux_(L, v, &(size), sizeof(t), limit, e))) -#define luaM_reallocvector(L, v,oldn,n,t) \ - ((v)=cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) +#define luaM_reallocvector(L, v, oldn, n, t) \ + ((v) = cast(t *, luaM_reallocv(L, v, oldn, n, sizeof(t)))) -LUAI_FUNC l_noret luaM_toobig (lua_State *L); +LUAI_FUNC l_noret luaM_toobig(lua_State *L); /* not to be called directly */ -LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, - size_t size); -LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int *size, - size_t size_elem, int limit, - const char *what); +LUAI_FUNC void *luaM_realloc_(lua_State *L, void *block, size_t oldsize, + size_t size); +LUAI_FUNC void *luaM_growaux_(lua_State *L, void *block, int *size, + size_t size_elem, int limit, + const char *what); #endif - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/loadlib.c b/examples/ThirdPartyLibs/lua-5.2.3/src/loadlib.c index 9318a9980..623b17e77 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/loadlib.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/loadlib.c @@ -8,7 +8,6 @@ ** systems. */ - /* ** if needed, includes windows header before everything else */ @@ -16,11 +15,9 @@ #include #endif - #include #include - #define loadlib_c #define LUA_LIB @@ -29,23 +26,22 @@ #include "lauxlib.h" #include "lualib.h" - /* ** LUA_PATH and LUA_CPATH are the names of the environment ** variables that Lua check to set its paths. */ #if !defined(LUA_PATH) -#define LUA_PATH "LUA_PATH" +#define LUA_PATH "LUA_PATH" #endif #if !defined(LUA_CPATH) -#define LUA_CPATH "LUA_CPATH" +#define LUA_CPATH "LUA_CPATH" #endif -#define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR +#define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR -#define LUA_PATHVERSION LUA_PATH LUA_PATHSUFFIX -#define LUA_CPATHVERSION LUA_CPATH LUA_PATHSUFFIX +#define LUA_PATHVERSION LUA_PATH LUA_PATHSUFFIX +#define LUA_CPATHVERSION LUA_CPATH LUA_PATHSUFFIX /* ** LUA_PATH_SEP is the character that separates templates in a path. @@ -56,20 +52,19 @@ ** LUA_IGMARK is a mark to ignore all before it when building the ** luaopen_ function name. */ -#if !defined (LUA_PATH_SEP) -#define LUA_PATH_SEP ";" +#if !defined(LUA_PATH_SEP) +#define LUA_PATH_SEP ";" #endif -#if !defined (LUA_PATH_MARK) -#define LUA_PATH_MARK "?" +#if !defined(LUA_PATH_MARK) +#define LUA_PATH_MARK "?" #endif -#if !defined (LUA_EXEC_DIR) -#define LUA_EXEC_DIR "!" +#if !defined(LUA_EXEC_DIR) +#define LUA_EXEC_DIR "!" #endif -#if !defined (LUA_IGMARK) -#define LUA_IGMARK "-" +#if !defined(LUA_IGMARK) +#define LUA_IGMARK "-" #endif - /* ** LUA_CSUBSEP is the character that replaces dots in submodule names ** when searching for a C loader. @@ -77,42 +72,36 @@ ** when searching for a Lua loader. */ #if !defined(LUA_CSUBSEP) -#define LUA_CSUBSEP LUA_DIRSEP +#define LUA_CSUBSEP LUA_DIRSEP #endif #if !defined(LUA_LSUBSEP) -#define LUA_LSUBSEP LUA_DIRSEP +#define LUA_LSUBSEP LUA_DIRSEP #endif - /* prefix for open functions in C libraries */ -#define LUA_POF "luaopen_" +#define LUA_POF "luaopen_" /* separator for open functions in C libraries */ -#define LUA_OFSEP "_" - +#define LUA_OFSEP "_" /* table (in the registry) that keeps handles for all loaded C libraries */ -#define CLIBS "_CLIBS" - -#define LIB_FAIL "open" +#define CLIBS "_CLIBS" +#define LIB_FAIL "open" /* error codes for ll_loadfunc */ -#define ERRLIB 1 -#define ERRFUNC 2 - -#define setprogdir(L) ((void)0) +#define ERRLIB 1 +#define ERRFUNC 2 +#define setprogdir(L) ((void)0) /* ** system-dependent functions */ -static void ll_unloadlib (void *lib); -static void *ll_load (lua_State *L, const char *path, int seeglb); -static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); - - +static void ll_unloadlib(void *lib); +static void *ll_load(lua_State *L, const char *path, int seeglb); +static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym); #if defined(LUA_USE_DLOPEN) @@ -127,28 +116,27 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); #include -static void ll_unloadlib (void *lib) { - dlclose(lib); +static void ll_unloadlib(void *lib) +{ + dlclose(lib); } - -static void *ll_load (lua_State *L, const char *path, int seeglb) { - void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL)); - if (lib == NULL) lua_pushstring(L, dlerror()); - return lib; +static void *ll_load(lua_State *L, const char *path, int seeglb) +{ + void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL)); + if (lib == NULL) lua_pushstring(L, dlerror()); + return lib; } - -static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { - lua_CFunction f = (lua_CFunction)dlsym(lib, sym); - if (f == NULL) lua_pushstring(L, dlerror()); - return f; +static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym) +{ + lua_CFunction f = (lua_CFunction)dlsym(lib, sym); + if (f == NULL) lua_pushstring(L, dlerror()); + return f; } /* }====================================================== */ - - #elif defined(LUA_DL_DLL) /* ** {====================================================================== @@ -162,57 +150,58 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { ** optional flags for LoadLibraryEx */ #if !defined(LUA_LLE_FLAGS) -#define LUA_LLE_FLAGS 0 +#define LUA_LLE_FLAGS 0 #endif - -static void setprogdir (lua_State *L) { - char buff[MAX_PATH + 1]; - char *lb; - DWORD nsize = sizeof(buff)/sizeof(char); - DWORD n = GetModuleFileNameA(NULL, buff, nsize); - if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) - luaL_error(L, "unable to get ModuleFileName"); - else { - *lb = '\0'; - luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff); - lua_remove(L, -2); /* remove original string */ - } +static void setprogdir(lua_State *L) +{ + char buff[MAX_PATH + 1]; + char *lb; + DWORD nsize = sizeof(buff) / sizeof(char); + DWORD n = GetModuleFileNameA(NULL, buff, nsize); + if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) + luaL_error(L, "unable to get ModuleFileName"); + else + { + *lb = '\0'; + luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff); + lua_remove(L, -2); /* remove original string */ + } } - -static void pusherror (lua_State *L) { - int error = GetLastError(); - char buffer[128]; - if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL)) - lua_pushstring(L, buffer); - else - lua_pushfstring(L, "system error %d\n", error); +static void pusherror(lua_State *L) +{ + int error = GetLastError(); + char buffer[128]; + if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, error, 0, buffer, sizeof(buffer) / sizeof(char), NULL)) + lua_pushstring(L, buffer); + else + lua_pushfstring(L, "system error %d\n", error); } -static void ll_unloadlib (void *lib) { - FreeLibrary((HMODULE)lib); +static void ll_unloadlib(void *lib) +{ + FreeLibrary((HMODULE)lib); } - -static void *ll_load (lua_State *L, const char *path, int seeglb) { - HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS); - (void)(seeglb); /* not used: symbols are 'global' by default */ - if (lib == NULL) pusherror(L); - return lib; +static void *ll_load(lua_State *L, const char *path, int seeglb) +{ + HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS); + (void)(seeglb); /* not used: symbols are 'global' by default */ + if (lib == NULL) pusherror(L); + return lib; } - -static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { - lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym); - if (f == NULL) pusherror(L); - return f; +static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym) +{ + lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym); + if (f == NULL) pusherror(L); + return f; } /* }====================================================== */ - #else /* ** {====================================================== @@ -221,319 +210,331 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { */ #undef LIB_FAIL -#define LIB_FAIL "absent" +#define LIB_FAIL "absent" +#define DLMSG "dynamic libraries not enabled; check your Lua installation" -#define DLMSG "dynamic libraries not enabled; check your Lua installation" - - -static void ll_unloadlib (void *lib) { - (void)(lib); /* not used */ +static void ll_unloadlib(void *lib) +{ + (void)(lib); /* not used */ } - -static void *ll_load (lua_State *L, const char *path, int seeglb) { - (void)(path); (void)(seeglb); /* not used */ - lua_pushliteral(L, DLMSG); - return NULL; +static void *ll_load(lua_State *L, const char *path, int seeglb) +{ + (void)(path); + (void)(seeglb); /* not used */ + lua_pushliteral(L, DLMSG); + return NULL; } - -static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { - (void)(lib); (void)(sym); /* not used */ - lua_pushliteral(L, DLMSG); - return NULL; +static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym) +{ + (void)(lib); + (void)(sym); /* not used */ + lua_pushliteral(L, DLMSG); + return NULL; } /* }====================================================== */ #endif - -static void *ll_checkclib (lua_State *L, const char *path) { - void *plib; - lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); - lua_getfield(L, -1, path); - plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */ - lua_pop(L, 2); /* pop CLIBS table and 'plib' */ - return plib; +static void *ll_checkclib(lua_State *L, const char *path) +{ + void *plib; + lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); + lua_getfield(L, -1, path); + plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */ + lua_pop(L, 2); /* pop CLIBS table and 'plib' */ + return plib; } - -static void ll_addtoclib (lua_State *L, const char *path, void *plib) { - lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); - lua_pushlightuserdata(L, plib); - lua_pushvalue(L, -1); - lua_setfield(L, -3, path); /* CLIBS[path] = plib */ - lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */ - lua_pop(L, 1); /* pop CLIBS table */ +static void ll_addtoclib(lua_State *L, const char *path, void *plib) +{ + lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); + lua_pushlightuserdata(L, plib); + lua_pushvalue(L, -1); + lua_setfield(L, -3, path); /* CLIBS[path] = plib */ + lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */ + lua_pop(L, 1); /* pop CLIBS table */ } - /* ** __gc tag method for CLIBS table: calls 'll_unloadlib' for all lib ** handles in list CLIBS */ -static int gctm (lua_State *L) { - int n = luaL_len(L, 1); - for (; n >= 1; n--) { /* for each handle, in reverse order */ - lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */ - ll_unloadlib(lua_touserdata(L, -1)); - lua_pop(L, 1); /* pop handle */ - } - return 0; +static int gctm(lua_State *L) +{ + int n = luaL_len(L, 1); + for (; n >= 1; n--) + { /* for each handle, in reverse order */ + lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */ + ll_unloadlib(lua_touserdata(L, -1)); + lua_pop(L, 1); /* pop handle */ + } + return 0; } - -static int ll_loadfunc (lua_State *L, const char *path, const char *sym) { - void *reg = ll_checkclib(L, path); /* check loaded C libraries */ - if (reg == NULL) { /* must load library? */ - reg = ll_load(L, path, *sym == '*'); - if (reg == NULL) return ERRLIB; /* unable to load library */ - ll_addtoclib(L, path, reg); - } - if (*sym == '*') { /* loading only library (no function)? */ - lua_pushboolean(L, 1); /* return 'true' */ - return 0; /* no errors */ - } - else { - lua_CFunction f = ll_sym(L, reg, sym); - if (f == NULL) - return ERRFUNC; /* unable to find function */ - lua_pushcfunction(L, f); /* else create new function */ - return 0; /* no errors */ - } +static int ll_loadfunc(lua_State *L, const char *path, const char *sym) +{ + void *reg = ll_checkclib(L, path); /* check loaded C libraries */ + if (reg == NULL) + { /* must load library? */ + reg = ll_load(L, path, *sym == '*'); + if (reg == NULL) return ERRLIB; /* unable to load library */ + ll_addtoclib(L, path, reg); + } + if (*sym == '*') + { /* loading only library (no function)? */ + lua_pushboolean(L, 1); /* return 'true' */ + return 0; /* no errors */ + } + else + { + lua_CFunction f = ll_sym(L, reg, sym); + if (f == NULL) + return ERRFUNC; /* unable to find function */ + lua_pushcfunction(L, f); /* else create new function */ + return 0; /* no errors */ + } } - -static int ll_loadlib (lua_State *L) { - const char *path = luaL_checkstring(L, 1); - const char *init = luaL_checkstring(L, 2); - int stat = ll_loadfunc(L, path, init); - if (stat == 0) /* no errors? */ - return 1; /* return the loaded function */ - else { /* error; error message is on stack top */ - lua_pushnil(L); - lua_insert(L, -2); - lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); - return 3; /* return nil, error message, and where */ - } +static int ll_loadlib(lua_State *L) +{ + const char *path = luaL_checkstring(L, 1); + const char *init = luaL_checkstring(L, 2); + int stat = ll_loadfunc(L, path, init); + if (stat == 0) /* no errors? */ + return 1; /* return the loaded function */ + else + { /* error; error message is on stack top */ + lua_pushnil(L); + lua_insert(L, -2); + lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); + return 3; /* return nil, error message, and where */ + } } - - /* ** {====================================================== ** 'require' function ** ======================================================= */ - -static int readable (const char *filename) { - FILE *f = fopen(filename, "r"); /* try to open file */ - if (f == NULL) return 0; /* open failed */ - fclose(f); - return 1; +static int readable(const char *filename) +{ + FILE *f = fopen(filename, "r"); /* try to open file */ + if (f == NULL) return 0; /* open failed */ + fclose(f); + return 1; } - -static const char *pushnexttemplate (lua_State *L, const char *path) { - const char *l; - while (*path == *LUA_PATH_SEP) path++; /* skip separators */ - if (*path == '\0') return NULL; /* no more templates */ - l = strchr(path, *LUA_PATH_SEP); /* find next separator */ - if (l == NULL) l = path + strlen(path); - lua_pushlstring(L, path, l - path); /* template */ - return l; +static const char *pushnexttemplate(lua_State *L, const char *path) +{ + const char *l; + while (*path == *LUA_PATH_SEP) path++; /* skip separators */ + if (*path == '\0') return NULL; /* no more templates */ + l = strchr(path, *LUA_PATH_SEP); /* find next separator */ + if (l == NULL) l = path + strlen(path); + lua_pushlstring(L, path, l - path); /* template */ + return l; } - -static const char *searchpath (lua_State *L, const char *name, - const char *path, - const char *sep, - const char *dirsep) { - luaL_Buffer msg; /* to build error message */ - luaL_buffinit(L, &msg); - if (*sep != '\0') /* non-empty separator? */ - name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */ - while ((path = pushnexttemplate(L, path)) != NULL) { - const char *filename = luaL_gsub(L, lua_tostring(L, -1), - LUA_PATH_MARK, name); - lua_remove(L, -2); /* remove path template */ - if (readable(filename)) /* does file exist and is readable? */ - return filename; /* return that file name */ - lua_pushfstring(L, "\n\tno file " LUA_QS, filename); - lua_remove(L, -2); /* remove file name */ - luaL_addvalue(&msg); /* concatenate error msg. entry */ - } - luaL_pushresult(&msg); /* create error message */ - return NULL; /* not found */ +static const char *searchpath(lua_State *L, const char *name, + const char *path, + const char *sep, + const char *dirsep) +{ + luaL_Buffer msg; /* to build error message */ + luaL_buffinit(L, &msg); + if (*sep != '\0') /* non-empty separator? */ + name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */ + while ((path = pushnexttemplate(L, path)) != NULL) + { + const char *filename = luaL_gsub(L, lua_tostring(L, -1), + LUA_PATH_MARK, name); + lua_remove(L, -2); /* remove path template */ + if (readable(filename)) /* does file exist and is readable? */ + return filename; /* return that file name */ + lua_pushfstring(L, "\n\tno file " LUA_QS, filename); + lua_remove(L, -2); /* remove file name */ + luaL_addvalue(&msg); /* concatenate error msg. entry */ + } + luaL_pushresult(&msg); /* create error message */ + return NULL; /* not found */ } - -static int ll_searchpath (lua_State *L) { - const char *f = searchpath(L, luaL_checkstring(L, 1), - luaL_checkstring(L, 2), - luaL_optstring(L, 3, "."), - luaL_optstring(L, 4, LUA_DIRSEP)); - if (f != NULL) return 1; - else { /* error message is on top of the stack */ - lua_pushnil(L); - lua_insert(L, -2); - return 2; /* return nil + error message */ - } +static int ll_searchpath(lua_State *L) +{ + const char *f = searchpath(L, luaL_checkstring(L, 1), + luaL_checkstring(L, 2), + luaL_optstring(L, 3, "."), + luaL_optstring(L, 4, LUA_DIRSEP)); + if (f != NULL) + return 1; + else + { /* error message is on top of the stack */ + lua_pushnil(L); + lua_insert(L, -2); + return 2; /* return nil + error message */ + } } - -static const char *findfile (lua_State *L, const char *name, - const char *pname, - const char *dirsep) { - const char *path; - lua_getfield(L, lua_upvalueindex(1), pname); - path = lua_tostring(L, -1); - if (path == NULL) - luaL_error(L, LUA_QL("package.%s") " must be a string", pname); - return searchpath(L, name, path, ".", dirsep); +static const char *findfile(lua_State *L, const char *name, + const char *pname, + const char *dirsep) +{ + const char *path; + lua_getfield(L, lua_upvalueindex(1), pname); + path = lua_tostring(L, -1); + if (path == NULL) + luaL_error(L, LUA_QL("package.%s") " must be a string", pname); + return searchpath(L, name, path, ".", dirsep); } - -static int checkload (lua_State *L, int stat, const char *filename) { - if (stat) { /* module loaded successfully? */ - lua_pushstring(L, filename); /* will be 2nd argument to module */ - return 2; /* return open function and file name */ - } - else - return luaL_error(L, "error loading module " LUA_QS - " from file " LUA_QS ":\n\t%s", - lua_tostring(L, 1), filename, lua_tostring(L, -1)); +static int checkload(lua_State *L, int stat, const char *filename) +{ + if (stat) + { /* module loaded successfully? */ + lua_pushstring(L, filename); /* will be 2nd argument to module */ + return 2; /* return open function and file name */ + } + else + return luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s", + lua_tostring(L, 1), filename, lua_tostring(L, -1)); } - -static int searcher_Lua (lua_State *L) { - const char *filename; - const char *name = luaL_checkstring(L, 1); - filename = findfile(L, name, "path", LUA_LSUBSEP); - if (filename == NULL) return 1; /* module not found in this path */ - return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename); +static int searcher_Lua(lua_State *L) +{ + const char *filename; + const char *name = luaL_checkstring(L, 1); + filename = findfile(L, name, "path", LUA_LSUBSEP); + if (filename == NULL) return 1; /* module not found in this path */ + return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename); } - -static int loadfunc (lua_State *L, const char *filename, const char *modname) { - const char *funcname; - const char *mark; - modname = luaL_gsub(L, modname, ".", LUA_OFSEP); - mark = strchr(modname, *LUA_IGMARK); - if (mark) { - int stat; - funcname = lua_pushlstring(L, modname, mark - modname); - funcname = lua_pushfstring(L, LUA_POF"%s", funcname); - stat = ll_loadfunc(L, filename, funcname); - if (stat != ERRFUNC) return stat; - modname = mark + 1; /* else go ahead and try old-style name */ - } - funcname = lua_pushfstring(L, LUA_POF"%s", modname); - return ll_loadfunc(L, filename, funcname); +static int loadfunc(lua_State *L, const char *filename, const char *modname) +{ + const char *funcname; + const char *mark; + modname = luaL_gsub(L, modname, ".", LUA_OFSEP); + mark = strchr(modname, *LUA_IGMARK); + if (mark) + { + int stat; + funcname = lua_pushlstring(L, modname, mark - modname); + funcname = lua_pushfstring(L, LUA_POF "%s", funcname); + stat = ll_loadfunc(L, filename, funcname); + if (stat != ERRFUNC) return stat; + modname = mark + 1; /* else go ahead and try old-style name */ + } + funcname = lua_pushfstring(L, LUA_POF "%s", modname); + return ll_loadfunc(L, filename, funcname); } - -static int searcher_C (lua_State *L) { - const char *name = luaL_checkstring(L, 1); - const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP); - if (filename == NULL) return 1; /* module not found in this path */ - return checkload(L, (loadfunc(L, filename, name) == 0), filename); +static int searcher_C(lua_State *L) +{ + const char *name = luaL_checkstring(L, 1); + const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP); + if (filename == NULL) return 1; /* module not found in this path */ + return checkload(L, (loadfunc(L, filename, name) == 0), filename); } - -static int searcher_Croot (lua_State *L) { - const char *filename; - const char *name = luaL_checkstring(L, 1); - const char *p = strchr(name, '.'); - int stat; - if (p == NULL) return 0; /* is root */ - lua_pushlstring(L, name, p - name); - filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP); - if (filename == NULL) return 1; /* root not found */ - if ((stat = loadfunc(L, filename, name)) != 0) { - if (stat != ERRFUNC) - return checkload(L, 0, filename); /* real error */ - else { /* open function not found */ - lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, - name, filename); - return 1; - } - } - lua_pushstring(L, filename); /* will be 2nd argument to module */ - return 2; +static int searcher_Croot(lua_State *L) +{ + const char *filename; + const char *name = luaL_checkstring(L, 1); + const char *p = strchr(name, '.'); + int stat; + if (p == NULL) return 0; /* is root */ + lua_pushlstring(L, name, p - name); + filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP); + if (filename == NULL) return 1; /* root not found */ + if ((stat = loadfunc(L, filename, name)) != 0) + { + if (stat != ERRFUNC) + return checkload(L, 0, filename); /* real error */ + else + { /* open function not found */ + lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, + name, filename); + return 1; + } + } + lua_pushstring(L, filename); /* will be 2nd argument to module */ + return 2; } - -static int searcher_preload (lua_State *L) { - const char *name = luaL_checkstring(L, 1); - lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); - lua_getfield(L, -1, name); - if (lua_isnil(L, -1)) /* not found? */ - lua_pushfstring(L, "\n\tno field package.preload['%s']", name); - return 1; +static int searcher_preload(lua_State *L) +{ + const char *name = luaL_checkstring(L, 1); + lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); + lua_getfield(L, -1, name); + if (lua_isnil(L, -1)) /* not found? */ + lua_pushfstring(L, "\n\tno field package.preload['%s']", name); + return 1; } - -static void findloader (lua_State *L, const char *name) { - int i; - luaL_Buffer msg; /* to build error message */ - luaL_buffinit(L, &msg); - lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */ - if (!lua_istable(L, 3)) - luaL_error(L, LUA_QL("package.searchers") " must be a table"); - /* iterate over available searchers to find a loader */ - for (i = 1; ; i++) { - lua_rawgeti(L, 3, i); /* get a searcher */ - if (lua_isnil(L, -1)) { /* no more searchers? */ - lua_pop(L, 1); /* remove nil */ - luaL_pushresult(&msg); /* create error message */ - luaL_error(L, "module " LUA_QS " not found:%s", - name, lua_tostring(L, -1)); - } - lua_pushstring(L, name); - lua_call(L, 1, 2); /* call it */ - if (lua_isfunction(L, -2)) /* did it find a loader? */ - return; /* module loader found */ - else if (lua_isstring(L, -2)) { /* searcher returned error message? */ - lua_pop(L, 1); /* remove extra return */ - luaL_addvalue(&msg); /* concatenate error message */ - } - else - lua_pop(L, 2); /* remove both returns */ - } +static void findloader(lua_State *L, const char *name) +{ + int i; + luaL_Buffer msg; /* to build error message */ + luaL_buffinit(L, &msg); + lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */ + if (!lua_istable(L, 3)) + luaL_error(L, LUA_QL("package.searchers") " must be a table"); + /* iterate over available searchers to find a loader */ + for (i = 1;; i++) + { + lua_rawgeti(L, 3, i); /* get a searcher */ + if (lua_isnil(L, -1)) + { /* no more searchers? */ + lua_pop(L, 1); /* remove nil */ + luaL_pushresult(&msg); /* create error message */ + luaL_error(L, "module " LUA_QS " not found:%s", + name, lua_tostring(L, -1)); + } + lua_pushstring(L, name); + lua_call(L, 1, 2); /* call it */ + if (lua_isfunction(L, -2)) /* did it find a loader? */ + return; /* module loader found */ + else if (lua_isstring(L, -2)) + { /* searcher returned error message? */ + lua_pop(L, 1); /* remove extra return */ + luaL_addvalue(&msg); /* concatenate error message */ + } + else + lua_pop(L, 2); /* remove both returns */ + } } - -static int ll_require (lua_State *L) { - const char *name = luaL_checkstring(L, 1); - lua_settop(L, 1); /* _LOADED table will be at index 2 */ - lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); - lua_getfield(L, 2, name); /* _LOADED[name] */ - if (lua_toboolean(L, -1)) /* is it there? */ - return 1; /* package is already loaded */ - /* else must load package */ - lua_pop(L, 1); /* remove 'getfield' result */ - findloader(L, name); - lua_pushstring(L, name); /* pass name as argument to module loader */ - lua_insert(L, -2); /* name is 1st argument (before search data) */ - lua_call(L, 2, 1); /* run loader to load module */ - if (!lua_isnil(L, -1)) /* non-nil return? */ - lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ - lua_getfield(L, 2, name); - if (lua_isnil(L, -1)) { /* module did not set a value? */ - lua_pushboolean(L, 1); /* use true as result */ - lua_pushvalue(L, -1); /* extra copy to be returned */ - lua_setfield(L, 2, name); /* _LOADED[name] = true */ - } - return 1; +static int ll_require(lua_State *L) +{ + const char *name = luaL_checkstring(L, 1); + lua_settop(L, 1); /* _LOADED table will be at index 2 */ + lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_getfield(L, 2, name); /* _LOADED[name] */ + if (lua_toboolean(L, -1)) /* is it there? */ + return 1; /* package is already loaded */ + /* else must load package */ + lua_pop(L, 1); /* remove 'getfield' result */ + findloader(L, name); + lua_pushstring(L, name); /* pass name as argument to module loader */ + lua_insert(L, -2); /* name is 1st argument (before search data) */ + lua_call(L, 2, 1); /* run loader to load module */ + if (!lua_isnil(L, -1)) /* non-nil return? */ + lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ + lua_getfield(L, 2, name); + if (lua_isnil(L, -1)) + { /* module did not set a value? */ + lua_pushboolean(L, 1); /* use true as result */ + lua_pushvalue(L, -1); /* extra copy to be returned */ + lua_setfield(L, 2, name); /* _LOADED[name] = true */ + } + return 1; } /* }====================================================== */ - - /* ** {====================================================== ** 'module' function @@ -544,183 +545,184 @@ static int ll_require (lua_State *L) { /* ** changes the environment variable of calling function */ -static void set_env (lua_State *L) { - lua_Debug ar; - if (lua_getstack(L, 1, &ar) == 0 || - lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ - lua_iscfunction(L, -1)) - luaL_error(L, LUA_QL("module") " not called from a Lua function"); - lua_pushvalue(L, -2); /* copy new environment table to top */ - lua_setupvalue(L, -2, 1); - lua_pop(L, 1); /* remove function */ +static void set_env(lua_State *L) +{ + lua_Debug ar; + if (lua_getstack(L, 1, &ar) == 0 || + lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ + lua_iscfunction(L, -1)) + luaL_error(L, LUA_QL("module") " not called from a Lua function"); + lua_pushvalue(L, -2); /* copy new environment table to top */ + lua_setupvalue(L, -2, 1); + lua_pop(L, 1); /* remove function */ } - -static void dooptions (lua_State *L, int n) { - int i; - for (i = 2; i <= n; i++) { - if (lua_isfunction(L, i)) { /* avoid 'calling' extra info. */ - lua_pushvalue(L, i); /* get option (a function) */ - lua_pushvalue(L, -2); /* module */ - lua_call(L, 1, 0); - } - } +static void dooptions(lua_State *L, int n) +{ + int i; + for (i = 2; i <= n; i++) + { + if (lua_isfunction(L, i)) + { /* avoid 'calling' extra info. */ + lua_pushvalue(L, i); /* get option (a function) */ + lua_pushvalue(L, -2); /* module */ + lua_call(L, 1, 0); + } + } } - -static void modinit (lua_State *L, const char *modname) { - const char *dot; - lua_pushvalue(L, -1); - lua_setfield(L, -2, "_M"); /* module._M = module */ - lua_pushstring(L, modname); - lua_setfield(L, -2, "_NAME"); - dot = strrchr(modname, '.'); /* look for last dot in module name */ - if (dot == NULL) dot = modname; - else dot++; - /* set _PACKAGE as package name (full module name minus last part) */ - lua_pushlstring(L, modname, dot - modname); - lua_setfield(L, -2, "_PACKAGE"); +static void modinit(lua_State *L, const char *modname) +{ + const char *dot; + lua_pushvalue(L, -1); + lua_setfield(L, -2, "_M"); /* module._M = module */ + lua_pushstring(L, modname); + lua_setfield(L, -2, "_NAME"); + dot = strrchr(modname, '.'); /* look for last dot in module name */ + if (dot == NULL) + dot = modname; + else + dot++; + /* set _PACKAGE as package name (full module name minus last part) */ + lua_pushlstring(L, modname, dot - modname); + lua_setfield(L, -2, "_PACKAGE"); } - -static int ll_module (lua_State *L) { - const char *modname = luaL_checkstring(L, 1); - int lastarg = lua_gettop(L); /* last parameter */ - luaL_pushmodule(L, modname, 1); /* get/create module table */ - /* check whether table already has a _NAME field */ - lua_getfield(L, -1, "_NAME"); - if (!lua_isnil(L, -1)) /* is table an initialized module? */ - lua_pop(L, 1); - else { /* no; initialize it */ - lua_pop(L, 1); - modinit(L, modname); - } - lua_pushvalue(L, -1); - set_env(L); - dooptions(L, lastarg); - return 1; +static int ll_module(lua_State *L) +{ + const char *modname = luaL_checkstring(L, 1); + int lastarg = lua_gettop(L); /* last parameter */ + luaL_pushmodule(L, modname, 1); /* get/create module table */ + /* check whether table already has a _NAME field */ + lua_getfield(L, -1, "_NAME"); + if (!lua_isnil(L, -1)) /* is table an initialized module? */ + lua_pop(L, 1); + else + { /* no; initialize it */ + lua_pop(L, 1); + modinit(L, modname); + } + lua_pushvalue(L, -1); + set_env(L); + dooptions(L, lastarg); + return 1; } - -static int ll_seeall (lua_State *L) { - luaL_checktype(L, 1, LUA_TTABLE); - if (!lua_getmetatable(L, 1)) { - lua_createtable(L, 0, 1); /* create new metatable */ - lua_pushvalue(L, -1); - lua_setmetatable(L, 1); - } - lua_pushglobaltable(L); - lua_setfield(L, -2, "__index"); /* mt.__index = _G */ - return 0; +static int ll_seeall(lua_State *L) +{ + luaL_checktype(L, 1, LUA_TTABLE); + if (!lua_getmetatable(L, 1)) + { + lua_createtable(L, 0, 1); /* create new metatable */ + lua_pushvalue(L, -1); + lua_setmetatable(L, 1); + } + lua_pushglobaltable(L); + lua_setfield(L, -2, "__index"); /* mt.__index = _G */ + return 0; } #endif /* }====================================================== */ - - /* auxiliary mark (for internal use) */ -#define AUXMARK "\1" - +#define AUXMARK "\1" /* ** return registry.LUA_NOENV as a boolean */ -static int noenv (lua_State *L) { - int b; - lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); - b = lua_toboolean(L, -1); - lua_pop(L, 1); /* remove value */ - return b; +static int noenv(lua_State *L) +{ + int b; + lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); + b = lua_toboolean(L, -1); + lua_pop(L, 1); /* remove value */ + return b; } - -static void setpath (lua_State *L, const char *fieldname, const char *envname1, - const char *envname2, const char *def) { - const char *path = getenv(envname1); - if (path == NULL) /* no environment variable? */ - path = getenv(envname2); /* try alternative name */ - if (path == NULL || noenv(L)) /* no environment variable? */ - lua_pushstring(L, def); /* use default */ - else { - /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ - path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP, - LUA_PATH_SEP AUXMARK LUA_PATH_SEP); - luaL_gsub(L, path, AUXMARK, def); - lua_remove(L, -2); - } - setprogdir(L); - lua_setfield(L, -2, fieldname); +static void setpath(lua_State *L, const char *fieldname, const char *envname1, + const char *envname2, const char *def) +{ + const char *path = getenv(envname1); + if (path == NULL) /* no environment variable? */ + path = getenv(envname2); /* try alternative name */ + if (path == NULL || noenv(L)) /* no environment variable? */ + lua_pushstring(L, def); /* use default */ + else + { + /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ + path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP, + LUA_PATH_SEP AUXMARK LUA_PATH_SEP); + luaL_gsub(L, path, AUXMARK, def); + lua_remove(L, -2); + } + setprogdir(L); + lua_setfield(L, -2, fieldname); } - static const luaL_Reg pk_funcs[] = { - {"loadlib", ll_loadlib}, - {"searchpath", ll_searchpath}, + {"loadlib", ll_loadlib}, + {"searchpath", ll_searchpath}, #if defined(LUA_COMPAT_MODULE) - {"seeall", ll_seeall}, + {"seeall", ll_seeall}, #endif - {NULL, NULL} -}; - + {NULL, NULL}}; static const luaL_Reg ll_funcs[] = { #if defined(LUA_COMPAT_MODULE) - {"module", ll_module}, + {"module", ll_module}, #endif - {"require", ll_require}, - {NULL, NULL} -}; + {"require", ll_require}, + {NULL, NULL}}; - -static void createsearcherstable (lua_State *L) { - static const lua_CFunction searchers[] = - {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL}; - int i; - /* create 'searchers' table */ - lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0); - /* fill it with pre-defined searchers */ - for (i=0; searchers[i] != NULL; i++) { - lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */ - lua_pushcclosure(L, searchers[i], 1); - lua_rawseti(L, -2, i+1); - } +static void createsearcherstable(lua_State *L) +{ + static const lua_CFunction searchers[] = + {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL}; + int i; + /* create 'searchers' table */ + lua_createtable(L, sizeof(searchers) / sizeof(searchers[0]) - 1, 0); + /* fill it with pre-defined searchers */ + for (i = 0; searchers[i] != NULL; i++) + { + lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */ + lua_pushcclosure(L, searchers[i], 1); + lua_rawseti(L, -2, i + 1); + } } - -LUAMOD_API int luaopen_package (lua_State *L) { - /* create table CLIBS to keep track of loaded C libraries */ - luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); - lua_createtable(L, 0, 1); /* metatable for CLIBS */ - lua_pushcfunction(L, gctm); - lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */ - lua_setmetatable(L, -2); - /* create `package' table */ - luaL_newlib(L, pk_funcs); - createsearcherstable(L); +LUAMOD_API int luaopen_package(lua_State *L) +{ + /* create table CLIBS to keep track of loaded C libraries */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); + lua_createtable(L, 0, 1); /* metatable for CLIBS */ + lua_pushcfunction(L, gctm); + lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */ + lua_setmetatable(L, -2); + /* create `package' table */ + luaL_newlib(L, pk_funcs); + createsearcherstable(L); #if defined(LUA_COMPAT_LOADERS) - lua_pushvalue(L, -1); /* make a copy of 'searchers' table */ - lua_setfield(L, -3, "loaders"); /* put it in field `loaders' */ + lua_pushvalue(L, -1); /* make a copy of 'searchers' table */ + lua_setfield(L, -3, "loaders"); /* put it in field `loaders' */ #endif - lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ - /* set field 'path' */ - setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT); - /* set field 'cpath' */ - setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT); - /* store config information */ - lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" - LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); - lua_setfield(L, -2, "config"); - /* set field `loaded' */ - luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); - lua_setfield(L, -2, "loaded"); - /* set field `preload' */ - luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); - lua_setfield(L, -2, "preload"); - lua_pushglobaltable(L); - lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ - luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */ - lua_pop(L, 1); /* pop global table */ - return 1; /* return 'package' table */ + lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ + /* set field 'path' */ + setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT); + /* set field 'cpath' */ + setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT); + /* store config information */ + lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); + lua_setfield(L, -2, "config"); + /* set field `loaded' */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_setfield(L, -2, "loaded"); + /* set field `preload' */ + luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); + lua_setfield(L, -2, "preload"); + lua_pushglobaltable(L); + lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ + luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */ + lua_pop(L, 1); /* pop global table */ + return 1; /* return 'package' table */ } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lobject.c b/examples/ThirdPartyLibs/lua-5.2.3/src/lobject.c index 882d994d4..62523dd7a 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lobject.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lobject.c @@ -23,265 +23,302 @@ #include "lstring.h" #include "lvm.h" - - LUAI_DDEF const TValue luaO_nilobject_ = {NILCONSTANT}; - /* ** converts an integer to a "floating point byte", represented as ** (eeeeexxx), where the real value is (1xxx) * 2^(eeeee - 1) if ** eeeee != 0 and (xxx) otherwise. */ -int luaO_int2fb (unsigned int x) { - int e = 0; /* exponent */ - if (x < 8) return x; - while (x >= 0x10) { - x = (x+1) >> 1; - e++; - } - return ((e+1) << 3) | (cast_int(x) - 8); +int luaO_int2fb(unsigned int x) +{ + int e = 0; /* exponent */ + if (x < 8) return x; + while (x >= 0x10) + { + x = (x + 1) >> 1; + e++; + } + return ((e + 1) << 3) | (cast_int(x) - 8); } - /* converts back */ -int luaO_fb2int (int x) { - int e = (x >> 3) & 0x1f; - if (e == 0) return x; - else return ((x & 7) + 8) << (e - 1); +int luaO_fb2int(int x) +{ + int e = (x >> 3) & 0x1f; + if (e == 0) + return x; + else + return ((x & 7) + 8) << (e - 1); } - -int luaO_ceillog2 (unsigned int x) { - static const lu_byte log_2[256] = { - 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, - 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8, - 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8 - }; - int l = 0; - x--; - while (x >= 256) { l += 8; x >>= 8; } - return l + log_2[x]; +int luaO_ceillog2(unsigned int x) +{ + static const lu_byte log_2[256] = { + 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, + 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8}; + int l = 0; + x--; + while (x >= 256) + { + l += 8; + x >>= 8; + } + return l + log_2[x]; } - -lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) { - switch (op) { - case LUA_OPADD: return luai_numadd(NULL, v1, v2); - case LUA_OPSUB: return luai_numsub(NULL, v1, v2); - case LUA_OPMUL: return luai_nummul(NULL, v1, v2); - case LUA_OPDIV: return luai_numdiv(NULL, v1, v2); - case LUA_OPMOD: return luai_nummod(NULL, v1, v2); - case LUA_OPPOW: return luai_numpow(NULL, v1, v2); - case LUA_OPUNM: return luai_numunm(NULL, v1); - default: lua_assert(0); return 0; - } +lua_Number luaO_arith(int op, lua_Number v1, lua_Number v2) +{ + switch (op) + { + case LUA_OPADD: + return luai_numadd(NULL, v1, v2); + case LUA_OPSUB: + return luai_numsub(NULL, v1, v2); + case LUA_OPMUL: + return luai_nummul(NULL, v1, v2); + case LUA_OPDIV: + return luai_numdiv(NULL, v1, v2); + case LUA_OPMOD: + return luai_nummod(NULL, v1, v2); + case LUA_OPPOW: + return luai_numpow(NULL, v1, v2); + case LUA_OPUNM: + return luai_numunm(NULL, v1); + default: + lua_assert(0); + return 0; + } } - -int luaO_hexavalue (int c) { - if (lisdigit(c)) return c - '0'; - else return ltolower(c) - 'a' + 10; +int luaO_hexavalue(int c) +{ + if (lisdigit(c)) + return c - '0'; + else + return ltolower(c) - 'a' + 10; } - #if !defined(lua_strx2number) #include - -static int isneg (const char **s) { - if (**s == '-') { (*s)++; return 1; } - else if (**s == '+') (*s)++; - return 0; +static int isneg(const char **s) +{ + if (**s == '-') + { + (*s)++; + return 1; + } + else if (**s == '+') + (*s)++; + return 0; } - -static lua_Number readhexa (const char **s, lua_Number r, int *count) { - for (; lisxdigit(cast_uchar(**s)); (*s)++) { /* read integer part */ - r = (r * cast_num(16.0)) + cast_num(luaO_hexavalue(cast_uchar(**s))); - (*count)++; - } - return r; +static lua_Number readhexa(const char **s, lua_Number r, int *count) +{ + for (; lisxdigit(cast_uchar(**s)); (*s)++) + { /* read integer part */ + r = (r * cast_num(16.0)) + cast_num(luaO_hexavalue(cast_uchar(**s))); + (*count)++; + } + return r; } - /* ** convert an hexadecimal numeric string to a number, following ** C99 specification for 'strtod' */ -static lua_Number lua_strx2number (const char *s, char **endptr) { - lua_Number r = 0.0; - int e = 0, i = 0; - int neg = 0; /* 1 if number is negative */ - *endptr = cast(char *, s); /* nothing is valid yet */ - while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ - neg = isneg(&s); /* check signal */ - if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */ - return 0.0; /* invalid format (no '0x') */ - s += 2; /* skip '0x' */ - r = readhexa(&s, r, &i); /* read integer part */ - if (*s == '.') { - s++; /* skip dot */ - r = readhexa(&s, r, &e); /* read fractional part */ - } - if (i == 0 && e == 0) - return 0.0; /* invalid format (no digit) */ - e *= -4; /* each fractional digit divides value by 2^-4 */ - *endptr = cast(char *, s); /* valid up to here */ - if (*s == 'p' || *s == 'P') { /* exponent part? */ - int exp1 = 0; - int neg1; - s++; /* skip 'p' */ - neg1 = isneg(&s); /* signal */ - if (!lisdigit(cast_uchar(*s))) - goto ret; /* must have at least one digit */ - while (lisdigit(cast_uchar(*s))) /* read exponent */ - exp1 = exp1 * 10 + *(s++) - '0'; - if (neg1) exp1 = -exp1; - e += exp1; - } - *endptr = cast(char *, s); /* valid up to here */ - ret: - if (neg) r = -r; - return l_mathop(ldexp)(r, e); +static lua_Number lua_strx2number(const char *s, char **endptr) +{ + lua_Number r = 0.0; + int e = 0, i = 0; + int neg = 0; /* 1 if number is negative */ + *endptr = cast(char *, s); /* nothing is valid yet */ + while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */ + neg = isneg(&s); /* check signal */ + if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */ + return 0.0; /* invalid format (no '0x') */ + s += 2; /* skip '0x' */ + r = readhexa(&s, r, &i); /* read integer part */ + if (*s == '.') + { + s++; /* skip dot */ + r = readhexa(&s, r, &e); /* read fractional part */ + } + if (i == 0 && e == 0) + return 0.0; /* invalid format (no digit) */ + e *= -4; /* each fractional digit divides value by 2^-4 */ + *endptr = cast(char *, s); /* valid up to here */ + if (*s == 'p' || *s == 'P') + { /* exponent part? */ + int exp1 = 0; + int neg1; + s++; /* skip 'p' */ + neg1 = isneg(&s); /* signal */ + if (!lisdigit(cast_uchar(*s))) + goto ret; /* must have at least one digit */ + while (lisdigit(cast_uchar(*s))) /* read exponent */ + exp1 = exp1 * 10 + *(s++) - '0'; + if (neg1) exp1 = -exp1; + e += exp1; + } + *endptr = cast(char *, s); /* valid up to here */ +ret: + if (neg) r = -r; + return l_mathop(ldexp)(r, e); } #endif - -int luaO_str2d (const char *s, size_t len, lua_Number *result) { - char *endptr; - if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */ - return 0; - else if (strpbrk(s, "xX")) /* hexa? */ - *result = lua_strx2number(s, &endptr); - else - *result = lua_str2number(s, &endptr); - if (endptr == s) return 0; /* nothing recognized */ - while (lisspace(cast_uchar(*endptr))) endptr++; - return (endptr == s + len); /* OK if no trailing characters */ +int luaO_str2d(const char *s, size_t len, lua_Number *result) +{ + char *endptr; + if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */ + return 0; + else if (strpbrk(s, "xX")) /* hexa? */ + *result = lua_strx2number(s, &endptr); + else + *result = lua_str2number(s, &endptr); + if (endptr == s) return 0; /* nothing recognized */ + while (lisspace(cast_uchar(*endptr))) endptr++; + return (endptr == s + len); /* OK if no trailing characters */ } - - -static void pushstr (lua_State *L, const char *str, size_t l) { - setsvalue2s(L, L->top++, luaS_newlstr(L, str, l)); +static void pushstr(lua_State *L, const char *str, size_t l) +{ + setsvalue2s(L, L->top++, luaS_newlstr(L, str, l)); } - /* this function handles only `%d', `%c', %f, %p, and `%s' formats */ -const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { - int n = 0; - for (;;) { - const char *e = strchr(fmt, '%'); - if (e == NULL) break; - luaD_checkstack(L, 2); /* fmt + item */ - pushstr(L, fmt, e - fmt); - switch (*(e+1)) { - case 's': { - const char *s = va_arg(argp, char *); - if (s == NULL) s = "(null)"; - pushstr(L, s, strlen(s)); - break; - } - case 'c': { - char buff; - buff = cast(char, va_arg(argp, int)); - pushstr(L, &buff, 1); - break; - } - case 'd': { - setnvalue(L->top++, cast_num(va_arg(argp, int))); - break; - } - case 'f': { - setnvalue(L->top++, cast_num(va_arg(argp, l_uacNumber))); - break; - } - case 'p': { - char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */ - int l = sprintf(buff, "%p", va_arg(argp, void *)); - pushstr(L, buff, l); - break; - } - case '%': { - pushstr(L, "%", 1); - break; - } - default: { - luaG_runerror(L, - "invalid option " LUA_QL("%%%c") " to " LUA_QL("lua_pushfstring"), - *(e + 1)); - } - } - n += 2; - fmt = e+2; - } - luaD_checkstack(L, 1); - pushstr(L, fmt, strlen(fmt)); - if (n > 0) luaV_concat(L, n + 1); - return svalue(L->top - 1); +const char *luaO_pushvfstring(lua_State *L, const char *fmt, va_list argp) +{ + int n = 0; + for (;;) + { + const char *e = strchr(fmt, '%'); + if (e == NULL) break; + luaD_checkstack(L, 2); /* fmt + item */ + pushstr(L, fmt, e - fmt); + switch (*(e + 1)) + { + case 's': + { + const char *s = va_arg(argp, char *); + if (s == NULL) s = "(null)"; + pushstr(L, s, strlen(s)); + break; + } + case 'c': + { + char buff; + buff = cast(char, va_arg(argp, int)); + pushstr(L, &buff, 1); + break; + } + case 'd': + { + setnvalue(L->top++, cast_num(va_arg(argp, int))); + break; + } + case 'f': + { + setnvalue(L->top++, cast_num(va_arg(argp, l_uacNumber))); + break; + } + case 'p': + { + char buff[4 * sizeof(void *) + 8]; /* should be enough space for a `%p' */ + int l = sprintf(buff, "%p", va_arg(argp, void *)); + pushstr(L, buff, l); + break; + } + case '%': + { + pushstr(L, "%", 1); + break; + } + default: + { + luaG_runerror(L, + "invalid option " LUA_QL("%%%c") " to " LUA_QL("lua_pushfstring"), + *(e + 1)); + } + } + n += 2; + fmt = e + 2; + } + luaD_checkstack(L, 1); + pushstr(L, fmt, strlen(fmt)); + if (n > 0) luaV_concat(L, n + 1); + return svalue(L->top - 1); } - -const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) { - const char *msg; - va_list argp; - va_start(argp, fmt); - msg = luaO_pushvfstring(L, fmt, argp); - va_end(argp); - return msg; +const char *luaO_pushfstring(lua_State *L, const char *fmt, ...) +{ + const char *msg; + va_list argp; + va_start(argp, fmt); + msg = luaO_pushvfstring(L, fmt, argp); + va_end(argp); + return msg; } - /* number of chars of a literal string without the ending \0 */ -#define LL(x) (sizeof(x)/sizeof(char) - 1) +#define LL(x) (sizeof(x) / sizeof(char) - 1) -#define RETS "..." -#define PRE "[string \"" -#define POS "\"]" +#define RETS "..." +#define PRE "[string \"" +#define POS "\"]" -#define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) ) +#define addstr(a, b, l) (memcpy(a, b, (l) * sizeof(char)), a += (l)) -void luaO_chunkid (char *out, const char *source, size_t bufflen) { - size_t l = strlen(source); - if (*source == '=') { /* 'literal' source */ - if (l <= bufflen) /* small enough? */ - memcpy(out, source + 1, l * sizeof(char)); - else { /* truncate it */ - addstr(out, source + 1, bufflen - 1); - *out = '\0'; - } - } - else if (*source == '@') { /* file name */ - if (l <= bufflen) /* small enough? */ - memcpy(out, source + 1, l * sizeof(char)); - else { /* add '...' before rest of name */ - addstr(out, RETS, LL(RETS)); - bufflen -= LL(RETS); - memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char)); - } - } - else { /* string; format as [string "source"] */ - const char *nl = strchr(source, '\n'); /* find first new line (if any) */ - addstr(out, PRE, LL(PRE)); /* add prefix */ - bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */ - if (l < bufflen && nl == NULL) { /* small one-line source? */ - addstr(out, source, l); /* keep it */ - } - else { - if (nl != NULL) l = nl - source; /* stop at first newline */ - if (l > bufflen) l = bufflen; - addstr(out, source, l); - addstr(out, RETS, LL(RETS)); - } - memcpy(out, POS, (LL(POS) + 1) * sizeof(char)); - } +void luaO_chunkid(char *out, const char *source, size_t bufflen) +{ + size_t l = strlen(source); + if (*source == '=') + { /* 'literal' source */ + if (l <= bufflen) /* small enough? */ + memcpy(out, source + 1, l * sizeof(char)); + else + { /* truncate it */ + addstr(out, source + 1, bufflen - 1); + *out = '\0'; + } + } + else if (*source == '@') + { /* file name */ + if (l <= bufflen) /* small enough? */ + memcpy(out, source + 1, l * sizeof(char)); + else + { /* add '...' before rest of name */ + addstr(out, RETS, LL(RETS)); + bufflen -= LL(RETS); + memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char)); + } + } + else + { /* string; format as [string "source"] */ + const char *nl = strchr(source, '\n'); /* find first new line (if any) */ + addstr(out, PRE, LL(PRE)); /* add prefix */ + bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */ + if (l < bufflen && nl == NULL) + { /* small one-line source? */ + addstr(out, source, l); /* keep it */ + } + else + { + if (nl != NULL) l = nl - source; /* stop at first newline */ + if (l > bufflen) l = bufflen; + addstr(out, source, l); + addstr(out, RETS, LL(RETS)); + } + memcpy(out, POS, (LL(POS) + 1) * sizeof(char)); + } } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lobject.h b/examples/ThirdPartyLibs/lua-5.2.3/src/lobject.h index 3a630b944..4d48cea39 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lobject.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lobject.h @@ -4,30 +4,25 @@ ** See Copyright Notice in lua.h */ - #ifndef lobject_h #define lobject_h - #include - #include "llimits.h" #include "lua.h" - /* ** Extra tags for non-values */ -#define LUA_TPROTO LUA_NUMTAGS -#define LUA_TUPVAL (LUA_NUMTAGS+1) -#define LUA_TDEADKEY (LUA_NUMTAGS+2) +#define LUA_TPROTO LUA_NUMTAGS +#define LUA_TUPVAL (LUA_NUMTAGS + 1) +#define LUA_TDEADKEY (LUA_NUMTAGS + 2) /* ** number of all possible tags (including LUA_TNONE but excluding DEADKEY) */ -#define LUA_TOTALTAGS (LUA_TUPVAL+2) - +#define LUA_TOTALTAGS (LUA_TUPVAL + 2) /* ** tags for Tagged Values have the following use of bits: @@ -36,8 +31,7 @@ ** bit 6: whether value is collectable */ -#define VARBITS (3 << 4) - +#define VARBITS (3 << 4) /* ** LUA_TFUNCTION variants: @@ -47,225 +41,253 @@ */ /* Variant tags for functions */ -#define LUA_TLCL (LUA_TFUNCTION | (0 << 4)) /* Lua closure */ -#define LUA_TLCF (LUA_TFUNCTION | (1 << 4)) /* light C function */ -#define LUA_TCCL (LUA_TFUNCTION | (2 << 4)) /* C closure */ - +#define LUA_TLCL (LUA_TFUNCTION | (0 << 4)) /* Lua closure */ +#define LUA_TLCF (LUA_TFUNCTION | (1 << 4)) /* light C function */ +#define LUA_TCCL (LUA_TFUNCTION | (2 << 4)) /* C closure */ /* Variant tags for strings */ -#define LUA_TSHRSTR (LUA_TSTRING | (0 << 4)) /* short strings */ -#define LUA_TLNGSTR (LUA_TSTRING | (1 << 4)) /* long strings */ - +#define LUA_TSHRSTR (LUA_TSTRING | (0 << 4)) /* short strings */ +#define LUA_TLNGSTR (LUA_TSTRING | (1 << 4)) /* long strings */ /* Bit mark for collectable types */ -#define BIT_ISCOLLECTABLE (1 << 6) +#define BIT_ISCOLLECTABLE (1 << 6) /* mark a tag as collectable */ -#define ctb(t) ((t) | BIT_ISCOLLECTABLE) - +#define ctb(t) ((t) | BIT_ISCOLLECTABLE) /* ** Union of all collectable objects */ typedef union GCObject GCObject; - /* ** Common Header for all collectable objects (in macro form, to be ** included in other objects) */ -#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked - +#define CommonHeader \ + GCObject *next; \ + lu_byte tt; \ + lu_byte marked /* ** Common header in struct form */ -typedef struct GCheader { - CommonHeader; +typedef struct GCheader +{ + CommonHeader; } GCheader; - - /* ** Union of all Lua values */ typedef union Value Value; - -#define numfield lua_Number n; /* numbers */ - - +#define numfield lua_Number n; /* numbers */ /* ** Tagged Values. This is the basic representation of values in Lua, ** an actual value plus a tag with its type. */ -#define TValuefields Value value_; int tt_ +#define TValuefields \ + Value value_; \ + int tt_ typedef struct lua_TValue TValue; - /* macro defining a nil value */ -#define NILCONSTANT {NULL}, LUA_TNIL - - -#define val_(o) ((o)->value_) -#define num_(o) (val_(o).n) +#define NILCONSTANT {NULL}, LUA_TNIL +#define val_(o) ((o)->value_) +#define num_(o) (val_(o).n) /* raw type tag of a TValue */ -#define rttype(o) ((o)->tt_) +#define rttype(o) ((o)->tt_) /* tag with no variants (bits 0-3) */ -#define novariant(x) ((x) & 0x0F) +#define novariant(x) ((x)&0x0F) /* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ -#define ttype(o) (rttype(o) & 0x3F) +#define ttype(o) (rttype(o) & 0x3F) /* type tag of a TValue with no variants (bits 0-3) */ -#define ttypenv(o) (novariant(rttype(o))) - +#define ttypenv(o) (novariant(rttype(o))) /* Macros to test type */ -#define checktag(o,t) (rttype(o) == (t)) -#define checktype(o,t) (ttypenv(o) == (t)) -#define ttisnumber(o) checktag((o), LUA_TNUMBER) -#define ttisnil(o) checktag((o), LUA_TNIL) -#define ttisboolean(o) checktag((o), LUA_TBOOLEAN) -#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA) -#define ttisstring(o) checktype((o), LUA_TSTRING) -#define ttisshrstring(o) checktag((o), ctb(LUA_TSHRSTR)) -#define ttislngstring(o) checktag((o), ctb(LUA_TLNGSTR)) -#define ttistable(o) checktag((o), ctb(LUA_TTABLE)) -#define ttisfunction(o) checktype(o, LUA_TFUNCTION) -#define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION) -#define ttisCclosure(o) checktag((o), ctb(LUA_TCCL)) -#define ttisLclosure(o) checktag((o), ctb(LUA_TLCL)) -#define ttislcf(o) checktag((o), LUA_TLCF) -#define ttisuserdata(o) checktag((o), ctb(LUA_TUSERDATA)) -#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD)) -#define ttisdeadkey(o) checktag((o), LUA_TDEADKEY) +#define checktag(o, t) (rttype(o) == (t)) +#define checktype(o, t) (ttypenv(o) == (t)) +#define ttisnumber(o) checktag((o), LUA_TNUMBER) +#define ttisnil(o) checktag((o), LUA_TNIL) +#define ttisboolean(o) checktag((o), LUA_TBOOLEAN) +#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA) +#define ttisstring(o) checktype((o), LUA_TSTRING) +#define ttisshrstring(o) checktag((o), ctb(LUA_TSHRSTR)) +#define ttislngstring(o) checktag((o), ctb(LUA_TLNGSTR)) +#define ttistable(o) checktag((o), ctb(LUA_TTABLE)) +#define ttisfunction(o) checktype(o, LUA_TFUNCTION) +#define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION) +#define ttisCclosure(o) checktag((o), ctb(LUA_TCCL)) +#define ttisLclosure(o) checktag((o), ctb(LUA_TLCL)) +#define ttislcf(o) checktag((o), LUA_TLCF) +#define ttisuserdata(o) checktag((o), ctb(LUA_TUSERDATA)) +#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD)) +#define ttisdeadkey(o) checktag((o), LUA_TDEADKEY) -#define ttisequal(o1,o2) (rttype(o1) == rttype(o2)) +#define ttisequal(o1, o2) (rttype(o1) == rttype(o2)) /* Macros to access values */ -#define nvalue(o) check_exp(ttisnumber(o), num_(o)) -#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc) -#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) -#define rawtsvalue(o) check_exp(ttisstring(o), &val_(o).gc->ts) -#define tsvalue(o) (&rawtsvalue(o)->tsv) -#define rawuvalue(o) check_exp(ttisuserdata(o), &val_(o).gc->u) -#define uvalue(o) (&rawuvalue(o)->uv) -#define clvalue(o) check_exp(ttisclosure(o), &val_(o).gc->cl) -#define clLvalue(o) check_exp(ttisLclosure(o), &val_(o).gc->cl.l) -#define clCvalue(o) check_exp(ttisCclosure(o), &val_(o).gc->cl.c) -#define fvalue(o) check_exp(ttislcf(o), val_(o).f) -#define hvalue(o) check_exp(ttistable(o), &val_(o).gc->h) -#define bvalue(o) check_exp(ttisboolean(o), val_(o).b) -#define thvalue(o) check_exp(ttisthread(o), &val_(o).gc->th) +#define nvalue(o) check_exp(ttisnumber(o), num_(o)) +#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc) +#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) +#define rawtsvalue(o) check_exp(ttisstring(o), &val_(o).gc->ts) +#define tsvalue(o) (&rawtsvalue(o)->tsv) +#define rawuvalue(o) check_exp(ttisuserdata(o), &val_(o).gc->u) +#define uvalue(o) (&rawuvalue(o)->uv) +#define clvalue(o) check_exp(ttisclosure(o), &val_(o).gc->cl) +#define clLvalue(o) check_exp(ttisLclosure(o), &val_(o).gc->cl.l) +#define clCvalue(o) check_exp(ttisCclosure(o), &val_(o).gc->cl.c) +#define fvalue(o) check_exp(ttislcf(o), val_(o).f) +#define hvalue(o) check_exp(ttistable(o), &val_(o).gc->h) +#define bvalue(o) check_exp(ttisboolean(o), val_(o).b) +#define thvalue(o) check_exp(ttisthread(o), &val_(o).gc->th) /* a dead value may get the 'gc' field, but cannot access its contents */ -#define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc)) +#define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc)) -#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) - - -#define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE) +#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0)) +#define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE) /* Macros for internal tests */ -#define righttt(obj) (ttype(obj) == gcvalue(obj)->gch.tt) +#define righttt(obj) (ttype(obj) == gcvalue(obj)->gch.tt) -#define checkliveness(g,obj) \ +#define checkliveness(g, obj) \ lua_longassert(!iscollectable(obj) || \ - (righttt(obj) && !isdead(g,gcvalue(obj)))) - + (righttt(obj) && !isdead(g, gcvalue(obj)))) /* Macros to set values */ -#define settt_(o,t) ((o)->tt_=(t)) +#define settt_(o, t) ((o)->tt_ = (t)) -#define setnvalue(obj,x) \ - { TValue *io=(obj); num_(io)=(x); settt_(io, LUA_TNUMBER); } +#define setnvalue(obj, x) \ + { \ + TValue *io = (obj); \ + num_(io) = (x); \ + settt_(io, LUA_TNUMBER); \ + } #define setnilvalue(obj) settt_(obj, LUA_TNIL) -#define setfvalue(obj,x) \ - { TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_TLCF); } +#define setfvalue(obj, x) \ + { \ + TValue *io = (obj); \ + val_(io).f = (x); \ + settt_(io, LUA_TLCF); \ + } -#define setpvalue(obj,x) \ - { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); } +#define setpvalue(obj, x) \ + { \ + TValue *io = (obj); \ + val_(io).p = (x); \ + settt_(io, LUA_TLIGHTUSERDATA); \ + } -#define setbvalue(obj,x) \ - { TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); } +#define setbvalue(obj, x) \ + { \ + TValue *io = (obj); \ + val_(io).b = (x); \ + settt_(io, LUA_TBOOLEAN); \ + } -#define setgcovalue(L,obj,x) \ - { TValue *io=(obj); GCObject *i_g=(x); \ - val_(io).gc=i_g; settt_(io, ctb(gch(i_g)->tt)); } +#define setgcovalue(L, obj, x) \ + { \ + TValue *io = (obj); \ + GCObject *i_g = (x); \ + val_(io).gc = i_g; \ + settt_(io, ctb(gch(i_g)->tt)); \ + } -#define setsvalue(L,obj,x) \ - { TValue *io=(obj); \ - TString *x_ = (x); \ - val_(io).gc=cast(GCObject *, x_); settt_(io, ctb(x_->tsv.tt)); \ - checkliveness(G(L),io); } +#define setsvalue(L, obj, x) \ + { \ + TValue *io = (obj); \ + TString *x_ = (x); \ + val_(io).gc = cast(GCObject *, x_); \ + settt_(io, ctb(x_->tsv.tt)); \ + checkliveness(G(L), io); \ + } -#define setuvalue(L,obj,x) \ - { TValue *io=(obj); \ - val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TUSERDATA)); \ - checkliveness(G(L),io); } +#define setuvalue(L, obj, x) \ + { \ + TValue *io = (obj); \ + val_(io).gc = cast(GCObject *, (x)); \ + settt_(io, ctb(LUA_TUSERDATA)); \ + checkliveness(G(L), io); \ + } -#define setthvalue(L,obj,x) \ - { TValue *io=(obj); \ - val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTHREAD)); \ - checkliveness(G(L),io); } +#define setthvalue(L, obj, x) \ + { \ + TValue *io = (obj); \ + val_(io).gc = cast(GCObject *, (x)); \ + settt_(io, ctb(LUA_TTHREAD)); \ + checkliveness(G(L), io); \ + } -#define setclLvalue(L,obj,x) \ - { TValue *io=(obj); \ - val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TLCL)); \ - checkliveness(G(L),io); } +#define setclLvalue(L, obj, x) \ + { \ + TValue *io = (obj); \ + val_(io).gc = cast(GCObject *, (x)); \ + settt_(io, ctb(LUA_TLCL)); \ + checkliveness(G(L), io); \ + } -#define setclCvalue(L,obj,x) \ - { TValue *io=(obj); \ - val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TCCL)); \ - checkliveness(G(L),io); } +#define setclCvalue(L, obj, x) \ + { \ + TValue *io = (obj); \ + val_(io).gc = cast(GCObject *, (x)); \ + settt_(io, ctb(LUA_TCCL)); \ + checkliveness(G(L), io); \ + } -#define sethvalue(L,obj,x) \ - { TValue *io=(obj); \ - val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTABLE)); \ - checkliveness(G(L),io); } +#define sethvalue(L, obj, x) \ + { \ + TValue *io = (obj); \ + val_(io).gc = cast(GCObject *, (x)); \ + settt_(io, ctb(LUA_TTABLE)); \ + checkliveness(G(L), io); \ + } -#define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY) - - - -#define setobj(L,obj1,obj2) \ - { const TValue *io2=(obj2); TValue *io1=(obj1); \ - io1->value_ = io2->value_; io1->tt_ = io2->tt_; \ - checkliveness(G(L),io1); } +#define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY) +#define setobj(L, obj1, obj2) \ + { \ + const TValue *io2 = (obj2); \ + TValue *io1 = (obj1); \ + io1->value_ = io2->value_; \ + io1->tt_ = io2->tt_; \ + checkliveness(G(L), io1); \ + } /* ** different types of assignments, according to destination */ /* from stack to (same) stack */ -#define setobjs2s setobj +#define setobjs2s setobj /* to stack (not from same stack) */ -#define setobj2s setobj -#define setsvalue2s setsvalue -#define sethvalue2s sethvalue -#define setptvalue2s setptvalue +#define setobj2s setobj +#define setsvalue2s setsvalue +#define sethvalue2s sethvalue +#define setptvalue2s setptvalue /* from table to same table */ -#define setobjt2t setobj +#define setobjt2t setobj /* to table */ -#define setobj2t setobj +#define setobj2t setobj /* to new object */ -#define setobj2n setobj -#define setsvalue2n setsvalue - +#define setobj2n setobj +#define setsvalue2n setsvalue /* check whether a number is valid (useful only for NaN trick) */ -#define luai_checknum(L,o,c) { /* empty */ } - +#define luai_checknum(L, o, c) \ + { /* empty */ \ + } /* ** {====================================================== @@ -282,79 +304,105 @@ typedef struct lua_TValue TValue; */ /* allows for external implementation for part of the trick */ -#if !defined(NNMARK) /* { */ - +#if !defined(NNMARK) /* { */ #if !defined(LUA_IEEEENDIAN) #error option 'LUA_NANTRICK' needs 'LUA_IEEEENDIAN' #endif - -#define NNMARK 0x7FF7A500 -#define NNMASK 0x7FFFFF00 +#define NNMARK 0x7FF7A500 +#define NNMASK 0x7FFFFF00 #undef TValuefields #undef NILCONSTANT -#if (LUA_IEEEENDIAN == 0) /* { */ +#if (LUA_IEEEENDIAN == 0) /* { */ /* little endian */ -#define TValuefields \ - union { struct { Value v__; int tt__; } i; double d__; } u -#define NILCONSTANT {{{NULL}, tag2tt(LUA_TNIL)}} +#define TValuefields \ + union { \ + struct \ + { \ + Value v__; \ + int tt__; \ + } i; \ + double d__; \ + } u +#define NILCONSTANT \ + { \ + { \ + {NULL}, tag2tt(LUA_TNIL) \ + } \ + } /* field-access macros */ -#define v_(o) ((o)->u.i.v__) -#define d_(o) ((o)->u.d__) -#define tt_(o) ((o)->u.i.tt__) +#define v_(o) ((o)->u.i.v__) +#define d_(o) ((o)->u.d__) +#define tt_(o) ((o)->u.i.tt__) -#else /* }{ */ +#else /* }{ */ /* big endian */ -#define TValuefields \ - union { struct { int tt__; Value v__; } i; double d__; } u -#define NILCONSTANT {{tag2tt(LUA_TNIL), {NULL}}} +#define TValuefields \ + union { \ + struct \ + { \ + int tt__; \ + Value v__; \ + } i; \ + double d__; \ + } u +#define NILCONSTANT \ + { \ + { \ + tag2tt(LUA_TNIL), { NULL } \ + } \ + } /* field-access macros */ -#define v_(o) ((o)->u.i.v__) -#define d_(o) ((o)->u.d__) -#define tt_(o) ((o)->u.i.tt__) +#define v_(o) ((o)->u.i.v__) +#define d_(o) ((o)->u.d__) +#define tt_(o) ((o)->u.i.tt__) -#endif /* } */ - -#endif /* } */ +#endif /* } */ +#endif /* } */ /* correspondence with standard representation */ #undef val_ -#define val_(o) v_(o) +#define val_(o) v_(o) #undef num_ -#define num_(o) d_(o) - +#define num_(o) d_(o) #undef numfield -#define numfield /* no such field; numbers are the entire struct */ +#define numfield /* no such field; numbers are the entire struct */ /* basic check to distinguish numbers from non-numbers */ #undef ttisnumber -#define ttisnumber(o) ((tt_(o) & NNMASK) != NNMARK) +#define ttisnumber(o) ((tt_(o) & NNMASK) != NNMARK) -#define tag2tt(t) (NNMARK | (t)) +#define tag2tt(t) (NNMARK | (t)) #undef rttype -#define rttype(o) (ttisnumber(o) ? LUA_TNUMBER : tt_(o) & 0xff) +#define rttype(o) (ttisnumber(o) ? LUA_TNUMBER : tt_(o) & 0xff) #undef settt_ -#define settt_(o,t) (tt_(o) = tag2tt(t)) +#define settt_(o, t) (tt_(o) = tag2tt(t)) #undef setnvalue -#define setnvalue(obj,x) \ - { TValue *io_=(obj); num_(io_)=(x); lua_assert(ttisnumber(io_)); } +#define setnvalue(obj, x) \ + { \ + TValue *io_ = (obj); \ + num_(io_) = (x); \ + lua_assert(ttisnumber(io_)); \ + } #undef setobj -#define setobj(L,obj1,obj2) \ - { const TValue *o2_=(obj2); TValue *o1_=(obj1); \ - o1_->u = o2_->u; \ - checkliveness(G(L),o1_); } - +#define setobj(L, obj1, obj2) \ + { \ + const TValue *o2_ = (obj2); \ + TValue *o1_ = (obj1); \ + o1_->u = o2_->u; \ + checkliveness(G(L), o1_); \ + } /* ** these redefinitions are not mandatory, but these forms are more efficient @@ -362,246 +410,232 @@ typedef struct lua_TValue TValue; #undef checktag #undef checktype -#define checktag(o,t) (tt_(o) == tag2tt(t)) -#define checktype(o,t) (ctb(tt_(o) | VARBITS) == ctb(tag2tt(t) | VARBITS)) +#define checktag(o, t) (tt_(o) == tag2tt(t)) +#define checktype(o, t) (ctb(tt_(o) | VARBITS) == ctb(tag2tt(t) | VARBITS)) #undef ttisequal -#define ttisequal(o1,o2) \ +#define ttisequal(o1, o2) \ (ttisnumber(o1) ? ttisnumber(o2) : (tt_(o1) == tt_(o2))) - #undef luai_checknum -#define luai_checknum(L,o,c) { if (!ttisnumber(o)) c; } +#define luai_checknum(L, o, c) \ + { \ + if (!ttisnumber(o)) c; \ + } #endif /* }====================================================== */ - - /* ** {====================================================== ** types and prototypes ** ======================================================= */ - union Value { - GCObject *gc; /* collectable objects */ - void *p; /* light userdata */ - int b; /* booleans */ - lua_CFunction f; /* light C functions */ - numfield /* numbers */ + GCObject *gc; /* collectable objects */ + void *p; /* light userdata */ + int b; /* booleans */ + lua_CFunction f; /* light C functions */ + numfield /* numbers */ }; - -struct lua_TValue { - TValuefields; +struct lua_TValue +{ + TValuefields; }; - -typedef TValue *StkId; /* index to stack elements */ - - - +typedef TValue *StkId; /* index to stack elements */ /* ** Header for string value; string bytes follow the end of this structure */ typedef union TString { - L_Umaxalign dummy; /* ensures maximum alignment for strings */ - struct { - CommonHeader; - lu_byte extra; /* reserved words for short strings; "has hash" for longs */ - unsigned int hash; - size_t len; /* number of characters in string */ - } tsv; + L_Umaxalign dummy; /* ensures maximum alignment for strings */ + struct + { + CommonHeader; + lu_byte extra; /* reserved words for short strings; "has hash" for longs */ + unsigned int hash; + size_t len; /* number of characters in string */ + } tsv; } TString; - /* get the actual string (array of bytes) from a TString */ -#define getstr(ts) cast(const char *, (ts) + 1) +#define getstr(ts) cast(const char *, (ts) + 1) /* get the actual string (array of bytes) from a Lua value */ -#define svalue(o) getstr(rawtsvalue(o)) - +#define svalue(o) getstr(rawtsvalue(o)) /* ** Header for userdata; memory area follows the end of this structure */ typedef union Udata { - L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ - struct { - CommonHeader; - struct Table *metatable; - struct Table *env; - size_t len; /* number of bytes */ - } uv; + L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */ + struct + { + CommonHeader; + struct Table *metatable; + struct Table *env; + size_t len; /* number of bytes */ + } uv; } Udata; - - /* ** Description of an upvalue for function prototypes */ -typedef struct Upvaldesc { - TString *name; /* upvalue name (for debug information) */ - lu_byte instack; /* whether it is in stack */ - lu_byte idx; /* index of upvalue (in stack or in outer function's list) */ +typedef struct Upvaldesc +{ + TString *name; /* upvalue name (for debug information) */ + lu_byte instack; /* whether it is in stack */ + lu_byte idx; /* index of upvalue (in stack or in outer function's list) */ } Upvaldesc; - /* ** Description of a local variable for function prototypes ** (used for debug information) */ -typedef struct LocVar { - TString *varname; - int startpc; /* first point where variable is active */ - int endpc; /* first point where variable is dead */ +typedef struct LocVar +{ + TString *varname; + int startpc; /* first point where variable is active */ + int endpc; /* first point where variable is dead */ } LocVar; - /* ** Function Prototypes */ -typedef struct Proto { - CommonHeader; - TValue *k; /* constants used by the function */ - Instruction *code; - struct Proto **p; /* functions defined inside the function */ - int *lineinfo; /* map from opcodes to source lines (debug information) */ - LocVar *locvars; /* information about local variables (debug information) */ - Upvaldesc *upvalues; /* upvalue information */ - union Closure *cache; /* last created closure with this prototype */ - TString *source; /* used for debug information */ - int sizeupvalues; /* size of 'upvalues' */ - int sizek; /* size of `k' */ - int sizecode; - int sizelineinfo; - int sizep; /* size of `p' */ - int sizelocvars; - int linedefined; - int lastlinedefined; - GCObject *gclist; - lu_byte numparams; /* number of fixed parameters */ - lu_byte is_vararg; - lu_byte maxstacksize; /* maximum stack used by this function */ +typedef struct Proto +{ + CommonHeader; + TValue *k; /* constants used by the function */ + Instruction *code; + struct Proto **p; /* functions defined inside the function */ + int *lineinfo; /* map from opcodes to source lines (debug information) */ + LocVar *locvars; /* information about local variables (debug information) */ + Upvaldesc *upvalues; /* upvalue information */ + union Closure *cache; /* last created closure with this prototype */ + TString *source; /* used for debug information */ + int sizeupvalues; /* size of 'upvalues' */ + int sizek; /* size of `k' */ + int sizecode; + int sizelineinfo; + int sizep; /* size of `p' */ + int sizelocvars; + int linedefined; + int lastlinedefined; + GCObject *gclist; + lu_byte numparams; /* number of fixed parameters */ + lu_byte is_vararg; + lu_byte maxstacksize; /* maximum stack used by this function */ } Proto; - - /* ** Lua Upvalues */ -typedef struct UpVal { - CommonHeader; - TValue *v; /* points to stack or to its own value */ - union { - TValue value; /* the value (when closed) */ - struct { /* double linked list (when open) */ - struct UpVal *prev; - struct UpVal *next; - } l; - } u; +typedef struct UpVal +{ + CommonHeader; + TValue *v; /* points to stack or to its own value */ + union { + TValue value; /* the value (when closed) */ + struct + { /* double linked list (when open) */ + struct UpVal *prev; + struct UpVal *next; + } l; + } u; } UpVal; - /* ** Closures */ -#define ClosureHeader \ - CommonHeader; lu_byte nupvalues; GCObject *gclist +#define ClosureHeader \ + CommonHeader; \ + lu_byte nupvalues; \ + GCObject *gclist -typedef struct CClosure { - ClosureHeader; - lua_CFunction f; - TValue upvalue[1]; /* list of upvalues */ +typedef struct CClosure +{ + ClosureHeader; + lua_CFunction f; + TValue upvalue[1]; /* list of upvalues */ } CClosure; - -typedef struct LClosure { - ClosureHeader; - struct Proto *p; - UpVal *upvals[1]; /* list of upvalues */ +typedef struct LClosure +{ + ClosureHeader; + struct Proto *p; + UpVal *upvals[1]; /* list of upvalues */ } LClosure; - typedef union Closure { - CClosure c; - LClosure l; + CClosure c; + LClosure l; } Closure; +#define isLfunction(o) ttisLclosure(o) -#define isLfunction(o) ttisLclosure(o) - -#define getproto(o) (clLvalue(o)->p) - +#define getproto(o) (clLvalue(o)->p) /* ** Tables */ typedef union TKey { - struct { - TValuefields; - struct Node *next; /* for chaining */ - } nk; - TValue tvk; + struct + { + TValuefields; + struct Node *next; /* for chaining */ + } nk; + TValue tvk; } TKey; - -typedef struct Node { - TValue i_val; - TKey i_key; +typedef struct Node +{ + TValue i_val; + TKey i_key; } Node; - -typedef struct Table { - CommonHeader; - lu_byte flags; /* 1<

lsizenode)) +#define lmod(s, size) \ + (check_exp((size & (size - 1)) == 0, (cast(int, (s) & ((size)-1))))) +#define twoto(x) (1 << (x)) +#define sizenode(t) (twoto((t)->lsizenode)) /* ** (address of) a fixed nil value */ -#define luaO_nilobject (&luaO_nilobject_) - +#define luaO_nilobject (&luaO_nilobject_) LUAI_DDEC const TValue luaO_nilobject_; - -LUAI_FUNC int luaO_int2fb (unsigned int x); -LUAI_FUNC int luaO_fb2int (int x); -LUAI_FUNC int luaO_ceillog2 (unsigned int x); -LUAI_FUNC lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2); -LUAI_FUNC int luaO_str2d (const char *s, size_t len, lua_Number *result); -LUAI_FUNC int luaO_hexavalue (int c); -LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, - va_list argp); -LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); -LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t len); - +LUAI_FUNC int luaO_int2fb(unsigned int x); +LUAI_FUNC int luaO_fb2int(int x); +LUAI_FUNC int luaO_ceillog2(unsigned int x); +LUAI_FUNC lua_Number luaO_arith(int op, lua_Number v1, lua_Number v2); +LUAI_FUNC int luaO_str2d(const char *s, size_t len, lua_Number *result); +LUAI_FUNC int luaO_hexavalue(int c); +LUAI_FUNC const char *luaO_pushvfstring(lua_State *L, const char *fmt, + va_list argp); +LUAI_FUNC const char *luaO_pushfstring(lua_State *L, const char *fmt, ...); +LUAI_FUNC void luaO_chunkid(char *out, const char *source, size_t len); #endif - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lopcodes.c b/examples/ThirdPartyLibs/lua-5.2.3/src/lopcodes.c index 4190dc762..ed74a5951 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lopcodes.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lopcodes.c @@ -4,104 +4,137 @@ ** See Copyright Notice in lua.h */ - #define lopcodes_c #define LUA_CORE - #include "lopcodes.h" - /* ORDER OP */ -LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { - "MOVE", - "LOADK", - "LOADKX", - "LOADBOOL", - "LOADNIL", - "GETUPVAL", - "GETTABUP", - "GETTABLE", - "SETTABUP", - "SETUPVAL", - "SETTABLE", - "NEWTABLE", - "SELF", - "ADD", - "SUB", - "MUL", - "DIV", - "MOD", - "POW", - "UNM", - "NOT", - "LEN", - "CONCAT", - "JMP", - "EQ", - "LT", - "LE", - "TEST", - "TESTSET", - "CALL", - "TAILCALL", - "RETURN", - "FORLOOP", - "FORPREP", - "TFORCALL", - "TFORLOOP", - "SETLIST", - "CLOSURE", - "VARARG", - "EXTRAARG", - NULL -}; +LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES + 1] = { + "MOVE", + "LOADK", + "LOADKX", + "LOADBOOL", + "LOADNIL", + "GETUPVAL", + "GETTABUP", + "GETTABLE", + "SETTABUP", + "SETUPVAL", + "SETTABLE", + "NEWTABLE", + "SELF", + "ADD", + "SUB", + "MUL", + "DIV", + "MOD", + "POW", + "UNM", + "NOT", + "LEN", + "CONCAT", + "JMP", + "EQ", + "LT", + "LE", + "TEST", + "TESTSET", + "CALL", + "TAILCALL", + "RETURN", + "FORLOOP", + "FORPREP", + "TFORCALL", + "TFORLOOP", + "SETLIST", + "CLOSURE", + "VARARG", + "EXTRAARG", + NULL}; - -#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m)) +#define opmode(t, a, b, c, m) (((t) << 7) | ((a) << 6) | ((b) << 4) | ((c) << 2) | (m)) LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { -/* T A B C mode opcode */ - opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ - ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ - ,opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */ - ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ - ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */ - ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ - ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */ - ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ - ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */ - ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ - ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ - ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ - ,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ - ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ - ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ - ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ - ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ - ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ - ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ - ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ - ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ - ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ - ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ - ,opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ - ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ - ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ - ,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ - ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */ - ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ - ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ - ,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ - ,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ - ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ - ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ - ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */ - ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */ - ,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ - ,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ - ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ - ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */ + /* T A B C mode opcode */ + opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */ + , + opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */ + , + opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */ + , + opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */ + , + opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */ + , + opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */ + , + opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */ + , + opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */ + , + opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */ + , + opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */ + , + opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */ + , + opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */ + , + opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_SELF */ + , + opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */ + , + opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */ + , + opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */ + , + opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */ + , + opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */ + , + opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */ + , + opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */ + , + opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */ + , + opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */ + , + opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */ + , + opmode(0, 0, OpArgR, OpArgN, iAsBx) /* OP_JMP */ + , + opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */ + , + opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */ + , + opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */ + , + opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */ + , + opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */ + , + opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */ + , + opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */ + , + opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */ + , + opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */ + , + opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */ + , + opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */ + , + opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */ + , + opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */ + , + opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */ + , + opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */ + , + opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */ }; - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lopcodes.h b/examples/ThirdPartyLibs/lua-5.2.3/src/lopcodes.h index 51f579154..7ad891819 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lopcodes.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lopcodes.h @@ -9,7 +9,6 @@ #include "llimits.h" - /*=========================================================================== We assume that instructions are unsigned numbers. All instructions have an opcode in the first 6 bits. @@ -28,128 +27,119 @@ unsigned argument. ===========================================================================*/ - -enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */ - +enum OpMode +{ + iABC, + iABx, + iAsBx, + iAx +}; /* basic instruction format */ /* ** size and position of opcode arguments. */ -#define SIZE_C 9 -#define SIZE_B 9 -#define SIZE_Bx (SIZE_C + SIZE_B) -#define SIZE_A 8 -#define SIZE_Ax (SIZE_C + SIZE_B + SIZE_A) +#define SIZE_C 9 +#define SIZE_B 9 +#define SIZE_Bx (SIZE_C + SIZE_B) +#define SIZE_A 8 +#define SIZE_Ax (SIZE_C + SIZE_B + SIZE_A) -#define SIZE_OP 6 - -#define POS_OP 0 -#define POS_A (POS_OP + SIZE_OP) -#define POS_C (POS_A + SIZE_A) -#define POS_B (POS_C + SIZE_C) -#define POS_Bx POS_C -#define POS_Ax POS_A +#define SIZE_OP 6 +#define POS_OP 0 +#define POS_A (POS_OP + SIZE_OP) +#define POS_C (POS_A + SIZE_A) +#define POS_B (POS_C + SIZE_C) +#define POS_Bx POS_C +#define POS_Ax POS_A /* ** limits for opcode arguments. ** we use (signed) int to manipulate most arguments, ** so they must fit in LUAI_BITSINT-1 bits (-1 for sign) */ -#if SIZE_Bx < LUAI_BITSINT-1 -#define MAXARG_Bx ((1<>1) /* `sBx' is signed */ +#if SIZE_Bx < LUAI_BITSINT - 1 +#define MAXARG_Bx ((1 << SIZE_Bx) - 1) +#define MAXARG_sBx (MAXARG_Bx >> 1) /* `sBx' is signed */ #else -#define MAXARG_Bx MAX_INT -#define MAXARG_sBx MAX_INT +#define MAXARG_Bx MAX_INT +#define MAXARG_sBx MAX_INT #endif -#if SIZE_Ax < LUAI_BITSINT-1 -#define MAXARG_Ax ((1<>POS_OP) & MASK1(SIZE_OP,0))) -#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ - ((cast(Instruction, o)<> POS_OP) & MASK1(SIZE_OP, 0))) +#define SET_OPCODE(i, o) ((i) = (((i)&MASK0(SIZE_OP, POS_OP)) | \ + ((cast(Instruction, o) << POS_OP) & MASK1(SIZE_OP, POS_OP)))) -#define getarg(i,pos,size) (cast(int, ((i)>>pos) & MASK1(size,0))) -#define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \ - ((cast(Instruction, v)<> pos) & MASK1(size, 0))) +#define setarg(i, v, pos, size) ((i) = (((i)&MASK0(size, pos)) | \ + ((cast(Instruction, v) << pos) & MASK1(size, pos)))) -#define GETARG_A(i) getarg(i, POS_A, SIZE_A) -#define SETARG_A(i,v) setarg(i, v, POS_A, SIZE_A) +#define GETARG_A(i) getarg(i, POS_A, SIZE_A) +#define SETARG_A(i, v) setarg(i, v, POS_A, SIZE_A) -#define GETARG_B(i) getarg(i, POS_B, SIZE_B) -#define SETARG_B(i,v) setarg(i, v, POS_B, SIZE_B) +#define GETARG_B(i) getarg(i, POS_B, SIZE_B) +#define SETARG_B(i, v) setarg(i, v, POS_B, SIZE_B) -#define GETARG_C(i) getarg(i, POS_C, SIZE_C) -#define SETARG_C(i,v) setarg(i, v, POS_C, SIZE_C) +#define GETARG_C(i) getarg(i, POS_C, SIZE_C) +#define SETARG_C(i, v) setarg(i, v, POS_C, SIZE_C) -#define GETARG_Bx(i) getarg(i, POS_Bx, SIZE_Bx) -#define SETARG_Bx(i,v) setarg(i, v, POS_Bx, SIZE_Bx) +#define GETARG_Bx(i) getarg(i, POS_Bx, SIZE_Bx) +#define SETARG_Bx(i, v) setarg(i, v, POS_Bx, SIZE_Bx) -#define GETARG_Ax(i) getarg(i, POS_Ax, SIZE_Ax) -#define SETARG_Ax(i,v) setarg(i, v, POS_Ax, SIZE_Ax) +#define GETARG_Ax(i) getarg(i, POS_Ax, SIZE_Ax) +#define SETARG_Ax(i, v) setarg(i, v, POS_Ax, SIZE_Ax) -#define GETARG_sBx(i) (GETARG_Bx(i)-MAXARG_sBx) -#define SETARG_sBx(i,b) SETARG_Bx((i),cast(unsigned int, (b)+MAXARG_sBx)) +#define GETARG_sBx(i) (GETARG_Bx(i) - MAXARG_sBx) +#define SETARG_sBx(i, b) SETARG_Bx((i), cast(unsigned int, (b) + MAXARG_sBx)) +#define CREATE_ABC(o, a, b, c) ((cast(Instruction, o) << POS_OP) | (cast(Instruction, a) << POS_A) | (cast(Instruction, b) << POS_B) | (cast(Instruction, c) << POS_C)) -#define CREATE_ABC(o,a,b,c) ((cast(Instruction, o)<= R(A) + 1 */ -OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ -OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ -OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ + OP_JMP, /* A sBx pc+=sBx; if (A) close all upvalues >= R(A) + 1 */ + OP_EQ, /* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ + OP_LT, /* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ + OP_LE, /* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ -OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ -OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ + OP_TEST, /* A C if not (R(A) <=> C) then pc++ */ + OP_TESTSET, /* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ -OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ -OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ -OP_RETURN,/* A B return R(A), ... ,R(A+B-2) (see note) */ + OP_CALL, /* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ + OP_TAILCALL, /* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ + OP_RETURN, /* A B return R(A), ... ,R(A+B-2) (see note) */ -OP_FORLOOP,/* A sBx R(A)+=R(A+2); + OP_FORLOOP, /* A sBx R(A)+=R(A+2); if R(A) > 4) & 3)) -#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3)) -#define testAMode(m) (luaP_opmodes[m] & (1 << 6)) -#define testTMode(m) (luaP_opmodes[m] & (1 << 7)) - - -LUAI_DDEC const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */ +#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3)) +#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3)) +#define getCMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 2) & 3)) +#define testAMode(m) (luaP_opmodes[m] & (1 << 6)) +#define testTMode(m) (luaP_opmodes[m] & (1 << 7)) +LUAI_DDEC const char *const luaP_opnames[NUM_OPCODES + 1]; /* opcode names */ /* number of list items to accumulate before a SETLIST instruction */ -#define LFIELDS_PER_FLUSH 50 - +#define LFIELDS_PER_FLUSH 50 #endif diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/loslib.c b/examples/ThirdPartyLibs/lua-5.2.3/src/loslib.c index 052ba1744..dffb52dda 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/loslib.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/loslib.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #include #include #include @@ -19,112 +18,119 @@ #include "lauxlib.h" #include "lualib.h" - /* ** list of valid conversion specifiers for the 'strftime' function */ #if !defined(LUA_STRFTIMEOPTIONS) #if !defined(LUA_USE_POSIX) -#define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" } +#define LUA_STRFTIMEOPTIONS \ + { \ + "aAbBcdHIjmMpSUwWxXyYz%", "" \ + } #else -#define LUA_STRFTIMEOPTIONS \ - { "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "" \ - "", "E", "cCxXyY", \ - "O", "deHImMSuUVwWy" } +#define LUA_STRFTIMEOPTIONS \ + { \ + "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", \ + "" \ + "", \ + "E", "cCxXyY", \ + "O", "deHImMSuUVwWy" \ + } #endif #endif - - /* ** By default, Lua uses tmpnam except when POSIX is available, where it ** uses mkstemp. */ #if defined(LUA_USE_MKSTEMP) #include -#define LUA_TMPNAMBUFSIZE 32 -#define lua_tmpnam(b,e) { \ - strcpy(b, "/tmp/lua_XXXXXX"); \ - e = mkstemp(b); \ - if (e != -1) close(e); \ - e = (e == -1); } +#define LUA_TMPNAMBUFSIZE 32 +#define lua_tmpnam(b, e) \ + { \ + strcpy(b, "/tmp/lua_XXXXXX"); \ + e = mkstemp(b); \ + if (e != -1) close(e); \ + e = (e == -1); \ + } #elif !defined(lua_tmpnam) -#define LUA_TMPNAMBUFSIZE L_tmpnam -#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); } +#define LUA_TMPNAMBUFSIZE L_tmpnam +#define lua_tmpnam(b, e) \ + { \ + e = (tmpnam(b) == NULL); \ + } #endif - /* ** By default, Lua uses gmtime/localtime, except when POSIX is available, ** where it uses gmtime_r/localtime_r */ #if defined(LUA_USE_GMTIME_R) -#define l_gmtime(t,r) gmtime_r(t,r) -#define l_localtime(t,r) localtime_r(t,r) +#define l_gmtime(t, r) gmtime_r(t, r) +#define l_localtime(t, r) localtime_r(t, r) #elif !defined(l_gmtime) -#define l_gmtime(t,r) ((void)r, gmtime(t)) -#define l_localtime(t,r) ((void)r, localtime(t)) +#define l_gmtime(t, r) ((void)r, gmtime(t)) +#define l_localtime(t, r) ((void)r, localtime(t)) #endif - - -static int os_execute (lua_State *L) { - const char *cmd = luaL_optstring(L, 1, NULL); - int stat = system(cmd); - if (cmd != NULL) - return luaL_execresult(L, stat); - else { - lua_pushboolean(L, stat); /* true if there is a shell */ - return 1; - } +static int os_execute(lua_State *L) +{ + const char *cmd = luaL_optstring(L, 1, NULL); + int stat = system(cmd); + if (cmd != NULL) + return luaL_execresult(L, stat); + else + { + lua_pushboolean(L, stat); /* true if there is a shell */ + return 1; + } } - -static int os_remove (lua_State *L) { - const char *filename = luaL_checkstring(L, 1); - return luaL_fileresult(L, remove(filename) == 0, filename); +static int os_remove(lua_State *L) +{ + const char *filename = luaL_checkstring(L, 1); + return luaL_fileresult(L, remove(filename) == 0, filename); } - -static int os_rename (lua_State *L) { - const char *fromname = luaL_checkstring(L, 1); - const char *toname = luaL_checkstring(L, 2); - return luaL_fileresult(L, rename(fromname, toname) == 0, NULL); +static int os_rename(lua_State *L) +{ + const char *fromname = luaL_checkstring(L, 1); + const char *toname = luaL_checkstring(L, 2); + return luaL_fileresult(L, rename(fromname, toname) == 0, NULL); } - -static int os_tmpname (lua_State *L) { - char buff[LUA_TMPNAMBUFSIZE]; - int err; - lua_tmpnam(buff, err); - if (err) - return luaL_error(L, "unable to generate a unique filename"); - lua_pushstring(L, buff); - return 1; +static int os_tmpname(lua_State *L) +{ + char buff[LUA_TMPNAMBUFSIZE]; + int err; + lua_tmpnam(buff, err); + if (err) + return luaL_error(L, "unable to generate a unique filename"); + lua_pushstring(L, buff); + return 1; } - -static int os_getenv (lua_State *L) { - lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ - return 1; +static int os_getenv(lua_State *L) +{ + lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */ + return 1; } - -static int os_clock (lua_State *L) { - lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC); - return 1; +static int os_clock(lua_State *L) +{ + lua_pushnumber(L, ((lua_Number)clock()) / (lua_Number)CLOCKS_PER_SEC); + return 1; } - /* ** {====================================================== ** Time/Date operations @@ -133,191 +139,201 @@ static int os_clock (lua_State *L) { ** ======================================================= */ -static void setfield (lua_State *L, const char *key, int value) { - lua_pushinteger(L, value); - lua_setfield(L, -2, key); +static void setfield(lua_State *L, const char *key, int value) +{ + lua_pushinteger(L, value); + lua_setfield(L, -2, key); } -static void setboolfield (lua_State *L, const char *key, int value) { - if (value < 0) /* undefined? */ - return; /* does not set field */ - lua_pushboolean(L, value); - lua_setfield(L, -2, key); +static void setboolfield(lua_State *L, const char *key, int value) +{ + if (value < 0) /* undefined? */ + return; /* does not set field */ + lua_pushboolean(L, value); + lua_setfield(L, -2, key); } -static int getboolfield (lua_State *L, const char *key) { - int res; - lua_getfield(L, -1, key); - res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1); - lua_pop(L, 1); - return res; +static int getboolfield(lua_State *L, const char *key) +{ + int res; + lua_getfield(L, -1, key); + res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1); + lua_pop(L, 1); + return res; } - -static int getfield (lua_State *L, const char *key, int d) { - int res, isnum; - lua_getfield(L, -1, key); - res = (int)lua_tointegerx(L, -1, &isnum); - if (!isnum) { - if (d < 0) - return luaL_error(L, "field " LUA_QS " missing in date table", key); - res = d; - } - lua_pop(L, 1); - return res; +static int getfield(lua_State *L, const char *key, int d) +{ + int res, isnum; + lua_getfield(L, -1, key); + res = (int)lua_tointegerx(L, -1, &isnum); + if (!isnum) + { + if (d < 0) + return luaL_error(L, "field " LUA_QS " missing in date table", key); + res = d; + } + lua_pop(L, 1); + return res; } - -static const char *checkoption (lua_State *L, const char *conv, char *buff) { - static const char *const options[] = LUA_STRFTIMEOPTIONS; - unsigned int i; - for (i = 0; i < sizeof(options)/sizeof(options[0]); i += 2) { - if (*conv != '\0' && strchr(options[i], *conv) != NULL) { - buff[1] = *conv; - if (*options[i + 1] == '\0') { /* one-char conversion specifier? */ - buff[2] = '\0'; /* end buffer */ - return conv + 1; - } - else if (*(conv + 1) != '\0' && - strchr(options[i + 1], *(conv + 1)) != NULL) { - buff[2] = *(conv + 1); /* valid two-char conversion specifier */ - buff[3] = '\0'; /* end buffer */ - return conv + 2; - } - } - } - luaL_argerror(L, 1, - lua_pushfstring(L, "invalid conversion specifier '%%%s'", conv)); - return conv; /* to avoid warnings */ +static const char *checkoption(lua_State *L, const char *conv, char *buff) +{ + static const char *const options[] = LUA_STRFTIMEOPTIONS; + unsigned int i; + for (i = 0; i < sizeof(options) / sizeof(options[0]); i += 2) + { + if (*conv != '\0' && strchr(options[i], *conv) != NULL) + { + buff[1] = *conv; + if (*options[i + 1] == '\0') + { /* one-char conversion specifier? */ + buff[2] = '\0'; /* end buffer */ + return conv + 1; + } + else if (*(conv + 1) != '\0' && + strchr(options[i + 1], *(conv + 1)) != NULL) + { + buff[2] = *(conv + 1); /* valid two-char conversion specifier */ + buff[3] = '\0'; /* end buffer */ + return conv + 2; + } + } + } + luaL_argerror(L, 1, + lua_pushfstring(L, "invalid conversion specifier '%%%s'", conv)); + return conv; /* to avoid warnings */ } - -static int os_date (lua_State *L) { - const char *s = luaL_optstring(L, 1, "%c"); - time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL)); - struct tm tmr, *stm; - if (*s == '!') { /* UTC? */ - stm = l_gmtime(&t, &tmr); - s++; /* skip `!' */ - } - else - stm = l_localtime(&t, &tmr); - if (stm == NULL) /* invalid date? */ - lua_pushnil(L); - else if (strcmp(s, "*t") == 0) { - lua_createtable(L, 0, 9); /* 9 = number of fields */ - setfield(L, "sec", stm->tm_sec); - setfield(L, "min", stm->tm_min); - setfield(L, "hour", stm->tm_hour); - setfield(L, "day", stm->tm_mday); - setfield(L, "month", stm->tm_mon+1); - setfield(L, "year", stm->tm_year+1900); - setfield(L, "wday", stm->tm_wday+1); - setfield(L, "yday", stm->tm_yday+1); - setboolfield(L, "isdst", stm->tm_isdst); - } - else { - char cc[4]; - luaL_Buffer b; - cc[0] = '%'; - luaL_buffinit(L, &b); - while (*s) { - if (*s != '%') /* no conversion specifier? */ - luaL_addchar(&b, *s++); - else { - size_t reslen; - char buff[200]; /* should be big enough for any conversion result */ - s = checkoption(L, s + 1, cc); - reslen = strftime(buff, sizeof(buff), cc, stm); - luaL_addlstring(&b, buff, reslen); - } - } - luaL_pushresult(&b); - } - return 1; +static int os_date(lua_State *L) +{ + const char *s = luaL_optstring(L, 1, "%c"); + time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL)); + struct tm tmr, *stm; + if (*s == '!') + { /* UTC? */ + stm = l_gmtime(&t, &tmr); + s++; /* skip `!' */ + } + else + stm = l_localtime(&t, &tmr); + if (stm == NULL) /* invalid date? */ + lua_pushnil(L); + else if (strcmp(s, "*t") == 0) + { + lua_createtable(L, 0, 9); /* 9 = number of fields */ + setfield(L, "sec", stm->tm_sec); + setfield(L, "min", stm->tm_min); + setfield(L, "hour", stm->tm_hour); + setfield(L, "day", stm->tm_mday); + setfield(L, "month", stm->tm_mon + 1); + setfield(L, "year", stm->tm_year + 1900); + setfield(L, "wday", stm->tm_wday + 1); + setfield(L, "yday", stm->tm_yday + 1); + setboolfield(L, "isdst", stm->tm_isdst); + } + else + { + char cc[4]; + luaL_Buffer b; + cc[0] = '%'; + luaL_buffinit(L, &b); + while (*s) + { + if (*s != '%') /* no conversion specifier? */ + luaL_addchar(&b, *s++); + else + { + size_t reslen; + char buff[200]; /* should be big enough for any conversion result */ + s = checkoption(L, s + 1, cc); + reslen = strftime(buff, sizeof(buff), cc, stm); + luaL_addlstring(&b, buff, reslen); + } + } + luaL_pushresult(&b); + } + return 1; } - -static int os_time (lua_State *L) { - time_t t; - if (lua_isnoneornil(L, 1)) /* called without args? */ - t = time(NULL); /* get current time */ - else { - struct tm ts; - luaL_checktype(L, 1, LUA_TTABLE); - lua_settop(L, 1); /* make sure table is at the top */ - ts.tm_sec = getfield(L, "sec", 0); - ts.tm_min = getfield(L, "min", 0); - ts.tm_hour = getfield(L, "hour", 12); - ts.tm_mday = getfield(L, "day", -1); - ts.tm_mon = getfield(L, "month", -1) - 1; - ts.tm_year = getfield(L, "year", -1) - 1900; - ts.tm_isdst = getboolfield(L, "isdst"); - t = mktime(&ts); - } - if (t == (time_t)(-1)) - lua_pushnil(L); - else - lua_pushnumber(L, (lua_Number)t); - return 1; +static int os_time(lua_State *L) +{ + time_t t; + if (lua_isnoneornil(L, 1)) /* called without args? */ + t = time(NULL); /* get current time */ + else + { + struct tm ts; + luaL_checktype(L, 1, LUA_TTABLE); + lua_settop(L, 1); /* make sure table is at the top */ + ts.tm_sec = getfield(L, "sec", 0); + ts.tm_min = getfield(L, "min", 0); + ts.tm_hour = getfield(L, "hour", 12); + ts.tm_mday = getfield(L, "day", -1); + ts.tm_mon = getfield(L, "month", -1) - 1; + ts.tm_year = getfield(L, "year", -1) - 1900; + ts.tm_isdst = getboolfield(L, "isdst"); + t = mktime(&ts); + } + if (t == (time_t)(-1)) + lua_pushnil(L); + else + lua_pushnumber(L, (lua_Number)t); + return 1; } - -static int os_difftime (lua_State *L) { - lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), - (time_t)(luaL_optnumber(L, 2, 0)))); - return 1; +static int os_difftime(lua_State *L) +{ + lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)), + (time_t)(luaL_optnumber(L, 2, 0)))); + return 1; } /* }====================================================== */ - -static int os_setlocale (lua_State *L) { - static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, - LC_NUMERIC, LC_TIME}; - static const char *const catnames[] = {"all", "collate", "ctype", "monetary", - "numeric", "time", NULL}; - const char *l = luaL_optstring(L, 1, NULL); - int op = luaL_checkoption(L, 2, "all", catnames); - lua_pushstring(L, setlocale(cat[op], l)); - return 1; +static int os_setlocale(lua_State *L) +{ + static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY, + LC_NUMERIC, LC_TIME}; + static const char *const catnames[] = {"all", "collate", "ctype", "monetary", + "numeric", "time", NULL}; + const char *l = luaL_optstring(L, 1, NULL); + int op = luaL_checkoption(L, 2, "all", catnames); + lua_pushstring(L, setlocale(cat[op], l)); + return 1; } - -static int os_exit (lua_State *L) { - int status; - if (lua_isboolean(L, 1)) - status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE); - else - status = luaL_optint(L, 1, EXIT_SUCCESS); - if (lua_toboolean(L, 2)) - lua_close(L); - if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */ - return 0; +static int os_exit(lua_State *L) +{ + int status; + if (lua_isboolean(L, 1)) + status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE); + else + status = luaL_optint(L, 1, EXIT_SUCCESS); + if (lua_toboolean(L, 2)) + lua_close(L); + if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */ + return 0; } - static const luaL_Reg syslib[] = { - {"clock", os_clock}, - {"date", os_date}, - {"difftime", os_difftime}, - {"execute", os_execute}, - {"exit", os_exit}, - {"getenv", os_getenv}, - {"remove", os_remove}, - {"rename", os_rename}, - {"setlocale", os_setlocale}, - {"time", os_time}, - {"tmpname", os_tmpname}, - {NULL, NULL} -}; + {"clock", os_clock}, + {"date", os_date}, + {"difftime", os_difftime}, + {"execute", os_execute}, + {"exit", os_exit}, + {"getenv", os_getenv}, + {"remove", os_remove}, + {"rename", os_rename}, + {"setlocale", os_setlocale}, + {"time", os_time}, + {"tmpname", os_tmpname}, + {NULL, NULL}}; /* }====================================================== */ - - -LUAMOD_API int luaopen_os (lua_State *L) { - luaL_newlib(L, syslib); - return 1; +LUAMOD_API int luaopen_os(lua_State *L) +{ + luaL_newlib(L, syslib); + return 1; } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lparser.c b/examples/ThirdPartyLibs/lua-5.2.3/src/lparser.c index 9e1a9ca2c..0a6bfa0a3 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lparser.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lparser.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #include #define lparser_c @@ -25,1614 +24,1762 @@ #include "lstring.h" #include "ltable.h" - - /* maximum number of local variables per function (must be smaller than 250, due to the bytecode format) */ -#define MAXVARS 200 - - -#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) - +#define MAXVARS 200 +#define hasmultret(k) ((k) == VCALL || (k) == VVARARG) /* ** nodes for block list (list of active blocks) */ -typedef struct BlockCnt { - struct BlockCnt *previous; /* chain */ - short firstlabel; /* index of first label in this block */ - short firstgoto; /* index of first pending goto in this block */ - lu_byte nactvar; /* # active locals outside the block */ - lu_byte upval; /* true if some variable in the block is an upvalue */ - lu_byte isloop; /* true if `block' is a loop */ +typedef struct BlockCnt +{ + struct BlockCnt *previous; /* chain */ + short firstlabel; /* index of first label in this block */ + short firstgoto; /* index of first pending goto in this block */ + lu_byte nactvar; /* # active locals outside the block */ + lu_byte upval; /* true if some variable in the block is an upvalue */ + lu_byte isloop; /* true if `block' is a loop */ } BlockCnt; - - /* ** prototypes for recursive non-terminal functions */ -static void statement (LexState *ls); -static void expr (LexState *ls, expdesc *v); +static void statement(LexState *ls); +static void expr(LexState *ls, expdesc *v); - -static void anchor_token (LexState *ls) { - /* last token from outer function must be EOS */ - lua_assert(ls->fs != NULL || ls->t.token == TK_EOS); - if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) { - TString *ts = ls->t.seminfo.ts; - luaX_newstring(ls, getstr(ts), ts->tsv.len); - } +static void anchor_token(LexState *ls) +{ + /* last token from outer function must be EOS */ + lua_assert(ls->fs != NULL || ls->t.token == TK_EOS); + if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) + { + TString *ts = ls->t.seminfo.ts; + luaX_newstring(ls, getstr(ts), ts->tsv.len); + } } - /* semantic error */ -static l_noret semerror (LexState *ls, const char *msg) { - ls->t.token = 0; /* remove 'near to' from final message */ - luaX_syntaxerror(ls, msg); +static l_noret semerror(LexState *ls, const char *msg) +{ + ls->t.token = 0; /* remove 'near to' from final message */ + luaX_syntaxerror(ls, msg); } - -static l_noret error_expected (LexState *ls, int token) { - luaX_syntaxerror(ls, - luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token))); +static l_noret error_expected(LexState *ls, int token) +{ + luaX_syntaxerror(ls, + luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token))); } - -static l_noret errorlimit (FuncState *fs, int limit, const char *what) { - lua_State *L = fs->ls->L; - const char *msg; - int line = fs->f->linedefined; - const char *where = (line == 0) - ? "main function" - : luaO_pushfstring(L, "function at line %d", line); - msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s", - what, limit, where); - luaX_syntaxerror(fs->ls, msg); +static l_noret errorlimit(FuncState *fs, int limit, const char *what) +{ + lua_State *L = fs->ls->L; + const char *msg; + int line = fs->f->linedefined; + const char *where = (line == 0) + ? "main function" + : luaO_pushfstring(L, "function at line %d", line); + msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s", + what, limit, where); + luaX_syntaxerror(fs->ls, msg); } - -static void checklimit (FuncState *fs, int v, int l, const char *what) { - if (v > l) errorlimit(fs, l, what); +static void checklimit(FuncState *fs, int v, int l, const char *what) +{ + if (v > l) errorlimit(fs, l, what); } - -static int testnext (LexState *ls, int c) { - if (ls->t.token == c) { - luaX_next(ls); - return 1; - } - else return 0; +static int testnext(LexState *ls, int c) +{ + if (ls->t.token == c) + { + luaX_next(ls); + return 1; + } + else + return 0; } - -static void check (LexState *ls, int c) { - if (ls->t.token != c) - error_expected(ls, c); +static void check(LexState *ls, int c) +{ + if (ls->t.token != c) + error_expected(ls, c); } - -static void checknext (LexState *ls, int c) { - check(ls, c); - luaX_next(ls); +static void checknext(LexState *ls, int c) +{ + check(ls, c); + luaX_next(ls); } +#define check_condition(ls, c, msg) \ + { \ + if (!(c)) luaX_syntaxerror(ls, msg); \ + } -#define check_condition(ls,c,msg) { if (!(c)) luaX_syntaxerror(ls, msg); } - - - -static void check_match (LexState *ls, int what, int who, int where) { - if (!testnext(ls, what)) { - if (where == ls->linenumber) - error_expected(ls, what); - else { - luaX_syntaxerror(ls, luaO_pushfstring(ls->L, - "%s expected (to close %s at line %d)", - luaX_token2str(ls, what), luaX_token2str(ls, who), where)); - } - } +static void check_match(LexState *ls, int what, int who, int where) +{ + if (!testnext(ls, what)) + { + if (where == ls->linenumber) + error_expected(ls, what); + else + { + luaX_syntaxerror(ls, luaO_pushfstring(ls->L, + "%s expected (to close %s at line %d)", + luaX_token2str(ls, what), luaX_token2str(ls, who), where)); + } + } } - -static TString *str_checkname (LexState *ls) { - TString *ts; - check(ls, TK_NAME); - ts = ls->t.seminfo.ts; - luaX_next(ls); - return ts; +static TString *str_checkname(LexState *ls) +{ + TString *ts; + check(ls, TK_NAME); + ts = ls->t.seminfo.ts; + luaX_next(ls); + return ts; } - -static void init_exp (expdesc *e, expkind k, int i) { - e->f = e->t = NO_JUMP; - e->k = k; - e->u.info = i; +static void init_exp(expdesc *e, expkind k, int i) +{ + e->f = e->t = NO_JUMP; + e->k = k; + e->u.info = i; } - -static void codestring (LexState *ls, expdesc *e, TString *s) { - init_exp(e, VK, luaK_stringK(ls->fs, s)); +static void codestring(LexState *ls, expdesc *e, TString *s) +{ + init_exp(e, VK, luaK_stringK(ls->fs, s)); } - -static void checkname (LexState *ls, expdesc *e) { - codestring(ls, e, str_checkname(ls)); +static void checkname(LexState *ls, expdesc *e) +{ + codestring(ls, e, str_checkname(ls)); } - -static int registerlocalvar (LexState *ls, TString *varname) { - FuncState *fs = ls->fs; - Proto *f = fs->f; - int oldsize = f->sizelocvars; - luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, - LocVar, SHRT_MAX, "local variables"); - while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; - f->locvars[fs->nlocvars].varname = varname; - luaC_objbarrier(ls->L, f, varname); - return fs->nlocvars++; +static int registerlocalvar(LexState *ls, TString *varname) +{ + FuncState *fs = ls->fs; + Proto *f = fs->f; + int oldsize = f->sizelocvars; + luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars, + LocVar, SHRT_MAX, "local variables"); + while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL; + f->locvars[fs->nlocvars].varname = varname; + luaC_objbarrier(ls->L, f, varname); + return fs->nlocvars++; } - -static void new_localvar (LexState *ls, TString *name) { - FuncState *fs = ls->fs; - Dyndata *dyd = ls->dyd; - int reg = registerlocalvar(ls, name); - checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, - MAXVARS, "local variables"); - luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1, - dyd->actvar.size, Vardesc, MAX_INT, "local variables"); - dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg); +static void new_localvar(LexState *ls, TString *name) +{ + FuncState *fs = ls->fs; + Dyndata *dyd = ls->dyd; + int reg = registerlocalvar(ls, name); + checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal, + MAXVARS, "local variables"); + luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1, + dyd->actvar.size, Vardesc, MAX_INT, "local variables"); + dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg); } - -static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) { - new_localvar(ls, luaX_newstring(ls, name, sz)); +static void new_localvarliteral_(LexState *ls, const char *name, size_t sz) +{ + new_localvar(ls, luaX_newstring(ls, name, sz)); } -#define new_localvarliteral(ls,v) \ - new_localvarliteral_(ls, "" v, (sizeof(v)/sizeof(char))-1) +#define new_localvarliteral(ls, v) \ + new_localvarliteral_(ls, "" v, (sizeof(v) / sizeof(char)) - 1) - -static LocVar *getlocvar (FuncState *fs, int i) { - int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx; - lua_assert(idx < fs->nlocvars); - return &fs->f->locvars[idx]; +static LocVar *getlocvar(FuncState *fs, int i) +{ + int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx; + lua_assert(idx < fs->nlocvars); + return &fs->f->locvars[idx]; } - -static void adjustlocalvars (LexState *ls, int nvars) { - FuncState *fs = ls->fs; - fs->nactvar = cast_byte(fs->nactvar + nvars); - for (; nvars; nvars--) { - getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc; - } +static void adjustlocalvars(LexState *ls, int nvars) +{ + FuncState *fs = ls->fs; + fs->nactvar = cast_byte(fs->nactvar + nvars); + for (; nvars; nvars--) + { + getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc; + } } - -static void removevars (FuncState *fs, int tolevel) { - fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); - while (fs->nactvar > tolevel) - getlocvar(fs, --fs->nactvar)->endpc = fs->pc; +static void removevars(FuncState *fs, int tolevel) +{ + fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel); + while (fs->nactvar > tolevel) + getlocvar(fs, --fs->nactvar)->endpc = fs->pc; } - -static int searchupvalue (FuncState *fs, TString *name) { - int i; - Upvaldesc *up = fs->f->upvalues; - for (i = 0; i < fs->nups; i++) { - if (luaS_eqstr(up[i].name, name)) return i; - } - return -1; /* not found */ +static int searchupvalue(FuncState *fs, TString *name) +{ + int i; + Upvaldesc *up = fs->f->upvalues; + for (i = 0; i < fs->nups; i++) + { + if (luaS_eqstr(up[i].name, name)) return i; + } + return -1; /* not found */ } - -static int newupvalue (FuncState *fs, TString *name, expdesc *v) { - Proto *f = fs->f; - int oldsize = f->sizeupvalues; - checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues"); - luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues, - Upvaldesc, MAXUPVAL, "upvalues"); - while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL; - f->upvalues[fs->nups].instack = (v->k == VLOCAL); - f->upvalues[fs->nups].idx = cast_byte(v->u.info); - f->upvalues[fs->nups].name = name; - luaC_objbarrier(fs->ls->L, f, name); - return fs->nups++; +static int newupvalue(FuncState *fs, TString *name, expdesc *v) +{ + Proto *f = fs->f; + int oldsize = f->sizeupvalues; + checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues"); + luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues, + Upvaldesc, MAXUPVAL, "upvalues"); + while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL; + f->upvalues[fs->nups].instack = (v->k == VLOCAL); + f->upvalues[fs->nups].idx = cast_byte(v->u.info); + f->upvalues[fs->nups].name = name; + luaC_objbarrier(fs->ls->L, f, name); + return fs->nups++; } - -static int searchvar (FuncState *fs, TString *n) { - int i; - for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) { - if (luaS_eqstr(n, getlocvar(fs, i)->varname)) - return i; - } - return -1; /* not found */ +static int searchvar(FuncState *fs, TString *n) +{ + int i; + for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) + { + if (luaS_eqstr(n, getlocvar(fs, i)->varname)) + return i; + } + return -1; /* not found */ } - /* Mark block where variable at given level was defined (to emit close instructions later). */ -static void markupval (FuncState *fs, int level) { - BlockCnt *bl = fs->bl; - while (bl->nactvar > level) bl = bl->previous; - bl->upval = 1; +static void markupval(FuncState *fs, int level) +{ + BlockCnt *bl = fs->bl; + while (bl->nactvar > level) bl = bl->previous; + bl->upval = 1; } - /* Find variable with given name 'n'. If it is an upvalue, add this upvalue into all intermediate functions. */ -static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) { - if (fs == NULL) /* no more levels? */ - return VVOID; /* default is global */ - else { - int v = searchvar(fs, n); /* look up locals at current level */ - if (v >= 0) { /* found? */ - init_exp(var, VLOCAL, v); /* variable is local */ - if (!base) - markupval(fs, v); /* local will be used as an upval */ - return VLOCAL; - } - else { /* not found as local at current level; try upvalues */ - int idx = searchupvalue(fs, n); /* try existing upvalues */ - if (idx < 0) { /* not found? */ - if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */ - return VVOID; /* not found; is a global */ - /* else was LOCAL or UPVAL */ - idx = newupvalue(fs, n, var); /* will be a new upvalue */ - } - init_exp(var, VUPVAL, idx); - return VUPVAL; - } - } +static int singlevaraux(FuncState *fs, TString *n, expdesc *var, int base) +{ + if (fs == NULL) /* no more levels? */ + return VVOID; /* default is global */ + else + { + int v = searchvar(fs, n); /* look up locals at current level */ + if (v >= 0) + { /* found? */ + init_exp(var, VLOCAL, v); /* variable is local */ + if (!base) + markupval(fs, v); /* local will be used as an upval */ + return VLOCAL; + } + else + { /* not found as local at current level; try upvalues */ + int idx = searchupvalue(fs, n); /* try existing upvalues */ + if (idx < 0) + { /* not found? */ + if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */ + return VVOID; /* not found; is a global */ + /* else was LOCAL or UPVAL */ + idx = newupvalue(fs, n, var); /* will be a new upvalue */ + } + init_exp(var, VUPVAL, idx); + return VUPVAL; + } + } } - -static void singlevar (LexState *ls, expdesc *var) { - TString *varname = str_checkname(ls); - FuncState *fs = ls->fs; - if (singlevaraux(fs, varname, var, 1) == VVOID) { /* global name? */ - expdesc key; - singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ - lua_assert(var->k == VLOCAL || var->k == VUPVAL); - codestring(ls, &key, varname); /* key is variable name */ - luaK_indexed(fs, var, &key); /* env[varname] */ - } +static void singlevar(LexState *ls, expdesc *var) +{ + TString *varname = str_checkname(ls); + FuncState *fs = ls->fs; + if (singlevaraux(fs, varname, var, 1) == VVOID) + { /* global name? */ + expdesc key; + singlevaraux(fs, ls->envn, var, 1); /* get environment variable */ + lua_assert(var->k == VLOCAL || var->k == VUPVAL); + codestring(ls, &key, varname); /* key is variable name */ + luaK_indexed(fs, var, &key); /* env[varname] */ + } } - -static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { - FuncState *fs = ls->fs; - int extra = nvars - nexps; - if (hasmultret(e->k)) { - extra++; /* includes call itself */ - if (extra < 0) extra = 0; - luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ - if (extra > 1) luaK_reserveregs(fs, extra-1); - } - else { - if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ - if (extra > 0) { - int reg = fs->freereg; - luaK_reserveregs(fs, extra); - luaK_nil(fs, reg, extra); - } - } +static void adjust_assign(LexState *ls, int nvars, int nexps, expdesc *e) +{ + FuncState *fs = ls->fs; + int extra = nvars - nexps; + if (hasmultret(e->k)) + { + extra++; /* includes call itself */ + if (extra < 0) extra = 0; + luaK_setreturns(fs, e, extra); /* last exp. provides the difference */ + if (extra > 1) luaK_reserveregs(fs, extra - 1); + } + else + { + if (e->k != VVOID) luaK_exp2nextreg(fs, e); /* close last expression */ + if (extra > 0) + { + int reg = fs->freereg; + luaK_reserveregs(fs, extra); + luaK_nil(fs, reg, extra); + } + } } - -static void enterlevel (LexState *ls) { - lua_State *L = ls->L; - ++L->nCcalls; - checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels"); +static void enterlevel(LexState *ls) +{ + lua_State *L = ls->L; + ++L->nCcalls; + checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels"); } +#define leavelevel(ls) ((ls)->L->nCcalls--) -#define leavelevel(ls) ((ls)->L->nCcalls--) - - -static void closegoto (LexState *ls, int g, Labeldesc *label) { - int i; - FuncState *fs = ls->fs; - Labellist *gl = &ls->dyd->gt; - Labeldesc *gt = &gl->arr[g]; - lua_assert(luaS_eqstr(gt->name, label->name)); - if (gt->nactvar < label->nactvar) { - TString *vname = getlocvar(fs, gt->nactvar)->varname; - const char *msg = luaO_pushfstring(ls->L, - " at line %d jumps into the scope of local " LUA_QS, - getstr(gt->name), gt->line, getstr(vname)); - semerror(ls, msg); - } - luaK_patchlist(fs, gt->pc, label->pc); - /* remove goto from pending list */ - for (i = g; i < gl->n - 1; i++) - gl->arr[i] = gl->arr[i + 1]; - gl->n--; +static void closegoto(LexState *ls, int g, Labeldesc *label) +{ + int i; + FuncState *fs = ls->fs; + Labellist *gl = &ls->dyd->gt; + Labeldesc *gt = &gl->arr[g]; + lua_assert(luaS_eqstr(gt->name, label->name)); + if (gt->nactvar < label->nactvar) + { + TString *vname = getlocvar(fs, gt->nactvar)->varname; + const char *msg = luaO_pushfstring(ls->L, + " at line %d jumps into the scope of local " LUA_QS, + getstr(gt->name), gt->line, getstr(vname)); + semerror(ls, msg); + } + luaK_patchlist(fs, gt->pc, label->pc); + /* remove goto from pending list */ + for (i = g; i < gl->n - 1; i++) + gl->arr[i] = gl->arr[i + 1]; + gl->n--; } - /* ** try to close a goto with existing labels; this solves backward jumps */ -static int findlabel (LexState *ls, int g) { - int i; - BlockCnt *bl = ls->fs->bl; - Dyndata *dyd = ls->dyd; - Labeldesc *gt = &dyd->gt.arr[g]; - /* check labels in current block for a match */ - for (i = bl->firstlabel; i < dyd->label.n; i++) { - Labeldesc *lb = &dyd->label.arr[i]; - if (luaS_eqstr(lb->name, gt->name)) { /* correct label? */ - if (gt->nactvar > lb->nactvar && - (bl->upval || dyd->label.n > bl->firstlabel)) - luaK_patchclose(ls->fs, gt->pc, lb->nactvar); - closegoto(ls, g, lb); /* close it */ - return 1; - } - } - return 0; /* label not found; cannot close goto */ +static int findlabel(LexState *ls, int g) +{ + int i; + BlockCnt *bl = ls->fs->bl; + Dyndata *dyd = ls->dyd; + Labeldesc *gt = &dyd->gt.arr[g]; + /* check labels in current block for a match */ + for (i = bl->firstlabel; i < dyd->label.n; i++) + { + Labeldesc *lb = &dyd->label.arr[i]; + if (luaS_eqstr(lb->name, gt->name)) + { /* correct label? */ + if (gt->nactvar > lb->nactvar && + (bl->upval || dyd->label.n > bl->firstlabel)) + luaK_patchclose(ls->fs, gt->pc, lb->nactvar); + closegoto(ls, g, lb); /* close it */ + return 1; + } + } + return 0; /* label not found; cannot close goto */ } - -static int newlabelentry (LexState *ls, Labellist *l, TString *name, - int line, int pc) { - int n = l->n; - luaM_growvector(ls->L, l->arr, n, l->size, - Labeldesc, SHRT_MAX, "labels/gotos"); - l->arr[n].name = name; - l->arr[n].line = line; - l->arr[n].nactvar = ls->fs->nactvar; - l->arr[n].pc = pc; - l->n++; - return n; +static int newlabelentry(LexState *ls, Labellist *l, TString *name, + int line, int pc) +{ + int n = l->n; + luaM_growvector(ls->L, l->arr, n, l->size, + Labeldesc, SHRT_MAX, "labels/gotos"); + l->arr[n].name = name; + l->arr[n].line = line; + l->arr[n].nactvar = ls->fs->nactvar; + l->arr[n].pc = pc; + l->n++; + return n; } - /* ** check whether new label 'lb' matches any pending gotos in current ** block; solves forward jumps */ -static void findgotos (LexState *ls, Labeldesc *lb) { - Labellist *gl = &ls->dyd->gt; - int i = ls->fs->bl->firstgoto; - while (i < gl->n) { - if (luaS_eqstr(gl->arr[i].name, lb->name)) - closegoto(ls, i, lb); - else - i++; - } +static void findgotos(LexState *ls, Labeldesc *lb) +{ + Labellist *gl = &ls->dyd->gt; + int i = ls->fs->bl->firstgoto; + while (i < gl->n) + { + if (luaS_eqstr(gl->arr[i].name, lb->name)) + closegoto(ls, i, lb); + else + i++; + } } - /* ** "export" pending gotos to outer level, to check them against ** outer labels; if the block being exited has upvalues, and ** the goto exits the scope of any variable (which can be the ** upvalue), close those variables being exited. */ -static void movegotosout (FuncState *fs, BlockCnt *bl) { - int i = bl->firstgoto; - Labellist *gl = &fs->ls->dyd->gt; - /* correct pending gotos to current block and try to close it +static void movegotosout(FuncState *fs, BlockCnt *bl) +{ + int i = bl->firstgoto; + Labellist *gl = &fs->ls->dyd->gt; + /* correct pending gotos to current block and try to close it with visible labels */ - while (i < gl->n) { - Labeldesc *gt = &gl->arr[i]; - if (gt->nactvar > bl->nactvar) { - if (bl->upval) - luaK_patchclose(fs, gt->pc, bl->nactvar); - gt->nactvar = bl->nactvar; - } - if (!findlabel(fs->ls, i)) - i++; /* move to next one */ - } + while (i < gl->n) + { + Labeldesc *gt = &gl->arr[i]; + if (gt->nactvar > bl->nactvar) + { + if (bl->upval) + luaK_patchclose(fs, gt->pc, bl->nactvar); + gt->nactvar = bl->nactvar; + } + if (!findlabel(fs->ls, i)) + i++; /* move to next one */ + } } - -static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) { - bl->isloop = isloop; - bl->nactvar = fs->nactvar; - bl->firstlabel = fs->ls->dyd->label.n; - bl->firstgoto = fs->ls->dyd->gt.n; - bl->upval = 0; - bl->previous = fs->bl; - fs->bl = bl; - lua_assert(fs->freereg == fs->nactvar); +static void enterblock(FuncState *fs, BlockCnt *bl, lu_byte isloop) +{ + bl->isloop = isloop; + bl->nactvar = fs->nactvar; + bl->firstlabel = fs->ls->dyd->label.n; + bl->firstgoto = fs->ls->dyd->gt.n; + bl->upval = 0; + bl->previous = fs->bl; + fs->bl = bl; + lua_assert(fs->freereg == fs->nactvar); } - /* ** create a label named "break" to resolve break statements */ -static void breaklabel (LexState *ls) { - TString *n = luaS_new(ls->L, "break"); - int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc); - findgotos(ls, &ls->dyd->label.arr[l]); +static void breaklabel(LexState *ls) +{ + TString *n = luaS_new(ls->L, "break"); + int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc); + findgotos(ls, &ls->dyd->label.arr[l]); } /* ** generates an error for an undefined 'goto'; choose appropriate ** message when label name is a reserved word (which can only be 'break') */ -static l_noret undefgoto (LexState *ls, Labeldesc *gt) { - const char *msg = isreserved(gt->name) - ? "<%s> at line %d not inside a loop" - : "no visible label " LUA_QS " for at line %d"; - msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); - semerror(ls, msg); +static l_noret undefgoto(LexState *ls, Labeldesc *gt) +{ + const char *msg = isreserved(gt->name) + ? "<%s> at line %d not inside a loop" + : "no visible label " LUA_QS " for at line %d"; + msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line); + semerror(ls, msg); } - -static void leaveblock (FuncState *fs) { - BlockCnt *bl = fs->bl; - LexState *ls = fs->ls; - if (bl->previous && bl->upval) { - /* create a 'jump to here' to close upvalues */ - int j = luaK_jump(fs); - luaK_patchclose(fs, j, bl->nactvar); - luaK_patchtohere(fs, j); - } - if (bl->isloop) - breaklabel(ls); /* close pending breaks */ - fs->bl = bl->previous; - removevars(fs, bl->nactvar); - lua_assert(bl->nactvar == fs->nactvar); - fs->freereg = fs->nactvar; /* free registers */ - ls->dyd->label.n = bl->firstlabel; /* remove local labels */ - if (bl->previous) /* inner block? */ - movegotosout(fs, bl); /* update pending gotos to outer block */ - else if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */ - undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */ +static void leaveblock(FuncState *fs) +{ + BlockCnt *bl = fs->bl; + LexState *ls = fs->ls; + if (bl->previous && bl->upval) + { + /* create a 'jump to here' to close upvalues */ + int j = luaK_jump(fs); + luaK_patchclose(fs, j, bl->nactvar); + luaK_patchtohere(fs, j); + } + if (bl->isloop) + breaklabel(ls); /* close pending breaks */ + fs->bl = bl->previous; + removevars(fs, bl->nactvar); + lua_assert(bl->nactvar == fs->nactvar); + fs->freereg = fs->nactvar; /* free registers */ + ls->dyd->label.n = bl->firstlabel; /* remove local labels */ + if (bl->previous) /* inner block? */ + movegotosout(fs, bl); /* update pending gotos to outer block */ + else if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */ + undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */ } - /* ** adds a new prototype into list of prototypes */ -static Proto *addprototype (LexState *ls) { - Proto *clp; - lua_State *L = ls->L; - FuncState *fs = ls->fs; - Proto *f = fs->f; /* prototype of current function */ - if (fs->np >= f->sizep) { - int oldsize = f->sizep; - luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions"); - while (oldsize < f->sizep) f->p[oldsize++] = NULL; - } - f->p[fs->np++] = clp = luaF_newproto(L); - luaC_objbarrier(L, f, clp); - return clp; +static Proto *addprototype(LexState *ls) +{ + Proto *clp; + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Proto *f = fs->f; /* prototype of current function */ + if (fs->np >= f->sizep) + { + int oldsize = f->sizep; + luaM_growvector(L, f->p, fs->np, f->sizep, Proto *, MAXARG_Bx, "functions"); + while (oldsize < f->sizep) f->p[oldsize++] = NULL; + } + f->p[fs->np++] = clp = luaF_newproto(L); + luaC_objbarrier(L, f, clp); + return clp; } - /* ** codes instruction to create new closure in parent function. ** The OP_CLOSURE instruction must use the last available register, ** so that, if it invokes the GC, the GC knows which registers ** are in use at that time. */ -static void codeclosure (LexState *ls, expdesc *v) { - FuncState *fs = ls->fs->prev; - init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1)); - luaK_exp2nextreg(fs, v); /* fix it at the last register */ +static void codeclosure(LexState *ls, expdesc *v) +{ + FuncState *fs = ls->fs->prev; + init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np - 1)); + luaK_exp2nextreg(fs, v); /* fix it at the last register */ } - -static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { - lua_State *L = ls->L; - Proto *f; - fs->prev = ls->fs; /* linked list of funcstates */ - fs->ls = ls; - ls->fs = fs; - fs->pc = 0; - fs->lasttarget = 0; - fs->jpc = NO_JUMP; - fs->freereg = 0; - fs->nk = 0; - fs->np = 0; - fs->nups = 0; - fs->nlocvars = 0; - fs->nactvar = 0; - fs->firstlocal = ls->dyd->actvar.n; - fs->bl = NULL; - f = fs->f; - f->source = ls->source; - f->maxstacksize = 2; /* registers 0/1 are always valid */ - fs->h = luaH_new(L); - /* anchor table of constants (to avoid being collected) */ - sethvalue2s(L, L->top, fs->h); - incr_top(L); - enterblock(fs, bl, 0); +static void open_func(LexState *ls, FuncState *fs, BlockCnt *bl) +{ + lua_State *L = ls->L; + Proto *f; + fs->prev = ls->fs; /* linked list of funcstates */ + fs->ls = ls; + ls->fs = fs; + fs->pc = 0; + fs->lasttarget = 0; + fs->jpc = NO_JUMP; + fs->freereg = 0; + fs->nk = 0; + fs->np = 0; + fs->nups = 0; + fs->nlocvars = 0; + fs->nactvar = 0; + fs->firstlocal = ls->dyd->actvar.n; + fs->bl = NULL; + f = fs->f; + f->source = ls->source; + f->maxstacksize = 2; /* registers 0/1 are always valid */ + fs->h = luaH_new(L); + /* anchor table of constants (to avoid being collected) */ + sethvalue2s(L, L->top, fs->h); + incr_top(L); + enterblock(fs, bl, 0); } - -static void close_func (LexState *ls) { - lua_State *L = ls->L; - FuncState *fs = ls->fs; - Proto *f = fs->f; - luaK_ret(fs, 0, 0); /* final return */ - leaveblock(fs); - luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); - f->sizecode = fs->pc; - luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); - f->sizelineinfo = fs->pc; - luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); - f->sizek = fs->nk; - luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); - f->sizep = fs->np; - luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); - f->sizelocvars = fs->nlocvars; - luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); - f->sizeupvalues = fs->nups; - lua_assert(fs->bl == NULL); - ls->fs = fs->prev; - /* last token read was anchored in defunct function; must re-anchor it */ - anchor_token(ls); - L->top--; /* pop table of constants */ - luaC_checkGC(L); +static void close_func(LexState *ls) +{ + lua_State *L = ls->L; + FuncState *fs = ls->fs; + Proto *f = fs->f; + luaK_ret(fs, 0, 0); /* final return */ + leaveblock(fs); + luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction); + f->sizecode = fs->pc; + luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int); + f->sizelineinfo = fs->pc; + luaM_reallocvector(L, f->k, f->sizek, fs->nk, TValue); + f->sizek = fs->nk; + luaM_reallocvector(L, f->p, f->sizep, fs->np, Proto *); + f->sizep = fs->np; + luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar); + f->sizelocvars = fs->nlocvars; + luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc); + f->sizeupvalues = fs->nups; + lua_assert(fs->bl == NULL); + ls->fs = fs->prev; + /* last token read was anchored in defunct function; must re-anchor it */ + anchor_token(ls); + L->top--; /* pop table of constants */ + luaC_checkGC(L); } - - /*============================================================*/ /* GRAMMAR RULES */ /*============================================================*/ - /* ** check whether current token is in the follow set of a block. ** 'until' closes syntactical blocks, but do not close scope, ** so it handled in separate. */ -static int block_follow (LexState *ls, int withuntil) { - switch (ls->t.token) { - case TK_ELSE: case TK_ELSEIF: - case TK_END: case TK_EOS: - return 1; - case TK_UNTIL: return withuntil; - default: return 0; - } +static int block_follow(LexState *ls, int withuntil) +{ + switch (ls->t.token) + { + case TK_ELSE: + case TK_ELSEIF: + case TK_END: + case TK_EOS: + return 1; + case TK_UNTIL: + return withuntil; + default: + return 0; + } } - -static void statlist (LexState *ls) { - /* statlist -> { stat [`;'] } */ - while (!block_follow(ls, 1)) { - if (ls->t.token == TK_RETURN) { - statement(ls); - return; /* 'return' must be last statement */ - } - statement(ls); - } +static void statlist(LexState *ls) +{ + /* statlist -> { stat [`;'] } */ + while (!block_follow(ls, 1)) + { + if (ls->t.token == TK_RETURN) + { + statement(ls); + return; /* 'return' must be last statement */ + } + statement(ls); + } } - -static void fieldsel (LexState *ls, expdesc *v) { - /* fieldsel -> ['.' | ':'] NAME */ - FuncState *fs = ls->fs; - expdesc key; - luaK_exp2anyregup(fs, v); - luaX_next(ls); /* skip the dot or colon */ - checkname(ls, &key); - luaK_indexed(fs, v, &key); +static void fieldsel(LexState *ls, expdesc *v) +{ + /* fieldsel -> ['.' | ':'] NAME */ + FuncState *fs = ls->fs; + expdesc key; + luaK_exp2anyregup(fs, v); + luaX_next(ls); /* skip the dot or colon */ + checkname(ls, &key); + luaK_indexed(fs, v, &key); } - -static void yindex (LexState *ls, expdesc *v) { - /* index -> '[' expr ']' */ - luaX_next(ls); /* skip the '[' */ - expr(ls, v); - luaK_exp2val(ls->fs, v); - checknext(ls, ']'); +static void yindex(LexState *ls, expdesc *v) +{ + /* index -> '[' expr ']' */ + luaX_next(ls); /* skip the '[' */ + expr(ls, v); + luaK_exp2val(ls->fs, v); + checknext(ls, ']'); } - /* ** {====================================================================== ** Rules for Constructors ** ======================================================================= */ - -struct ConsControl { - expdesc v; /* last list item read */ - expdesc *t; /* table descriptor */ - int nh; /* total number of `record' elements */ - int na; /* total number of array elements */ - int tostore; /* number of array elements pending to be stored */ +struct ConsControl +{ + expdesc v; /* last list item read */ + expdesc *t; /* table descriptor */ + int nh; /* total number of `record' elements */ + int na; /* total number of array elements */ + int tostore; /* number of array elements pending to be stored */ }; - -static void recfield (LexState *ls, struct ConsControl *cc) { - /* recfield -> (NAME | `['exp1`]') = exp1 */ - FuncState *fs = ls->fs; - int reg = ls->fs->freereg; - expdesc key, val; - int rkkey; - if (ls->t.token == TK_NAME) { - checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); - checkname(ls, &key); - } - else /* ls->t.token == '[' */ - yindex(ls, &key); - cc->nh++; - checknext(ls, '='); - rkkey = luaK_exp2RK(fs, &key); - expr(ls, &val); - luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val)); - fs->freereg = reg; /* free registers */ +static void recfield(LexState *ls, struct ConsControl *cc) +{ + /* recfield -> (NAME | `['exp1`]') = exp1 */ + FuncState *fs = ls->fs; + int reg = ls->fs->freereg; + expdesc key, val; + int rkkey; + if (ls->t.token == TK_NAME) + { + checklimit(fs, cc->nh, MAX_INT, "items in a constructor"); + checkname(ls, &key); + } + else /* ls->t.token == '[' */ + yindex(ls, &key); + cc->nh++; + checknext(ls, '='); + rkkey = luaK_exp2RK(fs, &key); + expr(ls, &val); + luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val)); + fs->freereg = reg; /* free registers */ } - -static void closelistfield (FuncState *fs, struct ConsControl *cc) { - if (cc->v.k == VVOID) return; /* there is no list item */ - luaK_exp2nextreg(fs, &cc->v); - cc->v.k = VVOID; - if (cc->tostore == LFIELDS_PER_FLUSH) { - luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */ - cc->tostore = 0; /* no more items pending */ - } +static void closelistfield(FuncState *fs, struct ConsControl *cc) +{ + if (cc->v.k == VVOID) return; /* there is no list item */ + luaK_exp2nextreg(fs, &cc->v); + cc->v.k = VVOID; + if (cc->tostore == LFIELDS_PER_FLUSH) + { + luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */ + cc->tostore = 0; /* no more items pending */ + } } - -static void lastlistfield (FuncState *fs, struct ConsControl *cc) { - if (cc->tostore == 0) return; - if (hasmultret(cc->v.k)) { - luaK_setmultret(fs, &cc->v); - luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET); - cc->na--; /* do not count last expression (unknown number of elements) */ - } - else { - if (cc->v.k != VVOID) - luaK_exp2nextreg(fs, &cc->v); - luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); - } +static void lastlistfield(FuncState *fs, struct ConsControl *cc) +{ + if (cc->tostore == 0) return; + if (hasmultret(cc->v.k)) + { + luaK_setmultret(fs, &cc->v); + luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET); + cc->na--; /* do not count last expression (unknown number of elements) */ + } + else + { + if (cc->v.k != VVOID) + luaK_exp2nextreg(fs, &cc->v); + luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); + } } - -static void listfield (LexState *ls, struct ConsControl *cc) { - /* listfield -> exp */ - expr(ls, &cc->v); - checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); - cc->na++; - cc->tostore++; +static void listfield(LexState *ls, struct ConsControl *cc) +{ + /* listfield -> exp */ + expr(ls, &cc->v); + checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor"); + cc->na++; + cc->tostore++; } - -static void field (LexState *ls, struct ConsControl *cc) { - /* field -> listfield | recfield */ - switch(ls->t.token) { - case TK_NAME: { /* may be 'listfield' or 'recfield' */ - if (luaX_lookahead(ls) != '=') /* expression? */ - listfield(ls, cc); - else - recfield(ls, cc); - break; - } - case '[': { - recfield(ls, cc); - break; - } - default: { - listfield(ls, cc); - break; - } - } +static void field(LexState *ls, struct ConsControl *cc) +{ + /* field -> listfield | recfield */ + switch (ls->t.token) + { + case TK_NAME: + { /* may be 'listfield' or 'recfield' */ + if (luaX_lookahead(ls) != '=') /* expression? */ + listfield(ls, cc); + else + recfield(ls, cc); + break; + } + case '[': + { + recfield(ls, cc); + break; + } + default: + { + listfield(ls, cc); + break; + } + } } - -static void constructor (LexState *ls, expdesc *t) { - /* constructor -> '{' [ field { sep field } [sep] ] '}' +static void constructor(LexState *ls, expdesc *t) +{ + /* constructor -> '{' [ field { sep field } [sep] ] '}' sep -> ',' | ';' */ - FuncState *fs = ls->fs; - int line = ls->linenumber; - int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); - struct ConsControl cc; - cc.na = cc.nh = cc.tostore = 0; - cc.t = t; - init_exp(t, VRELOCABLE, pc); - init_exp(&cc.v, VVOID, 0); /* no value (yet) */ - luaK_exp2nextreg(ls->fs, t); /* fix it at stack top */ - checknext(ls, '{'); - do { - lua_assert(cc.v.k == VVOID || cc.tostore > 0); - if (ls->t.token == '}') break; - closelistfield(fs, &cc); - field(ls, &cc); - } while (testnext(ls, ',') || testnext(ls, ';')); - check_match(ls, '}', '{', line); - lastlistfield(fs, &cc); - SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ - SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ + FuncState *fs = ls->fs; + int line = ls->linenumber; + int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0); + struct ConsControl cc; + cc.na = cc.nh = cc.tostore = 0; + cc.t = t; + init_exp(t, VRELOCABLE, pc); + init_exp(&cc.v, VVOID, 0); /* no value (yet) */ + luaK_exp2nextreg(ls->fs, t); /* fix it at stack top */ + checknext(ls, '{'); + do + { + lua_assert(cc.v.k == VVOID || cc.tostore > 0); + if (ls->t.token == '}') break; + closelistfield(fs, &cc); + field(ls, &cc); + } while (testnext(ls, ',') || testnext(ls, ';')); + check_match(ls, '}', '{', line); + lastlistfield(fs, &cc); + SETARG_B(fs->f->code[pc], luaO_int2fb(cc.na)); /* set initial array size */ + SETARG_C(fs->f->code[pc], luaO_int2fb(cc.nh)); /* set initial table size */ } /* }====================================================================== */ - - -static void parlist (LexState *ls) { - /* parlist -> [ param { `,' param } ] */ - FuncState *fs = ls->fs; - Proto *f = fs->f; - int nparams = 0; - f->is_vararg = 0; - if (ls->t.token != ')') { /* is `parlist' not empty? */ - do { - switch (ls->t.token) { - case TK_NAME: { /* param -> NAME */ - new_localvar(ls, str_checkname(ls)); - nparams++; - break; - } - case TK_DOTS: { /* param -> `...' */ - luaX_next(ls); - f->is_vararg = 1; - break; - } - default: luaX_syntaxerror(ls, " or " LUA_QL("...") " expected"); - } - } while (!f->is_vararg && testnext(ls, ',')); - } - adjustlocalvars(ls, nparams); - f->numparams = cast_byte(fs->nactvar); - luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ +static void parlist(LexState *ls) +{ + /* parlist -> [ param { `,' param } ] */ + FuncState *fs = ls->fs; + Proto *f = fs->f; + int nparams = 0; + f->is_vararg = 0; + if (ls->t.token != ')') + { /* is `parlist' not empty? */ + do + { + switch (ls->t.token) + { + case TK_NAME: + { /* param -> NAME */ + new_localvar(ls, str_checkname(ls)); + nparams++; + break; + } + case TK_DOTS: + { /* param -> `...' */ + luaX_next(ls); + f->is_vararg = 1; + break; + } + default: + luaX_syntaxerror(ls, " or " LUA_QL("...") " expected"); + } + } while (!f->is_vararg && testnext(ls, ',')); + } + adjustlocalvars(ls, nparams); + f->numparams = cast_byte(fs->nactvar); + luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */ } - -static void body (LexState *ls, expdesc *e, int ismethod, int line) { - /* body -> `(' parlist `)' block END */ - FuncState new_fs; - BlockCnt bl; - new_fs.f = addprototype(ls); - new_fs.f->linedefined = line; - open_func(ls, &new_fs, &bl); - checknext(ls, '('); - if (ismethod) { - new_localvarliteral(ls, "self"); /* create 'self' parameter */ - adjustlocalvars(ls, 1); - } - parlist(ls); - checknext(ls, ')'); - statlist(ls); - new_fs.f->lastlinedefined = ls->linenumber; - check_match(ls, TK_END, TK_FUNCTION, line); - codeclosure(ls, e); - close_func(ls); +static void body(LexState *ls, expdesc *e, int ismethod, int line) +{ + /* body -> `(' parlist `)' block END */ + FuncState new_fs; + BlockCnt bl; + new_fs.f = addprototype(ls); + new_fs.f->linedefined = line; + open_func(ls, &new_fs, &bl); + checknext(ls, '('); + if (ismethod) + { + new_localvarliteral(ls, "self"); /* create 'self' parameter */ + adjustlocalvars(ls, 1); + } + parlist(ls); + checknext(ls, ')'); + statlist(ls); + new_fs.f->lastlinedefined = ls->linenumber; + check_match(ls, TK_END, TK_FUNCTION, line); + codeclosure(ls, e); + close_func(ls); } - -static int explist (LexState *ls, expdesc *v) { - /* explist -> expr { `,' expr } */ - int n = 1; /* at least one expression */ - expr(ls, v); - while (testnext(ls, ',')) { - luaK_exp2nextreg(ls->fs, v); - expr(ls, v); - n++; - } - return n; +static int explist(LexState *ls, expdesc *v) +{ + /* explist -> expr { `,' expr } */ + int n = 1; /* at least one expression */ + expr(ls, v); + while (testnext(ls, ',')) + { + luaK_exp2nextreg(ls->fs, v); + expr(ls, v); + n++; + } + return n; } - -static void funcargs (LexState *ls, expdesc *f, int line) { - FuncState *fs = ls->fs; - expdesc args; - int base, nparams; - switch (ls->t.token) { - case '(': { /* funcargs -> `(' [ explist ] `)' */ - luaX_next(ls); - if (ls->t.token == ')') /* arg list is empty? */ - args.k = VVOID; - else { - explist(ls, &args); - luaK_setmultret(fs, &args); - } - check_match(ls, ')', '(', line); - break; - } - case '{': { /* funcargs -> constructor */ - constructor(ls, &args); - break; - } - case TK_STRING: { /* funcargs -> STRING */ - codestring(ls, &args, ls->t.seminfo.ts); - luaX_next(ls); /* must use `seminfo' before `next' */ - break; - } - default: { - luaX_syntaxerror(ls, "function arguments expected"); - } - } - lua_assert(f->k == VNONRELOC); - base = f->u.info; /* base register for call */ - if (hasmultret(args.k)) - nparams = LUA_MULTRET; /* open call */ - else { - if (args.k != VVOID) - luaK_exp2nextreg(fs, &args); /* close last argument */ - nparams = fs->freereg - (base+1); - } - init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); - luaK_fixline(fs, line); - fs->freereg = base+1; /* call remove function and arguments and leaves +static void funcargs(LexState *ls, expdesc *f, int line) +{ + FuncState *fs = ls->fs; + expdesc args; + int base, nparams; + switch (ls->t.token) + { + case '(': + { /* funcargs -> `(' [ explist ] `)' */ + luaX_next(ls); + if (ls->t.token == ')') /* arg list is empty? */ + args.k = VVOID; + else + { + explist(ls, &args); + luaK_setmultret(fs, &args); + } + check_match(ls, ')', '(', line); + break; + } + case '{': + { /* funcargs -> constructor */ + constructor(ls, &args); + break; + } + case TK_STRING: + { /* funcargs -> STRING */ + codestring(ls, &args, ls->t.seminfo.ts); + luaX_next(ls); /* must use `seminfo' before `next' */ + break; + } + default: + { + luaX_syntaxerror(ls, "function arguments expected"); + } + } + lua_assert(f->k == VNONRELOC); + base = f->u.info; /* base register for call */ + if (hasmultret(args.k)) + nparams = LUA_MULTRET; /* open call */ + else + { + if (args.k != VVOID) + luaK_exp2nextreg(fs, &args); /* close last argument */ + nparams = fs->freereg - (base + 1); + } + init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams + 1, 2)); + luaK_fixline(fs, line); + fs->freereg = base + 1; /* call remove function and arguments and leaves (unless changed) one result */ } - - - /* ** {====================================================================== ** Expression parsing ** ======================================================================= */ - -static void primaryexp (LexState *ls, expdesc *v) { - /* primaryexp -> NAME | '(' expr ')' */ - switch (ls->t.token) { - case '(': { - int line = ls->linenumber; - luaX_next(ls); - expr(ls, v); - check_match(ls, ')', '(', line); - luaK_dischargevars(ls->fs, v); - return; - } - case TK_NAME: { - singlevar(ls, v); - return; - } - default: { - luaX_syntaxerror(ls, "unexpected symbol"); - } - } +static void primaryexp(LexState *ls, expdesc *v) +{ + /* primaryexp -> NAME | '(' expr ')' */ + switch (ls->t.token) + { + case '(': + { + int line = ls->linenumber; + luaX_next(ls); + expr(ls, v); + check_match(ls, ')', '(', line); + luaK_dischargevars(ls->fs, v); + return; + } + case TK_NAME: + { + singlevar(ls, v); + return; + } + default: + { + luaX_syntaxerror(ls, "unexpected symbol"); + } + } } - -static void suffixedexp (LexState *ls, expdesc *v) { - /* suffixedexp -> +static void suffixedexp(LexState *ls, expdesc *v) +{ + /* suffixedexp -> primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */ - FuncState *fs = ls->fs; - int line = ls->linenumber; - primaryexp(ls, v); - for (;;) { - switch (ls->t.token) { - case '.': { /* fieldsel */ - fieldsel(ls, v); - break; - } - case '[': { /* `[' exp1 `]' */ - expdesc key; - luaK_exp2anyregup(fs, v); - yindex(ls, &key); - luaK_indexed(fs, v, &key); - break; - } - case ':': { /* `:' NAME funcargs */ - expdesc key; - luaX_next(ls); - checkname(ls, &key); - luaK_self(fs, v, &key); - funcargs(ls, v, line); - break; - } - case '(': case TK_STRING: case '{': { /* funcargs */ - luaK_exp2nextreg(fs, v); - funcargs(ls, v, line); - break; - } - default: return; - } - } + FuncState *fs = ls->fs; + int line = ls->linenumber; + primaryexp(ls, v); + for (;;) + { + switch (ls->t.token) + { + case '.': + { /* fieldsel */ + fieldsel(ls, v); + break; + } + case '[': + { /* `[' exp1 `]' */ + expdesc key; + luaK_exp2anyregup(fs, v); + yindex(ls, &key); + luaK_indexed(fs, v, &key); + break; + } + case ':': + { /* `:' NAME funcargs */ + expdesc key; + luaX_next(ls); + checkname(ls, &key); + luaK_self(fs, v, &key); + funcargs(ls, v, line); + break; + } + case '(': + case TK_STRING: + case '{': + { /* funcargs */ + luaK_exp2nextreg(fs, v); + funcargs(ls, v, line); + break; + } + default: + return; + } + } } - -static void simpleexp (LexState *ls, expdesc *v) { - /* simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... | +static void simpleexp(LexState *ls, expdesc *v) +{ + /* simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... | constructor | FUNCTION body | suffixedexp */ - switch (ls->t.token) { - case TK_NUMBER: { - init_exp(v, VKNUM, 0); - v->u.nval = ls->t.seminfo.r; - break; - } - case TK_STRING: { - codestring(ls, v, ls->t.seminfo.ts); - break; - } - case TK_NIL: { - init_exp(v, VNIL, 0); - break; - } - case TK_TRUE: { - init_exp(v, VTRUE, 0); - break; - } - case TK_FALSE: { - init_exp(v, VFALSE, 0); - break; - } - case TK_DOTS: { /* vararg */ - FuncState *fs = ls->fs; - check_condition(ls, fs->f->is_vararg, - "cannot use " LUA_QL("...") " outside a vararg function"); - init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); - break; - } - case '{': { /* constructor */ - constructor(ls, v); - return; - } - case TK_FUNCTION: { - luaX_next(ls); - body(ls, v, 0, ls->linenumber); - return; - } - default: { - suffixedexp(ls, v); - return; - } - } - luaX_next(ls); + switch (ls->t.token) + { + case TK_NUMBER: + { + init_exp(v, VKNUM, 0); + v->u.nval = ls->t.seminfo.r; + break; + } + case TK_STRING: + { + codestring(ls, v, ls->t.seminfo.ts); + break; + } + case TK_NIL: + { + init_exp(v, VNIL, 0); + break; + } + case TK_TRUE: + { + init_exp(v, VTRUE, 0); + break; + } + case TK_FALSE: + { + init_exp(v, VFALSE, 0); + break; + } + case TK_DOTS: + { /* vararg */ + FuncState *fs = ls->fs; + check_condition(ls, fs->f->is_vararg, + "cannot use " LUA_QL("...") " outside a vararg function"); + init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0)); + break; + } + case '{': + { /* constructor */ + constructor(ls, v); + return; + } + case TK_FUNCTION: + { + luaX_next(ls); + body(ls, v, 0, ls->linenumber); + return; + } + default: + { + suffixedexp(ls, v); + return; + } + } + luaX_next(ls); } - -static UnOpr getunopr (int op) { - switch (op) { - case TK_NOT: return OPR_NOT; - case '-': return OPR_MINUS; - case '#': return OPR_LEN; - default: return OPR_NOUNOPR; - } +static UnOpr getunopr(int op) +{ + switch (op) + { + case TK_NOT: + return OPR_NOT; + case '-': + return OPR_MINUS; + case '#': + return OPR_LEN; + default: + return OPR_NOUNOPR; + } } - -static BinOpr getbinopr (int op) { - switch (op) { - case '+': return OPR_ADD; - case '-': return OPR_SUB; - case '*': return OPR_MUL; - case '/': return OPR_DIV; - case '%': return OPR_MOD; - case '^': return OPR_POW; - case TK_CONCAT: return OPR_CONCAT; - case TK_NE: return OPR_NE; - case TK_EQ: return OPR_EQ; - case '<': return OPR_LT; - case TK_LE: return OPR_LE; - case '>': return OPR_GT; - case TK_GE: return OPR_GE; - case TK_AND: return OPR_AND; - case TK_OR: return OPR_OR; - default: return OPR_NOBINOPR; - } +static BinOpr getbinopr(int op) +{ + switch (op) + { + case '+': + return OPR_ADD; + case '-': + return OPR_SUB; + case '*': + return OPR_MUL; + case '/': + return OPR_DIV; + case '%': + return OPR_MOD; + case '^': + return OPR_POW; + case TK_CONCAT: + return OPR_CONCAT; + case TK_NE: + return OPR_NE; + case TK_EQ: + return OPR_EQ; + case '<': + return OPR_LT; + case TK_LE: + return OPR_LE; + case '>': + return OPR_GT; + case TK_GE: + return OPR_GE; + case TK_AND: + return OPR_AND; + case TK_OR: + return OPR_OR; + default: + return OPR_NOBINOPR; + } } - -static const struct { - lu_byte left; /* left priority for each binary operator */ - lu_byte right; /* right priority */ -} priority[] = { /* ORDER OPR */ - {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `*' `/' `%' */ - {10, 9}, {5, 4}, /* ^, .. (right associative) */ - {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */ - {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */ - {2, 2}, {1, 1} /* and, or */ +static const struct +{ + lu_byte left; /* left priority for each binary operator */ + lu_byte right; /* right priority */ +} priority[] = { + /* ORDER OPR */ + {6, 6}, + {6, 6}, + {7, 7}, + {7, 7}, + {7, 7}, /* `+' `-' `*' `/' `%' */ + {10, 9}, + {5, 4}, /* ^, .. (right associative) */ + {3, 3}, + {3, 3}, + {3, 3}, /* ==, <, <= */ + {3, 3}, + {3, 3}, + {3, 3}, /* ~=, >, >= */ + {2, 2}, + {1, 1} /* and, or */ }; -#define UNARY_PRIORITY 8 /* priority for unary operators */ - +#define UNARY_PRIORITY 8 /* priority for unary operators */ /* ** subexpr -> (simpleexp | unop subexpr) { binop subexpr } ** where `binop' is any binary operator with a priority higher than `limit' */ -static BinOpr subexpr (LexState *ls, expdesc *v, int limit) { - BinOpr op; - UnOpr uop; - enterlevel(ls); - uop = getunopr(ls->t.token); - if (uop != OPR_NOUNOPR) { - int line = ls->linenumber; - luaX_next(ls); - subexpr(ls, v, UNARY_PRIORITY); - luaK_prefix(ls->fs, uop, v, line); - } - else simpleexp(ls, v); - /* expand while operators have priorities higher than `limit' */ - op = getbinopr(ls->t.token); - while (op != OPR_NOBINOPR && priority[op].left > limit) { - expdesc v2; - BinOpr nextop; - int line = ls->linenumber; - luaX_next(ls); - luaK_infix(ls->fs, op, v); - /* read sub-expression with higher priority */ - nextop = subexpr(ls, &v2, priority[op].right); - luaK_posfix(ls->fs, op, v, &v2, line); - op = nextop; - } - leavelevel(ls); - return op; /* return first untreated operator */ +static BinOpr subexpr(LexState *ls, expdesc *v, int limit) +{ + BinOpr op; + UnOpr uop; + enterlevel(ls); + uop = getunopr(ls->t.token); + if (uop != OPR_NOUNOPR) + { + int line = ls->linenumber; + luaX_next(ls); + subexpr(ls, v, UNARY_PRIORITY); + luaK_prefix(ls->fs, uop, v, line); + } + else + simpleexp(ls, v); + /* expand while operators have priorities higher than `limit' */ + op = getbinopr(ls->t.token); + while (op != OPR_NOBINOPR && priority[op].left > limit) + { + expdesc v2; + BinOpr nextop; + int line = ls->linenumber; + luaX_next(ls); + luaK_infix(ls->fs, op, v); + /* read sub-expression with higher priority */ + nextop = subexpr(ls, &v2, priority[op].right); + luaK_posfix(ls->fs, op, v, &v2, line); + op = nextop; + } + leavelevel(ls); + return op; /* return first untreated operator */ } - -static void expr (LexState *ls, expdesc *v) { - subexpr(ls, v, 0); +static void expr(LexState *ls, expdesc *v) +{ + subexpr(ls, v, 0); } /* }==================================================================== */ - - /* ** {====================================================================== ** Rules for Statements ** ======================================================================= */ - -static void block (LexState *ls) { - /* block -> statlist */ - FuncState *fs = ls->fs; - BlockCnt bl; - enterblock(fs, &bl, 0); - statlist(ls); - leaveblock(fs); +static void block(LexState *ls) +{ + /* block -> statlist */ + FuncState *fs = ls->fs; + BlockCnt bl; + enterblock(fs, &bl, 0); + statlist(ls); + leaveblock(fs); } - /* ** structure to chain all variables in the left-hand side of an ** assignment */ -struct LHS_assign { - struct LHS_assign *prev; - expdesc v; /* variable (global, local, upvalue, or indexed) */ +struct LHS_assign +{ + struct LHS_assign *prev; + expdesc v; /* variable (global, local, upvalue, or indexed) */ }; - /* ** check whether, in an assignment to an upvalue/local variable, the ** upvalue/local variable is begin used in a previous assignment to a ** table. If so, save original upvalue/local value in a safe place and ** use this safe copy in the previous assignment. */ -static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) { - FuncState *fs = ls->fs; - int extra = fs->freereg; /* eventual position to save local variable */ - int conflict = 0; - for (; lh; lh = lh->prev) { /* check all previous assignments */ - if (lh->v.k == VINDEXED) { /* assigning to a table? */ - /* table is the upvalue/local being assigned now? */ - if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) { - conflict = 1; - lh->v.u.ind.vt = VLOCAL; - lh->v.u.ind.t = extra; /* previous assignment will use safe copy */ - } - /* index is the local being assigned? (index cannot be upvalue) */ - if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) { - conflict = 1; - lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ - } - } - } - if (conflict) { - /* copy upvalue/local value to a temporary (in position 'extra') */ - OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; - luaK_codeABC(fs, op, extra, v->u.info, 0); - luaK_reserveregs(fs, 1); - } +static void check_conflict(LexState *ls, struct LHS_assign *lh, expdesc *v) +{ + FuncState *fs = ls->fs; + int extra = fs->freereg; /* eventual position to save local variable */ + int conflict = 0; + for (; lh; lh = lh->prev) + { /* check all previous assignments */ + if (lh->v.k == VINDEXED) + { /* assigning to a table? */ + /* table is the upvalue/local being assigned now? */ + if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) + { + conflict = 1; + lh->v.u.ind.vt = VLOCAL; + lh->v.u.ind.t = extra; /* previous assignment will use safe copy */ + } + /* index is the local being assigned? (index cannot be upvalue) */ + if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) + { + conflict = 1; + lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */ + } + } + } + if (conflict) + { + /* copy upvalue/local value to a temporary (in position 'extra') */ + OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL; + luaK_codeABC(fs, op, extra, v->u.info, 0); + luaK_reserveregs(fs, 1); + } } - -static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) { - expdesc e; - check_condition(ls, vkisvar(lh->v.k), "syntax error"); - if (testnext(ls, ',')) { /* assignment -> ',' suffixedexp assignment */ - struct LHS_assign nv; - nv.prev = lh; - suffixedexp(ls, &nv.v); - if (nv.v.k != VINDEXED) - check_conflict(ls, lh, &nv.v); - checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS, - "C levels"); - assignment(ls, &nv, nvars+1); - } - else { /* assignment -> `=' explist */ - int nexps; - checknext(ls, '='); - nexps = explist(ls, &e); - if (nexps != nvars) { - adjust_assign(ls, nvars, nexps, &e); - if (nexps > nvars) - ls->fs->freereg -= nexps - nvars; /* remove extra values */ - } - else { - luaK_setoneret(ls->fs, &e); /* close last expression */ - luaK_storevar(ls->fs, &lh->v, &e); - return; /* avoid default */ - } - } - init_exp(&e, VNONRELOC, ls->fs->freereg-1); /* default assignment */ - luaK_storevar(ls->fs, &lh->v, &e); +static void assignment(LexState *ls, struct LHS_assign *lh, int nvars) +{ + expdesc e; + check_condition(ls, vkisvar(lh->v.k), "syntax error"); + if (testnext(ls, ',')) + { /* assignment -> ',' suffixedexp assignment */ + struct LHS_assign nv; + nv.prev = lh; + suffixedexp(ls, &nv.v); + if (nv.v.k != VINDEXED) + check_conflict(ls, lh, &nv.v); + checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS, + "C levels"); + assignment(ls, &nv, nvars + 1); + } + else + { /* assignment -> `=' explist */ + int nexps; + checknext(ls, '='); + nexps = explist(ls, &e); + if (nexps != nvars) + { + adjust_assign(ls, nvars, nexps, &e); + if (nexps > nvars) + ls->fs->freereg -= nexps - nvars; /* remove extra values */ + } + else + { + luaK_setoneret(ls->fs, &e); /* close last expression */ + luaK_storevar(ls->fs, &lh->v, &e); + return; /* avoid default */ + } + } + init_exp(&e, VNONRELOC, ls->fs->freereg - 1); /* default assignment */ + luaK_storevar(ls->fs, &lh->v, &e); } - -static int cond (LexState *ls) { - /* cond -> exp */ - expdesc v; - expr(ls, &v); /* read condition */ - if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */ - luaK_goiftrue(ls->fs, &v); - return v.f; +static int cond(LexState *ls) +{ + /* cond -> exp */ + expdesc v; + expr(ls, &v); /* read condition */ + if (v.k == VNIL) v.k = VFALSE; /* `falses' are all equal here */ + luaK_goiftrue(ls->fs, &v); + return v.f; } - -static void gotostat (LexState *ls, int pc) { - int line = ls->linenumber; - TString *label; - int g; - if (testnext(ls, TK_GOTO)) - label = str_checkname(ls); - else { - luaX_next(ls); /* skip break */ - label = luaS_new(ls->L, "break"); - } - g = newlabelentry(ls, &ls->dyd->gt, label, line, pc); - findlabel(ls, g); /* close it if label already defined */ +static void gotostat(LexState *ls, int pc) +{ + int line = ls->linenumber; + TString *label; + int g; + if (testnext(ls, TK_GOTO)) + label = str_checkname(ls); + else + { + luaX_next(ls); /* skip break */ + label = luaS_new(ls->L, "break"); + } + g = newlabelentry(ls, &ls->dyd->gt, label, line, pc); + findlabel(ls, g); /* close it if label already defined */ } - /* check for repeated labels on the same block */ -static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) { - int i; - for (i = fs->bl->firstlabel; i < ll->n; i++) { - if (luaS_eqstr(label, ll->arr[i].name)) { - const char *msg = luaO_pushfstring(fs->ls->L, - "label " LUA_QS " already defined on line %d", - getstr(label), ll->arr[i].line); - semerror(fs->ls, msg); - } - } +static void checkrepeated(FuncState *fs, Labellist *ll, TString *label) +{ + int i; + for (i = fs->bl->firstlabel; i < ll->n; i++) + { + if (luaS_eqstr(label, ll->arr[i].name)) + { + const char *msg = luaO_pushfstring(fs->ls->L, + "label " LUA_QS " already defined on line %d", + getstr(label), ll->arr[i].line); + semerror(fs->ls, msg); + } + } } - /* skip no-op statements */ -static void skipnoopstat (LexState *ls) { - while (ls->t.token == ';' || ls->t.token == TK_DBCOLON) - statement(ls); +static void skipnoopstat(LexState *ls) +{ + while (ls->t.token == ';' || ls->t.token == TK_DBCOLON) + statement(ls); } - -static void labelstat (LexState *ls, TString *label, int line) { - /* label -> '::' NAME '::' */ - FuncState *fs = ls->fs; - Labellist *ll = &ls->dyd->label; - int l; /* index of new label being created */ - checkrepeated(fs, ll, label); /* check for repeated labels */ - checknext(ls, TK_DBCOLON); /* skip double colon */ - /* create new entry for this label */ - l = newlabelentry(ls, ll, label, line, fs->pc); - skipnoopstat(ls); /* skip other no-op statements */ - if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */ - /* assume that locals are already out of scope */ - ll->arr[l].nactvar = fs->bl->nactvar; - } - findgotos(ls, &ll->arr[l]); +static void labelstat(LexState *ls, TString *label, int line) +{ + /* label -> '::' NAME '::' */ + FuncState *fs = ls->fs; + Labellist *ll = &ls->dyd->label; + int l; /* index of new label being created */ + checkrepeated(fs, ll, label); /* check for repeated labels */ + checknext(ls, TK_DBCOLON); /* skip double colon */ + /* create new entry for this label */ + l = newlabelentry(ls, ll, label, line, fs->pc); + skipnoopstat(ls); /* skip other no-op statements */ + if (block_follow(ls, 0)) + { /* label is last no-op statement in the block? */ + /* assume that locals are already out of scope */ + ll->arr[l].nactvar = fs->bl->nactvar; + } + findgotos(ls, &ll->arr[l]); } - -static void whilestat (LexState *ls, int line) { - /* whilestat -> WHILE cond DO block END */ - FuncState *fs = ls->fs; - int whileinit; - int condexit; - BlockCnt bl; - luaX_next(ls); /* skip WHILE */ - whileinit = luaK_getlabel(fs); - condexit = cond(ls); - enterblock(fs, &bl, 1); - checknext(ls, TK_DO); - block(ls); - luaK_jumpto(fs, whileinit); - check_match(ls, TK_END, TK_WHILE, line); - leaveblock(fs); - luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ +static void whilestat(LexState *ls, int line) +{ + /* whilestat -> WHILE cond DO block END */ + FuncState *fs = ls->fs; + int whileinit; + int condexit; + BlockCnt bl; + luaX_next(ls); /* skip WHILE */ + whileinit = luaK_getlabel(fs); + condexit = cond(ls); + enterblock(fs, &bl, 1); + checknext(ls, TK_DO); + block(ls); + luaK_jumpto(fs, whileinit); + check_match(ls, TK_END, TK_WHILE, line); + leaveblock(fs); + luaK_patchtohere(fs, condexit); /* false conditions finish the loop */ } - -static void repeatstat (LexState *ls, int line) { - /* repeatstat -> REPEAT block UNTIL cond */ - int condexit; - FuncState *fs = ls->fs; - int repeat_init = luaK_getlabel(fs); - BlockCnt bl1, bl2; - enterblock(fs, &bl1, 1); /* loop block */ - enterblock(fs, &bl2, 0); /* scope block */ - luaX_next(ls); /* skip REPEAT */ - statlist(ls); - check_match(ls, TK_UNTIL, TK_REPEAT, line); - condexit = cond(ls); /* read condition (inside scope block) */ - if (bl2.upval) /* upvalues? */ - luaK_patchclose(fs, condexit, bl2.nactvar); - leaveblock(fs); /* finish scope */ - luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ - leaveblock(fs); /* finish loop */ +static void repeatstat(LexState *ls, int line) +{ + /* repeatstat -> REPEAT block UNTIL cond */ + int condexit; + FuncState *fs = ls->fs; + int repeat_init = luaK_getlabel(fs); + BlockCnt bl1, bl2; + enterblock(fs, &bl1, 1); /* loop block */ + enterblock(fs, &bl2, 0); /* scope block */ + luaX_next(ls); /* skip REPEAT */ + statlist(ls); + check_match(ls, TK_UNTIL, TK_REPEAT, line); + condexit = cond(ls); /* read condition (inside scope block) */ + if (bl2.upval) /* upvalues? */ + luaK_patchclose(fs, condexit, bl2.nactvar); + leaveblock(fs); /* finish scope */ + luaK_patchlist(fs, condexit, repeat_init); /* close the loop */ + leaveblock(fs); /* finish loop */ } - -static int exp1 (LexState *ls) { - expdesc e; - int reg; - expr(ls, &e); - luaK_exp2nextreg(ls->fs, &e); - lua_assert(e.k == VNONRELOC); - reg = e.u.info; - return reg; +static int exp1(LexState *ls) +{ + expdesc e; + int reg; + expr(ls, &e); + luaK_exp2nextreg(ls->fs, &e); + lua_assert(e.k == VNONRELOC); + reg = e.u.info; + return reg; } - -static void forbody (LexState *ls, int base, int line, int nvars, int isnum) { - /* forbody -> DO block */ - BlockCnt bl; - FuncState *fs = ls->fs; - int prep, endfor; - adjustlocalvars(ls, 3); /* control variables */ - checknext(ls, TK_DO); - prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); - enterblock(fs, &bl, 0); /* scope for declared variables */ - adjustlocalvars(ls, nvars); - luaK_reserveregs(fs, nvars); - block(ls); - leaveblock(fs); /* end of scope for declared variables */ - luaK_patchtohere(fs, prep); - if (isnum) /* numeric for? */ - endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP); - else { /* generic for */ - luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); - luaK_fixline(fs, line); - endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP); - } - luaK_patchlist(fs, endfor, prep + 1); - luaK_fixline(fs, line); +static void forbody(LexState *ls, int base, int line, int nvars, int isnum) +{ + /* forbody -> DO block */ + BlockCnt bl; + FuncState *fs = ls->fs; + int prep, endfor; + adjustlocalvars(ls, 3); /* control variables */ + checknext(ls, TK_DO); + prep = isnum ? luaK_codeAsBx(fs, OP_FORPREP, base, NO_JUMP) : luaK_jump(fs); + enterblock(fs, &bl, 0); /* scope for declared variables */ + adjustlocalvars(ls, nvars); + luaK_reserveregs(fs, nvars); + block(ls); + leaveblock(fs); /* end of scope for declared variables */ + luaK_patchtohere(fs, prep); + if (isnum) /* numeric for? */ + endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP); + else + { /* generic for */ + luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars); + luaK_fixline(fs, line); + endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP); + } + luaK_patchlist(fs, endfor, prep + 1); + luaK_fixline(fs, line); } - -static void fornum (LexState *ls, TString *varname, int line) { - /* fornum -> NAME = exp1,exp1[,exp1] forbody */ - FuncState *fs = ls->fs; - int base = fs->freereg; - new_localvarliteral(ls, "(for index)"); - new_localvarliteral(ls, "(for limit)"); - new_localvarliteral(ls, "(for step)"); - new_localvar(ls, varname); - checknext(ls, '='); - exp1(ls); /* initial value */ - checknext(ls, ','); - exp1(ls); /* limit */ - if (testnext(ls, ',')) - exp1(ls); /* optional step */ - else { /* default step = 1 */ - luaK_codek(fs, fs->freereg, luaK_numberK(fs, 1)); - luaK_reserveregs(fs, 1); - } - forbody(ls, base, line, 1, 1); +static void fornum(LexState *ls, TString *varname, int line) +{ + /* fornum -> NAME = exp1,exp1[,exp1] forbody */ + FuncState *fs = ls->fs; + int base = fs->freereg; + new_localvarliteral(ls, "(for index)"); + new_localvarliteral(ls, "(for limit)"); + new_localvarliteral(ls, "(for step)"); + new_localvar(ls, varname); + checknext(ls, '='); + exp1(ls); /* initial value */ + checknext(ls, ','); + exp1(ls); /* limit */ + if (testnext(ls, ',')) + exp1(ls); /* optional step */ + else + { /* default step = 1 */ + luaK_codek(fs, fs->freereg, luaK_numberK(fs, 1)); + luaK_reserveregs(fs, 1); + } + forbody(ls, base, line, 1, 1); } - -static void forlist (LexState *ls, TString *indexname) { - /* forlist -> NAME {,NAME} IN explist forbody */ - FuncState *fs = ls->fs; - expdesc e; - int nvars = 4; /* gen, state, control, plus at least one declared var */ - int line; - int base = fs->freereg; - /* create control variables */ - new_localvarliteral(ls, "(for generator)"); - new_localvarliteral(ls, "(for state)"); - new_localvarliteral(ls, "(for control)"); - /* create declared variables */ - new_localvar(ls, indexname); - while (testnext(ls, ',')) { - new_localvar(ls, str_checkname(ls)); - nvars++; - } - checknext(ls, TK_IN); - line = ls->linenumber; - adjust_assign(ls, 3, explist(ls, &e), &e); - luaK_checkstack(fs, 3); /* extra space to call generator */ - forbody(ls, base, line, nvars - 3, 0); +static void forlist(LexState *ls, TString *indexname) +{ + /* forlist -> NAME {,NAME} IN explist forbody */ + FuncState *fs = ls->fs; + expdesc e; + int nvars = 4; /* gen, state, control, plus at least one declared var */ + int line; + int base = fs->freereg; + /* create control variables */ + new_localvarliteral(ls, "(for generator)"); + new_localvarliteral(ls, "(for state)"); + new_localvarliteral(ls, "(for control)"); + /* create declared variables */ + new_localvar(ls, indexname); + while (testnext(ls, ',')) + { + new_localvar(ls, str_checkname(ls)); + nvars++; + } + checknext(ls, TK_IN); + line = ls->linenumber; + adjust_assign(ls, 3, explist(ls, &e), &e); + luaK_checkstack(fs, 3); /* extra space to call generator */ + forbody(ls, base, line, nvars - 3, 0); } - -static void forstat (LexState *ls, int line) { - /* forstat -> FOR (fornum | forlist) END */ - FuncState *fs = ls->fs; - TString *varname; - BlockCnt bl; - enterblock(fs, &bl, 1); /* scope for loop and control variables */ - luaX_next(ls); /* skip `for' */ - varname = str_checkname(ls); /* first variable name */ - switch (ls->t.token) { - case '=': fornum(ls, varname, line); break; - case ',': case TK_IN: forlist(ls, varname); break; - default: luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected"); - } - check_match(ls, TK_END, TK_FOR, line); - leaveblock(fs); /* loop scope (`break' jumps to this point) */ +static void forstat(LexState *ls, int line) +{ + /* forstat -> FOR (fornum | forlist) END */ + FuncState *fs = ls->fs; + TString *varname; + BlockCnt bl; + enterblock(fs, &bl, 1); /* scope for loop and control variables */ + luaX_next(ls); /* skip `for' */ + varname = str_checkname(ls); /* first variable name */ + switch (ls->t.token) + { + case '=': + fornum(ls, varname, line); + break; + case ',': + case TK_IN: + forlist(ls, varname); + break; + default: + luaX_syntaxerror(ls, LUA_QL("=") " or " LUA_QL("in") " expected"); + } + check_match(ls, TK_END, TK_FOR, line); + leaveblock(fs); /* loop scope (`break' jumps to this point) */ } - -static void test_then_block (LexState *ls, int *escapelist) { - /* test_then_block -> [IF | ELSEIF] cond THEN block */ - BlockCnt bl; - FuncState *fs = ls->fs; - expdesc v; - int jf; /* instruction to skip 'then' code (if condition is false) */ - luaX_next(ls); /* skip IF or ELSEIF */ - expr(ls, &v); /* read condition */ - checknext(ls, TK_THEN); - if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) { - luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */ - enterblock(fs, &bl, 0); /* must enter block before 'goto' */ - gotostat(ls, v.t); /* handle goto/break */ - skipnoopstat(ls); /* skip other no-op statements */ - if (block_follow(ls, 0)) { /* 'goto' is the entire block? */ - leaveblock(fs); - return; /* and that is it */ - } - else /* must skip over 'then' part if condition is false */ - jf = luaK_jump(fs); - } - else { /* regular case (not goto/break) */ - luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */ - enterblock(fs, &bl, 0); - jf = v.f; - } - statlist(ls); /* `then' part */ - leaveblock(fs); - if (ls->t.token == TK_ELSE || - ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */ - luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */ - luaK_patchtohere(fs, jf); +static void test_then_block(LexState *ls, int *escapelist) +{ + /* test_then_block -> [IF | ELSEIF] cond THEN block */ + BlockCnt bl; + FuncState *fs = ls->fs; + expdesc v; + int jf; /* instruction to skip 'then' code (if condition is false) */ + luaX_next(ls); /* skip IF or ELSEIF */ + expr(ls, &v); /* read condition */ + checknext(ls, TK_THEN); + if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) + { + luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */ + enterblock(fs, &bl, 0); /* must enter block before 'goto' */ + gotostat(ls, v.t); /* handle goto/break */ + skipnoopstat(ls); /* skip other no-op statements */ + if (block_follow(ls, 0)) + { /* 'goto' is the entire block? */ + leaveblock(fs); + return; /* and that is it */ + } + else /* must skip over 'then' part if condition is false */ + jf = luaK_jump(fs); + } + else + { /* regular case (not goto/break) */ + luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */ + enterblock(fs, &bl, 0); + jf = v.f; + } + statlist(ls); /* `then' part */ + leaveblock(fs); + if (ls->t.token == TK_ELSE || + ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */ + luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */ + luaK_patchtohere(fs, jf); } - -static void ifstat (LexState *ls, int line) { - /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ - FuncState *fs = ls->fs; - int escapelist = NO_JUMP; /* exit list for finished parts */ - test_then_block(ls, &escapelist); /* IF cond THEN block */ - while (ls->t.token == TK_ELSEIF) - test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */ - if (testnext(ls, TK_ELSE)) - block(ls); /* `else' part */ - check_match(ls, TK_END, TK_IF, line); - luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */ +static void ifstat(LexState *ls, int line) +{ + /* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */ + FuncState *fs = ls->fs; + int escapelist = NO_JUMP; /* exit list for finished parts */ + test_then_block(ls, &escapelist); /* IF cond THEN block */ + while (ls->t.token == TK_ELSEIF) + test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */ + if (testnext(ls, TK_ELSE)) + block(ls); /* `else' part */ + check_match(ls, TK_END, TK_IF, line); + luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */ } - -static void localfunc (LexState *ls) { - expdesc b; - FuncState *fs = ls->fs; - new_localvar(ls, str_checkname(ls)); /* new local variable */ - adjustlocalvars(ls, 1); /* enter its scope */ - body(ls, &b, 0, ls->linenumber); /* function created in next register */ - /* debug information will only see the variable after this point! */ - getlocvar(fs, b.u.info)->startpc = fs->pc; +static void localfunc(LexState *ls) +{ + expdesc b; + FuncState *fs = ls->fs; + new_localvar(ls, str_checkname(ls)); /* new local variable */ + adjustlocalvars(ls, 1); /* enter its scope */ + body(ls, &b, 0, ls->linenumber); /* function created in next register */ + /* debug information will only see the variable after this point! */ + getlocvar(fs, b.u.info)->startpc = fs->pc; } - -static void localstat (LexState *ls) { - /* stat -> LOCAL NAME {`,' NAME} [`=' explist] */ - int nvars = 0; - int nexps; - expdesc e; - do { - new_localvar(ls, str_checkname(ls)); - nvars++; - } while (testnext(ls, ',')); - if (testnext(ls, '=')) - nexps = explist(ls, &e); - else { - e.k = VVOID; - nexps = 0; - } - adjust_assign(ls, nvars, nexps, &e); - adjustlocalvars(ls, nvars); +static void localstat(LexState *ls) +{ + /* stat -> LOCAL NAME {`,' NAME} [`=' explist] */ + int nvars = 0; + int nexps; + expdesc e; + do + { + new_localvar(ls, str_checkname(ls)); + nvars++; + } while (testnext(ls, ',')); + if (testnext(ls, '=')) + nexps = explist(ls, &e); + else + { + e.k = VVOID; + nexps = 0; + } + adjust_assign(ls, nvars, nexps, &e); + adjustlocalvars(ls, nvars); } - -static int funcname (LexState *ls, expdesc *v) { - /* funcname -> NAME {fieldsel} [`:' NAME] */ - int ismethod = 0; - singlevar(ls, v); - while (ls->t.token == '.') - fieldsel(ls, v); - if (ls->t.token == ':') { - ismethod = 1; - fieldsel(ls, v); - } - return ismethod; +static int funcname(LexState *ls, expdesc *v) +{ + /* funcname -> NAME {fieldsel} [`:' NAME] */ + int ismethod = 0; + singlevar(ls, v); + while (ls->t.token == '.') + fieldsel(ls, v); + if (ls->t.token == ':') + { + ismethod = 1; + fieldsel(ls, v); + } + return ismethod; } - -static void funcstat (LexState *ls, int line) { - /* funcstat -> FUNCTION funcname body */ - int ismethod; - expdesc v, b; - luaX_next(ls); /* skip FUNCTION */ - ismethod = funcname(ls, &v); - body(ls, &b, ismethod, line); - luaK_storevar(ls->fs, &v, &b); - luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ +static void funcstat(LexState *ls, int line) +{ + /* funcstat -> FUNCTION funcname body */ + int ismethod; + expdesc v, b; + luaX_next(ls); /* skip FUNCTION */ + ismethod = funcname(ls, &v); + body(ls, &b, ismethod, line); + luaK_storevar(ls->fs, &v, &b); + luaK_fixline(ls->fs, line); /* definition `happens' in the first line */ } - -static void exprstat (LexState *ls) { - /* stat -> func | assignment */ - FuncState *fs = ls->fs; - struct LHS_assign v; - suffixedexp(ls, &v.v); - if (ls->t.token == '=' || ls->t.token == ',') { /* stat -> assignment ? */ - v.prev = NULL; - assignment(ls, &v, 1); - } - else { /* stat -> func */ - check_condition(ls, v.v.k == VCALL, "syntax error"); - SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ - } +static void exprstat(LexState *ls) +{ + /* stat -> func | assignment */ + FuncState *fs = ls->fs; + struct LHS_assign v; + suffixedexp(ls, &v.v); + if (ls->t.token == '=' || ls->t.token == ',') + { /* stat -> assignment ? */ + v.prev = NULL; + assignment(ls, &v, 1); + } + else + { /* stat -> func */ + check_condition(ls, v.v.k == VCALL, "syntax error"); + SETARG_C(getcode(fs, &v.v), 1); /* call statement uses no results */ + } } - -static void retstat (LexState *ls) { - /* stat -> RETURN [explist] [';'] */ - FuncState *fs = ls->fs; - expdesc e; - int first, nret; /* registers with returned values */ - if (block_follow(ls, 1) || ls->t.token == ';') - first = nret = 0; /* return no values */ - else { - nret = explist(ls, &e); /* optional return values */ - if (hasmultret(e.k)) { - luaK_setmultret(fs, &e); - if (e.k == VCALL && nret == 1) { /* tail call? */ - SET_OPCODE(getcode(fs,&e), OP_TAILCALL); - lua_assert(GETARG_A(getcode(fs,&e)) == fs->nactvar); - } - first = fs->nactvar; - nret = LUA_MULTRET; /* return all values */ - } - else { - if (nret == 1) /* only one single value? */ - first = luaK_exp2anyreg(fs, &e); - else { - luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ - first = fs->nactvar; /* return all `active' values */ - lua_assert(nret == fs->freereg - first); - } - } - } - luaK_ret(fs, first, nret); - testnext(ls, ';'); /* skip optional semicolon */ +static void retstat(LexState *ls) +{ + /* stat -> RETURN [explist] [';'] */ + FuncState *fs = ls->fs; + expdesc e; + int first, nret; /* registers with returned values */ + if (block_follow(ls, 1) || ls->t.token == ';') + first = nret = 0; /* return no values */ + else + { + nret = explist(ls, &e); /* optional return values */ + if (hasmultret(e.k)) + { + luaK_setmultret(fs, &e); + if (e.k == VCALL && nret == 1) + { /* tail call? */ + SET_OPCODE(getcode(fs, &e), OP_TAILCALL); + lua_assert(GETARG_A(getcode(fs, &e)) == fs->nactvar); + } + first = fs->nactvar; + nret = LUA_MULTRET; /* return all values */ + } + else + { + if (nret == 1) /* only one single value? */ + first = luaK_exp2anyreg(fs, &e); + else + { + luaK_exp2nextreg(fs, &e); /* values must go to the `stack' */ + first = fs->nactvar; /* return all `active' values */ + lua_assert(nret == fs->freereg - first); + } + } + } + luaK_ret(fs, first, nret); + testnext(ls, ';'); /* skip optional semicolon */ } - -static void statement (LexState *ls) { - int line = ls->linenumber; /* may be needed for error messages */ - enterlevel(ls); - switch (ls->t.token) { - case ';': { /* stat -> ';' (empty statement) */ - luaX_next(ls); /* skip ';' */ - break; - } - case TK_IF: { /* stat -> ifstat */ - ifstat(ls, line); - break; - } - case TK_WHILE: { /* stat -> whilestat */ - whilestat(ls, line); - break; - } - case TK_DO: { /* stat -> DO block END */ - luaX_next(ls); /* skip DO */ - block(ls); - check_match(ls, TK_END, TK_DO, line); - break; - } - case TK_FOR: { /* stat -> forstat */ - forstat(ls, line); - break; - } - case TK_REPEAT: { /* stat -> repeatstat */ - repeatstat(ls, line); - break; - } - case TK_FUNCTION: { /* stat -> funcstat */ - funcstat(ls, line); - break; - } - case TK_LOCAL: { /* stat -> localstat */ - luaX_next(ls); /* skip LOCAL */ - if (testnext(ls, TK_FUNCTION)) /* local function? */ - localfunc(ls); - else - localstat(ls); - break; - } - case TK_DBCOLON: { /* stat -> label */ - luaX_next(ls); /* skip double colon */ - labelstat(ls, str_checkname(ls), line); - break; - } - case TK_RETURN: { /* stat -> retstat */ - luaX_next(ls); /* skip RETURN */ - retstat(ls); - break; - } - case TK_BREAK: /* stat -> breakstat */ - case TK_GOTO: { /* stat -> 'goto' NAME */ - gotostat(ls, luaK_jump(ls->fs)); - break; - } - default: { /* stat -> func | assignment */ - exprstat(ls); - break; - } - } - lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && - ls->fs->freereg >= ls->fs->nactvar); - ls->fs->freereg = ls->fs->nactvar; /* free registers */ - leavelevel(ls); +static void statement(LexState *ls) +{ + int line = ls->linenumber; /* may be needed for error messages */ + enterlevel(ls); + switch (ls->t.token) + { + case ';': + { /* stat -> ';' (empty statement) */ + luaX_next(ls); /* skip ';' */ + break; + } + case TK_IF: + { /* stat -> ifstat */ + ifstat(ls, line); + break; + } + case TK_WHILE: + { /* stat -> whilestat */ + whilestat(ls, line); + break; + } + case TK_DO: + { /* stat -> DO block END */ + luaX_next(ls); /* skip DO */ + block(ls); + check_match(ls, TK_END, TK_DO, line); + break; + } + case TK_FOR: + { /* stat -> forstat */ + forstat(ls, line); + break; + } + case TK_REPEAT: + { /* stat -> repeatstat */ + repeatstat(ls, line); + break; + } + case TK_FUNCTION: + { /* stat -> funcstat */ + funcstat(ls, line); + break; + } + case TK_LOCAL: + { /* stat -> localstat */ + luaX_next(ls); /* skip LOCAL */ + if (testnext(ls, TK_FUNCTION)) /* local function? */ + localfunc(ls); + else + localstat(ls); + break; + } + case TK_DBCOLON: + { /* stat -> label */ + luaX_next(ls); /* skip double colon */ + labelstat(ls, str_checkname(ls), line); + break; + } + case TK_RETURN: + { /* stat -> retstat */ + luaX_next(ls); /* skip RETURN */ + retstat(ls); + break; + } + case TK_BREAK: /* stat -> breakstat */ + case TK_GOTO: + { /* stat -> 'goto' NAME */ + gotostat(ls, luaK_jump(ls->fs)); + break; + } + default: + { /* stat -> func | assignment */ + exprstat(ls); + break; + } + } + lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg && + ls->fs->freereg >= ls->fs->nactvar); + ls->fs->freereg = ls->fs->nactvar; /* free registers */ + leavelevel(ls); } /* }====================================================================== */ - /* ** compiles the main function, which is a regular vararg function with an ** upvalue named LUA_ENV */ -static void mainfunc (LexState *ls, FuncState *fs) { - BlockCnt bl; - expdesc v; - open_func(ls, fs, &bl); - fs->f->is_vararg = 1; /* main function is always vararg */ - init_exp(&v, VLOCAL, 0); /* create and... */ - newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ - luaX_next(ls); /* read first token */ - statlist(ls); /* parse main body */ - check(ls, TK_EOS); - close_func(ls); +static void mainfunc(LexState *ls, FuncState *fs) +{ + BlockCnt bl; + expdesc v; + open_func(ls, fs, &bl); + fs->f->is_vararg = 1; /* main function is always vararg */ + init_exp(&v, VLOCAL, 0); /* create and... */ + newupvalue(fs, ls->envn, &v); /* ...set environment upvalue */ + luaX_next(ls); /* read first token */ + statlist(ls); /* parse main body */ + check(ls, TK_EOS); + close_func(ls); } - -Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, - Dyndata *dyd, const char *name, int firstchar) { - LexState lexstate; - FuncState funcstate; - Closure *cl = luaF_newLclosure(L, 1); /* create main closure */ - /* anchor closure (to avoid being collected) */ - setclLvalue(L, L->top, cl); - incr_top(L); - funcstate.f = cl->l.p = luaF_newproto(L); - funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ - lexstate.buff = buff; - lexstate.dyd = dyd; - dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; - luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar); - mainfunc(&lexstate, &funcstate); - lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); - /* all scopes should be correctly finished */ - lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); - return cl; /* it's on the stack too */ +Closure *luaY_parser(lua_State *L, ZIO *z, Mbuffer *buff, + Dyndata *dyd, const char *name, int firstchar) +{ + LexState lexstate; + FuncState funcstate; + Closure *cl = luaF_newLclosure(L, 1); /* create main closure */ + /* anchor closure (to avoid being collected) */ + setclLvalue(L, L->top, cl); + incr_top(L); + funcstate.f = cl->l.p = luaF_newproto(L); + funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ + lexstate.buff = buff; + lexstate.dyd = dyd; + dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; + luaX_setinput(L, &lexstate, z, funcstate.f->source, firstchar); + mainfunc(&lexstate, &funcstate); + lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs); + /* all scopes should be correctly finished */ + lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0); + return cl; /* it's on the stack too */ } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lparser.h b/examples/ThirdPartyLibs/lua-5.2.3/src/lparser.h index 0346e3c41..7c2200905 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lparser.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lparser.h @@ -11,109 +11,108 @@ #include "lobject.h" #include "lzio.h" - /* ** Expression descriptor */ -typedef enum { - VVOID, /* no value */ - VNIL, - VTRUE, - VFALSE, - VK, /* info = index of constant in `k' */ - VKNUM, /* nval = numerical value */ - VNONRELOC, /* info = result register */ - VLOCAL, /* info = local register */ - VUPVAL, /* info = index of upvalue in 'upvalues' */ - VINDEXED, /* t = table register/upvalue; idx = index R/K */ - VJMP, /* info = instruction pc */ - VRELOCABLE, /* info = instruction pc */ - VCALL, /* info = instruction pc */ - VVARARG /* info = instruction pc */ +typedef enum +{ + VVOID, /* no value */ + VNIL, + VTRUE, + VFALSE, + VK, /* info = index of constant in `k' */ + VKNUM, /* nval = numerical value */ + VNONRELOC, /* info = result register */ + VLOCAL, /* info = local register */ + VUPVAL, /* info = index of upvalue in 'upvalues' */ + VINDEXED, /* t = table register/upvalue; idx = index R/K */ + VJMP, /* info = instruction pc */ + VRELOCABLE, /* info = instruction pc */ + VCALL, /* info = instruction pc */ + VVARARG /* info = instruction pc */ } expkind; +#define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED) +#define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL) -#define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED) -#define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL) - -typedef struct expdesc { - expkind k; - union { - struct { /* for indexed variables (VINDEXED) */ - short idx; /* index (R/K) */ - lu_byte t; /* table (register or upvalue) */ - lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */ - } ind; - int info; /* for generic use */ - lua_Number nval; /* for VKNUM */ - } u; - int t; /* patch list of `exit when true' */ - int f; /* patch list of `exit when false' */ +typedef struct expdesc +{ + expkind k; + union { + struct + { /* for indexed variables (VINDEXED) */ + short idx; /* index (R/K) */ + lu_byte t; /* table (register or upvalue) */ + lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */ + } ind; + int info; /* for generic use */ + lua_Number nval; /* for VKNUM */ + } u; + int t; /* patch list of `exit when true' */ + int f; /* patch list of `exit when false' */ } expdesc; - /* description of active local variable */ -typedef struct Vardesc { - short idx; /* variable index in stack */ +typedef struct Vardesc +{ + short idx; /* variable index in stack */ } Vardesc; - /* description of pending goto statements and label statements */ -typedef struct Labeldesc { - TString *name; /* label identifier */ - int pc; /* position in code */ - int line; /* line where it appeared */ - lu_byte nactvar; /* local level where it appears in current block */ +typedef struct Labeldesc +{ + TString *name; /* label identifier */ + int pc; /* position in code */ + int line; /* line where it appeared */ + lu_byte nactvar; /* local level where it appears in current block */ } Labeldesc; - /* list of labels or gotos */ -typedef struct Labellist { - Labeldesc *arr; /* array */ - int n; /* number of entries in use */ - int size; /* array size */ +typedef struct Labellist +{ + Labeldesc *arr; /* array */ + int n; /* number of entries in use */ + int size; /* array size */ } Labellist; - /* dynamic structures used by the parser */ -typedef struct Dyndata { - struct { /* list of active local variables */ - Vardesc *arr; - int n; - int size; - } actvar; - Labellist gt; /* list of pending gotos */ - Labellist label; /* list of active labels */ +typedef struct Dyndata +{ + struct + { /* list of active local variables */ + Vardesc *arr; + int n; + int size; + } actvar; + Labellist gt; /* list of pending gotos */ + Labellist label; /* list of active labels */ } Dyndata; - /* control of blocks */ -struct BlockCnt; /* defined in lparser.c */ - +struct BlockCnt; /* defined in lparser.c */ /* state needed to generate code for a given function */ -typedef struct FuncState { - Proto *f; /* current function header */ - Table *h; /* table to find (and reuse) elements in `k' */ - struct FuncState *prev; /* enclosing function */ - struct LexState *ls; /* lexical state */ - struct BlockCnt *bl; /* chain of current blocks */ - int pc; /* next position to code (equivalent to `ncode') */ - int lasttarget; /* 'label' of last 'jump label' */ - int jpc; /* list of pending jumps to `pc' */ - int nk; /* number of elements in `k' */ - int np; /* number of elements in `p' */ - int firstlocal; /* index of first local var (in Dyndata array) */ - short nlocvars; /* number of elements in 'f->locvars' */ - lu_byte nactvar; /* number of active local variables */ - lu_byte nups; /* number of upvalues */ - lu_byte freereg; /* first free register */ +typedef struct FuncState +{ + Proto *f; /* current function header */ + Table *h; /* table to find (and reuse) elements in `k' */ + struct FuncState *prev; /* enclosing function */ + struct LexState *ls; /* lexical state */ + struct BlockCnt *bl; /* chain of current blocks */ + int pc; /* next position to code (equivalent to `ncode') */ + int lasttarget; /* 'label' of last 'jump label' */ + int jpc; /* list of pending jumps to `pc' */ + int nk; /* number of elements in `k' */ + int np; /* number of elements in `p' */ + int firstlocal; /* index of first local var (in Dyndata array) */ + short nlocvars; /* number of elements in 'f->locvars' */ + lu_byte nactvar; /* number of active local variables */ + lu_byte nups; /* number of upvalues */ + lu_byte freereg; /* first free register */ } FuncState; - -LUAI_FUNC Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, - Dyndata *dyd, const char *name, int firstchar); - +LUAI_FUNC Closure *luaY_parser(lua_State *L, ZIO *z, Mbuffer *buff, + Dyndata *dyd, const char *name, int firstchar); #endif diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lstate.c b/examples/ThirdPartyLibs/lua-5.2.3/src/lstate.c index c7f2672be..eeeb305df 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lstate.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lstate.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #include #include @@ -25,22 +24,19 @@ #include "ltable.h" #include "ltm.h" - #if !defined(LUAI_GCPAUSE) -#define LUAI_GCPAUSE 200 /* 200% */ +#define LUAI_GCPAUSE 200 /* 200% */ #endif #if !defined(LUAI_GCMAJOR) -#define LUAI_GCMAJOR 200 /* 200% */ +#define LUAI_GCMAJOR 200 /* 200% */ #endif #if !defined(LUAI_GCMUL) -#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ +#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */ #endif - -#define MEMERRMSG "not enough memory" - +#define MEMERRMSG "not enough memory" /* ** a macro to help the creation of a unique random seed when a state is @@ -48,276 +44,277 @@ */ #if !defined(luai_makeseed) #include -#define luai_makeseed() cast(unsigned int, time(NULL)) +#define luai_makeseed() cast(unsigned int, time(NULL)) #endif - - /* ** thread state + extra space */ -typedef struct LX { +typedef struct LX +{ #if defined(LUAI_EXTRASPACE) - char buff[LUAI_EXTRASPACE]; + char buff[LUAI_EXTRASPACE]; #endif - lua_State l; + lua_State l; } LX; - /* ** Main thread combines a thread state and the global state */ -typedef struct LG { - LX l; - global_State g; +typedef struct LG +{ + LX l; + global_State g; } LG; - - -#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l))) - +#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l))) /* ** Compute an initial seed as random as possible. In ANSI, rely on ** Address Space Layout Randomization (if present) to increase ** randomness.. */ -#define addbuff(b,p,e) \ - { size_t t = cast(size_t, e); \ - memcpy(buff + p, &t, sizeof(t)); p += sizeof(t); } +#define addbuff(b, p, e) \ + { \ + size_t t = cast(size_t, e); \ + memcpy(buff + p, &t, sizeof(t)); \ + p += sizeof(t); \ + } -static unsigned int makeseed (lua_State *L) { - char buff[4 * sizeof(size_t)]; - unsigned int h = luai_makeseed(); - int p = 0; - addbuff(buff, p, L); /* heap variable */ - addbuff(buff, p, &h); /* local variable */ - addbuff(buff, p, luaO_nilobject); /* global variable */ - addbuff(buff, p, &lua_newstate); /* public function */ - lua_assert(p == sizeof(buff)); - return luaS_hash(buff, p, h); +static unsigned int makeseed(lua_State *L) +{ + char buff[4 * sizeof(size_t)]; + unsigned int h = luai_makeseed(); + int p = 0; + addbuff(buff, p, L); /* heap variable */ + addbuff(buff, p, &h); /* local variable */ + addbuff(buff, p, luaO_nilobject); /* global variable */ + addbuff(buff, p, &lua_newstate); /* public function */ + lua_assert(p == sizeof(buff)); + return luaS_hash(buff, p, h); } - /* ** set GCdebt to a new value keeping the value (totalbytes + GCdebt) ** invariant */ -void luaE_setdebt (global_State *g, l_mem debt) { - g->totalbytes -= (debt - g->GCdebt); - g->GCdebt = debt; +void luaE_setdebt(global_State *g, l_mem debt) +{ + g->totalbytes -= (debt - g->GCdebt); + g->GCdebt = debt; } - -CallInfo *luaE_extendCI (lua_State *L) { - CallInfo *ci = luaM_new(L, CallInfo); - lua_assert(L->ci->next == NULL); - L->ci->next = ci; - ci->previous = L->ci; - ci->next = NULL; - return ci; +CallInfo *luaE_extendCI(lua_State *L) +{ + CallInfo *ci = luaM_new(L, CallInfo); + lua_assert(L->ci->next == NULL); + L->ci->next = ci; + ci->previous = L->ci; + ci->next = NULL; + return ci; } - -void luaE_freeCI (lua_State *L) { - CallInfo *ci = L->ci; - CallInfo *next = ci->next; - ci->next = NULL; - while ((ci = next) != NULL) { - next = ci->next; - luaM_free(L, ci); - } +void luaE_freeCI(lua_State *L) +{ + CallInfo *ci = L->ci; + CallInfo *next = ci->next; + ci->next = NULL; + while ((ci = next) != NULL) + { + next = ci->next; + luaM_free(L, ci); + } } - -static void stack_init (lua_State *L1, lua_State *L) { - int i; CallInfo *ci; - /* initialize stack array */ - L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue); - L1->stacksize = BASIC_STACK_SIZE; - for (i = 0; i < BASIC_STACK_SIZE; i++) - setnilvalue(L1->stack + i); /* erase new stack */ - L1->top = L1->stack; - L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; - /* initialize first ci */ - ci = &L1->base_ci; - ci->next = ci->previous = NULL; - ci->callstatus = 0; - ci->func = L1->top; - setnilvalue(L1->top++); /* 'function' entry for this 'ci' */ - ci->top = L1->top + LUA_MINSTACK; - L1->ci = ci; +static void stack_init(lua_State *L1, lua_State *L) +{ + int i; + CallInfo *ci; + /* initialize stack array */ + L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue); + L1->stacksize = BASIC_STACK_SIZE; + for (i = 0; i < BASIC_STACK_SIZE; i++) + setnilvalue(L1->stack + i); /* erase new stack */ + L1->top = L1->stack; + L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; + /* initialize first ci */ + ci = &L1->base_ci; + ci->next = ci->previous = NULL; + ci->callstatus = 0; + ci->func = L1->top; + setnilvalue(L1->top++); /* 'function' entry for this 'ci' */ + ci->top = L1->top + LUA_MINSTACK; + L1->ci = ci; } - -static void freestack (lua_State *L) { - if (L->stack == NULL) - return; /* stack not completely built yet */ - L->ci = &L->base_ci; /* free the entire 'ci' list */ - luaE_freeCI(L); - luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ +static void freestack(lua_State *L) +{ + if (L->stack == NULL) + return; /* stack not completely built yet */ + L->ci = &L->base_ci; /* free the entire 'ci' list */ + luaE_freeCI(L); + luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ } - /* ** Create registry table and its predefined values */ -static void init_registry (lua_State *L, global_State *g) { - TValue mt; - /* create registry */ - Table *registry = luaH_new(L); - sethvalue(L, &g->l_registry, registry); - luaH_resize(L, registry, LUA_RIDX_LAST, 0); - /* registry[LUA_RIDX_MAINTHREAD] = L */ - setthvalue(L, &mt, L); - luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt); - /* registry[LUA_RIDX_GLOBALS] = table of globals */ - sethvalue(L, &mt, luaH_new(L)); - luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt); +static void init_registry(lua_State *L, global_State *g) +{ + TValue mt; + /* create registry */ + Table *registry = luaH_new(L); + sethvalue(L, &g->l_registry, registry); + luaH_resize(L, registry, LUA_RIDX_LAST, 0); + /* registry[LUA_RIDX_MAINTHREAD] = L */ + setthvalue(L, &mt, L); + luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt); + /* registry[LUA_RIDX_GLOBALS] = table of globals */ + sethvalue(L, &mt, luaH_new(L)); + luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt); } - /* ** open parts of the state that may cause memory-allocation errors */ -static void f_luaopen (lua_State *L, void *ud) { - global_State *g = G(L); - UNUSED(ud); - stack_init(L, L); /* init stack */ - init_registry(L, g); - luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ - luaT_init(L); - luaX_init(L); - /* pre-create memory-error message */ - g->memerrmsg = luaS_newliteral(L, MEMERRMSG); - luaS_fix(g->memerrmsg); /* it should never be collected */ - g->gcrunning = 1; /* allow gc */ - g->version = lua_version(NULL); - luai_userstateopen(L); +static void f_luaopen(lua_State *L, void *ud) +{ + global_State *g = G(L); + UNUSED(ud); + stack_init(L, L); /* init stack */ + init_registry(L, g); + luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */ + luaT_init(L); + luaX_init(L); + /* pre-create memory-error message */ + g->memerrmsg = luaS_newliteral(L, MEMERRMSG); + luaS_fix(g->memerrmsg); /* it should never be collected */ + g->gcrunning = 1; /* allow gc */ + g->version = lua_version(NULL); + luai_userstateopen(L); } - /* ** preinitialize a state with consistent values without allocating ** any memory (to avoid errors) */ -static void preinit_state (lua_State *L, global_State *g) { - G(L) = g; - L->stack = NULL; - L->ci = NULL; - L->stacksize = 0; - L->errorJmp = NULL; - L->nCcalls = 0; - L->hook = NULL; - L->hookmask = 0; - L->basehookcount = 0; - L->allowhook = 1; - resethookcount(L); - L->openupval = NULL; - L->nny = 1; - L->status = LUA_OK; - L->errfunc = 0; +static void preinit_state(lua_State *L, global_State *g) +{ + G(L) = g; + L->stack = NULL; + L->ci = NULL; + L->stacksize = 0; + L->errorJmp = NULL; + L->nCcalls = 0; + L->hook = NULL; + L->hookmask = 0; + L->basehookcount = 0; + L->allowhook = 1; + resethookcount(L); + L->openupval = NULL; + L->nny = 1; + L->status = LUA_OK; + L->errfunc = 0; } - -static void close_state (lua_State *L) { - global_State *g = G(L); - luaF_close(L, L->stack); /* close all upvalues for this thread */ - luaC_freeallobjects(L); /* collect all objects */ - if (g->version) /* closing a fully built state? */ - luai_userstateclose(L); - luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); - luaZ_freebuffer(L, &g->buff); - freestack(L); - lua_assert(gettotalbytes(g) == sizeof(LG)); - (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */ +static void close_state(lua_State *L) +{ + global_State *g = G(L); + luaF_close(L, L->stack); /* close all upvalues for this thread */ + luaC_freeallobjects(L); /* collect all objects */ + if (g->version) /* closing a fully built state? */ + luai_userstateclose(L); + luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size); + luaZ_freebuffer(L, &g->buff); + freestack(L); + lua_assert(gettotalbytes(g) == sizeof(LG)); + (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */ } - -LUA_API lua_State *lua_newthread (lua_State *L) { - lua_State *L1; - lua_lock(L); - luaC_checkGC(L); - L1 = &luaC_newobj(L, LUA_TTHREAD, sizeof(LX), NULL, offsetof(LX, l))->th; - setthvalue(L, L->top, L1); - api_incr_top(L); - preinit_state(L1, G(L)); - L1->hookmask = L->hookmask; - L1->basehookcount = L->basehookcount; - L1->hook = L->hook; - resethookcount(L1); - luai_userstatethread(L, L1); - stack_init(L1, L); /* init stack */ - lua_unlock(L); - return L1; +LUA_API lua_State *lua_newthread(lua_State *L) +{ + lua_State *L1; + lua_lock(L); + luaC_checkGC(L); + L1 = &luaC_newobj(L, LUA_TTHREAD, sizeof(LX), NULL, offsetof(LX, l))->th; + setthvalue(L, L->top, L1); + api_incr_top(L); + preinit_state(L1, G(L)); + L1->hookmask = L->hookmask; + L1->basehookcount = L->basehookcount; + L1->hook = L->hook; + resethookcount(L1); + luai_userstatethread(L, L1); + stack_init(L1, L); /* init stack */ + lua_unlock(L); + return L1; } - -void luaE_freethread (lua_State *L, lua_State *L1) { - LX *l = fromstate(L1); - luaF_close(L1, L1->stack); /* close all upvalues for this thread */ - lua_assert(L1->openupval == NULL); - luai_userstatefree(L, L1); - freestack(L1); - luaM_free(L, l); +void luaE_freethread(lua_State *L, lua_State *L1) +{ + LX *l = fromstate(L1); + luaF_close(L1, L1->stack); /* close all upvalues for this thread */ + lua_assert(L1->openupval == NULL); + luai_userstatefree(L, L1); + freestack(L1); + luaM_free(L, l); } - -LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { - int i; - lua_State *L; - global_State *g; - LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG))); - if (l == NULL) return NULL; - L = &l->l.l; - g = &l->g; - L->next = NULL; - L->tt = LUA_TTHREAD; - g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); - L->marked = luaC_white(g); - g->gckind = KGC_NORMAL; - preinit_state(L, g); - g->frealloc = f; - g->ud = ud; - g->mainthread = L; - g->seed = makeseed(L); - g->uvhead.u.l.prev = &g->uvhead; - g->uvhead.u.l.next = &g->uvhead; - g->gcrunning = 0; /* no GC while building state */ - g->GCestimate = 0; - g->strt.size = 0; - g->strt.nuse = 0; - g->strt.hash = NULL; - setnilvalue(&g->l_registry); - luaZ_initbuffer(L, &g->buff); - g->panic = NULL; - g->version = NULL; - g->gcstate = GCSpause; - g->allgc = NULL; - g->finobj = NULL; - g->tobefnz = NULL; - g->sweepgc = g->sweepfin = NULL; - g->gray = g->grayagain = NULL; - g->weak = g->ephemeron = g->allweak = NULL; - g->totalbytes = sizeof(LG); - g->GCdebt = 0; - g->gcpause = LUAI_GCPAUSE; - g->gcmajorinc = LUAI_GCMAJOR; - g->gcstepmul = LUAI_GCMUL; - for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; - if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) { - /* memory allocation error: free partial state */ - close_state(L); - L = NULL; - } - return L; +LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud) +{ + int i; + lua_State *L; + global_State *g; + LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG))); + if (l == NULL) return NULL; + L = &l->l.l; + g = &l->g; + L->next = NULL; + L->tt = LUA_TTHREAD; + g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); + L->marked = luaC_white(g); + g->gckind = KGC_NORMAL; + preinit_state(L, g); + g->frealloc = f; + g->ud = ud; + g->mainthread = L; + g->seed = makeseed(L); + g->uvhead.u.l.prev = &g->uvhead; + g->uvhead.u.l.next = &g->uvhead; + g->gcrunning = 0; /* no GC while building state */ + g->GCestimate = 0; + g->strt.size = 0; + g->strt.nuse = 0; + g->strt.hash = NULL; + setnilvalue(&g->l_registry); + luaZ_initbuffer(L, &g->buff); + g->panic = NULL; + g->version = NULL; + g->gcstate = GCSpause; + g->allgc = NULL; + g->finobj = NULL; + g->tobefnz = NULL; + g->sweepgc = g->sweepfin = NULL; + g->gray = g->grayagain = NULL; + g->weak = g->ephemeron = g->allweak = NULL; + g->totalbytes = sizeof(LG); + g->GCdebt = 0; + g->gcpause = LUAI_GCPAUSE; + g->gcmajorinc = LUAI_GCMAJOR; + g->gcstepmul = LUAI_GCMUL; + for (i = 0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL; + if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) + { + /* memory allocation error: free partial state */ + close_state(L); + L = NULL; + } + return L; } - -LUA_API void lua_close (lua_State *L) { - L = G(L)->mainthread; /* only the main thread can be closed */ - lua_lock(L); - close_state(L); +LUA_API void lua_close(lua_State *L) +{ + L = G(L)->mainthread; /* only the main thread can be closed */ + lua_lock(L); + close_state(L); } - - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lstate.h b/examples/ThirdPartyLibs/lua-5.2.3/src/lstate.h index daffd9aac..7e21b1d52 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lstate.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lstate.h @@ -13,7 +13,6 @@ #include "ltm.h" #include "lzio.h" - /* ** Some notes about garbage-collected objects: All objects in Lua must @@ -38,191 +37,180 @@ */ - -struct lua_longjmp; /* defined in ldo.c */ - - +struct lua_longjmp; /* defined in ldo.c */ /* extra stack space to handle TM calls and some other extras */ -#define EXTRA_STACK 5 - - -#define BASIC_STACK_SIZE (2*LUA_MINSTACK) +#define EXTRA_STACK 5 +#define BASIC_STACK_SIZE (2 * LUA_MINSTACK) /* kinds of Garbage Collection */ -#define KGC_NORMAL 0 -#define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */ -#define KGC_GEN 2 /* generational collection */ +#define KGC_NORMAL 0 +#define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */ +#define KGC_GEN 2 /* generational collection */ - -typedef struct stringtable { - GCObject **hash; - lu_int32 nuse; /* number of elements */ - int size; +typedef struct stringtable +{ + GCObject **hash; + lu_int32 nuse; /* number of elements */ + int size; } stringtable; - /* ** information about a call */ -typedef struct CallInfo { - StkId func; /* function index in the stack */ - StkId top; /* top for this function */ - struct CallInfo *previous, *next; /* dynamic call link */ - short nresults; /* expected number of results from this function */ - lu_byte callstatus; - ptrdiff_t extra; - union { - struct { /* only for Lua functions */ - StkId base; /* base for this function */ - const Instruction *savedpc; - } l; - struct { /* only for C functions */ - int ctx; /* context info. in case of yields */ - lua_CFunction k; /* continuation in case of yields */ - ptrdiff_t old_errfunc; - lu_byte old_allowhook; - lu_byte status; - } c; - } u; +typedef struct CallInfo +{ + StkId func; /* function index in the stack */ + StkId top; /* top for this function */ + struct CallInfo *previous, *next; /* dynamic call link */ + short nresults; /* expected number of results from this function */ + lu_byte callstatus; + ptrdiff_t extra; + union { + struct + { /* only for Lua functions */ + StkId base; /* base for this function */ + const Instruction *savedpc; + } l; + struct + { /* only for C functions */ + int ctx; /* context info. in case of yields */ + lua_CFunction k; /* continuation in case of yields */ + ptrdiff_t old_errfunc; + lu_byte old_allowhook; + lu_byte status; + } c; + } u; } CallInfo; - /* ** Bits in CallInfo status */ -#define CIST_LUA (1<<0) /* call is running a Lua function */ -#define CIST_HOOKED (1<<1) /* call is running a debug hook */ -#define CIST_REENTRY (1<<2) /* call is running on same invocation of +#define CIST_LUA (1 << 0) /* call is running a Lua function */ +#define CIST_HOOKED (1 << 1) /* call is running a debug hook */ +#define CIST_REENTRY (1 << 2) /* call is running on same invocation of luaV_execute of previous call */ -#define CIST_YIELDED (1<<3) /* call reentered after suspension */ -#define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ -#define CIST_STAT (1<<5) /* call has an error status (pcall) */ -#define CIST_TAIL (1<<6) /* call was tail called */ -#define CIST_HOOKYIELD (1<<7) /* last hook called yielded */ - - -#define isLua(ci) ((ci)->callstatus & CIST_LUA) +#define CIST_YIELDED (1 << 3) /* call reentered after suspension */ +#define CIST_YPCALL (1 << 4) /* call is a yieldable protected call */ +#define CIST_STAT (1 << 5) /* call has an error status (pcall) */ +#define CIST_TAIL (1 << 6) /* call was tail called */ +#define CIST_HOOKYIELD (1 << 7) /* last hook called yielded */ +#define isLua(ci) ((ci)->callstatus & CIST_LUA) /* ** `global state', shared by all threads of this state */ -typedef struct global_State { - lua_Alloc frealloc; /* function to reallocate memory */ - void *ud; /* auxiliary data to `frealloc' */ - lu_mem totalbytes; /* number of bytes currently allocated - GCdebt */ - l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ - lu_mem GCmemtrav; /* memory traversed by the GC */ - lu_mem GCestimate; /* an estimate of the non-garbage memory in use */ - stringtable strt; /* hash table for strings */ - TValue l_registry; - unsigned int seed; /* randomized seed for hashes */ - lu_byte currentwhite; - lu_byte gcstate; /* state of garbage collector */ - lu_byte gckind; /* kind of GC running */ - lu_byte gcrunning; /* true if GC is running */ - int sweepstrgc; /* position of sweep in `strt' */ - GCObject *allgc; /* list of all collectable objects */ - GCObject *finobj; /* list of collectable objects with finalizers */ - GCObject **sweepgc; /* current position of sweep in list 'allgc' */ - GCObject **sweepfin; /* current position of sweep in list 'finobj' */ - GCObject *gray; /* list of gray objects */ - GCObject *grayagain; /* list of objects to be traversed atomically */ - GCObject *weak; /* list of tables with weak values */ - GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ - GCObject *allweak; /* list of all-weak tables */ - GCObject *tobefnz; /* list of userdata to be GC */ - UpVal uvhead; /* head of double-linked list of all open upvalues */ - Mbuffer buff; /* temporary buffer for string concatenation */ - int gcpause; /* size of pause between successive GCs */ - int gcmajorinc; /* pause between major collections (only in gen. mode) */ - int gcstepmul; /* GC `granularity' */ - lua_CFunction panic; /* to be called in unprotected errors */ - struct lua_State *mainthread; - const lua_Number *version; /* pointer to version number */ - TString *memerrmsg; /* memory-error message */ - TString *tmname[TM_N]; /* array with tag-method names */ - struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */ +typedef struct global_State +{ + lua_Alloc frealloc; /* function to reallocate memory */ + void *ud; /* auxiliary data to `frealloc' */ + lu_mem totalbytes; /* number of bytes currently allocated - GCdebt */ + l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ + lu_mem GCmemtrav; /* memory traversed by the GC */ + lu_mem GCestimate; /* an estimate of the non-garbage memory in use */ + stringtable strt; /* hash table for strings */ + TValue l_registry; + unsigned int seed; /* randomized seed for hashes */ + lu_byte currentwhite; + lu_byte gcstate; /* state of garbage collector */ + lu_byte gckind; /* kind of GC running */ + lu_byte gcrunning; /* true if GC is running */ + int sweepstrgc; /* position of sweep in `strt' */ + GCObject *allgc; /* list of all collectable objects */ + GCObject *finobj; /* list of collectable objects with finalizers */ + GCObject **sweepgc; /* current position of sweep in list 'allgc' */ + GCObject **sweepfin; /* current position of sweep in list 'finobj' */ + GCObject *gray; /* list of gray objects */ + GCObject *grayagain; /* list of objects to be traversed atomically */ + GCObject *weak; /* list of tables with weak values */ + GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ + GCObject *allweak; /* list of all-weak tables */ + GCObject *tobefnz; /* list of userdata to be GC */ + UpVal uvhead; /* head of double-linked list of all open upvalues */ + Mbuffer buff; /* temporary buffer for string concatenation */ + int gcpause; /* size of pause between successive GCs */ + int gcmajorinc; /* pause between major collections (only in gen. mode) */ + int gcstepmul; /* GC `granularity' */ + lua_CFunction panic; /* to be called in unprotected errors */ + struct lua_State *mainthread; + const lua_Number *version; /* pointer to version number */ + TString *memerrmsg; /* memory-error message */ + TString *tmname[TM_N]; /* array with tag-method names */ + struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */ } global_State; - /* ** `per thread' state */ -struct lua_State { - CommonHeader; - lu_byte status; - StkId top; /* first free slot in the stack */ - global_State *l_G; - CallInfo *ci; /* call info for current function */ - const Instruction *oldpc; /* last pc traced */ - StkId stack_last; /* last free slot in the stack */ - StkId stack; /* stack base */ - int stacksize; - unsigned short nny; /* number of non-yieldable calls in stack */ - unsigned short nCcalls; /* number of nested C calls */ - lu_byte hookmask; - lu_byte allowhook; - int basehookcount; - int hookcount; - lua_Hook hook; - GCObject *openupval; /* list of open upvalues in this stack */ - GCObject *gclist; - struct lua_longjmp *errorJmp; /* current error recover point */ - ptrdiff_t errfunc; /* current error handling function (stack index) */ - CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ +struct lua_State +{ + CommonHeader; + lu_byte status; + StkId top; /* first free slot in the stack */ + global_State *l_G; + CallInfo *ci; /* call info for current function */ + const Instruction *oldpc; /* last pc traced */ + StkId stack_last; /* last free slot in the stack */ + StkId stack; /* stack base */ + int stacksize; + unsigned short nny; /* number of non-yieldable calls in stack */ + unsigned short nCcalls; /* number of nested C calls */ + lu_byte hookmask; + lu_byte allowhook; + int basehookcount; + int hookcount; + lua_Hook hook; + GCObject *openupval; /* list of open upvalues in this stack */ + GCObject *gclist; + struct lua_longjmp *errorJmp; /* current error recover point */ + ptrdiff_t errfunc; /* current error handling function (stack index) */ + CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ }; - -#define G(L) (L->l_G) - +#define G(L) (L->l_G) /* ** Union of all collectable objects */ union GCObject { - GCheader gch; /* common header */ - union TString ts; - union Udata u; - union Closure cl; - struct Table h; - struct Proto p; - struct UpVal uv; - struct lua_State th; /* thread */ + GCheader gch; /* common header */ + union TString ts; + union Udata u; + union Closure cl; + struct Table h; + struct Proto p; + struct UpVal uv; + struct lua_State th; /* thread */ }; - -#define gch(o) (&(o)->gch) +#define gch(o) (&(o)->gch) /* macros to convert a GCObject into a specific value */ -#define rawgco2ts(o) \ +#define rawgco2ts(o) \ check_exp(novariant((o)->gch.tt) == LUA_TSTRING, &((o)->ts)) -#define gco2ts(o) (&rawgco2ts(o)->tsv) -#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) -#define gco2u(o) (&rawgco2u(o)->uv) -#define gco2lcl(o) check_exp((o)->gch.tt == LUA_TLCL, &((o)->cl.l)) -#define gco2ccl(o) check_exp((o)->gch.tt == LUA_TCCL, &((o)->cl.c)) -#define gco2cl(o) \ +#define gco2ts(o) (&rawgco2ts(o)->tsv) +#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u)) +#define gco2u(o) (&rawgco2u(o)->uv) +#define gco2lcl(o) check_exp((o)->gch.tt == LUA_TLCL, &((o)->cl.l)) +#define gco2ccl(o) check_exp((o)->gch.tt == LUA_TCCL, &((o)->cl.c)) +#define gco2cl(o) \ check_exp(novariant((o)->gch.tt) == LUA_TFUNCTION, &((o)->cl)) -#define gco2t(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) -#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) -#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) -#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) +#define gco2t(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h)) +#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p)) +#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv)) +#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th)) /* macro to convert any Lua object into a GCObject */ -#define obj2gco(v) (cast(GCObject *, (v))) - +#define obj2gco(v) (cast(GCObject *, (v))) /* actual number of total bytes allocated */ -#define gettotalbytes(g) ((g)->totalbytes + (g)->GCdebt) - -LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); -LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); -LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); -LUAI_FUNC void luaE_freeCI (lua_State *L); +#define gettotalbytes(g) ((g)->totalbytes + (g)->GCdebt) +LUAI_FUNC void luaE_setdebt(global_State *g, l_mem debt); +LUAI_FUNC void luaE_freethread(lua_State *L, lua_State *L1); +LUAI_FUNC CallInfo *luaE_extendCI(lua_State *L); +LUAI_FUNC void luaE_freeCI(lua_State *L); #endif - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lstring.c b/examples/ThirdPartyLibs/lua-5.2.3/src/lstring.c index af96c89c1..962296d28 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lstring.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lstring.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #include #define lstring_c @@ -17,169 +16,174 @@ #include "lstate.h" #include "lstring.h" - /* ** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to ** compute its hash */ #if !defined(LUAI_HASHLIMIT) -#define LUAI_HASHLIMIT 5 +#define LUAI_HASHLIMIT 5 #endif - /* ** equality for long strings */ -int luaS_eqlngstr (TString *a, TString *b) { - size_t len = a->tsv.len; - lua_assert(a->tsv.tt == LUA_TLNGSTR && b->tsv.tt == LUA_TLNGSTR); - return (a == b) || /* same instance or... */ - ((len == b->tsv.len) && /* equal length and ... */ - (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ +int luaS_eqlngstr(TString *a, TString *b) +{ + size_t len = a->tsv.len; + lua_assert(a->tsv.tt == LUA_TLNGSTR && b->tsv.tt == LUA_TLNGSTR); + return (a == b) || /* same instance or... */ + ((len == b->tsv.len) && /* equal length and ... */ + (memcmp(getstr(a), getstr(b), len) == 0)); /* equal contents */ } - /* ** equality for strings */ -int luaS_eqstr (TString *a, TString *b) { - return (a->tsv.tt == b->tsv.tt) && - (a->tsv.tt == LUA_TSHRSTR ? eqshrstr(a, b) : luaS_eqlngstr(a, b)); +int luaS_eqstr(TString *a, TString *b) +{ + return (a->tsv.tt == b->tsv.tt) && + (a->tsv.tt == LUA_TSHRSTR ? eqshrstr(a, b) : luaS_eqlngstr(a, b)); } - -unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { - unsigned int h = seed ^ cast(unsigned int, l); - size_t l1; - size_t step = (l >> LUAI_HASHLIMIT) + 1; - for (l1 = l; l1 >= step; l1 -= step) - h = h ^ ((h<<5) + (h>>2) + cast_byte(str[l1 - 1])); - return h; +unsigned int luaS_hash(const char *str, size_t l, unsigned int seed) +{ + unsigned int h = seed ^ cast(unsigned int, l); + size_t l1; + size_t step = (l >> LUAI_HASHLIMIT) + 1; + for (l1 = l; l1 >= step; l1 -= step) + h = h ^ ((h << 5) + (h >> 2) + cast_byte(str[l1 - 1])); + return h; } - /* ** resizes the string table */ -void luaS_resize (lua_State *L, int newsize) { - int i; - stringtable *tb = &G(L)->strt; - /* cannot resize while GC is traversing strings */ - luaC_runtilstate(L, ~bitmask(GCSsweepstring)); - if (newsize > tb->size) { - luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); - for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL; - } - /* rehash */ - for (i=0; isize; i++) { - GCObject *p = tb->hash[i]; - tb->hash[i] = NULL; - while (p) { /* for each node in the list */ - GCObject *next = gch(p)->next; /* save next */ - unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */ - gch(p)->next = tb->hash[h]; /* chain it */ - tb->hash[h] = p; - resetoldbit(p); /* see MOVE OLD rule */ - p = next; - } - } - if (newsize < tb->size) { - /* shrinking slice must be empty */ - lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL); - luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); - } - tb->size = newsize; +void luaS_resize(lua_State *L, int newsize) +{ + int i; + stringtable *tb = &G(L)->strt; + /* cannot resize while GC is traversing strings */ + luaC_runtilstate(L, ~bitmask(GCSsweepstring)); + if (newsize > tb->size) + { + luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); + for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL; + } + /* rehash */ + for (i = 0; i < tb->size; i++) + { + GCObject *p = tb->hash[i]; + tb->hash[i] = NULL; + while (p) + { /* for each node in the list */ + GCObject *next = gch(p)->next; /* save next */ + unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */ + gch(p)->next = tb->hash[h]; /* chain it */ + tb->hash[h] = p; + resetoldbit(p); /* see MOVE OLD rule */ + p = next; + } + } + if (newsize < tb->size) + { + /* shrinking slice must be empty */ + lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL); + luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *); + } + tb->size = newsize; } - /* ** creates a new string object */ -static TString *createstrobj (lua_State *L, const char *str, size_t l, - int tag, unsigned int h, GCObject **list) { - TString *ts; - size_t totalsize; /* total size of TString object */ - totalsize = sizeof(TString) + ((l + 1) * sizeof(char)); - ts = &luaC_newobj(L, tag, totalsize, list, 0)->ts; - ts->tsv.len = l; - ts->tsv.hash = h; - ts->tsv.extra = 0; - memcpy(ts+1, str, l*sizeof(char)); - ((char *)(ts+1))[l] = '\0'; /* ending 0 */ - return ts; +static TString *createstrobj(lua_State *L, const char *str, size_t l, + int tag, unsigned int h, GCObject **list) +{ + TString *ts; + size_t totalsize; /* total size of TString object */ + totalsize = sizeof(TString) + ((l + 1) * sizeof(char)); + ts = &luaC_newobj(L, tag, totalsize, list, 0)->ts; + ts->tsv.len = l; + ts->tsv.hash = h; + ts->tsv.extra = 0; + memcpy(ts + 1, str, l * sizeof(char)); + ((char *)(ts + 1))[l] = '\0'; /* ending 0 */ + return ts; } - /* ** creates a new short string, inserting it into string table */ -static TString *newshrstr (lua_State *L, const char *str, size_t l, - unsigned int h) { - GCObject **list; /* (pointer to) list where it will be inserted */ - stringtable *tb = &G(L)->strt; - TString *s; - if (tb->nuse >= cast(lu_int32, tb->size) && tb->size <= MAX_INT/2) - luaS_resize(L, tb->size*2); /* too crowded */ - list = &tb->hash[lmod(h, tb->size)]; - s = createstrobj(L, str, l, LUA_TSHRSTR, h, list); - tb->nuse++; - return s; +static TString *newshrstr(lua_State *L, const char *str, size_t l, + unsigned int h) +{ + GCObject **list; /* (pointer to) list where it will be inserted */ + stringtable *tb = &G(L)->strt; + TString *s; + if (tb->nuse >= cast(lu_int32, tb->size) && tb->size <= MAX_INT / 2) + luaS_resize(L, tb->size * 2); /* too crowded */ + list = &tb->hash[lmod(h, tb->size)]; + s = createstrobj(L, str, l, LUA_TSHRSTR, h, list); + tb->nuse++; + return s; } - /* ** checks whether short string exists and reuses it or creates a new one */ -static TString *internshrstr (lua_State *L, const char *str, size_t l) { - GCObject *o; - global_State *g = G(L); - unsigned int h = luaS_hash(str, l, g->seed); - for (o = g->strt.hash[lmod(h, g->strt.size)]; - o != NULL; - o = gch(o)->next) { - TString *ts = rawgco2ts(o); - if (h == ts->tsv.hash && - l == ts->tsv.len && - (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) { - if (isdead(G(L), o)) /* string is dead (but was not collected yet)? */ - changewhite(o); /* resurrect it */ - return ts; - } - } - return newshrstr(L, str, l, h); /* not found; create a new string */ +static TString *internshrstr(lua_State *L, const char *str, size_t l) +{ + GCObject *o; + global_State *g = G(L); + unsigned int h = luaS_hash(str, l, g->seed); + for (o = g->strt.hash[lmod(h, g->strt.size)]; + o != NULL; + o = gch(o)->next) + { + TString *ts = rawgco2ts(o); + if (h == ts->tsv.hash && + l == ts->tsv.len && + (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) + { + if (isdead(G(L), o)) /* string is dead (but was not collected yet)? */ + changewhite(o); /* resurrect it */ + return ts; + } + } + return newshrstr(L, str, l, h); /* not found; create a new string */ } - /* ** new string (with explicit length) */ -TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { - if (l <= LUAI_MAXSHORTLEN) /* short string? */ - return internshrstr(L, str, l); - else { - if (l + 1 > (MAX_SIZET - sizeof(TString))/sizeof(char)) - luaM_toobig(L); - return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed, NULL); - } +TString *luaS_newlstr(lua_State *L, const char *str, size_t l) +{ + if (l <= LUAI_MAXSHORTLEN) /* short string? */ + return internshrstr(L, str, l); + else + { + if (l + 1 > (MAX_SIZET - sizeof(TString)) / sizeof(char)) + luaM_toobig(L); + return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed, NULL); + } } - /* ** new zero-terminated string */ -TString *luaS_new (lua_State *L, const char *str) { - return luaS_newlstr(L, str, strlen(str)); +TString *luaS_new(lua_State *L, const char *str) +{ + return luaS_newlstr(L, str, strlen(str)); } - -Udata *luaS_newudata (lua_State *L, size_t s, Table *e) { - Udata *u; - if (s > MAX_SIZET - sizeof(Udata)) - luaM_toobig(L); - u = &luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s, NULL, 0)->u; - u->uv.len = s; - u->uv.metatable = NULL; - u->uv.env = e; - return u; +Udata *luaS_newudata(lua_State *L, size_t s, Table *e) +{ + Udata *u; + if (s > MAX_SIZET - sizeof(Udata)) + luaM_toobig(L); + u = &luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s, NULL, 0)->u; + u->uv.len = s; + u->uv.metatable = NULL; + u->uv.env = e; + return u; } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lstring.h b/examples/ThirdPartyLibs/lua-5.2.3/src/lstring.h index 260e7f169..73f5dcef2 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lstring.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lstring.h @@ -11,36 +11,31 @@ #include "lobject.h" #include "lstate.h" +#define sizestring(s) (sizeof(union TString) + ((s)->len + 1) * sizeof(char)) -#define sizestring(s) (sizeof(union TString)+((s)->len+1)*sizeof(char)) +#define sizeudata(u) (sizeof(union Udata) + (u)->len) -#define sizeudata(u) (sizeof(union Udata)+(u)->len) - -#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ - (sizeof(s)/sizeof(char))-1)) - -#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) +#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ + (sizeof(s) / sizeof(char)) - 1)) +#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) /* ** test whether a string is a reserved word */ -#define isreserved(s) ((s)->tsv.tt == LUA_TSHRSTR && (s)->tsv.extra > 0) - +#define isreserved(s) ((s)->tsv.tt == LUA_TSHRSTR && (s)->tsv.extra > 0) /* ** equality for short strings, which are always internalized */ -#define eqshrstr(a,b) check_exp((a)->tsv.tt == LUA_TSHRSTR, (a) == (b)) - - -LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); -LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); -LUAI_FUNC int luaS_eqstr (TString *a, TString *b); -LUAI_FUNC void luaS_resize (lua_State *L, int newsize); -LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e); -LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); -LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); +#define eqshrstr(a, b) check_exp((a)->tsv.tt == LUA_TSHRSTR, (a) == (b)) +LUAI_FUNC unsigned int luaS_hash(const char *str, size_t l, unsigned int seed); +LUAI_FUNC int luaS_eqlngstr(TString *a, TString *b); +LUAI_FUNC int luaS_eqstr(TString *a, TString *b); +LUAI_FUNC void luaS_resize(lua_State *L, int newsize); +LUAI_FUNC Udata *luaS_newudata(lua_State *L, size_t s, Table *e); +LUAI_FUNC TString *luaS_newlstr(lua_State *L, const char *str, size_t l); +LUAI_FUNC TString *luaS_new(lua_State *L, const char *str); #endif diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lstrlib.c b/examples/ThirdPartyLibs/lua-5.2.3/src/lstrlib.c index 9261fd220..899719819 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lstrlib.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lstrlib.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #include #include #include @@ -19,767 +18,885 @@ #include "lauxlib.h" #include "lualib.h" - /* ** maximum number of captures that a pattern can do during ** pattern-matching. This limit is arbitrary. */ #if !defined(LUA_MAXCAPTURES) -#define LUA_MAXCAPTURES 32 +#define LUA_MAXCAPTURES 32 #endif - /* macro to `unsign' a character */ -#define uchar(c) ((unsigned char)(c)) +#define uchar(c) ((unsigned char)(c)) - - -static int str_len (lua_State *L) { - size_t l; - luaL_checklstring(L, 1, &l); - lua_pushinteger(L, (lua_Integer)l); - return 1; +static int str_len(lua_State *L) +{ + size_t l; + luaL_checklstring(L, 1, &l); + lua_pushinteger(L, (lua_Integer)l); + return 1; } - /* translate a relative string position: negative means back from end */ -static size_t posrelat (ptrdiff_t pos, size_t len) { - if (pos >= 0) return (size_t)pos; - else if (0u - (size_t)pos > len) return 0; - else return len - ((size_t)-pos) + 1; +static size_t posrelat(ptrdiff_t pos, size_t len) +{ + if (pos >= 0) + return (size_t)pos; + else if (0u - (size_t)pos > len) + return 0; + else + return len - ((size_t)-pos) + 1; } - -static int str_sub (lua_State *L) { - size_t l; - const char *s = luaL_checklstring(L, 1, &l); - size_t start = posrelat(luaL_checkinteger(L, 2), l); - size_t end = posrelat(luaL_optinteger(L, 3, -1), l); - if (start < 1) start = 1; - if (end > l) end = l; - if (start <= end) - lua_pushlstring(L, s + start - 1, end - start + 1); - else lua_pushliteral(L, ""); - return 1; +static int str_sub(lua_State *L) +{ + size_t l; + const char *s = luaL_checklstring(L, 1, &l); + size_t start = posrelat(luaL_checkinteger(L, 2), l); + size_t end = posrelat(luaL_optinteger(L, 3, -1), l); + if (start < 1) start = 1; + if (end > l) end = l; + if (start <= end) + lua_pushlstring(L, s + start - 1, end - start + 1); + else + lua_pushliteral(L, ""); + return 1; } - -static int str_reverse (lua_State *L) { - size_t l, i; - luaL_Buffer b; - const char *s = luaL_checklstring(L, 1, &l); - char *p = luaL_buffinitsize(L, &b, l); - for (i = 0; i < l; i++) - p[i] = s[l - i - 1]; - luaL_pushresultsize(&b, l); - return 1; +static int str_reverse(lua_State *L) +{ + size_t l, i; + luaL_Buffer b; + const char *s = luaL_checklstring(L, 1, &l); + char *p = luaL_buffinitsize(L, &b, l); + for (i = 0; i < l; i++) + p[i] = s[l - i - 1]; + luaL_pushresultsize(&b, l); + return 1; } - -static int str_lower (lua_State *L) { - size_t l; - size_t i; - luaL_Buffer b; - const char *s = luaL_checklstring(L, 1, &l); - char *p = luaL_buffinitsize(L, &b, l); - for (i=0; i> 1) +#define MAXSIZE ((~(size_t)0) >> 1) -static int str_rep (lua_State *L) { - size_t l, lsep; - const char *s = luaL_checklstring(L, 1, &l); - int n = luaL_checkint(L, 2); - const char *sep = luaL_optlstring(L, 3, "", &lsep); - if (n <= 0) lua_pushliteral(L, ""); - else if (l + lsep < l || l + lsep >= MAXSIZE / n) /* may overflow? */ - return luaL_error(L, "resulting string too large"); - else { - size_t totallen = n * l + (n - 1) * lsep; - luaL_Buffer b; - char *p = luaL_buffinitsize(L, &b, totallen); - while (n-- > 1) { /* first n-1 copies (followed by separator) */ - memcpy(p, s, l * sizeof(char)); p += l; - if (lsep > 0) { /* avoid empty 'memcpy' (may be expensive) */ - memcpy(p, sep, lsep * sizeof(char)); p += lsep; - } - } - memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */ - luaL_pushresultsize(&b, totallen); - } - return 1; +static int str_rep(lua_State *L) +{ + size_t l, lsep; + const char *s = luaL_checklstring(L, 1, &l); + int n = luaL_checkint(L, 2); + const char *sep = luaL_optlstring(L, 3, "", &lsep); + if (n <= 0) + lua_pushliteral(L, ""); + else if (l + lsep < l || l + lsep >= MAXSIZE / n) /* may overflow? */ + return luaL_error(L, "resulting string too large"); + else + { + size_t totallen = n * l + (n - 1) * lsep; + luaL_Buffer b; + char *p = luaL_buffinitsize(L, &b, totallen); + while (n-- > 1) + { /* first n-1 copies (followed by separator) */ + memcpy(p, s, l * sizeof(char)); + p += l; + if (lsep > 0) + { /* avoid empty 'memcpy' (may be expensive) */ + memcpy(p, sep, lsep * sizeof(char)); + p += lsep; + } + } + memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */ + luaL_pushresultsize(&b, totallen); + } + return 1; } - -static int str_byte (lua_State *L) { - size_t l; - const char *s = luaL_checklstring(L, 1, &l); - size_t posi = posrelat(luaL_optinteger(L, 2, 1), l); - size_t pose = posrelat(luaL_optinteger(L, 3, posi), l); - int n, i; - if (posi < 1) posi = 1; - if (pose > l) pose = l; - if (posi > pose) return 0; /* empty interval; return no values */ - n = (int)(pose - posi + 1); - if (posi + n <= pose) /* (size_t -> int) overflow? */ - return luaL_error(L, "string slice too long"); - luaL_checkstack(L, n, "string slice too long"); - for (i=0; i l) pose = l; + if (posi > pose) return 0; /* empty interval; return no values */ + n = (int)(pose - posi + 1); + if (posi + n <= pose) /* (size_t -> int) overflow? */ + return luaL_error(L, "string slice too long"); + luaL_checkstack(L, n, "string slice too long"); + for (i = 0; i < n; i++) + lua_pushinteger(L, uchar(s[posi + i - 1])); + return n; } - -static int str_char (lua_State *L) { - int n = lua_gettop(L); /* number of arguments */ - int i; - luaL_Buffer b; - char *p = luaL_buffinitsize(L, &b, n); - for (i=1; i<=n; i++) { - int c = luaL_checkint(L, i); - luaL_argcheck(L, uchar(c) == c, i, "value out of range"); - p[i - 1] = uchar(c); - } - luaL_pushresultsize(&b, n); - return 1; +static int str_char(lua_State *L) +{ + int n = lua_gettop(L); /* number of arguments */ + int i; + luaL_Buffer b; + char *p = luaL_buffinitsize(L, &b, n); + for (i = 1; i <= n; i++) + { + int c = luaL_checkint(L, i); + luaL_argcheck(L, uchar(c) == c, i, "value out of range"); + p[i - 1] = uchar(c); + } + luaL_pushresultsize(&b, n); + return 1; } - -static int writer (lua_State *L, const void* b, size_t size, void* B) { - (void)L; - luaL_addlstring((luaL_Buffer*) B, (const char *)b, size); - return 0; +static int writer(lua_State *L, const void *b, size_t size, void *B) +{ + (void)L; + luaL_addlstring((luaL_Buffer *)B, (const char *)b, size); + return 0; } - -static int str_dump (lua_State *L) { - luaL_Buffer b; - luaL_checktype(L, 1, LUA_TFUNCTION); - lua_settop(L, 1); - luaL_buffinit(L,&b); - if (lua_dump(L, writer, &b) != 0) - return luaL_error(L, "unable to dump given function"); - luaL_pushresult(&b); - return 1; +static int str_dump(lua_State *L) +{ + luaL_Buffer b; + luaL_checktype(L, 1, LUA_TFUNCTION); + lua_settop(L, 1); + luaL_buffinit(L, &b); + if (lua_dump(L, writer, &b) != 0) + return luaL_error(L, "unable to dump given function"); + luaL_pushresult(&b); + return 1; } - - /* ** {====================================================== ** PATTERN MATCHING ** ======================================================= */ +#define CAP_UNFINISHED (-1) +#define CAP_POSITION (-2) -#define CAP_UNFINISHED (-1) -#define CAP_POSITION (-2) - - -typedef struct MatchState { - int matchdepth; /* control for recursive depth (to avoid C stack overflow) */ - const char *src_init; /* init of source string */ - const char *src_end; /* end ('\0') of source string */ - const char *p_end; /* end ('\0') of pattern */ - lua_State *L; - int level; /* total number of captures (finished or unfinished) */ - struct { - const char *init; - ptrdiff_t len; - } capture[LUA_MAXCAPTURES]; +typedef struct MatchState +{ + int matchdepth; /* control for recursive depth (to avoid C stack overflow) */ + const char *src_init; /* init of source string */ + const char *src_end; /* end ('\0') of source string */ + const char *p_end; /* end ('\0') of pattern */ + lua_State *L; + int level; /* total number of captures (finished or unfinished) */ + struct + { + const char *init; + ptrdiff_t len; + } capture[LUA_MAXCAPTURES]; } MatchState; - /* recursive function */ -static const char *match (MatchState *ms, const char *s, const char *p); - +static const char *match(MatchState *ms, const char *s, const char *p); /* maximum recursion depth for 'match' */ #if !defined(MAXCCALLS) -#define MAXCCALLS 200 +#define MAXCCALLS 200 #endif +#define L_ESC '%' +#define SPECIALS "^$*+?.([%-" -#define L_ESC '%' -#define SPECIALS "^$*+?.([%-" - - -static int check_capture (MatchState *ms, int l) { - l -= '1'; - if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED) - return luaL_error(ms->L, "invalid capture index %%%d", l + 1); - return l; +static int check_capture(MatchState *ms, int l) +{ + l -= '1'; + if (l < 0 || l >= ms->level || ms->capture[l].len == CAP_UNFINISHED) + return luaL_error(ms->L, "invalid capture index %%%d", l + 1); + return l; } - -static int capture_to_close (MatchState *ms) { - int level = ms->level; - for (level--; level>=0; level--) - if (ms->capture[level].len == CAP_UNFINISHED) return level; - return luaL_error(ms->L, "invalid pattern capture"); +static int capture_to_close(MatchState *ms) +{ + int level = ms->level; + for (level--; level >= 0; level--) + if (ms->capture[level].len == CAP_UNFINISHED) return level; + return luaL_error(ms->L, "invalid pattern capture"); } - -static const char *classend (MatchState *ms, const char *p) { - switch (*p++) { - case L_ESC: { - if (p == ms->p_end) - luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); - return p+1; - } - case '[': { - if (*p == '^') p++; - do { /* look for a `]' */ - if (p == ms->p_end) - luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); - if (*(p++) == L_ESC && p < ms->p_end) - p++; /* skip escapes (e.g. `%]') */ - } while (*p != ']'); - return p+1; - } - default: { - return p; - } - } +static const char *classend(MatchState *ms, const char *p) +{ + switch (*p++) + { + case L_ESC: + { + if (p == ms->p_end) + luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")"); + return p + 1; + } + case '[': + { + if (*p == '^') p++; + do + { /* look for a `]' */ + if (p == ms->p_end) + luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")"); + if (*(p++) == L_ESC && p < ms->p_end) + p++; /* skip escapes (e.g. `%]') */ + } while (*p != ']'); + return p + 1; + } + default: + { + return p; + } + } } - -static int match_class (int c, int cl) { - int res; - switch (tolower(cl)) { - case 'a' : res = isalpha(c); break; - case 'c' : res = iscntrl(c); break; - case 'd' : res = isdigit(c); break; - case 'g' : res = isgraph(c); break; - case 'l' : res = islower(c); break; - case 'p' : res = ispunct(c); break; - case 's' : res = isspace(c); break; - case 'u' : res = isupper(c); break; - case 'w' : res = isalnum(c); break; - case 'x' : res = isxdigit(c); break; - case 'z' : res = (c == 0); break; /* deprecated option */ - default: return (cl == c); - } - return (islower(cl) ? res : !res); +static int match_class(int c, int cl) +{ + int res; + switch (tolower(cl)) + { + case 'a': + res = isalpha(c); + break; + case 'c': + res = iscntrl(c); + break; + case 'd': + res = isdigit(c); + break; + case 'g': + res = isgraph(c); + break; + case 'l': + res = islower(c); + break; + case 'p': + res = ispunct(c); + break; + case 's': + res = isspace(c); + break; + case 'u': + res = isupper(c); + break; + case 'w': + res = isalnum(c); + break; + case 'x': + res = isxdigit(c); + break; + case 'z': + res = (c == 0); + break; /* deprecated option */ + default: + return (cl == c); + } + return (islower(cl) ? res : !res); } - -static int matchbracketclass (int c, const char *p, const char *ec) { - int sig = 1; - if (*(p+1) == '^') { - sig = 0; - p++; /* skip the `^' */ - } - while (++p < ec) { - if (*p == L_ESC) { - p++; - if (match_class(c, uchar(*p))) - return sig; - } - else if ((*(p+1) == '-') && (p+2 < ec)) { - p+=2; - if (uchar(*(p-2)) <= c && c <= uchar(*p)) - return sig; - } - else if (uchar(*p) == c) return sig; - } - return !sig; +static int matchbracketclass(int c, const char *p, const char *ec) +{ + int sig = 1; + if (*(p + 1) == '^') + { + sig = 0; + p++; /* skip the `^' */ + } + while (++p < ec) + { + if (*p == L_ESC) + { + p++; + if (match_class(c, uchar(*p))) + return sig; + } + else if ((*(p + 1) == '-') && (p + 2 < ec)) + { + p += 2; + if (uchar(*(p - 2)) <= c && c <= uchar(*p)) + return sig; + } + else if (uchar(*p) == c) + return sig; + } + return !sig; } - -static int singlematch (MatchState *ms, const char *s, const char *p, - const char *ep) { - if (s >= ms->src_end) - return 0; - else { - int c = uchar(*s); - switch (*p) { - case '.': return 1; /* matches any char */ - case L_ESC: return match_class(c, uchar(*(p+1))); - case '[': return matchbracketclass(c, p, ep-1); - default: return (uchar(*p) == c); - } - } +static int singlematch(MatchState *ms, const char *s, const char *p, + const char *ep) +{ + if (s >= ms->src_end) + return 0; + else + { + int c = uchar(*s); + switch (*p) + { + case '.': + return 1; /* matches any char */ + case L_ESC: + return match_class(c, uchar(*(p + 1))); + case '[': + return matchbracketclass(c, p, ep - 1); + default: + return (uchar(*p) == c); + } + } } - -static const char *matchbalance (MatchState *ms, const char *s, - const char *p) { - if (p >= ms->p_end - 1) - luaL_error(ms->L, "malformed pattern " - "(missing arguments to " LUA_QL("%%b") ")"); - if (*s != *p) return NULL; - else { - int b = *p; - int e = *(p+1); - int cont = 1; - while (++s < ms->src_end) { - if (*s == e) { - if (--cont == 0) return s+1; - } - else if (*s == b) cont++; - } - } - return NULL; /* string ends out of balance */ +static const char *matchbalance(MatchState *ms, const char *s, + const char *p) +{ + if (p >= ms->p_end - 1) + luaL_error(ms->L, + "malformed pattern " + "(missing arguments to " LUA_QL("%%b") ")"); + if (*s != *p) + return NULL; + else + { + int b = *p; + int e = *(p + 1); + int cont = 1; + while (++s < ms->src_end) + { + if (*s == e) + { + if (--cont == 0) return s + 1; + } + else if (*s == b) + cont++; + } + } + return NULL; /* string ends out of balance */ } - -static const char *max_expand (MatchState *ms, const char *s, - const char *p, const char *ep) { - ptrdiff_t i = 0; /* counts maximum expand for item */ - while (singlematch(ms, s + i, p, ep)) - i++; - /* keeps trying to match with the maximum repetitions */ - while (i>=0) { - const char *res = match(ms, (s+i), ep+1); - if (res) return res; - i--; /* else didn't match; reduce 1 repetition to try again */ - } - return NULL; +static const char *max_expand(MatchState *ms, const char *s, + const char *p, const char *ep) +{ + ptrdiff_t i = 0; /* counts maximum expand for item */ + while (singlematch(ms, s + i, p, ep)) + i++; + /* keeps trying to match with the maximum repetitions */ + while (i >= 0) + { + const char *res = match(ms, (s + i), ep + 1); + if (res) return res; + i--; /* else didn't match; reduce 1 repetition to try again */ + } + return NULL; } - -static const char *min_expand (MatchState *ms, const char *s, - const char *p, const char *ep) { - for (;;) { - const char *res = match(ms, s, ep+1); - if (res != NULL) - return res; - else if (singlematch(ms, s, p, ep)) - s++; /* try with one more repetition */ - else return NULL; - } +static const char *min_expand(MatchState *ms, const char *s, + const char *p, const char *ep) +{ + for (;;) + { + const char *res = match(ms, s, ep + 1); + if (res != NULL) + return res; + else if (singlematch(ms, s, p, ep)) + s++; /* try with one more repetition */ + else + return NULL; + } } - -static const char *start_capture (MatchState *ms, const char *s, - const char *p, int what) { - const char *res; - int level = ms->level; - if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); - ms->capture[level].init = s; - ms->capture[level].len = what; - ms->level = level+1; - if ((res=match(ms, s, p)) == NULL) /* match failed? */ - ms->level--; /* undo capture */ - return res; +static const char *start_capture(MatchState *ms, const char *s, + const char *p, int what) +{ + const char *res; + int level = ms->level; + if (level >= LUA_MAXCAPTURES) luaL_error(ms->L, "too many captures"); + ms->capture[level].init = s; + ms->capture[level].len = what; + ms->level = level + 1; + if ((res = match(ms, s, p)) == NULL) /* match failed? */ + ms->level--; /* undo capture */ + return res; } - -static const char *end_capture (MatchState *ms, const char *s, - const char *p) { - int l = capture_to_close(ms); - const char *res; - ms->capture[l].len = s - ms->capture[l].init; /* close capture */ - if ((res = match(ms, s, p)) == NULL) /* match failed? */ - ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ - return res; +static const char *end_capture(MatchState *ms, const char *s, + const char *p) +{ + int l = capture_to_close(ms); + const char *res; + ms->capture[l].len = s - ms->capture[l].init; /* close capture */ + if ((res = match(ms, s, p)) == NULL) /* match failed? */ + ms->capture[l].len = CAP_UNFINISHED; /* undo capture */ + return res; } - -static const char *match_capture (MatchState *ms, const char *s, int l) { - size_t len; - l = check_capture(ms, l); - len = ms->capture[l].len; - if ((size_t)(ms->src_end-s) >= len && - memcmp(ms->capture[l].init, s, len) == 0) - return s+len; - else return NULL; +static const char *match_capture(MatchState *ms, const char *s, int l) +{ + size_t len; + l = check_capture(ms, l); + len = ms->capture[l].len; + if ((size_t)(ms->src_end - s) >= len && + memcmp(ms->capture[l].init, s, len) == 0) + return s + len; + else + return NULL; } - -static const char *match (MatchState *ms, const char *s, const char *p) { - if (ms->matchdepth-- == 0) - luaL_error(ms->L, "pattern too complex"); - init: /* using goto's to optimize tail recursion */ - if (p != ms->p_end) { /* end of pattern? */ - switch (*p) { - case '(': { /* start capture */ - if (*(p + 1) == ')') /* position capture? */ - s = start_capture(ms, s, p + 2, CAP_POSITION); - else - s = start_capture(ms, s, p + 1, CAP_UNFINISHED); - break; - } - case ')': { /* end capture */ - s = end_capture(ms, s, p + 1); - break; - } - case '$': { - if ((p + 1) != ms->p_end) /* is the `$' the last char in pattern? */ - goto dflt; /* no; go to default */ - s = (s == ms->src_end) ? s : NULL; /* check end of string */ - break; - } - case L_ESC: { /* escaped sequences not in the format class[*+?-]? */ - switch (*(p + 1)) { - case 'b': { /* balanced string? */ - s = matchbalance(ms, s, p + 2); - if (s != NULL) { - p += 4; goto init; /* return match(ms, s, p + 4); */ - } /* else fail (s == NULL) */ - break; - } - case 'f': { /* frontier? */ - const char *ep; char previous; - p += 2; - if (*p != '[') - luaL_error(ms->L, "missing " LUA_QL("[") " after " - LUA_QL("%%f") " in pattern"); - ep = classend(ms, p); /* points to what is next */ - previous = (s == ms->src_init) ? '\0' : *(s - 1); - if (!matchbracketclass(uchar(previous), p, ep - 1) && - matchbracketclass(uchar(*s), p, ep - 1)) { - p = ep; goto init; /* return match(ms, s, ep); */ - } - s = NULL; /* match failed */ - break; - } - case '0': case '1': case '2': case '3': - case '4': case '5': case '6': case '7': - case '8': case '9': { /* capture results (%0-%9)? */ - s = match_capture(ms, s, uchar(*(p + 1))); - if (s != NULL) { - p += 2; goto init; /* return match(ms, s, p + 2) */ - } - break; - } - default: goto dflt; - } - break; - } - default: dflt: { /* pattern class plus optional suffix */ - const char *ep = classend(ms, p); /* points to optional suffix */ - /* does not match at least once? */ - if (!singlematch(ms, s, p, ep)) { - if (*ep == '*' || *ep == '?' || *ep == '-') { /* accept empty? */ - p = ep + 1; goto init; /* return match(ms, s, ep + 1); */ - } - else /* '+' or no suffix */ - s = NULL; /* fail */ - } - else { /* matched once */ - switch (*ep) { /* handle optional suffix */ - case '?': { /* optional */ - const char *res; - if ((res = match(ms, s + 1, ep + 1)) != NULL) - s = res; - else { - p = ep + 1; goto init; /* else return match(ms, s, ep + 1); */ - } - break; - } - case '+': /* 1 or more repetitions */ - s++; /* 1 match already done */ - /* go through */ - case '*': /* 0 or more repetitions */ - s = max_expand(ms, s, p, ep); - break; - case '-': /* 0 or more repetitions (minimum) */ - s = min_expand(ms, s, p, ep); - break; - default: /* no suffix */ - s++; p = ep; goto init; /* return match(ms, s + 1, ep); */ - } - } - break; - } - } - } - ms->matchdepth++; - return s; +static const char *match(MatchState *ms, const char *s, const char *p) +{ + if (ms->matchdepth-- == 0) + luaL_error(ms->L, "pattern too complex"); +init: /* using goto's to optimize tail recursion */ + if (p != ms->p_end) + { /* end of pattern? */ + switch (*p) + { + case '(': + { /* start capture */ + if (*(p + 1) == ')') /* position capture? */ + s = start_capture(ms, s, p + 2, CAP_POSITION); + else + s = start_capture(ms, s, p + 1, CAP_UNFINISHED); + break; + } + case ')': + { /* end capture */ + s = end_capture(ms, s, p + 1); + break; + } + case '$': + { + if ((p + 1) != ms->p_end) /* is the `$' the last char in pattern? */ + goto dflt; /* no; go to default */ + s = (s == ms->src_end) ? s : NULL; /* check end of string */ + break; + } + case L_ESC: + { /* escaped sequences not in the format class[*+?-]? */ + switch (*(p + 1)) + { + case 'b': + { /* balanced string? */ + s = matchbalance(ms, s, p + 2); + if (s != NULL) + { + p += 4; + goto init; /* return match(ms, s, p + 4); */ + } /* else fail (s == NULL) */ + break; + } + case 'f': + { /* frontier? */ + const char *ep; + char previous; + p += 2; + if (*p != '[') + luaL_error(ms->L, "missing " LUA_QL("[") " after " LUA_QL("%%f") " in pattern"); + ep = classend(ms, p); /* points to what is next */ + previous = (s == ms->src_init) ? '\0' : *(s - 1); + if (!matchbracketclass(uchar(previous), p, ep - 1) && + matchbracketclass(uchar(*s), p, ep - 1)) + { + p = ep; + goto init; /* return match(ms, s, ep); */ + } + s = NULL; /* match failed */ + break; + } + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + { /* capture results (%0-%9)? */ + s = match_capture(ms, s, uchar(*(p + 1))); + if (s != NULL) + { + p += 2; + goto init; /* return match(ms, s, p + 2) */ + } + break; + } + default: + goto dflt; + } + break; + } + default: + dflt: + { /* pattern class plus optional suffix */ + const char *ep = classend(ms, p); /* points to optional suffix */ + /* does not match at least once? */ + if (!singlematch(ms, s, p, ep)) + { + if (*ep == '*' || *ep == '?' || *ep == '-') + { /* accept empty? */ + p = ep + 1; + goto init; /* return match(ms, s, ep + 1); */ + } + else /* '+' or no suffix */ + s = NULL; /* fail */ + } + else + { /* matched once */ + switch (*ep) + { /* handle optional suffix */ + case '?': + { /* optional */ + const char *res; + if ((res = match(ms, s + 1, ep + 1)) != NULL) + s = res; + else + { + p = ep + 1; + goto init; /* else return match(ms, s, ep + 1); */ + } + break; + } + case '+': /* 1 or more repetitions */ + s++; /* 1 match already done */ + /* go through */ + case '*': /* 0 or more repetitions */ + s = max_expand(ms, s, p, ep); + break; + case '-': /* 0 or more repetitions (minimum) */ + s = min_expand(ms, s, p, ep); + break; + default: /* no suffix */ + s++; + p = ep; + goto init; /* return match(ms, s + 1, ep); */ + } + } + break; + } + } + } + ms->matchdepth++; + return s; } - - -static const char *lmemfind (const char *s1, size_t l1, - const char *s2, size_t l2) { - if (l2 == 0) return s1; /* empty strings are everywhere */ - else if (l2 > l1) return NULL; /* avoids a negative `l1' */ - else { - const char *init; /* to search for a `*s2' inside `s1' */ - l2--; /* 1st char will be checked by `memchr' */ - l1 = l1-l2; /* `s2' cannot be found after that */ - while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) { - init++; /* 1st char is already checked */ - if (memcmp(init, s2+1, l2) == 0) - return init-1; - else { /* correct `l1' and `s1' to try again */ - l1 -= init-s1; - s1 = init; - } - } - return NULL; /* not found */ - } +static const char *lmemfind(const char *s1, size_t l1, + const char *s2, size_t l2) +{ + if (l2 == 0) + return s1; /* empty strings are everywhere */ + else if (l2 > l1) + return NULL; /* avoids a negative `l1' */ + else + { + const char *init; /* to search for a `*s2' inside `s1' */ + l2--; /* 1st char will be checked by `memchr' */ + l1 = l1 - l2; /* `s2' cannot be found after that */ + while (l1 > 0 && (init = (const char *)memchr(s1, *s2, l1)) != NULL) + { + init++; /* 1st char is already checked */ + if (memcmp(init, s2 + 1, l2) == 0) + return init - 1; + else + { /* correct `l1' and `s1' to try again */ + l1 -= init - s1; + s1 = init; + } + } + return NULL; /* not found */ + } } - -static void push_onecapture (MatchState *ms, int i, const char *s, - const char *e) { - if (i >= ms->level) { - if (i == 0) /* ms->level == 0, too */ - lua_pushlstring(ms->L, s, e - s); /* add whole match */ - else - luaL_error(ms->L, "invalid capture index"); - } - else { - ptrdiff_t l = ms->capture[i].len; - if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); - if (l == CAP_POSITION) - lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1); - else - lua_pushlstring(ms->L, ms->capture[i].init, l); - } +static void push_onecapture(MatchState *ms, int i, const char *s, + const char *e) +{ + if (i >= ms->level) + { + if (i == 0) /* ms->level == 0, too */ + lua_pushlstring(ms->L, s, e - s); /* add whole match */ + else + luaL_error(ms->L, "invalid capture index"); + } + else + { + ptrdiff_t l = ms->capture[i].len; + if (l == CAP_UNFINISHED) luaL_error(ms->L, "unfinished capture"); + if (l == CAP_POSITION) + lua_pushinteger(ms->L, ms->capture[i].init - ms->src_init + 1); + else + lua_pushlstring(ms->L, ms->capture[i].init, l); + } } - -static int push_captures (MatchState *ms, const char *s, const char *e) { - int i; - int nlevels = (ms->level == 0 && s) ? 1 : ms->level; - luaL_checkstack(ms->L, nlevels, "too many captures"); - for (i = 0; i < nlevels; i++) - push_onecapture(ms, i, s, e); - return nlevels; /* number of strings pushed */ +static int push_captures(MatchState *ms, const char *s, const char *e) +{ + int i; + int nlevels = (ms->level == 0 && s) ? 1 : ms->level; + luaL_checkstack(ms->L, nlevels, "too many captures"); + for (i = 0; i < nlevels; i++) + push_onecapture(ms, i, s, e); + return nlevels; /* number of strings pushed */ } - /* check whether pattern has no special characters */ -static int nospecials (const char *p, size_t l) { - size_t upto = 0; - do { - if (strpbrk(p + upto, SPECIALS)) - return 0; /* pattern has a special character */ - upto += strlen(p + upto) + 1; /* may have more after \0 */ - } while (upto <= l); - return 1; /* no special chars found */ +static int nospecials(const char *p, size_t l) +{ + size_t upto = 0; + do + { + if (strpbrk(p + upto, SPECIALS)) + return 0; /* pattern has a special character */ + upto += strlen(p + upto) + 1; /* may have more after \0 */ + } while (upto <= l); + return 1; /* no special chars found */ } - -static int str_find_aux (lua_State *L, int find) { - size_t ls, lp; - const char *s = luaL_checklstring(L, 1, &ls); - const char *p = luaL_checklstring(L, 2, &lp); - size_t init = posrelat(luaL_optinteger(L, 3, 1), ls); - if (init < 1) init = 1; - else if (init > ls + 1) { /* start after string's end? */ - lua_pushnil(L); /* cannot find anything */ - return 1; - } - /* explicit request or no special characters? */ - if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) { - /* do a plain search */ - const char *s2 = lmemfind(s + init - 1, ls - init + 1, p, lp); - if (s2) { - lua_pushinteger(L, s2 - s + 1); - lua_pushinteger(L, s2 - s + lp); - return 2; - } - } - else { - MatchState ms; - const char *s1 = s + init - 1; - int anchor = (*p == '^'); - if (anchor) { - p++; lp--; /* skip anchor character */ - } - ms.L = L; - ms.matchdepth = MAXCCALLS; - ms.src_init = s; - ms.src_end = s + ls; - ms.p_end = p + lp; - do { - const char *res; - ms.level = 0; - lua_assert(ms.matchdepth == MAXCCALLS); - if ((res=match(&ms, s1, p)) != NULL) { - if (find) { - lua_pushinteger(L, s1 - s + 1); /* start */ - lua_pushinteger(L, res - s); /* end */ - return push_captures(&ms, NULL, 0) + 2; - } - else - return push_captures(&ms, s1, res); - } - } while (s1++ < ms.src_end && !anchor); - } - lua_pushnil(L); /* not found */ - return 1; +static int str_find_aux(lua_State *L, int find) +{ + size_t ls, lp; + const char *s = luaL_checklstring(L, 1, &ls); + const char *p = luaL_checklstring(L, 2, &lp); + size_t init = posrelat(luaL_optinteger(L, 3, 1), ls); + if (init < 1) + init = 1; + else if (init > ls + 1) + { /* start after string's end? */ + lua_pushnil(L); /* cannot find anything */ + return 1; + } + /* explicit request or no special characters? */ + if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) + { + /* do a plain search */ + const char *s2 = lmemfind(s + init - 1, ls - init + 1, p, lp); + if (s2) + { + lua_pushinteger(L, s2 - s + 1); + lua_pushinteger(L, s2 - s + lp); + return 2; + } + } + else + { + MatchState ms; + const char *s1 = s + init - 1; + int anchor = (*p == '^'); + if (anchor) + { + p++; + lp--; /* skip anchor character */ + } + ms.L = L; + ms.matchdepth = MAXCCALLS; + ms.src_init = s; + ms.src_end = s + ls; + ms.p_end = p + lp; + do + { + const char *res; + ms.level = 0; + lua_assert(ms.matchdepth == MAXCCALLS); + if ((res = match(&ms, s1, p)) != NULL) + { + if (find) + { + lua_pushinteger(L, s1 - s + 1); /* start */ + lua_pushinteger(L, res - s); /* end */ + return push_captures(&ms, NULL, 0) + 2; + } + else + return push_captures(&ms, s1, res); + } + } while (s1++ < ms.src_end && !anchor); + } + lua_pushnil(L); /* not found */ + return 1; } - -static int str_find (lua_State *L) { - return str_find_aux(L, 1); +static int str_find(lua_State *L) +{ + return str_find_aux(L, 1); } - -static int str_match (lua_State *L) { - return str_find_aux(L, 0); +static int str_match(lua_State *L) +{ + return str_find_aux(L, 0); } - -static int gmatch_aux (lua_State *L) { - MatchState ms; - size_t ls, lp; - const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); - const char *p = lua_tolstring(L, lua_upvalueindex(2), &lp); - const char *src; - ms.L = L; - ms.matchdepth = MAXCCALLS; - ms.src_init = s; - ms.src_end = s+ls; - ms.p_end = p + lp; - for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); - src <= ms.src_end; - src++) { - const char *e; - ms.level = 0; - lua_assert(ms.matchdepth == MAXCCALLS); - if ((e = match(&ms, src, p)) != NULL) { - lua_Integer newstart = e-s; - if (e == src) newstart++; /* empty match? go at least one position */ - lua_pushinteger(L, newstart); - lua_replace(L, lua_upvalueindex(3)); - return push_captures(&ms, src, e); - } - } - return 0; /* not found */ +static int gmatch_aux(lua_State *L) +{ + MatchState ms; + size_t ls, lp; + const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls); + const char *p = lua_tolstring(L, lua_upvalueindex(2), &lp); + const char *src; + ms.L = L; + ms.matchdepth = MAXCCALLS; + ms.src_init = s; + ms.src_end = s + ls; + ms.p_end = p + lp; + for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3)); + src <= ms.src_end; + src++) + { + const char *e; + ms.level = 0; + lua_assert(ms.matchdepth == MAXCCALLS); + if ((e = match(&ms, src, p)) != NULL) + { + lua_Integer newstart = e - s; + if (e == src) newstart++; /* empty match? go at least one position */ + lua_pushinteger(L, newstart); + lua_replace(L, lua_upvalueindex(3)); + return push_captures(&ms, src, e); + } + } + return 0; /* not found */ } - -static int gmatch (lua_State *L) { - luaL_checkstring(L, 1); - luaL_checkstring(L, 2); - lua_settop(L, 2); - lua_pushinteger(L, 0); - lua_pushcclosure(L, gmatch_aux, 3); - return 1; +static int gmatch(lua_State *L) +{ + luaL_checkstring(L, 1); + luaL_checkstring(L, 2); + lua_settop(L, 2); + lua_pushinteger(L, 0); + lua_pushcclosure(L, gmatch_aux, 3); + return 1; } - -static void add_s (MatchState *ms, luaL_Buffer *b, const char *s, - const char *e) { - size_t l, i; - const char *news = lua_tolstring(ms->L, 3, &l); - for (i = 0; i < l; i++) { - if (news[i] != L_ESC) - luaL_addchar(b, news[i]); - else { - i++; /* skip ESC */ - if (!isdigit(uchar(news[i]))) { - if (news[i] != L_ESC) - luaL_error(ms->L, "invalid use of " LUA_QL("%c") - " in replacement string", L_ESC); - luaL_addchar(b, news[i]); - } - else if (news[i] == '0') - luaL_addlstring(b, s, e - s); - else { - push_onecapture(ms, news[i] - '1', s, e); - luaL_addvalue(b); /* add capture to accumulated result */ - } - } - } +static void add_s(MatchState *ms, luaL_Buffer *b, const char *s, + const char *e) +{ + size_t l, i; + const char *news = lua_tolstring(ms->L, 3, &l); + for (i = 0; i < l; i++) + { + if (news[i] != L_ESC) + luaL_addchar(b, news[i]); + else + { + i++; /* skip ESC */ + if (!isdigit(uchar(news[i]))) + { + if (news[i] != L_ESC) + luaL_error(ms->L, "invalid use of " LUA_QL("%c") " in replacement string", L_ESC); + luaL_addchar(b, news[i]); + } + else if (news[i] == '0') + luaL_addlstring(b, s, e - s); + else + { + push_onecapture(ms, news[i] - '1', s, e); + luaL_addvalue(b); /* add capture to accumulated result */ + } + } + } } - -static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, - const char *e, int tr) { - lua_State *L = ms->L; - switch (tr) { - case LUA_TFUNCTION: { - int n; - lua_pushvalue(L, 3); - n = push_captures(ms, s, e); - lua_call(L, n, 1); - break; - } - case LUA_TTABLE: { - push_onecapture(ms, 0, s, e); - lua_gettable(L, 3); - break; - } - default: { /* LUA_TNUMBER or LUA_TSTRING */ - add_s(ms, b, s, e); - return; - } - } - if (!lua_toboolean(L, -1)) { /* nil or false? */ - lua_pop(L, 1); - lua_pushlstring(L, s, e - s); /* keep original text */ - } - else if (!lua_isstring(L, -1)) - luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); - luaL_addvalue(b); /* add result to accumulator */ +static void add_value(MatchState *ms, luaL_Buffer *b, const char *s, + const char *e, int tr) +{ + lua_State *L = ms->L; + switch (tr) + { + case LUA_TFUNCTION: + { + int n; + lua_pushvalue(L, 3); + n = push_captures(ms, s, e); + lua_call(L, n, 1); + break; + } + case LUA_TTABLE: + { + push_onecapture(ms, 0, s, e); + lua_gettable(L, 3); + break; + } + default: + { /* LUA_TNUMBER or LUA_TSTRING */ + add_s(ms, b, s, e); + return; + } + } + if (!lua_toboolean(L, -1)) + { /* nil or false? */ + lua_pop(L, 1); + lua_pushlstring(L, s, e - s); /* keep original text */ + } + else if (!lua_isstring(L, -1)) + luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); + luaL_addvalue(b); /* add result to accumulator */ } - -static int str_gsub (lua_State *L) { - size_t srcl, lp; - const char *src = luaL_checklstring(L, 1, &srcl); - const char *p = luaL_checklstring(L, 2, &lp); - int tr = lua_type(L, 3); - size_t max_s = luaL_optinteger(L, 4, srcl+1); - int anchor = (*p == '^'); - size_t n = 0; - MatchState ms; - luaL_Buffer b; - luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || - tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, - "string/function/table expected"); - luaL_buffinit(L, &b); - if (anchor) { - p++; lp--; /* skip anchor character */ - } - ms.L = L; - ms.matchdepth = MAXCCALLS; - ms.src_init = src; - ms.src_end = src+srcl; - ms.p_end = p + lp; - while (n < max_s) { - const char *e; - ms.level = 0; - lua_assert(ms.matchdepth == MAXCCALLS); - e = match(&ms, src, p); - if (e) { - n++; - add_value(&ms, &b, src, e, tr); - } - if (e && e>src) /* non empty match? */ - src = e; /* skip it */ - else if (src < ms.src_end) - luaL_addchar(&b, *src++); - else break; - if (anchor) break; - } - luaL_addlstring(&b, src, ms.src_end-src); - luaL_pushresult(&b); - lua_pushinteger(L, n); /* number of substitutions */ - return 2; +static int str_gsub(lua_State *L) +{ + size_t srcl, lp; + const char *src = luaL_checklstring(L, 1, &srcl); + const char *p = luaL_checklstring(L, 2, &lp); + int tr = lua_type(L, 3); + size_t max_s = luaL_optinteger(L, 4, srcl + 1); + int anchor = (*p == '^'); + size_t n = 0; + MatchState ms; + luaL_Buffer b; + luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING || tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3, + "string/function/table expected"); + luaL_buffinit(L, &b); + if (anchor) + { + p++; + lp--; /* skip anchor character */ + } + ms.L = L; + ms.matchdepth = MAXCCALLS; + ms.src_init = src; + ms.src_end = src + srcl; + ms.p_end = p + lp; + while (n < max_s) + { + const char *e; + ms.level = 0; + lua_assert(ms.matchdepth == MAXCCALLS); + e = match(&ms, src, p); + if (e) + { + n++; + add_value(&ms, &b, src, e, tr); + } + if (e && e > src) /* non empty match? */ + src = e; /* skip it */ + else if (src < ms.src_end) + luaL_addchar(&b, *src++); + else + break; + if (anchor) break; + } + luaL_addlstring(&b, src, ms.src_end - src); + luaL_pushresult(&b); + lua_pushinteger(L, n); /* number of substitutions */ + return 2; } /* }====================================================== */ - - /* ** {====================================================== ** STRING FORMAT @@ -791,20 +908,19 @@ static int str_gsub (lua_State *L) { ** 'string.format'; LUA_INTFRM_T is the integer type corresponding to ** the previous length */ -#if !defined(LUA_INTFRMLEN) /* { */ +#if !defined(LUA_INTFRMLEN) /* { */ #if defined(LUA_USE_LONGLONG) -#define LUA_INTFRMLEN "ll" -#define LUA_INTFRM_T long long +#define LUA_INTFRMLEN "ll" +#define LUA_INTFRM_T long long #else -#define LUA_INTFRMLEN "l" -#define LUA_INTFRM_T long +#define LUA_INTFRMLEN "l" +#define LUA_INTFRM_T long #endif -#endif /* } */ - +#endif /* } */ /* ** LUA_FLTFRMLEN is the length modifier for float conversions in @@ -813,207 +929,227 @@ static int str_gsub (lua_State *L) { */ #if !defined(LUA_FLTFRMLEN) -#define LUA_FLTFRMLEN "" -#define LUA_FLTFRM_T double +#define LUA_FLTFRMLEN "" +#define LUA_FLTFRM_T double #endif - /* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */ -#define MAX_ITEM 512 +#define MAX_ITEM 512 /* valid flags in a format specification */ -#define FLAGS "-+ #0" +#define FLAGS "-+ #0" /* ** maximum size of each format specification (such as '%-099.99d') ** (+10 accounts for %99.99x plus margin of error) */ -#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10) +#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10) - -static void addquoted (lua_State *L, luaL_Buffer *b, int arg) { - size_t l; - const char *s = luaL_checklstring(L, arg, &l); - luaL_addchar(b, '"'); - while (l--) { - if (*s == '"' || *s == '\\' || *s == '\n') { - luaL_addchar(b, '\\'); - luaL_addchar(b, *s); - } - else if (*s == '\0' || iscntrl(uchar(*s))) { - char buff[10]; - if (!isdigit(uchar(*(s+1)))) - sprintf(buff, "\\%d", (int)uchar(*s)); - else - sprintf(buff, "\\%03d", (int)uchar(*s)); - luaL_addstring(b, buff); - } - else - luaL_addchar(b, *s); - s++; - } - luaL_addchar(b, '"'); +static void addquoted(lua_State *L, luaL_Buffer *b, int arg) +{ + size_t l; + const char *s = luaL_checklstring(L, arg, &l); + luaL_addchar(b, '"'); + while (l--) + { + if (*s == '"' || *s == '\\' || *s == '\n') + { + luaL_addchar(b, '\\'); + luaL_addchar(b, *s); + } + else if (*s == '\0' || iscntrl(uchar(*s))) + { + char buff[10]; + if (!isdigit(uchar(*(s + 1)))) + sprintf(buff, "\\%d", (int)uchar(*s)); + else + sprintf(buff, "\\%03d", (int)uchar(*s)); + luaL_addstring(b, buff); + } + else + luaL_addchar(b, *s); + s++; + } + luaL_addchar(b, '"'); } -static const char *scanformat (lua_State *L, const char *strfrmt, char *form) { - const char *p = strfrmt; - while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ - if ((size_t)(p - strfrmt) >= sizeof(FLAGS)/sizeof(char)) - luaL_error(L, "invalid format (repeated flags)"); - if (isdigit(uchar(*p))) p++; /* skip width */ - if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ - if (*p == '.') { - p++; - if (isdigit(uchar(*p))) p++; /* skip precision */ - if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ - } - if (isdigit(uchar(*p))) - luaL_error(L, "invalid format (width or precision too long)"); - *(form++) = '%'; - memcpy(form, strfrmt, (p - strfrmt + 1) * sizeof(char)); - form += p - strfrmt + 1; - *form = '\0'; - return p; +static const char *scanformat(lua_State *L, const char *strfrmt, char *form) +{ + const char *p = strfrmt; + while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */ + if ((size_t)(p - strfrmt) >= sizeof(FLAGS) / sizeof(char)) + luaL_error(L, "invalid format (repeated flags)"); + if (isdigit(uchar(*p))) p++; /* skip width */ + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ + if (*p == '.') + { + p++; + if (isdigit(uchar(*p))) p++; /* skip precision */ + if (isdigit(uchar(*p))) p++; /* (2 digits at most) */ + } + if (isdigit(uchar(*p))) + luaL_error(L, "invalid format (width or precision too long)"); + *(form++) = '%'; + memcpy(form, strfrmt, (p - strfrmt + 1) * sizeof(char)); + form += p - strfrmt + 1; + *form = '\0'; + return p; } - /* ** add length modifier into formats */ -static void addlenmod (char *form, const char *lenmod) { - size_t l = strlen(form); - size_t lm = strlen(lenmod); - char spec = form[l - 1]; - strcpy(form + l - 1, lenmod); - form[l + lm - 1] = spec; - form[l + lm] = '\0'; +static void addlenmod(char *form, const char *lenmod) +{ + size_t l = strlen(form); + size_t lm = strlen(lenmod); + char spec = form[l - 1]; + strcpy(form + l - 1, lenmod); + form[l + lm - 1] = spec; + form[l + lm] = '\0'; } - -static int str_format (lua_State *L) { - int top = lua_gettop(L); - int arg = 1; - size_t sfl; - const char *strfrmt = luaL_checklstring(L, arg, &sfl); - const char *strfrmt_end = strfrmt+sfl; - luaL_Buffer b; - luaL_buffinit(L, &b); - while (strfrmt < strfrmt_end) { - if (*strfrmt != L_ESC) - luaL_addchar(&b, *strfrmt++); - else if (*++strfrmt == L_ESC) - luaL_addchar(&b, *strfrmt++); /* %% */ - else { /* format item */ - char form[MAX_FORMAT]; /* to store the format (`%...') */ - char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */ - int nb = 0; /* number of bytes in added item */ - if (++arg > top) - luaL_argerror(L, arg, "no value"); - strfrmt = scanformat(L, strfrmt, form); - switch (*strfrmt++) { - case 'c': { - nb = sprintf(buff, form, luaL_checkint(L, arg)); - break; - } - case 'd': case 'i': { - lua_Number n = luaL_checknumber(L, arg); - LUA_INTFRM_T ni = (LUA_INTFRM_T)n; - lua_Number diff = n - (lua_Number)ni; - luaL_argcheck(L, -1 < diff && diff < 1, arg, - "not a number in proper range"); - addlenmod(form, LUA_INTFRMLEN); - nb = sprintf(buff, form, ni); - break; - } - case 'o': case 'u': case 'x': case 'X': { - lua_Number n = luaL_checknumber(L, arg); - unsigned LUA_INTFRM_T ni = (unsigned LUA_INTFRM_T)n; - lua_Number diff = n - (lua_Number)ni; - luaL_argcheck(L, -1 < diff && diff < 1, arg, - "not a non-negative number in proper range"); - addlenmod(form, LUA_INTFRMLEN); - nb = sprintf(buff, form, ni); - break; - } - case 'e': case 'E': case 'f': +static int str_format(lua_State *L) +{ + int top = lua_gettop(L); + int arg = 1; + size_t sfl; + const char *strfrmt = luaL_checklstring(L, arg, &sfl); + const char *strfrmt_end = strfrmt + sfl; + luaL_Buffer b; + luaL_buffinit(L, &b); + while (strfrmt < strfrmt_end) + { + if (*strfrmt != L_ESC) + luaL_addchar(&b, *strfrmt++); + else if (*++strfrmt == L_ESC) + luaL_addchar(&b, *strfrmt++); /* %% */ + else + { /* format item */ + char form[MAX_FORMAT]; /* to store the format (`%...') */ + char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */ + int nb = 0; /* number of bytes in added item */ + if (++arg > top) + luaL_argerror(L, arg, "no value"); + strfrmt = scanformat(L, strfrmt, form); + switch (*strfrmt++) + { + case 'c': + { + nb = sprintf(buff, form, luaL_checkint(L, arg)); + break; + } + case 'd': + case 'i': + { + lua_Number n = luaL_checknumber(L, arg); + LUA_INTFRM_T ni = (LUA_INTFRM_T)n; + lua_Number diff = n - (lua_Number)ni; + luaL_argcheck(L, -1 < diff && diff < 1, arg, + "not a number in proper range"); + addlenmod(form, LUA_INTFRMLEN); + nb = sprintf(buff, form, ni); + break; + } + case 'o': + case 'u': + case 'x': + case 'X': + { + lua_Number n = luaL_checknumber(L, arg); + unsigned LUA_INTFRM_T ni = (unsigned LUA_INTFRM_T)n; + lua_Number diff = n - (lua_Number)ni; + luaL_argcheck(L, -1 < diff && diff < 1, arg, + "not a non-negative number in proper range"); + addlenmod(form, LUA_INTFRMLEN); + nb = sprintf(buff, form, ni); + break; + } + case 'e': + case 'E': + case 'f': #if defined(LUA_USE_AFORMAT) - case 'a': case 'A': + case 'a': + case 'A': #endif - case 'g': case 'G': { - addlenmod(form, LUA_FLTFRMLEN); - nb = sprintf(buff, form, (LUA_FLTFRM_T)luaL_checknumber(L, arg)); - break; - } - case 'q': { - addquoted(L, &b, arg); - break; - } - case 's': { - size_t l; - const char *s = luaL_tolstring(L, arg, &l); - if (!strchr(form, '.') && l >= 100) { - /* no precision and string is too long to be formatted; + case 'g': + case 'G': + { + addlenmod(form, LUA_FLTFRMLEN); + nb = sprintf(buff, form, (LUA_FLTFRM_T)luaL_checknumber(L, arg)); + break; + } + case 'q': + { + addquoted(L, &b, arg); + break; + } + case 's': + { + size_t l; + const char *s = luaL_tolstring(L, arg, &l); + if (!strchr(form, '.') && l >= 100) + { + /* no precision and string is too long to be formatted; keep original string */ - luaL_addvalue(&b); - break; - } - else { - nb = sprintf(buff, form, s); - lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ - break; - } - } - default: { /* also treat cases `pnLlh' */ - return luaL_error(L, "invalid option " LUA_QL("%%%c") " to " - LUA_QL("format"), *(strfrmt - 1)); - } - } - luaL_addsize(&b, nb); - } - } - luaL_pushresult(&b); - return 1; + luaL_addvalue(&b); + break; + } + else + { + nb = sprintf(buff, form, s); + lua_pop(L, 1); /* remove result from 'luaL_tolstring' */ + break; + } + } + default: + { /* also treat cases `pnLlh' */ + return luaL_error(L, "invalid option " LUA_QL("%%%c") " to " LUA_QL("format"), *(strfrmt - 1)); + } + } + luaL_addsize(&b, nb); + } + } + luaL_pushresult(&b); + return 1; } /* }====================================================== */ - static const luaL_Reg strlib[] = { - {"byte", str_byte}, - {"char", str_char}, - {"dump", str_dump}, - {"find", str_find}, - {"format", str_format}, - {"gmatch", gmatch}, - {"gsub", str_gsub}, - {"len", str_len}, - {"lower", str_lower}, - {"match", str_match}, - {"rep", str_rep}, - {"reverse", str_reverse}, - {"sub", str_sub}, - {"upper", str_upper}, - {NULL, NULL} -}; + {"byte", str_byte}, + {"char", str_char}, + {"dump", str_dump}, + {"find", str_find}, + {"format", str_format}, + {"gmatch", gmatch}, + {"gsub", str_gsub}, + {"len", str_len}, + {"lower", str_lower}, + {"match", str_match}, + {"rep", str_rep}, + {"reverse", str_reverse}, + {"sub", str_sub}, + {"upper", str_upper}, + {NULL, NULL}}; - -static void createmetatable (lua_State *L) { - lua_createtable(L, 0, 1); /* table to be metatable for strings */ - lua_pushliteral(L, ""); /* dummy string */ - lua_pushvalue(L, -2); /* copy table */ - lua_setmetatable(L, -2); /* set table as metatable for strings */ - lua_pop(L, 1); /* pop dummy string */ - lua_pushvalue(L, -2); /* get string library */ - lua_setfield(L, -2, "__index"); /* metatable.__index = string */ - lua_pop(L, 1); /* pop metatable */ +static void createmetatable(lua_State *L) +{ + lua_createtable(L, 0, 1); /* table to be metatable for strings */ + lua_pushliteral(L, ""); /* dummy string */ + lua_pushvalue(L, -2); /* copy table */ + lua_setmetatable(L, -2); /* set table as metatable for strings */ + lua_pop(L, 1); /* pop dummy string */ + lua_pushvalue(L, -2); /* get string library */ + lua_setfield(L, -2, "__index"); /* metatable.__index = string */ + lua_pop(L, 1); /* pop metatable */ } - /* ** Open string library */ -LUAMOD_API int luaopen_string (lua_State *L) { - luaL_newlib(L, strlib); - createmetatable(L); - return 1; +LUAMOD_API int luaopen_string(lua_State *L) +{ + luaL_newlib(L, strlib); + createmetatable(L); + return 1; } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/ltable.c b/examples/ThirdPartyLibs/lua-5.2.3/src/ltable.c index 5d76f97ec..8cd7eaf1b 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/ltable.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/ltable.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - /* ** Implementation of tables (aka arrays, objects, or hash tables). ** Tables keep its elements in two parts: an array part and a hash part. @@ -35,366 +34,385 @@ #include "ltable.h" #include "lvm.h" - /* ** max size of array part is 2^MAXBITS */ #if LUAI_BITSINT >= 32 -#define MAXBITS 30 +#define MAXBITS 30 #else -#define MAXBITS (LUAI_BITSINT-2) +#define MAXBITS (LUAI_BITSINT - 2) #endif -#define MAXASIZE (1 << MAXBITS) +#define MAXASIZE (1 << MAXBITS) +#define hashpow2(t, n) (gnode(t, lmod((n), sizenode(t)))) -#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) - -#define hashstr(t,str) hashpow2(t, (str)->tsv.hash) -#define hashboolean(t,p) hashpow2(t, p) - +#define hashstr(t, str) hashpow2(t, (str)->tsv.hash) +#define hashboolean(t, p) hashpow2(t, p) /* ** for some types, it is better to avoid modulus by power of 2, as ** they tend to have many 2 factors. */ -#define hashmod(t,n) (gnode(t, ((n) % ((sizenode(t)-1)|1)))) +#define hashmod(t, n) (gnode(t, ((n) % ((sizenode(t) - 1) | 1)))) +#define hashpointer(t, p) hashmod(t, IntPoint(p)) -#define hashpointer(t,p) hashmod(t, IntPoint(p)) +#define dummynode (&dummynode_) - -#define dummynode (&dummynode_) - -#define isdummy(n) ((n) == dummynode) +#define isdummy(n) ((n) == dummynode) static const Node dummynode_ = { - {NILCONSTANT}, /* value */ - {{NILCONSTANT, NULL}} /* key */ + {NILCONSTANT}, /* value */ + {{NILCONSTANT, NULL}} /* key */ }; - /* ** hash for lua_Numbers */ -static Node *hashnum (const Table *t, lua_Number n) { - int i; - luai_hashnum(i, n); - if (i < 0) { - if (cast(unsigned int, i) == 0u - i) /* use unsigned to avoid overflows */ - i = 0; /* handle INT_MIN */ - i = -i; /* must be a positive value */ - } - return hashmod(t, i); +static Node *hashnum(const Table *t, lua_Number n) +{ + int i; + luai_hashnum(i, n); + if (i < 0) + { + if (cast(unsigned int, i) == 0u - i) /* use unsigned to avoid overflows */ + i = 0; /* handle INT_MIN */ + i = -i; /* must be a positive value */ + } + return hashmod(t, i); } - - /* ** returns the `main' position of an element in a table (that is, the index ** of its hash value) */ -static Node *mainposition (const Table *t, const TValue *key) { - switch (ttype(key)) { - case LUA_TNUMBER: - return hashnum(t, nvalue(key)); - case LUA_TLNGSTR: { - TString *s = rawtsvalue(key); - if (s->tsv.extra == 0) { /* no hash? */ - s->tsv.hash = luaS_hash(getstr(s), s->tsv.len, s->tsv.hash); - s->tsv.extra = 1; /* now it has its hash */ - } - return hashstr(t, rawtsvalue(key)); - } - case LUA_TSHRSTR: - return hashstr(t, rawtsvalue(key)); - case LUA_TBOOLEAN: - return hashboolean(t, bvalue(key)); - case LUA_TLIGHTUSERDATA: - return hashpointer(t, pvalue(key)); - case LUA_TLCF: - return hashpointer(t, fvalue(key)); - default: - return hashpointer(t, gcvalue(key)); - } +static Node *mainposition(const Table *t, const TValue *key) +{ + switch (ttype(key)) + { + case LUA_TNUMBER: + return hashnum(t, nvalue(key)); + case LUA_TLNGSTR: + { + TString *s = rawtsvalue(key); + if (s->tsv.extra == 0) + { /* no hash? */ + s->tsv.hash = luaS_hash(getstr(s), s->tsv.len, s->tsv.hash); + s->tsv.extra = 1; /* now it has its hash */ + } + return hashstr(t, rawtsvalue(key)); + } + case LUA_TSHRSTR: + return hashstr(t, rawtsvalue(key)); + case LUA_TBOOLEAN: + return hashboolean(t, bvalue(key)); + case LUA_TLIGHTUSERDATA: + return hashpointer(t, pvalue(key)); + case LUA_TLCF: + return hashpointer(t, fvalue(key)); + default: + return hashpointer(t, gcvalue(key)); + } } - /* ** returns the index for `key' if `key' is an appropriate key to live in ** the array part of the table, -1 otherwise. */ -static int arrayindex (const TValue *key) { - if (ttisnumber(key)) { - lua_Number n = nvalue(key); - int k; - lua_number2int(k, n); - if (luai_numeq(cast_num(k), n)) - return k; - } - return -1; /* `key' did not match some condition */ +static int arrayindex(const TValue *key) +{ + if (ttisnumber(key)) + { + lua_Number n = nvalue(key); + int k; + lua_number2int(k, n); + if (luai_numeq(cast_num(k), n)) + return k; + } + return -1; /* `key' did not match some condition */ } - /* ** returns the index of a `key' for table traversals. First goes all ** elements in the array part, then elements in the hash part. The ** beginning of a traversal is signaled by -1. */ -static int findindex (lua_State *L, Table *t, StkId key) { - int i; - if (ttisnil(key)) return -1; /* first iteration */ - i = arrayindex(key); - if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ - return i-1; /* yes; that's the index (corrected to C) */ - else { - Node *n = mainposition(t, key); - for (;;) { /* check whether `key' is somewhere in the chain */ - /* key may be dead already, but it is ok to use it in `next' */ - if (luaV_rawequalobj(gkey(n), key) || - (ttisdeadkey(gkey(n)) && iscollectable(key) && - deadvalue(gkey(n)) == gcvalue(key))) { - i = cast_int(n - gnode(t, 0)); /* key index in hash table */ - /* hash elements are numbered after array ones */ - return i + t->sizearray; - } - else n = gnext(n); - if (n == NULL) - luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ - } - } +static int findindex(lua_State *L, Table *t, StkId key) +{ + int i; + if (ttisnil(key)) return -1; /* first iteration */ + i = arrayindex(key); + if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ + return i - 1; /* yes; that's the index (corrected to C) */ + else + { + Node *n = mainposition(t, key); + for (;;) + { /* check whether `key' is somewhere in the chain */ + /* key may be dead already, but it is ok to use it in `next' */ + if (luaV_rawequalobj(gkey(n), key) || + (ttisdeadkey(gkey(n)) && iscollectable(key) && + deadvalue(gkey(n)) == gcvalue(key))) + { + i = cast_int(n - gnode(t, 0)); /* key index in hash table */ + /* hash elements are numbered after array ones */ + return i + t->sizearray; + } + else + n = gnext(n); + if (n == NULL) + luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ + } + } } - -int luaH_next (lua_State *L, Table *t, StkId key) { - int i = findindex(L, t, key); /* find original element */ - for (i++; i < t->sizearray; i++) { /* try first array part */ - if (!ttisnil(&t->array[i])) { /* a non-nil value? */ - setnvalue(key, cast_num(i+1)); - setobj2s(L, key+1, &t->array[i]); - return 1; - } - } - for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */ - if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ - setobj2s(L, key, gkey(gnode(t, i))); - setobj2s(L, key+1, gval(gnode(t, i))); - return 1; - } - } - return 0; /* no more elements */ +int luaH_next(lua_State *L, Table *t, StkId key) +{ + int i = findindex(L, t, key); /* find original element */ + for (i++; i < t->sizearray; i++) + { /* try first array part */ + if (!ttisnil(&t->array[i])) + { /* a non-nil value? */ + setnvalue(key, cast_num(i + 1)); + setobj2s(L, key + 1, &t->array[i]); + return 1; + } + } + for (i -= t->sizearray; i < sizenode(t); i++) + { /* then hash part */ + if (!ttisnil(gval(gnode(t, i)))) + { /* a non-nil value? */ + setobj2s(L, key, gkey(gnode(t, i))); + setobj2s(L, key + 1, gval(gnode(t, i))); + return 1; + } + } + return 0; /* no more elements */ } - /* ** {============================================================= ** Rehash ** ============================================================== */ - -static int computesizes (int nums[], int *narray) { - int i; - int twotoi; /* 2^i */ - int a = 0; /* number of elements smaller than 2^i */ - int na = 0; /* number of elements to go to array part */ - int n = 0; /* optimal size for array part */ - for (i = 0, twotoi = 1; twotoi/2 < *narray; i++, twotoi *= 2) { - if (nums[i] > 0) { - a += nums[i]; - if (a > twotoi/2) { /* more than half elements present? */ - n = twotoi; /* optimal size (till now) */ - na = a; /* all elements smaller than n will go to array part */ - } - } - if (a == *narray) break; /* all elements already counted */ - } - *narray = n; - lua_assert(*narray/2 <= na && na <= *narray); - return na; +static int computesizes(int nums[], int *narray) +{ + int i; + int twotoi; /* 2^i */ + int a = 0; /* number of elements smaller than 2^i */ + int na = 0; /* number of elements to go to array part */ + int n = 0; /* optimal size for array part */ + for (i = 0, twotoi = 1; twotoi / 2 < *narray; i++, twotoi *= 2) + { + if (nums[i] > 0) + { + a += nums[i]; + if (a > twotoi / 2) + { /* more than half elements present? */ + n = twotoi; /* optimal size (till now) */ + na = a; /* all elements smaller than n will go to array part */ + } + } + if (a == *narray) break; /* all elements already counted */ + } + *narray = n; + lua_assert(*narray / 2 <= na && na <= *narray); + return na; } - -static int countint (const TValue *key, int *nums) { - int k = arrayindex(key); - if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */ - nums[luaO_ceillog2(k)]++; /* count as such */ - return 1; - } - else - return 0; +static int countint(const TValue *key, int *nums) +{ + int k = arrayindex(key); + if (0 < k && k <= MAXASIZE) + { /* is `key' an appropriate array index? */ + nums[luaO_ceillog2(k)]++; /* count as such */ + return 1; + } + else + return 0; } - -static int numusearray (const Table *t, int *nums) { - int lg; - int ttlg; /* 2^lg */ - int ause = 0; /* summation of `nums' */ - int i = 1; /* count to traverse all array keys */ - for (lg=0, ttlg=1; lg<=MAXBITS; lg++, ttlg*=2) { /* for each slice */ - int lc = 0; /* counter */ - int lim = ttlg; - if (lim > t->sizearray) { - lim = t->sizearray; /* adjust upper limit */ - if (i > lim) - break; /* no more elements to count */ - } - /* count elements in range (2^(lg-1), 2^lg] */ - for (; i <= lim; i++) { - if (!ttisnil(&t->array[i-1])) - lc++; - } - nums[lg] += lc; - ause += lc; - } - return ause; +static int numusearray(const Table *t, int *nums) +{ + int lg; + int ttlg; /* 2^lg */ + int ause = 0; /* summation of `nums' */ + int i = 1; /* count to traverse all array keys */ + for (lg = 0, ttlg = 1; lg <= MAXBITS; lg++, ttlg *= 2) + { /* for each slice */ + int lc = 0; /* counter */ + int lim = ttlg; + if (lim > t->sizearray) + { + lim = t->sizearray; /* adjust upper limit */ + if (i > lim) + break; /* no more elements to count */ + } + /* count elements in range (2^(lg-1), 2^lg] */ + for (; i <= lim; i++) + { + if (!ttisnil(&t->array[i - 1])) + lc++; + } + nums[lg] += lc; + ause += lc; + } + return ause; } - -static int numusehash (const Table *t, int *nums, int *pnasize) { - int totaluse = 0; /* total number of elements */ - int ause = 0; /* summation of `nums' */ - int i = sizenode(t); - while (i--) { - Node *n = &t->node[i]; - if (!ttisnil(gval(n))) { - ause += countint(gkey(n), nums); - totaluse++; - } - } - *pnasize += ause; - return totaluse; +static int numusehash(const Table *t, int *nums, int *pnasize) +{ + int totaluse = 0; /* total number of elements */ + int ause = 0; /* summation of `nums' */ + int i = sizenode(t); + while (i--) + { + Node *n = &t->node[i]; + if (!ttisnil(gval(n))) + { + ause += countint(gkey(n), nums); + totaluse++; + } + } + *pnasize += ause; + return totaluse; } - -static void setarrayvector (lua_State *L, Table *t, int size) { - int i; - luaM_reallocvector(L, t->array, t->sizearray, size, TValue); - for (i=t->sizearray; iarray[i]); - t->sizearray = size; +static void setarrayvector(lua_State *L, Table *t, int size) +{ + int i; + luaM_reallocvector(L, t->array, t->sizearray, size, TValue); + for (i = t->sizearray; i < size; i++) + setnilvalue(&t->array[i]); + t->sizearray = size; } - -static void setnodevector (lua_State *L, Table *t, int size) { - int lsize; - if (size == 0) { /* no elements to hash part? */ - t->node = cast(Node *, dummynode); /* use common `dummynode' */ - lsize = 0; - } - else { - int i; - lsize = luaO_ceillog2(size); - if (lsize > MAXBITS) - luaG_runerror(L, "table overflow"); - size = twoto(lsize); - t->node = luaM_newvector(L, size, Node); - for (i=0; ilsizenode = cast_byte(lsize); - t->lastfree = gnode(t, size); /* all positions are free */ +static void setnodevector(lua_State *L, Table *t, int size) +{ + int lsize; + if (size == 0) + { /* no elements to hash part? */ + t->node = cast(Node *, dummynode); /* use common `dummynode' */ + lsize = 0; + } + else + { + int i; + lsize = luaO_ceillog2(size); + if (lsize > MAXBITS) + luaG_runerror(L, "table overflow"); + size = twoto(lsize); + t->node = luaM_newvector(L, size, Node); + for (i = 0; i < size; i++) + { + Node *n = gnode(t, i); + gnext(n) = NULL; + setnilvalue(gkey(n)); + setnilvalue(gval(n)); + } + } + t->lsizenode = cast_byte(lsize); + t->lastfree = gnode(t, size); /* all positions are free */ } - -void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) { - int i; - int oldasize = t->sizearray; - int oldhsize = t->lsizenode; - Node *nold = t->node; /* save old hash ... */ - if (nasize > oldasize) /* array part must grow? */ - setarrayvector(L, t, nasize); - /* create new hash part with appropriate size */ - setnodevector(L, t, nhsize); - if (nasize < oldasize) { /* array part must shrink? */ - t->sizearray = nasize; - /* re-insert elements from vanishing slice */ - for (i=nasize; iarray[i])) - luaH_setint(L, t, i + 1, &t->array[i]); - } - /* shrink array */ - luaM_reallocvector(L, t->array, oldasize, nasize, TValue); - } - /* re-insert elements from hash part */ - for (i = twoto(oldhsize) - 1; i >= 0; i--) { - Node *old = nold+i; - if (!ttisnil(gval(old))) { - /* doesn't need barrier/invalidate cache, as entry was +void luaH_resize(lua_State *L, Table *t, int nasize, int nhsize) +{ + int i; + int oldasize = t->sizearray; + int oldhsize = t->lsizenode; + Node *nold = t->node; /* save old hash ... */ + if (nasize > oldasize) /* array part must grow? */ + setarrayvector(L, t, nasize); + /* create new hash part with appropriate size */ + setnodevector(L, t, nhsize); + if (nasize < oldasize) + { /* array part must shrink? */ + t->sizearray = nasize; + /* re-insert elements from vanishing slice */ + for (i = nasize; i < oldasize; i++) + { + if (!ttisnil(&t->array[i])) + luaH_setint(L, t, i + 1, &t->array[i]); + } + /* shrink array */ + luaM_reallocvector(L, t->array, oldasize, nasize, TValue); + } + /* re-insert elements from hash part */ + for (i = twoto(oldhsize) - 1; i >= 0; i--) + { + Node *old = nold + i; + if (!ttisnil(gval(old))) + { + /* doesn't need barrier/invalidate cache, as entry was already present in the table */ - setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old)); - } - } - if (!isdummy(nold)) - luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old array */ + setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old)); + } + } + if (!isdummy(nold)) + luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old array */ } - -void luaH_resizearray (lua_State *L, Table *t, int nasize) { - int nsize = isdummy(t->node) ? 0 : sizenode(t); - luaH_resize(L, t, nasize, nsize); +void luaH_resizearray(lua_State *L, Table *t, int nasize) +{ + int nsize = isdummy(t->node) ? 0 : sizenode(t); + luaH_resize(L, t, nasize, nsize); } - -static void rehash (lua_State *L, Table *t, const TValue *ek) { - int nasize, na; - int nums[MAXBITS+1]; /* nums[i] = number of keys with 2^(i-1) < k <= 2^i */ - int i; - int totaluse; - for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */ - nasize = numusearray(t, nums); /* count keys in array part */ - totaluse = nasize; /* all those keys are integer keys */ - totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */ - /* count extra key */ - nasize += countint(ek, nums); - totaluse++; - /* compute new size for array part */ - na = computesizes(nums, &nasize); - /* resize the table to new computed sizes */ - luaH_resize(L, t, nasize, totaluse - na); +static void rehash(lua_State *L, Table *t, const TValue *ek) +{ + int nasize, na; + int nums[MAXBITS + 1]; /* nums[i] = number of keys with 2^(i-1) < k <= 2^i */ + int i; + int totaluse; + for (i = 0; i <= MAXBITS; i++) nums[i] = 0; /* reset counts */ + nasize = numusearray(t, nums); /* count keys in array part */ + totaluse = nasize; /* all those keys are integer keys */ + totaluse += numusehash(t, nums, &nasize); /* count keys in hash part */ + /* count extra key */ + nasize += countint(ek, nums); + totaluse++; + /* compute new size for array part */ + na = computesizes(nums, &nasize); + /* resize the table to new computed sizes */ + luaH_resize(L, t, nasize, totaluse - na); } - - /* ** }============================================================= */ - -Table *luaH_new (lua_State *L) { - Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table), NULL, 0)->h; - t->metatable = NULL; - t->flags = cast_byte(~0); - t->array = NULL; - t->sizearray = 0; - setnodevector(L, t, 0); - return t; +Table *luaH_new(lua_State *L) +{ + Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table), NULL, 0)->h; + t->metatable = NULL; + t->flags = cast_byte(~0); + t->array = NULL; + t->sizearray = 0; + setnodevector(L, t, 0); + return t; } - -void luaH_free (lua_State *L, Table *t) { - if (!isdummy(t->node)) - luaM_freearray(L, t->node, cast(size_t, sizenode(t))); - luaM_freearray(L, t->array, t->sizearray); - luaM_free(L, t); +void luaH_free(lua_State *L, Table *t) +{ + if (!isdummy(t->node)) + luaM_freearray(L, t->node, cast(size_t, sizenode(t))); + luaM_freearray(L, t->array, t->sizearray); + luaM_free(L, t); } - -static Node *getfreepos (Table *t) { - while (t->lastfree > t->node) { - t->lastfree--; - if (ttisnil(gkey(t->lastfree))) - return t->lastfree; - } - return NULL; /* could not find a free place */ +static Node *getfreepos(Table *t) +{ + while (t->lastfree > t->node) + { + t->lastfree--; + if (ttisnil(gkey(t->lastfree))) + return t->lastfree; + } + return NULL; /* could not find a free place */ } - - /* ** inserts a new key into a hash table; first, check whether key's main ** position is free. If not, check whether colliding node is in its main @@ -402,187 +420,216 @@ static Node *getfreepos (Table *t) { ** put new key in its main position; otherwise (colliding node is in its main ** position), new key goes to an empty position. */ -TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { - Node *mp; - if (ttisnil(key)) luaG_runerror(L, "table index is nil"); - else if (ttisnumber(key) && luai_numisnan(L, nvalue(key))) - luaG_runerror(L, "table index is NaN"); - mp = mainposition(t, key); - if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */ - Node *othern; - Node *n = getfreepos(t); /* get a free place */ - if (n == NULL) { /* cannot find a free place? */ - rehash(L, t, key); /* grow table */ - /* whatever called 'newkey' take care of TM cache and GC barrier */ - return luaH_set(L, t, key); /* insert key into grown table */ - } - lua_assert(!isdummy(n)); - othern = mainposition(t, gkey(mp)); - if (othern != mp) { /* is colliding node out of its main position? */ - /* yes; move colliding node into free position */ - while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ - gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ - *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ - gnext(mp) = NULL; /* now `mp' is free */ - setnilvalue(gval(mp)); - } - else { /* colliding node is in its own main position */ - /* new node will go into free position */ - gnext(n) = gnext(mp); /* chain new position */ - gnext(mp) = n; - mp = n; - } - } - setobj2t(L, gkey(mp), key); - luaC_barrierback(L, obj2gco(t), key); - lua_assert(ttisnil(gval(mp))); - return gval(mp); +TValue *luaH_newkey(lua_State *L, Table *t, const TValue *key) +{ + Node *mp; + if (ttisnil(key)) + luaG_runerror(L, "table index is nil"); + else if (ttisnumber(key) && luai_numisnan(L, nvalue(key))) + luaG_runerror(L, "table index is NaN"); + mp = mainposition(t, key); + if (!ttisnil(gval(mp)) || isdummy(mp)) + { /* main position is taken? */ + Node *othern; + Node *n = getfreepos(t); /* get a free place */ + if (n == NULL) + { /* cannot find a free place? */ + rehash(L, t, key); /* grow table */ + /* whatever called 'newkey' take care of TM cache and GC barrier */ + return luaH_set(L, t, key); /* insert key into grown table */ + } + lua_assert(!isdummy(n)); + othern = mainposition(t, gkey(mp)); + if (othern != mp) + { /* is colliding node out of its main position? */ + /* yes; move colliding node into free position */ + while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ + gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ + *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ + gnext(mp) = NULL; /* now `mp' is free */ + setnilvalue(gval(mp)); + } + else + { /* colliding node is in its own main position */ + /* new node will go into free position */ + gnext(n) = gnext(mp); /* chain new position */ + gnext(mp) = n; + mp = n; + } + } + setobj2t(L, gkey(mp), key); + luaC_barrierback(L, obj2gco(t), key); + lua_assert(ttisnil(gval(mp))); + return gval(mp); } - /* ** search function for integers */ -const TValue *luaH_getint (Table *t, int key) { - /* (1 <= key && key <= t->sizearray) */ - if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray)) - return &t->array[key-1]; - else { - lua_Number nk = cast_num(key); - Node *n = hashnum(t, nk); - do { /* check whether `key' is somewhere in the chain */ - if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) - return gval(n); /* that's it */ - else n = gnext(n); - } while (n); - return luaO_nilobject; - } +const TValue *luaH_getint(Table *t, int key) +{ + /* (1 <= key && key <= t->sizearray) */ + if (cast(unsigned int, key - 1) < cast(unsigned int, t->sizearray)) + return &t->array[key - 1]; + else + { + lua_Number nk = cast_num(key); + Node *n = hashnum(t, nk); + do + { /* check whether `key' is somewhere in the chain */ + if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk)) + return gval(n); /* that's it */ + else + n = gnext(n); + } while (n); + return luaO_nilobject; + } } - /* ** search function for short strings */ -const TValue *luaH_getstr (Table *t, TString *key) { - Node *n = hashstr(t, key); - lua_assert(key->tsv.tt == LUA_TSHRSTR); - do { /* check whether `key' is somewhere in the chain */ - if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key)) - return gval(n); /* that's it */ - else n = gnext(n); - } while (n); - return luaO_nilobject; +const TValue *luaH_getstr(Table *t, TString *key) +{ + Node *n = hashstr(t, key); + lua_assert(key->tsv.tt == LUA_TSHRSTR); + do + { /* check whether `key' is somewhere in the chain */ + if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key)) + return gval(n); /* that's it */ + else + n = gnext(n); + } while (n); + return luaO_nilobject; } - /* ** main search function */ -const TValue *luaH_get (Table *t, const TValue *key) { - switch (ttype(key)) { - case LUA_TSHRSTR: return luaH_getstr(t, rawtsvalue(key)); - case LUA_TNIL: return luaO_nilobject; - case LUA_TNUMBER: { - int k; - lua_Number n = nvalue(key); - lua_number2int(k, n); - if (luai_numeq(cast_num(k), n)) /* index is int? */ - return luaH_getint(t, k); /* use specialized version */ - /* else go through */ - } - default: { - Node *n = mainposition(t, key); - do { /* check whether `key' is somewhere in the chain */ - if (luaV_rawequalobj(gkey(n), key)) - return gval(n); /* that's it */ - else n = gnext(n); - } while (n); - return luaO_nilobject; - } - } +const TValue *luaH_get(Table *t, const TValue *key) +{ + switch (ttype(key)) + { + case LUA_TSHRSTR: + return luaH_getstr(t, rawtsvalue(key)); + case LUA_TNIL: + return luaO_nilobject; + case LUA_TNUMBER: + { + int k; + lua_Number n = nvalue(key); + lua_number2int(k, n); + if (luai_numeq(cast_num(k), n)) /* index is int? */ + return luaH_getint(t, k); /* use specialized version */ + /* else go through */ + } + default: + { + Node *n = mainposition(t, key); + do + { /* check whether `key' is somewhere in the chain */ + if (luaV_rawequalobj(gkey(n), key)) + return gval(n); /* that's it */ + else + n = gnext(n); + } while (n); + return luaO_nilobject; + } + } } - /* ** beware: when using this function you probably need to check a GC ** barrier and invalidate the TM cache. */ -TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { - const TValue *p = luaH_get(t, key); - if (p != luaO_nilobject) - return cast(TValue *, p); - else return luaH_newkey(L, t, key); +TValue *luaH_set(lua_State *L, Table *t, const TValue *key) +{ + const TValue *p = luaH_get(t, key); + if (p != luaO_nilobject) + return cast(TValue *, p); + else + return luaH_newkey(L, t, key); } - -void luaH_setint (lua_State *L, Table *t, int key, TValue *value) { - const TValue *p = luaH_getint(t, key); - TValue *cell; - if (p != luaO_nilobject) - cell = cast(TValue *, p); - else { - TValue k; - setnvalue(&k, cast_num(key)); - cell = luaH_newkey(L, t, &k); - } - setobj2t(L, cell, value); +void luaH_setint(lua_State *L, Table *t, int key, TValue *value) +{ + const TValue *p = luaH_getint(t, key); + TValue *cell; + if (p != luaO_nilobject) + cell = cast(TValue *, p); + else + { + TValue k; + setnvalue(&k, cast_num(key)); + cell = luaH_newkey(L, t, &k); + } + setobj2t(L, cell, value); } - -static int unbound_search (Table *t, unsigned int j) { - unsigned int i = j; /* i is zero or a present index */ - j++; - /* find `i' and `j' such that i is present and j is not */ - while (!ttisnil(luaH_getint(t, j))) { - i = j; - j *= 2; - if (j > cast(unsigned int, MAX_INT)) { /* overflow? */ - /* table was built with bad purposes: resort to linear search */ - i = 1; - while (!ttisnil(luaH_getint(t, i))) i++; - return i - 1; - } - } - /* now do a binary search between them */ - while (j - i > 1) { - unsigned int m = (i+j)/2; - if (ttisnil(luaH_getint(t, m))) j = m; - else i = m; - } - return i; +static int unbound_search(Table *t, unsigned int j) +{ + unsigned int i = j; /* i is zero or a present index */ + j++; + /* find `i' and `j' such that i is present and j is not */ + while (!ttisnil(luaH_getint(t, j))) + { + i = j; + j *= 2; + if (j > cast(unsigned int, MAX_INT)) + { /* overflow? */ + /* table was built with bad purposes: resort to linear search */ + i = 1; + while (!ttisnil(luaH_getint(t, i))) i++; + return i - 1; + } + } + /* now do a binary search between them */ + while (j - i > 1) + { + unsigned int m = (i + j) / 2; + if (ttisnil(luaH_getint(t, m))) + j = m; + else + i = m; + } + return i; } - /* ** Try to find a boundary in table `t'. A `boundary' is an integer index ** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). */ -int luaH_getn (Table *t) { - unsigned int j = t->sizearray; - if (j > 0 && ttisnil(&t->array[j - 1])) { - /* there is a boundary in the array part: (binary) search for it */ - unsigned int i = 0; - while (j - i > 1) { - unsigned int m = (i+j)/2; - if (ttisnil(&t->array[m - 1])) j = m; - else i = m; - } - return i; - } - /* else must find a boundary in hash part */ - else if (isdummy(t->node)) /* hash part is empty? */ - return j; /* that is easy... */ - else return unbound_search(t, j); +int luaH_getn(Table *t) +{ + unsigned int j = t->sizearray; + if (j > 0 && ttisnil(&t->array[j - 1])) + { + /* there is a boundary in the array part: (binary) search for it */ + unsigned int i = 0; + while (j - i > 1) + { + unsigned int m = (i + j) / 2; + if (ttisnil(&t->array[m - 1])) + j = m; + else + i = m; + } + return i; + } + /* else must find a boundary in hash part */ + else if (isdummy(t->node)) /* hash part is empty? */ + return j; /* that is easy... */ + else + return unbound_search(t, j); } - - #if defined(LUA_DEBUG) -Node *luaH_mainposition (const Table *t, const TValue *key) { - return mainposition(t, key); +Node *luaH_mainposition(const Table *t, const TValue *key) +{ + return mainposition(t, key); } -int luaH_isdummy (Node *n) { return isdummy(n); } +int luaH_isdummy(Node *n) { return isdummy(n); } #endif diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/ltable.h b/examples/ThirdPartyLibs/lua-5.2.3/src/ltable.h index d69449b2b..e58e36c9e 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/ltable.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/ltable.h @@ -9,37 +9,33 @@ #include "lobject.h" +#define gnode(t, i) (&(t)->node[i]) +#define gkey(n) (&(n)->i_key.tvk) +#define gval(n) (&(n)->i_val) +#define gnext(n) ((n)->i_key.nk.next) -#define gnode(t,i) (&(t)->node[i]) -#define gkey(n) (&(n)->i_key.tvk) -#define gval(n) (&(n)->i_val) -#define gnext(n) ((n)->i_key.nk.next) - -#define invalidateTMcache(t) ((t)->flags = 0) +#define invalidateTMcache(t) ((t)->flags = 0) /* returns the key, given the value of a table entry */ #define keyfromval(v) \ - (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val)))) - - -LUAI_FUNC const TValue *luaH_getint (Table *t, int key); -LUAI_FUNC void luaH_setint (lua_State *L, Table *t, int key, TValue *value); -LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); -LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); -LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); -LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key); -LUAI_FUNC Table *luaH_new (lua_State *L); -LUAI_FUNC void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize); -LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize); -LUAI_FUNC void luaH_free (lua_State *L, Table *t); -LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); -LUAI_FUNC int luaH_getn (Table *t); + (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val)))) +LUAI_FUNC const TValue *luaH_getint(Table *t, int key); +LUAI_FUNC void luaH_setint(lua_State *L, Table *t, int key, TValue *value); +LUAI_FUNC const TValue *luaH_getstr(Table *t, TString *key); +LUAI_FUNC const TValue *luaH_get(Table *t, const TValue *key); +LUAI_FUNC TValue *luaH_newkey(lua_State *L, Table *t, const TValue *key); +LUAI_FUNC TValue *luaH_set(lua_State *L, Table *t, const TValue *key); +LUAI_FUNC Table *luaH_new(lua_State *L); +LUAI_FUNC void luaH_resize(lua_State *L, Table *t, int nasize, int nhsize); +LUAI_FUNC void luaH_resizearray(lua_State *L, Table *t, int nasize); +LUAI_FUNC void luaH_free(lua_State *L, Table *t); +LUAI_FUNC int luaH_next(lua_State *L, Table *t, StkId key); +LUAI_FUNC int luaH_getn(Table *t); #if defined(LUA_DEBUG) -LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); -LUAI_FUNC int luaH_isdummy (Node *n); +LUAI_FUNC Node *luaH_mainposition(const Table *t, const TValue *key); +LUAI_FUNC int luaH_isdummy(Node *n); #endif - #endif diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/ltablib.c b/examples/ThirdPartyLibs/lua-5.2.3/src/ltablib.c index 6001224e3..57afd744c 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/ltablib.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/ltablib.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #include #define ltablib_c @@ -15,143 +14,148 @@ #include "lauxlib.h" #include "lualib.h" - -#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_len(L, n)) - - +#define aux_getn(L, n) (luaL_checktype(L, n, LUA_TTABLE), luaL_len(L, n)) #if defined(LUA_COMPAT_MAXN) -static int maxn (lua_State *L) { - lua_Number max = 0; - luaL_checktype(L, 1, LUA_TTABLE); - lua_pushnil(L); /* first key */ - while (lua_next(L, 1)) { - lua_pop(L, 1); /* remove value */ - if (lua_type(L, -1) == LUA_TNUMBER) { - lua_Number v = lua_tonumber(L, -1); - if (v > max) max = v; - } - } - lua_pushnumber(L, max); - return 1; +static int maxn(lua_State *L) +{ + lua_Number max = 0; + luaL_checktype(L, 1, LUA_TTABLE); + lua_pushnil(L); /* first key */ + while (lua_next(L, 1)) + { + lua_pop(L, 1); /* remove value */ + if (lua_type(L, -1) == LUA_TNUMBER) + { + lua_Number v = lua_tonumber(L, -1); + if (v > max) max = v; + } + } + lua_pushnumber(L, max); + return 1; } #endif - -static int tinsert (lua_State *L) { - int e = aux_getn(L, 1) + 1; /* first empty element */ - int pos; /* where to insert new element */ - switch (lua_gettop(L)) { - case 2: { /* called with only 2 arguments */ - pos = e; /* insert new element at the end */ - break; - } - case 3: { - int i; - pos = luaL_checkint(L, 2); /* 2nd argument is the position */ - luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds"); - for (i = e; i > pos; i--) { /* move up elements */ - lua_rawgeti(L, 1, i-1); - lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ - } - break; - } - default: { - return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); - } - } - lua_rawseti(L, 1, pos); /* t[pos] = v */ - return 0; +static int tinsert(lua_State *L) +{ + int e = aux_getn(L, 1) + 1; /* first empty element */ + int pos; /* where to insert new element */ + switch (lua_gettop(L)) + { + case 2: + { /* called with only 2 arguments */ + pos = e; /* insert new element at the end */ + break; + } + case 3: + { + int i; + pos = luaL_checkint(L, 2); /* 2nd argument is the position */ + luaL_argcheck(L, 1 <= pos && pos <= e, 2, "position out of bounds"); + for (i = e; i > pos; i--) + { /* move up elements */ + lua_rawgeti(L, 1, i - 1); + lua_rawseti(L, 1, i); /* t[i] = t[i-1] */ + } + break; + } + default: + { + return luaL_error(L, "wrong number of arguments to " LUA_QL("insert")); + } + } + lua_rawseti(L, 1, pos); /* t[pos] = v */ + return 0; } - -static int tremove (lua_State *L) { - int size = aux_getn(L, 1); - int pos = luaL_optint(L, 2, size); - if (pos != size) /* validate 'pos' if given */ - luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds"); - lua_rawgeti(L, 1, pos); /* result = t[pos] */ - for ( ; pos < size; pos++) { - lua_rawgeti(L, 1, pos+1); - lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */ - } - lua_pushnil(L); - lua_rawseti(L, 1, pos); /* t[pos] = nil */ - return 1; +static int tremove(lua_State *L) +{ + int size = aux_getn(L, 1); + int pos = luaL_optint(L, 2, size); + if (pos != size) /* validate 'pos' if given */ + luaL_argcheck(L, 1 <= pos && pos <= size + 1, 1, "position out of bounds"); + lua_rawgeti(L, 1, pos); /* result = t[pos] */ + for (; pos < size; pos++) + { + lua_rawgeti(L, 1, pos + 1); + lua_rawseti(L, 1, pos); /* t[pos] = t[pos+1] */ + } + lua_pushnil(L); + lua_rawseti(L, 1, pos); /* t[pos] = nil */ + return 1; } - -static void addfield (lua_State *L, luaL_Buffer *b, int i) { - lua_rawgeti(L, 1, i); - if (!lua_isstring(L, -1)) - luaL_error(L, "invalid value (%s) at index %d in table for " - LUA_QL("concat"), luaL_typename(L, -1), i); - luaL_addvalue(b); +static void addfield(lua_State *L, luaL_Buffer *b, int i) +{ + lua_rawgeti(L, 1, i); + if (!lua_isstring(L, -1)) + luaL_error(L, "invalid value (%s) at index %d in table for " LUA_QL("concat"), luaL_typename(L, -1), i); + luaL_addvalue(b); } - -static int tconcat (lua_State *L) { - luaL_Buffer b; - size_t lsep; - int i, last; - const char *sep = luaL_optlstring(L, 2, "", &lsep); - luaL_checktype(L, 1, LUA_TTABLE); - i = luaL_optint(L, 3, 1); - last = luaL_opt(L, luaL_checkint, 4, luaL_len(L, 1)); - luaL_buffinit(L, &b); - for (; i < last; i++) { - addfield(L, &b, i); - luaL_addlstring(&b, sep, lsep); - } - if (i == last) /* add last value (if interval was not empty) */ - addfield(L, &b, i); - luaL_pushresult(&b); - return 1; +static int tconcat(lua_State *L) +{ + luaL_Buffer b; + size_t lsep; + int i, last; + const char *sep = luaL_optlstring(L, 2, "", &lsep); + luaL_checktype(L, 1, LUA_TTABLE); + i = luaL_optint(L, 3, 1); + last = luaL_opt(L, luaL_checkint, 4, luaL_len(L, 1)); + luaL_buffinit(L, &b); + for (; i < last; i++) + { + addfield(L, &b, i); + luaL_addlstring(&b, sep, lsep); + } + if (i == last) /* add last value (if interval was not empty) */ + addfield(L, &b, i); + luaL_pushresult(&b); + return 1; } - /* ** {====================================================== ** Pack/unpack ** ======================================================= */ -static int pack (lua_State *L) { - int n = lua_gettop(L); /* number of elements to pack */ - lua_createtable(L, n, 1); /* create result table */ - lua_pushinteger(L, n); - lua_setfield(L, -2, "n"); /* t.n = number of elements */ - if (n > 0) { /* at least one element? */ - int i; - lua_pushvalue(L, 1); - lua_rawseti(L, -2, 1); /* insert first element */ - lua_replace(L, 1); /* move table into index 1 */ - for (i = n; i >= 2; i--) /* assign other elements */ - lua_rawseti(L, 1, i); - } - return 1; /* return table */ +static int pack(lua_State *L) +{ + int n = lua_gettop(L); /* number of elements to pack */ + lua_createtable(L, n, 1); /* create result table */ + lua_pushinteger(L, n); + lua_setfield(L, -2, "n"); /* t.n = number of elements */ + if (n > 0) + { /* at least one element? */ + int i; + lua_pushvalue(L, 1); + lua_rawseti(L, -2, 1); /* insert first element */ + lua_replace(L, 1); /* move table into index 1 */ + for (i = n; i >= 2; i--) /* assign other elements */ + lua_rawseti(L, 1, i); + } + return 1; /* return table */ } - -static int unpack (lua_State *L) { - int i, e, n; - luaL_checktype(L, 1, LUA_TTABLE); - i = luaL_optint(L, 2, 1); - e = luaL_opt(L, luaL_checkint, 3, luaL_len(L, 1)); - if (i > e) return 0; /* empty range */ - n = e - i + 1; /* number of elements */ - if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ - return luaL_error(L, "too many results to unpack"); - lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ - while (i++ < e) /* push arg[i + 1...e] */ - lua_rawgeti(L, 1, i); - return n; +static int unpack(lua_State *L) +{ + int i, e, n; + luaL_checktype(L, 1, LUA_TTABLE); + i = luaL_optint(L, 2, 1); + e = luaL_opt(L, luaL_checkint, 3, luaL_len(L, 1)); + if (i > e) return 0; /* empty range */ + n = e - i + 1; /* number of elements */ + if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */ + return luaL_error(L, "too many results to unpack"); + lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */ + while (i++ < e) /* push arg[i + 1...e] */ + lua_rawgeti(L, 1, i); + return n; } /* }====================================================== */ - - /* ** {====================================================== ** Quicksort @@ -160,124 +164,138 @@ static int unpack (lua_State *L) { ** ======================================================= */ - -static void set2 (lua_State *L, int i, int j) { - lua_rawseti(L, 1, i); - lua_rawseti(L, 1, j); +static void set2(lua_State *L, int i, int j) +{ + lua_rawseti(L, 1, i); + lua_rawseti(L, 1, j); } -static int sort_comp (lua_State *L, int a, int b) { - if (!lua_isnil(L, 2)) { /* function? */ - int res; - lua_pushvalue(L, 2); - lua_pushvalue(L, a-1); /* -1 to compensate function */ - lua_pushvalue(L, b-2); /* -2 to compensate function and `a' */ - lua_call(L, 2, 1); - res = lua_toboolean(L, -1); - lua_pop(L, 1); - return res; - } - else /* a < b? */ - return lua_compare(L, a, b, LUA_OPLT); +static int sort_comp(lua_State *L, int a, int b) +{ + if (!lua_isnil(L, 2)) + { /* function? */ + int res; + lua_pushvalue(L, 2); + lua_pushvalue(L, a - 1); /* -1 to compensate function */ + lua_pushvalue(L, b - 2); /* -2 to compensate function and `a' */ + lua_call(L, 2, 1); + res = lua_toboolean(L, -1); + lua_pop(L, 1); + return res; + } + else /* a < b? */ + return lua_compare(L, a, b, LUA_OPLT); } -static void auxsort (lua_State *L, int l, int u) { - while (l < u) { /* for tail recursion */ - int i, j; - /* sort elements a[l], a[(l+u)/2] and a[u] */ - lua_rawgeti(L, 1, l); - lua_rawgeti(L, 1, u); - if (sort_comp(L, -1, -2)) /* a[u] < a[l]? */ - set2(L, l, u); /* swap a[l] - a[u] */ - else - lua_pop(L, 2); - if (u-l == 1) break; /* only 2 elements */ - i = (l+u)/2; - lua_rawgeti(L, 1, i); - lua_rawgeti(L, 1, l); - if (sort_comp(L, -2, -1)) /* a[i]= P */ - while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) { - if (i>=u) luaL_error(L, "invalid order function for sorting"); - lua_pop(L, 1); /* remove a[i] */ - } - /* repeat --j until a[j] <= P */ - while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) { - if (j<=l) luaL_error(L, "invalid order function for sorting"); - lua_pop(L, 1); /* remove a[j] */ - } - if (j= P */ + while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) + { + if (i >= u) luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[i] */ + } + /* repeat --j until a[j] <= P */ + while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) + { + if (j <= l) luaL_error(L, "invalid order function for sorting"); + lua_pop(L, 1); /* remove a[j] */ + } + if (j < i) + { + lua_pop(L, 3); /* pop pivot, a[i], a[j] */ + break; + } + set2(L, i, j); + } + lua_rawgeti(L, 1, u - 1); + lua_rawgeti(L, 1, i); + set2(L, u - 1, i); /* swap pivot (a[u-1]) with a[i] */ + /* a[l..i-1] <= a[i] == P <= a[i+1..u] */ + /* adjust so that smaller half is in [j..i] and larger one in [l..u] */ + if (i - l < u - i) + { + j = l; + i = i - 1; + l = i + 2; + } + else + { + j = i + 1; + i = u; + u = j - 2; + } + auxsort(L, j, i); /* call recursively the smaller one */ + } /* repeat the routine for the larger one */ } -static int sort (lua_State *L) { - int n = aux_getn(L, 1); - luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */ - if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ - luaL_checktype(L, 2, LUA_TFUNCTION); - lua_settop(L, 2); /* make sure there is two arguments */ - auxsort(L, 1, n); - return 0; +static int sort(lua_State *L) +{ + int n = aux_getn(L, 1); + luaL_checkstack(L, 40, ""); /* assume array is smaller than 2^40 */ + if (!lua_isnoneornil(L, 2)) /* is there a 2nd argument? */ + luaL_checktype(L, 2, LUA_TFUNCTION); + lua_settop(L, 2); /* make sure there is two arguments */ + auxsort(L, 1, n); + return 0; } /* }====================================================== */ - static const luaL_Reg tab_funcs[] = { - {"concat", tconcat}, + {"concat", tconcat}, #if defined(LUA_COMPAT_MAXN) - {"maxn", maxn}, + {"maxn", maxn}, #endif - {"insert", tinsert}, - {"pack", pack}, - {"unpack", unpack}, - {"remove", tremove}, - {"sort", sort}, - {NULL, NULL} -}; + {"insert", tinsert}, + {"pack", pack}, + {"unpack", unpack}, + {"remove", tremove}, + {"sort", sort}, + {NULL, NULL}}; - -LUAMOD_API int luaopen_table (lua_State *L) { - luaL_newlib(L, tab_funcs); +LUAMOD_API int luaopen_table(lua_State *L) +{ + luaL_newlib(L, tab_funcs); #if defined(LUA_COMPAT_UNPACK) - /* _G.unpack = table.unpack */ - lua_getfield(L, -1, "unpack"); - lua_setglobal(L, "unpack"); + /* _G.unpack = table.unpack */ + lua_getfield(L, -1, "unpack"); + lua_setglobal(L, "unpack"); #endif - return 1; + return 1; } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/ltm.c b/examples/ThirdPartyLibs/lua-5.2.3/src/ltm.c index 69b4ed772..a2f5a94ee 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/ltm.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/ltm.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #include #define ltm_c @@ -18,60 +17,61 @@ #include "ltable.h" #include "ltm.h" - static const char udatatypename[] = "userdata"; LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = { - "no value", - "nil", "boolean", udatatypename, "number", - "string", "table", "function", udatatypename, "thread", - "proto", "upval" /* these last two cases are used for tests only */ + "no value", + "nil", "boolean", udatatypename, "number", + "string", "table", "function", udatatypename, "thread", + "proto", "upval" /* these last two cases are used for tests only */ }; - -void luaT_init (lua_State *L) { - static const char *const luaT_eventname[] = { /* ORDER TM */ - "__index", "__newindex", - "__gc", "__mode", "__len", "__eq", - "__add", "__sub", "__mul", "__div", "__mod", - "__pow", "__unm", "__lt", "__le", - "__concat", "__call" - }; - int i; - for (i=0; itmname[i] = luaS_new(L, luaT_eventname[i]); - luaS_fix(G(L)->tmname[i]); /* never collect these names */ - } +void luaT_init(lua_State *L) +{ + static const char *const luaT_eventname[] = {/* ORDER TM */ + "__index", "__newindex", + "__gc", "__mode", "__len", "__eq", + "__add", "__sub", "__mul", "__div", "__mod", + "__pow", "__unm", "__lt", "__le", + "__concat", "__call"}; + int i; + for (i = 0; i < TM_N; i++) + { + G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]); + luaS_fix(G(L)->tmname[i]); /* never collect these names */ + } } - /* ** function to be used with macro "fasttm": optimized for absence of ** tag methods */ -const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { - const TValue *tm = luaH_getstr(events, ename); - lua_assert(event <= TM_EQ); - if (ttisnil(tm)) { /* no tag method? */ - events->flags |= cast_byte(1u<flags |= cast_byte(1u << event); /* cache this fact */ + return NULL; + } + else + return tm; } - -const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) { - Table *mt; - switch (ttypenv(o)) { - case LUA_TTABLE: - mt = hvalue(o)->metatable; - break; - case LUA_TUSERDATA: - mt = uvalue(o)->metatable; - break; - default: - mt = G(L)->mt[ttypenv(o)]; - } - return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); +const TValue *luaT_gettmbyobj(lua_State *L, const TValue *o, TMS event) +{ + Table *mt; + switch (ttypenv(o)) + { + case LUA_TTABLE: + mt = hvalue(o)->metatable; + break; + case LUA_TUSERDATA: + mt = uvalue(o)->metatable; + break; + default: + mt = G(L)->mt[ttypenv(o)]; + } + return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/ltm.h b/examples/ThirdPartyLibs/lua-5.2.3/src/ltm.h index 7f89c841f..13d0b789f 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/ltm.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/ltm.h @@ -7,51 +7,46 @@ #ifndef ltm_h #define ltm_h - #include "lobject.h" - /* * WARNING: if you change the order of this enumeration, * grep "ORDER TM" */ -typedef enum { - TM_INDEX, - TM_NEWINDEX, - TM_GC, - TM_MODE, - TM_LEN, - TM_EQ, /* last tag method with `fast' access */ - TM_ADD, - TM_SUB, - TM_MUL, - TM_DIV, - TM_MOD, - TM_POW, - TM_UNM, - TM_LT, - TM_LE, - TM_CONCAT, - TM_CALL, - TM_N /* number of elements in the enum */ +typedef enum +{ + TM_INDEX, + TM_NEWINDEX, + TM_GC, + TM_MODE, + TM_LEN, + TM_EQ, /* last tag method with `fast' access */ + TM_ADD, + TM_SUB, + TM_MUL, + TM_DIV, + TM_MOD, + TM_POW, + TM_UNM, + TM_LT, + TM_LE, + TM_CONCAT, + TM_CALL, + TM_N /* number of elements in the enum */ } TMS; +#define gfasttm(g, et, e) ((et) == NULL ? NULL : ((et)->flags & (1u << (e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) +#define fasttm(l, et, e) gfasttm(G(l), et, e) -#define gfasttm(g,et,e) ((et) == NULL ? NULL : \ - ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) - -#define fasttm(l,et,e) gfasttm(G(l), et, e) - -#define ttypename(x) luaT_typenames_[(x) + 1] -#define objtypename(x) ttypename(ttypenv(x)) +#define ttypename(x) luaT_typenames_[(x) + 1] +#define objtypename(x) ttypename(ttypenv(x)) LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS]; - -LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); -LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, - TMS event); -LUAI_FUNC void luaT_init (lua_State *L); +LUAI_FUNC const TValue *luaT_gettm(Table *events, TMS event, TString *ename); +LUAI_FUNC const TValue *luaT_gettmbyobj(lua_State *L, const TValue *o, + TMS event); +LUAI_FUNC void luaT_init(lua_State *L); #endif diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lua.h b/examples/ThirdPartyLibs/lua-5.2.3/src/lua.h index 149a2c37b..cd2e36360 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lua.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lua.h @@ -5,112 +5,95 @@ ** See Copyright Notice at the end of this file */ - #ifndef lua_h #define lua_h #include #include - #include "luaconf.h" +#define LUA_VERSION_MAJOR "5" +#define LUA_VERSION_MINOR "2" +#define LUA_VERSION_NUM 502 +#define LUA_VERSION_RELEASE "3" -#define LUA_VERSION_MAJOR "5" -#define LUA_VERSION_MINOR "2" -#define LUA_VERSION_NUM 502 -#define LUA_VERSION_RELEASE "3" - -#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR -#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE -#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2013 Lua.org, PUC-Rio" -#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" - +#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR +#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE +#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2013 Lua.org, PUC-Rio" +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" /* mark for precompiled code ('Lua') */ -#define LUA_SIGNATURE "\033Lua" +#define LUA_SIGNATURE "\033Lua" /* option for multiple returns in 'lua_pcall' and 'lua_call' */ -#define LUA_MULTRET (-1) - +#define LUA_MULTRET (-1) /* ** pseudo-indices */ -#define LUA_REGISTRYINDEX LUAI_FIRSTPSEUDOIDX -#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i)) - +#define LUA_REGISTRYINDEX LUAI_FIRSTPSEUDOIDX +#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i)) /* thread status */ -#define LUA_OK 0 -#define LUA_YIELD 1 -#define LUA_ERRRUN 2 -#define LUA_ERRSYNTAX 3 -#define LUA_ERRMEM 4 -#define LUA_ERRGCMM 5 -#define LUA_ERRERR 6 - +#define LUA_OK 0 +#define LUA_YIELD 1 +#define LUA_ERRRUN 2 +#define LUA_ERRSYNTAX 3 +#define LUA_ERRMEM 4 +#define LUA_ERRGCMM 5 +#define LUA_ERRERR 6 typedef struct lua_State lua_State; -typedef int (*lua_CFunction) (lua_State *L); - +typedef int (*lua_CFunction)(lua_State *L); /* ** functions that read/write blocks when loading/dumping Lua chunks */ -typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); - -typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud); +typedef const char *(*lua_Reader)(lua_State *L, void *ud, size_t *sz); +typedef int (*lua_Writer)(lua_State *L, const void *p, size_t sz, void *ud); /* ** prototype for memory-allocation functions */ -typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); - +typedef void *(*lua_Alloc)(void *ud, void *ptr, size_t osize, size_t nsize); /* ** basic types */ -#define LUA_TNONE (-1) - -#define LUA_TNIL 0 -#define LUA_TBOOLEAN 1 -#define LUA_TLIGHTUSERDATA 2 -#define LUA_TNUMBER 3 -#define LUA_TSTRING 4 -#define LUA_TTABLE 5 -#define LUA_TFUNCTION 6 -#define LUA_TUSERDATA 7 -#define LUA_TTHREAD 8 - -#define LUA_NUMTAGS 9 +#define LUA_TNONE (-1) +#define LUA_TNIL 0 +#define LUA_TBOOLEAN 1 +#define LUA_TLIGHTUSERDATA 2 +#define LUA_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 +#define LUA_TFUNCTION 6 +#define LUA_TUSERDATA 7 +#define LUA_TTHREAD 8 +#define LUA_NUMTAGS 9 /* minimum Lua stack available to a C function */ -#define LUA_MINSTACK 20 - +#define LUA_MINSTACK 20 /* predefined values in the registry */ -#define LUA_RIDX_MAINTHREAD 1 -#define LUA_RIDX_GLOBALS 2 -#define LUA_RIDX_LAST LUA_RIDX_GLOBALS - +#define LUA_RIDX_MAINTHREAD 1 +#define LUA_RIDX_GLOBALS 2 +#define LUA_RIDX_LAST LUA_RIDX_GLOBALS /* type of numbers in Lua */ typedef LUA_NUMBER lua_Number; - /* type for integer functions */ typedef LUA_INTEGER lua_Integer; /* unsigned integer type */ typedef LUA_UNSIGNED lua_Unsigned; - - /* ** generic extra include file */ @@ -118,197 +101,183 @@ typedef LUA_UNSIGNED lua_Unsigned; #include LUA_USER_H #endif - /* ** RCS ident string */ extern const char lua_ident[]; - /* ** state manipulation */ -LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); -LUA_API void (lua_close) (lua_State *L); -LUA_API lua_State *(lua_newthread) (lua_State *L); +LUA_API lua_State *(lua_newstate)(lua_Alloc f, void *ud); +LUA_API void(lua_close)(lua_State *L); +LUA_API lua_State *(lua_newthread)(lua_State *L); -LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); - - -LUA_API const lua_Number *(lua_version) (lua_State *L); +LUA_API lua_CFunction(lua_atpanic)(lua_State *L, lua_CFunction panicf); +LUA_API const lua_Number *(lua_version)(lua_State *L); /* ** basic stack manipulation */ -LUA_API int (lua_absindex) (lua_State *L, int idx); -LUA_API int (lua_gettop) (lua_State *L); -LUA_API void (lua_settop) (lua_State *L, int idx); -LUA_API void (lua_pushvalue) (lua_State *L, int idx); -LUA_API void (lua_remove) (lua_State *L, int idx); -LUA_API void (lua_insert) (lua_State *L, int idx); -LUA_API void (lua_replace) (lua_State *L, int idx); -LUA_API void (lua_copy) (lua_State *L, int fromidx, int toidx); -LUA_API int (lua_checkstack) (lua_State *L, int sz); - -LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); +LUA_API int(lua_absindex)(lua_State *L, int idx); +LUA_API int(lua_gettop)(lua_State *L); +LUA_API void(lua_settop)(lua_State *L, int idx); +LUA_API void(lua_pushvalue)(lua_State *L, int idx); +LUA_API void(lua_remove)(lua_State *L, int idx); +LUA_API void(lua_insert)(lua_State *L, int idx); +LUA_API void(lua_replace)(lua_State *L, int idx); +LUA_API void(lua_copy)(lua_State *L, int fromidx, int toidx); +LUA_API int(lua_checkstack)(lua_State *L, int sz); +LUA_API void(lua_xmove)(lua_State *from, lua_State *to, int n); /* ** access functions (stack -> C) */ -LUA_API int (lua_isnumber) (lua_State *L, int idx); -LUA_API int (lua_isstring) (lua_State *L, int idx); -LUA_API int (lua_iscfunction) (lua_State *L, int idx); -LUA_API int (lua_isuserdata) (lua_State *L, int idx); -LUA_API int (lua_type) (lua_State *L, int idx); -LUA_API const char *(lua_typename) (lua_State *L, int tp); - -LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum); -LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum); -LUA_API lua_Unsigned (lua_tounsignedx) (lua_State *L, int idx, int *isnum); -LUA_API int (lua_toboolean) (lua_State *L, int idx); -LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); -LUA_API size_t (lua_rawlen) (lua_State *L, int idx); -LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); -LUA_API void *(lua_touserdata) (lua_State *L, int idx); -LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); -LUA_API const void *(lua_topointer) (lua_State *L, int idx); +LUA_API int(lua_isnumber)(lua_State *L, int idx); +LUA_API int(lua_isstring)(lua_State *L, int idx); +LUA_API int(lua_iscfunction)(lua_State *L, int idx); +LUA_API int(lua_isuserdata)(lua_State *L, int idx); +LUA_API int(lua_type)(lua_State *L, int idx); +LUA_API const char *(lua_typename)(lua_State *L, int tp); +LUA_API lua_Number(lua_tonumberx)(lua_State *L, int idx, int *isnum); +LUA_API lua_Integer(lua_tointegerx)(lua_State *L, int idx, int *isnum); +LUA_API lua_Unsigned(lua_tounsignedx)(lua_State *L, int idx, int *isnum); +LUA_API int(lua_toboolean)(lua_State *L, int idx); +LUA_API const char *(lua_tolstring)(lua_State *L, int idx, size_t *len); +LUA_API size_t(lua_rawlen)(lua_State *L, int idx); +LUA_API lua_CFunction(lua_tocfunction)(lua_State *L, int idx); +LUA_API void *(lua_touserdata)(lua_State *L, int idx); +LUA_API lua_State *(lua_tothread)(lua_State *L, int idx); +LUA_API const void *(lua_topointer)(lua_State *L, int idx); /* ** Comparison and arithmetic functions */ -#define LUA_OPADD 0 /* ORDER TM */ -#define LUA_OPSUB 1 -#define LUA_OPMUL 2 -#define LUA_OPDIV 3 -#define LUA_OPMOD 4 -#define LUA_OPPOW 5 -#define LUA_OPUNM 6 +#define LUA_OPADD 0 /* ORDER TM */ +#define LUA_OPSUB 1 +#define LUA_OPMUL 2 +#define LUA_OPDIV 3 +#define LUA_OPMOD 4 +#define LUA_OPPOW 5 +#define LUA_OPUNM 6 -LUA_API void (lua_arith) (lua_State *L, int op); +LUA_API void(lua_arith)(lua_State *L, int op); -#define LUA_OPEQ 0 -#define LUA_OPLT 1 -#define LUA_OPLE 2 - -LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); -LUA_API int (lua_compare) (lua_State *L, int idx1, int idx2, int op); +#define LUA_OPEQ 0 +#define LUA_OPLT 1 +#define LUA_OPLE 2 +LUA_API int(lua_rawequal)(lua_State *L, int idx1, int idx2); +LUA_API int(lua_compare)(lua_State *L, int idx1, int idx2, int op); /* ** push functions (C -> stack) */ -LUA_API void (lua_pushnil) (lua_State *L); -LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); -LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); -LUA_API void (lua_pushunsigned) (lua_State *L, lua_Unsigned n); -LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t l); -LUA_API const char *(lua_pushstring) (lua_State *L, const char *s); -LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, - va_list argp); -LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); -LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); -LUA_API void (lua_pushboolean) (lua_State *L, int b); -LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); -LUA_API int (lua_pushthread) (lua_State *L); - +LUA_API void(lua_pushnil)(lua_State *L); +LUA_API void(lua_pushnumber)(lua_State *L, lua_Number n); +LUA_API void(lua_pushinteger)(lua_State *L, lua_Integer n); +LUA_API void(lua_pushunsigned)(lua_State *L, lua_Unsigned n); +LUA_API const char *(lua_pushlstring)(lua_State *L, const char *s, size_t l); +LUA_API const char *(lua_pushstring)(lua_State *L, const char *s); +LUA_API const char *(lua_pushvfstring)(lua_State *L, const char *fmt, + va_list argp); +LUA_API const char *(lua_pushfstring)(lua_State *L, const char *fmt, ...); +LUA_API void(lua_pushcclosure)(lua_State *L, lua_CFunction fn, int n); +LUA_API void(lua_pushboolean)(lua_State *L, int b); +LUA_API void(lua_pushlightuserdata)(lua_State *L, void *p); +LUA_API int(lua_pushthread)(lua_State *L); /* ** get functions (Lua -> stack) */ -LUA_API void (lua_getglobal) (lua_State *L, const char *var); -LUA_API void (lua_gettable) (lua_State *L, int idx); -LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k); -LUA_API void (lua_rawget) (lua_State *L, int idx); -LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n); -LUA_API void (lua_rawgetp) (lua_State *L, int idx, const void *p); -LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); -LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz); -LUA_API int (lua_getmetatable) (lua_State *L, int objindex); -LUA_API void (lua_getuservalue) (lua_State *L, int idx); - +LUA_API void(lua_getglobal)(lua_State *L, const char *var); +LUA_API void(lua_gettable)(lua_State *L, int idx); +LUA_API void(lua_getfield)(lua_State *L, int idx, const char *k); +LUA_API void(lua_rawget)(lua_State *L, int idx); +LUA_API void(lua_rawgeti)(lua_State *L, int idx, int n); +LUA_API void(lua_rawgetp)(lua_State *L, int idx, const void *p); +LUA_API void(lua_createtable)(lua_State *L, int narr, int nrec); +LUA_API void *(lua_newuserdata)(lua_State *L, size_t sz); +LUA_API int(lua_getmetatable)(lua_State *L, int objindex); +LUA_API void(lua_getuservalue)(lua_State *L, int idx); /* ** set functions (stack -> Lua) */ -LUA_API void (lua_setglobal) (lua_State *L, const char *var); -LUA_API void (lua_settable) (lua_State *L, int idx); -LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); -LUA_API void (lua_rawset) (lua_State *L, int idx); -LUA_API void (lua_rawseti) (lua_State *L, int idx, int n); -LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p); -LUA_API int (lua_setmetatable) (lua_State *L, int objindex); -LUA_API void (lua_setuservalue) (lua_State *L, int idx); - +LUA_API void(lua_setglobal)(lua_State *L, const char *var); +LUA_API void(lua_settable)(lua_State *L, int idx); +LUA_API void(lua_setfield)(lua_State *L, int idx, const char *k); +LUA_API void(lua_rawset)(lua_State *L, int idx); +LUA_API void(lua_rawseti)(lua_State *L, int idx, int n); +LUA_API void(lua_rawsetp)(lua_State *L, int idx, const void *p); +LUA_API int(lua_setmetatable)(lua_State *L, int objindex); +LUA_API void(lua_setuservalue)(lua_State *L, int idx); /* ** 'load' and 'call' functions (load and run Lua code) */ -LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults, int ctx, - lua_CFunction k); -#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL) +LUA_API void(lua_callk)(lua_State *L, int nargs, int nresults, int ctx, + lua_CFunction k); +#define lua_call(L, n, r) lua_callk(L, (n), (r), 0, NULL) -LUA_API int (lua_getctx) (lua_State *L, int *ctx); +LUA_API int(lua_getctx)(lua_State *L, int *ctx); -LUA_API int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc, - int ctx, lua_CFunction k); -#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL) +LUA_API int(lua_pcallk)(lua_State *L, int nargs, int nresults, int errfunc, + int ctx, lua_CFunction k); +#define lua_pcall(L, n, r, f) lua_pcallk(L, (n), (r), (f), 0, NULL) -LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, - const char *chunkname, - const char *mode); - -LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data); +LUA_API int(lua_load)(lua_State *L, lua_Reader reader, void *dt, + const char *chunkname, + const char *mode); +LUA_API int(lua_dump)(lua_State *L, lua_Writer writer, void *data); /* ** coroutine functions */ -LUA_API int (lua_yieldk) (lua_State *L, int nresults, int ctx, - lua_CFunction k); -#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL) -LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg); -LUA_API int (lua_status) (lua_State *L); +LUA_API int(lua_yieldk)(lua_State *L, int nresults, int ctx, + lua_CFunction k); +#define lua_yield(L, n) lua_yieldk(L, (n), 0, NULL) +LUA_API int(lua_resume)(lua_State *L, lua_State *from, int narg); +LUA_API int(lua_status)(lua_State *L); /* ** garbage-collection function and options */ -#define LUA_GCSTOP 0 -#define LUA_GCRESTART 1 -#define LUA_GCCOLLECT 2 -#define LUA_GCCOUNT 3 -#define LUA_GCCOUNTB 4 -#define LUA_GCSTEP 5 -#define LUA_GCSETPAUSE 6 -#define LUA_GCSETSTEPMUL 7 -#define LUA_GCSETMAJORINC 8 -#define LUA_GCISRUNNING 9 -#define LUA_GCGEN 10 -#define LUA_GCINC 11 - -LUA_API int (lua_gc) (lua_State *L, int what, int data); +#define LUA_GCSTOP 0 +#define LUA_GCRESTART 1 +#define LUA_GCCOLLECT 2 +#define LUA_GCCOUNT 3 +#define LUA_GCCOUNTB 4 +#define LUA_GCSTEP 5 +#define LUA_GCSETPAUSE 6 +#define LUA_GCSETSTEPMUL 7 +#define LUA_GCSETMAJORINC 8 +#define LUA_GCISRUNNING 9 +#define LUA_GCGEN 10 +#define LUA_GCINC 11 +LUA_API int(lua_gc)(lua_State *L, int what, int data); /* ** miscellaneous functions */ -LUA_API int (lua_error) (lua_State *L); +LUA_API int(lua_error)(lua_State *L); -LUA_API int (lua_next) (lua_State *L, int idx); - -LUA_API void (lua_concat) (lua_State *L, int n); -LUA_API void (lua_len) (lua_State *L, int idx); - -LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); -LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); +LUA_API int(lua_next)(lua_State *L, int idx); +LUA_API void(lua_concat)(lua_State *L, int n); +LUA_API void(lua_len)(lua_State *L, int idx); +LUA_API lua_Alloc(lua_getallocf)(lua_State *L, void **ud); +LUA_API void(lua_setallocf)(lua_State *L, lua_Alloc f, void *ud); /* ** =============================================================== @@ -316,36 +285,34 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); ** =============================================================== */ -#define lua_tonumber(L,i) lua_tonumberx(L,i,NULL) -#define lua_tointeger(L,i) lua_tointegerx(L,i,NULL) -#define lua_tounsigned(L,i) lua_tounsignedx(L,i,NULL) +#define lua_tonumber(L, i) lua_tonumberx(L, i, NULL) +#define lua_tointeger(L, i) lua_tointegerx(L, i, NULL) +#define lua_tounsigned(L, i) lua_tounsignedx(L, i, NULL) -#define lua_pop(L,n) lua_settop(L, -(n)-1) +#define lua_pop(L, n) lua_settop(L, -(n)-1) -#define lua_newtable(L) lua_createtable(L, 0, 0) +#define lua_newtable(L) lua_createtable(L, 0, 0) -#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) +#define lua_register(L, n, f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) -#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) +#define lua_pushcfunction(L, f) lua_pushcclosure(L, (f), 0) -#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) -#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) -#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) -#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) -#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) -#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) -#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) -#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) +#define lua_isfunction(L, n) (lua_type(L, (n)) == LUA_TFUNCTION) +#define lua_istable(L, n) (lua_type(L, (n)) == LUA_TTABLE) +#define lua_islightuserdata(L, n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L, n) (lua_type(L, (n)) == LUA_TNIL) +#define lua_isboolean(L, n) (lua_type(L, (n)) == LUA_TBOOLEAN) +#define lua_isthread(L, n) (lua_type(L, (n)) == LUA_TTHREAD) +#define lua_isnone(L, n) (lua_type(L, (n)) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) -#define lua_pushliteral(L, s) \ - lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1) +#define lua_pushliteral(L, s) \ + lua_pushlstring(L, "" s, (sizeof(s) / sizeof(char)) - 1) -#define lua_pushglobaltable(L) \ +#define lua_pushglobaltable(L) \ lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS) -#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) - - +#define lua_tostring(L, i) lua_tolstring(L, (i), NULL) /* ** {====================================================================== @@ -353,70 +320,65 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); ** ======================================================================= */ - /* ** Event codes */ -#define LUA_HOOKCALL 0 -#define LUA_HOOKRET 1 -#define LUA_HOOKLINE 2 -#define LUA_HOOKCOUNT 3 +#define LUA_HOOKCALL 0 +#define LUA_HOOKRET 1 +#define LUA_HOOKLINE 2 +#define LUA_HOOKCOUNT 3 #define LUA_HOOKTAILCALL 4 - /* ** Event masks */ -#define LUA_MASKCALL (1 << LUA_HOOKCALL) -#define LUA_MASKRET (1 << LUA_HOOKRET) -#define LUA_MASKLINE (1 << LUA_HOOKLINE) -#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) - -typedef struct lua_Debug lua_Debug; /* activation record */ +#define LUA_MASKCALL (1 << LUA_HOOKCALL) +#define LUA_MASKRET (1 << LUA_HOOKRET) +#define LUA_MASKLINE (1 << LUA_HOOKLINE) +#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) +typedef struct lua_Debug lua_Debug; /* activation record */ /* Functions to be called by the debugger in specific events */ -typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); +typedef void (*lua_Hook)(lua_State *L, lua_Debug *ar); +LUA_API int(lua_getstack)(lua_State *L, int level, lua_Debug *ar); +LUA_API int(lua_getinfo)(lua_State *L, const char *what, lua_Debug *ar); +LUA_API const char *(lua_getlocal)(lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *(lua_setlocal)(lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *(lua_getupvalue)(lua_State *L, int funcindex, int n); +LUA_API const char *(lua_setupvalue)(lua_State *L, int funcindex, int n); -LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar); -LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar); -LUA_API const char *(lua_getlocal) (lua_State *L, const lua_Debug *ar, int n); -LUA_API const char *(lua_setlocal) (lua_State *L, const lua_Debug *ar, int n); -LUA_API const char *(lua_getupvalue) (lua_State *L, int funcindex, int n); -LUA_API const char *(lua_setupvalue) (lua_State *L, int funcindex, int n); +LUA_API void *(lua_upvalueid)(lua_State *L, int fidx, int n); +LUA_API void(lua_upvaluejoin)(lua_State *L, int fidx1, int n1, + int fidx2, int n2); -LUA_API void *(lua_upvalueid) (lua_State *L, int fidx, int n); -LUA_API void (lua_upvaluejoin) (lua_State *L, int fidx1, int n1, - int fidx2, int n2); +LUA_API int(lua_sethook)(lua_State *L, lua_Hook func, int mask, int count); +LUA_API lua_Hook(lua_gethook)(lua_State *L); +LUA_API int(lua_gethookmask)(lua_State *L); +LUA_API int(lua_gethookcount)(lua_State *L); -LUA_API int (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count); -LUA_API lua_Hook (lua_gethook) (lua_State *L); -LUA_API int (lua_gethookmask) (lua_State *L); -LUA_API int (lua_gethookcount) (lua_State *L); - - -struct lua_Debug { - int event; - const char *name; /* (n) */ - const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */ - const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */ - const char *source; /* (S) */ - int currentline; /* (l) */ - int linedefined; /* (S) */ - int lastlinedefined; /* (S) */ - unsigned char nups; /* (u) number of upvalues */ - unsigned char nparams;/* (u) number of parameters */ - char isvararg; /* (u) */ - char istailcall; /* (t) */ - char short_src[LUA_IDSIZE]; /* (S) */ - /* private part */ - struct CallInfo *i_ci; /* active function */ +struct lua_Debug +{ + int event; + const char *name; /* (n) */ + const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */ + const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */ + const char *source; /* (S) */ + int currentline; /* (l) */ + int linedefined; /* (S) */ + int lastlinedefined; /* (S) */ + unsigned char nups; /* (u) number of upvalues */ + unsigned char nparams; /* (u) number of parameters */ + char isvararg; /* (u) */ + char istailcall; /* (t) */ + char short_src[LUA_IDSIZE]; /* (S) */ + /* private part */ + struct CallInfo *i_ci; /* active function */ }; /* }====================================================================== */ - /****************************************************************************** * Copyright (C) 1994-2013 Lua.org, PUC-Rio. * @@ -440,5 +402,4 @@ struct lua_Debug { * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ******************************************************************************/ - #endif diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lua.hpp b/examples/ThirdPartyLibs/lua-5.2.3/src/lua.hpp index ec417f594..2239969cd 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lua.hpp +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lua.hpp @@ -2,7 +2,8 @@ // Lua header files for C++ // <> not supplied automatically because Lua also compiles as C++ -extern "C" { +extern "C" +{ #include "lua.h" #include "lualib.h" #include "lauxlib.h" diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/luaconf.h b/examples/ThirdPartyLibs/lua-5.2.3/src/luaconf.h index e8aee009a..a9f18c7cf 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/luaconf.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/luaconf.h @@ -4,21 +4,18 @@ ** See Copyright Notice in lua.h */ - #ifndef lconfig_h #define lconfig_h #include #include - /* ** ================================================================== ** Search for "@@" to find all configurable definitions. ** =================================================================== */ - /* @@ LUA_ANSI controls the use of non-ansi features. ** CHANGE it (define it) if you want Lua to avoid the use of any @@ -28,38 +25,33 @@ #define LUA_ANSI #endif - #if !defined(LUA_ANSI) && defined(_WIN32) && !defined(_WIN32_WCE) -#define LUA_WIN /* enable goodies for regular Windows platforms */ +#define LUA_WIN /* enable goodies for regular Windows platforms */ #endif #if defined(LUA_WIN) #define LUA_DL_DLL -#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ +#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ #endif - - #if defined(LUA_USE_LINUX) #define LUA_USE_POSIX //#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ //#define LUA_USE_READLINE /* needs some extra libraries */ -#define LUA_USE_STRTODHEX /* assume 'strtod' handles hex formats */ -#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ -#define LUA_USE_LONGLONG /* assume support for long long */ +#define LUA_USE_STRTODHEX /* assume 'strtod' handles hex formats */ +#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ +#define LUA_USE_LONGLONG /* assume support for long long */ #endif #if defined(LUA_USE_MACOSX) #define LUA_USE_POSIX //#define LUA_USE_DLOPEN /* does not need -ldl */ //#define LUA_USE_READLINE /* needs an extra library: -lreadline */ -#define LUA_USE_STRTODHEX /* assume 'strtod' handles hex formats */ -#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ -#define LUA_USE_LONGLONG /* assume support for long long */ +#define LUA_USE_STRTODHEX /* assume 'strtod' handles hex formats */ +#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */ +#define LUA_USE_LONGLONG /* assume support for long long */ #endif - - /* @@ LUA_USE_POSIX includes all functionality listed as X/Open System @* Interfaces Extension (XSI). @@ -73,8 +65,6 @@ #define LUA_USE_GMTIME_R #endif - - /* @@ LUA_PATH_DEFAULT is the default path that Lua uses to look for @* Lua libraries. @@ -84,32 +74,37 @@ ** hierarchy or if you want to install your libraries in ** non-conventional directories. */ -#if defined(_WIN32) /* { */ +#if defined(_WIN32) /* { */ /* ** In Windows, any exclamation mark ('!') in the path is replaced by the ** path of the directory of the executable file of the current process. */ -#define LUA_LDIR "!\\lua\\" -#define LUA_CDIR "!\\" -#define LUA_PATH_DEFAULT \ - LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ - LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" ".\\?.lua" -#define LUA_CPATH_DEFAULT \ - LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?.dll" +#define LUA_LDIR "!\\lua\\" +#define LUA_CDIR "!\\" +#define LUA_PATH_DEFAULT \ + LUA_LDIR "?.lua;" LUA_LDIR "?\\init.lua;" LUA_CDIR "?.lua;" LUA_CDIR \ + "?\\init.lua;" \ + ".\\?.lua" +#define LUA_CPATH_DEFAULT \ + LUA_CDIR "?.dll;" LUA_CDIR \ + "loadall.dll;" \ + ".\\?.dll" -#else /* }{ */ - -#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR "/" -#define LUA_ROOT "/usr/local/" -#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR -#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR -#define LUA_PATH_DEFAULT \ - LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ - LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" "./?.lua" -#define LUA_CPATH_DEFAULT \ - LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so" -#endif /* } */ +#else /* }{ */ +#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR "/" +#define LUA_ROOT "/usr/local/" +#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR +#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR +#define LUA_PATH_DEFAULT \ + LUA_LDIR "?.lua;" LUA_LDIR "?/init.lua;" LUA_CDIR "?.lua;" LUA_CDIR \ + "?/init.lua;" \ + "./?.lua" +#define LUA_CPATH_DEFAULT \ + LUA_CDIR "?.so;" LUA_CDIR \ + "loadall.so;" \ + "./?.so" +#endif /* } */ /* @@ LUA_DIRSEP is the directory separator (for submodules). @@ -117,19 +112,17 @@ ** and is not Windows. (On Windows Lua automatically uses "\".) */ #if defined(_WIN32) -#define LUA_DIRSEP "\\" +#define LUA_DIRSEP "\\" #else -#define LUA_DIRSEP "/" +#define LUA_DIRSEP "/" #endif - /* @@ LUA_ENV is the name of the variable that holds the current @@ environment, used to access global names. ** CHANGE it if you do not like this name. */ -#define LUA_ENV "_ENV" - +#define LUA_ENV "_ENV" /* @@ LUA_API is a mark for all core API functions. @@ -140,25 +133,23 @@ ** the libraries, you may want to use the following definition (define ** LUA_BUILD_AS_DLL to get it). */ -#if defined(LUA_BUILD_AS_DLL) /* { */ +#if defined(LUA_BUILD_AS_DLL) /* { */ -#if defined(LUA_CORE) || defined(LUA_LIB) /* { */ +#if defined(LUA_CORE) || defined(LUA_LIB) /* { */ #define LUA_API __declspec(dllexport) -#else /* }{ */ +#else /* }{ */ #define LUA_API __declspec(dllimport) -#endif /* } */ +#endif /* } */ -#else /* }{ */ +#else /* }{ */ -#define LUA_API extern - -#endif /* } */ +#define LUA_API extern +#endif /* } */ /* more often than not the libs go together with the core */ -#define LUALIB_API LUA_API -#define LUAMOD_API LUALIB_API - +#define LUALIB_API LUA_API +#define LUAMOD_API LUALIB_API /* @@ LUAI_FUNC is a mark for all extern functions that are not to be @@ -174,35 +165,31 @@ ** give a warning about it. To avoid these warnings, change to the ** default definition. */ -#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ - defined(__ELF__) /* { */ -#define LUAI_FUNC __attribute__((visibility("hidden"))) extern -#define LUAI_DDEC LUAI_FUNC -#define LUAI_DDEF /* empty */ - -#else /* }{ */ -#define LUAI_FUNC extern -#define LUAI_DDEC extern -#define LUAI_DDEF /* empty */ -#endif /* } */ - +#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 302) && \ + defined(__ELF__) /* { */ +#define LUAI_FUNC __attribute__((visibility("hidden"))) extern +#define LUAI_DDEC LUAI_FUNC +#define LUAI_DDEF /* empty */ +#else /* }{ */ +#define LUAI_FUNC extern +#define LUAI_DDEC extern +#define LUAI_DDEF /* empty */ +#endif /* } */ /* @@ LUA_QL describes how error messages quote program elements. ** CHANGE it if you want a different appearance. */ -#define LUA_QL(x) "'" x "'" -#define LUA_QS LUA_QL("%s") - +#define LUA_QL(x) "'" x "'" +#define LUA_QS LUA_QL("%s") /* @@ LUA_IDSIZE gives the maximum size for the description of the source @* of a function in debug information. ** CHANGE it if you want a different size. */ -#define LUA_IDSIZE 60 - +#define LUA_IDSIZE 60 /* @@ luai_writestring/luai_writeline define how 'print' prints its results. @@ -211,27 +198,24 @@ */ #if defined(LUA_LIB) || defined(lua_c) #include -#define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) -#define luai_writeline() (luai_writestring("\n", 1), fflush(stdout)) +#define luai_writestring(s, l) fwrite((s), sizeof(char), (l), stdout) +#define luai_writeline() (luai_writestring("\n", 1), fflush(stdout)) #endif /* @@ luai_writestringerror defines how to print error messages. ** (A format string with one argument is enough for Lua...) */ -#define luai_writestringerror(s,p) \ +#define luai_writestringerror(s, p) \ (fprintf(stderr, (s), (p)), fflush(stderr)) - /* @@ LUAI_MAXSHORTLEN is the maximum length for short strings, that is, ** strings that are internalized. (Cannot be smaller than reserved words ** or tags for metamethods, as these strings must be internalized; ** #("function") = 8, #("__newindex") = 10.) */ -#define LUAI_MAXSHORTLEN 40 - - +#define LUAI_MAXSHORTLEN 40 /* ** {================================================================== @@ -244,7 +228,7 @@ ** You can define it to get all options, or change specific options ** to fit your specific needs. */ -#if defined(LUA_COMPAT_ALL) /* { */ +#if defined(LUA_COMPAT_ALL) /* { */ /* @@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'. @@ -262,11 +246,10 @@ @@ macro 'lua_cpcall' emulates deprecated function lua_cpcall. ** You can call your C function directly (with light C functions). */ -#define lua_cpcall(L,f,u) \ - (lua_pushcfunction(L, (f)), \ - lua_pushlightuserdata(L,(u)), \ - lua_pcall(L,1,0,0)) - +#define lua_cpcall(L, f, u) \ + (lua_pushcfunction(L, (f)), \ + lua_pushlightuserdata(L, (u)), \ + lua_pcall(L, 1, 0, 0)) /* @@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library. @@ -290,12 +273,12 @@ ** changes in the API. The macros themselves document how to ** change your code to avoid using them. */ -#define lua_strlen(L,i) lua_rawlen(L, (i)) +#define lua_strlen(L, i) lua_rawlen(L, (i)) -#define lua_objlen(L,i) lua_rawlen(L, (i)) +#define lua_objlen(L, i) lua_rawlen(L, (i)) -#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ) -#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT) +#define lua_equal(L, idx1, idx2) lua_compare(L, (idx1), (idx2), LUA_OPEQ) +#define lua_lessthan(L, idx1, idx2) lua_compare(L, (idx1), (idx2), LUA_OPLT) /* @@ LUA_COMPAT_MODULE controls compatibility with previous @@ -303,27 +286,24 @@ */ #define LUA_COMPAT_MODULE -#endif /* } */ +#endif /* } */ /* }================================================================== */ - - /* @@ LUAI_BITSINT defines the number of bits in an int. ** CHANGE here if Lua cannot automatically detect the number of bits of ** your machine. Probably you do not need to change this. */ /* avoid overflows in comparison */ -#if INT_MAX-20 < 32760 /* { */ -#define LUAI_BITSINT 16 -#elif INT_MAX > 2147483640L /* }{ */ +#if INT_MAX - 20 < 32760 /* { */ +#define LUAI_BITSINT 16 +#elif INT_MAX > 2147483640L /* }{ */ /* int has at least 32 bits */ -#define LUAI_BITSINT 32 -#else /* }{ */ +#define LUAI_BITSINT 32 +#else /* }{ */ #error "you must define LUA_BITSINT with number of bits in an integer" -#endif /* } */ - +#endif /* } */ /* @@ LUA_INT32 is an signed integer with exactly 32 bits. @@ -335,17 +315,16 @@ ** good enough for your machine. Probably you do not need to change ** this. */ -#if LUAI_BITSINT >= 32 /* { */ -#define LUA_INT32 int -#define LUAI_UMEM size_t -#define LUAI_MEM ptrdiff_t -#else /* }{ */ +#if LUAI_BITSINT >= 32 /* { */ +#define LUA_INT32 int +#define LUAI_UMEM size_t +#define LUAI_MEM ptrdiff_t +#else /* }{ */ /* 16-bit ints */ -#define LUA_INT32 long -#define LUAI_UMEM unsigned long -#define LUAI_MEM long -#endif /* } */ - +#define LUA_INT32 long +#define LUAI_UMEM unsigned long +#define LUAI_MEM long +#endif /* } */ /* @@ LUAI_MAXSTACK limits the size of the Lua stack. @@ -354,25 +333,19 @@ ** space (and to reserve some numbers for pseudo-indices). */ #if LUAI_BITSINT >= 32 -#define LUAI_MAXSTACK 1000000 +#define LUAI_MAXSTACK 1000000 #else -#define LUAI_MAXSTACK 15000 +#define LUAI_MAXSTACK 15000 #endif /* reserve some space for error handling */ -#define LUAI_FIRSTPSEUDOIDX (-LUAI_MAXSTACK - 1000) - - - +#define LUAI_FIRSTPSEUDOIDX (-LUAI_MAXSTACK - 1000) /* @@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. ** CHANGE it if it uses too much C-stack space. */ -#define LUAL_BUFFERSIZE BUFSIZ - - - +#define LUAL_BUFFERSIZE BUFSIZ /* ** {================================================================== @@ -384,14 +357,13 @@ */ #define LUA_NUMBER_DOUBLE -#define LUA_NUMBER double +#define LUA_NUMBER double /* @@ LUAI_UACNUMBER is the result of an 'usual argument conversion' @* over a number. */ -#define LUAI_UACNUMBER double - +#define LUAI_UACNUMBER double /* @@ LUA_NUMBER_SCAN is the format for reading numbers. @@ -399,17 +371,15 @@ @@ lua_number2str converts a number to a string. @@ LUAI_MAXNUMBER2STR is maximum size of previous conversion. */ -#define LUA_NUMBER_SCAN "%lf" -#define LUA_NUMBER_FMT "%.14g" -#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n)) -#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ - +#define LUA_NUMBER_SCAN "%lf" +#define LUA_NUMBER_FMT "%.14g" +#define lua_number2str(s, n) sprintf((s), LUA_NUMBER_FMT, (n)) +#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */ /* @@ l_mathop allows the addition of an 'l' or 'f' to all math operations */ -#define l_mathop(x) (x) - +#define l_mathop(x) (x) /* @@ lua_str2number converts a decimal numeric string to a number. @@ -419,13 +389,12 @@ ** systems, you can leave 'lua_strx2number' undefined and Lua will ** provide its own implementation. */ -#define lua_str2number(s,p) strtod((s), (p)) +#define lua_str2number(s, p) strtod((s), (p)) #if defined(LUA_USE_STRTODHEX) -#define lua_strx2number(s,p) strtod((s), (p)) +#define lua_strx2number(s, p) strtod((s), (p)) #endif - /* @@ The luai_num* macros define the primitive operations over numbers. */ @@ -433,45 +402,41 @@ /* the following operations need the math library */ #if defined(lobject_c) || defined(lvm_c) #include -#define luai_nummod(L,a,b) ((a) - l_mathop(floor)((a)/(b))*(b)) -#define luai_numpow(L,a,b) (l_mathop(pow)(a,b)) +#define luai_nummod(L, a, b) ((a)-l_mathop(floor)((a) / (b)) * (b)) +#define luai_numpow(L, a, b) (l_mathop(pow)(a, b)) #endif /* these are quite standard operations */ #if defined(LUA_CORE) -#define luai_numadd(L,a,b) ((a)+(b)) -#define luai_numsub(L,a,b) ((a)-(b)) -#define luai_nummul(L,a,b) ((a)*(b)) -#define luai_numdiv(L,a,b) ((a)/(b)) -#define luai_numunm(L,a) (-(a)) -#define luai_numeq(a,b) ((a)==(b)) -#define luai_numlt(L,a,b) ((a)<(b)) -#define luai_numle(L,a,b) ((a)<=(b)) -#define luai_numisnan(L,a) (!luai_numeq((a), (a))) +#define luai_numadd(L, a, b) ((a) + (b)) +#define luai_numsub(L, a, b) ((a) - (b)) +#define luai_nummul(L, a, b) ((a) * (b)) +#define luai_numdiv(L, a, b) ((a) / (b)) +#define luai_numunm(L, a) (-(a)) +#define luai_numeq(a, b) ((a) == (b)) +#define luai_numlt(L, a, b) ((a) < (b)) +#define luai_numle(L, a, b) ((a) <= (b)) +#define luai_numisnan(L, a) (!luai_numeq((a), (a))) #endif - - /* @@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger. ** CHANGE that if ptrdiff_t is not adequate on your machine. (On most ** machines, ptrdiff_t gives a good choice between int or long.) */ -#define LUA_INTEGER ptrdiff_t +#define LUA_INTEGER ptrdiff_t /* @@ LUA_UNSIGNED is the integral type used by lua_pushunsigned/lua_tounsigned. ** It must have at least 32 bits. */ -#define LUA_UNSIGNED unsigned LUA_INT32 - - +#define LUA_UNSIGNED unsigned LUA_INT32 /* ** Some tricks with doubles */ -#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */ +#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */ /* ** The next definitions activate some tricks to speed up the ** conversion from doubles to integer types, mainly to LUA_UNSIGNED. @@ -498,46 +463,42 @@ */ /* Microsoft compiler on a Pentium (32 bit) ? */ -#if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) /* { */ +#if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) /* { */ #define LUA_MSASMTRICK -#define LUA_IEEEENDIAN 0 +#define LUA_IEEEENDIAN 0 #define LUA_NANTRICK - /* pentium 32 bits? */ #elif defined(__i386__) || defined(__i386) || defined(__X86__) /* }{ */ #define LUA_IEEE754TRICK #define LUA_IEEELL -#define LUA_IEEEENDIAN 0 +#define LUA_IEEEENDIAN 0 #define LUA_NANTRICK /* pentium 64 bits? */ -#elif defined(__x86_64) /* }{ */ +#elif defined(__x86_64) /* }{ */ #define LUA_IEEE754TRICK -#define LUA_IEEEENDIAN 0 +#define LUA_IEEEENDIAN 0 -#elif defined(__POWERPC__) || defined(__ppc__) /* }{ */ +#elif defined(__POWERPC__) || defined(__ppc__) /* }{ */ #define LUA_IEEE754TRICK -#define LUA_IEEEENDIAN 1 +#define LUA_IEEEENDIAN 1 -#else /* }{ */ +#else /* }{ */ /* assume IEEE754 and a 32-bit integer type */ #define LUA_IEEE754TRICK -#endif /* } */ +#endif /* } */ -#endif /* } */ +#endif /* } */ /* }================================================================== */ - - - /* =================================================================== */ /* @@ -545,7 +506,4 @@ ** without modifying the main part of the file. */ - - #endif - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lualib.h b/examples/ThirdPartyLibs/lua-5.2.3/src/lualib.h index da82005c9..f183bab0a 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lualib.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lualib.h @@ -4,52 +4,45 @@ ** See Copyright Notice in lua.h */ - #ifndef lualib_h #define lualib_h #include "lua.h" +LUAMOD_API int(luaopen_base)(lua_State *L); +#define LUA_COLIBNAME "coroutine" +LUAMOD_API int(luaopen_coroutine)(lua_State *L); -LUAMOD_API int (luaopen_base) (lua_State *L); +#define LUA_TABLIBNAME "table" +LUAMOD_API int(luaopen_table)(lua_State *L); -#define LUA_COLIBNAME "coroutine" -LUAMOD_API int (luaopen_coroutine) (lua_State *L); +#define LUA_IOLIBNAME "io" +LUAMOD_API int(luaopen_io)(lua_State *L); -#define LUA_TABLIBNAME "table" -LUAMOD_API int (luaopen_table) (lua_State *L); +#define LUA_OSLIBNAME "os" +LUAMOD_API int(luaopen_os)(lua_State *L); -#define LUA_IOLIBNAME "io" -LUAMOD_API int (luaopen_io) (lua_State *L); +#define LUA_STRLIBNAME "string" +LUAMOD_API int(luaopen_string)(lua_State *L); -#define LUA_OSLIBNAME "os" -LUAMOD_API int (luaopen_os) (lua_State *L); +#define LUA_BITLIBNAME "bit32" +LUAMOD_API int(luaopen_bit32)(lua_State *L); -#define LUA_STRLIBNAME "string" -LUAMOD_API int (luaopen_string) (lua_State *L); +#define LUA_MATHLIBNAME "math" +LUAMOD_API int(luaopen_math)(lua_State *L); -#define LUA_BITLIBNAME "bit32" -LUAMOD_API int (luaopen_bit32) (lua_State *L); - -#define LUA_MATHLIBNAME "math" -LUAMOD_API int (luaopen_math) (lua_State *L); - -#define LUA_DBLIBNAME "debug" -LUAMOD_API int (luaopen_debug) (lua_State *L); - -#define LUA_LOADLIBNAME "package" -LUAMOD_API int (luaopen_package) (lua_State *L); +#define LUA_DBLIBNAME "debug" +LUAMOD_API int(luaopen_debug)(lua_State *L); +#define LUA_LOADLIBNAME "package" +LUAMOD_API int(luaopen_package)(lua_State *L); /* open all previous libraries */ -LUALIB_API void (luaL_openlibs) (lua_State *L); - - +LUALIB_API void(luaL_openlibs)(lua_State *L); #if !defined(lua_assert) -#define lua_assert(x) ((void)0) +#define lua_assert(x) ((void)0) #endif - #endif diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lundump.c b/examples/ThirdPartyLibs/lua-5.2.3/src/lundump.c index 4163cb5d3..cb316a8a1 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lundump.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lundump.c @@ -20,239 +20,245 @@ #include "lundump.h" #include "lzio.h" -typedef struct { - lua_State* L; - ZIO* Z; - Mbuffer* b; - const char* name; +typedef struct +{ + lua_State* L; + ZIO* Z; + Mbuffer* b; + const char* name; } LoadState; static l_noret error(LoadState* S, const char* why) { - luaO_pushfstring(S->L,"%s: %s precompiled chunk",S->name,why); - luaD_throw(S->L,LUA_ERRSYNTAX); + luaO_pushfstring(S->L, "%s: %s precompiled chunk", S->name, why); + luaD_throw(S->L, LUA_ERRSYNTAX); } -#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size)) -#define LoadByte(S) (lu_byte)LoadChar(S) -#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x)) -#define LoadVector(S,b,n,size) LoadMem(S,b,n,size) +#define LoadMem(S, b, n, size) LoadBlock(S, b, (n) * (size)) +#define LoadByte(S) (lu_byte) LoadChar(S) +#define LoadVar(S, x) LoadMem(S, &x, 1, sizeof(x)) +#define LoadVector(S, b, n, size) LoadMem(S, b, n, size) #if !defined(luai_verifycode) -#define luai_verifycode(L,b,f) /* empty */ +#define luai_verifycode(L, b, f) /* empty */ #endif static void LoadBlock(LoadState* S, void* b, size_t size) { - if (luaZ_read(S->Z,b,size)!=0) error(S,"truncated"); + if (luaZ_read(S->Z, b, size) != 0) error(S, "truncated"); } static int LoadChar(LoadState* S) { - char x; - LoadVar(S,x); - return x; + char x; + LoadVar(S, x); + return x; } static int LoadInt(LoadState* S) { - int x; - LoadVar(S,x); - if (x<0) error(S,"corrupted"); - return x; + int x; + LoadVar(S, x); + if (x < 0) error(S, "corrupted"); + return x; } static lua_Number LoadNumber(LoadState* S) { - lua_Number x; - LoadVar(S,x); - return x; + lua_Number x; + LoadVar(S, x); + return x; } static TString* LoadString(LoadState* S) { - size_t size; - LoadVar(S,size); - if (size==0) - return NULL; - else - { - char* s=luaZ_openspace(S->L,S->b,size); - LoadBlock(S,s,size*sizeof(char)); - return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ - } + size_t size; + LoadVar(S, size); + if (size == 0) + return NULL; + else + { + char* s = luaZ_openspace(S->L, S->b, size); + LoadBlock(S, s, size * sizeof(char)); + return luaS_newlstr(S->L, s, size - 1); /* remove trailing '\0' */ + } } static void LoadCode(LoadState* S, Proto* f) { - int n=LoadInt(S); - f->code=luaM_newvector(S->L,n,Instruction); - f->sizecode=n; - LoadVector(S,f->code,n,sizeof(Instruction)); + int n = LoadInt(S); + f->code = luaM_newvector(S->L, n, Instruction); + f->sizecode = n; + LoadVector(S, f->code, n, sizeof(Instruction)); } static void LoadFunction(LoadState* S, Proto* f); static void LoadConstants(LoadState* S, Proto* f) { - int i,n; - n=LoadInt(S); - f->k=luaM_newvector(S->L,n,TValue); - f->sizek=n; - for (i=0; ik[i]); - for (i=0; ik[i]; - int t=LoadChar(S); - switch (t) - { - case LUA_TNIL: - setnilvalue(o); - break; - case LUA_TBOOLEAN: - setbvalue(o,LoadChar(S)); - break; - case LUA_TNUMBER: - setnvalue(o,LoadNumber(S)); - break; - case LUA_TSTRING: - setsvalue2n(S->L,o,LoadString(S)); - break; - default: lua_assert(0); - } - } - n=LoadInt(S); - f->p=luaM_newvector(S->L,n,Proto*); - f->sizep=n; - for (i=0; ip[i]=NULL; - for (i=0; ip[i]=luaF_newproto(S->L); - LoadFunction(S,f->p[i]); - } + int i, n; + n = LoadInt(S); + f->k = luaM_newvector(S->L, n, TValue); + f->sizek = n; + for (i = 0; i < n; i++) setnilvalue(&f->k[i]); + for (i = 0; i < n; i++) + { + TValue* o = &f->k[i]; + int t = LoadChar(S); + switch (t) + { + case LUA_TNIL: + setnilvalue(o); + break; + case LUA_TBOOLEAN: + setbvalue(o, LoadChar(S)); + break; + case LUA_TNUMBER: + setnvalue(o, LoadNumber(S)); + break; + case LUA_TSTRING: + setsvalue2n(S->L, o, LoadString(S)); + break; + default: + lua_assert(0); + } + } + n = LoadInt(S); + f->p = luaM_newvector(S->L, n, Proto*); + f->sizep = n; + for (i = 0; i < n; i++) f->p[i] = NULL; + for (i = 0; i < n; i++) + { + f->p[i] = luaF_newproto(S->L); + LoadFunction(S, f->p[i]); + } } static void LoadUpvalues(LoadState* S, Proto* f) { - int i,n; - n=LoadInt(S); - f->upvalues=luaM_newvector(S->L,n,Upvaldesc); - f->sizeupvalues=n; - for (i=0; iupvalues[i].name=NULL; - for (i=0; iupvalues[i].instack=LoadByte(S); - f->upvalues[i].idx=LoadByte(S); - } + int i, n; + n = LoadInt(S); + f->upvalues = luaM_newvector(S->L, n, Upvaldesc); + f->sizeupvalues = n; + for (i = 0; i < n; i++) f->upvalues[i].name = NULL; + for (i = 0; i < n; i++) + { + f->upvalues[i].instack = LoadByte(S); + f->upvalues[i].idx = LoadByte(S); + } } static void LoadDebug(LoadState* S, Proto* f) { - int i,n; - f->source=LoadString(S); - n=LoadInt(S); - f->lineinfo=luaM_newvector(S->L,n,int); - f->sizelineinfo=n; - LoadVector(S,f->lineinfo,n,sizeof(int)); - n=LoadInt(S); - f->locvars=luaM_newvector(S->L,n,LocVar); - f->sizelocvars=n; - for (i=0; ilocvars[i].varname=NULL; - for (i=0; ilocvars[i].varname=LoadString(S); - f->locvars[i].startpc=LoadInt(S); - f->locvars[i].endpc=LoadInt(S); - } - n=LoadInt(S); - for (i=0; iupvalues[i].name=LoadString(S); + int i, n; + f->source = LoadString(S); + n = LoadInt(S); + f->lineinfo = luaM_newvector(S->L, n, int); + f->sizelineinfo = n; + LoadVector(S, f->lineinfo, n, sizeof(int)); + n = LoadInt(S); + f->locvars = luaM_newvector(S->L, n, LocVar); + f->sizelocvars = n; + for (i = 0; i < n; i++) f->locvars[i].varname = NULL; + for (i = 0; i < n; i++) + { + f->locvars[i].varname = LoadString(S); + f->locvars[i].startpc = LoadInt(S); + f->locvars[i].endpc = LoadInt(S); + } + n = LoadInt(S); + for (i = 0; i < n; i++) f->upvalues[i].name = LoadString(S); } static void LoadFunction(LoadState* S, Proto* f) { - f->linedefined=LoadInt(S); - f->lastlinedefined=LoadInt(S); - f->numparams=LoadByte(S); - f->is_vararg=LoadByte(S); - f->maxstacksize=LoadByte(S); - LoadCode(S,f); - LoadConstants(S,f); - LoadUpvalues(S,f); - LoadDebug(S,f); + f->linedefined = LoadInt(S); + f->lastlinedefined = LoadInt(S); + f->numparams = LoadByte(S); + f->is_vararg = LoadByte(S); + f->maxstacksize = LoadByte(S); + LoadCode(S, f); + LoadConstants(S, f); + LoadUpvalues(S, f); + LoadDebug(S, f); } /* the code below must be consistent with the code in luaU_header */ -#define N0 LUAC_HEADERSIZE -#define N1 (sizeof(LUA_SIGNATURE)-sizeof(char)) -#define N2 N1+2 -#define N3 N2+6 +#define N0 LUAC_HEADERSIZE +#define N1 (sizeof(LUA_SIGNATURE) - sizeof(char)) +#define N2 N1 + 2 +#define N3 N2 + 6 static void LoadHeader(LoadState* S) { - lu_byte h[LUAC_HEADERSIZE]; - lu_byte s[LUAC_HEADERSIZE]; - luaU_header(h); - memcpy(s,h,sizeof(char)); /* first char already read */ - LoadBlock(S,s+sizeof(char),LUAC_HEADERSIZE-sizeof(char)); - if (memcmp(h,s,N0)==0) return; - if (memcmp(h,s,N1)!=0) error(S,"not a"); - if (memcmp(h,s,N2)!=0) error(S,"version mismatch in"); - if (memcmp(h,s,N3)!=0) error(S,"incompatible"); else error(S,"corrupted"); + lu_byte h[LUAC_HEADERSIZE]; + lu_byte s[LUAC_HEADERSIZE]; + luaU_header(h); + memcpy(s, h, sizeof(char)); /* first char already read */ + LoadBlock(S, s + sizeof(char), LUAC_HEADERSIZE - sizeof(char)); + if (memcmp(h, s, N0) == 0) return; + if (memcmp(h, s, N1) != 0) error(S, "not a"); + if (memcmp(h, s, N2) != 0) error(S, "version mismatch in"); + if (memcmp(h, s, N3) != 0) + error(S, "incompatible"); + else + error(S, "corrupted"); } /* ** load precompiled chunk */ -Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) +Closure* luaU_undump(lua_State* L, ZIO* Z, Mbuffer* buff, const char* name) { - LoadState S; - Closure* cl; - if (*name=='@' || *name=='=') - S.name=name+1; - else if (*name==LUA_SIGNATURE[0]) - S.name="binary string"; - else - S.name=name; - S.L=L; - S.Z=Z; - S.b=buff; - LoadHeader(&S); - cl=luaF_newLclosure(L,1); - setclLvalue(L,L->top,cl); incr_top(L); - cl->l.p=luaF_newproto(L); - LoadFunction(&S,cl->l.p); - if (cl->l.p->sizeupvalues != 1) - { - Proto* p=cl->l.p; - cl=luaF_newLclosure(L,cl->l.p->sizeupvalues); - cl->l.p=p; - setclLvalue(L,L->top-1,cl); - } - luai_verifycode(L,buff,cl->l.p); - return cl; + LoadState S; + Closure* cl; + if (*name == '@' || *name == '=') + S.name = name + 1; + else if (*name == LUA_SIGNATURE[0]) + S.name = "binary string"; + else + S.name = name; + S.L = L; + S.Z = Z; + S.b = buff; + LoadHeader(&S); + cl = luaF_newLclosure(L, 1); + setclLvalue(L, L->top, cl); + incr_top(L); + cl->l.p = luaF_newproto(L); + LoadFunction(&S, cl->l.p); + if (cl->l.p->sizeupvalues != 1) + { + Proto* p = cl->l.p; + cl = luaF_newLclosure(L, cl->l.p->sizeupvalues); + cl->l.p = p; + setclLvalue(L, L->top - 1, cl); + } + luai_verifycode(L, buff, cl->l.p); + return cl; } -#define MYINT(s) (s[0]-'0') -#define VERSION MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR) -#define FORMAT 0 /* this is the official format */ +#define MYINT(s) (s[0] - '0') +#define VERSION MYINT(LUA_VERSION_MAJOR) * 16 + MYINT(LUA_VERSION_MINOR) +#define FORMAT 0 /* this is the official format */ /* * make header for precompiled chunks * if you change the code below be sure to update LoadHeader and FORMAT above * and LUAC_HEADERSIZE in lundump.h */ -void luaU_header (lu_byte* h) +void luaU_header(lu_byte* h) { - int x=1; - memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-sizeof(char)); - h+=sizeof(LUA_SIGNATURE)-sizeof(char); - *h++=cast_byte(VERSION); - *h++=cast_byte(FORMAT); - *h++=cast_byte(*(char*)&x); /* endianness */ - *h++=cast_byte(sizeof(int)); - *h++=cast_byte(sizeof(size_t)); - *h++=cast_byte(sizeof(Instruction)); - *h++=cast_byte(sizeof(lua_Number)); - *h++=cast_byte(((lua_Number)0.5)==0); /* is lua_Number integral? */ - memcpy(h,LUAC_TAIL,sizeof(LUAC_TAIL)-sizeof(char)); + int x = 1; + memcpy(h, LUA_SIGNATURE, sizeof(LUA_SIGNATURE) - sizeof(char)); + h += sizeof(LUA_SIGNATURE) - sizeof(char); + *h++ = cast_byte(VERSION); + *h++ = cast_byte(FORMAT); + *h++ = cast_byte(*(char*)&x); /* endianness */ + *h++ = cast_byte(sizeof(int)); + *h++ = cast_byte(sizeof(size_t)); + *h++ = cast_byte(sizeof(Instruction)); + *h++ = cast_byte(sizeof(lua_Number)); + *h++ = cast_byte(((lua_Number)0.5) == 0); /* is lua_Number integral? */ + memcpy(h, LUAC_TAIL, sizeof(LUAC_TAIL) - sizeof(char)); } diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lundump.h b/examples/ThirdPartyLibs/lua-5.2.3/src/lundump.h index 5255db259..7a4c50e74 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lundump.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lundump.h @@ -11,18 +11,18 @@ #include "lzio.h" /* load one chunk; from lundump.c */ -LUAI_FUNC Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); +LUAI_FUNC Closure* luaU_undump(lua_State* L, ZIO* Z, Mbuffer* buff, const char* name); /* make header; from lundump.c */ -LUAI_FUNC void luaU_header (lu_byte* h); +LUAI_FUNC void luaU_header(lu_byte* h); /* dump one chunk; from ldump.c */ -LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); +LUAI_FUNC int luaU_dump(lua_State* L, const Proto* f, lua_Writer w, void* data, int strip); /* data to catch conversion errors */ -#define LUAC_TAIL "\x19\x93\r\n\x1a\n" +#define LUAC_TAIL "\x19\x93\r\n\x1a\n" /* size in bytes of header of binary files */ -#define LUAC_HEADERSIZE (sizeof(LUA_SIGNATURE)-sizeof(char)+2+6+sizeof(LUAC_TAIL)-sizeof(char)) +#define LUAC_HEADERSIZE (sizeof(LUA_SIGNATURE) - sizeof(char) + 2 + 6 + sizeof(LUAC_TAIL) - sizeof(char)) #endif diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lvm.c b/examples/ThirdPartyLibs/lua-5.2.3/src/lvm.c index 141b9fd19..26fad26ac 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lvm.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lvm.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #include #include #include @@ -26,842 +25,733 @@ #include "ltm.h" #include "lvm.h" - - /* limit for table tag-method chains (to avoid loops) */ -#define MAXTAGLOOP 100 +#define MAXTAGLOOP 100 - -const TValue *luaV_tonumber (const TValue *obj, TValue *n) { - lua_Number num; - if (ttisnumber(obj)) return obj; - if (ttisstring(obj) && luaO_str2d(svalue(obj), tsvalue(obj)->len, &num)) { - setnvalue(n, num); - return n; - } - else - return NULL; +const TValue *luaV_tonumber(const TValue *obj, TValue *n) +{ + lua_Number num; + if (ttisnumber(obj)) return obj; + if (ttisstring(obj) && luaO_str2d(svalue(obj), tsvalue(obj)->len, &num)) + { + setnvalue(n, num); + return n; + } + else + return NULL; } - -int luaV_tostring (lua_State *L, StkId obj) { - if (!ttisnumber(obj)) - return 0; - else { - char s[LUAI_MAXNUMBER2STR]; - lua_Number n = nvalue(obj); - int l = lua_number2str(s, n); - setsvalue2s(L, obj, luaS_newlstr(L, s, l)); - return 1; - } +int luaV_tostring(lua_State *L, StkId obj) +{ + if (!ttisnumber(obj)) + return 0; + else + { + char s[LUAI_MAXNUMBER2STR]; + lua_Number n = nvalue(obj); + int l = lua_number2str(s, n); + setsvalue2s(L, obj, luaS_newlstr(L, s, l)); + return 1; + } } - -static void traceexec (lua_State *L) { - CallInfo *ci = L->ci; - lu_byte mask = L->hookmask; - int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0); - if (counthook) - resethookcount(L); /* reset count */ - if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ - ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ - return; /* do not call hook again (VM yielded, so it did not move) */ - } - if (counthook) - luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ - if (mask & LUA_MASKLINE) { - Proto *p = ci_func(ci)->p; - int npc = pcRel(ci->u.l.savedpc, p); - int newline = getfuncline(p, npc); - if (npc == 0 || /* call linehook when enter a new function, */ - ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ - newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ - luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ - } - L->oldpc = ci->u.l.savedpc; - if (L->status == LUA_YIELD) { /* did hook yield? */ - if (counthook) - L->hookcount = 1; /* undo decrement to zero */ - ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ - ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ - ci->func = L->top - 1; /* protect stack below results */ - luaD_throw(L, LUA_YIELD); - } +static void traceexec(lua_State *L) +{ + CallInfo *ci = L->ci; + lu_byte mask = L->hookmask; + int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0); + if (counthook) + resethookcount(L); /* reset count */ + if (ci->callstatus & CIST_HOOKYIELD) + { /* called hook last time? */ + ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ + return; /* do not call hook again (VM yielded, so it did not move) */ + } + if (counthook) + luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */ + if (mask & LUA_MASKLINE) + { + Proto *p = ci_func(ci)->p; + int npc = pcRel(ci->u.l.savedpc, p); + int newline = getfuncline(p, npc); + if (npc == 0 || /* call linehook when enter a new function, */ + ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */ + newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */ + luaD_hook(L, LUA_HOOKLINE, newline); /* call line hook */ + } + L->oldpc = ci->u.l.savedpc; + if (L->status == LUA_YIELD) + { /* did hook yield? */ + if (counthook) + L->hookcount = 1; /* undo decrement to zero */ + ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ + ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ + ci->func = L->top - 1; /* protect stack below results */ + luaD_throw(L, LUA_YIELD); + } } - -static void callTM (lua_State *L, const TValue *f, const TValue *p1, - const TValue *p2, TValue *p3, int hasres) { - ptrdiff_t result = savestack(L, p3); - setobj2s(L, L->top++, f); /* push function */ - setobj2s(L, L->top++, p1); /* 1st argument */ - setobj2s(L, L->top++, p2); /* 2nd argument */ - if (!hasres) /* no result? 'p3' is third argument */ - setobj2s(L, L->top++, p3); /* 3rd argument */ - /* metamethod may yield only when called from Lua code */ - luaD_call(L, L->top - (4 - hasres), hasres, isLua(L->ci)); - if (hasres) { /* if has result, move it to its place */ - p3 = restorestack(L, result); - setobjs2s(L, p3, --L->top); - } +static void callTM(lua_State *L, const TValue *f, const TValue *p1, + const TValue *p2, TValue *p3, int hasres) +{ + ptrdiff_t result = savestack(L, p3); + setobj2s(L, L->top++, f); /* push function */ + setobj2s(L, L->top++, p1); /* 1st argument */ + setobj2s(L, L->top++, p2); /* 2nd argument */ + if (!hasres) /* no result? 'p3' is third argument */ + setobj2s(L, L->top++, p3); /* 3rd argument */ + /* metamethod may yield only when called from Lua code */ + luaD_call(L, L->top - (4 - hasres), hasres, isLua(L->ci)); + if (hasres) + { /* if has result, move it to its place */ + p3 = restorestack(L, result); + setobjs2s(L, p3, --L->top); + } } - -void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { - int loop; - for (loop = 0; loop < MAXTAGLOOP; loop++) { - const TValue *tm; - if (ttistable(t)) { /* `t' is a table? */ - Table *h = hvalue(t); - const TValue *res = luaH_get(h, key); /* do a primitive get */ - if (!ttisnil(res) || /* result is not nil? */ - (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */ - setobj2s(L, val, res); - return; - } - /* else will try the tag method */ - } - else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) - luaG_typeerror(L, t, "index"); - if (ttisfunction(tm)) { - callTM(L, tm, t, key, val, 1); - return; - } - t = tm; /* else repeat with 'tm' */ - } - luaG_runerror(L, "loop in gettable"); +void luaV_gettable(lua_State *L, const TValue *t, TValue *key, StkId val) +{ + int loop; + for (loop = 0; loop < MAXTAGLOOP; loop++) + { + const TValue *tm; + if (ttistable(t)) + { /* `t' is a table? */ + Table *h = hvalue(t); + const TValue *res = luaH_get(h, key); /* do a primitive get */ + if (!ttisnil(res) || /* result is not nil? */ + (tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) + { /* or no TM? */ + setobj2s(L, val, res); + return; + } + /* else will try the tag method */ + } + else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX))) + luaG_typeerror(L, t, "index"); + if (ttisfunction(tm)) + { + callTM(L, tm, t, key, val, 1); + return; + } + t = tm; /* else repeat with 'tm' */ + } + luaG_runerror(L, "loop in gettable"); } - -void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { - int loop; - for (loop = 0; loop < MAXTAGLOOP; loop++) { - const TValue *tm; - if (ttistable(t)) { /* `t' is a table? */ - Table *h = hvalue(t); - TValue *oldval = cast(TValue *, luaH_get(h, key)); - /* if previous value is not nil, there must be a previous entry +void luaV_settable(lua_State *L, const TValue *t, TValue *key, StkId val) +{ + int loop; + for (loop = 0; loop < MAXTAGLOOP; loop++) + { + const TValue *tm; + if (ttistable(t)) + { /* `t' is a table? */ + Table *h = hvalue(t); + TValue *oldval = cast(TValue *, luaH_get(h, key)); + /* if previous value is not nil, there must be a previous entry in the table; moreover, a metamethod has no relevance */ - if (!ttisnil(oldval) || - /* previous value is nil; must check the metamethod */ - ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL && - /* no metamethod; is there a previous entry in the table? */ - (oldval != luaO_nilobject || - /* no previous entry; must create one. (The next test is + if (!ttisnil(oldval) || + /* previous value is nil; must check the metamethod */ + ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL && + /* no metamethod; is there a previous entry in the table? */ + (oldval != luaO_nilobject || + /* no previous entry; must create one. (The next test is always true; we only need the assignment.) */ - (oldval = luaH_newkey(L, h, key), 1)))) { - /* no metamethod and (now) there is an entry with given key */ - setobj2t(L, oldval, val); /* assign new value to that entry */ - invalidateTMcache(h); - luaC_barrierback(L, obj2gco(h), val); - return; - } - /* else will try the metamethod */ - } - else /* not a table; check metamethod */ - if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) - luaG_typeerror(L, t, "index"); - /* there is a metamethod */ - if (ttisfunction(tm)) { - callTM(L, tm, t, key, val, 0); - return; - } - t = tm; /* else repeat with 'tm' */ - } - luaG_runerror(L, "loop in settable"); + (oldval = luaH_newkey(L, h, key), 1)))) + { + /* no metamethod and (now) there is an entry with given key */ + setobj2t(L, oldval, val); /* assign new value to that entry */ + invalidateTMcache(h); + luaC_barrierback(L, obj2gco(h), val); + return; + } + /* else will try the metamethod */ + } + else /* not a table; check metamethod */ + if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) + luaG_typeerror(L, t, "index"); + /* there is a metamethod */ + if (ttisfunction(tm)) + { + callTM(L, tm, t, key, val, 0); + return; + } + t = tm; /* else repeat with 'tm' */ + } + luaG_runerror(L, "loop in settable"); } - -static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2, - StkId res, TMS event) { - const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ - if (ttisnil(tm)) - tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ - if (ttisnil(tm)) return 0; - callTM(L, tm, p1, p2, res, 1); - return 1; +static int call_binTM(lua_State *L, const TValue *p1, const TValue *p2, + StkId res, TMS event) +{ + const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ + if (ttisnil(tm)) + tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ + if (ttisnil(tm)) return 0; + callTM(L, tm, p1, p2, res, 1); + return 1; } - -static const TValue *get_equalTM (lua_State *L, Table *mt1, Table *mt2, - TMS event) { - const TValue *tm1 = fasttm(L, mt1, event); - const TValue *tm2; - if (tm1 == NULL) return NULL; /* no metamethod */ - if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ - tm2 = fasttm(L, mt2, event); - if (tm2 == NULL) return NULL; /* no metamethod */ - if (luaV_rawequalobj(tm1, tm2)) /* same metamethods? */ - return tm1; - return NULL; +static const TValue *get_equalTM(lua_State *L, Table *mt1, Table *mt2, + TMS event) +{ + const TValue *tm1 = fasttm(L, mt1, event); + const TValue *tm2; + if (tm1 == NULL) return NULL; /* no metamethod */ + if (mt1 == mt2) return tm1; /* same metatables => same metamethods */ + tm2 = fasttm(L, mt2, event); + if (tm2 == NULL) return NULL; /* no metamethod */ + if (luaV_rawequalobj(tm1, tm2)) /* same metamethods? */ + return tm1; + return NULL; } - -static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2, - TMS event) { - if (!call_binTM(L, p1, p2, L->top, event)) - return -1; /* no metamethod */ - else - return !l_isfalse(L->top); +static int call_orderTM(lua_State *L, const TValue *p1, const TValue *p2, + TMS event) +{ + if (!call_binTM(L, p1, p2, L->top, event)) + return -1; /* no metamethod */ + else + return !l_isfalse(L->top); } - -static int l_strcmp (const TString *ls, const TString *rs) { - const char *l = getstr(ls); - size_t ll = ls->tsv.len; - const char *r = getstr(rs); - size_t lr = rs->tsv.len; - for (;;) { - int temp = strcoll(l, r); - if (temp != 0) return temp; - else { /* strings are equal up to a `\0' */ - size_t len = strlen(l); /* index of first `\0' in both strings */ - if (len == lr) /* r is finished? */ - return (len == ll) ? 0 : 1; - else if (len == ll) /* l is finished? */ - return -1; /* l is smaller than r (because r is not finished) */ - /* both strings longer than `len'; go on comparing (after the `\0') */ - len++; - l += len; ll -= len; r += len; lr -= len; - } - } +static int l_strcmp(const TString *ls, const TString *rs) +{ + const char *l = getstr(ls); + size_t ll = ls->tsv.len; + const char *r = getstr(rs); + size_t lr = rs->tsv.len; + for (;;) + { + int temp = strcoll(l, r); + if (temp != 0) + return temp; + else + { /* strings are equal up to a `\0' */ + size_t len = strlen(l); /* index of first `\0' in both strings */ + if (len == lr) /* r is finished? */ + return (len == ll) ? 0 : 1; + else if (len == ll) /* l is finished? */ + return -1; /* l is smaller than r (because r is not finished) */ + /* both strings longer than `len'; go on comparing (after the `\0') */ + len++; + l += len; + ll -= len; + r += len; + lr -= len; + } + } } - -int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { - int res; - if (ttisnumber(l) && ttisnumber(r)) - return luai_numlt(L, nvalue(l), nvalue(r)); - else if (ttisstring(l) && ttisstring(r)) - return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; - else if ((res = call_orderTM(L, l, r, TM_LT)) < 0) - luaG_ordererror(L, l, r); - return res; +int luaV_lessthan(lua_State *L, const TValue *l, const TValue *r) +{ + int res; + if (ttisnumber(l) && ttisnumber(r)) + return luai_numlt(L, nvalue(l), nvalue(r)); + else if (ttisstring(l) && ttisstring(r)) + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0; + else if ((res = call_orderTM(L, l, r, TM_LT)) < 0) + luaG_ordererror(L, l, r); + return res; } - -int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { - int res; - if (ttisnumber(l) && ttisnumber(r)) - return luai_numle(L, nvalue(l), nvalue(r)); - else if (ttisstring(l) && ttisstring(r)) - return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; - else if ((res = call_orderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */ - return res; - else if ((res = call_orderTM(L, r, l, TM_LT)) < 0) /* else try `lt' */ - luaG_ordererror(L, l, r); - return !res; +int luaV_lessequal(lua_State *L, const TValue *l, const TValue *r) +{ + int res; + if (ttisnumber(l) && ttisnumber(r)) + return luai_numle(L, nvalue(l), nvalue(r)); + else if (ttisstring(l) && ttisstring(r)) + return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0; + else if ((res = call_orderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */ + return res; + else if ((res = call_orderTM(L, r, l, TM_LT)) < 0) /* else try `lt' */ + luaG_ordererror(L, l, r); + return !res; } - /* ** equality of Lua values. L == NULL means raw equality (no metamethods) */ -int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2) { - const TValue *tm; - lua_assert(ttisequal(t1, t2)); - switch (ttype(t1)) { - case LUA_TNIL: return 1; - case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2)); - case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ - case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2); - case LUA_TLCF: return fvalue(t1) == fvalue(t2); - case LUA_TSHRSTR: return eqshrstr(rawtsvalue(t1), rawtsvalue(t2)); - case LUA_TLNGSTR: return luaS_eqlngstr(rawtsvalue(t1), rawtsvalue(t2)); - case LUA_TUSERDATA: { - if (uvalue(t1) == uvalue(t2)) return 1; - else if (L == NULL) return 0; - tm = get_equalTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ); - break; /* will try TM */ - } - case LUA_TTABLE: { - if (hvalue(t1) == hvalue(t2)) return 1; - else if (L == NULL) return 0; - tm = get_equalTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); - break; /* will try TM */ - } - default: - lua_assert(iscollectable(t1)); - return gcvalue(t1) == gcvalue(t2); - } - if (tm == NULL) return 0; /* no TM? */ - callTM(L, tm, t1, t2, L->top, 1); /* call TM */ - return !l_isfalse(L->top); +int luaV_equalobj_(lua_State *L, const TValue *t1, const TValue *t2) +{ + const TValue *tm; + lua_assert(ttisequal(t1, t2)); + switch (ttype(t1)) + { + case LUA_TNIL: + return 1; + case LUA_TNUMBER: + return luai_numeq(nvalue(t1), nvalue(t2)); + case LUA_TBOOLEAN: + return bvalue(t1) == bvalue(t2); /* true must be 1 !! */ + case LUA_TLIGHTUSERDATA: + return pvalue(t1) == pvalue(t2); + case LUA_TLCF: + return fvalue(t1) == fvalue(t2); + case LUA_TSHRSTR: + return eqshrstr(rawtsvalue(t1), rawtsvalue(t2)); + case LUA_TLNGSTR: + return luaS_eqlngstr(rawtsvalue(t1), rawtsvalue(t2)); + case LUA_TUSERDATA: + { + if (uvalue(t1) == uvalue(t2)) + return 1; + else if (L == NULL) + return 0; + tm = get_equalTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ); + break; /* will try TM */ + } + case LUA_TTABLE: + { + if (hvalue(t1) == hvalue(t2)) + return 1; + else if (L == NULL) + return 0; + tm = get_equalTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ); + break; /* will try TM */ + } + default: + lua_assert(iscollectable(t1)); + return gcvalue(t1) == gcvalue(t2); + } + if (tm == NULL) return 0; /* no TM? */ + callTM(L, tm, t1, t2, L->top, 1); /* call TM */ + return !l_isfalse(L->top); } - -void luaV_concat (lua_State *L, int total) { - lua_assert(total >= 2); - do { - StkId top = L->top; - int n = 2; /* number of elements handled in this pass (at least 2) */ - if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) { - if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT)) - luaG_concaterror(L, top-2, top-1); - } - else if (tsvalue(top-1)->len == 0) /* second operand is empty? */ - (void)tostring(L, top - 2); /* result is first operand */ - else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) { - setobjs2s(L, top - 2, top - 1); /* result is second op. */ - } - else { - /* at least two non-empty string values; get as many as possible */ - size_t tl = tsvalue(top-1)->len; - char *buffer; - int i; - /* collect total length */ - for (i = 1; i < total && tostring(L, top-i-1); i++) { - size_t l = tsvalue(top-i-1)->len; - if (l >= (MAX_SIZET/sizeof(char)) - tl) - luaG_runerror(L, "string length overflow"); - tl += l; - } - buffer = luaZ_openspace(L, &G(L)->buff, tl); - tl = 0; - n = i; - do { /* concat all strings */ - size_t l = tsvalue(top-i)->len; - memcpy(buffer+tl, svalue(top-i), l * sizeof(char)); - tl += l; - } while (--i > 0); - setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl)); - } - total -= n-1; /* got 'n' strings to create 1 new */ - L->top -= n-1; /* popped 'n' strings and pushed one */ - } while (total > 1); /* repeat until only 1 result left */ +void luaV_concat(lua_State *L, int total) +{ + lua_assert(total >= 2); + do + { + StkId top = L->top; + int n = 2; /* number of elements handled in this pass (at least 2) */ + if (!(ttisstring(top - 2) || ttisnumber(top - 2)) || !tostring(L, top - 1)) + { + if (!call_binTM(L, top - 2, top - 1, top - 2, TM_CONCAT)) + luaG_concaterror(L, top - 2, top - 1); + } + else if (tsvalue(top - 1)->len == 0) /* second operand is empty? */ + (void)tostring(L, top - 2); /* result is first operand */ + else if (ttisstring(top - 2) && tsvalue(top - 2)->len == 0) + { + setobjs2s(L, top - 2, top - 1); /* result is second op. */ + } + else + { + /* at least two non-empty string values; get as many as possible */ + size_t tl = tsvalue(top - 1)->len; + char *buffer; + int i; + /* collect total length */ + for (i = 1; i < total && tostring(L, top - i - 1); i++) + { + size_t l = tsvalue(top - i - 1)->len; + if (l >= (MAX_SIZET / sizeof(char)) - tl) + luaG_runerror(L, "string length overflow"); + tl += l; + } + buffer = luaZ_openspace(L, &G(L)->buff, tl); + tl = 0; + n = i; + do + { /* concat all strings */ + size_t l = tsvalue(top - i)->len; + memcpy(buffer + tl, svalue(top - i), l * sizeof(char)); + tl += l; + } while (--i > 0); + setsvalue2s(L, top - n, luaS_newlstr(L, buffer, tl)); + } + total -= n - 1; /* got 'n' strings to create 1 new */ + L->top -= n - 1; /* popped 'n' strings and pushed one */ + } while (total > 1); /* repeat until only 1 result left */ } - -void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) { - const TValue *tm; - switch (ttypenv(rb)) { - case LUA_TTABLE: { - Table *h = hvalue(rb); - tm = fasttm(L, h->metatable, TM_LEN); - if (tm) break; /* metamethod? break switch to call it */ - setnvalue(ra, cast_num(luaH_getn(h))); /* else primitive len */ - return; - } - case LUA_TSTRING: { - setnvalue(ra, cast_num(tsvalue(rb)->len)); - return; - } - default: { /* try metamethod */ - tm = luaT_gettmbyobj(L, rb, TM_LEN); - if (ttisnil(tm)) /* no metamethod? */ - luaG_typeerror(L, rb, "get length of"); - break; - } - } - callTM(L, tm, rb, rb, ra, 1); +void luaV_objlen(lua_State *L, StkId ra, const TValue *rb) +{ + const TValue *tm; + switch (ttypenv(rb)) + { + case LUA_TTABLE: + { + Table *h = hvalue(rb); + tm = fasttm(L, h->metatable, TM_LEN); + if (tm) break; /* metamethod? break switch to call it */ + setnvalue(ra, cast_num(luaH_getn(h))); /* else primitive len */ + return; + } + case LUA_TSTRING: + { + setnvalue(ra, cast_num(tsvalue(rb)->len)); + return; + } + default: + { /* try metamethod */ + tm = luaT_gettmbyobj(L, rb, TM_LEN); + if (ttisnil(tm)) /* no metamethod? */ + luaG_typeerror(L, rb, "get length of"); + break; + } + } + callTM(L, tm, rb, rb, ra, 1); } - -void luaV_arith (lua_State *L, StkId ra, const TValue *rb, - const TValue *rc, TMS op) { - TValue tempb, tempc; - const TValue *b, *c; - if ((b = luaV_tonumber(rb, &tempb)) != NULL && - (c = luaV_tonumber(rc, &tempc)) != NULL) { - lua_Number res = luaO_arith(op - TM_ADD + LUA_OPADD, nvalue(b), nvalue(c)); - setnvalue(ra, res); - } - else if (!call_binTM(L, rb, rc, ra, op)) - luaG_aritherror(L, rb, rc); +void luaV_arith(lua_State *L, StkId ra, const TValue *rb, + const TValue *rc, TMS op) +{ + TValue tempb, tempc; + const TValue *b, *c; + if ((b = luaV_tonumber(rb, &tempb)) != NULL && + (c = luaV_tonumber(rc, &tempc)) != NULL) + { + lua_Number res = luaO_arith(op - TM_ADD + LUA_OPADD, nvalue(b), nvalue(c)); + setnvalue(ra, res); + } + else if (!call_binTM(L, rb, rc, ra, op)) + luaG_aritherror(L, rb, rc); } - /* ** check whether cached closure in prototype 'p' may be reused, that is, ** whether there is a cached closure with the same upvalues needed by ** new closure to be created. */ -static Closure *getcached (Proto *p, UpVal **encup, StkId base) { - Closure *c = p->cache; - if (c != NULL) { /* is there a cached closure? */ - int nup = p->sizeupvalues; - Upvaldesc *uv = p->upvalues; - int i; - for (i = 0; i < nup; i++) { /* check whether it has right upvalues */ - TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v; - if (c->l.upvals[i]->v != v) - return NULL; /* wrong upvalue; cannot reuse closure */ - } - } - return c; /* return cached closure (or NULL if no cached closure) */ +static Closure *getcached(Proto *p, UpVal **encup, StkId base) +{ + Closure *c = p->cache; + if (c != NULL) + { /* is there a cached closure? */ + int nup = p->sizeupvalues; + Upvaldesc *uv = p->upvalues; + int i; + for (i = 0; i < nup; i++) + { /* check whether it has right upvalues */ + TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v; + if (c->l.upvals[i]->v != v) + return NULL; /* wrong upvalue; cannot reuse closure */ + } + } + return c; /* return cached closure (or NULL if no cached closure) */ } - /* ** create a new Lua closure, push it in the stack, and initialize ** its upvalues. Note that the call to 'luaC_barrierproto' must come ** before the assignment to 'p->cache', as the function needs the ** original value of that field. */ -static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, - StkId ra) { - int nup = p->sizeupvalues; - Upvaldesc *uv = p->upvalues; - int i; - Closure *ncl = luaF_newLclosure(L, nup); - ncl->l.p = p; - setclLvalue(L, ra, ncl); /* anchor new closure in stack */ - for (i = 0; i < nup; i++) { /* fill in its upvalues */ - if (uv[i].instack) /* upvalue refers to local variable? */ - ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx); - else /* get upvalue from enclosing function */ - ncl->l.upvals[i] = encup[uv[i].idx]; - } - luaC_barrierproto(L, p, ncl); - p->cache = ncl; /* save it on cache for reuse */ +static void pushclosure(lua_State *L, Proto *p, UpVal **encup, StkId base, + StkId ra) +{ + int nup = p->sizeupvalues; + Upvaldesc *uv = p->upvalues; + int i; + Closure *ncl = luaF_newLclosure(L, nup); + ncl->l.p = p; + setclLvalue(L, ra, ncl); /* anchor new closure in stack */ + for (i = 0; i < nup; i++) + { /* fill in its upvalues */ + if (uv[i].instack) /* upvalue refers to local variable? */ + ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx); + else /* get upvalue from enclosing function */ + ncl->l.upvals[i] = encup[uv[i].idx]; + } + luaC_barrierproto(L, p, ncl); + p->cache = ncl; /* save it on cache for reuse */ } - /* ** finish execution of an opcode interrupted by an yield */ -void luaV_finishOp (lua_State *L) { - CallInfo *ci = L->ci; - StkId base = ci->u.l.base; - Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ - OpCode op = GET_OPCODE(inst); - switch (op) { /* finish its execution */ - case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: - case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN: - case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: { - setobjs2s(L, base + GETARG_A(inst), --L->top); - break; - } - case OP_LE: case OP_LT: case OP_EQ: { - int res = !l_isfalse(L->top - 1); - L->top--; - /* metamethod should not be called when operand is K */ - lua_assert(!ISK(GETARG_B(inst))); - if (op == OP_LE && /* "<=" using "<" instead? */ - ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE))) - res = !res; /* invert result */ - lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); - if (res != GETARG_A(inst)) /* condition failed? */ - ci->u.l.savedpc++; /* skip jump instruction */ - break; - } - case OP_CONCAT: { - StkId top = L->top - 1; /* top when 'call_binTM' was called */ - int b = GETARG_B(inst); /* first element to concatenate */ - int total = cast_int(top - 1 - (base + b)); /* yet to concatenate */ - setobj2s(L, top - 2, top); /* put TM result in proper position */ - if (total > 1) { /* are there elements to concat? */ - L->top = top - 1; /* top is one after last element (at top-2) */ - luaV_concat(L, total); /* concat them (may yield again) */ - } - /* move final result to final position */ - setobj2s(L, ci->u.l.base + GETARG_A(inst), L->top - 1); - L->top = ci->top; /* restore top */ - break; - } - case OP_TFORCALL: { - lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP); - L->top = ci->top; /* correct top */ - break; - } - case OP_CALL: { - if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */ - L->top = ci->top; /* adjust results */ - break; - } - case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE: - break; - default: lua_assert(0); - } +void luaV_finishOp(lua_State *L) +{ + CallInfo *ci = L->ci; + StkId base = ci->u.l.base; + Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */ + OpCode op = GET_OPCODE(inst); + switch (op) + { /* finish its execution */ + case OP_ADD: + case OP_SUB: + case OP_MUL: + case OP_DIV: + case OP_MOD: + case OP_POW: + case OP_UNM: + case OP_LEN: + case OP_GETTABUP: + case OP_GETTABLE: + case OP_SELF: + { + setobjs2s(L, base + GETARG_A(inst), --L->top); + break; + } + case OP_LE: + case OP_LT: + case OP_EQ: + { + int res = !l_isfalse(L->top - 1); + L->top--; + /* metamethod should not be called when operand is K */ + lua_assert(!ISK(GETARG_B(inst))); + if (op == OP_LE && /* "<=" using "<" instead? */ + ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE))) + res = !res; /* invert result */ + lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP); + if (res != GETARG_A(inst)) /* condition failed? */ + ci->u.l.savedpc++; /* skip jump instruction */ + break; + } + case OP_CONCAT: + { + StkId top = L->top - 1; /* top when 'call_binTM' was called */ + int b = GETARG_B(inst); /* first element to concatenate */ + int total = cast_int(top - 1 - (base + b)); /* yet to concatenate */ + setobj2s(L, top - 2, top); /* put TM result in proper position */ + if (total > 1) + { /* are there elements to concat? */ + L->top = top - 1; /* top is one after last element (at top-2) */ + luaV_concat(L, total); /* concat them (may yield again) */ + } + /* move final result to final position */ + setobj2s(L, ci->u.l.base + GETARG_A(inst), L->top - 1); + L->top = ci->top; /* restore top */ + break; + } + case OP_TFORCALL: + { + lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP); + L->top = ci->top; /* correct top */ + break; + } + case OP_CALL: + { + if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */ + L->top = ci->top; /* adjust results */ + break; + } + case OP_TAILCALL: + case OP_SETTABUP: + case OP_SETTABLE: + break; + default: + lua_assert(0); + } } - - /* ** some macros for common tasks in `luaV_execute' */ #if !defined luai_runtimecheck -#define luai_runtimecheck(L, c) /* void */ +#define luai_runtimecheck(L, c) /* void */ #endif - -#define RA(i) (base+GETARG_A(i)) +#define RA(i) (base + GETARG_A(i)) /* to be used after possible stack reallocation */ -#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base+GETARG_B(i)) -#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base+GETARG_C(i)) -#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ - ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i)) -#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ - ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i)) -#define KBx(i) \ - (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++))) - +#define RB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgR, base + GETARG_B(i)) +#define RC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgR, base + GETARG_C(i)) +#define RKB(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, \ + ISK(GETARG_B(i)) ? k + INDEXK(GETARG_B(i)) : base + GETARG_B(i)) +#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \ + ISK(GETARG_C(i)) ? k + INDEXK(GETARG_C(i)) : base + GETARG_C(i)) +#define KBx(i) \ + (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++))) /* execute a jump instruction */ -#define dojump(ci,i,e) \ - { int a = GETARG_A(i); \ - if (a > 0) luaF_close(L, ci->u.l.base + a - 1); \ - ci->u.l.savedpc += GETARG_sBx(i) + e; } +#define dojump(ci, i, e) \ + { \ + int a = GETARG_A(i); \ + if (a > 0) luaF_close(L, ci->u.l.base + a - 1); \ + ci->u.l.savedpc += GETARG_sBx(i) + e; \ + } /* for test instructions, execute the jump instruction that follows it */ -#define donextjump(ci) { i = *ci->u.l.savedpc; dojump(ci, i, 1); } +#define donextjump(ci) \ + { \ + i = *ci->u.l.savedpc; \ + dojump(ci, i, 1); \ + } +#define Protect(x) \ + { \ + { \ + x; \ + }; \ + base = ci->u.l.base; \ + } -#define Protect(x) { {x;}; base = ci->u.l.base; } - -#define checkGC(L,c) \ - Protect( luaC_condGC(L,{L->top = (c); /* limit of live values */ \ +#define checkGC(L, c) \ + Protect(luaC_condGC(L, {L->top = (c); /* limit of live values */ \ luaC_step(L); \ - L->top = ci->top;}) /* restore top */ \ - luai_threadyield(L); ) + L->top = ci->top; }) /* restore top */ \ + luai_threadyield(L);) +#define arith_op(op, tm) \ + { \ + TValue *rb = RKB(i); \ + TValue *rc = RKC(i); \ + if (ttisnumber(rb) && ttisnumber(rc)) \ + { \ + lua_Number nb = nvalue(rb), nc = nvalue(rc); \ + setnvalue(ra, op(L, nb, nc)); \ + } \ + else \ + { \ + Protect(luaV_arith(L, ra, rb, rc, tm)); \ + } \ + } -#define arith_op(op,tm) { \ - TValue *rb = RKB(i); \ - TValue *rc = RKC(i); \ - if (ttisnumber(rb) && ttisnumber(rc)) { \ - lua_Number nb = nvalue(rb), nc = nvalue(rc); \ - setnvalue(ra, op(L, nb, nc)); \ - } \ - else { Protect(luaV_arith(L, ra, rb, rc, tm)); } } +#define vmdispatch(o) switch (o) +#define vmcase(l, b) \ + case l: \ + { \ + b \ + } \ + break; +#define vmcasenb(l, b) \ + case l: \ + { \ + b \ + } /* nb = no break */ - -#define vmdispatch(o) switch(o) -#define vmcase(l,b) case l: {b} break; -#define vmcasenb(l,b) case l: {b} /* nb = no break */ - -void luaV_execute (lua_State *L) { - CallInfo *ci = L->ci; - LClosure *cl; - TValue *k; - StkId base; - newframe: /* reentry point when frame changes (call/return) */ - lua_assert(ci == L->ci); - cl = clLvalue(ci->func); - k = cl->p->k; - base = ci->u.l.base; - /* main loop of interpreter */ - for (;;) { - Instruction i = *(ci->u.l.savedpc++); - StkId ra; - if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && - (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) { - Protect(traceexec(L)); - } - /* WARNING: several calls may realloc the stack and invalidate `ra' */ - ra = RA(i); - lua_assert(base == ci->u.l.base); - lua_assert(base <= L->top && L->top < L->stack + L->stacksize); - vmdispatch (GET_OPCODE(i)) { - vmcase(OP_MOVE, - setobjs2s(L, ra, RB(i)); - ) - vmcase(OP_LOADK, - TValue *rb = k + GETARG_Bx(i); - setobj2s(L, ra, rb); - ) - vmcase(OP_LOADKX, - TValue *rb; - lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); - rb = k + GETARG_Ax(*ci->u.l.savedpc++); - setobj2s(L, ra, rb); - ) - vmcase(OP_LOADBOOL, - setbvalue(ra, GETARG_B(i)); - if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */ - ) - vmcase(OP_LOADNIL, - int b = GETARG_B(i); - do { - setnilvalue(ra++); - } while (b--); - ) - vmcase(OP_GETUPVAL, - int b = GETARG_B(i); - setobj2s(L, ra, cl->upvals[b]->v); - ) - vmcase(OP_GETTABUP, - int b = GETARG_B(i); - Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra)); - ) - vmcase(OP_GETTABLE, - Protect(luaV_gettable(L, RB(i), RKC(i), ra)); - ) - vmcase(OP_SETTABUP, - int a = GETARG_A(i); - Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i))); - ) - vmcase(OP_SETUPVAL, - UpVal *uv = cl->upvals[GETARG_B(i)]; - setobj(L, uv->v, ra); - luaC_barrier(L, uv, ra); - ) - vmcase(OP_SETTABLE, - Protect(luaV_settable(L, ra, RKB(i), RKC(i))); - ) - vmcase(OP_NEWTABLE, - int b = GETARG_B(i); - int c = GETARG_C(i); - Table *t = luaH_new(L); - sethvalue(L, ra, t); - if (b != 0 || c != 0) - luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c)); - checkGC(L, ra + 1); - ) - vmcase(OP_SELF, - StkId rb = RB(i); - setobjs2s(L, ra+1, rb); - Protect(luaV_gettable(L, rb, RKC(i), ra)); - ) - vmcase(OP_ADD, - arith_op(luai_numadd, TM_ADD); - ) - vmcase(OP_SUB, - arith_op(luai_numsub, TM_SUB); - ) - vmcase(OP_MUL, - arith_op(luai_nummul, TM_MUL); - ) - vmcase(OP_DIV, - arith_op(luai_numdiv, TM_DIV); - ) - vmcase(OP_MOD, - arith_op(luai_nummod, TM_MOD); - ) - vmcase(OP_POW, - arith_op(luai_numpow, TM_POW); - ) - vmcase(OP_UNM, - TValue *rb = RB(i); - if (ttisnumber(rb)) { +void luaV_execute(lua_State *L) +{ + CallInfo *ci = L->ci; + LClosure *cl; + TValue *k; + StkId base; +newframe: /* reentry point when frame changes (call/return) */ + lua_assert(ci == L->ci); + cl = clLvalue(ci->func); + k = cl->p->k; + base = ci->u.l.base; + /* main loop of interpreter */ + for (;;) + { + Instruction i = *(ci->u.l.savedpc++); + StkId ra; + if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) && + (--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) + { + Protect(traceexec(L)); + } + /* WARNING: several calls may realloc the stack and invalidate `ra' */ + ra = RA(i); + lua_assert(base == ci->u.l.base); + lua_assert(base <= L->top && L->top < L->stack + L->stacksize); + vmdispatch(GET_OPCODE(i)) + { + vmcase(OP_MOVE, + setobjs2s(L, ra, RB(i));) + vmcase(OP_LOADK, + TValue *rb = k + GETARG_Bx(i); + setobj2s(L, ra, rb);) + vmcase(OP_LOADKX, + TValue * rb; + lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); + rb = k + GETARG_Ax(*ci->u.l.savedpc++); + setobj2s(L, ra, rb);) + vmcase(OP_LOADBOOL, + setbvalue(ra, GETARG_B(i)); + if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */ + ) + vmcase(OP_LOADNIL, + int b = GETARG_B(i); + do { + setnilvalue(ra++); + } while (b--);) vmcase(OP_GETUPVAL, int b = GETARG_B(i); setobj2s(L, ra, cl->upvals[b]->v);) vmcase(OP_GETTABUP, int b = GETARG_B(i); Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra));) vmcase(OP_GETTABLE, Protect(luaV_gettable(L, RB(i), RKC(i), ra));) vmcase(OP_SETTABUP, int a = GETARG_A(i); Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i)));) vmcase(OP_SETUPVAL, UpVal *uv = cl->upvals[GETARG_B(i)]; setobj(L, uv->v, ra); luaC_barrier(L, uv, ra);) vmcase(OP_SETTABLE, Protect(luaV_settable(L, ra, RKB(i), RKC(i)));) vmcase(OP_NEWTABLE, int b = GETARG_B(i); int c = GETARG_C(i); Table *t = luaH_new(L); sethvalue(L, ra, t); if (b != 0 || c != 0) luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c)); checkGC(L, ra + 1);) vmcase(OP_SELF, StkId rb = RB(i); setobjs2s(L, ra + 1, rb); Protect(luaV_gettable(L, rb, RKC(i), ra));) vmcase(OP_ADD, arith_op(luai_numadd, TM_ADD);) vmcase(OP_SUB, arith_op(luai_numsub, TM_SUB);) vmcase(OP_MUL, arith_op(luai_nummul, TM_MUL);) vmcase(OP_DIV, arith_op(luai_numdiv, TM_DIV);) vmcase(OP_MOD, arith_op(luai_nummod, TM_MOD);) vmcase(OP_POW, arith_op(luai_numpow, TM_POW);) vmcase(OP_UNM, TValue *rb = RB(i); if (ttisnumber(rb)) { lua_Number nb = nvalue(rb); - setnvalue(ra, luai_numunm(L, nb)); - } - else { - Protect(luaV_arith(L, ra, rb, rb, TM_UNM)); - } - ) - vmcase(OP_NOT, - TValue *rb = RB(i); - int res = l_isfalse(rb); /* next assignment may change this value */ - setbvalue(ra, res); - ) - vmcase(OP_LEN, - Protect(luaV_objlen(L, ra, RB(i))); - ) - vmcase(OP_CONCAT, - int b = GETARG_B(i); - int c = GETARG_C(i); - StkId rb; - L->top = base + c + 1; /* mark the end of concat operands */ - Protect(luaV_concat(L, c - b + 1)); - ra = RA(i); /* 'luav_concat' may invoke TMs and move the stack */ - rb = b + base; - setobjs2s(L, ra, rb); - checkGC(L, (ra >= rb ? ra + 1 : rb)); - L->top = ci->top; /* restore top */ - ) - vmcase(OP_JMP, - dojump(ci, i, 0); - ) - vmcase(OP_EQ, - TValue *rb = RKB(i); - TValue *rc = RKC(i); - Protect( - if (cast_int(equalobj(L, rb, rc)) != GETARG_A(i)) - ci->u.l.savedpc++; - else - donextjump(ci); - ) - ) - vmcase(OP_LT, - Protect( - if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) - ci->u.l.savedpc++; - else - donextjump(ci); - ) - ) - vmcase(OP_LE, - Protect( - if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) - ci->u.l.savedpc++; - else - donextjump(ci); - ) - ) - vmcase(OP_TEST, - if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra)) - ci->u.l.savedpc++; - else - donextjump(ci); - ) - vmcase(OP_TESTSET, - TValue *rb = RB(i); - if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb)) - ci->u.l.savedpc++; - else { - setobjs2s(L, ra, rb); - donextjump(ci); - } - ) - vmcase(OP_CALL, - int b = GETARG_B(i); - int nresults = GETARG_C(i) - 1; - if (b != 0) L->top = ra+b; /* else previous instruction set top */ - if (luaD_precall(L, ra, nresults)) { /* C function? */ - if (nresults >= 0) L->top = ci->top; /* adjust results */ - base = ci->u.l.base; - } - else { /* Lua function */ - ci = L->ci; - ci->callstatus |= CIST_REENTRY; - goto newframe; /* restart luaV_execute over new Lua function */ - } - ) - vmcase(OP_TAILCALL, - int b = GETARG_B(i); - if (b != 0) L->top = ra+b; /* else previous instruction set top */ - lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); - if (luaD_precall(L, ra, LUA_MULTRET)) /* C function? */ - base = ci->u.l.base; - else { - /* tail call: put called frame (n) in place of caller one (o) */ - CallInfo *nci = L->ci; /* called frame */ - CallInfo *oci = nci->previous; /* caller frame */ - StkId nfunc = nci->func; /* called function */ - StkId ofunc = oci->func; /* caller function */ - /* last stack slot filled by 'precall' */ - StkId lim = nci->u.l.base + getproto(nfunc)->numparams; - int aux; - /* close all upvalues from previous call */ - if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base); - /* move new frame into old one */ - for (aux = 0; nfunc + aux < lim; aux++) - setobjs2s(L, ofunc + aux, nfunc + aux); - oci->u.l.base = ofunc + (nci->u.l.base - nfunc); /* correct base */ - oci->top = L->top = ofunc + (L->top - nfunc); /* correct top */ - oci->u.l.savedpc = nci->u.l.savedpc; - oci->callstatus |= CIST_TAIL; /* function was tail called */ - ci = L->ci = oci; /* remove new frame */ - lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize); - goto newframe; /* restart luaV_execute over new Lua function */ - } - ) - vmcasenb(OP_RETURN, - int b = GETARG_B(i); - if (b != 0) L->top = ra+b-1; - if (cl->p->sizep > 0) luaF_close(L, base); - b = luaD_poscall(L, ra); - if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */ - return; /* external invocation: return */ - else { /* invocation via reentry: continue execution */ - ci = L->ci; - if (b) L->top = ci->top; - lua_assert(isLua(ci)); - lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL); - goto newframe; /* restart luaV_execute over new Lua function */ - } - ) - vmcase(OP_FORLOOP, - lua_Number step = nvalue(ra+2); - lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */ - lua_Number limit = nvalue(ra+1); - if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) - : luai_numle(L, limit, idx)) { - ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ - setnvalue(ra, idx); /* update internal index... */ - setnvalue(ra+3, idx); /* ...and external index */ - } - ) - vmcase(OP_FORPREP, - const TValue *init = ra; - const TValue *plimit = ra+1; - const TValue *pstep = ra+2; - if (!tonumber(init, ra)) - luaG_runerror(L, LUA_QL("for") " initial value must be a number"); - else if (!tonumber(plimit, ra+1)) - luaG_runerror(L, LUA_QL("for") " limit must be a number"); - else if (!tonumber(pstep, ra+2)) - luaG_runerror(L, LUA_QL("for") " step must be a number"); - setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); - ci->u.l.savedpc += GETARG_sBx(i); - ) - vmcasenb(OP_TFORCALL, - StkId cb = ra + 3; /* call base */ - setobjs2s(L, cb+2, ra+2); - setobjs2s(L, cb+1, ra+1); - setobjs2s(L, cb, ra); - L->top = cb + 3; /* func. + 2 args (state and index) */ - Protect(luaD_call(L, cb, GETARG_C(i), 1)); - L->top = ci->top; - i = *(ci->u.l.savedpc++); /* go to next instruction */ - ra = RA(i); - lua_assert(GET_OPCODE(i) == OP_TFORLOOP); - goto l_tforloop; - ) - vmcase(OP_TFORLOOP, - l_tforloop: - if (!ttisnil(ra + 1)) { /* continue loop? */ - setobjs2s(L, ra, ra + 1); /* save control variable */ - ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ - } - ) - vmcase(OP_SETLIST, - int n = GETARG_B(i); - int c = GETARG_C(i); - int last; - Table *h; - if (n == 0) n = cast_int(L->top - ra) - 1; - if (c == 0) { + setnvalue(ra, luai_numunm(L, nb)); } else { + Protect(luaV_arith(L, ra, rb, rb, TM_UNM)); + }) vmcase(OP_NOT, TValue *rb = RB(i); int res = l_isfalse(rb); /* next assignment may change this value */ + setbvalue(ra, res);) vmcase(OP_LEN, Protect(luaV_objlen(L, ra, RB(i)));) vmcase(OP_CONCAT, int b = GETARG_B(i); int c = GETARG_C(i); StkId rb; L->top = base + c + 1; /* mark the end of concat operands */ + Protect(luaV_concat(L, c - b + 1)); ra = RA(i); /* 'luav_concat' may invoke TMs and move the stack */ + rb = b + base; setobjs2s(L, ra, rb); checkGC(L, (ra >= rb ? ra + 1 : rb)); L->top = ci->top; /* restore top */ + ) vmcase(OP_JMP, dojump(ci, i, 0);) vmcase(OP_EQ, TValue *rb = RKB(i); TValue *rc = RKC(i); Protect(if (cast_int(equalobj(L, rb, rc)) != GETARG_A(i)) ci->u.l.savedpc++; else donextjump(ci);)) vmcase(OP_LT, Protect(if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i)) ci->u.l.savedpc++; else donextjump(ci);)) vmcase(OP_LE, Protect(if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i)) ci->u.l.savedpc++; else donextjump(ci);)) vmcase(OP_TEST, if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra)) ci->u.l.savedpc++; else donextjump(ci);) vmcase(OP_TESTSET, TValue *rb = RB(i); if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb)) ci->u.l.savedpc++; else { + setobjs2s(L, ra, rb); + donextjump(ci); + }) vmcase(OP_CALL, int b = GETARG_B(i); int nresults = GETARG_C(i) - 1; if (b != 0) L->top = ra + b; /* else previous instruction set top */ + if (luaD_precall(L, ra, nresults)) { /* C function? */ + if (nresults >= 0) L->top = ci->top; /* adjust results */ + base = ci->u.l.base; + } else { /* Lua function */ + ci = L->ci; + ci->callstatus |= CIST_REENTRY; + goto newframe; /* restart luaV_execute over new Lua function */ + }) vmcase(OP_TAILCALL, int b = GETARG_B(i); if (b != 0) L->top = ra + b; /* else previous instruction set top */ + lua_assert(GETARG_C(i) - 1 == LUA_MULTRET); if (luaD_precall(L, ra, LUA_MULTRET)) /* C function? */ + base = ci->u.l.base; + else { + /* tail call: put called frame (n) in place of caller one (o) */ + CallInfo *nci = L->ci; /* called frame */ + CallInfo *oci = nci->previous; /* caller frame */ + StkId nfunc = nci->func; /* called function */ + StkId ofunc = oci->func; /* caller function */ + /* last stack slot filled by 'precall' */ + StkId lim = nci->u.l.base + getproto(nfunc)->numparams; + int aux; + /* close all upvalues from previous call */ + if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base); + /* move new frame into old one */ + for (aux = 0; nfunc + aux < lim; aux++) + setobjs2s(L, ofunc + aux, nfunc + aux); + oci->u.l.base = ofunc + (nci->u.l.base - nfunc); /* correct base */ + oci->top = L->top = ofunc + (L->top - nfunc); /* correct top */ + oci->u.l.savedpc = nci->u.l.savedpc; + oci->callstatus |= CIST_TAIL; /* function was tail called */ + ci = L->ci = oci; /* remove new frame */ + lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize); + goto newframe; /* restart luaV_execute over new Lua function */ + }) vmcasenb(OP_RETURN, int b = GETARG_B(i); if (b != 0) L->top = ra + b - 1; if (cl->p->sizep > 0) luaF_close(L, base); b = luaD_poscall(L, ra); if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */ + return; /* external invocation: return */ + else { /* invocation via reentry: continue execution */ + ci = L->ci; + if (b) L->top = ci->top; + lua_assert(isLua(ci)); + lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL); + goto newframe; /* restart luaV_execute over new Lua function */ + }) vmcase(OP_FORLOOP, lua_Number step = nvalue(ra + 2); lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */ + lua_Number limit = nvalue(ra + 1); if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit) : luai_numle(L, limit, idx)) { + ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ + setnvalue(ra, idx); /* update internal index... */ + setnvalue(ra + 3, idx); /* ...and external index */ + }) vmcase(OP_FORPREP, const TValue *init = ra; const TValue *plimit = ra + 1; const TValue *pstep = ra + 2; if (!tonumber(init, ra)) luaG_runerror(L, LUA_QL("for") " initial value must be a number"); else if (!tonumber(plimit, ra + 1)) luaG_runerror(L, LUA_QL("for") " limit must be a number"); else if (!tonumber(pstep, ra + 2)) luaG_runerror(L, LUA_QL("for") " step must be a number"); setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep))); ci->u.l.savedpc += GETARG_sBx(i);) vmcasenb(OP_TFORCALL, StkId cb = ra + 3; /* call base */ + setobjs2s(L, cb + 2, ra + 2); setobjs2s(L, cb + 1, ra + 1); setobjs2s(L, cb, ra); L->top = cb + 3; /* func. + 2 args (state and index) */ + Protect(luaD_call(L, cb, GETARG_C(i), 1)); L->top = ci->top; i = *(ci->u.l.savedpc++); /* go to next instruction */ + ra = RA(i); lua_assert(GET_OPCODE(i) == OP_TFORLOOP); goto l_tforloop;) vmcase(OP_TFORLOOP, l_tforloop + : if (!ttisnil(ra + 1)) { /* continue loop? */ + setobjs2s(L, ra, ra + 1); /* save control variable */ + ci->u.l.savedpc += GETARG_sBx(i); /* jump back */ + }) vmcase(OP_SETLIST, int n = GETARG_B(i); int c = GETARG_C(i); int last; Table * h; if (n == 0) n = cast_int(L->top - ra) - 1; if (c == 0) { lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG); - c = GETARG_Ax(*ci->u.l.savedpc++); - } - luai_runtimecheck(L, ttistable(ra)); - h = hvalue(ra); - last = ((c-1)*LFIELDS_PER_FLUSH) + n; - if (last > h->sizearray) /* needs more space? */ - luaH_resizearray(L, h, last); /* pre-allocate it at once */ - for (; n > 0; n--) { - TValue *val = ra+n; - luaH_setint(L, h, last--, val); - luaC_barrierback(L, obj2gco(h), val); - } - L->top = ci->top; /* correct top (in case of previous open call) */ - ) - vmcase(OP_CLOSURE, - Proto *p = cl->p->p[GETARG_Bx(i)]; - Closure *ncl = getcached(p, cl->upvals, base); /* cached closure */ - if (ncl == NULL) /* no match? */ - pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ - else - setclLvalue(L, ra, ncl); /* push cashed closure */ - checkGC(L, ra + 1); - ) - vmcase(OP_VARARG, - int b = GETARG_B(i) - 1; - int j; - int n = cast_int(base - ci->func) - cl->p->numparams - 1; - if (b < 0) { /* B == 0? */ - b = n; /* get all var. arguments */ - Protect(luaD_checkstack(L, n)); - ra = RA(i); /* previous call may change the stack */ - L->top = ra + n; - } - for (j = 0; j < b; j++) { - if (j < n) { - setobjs2s(L, ra + j, base - n + j); - } - else { - setnilvalue(ra + j); - } - } - ) - vmcase(OP_EXTRAARG, - lua_assert(0); - ) - } - } + c = GETARG_Ax(*ci->u.l.savedpc++); } luai_runtimecheck(L, ttistable(ra)); h = hvalue(ra); last = ((c - 1) * LFIELDS_PER_FLUSH) + n; if (last > h->sizearray) /* needs more space? */ + luaH_resizearray(L, h, last); /* pre-allocate it at once */ + for (; n > 0; n--) { + TValue *val = ra + n; + luaH_setint(L, h, last--, val); + luaC_barrierback(L, obj2gco(h), val); + } L->top = ci->top; /* correct top (in case of previous open call) */ + ) vmcase(OP_CLOSURE, Proto *p = cl->p->p[GETARG_Bx(i)]; Closure *ncl = getcached(p, cl->upvals, base); /* cached closure */ + if (ncl == NULL) /* no match? */ + pushclosure(L, p, cl->upvals, base, ra); /* create a new one */ + else setclLvalue(L, ra, ncl); /* push cashed closure */ + checkGC(L, ra + 1);) vmcase(OP_VARARG, int b = GETARG_B(i) - 1; int j; int n = cast_int(base - ci->func) - cl->p->numparams - 1; if (b < 0) { /* B == 0? */ + b = n; /* get all var. arguments */ + Protect(luaD_checkstack(L, n)); + ra = RA(i); /* previous call may change the stack */ + L->top = ra + n; + } for (j = 0; j < b; j++) { + if (j < n) + { + setobjs2s(L, ra + j, base - n + j); + } + else + { + setnilvalue(ra + j); + } + }) vmcase(OP_EXTRAARG, lua_assert(0);) + } + } } - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lvm.h b/examples/ThirdPartyLibs/lua-5.2.3/src/lvm.h index 5380270da..7332da4ae 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lvm.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lvm.h @@ -7,38 +7,34 @@ #ifndef lvm_h #define lvm_h - #include "ldo.h" #include "lobject.h" #include "ltm.h" +#define tostring(L, o) (ttisstring(o) || (luaV_tostring(L, o))) -#define tostring(L,o) (ttisstring(o) || (luaV_tostring(L, o))) +#define tonumber(o, n) (ttisnumber(o) || (((o) = luaV_tonumber(o, n)) != NULL)) -#define tonumber(o,n) (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL)) - -#define equalobj(L,o1,o2) (ttisequal(o1, o2) && luaV_equalobj_(L, o1, o2)) - -#define luaV_rawequalobj(o1,o2) equalobj(NULL,o1,o2) +#define equalobj(L, o1, o2) (ttisequal(o1, o2) && luaV_equalobj_(L, o1, o2)) +#define luaV_rawequalobj(o1, o2) equalobj(NULL, o1, o2) /* not to called directly */ -LUAI_FUNC int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2); +LUAI_FUNC int luaV_equalobj_(lua_State *L, const TValue *t1, const TValue *t2); - -LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); -LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); -LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n); -LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj); -LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key, - StkId val); -LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, - StkId val); -LUAI_FUNC void luaV_finishOp (lua_State *L); -LUAI_FUNC void luaV_execute (lua_State *L); -LUAI_FUNC void luaV_concat (lua_State *L, int total); -LUAI_FUNC void luaV_arith (lua_State *L, StkId ra, const TValue *rb, - const TValue *rc, TMS op); -LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); +LUAI_FUNC int luaV_lessthan(lua_State *L, const TValue *l, const TValue *r); +LUAI_FUNC int luaV_lessequal(lua_State *L, const TValue *l, const TValue *r); +LUAI_FUNC const TValue *luaV_tonumber(const TValue *obj, TValue *n); +LUAI_FUNC int luaV_tostring(lua_State *L, StkId obj); +LUAI_FUNC void luaV_gettable(lua_State *L, const TValue *t, TValue *key, + StkId val); +LUAI_FUNC void luaV_settable(lua_State *L, const TValue *t, TValue *key, + StkId val); +LUAI_FUNC void luaV_finishOp(lua_State *L); +LUAI_FUNC void luaV_execute(lua_State *L); +LUAI_FUNC void luaV_concat(lua_State *L, int total); +LUAI_FUNC void luaV_arith(lua_State *L, StkId ra, const TValue *rb, + const TValue *rc, TMS op); +LUAI_FUNC void luaV_objlen(lua_State *L, StkId ra, const TValue *rb); #endif diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lzio.c b/examples/ThirdPartyLibs/lua-5.2.3/src/lzio.c index 20efea983..3f79e8486 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lzio.c +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lzio.c @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #include #define lzio_c @@ -17,60 +16,63 @@ #include "lstate.h" #include "lzio.h" - -int luaZ_fill (ZIO *z) { - size_t size; - lua_State *L = z->L; - const char *buff; - lua_unlock(L); - buff = z->reader(L, z->data, &size); - lua_lock(L); - if (buff == NULL || size == 0) - return EOZ; - z->n = size - 1; /* discount char being returned */ - z->p = buff; - return cast_uchar(*(z->p++)); +int luaZ_fill(ZIO *z) +{ + size_t size; + lua_State *L = z->L; + const char *buff; + lua_unlock(L); + buff = z->reader(L, z->data, &size); + lua_lock(L); + if (buff == NULL || size == 0) + return EOZ; + z->n = size - 1; /* discount char being returned */ + z->p = buff; + return cast_uchar(*(z->p++)); } - -void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) { - z->L = L; - z->reader = reader; - z->data = data; - z->n = 0; - z->p = NULL; +void luaZ_init(lua_State *L, ZIO *z, lua_Reader reader, void *data) +{ + z->L = L; + z->reader = reader; + z->data = data; + z->n = 0; + z->p = NULL; } - /* --------------------------------------------------------------- read --- */ -size_t luaZ_read (ZIO *z, void *b, size_t n) { - while (n) { - size_t m; - if (z->n == 0) { /* no bytes in buffer? */ - if (luaZ_fill(z) == EOZ) /* try to read more */ - return n; /* no more input; return number of missing bytes */ - else { - z->n++; /* luaZ_fill consumed first byte; put it back */ - z->p--; - } - } - m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ - memcpy(b, z->p, m); - z->n -= m; - z->p += m; - b = (char *)b + m; - n -= m; - } - return 0; +size_t luaZ_read(ZIO *z, void *b, size_t n) +{ + while (n) + { + size_t m; + if (z->n == 0) + { /* no bytes in buffer? */ + if (luaZ_fill(z) == EOZ) /* try to read more */ + return n; /* no more input; return number of missing bytes */ + else + { + z->n++; /* luaZ_fill consumed first byte; put it back */ + z->p--; + } + } + m = (n <= z->n) ? n : z->n; /* min. between n and z->n */ + memcpy(b, z->p, m); + z->n -= m; + z->p += m; + b = (char *)b + m; + n -= m; + } + return 0; } /* ------------------------------------------------------------------------ */ -char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n) { - if (n > buff->buffsize) { - if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; - luaZ_resizebuffer(L, buff, n); - } - return buff->buffer; +char *luaZ_openspace(lua_State *L, Mbuffer *buff, size_t n) +{ + if (n > buff->buffsize) + { + if (n < LUA_MINBUFFER) n = LUA_MINBUFFER; + luaZ_resizebuffer(L, buff, n); + } + return buff->buffer; } - - diff --git a/examples/ThirdPartyLibs/lua-5.2.3/src/lzio.h b/examples/ThirdPartyLibs/lua-5.2.3/src/lzio.h index 441f7479c..38c5f8a32 100644 --- a/examples/ThirdPartyLibs/lua-5.2.3/src/lzio.h +++ b/examples/ThirdPartyLibs/lua-5.2.3/src/lzio.h @@ -4,7 +4,6 @@ ** See Copyright Notice in lua.h */ - #ifndef lzio_h #define lzio_h @@ -12,54 +11,49 @@ #include "lmem.h" - -#define EOZ (-1) /* end of stream */ +#define EOZ (-1) /* end of stream */ typedef struct Zio ZIO; -#define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) +#define zgetc(z) (((z)->n--) > 0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) - -typedef struct Mbuffer { - char *buffer; - size_t n; - size_t buffsize; +typedef struct Mbuffer +{ + char *buffer; + size_t n; + size_t buffsize; } Mbuffer; #define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) -#define luaZ_buffer(buff) ((buff)->buffer) -#define luaZ_sizebuffer(buff) ((buff)->buffsize) -#define luaZ_bufflen(buff) ((buff)->n) +#define luaZ_buffer(buff) ((buff)->buffer) +#define luaZ_sizebuffer(buff) ((buff)->buffsize) +#define luaZ_bufflen(buff) ((buff)->n) #define luaZ_resetbuffer(buff) ((buff)->n = 0) - -#define luaZ_resizebuffer(L, buff, size) \ +#define luaZ_resizebuffer(L, buff, size) \ (luaM_reallocvector(L, (buff)->buffer, (buff)->buffsize, size, char), \ - (buff)->buffsize = size) - -#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) - - -LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n); -LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, - void *data); -LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */ + (buff)->buffsize = size) +#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) +LUAI_FUNC char *luaZ_openspace(lua_State *L, Mbuffer *buff, size_t n); +LUAI_FUNC void luaZ_init(lua_State *L, ZIO *z, lua_Reader reader, + void *data); +LUAI_FUNC size_t luaZ_read(ZIO *z, void *b, size_t n); /* read next n bytes */ /* --------- Private Part ------------------ */ -struct Zio { - size_t n; /* bytes still unread */ - const char *p; /* current position in buffer */ - lua_Reader reader; /* reader function */ - void* data; /* additional data */ - lua_State *L; /* Lua state (for reader) */ +struct Zio +{ + size_t n; /* bytes still unread */ + const char *p; /* current position in buffer */ + lua_Reader reader; /* reader function */ + void *data; /* additional data */ + lua_State *L; /* Lua state (for reader) */ }; - -LUAI_FUNC int luaZ_fill (ZIO *z); +LUAI_FUNC int luaZ_fill(ZIO *z); #endif diff --git a/examples/ThirdPartyLibs/midi/RtError.h b/examples/ThirdPartyLibs/midi/RtError.h index 5cf7d510a..2ca17253e 100644 --- a/examples/ThirdPartyLibs/midi/RtError.h +++ b/examples/ThirdPartyLibs/midi/RtError.h @@ -20,7 +20,8 @@ class RtError : public std::exception { public: //! Defined RtError types. - enum Type { + enum Type + { WARNING, /*!< A non-critical error. */ DEBUG_WARNING, /*!< A non-critical error which might be useful for debugging. */ UNSPECIFIED, /*!< The default, unspecified error type. */ @@ -41,7 +42,8 @@ public: virtual ~RtError(void) throw() {} //! Prints thrown error message to stderr. - virtual void printMessage(void) const throw() { std::cerr << '\n' << message_ << "\n\n"; } + virtual void printMessage(void) const throw() { std::cerr << '\n' + << message_ << "\n\n"; } //! Returns the thrown error message type. virtual const Type& getType(void) const throw() { return type_; } diff --git a/examples/ThirdPartyLibs/midi/RtMidi.cpp b/examples/ThirdPartyLibs/midi/RtMidi.cpp index 9cbd260f0..35210bb8b 100644 --- a/examples/ThirdPartyLibs/midi/RtMidi.cpp +++ b/examples/ThirdPartyLibs/midi/RtMidi.cpp @@ -40,295 +40,307 @@ #include "RtMidi.h" #include -#include //exit +#include //exit //*********************************************************************// // RtMidi Definitions //*********************************************************************// -void RtMidi :: getCompiledApi( std::vector &apis ) +void RtMidi ::getCompiledApi(std::vector &apis) { - apis.clear(); + apis.clear(); - // The order here will control the order of RtMidi's API search in - // the constructor. + // The order here will control the order of RtMidi's API search in + // the constructor. #if defined(__MACOSX_CORE__) - apis.push_back( MACOSX_CORE ); + apis.push_back(MACOSX_CORE); #endif #if defined(__LINUX_ALSA__) - apis.push_back( LINUX_ALSA ); + apis.push_back(LINUX_ALSA); #endif #if defined(__UNIX_JACK__) - apis.push_back( UNIX_JACK ); + apis.push_back(UNIX_JACK); #endif #if defined(__WINDOWS_MM__) - apis.push_back( WINDOWS_MM ); + apis.push_back(WINDOWS_MM); #endif #if defined(__WINDOWS_KS__) - apis.push_back( WINDOWS_KS ); + apis.push_back(WINDOWS_KS); #endif #if defined(__RTMIDI_DUMMY__) - apis.push_back( RTMIDI_DUMMY ); + apis.push_back(RTMIDI_DUMMY); #endif - } -void RtMidi :: error( RtError::Type type, std::string errorString ) +void RtMidi ::error(RtError::Type type, std::string errorString) { - if (type == RtError::WARNING) { - std::cerr << '\n' << errorString << "\n\n"; - } - else if (type == RtError::DEBUG_WARNING) { + if (type == RtError::WARNING) + { + std::cerr << '\n' + << errorString << "\n\n"; + } + else if (type == RtError::DEBUG_WARNING) + { #if defined(__RTMIDI_DEBUG__) - std::cerr << '\n' << errorString << "\n\n"; + std::cerr << '\n' + << errorString << "\n\n"; #endif - } - else { - std::cerr << '\n' << errorString << "\n\n"; -// exit(0); - } + } + else + { + std::cerr << '\n' + << errorString << "\n\n"; + // exit(0); + } } //*********************************************************************// // RtMidiIn Definitions //*********************************************************************// -void RtMidiIn :: openMidiApi( RtMidi::Api api, const std::string clientName, unsigned int queueSizeLimit ) +void RtMidiIn ::openMidiApi(RtMidi::Api api, const std::string clientName, unsigned int queueSizeLimit) { - if ( rtapi_ ) - delete rtapi_; - rtapi_ = 0; + if (rtapi_) + delete rtapi_; + rtapi_ = 0; #if defined(__UNIX_JACK__) - if ( api == UNIX_JACK ) - rtapi_ = new MidiInJack( clientName, queueSizeLimit ); + if (api == UNIX_JACK) + rtapi_ = new MidiInJack(clientName, queueSizeLimit); #endif #if defined(__LINUX_ALSA__) - if ( api == LINUX_ALSA ) - rtapi_ = new MidiInAlsa( clientName, queueSizeLimit ); + if (api == LINUX_ALSA) + rtapi_ = new MidiInAlsa(clientName, queueSizeLimit); #endif #if defined(__WINDOWS_MM__) - if ( api == WINDOWS_MM ) - rtapi_ = new MidiInWinMM( clientName, queueSizeLimit ); + if (api == WINDOWS_MM) + rtapi_ = new MidiInWinMM(clientName, queueSizeLimit); #endif #if defined(__WINDOWS_KS__) - if ( api == WINDOWS_KS ) - rtapi_ = new MidiInWinKS( clientName, queueSizeLimit ); + if (api == WINDOWS_KS) + rtapi_ = new MidiInWinKS(clientName, queueSizeLimit); #endif #if defined(__MACOSX_CORE__) - if ( api == MACOSX_CORE ) - rtapi_ = new MidiInCore( clientName, queueSizeLimit ); + if (api == MACOSX_CORE) + rtapi_ = new MidiInCore(clientName, queueSizeLimit); #endif #if defined(__RTMIDI_DUMMY__) - if ( api == RTMIDI_DUMMY ) - rtapi_ = new MidiInDummy( clientName, queueSizeLimit ); + if (api == RTMIDI_DUMMY) + rtapi_ = new MidiInDummy(clientName, queueSizeLimit); #endif } -RtMidiIn :: RtMidiIn( RtMidi::Api api, const std::string clientName, unsigned int queueSizeLimit ) +RtMidiIn ::RtMidiIn(RtMidi::Api api, const std::string clientName, unsigned int queueSizeLimit) { - rtapi_ = 0; + rtapi_ = 0; - if ( api != UNSPECIFIED ) { - // Attempt to open the specified API. - openMidiApi( api, clientName, queueSizeLimit ); - if ( rtapi_ ) return; + if (api != UNSPECIFIED) + { + // Attempt to open the specified API. + openMidiApi(api, clientName, queueSizeLimit); + if (rtapi_) return; - // No compiled support for specified API value. Issue a debug - // warning and continue as if no API was specified. - RtMidi::error( RtError::WARNING, "RtMidiIn: no compiled support for specified API argument!" ); - } + // No compiled support for specified API value. Issue a debug + // warning and continue as if no API was specified. + RtMidi::error(RtError::WARNING, "RtMidiIn: no compiled support for specified API argument!"); + } - // Iterate through the compiled APIs and return as soon as we find - // one with at least one port or we reach the end of the list. - std::vector< RtMidi::Api > apis; - getCompiledApi( apis ); - for ( unsigned int i=0; igetPortCount() ) break; - } + // Iterate through the compiled APIs and return as soon as we find + // one with at least one port or we reach the end of the list. + std::vector apis; + getCompiledApi(apis); + for (unsigned int i = 0; i < apis.size(); i++) + { + openMidiApi(apis[i], clientName, queueSizeLimit); + if (rtapi_->getPortCount()) break; + } - if ( rtapi_ ) return; + if (rtapi_) return; - // It should not be possible to get here because the preprocessor - // definition __RTMIDI_DUMMY__ is automatically defined if no - // API-specific definitions are passed to the compiler. But just in - // case something weird happens, we'll print out an error message. - RtMidi::error( RtError::WARNING, "RtMidiIn: no compiled API support found ... critical error!!" ); + // It should not be possible to get here because the preprocessor + // definition __RTMIDI_DUMMY__ is automatically defined if no + // API-specific definitions are passed to the compiler. But just in + // case something weird happens, we'll print out an error message. + RtMidi::error(RtError::WARNING, "RtMidiIn: no compiled API support found ... critical error!!"); } -RtMidiIn :: ~RtMidiIn() +RtMidiIn ::~RtMidiIn() { - delete rtapi_; + delete rtapi_; } - //*********************************************************************// // RtMidiOut Definitions //*********************************************************************// -void RtMidiOut :: openMidiApi( RtMidi::Api api, const std::string clientName ) +void RtMidiOut ::openMidiApi(RtMidi::Api api, const std::string clientName) { - if ( rtapi_ ) - delete rtapi_; - rtapi_ = 0; + if (rtapi_) + delete rtapi_; + rtapi_ = 0; #if defined(__UNIX_JACK__) - if ( api == UNIX_JACK ) - rtapi_ = new MidiOutJack( clientName ); + if (api == UNIX_JACK) + rtapi_ = new MidiOutJack(clientName); #endif #if defined(__LINUX_ALSA__) - if ( api == LINUX_ALSA ) - rtapi_ = new MidiOutAlsa( clientName ); + if (api == LINUX_ALSA) + rtapi_ = new MidiOutAlsa(clientName); #endif #if defined(__WINDOWS_MM__) - if ( api == WINDOWS_MM ) - rtapi_ = new MidiOutWinMM( clientName ); + if (api == WINDOWS_MM) + rtapi_ = new MidiOutWinMM(clientName); #endif #if defined(__WINDOWS_KS__) - if ( api == WINDOWS_KS ) - rtapi_ = new MidiOutWinKS( clientName ); + if (api == WINDOWS_KS) + rtapi_ = new MidiOutWinKS(clientName); #endif #if defined(__MACOSX_CORE__) - if ( api == MACOSX_CORE ) - rtapi_ = new MidiOutCore( clientName ); + if (api == MACOSX_CORE) + rtapi_ = new MidiOutCore(clientName); #endif #if defined(__RTMIDI_DUMMY__) - if ( api == RTMIDI_DUMMY ) - rtapi_ = new MidiOutDummy( clientName ); + if (api == RTMIDI_DUMMY) + rtapi_ = new MidiOutDummy(clientName); #endif } -RtMidiOut :: RtMidiOut( RtMidi::Api api, const std::string clientName ) +RtMidiOut ::RtMidiOut(RtMidi::Api api, const std::string clientName) { - rtapi_ = 0; + rtapi_ = 0; - if ( api != UNSPECIFIED ) { - // Attempt to open the specified API. - openMidiApi( api, clientName ); - if ( rtapi_ ) return; + if (api != UNSPECIFIED) + { + // Attempt to open the specified API. + openMidiApi(api, clientName); + if (rtapi_) return; - // No compiled support for specified API value. Issue a debug - // warning and continue as if no API was specified. - RtMidi::error( RtError::WARNING, "RtMidiOut: no compiled support for specified API argument!" ); - } + // No compiled support for specified API value. Issue a debug + // warning and continue as if no API was specified. + RtMidi::error(RtError::WARNING, "RtMidiOut: no compiled support for specified API argument!"); + } - // Iterate through the compiled APIs and return as soon as we find - // one with at least one port or we reach the end of the list. - std::vector< RtMidi::Api > apis; - getCompiledApi( apis ); - for ( unsigned int i=0; igetPortCount() ) break; - } + // Iterate through the compiled APIs and return as soon as we find + // one with at least one port or we reach the end of the list. + std::vector apis; + getCompiledApi(apis); + for (unsigned int i = 0; i < apis.size(); i++) + { + openMidiApi(apis[i], clientName); + if (rtapi_->getPortCount()) break; + } - if ( rtapi_ ) return; + if (rtapi_) return; - // It should not be possible to get here because the preprocessor - // definition __RTMIDI_DUMMY__ is automatically defined if no - // API-specific definitions are passed to the compiler. But just in - // case something weird happens, we'll print out an error message. - RtMidi::error( RtError::WARNING, "RtMidiOut: no compiled API support found ... critical error!!" ); + // It should not be possible to get here because the preprocessor + // definition __RTMIDI_DUMMY__ is automatically defined if no + // API-specific definitions are passed to the compiler. But just in + // case something weird happens, we'll print out an error message. + RtMidi::error(RtError::WARNING, "RtMidiOut: no compiled API support found ... critical error!!"); } -RtMidiOut :: ~RtMidiOut() +RtMidiOut ::~RtMidiOut() { - delete rtapi_; + delete rtapi_; } //*********************************************************************// // Common MidiInApi Definitions //*********************************************************************// -MidiInApi :: MidiInApi( unsigned int queueSizeLimit ) - : apiData_( 0 ), connected_( false ) +MidiInApi ::MidiInApi(unsigned int queueSizeLimit) + : apiData_(0), connected_(false) { - // Allocate the MIDI queue. - inputData_.queue.ringSize = queueSizeLimit; - if ( inputData_.queue.ringSize > 0 ) - inputData_.queue.ring = new MidiMessage[ inputData_.queue.ringSize ]; + // Allocate the MIDI queue. + inputData_.queue.ringSize = queueSizeLimit; + if (inputData_.queue.ringSize > 0) + inputData_.queue.ring = new MidiMessage[inputData_.queue.ringSize]; } -MidiInApi :: ~MidiInApi( void ) +MidiInApi ::~MidiInApi(void) { - // Delete the MIDI queue. - if ( inputData_.queue.ringSize > 0 ) delete [] inputData_.queue.ring; + // Delete the MIDI queue. + if (inputData_.queue.ringSize > 0) delete[] inputData_.queue.ring; } -void MidiInApi :: setCallback( RtMidiIn::RtMidiCallback callback, void *userData ) +void MidiInApi ::setCallback(RtMidiIn::RtMidiCallback callback, void *userData) { - if ( inputData_.usingCallback ) { - errorString_ = "MidiInApi::setCallback: a callback function is already set!"; - RtMidi::error( RtError::WARNING, errorString_ ); - return; - } + if (inputData_.usingCallback) + { + errorString_ = "MidiInApi::setCallback: a callback function is already set!"; + RtMidi::error(RtError::WARNING, errorString_); + return; + } - if ( !callback ) { - errorString_ = "RtMidiIn::setCallback: callback function value is invalid!"; - RtMidi::error( RtError::WARNING, errorString_ ); - return; - } + if (!callback) + { + errorString_ = "RtMidiIn::setCallback: callback function value is invalid!"; + RtMidi::error(RtError::WARNING, errorString_); + return; + } - inputData_.userCallback = (void *) callback; - inputData_.userData = userData; - inputData_.usingCallback = true; + inputData_.userCallback = (void *)callback; + inputData_.userData = userData; + inputData_.usingCallback = true; } -void MidiInApi :: cancelCallback() +void MidiInApi ::cancelCallback() { - if ( !inputData_.usingCallback ) { - errorString_ = "RtMidiIn::cancelCallback: no callback function was set!"; - RtMidi::error( RtError::WARNING, errorString_ ); - return; - } + if (!inputData_.usingCallback) + { + errorString_ = "RtMidiIn::cancelCallback: no callback function was set!"; + RtMidi::error(RtError::WARNING, errorString_); + return; + } - inputData_.userCallback = 0; - inputData_.userData = 0; - inputData_.usingCallback = false; + inputData_.userCallback = 0; + inputData_.userData = 0; + inputData_.usingCallback = false; } -void MidiInApi :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) +void MidiInApi ::ignoreTypes(bool midiSysex, bool midiTime, bool midiSense) { - inputData_.ignoreFlags = 0; - if ( midiSysex ) inputData_.ignoreFlags = 0x01; - if ( midiTime ) inputData_.ignoreFlags |= 0x02; - if ( midiSense ) inputData_.ignoreFlags |= 0x04; + inputData_.ignoreFlags = 0; + if (midiSysex) inputData_.ignoreFlags = 0x01; + if (midiTime) inputData_.ignoreFlags |= 0x02; + if (midiSense) inputData_.ignoreFlags |= 0x04; } -double MidiInApi :: getMessage( std::vector *message ) +double MidiInApi ::getMessage(std::vector *message) { - message->clear(); + message->clear(); - if ( inputData_.usingCallback ) { - errorString_ = "RtMidiIn::getNextMessage: a user callback is currently set for this port."; - RtMidi::error( RtError::WARNING, errorString_ ); - return 0.0; - } + if (inputData_.usingCallback) + { + errorString_ = "RtMidiIn::getNextMessage: a user callback is currently set for this port."; + RtMidi::error(RtError::WARNING, errorString_); + return 0.0; + } - if ( inputData_.queue.size == 0 ) return 0.0; + if (inputData_.queue.size == 0) return 0.0; - // Copy queued message to the vector pointer argument and then "pop" it. - std::vector *bytes = &(inputData_.queue.ring[inputData_.queue.front].bytes); - message->assign( bytes->begin(), bytes->end() ); - double deltaTime = inputData_.queue.ring[inputData_.queue.front].timeStamp; - inputData_.queue.size--; - inputData_.queue.front++; - if ( inputData_.queue.front == inputData_.queue.ringSize ) - inputData_.queue.front = 0; + // Copy queued message to the vector pointer argument and then "pop" it. + std::vector *bytes = &(inputData_.queue.ring[inputData_.queue.front].bytes); + message->assign(bytes->begin(), bytes->end()); + double deltaTime = inputData_.queue.ring[inputData_.queue.front].timeStamp; + inputData_.queue.size--; + inputData_.queue.front++; + if (inputData_.queue.front == inputData_.queue.ringSize) + inputData_.queue.front = 0; - return deltaTime; + return deltaTime; } //*********************************************************************// // Common MidiOutApi Definitions //*********************************************************************// -MidiOutApi :: MidiOutApi( void ) - : apiData_( 0 ), connected_( false ) +MidiOutApi ::MidiOutApi(void) + : apiData_(0), connected_(false) { } -MidiOutApi :: ~MidiOutApi( void ) +MidiOutApi ::~MidiOutApi(void) { } @@ -351,13 +363,14 @@ MidiOutApi :: ~MidiOutApi( void ) // A structure to hold variables related to the CoreMIDI API // implementation. -struct CoreMidiData { - MIDIClientRef client; - MIDIPortRef port; - MIDIEndpointRef endpoint; - MIDIEndpointRef destinationId; - unsigned long long lastTime; - MIDISysexSendRequest sysexreq; +struct CoreMidiData +{ + MIDIClientRef client; + MIDIPortRef port; + MIDIEndpointRef endpoint; + MIDIEndpointRef destinationId; + unsigned long long lastTime; + MIDISysexSendRequest sysexreq; }; //*********************************************************************// @@ -365,425 +378,485 @@ struct CoreMidiData { // Class Definitions: MidiInCore //*********************************************************************// -void midiInputCallback( const MIDIPacketList *list, void *procRef, void *srcRef ) +void midiInputCallback(const MIDIPacketList *list, void *procRef, void *srcRef) { - MidiInApi::RtMidiInData *data = static_cast (procRef); - CoreMidiData *apiData = static_cast (data->apiData); + MidiInApi::RtMidiInData *data = static_cast(procRef); + CoreMidiData *apiData = static_cast(data->apiData); - unsigned char status; - unsigned short nBytes, iByte, size; - unsigned long long time; + unsigned char status; + unsigned short nBytes, iByte, size; + unsigned long long time; - bool& continueSysex = data->continueSysex; - MidiInApi::MidiMessage& message = data->message; + bool &continueSysex = data->continueSysex; + MidiInApi::MidiMessage &message = data->message; - const MIDIPacket *packet = &list->packet[0]; - for ( unsigned int i=0; inumPackets; ++i ) { + const MIDIPacket *packet = &list->packet[0]; + for (unsigned int i = 0; i < list->numPackets; ++i) + { + // My interpretation of the CoreMIDI documentation: all message + // types, except sysex, are complete within a packet and there may + // be several of them in a single packet. Sysex messages can be + // broken across multiple packets and PacketLists but are bundled + // alone within each packet (these packets do not contain other + // message types). If sysex messages are split across multiple + // MIDIPacketLists, they must be handled by multiple calls to this + // function. - // My interpretation of the CoreMIDI documentation: all message - // types, except sysex, are complete within a packet and there may - // be several of them in a single packet. Sysex messages can be - // broken across multiple packets and PacketLists but are bundled - // alone within each packet (these packets do not contain other - // message types). If sysex messages are split across multiple - // MIDIPacketLists, they must be handled by multiple calls to this - // function. + nBytes = packet->length; + if (nBytes == 0) continue; - nBytes = packet->length; - if ( nBytes == 0 ) continue; + // Calculate time stamp. - // Calculate time stamp. + if (data->firstMessage) + { + message.timeStamp = 0.0; + data->firstMessage = false; + } + else + { + time = packet->timeStamp; + if (time == 0) + { // this happens when receiving asynchronous sysex messages + time = AudioGetCurrentHostTime(); + } + time -= apiData->lastTime; + time = AudioConvertHostTimeToNanos(time); + if (!continueSysex) + message.timeStamp = time * 0.000000001; + } + apiData->lastTime = packet->timeStamp; + if (apiData->lastTime == 0) + { // this happens when receiving asynchronous sysex messages + apiData->lastTime = AudioGetCurrentHostTime(); + } + //std::cout << "TimeStamp = " << packet->timeStamp << std::endl; - if ( data->firstMessage ) { - message.timeStamp = 0.0; - data->firstMessage = false; - } - else { - time = packet->timeStamp; - if ( time == 0 ) { // this happens when receiving asynchronous sysex messages - time = AudioGetCurrentHostTime(); - } - time -= apiData->lastTime; - time = AudioConvertHostTimeToNanos( time ); - if ( !continueSysex ) - message.timeStamp = time * 0.000000001; - } - apiData->lastTime = packet->timeStamp; - if ( apiData->lastTime == 0 ) { // this happens when receiving asynchronous sysex messages - apiData->lastTime = AudioGetCurrentHostTime(); - } - //std::cout << "TimeStamp = " << packet->timeStamp << std::endl; + iByte = 0; + if (continueSysex) + { + // We have a continuing, segmented sysex message. + if (!(data->ignoreFlags & 0x01)) + { + // If we're not ignoring sysex messages, copy the entire packet. + for (unsigned int j = 0; j < nBytes; ++j) + message.bytes.push_back(packet->data[j]); + } + continueSysex = packet->data[nBytes - 1] != 0xF7; - iByte = 0; - if ( continueSysex ) { - // We have a continuing, segmented sysex message. - if ( !( data->ignoreFlags & 0x01 ) ) { - // If we're not ignoring sysex messages, copy the entire packet. - for ( unsigned int j=0; jdata[j] ); - } - continueSysex = packet->data[nBytes-1] != 0xF7; + if (!continueSysex) + { + // If not a continuing sysex message, invoke the user callback function or queue the message. + if (data->usingCallback) + { + RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback)data->userCallback; + callback(message.timeStamp, &message.bytes, data->userData); + } + else + { + // As long as we haven't reached our queue size limit, push the message. + if (data->queue.size < data->queue.ringSize) + { + data->queue.ring[data->queue.back++] = message; + if (data->queue.back == data->queue.ringSize) + data->queue.back = 0; + data->queue.size++; + } + else + std::cerr << "\nMidiInCore: message queue limit reached!!\n\n"; + } + message.bytes.clear(); + } + } + else + { + while (iByte < nBytes) + { + size = 0; + // We are expecting that the next byte in the packet is a status byte. + status = packet->data[iByte]; + if (!(status & 0x80)) break; + // Determine the number of bytes in the MIDI message. + if (status < 0xC0) + size = 3; + else if (status < 0xE0) + size = 2; + else if (status < 0xF0) + size = 3; + else if (status == 0xF0) + { + // A MIDI sysex + if (data->ignoreFlags & 0x01) + { + size = 0; + iByte = nBytes; + } + else + size = nBytes - iByte; + continueSysex = packet->data[nBytes - 1] != 0xF7; + } + else if (status == 0xF1) + { + // A MIDI time code message + if (data->ignoreFlags & 0x02) + { + size = 0; + iByte += 2; + } + else + size = 2; + } + else if (status == 0xF2) + size = 3; + else if (status == 0xF3) + size = 2; + else if (status == 0xF8 && (data->ignoreFlags & 0x02)) + { + // A MIDI timing tick message and we're ignoring it. + size = 0; + iByte += 1; + } + else if (status == 0xFE && (data->ignoreFlags & 0x04)) + { + // A MIDI active sensing message and we're ignoring it. + size = 0; + iByte += 1; + } + else + size = 1; - if ( !continueSysex ) { - // If not a continuing sysex message, invoke the user callback function or queue the message. - if ( data->usingCallback ) { - RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) data->userCallback; - callback( message.timeStamp, &message.bytes, data->userData ); - } - else { - // As long as we haven't reached our queue size limit, push the message. - if ( data->queue.size < data->queue.ringSize ) { - data->queue.ring[data->queue.back++] = message; - if ( data->queue.back == data->queue.ringSize ) - data->queue.back = 0; - data->queue.size++; - } - else - std::cerr << "\nMidiInCore: message queue limit reached!!\n\n"; - } - message.bytes.clear(); - } - } - else { - while ( iByte < nBytes ) { - size = 0; - // We are expecting that the next byte in the packet is a status byte. - status = packet->data[iByte]; - if ( !(status & 0x80) ) break; - // Determine the number of bytes in the MIDI message. - if ( status < 0xC0 ) size = 3; - else if ( status < 0xE0 ) size = 2; - else if ( status < 0xF0 ) size = 3; - else if ( status == 0xF0 ) { - // A MIDI sysex - if ( data->ignoreFlags & 0x01 ) { - size = 0; - iByte = nBytes; - } - else size = nBytes - iByte; - continueSysex = packet->data[nBytes-1] != 0xF7; - } - else if ( status == 0xF1 ) { - // A MIDI time code message - if ( data->ignoreFlags & 0x02 ) { - size = 0; - iByte += 2; - } - else size = 2; - } - else if ( status == 0xF2 ) size = 3; - else if ( status == 0xF3 ) size = 2; - else if ( status == 0xF8 && ( data->ignoreFlags & 0x02 ) ) { - // A MIDI timing tick message and we're ignoring it. - size = 0; - iByte += 1; - } - else if ( status == 0xFE && ( data->ignoreFlags & 0x04 ) ) { - // A MIDI active sensing message and we're ignoring it. - size = 0; - iByte += 1; - } - else size = 1; - - // Copy the MIDI data to our vector. - if ( size ) { - message.bytes.assign( &packet->data[iByte], &packet->data[iByte+size] ); - if ( !continueSysex ) { - // If not a continuing sysex message, invoke the user callback function or queue the message. - if ( data->usingCallback ) { - RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) data->userCallback; - callback( message.timeStamp, &message.bytes, data->userData ); - } - else { - // As long as we haven't reached our queue size limit, push the message. - if ( data->queue.size < data->queue.ringSize ) { - data->queue.ring[data->queue.back++] = message; - if ( data->queue.back == data->queue.ringSize ) - data->queue.back = 0; - data->queue.size++; - } - else - std::cerr << "\nMidiInCore: message queue limit reached!!\n\n"; - } - message.bytes.clear(); - } - iByte += size; - } - } - } - packet = MIDIPacketNext(packet); - } + // Copy the MIDI data to our vector. + if (size) + { + message.bytes.assign(&packet->data[iByte], &packet->data[iByte + size]); + if (!continueSysex) + { + // If not a continuing sysex message, invoke the user callback function or queue the message. + if (data->usingCallback) + { + RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback)data->userCallback; + callback(message.timeStamp, &message.bytes, data->userData); + } + else + { + // As long as we haven't reached our queue size limit, push the message. + if (data->queue.size < data->queue.ringSize) + { + data->queue.ring[data->queue.back++] = message; + if (data->queue.back == data->queue.ringSize) + data->queue.back = 0; + data->queue.size++; + } + else + std::cerr << "\nMidiInCore: message queue limit reached!!\n\n"; + } + message.bytes.clear(); + } + iByte += size; + } + } + } + packet = MIDIPacketNext(packet); + } } -MidiInCore :: MidiInCore( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) +MidiInCore ::MidiInCore(const std::string clientName, unsigned int queueSizeLimit) : MidiInApi(queueSizeLimit) { - initialize( clientName ); + initialize(clientName); } -MidiInCore :: ~MidiInCore( void ) +MidiInCore ::~MidiInCore(void) { - // Close a connection if it exists. - closePort(); + // Close a connection if it exists. + closePort(); - // Cleanup. - CoreMidiData *data = static_cast (apiData_); - MIDIClientDispose( data->client ); - if ( data->endpoint ) MIDIEndpointDispose( data->endpoint ); - delete data; + // Cleanup. + CoreMidiData *data = static_cast(apiData_); + MIDIClientDispose(data->client); + if (data->endpoint) MIDIEndpointDispose(data->endpoint); + delete data; } -void MidiInCore :: initialize( const std::string& clientName ) +void MidiInCore ::initialize(const std::string &clientName) { - // Set up our client. - MIDIClientRef client; - OSStatus result = MIDIClientCreate( CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII ), NULL, NULL, &client ); - if ( result != noErr ) { - errorString_ = "MidiInCore::initialize: error creating OS-X MIDI client object."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + // Set up our client. + MIDIClientRef client; + OSStatus result = MIDIClientCreate(CFStringCreateWithCString(NULL, clientName.c_str(), kCFStringEncodingASCII), NULL, NULL, &client); + if (result != noErr) + { + errorString_ = "MidiInCore::initialize: error creating OS-X MIDI client object."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - // Save our api-specific connection information. - CoreMidiData *data = (CoreMidiData *) new CoreMidiData; - data->client = client; - data->endpoint = 0; - apiData_ = (void *) data; - inputData_.apiData = (void *) data; + // Save our api-specific connection information. + CoreMidiData *data = (CoreMidiData *)new CoreMidiData; + data->client = client; + data->endpoint = 0; + apiData_ = (void *)data; + inputData_.apiData = (void *)data; } -void MidiInCore :: openPort( unsigned int portNumber, const std::string portName ) +void MidiInCore ::openPort(unsigned int portNumber, const std::string portName) { - if ( connected_ ) { - errorString_ = "MidiInCore::openPort: a valid connection already exists!"; - RtMidi::error( RtError::WARNING, errorString_ ); - return; - } + if (connected_) + { + errorString_ = "MidiInCore::openPort: a valid connection already exists!"; + RtMidi::error(RtError::WARNING, errorString_); + return; + } - unsigned int nSrc = MIDIGetNumberOfSources(); - if (nSrc < 1) { - errorString_ = "MidiInCore::openPort: no MIDI input sources found!"; - RtMidi::error( RtError::NO_DEVICES_FOUND, errorString_ ); - } + unsigned int nSrc = MIDIGetNumberOfSources(); + if (nSrc < 1) + { + errorString_ = "MidiInCore::openPort: no MIDI input sources found!"; + RtMidi::error(RtError::NO_DEVICES_FOUND, errorString_); + } - std::ostringstream ost; - if ( portNumber >= nSrc ) { - ost << "MidiInCore::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - RtMidi::error( RtError::INVALID_PARAMETER, errorString_ ); - } + std::ostringstream ost; + if (portNumber >= nSrc) + { + ost << "MidiInCore::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + RtMidi::error(RtError::INVALID_PARAMETER, errorString_); + } - MIDIPortRef port; - CoreMidiData *data = static_cast (apiData_); - OSStatus result = MIDIInputPortCreate( data->client, - CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ), - midiInputCallback, (void *)&inputData_, &port ); - if ( result != noErr ) { - MIDIClientDispose( data->client ); - errorString_ = "MidiInCore::openPort: error creating OS-X MIDI input port."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + MIDIPortRef port; + CoreMidiData *data = static_cast(apiData_); + OSStatus result = MIDIInputPortCreate(data->client, + CFStringCreateWithCString(NULL, portName.c_str(), kCFStringEncodingASCII), + midiInputCallback, (void *)&inputData_, &port); + if (result != noErr) + { + MIDIClientDispose(data->client); + errorString_ = "MidiInCore::openPort: error creating OS-X MIDI input port."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - // Get the desired input source identifier. - MIDIEndpointRef endpoint = MIDIGetSource( portNumber ); - if ( endpoint == 0 ) { - MIDIPortDispose( port ); - MIDIClientDispose( data->client ); - errorString_ = "MidiInCore::openPort: error getting MIDI input source reference."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + // Get the desired input source identifier. + MIDIEndpointRef endpoint = MIDIGetSource(portNumber); + if (endpoint == 0) + { + MIDIPortDispose(port); + MIDIClientDispose(data->client); + errorString_ = "MidiInCore::openPort: error getting MIDI input source reference."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - // Make the connection. - result = MIDIPortConnectSource( port, endpoint, NULL ); - if ( result != noErr ) { - MIDIPortDispose( port ); - MIDIClientDispose( data->client ); - errorString_ = "MidiInCore::openPort: error connecting OS-X MIDI input port."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + // Make the connection. + result = MIDIPortConnectSource(port, endpoint, NULL); + if (result != noErr) + { + MIDIPortDispose(port); + MIDIClientDispose(data->client); + errorString_ = "MidiInCore::openPort: error connecting OS-X MIDI input port."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - // Save our api-specific port information. - data->port = port; + // Save our api-specific port information. + data->port = port; - connected_ = true; + connected_ = true; } -void MidiInCore :: openVirtualPort( const std::string portName ) +void MidiInCore ::openVirtualPort(const std::string portName) { - CoreMidiData *data = static_cast (apiData_); + CoreMidiData *data = static_cast(apiData_); - // Create a virtual MIDI input destination. - MIDIEndpointRef endpoint; - OSStatus result = MIDIDestinationCreate( data->client, - CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ), - midiInputCallback, (void *)&inputData_, &endpoint ); - if ( result != noErr ) { - errorString_ = "MidiInCore::openVirtualPort: error creating virtual OS-X MIDI destination."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + // Create a virtual MIDI input destination. + MIDIEndpointRef endpoint; + OSStatus result = MIDIDestinationCreate(data->client, + CFStringCreateWithCString(NULL, portName.c_str(), kCFStringEncodingASCII), + midiInputCallback, (void *)&inputData_, &endpoint); + if (result != noErr) + { + errorString_ = "MidiInCore::openVirtualPort: error creating virtual OS-X MIDI destination."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - // Save our api-specific connection information. - data->endpoint = endpoint; + // Save our api-specific connection information. + data->endpoint = endpoint; } -void MidiInCore :: closePort( void ) +void MidiInCore ::closePort(void) { - if ( connected_ ) { - CoreMidiData *data = static_cast (apiData_); - MIDIPortDispose( data->port ); - connected_ = false; - } + if (connected_) + { + CoreMidiData *data = static_cast(apiData_); + MIDIPortDispose(data->port); + connected_ = false; + } } -unsigned int MidiInCore :: getPortCount() +unsigned int MidiInCore ::getPortCount() { - return MIDIGetNumberOfSources(); + return MIDIGetNumberOfSources(); } // This function was submitted by Douglas Casey Tucker and apparently // derived largely from PortMidi. -CFStringRef EndpointName( MIDIEndpointRef endpoint, bool isExternal ) +CFStringRef EndpointName(MIDIEndpointRef endpoint, bool isExternal) { - CFMutableStringRef result = CFStringCreateMutable( NULL, 0 ); - CFStringRef str; + CFMutableStringRef result = CFStringCreateMutable(NULL, 0); + CFStringRef str; - // Begin with the endpoint's name. - str = NULL; - MIDIObjectGetStringProperty( endpoint, kMIDIPropertyName, &str ); - if ( str != NULL ) { - CFStringAppend( result, str ); - CFRelease( str ); - } + // Begin with the endpoint's name. + str = NULL; + MIDIObjectGetStringProperty(endpoint, kMIDIPropertyName, &str); + if (str != NULL) + { + CFStringAppend(result, str); + CFRelease(str); + } - MIDIEntityRef entity = NULL; - MIDIEndpointGetEntity( endpoint, &entity ); - if ( entity == 0 ) - // probably virtual - return result; + MIDIEntityRef entity = NULL; + MIDIEndpointGetEntity(endpoint, &entity); + if (entity == 0) + // probably virtual + return result; - if ( CFStringGetLength( result ) == 0 ) { - // endpoint name has zero length -- try the entity - str = NULL; - MIDIObjectGetStringProperty( entity, kMIDIPropertyName, &str ); - if ( str != NULL ) { - CFStringAppend( result, str ); - CFRelease( str ); - } - } - // now consider the device's name - MIDIDeviceRef device = 0; - MIDIEntityGetDevice( entity, &device ); - if ( device == 0 ) - return result; + if (CFStringGetLength(result) == 0) + { + // endpoint name has zero length -- try the entity + str = NULL; + MIDIObjectGetStringProperty(entity, kMIDIPropertyName, &str); + if (str != NULL) + { + CFStringAppend(result, str); + CFRelease(str); + } + } + // now consider the device's name + MIDIDeviceRef device = 0; + MIDIEntityGetDevice(entity, &device); + if (device == 0) + return result; - str = NULL; - MIDIObjectGetStringProperty( device, kMIDIPropertyName, &str ); - if ( CFStringGetLength( result ) == 0 ) { - CFRelease( result ); - return str; - } - if ( str != NULL ) { - // if an external device has only one entity, throw away - // the endpoint name and just use the device name - if ( isExternal && MIDIDeviceGetNumberOfEntities( device ) < 2 ) { - CFRelease( result ); - return str; - } else { - if ( CFStringGetLength( str ) == 0 ) { - CFRelease( str ); - return result; - } - // does the entity name already start with the device name? - // (some drivers do this though they shouldn't) - // if so, do not prepend - if ( CFStringCompareWithOptions( result, /* endpoint name */ - str /* device name */, - CFRangeMake(0, CFStringGetLength( str ) ), 0 ) != kCFCompareEqualTo ) { - // prepend the device name to the entity name - if ( CFStringGetLength( result ) > 0 ) - CFStringInsert( result, 0, CFSTR(" ") ); - CFStringInsert( result, 0, str ); - } - CFRelease( str ); - } - } - return result; + str = NULL; + MIDIObjectGetStringProperty(device, kMIDIPropertyName, &str); + if (CFStringGetLength(result) == 0) + { + CFRelease(result); + return str; + } + if (str != NULL) + { + // if an external device has only one entity, throw away + // the endpoint name and just use the device name + if (isExternal && MIDIDeviceGetNumberOfEntities(device) < 2) + { + CFRelease(result); + return str; + } + else + { + if (CFStringGetLength(str) == 0) + { + CFRelease(str); + return result; + } + // does the entity name already start with the device name? + // (some drivers do this though they shouldn't) + // if so, do not prepend + if (CFStringCompareWithOptions(result, /* endpoint name */ + str /* device name */, + CFRangeMake(0, CFStringGetLength(str)), 0) != kCFCompareEqualTo) + { + // prepend the device name to the entity name + if (CFStringGetLength(result) > 0) + CFStringInsert(result, 0, CFSTR(" ")); + CFStringInsert(result, 0, str); + } + CFRelease(str); + } + } + return result; } // This function was submitted by Douglas Casey Tucker and apparently // derived largely from PortMidi. -static CFStringRef ConnectedEndpointName( MIDIEndpointRef endpoint ) +static CFStringRef ConnectedEndpointName(MIDIEndpointRef endpoint) { - CFMutableStringRef result = CFStringCreateMutable( NULL, 0 ); - CFStringRef str; - OSStatus err; - int i; + CFMutableStringRef result = CFStringCreateMutable(NULL, 0); + CFStringRef str; + OSStatus err; + int i; - // Does the endpoint have connections? - CFDataRef connections = NULL; - int nConnected = 0; - bool anyStrings = false; - err = MIDIObjectGetDataProperty( endpoint, kMIDIPropertyConnectionUniqueID, &connections ); - if ( connections != NULL ) { - // It has connections, follow them - // Concatenate the names of all connected devices - nConnected = CFDataGetLength( connections ) / sizeof(MIDIUniqueID); - if ( nConnected ) { - const SInt32 *pid = (const SInt32 *)(CFDataGetBytePtr(connections)); - for ( i=0; i= MIDIGetNumberOfSources() ) { - ost << "MidiInCore::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - RtMidi::error( RtError::WARNING, errorString_ ); - //RtMidi::error( RtError::INVALID_PARAMETER, errorString_ ); - return stringName; - } + std::string stringName; + if (portNumber >= MIDIGetNumberOfSources()) + { + ost << "MidiInCore::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + RtMidi::error(RtError::WARNING, errorString_); + //RtMidi::error( RtError::INVALID_PARAMETER, errorString_ ); + return stringName; + } - portRef = MIDIGetSource( portNumber ); - nameRef = ConnectedEndpointName(portRef); - CFStringGetCString( nameRef, name, sizeof(name), 0); - CFRelease( nameRef ); + portRef = MIDIGetSource(portNumber); + nameRef = ConnectedEndpointName(portRef); + CFStringGetCString(nameRef, name, sizeof(name), 0); + CFRelease(nameRef); - return stringName = name; + return stringName = name; } //*********************************************************************// @@ -791,239 +864,256 @@ std::string MidiInCore :: getPortName( unsigned int portNumber ) // Class Definitions: MidiOutCore //*********************************************************************// -MidiOutCore :: MidiOutCore( const std::string clientName ) : MidiOutApi() +MidiOutCore ::MidiOutCore(const std::string clientName) : MidiOutApi() { - initialize( clientName ); + initialize(clientName); } -MidiOutCore :: ~MidiOutCore( void ) +MidiOutCore ::~MidiOutCore(void) { - // Close a connection if it exists. - closePort(); + // Close a connection if it exists. + closePort(); - // Cleanup. - CoreMidiData *data = static_cast (apiData_); - MIDIClientDispose( data->client ); - if ( data->endpoint ) MIDIEndpointDispose( data->endpoint ); - delete data; + // Cleanup. + CoreMidiData *data = static_cast(apiData_); + MIDIClientDispose(data->client); + if (data->endpoint) MIDIEndpointDispose(data->endpoint); + delete data; } -void MidiOutCore :: initialize( const std::string& clientName ) +void MidiOutCore ::initialize(const std::string &clientName) { - // Set up our client. - MIDIClientRef client; - OSStatus result = MIDIClientCreate( CFStringCreateWithCString( NULL, clientName.c_str(), kCFStringEncodingASCII ), NULL, NULL, &client ); - if ( result != noErr ) { - errorString_ = "MidiOutCore::initialize: error creating OS-X MIDI client object."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + // Set up our client. + MIDIClientRef client; + OSStatus result = MIDIClientCreate(CFStringCreateWithCString(NULL, clientName.c_str(), kCFStringEncodingASCII), NULL, NULL, &client); + if (result != noErr) + { + errorString_ = "MidiOutCore::initialize: error creating OS-X MIDI client object."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - // Save our api-specific connection information. - CoreMidiData *data = (CoreMidiData *) new CoreMidiData; - data->client = client; - data->endpoint = 0; - apiData_ = (void *) data; + // Save our api-specific connection information. + CoreMidiData *data = (CoreMidiData *)new CoreMidiData; + data->client = client; + data->endpoint = 0; + apiData_ = (void *)data; } -unsigned int MidiOutCore :: getPortCount() +unsigned int MidiOutCore ::getPortCount() { - return MIDIGetNumberOfDestinations(); + return MIDIGetNumberOfDestinations(); } -std::string MidiOutCore :: getPortName( unsigned int portNumber ) +std::string MidiOutCore ::getPortName(unsigned int portNumber) { - CFStringRef nameRef; - MIDIEndpointRef portRef; - std::ostringstream ost; - char name[128]; + CFStringRef nameRef; + MIDIEndpointRef portRef; + std::ostringstream ost; + char name[128]; - std::string stringName; - if ( portNumber >= MIDIGetNumberOfDestinations() ) { - ost << "MidiOutCore::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - RtMidi::error( RtError::WARNING, errorString_ ); - return stringName; - //RtMidi::error( RtError::INVALID_PARAMETER, errorString_ ); - } + std::string stringName; + if (portNumber >= MIDIGetNumberOfDestinations()) + { + ost << "MidiOutCore::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + RtMidi::error(RtError::WARNING, errorString_); + return stringName; + //RtMidi::error( RtError::INVALID_PARAMETER, errorString_ ); + } - portRef = MIDIGetDestination( portNumber ); - nameRef = ConnectedEndpointName(portRef); - CFStringGetCString( nameRef, name, sizeof(name), 0); - CFRelease( nameRef ); - - return stringName = name; + portRef = MIDIGetDestination(portNumber); + nameRef = ConnectedEndpointName(portRef); + CFStringGetCString(nameRef, name, sizeof(name), 0); + CFRelease(nameRef); + + return stringName = name; } -void MidiOutCore :: openPort( unsigned int portNumber, const std::string portName ) +void MidiOutCore ::openPort(unsigned int portNumber, const std::string portName) { - if ( connected_ ) { - errorString_ = "MidiOutCore::openPort: a valid connection already exists!"; - RtMidi::error( RtError::WARNING, errorString_ ); - return; - } + if (connected_) + { + errorString_ = "MidiOutCore::openPort: a valid connection already exists!"; + RtMidi::error(RtError::WARNING, errorString_); + return; + } - unsigned int nDest = MIDIGetNumberOfDestinations(); - if (nDest < 1) { - errorString_ = "MidiOutCore::openPort: no MIDI output destinations found!"; - RtMidi::error( RtError::NO_DEVICES_FOUND, errorString_ ); - } + unsigned int nDest = MIDIGetNumberOfDestinations(); + if (nDest < 1) + { + errorString_ = "MidiOutCore::openPort: no MIDI output destinations found!"; + RtMidi::error(RtError::NO_DEVICES_FOUND, errorString_); + } - std::ostringstream ost; - if ( portNumber >= nDest ) { - ost << "MidiOutCore::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - RtMidi::error( RtError::INVALID_PARAMETER, errorString_ ); - } + std::ostringstream ost; + if (portNumber >= nDest) + { + ost << "MidiOutCore::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + RtMidi::error(RtError::INVALID_PARAMETER, errorString_); + } - MIDIPortRef port; - CoreMidiData *data = static_cast (apiData_); - OSStatus result = MIDIOutputPortCreate( data->client, - CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ), - &port ); - if ( result != noErr ) { - MIDIClientDispose( data->client ); - errorString_ = "MidiOutCore::openPort: error creating OS-X MIDI output port."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + MIDIPortRef port; + CoreMidiData *data = static_cast(apiData_); + OSStatus result = MIDIOutputPortCreate(data->client, + CFStringCreateWithCString(NULL, portName.c_str(), kCFStringEncodingASCII), + &port); + if (result != noErr) + { + MIDIClientDispose(data->client); + errorString_ = "MidiOutCore::openPort: error creating OS-X MIDI output port."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - // Get the desired output port identifier. - MIDIEndpointRef destination = MIDIGetDestination( portNumber ); - if ( destination == 0 ) { - MIDIPortDispose( port ); - MIDIClientDispose( data->client ); - errorString_ = "MidiOutCore::openPort: error getting MIDI output destination reference."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + // Get the desired output port identifier. + MIDIEndpointRef destination = MIDIGetDestination(portNumber); + if (destination == 0) + { + MIDIPortDispose(port); + MIDIClientDispose(data->client); + errorString_ = "MidiOutCore::openPort: error getting MIDI output destination reference."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - // Save our api-specific connection information. - data->port = port; - data->destinationId = destination; - connected_ = true; + // Save our api-specific connection information. + data->port = port; + data->destinationId = destination; + connected_ = true; } -void MidiOutCore :: closePort( void ) +void MidiOutCore ::closePort(void) { - if ( connected_ ) { - CoreMidiData *data = static_cast (apiData_); - MIDIPortDispose( data->port ); - connected_ = false; - } + if (connected_) + { + CoreMidiData *data = static_cast(apiData_); + MIDIPortDispose(data->port); + connected_ = false; + } } -void MidiOutCore :: openVirtualPort( std::string portName ) +void MidiOutCore ::openVirtualPort(std::string portName) { - CoreMidiData *data = static_cast (apiData_); + CoreMidiData *data = static_cast(apiData_); - if ( data->endpoint ) { - errorString_ = "MidiOutCore::openVirtualPort: a virtual output port already exists!"; - RtMidi::error( RtError::WARNING, errorString_ ); - return; - } + if (data->endpoint) + { + errorString_ = "MidiOutCore::openVirtualPort: a virtual output port already exists!"; + RtMidi::error(RtError::WARNING, errorString_); + return; + } - // Create a virtual MIDI output source. - MIDIEndpointRef endpoint; - OSStatus result = MIDISourceCreate( data->client, - CFStringCreateWithCString( NULL, portName.c_str(), kCFStringEncodingASCII ), - &endpoint ); - if ( result != noErr ) { - errorString_ = "MidiOutCore::initialize: error creating OS-X virtual MIDI source."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + // Create a virtual MIDI output source. + MIDIEndpointRef endpoint; + OSStatus result = MIDISourceCreate(data->client, + CFStringCreateWithCString(NULL, portName.c_str(), kCFStringEncodingASCII), + &endpoint); + if (result != noErr) + { + errorString_ = "MidiOutCore::initialize: error creating OS-X virtual MIDI source."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - // Save our api-specific connection information. - data->endpoint = endpoint; + // Save our api-specific connection information. + data->endpoint = endpoint; } char *sysexBuffer = 0; -void sysexCompletionProc( MIDISysexSendRequest * sreq ) +void sysexCompletionProc(MIDISysexSendRequest *sreq) { - //std::cout << "Completed SysEx send\n"; - delete sysexBuffer; - sysexBuffer = 0; + //std::cout << "Completed SysEx send\n"; + delete sysexBuffer; + sysexBuffer = 0; } -void MidiOutCore :: sendMessage( std::vector *message ) +void MidiOutCore ::sendMessage(std::vector *message) { - // We use the MIDISendSysex() function to asynchronously send sysex - // messages. Otherwise, we use a single CoreMidi MIDIPacket. - unsigned int nBytes = message->size(); - if ( nBytes == 0 ) { - errorString_ = "MidiOutCore::sendMessage: no data in message argument!"; - RtMidi::error( RtError::WARNING, errorString_ ); - return; - } + // We use the MIDISendSysex() function to asynchronously send sysex + // messages. Otherwise, we use a single CoreMidi MIDIPacket. + unsigned int nBytes = message->size(); + if (nBytes == 0) + { + errorString_ = "MidiOutCore::sendMessage: no data in message argument!"; + RtMidi::error(RtError::WARNING, errorString_); + return; + } - // unsigned int packetBytes, bytesLeft = nBytes; - // unsigned int messageIndex = 0; - MIDITimeStamp timeStamp = AudioGetCurrentHostTime(); - CoreMidiData *data = static_cast (apiData_); - OSStatus result; + // unsigned int packetBytes, bytesLeft = nBytes; + // unsigned int messageIndex = 0; + MIDITimeStamp timeStamp = AudioGetCurrentHostTime(); + CoreMidiData *data = static_cast(apiData_); + OSStatus result; - if ( message->at(0) == 0xF0 ) { + if (message->at(0) == 0xF0) + { + while (sysexBuffer != 0) usleep(1000); // sleep 1 ms - while ( sysexBuffer != 0 ) usleep( 1000 ); // sleep 1 ms + sysexBuffer = new char[nBytes]; + if (sysexBuffer == NULL) + { + errorString_ = "MidiOutCore::sendMessage: error allocating sysex message memory!"; + RtMidi::error(RtError::MEMORY_ERROR, errorString_); + } - sysexBuffer = new char[nBytes]; - if ( sysexBuffer == NULL ) { - errorString_ = "MidiOutCore::sendMessage: error allocating sysex message memory!"; - RtMidi::error( RtError::MEMORY_ERROR, errorString_ ); - } + // Copy data to buffer. + for (unsigned int i = 0; i < nBytes; ++i) sysexBuffer[i] = message->at(i); - // Copy data to buffer. - for ( unsigned int i=0; iat(i); + data->sysexreq.destination = data->destinationId; + data->sysexreq.data = (Byte *)sysexBuffer; + data->sysexreq.bytesToSend = nBytes; + data->sysexreq.complete = 0; + data->sysexreq.completionProc = sysexCompletionProc; + data->sysexreq.completionRefCon = &(data->sysexreq); - data->sysexreq.destination = data->destinationId; - data->sysexreq.data = (Byte *)sysexBuffer; - data->sysexreq.bytesToSend = nBytes; - data->sysexreq.complete = 0; - data->sysexreq.completionProc = sysexCompletionProc; - data->sysexreq.completionRefCon = &(data->sysexreq); + result = MIDISendSysex(&(data->sysexreq)); + if (result != noErr) + { + errorString_ = "MidiOutCore::sendMessage: error sending MIDI to virtual destinations."; + RtMidi::error(RtError::WARNING, errorString_); + } + return; + } + else if (nBytes > 3) + { + errorString_ = "MidiOutCore::sendMessage: message format problem ... not sysex but > 3 bytes?"; + RtMidi::error(RtError::WARNING, errorString_); + return; + } - result = MIDISendSysex( &(data->sysexreq) ); - if ( result != noErr ) { - errorString_ = "MidiOutCore::sendMessage: error sending MIDI to virtual destinations."; - RtMidi::error( RtError::WARNING, errorString_ ); - } - return; - } - else if ( nBytes > 3 ) { - errorString_ = "MidiOutCore::sendMessage: message format problem ... not sysex but > 3 bytes?"; - RtMidi::error( RtError::WARNING, errorString_ ); - return; - } + MIDIPacketList packetList; + MIDIPacket *packet = MIDIPacketListInit(&packetList); + packet = MIDIPacketListAdd(&packetList, sizeof(packetList), packet, timeStamp, nBytes, (const Byte *)&message->at(0)); + if (!packet) + { + errorString_ = "MidiOutCore::sendMessage: could not allocate packet list"; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - MIDIPacketList packetList; - MIDIPacket *packet = MIDIPacketListInit( &packetList ); - packet = MIDIPacketListAdd( &packetList, sizeof(packetList), packet, timeStamp, nBytes, (const Byte *) &message->at( 0 ) ); - if ( !packet ) { - errorString_ = "MidiOutCore::sendMessage: could not allocate packet list"; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } - - // Send to any destinations that may have connected to us. - if ( data->endpoint ) { - result = MIDIReceived( data->endpoint, &packetList ); - if ( result != noErr ) { - errorString_ = "MidiOutCore::sendMessage: error sending MIDI to virtual destinations."; - RtMidi::error( RtError::WARNING, errorString_ ); - } - } - - // And send to an explicit destination port if we're connected. - if ( connected_ ) { - result = MIDISend( data->port, data->destinationId, &packetList ); - if ( result != noErr ) { - errorString_ = "MidiOutCore::sendMessage: error sending MIDI message to port."; - RtMidi::error( RtError::WARNING, errorString_ ); - } - } + // Send to any destinations that may have connected to us. + if (data->endpoint) + { + result = MIDIReceived(data->endpoint, &packetList); + if (result != noErr) + { + errorString_ = "MidiOutCore::sendMessage: error sending MIDI to virtual destinations."; + RtMidi::error(RtError::WARNING, errorString_); + } + } + // And send to an explicit destination port if we're connected. + if (connected_) + { + result = MIDISend(data->port, data->destinationId, &packetList); + if (result != noErr) + { + errorString_ = "MidiOutCore::sendMessage: error sending MIDI message to port."; + RtMidi::error(RtError::WARNING, errorString_); + } + } } #endif // __MACOSX_CORE__ - //*********************************************************************// // API: LINUX ALSA SEQUENCER //*********************************************************************// @@ -1062,53 +1152,59 @@ static std::string s_clientName = "RtMidi Client"; // A structure to hold variables related to the ALSA API // implementation. -struct AlsaMidiData { - snd_seq_t *seq; - unsigned int portNum; - int vport; - snd_seq_port_subscribe_t *subscription; - snd_midi_event_t *coder; - unsigned int bufferSize; - unsigned char *buffer; - pthread_t thread; - pthread_t dummy_thread_id; - unsigned long long lastTime; - int queue_id; // an input queue is needed to get timestamped events - int trigger_fds[2]; +struct AlsaMidiData +{ + snd_seq_t *seq; + unsigned int portNum; + int vport; + snd_seq_port_subscribe_t *subscription; + snd_midi_event_t *coder; + unsigned int bufferSize; + unsigned char *buffer; + pthread_t thread; + pthread_t dummy_thread_id; + unsigned long long lastTime; + int queue_id; // an input queue is needed to get timestamped events + int trigger_fds[2]; }; -#define PORT_TYPE( pinfo, bits ) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits)) +#define PORT_TYPE(pinfo, bits) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits)) -snd_seq_t* createSequencer( const std::string& clientName ) +snd_seq_t *createSequencer(const std::string &clientName) { - // Set up the ALSA sequencer client. - if ( s_seq == NULL ) { - int result = snd_seq_open(&s_seq, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK); - if ( result < 0 ) { - s_seq = NULL; - } - else { - // Set client name, use current name if given string is empty. - if ( clientName != "" ) { - s_clientName = clientName; - } - snd_seq_set_client_name( s_seq, s_clientName.c_str() ); - } - } + // Set up the ALSA sequencer client. + if (s_seq == NULL) + { + int result = snd_seq_open(&s_seq, "default", SND_SEQ_OPEN_DUPLEX, SND_SEQ_NONBLOCK); + if (result < 0) + { + s_seq = NULL; + } + else + { + // Set client name, use current name if given string is empty. + if (clientName != "") + { + s_clientName = clientName; + } + snd_seq_set_client_name(s_seq, s_clientName.c_str()); + } + } - // Increment port count. - s_numPorts++; + // Increment port count. + s_numPorts++; - return s_seq; + return s_seq; } -void freeSequencer ( void ) +void freeSequencer(void) { - s_numPorts--; - if ( s_numPorts == 0 && s_seq != NULL ) { - snd_seq_close( s_seq ); - s_seq = NULL; - } + s_numPorts--; + if (s_numPorts == 0 && s_seq != NULL) + { + snd_seq_close(s_seq); + s_seq = NULL; + } } //*********************************************************************// @@ -1116,516 +1212,553 @@ void freeSequencer ( void ) // Class Definitions: MidiInAlsa //*********************************************************************// -extern "C" void *alsaMidiHandler( void *ptr ) +extern "C" void *alsaMidiHandler(void *ptr) { - MidiInApi::RtMidiInData *data = static_cast (ptr); - AlsaMidiData *apiData = static_cast (data->apiData); + MidiInApi::RtMidiInData *data = static_cast(ptr); + AlsaMidiData *apiData = static_cast(data->apiData); - long nBytes; - unsigned long long time, lastTime; - bool continueSysex = false; - bool doDecode = false; - MidiInApi::MidiMessage message; - int poll_fd_count; - struct pollfd *poll_fds; + long nBytes; + unsigned long long time, lastTime; + bool continueSysex = false; + bool doDecode = false; + MidiInApi::MidiMessage message; + int poll_fd_count; + struct pollfd *poll_fds; - snd_seq_event_t *ev; - int result; - apiData->bufferSize = 32; - result = snd_midi_event_new( 0, &apiData->coder ); - if ( result < 0 ) { - data->doInput = false; - std::cerr << "\nMidiInAlsa::alsaMidiHandler: error initializing MIDI event parser!\n\n"; - return 0; - } - unsigned char *buffer = (unsigned char *) malloc( apiData->bufferSize ); - if ( buffer == NULL ) { - data->doInput = false; - snd_midi_event_free( apiData->coder ); - apiData->coder = 0; - std::cerr << "\nMidiInAlsa::alsaMidiHandler: error initializing buffer memory!\n\n"; - return 0; - } - snd_midi_event_init( apiData->coder ); - snd_midi_event_no_status( apiData->coder, 1 ); // suppress running status messages + snd_seq_event_t *ev; + int result; + apiData->bufferSize = 32; + result = snd_midi_event_new(0, &apiData->coder); + if (result < 0) + { + data->doInput = false; + std::cerr << "\nMidiInAlsa::alsaMidiHandler: error initializing MIDI event parser!\n\n"; + return 0; + } + unsigned char *buffer = (unsigned char *)malloc(apiData->bufferSize); + if (buffer == NULL) + { + data->doInput = false; + snd_midi_event_free(apiData->coder); + apiData->coder = 0; + std::cerr << "\nMidiInAlsa::alsaMidiHandler: error initializing buffer memory!\n\n"; + return 0; + } + snd_midi_event_init(apiData->coder); + snd_midi_event_no_status(apiData->coder, 1); // suppress running status messages - poll_fd_count = snd_seq_poll_descriptors_count( apiData->seq, POLLIN ) + 1; - poll_fds = (struct pollfd*)alloca( poll_fd_count * sizeof( struct pollfd )); - snd_seq_poll_descriptors( apiData->seq, poll_fds + 1, poll_fd_count - 1, POLLIN ); - poll_fds[0].fd = apiData->trigger_fds[0]; - poll_fds[0].events = POLLIN; + poll_fd_count = snd_seq_poll_descriptors_count(apiData->seq, POLLIN) + 1; + poll_fds = (struct pollfd *)alloca(poll_fd_count * sizeof(struct pollfd)); + snd_seq_poll_descriptors(apiData->seq, poll_fds + 1, poll_fd_count - 1, POLLIN); + poll_fds[0].fd = apiData->trigger_fds[0]; + poll_fds[0].events = POLLIN; - while ( data->doInput ) { + while (data->doInput) + { + if (snd_seq_event_input_pending(apiData->seq, 1) == 0) + { + // No data pending + if (poll(poll_fds, poll_fd_count, -1) >= 0) + { + if (poll_fds[0].revents & POLLIN) + { + bool dummy; + int res = read(poll_fds[0].fd, &dummy, sizeof(dummy)); + (void)res; + } + } + continue; + } - if ( snd_seq_event_input_pending( apiData->seq, 1 ) == 0 ) { - // No data pending - if ( poll( poll_fds, poll_fd_count, -1) >= 0 ) { - if ( poll_fds[0].revents & POLLIN ) { - bool dummy; - int res = read( poll_fds[0].fd, &dummy, sizeof(dummy) ); - (void) res; - } - } - continue; - } + // If here, there should be data. + result = snd_seq_event_input(apiData->seq, &ev); + if (result == -ENOSPC) + { + std::cerr << "\nMidiInAlsa::alsaMidiHandler: MIDI input buffer overrun!\n\n"; + continue; + } + else if (result <= 0) + { + std::cerr << "MidiInAlsa::alsaMidiHandler: unknown MIDI input error!\n"; + continue; + } - // If here, there should be data. - result = snd_seq_event_input( apiData->seq, &ev ); - if ( result == -ENOSPC ) { - std::cerr << "\nMidiInAlsa::alsaMidiHandler: MIDI input buffer overrun!\n\n"; - continue; - } - else if ( result <= 0 ) { - std::cerr << "MidiInAlsa::alsaMidiHandler: unknown MIDI input error!\n"; - continue; - } + // This is a bit weird, but we now have to decode an ALSA MIDI + // event (back) into MIDI bytes. We'll ignore non-MIDI types. + if (!continueSysex) message.bytes.clear(); - // This is a bit weird, but we now have to decode an ALSA MIDI - // event (back) into MIDI bytes. We'll ignore non-MIDI types. - if ( !continueSysex ) message.bytes.clear(); - - doDecode = false; - switch ( ev->type ) { - - case SND_SEQ_EVENT_PORT_SUBSCRIBED: + doDecode = false; + switch (ev->type) + { + case SND_SEQ_EVENT_PORT_SUBSCRIBED: #if defined(__RTMIDI_DEBUG__) - std::cout << "MidiInAlsa::alsaMidiHandler: port connection made!\n"; + std::cout << "MidiInAlsa::alsaMidiHandler: port connection made!\n"; #endif - break; + break; - case SND_SEQ_EVENT_PORT_UNSUBSCRIBED: + case SND_SEQ_EVENT_PORT_UNSUBSCRIBED: #if defined(__RTMIDI_DEBUG__) - std::cerr << "MidiInAlsa::alsaMidiHandler: port connection has closed!\n"; - std::cout << "sender = " << (int) ev->data.connect.sender.client << ":" - << (int) ev->data.connect.sender.port - << ", dest = " << (int) ev->data.connect.dest.client << ":" - << (int) ev->data.connect.dest.port - << std::endl; + std::cerr << "MidiInAlsa::alsaMidiHandler: port connection has closed!\n"; + std::cout << "sender = " << (int)ev->data.connect.sender.client << ":" + << (int)ev->data.connect.sender.port + << ", dest = " << (int)ev->data.connect.dest.client << ":" + << (int)ev->data.connect.dest.port + << std::endl; #endif - break; + break; - case SND_SEQ_EVENT_QFRAME: // MIDI time code - if ( !( data->ignoreFlags & 0x02 ) ) doDecode = true; - break; + case SND_SEQ_EVENT_QFRAME: // MIDI time code + if (!(data->ignoreFlags & 0x02)) doDecode = true; + break; - case SND_SEQ_EVENT_TICK: // MIDI timing tick - if ( !( data->ignoreFlags & 0x02 ) ) doDecode = true; - break; + case SND_SEQ_EVENT_TICK: // MIDI timing tick + if (!(data->ignoreFlags & 0x02)) doDecode = true; + break; - case SND_SEQ_EVENT_SENSING: // Active sensing - if ( !( data->ignoreFlags & 0x04 ) ) doDecode = true; - break; + case SND_SEQ_EVENT_SENSING: // Active sensing + if (!(data->ignoreFlags & 0x04)) doDecode = true; + break; - case SND_SEQ_EVENT_SYSEX: - if ( (data->ignoreFlags & 0x01) ) break; - if ( ev->data.ext.len > apiData->bufferSize ) { - apiData->bufferSize = ev->data.ext.len; - free( buffer ); - buffer = (unsigned char *) malloc( apiData->bufferSize ); - if ( buffer == NULL ) { - data->doInput = false; - std::cerr << "\nMidiInAlsa::alsaMidiHandler: error resizing buffer memory!\n\n"; - break; - } - } + case SND_SEQ_EVENT_SYSEX: + if ((data->ignoreFlags & 0x01)) break; + if (ev->data.ext.len > apiData->bufferSize) + { + apiData->bufferSize = ev->data.ext.len; + free(buffer); + buffer = (unsigned char *)malloc(apiData->bufferSize); + if (buffer == NULL) + { + data->doInput = false; + std::cerr << "\nMidiInAlsa::alsaMidiHandler: error resizing buffer memory!\n\n"; + break; + } + } - default: - doDecode = true; - } + default: + doDecode = true; + } - if ( doDecode ) { + if (doDecode) + { + nBytes = snd_midi_event_decode(apiData->coder, buffer, apiData->bufferSize, ev); + if (nBytes > 0) + { + // The ALSA sequencer has a maximum buffer size for MIDI sysex + // events of 256 bytes. If a device sends sysex messages larger + // than this, they are segmented into 256 byte chunks. So, + // we'll watch for this and concatenate sysex chunks into a + // single sysex message if necessary. + if (!continueSysex) + message.bytes.assign(buffer, &buffer[nBytes]); + else + message.bytes.insert(message.bytes.end(), buffer, &buffer[nBytes]); - nBytes = snd_midi_event_decode( apiData->coder, buffer, apiData->bufferSize, ev ); - if ( nBytes > 0 ) { - // The ALSA sequencer has a maximum buffer size for MIDI sysex - // events of 256 bytes. If a device sends sysex messages larger - // than this, they are segmented into 256 byte chunks. So, - // we'll watch for this and concatenate sysex chunks into a - // single sysex message if necessary. - if ( !continueSysex ) - message.bytes.assign( buffer, &buffer[nBytes] ); - else - message.bytes.insert( message.bytes.end(), buffer, &buffer[nBytes] ); + continueSysex = ((ev->type == SND_SEQ_EVENT_SYSEX) && (message.bytes.back() != 0xF7)); + if (!continueSysex) + { + // Calculate the time stamp: + message.timeStamp = 0.0; - continueSysex = ( ( ev->type == SND_SEQ_EVENT_SYSEX ) && ( message.bytes.back() != 0xF7 ) ); - if ( !continueSysex ) { + // Method 1: Use the system time. + //(void)gettimeofday(&tv, (struct timezone *)NULL); + //time = (tv.tv_sec * 1000000) + tv.tv_usec; - // Calculate the time stamp: - message.timeStamp = 0.0; - - // Method 1: Use the system time. - //(void)gettimeofday(&tv, (struct timezone *)NULL); - //time = (tv.tv_sec * 1000000) + tv.tv_usec; - - // Method 2: Use the ALSA sequencer event time data. - // (thanks to Pedro Lopez-Cabanillas!). - time = ( ev->time.time.tv_sec * 1000000 ) + ( ev->time.time.tv_nsec/1000 ); - lastTime = time; - time -= apiData->lastTime; - apiData->lastTime = lastTime; - if ( data->firstMessage == true ) - data->firstMessage = false; - else - message.timeStamp = time * 0.000001; - } - else { + // Method 2: Use the ALSA sequencer event time data. + // (thanks to Pedro Lopez-Cabanillas!). + time = (ev->time.time.tv_sec * 1000000) + (ev->time.time.tv_nsec / 1000); + lastTime = time; + time -= apiData->lastTime; + apiData->lastTime = lastTime; + if (data->firstMessage == true) + data->firstMessage = false; + else + message.timeStamp = time * 0.000001; + } + else + { #if defined(__RTMIDI_DEBUG__) - std::cerr << "\nMidiInAlsa::alsaMidiHandler: event parsing error or not a MIDI event!\n\n"; + std::cerr << "\nMidiInAlsa::alsaMidiHandler: event parsing error or not a MIDI event!\n\n"; #endif - } - } - } + } + } + } - snd_seq_free_event( ev ); - if ( message.bytes.size() == 0 || continueSysex ) continue; + snd_seq_free_event(ev); + if (message.bytes.size() == 0 || continueSysex) continue; - if ( data->usingCallback ) { - RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) data->userCallback; - callback( message.timeStamp, &message.bytes, data->userData ); - } - else { - // As long as we haven't reached our queue size limit, push the message. - if ( data->queue.size < data->queue.ringSize ) { - data->queue.ring[data->queue.back++] = message; - if ( data->queue.back == data->queue.ringSize ) - data->queue.back = 0; - data->queue.size++; - } - else - std::cerr << "\nMidiInAlsa: message queue limit reached!!\n\n"; - } - } + if (data->usingCallback) + { + RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback)data->userCallback; + callback(message.timeStamp, &message.bytes, data->userData); + } + else + { + // As long as we haven't reached our queue size limit, push the message. + if (data->queue.size < data->queue.ringSize) + { + data->queue.ring[data->queue.back++] = message; + if (data->queue.back == data->queue.ringSize) + data->queue.back = 0; + data->queue.size++; + } + else + std::cerr << "\nMidiInAlsa: message queue limit reached!!\n\n"; + } + } - if ( buffer ) free( buffer ); - snd_midi_event_free( apiData->coder ); - apiData->coder = 0; - apiData->thread = apiData->dummy_thread_id; - return 0; + if (buffer) free(buffer); + snd_midi_event_free(apiData->coder); + apiData->coder = 0; + apiData->thread = apiData->dummy_thread_id; + return 0; } -MidiInAlsa :: MidiInAlsa( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) +MidiInAlsa ::MidiInAlsa(const std::string clientName, unsigned int queueSizeLimit) : MidiInApi(queueSizeLimit) { - initialize( clientName ); + initialize(clientName); } -MidiInAlsa :: ~MidiInAlsa() +MidiInAlsa ::~MidiInAlsa() { - // Close a connection if it exists. - closePort(); + // Close a connection if it exists. + closePort(); - // Shutdown the input thread. - AlsaMidiData *data = static_cast (apiData_); - if ( inputData_.doInput ) { - inputData_.doInput = false; - int res = write( data->trigger_fds[1], &inputData_.doInput, sizeof(inputData_.doInput) ); - (void) res; - if ( !pthread_equal(data->thread, data->dummy_thread_id) ) - pthread_join( data->thread, NULL ); - } + // Shutdown the input thread. + AlsaMidiData *data = static_cast(apiData_); + if (inputData_.doInput) + { + inputData_.doInput = false; + int res = write(data->trigger_fds[1], &inputData_.doInput, sizeof(inputData_.doInput)); + (void)res; + if (!pthread_equal(data->thread, data->dummy_thread_id)) + pthread_join(data->thread, NULL); + } - // Cleanup. - close ( data->trigger_fds[0] ); - close ( data->trigger_fds[1] ); - if ( data->vport >= 0 ) snd_seq_delete_port( data->seq, data->vport ); + // Cleanup. + close(data->trigger_fds[0]); + close(data->trigger_fds[1]); + if (data->vport >= 0) snd_seq_delete_port(data->seq, data->vport); #ifndef AVOID_TIMESTAMPING - snd_seq_free_queue( data->seq, data->queue_id ); + snd_seq_free_queue(data->seq, data->queue_id); #endif - freeSequencer(); - delete data; + freeSequencer(); + delete data; } -void MidiInAlsa :: initialize( const std::string& clientName ) +void MidiInAlsa ::initialize(const std::string &clientName) { - snd_seq_t* seq = createSequencer( clientName ); - if ( seq == NULL ) { - s_seq = NULL; - errorString_ = "MidiInAlsa::initialize: error creating ALSA sequencer client object."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + snd_seq_t *seq = createSequencer(clientName); + if (seq == NULL) + { + s_seq = NULL; + errorString_ = "MidiInAlsa::initialize: error creating ALSA sequencer client object."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - // Save our api-specific connection information. - AlsaMidiData *data = (AlsaMidiData *) new AlsaMidiData; - data->seq = seq; - data->portNum = -1; - data->vport = -1; - data->subscription = 0; - data->dummy_thread_id = pthread_self(); - data->thread = data->dummy_thread_id; - data->trigger_fds[0] = -1; - data->trigger_fds[1] = -1; - apiData_ = (void *) data; - inputData_.apiData = (void *) data; + // Save our api-specific connection information. + AlsaMidiData *data = (AlsaMidiData *)new AlsaMidiData; + data->seq = seq; + data->portNum = -1; + data->vport = -1; + data->subscription = 0; + data->dummy_thread_id = pthread_self(); + data->thread = data->dummy_thread_id; + data->trigger_fds[0] = -1; + data->trigger_fds[1] = -1; + apiData_ = (void *)data; + inputData_.apiData = (void *)data; - if ( pipe(data->trigger_fds) == -1 ) { - errorString_ = "MidiInAlsa::initialize: error creating pipe objects."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + if (pipe(data->trigger_fds) == -1) + { + errorString_ = "MidiInAlsa::initialize: error creating pipe objects."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - // Create the input queue + // Create the input queue #ifndef AVOID_TIMESTAMPING - data->queue_id = snd_seq_alloc_named_queue(s_seq, "RtMidi Queue"); - // Set arbitrary tempo (mm=100) and resolution (240) - snd_seq_queue_tempo_t *qtempo; - snd_seq_queue_tempo_alloca(&qtempo); - snd_seq_queue_tempo_set_tempo(qtempo, 600000); - snd_seq_queue_tempo_set_ppq(qtempo, 240); - snd_seq_set_queue_tempo(data->seq, data->queue_id, qtempo); - snd_seq_drain_output(data->seq); + data->queue_id = snd_seq_alloc_named_queue(s_seq, "RtMidi Queue"); + // Set arbitrary tempo (mm=100) and resolution (240) + snd_seq_queue_tempo_t *qtempo; + snd_seq_queue_tempo_alloca(&qtempo); + snd_seq_queue_tempo_set_tempo(qtempo, 600000); + snd_seq_queue_tempo_set_ppq(qtempo, 240); + snd_seq_set_queue_tempo(data->seq, data->queue_id, qtempo); + snd_seq_drain_output(data->seq); #endif } // This function is used to count or get the pinfo structure for a given port number. -unsigned int portInfo( snd_seq_t *seq, snd_seq_port_info_t *pinfo, unsigned int type, int portNumber ) +unsigned int portInfo(snd_seq_t *seq, snd_seq_port_info_t *pinfo, unsigned int type, int portNumber) { - snd_seq_client_info_t *cinfo; - int client; - int count = 0; - snd_seq_client_info_alloca( &cinfo ); + snd_seq_client_info_t *cinfo; + int client; + int count = 0; + snd_seq_client_info_alloca(&cinfo); - snd_seq_client_info_set_client( cinfo, -1 ); - while ( snd_seq_query_next_client( seq, cinfo ) >= 0 ) { - client = snd_seq_client_info_get_client( cinfo ); - if ( client == 0 ) continue; - // Reset query info - snd_seq_port_info_set_client( pinfo, client ); - snd_seq_port_info_set_port( pinfo, -1 ); - while ( snd_seq_query_next_port( seq, pinfo ) >= 0 ) { - unsigned int atyp = snd_seq_port_info_get_type( pinfo ); - if ( ( atyp & SND_SEQ_PORT_TYPE_MIDI_GENERIC ) == 0 ) continue; - unsigned int caps = snd_seq_port_info_get_capability( pinfo ); - if ( ( caps & type ) != type ) continue; - if ( count == portNumber ) return 1; - ++count; - } - } + snd_seq_client_info_set_client(cinfo, -1); + while (snd_seq_query_next_client(seq, cinfo) >= 0) + { + client = snd_seq_client_info_get_client(cinfo); + if (client == 0) continue; + // Reset query info + snd_seq_port_info_set_client(pinfo, client); + snd_seq_port_info_set_port(pinfo, -1); + while (snd_seq_query_next_port(seq, pinfo) >= 0) + { + unsigned int atyp = snd_seq_port_info_get_type(pinfo); + if ((atyp & SND_SEQ_PORT_TYPE_MIDI_GENERIC) == 0) continue; + unsigned int caps = snd_seq_port_info_get_capability(pinfo); + if ((caps & type) != type) continue; + if (count == portNumber) return 1; + ++count; + } + } - // If a negative portNumber was used, return the port count. - if ( portNumber < 0 ) return count; - return 0; + // If a negative portNumber was used, return the port count. + if (portNumber < 0) return count; + return 0; } -unsigned int MidiInAlsa :: getPortCount() +unsigned int MidiInAlsa ::getPortCount() { - snd_seq_port_info_t *pinfo; - snd_seq_port_info_alloca( &pinfo ); + snd_seq_port_info_t *pinfo; + snd_seq_port_info_alloca(&pinfo); - AlsaMidiData *data = static_cast (apiData_); - return portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, -1 ); + AlsaMidiData *data = static_cast(apiData_); + return portInfo(data->seq, pinfo, SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, -1); } -std::string MidiInAlsa :: getPortName( unsigned int portNumber ) +std::string MidiInAlsa ::getPortName(unsigned int portNumber) { - snd_seq_client_info_t *cinfo; - snd_seq_port_info_t *pinfo; - snd_seq_client_info_alloca( &cinfo ); - snd_seq_port_info_alloca( &pinfo ); + snd_seq_client_info_t *cinfo; + snd_seq_port_info_t *pinfo; + snd_seq_client_info_alloca(&cinfo); + snd_seq_port_info_alloca(&pinfo); - std::string stringName; - AlsaMidiData *data = static_cast (apiData_); - if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, (int) portNumber ) ) { - int cnum = snd_seq_port_info_get_client( pinfo ); - snd_seq_get_any_client_info( data->seq, cnum, cinfo ); - std::ostringstream os; - os << snd_seq_client_info_get_name( cinfo ); - os << " "; // GO: These lines added to make sure devices are listed - os << snd_seq_port_info_get_client( pinfo ); // GO: with full portnames added to ensure individual device names - os << ":"; - os << snd_seq_port_info_get_port( pinfo ); - stringName = os.str(); - return stringName; - } + std::string stringName; + AlsaMidiData *data = static_cast(apiData_); + if (portInfo(data->seq, pinfo, SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, (int)portNumber)) + { + int cnum = snd_seq_port_info_get_client(pinfo); + snd_seq_get_any_client_info(data->seq, cnum, cinfo); + std::ostringstream os; + os << snd_seq_client_info_get_name(cinfo); + os << " "; // GO: These lines added to make sure devices are listed + os << snd_seq_port_info_get_client(pinfo); // GO: with full portnames added to ensure individual device names + os << ":"; + os << snd_seq_port_info_get_port(pinfo); + stringName = os.str(); + return stringName; + } - // If we get here, we didn't find a match. - errorString_ = "MidiInAlsa::getPortName: error looking for port name!"; - RtMidi::error( RtError::WARNING, errorString_ ); - return stringName; - //RtMidi::error( RtError::INVALID_PARAMETER, errorString_ ); + // If we get here, we didn't find a match. + errorString_ = "MidiInAlsa::getPortName: error looking for port name!"; + RtMidi::error(RtError::WARNING, errorString_); + return stringName; + //RtMidi::error( RtError::INVALID_PARAMETER, errorString_ ); } -void MidiInAlsa :: openPort( unsigned int portNumber, const std::string portName ) +void MidiInAlsa ::openPort(unsigned int portNumber, const std::string portName) { - if ( connected_ ) { - errorString_ = "MidiInAlsa::openPort: a valid connection already exists!"; - RtMidi::error( RtError::WARNING, errorString_ ); - return; - } + if (connected_) + { + errorString_ = "MidiInAlsa::openPort: a valid connection already exists!"; + RtMidi::error(RtError::WARNING, errorString_); + return; + } - unsigned int nSrc = this->getPortCount(); - if (nSrc < 1) { - errorString_ = "MidiInAlsa::openPort: no MIDI input sources found!"; - RtMidi::error( RtError::NO_DEVICES_FOUND, errorString_ ); - } + unsigned int nSrc = this->getPortCount(); + if (nSrc < 1) + { + errorString_ = "MidiInAlsa::openPort: no MIDI input sources found!"; + RtMidi::error(RtError::NO_DEVICES_FOUND, errorString_); + } - snd_seq_port_info_t *pinfo; - snd_seq_port_info_alloca( &pinfo ); - std::ostringstream ost; - AlsaMidiData *data = static_cast (apiData_); - if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, (int) portNumber ) == 0 ) { - ost << "MidiInAlsa::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - RtMidi::error( RtError::INVALID_PARAMETER, errorString_ ); - } + snd_seq_port_info_t *pinfo; + snd_seq_port_info_alloca(&pinfo); + std::ostringstream ost; + AlsaMidiData *data = static_cast(apiData_); + if (portInfo(data->seq, pinfo, SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, (int)portNumber) == 0) + { + ost << "MidiInAlsa::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + RtMidi::error(RtError::INVALID_PARAMETER, errorString_); + } - - snd_seq_addr_t sender, receiver; - sender.client = snd_seq_port_info_get_client( pinfo ); - sender.port = snd_seq_port_info_get_port( pinfo ); - receiver.client = snd_seq_client_id( data->seq ); - if ( data->vport < 0 ) { - snd_seq_port_info_set_client( pinfo, 0 ); - snd_seq_port_info_set_port( pinfo, 0 ); - snd_seq_port_info_set_capability( pinfo, - SND_SEQ_PORT_CAP_WRITE | - SND_SEQ_PORT_CAP_SUBS_WRITE ); - snd_seq_port_info_set_type( pinfo, - SND_SEQ_PORT_TYPE_MIDI_GENERIC | - SND_SEQ_PORT_TYPE_APPLICATION ); - snd_seq_port_info_set_midi_channels(pinfo, 16); + snd_seq_addr_t sender, receiver; + sender.client = snd_seq_port_info_get_client(pinfo); + sender.port = snd_seq_port_info_get_port(pinfo); + receiver.client = snd_seq_client_id(data->seq); + if (data->vport < 0) + { + snd_seq_port_info_set_client(pinfo, 0); + snd_seq_port_info_set_port(pinfo, 0); + snd_seq_port_info_set_capability(pinfo, + SND_SEQ_PORT_CAP_WRITE | + SND_SEQ_PORT_CAP_SUBS_WRITE); + snd_seq_port_info_set_type(pinfo, + SND_SEQ_PORT_TYPE_MIDI_GENERIC | + SND_SEQ_PORT_TYPE_APPLICATION); + snd_seq_port_info_set_midi_channels(pinfo, 16); #ifndef AVOID_TIMESTAMPING - snd_seq_port_info_set_timestamping(pinfo, 1); - snd_seq_port_info_set_timestamp_real(pinfo, 1); - snd_seq_port_info_set_timestamp_queue(pinfo, data->queue_id); + snd_seq_port_info_set_timestamping(pinfo, 1); + snd_seq_port_info_set_timestamp_real(pinfo, 1); + snd_seq_port_info_set_timestamp_queue(pinfo, data->queue_id); #endif - snd_seq_port_info_set_name(pinfo, portName.c_str() ); - data->vport = snd_seq_create_port(data->seq, pinfo); - - if ( data->vport < 0 ) { - errorString_ = "MidiInAlsa::openPort: ALSA error creating input port."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } - } + snd_seq_port_info_set_name(pinfo, portName.c_str()); + data->vport = snd_seq_create_port(data->seq, pinfo); - receiver.port = data->vport; + if (data->vport < 0) + { + errorString_ = "MidiInAlsa::openPort: ALSA error creating input port."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } + } - if ( !data->subscription ) { - // Make subscription - if (snd_seq_port_subscribe_malloc( &data->subscription ) < 0) { - errorString_ = "MidiInAlsa::openPort: ALSA error allocation port subscription."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } - snd_seq_port_subscribe_set_sender(data->subscription, &sender); - snd_seq_port_subscribe_set_dest(data->subscription, &receiver); - if ( snd_seq_subscribe_port(data->seq, data->subscription) ) { - snd_seq_port_subscribe_free( data->subscription ); - data->subscription = 0; - errorString_ = "MidiInAlsa::openPort: ALSA error making port connection."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } - } + receiver.port = data->vport; - if ( inputData_.doInput == false ) { - // Start the input queue + if (!data->subscription) + { + // Make subscription + if (snd_seq_port_subscribe_malloc(&data->subscription) < 0) + { + errorString_ = "MidiInAlsa::openPort: ALSA error allocation port subscription."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } + snd_seq_port_subscribe_set_sender(data->subscription, &sender); + snd_seq_port_subscribe_set_dest(data->subscription, &receiver); + if (snd_seq_subscribe_port(data->seq, data->subscription)) + { + snd_seq_port_subscribe_free(data->subscription); + data->subscription = 0; + errorString_ = "MidiInAlsa::openPort: ALSA error making port connection."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } + } + + if (inputData_.doInput == false) + { + // Start the input queue #ifndef AVOID_TIMESTAMPING - snd_seq_start_queue( data->seq, data->queue_id, NULL ); - snd_seq_drain_output( data->seq ); + snd_seq_start_queue(data->seq, data->queue_id, NULL); + snd_seq_drain_output(data->seq); #endif - // Start our MIDI input thread. - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - pthread_attr_setschedpolicy(&attr, SCHED_OTHER); + // Start our MIDI input thread. + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + pthread_attr_setschedpolicy(&attr, SCHED_OTHER); - inputData_.doInput = true; - int err = pthread_create(&data->thread, &attr, alsaMidiHandler, &inputData_); - pthread_attr_destroy(&attr); - if ( err ) { - snd_seq_unsubscribe_port( data->seq, data->subscription ); - snd_seq_port_subscribe_free( data->subscription ); - data->subscription = 0; - inputData_.doInput = false; - errorString_ = "MidiInAlsa::openPort: error starting MIDI input thread!"; - RtMidi::error( RtError::THREAD_ERROR, errorString_ ); - } - } + inputData_.doInput = true; + int err = pthread_create(&data->thread, &attr, alsaMidiHandler, &inputData_); + pthread_attr_destroy(&attr); + if (err) + { + snd_seq_unsubscribe_port(data->seq, data->subscription); + snd_seq_port_subscribe_free(data->subscription); + data->subscription = 0; + inputData_.doInput = false; + errorString_ = "MidiInAlsa::openPort: error starting MIDI input thread!"; + RtMidi::error(RtError::THREAD_ERROR, errorString_); + } + } - connected_ = true; + connected_ = true; } -void MidiInAlsa :: openVirtualPort( std::string portName ) +void MidiInAlsa ::openVirtualPort(std::string portName) { - AlsaMidiData *data = static_cast (apiData_); - if ( data->vport < 0 ) { - snd_seq_port_info_t *pinfo; - snd_seq_port_info_alloca( &pinfo ); - snd_seq_port_info_set_capability( pinfo, - SND_SEQ_PORT_CAP_WRITE | - SND_SEQ_PORT_CAP_SUBS_WRITE ); - snd_seq_port_info_set_type( pinfo, - SND_SEQ_PORT_TYPE_MIDI_GENERIC | - SND_SEQ_PORT_TYPE_APPLICATION ); - snd_seq_port_info_set_midi_channels(pinfo, 16); + AlsaMidiData *data = static_cast(apiData_); + if (data->vport < 0) + { + snd_seq_port_info_t *pinfo; + snd_seq_port_info_alloca(&pinfo); + snd_seq_port_info_set_capability(pinfo, + SND_SEQ_PORT_CAP_WRITE | + SND_SEQ_PORT_CAP_SUBS_WRITE); + snd_seq_port_info_set_type(pinfo, + SND_SEQ_PORT_TYPE_MIDI_GENERIC | + SND_SEQ_PORT_TYPE_APPLICATION); + snd_seq_port_info_set_midi_channels(pinfo, 16); #ifndef AVOID_TIMESTAMPING - snd_seq_port_info_set_timestamping(pinfo, 1); - snd_seq_port_info_set_timestamp_real(pinfo, 1); - snd_seq_port_info_set_timestamp_queue(pinfo, data->queue_id); + snd_seq_port_info_set_timestamping(pinfo, 1); + snd_seq_port_info_set_timestamp_real(pinfo, 1); + snd_seq_port_info_set_timestamp_queue(pinfo, data->queue_id); #endif - snd_seq_port_info_set_name(pinfo, portName.c_str()); - data->vport = snd_seq_create_port(data->seq, pinfo); + snd_seq_port_info_set_name(pinfo, portName.c_str()); + data->vport = snd_seq_create_port(data->seq, pinfo); - if ( data->vport < 0 ) { - errorString_ = "MidiInAlsa::openVirtualPort: ALSA error creating virtual port."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } - } + if (data->vport < 0) + { + errorString_ = "MidiInAlsa::openVirtualPort: ALSA error creating virtual port."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } + } - if ( inputData_.doInput == false ) { - // Wait for old thread to stop, if still running - if ( !pthread_equal(data->thread, data->dummy_thread_id) ) - pthread_join( data->thread, NULL ); + if (inputData_.doInput == false) + { + // Wait for old thread to stop, if still running + if (!pthread_equal(data->thread, data->dummy_thread_id)) + pthread_join(data->thread, NULL); - // Start the input queue + // Start the input queue #ifndef AVOID_TIMESTAMPING - snd_seq_start_queue( data->seq, data->queue_id, NULL ); - snd_seq_drain_output( data->seq ); + snd_seq_start_queue(data->seq, data->queue_id, NULL); + snd_seq_drain_output(data->seq); #endif - // Start our MIDI input thread. - pthread_attr_t attr; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - pthread_attr_setschedpolicy(&attr, SCHED_OTHER); + // Start our MIDI input thread. + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); + pthread_attr_setschedpolicy(&attr, SCHED_OTHER); - inputData_.doInput = true; - int err = pthread_create(&data->thread, &attr, alsaMidiHandler, &inputData_); - pthread_attr_destroy(&attr); - if ( err ) { - if ( data->subscription ) { - snd_seq_unsubscribe_port( data->seq, data->subscription ); - snd_seq_port_subscribe_free( data->subscription ); - data->subscription = 0; - } - inputData_.doInput = false; - errorString_ = "MidiInAlsa::openPort: error starting MIDI input thread!"; - RtMidi::error( RtError::THREAD_ERROR, errorString_ ); - } - } + inputData_.doInput = true; + int err = pthread_create(&data->thread, &attr, alsaMidiHandler, &inputData_); + pthread_attr_destroy(&attr); + if (err) + { + if (data->subscription) + { + snd_seq_unsubscribe_port(data->seq, data->subscription); + snd_seq_port_subscribe_free(data->subscription); + data->subscription = 0; + } + inputData_.doInput = false; + errorString_ = "MidiInAlsa::openPort: error starting MIDI input thread!"; + RtMidi::error(RtError::THREAD_ERROR, errorString_); + } + } } -void MidiInAlsa :: closePort( void ) +void MidiInAlsa ::closePort(void) { - AlsaMidiData *data = static_cast (apiData_); + AlsaMidiData *data = static_cast(apiData_); - if ( connected_ ) { - if ( data->subscription ) { - snd_seq_unsubscribe_port( data->seq, data->subscription ); - snd_seq_port_subscribe_free( data->subscription ); - data->subscription = 0; - } - // Stop the input queue + if (connected_) + { + if (data->subscription) + { + snd_seq_unsubscribe_port(data->seq, data->subscription); + snd_seq_port_subscribe_free(data->subscription); + data->subscription = 0; + } + // Stop the input queue #ifndef AVOID_TIMESTAMPING - snd_seq_stop_queue( data->seq, data->queue_id, NULL ); - snd_seq_drain_output( data->seq ); + snd_seq_stop_queue(data->seq, data->queue_id, NULL); + snd_seq_drain_output(data->seq); #endif - connected_ = false; - } + connected_ = false; + } - // Stop thread to avoid triggering the callback, while the port is intended to be closed - if ( inputData_.doInput ) { - inputData_.doInput = false; - int res = write( data->trigger_fds[1], &inputData_.doInput, sizeof(inputData_.doInput) ); - (void) res; - if ( !pthread_equal(data->thread, data->dummy_thread_id) ) - pthread_join( data->thread, NULL ); - } + // Stop thread to avoid triggering the callback, while the port is intended to be closed + if (inputData_.doInput) + { + inputData_.doInput = false; + int res = write(data->trigger_fds[1], &inputData_.doInput, sizeof(inputData_.doInput)); + (void)res; + if (!pthread_equal(data->thread, data->dummy_thread_id)) + pthread_join(data->thread, NULL); + } } //*********************************************************************// @@ -1633,223 +1766,241 @@ void MidiInAlsa :: closePort( void ) // Class Definitions: MidiOutAlsa //*********************************************************************// -MidiOutAlsa :: MidiOutAlsa( const std::string clientName ) : MidiOutApi() +MidiOutAlsa ::MidiOutAlsa(const std::string clientName) : MidiOutApi() { - initialize( clientName ); + initialize(clientName); } -MidiOutAlsa :: ~MidiOutAlsa() +MidiOutAlsa ::~MidiOutAlsa() { - // Close a connection if it exists. - closePort(); + // Close a connection if it exists. + closePort(); - // Cleanup. - AlsaMidiData *data = static_cast (apiData_); - if ( data->vport >= 0 ) snd_seq_delete_port( data->seq, data->vport ); - if ( data->coder ) snd_midi_event_free( data->coder ); - if ( data->buffer ) free( data->buffer ); - freeSequencer(); - delete data; + // Cleanup. + AlsaMidiData *data = static_cast(apiData_); + if (data->vport >= 0) snd_seq_delete_port(data->seq, data->vport); + if (data->coder) snd_midi_event_free(data->coder); + if (data->buffer) free(data->buffer); + freeSequencer(); + delete data; } -void MidiOutAlsa :: initialize( const std::string& clientName ) +void MidiOutAlsa ::initialize(const std::string &clientName) { - snd_seq_t* seq = createSequencer( clientName ); - if ( seq == NULL ) { - s_seq = NULL; - errorString_ = "MidiOutAlsa::initialize: error creating ALSA sequencer client object."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); + snd_seq_t *seq = createSequencer(clientName); + if (seq == NULL) + { + s_seq = NULL; + errorString_ = "MidiOutAlsa::initialize: error creating ALSA sequencer client object."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); } - // Save our api-specific connection information. - AlsaMidiData *data = (AlsaMidiData *) new AlsaMidiData; - data->seq = seq; - data->portNum = -1; - data->vport = -1; - data->bufferSize = 32; - data->coder = 0; - data->buffer = 0; - int result = snd_midi_event_new( data->bufferSize, &data->coder ); - if ( result < 0 ) { - delete data; - errorString_ = "MidiOutAlsa::initialize: error initializing MIDI event parser!\n\n"; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } - data->buffer = (unsigned char *) malloc( data->bufferSize ); - if ( data->buffer == NULL ) { - delete data; - errorString_ = "MidiOutAlsa::initialize: error allocating buffer memory!\n\n"; - RtMidi::error( RtError::MEMORY_ERROR, errorString_ ); - } - snd_midi_event_init( data->coder ); - apiData_ = (void *) data; + // Save our api-specific connection information. + AlsaMidiData *data = (AlsaMidiData *)new AlsaMidiData; + data->seq = seq; + data->portNum = -1; + data->vport = -1; + data->bufferSize = 32; + data->coder = 0; + data->buffer = 0; + int result = snd_midi_event_new(data->bufferSize, &data->coder); + if (result < 0) + { + delete data; + errorString_ = "MidiOutAlsa::initialize: error initializing MIDI event parser!\n\n"; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } + data->buffer = (unsigned char *)malloc(data->bufferSize); + if (data->buffer == NULL) + { + delete data; + errorString_ = "MidiOutAlsa::initialize: error allocating buffer memory!\n\n"; + RtMidi::error(RtError::MEMORY_ERROR, errorString_); + } + snd_midi_event_init(data->coder); + apiData_ = (void *)data; } -unsigned int MidiOutAlsa :: getPortCount() +unsigned int MidiOutAlsa ::getPortCount() { snd_seq_port_info_t *pinfo; - snd_seq_port_info_alloca( &pinfo ); + snd_seq_port_info_alloca(&pinfo); - AlsaMidiData *data = static_cast (apiData_); - return portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, -1 ); + AlsaMidiData *data = static_cast(apiData_); + return portInfo(data->seq, pinfo, SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, -1); } -std::string MidiOutAlsa :: getPortName( unsigned int portNumber ) +std::string MidiOutAlsa ::getPortName(unsigned int portNumber) { - snd_seq_client_info_t *cinfo; - snd_seq_port_info_t *pinfo; - snd_seq_client_info_alloca( &cinfo ); - snd_seq_port_info_alloca( &pinfo ); + snd_seq_client_info_t *cinfo; + snd_seq_port_info_t *pinfo; + snd_seq_client_info_alloca(&cinfo); + snd_seq_port_info_alloca(&pinfo); - std::string stringName; - AlsaMidiData *data = static_cast (apiData_); - if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, (int) portNumber ) ) { - int cnum = snd_seq_port_info_get_client(pinfo); - snd_seq_get_any_client_info( data->seq, cnum, cinfo ); - std::ostringstream os; - os << snd_seq_client_info_get_name(cinfo); - os << ":"; - os << snd_seq_port_info_get_port(pinfo); - stringName = os.str(); - return stringName; - } + std::string stringName; + AlsaMidiData *data = static_cast(apiData_); + if (portInfo(data->seq, pinfo, SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, (int)portNumber)) + { + int cnum = snd_seq_port_info_get_client(pinfo); + snd_seq_get_any_client_info(data->seq, cnum, cinfo); + std::ostringstream os; + os << snd_seq_client_info_get_name(cinfo); + os << ":"; + os << snd_seq_port_info_get_port(pinfo); + stringName = os.str(); + return stringName; + } - // If we get here, we didn't find a match. - errorString_ = "MidiOutAlsa::getPortName: error looking for port name!"; - //RtMidi::error( RtError::INVALID_PARAMETER, errorString_ ); - RtMidi::error( RtError::WARNING, errorString_ ); - return stringName; + // If we get here, we didn't find a match. + errorString_ = "MidiOutAlsa::getPortName: error looking for port name!"; + //RtMidi::error( RtError::INVALID_PARAMETER, errorString_ ); + RtMidi::error(RtError::WARNING, errorString_); + return stringName; } -void MidiOutAlsa :: openPort( unsigned int portNumber, const std::string portName ) +void MidiOutAlsa ::openPort(unsigned int portNumber, const std::string portName) { - if ( connected_ ) { - errorString_ = "MidiOutAlsa::openPort: a valid connection already exists!"; - RtMidi::error( RtError::WARNING, errorString_ ); - return; - } + if (connected_) + { + errorString_ = "MidiOutAlsa::openPort: a valid connection already exists!"; + RtMidi::error(RtError::WARNING, errorString_); + return; + } - unsigned int nSrc = this->getPortCount(); - if (nSrc < 1) { - errorString_ = "MidiOutAlsa::openPort: no MIDI output sources found!"; - RtMidi::error( RtError::NO_DEVICES_FOUND, errorString_ ); - } + unsigned int nSrc = this->getPortCount(); + if (nSrc < 1) + { + errorString_ = "MidiOutAlsa::openPort: no MIDI output sources found!"; + RtMidi::error(RtError::NO_DEVICES_FOUND, errorString_); + } snd_seq_port_info_t *pinfo; - snd_seq_port_info_alloca( &pinfo ); - std::ostringstream ost; - AlsaMidiData *data = static_cast (apiData_); - if ( portInfo( data->seq, pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE, (int) portNumber ) == 0 ) { - ost << "MidiOutAlsa::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - RtMidi::error( RtError::INVALID_PARAMETER, errorString_ ); - } + snd_seq_port_info_alloca(&pinfo); + std::ostringstream ost; + AlsaMidiData *data = static_cast(apiData_); + if (portInfo(data->seq, pinfo, SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, (int)portNumber) == 0) + { + ost << "MidiOutAlsa::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + RtMidi::error(RtError::INVALID_PARAMETER, errorString_); + } - snd_seq_addr_t sender, receiver; - receiver.client = snd_seq_port_info_get_client( pinfo ); - receiver.port = snd_seq_port_info_get_port( pinfo ); - sender.client = snd_seq_client_id( data->seq ); + snd_seq_addr_t sender, receiver; + receiver.client = snd_seq_port_info_get_client(pinfo); + receiver.port = snd_seq_port_info_get_port(pinfo); + sender.client = snd_seq_client_id(data->seq); - if ( data->vport < 0 ) { - data->vport = snd_seq_create_simple_port( data->seq, portName.c_str(), - SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, - SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION ); - if ( data->vport < 0 ) { - errorString_ = "MidiOutAlsa::openPort: ALSA error creating output port."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } - } + if (data->vport < 0) + { + data->vport = snd_seq_create_simple_port(data->seq, portName.c_str(), + SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, + SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); + if (data->vport < 0) + { + errorString_ = "MidiOutAlsa::openPort: ALSA error creating output port."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } + } - sender.port = data->vport; + sender.port = data->vport; - // Make subscription - if (snd_seq_port_subscribe_malloc( &data->subscription ) < 0) { - snd_seq_port_subscribe_free( data->subscription ); - errorString_ = "MidiOutAlsa::openPort: error allocation port subscribtion."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } - snd_seq_port_subscribe_set_sender(data->subscription, &sender); - snd_seq_port_subscribe_set_dest(data->subscription, &receiver); - snd_seq_port_subscribe_set_time_update(data->subscription, 1); - snd_seq_port_subscribe_set_time_real(data->subscription, 1); - if ( snd_seq_subscribe_port(data->seq, data->subscription) ) { - snd_seq_port_subscribe_free( data->subscription ); - errorString_ = "MidiOutAlsa::openPort: ALSA error making port connection."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + // Make subscription + if (snd_seq_port_subscribe_malloc(&data->subscription) < 0) + { + snd_seq_port_subscribe_free(data->subscription); + errorString_ = "MidiOutAlsa::openPort: error allocation port subscribtion."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } + snd_seq_port_subscribe_set_sender(data->subscription, &sender); + snd_seq_port_subscribe_set_dest(data->subscription, &receiver); + snd_seq_port_subscribe_set_time_update(data->subscription, 1); + snd_seq_port_subscribe_set_time_real(data->subscription, 1); + if (snd_seq_subscribe_port(data->seq, data->subscription)) + { + snd_seq_port_subscribe_free(data->subscription); + errorString_ = "MidiOutAlsa::openPort: ALSA error making port connection."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - connected_ = true; + connected_ = true; } -void MidiOutAlsa :: closePort( void ) +void MidiOutAlsa ::closePort(void) { - if ( connected_ ) { - AlsaMidiData *data = static_cast (apiData_); - snd_seq_unsubscribe_port( data->seq, data->subscription ); - snd_seq_port_subscribe_free( data->subscription ); - connected_ = false; - } + if (connected_) + { + AlsaMidiData *data = static_cast(apiData_); + snd_seq_unsubscribe_port(data->seq, data->subscription); + snd_seq_port_subscribe_free(data->subscription); + connected_ = false; + } } -void MidiOutAlsa :: openVirtualPort( std::string portName ) +void MidiOutAlsa ::openVirtualPort(std::string portName) { - AlsaMidiData *data = static_cast (apiData_); - if ( data->vport < 0 ) { - data->vport = snd_seq_create_simple_port( data->seq, portName.c_str(), - SND_SEQ_PORT_CAP_READ|SND_SEQ_PORT_CAP_SUBS_READ, - SND_SEQ_PORT_TYPE_MIDI_GENERIC|SND_SEQ_PORT_TYPE_APPLICATION ); + AlsaMidiData *data = static_cast(apiData_); + if (data->vport < 0) + { + data->vport = snd_seq_create_simple_port(data->seq, portName.c_str(), + SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, + SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); - if ( data->vport < 0 ) { - errorString_ = "MidiOutAlsa::openVirtualPort: ALSA error creating virtual port."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } - } + if (data->vport < 0) + { + errorString_ = "MidiOutAlsa::openVirtualPort: ALSA error creating virtual port."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } + } } -void MidiOutAlsa :: sendMessage( std::vector *message ) +void MidiOutAlsa ::sendMessage(std::vector *message) { - int result; - AlsaMidiData *data = static_cast (apiData_); - unsigned int nBytes = message->size(); - if ( nBytes > data->bufferSize ) { - data->bufferSize = nBytes; - result = snd_midi_event_resize_buffer ( data->coder, nBytes); - if ( result != 0 ) { - errorString_ = "MidiOutAlsa::sendMessage: ALSA error resizing MIDI event buffer."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } - free (data->buffer); - data->buffer = (unsigned char *) malloc( data->bufferSize ); - if ( data->buffer == NULL ) { - errorString_ = "MidiOutAlsa::initialize: error allocating buffer memory!\n\n"; - RtMidi::error( RtError::MEMORY_ERROR, errorString_ ); - } - } + int result; + AlsaMidiData *data = static_cast(apiData_); + unsigned int nBytes = message->size(); + if (nBytes > data->bufferSize) + { + data->bufferSize = nBytes; + result = snd_midi_event_resize_buffer(data->coder, nBytes); + if (result != 0) + { + errorString_ = "MidiOutAlsa::sendMessage: ALSA error resizing MIDI event buffer."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } + free(data->buffer); + data->buffer = (unsigned char *)malloc(data->bufferSize); + if (data->buffer == NULL) + { + errorString_ = "MidiOutAlsa::initialize: error allocating buffer memory!\n\n"; + RtMidi::error(RtError::MEMORY_ERROR, errorString_); + } + } - snd_seq_event_t ev; - snd_seq_ev_clear(&ev); - snd_seq_ev_set_source(&ev, data->vport); - snd_seq_ev_set_subs(&ev); - snd_seq_ev_set_direct(&ev); - for ( unsigned int i=0; ibuffer[i] = message->at(i); - result = snd_midi_event_encode( data->coder, data->buffer, (long)nBytes, &ev ); - if ( result < (int)nBytes ) { - errorString_ = "MidiOutAlsa::sendMessage: event parsing error!"; - RtMidi::error( RtError::WARNING, errorString_ ); - return; - } + snd_seq_event_t ev; + snd_seq_ev_clear(&ev); + snd_seq_ev_set_source(&ev, data->vport); + snd_seq_ev_set_subs(&ev); + snd_seq_ev_set_direct(&ev); + for (unsigned int i = 0; i < nBytes; ++i) data->buffer[i] = message->at(i); + result = snd_midi_event_encode(data->coder, data->buffer, (long)nBytes, &ev); + if (result < (int)nBytes) + { + errorString_ = "MidiOutAlsa::sendMessage: event parsing error!"; + RtMidi::error(RtError::WARNING, errorString_); + return; + } - // Send the event. - result = snd_seq_event_output(data->seq, &ev); - if ( result < 0 ) { - errorString_ = "MidiOutAlsa::sendMessage: error sending MIDI message to port."; - RtMidi::error( RtError::WARNING, errorString_ ); - } - snd_seq_drain_output(data->seq); + // Send the event. + result = snd_seq_event_output(data->seq, &ev); + if (result < 0) + { + errorString_ = "MidiOutAlsa::sendMessage: error sending MIDI message to port."; + RtMidi::error(RtError::WARNING, errorString_); + } + snd_seq_drain_output(data->seq); } -#endif // __LINUX_ALSA__ - +#endif // __LINUX_ALSA__ //*********************************************************************// // API: Windows Multimedia Library (MM) @@ -1870,17 +2021,18 @@ void MidiOutAlsa :: sendMessage( std::vector *message ) #include #include -#define RT_SYSEX_BUFFER_SIZE 1024 -#define RT_SYSEX_BUFFER_COUNT 4 +#define RT_SYSEX_BUFFER_SIZE 1024 +#define RT_SYSEX_BUFFER_COUNT 4 // A structure to hold variables related to the CoreMIDI API // implementation. -struct WinMidiData { - HMIDIIN inHandle; // Handle to Midi Input Device - HMIDIOUT outHandle; // Handle to Midi Output Device - DWORD lastTime; - MidiInApi::MidiMessage message; - LPMIDIHDR sysexBuffer[RT_SYSEX_BUFFER_COUNT]; +struct WinMidiData +{ + HMIDIIN inHandle; // Handle to Midi Input Device + HMIDIOUT outHandle; // Handle to Midi Output Device + DWORD lastTime; + MidiInApi::MidiMessage message; + LPMIDIHDR sysexBuffer[RT_SYSEX_BUFFER_COUNT]; }; //*********************************************************************// @@ -1888,269 +2040,302 @@ struct WinMidiData { // Class Definitions: MidiInWinMM //*********************************************************************// -static void CALLBACK midiInputCallback( HMIDIIN hmin, - UINT inputStatus, - DWORD_PTR instancePtr, - DWORD_PTR midiMessage, - DWORD timestamp ) +static void CALLBACK midiInputCallback(HMIDIIN hmin, + UINT inputStatus, + DWORD_PTR instancePtr, + DWORD_PTR midiMessage, + DWORD timestamp) { - if ( inputStatus != MIM_DATA && inputStatus != MIM_LONGDATA && inputStatus != MIM_LONGERROR ) return; + if (inputStatus != MIM_DATA && inputStatus != MIM_LONGDATA && inputStatus != MIM_LONGERROR) return; - //MidiInApi::RtMidiInData *data = static_cast (instancePtr); - MidiInApi::RtMidiInData *data = (MidiInApi::RtMidiInData *)instancePtr; - WinMidiData *apiData = static_cast (data->apiData); + //MidiInApi::RtMidiInData *data = static_cast (instancePtr); + MidiInApi::RtMidiInData *data = (MidiInApi::RtMidiInData *)instancePtr; + WinMidiData *apiData = static_cast(data->apiData); - // Calculate time stamp. - if ( data->firstMessage == true ) { - apiData->message.timeStamp = 0.0; - data->firstMessage = false; - } - else apiData->message.timeStamp = (double) ( timestamp - apiData->lastTime ) * 0.001; - apiData->lastTime = timestamp; + // Calculate time stamp. + if (data->firstMessage == true) + { + apiData->message.timeStamp = 0.0; + data->firstMessage = false; + } + else + apiData->message.timeStamp = (double)(timestamp - apiData->lastTime) * 0.001; + apiData->lastTime = timestamp; - if ( inputStatus == MIM_DATA ) { // Channel or system message + if (inputStatus == MIM_DATA) + { // Channel or system message - // Make sure the first byte is a status byte. - unsigned char status = (unsigned char) (midiMessage & 0x000000FF); - if ( !(status & 0x80) ) return; + // Make sure the first byte is a status byte. + unsigned char status = (unsigned char)(midiMessage & 0x000000FF); + if (!(status & 0x80)) return; - // Determine the number of bytes in the MIDI message. - unsigned short nBytes = 1; - if ( status < 0xC0 ) nBytes = 3; - else if ( status < 0xE0 ) nBytes = 2; - else if ( status < 0xF0 ) nBytes = 3; - else if ( status == 0xF1 ) { - if ( data->ignoreFlags & 0x02 ) return; - else nBytes = 2; - } - else if ( status == 0xF2 ) nBytes = 3; - else if ( status == 0xF3 ) nBytes = 2; - else if ( status == 0xF8 && (data->ignoreFlags & 0x02) ) { - // A MIDI timing tick message and we're ignoring it. - return; - } - else if ( status == 0xFE && (data->ignoreFlags & 0x04) ) { - // A MIDI active sensing message and we're ignoring it. - return; - } + // Determine the number of bytes in the MIDI message. + unsigned short nBytes = 1; + if (status < 0xC0) + nBytes = 3; + else if (status < 0xE0) + nBytes = 2; + else if (status < 0xF0) + nBytes = 3; + else if (status == 0xF1) + { + if (data->ignoreFlags & 0x02) + return; + else + nBytes = 2; + } + else if (status == 0xF2) + nBytes = 3; + else if (status == 0xF3) + nBytes = 2; + else if (status == 0xF8 && (data->ignoreFlags & 0x02)) + { + // A MIDI timing tick message and we're ignoring it. + return; + } + else if (status == 0xFE && (data->ignoreFlags & 0x04)) + { + // A MIDI active sensing message and we're ignoring it. + return; + } - // Copy bytes to our MIDI message. - unsigned char *ptr = (unsigned char *) &midiMessage; - for ( int i=0; imessage.bytes.push_back( *ptr++ ); - } - else { // Sysex message ( MIM_LONGDATA or MIM_LONGERROR ) - MIDIHDR *sysex = ( MIDIHDR *) midiMessage; - if ( !( data->ignoreFlags & 0x01 ) && inputStatus != MIM_LONGERROR ) { - // Sysex message and we're not ignoring it - for ( int i=0; i<(int)sysex->dwBytesRecorded; ++i ) - apiData->message.bytes.push_back( sysex->lpData[i] ); - } + // Copy bytes to our MIDI message. + unsigned char *ptr = (unsigned char *)&midiMessage; + for (int i = 0; i < nBytes; ++i) apiData->message.bytes.push_back(*ptr++); + } + else + { // Sysex message ( MIM_LONGDATA or MIM_LONGERROR ) + MIDIHDR *sysex = (MIDIHDR *)midiMessage; + if (!(data->ignoreFlags & 0x01) && inputStatus != MIM_LONGERROR) + { + // Sysex message and we're not ignoring it + for (int i = 0; i < (int)sysex->dwBytesRecorded; ++i) + apiData->message.bytes.push_back(sysex->lpData[i]); + } - // The WinMM API requires that the sysex buffer be requeued after - // input of each sysex message. Even if we are ignoring sysex - // messages, we still need to requeue the buffer in case the user - // decides to not ignore sysex messages in the future. However, - // it seems that WinMM calls this function with an empty sysex - // buffer when an application closes and in this case, we should - // avoid requeueing it, else the computer suddenly reboots after - // one or two minutes. - if ( apiData->sysexBuffer[sysex->dwUser]->dwBytesRecorded > 0 ) { - //if ( sysex->dwBytesRecorded > 0 ) { - MMRESULT result = midiInAddBuffer( apiData->inHandle, apiData->sysexBuffer[sysex->dwUser], sizeof(MIDIHDR) ); - if ( result != MMSYSERR_NOERROR ) - std::cerr << "\nRtMidiIn::midiInputCallback: error sending sysex to Midi device!!\n\n"; + // The WinMM API requires that the sysex buffer be requeued after + // input of each sysex message. Even if we are ignoring sysex + // messages, we still need to requeue the buffer in case the user + // decides to not ignore sysex messages in the future. However, + // it seems that WinMM calls this function with an empty sysex + // buffer when an application closes and in this case, we should + // avoid requeueing it, else the computer suddenly reboots after + // one or two minutes. + if (apiData->sysexBuffer[sysex->dwUser]->dwBytesRecorded > 0) + { + //if ( sysex->dwBytesRecorded > 0 ) { + MMRESULT result = midiInAddBuffer(apiData->inHandle, apiData->sysexBuffer[sysex->dwUser], sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) + std::cerr << "\nRtMidiIn::midiInputCallback: error sending sysex to Midi device!!\n\n"; - if ( data->ignoreFlags & 0x01 ) return; - } - else return; - } + if (data->ignoreFlags & 0x01) return; + } + else + return; + } - if ( data->usingCallback ) { - RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) data->userCallback; - callback( apiData->message.timeStamp, &apiData->message.bytes, data->userData ); - } - else { - // As long as we haven't reached our queue size limit, push the message. - if ( data->queue.size < data->queue.ringSize ) { - data->queue.ring[data->queue.back++] = apiData->message; - if ( data->queue.back == data->queue.ringSize ) - data->queue.back = 0; - data->queue.size++; - } - else - std::cerr << "\nRtMidiIn: message queue limit reached!!\n\n"; - } + if (data->usingCallback) + { + RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback)data->userCallback; + callback(apiData->message.timeStamp, &apiData->message.bytes, data->userData); + } + else + { + // As long as we haven't reached our queue size limit, push the message. + if (data->queue.size < data->queue.ringSize) + { + data->queue.ring[data->queue.back++] = apiData->message; + if (data->queue.back == data->queue.ringSize) + data->queue.back = 0; + data->queue.size++; + } + else + std::cerr << "\nRtMidiIn: message queue limit reached!!\n\n"; + } - // Clear the vector for the next input message. - apiData->message.bytes.clear(); + // Clear the vector for the next input message. + apiData->message.bytes.clear(); } -MidiInWinMM :: MidiInWinMM( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) +MidiInWinMM ::MidiInWinMM(const std::string clientName, unsigned int queueSizeLimit) : MidiInApi(queueSizeLimit) { - initialize( clientName ); + initialize(clientName); } -MidiInWinMM :: ~MidiInWinMM() +MidiInWinMM ::~MidiInWinMM() { - // Close a connection if it exists. - closePort(); + // Close a connection if it exists. + closePort(); - // Cleanup. - WinMidiData *data = static_cast (apiData_); - delete data; + // Cleanup. + WinMidiData *data = static_cast(apiData_); + delete data; } -void MidiInWinMM :: initialize( const std::string& /*clientName*/ ) +void MidiInWinMM ::initialize(const std::string & /*clientName*/) { - // We'll issue a warning here if no devices are available but not - // throw an error since the user can plugin something later. - unsigned int nDevices = midiInGetNumDevs(); - if ( nDevices == 0 ) { - errorString_ = "MidiInWinMM::initialize: no MIDI input devices currently available."; - RtMidi::error( RtError::WARNING, errorString_ ); - } + // We'll issue a warning here if no devices are available but not + // throw an error since the user can plugin something later. + unsigned int nDevices = midiInGetNumDevs(); + if (nDevices == 0) + { + errorString_ = "MidiInWinMM::initialize: no MIDI input devices currently available."; + RtMidi::error(RtError::WARNING, errorString_); + } - // Save our api-specific connection information. - WinMidiData *data = (WinMidiData *) new WinMidiData; - apiData_ = (void *) data; - inputData_.apiData = (void *) data; - data->message.bytes.clear(); // needs to be empty for first input message + // Save our api-specific connection information. + WinMidiData *data = (WinMidiData *)new WinMidiData; + apiData_ = (void *)data; + inputData_.apiData = (void *)data; + data->message.bytes.clear(); // needs to be empty for first input message } -void MidiInWinMM :: openPort( unsigned int portNumber, const std::string /*portName*/ ) +void MidiInWinMM ::openPort(unsigned int portNumber, const std::string /*portName*/) { - if ( connected_ ) { - errorString_ = "MidiInWinMM::openPort: a valid connection already exists!"; - RtMidi::error( RtError::WARNING, errorString_ ); - return; - } + if (connected_) + { + errorString_ = "MidiInWinMM::openPort: a valid connection already exists!"; + RtMidi::error(RtError::WARNING, errorString_); + return; + } - unsigned int nDevices = midiInGetNumDevs(); - if (nDevices == 0) { - errorString_ = "MidiInWinMM::openPort: no MIDI input sources found!"; - RtMidi::error( RtError::NO_DEVICES_FOUND, errorString_ ); - } + unsigned int nDevices = midiInGetNumDevs(); + if (nDevices == 0) + { + errorString_ = "MidiInWinMM::openPort: no MIDI input sources found!"; + RtMidi::error(RtError::NO_DEVICES_FOUND, errorString_); + } - std::ostringstream ost; - if ( portNumber >= nDevices ) { - ost << "MidiInWinMM::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - RtMidi::error( RtError::INVALID_PARAMETER, errorString_ ); - } + std::ostringstream ost; + if (portNumber >= nDevices) + { + ost << "MidiInWinMM::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + RtMidi::error(RtError::INVALID_PARAMETER, errorString_); + } - WinMidiData *data = static_cast (apiData_); - MMRESULT result = midiInOpen( &data->inHandle, - portNumber, - (DWORD_PTR)&midiInputCallback, - (DWORD_PTR)&inputData_, - CALLBACK_FUNCTION ); - if ( result != MMSYSERR_NOERROR ) { - errorString_ = "MidiInWinMM::openPort: error creating Windows MM MIDI input port."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + WinMidiData *data = static_cast(apiData_); + MMRESULT result = midiInOpen(&data->inHandle, + portNumber, + (DWORD_PTR)&midiInputCallback, + (DWORD_PTR)&inputData_, + CALLBACK_FUNCTION); + if (result != MMSYSERR_NOERROR) + { + errorString_ = "MidiInWinMM::openPort: error creating Windows MM MIDI input port."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - // Allocate and init the sysex buffers. - for ( int i=0; isysexBuffer[i] = (MIDIHDR*) new char[ sizeof(MIDIHDR) ]; - data->sysexBuffer[i]->lpData = new char[ RT_SYSEX_BUFFER_SIZE ]; - data->sysexBuffer[i]->dwBufferLength = RT_SYSEX_BUFFER_SIZE; - data->sysexBuffer[i]->dwUser = i; // We use the dwUser parameter as buffer indicator - data->sysexBuffer[i]->dwFlags = 0; + // Allocate and init the sysex buffers. + for (int i = 0; i < RT_SYSEX_BUFFER_COUNT; ++i) + { + data->sysexBuffer[i] = (MIDIHDR *)new char[sizeof(MIDIHDR)]; + data->sysexBuffer[i]->lpData = new char[RT_SYSEX_BUFFER_SIZE]; + data->sysexBuffer[i]->dwBufferLength = RT_SYSEX_BUFFER_SIZE; + data->sysexBuffer[i]->dwUser = i; // We use the dwUser parameter as buffer indicator + data->sysexBuffer[i]->dwFlags = 0; - result = midiInPrepareHeader( data->inHandle, data->sysexBuffer[i], sizeof(MIDIHDR) ); - if ( result != MMSYSERR_NOERROR ) { - midiInClose( data->inHandle ); - errorString_ = "MidiInWinMM::openPort: error starting Windows MM MIDI input port (PrepareHeader)."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + result = midiInPrepareHeader(data->inHandle, data->sysexBuffer[i], sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) + { + midiInClose(data->inHandle); + errorString_ = "MidiInWinMM::openPort: error starting Windows MM MIDI input port (PrepareHeader)."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - // Register the buffer. - result = midiInAddBuffer( data->inHandle, data->sysexBuffer[i], sizeof(MIDIHDR) ); - if ( result != MMSYSERR_NOERROR ) { - midiInClose( data->inHandle ); - errorString_ = "MidiInWinMM::openPort: error starting Windows MM MIDI input port (AddBuffer)."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } - } + // Register the buffer. + result = midiInAddBuffer(data->inHandle, data->sysexBuffer[i], sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) + { + midiInClose(data->inHandle); + errorString_ = "MidiInWinMM::openPort: error starting Windows MM MIDI input port (AddBuffer)."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } + } - result = midiInStart( data->inHandle ); - if ( result != MMSYSERR_NOERROR ) { - midiInClose( data->inHandle ); - errorString_ = "MidiInWinMM::openPort: error starting Windows MM MIDI input port."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + result = midiInStart(data->inHandle); + if (result != MMSYSERR_NOERROR) + { + midiInClose(data->inHandle); + errorString_ = "MidiInWinMM::openPort: error starting Windows MM MIDI input port."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - connected_ = true; + connected_ = true; } -void MidiInWinMM :: openVirtualPort( std::string portName ) +void MidiInWinMM ::openVirtualPort(std::string portName) { - // This function cannot be implemented for the Windows MM MIDI API. - errorString_ = "MidiInWinMM::openVirtualPort: cannot be implemented in Windows MM MIDI API!"; - RtMidi::error( RtError::WARNING, errorString_ ); + // This function cannot be implemented for the Windows MM MIDI API. + errorString_ = "MidiInWinMM::openVirtualPort: cannot be implemented in Windows MM MIDI API!"; + RtMidi::error(RtError::WARNING, errorString_); } -void MidiInWinMM :: closePort( void ) +void MidiInWinMM ::closePort(void) { - if ( connected_ ) { - WinMidiData *data = static_cast (apiData_); - midiInReset( data->inHandle ); - midiInStop( data->inHandle ); + if (connected_) + { + WinMidiData *data = static_cast(apiData_); + midiInReset(data->inHandle); + midiInStop(data->inHandle); - for ( int i=0; iinHandle, data->sysexBuffer[i], sizeof(MIDIHDR)); - delete [] data->sysexBuffer[i]->lpData; - delete [] data->sysexBuffer[i]; - if ( result != MMSYSERR_NOERROR ) { - midiInClose( data->inHandle ); - errorString_ = "MidiInWinMM::openPort: error closing Windows MM MIDI input port (midiInUnprepareHeader)."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } - } + for (int i = 0; i < RT_SYSEX_BUFFER_COUNT; ++i) + { + int result = midiInUnprepareHeader(data->inHandle, data->sysexBuffer[i], sizeof(MIDIHDR)); + delete[] data->sysexBuffer[i]->lpData; + delete[] data->sysexBuffer[i]; + if (result != MMSYSERR_NOERROR) + { + midiInClose(data->inHandle); + errorString_ = "MidiInWinMM::openPort: error closing Windows MM MIDI input port (midiInUnprepareHeader)."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } + } - midiInClose( data->inHandle ); - connected_ = false; - } + midiInClose(data->inHandle); + connected_ = false; + } } -unsigned int MidiInWinMM :: getPortCount() +unsigned int MidiInWinMM ::getPortCount() { - return midiInGetNumDevs(); + return midiInGetNumDevs(); } -std::string MidiInWinMM :: getPortName( unsigned int portNumber ) +std::string MidiInWinMM ::getPortName(unsigned int portNumber) { - std::string stringName; - unsigned int nDevices = midiInGetNumDevs(); - if ( portNumber >= nDevices ) { - std::ostringstream ost; - ost << "MidiInWinMM::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - //RtMidi::error( RtError::INVALID_PARAMETER, errorString_ ); - RtMidi::error( RtError::WARNING, errorString_ ); - return stringName; - } + std::string stringName; + unsigned int nDevices = midiInGetNumDevs(); + if (portNumber >= nDevices) + { + std::ostringstream ost; + ost << "MidiInWinMM::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + //RtMidi::error( RtError::INVALID_PARAMETER, errorString_ ); + RtMidi::error(RtError::WARNING, errorString_); + return stringName; + } - MIDIINCAPS deviceCaps; - midiInGetDevCaps( portNumber, &deviceCaps, sizeof(MIDIINCAPS)); + MIDIINCAPS deviceCaps; + midiInGetDevCaps(portNumber, &deviceCaps, sizeof(MIDIINCAPS)); -#if defined( UNICODE ) || defined( _UNICODE ) - int length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, -1, NULL, 0, NULL, NULL); - stringName.assign( length, 0 ); - length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, wcslen(deviceCaps.szPname), &stringName[0], length, NULL, NULL); +#if defined(UNICODE) || defined(_UNICODE) + int length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, -1, NULL, 0, NULL, NULL); + stringName.assign(length, 0); + length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, wcslen(deviceCaps.szPname), &stringName[0], length, NULL, NULL); #else - stringName = std::string( deviceCaps.szPname ); + stringName = std::string(deviceCaps.szPname); #endif - // Next lines added to add the portNumber to the name so that - // the device's names are sure to be listed with individual names - // even when they have the same brand name - std::ostringstream os; - os << " "; - os << portNumber; - stringName += os.str(); + // Next lines added to add the portNumber to the name so that + // the device's names are sure to be listed with individual names + // even when they have the same brand name + std::ostringstream os; + os << " "; + os << portNumber; + stringName += os.str(); - return stringName; + return stringName; } //*********************************************************************// @@ -2158,192 +2343,207 @@ std::string MidiInWinMM :: getPortName( unsigned int portNumber ) // Class Definitions: MidiOutWinMM //*********************************************************************// -MidiOutWinMM :: MidiOutWinMM( const std::string clientName ) : MidiOutApi() +MidiOutWinMM ::MidiOutWinMM(const std::string clientName) : MidiOutApi() { - initialize( clientName ); + initialize(clientName); } -MidiOutWinMM :: ~MidiOutWinMM() +MidiOutWinMM ::~MidiOutWinMM() { - // Close a connection if it exists. - closePort(); + // Close a connection if it exists. + closePort(); - // Cleanup. - WinMidiData *data = static_cast (apiData_); - delete data; + // Cleanup. + WinMidiData *data = static_cast(apiData_); + delete data; } -void MidiOutWinMM :: initialize( const std::string& /*clientName*/ ) +void MidiOutWinMM ::initialize(const std::string & /*clientName*/) { - // We'll issue a warning here if no devices are available but not - // throw an error since the user can plug something in later. - unsigned int nDevices = midiOutGetNumDevs(); - if ( nDevices == 0 ) { - errorString_ = "MidiOutWinMM::initialize: no MIDI output devices currently available."; - RtMidi::error( RtError::WARNING, errorString_ ); - } + // We'll issue a warning here if no devices are available but not + // throw an error since the user can plug something in later. + unsigned int nDevices = midiOutGetNumDevs(); + if (nDevices == 0) + { + errorString_ = "MidiOutWinMM::initialize: no MIDI output devices currently available."; + RtMidi::error(RtError::WARNING, errorString_); + } - // Save our api-specific connection information. - WinMidiData *data = (WinMidiData *) new WinMidiData; - apiData_ = (void *) data; + // Save our api-specific connection information. + WinMidiData *data = (WinMidiData *)new WinMidiData; + apiData_ = (void *)data; } -unsigned int MidiOutWinMM :: getPortCount() +unsigned int MidiOutWinMM ::getPortCount() { - return midiOutGetNumDevs(); + return midiOutGetNumDevs(); } -std::string MidiOutWinMM :: getPortName( unsigned int portNumber ) +std::string MidiOutWinMM ::getPortName(unsigned int portNumber) { - std::string stringName; - unsigned int nDevices = midiOutGetNumDevs(); - if ( portNumber >= nDevices ) { - std::ostringstream ost; - ost << "MidiOutWinMM::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - //RtMidi::error( RtError::INVALID_PARAMETER, errorString_ ); - RtMidi::error( RtError::WARNING, errorString_ ); - return stringName; - } + std::string stringName; + unsigned int nDevices = midiOutGetNumDevs(); + if (portNumber >= nDevices) + { + std::ostringstream ost; + ost << "MidiOutWinMM::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + //RtMidi::error( RtError::INVALID_PARAMETER, errorString_ ); + RtMidi::error(RtError::WARNING, errorString_); + return stringName; + } - MIDIOUTCAPS deviceCaps; - midiOutGetDevCaps( portNumber, &deviceCaps, sizeof(MIDIOUTCAPS)); + MIDIOUTCAPS deviceCaps; + midiOutGetDevCaps(portNumber, &deviceCaps, sizeof(MIDIOUTCAPS)); -#if defined( UNICODE ) || defined( _UNICODE ) - int length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, -1, NULL, 0, NULL, NULL); - stringName.assign( length, 0 ); - length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, wcslen(deviceCaps.szPname), &stringName[0], length, NULL, NULL); +#if defined(UNICODE) || defined(_UNICODE) + int length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, -1, NULL, 0, NULL, NULL); + stringName.assign(length, 0); + length = WideCharToMultiByte(CP_UTF8, 0, deviceCaps.szPname, wcslen(deviceCaps.szPname), &stringName[0], length, NULL, NULL); #else - stringName = std::string( deviceCaps.szPname ); + stringName = std::string(deviceCaps.szPname); #endif - return stringName; + return stringName; } -void MidiOutWinMM :: openPort( unsigned int portNumber, const std::string /*portName*/ ) +void MidiOutWinMM ::openPort(unsigned int portNumber, const std::string /*portName*/) { - if ( connected_ ) { - errorString_ = "MidiOutWinMM::openPort: a valid connection already exists!"; - RtMidi::error( RtError::WARNING, errorString_ ); - return; - } + if (connected_) + { + errorString_ = "MidiOutWinMM::openPort: a valid connection already exists!"; + RtMidi::error(RtError::WARNING, errorString_); + return; + } - unsigned int nDevices = midiOutGetNumDevs(); - if (nDevices < 1) { - errorString_ = "MidiOutWinMM::openPort: no MIDI output destinations found!"; - RtMidi::error( RtError::NO_DEVICES_FOUND, errorString_ ); - } + unsigned int nDevices = midiOutGetNumDevs(); + if (nDevices < 1) + { + errorString_ = "MidiOutWinMM::openPort: no MIDI output destinations found!"; + RtMidi::error(RtError::NO_DEVICES_FOUND, errorString_); + } - std::ostringstream ost; - if ( portNumber >= nDevices ) { - ost << "MidiOutWinMM::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - RtMidi::error( RtError::INVALID_PARAMETER, errorString_ ); - } + std::ostringstream ost; + if (portNumber >= nDevices) + { + ost << "MidiOutWinMM::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + RtMidi::error(RtError::INVALID_PARAMETER, errorString_); + } - WinMidiData *data = static_cast (apiData_); - MMRESULT result = midiOutOpen( &data->outHandle, - portNumber, - (DWORD)NULL, - (DWORD)NULL, - CALLBACK_NULL ); - if ( result != MMSYSERR_NOERROR ) { - errorString_ = "MidiOutWinMM::openPort: error creating Windows MM MIDI output port."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + WinMidiData *data = static_cast(apiData_); + MMRESULT result = midiOutOpen(&data->outHandle, + portNumber, + (DWORD)NULL, + (DWORD)NULL, + CALLBACK_NULL); + if (result != MMSYSERR_NOERROR) + { + errorString_ = "MidiOutWinMM::openPort: error creating Windows MM MIDI output port."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - connected_ = true; + connected_ = true; } -void MidiOutWinMM :: closePort( void ) +void MidiOutWinMM ::closePort(void) { - if ( connected_ ) { - WinMidiData *data = static_cast (apiData_); - midiOutReset( data->outHandle ); - midiOutClose( data->outHandle ); - connected_ = false; - } + if (connected_) + { + WinMidiData *data = static_cast(apiData_); + midiOutReset(data->outHandle); + midiOutClose(data->outHandle); + connected_ = false; + } } -void MidiOutWinMM :: openVirtualPort( std::string portName ) +void MidiOutWinMM ::openVirtualPort(std::string portName) { - // This function cannot be implemented for the Windows MM MIDI API. - errorString_ = "MidiOutWinMM::openVirtualPort: cannot be implemented in Windows MM MIDI API!"; - RtMidi::error( RtError::WARNING, errorString_ ); + // This function cannot be implemented for the Windows MM MIDI API. + errorString_ = "MidiOutWinMM::openVirtualPort: cannot be implemented in Windows MM MIDI API!"; + RtMidi::error(RtError::WARNING, errorString_); } -void MidiOutWinMM :: sendMessage( std::vector *message ) +void MidiOutWinMM ::sendMessage(std::vector *message) { - unsigned int nBytes = static_cast(message->size()); - if ( nBytes == 0 ) { - errorString_ = "MidiOutWinMM::sendMessage: message argument is empty!"; - RtMidi::error( RtError::WARNING, errorString_ ); - return; - } + unsigned int nBytes = static_cast(message->size()); + if (nBytes == 0) + { + errorString_ = "MidiOutWinMM::sendMessage: message argument is empty!"; + RtMidi::error(RtError::WARNING, errorString_); + return; + } - MMRESULT result; - WinMidiData *data = static_cast (apiData_); - if ( message->at(0) == 0xF0 ) { // Sysex message + MMRESULT result; + WinMidiData *data = static_cast(apiData_); + if (message->at(0) == 0xF0) + { // Sysex message - // Allocate buffer for sysex data. - char *buffer = (char *) malloc( nBytes ); - if ( buffer == NULL ) { - errorString_ = "MidiOutWinMM::sendMessage: error allocating sysex message memory!"; - RtMidi::error( RtError::MEMORY_ERROR, errorString_ ); - } + // Allocate buffer for sysex data. + char *buffer = (char *)malloc(nBytes); + if (buffer == NULL) + { + errorString_ = "MidiOutWinMM::sendMessage: error allocating sysex message memory!"; + RtMidi::error(RtError::MEMORY_ERROR, errorString_); + } - // Copy data to buffer. - for ( unsigned int i=0; iat(i); + // Copy data to buffer. + for (unsigned int i = 0; i < nBytes; ++i) buffer[i] = message->at(i); - // Create and prepare MIDIHDR structure. - MIDIHDR sysex; - sysex.lpData = (LPSTR) buffer; - sysex.dwBufferLength = nBytes; - sysex.dwFlags = 0; - result = midiOutPrepareHeader( data->outHandle, &sysex, sizeof(MIDIHDR) ); - if ( result != MMSYSERR_NOERROR ) { - free( buffer ); - errorString_ = "MidiOutWinMM::sendMessage: error preparing sysex header."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + // Create and prepare MIDIHDR structure. + MIDIHDR sysex; + sysex.lpData = (LPSTR)buffer; + sysex.dwBufferLength = nBytes; + sysex.dwFlags = 0; + result = midiOutPrepareHeader(data->outHandle, &sysex, sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) + { + free(buffer); + errorString_ = "MidiOutWinMM::sendMessage: error preparing sysex header."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - // Send the message. - result = midiOutLongMsg( data->outHandle, &sysex, sizeof(MIDIHDR) ); - if ( result != MMSYSERR_NOERROR ) { - free( buffer ); - errorString_ = "MidiOutWinMM::sendMessage: error sending sysex message."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + // Send the message. + result = midiOutLongMsg(data->outHandle, &sysex, sizeof(MIDIHDR)); + if (result != MMSYSERR_NOERROR) + { + free(buffer); + errorString_ = "MidiOutWinMM::sendMessage: error sending sysex message."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - // Unprepare the buffer and MIDIHDR. - while ( MIDIERR_STILLPLAYING == midiOutUnprepareHeader( data->outHandle, &sysex, sizeof (MIDIHDR) ) ) Sleep( 1 ); - free( buffer ); + // Unprepare the buffer and MIDIHDR. + while (MIDIERR_STILLPLAYING == midiOutUnprepareHeader(data->outHandle, &sysex, sizeof(MIDIHDR))) Sleep(1); + free(buffer); + } + else + { // Channel or system message. - } - else { // Channel or system message. + // Make sure the message size isn't too big. + if (nBytes > 3) + { + errorString_ = "MidiOutWinMM::sendMessage: message size is greater than 3 bytes (and not sysex)!"; + RtMidi::error(RtError::WARNING, errorString_); + return; + } - // Make sure the message size isn't too big. - if ( nBytes > 3 ) { - errorString_ = "MidiOutWinMM::sendMessage: message size is greater than 3 bytes (and not sysex)!"; - RtMidi::error( RtError::WARNING, errorString_ ); - return; - } + // Pack MIDI bytes into double word. + DWORD packet; + unsigned char *ptr = (unsigned char *)&packet; + for (unsigned int i = 0; i < nBytes; ++i) + { + *ptr = message->at(i); + ++ptr; + } - // Pack MIDI bytes into double word. - DWORD packet; - unsigned char *ptr = (unsigned char *) &packet; - for ( unsigned int i=0; iat(i); - ++ptr; - } - - // Send the message immediately. - result = midiOutShortMsg( data->outHandle, packet ); - if ( result != MMSYSERR_NOERROR ) { - errorString_ = "MidiOutWinMM::sendMessage: error sending MIDI message."; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } - } + // Send the message immediately. + result = midiOutShortMsg(data->outHandle, packet); + if (result != MMSYSERR_NOERROR) + { + errorString_ = "MidiOutWinMM::sendMessage: error sending MIDI message."; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } + } } #endif // __WINDOWS_MM__ @@ -2371,7 +2571,7 @@ void MidiOutWinMM :: sendMessage( std::vector *message ) #include "ks.h" #include "ksmedia.h" -#define INSTANTIATE_GUID(a) GUID const a = { STATIC_ ## a } +#define INSTANTIATE_GUID(a) GUID const a = {STATIC_##a} INSTANTIATE_GUID(GUID_NULL); INSTANTIATE_GUID(KSPROPSETID_Pin); @@ -2389,716 +2589,712 @@ typedef std::basic_string tstring; inline bool IsValid(HANDLE handle) { - return handle != NULL && handle != INVALID_HANDLE_VALUE; + return handle != NULL && handle != INVALID_HANDLE_VALUE; } class ComException : public std::runtime_error { private: - static std::string MakeString(std::string const& s, HRESULT hr) - { - std::stringstream ss; - ss << "(error 0x" << std::hex << hr << ")"; - return s + ss.str(); - } + static std::string MakeString(std::string const &s, HRESULT hr) + { + std::stringstream ss; + ss << "(error 0x" << std::hex << hr << ")"; + return s + ss.str(); + } public: - ComException(std::string const& s, HRESULT hr) : - std::runtime_error(MakeString(s, hr)) - { - } + ComException(std::string const &s, HRESULT hr) : std::runtime_error(MakeString(s, hr)) + { + } }; -template +template class CKsEnumFilters { public: - ~CKsEnumFilters() - { - DestroyLists(); - } - - void EnumFilters(GUID const* categories, size_t numCategories) - { - DestroyLists(); - - if (categories == 0) + ~CKsEnumFilters() { - printf ("Error: CKsEnumFilters: invalid argument\n"); - assert(0); - } - // Get a handle to the device set specified by the guid - HDEVINFO hDevInfo = ::SetupDiGetClassDevs(&categories[0], NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); - if (!IsValid(hDevInfo)) - { - printf ("Error: CKsEnumFilters: no devices found"); - assert (0); + DestroyLists(); } - // Loop through members of the set and get details for each - for (int iClassMember=0;;iClassMember++) { - { - SP_DEVICE_INTERFACE_DATA DID; - DID.cbSize = sizeof(DID); - DID.Reserved = 0; + void EnumFilters(GUID const *categories, size_t numCategories) + { + DestroyLists(); - bool fRes = ::SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &categories[0], iClassMember, &DID); - if (!fRes) - break; - - // Get filter friendly name - HKEY hRegKey = ::SetupDiOpenDeviceInterfaceRegKey(hDevInfo, &DID, 0, KEY_READ); - if (hRegKey == INVALID_HANDLE_VALUE) + if (categories == 0) { + printf("Error: CKsEnumFilters: invalid argument\n"); assert(0); + } + // Get a handle to the device set specified by the guid + HDEVINFO hDevInfo = ::SetupDiGetClassDevs(&categories[0], NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE); + if (!IsValid(hDevInfo)) + { + printf("Error: CKsEnumFilters: no devices found"); + assert(0); + } + + // Loop through members of the set and get details for each + for (int iClassMember = 0;; iClassMember++) + { + { + SP_DEVICE_INTERFACE_DATA DID; + DID.cbSize = sizeof(DID); + DID.Reserved = 0; + + bool fRes = ::SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &categories[0], iClassMember, &DID); + if (!fRes) + break; + + // Get filter friendly name + HKEY hRegKey = ::SetupDiOpenDeviceInterfaceRegKey(hDevInfo, &DID, 0, KEY_READ); + if (hRegKey == INVALID_HANDLE_VALUE) + { + assert(0); printf "CKsEnumFilters: interface has no registry\n"); + } + char friendlyName[256]; + DWORD dwSize = sizeof friendlyName; + LONG lval = ::RegQueryValueEx(hRegKey, TEXT("FriendlyName"), NULL, NULL, (LPBYTE)friendlyName, &dwSize); + ::RegCloseKey(hRegKey); + if (lval != ERROR_SUCCESS) + { + assert(0); + printf("CKsEnumFilters: interface has no friendly name"); + } + // Get details for the device registered in this class + DWORD const cbItfDetails = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + MAX_PATH * sizeof(WCHAR); + std::vector buffer(cbItfDetails); + + SP_DEVICE_INTERFACE_DETAIL_DATA *pDevInterfaceDetails = reinterpret_cast(&buffer[0]); + pDevInterfaceDetails->cbSize = sizeof(*pDevInterfaceDetails); + + SP_DEVINFO_DATA DevInfoData; + DevInfoData.cbSize = sizeof(DevInfoData); + DevInfoData.Reserved = 0; + + fRes = ::SetupDiGetDeviceInterfaceDetail(hDevInfo, &DID, pDevInterfaceDetails, cbItfDetails, NULL, &DevInfoData); + if (!fRes) + { + printf("CKsEnumFilters: could not get interface details"); + assert(0); + } + // check additional category guids which may (or may not) have been supplied + for (size_t i = 1; i < numCategories; ++i) + { + SP_DEVICE_INTERFACE_DATA DIDAlias; + DIDAlias.cbSize = sizeof(DIDAlias); + DIDAlias.Reserved = 0; + + fRes = ::SetupDiGetDeviceInterfaceAlias(hDevInfo, &DID, &categories[i], &DIDAlias); + if (!fRes) + { + printf("CKsEnumFilters: could not get interface alias"); + assert(0); + } + // Check if the this interface alias is enabled. + if (!DIDAlias.Flags || (DIDAlias.Flags & SPINT_REMOVED)) + { + printf("CKsEnumFilters: interface alias is not enabled"); + assert(0); + } + } + + std::auto_ptr pFilter(new TFilterType(pDevInterfaceDetails->DevicePath, friendlyName)); + + pFilter->Instantiate(); + pFilter->FindMidiPins(); + pFilter->Validate(); + + m_Filters.push_back(pFilter.release()); + } } - char friendlyName[256]; - DWORD dwSize = sizeof friendlyName; - LONG lval = ::RegQueryValueEx(hRegKey, TEXT("FriendlyName"), NULL, NULL, (LPBYTE)friendlyName, &dwSize); - ::RegCloseKey(hRegKey); - if (lval != ERROR_SUCCESS) - { - assert(0); - printf ("CKsEnumFilters: interface has no friendly name"); - } - // Get details for the device registered in this class - DWORD const cbItfDetails = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA) + MAX_PATH * sizeof(WCHAR); - std::vector buffer(cbItfDetails); - SP_DEVICE_INTERFACE_DETAIL_DATA* pDevInterfaceDetails = reinterpret_cast(&buffer[0]); - pDevInterfaceDetails->cbSize = sizeof(*pDevInterfaceDetails); - - SP_DEVINFO_DATA DevInfoData; - DevInfoData.cbSize = sizeof(DevInfoData); - DevInfoData.Reserved = 0; - - fRes = ::SetupDiGetDeviceInterfaceDetail(hDevInfo, &DID, pDevInterfaceDetails, cbItfDetails, NULL, &DevInfoData); - if (!fRes) - { - printf("CKsEnumFilters: could not get interface details"); - assert(0); - } - // check additional category guids which may (or may not) have been supplied - for (size_t i=1; i < numCategories; ++i) { - SP_DEVICE_INTERFACE_DATA DIDAlias; - DIDAlias.cbSize = sizeof(DIDAlias); - DIDAlias.Reserved = 0; - - fRes = ::SetupDiGetDeviceInterfaceAlias(hDevInfo, &DID, &categories[i], &DIDAlias); - if (!fRes) - { - printf("CKsEnumFilters: could not get interface alias"); - assert(0); - } - // Check if the this interface alias is enabled. - if (!DIDAlias.Flags || (DIDAlias.Flags & SPINT_REMOVED)) - { - printf("CKsEnumFilters: interface alias is not enabled"); - assert(0); - } - } - - std::auto_ptr pFilter(new TFilterType(pDevInterfaceDetails->DevicePath, friendlyName)); - - pFilter->Instantiate(); - pFilter->FindMidiPins(); - pFilter->Validate(); - - m_Filters.push_back(pFilter.release()); - } - } - - ::SetupDiDestroyDeviceInfoList(hDevInfo); - } + ::SetupDiDestroyDeviceInfoList(hDevInfo); + } private: - void DestroyLists() - { - for (size_t i=0;i < m_Filters.size();++i) - delete m_Filters[i]; - m_Filters.clear(); - } + void DestroyLists() + { + for (size_t i = 0; i < m_Filters.size(); ++i) + delete m_Filters[i]; + m_Filters.clear(); + } public: - // TODO: make this private. - std::vector m_Filters; + // TODO: make this private. + std::vector m_Filters; }; class CKsObject { public: - CKsObject(HANDLE handle) : m_handle(handle) - { - } + CKsObject(HANDLE handle) : m_handle(handle) + { + } protected: - HANDLE m_handle; + HANDLE m_handle; - void SetProperty(REFGUID guidPropertySet, ULONG nProperty, void* pvValue, ULONG cbValue) - { - KSPROPERTY ksProperty; - memset(&ksProperty, 0, sizeof ksProperty); - ksProperty.Set = guidPropertySet; - ksProperty.Id = nProperty; - ksProperty.Flags = KSPROPERTY_TYPE_SET; - - HRESULT hr = DeviceIoControlKsProperty(ksProperty, pvValue, cbValue); - if (FAILED(hr)) + void SetProperty(REFGUID guidPropertySet, ULONG nProperty, void *pvValue, ULONG cbValue) { - printf("CKsObject::SetProperty: could not set property"); - exit(0); + KSPROPERTY ksProperty; + memset(&ksProperty, 0, sizeof ksProperty); + ksProperty.Set = guidPropertySet; + ksProperty.Id = nProperty; + ksProperty.Flags = KSPROPERTY_TYPE_SET; + + HRESULT hr = DeviceIoControlKsProperty(ksProperty, pvValue, cbValue); + if (FAILED(hr)) + { + printf("CKsObject::SetProperty: could not set property"); + exit(0); + } } - } private: - - HRESULT DeviceIoControlKsProperty(KSPROPERTY& ksProperty, void* pvValue, ULONG cbValue) - { - ULONG ulReturned; - return ::DeviceIoControl( - m_handle, - IOCTL_KS_PROPERTY, - &ksProperty, - sizeof(ksProperty), - pvValue, - cbValue, - &ulReturned, - NULL); - } + HRESULT DeviceIoControlKsProperty(KSPROPERTY &ksProperty, void *pvValue, ULONG cbValue) + { + ULONG ulReturned; + return ::DeviceIoControl( + m_handle, + IOCTL_KS_PROPERTY, + &ksProperty, + sizeof(ksProperty), + pvValue, + cbValue, + &ulReturned, + NULL); + } }; class CKsPin; class CKsFilter : public CKsObject { - friend class CKsPin; + friend class CKsPin; public: - CKsFilter(tstring const& name, std::string const& sFriendlyName); - virtual ~CKsFilter(); + CKsFilter(tstring const &name, std::string const &sFriendlyName); + virtual ~CKsFilter(); - virtual void Instantiate(); + virtual void Instantiate(); - template - T GetPinProperty(ULONG nPinId, ULONG nProperty) - { - ULONG ulReturned = 0; - T value; - - KSP_PIN ksPProp; - ksPProp.Property.Set = KSPROPSETID_Pin; - ksPProp.Property.Id = nProperty; - ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; - ksPProp.PinId = nPinId; - ksPProp.Reserved = 0; - - HRESULT hr = ::DeviceIoControl( - m_handle, - IOCTL_KS_PROPERTY, - &ksPProp, - sizeof(KSP_PIN), - &value, - sizeof(value), - &ulReturned, - NULL); - if (FAILED(hr)) + template + T GetPinProperty(ULONG nPinId, ULONG nProperty) { - printf("CKsFilter::GetPinProperty: failed to retrieve property"); - exit(0); + ULONG ulReturned = 0; + T value; + + KSP_PIN ksPProp; + ksPProp.Property.Set = KSPROPSETID_Pin; + ksPProp.Property.Id = nProperty; + ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; + ksPProp.PinId = nPinId; + ksPProp.Reserved = 0; + + HRESULT hr = ::DeviceIoControl( + m_handle, + IOCTL_KS_PROPERTY, + &ksPProp, + sizeof(KSP_PIN), + &value, + sizeof(value), + &ulReturned, + NULL); + if (FAILED(hr)) + { + printf("CKsFilter::GetPinProperty: failed to retrieve property"); + exit(0); + } + + return value; } - return value; - } - - void GetPinPropertyMulti(ULONG nPinId, REFGUID guidPropertySet, ULONG nProperty, PKSMULTIPLE_ITEM* ppKsMultipleItem) - { - HRESULT hr; - - KSP_PIN ksPProp; - ksPProp.Property.Set = guidPropertySet; - ksPProp.Property.Id = nProperty; - ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; - ksPProp.PinId = nPinId; - ksPProp.Reserved = 0; - - ULONG cbMultipleItem = 0; - hr = ::DeviceIoControl(m_handle, - IOCTL_KS_PROPERTY, - &ksPProp.Property, - sizeof(KSP_PIN), - NULL, - 0, - &cbMultipleItem, - NULL); - if (FAILED(hr)) + void GetPinPropertyMulti(ULONG nPinId, REFGUID guidPropertySet, ULONG nProperty, PKSMULTIPLE_ITEM *ppKsMultipleItem) { - printf("CKsFilter::GetPinPropertyMulti: cannot get property"); - exit(0); + HRESULT hr; + + KSP_PIN ksPProp; + ksPProp.Property.Set = guidPropertySet; + ksPProp.Property.Id = nProperty; + ksPProp.Property.Flags = KSPROPERTY_TYPE_GET; + ksPProp.PinId = nPinId; + ksPProp.Reserved = 0; + + ULONG cbMultipleItem = 0; + hr = ::DeviceIoControl(m_handle, + IOCTL_KS_PROPERTY, + &ksPProp.Property, + sizeof(KSP_PIN), + NULL, + 0, + &cbMultipleItem, + NULL); + if (FAILED(hr)) + { + printf("CKsFilter::GetPinPropertyMulti: cannot get property"); + exit(0); + } + + *ppKsMultipleItem = (PKSMULTIPLE_ITEM) new BYTE[cbMultipleItem]; + + ULONG ulReturned = 0; + hr = ::DeviceIoControl( + m_handle, + IOCTL_KS_PROPERTY, + &ksPProp, + sizeof(KSP_PIN), + (PVOID)*ppKsMultipleItem, + cbMultipleItem, + &ulReturned, + NULL); + if (FAILED(hr)) + { + printf("CKsFilter::GetPinPropertyMulti: cannot get property"); + exit(0); + } } - *ppKsMultipleItem = (PKSMULTIPLE_ITEM) new BYTE[cbMultipleItem]; - - ULONG ulReturned = 0; - hr = ::DeviceIoControl( - m_handle, - IOCTL_KS_PROPERTY, - &ksPProp, - sizeof(KSP_PIN), - (PVOID)*ppKsMultipleItem, - cbMultipleItem, - &ulReturned, - NULL); - if (FAILED(hr)) + std::string const &GetFriendlyName() const { - printf("CKsFilter::GetPinPropertyMulti: cannot get property"); - exit(0); + return m_sFriendlyName; } - } - - std::string const& GetFriendlyName() const - { - return m_sFriendlyName; - } protected: + std::vector m_Pins; // this list owns the pins. - std::vector m_Pins; // this list owns the pins. - - std::vector m_RenderPins; - std::vector m_CapturePins; + std::vector m_RenderPins; + std::vector m_CapturePins; private: - std::string const m_sFriendlyName; // friendly name eg "Virus TI Synth" - tstring const m_sName; // Filter path, eg "\\?\usb#vid_133e&pid_0815...\vtimidi02" + std::string const m_sFriendlyName; // friendly name eg "Virus TI Synth" + tstring const m_sName; // Filter path, eg "\\?\usb#vid_133e&pid_0815...\vtimidi02" }; class CKsPin : public CKsObject { public: - CKsPin(CKsFilter* pFilter, ULONG nId); - virtual ~CKsPin(); + CKsPin(CKsFilter *pFilter, ULONG nId); + virtual ~CKsPin(); - virtual void Instantiate(); + virtual void Instantiate(); - void ClosePin(); + void ClosePin(); - void SetState(KSSTATE ksState); + void SetState(KSSTATE ksState); - void WriteData(KSSTREAM_HEADER* pKSSTREAM_HEADER, OVERLAPPED* pOVERLAPPED); - void ReadData(KSSTREAM_HEADER* pKSSTREAM_HEADER, OVERLAPPED* pOVERLAPPED); + void WriteData(KSSTREAM_HEADER *pKSSTREAM_HEADER, OVERLAPPED *pOVERLAPPED); + void ReadData(KSSTREAM_HEADER *pKSSTREAM_HEADER, OVERLAPPED *pOVERLAPPED); - KSPIN_DATAFLOW GetDataFlow() const - { - return m_DataFlow; - } - - bool IsSink() const - { - return m_Communication == KSPIN_COMMUNICATION_SINK - || m_Communication == KSPIN_COMMUNICATION_BOTH; - } + KSPIN_DATAFLOW GetDataFlow() const + { + return m_DataFlow; + } + bool IsSink() const + { + return m_Communication == KSPIN_COMMUNICATION_SINK || m_Communication == KSPIN_COMMUNICATION_BOTH; + } protected: - PKSPIN_CONNECT m_pKsPinConnect; // creation parameters of pin - CKsFilter* const m_pFilter; + PKSPIN_CONNECT m_pKsPinConnect; // creation parameters of pin + CKsFilter *const m_pFilter; - ULONG m_cInterfaces; - PKSIDENTIFIER m_pInterfaces; - PKSMULTIPLE_ITEM m_pmiInterfaces; + ULONG m_cInterfaces; + PKSIDENTIFIER m_pInterfaces; + PKSMULTIPLE_ITEM m_pmiInterfaces; - ULONG m_cMediums; - PKSIDENTIFIER m_pMediums; - PKSMULTIPLE_ITEM m_pmiMediums; + ULONG m_cMediums; + PKSIDENTIFIER m_pMediums; + PKSMULTIPLE_ITEM m_pmiMediums; - ULONG m_cDataRanges; - PKSDATARANGE m_pDataRanges; - PKSMULTIPLE_ITEM m_pmiDataRanges; + ULONG m_cDataRanges; + PKSDATARANGE m_pDataRanges; + PKSMULTIPLE_ITEM m_pmiDataRanges; - KSPIN_DATAFLOW m_DataFlow; - KSPIN_COMMUNICATION m_Communication; + KSPIN_DATAFLOW m_DataFlow; + KSPIN_COMMUNICATION m_Communication; }; -CKsFilter::CKsFilter(tstring const& sName, std::string const& sFriendlyName) : - CKsObject(INVALID_HANDLE_VALUE), - m_sFriendlyName(sFriendlyName), - m_sName(sName) +CKsFilter::CKsFilter(tstring const &sName, std::string const &sFriendlyName) : CKsObject(INVALID_HANDLE_VALUE), + m_sFriendlyName(sFriendlyName), + m_sName(sName) { - if (sName.empty()) - { - printf("CKsFilter::CKsFilter: name can't be empty"); - assert(0); - } + if (sName.empty()) + { + printf("CKsFilter::CKsFilter: name can't be empty"); + assert(0); + } } CKsFilter::~CKsFilter() { - for (size_t i=0;i < m_Pins.size();++i) - delete m_Pins[i]; + for (size_t i = 0; i < m_Pins.size(); ++i) + delete m_Pins[i]; - if (IsValid(m_handle)) - ::CloseHandle(m_handle); + if (IsValid(m_handle)) + ::CloseHandle(m_handle); } void CKsFilter::Instantiate() { - m_handle = CreateFile( - m_sName.c_str(), - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, - NULL); + m_handle = CreateFile( + m_sName.c_str(), + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, + NULL); - if (!IsValid(m_handle)) - { - DWORD const dwError = GetLastError(); - throw ComException("CKsFilter::Instantiate: can't open driver", HRESULT_FROM_WIN32(dwError)); - } + if (!IsValid(m_handle)) + { + DWORD const dwError = GetLastError(); + throw ComException("CKsFilter::Instantiate: can't open driver", HRESULT_FROM_WIN32(dwError)); + } } -CKsPin::CKsPin(CKsFilter* pFilter, ULONG PinId) : - CKsObject(INVALID_HANDLE_VALUE), - m_pKsPinConnect(NULL), - m_pFilter(pFilter) +CKsPin::CKsPin(CKsFilter *pFilter, ULONG PinId) : CKsObject(INVALID_HANDLE_VALUE), + m_pKsPinConnect(NULL), + m_pFilter(pFilter) { - m_Communication = m_pFilter->GetPinProperty(PinId, KSPROPERTY_PIN_COMMUNICATION); - m_DataFlow = m_pFilter->GetPinProperty(PinId, KSPROPERTY_PIN_DATAFLOW); + m_Communication = m_pFilter->GetPinProperty(PinId, KSPROPERTY_PIN_COMMUNICATION); + m_DataFlow = m_pFilter->GetPinProperty(PinId, KSPROPERTY_PIN_DATAFLOW); - // Interfaces - m_pFilter->GetPinPropertyMulti( - PinId, - KSPROPSETID_Pin, - KSPROPERTY_PIN_INTERFACES, - &m_pmiInterfaces); + // Interfaces + m_pFilter->GetPinPropertyMulti( + PinId, + KSPROPSETID_Pin, + KSPROPERTY_PIN_INTERFACES, + &m_pmiInterfaces); - m_cInterfaces = m_pmiInterfaces->Count; - m_pInterfaces = (PKSPIN_INTERFACE)(m_pmiInterfaces + 1); + m_cInterfaces = m_pmiInterfaces->Count; + m_pInterfaces = (PKSPIN_INTERFACE)(m_pmiInterfaces + 1); - // Mediums - m_pFilter->GetPinPropertyMulti( - PinId, - KSPROPSETID_Pin, - KSPROPERTY_PIN_MEDIUMS, - &m_pmiMediums); + // Mediums + m_pFilter->GetPinPropertyMulti( + PinId, + KSPROPSETID_Pin, + KSPROPERTY_PIN_MEDIUMS, + &m_pmiMediums); - m_cMediums = m_pmiMediums->Count; - m_pMediums = (PKSPIN_MEDIUM)(m_pmiMediums + 1); + m_cMediums = m_pmiMediums->Count; + m_pMediums = (PKSPIN_MEDIUM)(m_pmiMediums + 1); - // Data ranges - m_pFilter->GetPinPropertyMulti( - PinId, - KSPROPSETID_Pin, - KSPROPERTY_PIN_DATARANGES, - &m_pmiDataRanges); + // Data ranges + m_pFilter->GetPinPropertyMulti( + PinId, + KSPROPSETID_Pin, + KSPROPERTY_PIN_DATARANGES, + &m_pmiDataRanges); - m_cDataRanges = m_pmiDataRanges->Count; - m_pDataRanges = (PKSDATARANGE)(m_pmiDataRanges + 1); + m_cDataRanges = m_pmiDataRanges->Count; + m_pDataRanges = (PKSDATARANGE)(m_pmiDataRanges + 1); } CKsPin::~CKsPin() { - ClosePin(); + ClosePin(); - delete[] (BYTE*)m_pKsPinConnect; - delete[] (BYTE*)m_pmiDataRanges; - delete[] (BYTE*)m_pmiInterfaces; - delete[] (BYTE*)m_pmiMediums; + delete[](BYTE *) m_pKsPinConnect; + delete[](BYTE *) m_pmiDataRanges; + delete[](BYTE *) m_pmiInterfaces; + delete[](BYTE *) m_pmiMediums; } void CKsPin::ClosePin() { - if (IsValid(m_handle)) { - SetState(KSSTATE_STOP); - ::CloseHandle(m_handle); - } - m_handle = INVALID_HANDLE_VALUE; + if (IsValid(m_handle)) + { + SetState(KSSTATE_STOP); + ::CloseHandle(m_handle); + } + m_handle = INVALID_HANDLE_VALUE; } void CKsPin::SetState(KSSTATE ksState) { - SetProperty(KSPROPSETID_Connection, KSPROPERTY_CONNECTION_STATE, &ksState, sizeof(ksState)); + SetProperty(KSPROPSETID_Connection, KSPROPERTY_CONNECTION_STATE, &ksState, sizeof(ksState)); } void CKsPin::Instantiate() { - if (!m_pKsPinConnect) - { - printf("CKsPin::Instanciate: abstract pin"); - assert(0); - } - DWORD const dwResult = KsCreatePin(m_pFilter->m_handle, m_pKsPinConnect, GENERIC_WRITE | GENERIC_READ, &m_handle); - if (dwResult != ERROR_SUCCESS) - throw ComException("CKsMidiCapFilter::CreateRenderPin: Pin instanciation failed", HRESULT_FROM_WIN32(dwResult)); + if (!m_pKsPinConnect) + { + printf("CKsPin::Instanciate: abstract pin"); + assert(0); + } + DWORD const dwResult = KsCreatePin(m_pFilter->m_handle, m_pKsPinConnect, GENERIC_WRITE | GENERIC_READ, &m_handle); + if (dwResult != ERROR_SUCCESS) + throw ComException("CKsMidiCapFilter::CreateRenderPin: Pin instanciation failed", HRESULT_FROM_WIN32(dwResult)); } -void CKsPin::WriteData(KSSTREAM_HEADER* pKSSTREAM_HEADER, OVERLAPPED* pOVERLAPPED) +void CKsPin::WriteData(KSSTREAM_HEADER *pKSSTREAM_HEADER, OVERLAPPED *pOVERLAPPED) { - DWORD cbWritten; - BOOL fRes = ::DeviceIoControl( - m_handle, - IOCTL_KS_WRITE_STREAM, - NULL, - 0, - pKSSTREAM_HEADER, - pKSSTREAM_HEADER->Size, - &cbWritten, - pOVERLAPPED); - if (!fRes) { - DWORD const dwError = GetLastError(); - if (dwError != ERROR_IO_PENDING) - throw ComException("CKsPin::WriteData: DeviceIoControl failed", HRESULT_FROM_WIN32(dwError)); - } + DWORD cbWritten; + BOOL fRes = ::DeviceIoControl( + m_handle, + IOCTL_KS_WRITE_STREAM, + NULL, + 0, + pKSSTREAM_HEADER, + pKSSTREAM_HEADER->Size, + &cbWritten, + pOVERLAPPED); + if (!fRes) + { + DWORD const dwError = GetLastError(); + if (dwError != ERROR_IO_PENDING) + throw ComException("CKsPin::WriteData: DeviceIoControl failed", HRESULT_FROM_WIN32(dwError)); + } } -void CKsPin::ReadData(KSSTREAM_HEADER* pKSSTREAM_HEADER, OVERLAPPED* pOVERLAPPED) +void CKsPin::ReadData(KSSTREAM_HEADER *pKSSTREAM_HEADER, OVERLAPPED *pOVERLAPPED) { - DWORD cbReturned; - BOOL fRes = ::DeviceIoControl( - m_handle, - IOCTL_KS_READ_STREAM, - NULL, - 0, - pKSSTREAM_HEADER, - pKSSTREAM_HEADER->Size, - &cbReturned, - pOVERLAPPED); - if (!fRes) { - DWORD const dwError = GetLastError(); - if (dwError != ERROR_IO_PENDING) - throw ComException("CKsPin::ReadData: DeviceIoControl failed", HRESULT_FROM_WIN32(dwError)); - } + DWORD cbReturned; + BOOL fRes = ::DeviceIoControl( + m_handle, + IOCTL_KS_READ_STREAM, + NULL, + 0, + pKSSTREAM_HEADER, + pKSSTREAM_HEADER->Size, + &cbReturned, + pOVERLAPPED); + if (!fRes) + { + DWORD const dwError = GetLastError(); + if (dwError != ERROR_IO_PENDING) + throw ComException("CKsPin::ReadData: DeviceIoControl failed", HRESULT_FROM_WIN32(dwError)); + } } class CKsMidiFilter : public CKsFilter { public: - void FindMidiPins(); + void FindMidiPins(); protected: - CKsMidiFilter(tstring const& sPath, std::string const& sFriendlyName); + CKsMidiFilter(tstring const &sPath, std::string const &sFriendlyName); }; class CKsMidiPin : public CKsPin { public: - CKsMidiPin(CKsFilter* pFilter, ULONG nId); + CKsMidiPin(CKsFilter *pFilter, ULONG nId); }; class CKsMidiRenFilter : public CKsMidiFilter { public: - CKsMidiRenFilter(tstring const& sPath, std::string const& sFriendlyName); - CKsMidiPin* CreateRenderPin(); + CKsMidiRenFilter(tstring const &sPath, std::string const &sFriendlyName); + CKsMidiPin *CreateRenderPin(); - void Validate() - { - if (m_RenderPins.empty()) + void Validate() { - printf("Could not find a MIDI render pin"); - assert(0); + if (m_RenderPins.empty()) + { + printf("Could not find a MIDI render pin"); + assert(0); + } } - } }; class CKsMidiCapFilter : public CKsMidiFilter { public: - CKsMidiCapFilter(tstring const& sPath, std::string const& sFriendlyName); - CKsMidiPin* CreateCapturePin(); + CKsMidiCapFilter(tstring const &sPath, std::string const &sFriendlyName); + CKsMidiPin *CreateCapturePin(); - void Validate() - { - if (m_CapturePins.empty()) + void Validate() { - assert(0); - printf("Could not find a MIDI capture pin"); + if (m_CapturePins.empty()) + { + assert(0); + printf("Could not find a MIDI capture pin"); + } } - } }; -CKsMidiFilter::CKsMidiFilter(tstring const& sPath, std::string const& sFriendlyName) : - CKsFilter(sPath, sFriendlyName) +CKsMidiFilter::CKsMidiFilter(tstring const &sPath, std::string const &sFriendlyName) : CKsFilter(sPath, sFriendlyName) { } void CKsMidiFilter::FindMidiPins() { - ULONG numPins = GetPinProperty(0, KSPROPERTY_PIN_CTYPES); + ULONG numPins = GetPinProperty(0, KSPROPERTY_PIN_CTYPES); - for (ULONG iPin = 0; iPin < numPins; ++iPin) { - { - KSPIN_COMMUNICATION com = GetPinProperty(iPin, KSPROPERTY_PIN_COMMUNICATION); - if (com != KSPIN_COMMUNICATION_SINK && com != KSPIN_COMMUNICATION_BOTH) - { - printf("Unknown pin communication value"); - assert(0); - } - - m_Pins.push_back(new CKsMidiPin(this, iPin)); - } - - } + for (ULONG iPin = 0; iPin < numPins; ++iPin) + { + { + KSPIN_COMMUNICATION com = GetPinProperty(iPin, KSPROPERTY_PIN_COMMUNICATION); + if (com != KSPIN_COMMUNICATION_SINK && com != KSPIN_COMMUNICATION_BOTH) + { + printf("Unknown pin communication value"); + assert(0); + } - m_RenderPins.clear(); - m_CapturePins.clear(); + m_Pins.push_back(new CKsMidiPin(this, iPin)); + } + } - for (size_t i = 0; i < m_Pins.size(); ++i) { - CKsPin* const pPin = m_Pins[i]; + m_RenderPins.clear(); + m_CapturePins.clear(); - if (pPin->IsSink()) { - if (pPin->GetDataFlow() == KSPIN_DATAFLOW_IN) - m_RenderPins.push_back(pPin); - else - m_CapturePins.push_back(pPin); - } - } + for (size_t i = 0; i < m_Pins.size(); ++i) + { + CKsPin *const pPin = m_Pins[i]; - if (m_RenderPins.empty() && m_CapturePins.empty()) - { - printf("No valid pins found on the filter."); - assert(0); + if (pPin->IsSink()) + { + if (pPin->GetDataFlow() == KSPIN_DATAFLOW_IN) + m_RenderPins.push_back(pPin); + else + m_CapturePins.push_back(pPin); + } + } - } + if (m_RenderPins.empty() && m_CapturePins.empty()) + { + printf("No valid pins found on the filter."); + assert(0); + } } -CKsMidiRenFilter::CKsMidiRenFilter(tstring const& sPath, std::string const& sFriendlyName) : - CKsMidiFilter(sPath, sFriendlyName) +CKsMidiRenFilter::CKsMidiRenFilter(tstring const &sPath, std::string const &sFriendlyName) : CKsMidiFilter(sPath, sFriendlyName) { } -CKsMidiPin* CKsMidiRenFilter::CreateRenderPin() +CKsMidiPin *CKsMidiRenFilter::CreateRenderPin() { - if (m_RenderPins.empty()) - { - printf("Could not find a MIDI render pin"); - assert(0); - } + if (m_RenderPins.empty()) + { + printf("Could not find a MIDI render pin"); + assert(0); + } - CKsMidiPin* pPin = (CKsMidiPin*)m_RenderPins[0]; - pPin->Instantiate(); - return pPin; + CKsMidiPin *pPin = (CKsMidiPin *)m_RenderPins[0]; + pPin->Instantiate(); + return pPin; } -CKsMidiCapFilter::CKsMidiCapFilter(tstring const& sPath, std::string const& sFriendlyName) : - CKsMidiFilter(sPath, sFriendlyName) +CKsMidiCapFilter::CKsMidiCapFilter(tstring const &sPath, std::string const &sFriendlyName) : CKsMidiFilter(sPath, sFriendlyName) { } -CKsMidiPin* CKsMidiCapFilter::CreateCapturePin() +CKsMidiPin *CKsMidiCapFilter::CreateCapturePin() { - if (m_CapturePins.empty()) - { - printf("Could not find a MIDI capture pin"); - assert(0); - } - CKsMidiPin* pPin = (CKsMidiPin*)m_CapturePins[0]; - pPin->Instantiate(); - return pPin; + if (m_CapturePins.empty()) + { + printf("Could not find a MIDI capture pin"); + assert(0); + } + CKsMidiPin *pPin = (CKsMidiPin *)m_CapturePins[0]; + pPin->Instantiate(); + return pPin; } -CKsMidiPin::CKsMidiPin(CKsFilter* pFilter, ULONG nId) : - CKsPin(pFilter, nId) +CKsMidiPin::CKsMidiPin(CKsFilter *pFilter, ULONG nId) : CKsPin(pFilter, nId) { - DWORD const cbPinCreateSize = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT); - m_pKsPinConnect = (PKSPIN_CONNECT) new BYTE[cbPinCreateSize]; + DWORD const cbPinCreateSize = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT); + m_pKsPinConnect = (PKSPIN_CONNECT) new BYTE[cbPinCreateSize]; - m_pKsPinConnect->Interface.Set = KSINTERFACESETID_Standard; - m_pKsPinConnect->Interface.Id = KSINTERFACE_STANDARD_STREAMING; - m_pKsPinConnect->Interface.Flags = 0; - m_pKsPinConnect->Medium.Set = KSMEDIUMSETID_Standard; - m_pKsPinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE; - m_pKsPinConnect->Medium.Flags = 0; - m_pKsPinConnect->PinId = nId; - m_pKsPinConnect->PinToHandle = NULL; - m_pKsPinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; - m_pKsPinConnect->Priority.PrioritySubClass = 1; + m_pKsPinConnect->Interface.Set = KSINTERFACESETID_Standard; + m_pKsPinConnect->Interface.Id = KSINTERFACE_STANDARD_STREAMING; + m_pKsPinConnect->Interface.Flags = 0; + m_pKsPinConnect->Medium.Set = KSMEDIUMSETID_Standard; + m_pKsPinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE; + m_pKsPinConnect->Medium.Flags = 0; + m_pKsPinConnect->PinId = nId; + m_pKsPinConnect->PinToHandle = NULL; + m_pKsPinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL; + m_pKsPinConnect->Priority.PrioritySubClass = 1; - // point m_pDataFormat to just after the pConnect struct - KSDATAFORMAT* m_pDataFormat = (KSDATAFORMAT*)(m_pKsPinConnect + 1); - m_pDataFormat->FormatSize = sizeof(KSDATAFORMAT); - m_pDataFormat->Flags = 0; - m_pDataFormat->SampleSize = 0; - m_pDataFormat->Reserved = 0; - m_pDataFormat->MajorFormat = GUID(KSDATAFORMAT_TYPE_MUSIC); - m_pDataFormat->SubFormat = GUID(KSDATAFORMAT_SUBTYPE_MIDI); - m_pDataFormat->Specifier = GUID(KSDATAFORMAT_SPECIFIER_NONE); + // point m_pDataFormat to just after the pConnect struct + KSDATAFORMAT *m_pDataFormat = (KSDATAFORMAT *)(m_pKsPinConnect + 1); + m_pDataFormat->FormatSize = sizeof(KSDATAFORMAT); + m_pDataFormat->Flags = 0; + m_pDataFormat->SampleSize = 0; + m_pDataFormat->Reserved = 0; + m_pDataFormat->MajorFormat = GUID(KSDATAFORMAT_TYPE_MUSIC); + m_pDataFormat->SubFormat = GUID(KSDATAFORMAT_SUBTYPE_MIDI); + m_pDataFormat->Specifier = GUID(KSDATAFORMAT_SPECIFIER_NONE); - bool hasStdStreamingInterface = false; - bool hasStdStreamingMedium = false; + bool hasStdStreamingInterface = false; + bool hasStdStreamingMedium = false; - for ( ULONG i = 0; i < m_cInterfaces; i++ ) { - if (m_pInterfaces[i].Set == KSINTERFACESETID_Standard - && m_pInterfaces[i].Id == KSINTERFACE_STANDARD_STREAMING) - hasStdStreamingInterface = true; - } + for (ULONG i = 0; i < m_cInterfaces; i++) + { + if (m_pInterfaces[i].Set == KSINTERFACESETID_Standard && m_pInterfaces[i].Id == KSINTERFACE_STANDARD_STREAMING) + hasStdStreamingInterface = true; + } - for (ULONG i = 0; i < m_cMediums; i++) { - if (m_pMediums[i].Set == KSMEDIUMSETID_Standard - && m_pMediums[i].Id == KSMEDIUM_STANDARD_DEVIO) - hasStdStreamingMedium = true; - } + for (ULONG i = 0; i < m_cMediums; i++) + { + if (m_pMediums[i].Set == KSMEDIUMSETID_Standard && m_pMediums[i].Id == KSMEDIUM_STANDARD_DEVIO) + hasStdStreamingMedium = true; + } - if (!hasStdStreamingInterface) // No standard streaming interfaces on the pin - { - printf("CKsMidiPin::CKsMidiPin: no standard streaming interface"); - assert(0); - } + if (!hasStdStreamingInterface) // No standard streaming interfaces on the pin + { + printf("CKsMidiPin::CKsMidiPin: no standard streaming interface"); + assert(0); + } - if (!hasStdStreamingMedium) // No standard streaming mediums on the pin - { - printf("CKsMidiPin::CKsMidiPin: no standard streaming medium") - assert(0); - }; + if (!hasStdStreamingMedium) // No standard streaming mediums on the pin + { + printf("CKsMidiPin::CKsMidiPin: no standard streaming medium") + assert(0); + }; - bool hasMidiDataRange = false; + bool hasMidiDataRange = false; - BYTE const* pDataRangePtr = reinterpret_cast(m_pDataRanges); + BYTE const *pDataRangePtr = reinterpret_cast(m_pDataRanges); - for (ULONG i = 0; i < m_cDataRanges; ++i) { - KSDATARANGE const* pDataRange = reinterpret_cast(pDataRangePtr); + for (ULONG i = 0; i < m_cDataRanges; ++i) + { + KSDATARANGE const *pDataRange = reinterpret_cast(pDataRangePtr); - if (pDataRange->SubFormat == KSDATAFORMAT_SUBTYPE_MIDI) { - hasMidiDataRange = true; - break; - } + if (pDataRange->SubFormat == KSDATAFORMAT_SUBTYPE_MIDI) + { + hasMidiDataRange = true; + break; + } - pDataRangePtr += pDataRange->FormatSize; - } + pDataRangePtr += pDataRange->FormatSize; + } - if (!hasMidiDataRange) // No MIDI dataranges on the pin - { - printf("CKsMidiPin::CKsMidiPin: no MIDI datarange"); - assert(0); - } + if (!hasMidiDataRange) // No MIDI dataranges on the pin + { + printf("CKsMidiPin::CKsMidiPin: no MIDI datarange"); + assert(0); + } } - struct WindowsKsData { - WindowsKsData() : m_pPin(NULL), m_Buffer(1024), m_hInputThread(NULL) - { - memset(&overlapped, 0, sizeof(OVERLAPPED)); - m_hExitEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); - overlapped.hEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); - m_hInputThread = NULL; - } + WindowsKsData() : m_pPin(NULL), m_Buffer(1024), m_hInputThread(NULL) + { + memset(&overlapped, 0, sizeof(OVERLAPPED)); + m_hExitEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); + overlapped.hEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL); + m_hInputThread = NULL; + } - ~WindowsKsData() - { - ::CloseHandle(overlapped.hEvent); - ::CloseHandle(m_hExitEvent); - } + ~WindowsKsData() + { + ::CloseHandle(overlapped.hEvent); + ::CloseHandle(m_hExitEvent); + } - OVERLAPPED overlapped; - CKsPin* m_pPin; - std::vector m_Buffer; - std::auto_ptr > m_pCaptureEnum; - std::auto_ptr > m_pRenderEnum; - HANDLE m_hInputThread; - HANDLE m_hExitEvent; + OVERLAPPED overlapped; + CKsPin *m_pPin; + std::vector m_Buffer; + std::auto_ptr > m_pCaptureEnum; + std::auto_ptr > m_pRenderEnum; + HANDLE m_hInputThread; + HANDLE m_hExitEvent; }; // *********************************************************************// @@ -3106,179 +3302,191 @@ struct WindowsKsData // Class Definitions: MidiInWinKS // *********************************************************************// -DWORD WINAPI midiKsInputThread(VOID* pUser) +DWORD WINAPI midiKsInputThread(VOID *pUser) { - MidiInApi::RtMidiInData* data = static_cast(pUser); - WindowsKsData* apiData = static_cast(data->apiData); + MidiInApi::RtMidiInData *data = static_cast(pUser); + WindowsKsData *apiData = static_cast(data->apiData); - HANDLE hEvents[] = { apiData->overlapped.hEvent, apiData->m_hExitEvent }; + HANDLE hEvents[] = {apiData->overlapped.hEvent, apiData->m_hExitEvent}; - while ( true ) { - KSSTREAM_HEADER packet; - memset(&packet, 0, sizeof packet); - packet.Size = sizeof(KSSTREAM_HEADER); - packet.PresentationTime.Time = 0; - packet.PresentationTime.Numerator = 1; - packet.PresentationTime.Denominator = 1; - packet.Data = &apiData->m_Buffer[0]; - packet.DataUsed = 0; - packet.FrameExtent = apiData->m_Buffer.size(); - apiData->m_pPin->ReadData(&packet, &apiData->overlapped); + while (true) + { + KSSTREAM_HEADER packet; + memset(&packet, 0, sizeof packet); + packet.Size = sizeof(KSSTREAM_HEADER); + packet.PresentationTime.Time = 0; + packet.PresentationTime.Numerator = 1; + packet.PresentationTime.Denominator = 1; + packet.Data = &apiData->m_Buffer[0]; + packet.DataUsed = 0; + packet.FrameExtent = apiData->m_Buffer.size(); + apiData->m_pPin->ReadData(&packet, &apiData->overlapped); - DWORD dwRet = ::WaitForMultipleObjects(2, hEvents, FALSE, INFINITE); + DWORD dwRet = ::WaitForMultipleObjects(2, hEvents, FALSE, INFINITE); - if ( dwRet == WAIT_OBJECT_0 ) { - // parse packet - unsigned char* pData = (unsigned char*)packet.Data; - unsigned int iOffset = 0; + if (dwRet == WAIT_OBJECT_0) + { + // parse packet + unsigned char *pData = (unsigned char *)packet.Data; + unsigned int iOffset = 0; - while ( iOffset < packet.DataUsed ) { - KSMUSICFORMAT* pMusic = (KSMUSICFORMAT*)&pData[iOffset]; - iOffset += sizeof(KSMUSICFORMAT); + while (iOffset < packet.DataUsed) + { + KSMUSICFORMAT *pMusic = (KSMUSICFORMAT *)&pData[iOffset]; + iOffset += sizeof(KSMUSICFORMAT); - MidiInApi::MidiMessage message; - message.timeStamp = 0; - for(size_t i=0;i < pMusic->ByteCount;++i) - message.bytes.push_back(pData[iOffset+i]); + MidiInApi::MidiMessage message; + message.timeStamp = 0; + for (size_t i = 0; i < pMusic->ByteCount; ++i) + message.bytes.push_back(pData[iOffset + i]); - if ( data->usingCallback ) { - RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback)data->userCallback; - callback(message.timeStamp, &message.bytes, data->userData); - } - else { - // As long as we haven't reached our queue size limit, push the message. - if ( data->queue.size < data->queue.ringSize ) { - data->queue.ring[data->queue.back++] = message; - if(data->queue.back == data->queue.ringSize) - data->queue.back = 0; - data->queue.size++; - } - else - std::cerr << "\nRtMidiIn: message queue limit reached!!\n\n"; - } + if (data->usingCallback) + { + RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback)data->userCallback; + callback(message.timeStamp, &message.bytes, data->userData); + } + else + { + // As long as we haven't reached our queue size limit, push the message. + if (data->queue.size < data->queue.ringSize) + { + data->queue.ring[data->queue.back++] = message; + if (data->queue.back == data->queue.ringSize) + data->queue.back = 0; + data->queue.size++; + } + else + std::cerr << "\nRtMidiIn: message queue limit reached!!\n\n"; + } - iOffset += pMusic->ByteCount; + iOffset += pMusic->ByteCount; - // re-align on 32 bits - if ( iOffset % 4 != 0 ) - iOffset += (4 - iOffset % 4); - } - } - else - break; - } - return 0; + // re-align on 32 bits + if (iOffset % 4 != 0) + iOffset += (4 - iOffset % 4); + } + } + else + break; + } + return 0; } -MidiInWinKS :: MidiInWinKS( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) +MidiInWinKS ::MidiInWinKS(const std::string clientName, unsigned int queueSizeLimit) : MidiInApi(queueSizeLimit) { - initialize( clientName ); + initialize(clientName); } -void MidiInWinKS :: initialize( const std::string& clientName ) +void MidiInWinKS ::initialize(const std::string &clientName) { - WindowsKsData* data = new WindowsKsData; - apiData_ = (void*)data; - inputData_.apiData = data; + WindowsKsData *data = new WindowsKsData; + apiData_ = (void *)data; + inputData_.apiData = data; - GUID const aguidEnumCats[] = - { - { STATIC_KSCATEGORY_AUDIO }, { STATIC_KSCATEGORY_CAPTURE } - }; - data->m_pCaptureEnum.reset(new CKsEnumFilters ); - data->m_pCaptureEnum->EnumFilters(aguidEnumCats, 2); + GUID const aguidEnumCats[] = + { + {STATIC_KSCATEGORY_AUDIO}, {STATIC_KSCATEGORY_CAPTURE}}; + data->m_pCaptureEnum.reset(new CKsEnumFilters); + data->m_pCaptureEnum->EnumFilters(aguidEnumCats, 2); } -MidiInWinKS :: ~MidiInWinKS() +MidiInWinKS ::~MidiInWinKS() { - WindowsKsData* data = static_cast(apiData_); - { - if ( data->m_pPin ) - closePort(); - } - - delete data; + WindowsKsData *data = static_cast(apiData_); + { + if (data->m_pPin) + closePort(); + } + + delete data; } -void MidiInWinKS :: openPort( unsigned int portNumber, const std::string portName ) +void MidiInWinKS ::openPort(unsigned int portNumber, const std::string portName) { - WindowsKsData* data = static_cast(apiData_); + WindowsKsData *data = static_cast(apiData_); - if ( portNumber < 0 || portNumber >= data->m_pCaptureEnum->m_Filters.size() ) { - std::stringstream ost; - ost << "MidiInWinKS::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - RtMidi::error( RtError::WARNING, errorString_ ); - } + if (portNumber < 0 || portNumber >= data->m_pCaptureEnum->m_Filters.size()) + { + std::stringstream ost; + ost << "MidiInWinKS::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + RtMidi::error(RtError::WARNING, errorString_); + } - CKsMidiCapFilter* pFilter = data->m_pCaptureEnum->m_Filters[portNumber]; - data->m_pPin = pFilter->CreateCapturePin(); + CKsMidiCapFilter *pFilter = data->m_pCaptureEnum->m_Filters[portNumber]; + data->m_pPin = pFilter->CreateCapturePin(); - if ( data->m_pPin == NULL ) { - std::stringstream ost; - ost << "MidiInWinKS::openPort: KS error opening port (could not create pin)"; - errorString_ = ost.str(); - RtMidi::error( RtError::WARNING, errorString_ ); - } + if (data->m_pPin == NULL) + { + std::stringstream ost; + ost << "MidiInWinKS::openPort: KS error opening port (could not create pin)"; + errorString_ = ost.str(); + RtMidi::error(RtError::WARNING, errorString_); + } - data->m_pPin->SetState(KSSTATE_RUN); + data->m_pPin->SetState(KSSTATE_RUN); - DWORD threadId; - data->m_hInputThread = ::CreateThread(NULL, 0, &midiKsInputThread, &inputData_, 0, &threadId); - if ( data->m_hInputThread == NULL ) { - std::stringstream ost; - ost << "MidiInWinKS::initialize: Could not create input thread : Windows error " << GetLastError() << std::endl;; - errorString_ = ost.str(); - RtMidi::error( RtError::WARNING, errorString_ ); - } + DWORD threadId; + data->m_hInputThread = ::CreateThread(NULL, 0, &midiKsInputThread, &inputData_, 0, &threadId); + if (data->m_hInputThread == NULL) + { + std::stringstream ost; + ost << "MidiInWinKS::initialize: Could not create input thread : Windows error " << GetLastError() << std::endl; + ; + errorString_ = ost.str(); + RtMidi::error(RtError::WARNING, errorString_); + } - connected_ = true; + connected_ = true; } -void MidiInWinKS :: openVirtualPort( const std::string portName ) +void MidiInWinKS ::openVirtualPort(const std::string portName) { - // This function cannot be implemented for the Windows KS MIDI API. - errorString_ = "MidiInWinKS::openVirtualPort: cannot be implemented in Windows KS MIDI API!"; - RtMidi::error( RtError::WARNING, errorString_ ); + // This function cannot be implemented for the Windows KS MIDI API. + errorString_ = "MidiInWinKS::openVirtualPort: cannot be implemented in Windows KS MIDI API!"; + RtMidi::error(RtError::WARNING, errorString_); } -unsigned int MidiInWinKS :: getPortCount() +unsigned int MidiInWinKS ::getPortCount() { - WindowsKsData* data = static_cast(apiData_); - return (unsigned int)data->m_pCaptureEnum->m_Filters.size(); + WindowsKsData *data = static_cast(apiData_); + return (unsigned int)data->m_pCaptureEnum->m_Filters.size(); } -std::string MidiInWinKS :: getPortName(unsigned int portNumber) +std::string MidiInWinKS ::getPortName(unsigned int portNumber) { - WindowsKsData* data = static_cast(apiData_); + WindowsKsData *data = static_cast(apiData_); - if(portNumber < 0 || portNumber >= data->m_pCaptureEnum->m_Filters.size()) { - std::stringstream ost; - ost << "MidiInWinKS::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - RtMidi::error( RtError::WARNING, errorString_ ); - } + if (portNumber < 0 || portNumber >= data->m_pCaptureEnum->m_Filters.size()) + { + std::stringstream ost; + ost << "MidiInWinKS::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + RtMidi::error(RtError::WARNING, errorString_); + } - CKsMidiCapFilter* pFilter = data->m_pCaptureEnum->m_Filters[portNumber]; - return pFilter->GetFriendlyName(); + CKsMidiCapFilter *pFilter = data->m_pCaptureEnum->m_Filters[portNumber]; + return pFilter->GetFriendlyName(); } -void MidiInWinKS :: closePort() +void MidiInWinKS ::closePort() { - WindowsKsData* data = static_cast(apiData_); - connected_ = false; + WindowsKsData *data = static_cast(apiData_); + connected_ = false; - if(data->m_hInputThread) { - ::SignalObjectAndWait(data->m_hExitEvent, data->m_hInputThread, INFINITE, FALSE); - ::CloseHandle(data->m_hInputThread); - } + if (data->m_hInputThread) + { + ::SignalObjectAndWait(data->m_hExitEvent, data->m_hInputThread, INFINITE, FALSE); + ::CloseHandle(data->m_hInputThread); + } - if(data->m_pPin) { - data->m_pPin->SetState(KSSTATE_PAUSE); - data->m_pPin->SetState(KSSTATE_STOP); - data->m_pPin->ClosePin(); - data->m_pPin = NULL; - } + if (data->m_pPin) + { + data->m_pPin->SetState(KSSTATE_PAUSE); + data->m_pPin->SetState(KSSTATE_STOP); + data->m_pPin->ClosePin(); + data->m_pPin = NULL; + } } // *********************************************************************// @@ -3286,145 +3494,150 @@ void MidiInWinKS :: closePort() // Class Definitions: MidiOutWinKS // *********************************************************************// -MidiOutWinKS :: MidiOutWinKS( const std::string clientName ) : MidiOutApi() +MidiOutWinKS ::MidiOutWinKS(const std::string clientName) : MidiOutApi() { - initialize( clientName ); + initialize(clientName); } -void MidiOutWinKS :: initialize( const std::string& clientName ) +void MidiOutWinKS ::initialize(const std::string &clientName) { - WindowsKsData* data = new WindowsKsData; + WindowsKsData *data = new WindowsKsData; - data->m_pPin = NULL; - data->m_pRenderEnum.reset(new CKsEnumFilters ); - GUID const aguidEnumCats[] = - { - { STATIC_KSCATEGORY_AUDIO }, { STATIC_KSCATEGORY_RENDER } - }; - data->m_pRenderEnum->EnumFilters(aguidEnumCats, 2); + data->m_pPin = NULL; + data->m_pRenderEnum.reset(new CKsEnumFilters); + GUID const aguidEnumCats[] = + { + {STATIC_KSCATEGORY_AUDIO}, {STATIC_KSCATEGORY_RENDER}}; + data->m_pRenderEnum->EnumFilters(aguidEnumCats, 2); - apiData_ = (void*)data; + apiData_ = (void *)data; } -MidiOutWinKS :: ~MidiOutWinKS() +MidiOutWinKS ::~MidiOutWinKS() { - // Close a connection if it exists. - closePort(); + // Close a connection if it exists. + closePort(); - // Cleanup. - WindowsKsData* data = static_cast(apiData_); - delete data; + // Cleanup. + WindowsKsData *data = static_cast(apiData_); + delete data; } -void MidiOutWinKS :: openPort( unsigned int portNumber, const std::string portName ) +void MidiOutWinKS ::openPort(unsigned int portNumber, const std::string portName) { - WindowsKsData* data = static_cast(apiData_); + WindowsKsData *data = static_cast(apiData_); - if(portNumber < 0 || portNumber >= data->m_pRenderEnum->m_Filters.size()) { - std::stringstream ost; - ost << "MidiOutWinKS::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - RtMidi::error( RtError::WARNING, errorString_ ); - } + if (portNumber < 0 || portNumber >= data->m_pRenderEnum->m_Filters.size()) + { + std::stringstream ost; + ost << "MidiOutWinKS::openPort: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + RtMidi::error(RtError::WARNING, errorString_); + } - CKsMidiRenFilter* pFilter = data->m_pRenderEnum->m_Filters[portNumber]; - data->m_pPin = pFilter->CreateRenderPin(); + CKsMidiRenFilter *pFilter = data->m_pRenderEnum->m_Filters[portNumber]; + data->m_pPin = pFilter->CreateRenderPin(); - if(data->m_pPin == NULL) { - std::stringstream ost; - ost << "MidiOutWinKS::openPort: KS error opening port (could not create pin)"; - errorString_ = ost.str(); - RtMidi::error( RtError::WARNING, errorString_ ); - } + if (data->m_pPin == NULL) + { + std::stringstream ost; + ost << "MidiOutWinKS::openPort: KS error opening port (could not create pin)"; + errorString_ = ost.str(); + RtMidi::error(RtError::WARNING, errorString_); + } - data->m_pPin->SetState(KSSTATE_RUN); - connected_ = true; + data->m_pPin->SetState(KSSTATE_RUN); + connected_ = true; } -void MidiOutWinKS :: openVirtualPort( const std::string portName ) +void MidiOutWinKS ::openVirtualPort(const std::string portName) { - // This function cannot be implemented for the Windows KS MIDI API. - errorString_ = "MidiOutWinKS::openVirtualPort: cannot be implemented in Windows KS MIDI API!"; - RtMidi::error( RtError::WARNING, errorString_ ); + // This function cannot be implemented for the Windows KS MIDI API. + errorString_ = "MidiOutWinKS::openVirtualPort: cannot be implemented in Windows KS MIDI API!"; + RtMidi::error(RtError::WARNING, errorString_); } -unsigned int MidiOutWinKS :: getPortCount() +unsigned int MidiOutWinKS ::getPortCount() { - WindowsKsData* data = static_cast(apiData_); + WindowsKsData *data = static_cast(apiData_); - return (unsigned int)data->m_pRenderEnum->m_Filters.size(); + return (unsigned int)data->m_pRenderEnum->m_Filters.size(); } -std::string MidiOutWinKS :: getPortName( unsigned int portNumber ) +std::string MidiOutWinKS ::getPortName(unsigned int portNumber) { - WindowsKsData* data = static_cast(apiData_); + WindowsKsData *data = static_cast(apiData_); - if ( portNumber < 0 || portNumber >= data->m_pRenderEnum->m_Filters.size() ) { - std::stringstream ost; - ost << "MidiOutWinKS::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - RtMidi::error( RtError::WARNING, errorString_ ); - } + if (portNumber < 0 || portNumber >= data->m_pRenderEnum->m_Filters.size()) + { + std::stringstream ost; + ost << "MidiOutWinKS::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + RtMidi::error(RtError::WARNING, errorString_); + } - CKsMidiRenFilter* pFilter = data->m_pRenderEnum->m_Filters[portNumber]; - return pFilter->GetFriendlyName(); + CKsMidiRenFilter *pFilter = data->m_pRenderEnum->m_Filters[portNumber]; + return pFilter->GetFriendlyName(); } -void MidiOutWinKS :: closePort() +void MidiOutWinKS ::closePort() { - WindowsKsData* data = static_cast(apiData_); - connected_ = false; + WindowsKsData *data = static_cast(apiData_); + connected_ = false; - if ( data->m_pPin ) { - data->m_pPin->SetState(KSSTATE_PAUSE); - data->m_pPin->SetState(KSSTATE_STOP); - data->m_pPin->ClosePin(); - data->m_pPin = NULL; - } + if (data->m_pPin) + { + data->m_pPin->SetState(KSSTATE_PAUSE); + data->m_pPin->SetState(KSSTATE_STOP); + data->m_pPin->ClosePin(); + data->m_pPin = NULL; + } } -void MidiOutWinKS :: sendMessage(std::vector* pMessage) +void MidiOutWinKS ::sendMessage(std::vector *pMessage) { - std::vector const& msg = *pMessage; - WindowsKsData* data = static_cast(apiData_); - size_t iNumMidiBytes = msg.size(); - size_t pos = 0; + std::vector const &msg = *pMessage; + WindowsKsData *data = static_cast(apiData_); + size_t iNumMidiBytes = msg.size(); + size_t pos = 0; - // write header - KSMUSICFORMAT* pKsMusicFormat = reinterpret_cast(&data->m_Buffer[pos]); - pKsMusicFormat->TimeDeltaMs = 0; - pKsMusicFormat->ByteCount = iNumMidiBytes; - pos += sizeof(KSMUSICFORMAT); + // write header + KSMUSICFORMAT *pKsMusicFormat = reinterpret_cast(&data->m_Buffer[pos]); + pKsMusicFormat->TimeDeltaMs = 0; + pKsMusicFormat->ByteCount = iNumMidiBytes; + pos += sizeof(KSMUSICFORMAT); - // write MIDI bytes - if ( pos + iNumMidiBytes > data->m_Buffer.size() ) { - std::stringstream ost; - ost << "KsMidiInput::Write: MIDI buffer too small. Required " << pos + iNumMidiBytes << " bytes, only has " << data->m_Buffer.size(); - errorString_ = ost.str(); - RtMidi::error( RtError::WARNING, errorString_ ); - } + // write MIDI bytes + if (pos + iNumMidiBytes > data->m_Buffer.size()) + { + std::stringstream ost; + ost << "KsMidiInput::Write: MIDI buffer too small. Required " << pos + iNumMidiBytes << " bytes, only has " << data->m_Buffer.size(); + errorString_ = ost.str(); + RtMidi::error(RtError::WARNING, errorString_); + } - if ( data->m_pPin == NULL ) { - std::stringstream ost; - ost << "MidiOutWinKS::sendMessage: port is not open"; - errorString_ = ost.str(); - RtMidi::error( RtError::WARNING, errorString_ ); - } + if (data->m_pPin == NULL) + { + std::stringstream ost; + ost << "MidiOutWinKS::sendMessage: port is not open"; + errorString_ = ost.str(); + RtMidi::error(RtError::WARNING, errorString_); + } - memcpy(&data->m_Buffer[pos], &msg[0], iNumMidiBytes); - pos += iNumMidiBytes; + memcpy(&data->m_Buffer[pos], &msg[0], iNumMidiBytes); + pos += iNumMidiBytes; - KSSTREAM_HEADER packet; - memset(&packet, 0, sizeof packet); - packet.Size = sizeof(packet); - packet.PresentationTime.Time = 0; - packet.PresentationTime.Numerator = 1; - packet.PresentationTime.Denominator = 1; - packet.Data = const_cast(&data->m_Buffer[0]); - packet.DataUsed = ((pos+3)/4)*4; - packet.FrameExtent = data->m_Buffer.size(); + KSSTREAM_HEADER packet; + memset(&packet, 0, sizeof packet); + packet.Size = sizeof(packet); + packet.PresentationTime.Time = 0; + packet.PresentationTime.Numerator = 1; + packet.PresentationTime.Denominator = 1; + packet.Data = const_cast(&data->m_Buffer[0]); + packet.DataUsed = ((pos + 3) / 4) * 4; + packet.FrameExtent = data->m_Buffer.size(); - data->m_pPin->WriteData(&packet, NULL); + data->m_pPin->WriteData(&packet, NULL); } #endif // __WINDOWS_KS__ @@ -3444,193 +3657,205 @@ void MidiOutWinKS :: sendMessage(std::vector* pMessage) #include #include -#define JACK_RINGBUFFER_SIZE 16384 // Default size for ringbuffer +#define JACK_RINGBUFFER_SIZE 16384 // Default size for ringbuffer -struct JackMidiData { - jack_client_t *client; - jack_port_t *port; - jack_ringbuffer_t *buffSize; - jack_ringbuffer_t *buffMessage; - jack_time_t lastTime; - MidiInApi :: RtMidiInData *rtMidiIn; - }; +struct JackMidiData +{ + jack_client_t *client; + jack_port_t *port; + jack_ringbuffer_t *buffSize; + jack_ringbuffer_t *buffMessage; + jack_time_t lastTime; + MidiInApi ::RtMidiInData *rtMidiIn; +}; //*********************************************************************// // API: JACK // Class Definitions: MidiInJack //*********************************************************************// -int jackProcessIn( jack_nframes_t nframes, void *arg ) +int jackProcessIn(jack_nframes_t nframes, void *arg) { - JackMidiData *jData = (JackMidiData *) arg; - MidiInApi :: RtMidiInData *rtData = jData->rtMidiIn; - jack_midi_event_t event; - jack_time_t long long time; + JackMidiData *jData = (JackMidiData *)arg; + MidiInApi ::RtMidiInData *rtData = jData->rtMidiIn; + jack_midi_event_t event; + jack_time_t long long time; - // Is port created? - if ( jData->port == NULL ) return 0; - void *buff = jack_port_get_buffer( jData->port, nframes ); + // Is port created? + if (jData->port == NULL) return 0; + void *buff = jack_port_get_buffer(jData->port, nframes); - // We have midi events in buffer - int evCount = jack_midi_get_event_count( buff ); - if ( evCount > 0 ) { - MidiInApi::MidiMessage message; - message.bytes.clear(); + // We have midi events in buffer + int evCount = jack_midi_get_event_count(buff); + if (evCount > 0) + { + MidiInApi::MidiMessage message; + message.bytes.clear(); - jack_midi_event_get( &event, buff, 0 ); + jack_midi_event_get(&event, buff, 0); - for (unsigned int i = 0; i < event.size; i++ ) - message.bytes.push_back( event.buffer[i] ); + for (unsigned int i = 0; i < event.size; i++) + message.bytes.push_back(event.buffer[i]); - // Compute the delta time. - time = jack_get_time(); - if ( rtData->firstMessage == true ) - rtData->firstMessage = false; - else - message.timeStamp = ( time - jData->lastTime ) * 0.000001; + // Compute the delta time. + time = jack_get_time(); + if (rtData->firstMessage == true) + rtData->firstMessage = false; + else + message.timeStamp = (time - jData->lastTime) * 0.000001; - jData->lastTime = time; + jData->lastTime = time; - if ( !rtData->continueSysex ) { - if ( rtData->usingCallback ) { - RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback) rtData->userCallback; - callback( message.timeStamp, &message.bytes, rtData->userData ); - } - else { - // As long as we haven't reached our queue size limit, push the message. - if ( rtData->queue.size < rtData->queue.ringSize ) { - rtData->queue.ring[rtData->queue.back++] = message; - if ( rtData->queue.back == rtData->queue.ringSize ) - rtData->queue.back = 0; - rtData->queue.size++; - } - else - std::cerr << "\nMidiInJack: message queue limit reached!!\n\n"; - } - } - } + if (!rtData->continueSysex) + { + if (rtData->usingCallback) + { + RtMidiIn::RtMidiCallback callback = (RtMidiIn::RtMidiCallback)rtData->userCallback; + callback(message.timeStamp, &message.bytes, rtData->userData); + } + else + { + // As long as we haven't reached our queue size limit, push the message. + if (rtData->queue.size < rtData->queue.ringSize) + { + rtData->queue.ring[rtData->queue.back++] = message; + if (rtData->queue.back == rtData->queue.ringSize) + rtData->queue.back = 0; + rtData->queue.size++; + } + else + std::cerr << "\nMidiInJack: message queue limit reached!!\n\n"; + } + } + } - return 0; + return 0; } -MidiInJack :: MidiInJack( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) +MidiInJack ::MidiInJack(const std::string clientName, unsigned int queueSizeLimit) : MidiInApi(queueSizeLimit) { - initialize( clientName ); + initialize(clientName); } -void MidiInJack :: initialize( const std::string& clientName ) +void MidiInJack ::initialize(const std::string &clientName) { - JackMidiData *data = new JackMidiData; - apiData_ = (void *) data; + JackMidiData *data = new JackMidiData; + apiData_ = (void *)data; - // Initialize JACK client - if (( data->client = jack_client_open( clientName.c_str(), JackNullOption, NULL )) == 0) { - errorString_ = "MidiInJack::initialize: JACK server not running?"; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - return; - } + // Initialize JACK client + if ((data->client = jack_client_open(clientName.c_str(), JackNullOption, NULL)) == 0) + { + errorString_ = "MidiInJack::initialize: JACK server not running?"; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + return; + } - data->rtMidiIn = &inputData_; - data->port = NULL; + data->rtMidiIn = &inputData_; + data->port = NULL; - jack_set_process_callback( data->client, jackProcessIn, data ); - jack_activate( data->client ); + jack_set_process_callback(data->client, jackProcessIn, data); + jack_activate(data->client); } -MidiInJack :: ~MidiInJack() +MidiInJack ::~MidiInJack() { - JackMidiData *data = static_cast (apiData_); - closePort(); + JackMidiData *data = static_cast(apiData_); + closePort(); - jack_client_close( data->client ); + jack_client_close(data->client); } -void MidiInJack :: openPort( unsigned int portNumber, const std::string portName ) +void MidiInJack ::openPort(unsigned int portNumber, const std::string portName) { - JackMidiData *data = static_cast (apiData_); + JackMidiData *data = static_cast(apiData_); - // Creating new port - if ( data->port == NULL) - data->port = jack_port_register( data->client, portName.c_str(), - JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0 ); + // Creating new port + if (data->port == NULL) + data->port = jack_port_register(data->client, portName.c_str(), + JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); - if ( data->port == NULL) { - errorString_ = "MidiInJack::openVirtualPort: JACK error creating virtual port"; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + if (data->port == NULL) + { + errorString_ = "MidiInJack::openVirtualPort: JACK error creating virtual port"; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - // Connecting to the output - std::string name = getPortName( portNumber ); - jack_connect( data->client, name.c_str(), jack_port_name( data->port ) ); + // Connecting to the output + std::string name = getPortName(portNumber); + jack_connect(data->client, name.c_str(), jack_port_name(data->port)); } -void MidiInJack :: openVirtualPort( const std::string portName ) +void MidiInJack ::openVirtualPort(const std::string portName) { - JackMidiData *data = static_cast (apiData_); + JackMidiData *data = static_cast(apiData_); - if ( data->port == NULL ) - data->port = jack_port_register( data->client, portName.c_str(), - JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0 ); + if (data->port == NULL) + data->port = jack_port_register(data->client, portName.c_str(), + JACK_DEFAULT_MIDI_TYPE, JackPortIsInput, 0); - if ( data->port == NULL ) { - errorString_ = "MidiInJack::openVirtualPort: JACK error creating virtual port"; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + if (data->port == NULL) + { + errorString_ = "MidiInJack::openVirtualPort: JACK error creating virtual port"; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } } -unsigned int MidiInJack :: getPortCount() +unsigned int MidiInJack ::getPortCount() { - int count = 0; - JackMidiData *data = static_cast (apiData_); + int count = 0; + JackMidiData *data = static_cast(apiData_); - // List of available ports - const char **ports = jack_get_ports( data->client, NULL, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput ); + // List of available ports + const char **ports = jack_get_ports(data->client, NULL, JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput); - if ( ports == NULL ) return 0; - while ( ports[count] != NULL ) - count++; + if (ports == NULL) return 0; + while (ports[count] != NULL) + count++; - free( ports ); + free(ports); - return count; + return count; } -std::string MidiInJack :: getPortName( unsigned int portNumber ) +std::string MidiInJack ::getPortName(unsigned int portNumber) { - JackMidiData *data = static_cast (apiData_); - std::ostringstream ost; - std::string retStr(""); + JackMidiData *data = static_cast(apiData_); + std::ostringstream ost; + std::string retStr(""); - // List of available ports - const char **ports = jack_get_ports( data->client, NULL, - JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput ); + // List of available ports + const char **ports = jack_get_ports(data->client, NULL, + JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput); - // Check port validity - if ( ports == NULL ) { - errorString_ = "MidiInJack::getPortName: no ports available!"; - RtMidi::error( RtError::WARNING, errorString_ ); - return retStr; - } + // Check port validity + if (ports == NULL) + { + errorString_ = "MidiInJack::getPortName: no ports available!"; + RtMidi::error(RtError::WARNING, errorString_); + return retStr; + } - if ( ports[portNumber] == NULL ) { - ost << "MidiInJack::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - RtMidi::error( RtError::WARNING, errorString_ ); - } - else retStr.assign( ports[portNumber] ); + if (ports[portNumber] == NULL) + { + ost << "MidiInJack::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + RtMidi::error(RtError::WARNING, errorString_); + } + else + retStr.assign(ports[portNumber]); - free( ports ); + free(ports); - return retStr; + return retStr; } -void MidiInJack :: closePort() +void MidiInJack ::closePort() { - JackMidiData *data = static_cast (apiData_); + JackMidiData *data = static_cast(apiData_); - if ( data->port == NULL ) return; - jack_port_unregister( data->client, data->port ); - data->port = NULL; + if (data->port == NULL) return; + jack_port_unregister(data->client, data->port); + data->port = NULL; } //*********************************************************************// @@ -3639,165 +3864,172 @@ void MidiInJack :: closePort() //*********************************************************************// // Jack process callback -int jackProcessOut( jack_nframes_t nframes, void *arg ) +int jackProcessOut(jack_nframes_t nframes, void *arg) { - JackMidiData *data = (JackMidiData *) arg; - jack_midi_data_t *midiData; - int space; + JackMidiData *data = (JackMidiData *)arg; + jack_midi_data_t *midiData; + int space; - // Is port created? - if ( data->port == NULL ) return 0; + // Is port created? + if (data->port == NULL) return 0; - void *buff = jack_port_get_buffer( data->port, nframes ); - jack_midi_clear_buffer( buff ); + void *buff = jack_port_get_buffer(data->port, nframes); + jack_midi_clear_buffer(buff); - while ( jack_ringbuffer_read_space( data->buffSize ) > 0 ) { - jack_ringbuffer_read( data->buffSize, (char *) &space, (size_t) sizeof(space) ); - midiData = jack_midi_event_reserve( buff, 0, space ); + while (jack_ringbuffer_read_space(data->buffSize) > 0) + { + jack_ringbuffer_read(data->buffSize, (char *)&space, (size_t)sizeof(space)); + midiData = jack_midi_event_reserve(buff, 0, space); - jack_ringbuffer_read( data->buffMessage, (char *) midiData, (size_t) space ); - } + jack_ringbuffer_read(data->buffMessage, (char *)midiData, (size_t)space); + } - return 0; + return 0; } -MidiOutJack :: MidiOutJack( const std::string clientName ) : MidiOutApi() +MidiOutJack ::MidiOutJack(const std::string clientName) : MidiOutApi() { - initialize( clientName ); + initialize(clientName); } -void MidiOutJack :: initialize( const std::string& clientName ) +void MidiOutJack ::initialize(const std::string &clientName) { - JackMidiData *data = new JackMidiData; + JackMidiData *data = new JackMidiData; - data->port = NULL; + data->port = NULL; - // Initialize JACK client - if (( data->client = jack_client_open( clientName.c_str(), JackNullOption, NULL )) == 0) { - errorString_ = "MidiOutJack::initialize: JACK server not running?"; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - return; - } + // Initialize JACK client + if ((data->client = jack_client_open(clientName.c_str(), JackNullOption, NULL)) == 0) + { + errorString_ = "MidiOutJack::initialize: JACK server not running?"; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + return; + } - jack_set_process_callback( data->client, jackProcessOut, data ); - data->buffSize = jack_ringbuffer_create( JACK_RINGBUFFER_SIZE ); - data->buffMessage = jack_ringbuffer_create( JACK_RINGBUFFER_SIZE ); - jack_activate( data->client ); + jack_set_process_callback(data->client, jackProcessOut, data); + data->buffSize = jack_ringbuffer_create(JACK_RINGBUFFER_SIZE); + data->buffMessage = jack_ringbuffer_create(JACK_RINGBUFFER_SIZE); + jack_activate(data->client); - apiData_ = (void *) data; + apiData_ = (void *)data; } -MidiOutJack :: ~MidiOutJack() +MidiOutJack ::~MidiOutJack() { - JackMidiData *data = static_cast (apiData_); - closePort(); + JackMidiData *data = static_cast(apiData_); + closePort(); - // Cleanup - jack_client_close( data->client ); - jack_ringbuffer_free( data->buffSize ); - jack_ringbuffer_free( data->buffMessage ); + // Cleanup + jack_client_close(data->client); + jack_ringbuffer_free(data->buffSize); + jack_ringbuffer_free(data->buffMessage); - delete data; + delete data; } -void MidiOutJack :: openPort( unsigned int portNumber, const std::string portName ) +void MidiOutJack ::openPort(unsigned int portNumber, const std::string portName) { - JackMidiData *data = static_cast (apiData_); + JackMidiData *data = static_cast(apiData_); - // Creating new port - if ( data->port == NULL ) - data->port = jack_port_register( data->client, portName.c_str(), - JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0 ); + // Creating new port + if (data->port == NULL) + data->port = jack_port_register(data->client, portName.c_str(), + JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); - if ( data->port == NULL ) { - errorString_ = "MidiOutJack::openVirtualPort: JACK error creating virtual port"; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + if (data->port == NULL) + { + errorString_ = "MidiOutJack::openVirtualPort: JACK error creating virtual port"; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } - // Connecting to the output - std::string name = getPortName( portNumber ); - jack_connect( data->client, jack_port_name( data->port ), name.c_str() ); + // Connecting to the output + std::string name = getPortName(portNumber); + jack_connect(data->client, jack_port_name(data->port), name.c_str()); } -void MidiOutJack :: openVirtualPort( const std::string portName ) +void MidiOutJack ::openVirtualPort(const std::string portName) { - JackMidiData *data = static_cast (apiData_); + JackMidiData *data = static_cast(apiData_); - if ( data->port == NULL ) - data->port = jack_port_register( data->client, portName.c_str(), - JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0 ); + if (data->port == NULL) + data->port = jack_port_register(data->client, portName.c_str(), + JACK_DEFAULT_MIDI_TYPE, JackPortIsOutput, 0); - if ( data->port == NULL ) { - errorString_ = "MidiOutJack::openVirtualPort: JACK error creating virtual port"; - RtMidi::error( RtError::DRIVER_ERROR, errorString_ ); - } + if (data->port == NULL) + { + errorString_ = "MidiOutJack::openVirtualPort: JACK error creating virtual port"; + RtMidi::error(RtError::DRIVER_ERROR, errorString_); + } } -unsigned int MidiOutJack :: getPortCount() +unsigned int MidiOutJack ::getPortCount() { - int count = 0; - JackMidiData *data = static_cast (apiData_); + int count = 0; + JackMidiData *data = static_cast(apiData_); - // List of available ports - const char **ports = jack_get_ports( data->client, NULL, - JACK_DEFAULT_MIDI_TYPE, JackPortIsInput ); + // List of available ports + const char **ports = jack_get_ports(data->client, NULL, + JACK_DEFAULT_MIDI_TYPE, JackPortIsInput); - if ( ports == NULL ) return 0; - while ( ports[count] != NULL ) - count++; + if (ports == NULL) return 0; + while (ports[count] != NULL) + count++; - free( ports ); + free(ports); - return count; + return count; } -std::string MidiOutJack :: getPortName( unsigned int portNumber ) +std::string MidiOutJack ::getPortName(unsigned int portNumber) { - JackMidiData *data = static_cast (apiData_); - std::ostringstream ost; - std::string retStr(""); + JackMidiData *data = static_cast(apiData_); + std::ostringstream ost; + std::string retStr(""); - // List of available ports - const char **ports = jack_get_ports( data->client, NULL, - JACK_DEFAULT_MIDI_TYPE, JackPortIsInput ); + // List of available ports + const char **ports = jack_get_ports(data->client, NULL, + JACK_DEFAULT_MIDI_TYPE, JackPortIsInput); - // Check port validity - if ( ports == NULL) { - errorString_ = "MidiOutJack::getPortName: no ports available!"; - RtMidi::error( RtError::WARNING, errorString_ ); - return retStr; - } + // Check port validity + if (ports == NULL) + { + errorString_ = "MidiOutJack::getPortName: no ports available!"; + RtMidi::error(RtError::WARNING, errorString_); + return retStr; + } - if ( ports[portNumber] == NULL) { - ost << "MidiOutJack::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; - errorString_ = ost.str(); - RtMidi::error( RtError::WARNING, errorString_ ); - } - else retStr.assign( ports[portNumber] ); + if (ports[portNumber] == NULL) + { + ost << "MidiOutJack::getPortName: the 'portNumber' argument (" << portNumber << ") is invalid."; + errorString_ = ost.str(); + RtMidi::error(RtError::WARNING, errorString_); + } + else + retStr.assign(ports[portNumber]); - free( ports ); + free(ports); - return retStr; + return retStr; } -void MidiOutJack :: closePort() +void MidiOutJack ::closePort() { - JackMidiData *data = static_cast (apiData_); + JackMidiData *data = static_cast(apiData_); - if ( data->port == NULL ) return; - jack_port_unregister( data->client, data->port ); - data->port = NULL; + if (data->port == NULL) return; + jack_port_unregister(data->client, data->port); + data->port = NULL; } -void MidiOutJack :: sendMessage( std::vector *message ) +void MidiOutJack ::sendMessage(std::vector *message) { - int nBytes = message->size(); - JackMidiData *data = static_cast (apiData_); + int nBytes = message->size(); + JackMidiData *data = static_cast(apiData_); - // Write full message to buffer - jack_ringbuffer_write( data->buffMessage, ( const char * ) &( *message )[0], - message->size() ); - jack_ringbuffer_write( data->buffSize, ( char * ) &nBytes, sizeof( nBytes ) ); + // Write full message to buffer + jack_ringbuffer_write(data->buffMessage, (const char *)&(*message)[0], + message->size()); + jack_ringbuffer_write(data->buffSize, (char *)&nBytes, sizeof(nBytes)); } #endif // __UNIX_JACK__ \ No newline at end of file diff --git a/examples/ThirdPartyLibs/midi/RtMidi.h b/examples/ThirdPartyLibs/midi/RtMidi.h index 66eb4fc3c..f780191ed 100644 --- a/examples/ThirdPartyLibs/midi/RtMidi.h +++ b/examples/ThirdPartyLibs/midi/RtMidi.h @@ -51,49 +51,48 @@ class RtMidi { - public: +public: + //! MIDI API specifier arguments. + enum Api + { + UNSPECIFIED, /*!< Search for a working compiled API. */ + MACOSX_CORE, /*!< Macintosh OS-X Core Midi API. */ + LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */ + UNIX_JACK, /*!< The Jack Low-Latency MIDI Server API. */ + WINDOWS_MM, /*!< The Microsoft Multimedia MIDI API. */ + WINDOWS_KS, /*!< The Microsoft Kernel Streaming MIDI API. */ + RTMIDI_DUMMY /*!< A compilable but non-functional API. */ + }; - //! MIDI API specifier arguments. - enum Api { - UNSPECIFIED, /*!< Search for a working compiled API. */ - MACOSX_CORE, /*!< Macintosh OS-X Core Midi API. */ - LINUX_ALSA, /*!< The Advanced Linux Sound Architecture API. */ - UNIX_JACK, /*!< The Jack Low-Latency MIDI Server API. */ - WINDOWS_MM, /*!< The Microsoft Multimedia MIDI API. */ - WINDOWS_KS, /*!< The Microsoft Kernel Streaming MIDI API. */ - RTMIDI_DUMMY /*!< A compilable but non-functional API. */ - }; - - //! A static function to determine the available compiled MIDI APIs. - /*! + //! A static function to determine the available compiled MIDI APIs. + /*! The values returned in the std::vector can be compared against the enumerated list values. Note that there can be more than one API compiled for certain operating systems. */ - static void getCompiledApi( std::vector &apis ); + static void getCompiledApi(std::vector &apis); - //! Pure virtual openPort() function. - virtual void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi" ) ) = 0; + //! Pure virtual openPort() function. + virtual void openPort(unsigned int portNumber = 0, const std::string portName = std::string("RtMidi")) = 0; - //! Pure virtual openVirtualPort() function. - virtual void openVirtualPort( const std::string portName = std::string( "RtMidi" ) ) = 0; + //! Pure virtual openVirtualPort() function. + virtual void openVirtualPort(const std::string portName = std::string("RtMidi")) = 0; - //! Pure virtual getPortCount() function. - virtual unsigned int getPortCount() = 0; + //! Pure virtual getPortCount() function. + virtual unsigned int getPortCount() = 0; - //! Pure virtual getPortName() function. - virtual std::string getPortName( unsigned int portNumber = 0 ) = 0; + //! Pure virtual getPortName() function. + virtual std::string getPortName(unsigned int portNumber = 0) = 0; - //! Pure virtual closePort() function. - virtual void closePort( void ) = 0; + //! Pure virtual closePort() function. + virtual void closePort(void) = 0; - //! A basic error reporting function for RtMidi classes. - static void error( RtError::Type type, std::string errorString ); + //! A basic error reporting function for RtMidi classes. + static void error(RtError::Type type, std::string errorString); - protected: - - RtMidi() {}; - virtual ~RtMidi() {}; +protected: + RtMidi(){}; + virtual ~RtMidi(){}; }; /**********************************************************************/ @@ -133,13 +132,12 @@ class MidiOutApi; class RtMidiIn : public RtMidi { - public: +public: + //! User callback function type definition. + typedef void (*RtMidiCallback)(double timeStamp, std::vector *message, void *userData); - //! User callback function type definition. - typedef void (*RtMidiCallback)( double timeStamp, std::vector *message, void *userData); - - //! Default constructor that allows an optional api, client name and queue size. - /*! + //! Default constructor that allows an optional api, client name and queue size. + /*! An assert will be fired if a MIDI system initialization error occurs. The queue size defines the maximum number of messages that can be held in the MIDI queue (when not using a @@ -150,84 +148,83 @@ class RtMidiIn : public RtMidi compiled, the default order of use is JACK, ALSA (Linux) and CORE, Jack (OS-X). */ - RtMidiIn( RtMidi::Api api=UNSPECIFIED, - const std::string clientName = std::string( "RtMidi Input Client"), - unsigned int queueSizeLimit = 100 ); + RtMidiIn(RtMidi::Api api = UNSPECIFIED, + const std::string clientName = std::string("RtMidi Input Client"), + unsigned int queueSizeLimit = 100); - //! If a MIDI connection is still open, it will be closed by the destructor. - ~RtMidiIn ( void ); + //! If a MIDI connection is still open, it will be closed by the destructor. + ~RtMidiIn(void); - //! Returns the MIDI API specifier for the current instance of RtMidiIn. - RtMidi::Api getCurrentApi( void ); + //! Returns the MIDI API specifier for the current instance of RtMidiIn. + RtMidi::Api getCurrentApi(void); - //! Open a MIDI input connection. - /*! + //! Open a MIDI input connection. + /*! An optional port number greater than 0 can be specified. Otherwise, the default or first port found is opened. */ - void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi Input" ) ); + void openPort(unsigned int portNumber = 0, const std::string portName = std::string("RtMidi Input")); - //! Create a virtual input port, with optional name, to allow software connections (OS X and ALSA only). - /*! + //! Create a virtual input port, with optional name, to allow software connections (OS X and ALSA only). + /*! This function creates a virtual MIDI input port to which other software applications can connect. This type of functionality is currently only supported by the Macintosh OS-X and Linux ALSA APIs (the function does nothing for the other APIs). */ - void openVirtualPort( const std::string portName = std::string( "RtMidi Input" ) ); + void openVirtualPort(const std::string portName = std::string("RtMidi Input")); - //! Set a callback function to be invoked for incoming MIDI messages. - /*! + //! Set a callback function to be invoked for incoming MIDI messages. + /*! The callback function will be called whenever an incoming MIDI message is received. While not absolutely necessary, it is best to set the callback function before opening a MIDI port to avoid leaving some messages in the queue. */ - void setCallback( RtMidiCallback callback, void *userData = 0 ); + void setCallback(RtMidiCallback callback, void *userData = 0); - //! Cancel use of the current callback function (if one exists). - /*! + //! Cancel use of the current callback function (if one exists). + /*! Subsequent incoming MIDI messages will be written to the queue and can be retrieved with the \e getMessage function. */ - void cancelCallback(); + void cancelCallback(); - //! Close an open MIDI connection (if one exists). - void closePort( void ); + //! Close an open MIDI connection (if one exists). + void closePort(void); - //! Return the number of available MIDI input ports. - unsigned int getPortCount(); + //! Return the number of available MIDI input ports. + unsigned int getPortCount(); - //! Return a string identifier for the specified MIDI input port number. - /*! + //! Return a string identifier for the specified MIDI input port number. + /*! An empty string is returned if an invalid port specifier is provided. */ - std::string getPortName( unsigned int portNumber = 0 ); + std::string getPortName(unsigned int portNumber = 0); - //! Specify whether certain MIDI message types should be queued or ignored during input. - /*! + //! Specify whether certain MIDI message types should be queued or ignored during input. + /*! o By default, MIDI timing and active sensing messages are ignored during message input because of their relative high data rates. MIDI sysex messages are ignored by default as well. Variable values of "true" imply that the respective message type will be ignored. */ - void ignoreTypes( bool midiSysex = true, bool midiTime = true, bool midiSense = true ); + void ignoreTypes(bool midiSysex = true, bool midiTime = true, bool midiSense = true); - //! Fill the user-provided vector with the data bytes for the next available MIDI message in the input queue and return the event delta-time in seconds. - /*! + //! Fill the user-provided vector with the data bytes for the next available MIDI message in the input queue and return the event delta-time in seconds. + /*! This function returns immediately whether a new message is available or not. A valid message is indicated by a non-zero vector size. An assert is fired if an error occurs during message retrieval or an input connection was not previously established. */ - double getMessage( std::vector *message ); - - protected: - void openMidiApi( RtMidi::Api api, const std::string clientName, unsigned int queueSizeLimit ); - MidiInApi *rtapi_; + double getMessage(std::vector *message); +protected: + void openMidiApi(RtMidi::Api api, const std::string clientName, unsigned int queueSizeLimit); + MidiInApi *rtapi_; }; /**********************************************************************/ @@ -248,39 +245,38 @@ class RtMidiIn : public RtMidi class RtMidiOut : public RtMidi { - public: - - //! Default constructor that allows an optional client name. - /*! +public: + //! Default constructor that allows an optional client name. + /*! An exception will be thrown if a MIDI system initialization error occurs. If no API argument is specified and multiple API support has been compiled, the default order of use is JACK, ALSA (Linux) and CORE, Jack (OS-X). */ - RtMidiOut( RtMidi::Api api=UNSPECIFIED, - const std::string clientName = std::string( "RtMidi Output Client") ); + RtMidiOut(RtMidi::Api api = UNSPECIFIED, + const std::string clientName = std::string("RtMidi Output Client")); - //! The destructor closes any open MIDI connections. - ~RtMidiOut( void ); + //! The destructor closes any open MIDI connections. + ~RtMidiOut(void); - //! Returns the MIDI API specifier for the current instance of RtMidiOut. - RtMidi::Api getCurrentApi( void ); + //! Returns the MIDI API specifier for the current instance of RtMidiOut. + RtMidi::Api getCurrentApi(void); - //! Open a MIDI output connection. - /*! + //! Open a MIDI output connection. + /*! An optional port number greater than 0 can be specified. Otherwise, the default or first port found is opened. An exception is thrown if an error occurs while attempting to make the port connection. */ - void openPort( unsigned int portNumber = 0, const std::string portName = std::string( "RtMidi Output" ) ); + void openPort(unsigned int portNumber = 0, const std::string portName = std::string("RtMidi Output")); - //! Close an open MIDI connection (if one exists). - void closePort( void ); + //! Close an open MIDI connection (if one exists). + void closePort(void); - //! Create a virtual output port, with optional name, to allow software connections (OS X and ALSA only). - /*! + //! Create a virtual output port, with optional name, to allow software connections (OS X and ALSA only). + /*! This function creates a virtual MIDI output port to which other software applications can connect. This type of functionality is currently only supported by the Macintosh OS-X and Linux ALSA @@ -288,30 +284,29 @@ class RtMidiOut : public RtMidi exception is thrown if an error occurs while attempting to create the virtual port. */ - void openVirtualPort( const std::string portName = std::string( "RtMidi Output" ) ); + void openVirtualPort(const std::string portName = std::string("RtMidi Output")); - //! Return the number of available MIDI output ports. - unsigned int getPortCount( void ); + //! Return the number of available MIDI output ports. + unsigned int getPortCount(void); - //! Return a string identifier for the specified MIDI port type and number. - /*! + //! Return a string identifier for the specified MIDI port type and number. + /*! An empty string is returned if an invalid port specifier is provided. */ - std::string getPortName( unsigned int portNumber = 0 ); + std::string getPortName(unsigned int portNumber = 0); - //! Immediately send a single message out an open MIDI output port. - /*! + //! Immediately send a single message out an open MIDI output port. + /*! An exception is thrown if an error occurs during output or an output connection was not previously established. */ - void sendMessage( std::vector *message ); + void sendMessage(std::vector *message); - protected: - void openMidiApi( RtMidi::Api api, const std::string clientName ); - MidiOutApi *rtapi_; +protected: + void openMidiApi(RtMidi::Api api, const std::string clientName); + MidiOutApi *rtapi_; }; - // **************************************************************** // // // MidiInApi / MidiOutApi class declarations. @@ -327,94 +322,93 @@ class RtMidiOut : public RtMidi class MidiInApi { - public: +public: + MidiInApi(unsigned int queueSizeLimit); + virtual ~MidiInApi(void); + virtual RtMidi::Api getCurrentApi(void) = 0; + virtual void openPort(unsigned int portNumber, const std::string portName) = 0; + virtual void openVirtualPort(const std::string portName) = 0; + virtual void closePort(void) = 0; + void setCallback(RtMidiIn::RtMidiCallback callback, void *userData); + void cancelCallback(void); + virtual unsigned int getPortCount(void) = 0; + virtual std::string getPortName(unsigned int portNumber) = 0; + virtual void ignoreTypes(bool midiSysex, bool midiTime, bool midiSense); + double getMessage(std::vector *message); - MidiInApi( unsigned int queueSizeLimit ); - virtual ~MidiInApi( void ); - virtual RtMidi::Api getCurrentApi( void ) = 0; - virtual void openPort( unsigned int portNumber, const std::string portName ) = 0; - virtual void openVirtualPort( const std::string portName ) = 0; - virtual void closePort( void ) = 0; - void setCallback( RtMidiIn::RtMidiCallback callback, void *userData ); - void cancelCallback( void ); - virtual unsigned int getPortCount( void ) = 0; - virtual std::string getPortName( unsigned int portNumber ) = 0; - virtual void ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ); - double getMessage( std::vector *message ); + // A MIDI structure used internally by the class to store incoming + // messages. Each message represents one and only one MIDI message. + struct MidiMessage + { + std::vector bytes; + double timeStamp; - // A MIDI structure used internally by the class to store incoming - // messages. Each message represents one and only one MIDI message. - struct MidiMessage { - std::vector bytes; - double timeStamp; + // Default constructor. + MidiMessage() + : bytes(0), timeStamp(0.0) {} + }; - // Default constructor. - MidiMessage() - :bytes(0), timeStamp(0.0) {} - }; + struct MidiQueue + { + unsigned int front; + unsigned int back; + unsigned int size; + unsigned int ringSize; + MidiMessage *ring; - struct MidiQueue { - unsigned int front; - unsigned int back; - unsigned int size; - unsigned int ringSize; - MidiMessage *ring; + // Default constructor. + MidiQueue() + : front(0), back(0), size(0), ringSize(0) {} + }; - // Default constructor. - MidiQueue() - :front(0), back(0), size(0), ringSize(0) {} - }; + // The RtMidiInData structure is used to pass private class data to + // the MIDI input handling function or thread. + struct RtMidiInData + { + MidiQueue queue; + MidiMessage message; + unsigned char ignoreFlags; + bool doInput; + bool firstMessage; + void *apiData; + bool usingCallback; + void *userCallback; + void *userData; + bool continueSysex; - // The RtMidiInData structure is used to pass private class data to - // the MIDI input handling function or thread. - struct RtMidiInData { - MidiQueue queue; - MidiMessage message; - unsigned char ignoreFlags; - bool doInput; - bool firstMessage; - void *apiData; - bool usingCallback; - void *userCallback; - void *userData; - bool continueSysex; + // Default constructor. + RtMidiInData() + : ignoreFlags(7), doInput(false), firstMessage(true), apiData(0), usingCallback(false), userCallback(0), userData(0), continueSysex(false) {} + }; - // Default constructor. - RtMidiInData() - : ignoreFlags(7), doInput(false), firstMessage(true), - apiData(0), usingCallback(false), userCallback(0), userData(0), - continueSysex(false) {} - }; +protected: + virtual void initialize(const std::string &clientName) = 0; + RtMidiInData inputData_; - protected: - virtual void initialize( const std::string& clientName ) = 0; - RtMidiInData inputData_; - - void *apiData_; - bool connected_; - std::string errorString_; + void *apiData_; + bool connected_; + std::string errorString_; }; class MidiOutApi { - public: +public: + MidiOutApi(void); + virtual ~MidiOutApi(void); + virtual RtMidi::Api getCurrentApi(void) = 0; + virtual void openPort(unsigned int portNumber, const std::string portName) = 0; + virtual void openVirtualPort(const std::string portName) = 0; + virtual void closePort(void) = 0; + virtual unsigned int getPortCount(void) = 0; + virtual std::string getPortName(unsigned int portNumber) = 0; + virtual void sendMessage(std::vector *message) = 0; - MidiOutApi( void ); - virtual ~MidiOutApi( void ); - virtual RtMidi::Api getCurrentApi( void ) = 0; - virtual void openPort( unsigned int portNumber, const std::string portName ) = 0; - virtual void openVirtualPort( const std::string portName ) = 0; - virtual void closePort( void ) = 0; - virtual unsigned int getPortCount( void ) = 0; - virtual std::string getPortName( unsigned int portNumber ) = 0; - virtual void sendMessage( std::vector *message ) = 0; +protected: + virtual void initialize(const std::string &clientName) = 0; - protected: - virtual void initialize( const std::string& clientName ) = 0; - - void *apiData_; - bool connected_; - std::string errorString_; + void *apiData_; + bool connected_; + std::string errorString_; }; // **************************************************************** // @@ -423,24 +417,24 @@ class MidiOutApi // // **************************************************************** // -inline RtMidi::Api RtMidiIn :: getCurrentApi( void ) { return rtapi_->getCurrentApi(); } -inline void RtMidiIn :: openPort( unsigned int portNumber, const std::string portName ) { return rtapi_->openPort( portNumber, portName ); } -inline void RtMidiIn :: openVirtualPort( const std::string portName ) { return rtapi_->openVirtualPort( portName ); } -inline void RtMidiIn :: closePort( void ) { return rtapi_->closePort(); } -inline void RtMidiIn :: setCallback( RtMidiCallback callback, void *userData ) { return rtapi_->setCallback( callback, userData ); } -inline void RtMidiIn :: cancelCallback( void ) { return rtapi_->cancelCallback(); } -inline unsigned int RtMidiIn :: getPortCount( void ) { return rtapi_->getPortCount(); } -inline std::string RtMidiIn :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); } -inline void RtMidiIn :: ignoreTypes( bool midiSysex, bool midiTime, bool midiSense ) { return rtapi_->ignoreTypes( midiSysex, midiTime, midiSense ); } -inline double RtMidiIn :: getMessage( std::vector *message ) { return rtapi_->getMessage( message ); } +inline RtMidi::Api RtMidiIn ::getCurrentApi(void) { return rtapi_->getCurrentApi(); } +inline void RtMidiIn ::openPort(unsigned int portNumber, const std::string portName) { return rtapi_->openPort(portNumber, portName); } +inline void RtMidiIn ::openVirtualPort(const std::string portName) { return rtapi_->openVirtualPort(portName); } +inline void RtMidiIn ::closePort(void) { return rtapi_->closePort(); } +inline void RtMidiIn ::setCallback(RtMidiCallback callback, void *userData) { return rtapi_->setCallback(callback, userData); } +inline void RtMidiIn ::cancelCallback(void) { return rtapi_->cancelCallback(); } +inline unsigned int RtMidiIn ::getPortCount(void) { return rtapi_->getPortCount(); } +inline std::string RtMidiIn ::getPortName(unsigned int portNumber) { return rtapi_->getPortName(portNumber); } +inline void RtMidiIn ::ignoreTypes(bool midiSysex, bool midiTime, bool midiSense) { return rtapi_->ignoreTypes(midiSysex, midiTime, midiSense); } +inline double RtMidiIn ::getMessage(std::vector *message) { return rtapi_->getMessage(message); } -inline RtMidi::Api RtMidiOut :: getCurrentApi( void ) { return rtapi_->getCurrentApi(); } -inline void RtMidiOut :: openPort( unsigned int portNumber, const std::string portName ) { return rtapi_->openPort( portNumber, portName ); } -inline void RtMidiOut :: openVirtualPort( const std::string portName ) { return rtapi_->openVirtualPort( portName ); } -inline void RtMidiOut :: closePort( void ) { return rtapi_->closePort(); } -inline unsigned int RtMidiOut :: getPortCount( void ) { return rtapi_->getPortCount(); } -inline std::string RtMidiOut :: getPortName( unsigned int portNumber ) { return rtapi_->getPortName( portNumber ); } -inline void RtMidiOut :: sendMessage( std::vector *message ) { return rtapi_->sendMessage( message ); } +inline RtMidi::Api RtMidiOut ::getCurrentApi(void) { return rtapi_->getCurrentApi(); } +inline void RtMidiOut ::openPort(unsigned int portNumber, const std::string portName) { return rtapi_->openPort(portNumber, portName); } +inline void RtMidiOut ::openVirtualPort(const std::string portName) { return rtapi_->openVirtualPort(portName); } +inline void RtMidiOut ::closePort(void) { return rtapi_->closePort(); } +inline unsigned int RtMidiOut ::getPortCount(void) { return rtapi_->getPortCount(); } +inline std::string RtMidiOut ::getPortName(unsigned int portNumber) { return rtapi_->getPortName(portNumber); } +inline void RtMidiOut ::sendMessage(std::vector *message) { return rtapi_->sendMessage(message); } // **************************************************************** // // @@ -449,225 +443,233 @@ inline void RtMidiOut :: sendMessage( std::vector *message ) { re // **************************************************************** // #if !defined(__LINUX_ALSA__) && !defined(__UNIX_JACK__) && !defined(__MACOSX_CORE__) && !defined(__WINDOWS_MM__) && !defined(__WINDOWS_KS__) - #define __RTMIDI_DUMMY__ +#define __RTMIDI_DUMMY__ #endif #if defined(__MACOSX_CORE__) -class MidiInCore: public MidiInApi +class MidiInCore : public MidiInApi { - public: - MidiInCore( const std::string clientName, unsigned int queueSizeLimit ); - ~MidiInCore( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::MACOSX_CORE; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); +public: + MidiInCore(const std::string clientName, unsigned int queueSizeLimit); + ~MidiInCore(void); + RtMidi::Api getCurrentApi(void) { return RtMidi::MACOSX_CORE; }; + void openPort(unsigned int portNumber, const std::string portName); + void openVirtualPort(const std::string portName); + void closePort(void); + unsigned int getPortCount(void); + std::string getPortName(unsigned int portNumber); - protected: - void initialize( const std::string& clientName ); +protected: + void initialize(const std::string &clientName); }; -class MidiOutCore: public MidiOutApi +class MidiOutCore : public MidiOutApi { - public: - MidiOutCore( const std::string clientName ); - ~MidiOutCore( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::MACOSX_CORE; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); - void sendMessage( std::vector *message ); +public: + MidiOutCore(const std::string clientName); + ~MidiOutCore(void); + RtMidi::Api getCurrentApi(void) { return RtMidi::MACOSX_CORE; }; + void openPort(unsigned int portNumber, const std::string portName); + void openVirtualPort(const std::string portName); + void closePort(void); + unsigned int getPortCount(void); + std::string getPortName(unsigned int portNumber); + void sendMessage(std::vector *message); - protected: - void initialize( const std::string& clientName ); +protected: + void initialize(const std::string &clientName); }; #endif #if defined(__UNIX_JACK__) -class MidiInJack: public MidiInApi +class MidiInJack : public MidiInApi { - public: - MidiInJack( const std::string clientName, unsigned int queueSizeLimit ); - ~MidiInJack( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::UNIX_JACK; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); +public: + MidiInJack(const std::string clientName, unsigned int queueSizeLimit); + ~MidiInJack(void); + RtMidi::Api getCurrentApi(void) { return RtMidi::UNIX_JACK; }; + void openPort(unsigned int portNumber, const std::string portName); + void openVirtualPort(const std::string portName); + void closePort(void); + unsigned int getPortCount(void); + std::string getPortName(unsigned int portNumber); - protected: - void initialize( const std::string& clientName ); +protected: + void initialize(const std::string &clientName); }; -class MidiOutJack: public MidiOutApi +class MidiOutJack : public MidiOutApi { - public: - MidiOutJack( const std::string clientName ); - ~MidiOutJack( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::UNIX_JACK; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); - void sendMessage( std::vector *message ); +public: + MidiOutJack(const std::string clientName); + ~MidiOutJack(void); + RtMidi::Api getCurrentApi(void) { return RtMidi::UNIX_JACK; }; + void openPort(unsigned int portNumber, const std::string portName); + void openVirtualPort(const std::string portName); + void closePort(void); + unsigned int getPortCount(void); + std::string getPortName(unsigned int portNumber); + void sendMessage(std::vector *message); - protected: - void initialize( const std::string& clientName ); +protected: + void initialize(const std::string &clientName); }; #endif #if defined(__LINUX_ALSA__) -class MidiInAlsa: public MidiInApi +class MidiInAlsa : public MidiInApi { - public: - MidiInAlsa( const std::string clientName, unsigned int queueSizeLimit ); - ~MidiInAlsa( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::LINUX_ALSA; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); +public: + MidiInAlsa(const std::string clientName, unsigned int queueSizeLimit); + ~MidiInAlsa(void); + RtMidi::Api getCurrentApi(void) { return RtMidi::LINUX_ALSA; }; + void openPort(unsigned int portNumber, const std::string portName); + void openVirtualPort(const std::string portName); + void closePort(void); + unsigned int getPortCount(void); + std::string getPortName(unsigned int portNumber); - protected: - void initialize( const std::string& clientName ); +protected: + void initialize(const std::string &clientName); }; -class MidiOutAlsa: public MidiOutApi +class MidiOutAlsa : public MidiOutApi { - public: - MidiOutAlsa( const std::string clientName ); - ~MidiOutAlsa( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::LINUX_ALSA; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); - void sendMessage( std::vector *message ); +public: + MidiOutAlsa(const std::string clientName); + ~MidiOutAlsa(void); + RtMidi::Api getCurrentApi(void) { return RtMidi::LINUX_ALSA; }; + void openPort(unsigned int portNumber, const std::string portName); + void openVirtualPort(const std::string portName); + void closePort(void); + unsigned int getPortCount(void); + std::string getPortName(unsigned int portNumber); + void sendMessage(std::vector *message); - protected: - void initialize( const std::string& clientName ); +protected: + void initialize(const std::string &clientName); }; #endif #if defined(__WINDOWS_MM__) -class MidiInWinMM: public MidiInApi +class MidiInWinMM : public MidiInApi { - public: - MidiInWinMM( const std::string clientName, unsigned int queueSizeLimit ); - ~MidiInWinMM( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_MM; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); +public: + MidiInWinMM(const std::string clientName, unsigned int queueSizeLimit); + ~MidiInWinMM(void); + RtMidi::Api getCurrentApi(void) { return RtMidi::WINDOWS_MM; }; + void openPort(unsigned int portNumber, const std::string portName); + void openVirtualPort(const std::string portName); + void closePort(void); + unsigned int getPortCount(void); + std::string getPortName(unsigned int portNumber); - protected: - void initialize( const std::string& clientName ); +protected: + void initialize(const std::string &clientName); }; -class MidiOutWinMM: public MidiOutApi +class MidiOutWinMM : public MidiOutApi { - public: - MidiOutWinMM( const std::string clientName ); - ~MidiOutWinMM( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_MM; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); - void sendMessage( std::vector *message ); +public: + MidiOutWinMM(const std::string clientName); + ~MidiOutWinMM(void); + RtMidi::Api getCurrentApi(void) { return RtMidi::WINDOWS_MM; }; + void openPort(unsigned int portNumber, const std::string portName); + void openVirtualPort(const std::string portName); + void closePort(void); + unsigned int getPortCount(void); + std::string getPortName(unsigned int portNumber); + void sendMessage(std::vector *message); - protected: - void initialize( const std::string& clientName ); +protected: + void initialize(const std::string &clientName); }; #endif #if defined(__WINDOWS_KS__) -class MidiInWinKS: public MidiInApi +class MidiInWinKS : public MidiInApi { - public: - MidiInWinKS( const std::string clientName, unsigned int queueSizeLimit ); - ~MidiInWinKS( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_KS; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); +public: + MidiInWinKS(const std::string clientName, unsigned int queueSizeLimit); + ~MidiInWinKS(void); + RtMidi::Api getCurrentApi(void) { return RtMidi::WINDOWS_KS; }; + void openPort(unsigned int portNumber, const std::string portName); + void openVirtualPort(const std::string portName); + void closePort(void); + unsigned int getPortCount(void); + std::string getPortName(unsigned int portNumber); - protected: - void initialize( const std::string& clientName ); +protected: + void initialize(const std::string &clientName); }; -class MidiOutWinKS: public MidiOutApi +class MidiOutWinKS : public MidiOutApi { - public: - MidiOutWinKS( const std::string clientName ); - ~MidiOutWinKS( void ); - RtMidi::Api getCurrentApi( void ) { return RtMidi::WINDOWS_KS; }; - void openPort( unsigned int portNumber, const std::string portName ); - void openVirtualPort( const std::string portName ); - void closePort( void ); - unsigned int getPortCount( void ); - std::string getPortName( unsigned int portNumber ); - void sendMessage( std::vector *message ); +public: + MidiOutWinKS(const std::string clientName); + ~MidiOutWinKS(void); + RtMidi::Api getCurrentApi(void) { return RtMidi::WINDOWS_KS; }; + void openPort(unsigned int portNumber, const std::string portName); + void openVirtualPort(const std::string portName); + void closePort(void); + unsigned int getPortCount(void); + std::string getPortName(unsigned int portNumber); + void sendMessage(std::vector *message); - protected: - void initialize( const std::string& clientName ); +protected: + void initialize(const std::string &clientName); }; #endif #if defined(__RTMIDI_DUMMY__) -class MidiInDummy: public MidiInApi +class MidiInDummy : public MidiInApi { - public: - MidiInDummy( const std::string clientName, unsigned int queueSizeLimit ) : MidiInApi( queueSizeLimit ) { errorString_ = "MidiInDummy: This class provides no functionality."; RtMidi::error( RtError::WARNING, errorString_ ); }; - RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; }; - void openPort( unsigned int portNumber, const std::string portName ) {}; - void openVirtualPort( const std::string portName ) {}; - void closePort( void ) {}; - unsigned int getPortCount( void ) { return 0; }; - std::string getPortName( unsigned int portNumber ) { return ""; }; +public: + MidiInDummy(const std::string clientName, unsigned int queueSizeLimit) : MidiInApi(queueSizeLimit) + { + errorString_ = "MidiInDummy: This class provides no functionality."; + RtMidi::error(RtError::WARNING, errorString_); + }; + RtMidi::Api getCurrentApi(void) { return RtMidi::RTMIDI_DUMMY; }; + void openPort(unsigned int portNumber, const std::string portName){}; + void openVirtualPort(const std::string portName){}; + void closePort(void){}; + unsigned int getPortCount(void) { return 0; }; + std::string getPortName(unsigned int portNumber) { return ""; }; - protected: - void initialize( const std::string& clientName ) {}; +protected: + void initialize(const std::string &clientName){}; }; -class MidiOutDummy: public MidiOutApi +class MidiOutDummy : public MidiOutApi { - public: - MidiOutDummy( const std::string clientName ) { errorString_ = "MidiOutDummy: This class provides no functionality."; RtMidi::error( RtError::WARNING, errorString_ ); }; - RtMidi::Api getCurrentApi( void ) { return RtMidi::RTMIDI_DUMMY; }; - void openPort( unsigned int portNumber, const std::string portName ) {}; - void openVirtualPort( const std::string portName ) {}; - void closePort( void ) {}; - unsigned int getPortCount( void ) { return 0; }; - std::string getPortName( unsigned int portNumber ) { return ""; }; - void sendMessage( std::vector *message ) {}; +public: + MidiOutDummy(const std::string clientName) + { + errorString_ = "MidiOutDummy: This class provides no functionality."; + RtMidi::error(RtError::WARNING, errorString_); + }; + RtMidi::Api getCurrentApi(void) { return RtMidi::RTMIDI_DUMMY; }; + void openPort(unsigned int portNumber, const std::string portName){}; + void openVirtualPort(const std::string portName){}; + void closePort(void){}; + unsigned int getPortCount(void) { return 0; }; + std::string getPortName(unsigned int portNumber) { return ""; }; + void sendMessage(std::vector *message){}; - protected: - void initialize( const std::string& clientName ) {}; +protected: + void initialize(const std::string &clientName){}; }; #endif diff --git a/examples/ThirdPartyLibs/midi/cmidiin.cpp b/examples/ThirdPartyLibs/midi/cmidiin.cpp index 75d2958b0..3e10233bc 100644 --- a/examples/ThirdPartyLibs/midi/cmidiin.cpp +++ b/examples/ThirdPartyLibs/midi/cmidiin.cpp @@ -11,67 +11,65 @@ #include #include "RtMidi.h" -void usage( void ) { - // Error function in case of incorrect command-line - // argument specifications. - std::cout << "\nuseage: cmidiin \n"; - std::cout << " where port = the device to use (default = 0).\n\n"; - exit( 0 ); +void usage(void) +{ + // Error function in case of incorrect command-line + // argument specifications. + std::cout << "\nuseage: cmidiin \n"; + std::cout << " where port = the device to use (default = 0).\n\n"; + exit(0); } -void mycallback( double deltatime, std::vector< unsigned char > *message, void *userData ) +void mycallback(double deltatime, std::vector *message, void *userData) { - unsigned int nBytes = message->size(); - for ( unsigned int i=0; i 0 ) - std::cout << "stamp = " << deltatime << std::endl; + unsigned int nBytes = message->size(); + for (unsigned int i = 0; i < nBytes; i++) + std::cout << "Byte " << i << " = " << (int)message->at(i) << ", "; + if (nBytes > 0) + std::cout << "stamp = " << deltatime << std::endl; } // This function should be embedded in a try/catch block in case of // an exception. It offers the user a choice of MIDI ports to open. // It returns false if there are no ports available. -bool chooseMidiPort( RtMidiIn *rtmidi ); +bool chooseMidiPort(RtMidiIn *rtmidi); -int main( int argc, char *argv[] ) +int main(int argc, char *argv[]) { - RtMidiIn *midiin = 0; + RtMidiIn *midiin = 0; - // Minimal command-line check. - if ( argc > 2 ) usage(); + // Minimal command-line check. + if (argc > 2) usage(); + // RtMidiIn constructor + midiin = new RtMidiIn(); - // RtMidiIn constructor - midiin = new RtMidiIn(); + // Call function to select port. + if (chooseMidiPort(midiin) == false) goto cleanup; - // Call function to select port. - if ( chooseMidiPort( midiin ) == false ) goto cleanup; + // Set our callback function. This should be done immediately after + // opening the port to avoid having incoming messages written to the + // queue instead of sent to the callback function. + midiin->setCallback(&mycallback); - // Set our callback function. This should be done immediately after - // opening the port to avoid having incoming messages written to the - // queue instead of sent to the callback function. - midiin->setCallback( &mycallback ); + // Don't ignore sysex, timing, or active sensing messages. + midiin->ignoreTypes(false, false, false); - // Don't ignore sysex, timing, or active sensing messages. - midiin->ignoreTypes( false, false, false ); - - std::cout << "\nReading MIDI input ... press to quit.\n"; - char input; - std::cin.get(input); + std::cout << "\nReading MIDI input ... press to quit.\n"; + char input; + std::cin.get(input); std::cin.get(input); +cleanup: + delete midiin; - cleanup: - - delete midiin; - - return 0; + return 0; } -bool chooseMidiPort( RtMidiIn *rtmidi ) +bool chooseMidiPort(RtMidiIn *rtmidi) { - /* + /* std::cout << "\nWould you like to open a virtual input port? [y/N] "; @@ -83,30 +81,35 @@ bool chooseMidiPort( RtMidiIn *rtmidi ) } */ - std::string portName; - unsigned int i = 0, nPorts = rtmidi->getPortCount(); - if ( nPorts == 0 ) { - std::cout << "No input ports available!" << std::endl; - return false; - } + std::string portName; + unsigned int i = 0, nPorts = rtmidi->getPortCount(); + if (nPorts == 0) + { + std::cout << "No input ports available!" << std::endl; + return false; + } - if ( nPorts == 1 ) { - std::cout << "\nOpening " << rtmidi->getPortName() << std::endl; - } - else { - for ( i=0; igetPortName(i); - std::cout << " Input port #" << i << ": " << portName << '\n'; - } + if (nPorts == 1) + { + std::cout << "\nOpening " << rtmidi->getPortName() << std::endl; + } + else + { + for (i = 0; i < nPorts; i++) + { + portName = rtmidi->getPortName(i); + std::cout << " Input port #" << i << ": " << portName << '\n'; + } - do { - std::cout << "\nChoose a port number: "; - std::cin >> i; - } while ( i >= nPorts ); - } + do + { + std::cout << "\nChoose a port number: "; + std::cin >> i; + } while (i >= nPorts); + } -// std::getline( std::cin, keyHit ); // used to clear out stdin - rtmidi->openPort( i ); + // std::getline( std::cin, keyHit ); // used to clear out stdin + rtmidi->openPort(i); - return true; + return true; } \ No newline at end of file diff --git a/examples/ThirdPartyLibs/minizip/crypt.h b/examples/ThirdPartyLibs/minizip/crypt.h index acdf125b9..55eccdaf2 100644 --- a/examples/ThirdPartyLibs/minizip/crypt.h +++ b/examples/ThirdPartyLibs/minizip/crypt.h @@ -29,105 +29,105 @@ #define NOCRYPT #define NOUNCRYPT -#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) +#define CRC32(c, b) ((*(pcrc_32_tab + (((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) /*********************************************************************** * Return the next byte in the pseudo-random sequence */ static int decrypt_byte(unsigned long* pkeys, const unsigned long* pcrc_32_tab) { - unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an + unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an * unpredictable manner on 16-bit systems; not a problem * with any known compiler so far, though */ - temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2; - return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); + temp = ((unsigned)(*(pkeys + 2)) & 0xffff) | 2; + return (int)(((temp * (temp ^ 1)) >> 8) & 0xff); } /*********************************************************************** * Update the encryption keys with the next byte of plain text */ -static int update_keys(unsigned long* pkeys,const unsigned long* pcrc_32_tab,int c) +static int update_keys(unsigned long* pkeys, const unsigned long* pcrc_32_tab, int c) { - (*(pkeys+0)) = CRC32((*(pkeys+0)), c); - (*(pkeys+1)) += (*(pkeys+0)) & 0xff; - (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1; - { - register int keyshift = (int)((*(pkeys+1)) >> 24); - (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift); - } - return c; + (*(pkeys + 0)) = CRC32((*(pkeys + 0)), c); + (*(pkeys + 1)) += (*(pkeys + 0)) & 0xff; + (*(pkeys + 1)) = (*(pkeys + 1)) * 134775813L + 1; + { + register int keyshift = (int)((*(pkeys + 1)) >> 24); + (*(pkeys + 2)) = CRC32((*(pkeys + 2)), keyshift); + } + return c; } - /*********************************************************************** * Initialize the encryption keys and the random header according to * the given password. */ -static void init_keys(const char* passwd,unsigned long* pkeys,const unsigned long* pcrc_32_tab) +static void init_keys(const char* passwd, unsigned long* pkeys, const unsigned long* pcrc_32_tab) { - *(pkeys+0) = 305419896L; - *(pkeys+1) = 591751049L; - *(pkeys+2) = 878082192L; - while (*passwd != '\0') { - update_keys(pkeys,pcrc_32_tab,(int)*passwd); - passwd++; - } + *(pkeys + 0) = 305419896L; + *(pkeys + 1) = 591751049L; + *(pkeys + 2) = 878082192L; + while (*passwd != '\0') + { + update_keys(pkeys, pcrc_32_tab, (int)*passwd); + passwd++; + } } -#define zdecode(pkeys,pcrc_32_tab,c) \ - (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab))) +#define zdecode(pkeys, pcrc_32_tab, c) \ + (update_keys(pkeys, pcrc_32_tab, c ^= decrypt_byte(pkeys, pcrc_32_tab))) -#define zencode(pkeys,pcrc_32_tab,c,t) \ - (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c)) +#define zencode(pkeys, pcrc_32_tab, c, t) \ + (t = decrypt_byte(pkeys, pcrc_32_tab), update_keys(pkeys, pcrc_32_tab, c), t ^ (c)) #ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED -#define RAND_HEAD_LEN 12 - /* "last resort" source for second part of crypt seed pattern */ -# ifndef ZCR_SEED2 -# define ZCR_SEED2 3141592654UL /* use PI as default pattern */ -# endif +#define RAND_HEAD_LEN 12 +/* "last resort" source for second part of crypt seed pattern */ +#ifndef ZCR_SEED2 +#define ZCR_SEED2 3141592654UL /* use PI as default pattern */ +#endif -static int crypthead(const char* passwd, /* password string */ - unsigned char* buf, /* where to write header */ - int bufSize, - unsigned long* pkeys, - const unsigned long* pcrc_32_tab, - unsigned long crcForCrypting) +static int crypthead(const char* passwd, /* password string */ + unsigned char* buf, /* where to write header */ + int bufSize, + unsigned long* pkeys, + const unsigned long* pcrc_32_tab, + unsigned long crcForCrypting) { - int n; /* index in random header */ - int t; /* temporary */ - int c; /* random byte */ - unsigned char header[RAND_HEAD_LEN-2]; /* random header */ - static unsigned calls = 0; /* ensure different random header each time */ + int n; /* index in random header */ + int t; /* temporary */ + int c; /* random byte */ + unsigned char header[RAND_HEAD_LEN - 2]; /* random header */ + static unsigned calls = 0; /* ensure different random header each time */ - if (bufSize> 7) & 0xff; - header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); - } - /* Encrypt random header (last two bytes is high word of crc) */ - init_keys(passwd, pkeys, pcrc_32_tab); - for (n = 0; n < RAND_HEAD_LEN-2; n++) - { - buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); - } - buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); - buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); - return n; + if (++calls == 1) + { + srand((unsigned)(time(NULL) ^ ZCR_SEED2)); + } + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN - 2; n++) + { + c = (rand() >> 7) & 0xff; + header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t); + } + /* Encrypt random header (last two bytes is high word of crc) */ + init_keys(passwd, pkeys, pcrc_32_tab); + for (n = 0; n < RAND_HEAD_LEN - 2; n++) + { + buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t); + } + buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t); + buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t); + return n; } #endif diff --git a/examples/ThirdPartyLibs/minizip/ioapi.c b/examples/ThirdPartyLibs/minizip/ioapi.c index cdf203208..f3893918c 100644 --- a/examples/ThirdPartyLibs/minizip/ioapi.c +++ b/examples/ThirdPartyLibs/minizip/ioapi.c @@ -11,236 +11,224 @@ */ #if (defined(_WIN32)) - #define _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS #endif #include "ioapi.h" -voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode) +voidpf call_zopen64(const zlib_filefunc64_32_def* pfilefunc, const void* filename, int mode) { - if (pfilefunc->zfile_func64.zopen64_file != NULL) - return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode); - else - { - return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode); - } + if (pfilefunc->zfile_func64.zopen64_file != NULL) + return (*(pfilefunc->zfile_func64.zopen64_file))(pfilefunc->zfile_func64.opaque, filename, mode); + else + { + return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque, (const char*)filename, mode); + } } -long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin) +long call_zseek64(const zlib_filefunc64_32_def* pfilefunc, voidpf filestream, ZPOS64_T offset, int origin) { - if (pfilefunc->zfile_func64.zseek64_file != NULL) - return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin); - else - { - uLong offsetTruncated = (uLong)offset; - if (offsetTruncated != offset) - return -1; - else - return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin); - } + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.zseek64_file))(pfilefunc->zfile_func64.opaque, filestream, offset, origin); + else + { + uLong offsetTruncated = (uLong)offset; + if (offsetTruncated != offset) + return -1; + else + return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque, filestream, offsetTruncated, origin); + } } -ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream) +ZPOS64_T call_ztell64(const zlib_filefunc64_32_def* pfilefunc, voidpf filestream) { - if (pfilefunc->zfile_func64.zseek64_file != NULL) - return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream); - else - { - uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream); - if ((tell_uLong) == ((uLong)-1)) - return (ZPOS64_T)-1; - else - return tell_uLong; - } + if (pfilefunc->zfile_func64.zseek64_file != NULL) + return (*(pfilefunc->zfile_func64.ztell64_file))(pfilefunc->zfile_func64.opaque, filestream); + else + { + uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque, filestream); + if ((tell_uLong) == ((uLong)-1)) + return (ZPOS64_T)-1; + else + return tell_uLong; + } } -void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32) +void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32, const zlib_filefunc_def* p_filefunc32) { - p_filefunc64_32->zfile_func64.zopen64_file = NULL; - p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; - p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; - p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; - p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; - p_filefunc64_32->zfile_func64.ztell64_file = NULL; - p_filefunc64_32->zfile_func64.zseek64_file = NULL; - p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file; - p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; - p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque; - p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file; - p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; + p_filefunc64_32->zfile_func64.zopen64_file = NULL; + p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file; + p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file; + p_filefunc64_32->zfile_func64.ztell64_file = NULL; + p_filefunc64_32->zfile_func64.zseek64_file = NULL; + p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file; + p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file; + p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque; + p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file; + p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file; } - - -static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode)); -static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); -static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size)); +static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode)); +static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size)); +static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream)); -static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); -static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream)); -static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); +static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); +static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream)); +static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream)); -static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode) +static voidpf ZCALLBACK fopen_file_func(voidpf opaque, const char* filename, int mode) { - FILE* file = NULL; - const char* mode_fopen = NULL; - if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) - mode_fopen = "rb"; - else - if (mode & ZLIB_FILEFUNC_MODE_EXISTING) - mode_fopen = "r+b"; - else - if (mode & ZLIB_FILEFUNC_MODE_CREATE) - mode_fopen = "wb"; + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; - if ((filename!=NULL) && (mode_fopen != NULL)) - file = fopen(filename, mode_fopen); - return file; + if ((filename != NULL) && (mode_fopen != NULL)) + file = fopen(filename, mode_fopen); + return file; } - -static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode) +static voidpf ZCALLBACK fopen64_file_func(voidpf opaque, const void* filename, int mode) { - FILE* file = NULL; - const char* mode_fopen = NULL; - if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ) - mode_fopen = "rb"; - else - if (mode & ZLIB_FILEFUNC_MODE_EXISTING) - mode_fopen = "r+b"; - else - if (mode & ZLIB_FILEFUNC_MODE_CREATE) - mode_fopen = "wb"; + FILE* file = NULL; + const char* mode_fopen = NULL; + if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER) == ZLIB_FILEFUNC_MODE_READ) + mode_fopen = "rb"; + else if (mode & ZLIB_FILEFUNC_MODE_EXISTING) + mode_fopen = "r+b"; + else if (mode & ZLIB_FILEFUNC_MODE_CREATE) + mode_fopen = "wb"; - if ((filename!=NULL) && (mode_fopen != NULL)) - // file = fopen64((const char*)filename, mode_fopen); - file = fopen((const char*)filename, mode_fopen); + if ((filename != NULL) && (mode_fopen != NULL)) + // file = fopen64((const char*)filename, mode_fopen); + file = fopen((const char*)filename, mode_fopen); - - return file; + return file; } - - -static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size) +static uLong ZCALLBACK fread_file_func(voidpf opaque, voidpf stream, void* buf, uLong size) { - uLong ret; - ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream); - return ret; + uLong ret; + ret = (uLong)fread(buf, 1, (size_t)size, (FILE*)stream); + return ret; } -static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size) +static uLong ZCALLBACK fwrite_file_func(voidpf opaque, voidpf stream, const void* buf, uLong size) { - uLong ret; - ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream); - return ret; + uLong ret; + ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE*)stream); + return ret; } -static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream) +static long ZCALLBACK ftell_file_func(voidpf opaque, voidpf stream) { - long ret; - ret = ftell((FILE *)stream); - return ret; + long ret; + ret = ftell((FILE*)stream); + return ret; } - -static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream) +static ZPOS64_T ZCALLBACK ftell64_file_func(voidpf opaque, voidpf stream) { - ZPOS64_T ret; - ret = ftell((FILE *)stream); + ZPOS64_T ret; + ret = ftell((FILE*)stream); // ret = ftello64((FILE *)stream); - return ret; + return ret; } -static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin) +static long ZCALLBACK fseek_file_func(voidpf opaque, voidpf stream, uLong offset, int origin) { - int fseek_origin=0; - long ret; - switch (origin) - { - case ZLIB_FILEFUNC_SEEK_CUR : - fseek_origin = SEEK_CUR; - break; - case ZLIB_FILEFUNC_SEEK_END : - fseek_origin = SEEK_END; - break; - case ZLIB_FILEFUNC_SEEK_SET : - fseek_origin = SEEK_SET; - break; - default: return -1; - } - ret = 0; - if (fseek((FILE *)stream, offset, fseek_origin) != 0) - ret = -1; - return ret; + int fseek_origin = 0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR: + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END: + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET: + fseek_origin = SEEK_SET; + break; + default: + return -1; + } + ret = 0; + if (fseek((FILE*)stream, offset, fseek_origin) != 0) + ret = -1; + return ret; } -static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) +static long ZCALLBACK fseek64_file_func(voidpf opaque, voidpf stream, ZPOS64_T offset, int origin) { - int fseek_origin=0; - long ret; - switch (origin) - { - case ZLIB_FILEFUNC_SEEK_CUR : - fseek_origin = SEEK_CUR; - break; - case ZLIB_FILEFUNC_SEEK_END : - fseek_origin = SEEK_END; - break; - case ZLIB_FILEFUNC_SEEK_SET : - fseek_origin = SEEK_SET; - break; - default: return -1; - } - ret = 0; + int fseek_origin = 0; + long ret; + switch (origin) + { + case ZLIB_FILEFUNC_SEEK_CUR: + fseek_origin = SEEK_CUR; + break; + case ZLIB_FILEFUNC_SEEK_END: + fseek_origin = SEEK_END; + break; + case ZLIB_FILEFUNC_SEEK_SET: + fseek_origin = SEEK_SET; + break; + default: + return -1; + } + ret = 0; - if(fseek((FILE *)stream, offset, fseek_origin) != 0) - -// if(fseeko64((FILE *)stream, offset, fseek_origin) != 0) - ret = -1; + if (fseek((FILE*)stream, offset, fseek_origin) != 0) - return ret; + // if(fseeko64((FILE *)stream, offset, fseek_origin) != 0) + ret = -1; + + return ret; } - -static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream) +static int ZCALLBACK fclose_file_func(voidpf opaque, voidpf stream) { - int ret; - ret = fclose((FILE *)stream); - return ret; + int ret; + ret = fclose((FILE*)stream); + return ret; } -static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream) +static int ZCALLBACK ferror_file_func(voidpf opaque, voidpf stream) { - int ret; - ret = ferror((FILE *)stream); - return ret; + int ret; + ret = ferror((FILE*)stream); + return ret; } -void fill_fopen_filefunc (pzlib_filefunc_def) - zlib_filefunc_def* pzlib_filefunc_def; +void fill_fopen_filefunc(pzlib_filefunc_def) + zlib_filefunc_def* pzlib_filefunc_def; { - pzlib_filefunc_def->zopen_file = fopen_file_func; - pzlib_filefunc_def->zread_file = fread_file_func; - pzlib_filefunc_def->zwrite_file = fwrite_file_func; - pzlib_filefunc_def->ztell_file = ftell_file_func; - pzlib_filefunc_def->zseek_file = fseek_file_func; - pzlib_filefunc_def->zclose_file = fclose_file_func; - pzlib_filefunc_def->zerror_file = ferror_file_func; - pzlib_filefunc_def->opaque = NULL; + pzlib_filefunc_def->zopen_file = fopen_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell_file = ftell_file_func; + pzlib_filefunc_def->zseek_file = fseek_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; } - -void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def) +void fill_fopen64_filefunc(zlib_filefunc64_def* pzlib_filefunc_def) { - pzlib_filefunc_def->zopen64_file = fopen64_file_func; - pzlib_filefunc_def->zread_file = fread_file_func; - pzlib_filefunc_def->zwrite_file = fwrite_file_func; - pzlib_filefunc_def->ztell64_file = ftell64_file_func; - pzlib_filefunc_def->zseek64_file = fseek64_file_func; - pzlib_filefunc_def->zclose_file = fclose_file_func; - pzlib_filefunc_def->zerror_file = ferror_file_func; - pzlib_filefunc_def->opaque = NULL; + pzlib_filefunc_def->zopen64_file = fopen64_file_func; + pzlib_filefunc_def->zread_file = fread_file_func; + pzlib_filefunc_def->zwrite_file = fwrite_file_func; + pzlib_filefunc_def->ztell64_file = ftell64_file_func; + pzlib_filefunc_def->zseek64_file = fseek64_file_func; + pzlib_filefunc_def->zclose_file = fclose_file_func; + pzlib_filefunc_def->zerror_file = ferror_file_func; + pzlib_filefunc_def->opaque = NULL; } - diff --git a/examples/ThirdPartyLibs/minizip/ioapi.h b/examples/ThirdPartyLibs/minizip/ioapi.h index 6e98495eb..bf9aac0ed 100644 --- a/examples/ThirdPartyLibs/minizip/ioapi.h +++ b/examples/ThirdPartyLibs/minizip/ioapi.h @@ -23,21 +23,21 @@ #if (!defined(_WIN32)) && (!defined(WIN32)) - // Linux needs this to support file operation on files larger then 4+GB - // But might need better if/def to select just the platforms that needs them. +// Linux needs this to support file operation on files larger then 4+GB +// But might need better if/def to select just the platforms that needs them. - #ifndef __USE_FILE_OFFSET64 - #define __USE_FILE_OFFSET64 - #endif - #ifndef __USE_LARGEFILE64 - #define __USE_LARGEFILE64 - #endif - #ifndef _LARGEFILE64_SOURCE - #define _LARGEFILE64_SOURCE - #endif - #ifndef _FILE_OFFSET_BIT - #define _FILE_OFFSET_BIT 64 - #endif +#ifndef __USE_FILE_OFFSET64 +#define __USE_FILE_OFFSET64 +#endif +#ifndef __USE_LARGEFILE64 +#define __USE_LARGEFILE64 +#endif +#ifndef _LARGEFILE64_SOURCE +#define _LARGEFILE64_SOURCE +#endif +#ifndef _FILE_OFFSET_BIT +#define _FILE_OFFSET_BIT 64 +#endif #endif #include @@ -50,14 +50,14 @@ #define fseeko64 fseek #else #ifdef _MSC_VER - #define fopen64 fopen - #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) - #define ftello64 _ftelli64 - #define fseeko64 _fseeki64 - #else // old MSC - #define ftello64 ftell - #define fseeko64 fseek - #endif +#define fopen64 fopen +#if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) +#define ftello64 _ftelli64 +#define fseeko64 _fseeki64 +#else // old MSC +#define ftello64 ftell +#define fseeko64 fseek +#endif #endif #endif @@ -78,14 +78,13 @@ /* a type choosen by DEFINE */ #ifdef HAVE_64BIT_INT_CUSTOM -typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; +typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T; #else #ifdef HAS_STDINT_H #include "stdint.h" typedef uint64_t ZPOS64_T; #else - #if defined(_MSC_VER) || defined(__BORLANDC__) typedef unsigned __int64 ZPOS64_T; #else @@ -94,104 +93,96 @@ typedef unsigned long long int ZPOS64_T; #endif #endif - - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif - #define ZLIB_FILEFUNC_SEEK_CUR (1) #define ZLIB_FILEFUNC_SEEK_END (2) #define ZLIB_FILEFUNC_SEEK_SET (0) -#define ZLIB_FILEFUNC_MODE_READ (1) -#define ZLIB_FILEFUNC_MODE_WRITE (2) +#define ZLIB_FILEFUNC_MODE_READ (1) +#define ZLIB_FILEFUNC_MODE_WRITE (2) #define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3) #define ZLIB_FILEFUNC_MODE_EXISTING (4) -#define ZLIB_FILEFUNC_MODE_CREATE (8) - +#define ZLIB_FILEFUNC_MODE_CREATE (8) #ifndef ZCALLBACK - #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK) - #define ZCALLBACK CALLBACK - #else - #define ZCALLBACK - #endif +#if (defined(WIN32) || defined(_WIN32) || defined(WINDOWS) || defined(_WINDOWS)) && defined(CALLBACK) && defined(USEWINDOWS_CALLBACK) +#define ZCALLBACK CALLBACK +#else +#define ZCALLBACK +#endif #endif + typedef voidpf(ZCALLBACK *open_file_func) OF((voidpf opaque, const char *filename, int mode)); + typedef uLong(ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void *buf, uLong size)); + typedef uLong(ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void *buf, uLong size)); + typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); + typedef int(ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); + typedef long(ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); + typedef long(ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); + /* here is the "old" 32 bits structure structure */ + typedef struct zlib_filefunc_def_s + { + open_file_func zopen_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell_file_func ztell_file; + seek_file_func zseek_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; + } zlib_filefunc_def; -typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode)); -typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size)); -typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size)); -typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream)); -typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream)); + typedef ZPOS64_T(ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); + typedef long(ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); + typedef voidpf(ZCALLBACK *open64_file_func) OF((voidpf opaque, const void *filename, int mode)); -typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream)); -typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin)); + typedef struct zlib_filefunc64_def_s + { + open64_file_func zopen64_file; + read_file_func zread_file; + write_file_func zwrite_file; + tell64_file_func ztell64_file; + seek64_file_func zseek64_file; + close_file_func zclose_file; + testerror_file_func zerror_file; + voidpf opaque; + } zlib_filefunc64_def; + void fill_fopen64_filefunc OF((zlib_filefunc64_def * pzlib_filefunc_def)); + void fill_fopen_filefunc OF((zlib_filefunc_def * pzlib_filefunc_def)); -/* here is the "old" 32 bits structure structure */ -typedef struct zlib_filefunc_def_s -{ - open_file_func zopen_file; - read_file_func zread_file; - write_file_func zwrite_file; - tell_file_func ztell_file; - seek_file_func zseek_file; - close_file_func zclose_file; - testerror_file_func zerror_file; - voidpf opaque; -} zlib_filefunc_def; + /* now internal definition, only for zip.c and unzip.h */ + typedef struct zlib_filefunc64_32_def_s + { + zlib_filefunc64_def zfile_func64; + open_file_func zopen32_file; + tell_file_func ztell32_file; + seek_file_func zseek32_file; + } zlib_filefunc64_32_def; -typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream)); -typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)); -typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode)); - -typedef struct zlib_filefunc64_def_s -{ - open64_file_func zopen64_file; - read_file_func zread_file; - write_file_func zwrite_file; - tell64_file_func ztell64_file; - seek64_file_func zseek64_file; - close_file_func zclose_file; - testerror_file_func zerror_file; - voidpf opaque; -} zlib_filefunc64_def; - -void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def)); -void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def)); - -/* now internal definition, only for zip.c and unzip.h */ -typedef struct zlib_filefunc64_32_def_s -{ - zlib_filefunc64_def zfile_func64; - open_file_func zopen32_file; - tell_file_func ztell32_file; - seek_file_func zseek32_file; -} zlib_filefunc64_32_def; - - -#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) -#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size)) +#define ZREAD64(filefunc, filestream, buf, size) ((*((filefunc).zfile_func64.zread_file))((filefunc).zfile_func64.opaque, filestream, buf, size)) +#define ZWRITE64(filefunc, filestream, buf, size) ((*((filefunc).zfile_func64.zwrite_file))((filefunc).zfile_func64.opaque, filestream, buf, size)) //#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream)) //#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode)) -#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream)) -#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream)) +#define ZCLOSE64(filefunc, filestream) ((*((filefunc).zfile_func64.zclose_file))((filefunc).zfile_func64.opaque, filestream)) +#define ZERROR64(filefunc, filestream) ((*((filefunc).zfile_func64.zerror_file))((filefunc).zfile_func64.opaque, filestream)) -voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)); -long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)); -ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)); + voidpf call_zopen64 OF((const zlib_filefunc64_32_def *pfilefunc, const void *filename, int mode)); + long call_zseek64 OF((const zlib_filefunc64_32_def *pfilefunc, voidpf filestream, ZPOS64_T offset, int origin)); + ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def *pfilefunc, voidpf filestream)); -void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32); + void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def *p_filefunc64_32, const zlib_filefunc_def *p_filefunc32); -#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode))) -#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream))) -#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode))) +#define ZOPEN64(filefunc, filename, mode) (call_zopen64((&(filefunc)), (filename), (mode))) +#define ZTELL64(filefunc, filestream) (call_ztell64((&(filefunc)), (filestream))) +#define ZSEEK64(filefunc, filestream, pos, mode) (call_zseek64((&(filefunc)), (filestream), (pos), (mode))) #ifdef __cplusplus } diff --git a/examples/ThirdPartyLibs/minizip/unzip.c b/examples/ThirdPartyLibs/minizip/unzip.c index 21878de0f..2a01b1e6d 100644 --- a/examples/ThirdPartyLibs/minizip/unzip.c +++ b/examples/ThirdPartyLibs/minizip/unzip.c @@ -63,42 +63,38 @@ */ - #include #include #include #ifndef NOUNCRYPT - #define NOUNCRYPT +#define NOUNCRYPT #endif #include "../zlib/zlib.h" #include "unzip.h" #ifdef STDC -# include -# include -# include +#include +#include +#include #endif #ifdef NO_ERRNO_H - extern int errno; +extern int errno; #else -# include +#include #endif - #ifndef local -# define local static +#define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ - #ifndef CASESENSITIVITYDEFAULT_NO -# if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) -# define CASESENSITIVITYDEFAULT_NO -# endif +#if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES) +#define CASESENSITIVITYDEFAULT_NO +#endif #endif - #ifndef UNZ_BUFSIZE #define UNZ_BUFSIZE (16384) @@ -109,90 +105,89 @@ #endif #ifndef ALLOC -# define ALLOC(size) (malloc(size)) +#define ALLOC(size) (malloc(size)) #endif #ifndef TRYFREE -# define TRYFREE(p) {if (p) free(p);} +#define TRYFREE(p) \ + { \ + if (p) free(p); \ + } #endif #define SIZECENTRALDIRITEM (0x2e) #define SIZEZIPLOCALHEADER (0x1e) - const char unz_copyright[] = - " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; + " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; /* unz_file_info_interntal contain internal info about a file in zipfile*/ typedef struct unz_file_info64_internal_s { - ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */ + ZPOS64_T offset_curfile; /* relative offset of local header 8 bytes */ } unz_file_info64_internal; - /* file_in_zip_read_info_s contain internal information about a file in zipfile, when reading and decompress it */ typedef struct { - char *read_buffer; /* internal buffer for compressed data */ - z_stream stream; /* zLib stream structure for inflate */ + char* read_buffer; /* internal buffer for compressed data */ + z_stream stream; /* zLib stream structure for inflate */ #ifdef HAVE_BZIP2 - bz_stream bstream; /* bzLib stream structure for bziped */ + bz_stream bstream; /* bzLib stream structure for bziped */ #endif - ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ - uLong stream_initialised; /* flag set if stream structure is initialised*/ + ZPOS64_T pos_in_zipfile; /* position in byte on the zipfile, for fseek*/ + uLong stream_initialised; /* flag set if stream structure is initialised*/ - ZPOS64_T offset_local_extrafield;/* offset of the local extra field */ - uInt size_local_extrafield;/* size of the local extra field */ - ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ - ZPOS64_T total_out_64; + ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ + ZPOS64_T pos_local_extrafield; /* position in the local extra field in read*/ + ZPOS64_T total_out_64; - uLong crc32; /* crc32 of all data uncompressed */ - uLong crc32_wait; /* crc32 we must obtain after decompress all */ - ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ - ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/ - zlib_filefunc64_32_def z_filefunc; - voidpf filestream; /* io structore of the zipfile */ - uLong compression_method; /* compression method (0==store) */ - ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ - int raw; + uLong crc32; /* crc32 of all data uncompressed */ + uLong crc32_wait; /* crc32 we must obtain after decompress all */ + ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */ + ZPOS64_T rest_read_uncompressed; /*number of byte to be obtained after decomp*/ + zlib_filefunc64_32_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + uLong compression_method; /* compression method (0==store) */ + ZPOS64_T byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx)*/ + int raw; } file_in_zip64_read_info_s; - /* unz64_s contain internal information about the zipfile */ typedef struct { - zlib_filefunc64_32_def z_filefunc; - int is64bitOpenFunction; - voidpf filestream; /* io structore of the zipfile */ - unz_global_info64 gi; /* public global information */ - ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ - ZPOS64_T num_file; /* number of the current file in the zipfile*/ - ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ - ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ - ZPOS64_T central_pos; /* position of the beginning of the central dir*/ + zlib_filefunc64_32_def z_filefunc; + int is64bitOpenFunction; + voidpf filestream; /* io structore of the zipfile */ + unz_global_info64 gi; /* public global information */ + ZPOS64_T byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx)*/ + ZPOS64_T num_file; /* number of the current file in the zipfile*/ + ZPOS64_T pos_in_central_dir; /* pos of the current file in the central dir*/ + ZPOS64_T current_file_ok; /* flag about the usability of the current file*/ + ZPOS64_T central_pos; /* position of the beginning of the central dir*/ - ZPOS64_T size_central_dir; /* size of the central directory */ - ZPOS64_T offset_central_dir; /* offset of start of central directory with + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory with respect to the starting disk number */ - unz_file_info64 cur_file_info; /* public info about the current file in zip*/ - unz_file_info64_internal cur_file_info_internal; /* private info about it*/ - file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current + unz_file_info64 cur_file_info; /* public info about the current file in zip*/ + unz_file_info64_internal cur_file_info_internal; /* private info about it*/ + file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current file if we are decompressing it */ - int encrypted; + int encrypted; - int isZip64; + int isZip64; -# ifndef NOUNCRYPT - unsigned long keys[3]; /* keys defining the pseudo-random sequence */ - const unsigned long* pcrc_32_tab; -# endif +#ifndef NOUNCRYPT + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; +#endif } unz64_s; - #ifndef NOUNCRYPT #include "crypt.h" #endif @@ -203,172 +198,168 @@ typedef struct IN assertion: the stream s has been sucessfully opened for reading. */ - local int unz64local_getByte OF(( - const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - int *pi)); + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + int* pi)); -local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi) +local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int* pi) { - unsigned char c; - int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); - if (err==1) - { - *pi = (int)c; - return UNZ_OK; - } - else - { - if (ZERROR64(*pzlib_filefunc_def,filestream)) - return UNZ_ERRNO; - else - return UNZ_EOF; - } + unsigned char c; + int err = (int)ZREAD64(*pzlib_filefunc_def, filestream, &c, 1); + if (err == 1) + { + *pi = (int)c; + return UNZ_OK; + } + else + { + if (ZERROR64(*pzlib_filefunc_def, filestream)) + return UNZ_ERRNO; + else + return UNZ_EOF; + } } - /* =========================================================================== Reads a long in LSB order from the given gz_stream. Sets */ local int unz64local_getShort OF(( - const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX)); + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong* pX)); -local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX) +local int unz64local_getShort(const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong* pX) { - uLong x ; - int i = 0; - int err; + uLong x; + int i = 0; + int err; - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x = (uLong)i; + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); + x = (uLong)i; - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((uLong)i)<<8; + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); + x |= ((uLong)i) << 8; - if (err==UNZ_OK) - *pX = x; - else - *pX = 0; - return err; + if (err == UNZ_OK) + *pX = x; + else + *pX = 0; + return err; } local int unz64local_getLong OF(( - const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX)); + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong* pX)); -local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - uLong *pX) +local int unz64local_getLong(const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + uLong* pX) { - uLong x ; - int i = 0; - int err; + uLong x; + int i = 0; + int err; - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x = (uLong)i; + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); + x = (uLong)i; - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((uLong)i)<<8; + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); + x |= ((uLong)i) << 8; - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((uLong)i)<<16; + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); + x |= ((uLong)i) << 16; - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<24; + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); + x += ((uLong)i) << 24; - if (err==UNZ_OK) - *pX = x; - else - *pX = 0; - return err; + if (err == UNZ_OK) + *pX = x; + else + *pX = 0; + return err; } local int unz64local_getLong64 OF(( - const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - ZPOS64_T *pX)); + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T* pX)); - -local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream, - ZPOS64_T *pX) +local int unz64local_getLong64(const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream, + ZPOS64_T* pX) { - ZPOS64_T x ; - int i = 0; - int err; + ZPOS64_T x; + int i = 0; + int err; - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x = (ZPOS64_T)i; + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); + x = (ZPOS64_T)i; - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<8; + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); + x |= ((ZPOS64_T)i) << 8; - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<16; + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); + x |= ((ZPOS64_T)i) << 16; - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<24; + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); + x |= ((ZPOS64_T)i) << 24; - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<32; + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); + x |= ((ZPOS64_T)i) << 32; - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<40; + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); + x |= ((ZPOS64_T)i) << 40; - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<48; + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); + x |= ((ZPOS64_T)i) << 48; - if (err==UNZ_OK) - err = unz64local_getByte(pzlib_filefunc_def,filestream,&i); - x |= ((ZPOS64_T)i)<<56; + if (err == UNZ_OK) + err = unz64local_getByte(pzlib_filefunc_def, filestream, &i); + x |= ((ZPOS64_T)i) << 56; - if (err==UNZ_OK) - *pX = x; - else - *pX = 0; - return err; + if (err == UNZ_OK) + *pX = x; + else + *pX = 0; + return err; } /* My own strcmpi / strcasecmp */ -local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2) +local int strcmpcasenosensitive_internal(const char* fileName1, const char* fileName2) { - for (;;) - { - char c1=*(fileName1++); - char c2=*(fileName2++); - if ((c1>='a') && (c1<='z')) - c1 -= 0x20; - if ((c2>='a') && (c2<='z')) - c2 -= 0x20; - if (c1=='\0') - return ((c2=='\0') ? 0 : -1); - if (c2=='\0') - return 1; - if (c1c2) - return 1; - } + for (;;) + { + char c1 = *(fileName1++); + char c2 = *(fileName2++); + if ((c1 >= 'a') && (c1 <= 'z')) + c1 -= 0x20; + if ((c2 >= 'a') && (c2 <= 'z')) + c2 -= 0x20; + if (c1 == '\0') + return ((c2 == '\0') ? 0 : -1); + if (c2 == '\0') + return 1; + if (c1 < c2) + return -1; + if (c1 > c2) + return 1; + } } - -#ifdef CASESENSITIVITYDEFAULT_NO +#ifdef CASESENSITIVITYDEFAULT_NO #define CASESENSITIVITYDEFAULTVALUE 2 #else #define CASESENSITIVITYDEFAULTVALUE 1 @@ -387,18 +378,18 @@ local int strcmpcasenosensitive_internal (const char* fileName1, const char* fil (like 1 on Unix, 2 on Windows) */ -extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, - const char* fileName2, - int iCaseSensitivity) +extern int ZEXPORT unzStringFileNameCompare(const char* fileName1, + const char* fileName2, + int iCaseSensitivity) { - if (iCaseSensitivity==0) - iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE; + if (iCaseSensitivity == 0) + iCaseSensitivity = CASESENSITIVITYDEFAULTVALUE; - if (iCaseSensitivity==1) - return strcmp(fileName1,fileName2); + if (iCaseSensitivity == 1) + return strcmp(fileName1, fileName2); - return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2); + return STRCMPCASENOSENTIVEFUNCTION(fileName1, fileName2); } #ifndef BUFREADCOMMENT @@ -412,164 +403,159 @@ extern int ZEXPORT unzStringFileNameCompare (const char* fileName1, local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)); local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { - unsigned char* buf; - ZPOS64_T uSizeFile; - ZPOS64_T uBackRead; - ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ - ZPOS64_T uPosFound=0; + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack = 0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound = 0; - if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; + if (ZSEEK64(*pzlib_filefunc_def, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + uSizeFile = ZTELL64(*pzlib_filefunc_def, filestream); - uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + if (uMaxBack > uSizeFile) + uMaxBack = uSizeFile; - if (uMaxBack>uSizeFile) - uMaxBack = uSizeFile; + buf = (unsigned char*)ALLOC(BUFREADCOMMENT + 4); + if (buf == NULL) + return 0; - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); - if (buf==NULL) - return 0; + uBackRead = 4; + while (uBackRead < uMaxBack) + { + uLong uReadSize; + ZPOS64_T uReadPos; + int i; + if (uBackRead + BUFREADCOMMENT > uMaxBack) + uBackRead = uMaxBack; + else + uBackRead += BUFREADCOMMENT; + uReadPos = uSizeFile - uBackRead; - uBackRead = 4; - while (uBackReaduMaxBack) - uBackRead = uMaxBack; - else - uBackRead+=BUFREADCOMMENT; - uReadPos = uSizeFile-uBackRead ; + uReadSize = ((BUFREADCOMMENT + 4) < (uSizeFile - uReadPos)) ? (BUFREADCOMMENT + 4) : (uLong)(uSizeFile - uReadPos); + if (ZSEEK64(*pzlib_filefunc_def, filestream, uReadPos, ZLIB_FILEFUNC_SEEK_SET) != 0) + break; - uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? - (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); - if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) - break; + if (ZREAD64(*pzlib_filefunc_def, filestream, buf, uReadSize) != uReadSize) + break; - if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) - break; + for (i = (int)uReadSize - 3; (i--) > 0;) + if (((*(buf + i)) == 0x50) && ((*(buf + i + 1)) == 0x4b) && + ((*(buf + i + 2)) == 0x05) && ((*(buf + i + 3)) == 0x06)) + { + uPosFound = uReadPos + i; + break; + } - for (i=(int)uReadSize-3; (i--)>0;) - if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && - ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) - { - uPosFound = uReadPos+i; - break; - } - - if (uPosFound!=0) - break; - } - TRYFREE(buf); - return uPosFound; + if (uPosFound != 0) + break; + } + TRYFREE(buf); + return uPosFound; } - /* Locate the Central directory 64 of a zipfile (at the end, just before the global comment) */ local ZPOS64_T unz64local_SearchCentralDir64 OF(( - const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream)); + const zlib_filefunc64_32_def* pzlib_filefunc_def, + voidpf filestream)); local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, - voidpf filestream) + voidpf filestream) { - unsigned char* buf; - ZPOS64_T uSizeFile; - ZPOS64_T uBackRead; - ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ - ZPOS64_T uPosFound=0; - uLong uL; - ZPOS64_T relativeOffset; + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack = 0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound = 0; + uLong uL; + ZPOS64_T relativeOffset; - if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; + if (ZSEEK64(*pzlib_filefunc_def, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + uSizeFile = ZTELL64(*pzlib_filefunc_def, filestream); - uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + if (uMaxBack > uSizeFile) + uMaxBack = uSizeFile; - if (uMaxBack>uSizeFile) - uMaxBack = uSizeFile; + buf = (unsigned char*)ALLOC(BUFREADCOMMENT + 4); + if (buf == NULL) + return 0; - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); - if (buf==NULL) - return 0; + uBackRead = 4; + while (uBackRead < uMaxBack) + { + uLong uReadSize; + ZPOS64_T uReadPos; + int i; + if (uBackRead + BUFREADCOMMENT > uMaxBack) + uBackRead = uMaxBack; + else + uBackRead += BUFREADCOMMENT; + uReadPos = uSizeFile - uBackRead; - uBackRead = 4; - while (uBackReaduMaxBack) - uBackRead = uMaxBack; - else - uBackRead+=BUFREADCOMMENT; - uReadPos = uSizeFile-uBackRead ; + uReadSize = ((BUFREADCOMMENT + 4) < (uSizeFile - uReadPos)) ? (BUFREADCOMMENT + 4) : (uLong)(uSizeFile - uReadPos); + if (ZSEEK64(*pzlib_filefunc_def, filestream, uReadPos, ZLIB_FILEFUNC_SEEK_SET) != 0) + break; - uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? - (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); - if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) - break; + if (ZREAD64(*pzlib_filefunc_def, filestream, buf, uReadSize) != uReadSize) + break; - if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) - break; + for (i = (int)uReadSize - 3; (i--) > 0;) + if (((*(buf + i)) == 0x50) && ((*(buf + i + 1)) == 0x4b) && + ((*(buf + i + 2)) == 0x06) && ((*(buf + i + 3)) == 0x07)) + { + uPosFound = uReadPos + i; + break; + } - for (i=(int)uReadSize-3; (i--)>0;) - if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && - ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) - { - uPosFound = uReadPos+i; - break; - } + if (uPosFound != 0) + break; + } + TRYFREE(buf); + if (uPosFound == 0) + return 0; - if (uPosFound!=0) - break; - } - TRYFREE(buf); - if (uPosFound == 0) - return 0; + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def, filestream, uPosFound, ZLIB_FILEFUNC_SEEK_SET) != 0) + return 0; - /* Zip64 end of central directory locator */ - if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) - return 0; + /* the signature, already checked */ + if (unz64local_getLong(pzlib_filefunc_def, filestream, &uL) != UNZ_OK) + return 0; - /* the signature, already checked */ - if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) - return 0; + /* number of the disk with the start of the zip64 end of central directory */ + if (unz64local_getLong(pzlib_filefunc_def, filestream, &uL) != UNZ_OK) + return 0; + if (uL != 0) + return 0; - /* number of the disk with the start of the zip64 end of central directory */ - if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) - return 0; - if (uL != 0) - return 0; + /* relative offset of the zip64 end of central directory record */ + if (unz64local_getLong64(pzlib_filefunc_def, filestream, &relativeOffset) != UNZ_OK) + return 0; - /* relative offset of the zip64 end of central directory record */ - if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK) - return 0; + /* total number of disks */ + if (unz64local_getLong(pzlib_filefunc_def, filestream, &uL) != UNZ_OK) + return 0; + if (uL != 1) + return 0; - /* total number of disks */ - if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) - return 0; - if (uL != 1) - return 0; + /* Goto end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def, filestream, relativeOffset, ZLIB_FILEFUNC_SEEK_SET) != 0) + return 0; - /* Goto end of central directory record */ - if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) - return 0; + /* the signature */ + if (unz64local_getLong(pzlib_filefunc_def, filestream, &uL) != UNZ_OK) + return 0; - /* the signature */ - if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK) - return 0; + if (uL != 0x06064b50) + return 0; - if (uL != 0x06064b50) - return 0; - - return relativeOffset; + return relativeOffset; } /* @@ -581,223 +567,219 @@ local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib Else, the return value is a unzFile Handle, usable with other function of this unzip package. */ -local unzFile unzOpenInternal (const void *path, - zlib_filefunc64_32_def* pzlib_filefunc64_32_def, - int is64bitOpenFunction) +local unzFile unzOpenInternal(const void* path, + zlib_filefunc64_32_def* pzlib_filefunc64_32_def, + int is64bitOpenFunction) { - unz64_s us; - unz64_s *s; - ZPOS64_T central_pos; - uLong uL; + unz64_s us; + unz64_s* s; + ZPOS64_T central_pos; + uLong uL; - uLong number_disk; /* number of the current dist, used for + uLong number_disk; /* number of the current dist, used for spaning ZIP, unsupported, always 0*/ - uLong number_disk_with_CD; /* number the the disk with central dir, used + uLong number_disk_with_CD; /* number the the disk with central dir, used for spaning ZIP, unsupported, always 0*/ - ZPOS64_T number_entry_CD; /* total number of entries in + ZPOS64_T number_entry_CD; /* total number of entries in the central dir (same than number_entry on nospan) */ - int err=UNZ_OK; + int err = UNZ_OK; - if (unz_copyright[0]!=' ') - return NULL; + if (unz_copyright[0] != ' ') + return NULL; - us.z_filefunc.zseek32_file = NULL; - us.z_filefunc.ztell32_file = NULL; - if (pzlib_filefunc64_32_def==NULL) - fill_fopen64_filefunc(&us.z_filefunc.zfile_func64); - else - us.z_filefunc = *pzlib_filefunc64_32_def; - us.is64bitOpenFunction = is64bitOpenFunction; + us.z_filefunc.zseek32_file = NULL; + us.z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def == NULL) + fill_fopen64_filefunc(&us.z_filefunc.zfile_func64); + else + us.z_filefunc = *pzlib_filefunc64_32_def; + us.is64bitOpenFunction = is64bitOpenFunction; + us.filestream = ZOPEN64(us.z_filefunc, + path, + ZLIB_FILEFUNC_MODE_READ | + ZLIB_FILEFUNC_MODE_EXISTING); + if (us.filestream == NULL) + return NULL; + central_pos = unz64local_SearchCentralDir64(&us.z_filefunc, us.filestream); + if (central_pos) + { + uLong uS; + ZPOS64_T uL64; - us.filestream = ZOPEN64(us.z_filefunc, - path, - ZLIB_FILEFUNC_MODE_READ | - ZLIB_FILEFUNC_MODE_EXISTING); - if (us.filestream==NULL) - return NULL; + us.isZip64 = 1; - central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream); - if (central_pos) - { - uLong uS; - ZPOS64_T uL64; + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) + err = UNZ_ERRNO; - us.isZip64 = 1; + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; - if (ZSEEK64(us.z_filefunc, us.filestream, - central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) - err=UNZ_ERRNO; + /* size of zip64 end of central directory record */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream, &uL64) != UNZ_OK) + err = UNZ_ERRNO; - /* the signature, already checked */ - if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) - err=UNZ_ERRNO; + /* version made by */ + if (unz64local_getShort(&us.z_filefunc, us.filestream, &uS) != UNZ_OK) + err = UNZ_ERRNO; - /* size of zip64 end of central directory record */ - if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK) - err=UNZ_ERRNO; + /* version needed to extract */ + if (unz64local_getShort(&us.z_filefunc, us.filestream, &uS) != UNZ_OK) + err = UNZ_ERRNO; - /* version made by */ - if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) - err=UNZ_ERRNO; + /* number of this disk */ + if (unz64local_getLong(&us.z_filefunc, us.filestream, &number_disk) != UNZ_OK) + err = UNZ_ERRNO; - /* version needed to extract */ - if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK) - err=UNZ_ERRNO; + /* number of the disk with the start of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream, &number_disk_with_CD) != UNZ_OK) + err = UNZ_ERRNO; - /* number of this disk */ - if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) - err=UNZ_ERRNO; + /* total number of entries in the central directory on this disk */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream, &us.gi.number_entry) != UNZ_OK) + err = UNZ_ERRNO; - /* number of the disk with the start of the central directory */ - if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) - err=UNZ_ERRNO; + /* total number of entries in the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream, &number_entry_CD) != UNZ_OK) + err = UNZ_ERRNO; - /* total number of entries in the central directory on this disk */ - if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK) - err=UNZ_ERRNO; + if ((number_entry_CD != us.gi.number_entry) || + (number_disk_with_CD != 0) || + (number_disk != 0)) + err = UNZ_BADZIPFILE; - /* total number of entries in the central directory */ - if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK) - err=UNZ_ERRNO; + /* size of the central directory */ + if (unz64local_getLong64(&us.z_filefunc, us.filestream, &us.size_central_dir) != UNZ_OK) + err = UNZ_ERRNO; - if ((number_entry_CD!=us.gi.number_entry) || - (number_disk_with_CD!=0) || - (number_disk!=0)) - err=UNZ_BADZIPFILE; - - /* size of the central directory */ - if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK) - err=UNZ_ERRNO; - - /* offset of start of central directory with respect to the + /* offset of start of central directory with respect to the starting disk number */ - if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK) - err=UNZ_ERRNO; + if (unz64local_getLong64(&us.z_filefunc, us.filestream, &us.offset_central_dir) != UNZ_OK) + err = UNZ_ERRNO; - us.gi.size_comment = 0; - } - else - { - central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream); - if (central_pos==0) - err=UNZ_ERRNO; + us.gi.size_comment = 0; + } + else + { + central_pos = unz64local_SearchCentralDir(&us.z_filefunc, us.filestream); + if (central_pos == 0) + err = UNZ_ERRNO; - us.isZip64 = 0; + us.isZip64 = 0; - if (ZSEEK64(us.z_filefunc, us.filestream, - central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) - err=UNZ_ERRNO; + if (ZSEEK64(us.z_filefunc, us.filestream, + central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) + err = UNZ_ERRNO; - /* the signature, already checked */ - if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) - err=UNZ_ERRNO; + /* the signature, already checked */ + if (unz64local_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; - /* number of this disk */ - if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK) - err=UNZ_ERRNO; + /* number of this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream, &number_disk) != UNZ_OK) + err = UNZ_ERRNO; - /* number of the disk with the start of the central directory */ - if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK) - err=UNZ_ERRNO; + /* number of the disk with the start of the central directory */ + if (unz64local_getShort(&us.z_filefunc, us.filestream, &number_disk_with_CD) != UNZ_OK) + err = UNZ_ERRNO; - /* total number of entries in the central dir on this disk */ - if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) - err=UNZ_ERRNO; - us.gi.number_entry = uL; + /* total number of entries in the central dir on this disk */ + if (unz64local_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; + us.gi.number_entry = uL; - /* total number of entries in the central dir */ - if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) - err=UNZ_ERRNO; - number_entry_CD = uL; + /* total number of entries in the central dir */ + if (unz64local_getShort(&us.z_filefunc, us.filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; + number_entry_CD = uL; - if ((number_entry_CD!=us.gi.number_entry) || - (number_disk_with_CD!=0) || - (number_disk!=0)) - err=UNZ_BADZIPFILE; + if ((number_entry_CD != us.gi.number_entry) || + (number_disk_with_CD != 0) || + (number_disk != 0)) + err = UNZ_BADZIPFILE; - /* size of the central directory */ - if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) - err=UNZ_ERRNO; - us.size_central_dir = uL; + /* size of the central directory */ + if (unz64local_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; + us.size_central_dir = uL; - /* offset of start of central directory with respect to the + /* offset of start of central directory with respect to the starting disk number */ - if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK) - err=UNZ_ERRNO; - us.offset_central_dir = uL; + if (unz64local_getLong(&us.z_filefunc, us.filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; + us.offset_central_dir = uL; - /* zipfile comment length */ - if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK) - err=UNZ_ERRNO; - } + /* zipfile comment length */ + if (unz64local_getShort(&us.z_filefunc, us.filestream, &us.gi.size_comment) != UNZ_OK) + err = UNZ_ERRNO; + } - if ((central_pospfile_in_zip_read!=NULL) - unzCloseCurrentFile(file); + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); - ZCLOSE64(s->z_filefunc, s->filestream); - TRYFREE(s); - return UNZ_OK; + ZCLOSE64(s->z_filefunc, s->filestream); + TRYFREE(s); + return UNZ_OK; } - /* Write info about the ZipFile in the *pglobal_info structure. No preparation of the structure is needed return UNZ_OK if there is no problem. */ -extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info) +extern int ZEXPORT unzGetGlobalInfo64(unzFile file, unz_global_info64* pglobal_info) { - unz64_s* s; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - *pglobal_info=s->gi; - return UNZ_OK; + unz64_s* s; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; + *pglobal_info = s->gi; + return UNZ_OK; } -extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32) +extern int ZEXPORT unzGetGlobalInfo(unzFile file, unz_global_info* pglobal_info32) { - unz64_s* s; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - /* to do : check if number_entry is not truncated */ - pglobal_info32->number_entry = (uLong)s->gi.number_entry; - pglobal_info32->size_comment = s->gi.size_comment; - return UNZ_OK; + unz64_s* s; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; + /* to do : check if number_entry is not truncated */ + pglobal_info32->number_entry = (uLong)s->gi.number_entry; + pglobal_info32->size_comment = s->gi.size_comment; + return UNZ_OK; } /* Translate date/time from Dos format to tm_unz (readable more easilty) */ -local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm) +local void unz64local_DosDateToTmuDate(ZPOS64_T ulDosDate, tm_unz* ptm) { - ZPOS64_T uDate; - uDate = (ZPOS64_T)(ulDosDate>>16); - ptm->tm_mday = (uInt)(uDate&0x1f) ; - ptm->tm_mon = (uInt)((((uDate)&0x1E0)/0x20)-1) ; - ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ; + ZPOS64_T uDate; + uDate = (ZPOS64_T)(ulDosDate >> 16); + ptm->tm_mday = (uInt)(uDate & 0x1f); + ptm->tm_mon = (uInt)((((uDate)&0x1E0) / 0x20) - 1); + ptm->tm_year = (uInt)(((uDate & 0x0FE00) / 0x0200) + 1980); - ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800); - ptm->tm_min = (uInt) ((ulDosDate&0x7E0)/0x20) ; - ptm->tm_sec = (uInt) (2*(ulDosDate&0x1f)) ; + ptm->tm_hour = (uInt)((ulDosDate & 0xF800) / 0x800); + ptm->tm_min = (uInt)((ulDosDate & 0x7E0) / 0x20); + ptm->tm_sec = (uInt)(2 * (ulDosDate & 0x1f)); } /* Get Info about the current file in the zipfile, with internal only info */ local int unz64local_GetCurrentFileInfoInternal OF((unzFile file, - unz_file_info64 *pfile_info, - unz_file_info64_internal - *pfile_info_internal, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize)); + unz_file_info64* pfile_info, + unz_file_info64_internal* pfile_info_internal, + char* szFileName, + uLong fileNameBufferSize, + void* extraField, + uLong extraFieldBufferSize, + char* szComment, + uLong commentBufferSize)); -local int unz64local_GetCurrentFileInfoInternal (unzFile file, - unz_file_info64 *pfile_info, - unz_file_info64_internal - *pfile_info_internal, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize) +local int unz64local_GetCurrentFileInfoInternal(unzFile file, + unz_file_info64* pfile_info, + unz_file_info64_internal* pfile_info_internal, + char* szFileName, + uLong fileNameBufferSize, + void* extraField, + uLong extraFieldBufferSize, + char* szComment, + uLong commentBufferSize) { - unz64_s* s; - unz_file_info64 file_info; - unz_file_info64_internal file_info_internal; - int err=UNZ_OK; - uLong uMagic; - long lSeek=0; - uLong uL; + unz64_s* s; + unz_file_info64 file_info; + unz_file_info64_internal file_info_internal; + int err = UNZ_OK; + uLong uMagic; + long lSeek = 0; + uLong uL; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - if (ZSEEK64(s->z_filefunc, s->filestream, - s->pos_in_central_dir+s->byte_before_the_zipfile, - ZLIB_FILEFUNC_SEEK_SET)!=0) - err=UNZ_ERRNO; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pos_in_central_dir + s->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET) != 0) + err = UNZ_ERRNO; + /* we check the magic */ + if (err == UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream, &uMagic) != UNZ_OK) + err = UNZ_ERRNO; + else if (uMagic != 0x02014b50) + err = UNZ_BADZIPFILE; + } - /* we check the magic */ - if (err==UNZ_OK) - { - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) - err=UNZ_ERRNO; - else if (uMagic!=0x02014b50) - err=UNZ_BADZIPFILE; - } + if (unz64local_getShort(&s->z_filefunc, s->filestream, &file_info.version) != UNZ_OK) + err = UNZ_ERRNO; - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK) - err=UNZ_ERRNO; + if (unz64local_getShort(&s->z_filefunc, s->filestream, &file_info.version_needed) != UNZ_OK) + err = UNZ_ERRNO; - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK) - err=UNZ_ERRNO; + if (unz64local_getShort(&s->z_filefunc, s->filestream, &file_info.flag) != UNZ_OK) + err = UNZ_ERRNO; - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK) - err=UNZ_ERRNO; + if (unz64local_getShort(&s->z_filefunc, s->filestream, &file_info.compression_method) != UNZ_OK) + err = UNZ_ERRNO; - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK) - err=UNZ_ERRNO; + if (unz64local_getLong(&s->z_filefunc, s->filestream, &file_info.dosDate) != UNZ_OK) + err = UNZ_ERRNO; - if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK) - err=UNZ_ERRNO; + unz64local_DosDateToTmuDate(file_info.dosDate, &file_info.tmu_date); - unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date); + if (unz64local_getLong(&s->z_filefunc, s->filestream, &file_info.crc) != UNZ_OK) + err = UNZ_ERRNO; - if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK) - err=UNZ_ERRNO; + if (unz64local_getLong(&s->z_filefunc, s->filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; + file_info.compressed_size = uL; - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) - err=UNZ_ERRNO; - file_info.compressed_size = uL; + if (unz64local_getLong(&s->z_filefunc, s->filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; + file_info.uncompressed_size = uL; - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) - err=UNZ_ERRNO; - file_info.uncompressed_size = uL; + if (unz64local_getShort(&s->z_filefunc, s->filestream, &file_info.size_filename) != UNZ_OK) + err = UNZ_ERRNO; - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK) - err=UNZ_ERRNO; + if (unz64local_getShort(&s->z_filefunc, s->filestream, &file_info.size_file_extra) != UNZ_OK) + err = UNZ_ERRNO; - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK) - err=UNZ_ERRNO; + if (unz64local_getShort(&s->z_filefunc, s->filestream, &file_info.size_file_comment) != UNZ_OK) + err = UNZ_ERRNO; - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK) - err=UNZ_ERRNO; + if (unz64local_getShort(&s->z_filefunc, s->filestream, &file_info.disk_num_start) != UNZ_OK) + err = UNZ_ERRNO; - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK) - err=UNZ_ERRNO; + if (unz64local_getShort(&s->z_filefunc, s->filestream, &file_info.internal_fa) != UNZ_OK) + err = UNZ_ERRNO; - if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK) - err=UNZ_ERRNO; + if (unz64local_getLong(&s->z_filefunc, s->filestream, &file_info.external_fa) != UNZ_OK) + err = UNZ_ERRNO; - if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK) - err=UNZ_ERRNO; + // relative offset of local header + if (unz64local_getLong(&s->z_filefunc, s->filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; + file_info_internal.offset_curfile = uL; - // relative offset of local header - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) - err=UNZ_ERRNO; - file_info_internal.offset_curfile = uL; + lSeek += file_info.size_filename; + if ((err == UNZ_OK) && (szFileName != NULL)) + { + uLong uSizeRead; + if (file_info.size_filename < fileNameBufferSize) + { + *(szFileName + file_info.size_filename) = '\0'; + uSizeRead = file_info.size_filename; + } + else + uSizeRead = fileNameBufferSize; - lSeek+=file_info.size_filename; - if ((err==UNZ_OK) && (szFileName!=NULL)) - { - uLong uSizeRead ; - if (file_info.size_filename 0) && (fileNameBufferSize > 0)) + if (ZREAD64(s->z_filefunc, s->filestream, szFileName, uSizeRead) != uSizeRead) + err = UNZ_ERRNO; + lSeek -= uSizeRead; + } - if ((file_info.size_filename>0) && (fileNameBufferSize>0)) - if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; - lSeek -= uSizeRead; - } + // Read extrafield + if ((err == UNZ_OK) && (extraField != NULL)) + { + ZPOS64_T uSizeRead; + if (file_info.size_file_extra < extraFieldBufferSize) + uSizeRead = file_info.size_file_extra; + else + uSizeRead = extraFieldBufferSize; - // Read extrafield - if ((err==UNZ_OK) && (extraField!=NULL)) - { - ZPOS64_T uSizeRead ; - if (file_info.size_file_extraz_filefunc, s->filestream, lSeek, ZLIB_FILEFUNC_SEEK_CUR) == 0) + lSeek = 0; + else + err = UNZ_ERRNO; + } - if (lSeek!=0) - { - if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) - lSeek=0; - else - err=UNZ_ERRNO; - } + if ((file_info.size_file_extra > 0) && (extraFieldBufferSize > 0)) + if (ZREAD64(s->z_filefunc, s->filestream, extraField, (uLong)uSizeRead) != uSizeRead) + err = UNZ_ERRNO; - if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0)) - if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; + lSeek += file_info.size_file_extra - (uLong)uSizeRead; + } + else + lSeek += file_info.size_file_extra; - lSeek += file_info.size_file_extra - (uLong)uSizeRead; - } - else - lSeek += file_info.size_file_extra; + if ((err == UNZ_OK) && (file_info.size_file_extra != 0)) + { + uLong acc = 0; + // since lSeek now points to after the extra field we need to move back + lSeek -= file_info.size_file_extra; - if ((err==UNZ_OK) && (file_info.size_file_extra != 0)) - { - uLong acc = 0; + if (lSeek != 0) + { + if (ZSEEK64(s->z_filefunc, s->filestream, lSeek, ZLIB_FILEFUNC_SEEK_CUR) == 0) + lSeek = 0; + else + err = UNZ_ERRNO; + } - // since lSeek now points to after the extra field we need to move back - lSeek -= file_info.size_file_extra; + while (acc < file_info.size_file_extra) + { + uLong headerId; + uLong dataSize; - if (lSeek!=0) - { - if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) - lSeek=0; - else - err=UNZ_ERRNO; - } + if (unz64local_getShort(&s->z_filefunc, s->filestream, &headerId) != UNZ_OK) + err = UNZ_ERRNO; - while(acc < file_info.size_file_extra) - { - uLong headerId; - uLong dataSize; + if (unz64local_getShort(&s->z_filefunc, s->filestream, &dataSize) != UNZ_OK) + err = UNZ_ERRNO; - if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK) - err=UNZ_ERRNO; + /* ZIP64 extra fields */ + if (headerId == 0x0001) + { + uLong uL; - if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK) - err=UNZ_ERRNO; + if (file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream, &file_info.uncompressed_size) != UNZ_OK) + err = UNZ_ERRNO; + } - /* ZIP64 extra fields */ - if (headerId == 0x0001) - { - uLong uL; + if (file_info.compressed_size == (ZPOS64_T)(unsigned long)-1) + { + if (unz64local_getLong64(&s->z_filefunc, s->filestream, &file_info.compressed_size) != UNZ_OK) + err = UNZ_ERRNO; + } - if(file_info.uncompressed_size == (ZPOS64_T)(unsigned long)-1) - { - if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK) - err=UNZ_ERRNO; - } + if (file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1) + { + /* Relative Header offset */ + if (unz64local_getLong64(&s->z_filefunc, s->filestream, &file_info_internal.offset_curfile) != UNZ_OK) + err = UNZ_ERRNO; + } - if(file_info.compressed_size == (ZPOS64_T)(unsigned long)-1) - { - if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK) - err=UNZ_ERRNO; - } + if (file_info.disk_num_start == (unsigned long)-1) + { + /* Disk Start Number */ + if (unz64local_getLong(&s->z_filefunc, s->filestream, &uL) != UNZ_OK) + err = UNZ_ERRNO; + } + } + else + { + if (ZSEEK64(s->z_filefunc, s->filestream, dataSize, ZLIB_FILEFUNC_SEEK_CUR) != 0) + err = UNZ_ERRNO; + } - if(file_info_internal.offset_curfile == (ZPOS64_T)(unsigned long)-1) - { - /* Relative Header offset */ - if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK) - err=UNZ_ERRNO; - } + acc += 2 + 2 + dataSize; + } + } - if(file_info.disk_num_start == (unsigned long)-1) - { - /* Disk Start Number */ - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK) - err=UNZ_ERRNO; - } + if ((err == UNZ_OK) && (szComment != NULL)) + { + uLong uSizeRead; + if (file_info.size_file_comment < commentBufferSize) + { + *(szComment + file_info.size_file_comment) = '\0'; + uSizeRead = file_info.size_file_comment; + } + else + uSizeRead = commentBufferSize; - } - else - { - if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0) - err=UNZ_ERRNO; - } + if (lSeek != 0) + { + if (ZSEEK64(s->z_filefunc, s->filestream, lSeek, ZLIB_FILEFUNC_SEEK_CUR) == 0) + lSeek = 0; + else + err = UNZ_ERRNO; + } - acc += 2 + 2 + dataSize; - } - } + if ((file_info.size_file_comment > 0) && (commentBufferSize > 0)) + if (ZREAD64(s->z_filefunc, s->filestream, szComment, uSizeRead) != uSizeRead) + err = UNZ_ERRNO; + lSeek += file_info.size_file_comment - uSizeRead; + } + else + lSeek += file_info.size_file_comment; - if ((err==UNZ_OK) && (szComment!=NULL)) - { - uLong uSizeRead ; - if (file_info.size_file_commentz_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0) - lSeek=0; - else - err=UNZ_ERRNO; - } + if ((err == UNZ_OK) && (pfile_info_internal != NULL)) + *pfile_info_internal = file_info_internal; - if ((file_info.size_file_comment>0) && (commentBufferSize>0)) - if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead) - err=UNZ_ERRNO; - lSeek+=file_info.size_file_comment - uSizeRead; - } - else - lSeek+=file_info.size_file_comment; - - - if ((err==UNZ_OK) && (pfile_info!=NULL)) - *pfile_info=file_info; - - if ((err==UNZ_OK) && (pfile_info_internal!=NULL)) - *pfile_info_internal=file_info_internal; - - return err; + return err; } - - /* Write info about the ZipFile in the *pglobal_info structure. No preparation of the structure is needed return UNZ_OK if there is no problem. */ -extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file, - unz_file_info64 * pfile_info, - char * szFileName, uLong fileNameBufferSize, - void *extraField, uLong extraFieldBufferSize, - char* szComment, uLong commentBufferSize) +extern int ZEXPORT unzGetCurrentFileInfo64(unzFile file, + unz_file_info64* pfile_info, + char* szFileName, uLong fileNameBufferSize, + void* extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) { - return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL, - szFileName,fileNameBufferSize, - extraField,extraFieldBufferSize, - szComment,commentBufferSize); + return unz64local_GetCurrentFileInfoInternal(file, pfile_info, NULL, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize); } -extern int ZEXPORT unzGetCurrentFileInfo (unzFile file, - unz_file_info * pfile_info, - char * szFileName, uLong fileNameBufferSize, - void *extraField, uLong extraFieldBufferSize, - char* szComment, uLong commentBufferSize) +extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, + unz_file_info* pfile_info, + char* szFileName, uLong fileNameBufferSize, + void* extraField, uLong extraFieldBufferSize, + char* szComment, uLong commentBufferSize) { - int err; - unz_file_info64 file_info64; - err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL, - szFileName,fileNameBufferSize, - extraField,extraFieldBufferSize, - szComment,commentBufferSize); - if (err==UNZ_OK) - { - pfile_info->version = file_info64.version; - pfile_info->version_needed = file_info64.version_needed; - pfile_info->flag = file_info64.flag; - pfile_info->compression_method = file_info64.compression_method; - pfile_info->dosDate = file_info64.dosDate; - pfile_info->crc = file_info64.crc; + int err; + unz_file_info64 file_info64; + err = unz64local_GetCurrentFileInfoInternal(file, &file_info64, NULL, + szFileName, fileNameBufferSize, + extraField, extraFieldBufferSize, + szComment, commentBufferSize); + if (err == UNZ_OK) + { + pfile_info->version = file_info64.version; + pfile_info->version_needed = file_info64.version_needed; + pfile_info->flag = file_info64.flag; + pfile_info->compression_method = file_info64.compression_method; + pfile_info->dosDate = file_info64.dosDate; + pfile_info->crc = file_info64.crc; - pfile_info->size_filename = file_info64.size_filename; - pfile_info->size_file_extra = file_info64.size_file_extra; - pfile_info->size_file_comment = file_info64.size_file_comment; + pfile_info->size_filename = file_info64.size_filename; + pfile_info->size_file_extra = file_info64.size_file_extra; + pfile_info->size_file_comment = file_info64.size_file_comment; - pfile_info->disk_num_start = file_info64.disk_num_start; - pfile_info->internal_fa = file_info64.internal_fa; - pfile_info->external_fa = file_info64.external_fa; + pfile_info->disk_num_start = file_info64.disk_num_start; + pfile_info->internal_fa = file_info64.internal_fa; + pfile_info->external_fa = file_info64.external_fa; - pfile_info->tmu_date = file_info64.tmu_date, + pfile_info->tmu_date = file_info64.tmu_date, - - pfile_info->compressed_size = (uLong)file_info64.compressed_size; - pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; - - } - return err; + pfile_info->compressed_size = (uLong)file_info64.compressed_size; + pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size; + } + return err; } /* Set the current file of the zipfile to the first file. return UNZ_OK if there is no problem */ -extern int ZEXPORT unzGoToFirstFile (unzFile file) +extern int ZEXPORT unzGoToFirstFile(unzFile file) { - int err=UNZ_OK; - unz64_s* s; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - s->pos_in_central_dir=s->offset_central_dir; - s->num_file=0; - err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; + int err = UNZ_OK; + unz64_s* s; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; + s->pos_in_central_dir = s->offset_central_dir; + s->num_file = 0; + err = unz64local_GetCurrentFileInfoInternal(file, &s->cur_file_info, + &s->cur_file_info_internal, + NULL, 0, NULL, 0, NULL, 0); + s->current_file_ok = (err == UNZ_OK); + return err; } /* @@ -1196,31 +1167,30 @@ extern int ZEXPORT unzGoToFirstFile (unzFile file) return UNZ_OK if there is no problem return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. */ -extern int ZEXPORT unzGoToNextFile (unzFile file) +extern int ZEXPORT unzGoToNextFile(unzFile file) { - unz64_s* s; - int err; + unz64_s* s; + int err; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; - if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ - if (s->num_file+1==s->gi.number_entry) - return UNZ_END_OF_LIST_OF_FILE; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; + if (s->gi.number_entry != 0xffff) /* 2^16 files overflow hack */ + if (s->num_file + 1 == s->gi.number_entry) + return UNZ_END_OF_LIST_OF_FILE; - s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + - s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ; - s->num_file++; - err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; + s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename + + s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment; + s->num_file++; + err = unz64local_GetCurrentFileInfoInternal(file, &s->cur_file_info, + &s->cur_file_info_internal, + NULL, 0, NULL, 0, NULL, 0); + s->current_file_ok = (err == UNZ_OK); + return err; } - /* Try locate the file szFileName in the zipfile. For the iCaseSensitivity signification, see unzipStringFileNameCompare @@ -1229,64 +1199,62 @@ extern int ZEXPORT unzGoToNextFile (unzFile file) UNZ_OK if the file is found. It becomes the current file. UNZ_END_OF_LIST_OF_FILE if the file is not found */ -extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity) +extern int ZEXPORT unzLocateFile(unzFile file, const char* szFileName, int iCaseSensitivity) { - unz64_s* s; - int err; + unz64_s* s; + int err; - /* We remember the 'current' position in the file so that we can jump + /* We remember the 'current' position in the file so that we can jump * back there if we fail. */ - unz_file_info64 cur_file_infoSaved; - unz_file_info64_internal cur_file_info_internalSaved; - ZPOS64_T num_fileSaved; - ZPOS64_T pos_in_central_dirSaved; + unz_file_info64 cur_file_infoSaved; + unz_file_info64_internal cur_file_info_internalSaved; + ZPOS64_T num_fileSaved; + ZPOS64_T pos_in_central_dirSaved; + if (file == NULL) + return UNZ_PARAMERROR; - if (file==NULL) - return UNZ_PARAMERROR; + if (strlen(szFileName) >= UNZ_MAXFILENAMEINZIP) + return UNZ_PARAMERROR; - if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP) - return UNZ_PARAMERROR; + s = (unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; - s=(unz64_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; + /* Save the current state */ + num_fileSaved = s->num_file; + pos_in_central_dirSaved = s->pos_in_central_dir; + cur_file_infoSaved = s->cur_file_info; + cur_file_info_internalSaved = s->cur_file_info_internal; - /* Save the current state */ - num_fileSaved = s->num_file; - pos_in_central_dirSaved = s->pos_in_central_dir; - cur_file_infoSaved = s->cur_file_info; - cur_file_info_internalSaved = s->cur_file_info_internal; + err = unzGoToFirstFile(file); - err = unzGoToFirstFile(file); + while (err == UNZ_OK) + { + char szCurrentFileName[UNZ_MAXFILENAMEINZIP + 1]; + err = unzGetCurrentFileInfo64(file, NULL, + szCurrentFileName, sizeof(szCurrentFileName) - 1, + NULL, 0, NULL, 0); + if (err == UNZ_OK) + { + if (unzStringFileNameCompare(szCurrentFileName, + szFileName, iCaseSensitivity) == 0) + return UNZ_OK; + err = unzGoToNextFile(file); + } + } - while (err == UNZ_OK) - { - char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1]; - err = unzGetCurrentFileInfo64(file,NULL, - szCurrentFileName,sizeof(szCurrentFileName)-1, - NULL,0,NULL,0); - if (err == UNZ_OK) - { - if (unzStringFileNameCompare(szCurrentFileName, - szFileName,iCaseSensitivity)==0) - return UNZ_OK; - err = unzGoToNextFile(file); - } - } - - /* We failed, so restore the state of the 'current file' to where we + /* We failed, so restore the state of the 'current file' to where we * were. */ - s->num_file = num_fileSaved ; - s->pos_in_central_dir = pos_in_central_dirSaved ; - s->cur_file_info = cur_file_infoSaved; - s->cur_file_info_internal = cur_file_info_internalSaved; - return err; + s->num_file = num_fileSaved; + s->pos_in_central_dir = pos_in_central_dirSaved; + s->cur_file_info = cur_file_infoSaved; + s->cur_file_info_internal = cur_file_info_internalSaved; + return err; } - /* /////////////////////////////////////////// // Contributed by Ryan Haksi (mailto://cryogen@infoserve.net) @@ -1305,69 +1273,69 @@ typedef struct unz_file_pos_s } unz_file_pos; */ -extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) +extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos* file_pos) { - unz64_s* s; + unz64_s* s; - if (file==NULL || file_pos==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - if (!s->current_file_ok) - return UNZ_END_OF_LIST_OF_FILE; + if (file == NULL || file_pos == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; + if (!s->current_file_ok) + return UNZ_END_OF_LIST_OF_FILE; - file_pos->pos_in_zip_directory = s->pos_in_central_dir; - file_pos->num_of_file = s->num_file; + file_pos->pos_in_zip_directory = s->pos_in_central_dir; + file_pos->num_of_file = s->num_file; - return UNZ_OK; + return UNZ_OK; } extern int ZEXPORT unzGetFilePos( - unzFile file, - unz_file_pos* file_pos) + unzFile file, + unz_file_pos* file_pos) { - unz64_file_pos file_pos64; - int err = unzGetFilePos64(file,&file_pos64); - if (err==UNZ_OK) - { - file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; - file_pos->num_of_file = (uLong)file_pos64.num_of_file; - } - return err; + unz64_file_pos file_pos64; + int err = unzGetFilePos64(file, &file_pos64); + if (err == UNZ_OK) + { + file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory; + file_pos->num_of_file = (uLong)file_pos64.num_of_file; + } + return err; } extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos) { - unz64_s* s; - int err; + unz64_s* s; + int err; - if (file==NULL || file_pos==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; + if (file == NULL || file_pos == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; - /* jump to the right spot */ - s->pos_in_central_dir = file_pos->pos_in_zip_directory; - s->num_file = file_pos->num_of_file; + /* jump to the right spot */ + s->pos_in_central_dir = file_pos->pos_in_zip_directory; + s->num_file = file_pos->num_of_file; - /* set the current file */ - err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - /* return results */ - s->current_file_ok = (err == UNZ_OK); - return err; + /* set the current file */ + err = unz64local_GetCurrentFileInfoInternal(file, &s->cur_file_info, + &s->cur_file_info_internal, + NULL, 0, NULL, 0, NULL, 0); + /* return results */ + s->current_file_ok = (err == UNZ_OK); + return err; } extern int ZEXPORT unzGoToFilePos( - unzFile file, - unz_file_pos* file_pos) + unzFile file, + unz_file_pos* file_pos) { - unz64_file_pos file_pos64; - if (file_pos == NULL) - return UNZ_PARAMERROR; + unz64_file_pos file_pos64; + if (file_pos == NULL) + return UNZ_PARAMERROR; - file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; - file_pos64.num_of_file = file_pos->num_of_file; - return unzGoToFilePos64(file,&file_pos64); + file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory; + file_pos64.num_of_file = file_pos->num_of_file; + return unzGoToFilePos64(file, &file_pos64); } /* @@ -1382,291 +1350,293 @@ extern int ZEXPORT unzGoToFilePos( store in *piSizeVar the size of extra info in local header (filename and size of extra field data) */ -local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar, - ZPOS64_T * poffset_local_extrafield, - uInt * psize_local_extrafield) +local int unz64local_CheckCurrentFileCoherencyHeader(unz64_s* s, uInt* piSizeVar, + ZPOS64_T* poffset_local_extrafield, + uInt* psize_local_extrafield) { - uLong uMagic,uData,uFlags; - uLong size_filename; - uLong size_extra_field; - int err=UNZ_OK; + uLong uMagic, uData, uFlags; + uLong size_filename; + uLong size_extra_field; + int err = UNZ_OK; - *piSizeVar = 0; - *poffset_local_extrafield = 0; - *psize_local_extrafield = 0; + *piSizeVar = 0; + *poffset_local_extrafield = 0; + *psize_local_extrafield = 0; - if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile + - s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; + if (ZSEEK64(s->z_filefunc, s->filestream, s->cur_file_info_internal.offset_curfile + s->byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) + return UNZ_ERRNO; + if (err == UNZ_OK) + { + if (unz64local_getLong(&s->z_filefunc, s->filestream, &uMagic) != UNZ_OK) + err = UNZ_ERRNO; + else if (uMagic != 0x04034b50) + err = UNZ_BADZIPFILE; + } - if (err==UNZ_OK) - { - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK) - err=UNZ_ERRNO; - else if (uMagic!=0x04034b50) - err=UNZ_BADZIPFILE; - } - - if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) - err=UNZ_ERRNO; -/* + if (unz64local_getShort(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) + err = UNZ_ERRNO; + /* else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion)) err=UNZ_BADZIPFILE; */ - if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK) - err=UNZ_ERRNO; + if (unz64local_getShort(&s->z_filefunc, s->filestream, &uFlags) != UNZ_OK) + err = UNZ_ERRNO; - if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method)) - err=UNZ_BADZIPFILE; + if (unz64local_getShort(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) + err = UNZ_ERRNO; + else if ((err == UNZ_OK) && (uData != s->cur_file_info.compression_method)) + err = UNZ_BADZIPFILE; - if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) && -/* #ifdef HAVE_BZIP2 */ - (s->cur_file_info.compression_method!=Z_BZIP2ED) && -/* #endif */ - (s->cur_file_info.compression_method!=Z_DEFLATED)) - err=UNZ_BADZIPFILE; + if ((err == UNZ_OK) && (s->cur_file_info.compression_method != 0) && + /* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method != Z_BZIP2ED) && + /* #endif */ + (s->cur_file_info.compression_method != Z_DEFLATED)) + err = UNZ_BADZIPFILE; - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */ - err=UNZ_ERRNO; + if (unz64local_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) /* date/time */ + err = UNZ_ERRNO; - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */ - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; + if (unz64local_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) /* crc */ + err = UNZ_ERRNO; + else if ((err == UNZ_OK) && (uData != s->cur_file_info.crc) && ((uFlags & 8) == 0)) + err = UNZ_BADZIPFILE; - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */ - err=UNZ_ERRNO; - else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; + if (unz64local_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) /* size compr */ + err = UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err == UNZ_OK) && (uData != s->cur_file_info.compressed_size) && ((uFlags & 8) == 0)) + err = UNZ_BADZIPFILE; - if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */ - err=UNZ_ERRNO; - else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0)) - err=UNZ_BADZIPFILE; + if (unz64local_getLong(&s->z_filefunc, s->filestream, &uData) != UNZ_OK) /* size uncompr */ + err = UNZ_ERRNO; + else if (uData != 0xFFFFFFFF && (err == UNZ_OK) && (uData != s->cur_file_info.uncompressed_size) && ((uFlags & 8) == 0)) + err = UNZ_BADZIPFILE; - if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK) - err=UNZ_ERRNO; - else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename)) - err=UNZ_BADZIPFILE; + if (unz64local_getShort(&s->z_filefunc, s->filestream, &size_filename) != UNZ_OK) + err = UNZ_ERRNO; + else if ((err == UNZ_OK) && (size_filename != s->cur_file_info.size_filename)) + err = UNZ_BADZIPFILE; - *piSizeVar += (uInt)size_filename; + *piSizeVar += (uInt)size_filename; - if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK) - err=UNZ_ERRNO; - *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile + - SIZEZIPLOCALHEADER + size_filename; - *psize_local_extrafield = (uInt)size_extra_field; + if (unz64local_getShort(&s->z_filefunc, s->filestream, &size_extra_field) != UNZ_OK) + err = UNZ_ERRNO; + *poffset_local_extrafield = s->cur_file_info_internal.offset_curfile + + SIZEZIPLOCALHEADER + size_filename; + *psize_local_extrafield = (uInt)size_extra_field; - *piSizeVar += (uInt)size_extra_field; + *piSizeVar += (uInt)size_extra_field; - return err; + return err; } /* Open for reading data the current file in the zipfile. If there is no error and the file is opened, the return value is UNZ_OK. */ -extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method, - int* level, int raw, const char* password) +extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int* method, + int* level, int raw, const char* password) { - int err=UNZ_OK; - uInt iSizeVar; - unz64_s* s; - file_in_zip64_read_info_s* pfile_in_zip_read_info; - ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ - uInt size_local_extrafield; /* size of the local extra field */ -# ifndef NOUNCRYPT - char source[12]; -# else - if (password != NULL) - return UNZ_PARAMERROR; -# endif - - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - if (!s->current_file_ok) - return UNZ_PARAMERROR; - - if (s->pfile_in_zip_read != NULL) - unzCloseCurrentFile(file); - - if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK) - return UNZ_BADZIPFILE; - - pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); - if (pfile_in_zip_read_info==NULL) - return UNZ_INTERNALERROR; - - pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE); - pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; - pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; - pfile_in_zip_read_info->pos_local_extrafield=0; - pfile_in_zip_read_info->raw=raw; - - if (pfile_in_zip_read_info->read_buffer==NULL) - { - TRYFREE(pfile_in_zip_read_info); - return UNZ_INTERNALERROR; - } - - pfile_in_zip_read_info->stream_initialised=0; - - if (method!=NULL) - *method = (int)s->cur_file_info.compression_method; - - if (level!=NULL) - { - *level = 6; - switch (s->cur_file_info.flag & 0x06) - { - case 6 : *level = 1; break; - case 4 : *level = 2; break; - case 2 : *level = 9; break; - } - } - - if ((s->cur_file_info.compression_method!=0) && -/* #ifdef HAVE_BZIP2 */ - (s->cur_file_info.compression_method!=Z_BZIP2ED) && -/* #endif */ - (s->cur_file_info.compression_method!=Z_DEFLATED)) - - err=UNZ_BADZIPFILE; - - pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc; - pfile_in_zip_read_info->crc32=0; - pfile_in_zip_read_info->total_out_64=0; - pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; - pfile_in_zip_read_info->filestream=s->filestream; - pfile_in_zip_read_info->z_filefunc=s->z_filefunc; - pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile; - - pfile_in_zip_read_info->stream.total_out = 0; - - if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw)) - { -#ifdef HAVE_BZIP2 - pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0; - pfile_in_zip_read_info->bstream.bzfree = (free_func)0; - pfile_in_zip_read_info->bstream.opaque = (voidpf)0; - pfile_in_zip_read_info->bstream.state = (voidpf)0; - - pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; - pfile_in_zip_read_info->stream.zfree = (free_func)0; - pfile_in_zip_read_info->stream.opaque = (voidpf)0; - pfile_in_zip_read_info->stream.next_in = (voidpf)0; - pfile_in_zip_read_info->stream.avail_in = 0; - - err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); - if (err == Z_OK) - pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED; - else - { - TRYFREE(pfile_in_zip_read_info); - return err; - } + int err = UNZ_OK; + uInt iSizeVar; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + ZPOS64_T offset_local_extrafield; /* offset of the local extra field */ + uInt size_local_extrafield; /* size of the local extra field */ +#ifndef NOUNCRYPT + char source[12]; #else - pfile_in_zip_read_info->raw=1; + if (password != NULL) + return UNZ_PARAMERROR; #endif - } - else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw)) - { - pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; - pfile_in_zip_read_info->stream.zfree = (free_func)0; - pfile_in_zip_read_info->stream.opaque = (voidpf)0; - pfile_in_zip_read_info->stream.next_in = 0; - pfile_in_zip_read_info->stream.avail_in = 0; - err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); - if (err == Z_OK) - pfile_in_zip_read_info->stream_initialised=Z_DEFLATED; - else - { - TRYFREE(pfile_in_zip_read_info); - return err; - } - /* windowBits is passed < 0 to tell that there is no zlib header. + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; + if (!s->current_file_ok) + return UNZ_PARAMERROR; + + if (s->pfile_in_zip_read != NULL) + unzCloseCurrentFile(file); + + if (unz64local_CheckCurrentFileCoherencyHeader(s, &iSizeVar, &offset_local_extrafield, &size_local_extrafield) != UNZ_OK) + return UNZ_BADZIPFILE; + + pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s)); + if (pfile_in_zip_read_info == NULL) + return UNZ_INTERNALERROR; + + pfile_in_zip_read_info->read_buffer = (char*)ALLOC(UNZ_BUFSIZE); + pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield; + pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield; + pfile_in_zip_read_info->pos_local_extrafield = 0; + pfile_in_zip_read_info->raw = raw; + + if (pfile_in_zip_read_info->read_buffer == NULL) + { + TRYFREE(pfile_in_zip_read_info); + return UNZ_INTERNALERROR; + } + + pfile_in_zip_read_info->stream_initialised = 0; + + if (method != NULL) + *method = (int)s->cur_file_info.compression_method; + + if (level != NULL) + { + *level = 6; + switch (s->cur_file_info.flag & 0x06) + { + case 6: + *level = 1; + break; + case 4: + *level = 2; + break; + case 2: + *level = 9; + break; + } + } + + if ((s->cur_file_info.compression_method != 0) && + /* #ifdef HAVE_BZIP2 */ + (s->cur_file_info.compression_method != Z_BZIP2ED) && + /* #endif */ + (s->cur_file_info.compression_method != Z_DEFLATED)) + + err = UNZ_BADZIPFILE; + + pfile_in_zip_read_info->crc32_wait = s->cur_file_info.crc; + pfile_in_zip_read_info->crc32 = 0; + pfile_in_zip_read_info->total_out_64 = 0; + pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method; + pfile_in_zip_read_info->filestream = s->filestream; + pfile_in_zip_read_info->z_filefunc = s->z_filefunc; + pfile_in_zip_read_info->byte_before_the_zipfile = s->byte_before_the_zipfile; + + pfile_in_zip_read_info->stream.total_out = 0; + + if ((s->cur_file_info.compression_method == Z_BZIP2ED) && (!raw)) + { +#ifdef HAVE_BZIP2 + pfile_in_zip_read_info->bstream.bzalloc = (void* (*)(void*, int, int))0; + pfile_in_zip_read_info->bstream.bzfree = (free_func)0; + pfile_in_zip_read_info->bstream.opaque = (voidpf)0; + pfile_in_zip_read_info->bstream.state = (voidpf)0; + + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = (voidpf)0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err = BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised = Z_BZIP2ED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } +#else + pfile_in_zip_read_info->raw = 1; +#endif + } + else if ((s->cur_file_info.compression_method == Z_DEFLATED) && (!raw)) + { + pfile_in_zip_read_info->stream.zalloc = (alloc_func)0; + pfile_in_zip_read_info->stream.zfree = (free_func)0; + pfile_in_zip_read_info->stream.opaque = (voidpf)0; + pfile_in_zip_read_info->stream.next_in = 0; + pfile_in_zip_read_info->stream.avail_in = 0; + + err = inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS); + if (err == Z_OK) + pfile_in_zip_read_info->stream_initialised = Z_DEFLATED; + else + { + TRYFREE(pfile_in_zip_read_info); + return err; + } + /* windowBits is passed < 0 to tell that there is no zlib header. * Note that in this case inflate *requires* an extra "dummy" byte * after the compressed stream in order to complete decompression and * return Z_STREAM_END. * In unzip, i don't wait absolutely Z_STREAM_END because I known the * size of both compressed and uncompressed data */ - } - pfile_in_zip_read_info->rest_read_compressed = - s->cur_file_info.compressed_size ; - pfile_in_zip_read_info->rest_read_uncompressed = - s->cur_file_info.uncompressed_size ; + } + pfile_in_zip_read_info->rest_read_compressed = + s->cur_file_info.compressed_size; + pfile_in_zip_read_info->rest_read_uncompressed = + s->cur_file_info.uncompressed_size; + pfile_in_zip_read_info->pos_in_zipfile = + s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + + iSizeVar; - pfile_in_zip_read_info->pos_in_zipfile = - s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER + - iSizeVar; + pfile_in_zip_read_info->stream.avail_in = (uInt)0; - pfile_in_zip_read_info->stream.avail_in = (uInt)0; + s->pfile_in_zip_read = pfile_in_zip_read_info; + s->encrypted = 0; - s->pfile_in_zip_read = pfile_in_zip_read_info; - s->encrypted = 0; +#ifndef NOUNCRYPT + if (password != NULL) + { + int i; + s->pcrc_32_tab = get_crc_table(); + init_keys(password, s->keys, s->pcrc_32_tab); + if (ZSEEK64(s->z_filefunc, s->filestream, + s->pfile_in_zip_read->pos_in_zipfile + + s->pfile_in_zip_read->byte_before_the_zipfile, + SEEK_SET) != 0) + return UNZ_INTERNALERROR; + if (ZREAD64(s->z_filefunc, s->filestream, source, 12) < 12) + return UNZ_INTERNALERROR; -# ifndef NOUNCRYPT - if (password != NULL) - { - int i; - s->pcrc_32_tab = get_crc_table(); - init_keys(password,s->keys,s->pcrc_32_tab); - if (ZSEEK64(s->z_filefunc, s->filestream, - s->pfile_in_zip_read->pos_in_zipfile + - s->pfile_in_zip_read->byte_before_the_zipfile, - SEEK_SET)!=0) - return UNZ_INTERNALERROR; - if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12) - return UNZ_INTERNALERROR; + for (i = 0; i < 12; i++) + zdecode(s->keys, s->pcrc_32_tab, source[i]); - for (i = 0; i<12; i++) - zdecode(s->keys,s->pcrc_32_tab,source[i]); + s->pfile_in_zip_read->pos_in_zipfile += 12; + s->encrypted = 1; + } +#endif - s->pfile_in_zip_read->pos_in_zipfile+=12; - s->encrypted=1; - } -# endif - - - return UNZ_OK; + return UNZ_OK; } -extern int ZEXPORT unzOpenCurrentFile (unzFile file) +extern int ZEXPORT unzOpenCurrentFile(unzFile file) { - return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); + return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); } -extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char* password) +extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, const char* password) { - return unzOpenCurrentFile3(file, NULL, NULL, 0, password); + return unzOpenCurrentFile3(file, NULL, NULL, 0, password); } -extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw) +extern int ZEXPORT unzOpenCurrentFile2(unzFile file, int* method, int* level, int raw) { - return unzOpenCurrentFile3(file, method, level, raw, NULL); + return unzOpenCurrentFile3(file, method, level, raw, NULL); } /** Addition for GDAL : START */ -extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) +extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64(unzFile file) { - unz64_s* s; - file_in_zip64_read_info_s* pfile_in_zip_read_info; - s=(unz64_s*)file; - if (file==NULL) - return 0; //UNZ_PARAMERROR; - pfile_in_zip_read_info=s->pfile_in_zip_read; - if (pfile_in_zip_read_info==NULL) - return 0; //UNZ_PARAMERROR; - return pfile_in_zip_read_info->pos_in_zipfile + - pfile_in_zip_read_info->byte_before_the_zipfile; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + s = (unz64_s*)file; + if (file == NULL) + return 0; //UNZ_PARAMERROR; + pfile_in_zip_read_info = s->pfile_in_zip_read; + if (pfile_in_zip_read_info == NULL) + return 0; //UNZ_PARAMERROR; + return pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile; } /** Addition for GDAL : END */ @@ -1681,266 +1651,258 @@ extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file) return <0 with error code if there is an error (UNZ_ERRNO for IO error, or zLib error for uncompress error) */ -extern int ZEXPORT unzReadCurrentFile (unzFile file, voidp buf, unsigned len) +extern int ZEXPORT unzReadCurrentFile(unzFile file, voidp buf, unsigned len) { - int err=UNZ_OK; - uInt iRead = 0; - unz64_s* s; - file_in_zip64_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; + int err = UNZ_OK; + uInt iRead = 0; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; + if (pfile_in_zip_read_info == NULL) + return UNZ_PARAMERROR; + if ((pfile_in_zip_read_info->read_buffer == NULL)) + return UNZ_END_OF_LIST_OF_FILE; + if (len == 0) + return 0; - if ((pfile_in_zip_read_info->read_buffer == NULL)) - return UNZ_END_OF_LIST_OF_FILE; - if (len==0) - return 0; + pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; - pfile_in_zip_read_info->stream.next_out = (Bytef*)buf; + pfile_in_zip_read_info->stream.avail_out = (uInt)len; - pfile_in_zip_read_info->stream.avail_out = (uInt)len; + if ((len > pfile_in_zip_read_info->rest_read_uncompressed) && + (!(pfile_in_zip_read_info->raw))) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_uncompressed; - if ((len>pfile_in_zip_read_info->rest_read_uncompressed) && - (!(pfile_in_zip_read_info->raw))) - pfile_in_zip_read_info->stream.avail_out = - (uInt)pfile_in_zip_read_info->rest_read_uncompressed; + if ((len > pfile_in_zip_read_info->rest_read_compressed + + pfile_in_zip_read_info->stream.avail_in) && + (pfile_in_zip_read_info->raw)) + pfile_in_zip_read_info->stream.avail_out = + (uInt)pfile_in_zip_read_info->rest_read_compressed + + pfile_in_zip_read_info->stream.avail_in; - if ((len>pfile_in_zip_read_info->rest_read_compressed+ - pfile_in_zip_read_info->stream.avail_in) && - (pfile_in_zip_read_info->raw)) - pfile_in_zip_read_info->stream.avail_out = - (uInt)pfile_in_zip_read_info->rest_read_compressed+ - pfile_in_zip_read_info->stream.avail_in; + while (pfile_in_zip_read_info->stream.avail_out > 0) + { + if ((pfile_in_zip_read_info->stream.avail_in == 0) && + (pfile_in_zip_read_info->rest_read_compressed > 0)) + { + uInt uReadThis = UNZ_BUFSIZE; + if (pfile_in_zip_read_info->rest_read_compressed < uReadThis) + uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed; + if (uReadThis == 0) + return UNZ_EOF; + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->pos_in_zipfile + + pfile_in_zip_read_info->byte_before_the_zipfile, + ZLIB_FILEFUNC_SEEK_SET) != 0) + return UNZ_ERRNO; + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->read_buffer, + uReadThis) != uReadThis) + return UNZ_ERRNO; - while (pfile_in_zip_read_info->stream.avail_out>0) - { - if ((pfile_in_zip_read_info->stream.avail_in==0) && - (pfile_in_zip_read_info->rest_read_compressed>0)) - { - uInt uReadThis = UNZ_BUFSIZE; - if (pfile_in_zip_read_info->rest_read_compressedrest_read_compressed; - if (uReadThis == 0) - return UNZ_EOF; - if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->pos_in_zipfile + - pfile_in_zip_read_info->byte_before_the_zipfile, - ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; - if (ZREAD64(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->read_buffer, - uReadThis)!=uReadThis) - return UNZ_ERRNO; - - -# ifndef NOUNCRYPT - if(s->encrypted) - { - uInt i; - for(i=0;iread_buffer[i] = - zdecode(s->keys,s->pcrc_32_tab, - pfile_in_zip_read_info->read_buffer[i]); - } -# endif - - - pfile_in_zip_read_info->pos_in_zipfile += uReadThis; - - pfile_in_zip_read_info->rest_read_compressed-=uReadThis; - - pfile_in_zip_read_info->stream.next_in = - (Bytef*)pfile_in_zip_read_info->read_buffer; - pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; - } - - if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw)) - { - uInt uDoCopy,i ; - - if ((pfile_in_zip_read_info->stream.avail_in == 0) && - (pfile_in_zip_read_info->rest_read_compressed == 0)) - return (iRead==0) ? UNZ_EOF : iRead; - - if (pfile_in_zip_read_info->stream.avail_out < - pfile_in_zip_read_info->stream.avail_in) - uDoCopy = pfile_in_zip_read_info->stream.avail_out ; - else - uDoCopy = pfile_in_zip_read_info->stream.avail_in ; - - for (i=0;istream.next_out+i) = - *(pfile_in_zip_read_info->stream.next_in+i); - - pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; - - pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, - pfile_in_zip_read_info->stream.next_out, - uDoCopy); - pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy; - pfile_in_zip_read_info->stream.avail_in -= uDoCopy; - pfile_in_zip_read_info->stream.avail_out -= uDoCopy; - pfile_in_zip_read_info->stream.next_out += uDoCopy; - pfile_in_zip_read_info->stream.next_in += uDoCopy; - pfile_in_zip_read_info->stream.total_out += uDoCopy; - iRead += uDoCopy; - } - else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED) - { -#ifdef HAVE_BZIP2 - uLong uTotalOutBefore,uTotalOutAfter; - const Bytef *bufBefore; - uLong uOutThis; - - pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; - pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; - pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; - pfile_in_zip_read_info->bstream.total_in_hi32 = 0; - pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; - pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; - pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; - pfile_in_zip_read_info->bstream.total_out_hi32 = 0; - - uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; - bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out; - - err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); - - uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; - uOutThis = uTotalOutAfter-uTotalOutBefore; - - pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; - - pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis)); - pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; - iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); - - pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; - pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; - pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; - pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; - pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; - pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; - - if (err==BZ_STREAM_END) - return (iRead==0) ? UNZ_EOF : iRead; - if (err!=BZ_OK) - break; +#ifndef NOUNCRYPT + if (s->encrypted) + { + uInt i; + for (i = 0; i < uReadThis; i++) + pfile_in_zip_read_info->read_buffer[i] = + zdecode(s->keys, s->pcrc_32_tab, + pfile_in_zip_read_info->read_buffer[i]); + } #endif - } // end Z_BZIP2ED - else - { - ZPOS64_T uTotalOutBefore,uTotalOutAfter; - const Bytef *bufBefore; - ZPOS64_T uOutThis; - int flush=Z_SYNC_FLUSH; - uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; - bufBefore = pfile_in_zip_read_info->stream.next_out; + pfile_in_zip_read_info->pos_in_zipfile += uReadThis; - /* + pfile_in_zip_read_info->rest_read_compressed -= uReadThis; + + pfile_in_zip_read_info->stream.next_in = + (Bytef*)pfile_in_zip_read_info->read_buffer; + pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis; + } + + if ((pfile_in_zip_read_info->compression_method == 0) || (pfile_in_zip_read_info->raw)) + { + uInt uDoCopy, i; + + if ((pfile_in_zip_read_info->stream.avail_in == 0) && + (pfile_in_zip_read_info->rest_read_compressed == 0)) + return (iRead == 0) ? UNZ_EOF : iRead; + + if (pfile_in_zip_read_info->stream.avail_out < + pfile_in_zip_read_info->stream.avail_in) + uDoCopy = pfile_in_zip_read_info->stream.avail_out; + else + uDoCopy = pfile_in_zip_read_info->stream.avail_in; + + for (i = 0; i < uDoCopy; i++) + *(pfile_in_zip_read_info->stream.next_out + i) = + *(pfile_in_zip_read_info->stream.next_in + i); + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, + pfile_in_zip_read_info->stream.next_out, + uDoCopy); + pfile_in_zip_read_info->rest_read_uncompressed -= uDoCopy; + pfile_in_zip_read_info->stream.avail_in -= uDoCopy; + pfile_in_zip_read_info->stream.avail_out -= uDoCopy; + pfile_in_zip_read_info->stream.next_out += uDoCopy; + pfile_in_zip_read_info->stream.next_in += uDoCopy; + pfile_in_zip_read_info->stream.total_out += uDoCopy; + iRead += uDoCopy; + } + else if (pfile_in_zip_read_info->compression_method == Z_BZIP2ED) + { +#ifdef HAVE_BZIP2 + uLong uTotalOutBefore, uTotalOutAfter; + const Bytef* bufBefore; + uLong uOutThis; + + pfile_in_zip_read_info->bstream.next_in = (char*)pfile_in_zip_read_info->stream.next_in; + pfile_in_zip_read_info->bstream.avail_in = pfile_in_zip_read_info->stream.avail_in; + pfile_in_zip_read_info->bstream.total_in_lo32 = pfile_in_zip_read_info->stream.total_in; + pfile_in_zip_read_info->bstream.total_in_hi32 = 0; + pfile_in_zip_read_info->bstream.next_out = (char*)pfile_in_zip_read_info->stream.next_out; + pfile_in_zip_read_info->bstream.avail_out = pfile_in_zip_read_info->stream.avail_out; + pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out; + pfile_in_zip_read_info->bstream.total_out_hi32 = 0; + + uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32; + bufBefore = (const Bytef*)pfile_in_zip_read_info->bstream.next_out; + + err = BZ2_bzDecompress(&pfile_in_zip_read_info->bstream); + + uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32; + uOutThis = uTotalOutAfter - uTotalOutBefore; + + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + + pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32, bufBefore, (uInt)(uOutThis)); + pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis; + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + + pfile_in_zip_read_info->stream.next_in = (Bytef*)pfile_in_zip_read_info->bstream.next_in; + pfile_in_zip_read_info->stream.avail_in = pfile_in_zip_read_info->bstream.avail_in; + pfile_in_zip_read_info->stream.total_in = pfile_in_zip_read_info->bstream.total_in_lo32; + pfile_in_zip_read_info->stream.next_out = (Bytef*)pfile_in_zip_read_info->bstream.next_out; + pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out; + pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32; + + if (err == BZ_STREAM_END) + return (iRead == 0) ? UNZ_EOF : iRead; + if (err != BZ_OK) + break; +#endif + } // end Z_BZIP2ED + else + { + ZPOS64_T uTotalOutBefore, uTotalOutAfter; + const Bytef* bufBefore; + ZPOS64_T uOutThis; + int flush = Z_SYNC_FLUSH; + + uTotalOutBefore = pfile_in_zip_read_info->stream.total_out; + bufBefore = pfile_in_zip_read_info->stream.next_out; + + /* if ((pfile_in_zip_read_info->rest_read_uncompressed == pfile_in_zip_read_info->stream.avail_out) && (pfile_in_zip_read_info->rest_read_compressed == 0)) flush = Z_FINISH; */ - err=inflate(&pfile_in_zip_read_info->stream,flush); + err = inflate(&pfile_in_zip_read_info->stream, flush); - if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL)) - err = Z_DATA_ERROR; + if ((err >= 0) && (pfile_in_zip_read_info->stream.msg != NULL)) + err = Z_DATA_ERROR; - uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; - uOutThis = uTotalOutAfter-uTotalOutBefore; + uTotalOutAfter = pfile_in_zip_read_info->stream.total_out; + uOutThis = uTotalOutAfter - uTotalOutBefore; - pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; + pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis; - pfile_in_zip_read_info->crc32 = - crc32(pfile_in_zip_read_info->crc32,bufBefore, - (uInt)(uOutThis)); + pfile_in_zip_read_info->crc32 = + crc32(pfile_in_zip_read_info->crc32, bufBefore, + (uInt)(uOutThis)); - pfile_in_zip_read_info->rest_read_uncompressed -= - uOutThis; + pfile_in_zip_read_info->rest_read_uncompressed -= + uOutThis; - iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); + iRead += (uInt)(uTotalOutAfter - uTotalOutBefore); - if (err==Z_STREAM_END) - return (iRead==0) ? UNZ_EOF : iRead; - if (err!=Z_OK) - break; - } - } + if (err == Z_STREAM_END) + return (iRead == 0) ? UNZ_EOF : iRead; + if (err != Z_OK) + break; + } + } - if (err==Z_OK) - return iRead; - return err; + if (err == Z_OK) + return iRead; + return err; } - /* Give the current position in uncompressed data */ -extern z_off_t ZEXPORT unztell (unzFile file) +extern z_off_t ZEXPORT unztell(unzFile file) { - unz64_s* s; - file_in_zip64_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; + if (pfile_in_zip_read_info == NULL) + return UNZ_PARAMERROR; - return (z_off_t)pfile_in_zip_read_info->stream.total_out; + return (z_off_t)pfile_in_zip_read_info->stream.total_out; } -extern ZPOS64_T ZEXPORT unztell64 (unzFile file) +extern ZPOS64_T ZEXPORT unztell64(unzFile file) { + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file == NULL) + return (ZPOS64_T)-1; + s = (unz64_s*)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; - unz64_s* s; - file_in_zip64_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return (ZPOS64_T)-1; - s=(unz64_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; + if (pfile_in_zip_read_info == NULL) + return (ZPOS64_T)-1; - if (pfile_in_zip_read_info==NULL) - return (ZPOS64_T)-1; - - return pfile_in_zip_read_info->total_out_64; + return pfile_in_zip_read_info->total_out_64; } - /* return 1 if the end of file was reached, 0 elsewhere */ -extern int ZEXPORT unzeof (unzFile file) +extern int ZEXPORT unzeof(unzFile file) { - unz64_s* s; - file_in_zip64_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; + if (pfile_in_zip_read_info == NULL) + return UNZ_PARAMERROR; - if (pfile_in_zip_read_info->rest_read_uncompressed == 0) - return 1; - else - return 0; + if (pfile_in_zip_read_info->rest_read_uncompressed == 0) + return 1; + else + return 0; } - - /* Read extra field from the current file (opened by unzOpenCurrentFile) This is the local-header version of the extra field (sometimes, there is @@ -1953,173 +1915,169 @@ more info in the local-header version than in the central-header) the return value is the number of bytes copied in buf, or (if <0) the error code */ -extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len) +extern int ZEXPORT unzGetLocalExtrafield(unzFile file, voidp buf, unsigned len) { - unz64_s* s; - file_in_zip64_read_info_s* pfile_in_zip_read_info; - uInt read_now; - ZPOS64_T size_to_read; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + uInt read_now; + ZPOS64_T size_to_read; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; + if (pfile_in_zip_read_info == NULL) + return UNZ_PARAMERROR; - size_to_read = (pfile_in_zip_read_info->size_local_extrafield - - pfile_in_zip_read_info->pos_local_extrafield); + size_to_read = (pfile_in_zip_read_info->size_local_extrafield - + pfile_in_zip_read_info->pos_local_extrafield); - if (buf==NULL) - return (int)size_to_read; + if (buf == NULL) + return (int)size_to_read; - if (len>size_to_read) - read_now = (uInt)size_to_read; - else - read_now = (uInt)len ; + if (len > size_to_read) + read_now = (uInt)size_to_read; + else + read_now = (uInt)len; - if (read_now==0) - return 0; + if (read_now == 0) + return 0; - if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - pfile_in_zip_read_info->offset_local_extrafield + - pfile_in_zip_read_info->pos_local_extrafield, - ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; + if (ZSEEK64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + pfile_in_zip_read_info->offset_local_extrafield + + pfile_in_zip_read_info->pos_local_extrafield, + ZLIB_FILEFUNC_SEEK_SET) != 0) + return UNZ_ERRNO; - if (ZREAD64(pfile_in_zip_read_info->z_filefunc, - pfile_in_zip_read_info->filestream, - buf,read_now)!=read_now) - return UNZ_ERRNO; + if (ZREAD64(pfile_in_zip_read_info->z_filefunc, + pfile_in_zip_read_info->filestream, + buf, read_now) != read_now) + return UNZ_ERRNO; - return (int)read_now; + return (int)read_now; } /* Close the file in zip opened with unzipOpenCurrentFile Return UNZ_CRCERROR if all the file was read but the CRC is not good */ -extern int ZEXPORT unzCloseCurrentFile (unzFile file) +extern int ZEXPORT unzCloseCurrentFile(unzFile file) { - int err=UNZ_OK; + int err = UNZ_OK; - unz64_s* s; - file_in_zip64_read_info_s* pfile_in_zip_read_info; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; - pfile_in_zip_read_info=s->pfile_in_zip_read; + unz64_s* s; + file_in_zip64_read_info_s* pfile_in_zip_read_info; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; + pfile_in_zip_read_info = s->pfile_in_zip_read; - if (pfile_in_zip_read_info==NULL) - return UNZ_PARAMERROR; + if (pfile_in_zip_read_info == NULL) + return UNZ_PARAMERROR; + if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && + (!pfile_in_zip_read_info->raw)) + { + if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) + err = UNZ_CRCERROR; + } - if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) && - (!pfile_in_zip_read_info->raw)) - { - if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) - err=UNZ_CRCERROR; - } - - - TRYFREE(pfile_in_zip_read_info->read_buffer); - pfile_in_zip_read_info->read_buffer = NULL; - if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) - inflateEnd(&pfile_in_zip_read_info->stream); + TRYFREE(pfile_in_zip_read_info->read_buffer); + pfile_in_zip_read_info->read_buffer = NULL; + if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED) + inflateEnd(&pfile_in_zip_read_info->stream); #ifdef HAVE_BZIP2 - else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) - BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); + else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED) + BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream); #endif + pfile_in_zip_read_info->stream_initialised = 0; + TRYFREE(pfile_in_zip_read_info); - pfile_in_zip_read_info->stream_initialised = 0; - TRYFREE(pfile_in_zip_read_info); + s->pfile_in_zip_read = NULL; - s->pfile_in_zip_read=NULL; - - return err; + return err; } - /* Get the global comment string of the ZipFile, in the szComment buffer. uSizeBuf is the size of the szComment buffer. return the number of byte copied or an error code <0 */ -extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf) +extern int ZEXPORT unzGetGlobalComment(unzFile file, char* szComment, uLong uSizeBuf) { - unz64_s* s; - uLong uReadThis ; - if (file==NULL) - return (int)UNZ_PARAMERROR; - s=(unz64_s*)file; + unz64_s* s; + uLong uReadThis; + if (file == NULL) + return (int)UNZ_PARAMERROR; + s = (unz64_s*)file; - uReadThis = uSizeBuf; - if (uReadThis>s->gi.size_comment) - uReadThis = s->gi.size_comment; + uReadThis = uSizeBuf; + if (uReadThis > s->gi.size_comment) + uReadThis = s->gi.size_comment; - if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0) - return UNZ_ERRNO; + if (ZSEEK64(s->z_filefunc, s->filestream, s->central_pos + 22, ZLIB_FILEFUNC_SEEK_SET) != 0) + return UNZ_ERRNO; - if (uReadThis>0) - { - *szComment='\0'; - if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis) - return UNZ_ERRNO; - } + if (uReadThis > 0) + { + *szComment = '\0'; + if (ZREAD64(s->z_filefunc, s->filestream, szComment, uReadThis) != uReadThis) + return UNZ_ERRNO; + } - if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) - *(szComment+s->gi.size_comment)='\0'; - return (int)uReadThis; + if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment)) + *(szComment + s->gi.size_comment) = '\0'; + return (int)uReadThis; } /* Additions by RX '2004 */ extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file) { - unz64_s* s; + unz64_s* s; - if (file==NULL) - return 0; //UNZ_PARAMERROR; - s=(unz64_s*)file; - if (!s->current_file_ok) - return 0; - if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) - if (s->num_file==s->gi.number_entry) - return 0; - return s->pos_in_central_dir; + if (file == NULL) + return 0; //UNZ_PARAMERROR; + s = (unz64_s*)file; + if (!s->current_file_ok) + return 0; + if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff) + if (s->num_file == s->gi.number_entry) + return 0; + return s->pos_in_central_dir; } -extern uLong ZEXPORT unzGetOffset (unzFile file) +extern uLong ZEXPORT unzGetOffset(unzFile file) { - ZPOS64_T offset64; + ZPOS64_T offset64; - if (file==NULL) - return 0; //UNZ_PARAMERROR; - offset64 = unzGetOffset64(file); - return (uLong)offset64; + if (file == NULL) + return 0; //UNZ_PARAMERROR; + offset64 = unzGetOffset64(file); + return (uLong)offset64; } extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos) { - unz64_s* s; - int err; + unz64_s* s; + int err; - if (file==NULL) - return UNZ_PARAMERROR; - s=(unz64_s*)file; + if (file == NULL) + return UNZ_PARAMERROR; + s = (unz64_s*)file; - s->pos_in_central_dir = pos; - s->num_file = s->gi.number_entry; /* hack */ - err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info, - &s->cur_file_info_internal, - NULL,0,NULL,0,NULL,0); - s->current_file_ok = (err == UNZ_OK); - return err; + s->pos_in_central_dir = pos; + s->num_file = s->gi.number_entry; /* hack */ + err = unz64local_GetCurrentFileInfoInternal(file, &s->cur_file_info, + &s->cur_file_info_internal, + NULL, 0, NULL, 0, NULL, 0); + s->current_file_ok = (err == UNZ_OK); + return err; } -extern int ZEXPORT unzSetOffset (unzFile file, uLong pos) +extern int ZEXPORT unzSetOffset(unzFile file, uLong pos) { - return unzSetOffset64(file,pos); + return unzSetOffset64(file, pos); } diff --git a/examples/ThirdPartyLibs/minizip/unzip.h b/examples/ThirdPartyLibs/minizip/unzip.h index 910dda07a..d711237d0 100644 --- a/examples/ThirdPartyLibs/minizip/unzip.h +++ b/examples/ThirdPartyLibs/minizip/unzip.h @@ -44,14 +44,15 @@ #define _unz64_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #ifndef _ZLIB_H #include "../zlib/zlib.h" #endif -#ifndef _ZLIBIOAPI_H +#ifndef _ZLIBIOAPI_H #include "ioapi.h" #endif @@ -62,98 +63,100 @@ extern "C" { #define Z_BZIP2ED 12 #if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) -/* like the STRICT of WIN32, we define a pointer that cannot be converted + /* like the STRICT of WIN32, we define a pointer that cannot be converted from (void*) without cast */ -typedef struct TagunzFile__ { int unused; } unzFile__; -typedef unzFile__ *unzFile; + typedef struct TagunzFile__ + { + int unused; + } unzFile__; + typedef unzFile__ *unzFile; #else typedef voidp unzFile; #endif +#define UNZ_OK (0) +#define UNZ_END_OF_LIST_OF_FILE (-100) +#define UNZ_ERRNO (Z_ERRNO) +#define UNZ_EOF (0) +#define UNZ_PARAMERROR (-102) +#define UNZ_BADZIPFILE (-103) +#define UNZ_INTERNALERROR (-104) +#define UNZ_CRCERROR (-105) -#define UNZ_OK (0) -#define UNZ_END_OF_LIST_OF_FILE (-100) -#define UNZ_ERRNO (Z_ERRNO) -#define UNZ_EOF (0) -#define UNZ_PARAMERROR (-102) -#define UNZ_BADZIPFILE (-103) -#define UNZ_INTERNALERROR (-104) -#define UNZ_CRCERROR (-105) + /* tm_unz contain date/time info */ + typedef struct tm_unz_s + { + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ + } tm_unz; -/* tm_unz contain date/time info */ -typedef struct tm_unz_s -{ - uInt tm_sec; /* seconds after the minute - [0,59] */ - uInt tm_min; /* minutes after the hour - [0,59] */ - uInt tm_hour; /* hours since midnight - [0,23] */ - uInt tm_mday; /* day of the month - [1,31] */ - uInt tm_mon; /* months since January - [0,11] */ - uInt tm_year; /* years - [1980..2044] */ -} tm_unz; - -/* unz_global_info structure contain global data about the ZIPfile + /* unz_global_info structure contain global data about the ZIPfile These data comes from the end of central dir */ -typedef struct unz_global_info64_s -{ - ZPOS64_T number_entry; /* total number of entries in + typedef struct unz_global_info64_s + { + ZPOS64_T number_entry; /* total number of entries in the central dir on this disk */ - uLong size_comment; /* size of the global comment of the zipfile */ -} unz_global_info64; + uLong size_comment; /* size of the global comment of the zipfile */ + } unz_global_info64; -typedef struct unz_global_info_s -{ - uLong number_entry; /* total number of entries in + typedef struct unz_global_info_s + { + uLong number_entry; /* total number of entries in the central dir on this disk */ - uLong size_comment; /* size of the global comment of the zipfile */ -} unz_global_info; + uLong size_comment; /* size of the global comment of the zipfile */ + } unz_global_info; -/* unz_file_info contain information about a file in the zipfile */ -typedef struct unz_file_info64_s -{ - uLong version; /* version made by 2 bytes */ - uLong version_needed; /* version needed to extract 2 bytes */ - uLong flag; /* general purpose bit flag 2 bytes */ - uLong compression_method; /* compression method 2 bytes */ - uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ - uLong crc; /* crc-32 4 bytes */ - ZPOS64_T compressed_size; /* compressed size 8 bytes */ - ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */ - uLong size_filename; /* filename length 2 bytes */ - uLong size_file_extra; /* extra field length 2 bytes */ - uLong size_file_comment; /* file comment length 2 bytes */ + /* unz_file_info contain information about a file in the zipfile */ + typedef struct unz_file_info64_s + { + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + ZPOS64_T compressed_size; /* compressed size 8 bytes */ + ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ - uLong disk_num_start; /* disk number start 2 bytes */ - uLong internal_fa; /* internal file attributes 2 bytes */ - uLong external_fa; /* external file attributes 4 bytes */ + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ - tm_unz tmu_date; -} unz_file_info64; + tm_unz tmu_date; + } unz_file_info64; -typedef struct unz_file_info_s -{ - uLong version; /* version made by 2 bytes */ - uLong version_needed; /* version needed to extract 2 bytes */ - uLong flag; /* general purpose bit flag 2 bytes */ - uLong compression_method; /* compression method 2 bytes */ - uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ - uLong crc; /* crc-32 4 bytes */ - uLong compressed_size; /* compressed size 4 bytes */ - uLong uncompressed_size; /* uncompressed size 4 bytes */ - uLong size_filename; /* filename length 2 bytes */ - uLong size_file_extra; /* extra field length 2 bytes */ - uLong size_file_comment; /* file comment length 2 bytes */ + typedef struct unz_file_info_s + { + uLong version; /* version made by 2 bytes */ + uLong version_needed; /* version needed to extract 2 bytes */ + uLong flag; /* general purpose bit flag 2 bytes */ + uLong compression_method; /* compression method 2 bytes */ + uLong dosDate; /* last mod file date in Dos fmt 4 bytes */ + uLong crc; /* crc-32 4 bytes */ + uLong compressed_size; /* compressed size 4 bytes */ + uLong uncompressed_size; /* uncompressed size 4 bytes */ + uLong size_filename; /* filename length 2 bytes */ + uLong size_file_extra; /* extra field length 2 bytes */ + uLong size_file_comment; /* file comment length 2 bytes */ - uLong disk_num_start; /* disk number start 2 bytes */ - uLong internal_fa; /* internal file attributes 2 bytes */ - uLong external_fa; /* external file attributes 4 bytes */ + uLong disk_num_start; /* disk number start 2 bytes */ + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ - tm_unz tmu_date; -} unz_file_info; + tm_unz tmu_date; + } unz_file_info; -extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, - const char* fileName2, - int iCaseSensitivity)); -/* + extern int ZEXPORT unzStringFileNameCompare OF((const char *fileName1, + const char *fileName2, + int iCaseSensitivity)); + /* Compare two filename (fileName1,fileName2). If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp) If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi @@ -162,10 +165,9 @@ extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1, (like 1 on Unix, 2 on Windows) */ - -extern unzFile ZEXPORT unzOpen OF((const char *path)); -extern unzFile ZEXPORT unzOpen64 OF((const void *path)); -/* + extern unzFile ZEXPORT unzOpen OF((const char *path)); + extern unzFile ZEXPORT unzOpen64 OF((const void *path)); + /* Open a Zip file. path contain the full pathname (by example, on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer "zlib/zlib113.zip". @@ -180,69 +182,66 @@ extern unzFile ZEXPORT unzOpen64 OF((const void *path)); does not describe the reality */ - -extern unzFile ZEXPORT unzOpen2 OF((const char *path, - zlib_filefunc_def* pzlib_filefunc_def)); -/* + extern unzFile ZEXPORT unzOpen2 OF((const char *path, + zlib_filefunc_def *pzlib_filefunc_def)); + /* Open a Zip file, like unzOpen, but provide a set of file low level API for read/write the zip file (see ioapi.h) */ -extern unzFile ZEXPORT unzOpen2_64 OF((const void *path, - zlib_filefunc64_def* pzlib_filefunc_def)); -/* + extern unzFile ZEXPORT unzOpen2_64 OF((const void *path, + zlib_filefunc64_def *pzlib_filefunc_def)); + /* Open a Zip file, like unz64Open, but provide a set of file low level API for read/write the zip file (see ioapi.h) */ -extern int ZEXPORT unzClose OF((unzFile file)); -/* + extern int ZEXPORT unzClose OF((unzFile file)); + /* Close a ZipFile opened with unzipOpen. If there is files inside the .Zip opened with unzOpenCurrentFile (see later), these files MUST be closed with unzipCloseCurrentFile before call unzipClose. return UNZ_OK if there is no problem. */ -extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, - unz_global_info *pglobal_info)); + extern int ZEXPORT unzGetGlobalInfo OF((unzFile file, + unz_global_info *pglobal_info)); -extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, - unz_global_info64 *pglobal_info)); -/* + extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file, + unz_global_info64 *pglobal_info)); + /* Write info about the ZipFile in the *pglobal_info structure. No preparation of the structure is needed return UNZ_OK if there is no problem. */ - -extern int ZEXPORT unzGetGlobalComment OF((unzFile file, - char *szComment, - uLong uSizeBuf)); -/* + extern int ZEXPORT unzGetGlobalComment OF((unzFile file, + char *szComment, + uLong uSizeBuf)); + /* Get the global comment string of the ZipFile, in the szComment buffer. uSizeBuf is the size of the szComment buffer. return the number of byte copied or an error code <0 */ + /***************************************************************************/ + /* Unzip package allow you browse the directory of the zipfile */ -/***************************************************************************/ -/* Unzip package allow you browse the directory of the zipfile */ - -extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); -/* + extern int ZEXPORT unzGoToFirstFile OF((unzFile file)); + /* Set the current file of the zipfile to the first file. return UNZ_OK if there is no problem */ -extern int ZEXPORT unzGoToNextFile OF((unzFile file)); -/* + extern int ZEXPORT unzGoToNextFile OF((unzFile file)); + /* Set the current file of the zipfile to the next file. return UNZ_OK if there is no problem return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest. */ -extern int ZEXPORT unzLocateFile OF((unzFile file, - const char *szFileName, - int iCaseSensitivity)); -/* + extern int ZEXPORT unzLocateFile OF((unzFile file, + const char *szFileName, + int iCaseSensitivity)); + /* Try locate the file szFileName in the zipfile. For the iCaseSensitivity signification, see unzStringFileNameCompare @@ -251,58 +250,57 @@ extern int ZEXPORT unzLocateFile OF((unzFile file, UNZ_END_OF_LIST_OF_FILE if the file is not found */ + /* ****************************************** */ + /* Ryan supplied functions */ + /* unz_file_info contain information about a file in the zipfile */ + typedef struct unz_file_pos_s + { + uLong pos_in_zip_directory; /* offset in zip file directory */ + uLong num_of_file; /* # of file */ + } unz_file_pos; -/* ****************************************** */ -/* Ryan supplied functions */ -/* unz_file_info contain information about a file in the zipfile */ -typedef struct unz_file_pos_s -{ - uLong pos_in_zip_directory; /* offset in zip file directory */ - uLong num_of_file; /* # of file */ -} unz_file_pos; + extern int ZEXPORT unzGetFilePos( + unzFile file, + unz_file_pos *file_pos); -extern int ZEXPORT unzGetFilePos( - unzFile file, - unz_file_pos* file_pos); + extern int ZEXPORT unzGoToFilePos( + unzFile file, + unz_file_pos *file_pos); -extern int ZEXPORT unzGoToFilePos( - unzFile file, - unz_file_pos* file_pos); + typedef struct unz64_file_pos_s + { + ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */ + ZPOS64_T num_of_file; /* # of file */ + } unz64_file_pos; -typedef struct unz64_file_pos_s -{ - ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */ - ZPOS64_T num_of_file; /* # of file */ -} unz64_file_pos; + extern int ZEXPORT unzGetFilePos64( + unzFile file, + unz64_file_pos *file_pos); -extern int ZEXPORT unzGetFilePos64( - unzFile file, - unz64_file_pos* file_pos); + extern int ZEXPORT unzGoToFilePos64( + unzFile file, + const unz64_file_pos *file_pos); -extern int ZEXPORT unzGoToFilePos64( - unzFile file, - const unz64_file_pos* file_pos); + /* ****************************************** */ -/* ****************************************** */ + extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file, + unz_file_info64 *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); -extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file, - unz_file_info64 *pfile_info, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize)); - -extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, - unz_file_info *pfile_info, - char *szFileName, - uLong fileNameBufferSize, - void *extraField, - uLong extraFieldBufferSize, - char *szComment, - uLong commentBufferSize)); -/* + extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, + unz_file_info *pfile_info, + char *szFileName, + uLong fileNameBufferSize, + void *extraField, + uLong extraFieldBufferSize, + char *szComment, + uLong commentBufferSize)); + /* Get Info about the current file if pfile_info!=NULL, the *pfile_info structure will contain somes info about the current file @@ -315,38 +313,36 @@ extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file, (commentBufferSize is the size of the buffer) */ + /** Addition for GDAL : START */ -/** Addition for GDAL : START */ + extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); -extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file)); + /** Addition for GDAL : END */ -/** Addition for GDAL : END */ - - -/***************************************************************************/ -/* for reading the content of the current zipfile, you can open it, read data + /***************************************************************************/ + /* for reading the content of the current zipfile, you can open it, read data from it, and close it (you can close it before reading all the file) */ -extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); -/* + extern int ZEXPORT unzOpenCurrentFile OF((unzFile file)); + /* Open for reading data the current file in the zipfile. If there is no error, the return value is UNZ_OK. */ -extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, - const char* password)); -/* + extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file, + const char *password)); + /* Open for reading data the current file in the zipfile. password is a crypting password If there is no error, the return value is UNZ_OK. */ -extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, - int* method, - int* level, - int raw)); -/* + extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, + int *method, + int *level, + int raw)); + /* Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) if raw==1 *method will receive method of compression, *level will receive level of @@ -355,12 +351,12 @@ extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file, but you CANNOT set method parameter as NULL */ -extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, - int* method, - int* level, - int raw, - const char* password)); -/* + extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, + int *method, + int *level, + int raw, + const char *password)); + /* Same than unzOpenCurrentFile, but open for read raw the file (not uncompress) if raw==1 *method will receive method of compression, *level will receive level of @@ -369,17 +365,16 @@ extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file, but you CANNOT set method parameter as NULL */ - -extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); -/* + extern int ZEXPORT unzCloseCurrentFile OF((unzFile file)); + /* Close the file in zip opened with unzOpenCurrentFile Return UNZ_CRCERROR if all the file was read but the CRC is not good */ -extern int ZEXPORT unzReadCurrentFile OF((unzFile file, - voidp buf, - unsigned len)); -/* + extern int ZEXPORT unzReadCurrentFile OF((unzFile file, + voidp buf, + unsigned len)); + /* Read bytes from the current file (opened by unzOpenCurrentFile) buf contain buffer where data must be copied len the size of buf. @@ -390,22 +385,22 @@ extern int ZEXPORT unzReadCurrentFile OF((unzFile file, (UNZ_ERRNO for IO error, or zLib error for uncompress error) */ -extern z_off_t ZEXPORT unztell OF((unzFile file)); + extern z_off_t ZEXPORT unztell OF((unzFile file)); -extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file)); -/* + extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file)); + /* Give the current position in uncompressed data */ -extern int ZEXPORT unzeof OF((unzFile file)); -/* + extern int ZEXPORT unzeof OF((unzFile file)); + /* return 1 if the end of file was reached, 0 elsewhere */ -extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, - voidp buf, - unsigned len)); -/* + extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, + voidp buf, + unsigned len)); + /* Read extra field from the current file (opened by unzOpenCurrentFile) This is the local-header version of the extra field (sometimes, there is more info in the local-header version than in the central-header) @@ -418,17 +413,15 @@ extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file, the error code */ -/***************************************************************************/ - -/* Get the current file offset */ -extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file); -extern uLong ZEXPORT unzGetOffset (unzFile file); - -/* Set the current file offset */ -extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos); -extern int ZEXPORT unzSetOffset (unzFile file, uLong pos); + /***************************************************************************/ + /* Get the current file offset */ + extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file); + extern uLong ZEXPORT unzGetOffset(unzFile file); + /* Set the current file offset */ + extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos); + extern int ZEXPORT unzSetOffset(unzFile file, uLong pos); #ifdef __cplusplus } diff --git a/examples/ThirdPartyLibs/minizip/zip.c b/examples/ThirdPartyLibs/minizip/zip.c index a024136a0..0b52f490d 100644 --- a/examples/ThirdPartyLibs/minizip/zip.c +++ b/examples/ThirdPartyLibs/minizip/zip.c @@ -21,7 +21,6 @@ */ - #include #include #include @@ -30,28 +29,27 @@ #include "zip.h" #ifdef STDC -# include -# include -# include +#include +#include +#include #endif #ifdef NO_ERRNO_H - extern int errno; +extern int errno; #else -# include +#include #endif - #ifndef local -# define local static +#define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ #ifndef VERSIONMADEBY -# define VERSIONMADEBY (0x0) /* platform depedent */ +#define VERSIONMADEBY (0x0) /* platform depedent */ #endif #ifndef Z_BUFSIZE -#define Z_BUFSIZE (64*1024) //(16384) +#define Z_BUFSIZE (64 * 1024) //(16384) #endif #ifndef Z_MAXFILENAMEINZIP @@ -59,10 +57,13 @@ #endif #ifndef ALLOC -# define ALLOC(size) (malloc(size)) +#define ALLOC(size) (malloc(size)) #endif #ifndef TRYFREE -# define TRYFREE(p) {if (p) free(p);} +#define TRYFREE(p) \ + { \ + if (p) free(p); \ + } #endif /* @@ -72,115 +73,111 @@ /* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */ - // NOT sure that this work on ALL platform #define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32)) #ifndef SEEK_CUR -#define SEEK_CUR 1 +#define SEEK_CUR 1 #endif #ifndef SEEK_END -#define SEEK_END 2 +#define SEEK_END 2 #endif #ifndef SEEK_SET -#define SEEK_SET 0 +#define SEEK_SET 0 #endif #ifndef DEF_MEM_LEVEL #if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 +#define DEF_MEM_LEVEL 8 #else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif #endif -const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; +const char zip_copyright[] = " zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll"; +#define SIZEDATA_INDATABLOCK (4096 - (4 * 4)) -#define SIZEDATA_INDATABLOCK (4096-(4*4)) - -#define LOCALHEADERMAGIC (0x04034b50) -#define CENTRALHEADERMAGIC (0x02014b50) -#define ENDHEADERMAGIC (0x06054b50) -#define ZIP64ENDHEADERMAGIC (0x6064b50) -#define ZIP64ENDLOCHEADERMAGIC (0x7064b50) +#define LOCALHEADERMAGIC (0x04034b50) +#define CENTRALHEADERMAGIC (0x02014b50) +#define ENDHEADERMAGIC (0x06054b50) +#define ZIP64ENDHEADERMAGIC (0x6064b50) +#define ZIP64ENDLOCHEADERMAGIC (0x7064b50) #define FLAG_LOCALHEADER_OFFSET (0x06) -#define CRC_LOCALHEADER_OFFSET (0x0e) +#define CRC_LOCALHEADER_OFFSET (0x0e) #define SIZECENTRALHEADER (0x2e) /* 46 */ typedef struct linkedlist_datablock_internal_s { - struct linkedlist_datablock_internal_s* next_datablock; - uLong avail_in_this_block; - uLong filled_in_this_block; - uLong unused; /* for future use and alignement */ - unsigned char data[SIZEDATA_INDATABLOCK]; + struct linkedlist_datablock_internal_s* next_datablock; + uLong avail_in_this_block; + uLong filled_in_this_block; + uLong unused; /* for future use and alignement */ + unsigned char data[SIZEDATA_INDATABLOCK]; } linkedlist_datablock_internal; typedef struct linkedlist_data_s { - linkedlist_datablock_internal* first_block; - linkedlist_datablock_internal* last_block; + linkedlist_datablock_internal* first_block; + linkedlist_datablock_internal* last_block; } linkedlist_data; - typedef struct { - z_stream stream; /* zLib stream structure for inflate */ + z_stream stream; /* zLib stream structure for inflate */ #ifdef HAVE_BZIP2 - bz_stream bstream; /* bzLib stream structure for bziped */ + bz_stream bstream; /* bzLib stream structure for bziped */ #endif - int stream_initialised; /* 1 is stream is initialised */ - uInt pos_in_buffered_data; /* last written byte in buffered_data */ + int stream_initialised; /* 1 is stream is initialised */ + uInt pos_in_buffered_data; /* last written byte in buffered_data */ - ZPOS64_T pos_local_header; /* offset of the local header of the file + ZPOS64_T pos_local_header; /* offset of the local header of the file currenty writing */ - char* central_header; /* central header data for the current file */ - uLong size_centralExtra; - uLong size_centralheader; /* size of the central header for cur file */ - uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */ - uLong flag; /* flag of the file currently writing */ + char* central_header; /* central header data for the current file */ + uLong size_centralExtra; + uLong size_centralheader; /* size of the central header for cur file */ + uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */ + uLong flag; /* flag of the file currently writing */ - int method; /* compression method of file currenty wr.*/ - int raw; /* 1 for directly writing raw data */ - Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/ - uLong dosDate; - uLong crc32; - int encrypt; - int zip64; /* Add ZIP64 extened information in the extra field */ - ZPOS64_T pos_zip64extrainfo; - ZPOS64_T totalCompressedData; - ZPOS64_T totalUncompressedData; + int method; /* compression method of file currenty wr.*/ + int raw; /* 1 for directly writing raw data */ + Byte buffered_data[Z_BUFSIZE]; /* buffer contain compressed data to be writ*/ + uLong dosDate; + uLong crc32; + int encrypt; + int zip64; /* Add ZIP64 extened information in the extra field */ + ZPOS64_T pos_zip64extrainfo; + ZPOS64_T totalCompressedData; + ZPOS64_T totalUncompressedData; #ifndef NOCRYPT - unsigned long keys[3]; /* keys defining the pseudo-random sequence */ - const unsigned long* pcrc_32_tab; - int crypt_header_size; + unsigned long keys[3]; /* keys defining the pseudo-random sequence */ + const unsigned long* pcrc_32_tab; + int crypt_header_size; #endif } curfile64_info; typedef struct { - zlib_filefunc64_32_def z_filefunc; - voidpf filestream; /* io structore of the zipfile */ - linkedlist_data central_dir;/* datablock with central dir in construction*/ - int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ - curfile64_info ci; /* info on the file curretly writing */ + zlib_filefunc64_32_def z_filefunc; + voidpf filestream; /* io structore of the zipfile */ + linkedlist_data central_dir; /* datablock with central dir in construction*/ + int in_opened_file_inzip; /* 1 if a file in the zip is currently writ.*/ + curfile64_info ci; /* info on the file curretly writing */ - ZPOS64_T begin_pos; /* position of the beginning of the zipfile */ - ZPOS64_T add_position_when_writting_offset; - ZPOS64_T number_entry; + ZPOS64_T begin_pos; /* position of the beginning of the zipfile */ + ZPOS64_T add_position_when_writting_offset; + ZPOS64_T number_entry; #ifndef NO_ADDFILEINEXISTINGZIP - char *globalcomment; + char* globalcomment; #endif } zip64_internal; - #ifndef NOCRYPT #define INCLUDECRYPTINGCODE_IFCRYPTALLOWED #include "crypt.h" @@ -188,93 +185,90 @@ typedef struct local linkedlist_datablock_internal* allocate_new_datablock() { - linkedlist_datablock_internal* ldi; - ldi = (linkedlist_datablock_internal*) - ALLOC(sizeof(linkedlist_datablock_internal)); - if (ldi!=NULL) - { - ldi->next_datablock = NULL ; - ldi->filled_in_this_block = 0 ; - ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ; - } - return ldi; + linkedlist_datablock_internal* ldi; + ldi = (linkedlist_datablock_internal*) + ALLOC(sizeof(linkedlist_datablock_internal)); + if (ldi != NULL) + { + ldi->next_datablock = NULL; + ldi->filled_in_this_block = 0; + ldi->avail_in_this_block = SIZEDATA_INDATABLOCK; + } + return ldi; } local void free_datablock(linkedlist_datablock_internal* ldi) { - while (ldi!=NULL) - { - linkedlist_datablock_internal* ldinext = ldi->next_datablock; - TRYFREE(ldi); - ldi = ldinext; - } + while (ldi != NULL) + { + linkedlist_datablock_internal* ldinext = ldi->next_datablock; + TRYFREE(ldi); + ldi = ldinext; + } } local void init_linkedlist(linkedlist_data* ll) { - ll->first_block = ll->last_block = NULL; + ll->first_block = ll->last_block = NULL; } local void free_linkedlist(linkedlist_data* ll) { - free_datablock(ll->first_block); - ll->first_block = ll->last_block = NULL; + free_datablock(ll->first_block); + ll->first_block = ll->last_block = NULL; } - local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) { - linkedlist_datablock_internal* ldi; - const unsigned char* from_copy; + linkedlist_datablock_internal* ldi; + const unsigned char* from_copy; - if (ll==NULL) - return ZIP_INTERNALERROR; + if (ll == NULL) + return ZIP_INTERNALERROR; - if (ll->last_block == NULL) - { - ll->first_block = ll->last_block = allocate_new_datablock(); - if (ll->first_block == NULL) - return ZIP_INTERNALERROR; - } + if (ll->last_block == NULL) + { + ll->first_block = ll->last_block = allocate_new_datablock(); + if (ll->first_block == NULL) + return ZIP_INTERNALERROR; + } - ldi = ll->last_block; - from_copy = (unsigned char*)buf; + ldi = ll->last_block; + from_copy = (unsigned char*)buf; - while (len>0) - { - uInt copy_this; - uInt i; - unsigned char* to_copy; + while (len > 0) + { + uInt copy_this; + uInt i; + unsigned char* to_copy; - if (ldi->avail_in_this_block==0) - { - ldi->next_datablock = allocate_new_datablock(); - if (ldi->next_datablock == NULL) - return ZIP_INTERNALERROR; - ldi = ldi->next_datablock ; - ll->last_block = ldi; - } + if (ldi->avail_in_this_block == 0) + { + ldi->next_datablock = allocate_new_datablock(); + if (ldi->next_datablock == NULL) + return ZIP_INTERNALERROR; + ldi = ldi->next_datablock; + ll->last_block = ldi; + } - if (ldi->avail_in_this_block < len) - copy_this = (uInt)ldi->avail_in_this_block; - else - copy_this = (uInt)len; + if (ldi->avail_in_this_block < len) + copy_this = (uInt)ldi->avail_in_this_block; + else + copy_this = (uInt)len; - to_copy = &(ldi->data[ldi->filled_in_this_block]); + to_copy = &(ldi->data[ldi->filled_in_this_block]); - for (i=0;ifilled_in_this_block += copy_this; - ldi->avail_in_this_block -= copy_this; - from_copy += copy_this ; - len -= copy_this; - } - return ZIP_OK; + ldi->filled_in_this_block += copy_this; + ldi->avail_in_this_block -= copy_this; + from_copy += copy_this; + len -= copy_this; + } + return ZIP_OK; } - - /****************************************************************************/ #ifndef NO_ADDFILEINEXISTINGZIP @@ -284,188 +278,184 @@ local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len) */ local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)); -local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) +local int zip64local_putValue(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte) { - unsigned char buf[8]; - int n; - for (n = 0; n < nbByte; n++) - { - buf[n] = (unsigned char)(x & 0xff); - x >>= 8; - } - if (x != 0) - { /* data overflow - hack for ZIP64 (X Roche) */ - for (n = 0; n < nbByte; n++) - { - buf[n] = 0xff; - } - } + unsigned char buf[8]; + int n; + for (n = 0; n < nbByte; n++) + { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } + if (x != 0) + { /* data overflow - hack for ZIP64 (X Roche) */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } - if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte) - return ZIP_ERRNO; - else - return ZIP_OK; + if (ZWRITE64(*pzlib_filefunc_def, filestream, buf, nbByte) != (uLong)nbByte) + return ZIP_ERRNO; + else + return ZIP_OK; } local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte)); -local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte) +local void zip64local_putValue_inmemory(void* dest, ZPOS64_T x, int nbByte) { - unsigned char* buf=(unsigned char*)dest; - int n; - for (n = 0; n < nbByte; n++) { - buf[n] = (unsigned char)(x & 0xff); - x >>= 8; - } + unsigned char* buf = (unsigned char*)dest; + int n; + for (n = 0; n < nbByte; n++) + { + buf[n] = (unsigned char)(x & 0xff); + x >>= 8; + } - if (x != 0) - { /* data overflow - hack for ZIP64 */ - for (n = 0; n < nbByte; n++) - { - buf[n] = 0xff; - } - } + if (x != 0) + { /* data overflow - hack for ZIP64 */ + for (n = 0; n < nbByte; n++) + { + buf[n] = 0xff; + } + } } /****************************************************************************/ - local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm) { - uLong year = (uLong)ptm->tm_year; - if (year>=1980) - year-=1980; - else if (year>=80) - year-=80; - return - (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) | - ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); + uLong year = (uLong)ptm->tm_year; + if (year >= 1980) + year -= 1980; + else if (year >= 80) + year -= 80; + return (uLong)(((ptm->tm_mday) + (32 * (ptm->tm_mon + 1)) + (512 * year)) << 16) | + ((ptm->tm_sec / 2) + (32 * ptm->tm_min) + (2048 * (uLong)ptm->tm_hour)); } - /****************************************************************************/ -local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)); +local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int* pi)); -local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi) +local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int* pi) { - unsigned char c; - int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1); - if (err==1) - { - *pi = (int)c; - return ZIP_OK; - } - else - { - if (ZERROR64(*pzlib_filefunc_def,filestream)) - return ZIP_ERRNO; - else - return ZIP_EOF; - } + unsigned char c; + int err = (int)ZREAD64(*pzlib_filefunc_def, filestream, &c, 1); + if (err == 1) + { + *pi = (int)c; + return ZIP_OK; + } + else + { + if (ZERROR64(*pzlib_filefunc_def, filestream)) + return ZIP_ERRNO; + else + return ZIP_EOF; + } } - /* =========================================================================== Reads a long in LSB order from the given gz_stream. Sets */ -local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); +local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)); -local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) +local int zip64local_getShort(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) { - uLong x ; - int i = 0; - int err; + uLong x; + int i = 0; + int err; - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x = (uLong)i; + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x = (uLong)i; - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<8; + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x += ((uLong)i) << 8; - if (err==ZIP_OK) - *pX = x; - else - *pX = 0; - return err; + if (err == ZIP_OK) + *pX = x; + else + *pX = 0; + return err; } -local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX)); +local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)); -local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) +local int zip64local_getLong(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX) { - uLong x ; - int i = 0; - int err; + uLong x; + int i = 0; + int err; - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x = (uLong)i; + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x = (uLong)i; - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<8; + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x += ((uLong)i) << 8; - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<16; + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x += ((uLong)i) << 16; - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((uLong)i)<<24; + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x += ((uLong)i) << 24; - if (err==ZIP_OK) - *pX = x; - else - *pX = 0; - return err; + if (err == ZIP_OK) + *pX = x; + else + *pX = 0; + return err; } -local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)); +local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T* pX)); - -local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX) +local int zip64local_getLong64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T* pX) { - ZPOS64_T x; - int i = 0; - int err; + ZPOS64_T x; + int i = 0; + int err; - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x = (ZPOS64_T)i; + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x = (ZPOS64_T)i; - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<8; + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x += ((ZPOS64_T)i) << 8; - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<16; + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x += ((ZPOS64_T)i) << 16; - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<24; + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x += ((ZPOS64_T)i) << 24; - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<32; + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x += ((ZPOS64_T)i) << 32; - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<40; + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x += ((ZPOS64_T)i) << 40; - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<48; + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x += ((ZPOS64_T)i) << 48; - if (err==ZIP_OK) - err = zip64local_getByte(pzlib_filefunc_def,filestream,&i); - x += ((ZPOS64_T)i)<<56; + if (err == ZIP_OK) + err = zip64local_getByte(pzlib_filefunc_def, filestream, &i); + x += ((ZPOS64_T)i) << 56; - if (err==ZIP_OK) - *pX = x; - else - *pX = 0; + if (err == ZIP_OK) + *pX = x; + else + *pX = 0; - return err; + return err; } #ifndef BUFREADCOMMENT @@ -479,58 +469,56 @@ local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzl local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { - unsigned char* buf; - ZPOS64_T uSizeFile; - ZPOS64_T uBackRead; - ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ - ZPOS64_T uPosFound=0; + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack = 0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound = 0; - if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; + if (ZSEEK64(*pzlib_filefunc_def, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; + uSizeFile = ZTELL64(*pzlib_filefunc_def, filestream); - uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + if (uMaxBack > uSizeFile) + uMaxBack = uSizeFile; - if (uMaxBack>uSizeFile) - uMaxBack = uSizeFile; + buf = (unsigned char*)ALLOC(BUFREADCOMMENT + 4); + if (buf == NULL) + return 0; - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); - if (buf==NULL) - return 0; + uBackRead = 4; + while (uBackRead < uMaxBack) + { + uLong uReadSize; + ZPOS64_T uReadPos; + int i; + if (uBackRead + BUFREADCOMMENT > uMaxBack) + uBackRead = uMaxBack; + else + uBackRead += BUFREADCOMMENT; + uReadPos = uSizeFile - uBackRead; - uBackRead = 4; - while (uBackReaduMaxBack) - uBackRead = uMaxBack; - else - uBackRead+=BUFREADCOMMENT; - uReadPos = uSizeFile-uBackRead ; + uReadSize = ((BUFREADCOMMENT + 4) < (uSizeFile - uReadPos)) ? (BUFREADCOMMENT + 4) : (uLong)(uSizeFile - uReadPos); + if (ZSEEK64(*pzlib_filefunc_def, filestream, uReadPos, ZLIB_FILEFUNC_SEEK_SET) != 0) + break; - uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? - (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); - if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) - break; + if (ZREAD64(*pzlib_filefunc_def, filestream, buf, uReadSize) != uReadSize) + break; - if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) - break; + for (i = (int)uReadSize - 3; (i--) > 0;) + if (((*(buf + i)) == 0x50) && ((*(buf + i + 1)) == 0x4b) && + ((*(buf + i + 2)) == 0x05) && ((*(buf + i + 3)) == 0x06)) + { + uPosFound = uReadPos + i; + break; + } - for (i=(int)uReadSize-3; (i--)>0;) - if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && - ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06)) - { - uPosFound = uReadPos+i; - break; - } - - if (uPosFound!=0) - break; - } - TRYFREE(buf); - return uPosFound; + if (uPosFound != 0) + break; + } + TRYFREE(buf); + return uPosFound; } /* @@ -541,507 +529,496 @@ local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* p local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream) { - unsigned char* buf; - ZPOS64_T uSizeFile; - ZPOS64_T uBackRead; - ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */ - ZPOS64_T uPosFound=0; - uLong uL; - ZPOS64_T relativeOffset; + unsigned char* buf; + ZPOS64_T uSizeFile; + ZPOS64_T uBackRead; + ZPOS64_T uMaxBack = 0xffff; /* maximum size of global comment */ + ZPOS64_T uPosFound = 0; + uLong uL; + ZPOS64_T relativeOffset; - if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0) - return 0; + if (ZSEEK64(*pzlib_filefunc_def, filestream, 0, ZLIB_FILEFUNC_SEEK_END) != 0) + return 0; - uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream); + uSizeFile = ZTELL64(*pzlib_filefunc_def, filestream); - if (uMaxBack>uSizeFile) - uMaxBack = uSizeFile; + if (uMaxBack > uSizeFile) + uMaxBack = uSizeFile; - buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4); - if (buf==NULL) - return 0; + buf = (unsigned char*)ALLOC(BUFREADCOMMENT + 4); + if (buf == NULL) + return 0; - uBackRead = 4; - while (uBackReaduMaxBack) - uBackRead = uMaxBack; - else - uBackRead+=BUFREADCOMMENT; - uReadPos = uSizeFile-uBackRead ; + uBackRead = 4; + while (uBackRead < uMaxBack) + { + uLong uReadSize; + ZPOS64_T uReadPos; + int i; + if (uBackRead + BUFREADCOMMENT > uMaxBack) + uBackRead = uMaxBack; + else + uBackRead += BUFREADCOMMENT; + uReadPos = uSizeFile - uBackRead; - uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ? - (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos); - if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0) - break; + uReadSize = ((BUFREADCOMMENT + 4) < (uSizeFile - uReadPos)) ? (BUFREADCOMMENT + 4) : (uLong)(uSizeFile - uReadPos); + if (ZSEEK64(*pzlib_filefunc_def, filestream, uReadPos, ZLIB_FILEFUNC_SEEK_SET) != 0) + break; - if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize) - break; + if (ZREAD64(*pzlib_filefunc_def, filestream, buf, uReadSize) != uReadSize) + break; - for (i=(int)uReadSize-3; (i--)>0;) - { - // Signature "0x07064b50" Zip64 end of central directory locater - if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07)) - { - uPosFound = uReadPos+i; - break; - } - } + for (i = (int)uReadSize - 3; (i--) > 0;) + { + // Signature "0x07064b50" Zip64 end of central directory locater + if (((*(buf + i)) == 0x50) && ((*(buf + i + 1)) == 0x4b) && ((*(buf + i + 2)) == 0x06) && ((*(buf + i + 3)) == 0x07)) + { + uPosFound = uReadPos + i; + break; + } + } - if (uPosFound!=0) - break; - } + if (uPosFound != 0) + break; + } - TRYFREE(buf); - if (uPosFound == 0) - return 0; + TRYFREE(buf); + if (uPosFound == 0) + return 0; - /* Zip64 end of central directory locator */ - if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0) - return 0; + /* Zip64 end of central directory locator */ + if (ZSEEK64(*pzlib_filefunc_def, filestream, uPosFound, ZLIB_FILEFUNC_SEEK_SET) != 0) + return 0; - /* the signature, already checked */ - if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) - return 0; + /* the signature, already checked */ + if (zip64local_getLong(pzlib_filefunc_def, filestream, &uL) != ZIP_OK) + return 0; - /* number of the disk with the start of the zip64 end of central directory */ - if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) - return 0; - if (uL != 0) - return 0; + /* number of the disk with the start of the zip64 end of central directory */ + if (zip64local_getLong(pzlib_filefunc_def, filestream, &uL) != ZIP_OK) + return 0; + if (uL != 0) + return 0; - /* relative offset of the zip64 end of central directory record */ - if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK) - return 0; + /* relative offset of the zip64 end of central directory record */ + if (zip64local_getLong64(pzlib_filefunc_def, filestream, &relativeOffset) != ZIP_OK) + return 0; - /* total number of disks */ - if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) - return 0; - if (uL != 1) - return 0; + /* total number of disks */ + if (zip64local_getLong(pzlib_filefunc_def, filestream, &uL) != ZIP_OK) + return 0; + if (uL != 1) + return 0; - /* Goto Zip64 end of central directory record */ - if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0) - return 0; + /* Goto Zip64 end of central directory record */ + if (ZSEEK64(*pzlib_filefunc_def, filestream, relativeOffset, ZLIB_FILEFUNC_SEEK_SET) != 0) + return 0; - /* the signature */ - if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK) - return 0; + /* the signature */ + if (zip64local_getLong(pzlib_filefunc_def, filestream, &uL) != ZIP_OK) + return 0; - if (uL != 0x06064b50) // signature of 'Zip64 end of central directory' - return 0; + if (uL != 0x06064b50) // signature of 'Zip64 end of central directory' + return 0; - return relativeOffset; + return relativeOffset; } int LoadCentralDirectoryRecord(zip64_internal* pziinit) { - int err=ZIP_OK; - ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/ + int err = ZIP_OK; + ZPOS64_T byte_before_the_zipfile; /* byte before the zipfile, (>0 for sfx)*/ - ZPOS64_T size_central_dir; /* size of the central directory */ - ZPOS64_T offset_central_dir; /* offset of start of central directory */ - ZPOS64_T central_pos; - uLong uL; + ZPOS64_T size_central_dir; /* size of the central directory */ + ZPOS64_T offset_central_dir; /* offset of start of central directory */ + ZPOS64_T central_pos; + uLong uL; - uLong number_disk; /* number of the current dist, used for + uLong number_disk; /* number of the current dist, used for spaning ZIP, unsupported, always 0*/ - uLong number_disk_with_CD; /* number the the disk with central dir, used + uLong number_disk_with_CD; /* number the the disk with central dir, used for spaning ZIP, unsupported, always 0*/ - ZPOS64_T number_entry; - ZPOS64_T number_entry_CD; /* total number of entries in + ZPOS64_T number_entry; + ZPOS64_T number_entry_CD; /* total number of entries in the central dir (same than number_entry on nospan) */ - uLong VersionMadeBy; - uLong VersionNeeded; - uLong size_comment; + uLong VersionMadeBy; + uLong VersionNeeded; + uLong size_comment; - int hasZIP64Record = 0; + int hasZIP64Record = 0; - // check first if we find a ZIP64 record - central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream); - if(central_pos > 0) - { - hasZIP64Record = 1; - } - else if(central_pos == 0) - { - central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream); - } + // check first if we find a ZIP64 record + central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc, pziinit->filestream); + if (central_pos > 0) + { + hasZIP64Record = 1; + } + else if (central_pos == 0) + { + central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc, pziinit->filestream); + } -/* disable to allow appending to empty ZIP archive + /* disable to allow appending to empty ZIP archive if (central_pos==0) err=ZIP_ERRNO; */ - if(hasZIP64Record) - { - ZPOS64_T sizeEndOfCentralDirectory; - if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) - err=ZIP_ERRNO; + if (hasZIP64Record) + { + ZPOS64_T sizeEndOfCentralDirectory; + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) + err = ZIP_ERRNO; - /* the signature, already checked */ - if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) - err=ZIP_ERRNO; + /* the signature, already checked */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL) != ZIP_OK) + err = ZIP_ERRNO; - /* size of zip64 end of central directory record */ - if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK) - err=ZIP_ERRNO; + /* size of zip64 end of central directory record */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory) != ZIP_OK) + err = ZIP_ERRNO; - /* version made by */ - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK) - err=ZIP_ERRNO; + /* version made by */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy) != ZIP_OK) + err = ZIP_ERRNO; - /* version needed to extract */ - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK) - err=ZIP_ERRNO; + /* version needed to extract */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded) != ZIP_OK) + err = ZIP_ERRNO; - /* number of this disk */ - if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) - err=ZIP_ERRNO; + /* number of this disk */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &number_disk) != ZIP_OK) + err = ZIP_ERRNO; - /* number of the disk with the start of the central directory */ - if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) - err=ZIP_ERRNO; + /* number of the disk with the start of the central directory */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &number_disk_with_CD) != ZIP_OK) + err = ZIP_ERRNO; - /* total number of entries in the central directory on this disk */ - if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK) - err=ZIP_ERRNO; + /* total number of entries in the central directory on this disk */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry) != ZIP_OK) + err = ZIP_ERRNO; - /* total number of entries in the central directory */ - if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK) - err=ZIP_ERRNO; + /* total number of entries in the central directory */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry_CD) != ZIP_OK) + err = ZIP_ERRNO; - if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) - err=ZIP_BADZIPFILE; + if ((number_entry_CD != number_entry) || (number_disk_with_CD != 0) || (number_disk != 0)) + err = ZIP_BADZIPFILE; - /* size of the central directory */ - if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK) - err=ZIP_ERRNO; + /* size of the central directory */ + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &size_central_dir) != ZIP_OK) + err = ZIP_ERRNO; - /* offset of start of central directory with respect to the + /* offset of start of central directory with respect to the starting disk number */ - if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK) - err=ZIP_ERRNO; + if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &offset_central_dir) != ZIP_OK) + err = ZIP_ERRNO; - // TODO.. - // read the comment from the standard central header. - size_comment = 0; - } - else - { - // Read End of central Directory info - if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0) - err=ZIP_ERRNO; + // TODO.. + // read the comment from the standard central header. + size_comment = 0; + } + else + { + // Read End of central Directory info + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0) + err = ZIP_ERRNO; - /* the signature, already checked */ - if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK) - err=ZIP_ERRNO; + /* the signature, already checked */ + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL) != ZIP_OK) + err = ZIP_ERRNO; - /* number of this disk */ - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK) - err=ZIP_ERRNO; + /* number of this disk */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &number_disk) != ZIP_OK) + err = ZIP_ERRNO; - /* number of the disk with the start of the central directory */ - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK) - err=ZIP_ERRNO; + /* number of the disk with the start of the central directory */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &number_disk_with_CD) != ZIP_OK) + err = ZIP_ERRNO; - /* total number of entries in the central dir on this disk */ - number_entry = 0; - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) - err=ZIP_ERRNO; - else - number_entry = uL; + /* total number of entries in the central dir on this disk */ + number_entry = 0; + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL) != ZIP_OK) + err = ZIP_ERRNO; + else + number_entry = uL; - /* total number of entries in the central dir */ - number_entry_CD = 0; - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) - err=ZIP_ERRNO; - else - number_entry_CD = uL; + /* total number of entries in the central dir */ + number_entry_CD = 0; + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL) != ZIP_OK) + err = ZIP_ERRNO; + else + number_entry_CD = uL; - if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0)) - err=ZIP_BADZIPFILE; + if ((number_entry_CD != number_entry) || (number_disk_with_CD != 0) || (number_disk != 0)) + err = ZIP_BADZIPFILE; - /* size of the central directory */ - size_central_dir = 0; - if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) - err=ZIP_ERRNO; - else - size_central_dir = uL; + /* size of the central directory */ + size_central_dir = 0; + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL) != ZIP_OK) + err = ZIP_ERRNO; + else + size_central_dir = uL; - /* offset of start of central directory with respect to the starting disk number */ - offset_central_dir = 0; - if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK) - err=ZIP_ERRNO; - else - offset_central_dir = uL; + /* offset of start of central directory with respect to the starting disk number */ + offset_central_dir = 0; + if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL) != ZIP_OK) + err = ZIP_ERRNO; + else + offset_central_dir = uL; + /* zipfile global comment length */ + if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment) != ZIP_OK) + err = ZIP_ERRNO; + } - /* zipfile global comment length */ - if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK) - err=ZIP_ERRNO; - } + if ((central_pos < offset_central_dir + size_central_dir) && + (err == ZIP_OK)) + err = ZIP_BADZIPFILE; - if ((central_posz_filefunc, pziinit->filestream); + return ZIP_ERRNO; + } - if (err!=ZIP_OK) - { - ZCLOSE64(pziinit->z_filefunc, pziinit->filestream); - return ZIP_ERRNO; - } + if (size_comment > 0) + { + pziinit->globalcomment = (char*)ALLOC(size_comment + 1); + if (pziinit->globalcomment) + { + size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment, size_comment); + pziinit->globalcomment[size_comment] = 0; + } + } - if (size_comment>0) - { - pziinit->globalcomment = (char*)ALLOC(size_comment+1); - if (pziinit->globalcomment) - { - size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment); - pziinit->globalcomment[size_comment]=0; - } - } + byte_before_the_zipfile = central_pos - (offset_central_dir + size_central_dir); + pziinit->add_position_when_writting_offset = byte_before_the_zipfile; - byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir); - pziinit->add_position_when_writting_offset = byte_before_the_zipfile; + { + ZPOS64_T size_central_dir_to_read = size_central_dir; + size_t buf_size = SIZEDATA_INDATABLOCK; + void* buf_read = (void*)ALLOC(buf_size); + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) + err = ZIP_ERRNO; - { - ZPOS64_T size_central_dir_to_read = size_central_dir; - size_t buf_size = SIZEDATA_INDATABLOCK; - void* buf_read = (void*)ALLOC(buf_size); - if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) - err=ZIP_ERRNO; + while ((size_central_dir_to_read > 0) && (err == ZIP_OK)) + { + ZPOS64_T read_this = SIZEDATA_INDATABLOCK; + if (read_this > size_central_dir_to_read) + read_this = size_central_dir_to_read; - while ((size_central_dir_to_read>0) && (err==ZIP_OK)) - { - ZPOS64_T read_this = SIZEDATA_INDATABLOCK; - if (read_this > size_central_dir_to_read) - read_this = size_central_dir_to_read; + if (ZREAD64(pziinit->z_filefunc, pziinit->filestream, buf_read, (uLong)read_this) != read_this) + err = ZIP_ERRNO; - if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this) - err=ZIP_ERRNO; + if (err == ZIP_OK) + err = add_data_in_datablock(&pziinit->central_dir, buf_read, (uLong)read_this); - if (err==ZIP_OK) - err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this); + size_central_dir_to_read -= read_this; + } + TRYFREE(buf_read); + } + pziinit->begin_pos = byte_before_the_zipfile; + pziinit->number_entry = number_entry_CD; - size_central_dir_to_read-=read_this; - } - TRYFREE(buf_read); - } - pziinit->begin_pos = byte_before_the_zipfile; - pziinit->number_entry = number_entry_CD; + if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0) + err = ZIP_ERRNO; - if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0) - err=ZIP_ERRNO; - - return err; + return err; } - #endif /* !NO_ADDFILEINEXISTINGZIP*/ - /************************************************************/ -extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) +extern zipFile ZEXPORT zipOpen3(const void* pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def) { - zip64_internal ziinit; - zip64_internal* zi; - int err=ZIP_OK; + zip64_internal ziinit; + zip64_internal* zi; + int err = ZIP_OK; - ziinit.z_filefunc.zseek32_file = NULL; - ziinit.z_filefunc.ztell32_file = NULL; - if (pzlib_filefunc64_32_def==NULL) - fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64); - else - ziinit.z_filefunc = *pzlib_filefunc64_32_def; + ziinit.z_filefunc.zseek32_file = NULL; + ziinit.z_filefunc.ztell32_file = NULL; + if (pzlib_filefunc64_32_def == NULL) + fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64); + else + ziinit.z_filefunc = *pzlib_filefunc64_32_def; - ziinit.filestream = ZOPEN64(ziinit.z_filefunc, - pathname, - (append == APPEND_STATUS_CREATE) ? - (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : - (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); + ziinit.filestream = ZOPEN64(ziinit.z_filefunc, + pathname, + (append == APPEND_STATUS_CREATE) ? (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) : (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING)); - if (ziinit.filestream == NULL) - return NULL; + if (ziinit.filestream == NULL) + return NULL; - if (append == APPEND_STATUS_CREATEAFTER) - ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END); + if (append == APPEND_STATUS_CREATEAFTER) + ZSEEK64(ziinit.z_filefunc, ziinit.filestream, 0, SEEK_END); - ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream); - ziinit.in_opened_file_inzip = 0; - ziinit.ci.stream_initialised = 0; - ziinit.number_entry = 0; - ziinit.add_position_when_writting_offset = 0; - init_linkedlist(&(ziinit.central_dir)); + ziinit.begin_pos = ZTELL64(ziinit.z_filefunc, ziinit.filestream); + ziinit.in_opened_file_inzip = 0; + ziinit.ci.stream_initialised = 0; + ziinit.number_entry = 0; + ziinit.add_position_when_writting_offset = 0; + init_linkedlist(&(ziinit.central_dir)); + zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); + if (zi == NULL) + { + ZCLOSE64(ziinit.z_filefunc, ziinit.filestream); + return NULL; + } + /* now we add file in a zipfile */ +#ifndef NO_ADDFILEINEXISTINGZIP + ziinit.globalcomment = NULL; + if (append == APPEND_STATUS_ADDINZIP) + { + // Read and Cache Central Directory Records + err = LoadCentralDirectoryRecord(&ziinit); + } - zi = (zip64_internal*)ALLOC(sizeof(zip64_internal)); - if (zi==NULL) - { - ZCLOSE64(ziinit.z_filefunc,ziinit.filestream); - return NULL; - } + if (globalcomment) + { + *globalcomment = ziinit.globalcomment; + } +#endif /* !NO_ADDFILEINEXISTINGZIP*/ - /* now we add file in a zipfile */ -# ifndef NO_ADDFILEINEXISTINGZIP - ziinit.globalcomment = NULL; - if (append == APPEND_STATUS_ADDINZIP) - { - // Read and Cache Central Directory Records - err = LoadCentralDirectoryRecord(&ziinit); - } - - if (globalcomment) - { - *globalcomment = ziinit.globalcomment; - } -# endif /* !NO_ADDFILEINEXISTINGZIP*/ - - if (err != ZIP_OK) - { -# ifndef NO_ADDFILEINEXISTINGZIP - TRYFREE(ziinit.globalcomment); -# endif /* !NO_ADDFILEINEXISTINGZIP*/ - TRYFREE(zi); - return NULL; - } - else - { - *zi = ziinit; - return (zipFile)zi; - } + if (err != ZIP_OK) + { +#ifndef NO_ADDFILEINEXISTINGZIP + TRYFREE(ziinit.globalcomment); +#endif /* !NO_ADDFILEINEXISTINGZIP*/ + TRYFREE(zi); + return NULL; + } + else + { + *zi = ziinit; + return (zipFile)zi; + } } -extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) +extern zipFile ZEXPORT zipOpen2(const char* pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def) { - if (pzlib_filefunc32_def != NULL) - { - zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; - fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def); - return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); - } - else - return zipOpen3(pathname, append, globalcomment, NULL); + if (pzlib_filefunc32_def != NULL) + { + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; + fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill, pzlib_filefunc32_def); + return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); + } + else + return zipOpen3(pathname, append, globalcomment, NULL); } -extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) +extern zipFile ZEXPORT zipOpen2_64(const void* pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def) { - if (pzlib_filefunc_def != NULL) - { - zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; - zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; - zlib_filefunc64_32_def_fill.ztell32_file = NULL; - zlib_filefunc64_32_def_fill.zseek32_file = NULL; - return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); - } - else - return zipOpen3(pathname, append, globalcomment, NULL); + if (pzlib_filefunc_def != NULL) + { + zlib_filefunc64_32_def zlib_filefunc64_32_def_fill; + zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def; + zlib_filefunc64_32_def_fill.ztell32_file = NULL; + zlib_filefunc64_32_def_fill.zseek32_file = NULL; + return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill); + } + else + return zipOpen3(pathname, append, globalcomment, NULL); } - - -extern zipFile ZEXPORT zipOpen (const char* pathname, int append) +extern zipFile ZEXPORT zipOpen(const char* pathname, int append) { - return zipOpen3((const void*)pathname,append,NULL,NULL); + return zipOpen3((const void*)pathname, append, NULL, NULL); } -extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append) +extern zipFile ZEXPORT zipOpen64(const void* pathname, int append) { - return zipOpen3(pathname,append,NULL,NULL); + return zipOpen3(pathname, append, NULL, NULL); } int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local) { - /* write the local header */ - int err; - uInt size_filename = (uInt)strlen(filename); - uInt size_extrafield = size_extrafield_local; + /* write the local header */ + int err; + uInt size_filename = (uInt)strlen(filename); + uInt size_extrafield = size_extrafield_local; - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)LOCALHEADERMAGIC, 4); - if (err==ZIP_OK) - { - if(zi->ci.zip64) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */ - else - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */ - } + if (err == ZIP_OK) + { + if (zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)45, 2); /* version needed to extract */ + else + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)20, 2); /* version needed to extract */ + } - if (err==ZIP_OK) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2); + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->ci.flag, 2); - if (err==ZIP_OK) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2); + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->ci.method, 2); - if (err==ZIP_OK) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4); + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->ci.dosDate, 4); - // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later - if (err==ZIP_OK) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */ - if (err==ZIP_OK) - { - if(zi->ci.zip64) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */ - else - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */ - } - if (err==ZIP_OK) - { - if(zi->ci.zip64) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */ - else - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */ - } + // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0, 4); /* crc 32, unknown */ + if (err == ZIP_OK) + { + if (zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0xFFFFFFFF, 4); /* compressed size, unknown */ + else + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0, 4); /* compressed size, unknown */ + } + if (err == ZIP_OK) + { + if (zi->ci.zip64) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0xFFFFFFFF, 4); /* uncompressed size, unknown */ + else + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0, 4); /* uncompressed size, unknown */ + } - if (err==ZIP_OK) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2); + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)size_filename, 2); - if(zi->ci.zip64) - { - size_extrafield += 20; - } + if (zi->ci.zip64) + { + size_extrafield += 20; + } - if (err==ZIP_OK) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2); + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)size_extrafield, 2); - if ((err==ZIP_OK) && (size_filename > 0)) - { - if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename) - err = ZIP_ERRNO; - } + if ((err == ZIP_OK) && (size_filename > 0)) + { + if (ZWRITE64(zi->z_filefunc, zi->filestream, filename, size_filename) != size_filename) + err = ZIP_ERRNO; + } - if ((err==ZIP_OK) && (size_extrafield_local > 0)) - { - if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local) - err = ZIP_ERRNO; - } + if ((err == ZIP_OK) && (size_extrafield_local > 0)) + { + if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local) + err = ZIP_ERRNO; + } + if ((err == ZIP_OK) && (zi->ci.zip64)) + { + // write the Zip64 extended info + short HeaderID = 1; + short DataSize = 16; + ZPOS64_T CompressedSize = 0; + ZPOS64_T UncompressedSize = 0; - if ((err==ZIP_OK) && (zi->ci.zip64)) - { - // write the Zip64 extended info - short HeaderID = 1; - short DataSize = 16; - ZPOS64_T CompressedSize = 0; - ZPOS64_T UncompressedSize = 0; + // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) + zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc, zi->filestream); - // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file) - zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID, 2); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize, 2); - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2); - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize, 8); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize, 8); + } - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8); - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8); - } - - return err; + return err; } /* @@ -1052,953 +1029,946 @@ int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_ex It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize unnecessary allocations. */ -extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, - int windowBits,int memLevel, int strategy, - const char* password, uLong crcForCrypting, - uLong versionMadeBy, uLong flagBase, int zip64) +extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits, int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase, int zip64) { - zip64_internal* zi; - uInt size_filename; - uInt size_comment; - uInt i; - int err = ZIP_OK; + zip64_internal* zi; + uInt size_filename; + uInt size_comment; + uInt i; + int err = ZIP_OK; -# ifdef NOCRYPT - if (password != NULL) - return ZIP_PARAMERROR; -# endif +#ifdef NOCRYPT + if (password != NULL) + return ZIP_PARAMERROR; +#endif - if (file == NULL) - return ZIP_PARAMERROR; + if (file == NULL) + return ZIP_PARAMERROR; #ifdef HAVE_BZIP2 - if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED)) - return ZIP_PARAMERROR; + if ((method != 0) && (method != Z_DEFLATED) && (method != Z_BZIP2ED)) + return ZIP_PARAMERROR; #else - if ((method!=0) && (method!=Z_DEFLATED)) - return ZIP_PARAMERROR; + if ((method != 0) && (method != Z_DEFLATED)) + return ZIP_PARAMERROR; #endif - zi = (zip64_internal*)file; + zi = (zip64_internal*)file; - if (zi->in_opened_file_inzip == 1) - { - err = zipCloseFileInZip (file); - if (err != ZIP_OK) - return err; - } + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip(file); + if (err != ZIP_OK) + return err; + } - if (filename==NULL) - filename="-"; + if (filename == NULL) + filename = "-"; - if (comment==NULL) - size_comment = 0; - else - size_comment = (uInt)strlen(comment); + if (comment == NULL) + size_comment = 0; + else + size_comment = (uInt)strlen(comment); - size_filename = (uInt)strlen(filename); + size_filename = (uInt)strlen(filename); - if (zipfi == NULL) - zi->ci.dosDate = 0; - else - { - if (zipfi->dosDate != 0) - zi->ci.dosDate = zipfi->dosDate; - else - zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date); - } + if (zipfi == NULL) + zi->ci.dosDate = 0; + else + { + if (zipfi->dosDate != 0) + zi->ci.dosDate = zipfi->dosDate; + else + zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date); + } - zi->ci.flag = flagBase; - if ((level==8) || (level==9)) - zi->ci.flag |= 2; - if ((level==2)) - zi->ci.flag |= 4; - if ((level==1)) - zi->ci.flag |= 6; - if (password != NULL) - zi->ci.flag |= 1; + zi->ci.flag = flagBase; + if ((level == 8) || (level == 9)) + zi->ci.flag |= 2; + if ((level == 2)) + zi->ci.flag |= 4; + if ((level == 1)) + zi->ci.flag |= 6; + if (password != NULL) + zi->ci.flag |= 1; - zi->ci.crc32 = 0; - zi->ci.method = method; - zi->ci.encrypt = 0; - zi->ci.stream_initialised = 0; - zi->ci.pos_in_buffered_data = 0; - zi->ci.raw = raw; - zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream); + zi->ci.crc32 = 0; + zi->ci.method = method; + zi->ci.encrypt = 0; + zi->ci.stream_initialised = 0; + zi->ci.pos_in_buffered_data = 0; + zi->ci.raw = raw; + zi->ci.pos_local_header = ZTELL64(zi->z_filefunc, zi->filestream); - zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; - zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data + zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment; + zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data - zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree); + zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree); - zi->ci.size_centralExtra = size_extrafield_global; - zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4); - /* version info */ - zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2); - zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2); - zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2); - zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2); - zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4); - zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/ - zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/ - zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/ - zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2); - zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2); - zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2); - zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/ + zi->ci.size_centralExtra = size_extrafield_global; + zip64local_putValue_inmemory(zi->ci.central_header, (uLong)CENTRALHEADERMAGIC, 4); + /* version info */ + zip64local_putValue_inmemory(zi->ci.central_header + 4, (uLong)versionMadeBy, 2); + zip64local_putValue_inmemory(zi->ci.central_header + 6, (uLong)20, 2); + zip64local_putValue_inmemory(zi->ci.central_header + 8, (uLong)zi->ci.flag, 2); + zip64local_putValue_inmemory(zi->ci.central_header + 10, (uLong)zi->ci.method, 2); + zip64local_putValue_inmemory(zi->ci.central_header + 12, (uLong)zi->ci.dosDate, 4); + zip64local_putValue_inmemory(zi->ci.central_header + 16, (uLong)0, 4); /*crc*/ + zip64local_putValue_inmemory(zi->ci.central_header + 20, (uLong)0, 4); /*compr size*/ + zip64local_putValue_inmemory(zi->ci.central_header + 24, (uLong)0, 4); /*uncompr size*/ + zip64local_putValue_inmemory(zi->ci.central_header + 28, (uLong)size_filename, 2); + zip64local_putValue_inmemory(zi->ci.central_header + 30, (uLong)size_extrafield_global, 2); + zip64local_putValue_inmemory(zi->ci.central_header + 32, (uLong)size_comment, 2); + zip64local_putValue_inmemory(zi->ci.central_header + 34, (uLong)0, 2); /*disk nm start*/ - if (zipfi==NULL) - zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2); - else - zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2); + if (zipfi == NULL) + zip64local_putValue_inmemory(zi->ci.central_header + 36, (uLong)0, 2); + else + zip64local_putValue_inmemory(zi->ci.central_header + 36, (uLong)zipfi->internal_fa, 2); - if (zipfi==NULL) - zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4); - else - zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4); + if (zipfi == NULL) + zip64local_putValue_inmemory(zi->ci.central_header + 38, (uLong)0, 4); + else + zip64local_putValue_inmemory(zi->ci.central_header + 38, (uLong)zipfi->external_fa, 4); - if(zi->ci.pos_local_header >= 0xffffffff) - zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4); - else - zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4); + if (zi->ci.pos_local_header >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header + 42, (uLong)0xffffffff, 4); + else + zip64local_putValue_inmemory(zi->ci.central_header + 42, (uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset, 4); - for (i=0;ici.central_header+SIZECENTRALHEADER+i) = *(filename+i); + for (i = 0; i < size_filename; i++) + *(zi->ci.central_header + SIZECENTRALHEADER + i) = *(filename + i); - for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+i) = - *(((const char*)extrafield_global)+i); + for (i = 0; i < size_extrafield_global; i++) + *(zi->ci.central_header + SIZECENTRALHEADER + size_filename + i) = + *(((const char*)extrafield_global) + i); - for (i=0;ici.central_header+SIZECENTRALHEADER+size_filename+ - size_extrafield_global+i) = *(comment+i); - if (zi->ci.central_header == NULL) - return ZIP_INTERNALERROR; + for (i = 0; i < size_comment; i++) + *(zi->ci.central_header + SIZECENTRALHEADER + size_filename + + size_extrafield_global + i) = *(comment + i); + if (zi->ci.central_header == NULL) + return ZIP_INTERNALERROR; - zi->ci.zip64 = zip64; - zi->ci.totalCompressedData = 0; - zi->ci.totalUncompressedData = 0; - zi->ci.pos_zip64extrainfo = 0; + zi->ci.zip64 = zip64; + zi->ci.totalCompressedData = 0; + zi->ci.totalUncompressedData = 0; + zi->ci.pos_zip64extrainfo = 0; - err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local); + err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local); #ifdef HAVE_BZIP2 - zi->ci.bstream.avail_in = (uInt)0; - zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; - zi->ci.bstream.total_in_hi32 = 0; - zi->ci.bstream.total_in_lo32 = 0; - zi->ci.bstream.total_out_hi32 = 0; - zi->ci.bstream.total_out_lo32 = 0; + zi->ci.bstream.avail_in = (uInt)0; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + zi->ci.bstream.total_in_hi32 = 0; + zi->ci.bstream.total_in_lo32 = 0; + zi->ci.bstream.total_out_hi32 = 0; + zi->ci.bstream.total_out_lo32 = 0; #endif - zi->ci.stream.avail_in = (uInt)0; - zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.stream.next_out = zi->ci.buffered_data; - zi->ci.stream.total_in = 0; - zi->ci.stream.total_out = 0; - zi->ci.stream.data_type = Z_BINARY; + zi->ci.stream.avail_in = (uInt)0; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + zi->ci.stream.total_in = 0; + zi->ci.stream.total_out = 0; + zi->ci.stream.data_type = Z_BINARY; #ifdef HAVE_BZIP2 - if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + if ((err == ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) #else - if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + if ((err == ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) #endif - { - if(zi->ci.method == Z_DEFLATED) - { - zi->ci.stream.zalloc = (alloc_func)0; - zi->ci.stream.zfree = (free_func)0; - zi->ci.stream.opaque = (voidpf)0; + { + if (zi->ci.method == Z_DEFLATED) + { + zi->ci.stream.zalloc = (alloc_func)0; + zi->ci.stream.zfree = (free_func)0; + zi->ci.stream.opaque = (voidpf)0; - if (windowBits>0) - windowBits = -windowBits; + if (windowBits > 0) + windowBits = -windowBits; - err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy); + err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy); - if (err==Z_OK) - zi->ci.stream_initialised = Z_DEFLATED; - } - else if(zi->ci.method == Z_BZIP2ED) - { + if (err == Z_OK) + zi->ci.stream_initialised = Z_DEFLATED; + } + else if (zi->ci.method == Z_BZIP2ED) + { #ifdef HAVE_BZIP2 - // Init BZip stuff here - zi->ci.bstream.bzalloc = 0; - zi->ci.bstream.bzfree = 0; - zi->ci.bstream.opaque = (voidpf)0; + // Init BZip stuff here + zi->ci.bstream.bzalloc = 0; + zi->ci.bstream.bzfree = 0; + zi->ci.bstream.opaque = (voidpf)0; - err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35); - if(err == BZ_OK) - zi->ci.stream_initialised = Z_BZIP2ED; + err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0, 35); + if (err == BZ_OK) + zi->ci.stream_initialised = Z_BZIP2ED; #endif - } + } + } - } +#ifndef NOCRYPT + zi->ci.crypt_header_size = 0; + if ((err == Z_OK) && (password != NULL)) + { + unsigned char bufHead[RAND_HEAD_LEN]; + unsigned int sizeHead; + zi->ci.encrypt = 1; + zi->ci.pcrc_32_tab = get_crc_table(); + /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ -# ifndef NOCRYPT - zi->ci.crypt_header_size = 0; - if ((err==Z_OK) && (password != NULL)) - { - unsigned char bufHead[RAND_HEAD_LEN]; - unsigned int sizeHead; - zi->ci.encrypt = 1; - zi->ci.pcrc_32_tab = get_crc_table(); - /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/ + sizeHead = crypthead(password, bufHead, RAND_HEAD_LEN, zi->ci.keys, zi->ci.pcrc_32_tab, crcForCrypting); + zi->ci.crypt_header_size = sizeHead; - sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting); - zi->ci.crypt_header_size = sizeHead; + if (ZWRITE64(zi->z_filefunc, zi->filestream, bufHead, sizeHead) != sizeHead) + err = ZIP_ERRNO; + } +#endif - if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead) - err = ZIP_ERRNO; - } -# endif - - if (err==Z_OK) - zi->in_opened_file_inzip = 1; - return err; + if (err == Z_OK) + zi->in_opened_file_inzip = 1; + return err; } -extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, - int windowBits,int memLevel, int strategy, - const char* password, uLong crcForCrypting, - uLong versionMadeBy, uLong flagBase) +extern int ZEXPORT zipOpenNewFileInZip4(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits, int memLevel, int strategy, + const char* password, uLong crcForCrypting, + uLong versionMadeBy, uLong flagBase) { - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - windowBits, memLevel, strategy, - password, crcForCrypting, versionMadeBy, flagBase, 0); + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, versionMadeBy, flagBase, 0); } -extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, - int windowBits,int memLevel, int strategy, - const char* password, uLong crcForCrypting) +extern int ZEXPORT zipOpenNewFileInZip3(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits, int memLevel, int strategy, + const char* password, uLong crcForCrypting) { - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - windowBits, memLevel, strategy, - password, crcForCrypting, VERSIONMADEBY, 0, 0); + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, 0); } extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, - int windowBits,int memLevel, int strategy, - const char* password, uLong crcForCrypting, int zip64) + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, + int windowBits, int memLevel, int strategy, + const char* password, uLong crcForCrypting, int zip64) { - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - windowBits, memLevel, strategy, - password, crcForCrypting, VERSIONMADEBY, 0, zip64); + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + windowBits, memLevel, strategy, + password, crcForCrypting, VERSIONMADEBY, 0, zip64); } extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw) + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw) { - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0, VERSIONMADEBY, 0, 0); + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); } extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void* extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int raw, int zip64) + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int raw, int zip64) { - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, raw, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0, VERSIONMADEBY, 0, zip64); + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, raw, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); } -extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void*extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level, int zip64) +extern int ZEXPORT zipOpenNewFileInZip64(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level, int zip64) { - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, 0, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0, VERSIONMADEBY, 0, zip64); + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, zip64); } -extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi, - const void* extrafield_local, uInt size_extrafield_local, - const void*extrafield_global, uInt size_extrafield_global, - const char* comment, int method, int level) +extern int ZEXPORT zipOpenNewFileInZip(zipFile file, const char* filename, const zip_fileinfo* zipfi, + const void* extrafield_local, uInt size_extrafield_local, + const void* extrafield_global, uInt size_extrafield_global, + const char* comment, int method, int level) { - return zipOpenNewFileInZip4_64 (file, filename, zipfi, - extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, - comment, method, level, 0, - -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, - NULL, 0, VERSIONMADEBY, 0, 0); + return zipOpenNewFileInZip4_64(file, filename, zipfi, + extrafield_local, size_extrafield_local, + extrafield_global, size_extrafield_global, + comment, method, level, 0, + -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, + NULL, 0, VERSIONMADEBY, 0, 0); } local int zip64FlushWriteBuffer(zip64_internal* zi) { - int err=ZIP_OK; + int err = ZIP_OK; - if (zi->ci.encrypt != 0) - { + if (zi->ci.encrypt != 0) + { #ifndef NOCRYPT - uInt i; - int t; - for (i=0;ici.pos_in_buffered_data;i++) - zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t); + uInt i; + int t; + for (i = 0; i < zi->ci.pos_in_buffered_data; i++) + zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i], t); #endif - } + } - if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data) - err = ZIP_ERRNO; + if (ZWRITE64(zi->z_filefunc, zi->filestream, zi->ci.buffered_data, zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data) + err = ZIP_ERRNO; - zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data; + zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data; #ifdef HAVE_BZIP2 - if(zi->ci.method == Z_BZIP2ED) - { - zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32; - zi->ci.bstream.total_in_lo32 = 0; - zi->ci.bstream.total_in_hi32 = 0; - } - else + if (zi->ci.method == Z_BZIP2ED) + { + zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32; + zi->ci.bstream.total_in_lo32 = 0; + zi->ci.bstream.total_in_hi32 = 0; + } + else #endif - { - zi->ci.totalUncompressedData += zi->ci.stream.total_in; - zi->ci.stream.total_in = 0; - } + { + zi->ci.totalUncompressedData += zi->ci.stream.total_in; + zi->ci.stream.total_in = 0; + } + zi->ci.pos_in_buffered_data = 0; - zi->ci.pos_in_buffered_data = 0; - - return err; + return err; } -extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len) +extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void* buf, unsigned int len) { - zip64_internal* zi; - int err=ZIP_OK; + zip64_internal* zi; + int err = ZIP_OK; - if (file == NULL) - return ZIP_PARAMERROR; - zi = (zip64_internal*)file; + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; - if (zi->in_opened_file_inzip == 0) - return ZIP_PARAMERROR; + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; - zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len); + zi->ci.crc32 = crc32(zi->ci.crc32, buf, (uInt)len); #ifdef HAVE_BZIP2 - if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw)) - { - zi->ci.bstream.next_in = (void*)buf; - zi->ci.bstream.avail_in = len; - err = BZ_RUN_OK; + if (zi->ci.method == Z_BZIP2ED && (!zi->ci.raw)) + { + zi->ci.bstream.next_in = (void*)buf; + zi->ci.bstream.avail_in = len; + err = BZ_RUN_OK; - while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0)) - { - if (zi->ci.bstream.avail_out == 0) - { - if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) - err = ZIP_ERRNO; - zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; - } + while ((err == BZ_RUN_OK) && (zi->ci.bstream.avail_in > 0)) + { + if (zi->ci.bstream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + } + if (err != BZ_RUN_OK) + break; - if(err != BZ_RUN_OK) - break; + if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { + uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; + // uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; + err = BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); - if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) - { - uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32; -// uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32; - err=BZ2_bzCompress(&zi->ci.bstream, BZ_RUN); + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo); + } + } - zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ; - } - } - - if(err == BZ_RUN_OK) - err = ZIP_OK; - } - else + if (err == BZ_RUN_OK) + err = ZIP_OK; + } + else #endif - { - zi->ci.stream.next_in = (Bytef*)buf; - zi->ci.stream.avail_in = len; + { + zi->ci.stream.next_in = (Bytef*)buf; + zi->ci.stream.avail_in = len; - while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0)) - { - if (zi->ci.stream.avail_out == 0) - { - if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) - err = ZIP_ERRNO; - zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.stream.next_out = zi->ci.buffered_data; - } + while ((err == ZIP_OK) && (zi->ci.stream.avail_in > 0)) + { + if (zi->ci.stream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + if (err != ZIP_OK) + break; - if(err != ZIP_OK) - break; + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + uLong uTotalOutBefore = zi->ci.stream.total_out; + err = deflate(&zi->ci.stream, Z_NO_FLUSH); + if (uTotalOutBefore > zi->ci.stream.total_out) + { + int bBreak = 0; + bBreak++; + } - if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) - { - uLong uTotalOutBefore = zi->ci.stream.total_out; - err=deflate(&zi->ci.stream, Z_NO_FLUSH); - if(uTotalOutBefore > zi->ci.stream.total_out) - { - int bBreak = 0; - bBreak++; - } + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore); + } + else + { + uInt copy_this, i; + if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) + copy_this = zi->ci.stream.avail_in; + else + copy_this = zi->ci.stream.avail_out; - zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; - } - else - { - uInt copy_this,i; - if (zi->ci.stream.avail_in < zi->ci.stream.avail_out) - copy_this = zi->ci.stream.avail_in; - else - copy_this = zi->ci.stream.avail_out; + for (i = 0; i < copy_this; i++) + *(((char*)zi->ci.stream.next_out) + i) = + *(((const char*)zi->ci.stream.next_in) + i); + { + zi->ci.stream.avail_in -= copy_this; + zi->ci.stream.avail_out -= copy_this; + zi->ci.stream.next_in += copy_this; + zi->ci.stream.next_out += copy_this; + zi->ci.stream.total_in += copy_this; + zi->ci.stream.total_out += copy_this; + zi->ci.pos_in_buffered_data += copy_this; + } + } + } // while(...) + } - for (i = 0; i < copy_this; i++) - *(((char*)zi->ci.stream.next_out)+i) = - *(((const char*)zi->ci.stream.next_in)+i); - { - zi->ci.stream.avail_in -= copy_this; - zi->ci.stream.avail_out-= copy_this; - zi->ci.stream.next_in+= copy_this; - zi->ci.stream.next_out+= copy_this; - zi->ci.stream.total_in+= copy_this; - zi->ci.stream.total_out+= copy_this; - zi->ci.pos_in_buffered_data += copy_this; - } - } - }// while(...) - } - - return err; + return err; } -extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32) +extern int ZEXPORT zipCloseFileInZipRaw(zipFile file, uLong uncompressed_size, uLong crc32) { - return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32); + return zipCloseFileInZipRaw64(file, uncompressed_size, crc32); } -extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32) +extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, ZPOS64_T uncompressed_size, uLong crc32) { - zip64_internal* zi; - ZPOS64_T compressed_size; - uLong invalidValue = 0xffffffff; - short datasize = 0; - int err=ZIP_OK; + zip64_internal* zi; + ZPOS64_T compressed_size; + uLong invalidValue = 0xffffffff; + short datasize = 0; + int err = ZIP_OK; - if (file == NULL) - return ZIP_PARAMERROR; - zi = (zip64_internal*)file; + if (file == NULL) + return ZIP_PARAMERROR; + zi = (zip64_internal*)file; - if (zi->in_opened_file_inzip == 0) - return ZIP_PARAMERROR; - zi->ci.stream.avail_in = 0; + if (zi->in_opened_file_inzip == 0) + return ZIP_PARAMERROR; + zi->ci.stream.avail_in = 0; - if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) - { - while (err==ZIP_OK) - { - uLong uTotalOutBefore; - if (zi->ci.stream.avail_out == 0) - { - if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) - err = ZIP_ERRNO; - zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.stream.next_out = zi->ci.buffered_data; - } - uTotalOutBefore = zi->ci.stream.total_out; - err=deflate(&zi->ci.stream, Z_FINISH); - zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ; - } - } - else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) - { + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + while (err == ZIP_OK) + { + uLong uTotalOutBefore; + if (zi->ci.stream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.stream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.stream.next_out = zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.stream.total_out; + err = deflate(&zi->ci.stream, Z_FINISH); + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore); + } + } + else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { #ifdef HAVE_BZIP2 - err = BZ_FINISH_OK; - while (err==BZ_FINISH_OK) - { - uLong uTotalOutBefore; - if (zi->ci.bstream.avail_out == 0) - { - if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) - err = ZIP_ERRNO; - zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; - zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; - } - uTotalOutBefore = zi->ci.bstream.total_out_lo32; - err=BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH); - if(err == BZ_STREAM_END) - err = Z_STREAM_END; + err = BZ_FINISH_OK; + while (err == BZ_FINISH_OK) + { + uLong uTotalOutBefore; + if (zi->ci.bstream.avail_out == 0) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE; + zi->ci.bstream.next_out = (char*)zi->ci.buffered_data; + } + uTotalOutBefore = zi->ci.bstream.total_out_lo32; + err = BZ2_bzCompress(&zi->ci.bstream, BZ_FINISH); + if (err == BZ_STREAM_END) + err = Z_STREAM_END; - zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore); - } + zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore); + } - if(err == BZ_FINISH_OK) - err = ZIP_OK; + if (err == BZ_FINISH_OK) + err = ZIP_OK; #endif - } + } - if (err==Z_STREAM_END) - err=ZIP_OK; /* this is normal */ + if (err == Z_STREAM_END) + err = ZIP_OK; /* this is normal */ - if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK)) - { - if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO) - err = ZIP_ERRNO; - } + if ((zi->ci.pos_in_buffered_data > 0) && (err == ZIP_OK)) + { + if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO) + err = ZIP_ERRNO; + } - if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) - { - int tmp_err = deflateEnd(&zi->ci.stream); - if (err == ZIP_OK) - err = tmp_err; - zi->ci.stream_initialised = 0; - } + if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw)) + { + int tmp_err = deflateEnd(&zi->ci.stream); + if (err == ZIP_OK) + err = tmp_err; + zi->ci.stream_initialised = 0; + } #ifdef HAVE_BZIP2 - else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) - { - int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream); - if (err==ZIP_OK) - err = tmperr; - zi->ci.stream_initialised = 0; - } + else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw)) + { + int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream); + if (err == ZIP_OK) + err = tmperr; + zi->ci.stream_initialised = 0; + } #endif - if (!zi->ci.raw) - { - crc32 = (uLong)zi->ci.crc32; - uncompressed_size = zi->ci.totalUncompressedData; - } - compressed_size = zi->ci.totalCompressedData; + if (!zi->ci.raw) + { + crc32 = (uLong)zi->ci.crc32; + uncompressed_size = zi->ci.totalUncompressedData; + } + compressed_size = zi->ci.totalCompressedData; -# ifndef NOCRYPT - compressed_size += zi->ci.crypt_header_size; -# endif +#ifndef NOCRYPT + compressed_size += zi->ci.crypt_header_size; +#endif - // update Current Item crc and sizes, - if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) - { - /*version Made by*/ - zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2); - /*version needed*/ - zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2); + // update Current Item crc and sizes, + if (compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff) + { + /*version Made by*/ + zip64local_putValue_inmemory(zi->ci.central_header + 4, (uLong)45, 2); + /*version needed*/ + zip64local_putValue_inmemory(zi->ci.central_header + 6, (uLong)45, 2); + } - } + zip64local_putValue_inmemory(zi->ci.central_header + 16, crc32, 4); /*crc*/ - zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/ + if (compressed_size >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header + 20, invalidValue, 4); /*compr size*/ + else + zip64local_putValue_inmemory(zi->ci.central_header + 20, compressed_size, 4); /*compr size*/ + /// set internal file attributes field + if (zi->ci.stream.data_type == Z_ASCII) + zip64local_putValue_inmemory(zi->ci.central_header + 36, (uLong)Z_ASCII, 2); - if(compressed_size >= 0xffffffff) - zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/ - else - zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/ + if (uncompressed_size >= 0xffffffff) + zip64local_putValue_inmemory(zi->ci.central_header + 24, invalidValue, 4); /*uncompr size*/ + else + zip64local_putValue_inmemory(zi->ci.central_header + 24, uncompressed_size, 4); /*uncompr size*/ - /// set internal file attributes field - if (zi->ci.stream.data_type == Z_ASCII) - zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2); + // Add ZIP64 extra info field for uncompressed size + if (uncompressed_size >= 0xffffffff) + datasize += 8; - if(uncompressed_size >= 0xffffffff) - zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/ - else - zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/ + // Add ZIP64 extra info field for compressed size + if (compressed_size >= 0xffffffff) + datasize += 8; - // Add ZIP64 extra info field for uncompressed size - if(uncompressed_size >= 0xffffffff) - datasize += 8; + // Add ZIP64 extra info field for relative offset to local file header of current file + if (zi->ci.pos_local_header >= 0xffffffff) + datasize += 8; - // Add ZIP64 extra info field for compressed size - if(compressed_size >= 0xffffffff) - datasize += 8; + if (datasize > 0) + { + char* p = NULL; - // Add ZIP64 extra info field for relative offset to local file header of current file - if(zi->ci.pos_local_header >= 0xffffffff) - datasize += 8; + if ((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) + { + // we can not write more data to the buffer that we have room for. + return ZIP_BADZIPFILE; + } - if(datasize > 0) - { - char* p = NULL; + p = zi->ci.central_header + zi->ci.size_centralheader; - if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree) - { - // we can not write more data to the buffer that we have room for. - return ZIP_BADZIPFILE; - } + // Add Extra Information Header for 'ZIP64 information' + zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID + p += 2; + zip64local_putValue_inmemory(p, datasize, 2); // DataSize + p += 2; - p = zi->ci.central_header + zi->ci.size_centralheader; + if (uncompressed_size >= 0xffffffff) + { + zip64local_putValue_inmemory(p, uncompressed_size, 8); + p += 8; + } - // Add Extra Information Header for 'ZIP64 information' - zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID - p += 2; - zip64local_putValue_inmemory(p, datasize, 2); // DataSize - p += 2; + if (compressed_size >= 0xffffffff) + { + zip64local_putValue_inmemory(p, compressed_size, 8); + p += 8; + } - if(uncompressed_size >= 0xffffffff) - { - zip64local_putValue_inmemory(p, uncompressed_size, 8); - p += 8; - } + if (zi->ci.pos_local_header >= 0xffffffff) + { + zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8); + p += 8; + } - if(compressed_size >= 0xffffffff) - { - zip64local_putValue_inmemory(p, compressed_size, 8); - p += 8; - } + // Update how much extra free space we got in the memory buffer + // and increase the centralheader size so the new ZIP64 fields are included + // ( 4 below is the size of HeaderID and DataSize field ) + zi->ci.size_centralExtraFree -= datasize + 4; + zi->ci.size_centralheader += datasize + 4; - if(zi->ci.pos_local_header >= 0xffffffff) - { - zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8); - p += 8; - } + // Update the extra info size field + zi->ci.size_centralExtra += datasize + 4; + zip64local_putValue_inmemory(zi->ci.central_header + 30, (uLong)zi->ci.size_centralExtra, 2); + } - // Update how much extra free space we got in the memory buffer - // and increase the centralheader size so the new ZIP64 fields are included - // ( 4 below is the size of HeaderID and DataSize field ) - zi->ci.size_centralExtraFree -= datasize + 4; - zi->ci.size_centralheader += datasize + 4; + if (err == ZIP_OK) + err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader); - // Update the extra info size field - zi->ci.size_centralExtra += datasize + 4; - zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2); - } + free(zi->ci.central_header); - if (err==ZIP_OK) - err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader); + if (err == ZIP_OK) + { + // Update the LocalFileHeader with the new values. - free(zi->ci.central_header); + ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc, zi->filestream); - if (err==ZIP_OK) - { - // Update the LocalFileHeader with the new values. + if (ZSEEK64(zi->z_filefunc, zi->filestream, zi->ci.pos_local_header + 14, ZLIB_FILEFUNC_SEEK_SET) != 0) + err = ZIP_ERRNO; - ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + if (err == ZIP_OK) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, crc32, 4); /* crc 32, unknown */ - if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0) - err = ZIP_ERRNO; + if (uncompressed_size >= 0xffffffff) + { + if (zi->ci.pos_zip64extrainfo > 0) + { + // Update the size in the ZIP64 extended field. + if (ZSEEK64(zi->z_filefunc, zi->filestream, zi->ci.pos_zip64extrainfo + 4, ZLIB_FILEFUNC_SEEK_SET) != 0) + err = ZIP_ERRNO; - if (err==ZIP_OK) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */ + if (err == ZIP_OK) /* compressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8); - if(uncompressed_size >= 0xffffffff) - { - if(zi->ci.pos_zip64extrainfo > 0) - { - // Update the size in the ZIP64 extended field. - if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0) - err = ZIP_ERRNO; + if (err == ZIP_OK) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8); + } + } + else + { + if (err == ZIP_OK) /* compressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 4); - if (err==ZIP_OK) /* compressed size, unknown */ - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8); + if (err == ZIP_OK) /* uncompressed size, unknown */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 4); + } - if (err==ZIP_OK) /* uncompressed size, unknown */ - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8); - } - } - else - { - if (err==ZIP_OK) /* compressed size, unknown */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4); + if (ZSEEK64(zi->z_filefunc, zi->filestream, cur_pos_inzip, ZLIB_FILEFUNC_SEEK_SET) != 0) + err = ZIP_ERRNO; + } - if (err==ZIP_OK) /* uncompressed size, unknown */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4); - } + zi->number_entry++; + zi->in_opened_file_inzip = 0; - if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0) - err = ZIP_ERRNO; - } - - zi->number_entry ++; - zi->in_opened_file_inzip = 0; - - return err; + return err; } -extern int ZEXPORT zipCloseFileInZip (zipFile file) +extern int ZEXPORT zipCloseFileInZip(zipFile file) { - return zipCloseFileInZipRaw (file,0,0); + return zipCloseFileInZipRaw(file, 0, 0); } int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip) { - int err = ZIP_OK; - ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset; + int err = ZIP_OK; + ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset; - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)ZIP64ENDLOCHEADERMAGIC, 4); - /*num disks*/ - if (err==ZIP_OK) /* number of the disk with the start of the central directory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + /*num disks*/ + if (err == ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0, 4); - /*relative offset*/ - if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8); + /*relative offset*/ + if (err == ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, pos, 8); - /*total disks*/ /* Do not support spawning of disk so always say 1 here*/ - if (err==ZIP_OK) /* number of the disk with the start of the central directory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4); + /*total disks*/ /* Do not support spawning of disk so always say 1 here*/ + if (err == ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)1, 4); - return err; + return err; } int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) { - int err = ZIP_OK; + int err = ZIP_OK; - uLong Zip64DataSize = 44; + uLong Zip64DataSize = 44; - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)ZIP64ENDHEADERMAGIC, 4); - if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ? + if (err == ZIP_OK) /* size of this 'zip64 end of central directory' */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)Zip64DataSize, 8); // why ZPOS64_T of this ? - if (err==ZIP_OK) /* version made by */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); + if (err == ZIP_OK) /* version made by */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)45, 2); - if (err==ZIP_OK) /* version needed */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2); + if (err == ZIP_OK) /* version needed */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)45, 2); - if (err==ZIP_OK) /* number of this disk */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + if (err == ZIP_OK) /* number of this disk */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0, 4); - if (err==ZIP_OK) /* number of the disk with the start of the central directory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); + if (err == ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0, 4); - if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); + if (err == ZIP_OK) /* total number of entries in the central dir on this disk */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); - if (err==ZIP_OK) /* total number of entries in the central dir */ - err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); + if (err == ZIP_OK) /* total number of entries in the central dir */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8); - if (err==ZIP_OK) /* size of the central directory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8); + if (err == ZIP_OK) /* size of the central directory */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)size_centraldir, 8); - if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ - { - ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; - err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8); - } - return err; + if (err == ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ + { + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)pos, 8); + } + return err; } int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip) { - int err = ZIP_OK; + int err = ZIP_OK; - /*signature*/ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4); + /*signature*/ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)ENDHEADERMAGIC, 4); - if (err==ZIP_OK) /* number of this disk */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); + if (err == ZIP_OK) /* number of this disk */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0, 2); - if (err==ZIP_OK) /* number of the disk with the start of the central directory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2); + if (err == ZIP_OK) /* number of the disk with the start of the central directory */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0, 2); - if (err==ZIP_OK) /* total number of entries in the central dir on this disk */ - { - { - if(zi->number_entry >= 0xFFFF) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record - else - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); - } - } + if (err == ZIP_OK) /* total number of entries in the central dir on this disk */ + { + { + if (zi->number_entry >= 0xFFFF) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0xffff, 2); // use value in ZIP64 record + else + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_entry, 2); + } + } - if (err==ZIP_OK) /* total number of entries in the central dir */ - { - if(zi->number_entry >= 0xFFFF) - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record - else - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2); - } + if (err == ZIP_OK) /* total number of entries in the central dir */ + { + if (zi->number_entry >= 0xFFFF) + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0xffff, 2); // use value in ZIP64 record + else + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)zi->number_entry, 2); + } - if (err==ZIP_OK) /* size of the central directory */ - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4); + if (err == ZIP_OK) /* size of the central directory */ + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)size_centraldir, 4); - if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ - { - ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; - if(pos >= 0xffffffff) - { - err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4); - } - else - err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4); - } + if (err == ZIP_OK) /* offset of start of central directory with respect to the starting disk number */ + { + ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + if (pos >= 0xffffffff) + { + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)0xffffffff, 4); + } + else + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset), 4); + } - return err; + return err; } int Write_GlobalComment(zip64_internal* zi, const char* global_comment) { - int err = ZIP_OK; - uInt size_global_comment = 0; + int err = ZIP_OK; + uInt size_global_comment = 0; - if(global_comment != NULL) - size_global_comment = (uInt)strlen(global_comment); + if (global_comment != NULL) + size_global_comment = (uInt)strlen(global_comment); - err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2); + err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (uLong)size_global_comment, 2); - if (err == ZIP_OK && size_global_comment > 0) - { - if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment) - err = ZIP_ERRNO; - } - return err; + if (err == ZIP_OK && size_global_comment > 0) + { + if (ZWRITE64(zi->z_filefunc, zi->filestream, global_comment, size_global_comment) != size_global_comment) + err = ZIP_ERRNO; + } + return err; } -extern int ZEXPORT zipClose (zipFile file, const char* global_comment) +extern int ZEXPORT zipClose(zipFile file, const char* global_comment) { - zip64_internal* zi; - int err = 0; - uLong size_centraldir = 0; - ZPOS64_T centraldir_pos_inzip; - ZPOS64_T pos; + zip64_internal* zi; + int err = 0; + uLong size_centraldir = 0; + ZPOS64_T centraldir_pos_inzip; + ZPOS64_T pos; - if (file == NULL) - return ZIP_PARAMERROR; + if (file == NULL) + return ZIP_PARAMERROR; - zi = (zip64_internal*)file; + zi = (zip64_internal*)file; - if (zi->in_opened_file_inzip == 1) - { - err = zipCloseFileInZip (file); - } + if (zi->in_opened_file_inzip == 1) + { + err = zipCloseFileInZip(file); + } #ifndef NO_ADDFILEINEXISTINGZIP - if (global_comment==NULL) - global_comment = zi->globalcomment; + if (global_comment == NULL) + global_comment = zi->globalcomment; #endif - centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream); + centraldir_pos_inzip = ZTELL64(zi->z_filefunc, zi->filestream); - if (err==ZIP_OK) - { - linkedlist_datablock_internal* ldi = zi->central_dir.first_block; - while (ldi!=NULL) - { - if ((err==ZIP_OK) && (ldi->filled_in_this_block>0)) - { - if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block) - err = ZIP_ERRNO; - } + if (err == ZIP_OK) + { + linkedlist_datablock_internal* ldi = zi->central_dir.first_block; + while (ldi != NULL) + { + if ((err == ZIP_OK) && (ldi->filled_in_this_block > 0)) + { + if (ZWRITE64(zi->z_filefunc, zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block) + err = ZIP_ERRNO; + } - size_centraldir += ldi->filled_in_this_block; - ldi = ldi->next_datablock; - } - } - free_linkedlist(&(zi->central_dir)); + size_centraldir += ldi->filled_in_this_block; + ldi = ldi->next_datablock; + } + } + free_linkedlist(&(zi->central_dir)); - pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; - if(pos >= 0xffffffff) - { - ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream); - Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); + pos = centraldir_pos_inzip - zi->add_position_when_writting_offset; + if (pos >= 0xffffffff) + { + ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc, zi->filestream); + Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); - Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos); - } + Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos); + } - if (err==ZIP_OK) - err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); + if (err == ZIP_OK) + err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip); - if(err == ZIP_OK) - err = Write_GlobalComment(zi, global_comment); + if (err == ZIP_OK) + err = Write_GlobalComment(zi, global_comment); - if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0) - if (err == ZIP_OK) - err = ZIP_ERRNO; + if (ZCLOSE64(zi->z_filefunc, zi->filestream) != 0) + if (err == ZIP_OK) + err = ZIP_ERRNO; #ifndef NO_ADDFILEINEXISTINGZIP - TRYFREE(zi->globalcomment); + TRYFREE(zi->globalcomment); #endif - TRYFREE(zi); + TRYFREE(zi); - return err; + return err; } -extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader) +extern int ZEXPORT zipRemoveExtraInfoBlock(char* pData, int* dataLen, short sHeader) { - char* p = pData; - int size = 0; - char* pNewHeader; - char* pTmp; - short header; - short dataSize; + char* p = pData; + int size = 0; + char* pNewHeader; + char* pTmp; + short header; + short dataSize; - int retVal = ZIP_OK; + int retVal = ZIP_OK; - if(pData == NULL || *dataLen < 4) - return ZIP_PARAMERROR; + if (pData == NULL || *dataLen < 4) + return ZIP_PARAMERROR; - pNewHeader = (char*)ALLOC(*dataLen); - pTmp = pNewHeader; + pNewHeader = (char*)ALLOC(*dataLen); + pTmp = pNewHeader; - while(p < (pData + *dataLen)) - { - header = *(short*)p; - dataSize = *(((short*)p)+1); + while (p < (pData + *dataLen)) + { + header = *(short*)p; + dataSize = *(((short*)p) + 1); - if( header == sHeader ) // Header found. - { - p += dataSize + 4; // skip it. do not copy to temp buffer - } - else - { - // Extra Info block should not be removed, So copy it to the temp buffer. - memcpy(pTmp, p, dataSize + 4); - p += dataSize + 4; - size += dataSize + 4; - } + if (header == sHeader) // Header found. + { + p += dataSize + 4; // skip it. do not copy to temp buffer + } + else + { + // Extra Info block should not be removed, So copy it to the temp buffer. + memcpy(pTmp, p, dataSize + 4); + p += dataSize + 4; + size += dataSize + 4; + } + } - } + if (size < *dataLen) + { + // clean old extra info block. + memset(pData, 0, *dataLen); - if(size < *dataLen) - { - // clean old extra info block. - memset(pData,0, *dataLen); + // copy the new extra info block over the old + if (size > 0) + memcpy(pData, pNewHeader, size); - // copy the new extra info block over the old - if(size > 0) - memcpy(pData, pNewHeader, size); + // set the new extra info size + *dataLen = size; - // set the new extra info size - *dataLen = size; + retVal = ZIP_OK; + } + else + retVal = ZIP_ERRNO; - retVal = ZIP_OK; - } - else - retVal = ZIP_ERRNO; + TRYFREE(pNewHeader); - TRYFREE(pNewHeader); - - return retVal; + return retVal; } diff --git a/examples/ThirdPartyLibs/minizip/zip.h b/examples/ThirdPartyLibs/minizip/zip.h index 510907c5b..4aa5ffa4a 100644 --- a/examples/ThirdPartyLibs/minizip/zip.h +++ b/examples/ThirdPartyLibs/minizip/zip.h @@ -41,10 +41,11 @@ #define _zip12_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -//#define HAVE_BZIP2 + //#define HAVE_BZIP2 #ifndef _ZLIB_H #include "../zlib/zlib.h" @@ -61,61 +62,63 @@ extern "C" { #define Z_BZIP2ED 12 #if defined(STRICTZIP) || defined(STRICTZIPUNZIP) -/* like the STRICT of WIN32, we define a pointer that cannot be converted + /* like the STRICT of WIN32, we define a pointer that cannot be converted from (void*) without cast */ -typedef struct TagzipFile__ { int unused; } zipFile__; -typedef zipFile__ *zipFile; + typedef struct TagzipFile__ + { + int unused; + } zipFile__; + typedef zipFile__* zipFile; #else typedef voidp zipFile; #endif -#define ZIP_OK (0) -#define ZIP_EOF (0) -#define ZIP_ERRNO (Z_ERRNO) -#define ZIP_PARAMERROR (-102) -#define ZIP_BADZIPFILE (-103) -#define ZIP_INTERNALERROR (-104) +#define ZIP_OK (0) +#define ZIP_EOF (0) +#define ZIP_ERRNO (Z_ERRNO) +#define ZIP_PARAMERROR (-102) +#define ZIP_BADZIPFILE (-103) +#define ZIP_INTERNALERROR (-104) #ifndef DEF_MEM_LEVEL -# if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -# else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -# endif +#if MAX_MEM_LEVEL >= 8 +#define DEF_MEM_LEVEL 8 +#else +#define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif -/* default memLevel */ +#endif + /* default memLevel */ -/* tm_zip contain date/time info */ -typedef struct tm_zip_s -{ - uInt tm_sec; /* seconds after the minute - [0,59] */ - uInt tm_min; /* minutes after the hour - [0,59] */ - uInt tm_hour; /* hours since midnight - [0,23] */ - uInt tm_mday; /* day of the month - [1,31] */ - uInt tm_mon; /* months since January - [0,11] */ - uInt tm_year; /* years - [1980..2044] */ -} tm_zip; + /* tm_zip contain date/time info */ + typedef struct tm_zip_s + { + uInt tm_sec; /* seconds after the minute - [0,59] */ + uInt tm_min; /* minutes after the hour - [0,59] */ + uInt tm_hour; /* hours since midnight - [0,23] */ + uInt tm_mday; /* day of the month - [1,31] */ + uInt tm_mon; /* months since January - [0,11] */ + uInt tm_year; /* years - [1980..2044] */ + } tm_zip; -typedef struct -{ - tm_zip tmz_date; /* date in understandable format */ - uLong dosDate; /* if dos_date == 0, tmu_date is used */ -/* uLong flag; */ /* general purpose bit flag 2 bytes */ + typedef struct + { + tm_zip tmz_date; /* date in understandable format */ + uLong dosDate; /* if dos_date == 0, tmu_date is used */ + /* uLong flag; */ /* general purpose bit flag 2 bytes */ - uLong internal_fa; /* internal file attributes 2 bytes */ - uLong external_fa; /* external file attributes 4 bytes */ -} zip_fileinfo; + uLong internal_fa; /* internal file attributes 2 bytes */ + uLong external_fa; /* external file attributes 4 bytes */ + } zip_fileinfo; -typedef const char* zipcharpc; + typedef const char* zipcharpc; +#define APPEND_STATUS_CREATE (0) +#define APPEND_STATUS_CREATEAFTER (1) +#define APPEND_STATUS_ADDINZIP (2) -#define APPEND_STATUS_CREATE (0) -#define APPEND_STATUS_CREATEAFTER (1) -#define APPEND_STATUS_ADDINZIP (2) - -extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append)); -extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append)); -/* + extern zipFile ZEXPORT zipOpen OF((const char* pathname, int append)); + extern zipFile ZEXPORT zipOpen64 OF((const void* pathname, int append)); + /* Create a zipfile. pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on an Unix computer "zlib/zlib113.zip". @@ -129,45 +132,45 @@ extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append)); of this zip package. */ -/* Note : there is no delete function into a zipfile. + /* Note : there is no delete function into a zipfile. If you want delete file into a zipfile, you must open a zipfile, and create another Of couse, you can use RAW reading and writing to copy the file you did not want delte */ -extern zipFile ZEXPORT zipOpen2 OF((const char *pathname, - int append, - zipcharpc* globalcomment, - zlib_filefunc_def* pzlib_filefunc_def)); + extern zipFile ZEXPORT zipOpen2 OF((const char* pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc_def* pzlib_filefunc_def)); -extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname, - int append, - zipcharpc* globalcomment, - zlib_filefunc64_def* pzlib_filefunc_def)); + extern zipFile ZEXPORT zipOpen2_64 OF((const void* pathname, + int append, + zipcharpc* globalcomment, + zlib_filefunc64_def* pzlib_filefunc_def)); -extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level)); + extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level)); -extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int zip64)); + extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int zip64)); -/* + /* Open a file in the ZIP for writing. filename : the filename in zip (if NULL, '-' without quote will be used *zipfi contain supplemental information @@ -183,162 +186,154 @@ extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file, */ + extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw)); -extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw)); - - -extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int zip64)); -/* + extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int zip64)); + /* Same than zipOpenNewFileInZip, except if raw=1, we write raw file */ -extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCrypting)); + extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting)); -extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCrypting, - int zip64 - )); + extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + int zip64)); -/* + /* Same than zipOpenNewFileInZip2, except windowBits,memLevel,,strategy : see parameter strategy in deflateInit2 password : crypting password (NULL for no crypting) crcForCrypting : crc of file to compress (needed for crypting) */ -extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCrypting, - uLong versionMadeBy, - uLong flagBase - )); + extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase)); - -extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, - const char* filename, - const zip_fileinfo* zipfi, - const void* extrafield_local, - uInt size_extrafield_local, - const void* extrafield_global, - uInt size_extrafield_global, - const char* comment, - int method, - int level, - int raw, - int windowBits, - int memLevel, - int strategy, - const char* password, - uLong crcForCrypting, - uLong versionMadeBy, - uLong flagBase, - int zip64 - )); -/* + extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file, + const char* filename, + const zip_fileinfo* zipfi, + const void* extrafield_local, + uInt size_extrafield_local, + const void* extrafield_global, + uInt size_extrafield_global, + const char* comment, + int method, + int level, + int raw, + int windowBits, + int memLevel, + int strategy, + const char* password, + uLong crcForCrypting, + uLong versionMadeBy, + uLong flagBase, + int zip64)); + /* Same than zipOpenNewFileInZip4, except versionMadeBy : value for Version made by field flag : value for flag field (compression level info will be added) */ - -extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, - const void* buf, - unsigned len)); -/* + extern int ZEXPORT zipWriteInFileInZip OF((zipFile file, + const void* buf, + unsigned len)); + /* Write data in the zipfile */ -extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); -/* + extern int ZEXPORT zipCloseFileInZip OF((zipFile file)); + /* Close the current file in the zipfile */ -extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, - uLong uncompressed_size, - uLong crc32)); + extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file, + uLong uncompressed_size, + uLong crc32)); -extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, - ZPOS64_T uncompressed_size, - uLong crc32)); + extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file, + ZPOS64_T uncompressed_size, + uLong crc32)); -/* + /* Close the current file in the zipfile, for file opened with parameter raw=1 in zipOpenNewFileInZip2 uncompressed_size and crc32 are value for the uncompressed size */ -extern int ZEXPORT zipClose OF((zipFile file, - const char* global_comment)); -/* + extern int ZEXPORT zipClose OF((zipFile file, + const char* global_comment)); + /* Close the zipfile */ - -extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader)); -/* + extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader)); + /* zipRemoveExtraInfoBlock - Added by Mathias Svensson Remove extra information block from a extra information data for the local file header or central directory header diff --git a/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Headers/openvr.h b/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Headers/openvr.h index f945dbc1a..80461f968 100644 --- a/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Headers/openvr.h +++ b/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Headers/openvr.h @@ -9,8 +9,6 @@ #include - - // vrtypes.h #ifndef _INCLUDE_VRTYPES_H #define _INCLUDE_VRTYPES_H @@ -27,9 +25,9 @@ struct ID3D12CommandQueue; namespace vr { -#pragma pack( push, 8 ) +#pragma pack(push, 8) -typedef void* glSharedTextureHandle_t; +typedef void *glSharedTextureHandle_t; typedef int32_t glInt_t; typedef uint32_t glUInt_t; @@ -80,7 +78,7 @@ struct HmdColor_t struct HmdQuad_t { - HmdVector3_t vCorners[ 4 ]; + HmdVector3_t vCorners[4]; }; struct HmdRect2_t @@ -107,40 +105,40 @@ enum EVREye enum ETextureType { - TextureType_DirectX = 0, // Handle is an ID3D11Texture - TextureType_OpenGL = 1, // Handle is an OpenGL texture name or an OpenGL render buffer name, depending on submit flags - TextureType_Vulkan = 2, // Handle is a pointer to a VRVulkanTextureData_t structure - TextureType_IOSurface = 3, // Handle is a macOS cross-process-sharable IOSurfaceRef - TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure + TextureType_DirectX = 0, // Handle is an ID3D11Texture + TextureType_OpenGL = 1, // Handle is an OpenGL texture name or an OpenGL render buffer name, depending on submit flags + TextureType_Vulkan = 2, // Handle is a pointer to a VRVulkanTextureData_t structure + TextureType_IOSurface = 3, // Handle is a macOS cross-process-sharable IOSurfaceRef + TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure }; enum EColorSpace { - ColorSpace_Auto = 0, // Assumes 'gamma' for 8-bit per component formats, otherwise 'linear'. This mirrors the DXGI formats which have _SRGB variants. - ColorSpace_Gamma = 1, // Texture data can be displayed directly on the display without any conversion (a.k.a. display native format). - ColorSpace_Linear = 2, // Same as gamma but has been converted to a linear representation using DXGI's sRGB conversion algorithm. + ColorSpace_Auto = 0, // Assumes 'gamma' for 8-bit per component formats, otherwise 'linear'. This mirrors the DXGI formats which have _SRGB variants. + ColorSpace_Gamma = 1, // Texture data can be displayed directly on the display without any conversion (a.k.a. display native format). + ColorSpace_Linear = 2, // Same as gamma but has been converted to a linear representation using DXGI's sRGB conversion algorithm. }; struct Texture_t { - void* handle; // See ETextureType definition above + void *handle; // See ETextureType definition above ETextureType eType; EColorSpace eColorSpace; }; // Handle to a shared texture (HANDLE on Windows obtained using OpenSharedResource). typedef uint64_t SharedTextureHandle_t; -#define INVALID_SHARED_TEXTURE_HANDLE ((vr::SharedTextureHandle_t)0) +#define INVALID_SHARED_TEXTURE_HANDLE ((vr::SharedTextureHandle_t)0) enum ETrackingResult { - TrackingResult_Uninitialized = 1, + TrackingResult_Uninitialized = 1, - TrackingResult_Calibrating_InProgress = 100, - TrackingResult_Calibrating_OutOfRange = 101, + TrackingResult_Calibrating_InProgress = 100, + TrackingResult_Calibrating_OutOfRange = 101, - TrackingResult_Running_OK = 200, - TrackingResult_Running_OutOfRange = 201, + TrackingResult_Running_OK = 200, + TrackingResult_Running_OutOfRange = 201, }; typedef uint32_t DriverId_t; @@ -158,30 +156,28 @@ static const uint32_t k_unTrackedDeviceIndexInvalid = 0xFFFFFFFF; /** Describes what kind of object is being tracked at a given ID */ enum ETrackedDeviceClass { - TrackedDeviceClass_Invalid = 0, // the ID was not valid. - TrackedDeviceClass_HMD = 1, // Head-Mounted Displays - TrackedDeviceClass_Controller = 2, // Tracked controllers - TrackedDeviceClass_GenericTracker = 3, // Generic trackers, similar to controllers - TrackedDeviceClass_TrackingReference = 4, // Camera and base stations that serve as tracking reference points - TrackedDeviceClass_DisplayRedirect = 5, // Accessories that aren't necessarily tracked themselves, but may redirect video output from other tracked devices + TrackedDeviceClass_Invalid = 0, // the ID was not valid. + TrackedDeviceClass_HMD = 1, // Head-Mounted Displays + TrackedDeviceClass_Controller = 2, // Tracked controllers + TrackedDeviceClass_GenericTracker = 3, // Generic trackers, similar to controllers + TrackedDeviceClass_TrackingReference = 4, // Camera and base stations that serve as tracking reference points + TrackedDeviceClass_DisplayRedirect = 5, // Accessories that aren't necessarily tracked themselves, but may redirect video output from other tracked devices }; - /** Describes what specific role associated with a tracked device */ enum ETrackedControllerRole { - TrackedControllerRole_Invalid = 0, // Invalid value for controller type - TrackedControllerRole_LeftHand = 1, // Tracked device associated with the left hand - TrackedControllerRole_RightHand = 2, // Tracked device associated with the right hand + TrackedControllerRole_Invalid = 0, // Invalid value for controller type + TrackedControllerRole_LeftHand = 1, // Tracked device associated with the left hand + TrackedControllerRole_RightHand = 2, // Tracked device associated with the right hand }; - /** describes a single pose for a tracked object */ struct TrackedDevicePose_t { HmdMatrix34_t mDeviceToAbsoluteTracking; - HmdVector3_t vVelocity; // velocity in tracker space in m/s - HmdVector3_t vAngularVelocity; // angular velocity in radians/s (?) + HmdVector3_t vVelocity; // velocity in tracker space in m/s + HmdVector3_t vAngularVelocity; // angular velocity in radians/s (?) ETrackingResult eTrackingResult; bool bPoseIsValid; @@ -194,9 +190,9 @@ struct TrackedDevicePose_t * for the poses it is requesting */ enum ETrackingUniverseOrigin { - TrackingUniverseSeated = 0, // Poses are provided relative to the seated zero pose - TrackingUniverseStanding = 1, // Poses are provided relative to the safe bounds configured by the user - TrackingUniverseRawAndUncalibrated = 2, // Poses are provided in the coordinate system defined by the driver. It has Y up and is unified for devices of the same driver. You usually don't want this one. + TrackingUniverseSeated = 0, // Poses are provided relative to the seated zero pose + TrackingUniverseStanding = 1, // Poses are provided relative to the safe bounds configured by the user + TrackingUniverseRawAndUncalibrated = 2, // Poses are provided in the coordinate system defined by the driver. It has Y up and is unified for devices of the same driver. You usually don't want this one. }; // Refers to a single container of properties @@ -223,146 +219,145 @@ static const PropertyTypeTag_t k_unHiddenAreaPropertyTag = 30; static const PropertyTypeTag_t k_unOpenVRInternalReserved_Start = 1000; static const PropertyTypeTag_t k_unOpenVRInternalReserved_End = 10000; - /** Each entry in this enum represents a property that can be retrieved about a * tracked device. Many fields are only valid for one ETrackedDeviceClass. */ enum ETrackedDeviceProperty { - Prop_Invalid = 0, + Prop_Invalid = 0, // general properties that apply to all device classes - Prop_TrackingSystemName_String = 1000, - Prop_ModelNumber_String = 1001, - Prop_SerialNumber_String = 1002, - Prop_RenderModelName_String = 1003, - Prop_WillDriftInYaw_Bool = 1004, - Prop_ManufacturerName_String = 1005, - Prop_TrackingFirmwareVersion_String = 1006, - Prop_HardwareRevision_String = 1007, - Prop_AllWirelessDongleDescriptions_String = 1008, - Prop_ConnectedWirelessDongle_String = 1009, - Prop_DeviceIsWireless_Bool = 1010, - Prop_DeviceIsCharging_Bool = 1011, - Prop_DeviceBatteryPercentage_Float = 1012, // 0 is empty, 1 is full - Prop_StatusDisplayTransform_Matrix34 = 1013, - Prop_Firmware_UpdateAvailable_Bool = 1014, - Prop_Firmware_ManualUpdate_Bool = 1015, - Prop_Firmware_ManualUpdateURL_String = 1016, - Prop_HardwareRevision_Uint64 = 1017, - Prop_FirmwareVersion_Uint64 = 1018, - Prop_FPGAVersion_Uint64 = 1019, - Prop_VRCVersion_Uint64 = 1020, - Prop_RadioVersion_Uint64 = 1021, - Prop_DongleVersion_Uint64 = 1022, - Prop_BlockServerShutdown_Bool = 1023, - Prop_CanUnifyCoordinateSystemWithHmd_Bool = 1024, - Prop_ContainsProximitySensor_Bool = 1025, - Prop_DeviceProvidesBatteryStatus_Bool = 1026, - Prop_DeviceCanPowerOff_Bool = 1027, - Prop_Firmware_ProgrammingTarget_String = 1028, - Prop_DeviceClass_Int32 = 1029, - Prop_HasCamera_Bool = 1030, - Prop_DriverVersion_String = 1031, - Prop_Firmware_ForceUpdateRequired_Bool = 1032, - Prop_ViveSystemButtonFixRequired_Bool = 1033, - Prop_ParentDriver_Uint64 = 1034, - Prop_ResourceRoot_String = 1035, + Prop_TrackingSystemName_String = 1000, + Prop_ModelNumber_String = 1001, + Prop_SerialNumber_String = 1002, + Prop_RenderModelName_String = 1003, + Prop_WillDriftInYaw_Bool = 1004, + Prop_ManufacturerName_String = 1005, + Prop_TrackingFirmwareVersion_String = 1006, + Prop_HardwareRevision_String = 1007, + Prop_AllWirelessDongleDescriptions_String = 1008, + Prop_ConnectedWirelessDongle_String = 1009, + Prop_DeviceIsWireless_Bool = 1010, + Prop_DeviceIsCharging_Bool = 1011, + Prop_DeviceBatteryPercentage_Float = 1012, // 0 is empty, 1 is full + Prop_StatusDisplayTransform_Matrix34 = 1013, + Prop_Firmware_UpdateAvailable_Bool = 1014, + Prop_Firmware_ManualUpdate_Bool = 1015, + Prop_Firmware_ManualUpdateURL_String = 1016, + Prop_HardwareRevision_Uint64 = 1017, + Prop_FirmwareVersion_Uint64 = 1018, + Prop_FPGAVersion_Uint64 = 1019, + Prop_VRCVersion_Uint64 = 1020, + Prop_RadioVersion_Uint64 = 1021, + Prop_DongleVersion_Uint64 = 1022, + Prop_BlockServerShutdown_Bool = 1023, + Prop_CanUnifyCoordinateSystemWithHmd_Bool = 1024, + Prop_ContainsProximitySensor_Bool = 1025, + Prop_DeviceProvidesBatteryStatus_Bool = 1026, + Prop_DeviceCanPowerOff_Bool = 1027, + Prop_Firmware_ProgrammingTarget_String = 1028, + Prop_DeviceClass_Int32 = 1029, + Prop_HasCamera_Bool = 1030, + Prop_DriverVersion_String = 1031, + Prop_Firmware_ForceUpdateRequired_Bool = 1032, + Prop_ViveSystemButtonFixRequired_Bool = 1033, + Prop_ParentDriver_Uint64 = 1034, + Prop_ResourceRoot_String = 1035, // Properties that are unique to TrackedDeviceClass_HMD - Prop_ReportsTimeSinceVSync_Bool = 2000, - Prop_SecondsFromVsyncToPhotons_Float = 2001, - Prop_DisplayFrequency_Float = 2002, - Prop_UserIpdMeters_Float = 2003, - Prop_CurrentUniverseId_Uint64 = 2004, - Prop_PreviousUniverseId_Uint64 = 2005, - Prop_DisplayFirmwareVersion_Uint64 = 2006, - Prop_IsOnDesktop_Bool = 2007, - Prop_DisplayMCType_Int32 = 2008, - Prop_DisplayMCOffset_Float = 2009, - Prop_DisplayMCScale_Float = 2010, - Prop_EdidVendorID_Int32 = 2011, - Prop_DisplayMCImageLeft_String = 2012, - Prop_DisplayMCImageRight_String = 2013, - Prop_DisplayGCBlackClamp_Float = 2014, - Prop_EdidProductID_Int32 = 2015, - Prop_CameraToHeadTransform_Matrix34 = 2016, - Prop_DisplayGCType_Int32 = 2017, - Prop_DisplayGCOffset_Float = 2018, - Prop_DisplayGCScale_Float = 2019, - Prop_DisplayGCPrescale_Float = 2020, - Prop_DisplayGCImage_String = 2021, - Prop_LensCenterLeftU_Float = 2022, - Prop_LensCenterLeftV_Float = 2023, - Prop_LensCenterRightU_Float = 2024, - Prop_LensCenterRightV_Float = 2025, - Prop_UserHeadToEyeDepthMeters_Float = 2026, - Prop_CameraFirmwareVersion_Uint64 = 2027, - Prop_CameraFirmwareDescription_String = 2028, - Prop_DisplayFPGAVersion_Uint64 = 2029, - Prop_DisplayBootloaderVersion_Uint64 = 2030, - Prop_DisplayHardwareVersion_Uint64 = 2031, - Prop_AudioFirmwareVersion_Uint64 = 2032, - Prop_CameraCompatibilityMode_Int32 = 2033, + Prop_ReportsTimeSinceVSync_Bool = 2000, + Prop_SecondsFromVsyncToPhotons_Float = 2001, + Prop_DisplayFrequency_Float = 2002, + Prop_UserIpdMeters_Float = 2003, + Prop_CurrentUniverseId_Uint64 = 2004, + Prop_PreviousUniverseId_Uint64 = 2005, + Prop_DisplayFirmwareVersion_Uint64 = 2006, + Prop_IsOnDesktop_Bool = 2007, + Prop_DisplayMCType_Int32 = 2008, + Prop_DisplayMCOffset_Float = 2009, + Prop_DisplayMCScale_Float = 2010, + Prop_EdidVendorID_Int32 = 2011, + Prop_DisplayMCImageLeft_String = 2012, + Prop_DisplayMCImageRight_String = 2013, + Prop_DisplayGCBlackClamp_Float = 2014, + Prop_EdidProductID_Int32 = 2015, + Prop_CameraToHeadTransform_Matrix34 = 2016, + Prop_DisplayGCType_Int32 = 2017, + Prop_DisplayGCOffset_Float = 2018, + Prop_DisplayGCScale_Float = 2019, + Prop_DisplayGCPrescale_Float = 2020, + Prop_DisplayGCImage_String = 2021, + Prop_LensCenterLeftU_Float = 2022, + Prop_LensCenterLeftV_Float = 2023, + Prop_LensCenterRightU_Float = 2024, + Prop_LensCenterRightV_Float = 2025, + Prop_UserHeadToEyeDepthMeters_Float = 2026, + Prop_CameraFirmwareVersion_Uint64 = 2027, + Prop_CameraFirmwareDescription_String = 2028, + Prop_DisplayFPGAVersion_Uint64 = 2029, + Prop_DisplayBootloaderVersion_Uint64 = 2030, + Prop_DisplayHardwareVersion_Uint64 = 2031, + Prop_AudioFirmwareVersion_Uint64 = 2032, + Prop_CameraCompatibilityMode_Int32 = 2033, Prop_ScreenshotHorizontalFieldOfViewDegrees_Float = 2034, Prop_ScreenshotVerticalFieldOfViewDegrees_Float = 2035, - Prop_DisplaySuppressed_Bool = 2036, - Prop_DisplayAllowNightMode_Bool = 2037, - Prop_DisplayMCImageWidth_Int32 = 2038, - Prop_DisplayMCImageHeight_Int32 = 2039, - Prop_DisplayMCImageNumChannels_Int32 = 2040, - Prop_DisplayMCImageData_Binary = 2041, - Prop_SecondsFromPhotonsToVblank_Float = 2042, - Prop_DriverDirectModeSendsVsyncEvents_Bool = 2043, - Prop_DisplayDebugMode_Bool = 2044, - Prop_GraphicsAdapterLuid_Uint64 = 2045, - Prop_DriverProvidedChaperonePath_String = 2048, + Prop_DisplaySuppressed_Bool = 2036, + Prop_DisplayAllowNightMode_Bool = 2037, + Prop_DisplayMCImageWidth_Int32 = 2038, + Prop_DisplayMCImageHeight_Int32 = 2039, + Prop_DisplayMCImageNumChannels_Int32 = 2040, + Prop_DisplayMCImageData_Binary = 2041, + Prop_SecondsFromPhotonsToVblank_Float = 2042, + Prop_DriverDirectModeSendsVsyncEvents_Bool = 2043, + Prop_DisplayDebugMode_Bool = 2044, + Prop_GraphicsAdapterLuid_Uint64 = 2045, + Prop_DriverProvidedChaperonePath_String = 2048, // Properties that are unique to TrackedDeviceClass_Controller - Prop_AttachedDeviceId_String = 3000, - Prop_SupportedButtons_Uint64 = 3001, - Prop_Axis0Type_Int32 = 3002, // Return value is of type EVRControllerAxisType - Prop_Axis1Type_Int32 = 3003, // Return value is of type EVRControllerAxisType - Prop_Axis2Type_Int32 = 3004, // Return value is of type EVRControllerAxisType - Prop_Axis3Type_Int32 = 3005, // Return value is of type EVRControllerAxisType - Prop_Axis4Type_Int32 = 3006, // Return value is of type EVRControllerAxisType - Prop_ControllerRoleHint_Int32 = 3007, // Return value is of type ETrackedControllerRole + Prop_AttachedDeviceId_String = 3000, + Prop_SupportedButtons_Uint64 = 3001, + Prop_Axis0Type_Int32 = 3002, // Return value is of type EVRControllerAxisType + Prop_Axis1Type_Int32 = 3003, // Return value is of type EVRControllerAxisType + Prop_Axis2Type_Int32 = 3004, // Return value is of type EVRControllerAxisType + Prop_Axis3Type_Int32 = 3005, // Return value is of type EVRControllerAxisType + Prop_Axis4Type_Int32 = 3006, // Return value is of type EVRControllerAxisType + Prop_ControllerRoleHint_Int32 = 3007, // Return value is of type ETrackedControllerRole // Properties that are unique to TrackedDeviceClass_TrackingReference - Prop_FieldOfViewLeftDegrees_Float = 4000, - Prop_FieldOfViewRightDegrees_Float = 4001, - Prop_FieldOfViewTopDegrees_Float = 4002, - Prop_FieldOfViewBottomDegrees_Float = 4003, - Prop_TrackingRangeMinimumMeters_Float = 4004, - Prop_TrackingRangeMaximumMeters_Float = 4005, - Prop_ModeLabel_String = 4006, + Prop_FieldOfViewLeftDegrees_Float = 4000, + Prop_FieldOfViewRightDegrees_Float = 4001, + Prop_FieldOfViewTopDegrees_Float = 4002, + Prop_FieldOfViewBottomDegrees_Float = 4003, + Prop_TrackingRangeMinimumMeters_Float = 4004, + Prop_TrackingRangeMaximumMeters_Float = 4005, + Prop_ModeLabel_String = 4006, // Properties that are used for user interface like icons names - Prop_IconPathName_String = 5000, // DEPRECATED. Value not referenced. Now expected to be part of icon path properties. - Prop_NamedIconPathDeviceOff_String = 5001, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceSearching_String = 5002, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceSearchingAlert_String = 5003, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceReady_String = 5004, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceReadyAlert_String = 5005, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceNotReady_String = 5006, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceStandby_String = 5007, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceAlertLow_String = 5008, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_IconPathName_String = 5000, // DEPRECATED. Value not referenced. Now expected to be part of icon path properties. + Prop_NamedIconPathDeviceOff_String = 5001, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceSearching_String = 5002, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceSearchingAlert_String = 5003, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceReady_String = 5004, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceReadyAlert_String = 5005, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceNotReady_String = 5006, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceStandby_String = 5007, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceAlertLow_String = 5008, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others // Properties that are used by helpers, but are opaque to applications - Prop_DisplayHiddenArea_Binary_Start = 5100, - Prop_DisplayHiddenArea_Binary_End = 5150, + Prop_DisplayHiddenArea_Binary_Start = 5100, + Prop_DisplayHiddenArea_Binary_End = 5150, // Properties that are unique to drivers - Prop_UserConfigPath_String = 6000, - Prop_InstallPath_String = 6001, - Prop_HasDisplayComponent_Bool = 6002, - Prop_HasControllerComponent_Bool = 6003, - Prop_HasCameraComponent_Bool = 6004, - Prop_HasDriverDirectModeComponent_Bool = 6005, - Prop_HasVirtualDisplayComponent_Bool = 6006, + Prop_UserConfigPath_String = 6000, + Prop_InstallPath_String = 6001, + Prop_HasDisplayComponent_Bool = 6002, + Prop_HasControllerComponent_Bool = 6003, + Prop_HasCameraComponent_Bool = 6004, + Prop_HasDriverDirectModeComponent_Bool = 6005, + Prop_HasVirtualDisplayComponent_Bool = 6006, // Vendors are free to expose private debug data in this reserved region - Prop_VendorSpecific_Reserved_Start = 10000, - Prop_VendorSpecific_Reserved_End = 10999, + Prop_VendorSpecific_Reserved_Start = 10000, + Prop_VendorSpecific_Reserved_End = 10999, }; /** No string property will ever be longer than this length */ @@ -371,18 +366,18 @@ static const uint32_t k_unMaxPropertyStringSize = 32 * 1024; /** Used to return errors that occur when reading properties. */ enum ETrackedPropertyError { - TrackedProp_Success = 0, - TrackedProp_WrongDataType = 1, - TrackedProp_WrongDeviceClass = 2, - TrackedProp_BufferTooSmall = 3, - TrackedProp_UnknownProperty = 4, // Driver has not set the property (and may not ever). - TrackedProp_InvalidDevice = 5, - TrackedProp_CouldNotContactServer = 6, - TrackedProp_ValueNotProvidedByDevice = 7, - TrackedProp_StringExceedsMaximumLength = 8, - TrackedProp_NotYetAvailable = 9, // The property value isn't known yet, but is expected soon. Call again later. - TrackedProp_PermissionDenied = 10, - TrackedProp_InvalidOperation = 11, + TrackedProp_Success = 0, + TrackedProp_WrongDataType = 1, + TrackedProp_WrongDeviceClass = 2, + TrackedProp_BufferTooSmall = 3, + TrackedProp_UnknownProperty = 4, // Driver has not set the property (and may not ever). + TrackedProp_InvalidDevice = 5, + TrackedProp_CouldNotContactServer = 6, + TrackedProp_ValueNotProvidedByDevice = 7, + TrackedProp_StringExceedsMaximumLength = 8, + TrackedProp_NotYetAvailable = 9, // The property value isn't known yet, but is expected soon. Call again later. + TrackedProp_PermissionDenied = 10, + TrackedProp_InvalidOperation = 11, }; /** Allows the application to control what part of the provided texture will be used in the @@ -396,7 +391,7 @@ struct VRTextureBounds_t /** Allows specifying pose used to render provided scene texture (if different from value returned by WaitGetPoses). */ struct VRTextureWithPose_t : public Texture_t { - HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures. + HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures. }; /** Allows the application to control how scene textures are used by the compositor when calling Submit. */ @@ -424,7 +419,7 @@ enum EVRSubmitFlags * Be sure to call OpenVR_Shutdown before destroying these resources. */ struct VRVulkanTextureData_t { - uint64_t m_nImage; // VkImage + uint64_t m_nImage; // VkImage VkDevice_T *m_pDevice; VkPhysicalDevice_T *m_pPhysicalDevice; VkInstance_T *m_pInstance; @@ -461,220 +456,216 @@ enum EVREventType { VREvent_None = 0, - VREvent_TrackedDeviceActivated = 100, - VREvent_TrackedDeviceDeactivated = 101, - VREvent_TrackedDeviceUpdated = 102, - VREvent_TrackedDeviceUserInteractionStarted = 103, - VREvent_TrackedDeviceUserInteractionEnded = 104, - VREvent_IpdChanged = 105, - VREvent_EnterStandbyMode = 106, - VREvent_LeaveStandbyMode = 107, - VREvent_TrackedDeviceRoleChanged = 108, - VREvent_WatchdogWakeUpRequested = 109, - VREvent_LensDistortionChanged = 110, - VREvent_PropertyChanged = 111, - VREvent_WirelessDisconnect = 112, - VREvent_WirelessReconnect = 113, + VREvent_TrackedDeviceActivated = 100, + VREvent_TrackedDeviceDeactivated = 101, + VREvent_TrackedDeviceUpdated = 102, + VREvent_TrackedDeviceUserInteractionStarted = 103, + VREvent_TrackedDeviceUserInteractionEnded = 104, + VREvent_IpdChanged = 105, + VREvent_EnterStandbyMode = 106, + VREvent_LeaveStandbyMode = 107, + VREvent_TrackedDeviceRoleChanged = 108, + VREvent_WatchdogWakeUpRequested = 109, + VREvent_LensDistortionChanged = 110, + VREvent_PropertyChanged = 111, + VREvent_WirelessDisconnect = 112, + VREvent_WirelessReconnect = 113, - VREvent_ButtonPress = 200, // data is controller - VREvent_ButtonUnpress = 201, // data is controller - VREvent_ButtonTouch = 202, // data is controller - VREvent_ButtonUntouch = 203, // data is controller + VREvent_ButtonPress = 200, // data is controller + VREvent_ButtonUnpress = 201, // data is controller + VREvent_ButtonTouch = 202, // data is controller + VREvent_ButtonUntouch = 203, // data is controller - VREvent_MouseMove = 300, // data is mouse - VREvent_MouseButtonDown = 301, // data is mouse - VREvent_MouseButtonUp = 302, // data is mouse - VREvent_FocusEnter = 303, // data is overlay - VREvent_FocusLeave = 304, // data is overlay - VREvent_Scroll = 305, // data is mouse - VREvent_TouchPadMove = 306, // data is mouse - VREvent_OverlayFocusChanged = 307, // data is overlay, global event + VREvent_MouseMove = 300, // data is mouse + VREvent_MouseButtonDown = 301, // data is mouse + VREvent_MouseButtonUp = 302, // data is mouse + VREvent_FocusEnter = 303, // data is overlay + VREvent_FocusLeave = 304, // data is overlay + VREvent_Scroll = 305, // data is mouse + VREvent_TouchPadMove = 306, // data is mouse + VREvent_OverlayFocusChanged = 307, // data is overlay, global event - VREvent_InputFocusCaptured = 400, // data is process DEPRECATED - VREvent_InputFocusReleased = 401, // data is process DEPRECATED - VREvent_SceneFocusLost = 402, // data is process - VREvent_SceneFocusGained = 403, // data is process - VREvent_SceneApplicationChanged = 404, // data is process - The App actually drawing the scene changed (usually to or from the compositor) - VREvent_SceneFocusChanged = 405, // data is process - New app got access to draw the scene - VREvent_InputFocusChanged = 406, // data is process - VREvent_SceneApplicationSecondaryRenderingStarted = 407, // data is process + VREvent_InputFocusCaptured = 400, // data is process DEPRECATED + VREvent_InputFocusReleased = 401, // data is process DEPRECATED + VREvent_SceneFocusLost = 402, // data is process + VREvent_SceneFocusGained = 403, // data is process + VREvent_SceneApplicationChanged = 404, // data is process - The App actually drawing the scene changed (usually to or from the compositor) + VREvent_SceneFocusChanged = 405, // data is process - New app got access to draw the scene + VREvent_InputFocusChanged = 406, // data is process + VREvent_SceneApplicationSecondaryRenderingStarted = 407, // data is process - VREvent_HideRenderModels = 410, // Sent to the scene application to request hiding render models temporarily - VREvent_ShowRenderModels = 411, // Sent to the scene application to request restoring render model visibility + VREvent_HideRenderModels = 410, // Sent to the scene application to request hiding render models temporarily + VREvent_ShowRenderModels = 411, // Sent to the scene application to request restoring render model visibility - VREvent_OverlayShown = 500, - VREvent_OverlayHidden = 501, - VREvent_DashboardActivated = 502, - VREvent_DashboardDeactivated = 503, - VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay - VREvent_DashboardRequested = 505, // Sent to the overlay manager - data is overlay - VREvent_ResetDashboard = 506, // Send to the overlay manager - VREvent_RenderToast = 507, // Send to the dashboard to render a toast - data is the notification ID - VREvent_ImageLoaded = 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading - VREvent_ShowKeyboard = 509, // Sent to keyboard renderer in the dashboard to invoke it - VREvent_HideKeyboard = 510, // Sent to keyboard renderer in the dashboard to hide it - VREvent_OverlayGamepadFocusGained = 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it - VREvent_OverlayGamepadFocusLost = 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else + VREvent_OverlayShown = 500, + VREvent_OverlayHidden = 501, + VREvent_DashboardActivated = 502, + VREvent_DashboardDeactivated = 503, + VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay + VREvent_DashboardRequested = 505, // Sent to the overlay manager - data is overlay + VREvent_ResetDashboard = 506, // Send to the overlay manager + VREvent_RenderToast = 507, // Send to the dashboard to render a toast - data is the notification ID + VREvent_ImageLoaded = 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading + VREvent_ShowKeyboard = 509, // Sent to keyboard renderer in the dashboard to invoke it + VREvent_HideKeyboard = 510, // Sent to keyboard renderer in the dashboard to hide it + VREvent_OverlayGamepadFocusGained = 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it + VREvent_OverlayGamepadFocusLost = 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else VREvent_OverlaySharedTextureChanged = 513, - VREvent_DashboardGuideButtonDown = 514, - VREvent_DashboardGuideButtonUp = 515, - VREvent_ScreenshotTriggered = 516, // Screenshot button combo was pressed, Dashboard should request a screenshot - VREvent_ImageFailed = 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load - VREvent_DashboardOverlayCreated = 518, + VREvent_DashboardGuideButtonDown = 514, + VREvent_DashboardGuideButtonUp = 515, + VREvent_ScreenshotTriggered = 516, // Screenshot button combo was pressed, Dashboard should request a screenshot + VREvent_ImageFailed = 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load + VREvent_DashboardOverlayCreated = 518, // Screenshot API - VREvent_RequestScreenshot = 520, // Sent by vrclient application to compositor to take a screenshot - VREvent_ScreenshotTaken = 521, // Sent by compositor to the application that the screenshot has been taken - VREvent_ScreenshotFailed = 522, // Sent by compositor to the application that the screenshot failed to be taken - VREvent_SubmitScreenshotToDashboard = 523, // Sent by compositor to the dashboard that a completed screenshot was submitted - VREvent_ScreenshotProgressToDashboard = 524, // Sent by compositor to the dashboard that a completed screenshot was submitted + VREvent_RequestScreenshot = 520, // Sent by vrclient application to compositor to take a screenshot + VREvent_ScreenshotTaken = 521, // Sent by compositor to the application that the screenshot has been taken + VREvent_ScreenshotFailed = 522, // Sent by compositor to the application that the screenshot failed to be taken + VREvent_SubmitScreenshotToDashboard = 523, // Sent by compositor to the dashboard that a completed screenshot was submitted + VREvent_ScreenshotProgressToDashboard = 524, // Sent by compositor to the dashboard that a completed screenshot was submitted - VREvent_PrimaryDashboardDeviceChanged = 525, + VREvent_PrimaryDashboardDeviceChanged = 525, - VREvent_Notification_Shown = 600, - VREvent_Notification_Hidden = 601, - VREvent_Notification_BeginInteraction = 602, - VREvent_Notification_Destroyed = 603, + VREvent_Notification_Shown = 600, + VREvent_Notification_Hidden = 601, + VREvent_Notification_BeginInteraction = 602, + VREvent_Notification_Destroyed = 603, - VREvent_Quit = 700, // data is process - VREvent_ProcessQuit = 701, // data is process - VREvent_QuitAborted_UserPrompt = 702, // data is process - VREvent_QuitAcknowledged = 703, // data is process - VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down + VREvent_Quit = 700, // data is process + VREvent_ProcessQuit = 701, // data is process + VREvent_QuitAborted_UserPrompt = 702, // data is process + VREvent_QuitAcknowledged = 703, // data is process + VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down - VREvent_ChaperoneDataHasChanged = 800, - VREvent_ChaperoneUniverseHasChanged = 801, - VREvent_ChaperoneTempDataHasChanged = 802, - VREvent_ChaperoneSettingsHaveChanged = 803, - VREvent_SeatedZeroPoseReset = 804, + VREvent_ChaperoneDataHasChanged = 800, + VREvent_ChaperoneUniverseHasChanged = 801, + VREvent_ChaperoneTempDataHasChanged = 802, + VREvent_ChaperoneSettingsHaveChanged = 803, + VREvent_SeatedZeroPoseReset = 804, - VREvent_AudioSettingsHaveChanged = 820, + VREvent_AudioSettingsHaveChanged = 820, - VREvent_BackgroundSettingHasChanged = 850, - VREvent_CameraSettingsHaveChanged = 851, - VREvent_ReprojectionSettingHasChanged = 852, - VREvent_ModelSkinSettingsHaveChanged = 853, - VREvent_EnvironmentSettingsHaveChanged = 854, - VREvent_PowerSettingsHaveChanged = 855, + VREvent_BackgroundSettingHasChanged = 850, + VREvent_CameraSettingsHaveChanged = 851, + VREvent_ReprojectionSettingHasChanged = 852, + VREvent_ModelSkinSettingsHaveChanged = 853, + VREvent_EnvironmentSettingsHaveChanged = 854, + VREvent_PowerSettingsHaveChanged = 855, VREvent_EnableHomeAppSettingsHaveChanged = 856, - VREvent_StatusUpdate = 900, + VREvent_StatusUpdate = 900, - VREvent_MCImageUpdated = 1000, + VREvent_MCImageUpdated = 1000, - VREvent_FirmwareUpdateStarted = 1100, - VREvent_FirmwareUpdateFinished = 1101, + VREvent_FirmwareUpdateStarted = 1100, + VREvent_FirmwareUpdateFinished = 1101, - VREvent_KeyboardClosed = 1200, - VREvent_KeyboardCharInput = 1201, - VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard + VREvent_KeyboardClosed = 1200, + VREvent_KeyboardCharInput = 1201, + VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard - VREvent_ApplicationTransitionStarted = 1300, - VREvent_ApplicationTransitionAborted = 1301, - VREvent_ApplicationTransitionNewAppStarted = 1302, - VREvent_ApplicationListUpdated = 1303, - VREvent_ApplicationMimeTypeLoad = 1304, + VREvent_ApplicationTransitionStarted = 1300, + VREvent_ApplicationTransitionAborted = 1301, + VREvent_ApplicationTransitionNewAppStarted = 1302, + VREvent_ApplicationListUpdated = 1303, + VREvent_ApplicationMimeTypeLoad = 1304, VREvent_ApplicationTransitionNewAppLaunchComplete = 1305, - VREvent_ProcessConnected = 1306, - VREvent_ProcessDisconnected = 1307, + VREvent_ProcessConnected = 1306, + VREvent_ProcessDisconnected = 1307, - VREvent_Compositor_MirrorWindowShown = 1400, - VREvent_Compositor_MirrorWindowHidden = 1401, - VREvent_Compositor_ChaperoneBoundsShown = 1410, - VREvent_Compositor_ChaperoneBoundsHidden = 1411, + VREvent_Compositor_MirrorWindowShown = 1400, + VREvent_Compositor_MirrorWindowHidden = 1401, + VREvent_Compositor_ChaperoneBoundsShown = 1410, + VREvent_Compositor_ChaperoneBoundsHidden = 1411, - VREvent_TrackedCamera_StartVideoStream = 1500, - VREvent_TrackedCamera_StopVideoStream = 1501, - VREvent_TrackedCamera_PauseVideoStream = 1502, + VREvent_TrackedCamera_StartVideoStream = 1500, + VREvent_TrackedCamera_StopVideoStream = 1501, + VREvent_TrackedCamera_PauseVideoStream = 1502, VREvent_TrackedCamera_ResumeVideoStream = 1503, - VREvent_TrackedCamera_EditingSurface = 1550, + VREvent_TrackedCamera_EditingSurface = 1550, - VREvent_PerformanceTest_EnableCapture = 1600, - VREvent_PerformanceTest_DisableCapture = 1601, - VREvent_PerformanceTest_FidelityLevel = 1602, + VREvent_PerformanceTest_EnableCapture = 1600, + VREvent_PerformanceTest_DisableCapture = 1601, + VREvent_PerformanceTest_FidelityLevel = 1602, + + VREvent_MessageOverlay_Closed = 1650, + VREvent_MessageOverlayCloseRequested = 1651, - VREvent_MessageOverlay_Closed = 1650, - VREvent_MessageOverlayCloseRequested = 1651, - // Vendors are free to expose private events in this reserved region - VREvent_VendorSpecific_Reserved_Start = 10000, - VREvent_VendorSpecific_Reserved_End = 19999, + VREvent_VendorSpecific_Reserved_Start = 10000, + VREvent_VendorSpecific_Reserved_End = 19999, }; - /** Level of Hmd activity */ // UserInteraction_Timeout means the device is in the process of timing out. // InUse = ( k_EDeviceActivityLevel_UserInteraction || k_EDeviceActivityLevel_UserInteraction_Timeout ) // VREvent_TrackedDeviceUserInteractionStarted fires when the devices transitions from Standby -> UserInteraction or Idle -> UserInteraction. // VREvent_TrackedDeviceUserInteractionEnded fires when the devices transitions from UserInteraction_Timeout -> Idle enum EDeviceActivityLevel -{ - k_EDeviceActivityLevel_Unknown = -1, - k_EDeviceActivityLevel_Idle = 0, // No activity for the last 10 seconds - k_EDeviceActivityLevel_UserInteraction = 1, // Activity (movement or prox sensor) is happening now - k_EDeviceActivityLevel_UserInteraction_Timeout = 2, // No activity for the last 0.5 seconds - k_EDeviceActivityLevel_Standby = 3, // Idle for at least 5 seconds (configurable in Settings -> Power Management) +{ + k_EDeviceActivityLevel_Unknown = -1, + k_EDeviceActivityLevel_Idle = 0, // No activity for the last 10 seconds + k_EDeviceActivityLevel_UserInteraction = 1, // Activity (movement or prox sensor) is happening now + k_EDeviceActivityLevel_UserInteraction_Timeout = 2, // No activity for the last 0.5 seconds + k_EDeviceActivityLevel_Standby = 3, // Idle for at least 5 seconds (configurable in Settings -> Power Management) }; - /** VR controller button and axis IDs */ enum EVRButtonId { - k_EButton_System = 0, - k_EButton_ApplicationMenu = 1, - k_EButton_Grip = 2, - k_EButton_DPad_Left = 3, - k_EButton_DPad_Up = 4, - k_EButton_DPad_Right = 5, - k_EButton_DPad_Down = 6, - k_EButton_A = 7, - - k_EButton_ProximitySensor = 31, + k_EButton_System = 0, + k_EButton_ApplicationMenu = 1, + k_EButton_Grip = 2, + k_EButton_DPad_Left = 3, + k_EButton_DPad_Up = 4, + k_EButton_DPad_Right = 5, + k_EButton_DPad_Down = 6, + k_EButton_A = 7, - k_EButton_Axis0 = 32, - k_EButton_Axis1 = 33, - k_EButton_Axis2 = 34, - k_EButton_Axis3 = 35, - k_EButton_Axis4 = 36, + k_EButton_ProximitySensor = 31, + + k_EButton_Axis0 = 32, + k_EButton_Axis1 = 33, + k_EButton_Axis2 = 34, + k_EButton_Axis3 = 35, + k_EButton_Axis4 = 36, // aliases for well known controllers - k_EButton_SteamVR_Touchpad = k_EButton_Axis0, - k_EButton_SteamVR_Trigger = k_EButton_Axis1, + k_EButton_SteamVR_Touchpad = k_EButton_Axis0, + k_EButton_SteamVR_Trigger = k_EButton_Axis1, - k_EButton_Dashboard_Back = k_EButton_Grip, + k_EButton_Dashboard_Back = k_EButton_Grip, - k_EButton_Max = 64 + k_EButton_Max = 64 }; -inline uint64_t ButtonMaskFromId( EVRButtonId id ) { return 1ull << id; } +inline uint64_t ButtonMaskFromId(EVRButtonId id) { return 1ull << id; } /** used for controller button events */ struct VREvent_Controller_t { - uint32_t button; // EVRButtonId enum + uint32_t button; // EVRButtonId enum }; - /** used for simulated mouse events in overlay space */ enum EVRMouseButton { - VRMouseButton_Left = 0x0001, - VRMouseButton_Right = 0x0002, - VRMouseButton_Middle = 0x0004, + VRMouseButton_Left = 0x0001, + VRMouseButton_Right = 0x0002, + VRMouseButton_Middle = 0x0004, }; - /** used for simulated mouse events in overlay space */ struct VREvent_Mouse_t { - float x, y; // co-ords are in GL space, bottom left of the texture is 0,0 - uint32_t button; // EVRMouseButton enum + float x, y; // co-ords are in GL space, bottom left of the texture is 0,0 + uint32_t button; // EVRMouseButton enum }; /** used for simulated mouse wheel scroll in overlay space */ struct VREvent_Scroll_t { - float xdelta, ydelta; // movement in fraction of the pad traversed since last delta, 1.0 for a full swipe + float xdelta, ydelta; // movement in fraction of the pad traversed since last delta, 1.0 for a full swipe uint32_t repeatCount; }; @@ -713,25 +704,23 @@ struct VREvent_Process_t bool bForced; }; - /** Used for a few events about overlays */ struct VREvent_Overlay_t { uint64_t overlayHandle; }; - /** Used for a few events about overlays */ struct VREvent_Status_t { - uint32_t statusState; // EVRState enum + uint32_t statusState; // EVRState enum }; /** Used for keyboard events **/ struct VREvent_Keyboard_t { - char cNewInput[8]; // Up to 11 bytes of new input - uint64_t uUserValue; // Possible flags about the new input + char cNewInput[8]; // Up to 11 bytes of new input + uint64_t uUserValue; // Possible flags about the new input }; struct VREvent_Ipd_t @@ -787,7 +776,7 @@ struct VREvent_EditingCameraSurface_t struct VREvent_MessageOverlay_t { - uint32_t unVRMessageOverlayResponse; // vr::VRMessageOverlayResponse enum + uint32_t unVRMessageOverlayResponse; // vr::VRMessageOverlayResponse enum }; struct VREvent_Property_t @@ -797,8 +786,7 @@ struct VREvent_Property_t }; /** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py */ -typedef union -{ +typedef union { VREvent_Reserved_t reserved; VREvent_Controller_t controller; VREvent_Mouse_t mouse; @@ -821,25 +809,24 @@ typedef union VREvent_Property_t property; } VREvent_Data_t; - -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif /** An event posted by the server to all running applications */ struct VREvent_t { - uint32_t eventType; // EVREventType enum + uint32_t eventType; // EVREventType enum TrackedDeviceIndex_t trackedDeviceIndex; float eventAgeSeconds; // event data must be the end of the struct as its size is variable VREvent_Data_t data; }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif /** The mesh to draw into the stencil (or depth) buffer to perform @@ -854,7 +841,6 @@ struct HiddenAreaMesh_t uint32_t unTriangleCount; }; - enum EHiddenAreaMeshType { k_eHiddenAreaMesh_Standard = 0, @@ -864,7 +850,6 @@ enum EHiddenAreaMeshType k_eHiddenAreaMesh_Max = 3, }; - /** Identifies what kind of axis is on the controller at index n. Read this type * with pVRSystem->Get( nControllerDeviceIndex, Prop_Axis0Type_Int32 + n ); */ @@ -873,32 +858,29 @@ enum EVRControllerAxisType k_eControllerAxis_None = 0, k_eControllerAxis_TrackPad = 1, k_eControllerAxis_Joystick = 2, - k_eControllerAxis_Trigger = 3, // Analog trigger data is in the X axis + k_eControllerAxis_Trigger = 3, // Analog trigger data is in the X axis }; - /** contains information about one axis on the controller */ struct VRControllerAxis_t { - float x; // Ranges from -1.0 to 1.0 for joysticks and track pads. Ranges from 0.0 to 1.0 for triggers were 0 is fully released. - float y; // Ranges from -1.0 to 1.0 for joysticks and track pads. Is always 0.0 for triggers. + float x; // Ranges from -1.0 to 1.0 for joysticks and track pads. Ranges from 0.0 to 1.0 for triggers were 0 is fully released. + float y; // Ranges from -1.0 to 1.0 for joysticks and track pads. Is always 0.0 for triggers. }; - /** the number of axes in the controller state */ static const uint32_t k_unControllerStateAxisCount = 5; - -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif /** Holds all the state of a controller at one moment in time. */ struct VRControllerState001_t { - // If packet num matches that on your prior call, then the controller state hasn't been changed since + // If packet num matches that on your prior call, then the controller state hasn't been changed since // your last call and there is no need to process it uint32_t unPacketNum; @@ -907,16 +889,14 @@ struct VRControllerState001_t uint64_t ulButtonTouched; // Axis data for the controller's analog inputs - VRControllerAxis_t rAxis[ k_unControllerStateAxisCount ]; + VRControllerAxis_t rAxis[k_unControllerStateAxisCount]; }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif - typedef VRControllerState001_t VRControllerState_t; - /** determines how to provide output to the application of various event processing functions. */ enum EVRControllerEventOutputType { @@ -924,8 +904,6 @@ enum EVRControllerEventOutputType ControllerEventOutput_VREvents = 1, }; - - /** Collision Bounds Style */ enum ECollisionBoundsStyle { @@ -941,7 +919,7 @@ enum ECollisionBoundsStyle /** Allows the application to customize how the overlay appears in the compositor */ struct Compositor_OverlaySettings { - uint32_t size; // sizeof(Compositor_OverlaySettings) + uint32_t size; // sizeof(Compositor_OverlaySettings) bool curved, antialias; float scale, distance, alpha; float uOffset, vOffset, uScale, vScale; @@ -957,49 +935,48 @@ static const VROverlayHandle_t k_ulOverlayHandleInvalid = 0; /** Errors that can occur around VR overlays */ enum EVROverlayError { - VROverlayError_None = 0, + VROverlayError_None = 0, - VROverlayError_UnknownOverlay = 10, - VROverlayError_InvalidHandle = 11, - VROverlayError_PermissionDenied = 12, - VROverlayError_OverlayLimitExceeded = 13, // No more overlays could be created because the maximum number already exist - VROverlayError_WrongVisibilityType = 14, - VROverlayError_KeyTooLong = 15, - VROverlayError_NameTooLong = 16, - VROverlayError_KeyInUse = 17, - VROverlayError_WrongTransformType = 18, - VROverlayError_InvalidTrackedDevice = 19, - VROverlayError_InvalidParameter = 20, - VROverlayError_ThumbnailCantBeDestroyed = 21, - VROverlayError_ArrayTooSmall = 22, - VROverlayError_RequestFailed = 23, - VROverlayError_InvalidTexture = 24, - VROverlayError_UnableToLoadFile = 25, - VROverlayError_KeyboardAlreadyInUse = 26, - VROverlayError_NoNeighbor = 27, - VROverlayError_TooManyMaskPrimitives = 29, - VROverlayError_BadMaskPrimitive = 30, + VROverlayError_UnknownOverlay = 10, + VROverlayError_InvalidHandle = 11, + VROverlayError_PermissionDenied = 12, + VROverlayError_OverlayLimitExceeded = 13, // No more overlays could be created because the maximum number already exist + VROverlayError_WrongVisibilityType = 14, + VROverlayError_KeyTooLong = 15, + VROverlayError_NameTooLong = 16, + VROverlayError_KeyInUse = 17, + VROverlayError_WrongTransformType = 18, + VROverlayError_InvalidTrackedDevice = 19, + VROverlayError_InvalidParameter = 20, + VROverlayError_ThumbnailCantBeDestroyed = 21, + VROverlayError_ArrayTooSmall = 22, + VROverlayError_RequestFailed = 23, + VROverlayError_InvalidTexture = 24, + VROverlayError_UnableToLoadFile = 25, + VROverlayError_KeyboardAlreadyInUse = 26, + VROverlayError_NoNeighbor = 27, + VROverlayError_TooManyMaskPrimitives = 29, + VROverlayError_BadMaskPrimitive = 30, }; /** enum values to pass in to VR_Init to identify whether the application will * draw a 3D scene. */ enum EVRApplicationType { - VRApplication_Other = 0, // Some other kind of application that isn't covered by the other entries - VRApplication_Scene = 1, // Application will submit 3D frames - VRApplication_Overlay = 2, // Application only interacts with overlays - VRApplication_Background = 3, // Application should not start SteamVR if it's not already running, and should not - // keep it running if everything else quits. - VRApplication_Utility = 4, // Init should not try to load any drivers. The application needs access to utility - // interfaces (like IVRSettings and IVRApplications) but not hardware. - VRApplication_VRMonitor = 5, // Reserved for vrmonitor - VRApplication_SteamWatchdog = 6,// Reserved for Steam - VRApplication_Bootstrapper = 7, // Start up SteamVR + VRApplication_Other = 0, // Some other kind of application that isn't covered by the other entries + VRApplication_Scene = 1, // Application will submit 3D frames + VRApplication_Overlay = 2, // Application only interacts with overlays + VRApplication_Background = 3, // Application should not start SteamVR if it's not already running, and should not + // keep it running if everything else quits. + VRApplication_Utility = 4, // Init should not try to load any drivers. The application needs access to utility + // interfaces (like IVRSettings and IVRApplications) but not hardware. + VRApplication_VRMonitor = 5, // Reserved for vrmonitor + VRApplication_SteamWatchdog = 6, // Reserved for Steam + VRApplication_Bootstrapper = 7, // Start up SteamVR VRApplication_Max }; - /** error codes for firmware */ enum EVRFirmwareError { @@ -1008,7 +985,6 @@ enum EVRFirmwareError VRFirmwareError_Fail = 2, }; - /** error codes for notifications */ enum EVRNotificationError { @@ -1019,103 +995,101 @@ enum EVRNotificationError VRNotificationError_SystemWithUserValueAlreadyExists = 103, }; - /** error codes returned by Vr_Init */ // Please add adequate error description to https://developer.valvesoftware.com/w/index.php?title=Category:SteamVRHelp enum EVRInitError { - VRInitError_None = 0, + VRInitError_None = 0, VRInitError_Unknown = 1, - VRInitError_Init_InstallationNotFound = 100, - VRInitError_Init_InstallationCorrupt = 101, - VRInitError_Init_VRClientDLLNotFound = 102, - VRInitError_Init_FileNotFound = 103, - VRInitError_Init_FactoryNotFound = 104, - VRInitError_Init_InterfaceNotFound = 105, - VRInitError_Init_InvalidInterface = 106, - VRInitError_Init_UserConfigDirectoryInvalid = 107, - VRInitError_Init_HmdNotFound = 108, - VRInitError_Init_NotInitialized = 109, - VRInitError_Init_PathRegistryNotFound = 110, - VRInitError_Init_NoConfigPath = 111, - VRInitError_Init_NoLogPath = 112, - VRInitError_Init_PathRegistryNotWritable = 113, - VRInitError_Init_AppInfoInitFailed = 114, - VRInitError_Init_Retry = 115, // Used internally to cause retries to vrserver - VRInitError_Init_InitCanceledByUser = 116, // The calling application should silently exit. The user canceled app startup - VRInitError_Init_AnotherAppLaunching = 117, - VRInitError_Init_SettingsInitFailed = 118, - VRInitError_Init_ShuttingDown = 119, - VRInitError_Init_TooManyObjects = 120, - VRInitError_Init_NoServerForBackgroundApp = 121, - VRInitError_Init_NotSupportedWithCompositor = 122, - VRInitError_Init_NotAvailableToUtilityApps = 123, - VRInitError_Init_Internal = 124, - VRInitError_Init_HmdDriverIdIsNone = 125, - VRInitError_Init_HmdNotFoundPresenceFailed = 126, - VRInitError_Init_VRMonitorNotFound = 127, - VRInitError_Init_VRMonitorStartupFailed = 128, - VRInitError_Init_LowPowerWatchdogNotSupported = 129, - VRInitError_Init_InvalidApplicationType = 130, - VRInitError_Init_NotAvailableToWatchdogApps = 131, - VRInitError_Init_WatchdogDisabledInSettings = 132, - VRInitError_Init_VRDashboardNotFound = 133, - VRInitError_Init_VRDashboardStartupFailed = 134, - VRInitError_Init_VRHomeNotFound = 135, - VRInitError_Init_VRHomeStartupFailed = 136, - VRInitError_Init_RebootingBusy = 137, - VRInitError_Init_FirmwareUpdateBusy = 138, - VRInitError_Init_FirmwareRecoveryBusy = 139, + VRInitError_Init_InstallationNotFound = 100, + VRInitError_Init_InstallationCorrupt = 101, + VRInitError_Init_VRClientDLLNotFound = 102, + VRInitError_Init_FileNotFound = 103, + VRInitError_Init_FactoryNotFound = 104, + VRInitError_Init_InterfaceNotFound = 105, + VRInitError_Init_InvalidInterface = 106, + VRInitError_Init_UserConfigDirectoryInvalid = 107, + VRInitError_Init_HmdNotFound = 108, + VRInitError_Init_NotInitialized = 109, + VRInitError_Init_PathRegistryNotFound = 110, + VRInitError_Init_NoConfigPath = 111, + VRInitError_Init_NoLogPath = 112, + VRInitError_Init_PathRegistryNotWritable = 113, + VRInitError_Init_AppInfoInitFailed = 114, + VRInitError_Init_Retry = 115, // Used internally to cause retries to vrserver + VRInitError_Init_InitCanceledByUser = 116, // The calling application should silently exit. The user canceled app startup + VRInitError_Init_AnotherAppLaunching = 117, + VRInitError_Init_SettingsInitFailed = 118, + VRInitError_Init_ShuttingDown = 119, + VRInitError_Init_TooManyObjects = 120, + VRInitError_Init_NoServerForBackgroundApp = 121, + VRInitError_Init_NotSupportedWithCompositor = 122, + VRInitError_Init_NotAvailableToUtilityApps = 123, + VRInitError_Init_Internal = 124, + VRInitError_Init_HmdDriverIdIsNone = 125, + VRInitError_Init_HmdNotFoundPresenceFailed = 126, + VRInitError_Init_VRMonitorNotFound = 127, + VRInitError_Init_VRMonitorStartupFailed = 128, + VRInitError_Init_LowPowerWatchdogNotSupported = 129, + VRInitError_Init_InvalidApplicationType = 130, + VRInitError_Init_NotAvailableToWatchdogApps = 131, + VRInitError_Init_WatchdogDisabledInSettings = 132, + VRInitError_Init_VRDashboardNotFound = 133, + VRInitError_Init_VRDashboardStartupFailed = 134, + VRInitError_Init_VRHomeNotFound = 135, + VRInitError_Init_VRHomeStartupFailed = 136, + VRInitError_Init_RebootingBusy = 137, + VRInitError_Init_FirmwareUpdateBusy = 138, + VRInitError_Init_FirmwareRecoveryBusy = 139, - - VRInitError_Driver_Failed = 200, - VRInitError_Driver_Unknown = 201, - VRInitError_Driver_HmdUnknown = 202, - VRInitError_Driver_NotLoaded = 203, - VRInitError_Driver_RuntimeOutOfDate = 204, - VRInitError_Driver_HmdInUse = 205, - VRInitError_Driver_NotCalibrated = 206, - VRInitError_Driver_CalibrationInvalid = 207, - VRInitError_Driver_HmdDisplayNotFound = 208, + VRInitError_Driver_Failed = 200, + VRInitError_Driver_Unknown = 201, + VRInitError_Driver_HmdUnknown = 202, + VRInitError_Driver_NotLoaded = 203, + VRInitError_Driver_RuntimeOutOfDate = 204, + VRInitError_Driver_HmdInUse = 205, + VRInitError_Driver_NotCalibrated = 206, + VRInitError_Driver_CalibrationInvalid = 207, + VRInitError_Driver_HmdDisplayNotFound = 208, VRInitError_Driver_TrackedDeviceInterfaceUnknown = 209, // VRInitError_Driver_HmdDisplayNotFoundAfterFix = 210, // not needed: here for historic reasons - VRInitError_Driver_HmdDriverIdOutOfBounds = 211, - VRInitError_Driver_HmdDisplayMirrored = 212, + VRInitError_Driver_HmdDriverIdOutOfBounds = 211, + VRInitError_Driver_HmdDisplayMirrored = 212, - VRInitError_IPC_ServerInitFailed = 300, - VRInitError_IPC_ConnectFailed = 301, - VRInitError_IPC_SharedStateInitFailed = 302, - VRInitError_IPC_CompositorInitFailed = 303, - VRInitError_IPC_MutexInitFailed = 304, - VRInitError_IPC_Failed = 305, - VRInitError_IPC_CompositorConnectFailed = 306, + VRInitError_IPC_ServerInitFailed = 300, + VRInitError_IPC_ConnectFailed = 301, + VRInitError_IPC_SharedStateInitFailed = 302, + VRInitError_IPC_CompositorInitFailed = 303, + VRInitError_IPC_MutexInitFailed = 304, + VRInitError_IPC_Failed = 305, + VRInitError_IPC_CompositorConnectFailed = 306, VRInitError_IPC_CompositorInvalidConnectResponse = 307, VRInitError_IPC_ConnectFailedAfterMultipleAttempts = 308, - VRInitError_Compositor_Failed = 400, - VRInitError_Compositor_D3D11HardwareRequired = 401, - VRInitError_Compositor_FirmwareRequiresUpdate = 402, - VRInitError_Compositor_OverlayInitFailed = 403, - VRInitError_Compositor_ScreenshotsInitFailed = 404, - VRInitError_Compositor_UnableToCreateDevice = 405, + VRInitError_Compositor_Failed = 400, + VRInitError_Compositor_D3D11HardwareRequired = 401, + VRInitError_Compositor_FirmwareRequiresUpdate = 402, + VRInitError_Compositor_OverlayInitFailed = 403, + VRInitError_Compositor_ScreenshotsInitFailed = 404, + VRInitError_Compositor_UnableToCreateDevice = 405, - VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000, + VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000, - VRInitError_VendorSpecific_HmdFound_CantOpenDevice = 1101, - VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102, - VRInitError_VendorSpecific_HmdFound_NoStoredConfig = 1103, - VRInitError_VendorSpecific_HmdFound_ConfigTooBig = 1104, - VRInitError_VendorSpecific_HmdFound_ConfigTooSmall = 1105, - VRInitError_VendorSpecific_HmdFound_UnableToInitZLib = 1106, - VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion = 1107, - VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart = 1108, - VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart = 1109, - VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext = 1110, - VRInitError_VendorSpecific_HmdFound_UserDataAddressRange = 1111, - VRInitError_VendorSpecific_HmdFound_UserDataError = 1112, - VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck = 1113, + VRInitError_VendorSpecific_HmdFound_CantOpenDevice = 1101, + VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102, + VRInitError_VendorSpecific_HmdFound_NoStoredConfig = 1103, + VRInitError_VendorSpecific_HmdFound_ConfigTooBig = 1104, + VRInitError_VendorSpecific_HmdFound_ConfigTooSmall = 1105, + VRInitError_VendorSpecific_HmdFound_UnableToInitZLib = 1106, + VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion = 1107, + VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart = 1108, + VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart = 1109, + VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext = 1110, + VRInitError_VendorSpecific_HmdFound_UserDataAddressRange = 1111, + VRInitError_VendorSpecific_HmdFound_UserDataError = 1112, + VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck = 1113, VRInitError_Steam_SteamInstallationNotFound = 2000, }; @@ -1123,7 +1097,7 @@ enum EVRInitError enum EVRScreenshotType { VRScreenshotType_None = 0, - VRScreenshotType_Mono = 1, // left eye only + VRScreenshotType_Mono = 1, // left eye only VRScreenshotType_Stereo = 2, VRScreenshotType_Cubemap = 3, VRScreenshotType_MonoPanorama = 4, @@ -1138,35 +1112,35 @@ enum EVRScreenshotPropertyFilenames enum EVRTrackedCameraError { - VRTrackedCameraError_None = 0, - VRTrackedCameraError_OperationFailed = 100, - VRTrackedCameraError_InvalidHandle = 101, - VRTrackedCameraError_InvalidFrameHeaderVersion = 102, - VRTrackedCameraError_OutOfHandles = 103, - VRTrackedCameraError_IPCFailure = 104, - VRTrackedCameraError_NotSupportedForThisDevice = 105, - VRTrackedCameraError_SharedMemoryFailure = 106, - VRTrackedCameraError_FrameBufferingFailure = 107, - VRTrackedCameraError_StreamSetupFailure = 108, - VRTrackedCameraError_InvalidGLTextureId = 109, + VRTrackedCameraError_None = 0, + VRTrackedCameraError_OperationFailed = 100, + VRTrackedCameraError_InvalidHandle = 101, + VRTrackedCameraError_InvalidFrameHeaderVersion = 102, + VRTrackedCameraError_OutOfHandles = 103, + VRTrackedCameraError_IPCFailure = 104, + VRTrackedCameraError_NotSupportedForThisDevice = 105, + VRTrackedCameraError_SharedMemoryFailure = 106, + VRTrackedCameraError_FrameBufferingFailure = 107, + VRTrackedCameraError_StreamSetupFailure = 108, + VRTrackedCameraError_InvalidGLTextureId = 109, VRTrackedCameraError_InvalidSharedTextureHandle = 110, - VRTrackedCameraError_FailedToGetGLTextureId = 111, - VRTrackedCameraError_SharedTextureFailure = 112, - VRTrackedCameraError_NoFrameAvailable = 113, - VRTrackedCameraError_InvalidArgument = 114, - VRTrackedCameraError_InvalidFrameBufferSize = 115, + VRTrackedCameraError_FailedToGetGLTextureId = 111, + VRTrackedCameraError_SharedTextureFailure = 112, + VRTrackedCameraError_NoFrameAvailable = 113, + VRTrackedCameraError_InvalidArgument = 114, + VRTrackedCameraError_InvalidFrameBufferSize = 115, }; enum EVRTrackedCameraFrameType { - VRTrackedCameraFrameType_Distorted = 0, // This is the camera video frame size in pixels, still distorted. - VRTrackedCameraFrameType_Undistorted, // In pixels, an undistorted inscribed rectangle region without invalid regions. This size is subject to changes shortly. - VRTrackedCameraFrameType_MaximumUndistorted, // In pixels, maximum undistorted with invalid regions. Non zero alpha component identifies valid regions. + VRTrackedCameraFrameType_Distorted = 0, // This is the camera video frame size in pixels, still distorted. + VRTrackedCameraFrameType_Undistorted, // In pixels, an undistorted inscribed rectangle region without invalid regions. This size is subject to changes shortly. + VRTrackedCameraFrameType_MaximumUndistorted, // In pixels, maximum undistorted with invalid regions. Non zero alpha component identifies valid regions. MAX_CAMERA_FRAME_TYPES }; typedef uint64_t TrackedCameraHandle_t; -#define INVALID_TRACKED_CAMERA_HANDLE ((vr::TrackedCameraHandle_t)0) +#define INVALID_TRACKED_CAMERA_HANDLE ((vr::TrackedCameraHandle_t)0) struct CameraVideoStreamFrameHeader_t { @@ -1186,15 +1160,15 @@ typedef uint32_t ScreenshotHandle_t; static const uint32_t k_unScreenshotHandleInvalid = 0; -#pragma pack( pop ) +#pragma pack(pop) // figure out how to import from the VR API dll #if defined(_WIN32) #ifdef VR_API_EXPORT -#define VR_INTERFACE extern "C" __declspec( dllexport ) +#define VR_INTERFACE extern "C" __declspec(dllexport) #else -#define VR_INTERFACE extern "C" __declspec( dllimport ) +#define VR_INTERFACE extern "C" __declspec(dllimport) #endif #elif defined(__GNUC__) || defined(COMPILER_GCC) || defined(__APPLE__) @@ -1202,83 +1176,78 @@ static const uint32_t k_unScreenshotHandleInvalid = 0; #ifdef VR_API_EXPORT #define VR_INTERFACE extern "C" __attribute__((visibility("default"))) #else -#define VR_INTERFACE extern "C" +#define VR_INTERFACE extern "C" #endif #else #error "Unsupported Platform." #endif - -#if defined( _WIN32 ) +#if defined(_WIN32) #define VR_CALLTYPE __cdecl #else -#define VR_CALLTYPE +#define VR_CALLTYPE #endif -} // namespace vr - -#endif // _INCLUDE_VRTYPES_H +} // namespace vr +#endif // _INCLUDE_VRTYPES_H // vrannotation.h #ifdef API_GEN -# define VR_CLANG_ATTR(ATTR) __attribute__((annotate( ATTR ))) +#define VR_CLANG_ATTR(ATTR) __attribute__((annotate(ATTR))) #else -# define VR_CLANG_ATTR(ATTR) +#define VR_CLANG_ATTR(ATTR) #endif -#define VR_METHOD_DESC(DESC) VR_CLANG_ATTR( "desc:" #DESC ";" ) -#define VR_IGNOREATTR() VR_CLANG_ATTR( "ignore" ) -#define VR_OUT_STRUCT() VR_CLANG_ATTR( "out_struct: ;" ) -#define VR_OUT_STRING() VR_CLANG_ATTR( "out_string: ;" ) -#define VR_OUT_ARRAY_CALL(COUNTER,FUNCTION,PARAMS) VR_CLANG_ATTR( "out_array_call:" #COUNTER "," #FUNCTION "," #PARAMS ";" ) -#define VR_OUT_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR( "out_array_count:" #COUNTER ";" ) -#define VR_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR( "array_count:" #COUNTER ";" ) -#define VR_ARRAY_COUNT_D(COUNTER, DESC) VR_CLANG_ATTR( "array_count:" #COUNTER ";desc:" #DESC ) -#define VR_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR( "buffer_count:" #COUNTER ";" ) -#define VR_OUT_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR( "out_buffer_count:" #COUNTER ";" ) -#define VR_OUT_STRING_COUNT(COUNTER) VR_CLANG_ATTR( "out_string_count:" #COUNTER ";" ) +#define VR_METHOD_DESC(DESC) VR_CLANG_ATTR("desc:" #DESC ";") +#define VR_IGNOREATTR() VR_CLANG_ATTR("ignore") +#define VR_OUT_STRUCT() VR_CLANG_ATTR("out_struct: ;") +#define VR_OUT_STRING() VR_CLANG_ATTR("out_string: ;") +#define VR_OUT_ARRAY_CALL(COUNTER, FUNCTION, PARAMS) VR_CLANG_ATTR("out_array_call:" #COUNTER "," #FUNCTION "," #PARAMS ";") +#define VR_OUT_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR("out_array_count:" #COUNTER ";") +#define VR_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR("array_count:" #COUNTER ";") +#define VR_ARRAY_COUNT_D(COUNTER, DESC) VR_CLANG_ATTR("array_count:" #COUNTER ";desc:" #DESC) +#define VR_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR("buffer_count:" #COUNTER ";") +#define VR_OUT_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR("out_buffer_count:" #COUNTER ";") +#define VR_OUT_STRING_COUNT(COUNTER) VR_CLANG_ATTR("out_string_count:" #COUNTER ";") // ivrsystem.h namespace vr { - class IVRSystem { public: - - // ------------------------------------ // Display Methods // ------------------------------------ /** Suggested size for the intermediate render target that the distortion pulls from. */ - virtual void GetRecommendedRenderTargetSize( uint32_t *pnWidth, uint32_t *pnHeight ) = 0; + virtual void GetRecommendedRenderTargetSize(uint32_t *pnWidth, uint32_t *pnHeight) = 0; /** The projection matrix for the specified eye */ - virtual HmdMatrix44_t GetProjectionMatrix( EVREye eEye, float fNearZ, float fFarZ ) = 0; + virtual HmdMatrix44_t GetProjectionMatrix(EVREye eEye, float fNearZ, float fFarZ) = 0; /** The components necessary to build your own projection matrix in case your * application is doing something fancy like infinite Z */ - virtual void GetProjectionRaw( EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom ) = 0; + virtual void GetProjectionRaw(EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom) = 0; /** Gets the result of the distortion function for the specified eye and input UVs. UVs go from 0,0 in * the upper left of that eye's viewport and 1,1 in the lower right of that eye's viewport. * Returns true for success. Otherwise, returns false, and distortion coordinates are not suitable. */ - virtual bool ComputeDistortion( EVREye eEye, float fU, float fV, DistortionCoordinates_t *pDistortionCoordinates ) = 0; + virtual bool ComputeDistortion(EVREye eEye, float fU, float fV, DistortionCoordinates_t *pDistortionCoordinates) = 0; /** Returns the transform from eye space to the head space. Eye space is the per-eye flavor of head * space that provides stereo disparity. Instead of Model * View * Projection the sequence is Model * View * Eye^-1 * Projection. * Normally View and Eye^-1 will be multiplied together and treated as View in your application. */ - virtual HmdMatrix34_t GetEyeToHeadTransform( EVREye eEye ) = 0; + virtual HmdMatrix34_t GetEyeToHeadTransform(EVREye eEye) = 0; /** Returns the number of elapsed seconds since the last recorded vsync event. This * will come from a vsync timer event in the timer if possible or from the application-reported * time if that is not available. If no vsync times are available the function will * return zero for vsync time and frame counter and return false from the method. */ - virtual bool GetTimeSinceLastVsync( float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter ) = 0; + virtual bool GetTimeSinceLastVsync(float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter) = 0; /** [D3D9 Only] * Returns the adapter index that the user should pass into CreateDevice to set up D3D9 in such @@ -1290,8 +1259,8 @@ public: * Returns the adapter index that the user should pass into EnumAdapters to create the device * and swap chain in DX10 and DX11. If an error occurs the index will be set to -1. */ - virtual void GetDXGIOutputInfo( int32_t *pnAdapterIndex ) = 0; - + virtual void GetDXGIOutputInfo(int32_t *pnAdapterIndex) = 0; + /** * Returns platform- and texture-type specific adapter identification so that applications and the * compositor are creating textures and swap chains on the same GPU. If an error occurs the device @@ -1309,7 +1278,7 @@ public: * [macOS Only] * Returns an id that should be used by the application. */ - virtual void GetOutputDevice( uint64_t *pnDevice, ETextureType textureType, VkInstance_T *pInstance = nullptr ) = 0; + virtual void GetOutputDevice(uint64_t *pnDevice, ETextureType textureType, VkInstance_T *pInstance = nullptr) = 0; // ------------------------------------ // Display Mode methods @@ -1319,7 +1288,7 @@ public: virtual bool IsDisplayOnDesktop() = 0; /** Set the display visibility (true = extended, false = direct mode). Return value of true indicates that the change was successful. */ - virtual bool SetDisplayVisibility( bool bIsVisibleOnDesktop ) = 0; + virtual bool SetDisplayVisibility(bool bIsVisibleOnDesktop) = 0; // ------------------------------------ // Tracking Methods @@ -1342,7 +1311,7 @@ public: * probably not be used unless the application is the Chaperone calibration tool itself, but will provide * poses relative to the hardware-specific coordinate system in the driver. */ - virtual void GetDeviceToAbsoluteTrackingPose( ETrackingUniverseOrigin eOrigin, float fPredictedSecondsToPhotonsFromNow, VR_ARRAY_COUNT(unTrackedDevicePoseArrayCount) TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount ) = 0; + virtual void GetDeviceToAbsoluteTrackingPose(ETrackingUniverseOrigin eOrigin, float fPredictedSecondsToPhotonsFromNow, VR_ARRAY_COUNT(unTrackedDevicePoseArrayCount) TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount) = 0; /** Sets the zero pose for the seated tracker coordinate system to the current position and yaw of the HMD. After * ResetSeatedZeroPose all GetDeviceToAbsoluteTrackingPose calls that pass TrackingUniverseSeated as the origin @@ -1370,21 +1339,21 @@ public: /** Get a sorted array of device indices of a given class of tracked devices (e.g. controllers). Devices are sorted right to left * relative to the specified tracked device (default: hmd -- pass in -1 for absolute tracking space). Returns the number of devices * in the list, or the size of the array needed if not large enough. */ - virtual uint32_t GetSortedTrackedDeviceIndicesOfClass( ETrackedDeviceClass eTrackedDeviceClass, VR_ARRAY_COUNT(unTrackedDeviceIndexArrayCount) vr::TrackedDeviceIndex_t *punTrackedDeviceIndexArray, uint32_t unTrackedDeviceIndexArrayCount, vr::TrackedDeviceIndex_t unRelativeToTrackedDeviceIndex = k_unTrackedDeviceIndex_Hmd ) = 0; + virtual uint32_t GetSortedTrackedDeviceIndicesOfClass(ETrackedDeviceClass eTrackedDeviceClass, VR_ARRAY_COUNT(unTrackedDeviceIndexArrayCount) vr::TrackedDeviceIndex_t *punTrackedDeviceIndexArray, uint32_t unTrackedDeviceIndexArrayCount, vr::TrackedDeviceIndex_t unRelativeToTrackedDeviceIndex = k_unTrackedDeviceIndex_Hmd) = 0; /** Returns the level of activity on the device. */ - virtual EDeviceActivityLevel GetTrackedDeviceActivityLevel( vr::TrackedDeviceIndex_t unDeviceId ) = 0; + virtual EDeviceActivityLevel GetTrackedDeviceActivityLevel(vr::TrackedDeviceIndex_t unDeviceId) = 0; /** Convenience utility to apply the specified transform to the specified pose. * This properly transforms all pose components, including velocity and angular velocity */ - virtual void ApplyTransform( TrackedDevicePose_t *pOutputPose, const TrackedDevicePose_t *pTrackedDevicePose, const HmdMatrix34_t *pTransform ) = 0; + virtual void ApplyTransform(TrackedDevicePose_t *pOutputPose, const TrackedDevicePose_t *pTrackedDevicePose, const HmdMatrix34_t *pTransform) = 0; /** Returns the device index associated with a specific role, for example the left hand or the right hand. */ - virtual vr::TrackedDeviceIndex_t GetTrackedDeviceIndexForControllerRole( vr::ETrackedControllerRole unDeviceType ) = 0; + virtual vr::TrackedDeviceIndex_t GetTrackedDeviceIndexForControllerRole(vr::ETrackedControllerRole unDeviceType) = 0; /** Returns the controller type associated with a device index. */ - virtual vr::ETrackedControllerRole GetControllerRoleForTrackedDeviceIndex( vr::TrackedDeviceIndex_t unDeviceIndex ) = 0; + virtual vr::ETrackedControllerRole GetControllerRoleForTrackedDeviceIndex(vr::TrackedDeviceIndex_t unDeviceIndex) = 0; // ------------------------------------ // Property methods @@ -1397,34 +1366,34 @@ public: * To determine which devices exist on the system, just loop from 0 to k_unMaxTrackedDeviceCount and check * the device class. Every device with something other than TrackedDevice_Invalid is associated with an * actual tracked device. */ - virtual ETrackedDeviceClass GetTrackedDeviceClass( vr::TrackedDeviceIndex_t unDeviceIndex ) = 0; + virtual ETrackedDeviceClass GetTrackedDeviceClass(vr::TrackedDeviceIndex_t unDeviceIndex) = 0; /** Returns true if there is a device connected in this slot. */ - virtual bool IsTrackedDeviceConnected( vr::TrackedDeviceIndex_t unDeviceIndex ) = 0; + virtual bool IsTrackedDeviceConnected(vr::TrackedDeviceIndex_t unDeviceIndex) = 0; /** Returns a bool property. If the device index is not valid or the property is not a bool type this function will return false. */ - virtual bool GetBoolTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + virtual bool GetBoolTrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L) = 0; /** Returns a float property. If the device index is not valid or the property is not a float type this function will return 0. */ - virtual float GetFloatTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + virtual float GetFloatTrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L) = 0; /** Returns an int property. If the device index is not valid or the property is not a int type this function will return 0. */ - virtual int32_t GetInt32TrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + virtual int32_t GetInt32TrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L) = 0; /** Returns a uint64 property. If the device index is not valid or the property is not a uint64 type this function will return 0. */ - virtual uint64_t GetUint64TrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + virtual uint64_t GetUint64TrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L) = 0; /** Returns a matrix property. If the device index is not valid or the property is not a matrix type, this function will return identity. */ - virtual HmdMatrix34_t GetMatrix34TrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + virtual HmdMatrix34_t GetMatrix34TrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L) = 0; /** Returns a string property. If the device index is not valid or the property is not a string type this function will * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */ - virtual uint32_t GetStringTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L ) = 0; + virtual uint32_t GetStringTrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L) = 0; /** returns a string that corresponds with the specified property error. The string will be the name * of the error enum value for all valid error codes */ - virtual const char *GetPropErrorNameFromEnum( ETrackedPropertyError error ) = 0; + virtual const char *GetPropErrorNameFromEnum(ETrackedPropertyError error) = 0; // ------------------------------------ // Event methods @@ -1432,16 +1401,16 @@ public: /** Returns true and fills the event with the next event on the queue if there is one. If there are no events * this method returns false. uncbVREvent should be the size in bytes of the VREvent_t struct */ - virtual bool PollNextEvent( VREvent_t *pEvent, uint32_t uncbVREvent ) = 0; + virtual bool PollNextEvent(VREvent_t *pEvent, uint32_t uncbVREvent) = 0; /** Returns true and fills the event with the next event on the queue if there is one. If there are no events * this method returns false. Fills in the pose of the associated tracked device in the provided pose struct. * This pose will always be older than the call to this function and should not be used to render the device. uncbVREvent should be the size in bytes of the VREvent_t struct */ - virtual bool PollNextEventWithPose( ETrackingUniverseOrigin eOrigin, VREvent_t *pEvent, uint32_t uncbVREvent, vr::TrackedDevicePose_t *pTrackedDevicePose ) = 0; + virtual bool PollNextEventWithPose(ETrackingUniverseOrigin eOrigin, VREvent_t *pEvent, uint32_t uncbVREvent, vr::TrackedDevicePose_t *pTrackedDevicePose) = 0; /** returns the name of an EVREvent enum value */ - virtual const char *GetEventTypeNameFromEnum( EVREventType eType ) = 0; + virtual const char *GetEventTypeNameFromEnum(EVREventType eType) = 0; // ------------------------------------ // Rendering helper methods @@ -1455,7 +1424,7 @@ public: * Setting the bInverse argument to true will produce the visible area mesh that is commonly used in place of full-screen quads. The visible area mesh covers all of the pixels the hidden area mesh does not cover. * Setting the bLineLoop argument will return a line loop of vertices in HiddenAreaMesh_t->pVertexData with HiddenAreaMesh_t->unTriangleCount set to the number of vertices. */ - virtual HiddenAreaMesh_t GetHiddenAreaMesh( EVREye eEye, EHiddenAreaMeshType type = k_eHiddenAreaMesh_Standard ) = 0; + virtual HiddenAreaMesh_t GetHiddenAreaMesh(EVREye eEye, EHiddenAreaMeshType type = k_eHiddenAreaMesh_Standard) = 0; // ------------------------------------ // Controller methods @@ -1463,22 +1432,22 @@ public: /** Fills the supplied struct with the current state of the controller. Returns false if the controller index * is invalid. */ - virtual bool GetControllerState( vr::TrackedDeviceIndex_t unControllerDeviceIndex, vr::VRControllerState_t *pControllerState, uint32_t unControllerStateSize ) = 0; + virtual bool GetControllerState(vr::TrackedDeviceIndex_t unControllerDeviceIndex, vr::VRControllerState_t *pControllerState, uint32_t unControllerStateSize) = 0; /** fills the supplied struct with the current state of the controller and the provided pose with the pose of * the controller when the controller state was updated most recently. Use this form if you need a precise controller * pose as input to your application when the user presses or releases a button. */ - virtual bool GetControllerStateWithPose( ETrackingUniverseOrigin eOrigin, vr::TrackedDeviceIndex_t unControllerDeviceIndex, vr::VRControllerState_t *pControllerState, uint32_t unControllerStateSize, TrackedDevicePose_t *pTrackedDevicePose ) = 0; + virtual bool GetControllerStateWithPose(ETrackingUniverseOrigin eOrigin, vr::TrackedDeviceIndex_t unControllerDeviceIndex, vr::VRControllerState_t *pControllerState, uint32_t unControllerStateSize, TrackedDevicePose_t *pTrackedDevicePose) = 0; /** Trigger a single haptic pulse on a controller. After this call the application may not trigger another haptic pulse on this controller * and axis combination for 5ms. */ - virtual void TriggerHapticPulse( vr::TrackedDeviceIndex_t unControllerDeviceIndex, uint32_t unAxisId, unsigned short usDurationMicroSec ) = 0; + virtual void TriggerHapticPulse(vr::TrackedDeviceIndex_t unControllerDeviceIndex, uint32_t unAxisId, unsigned short usDurationMicroSec) = 0; /** returns the name of an EVRButtonId enum value */ - virtual const char *GetButtonIdNameFromEnum( EVRButtonId eButtonId ) = 0; + virtual const char *GetButtonIdNameFromEnum(EVRButtonId eButtonId) = 0; /** returns the name of an EVRControllerAxisType enum value */ - virtual const char *GetControllerAxisTypeNameFromEnum( EVRControllerAxisType eAxisType ) = 0; + virtual const char *GetControllerAxisTypeNameFromEnum(EVRControllerAxisType eAxisType) = 0; /** Tells OpenVR that this process wants exclusive access to controller button states and button events. Other apps will be notified that * they have lost input focus with a VREvent_InputFocusCaptured event. Returns false if input focus could not be captured for @@ -1499,18 +1468,18 @@ public: /** Sends a request to the driver for the specified device and returns the response. The maximum response size is 32k, * but this method can be called with a smaller buffer. If the response exceeds the size of the buffer, it is truncated. * The size of the response including its terminating null is returned. */ - virtual uint32_t DriverDebugRequest( vr::TrackedDeviceIndex_t unDeviceIndex, const char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize ) = 0; + virtual uint32_t DriverDebugRequest(vr::TrackedDeviceIndex_t unDeviceIndex, const char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize) = 0; // ------------------------------------ // Firmware methods // ------------------------------------ - + /** Performs the actual firmware update if applicable. * The following events will be sent, if VRFirmwareError_None was returned: VREvent_FirmwareUpdateStarted, VREvent_FirmwareUpdateFinished * Use the properties Prop_Firmware_UpdateAvailable_Bool, Prop_Firmware_ManualUpdate_Bool, and Prop_Firmware_ManualUpdateURL_String * to figure our whether a firmware update is available, and to figure out whether its a manual update * Prop_Firmware_ManualUpdateURL_String should point to an URL describing the manual update process */ - virtual vr::EVRFirmwareError PerformFirmwareUpdate( vr::TrackedDeviceIndex_t unDeviceIndex ) = 0; + virtual vr::EVRFirmwareError PerformFirmwareUpdate(vr::TrackedDeviceIndex_t unDeviceIndex) = 0; // ------------------------------------ // Application life cycle methods @@ -1524,195 +1493,191 @@ public: * halts the timeout and dismisses the dashboard (if it was up). Applications should be sure to actually * prompt the user to save and then exit afterward, otherwise the user will be left in a confusing state. */ virtual void AcknowledgeQuit_UserPrompt() = 0; - }; -static const char * const IVRSystem_Version = "IVRSystem_017"; - -} +static const char *const IVRSystem_Version = "IVRSystem_017"; +} // namespace vr // ivrapplications.h namespace vr { +/** Used for all errors reported by the IVRApplications interface */ +enum EVRApplicationError +{ + VRApplicationError_None = 0, - /** Used for all errors reported by the IVRApplications interface */ - enum EVRApplicationError - { - VRApplicationError_None = 0, + VRApplicationError_AppKeyAlreadyExists = 100, // Only one application can use any given key + VRApplicationError_NoManifest = 101, // the running application does not have a manifest + VRApplicationError_NoApplication = 102, // No application is running + VRApplicationError_InvalidIndex = 103, + VRApplicationError_UnknownApplication = 104, // the application could not be found + VRApplicationError_IPCFailed = 105, // An IPC failure caused the request to fail + VRApplicationError_ApplicationAlreadyRunning = 106, + VRApplicationError_InvalidManifest = 107, + VRApplicationError_InvalidApplication = 108, + VRApplicationError_LaunchFailed = 109, // the process didn't start + VRApplicationError_ApplicationAlreadyStarting = 110, // the system was already starting the same application + VRApplicationError_LaunchInProgress = 111, // The system was already starting a different application + VRApplicationError_OldApplicationQuitting = 112, + VRApplicationError_TransitionAborted = 113, + VRApplicationError_IsTemplate = 114, // error when you try to call LaunchApplication() on a template type app (use LaunchTemplateApplication) + VRApplicationError_SteamVRIsExiting = 115, - VRApplicationError_AppKeyAlreadyExists = 100, // Only one application can use any given key - VRApplicationError_NoManifest = 101, // the running application does not have a manifest - VRApplicationError_NoApplication = 102, // No application is running - VRApplicationError_InvalidIndex = 103, - VRApplicationError_UnknownApplication = 104, // the application could not be found - VRApplicationError_IPCFailed = 105, // An IPC failure caused the request to fail - VRApplicationError_ApplicationAlreadyRunning = 106, - VRApplicationError_InvalidManifest = 107, - VRApplicationError_InvalidApplication = 108, - VRApplicationError_LaunchFailed = 109, // the process didn't start - VRApplicationError_ApplicationAlreadyStarting = 110, // the system was already starting the same application - VRApplicationError_LaunchInProgress = 111, // The system was already starting a different application - VRApplicationError_OldApplicationQuitting = 112, - VRApplicationError_TransitionAborted = 113, - VRApplicationError_IsTemplate = 114, // error when you try to call LaunchApplication() on a template type app (use LaunchTemplateApplication) - VRApplicationError_SteamVRIsExiting = 115, + VRApplicationError_BufferTooSmall = 200, // The provided buffer was too small to fit the requested data + VRApplicationError_PropertyNotSet = 201, // The requested property was not set + VRApplicationError_UnknownProperty = 202, + VRApplicationError_InvalidParameter = 203, +}; - VRApplicationError_BufferTooSmall = 200, // The provided buffer was too small to fit the requested data - VRApplicationError_PropertyNotSet = 201, // The requested property was not set - VRApplicationError_UnknownProperty = 202, - VRApplicationError_InvalidParameter = 203, - }; +/** The maximum length of an application key */ +static const uint32_t k_unMaxApplicationKeyLength = 128; - /** The maximum length of an application key */ - static const uint32_t k_unMaxApplicationKeyLength = 128; +/** these are the properties available on applications. */ +enum EVRApplicationProperty +{ + VRApplicationProperty_Name_String = 0, - /** these are the properties available on applications. */ - enum EVRApplicationProperty - { - VRApplicationProperty_Name_String = 0, + VRApplicationProperty_LaunchType_String = 11, + VRApplicationProperty_WorkingDirectory_String = 12, + VRApplicationProperty_BinaryPath_String = 13, + VRApplicationProperty_Arguments_String = 14, + VRApplicationProperty_URL_String = 15, - VRApplicationProperty_LaunchType_String = 11, - VRApplicationProperty_WorkingDirectory_String = 12, - VRApplicationProperty_BinaryPath_String = 13, - VRApplicationProperty_Arguments_String = 14, - VRApplicationProperty_URL_String = 15, + VRApplicationProperty_Description_String = 50, + VRApplicationProperty_NewsURL_String = 51, + VRApplicationProperty_ImagePath_String = 52, + VRApplicationProperty_Source_String = 53, - VRApplicationProperty_Description_String = 50, - VRApplicationProperty_NewsURL_String = 51, - VRApplicationProperty_ImagePath_String = 52, - VRApplicationProperty_Source_String = 53, + VRApplicationProperty_IsDashboardOverlay_Bool = 60, + VRApplicationProperty_IsTemplate_Bool = 61, + VRApplicationProperty_IsInstanced_Bool = 62, + VRApplicationProperty_IsInternal_Bool = 63, + VRApplicationProperty_WantsCompositorPauseInStandby_Bool = 64, - VRApplicationProperty_IsDashboardOverlay_Bool = 60, - VRApplicationProperty_IsTemplate_Bool = 61, - VRApplicationProperty_IsInstanced_Bool = 62, - VRApplicationProperty_IsInternal_Bool = 63, - VRApplicationProperty_WantsCompositorPauseInStandby_Bool = 64, + VRApplicationProperty_LastLaunchTime_Uint64 = 70, +}; - VRApplicationProperty_LastLaunchTime_Uint64 = 70, - }; +/** These are states the scene application startup process will go through. */ +enum EVRApplicationTransitionState +{ + VRApplicationTransition_None = 0, - /** These are states the scene application startup process will go through. */ - enum EVRApplicationTransitionState - { - VRApplicationTransition_None = 0, + VRApplicationTransition_OldAppQuitSent = 10, + VRApplicationTransition_WaitingForExternalLaunch = 11, - VRApplicationTransition_OldAppQuitSent = 10, - VRApplicationTransition_WaitingForExternalLaunch = 11, - - VRApplicationTransition_NewAppLaunched = 20, - }; + VRApplicationTransition_NewAppLaunched = 20, +}; - struct AppOverrideKeys_t - { - const char *pchKey; - const char *pchValue; - }; +struct AppOverrideKeys_t +{ + const char *pchKey; + const char *pchValue; +}; - /** Currently recognized mime types */ - static const char * const k_pch_MimeType_HomeApp = "vr/home"; - static const char * const k_pch_MimeType_GameTheater = "vr/game_theater"; +/** Currently recognized mime types */ +static const char *const k_pch_MimeType_HomeApp = "vr/home"; +static const char *const k_pch_MimeType_GameTheater = "vr/game_theater"; - class IVRApplications - { - public: +class IVRApplications +{ +public: + // --------------- Application management --------------- // - // --------------- Application management --------------- // - - /** Adds an application manifest to the list to load when building the list of installed applications. + /** Adds an application manifest to the list to load when building the list of installed applications. * Temporary manifests are not automatically loaded */ - virtual EVRApplicationError AddApplicationManifest( const char *pchApplicationManifestFullPath, bool bTemporary = false ) = 0; + virtual EVRApplicationError AddApplicationManifest(const char *pchApplicationManifestFullPath, bool bTemporary = false) = 0; - /** Removes an application manifest from the list to load when building the list of installed applications. */ - virtual EVRApplicationError RemoveApplicationManifest( const char *pchApplicationManifestFullPath ) = 0; + /** Removes an application manifest from the list to load when building the list of installed applications. */ + virtual EVRApplicationError RemoveApplicationManifest(const char *pchApplicationManifestFullPath) = 0; - /** Returns true if an application is installed */ - virtual bool IsApplicationInstalled( const char *pchAppKey ) = 0; + /** Returns true if an application is installed */ + virtual bool IsApplicationInstalled(const char *pchAppKey) = 0; - /** Returns the number of applications available in the list */ - virtual uint32_t GetApplicationCount() = 0; + /** Returns the number of applications available in the list */ + virtual uint32_t GetApplicationCount() = 0; - /** Returns the key of the specified application. The index is at least 0 and is less than the return + /** Returns the key of the specified application. The index is at least 0 and is less than the return * value of GetApplicationCount(). The buffer should be at least k_unMaxApplicationKeyLength in order to * fit the key. */ - virtual EVRApplicationError GetApplicationKeyByIndex( uint32_t unApplicationIndex, VR_OUT_STRING() char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0; + virtual EVRApplicationError GetApplicationKeyByIndex(uint32_t unApplicationIndex, VR_OUT_STRING() char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen) = 0; - /** Returns the key of the application for the specified Process Id. The buffer should be at least + /** Returns the key of the application for the specified Process Id. The buffer should be at least * k_unMaxApplicationKeyLength in order to fit the key. */ - virtual EVRApplicationError GetApplicationKeyByProcessId( uint32_t unProcessId, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0; + virtual EVRApplicationError GetApplicationKeyByProcessId(uint32_t unProcessId, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen) = 0; - /** Launches the application. The existing scene application will exit and then the new application will start. + /** Launches the application. The existing scene application will exit and then the new application will start. * This call is not valid for dashboard overlay applications. */ - virtual EVRApplicationError LaunchApplication( const char *pchAppKey ) = 0; + virtual EVRApplicationError LaunchApplication(const char *pchAppKey) = 0; - /** Launches an instance of an application of type template, with its app key being pchNewAppKey (which must be unique) and optionally override sections + /** Launches an instance of an application of type template, with its app key being pchNewAppKey (which must be unique) and optionally override sections * from the manifest file via AppOverrideKeys_t */ - virtual EVRApplicationError LaunchTemplateApplication( const char *pchTemplateAppKey, const char *pchNewAppKey, VR_ARRAY_COUNT( unKeys ) const AppOverrideKeys_t *pKeys, uint32_t unKeys ) = 0; + virtual EVRApplicationError LaunchTemplateApplication(const char *pchTemplateAppKey, const char *pchNewAppKey, VR_ARRAY_COUNT(unKeys) const AppOverrideKeys_t *pKeys, uint32_t unKeys) = 0; - /** launches the application currently associated with this mime type and passes it the option args, typically the filename or object name of the item being launched */ - virtual vr::EVRApplicationError LaunchApplicationFromMimeType( const char *pchMimeType, const char *pchArgs ) = 0; + /** launches the application currently associated with this mime type and passes it the option args, typically the filename or object name of the item being launched */ + virtual vr::EVRApplicationError LaunchApplicationFromMimeType(const char *pchMimeType, const char *pchArgs) = 0; - /** Launches the dashboard overlay application if it is not already running. This call is only valid for + /** Launches the dashboard overlay application if it is not already running. This call is only valid for * dashboard overlay applications. */ - virtual EVRApplicationError LaunchDashboardOverlay( const char *pchAppKey ) = 0; + virtual EVRApplicationError LaunchDashboardOverlay(const char *pchAppKey) = 0; - /** Cancel a pending launch for an application */ - virtual bool CancelApplicationLaunch( const char *pchAppKey ) = 0; + /** Cancel a pending launch for an application */ + virtual bool CancelApplicationLaunch(const char *pchAppKey) = 0; - /** Identifies a running application. OpenVR can't always tell which process started in response + /** Identifies a running application. OpenVR can't always tell which process started in response * to a URL. This function allows a URL handler (or the process itself) to identify the app key * for the now running application. Passing a process ID of 0 identifies the calling process. * The application must be one that's known to the system via a call to AddApplicationManifest. */ - virtual EVRApplicationError IdentifyApplication( uint32_t unProcessId, const char *pchAppKey ) = 0; + virtual EVRApplicationError IdentifyApplication(uint32_t unProcessId, const char *pchAppKey) = 0; - /** Returns the process ID for an application. Return 0 if the application was not found or is not running. */ - virtual uint32_t GetApplicationProcessId( const char *pchAppKey ) = 0; + /** Returns the process ID for an application. Return 0 if the application was not found or is not running. */ + virtual uint32_t GetApplicationProcessId(const char *pchAppKey) = 0; - /** Returns a string for an applications error */ - virtual const char *GetApplicationsErrorNameFromEnum( EVRApplicationError error ) = 0; + /** Returns a string for an applications error */ + virtual const char *GetApplicationsErrorNameFromEnum(EVRApplicationError error) = 0; - // --------------- Application properties --------------- // + // --------------- Application properties --------------- // - /** Returns a value for an application property. The required buffer size to fit this value will be returned. */ - virtual uint32_t GetApplicationPropertyString( const char *pchAppKey, EVRApplicationProperty eProperty, VR_OUT_STRING() char *pchPropertyValueBuffer, uint32_t unPropertyValueBufferLen, EVRApplicationError *peError = nullptr ) = 0; + /** Returns a value for an application property. The required buffer size to fit this value will be returned. */ + virtual uint32_t GetApplicationPropertyString(const char *pchAppKey, EVRApplicationProperty eProperty, VR_OUT_STRING() char *pchPropertyValueBuffer, uint32_t unPropertyValueBufferLen, EVRApplicationError *peError = nullptr) = 0; - /** Returns a bool value for an application property. Returns false in all error cases. */ - virtual bool GetApplicationPropertyBool( const char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError = nullptr ) = 0; + /** Returns a bool value for an application property. Returns false in all error cases. */ + virtual bool GetApplicationPropertyBool(const char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError = nullptr) = 0; - /** Returns a uint64 value for an application property. Returns 0 in all error cases. */ - virtual uint64_t GetApplicationPropertyUint64( const char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError = nullptr ) = 0; + /** Returns a uint64 value for an application property. Returns 0 in all error cases. */ + virtual uint64_t GetApplicationPropertyUint64(const char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError = nullptr) = 0; - /** Sets the application auto-launch flag. This is only valid for applications which return true for VRApplicationProperty_IsDashboardOverlay_Bool. */ - virtual EVRApplicationError SetApplicationAutoLaunch( const char *pchAppKey, bool bAutoLaunch ) = 0; + /** Sets the application auto-launch flag. This is only valid for applications which return true for VRApplicationProperty_IsDashboardOverlay_Bool. */ + virtual EVRApplicationError SetApplicationAutoLaunch(const char *pchAppKey, bool bAutoLaunch) = 0; - /** Gets the application auto-launch flag. This is only valid for applications which return true for VRApplicationProperty_IsDashboardOverlay_Bool. */ - virtual bool GetApplicationAutoLaunch( const char *pchAppKey ) = 0; + /** Gets the application auto-launch flag. This is only valid for applications which return true for VRApplicationProperty_IsDashboardOverlay_Bool. */ + virtual bool GetApplicationAutoLaunch(const char *pchAppKey) = 0; - /** Adds this mime-type to the list of supported mime types for this application*/ - virtual EVRApplicationError SetDefaultApplicationForMimeType( const char *pchAppKey, const char *pchMimeType ) = 0; + /** Adds this mime-type to the list of supported mime types for this application*/ + virtual EVRApplicationError SetDefaultApplicationForMimeType(const char *pchAppKey, const char *pchMimeType) = 0; - /** return the app key that will open this mime type */ - virtual bool GetDefaultApplicationForMimeType( const char *pchMimeType, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0; + /** return the app key that will open this mime type */ + virtual bool GetDefaultApplicationForMimeType(const char *pchMimeType, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen) = 0; - /** Get the list of supported mime types for this application, comma-delimited */ - virtual bool GetApplicationSupportedMimeTypes( const char *pchAppKey, char *pchMimeTypesBuffer, uint32_t unMimeTypesBuffer ) = 0; + /** Get the list of supported mime types for this application, comma-delimited */ + virtual bool GetApplicationSupportedMimeTypes(const char *pchAppKey, char *pchMimeTypesBuffer, uint32_t unMimeTypesBuffer) = 0; - /** Get the list of app-keys that support this mime type, comma-delimited, the return value is number of bytes you need to return the full string */ - virtual uint32_t GetApplicationsThatSupportMimeType( const char *pchMimeType, char *pchAppKeysThatSupportBuffer, uint32_t unAppKeysThatSupportBuffer ) = 0; + /** Get the list of app-keys that support this mime type, comma-delimited, the return value is number of bytes you need to return the full string */ + virtual uint32_t GetApplicationsThatSupportMimeType(const char *pchMimeType, char *pchAppKeysThatSupportBuffer, uint32_t unAppKeysThatSupportBuffer) = 0; - /** Get the args list from an app launch that had the process already running, you call this when you get a VREvent_ApplicationMimeTypeLoad */ - virtual uint32_t GetApplicationLaunchArguments( uint32_t unHandle, char *pchArgs, uint32_t unArgs ) = 0; + /** Get the args list from an app launch that had the process already running, you call this when you get a VREvent_ApplicationMimeTypeLoad */ + virtual uint32_t GetApplicationLaunchArguments(uint32_t unHandle, char *pchArgs, uint32_t unArgs) = 0; - // --------------- Transition methods --------------- // + // --------------- Transition methods --------------- // - /** Returns the app key for the application that is starting up */ - virtual EVRApplicationError GetStartingApplication( char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0; + /** Returns the app key for the application that is starting up */ + virtual EVRApplicationError GetStartingApplication(char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen) = 0; - /** Returns the application transition state */ - virtual EVRApplicationTransitionState GetTransitionState() = 0; + /** Returns the application transition state */ + virtual EVRApplicationTransitionState GetTransitionState() = 0; - /** Returns errors that would prevent the specified application from launching immediately. Calling this function will + /** Returns errors that would prevent the specified application from launching immediately. Calling this function will * cause the current scene application to quit, so only call it when you are actually about to launch something else. * What the caller should do about these failures depends on the failure: * VRApplicationError_OldApplicationQuitting - An existing application has been told to quit. Wait for a VREvent_ProcessQuit @@ -1721,267 +1686,265 @@ namespace vr * VRApplicationError_LaunchInProgress - A different application is already starting. This is a permanent failure. * VRApplicationError_None - Go ahead and launch. Everything is clear. */ - virtual EVRApplicationError PerformApplicationPrelaunchCheck( const char *pchAppKey ) = 0; + virtual EVRApplicationError PerformApplicationPrelaunchCheck(const char *pchAppKey) = 0; - /** Returns a string for an application transition state */ - virtual const char *GetApplicationsTransitionStateNameFromEnum( EVRApplicationTransitionState state ) = 0; + /** Returns a string for an application transition state */ + virtual const char *GetApplicationsTransitionStateNameFromEnum(EVRApplicationTransitionState state) = 0; - /** Returns true if the outgoing scene app has requested a save prompt before exiting */ - virtual bool IsQuitUserPromptRequested() = 0; + /** Returns true if the outgoing scene app has requested a save prompt before exiting */ + virtual bool IsQuitUserPromptRequested() = 0; - /** Starts a subprocess within the calling application. This + /** Starts a subprocess within the calling application. This * suppresses all application transition UI and automatically identifies the new executable * as part of the same application. On success the calling process should exit immediately. * If working directory is NULL or "" the directory portion of the binary path will be * the working directory. */ - virtual EVRApplicationError LaunchInternalProcess( const char *pchBinaryPath, const char *pchArguments, const char *pchWorkingDirectory ) = 0; + virtual EVRApplicationError LaunchInternalProcess(const char *pchBinaryPath, const char *pchArguments, const char *pchWorkingDirectory) = 0; - /** Returns the current scene process ID according to the application system. A scene process will get scene + /** Returns the current scene process ID according to the application system. A scene process will get scene * focus once it starts rendering, but it will appear here once it calls VR_Init with the Scene application * type. */ - virtual uint32_t GetCurrentSceneProcessId() = 0; - }; + virtual uint32_t GetCurrentSceneProcessId() = 0; +}; - static const char * const IVRApplications_Version = "IVRApplications_006"; +static const char *const IVRApplications_Version = "IVRApplications_006"; -} // namespace vr +} // namespace vr // ivrsettings.h namespace vr { - enum EVRSettingsError - { - VRSettingsError_None = 0, - VRSettingsError_IPCFailed = 1, - VRSettingsError_WriteFailed = 2, - VRSettingsError_ReadFailed = 3, - VRSettingsError_JsonParseFailed = 4, - VRSettingsError_UnsetSettingHasNoDefault = 5, // This will be returned if the setting does not appear in the appropriate default file and has not been set - }; +enum EVRSettingsError +{ + VRSettingsError_None = 0, + VRSettingsError_IPCFailed = 1, + VRSettingsError_WriteFailed = 2, + VRSettingsError_ReadFailed = 3, + VRSettingsError_JsonParseFailed = 4, + VRSettingsError_UnsetSettingHasNoDefault = 5, // This will be returned if the setting does not appear in the appropriate default file and has not been set +}; - // The maximum length of a settings key - static const uint32_t k_unMaxSettingsKeyLength = 128; +// The maximum length of a settings key +static const uint32_t k_unMaxSettingsKeyLength = 128; - class IVRSettings - { - public: - virtual const char *GetSettingsErrorNameFromEnum( EVRSettingsError eError ) = 0; +class IVRSettings +{ +public: + virtual const char *GetSettingsErrorNameFromEnum(EVRSettingsError eError) = 0; - // Returns true if file sync occurred (force or settings dirty) - virtual bool Sync( bool bForce = false, EVRSettingsError *peError = nullptr ) = 0; + // Returns true if file sync occurred (force or settings dirty) + virtual bool Sync(bool bForce = false, EVRSettingsError *peError = nullptr) = 0; - virtual void SetBool( const char *pchSection, const char *pchSettingsKey, bool bValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetInt32( const char *pchSection, const char *pchSettingsKey, int32_t nValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetFloat( const char *pchSection, const char *pchSettingsKey, float flValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetString( const char *pchSection, const char *pchSettingsKey, const char *pchValue, EVRSettingsError *peError = nullptr ) = 0; + virtual void SetBool(const char *pchSection, const char *pchSettingsKey, bool bValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetInt32(const char *pchSection, const char *pchSettingsKey, int32_t nValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetFloat(const char *pchSection, const char *pchSettingsKey, float flValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetString(const char *pchSection, const char *pchSettingsKey, const char *pchValue, EVRSettingsError *peError = nullptr) = 0; - // Users of the system need to provide a proper default in default.vrsettings in the resources/settings/ directory - // of either the runtime or the driver_xxx directory. Otherwise the default will be false, 0, 0.0 or "" - virtual bool GetBool( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual int32_t GetInt32( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual float GetFloat( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual void GetString( const char *pchSection, const char *pchSettingsKey, VR_OUT_STRING() char *pchValue, uint32_t unValueLen, EVRSettingsError *peError = nullptr ) = 0; + // Users of the system need to provide a proper default in default.vrsettings in the resources/settings/ directory + // of either the runtime or the driver_xxx directory. Otherwise the default will be false, 0, 0.0 or "" + virtual bool GetBool(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual int32_t GetInt32(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual float GetFloat(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual void GetString(const char *pchSection, const char *pchSettingsKey, VR_OUT_STRING() char *pchValue, uint32_t unValueLen, EVRSettingsError *peError = nullptr) = 0; - virtual void RemoveSection( const char *pchSection, EVRSettingsError *peError = nullptr ) = 0; - virtual void RemoveKeyInSection( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - }; + virtual void RemoveSection(const char *pchSection, EVRSettingsError *peError = nullptr) = 0; + virtual void RemoveKeyInSection(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; +}; - //----------------------------------------------------------------------------- - static const char * const IVRSettings_Version = "IVRSettings_002"; +//----------------------------------------------------------------------------- +static const char *const IVRSettings_Version = "IVRSettings_002"; - //----------------------------------------------------------------------------- - // steamvr keys - static const char * const k_pch_SteamVR_Section = "steamvr"; - static const char * const k_pch_SteamVR_RequireHmd_String = "requireHmd"; - static const char * const k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; - static const char * const k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; - static const char * const k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; - static const char * const k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; - static const char * const k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; - static const char * const k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; - static const char * const k_pch_SteamVR_SendSystemButtonToAllApps_Bool= "sendSystemButtonToAllApps"; - static const char * const k_pch_SteamVR_LogLevel_Int32 = "loglevel"; - static const char * const k_pch_SteamVR_IPD_Float = "ipd"; - static const char * const k_pch_SteamVR_Background_String = "background"; - static const char * const k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; - static const char * const k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; - static const char * const k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; - static const char * const k_pch_SteamVR_GridColor_String = "gridColor"; - static const char * const k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; - static const char * const k_pch_SteamVR_ShowStage_Bool = "showStage"; - static const char * const k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; - static const char * const k_pch_SteamVR_DirectMode_Bool = "directMode"; - static const char * const k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; - static const char * const k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; - static const char * const k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; - static const char * const k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; - static const char * const k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; - static const char * const k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; - static const char * const k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; - static const char * const k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; - static const char * const k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; - static const char * const k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; - static const char * const k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; - static const char * const k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; - static const char * const k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; - static const char * const k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; - static const char * const k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; - static const char * const k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; - static const char * const k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; - static const char * const k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; - static const char * const k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; - static const char * const k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; - static const char * const k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; - static const char * const k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; - static const char * const k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; - static const char * const k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; +//----------------------------------------------------------------------------- +// steamvr keys +static const char *const k_pch_SteamVR_Section = "steamvr"; +static const char *const k_pch_SteamVR_RequireHmd_String = "requireHmd"; +static const char *const k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; +static const char *const k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; +static const char *const k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; +static const char *const k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; +static const char *const k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; +static const char *const k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; +static const char *const k_pch_SteamVR_SendSystemButtonToAllApps_Bool = "sendSystemButtonToAllApps"; +static const char *const k_pch_SteamVR_LogLevel_Int32 = "loglevel"; +static const char *const k_pch_SteamVR_IPD_Float = "ipd"; +static const char *const k_pch_SteamVR_Background_String = "background"; +static const char *const k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; +static const char *const k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; +static const char *const k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; +static const char *const k_pch_SteamVR_GridColor_String = "gridColor"; +static const char *const k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; +static const char *const k_pch_SteamVR_ShowStage_Bool = "showStage"; +static const char *const k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; +static const char *const k_pch_SteamVR_DirectMode_Bool = "directMode"; +static const char *const k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; +static const char *const k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; +static const char *const k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; +static const char *const k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; +static const char *const k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; +static const char *const k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; +static const char *const k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; +static const char *const k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; +static const char *const k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; +static const char *const k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; +static const char *const k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; +static const char *const k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; +static const char *const k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; +static const char *const k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; +static const char *const k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; +static const char *const k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; +static const char *const k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; +static const char *const k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; +static const char *const k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; +static const char *const k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; +static const char *const k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; +static const char *const k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; +static const char *const k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; +static const char *const k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; - //----------------------------------------------------------------------------- - // lighthouse keys - static const char * const k_pch_Lighthouse_Section = "driver_lighthouse"; - static const char * const k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; - static const char * const k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; - static const char * const k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; - static const char * const k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; - static const char * const k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; +//----------------------------------------------------------------------------- +// lighthouse keys +static const char *const k_pch_Lighthouse_Section = "driver_lighthouse"; +static const char *const k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; +static const char *const k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; +static const char *const k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; +static const char *const k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; +static const char *const k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; - //----------------------------------------------------------------------------- - // null keys - static const char * const k_pch_Null_Section = "driver_null"; - static const char * const k_pch_Null_SerialNumber_String = "serialNumber"; - static const char * const k_pch_Null_ModelNumber_String = "modelNumber"; - static const char * const k_pch_Null_WindowX_Int32 = "windowX"; - static const char * const k_pch_Null_WindowY_Int32 = "windowY"; - static const char * const k_pch_Null_WindowWidth_Int32 = "windowWidth"; - static const char * const k_pch_Null_WindowHeight_Int32 = "windowHeight"; - static const char * const k_pch_Null_RenderWidth_Int32 = "renderWidth"; - static const char * const k_pch_Null_RenderHeight_Int32 = "renderHeight"; - static const char * const k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; - static const char * const k_pch_Null_DisplayFrequency_Float = "displayFrequency"; +//----------------------------------------------------------------------------- +// null keys +static const char *const k_pch_Null_Section = "driver_null"; +static const char *const k_pch_Null_SerialNumber_String = "serialNumber"; +static const char *const k_pch_Null_ModelNumber_String = "modelNumber"; +static const char *const k_pch_Null_WindowX_Int32 = "windowX"; +static const char *const k_pch_Null_WindowY_Int32 = "windowY"; +static const char *const k_pch_Null_WindowWidth_Int32 = "windowWidth"; +static const char *const k_pch_Null_WindowHeight_Int32 = "windowHeight"; +static const char *const k_pch_Null_RenderWidth_Int32 = "renderWidth"; +static const char *const k_pch_Null_RenderHeight_Int32 = "renderHeight"; +static const char *const k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; +static const char *const k_pch_Null_DisplayFrequency_Float = "displayFrequency"; - //----------------------------------------------------------------------------- - // user interface keys - static const char * const k_pch_UserInterface_Section = "userinterface"; - static const char * const k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; - static const char * const k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; - static const char * const k_pch_UserInterface_Screenshots_Bool = "screenshots"; - static const char * const k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; +//----------------------------------------------------------------------------- +// user interface keys +static const char *const k_pch_UserInterface_Section = "userinterface"; +static const char *const k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; +static const char *const k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; +static const char *const k_pch_UserInterface_Screenshots_Bool = "screenshots"; +static const char *const k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; - //----------------------------------------------------------------------------- - // notification keys - static const char * const k_pch_Notifications_Section = "notifications"; - static const char * const k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; +//----------------------------------------------------------------------------- +// notification keys +static const char *const k_pch_Notifications_Section = "notifications"; +static const char *const k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; - //----------------------------------------------------------------------------- - // keyboard keys - static const char * const k_pch_Keyboard_Section = "keyboard"; - static const char * const k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; - static const char * const k_pch_Keyboard_ScaleX = "ScaleX"; - static const char * const k_pch_Keyboard_ScaleY = "ScaleY"; - static const char * const k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; - static const char * const k_pch_Keyboard_OffsetRightX = "OffsetRightX"; - static const char * const k_pch_Keyboard_OffsetY = "OffsetY"; - static const char * const k_pch_Keyboard_Smoothing = "Smoothing"; +//----------------------------------------------------------------------------- +// keyboard keys +static const char *const k_pch_Keyboard_Section = "keyboard"; +static const char *const k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; +static const char *const k_pch_Keyboard_ScaleX = "ScaleX"; +static const char *const k_pch_Keyboard_ScaleY = "ScaleY"; +static const char *const k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; +static const char *const k_pch_Keyboard_OffsetRightX = "OffsetRightX"; +static const char *const k_pch_Keyboard_OffsetY = "OffsetY"; +static const char *const k_pch_Keyboard_Smoothing = "Smoothing"; - //----------------------------------------------------------------------------- - // perf keys - static const char * const k_pch_Perf_Section = "perfcheck"; - static const char * const k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; - static const char * const k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; - static const char * const k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; - static const char * const k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; - static const char * const k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; - static const char * const k_pch_Perf_TestData_Float = "perfTestData"; - static const char * const k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; +//----------------------------------------------------------------------------- +// perf keys +static const char *const k_pch_Perf_Section = "perfcheck"; +static const char *const k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; +static const char *const k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; +static const char *const k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; +static const char *const k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; +static const char *const k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; +static const char *const k_pch_Perf_TestData_Float = "perfTestData"; +static const char *const k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; - //----------------------------------------------------------------------------- - // collision bounds keys - static const char * const k_pch_CollisionBounds_Section = "collisionBounds"; - static const char * const k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; - static const char * const k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; - static const char * const k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; - static const char * const k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; - static const char * const k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; - static const char * const k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; - static const char * const k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; - static const char * const k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; - static const char * const k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; +//----------------------------------------------------------------------------- +// collision bounds keys +static const char *const k_pch_CollisionBounds_Section = "collisionBounds"; +static const char *const k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; +static const char *const k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; +static const char *const k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; +static const char *const k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; +static const char *const k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; +static const char *const k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; +static const char *const k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; +static const char *const k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; +static const char *const k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; - //----------------------------------------------------------------------------- - // camera keys - static const char * const k_pch_Camera_Section = "camera"; - static const char * const k_pch_Camera_EnableCamera_Bool = "enableCamera"; - static const char * const k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; - static const char * const k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; - static const char * const k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; - static const char * const k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; - static const char * const k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; - static const char * const k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; - static const char * const k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; - static const char * const k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; +//----------------------------------------------------------------------------- +// camera keys +static const char *const k_pch_Camera_Section = "camera"; +static const char *const k_pch_Camera_EnableCamera_Bool = "enableCamera"; +static const char *const k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; +static const char *const k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; +static const char *const k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; +static const char *const k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; +static const char *const k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; +static const char *const k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; +static const char *const k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; +static const char *const k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; - //----------------------------------------------------------------------------- - // audio keys - static const char * const k_pch_audio_Section = "audio"; - static const char * const k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; - static const char * const k_pch_audio_OnRecordDevice_String = "onRecordDevice"; - static const char * const k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; - static const char * const k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; - static const char * const k_pch_audio_OffRecordDevice_String = "offRecordDevice"; - static const char * const k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; +//----------------------------------------------------------------------------- +// audio keys +static const char *const k_pch_audio_Section = "audio"; +static const char *const k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; +static const char *const k_pch_audio_OnRecordDevice_String = "onRecordDevice"; +static const char *const k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; +static const char *const k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; +static const char *const k_pch_audio_OffRecordDevice_String = "offRecordDevice"; +static const char *const k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; - //----------------------------------------------------------------------------- - // power management keys - static const char * const k_pch_Power_Section = "power"; - static const char * const k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; - static const char * const k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; - static const char * const k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; - static const char * const k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; - static const char * const k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; - static const char * const k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; +//----------------------------------------------------------------------------- +// power management keys +static const char *const k_pch_Power_Section = "power"; +static const char *const k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; +static const char *const k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; +static const char *const k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; +static const char *const k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; +static const char *const k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; +static const char *const k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; - //----------------------------------------------------------------------------- - // dashboard keys - static const char * const k_pch_Dashboard_Section = "dashboard"; - static const char * const k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; - static const char * const k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; +//----------------------------------------------------------------------------- +// dashboard keys +static const char *const k_pch_Dashboard_Section = "dashboard"; +static const char *const k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; +static const char *const k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; - //----------------------------------------------------------------------------- - // model skin keys - static const char * const k_pch_modelskin_Section = "modelskins"; +//----------------------------------------------------------------------------- +// model skin keys +static const char *const k_pch_modelskin_Section = "modelskins"; - //----------------------------------------------------------------------------- - // driver keys - These could be checked in any driver_ section - static const char * const k_pch_Driver_Enable_Bool = "enable"; +//----------------------------------------------------------------------------- +// driver keys - These could be checked in any driver_ section +static const char *const k_pch_Driver_Enable_Bool = "enable"; -} // namespace vr +} // namespace vr // ivrchaperone.h namespace vr { - -#pragma pack( push, 8 ) +#pragma pack(push, 8) enum ChaperoneCalibrationState { // OK! - ChaperoneCalibrationState_OK = 1, // Chaperone is fully calibrated and working correctly + ChaperoneCalibrationState_OK = 1, // Chaperone is fully calibrated and working correctly // Warnings ChaperoneCalibrationState_Warning = 100, - ChaperoneCalibrationState_Warning_BaseStationMayHaveMoved = 101, // A base station thinks that it might have moved - ChaperoneCalibrationState_Warning_BaseStationRemoved = 102, // There are less base stations than when calibrated - ChaperoneCalibrationState_Warning_SeatedBoundsInvalid = 103, // Seated bounds haven't been calibrated for the current tracking center + ChaperoneCalibrationState_Warning_BaseStationMayHaveMoved = 101, // A base station thinks that it might have moved + ChaperoneCalibrationState_Warning_BaseStationRemoved = 102, // There are less base stations than when calibrated + ChaperoneCalibrationState_Warning_SeatedBoundsInvalid = 103, // Seated bounds haven't been calibrated for the current tracking center // Errors - ChaperoneCalibrationState_Error = 200, // The UniverseID is invalid - ChaperoneCalibrationState_Error_BaseStationUninitialized = 201, // Tracking center hasn't be calibrated for at least one of the base stations - ChaperoneCalibrationState_Error_BaseStationConflict = 202, // Tracking center is calibrated, but base stations disagree on the tracking space - ChaperoneCalibrationState_Error_PlayAreaInvalid = 203, // Play Area hasn't been calibrated for the current tracking center - ChaperoneCalibrationState_Error_CollisionBoundsInvalid = 204, // Collision Bounds haven't been calibrated for the current tracking center + ChaperoneCalibrationState_Error = 200, // The UniverseID is invalid + ChaperoneCalibrationState_Error_BaseStationUninitialized = 201, // Tracking center hasn't be calibrated for at least one of the base stations + ChaperoneCalibrationState_Error_BaseStationConflict = 202, // Tracking center is calibrated, but base stations disagree on the tracking space + ChaperoneCalibrationState_Error_PlayAreaInvalid = 203, // Play Area hasn't been calibrated for the current tracking center + ChaperoneCalibrationState_Error_CollisionBoundsInvalid = 204, // Collision Bounds haven't been calibrated for the current tracking center }; - /** HIGH LEVEL TRACKING SPACE ASSUMPTIONS: * 0,0,0 is the preferred standing area center. * 0Y is the floor height. @@ -1989,13 +1952,12 @@ enum ChaperoneCalibrationState class IVRChaperone { public: - /** Get the current state of Chaperone calibration. This state can change at any time during a session due to physical base station changes. **/ virtual ChaperoneCalibrationState GetCalibrationState() = 0; /** Returns the width and depth of the Play Area (formerly named Soft Bounds) in X and Z. * Tracking space center (0,0,0) is the center of the Play Area. **/ - virtual bool GetPlayAreaSize( float *pSizeX, float *pSizeZ ) = 0; + virtual bool GetPlayAreaSize(float *pSizeX, float *pSizeZ) = 0; /** Returns the 4 corner positions of the Play Area (formerly named Soft Bounds). * Corners are in counter-clockwise order. @@ -2003,38 +1965,37 @@ public: * It's a rectangle. * 2 sides are parallel to the X axis and 2 sides are parallel to the Z axis. * Height of every corner is 0Y (on the floor). **/ - virtual bool GetPlayAreaRect( HmdQuad_t *rect ) = 0; + virtual bool GetPlayAreaRect(HmdQuad_t *rect) = 0; /** Reload Chaperone data from the .vrchap file on disk. */ - virtual void ReloadInfo( void ) = 0; + virtual void ReloadInfo(void) = 0; /** Optionally give the chaperone system a hit about the color and brightness in the scene **/ - virtual void SetSceneColor( HmdColor_t color ) = 0; + virtual void SetSceneColor(HmdColor_t color) = 0; /** Get the current chaperone bounds draw color and brightness **/ - virtual void GetBoundsColor( HmdColor_t *pOutputColorArray, int nNumOutputColors, float flCollisionBoundsFadeDistance, HmdColor_t *pOutputCameraColor ) = 0; + virtual void GetBoundsColor(HmdColor_t *pOutputColorArray, int nNumOutputColors, float flCollisionBoundsFadeDistance, HmdColor_t *pOutputCameraColor) = 0; /** Determine whether the bounds are showing right now **/ virtual bool AreBoundsVisible() = 0; /** Force the bounds to show, mostly for utilities **/ - virtual void ForceBoundsVisible( bool bForce ) = 0; + virtual void ForceBoundsVisible(bool bForce) = 0; }; -static const char * const IVRChaperone_Version = "IVRChaperone_003"; +static const char *const IVRChaperone_Version = "IVRChaperone_003"; -#pragma pack( pop ) +#pragma pack(pop) -} +} // namespace vr // ivrchaperonesetup.h namespace vr { - enum EChaperoneConfigFile { - EChaperoneConfigFile_Live = 1, // The live chaperone config, used by most applications and games - EChaperoneConfigFile_Temp = 2, // The temporary chaperone config, used to live-preview collision bounds in room setup + EChaperoneConfigFile_Live = 1, // The live chaperone config, used by most applications and games + EChaperoneConfigFile_Temp = 2, // The temporary chaperone config, used to live-preview collision bounds in room setup }; enum EChaperoneImportFlags @@ -2049,9 +2010,8 @@ enum EChaperoneImportFlags class IVRChaperoneSetup { public: - /** Saves the current working copy to disk */ - virtual bool CommitWorkingCopy( EChaperoneConfigFile configFile ) = 0; + virtual bool CommitWorkingCopy(EChaperoneConfigFile configFile) = 0; /** Reverts the working copy to match the live chaperone calibration. * To modify existing data this MUST be do WHILE getting a non-error ChaperoneCalibrationStatus. @@ -2060,7 +2020,7 @@ public: /** Returns the width and depth of the Play Area (formerly named Soft Bounds) in X and Z from the working copy. * Tracking space center (0,0,0) is the center of the Play Area. */ - virtual bool GetWorkingPlayAreaSize( float *pSizeX, float *pSizeZ ) = 0; + virtual bool GetWorkingPlayAreaSize(float *pSizeX, float *pSizeZ) = 0; /** Returns the 4 corner positions of the Play Area (formerly named Soft Bounds) from the working copy. * Corners are in clockwise order. @@ -2068,95 +2028,93 @@ public: * It's a rectangle. * 2 sides are parallel to the X axis and 2 sides are parallel to the Z axis. * Height of every corner is 0Y (on the floor). **/ - virtual bool GetWorkingPlayAreaRect( HmdQuad_t *rect ) = 0; + virtual bool GetWorkingPlayAreaRect(HmdQuad_t *rect) = 0; /** Returns the number of Quads if the buffer points to null. Otherwise it returns Quads * into the buffer up to the max specified from the working copy. */ - virtual bool GetWorkingCollisionBoundsInfo( VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t* punQuadsCount ) = 0; + virtual bool GetWorkingCollisionBoundsInfo(VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount) = 0; /** Returns the number of Quads if the buffer points to null. Otherwise it returns Quads * into the buffer up to the max specified. */ - virtual bool GetLiveCollisionBoundsInfo( VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t* punQuadsCount ) = 0; + virtual bool GetLiveCollisionBoundsInfo(VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount) = 0; /** Returns the preferred seated position from the working copy. */ - virtual bool GetWorkingSeatedZeroPoseToRawTrackingPose( HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose ) = 0; + virtual bool GetWorkingSeatedZeroPoseToRawTrackingPose(HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose) = 0; /** Returns the standing origin from the working copy. */ - virtual bool GetWorkingStandingZeroPoseToRawTrackingPose( HmdMatrix34_t *pmatStandingZeroPoseToRawTrackingPose ) = 0; + virtual bool GetWorkingStandingZeroPoseToRawTrackingPose(HmdMatrix34_t *pmatStandingZeroPoseToRawTrackingPose) = 0; /** Sets the Play Area in the working copy. */ - virtual void SetWorkingPlayAreaSize( float sizeX, float sizeZ ) = 0; + virtual void SetWorkingPlayAreaSize(float sizeX, float sizeZ) = 0; /** Sets the Collision Bounds in the working copy. */ - virtual void SetWorkingCollisionBoundsInfo( VR_ARRAY_COUNT(unQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount ) = 0; + virtual void SetWorkingCollisionBoundsInfo(VR_ARRAY_COUNT(unQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount) = 0; /** Sets the preferred seated position in the working copy. */ - virtual void SetWorkingSeatedZeroPoseToRawTrackingPose( const HmdMatrix34_t *pMatSeatedZeroPoseToRawTrackingPose ) = 0; + virtual void SetWorkingSeatedZeroPoseToRawTrackingPose(const HmdMatrix34_t *pMatSeatedZeroPoseToRawTrackingPose) = 0; /** Sets the preferred standing position in the working copy. */ - virtual void SetWorkingStandingZeroPoseToRawTrackingPose( const HmdMatrix34_t *pMatStandingZeroPoseToRawTrackingPose ) = 0; + virtual void SetWorkingStandingZeroPoseToRawTrackingPose(const HmdMatrix34_t *pMatStandingZeroPoseToRawTrackingPose) = 0; /** Tear everything down and reload it from the file on disk */ - virtual void ReloadFromDisk( EChaperoneConfigFile configFile ) = 0; + virtual void ReloadFromDisk(EChaperoneConfigFile configFile) = 0; /** Returns the preferred seated position. */ - virtual bool GetLiveSeatedZeroPoseToRawTrackingPose( HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose ) = 0; + virtual bool GetLiveSeatedZeroPoseToRawTrackingPose(HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose) = 0; - virtual void SetWorkingCollisionBoundsTagsInfo( VR_ARRAY_COUNT(unTagCount) uint8_t *pTagsBuffer, uint32_t unTagCount ) = 0; - virtual bool GetLiveCollisionBoundsTagsInfo( VR_OUT_ARRAY_COUNT(punTagCount) uint8_t *pTagsBuffer, uint32_t *punTagCount ) = 0; + virtual void SetWorkingCollisionBoundsTagsInfo(VR_ARRAY_COUNT(unTagCount) uint8_t *pTagsBuffer, uint32_t unTagCount) = 0; + virtual bool GetLiveCollisionBoundsTagsInfo(VR_OUT_ARRAY_COUNT(punTagCount) uint8_t *pTagsBuffer, uint32_t *punTagCount) = 0; - virtual bool SetWorkingPhysicalBoundsInfo( VR_ARRAY_COUNT(unQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount ) = 0; - virtual bool GetLivePhysicalBoundsInfo( VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t* punQuadsCount ) = 0; + virtual bool SetWorkingPhysicalBoundsInfo(VR_ARRAY_COUNT(unQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount) = 0; + virtual bool GetLivePhysicalBoundsInfo(VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount) = 0; - virtual bool ExportLiveToBuffer( VR_OUT_STRING() char *pBuffer, uint32_t *pnBufferLength ) = 0; - virtual bool ImportFromBufferToWorking( const char *pBuffer, uint32_t nImportFlags ) = 0; + virtual bool ExportLiveToBuffer(VR_OUT_STRING() char *pBuffer, uint32_t *pnBufferLength) = 0; + virtual bool ImportFromBufferToWorking(const char *pBuffer, uint32_t nImportFlags) = 0; }; -static const char * const IVRChaperoneSetup_Version = "IVRChaperoneSetup_005"; +static const char *const IVRChaperoneSetup_Version = "IVRChaperoneSetup_005"; - -} +} // namespace vr // ivrcompositor.h namespace vr { - -#pragma pack( push, 8 ) +#pragma pack(push, 8) /** Errors that can occur with the VR compositor */ enum EVRCompositorError { - VRCompositorError_None = 0, - VRCompositorError_RequestFailed = 1, - VRCompositorError_IncompatibleVersion = 100, - VRCompositorError_DoNotHaveFocus = 101, - VRCompositorError_InvalidTexture = 102, - VRCompositorError_IsNotSceneApplication = 103, - VRCompositorError_TextureIsOnWrongDevice = 104, + VRCompositorError_None = 0, + VRCompositorError_RequestFailed = 1, + VRCompositorError_IncompatibleVersion = 100, + VRCompositorError_DoNotHaveFocus = 101, + VRCompositorError_InvalidTexture = 102, + VRCompositorError_IsNotSceneApplication = 103, + VRCompositorError_TextureIsOnWrongDevice = 104, VRCompositorError_TextureUsesUnsupportedFormat = 105, VRCompositorError_SharedTexturesNotSupported = 106, - VRCompositorError_IndexOutOfRange = 107, - VRCompositorError_AlreadySubmitted = 108, - VRCompositorError_InvalidBounds = 109, + VRCompositorError_IndexOutOfRange = 107, + VRCompositorError_AlreadySubmitted = 108, + VRCompositorError_InvalidBounds = 109, }; const uint32_t VRCompositor_ReprojectionReason_Cpu = 0x01; const uint32_t VRCompositor_ReprojectionReason_Gpu = 0x02; -const uint32_t VRCompositor_ReprojectionAsync = 0x04; // This flag indicates the async reprojection mode is active, - // but does not indicate if reprojection actually happened or not. - // Use the ReprojectionReason flags above to check if reprojection - // was actually applied (i.e. scene texture was reused). - // NumFramePresents > 1 also indicates the scene texture was reused, - // and also the number of times that it was presented in total. +const uint32_t VRCompositor_ReprojectionAsync = 0x04; // This flag indicates the async reprojection mode is active, + // but does not indicate if reprojection actually happened or not. + // Use the ReprojectionReason flags above to check if reprojection + // was actually applied (i.e. scene texture was reused). + // NumFramePresents > 1 also indicates the scene texture was reused, + // and also the number of times that it was presented in total. /** Provides a single frame's timing information to the app */ struct Compositor_FrameTiming { - uint32_t m_nSize; // Set to sizeof( Compositor_FrameTiming ) + uint32_t m_nSize; // Set to sizeof( Compositor_FrameTiming ) uint32_t m_nFrameIndex; - uint32_t m_nNumFramePresents; // number of times this frame was presented - uint32_t m_nNumMisPresented; // number of times this frame was presented on a vsync other than it was originally predicted to - uint32_t m_nNumDroppedFrames; // number of additional times previous frame was scanned out + uint32_t m_nNumFramePresents; // number of times this frame was presented + uint32_t m_nNumMisPresented; // number of times this frame was presented on a vsync other than it was originally predicted to + uint32_t m_nNumDroppedFrames; // number of additional times previous frame was scanned out uint32_t m_nReprojectionFlags; /** Absolute time reference for comparing frames. This aligns with the vsync that running start is relative to. */ @@ -2166,38 +2124,38 @@ struct Compositor_FrameTiming * The fewer packets of work these are broken up into, the less likely this will happen. * GPU work can be broken up by calling Flush. This can sometimes be useful to get the GPU started * processing that work earlier in the frame. */ - float m_flPreSubmitGpuMs; // time spent rendering the scene (gpu work submitted between WaitGetPoses and second Submit) - float m_flPostSubmitGpuMs; // additional time spent rendering by application (e.g. companion window) - float m_flTotalRenderGpuMs; // time between work submitted immediately after present (ideally vsync) until the end of compositor submitted work - float m_flCompositorRenderGpuMs; // time spend performing distortion correction, rendering chaperone, overlays, etc. - float m_flCompositorRenderCpuMs; // time spent on cpu submitting the above work for this frame - float m_flCompositorIdleCpuMs; // time spent waiting for running start (application could have used this much more time) + float m_flPreSubmitGpuMs; // time spent rendering the scene (gpu work submitted between WaitGetPoses and second Submit) + float m_flPostSubmitGpuMs; // additional time spent rendering by application (e.g. companion window) + float m_flTotalRenderGpuMs; // time between work submitted immediately after present (ideally vsync) until the end of compositor submitted work + float m_flCompositorRenderGpuMs; // time spend performing distortion correction, rendering chaperone, overlays, etc. + float m_flCompositorRenderCpuMs; // time spent on cpu submitting the above work for this frame + float m_flCompositorIdleCpuMs; // time spent waiting for running start (application could have used this much more time) /** Miscellaneous measured intervals. */ - float m_flClientFrameIntervalMs; // time between calls to WaitGetPoses - float m_flPresentCallCpuMs; // time blocked on call to present (usually 0.0, but can go long) - float m_flWaitForPresentCpuMs; // time spent spin-waiting for frame index to change (not near-zero indicates wait object failure) - float m_flSubmitFrameMs; // time spent in IVRCompositor::Submit (not near-zero indicates driver issue) + float m_flClientFrameIntervalMs; // time between calls to WaitGetPoses + float m_flPresentCallCpuMs; // time blocked on call to present (usually 0.0, but can go long) + float m_flWaitForPresentCpuMs; // time spent spin-waiting for frame index to change (not near-zero indicates wait object failure) + float m_flSubmitFrameMs; // time spent in IVRCompositor::Submit (not near-zero indicates driver issue) /** The following are all relative to this frame's SystemTimeInSeconds */ float m_flWaitGetPosesCalledMs; float m_flNewPosesReadyMs; - float m_flNewFrameReadyMs; // second call to IVRCompositor::Submit + float m_flNewFrameReadyMs; // second call to IVRCompositor::Submit float m_flCompositorUpdateStartMs; float m_flCompositorUpdateEndMs; float m_flCompositorRenderStartMs; - vr::TrackedDevicePose_t m_HmdPose; // pose used by app to render this frame + vr::TrackedDevicePose_t m_HmdPose; // pose used by app to render this frame }; /** Cumulative stats for current application. These are not cleared until a new app connects, * but they do stop accumulating once the associated app disconnects. */ struct Compositor_CumulativeStats { - uint32_t m_nPid; // Process id associated with these stats (may no longer be running). - uint32_t m_nNumFramePresents; // total number of times we called present (includes reprojected frames) - uint32_t m_nNumDroppedFrames; // total number of times an old frame was re-scanned out (without reprojection) - uint32_t m_nNumReprojectedFrames; // total number of times a frame was scanned out a second time (with reprojection) + uint32_t m_nPid; // Process id associated with these stats (may no longer be running). + uint32_t m_nNumFramePresents; // total number of times we called present (includes reprojected frames) + uint32_t m_nNumDroppedFrames; // total number of times an old frame was re-scanned out (without reprojection) + uint32_t m_nNumReprojectedFrames; // total number of times a frame was scanned out a second time (with reprojection) /** Values recorded at startup before application has fully faded in the first time. */ uint32_t m_nNumFramePresentsOnStartup; @@ -2220,14 +2178,14 @@ struct Compositor_CumulativeStats uint32_t m_nNumReprojectedFramesTimedOut; }; -#pragma pack( pop ) +#pragma pack(pop) /** Allows the application to interact with the compositor */ class IVRCompositor { public: /** Sets tracking space returned by WaitGetPoses */ - virtual void SetTrackingSpace( ETrackingUniverseOrigin eOrigin ) = 0; + virtual void SetTrackingSpace(ETrackingUniverseOrigin eOrigin) = 0; /** Gets current tracking space returned by WaitGetPoses */ virtual ETrackingUniverseOrigin GetTrackingSpace() = 0; @@ -2240,17 +2198,17 @@ public: * - IsNotSceneApplication (make sure to call VR_Init with VRApplicaiton_Scene) * - DoNotHaveFocus (some other app has taken focus - this will throttle the call to 10hz to reduce the impact on that app) */ - virtual EVRCompositorError WaitGetPoses( VR_ARRAY_COUNT(unRenderPoseArrayCount) TrackedDevicePose_t* pRenderPoseArray, uint32_t unRenderPoseArrayCount, - VR_ARRAY_COUNT(unGamePoseArrayCount) TrackedDevicePose_t* pGamePoseArray, uint32_t unGamePoseArrayCount ) = 0; + virtual EVRCompositorError WaitGetPoses(VR_ARRAY_COUNT(unRenderPoseArrayCount) TrackedDevicePose_t *pRenderPoseArray, uint32_t unRenderPoseArrayCount, + VR_ARRAY_COUNT(unGamePoseArrayCount) TrackedDevicePose_t *pGamePoseArray, uint32_t unGamePoseArrayCount) = 0; /** Get the last set of poses returned by WaitGetPoses. */ - virtual EVRCompositorError GetLastPoses( VR_ARRAY_COUNT( unRenderPoseArrayCount ) TrackedDevicePose_t* pRenderPoseArray, uint32_t unRenderPoseArrayCount, - VR_ARRAY_COUNT( unGamePoseArrayCount ) TrackedDevicePose_t* pGamePoseArray, uint32_t unGamePoseArrayCount ) = 0; + virtual EVRCompositorError GetLastPoses(VR_ARRAY_COUNT(unRenderPoseArrayCount) TrackedDevicePose_t *pRenderPoseArray, uint32_t unRenderPoseArrayCount, + VR_ARRAY_COUNT(unGamePoseArrayCount) TrackedDevicePose_t *pGamePoseArray, uint32_t unGamePoseArrayCount) = 0; /** Interface for accessing last set of poses returned by WaitGetPoses one at a time. * Returns VRCompositorError_IndexOutOfRange if unDeviceIndex not less than k_unMaxTrackedDeviceCount otherwise VRCompositorError_None. * It is okay to pass NULL for either pose if you only want one of the values. */ - virtual EVRCompositorError GetLastPoseForTrackedDeviceIndex( TrackedDeviceIndex_t unDeviceIndex, TrackedDevicePose_t *pOutputPose, TrackedDevicePose_t *pOutputGamePose ) = 0; + virtual EVRCompositorError GetLastPoseForTrackedDeviceIndex(TrackedDeviceIndex_t unDeviceIndex, TrackedDevicePose_t *pOutputPose, TrackedDevicePose_t *pOutputGamePose) = 0; /** Updated scene texture to display. If pBounds is NULL the entire texture will be used. If called from an OpenGL app, consider adding a glFlush after * Submitting both frames to signal the driver to start processing, otherwise it may wait until the command buffer fills up, causing the app to miss frames. @@ -2267,7 +2225,7 @@ public: * - InvalidTexture (usually means bad arguments passed in) * - AlreadySubmitted (app has submitted two left textures or two right textures in a single frame - i.e. before calling WaitGetPoses again) */ - virtual EVRCompositorError Submit( EVREye eEye, const Texture_t *pTexture, const VRTextureBounds_t* pBounds = 0, EVRSubmitFlags nSubmitFlags = Submit_Default ) = 0; + virtual EVRCompositorError Submit(EVREye eEye, const Texture_t *pTexture, const VRTextureBounds_t *pBounds = 0, EVRSubmitFlags nSubmitFlags = Submit_Default) = 0; /** Clears the frame that was sent with the last call to Submit. This will cause the * compositor to show the grid until Submit is called again. */ @@ -2282,29 +2240,29 @@ public: /** Returns true if timing data is filled it. Sets oldest timing info if nFramesAgo is larger than the stored history. * Be sure to set timing.size = sizeof(Compositor_FrameTiming) on struct passed in before calling this function. */ - virtual bool GetFrameTiming( Compositor_FrameTiming *pTiming, uint32_t unFramesAgo = 0 ) = 0; + virtual bool GetFrameTiming(Compositor_FrameTiming *pTiming, uint32_t unFramesAgo = 0) = 0; /** Interface for copying a range of timing data. Frames are returned in ascending order (oldest to newest) with the last being the most recent frame. * Only the first entry's m_nSize needs to be set, as the rest will be inferred from that. Returns total number of entries filled out. */ - virtual uint32_t GetFrameTimings( Compositor_FrameTiming *pTiming, uint32_t nFrames ) = 0; + virtual uint32_t GetFrameTimings(Compositor_FrameTiming *pTiming, uint32_t nFrames) = 0; /** Returns the time in seconds left in the current (as identified by FrameTiming's frameIndex) frame. * Due to "running start", this value may roll over to the next frame before ever reaching 0.0. */ virtual float GetFrameTimeRemaining() = 0; /** Fills out stats accumulated for the last connected application. Pass in sizeof( Compositor_CumulativeStats ) as second parameter. */ - virtual void GetCumulativeStats( Compositor_CumulativeStats *pStats, uint32_t nStatsSizeInBytes ) = 0; + virtual void GetCumulativeStats(Compositor_CumulativeStats *pStats, uint32_t nStatsSizeInBytes) = 0; /** Fades the view on the HMD to the specified color. The fade will take fSeconds, and the color values are between * 0.0 and 1.0. This color is faded on top of the scene based on the alpha parameter. Removing the fade color instantly * would be FadeToColor( 0.0, 0.0, 0.0, 0.0, 0.0 ). Values are in un-premultiplied alpha space. */ - virtual void FadeToColor( float fSeconds, float fRed, float fGreen, float fBlue, float fAlpha, bool bBackground = false ) = 0; + virtual void FadeToColor(float fSeconds, float fRed, float fGreen, float fBlue, float fAlpha, bool bBackground = false) = 0; /** Get current fade color value. */ - virtual HmdColor_t GetCurrentFadeColor( bool bBackground = false ) = 0; + virtual HmdColor_t GetCurrentFadeColor(bool bBackground = false) = 0; /** Fading the Grid in or out in fSeconds */ - virtual void FadeGrid( float fSeconds, bool bFadeIn ) = 0; + virtual void FadeGrid(float fSeconds, bool bFadeIn) = 0; /** Get current alpha value of grid. */ virtual float GetCurrentGridAlpha() = 0; @@ -2312,7 +2270,7 @@ public: /** Override the skybox used in the compositor (e.g. for during level loads when the app can't feed scene images fast enough) * Order is Front, Back, Left, Right, Top, Bottom. If only a single texture is passed, it is assumed in lat-long format. * If two are passed, it is assumed a lat-long stereo pair. */ - virtual EVRCompositorError SetSkyboxOverride( VR_ARRAY_COUNT( unTextureCount ) const Texture_t *pTextures, uint32_t unTextureCount ) = 0; + virtual EVRCompositorError SetSkyboxOverride(VR_ARRAY_COUNT(unTextureCount) const Texture_t *pTextures, uint32_t unTextureCount) = 0; /** Resets compositor skybox back to defaults. */ virtual void ClearSkyboxOverride() = 0; @@ -2327,7 +2285,7 @@ public: /** Tells the compositor process to clean up and exit. You do not need to call this function at shutdown. Under normal * circumstances the compositor will manage its own life cycle based on what applications are running. */ virtual void CompositorQuit() = 0; - + /** Return whether the compositor is fullscreen */ virtual bool IsFullscreen() = 0; @@ -2357,34 +2315,34 @@ public: virtual bool ShouldAppRenderWithLowResources() = 0; /** Override interleaved reprojection logic to force on. */ - virtual void ForceInterleavedReprojectionOn( bool bOverride ) = 0; + virtual void ForceInterleavedReprojectionOn(bool bOverride) = 0; /** Force reconnecting to the compositor process. */ virtual void ForceReconnectProcess() = 0; /** Temporarily suspends rendering (useful for finer control over scene transitions). */ - virtual void SuspendRendering( bool bSuspend ) = 0; + virtual void SuspendRendering(bool bSuspend) = 0; /** Opens a shared D3D11 texture with the undistorted composited image for each eye. Use ReleaseMirrorTextureD3D11 when finished * instead of calling Release on the resource itself. */ - virtual vr::EVRCompositorError GetMirrorTextureD3D11( vr::EVREye eEye, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView ) = 0; - virtual void ReleaseMirrorTextureD3D11( void *pD3D11ShaderResourceView ) = 0; + virtual vr::EVRCompositorError GetMirrorTextureD3D11(vr::EVREye eEye, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView) = 0; + virtual void ReleaseMirrorTextureD3D11(void *pD3D11ShaderResourceView) = 0; /** Access to mirror textures from OpenGL. */ - virtual vr::EVRCompositorError GetMirrorTextureGL( vr::EVREye eEye, vr::glUInt_t *pglTextureId, vr::glSharedTextureHandle_t *pglSharedTextureHandle ) = 0; - virtual bool ReleaseSharedGLTexture( vr::glUInt_t glTextureId, vr::glSharedTextureHandle_t glSharedTextureHandle ) = 0; - virtual void LockGLSharedTextureForAccess( vr::glSharedTextureHandle_t glSharedTextureHandle ) = 0; - virtual void UnlockGLSharedTextureForAccess( vr::glSharedTextureHandle_t glSharedTextureHandle ) = 0; + virtual vr::EVRCompositorError GetMirrorTextureGL(vr::EVREye eEye, vr::glUInt_t *pglTextureId, vr::glSharedTextureHandle_t *pglSharedTextureHandle) = 0; + virtual bool ReleaseSharedGLTexture(vr::glUInt_t glTextureId, vr::glSharedTextureHandle_t glSharedTextureHandle) = 0; + virtual void LockGLSharedTextureForAccess(vr::glSharedTextureHandle_t glSharedTextureHandle) = 0; + virtual void UnlockGLSharedTextureForAccess(vr::glSharedTextureHandle_t glSharedTextureHandle) = 0; /** [Vulkan Only] * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. The string will be a space separated list of-required instance extensions to enable in VkCreateInstance */ - virtual uint32_t GetVulkanInstanceExtensionsRequired( VR_OUT_STRING() char *pchValue, uint32_t unBufferSize ) = 0; + virtual uint32_t GetVulkanInstanceExtensionsRequired(VR_OUT_STRING() char *pchValue, uint32_t unBufferSize) = 0; /** [Vulkan only] * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. The string will be a space separated list of required device extensions to enable in VkCreateDevice */ - virtual uint32_t GetVulkanDeviceExtensionsRequired( VkPhysicalDevice_T *pPhysicalDevice, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize ) = 0; + virtual uint32_t GetVulkanDeviceExtensionsRequired(VkPhysicalDevice_T *pPhysicalDevice, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize) = 0; /** [ Vulkan/D3D12 Only ] * There are two purposes for SetExplicitTimingMode: @@ -2404,7 +2362,7 @@ public: * application calls PostPresentHandoff, then WaitGetPoses is guaranteed not to access the queue. Note that PostPresentHandoff * and SubmitExplicitTimingData will access the queue, so only WaitGetPoses becomes safe for accessing the queue from another * thread. */ - virtual void SetExplicitTimingMode( bool bExplicitTimingMode ) = 0; + virtual void SetExplicitTimingMode(bool bExplicitTimingMode) = 0; /** [ Vulkan/D3D12 Only ] * Submit explicit timing data. When SetExplicitTimingMode is true, this must be called immediately before @@ -2415,28 +2373,20 @@ public: virtual EVRCompositorError SubmitExplicitTimingData() = 0; }; -static const char * const IVRCompositor_Version = "IVRCompositor_021"; - -} // namespace vr - +static const char *const IVRCompositor_Version = "IVRCompositor_021"; +} // namespace vr // ivrnotifications.h namespace vr { - -#pragma pack( push, 8 ) +#pragma pack(push, 8) // Used for passing graphic data struct NotificationBitmap_t { NotificationBitmap_t() - : m_pImageData( nullptr ) - , m_nWidth( 0 ) - , m_nHeight( 0 ) - , m_nBytesPerPixel( 0 ) - { - }; + : m_pImageData(nullptr), m_nWidth(0), m_nHeight(0), m_nBytesPerPixel(0){}; void *m_pImageData; int32_t m_nWidth; @@ -2444,7 +2394,6 @@ struct NotificationBitmap_t int32_t m_nBytesPerPixel; }; - /** Be aware that the notification type is used as 'priority' to pick the next notification */ enum EVRNotificationType { @@ -2484,9 +2433,7 @@ static const uint32_t k_unNotificationTextMaxSize = 256; typedef uint32_t VRNotificationId; - - -#pragma pack( pop ) +#pragma pack(pop) /** Allows notification sources to interact with the VR system This current interface is not yet implemented. Do not use yet. */ @@ -2497,267 +2444,261 @@ public: * An overlay handle is required to create a notification, as otherwise it would be impossible for a user to act on it. * To create a two-line notification, use a line break ('\n') to split the text into two lines. * The pImage argument may be NULL, in which case the specified overlay's icon will be used instead. */ - virtual EVRNotificationError CreateNotification( VROverlayHandle_t ulOverlayHandle, uint64_t ulUserValue, EVRNotificationType type, const char *pchText, EVRNotificationStyle style, const NotificationBitmap_t *pImage, /* out */ VRNotificationId *pNotificationId ) = 0; + virtual EVRNotificationError CreateNotification(VROverlayHandle_t ulOverlayHandle, uint64_t ulUserValue, EVRNotificationType type, const char *pchText, EVRNotificationStyle style, const NotificationBitmap_t *pImage, /* out */ VRNotificationId *pNotificationId) = 0; /** Destroy a notification, hiding it first if it currently shown to the user. */ - virtual EVRNotificationError RemoveNotification( VRNotificationId notificationId ) = 0; - + virtual EVRNotificationError RemoveNotification(VRNotificationId notificationId) = 0; }; -static const char * const IVRNotifications_Version = "IVRNotifications_002"; - -} // namespace vr - +static const char *const IVRNotifications_Version = "IVRNotifications_002"; +} // namespace vr // ivroverlay.h namespace vr { +/** The maximum length of an overlay key in bytes, counting the terminating null character. */ +static const uint32_t k_unVROverlayMaxKeyLength = 128; - /** The maximum length of an overlay key in bytes, counting the terminating null character. */ - static const uint32_t k_unVROverlayMaxKeyLength = 128; +/** The maximum length of an overlay name in bytes, counting the terminating null character. */ +static const uint32_t k_unVROverlayMaxNameLength = 128; - /** The maximum length of an overlay name in bytes, counting the terminating null character. */ - static const uint32_t k_unVROverlayMaxNameLength = 128; +/** The maximum number of overlays that can exist in the system at one time. */ +static const uint32_t k_unMaxOverlayCount = 64; - /** The maximum number of overlays that can exist in the system at one time. */ - static const uint32_t k_unMaxOverlayCount = 64; +/** The maximum number of overlay intersection mask primitives per overlay */ +static const uint32_t k_unMaxOverlayIntersectionMaskPrimitivesCount = 32; - /** The maximum number of overlay intersection mask primitives per overlay */ - static const uint32_t k_unMaxOverlayIntersectionMaskPrimitivesCount = 32; +/** Types of input supported by VR Overlays */ +enum VROverlayInputMethod +{ + VROverlayInputMethod_None = 0, // No input events will be generated automatically for this overlay + VROverlayInputMethod_Mouse = 1, // Tracked controllers will get mouse events automatically +}; - /** Types of input supported by VR Overlays */ - enum VROverlayInputMethod - { - VROverlayInputMethod_None = 0, // No input events will be generated automatically for this overlay - VROverlayInputMethod_Mouse = 1, // Tracked controllers will get mouse events automatically - }; +/** Allows the caller to figure out which overlay transform getter to call. */ +enum VROverlayTransformType +{ + VROverlayTransform_Absolute = 0, + VROverlayTransform_TrackedDeviceRelative = 1, + VROverlayTransform_SystemOverlay = 2, + VROverlayTransform_TrackedComponent = 3, +}; - /** Allows the caller to figure out which overlay transform getter to call. */ - enum VROverlayTransformType - { - VROverlayTransform_Absolute = 0, - VROverlayTransform_TrackedDeviceRelative = 1, - VROverlayTransform_SystemOverlay = 2, - VROverlayTransform_TrackedComponent = 3, - }; +/** Overlay control settings */ +enum VROverlayFlags +{ + VROverlayFlags_None = 0, - /** Overlay control settings */ - enum VROverlayFlags - { - VROverlayFlags_None = 0, + // The following only take effect when rendered using the high quality render path (see SetHighQualityOverlay). + VROverlayFlags_Curved = 1, + VROverlayFlags_RGSS4X = 2, - // The following only take effect when rendered using the high quality render path (see SetHighQualityOverlay). - VROverlayFlags_Curved = 1, - VROverlayFlags_RGSS4X = 2, + // Set this flag on a dashboard overlay to prevent a tab from showing up for that overlay + VROverlayFlags_NoDashboardTab = 3, - // Set this flag on a dashboard overlay to prevent a tab from showing up for that overlay - VROverlayFlags_NoDashboardTab = 3, + // Set this flag on a dashboard that is able to deal with gamepad focus events + VROverlayFlags_AcceptsGamepadEvents = 4, - // Set this flag on a dashboard that is able to deal with gamepad focus events - VROverlayFlags_AcceptsGamepadEvents = 4, + // Indicates that the overlay should dim/brighten to show gamepad focus + VROverlayFlags_ShowGamepadFocus = 5, - // Indicates that the overlay should dim/brighten to show gamepad focus - VROverlayFlags_ShowGamepadFocus = 5, + // When in VROverlayInputMethod_Mouse you can optionally enable sending VRScroll_t + VROverlayFlags_SendVRScrollEvents = 6, + VROverlayFlags_SendVRTouchpadEvents = 7, - // When in VROverlayInputMethod_Mouse you can optionally enable sending VRScroll_t - VROverlayFlags_SendVRScrollEvents = 6, - VROverlayFlags_SendVRTouchpadEvents = 7, + // If set this will render a vertical scroll wheel on the primary controller, + // only needed if not using VROverlayFlags_SendVRScrollEvents but you still want to represent a scroll wheel + VROverlayFlags_ShowTouchPadScrollWheel = 8, - // If set this will render a vertical scroll wheel on the primary controller, - // only needed if not using VROverlayFlags_SendVRScrollEvents but you still want to represent a scroll wheel - VROverlayFlags_ShowTouchPadScrollWheel = 8, + // If this is set ownership and render access to the overlay are transferred + // to the new scene process on a call to IVRApplications::LaunchInternalProcess + VROverlayFlags_TransferOwnershipToInternalProcess = 9, - // If this is set ownership and render access to the overlay are transferred - // to the new scene process on a call to IVRApplications::LaunchInternalProcess - VROverlayFlags_TransferOwnershipToInternalProcess = 9, + // If set, renders 50% of the texture in each eye, side by side + VROverlayFlags_SideBySide_Parallel = 10, // Texture is left/right + VROverlayFlags_SideBySide_Crossed = 11, // Texture is crossed and right/left - // If set, renders 50% of the texture in each eye, side by side - VROverlayFlags_SideBySide_Parallel = 10, // Texture is left/right - VROverlayFlags_SideBySide_Crossed = 11, // Texture is crossed and right/left + VROverlayFlags_Panorama = 12, // Texture is a panorama + VROverlayFlags_StereoPanorama = 13, // Texture is a stereo panorama - VROverlayFlags_Panorama = 12, // Texture is a panorama - VROverlayFlags_StereoPanorama = 13, // Texture is a stereo panorama + // If this is set on an overlay owned by the scene application that overlay + // will be sorted with the "Other" overlays on top of all other scene overlays + VROverlayFlags_SortWithNonSceneOverlays = 14, - // If this is set on an overlay owned by the scene application that overlay - // will be sorted with the "Other" overlays on top of all other scene overlays - VROverlayFlags_SortWithNonSceneOverlays = 14, + // If set, the overlay will be shown in the dashboard, otherwise it will be hidden. + VROverlayFlags_VisibleInDashboard = 15, +}; - // If set, the overlay will be shown in the dashboard, otherwise it will be hidden. - VROverlayFlags_VisibleInDashboard = 15, - }; +enum VRMessageOverlayResponse +{ + VRMessageOverlayResponse_ButtonPress_0 = 0, + VRMessageOverlayResponse_ButtonPress_1 = 1, + VRMessageOverlayResponse_ButtonPress_2 = 2, + VRMessageOverlayResponse_ButtonPress_3 = 3, + VRMessageOverlayResponse_CouldntFindSystemOverlay = 4, + VRMessageOverlayResponse_CouldntFindOrCreateClientOverlay = 5, + VRMessageOverlayResponse_ApplicationQuit = 6 +}; - enum VRMessageOverlayResponse - { - VRMessageOverlayResponse_ButtonPress_0 = 0, - VRMessageOverlayResponse_ButtonPress_1 = 1, - VRMessageOverlayResponse_ButtonPress_2 = 2, - VRMessageOverlayResponse_ButtonPress_3 = 3, - VRMessageOverlayResponse_CouldntFindSystemOverlay = 4, - VRMessageOverlayResponse_CouldntFindOrCreateClientOverlay= 5, - VRMessageOverlayResponse_ApplicationQuit = 6 - }; +struct VROverlayIntersectionParams_t +{ + HmdVector3_t vSource; + HmdVector3_t vDirection; + ETrackingUniverseOrigin eOrigin; +}; - struct VROverlayIntersectionParams_t - { - HmdVector3_t vSource; - HmdVector3_t vDirection; - ETrackingUniverseOrigin eOrigin; - }; +struct VROverlayIntersectionResults_t +{ + HmdVector3_t vPoint; + HmdVector3_t vNormal; + HmdVector2_t vUVs; + float fDistance; +}; - struct VROverlayIntersectionResults_t - { - HmdVector3_t vPoint; - HmdVector3_t vNormal; - HmdVector2_t vUVs; - float fDistance; - }; +// Input modes for the Big Picture gamepad text entry +enum EGamepadTextInputMode +{ + k_EGamepadTextInputModeNormal = 0, + k_EGamepadTextInputModePassword = 1, + k_EGamepadTextInputModeSubmit = 2, +}; - // Input modes for the Big Picture gamepad text entry - enum EGamepadTextInputMode - { - k_EGamepadTextInputModeNormal = 0, - k_EGamepadTextInputModePassword = 1, - k_EGamepadTextInputModeSubmit = 2, - }; +// Controls number of allowed lines for the Big Picture gamepad text entry +enum EGamepadTextInputLineMode +{ + k_EGamepadTextInputLineModeSingleLine = 0, + k_EGamepadTextInputLineModeMultipleLines = 1 +}; - // Controls number of allowed lines for the Big Picture gamepad text entry - enum EGamepadTextInputLineMode - { - k_EGamepadTextInputLineModeSingleLine = 0, - k_EGamepadTextInputLineModeMultipleLines = 1 - }; +/** Directions for changing focus between overlays with the gamepad */ +enum EOverlayDirection +{ + OverlayDirection_Up = 0, + OverlayDirection_Down = 1, + OverlayDirection_Left = 2, + OverlayDirection_Right = 3, - /** Directions for changing focus between overlays with the gamepad */ - enum EOverlayDirection - { - OverlayDirection_Up = 0, - OverlayDirection_Down = 1, - OverlayDirection_Left = 2, - OverlayDirection_Right = 3, - - OverlayDirection_Count = 4, - }; + OverlayDirection_Count = 4, +}; - enum EVROverlayIntersectionMaskPrimitiveType - { - OverlayIntersectionPrimitiveType_Rectangle, - OverlayIntersectionPrimitiveType_Circle, - }; +enum EVROverlayIntersectionMaskPrimitiveType +{ + OverlayIntersectionPrimitiveType_Rectangle, + OverlayIntersectionPrimitiveType_Circle, +}; - struct IntersectionMaskRectangle_t - { - float m_flTopLeftX; - float m_flTopLeftY; - float m_flWidth; - float m_flHeight; - }; +struct IntersectionMaskRectangle_t +{ + float m_flTopLeftX; + float m_flTopLeftY; + float m_flWidth; + float m_flHeight; +}; - struct IntersectionMaskCircle_t - { - float m_flCenterX; - float m_flCenterY; - float m_flRadius; - }; +struct IntersectionMaskCircle_t +{ + float m_flCenterX; + float m_flCenterY; + float m_flRadius; +}; - /** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py and openvr_api_flat.h.py */ - typedef union - { - IntersectionMaskRectangle_t m_Rectangle; - IntersectionMaskCircle_t m_Circle; - } VROverlayIntersectionMaskPrimitive_Data_t; +/** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py and openvr_api_flat.h.py */ +typedef union { + IntersectionMaskRectangle_t m_Rectangle; + IntersectionMaskCircle_t m_Circle; +} VROverlayIntersectionMaskPrimitive_Data_t; - struct VROverlayIntersectionMaskPrimitive_t - { - EVROverlayIntersectionMaskPrimitiveType m_nPrimitiveType; - VROverlayIntersectionMaskPrimitive_Data_t m_Primitive; - }; +struct VROverlayIntersectionMaskPrimitive_t +{ + EVROverlayIntersectionMaskPrimitiveType m_nPrimitiveType; + VROverlayIntersectionMaskPrimitive_Data_t m_Primitive; +}; - class IVROverlay - { - public: +class IVROverlay +{ +public: + // --------------------------------------------- + // Overlay management methods + // --------------------------------------------- - // --------------------------------------------- - // Overlay management methods - // --------------------------------------------- + /** Finds an existing overlay with the specified key. */ + virtual EVROverlayError FindOverlay(const char *pchOverlayKey, VROverlayHandle_t *pOverlayHandle) = 0; - /** Finds an existing overlay with the specified key. */ - virtual EVROverlayError FindOverlay( const char *pchOverlayKey, VROverlayHandle_t * pOverlayHandle ) = 0; + /** Creates a new named overlay. All overlays start hidden and with default settings. */ + virtual EVROverlayError CreateOverlay(const char *pchOverlayKey, const char *pchOverlayName, VROverlayHandle_t *pOverlayHandle) = 0; - /** Creates a new named overlay. All overlays start hidden and with default settings. */ - virtual EVROverlayError CreateOverlay( const char *pchOverlayKey, const char *pchOverlayName, VROverlayHandle_t * pOverlayHandle ) = 0; - - /** Destroys the specified overlay. When an application calls VR_Shutdown all overlays created by that app are + /** Destroys the specified overlay. When an application calls VR_Shutdown all overlays created by that app are * automatically destroyed. */ - virtual EVROverlayError DestroyOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + virtual EVROverlayError DestroyOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Specify which overlay to use the high quality render path. This overlay will be composited in during the distortion pass which + /** Specify which overlay to use the high quality render path. This overlay will be composited in during the distortion pass which * results in it drawing on top of everything else, but also at a higher quality as it samples the source texture directly rather than * rasterizing into each eye's render texture first. Because if this, only one of these is supported at any given time. It is most useful * for overlays that are expected to take up most of the user's view (e.g. streaming video). * This mode does not support mouse input to your overlay. */ - virtual EVROverlayError SetHighQualityOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + virtual EVROverlayError SetHighQualityOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Returns the overlay handle of the current overlay being rendered using the single high quality overlay render path. + /** Returns the overlay handle of the current overlay being rendered using the single high quality overlay render path. * Otherwise it will return k_ulOverlayHandleInvalid. */ - virtual vr::VROverlayHandle_t GetHighQualityOverlay() = 0; + virtual vr::VROverlayHandle_t GetHighQualityOverlay() = 0; - /** Fills the provided buffer with the string key of the overlay. Returns the size of buffer required to store the key, including + /** Fills the provided buffer with the string key of the overlay. Returns the size of buffer required to store the key, including * the terminating null character. k_unVROverlayMaxKeyLength will be enough bytes to fit the string. */ - virtual uint32_t GetOverlayKey( VROverlayHandle_t ulOverlayHandle, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, EVROverlayError *pError = 0L ) = 0; + virtual uint32_t GetOverlayKey(VROverlayHandle_t ulOverlayHandle, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, EVROverlayError *pError = 0L) = 0; - /** Fills the provided buffer with the friendly name of the overlay. Returns the size of buffer required to store the key, including + /** Fills the provided buffer with the friendly name of the overlay. Returns the size of buffer required to store the key, including * the terminating null character. k_unVROverlayMaxNameLength will be enough bytes to fit the string. */ - virtual uint32_t GetOverlayName( VROverlayHandle_t ulOverlayHandle, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, EVROverlayError *pError = 0L ) = 0; + virtual uint32_t GetOverlayName(VROverlayHandle_t ulOverlayHandle, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, EVROverlayError *pError = 0L) = 0; - /** set the name to use for this overlay */ - virtual EVROverlayError SetOverlayName( VROverlayHandle_t ulOverlayHandle, const char *pchName ) = 0; + /** set the name to use for this overlay */ + virtual EVROverlayError SetOverlayName(VROverlayHandle_t ulOverlayHandle, const char *pchName) = 0; - /** Gets the raw image data from an overlay. Overlay image data is always returned as RGBA data, 4 bytes per pixel. If the buffer is not large enough, width and height + /** Gets the raw image data from an overlay. Overlay image data is always returned as RGBA data, 4 bytes per pixel. If the buffer is not large enough, width and height * will be set and VROverlayError_ArrayTooSmall is returned. */ - virtual EVROverlayError GetOverlayImageData( VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unBufferSize, uint32_t *punWidth, uint32_t *punHeight ) = 0; + virtual EVROverlayError GetOverlayImageData(VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unBufferSize, uint32_t *punWidth, uint32_t *punHeight) = 0; - /** returns a string that corresponds with the specified overlay error. The string will be the name + /** returns a string that corresponds with the specified overlay error. The string will be the name * of the error enum value for all valid error codes */ - virtual const char *GetOverlayErrorNameFromEnum( EVROverlayError error ) = 0; + virtual const char *GetOverlayErrorNameFromEnum(EVROverlayError error) = 0; - // --------------------------------------------- - // Overlay rendering methods - // --------------------------------------------- + // --------------------------------------------- + // Overlay rendering methods + // --------------------------------------------- - /** Sets the pid that is allowed to render to this overlay (the creator pid is always allow to render), + /** Sets the pid that is allowed to render to this overlay (the creator pid is always allow to render), * by default this is the pid of the process that made the overlay */ - virtual EVROverlayError SetOverlayRenderingPid( VROverlayHandle_t ulOverlayHandle, uint32_t unPID ) = 0; + virtual EVROverlayError SetOverlayRenderingPid(VROverlayHandle_t ulOverlayHandle, uint32_t unPID) = 0; - /** Gets the pid that is allowed to render to this overlay */ - virtual uint32_t GetOverlayRenderingPid( VROverlayHandle_t ulOverlayHandle ) = 0; + /** Gets the pid that is allowed to render to this overlay */ + virtual uint32_t GetOverlayRenderingPid(VROverlayHandle_t ulOverlayHandle) = 0; - /** Specify flag setting for a given overlay */ - virtual EVROverlayError SetOverlayFlag( VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool bEnabled ) = 0; + /** Specify flag setting for a given overlay */ + virtual EVROverlayError SetOverlayFlag(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool bEnabled) = 0; - /** Sets flag setting for a given overlay */ - virtual EVROverlayError GetOverlayFlag( VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool *pbEnabled ) = 0; + /** Sets flag setting for a given overlay */ + virtual EVROverlayError GetOverlayFlag(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool *pbEnabled) = 0; - /** Sets the color tint of the overlay quad. Use 0.0 to 1.0 per channel. */ - virtual EVROverlayError SetOverlayColor( VROverlayHandle_t ulOverlayHandle, float fRed, float fGreen, float fBlue ) = 0; + /** Sets the color tint of the overlay quad. Use 0.0 to 1.0 per channel. */ + virtual EVROverlayError SetOverlayColor(VROverlayHandle_t ulOverlayHandle, float fRed, float fGreen, float fBlue) = 0; - /** Gets the color tint of the overlay quad. */ - virtual EVROverlayError GetOverlayColor( VROverlayHandle_t ulOverlayHandle, float *pfRed, float *pfGreen, float *pfBlue ) = 0; + /** Gets the color tint of the overlay quad. */ + virtual EVROverlayError GetOverlayColor(VROverlayHandle_t ulOverlayHandle, float *pfRed, float *pfGreen, float *pfBlue) = 0; - /** Sets the alpha of the overlay quad. Use 1.0 for 100 percent opacity to 0.0 for 0 percent opacity. */ - virtual EVROverlayError SetOverlayAlpha( VROverlayHandle_t ulOverlayHandle, float fAlpha ) = 0; + /** Sets the alpha of the overlay quad. Use 1.0 for 100 percent opacity to 0.0 for 0 percent opacity. */ + virtual EVROverlayError SetOverlayAlpha(VROverlayHandle_t ulOverlayHandle, float fAlpha) = 0; - /** Gets the alpha of the overlay quad. By default overlays are rendering at 100 percent alpha (1.0). */ - virtual EVROverlayError GetOverlayAlpha( VROverlayHandle_t ulOverlayHandle, float *pfAlpha ) = 0; + /** Gets the alpha of the overlay quad. By default overlays are rendering at 100 percent alpha (1.0). */ + virtual EVROverlayError GetOverlayAlpha(VROverlayHandle_t ulOverlayHandle, float *pfAlpha) = 0; - /** Sets the aspect ratio of the texels in the overlay. 1.0 means the texels are square. 2.0 means the texels + /** Sets the aspect ratio of the texels in the overlay. 1.0 means the texels are square. 2.0 means the texels * are twice as wide as they are tall. Defaults to 1.0. */ - virtual EVROverlayError SetOverlayTexelAspect( VROverlayHandle_t ulOverlayHandle, float fTexelAspect ) = 0; + virtual EVROverlayError SetOverlayTexelAspect(VROverlayHandle_t ulOverlayHandle, float fTexelAspect) = 0; - /** Gets the aspect ratio of the texels in the overlay. Defaults to 1.0 */ - virtual EVROverlayError GetOverlayTexelAspect( VROverlayHandle_t ulOverlayHandle, float *pfTexelAspect ) = 0; + /** Gets the aspect ratio of the texels in the overlay. Defaults to 1.0 */ + virtual EVROverlayError GetOverlayTexelAspect(VROverlayHandle_t ulOverlayHandle, float *pfTexelAspect) = 0; - /** Sets the rendering sort order for the overlay. Overlays are rendered this order: + /** Sets the rendering sort order for the overlay. Overlays are rendered this order: * Overlays owned by the scene application * Overlays owned by some other application * @@ -2765,160 +2706,160 @@ namespace vr * sort order are rendered back to front base on distance from the HMD. * * Sort order defaults to 0. */ - virtual EVROverlayError SetOverlaySortOrder( VROverlayHandle_t ulOverlayHandle, uint32_t unSortOrder ) = 0; + virtual EVROverlayError SetOverlaySortOrder(VROverlayHandle_t ulOverlayHandle, uint32_t unSortOrder) = 0; - /** Gets the sort order of the overlay. See SetOverlaySortOrder for how this works. */ - virtual EVROverlayError GetOverlaySortOrder( VROverlayHandle_t ulOverlayHandle, uint32_t *punSortOrder ) = 0; + /** Gets the sort order of the overlay. See SetOverlaySortOrder for how this works. */ + virtual EVROverlayError GetOverlaySortOrder(VROverlayHandle_t ulOverlayHandle, uint32_t *punSortOrder) = 0; - /** Sets the width of the overlay quad in meters. By default overlays are rendered on a quad that is 1 meter across */ - virtual EVROverlayError SetOverlayWidthInMeters( VROverlayHandle_t ulOverlayHandle, float fWidthInMeters ) = 0; + /** Sets the width of the overlay quad in meters. By default overlays are rendered on a quad that is 1 meter across */ + virtual EVROverlayError SetOverlayWidthInMeters(VROverlayHandle_t ulOverlayHandle, float fWidthInMeters) = 0; - /** Returns the width of the overlay quad in meters. By default overlays are rendered on a quad that is 1 meter across */ - virtual EVROverlayError GetOverlayWidthInMeters( VROverlayHandle_t ulOverlayHandle, float *pfWidthInMeters ) = 0; + /** Returns the width of the overlay quad in meters. By default overlays are rendered on a quad that is 1 meter across */ + virtual EVROverlayError GetOverlayWidthInMeters(VROverlayHandle_t ulOverlayHandle, float *pfWidthInMeters) = 0; - /** For high-quality curved overlays only, sets the distance range in meters from the overlay used to automatically curve + /** For high-quality curved overlays only, sets the distance range in meters from the overlay used to automatically curve * the surface around the viewer. Min is distance is when the surface will be most curved. Max is when least curved. */ - virtual EVROverlayError SetOverlayAutoCurveDistanceRangeInMeters( VROverlayHandle_t ulOverlayHandle, float fMinDistanceInMeters, float fMaxDistanceInMeters ) = 0; + virtual EVROverlayError SetOverlayAutoCurveDistanceRangeInMeters(VROverlayHandle_t ulOverlayHandle, float fMinDistanceInMeters, float fMaxDistanceInMeters) = 0; - /** For high-quality curved overlays only, gets the distance range in meters from the overlay used to automatically curve + /** For high-quality curved overlays only, gets the distance range in meters from the overlay used to automatically curve * the surface around the viewer. Min is distance is when the surface will be most curved. Max is when least curved. */ - virtual EVROverlayError GetOverlayAutoCurveDistanceRangeInMeters( VROverlayHandle_t ulOverlayHandle, float *pfMinDistanceInMeters, float *pfMaxDistanceInMeters ) = 0; + virtual EVROverlayError GetOverlayAutoCurveDistanceRangeInMeters(VROverlayHandle_t ulOverlayHandle, float *pfMinDistanceInMeters, float *pfMaxDistanceInMeters) = 0; - /** Sets the colorspace the overlay texture's data is in. Defaults to 'auto'. + /** Sets the colorspace the overlay texture's data is in. Defaults to 'auto'. * If the texture needs to be resolved, you should call SetOverlayTexture with the appropriate colorspace instead. */ - virtual EVROverlayError SetOverlayTextureColorSpace( VROverlayHandle_t ulOverlayHandle, EColorSpace eTextureColorSpace ) = 0; + virtual EVROverlayError SetOverlayTextureColorSpace(VROverlayHandle_t ulOverlayHandle, EColorSpace eTextureColorSpace) = 0; - /** Gets the overlay's current colorspace setting. */ - virtual EVROverlayError GetOverlayTextureColorSpace( VROverlayHandle_t ulOverlayHandle, EColorSpace *peTextureColorSpace ) = 0; + /** Gets the overlay's current colorspace setting. */ + virtual EVROverlayError GetOverlayTextureColorSpace(VROverlayHandle_t ulOverlayHandle, EColorSpace *peTextureColorSpace) = 0; - /** Sets the part of the texture to use for the overlay. UV Min is the upper left corner and UV Max is the lower right corner. */ - virtual EVROverlayError SetOverlayTextureBounds( VROverlayHandle_t ulOverlayHandle, const VRTextureBounds_t *pOverlayTextureBounds ) = 0; + /** Sets the part of the texture to use for the overlay. UV Min is the upper left corner and UV Max is the lower right corner. */ + virtual EVROverlayError SetOverlayTextureBounds(VROverlayHandle_t ulOverlayHandle, const VRTextureBounds_t *pOverlayTextureBounds) = 0; - /** Gets the part of the texture to use for the overlay. UV Min is the upper left corner and UV Max is the lower right corner. */ - virtual EVROverlayError GetOverlayTextureBounds( VROverlayHandle_t ulOverlayHandle, VRTextureBounds_t *pOverlayTextureBounds ) = 0; + /** Gets the part of the texture to use for the overlay. UV Min is the upper left corner and UV Max is the lower right corner. */ + virtual EVROverlayError GetOverlayTextureBounds(VROverlayHandle_t ulOverlayHandle, VRTextureBounds_t *pOverlayTextureBounds) = 0; - /** Gets render model to draw behind this overlay */ - virtual uint32_t GetOverlayRenderModel( vr::VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, HmdColor_t *pColor, vr::EVROverlayError *pError ) = 0; + /** Gets render model to draw behind this overlay */ + virtual uint32_t GetOverlayRenderModel(vr::VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, HmdColor_t *pColor, vr::EVROverlayError *pError) = 0; - /** Sets render model to draw behind this overlay and the vertex color to use, pass null for pColor to match the overlays vertex color. + /** Sets render model to draw behind this overlay and the vertex color to use, pass null for pColor to match the overlays vertex color. The model is scaled by the same amount as the overlay, with a default of 1m. */ - virtual vr::EVROverlayError SetOverlayRenderModel( vr::VROverlayHandle_t ulOverlayHandle, const char *pchRenderModel, const HmdColor_t *pColor ) = 0; + virtual vr::EVROverlayError SetOverlayRenderModel(vr::VROverlayHandle_t ulOverlayHandle, const char *pchRenderModel, const HmdColor_t *pColor) = 0; - /** Returns the transform type of this overlay. */ - virtual EVROverlayError GetOverlayTransformType( VROverlayHandle_t ulOverlayHandle, VROverlayTransformType *peTransformType ) = 0; + /** Returns the transform type of this overlay. */ + virtual EVROverlayError GetOverlayTransformType(VROverlayHandle_t ulOverlayHandle, VROverlayTransformType *peTransformType) = 0; - /** Sets the transform to absolute tracking origin. */ - virtual EVROverlayError SetOverlayTransformAbsolute( VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, const HmdMatrix34_t *pmatTrackingOriginToOverlayTransform ) = 0; + /** Sets the transform to absolute tracking origin. */ + virtual EVROverlayError SetOverlayTransformAbsolute(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, const HmdMatrix34_t *pmatTrackingOriginToOverlayTransform) = 0; - /** Gets the transform if it is absolute. Returns an error if the transform is some other type. */ - virtual EVROverlayError GetOverlayTransformAbsolute( VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin *peTrackingOrigin, HmdMatrix34_t *pmatTrackingOriginToOverlayTransform ) = 0; + /** Gets the transform if it is absolute. Returns an error if the transform is some other type. */ + virtual EVROverlayError GetOverlayTransformAbsolute(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin *peTrackingOrigin, HmdMatrix34_t *pmatTrackingOriginToOverlayTransform) = 0; - /** Sets the transform to relative to the transform of the specified tracked device. */ - virtual EVROverlayError SetOverlayTransformTrackedDeviceRelative( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unTrackedDevice, const HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform ) = 0; + /** Sets the transform to relative to the transform of the specified tracked device. */ + virtual EVROverlayError SetOverlayTransformTrackedDeviceRelative(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unTrackedDevice, const HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform) = 0; - /** Gets the transform if it is relative to a tracked device. Returns an error if the transform is some other type. */ - virtual EVROverlayError GetOverlayTransformTrackedDeviceRelative( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punTrackedDevice, HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform ) = 0; + /** Gets the transform if it is relative to a tracked device. Returns an error if the transform is some other type. */ + virtual EVROverlayError GetOverlayTransformTrackedDeviceRelative(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punTrackedDevice, HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform) = 0; - /** Sets the transform to draw the overlay on a rendermodel component mesh instead of a quad. This will only draw when the system is + /** Sets the transform to draw the overlay on a rendermodel component mesh instead of a quad. This will only draw when the system is * drawing the device. Overlays with this transform type cannot receive mouse events. */ - virtual EVROverlayError SetOverlayTransformTrackedDeviceComponent( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unDeviceIndex, const char *pchComponentName ) = 0; + virtual EVROverlayError SetOverlayTransformTrackedDeviceComponent(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unDeviceIndex, const char *pchComponentName) = 0; - /** Gets the transform information when the overlay is rendering on a component. */ - virtual EVROverlayError GetOverlayTransformTrackedDeviceComponent( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punDeviceIndex, char *pchComponentName, uint32_t unComponentNameSize ) = 0; + /** Gets the transform information when the overlay is rendering on a component. */ + virtual EVROverlayError GetOverlayTransformTrackedDeviceComponent(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punDeviceIndex, char *pchComponentName, uint32_t unComponentNameSize) = 0; - /** Gets the transform if it is relative to another overlay. Returns an error if the transform is some other type. */ - virtual vr::EVROverlayError GetOverlayTransformOverlayRelative( VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t *ulOverlayHandleParent, HmdMatrix34_t *pmatParentOverlayToOverlayTransform ) = 0; - - /** Sets the transform to relative to the transform of the specified overlay. This overlays visibility will also track the parents visibility */ - virtual vr::EVROverlayError SetOverlayTransformOverlayRelative( VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t ulOverlayHandleParent, const HmdMatrix34_t *pmatParentOverlayToOverlayTransform ) = 0; + /** Gets the transform if it is relative to another overlay. Returns an error if the transform is some other type. */ + virtual vr::EVROverlayError GetOverlayTransformOverlayRelative(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t *ulOverlayHandleParent, HmdMatrix34_t *pmatParentOverlayToOverlayTransform) = 0; - /** Shows the VR overlay. For dashboard overlays, only the Dashboard Manager is allowed to call this. */ - virtual EVROverlayError ShowOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + /** Sets the transform to relative to the transform of the specified overlay. This overlays visibility will also track the parents visibility */ + virtual vr::EVROverlayError SetOverlayTransformOverlayRelative(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t ulOverlayHandleParent, const HmdMatrix34_t *pmatParentOverlayToOverlayTransform) = 0; - /** Hides the VR overlay. For dashboard overlays, only the Dashboard Manager is allowed to call this. */ - virtual EVROverlayError HideOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + /** Shows the VR overlay. For dashboard overlays, only the Dashboard Manager is allowed to call this. */ + virtual EVROverlayError ShowOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Returns true if the overlay is visible. */ - virtual bool IsOverlayVisible( VROverlayHandle_t ulOverlayHandle ) = 0; + /** Hides the VR overlay. For dashboard overlays, only the Dashboard Manager is allowed to call this. */ + virtual EVROverlayError HideOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Get the transform in 3d space associated with a specific 2d point in the overlay's coordinate space (where 0,0 is the lower left). -Z points out of the overlay */ - virtual EVROverlayError GetTransformForOverlayCoordinates( VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, HmdVector2_t coordinatesInOverlay, HmdMatrix34_t *pmatTransform ) = 0; + /** Returns true if the overlay is visible. */ + virtual bool IsOverlayVisible(VROverlayHandle_t ulOverlayHandle) = 0; - // --------------------------------------------- - // Overlay input methods - // --------------------------------------------- + /** Get the transform in 3d space associated with a specific 2d point in the overlay's coordinate space (where 0,0 is the lower left). -Z points out of the overlay */ + virtual EVROverlayError GetTransformForOverlayCoordinates(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, HmdVector2_t coordinatesInOverlay, HmdMatrix34_t *pmatTransform) = 0; - /** Returns true and fills the event with the next event on the overlay's event queue, if there is one. + // --------------------------------------------- + // Overlay input methods + // --------------------------------------------- + + /** Returns true and fills the event with the next event on the overlay's event queue, if there is one. * If there are no events this method returns false. uncbVREvent should be the size in bytes of the VREvent_t struct */ - virtual bool PollNextOverlayEvent( VROverlayHandle_t ulOverlayHandle, VREvent_t *pEvent, uint32_t uncbVREvent ) = 0; + virtual bool PollNextOverlayEvent(VROverlayHandle_t ulOverlayHandle, VREvent_t *pEvent, uint32_t uncbVREvent) = 0; - /** Returns the current input settings for the specified overlay. */ - virtual EVROverlayError GetOverlayInputMethod( VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod *peInputMethod ) = 0; + /** Returns the current input settings for the specified overlay. */ + virtual EVROverlayError GetOverlayInputMethod(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod *peInputMethod) = 0; - /** Sets the input settings for the specified overlay. */ - virtual EVROverlayError SetOverlayInputMethod( VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod eInputMethod ) = 0; + /** Sets the input settings for the specified overlay. */ + virtual EVROverlayError SetOverlayInputMethod(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod eInputMethod) = 0; - /** Gets the mouse scaling factor that is used for mouse events. The actual texture may be a different size, but this is + /** Gets the mouse scaling factor that is used for mouse events. The actual texture may be a different size, but this is * typically the size of the underlying UI in pixels. */ - virtual EVROverlayError GetOverlayMouseScale( VROverlayHandle_t ulOverlayHandle, HmdVector2_t *pvecMouseScale ) = 0; + virtual EVROverlayError GetOverlayMouseScale(VROverlayHandle_t ulOverlayHandle, HmdVector2_t *pvecMouseScale) = 0; - /** Sets the mouse scaling factor that is used for mouse events. The actual texture may be a different size, but this is + /** Sets the mouse scaling factor that is used for mouse events. The actual texture may be a different size, but this is * typically the size of the underlying UI in pixels (not in world space). */ - virtual EVROverlayError SetOverlayMouseScale( VROverlayHandle_t ulOverlayHandle, const HmdVector2_t *pvecMouseScale ) = 0; + virtual EVROverlayError SetOverlayMouseScale(VROverlayHandle_t ulOverlayHandle, const HmdVector2_t *pvecMouseScale) = 0; - /** Computes the overlay-space pixel coordinates of where the ray intersects the overlay with the + /** Computes the overlay-space pixel coordinates of where the ray intersects the overlay with the * specified settings. Returns false if there is no intersection. */ - virtual bool ComputeOverlayIntersection( VROverlayHandle_t ulOverlayHandle, const VROverlayIntersectionParams_t *pParams, VROverlayIntersectionResults_t *pResults ) = 0; + virtual bool ComputeOverlayIntersection(VROverlayHandle_t ulOverlayHandle, const VROverlayIntersectionParams_t *pParams, VROverlayIntersectionResults_t *pResults) = 0; - /** Processes mouse input from the specified controller as though it were a mouse pointed at a compositor overlay with the + /** Processes mouse input from the specified controller as though it were a mouse pointed at a compositor overlay with the * specified settings. The controller is treated like a laser pointer on the -z axis. The point where the laser pointer would * intersect with the overlay is the mouse position, the trigger is left mouse, and the track pad is right mouse. * * Return true if the controller is pointed at the overlay and an event was generated. */ - virtual bool HandleControllerOverlayInteractionAsMouse( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unControllerDeviceIndex ) = 0; + virtual bool HandleControllerOverlayInteractionAsMouse(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unControllerDeviceIndex) = 0; - /** Returns true if the specified overlay is the hover target. An overlay is the hover target when it is the last overlay "moused over" + /** Returns true if the specified overlay is the hover target. An overlay is the hover target when it is the last overlay "moused over" * by the virtual mouse pointer */ - virtual bool IsHoverTargetOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + virtual bool IsHoverTargetOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Returns the current Gamepad focus overlay */ - virtual vr::VROverlayHandle_t GetGamepadFocusOverlay() = 0; + /** Returns the current Gamepad focus overlay */ + virtual vr::VROverlayHandle_t GetGamepadFocusOverlay() = 0; - /** Sets the current Gamepad focus overlay */ - virtual EVROverlayError SetGamepadFocusOverlay( VROverlayHandle_t ulNewFocusOverlay ) = 0; + /** Sets the current Gamepad focus overlay */ + virtual EVROverlayError SetGamepadFocusOverlay(VROverlayHandle_t ulNewFocusOverlay) = 0; - /** Sets an overlay's neighbor. This will also set the neighbor of the "to" overlay + /** Sets an overlay's neighbor. This will also set the neighbor of the "to" overlay * to point back to the "from" overlay. If an overlay's neighbor is set to invalid both * ends will be cleared */ - virtual EVROverlayError SetOverlayNeighbor( EOverlayDirection eDirection, VROverlayHandle_t ulFrom, VROverlayHandle_t ulTo ) = 0; + virtual EVROverlayError SetOverlayNeighbor(EOverlayDirection eDirection, VROverlayHandle_t ulFrom, VROverlayHandle_t ulTo) = 0; - /** Changes the Gamepad focus from one overlay to one of its neighbors. Returns VROverlayError_NoNeighbor if there is no + /** Changes the Gamepad focus from one overlay to one of its neighbors. Returns VROverlayError_NoNeighbor if there is no * neighbor in that direction */ - virtual EVROverlayError MoveGamepadFocusToNeighbor( EOverlayDirection eDirection, VROverlayHandle_t ulFrom ) = 0; + virtual EVROverlayError MoveGamepadFocusToNeighbor(EOverlayDirection eDirection, VROverlayHandle_t ulFrom) = 0; - // --------------------------------------------- - // Overlay texture methods - // --------------------------------------------- + // --------------------------------------------- + // Overlay texture methods + // --------------------------------------------- - /** Texture to draw for the overlay. This function can only be called by the overlay's creator or renderer process (see SetOverlayRenderingPid) . + /** Texture to draw for the overlay. This function can only be called by the overlay's creator or renderer process (see SetOverlayRenderingPid) . * * OpenGL dirty state: * glBindTexture */ - virtual EVROverlayError SetOverlayTexture( VROverlayHandle_t ulOverlayHandle, const Texture_t *pTexture ) = 0; + virtual EVROverlayError SetOverlayTexture(VROverlayHandle_t ulOverlayHandle, const Texture_t *pTexture) = 0; - /** Use this to tell the overlay system to release the texture set for this overlay. */ - virtual EVROverlayError ClearOverlayTexture( VROverlayHandle_t ulOverlayHandle ) = 0; + /** Use this to tell the overlay system to release the texture set for this overlay. */ + virtual EVROverlayError ClearOverlayTexture(VROverlayHandle_t ulOverlayHandle) = 0; - /** Separate interface for providing the data as a stream of bytes, but there is an upper bound on data + /** Separate interface for providing the data as a stream of bytes, but there is an upper bound on data * that can be sent. This function can only be called by the overlay's renderer process. */ - virtual EVROverlayError SetOverlayRaw( VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unWidth, uint32_t unHeight, uint32_t unDepth ) = 0; + virtual EVROverlayError SetOverlayRaw(VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unWidth, uint32_t unHeight, uint32_t unDepth) = 0; - /** Separate interface for providing the image through a filename: can be png or jpg, and should not be bigger than 1920x1080. + /** Separate interface for providing the image through a filename: can be png or jpg, and should not be bigger than 1920x1080. * This function can only be called by the overlay's renderer process */ - virtual EVROverlayError SetOverlayFromFile( VROverlayHandle_t ulOverlayHandle, const char *pchFilePath ) = 0; + virtual EVROverlayError SetOverlayFromFile(VROverlayHandle_t ulOverlayHandle, const char *pchFilePath) = 0; - /** Get the native texture handle/device for an overlay you have created. + /** Get the native texture handle/device for an overlay you have created. * On windows this handle will be a ID3D11ShaderResourceView with a ID3D11Texture2D bound. * * The texture will always be sized to match the backing texture you supplied in SetOverlayTexture above. @@ -2928,98 +2869,97 @@ namespace vr * pNativeTextureHandle is an OUTPUT, it will be a pointer to a ID3D11ShaderResourceView *. * pNativeTextureRef is an INPUT and should be a ID3D11Resource *. The device used by pNativeTextureRef will be used to bind pNativeTextureHandle. */ - virtual EVROverlayError GetOverlayTexture( VROverlayHandle_t ulOverlayHandle, void **pNativeTextureHandle, void *pNativeTextureRef, uint32_t *pWidth, uint32_t *pHeight, uint32_t *pNativeFormat, ETextureType *pAPIType, EColorSpace *pColorSpace, VRTextureBounds_t *pTextureBounds ) = 0; + virtual EVROverlayError GetOverlayTexture(VROverlayHandle_t ulOverlayHandle, void **pNativeTextureHandle, void *pNativeTextureRef, uint32_t *pWidth, uint32_t *pHeight, uint32_t *pNativeFormat, ETextureType *pAPIType, EColorSpace *pColorSpace, VRTextureBounds_t *pTextureBounds) = 0; - /** Release the pNativeTextureHandle provided from the GetOverlayTexture call, this allows the system to free the underlying GPU resources for this object, + /** Release the pNativeTextureHandle provided from the GetOverlayTexture call, this allows the system to free the underlying GPU resources for this object, * so only do it once you stop rendering this texture. */ - virtual EVROverlayError ReleaseNativeOverlayHandle( VROverlayHandle_t ulOverlayHandle, void *pNativeTextureHandle ) = 0; + virtual EVROverlayError ReleaseNativeOverlayHandle(VROverlayHandle_t ulOverlayHandle, void *pNativeTextureHandle) = 0; - /** Get the size of the overlay texture */ - virtual EVROverlayError GetOverlayTextureSize( VROverlayHandle_t ulOverlayHandle, uint32_t *pWidth, uint32_t *pHeight ) = 0; + /** Get the size of the overlay texture */ + virtual EVROverlayError GetOverlayTextureSize(VROverlayHandle_t ulOverlayHandle, uint32_t *pWidth, uint32_t *pHeight) = 0; - // ---------------------------------------------- - // Dashboard Overlay Methods - // ---------------------------------------------- + // ---------------------------------------------- + // Dashboard Overlay Methods + // ---------------------------------------------- - /** Creates a dashboard overlay and returns its handle */ - virtual EVROverlayError CreateDashboardOverlay( const char *pchOverlayKey, const char *pchOverlayFriendlyName, VROverlayHandle_t * pMainHandle, VROverlayHandle_t *pThumbnailHandle ) = 0; + /** Creates a dashboard overlay and returns its handle */ + virtual EVROverlayError CreateDashboardOverlay(const char *pchOverlayKey, const char *pchOverlayFriendlyName, VROverlayHandle_t *pMainHandle, VROverlayHandle_t *pThumbnailHandle) = 0; - /** Returns true if the dashboard is visible */ - virtual bool IsDashboardVisible() = 0; + /** Returns true if the dashboard is visible */ + virtual bool IsDashboardVisible() = 0; - /** returns true if the dashboard is visible and the specified overlay is the active system Overlay */ - virtual bool IsActiveDashboardOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + /** returns true if the dashboard is visible and the specified overlay is the active system Overlay */ + virtual bool IsActiveDashboardOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Sets the dashboard overlay to only appear when the specified process ID has scene focus */ - virtual EVROverlayError SetDashboardOverlaySceneProcess( VROverlayHandle_t ulOverlayHandle, uint32_t unProcessId ) = 0; + /** Sets the dashboard overlay to only appear when the specified process ID has scene focus */ + virtual EVROverlayError SetDashboardOverlaySceneProcess(VROverlayHandle_t ulOverlayHandle, uint32_t unProcessId) = 0; - /** Gets the process ID that this dashboard overlay requires to have scene focus */ - virtual EVROverlayError GetDashboardOverlaySceneProcess( VROverlayHandle_t ulOverlayHandle, uint32_t *punProcessId ) = 0; + /** Gets the process ID that this dashboard overlay requires to have scene focus */ + virtual EVROverlayError GetDashboardOverlaySceneProcess(VROverlayHandle_t ulOverlayHandle, uint32_t *punProcessId) = 0; - /** Shows the dashboard. */ - virtual void ShowDashboard( const char *pchOverlayToShow ) = 0; + /** Shows the dashboard. */ + virtual void ShowDashboard(const char *pchOverlayToShow) = 0; - /** Returns the tracked device that has the laser pointer in the dashboard */ - virtual vr::TrackedDeviceIndex_t GetPrimaryDashboardDevice() = 0; + /** Returns the tracked device that has the laser pointer in the dashboard */ + virtual vr::TrackedDeviceIndex_t GetPrimaryDashboardDevice() = 0; - // --------------------------------------------- - // Keyboard methods - // --------------------------------------------- - - /** Show the virtual keyboard to accept input **/ - virtual EVROverlayError ShowKeyboard( EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32_t unCharMax, const char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue ) = 0; + // --------------------------------------------- + // Keyboard methods + // --------------------------------------------- - virtual EVROverlayError ShowKeyboardForOverlay( VROverlayHandle_t ulOverlayHandle, EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32_t unCharMax, const char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue ) = 0; + /** Show the virtual keyboard to accept input **/ + virtual EVROverlayError ShowKeyboard(EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32_t unCharMax, const char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue) = 0; - /** Get the text that was entered into the text input **/ - virtual uint32_t GetKeyboardText( VR_OUT_STRING() char *pchText, uint32_t cchText ) = 0; + virtual EVROverlayError ShowKeyboardForOverlay(VROverlayHandle_t ulOverlayHandle, EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32_t unCharMax, const char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue) = 0; - /** Hide the virtual keyboard **/ - virtual void HideKeyboard() = 0; + /** Get the text that was entered into the text input **/ + virtual uint32_t GetKeyboardText(VR_OUT_STRING() char *pchText, uint32_t cchText) = 0; - /** Set the position of the keyboard in world space **/ - virtual void SetKeyboardTransformAbsolute( ETrackingUniverseOrigin eTrackingOrigin, const HmdMatrix34_t *pmatTrackingOriginToKeyboardTransform ) = 0; + /** Hide the virtual keyboard **/ + virtual void HideKeyboard() = 0; - /** Set the position of the keyboard in overlay space by telling it to avoid a rectangle in the overlay. Rectangle coords have (0,0) in the bottom left **/ - virtual void SetKeyboardPositionForOverlay( VROverlayHandle_t ulOverlayHandle, HmdRect2_t avoidRect ) = 0; + /** Set the position of the keyboard in world space **/ + virtual void SetKeyboardTransformAbsolute(ETrackingUniverseOrigin eTrackingOrigin, const HmdMatrix34_t *pmatTrackingOriginToKeyboardTransform) = 0; - // --------------------------------------------- - // Overlay input methods - // --------------------------------------------- + /** Set the position of the keyboard in overlay space by telling it to avoid a rectangle in the overlay. Rectangle coords have (0,0) in the bottom left **/ + virtual void SetKeyboardPositionForOverlay(VROverlayHandle_t ulOverlayHandle, HmdRect2_t avoidRect) = 0; - /** Sets a list of primitives to be used for controller ray intersection + // --------------------------------------------- + // Overlay input methods + // --------------------------------------------- + + /** Sets a list of primitives to be used for controller ray intersection * typically the size of the underlying UI in pixels (not in world space). */ - virtual EVROverlayError SetOverlayIntersectionMask( VROverlayHandle_t ulOverlayHandle, VROverlayIntersectionMaskPrimitive_t *pMaskPrimitives, uint32_t unNumMaskPrimitives, uint32_t unPrimitiveSize = sizeof( VROverlayIntersectionMaskPrimitive_t ) ) = 0; + virtual EVROverlayError SetOverlayIntersectionMask(VROverlayHandle_t ulOverlayHandle, VROverlayIntersectionMaskPrimitive_t *pMaskPrimitives, uint32_t unNumMaskPrimitives, uint32_t unPrimitiveSize = sizeof(VROverlayIntersectionMaskPrimitive_t)) = 0; - virtual EVROverlayError GetOverlayFlags( VROverlayHandle_t ulOverlayHandle, uint32_t *pFlags ) = 0; + virtual EVROverlayError GetOverlayFlags(VROverlayHandle_t ulOverlayHandle, uint32_t *pFlags) = 0; - // --------------------------------------------- - // Message box methods - // --------------------------------------------- + // --------------------------------------------- + // Message box methods + // --------------------------------------------- - /** Show the message overlay. This will block and return you a result. **/ - virtual VRMessageOverlayResponse ShowMessageOverlay( const char* pchText, const char* pchCaption, const char* pchButton0Text, const char* pchButton1Text = nullptr, const char* pchButton2Text = nullptr, const char* pchButton3Text = nullptr ) = 0; + /** Show the message overlay. This will block and return you a result. **/ + virtual VRMessageOverlayResponse ShowMessageOverlay(const char *pchText, const char *pchCaption, const char *pchButton0Text, const char *pchButton1Text = nullptr, const char *pchButton2Text = nullptr, const char *pchButton3Text = nullptr) = 0; - /** If the calling process owns the overlay and it's open, this will close it. **/ - virtual void CloseMessageOverlay() = 0; - }; + /** If the calling process owns the overlay and it's open, this will close it. **/ + virtual void CloseMessageOverlay() = 0; +}; - static const char * const IVROverlay_Version = "IVROverlay_016"; +static const char *const IVROverlay_Version = "IVROverlay_016"; -} // namespace vr +} // namespace vr // ivrrendermodels.h namespace vr { +static const char *const k_pch_Controller_Component_GDC2015 = "gdc2015"; // Canonical coordinate system of the gdc 2015 wired controller, provided for backwards compatibility +static const char *const k_pch_Controller_Component_Base = "base"; // For controllers with an unambiguous 'base'. +static const char *const k_pch_Controller_Component_Tip = "tip"; // For controllers with an unambiguous 'tip' (used for 'laser-pointing') +static const char *const k_pch_Controller_Component_HandGrip = "handgrip"; // Neutral, ambidextrous hand-pose when holding controller. On plane between neutrally posed index finger and thumb +static const char *const k_pch_Controller_Component_Status = "status"; // 1:1 aspect ratio status area, with canonical [0,1] uv mapping -static const char * const k_pch_Controller_Component_GDC2015 = "gdc2015"; // Canonical coordinate system of the gdc 2015 wired controller, provided for backwards compatibility -static const char * const k_pch_Controller_Component_Base = "base"; // For controllers with an unambiguous 'base'. -static const char * const k_pch_Controller_Component_Tip = "tip"; // For controllers with an unambiguous 'tip' (used for 'laser-pointing') -static const char * const k_pch_Controller_Component_HandGrip = "handgrip"; // Neutral, ambidextrous hand-pose when holding controller. On plane between neutrally posed index finger and thumb -static const char * const k_pch_Controller_Component_Status = "status"; // 1:1 aspect ratio status area, with canonical [0,1] uv mapping - -#pragma pack( push, 8 ) +#pragma pack(push, 8) /** Errors that can occur with the VR compositor */ enum EVRRenderModelError @@ -3062,25 +3002,25 @@ struct RenderModel_ComponentState_t /** A single vertex in a render model */ struct RenderModel_Vertex_t { - HmdVector3_t vPosition; // position in meters in device space + HmdVector3_t vPosition; // position in meters in device space HmdVector3_t vNormal; float rfTextureCoord[2]; }; /** A texture map for use on a render model */ -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif struct RenderModel_TextureMap_t { - uint16_t unWidth, unHeight; // width and height of the texture map in pixels - const uint8_t *rubTextureMapData; // Map texture data. All textures are RGBA with 8 bits per channel per pixel. Data size is width * height * 4ub + uint16_t unWidth, unHeight; // width and height of the texture map in pixels + const uint8_t *rubTextureMapData; // Map texture data. All textures are RGBA with 8 bits per channel per pixel. Data size is width * height * 4ub }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif /** Session unique texture identifier. Rendermodels which share the same texture will have the same id. @@ -3090,36 +3030,34 @@ typedef int32_t TextureID_t; const TextureID_t INVALID_TEXTURE_ID = -1; -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif struct RenderModel_t { - const RenderModel_Vertex_t *rVertexData; // Vertex data for the mesh - uint32_t unVertexCount; // Number of vertices in the vertex data - const uint16_t *rIndexData; // Indices into the vertex data for each triangle - uint32_t unTriangleCount; // Number of triangles in the mesh. Index count is 3 * TriangleCount - TextureID_t diffuseTextureId; // Session unique texture identifier. Rendermodels which share the same texture will have the same id. <0 == texture not present + const RenderModel_Vertex_t *rVertexData; // Vertex data for the mesh + uint32_t unVertexCount; // Number of vertices in the vertex data + const uint16_t *rIndexData; // Indices into the vertex data for each triangle + uint32_t unTriangleCount; // Number of triangles in the mesh. Index count is 3 * TriangleCount + TextureID_t diffuseTextureId; // Session unique texture identifier. Rendermodels which share the same texture will have the same id. <0 == texture not present }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif - struct RenderModel_ControllerMode_State_t { - bool bScrollWheelVisible; // is this controller currently set to be in a scroll wheel mode + bool bScrollWheelVisible; // is this controller currently set to be in a scroll wheel mode }; -#pragma pack( pop ) +#pragma pack(pop) class IVRRenderModels { public: - /** Loads and returns a render model for use in the application. pchRenderModelName should be a render model name * from the Prop_RenderModelName_String property or an absolute path name to a render model on disk. * @@ -3129,37 +3067,36 @@ public: * * The method returns VRRenderModelError_Loading while the render model is still being loaded. * The method returns VRRenderModelError_None once loaded successfully, otherwise will return an error. */ - virtual EVRRenderModelError LoadRenderModel_Async( const char *pchRenderModelName, RenderModel_t **ppRenderModel ) = 0; + virtual EVRRenderModelError LoadRenderModel_Async(const char *pchRenderModelName, RenderModel_t **ppRenderModel) = 0; /** Frees a previously returned render model * It is safe to call this on a null ptr. */ - virtual void FreeRenderModel( RenderModel_t *pRenderModel ) = 0; + virtual void FreeRenderModel(RenderModel_t *pRenderModel) = 0; /** Loads and returns a texture for use in the application. */ - virtual EVRRenderModelError LoadTexture_Async( TextureID_t textureId, RenderModel_TextureMap_t **ppTexture ) = 0; + virtual EVRRenderModelError LoadTexture_Async(TextureID_t textureId, RenderModel_TextureMap_t **ppTexture) = 0; /** Frees a previously returned texture * It is safe to call this on a null ptr. */ - virtual void FreeTexture( RenderModel_TextureMap_t *pTexture ) = 0; + virtual void FreeTexture(RenderModel_TextureMap_t *pTexture) = 0; /** Creates a D3D11 texture and loads data into it. */ - virtual EVRRenderModelError LoadTextureD3D11_Async( TextureID_t textureId, void *pD3D11Device, void **ppD3D11Texture2D ) = 0; + virtual EVRRenderModelError LoadTextureD3D11_Async(TextureID_t textureId, void *pD3D11Device, void **ppD3D11Texture2D) = 0; /** Helper function to copy the bits into an existing texture. */ - virtual EVRRenderModelError LoadIntoTextureD3D11_Async( TextureID_t textureId, void *pDstTexture ) = 0; + virtual EVRRenderModelError LoadIntoTextureD3D11_Async(TextureID_t textureId, void *pDstTexture) = 0; /** Use this to free textures created with LoadTextureD3D11_Async instead of calling Release on them. */ - virtual void FreeTextureD3D11( void *pD3D11Texture2D ) = 0; + virtual void FreeTextureD3D11(void *pD3D11Texture2D) = 0; /** Use this to get the names of available render models. Index does not correlate to a tracked device index, but * is only used for iterating over all available render models. If the index is out of range, this function will return 0. * Otherwise, it will return the size of the buffer required for the name. */ - virtual uint32_t GetRenderModelName( uint32_t unRenderModelIndex, VR_OUT_STRING() char *pchRenderModelName, uint32_t unRenderModelNameLen ) = 0; + virtual uint32_t GetRenderModelName(uint32_t unRenderModelIndex, VR_OUT_STRING() char *pchRenderModelName, uint32_t unRenderModelNameLen) = 0; /** Returns the number of available render models. */ virtual uint32_t GetRenderModelCount() = 0; - /** Returns the number of components of the specified render model. * Components are useful when client application wish to draw, label, or otherwise interact with components of tracked objects. * Examples controller components: @@ -3167,23 +3104,23 @@ public: * non-renderable things which include coordinate systems such as 'tip', 'base', a neutral controller agnostic hand-pose * If all controller components are enumerated and rendered, it will be equivalent to drawing the traditional render model * Returns 0 if components not supported, >0 otherwise */ - virtual uint32_t GetComponentCount( const char *pchRenderModelName ) = 0; + virtual uint32_t GetComponentCount(const char *pchRenderModelName) = 0; /** Use this to get the names of available components. Index does not correlate to a tracked device index, but * is only used for iterating over all available components. If the index is out of range, this function will return 0. * Otherwise, it will return the size of the buffer required for the name. */ - virtual uint32_t GetComponentName( const char *pchRenderModelName, uint32_t unComponentIndex, VR_OUT_STRING( ) char *pchComponentName, uint32_t unComponentNameLen ) = 0; + virtual uint32_t GetComponentName(const char *pchRenderModelName, uint32_t unComponentIndex, VR_OUT_STRING() char *pchComponentName, uint32_t unComponentNameLen) = 0; /** Get the button mask for all buttons associated with this component * If no buttons (or axes) are associated with this component, return 0 * Note: multiple components may be associated with the same button. Ex: two grip buttons on a single controller. * Note: A single component may be associated with multiple buttons. Ex: A trackpad which also provides "D-pad" functionality */ - virtual uint64_t GetComponentButtonMask( const char *pchRenderModelName, const char *pchComponentName ) = 0; + virtual uint64_t GetComponentButtonMask(const char *pchRenderModelName, const char *pchComponentName) = 0; /** Use this to get the render model name for the specified rendermode/component combination, to be passed to LoadRenderModel. * If the component name is out of range, this function will return 0. * Otherwise, it will return the size of the buffer required for the name. */ - virtual uint32_t GetComponentRenderModelName( const char *pchRenderModelName, const char *pchComponentName, VR_OUT_STRING( ) char *pchComponentRenderModelName, uint32_t unComponentRenderModelNameLen ) = 0; + virtual uint32_t GetComponentRenderModelName(const char *pchRenderModelName, const char *pchComponentName, VR_OUT_STRING() char *pchComponentRenderModelName, uint32_t unComponentRenderModelNameLen) = 0; /** Use this to query information about the component, as a function of the controller state. * @@ -3193,93 +3130,87 @@ public: * If the pchRenderModelName or pchComponentName is invalid, this will return false (and transforms will be set to identity). * Otherwise, return true * Note: For dynamic objects, visibility may be dynamic. (I.e., true/false will be returned based on controller state and controller mode state ) */ - virtual bool GetComponentState( const char *pchRenderModelName, const char *pchComponentName, const vr::VRControllerState_t *pControllerState, const RenderModel_ControllerMode_State_t *pState, RenderModel_ComponentState_t *pComponentState ) = 0; + virtual bool GetComponentState(const char *pchRenderModelName, const char *pchComponentName, const vr::VRControllerState_t *pControllerState, const RenderModel_ControllerMode_State_t *pState, RenderModel_ComponentState_t *pComponentState) = 0; /** Returns true if the render model has a component with the specified name */ - virtual bool RenderModelHasComponent( const char *pchRenderModelName, const char *pchComponentName ) = 0; + virtual bool RenderModelHasComponent(const char *pchRenderModelName, const char *pchComponentName) = 0; /** Returns the URL of the thumbnail image for this rendermodel */ - virtual uint32_t GetRenderModelThumbnailURL( const char *pchRenderModelName, VR_OUT_STRING() char *pchThumbnailURL, uint32_t unThumbnailURLLen, vr::EVRRenderModelError *peError ) = 0; + virtual uint32_t GetRenderModelThumbnailURL(const char *pchRenderModelName, VR_OUT_STRING() char *pchThumbnailURL, uint32_t unThumbnailURLLen, vr::EVRRenderModelError *peError) = 0; /** Provides a render model path that will load the unskinned model if the model name provided has been replace by the user. If the model * hasn't been replaced the path value will still be a valid path to load the model. Pass this to LoadRenderModel_Async, etc. to load the * model. */ - virtual uint32_t GetRenderModelOriginalPath( const char *pchRenderModelName, VR_OUT_STRING() char *pchOriginalPath, uint32_t unOriginalPathLen, vr::EVRRenderModelError *peError ) = 0; + virtual uint32_t GetRenderModelOriginalPath(const char *pchRenderModelName, VR_OUT_STRING() char *pchOriginalPath, uint32_t unOriginalPathLen, vr::EVRRenderModelError *peError) = 0; /** Returns a string for a render model error */ - virtual const char *GetRenderModelErrorNameFromEnum( vr::EVRRenderModelError error ) = 0; + virtual const char *GetRenderModelErrorNameFromEnum(vr::EVRRenderModelError error) = 0; }; -static const char * const IVRRenderModels_Version = "IVRRenderModels_005"; - -} +static const char *const IVRRenderModels_Version = "IVRRenderModels_005"; +} // namespace vr // ivrextendeddisplay.h namespace vr { - - /** NOTE: Use of this interface is not recommended in production applications. It will not work for displays which use +/** NOTE: Use of this interface is not recommended in production applications. It will not work for displays which use * direct-to-display mode. Creating our own window is also incompatible with the VR compositor and is not available when the compositor is running. */ - class IVRExtendedDisplay - { - public: +class IVRExtendedDisplay +{ +public: + /** Size and position that the window needs to be on the VR display. */ + virtual void GetWindowBounds(int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight) = 0; - /** Size and position that the window needs to be on the VR display. */ - virtual void GetWindowBounds( int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; + /** Gets the viewport in the frame buffer to draw the output of the distortion into */ + virtual void GetEyeOutputViewport(EVREye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight) = 0; - /** Gets the viewport in the frame buffer to draw the output of the distortion into */ - virtual void GetEyeOutputViewport( EVREye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; - - /** [D3D10/11 Only] + /** [D3D10/11 Only] * Returns the adapter index and output index that the user should pass into EnumAdapters and EnumOutputs * to create the device and swap chain in DX10 and DX11. If an error occurs both indices will be set to -1. */ - virtual void GetDXGIOutputInfo( int32_t *pnAdapterIndex, int32_t *pnAdapterOutputIndex ) = 0; + virtual void GetDXGIOutputInfo(int32_t *pnAdapterIndex, int32_t *pnAdapterOutputIndex) = 0; +}; - }; - - static const char * const IVRExtendedDisplay_Version = "IVRExtendedDisplay_001"; - -} +static const char *const IVRExtendedDisplay_Version = "IVRExtendedDisplay_001"; +} // namespace vr // ivrtrackedcamera.h namespace vr { - class IVRTrackedCamera { public: /** Returns a string for an error */ - virtual const char *GetCameraErrorNameFromEnum( vr::EVRTrackedCameraError eCameraError ) = 0; + virtual const char *GetCameraErrorNameFromEnum(vr::EVRTrackedCameraError eCameraError) = 0; /** For convenience, same as tracked property request Prop_HasCamera_Bool */ - virtual vr::EVRTrackedCameraError HasCamera( vr::TrackedDeviceIndex_t nDeviceIndex, bool *pHasCamera ) = 0; + virtual vr::EVRTrackedCameraError HasCamera(vr::TrackedDeviceIndex_t nDeviceIndex, bool *pHasCamera) = 0; /** Gets size of the image frame. */ - virtual vr::EVRTrackedCameraError GetCameraFrameSize( vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, uint32_t *pnWidth, uint32_t *pnHeight, uint32_t *pnFrameBufferSize ) = 0; + virtual vr::EVRTrackedCameraError GetCameraFrameSize(vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, uint32_t *pnWidth, uint32_t *pnHeight, uint32_t *pnFrameBufferSize) = 0; - virtual vr::EVRTrackedCameraError GetCameraIntrinsics( vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, vr::HmdVector2_t *pFocalLength, vr::HmdVector2_t *pCenter ) = 0; + virtual vr::EVRTrackedCameraError GetCameraIntrinsics(vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, vr::HmdVector2_t *pFocalLength, vr::HmdVector2_t *pCenter) = 0; - virtual vr::EVRTrackedCameraError GetCameraProjection( vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, vr::HmdMatrix44_t *pProjection ) = 0; + virtual vr::EVRTrackedCameraError GetCameraProjection(vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, vr::HmdMatrix44_t *pProjection) = 0; /** Acquiring streaming service permits video streaming for the caller. Releasing hints the system that video services do not need to be maintained for this client. * If the camera has not already been activated, a one time spin up may incur some auto exposure as well as initial streaming frame delays. * The camera should be considered a global resource accessible for shared consumption but not exclusive to any caller. * The camera may go inactive due to lack of active consumers or headset idleness. */ - virtual vr::EVRTrackedCameraError AcquireVideoStreamingService( vr::TrackedDeviceIndex_t nDeviceIndex, vr::TrackedCameraHandle_t *pHandle ) = 0; - virtual vr::EVRTrackedCameraError ReleaseVideoStreamingService( vr::TrackedCameraHandle_t hTrackedCamera ) = 0; + virtual vr::EVRTrackedCameraError AcquireVideoStreamingService(vr::TrackedDeviceIndex_t nDeviceIndex, vr::TrackedCameraHandle_t *pHandle) = 0; + virtual vr::EVRTrackedCameraError ReleaseVideoStreamingService(vr::TrackedCameraHandle_t hTrackedCamera) = 0; /** Copies the image frame into a caller's provided buffer. The image data is currently provided as RGBA data, 4 bytes per pixel. * A caller can provide null for the framebuffer or frameheader if not desired. Requesting the frame header first, followed by the frame buffer allows * the caller to determine if the frame as advanced per the frame header sequence. * If there is no frame available yet, due to initial camera spinup or re-activation, the error will be VRTrackedCameraError_NoFrameAvailable. * Ideally a caller should be polling at ~16ms intervals */ - virtual vr::EVRTrackedCameraError GetVideoStreamFrameBuffer( vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, void *pFrameBuffer, uint32_t nFrameBufferSize, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize ) = 0; + virtual vr::EVRTrackedCameraError GetVideoStreamFrameBuffer(vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, void *pFrameBuffer, uint32_t nFrameBufferSize, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize) = 0; /** Gets size of the image frame. */ - virtual vr::EVRTrackedCameraError GetVideoStreamTextureSize( vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, vr::VRTextureBounds_t *pTextureBounds, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; + virtual vr::EVRTrackedCameraError GetVideoStreamTextureSize(vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, vr::VRTextureBounds_t *pTextureBounds, uint32_t *pnWidth, uint32_t *pnHeight) = 0; /** Access a shared D3D11 texture for the specified tracked camera stream. * The camera frame type VRTrackedCameraFrameType_Undistorted is not supported directly as a shared texture. It is an interior subregion of the shared texture VRTrackedCameraFrameType_MaximumUndistorted. @@ -3287,31 +3218,29 @@ public: * VRTrackedCameraFrameType_MaximumUndistorted to provide the texture. The VRTrackedCameraFrameType_MaximumUndistorted will yield an image where the invalid regions are decoded * by the alpha channel having a zero component. The valid regions all have a non-zero alpha component. The subregion as described by VRTrackedCameraFrameType_Undistorted * guarantees a rectangle where all pixels are valid. */ - virtual vr::EVRTrackedCameraError GetVideoStreamTextureD3D11( vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize ) = 0; + virtual vr::EVRTrackedCameraError GetVideoStreamTextureD3D11(vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize) = 0; /** Access a shared GL texture for the specified tracked camera stream */ - virtual vr::EVRTrackedCameraError GetVideoStreamTextureGL( vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, vr::glUInt_t *pglTextureId, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize ) = 0; - virtual vr::EVRTrackedCameraError ReleaseVideoStreamTextureGL( vr::TrackedCameraHandle_t hTrackedCamera, vr::glUInt_t glTextureId ) = 0; + virtual vr::EVRTrackedCameraError GetVideoStreamTextureGL(vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, vr::glUInt_t *pglTextureId, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize) = 0; + virtual vr::EVRTrackedCameraError ReleaseVideoStreamTextureGL(vr::TrackedCameraHandle_t hTrackedCamera, vr::glUInt_t glTextureId) = 0; }; -static const char * const IVRTrackedCamera_Version = "IVRTrackedCamera_003"; - -} // namespace vr +static const char *const IVRTrackedCamera_Version = "IVRTrackedCamera_003"; +} // namespace vr // ivrscreenshots.h namespace vr { - /** Errors that can occur with the VR compositor */ enum EVRScreenshotError { - VRScreenshotError_None = 0, - VRScreenshotError_RequestFailed = 1, - VRScreenshotError_IncompatibleVersion = 100, - VRScreenshotError_NotFound = 101, - VRScreenshotError_BufferTooSmall = 102, - VRScreenshotError_ScreenshotAlreadyInProgress = 108, + VRScreenshotError_None = 0, + VRScreenshotError_RequestFailed = 1, + VRScreenshotError_IncompatibleVersion = 100, + VRScreenshotError_NotFound = 101, + VRScreenshotError_BufferTooSmall = 102, + VRScreenshotError_ScreenshotAlreadyInProgress = 108, }; /** Allows the application to generate screenshots */ @@ -3349,7 +3278,7 @@ public: * The destination file names do not need an extension, * will be replaced with the correct one for the format * which is currently .png. */ - virtual vr::EVRScreenshotError RequestScreenshot( vr::ScreenshotHandle_t *pOutScreenshotHandle, vr::EVRScreenshotType type, const char *pchPreviewFilename, const char *pchVRFilename ) = 0; + virtual vr::EVRScreenshotError RequestScreenshot(vr::ScreenshotHandle_t *pOutScreenshotHandle, vr::EVRScreenshotType type, const char *pchPreviewFilename, const char *pchVRFilename) = 0; /** Called by the running VR application to indicate that it * wishes to be in charge of screenshots. If the @@ -3359,23 +3288,23 @@ public: * Once hooked your application will receive a * VREvent_RequestScreenshot event when the user presses the * buttons to take a screenshot. */ - virtual vr::EVRScreenshotError HookScreenshot( VR_ARRAY_COUNT( numTypes ) const vr::EVRScreenshotType *pSupportedTypes, int numTypes ) = 0; + virtual vr::EVRScreenshotError HookScreenshot(VR_ARRAY_COUNT(numTypes) const vr::EVRScreenshotType *pSupportedTypes, int numTypes) = 0; /** When your application receives a * VREvent_RequestScreenshot event, call these functions to get * the details of the screenshot request. */ - virtual vr::EVRScreenshotType GetScreenshotPropertyType( vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotError *pError ) = 0; + virtual vr::EVRScreenshotType GetScreenshotPropertyType(vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotError *pError) = 0; /** Get the filename for the preview or vr image (see * vr::EScreenshotPropertyFilenames). The return value is * the size of the string. */ - virtual uint32_t GetScreenshotPropertyFilename( vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotPropertyFilenames filenameType, VR_OUT_STRING() char *pchFilename, uint32_t cchFilename, vr::EVRScreenshotError *pError ) = 0; + virtual uint32_t GetScreenshotPropertyFilename(vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotPropertyFilenames filenameType, VR_OUT_STRING() char *pchFilename, uint32_t cchFilename, vr::EVRScreenshotError *pError) = 0; /** Call this if the application is taking the screen shot * will take more than a few ms processing. This will result * in an overlay being presented that shows a completion * bar. */ - virtual vr::EVRScreenshotError UpdateScreenshotProgress( vr::ScreenshotHandle_t screenshotHandle, float flProgress ) = 0; + virtual vr::EVRScreenshotError UpdateScreenshotProgress(vr::ScreenshotHandle_t screenshotHandle, float flProgress) = 0; /** Tells the compositor to take an internal screenshot of * type VRScreenshotType_Stereo. It will take the current @@ -3384,7 +3313,7 @@ public: * for the VR image. * This is similar to request screenshot, but doesn't ever * talk to the application, just takes the shot and submits. */ - virtual vr::EVRScreenshotError TakeStereoScreenshot( vr::ScreenshotHandle_t *pOutScreenshotHandle, const char *pchPreviewFilename, const char *pchVRFilename ) = 0; + virtual vr::EVRScreenshotError TakeStereoScreenshot(vr::ScreenshotHandle_t *pOutScreenshotHandle, const char *pchPreviewFilename, const char *pchVRFilename) = 0; /** Submit the completed screenshot. If Steam is running * this will call into the Steam client and upload the @@ -3397,67 +3326,59 @@ public: * screenshotHandle can be k_unScreenshotHandleInvalid if this * was a new shot taking by the app to be saved and not * initiated by a user (achievement earned or something) */ - virtual vr::EVRScreenshotError SubmitScreenshot( vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotType type, const char *pchSourcePreviewFilename, const char *pchSourceVRFilename ) = 0; + virtual vr::EVRScreenshotError SubmitScreenshot(vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotType type, const char *pchSourcePreviewFilename, const char *pchSourceVRFilename) = 0; }; -static const char * const IVRScreenshots_Version = "IVRScreenshots_001"; - -} // namespace vr - +static const char *const IVRScreenshots_Version = "IVRScreenshots_001"; +} // namespace vr // ivrresources.h namespace vr { - class IVRResources { public: - // ------------------------------------ // Shared Resource Methods // ------------------------------------ /** Loads the specified resource into the provided buffer if large enough. * Returns the size in bytes of the buffer required to hold the specified resource. */ - virtual uint32_t LoadSharedResource( const char *pchResourceName, char *pchBuffer, uint32_t unBufferLen ) = 0; + virtual uint32_t LoadSharedResource(const char *pchResourceName, char *pchBuffer, uint32_t unBufferLen) = 0; /** Provides the full path to the specified resource. Resource names can include named directories for * drivers and other things, and this resolves all of those and returns the actual physical path. * pchResourceTypeDirectory is the subdirectory of resources to look in. */ - virtual uint32_t GetResourceFullPath( const char *pchResourceName, const char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen ) = 0; + virtual uint32_t GetResourceFullPath(const char *pchResourceName, const char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen) = 0; }; -static const char * const IVRResources_Version = "IVRResources_001"; +static const char *const IVRResources_Version = "IVRResources_001"; - -} +} // namespace vr // ivrdrivermanager.h namespace vr { - class IVRDriverManager { public: virtual uint32_t GetDriverCount() const = 0; /** Returns the length of the number of bytes necessary to hold this string including the trailing null. */ - virtual uint32_t GetDriverName( vr::DriverId_t nDriver, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize ) = 0; + virtual uint32_t GetDriverName(vr::DriverId_t nDriver, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize) = 0; }; -static const char * const IVRDriverManager_Version = "IVRDriverManager_001"; - -} // namespace vr +static const char *const IVRDriverManager_Version = "IVRDriverManager_001"; +} // namespace vr // End -#endif // _OPENVR_API - +#endif // _OPENVR_API namespace vr { - /** Finds the active installation of the VR API and initializes it. The provided path must be absolute +/** Finds the active installation of the VR API and initializes it. The provided path must be absolute * or relative to the current working directory. These are the local install versions of the equivalent * functions in steamvr.h and will work without a local Steam install. * @@ -3466,312 +3387,312 @@ namespace vr * * pStartupInfo is reserved for future use. */ - inline IVRSystem *VR_Init( EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo = nullptr ); +inline IVRSystem *VR_Init(EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo = nullptr); - /** unloads vrclient.dll. Any interface pointers from the interface are +/** unloads vrclient.dll. Any interface pointers from the interface are * invalid after this point */ - inline void VR_Shutdown(); +inline void VR_Shutdown(); - /** Returns true if there is an HMD attached. This check is as lightweight as possible and +/** Returns true if there is an HMD attached. This check is as lightweight as possible and * can be called outside of VR_Init/VR_Shutdown. It should be used when an application wants * to know if initializing VR is a possibility but isn't ready to take that step yet. */ - VR_INTERFACE bool VR_CALLTYPE VR_IsHmdPresent(); +VR_INTERFACE bool VR_CALLTYPE VR_IsHmdPresent(); - /** Returns true if the OpenVR runtime is installed. */ - VR_INTERFACE bool VR_CALLTYPE VR_IsRuntimeInstalled(); +/** Returns true if the OpenVR runtime is installed. */ +VR_INTERFACE bool VR_CALLTYPE VR_IsRuntimeInstalled(); - /** Returns where the OpenVR runtime is installed. */ - VR_INTERFACE const char *VR_CALLTYPE VR_RuntimePath(); +/** Returns where the OpenVR runtime is installed. */ +VR_INTERFACE const char *VR_CALLTYPE VR_RuntimePath(); - /** Returns the name of the enum value for an EVRInitError. This function may be called outside of VR_Init()/VR_Shutdown(). */ - VR_INTERFACE const char *VR_CALLTYPE VR_GetVRInitErrorAsSymbol( EVRInitError error ); +/** Returns the name of the enum value for an EVRInitError. This function may be called outside of VR_Init()/VR_Shutdown(). */ +VR_INTERFACE const char *VR_CALLTYPE VR_GetVRInitErrorAsSymbol(EVRInitError error); - /** Returns an English string for an EVRInitError. Applications should call VR_GetVRInitErrorAsSymbol instead and +/** Returns an English string for an EVRInitError. Applications should call VR_GetVRInitErrorAsSymbol instead and * use that as a key to look up their own localized error message. This function may be called outside of VR_Init()/VR_Shutdown(). */ - VR_INTERFACE const char *VR_CALLTYPE VR_GetVRInitErrorAsEnglishDescription( EVRInitError error ); +VR_INTERFACE const char *VR_CALLTYPE VR_GetVRInitErrorAsEnglishDescription(EVRInitError error); - /** Returns the interface of the specified version. This method must be called after VR_Init. The +/** Returns the interface of the specified version. This method must be called after VR_Init. The * pointer returned is valid until VR_Shutdown is called. */ - VR_INTERFACE void *VR_CALLTYPE VR_GetGenericInterface( const char *pchInterfaceVersion, EVRInitError *peError ); +VR_INTERFACE void *VR_CALLTYPE VR_GetGenericInterface(const char *pchInterfaceVersion, EVRInitError *peError); - /** Returns whether the interface of the specified version exists. +/** Returns whether the interface of the specified version exists. */ - VR_INTERFACE bool VR_CALLTYPE VR_IsInterfaceVersionValid( const char *pchInterfaceVersion ); +VR_INTERFACE bool VR_CALLTYPE VR_IsInterfaceVersionValid(const char *pchInterfaceVersion); - /** Returns a token that represents whether the VR interface handles need to be reloaded */ - VR_INTERFACE uint32_t VR_CALLTYPE VR_GetInitToken(); +/** Returns a token that represents whether the VR interface handles need to be reloaded */ +VR_INTERFACE uint32_t VR_CALLTYPE VR_GetInitToken(); - // These typedefs allow old enum names from SDK 0.9.11 to be used in applications. - // They will go away in the future. - typedef EVRInitError HmdError; - typedef EVREye Hmd_Eye; - typedef EColorSpace ColorSpace; - typedef ETrackingResult HmdTrackingResult; - typedef ETrackedDeviceClass TrackedDeviceClass; - typedef ETrackingUniverseOrigin TrackingUniverseOrigin; - typedef ETrackedDeviceProperty TrackedDeviceProperty; - typedef ETrackedPropertyError TrackedPropertyError; - typedef EVRSubmitFlags VRSubmitFlags_t; - typedef EVRState VRState_t; - typedef ECollisionBoundsStyle CollisionBoundsStyle_t; - typedef EVROverlayError VROverlayError; - typedef EVRFirmwareError VRFirmwareError; - typedef EVRCompositorError VRCompositorError; - typedef EVRScreenshotError VRScreenshotsError; +// These typedefs allow old enum names from SDK 0.9.11 to be used in applications. +// They will go away in the future. +typedef EVRInitError HmdError; +typedef EVREye Hmd_Eye; +typedef EColorSpace ColorSpace; +typedef ETrackingResult HmdTrackingResult; +typedef ETrackedDeviceClass TrackedDeviceClass; +typedef ETrackingUniverseOrigin TrackingUniverseOrigin; +typedef ETrackedDeviceProperty TrackedDeviceProperty; +typedef ETrackedPropertyError TrackedPropertyError; +typedef EVRSubmitFlags VRSubmitFlags_t; +typedef EVRState VRState_t; +typedef ECollisionBoundsStyle CollisionBoundsStyle_t; +typedef EVROverlayError VROverlayError; +typedef EVRFirmwareError VRFirmwareError; +typedef EVRCompositorError VRCompositorError; +typedef EVRScreenshotError VRScreenshotsError; - inline uint32_t &VRToken() - { - static uint32_t token; - return token; - } - - class COpenVRContext - { - public: - COpenVRContext() { Clear(); } - void Clear(); - - inline void CheckClear() - { - if ( VRToken() != VR_GetInitToken() ) - { - Clear(); - VRToken() = VR_GetInitToken(); - } - } - - IVRSystem *VRSystem() - { - CheckClear(); - if ( m_pVRSystem == nullptr ) - { - EVRInitError eError; - m_pVRSystem = ( IVRSystem * )VR_GetGenericInterface( IVRSystem_Version, &eError ); - } - return m_pVRSystem; - } - IVRChaperone *VRChaperone() - { - CheckClear(); - if ( m_pVRChaperone == nullptr ) - { - EVRInitError eError; - m_pVRChaperone = ( IVRChaperone * )VR_GetGenericInterface( IVRChaperone_Version, &eError ); - } - return m_pVRChaperone; - } - - IVRChaperoneSetup *VRChaperoneSetup() - { - CheckClear(); - if ( m_pVRChaperoneSetup == nullptr ) - { - EVRInitError eError; - m_pVRChaperoneSetup = ( IVRChaperoneSetup * )VR_GetGenericInterface( IVRChaperoneSetup_Version, &eError ); - } - return m_pVRChaperoneSetup; - } - - IVRCompositor *VRCompositor() - { - CheckClear(); - if ( m_pVRCompositor == nullptr ) - { - EVRInitError eError; - m_pVRCompositor = ( IVRCompositor * )VR_GetGenericInterface( IVRCompositor_Version, &eError ); - } - return m_pVRCompositor; - } - - IVROverlay *VROverlay() - { - CheckClear(); - if ( m_pVROverlay == nullptr ) - { - EVRInitError eError; - m_pVROverlay = ( IVROverlay * )VR_GetGenericInterface( IVROverlay_Version, &eError ); - } - return m_pVROverlay; - } - - IVRResources *VRResources() - { - CheckClear(); - if ( m_pVRResources == nullptr ) - { - EVRInitError eError; - m_pVRResources = (IVRResources *)VR_GetGenericInterface( IVRResources_Version, &eError ); - } - return m_pVRResources; - } - - IVRScreenshots *VRScreenshots() - { - CheckClear(); - if ( m_pVRScreenshots == nullptr ) - { - EVRInitError eError; - m_pVRScreenshots = ( IVRScreenshots * )VR_GetGenericInterface( IVRScreenshots_Version, &eError ); - } - return m_pVRScreenshots; - } - - IVRRenderModels *VRRenderModels() - { - CheckClear(); - if ( m_pVRRenderModels == nullptr ) - { - EVRInitError eError; - m_pVRRenderModels = ( IVRRenderModels * )VR_GetGenericInterface( IVRRenderModels_Version, &eError ); - } - return m_pVRRenderModels; - } - - IVRExtendedDisplay *VRExtendedDisplay() - { - CheckClear(); - if ( m_pVRExtendedDisplay == nullptr ) - { - EVRInitError eError; - m_pVRExtendedDisplay = ( IVRExtendedDisplay * )VR_GetGenericInterface( IVRExtendedDisplay_Version, &eError ); - } - return m_pVRExtendedDisplay; - } - - IVRSettings *VRSettings() - { - CheckClear(); - if ( m_pVRSettings == nullptr ) - { - EVRInitError eError; - m_pVRSettings = ( IVRSettings * )VR_GetGenericInterface( IVRSettings_Version, &eError ); - } - return m_pVRSettings; - } - - IVRApplications *VRApplications() - { - CheckClear(); - if ( m_pVRApplications == nullptr ) - { - EVRInitError eError; - m_pVRApplications = ( IVRApplications * )VR_GetGenericInterface( IVRApplications_Version, &eError ); - } - return m_pVRApplications; - } - - IVRTrackedCamera *VRTrackedCamera() - { - CheckClear(); - if ( m_pVRTrackedCamera == nullptr ) - { - EVRInitError eError; - m_pVRTrackedCamera = ( IVRTrackedCamera * )VR_GetGenericInterface( IVRTrackedCamera_Version, &eError ); - } - return m_pVRTrackedCamera; - } - - IVRDriverManager *VRDriverManager() - { - CheckClear(); - if ( !m_pVRDriverManager ) - { - EVRInitError eError; - m_pVRDriverManager = ( IVRDriverManager * )VR_GetGenericInterface( IVRDriverManager_Version, &eError ); - } - return m_pVRDriverManager; - } - - private: - IVRSystem *m_pVRSystem; - IVRChaperone *m_pVRChaperone; - IVRChaperoneSetup *m_pVRChaperoneSetup; - IVRCompositor *m_pVRCompositor; - IVROverlay *m_pVROverlay; - IVRResources *m_pVRResources; - IVRRenderModels *m_pVRRenderModels; - IVRExtendedDisplay *m_pVRExtendedDisplay; - IVRSettings *m_pVRSettings; - IVRApplications *m_pVRApplications; - IVRTrackedCamera *m_pVRTrackedCamera; - IVRScreenshots *m_pVRScreenshots; - IVRDriverManager *m_pVRDriverManager; - }; - - inline COpenVRContext &OpenVRInternal_ModuleContext() - { - static void *ctx[ sizeof( COpenVRContext ) / sizeof( void * ) ]; - return *( COpenVRContext * )ctx; // bypass zero-init constructor - } - - inline IVRSystem *VR_CALLTYPE VRSystem() { return OpenVRInternal_ModuleContext().VRSystem(); } - inline IVRChaperone *VR_CALLTYPE VRChaperone() { return OpenVRInternal_ModuleContext().VRChaperone(); } - inline IVRChaperoneSetup *VR_CALLTYPE VRChaperoneSetup() { return OpenVRInternal_ModuleContext().VRChaperoneSetup(); } - inline IVRCompositor *VR_CALLTYPE VRCompositor() { return OpenVRInternal_ModuleContext().VRCompositor(); } - inline IVROverlay *VR_CALLTYPE VROverlay() { return OpenVRInternal_ModuleContext().VROverlay(); } - inline IVRScreenshots *VR_CALLTYPE VRScreenshots() { return OpenVRInternal_ModuleContext().VRScreenshots(); } - inline IVRRenderModels *VR_CALLTYPE VRRenderModels() { return OpenVRInternal_ModuleContext().VRRenderModels(); } - inline IVRApplications *VR_CALLTYPE VRApplications() { return OpenVRInternal_ModuleContext().VRApplications(); } - inline IVRSettings *VR_CALLTYPE VRSettings() { return OpenVRInternal_ModuleContext().VRSettings(); } - inline IVRResources *VR_CALLTYPE VRResources() { return OpenVRInternal_ModuleContext().VRResources(); } - inline IVRExtendedDisplay *VR_CALLTYPE VRExtendedDisplay() { return OpenVRInternal_ModuleContext().VRExtendedDisplay(); } - inline IVRTrackedCamera *VR_CALLTYPE VRTrackedCamera() { return OpenVRInternal_ModuleContext().VRTrackedCamera(); } - inline IVRDriverManager *VR_CALLTYPE VRDriverManager() { return OpenVRInternal_ModuleContext().VRDriverManager(); } - - inline void COpenVRContext::Clear() - { - m_pVRSystem = nullptr; - m_pVRChaperone = nullptr; - m_pVRChaperoneSetup = nullptr; - m_pVRCompositor = nullptr; - m_pVROverlay = nullptr; - m_pVRRenderModels = nullptr; - m_pVRExtendedDisplay = nullptr; - m_pVRSettings = nullptr; - m_pVRApplications = nullptr; - m_pVRTrackedCamera = nullptr; - m_pVRResources = nullptr; - m_pVRScreenshots = nullptr; - m_pVRDriverManager = nullptr; - } - - VR_INTERFACE uint32_t VR_CALLTYPE VR_InitInternal2( EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo ); - VR_INTERFACE void VR_CALLTYPE VR_ShutdownInternal(); - - /** Finds the active installation of vrclient.dll and initializes it */ - inline IVRSystem *VR_Init( EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo ) - { - IVRSystem *pVRSystem = nullptr; - - EVRInitError eError; - VRToken() = VR_InitInternal2( &eError, eApplicationType, pStartupInfo ); - COpenVRContext &ctx = OpenVRInternal_ModuleContext(); - ctx.Clear(); - - if ( eError == VRInitError_None ) - { - if ( VR_IsInterfaceVersionValid( IVRSystem_Version ) ) - { - pVRSystem = VRSystem(); - } - else - { - VR_ShutdownInternal(); - eError = VRInitError_Init_InterfaceNotFound; - } - } - - if ( peError ) - *peError = eError; - return pVRSystem; - } - - /** unloads vrclient.dll. Any interface pointers from the interface are - * invalid after this point */ - inline void VR_Shutdown() - { - VR_ShutdownInternal(); - } +inline uint32_t &VRToken() +{ + static uint32_t token; + return token; } + +class COpenVRContext +{ +public: + COpenVRContext() { Clear(); } + void Clear(); + + inline void CheckClear() + { + if (VRToken() != VR_GetInitToken()) + { + Clear(); + VRToken() = VR_GetInitToken(); + } + } + + IVRSystem *VRSystem() + { + CheckClear(); + if (m_pVRSystem == nullptr) + { + EVRInitError eError; + m_pVRSystem = (IVRSystem *)VR_GetGenericInterface(IVRSystem_Version, &eError); + } + return m_pVRSystem; + } + IVRChaperone *VRChaperone() + { + CheckClear(); + if (m_pVRChaperone == nullptr) + { + EVRInitError eError; + m_pVRChaperone = (IVRChaperone *)VR_GetGenericInterface(IVRChaperone_Version, &eError); + } + return m_pVRChaperone; + } + + IVRChaperoneSetup *VRChaperoneSetup() + { + CheckClear(); + if (m_pVRChaperoneSetup == nullptr) + { + EVRInitError eError; + m_pVRChaperoneSetup = (IVRChaperoneSetup *)VR_GetGenericInterface(IVRChaperoneSetup_Version, &eError); + } + return m_pVRChaperoneSetup; + } + + IVRCompositor *VRCompositor() + { + CheckClear(); + if (m_pVRCompositor == nullptr) + { + EVRInitError eError; + m_pVRCompositor = (IVRCompositor *)VR_GetGenericInterface(IVRCompositor_Version, &eError); + } + return m_pVRCompositor; + } + + IVROverlay *VROverlay() + { + CheckClear(); + if (m_pVROverlay == nullptr) + { + EVRInitError eError; + m_pVROverlay = (IVROverlay *)VR_GetGenericInterface(IVROverlay_Version, &eError); + } + return m_pVROverlay; + } + + IVRResources *VRResources() + { + CheckClear(); + if (m_pVRResources == nullptr) + { + EVRInitError eError; + m_pVRResources = (IVRResources *)VR_GetGenericInterface(IVRResources_Version, &eError); + } + return m_pVRResources; + } + + IVRScreenshots *VRScreenshots() + { + CheckClear(); + if (m_pVRScreenshots == nullptr) + { + EVRInitError eError; + m_pVRScreenshots = (IVRScreenshots *)VR_GetGenericInterface(IVRScreenshots_Version, &eError); + } + return m_pVRScreenshots; + } + + IVRRenderModels *VRRenderModels() + { + CheckClear(); + if (m_pVRRenderModels == nullptr) + { + EVRInitError eError; + m_pVRRenderModels = (IVRRenderModels *)VR_GetGenericInterface(IVRRenderModels_Version, &eError); + } + return m_pVRRenderModels; + } + + IVRExtendedDisplay *VRExtendedDisplay() + { + CheckClear(); + if (m_pVRExtendedDisplay == nullptr) + { + EVRInitError eError; + m_pVRExtendedDisplay = (IVRExtendedDisplay *)VR_GetGenericInterface(IVRExtendedDisplay_Version, &eError); + } + return m_pVRExtendedDisplay; + } + + IVRSettings *VRSettings() + { + CheckClear(); + if (m_pVRSettings == nullptr) + { + EVRInitError eError; + m_pVRSettings = (IVRSettings *)VR_GetGenericInterface(IVRSettings_Version, &eError); + } + return m_pVRSettings; + } + + IVRApplications *VRApplications() + { + CheckClear(); + if (m_pVRApplications == nullptr) + { + EVRInitError eError; + m_pVRApplications = (IVRApplications *)VR_GetGenericInterface(IVRApplications_Version, &eError); + } + return m_pVRApplications; + } + + IVRTrackedCamera *VRTrackedCamera() + { + CheckClear(); + if (m_pVRTrackedCamera == nullptr) + { + EVRInitError eError; + m_pVRTrackedCamera = (IVRTrackedCamera *)VR_GetGenericInterface(IVRTrackedCamera_Version, &eError); + } + return m_pVRTrackedCamera; + } + + IVRDriverManager *VRDriverManager() + { + CheckClear(); + if (!m_pVRDriverManager) + { + EVRInitError eError; + m_pVRDriverManager = (IVRDriverManager *)VR_GetGenericInterface(IVRDriverManager_Version, &eError); + } + return m_pVRDriverManager; + } + +private: + IVRSystem *m_pVRSystem; + IVRChaperone *m_pVRChaperone; + IVRChaperoneSetup *m_pVRChaperoneSetup; + IVRCompositor *m_pVRCompositor; + IVROverlay *m_pVROverlay; + IVRResources *m_pVRResources; + IVRRenderModels *m_pVRRenderModels; + IVRExtendedDisplay *m_pVRExtendedDisplay; + IVRSettings *m_pVRSettings; + IVRApplications *m_pVRApplications; + IVRTrackedCamera *m_pVRTrackedCamera; + IVRScreenshots *m_pVRScreenshots; + IVRDriverManager *m_pVRDriverManager; +}; + +inline COpenVRContext &OpenVRInternal_ModuleContext() +{ + static void *ctx[sizeof(COpenVRContext) / sizeof(void *)]; + return *(COpenVRContext *)ctx; // bypass zero-init constructor +} + +inline IVRSystem *VR_CALLTYPE VRSystem() { return OpenVRInternal_ModuleContext().VRSystem(); } +inline IVRChaperone *VR_CALLTYPE VRChaperone() { return OpenVRInternal_ModuleContext().VRChaperone(); } +inline IVRChaperoneSetup *VR_CALLTYPE VRChaperoneSetup() { return OpenVRInternal_ModuleContext().VRChaperoneSetup(); } +inline IVRCompositor *VR_CALLTYPE VRCompositor() { return OpenVRInternal_ModuleContext().VRCompositor(); } +inline IVROverlay *VR_CALLTYPE VROverlay() { return OpenVRInternal_ModuleContext().VROverlay(); } +inline IVRScreenshots *VR_CALLTYPE VRScreenshots() { return OpenVRInternal_ModuleContext().VRScreenshots(); } +inline IVRRenderModels *VR_CALLTYPE VRRenderModels() { return OpenVRInternal_ModuleContext().VRRenderModels(); } +inline IVRApplications *VR_CALLTYPE VRApplications() { return OpenVRInternal_ModuleContext().VRApplications(); } +inline IVRSettings *VR_CALLTYPE VRSettings() { return OpenVRInternal_ModuleContext().VRSettings(); } +inline IVRResources *VR_CALLTYPE VRResources() { return OpenVRInternal_ModuleContext().VRResources(); } +inline IVRExtendedDisplay *VR_CALLTYPE VRExtendedDisplay() { return OpenVRInternal_ModuleContext().VRExtendedDisplay(); } +inline IVRTrackedCamera *VR_CALLTYPE VRTrackedCamera() { return OpenVRInternal_ModuleContext().VRTrackedCamera(); } +inline IVRDriverManager *VR_CALLTYPE VRDriverManager() { return OpenVRInternal_ModuleContext().VRDriverManager(); } + +inline void COpenVRContext::Clear() +{ + m_pVRSystem = nullptr; + m_pVRChaperone = nullptr; + m_pVRChaperoneSetup = nullptr; + m_pVRCompositor = nullptr; + m_pVROverlay = nullptr; + m_pVRRenderModels = nullptr; + m_pVRExtendedDisplay = nullptr; + m_pVRSettings = nullptr; + m_pVRApplications = nullptr; + m_pVRTrackedCamera = nullptr; + m_pVRResources = nullptr; + m_pVRScreenshots = nullptr; + m_pVRDriverManager = nullptr; +} + +VR_INTERFACE uint32_t VR_CALLTYPE VR_InitInternal2(EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo); +VR_INTERFACE void VR_CALLTYPE VR_ShutdownInternal(); + +/** Finds the active installation of vrclient.dll and initializes it */ +inline IVRSystem *VR_Init(EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo) +{ + IVRSystem *pVRSystem = nullptr; + + EVRInitError eError; + VRToken() = VR_InitInternal2(&eError, eApplicationType, pStartupInfo); + COpenVRContext &ctx = OpenVRInternal_ModuleContext(); + ctx.Clear(); + + if (eError == VRInitError_None) + { + if (VR_IsInterfaceVersionValid(IVRSystem_Version)) + { + pVRSystem = VRSystem(); + } + else + { + VR_ShutdownInternal(); + eError = VRInitError_Init_InterfaceNotFound; + } + } + + if (peError) + *peError = eError; + return pVRSystem; +} + +/** unloads vrclient.dll. Any interface pointers from the interface are + * invalid after this point */ +inline void VR_Shutdown() +{ + VR_ShutdownInternal(); +} +} // namespace vr diff --git a/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Headers/openvr_capi.h b/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Headers/openvr_capi.h index 50f895869..245365f4e 100644 --- a/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Headers/openvr_capi.h +++ b/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Headers/openvr_capi.h @@ -7,7 +7,7 @@ #ifndef __OPENVR_API_FLAT_H__ #define __OPENVR_API_FLAT_H__ -#if defined( _WIN32 ) || defined( __clang__ ) +#if defined(_WIN32) || defined(__clang__) #pragma once #endif @@ -17,38 +17,38 @@ #define EXTERN_C #endif -#if defined( _WIN32 ) +#if defined(_WIN32) #define OPENVR_FNTABLE_CALLTYPE __stdcall #else -#define OPENVR_FNTABLE_CALLTYPE +#define OPENVR_FNTABLE_CALLTYPE #endif // OPENVR API export macro -#if defined( _WIN32 ) && !defined( _X360 ) - #if defined( OPENVR_API_EXPORTS ) - #define S_API EXTERN_C __declspec( dllexport ) - #elif defined( OPENVR_API_NODLL ) - #define S_API EXTERN_C - #else - #define S_API extern "C" __declspec( dllimport ) - #endif // OPENVR_API_EXPORTS -#elif defined( __GNUC__ ) - #if defined( OPENVR_API_EXPORTS ) - #define S_API EXTERN_C __attribute__ ((visibility("default"))) - #else - #define S_API EXTERN_C - #endif // OPENVR_API_EXPORTS -#else // !WIN32 - #if defined( OPENVR_API_EXPORTS ) - #define S_API EXTERN_C - #else - #define S_API EXTERN_C - #endif // OPENVR_API_EXPORTS +#if defined(_WIN32) && !defined(_X360) +#if defined(OPENVR_API_EXPORTS) +#define S_API EXTERN_C __declspec(dllexport) +#elif defined(OPENVR_API_NODLL) +#define S_API EXTERN_C +#else +#define S_API extern "C" __declspec(dllimport) +#endif // OPENVR_API_EXPORTS +#elif defined(__GNUC__) +#if defined(OPENVR_API_EXPORTS) +#define S_API EXTERN_C __attribute__((visibility("default"))) +#else +#define S_API EXTERN_C +#endif // OPENVR_API_EXPORTS +#else // !WIN32 +#if defined(OPENVR_API_EXPORTS) +#define S_API EXTERN_C +#else +#define S_API EXTERN_C +#endif // OPENVR_API_EXPORTS #endif #include -#if defined( __WIN32 ) +#if defined(__WIN32) typedef char bool; #else #include @@ -60,7 +60,6 @@ typedef uint64_t VRActionHandle_t; typedef uint64_t VRActionSetHandle_t; typedef uint64_t VRInputOriginHandle_t; - // OpenVR Constants static const unsigned int k_nDriverNone = 4294967295; @@ -87,157 +86,157 @@ static const unsigned int k_unMaxPropertyStringSize = 32768; static const unsigned int k_unControllerStateAxisCount = 5; static const unsigned long k_ulOverlayHandleInvalid = 0; static const unsigned int k_unScreenshotHandleInvalid = 0; -static const char * IVRSystem_Version = "IVRSystem_017"; -static const char * IVRExtendedDisplay_Version = "IVRExtendedDisplay_001"; -static const char * IVRTrackedCamera_Version = "IVRTrackedCamera_003"; +static const char *IVRSystem_Version = "IVRSystem_017"; +static const char *IVRExtendedDisplay_Version = "IVRExtendedDisplay_001"; +static const char *IVRTrackedCamera_Version = "IVRTrackedCamera_003"; static const unsigned int k_unMaxApplicationKeyLength = 128; -static const char * k_pch_MimeType_HomeApp = "vr/home"; -static const char * k_pch_MimeType_GameTheater = "vr/game_theater"; -static const char * IVRApplications_Version = "IVRApplications_006"; -static const char * IVRChaperone_Version = "IVRChaperone_003"; -static const char * IVRChaperoneSetup_Version = "IVRChaperoneSetup_005"; -static const char * IVRCompositor_Version = "IVRCompositor_021"; +static const char *k_pch_MimeType_HomeApp = "vr/home"; +static const char *k_pch_MimeType_GameTheater = "vr/game_theater"; +static const char *IVRApplications_Version = "IVRApplications_006"; +static const char *IVRChaperone_Version = "IVRChaperone_003"; +static const char *IVRChaperoneSetup_Version = "IVRChaperoneSetup_005"; +static const char *IVRCompositor_Version = "IVRCompositor_021"; static const unsigned int k_unVROverlayMaxKeyLength = 128; static const unsigned int k_unVROverlayMaxNameLength = 128; static const unsigned int k_unMaxOverlayCount = 64; static const unsigned int k_unMaxOverlayIntersectionMaskPrimitivesCount = 32; -static const char * IVROverlay_Version = "IVROverlay_016"; -static const char * k_pch_Controller_Component_GDC2015 = "gdc2015"; -static const char * k_pch_Controller_Component_Base = "base"; -static const char * k_pch_Controller_Component_Tip = "tip"; -static const char * k_pch_Controller_Component_HandGrip = "handgrip"; -static const char * k_pch_Controller_Component_Status = "status"; -static const char * IVRRenderModels_Version = "IVRRenderModels_005"; +static const char *IVROverlay_Version = "IVROverlay_016"; +static const char *k_pch_Controller_Component_GDC2015 = "gdc2015"; +static const char *k_pch_Controller_Component_Base = "base"; +static const char *k_pch_Controller_Component_Tip = "tip"; +static const char *k_pch_Controller_Component_HandGrip = "handgrip"; +static const char *k_pch_Controller_Component_Status = "status"; +static const char *IVRRenderModels_Version = "IVRRenderModels_005"; static const unsigned int k_unNotificationTextMaxSize = 256; -static const char * IVRNotifications_Version = "IVRNotifications_002"; +static const char *IVRNotifications_Version = "IVRNotifications_002"; static const unsigned int k_unMaxSettingsKeyLength = 128; -static const char * IVRSettings_Version = "IVRSettings_002"; -static const char * k_pch_SteamVR_Section = "steamvr"; -static const char * k_pch_SteamVR_RequireHmd_String = "requireHmd"; -static const char * k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; -static const char * k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; -static const char * k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; -static const char * k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; -static const char * k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; -static const char * k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; -static const char * k_pch_SteamVR_SendSystemButtonToAllApps_Bool = "sendSystemButtonToAllApps"; -static const char * k_pch_SteamVR_LogLevel_Int32 = "loglevel"; -static const char * k_pch_SteamVR_IPD_Float = "ipd"; -static const char * k_pch_SteamVR_Background_String = "background"; -static const char * k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; -static const char * k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; -static const char * k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; -static const char * k_pch_SteamVR_GridColor_String = "gridColor"; -static const char * k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; -static const char * k_pch_SteamVR_ShowStage_Bool = "showStage"; -static const char * k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; -static const char * k_pch_SteamVR_DirectMode_Bool = "directMode"; -static const char * k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; -static const char * k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; -static const char * k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; -static const char * k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; -static const char * k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; -static const char * k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; -static const char * k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; -static const char * k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; -static const char * k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; -static const char * k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; -static const char * k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; -static const char * k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; -static const char * k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; -static const char * k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; -static const char * k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; -static const char * k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; -static const char * k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; -static const char * k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; -static const char * k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; -static const char * k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; -static const char * k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; -static const char * k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; -static const char * k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; -static const char * k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; -static const char * k_pch_Lighthouse_Section = "driver_lighthouse"; -static const char * k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; -static const char * k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; -static const char * k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; -static const char * k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; -static const char * k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; -static const char * k_pch_Null_Section = "driver_null"; -static const char * k_pch_Null_SerialNumber_String = "serialNumber"; -static const char * k_pch_Null_ModelNumber_String = "modelNumber"; -static const char * k_pch_Null_WindowX_Int32 = "windowX"; -static const char * k_pch_Null_WindowY_Int32 = "windowY"; -static const char * k_pch_Null_WindowWidth_Int32 = "windowWidth"; -static const char * k_pch_Null_WindowHeight_Int32 = "windowHeight"; -static const char * k_pch_Null_RenderWidth_Int32 = "renderWidth"; -static const char * k_pch_Null_RenderHeight_Int32 = "renderHeight"; -static const char * k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; -static const char * k_pch_Null_DisplayFrequency_Float = "displayFrequency"; -static const char * k_pch_UserInterface_Section = "userinterface"; -static const char * k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; -static const char * k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; -static const char * k_pch_UserInterface_Screenshots_Bool = "screenshots"; -static const char * k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; -static const char * k_pch_Notifications_Section = "notifications"; -static const char * k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; -static const char * k_pch_Keyboard_Section = "keyboard"; -static const char * k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; -static const char * k_pch_Keyboard_ScaleX = "ScaleX"; -static const char * k_pch_Keyboard_ScaleY = "ScaleY"; -static const char * k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; -static const char * k_pch_Keyboard_OffsetRightX = "OffsetRightX"; -static const char * k_pch_Keyboard_OffsetY = "OffsetY"; -static const char * k_pch_Keyboard_Smoothing = "Smoothing"; -static const char * k_pch_Perf_Section = "perfcheck"; -static const char * k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; -static const char * k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; -static const char * k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; -static const char * k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; -static const char * k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; -static const char * k_pch_Perf_TestData_Float = "perfTestData"; -static const char * k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; -static const char * k_pch_CollisionBounds_Section = "collisionBounds"; -static const char * k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; -static const char * k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; -static const char * k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; -static const char * k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; -static const char * k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; -static const char * k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; -static const char * k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; -static const char * k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; -static const char * k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; -static const char * k_pch_Camera_Section = "camera"; -static const char * k_pch_Camera_EnableCamera_Bool = "enableCamera"; -static const char * k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; -static const char * k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; -static const char * k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; -static const char * k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; -static const char * k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; -static const char * k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; -static const char * k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; -static const char * k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; -static const char * k_pch_audio_Section = "audio"; -static const char * k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; -static const char * k_pch_audio_OnRecordDevice_String = "onRecordDevice"; -static const char * k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; -static const char * k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; -static const char * k_pch_audio_OffRecordDevice_String = "offRecordDevice"; -static const char * k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; -static const char * k_pch_Power_Section = "power"; -static const char * k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; -static const char * k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; -static const char * k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; -static const char * k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; -static const char * k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; -static const char * k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; -static const char * k_pch_Dashboard_Section = "dashboard"; -static const char * k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; -static const char * k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; -static const char * k_pch_modelskin_Section = "modelskins"; -static const char * k_pch_Driver_Enable_Bool = "enable"; -static const char * IVRScreenshots_Version = "IVRScreenshots_001"; -static const char * IVRResources_Version = "IVRResources_001"; -static const char * IVRDriverManager_Version = "IVRDriverManager_001"; +static const char *IVRSettings_Version = "IVRSettings_002"; +static const char *k_pch_SteamVR_Section = "steamvr"; +static const char *k_pch_SteamVR_RequireHmd_String = "requireHmd"; +static const char *k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; +static const char *k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; +static const char *k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; +static const char *k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; +static const char *k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; +static const char *k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; +static const char *k_pch_SteamVR_SendSystemButtonToAllApps_Bool = "sendSystemButtonToAllApps"; +static const char *k_pch_SteamVR_LogLevel_Int32 = "loglevel"; +static const char *k_pch_SteamVR_IPD_Float = "ipd"; +static const char *k_pch_SteamVR_Background_String = "background"; +static const char *k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; +static const char *k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; +static const char *k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; +static const char *k_pch_SteamVR_GridColor_String = "gridColor"; +static const char *k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; +static const char *k_pch_SteamVR_ShowStage_Bool = "showStage"; +static const char *k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; +static const char *k_pch_SteamVR_DirectMode_Bool = "directMode"; +static const char *k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; +static const char *k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; +static const char *k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; +static const char *k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; +static const char *k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; +static const char *k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; +static const char *k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; +static const char *k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; +static const char *k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; +static const char *k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; +static const char *k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; +static const char *k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; +static const char *k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; +static const char *k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; +static const char *k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; +static const char *k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; +static const char *k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; +static const char *k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; +static const char *k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; +static const char *k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; +static const char *k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; +static const char *k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; +static const char *k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; +static const char *k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; +static const char *k_pch_Lighthouse_Section = "driver_lighthouse"; +static const char *k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; +static const char *k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; +static const char *k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; +static const char *k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; +static const char *k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; +static const char *k_pch_Null_Section = "driver_null"; +static const char *k_pch_Null_SerialNumber_String = "serialNumber"; +static const char *k_pch_Null_ModelNumber_String = "modelNumber"; +static const char *k_pch_Null_WindowX_Int32 = "windowX"; +static const char *k_pch_Null_WindowY_Int32 = "windowY"; +static const char *k_pch_Null_WindowWidth_Int32 = "windowWidth"; +static const char *k_pch_Null_WindowHeight_Int32 = "windowHeight"; +static const char *k_pch_Null_RenderWidth_Int32 = "renderWidth"; +static const char *k_pch_Null_RenderHeight_Int32 = "renderHeight"; +static const char *k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; +static const char *k_pch_Null_DisplayFrequency_Float = "displayFrequency"; +static const char *k_pch_UserInterface_Section = "userinterface"; +static const char *k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; +static const char *k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; +static const char *k_pch_UserInterface_Screenshots_Bool = "screenshots"; +static const char *k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; +static const char *k_pch_Notifications_Section = "notifications"; +static const char *k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; +static const char *k_pch_Keyboard_Section = "keyboard"; +static const char *k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; +static const char *k_pch_Keyboard_ScaleX = "ScaleX"; +static const char *k_pch_Keyboard_ScaleY = "ScaleY"; +static const char *k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; +static const char *k_pch_Keyboard_OffsetRightX = "OffsetRightX"; +static const char *k_pch_Keyboard_OffsetY = "OffsetY"; +static const char *k_pch_Keyboard_Smoothing = "Smoothing"; +static const char *k_pch_Perf_Section = "perfcheck"; +static const char *k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; +static const char *k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; +static const char *k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; +static const char *k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; +static const char *k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; +static const char *k_pch_Perf_TestData_Float = "perfTestData"; +static const char *k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; +static const char *k_pch_CollisionBounds_Section = "collisionBounds"; +static const char *k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; +static const char *k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; +static const char *k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; +static const char *k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; +static const char *k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; +static const char *k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; +static const char *k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; +static const char *k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; +static const char *k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; +static const char *k_pch_Camera_Section = "camera"; +static const char *k_pch_Camera_EnableCamera_Bool = "enableCamera"; +static const char *k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; +static const char *k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; +static const char *k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; +static const char *k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; +static const char *k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; +static const char *k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; +static const char *k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; +static const char *k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; +static const char *k_pch_audio_Section = "audio"; +static const char *k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; +static const char *k_pch_audio_OnRecordDevice_String = "onRecordDevice"; +static const char *k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; +static const char *k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; +static const char *k_pch_audio_OffRecordDevice_String = "offRecordDevice"; +static const char *k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; +static const char *k_pch_Power_Section = "power"; +static const char *k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; +static const char *k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; +static const char *k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; +static const char *k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; +static const char *k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; +static const char *k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; +static const char *k_pch_Dashboard_Section = "dashboard"; +static const char *k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; +static const char *k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; +static const char *k_pch_modelskin_Section = "modelskins"; +static const char *k_pch_Driver_Enable_Bool = "enable"; +static const char *IVRScreenshots_Version = "IVRScreenshots_001"; +static const char *IVRResources_Version = "IVRResources_001"; +static const char *IVRDriverManager_Version = "IVRDriverManager_001"; // OpenVR Enums @@ -1062,14 +1061,13 @@ typedef enum EVRScreenshotError EVRScreenshotError_VRScreenshotError_ScreenshotAlreadyInProgress = 108, } EVRScreenshotError; - // OpenVR typedefs typedef uint32_t TrackedDeviceIndex_t; typedef uint32_t VRNotificationId; typedef uint64_t VROverlayHandle_t; -typedef void * glSharedTextureHandle_t; +typedef void *glSharedTextureHandle_t; typedef int32_t glInt_t; typedef uint32_t glUInt_t; typedef uint64_t SharedTextureHandle_t; @@ -1103,32 +1101,32 @@ typedef EVRScreenshotError VRScreenshotsError; typedef struct HmdMatrix34_t { - float m[3][4]; //float[3][4] + float m[3][4]; //float[3][4] } HmdMatrix34_t; typedef struct HmdMatrix44_t { - float m[4][4]; //float[4][4] + float m[4][4]; //float[4][4] } HmdMatrix44_t; typedef struct HmdVector3_t { - float v[3]; //float[3] + float v[3]; //float[3] } HmdVector3_t; typedef struct HmdVector4_t { - float v[4]; //float[4] + float v[4]; //float[4] } HmdVector4_t; typedef struct HmdVector3d_t { - double v[3]; //double[3] + double v[3]; //double[3] } HmdVector3d_t; typedef struct HmdVector2_t { - float v[2]; //float[2] + float v[2]; //float[2] } HmdVector2_t; typedef struct HmdQuaternion_t @@ -1149,7 +1147,7 @@ typedef struct HmdColor_t typedef struct HmdQuad_t { - struct HmdVector3_t vCorners[4]; //struct vr::HmdVector3_t[4] + struct HmdVector3_t vCorners[4]; //struct vr::HmdVector3_t[4] } HmdQuad_t; typedef struct HmdRect2_t @@ -1160,14 +1158,14 @@ typedef struct HmdRect2_t typedef struct DistortionCoordinates_t { - float rfRed[2]; //float[2] - float rfGreen[2]; //float[2] - float rfBlue[2]; //float[2] + float rfRed[2]; //float[2] + float rfGreen[2]; //float[2] + float rfBlue[2]; //float[2] } DistortionCoordinates_t; typedef struct Texture_t { - void * handle; // void * + void *handle; // void * enum ETextureType eType; enum EColorSpace eColorSpace; } Texture_t; @@ -1198,10 +1196,10 @@ typedef struct VRTextureWithPose_t typedef struct VRVulkanTextureData_t { uint64_t m_nImage; - struct VkDevice_T * m_pDevice; // struct VkDevice_T * - struct VkPhysicalDevice_T * m_pPhysicalDevice; // struct VkPhysicalDevice_T * - struct VkInstance_T * m_pInstance; // struct VkInstance_T * - struct VkQueue_T * m_pQueue; // struct VkQueue_T * + struct VkDevice_T *m_pDevice; // struct VkDevice_T * + struct VkPhysicalDevice_T *m_pPhysicalDevice; // struct VkPhysicalDevice_T * + struct VkInstance_T *m_pInstance; // struct VkInstance_T * + struct VkQueue_T *m_pQueue; // struct VkQueue_T * uint32_t m_nQueueFamilyIndex; uint32_t m_nWidth; uint32_t m_nHeight; @@ -1211,8 +1209,8 @@ typedef struct VRVulkanTextureData_t typedef struct D3D12TextureData_t { - struct ID3D12Resource * m_pResource; // struct ID3D12Resource * - struct ID3D12CommandQueue * m_pCommandQueue; // struct ID3D12CommandQueue * + struct ID3D12Resource *m_pResource; // struct ID3D12Resource * + struct ID3D12CommandQueue *m_pCommandQueue; // struct ID3D12CommandQueue * uint32_t m_nNodeMask; } D3D12TextureData_t; @@ -1270,7 +1268,7 @@ typedef struct VREvent_Status_t typedef struct VREvent_Keyboard_t { - char * cNewInput[8]; //char[8] + char *cNewInput[8]; //char[8] uint64_t uUserValue; } VREvent_Keyboard_t; @@ -1337,7 +1335,7 @@ typedef struct VREvent_Property_t typedef struct HiddenAreaMesh_t { - struct HmdVector2_t * pVertexData; // const struct vr::HmdVector2_t * + struct HmdVector2_t *pVertexData; // const struct vr::HmdVector2_t * uint32_t unTriangleCount; } HiddenAreaMesh_t; @@ -1352,7 +1350,7 @@ typedef struct VRControllerState_t uint32_t unPacketNum; uint64_t ulButtonPressed; uint64_t ulButtonTouched; - struct VRControllerAxis_t rAxis[5]; //struct vr::VRControllerAxis_t[5] + struct VRControllerAxis_t rAxis[5]; //struct vr::VRControllerAxis_t[5] } VRControllerState_t; typedef struct Compositor_OverlaySettings @@ -1385,8 +1383,8 @@ typedef struct CameraVideoStreamFrameHeader_t typedef struct AppOverrideKeys_t { - char * pchKey; // const char * - char * pchValue; // const char * + char *pchKey; // const char * + char *pchValue; // const char * } AppOverrideKeys_t; typedef struct Compositor_FrameTiming @@ -1477,36 +1475,36 @@ typedef struct RenderModel_Vertex_t { struct HmdVector3_t vPosition; struct HmdVector3_t vNormal; - float rfTextureCoord[2]; //float[2] + float rfTextureCoord[2]; //float[2] } RenderModel_Vertex_t; #if defined(__linux__) || defined(__APPLE__) -#pragma pack( push, 4 ) +#pragma pack(push, 4) #endif typedef struct RenderModel_TextureMap_t { uint16_t unWidth; uint16_t unHeight; - uint8_t * rubTextureMapData; // const uint8_t * + uint8_t *rubTextureMapData; // const uint8_t * } RenderModel_TextureMap_t; #if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#pragma pack(pop) #endif #if defined(__linux__) || defined(__APPLE__) -#pragma pack( push, 4 ) +#pragma pack(push, 4) #endif typedef struct RenderModel_t { - struct RenderModel_Vertex_t * rVertexData; // const struct vr::RenderModel_Vertex_t * + struct RenderModel_Vertex_t *rVertexData; // const struct vr::RenderModel_Vertex_t * uint32_t unVertexCount; - uint16_t * rIndexData; // const uint16_t * + uint16_t *rIndexData; // const uint16_t * uint32_t unTriangleCount; TextureID_t diffuseTextureId; } RenderModel_t; #if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#pragma pack(pop) #endif typedef struct RenderModel_ControllerMode_State_t { @@ -1515,7 +1513,7 @@ typedef struct RenderModel_ControllerMode_State_t typedef struct NotificationBitmap_t { - void * m_pImageData; // void * + void *m_pImageData; // void * int32_t m_nWidth; int32_t m_nHeight; int32_t m_nBytesPerPixel; @@ -1523,24 +1521,22 @@ typedef struct NotificationBitmap_t typedef struct COpenVRContext { - intptr_t m_pVRSystem; // class vr::IVRSystem * - intptr_t m_pVRChaperone; // class vr::IVRChaperone * - intptr_t m_pVRChaperoneSetup; // class vr::IVRChaperoneSetup * - intptr_t m_pVRCompositor; // class vr::IVRCompositor * - intptr_t m_pVROverlay; // class vr::IVROverlay * - intptr_t m_pVRResources; // class vr::IVRResources * - intptr_t m_pVRRenderModels; // class vr::IVRRenderModels * - intptr_t m_pVRExtendedDisplay; // class vr::IVRExtendedDisplay * - intptr_t m_pVRSettings; // class vr::IVRSettings * - intptr_t m_pVRApplications; // class vr::IVRApplications * - intptr_t m_pVRTrackedCamera; // class vr::IVRTrackedCamera * - intptr_t m_pVRScreenshots; // class vr::IVRScreenshots * - intptr_t m_pVRDriverManager; // class vr::IVRDriverManager * + intptr_t m_pVRSystem; // class vr::IVRSystem * + intptr_t m_pVRChaperone; // class vr::IVRChaperone * + intptr_t m_pVRChaperoneSetup; // class vr::IVRChaperoneSetup * + intptr_t m_pVRCompositor; // class vr::IVRCompositor * + intptr_t m_pVROverlay; // class vr::IVROverlay * + intptr_t m_pVRResources; // class vr::IVRResources * + intptr_t m_pVRRenderModels; // class vr::IVRRenderModels * + intptr_t m_pVRExtendedDisplay; // class vr::IVRExtendedDisplay * + intptr_t m_pVRSettings; // class vr::IVRSettings * + intptr_t m_pVRApplications; // class vr::IVRApplications * + intptr_t m_pVRTrackedCamera; // class vr::IVRTrackedCamera * + intptr_t m_pVRScreenshots; // class vr::IVRScreenshots * + intptr_t m_pVRDriverManager; // class vr::IVRDriverManager * } COpenVRContext; - -typedef union -{ +typedef union { VREvent_Reserved_t reserved; VREvent_Controller_t controller; VREvent_Mouse_t mouse; @@ -1560,16 +1556,14 @@ typedef union /** An event posted by the server to all running applications */ struct VREvent_t { - uint32_t eventType; // EVREventType enum + uint32_t eventType; // EVREventType enum TrackedDeviceIndex_t trackedDeviceIndex; float eventAgeSeconds; // event data must be the end of the struct as its size is variable VREvent_Data_t data; }; - -typedef union -{ +typedef union { IntersectionMaskRectangle_t m_Rectangle; IntersectionMaskCircle_t m_Circle; } VROverlayIntersectionMaskPrimitive_Data_t; @@ -1580,352 +1574,350 @@ struct VROverlayIntersectionMaskPrimitive_t VROverlayIntersectionMaskPrimitive_Data_t m_Primitive; }; - // OpenVR Function Pointer Tables struct VR_IVRSystem_FnTable { - void (OPENVR_FNTABLE_CALLTYPE *GetRecommendedRenderTargetSize)(uint32_t * pnWidth, uint32_t * pnHeight); - struct HmdMatrix44_t (OPENVR_FNTABLE_CALLTYPE *GetProjectionMatrix)(EVREye eEye, float fNearZ, float fFarZ); - void (OPENVR_FNTABLE_CALLTYPE *GetProjectionRaw)(EVREye eEye, float * pfLeft, float * pfRight, float * pfTop, float * pfBottom); - bool (OPENVR_FNTABLE_CALLTYPE *ComputeDistortion)(EVREye eEye, float fU, float fV, struct DistortionCoordinates_t * pDistortionCoordinates); - struct HmdMatrix34_t (OPENVR_FNTABLE_CALLTYPE *GetEyeToHeadTransform)(EVREye eEye); - bool (OPENVR_FNTABLE_CALLTYPE *GetTimeSinceLastVsync)(float * pfSecondsSinceLastVsync, uint64_t * pulFrameCounter); - int32_t (OPENVR_FNTABLE_CALLTYPE *GetD3D9AdapterIndex)(); - void (OPENVR_FNTABLE_CALLTYPE *GetDXGIOutputInfo)(int32_t * pnAdapterIndex); - void (OPENVR_FNTABLE_CALLTYPE *GetOutputDevice)(uint64_t * pnDevice, ETextureType textureType, struct VkInstance_T * pInstance); - bool (OPENVR_FNTABLE_CALLTYPE *IsDisplayOnDesktop)(); - bool (OPENVR_FNTABLE_CALLTYPE *SetDisplayVisibility)(bool bIsVisibleOnDesktop); - void (OPENVR_FNTABLE_CALLTYPE *GetDeviceToAbsoluteTrackingPose)(ETrackingUniverseOrigin eOrigin, float fPredictedSecondsToPhotonsFromNow, struct TrackedDevicePose_t * pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount); - void (OPENVR_FNTABLE_CALLTYPE *ResetSeatedZeroPose)(); - struct HmdMatrix34_t (OPENVR_FNTABLE_CALLTYPE *GetSeatedZeroPoseToStandingAbsoluteTrackingPose)(); - struct HmdMatrix34_t (OPENVR_FNTABLE_CALLTYPE *GetRawZeroPoseToStandingAbsoluteTrackingPose)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetSortedTrackedDeviceIndicesOfClass)(ETrackedDeviceClass eTrackedDeviceClass, TrackedDeviceIndex_t * punTrackedDeviceIndexArray, uint32_t unTrackedDeviceIndexArrayCount, TrackedDeviceIndex_t unRelativeToTrackedDeviceIndex); - EDeviceActivityLevel (OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceActivityLevel)(TrackedDeviceIndex_t unDeviceId); - void (OPENVR_FNTABLE_CALLTYPE *ApplyTransform)(struct TrackedDevicePose_t * pOutputPose, struct TrackedDevicePose_t * pTrackedDevicePose, struct HmdMatrix34_t * pTransform); - TrackedDeviceIndex_t (OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceIndexForControllerRole)(ETrackedControllerRole unDeviceType); - ETrackedControllerRole (OPENVR_FNTABLE_CALLTYPE *GetControllerRoleForTrackedDeviceIndex)(TrackedDeviceIndex_t unDeviceIndex); - ETrackedDeviceClass (OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceClass)(TrackedDeviceIndex_t unDeviceIndex); - bool (OPENVR_FNTABLE_CALLTYPE *IsTrackedDeviceConnected)(TrackedDeviceIndex_t unDeviceIndex); - bool (OPENVR_FNTABLE_CALLTYPE *GetBoolTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); - float (OPENVR_FNTABLE_CALLTYPE *GetFloatTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); - int32_t (OPENVR_FNTABLE_CALLTYPE *GetInt32TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); - uint64_t (OPENVR_FNTABLE_CALLTYPE *GetUint64TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); - struct HmdMatrix34_t (OPENVR_FNTABLE_CALLTYPE *GetMatrix34TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetStringTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, char * pchValue, uint32_t unBufferSize, ETrackedPropertyError * pError); - char * (OPENVR_FNTABLE_CALLTYPE *GetPropErrorNameFromEnum)(ETrackedPropertyError error); - bool (OPENVR_FNTABLE_CALLTYPE *PollNextEvent)(struct VREvent_t * pEvent, uint32_t uncbVREvent); - bool (OPENVR_FNTABLE_CALLTYPE *PollNextEventWithPose)(ETrackingUniverseOrigin eOrigin, struct VREvent_t * pEvent, uint32_t uncbVREvent, TrackedDevicePose_t * pTrackedDevicePose); - char * (OPENVR_FNTABLE_CALLTYPE *GetEventTypeNameFromEnum)(EVREventType eType); - struct HiddenAreaMesh_t (OPENVR_FNTABLE_CALLTYPE *GetHiddenAreaMesh)(EVREye eEye, EHiddenAreaMeshType type); - bool (OPENVR_FNTABLE_CALLTYPE *GetControllerState)(TrackedDeviceIndex_t unControllerDeviceIndex, VRControllerState_t * pControllerState, uint32_t unControllerStateSize); - bool (OPENVR_FNTABLE_CALLTYPE *GetControllerStateWithPose)(ETrackingUniverseOrigin eOrigin, TrackedDeviceIndex_t unControllerDeviceIndex, VRControllerState_t * pControllerState, uint32_t unControllerStateSize, struct TrackedDevicePose_t * pTrackedDevicePose); - void (OPENVR_FNTABLE_CALLTYPE *TriggerHapticPulse)(TrackedDeviceIndex_t unControllerDeviceIndex, uint32_t unAxisId, unsigned short usDurationMicroSec); - char * (OPENVR_FNTABLE_CALLTYPE *GetButtonIdNameFromEnum)(EVRButtonId eButtonId); - char * (OPENVR_FNTABLE_CALLTYPE *GetControllerAxisTypeNameFromEnum)(EVRControllerAxisType eAxisType); - bool (OPENVR_FNTABLE_CALLTYPE *CaptureInputFocus)(); - void (OPENVR_FNTABLE_CALLTYPE *ReleaseInputFocus)(); - bool (OPENVR_FNTABLE_CALLTYPE *IsInputFocusCapturedByAnotherProcess)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *DriverDebugRequest)(TrackedDeviceIndex_t unDeviceIndex, char * pchRequest, char * pchResponseBuffer, uint32_t unResponseBufferSize); - EVRFirmwareError (OPENVR_FNTABLE_CALLTYPE *PerformFirmwareUpdate)(TrackedDeviceIndex_t unDeviceIndex); - void (OPENVR_FNTABLE_CALLTYPE *AcknowledgeQuit_Exiting)(); - void (OPENVR_FNTABLE_CALLTYPE *AcknowledgeQuit_UserPrompt)(); + void(OPENVR_FNTABLE_CALLTYPE *GetRecommendedRenderTargetSize)(uint32_t *pnWidth, uint32_t *pnHeight); + struct HmdMatrix44_t(OPENVR_FNTABLE_CALLTYPE *GetProjectionMatrix)(EVREye eEye, float fNearZ, float fFarZ); + void(OPENVR_FNTABLE_CALLTYPE *GetProjectionRaw)(EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom); + bool(OPENVR_FNTABLE_CALLTYPE *ComputeDistortion)(EVREye eEye, float fU, float fV, struct DistortionCoordinates_t *pDistortionCoordinates); + struct HmdMatrix34_t(OPENVR_FNTABLE_CALLTYPE *GetEyeToHeadTransform)(EVREye eEye); + bool(OPENVR_FNTABLE_CALLTYPE *GetTimeSinceLastVsync)(float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter); + int32_t(OPENVR_FNTABLE_CALLTYPE *GetD3D9AdapterIndex)(); + void(OPENVR_FNTABLE_CALLTYPE *GetDXGIOutputInfo)(int32_t *pnAdapterIndex); + void(OPENVR_FNTABLE_CALLTYPE *GetOutputDevice)(uint64_t *pnDevice, ETextureType textureType, struct VkInstance_T *pInstance); + bool(OPENVR_FNTABLE_CALLTYPE *IsDisplayOnDesktop)(); + bool(OPENVR_FNTABLE_CALLTYPE *SetDisplayVisibility)(bool bIsVisibleOnDesktop); + void(OPENVR_FNTABLE_CALLTYPE *GetDeviceToAbsoluteTrackingPose)(ETrackingUniverseOrigin eOrigin, float fPredictedSecondsToPhotonsFromNow, struct TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount); + void(OPENVR_FNTABLE_CALLTYPE *ResetSeatedZeroPose)(); + struct HmdMatrix34_t(OPENVR_FNTABLE_CALLTYPE *GetSeatedZeroPoseToStandingAbsoluteTrackingPose)(); + struct HmdMatrix34_t(OPENVR_FNTABLE_CALLTYPE *GetRawZeroPoseToStandingAbsoluteTrackingPose)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetSortedTrackedDeviceIndicesOfClass)(ETrackedDeviceClass eTrackedDeviceClass, TrackedDeviceIndex_t *punTrackedDeviceIndexArray, uint32_t unTrackedDeviceIndexArrayCount, TrackedDeviceIndex_t unRelativeToTrackedDeviceIndex); + EDeviceActivityLevel(OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceActivityLevel)(TrackedDeviceIndex_t unDeviceId); + void(OPENVR_FNTABLE_CALLTYPE *ApplyTransform)(struct TrackedDevicePose_t *pOutputPose, struct TrackedDevicePose_t *pTrackedDevicePose, struct HmdMatrix34_t *pTransform); + TrackedDeviceIndex_t(OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceIndexForControllerRole)(ETrackedControllerRole unDeviceType); + ETrackedControllerRole(OPENVR_FNTABLE_CALLTYPE *GetControllerRoleForTrackedDeviceIndex)(TrackedDeviceIndex_t unDeviceIndex); + ETrackedDeviceClass(OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceClass)(TrackedDeviceIndex_t unDeviceIndex); + bool(OPENVR_FNTABLE_CALLTYPE *IsTrackedDeviceConnected)(TrackedDeviceIndex_t unDeviceIndex); + bool(OPENVR_FNTABLE_CALLTYPE *GetBoolTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError); + float(OPENVR_FNTABLE_CALLTYPE *GetFloatTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError); + int32_t(OPENVR_FNTABLE_CALLTYPE *GetInt32TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError); + uint64_t(OPENVR_FNTABLE_CALLTYPE *GetUint64TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError); + struct HmdMatrix34_t(OPENVR_FNTABLE_CALLTYPE *GetMatrix34TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetStringTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError); + char *(OPENVR_FNTABLE_CALLTYPE *GetPropErrorNameFromEnum)(ETrackedPropertyError error); + bool(OPENVR_FNTABLE_CALLTYPE *PollNextEvent)(struct VREvent_t *pEvent, uint32_t uncbVREvent); + bool(OPENVR_FNTABLE_CALLTYPE *PollNextEventWithPose)(ETrackingUniverseOrigin eOrigin, struct VREvent_t *pEvent, uint32_t uncbVREvent, TrackedDevicePose_t *pTrackedDevicePose); + char *(OPENVR_FNTABLE_CALLTYPE *GetEventTypeNameFromEnum)(EVREventType eType); + struct HiddenAreaMesh_t(OPENVR_FNTABLE_CALLTYPE *GetHiddenAreaMesh)(EVREye eEye, EHiddenAreaMeshType type); + bool(OPENVR_FNTABLE_CALLTYPE *GetControllerState)(TrackedDeviceIndex_t unControllerDeviceIndex, VRControllerState_t *pControllerState, uint32_t unControllerStateSize); + bool(OPENVR_FNTABLE_CALLTYPE *GetControllerStateWithPose)(ETrackingUniverseOrigin eOrigin, TrackedDeviceIndex_t unControllerDeviceIndex, VRControllerState_t *pControllerState, uint32_t unControllerStateSize, struct TrackedDevicePose_t *pTrackedDevicePose); + void(OPENVR_FNTABLE_CALLTYPE *TriggerHapticPulse)(TrackedDeviceIndex_t unControllerDeviceIndex, uint32_t unAxisId, unsigned short usDurationMicroSec); + char *(OPENVR_FNTABLE_CALLTYPE *GetButtonIdNameFromEnum)(EVRButtonId eButtonId); + char *(OPENVR_FNTABLE_CALLTYPE *GetControllerAxisTypeNameFromEnum)(EVRControllerAxisType eAxisType); + bool(OPENVR_FNTABLE_CALLTYPE *CaptureInputFocus)(); + void(OPENVR_FNTABLE_CALLTYPE *ReleaseInputFocus)(); + bool(OPENVR_FNTABLE_CALLTYPE *IsInputFocusCapturedByAnotherProcess)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *DriverDebugRequest)(TrackedDeviceIndex_t unDeviceIndex, char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize); + EVRFirmwareError(OPENVR_FNTABLE_CALLTYPE *PerformFirmwareUpdate)(TrackedDeviceIndex_t unDeviceIndex); + void(OPENVR_FNTABLE_CALLTYPE *AcknowledgeQuit_Exiting)(); + void(OPENVR_FNTABLE_CALLTYPE *AcknowledgeQuit_UserPrompt)(); }; struct VR_IVRExtendedDisplay_FnTable { - void (OPENVR_FNTABLE_CALLTYPE *GetWindowBounds)(int32_t * pnX, int32_t * pnY, uint32_t * pnWidth, uint32_t * pnHeight); - void (OPENVR_FNTABLE_CALLTYPE *GetEyeOutputViewport)(EVREye eEye, uint32_t * pnX, uint32_t * pnY, uint32_t * pnWidth, uint32_t * pnHeight); - void (OPENVR_FNTABLE_CALLTYPE *GetDXGIOutputInfo)(int32_t * pnAdapterIndex, int32_t * pnAdapterOutputIndex); + void(OPENVR_FNTABLE_CALLTYPE *GetWindowBounds)(int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight); + void(OPENVR_FNTABLE_CALLTYPE *GetEyeOutputViewport)(EVREye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight); + void(OPENVR_FNTABLE_CALLTYPE *GetDXGIOutputInfo)(int32_t *pnAdapterIndex, int32_t *pnAdapterOutputIndex); }; struct VR_IVRTrackedCamera_FnTable { - char * (OPENVR_FNTABLE_CALLTYPE *GetCameraErrorNameFromEnum)(EVRTrackedCameraError eCameraError); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *HasCamera)(TrackedDeviceIndex_t nDeviceIndex, bool * pHasCamera); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetCameraFrameSize)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, uint32_t * pnWidth, uint32_t * pnHeight, uint32_t * pnFrameBufferSize); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetCameraIntrinsics)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, HmdVector2_t * pFocalLength, HmdVector2_t * pCenter); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetCameraProjection)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, HmdMatrix44_t * pProjection); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *AcquireVideoStreamingService)(TrackedDeviceIndex_t nDeviceIndex, TrackedCameraHandle_t * pHandle); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *ReleaseVideoStreamingService)(TrackedCameraHandle_t hTrackedCamera); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetVideoStreamFrameBuffer)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, void * pFrameBuffer, uint32_t nFrameBufferSize, CameraVideoStreamFrameHeader_t * pFrameHeader, uint32_t nFrameHeaderSize); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureSize)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, VRTextureBounds_t * pTextureBounds, uint32_t * pnWidth, uint32_t * pnHeight); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureD3D11)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, void * pD3D11DeviceOrResource, void ** ppD3D11ShaderResourceView, CameraVideoStreamFrameHeader_t * pFrameHeader, uint32_t nFrameHeaderSize); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureGL)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, glUInt_t * pglTextureId, CameraVideoStreamFrameHeader_t * pFrameHeader, uint32_t nFrameHeaderSize); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *ReleaseVideoStreamTextureGL)(TrackedCameraHandle_t hTrackedCamera, glUInt_t glTextureId); + char *(OPENVR_FNTABLE_CALLTYPE *GetCameraErrorNameFromEnum)(EVRTrackedCameraError eCameraError); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *HasCamera)(TrackedDeviceIndex_t nDeviceIndex, bool *pHasCamera); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetCameraFrameSize)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, uint32_t *pnWidth, uint32_t *pnHeight, uint32_t *pnFrameBufferSize); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetCameraIntrinsics)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, HmdVector2_t *pFocalLength, HmdVector2_t *pCenter); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetCameraProjection)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, HmdMatrix44_t *pProjection); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *AcquireVideoStreamingService)(TrackedDeviceIndex_t nDeviceIndex, TrackedCameraHandle_t *pHandle); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *ReleaseVideoStreamingService)(TrackedCameraHandle_t hTrackedCamera); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetVideoStreamFrameBuffer)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, void *pFrameBuffer, uint32_t nFrameBufferSize, CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureSize)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, VRTextureBounds_t *pTextureBounds, uint32_t *pnWidth, uint32_t *pnHeight); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureD3D11)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView, CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureGL)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, glUInt_t *pglTextureId, CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *ReleaseVideoStreamTextureGL)(TrackedCameraHandle_t hTrackedCamera, glUInt_t glTextureId); }; struct VR_IVRApplications_FnTable { - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *AddApplicationManifest)(char * pchApplicationManifestFullPath, bool bTemporary); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *RemoveApplicationManifest)(char * pchApplicationManifestFullPath); - bool (OPENVR_FNTABLE_CALLTYPE *IsApplicationInstalled)(char * pchAppKey); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationCount)(); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *GetApplicationKeyByIndex)(uint32_t unApplicationIndex, char * pchAppKeyBuffer, uint32_t unAppKeyBufferLen); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *GetApplicationKeyByProcessId)(uint32_t unProcessId, char * pchAppKeyBuffer, uint32_t unAppKeyBufferLen); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchApplication)(char * pchAppKey); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchTemplateApplication)(char * pchTemplateAppKey, char * pchNewAppKey, struct AppOverrideKeys_t * pKeys, uint32_t unKeys); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchApplicationFromMimeType)(char * pchMimeType, char * pchArgs); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchDashboardOverlay)(char * pchAppKey); - bool (OPENVR_FNTABLE_CALLTYPE *CancelApplicationLaunch)(char * pchAppKey); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *IdentifyApplication)(uint32_t unProcessId, char * pchAppKey); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationProcessId)(char * pchAppKey); - char * (OPENVR_FNTABLE_CALLTYPE *GetApplicationsErrorNameFromEnum)(EVRApplicationError error); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyString)(char * pchAppKey, EVRApplicationProperty eProperty, char * pchPropertyValueBuffer, uint32_t unPropertyValueBufferLen, EVRApplicationError * peError); - bool (OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyBool)(char * pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError * peError); - uint64_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyUint64)(char * pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError * peError); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *SetApplicationAutoLaunch)(char * pchAppKey, bool bAutoLaunch); - bool (OPENVR_FNTABLE_CALLTYPE *GetApplicationAutoLaunch)(char * pchAppKey); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *SetDefaultApplicationForMimeType)(char * pchAppKey, char * pchMimeType); - bool (OPENVR_FNTABLE_CALLTYPE *GetDefaultApplicationForMimeType)(char * pchMimeType, char * pchAppKeyBuffer, uint32_t unAppKeyBufferLen); - bool (OPENVR_FNTABLE_CALLTYPE *GetApplicationSupportedMimeTypes)(char * pchAppKey, char * pchMimeTypesBuffer, uint32_t unMimeTypesBuffer); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationsThatSupportMimeType)(char * pchMimeType, char * pchAppKeysThatSupportBuffer, uint32_t unAppKeysThatSupportBuffer); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationLaunchArguments)(uint32_t unHandle, char * pchArgs, uint32_t unArgs); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *GetStartingApplication)(char * pchAppKeyBuffer, uint32_t unAppKeyBufferLen); - EVRApplicationTransitionState (OPENVR_FNTABLE_CALLTYPE *GetTransitionState)(); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *PerformApplicationPrelaunchCheck)(char * pchAppKey); - char * (OPENVR_FNTABLE_CALLTYPE *GetApplicationsTransitionStateNameFromEnum)(EVRApplicationTransitionState state); - bool (OPENVR_FNTABLE_CALLTYPE *IsQuitUserPromptRequested)(); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchInternalProcess)(char * pchBinaryPath, char * pchArguments, char * pchWorkingDirectory); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetCurrentSceneProcessId)(); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *AddApplicationManifest)(char *pchApplicationManifestFullPath, bool bTemporary); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *RemoveApplicationManifest)(char *pchApplicationManifestFullPath); + bool(OPENVR_FNTABLE_CALLTYPE *IsApplicationInstalled)(char *pchAppKey); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationCount)(); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *GetApplicationKeyByIndex)(uint32_t unApplicationIndex, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *GetApplicationKeyByProcessId)(uint32_t unProcessId, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *LaunchApplication)(char *pchAppKey); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *LaunchTemplateApplication)(char *pchTemplateAppKey, char *pchNewAppKey, struct AppOverrideKeys_t *pKeys, uint32_t unKeys); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *LaunchApplicationFromMimeType)(char *pchMimeType, char *pchArgs); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *LaunchDashboardOverlay)(char *pchAppKey); + bool(OPENVR_FNTABLE_CALLTYPE *CancelApplicationLaunch)(char *pchAppKey); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *IdentifyApplication)(uint32_t unProcessId, char *pchAppKey); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationProcessId)(char *pchAppKey); + char *(OPENVR_FNTABLE_CALLTYPE *GetApplicationsErrorNameFromEnum)(EVRApplicationError error); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyString)(char *pchAppKey, EVRApplicationProperty eProperty, char *pchPropertyValueBuffer, uint32_t unPropertyValueBufferLen, EVRApplicationError *peError); + bool(OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyBool)(char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError); + uint64_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyUint64)(char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *SetApplicationAutoLaunch)(char *pchAppKey, bool bAutoLaunch); + bool(OPENVR_FNTABLE_CALLTYPE *GetApplicationAutoLaunch)(char *pchAppKey); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *SetDefaultApplicationForMimeType)(char *pchAppKey, char *pchMimeType); + bool(OPENVR_FNTABLE_CALLTYPE *GetDefaultApplicationForMimeType)(char *pchMimeType, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen); + bool(OPENVR_FNTABLE_CALLTYPE *GetApplicationSupportedMimeTypes)(char *pchAppKey, char *pchMimeTypesBuffer, uint32_t unMimeTypesBuffer); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationsThatSupportMimeType)(char *pchMimeType, char *pchAppKeysThatSupportBuffer, uint32_t unAppKeysThatSupportBuffer); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationLaunchArguments)(uint32_t unHandle, char *pchArgs, uint32_t unArgs); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *GetStartingApplication)(char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen); + EVRApplicationTransitionState(OPENVR_FNTABLE_CALLTYPE *GetTransitionState)(); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *PerformApplicationPrelaunchCheck)(char *pchAppKey); + char *(OPENVR_FNTABLE_CALLTYPE *GetApplicationsTransitionStateNameFromEnum)(EVRApplicationTransitionState state); + bool(OPENVR_FNTABLE_CALLTYPE *IsQuitUserPromptRequested)(); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *LaunchInternalProcess)(char *pchBinaryPath, char *pchArguments, char *pchWorkingDirectory); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetCurrentSceneProcessId)(); }; struct VR_IVRChaperone_FnTable { - ChaperoneCalibrationState (OPENVR_FNTABLE_CALLTYPE *GetCalibrationState)(); - bool (OPENVR_FNTABLE_CALLTYPE *GetPlayAreaSize)(float * pSizeX, float * pSizeZ); - bool (OPENVR_FNTABLE_CALLTYPE *GetPlayAreaRect)(struct HmdQuad_t * rect); - void (OPENVR_FNTABLE_CALLTYPE *ReloadInfo)(); - void (OPENVR_FNTABLE_CALLTYPE *SetSceneColor)(struct HmdColor_t color); - void (OPENVR_FNTABLE_CALLTYPE *GetBoundsColor)(struct HmdColor_t * pOutputColorArray, int nNumOutputColors, float flCollisionBoundsFadeDistance, struct HmdColor_t * pOutputCameraColor); - bool (OPENVR_FNTABLE_CALLTYPE *AreBoundsVisible)(); - void (OPENVR_FNTABLE_CALLTYPE *ForceBoundsVisible)(bool bForce); + ChaperoneCalibrationState(OPENVR_FNTABLE_CALLTYPE *GetCalibrationState)(); + bool(OPENVR_FNTABLE_CALLTYPE *GetPlayAreaSize)(float *pSizeX, float *pSizeZ); + bool(OPENVR_FNTABLE_CALLTYPE *GetPlayAreaRect)(struct HmdQuad_t *rect); + void(OPENVR_FNTABLE_CALLTYPE *ReloadInfo)(); + void(OPENVR_FNTABLE_CALLTYPE *SetSceneColor)(struct HmdColor_t color); + void(OPENVR_FNTABLE_CALLTYPE *GetBoundsColor)(struct HmdColor_t *pOutputColorArray, int nNumOutputColors, float flCollisionBoundsFadeDistance, struct HmdColor_t *pOutputCameraColor); + bool(OPENVR_FNTABLE_CALLTYPE *AreBoundsVisible)(); + void(OPENVR_FNTABLE_CALLTYPE *ForceBoundsVisible)(bool bForce); }; struct VR_IVRChaperoneSetup_FnTable { - bool (OPENVR_FNTABLE_CALLTYPE *CommitWorkingCopy)(EChaperoneConfigFile configFile); - void (OPENVR_FNTABLE_CALLTYPE *RevertWorkingCopy)(); - bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingPlayAreaSize)(float * pSizeX, float * pSizeZ); - bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingPlayAreaRect)(struct HmdQuad_t * rect); - bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingCollisionBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t * punQuadsCount); - bool (OPENVR_FNTABLE_CALLTYPE *GetLiveCollisionBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t * punQuadsCount); - bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pmatSeatedZeroPoseToRawTrackingPose); - bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingStandingZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pmatStandingZeroPoseToRawTrackingPose); - void (OPENVR_FNTABLE_CALLTYPE *SetWorkingPlayAreaSize)(float sizeX, float sizeZ); - void (OPENVR_FNTABLE_CALLTYPE *SetWorkingCollisionBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t unQuadsCount); - void (OPENVR_FNTABLE_CALLTYPE *SetWorkingSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pMatSeatedZeroPoseToRawTrackingPose); - void (OPENVR_FNTABLE_CALLTYPE *SetWorkingStandingZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pMatStandingZeroPoseToRawTrackingPose); - void (OPENVR_FNTABLE_CALLTYPE *ReloadFromDisk)(EChaperoneConfigFile configFile); - bool (OPENVR_FNTABLE_CALLTYPE *GetLiveSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pmatSeatedZeroPoseToRawTrackingPose); - void (OPENVR_FNTABLE_CALLTYPE *SetWorkingCollisionBoundsTagsInfo)(uint8_t * pTagsBuffer, uint32_t unTagCount); - bool (OPENVR_FNTABLE_CALLTYPE *GetLiveCollisionBoundsTagsInfo)(uint8_t * pTagsBuffer, uint32_t * punTagCount); - bool (OPENVR_FNTABLE_CALLTYPE *SetWorkingPhysicalBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t unQuadsCount); - bool (OPENVR_FNTABLE_CALLTYPE *GetLivePhysicalBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t * punQuadsCount); - bool (OPENVR_FNTABLE_CALLTYPE *ExportLiveToBuffer)(char * pBuffer, uint32_t * pnBufferLength); - bool (OPENVR_FNTABLE_CALLTYPE *ImportFromBufferToWorking)(char * pBuffer, uint32_t nImportFlags); + bool(OPENVR_FNTABLE_CALLTYPE *CommitWorkingCopy)(EChaperoneConfigFile configFile); + void(OPENVR_FNTABLE_CALLTYPE *RevertWorkingCopy)(); + bool(OPENVR_FNTABLE_CALLTYPE *GetWorkingPlayAreaSize)(float *pSizeX, float *pSizeZ); + bool(OPENVR_FNTABLE_CALLTYPE *GetWorkingPlayAreaRect)(struct HmdQuad_t *rect); + bool(OPENVR_FNTABLE_CALLTYPE *GetWorkingCollisionBoundsInfo)(struct HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount); + bool(OPENVR_FNTABLE_CALLTYPE *GetLiveCollisionBoundsInfo)(struct HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount); + bool(OPENVR_FNTABLE_CALLTYPE *GetWorkingSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose); + bool(OPENVR_FNTABLE_CALLTYPE *GetWorkingStandingZeroPoseToRawTrackingPose)(struct HmdMatrix34_t *pmatStandingZeroPoseToRawTrackingPose); + void(OPENVR_FNTABLE_CALLTYPE *SetWorkingPlayAreaSize)(float sizeX, float sizeZ); + void(OPENVR_FNTABLE_CALLTYPE *SetWorkingCollisionBoundsInfo)(struct HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount); + void(OPENVR_FNTABLE_CALLTYPE *SetWorkingSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t *pMatSeatedZeroPoseToRawTrackingPose); + void(OPENVR_FNTABLE_CALLTYPE *SetWorkingStandingZeroPoseToRawTrackingPose)(struct HmdMatrix34_t *pMatStandingZeroPoseToRawTrackingPose); + void(OPENVR_FNTABLE_CALLTYPE *ReloadFromDisk)(EChaperoneConfigFile configFile); + bool(OPENVR_FNTABLE_CALLTYPE *GetLiveSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose); + void(OPENVR_FNTABLE_CALLTYPE *SetWorkingCollisionBoundsTagsInfo)(uint8_t *pTagsBuffer, uint32_t unTagCount); + bool(OPENVR_FNTABLE_CALLTYPE *GetLiveCollisionBoundsTagsInfo)(uint8_t *pTagsBuffer, uint32_t *punTagCount); + bool(OPENVR_FNTABLE_CALLTYPE *SetWorkingPhysicalBoundsInfo)(struct HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount); + bool(OPENVR_FNTABLE_CALLTYPE *GetLivePhysicalBoundsInfo)(struct HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount); + bool(OPENVR_FNTABLE_CALLTYPE *ExportLiveToBuffer)(char *pBuffer, uint32_t *pnBufferLength); + bool(OPENVR_FNTABLE_CALLTYPE *ImportFromBufferToWorking)(char *pBuffer, uint32_t nImportFlags); }; struct VR_IVRCompositor_FnTable { - void (OPENVR_FNTABLE_CALLTYPE *SetTrackingSpace)(ETrackingUniverseOrigin eOrigin); - ETrackingUniverseOrigin (OPENVR_FNTABLE_CALLTYPE *GetTrackingSpace)(); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *WaitGetPoses)(struct TrackedDevicePose_t * pRenderPoseArray, uint32_t unRenderPoseArrayCount, struct TrackedDevicePose_t * pGamePoseArray, uint32_t unGamePoseArrayCount); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *GetLastPoses)(struct TrackedDevicePose_t * pRenderPoseArray, uint32_t unRenderPoseArrayCount, struct TrackedDevicePose_t * pGamePoseArray, uint32_t unGamePoseArrayCount); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *GetLastPoseForTrackedDeviceIndex)(TrackedDeviceIndex_t unDeviceIndex, struct TrackedDevicePose_t * pOutputPose, struct TrackedDevicePose_t * pOutputGamePose); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *Submit)(EVREye eEye, struct Texture_t * pTexture, struct VRTextureBounds_t * pBounds, EVRSubmitFlags nSubmitFlags); - void (OPENVR_FNTABLE_CALLTYPE *ClearLastSubmittedFrame)(); - void (OPENVR_FNTABLE_CALLTYPE *PostPresentHandoff)(); - bool (OPENVR_FNTABLE_CALLTYPE *GetFrameTiming)(struct Compositor_FrameTiming * pTiming, uint32_t unFramesAgo); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetFrameTimings)(struct Compositor_FrameTiming * pTiming, uint32_t nFrames); - float (OPENVR_FNTABLE_CALLTYPE *GetFrameTimeRemaining)(); - void (OPENVR_FNTABLE_CALLTYPE *GetCumulativeStats)(struct Compositor_CumulativeStats * pStats, uint32_t nStatsSizeInBytes); - void (OPENVR_FNTABLE_CALLTYPE *FadeToColor)(float fSeconds, float fRed, float fGreen, float fBlue, float fAlpha, bool bBackground); - struct HmdColor_t (OPENVR_FNTABLE_CALLTYPE *GetCurrentFadeColor)(bool bBackground); - void (OPENVR_FNTABLE_CALLTYPE *FadeGrid)(float fSeconds, bool bFadeIn); - float (OPENVR_FNTABLE_CALLTYPE *GetCurrentGridAlpha)(); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *SetSkyboxOverride)(struct Texture_t * pTextures, uint32_t unTextureCount); - void (OPENVR_FNTABLE_CALLTYPE *ClearSkyboxOverride)(); - void (OPENVR_FNTABLE_CALLTYPE *CompositorBringToFront)(); - void (OPENVR_FNTABLE_CALLTYPE *CompositorGoToBack)(); - void (OPENVR_FNTABLE_CALLTYPE *CompositorQuit)(); - bool (OPENVR_FNTABLE_CALLTYPE *IsFullscreen)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetCurrentSceneFocusProcess)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetLastFrameRenderer)(); - bool (OPENVR_FNTABLE_CALLTYPE *CanRenderScene)(); - void (OPENVR_FNTABLE_CALLTYPE *ShowMirrorWindow)(); - void (OPENVR_FNTABLE_CALLTYPE *HideMirrorWindow)(); - bool (OPENVR_FNTABLE_CALLTYPE *IsMirrorWindowVisible)(); - void (OPENVR_FNTABLE_CALLTYPE *CompositorDumpImages)(); - bool (OPENVR_FNTABLE_CALLTYPE *ShouldAppRenderWithLowResources)(); - void (OPENVR_FNTABLE_CALLTYPE *ForceInterleavedReprojectionOn)(bool bOverride); - void (OPENVR_FNTABLE_CALLTYPE *ForceReconnectProcess)(); - void (OPENVR_FNTABLE_CALLTYPE *SuspendRendering)(bool bSuspend); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *GetMirrorTextureD3D11)(EVREye eEye, void * pD3D11DeviceOrResource, void ** ppD3D11ShaderResourceView); - void (OPENVR_FNTABLE_CALLTYPE *ReleaseMirrorTextureD3D11)(void * pD3D11ShaderResourceView); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *GetMirrorTextureGL)(EVREye eEye, glUInt_t * pglTextureId, glSharedTextureHandle_t * pglSharedTextureHandle); - bool (OPENVR_FNTABLE_CALLTYPE *ReleaseSharedGLTexture)(glUInt_t glTextureId, glSharedTextureHandle_t glSharedTextureHandle); - void (OPENVR_FNTABLE_CALLTYPE *LockGLSharedTextureForAccess)(glSharedTextureHandle_t glSharedTextureHandle); - void (OPENVR_FNTABLE_CALLTYPE *UnlockGLSharedTextureForAccess)(glSharedTextureHandle_t glSharedTextureHandle); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetVulkanInstanceExtensionsRequired)(char * pchValue, uint32_t unBufferSize); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetVulkanDeviceExtensionsRequired)(struct VkPhysicalDevice_T * pPhysicalDevice, char * pchValue, uint32_t unBufferSize); - void (OPENVR_FNTABLE_CALLTYPE *SetExplicitTimingMode)(bool bExplicitTimingMode); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *SubmitExplicitTimingData)(); + void(OPENVR_FNTABLE_CALLTYPE *SetTrackingSpace)(ETrackingUniverseOrigin eOrigin); + ETrackingUniverseOrigin(OPENVR_FNTABLE_CALLTYPE *GetTrackingSpace)(); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *WaitGetPoses)(struct TrackedDevicePose_t *pRenderPoseArray, uint32_t unRenderPoseArrayCount, struct TrackedDevicePose_t *pGamePoseArray, uint32_t unGamePoseArrayCount); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *GetLastPoses)(struct TrackedDevicePose_t *pRenderPoseArray, uint32_t unRenderPoseArrayCount, struct TrackedDevicePose_t *pGamePoseArray, uint32_t unGamePoseArrayCount); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *GetLastPoseForTrackedDeviceIndex)(TrackedDeviceIndex_t unDeviceIndex, struct TrackedDevicePose_t *pOutputPose, struct TrackedDevicePose_t *pOutputGamePose); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *Submit)(EVREye eEye, struct Texture_t *pTexture, struct VRTextureBounds_t *pBounds, EVRSubmitFlags nSubmitFlags); + void(OPENVR_FNTABLE_CALLTYPE *ClearLastSubmittedFrame)(); + void(OPENVR_FNTABLE_CALLTYPE *PostPresentHandoff)(); + bool(OPENVR_FNTABLE_CALLTYPE *GetFrameTiming)(struct Compositor_FrameTiming *pTiming, uint32_t unFramesAgo); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetFrameTimings)(struct Compositor_FrameTiming *pTiming, uint32_t nFrames); + float(OPENVR_FNTABLE_CALLTYPE *GetFrameTimeRemaining)(); + void(OPENVR_FNTABLE_CALLTYPE *GetCumulativeStats)(struct Compositor_CumulativeStats *pStats, uint32_t nStatsSizeInBytes); + void(OPENVR_FNTABLE_CALLTYPE *FadeToColor)(float fSeconds, float fRed, float fGreen, float fBlue, float fAlpha, bool bBackground); + struct HmdColor_t(OPENVR_FNTABLE_CALLTYPE *GetCurrentFadeColor)(bool bBackground); + void(OPENVR_FNTABLE_CALLTYPE *FadeGrid)(float fSeconds, bool bFadeIn); + float(OPENVR_FNTABLE_CALLTYPE *GetCurrentGridAlpha)(); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *SetSkyboxOverride)(struct Texture_t *pTextures, uint32_t unTextureCount); + void(OPENVR_FNTABLE_CALLTYPE *ClearSkyboxOverride)(); + void(OPENVR_FNTABLE_CALLTYPE *CompositorBringToFront)(); + void(OPENVR_FNTABLE_CALLTYPE *CompositorGoToBack)(); + void(OPENVR_FNTABLE_CALLTYPE *CompositorQuit)(); + bool(OPENVR_FNTABLE_CALLTYPE *IsFullscreen)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetCurrentSceneFocusProcess)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetLastFrameRenderer)(); + bool(OPENVR_FNTABLE_CALLTYPE *CanRenderScene)(); + void(OPENVR_FNTABLE_CALLTYPE *ShowMirrorWindow)(); + void(OPENVR_FNTABLE_CALLTYPE *HideMirrorWindow)(); + bool(OPENVR_FNTABLE_CALLTYPE *IsMirrorWindowVisible)(); + void(OPENVR_FNTABLE_CALLTYPE *CompositorDumpImages)(); + bool(OPENVR_FNTABLE_CALLTYPE *ShouldAppRenderWithLowResources)(); + void(OPENVR_FNTABLE_CALLTYPE *ForceInterleavedReprojectionOn)(bool bOverride); + void(OPENVR_FNTABLE_CALLTYPE *ForceReconnectProcess)(); + void(OPENVR_FNTABLE_CALLTYPE *SuspendRendering)(bool bSuspend); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *GetMirrorTextureD3D11)(EVREye eEye, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView); + void(OPENVR_FNTABLE_CALLTYPE *ReleaseMirrorTextureD3D11)(void *pD3D11ShaderResourceView); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *GetMirrorTextureGL)(EVREye eEye, glUInt_t *pglTextureId, glSharedTextureHandle_t *pglSharedTextureHandle); + bool(OPENVR_FNTABLE_CALLTYPE *ReleaseSharedGLTexture)(glUInt_t glTextureId, glSharedTextureHandle_t glSharedTextureHandle); + void(OPENVR_FNTABLE_CALLTYPE *LockGLSharedTextureForAccess)(glSharedTextureHandle_t glSharedTextureHandle); + void(OPENVR_FNTABLE_CALLTYPE *UnlockGLSharedTextureForAccess)(glSharedTextureHandle_t glSharedTextureHandle); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetVulkanInstanceExtensionsRequired)(char *pchValue, uint32_t unBufferSize); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetVulkanDeviceExtensionsRequired)(struct VkPhysicalDevice_T *pPhysicalDevice, char *pchValue, uint32_t unBufferSize); + void(OPENVR_FNTABLE_CALLTYPE *SetExplicitTimingMode)(bool bExplicitTimingMode); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *SubmitExplicitTimingData)(); }; struct VR_IVROverlay_FnTable { - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *FindOverlay)(char * pchOverlayKey, VROverlayHandle_t * pOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *CreateOverlay)(char * pchOverlayKey, char * pchOverlayName, VROverlayHandle_t * pOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *DestroyOverlay)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetHighQualityOverlay)(VROverlayHandle_t ulOverlayHandle); - VROverlayHandle_t (OPENVR_FNTABLE_CALLTYPE *GetHighQualityOverlay)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayKey)(VROverlayHandle_t ulOverlayHandle, char * pchValue, uint32_t unBufferSize, EVROverlayError * pError); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayName)(VROverlayHandle_t ulOverlayHandle, char * pchValue, uint32_t unBufferSize, EVROverlayError * pError); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayName)(VROverlayHandle_t ulOverlayHandle, char * pchName); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayImageData)(VROverlayHandle_t ulOverlayHandle, void * pvBuffer, uint32_t unBufferSize, uint32_t * punWidth, uint32_t * punHeight); - char * (OPENVR_FNTABLE_CALLTYPE *GetOverlayErrorNameFromEnum)(EVROverlayError error); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayRenderingPid)(VROverlayHandle_t ulOverlayHandle, uint32_t unPID); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayRenderingPid)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayFlag)(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool bEnabled); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayFlag)(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool * pbEnabled); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayColor)(VROverlayHandle_t ulOverlayHandle, float fRed, float fGreen, float fBlue); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayColor)(VROverlayHandle_t ulOverlayHandle, float * pfRed, float * pfGreen, float * pfBlue); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayAlpha)(VROverlayHandle_t ulOverlayHandle, float fAlpha); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayAlpha)(VROverlayHandle_t ulOverlayHandle, float * pfAlpha); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTexelAspect)(VROverlayHandle_t ulOverlayHandle, float fTexelAspect); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTexelAspect)(VROverlayHandle_t ulOverlayHandle, float * pfTexelAspect); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlaySortOrder)(VROverlayHandle_t ulOverlayHandle, uint32_t unSortOrder); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlaySortOrder)(VROverlayHandle_t ulOverlayHandle, uint32_t * punSortOrder); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayWidthInMeters)(VROverlayHandle_t ulOverlayHandle, float fWidthInMeters); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayWidthInMeters)(VROverlayHandle_t ulOverlayHandle, float * pfWidthInMeters); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayAutoCurveDistanceRangeInMeters)(VROverlayHandle_t ulOverlayHandle, float fMinDistanceInMeters, float fMaxDistanceInMeters); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayAutoCurveDistanceRangeInMeters)(VROverlayHandle_t ulOverlayHandle, float * pfMinDistanceInMeters, float * pfMaxDistanceInMeters); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTextureColorSpace)(VROverlayHandle_t ulOverlayHandle, EColorSpace eTextureColorSpace); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureColorSpace)(VROverlayHandle_t ulOverlayHandle, EColorSpace * peTextureColorSpace); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTextureBounds)(VROverlayHandle_t ulOverlayHandle, struct VRTextureBounds_t * pOverlayTextureBounds); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureBounds)(VROverlayHandle_t ulOverlayHandle, struct VRTextureBounds_t * pOverlayTextureBounds); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayRenderModel)(VROverlayHandle_t ulOverlayHandle, char * pchValue, uint32_t unBufferSize, struct HmdColor_t * pColor, EVROverlayError * pError); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayRenderModel)(VROverlayHandle_t ulOverlayHandle, char * pchRenderModel, struct HmdColor_t * pColor); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformType)(VROverlayHandle_t ulOverlayHandle, VROverlayTransformType * peTransformType); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformAbsolute)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, struct HmdMatrix34_t * pmatTrackingOriginToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformAbsolute)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin * peTrackingOrigin, struct HmdMatrix34_t * pmatTrackingOriginToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformTrackedDeviceRelative)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unTrackedDevice, struct HmdMatrix34_t * pmatTrackedDeviceToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformTrackedDeviceRelative)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t * punTrackedDevice, struct HmdMatrix34_t * pmatTrackedDeviceToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformTrackedDeviceComponent)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unDeviceIndex, char * pchComponentName); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformTrackedDeviceComponent)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t * punDeviceIndex, char * pchComponentName, uint32_t unComponentNameSize); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformOverlayRelative)(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t * ulOverlayHandleParent, struct HmdMatrix34_t * pmatParentOverlayToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformOverlayRelative)(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t ulOverlayHandleParent, struct HmdMatrix34_t * pmatParentOverlayToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ShowOverlay)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *HideOverlay)(VROverlayHandle_t ulOverlayHandle); - bool (OPENVR_FNTABLE_CALLTYPE *IsOverlayVisible)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetTransformForOverlayCoordinates)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, struct HmdVector2_t coordinatesInOverlay, struct HmdMatrix34_t * pmatTransform); - bool (OPENVR_FNTABLE_CALLTYPE *PollNextOverlayEvent)(VROverlayHandle_t ulOverlayHandle, struct VREvent_t * pEvent, uint32_t uncbVREvent); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayInputMethod)(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod * peInputMethod); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayInputMethod)(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod eInputMethod); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayMouseScale)(VROverlayHandle_t ulOverlayHandle, struct HmdVector2_t * pvecMouseScale); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayMouseScale)(VROverlayHandle_t ulOverlayHandle, struct HmdVector2_t * pvecMouseScale); - bool (OPENVR_FNTABLE_CALLTYPE *ComputeOverlayIntersection)(VROverlayHandle_t ulOverlayHandle, struct VROverlayIntersectionParams_t * pParams, struct VROverlayIntersectionResults_t * pResults); - bool (OPENVR_FNTABLE_CALLTYPE *HandleControllerOverlayInteractionAsMouse)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unControllerDeviceIndex); - bool (OPENVR_FNTABLE_CALLTYPE *IsHoverTargetOverlay)(VROverlayHandle_t ulOverlayHandle); - VROverlayHandle_t (OPENVR_FNTABLE_CALLTYPE *GetGamepadFocusOverlay)(); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetGamepadFocusOverlay)(VROverlayHandle_t ulNewFocusOverlay); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayNeighbor)(EOverlayDirection eDirection, VROverlayHandle_t ulFrom, VROverlayHandle_t ulTo); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *MoveGamepadFocusToNeighbor)(EOverlayDirection eDirection, VROverlayHandle_t ulFrom); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTexture)(VROverlayHandle_t ulOverlayHandle, struct Texture_t * pTexture); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ClearOverlayTexture)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayRaw)(VROverlayHandle_t ulOverlayHandle, void * pvBuffer, uint32_t unWidth, uint32_t unHeight, uint32_t unDepth); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayFromFile)(VROverlayHandle_t ulOverlayHandle, char * pchFilePath); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTexture)(VROverlayHandle_t ulOverlayHandle, void ** pNativeTextureHandle, void * pNativeTextureRef, uint32_t * pWidth, uint32_t * pHeight, uint32_t * pNativeFormat, ETextureType * pAPIType, EColorSpace * pColorSpace, struct VRTextureBounds_t * pTextureBounds); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ReleaseNativeOverlayHandle)(VROverlayHandle_t ulOverlayHandle, void * pNativeTextureHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureSize)(VROverlayHandle_t ulOverlayHandle, uint32_t * pWidth, uint32_t * pHeight); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *CreateDashboardOverlay)(char * pchOverlayKey, char * pchOverlayFriendlyName, VROverlayHandle_t * pMainHandle, VROverlayHandle_t * pThumbnailHandle); - bool (OPENVR_FNTABLE_CALLTYPE *IsDashboardVisible)(); - bool (OPENVR_FNTABLE_CALLTYPE *IsActiveDashboardOverlay)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetDashboardOverlaySceneProcess)(VROverlayHandle_t ulOverlayHandle, uint32_t unProcessId); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetDashboardOverlaySceneProcess)(VROverlayHandle_t ulOverlayHandle, uint32_t * punProcessId); - void (OPENVR_FNTABLE_CALLTYPE *ShowDashboard)(char * pchOverlayToShow); - TrackedDeviceIndex_t (OPENVR_FNTABLE_CALLTYPE *GetPrimaryDashboardDevice)(); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ShowKeyboard)(EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, char * pchDescription, uint32_t unCharMax, char * pchExistingText, bool bUseMinimalMode, uint64_t uUserValue); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ShowKeyboardForOverlay)(VROverlayHandle_t ulOverlayHandle, EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, char * pchDescription, uint32_t unCharMax, char * pchExistingText, bool bUseMinimalMode, uint64_t uUserValue); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetKeyboardText)(char * pchText, uint32_t cchText); - void (OPENVR_FNTABLE_CALLTYPE *HideKeyboard)(); - void (OPENVR_FNTABLE_CALLTYPE *SetKeyboardTransformAbsolute)(ETrackingUniverseOrigin eTrackingOrigin, struct HmdMatrix34_t * pmatTrackingOriginToKeyboardTransform); - void (OPENVR_FNTABLE_CALLTYPE *SetKeyboardPositionForOverlay)(VROverlayHandle_t ulOverlayHandle, struct HmdRect2_t avoidRect); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayIntersectionMask)(VROverlayHandle_t ulOverlayHandle, struct VROverlayIntersectionMaskPrimitive_t * pMaskPrimitives, uint32_t unNumMaskPrimitives, uint32_t unPrimitiveSize); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayFlags)(VROverlayHandle_t ulOverlayHandle, uint32_t * pFlags); - VRMessageOverlayResponse (OPENVR_FNTABLE_CALLTYPE *ShowMessageOverlay)(char * pchText, char * pchCaption, char * pchButton0Text, char * pchButton1Text, char * pchButton2Text, char * pchButton3Text); - void (OPENVR_FNTABLE_CALLTYPE *CloseMessageOverlay)(); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *FindOverlay)(char *pchOverlayKey, VROverlayHandle_t *pOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *CreateOverlay)(char *pchOverlayKey, char *pchOverlayName, VROverlayHandle_t *pOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *DestroyOverlay)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetHighQualityOverlay)(VROverlayHandle_t ulOverlayHandle); + VROverlayHandle_t(OPENVR_FNTABLE_CALLTYPE *GetHighQualityOverlay)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetOverlayKey)(VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, EVROverlayError *pError); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetOverlayName)(VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, EVROverlayError *pError); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayName)(VROverlayHandle_t ulOverlayHandle, char *pchName); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayImageData)(VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unBufferSize, uint32_t *punWidth, uint32_t *punHeight); + char *(OPENVR_FNTABLE_CALLTYPE *GetOverlayErrorNameFromEnum)(EVROverlayError error); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayRenderingPid)(VROverlayHandle_t ulOverlayHandle, uint32_t unPID); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetOverlayRenderingPid)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayFlag)(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool bEnabled); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayFlag)(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool *pbEnabled); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayColor)(VROverlayHandle_t ulOverlayHandle, float fRed, float fGreen, float fBlue); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayColor)(VROverlayHandle_t ulOverlayHandle, float *pfRed, float *pfGreen, float *pfBlue); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayAlpha)(VROverlayHandle_t ulOverlayHandle, float fAlpha); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayAlpha)(VROverlayHandle_t ulOverlayHandle, float *pfAlpha); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTexelAspect)(VROverlayHandle_t ulOverlayHandle, float fTexelAspect); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTexelAspect)(VROverlayHandle_t ulOverlayHandle, float *pfTexelAspect); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlaySortOrder)(VROverlayHandle_t ulOverlayHandle, uint32_t unSortOrder); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlaySortOrder)(VROverlayHandle_t ulOverlayHandle, uint32_t *punSortOrder); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayWidthInMeters)(VROverlayHandle_t ulOverlayHandle, float fWidthInMeters); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayWidthInMeters)(VROverlayHandle_t ulOverlayHandle, float *pfWidthInMeters); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayAutoCurveDistanceRangeInMeters)(VROverlayHandle_t ulOverlayHandle, float fMinDistanceInMeters, float fMaxDistanceInMeters); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayAutoCurveDistanceRangeInMeters)(VROverlayHandle_t ulOverlayHandle, float *pfMinDistanceInMeters, float *pfMaxDistanceInMeters); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTextureColorSpace)(VROverlayHandle_t ulOverlayHandle, EColorSpace eTextureColorSpace); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureColorSpace)(VROverlayHandle_t ulOverlayHandle, EColorSpace *peTextureColorSpace); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTextureBounds)(VROverlayHandle_t ulOverlayHandle, struct VRTextureBounds_t *pOverlayTextureBounds); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureBounds)(VROverlayHandle_t ulOverlayHandle, struct VRTextureBounds_t *pOverlayTextureBounds); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetOverlayRenderModel)(VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, struct HmdColor_t *pColor, EVROverlayError *pError); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayRenderModel)(VROverlayHandle_t ulOverlayHandle, char *pchRenderModel, struct HmdColor_t *pColor); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformType)(VROverlayHandle_t ulOverlayHandle, VROverlayTransformType *peTransformType); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformAbsolute)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, struct HmdMatrix34_t *pmatTrackingOriginToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformAbsolute)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin *peTrackingOrigin, struct HmdMatrix34_t *pmatTrackingOriginToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformTrackedDeviceRelative)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unTrackedDevice, struct HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformTrackedDeviceRelative)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punTrackedDevice, struct HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformTrackedDeviceComponent)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unDeviceIndex, char *pchComponentName); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformTrackedDeviceComponent)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punDeviceIndex, char *pchComponentName, uint32_t unComponentNameSize); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformOverlayRelative)(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t *ulOverlayHandleParent, struct HmdMatrix34_t *pmatParentOverlayToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformOverlayRelative)(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t ulOverlayHandleParent, struct HmdMatrix34_t *pmatParentOverlayToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *ShowOverlay)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *HideOverlay)(VROverlayHandle_t ulOverlayHandle); + bool(OPENVR_FNTABLE_CALLTYPE *IsOverlayVisible)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetTransformForOverlayCoordinates)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, struct HmdVector2_t coordinatesInOverlay, struct HmdMatrix34_t *pmatTransform); + bool(OPENVR_FNTABLE_CALLTYPE *PollNextOverlayEvent)(VROverlayHandle_t ulOverlayHandle, struct VREvent_t *pEvent, uint32_t uncbVREvent); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayInputMethod)(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod *peInputMethod); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayInputMethod)(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod eInputMethod); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayMouseScale)(VROverlayHandle_t ulOverlayHandle, struct HmdVector2_t *pvecMouseScale); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayMouseScale)(VROverlayHandle_t ulOverlayHandle, struct HmdVector2_t *pvecMouseScale); + bool(OPENVR_FNTABLE_CALLTYPE *ComputeOverlayIntersection)(VROverlayHandle_t ulOverlayHandle, struct VROverlayIntersectionParams_t *pParams, struct VROverlayIntersectionResults_t *pResults); + bool(OPENVR_FNTABLE_CALLTYPE *HandleControllerOverlayInteractionAsMouse)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unControllerDeviceIndex); + bool(OPENVR_FNTABLE_CALLTYPE *IsHoverTargetOverlay)(VROverlayHandle_t ulOverlayHandle); + VROverlayHandle_t(OPENVR_FNTABLE_CALLTYPE *GetGamepadFocusOverlay)(); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetGamepadFocusOverlay)(VROverlayHandle_t ulNewFocusOverlay); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayNeighbor)(EOverlayDirection eDirection, VROverlayHandle_t ulFrom, VROverlayHandle_t ulTo); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *MoveGamepadFocusToNeighbor)(EOverlayDirection eDirection, VROverlayHandle_t ulFrom); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTexture)(VROverlayHandle_t ulOverlayHandle, struct Texture_t *pTexture); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *ClearOverlayTexture)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayRaw)(VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unWidth, uint32_t unHeight, uint32_t unDepth); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayFromFile)(VROverlayHandle_t ulOverlayHandle, char *pchFilePath); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTexture)(VROverlayHandle_t ulOverlayHandle, void **pNativeTextureHandle, void *pNativeTextureRef, uint32_t *pWidth, uint32_t *pHeight, uint32_t *pNativeFormat, ETextureType *pAPIType, EColorSpace *pColorSpace, struct VRTextureBounds_t *pTextureBounds); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *ReleaseNativeOverlayHandle)(VROverlayHandle_t ulOverlayHandle, void *pNativeTextureHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureSize)(VROverlayHandle_t ulOverlayHandle, uint32_t *pWidth, uint32_t *pHeight); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *CreateDashboardOverlay)(char *pchOverlayKey, char *pchOverlayFriendlyName, VROverlayHandle_t *pMainHandle, VROverlayHandle_t *pThumbnailHandle); + bool(OPENVR_FNTABLE_CALLTYPE *IsDashboardVisible)(); + bool(OPENVR_FNTABLE_CALLTYPE *IsActiveDashboardOverlay)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetDashboardOverlaySceneProcess)(VROverlayHandle_t ulOverlayHandle, uint32_t unProcessId); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetDashboardOverlaySceneProcess)(VROverlayHandle_t ulOverlayHandle, uint32_t *punProcessId); + void(OPENVR_FNTABLE_CALLTYPE *ShowDashboard)(char *pchOverlayToShow); + TrackedDeviceIndex_t(OPENVR_FNTABLE_CALLTYPE *GetPrimaryDashboardDevice)(); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *ShowKeyboard)(EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, char *pchDescription, uint32_t unCharMax, char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *ShowKeyboardForOverlay)(VROverlayHandle_t ulOverlayHandle, EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, char *pchDescription, uint32_t unCharMax, char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetKeyboardText)(char *pchText, uint32_t cchText); + void(OPENVR_FNTABLE_CALLTYPE *HideKeyboard)(); + void(OPENVR_FNTABLE_CALLTYPE *SetKeyboardTransformAbsolute)(ETrackingUniverseOrigin eTrackingOrigin, struct HmdMatrix34_t *pmatTrackingOriginToKeyboardTransform); + void(OPENVR_FNTABLE_CALLTYPE *SetKeyboardPositionForOverlay)(VROverlayHandle_t ulOverlayHandle, struct HmdRect2_t avoidRect); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayIntersectionMask)(VROverlayHandle_t ulOverlayHandle, struct VROverlayIntersectionMaskPrimitive_t *pMaskPrimitives, uint32_t unNumMaskPrimitives, uint32_t unPrimitiveSize); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayFlags)(VROverlayHandle_t ulOverlayHandle, uint32_t *pFlags); + VRMessageOverlayResponse(OPENVR_FNTABLE_CALLTYPE *ShowMessageOverlay)(char *pchText, char *pchCaption, char *pchButton0Text, char *pchButton1Text, char *pchButton2Text, char *pchButton3Text); + void(OPENVR_FNTABLE_CALLTYPE *CloseMessageOverlay)(); }; struct VR_IVRRenderModels_FnTable { - EVRRenderModelError (OPENVR_FNTABLE_CALLTYPE *LoadRenderModel_Async)(char * pchRenderModelName, struct RenderModel_t ** ppRenderModel); - void (OPENVR_FNTABLE_CALLTYPE *FreeRenderModel)(struct RenderModel_t * pRenderModel); - EVRRenderModelError (OPENVR_FNTABLE_CALLTYPE *LoadTexture_Async)(TextureID_t textureId, struct RenderModel_TextureMap_t ** ppTexture); - void (OPENVR_FNTABLE_CALLTYPE *FreeTexture)(struct RenderModel_TextureMap_t * pTexture); - EVRRenderModelError (OPENVR_FNTABLE_CALLTYPE *LoadTextureD3D11_Async)(TextureID_t textureId, void * pD3D11Device, void ** ppD3D11Texture2D); - EVRRenderModelError (OPENVR_FNTABLE_CALLTYPE *LoadIntoTextureD3D11_Async)(TextureID_t textureId, void * pDstTexture); - void (OPENVR_FNTABLE_CALLTYPE *FreeTextureD3D11)(void * pD3D11Texture2D); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetRenderModelName)(uint32_t unRenderModelIndex, char * pchRenderModelName, uint32_t unRenderModelNameLen); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetRenderModelCount)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetComponentCount)(char * pchRenderModelName); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetComponentName)(char * pchRenderModelName, uint32_t unComponentIndex, char * pchComponentName, uint32_t unComponentNameLen); - uint64_t (OPENVR_FNTABLE_CALLTYPE *GetComponentButtonMask)(char * pchRenderModelName, char * pchComponentName); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetComponentRenderModelName)(char * pchRenderModelName, char * pchComponentName, char * pchComponentRenderModelName, uint32_t unComponentRenderModelNameLen); - bool (OPENVR_FNTABLE_CALLTYPE *GetComponentState)(char * pchRenderModelName, char * pchComponentName, VRControllerState_t * pControllerState, struct RenderModel_ControllerMode_State_t * pState, struct RenderModel_ComponentState_t * pComponentState); - bool (OPENVR_FNTABLE_CALLTYPE *RenderModelHasComponent)(char * pchRenderModelName, char * pchComponentName); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetRenderModelThumbnailURL)(char * pchRenderModelName, char * pchThumbnailURL, uint32_t unThumbnailURLLen, EVRRenderModelError * peError); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetRenderModelOriginalPath)(char * pchRenderModelName, char * pchOriginalPath, uint32_t unOriginalPathLen, EVRRenderModelError * peError); - char * (OPENVR_FNTABLE_CALLTYPE *GetRenderModelErrorNameFromEnum)(EVRRenderModelError error); + EVRRenderModelError(OPENVR_FNTABLE_CALLTYPE *LoadRenderModel_Async)(char *pchRenderModelName, struct RenderModel_t **ppRenderModel); + void(OPENVR_FNTABLE_CALLTYPE *FreeRenderModel)(struct RenderModel_t *pRenderModel); + EVRRenderModelError(OPENVR_FNTABLE_CALLTYPE *LoadTexture_Async)(TextureID_t textureId, struct RenderModel_TextureMap_t **ppTexture); + void(OPENVR_FNTABLE_CALLTYPE *FreeTexture)(struct RenderModel_TextureMap_t *pTexture); + EVRRenderModelError(OPENVR_FNTABLE_CALLTYPE *LoadTextureD3D11_Async)(TextureID_t textureId, void *pD3D11Device, void **ppD3D11Texture2D); + EVRRenderModelError(OPENVR_FNTABLE_CALLTYPE *LoadIntoTextureD3D11_Async)(TextureID_t textureId, void *pDstTexture); + void(OPENVR_FNTABLE_CALLTYPE *FreeTextureD3D11)(void *pD3D11Texture2D); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetRenderModelName)(uint32_t unRenderModelIndex, char *pchRenderModelName, uint32_t unRenderModelNameLen); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetRenderModelCount)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetComponentCount)(char *pchRenderModelName); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetComponentName)(char *pchRenderModelName, uint32_t unComponentIndex, char *pchComponentName, uint32_t unComponentNameLen); + uint64_t(OPENVR_FNTABLE_CALLTYPE *GetComponentButtonMask)(char *pchRenderModelName, char *pchComponentName); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetComponentRenderModelName)(char *pchRenderModelName, char *pchComponentName, char *pchComponentRenderModelName, uint32_t unComponentRenderModelNameLen); + bool(OPENVR_FNTABLE_CALLTYPE *GetComponentState)(char *pchRenderModelName, char *pchComponentName, VRControllerState_t *pControllerState, struct RenderModel_ControllerMode_State_t *pState, struct RenderModel_ComponentState_t *pComponentState); + bool(OPENVR_FNTABLE_CALLTYPE *RenderModelHasComponent)(char *pchRenderModelName, char *pchComponentName); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetRenderModelThumbnailURL)(char *pchRenderModelName, char *pchThumbnailURL, uint32_t unThumbnailURLLen, EVRRenderModelError *peError); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetRenderModelOriginalPath)(char *pchRenderModelName, char *pchOriginalPath, uint32_t unOriginalPathLen, EVRRenderModelError *peError); + char *(OPENVR_FNTABLE_CALLTYPE *GetRenderModelErrorNameFromEnum)(EVRRenderModelError error); }; struct VR_IVRNotifications_FnTable { - EVRNotificationError (OPENVR_FNTABLE_CALLTYPE *CreateNotification)(VROverlayHandle_t ulOverlayHandle, uint64_t ulUserValue, EVRNotificationType type, char * pchText, EVRNotificationStyle style, struct NotificationBitmap_t * pImage, VRNotificationId * pNotificationId); - EVRNotificationError (OPENVR_FNTABLE_CALLTYPE *RemoveNotification)(VRNotificationId notificationId); + EVRNotificationError(OPENVR_FNTABLE_CALLTYPE *CreateNotification)(VROverlayHandle_t ulOverlayHandle, uint64_t ulUserValue, EVRNotificationType type, char *pchText, EVRNotificationStyle style, struct NotificationBitmap_t *pImage, VRNotificationId *pNotificationId); + EVRNotificationError(OPENVR_FNTABLE_CALLTYPE *RemoveNotification)(VRNotificationId notificationId); }; struct VR_IVRSettings_FnTable { - char * (OPENVR_FNTABLE_CALLTYPE *GetSettingsErrorNameFromEnum)(EVRSettingsError eError); - bool (OPENVR_FNTABLE_CALLTYPE *Sync)(bool bForce, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *SetBool)(char * pchSection, char * pchSettingsKey, bool bValue, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *SetInt32)(char * pchSection, char * pchSettingsKey, int32_t nValue, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *SetFloat)(char * pchSection, char * pchSettingsKey, float flValue, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *SetString)(char * pchSection, char * pchSettingsKey, char * pchValue, EVRSettingsError * peError); - bool (OPENVR_FNTABLE_CALLTYPE *GetBool)(char * pchSection, char * pchSettingsKey, EVRSettingsError * peError); - int32_t (OPENVR_FNTABLE_CALLTYPE *GetInt32)(char * pchSection, char * pchSettingsKey, EVRSettingsError * peError); - float (OPENVR_FNTABLE_CALLTYPE *GetFloat)(char * pchSection, char * pchSettingsKey, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *GetString)(char * pchSection, char * pchSettingsKey, char * pchValue, uint32_t unValueLen, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *RemoveSection)(char * pchSection, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *RemoveKeyInSection)(char * pchSection, char * pchSettingsKey, EVRSettingsError * peError); + char *(OPENVR_FNTABLE_CALLTYPE *GetSettingsErrorNameFromEnum)(EVRSettingsError eError); + bool(OPENVR_FNTABLE_CALLTYPE *Sync)(bool bForce, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *SetBool)(char *pchSection, char *pchSettingsKey, bool bValue, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *SetInt32)(char *pchSection, char *pchSettingsKey, int32_t nValue, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *SetFloat)(char *pchSection, char *pchSettingsKey, float flValue, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *SetString)(char *pchSection, char *pchSettingsKey, char *pchValue, EVRSettingsError *peError); + bool(OPENVR_FNTABLE_CALLTYPE *GetBool)(char *pchSection, char *pchSettingsKey, EVRSettingsError *peError); + int32_t(OPENVR_FNTABLE_CALLTYPE *GetInt32)(char *pchSection, char *pchSettingsKey, EVRSettingsError *peError); + float(OPENVR_FNTABLE_CALLTYPE *GetFloat)(char *pchSection, char *pchSettingsKey, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *GetString)(char *pchSection, char *pchSettingsKey, char *pchValue, uint32_t unValueLen, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *RemoveSection)(char *pchSection, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *RemoveKeyInSection)(char *pchSection, char *pchSettingsKey, EVRSettingsError *peError); }; struct VR_IVRScreenshots_FnTable { - EVRScreenshotError (OPENVR_FNTABLE_CALLTYPE *RequestScreenshot)(ScreenshotHandle_t * pOutScreenshotHandle, EVRScreenshotType type, char * pchPreviewFilename, char * pchVRFilename); - EVRScreenshotError (OPENVR_FNTABLE_CALLTYPE *HookScreenshot)(EVRScreenshotType * pSupportedTypes, int numTypes); - EVRScreenshotType (OPENVR_FNTABLE_CALLTYPE *GetScreenshotPropertyType)(ScreenshotHandle_t screenshotHandle, EVRScreenshotError * pError); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetScreenshotPropertyFilename)(ScreenshotHandle_t screenshotHandle, EVRScreenshotPropertyFilenames filenameType, char * pchFilename, uint32_t cchFilename, EVRScreenshotError * pError); - EVRScreenshotError (OPENVR_FNTABLE_CALLTYPE *UpdateScreenshotProgress)(ScreenshotHandle_t screenshotHandle, float flProgress); - EVRScreenshotError (OPENVR_FNTABLE_CALLTYPE *TakeStereoScreenshot)(ScreenshotHandle_t * pOutScreenshotHandle, char * pchPreviewFilename, char * pchVRFilename); - EVRScreenshotError (OPENVR_FNTABLE_CALLTYPE *SubmitScreenshot)(ScreenshotHandle_t screenshotHandle, EVRScreenshotType type, char * pchSourcePreviewFilename, char * pchSourceVRFilename); + EVRScreenshotError(OPENVR_FNTABLE_CALLTYPE *RequestScreenshot)(ScreenshotHandle_t *pOutScreenshotHandle, EVRScreenshotType type, char *pchPreviewFilename, char *pchVRFilename); + EVRScreenshotError(OPENVR_FNTABLE_CALLTYPE *HookScreenshot)(EVRScreenshotType *pSupportedTypes, int numTypes); + EVRScreenshotType(OPENVR_FNTABLE_CALLTYPE *GetScreenshotPropertyType)(ScreenshotHandle_t screenshotHandle, EVRScreenshotError *pError); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetScreenshotPropertyFilename)(ScreenshotHandle_t screenshotHandle, EVRScreenshotPropertyFilenames filenameType, char *pchFilename, uint32_t cchFilename, EVRScreenshotError *pError); + EVRScreenshotError(OPENVR_FNTABLE_CALLTYPE *UpdateScreenshotProgress)(ScreenshotHandle_t screenshotHandle, float flProgress); + EVRScreenshotError(OPENVR_FNTABLE_CALLTYPE *TakeStereoScreenshot)(ScreenshotHandle_t *pOutScreenshotHandle, char *pchPreviewFilename, char *pchVRFilename); + EVRScreenshotError(OPENVR_FNTABLE_CALLTYPE *SubmitScreenshot)(ScreenshotHandle_t screenshotHandle, EVRScreenshotType type, char *pchSourcePreviewFilename, char *pchSourceVRFilename); }; struct VR_IVRResources_FnTable { - uint32_t (OPENVR_FNTABLE_CALLTYPE *LoadSharedResource)(char * pchResourceName, char * pchBuffer, uint32_t unBufferLen); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetResourceFullPath)(char * pchResourceName, char * pchResourceTypeDirectory, char * pchPathBuffer, uint32_t unBufferLen); + uint32_t(OPENVR_FNTABLE_CALLTYPE *LoadSharedResource)(char *pchResourceName, char *pchBuffer, uint32_t unBufferLen); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetResourceFullPath)(char *pchResourceName, char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen); }; struct VR_IVRDriverManager_FnTable { - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetDriverCount)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetDriverName)(DriverId_t nDriver, char * pchValue, uint32_t unBufferSize); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetDriverCount)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetDriverName)(DriverId_t nDriver, char *pchValue, uint32_t unBufferSize); }; - #if 0 // Global entry points S_API intptr_t VR_InitInternal( EVRInitError *peError, EVRApplicationType eType ); @@ -1937,6 +1929,4 @@ S_API const char * VR_GetVRInitErrorAsSymbol( EVRInitError error ); S_API const char * VR_GetVRInitErrorAsEnglishDescription( EVRInitError error ); #endif -#endif // __OPENVR_API_FLAT_H__ - - +#endif // __OPENVR_API_FLAT_H__ diff --git a/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Headers/openvr_driver.h b/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Headers/openvr_driver.h index 7ab997e25..b07699f82 100644 --- a/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Headers/openvr_driver.h +++ b/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Headers/openvr_driver.h @@ -9,8 +9,6 @@ #include - - // vrtypes.h #ifndef _INCLUDE_VRTYPES_H #define _INCLUDE_VRTYPES_H @@ -27,9 +25,9 @@ struct ID3D12CommandQueue; namespace vr { -#pragma pack( push, 8 ) +#pragma pack(push, 8) -typedef void* glSharedTextureHandle_t; +typedef void *glSharedTextureHandle_t; typedef int32_t glInt_t; typedef uint32_t glUInt_t; @@ -80,7 +78,7 @@ struct HmdColor_t struct HmdQuad_t { - HmdVector3_t vCorners[ 4 ]; + HmdVector3_t vCorners[4]; }; struct HmdRect2_t @@ -107,40 +105,40 @@ enum EVREye enum ETextureType { - TextureType_DirectX = 0, // Handle is an ID3D11Texture - TextureType_OpenGL = 1, // Handle is an OpenGL texture name or an OpenGL render buffer name, depending on submit flags - TextureType_Vulkan = 2, // Handle is a pointer to a VRVulkanTextureData_t structure - TextureType_IOSurface = 3, // Handle is a macOS cross-process-sharable IOSurfaceRef - TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure + TextureType_DirectX = 0, // Handle is an ID3D11Texture + TextureType_OpenGL = 1, // Handle is an OpenGL texture name or an OpenGL render buffer name, depending on submit flags + TextureType_Vulkan = 2, // Handle is a pointer to a VRVulkanTextureData_t structure + TextureType_IOSurface = 3, // Handle is a macOS cross-process-sharable IOSurfaceRef + TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure }; enum EColorSpace { - ColorSpace_Auto = 0, // Assumes 'gamma' for 8-bit per component formats, otherwise 'linear'. This mirrors the DXGI formats which have _SRGB variants. - ColorSpace_Gamma = 1, // Texture data can be displayed directly on the display without any conversion (a.k.a. display native format). - ColorSpace_Linear = 2, // Same as gamma but has been converted to a linear representation using DXGI's sRGB conversion algorithm. + ColorSpace_Auto = 0, // Assumes 'gamma' for 8-bit per component formats, otherwise 'linear'. This mirrors the DXGI formats which have _SRGB variants. + ColorSpace_Gamma = 1, // Texture data can be displayed directly on the display without any conversion (a.k.a. display native format). + ColorSpace_Linear = 2, // Same as gamma but has been converted to a linear representation using DXGI's sRGB conversion algorithm. }; struct Texture_t { - void* handle; // See ETextureType definition above + void *handle; // See ETextureType definition above ETextureType eType; EColorSpace eColorSpace; }; // Handle to a shared texture (HANDLE on Windows obtained using OpenSharedResource). typedef uint64_t SharedTextureHandle_t; -#define INVALID_SHARED_TEXTURE_HANDLE ((vr::SharedTextureHandle_t)0) +#define INVALID_SHARED_TEXTURE_HANDLE ((vr::SharedTextureHandle_t)0) enum ETrackingResult { - TrackingResult_Uninitialized = 1, + TrackingResult_Uninitialized = 1, - TrackingResult_Calibrating_InProgress = 100, - TrackingResult_Calibrating_OutOfRange = 101, + TrackingResult_Calibrating_InProgress = 100, + TrackingResult_Calibrating_OutOfRange = 101, - TrackingResult_Running_OK = 200, - TrackingResult_Running_OutOfRange = 201, + TrackingResult_Running_OK = 200, + TrackingResult_Running_OutOfRange = 201, }; typedef uint32_t DriverId_t; @@ -158,30 +156,28 @@ static const uint32_t k_unTrackedDeviceIndexInvalid = 0xFFFFFFFF; /** Describes what kind of object is being tracked at a given ID */ enum ETrackedDeviceClass { - TrackedDeviceClass_Invalid = 0, // the ID was not valid. - TrackedDeviceClass_HMD = 1, // Head-Mounted Displays - TrackedDeviceClass_Controller = 2, // Tracked controllers - TrackedDeviceClass_GenericTracker = 3, // Generic trackers, similar to controllers - TrackedDeviceClass_TrackingReference = 4, // Camera and base stations that serve as tracking reference points - TrackedDeviceClass_DisplayRedirect = 5, // Accessories that aren't necessarily tracked themselves, but may redirect video output from other tracked devices + TrackedDeviceClass_Invalid = 0, // the ID was not valid. + TrackedDeviceClass_HMD = 1, // Head-Mounted Displays + TrackedDeviceClass_Controller = 2, // Tracked controllers + TrackedDeviceClass_GenericTracker = 3, // Generic trackers, similar to controllers + TrackedDeviceClass_TrackingReference = 4, // Camera and base stations that serve as tracking reference points + TrackedDeviceClass_DisplayRedirect = 5, // Accessories that aren't necessarily tracked themselves, but may redirect video output from other tracked devices }; - /** Describes what specific role associated with a tracked device */ enum ETrackedControllerRole { - TrackedControllerRole_Invalid = 0, // Invalid value for controller type - TrackedControllerRole_LeftHand = 1, // Tracked device associated with the left hand - TrackedControllerRole_RightHand = 2, // Tracked device associated with the right hand + TrackedControllerRole_Invalid = 0, // Invalid value for controller type + TrackedControllerRole_LeftHand = 1, // Tracked device associated with the left hand + TrackedControllerRole_RightHand = 2, // Tracked device associated with the right hand }; - /** describes a single pose for a tracked object */ struct TrackedDevicePose_t { HmdMatrix34_t mDeviceToAbsoluteTracking; - HmdVector3_t vVelocity; // velocity in tracker space in m/s - HmdVector3_t vAngularVelocity; // angular velocity in radians/s (?) + HmdVector3_t vVelocity; // velocity in tracker space in m/s + HmdVector3_t vAngularVelocity; // angular velocity in radians/s (?) ETrackingResult eTrackingResult; bool bPoseIsValid; @@ -194,9 +190,9 @@ struct TrackedDevicePose_t * for the poses it is requesting */ enum ETrackingUniverseOrigin { - TrackingUniverseSeated = 0, // Poses are provided relative to the seated zero pose - TrackingUniverseStanding = 1, // Poses are provided relative to the safe bounds configured by the user - TrackingUniverseRawAndUncalibrated = 2, // Poses are provided in the coordinate system defined by the driver. It has Y up and is unified for devices of the same driver. You usually don't want this one. + TrackingUniverseSeated = 0, // Poses are provided relative to the seated zero pose + TrackingUniverseStanding = 1, // Poses are provided relative to the safe bounds configured by the user + TrackingUniverseRawAndUncalibrated = 2, // Poses are provided in the coordinate system defined by the driver. It has Y up and is unified for devices of the same driver. You usually don't want this one. }; // Refers to a single container of properties @@ -223,146 +219,145 @@ static const PropertyTypeTag_t k_unHiddenAreaPropertyTag = 30; static const PropertyTypeTag_t k_unOpenVRInternalReserved_Start = 1000; static const PropertyTypeTag_t k_unOpenVRInternalReserved_End = 10000; - /** Each entry in this enum represents a property that can be retrieved about a * tracked device. Many fields are only valid for one ETrackedDeviceClass. */ enum ETrackedDeviceProperty { - Prop_Invalid = 0, + Prop_Invalid = 0, // general properties that apply to all device classes - Prop_TrackingSystemName_String = 1000, - Prop_ModelNumber_String = 1001, - Prop_SerialNumber_String = 1002, - Prop_RenderModelName_String = 1003, - Prop_WillDriftInYaw_Bool = 1004, - Prop_ManufacturerName_String = 1005, - Prop_TrackingFirmwareVersion_String = 1006, - Prop_HardwareRevision_String = 1007, - Prop_AllWirelessDongleDescriptions_String = 1008, - Prop_ConnectedWirelessDongle_String = 1009, - Prop_DeviceIsWireless_Bool = 1010, - Prop_DeviceIsCharging_Bool = 1011, - Prop_DeviceBatteryPercentage_Float = 1012, // 0 is empty, 1 is full - Prop_StatusDisplayTransform_Matrix34 = 1013, - Prop_Firmware_UpdateAvailable_Bool = 1014, - Prop_Firmware_ManualUpdate_Bool = 1015, - Prop_Firmware_ManualUpdateURL_String = 1016, - Prop_HardwareRevision_Uint64 = 1017, - Prop_FirmwareVersion_Uint64 = 1018, - Prop_FPGAVersion_Uint64 = 1019, - Prop_VRCVersion_Uint64 = 1020, - Prop_RadioVersion_Uint64 = 1021, - Prop_DongleVersion_Uint64 = 1022, - Prop_BlockServerShutdown_Bool = 1023, - Prop_CanUnifyCoordinateSystemWithHmd_Bool = 1024, - Prop_ContainsProximitySensor_Bool = 1025, - Prop_DeviceProvidesBatteryStatus_Bool = 1026, - Prop_DeviceCanPowerOff_Bool = 1027, - Prop_Firmware_ProgrammingTarget_String = 1028, - Prop_DeviceClass_Int32 = 1029, - Prop_HasCamera_Bool = 1030, - Prop_DriverVersion_String = 1031, - Prop_Firmware_ForceUpdateRequired_Bool = 1032, - Prop_ViveSystemButtonFixRequired_Bool = 1033, - Prop_ParentDriver_Uint64 = 1034, - Prop_ResourceRoot_String = 1035, + Prop_TrackingSystemName_String = 1000, + Prop_ModelNumber_String = 1001, + Prop_SerialNumber_String = 1002, + Prop_RenderModelName_String = 1003, + Prop_WillDriftInYaw_Bool = 1004, + Prop_ManufacturerName_String = 1005, + Prop_TrackingFirmwareVersion_String = 1006, + Prop_HardwareRevision_String = 1007, + Prop_AllWirelessDongleDescriptions_String = 1008, + Prop_ConnectedWirelessDongle_String = 1009, + Prop_DeviceIsWireless_Bool = 1010, + Prop_DeviceIsCharging_Bool = 1011, + Prop_DeviceBatteryPercentage_Float = 1012, // 0 is empty, 1 is full + Prop_StatusDisplayTransform_Matrix34 = 1013, + Prop_Firmware_UpdateAvailable_Bool = 1014, + Prop_Firmware_ManualUpdate_Bool = 1015, + Prop_Firmware_ManualUpdateURL_String = 1016, + Prop_HardwareRevision_Uint64 = 1017, + Prop_FirmwareVersion_Uint64 = 1018, + Prop_FPGAVersion_Uint64 = 1019, + Prop_VRCVersion_Uint64 = 1020, + Prop_RadioVersion_Uint64 = 1021, + Prop_DongleVersion_Uint64 = 1022, + Prop_BlockServerShutdown_Bool = 1023, + Prop_CanUnifyCoordinateSystemWithHmd_Bool = 1024, + Prop_ContainsProximitySensor_Bool = 1025, + Prop_DeviceProvidesBatteryStatus_Bool = 1026, + Prop_DeviceCanPowerOff_Bool = 1027, + Prop_Firmware_ProgrammingTarget_String = 1028, + Prop_DeviceClass_Int32 = 1029, + Prop_HasCamera_Bool = 1030, + Prop_DriverVersion_String = 1031, + Prop_Firmware_ForceUpdateRequired_Bool = 1032, + Prop_ViveSystemButtonFixRequired_Bool = 1033, + Prop_ParentDriver_Uint64 = 1034, + Prop_ResourceRoot_String = 1035, // Properties that are unique to TrackedDeviceClass_HMD - Prop_ReportsTimeSinceVSync_Bool = 2000, - Prop_SecondsFromVsyncToPhotons_Float = 2001, - Prop_DisplayFrequency_Float = 2002, - Prop_UserIpdMeters_Float = 2003, - Prop_CurrentUniverseId_Uint64 = 2004, - Prop_PreviousUniverseId_Uint64 = 2005, - Prop_DisplayFirmwareVersion_Uint64 = 2006, - Prop_IsOnDesktop_Bool = 2007, - Prop_DisplayMCType_Int32 = 2008, - Prop_DisplayMCOffset_Float = 2009, - Prop_DisplayMCScale_Float = 2010, - Prop_EdidVendorID_Int32 = 2011, - Prop_DisplayMCImageLeft_String = 2012, - Prop_DisplayMCImageRight_String = 2013, - Prop_DisplayGCBlackClamp_Float = 2014, - Prop_EdidProductID_Int32 = 2015, - Prop_CameraToHeadTransform_Matrix34 = 2016, - Prop_DisplayGCType_Int32 = 2017, - Prop_DisplayGCOffset_Float = 2018, - Prop_DisplayGCScale_Float = 2019, - Prop_DisplayGCPrescale_Float = 2020, - Prop_DisplayGCImage_String = 2021, - Prop_LensCenterLeftU_Float = 2022, - Prop_LensCenterLeftV_Float = 2023, - Prop_LensCenterRightU_Float = 2024, - Prop_LensCenterRightV_Float = 2025, - Prop_UserHeadToEyeDepthMeters_Float = 2026, - Prop_CameraFirmwareVersion_Uint64 = 2027, - Prop_CameraFirmwareDescription_String = 2028, - Prop_DisplayFPGAVersion_Uint64 = 2029, - Prop_DisplayBootloaderVersion_Uint64 = 2030, - Prop_DisplayHardwareVersion_Uint64 = 2031, - Prop_AudioFirmwareVersion_Uint64 = 2032, - Prop_CameraCompatibilityMode_Int32 = 2033, + Prop_ReportsTimeSinceVSync_Bool = 2000, + Prop_SecondsFromVsyncToPhotons_Float = 2001, + Prop_DisplayFrequency_Float = 2002, + Prop_UserIpdMeters_Float = 2003, + Prop_CurrentUniverseId_Uint64 = 2004, + Prop_PreviousUniverseId_Uint64 = 2005, + Prop_DisplayFirmwareVersion_Uint64 = 2006, + Prop_IsOnDesktop_Bool = 2007, + Prop_DisplayMCType_Int32 = 2008, + Prop_DisplayMCOffset_Float = 2009, + Prop_DisplayMCScale_Float = 2010, + Prop_EdidVendorID_Int32 = 2011, + Prop_DisplayMCImageLeft_String = 2012, + Prop_DisplayMCImageRight_String = 2013, + Prop_DisplayGCBlackClamp_Float = 2014, + Prop_EdidProductID_Int32 = 2015, + Prop_CameraToHeadTransform_Matrix34 = 2016, + Prop_DisplayGCType_Int32 = 2017, + Prop_DisplayGCOffset_Float = 2018, + Prop_DisplayGCScale_Float = 2019, + Prop_DisplayGCPrescale_Float = 2020, + Prop_DisplayGCImage_String = 2021, + Prop_LensCenterLeftU_Float = 2022, + Prop_LensCenterLeftV_Float = 2023, + Prop_LensCenterRightU_Float = 2024, + Prop_LensCenterRightV_Float = 2025, + Prop_UserHeadToEyeDepthMeters_Float = 2026, + Prop_CameraFirmwareVersion_Uint64 = 2027, + Prop_CameraFirmwareDescription_String = 2028, + Prop_DisplayFPGAVersion_Uint64 = 2029, + Prop_DisplayBootloaderVersion_Uint64 = 2030, + Prop_DisplayHardwareVersion_Uint64 = 2031, + Prop_AudioFirmwareVersion_Uint64 = 2032, + Prop_CameraCompatibilityMode_Int32 = 2033, Prop_ScreenshotHorizontalFieldOfViewDegrees_Float = 2034, Prop_ScreenshotVerticalFieldOfViewDegrees_Float = 2035, - Prop_DisplaySuppressed_Bool = 2036, - Prop_DisplayAllowNightMode_Bool = 2037, - Prop_DisplayMCImageWidth_Int32 = 2038, - Prop_DisplayMCImageHeight_Int32 = 2039, - Prop_DisplayMCImageNumChannels_Int32 = 2040, - Prop_DisplayMCImageData_Binary = 2041, - Prop_SecondsFromPhotonsToVblank_Float = 2042, - Prop_DriverDirectModeSendsVsyncEvents_Bool = 2043, - Prop_DisplayDebugMode_Bool = 2044, - Prop_GraphicsAdapterLuid_Uint64 = 2045, - Prop_DriverProvidedChaperonePath_String = 2048, + Prop_DisplaySuppressed_Bool = 2036, + Prop_DisplayAllowNightMode_Bool = 2037, + Prop_DisplayMCImageWidth_Int32 = 2038, + Prop_DisplayMCImageHeight_Int32 = 2039, + Prop_DisplayMCImageNumChannels_Int32 = 2040, + Prop_DisplayMCImageData_Binary = 2041, + Prop_SecondsFromPhotonsToVblank_Float = 2042, + Prop_DriverDirectModeSendsVsyncEvents_Bool = 2043, + Prop_DisplayDebugMode_Bool = 2044, + Prop_GraphicsAdapterLuid_Uint64 = 2045, + Prop_DriverProvidedChaperonePath_String = 2048, // Properties that are unique to TrackedDeviceClass_Controller - Prop_AttachedDeviceId_String = 3000, - Prop_SupportedButtons_Uint64 = 3001, - Prop_Axis0Type_Int32 = 3002, // Return value is of type EVRControllerAxisType - Prop_Axis1Type_Int32 = 3003, // Return value is of type EVRControllerAxisType - Prop_Axis2Type_Int32 = 3004, // Return value is of type EVRControllerAxisType - Prop_Axis3Type_Int32 = 3005, // Return value is of type EVRControllerAxisType - Prop_Axis4Type_Int32 = 3006, // Return value is of type EVRControllerAxisType - Prop_ControllerRoleHint_Int32 = 3007, // Return value is of type ETrackedControllerRole + Prop_AttachedDeviceId_String = 3000, + Prop_SupportedButtons_Uint64 = 3001, + Prop_Axis0Type_Int32 = 3002, // Return value is of type EVRControllerAxisType + Prop_Axis1Type_Int32 = 3003, // Return value is of type EVRControllerAxisType + Prop_Axis2Type_Int32 = 3004, // Return value is of type EVRControllerAxisType + Prop_Axis3Type_Int32 = 3005, // Return value is of type EVRControllerAxisType + Prop_Axis4Type_Int32 = 3006, // Return value is of type EVRControllerAxisType + Prop_ControllerRoleHint_Int32 = 3007, // Return value is of type ETrackedControllerRole // Properties that are unique to TrackedDeviceClass_TrackingReference - Prop_FieldOfViewLeftDegrees_Float = 4000, - Prop_FieldOfViewRightDegrees_Float = 4001, - Prop_FieldOfViewTopDegrees_Float = 4002, - Prop_FieldOfViewBottomDegrees_Float = 4003, - Prop_TrackingRangeMinimumMeters_Float = 4004, - Prop_TrackingRangeMaximumMeters_Float = 4005, - Prop_ModeLabel_String = 4006, + Prop_FieldOfViewLeftDegrees_Float = 4000, + Prop_FieldOfViewRightDegrees_Float = 4001, + Prop_FieldOfViewTopDegrees_Float = 4002, + Prop_FieldOfViewBottomDegrees_Float = 4003, + Prop_TrackingRangeMinimumMeters_Float = 4004, + Prop_TrackingRangeMaximumMeters_Float = 4005, + Prop_ModeLabel_String = 4006, // Properties that are used for user interface like icons names - Prop_IconPathName_String = 5000, // DEPRECATED. Value not referenced. Now expected to be part of icon path properties. - Prop_NamedIconPathDeviceOff_String = 5001, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceSearching_String = 5002, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceSearchingAlert_String = 5003, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceReady_String = 5004, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceReadyAlert_String = 5005, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceNotReady_String = 5006, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceStandby_String = 5007, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceAlertLow_String = 5008, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_IconPathName_String = 5000, // DEPRECATED. Value not referenced. Now expected to be part of icon path properties. + Prop_NamedIconPathDeviceOff_String = 5001, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceSearching_String = 5002, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceSearchingAlert_String = 5003, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceReady_String = 5004, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceReadyAlert_String = 5005, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceNotReady_String = 5006, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceStandby_String = 5007, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceAlertLow_String = 5008, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others // Properties that are used by helpers, but are opaque to applications - Prop_DisplayHiddenArea_Binary_Start = 5100, - Prop_DisplayHiddenArea_Binary_End = 5150, + Prop_DisplayHiddenArea_Binary_Start = 5100, + Prop_DisplayHiddenArea_Binary_End = 5150, // Properties that are unique to drivers - Prop_UserConfigPath_String = 6000, - Prop_InstallPath_String = 6001, - Prop_HasDisplayComponent_Bool = 6002, - Prop_HasControllerComponent_Bool = 6003, - Prop_HasCameraComponent_Bool = 6004, - Prop_HasDriverDirectModeComponent_Bool = 6005, - Prop_HasVirtualDisplayComponent_Bool = 6006, + Prop_UserConfigPath_String = 6000, + Prop_InstallPath_String = 6001, + Prop_HasDisplayComponent_Bool = 6002, + Prop_HasControllerComponent_Bool = 6003, + Prop_HasCameraComponent_Bool = 6004, + Prop_HasDriverDirectModeComponent_Bool = 6005, + Prop_HasVirtualDisplayComponent_Bool = 6006, // Vendors are free to expose private debug data in this reserved region - Prop_VendorSpecific_Reserved_Start = 10000, - Prop_VendorSpecific_Reserved_End = 10999, + Prop_VendorSpecific_Reserved_Start = 10000, + Prop_VendorSpecific_Reserved_End = 10999, }; /** No string property will ever be longer than this length */ @@ -371,18 +366,18 @@ static const uint32_t k_unMaxPropertyStringSize = 32 * 1024; /** Used to return errors that occur when reading properties. */ enum ETrackedPropertyError { - TrackedProp_Success = 0, - TrackedProp_WrongDataType = 1, - TrackedProp_WrongDeviceClass = 2, - TrackedProp_BufferTooSmall = 3, - TrackedProp_UnknownProperty = 4, // Driver has not set the property (and may not ever). - TrackedProp_InvalidDevice = 5, - TrackedProp_CouldNotContactServer = 6, - TrackedProp_ValueNotProvidedByDevice = 7, - TrackedProp_StringExceedsMaximumLength = 8, - TrackedProp_NotYetAvailable = 9, // The property value isn't known yet, but is expected soon. Call again later. - TrackedProp_PermissionDenied = 10, - TrackedProp_InvalidOperation = 11, + TrackedProp_Success = 0, + TrackedProp_WrongDataType = 1, + TrackedProp_WrongDeviceClass = 2, + TrackedProp_BufferTooSmall = 3, + TrackedProp_UnknownProperty = 4, // Driver has not set the property (and may not ever). + TrackedProp_InvalidDevice = 5, + TrackedProp_CouldNotContactServer = 6, + TrackedProp_ValueNotProvidedByDevice = 7, + TrackedProp_StringExceedsMaximumLength = 8, + TrackedProp_NotYetAvailable = 9, // The property value isn't known yet, but is expected soon. Call again later. + TrackedProp_PermissionDenied = 10, + TrackedProp_InvalidOperation = 11, }; /** Allows the application to control what part of the provided texture will be used in the @@ -396,7 +391,7 @@ struct VRTextureBounds_t /** Allows specifying pose used to render provided scene texture (if different from value returned by WaitGetPoses). */ struct VRTextureWithPose_t : public Texture_t { - HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures. + HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures. }; /** Allows the application to control how scene textures are used by the compositor when calling Submit. */ @@ -424,7 +419,7 @@ enum EVRSubmitFlags * Be sure to call OpenVR_Shutdown before destroying these resources. */ struct VRVulkanTextureData_t { - uint64_t m_nImage; // VkImage + uint64_t m_nImage; // VkImage VkDevice_T *m_pDevice; VkPhysicalDevice_T *m_pPhysicalDevice; VkInstance_T *m_pInstance; @@ -461,220 +456,216 @@ enum EVREventType { VREvent_None = 0, - VREvent_TrackedDeviceActivated = 100, - VREvent_TrackedDeviceDeactivated = 101, - VREvent_TrackedDeviceUpdated = 102, - VREvent_TrackedDeviceUserInteractionStarted = 103, - VREvent_TrackedDeviceUserInteractionEnded = 104, - VREvent_IpdChanged = 105, - VREvent_EnterStandbyMode = 106, - VREvent_LeaveStandbyMode = 107, - VREvent_TrackedDeviceRoleChanged = 108, - VREvent_WatchdogWakeUpRequested = 109, - VREvent_LensDistortionChanged = 110, - VREvent_PropertyChanged = 111, - VREvent_WirelessDisconnect = 112, - VREvent_WirelessReconnect = 113, + VREvent_TrackedDeviceActivated = 100, + VREvent_TrackedDeviceDeactivated = 101, + VREvent_TrackedDeviceUpdated = 102, + VREvent_TrackedDeviceUserInteractionStarted = 103, + VREvent_TrackedDeviceUserInteractionEnded = 104, + VREvent_IpdChanged = 105, + VREvent_EnterStandbyMode = 106, + VREvent_LeaveStandbyMode = 107, + VREvent_TrackedDeviceRoleChanged = 108, + VREvent_WatchdogWakeUpRequested = 109, + VREvent_LensDistortionChanged = 110, + VREvent_PropertyChanged = 111, + VREvent_WirelessDisconnect = 112, + VREvent_WirelessReconnect = 113, - VREvent_ButtonPress = 200, // data is controller - VREvent_ButtonUnpress = 201, // data is controller - VREvent_ButtonTouch = 202, // data is controller - VREvent_ButtonUntouch = 203, // data is controller + VREvent_ButtonPress = 200, // data is controller + VREvent_ButtonUnpress = 201, // data is controller + VREvent_ButtonTouch = 202, // data is controller + VREvent_ButtonUntouch = 203, // data is controller - VREvent_MouseMove = 300, // data is mouse - VREvent_MouseButtonDown = 301, // data is mouse - VREvent_MouseButtonUp = 302, // data is mouse - VREvent_FocusEnter = 303, // data is overlay - VREvent_FocusLeave = 304, // data is overlay - VREvent_Scroll = 305, // data is mouse - VREvent_TouchPadMove = 306, // data is mouse - VREvent_OverlayFocusChanged = 307, // data is overlay, global event + VREvent_MouseMove = 300, // data is mouse + VREvent_MouseButtonDown = 301, // data is mouse + VREvent_MouseButtonUp = 302, // data is mouse + VREvent_FocusEnter = 303, // data is overlay + VREvent_FocusLeave = 304, // data is overlay + VREvent_Scroll = 305, // data is mouse + VREvent_TouchPadMove = 306, // data is mouse + VREvent_OverlayFocusChanged = 307, // data is overlay, global event - VREvent_InputFocusCaptured = 400, // data is process DEPRECATED - VREvent_InputFocusReleased = 401, // data is process DEPRECATED - VREvent_SceneFocusLost = 402, // data is process - VREvent_SceneFocusGained = 403, // data is process - VREvent_SceneApplicationChanged = 404, // data is process - The App actually drawing the scene changed (usually to or from the compositor) - VREvent_SceneFocusChanged = 405, // data is process - New app got access to draw the scene - VREvent_InputFocusChanged = 406, // data is process - VREvent_SceneApplicationSecondaryRenderingStarted = 407, // data is process + VREvent_InputFocusCaptured = 400, // data is process DEPRECATED + VREvent_InputFocusReleased = 401, // data is process DEPRECATED + VREvent_SceneFocusLost = 402, // data is process + VREvent_SceneFocusGained = 403, // data is process + VREvent_SceneApplicationChanged = 404, // data is process - The App actually drawing the scene changed (usually to or from the compositor) + VREvent_SceneFocusChanged = 405, // data is process - New app got access to draw the scene + VREvent_InputFocusChanged = 406, // data is process + VREvent_SceneApplicationSecondaryRenderingStarted = 407, // data is process - VREvent_HideRenderModels = 410, // Sent to the scene application to request hiding render models temporarily - VREvent_ShowRenderModels = 411, // Sent to the scene application to request restoring render model visibility + VREvent_HideRenderModels = 410, // Sent to the scene application to request hiding render models temporarily + VREvent_ShowRenderModels = 411, // Sent to the scene application to request restoring render model visibility - VREvent_OverlayShown = 500, - VREvent_OverlayHidden = 501, - VREvent_DashboardActivated = 502, - VREvent_DashboardDeactivated = 503, - VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay - VREvent_DashboardRequested = 505, // Sent to the overlay manager - data is overlay - VREvent_ResetDashboard = 506, // Send to the overlay manager - VREvent_RenderToast = 507, // Send to the dashboard to render a toast - data is the notification ID - VREvent_ImageLoaded = 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading - VREvent_ShowKeyboard = 509, // Sent to keyboard renderer in the dashboard to invoke it - VREvent_HideKeyboard = 510, // Sent to keyboard renderer in the dashboard to hide it - VREvent_OverlayGamepadFocusGained = 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it - VREvent_OverlayGamepadFocusLost = 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else + VREvent_OverlayShown = 500, + VREvent_OverlayHidden = 501, + VREvent_DashboardActivated = 502, + VREvent_DashboardDeactivated = 503, + VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay + VREvent_DashboardRequested = 505, // Sent to the overlay manager - data is overlay + VREvent_ResetDashboard = 506, // Send to the overlay manager + VREvent_RenderToast = 507, // Send to the dashboard to render a toast - data is the notification ID + VREvent_ImageLoaded = 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading + VREvent_ShowKeyboard = 509, // Sent to keyboard renderer in the dashboard to invoke it + VREvent_HideKeyboard = 510, // Sent to keyboard renderer in the dashboard to hide it + VREvent_OverlayGamepadFocusGained = 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it + VREvent_OverlayGamepadFocusLost = 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else VREvent_OverlaySharedTextureChanged = 513, - VREvent_DashboardGuideButtonDown = 514, - VREvent_DashboardGuideButtonUp = 515, - VREvent_ScreenshotTriggered = 516, // Screenshot button combo was pressed, Dashboard should request a screenshot - VREvent_ImageFailed = 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load - VREvent_DashboardOverlayCreated = 518, + VREvent_DashboardGuideButtonDown = 514, + VREvent_DashboardGuideButtonUp = 515, + VREvent_ScreenshotTriggered = 516, // Screenshot button combo was pressed, Dashboard should request a screenshot + VREvent_ImageFailed = 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load + VREvent_DashboardOverlayCreated = 518, // Screenshot API - VREvent_RequestScreenshot = 520, // Sent by vrclient application to compositor to take a screenshot - VREvent_ScreenshotTaken = 521, // Sent by compositor to the application that the screenshot has been taken - VREvent_ScreenshotFailed = 522, // Sent by compositor to the application that the screenshot failed to be taken - VREvent_SubmitScreenshotToDashboard = 523, // Sent by compositor to the dashboard that a completed screenshot was submitted - VREvent_ScreenshotProgressToDashboard = 524, // Sent by compositor to the dashboard that a completed screenshot was submitted + VREvent_RequestScreenshot = 520, // Sent by vrclient application to compositor to take a screenshot + VREvent_ScreenshotTaken = 521, // Sent by compositor to the application that the screenshot has been taken + VREvent_ScreenshotFailed = 522, // Sent by compositor to the application that the screenshot failed to be taken + VREvent_SubmitScreenshotToDashboard = 523, // Sent by compositor to the dashboard that a completed screenshot was submitted + VREvent_ScreenshotProgressToDashboard = 524, // Sent by compositor to the dashboard that a completed screenshot was submitted - VREvent_PrimaryDashboardDeviceChanged = 525, + VREvent_PrimaryDashboardDeviceChanged = 525, - VREvent_Notification_Shown = 600, - VREvent_Notification_Hidden = 601, - VREvent_Notification_BeginInteraction = 602, - VREvent_Notification_Destroyed = 603, + VREvent_Notification_Shown = 600, + VREvent_Notification_Hidden = 601, + VREvent_Notification_BeginInteraction = 602, + VREvent_Notification_Destroyed = 603, - VREvent_Quit = 700, // data is process - VREvent_ProcessQuit = 701, // data is process - VREvent_QuitAborted_UserPrompt = 702, // data is process - VREvent_QuitAcknowledged = 703, // data is process - VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down + VREvent_Quit = 700, // data is process + VREvent_ProcessQuit = 701, // data is process + VREvent_QuitAborted_UserPrompt = 702, // data is process + VREvent_QuitAcknowledged = 703, // data is process + VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down - VREvent_ChaperoneDataHasChanged = 800, - VREvent_ChaperoneUniverseHasChanged = 801, - VREvent_ChaperoneTempDataHasChanged = 802, - VREvent_ChaperoneSettingsHaveChanged = 803, - VREvent_SeatedZeroPoseReset = 804, + VREvent_ChaperoneDataHasChanged = 800, + VREvent_ChaperoneUniverseHasChanged = 801, + VREvent_ChaperoneTempDataHasChanged = 802, + VREvent_ChaperoneSettingsHaveChanged = 803, + VREvent_SeatedZeroPoseReset = 804, - VREvent_AudioSettingsHaveChanged = 820, + VREvent_AudioSettingsHaveChanged = 820, - VREvent_BackgroundSettingHasChanged = 850, - VREvent_CameraSettingsHaveChanged = 851, - VREvent_ReprojectionSettingHasChanged = 852, - VREvent_ModelSkinSettingsHaveChanged = 853, - VREvent_EnvironmentSettingsHaveChanged = 854, - VREvent_PowerSettingsHaveChanged = 855, + VREvent_BackgroundSettingHasChanged = 850, + VREvent_CameraSettingsHaveChanged = 851, + VREvent_ReprojectionSettingHasChanged = 852, + VREvent_ModelSkinSettingsHaveChanged = 853, + VREvent_EnvironmentSettingsHaveChanged = 854, + VREvent_PowerSettingsHaveChanged = 855, VREvent_EnableHomeAppSettingsHaveChanged = 856, - VREvent_StatusUpdate = 900, + VREvent_StatusUpdate = 900, - VREvent_MCImageUpdated = 1000, + VREvent_MCImageUpdated = 1000, - VREvent_FirmwareUpdateStarted = 1100, - VREvent_FirmwareUpdateFinished = 1101, + VREvent_FirmwareUpdateStarted = 1100, + VREvent_FirmwareUpdateFinished = 1101, - VREvent_KeyboardClosed = 1200, - VREvent_KeyboardCharInput = 1201, - VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard + VREvent_KeyboardClosed = 1200, + VREvent_KeyboardCharInput = 1201, + VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard - VREvent_ApplicationTransitionStarted = 1300, - VREvent_ApplicationTransitionAborted = 1301, - VREvent_ApplicationTransitionNewAppStarted = 1302, - VREvent_ApplicationListUpdated = 1303, - VREvent_ApplicationMimeTypeLoad = 1304, + VREvent_ApplicationTransitionStarted = 1300, + VREvent_ApplicationTransitionAborted = 1301, + VREvent_ApplicationTransitionNewAppStarted = 1302, + VREvent_ApplicationListUpdated = 1303, + VREvent_ApplicationMimeTypeLoad = 1304, VREvent_ApplicationTransitionNewAppLaunchComplete = 1305, - VREvent_ProcessConnected = 1306, - VREvent_ProcessDisconnected = 1307, + VREvent_ProcessConnected = 1306, + VREvent_ProcessDisconnected = 1307, - VREvent_Compositor_MirrorWindowShown = 1400, - VREvent_Compositor_MirrorWindowHidden = 1401, - VREvent_Compositor_ChaperoneBoundsShown = 1410, - VREvent_Compositor_ChaperoneBoundsHidden = 1411, + VREvent_Compositor_MirrorWindowShown = 1400, + VREvent_Compositor_MirrorWindowHidden = 1401, + VREvent_Compositor_ChaperoneBoundsShown = 1410, + VREvent_Compositor_ChaperoneBoundsHidden = 1411, - VREvent_TrackedCamera_StartVideoStream = 1500, - VREvent_TrackedCamera_StopVideoStream = 1501, - VREvent_TrackedCamera_PauseVideoStream = 1502, + VREvent_TrackedCamera_StartVideoStream = 1500, + VREvent_TrackedCamera_StopVideoStream = 1501, + VREvent_TrackedCamera_PauseVideoStream = 1502, VREvent_TrackedCamera_ResumeVideoStream = 1503, - VREvent_TrackedCamera_EditingSurface = 1550, + VREvent_TrackedCamera_EditingSurface = 1550, - VREvent_PerformanceTest_EnableCapture = 1600, - VREvent_PerformanceTest_DisableCapture = 1601, - VREvent_PerformanceTest_FidelityLevel = 1602, + VREvent_PerformanceTest_EnableCapture = 1600, + VREvent_PerformanceTest_DisableCapture = 1601, + VREvent_PerformanceTest_FidelityLevel = 1602, + + VREvent_MessageOverlay_Closed = 1650, + VREvent_MessageOverlayCloseRequested = 1651, - VREvent_MessageOverlay_Closed = 1650, - VREvent_MessageOverlayCloseRequested = 1651, - // Vendors are free to expose private events in this reserved region - VREvent_VendorSpecific_Reserved_Start = 10000, - VREvent_VendorSpecific_Reserved_End = 19999, + VREvent_VendorSpecific_Reserved_Start = 10000, + VREvent_VendorSpecific_Reserved_End = 19999, }; - /** Level of Hmd activity */ // UserInteraction_Timeout means the device is in the process of timing out. // InUse = ( k_EDeviceActivityLevel_UserInteraction || k_EDeviceActivityLevel_UserInteraction_Timeout ) // VREvent_TrackedDeviceUserInteractionStarted fires when the devices transitions from Standby -> UserInteraction or Idle -> UserInteraction. // VREvent_TrackedDeviceUserInteractionEnded fires when the devices transitions from UserInteraction_Timeout -> Idle enum EDeviceActivityLevel -{ - k_EDeviceActivityLevel_Unknown = -1, - k_EDeviceActivityLevel_Idle = 0, // No activity for the last 10 seconds - k_EDeviceActivityLevel_UserInteraction = 1, // Activity (movement or prox sensor) is happening now - k_EDeviceActivityLevel_UserInteraction_Timeout = 2, // No activity for the last 0.5 seconds - k_EDeviceActivityLevel_Standby = 3, // Idle for at least 5 seconds (configurable in Settings -> Power Management) +{ + k_EDeviceActivityLevel_Unknown = -1, + k_EDeviceActivityLevel_Idle = 0, // No activity for the last 10 seconds + k_EDeviceActivityLevel_UserInteraction = 1, // Activity (movement or prox sensor) is happening now + k_EDeviceActivityLevel_UserInteraction_Timeout = 2, // No activity for the last 0.5 seconds + k_EDeviceActivityLevel_Standby = 3, // Idle for at least 5 seconds (configurable in Settings -> Power Management) }; - /** VR controller button and axis IDs */ enum EVRButtonId { - k_EButton_System = 0, - k_EButton_ApplicationMenu = 1, - k_EButton_Grip = 2, - k_EButton_DPad_Left = 3, - k_EButton_DPad_Up = 4, - k_EButton_DPad_Right = 5, - k_EButton_DPad_Down = 6, - k_EButton_A = 7, - - k_EButton_ProximitySensor = 31, + k_EButton_System = 0, + k_EButton_ApplicationMenu = 1, + k_EButton_Grip = 2, + k_EButton_DPad_Left = 3, + k_EButton_DPad_Up = 4, + k_EButton_DPad_Right = 5, + k_EButton_DPad_Down = 6, + k_EButton_A = 7, - k_EButton_Axis0 = 32, - k_EButton_Axis1 = 33, - k_EButton_Axis2 = 34, - k_EButton_Axis3 = 35, - k_EButton_Axis4 = 36, + k_EButton_ProximitySensor = 31, + + k_EButton_Axis0 = 32, + k_EButton_Axis1 = 33, + k_EButton_Axis2 = 34, + k_EButton_Axis3 = 35, + k_EButton_Axis4 = 36, // aliases for well known controllers - k_EButton_SteamVR_Touchpad = k_EButton_Axis0, - k_EButton_SteamVR_Trigger = k_EButton_Axis1, + k_EButton_SteamVR_Touchpad = k_EButton_Axis0, + k_EButton_SteamVR_Trigger = k_EButton_Axis1, - k_EButton_Dashboard_Back = k_EButton_Grip, + k_EButton_Dashboard_Back = k_EButton_Grip, - k_EButton_Max = 64 + k_EButton_Max = 64 }; -inline uint64_t ButtonMaskFromId( EVRButtonId id ) { return 1ull << id; } +inline uint64_t ButtonMaskFromId(EVRButtonId id) { return 1ull << id; } /** used for controller button events */ struct VREvent_Controller_t { - uint32_t button; // EVRButtonId enum + uint32_t button; // EVRButtonId enum }; - /** used for simulated mouse events in overlay space */ enum EVRMouseButton { - VRMouseButton_Left = 0x0001, - VRMouseButton_Right = 0x0002, - VRMouseButton_Middle = 0x0004, + VRMouseButton_Left = 0x0001, + VRMouseButton_Right = 0x0002, + VRMouseButton_Middle = 0x0004, }; - /** used for simulated mouse events in overlay space */ struct VREvent_Mouse_t { - float x, y; // co-ords are in GL space, bottom left of the texture is 0,0 - uint32_t button; // EVRMouseButton enum + float x, y; // co-ords are in GL space, bottom left of the texture is 0,0 + uint32_t button; // EVRMouseButton enum }; /** used for simulated mouse wheel scroll in overlay space */ struct VREvent_Scroll_t { - float xdelta, ydelta; // movement in fraction of the pad traversed since last delta, 1.0 for a full swipe + float xdelta, ydelta; // movement in fraction of the pad traversed since last delta, 1.0 for a full swipe uint32_t repeatCount; }; @@ -713,25 +704,23 @@ struct VREvent_Process_t bool bForced; }; - /** Used for a few events about overlays */ struct VREvent_Overlay_t { uint64_t overlayHandle; }; - /** Used for a few events about overlays */ struct VREvent_Status_t { - uint32_t statusState; // EVRState enum + uint32_t statusState; // EVRState enum }; /** Used for keyboard events **/ struct VREvent_Keyboard_t { - char cNewInput[8]; // Up to 11 bytes of new input - uint64_t uUserValue; // Possible flags about the new input + char cNewInput[8]; // Up to 11 bytes of new input + uint64_t uUserValue; // Possible flags about the new input }; struct VREvent_Ipd_t @@ -787,7 +776,7 @@ struct VREvent_EditingCameraSurface_t struct VREvent_MessageOverlay_t { - uint32_t unVRMessageOverlayResponse; // vr::VRMessageOverlayResponse enum + uint32_t unVRMessageOverlayResponse; // vr::VRMessageOverlayResponse enum }; struct VREvent_Property_t @@ -797,8 +786,7 @@ struct VREvent_Property_t }; /** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py */ -typedef union -{ +typedef union { VREvent_Reserved_t reserved; VREvent_Controller_t controller; VREvent_Mouse_t mouse; @@ -821,25 +809,24 @@ typedef union VREvent_Property_t property; } VREvent_Data_t; - -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif /** An event posted by the server to all running applications */ struct VREvent_t { - uint32_t eventType; // EVREventType enum + uint32_t eventType; // EVREventType enum TrackedDeviceIndex_t trackedDeviceIndex; float eventAgeSeconds; // event data must be the end of the struct as its size is variable VREvent_Data_t data; }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif /** The mesh to draw into the stencil (or depth) buffer to perform @@ -854,7 +841,6 @@ struct HiddenAreaMesh_t uint32_t unTriangleCount; }; - enum EHiddenAreaMeshType { k_eHiddenAreaMesh_Standard = 0, @@ -864,7 +850,6 @@ enum EHiddenAreaMeshType k_eHiddenAreaMesh_Max = 3, }; - /** Identifies what kind of axis is on the controller at index n. Read this type * with pVRSystem->Get( nControllerDeviceIndex, Prop_Axis0Type_Int32 + n ); */ @@ -873,32 +858,29 @@ enum EVRControllerAxisType k_eControllerAxis_None = 0, k_eControllerAxis_TrackPad = 1, k_eControllerAxis_Joystick = 2, - k_eControllerAxis_Trigger = 3, // Analog trigger data is in the X axis + k_eControllerAxis_Trigger = 3, // Analog trigger data is in the X axis }; - /** contains information about one axis on the controller */ struct VRControllerAxis_t { - float x; // Ranges from -1.0 to 1.0 for joysticks and track pads. Ranges from 0.0 to 1.0 for triggers were 0 is fully released. - float y; // Ranges from -1.0 to 1.0 for joysticks and track pads. Is always 0.0 for triggers. + float x; // Ranges from -1.0 to 1.0 for joysticks and track pads. Ranges from 0.0 to 1.0 for triggers were 0 is fully released. + float y; // Ranges from -1.0 to 1.0 for joysticks and track pads. Is always 0.0 for triggers. }; - /** the number of axes in the controller state */ static const uint32_t k_unControllerStateAxisCount = 5; - -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif /** Holds all the state of a controller at one moment in time. */ struct VRControllerState001_t { - // If packet num matches that on your prior call, then the controller state hasn't been changed since + // If packet num matches that on your prior call, then the controller state hasn't been changed since // your last call and there is no need to process it uint32_t unPacketNum; @@ -907,16 +889,14 @@ struct VRControllerState001_t uint64_t ulButtonTouched; // Axis data for the controller's analog inputs - VRControllerAxis_t rAxis[ k_unControllerStateAxisCount ]; + VRControllerAxis_t rAxis[k_unControllerStateAxisCount]; }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif - typedef VRControllerState001_t VRControllerState_t; - /** determines how to provide output to the application of various event processing functions. */ enum EVRControllerEventOutputType { @@ -924,8 +904,6 @@ enum EVRControllerEventOutputType ControllerEventOutput_VREvents = 1, }; - - /** Collision Bounds Style */ enum ECollisionBoundsStyle { @@ -941,7 +919,7 @@ enum ECollisionBoundsStyle /** Allows the application to customize how the overlay appears in the compositor */ struct Compositor_OverlaySettings { - uint32_t size; // sizeof(Compositor_OverlaySettings) + uint32_t size; // sizeof(Compositor_OverlaySettings) bool curved, antialias; float scale, distance, alpha; float uOffset, vOffset, uScale, vScale; @@ -957,49 +935,48 @@ static const VROverlayHandle_t k_ulOverlayHandleInvalid = 0; /** Errors that can occur around VR overlays */ enum EVROverlayError { - VROverlayError_None = 0, + VROverlayError_None = 0, - VROverlayError_UnknownOverlay = 10, - VROverlayError_InvalidHandle = 11, - VROverlayError_PermissionDenied = 12, - VROverlayError_OverlayLimitExceeded = 13, // No more overlays could be created because the maximum number already exist - VROverlayError_WrongVisibilityType = 14, - VROverlayError_KeyTooLong = 15, - VROverlayError_NameTooLong = 16, - VROverlayError_KeyInUse = 17, - VROverlayError_WrongTransformType = 18, - VROverlayError_InvalidTrackedDevice = 19, - VROverlayError_InvalidParameter = 20, - VROverlayError_ThumbnailCantBeDestroyed = 21, - VROverlayError_ArrayTooSmall = 22, - VROverlayError_RequestFailed = 23, - VROverlayError_InvalidTexture = 24, - VROverlayError_UnableToLoadFile = 25, - VROverlayError_KeyboardAlreadyInUse = 26, - VROverlayError_NoNeighbor = 27, - VROverlayError_TooManyMaskPrimitives = 29, - VROverlayError_BadMaskPrimitive = 30, + VROverlayError_UnknownOverlay = 10, + VROverlayError_InvalidHandle = 11, + VROverlayError_PermissionDenied = 12, + VROverlayError_OverlayLimitExceeded = 13, // No more overlays could be created because the maximum number already exist + VROverlayError_WrongVisibilityType = 14, + VROverlayError_KeyTooLong = 15, + VROverlayError_NameTooLong = 16, + VROverlayError_KeyInUse = 17, + VROverlayError_WrongTransformType = 18, + VROverlayError_InvalidTrackedDevice = 19, + VROverlayError_InvalidParameter = 20, + VROverlayError_ThumbnailCantBeDestroyed = 21, + VROverlayError_ArrayTooSmall = 22, + VROverlayError_RequestFailed = 23, + VROverlayError_InvalidTexture = 24, + VROverlayError_UnableToLoadFile = 25, + VROverlayError_KeyboardAlreadyInUse = 26, + VROverlayError_NoNeighbor = 27, + VROverlayError_TooManyMaskPrimitives = 29, + VROverlayError_BadMaskPrimitive = 30, }; /** enum values to pass in to VR_Init to identify whether the application will * draw a 3D scene. */ enum EVRApplicationType { - VRApplication_Other = 0, // Some other kind of application that isn't covered by the other entries - VRApplication_Scene = 1, // Application will submit 3D frames - VRApplication_Overlay = 2, // Application only interacts with overlays - VRApplication_Background = 3, // Application should not start SteamVR if it's not already running, and should not - // keep it running if everything else quits. - VRApplication_Utility = 4, // Init should not try to load any drivers. The application needs access to utility - // interfaces (like IVRSettings and IVRApplications) but not hardware. - VRApplication_VRMonitor = 5, // Reserved for vrmonitor - VRApplication_SteamWatchdog = 6,// Reserved for Steam - VRApplication_Bootstrapper = 7, // Start up SteamVR + VRApplication_Other = 0, // Some other kind of application that isn't covered by the other entries + VRApplication_Scene = 1, // Application will submit 3D frames + VRApplication_Overlay = 2, // Application only interacts with overlays + VRApplication_Background = 3, // Application should not start SteamVR if it's not already running, and should not + // keep it running if everything else quits. + VRApplication_Utility = 4, // Init should not try to load any drivers. The application needs access to utility + // interfaces (like IVRSettings and IVRApplications) but not hardware. + VRApplication_VRMonitor = 5, // Reserved for vrmonitor + VRApplication_SteamWatchdog = 6, // Reserved for Steam + VRApplication_Bootstrapper = 7, // Start up SteamVR VRApplication_Max }; - /** error codes for firmware */ enum EVRFirmwareError { @@ -1008,7 +985,6 @@ enum EVRFirmwareError VRFirmwareError_Fail = 2, }; - /** error codes for notifications */ enum EVRNotificationError { @@ -1019,103 +995,101 @@ enum EVRNotificationError VRNotificationError_SystemWithUserValueAlreadyExists = 103, }; - /** error codes returned by Vr_Init */ // Please add adequate error description to https://developer.valvesoftware.com/w/index.php?title=Category:SteamVRHelp enum EVRInitError { - VRInitError_None = 0, + VRInitError_None = 0, VRInitError_Unknown = 1, - VRInitError_Init_InstallationNotFound = 100, - VRInitError_Init_InstallationCorrupt = 101, - VRInitError_Init_VRClientDLLNotFound = 102, - VRInitError_Init_FileNotFound = 103, - VRInitError_Init_FactoryNotFound = 104, - VRInitError_Init_InterfaceNotFound = 105, - VRInitError_Init_InvalidInterface = 106, - VRInitError_Init_UserConfigDirectoryInvalid = 107, - VRInitError_Init_HmdNotFound = 108, - VRInitError_Init_NotInitialized = 109, - VRInitError_Init_PathRegistryNotFound = 110, - VRInitError_Init_NoConfigPath = 111, - VRInitError_Init_NoLogPath = 112, - VRInitError_Init_PathRegistryNotWritable = 113, - VRInitError_Init_AppInfoInitFailed = 114, - VRInitError_Init_Retry = 115, // Used internally to cause retries to vrserver - VRInitError_Init_InitCanceledByUser = 116, // The calling application should silently exit. The user canceled app startup - VRInitError_Init_AnotherAppLaunching = 117, - VRInitError_Init_SettingsInitFailed = 118, - VRInitError_Init_ShuttingDown = 119, - VRInitError_Init_TooManyObjects = 120, - VRInitError_Init_NoServerForBackgroundApp = 121, - VRInitError_Init_NotSupportedWithCompositor = 122, - VRInitError_Init_NotAvailableToUtilityApps = 123, - VRInitError_Init_Internal = 124, - VRInitError_Init_HmdDriverIdIsNone = 125, - VRInitError_Init_HmdNotFoundPresenceFailed = 126, - VRInitError_Init_VRMonitorNotFound = 127, - VRInitError_Init_VRMonitorStartupFailed = 128, - VRInitError_Init_LowPowerWatchdogNotSupported = 129, - VRInitError_Init_InvalidApplicationType = 130, - VRInitError_Init_NotAvailableToWatchdogApps = 131, - VRInitError_Init_WatchdogDisabledInSettings = 132, - VRInitError_Init_VRDashboardNotFound = 133, - VRInitError_Init_VRDashboardStartupFailed = 134, - VRInitError_Init_VRHomeNotFound = 135, - VRInitError_Init_VRHomeStartupFailed = 136, - VRInitError_Init_RebootingBusy = 137, - VRInitError_Init_FirmwareUpdateBusy = 138, - VRInitError_Init_FirmwareRecoveryBusy = 139, + VRInitError_Init_InstallationNotFound = 100, + VRInitError_Init_InstallationCorrupt = 101, + VRInitError_Init_VRClientDLLNotFound = 102, + VRInitError_Init_FileNotFound = 103, + VRInitError_Init_FactoryNotFound = 104, + VRInitError_Init_InterfaceNotFound = 105, + VRInitError_Init_InvalidInterface = 106, + VRInitError_Init_UserConfigDirectoryInvalid = 107, + VRInitError_Init_HmdNotFound = 108, + VRInitError_Init_NotInitialized = 109, + VRInitError_Init_PathRegistryNotFound = 110, + VRInitError_Init_NoConfigPath = 111, + VRInitError_Init_NoLogPath = 112, + VRInitError_Init_PathRegistryNotWritable = 113, + VRInitError_Init_AppInfoInitFailed = 114, + VRInitError_Init_Retry = 115, // Used internally to cause retries to vrserver + VRInitError_Init_InitCanceledByUser = 116, // The calling application should silently exit. The user canceled app startup + VRInitError_Init_AnotherAppLaunching = 117, + VRInitError_Init_SettingsInitFailed = 118, + VRInitError_Init_ShuttingDown = 119, + VRInitError_Init_TooManyObjects = 120, + VRInitError_Init_NoServerForBackgroundApp = 121, + VRInitError_Init_NotSupportedWithCompositor = 122, + VRInitError_Init_NotAvailableToUtilityApps = 123, + VRInitError_Init_Internal = 124, + VRInitError_Init_HmdDriverIdIsNone = 125, + VRInitError_Init_HmdNotFoundPresenceFailed = 126, + VRInitError_Init_VRMonitorNotFound = 127, + VRInitError_Init_VRMonitorStartupFailed = 128, + VRInitError_Init_LowPowerWatchdogNotSupported = 129, + VRInitError_Init_InvalidApplicationType = 130, + VRInitError_Init_NotAvailableToWatchdogApps = 131, + VRInitError_Init_WatchdogDisabledInSettings = 132, + VRInitError_Init_VRDashboardNotFound = 133, + VRInitError_Init_VRDashboardStartupFailed = 134, + VRInitError_Init_VRHomeNotFound = 135, + VRInitError_Init_VRHomeStartupFailed = 136, + VRInitError_Init_RebootingBusy = 137, + VRInitError_Init_FirmwareUpdateBusy = 138, + VRInitError_Init_FirmwareRecoveryBusy = 139, - - VRInitError_Driver_Failed = 200, - VRInitError_Driver_Unknown = 201, - VRInitError_Driver_HmdUnknown = 202, - VRInitError_Driver_NotLoaded = 203, - VRInitError_Driver_RuntimeOutOfDate = 204, - VRInitError_Driver_HmdInUse = 205, - VRInitError_Driver_NotCalibrated = 206, - VRInitError_Driver_CalibrationInvalid = 207, - VRInitError_Driver_HmdDisplayNotFound = 208, + VRInitError_Driver_Failed = 200, + VRInitError_Driver_Unknown = 201, + VRInitError_Driver_HmdUnknown = 202, + VRInitError_Driver_NotLoaded = 203, + VRInitError_Driver_RuntimeOutOfDate = 204, + VRInitError_Driver_HmdInUse = 205, + VRInitError_Driver_NotCalibrated = 206, + VRInitError_Driver_CalibrationInvalid = 207, + VRInitError_Driver_HmdDisplayNotFound = 208, VRInitError_Driver_TrackedDeviceInterfaceUnknown = 209, // VRInitError_Driver_HmdDisplayNotFoundAfterFix = 210, // not needed: here for historic reasons - VRInitError_Driver_HmdDriverIdOutOfBounds = 211, - VRInitError_Driver_HmdDisplayMirrored = 212, + VRInitError_Driver_HmdDriverIdOutOfBounds = 211, + VRInitError_Driver_HmdDisplayMirrored = 212, - VRInitError_IPC_ServerInitFailed = 300, - VRInitError_IPC_ConnectFailed = 301, - VRInitError_IPC_SharedStateInitFailed = 302, - VRInitError_IPC_CompositorInitFailed = 303, - VRInitError_IPC_MutexInitFailed = 304, - VRInitError_IPC_Failed = 305, - VRInitError_IPC_CompositorConnectFailed = 306, + VRInitError_IPC_ServerInitFailed = 300, + VRInitError_IPC_ConnectFailed = 301, + VRInitError_IPC_SharedStateInitFailed = 302, + VRInitError_IPC_CompositorInitFailed = 303, + VRInitError_IPC_MutexInitFailed = 304, + VRInitError_IPC_Failed = 305, + VRInitError_IPC_CompositorConnectFailed = 306, VRInitError_IPC_CompositorInvalidConnectResponse = 307, VRInitError_IPC_ConnectFailedAfterMultipleAttempts = 308, - VRInitError_Compositor_Failed = 400, - VRInitError_Compositor_D3D11HardwareRequired = 401, - VRInitError_Compositor_FirmwareRequiresUpdate = 402, - VRInitError_Compositor_OverlayInitFailed = 403, - VRInitError_Compositor_ScreenshotsInitFailed = 404, - VRInitError_Compositor_UnableToCreateDevice = 405, + VRInitError_Compositor_Failed = 400, + VRInitError_Compositor_D3D11HardwareRequired = 401, + VRInitError_Compositor_FirmwareRequiresUpdate = 402, + VRInitError_Compositor_OverlayInitFailed = 403, + VRInitError_Compositor_ScreenshotsInitFailed = 404, + VRInitError_Compositor_UnableToCreateDevice = 405, - VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000, + VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000, - VRInitError_VendorSpecific_HmdFound_CantOpenDevice = 1101, - VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102, - VRInitError_VendorSpecific_HmdFound_NoStoredConfig = 1103, - VRInitError_VendorSpecific_HmdFound_ConfigTooBig = 1104, - VRInitError_VendorSpecific_HmdFound_ConfigTooSmall = 1105, - VRInitError_VendorSpecific_HmdFound_UnableToInitZLib = 1106, - VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion = 1107, - VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart = 1108, - VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart = 1109, - VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext = 1110, - VRInitError_VendorSpecific_HmdFound_UserDataAddressRange = 1111, - VRInitError_VendorSpecific_HmdFound_UserDataError = 1112, - VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck = 1113, + VRInitError_VendorSpecific_HmdFound_CantOpenDevice = 1101, + VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102, + VRInitError_VendorSpecific_HmdFound_NoStoredConfig = 1103, + VRInitError_VendorSpecific_HmdFound_ConfigTooBig = 1104, + VRInitError_VendorSpecific_HmdFound_ConfigTooSmall = 1105, + VRInitError_VendorSpecific_HmdFound_UnableToInitZLib = 1106, + VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion = 1107, + VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart = 1108, + VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart = 1109, + VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext = 1110, + VRInitError_VendorSpecific_HmdFound_UserDataAddressRange = 1111, + VRInitError_VendorSpecific_HmdFound_UserDataError = 1112, + VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck = 1113, VRInitError_Steam_SteamInstallationNotFound = 2000, }; @@ -1123,7 +1097,7 @@ enum EVRInitError enum EVRScreenshotType { VRScreenshotType_None = 0, - VRScreenshotType_Mono = 1, // left eye only + VRScreenshotType_Mono = 1, // left eye only VRScreenshotType_Stereo = 2, VRScreenshotType_Cubemap = 3, VRScreenshotType_MonoPanorama = 4, @@ -1138,35 +1112,35 @@ enum EVRScreenshotPropertyFilenames enum EVRTrackedCameraError { - VRTrackedCameraError_None = 0, - VRTrackedCameraError_OperationFailed = 100, - VRTrackedCameraError_InvalidHandle = 101, - VRTrackedCameraError_InvalidFrameHeaderVersion = 102, - VRTrackedCameraError_OutOfHandles = 103, - VRTrackedCameraError_IPCFailure = 104, - VRTrackedCameraError_NotSupportedForThisDevice = 105, - VRTrackedCameraError_SharedMemoryFailure = 106, - VRTrackedCameraError_FrameBufferingFailure = 107, - VRTrackedCameraError_StreamSetupFailure = 108, - VRTrackedCameraError_InvalidGLTextureId = 109, + VRTrackedCameraError_None = 0, + VRTrackedCameraError_OperationFailed = 100, + VRTrackedCameraError_InvalidHandle = 101, + VRTrackedCameraError_InvalidFrameHeaderVersion = 102, + VRTrackedCameraError_OutOfHandles = 103, + VRTrackedCameraError_IPCFailure = 104, + VRTrackedCameraError_NotSupportedForThisDevice = 105, + VRTrackedCameraError_SharedMemoryFailure = 106, + VRTrackedCameraError_FrameBufferingFailure = 107, + VRTrackedCameraError_StreamSetupFailure = 108, + VRTrackedCameraError_InvalidGLTextureId = 109, VRTrackedCameraError_InvalidSharedTextureHandle = 110, - VRTrackedCameraError_FailedToGetGLTextureId = 111, - VRTrackedCameraError_SharedTextureFailure = 112, - VRTrackedCameraError_NoFrameAvailable = 113, - VRTrackedCameraError_InvalidArgument = 114, - VRTrackedCameraError_InvalidFrameBufferSize = 115, + VRTrackedCameraError_FailedToGetGLTextureId = 111, + VRTrackedCameraError_SharedTextureFailure = 112, + VRTrackedCameraError_NoFrameAvailable = 113, + VRTrackedCameraError_InvalidArgument = 114, + VRTrackedCameraError_InvalidFrameBufferSize = 115, }; enum EVRTrackedCameraFrameType { - VRTrackedCameraFrameType_Distorted = 0, // This is the camera video frame size in pixels, still distorted. - VRTrackedCameraFrameType_Undistorted, // In pixels, an undistorted inscribed rectangle region without invalid regions. This size is subject to changes shortly. - VRTrackedCameraFrameType_MaximumUndistorted, // In pixels, maximum undistorted with invalid regions. Non zero alpha component identifies valid regions. + VRTrackedCameraFrameType_Distorted = 0, // This is the camera video frame size in pixels, still distorted. + VRTrackedCameraFrameType_Undistorted, // In pixels, an undistorted inscribed rectangle region without invalid regions. This size is subject to changes shortly. + VRTrackedCameraFrameType_MaximumUndistorted, // In pixels, maximum undistorted with invalid regions. Non zero alpha component identifies valid regions. MAX_CAMERA_FRAME_TYPES }; typedef uint64_t TrackedCameraHandle_t; -#define INVALID_TRACKED_CAMERA_HANDLE ((vr::TrackedCameraHandle_t)0) +#define INVALID_TRACKED_CAMERA_HANDLE ((vr::TrackedCameraHandle_t)0) struct CameraVideoStreamFrameHeader_t { @@ -1186,15 +1160,15 @@ typedef uint32_t ScreenshotHandle_t; static const uint32_t k_unScreenshotHandleInvalid = 0; -#pragma pack( pop ) +#pragma pack(pop) // figure out how to import from the VR API dll #if defined(_WIN32) #ifdef VR_API_EXPORT -#define VR_INTERFACE extern "C" __declspec( dllexport ) +#define VR_INTERFACE extern "C" __declspec(dllexport) #else -#define VR_INTERFACE extern "C" __declspec( dllimport ) +#define VR_INTERFACE extern "C" __declspec(dllimport) #endif #elif defined(__GNUC__) || defined(COMPILER_GCC) || defined(__APPLE__) @@ -1202,59 +1176,56 @@ static const uint32_t k_unScreenshotHandleInvalid = 0; #ifdef VR_API_EXPORT #define VR_INTERFACE extern "C" __attribute__((visibility("default"))) #else -#define VR_INTERFACE extern "C" +#define VR_INTERFACE extern "C" #endif #else #error "Unsupported Platform." #endif - -#if defined( _WIN32 ) +#if defined(_WIN32) #define VR_CALLTYPE __cdecl #else -#define VR_CALLTYPE +#define VR_CALLTYPE #endif -} // namespace vr - -#endif // _INCLUDE_VRTYPES_H +} // namespace vr +#endif // _INCLUDE_VRTYPES_H // vrannotation.h #ifdef API_GEN -# define VR_CLANG_ATTR(ATTR) __attribute__((annotate( ATTR ))) +#define VR_CLANG_ATTR(ATTR) __attribute__((annotate(ATTR))) #else -# define VR_CLANG_ATTR(ATTR) +#define VR_CLANG_ATTR(ATTR) #endif -#define VR_METHOD_DESC(DESC) VR_CLANG_ATTR( "desc:" #DESC ";" ) -#define VR_IGNOREATTR() VR_CLANG_ATTR( "ignore" ) -#define VR_OUT_STRUCT() VR_CLANG_ATTR( "out_struct: ;" ) -#define VR_OUT_STRING() VR_CLANG_ATTR( "out_string: ;" ) -#define VR_OUT_ARRAY_CALL(COUNTER,FUNCTION,PARAMS) VR_CLANG_ATTR( "out_array_call:" #COUNTER "," #FUNCTION "," #PARAMS ";" ) -#define VR_OUT_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR( "out_array_count:" #COUNTER ";" ) -#define VR_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR( "array_count:" #COUNTER ";" ) -#define VR_ARRAY_COUNT_D(COUNTER, DESC) VR_CLANG_ATTR( "array_count:" #COUNTER ";desc:" #DESC ) -#define VR_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR( "buffer_count:" #COUNTER ";" ) -#define VR_OUT_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR( "out_buffer_count:" #COUNTER ";" ) -#define VR_OUT_STRING_COUNT(COUNTER) VR_CLANG_ATTR( "out_string_count:" #COUNTER ";" ) +#define VR_METHOD_DESC(DESC) VR_CLANG_ATTR("desc:" #DESC ";") +#define VR_IGNOREATTR() VR_CLANG_ATTR("ignore") +#define VR_OUT_STRUCT() VR_CLANG_ATTR("out_struct: ;") +#define VR_OUT_STRING() VR_CLANG_ATTR("out_string: ;") +#define VR_OUT_ARRAY_CALL(COUNTER, FUNCTION, PARAMS) VR_CLANG_ATTR("out_array_call:" #COUNTER "," #FUNCTION "," #PARAMS ";") +#define VR_OUT_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR("out_array_count:" #COUNTER ";") +#define VR_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR("array_count:" #COUNTER ";") +#define VR_ARRAY_COUNT_D(COUNTER, DESC) VR_CLANG_ATTR("array_count:" #COUNTER ";desc:" #DESC) +#define VR_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR("buffer_count:" #COUNTER ";") +#define VR_OUT_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR("out_buffer_count:" #COUNTER ";") +#define VR_OUT_STRING_COUNT(COUNTER) VR_CLANG_ATTR("out_string_count:" #COUNTER ";") // vrtrackedcameratypes.h #ifndef _VRTRACKEDCAMERATYPES_H -#define _VRTRACKEDCAMERATYPES_H +#define _VRTRACKEDCAMERATYPES_H namespace vr { - -#pragma pack( push, 8 ) +#pragma pack(push, 8) enum ECameraVideoStreamFormat { CVS_FORMAT_UNKNOWN = 0, - CVS_FORMAT_RAW10 = 1, // 10 bits per pixel - CVS_FORMAT_NV12 = 2, // 12 bits per pixel - CVS_FORMAT_RGB24 = 3, // 24 bits per pixel + CVS_FORMAT_RAW10 = 1, // 10 bits per pixel + CVS_FORMAT_NV12 = 2, // 12 bits per pixel + CVS_FORMAT_RGB24 = 3, // 24 bits per pixel CVS_MAX_FORMATS }; @@ -1277,30 +1248,31 @@ enum ECameraCompatibilityMode }; #ifdef _MSC_VER -#define VR_CAMERA_DECL_ALIGN( x ) __declspec( align( x ) ) +#define VR_CAMERA_DECL_ALIGN(x) __declspec(align(x)) #else -#define VR_CAMERA_DECL_ALIGN( x ) // +#define VR_CAMERA_DECL_ALIGN(x) // #endif -#define MAX_CAMERA_FRAME_SHARED_HANDLES 4 +#define MAX_CAMERA_FRAME_SHARED_HANDLES 4 -VR_CAMERA_DECL_ALIGN( 8 ) struct CameraVideoStreamFrame_t +VR_CAMERA_DECL_ALIGN(8) +struct CameraVideoStreamFrame_t { ECameraVideoStreamFormat m_nStreamFormat; uint32_t m_nWidth; uint32_t m_nHeight; - uint32_t m_nImageDataSize; // Based on stream format, width, height + uint32_t m_nImageDataSize; // Based on stream format, width, height - uint32_t m_nFrameSequence; // Starts from 0 when stream starts. + uint32_t m_nFrameSequence; // Starts from 0 when stream starts. - uint32_t m_nBufferIndex; // Identifies which buffer the image data is hosted - uint32_t m_nBufferCount; // Total number of configured buffers + uint32_t m_nBufferIndex; // Identifies which buffer the image data is hosted + uint32_t m_nBufferCount; // Total number of configured buffers uint32_t m_nExposureTime; - uint32_t m_nISPFrameTimeStamp; // Driver provided time stamp per driver centric time base + uint32_t m_nISPFrameTimeStamp; // Driver provided time stamp per driver centric time base uint32_t m_nISPReferenceTimeStamp; uint32_t m_nSyncCounter; @@ -1309,241 +1281,239 @@ VR_CAMERA_DECL_ALIGN( 8 ) struct CameraVideoStreamFrame_t double m_flReferenceCamSyncTime; - double m_flFrameElapsedTime; // Starts from 0 when stream starts. In seconds. + double m_flFrameElapsedTime; // Starts from 0 when stream starts. In seconds. double m_flFrameDeliveryRate; - double m_flFrameCaptureTime_DriverAbsolute; // In USB time, via AuxEvent - double m_flFrameCaptureTime_ServerRelative; // In System time within the server - uint64_t m_nFrameCaptureTicks_ServerAbsolute; // In system ticks within the server - double m_flFrameCaptureTime_ClientRelative; // At the client, relative to when the frame was exposed/captured. + double m_flFrameCaptureTime_DriverAbsolute; // In USB time, via AuxEvent + double m_flFrameCaptureTime_ServerRelative; // In System time within the server + uint64_t m_nFrameCaptureTicks_ServerAbsolute; // In system ticks within the server + double m_flFrameCaptureTime_ClientRelative; // At the client, relative to when the frame was exposed/captured. double m_flSyncMarkerError; - TrackedDevicePose_t m_StandingTrackedDevicePose; // Supplied by HMD layer when used as a tracked camera + TrackedDevicePose_t m_StandingTrackedDevicePose; // Supplied by HMD layer when used as a tracked camera uint64_t m_pImageData; }; -#pragma pack( pop ) +#pragma pack(pop) -} +} // namespace vr -#endif // _VRTRACKEDCAMERATYPES_H +#endif // _VRTRACKEDCAMERATYPES_H // ivrsettings.h namespace vr { - enum EVRSettingsError - { - VRSettingsError_None = 0, - VRSettingsError_IPCFailed = 1, - VRSettingsError_WriteFailed = 2, - VRSettingsError_ReadFailed = 3, - VRSettingsError_JsonParseFailed = 4, - VRSettingsError_UnsetSettingHasNoDefault = 5, // This will be returned if the setting does not appear in the appropriate default file and has not been set - }; +enum EVRSettingsError +{ + VRSettingsError_None = 0, + VRSettingsError_IPCFailed = 1, + VRSettingsError_WriteFailed = 2, + VRSettingsError_ReadFailed = 3, + VRSettingsError_JsonParseFailed = 4, + VRSettingsError_UnsetSettingHasNoDefault = 5, // This will be returned if the setting does not appear in the appropriate default file and has not been set +}; - // The maximum length of a settings key - static const uint32_t k_unMaxSettingsKeyLength = 128; +// The maximum length of a settings key +static const uint32_t k_unMaxSettingsKeyLength = 128; - class IVRSettings - { - public: - virtual const char *GetSettingsErrorNameFromEnum( EVRSettingsError eError ) = 0; +class IVRSettings +{ +public: + virtual const char *GetSettingsErrorNameFromEnum(EVRSettingsError eError) = 0; - // Returns true if file sync occurred (force or settings dirty) - virtual bool Sync( bool bForce = false, EVRSettingsError *peError = nullptr ) = 0; + // Returns true if file sync occurred (force or settings dirty) + virtual bool Sync(bool bForce = false, EVRSettingsError *peError = nullptr) = 0; - virtual void SetBool( const char *pchSection, const char *pchSettingsKey, bool bValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetInt32( const char *pchSection, const char *pchSettingsKey, int32_t nValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetFloat( const char *pchSection, const char *pchSettingsKey, float flValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetString( const char *pchSection, const char *pchSettingsKey, const char *pchValue, EVRSettingsError *peError = nullptr ) = 0; + virtual void SetBool(const char *pchSection, const char *pchSettingsKey, bool bValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetInt32(const char *pchSection, const char *pchSettingsKey, int32_t nValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetFloat(const char *pchSection, const char *pchSettingsKey, float flValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetString(const char *pchSection, const char *pchSettingsKey, const char *pchValue, EVRSettingsError *peError = nullptr) = 0; - // Users of the system need to provide a proper default in default.vrsettings in the resources/settings/ directory - // of either the runtime or the driver_xxx directory. Otherwise the default will be false, 0, 0.0 or "" - virtual bool GetBool( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual int32_t GetInt32( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual float GetFloat( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual void GetString( const char *pchSection, const char *pchSettingsKey, VR_OUT_STRING() char *pchValue, uint32_t unValueLen, EVRSettingsError *peError = nullptr ) = 0; + // Users of the system need to provide a proper default in default.vrsettings in the resources/settings/ directory + // of either the runtime or the driver_xxx directory. Otherwise the default will be false, 0, 0.0 or "" + virtual bool GetBool(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual int32_t GetInt32(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual float GetFloat(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual void GetString(const char *pchSection, const char *pchSettingsKey, VR_OUT_STRING() char *pchValue, uint32_t unValueLen, EVRSettingsError *peError = nullptr) = 0; - virtual void RemoveSection( const char *pchSection, EVRSettingsError *peError = nullptr ) = 0; - virtual void RemoveKeyInSection( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - }; + virtual void RemoveSection(const char *pchSection, EVRSettingsError *peError = nullptr) = 0; + virtual void RemoveKeyInSection(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; +}; - //----------------------------------------------------------------------------- - static const char * const IVRSettings_Version = "IVRSettings_002"; +//----------------------------------------------------------------------------- +static const char *const IVRSettings_Version = "IVRSettings_002"; - //----------------------------------------------------------------------------- - // steamvr keys - static const char * const k_pch_SteamVR_Section = "steamvr"; - static const char * const k_pch_SteamVR_RequireHmd_String = "requireHmd"; - static const char * const k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; - static const char * const k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; - static const char * const k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; - static const char * const k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; - static const char * const k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; - static const char * const k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; - static const char * const k_pch_SteamVR_SendSystemButtonToAllApps_Bool= "sendSystemButtonToAllApps"; - static const char * const k_pch_SteamVR_LogLevel_Int32 = "loglevel"; - static const char * const k_pch_SteamVR_IPD_Float = "ipd"; - static const char * const k_pch_SteamVR_Background_String = "background"; - static const char * const k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; - static const char * const k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; - static const char * const k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; - static const char * const k_pch_SteamVR_GridColor_String = "gridColor"; - static const char * const k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; - static const char * const k_pch_SteamVR_ShowStage_Bool = "showStage"; - static const char * const k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; - static const char * const k_pch_SteamVR_DirectMode_Bool = "directMode"; - static const char * const k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; - static const char * const k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; - static const char * const k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; - static const char * const k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; - static const char * const k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; - static const char * const k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; - static const char * const k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; - static const char * const k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; - static const char * const k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; - static const char * const k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; - static const char * const k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; - static const char * const k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; - static const char * const k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; - static const char * const k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; - static const char * const k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; - static const char * const k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; - static const char * const k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; - static const char * const k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; - static const char * const k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; - static const char * const k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; - static const char * const k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; - static const char * const k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; - static const char * const k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; - static const char * const k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; +//----------------------------------------------------------------------------- +// steamvr keys +static const char *const k_pch_SteamVR_Section = "steamvr"; +static const char *const k_pch_SteamVR_RequireHmd_String = "requireHmd"; +static const char *const k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; +static const char *const k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; +static const char *const k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; +static const char *const k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; +static const char *const k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; +static const char *const k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; +static const char *const k_pch_SteamVR_SendSystemButtonToAllApps_Bool = "sendSystemButtonToAllApps"; +static const char *const k_pch_SteamVR_LogLevel_Int32 = "loglevel"; +static const char *const k_pch_SteamVR_IPD_Float = "ipd"; +static const char *const k_pch_SteamVR_Background_String = "background"; +static const char *const k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; +static const char *const k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; +static const char *const k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; +static const char *const k_pch_SteamVR_GridColor_String = "gridColor"; +static const char *const k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; +static const char *const k_pch_SteamVR_ShowStage_Bool = "showStage"; +static const char *const k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; +static const char *const k_pch_SteamVR_DirectMode_Bool = "directMode"; +static const char *const k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; +static const char *const k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; +static const char *const k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; +static const char *const k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; +static const char *const k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; +static const char *const k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; +static const char *const k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; +static const char *const k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; +static const char *const k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; +static const char *const k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; +static const char *const k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; +static const char *const k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; +static const char *const k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; +static const char *const k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; +static const char *const k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; +static const char *const k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; +static const char *const k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; +static const char *const k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; +static const char *const k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; +static const char *const k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; +static const char *const k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; +static const char *const k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; +static const char *const k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; +static const char *const k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; - //----------------------------------------------------------------------------- - // lighthouse keys - static const char * const k_pch_Lighthouse_Section = "driver_lighthouse"; - static const char * const k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; - static const char * const k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; - static const char * const k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; - static const char * const k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; - static const char * const k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; +//----------------------------------------------------------------------------- +// lighthouse keys +static const char *const k_pch_Lighthouse_Section = "driver_lighthouse"; +static const char *const k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; +static const char *const k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; +static const char *const k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; +static const char *const k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; +static const char *const k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; - //----------------------------------------------------------------------------- - // null keys - static const char * const k_pch_Null_Section = "driver_null"; - static const char * const k_pch_Null_SerialNumber_String = "serialNumber"; - static const char * const k_pch_Null_ModelNumber_String = "modelNumber"; - static const char * const k_pch_Null_WindowX_Int32 = "windowX"; - static const char * const k_pch_Null_WindowY_Int32 = "windowY"; - static const char * const k_pch_Null_WindowWidth_Int32 = "windowWidth"; - static const char * const k_pch_Null_WindowHeight_Int32 = "windowHeight"; - static const char * const k_pch_Null_RenderWidth_Int32 = "renderWidth"; - static const char * const k_pch_Null_RenderHeight_Int32 = "renderHeight"; - static const char * const k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; - static const char * const k_pch_Null_DisplayFrequency_Float = "displayFrequency"; +//----------------------------------------------------------------------------- +// null keys +static const char *const k_pch_Null_Section = "driver_null"; +static const char *const k_pch_Null_SerialNumber_String = "serialNumber"; +static const char *const k_pch_Null_ModelNumber_String = "modelNumber"; +static const char *const k_pch_Null_WindowX_Int32 = "windowX"; +static const char *const k_pch_Null_WindowY_Int32 = "windowY"; +static const char *const k_pch_Null_WindowWidth_Int32 = "windowWidth"; +static const char *const k_pch_Null_WindowHeight_Int32 = "windowHeight"; +static const char *const k_pch_Null_RenderWidth_Int32 = "renderWidth"; +static const char *const k_pch_Null_RenderHeight_Int32 = "renderHeight"; +static const char *const k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; +static const char *const k_pch_Null_DisplayFrequency_Float = "displayFrequency"; - //----------------------------------------------------------------------------- - // user interface keys - static const char * const k_pch_UserInterface_Section = "userinterface"; - static const char * const k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; - static const char * const k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; - static const char * const k_pch_UserInterface_Screenshots_Bool = "screenshots"; - static const char * const k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; +//----------------------------------------------------------------------------- +// user interface keys +static const char *const k_pch_UserInterface_Section = "userinterface"; +static const char *const k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; +static const char *const k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; +static const char *const k_pch_UserInterface_Screenshots_Bool = "screenshots"; +static const char *const k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; - //----------------------------------------------------------------------------- - // notification keys - static const char * const k_pch_Notifications_Section = "notifications"; - static const char * const k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; +//----------------------------------------------------------------------------- +// notification keys +static const char *const k_pch_Notifications_Section = "notifications"; +static const char *const k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; - //----------------------------------------------------------------------------- - // keyboard keys - static const char * const k_pch_Keyboard_Section = "keyboard"; - static const char * const k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; - static const char * const k_pch_Keyboard_ScaleX = "ScaleX"; - static const char * const k_pch_Keyboard_ScaleY = "ScaleY"; - static const char * const k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; - static const char * const k_pch_Keyboard_OffsetRightX = "OffsetRightX"; - static const char * const k_pch_Keyboard_OffsetY = "OffsetY"; - static const char * const k_pch_Keyboard_Smoothing = "Smoothing"; +//----------------------------------------------------------------------------- +// keyboard keys +static const char *const k_pch_Keyboard_Section = "keyboard"; +static const char *const k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; +static const char *const k_pch_Keyboard_ScaleX = "ScaleX"; +static const char *const k_pch_Keyboard_ScaleY = "ScaleY"; +static const char *const k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; +static const char *const k_pch_Keyboard_OffsetRightX = "OffsetRightX"; +static const char *const k_pch_Keyboard_OffsetY = "OffsetY"; +static const char *const k_pch_Keyboard_Smoothing = "Smoothing"; - //----------------------------------------------------------------------------- - // perf keys - static const char * const k_pch_Perf_Section = "perfcheck"; - static const char * const k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; - static const char * const k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; - static const char * const k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; - static const char * const k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; - static const char * const k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; - static const char * const k_pch_Perf_TestData_Float = "perfTestData"; - static const char * const k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; +//----------------------------------------------------------------------------- +// perf keys +static const char *const k_pch_Perf_Section = "perfcheck"; +static const char *const k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; +static const char *const k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; +static const char *const k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; +static const char *const k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; +static const char *const k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; +static const char *const k_pch_Perf_TestData_Float = "perfTestData"; +static const char *const k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; - //----------------------------------------------------------------------------- - // collision bounds keys - static const char * const k_pch_CollisionBounds_Section = "collisionBounds"; - static const char * const k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; - static const char * const k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; - static const char * const k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; - static const char * const k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; - static const char * const k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; - static const char * const k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; - static const char * const k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; - static const char * const k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; - static const char * const k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; +//----------------------------------------------------------------------------- +// collision bounds keys +static const char *const k_pch_CollisionBounds_Section = "collisionBounds"; +static const char *const k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; +static const char *const k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; +static const char *const k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; +static const char *const k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; +static const char *const k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; +static const char *const k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; +static const char *const k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; +static const char *const k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; +static const char *const k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; - //----------------------------------------------------------------------------- - // camera keys - static const char * const k_pch_Camera_Section = "camera"; - static const char * const k_pch_Camera_EnableCamera_Bool = "enableCamera"; - static const char * const k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; - static const char * const k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; - static const char * const k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; - static const char * const k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; - static const char * const k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; - static const char * const k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; - static const char * const k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; - static const char * const k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; +//----------------------------------------------------------------------------- +// camera keys +static const char *const k_pch_Camera_Section = "camera"; +static const char *const k_pch_Camera_EnableCamera_Bool = "enableCamera"; +static const char *const k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; +static const char *const k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; +static const char *const k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; +static const char *const k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; +static const char *const k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; +static const char *const k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; +static const char *const k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; +static const char *const k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; - //----------------------------------------------------------------------------- - // audio keys - static const char * const k_pch_audio_Section = "audio"; - static const char * const k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; - static const char * const k_pch_audio_OnRecordDevice_String = "onRecordDevice"; - static const char * const k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; - static const char * const k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; - static const char * const k_pch_audio_OffRecordDevice_String = "offRecordDevice"; - static const char * const k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; +//----------------------------------------------------------------------------- +// audio keys +static const char *const k_pch_audio_Section = "audio"; +static const char *const k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; +static const char *const k_pch_audio_OnRecordDevice_String = "onRecordDevice"; +static const char *const k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; +static const char *const k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; +static const char *const k_pch_audio_OffRecordDevice_String = "offRecordDevice"; +static const char *const k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; - //----------------------------------------------------------------------------- - // power management keys - static const char * const k_pch_Power_Section = "power"; - static const char * const k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; - static const char * const k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; - static const char * const k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; - static const char * const k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; - static const char * const k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; - static const char * const k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; +//----------------------------------------------------------------------------- +// power management keys +static const char *const k_pch_Power_Section = "power"; +static const char *const k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; +static const char *const k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; +static const char *const k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; +static const char *const k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; +static const char *const k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; +static const char *const k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; - //----------------------------------------------------------------------------- - // dashboard keys - static const char * const k_pch_Dashboard_Section = "dashboard"; - static const char * const k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; - static const char * const k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; +//----------------------------------------------------------------------------- +// dashboard keys +static const char *const k_pch_Dashboard_Section = "dashboard"; +static const char *const k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; +static const char *const k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; - //----------------------------------------------------------------------------- - // model skin keys - static const char * const k_pch_modelskin_Section = "modelskins"; +//----------------------------------------------------------------------------- +// model skin keys +static const char *const k_pch_modelskin_Section = "modelskins"; - //----------------------------------------------------------------------------- - // driver keys - These could be checked in any driver_ section - static const char * const k_pch_Driver_Enable_Bool = "enable"; +//----------------------------------------------------------------------------- +// driver keys - These could be checked in any driver_ section +static const char *const k_pch_Driver_Enable_Bool = "enable"; -} // namespace vr +} // namespace vr // iservertrackeddevicedriver.h namespace vr { - - struct DriverPoseQuaternion_t { double w, x, y, z; @@ -1573,10 +1543,10 @@ struct DriverPose_t * lagged due to the filtering required to reduce noise to an acceptable level. */ vr::HmdQuaternion_t qWorldFromDriverRotation; - double vecWorldFromDriverTranslation[ 3 ]; + double vecWorldFromDriverTranslation[3]; vr::HmdQuaternion_t qDriverFromHeadRotation; - double vecDriverFromHeadTranslation[ 3 ]; + double vecDriverFromHeadTranslation[3]; /* State of driver pose, in meters and radians. */ /* Position of the driver tracking reference in driver world space @@ -1584,13 +1554,13 @@ struct DriverPose_t * +[1] (y) is up * -[2] (z) is forward */ - double vecPosition[ 3 ]; + double vecPosition[3]; /* Velocity of the pose in meters/second */ - double vecVelocity[ 3 ]; + double vecVelocity[3]; /* Acceleration of the pose in meters/second */ - double vecAcceleration[ 3 ]; + double vecAcceleration[3]; /* Orientation of the tracker, represented as a quaternion */ vr::HmdQuaternion_t qRotation; @@ -1599,13 +1569,13 @@ struct DriverPose_t * representation. The direction is the angle of * rotation and the magnitude is the angle around * that axis in radians/second. */ - double vecAngularVelocity[ 3 ]; + double vecAngularVelocity[3]; /* Angular acceleration of the pose in axis-angle * representation. The direction is the angle of * rotation and the magnitude is the angle around * that axis in radians/second^2. */ - double vecAngularAcceleration[ 3 ]; + double vecAngularAcceleration[3]; ETrackingResult result; @@ -1615,14 +1585,12 @@ struct DriverPose_t bool deviceIsConnected; }; - // ---------------------------------------------------------------------------------------------- // Purpose: Represents a single tracked device in a driver // ---------------------------------------------------------------------------------------------- class ITrackedDeviceServerDriver { public: - // ------------------------------------ // Management Methods // ------------------------------------ @@ -1631,7 +1599,7 @@ public: * ITrackedDeviceServerDriver object should be kept to a minimum until it is activated. * The pose listener is guaranteed to be valid until Deactivate is called, but * should not be used after that point. */ - virtual EVRInitError Activate( uint32_t unObjectId ) = 0; + virtual EVRInitError Activate(uint32_t unObjectId) = 0; /** This is called when The VR system is switching from this Hmd being the active display * to another Hmd being the active display. The driver should clean whatever memory @@ -1643,12 +1611,12 @@ public: /** Requests a component interface of the driver for device-specific functionality. The driver should return NULL * if the requested interface or version is not supported. */ - virtual void *GetComponent( const char *pchComponentNameAndVersion ) = 0; + virtual void *GetComponent(const char *pchComponentNameAndVersion) = 0; /** A VR Client has made this debug request of the driver. The set of valid requests is entirely * up to the driver and the client to figure out, as is the format of the response. Responses that * exceed the length of the supplied buffer should be truncated and null terminated */ - virtual void DebugRequest( const char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize ) = 0; + virtual void DebugRequest(const char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize) = 0; // ------------------------------------ // Tracking Methods @@ -1656,177 +1624,160 @@ public: virtual DriverPose_t GetPose() = 0; }; - - static const char *ITrackedDeviceServerDriver_Version = "ITrackedDeviceServerDriver_005"; -} +} // namespace vr // ivrdisplaycomponent.h namespace vr { +// ---------------------------------------------------------------------------------------------- +// Purpose: The display component on a single tracked device +// ---------------------------------------------------------------------------------------------- +class IVRDisplayComponent +{ +public: + // ------------------------------------ + // Display Methods + // ------------------------------------ + /** Size and position that the window needs to be on the VR display. */ + virtual void GetWindowBounds(int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight) = 0; - // ---------------------------------------------------------------------------------------------- - // Purpose: The display component on a single tracked device - // ---------------------------------------------------------------------------------------------- - class IVRDisplayComponent - { - public: + /** Returns true if the display is extending the desktop. */ + virtual bool IsDisplayOnDesktop() = 0; - // ------------------------------------ - // Display Methods - // ------------------------------------ + /** Returns true if the display is real and not a fictional display. */ + virtual bool IsDisplayRealDisplay() = 0; - /** Size and position that the window needs to be on the VR display. */ - virtual void GetWindowBounds( int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; + /** Suggested size for the intermediate render target that the distortion pulls from. */ + virtual void GetRecommendedRenderTargetSize(uint32_t *pnWidth, uint32_t *pnHeight) = 0; - /** Returns true if the display is extending the desktop. */ - virtual bool IsDisplayOnDesktop( ) = 0; + /** Gets the viewport in the frame buffer to draw the output of the distortion into */ + virtual void GetEyeOutputViewport(EVREye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight) = 0; - /** Returns true if the display is real and not a fictional display. */ - virtual bool IsDisplayRealDisplay( ) = 0; - - /** Suggested size for the intermediate render target that the distortion pulls from. */ - virtual void GetRecommendedRenderTargetSize( uint32_t *pnWidth, uint32_t *pnHeight ) = 0; - - /** Gets the viewport in the frame buffer to draw the output of the distortion into */ - virtual void GetEyeOutputViewport( EVREye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; - - /** The components necessary to build your own projection matrix in case your + /** The components necessary to build your own projection matrix in case your * application is doing something fancy like infinite Z */ - virtual void GetProjectionRaw( EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom ) = 0; + virtual void GetProjectionRaw(EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom) = 0; - /** Returns the result of the distortion function for the specified eye and input UVs. UVs go from 0,0 in + /** Returns the result of the distortion function for the specified eye and input UVs. UVs go from 0,0 in * the upper left of that eye's viewport and 1,1 in the lower right of that eye's viewport. */ - virtual DistortionCoordinates_t ComputeDistortion( EVREye eEye, float fU, float fV ) = 0; + virtual DistortionCoordinates_t ComputeDistortion(EVREye eEye, float fU, float fV) = 0; +}; - }; +static const char *IVRDisplayComponent_Version = "IVRDisplayComponent_002"; - static const char *IVRDisplayComponent_Version = "IVRDisplayComponent_002"; - -} +} // namespace vr // ivrdriverdirectmodecomponent.h namespace vr { +// ---------------------------------------------------------------------------------------------- +// Purpose: This component is used for drivers that implement direct mode entirely on their own +// without allowing the VR Compositor to own the window/device. Chances are you don't +// need to implement this component in your driver. +// ---------------------------------------------------------------------------------------------- +class IVRDriverDirectModeComponent +{ +public: + // ----------------------------------- + // Direct mode methods + // ----------------------------------- + /** Specific to Oculus compositor support, textures supplied must be created using this method. */ + virtual void CreateSwapTextureSet(uint32_t unPid, uint32_t unFormat, uint32_t unWidth, uint32_t unHeight, vr::SharedTextureHandle_t (*pSharedTextureHandles)[3]) {} - // ---------------------------------------------------------------------------------------------- - // Purpose: This component is used for drivers that implement direct mode entirely on their own - // without allowing the VR Compositor to own the window/device. Chances are you don't - // need to implement this component in your driver. - // ---------------------------------------------------------------------------------------------- - class IVRDriverDirectModeComponent - { - public: + /** Used to textures created using CreateSwapTextureSet. Only one of the set's handles needs to be used to destroy the entire set. */ + virtual void DestroySwapTextureSet(vr::SharedTextureHandle_t sharedTextureHandle) {} - // ----------------------------------- - // Direct mode methods - // ----------------------------------- + /** Used to purge all texture sets for a given process. */ + virtual void DestroyAllSwapTextureSets(uint32_t unPid) {} - /** Specific to Oculus compositor support, textures supplied must be created using this method. */ - virtual void CreateSwapTextureSet( uint32_t unPid, uint32_t unFormat, uint32_t unWidth, uint32_t unHeight, vr::SharedTextureHandle_t( *pSharedTextureHandles )[ 3 ] ) {} + /** After Present returns, calls this to get the next index to use for rendering. */ + virtual void GetNextSwapTextureSetIndex(vr::SharedTextureHandle_t sharedTextureHandles[2], uint32_t (*pIndices)[2]) {} - /** Used to textures created using CreateSwapTextureSet. Only one of the set's handles needs to be used to destroy the entire set. */ - virtual void DestroySwapTextureSet( vr::SharedTextureHandle_t sharedTextureHandle ) {} - - /** Used to purge all texture sets for a given process. */ - virtual void DestroyAllSwapTextureSets( uint32_t unPid ) {} - - /** After Present returns, calls this to get the next index to use for rendering. */ - virtual void GetNextSwapTextureSetIndex( vr::SharedTextureHandle_t sharedTextureHandles[ 2 ], uint32_t( *pIndices )[ 2 ] ) {} - - /** Call once per layer to draw for this frame. One shared texture handle per eye. Textures must be created + /** Call once per layer to draw for this frame. One shared texture handle per eye. Textures must be created * using CreateSwapTextureSet and should be alternated per frame. Call Present once all layers have been submitted. */ - virtual void SubmitLayer( vr::SharedTextureHandle_t sharedTextureHandles[ 2 ], const vr::VRTextureBounds_t( &bounds )[ 2 ], const vr::HmdMatrix34_t *pPose ) {} + virtual void SubmitLayer(vr::SharedTextureHandle_t sharedTextureHandles[2], const vr::VRTextureBounds_t (&bounds)[2], const vr::HmdMatrix34_t *pPose) {} - /** Submits queued layers for display. */ - virtual void Present( vr::SharedTextureHandle_t syncTexture ) {} + /** Submits queued layers for display. */ + virtual void Present(vr::SharedTextureHandle_t syncTexture) {} +}; - }; +static const char *IVRDriverDirectModeComponent_Version = "IVRDriverDirectModeComponent_002"; - static const char *IVRDriverDirectModeComponent_Version = "IVRDriverDirectModeComponent_002"; - -} +} // namespace vr // ivrcontrollercomponent.h namespace vr { +// ---------------------------------------------------------------------------------------------- +// Purpose: Controller access on a single tracked device. +// ---------------------------------------------------------------------------------------------- +class IVRControllerComponent +{ +public: + // ------------------------------------ + // Controller Methods + // ------------------------------------ + /** Gets the current state of a controller. */ + virtual VRControllerState_t GetControllerState() = 0; - // ---------------------------------------------------------------------------------------------- - // Purpose: Controller access on a single tracked device. - // ---------------------------------------------------------------------------------------------- - class IVRControllerComponent - { - public: + /** Returns a uint64 property. If the property is not available this function will return 0. */ + virtual bool TriggerHapticPulse(uint32_t unAxisId, uint16_t usPulseDurationMicroseconds) = 0; +}; - // ------------------------------------ - // Controller Methods - // ------------------------------------ +static const char *IVRControllerComponent_Version = "IVRControllerComponent_001"; - /** Gets the current state of a controller. */ - virtual VRControllerState_t GetControllerState( ) = 0; - - /** Returns a uint64 property. If the property is not available this function will return 0. */ - virtual bool TriggerHapticPulse( uint32_t unAxisId, uint16_t usPulseDurationMicroseconds ) = 0; - - }; - - - - static const char *IVRControllerComponent_Version = "IVRControllerComponent_001"; - -} +} // namespace vr // ivrcameracomponent.h namespace vr { - //----------------------------------------------------------------------------- - //----------------------------------------------------------------------------- - class ICameraVideoSinkCallback - { - public: - virtual void OnCameraVideoSinkCallback() = 0; - }; +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +class ICameraVideoSinkCallback +{ +public: + virtual void OnCameraVideoSinkCallback() = 0; +}; - // ---------------------------------------------------------------------------------------------- - // Purpose: The camera on a single tracked device - // ---------------------------------------------------------------------------------------------- - class IVRCameraComponent - { - public: - // ------------------------------------ - // Camera Methods - // ------------------------------------ - virtual bool GetCameraFrameDimensions( vr::ECameraVideoStreamFormat nVideoStreamFormat, uint32_t *pWidth, uint32_t *pHeight ) = 0; - virtual bool GetCameraFrameBufferingRequirements( int *pDefaultFrameQueueSize, uint32_t *pFrameBufferDataSize ) = 0; - virtual bool SetCameraFrameBuffering( int nFrameBufferCount, void **ppFrameBuffers, uint32_t nFrameBufferDataSize ) = 0; - virtual bool SetCameraVideoStreamFormat( vr::ECameraVideoStreamFormat nVideoStreamFormat ) = 0; - virtual vr::ECameraVideoStreamFormat GetCameraVideoStreamFormat() = 0; - virtual bool StartVideoStream() = 0; - virtual void StopVideoStream() = 0; - virtual bool IsVideoStreamActive( bool *pbPaused, float *pflElapsedTime ) = 0; - virtual const vr::CameraVideoStreamFrame_t *GetVideoStreamFrame() = 0; - virtual void ReleaseVideoStreamFrame( const vr::CameraVideoStreamFrame_t *pFrameImage ) = 0; - virtual bool SetAutoExposure( bool bEnable ) = 0; - virtual bool PauseVideoStream() = 0; - virtual bool ResumeVideoStream() = 0; - virtual bool GetCameraDistortion( float flInputU, float flInputV, float *pflOutputU, float *pflOutputV ) = 0; - virtual bool GetCameraProjection( vr::EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, vr::HmdMatrix44_t *pProjection ) = 0; - virtual bool SetFrameRate( int nISPFrameRate, int nSensorFrameRate ) = 0; - virtual bool SetCameraVideoSinkCallback( vr::ICameraVideoSinkCallback *pCameraVideoSinkCallback ) = 0; - virtual bool GetCameraCompatibilityMode( vr::ECameraCompatibilityMode *pCameraCompatibilityMode ) = 0; - virtual bool SetCameraCompatibilityMode( vr::ECameraCompatibilityMode nCameraCompatibilityMode ) = 0; - virtual bool GetCameraFrameBounds( vr::EVRTrackedCameraFrameType eFrameType, uint32_t *pLeft, uint32_t *pTop, uint32_t *pWidth, uint32_t *pHeight ) = 0; - virtual bool GetCameraIntrinsics( vr::EVRTrackedCameraFrameType eFrameType, HmdVector2_t *pFocalLength, HmdVector2_t *pCenter ) = 0; - }; +// ---------------------------------------------------------------------------------------------- +// Purpose: The camera on a single tracked device +// ---------------------------------------------------------------------------------------------- +class IVRCameraComponent +{ +public: + // ------------------------------------ + // Camera Methods + // ------------------------------------ + virtual bool GetCameraFrameDimensions(vr::ECameraVideoStreamFormat nVideoStreamFormat, uint32_t *pWidth, uint32_t *pHeight) = 0; + virtual bool GetCameraFrameBufferingRequirements(int *pDefaultFrameQueueSize, uint32_t *pFrameBufferDataSize) = 0; + virtual bool SetCameraFrameBuffering(int nFrameBufferCount, void **ppFrameBuffers, uint32_t nFrameBufferDataSize) = 0; + virtual bool SetCameraVideoStreamFormat(vr::ECameraVideoStreamFormat nVideoStreamFormat) = 0; + virtual vr::ECameraVideoStreamFormat GetCameraVideoStreamFormat() = 0; + virtual bool StartVideoStream() = 0; + virtual void StopVideoStream() = 0; + virtual bool IsVideoStreamActive(bool *pbPaused, float *pflElapsedTime) = 0; + virtual const vr::CameraVideoStreamFrame_t *GetVideoStreamFrame() = 0; + virtual void ReleaseVideoStreamFrame(const vr::CameraVideoStreamFrame_t *pFrameImage) = 0; + virtual bool SetAutoExposure(bool bEnable) = 0; + virtual bool PauseVideoStream() = 0; + virtual bool ResumeVideoStream() = 0; + virtual bool GetCameraDistortion(float flInputU, float flInputV, float *pflOutputU, float *pflOutputV) = 0; + virtual bool GetCameraProjection(vr::EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, vr::HmdMatrix44_t *pProjection) = 0; + virtual bool SetFrameRate(int nISPFrameRate, int nSensorFrameRate) = 0; + virtual bool SetCameraVideoSinkCallback(vr::ICameraVideoSinkCallback *pCameraVideoSinkCallback) = 0; + virtual bool GetCameraCompatibilityMode(vr::ECameraCompatibilityMode *pCameraCompatibilityMode) = 0; + virtual bool SetCameraCompatibilityMode(vr::ECameraCompatibilityMode nCameraCompatibilityMode) = 0; + virtual bool GetCameraFrameBounds(vr::EVRTrackedCameraFrameType eFrameType, uint32_t *pLeft, uint32_t *pTop, uint32_t *pWidth, uint32_t *pHeight) = 0; + virtual bool GetCameraIntrinsics(vr::EVRTrackedCameraFrameType eFrameType, HmdVector2_t *pFocalLength, HmdVector2_t *pCenter) = 0; +}; - static const char *IVRCameraComponent_Version = "IVRCameraComponent_002"; -} +static const char *IVRCameraComponent_Version = "IVRCameraComponent_002"; +} // namespace vr // itrackeddevicedriverprovider.h namespace vr { - class ITrackedDeviceServerDriver; struct TrackedDeviceDriverInfo_t; struct DriverPose_t; @@ -1841,13 +1792,12 @@ class IVRDriverContext public: /** Returns the requested interface. If the interface was not available it will return NULL and fill * out the error. */ - virtual void *GetGenericInterface( const char *pchInterfaceVersion, EVRInitError *peError = nullptr ) = 0; + virtual void *GetGenericInterface(const char *pchInterfaceVersion, EVRInitError *peError = nullptr) = 0; /** Returns the property container handle for this driver */ virtual DriverHandle_t GetDriverHandle() = 0; }; - /** This interface must be implemented in each driver. It will be loaded in vrserver.exe */ class IServerTrackedDeviceProvider { @@ -1861,18 +1811,17 @@ public: * config files. * pchDriverInstallDir - The absolute path of the root directory for the driver. */ - virtual EVRInitError Init( IVRDriverContext *pDriverContext ) = 0; + virtual EVRInitError Init(IVRDriverContext *pDriverContext) = 0; /** cleans up the driver right before it is unloaded */ virtual void Cleanup() = 0; /** Returns the version of the ITrackedDeviceServerDriver interface used by this driver */ - virtual const char * const *GetInterfaceVersions() = 0; + virtual const char *const *GetInterfaceVersions() = 0; /** Allows the driver do to some work in the main loop of the server. */ virtual void RunFrame() = 0; - // ------------ Power State Functions ----------------------- // /** Returns true if the driver wants to block Standby mode. */ @@ -1885,21 +1834,16 @@ public: /** Called when the system is leaving Standby mode. The driver should switch itself back to full operation. */ virtual void LeaveStandby() = 0; - }; - static const char *IServerTrackedDeviceProvider_Version = "IServerTrackedDeviceProvider_004"; - - - /** This interface must be implemented in each driver. It will be loaded in vrclient.dll */ class IVRWatchdogProvider { public: /** initializes the driver in watchdog mode. */ - virtual EVRInitError Init( IVRDriverContext *pDriverContext ) = 0; + virtual EVRInitError Init(IVRDriverContext *pDriverContext) = 0; /** cleans up the driver right before it is unloaded */ virtual void Cleanup() = 0; @@ -1907,134 +1851,128 @@ public: static const char *IVRWatchdogProvider_Version = "IVRWatchdogProvider_001"; -} +} // namespace vr // ivrproperties.h #include namespace vr { +enum EPropertyWriteType +{ + PropertyWrite_Set = 0, + PropertyWrite_Erase = 1, + PropertyWrite_SetError = 2 +}; - enum EPropertyWriteType - { - PropertyWrite_Set = 0, - PropertyWrite_Erase = 1, - PropertyWrite_SetError = 2 - }; - - struct PropertyWrite_t - { - ETrackedDeviceProperty prop; - EPropertyWriteType writeType; - ETrackedPropertyError eSetError; - void *pvBuffer; - uint32_t unBufferSize; - PropertyTypeTag_t unTag; - ETrackedPropertyError eError; - }; - - struct PropertyRead_t - { - ETrackedDeviceProperty prop; - void *pvBuffer; - uint32_t unBufferSize; - PropertyTypeTag_t unTag; - uint32_t unRequiredBufferSize; - ETrackedPropertyError eError; - }; +struct PropertyWrite_t +{ + ETrackedDeviceProperty prop; + EPropertyWriteType writeType; + ETrackedPropertyError eSetError; + void *pvBuffer; + uint32_t unBufferSize; + PropertyTypeTag_t unTag; + ETrackedPropertyError eError; +}; +struct PropertyRead_t +{ + ETrackedDeviceProperty prop; + void *pvBuffer; + uint32_t unBufferSize; + PropertyTypeTag_t unTag; + uint32_t unRequiredBufferSize; + ETrackedPropertyError eError; +}; class IVRProperties { public: - /** Reads a set of properties atomically. See the PropertyReadBatch_t struct for more information. */ - virtual ETrackedPropertyError ReadPropertyBatch( PropertyContainerHandle_t ulContainerHandle, PropertyRead_t *pBatch, uint32_t unBatchEntryCount ) = 0; + virtual ETrackedPropertyError ReadPropertyBatch(PropertyContainerHandle_t ulContainerHandle, PropertyRead_t *pBatch, uint32_t unBatchEntryCount) = 0; /** Writes a set of properties atomically. See the PropertyWriteBatch_t struct for more information. */ - virtual ETrackedPropertyError WritePropertyBatch( PropertyContainerHandle_t ulContainerHandle, PropertyWrite_t *pBatch, uint32_t unBatchEntryCount ) = 0; + virtual ETrackedPropertyError WritePropertyBatch(PropertyContainerHandle_t ulContainerHandle, PropertyWrite_t *pBatch, uint32_t unBatchEntryCount) = 0; /** returns a string that corresponds with the specified property error. The string will be the name * of the error enum value for all valid error codes */ - virtual const char *GetPropErrorNameFromEnum( ETrackedPropertyError error ) = 0; + virtual const char *GetPropErrorNameFromEnum(ETrackedPropertyError error) = 0; /** Returns a container handle given a tracked device index */ - virtual PropertyContainerHandle_t TrackedDeviceToPropertyContainer( TrackedDeviceIndex_t nDevice ) = 0; - + virtual PropertyContainerHandle_t TrackedDeviceToPropertyContainer(TrackedDeviceIndex_t nDevice) = 0; }; -static const char * const IVRProperties_Version = "IVRProperties_001"; +static const char *const IVRProperties_Version = "IVRProperties_001"; class CVRPropertyHelpers { public: - CVRPropertyHelpers( IVRProperties * pProperties ) : m_pProperties( pProperties ) {} + CVRPropertyHelpers(IVRProperties *pProperties) : m_pProperties(pProperties) {} /** Returns a scaler property. If the device index is not valid or the property value type does not match, * this function will return false. */ - bool GetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ); - float GetFloatProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ); - int32_t GetInt32Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ); - uint64_t GetUint64Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ); + bool GetBoolProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L); + float GetFloatProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L); + int32_t GetInt32Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L); + uint64_t GetUint64Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L); /** Returns a single typed property. If the device index is not valid or the property is not a string type this function will * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */ - uint32_t GetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() void *pvBuffer, uint32_t unBufferSize, PropertyTypeTag_t *punTag, ETrackedPropertyError *pError = 0L ); - + uint32_t GetProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() void *pvBuffer, uint32_t unBufferSize, PropertyTypeTag_t *punTag, ETrackedPropertyError *pError = 0L); /** Returns a string property. If the device index is not valid or the property is not a string type this function will * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */ - uint32_t GetStringProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L ); + uint32_t GetStringProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L); /** Returns a string property as a std::string. If the device index is not valid or the property is not a string type this function will * return an empty string. */ - std::string GetStringProperty( vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError = nullptr ); + std::string GetStringProperty(vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError = nullptr); /** Sets a scaler property. The new value will be returned on any subsequent call to get this property in any process. */ - ETrackedPropertyError SetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, bool bNewValue ); - ETrackedPropertyError SetFloatProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, float fNewValue ); - ETrackedPropertyError SetInt32Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, int32_t nNewValue ); - ETrackedPropertyError SetUint64Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, uint64_t ulNewValue ); + ETrackedPropertyError SetBoolProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, bool bNewValue); + ETrackedPropertyError SetFloatProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, float fNewValue); + ETrackedPropertyError SetInt32Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, int32_t nNewValue); + ETrackedPropertyError SetUint64Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, uint64_t ulNewValue); /** Sets a string property. The new value will be returned on any subsequent call to get this property in any process. */ - ETrackedPropertyError SetStringProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, const char *pchNewValue ); + ETrackedPropertyError SetStringProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, const char *pchNewValue); /** Sets a single typed property. The new value will be returned on any subsequent call to get this property in any process. */ - ETrackedPropertyError SetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, void *pvNewValue, uint32_t unNewValueSize, PropertyTypeTag_t unTag ); + ETrackedPropertyError SetProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, void *pvNewValue, uint32_t unNewValueSize, PropertyTypeTag_t unTag); /** Sets the error return value for a property. This value will be returned on all subsequent requests to get the property */ - ETrackedPropertyError SetPropertyError( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError eError ); + ETrackedPropertyError SetPropertyError(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError eError); /** Clears any value or error set for the property. */ - ETrackedPropertyError EraseProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop ); + ETrackedPropertyError EraseProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop); /* Turns a device index into a property container handle. */ - PropertyContainerHandle_t TrackedDeviceToPropertyContainer( TrackedDeviceIndex_t nDevice ) { return m_pProperties->TrackedDeviceToPropertyContainer( nDevice ); } + PropertyContainerHandle_t TrackedDeviceToPropertyContainer(TrackedDeviceIndex_t nDevice) { return m_pProperties->TrackedDeviceToPropertyContainer(nDevice); } private: - template - T GetPropertyHelper( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError, T bDefault, PropertyTypeTag_t unTypeTag ); + template + T GetPropertyHelper(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError, T bDefault, PropertyTypeTag_t unTypeTag); IVRProperties *m_pProperties; }; - -inline uint32_t CVRPropertyHelpers::GetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() void *pvBuffer, uint32_t unBufferSize, PropertyTypeTag_t *punTag, ETrackedPropertyError *pError ) +inline uint32_t CVRPropertyHelpers::GetProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() void *pvBuffer, uint32_t unBufferSize, PropertyTypeTag_t *punTag, ETrackedPropertyError *pError) { PropertyRead_t batch; batch.prop = prop; batch.pvBuffer = pvBuffer; batch.unBufferSize = unBufferSize; - m_pProperties->ReadPropertyBatch( ulContainerHandle, &batch, 1 ); + m_pProperties->ReadPropertyBatch(ulContainerHandle, &batch, 1); - if ( pError ) + if (pError) { *pError = batch.eError; } - if ( punTag ) + if (punTag) { *punTag = batch.unTag; } @@ -2042,9 +1980,8 @@ inline uint32_t CVRPropertyHelpers::GetProperty( PropertyContainerHandle_t ulCon return batch.unRequiredBufferSize; } - /** Sets a single typed property. The new value will be returned on any subsequent call to get this property in any process. */ -inline ETrackedPropertyError CVRPropertyHelpers::SetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, void *pvNewValue, uint32_t unNewValueSize, PropertyTypeTag_t unTag ) +inline ETrackedPropertyError CVRPropertyHelpers::SetProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, void *pvNewValue, uint32_t unNewValueSize, PropertyTypeTag_t unTag) { PropertyWrite_t batch; batch.writeType = PropertyWrite_Set; @@ -2053,33 +1990,32 @@ inline ETrackedPropertyError CVRPropertyHelpers::SetProperty( PropertyContainerH batch.unBufferSize = unNewValueSize; batch.unTag = unTag; - m_pProperties->WritePropertyBatch( ulContainerHandle, &batch, 1 ); + m_pProperties->WritePropertyBatch(ulContainerHandle, &batch, 1); return batch.eError; } - /** Returns a string property. If the device index is not valid or the property is not a string type this function will * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */ -inline uint32_t CVRPropertyHelpers::GetStringProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError ) +inline uint32_t CVRPropertyHelpers::GetStringProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError) { PropertyTypeTag_t unTag; ETrackedPropertyError error; - uint32_t unRequiredSize = GetProperty( ulContainerHandle, prop, pchValue, unBufferSize, &unTag, &error ); - if ( unTag != k_unStringPropertyTag && error == TrackedProp_Success ) + uint32_t unRequiredSize = GetProperty(ulContainerHandle, prop, pchValue, unBufferSize, &unTag, &error); + if (unTag != k_unStringPropertyTag && error == TrackedProp_Success) { error = TrackedProp_WrongDataType; } - if ( pError ) + if (pError) { *pError = error; } - if ( error != TrackedProp_Success ) + if (error != TrackedProp_Success) { - if ( pchValue && unBufferSize ) + if (pchValue && unBufferSize) { *pchValue = '\0'; } @@ -2088,30 +2024,29 @@ inline uint32_t CVRPropertyHelpers::GetStringProperty( PropertyContainerHandle_t return unRequiredSize; } - /** Returns a string property as a std::string. If the device index is not valid or the property is not a string type this function will * return an empty string. */ -inline std::string CVRPropertyHelpers::GetStringProperty( vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError ) +inline std::string CVRPropertyHelpers::GetStringProperty(vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError) { char buf[1024]; vr::ETrackedPropertyError err; - uint32_t unRequiredBufferLen = GetStringProperty( ulContainer, prop, buf, sizeof(buf), &err ); + uint32_t unRequiredBufferLen = GetStringProperty(ulContainer, prop, buf, sizeof(buf), &err); std::string sResult; - if ( err == TrackedProp_Success ) + if (err == TrackedProp_Success) { sResult = buf; } - else if ( err == TrackedProp_BufferTooSmall ) + else if (err == TrackedProp_BufferTooSmall) { char *pchBuffer = new char[unRequiredBufferLen]; - unRequiredBufferLen = GetStringProperty( ulContainer, prop, pchBuffer, unRequiredBufferLen, &err ); + unRequiredBufferLen = GetStringProperty(ulContainer, prop, pchBuffer, unRequiredBufferLen, &err); sResult = pchBuffer; delete[] pchBuffer; } - if ( peError ) + if (peError) { *peError = err; } @@ -2119,39 +2054,37 @@ inline std::string CVRPropertyHelpers::GetStringProperty( vr::PropertyContainerH return sResult; } - /** Sets a string property. The new value will be returned on any subsequent call to get this property in any process. */ -inline ETrackedPropertyError CVRPropertyHelpers::SetStringProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, const char *pchNewValue ) +inline ETrackedPropertyError CVRPropertyHelpers::SetStringProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, const char *pchNewValue) { - if ( !pchNewValue ) + if (!pchNewValue) return TrackedProp_InvalidOperation; // this is strlen without the dependency on string.h const char *pchCurr = pchNewValue; - while ( *pchCurr ) + while (*pchCurr) { pchCurr++; } - return SetProperty( ulContainerHandle, prop, (void *)pchNewValue, (uint32_t)(pchCurr - pchNewValue) + 1, k_unStringPropertyTag ); + return SetProperty(ulContainerHandle, prop, (void *)pchNewValue, (uint32_t)(pchCurr - pchNewValue) + 1, k_unStringPropertyTag); } - -template -inline T CVRPropertyHelpers::GetPropertyHelper( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError, T bDefault, PropertyTypeTag_t unTypeTag ) +template +inline T CVRPropertyHelpers::GetPropertyHelper(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError, T bDefault, PropertyTypeTag_t unTypeTag) { T bValue; ETrackedPropertyError eError; PropertyTypeTag_t unReadTag; - GetProperty( ulContainerHandle, prop, &bValue, sizeof( bValue ), &unReadTag, &eError ); - if ( unReadTag != unTypeTag && eError == TrackedProp_Success ) + GetProperty(ulContainerHandle, prop, &bValue, sizeof(bValue), &unReadTag, &eError); + if (unReadTag != unTypeTag && eError == TrackedProp_Success) { eError = TrackedProp_WrongDataType; }; - if ( pError ) + if (pError) *pError = eError; - if ( eError != TrackedProp_Success ) + if (eError != TrackedProp_Success) { return bDefault; } @@ -2161,96 +2094,89 @@ inline T CVRPropertyHelpers::GetPropertyHelper( PropertyContainerHandle_t ulCont } } - -inline bool CVRPropertyHelpers::GetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) +inline bool CVRPropertyHelpers::GetBoolProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError) { - return GetPropertyHelper( ulContainerHandle, prop, pError, false, k_unBoolPropertyTag ); + return GetPropertyHelper(ulContainerHandle, prop, pError, false, k_unBoolPropertyTag); } - -inline float CVRPropertyHelpers::GetFloatProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) +inline float CVRPropertyHelpers::GetFloatProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError) { - return GetPropertyHelper( ulContainerHandle, prop, pError, 0.f, k_unFloatPropertyTag ); + return GetPropertyHelper(ulContainerHandle, prop, pError, 0.f, k_unFloatPropertyTag); } -inline int32_t CVRPropertyHelpers::GetInt32Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) +inline int32_t CVRPropertyHelpers::GetInt32Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError) { - return GetPropertyHelper( ulContainerHandle, prop, pError, 0, k_unInt32PropertyTag ); + return GetPropertyHelper(ulContainerHandle, prop, pError, 0, k_unInt32PropertyTag); } -inline uint64_t CVRPropertyHelpers::GetUint64Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) +inline uint64_t CVRPropertyHelpers::GetUint64Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError) { - return GetPropertyHelper( ulContainerHandle, prop, pError, 0, k_unUint64PropertyTag ); + return GetPropertyHelper(ulContainerHandle, prop, pError, 0, k_unUint64PropertyTag); } -inline ETrackedPropertyError CVRPropertyHelpers::SetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, bool bNewValue ) +inline ETrackedPropertyError CVRPropertyHelpers::SetBoolProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, bool bNewValue) { - return SetProperty( ulContainerHandle, prop, &bNewValue, sizeof( bNewValue ), k_unBoolPropertyTag ); + return SetProperty(ulContainerHandle, prop, &bNewValue, sizeof(bNewValue), k_unBoolPropertyTag); } -inline ETrackedPropertyError CVRPropertyHelpers::SetFloatProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, float fNewValue ) +inline ETrackedPropertyError CVRPropertyHelpers::SetFloatProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, float fNewValue) { - return SetProperty( ulContainerHandle, prop, &fNewValue, sizeof( fNewValue ), k_unFloatPropertyTag ); + return SetProperty(ulContainerHandle, prop, &fNewValue, sizeof(fNewValue), k_unFloatPropertyTag); } -inline ETrackedPropertyError CVRPropertyHelpers::SetInt32Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, int32_t nNewValue ) +inline ETrackedPropertyError CVRPropertyHelpers::SetInt32Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, int32_t nNewValue) { - return SetProperty( ulContainerHandle, prop, &nNewValue, sizeof( nNewValue ), k_unInt32PropertyTag ); + return SetProperty(ulContainerHandle, prop, &nNewValue, sizeof(nNewValue), k_unInt32PropertyTag); } -inline ETrackedPropertyError CVRPropertyHelpers::SetUint64Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, uint64_t ulNewValue ) +inline ETrackedPropertyError CVRPropertyHelpers::SetUint64Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, uint64_t ulNewValue) { - return SetProperty( ulContainerHandle, prop, &ulNewValue, sizeof( ulNewValue ), k_unUint64PropertyTag ); + return SetProperty(ulContainerHandle, prop, &ulNewValue, sizeof(ulNewValue), k_unUint64PropertyTag); } /** Sets the error return value for a property. This value will be returned on all subsequent requests to get the property */ -inline ETrackedPropertyError CVRPropertyHelpers::SetPropertyError( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError eError ) +inline ETrackedPropertyError CVRPropertyHelpers::SetPropertyError(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError eError) { PropertyWrite_t batch; batch.writeType = PropertyWrite_SetError; batch.prop = prop; batch.eSetError = eError; - m_pProperties->WritePropertyBatch( ulContainerHandle, &batch, 1 ); + m_pProperties->WritePropertyBatch(ulContainerHandle, &batch, 1); return batch.eError; } /** Clears any value or error set for the property. */ -inline ETrackedPropertyError CVRPropertyHelpers::EraseProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop ) +inline ETrackedPropertyError CVRPropertyHelpers::EraseProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop) { PropertyWrite_t batch; batch.writeType = PropertyWrite_Erase; batch.prop = prop; - m_pProperties->WritePropertyBatch( ulContainerHandle, &batch, 1 ); + m_pProperties->WritePropertyBatch(ulContainerHandle, &batch, 1); return batch.eError; - -} - } +} // namespace vr // ivrdriverlog.h namespace vr { - class IVRDriverLog { public: /** Writes a log message to the log file prefixed with the driver name */ - virtual void Log( const char *pchLogMessage ) = 0; + virtual void Log(const char *pchLogMessage) = 0; }; - static const char *IVRDriverLog_Version = "IVRDriverLog_001"; -} +} // namespace vr // ivrserverdriverhost.h namespace vr { - class ITrackedDeviceServerDriver; struct TrackedDeviceDriverInfo_t; struct DriverPose_t; @@ -2265,74 +2191,73 @@ public: /** Notifies the server that a tracked device has been added. If this function returns true * the server will call Activate on the device. If it returns false some kind of error * has occurred and the device will not be activated. */ - virtual bool TrackedDeviceAdded( const char *pchDeviceSerialNumber, ETrackedDeviceClass eDeviceClass, ITrackedDeviceServerDriver *pDriver ) = 0; + virtual bool TrackedDeviceAdded(const char *pchDeviceSerialNumber, ETrackedDeviceClass eDeviceClass, ITrackedDeviceServerDriver *pDriver) = 0; /** Notifies the server that a tracked device's pose has been updated */ - virtual void TrackedDevicePoseUpdated( uint32_t unWhichDevice, const DriverPose_t & newPose, uint32_t unPoseStructSize ) = 0; + virtual void TrackedDevicePoseUpdated(uint32_t unWhichDevice, const DriverPose_t &newPose, uint32_t unPoseStructSize) = 0; /** Notifies the server that vsync has occurred on the the display attached to the device. This is * only permitted on devices of the HMD class. */ - virtual void VsyncEvent( double vsyncTimeOffsetSeconds ) = 0; + virtual void VsyncEvent(double vsyncTimeOffsetSeconds) = 0; /** notifies the server that the button was pressed */ - virtual void TrackedDeviceButtonPressed( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; + virtual void TrackedDeviceButtonPressed(uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset) = 0; /** notifies the server that the button was unpressed */ - virtual void TrackedDeviceButtonUnpressed( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; + virtual void TrackedDeviceButtonUnpressed(uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset) = 0; /** notifies the server that the button was pressed */ - virtual void TrackedDeviceButtonTouched( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; + virtual void TrackedDeviceButtonTouched(uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset) = 0; /** notifies the server that the button was unpressed */ - virtual void TrackedDeviceButtonUntouched( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; + virtual void TrackedDeviceButtonUntouched(uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset) = 0; /** notifies the server than a controller axis changed */ - virtual void TrackedDeviceAxisUpdated( uint32_t unWhichDevice, uint32_t unWhichAxis, const VRControllerAxis_t & axisState ) = 0; + virtual void TrackedDeviceAxisUpdated(uint32_t unWhichDevice, uint32_t unWhichAxis, const VRControllerAxis_t &axisState) = 0; /** Notifies the server that the proximity sensor on the specified device */ - virtual void ProximitySensorState( uint32_t unWhichDevice, bool bProximitySensorTriggered ) = 0; + virtual void ProximitySensorState(uint32_t unWhichDevice, bool bProximitySensorTriggered) = 0; /** Sends a vendor specific event (VREvent_VendorSpecific_Reserved_Start..VREvent_VendorSpecific_Reserved_End */ - virtual void VendorSpecificEvent( uint32_t unWhichDevice, vr::EVREventType eventType, const VREvent_Data_t & eventData, double eventTimeOffset ) = 0; + virtual void VendorSpecificEvent(uint32_t unWhichDevice, vr::EVREventType eventType, const VREvent_Data_t &eventData, double eventTimeOffset) = 0; /** Returns true if SteamVR is exiting */ virtual bool IsExiting() = 0; /** Returns true and fills the event with the next event on the queue if there is one. If there are no events * this method returns false. uncbVREvent should be the size in bytes of the VREvent_t struct */ - virtual bool PollNextEvent( VREvent_t *pEvent, uint32_t uncbVREvent ) = 0; + virtual bool PollNextEvent(VREvent_t *pEvent, uint32_t uncbVREvent) = 0; /** Provides access to device poses for drivers. Poses are in their "raw" tracking space which is uniquely * defined by each driver providing poses for its devices. It is up to clients of this function to correlate * poses across different drivers. Poses are indexed by their device id, and their associated driver and * other properties can be looked up via IVRProperties. */ - virtual void GetRawTrackedDevicePoses( float fPredictedSecondsFromNow, TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount ) = 0; + virtual void GetRawTrackedDevicePoses(float fPredictedSecondsFromNow, TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount) = 0; /** Notifies the server that a tracked device's display component transforms have been updated. */ - virtual void TrackedDeviceDisplayTransformUpdated( uint32_t unWhichDevice, HmdMatrix34_t eyeToHeadLeft, HmdMatrix34_t eyeToHeadRight ) = 0; + virtual void TrackedDeviceDisplayTransformUpdated(uint32_t unWhichDevice, HmdMatrix34_t eyeToHeadLeft, HmdMatrix34_t eyeToHeadRight) = 0; }; static const char *IVRServerDriverHost_Version = "IVRServerDriverHost_004"; -} +} // namespace vr // ivrhiddenarea.h namespace vr { - class CVRHiddenAreaHelpers { public: - CVRHiddenAreaHelpers( IVRProperties *pProperties ) : m_pProperties( pProperties ) {} + CVRHiddenAreaHelpers(IVRProperties *pProperties) : m_pProperties(pProperties) {} /** Stores a hidden area mesh in a property */ - ETrackedPropertyError SetHiddenArea( EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount ); + ETrackedPropertyError SetHiddenArea(EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount); /** retrieves a hidden area mesh from a property. Returns the vert count read out of the property. */ - uint32_t GetHiddenArea( EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount, ETrackedPropertyError *peError ); + uint32_t GetHiddenArea(EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount, ETrackedPropertyError *peError); private: - ETrackedDeviceProperty GetPropertyEnum( EVREye eEye, EHiddenAreaMeshType type ) + ETrackedDeviceProperty GetPropertyEnum(EVREye eEye, EHiddenAreaMeshType type) { return (ETrackedDeviceProperty)(Prop_DisplayHiddenArea_Binary_Start + ((int)type * 2) + (int)eEye); } @@ -2340,41 +2265,38 @@ private: IVRProperties *m_pProperties; }; - -inline ETrackedPropertyError CVRHiddenAreaHelpers::SetHiddenArea( EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount ) +inline ETrackedPropertyError CVRHiddenAreaHelpers::SetHiddenArea(EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount) { - ETrackedDeviceProperty prop = GetPropertyEnum( eEye, type ); - CVRPropertyHelpers propHelpers( m_pProperties ); - return propHelpers.SetProperty( propHelpers.TrackedDeviceToPropertyContainer( k_unTrackedDeviceIndex_Hmd ), prop, pVerts, sizeof( HmdVector2_t ) * unVertCount, k_unHiddenAreaPropertyTag ); + ETrackedDeviceProperty prop = GetPropertyEnum(eEye, type); + CVRPropertyHelpers propHelpers(m_pProperties); + return propHelpers.SetProperty(propHelpers.TrackedDeviceToPropertyContainer(k_unTrackedDeviceIndex_Hmd), prop, pVerts, sizeof(HmdVector2_t) * unVertCount, k_unHiddenAreaPropertyTag); } - -inline uint32_t CVRHiddenAreaHelpers::GetHiddenArea( EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount, ETrackedPropertyError *peError ) +inline uint32_t CVRHiddenAreaHelpers::GetHiddenArea(EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount, ETrackedPropertyError *peError) { - ETrackedDeviceProperty prop = GetPropertyEnum( eEye, type ); - CVRPropertyHelpers propHelpers( m_pProperties ); + ETrackedDeviceProperty prop = GetPropertyEnum(eEye, type); + CVRPropertyHelpers propHelpers(m_pProperties); ETrackedPropertyError propError; PropertyTypeTag_t unTag; - uint32_t unBytesNeeded = propHelpers.GetProperty( propHelpers.TrackedDeviceToPropertyContainer( k_unTrackedDeviceIndex_Hmd ), prop, pVerts, sizeof( HmdVector2_t )*unVertCount, &unTag, &propError ); - if ( propError == TrackedProp_Success && unTag != k_unHiddenAreaPropertyTag ) + uint32_t unBytesNeeded = propHelpers.GetProperty(propHelpers.TrackedDeviceToPropertyContainer(k_unTrackedDeviceIndex_Hmd), prop, pVerts, sizeof(HmdVector2_t) * unVertCount, &unTag, &propError); + if (propError == TrackedProp_Success && unTag != k_unHiddenAreaPropertyTag) { propError = TrackedProp_WrongDataType; unBytesNeeded = 0; } - if ( peError ) + if (peError) { *peError = propError; } - return unBytesNeeded / sizeof( HmdVector2_t ); + return unBytesNeeded / sizeof(HmdVector2_t); } -} +} // namespace vr // ivrwatchdoghost.h namespace vr { - /** This interface is provided by vrclient to allow the driver to make everything wake up */ class IVRWatchdogHost { @@ -2386,87 +2308,75 @@ public: static const char *IVRWatchdogHost_Version = "IVRWatchdogHost_001"; -}; - - +}; // namespace vr // ivrvirtualdisplay.h namespace vr { - // ---------------------------------------------------------------------------------------------- - // Purpose: This component is used for drivers that implement a virtual display (e.g. wireless). - // ---------------------------------------------------------------------------------------------- - class IVRVirtualDisplay - { - public: +// ---------------------------------------------------------------------------------------------- +// Purpose: This component is used for drivers that implement a virtual display (e.g. wireless). +// ---------------------------------------------------------------------------------------------- +class IVRVirtualDisplay +{ +public: + /** Submits final backbuffer for display. */ + virtual void Present(vr::SharedTextureHandle_t backbufferTextureHandle) = 0; - /** Submits final backbuffer for display. */ - virtual void Present( vr::SharedTextureHandle_t backbufferTextureHandle ) = 0; + /** Block until the last presented buffer start scanning out. */ + virtual void WaitForPresent() = 0; - /** Block until the last presented buffer start scanning out. */ - virtual void WaitForPresent() = 0; + /** Provides timing data for synchronizing with display. */ + virtual bool GetTimeSinceLastVsync(float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter) = 0; +}; - /** Provides timing data for synchronizing with display. */ - virtual bool GetTimeSinceLastVsync( float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter ) = 0; - }; - - static const char *IVRVirtualDisplay_Version = "IVRVirtualDisplay_001"; - - /** Returns the current IVRVirtualDisplay pointer or NULL the interface could not be found. */ - VR_INTERFACE vr::IVRVirtualDisplay *VR_CALLTYPE VRVirtualDisplay(); -} +static const char *IVRVirtualDisplay_Version = "IVRVirtualDisplay_001"; +/** Returns the current IVRVirtualDisplay pointer or NULL the interface could not be found. */ +VR_INTERFACE vr::IVRVirtualDisplay *VR_CALLTYPE VRVirtualDisplay(); +} // namespace vr // ivrresources.h namespace vr { - class IVRResources { public: - // ------------------------------------ // Shared Resource Methods // ------------------------------------ /** Loads the specified resource into the provided buffer if large enough. * Returns the size in bytes of the buffer required to hold the specified resource. */ - virtual uint32_t LoadSharedResource( const char *pchResourceName, char *pchBuffer, uint32_t unBufferLen ) = 0; + virtual uint32_t LoadSharedResource(const char *pchResourceName, char *pchBuffer, uint32_t unBufferLen) = 0; /** Provides the full path to the specified resource. Resource names can include named directories for * drivers and other things, and this resolves all of those and returns the actual physical path. * pchResourceTypeDirectory is the subdirectory of resources to look in. */ - virtual uint32_t GetResourceFullPath( const char *pchResourceName, const char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen ) = 0; + virtual uint32_t GetResourceFullPath(const char *pchResourceName, const char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen) = 0; }; -static const char * const IVRResources_Version = "IVRResources_001"; +static const char *const IVRResources_Version = "IVRResources_001"; - -} +} // namespace vr // ivrdrivermanager.h namespace vr { - class IVRDriverManager { public: virtual uint32_t GetDriverCount() const = 0; /** Returns the length of the number of bytes necessary to hold this string including the trailing null. */ - virtual uint32_t GetDriverName( vr::DriverId_t nDriver, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize ) = 0; + virtual uint32_t GetDriverName(vr::DriverId_t nDriver, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize) = 0; }; -static const char * const IVRDriverManager_Version = "IVRDriverManager_001"; - -} // namespace vr - - - +static const char *const IVRDriverManager_Version = "IVRDriverManager_001"; +} // namespace vr namespace vr { - static const char * const k_InterfaceVersions[] = +static const char *const k_InterfaceVersions[] = { IVRSettings_Version, ITrackedDeviceServerDriver_Version, @@ -2479,217 +2389,207 @@ namespace vr IVRVirtualDisplay_Version, IVRDriverManager_Version, IVRResources_Version, - nullptr - }; + nullptr}; - inline IVRDriverContext *&VRDriverContext() - { - static IVRDriverContext *pHost; - return pHost; - } - - class COpenVRDriverContext - { - public: - COpenVRDriverContext() : m_propertyHelpers(nullptr), m_hiddenAreaHelpers(nullptr) { Clear(); } - void Clear(); - - EVRInitError InitServer(); - EVRInitError InitWatchdog(); - - IVRSettings *VRSettings() - { - if ( m_pVRSettings == nullptr ) - { - EVRInitError eError; - m_pVRSettings = (IVRSettings *)VRDriverContext()->GetGenericInterface( IVRSettings_Version, &eError ); - } - return m_pVRSettings; - } - - IVRProperties *VRPropertiesRaw() - { - if ( m_pVRProperties == nullptr ) - { - EVRInitError eError; - m_pVRProperties = (IVRProperties *)VRDriverContext()->GetGenericInterface( IVRProperties_Version, &eError ); - m_propertyHelpers = CVRPropertyHelpers( m_pVRProperties ); - m_hiddenAreaHelpers = CVRHiddenAreaHelpers( m_pVRProperties ); - } - return m_pVRProperties; - } - - CVRPropertyHelpers *VRProperties() - { - VRPropertiesRaw(); - return &m_propertyHelpers; - } - - CVRHiddenAreaHelpers *VRHiddenArea() - { - VRPropertiesRaw(); - return &m_hiddenAreaHelpers; - } - - IVRServerDriverHost *VRServerDriverHost() - { - if ( m_pVRServerDriverHost == nullptr ) - { - EVRInitError eError; - m_pVRServerDriverHost = (IVRServerDriverHost *)VRDriverContext()->GetGenericInterface( IVRServerDriverHost_Version, &eError ); - } - return m_pVRServerDriverHost; - } - - IVRWatchdogHost *VRWatchdogHost() - { - if ( m_pVRWatchdogHost == nullptr ) - { - EVRInitError eError; - m_pVRWatchdogHost = (IVRWatchdogHost *)VRDriverContext()->GetGenericInterface( IVRWatchdogHost_Version, &eError ); - } - return m_pVRWatchdogHost; - } - - IVRDriverLog *VRDriverLog() - { - if ( m_pVRDriverLog == nullptr ) - { - EVRInitError eError; - m_pVRDriverLog = (IVRDriverLog *)VRDriverContext()->GetGenericInterface( IVRDriverLog_Version, &eError ); - } - return m_pVRDriverLog; - } - - DriverHandle_t VR_CALLTYPE VRDriverHandle() - { - return VRDriverContext()->GetDriverHandle(); - } - - IVRDriverManager *VRDriverManager() - { - if ( !m_pVRDriverManager ) - { - EVRInitError eError; - m_pVRDriverManager = (IVRDriverManager *)VRDriverContext()->GetGenericInterface( IVRDriverManager_Version, &eError ); - } - return m_pVRDriverManager; - } - - IVRResources *VRResources() - { - if ( !m_pVRResources ) - { - EVRInitError eError; - m_pVRResources = (IVRResources *)VRDriverContext()->GetGenericInterface( IVRResources_Version, &eError ); - } - return m_pVRResources; - } - - private: - CVRPropertyHelpers m_propertyHelpers; - CVRHiddenAreaHelpers m_hiddenAreaHelpers; - - IVRSettings *m_pVRSettings; - IVRProperties *m_pVRProperties; - IVRServerDriverHost *m_pVRServerDriverHost; - IVRWatchdogHost *m_pVRWatchdogHost; - IVRDriverLog *m_pVRDriverLog; - IVRDriverManager *m_pVRDriverManager; - IVRResources *m_pVRResources; - }; - - inline COpenVRDriverContext &OpenVRInternal_ModuleServerDriverContext() - { - static void *ctx[sizeof( COpenVRDriverContext ) / sizeof( void * )]; - return *(COpenVRDriverContext *)ctx; // bypass zero-init constructor - } - - inline IVRSettings *VR_CALLTYPE VRSettings() { return OpenVRInternal_ModuleServerDriverContext().VRSettings(); } - inline IVRProperties *VR_CALLTYPE VRPropertiesRaw() { return OpenVRInternal_ModuleServerDriverContext().VRPropertiesRaw(); } - inline CVRPropertyHelpers *VR_CALLTYPE VRProperties() { return OpenVRInternal_ModuleServerDriverContext().VRProperties(); } - inline CVRHiddenAreaHelpers *VR_CALLTYPE VRHiddenArea() { return OpenVRInternal_ModuleServerDriverContext().VRHiddenArea(); } - inline IVRDriverLog *VR_CALLTYPE VRDriverLog() { return OpenVRInternal_ModuleServerDriverContext().VRDriverLog(); } - inline IVRServerDriverHost *VR_CALLTYPE VRServerDriverHost() { return OpenVRInternal_ModuleServerDriverContext().VRServerDriverHost(); } - inline IVRWatchdogHost *VR_CALLTYPE VRWatchdogHost() { return OpenVRInternal_ModuleServerDriverContext().VRWatchdogHost(); } - inline DriverHandle_t VR_CALLTYPE VRDriverHandle() { return OpenVRInternal_ModuleServerDriverContext().VRDriverHandle(); } - inline IVRDriverManager *VR_CALLTYPE VRDriverManager() { return OpenVRInternal_ModuleServerDriverContext().VRDriverManager(); } - inline IVRResources *VR_CALLTYPE VRResources() { return OpenVRInternal_ModuleServerDriverContext().VRResources(); } - - inline void COpenVRDriverContext::Clear() - { - m_pVRSettings = nullptr; - m_pVRProperties = nullptr; - m_pVRServerDriverHost = nullptr; - m_pVRDriverLog = nullptr; - m_pVRWatchdogHost = nullptr; - m_pVRDriverManager = nullptr; - m_pVRResources = nullptr; - } - - inline EVRInitError COpenVRDriverContext::InitServer() - { - Clear(); - if ( !VRServerDriverHost() - || !VRSettings() - || !VRProperties() - || !VRDriverLog() - || !VRDriverManager() - || !VRResources() ) - return VRInitError_Init_InterfaceNotFound; - return VRInitError_None; - } - - inline EVRInitError COpenVRDriverContext::InitWatchdog() - { - Clear(); - if ( !VRWatchdogHost() - || !VRSettings() - || !VRDriverLog() ) - return VRInitError_Init_InterfaceNotFound; - return VRInitError_None; - } - - inline EVRInitError InitServerDriverContext( IVRDriverContext *pContext ) - { - VRDriverContext() = pContext; - return OpenVRInternal_ModuleServerDriverContext().InitServer(); - } - - inline EVRInitError InitWatchdogDriverContext( IVRDriverContext *pContext ) - { - VRDriverContext() = pContext; - return OpenVRInternal_ModuleServerDriverContext().InitWatchdog(); - } - - inline void CleanupDriverContext() - { - VRDriverContext() = nullptr; - OpenVRInternal_ModuleServerDriverContext().Clear(); - } - - #define VR_INIT_SERVER_DRIVER_CONTEXT( pContext ) \ - { \ - vr::EVRInitError eError = vr::InitServerDriverContext( pContext ); \ - if( eError != vr::VRInitError_None ) \ - return eError; \ - } - - #define VR_CLEANUP_SERVER_DRIVER_CONTEXT() \ - vr::CleanupDriverContext(); - - #define VR_INIT_WATCHDOG_DRIVER_CONTEXT( pContext ) \ - { \ - vr::EVRInitError eError = vr::InitWatchdogDriverContext( pContext ); \ - if( eError != vr::VRInitError_None ) \ - return eError; \ - } - - #define VR_CLEANUP_WATCHDOG_DRIVER_CONTEXT() \ - vr::CleanupDriverContext(); +inline IVRDriverContext *&VRDriverContext() +{ + static IVRDriverContext *pHost; + return pHost; } + +class COpenVRDriverContext +{ +public: + COpenVRDriverContext() : m_propertyHelpers(nullptr), m_hiddenAreaHelpers(nullptr) { Clear(); } + void Clear(); + + EVRInitError InitServer(); + EVRInitError InitWatchdog(); + + IVRSettings *VRSettings() + { + if (m_pVRSettings == nullptr) + { + EVRInitError eError; + m_pVRSettings = (IVRSettings *)VRDriverContext()->GetGenericInterface(IVRSettings_Version, &eError); + } + return m_pVRSettings; + } + + IVRProperties *VRPropertiesRaw() + { + if (m_pVRProperties == nullptr) + { + EVRInitError eError; + m_pVRProperties = (IVRProperties *)VRDriverContext()->GetGenericInterface(IVRProperties_Version, &eError); + m_propertyHelpers = CVRPropertyHelpers(m_pVRProperties); + m_hiddenAreaHelpers = CVRHiddenAreaHelpers(m_pVRProperties); + } + return m_pVRProperties; + } + + CVRPropertyHelpers *VRProperties() + { + VRPropertiesRaw(); + return &m_propertyHelpers; + } + + CVRHiddenAreaHelpers *VRHiddenArea() + { + VRPropertiesRaw(); + return &m_hiddenAreaHelpers; + } + + IVRServerDriverHost *VRServerDriverHost() + { + if (m_pVRServerDriverHost == nullptr) + { + EVRInitError eError; + m_pVRServerDriverHost = (IVRServerDriverHost *)VRDriverContext()->GetGenericInterface(IVRServerDriverHost_Version, &eError); + } + return m_pVRServerDriverHost; + } + + IVRWatchdogHost *VRWatchdogHost() + { + if (m_pVRWatchdogHost == nullptr) + { + EVRInitError eError; + m_pVRWatchdogHost = (IVRWatchdogHost *)VRDriverContext()->GetGenericInterface(IVRWatchdogHost_Version, &eError); + } + return m_pVRWatchdogHost; + } + + IVRDriverLog *VRDriverLog() + { + if (m_pVRDriverLog == nullptr) + { + EVRInitError eError; + m_pVRDriverLog = (IVRDriverLog *)VRDriverContext()->GetGenericInterface(IVRDriverLog_Version, &eError); + } + return m_pVRDriverLog; + } + + DriverHandle_t VR_CALLTYPE VRDriverHandle() + { + return VRDriverContext()->GetDriverHandle(); + } + + IVRDriverManager *VRDriverManager() + { + if (!m_pVRDriverManager) + { + EVRInitError eError; + m_pVRDriverManager = (IVRDriverManager *)VRDriverContext()->GetGenericInterface(IVRDriverManager_Version, &eError); + } + return m_pVRDriverManager; + } + + IVRResources *VRResources() + { + if (!m_pVRResources) + { + EVRInitError eError; + m_pVRResources = (IVRResources *)VRDriverContext()->GetGenericInterface(IVRResources_Version, &eError); + } + return m_pVRResources; + } + +private: + CVRPropertyHelpers m_propertyHelpers; + CVRHiddenAreaHelpers m_hiddenAreaHelpers; + + IVRSettings *m_pVRSettings; + IVRProperties *m_pVRProperties; + IVRServerDriverHost *m_pVRServerDriverHost; + IVRWatchdogHost *m_pVRWatchdogHost; + IVRDriverLog *m_pVRDriverLog; + IVRDriverManager *m_pVRDriverManager; + IVRResources *m_pVRResources; +}; + +inline COpenVRDriverContext &OpenVRInternal_ModuleServerDriverContext() +{ + static void *ctx[sizeof(COpenVRDriverContext) / sizeof(void *)]; + return *(COpenVRDriverContext *)ctx; // bypass zero-init constructor +} + +inline IVRSettings *VR_CALLTYPE VRSettings() { return OpenVRInternal_ModuleServerDriverContext().VRSettings(); } +inline IVRProperties *VR_CALLTYPE VRPropertiesRaw() { return OpenVRInternal_ModuleServerDriverContext().VRPropertiesRaw(); } +inline CVRPropertyHelpers *VR_CALLTYPE VRProperties() { return OpenVRInternal_ModuleServerDriverContext().VRProperties(); } +inline CVRHiddenAreaHelpers *VR_CALLTYPE VRHiddenArea() { return OpenVRInternal_ModuleServerDriverContext().VRHiddenArea(); } +inline IVRDriverLog *VR_CALLTYPE VRDriverLog() { return OpenVRInternal_ModuleServerDriverContext().VRDriverLog(); } +inline IVRServerDriverHost *VR_CALLTYPE VRServerDriverHost() { return OpenVRInternal_ModuleServerDriverContext().VRServerDriverHost(); } +inline IVRWatchdogHost *VR_CALLTYPE VRWatchdogHost() { return OpenVRInternal_ModuleServerDriverContext().VRWatchdogHost(); } +inline DriverHandle_t VR_CALLTYPE VRDriverHandle() { return OpenVRInternal_ModuleServerDriverContext().VRDriverHandle(); } +inline IVRDriverManager *VR_CALLTYPE VRDriverManager() { return OpenVRInternal_ModuleServerDriverContext().VRDriverManager(); } +inline IVRResources *VR_CALLTYPE VRResources() { return OpenVRInternal_ModuleServerDriverContext().VRResources(); } + +inline void COpenVRDriverContext::Clear() +{ + m_pVRSettings = nullptr; + m_pVRProperties = nullptr; + m_pVRServerDriverHost = nullptr; + m_pVRDriverLog = nullptr; + m_pVRWatchdogHost = nullptr; + m_pVRDriverManager = nullptr; + m_pVRResources = nullptr; +} + +inline EVRInitError COpenVRDriverContext::InitServer() +{ + Clear(); + if (!VRServerDriverHost() || !VRSettings() || !VRProperties() || !VRDriverLog() || !VRDriverManager() || !VRResources()) + return VRInitError_Init_InterfaceNotFound; + return VRInitError_None; +} + +inline EVRInitError COpenVRDriverContext::InitWatchdog() +{ + Clear(); + if (!VRWatchdogHost() || !VRSettings() || !VRDriverLog()) + return VRInitError_Init_InterfaceNotFound; + return VRInitError_None; +} + +inline EVRInitError InitServerDriverContext(IVRDriverContext *pContext) +{ + VRDriverContext() = pContext; + return OpenVRInternal_ModuleServerDriverContext().InitServer(); +} + +inline EVRInitError InitWatchdogDriverContext(IVRDriverContext *pContext) +{ + VRDriverContext() = pContext; + return OpenVRInternal_ModuleServerDriverContext().InitWatchdog(); +} + +inline void CleanupDriverContext() +{ + VRDriverContext() = nullptr; + OpenVRInternal_ModuleServerDriverContext().Clear(); +} + +#define VR_INIT_SERVER_DRIVER_CONTEXT(pContext) \ + { \ + vr::EVRInitError eError = vr::InitServerDriverContext(pContext); \ + if (eError != vr::VRInitError_None) \ + return eError; \ + } + +#define VR_CLEANUP_SERVER_DRIVER_CONTEXT() \ + vr::CleanupDriverContext(); + +#define VR_INIT_WATCHDOG_DRIVER_CONTEXT(pContext) \ + { \ + vr::EVRInitError eError = vr::InitWatchdogDriverContext(pContext); \ + if (eError != vr::VRInitError_None) \ + return eError; \ + } + +#define VR_CLEANUP_WATCHDOG_DRIVER_CONTEXT() \ + vr::CleanupDriverContext(); +} // namespace vr // End -#endif // _OPENVR_DRIVER_API - - +#endif // _OPENVR_DRIVER_API diff --git a/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/A/Headers/openvr.h b/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/A/Headers/openvr.h index f945dbc1a..80461f968 100644 --- a/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/A/Headers/openvr.h +++ b/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/A/Headers/openvr.h @@ -9,8 +9,6 @@ #include - - // vrtypes.h #ifndef _INCLUDE_VRTYPES_H #define _INCLUDE_VRTYPES_H @@ -27,9 +25,9 @@ struct ID3D12CommandQueue; namespace vr { -#pragma pack( push, 8 ) +#pragma pack(push, 8) -typedef void* glSharedTextureHandle_t; +typedef void *glSharedTextureHandle_t; typedef int32_t glInt_t; typedef uint32_t glUInt_t; @@ -80,7 +78,7 @@ struct HmdColor_t struct HmdQuad_t { - HmdVector3_t vCorners[ 4 ]; + HmdVector3_t vCorners[4]; }; struct HmdRect2_t @@ -107,40 +105,40 @@ enum EVREye enum ETextureType { - TextureType_DirectX = 0, // Handle is an ID3D11Texture - TextureType_OpenGL = 1, // Handle is an OpenGL texture name or an OpenGL render buffer name, depending on submit flags - TextureType_Vulkan = 2, // Handle is a pointer to a VRVulkanTextureData_t structure - TextureType_IOSurface = 3, // Handle is a macOS cross-process-sharable IOSurfaceRef - TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure + TextureType_DirectX = 0, // Handle is an ID3D11Texture + TextureType_OpenGL = 1, // Handle is an OpenGL texture name or an OpenGL render buffer name, depending on submit flags + TextureType_Vulkan = 2, // Handle is a pointer to a VRVulkanTextureData_t structure + TextureType_IOSurface = 3, // Handle is a macOS cross-process-sharable IOSurfaceRef + TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure }; enum EColorSpace { - ColorSpace_Auto = 0, // Assumes 'gamma' for 8-bit per component formats, otherwise 'linear'. This mirrors the DXGI formats which have _SRGB variants. - ColorSpace_Gamma = 1, // Texture data can be displayed directly on the display without any conversion (a.k.a. display native format). - ColorSpace_Linear = 2, // Same as gamma but has been converted to a linear representation using DXGI's sRGB conversion algorithm. + ColorSpace_Auto = 0, // Assumes 'gamma' for 8-bit per component formats, otherwise 'linear'. This mirrors the DXGI formats which have _SRGB variants. + ColorSpace_Gamma = 1, // Texture data can be displayed directly on the display without any conversion (a.k.a. display native format). + ColorSpace_Linear = 2, // Same as gamma but has been converted to a linear representation using DXGI's sRGB conversion algorithm. }; struct Texture_t { - void* handle; // See ETextureType definition above + void *handle; // See ETextureType definition above ETextureType eType; EColorSpace eColorSpace; }; // Handle to a shared texture (HANDLE on Windows obtained using OpenSharedResource). typedef uint64_t SharedTextureHandle_t; -#define INVALID_SHARED_TEXTURE_HANDLE ((vr::SharedTextureHandle_t)0) +#define INVALID_SHARED_TEXTURE_HANDLE ((vr::SharedTextureHandle_t)0) enum ETrackingResult { - TrackingResult_Uninitialized = 1, + TrackingResult_Uninitialized = 1, - TrackingResult_Calibrating_InProgress = 100, - TrackingResult_Calibrating_OutOfRange = 101, + TrackingResult_Calibrating_InProgress = 100, + TrackingResult_Calibrating_OutOfRange = 101, - TrackingResult_Running_OK = 200, - TrackingResult_Running_OutOfRange = 201, + TrackingResult_Running_OK = 200, + TrackingResult_Running_OutOfRange = 201, }; typedef uint32_t DriverId_t; @@ -158,30 +156,28 @@ static const uint32_t k_unTrackedDeviceIndexInvalid = 0xFFFFFFFF; /** Describes what kind of object is being tracked at a given ID */ enum ETrackedDeviceClass { - TrackedDeviceClass_Invalid = 0, // the ID was not valid. - TrackedDeviceClass_HMD = 1, // Head-Mounted Displays - TrackedDeviceClass_Controller = 2, // Tracked controllers - TrackedDeviceClass_GenericTracker = 3, // Generic trackers, similar to controllers - TrackedDeviceClass_TrackingReference = 4, // Camera and base stations that serve as tracking reference points - TrackedDeviceClass_DisplayRedirect = 5, // Accessories that aren't necessarily tracked themselves, but may redirect video output from other tracked devices + TrackedDeviceClass_Invalid = 0, // the ID was not valid. + TrackedDeviceClass_HMD = 1, // Head-Mounted Displays + TrackedDeviceClass_Controller = 2, // Tracked controllers + TrackedDeviceClass_GenericTracker = 3, // Generic trackers, similar to controllers + TrackedDeviceClass_TrackingReference = 4, // Camera and base stations that serve as tracking reference points + TrackedDeviceClass_DisplayRedirect = 5, // Accessories that aren't necessarily tracked themselves, but may redirect video output from other tracked devices }; - /** Describes what specific role associated with a tracked device */ enum ETrackedControllerRole { - TrackedControllerRole_Invalid = 0, // Invalid value for controller type - TrackedControllerRole_LeftHand = 1, // Tracked device associated with the left hand - TrackedControllerRole_RightHand = 2, // Tracked device associated with the right hand + TrackedControllerRole_Invalid = 0, // Invalid value for controller type + TrackedControllerRole_LeftHand = 1, // Tracked device associated with the left hand + TrackedControllerRole_RightHand = 2, // Tracked device associated with the right hand }; - /** describes a single pose for a tracked object */ struct TrackedDevicePose_t { HmdMatrix34_t mDeviceToAbsoluteTracking; - HmdVector3_t vVelocity; // velocity in tracker space in m/s - HmdVector3_t vAngularVelocity; // angular velocity in radians/s (?) + HmdVector3_t vVelocity; // velocity in tracker space in m/s + HmdVector3_t vAngularVelocity; // angular velocity in radians/s (?) ETrackingResult eTrackingResult; bool bPoseIsValid; @@ -194,9 +190,9 @@ struct TrackedDevicePose_t * for the poses it is requesting */ enum ETrackingUniverseOrigin { - TrackingUniverseSeated = 0, // Poses are provided relative to the seated zero pose - TrackingUniverseStanding = 1, // Poses are provided relative to the safe bounds configured by the user - TrackingUniverseRawAndUncalibrated = 2, // Poses are provided in the coordinate system defined by the driver. It has Y up and is unified for devices of the same driver. You usually don't want this one. + TrackingUniverseSeated = 0, // Poses are provided relative to the seated zero pose + TrackingUniverseStanding = 1, // Poses are provided relative to the safe bounds configured by the user + TrackingUniverseRawAndUncalibrated = 2, // Poses are provided in the coordinate system defined by the driver. It has Y up and is unified for devices of the same driver. You usually don't want this one. }; // Refers to a single container of properties @@ -223,146 +219,145 @@ static const PropertyTypeTag_t k_unHiddenAreaPropertyTag = 30; static const PropertyTypeTag_t k_unOpenVRInternalReserved_Start = 1000; static const PropertyTypeTag_t k_unOpenVRInternalReserved_End = 10000; - /** Each entry in this enum represents a property that can be retrieved about a * tracked device. Many fields are only valid for one ETrackedDeviceClass. */ enum ETrackedDeviceProperty { - Prop_Invalid = 0, + Prop_Invalid = 0, // general properties that apply to all device classes - Prop_TrackingSystemName_String = 1000, - Prop_ModelNumber_String = 1001, - Prop_SerialNumber_String = 1002, - Prop_RenderModelName_String = 1003, - Prop_WillDriftInYaw_Bool = 1004, - Prop_ManufacturerName_String = 1005, - Prop_TrackingFirmwareVersion_String = 1006, - Prop_HardwareRevision_String = 1007, - Prop_AllWirelessDongleDescriptions_String = 1008, - Prop_ConnectedWirelessDongle_String = 1009, - Prop_DeviceIsWireless_Bool = 1010, - Prop_DeviceIsCharging_Bool = 1011, - Prop_DeviceBatteryPercentage_Float = 1012, // 0 is empty, 1 is full - Prop_StatusDisplayTransform_Matrix34 = 1013, - Prop_Firmware_UpdateAvailable_Bool = 1014, - Prop_Firmware_ManualUpdate_Bool = 1015, - Prop_Firmware_ManualUpdateURL_String = 1016, - Prop_HardwareRevision_Uint64 = 1017, - Prop_FirmwareVersion_Uint64 = 1018, - Prop_FPGAVersion_Uint64 = 1019, - Prop_VRCVersion_Uint64 = 1020, - Prop_RadioVersion_Uint64 = 1021, - Prop_DongleVersion_Uint64 = 1022, - Prop_BlockServerShutdown_Bool = 1023, - Prop_CanUnifyCoordinateSystemWithHmd_Bool = 1024, - Prop_ContainsProximitySensor_Bool = 1025, - Prop_DeviceProvidesBatteryStatus_Bool = 1026, - Prop_DeviceCanPowerOff_Bool = 1027, - Prop_Firmware_ProgrammingTarget_String = 1028, - Prop_DeviceClass_Int32 = 1029, - Prop_HasCamera_Bool = 1030, - Prop_DriverVersion_String = 1031, - Prop_Firmware_ForceUpdateRequired_Bool = 1032, - Prop_ViveSystemButtonFixRequired_Bool = 1033, - Prop_ParentDriver_Uint64 = 1034, - Prop_ResourceRoot_String = 1035, + Prop_TrackingSystemName_String = 1000, + Prop_ModelNumber_String = 1001, + Prop_SerialNumber_String = 1002, + Prop_RenderModelName_String = 1003, + Prop_WillDriftInYaw_Bool = 1004, + Prop_ManufacturerName_String = 1005, + Prop_TrackingFirmwareVersion_String = 1006, + Prop_HardwareRevision_String = 1007, + Prop_AllWirelessDongleDescriptions_String = 1008, + Prop_ConnectedWirelessDongle_String = 1009, + Prop_DeviceIsWireless_Bool = 1010, + Prop_DeviceIsCharging_Bool = 1011, + Prop_DeviceBatteryPercentage_Float = 1012, // 0 is empty, 1 is full + Prop_StatusDisplayTransform_Matrix34 = 1013, + Prop_Firmware_UpdateAvailable_Bool = 1014, + Prop_Firmware_ManualUpdate_Bool = 1015, + Prop_Firmware_ManualUpdateURL_String = 1016, + Prop_HardwareRevision_Uint64 = 1017, + Prop_FirmwareVersion_Uint64 = 1018, + Prop_FPGAVersion_Uint64 = 1019, + Prop_VRCVersion_Uint64 = 1020, + Prop_RadioVersion_Uint64 = 1021, + Prop_DongleVersion_Uint64 = 1022, + Prop_BlockServerShutdown_Bool = 1023, + Prop_CanUnifyCoordinateSystemWithHmd_Bool = 1024, + Prop_ContainsProximitySensor_Bool = 1025, + Prop_DeviceProvidesBatteryStatus_Bool = 1026, + Prop_DeviceCanPowerOff_Bool = 1027, + Prop_Firmware_ProgrammingTarget_String = 1028, + Prop_DeviceClass_Int32 = 1029, + Prop_HasCamera_Bool = 1030, + Prop_DriverVersion_String = 1031, + Prop_Firmware_ForceUpdateRequired_Bool = 1032, + Prop_ViveSystemButtonFixRequired_Bool = 1033, + Prop_ParentDriver_Uint64 = 1034, + Prop_ResourceRoot_String = 1035, // Properties that are unique to TrackedDeviceClass_HMD - Prop_ReportsTimeSinceVSync_Bool = 2000, - Prop_SecondsFromVsyncToPhotons_Float = 2001, - Prop_DisplayFrequency_Float = 2002, - Prop_UserIpdMeters_Float = 2003, - Prop_CurrentUniverseId_Uint64 = 2004, - Prop_PreviousUniverseId_Uint64 = 2005, - Prop_DisplayFirmwareVersion_Uint64 = 2006, - Prop_IsOnDesktop_Bool = 2007, - Prop_DisplayMCType_Int32 = 2008, - Prop_DisplayMCOffset_Float = 2009, - Prop_DisplayMCScale_Float = 2010, - Prop_EdidVendorID_Int32 = 2011, - Prop_DisplayMCImageLeft_String = 2012, - Prop_DisplayMCImageRight_String = 2013, - Prop_DisplayGCBlackClamp_Float = 2014, - Prop_EdidProductID_Int32 = 2015, - Prop_CameraToHeadTransform_Matrix34 = 2016, - Prop_DisplayGCType_Int32 = 2017, - Prop_DisplayGCOffset_Float = 2018, - Prop_DisplayGCScale_Float = 2019, - Prop_DisplayGCPrescale_Float = 2020, - Prop_DisplayGCImage_String = 2021, - Prop_LensCenterLeftU_Float = 2022, - Prop_LensCenterLeftV_Float = 2023, - Prop_LensCenterRightU_Float = 2024, - Prop_LensCenterRightV_Float = 2025, - Prop_UserHeadToEyeDepthMeters_Float = 2026, - Prop_CameraFirmwareVersion_Uint64 = 2027, - Prop_CameraFirmwareDescription_String = 2028, - Prop_DisplayFPGAVersion_Uint64 = 2029, - Prop_DisplayBootloaderVersion_Uint64 = 2030, - Prop_DisplayHardwareVersion_Uint64 = 2031, - Prop_AudioFirmwareVersion_Uint64 = 2032, - Prop_CameraCompatibilityMode_Int32 = 2033, + Prop_ReportsTimeSinceVSync_Bool = 2000, + Prop_SecondsFromVsyncToPhotons_Float = 2001, + Prop_DisplayFrequency_Float = 2002, + Prop_UserIpdMeters_Float = 2003, + Prop_CurrentUniverseId_Uint64 = 2004, + Prop_PreviousUniverseId_Uint64 = 2005, + Prop_DisplayFirmwareVersion_Uint64 = 2006, + Prop_IsOnDesktop_Bool = 2007, + Prop_DisplayMCType_Int32 = 2008, + Prop_DisplayMCOffset_Float = 2009, + Prop_DisplayMCScale_Float = 2010, + Prop_EdidVendorID_Int32 = 2011, + Prop_DisplayMCImageLeft_String = 2012, + Prop_DisplayMCImageRight_String = 2013, + Prop_DisplayGCBlackClamp_Float = 2014, + Prop_EdidProductID_Int32 = 2015, + Prop_CameraToHeadTransform_Matrix34 = 2016, + Prop_DisplayGCType_Int32 = 2017, + Prop_DisplayGCOffset_Float = 2018, + Prop_DisplayGCScale_Float = 2019, + Prop_DisplayGCPrescale_Float = 2020, + Prop_DisplayGCImage_String = 2021, + Prop_LensCenterLeftU_Float = 2022, + Prop_LensCenterLeftV_Float = 2023, + Prop_LensCenterRightU_Float = 2024, + Prop_LensCenterRightV_Float = 2025, + Prop_UserHeadToEyeDepthMeters_Float = 2026, + Prop_CameraFirmwareVersion_Uint64 = 2027, + Prop_CameraFirmwareDescription_String = 2028, + Prop_DisplayFPGAVersion_Uint64 = 2029, + Prop_DisplayBootloaderVersion_Uint64 = 2030, + Prop_DisplayHardwareVersion_Uint64 = 2031, + Prop_AudioFirmwareVersion_Uint64 = 2032, + Prop_CameraCompatibilityMode_Int32 = 2033, Prop_ScreenshotHorizontalFieldOfViewDegrees_Float = 2034, Prop_ScreenshotVerticalFieldOfViewDegrees_Float = 2035, - Prop_DisplaySuppressed_Bool = 2036, - Prop_DisplayAllowNightMode_Bool = 2037, - Prop_DisplayMCImageWidth_Int32 = 2038, - Prop_DisplayMCImageHeight_Int32 = 2039, - Prop_DisplayMCImageNumChannels_Int32 = 2040, - Prop_DisplayMCImageData_Binary = 2041, - Prop_SecondsFromPhotonsToVblank_Float = 2042, - Prop_DriverDirectModeSendsVsyncEvents_Bool = 2043, - Prop_DisplayDebugMode_Bool = 2044, - Prop_GraphicsAdapterLuid_Uint64 = 2045, - Prop_DriverProvidedChaperonePath_String = 2048, + Prop_DisplaySuppressed_Bool = 2036, + Prop_DisplayAllowNightMode_Bool = 2037, + Prop_DisplayMCImageWidth_Int32 = 2038, + Prop_DisplayMCImageHeight_Int32 = 2039, + Prop_DisplayMCImageNumChannels_Int32 = 2040, + Prop_DisplayMCImageData_Binary = 2041, + Prop_SecondsFromPhotonsToVblank_Float = 2042, + Prop_DriverDirectModeSendsVsyncEvents_Bool = 2043, + Prop_DisplayDebugMode_Bool = 2044, + Prop_GraphicsAdapterLuid_Uint64 = 2045, + Prop_DriverProvidedChaperonePath_String = 2048, // Properties that are unique to TrackedDeviceClass_Controller - Prop_AttachedDeviceId_String = 3000, - Prop_SupportedButtons_Uint64 = 3001, - Prop_Axis0Type_Int32 = 3002, // Return value is of type EVRControllerAxisType - Prop_Axis1Type_Int32 = 3003, // Return value is of type EVRControllerAxisType - Prop_Axis2Type_Int32 = 3004, // Return value is of type EVRControllerAxisType - Prop_Axis3Type_Int32 = 3005, // Return value is of type EVRControllerAxisType - Prop_Axis4Type_Int32 = 3006, // Return value is of type EVRControllerAxisType - Prop_ControllerRoleHint_Int32 = 3007, // Return value is of type ETrackedControllerRole + Prop_AttachedDeviceId_String = 3000, + Prop_SupportedButtons_Uint64 = 3001, + Prop_Axis0Type_Int32 = 3002, // Return value is of type EVRControllerAxisType + Prop_Axis1Type_Int32 = 3003, // Return value is of type EVRControllerAxisType + Prop_Axis2Type_Int32 = 3004, // Return value is of type EVRControllerAxisType + Prop_Axis3Type_Int32 = 3005, // Return value is of type EVRControllerAxisType + Prop_Axis4Type_Int32 = 3006, // Return value is of type EVRControllerAxisType + Prop_ControllerRoleHint_Int32 = 3007, // Return value is of type ETrackedControllerRole // Properties that are unique to TrackedDeviceClass_TrackingReference - Prop_FieldOfViewLeftDegrees_Float = 4000, - Prop_FieldOfViewRightDegrees_Float = 4001, - Prop_FieldOfViewTopDegrees_Float = 4002, - Prop_FieldOfViewBottomDegrees_Float = 4003, - Prop_TrackingRangeMinimumMeters_Float = 4004, - Prop_TrackingRangeMaximumMeters_Float = 4005, - Prop_ModeLabel_String = 4006, + Prop_FieldOfViewLeftDegrees_Float = 4000, + Prop_FieldOfViewRightDegrees_Float = 4001, + Prop_FieldOfViewTopDegrees_Float = 4002, + Prop_FieldOfViewBottomDegrees_Float = 4003, + Prop_TrackingRangeMinimumMeters_Float = 4004, + Prop_TrackingRangeMaximumMeters_Float = 4005, + Prop_ModeLabel_String = 4006, // Properties that are used for user interface like icons names - Prop_IconPathName_String = 5000, // DEPRECATED. Value not referenced. Now expected to be part of icon path properties. - Prop_NamedIconPathDeviceOff_String = 5001, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceSearching_String = 5002, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceSearchingAlert_String = 5003, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceReady_String = 5004, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceReadyAlert_String = 5005, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceNotReady_String = 5006, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceStandby_String = 5007, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceAlertLow_String = 5008, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_IconPathName_String = 5000, // DEPRECATED. Value not referenced. Now expected to be part of icon path properties. + Prop_NamedIconPathDeviceOff_String = 5001, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceSearching_String = 5002, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceSearchingAlert_String = 5003, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceReady_String = 5004, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceReadyAlert_String = 5005, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceNotReady_String = 5006, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceStandby_String = 5007, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceAlertLow_String = 5008, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others // Properties that are used by helpers, but are opaque to applications - Prop_DisplayHiddenArea_Binary_Start = 5100, - Prop_DisplayHiddenArea_Binary_End = 5150, + Prop_DisplayHiddenArea_Binary_Start = 5100, + Prop_DisplayHiddenArea_Binary_End = 5150, // Properties that are unique to drivers - Prop_UserConfigPath_String = 6000, - Prop_InstallPath_String = 6001, - Prop_HasDisplayComponent_Bool = 6002, - Prop_HasControllerComponent_Bool = 6003, - Prop_HasCameraComponent_Bool = 6004, - Prop_HasDriverDirectModeComponent_Bool = 6005, - Prop_HasVirtualDisplayComponent_Bool = 6006, + Prop_UserConfigPath_String = 6000, + Prop_InstallPath_String = 6001, + Prop_HasDisplayComponent_Bool = 6002, + Prop_HasControllerComponent_Bool = 6003, + Prop_HasCameraComponent_Bool = 6004, + Prop_HasDriverDirectModeComponent_Bool = 6005, + Prop_HasVirtualDisplayComponent_Bool = 6006, // Vendors are free to expose private debug data in this reserved region - Prop_VendorSpecific_Reserved_Start = 10000, - Prop_VendorSpecific_Reserved_End = 10999, + Prop_VendorSpecific_Reserved_Start = 10000, + Prop_VendorSpecific_Reserved_End = 10999, }; /** No string property will ever be longer than this length */ @@ -371,18 +366,18 @@ static const uint32_t k_unMaxPropertyStringSize = 32 * 1024; /** Used to return errors that occur when reading properties. */ enum ETrackedPropertyError { - TrackedProp_Success = 0, - TrackedProp_WrongDataType = 1, - TrackedProp_WrongDeviceClass = 2, - TrackedProp_BufferTooSmall = 3, - TrackedProp_UnknownProperty = 4, // Driver has not set the property (and may not ever). - TrackedProp_InvalidDevice = 5, - TrackedProp_CouldNotContactServer = 6, - TrackedProp_ValueNotProvidedByDevice = 7, - TrackedProp_StringExceedsMaximumLength = 8, - TrackedProp_NotYetAvailable = 9, // The property value isn't known yet, but is expected soon. Call again later. - TrackedProp_PermissionDenied = 10, - TrackedProp_InvalidOperation = 11, + TrackedProp_Success = 0, + TrackedProp_WrongDataType = 1, + TrackedProp_WrongDeviceClass = 2, + TrackedProp_BufferTooSmall = 3, + TrackedProp_UnknownProperty = 4, // Driver has not set the property (and may not ever). + TrackedProp_InvalidDevice = 5, + TrackedProp_CouldNotContactServer = 6, + TrackedProp_ValueNotProvidedByDevice = 7, + TrackedProp_StringExceedsMaximumLength = 8, + TrackedProp_NotYetAvailable = 9, // The property value isn't known yet, but is expected soon. Call again later. + TrackedProp_PermissionDenied = 10, + TrackedProp_InvalidOperation = 11, }; /** Allows the application to control what part of the provided texture will be used in the @@ -396,7 +391,7 @@ struct VRTextureBounds_t /** Allows specifying pose used to render provided scene texture (if different from value returned by WaitGetPoses). */ struct VRTextureWithPose_t : public Texture_t { - HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures. + HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures. }; /** Allows the application to control how scene textures are used by the compositor when calling Submit. */ @@ -424,7 +419,7 @@ enum EVRSubmitFlags * Be sure to call OpenVR_Shutdown before destroying these resources. */ struct VRVulkanTextureData_t { - uint64_t m_nImage; // VkImage + uint64_t m_nImage; // VkImage VkDevice_T *m_pDevice; VkPhysicalDevice_T *m_pPhysicalDevice; VkInstance_T *m_pInstance; @@ -461,220 +456,216 @@ enum EVREventType { VREvent_None = 0, - VREvent_TrackedDeviceActivated = 100, - VREvent_TrackedDeviceDeactivated = 101, - VREvent_TrackedDeviceUpdated = 102, - VREvent_TrackedDeviceUserInteractionStarted = 103, - VREvent_TrackedDeviceUserInteractionEnded = 104, - VREvent_IpdChanged = 105, - VREvent_EnterStandbyMode = 106, - VREvent_LeaveStandbyMode = 107, - VREvent_TrackedDeviceRoleChanged = 108, - VREvent_WatchdogWakeUpRequested = 109, - VREvent_LensDistortionChanged = 110, - VREvent_PropertyChanged = 111, - VREvent_WirelessDisconnect = 112, - VREvent_WirelessReconnect = 113, + VREvent_TrackedDeviceActivated = 100, + VREvent_TrackedDeviceDeactivated = 101, + VREvent_TrackedDeviceUpdated = 102, + VREvent_TrackedDeviceUserInteractionStarted = 103, + VREvent_TrackedDeviceUserInteractionEnded = 104, + VREvent_IpdChanged = 105, + VREvent_EnterStandbyMode = 106, + VREvent_LeaveStandbyMode = 107, + VREvent_TrackedDeviceRoleChanged = 108, + VREvent_WatchdogWakeUpRequested = 109, + VREvent_LensDistortionChanged = 110, + VREvent_PropertyChanged = 111, + VREvent_WirelessDisconnect = 112, + VREvent_WirelessReconnect = 113, - VREvent_ButtonPress = 200, // data is controller - VREvent_ButtonUnpress = 201, // data is controller - VREvent_ButtonTouch = 202, // data is controller - VREvent_ButtonUntouch = 203, // data is controller + VREvent_ButtonPress = 200, // data is controller + VREvent_ButtonUnpress = 201, // data is controller + VREvent_ButtonTouch = 202, // data is controller + VREvent_ButtonUntouch = 203, // data is controller - VREvent_MouseMove = 300, // data is mouse - VREvent_MouseButtonDown = 301, // data is mouse - VREvent_MouseButtonUp = 302, // data is mouse - VREvent_FocusEnter = 303, // data is overlay - VREvent_FocusLeave = 304, // data is overlay - VREvent_Scroll = 305, // data is mouse - VREvent_TouchPadMove = 306, // data is mouse - VREvent_OverlayFocusChanged = 307, // data is overlay, global event + VREvent_MouseMove = 300, // data is mouse + VREvent_MouseButtonDown = 301, // data is mouse + VREvent_MouseButtonUp = 302, // data is mouse + VREvent_FocusEnter = 303, // data is overlay + VREvent_FocusLeave = 304, // data is overlay + VREvent_Scroll = 305, // data is mouse + VREvent_TouchPadMove = 306, // data is mouse + VREvent_OverlayFocusChanged = 307, // data is overlay, global event - VREvent_InputFocusCaptured = 400, // data is process DEPRECATED - VREvent_InputFocusReleased = 401, // data is process DEPRECATED - VREvent_SceneFocusLost = 402, // data is process - VREvent_SceneFocusGained = 403, // data is process - VREvent_SceneApplicationChanged = 404, // data is process - The App actually drawing the scene changed (usually to or from the compositor) - VREvent_SceneFocusChanged = 405, // data is process - New app got access to draw the scene - VREvent_InputFocusChanged = 406, // data is process - VREvent_SceneApplicationSecondaryRenderingStarted = 407, // data is process + VREvent_InputFocusCaptured = 400, // data is process DEPRECATED + VREvent_InputFocusReleased = 401, // data is process DEPRECATED + VREvent_SceneFocusLost = 402, // data is process + VREvent_SceneFocusGained = 403, // data is process + VREvent_SceneApplicationChanged = 404, // data is process - The App actually drawing the scene changed (usually to or from the compositor) + VREvent_SceneFocusChanged = 405, // data is process - New app got access to draw the scene + VREvent_InputFocusChanged = 406, // data is process + VREvent_SceneApplicationSecondaryRenderingStarted = 407, // data is process - VREvent_HideRenderModels = 410, // Sent to the scene application to request hiding render models temporarily - VREvent_ShowRenderModels = 411, // Sent to the scene application to request restoring render model visibility + VREvent_HideRenderModels = 410, // Sent to the scene application to request hiding render models temporarily + VREvent_ShowRenderModels = 411, // Sent to the scene application to request restoring render model visibility - VREvent_OverlayShown = 500, - VREvent_OverlayHidden = 501, - VREvent_DashboardActivated = 502, - VREvent_DashboardDeactivated = 503, - VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay - VREvent_DashboardRequested = 505, // Sent to the overlay manager - data is overlay - VREvent_ResetDashboard = 506, // Send to the overlay manager - VREvent_RenderToast = 507, // Send to the dashboard to render a toast - data is the notification ID - VREvent_ImageLoaded = 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading - VREvent_ShowKeyboard = 509, // Sent to keyboard renderer in the dashboard to invoke it - VREvent_HideKeyboard = 510, // Sent to keyboard renderer in the dashboard to hide it - VREvent_OverlayGamepadFocusGained = 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it - VREvent_OverlayGamepadFocusLost = 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else + VREvent_OverlayShown = 500, + VREvent_OverlayHidden = 501, + VREvent_DashboardActivated = 502, + VREvent_DashboardDeactivated = 503, + VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay + VREvent_DashboardRequested = 505, // Sent to the overlay manager - data is overlay + VREvent_ResetDashboard = 506, // Send to the overlay manager + VREvent_RenderToast = 507, // Send to the dashboard to render a toast - data is the notification ID + VREvent_ImageLoaded = 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading + VREvent_ShowKeyboard = 509, // Sent to keyboard renderer in the dashboard to invoke it + VREvent_HideKeyboard = 510, // Sent to keyboard renderer in the dashboard to hide it + VREvent_OverlayGamepadFocusGained = 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it + VREvent_OverlayGamepadFocusLost = 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else VREvent_OverlaySharedTextureChanged = 513, - VREvent_DashboardGuideButtonDown = 514, - VREvent_DashboardGuideButtonUp = 515, - VREvent_ScreenshotTriggered = 516, // Screenshot button combo was pressed, Dashboard should request a screenshot - VREvent_ImageFailed = 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load - VREvent_DashboardOverlayCreated = 518, + VREvent_DashboardGuideButtonDown = 514, + VREvent_DashboardGuideButtonUp = 515, + VREvent_ScreenshotTriggered = 516, // Screenshot button combo was pressed, Dashboard should request a screenshot + VREvent_ImageFailed = 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load + VREvent_DashboardOverlayCreated = 518, // Screenshot API - VREvent_RequestScreenshot = 520, // Sent by vrclient application to compositor to take a screenshot - VREvent_ScreenshotTaken = 521, // Sent by compositor to the application that the screenshot has been taken - VREvent_ScreenshotFailed = 522, // Sent by compositor to the application that the screenshot failed to be taken - VREvent_SubmitScreenshotToDashboard = 523, // Sent by compositor to the dashboard that a completed screenshot was submitted - VREvent_ScreenshotProgressToDashboard = 524, // Sent by compositor to the dashboard that a completed screenshot was submitted + VREvent_RequestScreenshot = 520, // Sent by vrclient application to compositor to take a screenshot + VREvent_ScreenshotTaken = 521, // Sent by compositor to the application that the screenshot has been taken + VREvent_ScreenshotFailed = 522, // Sent by compositor to the application that the screenshot failed to be taken + VREvent_SubmitScreenshotToDashboard = 523, // Sent by compositor to the dashboard that a completed screenshot was submitted + VREvent_ScreenshotProgressToDashboard = 524, // Sent by compositor to the dashboard that a completed screenshot was submitted - VREvent_PrimaryDashboardDeviceChanged = 525, + VREvent_PrimaryDashboardDeviceChanged = 525, - VREvent_Notification_Shown = 600, - VREvent_Notification_Hidden = 601, - VREvent_Notification_BeginInteraction = 602, - VREvent_Notification_Destroyed = 603, + VREvent_Notification_Shown = 600, + VREvent_Notification_Hidden = 601, + VREvent_Notification_BeginInteraction = 602, + VREvent_Notification_Destroyed = 603, - VREvent_Quit = 700, // data is process - VREvent_ProcessQuit = 701, // data is process - VREvent_QuitAborted_UserPrompt = 702, // data is process - VREvent_QuitAcknowledged = 703, // data is process - VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down + VREvent_Quit = 700, // data is process + VREvent_ProcessQuit = 701, // data is process + VREvent_QuitAborted_UserPrompt = 702, // data is process + VREvent_QuitAcknowledged = 703, // data is process + VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down - VREvent_ChaperoneDataHasChanged = 800, - VREvent_ChaperoneUniverseHasChanged = 801, - VREvent_ChaperoneTempDataHasChanged = 802, - VREvent_ChaperoneSettingsHaveChanged = 803, - VREvent_SeatedZeroPoseReset = 804, + VREvent_ChaperoneDataHasChanged = 800, + VREvent_ChaperoneUniverseHasChanged = 801, + VREvent_ChaperoneTempDataHasChanged = 802, + VREvent_ChaperoneSettingsHaveChanged = 803, + VREvent_SeatedZeroPoseReset = 804, - VREvent_AudioSettingsHaveChanged = 820, + VREvent_AudioSettingsHaveChanged = 820, - VREvent_BackgroundSettingHasChanged = 850, - VREvent_CameraSettingsHaveChanged = 851, - VREvent_ReprojectionSettingHasChanged = 852, - VREvent_ModelSkinSettingsHaveChanged = 853, - VREvent_EnvironmentSettingsHaveChanged = 854, - VREvent_PowerSettingsHaveChanged = 855, + VREvent_BackgroundSettingHasChanged = 850, + VREvent_CameraSettingsHaveChanged = 851, + VREvent_ReprojectionSettingHasChanged = 852, + VREvent_ModelSkinSettingsHaveChanged = 853, + VREvent_EnvironmentSettingsHaveChanged = 854, + VREvent_PowerSettingsHaveChanged = 855, VREvent_EnableHomeAppSettingsHaveChanged = 856, - VREvent_StatusUpdate = 900, + VREvent_StatusUpdate = 900, - VREvent_MCImageUpdated = 1000, + VREvent_MCImageUpdated = 1000, - VREvent_FirmwareUpdateStarted = 1100, - VREvent_FirmwareUpdateFinished = 1101, + VREvent_FirmwareUpdateStarted = 1100, + VREvent_FirmwareUpdateFinished = 1101, - VREvent_KeyboardClosed = 1200, - VREvent_KeyboardCharInput = 1201, - VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard + VREvent_KeyboardClosed = 1200, + VREvent_KeyboardCharInput = 1201, + VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard - VREvent_ApplicationTransitionStarted = 1300, - VREvent_ApplicationTransitionAborted = 1301, - VREvent_ApplicationTransitionNewAppStarted = 1302, - VREvent_ApplicationListUpdated = 1303, - VREvent_ApplicationMimeTypeLoad = 1304, + VREvent_ApplicationTransitionStarted = 1300, + VREvent_ApplicationTransitionAborted = 1301, + VREvent_ApplicationTransitionNewAppStarted = 1302, + VREvent_ApplicationListUpdated = 1303, + VREvent_ApplicationMimeTypeLoad = 1304, VREvent_ApplicationTransitionNewAppLaunchComplete = 1305, - VREvent_ProcessConnected = 1306, - VREvent_ProcessDisconnected = 1307, + VREvent_ProcessConnected = 1306, + VREvent_ProcessDisconnected = 1307, - VREvent_Compositor_MirrorWindowShown = 1400, - VREvent_Compositor_MirrorWindowHidden = 1401, - VREvent_Compositor_ChaperoneBoundsShown = 1410, - VREvent_Compositor_ChaperoneBoundsHidden = 1411, + VREvent_Compositor_MirrorWindowShown = 1400, + VREvent_Compositor_MirrorWindowHidden = 1401, + VREvent_Compositor_ChaperoneBoundsShown = 1410, + VREvent_Compositor_ChaperoneBoundsHidden = 1411, - VREvent_TrackedCamera_StartVideoStream = 1500, - VREvent_TrackedCamera_StopVideoStream = 1501, - VREvent_TrackedCamera_PauseVideoStream = 1502, + VREvent_TrackedCamera_StartVideoStream = 1500, + VREvent_TrackedCamera_StopVideoStream = 1501, + VREvent_TrackedCamera_PauseVideoStream = 1502, VREvent_TrackedCamera_ResumeVideoStream = 1503, - VREvent_TrackedCamera_EditingSurface = 1550, + VREvent_TrackedCamera_EditingSurface = 1550, - VREvent_PerformanceTest_EnableCapture = 1600, - VREvent_PerformanceTest_DisableCapture = 1601, - VREvent_PerformanceTest_FidelityLevel = 1602, + VREvent_PerformanceTest_EnableCapture = 1600, + VREvent_PerformanceTest_DisableCapture = 1601, + VREvent_PerformanceTest_FidelityLevel = 1602, + + VREvent_MessageOverlay_Closed = 1650, + VREvent_MessageOverlayCloseRequested = 1651, - VREvent_MessageOverlay_Closed = 1650, - VREvent_MessageOverlayCloseRequested = 1651, - // Vendors are free to expose private events in this reserved region - VREvent_VendorSpecific_Reserved_Start = 10000, - VREvent_VendorSpecific_Reserved_End = 19999, + VREvent_VendorSpecific_Reserved_Start = 10000, + VREvent_VendorSpecific_Reserved_End = 19999, }; - /** Level of Hmd activity */ // UserInteraction_Timeout means the device is in the process of timing out. // InUse = ( k_EDeviceActivityLevel_UserInteraction || k_EDeviceActivityLevel_UserInteraction_Timeout ) // VREvent_TrackedDeviceUserInteractionStarted fires when the devices transitions from Standby -> UserInteraction or Idle -> UserInteraction. // VREvent_TrackedDeviceUserInteractionEnded fires when the devices transitions from UserInteraction_Timeout -> Idle enum EDeviceActivityLevel -{ - k_EDeviceActivityLevel_Unknown = -1, - k_EDeviceActivityLevel_Idle = 0, // No activity for the last 10 seconds - k_EDeviceActivityLevel_UserInteraction = 1, // Activity (movement or prox sensor) is happening now - k_EDeviceActivityLevel_UserInteraction_Timeout = 2, // No activity for the last 0.5 seconds - k_EDeviceActivityLevel_Standby = 3, // Idle for at least 5 seconds (configurable in Settings -> Power Management) +{ + k_EDeviceActivityLevel_Unknown = -1, + k_EDeviceActivityLevel_Idle = 0, // No activity for the last 10 seconds + k_EDeviceActivityLevel_UserInteraction = 1, // Activity (movement or prox sensor) is happening now + k_EDeviceActivityLevel_UserInteraction_Timeout = 2, // No activity for the last 0.5 seconds + k_EDeviceActivityLevel_Standby = 3, // Idle for at least 5 seconds (configurable in Settings -> Power Management) }; - /** VR controller button and axis IDs */ enum EVRButtonId { - k_EButton_System = 0, - k_EButton_ApplicationMenu = 1, - k_EButton_Grip = 2, - k_EButton_DPad_Left = 3, - k_EButton_DPad_Up = 4, - k_EButton_DPad_Right = 5, - k_EButton_DPad_Down = 6, - k_EButton_A = 7, - - k_EButton_ProximitySensor = 31, + k_EButton_System = 0, + k_EButton_ApplicationMenu = 1, + k_EButton_Grip = 2, + k_EButton_DPad_Left = 3, + k_EButton_DPad_Up = 4, + k_EButton_DPad_Right = 5, + k_EButton_DPad_Down = 6, + k_EButton_A = 7, - k_EButton_Axis0 = 32, - k_EButton_Axis1 = 33, - k_EButton_Axis2 = 34, - k_EButton_Axis3 = 35, - k_EButton_Axis4 = 36, + k_EButton_ProximitySensor = 31, + + k_EButton_Axis0 = 32, + k_EButton_Axis1 = 33, + k_EButton_Axis2 = 34, + k_EButton_Axis3 = 35, + k_EButton_Axis4 = 36, // aliases for well known controllers - k_EButton_SteamVR_Touchpad = k_EButton_Axis0, - k_EButton_SteamVR_Trigger = k_EButton_Axis1, + k_EButton_SteamVR_Touchpad = k_EButton_Axis0, + k_EButton_SteamVR_Trigger = k_EButton_Axis1, - k_EButton_Dashboard_Back = k_EButton_Grip, + k_EButton_Dashboard_Back = k_EButton_Grip, - k_EButton_Max = 64 + k_EButton_Max = 64 }; -inline uint64_t ButtonMaskFromId( EVRButtonId id ) { return 1ull << id; } +inline uint64_t ButtonMaskFromId(EVRButtonId id) { return 1ull << id; } /** used for controller button events */ struct VREvent_Controller_t { - uint32_t button; // EVRButtonId enum + uint32_t button; // EVRButtonId enum }; - /** used for simulated mouse events in overlay space */ enum EVRMouseButton { - VRMouseButton_Left = 0x0001, - VRMouseButton_Right = 0x0002, - VRMouseButton_Middle = 0x0004, + VRMouseButton_Left = 0x0001, + VRMouseButton_Right = 0x0002, + VRMouseButton_Middle = 0x0004, }; - /** used for simulated mouse events in overlay space */ struct VREvent_Mouse_t { - float x, y; // co-ords are in GL space, bottom left of the texture is 0,0 - uint32_t button; // EVRMouseButton enum + float x, y; // co-ords are in GL space, bottom left of the texture is 0,0 + uint32_t button; // EVRMouseButton enum }; /** used for simulated mouse wheel scroll in overlay space */ struct VREvent_Scroll_t { - float xdelta, ydelta; // movement in fraction of the pad traversed since last delta, 1.0 for a full swipe + float xdelta, ydelta; // movement in fraction of the pad traversed since last delta, 1.0 for a full swipe uint32_t repeatCount; }; @@ -713,25 +704,23 @@ struct VREvent_Process_t bool bForced; }; - /** Used for a few events about overlays */ struct VREvent_Overlay_t { uint64_t overlayHandle; }; - /** Used for a few events about overlays */ struct VREvent_Status_t { - uint32_t statusState; // EVRState enum + uint32_t statusState; // EVRState enum }; /** Used for keyboard events **/ struct VREvent_Keyboard_t { - char cNewInput[8]; // Up to 11 bytes of new input - uint64_t uUserValue; // Possible flags about the new input + char cNewInput[8]; // Up to 11 bytes of new input + uint64_t uUserValue; // Possible flags about the new input }; struct VREvent_Ipd_t @@ -787,7 +776,7 @@ struct VREvent_EditingCameraSurface_t struct VREvent_MessageOverlay_t { - uint32_t unVRMessageOverlayResponse; // vr::VRMessageOverlayResponse enum + uint32_t unVRMessageOverlayResponse; // vr::VRMessageOverlayResponse enum }; struct VREvent_Property_t @@ -797,8 +786,7 @@ struct VREvent_Property_t }; /** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py */ -typedef union -{ +typedef union { VREvent_Reserved_t reserved; VREvent_Controller_t controller; VREvent_Mouse_t mouse; @@ -821,25 +809,24 @@ typedef union VREvent_Property_t property; } VREvent_Data_t; - -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif /** An event posted by the server to all running applications */ struct VREvent_t { - uint32_t eventType; // EVREventType enum + uint32_t eventType; // EVREventType enum TrackedDeviceIndex_t trackedDeviceIndex; float eventAgeSeconds; // event data must be the end of the struct as its size is variable VREvent_Data_t data; }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif /** The mesh to draw into the stencil (or depth) buffer to perform @@ -854,7 +841,6 @@ struct HiddenAreaMesh_t uint32_t unTriangleCount; }; - enum EHiddenAreaMeshType { k_eHiddenAreaMesh_Standard = 0, @@ -864,7 +850,6 @@ enum EHiddenAreaMeshType k_eHiddenAreaMesh_Max = 3, }; - /** Identifies what kind of axis is on the controller at index n. Read this type * with pVRSystem->Get( nControllerDeviceIndex, Prop_Axis0Type_Int32 + n ); */ @@ -873,32 +858,29 @@ enum EVRControllerAxisType k_eControllerAxis_None = 0, k_eControllerAxis_TrackPad = 1, k_eControllerAxis_Joystick = 2, - k_eControllerAxis_Trigger = 3, // Analog trigger data is in the X axis + k_eControllerAxis_Trigger = 3, // Analog trigger data is in the X axis }; - /** contains information about one axis on the controller */ struct VRControllerAxis_t { - float x; // Ranges from -1.0 to 1.0 for joysticks and track pads. Ranges from 0.0 to 1.0 for triggers were 0 is fully released. - float y; // Ranges from -1.0 to 1.0 for joysticks and track pads. Is always 0.0 for triggers. + float x; // Ranges from -1.0 to 1.0 for joysticks and track pads. Ranges from 0.0 to 1.0 for triggers were 0 is fully released. + float y; // Ranges from -1.0 to 1.0 for joysticks and track pads. Is always 0.0 for triggers. }; - /** the number of axes in the controller state */ static const uint32_t k_unControllerStateAxisCount = 5; - -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif /** Holds all the state of a controller at one moment in time. */ struct VRControllerState001_t { - // If packet num matches that on your prior call, then the controller state hasn't been changed since + // If packet num matches that on your prior call, then the controller state hasn't been changed since // your last call and there is no need to process it uint32_t unPacketNum; @@ -907,16 +889,14 @@ struct VRControllerState001_t uint64_t ulButtonTouched; // Axis data for the controller's analog inputs - VRControllerAxis_t rAxis[ k_unControllerStateAxisCount ]; + VRControllerAxis_t rAxis[k_unControllerStateAxisCount]; }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif - typedef VRControllerState001_t VRControllerState_t; - /** determines how to provide output to the application of various event processing functions. */ enum EVRControllerEventOutputType { @@ -924,8 +904,6 @@ enum EVRControllerEventOutputType ControllerEventOutput_VREvents = 1, }; - - /** Collision Bounds Style */ enum ECollisionBoundsStyle { @@ -941,7 +919,7 @@ enum ECollisionBoundsStyle /** Allows the application to customize how the overlay appears in the compositor */ struct Compositor_OverlaySettings { - uint32_t size; // sizeof(Compositor_OverlaySettings) + uint32_t size; // sizeof(Compositor_OverlaySettings) bool curved, antialias; float scale, distance, alpha; float uOffset, vOffset, uScale, vScale; @@ -957,49 +935,48 @@ static const VROverlayHandle_t k_ulOverlayHandleInvalid = 0; /** Errors that can occur around VR overlays */ enum EVROverlayError { - VROverlayError_None = 0, + VROverlayError_None = 0, - VROverlayError_UnknownOverlay = 10, - VROverlayError_InvalidHandle = 11, - VROverlayError_PermissionDenied = 12, - VROverlayError_OverlayLimitExceeded = 13, // No more overlays could be created because the maximum number already exist - VROverlayError_WrongVisibilityType = 14, - VROverlayError_KeyTooLong = 15, - VROverlayError_NameTooLong = 16, - VROverlayError_KeyInUse = 17, - VROverlayError_WrongTransformType = 18, - VROverlayError_InvalidTrackedDevice = 19, - VROverlayError_InvalidParameter = 20, - VROverlayError_ThumbnailCantBeDestroyed = 21, - VROverlayError_ArrayTooSmall = 22, - VROverlayError_RequestFailed = 23, - VROverlayError_InvalidTexture = 24, - VROverlayError_UnableToLoadFile = 25, - VROverlayError_KeyboardAlreadyInUse = 26, - VROverlayError_NoNeighbor = 27, - VROverlayError_TooManyMaskPrimitives = 29, - VROverlayError_BadMaskPrimitive = 30, + VROverlayError_UnknownOverlay = 10, + VROverlayError_InvalidHandle = 11, + VROverlayError_PermissionDenied = 12, + VROverlayError_OverlayLimitExceeded = 13, // No more overlays could be created because the maximum number already exist + VROverlayError_WrongVisibilityType = 14, + VROverlayError_KeyTooLong = 15, + VROverlayError_NameTooLong = 16, + VROverlayError_KeyInUse = 17, + VROverlayError_WrongTransformType = 18, + VROverlayError_InvalidTrackedDevice = 19, + VROverlayError_InvalidParameter = 20, + VROverlayError_ThumbnailCantBeDestroyed = 21, + VROverlayError_ArrayTooSmall = 22, + VROverlayError_RequestFailed = 23, + VROverlayError_InvalidTexture = 24, + VROverlayError_UnableToLoadFile = 25, + VROverlayError_KeyboardAlreadyInUse = 26, + VROverlayError_NoNeighbor = 27, + VROverlayError_TooManyMaskPrimitives = 29, + VROverlayError_BadMaskPrimitive = 30, }; /** enum values to pass in to VR_Init to identify whether the application will * draw a 3D scene. */ enum EVRApplicationType { - VRApplication_Other = 0, // Some other kind of application that isn't covered by the other entries - VRApplication_Scene = 1, // Application will submit 3D frames - VRApplication_Overlay = 2, // Application only interacts with overlays - VRApplication_Background = 3, // Application should not start SteamVR if it's not already running, and should not - // keep it running if everything else quits. - VRApplication_Utility = 4, // Init should not try to load any drivers. The application needs access to utility - // interfaces (like IVRSettings and IVRApplications) but not hardware. - VRApplication_VRMonitor = 5, // Reserved for vrmonitor - VRApplication_SteamWatchdog = 6,// Reserved for Steam - VRApplication_Bootstrapper = 7, // Start up SteamVR + VRApplication_Other = 0, // Some other kind of application that isn't covered by the other entries + VRApplication_Scene = 1, // Application will submit 3D frames + VRApplication_Overlay = 2, // Application only interacts with overlays + VRApplication_Background = 3, // Application should not start SteamVR if it's not already running, and should not + // keep it running if everything else quits. + VRApplication_Utility = 4, // Init should not try to load any drivers. The application needs access to utility + // interfaces (like IVRSettings and IVRApplications) but not hardware. + VRApplication_VRMonitor = 5, // Reserved for vrmonitor + VRApplication_SteamWatchdog = 6, // Reserved for Steam + VRApplication_Bootstrapper = 7, // Start up SteamVR VRApplication_Max }; - /** error codes for firmware */ enum EVRFirmwareError { @@ -1008,7 +985,6 @@ enum EVRFirmwareError VRFirmwareError_Fail = 2, }; - /** error codes for notifications */ enum EVRNotificationError { @@ -1019,103 +995,101 @@ enum EVRNotificationError VRNotificationError_SystemWithUserValueAlreadyExists = 103, }; - /** error codes returned by Vr_Init */ // Please add adequate error description to https://developer.valvesoftware.com/w/index.php?title=Category:SteamVRHelp enum EVRInitError { - VRInitError_None = 0, + VRInitError_None = 0, VRInitError_Unknown = 1, - VRInitError_Init_InstallationNotFound = 100, - VRInitError_Init_InstallationCorrupt = 101, - VRInitError_Init_VRClientDLLNotFound = 102, - VRInitError_Init_FileNotFound = 103, - VRInitError_Init_FactoryNotFound = 104, - VRInitError_Init_InterfaceNotFound = 105, - VRInitError_Init_InvalidInterface = 106, - VRInitError_Init_UserConfigDirectoryInvalid = 107, - VRInitError_Init_HmdNotFound = 108, - VRInitError_Init_NotInitialized = 109, - VRInitError_Init_PathRegistryNotFound = 110, - VRInitError_Init_NoConfigPath = 111, - VRInitError_Init_NoLogPath = 112, - VRInitError_Init_PathRegistryNotWritable = 113, - VRInitError_Init_AppInfoInitFailed = 114, - VRInitError_Init_Retry = 115, // Used internally to cause retries to vrserver - VRInitError_Init_InitCanceledByUser = 116, // The calling application should silently exit. The user canceled app startup - VRInitError_Init_AnotherAppLaunching = 117, - VRInitError_Init_SettingsInitFailed = 118, - VRInitError_Init_ShuttingDown = 119, - VRInitError_Init_TooManyObjects = 120, - VRInitError_Init_NoServerForBackgroundApp = 121, - VRInitError_Init_NotSupportedWithCompositor = 122, - VRInitError_Init_NotAvailableToUtilityApps = 123, - VRInitError_Init_Internal = 124, - VRInitError_Init_HmdDriverIdIsNone = 125, - VRInitError_Init_HmdNotFoundPresenceFailed = 126, - VRInitError_Init_VRMonitorNotFound = 127, - VRInitError_Init_VRMonitorStartupFailed = 128, - VRInitError_Init_LowPowerWatchdogNotSupported = 129, - VRInitError_Init_InvalidApplicationType = 130, - VRInitError_Init_NotAvailableToWatchdogApps = 131, - VRInitError_Init_WatchdogDisabledInSettings = 132, - VRInitError_Init_VRDashboardNotFound = 133, - VRInitError_Init_VRDashboardStartupFailed = 134, - VRInitError_Init_VRHomeNotFound = 135, - VRInitError_Init_VRHomeStartupFailed = 136, - VRInitError_Init_RebootingBusy = 137, - VRInitError_Init_FirmwareUpdateBusy = 138, - VRInitError_Init_FirmwareRecoveryBusy = 139, + VRInitError_Init_InstallationNotFound = 100, + VRInitError_Init_InstallationCorrupt = 101, + VRInitError_Init_VRClientDLLNotFound = 102, + VRInitError_Init_FileNotFound = 103, + VRInitError_Init_FactoryNotFound = 104, + VRInitError_Init_InterfaceNotFound = 105, + VRInitError_Init_InvalidInterface = 106, + VRInitError_Init_UserConfigDirectoryInvalid = 107, + VRInitError_Init_HmdNotFound = 108, + VRInitError_Init_NotInitialized = 109, + VRInitError_Init_PathRegistryNotFound = 110, + VRInitError_Init_NoConfigPath = 111, + VRInitError_Init_NoLogPath = 112, + VRInitError_Init_PathRegistryNotWritable = 113, + VRInitError_Init_AppInfoInitFailed = 114, + VRInitError_Init_Retry = 115, // Used internally to cause retries to vrserver + VRInitError_Init_InitCanceledByUser = 116, // The calling application should silently exit. The user canceled app startup + VRInitError_Init_AnotherAppLaunching = 117, + VRInitError_Init_SettingsInitFailed = 118, + VRInitError_Init_ShuttingDown = 119, + VRInitError_Init_TooManyObjects = 120, + VRInitError_Init_NoServerForBackgroundApp = 121, + VRInitError_Init_NotSupportedWithCompositor = 122, + VRInitError_Init_NotAvailableToUtilityApps = 123, + VRInitError_Init_Internal = 124, + VRInitError_Init_HmdDriverIdIsNone = 125, + VRInitError_Init_HmdNotFoundPresenceFailed = 126, + VRInitError_Init_VRMonitorNotFound = 127, + VRInitError_Init_VRMonitorStartupFailed = 128, + VRInitError_Init_LowPowerWatchdogNotSupported = 129, + VRInitError_Init_InvalidApplicationType = 130, + VRInitError_Init_NotAvailableToWatchdogApps = 131, + VRInitError_Init_WatchdogDisabledInSettings = 132, + VRInitError_Init_VRDashboardNotFound = 133, + VRInitError_Init_VRDashboardStartupFailed = 134, + VRInitError_Init_VRHomeNotFound = 135, + VRInitError_Init_VRHomeStartupFailed = 136, + VRInitError_Init_RebootingBusy = 137, + VRInitError_Init_FirmwareUpdateBusy = 138, + VRInitError_Init_FirmwareRecoveryBusy = 139, - - VRInitError_Driver_Failed = 200, - VRInitError_Driver_Unknown = 201, - VRInitError_Driver_HmdUnknown = 202, - VRInitError_Driver_NotLoaded = 203, - VRInitError_Driver_RuntimeOutOfDate = 204, - VRInitError_Driver_HmdInUse = 205, - VRInitError_Driver_NotCalibrated = 206, - VRInitError_Driver_CalibrationInvalid = 207, - VRInitError_Driver_HmdDisplayNotFound = 208, + VRInitError_Driver_Failed = 200, + VRInitError_Driver_Unknown = 201, + VRInitError_Driver_HmdUnknown = 202, + VRInitError_Driver_NotLoaded = 203, + VRInitError_Driver_RuntimeOutOfDate = 204, + VRInitError_Driver_HmdInUse = 205, + VRInitError_Driver_NotCalibrated = 206, + VRInitError_Driver_CalibrationInvalid = 207, + VRInitError_Driver_HmdDisplayNotFound = 208, VRInitError_Driver_TrackedDeviceInterfaceUnknown = 209, // VRInitError_Driver_HmdDisplayNotFoundAfterFix = 210, // not needed: here for historic reasons - VRInitError_Driver_HmdDriverIdOutOfBounds = 211, - VRInitError_Driver_HmdDisplayMirrored = 212, + VRInitError_Driver_HmdDriverIdOutOfBounds = 211, + VRInitError_Driver_HmdDisplayMirrored = 212, - VRInitError_IPC_ServerInitFailed = 300, - VRInitError_IPC_ConnectFailed = 301, - VRInitError_IPC_SharedStateInitFailed = 302, - VRInitError_IPC_CompositorInitFailed = 303, - VRInitError_IPC_MutexInitFailed = 304, - VRInitError_IPC_Failed = 305, - VRInitError_IPC_CompositorConnectFailed = 306, + VRInitError_IPC_ServerInitFailed = 300, + VRInitError_IPC_ConnectFailed = 301, + VRInitError_IPC_SharedStateInitFailed = 302, + VRInitError_IPC_CompositorInitFailed = 303, + VRInitError_IPC_MutexInitFailed = 304, + VRInitError_IPC_Failed = 305, + VRInitError_IPC_CompositorConnectFailed = 306, VRInitError_IPC_CompositorInvalidConnectResponse = 307, VRInitError_IPC_ConnectFailedAfterMultipleAttempts = 308, - VRInitError_Compositor_Failed = 400, - VRInitError_Compositor_D3D11HardwareRequired = 401, - VRInitError_Compositor_FirmwareRequiresUpdate = 402, - VRInitError_Compositor_OverlayInitFailed = 403, - VRInitError_Compositor_ScreenshotsInitFailed = 404, - VRInitError_Compositor_UnableToCreateDevice = 405, + VRInitError_Compositor_Failed = 400, + VRInitError_Compositor_D3D11HardwareRequired = 401, + VRInitError_Compositor_FirmwareRequiresUpdate = 402, + VRInitError_Compositor_OverlayInitFailed = 403, + VRInitError_Compositor_ScreenshotsInitFailed = 404, + VRInitError_Compositor_UnableToCreateDevice = 405, - VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000, + VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000, - VRInitError_VendorSpecific_HmdFound_CantOpenDevice = 1101, - VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102, - VRInitError_VendorSpecific_HmdFound_NoStoredConfig = 1103, - VRInitError_VendorSpecific_HmdFound_ConfigTooBig = 1104, - VRInitError_VendorSpecific_HmdFound_ConfigTooSmall = 1105, - VRInitError_VendorSpecific_HmdFound_UnableToInitZLib = 1106, - VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion = 1107, - VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart = 1108, - VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart = 1109, - VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext = 1110, - VRInitError_VendorSpecific_HmdFound_UserDataAddressRange = 1111, - VRInitError_VendorSpecific_HmdFound_UserDataError = 1112, - VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck = 1113, + VRInitError_VendorSpecific_HmdFound_CantOpenDevice = 1101, + VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102, + VRInitError_VendorSpecific_HmdFound_NoStoredConfig = 1103, + VRInitError_VendorSpecific_HmdFound_ConfigTooBig = 1104, + VRInitError_VendorSpecific_HmdFound_ConfigTooSmall = 1105, + VRInitError_VendorSpecific_HmdFound_UnableToInitZLib = 1106, + VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion = 1107, + VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart = 1108, + VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart = 1109, + VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext = 1110, + VRInitError_VendorSpecific_HmdFound_UserDataAddressRange = 1111, + VRInitError_VendorSpecific_HmdFound_UserDataError = 1112, + VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck = 1113, VRInitError_Steam_SteamInstallationNotFound = 2000, }; @@ -1123,7 +1097,7 @@ enum EVRInitError enum EVRScreenshotType { VRScreenshotType_None = 0, - VRScreenshotType_Mono = 1, // left eye only + VRScreenshotType_Mono = 1, // left eye only VRScreenshotType_Stereo = 2, VRScreenshotType_Cubemap = 3, VRScreenshotType_MonoPanorama = 4, @@ -1138,35 +1112,35 @@ enum EVRScreenshotPropertyFilenames enum EVRTrackedCameraError { - VRTrackedCameraError_None = 0, - VRTrackedCameraError_OperationFailed = 100, - VRTrackedCameraError_InvalidHandle = 101, - VRTrackedCameraError_InvalidFrameHeaderVersion = 102, - VRTrackedCameraError_OutOfHandles = 103, - VRTrackedCameraError_IPCFailure = 104, - VRTrackedCameraError_NotSupportedForThisDevice = 105, - VRTrackedCameraError_SharedMemoryFailure = 106, - VRTrackedCameraError_FrameBufferingFailure = 107, - VRTrackedCameraError_StreamSetupFailure = 108, - VRTrackedCameraError_InvalidGLTextureId = 109, + VRTrackedCameraError_None = 0, + VRTrackedCameraError_OperationFailed = 100, + VRTrackedCameraError_InvalidHandle = 101, + VRTrackedCameraError_InvalidFrameHeaderVersion = 102, + VRTrackedCameraError_OutOfHandles = 103, + VRTrackedCameraError_IPCFailure = 104, + VRTrackedCameraError_NotSupportedForThisDevice = 105, + VRTrackedCameraError_SharedMemoryFailure = 106, + VRTrackedCameraError_FrameBufferingFailure = 107, + VRTrackedCameraError_StreamSetupFailure = 108, + VRTrackedCameraError_InvalidGLTextureId = 109, VRTrackedCameraError_InvalidSharedTextureHandle = 110, - VRTrackedCameraError_FailedToGetGLTextureId = 111, - VRTrackedCameraError_SharedTextureFailure = 112, - VRTrackedCameraError_NoFrameAvailable = 113, - VRTrackedCameraError_InvalidArgument = 114, - VRTrackedCameraError_InvalidFrameBufferSize = 115, + VRTrackedCameraError_FailedToGetGLTextureId = 111, + VRTrackedCameraError_SharedTextureFailure = 112, + VRTrackedCameraError_NoFrameAvailable = 113, + VRTrackedCameraError_InvalidArgument = 114, + VRTrackedCameraError_InvalidFrameBufferSize = 115, }; enum EVRTrackedCameraFrameType { - VRTrackedCameraFrameType_Distorted = 0, // This is the camera video frame size in pixels, still distorted. - VRTrackedCameraFrameType_Undistorted, // In pixels, an undistorted inscribed rectangle region without invalid regions. This size is subject to changes shortly. - VRTrackedCameraFrameType_MaximumUndistorted, // In pixels, maximum undistorted with invalid regions. Non zero alpha component identifies valid regions. + VRTrackedCameraFrameType_Distorted = 0, // This is the camera video frame size in pixels, still distorted. + VRTrackedCameraFrameType_Undistorted, // In pixels, an undistorted inscribed rectangle region without invalid regions. This size is subject to changes shortly. + VRTrackedCameraFrameType_MaximumUndistorted, // In pixels, maximum undistorted with invalid regions. Non zero alpha component identifies valid regions. MAX_CAMERA_FRAME_TYPES }; typedef uint64_t TrackedCameraHandle_t; -#define INVALID_TRACKED_CAMERA_HANDLE ((vr::TrackedCameraHandle_t)0) +#define INVALID_TRACKED_CAMERA_HANDLE ((vr::TrackedCameraHandle_t)0) struct CameraVideoStreamFrameHeader_t { @@ -1186,15 +1160,15 @@ typedef uint32_t ScreenshotHandle_t; static const uint32_t k_unScreenshotHandleInvalid = 0; -#pragma pack( pop ) +#pragma pack(pop) // figure out how to import from the VR API dll #if defined(_WIN32) #ifdef VR_API_EXPORT -#define VR_INTERFACE extern "C" __declspec( dllexport ) +#define VR_INTERFACE extern "C" __declspec(dllexport) #else -#define VR_INTERFACE extern "C" __declspec( dllimport ) +#define VR_INTERFACE extern "C" __declspec(dllimport) #endif #elif defined(__GNUC__) || defined(COMPILER_GCC) || defined(__APPLE__) @@ -1202,83 +1176,78 @@ static const uint32_t k_unScreenshotHandleInvalid = 0; #ifdef VR_API_EXPORT #define VR_INTERFACE extern "C" __attribute__((visibility("default"))) #else -#define VR_INTERFACE extern "C" +#define VR_INTERFACE extern "C" #endif #else #error "Unsupported Platform." #endif - -#if defined( _WIN32 ) +#if defined(_WIN32) #define VR_CALLTYPE __cdecl #else -#define VR_CALLTYPE +#define VR_CALLTYPE #endif -} // namespace vr - -#endif // _INCLUDE_VRTYPES_H +} // namespace vr +#endif // _INCLUDE_VRTYPES_H // vrannotation.h #ifdef API_GEN -# define VR_CLANG_ATTR(ATTR) __attribute__((annotate( ATTR ))) +#define VR_CLANG_ATTR(ATTR) __attribute__((annotate(ATTR))) #else -# define VR_CLANG_ATTR(ATTR) +#define VR_CLANG_ATTR(ATTR) #endif -#define VR_METHOD_DESC(DESC) VR_CLANG_ATTR( "desc:" #DESC ";" ) -#define VR_IGNOREATTR() VR_CLANG_ATTR( "ignore" ) -#define VR_OUT_STRUCT() VR_CLANG_ATTR( "out_struct: ;" ) -#define VR_OUT_STRING() VR_CLANG_ATTR( "out_string: ;" ) -#define VR_OUT_ARRAY_CALL(COUNTER,FUNCTION,PARAMS) VR_CLANG_ATTR( "out_array_call:" #COUNTER "," #FUNCTION "," #PARAMS ";" ) -#define VR_OUT_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR( "out_array_count:" #COUNTER ";" ) -#define VR_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR( "array_count:" #COUNTER ";" ) -#define VR_ARRAY_COUNT_D(COUNTER, DESC) VR_CLANG_ATTR( "array_count:" #COUNTER ";desc:" #DESC ) -#define VR_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR( "buffer_count:" #COUNTER ";" ) -#define VR_OUT_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR( "out_buffer_count:" #COUNTER ";" ) -#define VR_OUT_STRING_COUNT(COUNTER) VR_CLANG_ATTR( "out_string_count:" #COUNTER ";" ) +#define VR_METHOD_DESC(DESC) VR_CLANG_ATTR("desc:" #DESC ";") +#define VR_IGNOREATTR() VR_CLANG_ATTR("ignore") +#define VR_OUT_STRUCT() VR_CLANG_ATTR("out_struct: ;") +#define VR_OUT_STRING() VR_CLANG_ATTR("out_string: ;") +#define VR_OUT_ARRAY_CALL(COUNTER, FUNCTION, PARAMS) VR_CLANG_ATTR("out_array_call:" #COUNTER "," #FUNCTION "," #PARAMS ";") +#define VR_OUT_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR("out_array_count:" #COUNTER ";") +#define VR_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR("array_count:" #COUNTER ";") +#define VR_ARRAY_COUNT_D(COUNTER, DESC) VR_CLANG_ATTR("array_count:" #COUNTER ";desc:" #DESC) +#define VR_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR("buffer_count:" #COUNTER ";") +#define VR_OUT_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR("out_buffer_count:" #COUNTER ";") +#define VR_OUT_STRING_COUNT(COUNTER) VR_CLANG_ATTR("out_string_count:" #COUNTER ";") // ivrsystem.h namespace vr { - class IVRSystem { public: - - // ------------------------------------ // Display Methods // ------------------------------------ /** Suggested size for the intermediate render target that the distortion pulls from. */ - virtual void GetRecommendedRenderTargetSize( uint32_t *pnWidth, uint32_t *pnHeight ) = 0; + virtual void GetRecommendedRenderTargetSize(uint32_t *pnWidth, uint32_t *pnHeight) = 0; /** The projection matrix for the specified eye */ - virtual HmdMatrix44_t GetProjectionMatrix( EVREye eEye, float fNearZ, float fFarZ ) = 0; + virtual HmdMatrix44_t GetProjectionMatrix(EVREye eEye, float fNearZ, float fFarZ) = 0; /** The components necessary to build your own projection matrix in case your * application is doing something fancy like infinite Z */ - virtual void GetProjectionRaw( EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom ) = 0; + virtual void GetProjectionRaw(EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom) = 0; /** Gets the result of the distortion function for the specified eye and input UVs. UVs go from 0,0 in * the upper left of that eye's viewport and 1,1 in the lower right of that eye's viewport. * Returns true for success. Otherwise, returns false, and distortion coordinates are not suitable. */ - virtual bool ComputeDistortion( EVREye eEye, float fU, float fV, DistortionCoordinates_t *pDistortionCoordinates ) = 0; + virtual bool ComputeDistortion(EVREye eEye, float fU, float fV, DistortionCoordinates_t *pDistortionCoordinates) = 0; /** Returns the transform from eye space to the head space. Eye space is the per-eye flavor of head * space that provides stereo disparity. Instead of Model * View * Projection the sequence is Model * View * Eye^-1 * Projection. * Normally View and Eye^-1 will be multiplied together and treated as View in your application. */ - virtual HmdMatrix34_t GetEyeToHeadTransform( EVREye eEye ) = 0; + virtual HmdMatrix34_t GetEyeToHeadTransform(EVREye eEye) = 0; /** Returns the number of elapsed seconds since the last recorded vsync event. This * will come from a vsync timer event in the timer if possible or from the application-reported * time if that is not available. If no vsync times are available the function will * return zero for vsync time and frame counter and return false from the method. */ - virtual bool GetTimeSinceLastVsync( float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter ) = 0; + virtual bool GetTimeSinceLastVsync(float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter) = 0; /** [D3D9 Only] * Returns the adapter index that the user should pass into CreateDevice to set up D3D9 in such @@ -1290,8 +1259,8 @@ public: * Returns the adapter index that the user should pass into EnumAdapters to create the device * and swap chain in DX10 and DX11. If an error occurs the index will be set to -1. */ - virtual void GetDXGIOutputInfo( int32_t *pnAdapterIndex ) = 0; - + virtual void GetDXGIOutputInfo(int32_t *pnAdapterIndex) = 0; + /** * Returns platform- and texture-type specific adapter identification so that applications and the * compositor are creating textures and swap chains on the same GPU. If an error occurs the device @@ -1309,7 +1278,7 @@ public: * [macOS Only] * Returns an id that should be used by the application. */ - virtual void GetOutputDevice( uint64_t *pnDevice, ETextureType textureType, VkInstance_T *pInstance = nullptr ) = 0; + virtual void GetOutputDevice(uint64_t *pnDevice, ETextureType textureType, VkInstance_T *pInstance = nullptr) = 0; // ------------------------------------ // Display Mode methods @@ -1319,7 +1288,7 @@ public: virtual bool IsDisplayOnDesktop() = 0; /** Set the display visibility (true = extended, false = direct mode). Return value of true indicates that the change was successful. */ - virtual bool SetDisplayVisibility( bool bIsVisibleOnDesktop ) = 0; + virtual bool SetDisplayVisibility(bool bIsVisibleOnDesktop) = 0; // ------------------------------------ // Tracking Methods @@ -1342,7 +1311,7 @@ public: * probably not be used unless the application is the Chaperone calibration tool itself, but will provide * poses relative to the hardware-specific coordinate system in the driver. */ - virtual void GetDeviceToAbsoluteTrackingPose( ETrackingUniverseOrigin eOrigin, float fPredictedSecondsToPhotonsFromNow, VR_ARRAY_COUNT(unTrackedDevicePoseArrayCount) TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount ) = 0; + virtual void GetDeviceToAbsoluteTrackingPose(ETrackingUniverseOrigin eOrigin, float fPredictedSecondsToPhotonsFromNow, VR_ARRAY_COUNT(unTrackedDevicePoseArrayCount) TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount) = 0; /** Sets the zero pose for the seated tracker coordinate system to the current position and yaw of the HMD. After * ResetSeatedZeroPose all GetDeviceToAbsoluteTrackingPose calls that pass TrackingUniverseSeated as the origin @@ -1370,21 +1339,21 @@ public: /** Get a sorted array of device indices of a given class of tracked devices (e.g. controllers). Devices are sorted right to left * relative to the specified tracked device (default: hmd -- pass in -1 for absolute tracking space). Returns the number of devices * in the list, or the size of the array needed if not large enough. */ - virtual uint32_t GetSortedTrackedDeviceIndicesOfClass( ETrackedDeviceClass eTrackedDeviceClass, VR_ARRAY_COUNT(unTrackedDeviceIndexArrayCount) vr::TrackedDeviceIndex_t *punTrackedDeviceIndexArray, uint32_t unTrackedDeviceIndexArrayCount, vr::TrackedDeviceIndex_t unRelativeToTrackedDeviceIndex = k_unTrackedDeviceIndex_Hmd ) = 0; + virtual uint32_t GetSortedTrackedDeviceIndicesOfClass(ETrackedDeviceClass eTrackedDeviceClass, VR_ARRAY_COUNT(unTrackedDeviceIndexArrayCount) vr::TrackedDeviceIndex_t *punTrackedDeviceIndexArray, uint32_t unTrackedDeviceIndexArrayCount, vr::TrackedDeviceIndex_t unRelativeToTrackedDeviceIndex = k_unTrackedDeviceIndex_Hmd) = 0; /** Returns the level of activity on the device. */ - virtual EDeviceActivityLevel GetTrackedDeviceActivityLevel( vr::TrackedDeviceIndex_t unDeviceId ) = 0; + virtual EDeviceActivityLevel GetTrackedDeviceActivityLevel(vr::TrackedDeviceIndex_t unDeviceId) = 0; /** Convenience utility to apply the specified transform to the specified pose. * This properly transforms all pose components, including velocity and angular velocity */ - virtual void ApplyTransform( TrackedDevicePose_t *pOutputPose, const TrackedDevicePose_t *pTrackedDevicePose, const HmdMatrix34_t *pTransform ) = 0; + virtual void ApplyTransform(TrackedDevicePose_t *pOutputPose, const TrackedDevicePose_t *pTrackedDevicePose, const HmdMatrix34_t *pTransform) = 0; /** Returns the device index associated with a specific role, for example the left hand or the right hand. */ - virtual vr::TrackedDeviceIndex_t GetTrackedDeviceIndexForControllerRole( vr::ETrackedControllerRole unDeviceType ) = 0; + virtual vr::TrackedDeviceIndex_t GetTrackedDeviceIndexForControllerRole(vr::ETrackedControllerRole unDeviceType) = 0; /** Returns the controller type associated with a device index. */ - virtual vr::ETrackedControllerRole GetControllerRoleForTrackedDeviceIndex( vr::TrackedDeviceIndex_t unDeviceIndex ) = 0; + virtual vr::ETrackedControllerRole GetControllerRoleForTrackedDeviceIndex(vr::TrackedDeviceIndex_t unDeviceIndex) = 0; // ------------------------------------ // Property methods @@ -1397,34 +1366,34 @@ public: * To determine which devices exist on the system, just loop from 0 to k_unMaxTrackedDeviceCount and check * the device class. Every device with something other than TrackedDevice_Invalid is associated with an * actual tracked device. */ - virtual ETrackedDeviceClass GetTrackedDeviceClass( vr::TrackedDeviceIndex_t unDeviceIndex ) = 0; + virtual ETrackedDeviceClass GetTrackedDeviceClass(vr::TrackedDeviceIndex_t unDeviceIndex) = 0; /** Returns true if there is a device connected in this slot. */ - virtual bool IsTrackedDeviceConnected( vr::TrackedDeviceIndex_t unDeviceIndex ) = 0; + virtual bool IsTrackedDeviceConnected(vr::TrackedDeviceIndex_t unDeviceIndex) = 0; /** Returns a bool property. If the device index is not valid or the property is not a bool type this function will return false. */ - virtual bool GetBoolTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + virtual bool GetBoolTrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L) = 0; /** Returns a float property. If the device index is not valid or the property is not a float type this function will return 0. */ - virtual float GetFloatTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + virtual float GetFloatTrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L) = 0; /** Returns an int property. If the device index is not valid or the property is not a int type this function will return 0. */ - virtual int32_t GetInt32TrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + virtual int32_t GetInt32TrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L) = 0; /** Returns a uint64 property. If the device index is not valid or the property is not a uint64 type this function will return 0. */ - virtual uint64_t GetUint64TrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + virtual uint64_t GetUint64TrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L) = 0; /** Returns a matrix property. If the device index is not valid or the property is not a matrix type, this function will return identity. */ - virtual HmdMatrix34_t GetMatrix34TrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + virtual HmdMatrix34_t GetMatrix34TrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L) = 0; /** Returns a string property. If the device index is not valid or the property is not a string type this function will * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */ - virtual uint32_t GetStringTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L ) = 0; + virtual uint32_t GetStringTrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L) = 0; /** returns a string that corresponds with the specified property error. The string will be the name * of the error enum value for all valid error codes */ - virtual const char *GetPropErrorNameFromEnum( ETrackedPropertyError error ) = 0; + virtual const char *GetPropErrorNameFromEnum(ETrackedPropertyError error) = 0; // ------------------------------------ // Event methods @@ -1432,16 +1401,16 @@ public: /** Returns true and fills the event with the next event on the queue if there is one. If there are no events * this method returns false. uncbVREvent should be the size in bytes of the VREvent_t struct */ - virtual bool PollNextEvent( VREvent_t *pEvent, uint32_t uncbVREvent ) = 0; + virtual bool PollNextEvent(VREvent_t *pEvent, uint32_t uncbVREvent) = 0; /** Returns true and fills the event with the next event on the queue if there is one. If there are no events * this method returns false. Fills in the pose of the associated tracked device in the provided pose struct. * This pose will always be older than the call to this function and should not be used to render the device. uncbVREvent should be the size in bytes of the VREvent_t struct */ - virtual bool PollNextEventWithPose( ETrackingUniverseOrigin eOrigin, VREvent_t *pEvent, uint32_t uncbVREvent, vr::TrackedDevicePose_t *pTrackedDevicePose ) = 0; + virtual bool PollNextEventWithPose(ETrackingUniverseOrigin eOrigin, VREvent_t *pEvent, uint32_t uncbVREvent, vr::TrackedDevicePose_t *pTrackedDevicePose) = 0; /** returns the name of an EVREvent enum value */ - virtual const char *GetEventTypeNameFromEnum( EVREventType eType ) = 0; + virtual const char *GetEventTypeNameFromEnum(EVREventType eType) = 0; // ------------------------------------ // Rendering helper methods @@ -1455,7 +1424,7 @@ public: * Setting the bInverse argument to true will produce the visible area mesh that is commonly used in place of full-screen quads. The visible area mesh covers all of the pixels the hidden area mesh does not cover. * Setting the bLineLoop argument will return a line loop of vertices in HiddenAreaMesh_t->pVertexData with HiddenAreaMesh_t->unTriangleCount set to the number of vertices. */ - virtual HiddenAreaMesh_t GetHiddenAreaMesh( EVREye eEye, EHiddenAreaMeshType type = k_eHiddenAreaMesh_Standard ) = 0; + virtual HiddenAreaMesh_t GetHiddenAreaMesh(EVREye eEye, EHiddenAreaMeshType type = k_eHiddenAreaMesh_Standard) = 0; // ------------------------------------ // Controller methods @@ -1463,22 +1432,22 @@ public: /** Fills the supplied struct with the current state of the controller. Returns false if the controller index * is invalid. */ - virtual bool GetControllerState( vr::TrackedDeviceIndex_t unControllerDeviceIndex, vr::VRControllerState_t *pControllerState, uint32_t unControllerStateSize ) = 0; + virtual bool GetControllerState(vr::TrackedDeviceIndex_t unControllerDeviceIndex, vr::VRControllerState_t *pControllerState, uint32_t unControllerStateSize) = 0; /** fills the supplied struct with the current state of the controller and the provided pose with the pose of * the controller when the controller state was updated most recently. Use this form if you need a precise controller * pose as input to your application when the user presses or releases a button. */ - virtual bool GetControllerStateWithPose( ETrackingUniverseOrigin eOrigin, vr::TrackedDeviceIndex_t unControllerDeviceIndex, vr::VRControllerState_t *pControllerState, uint32_t unControllerStateSize, TrackedDevicePose_t *pTrackedDevicePose ) = 0; + virtual bool GetControllerStateWithPose(ETrackingUniverseOrigin eOrigin, vr::TrackedDeviceIndex_t unControllerDeviceIndex, vr::VRControllerState_t *pControllerState, uint32_t unControllerStateSize, TrackedDevicePose_t *pTrackedDevicePose) = 0; /** Trigger a single haptic pulse on a controller. After this call the application may not trigger another haptic pulse on this controller * and axis combination for 5ms. */ - virtual void TriggerHapticPulse( vr::TrackedDeviceIndex_t unControllerDeviceIndex, uint32_t unAxisId, unsigned short usDurationMicroSec ) = 0; + virtual void TriggerHapticPulse(vr::TrackedDeviceIndex_t unControllerDeviceIndex, uint32_t unAxisId, unsigned short usDurationMicroSec) = 0; /** returns the name of an EVRButtonId enum value */ - virtual const char *GetButtonIdNameFromEnum( EVRButtonId eButtonId ) = 0; + virtual const char *GetButtonIdNameFromEnum(EVRButtonId eButtonId) = 0; /** returns the name of an EVRControllerAxisType enum value */ - virtual const char *GetControllerAxisTypeNameFromEnum( EVRControllerAxisType eAxisType ) = 0; + virtual const char *GetControllerAxisTypeNameFromEnum(EVRControllerAxisType eAxisType) = 0; /** Tells OpenVR that this process wants exclusive access to controller button states and button events. Other apps will be notified that * they have lost input focus with a VREvent_InputFocusCaptured event. Returns false if input focus could not be captured for @@ -1499,18 +1468,18 @@ public: /** Sends a request to the driver for the specified device and returns the response. The maximum response size is 32k, * but this method can be called with a smaller buffer. If the response exceeds the size of the buffer, it is truncated. * The size of the response including its terminating null is returned. */ - virtual uint32_t DriverDebugRequest( vr::TrackedDeviceIndex_t unDeviceIndex, const char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize ) = 0; + virtual uint32_t DriverDebugRequest(vr::TrackedDeviceIndex_t unDeviceIndex, const char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize) = 0; // ------------------------------------ // Firmware methods // ------------------------------------ - + /** Performs the actual firmware update if applicable. * The following events will be sent, if VRFirmwareError_None was returned: VREvent_FirmwareUpdateStarted, VREvent_FirmwareUpdateFinished * Use the properties Prop_Firmware_UpdateAvailable_Bool, Prop_Firmware_ManualUpdate_Bool, and Prop_Firmware_ManualUpdateURL_String * to figure our whether a firmware update is available, and to figure out whether its a manual update * Prop_Firmware_ManualUpdateURL_String should point to an URL describing the manual update process */ - virtual vr::EVRFirmwareError PerformFirmwareUpdate( vr::TrackedDeviceIndex_t unDeviceIndex ) = 0; + virtual vr::EVRFirmwareError PerformFirmwareUpdate(vr::TrackedDeviceIndex_t unDeviceIndex) = 0; // ------------------------------------ // Application life cycle methods @@ -1524,195 +1493,191 @@ public: * halts the timeout and dismisses the dashboard (if it was up). Applications should be sure to actually * prompt the user to save and then exit afterward, otherwise the user will be left in a confusing state. */ virtual void AcknowledgeQuit_UserPrompt() = 0; - }; -static const char * const IVRSystem_Version = "IVRSystem_017"; - -} +static const char *const IVRSystem_Version = "IVRSystem_017"; +} // namespace vr // ivrapplications.h namespace vr { +/** Used for all errors reported by the IVRApplications interface */ +enum EVRApplicationError +{ + VRApplicationError_None = 0, - /** Used for all errors reported by the IVRApplications interface */ - enum EVRApplicationError - { - VRApplicationError_None = 0, + VRApplicationError_AppKeyAlreadyExists = 100, // Only one application can use any given key + VRApplicationError_NoManifest = 101, // the running application does not have a manifest + VRApplicationError_NoApplication = 102, // No application is running + VRApplicationError_InvalidIndex = 103, + VRApplicationError_UnknownApplication = 104, // the application could not be found + VRApplicationError_IPCFailed = 105, // An IPC failure caused the request to fail + VRApplicationError_ApplicationAlreadyRunning = 106, + VRApplicationError_InvalidManifest = 107, + VRApplicationError_InvalidApplication = 108, + VRApplicationError_LaunchFailed = 109, // the process didn't start + VRApplicationError_ApplicationAlreadyStarting = 110, // the system was already starting the same application + VRApplicationError_LaunchInProgress = 111, // The system was already starting a different application + VRApplicationError_OldApplicationQuitting = 112, + VRApplicationError_TransitionAborted = 113, + VRApplicationError_IsTemplate = 114, // error when you try to call LaunchApplication() on a template type app (use LaunchTemplateApplication) + VRApplicationError_SteamVRIsExiting = 115, - VRApplicationError_AppKeyAlreadyExists = 100, // Only one application can use any given key - VRApplicationError_NoManifest = 101, // the running application does not have a manifest - VRApplicationError_NoApplication = 102, // No application is running - VRApplicationError_InvalidIndex = 103, - VRApplicationError_UnknownApplication = 104, // the application could not be found - VRApplicationError_IPCFailed = 105, // An IPC failure caused the request to fail - VRApplicationError_ApplicationAlreadyRunning = 106, - VRApplicationError_InvalidManifest = 107, - VRApplicationError_InvalidApplication = 108, - VRApplicationError_LaunchFailed = 109, // the process didn't start - VRApplicationError_ApplicationAlreadyStarting = 110, // the system was already starting the same application - VRApplicationError_LaunchInProgress = 111, // The system was already starting a different application - VRApplicationError_OldApplicationQuitting = 112, - VRApplicationError_TransitionAborted = 113, - VRApplicationError_IsTemplate = 114, // error when you try to call LaunchApplication() on a template type app (use LaunchTemplateApplication) - VRApplicationError_SteamVRIsExiting = 115, + VRApplicationError_BufferTooSmall = 200, // The provided buffer was too small to fit the requested data + VRApplicationError_PropertyNotSet = 201, // The requested property was not set + VRApplicationError_UnknownProperty = 202, + VRApplicationError_InvalidParameter = 203, +}; - VRApplicationError_BufferTooSmall = 200, // The provided buffer was too small to fit the requested data - VRApplicationError_PropertyNotSet = 201, // The requested property was not set - VRApplicationError_UnknownProperty = 202, - VRApplicationError_InvalidParameter = 203, - }; +/** The maximum length of an application key */ +static const uint32_t k_unMaxApplicationKeyLength = 128; - /** The maximum length of an application key */ - static const uint32_t k_unMaxApplicationKeyLength = 128; +/** these are the properties available on applications. */ +enum EVRApplicationProperty +{ + VRApplicationProperty_Name_String = 0, - /** these are the properties available on applications. */ - enum EVRApplicationProperty - { - VRApplicationProperty_Name_String = 0, + VRApplicationProperty_LaunchType_String = 11, + VRApplicationProperty_WorkingDirectory_String = 12, + VRApplicationProperty_BinaryPath_String = 13, + VRApplicationProperty_Arguments_String = 14, + VRApplicationProperty_URL_String = 15, - VRApplicationProperty_LaunchType_String = 11, - VRApplicationProperty_WorkingDirectory_String = 12, - VRApplicationProperty_BinaryPath_String = 13, - VRApplicationProperty_Arguments_String = 14, - VRApplicationProperty_URL_String = 15, + VRApplicationProperty_Description_String = 50, + VRApplicationProperty_NewsURL_String = 51, + VRApplicationProperty_ImagePath_String = 52, + VRApplicationProperty_Source_String = 53, - VRApplicationProperty_Description_String = 50, - VRApplicationProperty_NewsURL_String = 51, - VRApplicationProperty_ImagePath_String = 52, - VRApplicationProperty_Source_String = 53, + VRApplicationProperty_IsDashboardOverlay_Bool = 60, + VRApplicationProperty_IsTemplate_Bool = 61, + VRApplicationProperty_IsInstanced_Bool = 62, + VRApplicationProperty_IsInternal_Bool = 63, + VRApplicationProperty_WantsCompositorPauseInStandby_Bool = 64, - VRApplicationProperty_IsDashboardOverlay_Bool = 60, - VRApplicationProperty_IsTemplate_Bool = 61, - VRApplicationProperty_IsInstanced_Bool = 62, - VRApplicationProperty_IsInternal_Bool = 63, - VRApplicationProperty_WantsCompositorPauseInStandby_Bool = 64, + VRApplicationProperty_LastLaunchTime_Uint64 = 70, +}; - VRApplicationProperty_LastLaunchTime_Uint64 = 70, - }; +/** These are states the scene application startup process will go through. */ +enum EVRApplicationTransitionState +{ + VRApplicationTransition_None = 0, - /** These are states the scene application startup process will go through. */ - enum EVRApplicationTransitionState - { - VRApplicationTransition_None = 0, + VRApplicationTransition_OldAppQuitSent = 10, + VRApplicationTransition_WaitingForExternalLaunch = 11, - VRApplicationTransition_OldAppQuitSent = 10, - VRApplicationTransition_WaitingForExternalLaunch = 11, - - VRApplicationTransition_NewAppLaunched = 20, - }; + VRApplicationTransition_NewAppLaunched = 20, +}; - struct AppOverrideKeys_t - { - const char *pchKey; - const char *pchValue; - }; +struct AppOverrideKeys_t +{ + const char *pchKey; + const char *pchValue; +}; - /** Currently recognized mime types */ - static const char * const k_pch_MimeType_HomeApp = "vr/home"; - static const char * const k_pch_MimeType_GameTheater = "vr/game_theater"; +/** Currently recognized mime types */ +static const char *const k_pch_MimeType_HomeApp = "vr/home"; +static const char *const k_pch_MimeType_GameTheater = "vr/game_theater"; - class IVRApplications - { - public: +class IVRApplications +{ +public: + // --------------- Application management --------------- // - // --------------- Application management --------------- // - - /** Adds an application manifest to the list to load when building the list of installed applications. + /** Adds an application manifest to the list to load when building the list of installed applications. * Temporary manifests are not automatically loaded */ - virtual EVRApplicationError AddApplicationManifest( const char *pchApplicationManifestFullPath, bool bTemporary = false ) = 0; + virtual EVRApplicationError AddApplicationManifest(const char *pchApplicationManifestFullPath, bool bTemporary = false) = 0; - /** Removes an application manifest from the list to load when building the list of installed applications. */ - virtual EVRApplicationError RemoveApplicationManifest( const char *pchApplicationManifestFullPath ) = 0; + /** Removes an application manifest from the list to load when building the list of installed applications. */ + virtual EVRApplicationError RemoveApplicationManifest(const char *pchApplicationManifestFullPath) = 0; - /** Returns true if an application is installed */ - virtual bool IsApplicationInstalled( const char *pchAppKey ) = 0; + /** Returns true if an application is installed */ + virtual bool IsApplicationInstalled(const char *pchAppKey) = 0; - /** Returns the number of applications available in the list */ - virtual uint32_t GetApplicationCount() = 0; + /** Returns the number of applications available in the list */ + virtual uint32_t GetApplicationCount() = 0; - /** Returns the key of the specified application. The index is at least 0 and is less than the return + /** Returns the key of the specified application. The index is at least 0 and is less than the return * value of GetApplicationCount(). The buffer should be at least k_unMaxApplicationKeyLength in order to * fit the key. */ - virtual EVRApplicationError GetApplicationKeyByIndex( uint32_t unApplicationIndex, VR_OUT_STRING() char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0; + virtual EVRApplicationError GetApplicationKeyByIndex(uint32_t unApplicationIndex, VR_OUT_STRING() char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen) = 0; - /** Returns the key of the application for the specified Process Id. The buffer should be at least + /** Returns the key of the application for the specified Process Id. The buffer should be at least * k_unMaxApplicationKeyLength in order to fit the key. */ - virtual EVRApplicationError GetApplicationKeyByProcessId( uint32_t unProcessId, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0; + virtual EVRApplicationError GetApplicationKeyByProcessId(uint32_t unProcessId, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen) = 0; - /** Launches the application. The existing scene application will exit and then the new application will start. + /** Launches the application. The existing scene application will exit and then the new application will start. * This call is not valid for dashboard overlay applications. */ - virtual EVRApplicationError LaunchApplication( const char *pchAppKey ) = 0; + virtual EVRApplicationError LaunchApplication(const char *pchAppKey) = 0; - /** Launches an instance of an application of type template, with its app key being pchNewAppKey (which must be unique) and optionally override sections + /** Launches an instance of an application of type template, with its app key being pchNewAppKey (which must be unique) and optionally override sections * from the manifest file via AppOverrideKeys_t */ - virtual EVRApplicationError LaunchTemplateApplication( const char *pchTemplateAppKey, const char *pchNewAppKey, VR_ARRAY_COUNT( unKeys ) const AppOverrideKeys_t *pKeys, uint32_t unKeys ) = 0; + virtual EVRApplicationError LaunchTemplateApplication(const char *pchTemplateAppKey, const char *pchNewAppKey, VR_ARRAY_COUNT(unKeys) const AppOverrideKeys_t *pKeys, uint32_t unKeys) = 0; - /** launches the application currently associated with this mime type and passes it the option args, typically the filename or object name of the item being launched */ - virtual vr::EVRApplicationError LaunchApplicationFromMimeType( const char *pchMimeType, const char *pchArgs ) = 0; + /** launches the application currently associated with this mime type and passes it the option args, typically the filename or object name of the item being launched */ + virtual vr::EVRApplicationError LaunchApplicationFromMimeType(const char *pchMimeType, const char *pchArgs) = 0; - /** Launches the dashboard overlay application if it is not already running. This call is only valid for + /** Launches the dashboard overlay application if it is not already running. This call is only valid for * dashboard overlay applications. */ - virtual EVRApplicationError LaunchDashboardOverlay( const char *pchAppKey ) = 0; + virtual EVRApplicationError LaunchDashboardOverlay(const char *pchAppKey) = 0; - /** Cancel a pending launch for an application */ - virtual bool CancelApplicationLaunch( const char *pchAppKey ) = 0; + /** Cancel a pending launch for an application */ + virtual bool CancelApplicationLaunch(const char *pchAppKey) = 0; - /** Identifies a running application. OpenVR can't always tell which process started in response + /** Identifies a running application. OpenVR can't always tell which process started in response * to a URL. This function allows a URL handler (or the process itself) to identify the app key * for the now running application. Passing a process ID of 0 identifies the calling process. * The application must be one that's known to the system via a call to AddApplicationManifest. */ - virtual EVRApplicationError IdentifyApplication( uint32_t unProcessId, const char *pchAppKey ) = 0; + virtual EVRApplicationError IdentifyApplication(uint32_t unProcessId, const char *pchAppKey) = 0; - /** Returns the process ID for an application. Return 0 if the application was not found or is not running. */ - virtual uint32_t GetApplicationProcessId( const char *pchAppKey ) = 0; + /** Returns the process ID for an application. Return 0 if the application was not found or is not running. */ + virtual uint32_t GetApplicationProcessId(const char *pchAppKey) = 0; - /** Returns a string for an applications error */ - virtual const char *GetApplicationsErrorNameFromEnum( EVRApplicationError error ) = 0; + /** Returns a string for an applications error */ + virtual const char *GetApplicationsErrorNameFromEnum(EVRApplicationError error) = 0; - // --------------- Application properties --------------- // + // --------------- Application properties --------------- // - /** Returns a value for an application property. The required buffer size to fit this value will be returned. */ - virtual uint32_t GetApplicationPropertyString( const char *pchAppKey, EVRApplicationProperty eProperty, VR_OUT_STRING() char *pchPropertyValueBuffer, uint32_t unPropertyValueBufferLen, EVRApplicationError *peError = nullptr ) = 0; + /** Returns a value for an application property. The required buffer size to fit this value will be returned. */ + virtual uint32_t GetApplicationPropertyString(const char *pchAppKey, EVRApplicationProperty eProperty, VR_OUT_STRING() char *pchPropertyValueBuffer, uint32_t unPropertyValueBufferLen, EVRApplicationError *peError = nullptr) = 0; - /** Returns a bool value for an application property. Returns false in all error cases. */ - virtual bool GetApplicationPropertyBool( const char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError = nullptr ) = 0; + /** Returns a bool value for an application property. Returns false in all error cases. */ + virtual bool GetApplicationPropertyBool(const char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError = nullptr) = 0; - /** Returns a uint64 value for an application property. Returns 0 in all error cases. */ - virtual uint64_t GetApplicationPropertyUint64( const char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError = nullptr ) = 0; + /** Returns a uint64 value for an application property. Returns 0 in all error cases. */ + virtual uint64_t GetApplicationPropertyUint64(const char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError = nullptr) = 0; - /** Sets the application auto-launch flag. This is only valid for applications which return true for VRApplicationProperty_IsDashboardOverlay_Bool. */ - virtual EVRApplicationError SetApplicationAutoLaunch( const char *pchAppKey, bool bAutoLaunch ) = 0; + /** Sets the application auto-launch flag. This is only valid for applications which return true for VRApplicationProperty_IsDashboardOverlay_Bool. */ + virtual EVRApplicationError SetApplicationAutoLaunch(const char *pchAppKey, bool bAutoLaunch) = 0; - /** Gets the application auto-launch flag. This is only valid for applications which return true for VRApplicationProperty_IsDashboardOverlay_Bool. */ - virtual bool GetApplicationAutoLaunch( const char *pchAppKey ) = 0; + /** Gets the application auto-launch flag. This is only valid for applications which return true for VRApplicationProperty_IsDashboardOverlay_Bool. */ + virtual bool GetApplicationAutoLaunch(const char *pchAppKey) = 0; - /** Adds this mime-type to the list of supported mime types for this application*/ - virtual EVRApplicationError SetDefaultApplicationForMimeType( const char *pchAppKey, const char *pchMimeType ) = 0; + /** Adds this mime-type to the list of supported mime types for this application*/ + virtual EVRApplicationError SetDefaultApplicationForMimeType(const char *pchAppKey, const char *pchMimeType) = 0; - /** return the app key that will open this mime type */ - virtual bool GetDefaultApplicationForMimeType( const char *pchMimeType, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0; + /** return the app key that will open this mime type */ + virtual bool GetDefaultApplicationForMimeType(const char *pchMimeType, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen) = 0; - /** Get the list of supported mime types for this application, comma-delimited */ - virtual bool GetApplicationSupportedMimeTypes( const char *pchAppKey, char *pchMimeTypesBuffer, uint32_t unMimeTypesBuffer ) = 0; + /** Get the list of supported mime types for this application, comma-delimited */ + virtual bool GetApplicationSupportedMimeTypes(const char *pchAppKey, char *pchMimeTypesBuffer, uint32_t unMimeTypesBuffer) = 0; - /** Get the list of app-keys that support this mime type, comma-delimited, the return value is number of bytes you need to return the full string */ - virtual uint32_t GetApplicationsThatSupportMimeType( const char *pchMimeType, char *pchAppKeysThatSupportBuffer, uint32_t unAppKeysThatSupportBuffer ) = 0; + /** Get the list of app-keys that support this mime type, comma-delimited, the return value is number of bytes you need to return the full string */ + virtual uint32_t GetApplicationsThatSupportMimeType(const char *pchMimeType, char *pchAppKeysThatSupportBuffer, uint32_t unAppKeysThatSupportBuffer) = 0; - /** Get the args list from an app launch that had the process already running, you call this when you get a VREvent_ApplicationMimeTypeLoad */ - virtual uint32_t GetApplicationLaunchArguments( uint32_t unHandle, char *pchArgs, uint32_t unArgs ) = 0; + /** Get the args list from an app launch that had the process already running, you call this when you get a VREvent_ApplicationMimeTypeLoad */ + virtual uint32_t GetApplicationLaunchArguments(uint32_t unHandle, char *pchArgs, uint32_t unArgs) = 0; - // --------------- Transition methods --------------- // + // --------------- Transition methods --------------- // - /** Returns the app key for the application that is starting up */ - virtual EVRApplicationError GetStartingApplication( char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0; + /** Returns the app key for the application that is starting up */ + virtual EVRApplicationError GetStartingApplication(char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen) = 0; - /** Returns the application transition state */ - virtual EVRApplicationTransitionState GetTransitionState() = 0; + /** Returns the application transition state */ + virtual EVRApplicationTransitionState GetTransitionState() = 0; - /** Returns errors that would prevent the specified application from launching immediately. Calling this function will + /** Returns errors that would prevent the specified application from launching immediately. Calling this function will * cause the current scene application to quit, so only call it when you are actually about to launch something else. * What the caller should do about these failures depends on the failure: * VRApplicationError_OldApplicationQuitting - An existing application has been told to quit. Wait for a VREvent_ProcessQuit @@ -1721,267 +1686,265 @@ namespace vr * VRApplicationError_LaunchInProgress - A different application is already starting. This is a permanent failure. * VRApplicationError_None - Go ahead and launch. Everything is clear. */ - virtual EVRApplicationError PerformApplicationPrelaunchCheck( const char *pchAppKey ) = 0; + virtual EVRApplicationError PerformApplicationPrelaunchCheck(const char *pchAppKey) = 0; - /** Returns a string for an application transition state */ - virtual const char *GetApplicationsTransitionStateNameFromEnum( EVRApplicationTransitionState state ) = 0; + /** Returns a string for an application transition state */ + virtual const char *GetApplicationsTransitionStateNameFromEnum(EVRApplicationTransitionState state) = 0; - /** Returns true if the outgoing scene app has requested a save prompt before exiting */ - virtual bool IsQuitUserPromptRequested() = 0; + /** Returns true if the outgoing scene app has requested a save prompt before exiting */ + virtual bool IsQuitUserPromptRequested() = 0; - /** Starts a subprocess within the calling application. This + /** Starts a subprocess within the calling application. This * suppresses all application transition UI and automatically identifies the new executable * as part of the same application. On success the calling process should exit immediately. * If working directory is NULL or "" the directory portion of the binary path will be * the working directory. */ - virtual EVRApplicationError LaunchInternalProcess( const char *pchBinaryPath, const char *pchArguments, const char *pchWorkingDirectory ) = 0; + virtual EVRApplicationError LaunchInternalProcess(const char *pchBinaryPath, const char *pchArguments, const char *pchWorkingDirectory) = 0; - /** Returns the current scene process ID according to the application system. A scene process will get scene + /** Returns the current scene process ID according to the application system. A scene process will get scene * focus once it starts rendering, but it will appear here once it calls VR_Init with the Scene application * type. */ - virtual uint32_t GetCurrentSceneProcessId() = 0; - }; + virtual uint32_t GetCurrentSceneProcessId() = 0; +}; - static const char * const IVRApplications_Version = "IVRApplications_006"; +static const char *const IVRApplications_Version = "IVRApplications_006"; -} // namespace vr +} // namespace vr // ivrsettings.h namespace vr { - enum EVRSettingsError - { - VRSettingsError_None = 0, - VRSettingsError_IPCFailed = 1, - VRSettingsError_WriteFailed = 2, - VRSettingsError_ReadFailed = 3, - VRSettingsError_JsonParseFailed = 4, - VRSettingsError_UnsetSettingHasNoDefault = 5, // This will be returned if the setting does not appear in the appropriate default file and has not been set - }; +enum EVRSettingsError +{ + VRSettingsError_None = 0, + VRSettingsError_IPCFailed = 1, + VRSettingsError_WriteFailed = 2, + VRSettingsError_ReadFailed = 3, + VRSettingsError_JsonParseFailed = 4, + VRSettingsError_UnsetSettingHasNoDefault = 5, // This will be returned if the setting does not appear in the appropriate default file and has not been set +}; - // The maximum length of a settings key - static const uint32_t k_unMaxSettingsKeyLength = 128; +// The maximum length of a settings key +static const uint32_t k_unMaxSettingsKeyLength = 128; - class IVRSettings - { - public: - virtual const char *GetSettingsErrorNameFromEnum( EVRSettingsError eError ) = 0; +class IVRSettings +{ +public: + virtual const char *GetSettingsErrorNameFromEnum(EVRSettingsError eError) = 0; - // Returns true if file sync occurred (force or settings dirty) - virtual bool Sync( bool bForce = false, EVRSettingsError *peError = nullptr ) = 0; + // Returns true if file sync occurred (force or settings dirty) + virtual bool Sync(bool bForce = false, EVRSettingsError *peError = nullptr) = 0; - virtual void SetBool( const char *pchSection, const char *pchSettingsKey, bool bValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetInt32( const char *pchSection, const char *pchSettingsKey, int32_t nValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetFloat( const char *pchSection, const char *pchSettingsKey, float flValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetString( const char *pchSection, const char *pchSettingsKey, const char *pchValue, EVRSettingsError *peError = nullptr ) = 0; + virtual void SetBool(const char *pchSection, const char *pchSettingsKey, bool bValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetInt32(const char *pchSection, const char *pchSettingsKey, int32_t nValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetFloat(const char *pchSection, const char *pchSettingsKey, float flValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetString(const char *pchSection, const char *pchSettingsKey, const char *pchValue, EVRSettingsError *peError = nullptr) = 0; - // Users of the system need to provide a proper default in default.vrsettings in the resources/settings/ directory - // of either the runtime or the driver_xxx directory. Otherwise the default will be false, 0, 0.0 or "" - virtual bool GetBool( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual int32_t GetInt32( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual float GetFloat( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual void GetString( const char *pchSection, const char *pchSettingsKey, VR_OUT_STRING() char *pchValue, uint32_t unValueLen, EVRSettingsError *peError = nullptr ) = 0; + // Users of the system need to provide a proper default in default.vrsettings in the resources/settings/ directory + // of either the runtime or the driver_xxx directory. Otherwise the default will be false, 0, 0.0 or "" + virtual bool GetBool(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual int32_t GetInt32(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual float GetFloat(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual void GetString(const char *pchSection, const char *pchSettingsKey, VR_OUT_STRING() char *pchValue, uint32_t unValueLen, EVRSettingsError *peError = nullptr) = 0; - virtual void RemoveSection( const char *pchSection, EVRSettingsError *peError = nullptr ) = 0; - virtual void RemoveKeyInSection( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - }; + virtual void RemoveSection(const char *pchSection, EVRSettingsError *peError = nullptr) = 0; + virtual void RemoveKeyInSection(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; +}; - //----------------------------------------------------------------------------- - static const char * const IVRSettings_Version = "IVRSettings_002"; +//----------------------------------------------------------------------------- +static const char *const IVRSettings_Version = "IVRSettings_002"; - //----------------------------------------------------------------------------- - // steamvr keys - static const char * const k_pch_SteamVR_Section = "steamvr"; - static const char * const k_pch_SteamVR_RequireHmd_String = "requireHmd"; - static const char * const k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; - static const char * const k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; - static const char * const k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; - static const char * const k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; - static const char * const k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; - static const char * const k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; - static const char * const k_pch_SteamVR_SendSystemButtonToAllApps_Bool= "sendSystemButtonToAllApps"; - static const char * const k_pch_SteamVR_LogLevel_Int32 = "loglevel"; - static const char * const k_pch_SteamVR_IPD_Float = "ipd"; - static const char * const k_pch_SteamVR_Background_String = "background"; - static const char * const k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; - static const char * const k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; - static const char * const k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; - static const char * const k_pch_SteamVR_GridColor_String = "gridColor"; - static const char * const k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; - static const char * const k_pch_SteamVR_ShowStage_Bool = "showStage"; - static const char * const k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; - static const char * const k_pch_SteamVR_DirectMode_Bool = "directMode"; - static const char * const k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; - static const char * const k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; - static const char * const k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; - static const char * const k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; - static const char * const k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; - static const char * const k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; - static const char * const k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; - static const char * const k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; - static const char * const k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; - static const char * const k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; - static const char * const k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; - static const char * const k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; - static const char * const k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; - static const char * const k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; - static const char * const k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; - static const char * const k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; - static const char * const k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; - static const char * const k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; - static const char * const k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; - static const char * const k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; - static const char * const k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; - static const char * const k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; - static const char * const k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; - static const char * const k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; +//----------------------------------------------------------------------------- +// steamvr keys +static const char *const k_pch_SteamVR_Section = "steamvr"; +static const char *const k_pch_SteamVR_RequireHmd_String = "requireHmd"; +static const char *const k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; +static const char *const k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; +static const char *const k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; +static const char *const k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; +static const char *const k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; +static const char *const k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; +static const char *const k_pch_SteamVR_SendSystemButtonToAllApps_Bool = "sendSystemButtonToAllApps"; +static const char *const k_pch_SteamVR_LogLevel_Int32 = "loglevel"; +static const char *const k_pch_SteamVR_IPD_Float = "ipd"; +static const char *const k_pch_SteamVR_Background_String = "background"; +static const char *const k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; +static const char *const k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; +static const char *const k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; +static const char *const k_pch_SteamVR_GridColor_String = "gridColor"; +static const char *const k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; +static const char *const k_pch_SteamVR_ShowStage_Bool = "showStage"; +static const char *const k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; +static const char *const k_pch_SteamVR_DirectMode_Bool = "directMode"; +static const char *const k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; +static const char *const k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; +static const char *const k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; +static const char *const k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; +static const char *const k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; +static const char *const k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; +static const char *const k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; +static const char *const k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; +static const char *const k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; +static const char *const k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; +static const char *const k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; +static const char *const k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; +static const char *const k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; +static const char *const k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; +static const char *const k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; +static const char *const k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; +static const char *const k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; +static const char *const k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; +static const char *const k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; +static const char *const k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; +static const char *const k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; +static const char *const k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; +static const char *const k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; +static const char *const k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; - //----------------------------------------------------------------------------- - // lighthouse keys - static const char * const k_pch_Lighthouse_Section = "driver_lighthouse"; - static const char * const k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; - static const char * const k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; - static const char * const k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; - static const char * const k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; - static const char * const k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; +//----------------------------------------------------------------------------- +// lighthouse keys +static const char *const k_pch_Lighthouse_Section = "driver_lighthouse"; +static const char *const k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; +static const char *const k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; +static const char *const k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; +static const char *const k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; +static const char *const k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; - //----------------------------------------------------------------------------- - // null keys - static const char * const k_pch_Null_Section = "driver_null"; - static const char * const k_pch_Null_SerialNumber_String = "serialNumber"; - static const char * const k_pch_Null_ModelNumber_String = "modelNumber"; - static const char * const k_pch_Null_WindowX_Int32 = "windowX"; - static const char * const k_pch_Null_WindowY_Int32 = "windowY"; - static const char * const k_pch_Null_WindowWidth_Int32 = "windowWidth"; - static const char * const k_pch_Null_WindowHeight_Int32 = "windowHeight"; - static const char * const k_pch_Null_RenderWidth_Int32 = "renderWidth"; - static const char * const k_pch_Null_RenderHeight_Int32 = "renderHeight"; - static const char * const k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; - static const char * const k_pch_Null_DisplayFrequency_Float = "displayFrequency"; +//----------------------------------------------------------------------------- +// null keys +static const char *const k_pch_Null_Section = "driver_null"; +static const char *const k_pch_Null_SerialNumber_String = "serialNumber"; +static const char *const k_pch_Null_ModelNumber_String = "modelNumber"; +static const char *const k_pch_Null_WindowX_Int32 = "windowX"; +static const char *const k_pch_Null_WindowY_Int32 = "windowY"; +static const char *const k_pch_Null_WindowWidth_Int32 = "windowWidth"; +static const char *const k_pch_Null_WindowHeight_Int32 = "windowHeight"; +static const char *const k_pch_Null_RenderWidth_Int32 = "renderWidth"; +static const char *const k_pch_Null_RenderHeight_Int32 = "renderHeight"; +static const char *const k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; +static const char *const k_pch_Null_DisplayFrequency_Float = "displayFrequency"; - //----------------------------------------------------------------------------- - // user interface keys - static const char * const k_pch_UserInterface_Section = "userinterface"; - static const char * const k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; - static const char * const k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; - static const char * const k_pch_UserInterface_Screenshots_Bool = "screenshots"; - static const char * const k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; +//----------------------------------------------------------------------------- +// user interface keys +static const char *const k_pch_UserInterface_Section = "userinterface"; +static const char *const k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; +static const char *const k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; +static const char *const k_pch_UserInterface_Screenshots_Bool = "screenshots"; +static const char *const k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; - //----------------------------------------------------------------------------- - // notification keys - static const char * const k_pch_Notifications_Section = "notifications"; - static const char * const k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; +//----------------------------------------------------------------------------- +// notification keys +static const char *const k_pch_Notifications_Section = "notifications"; +static const char *const k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; - //----------------------------------------------------------------------------- - // keyboard keys - static const char * const k_pch_Keyboard_Section = "keyboard"; - static const char * const k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; - static const char * const k_pch_Keyboard_ScaleX = "ScaleX"; - static const char * const k_pch_Keyboard_ScaleY = "ScaleY"; - static const char * const k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; - static const char * const k_pch_Keyboard_OffsetRightX = "OffsetRightX"; - static const char * const k_pch_Keyboard_OffsetY = "OffsetY"; - static const char * const k_pch_Keyboard_Smoothing = "Smoothing"; +//----------------------------------------------------------------------------- +// keyboard keys +static const char *const k_pch_Keyboard_Section = "keyboard"; +static const char *const k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; +static const char *const k_pch_Keyboard_ScaleX = "ScaleX"; +static const char *const k_pch_Keyboard_ScaleY = "ScaleY"; +static const char *const k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; +static const char *const k_pch_Keyboard_OffsetRightX = "OffsetRightX"; +static const char *const k_pch_Keyboard_OffsetY = "OffsetY"; +static const char *const k_pch_Keyboard_Smoothing = "Smoothing"; - //----------------------------------------------------------------------------- - // perf keys - static const char * const k_pch_Perf_Section = "perfcheck"; - static const char * const k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; - static const char * const k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; - static const char * const k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; - static const char * const k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; - static const char * const k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; - static const char * const k_pch_Perf_TestData_Float = "perfTestData"; - static const char * const k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; +//----------------------------------------------------------------------------- +// perf keys +static const char *const k_pch_Perf_Section = "perfcheck"; +static const char *const k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; +static const char *const k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; +static const char *const k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; +static const char *const k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; +static const char *const k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; +static const char *const k_pch_Perf_TestData_Float = "perfTestData"; +static const char *const k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; - //----------------------------------------------------------------------------- - // collision bounds keys - static const char * const k_pch_CollisionBounds_Section = "collisionBounds"; - static const char * const k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; - static const char * const k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; - static const char * const k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; - static const char * const k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; - static const char * const k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; - static const char * const k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; - static const char * const k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; - static const char * const k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; - static const char * const k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; +//----------------------------------------------------------------------------- +// collision bounds keys +static const char *const k_pch_CollisionBounds_Section = "collisionBounds"; +static const char *const k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; +static const char *const k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; +static const char *const k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; +static const char *const k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; +static const char *const k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; +static const char *const k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; +static const char *const k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; +static const char *const k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; +static const char *const k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; - //----------------------------------------------------------------------------- - // camera keys - static const char * const k_pch_Camera_Section = "camera"; - static const char * const k_pch_Camera_EnableCamera_Bool = "enableCamera"; - static const char * const k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; - static const char * const k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; - static const char * const k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; - static const char * const k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; - static const char * const k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; - static const char * const k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; - static const char * const k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; - static const char * const k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; +//----------------------------------------------------------------------------- +// camera keys +static const char *const k_pch_Camera_Section = "camera"; +static const char *const k_pch_Camera_EnableCamera_Bool = "enableCamera"; +static const char *const k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; +static const char *const k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; +static const char *const k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; +static const char *const k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; +static const char *const k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; +static const char *const k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; +static const char *const k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; +static const char *const k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; - //----------------------------------------------------------------------------- - // audio keys - static const char * const k_pch_audio_Section = "audio"; - static const char * const k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; - static const char * const k_pch_audio_OnRecordDevice_String = "onRecordDevice"; - static const char * const k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; - static const char * const k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; - static const char * const k_pch_audio_OffRecordDevice_String = "offRecordDevice"; - static const char * const k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; +//----------------------------------------------------------------------------- +// audio keys +static const char *const k_pch_audio_Section = "audio"; +static const char *const k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; +static const char *const k_pch_audio_OnRecordDevice_String = "onRecordDevice"; +static const char *const k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; +static const char *const k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; +static const char *const k_pch_audio_OffRecordDevice_String = "offRecordDevice"; +static const char *const k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; - //----------------------------------------------------------------------------- - // power management keys - static const char * const k_pch_Power_Section = "power"; - static const char * const k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; - static const char * const k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; - static const char * const k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; - static const char * const k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; - static const char * const k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; - static const char * const k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; +//----------------------------------------------------------------------------- +// power management keys +static const char *const k_pch_Power_Section = "power"; +static const char *const k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; +static const char *const k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; +static const char *const k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; +static const char *const k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; +static const char *const k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; +static const char *const k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; - //----------------------------------------------------------------------------- - // dashboard keys - static const char * const k_pch_Dashboard_Section = "dashboard"; - static const char * const k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; - static const char * const k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; +//----------------------------------------------------------------------------- +// dashboard keys +static const char *const k_pch_Dashboard_Section = "dashboard"; +static const char *const k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; +static const char *const k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; - //----------------------------------------------------------------------------- - // model skin keys - static const char * const k_pch_modelskin_Section = "modelskins"; +//----------------------------------------------------------------------------- +// model skin keys +static const char *const k_pch_modelskin_Section = "modelskins"; - //----------------------------------------------------------------------------- - // driver keys - These could be checked in any driver_ section - static const char * const k_pch_Driver_Enable_Bool = "enable"; +//----------------------------------------------------------------------------- +// driver keys - These could be checked in any driver_ section +static const char *const k_pch_Driver_Enable_Bool = "enable"; -} // namespace vr +} // namespace vr // ivrchaperone.h namespace vr { - -#pragma pack( push, 8 ) +#pragma pack(push, 8) enum ChaperoneCalibrationState { // OK! - ChaperoneCalibrationState_OK = 1, // Chaperone is fully calibrated and working correctly + ChaperoneCalibrationState_OK = 1, // Chaperone is fully calibrated and working correctly // Warnings ChaperoneCalibrationState_Warning = 100, - ChaperoneCalibrationState_Warning_BaseStationMayHaveMoved = 101, // A base station thinks that it might have moved - ChaperoneCalibrationState_Warning_BaseStationRemoved = 102, // There are less base stations than when calibrated - ChaperoneCalibrationState_Warning_SeatedBoundsInvalid = 103, // Seated bounds haven't been calibrated for the current tracking center + ChaperoneCalibrationState_Warning_BaseStationMayHaveMoved = 101, // A base station thinks that it might have moved + ChaperoneCalibrationState_Warning_BaseStationRemoved = 102, // There are less base stations than when calibrated + ChaperoneCalibrationState_Warning_SeatedBoundsInvalid = 103, // Seated bounds haven't been calibrated for the current tracking center // Errors - ChaperoneCalibrationState_Error = 200, // The UniverseID is invalid - ChaperoneCalibrationState_Error_BaseStationUninitialized = 201, // Tracking center hasn't be calibrated for at least one of the base stations - ChaperoneCalibrationState_Error_BaseStationConflict = 202, // Tracking center is calibrated, but base stations disagree on the tracking space - ChaperoneCalibrationState_Error_PlayAreaInvalid = 203, // Play Area hasn't been calibrated for the current tracking center - ChaperoneCalibrationState_Error_CollisionBoundsInvalid = 204, // Collision Bounds haven't been calibrated for the current tracking center + ChaperoneCalibrationState_Error = 200, // The UniverseID is invalid + ChaperoneCalibrationState_Error_BaseStationUninitialized = 201, // Tracking center hasn't be calibrated for at least one of the base stations + ChaperoneCalibrationState_Error_BaseStationConflict = 202, // Tracking center is calibrated, but base stations disagree on the tracking space + ChaperoneCalibrationState_Error_PlayAreaInvalid = 203, // Play Area hasn't been calibrated for the current tracking center + ChaperoneCalibrationState_Error_CollisionBoundsInvalid = 204, // Collision Bounds haven't been calibrated for the current tracking center }; - /** HIGH LEVEL TRACKING SPACE ASSUMPTIONS: * 0,0,0 is the preferred standing area center. * 0Y is the floor height. @@ -1989,13 +1952,12 @@ enum ChaperoneCalibrationState class IVRChaperone { public: - /** Get the current state of Chaperone calibration. This state can change at any time during a session due to physical base station changes. **/ virtual ChaperoneCalibrationState GetCalibrationState() = 0; /** Returns the width and depth of the Play Area (formerly named Soft Bounds) in X and Z. * Tracking space center (0,0,0) is the center of the Play Area. **/ - virtual bool GetPlayAreaSize( float *pSizeX, float *pSizeZ ) = 0; + virtual bool GetPlayAreaSize(float *pSizeX, float *pSizeZ) = 0; /** Returns the 4 corner positions of the Play Area (formerly named Soft Bounds). * Corners are in counter-clockwise order. @@ -2003,38 +1965,37 @@ public: * It's a rectangle. * 2 sides are parallel to the X axis and 2 sides are parallel to the Z axis. * Height of every corner is 0Y (on the floor). **/ - virtual bool GetPlayAreaRect( HmdQuad_t *rect ) = 0; + virtual bool GetPlayAreaRect(HmdQuad_t *rect) = 0; /** Reload Chaperone data from the .vrchap file on disk. */ - virtual void ReloadInfo( void ) = 0; + virtual void ReloadInfo(void) = 0; /** Optionally give the chaperone system a hit about the color and brightness in the scene **/ - virtual void SetSceneColor( HmdColor_t color ) = 0; + virtual void SetSceneColor(HmdColor_t color) = 0; /** Get the current chaperone bounds draw color and brightness **/ - virtual void GetBoundsColor( HmdColor_t *pOutputColorArray, int nNumOutputColors, float flCollisionBoundsFadeDistance, HmdColor_t *pOutputCameraColor ) = 0; + virtual void GetBoundsColor(HmdColor_t *pOutputColorArray, int nNumOutputColors, float flCollisionBoundsFadeDistance, HmdColor_t *pOutputCameraColor) = 0; /** Determine whether the bounds are showing right now **/ virtual bool AreBoundsVisible() = 0; /** Force the bounds to show, mostly for utilities **/ - virtual void ForceBoundsVisible( bool bForce ) = 0; + virtual void ForceBoundsVisible(bool bForce) = 0; }; -static const char * const IVRChaperone_Version = "IVRChaperone_003"; +static const char *const IVRChaperone_Version = "IVRChaperone_003"; -#pragma pack( pop ) +#pragma pack(pop) -} +} // namespace vr // ivrchaperonesetup.h namespace vr { - enum EChaperoneConfigFile { - EChaperoneConfigFile_Live = 1, // The live chaperone config, used by most applications and games - EChaperoneConfigFile_Temp = 2, // The temporary chaperone config, used to live-preview collision bounds in room setup + EChaperoneConfigFile_Live = 1, // The live chaperone config, used by most applications and games + EChaperoneConfigFile_Temp = 2, // The temporary chaperone config, used to live-preview collision bounds in room setup }; enum EChaperoneImportFlags @@ -2049,9 +2010,8 @@ enum EChaperoneImportFlags class IVRChaperoneSetup { public: - /** Saves the current working copy to disk */ - virtual bool CommitWorkingCopy( EChaperoneConfigFile configFile ) = 0; + virtual bool CommitWorkingCopy(EChaperoneConfigFile configFile) = 0; /** Reverts the working copy to match the live chaperone calibration. * To modify existing data this MUST be do WHILE getting a non-error ChaperoneCalibrationStatus. @@ -2060,7 +2020,7 @@ public: /** Returns the width and depth of the Play Area (formerly named Soft Bounds) in X and Z from the working copy. * Tracking space center (0,0,0) is the center of the Play Area. */ - virtual bool GetWorkingPlayAreaSize( float *pSizeX, float *pSizeZ ) = 0; + virtual bool GetWorkingPlayAreaSize(float *pSizeX, float *pSizeZ) = 0; /** Returns the 4 corner positions of the Play Area (formerly named Soft Bounds) from the working copy. * Corners are in clockwise order. @@ -2068,95 +2028,93 @@ public: * It's a rectangle. * 2 sides are parallel to the X axis and 2 sides are parallel to the Z axis. * Height of every corner is 0Y (on the floor). **/ - virtual bool GetWorkingPlayAreaRect( HmdQuad_t *rect ) = 0; + virtual bool GetWorkingPlayAreaRect(HmdQuad_t *rect) = 0; /** Returns the number of Quads if the buffer points to null. Otherwise it returns Quads * into the buffer up to the max specified from the working copy. */ - virtual bool GetWorkingCollisionBoundsInfo( VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t* punQuadsCount ) = 0; + virtual bool GetWorkingCollisionBoundsInfo(VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount) = 0; /** Returns the number of Quads if the buffer points to null. Otherwise it returns Quads * into the buffer up to the max specified. */ - virtual bool GetLiveCollisionBoundsInfo( VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t* punQuadsCount ) = 0; + virtual bool GetLiveCollisionBoundsInfo(VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount) = 0; /** Returns the preferred seated position from the working copy. */ - virtual bool GetWorkingSeatedZeroPoseToRawTrackingPose( HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose ) = 0; + virtual bool GetWorkingSeatedZeroPoseToRawTrackingPose(HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose) = 0; /** Returns the standing origin from the working copy. */ - virtual bool GetWorkingStandingZeroPoseToRawTrackingPose( HmdMatrix34_t *pmatStandingZeroPoseToRawTrackingPose ) = 0; + virtual bool GetWorkingStandingZeroPoseToRawTrackingPose(HmdMatrix34_t *pmatStandingZeroPoseToRawTrackingPose) = 0; /** Sets the Play Area in the working copy. */ - virtual void SetWorkingPlayAreaSize( float sizeX, float sizeZ ) = 0; + virtual void SetWorkingPlayAreaSize(float sizeX, float sizeZ) = 0; /** Sets the Collision Bounds in the working copy. */ - virtual void SetWorkingCollisionBoundsInfo( VR_ARRAY_COUNT(unQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount ) = 0; + virtual void SetWorkingCollisionBoundsInfo(VR_ARRAY_COUNT(unQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount) = 0; /** Sets the preferred seated position in the working copy. */ - virtual void SetWorkingSeatedZeroPoseToRawTrackingPose( const HmdMatrix34_t *pMatSeatedZeroPoseToRawTrackingPose ) = 0; + virtual void SetWorkingSeatedZeroPoseToRawTrackingPose(const HmdMatrix34_t *pMatSeatedZeroPoseToRawTrackingPose) = 0; /** Sets the preferred standing position in the working copy. */ - virtual void SetWorkingStandingZeroPoseToRawTrackingPose( const HmdMatrix34_t *pMatStandingZeroPoseToRawTrackingPose ) = 0; + virtual void SetWorkingStandingZeroPoseToRawTrackingPose(const HmdMatrix34_t *pMatStandingZeroPoseToRawTrackingPose) = 0; /** Tear everything down and reload it from the file on disk */ - virtual void ReloadFromDisk( EChaperoneConfigFile configFile ) = 0; + virtual void ReloadFromDisk(EChaperoneConfigFile configFile) = 0; /** Returns the preferred seated position. */ - virtual bool GetLiveSeatedZeroPoseToRawTrackingPose( HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose ) = 0; + virtual bool GetLiveSeatedZeroPoseToRawTrackingPose(HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose) = 0; - virtual void SetWorkingCollisionBoundsTagsInfo( VR_ARRAY_COUNT(unTagCount) uint8_t *pTagsBuffer, uint32_t unTagCount ) = 0; - virtual bool GetLiveCollisionBoundsTagsInfo( VR_OUT_ARRAY_COUNT(punTagCount) uint8_t *pTagsBuffer, uint32_t *punTagCount ) = 0; + virtual void SetWorkingCollisionBoundsTagsInfo(VR_ARRAY_COUNT(unTagCount) uint8_t *pTagsBuffer, uint32_t unTagCount) = 0; + virtual bool GetLiveCollisionBoundsTagsInfo(VR_OUT_ARRAY_COUNT(punTagCount) uint8_t *pTagsBuffer, uint32_t *punTagCount) = 0; - virtual bool SetWorkingPhysicalBoundsInfo( VR_ARRAY_COUNT(unQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount ) = 0; - virtual bool GetLivePhysicalBoundsInfo( VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t* punQuadsCount ) = 0; + virtual bool SetWorkingPhysicalBoundsInfo(VR_ARRAY_COUNT(unQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount) = 0; + virtual bool GetLivePhysicalBoundsInfo(VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount) = 0; - virtual bool ExportLiveToBuffer( VR_OUT_STRING() char *pBuffer, uint32_t *pnBufferLength ) = 0; - virtual bool ImportFromBufferToWorking( const char *pBuffer, uint32_t nImportFlags ) = 0; + virtual bool ExportLiveToBuffer(VR_OUT_STRING() char *pBuffer, uint32_t *pnBufferLength) = 0; + virtual bool ImportFromBufferToWorking(const char *pBuffer, uint32_t nImportFlags) = 0; }; -static const char * const IVRChaperoneSetup_Version = "IVRChaperoneSetup_005"; +static const char *const IVRChaperoneSetup_Version = "IVRChaperoneSetup_005"; - -} +} // namespace vr // ivrcompositor.h namespace vr { - -#pragma pack( push, 8 ) +#pragma pack(push, 8) /** Errors that can occur with the VR compositor */ enum EVRCompositorError { - VRCompositorError_None = 0, - VRCompositorError_RequestFailed = 1, - VRCompositorError_IncompatibleVersion = 100, - VRCompositorError_DoNotHaveFocus = 101, - VRCompositorError_InvalidTexture = 102, - VRCompositorError_IsNotSceneApplication = 103, - VRCompositorError_TextureIsOnWrongDevice = 104, + VRCompositorError_None = 0, + VRCompositorError_RequestFailed = 1, + VRCompositorError_IncompatibleVersion = 100, + VRCompositorError_DoNotHaveFocus = 101, + VRCompositorError_InvalidTexture = 102, + VRCompositorError_IsNotSceneApplication = 103, + VRCompositorError_TextureIsOnWrongDevice = 104, VRCompositorError_TextureUsesUnsupportedFormat = 105, VRCompositorError_SharedTexturesNotSupported = 106, - VRCompositorError_IndexOutOfRange = 107, - VRCompositorError_AlreadySubmitted = 108, - VRCompositorError_InvalidBounds = 109, + VRCompositorError_IndexOutOfRange = 107, + VRCompositorError_AlreadySubmitted = 108, + VRCompositorError_InvalidBounds = 109, }; const uint32_t VRCompositor_ReprojectionReason_Cpu = 0x01; const uint32_t VRCompositor_ReprojectionReason_Gpu = 0x02; -const uint32_t VRCompositor_ReprojectionAsync = 0x04; // This flag indicates the async reprojection mode is active, - // but does not indicate if reprojection actually happened or not. - // Use the ReprojectionReason flags above to check if reprojection - // was actually applied (i.e. scene texture was reused). - // NumFramePresents > 1 also indicates the scene texture was reused, - // and also the number of times that it was presented in total. +const uint32_t VRCompositor_ReprojectionAsync = 0x04; // This flag indicates the async reprojection mode is active, + // but does not indicate if reprojection actually happened or not. + // Use the ReprojectionReason flags above to check if reprojection + // was actually applied (i.e. scene texture was reused). + // NumFramePresents > 1 also indicates the scene texture was reused, + // and also the number of times that it was presented in total. /** Provides a single frame's timing information to the app */ struct Compositor_FrameTiming { - uint32_t m_nSize; // Set to sizeof( Compositor_FrameTiming ) + uint32_t m_nSize; // Set to sizeof( Compositor_FrameTiming ) uint32_t m_nFrameIndex; - uint32_t m_nNumFramePresents; // number of times this frame was presented - uint32_t m_nNumMisPresented; // number of times this frame was presented on a vsync other than it was originally predicted to - uint32_t m_nNumDroppedFrames; // number of additional times previous frame was scanned out + uint32_t m_nNumFramePresents; // number of times this frame was presented + uint32_t m_nNumMisPresented; // number of times this frame was presented on a vsync other than it was originally predicted to + uint32_t m_nNumDroppedFrames; // number of additional times previous frame was scanned out uint32_t m_nReprojectionFlags; /** Absolute time reference for comparing frames. This aligns with the vsync that running start is relative to. */ @@ -2166,38 +2124,38 @@ struct Compositor_FrameTiming * The fewer packets of work these are broken up into, the less likely this will happen. * GPU work can be broken up by calling Flush. This can sometimes be useful to get the GPU started * processing that work earlier in the frame. */ - float m_flPreSubmitGpuMs; // time spent rendering the scene (gpu work submitted between WaitGetPoses and second Submit) - float m_flPostSubmitGpuMs; // additional time spent rendering by application (e.g. companion window) - float m_flTotalRenderGpuMs; // time between work submitted immediately after present (ideally vsync) until the end of compositor submitted work - float m_flCompositorRenderGpuMs; // time spend performing distortion correction, rendering chaperone, overlays, etc. - float m_flCompositorRenderCpuMs; // time spent on cpu submitting the above work for this frame - float m_flCompositorIdleCpuMs; // time spent waiting for running start (application could have used this much more time) + float m_flPreSubmitGpuMs; // time spent rendering the scene (gpu work submitted between WaitGetPoses and second Submit) + float m_flPostSubmitGpuMs; // additional time spent rendering by application (e.g. companion window) + float m_flTotalRenderGpuMs; // time between work submitted immediately after present (ideally vsync) until the end of compositor submitted work + float m_flCompositorRenderGpuMs; // time spend performing distortion correction, rendering chaperone, overlays, etc. + float m_flCompositorRenderCpuMs; // time spent on cpu submitting the above work for this frame + float m_flCompositorIdleCpuMs; // time spent waiting for running start (application could have used this much more time) /** Miscellaneous measured intervals. */ - float m_flClientFrameIntervalMs; // time between calls to WaitGetPoses - float m_flPresentCallCpuMs; // time blocked on call to present (usually 0.0, but can go long) - float m_flWaitForPresentCpuMs; // time spent spin-waiting for frame index to change (not near-zero indicates wait object failure) - float m_flSubmitFrameMs; // time spent in IVRCompositor::Submit (not near-zero indicates driver issue) + float m_flClientFrameIntervalMs; // time between calls to WaitGetPoses + float m_flPresentCallCpuMs; // time blocked on call to present (usually 0.0, but can go long) + float m_flWaitForPresentCpuMs; // time spent spin-waiting for frame index to change (not near-zero indicates wait object failure) + float m_flSubmitFrameMs; // time spent in IVRCompositor::Submit (not near-zero indicates driver issue) /** The following are all relative to this frame's SystemTimeInSeconds */ float m_flWaitGetPosesCalledMs; float m_flNewPosesReadyMs; - float m_flNewFrameReadyMs; // second call to IVRCompositor::Submit + float m_flNewFrameReadyMs; // second call to IVRCompositor::Submit float m_flCompositorUpdateStartMs; float m_flCompositorUpdateEndMs; float m_flCompositorRenderStartMs; - vr::TrackedDevicePose_t m_HmdPose; // pose used by app to render this frame + vr::TrackedDevicePose_t m_HmdPose; // pose used by app to render this frame }; /** Cumulative stats for current application. These are not cleared until a new app connects, * but they do stop accumulating once the associated app disconnects. */ struct Compositor_CumulativeStats { - uint32_t m_nPid; // Process id associated with these stats (may no longer be running). - uint32_t m_nNumFramePresents; // total number of times we called present (includes reprojected frames) - uint32_t m_nNumDroppedFrames; // total number of times an old frame was re-scanned out (without reprojection) - uint32_t m_nNumReprojectedFrames; // total number of times a frame was scanned out a second time (with reprojection) + uint32_t m_nPid; // Process id associated with these stats (may no longer be running). + uint32_t m_nNumFramePresents; // total number of times we called present (includes reprojected frames) + uint32_t m_nNumDroppedFrames; // total number of times an old frame was re-scanned out (without reprojection) + uint32_t m_nNumReprojectedFrames; // total number of times a frame was scanned out a second time (with reprojection) /** Values recorded at startup before application has fully faded in the first time. */ uint32_t m_nNumFramePresentsOnStartup; @@ -2220,14 +2178,14 @@ struct Compositor_CumulativeStats uint32_t m_nNumReprojectedFramesTimedOut; }; -#pragma pack( pop ) +#pragma pack(pop) /** Allows the application to interact with the compositor */ class IVRCompositor { public: /** Sets tracking space returned by WaitGetPoses */ - virtual void SetTrackingSpace( ETrackingUniverseOrigin eOrigin ) = 0; + virtual void SetTrackingSpace(ETrackingUniverseOrigin eOrigin) = 0; /** Gets current tracking space returned by WaitGetPoses */ virtual ETrackingUniverseOrigin GetTrackingSpace() = 0; @@ -2240,17 +2198,17 @@ public: * - IsNotSceneApplication (make sure to call VR_Init with VRApplicaiton_Scene) * - DoNotHaveFocus (some other app has taken focus - this will throttle the call to 10hz to reduce the impact on that app) */ - virtual EVRCompositorError WaitGetPoses( VR_ARRAY_COUNT(unRenderPoseArrayCount) TrackedDevicePose_t* pRenderPoseArray, uint32_t unRenderPoseArrayCount, - VR_ARRAY_COUNT(unGamePoseArrayCount) TrackedDevicePose_t* pGamePoseArray, uint32_t unGamePoseArrayCount ) = 0; + virtual EVRCompositorError WaitGetPoses(VR_ARRAY_COUNT(unRenderPoseArrayCount) TrackedDevicePose_t *pRenderPoseArray, uint32_t unRenderPoseArrayCount, + VR_ARRAY_COUNT(unGamePoseArrayCount) TrackedDevicePose_t *pGamePoseArray, uint32_t unGamePoseArrayCount) = 0; /** Get the last set of poses returned by WaitGetPoses. */ - virtual EVRCompositorError GetLastPoses( VR_ARRAY_COUNT( unRenderPoseArrayCount ) TrackedDevicePose_t* pRenderPoseArray, uint32_t unRenderPoseArrayCount, - VR_ARRAY_COUNT( unGamePoseArrayCount ) TrackedDevicePose_t* pGamePoseArray, uint32_t unGamePoseArrayCount ) = 0; + virtual EVRCompositorError GetLastPoses(VR_ARRAY_COUNT(unRenderPoseArrayCount) TrackedDevicePose_t *pRenderPoseArray, uint32_t unRenderPoseArrayCount, + VR_ARRAY_COUNT(unGamePoseArrayCount) TrackedDevicePose_t *pGamePoseArray, uint32_t unGamePoseArrayCount) = 0; /** Interface for accessing last set of poses returned by WaitGetPoses one at a time. * Returns VRCompositorError_IndexOutOfRange if unDeviceIndex not less than k_unMaxTrackedDeviceCount otherwise VRCompositorError_None. * It is okay to pass NULL for either pose if you only want one of the values. */ - virtual EVRCompositorError GetLastPoseForTrackedDeviceIndex( TrackedDeviceIndex_t unDeviceIndex, TrackedDevicePose_t *pOutputPose, TrackedDevicePose_t *pOutputGamePose ) = 0; + virtual EVRCompositorError GetLastPoseForTrackedDeviceIndex(TrackedDeviceIndex_t unDeviceIndex, TrackedDevicePose_t *pOutputPose, TrackedDevicePose_t *pOutputGamePose) = 0; /** Updated scene texture to display. If pBounds is NULL the entire texture will be used. If called from an OpenGL app, consider adding a glFlush after * Submitting both frames to signal the driver to start processing, otherwise it may wait until the command buffer fills up, causing the app to miss frames. @@ -2267,7 +2225,7 @@ public: * - InvalidTexture (usually means bad arguments passed in) * - AlreadySubmitted (app has submitted two left textures or two right textures in a single frame - i.e. before calling WaitGetPoses again) */ - virtual EVRCompositorError Submit( EVREye eEye, const Texture_t *pTexture, const VRTextureBounds_t* pBounds = 0, EVRSubmitFlags nSubmitFlags = Submit_Default ) = 0; + virtual EVRCompositorError Submit(EVREye eEye, const Texture_t *pTexture, const VRTextureBounds_t *pBounds = 0, EVRSubmitFlags nSubmitFlags = Submit_Default) = 0; /** Clears the frame that was sent with the last call to Submit. This will cause the * compositor to show the grid until Submit is called again. */ @@ -2282,29 +2240,29 @@ public: /** Returns true if timing data is filled it. Sets oldest timing info if nFramesAgo is larger than the stored history. * Be sure to set timing.size = sizeof(Compositor_FrameTiming) on struct passed in before calling this function. */ - virtual bool GetFrameTiming( Compositor_FrameTiming *pTiming, uint32_t unFramesAgo = 0 ) = 0; + virtual bool GetFrameTiming(Compositor_FrameTiming *pTiming, uint32_t unFramesAgo = 0) = 0; /** Interface for copying a range of timing data. Frames are returned in ascending order (oldest to newest) with the last being the most recent frame. * Only the first entry's m_nSize needs to be set, as the rest will be inferred from that. Returns total number of entries filled out. */ - virtual uint32_t GetFrameTimings( Compositor_FrameTiming *pTiming, uint32_t nFrames ) = 0; + virtual uint32_t GetFrameTimings(Compositor_FrameTiming *pTiming, uint32_t nFrames) = 0; /** Returns the time in seconds left in the current (as identified by FrameTiming's frameIndex) frame. * Due to "running start", this value may roll over to the next frame before ever reaching 0.0. */ virtual float GetFrameTimeRemaining() = 0; /** Fills out stats accumulated for the last connected application. Pass in sizeof( Compositor_CumulativeStats ) as second parameter. */ - virtual void GetCumulativeStats( Compositor_CumulativeStats *pStats, uint32_t nStatsSizeInBytes ) = 0; + virtual void GetCumulativeStats(Compositor_CumulativeStats *pStats, uint32_t nStatsSizeInBytes) = 0; /** Fades the view on the HMD to the specified color. The fade will take fSeconds, and the color values are between * 0.0 and 1.0. This color is faded on top of the scene based on the alpha parameter. Removing the fade color instantly * would be FadeToColor( 0.0, 0.0, 0.0, 0.0, 0.0 ). Values are in un-premultiplied alpha space. */ - virtual void FadeToColor( float fSeconds, float fRed, float fGreen, float fBlue, float fAlpha, bool bBackground = false ) = 0; + virtual void FadeToColor(float fSeconds, float fRed, float fGreen, float fBlue, float fAlpha, bool bBackground = false) = 0; /** Get current fade color value. */ - virtual HmdColor_t GetCurrentFadeColor( bool bBackground = false ) = 0; + virtual HmdColor_t GetCurrentFadeColor(bool bBackground = false) = 0; /** Fading the Grid in or out in fSeconds */ - virtual void FadeGrid( float fSeconds, bool bFadeIn ) = 0; + virtual void FadeGrid(float fSeconds, bool bFadeIn) = 0; /** Get current alpha value of grid. */ virtual float GetCurrentGridAlpha() = 0; @@ -2312,7 +2270,7 @@ public: /** Override the skybox used in the compositor (e.g. for during level loads when the app can't feed scene images fast enough) * Order is Front, Back, Left, Right, Top, Bottom. If only a single texture is passed, it is assumed in lat-long format. * If two are passed, it is assumed a lat-long stereo pair. */ - virtual EVRCompositorError SetSkyboxOverride( VR_ARRAY_COUNT( unTextureCount ) const Texture_t *pTextures, uint32_t unTextureCount ) = 0; + virtual EVRCompositorError SetSkyboxOverride(VR_ARRAY_COUNT(unTextureCount) const Texture_t *pTextures, uint32_t unTextureCount) = 0; /** Resets compositor skybox back to defaults. */ virtual void ClearSkyboxOverride() = 0; @@ -2327,7 +2285,7 @@ public: /** Tells the compositor process to clean up and exit. You do not need to call this function at shutdown. Under normal * circumstances the compositor will manage its own life cycle based on what applications are running. */ virtual void CompositorQuit() = 0; - + /** Return whether the compositor is fullscreen */ virtual bool IsFullscreen() = 0; @@ -2357,34 +2315,34 @@ public: virtual bool ShouldAppRenderWithLowResources() = 0; /** Override interleaved reprojection logic to force on. */ - virtual void ForceInterleavedReprojectionOn( bool bOverride ) = 0; + virtual void ForceInterleavedReprojectionOn(bool bOverride) = 0; /** Force reconnecting to the compositor process. */ virtual void ForceReconnectProcess() = 0; /** Temporarily suspends rendering (useful for finer control over scene transitions). */ - virtual void SuspendRendering( bool bSuspend ) = 0; + virtual void SuspendRendering(bool bSuspend) = 0; /** Opens a shared D3D11 texture with the undistorted composited image for each eye. Use ReleaseMirrorTextureD3D11 when finished * instead of calling Release on the resource itself. */ - virtual vr::EVRCompositorError GetMirrorTextureD3D11( vr::EVREye eEye, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView ) = 0; - virtual void ReleaseMirrorTextureD3D11( void *pD3D11ShaderResourceView ) = 0; + virtual vr::EVRCompositorError GetMirrorTextureD3D11(vr::EVREye eEye, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView) = 0; + virtual void ReleaseMirrorTextureD3D11(void *pD3D11ShaderResourceView) = 0; /** Access to mirror textures from OpenGL. */ - virtual vr::EVRCompositorError GetMirrorTextureGL( vr::EVREye eEye, vr::glUInt_t *pglTextureId, vr::glSharedTextureHandle_t *pglSharedTextureHandle ) = 0; - virtual bool ReleaseSharedGLTexture( vr::glUInt_t glTextureId, vr::glSharedTextureHandle_t glSharedTextureHandle ) = 0; - virtual void LockGLSharedTextureForAccess( vr::glSharedTextureHandle_t glSharedTextureHandle ) = 0; - virtual void UnlockGLSharedTextureForAccess( vr::glSharedTextureHandle_t glSharedTextureHandle ) = 0; + virtual vr::EVRCompositorError GetMirrorTextureGL(vr::EVREye eEye, vr::glUInt_t *pglTextureId, vr::glSharedTextureHandle_t *pglSharedTextureHandle) = 0; + virtual bool ReleaseSharedGLTexture(vr::glUInt_t glTextureId, vr::glSharedTextureHandle_t glSharedTextureHandle) = 0; + virtual void LockGLSharedTextureForAccess(vr::glSharedTextureHandle_t glSharedTextureHandle) = 0; + virtual void UnlockGLSharedTextureForAccess(vr::glSharedTextureHandle_t glSharedTextureHandle) = 0; /** [Vulkan Only] * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. The string will be a space separated list of-required instance extensions to enable in VkCreateInstance */ - virtual uint32_t GetVulkanInstanceExtensionsRequired( VR_OUT_STRING() char *pchValue, uint32_t unBufferSize ) = 0; + virtual uint32_t GetVulkanInstanceExtensionsRequired(VR_OUT_STRING() char *pchValue, uint32_t unBufferSize) = 0; /** [Vulkan only] * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. The string will be a space separated list of required device extensions to enable in VkCreateDevice */ - virtual uint32_t GetVulkanDeviceExtensionsRequired( VkPhysicalDevice_T *pPhysicalDevice, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize ) = 0; + virtual uint32_t GetVulkanDeviceExtensionsRequired(VkPhysicalDevice_T *pPhysicalDevice, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize) = 0; /** [ Vulkan/D3D12 Only ] * There are two purposes for SetExplicitTimingMode: @@ -2404,7 +2362,7 @@ public: * application calls PostPresentHandoff, then WaitGetPoses is guaranteed not to access the queue. Note that PostPresentHandoff * and SubmitExplicitTimingData will access the queue, so only WaitGetPoses becomes safe for accessing the queue from another * thread. */ - virtual void SetExplicitTimingMode( bool bExplicitTimingMode ) = 0; + virtual void SetExplicitTimingMode(bool bExplicitTimingMode) = 0; /** [ Vulkan/D3D12 Only ] * Submit explicit timing data. When SetExplicitTimingMode is true, this must be called immediately before @@ -2415,28 +2373,20 @@ public: virtual EVRCompositorError SubmitExplicitTimingData() = 0; }; -static const char * const IVRCompositor_Version = "IVRCompositor_021"; - -} // namespace vr - +static const char *const IVRCompositor_Version = "IVRCompositor_021"; +} // namespace vr // ivrnotifications.h namespace vr { - -#pragma pack( push, 8 ) +#pragma pack(push, 8) // Used for passing graphic data struct NotificationBitmap_t { NotificationBitmap_t() - : m_pImageData( nullptr ) - , m_nWidth( 0 ) - , m_nHeight( 0 ) - , m_nBytesPerPixel( 0 ) - { - }; + : m_pImageData(nullptr), m_nWidth(0), m_nHeight(0), m_nBytesPerPixel(0){}; void *m_pImageData; int32_t m_nWidth; @@ -2444,7 +2394,6 @@ struct NotificationBitmap_t int32_t m_nBytesPerPixel; }; - /** Be aware that the notification type is used as 'priority' to pick the next notification */ enum EVRNotificationType { @@ -2484,9 +2433,7 @@ static const uint32_t k_unNotificationTextMaxSize = 256; typedef uint32_t VRNotificationId; - - -#pragma pack( pop ) +#pragma pack(pop) /** Allows notification sources to interact with the VR system This current interface is not yet implemented. Do not use yet. */ @@ -2497,267 +2444,261 @@ public: * An overlay handle is required to create a notification, as otherwise it would be impossible for a user to act on it. * To create a two-line notification, use a line break ('\n') to split the text into two lines. * The pImage argument may be NULL, in which case the specified overlay's icon will be used instead. */ - virtual EVRNotificationError CreateNotification( VROverlayHandle_t ulOverlayHandle, uint64_t ulUserValue, EVRNotificationType type, const char *pchText, EVRNotificationStyle style, const NotificationBitmap_t *pImage, /* out */ VRNotificationId *pNotificationId ) = 0; + virtual EVRNotificationError CreateNotification(VROverlayHandle_t ulOverlayHandle, uint64_t ulUserValue, EVRNotificationType type, const char *pchText, EVRNotificationStyle style, const NotificationBitmap_t *pImage, /* out */ VRNotificationId *pNotificationId) = 0; /** Destroy a notification, hiding it first if it currently shown to the user. */ - virtual EVRNotificationError RemoveNotification( VRNotificationId notificationId ) = 0; - + virtual EVRNotificationError RemoveNotification(VRNotificationId notificationId) = 0; }; -static const char * const IVRNotifications_Version = "IVRNotifications_002"; - -} // namespace vr - +static const char *const IVRNotifications_Version = "IVRNotifications_002"; +} // namespace vr // ivroverlay.h namespace vr { +/** The maximum length of an overlay key in bytes, counting the terminating null character. */ +static const uint32_t k_unVROverlayMaxKeyLength = 128; - /** The maximum length of an overlay key in bytes, counting the terminating null character. */ - static const uint32_t k_unVROverlayMaxKeyLength = 128; +/** The maximum length of an overlay name in bytes, counting the terminating null character. */ +static const uint32_t k_unVROverlayMaxNameLength = 128; - /** The maximum length of an overlay name in bytes, counting the terminating null character. */ - static const uint32_t k_unVROverlayMaxNameLength = 128; +/** The maximum number of overlays that can exist in the system at one time. */ +static const uint32_t k_unMaxOverlayCount = 64; - /** The maximum number of overlays that can exist in the system at one time. */ - static const uint32_t k_unMaxOverlayCount = 64; +/** The maximum number of overlay intersection mask primitives per overlay */ +static const uint32_t k_unMaxOverlayIntersectionMaskPrimitivesCount = 32; - /** The maximum number of overlay intersection mask primitives per overlay */ - static const uint32_t k_unMaxOverlayIntersectionMaskPrimitivesCount = 32; +/** Types of input supported by VR Overlays */ +enum VROverlayInputMethod +{ + VROverlayInputMethod_None = 0, // No input events will be generated automatically for this overlay + VROverlayInputMethod_Mouse = 1, // Tracked controllers will get mouse events automatically +}; - /** Types of input supported by VR Overlays */ - enum VROverlayInputMethod - { - VROverlayInputMethod_None = 0, // No input events will be generated automatically for this overlay - VROverlayInputMethod_Mouse = 1, // Tracked controllers will get mouse events automatically - }; +/** Allows the caller to figure out which overlay transform getter to call. */ +enum VROverlayTransformType +{ + VROverlayTransform_Absolute = 0, + VROverlayTransform_TrackedDeviceRelative = 1, + VROverlayTransform_SystemOverlay = 2, + VROverlayTransform_TrackedComponent = 3, +}; - /** Allows the caller to figure out which overlay transform getter to call. */ - enum VROverlayTransformType - { - VROverlayTransform_Absolute = 0, - VROverlayTransform_TrackedDeviceRelative = 1, - VROverlayTransform_SystemOverlay = 2, - VROverlayTransform_TrackedComponent = 3, - }; +/** Overlay control settings */ +enum VROverlayFlags +{ + VROverlayFlags_None = 0, - /** Overlay control settings */ - enum VROverlayFlags - { - VROverlayFlags_None = 0, + // The following only take effect when rendered using the high quality render path (see SetHighQualityOverlay). + VROverlayFlags_Curved = 1, + VROverlayFlags_RGSS4X = 2, - // The following only take effect when rendered using the high quality render path (see SetHighQualityOverlay). - VROverlayFlags_Curved = 1, - VROverlayFlags_RGSS4X = 2, + // Set this flag on a dashboard overlay to prevent a tab from showing up for that overlay + VROverlayFlags_NoDashboardTab = 3, - // Set this flag on a dashboard overlay to prevent a tab from showing up for that overlay - VROverlayFlags_NoDashboardTab = 3, + // Set this flag on a dashboard that is able to deal with gamepad focus events + VROverlayFlags_AcceptsGamepadEvents = 4, - // Set this flag on a dashboard that is able to deal with gamepad focus events - VROverlayFlags_AcceptsGamepadEvents = 4, + // Indicates that the overlay should dim/brighten to show gamepad focus + VROverlayFlags_ShowGamepadFocus = 5, - // Indicates that the overlay should dim/brighten to show gamepad focus - VROverlayFlags_ShowGamepadFocus = 5, + // When in VROverlayInputMethod_Mouse you can optionally enable sending VRScroll_t + VROverlayFlags_SendVRScrollEvents = 6, + VROverlayFlags_SendVRTouchpadEvents = 7, - // When in VROverlayInputMethod_Mouse you can optionally enable sending VRScroll_t - VROverlayFlags_SendVRScrollEvents = 6, - VROverlayFlags_SendVRTouchpadEvents = 7, + // If set this will render a vertical scroll wheel on the primary controller, + // only needed if not using VROverlayFlags_SendVRScrollEvents but you still want to represent a scroll wheel + VROverlayFlags_ShowTouchPadScrollWheel = 8, - // If set this will render a vertical scroll wheel on the primary controller, - // only needed if not using VROverlayFlags_SendVRScrollEvents but you still want to represent a scroll wheel - VROverlayFlags_ShowTouchPadScrollWheel = 8, + // If this is set ownership and render access to the overlay are transferred + // to the new scene process on a call to IVRApplications::LaunchInternalProcess + VROverlayFlags_TransferOwnershipToInternalProcess = 9, - // If this is set ownership and render access to the overlay are transferred - // to the new scene process on a call to IVRApplications::LaunchInternalProcess - VROverlayFlags_TransferOwnershipToInternalProcess = 9, + // If set, renders 50% of the texture in each eye, side by side + VROverlayFlags_SideBySide_Parallel = 10, // Texture is left/right + VROverlayFlags_SideBySide_Crossed = 11, // Texture is crossed and right/left - // If set, renders 50% of the texture in each eye, side by side - VROverlayFlags_SideBySide_Parallel = 10, // Texture is left/right - VROverlayFlags_SideBySide_Crossed = 11, // Texture is crossed and right/left + VROverlayFlags_Panorama = 12, // Texture is a panorama + VROverlayFlags_StereoPanorama = 13, // Texture is a stereo panorama - VROverlayFlags_Panorama = 12, // Texture is a panorama - VROverlayFlags_StereoPanorama = 13, // Texture is a stereo panorama + // If this is set on an overlay owned by the scene application that overlay + // will be sorted with the "Other" overlays on top of all other scene overlays + VROverlayFlags_SortWithNonSceneOverlays = 14, - // If this is set on an overlay owned by the scene application that overlay - // will be sorted with the "Other" overlays on top of all other scene overlays - VROverlayFlags_SortWithNonSceneOverlays = 14, + // If set, the overlay will be shown in the dashboard, otherwise it will be hidden. + VROverlayFlags_VisibleInDashboard = 15, +}; - // If set, the overlay will be shown in the dashboard, otherwise it will be hidden. - VROverlayFlags_VisibleInDashboard = 15, - }; +enum VRMessageOverlayResponse +{ + VRMessageOverlayResponse_ButtonPress_0 = 0, + VRMessageOverlayResponse_ButtonPress_1 = 1, + VRMessageOverlayResponse_ButtonPress_2 = 2, + VRMessageOverlayResponse_ButtonPress_3 = 3, + VRMessageOverlayResponse_CouldntFindSystemOverlay = 4, + VRMessageOverlayResponse_CouldntFindOrCreateClientOverlay = 5, + VRMessageOverlayResponse_ApplicationQuit = 6 +}; - enum VRMessageOverlayResponse - { - VRMessageOverlayResponse_ButtonPress_0 = 0, - VRMessageOverlayResponse_ButtonPress_1 = 1, - VRMessageOverlayResponse_ButtonPress_2 = 2, - VRMessageOverlayResponse_ButtonPress_3 = 3, - VRMessageOverlayResponse_CouldntFindSystemOverlay = 4, - VRMessageOverlayResponse_CouldntFindOrCreateClientOverlay= 5, - VRMessageOverlayResponse_ApplicationQuit = 6 - }; +struct VROverlayIntersectionParams_t +{ + HmdVector3_t vSource; + HmdVector3_t vDirection; + ETrackingUniverseOrigin eOrigin; +}; - struct VROverlayIntersectionParams_t - { - HmdVector3_t vSource; - HmdVector3_t vDirection; - ETrackingUniverseOrigin eOrigin; - }; +struct VROverlayIntersectionResults_t +{ + HmdVector3_t vPoint; + HmdVector3_t vNormal; + HmdVector2_t vUVs; + float fDistance; +}; - struct VROverlayIntersectionResults_t - { - HmdVector3_t vPoint; - HmdVector3_t vNormal; - HmdVector2_t vUVs; - float fDistance; - }; +// Input modes for the Big Picture gamepad text entry +enum EGamepadTextInputMode +{ + k_EGamepadTextInputModeNormal = 0, + k_EGamepadTextInputModePassword = 1, + k_EGamepadTextInputModeSubmit = 2, +}; - // Input modes for the Big Picture gamepad text entry - enum EGamepadTextInputMode - { - k_EGamepadTextInputModeNormal = 0, - k_EGamepadTextInputModePassword = 1, - k_EGamepadTextInputModeSubmit = 2, - }; +// Controls number of allowed lines for the Big Picture gamepad text entry +enum EGamepadTextInputLineMode +{ + k_EGamepadTextInputLineModeSingleLine = 0, + k_EGamepadTextInputLineModeMultipleLines = 1 +}; - // Controls number of allowed lines for the Big Picture gamepad text entry - enum EGamepadTextInputLineMode - { - k_EGamepadTextInputLineModeSingleLine = 0, - k_EGamepadTextInputLineModeMultipleLines = 1 - }; +/** Directions for changing focus between overlays with the gamepad */ +enum EOverlayDirection +{ + OverlayDirection_Up = 0, + OverlayDirection_Down = 1, + OverlayDirection_Left = 2, + OverlayDirection_Right = 3, - /** Directions for changing focus between overlays with the gamepad */ - enum EOverlayDirection - { - OverlayDirection_Up = 0, - OverlayDirection_Down = 1, - OverlayDirection_Left = 2, - OverlayDirection_Right = 3, - - OverlayDirection_Count = 4, - }; + OverlayDirection_Count = 4, +}; - enum EVROverlayIntersectionMaskPrimitiveType - { - OverlayIntersectionPrimitiveType_Rectangle, - OverlayIntersectionPrimitiveType_Circle, - }; +enum EVROverlayIntersectionMaskPrimitiveType +{ + OverlayIntersectionPrimitiveType_Rectangle, + OverlayIntersectionPrimitiveType_Circle, +}; - struct IntersectionMaskRectangle_t - { - float m_flTopLeftX; - float m_flTopLeftY; - float m_flWidth; - float m_flHeight; - }; +struct IntersectionMaskRectangle_t +{ + float m_flTopLeftX; + float m_flTopLeftY; + float m_flWidth; + float m_flHeight; +}; - struct IntersectionMaskCircle_t - { - float m_flCenterX; - float m_flCenterY; - float m_flRadius; - }; +struct IntersectionMaskCircle_t +{ + float m_flCenterX; + float m_flCenterY; + float m_flRadius; +}; - /** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py and openvr_api_flat.h.py */ - typedef union - { - IntersectionMaskRectangle_t m_Rectangle; - IntersectionMaskCircle_t m_Circle; - } VROverlayIntersectionMaskPrimitive_Data_t; +/** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py and openvr_api_flat.h.py */ +typedef union { + IntersectionMaskRectangle_t m_Rectangle; + IntersectionMaskCircle_t m_Circle; +} VROverlayIntersectionMaskPrimitive_Data_t; - struct VROverlayIntersectionMaskPrimitive_t - { - EVROverlayIntersectionMaskPrimitiveType m_nPrimitiveType; - VROverlayIntersectionMaskPrimitive_Data_t m_Primitive; - }; +struct VROverlayIntersectionMaskPrimitive_t +{ + EVROverlayIntersectionMaskPrimitiveType m_nPrimitiveType; + VROverlayIntersectionMaskPrimitive_Data_t m_Primitive; +}; - class IVROverlay - { - public: +class IVROverlay +{ +public: + // --------------------------------------------- + // Overlay management methods + // --------------------------------------------- - // --------------------------------------------- - // Overlay management methods - // --------------------------------------------- + /** Finds an existing overlay with the specified key. */ + virtual EVROverlayError FindOverlay(const char *pchOverlayKey, VROverlayHandle_t *pOverlayHandle) = 0; - /** Finds an existing overlay with the specified key. */ - virtual EVROverlayError FindOverlay( const char *pchOverlayKey, VROverlayHandle_t * pOverlayHandle ) = 0; + /** Creates a new named overlay. All overlays start hidden and with default settings. */ + virtual EVROverlayError CreateOverlay(const char *pchOverlayKey, const char *pchOverlayName, VROverlayHandle_t *pOverlayHandle) = 0; - /** Creates a new named overlay. All overlays start hidden and with default settings. */ - virtual EVROverlayError CreateOverlay( const char *pchOverlayKey, const char *pchOverlayName, VROverlayHandle_t * pOverlayHandle ) = 0; - - /** Destroys the specified overlay. When an application calls VR_Shutdown all overlays created by that app are + /** Destroys the specified overlay. When an application calls VR_Shutdown all overlays created by that app are * automatically destroyed. */ - virtual EVROverlayError DestroyOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + virtual EVROverlayError DestroyOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Specify which overlay to use the high quality render path. This overlay will be composited in during the distortion pass which + /** Specify which overlay to use the high quality render path. This overlay will be composited in during the distortion pass which * results in it drawing on top of everything else, but also at a higher quality as it samples the source texture directly rather than * rasterizing into each eye's render texture first. Because if this, only one of these is supported at any given time. It is most useful * for overlays that are expected to take up most of the user's view (e.g. streaming video). * This mode does not support mouse input to your overlay. */ - virtual EVROverlayError SetHighQualityOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + virtual EVROverlayError SetHighQualityOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Returns the overlay handle of the current overlay being rendered using the single high quality overlay render path. + /** Returns the overlay handle of the current overlay being rendered using the single high quality overlay render path. * Otherwise it will return k_ulOverlayHandleInvalid. */ - virtual vr::VROverlayHandle_t GetHighQualityOverlay() = 0; + virtual vr::VROverlayHandle_t GetHighQualityOverlay() = 0; - /** Fills the provided buffer with the string key of the overlay. Returns the size of buffer required to store the key, including + /** Fills the provided buffer with the string key of the overlay. Returns the size of buffer required to store the key, including * the terminating null character. k_unVROverlayMaxKeyLength will be enough bytes to fit the string. */ - virtual uint32_t GetOverlayKey( VROverlayHandle_t ulOverlayHandle, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, EVROverlayError *pError = 0L ) = 0; + virtual uint32_t GetOverlayKey(VROverlayHandle_t ulOverlayHandle, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, EVROverlayError *pError = 0L) = 0; - /** Fills the provided buffer with the friendly name of the overlay. Returns the size of buffer required to store the key, including + /** Fills the provided buffer with the friendly name of the overlay. Returns the size of buffer required to store the key, including * the terminating null character. k_unVROverlayMaxNameLength will be enough bytes to fit the string. */ - virtual uint32_t GetOverlayName( VROverlayHandle_t ulOverlayHandle, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, EVROverlayError *pError = 0L ) = 0; + virtual uint32_t GetOverlayName(VROverlayHandle_t ulOverlayHandle, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, EVROverlayError *pError = 0L) = 0; - /** set the name to use for this overlay */ - virtual EVROverlayError SetOverlayName( VROverlayHandle_t ulOverlayHandle, const char *pchName ) = 0; + /** set the name to use for this overlay */ + virtual EVROverlayError SetOverlayName(VROverlayHandle_t ulOverlayHandle, const char *pchName) = 0; - /** Gets the raw image data from an overlay. Overlay image data is always returned as RGBA data, 4 bytes per pixel. If the buffer is not large enough, width and height + /** Gets the raw image data from an overlay. Overlay image data is always returned as RGBA data, 4 bytes per pixel. If the buffer is not large enough, width and height * will be set and VROverlayError_ArrayTooSmall is returned. */ - virtual EVROverlayError GetOverlayImageData( VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unBufferSize, uint32_t *punWidth, uint32_t *punHeight ) = 0; + virtual EVROverlayError GetOverlayImageData(VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unBufferSize, uint32_t *punWidth, uint32_t *punHeight) = 0; - /** returns a string that corresponds with the specified overlay error. The string will be the name + /** returns a string that corresponds with the specified overlay error. The string will be the name * of the error enum value for all valid error codes */ - virtual const char *GetOverlayErrorNameFromEnum( EVROverlayError error ) = 0; + virtual const char *GetOverlayErrorNameFromEnum(EVROverlayError error) = 0; - // --------------------------------------------- - // Overlay rendering methods - // --------------------------------------------- + // --------------------------------------------- + // Overlay rendering methods + // --------------------------------------------- - /** Sets the pid that is allowed to render to this overlay (the creator pid is always allow to render), + /** Sets the pid that is allowed to render to this overlay (the creator pid is always allow to render), * by default this is the pid of the process that made the overlay */ - virtual EVROverlayError SetOverlayRenderingPid( VROverlayHandle_t ulOverlayHandle, uint32_t unPID ) = 0; + virtual EVROverlayError SetOverlayRenderingPid(VROverlayHandle_t ulOverlayHandle, uint32_t unPID) = 0; - /** Gets the pid that is allowed to render to this overlay */ - virtual uint32_t GetOverlayRenderingPid( VROverlayHandle_t ulOverlayHandle ) = 0; + /** Gets the pid that is allowed to render to this overlay */ + virtual uint32_t GetOverlayRenderingPid(VROverlayHandle_t ulOverlayHandle) = 0; - /** Specify flag setting for a given overlay */ - virtual EVROverlayError SetOverlayFlag( VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool bEnabled ) = 0; + /** Specify flag setting for a given overlay */ + virtual EVROverlayError SetOverlayFlag(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool bEnabled) = 0; - /** Sets flag setting for a given overlay */ - virtual EVROverlayError GetOverlayFlag( VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool *pbEnabled ) = 0; + /** Sets flag setting for a given overlay */ + virtual EVROverlayError GetOverlayFlag(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool *pbEnabled) = 0; - /** Sets the color tint of the overlay quad. Use 0.0 to 1.0 per channel. */ - virtual EVROverlayError SetOverlayColor( VROverlayHandle_t ulOverlayHandle, float fRed, float fGreen, float fBlue ) = 0; + /** Sets the color tint of the overlay quad. Use 0.0 to 1.0 per channel. */ + virtual EVROverlayError SetOverlayColor(VROverlayHandle_t ulOverlayHandle, float fRed, float fGreen, float fBlue) = 0; - /** Gets the color tint of the overlay quad. */ - virtual EVROverlayError GetOverlayColor( VROverlayHandle_t ulOverlayHandle, float *pfRed, float *pfGreen, float *pfBlue ) = 0; + /** Gets the color tint of the overlay quad. */ + virtual EVROverlayError GetOverlayColor(VROverlayHandle_t ulOverlayHandle, float *pfRed, float *pfGreen, float *pfBlue) = 0; - /** Sets the alpha of the overlay quad. Use 1.0 for 100 percent opacity to 0.0 for 0 percent opacity. */ - virtual EVROverlayError SetOverlayAlpha( VROverlayHandle_t ulOverlayHandle, float fAlpha ) = 0; + /** Sets the alpha of the overlay quad. Use 1.0 for 100 percent opacity to 0.0 for 0 percent opacity. */ + virtual EVROverlayError SetOverlayAlpha(VROverlayHandle_t ulOverlayHandle, float fAlpha) = 0; - /** Gets the alpha of the overlay quad. By default overlays are rendering at 100 percent alpha (1.0). */ - virtual EVROverlayError GetOverlayAlpha( VROverlayHandle_t ulOverlayHandle, float *pfAlpha ) = 0; + /** Gets the alpha of the overlay quad. By default overlays are rendering at 100 percent alpha (1.0). */ + virtual EVROverlayError GetOverlayAlpha(VROverlayHandle_t ulOverlayHandle, float *pfAlpha) = 0; - /** Sets the aspect ratio of the texels in the overlay. 1.0 means the texels are square. 2.0 means the texels + /** Sets the aspect ratio of the texels in the overlay. 1.0 means the texels are square. 2.0 means the texels * are twice as wide as they are tall. Defaults to 1.0. */ - virtual EVROverlayError SetOverlayTexelAspect( VROverlayHandle_t ulOverlayHandle, float fTexelAspect ) = 0; + virtual EVROverlayError SetOverlayTexelAspect(VROverlayHandle_t ulOverlayHandle, float fTexelAspect) = 0; - /** Gets the aspect ratio of the texels in the overlay. Defaults to 1.0 */ - virtual EVROverlayError GetOverlayTexelAspect( VROverlayHandle_t ulOverlayHandle, float *pfTexelAspect ) = 0; + /** Gets the aspect ratio of the texels in the overlay. Defaults to 1.0 */ + virtual EVROverlayError GetOverlayTexelAspect(VROverlayHandle_t ulOverlayHandle, float *pfTexelAspect) = 0; - /** Sets the rendering sort order for the overlay. Overlays are rendered this order: + /** Sets the rendering sort order for the overlay. Overlays are rendered this order: * Overlays owned by the scene application * Overlays owned by some other application * @@ -2765,160 +2706,160 @@ namespace vr * sort order are rendered back to front base on distance from the HMD. * * Sort order defaults to 0. */ - virtual EVROverlayError SetOverlaySortOrder( VROverlayHandle_t ulOverlayHandle, uint32_t unSortOrder ) = 0; + virtual EVROverlayError SetOverlaySortOrder(VROverlayHandle_t ulOverlayHandle, uint32_t unSortOrder) = 0; - /** Gets the sort order of the overlay. See SetOverlaySortOrder for how this works. */ - virtual EVROverlayError GetOverlaySortOrder( VROverlayHandle_t ulOverlayHandle, uint32_t *punSortOrder ) = 0; + /** Gets the sort order of the overlay. See SetOverlaySortOrder for how this works. */ + virtual EVROverlayError GetOverlaySortOrder(VROverlayHandle_t ulOverlayHandle, uint32_t *punSortOrder) = 0; - /** Sets the width of the overlay quad in meters. By default overlays are rendered on a quad that is 1 meter across */ - virtual EVROverlayError SetOverlayWidthInMeters( VROverlayHandle_t ulOverlayHandle, float fWidthInMeters ) = 0; + /** Sets the width of the overlay quad in meters. By default overlays are rendered on a quad that is 1 meter across */ + virtual EVROverlayError SetOverlayWidthInMeters(VROverlayHandle_t ulOverlayHandle, float fWidthInMeters) = 0; - /** Returns the width of the overlay quad in meters. By default overlays are rendered on a quad that is 1 meter across */ - virtual EVROverlayError GetOverlayWidthInMeters( VROverlayHandle_t ulOverlayHandle, float *pfWidthInMeters ) = 0; + /** Returns the width of the overlay quad in meters. By default overlays are rendered on a quad that is 1 meter across */ + virtual EVROverlayError GetOverlayWidthInMeters(VROverlayHandle_t ulOverlayHandle, float *pfWidthInMeters) = 0; - /** For high-quality curved overlays only, sets the distance range in meters from the overlay used to automatically curve + /** For high-quality curved overlays only, sets the distance range in meters from the overlay used to automatically curve * the surface around the viewer. Min is distance is when the surface will be most curved. Max is when least curved. */ - virtual EVROverlayError SetOverlayAutoCurveDistanceRangeInMeters( VROverlayHandle_t ulOverlayHandle, float fMinDistanceInMeters, float fMaxDistanceInMeters ) = 0; + virtual EVROverlayError SetOverlayAutoCurveDistanceRangeInMeters(VROverlayHandle_t ulOverlayHandle, float fMinDistanceInMeters, float fMaxDistanceInMeters) = 0; - /** For high-quality curved overlays only, gets the distance range in meters from the overlay used to automatically curve + /** For high-quality curved overlays only, gets the distance range in meters from the overlay used to automatically curve * the surface around the viewer. Min is distance is when the surface will be most curved. Max is when least curved. */ - virtual EVROverlayError GetOverlayAutoCurveDistanceRangeInMeters( VROverlayHandle_t ulOverlayHandle, float *pfMinDistanceInMeters, float *pfMaxDistanceInMeters ) = 0; + virtual EVROverlayError GetOverlayAutoCurveDistanceRangeInMeters(VROverlayHandle_t ulOverlayHandle, float *pfMinDistanceInMeters, float *pfMaxDistanceInMeters) = 0; - /** Sets the colorspace the overlay texture's data is in. Defaults to 'auto'. + /** Sets the colorspace the overlay texture's data is in. Defaults to 'auto'. * If the texture needs to be resolved, you should call SetOverlayTexture with the appropriate colorspace instead. */ - virtual EVROverlayError SetOverlayTextureColorSpace( VROverlayHandle_t ulOverlayHandle, EColorSpace eTextureColorSpace ) = 0; + virtual EVROverlayError SetOverlayTextureColorSpace(VROverlayHandle_t ulOverlayHandle, EColorSpace eTextureColorSpace) = 0; - /** Gets the overlay's current colorspace setting. */ - virtual EVROverlayError GetOverlayTextureColorSpace( VROverlayHandle_t ulOverlayHandle, EColorSpace *peTextureColorSpace ) = 0; + /** Gets the overlay's current colorspace setting. */ + virtual EVROverlayError GetOverlayTextureColorSpace(VROverlayHandle_t ulOverlayHandle, EColorSpace *peTextureColorSpace) = 0; - /** Sets the part of the texture to use for the overlay. UV Min is the upper left corner and UV Max is the lower right corner. */ - virtual EVROverlayError SetOverlayTextureBounds( VROverlayHandle_t ulOverlayHandle, const VRTextureBounds_t *pOverlayTextureBounds ) = 0; + /** Sets the part of the texture to use for the overlay. UV Min is the upper left corner and UV Max is the lower right corner. */ + virtual EVROverlayError SetOverlayTextureBounds(VROverlayHandle_t ulOverlayHandle, const VRTextureBounds_t *pOverlayTextureBounds) = 0; - /** Gets the part of the texture to use for the overlay. UV Min is the upper left corner and UV Max is the lower right corner. */ - virtual EVROverlayError GetOverlayTextureBounds( VROverlayHandle_t ulOverlayHandle, VRTextureBounds_t *pOverlayTextureBounds ) = 0; + /** Gets the part of the texture to use for the overlay. UV Min is the upper left corner and UV Max is the lower right corner. */ + virtual EVROverlayError GetOverlayTextureBounds(VROverlayHandle_t ulOverlayHandle, VRTextureBounds_t *pOverlayTextureBounds) = 0; - /** Gets render model to draw behind this overlay */ - virtual uint32_t GetOverlayRenderModel( vr::VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, HmdColor_t *pColor, vr::EVROverlayError *pError ) = 0; + /** Gets render model to draw behind this overlay */ + virtual uint32_t GetOverlayRenderModel(vr::VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, HmdColor_t *pColor, vr::EVROverlayError *pError) = 0; - /** Sets render model to draw behind this overlay and the vertex color to use, pass null for pColor to match the overlays vertex color. + /** Sets render model to draw behind this overlay and the vertex color to use, pass null for pColor to match the overlays vertex color. The model is scaled by the same amount as the overlay, with a default of 1m. */ - virtual vr::EVROverlayError SetOverlayRenderModel( vr::VROverlayHandle_t ulOverlayHandle, const char *pchRenderModel, const HmdColor_t *pColor ) = 0; + virtual vr::EVROverlayError SetOverlayRenderModel(vr::VROverlayHandle_t ulOverlayHandle, const char *pchRenderModel, const HmdColor_t *pColor) = 0; - /** Returns the transform type of this overlay. */ - virtual EVROverlayError GetOverlayTransformType( VROverlayHandle_t ulOverlayHandle, VROverlayTransformType *peTransformType ) = 0; + /** Returns the transform type of this overlay. */ + virtual EVROverlayError GetOverlayTransformType(VROverlayHandle_t ulOverlayHandle, VROverlayTransformType *peTransformType) = 0; - /** Sets the transform to absolute tracking origin. */ - virtual EVROverlayError SetOverlayTransformAbsolute( VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, const HmdMatrix34_t *pmatTrackingOriginToOverlayTransform ) = 0; + /** Sets the transform to absolute tracking origin. */ + virtual EVROverlayError SetOverlayTransformAbsolute(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, const HmdMatrix34_t *pmatTrackingOriginToOverlayTransform) = 0; - /** Gets the transform if it is absolute. Returns an error if the transform is some other type. */ - virtual EVROverlayError GetOverlayTransformAbsolute( VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin *peTrackingOrigin, HmdMatrix34_t *pmatTrackingOriginToOverlayTransform ) = 0; + /** Gets the transform if it is absolute. Returns an error if the transform is some other type. */ + virtual EVROverlayError GetOverlayTransformAbsolute(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin *peTrackingOrigin, HmdMatrix34_t *pmatTrackingOriginToOverlayTransform) = 0; - /** Sets the transform to relative to the transform of the specified tracked device. */ - virtual EVROverlayError SetOverlayTransformTrackedDeviceRelative( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unTrackedDevice, const HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform ) = 0; + /** Sets the transform to relative to the transform of the specified tracked device. */ + virtual EVROverlayError SetOverlayTransformTrackedDeviceRelative(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unTrackedDevice, const HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform) = 0; - /** Gets the transform if it is relative to a tracked device. Returns an error if the transform is some other type. */ - virtual EVROverlayError GetOverlayTransformTrackedDeviceRelative( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punTrackedDevice, HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform ) = 0; + /** Gets the transform if it is relative to a tracked device. Returns an error if the transform is some other type. */ + virtual EVROverlayError GetOverlayTransformTrackedDeviceRelative(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punTrackedDevice, HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform) = 0; - /** Sets the transform to draw the overlay on a rendermodel component mesh instead of a quad. This will only draw when the system is + /** Sets the transform to draw the overlay on a rendermodel component mesh instead of a quad. This will only draw when the system is * drawing the device. Overlays with this transform type cannot receive mouse events. */ - virtual EVROverlayError SetOverlayTransformTrackedDeviceComponent( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unDeviceIndex, const char *pchComponentName ) = 0; + virtual EVROverlayError SetOverlayTransformTrackedDeviceComponent(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unDeviceIndex, const char *pchComponentName) = 0; - /** Gets the transform information when the overlay is rendering on a component. */ - virtual EVROverlayError GetOverlayTransformTrackedDeviceComponent( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punDeviceIndex, char *pchComponentName, uint32_t unComponentNameSize ) = 0; + /** Gets the transform information when the overlay is rendering on a component. */ + virtual EVROverlayError GetOverlayTransformTrackedDeviceComponent(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punDeviceIndex, char *pchComponentName, uint32_t unComponentNameSize) = 0; - /** Gets the transform if it is relative to another overlay. Returns an error if the transform is some other type. */ - virtual vr::EVROverlayError GetOverlayTransformOverlayRelative( VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t *ulOverlayHandleParent, HmdMatrix34_t *pmatParentOverlayToOverlayTransform ) = 0; - - /** Sets the transform to relative to the transform of the specified overlay. This overlays visibility will also track the parents visibility */ - virtual vr::EVROverlayError SetOverlayTransformOverlayRelative( VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t ulOverlayHandleParent, const HmdMatrix34_t *pmatParentOverlayToOverlayTransform ) = 0; + /** Gets the transform if it is relative to another overlay. Returns an error if the transform is some other type. */ + virtual vr::EVROverlayError GetOverlayTransformOverlayRelative(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t *ulOverlayHandleParent, HmdMatrix34_t *pmatParentOverlayToOverlayTransform) = 0; - /** Shows the VR overlay. For dashboard overlays, only the Dashboard Manager is allowed to call this. */ - virtual EVROverlayError ShowOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + /** Sets the transform to relative to the transform of the specified overlay. This overlays visibility will also track the parents visibility */ + virtual vr::EVROverlayError SetOverlayTransformOverlayRelative(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t ulOverlayHandleParent, const HmdMatrix34_t *pmatParentOverlayToOverlayTransform) = 0; - /** Hides the VR overlay. For dashboard overlays, only the Dashboard Manager is allowed to call this. */ - virtual EVROverlayError HideOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + /** Shows the VR overlay. For dashboard overlays, only the Dashboard Manager is allowed to call this. */ + virtual EVROverlayError ShowOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Returns true if the overlay is visible. */ - virtual bool IsOverlayVisible( VROverlayHandle_t ulOverlayHandle ) = 0; + /** Hides the VR overlay. For dashboard overlays, only the Dashboard Manager is allowed to call this. */ + virtual EVROverlayError HideOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Get the transform in 3d space associated with a specific 2d point in the overlay's coordinate space (where 0,0 is the lower left). -Z points out of the overlay */ - virtual EVROverlayError GetTransformForOverlayCoordinates( VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, HmdVector2_t coordinatesInOverlay, HmdMatrix34_t *pmatTransform ) = 0; + /** Returns true if the overlay is visible. */ + virtual bool IsOverlayVisible(VROverlayHandle_t ulOverlayHandle) = 0; - // --------------------------------------------- - // Overlay input methods - // --------------------------------------------- + /** Get the transform in 3d space associated with a specific 2d point in the overlay's coordinate space (where 0,0 is the lower left). -Z points out of the overlay */ + virtual EVROverlayError GetTransformForOverlayCoordinates(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, HmdVector2_t coordinatesInOverlay, HmdMatrix34_t *pmatTransform) = 0; - /** Returns true and fills the event with the next event on the overlay's event queue, if there is one. + // --------------------------------------------- + // Overlay input methods + // --------------------------------------------- + + /** Returns true and fills the event with the next event on the overlay's event queue, if there is one. * If there are no events this method returns false. uncbVREvent should be the size in bytes of the VREvent_t struct */ - virtual bool PollNextOverlayEvent( VROverlayHandle_t ulOverlayHandle, VREvent_t *pEvent, uint32_t uncbVREvent ) = 0; + virtual bool PollNextOverlayEvent(VROverlayHandle_t ulOverlayHandle, VREvent_t *pEvent, uint32_t uncbVREvent) = 0; - /** Returns the current input settings for the specified overlay. */ - virtual EVROverlayError GetOverlayInputMethod( VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod *peInputMethod ) = 0; + /** Returns the current input settings for the specified overlay. */ + virtual EVROverlayError GetOverlayInputMethod(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod *peInputMethod) = 0; - /** Sets the input settings for the specified overlay. */ - virtual EVROverlayError SetOverlayInputMethod( VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod eInputMethod ) = 0; + /** Sets the input settings for the specified overlay. */ + virtual EVROverlayError SetOverlayInputMethod(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod eInputMethod) = 0; - /** Gets the mouse scaling factor that is used for mouse events. The actual texture may be a different size, but this is + /** Gets the mouse scaling factor that is used for mouse events. The actual texture may be a different size, but this is * typically the size of the underlying UI in pixels. */ - virtual EVROverlayError GetOverlayMouseScale( VROverlayHandle_t ulOverlayHandle, HmdVector2_t *pvecMouseScale ) = 0; + virtual EVROverlayError GetOverlayMouseScale(VROverlayHandle_t ulOverlayHandle, HmdVector2_t *pvecMouseScale) = 0; - /** Sets the mouse scaling factor that is used for mouse events. The actual texture may be a different size, but this is + /** Sets the mouse scaling factor that is used for mouse events. The actual texture may be a different size, but this is * typically the size of the underlying UI in pixels (not in world space). */ - virtual EVROverlayError SetOverlayMouseScale( VROverlayHandle_t ulOverlayHandle, const HmdVector2_t *pvecMouseScale ) = 0; + virtual EVROverlayError SetOverlayMouseScale(VROverlayHandle_t ulOverlayHandle, const HmdVector2_t *pvecMouseScale) = 0; - /** Computes the overlay-space pixel coordinates of where the ray intersects the overlay with the + /** Computes the overlay-space pixel coordinates of where the ray intersects the overlay with the * specified settings. Returns false if there is no intersection. */ - virtual bool ComputeOverlayIntersection( VROverlayHandle_t ulOverlayHandle, const VROverlayIntersectionParams_t *pParams, VROverlayIntersectionResults_t *pResults ) = 0; + virtual bool ComputeOverlayIntersection(VROverlayHandle_t ulOverlayHandle, const VROverlayIntersectionParams_t *pParams, VROverlayIntersectionResults_t *pResults) = 0; - /** Processes mouse input from the specified controller as though it were a mouse pointed at a compositor overlay with the + /** Processes mouse input from the specified controller as though it were a mouse pointed at a compositor overlay with the * specified settings. The controller is treated like a laser pointer on the -z axis. The point where the laser pointer would * intersect with the overlay is the mouse position, the trigger is left mouse, and the track pad is right mouse. * * Return true if the controller is pointed at the overlay and an event was generated. */ - virtual bool HandleControllerOverlayInteractionAsMouse( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unControllerDeviceIndex ) = 0; + virtual bool HandleControllerOverlayInteractionAsMouse(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unControllerDeviceIndex) = 0; - /** Returns true if the specified overlay is the hover target. An overlay is the hover target when it is the last overlay "moused over" + /** Returns true if the specified overlay is the hover target. An overlay is the hover target when it is the last overlay "moused over" * by the virtual mouse pointer */ - virtual bool IsHoverTargetOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + virtual bool IsHoverTargetOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Returns the current Gamepad focus overlay */ - virtual vr::VROverlayHandle_t GetGamepadFocusOverlay() = 0; + /** Returns the current Gamepad focus overlay */ + virtual vr::VROverlayHandle_t GetGamepadFocusOverlay() = 0; - /** Sets the current Gamepad focus overlay */ - virtual EVROverlayError SetGamepadFocusOverlay( VROverlayHandle_t ulNewFocusOverlay ) = 0; + /** Sets the current Gamepad focus overlay */ + virtual EVROverlayError SetGamepadFocusOverlay(VROverlayHandle_t ulNewFocusOverlay) = 0; - /** Sets an overlay's neighbor. This will also set the neighbor of the "to" overlay + /** Sets an overlay's neighbor. This will also set the neighbor of the "to" overlay * to point back to the "from" overlay. If an overlay's neighbor is set to invalid both * ends will be cleared */ - virtual EVROverlayError SetOverlayNeighbor( EOverlayDirection eDirection, VROverlayHandle_t ulFrom, VROverlayHandle_t ulTo ) = 0; + virtual EVROverlayError SetOverlayNeighbor(EOverlayDirection eDirection, VROverlayHandle_t ulFrom, VROverlayHandle_t ulTo) = 0; - /** Changes the Gamepad focus from one overlay to one of its neighbors. Returns VROverlayError_NoNeighbor if there is no + /** Changes the Gamepad focus from one overlay to one of its neighbors. Returns VROverlayError_NoNeighbor if there is no * neighbor in that direction */ - virtual EVROverlayError MoveGamepadFocusToNeighbor( EOverlayDirection eDirection, VROverlayHandle_t ulFrom ) = 0; + virtual EVROverlayError MoveGamepadFocusToNeighbor(EOverlayDirection eDirection, VROverlayHandle_t ulFrom) = 0; - // --------------------------------------------- - // Overlay texture methods - // --------------------------------------------- + // --------------------------------------------- + // Overlay texture methods + // --------------------------------------------- - /** Texture to draw for the overlay. This function can only be called by the overlay's creator or renderer process (see SetOverlayRenderingPid) . + /** Texture to draw for the overlay. This function can only be called by the overlay's creator or renderer process (see SetOverlayRenderingPid) . * * OpenGL dirty state: * glBindTexture */ - virtual EVROverlayError SetOverlayTexture( VROverlayHandle_t ulOverlayHandle, const Texture_t *pTexture ) = 0; + virtual EVROverlayError SetOverlayTexture(VROverlayHandle_t ulOverlayHandle, const Texture_t *pTexture) = 0; - /** Use this to tell the overlay system to release the texture set for this overlay. */ - virtual EVROverlayError ClearOverlayTexture( VROverlayHandle_t ulOverlayHandle ) = 0; + /** Use this to tell the overlay system to release the texture set for this overlay. */ + virtual EVROverlayError ClearOverlayTexture(VROverlayHandle_t ulOverlayHandle) = 0; - /** Separate interface for providing the data as a stream of bytes, but there is an upper bound on data + /** Separate interface for providing the data as a stream of bytes, but there is an upper bound on data * that can be sent. This function can only be called by the overlay's renderer process. */ - virtual EVROverlayError SetOverlayRaw( VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unWidth, uint32_t unHeight, uint32_t unDepth ) = 0; + virtual EVROverlayError SetOverlayRaw(VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unWidth, uint32_t unHeight, uint32_t unDepth) = 0; - /** Separate interface for providing the image through a filename: can be png or jpg, and should not be bigger than 1920x1080. + /** Separate interface for providing the image through a filename: can be png or jpg, and should not be bigger than 1920x1080. * This function can only be called by the overlay's renderer process */ - virtual EVROverlayError SetOverlayFromFile( VROverlayHandle_t ulOverlayHandle, const char *pchFilePath ) = 0; + virtual EVROverlayError SetOverlayFromFile(VROverlayHandle_t ulOverlayHandle, const char *pchFilePath) = 0; - /** Get the native texture handle/device for an overlay you have created. + /** Get the native texture handle/device for an overlay you have created. * On windows this handle will be a ID3D11ShaderResourceView with a ID3D11Texture2D bound. * * The texture will always be sized to match the backing texture you supplied in SetOverlayTexture above. @@ -2928,98 +2869,97 @@ namespace vr * pNativeTextureHandle is an OUTPUT, it will be a pointer to a ID3D11ShaderResourceView *. * pNativeTextureRef is an INPUT and should be a ID3D11Resource *. The device used by pNativeTextureRef will be used to bind pNativeTextureHandle. */ - virtual EVROverlayError GetOverlayTexture( VROverlayHandle_t ulOverlayHandle, void **pNativeTextureHandle, void *pNativeTextureRef, uint32_t *pWidth, uint32_t *pHeight, uint32_t *pNativeFormat, ETextureType *pAPIType, EColorSpace *pColorSpace, VRTextureBounds_t *pTextureBounds ) = 0; + virtual EVROverlayError GetOverlayTexture(VROverlayHandle_t ulOverlayHandle, void **pNativeTextureHandle, void *pNativeTextureRef, uint32_t *pWidth, uint32_t *pHeight, uint32_t *pNativeFormat, ETextureType *pAPIType, EColorSpace *pColorSpace, VRTextureBounds_t *pTextureBounds) = 0; - /** Release the pNativeTextureHandle provided from the GetOverlayTexture call, this allows the system to free the underlying GPU resources for this object, + /** Release the pNativeTextureHandle provided from the GetOverlayTexture call, this allows the system to free the underlying GPU resources for this object, * so only do it once you stop rendering this texture. */ - virtual EVROverlayError ReleaseNativeOverlayHandle( VROverlayHandle_t ulOverlayHandle, void *pNativeTextureHandle ) = 0; + virtual EVROverlayError ReleaseNativeOverlayHandle(VROverlayHandle_t ulOverlayHandle, void *pNativeTextureHandle) = 0; - /** Get the size of the overlay texture */ - virtual EVROverlayError GetOverlayTextureSize( VROverlayHandle_t ulOverlayHandle, uint32_t *pWidth, uint32_t *pHeight ) = 0; + /** Get the size of the overlay texture */ + virtual EVROverlayError GetOverlayTextureSize(VROverlayHandle_t ulOverlayHandle, uint32_t *pWidth, uint32_t *pHeight) = 0; - // ---------------------------------------------- - // Dashboard Overlay Methods - // ---------------------------------------------- + // ---------------------------------------------- + // Dashboard Overlay Methods + // ---------------------------------------------- - /** Creates a dashboard overlay and returns its handle */ - virtual EVROverlayError CreateDashboardOverlay( const char *pchOverlayKey, const char *pchOverlayFriendlyName, VROverlayHandle_t * pMainHandle, VROverlayHandle_t *pThumbnailHandle ) = 0; + /** Creates a dashboard overlay and returns its handle */ + virtual EVROverlayError CreateDashboardOverlay(const char *pchOverlayKey, const char *pchOverlayFriendlyName, VROverlayHandle_t *pMainHandle, VROverlayHandle_t *pThumbnailHandle) = 0; - /** Returns true if the dashboard is visible */ - virtual bool IsDashboardVisible() = 0; + /** Returns true if the dashboard is visible */ + virtual bool IsDashboardVisible() = 0; - /** returns true if the dashboard is visible and the specified overlay is the active system Overlay */ - virtual bool IsActiveDashboardOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + /** returns true if the dashboard is visible and the specified overlay is the active system Overlay */ + virtual bool IsActiveDashboardOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Sets the dashboard overlay to only appear when the specified process ID has scene focus */ - virtual EVROverlayError SetDashboardOverlaySceneProcess( VROverlayHandle_t ulOverlayHandle, uint32_t unProcessId ) = 0; + /** Sets the dashboard overlay to only appear when the specified process ID has scene focus */ + virtual EVROverlayError SetDashboardOverlaySceneProcess(VROverlayHandle_t ulOverlayHandle, uint32_t unProcessId) = 0; - /** Gets the process ID that this dashboard overlay requires to have scene focus */ - virtual EVROverlayError GetDashboardOverlaySceneProcess( VROverlayHandle_t ulOverlayHandle, uint32_t *punProcessId ) = 0; + /** Gets the process ID that this dashboard overlay requires to have scene focus */ + virtual EVROverlayError GetDashboardOverlaySceneProcess(VROverlayHandle_t ulOverlayHandle, uint32_t *punProcessId) = 0; - /** Shows the dashboard. */ - virtual void ShowDashboard( const char *pchOverlayToShow ) = 0; + /** Shows the dashboard. */ + virtual void ShowDashboard(const char *pchOverlayToShow) = 0; - /** Returns the tracked device that has the laser pointer in the dashboard */ - virtual vr::TrackedDeviceIndex_t GetPrimaryDashboardDevice() = 0; + /** Returns the tracked device that has the laser pointer in the dashboard */ + virtual vr::TrackedDeviceIndex_t GetPrimaryDashboardDevice() = 0; - // --------------------------------------------- - // Keyboard methods - // --------------------------------------------- - - /** Show the virtual keyboard to accept input **/ - virtual EVROverlayError ShowKeyboard( EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32_t unCharMax, const char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue ) = 0; + // --------------------------------------------- + // Keyboard methods + // --------------------------------------------- - virtual EVROverlayError ShowKeyboardForOverlay( VROverlayHandle_t ulOverlayHandle, EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32_t unCharMax, const char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue ) = 0; + /** Show the virtual keyboard to accept input **/ + virtual EVROverlayError ShowKeyboard(EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32_t unCharMax, const char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue) = 0; - /** Get the text that was entered into the text input **/ - virtual uint32_t GetKeyboardText( VR_OUT_STRING() char *pchText, uint32_t cchText ) = 0; + virtual EVROverlayError ShowKeyboardForOverlay(VROverlayHandle_t ulOverlayHandle, EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32_t unCharMax, const char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue) = 0; - /** Hide the virtual keyboard **/ - virtual void HideKeyboard() = 0; + /** Get the text that was entered into the text input **/ + virtual uint32_t GetKeyboardText(VR_OUT_STRING() char *pchText, uint32_t cchText) = 0; - /** Set the position of the keyboard in world space **/ - virtual void SetKeyboardTransformAbsolute( ETrackingUniverseOrigin eTrackingOrigin, const HmdMatrix34_t *pmatTrackingOriginToKeyboardTransform ) = 0; + /** Hide the virtual keyboard **/ + virtual void HideKeyboard() = 0; - /** Set the position of the keyboard in overlay space by telling it to avoid a rectangle in the overlay. Rectangle coords have (0,0) in the bottom left **/ - virtual void SetKeyboardPositionForOverlay( VROverlayHandle_t ulOverlayHandle, HmdRect2_t avoidRect ) = 0; + /** Set the position of the keyboard in world space **/ + virtual void SetKeyboardTransformAbsolute(ETrackingUniverseOrigin eTrackingOrigin, const HmdMatrix34_t *pmatTrackingOriginToKeyboardTransform) = 0; - // --------------------------------------------- - // Overlay input methods - // --------------------------------------------- + /** Set the position of the keyboard in overlay space by telling it to avoid a rectangle in the overlay. Rectangle coords have (0,0) in the bottom left **/ + virtual void SetKeyboardPositionForOverlay(VROverlayHandle_t ulOverlayHandle, HmdRect2_t avoidRect) = 0; - /** Sets a list of primitives to be used for controller ray intersection + // --------------------------------------------- + // Overlay input methods + // --------------------------------------------- + + /** Sets a list of primitives to be used for controller ray intersection * typically the size of the underlying UI in pixels (not in world space). */ - virtual EVROverlayError SetOverlayIntersectionMask( VROverlayHandle_t ulOverlayHandle, VROverlayIntersectionMaskPrimitive_t *pMaskPrimitives, uint32_t unNumMaskPrimitives, uint32_t unPrimitiveSize = sizeof( VROverlayIntersectionMaskPrimitive_t ) ) = 0; + virtual EVROverlayError SetOverlayIntersectionMask(VROverlayHandle_t ulOverlayHandle, VROverlayIntersectionMaskPrimitive_t *pMaskPrimitives, uint32_t unNumMaskPrimitives, uint32_t unPrimitiveSize = sizeof(VROverlayIntersectionMaskPrimitive_t)) = 0; - virtual EVROverlayError GetOverlayFlags( VROverlayHandle_t ulOverlayHandle, uint32_t *pFlags ) = 0; + virtual EVROverlayError GetOverlayFlags(VROverlayHandle_t ulOverlayHandle, uint32_t *pFlags) = 0; - // --------------------------------------------- - // Message box methods - // --------------------------------------------- + // --------------------------------------------- + // Message box methods + // --------------------------------------------- - /** Show the message overlay. This will block and return you a result. **/ - virtual VRMessageOverlayResponse ShowMessageOverlay( const char* pchText, const char* pchCaption, const char* pchButton0Text, const char* pchButton1Text = nullptr, const char* pchButton2Text = nullptr, const char* pchButton3Text = nullptr ) = 0; + /** Show the message overlay. This will block and return you a result. **/ + virtual VRMessageOverlayResponse ShowMessageOverlay(const char *pchText, const char *pchCaption, const char *pchButton0Text, const char *pchButton1Text = nullptr, const char *pchButton2Text = nullptr, const char *pchButton3Text = nullptr) = 0; - /** If the calling process owns the overlay and it's open, this will close it. **/ - virtual void CloseMessageOverlay() = 0; - }; + /** If the calling process owns the overlay and it's open, this will close it. **/ + virtual void CloseMessageOverlay() = 0; +}; - static const char * const IVROverlay_Version = "IVROverlay_016"; +static const char *const IVROverlay_Version = "IVROverlay_016"; -} // namespace vr +} // namespace vr // ivrrendermodels.h namespace vr { +static const char *const k_pch_Controller_Component_GDC2015 = "gdc2015"; // Canonical coordinate system of the gdc 2015 wired controller, provided for backwards compatibility +static const char *const k_pch_Controller_Component_Base = "base"; // For controllers with an unambiguous 'base'. +static const char *const k_pch_Controller_Component_Tip = "tip"; // For controllers with an unambiguous 'tip' (used for 'laser-pointing') +static const char *const k_pch_Controller_Component_HandGrip = "handgrip"; // Neutral, ambidextrous hand-pose when holding controller. On plane between neutrally posed index finger and thumb +static const char *const k_pch_Controller_Component_Status = "status"; // 1:1 aspect ratio status area, with canonical [0,1] uv mapping -static const char * const k_pch_Controller_Component_GDC2015 = "gdc2015"; // Canonical coordinate system of the gdc 2015 wired controller, provided for backwards compatibility -static const char * const k_pch_Controller_Component_Base = "base"; // For controllers with an unambiguous 'base'. -static const char * const k_pch_Controller_Component_Tip = "tip"; // For controllers with an unambiguous 'tip' (used for 'laser-pointing') -static const char * const k_pch_Controller_Component_HandGrip = "handgrip"; // Neutral, ambidextrous hand-pose when holding controller. On plane between neutrally posed index finger and thumb -static const char * const k_pch_Controller_Component_Status = "status"; // 1:1 aspect ratio status area, with canonical [0,1] uv mapping - -#pragma pack( push, 8 ) +#pragma pack(push, 8) /** Errors that can occur with the VR compositor */ enum EVRRenderModelError @@ -3062,25 +3002,25 @@ struct RenderModel_ComponentState_t /** A single vertex in a render model */ struct RenderModel_Vertex_t { - HmdVector3_t vPosition; // position in meters in device space + HmdVector3_t vPosition; // position in meters in device space HmdVector3_t vNormal; float rfTextureCoord[2]; }; /** A texture map for use on a render model */ -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif struct RenderModel_TextureMap_t { - uint16_t unWidth, unHeight; // width and height of the texture map in pixels - const uint8_t *rubTextureMapData; // Map texture data. All textures are RGBA with 8 bits per channel per pixel. Data size is width * height * 4ub + uint16_t unWidth, unHeight; // width and height of the texture map in pixels + const uint8_t *rubTextureMapData; // Map texture data. All textures are RGBA with 8 bits per channel per pixel. Data size is width * height * 4ub }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif /** Session unique texture identifier. Rendermodels which share the same texture will have the same id. @@ -3090,36 +3030,34 @@ typedef int32_t TextureID_t; const TextureID_t INVALID_TEXTURE_ID = -1; -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif struct RenderModel_t { - const RenderModel_Vertex_t *rVertexData; // Vertex data for the mesh - uint32_t unVertexCount; // Number of vertices in the vertex data - const uint16_t *rIndexData; // Indices into the vertex data for each triangle - uint32_t unTriangleCount; // Number of triangles in the mesh. Index count is 3 * TriangleCount - TextureID_t diffuseTextureId; // Session unique texture identifier. Rendermodels which share the same texture will have the same id. <0 == texture not present + const RenderModel_Vertex_t *rVertexData; // Vertex data for the mesh + uint32_t unVertexCount; // Number of vertices in the vertex data + const uint16_t *rIndexData; // Indices into the vertex data for each triangle + uint32_t unTriangleCount; // Number of triangles in the mesh. Index count is 3 * TriangleCount + TextureID_t diffuseTextureId; // Session unique texture identifier. Rendermodels which share the same texture will have the same id. <0 == texture not present }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif - struct RenderModel_ControllerMode_State_t { - bool bScrollWheelVisible; // is this controller currently set to be in a scroll wheel mode + bool bScrollWheelVisible; // is this controller currently set to be in a scroll wheel mode }; -#pragma pack( pop ) +#pragma pack(pop) class IVRRenderModels { public: - /** Loads and returns a render model for use in the application. pchRenderModelName should be a render model name * from the Prop_RenderModelName_String property or an absolute path name to a render model on disk. * @@ -3129,37 +3067,36 @@ public: * * The method returns VRRenderModelError_Loading while the render model is still being loaded. * The method returns VRRenderModelError_None once loaded successfully, otherwise will return an error. */ - virtual EVRRenderModelError LoadRenderModel_Async( const char *pchRenderModelName, RenderModel_t **ppRenderModel ) = 0; + virtual EVRRenderModelError LoadRenderModel_Async(const char *pchRenderModelName, RenderModel_t **ppRenderModel) = 0; /** Frees a previously returned render model * It is safe to call this on a null ptr. */ - virtual void FreeRenderModel( RenderModel_t *pRenderModel ) = 0; + virtual void FreeRenderModel(RenderModel_t *pRenderModel) = 0; /** Loads and returns a texture for use in the application. */ - virtual EVRRenderModelError LoadTexture_Async( TextureID_t textureId, RenderModel_TextureMap_t **ppTexture ) = 0; + virtual EVRRenderModelError LoadTexture_Async(TextureID_t textureId, RenderModel_TextureMap_t **ppTexture) = 0; /** Frees a previously returned texture * It is safe to call this on a null ptr. */ - virtual void FreeTexture( RenderModel_TextureMap_t *pTexture ) = 0; + virtual void FreeTexture(RenderModel_TextureMap_t *pTexture) = 0; /** Creates a D3D11 texture and loads data into it. */ - virtual EVRRenderModelError LoadTextureD3D11_Async( TextureID_t textureId, void *pD3D11Device, void **ppD3D11Texture2D ) = 0; + virtual EVRRenderModelError LoadTextureD3D11_Async(TextureID_t textureId, void *pD3D11Device, void **ppD3D11Texture2D) = 0; /** Helper function to copy the bits into an existing texture. */ - virtual EVRRenderModelError LoadIntoTextureD3D11_Async( TextureID_t textureId, void *pDstTexture ) = 0; + virtual EVRRenderModelError LoadIntoTextureD3D11_Async(TextureID_t textureId, void *pDstTexture) = 0; /** Use this to free textures created with LoadTextureD3D11_Async instead of calling Release on them. */ - virtual void FreeTextureD3D11( void *pD3D11Texture2D ) = 0; + virtual void FreeTextureD3D11(void *pD3D11Texture2D) = 0; /** Use this to get the names of available render models. Index does not correlate to a tracked device index, but * is only used for iterating over all available render models. If the index is out of range, this function will return 0. * Otherwise, it will return the size of the buffer required for the name. */ - virtual uint32_t GetRenderModelName( uint32_t unRenderModelIndex, VR_OUT_STRING() char *pchRenderModelName, uint32_t unRenderModelNameLen ) = 0; + virtual uint32_t GetRenderModelName(uint32_t unRenderModelIndex, VR_OUT_STRING() char *pchRenderModelName, uint32_t unRenderModelNameLen) = 0; /** Returns the number of available render models. */ virtual uint32_t GetRenderModelCount() = 0; - /** Returns the number of components of the specified render model. * Components are useful when client application wish to draw, label, or otherwise interact with components of tracked objects. * Examples controller components: @@ -3167,23 +3104,23 @@ public: * non-renderable things which include coordinate systems such as 'tip', 'base', a neutral controller agnostic hand-pose * If all controller components are enumerated and rendered, it will be equivalent to drawing the traditional render model * Returns 0 if components not supported, >0 otherwise */ - virtual uint32_t GetComponentCount( const char *pchRenderModelName ) = 0; + virtual uint32_t GetComponentCount(const char *pchRenderModelName) = 0; /** Use this to get the names of available components. Index does not correlate to a tracked device index, but * is only used for iterating over all available components. If the index is out of range, this function will return 0. * Otherwise, it will return the size of the buffer required for the name. */ - virtual uint32_t GetComponentName( const char *pchRenderModelName, uint32_t unComponentIndex, VR_OUT_STRING( ) char *pchComponentName, uint32_t unComponentNameLen ) = 0; + virtual uint32_t GetComponentName(const char *pchRenderModelName, uint32_t unComponentIndex, VR_OUT_STRING() char *pchComponentName, uint32_t unComponentNameLen) = 0; /** Get the button mask for all buttons associated with this component * If no buttons (or axes) are associated with this component, return 0 * Note: multiple components may be associated with the same button. Ex: two grip buttons on a single controller. * Note: A single component may be associated with multiple buttons. Ex: A trackpad which also provides "D-pad" functionality */ - virtual uint64_t GetComponentButtonMask( const char *pchRenderModelName, const char *pchComponentName ) = 0; + virtual uint64_t GetComponentButtonMask(const char *pchRenderModelName, const char *pchComponentName) = 0; /** Use this to get the render model name for the specified rendermode/component combination, to be passed to LoadRenderModel. * If the component name is out of range, this function will return 0. * Otherwise, it will return the size of the buffer required for the name. */ - virtual uint32_t GetComponentRenderModelName( const char *pchRenderModelName, const char *pchComponentName, VR_OUT_STRING( ) char *pchComponentRenderModelName, uint32_t unComponentRenderModelNameLen ) = 0; + virtual uint32_t GetComponentRenderModelName(const char *pchRenderModelName, const char *pchComponentName, VR_OUT_STRING() char *pchComponentRenderModelName, uint32_t unComponentRenderModelNameLen) = 0; /** Use this to query information about the component, as a function of the controller state. * @@ -3193,93 +3130,87 @@ public: * If the pchRenderModelName or pchComponentName is invalid, this will return false (and transforms will be set to identity). * Otherwise, return true * Note: For dynamic objects, visibility may be dynamic. (I.e., true/false will be returned based on controller state and controller mode state ) */ - virtual bool GetComponentState( const char *pchRenderModelName, const char *pchComponentName, const vr::VRControllerState_t *pControllerState, const RenderModel_ControllerMode_State_t *pState, RenderModel_ComponentState_t *pComponentState ) = 0; + virtual bool GetComponentState(const char *pchRenderModelName, const char *pchComponentName, const vr::VRControllerState_t *pControllerState, const RenderModel_ControllerMode_State_t *pState, RenderModel_ComponentState_t *pComponentState) = 0; /** Returns true if the render model has a component with the specified name */ - virtual bool RenderModelHasComponent( const char *pchRenderModelName, const char *pchComponentName ) = 0; + virtual bool RenderModelHasComponent(const char *pchRenderModelName, const char *pchComponentName) = 0; /** Returns the URL of the thumbnail image for this rendermodel */ - virtual uint32_t GetRenderModelThumbnailURL( const char *pchRenderModelName, VR_OUT_STRING() char *pchThumbnailURL, uint32_t unThumbnailURLLen, vr::EVRRenderModelError *peError ) = 0; + virtual uint32_t GetRenderModelThumbnailURL(const char *pchRenderModelName, VR_OUT_STRING() char *pchThumbnailURL, uint32_t unThumbnailURLLen, vr::EVRRenderModelError *peError) = 0; /** Provides a render model path that will load the unskinned model if the model name provided has been replace by the user. If the model * hasn't been replaced the path value will still be a valid path to load the model. Pass this to LoadRenderModel_Async, etc. to load the * model. */ - virtual uint32_t GetRenderModelOriginalPath( const char *pchRenderModelName, VR_OUT_STRING() char *pchOriginalPath, uint32_t unOriginalPathLen, vr::EVRRenderModelError *peError ) = 0; + virtual uint32_t GetRenderModelOriginalPath(const char *pchRenderModelName, VR_OUT_STRING() char *pchOriginalPath, uint32_t unOriginalPathLen, vr::EVRRenderModelError *peError) = 0; /** Returns a string for a render model error */ - virtual const char *GetRenderModelErrorNameFromEnum( vr::EVRRenderModelError error ) = 0; + virtual const char *GetRenderModelErrorNameFromEnum(vr::EVRRenderModelError error) = 0; }; -static const char * const IVRRenderModels_Version = "IVRRenderModels_005"; - -} +static const char *const IVRRenderModels_Version = "IVRRenderModels_005"; +} // namespace vr // ivrextendeddisplay.h namespace vr { - - /** NOTE: Use of this interface is not recommended in production applications. It will not work for displays which use +/** NOTE: Use of this interface is not recommended in production applications. It will not work for displays which use * direct-to-display mode. Creating our own window is also incompatible with the VR compositor and is not available when the compositor is running. */ - class IVRExtendedDisplay - { - public: +class IVRExtendedDisplay +{ +public: + /** Size and position that the window needs to be on the VR display. */ + virtual void GetWindowBounds(int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight) = 0; - /** Size and position that the window needs to be on the VR display. */ - virtual void GetWindowBounds( int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; + /** Gets the viewport in the frame buffer to draw the output of the distortion into */ + virtual void GetEyeOutputViewport(EVREye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight) = 0; - /** Gets the viewport in the frame buffer to draw the output of the distortion into */ - virtual void GetEyeOutputViewport( EVREye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; - - /** [D3D10/11 Only] + /** [D3D10/11 Only] * Returns the adapter index and output index that the user should pass into EnumAdapters and EnumOutputs * to create the device and swap chain in DX10 and DX11. If an error occurs both indices will be set to -1. */ - virtual void GetDXGIOutputInfo( int32_t *pnAdapterIndex, int32_t *pnAdapterOutputIndex ) = 0; + virtual void GetDXGIOutputInfo(int32_t *pnAdapterIndex, int32_t *pnAdapterOutputIndex) = 0; +}; - }; - - static const char * const IVRExtendedDisplay_Version = "IVRExtendedDisplay_001"; - -} +static const char *const IVRExtendedDisplay_Version = "IVRExtendedDisplay_001"; +} // namespace vr // ivrtrackedcamera.h namespace vr { - class IVRTrackedCamera { public: /** Returns a string for an error */ - virtual const char *GetCameraErrorNameFromEnum( vr::EVRTrackedCameraError eCameraError ) = 0; + virtual const char *GetCameraErrorNameFromEnum(vr::EVRTrackedCameraError eCameraError) = 0; /** For convenience, same as tracked property request Prop_HasCamera_Bool */ - virtual vr::EVRTrackedCameraError HasCamera( vr::TrackedDeviceIndex_t nDeviceIndex, bool *pHasCamera ) = 0; + virtual vr::EVRTrackedCameraError HasCamera(vr::TrackedDeviceIndex_t nDeviceIndex, bool *pHasCamera) = 0; /** Gets size of the image frame. */ - virtual vr::EVRTrackedCameraError GetCameraFrameSize( vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, uint32_t *pnWidth, uint32_t *pnHeight, uint32_t *pnFrameBufferSize ) = 0; + virtual vr::EVRTrackedCameraError GetCameraFrameSize(vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, uint32_t *pnWidth, uint32_t *pnHeight, uint32_t *pnFrameBufferSize) = 0; - virtual vr::EVRTrackedCameraError GetCameraIntrinsics( vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, vr::HmdVector2_t *pFocalLength, vr::HmdVector2_t *pCenter ) = 0; + virtual vr::EVRTrackedCameraError GetCameraIntrinsics(vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, vr::HmdVector2_t *pFocalLength, vr::HmdVector2_t *pCenter) = 0; - virtual vr::EVRTrackedCameraError GetCameraProjection( vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, vr::HmdMatrix44_t *pProjection ) = 0; + virtual vr::EVRTrackedCameraError GetCameraProjection(vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, vr::HmdMatrix44_t *pProjection) = 0; /** Acquiring streaming service permits video streaming for the caller. Releasing hints the system that video services do not need to be maintained for this client. * If the camera has not already been activated, a one time spin up may incur some auto exposure as well as initial streaming frame delays. * The camera should be considered a global resource accessible for shared consumption but not exclusive to any caller. * The camera may go inactive due to lack of active consumers or headset idleness. */ - virtual vr::EVRTrackedCameraError AcquireVideoStreamingService( vr::TrackedDeviceIndex_t nDeviceIndex, vr::TrackedCameraHandle_t *pHandle ) = 0; - virtual vr::EVRTrackedCameraError ReleaseVideoStreamingService( vr::TrackedCameraHandle_t hTrackedCamera ) = 0; + virtual vr::EVRTrackedCameraError AcquireVideoStreamingService(vr::TrackedDeviceIndex_t nDeviceIndex, vr::TrackedCameraHandle_t *pHandle) = 0; + virtual vr::EVRTrackedCameraError ReleaseVideoStreamingService(vr::TrackedCameraHandle_t hTrackedCamera) = 0; /** Copies the image frame into a caller's provided buffer. The image data is currently provided as RGBA data, 4 bytes per pixel. * A caller can provide null for the framebuffer or frameheader if not desired. Requesting the frame header first, followed by the frame buffer allows * the caller to determine if the frame as advanced per the frame header sequence. * If there is no frame available yet, due to initial camera spinup or re-activation, the error will be VRTrackedCameraError_NoFrameAvailable. * Ideally a caller should be polling at ~16ms intervals */ - virtual vr::EVRTrackedCameraError GetVideoStreamFrameBuffer( vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, void *pFrameBuffer, uint32_t nFrameBufferSize, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize ) = 0; + virtual vr::EVRTrackedCameraError GetVideoStreamFrameBuffer(vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, void *pFrameBuffer, uint32_t nFrameBufferSize, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize) = 0; /** Gets size of the image frame. */ - virtual vr::EVRTrackedCameraError GetVideoStreamTextureSize( vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, vr::VRTextureBounds_t *pTextureBounds, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; + virtual vr::EVRTrackedCameraError GetVideoStreamTextureSize(vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, vr::VRTextureBounds_t *pTextureBounds, uint32_t *pnWidth, uint32_t *pnHeight) = 0; /** Access a shared D3D11 texture for the specified tracked camera stream. * The camera frame type VRTrackedCameraFrameType_Undistorted is not supported directly as a shared texture. It is an interior subregion of the shared texture VRTrackedCameraFrameType_MaximumUndistorted. @@ -3287,31 +3218,29 @@ public: * VRTrackedCameraFrameType_MaximumUndistorted to provide the texture. The VRTrackedCameraFrameType_MaximumUndistorted will yield an image where the invalid regions are decoded * by the alpha channel having a zero component. The valid regions all have a non-zero alpha component. The subregion as described by VRTrackedCameraFrameType_Undistorted * guarantees a rectangle where all pixels are valid. */ - virtual vr::EVRTrackedCameraError GetVideoStreamTextureD3D11( vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize ) = 0; + virtual vr::EVRTrackedCameraError GetVideoStreamTextureD3D11(vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize) = 0; /** Access a shared GL texture for the specified tracked camera stream */ - virtual vr::EVRTrackedCameraError GetVideoStreamTextureGL( vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, vr::glUInt_t *pglTextureId, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize ) = 0; - virtual vr::EVRTrackedCameraError ReleaseVideoStreamTextureGL( vr::TrackedCameraHandle_t hTrackedCamera, vr::glUInt_t glTextureId ) = 0; + virtual vr::EVRTrackedCameraError GetVideoStreamTextureGL(vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, vr::glUInt_t *pglTextureId, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize) = 0; + virtual vr::EVRTrackedCameraError ReleaseVideoStreamTextureGL(vr::TrackedCameraHandle_t hTrackedCamera, vr::glUInt_t glTextureId) = 0; }; -static const char * const IVRTrackedCamera_Version = "IVRTrackedCamera_003"; - -} // namespace vr +static const char *const IVRTrackedCamera_Version = "IVRTrackedCamera_003"; +} // namespace vr // ivrscreenshots.h namespace vr { - /** Errors that can occur with the VR compositor */ enum EVRScreenshotError { - VRScreenshotError_None = 0, - VRScreenshotError_RequestFailed = 1, - VRScreenshotError_IncompatibleVersion = 100, - VRScreenshotError_NotFound = 101, - VRScreenshotError_BufferTooSmall = 102, - VRScreenshotError_ScreenshotAlreadyInProgress = 108, + VRScreenshotError_None = 0, + VRScreenshotError_RequestFailed = 1, + VRScreenshotError_IncompatibleVersion = 100, + VRScreenshotError_NotFound = 101, + VRScreenshotError_BufferTooSmall = 102, + VRScreenshotError_ScreenshotAlreadyInProgress = 108, }; /** Allows the application to generate screenshots */ @@ -3349,7 +3278,7 @@ public: * The destination file names do not need an extension, * will be replaced with the correct one for the format * which is currently .png. */ - virtual vr::EVRScreenshotError RequestScreenshot( vr::ScreenshotHandle_t *pOutScreenshotHandle, vr::EVRScreenshotType type, const char *pchPreviewFilename, const char *pchVRFilename ) = 0; + virtual vr::EVRScreenshotError RequestScreenshot(vr::ScreenshotHandle_t *pOutScreenshotHandle, vr::EVRScreenshotType type, const char *pchPreviewFilename, const char *pchVRFilename) = 0; /** Called by the running VR application to indicate that it * wishes to be in charge of screenshots. If the @@ -3359,23 +3288,23 @@ public: * Once hooked your application will receive a * VREvent_RequestScreenshot event when the user presses the * buttons to take a screenshot. */ - virtual vr::EVRScreenshotError HookScreenshot( VR_ARRAY_COUNT( numTypes ) const vr::EVRScreenshotType *pSupportedTypes, int numTypes ) = 0; + virtual vr::EVRScreenshotError HookScreenshot(VR_ARRAY_COUNT(numTypes) const vr::EVRScreenshotType *pSupportedTypes, int numTypes) = 0; /** When your application receives a * VREvent_RequestScreenshot event, call these functions to get * the details of the screenshot request. */ - virtual vr::EVRScreenshotType GetScreenshotPropertyType( vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotError *pError ) = 0; + virtual vr::EVRScreenshotType GetScreenshotPropertyType(vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotError *pError) = 0; /** Get the filename for the preview or vr image (see * vr::EScreenshotPropertyFilenames). The return value is * the size of the string. */ - virtual uint32_t GetScreenshotPropertyFilename( vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotPropertyFilenames filenameType, VR_OUT_STRING() char *pchFilename, uint32_t cchFilename, vr::EVRScreenshotError *pError ) = 0; + virtual uint32_t GetScreenshotPropertyFilename(vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotPropertyFilenames filenameType, VR_OUT_STRING() char *pchFilename, uint32_t cchFilename, vr::EVRScreenshotError *pError) = 0; /** Call this if the application is taking the screen shot * will take more than a few ms processing. This will result * in an overlay being presented that shows a completion * bar. */ - virtual vr::EVRScreenshotError UpdateScreenshotProgress( vr::ScreenshotHandle_t screenshotHandle, float flProgress ) = 0; + virtual vr::EVRScreenshotError UpdateScreenshotProgress(vr::ScreenshotHandle_t screenshotHandle, float flProgress) = 0; /** Tells the compositor to take an internal screenshot of * type VRScreenshotType_Stereo. It will take the current @@ -3384,7 +3313,7 @@ public: * for the VR image. * This is similar to request screenshot, but doesn't ever * talk to the application, just takes the shot and submits. */ - virtual vr::EVRScreenshotError TakeStereoScreenshot( vr::ScreenshotHandle_t *pOutScreenshotHandle, const char *pchPreviewFilename, const char *pchVRFilename ) = 0; + virtual vr::EVRScreenshotError TakeStereoScreenshot(vr::ScreenshotHandle_t *pOutScreenshotHandle, const char *pchPreviewFilename, const char *pchVRFilename) = 0; /** Submit the completed screenshot. If Steam is running * this will call into the Steam client and upload the @@ -3397,67 +3326,59 @@ public: * screenshotHandle can be k_unScreenshotHandleInvalid if this * was a new shot taking by the app to be saved and not * initiated by a user (achievement earned or something) */ - virtual vr::EVRScreenshotError SubmitScreenshot( vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotType type, const char *pchSourcePreviewFilename, const char *pchSourceVRFilename ) = 0; + virtual vr::EVRScreenshotError SubmitScreenshot(vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotType type, const char *pchSourcePreviewFilename, const char *pchSourceVRFilename) = 0; }; -static const char * const IVRScreenshots_Version = "IVRScreenshots_001"; - -} // namespace vr - +static const char *const IVRScreenshots_Version = "IVRScreenshots_001"; +} // namespace vr // ivrresources.h namespace vr { - class IVRResources { public: - // ------------------------------------ // Shared Resource Methods // ------------------------------------ /** Loads the specified resource into the provided buffer if large enough. * Returns the size in bytes of the buffer required to hold the specified resource. */ - virtual uint32_t LoadSharedResource( const char *pchResourceName, char *pchBuffer, uint32_t unBufferLen ) = 0; + virtual uint32_t LoadSharedResource(const char *pchResourceName, char *pchBuffer, uint32_t unBufferLen) = 0; /** Provides the full path to the specified resource. Resource names can include named directories for * drivers and other things, and this resolves all of those and returns the actual physical path. * pchResourceTypeDirectory is the subdirectory of resources to look in. */ - virtual uint32_t GetResourceFullPath( const char *pchResourceName, const char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen ) = 0; + virtual uint32_t GetResourceFullPath(const char *pchResourceName, const char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen) = 0; }; -static const char * const IVRResources_Version = "IVRResources_001"; +static const char *const IVRResources_Version = "IVRResources_001"; - -} +} // namespace vr // ivrdrivermanager.h namespace vr { - class IVRDriverManager { public: virtual uint32_t GetDriverCount() const = 0; /** Returns the length of the number of bytes necessary to hold this string including the trailing null. */ - virtual uint32_t GetDriverName( vr::DriverId_t nDriver, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize ) = 0; + virtual uint32_t GetDriverName(vr::DriverId_t nDriver, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize) = 0; }; -static const char * const IVRDriverManager_Version = "IVRDriverManager_001"; - -} // namespace vr +static const char *const IVRDriverManager_Version = "IVRDriverManager_001"; +} // namespace vr // End -#endif // _OPENVR_API - +#endif // _OPENVR_API namespace vr { - /** Finds the active installation of the VR API and initializes it. The provided path must be absolute +/** Finds the active installation of the VR API and initializes it. The provided path must be absolute * or relative to the current working directory. These are the local install versions of the equivalent * functions in steamvr.h and will work without a local Steam install. * @@ -3466,312 +3387,312 @@ namespace vr * * pStartupInfo is reserved for future use. */ - inline IVRSystem *VR_Init( EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo = nullptr ); +inline IVRSystem *VR_Init(EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo = nullptr); - /** unloads vrclient.dll. Any interface pointers from the interface are +/** unloads vrclient.dll. Any interface pointers from the interface are * invalid after this point */ - inline void VR_Shutdown(); +inline void VR_Shutdown(); - /** Returns true if there is an HMD attached. This check is as lightweight as possible and +/** Returns true if there is an HMD attached. This check is as lightweight as possible and * can be called outside of VR_Init/VR_Shutdown. It should be used when an application wants * to know if initializing VR is a possibility but isn't ready to take that step yet. */ - VR_INTERFACE bool VR_CALLTYPE VR_IsHmdPresent(); +VR_INTERFACE bool VR_CALLTYPE VR_IsHmdPresent(); - /** Returns true if the OpenVR runtime is installed. */ - VR_INTERFACE bool VR_CALLTYPE VR_IsRuntimeInstalled(); +/** Returns true if the OpenVR runtime is installed. */ +VR_INTERFACE bool VR_CALLTYPE VR_IsRuntimeInstalled(); - /** Returns where the OpenVR runtime is installed. */ - VR_INTERFACE const char *VR_CALLTYPE VR_RuntimePath(); +/** Returns where the OpenVR runtime is installed. */ +VR_INTERFACE const char *VR_CALLTYPE VR_RuntimePath(); - /** Returns the name of the enum value for an EVRInitError. This function may be called outside of VR_Init()/VR_Shutdown(). */ - VR_INTERFACE const char *VR_CALLTYPE VR_GetVRInitErrorAsSymbol( EVRInitError error ); +/** Returns the name of the enum value for an EVRInitError. This function may be called outside of VR_Init()/VR_Shutdown(). */ +VR_INTERFACE const char *VR_CALLTYPE VR_GetVRInitErrorAsSymbol(EVRInitError error); - /** Returns an English string for an EVRInitError. Applications should call VR_GetVRInitErrorAsSymbol instead and +/** Returns an English string for an EVRInitError. Applications should call VR_GetVRInitErrorAsSymbol instead and * use that as a key to look up their own localized error message. This function may be called outside of VR_Init()/VR_Shutdown(). */ - VR_INTERFACE const char *VR_CALLTYPE VR_GetVRInitErrorAsEnglishDescription( EVRInitError error ); +VR_INTERFACE const char *VR_CALLTYPE VR_GetVRInitErrorAsEnglishDescription(EVRInitError error); - /** Returns the interface of the specified version. This method must be called after VR_Init. The +/** Returns the interface of the specified version. This method must be called after VR_Init. The * pointer returned is valid until VR_Shutdown is called. */ - VR_INTERFACE void *VR_CALLTYPE VR_GetGenericInterface( const char *pchInterfaceVersion, EVRInitError *peError ); +VR_INTERFACE void *VR_CALLTYPE VR_GetGenericInterface(const char *pchInterfaceVersion, EVRInitError *peError); - /** Returns whether the interface of the specified version exists. +/** Returns whether the interface of the specified version exists. */ - VR_INTERFACE bool VR_CALLTYPE VR_IsInterfaceVersionValid( const char *pchInterfaceVersion ); +VR_INTERFACE bool VR_CALLTYPE VR_IsInterfaceVersionValid(const char *pchInterfaceVersion); - /** Returns a token that represents whether the VR interface handles need to be reloaded */ - VR_INTERFACE uint32_t VR_CALLTYPE VR_GetInitToken(); +/** Returns a token that represents whether the VR interface handles need to be reloaded */ +VR_INTERFACE uint32_t VR_CALLTYPE VR_GetInitToken(); - // These typedefs allow old enum names from SDK 0.9.11 to be used in applications. - // They will go away in the future. - typedef EVRInitError HmdError; - typedef EVREye Hmd_Eye; - typedef EColorSpace ColorSpace; - typedef ETrackingResult HmdTrackingResult; - typedef ETrackedDeviceClass TrackedDeviceClass; - typedef ETrackingUniverseOrigin TrackingUniverseOrigin; - typedef ETrackedDeviceProperty TrackedDeviceProperty; - typedef ETrackedPropertyError TrackedPropertyError; - typedef EVRSubmitFlags VRSubmitFlags_t; - typedef EVRState VRState_t; - typedef ECollisionBoundsStyle CollisionBoundsStyle_t; - typedef EVROverlayError VROverlayError; - typedef EVRFirmwareError VRFirmwareError; - typedef EVRCompositorError VRCompositorError; - typedef EVRScreenshotError VRScreenshotsError; +// These typedefs allow old enum names from SDK 0.9.11 to be used in applications. +// They will go away in the future. +typedef EVRInitError HmdError; +typedef EVREye Hmd_Eye; +typedef EColorSpace ColorSpace; +typedef ETrackingResult HmdTrackingResult; +typedef ETrackedDeviceClass TrackedDeviceClass; +typedef ETrackingUniverseOrigin TrackingUniverseOrigin; +typedef ETrackedDeviceProperty TrackedDeviceProperty; +typedef ETrackedPropertyError TrackedPropertyError; +typedef EVRSubmitFlags VRSubmitFlags_t; +typedef EVRState VRState_t; +typedef ECollisionBoundsStyle CollisionBoundsStyle_t; +typedef EVROverlayError VROverlayError; +typedef EVRFirmwareError VRFirmwareError; +typedef EVRCompositorError VRCompositorError; +typedef EVRScreenshotError VRScreenshotsError; - inline uint32_t &VRToken() - { - static uint32_t token; - return token; - } - - class COpenVRContext - { - public: - COpenVRContext() { Clear(); } - void Clear(); - - inline void CheckClear() - { - if ( VRToken() != VR_GetInitToken() ) - { - Clear(); - VRToken() = VR_GetInitToken(); - } - } - - IVRSystem *VRSystem() - { - CheckClear(); - if ( m_pVRSystem == nullptr ) - { - EVRInitError eError; - m_pVRSystem = ( IVRSystem * )VR_GetGenericInterface( IVRSystem_Version, &eError ); - } - return m_pVRSystem; - } - IVRChaperone *VRChaperone() - { - CheckClear(); - if ( m_pVRChaperone == nullptr ) - { - EVRInitError eError; - m_pVRChaperone = ( IVRChaperone * )VR_GetGenericInterface( IVRChaperone_Version, &eError ); - } - return m_pVRChaperone; - } - - IVRChaperoneSetup *VRChaperoneSetup() - { - CheckClear(); - if ( m_pVRChaperoneSetup == nullptr ) - { - EVRInitError eError; - m_pVRChaperoneSetup = ( IVRChaperoneSetup * )VR_GetGenericInterface( IVRChaperoneSetup_Version, &eError ); - } - return m_pVRChaperoneSetup; - } - - IVRCompositor *VRCompositor() - { - CheckClear(); - if ( m_pVRCompositor == nullptr ) - { - EVRInitError eError; - m_pVRCompositor = ( IVRCompositor * )VR_GetGenericInterface( IVRCompositor_Version, &eError ); - } - return m_pVRCompositor; - } - - IVROverlay *VROverlay() - { - CheckClear(); - if ( m_pVROverlay == nullptr ) - { - EVRInitError eError; - m_pVROverlay = ( IVROverlay * )VR_GetGenericInterface( IVROverlay_Version, &eError ); - } - return m_pVROverlay; - } - - IVRResources *VRResources() - { - CheckClear(); - if ( m_pVRResources == nullptr ) - { - EVRInitError eError; - m_pVRResources = (IVRResources *)VR_GetGenericInterface( IVRResources_Version, &eError ); - } - return m_pVRResources; - } - - IVRScreenshots *VRScreenshots() - { - CheckClear(); - if ( m_pVRScreenshots == nullptr ) - { - EVRInitError eError; - m_pVRScreenshots = ( IVRScreenshots * )VR_GetGenericInterface( IVRScreenshots_Version, &eError ); - } - return m_pVRScreenshots; - } - - IVRRenderModels *VRRenderModels() - { - CheckClear(); - if ( m_pVRRenderModels == nullptr ) - { - EVRInitError eError; - m_pVRRenderModels = ( IVRRenderModels * )VR_GetGenericInterface( IVRRenderModels_Version, &eError ); - } - return m_pVRRenderModels; - } - - IVRExtendedDisplay *VRExtendedDisplay() - { - CheckClear(); - if ( m_pVRExtendedDisplay == nullptr ) - { - EVRInitError eError; - m_pVRExtendedDisplay = ( IVRExtendedDisplay * )VR_GetGenericInterface( IVRExtendedDisplay_Version, &eError ); - } - return m_pVRExtendedDisplay; - } - - IVRSettings *VRSettings() - { - CheckClear(); - if ( m_pVRSettings == nullptr ) - { - EVRInitError eError; - m_pVRSettings = ( IVRSettings * )VR_GetGenericInterface( IVRSettings_Version, &eError ); - } - return m_pVRSettings; - } - - IVRApplications *VRApplications() - { - CheckClear(); - if ( m_pVRApplications == nullptr ) - { - EVRInitError eError; - m_pVRApplications = ( IVRApplications * )VR_GetGenericInterface( IVRApplications_Version, &eError ); - } - return m_pVRApplications; - } - - IVRTrackedCamera *VRTrackedCamera() - { - CheckClear(); - if ( m_pVRTrackedCamera == nullptr ) - { - EVRInitError eError; - m_pVRTrackedCamera = ( IVRTrackedCamera * )VR_GetGenericInterface( IVRTrackedCamera_Version, &eError ); - } - return m_pVRTrackedCamera; - } - - IVRDriverManager *VRDriverManager() - { - CheckClear(); - if ( !m_pVRDriverManager ) - { - EVRInitError eError; - m_pVRDriverManager = ( IVRDriverManager * )VR_GetGenericInterface( IVRDriverManager_Version, &eError ); - } - return m_pVRDriverManager; - } - - private: - IVRSystem *m_pVRSystem; - IVRChaperone *m_pVRChaperone; - IVRChaperoneSetup *m_pVRChaperoneSetup; - IVRCompositor *m_pVRCompositor; - IVROverlay *m_pVROverlay; - IVRResources *m_pVRResources; - IVRRenderModels *m_pVRRenderModels; - IVRExtendedDisplay *m_pVRExtendedDisplay; - IVRSettings *m_pVRSettings; - IVRApplications *m_pVRApplications; - IVRTrackedCamera *m_pVRTrackedCamera; - IVRScreenshots *m_pVRScreenshots; - IVRDriverManager *m_pVRDriverManager; - }; - - inline COpenVRContext &OpenVRInternal_ModuleContext() - { - static void *ctx[ sizeof( COpenVRContext ) / sizeof( void * ) ]; - return *( COpenVRContext * )ctx; // bypass zero-init constructor - } - - inline IVRSystem *VR_CALLTYPE VRSystem() { return OpenVRInternal_ModuleContext().VRSystem(); } - inline IVRChaperone *VR_CALLTYPE VRChaperone() { return OpenVRInternal_ModuleContext().VRChaperone(); } - inline IVRChaperoneSetup *VR_CALLTYPE VRChaperoneSetup() { return OpenVRInternal_ModuleContext().VRChaperoneSetup(); } - inline IVRCompositor *VR_CALLTYPE VRCompositor() { return OpenVRInternal_ModuleContext().VRCompositor(); } - inline IVROverlay *VR_CALLTYPE VROverlay() { return OpenVRInternal_ModuleContext().VROverlay(); } - inline IVRScreenshots *VR_CALLTYPE VRScreenshots() { return OpenVRInternal_ModuleContext().VRScreenshots(); } - inline IVRRenderModels *VR_CALLTYPE VRRenderModels() { return OpenVRInternal_ModuleContext().VRRenderModels(); } - inline IVRApplications *VR_CALLTYPE VRApplications() { return OpenVRInternal_ModuleContext().VRApplications(); } - inline IVRSettings *VR_CALLTYPE VRSettings() { return OpenVRInternal_ModuleContext().VRSettings(); } - inline IVRResources *VR_CALLTYPE VRResources() { return OpenVRInternal_ModuleContext().VRResources(); } - inline IVRExtendedDisplay *VR_CALLTYPE VRExtendedDisplay() { return OpenVRInternal_ModuleContext().VRExtendedDisplay(); } - inline IVRTrackedCamera *VR_CALLTYPE VRTrackedCamera() { return OpenVRInternal_ModuleContext().VRTrackedCamera(); } - inline IVRDriverManager *VR_CALLTYPE VRDriverManager() { return OpenVRInternal_ModuleContext().VRDriverManager(); } - - inline void COpenVRContext::Clear() - { - m_pVRSystem = nullptr; - m_pVRChaperone = nullptr; - m_pVRChaperoneSetup = nullptr; - m_pVRCompositor = nullptr; - m_pVROverlay = nullptr; - m_pVRRenderModels = nullptr; - m_pVRExtendedDisplay = nullptr; - m_pVRSettings = nullptr; - m_pVRApplications = nullptr; - m_pVRTrackedCamera = nullptr; - m_pVRResources = nullptr; - m_pVRScreenshots = nullptr; - m_pVRDriverManager = nullptr; - } - - VR_INTERFACE uint32_t VR_CALLTYPE VR_InitInternal2( EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo ); - VR_INTERFACE void VR_CALLTYPE VR_ShutdownInternal(); - - /** Finds the active installation of vrclient.dll and initializes it */ - inline IVRSystem *VR_Init( EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo ) - { - IVRSystem *pVRSystem = nullptr; - - EVRInitError eError; - VRToken() = VR_InitInternal2( &eError, eApplicationType, pStartupInfo ); - COpenVRContext &ctx = OpenVRInternal_ModuleContext(); - ctx.Clear(); - - if ( eError == VRInitError_None ) - { - if ( VR_IsInterfaceVersionValid( IVRSystem_Version ) ) - { - pVRSystem = VRSystem(); - } - else - { - VR_ShutdownInternal(); - eError = VRInitError_Init_InterfaceNotFound; - } - } - - if ( peError ) - *peError = eError; - return pVRSystem; - } - - /** unloads vrclient.dll. Any interface pointers from the interface are - * invalid after this point */ - inline void VR_Shutdown() - { - VR_ShutdownInternal(); - } +inline uint32_t &VRToken() +{ + static uint32_t token; + return token; } + +class COpenVRContext +{ +public: + COpenVRContext() { Clear(); } + void Clear(); + + inline void CheckClear() + { + if (VRToken() != VR_GetInitToken()) + { + Clear(); + VRToken() = VR_GetInitToken(); + } + } + + IVRSystem *VRSystem() + { + CheckClear(); + if (m_pVRSystem == nullptr) + { + EVRInitError eError; + m_pVRSystem = (IVRSystem *)VR_GetGenericInterface(IVRSystem_Version, &eError); + } + return m_pVRSystem; + } + IVRChaperone *VRChaperone() + { + CheckClear(); + if (m_pVRChaperone == nullptr) + { + EVRInitError eError; + m_pVRChaperone = (IVRChaperone *)VR_GetGenericInterface(IVRChaperone_Version, &eError); + } + return m_pVRChaperone; + } + + IVRChaperoneSetup *VRChaperoneSetup() + { + CheckClear(); + if (m_pVRChaperoneSetup == nullptr) + { + EVRInitError eError; + m_pVRChaperoneSetup = (IVRChaperoneSetup *)VR_GetGenericInterface(IVRChaperoneSetup_Version, &eError); + } + return m_pVRChaperoneSetup; + } + + IVRCompositor *VRCompositor() + { + CheckClear(); + if (m_pVRCompositor == nullptr) + { + EVRInitError eError; + m_pVRCompositor = (IVRCompositor *)VR_GetGenericInterface(IVRCompositor_Version, &eError); + } + return m_pVRCompositor; + } + + IVROverlay *VROverlay() + { + CheckClear(); + if (m_pVROverlay == nullptr) + { + EVRInitError eError; + m_pVROverlay = (IVROverlay *)VR_GetGenericInterface(IVROverlay_Version, &eError); + } + return m_pVROverlay; + } + + IVRResources *VRResources() + { + CheckClear(); + if (m_pVRResources == nullptr) + { + EVRInitError eError; + m_pVRResources = (IVRResources *)VR_GetGenericInterface(IVRResources_Version, &eError); + } + return m_pVRResources; + } + + IVRScreenshots *VRScreenshots() + { + CheckClear(); + if (m_pVRScreenshots == nullptr) + { + EVRInitError eError; + m_pVRScreenshots = (IVRScreenshots *)VR_GetGenericInterface(IVRScreenshots_Version, &eError); + } + return m_pVRScreenshots; + } + + IVRRenderModels *VRRenderModels() + { + CheckClear(); + if (m_pVRRenderModels == nullptr) + { + EVRInitError eError; + m_pVRRenderModels = (IVRRenderModels *)VR_GetGenericInterface(IVRRenderModels_Version, &eError); + } + return m_pVRRenderModels; + } + + IVRExtendedDisplay *VRExtendedDisplay() + { + CheckClear(); + if (m_pVRExtendedDisplay == nullptr) + { + EVRInitError eError; + m_pVRExtendedDisplay = (IVRExtendedDisplay *)VR_GetGenericInterface(IVRExtendedDisplay_Version, &eError); + } + return m_pVRExtendedDisplay; + } + + IVRSettings *VRSettings() + { + CheckClear(); + if (m_pVRSettings == nullptr) + { + EVRInitError eError; + m_pVRSettings = (IVRSettings *)VR_GetGenericInterface(IVRSettings_Version, &eError); + } + return m_pVRSettings; + } + + IVRApplications *VRApplications() + { + CheckClear(); + if (m_pVRApplications == nullptr) + { + EVRInitError eError; + m_pVRApplications = (IVRApplications *)VR_GetGenericInterface(IVRApplications_Version, &eError); + } + return m_pVRApplications; + } + + IVRTrackedCamera *VRTrackedCamera() + { + CheckClear(); + if (m_pVRTrackedCamera == nullptr) + { + EVRInitError eError; + m_pVRTrackedCamera = (IVRTrackedCamera *)VR_GetGenericInterface(IVRTrackedCamera_Version, &eError); + } + return m_pVRTrackedCamera; + } + + IVRDriverManager *VRDriverManager() + { + CheckClear(); + if (!m_pVRDriverManager) + { + EVRInitError eError; + m_pVRDriverManager = (IVRDriverManager *)VR_GetGenericInterface(IVRDriverManager_Version, &eError); + } + return m_pVRDriverManager; + } + +private: + IVRSystem *m_pVRSystem; + IVRChaperone *m_pVRChaperone; + IVRChaperoneSetup *m_pVRChaperoneSetup; + IVRCompositor *m_pVRCompositor; + IVROverlay *m_pVROverlay; + IVRResources *m_pVRResources; + IVRRenderModels *m_pVRRenderModels; + IVRExtendedDisplay *m_pVRExtendedDisplay; + IVRSettings *m_pVRSettings; + IVRApplications *m_pVRApplications; + IVRTrackedCamera *m_pVRTrackedCamera; + IVRScreenshots *m_pVRScreenshots; + IVRDriverManager *m_pVRDriverManager; +}; + +inline COpenVRContext &OpenVRInternal_ModuleContext() +{ + static void *ctx[sizeof(COpenVRContext) / sizeof(void *)]; + return *(COpenVRContext *)ctx; // bypass zero-init constructor +} + +inline IVRSystem *VR_CALLTYPE VRSystem() { return OpenVRInternal_ModuleContext().VRSystem(); } +inline IVRChaperone *VR_CALLTYPE VRChaperone() { return OpenVRInternal_ModuleContext().VRChaperone(); } +inline IVRChaperoneSetup *VR_CALLTYPE VRChaperoneSetup() { return OpenVRInternal_ModuleContext().VRChaperoneSetup(); } +inline IVRCompositor *VR_CALLTYPE VRCompositor() { return OpenVRInternal_ModuleContext().VRCompositor(); } +inline IVROverlay *VR_CALLTYPE VROverlay() { return OpenVRInternal_ModuleContext().VROverlay(); } +inline IVRScreenshots *VR_CALLTYPE VRScreenshots() { return OpenVRInternal_ModuleContext().VRScreenshots(); } +inline IVRRenderModels *VR_CALLTYPE VRRenderModels() { return OpenVRInternal_ModuleContext().VRRenderModels(); } +inline IVRApplications *VR_CALLTYPE VRApplications() { return OpenVRInternal_ModuleContext().VRApplications(); } +inline IVRSettings *VR_CALLTYPE VRSettings() { return OpenVRInternal_ModuleContext().VRSettings(); } +inline IVRResources *VR_CALLTYPE VRResources() { return OpenVRInternal_ModuleContext().VRResources(); } +inline IVRExtendedDisplay *VR_CALLTYPE VRExtendedDisplay() { return OpenVRInternal_ModuleContext().VRExtendedDisplay(); } +inline IVRTrackedCamera *VR_CALLTYPE VRTrackedCamera() { return OpenVRInternal_ModuleContext().VRTrackedCamera(); } +inline IVRDriverManager *VR_CALLTYPE VRDriverManager() { return OpenVRInternal_ModuleContext().VRDriverManager(); } + +inline void COpenVRContext::Clear() +{ + m_pVRSystem = nullptr; + m_pVRChaperone = nullptr; + m_pVRChaperoneSetup = nullptr; + m_pVRCompositor = nullptr; + m_pVROverlay = nullptr; + m_pVRRenderModels = nullptr; + m_pVRExtendedDisplay = nullptr; + m_pVRSettings = nullptr; + m_pVRApplications = nullptr; + m_pVRTrackedCamera = nullptr; + m_pVRResources = nullptr; + m_pVRScreenshots = nullptr; + m_pVRDriverManager = nullptr; +} + +VR_INTERFACE uint32_t VR_CALLTYPE VR_InitInternal2(EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo); +VR_INTERFACE void VR_CALLTYPE VR_ShutdownInternal(); + +/** Finds the active installation of vrclient.dll and initializes it */ +inline IVRSystem *VR_Init(EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo) +{ + IVRSystem *pVRSystem = nullptr; + + EVRInitError eError; + VRToken() = VR_InitInternal2(&eError, eApplicationType, pStartupInfo); + COpenVRContext &ctx = OpenVRInternal_ModuleContext(); + ctx.Clear(); + + if (eError == VRInitError_None) + { + if (VR_IsInterfaceVersionValid(IVRSystem_Version)) + { + pVRSystem = VRSystem(); + } + else + { + VR_ShutdownInternal(); + eError = VRInitError_Init_InterfaceNotFound; + } + } + + if (peError) + *peError = eError; + return pVRSystem; +} + +/** unloads vrclient.dll. Any interface pointers from the interface are + * invalid after this point */ +inline void VR_Shutdown() +{ + VR_ShutdownInternal(); +} +} // namespace vr diff --git a/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/A/Headers/openvr_capi.h b/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/A/Headers/openvr_capi.h index 50f895869..245365f4e 100644 --- a/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/A/Headers/openvr_capi.h +++ b/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/A/Headers/openvr_capi.h @@ -7,7 +7,7 @@ #ifndef __OPENVR_API_FLAT_H__ #define __OPENVR_API_FLAT_H__ -#if defined( _WIN32 ) || defined( __clang__ ) +#if defined(_WIN32) || defined(__clang__) #pragma once #endif @@ -17,38 +17,38 @@ #define EXTERN_C #endif -#if defined( _WIN32 ) +#if defined(_WIN32) #define OPENVR_FNTABLE_CALLTYPE __stdcall #else -#define OPENVR_FNTABLE_CALLTYPE +#define OPENVR_FNTABLE_CALLTYPE #endif // OPENVR API export macro -#if defined( _WIN32 ) && !defined( _X360 ) - #if defined( OPENVR_API_EXPORTS ) - #define S_API EXTERN_C __declspec( dllexport ) - #elif defined( OPENVR_API_NODLL ) - #define S_API EXTERN_C - #else - #define S_API extern "C" __declspec( dllimport ) - #endif // OPENVR_API_EXPORTS -#elif defined( __GNUC__ ) - #if defined( OPENVR_API_EXPORTS ) - #define S_API EXTERN_C __attribute__ ((visibility("default"))) - #else - #define S_API EXTERN_C - #endif // OPENVR_API_EXPORTS -#else // !WIN32 - #if defined( OPENVR_API_EXPORTS ) - #define S_API EXTERN_C - #else - #define S_API EXTERN_C - #endif // OPENVR_API_EXPORTS +#if defined(_WIN32) && !defined(_X360) +#if defined(OPENVR_API_EXPORTS) +#define S_API EXTERN_C __declspec(dllexport) +#elif defined(OPENVR_API_NODLL) +#define S_API EXTERN_C +#else +#define S_API extern "C" __declspec(dllimport) +#endif // OPENVR_API_EXPORTS +#elif defined(__GNUC__) +#if defined(OPENVR_API_EXPORTS) +#define S_API EXTERN_C __attribute__((visibility("default"))) +#else +#define S_API EXTERN_C +#endif // OPENVR_API_EXPORTS +#else // !WIN32 +#if defined(OPENVR_API_EXPORTS) +#define S_API EXTERN_C +#else +#define S_API EXTERN_C +#endif // OPENVR_API_EXPORTS #endif #include -#if defined( __WIN32 ) +#if defined(__WIN32) typedef char bool; #else #include @@ -60,7 +60,6 @@ typedef uint64_t VRActionHandle_t; typedef uint64_t VRActionSetHandle_t; typedef uint64_t VRInputOriginHandle_t; - // OpenVR Constants static const unsigned int k_nDriverNone = 4294967295; @@ -87,157 +86,157 @@ static const unsigned int k_unMaxPropertyStringSize = 32768; static const unsigned int k_unControllerStateAxisCount = 5; static const unsigned long k_ulOverlayHandleInvalid = 0; static const unsigned int k_unScreenshotHandleInvalid = 0; -static const char * IVRSystem_Version = "IVRSystem_017"; -static const char * IVRExtendedDisplay_Version = "IVRExtendedDisplay_001"; -static const char * IVRTrackedCamera_Version = "IVRTrackedCamera_003"; +static const char *IVRSystem_Version = "IVRSystem_017"; +static const char *IVRExtendedDisplay_Version = "IVRExtendedDisplay_001"; +static const char *IVRTrackedCamera_Version = "IVRTrackedCamera_003"; static const unsigned int k_unMaxApplicationKeyLength = 128; -static const char * k_pch_MimeType_HomeApp = "vr/home"; -static const char * k_pch_MimeType_GameTheater = "vr/game_theater"; -static const char * IVRApplications_Version = "IVRApplications_006"; -static const char * IVRChaperone_Version = "IVRChaperone_003"; -static const char * IVRChaperoneSetup_Version = "IVRChaperoneSetup_005"; -static const char * IVRCompositor_Version = "IVRCompositor_021"; +static const char *k_pch_MimeType_HomeApp = "vr/home"; +static const char *k_pch_MimeType_GameTheater = "vr/game_theater"; +static const char *IVRApplications_Version = "IVRApplications_006"; +static const char *IVRChaperone_Version = "IVRChaperone_003"; +static const char *IVRChaperoneSetup_Version = "IVRChaperoneSetup_005"; +static const char *IVRCompositor_Version = "IVRCompositor_021"; static const unsigned int k_unVROverlayMaxKeyLength = 128; static const unsigned int k_unVROverlayMaxNameLength = 128; static const unsigned int k_unMaxOverlayCount = 64; static const unsigned int k_unMaxOverlayIntersectionMaskPrimitivesCount = 32; -static const char * IVROverlay_Version = "IVROverlay_016"; -static const char * k_pch_Controller_Component_GDC2015 = "gdc2015"; -static const char * k_pch_Controller_Component_Base = "base"; -static const char * k_pch_Controller_Component_Tip = "tip"; -static const char * k_pch_Controller_Component_HandGrip = "handgrip"; -static const char * k_pch_Controller_Component_Status = "status"; -static const char * IVRRenderModels_Version = "IVRRenderModels_005"; +static const char *IVROverlay_Version = "IVROverlay_016"; +static const char *k_pch_Controller_Component_GDC2015 = "gdc2015"; +static const char *k_pch_Controller_Component_Base = "base"; +static const char *k_pch_Controller_Component_Tip = "tip"; +static const char *k_pch_Controller_Component_HandGrip = "handgrip"; +static const char *k_pch_Controller_Component_Status = "status"; +static const char *IVRRenderModels_Version = "IVRRenderModels_005"; static const unsigned int k_unNotificationTextMaxSize = 256; -static const char * IVRNotifications_Version = "IVRNotifications_002"; +static const char *IVRNotifications_Version = "IVRNotifications_002"; static const unsigned int k_unMaxSettingsKeyLength = 128; -static const char * IVRSettings_Version = "IVRSettings_002"; -static const char * k_pch_SteamVR_Section = "steamvr"; -static const char * k_pch_SteamVR_RequireHmd_String = "requireHmd"; -static const char * k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; -static const char * k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; -static const char * k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; -static const char * k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; -static const char * k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; -static const char * k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; -static const char * k_pch_SteamVR_SendSystemButtonToAllApps_Bool = "sendSystemButtonToAllApps"; -static const char * k_pch_SteamVR_LogLevel_Int32 = "loglevel"; -static const char * k_pch_SteamVR_IPD_Float = "ipd"; -static const char * k_pch_SteamVR_Background_String = "background"; -static const char * k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; -static const char * k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; -static const char * k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; -static const char * k_pch_SteamVR_GridColor_String = "gridColor"; -static const char * k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; -static const char * k_pch_SteamVR_ShowStage_Bool = "showStage"; -static const char * k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; -static const char * k_pch_SteamVR_DirectMode_Bool = "directMode"; -static const char * k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; -static const char * k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; -static const char * k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; -static const char * k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; -static const char * k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; -static const char * k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; -static const char * k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; -static const char * k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; -static const char * k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; -static const char * k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; -static const char * k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; -static const char * k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; -static const char * k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; -static const char * k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; -static const char * k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; -static const char * k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; -static const char * k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; -static const char * k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; -static const char * k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; -static const char * k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; -static const char * k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; -static const char * k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; -static const char * k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; -static const char * k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; -static const char * k_pch_Lighthouse_Section = "driver_lighthouse"; -static const char * k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; -static const char * k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; -static const char * k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; -static const char * k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; -static const char * k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; -static const char * k_pch_Null_Section = "driver_null"; -static const char * k_pch_Null_SerialNumber_String = "serialNumber"; -static const char * k_pch_Null_ModelNumber_String = "modelNumber"; -static const char * k_pch_Null_WindowX_Int32 = "windowX"; -static const char * k_pch_Null_WindowY_Int32 = "windowY"; -static const char * k_pch_Null_WindowWidth_Int32 = "windowWidth"; -static const char * k_pch_Null_WindowHeight_Int32 = "windowHeight"; -static const char * k_pch_Null_RenderWidth_Int32 = "renderWidth"; -static const char * k_pch_Null_RenderHeight_Int32 = "renderHeight"; -static const char * k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; -static const char * k_pch_Null_DisplayFrequency_Float = "displayFrequency"; -static const char * k_pch_UserInterface_Section = "userinterface"; -static const char * k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; -static const char * k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; -static const char * k_pch_UserInterface_Screenshots_Bool = "screenshots"; -static const char * k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; -static const char * k_pch_Notifications_Section = "notifications"; -static const char * k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; -static const char * k_pch_Keyboard_Section = "keyboard"; -static const char * k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; -static const char * k_pch_Keyboard_ScaleX = "ScaleX"; -static const char * k_pch_Keyboard_ScaleY = "ScaleY"; -static const char * k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; -static const char * k_pch_Keyboard_OffsetRightX = "OffsetRightX"; -static const char * k_pch_Keyboard_OffsetY = "OffsetY"; -static const char * k_pch_Keyboard_Smoothing = "Smoothing"; -static const char * k_pch_Perf_Section = "perfcheck"; -static const char * k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; -static const char * k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; -static const char * k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; -static const char * k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; -static const char * k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; -static const char * k_pch_Perf_TestData_Float = "perfTestData"; -static const char * k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; -static const char * k_pch_CollisionBounds_Section = "collisionBounds"; -static const char * k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; -static const char * k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; -static const char * k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; -static const char * k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; -static const char * k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; -static const char * k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; -static const char * k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; -static const char * k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; -static const char * k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; -static const char * k_pch_Camera_Section = "camera"; -static const char * k_pch_Camera_EnableCamera_Bool = "enableCamera"; -static const char * k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; -static const char * k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; -static const char * k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; -static const char * k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; -static const char * k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; -static const char * k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; -static const char * k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; -static const char * k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; -static const char * k_pch_audio_Section = "audio"; -static const char * k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; -static const char * k_pch_audio_OnRecordDevice_String = "onRecordDevice"; -static const char * k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; -static const char * k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; -static const char * k_pch_audio_OffRecordDevice_String = "offRecordDevice"; -static const char * k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; -static const char * k_pch_Power_Section = "power"; -static const char * k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; -static const char * k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; -static const char * k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; -static const char * k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; -static const char * k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; -static const char * k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; -static const char * k_pch_Dashboard_Section = "dashboard"; -static const char * k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; -static const char * k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; -static const char * k_pch_modelskin_Section = "modelskins"; -static const char * k_pch_Driver_Enable_Bool = "enable"; -static const char * IVRScreenshots_Version = "IVRScreenshots_001"; -static const char * IVRResources_Version = "IVRResources_001"; -static const char * IVRDriverManager_Version = "IVRDriverManager_001"; +static const char *IVRSettings_Version = "IVRSettings_002"; +static const char *k_pch_SteamVR_Section = "steamvr"; +static const char *k_pch_SteamVR_RequireHmd_String = "requireHmd"; +static const char *k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; +static const char *k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; +static const char *k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; +static const char *k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; +static const char *k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; +static const char *k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; +static const char *k_pch_SteamVR_SendSystemButtonToAllApps_Bool = "sendSystemButtonToAllApps"; +static const char *k_pch_SteamVR_LogLevel_Int32 = "loglevel"; +static const char *k_pch_SteamVR_IPD_Float = "ipd"; +static const char *k_pch_SteamVR_Background_String = "background"; +static const char *k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; +static const char *k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; +static const char *k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; +static const char *k_pch_SteamVR_GridColor_String = "gridColor"; +static const char *k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; +static const char *k_pch_SteamVR_ShowStage_Bool = "showStage"; +static const char *k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; +static const char *k_pch_SteamVR_DirectMode_Bool = "directMode"; +static const char *k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; +static const char *k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; +static const char *k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; +static const char *k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; +static const char *k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; +static const char *k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; +static const char *k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; +static const char *k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; +static const char *k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; +static const char *k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; +static const char *k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; +static const char *k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; +static const char *k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; +static const char *k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; +static const char *k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; +static const char *k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; +static const char *k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; +static const char *k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; +static const char *k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; +static const char *k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; +static const char *k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; +static const char *k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; +static const char *k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; +static const char *k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; +static const char *k_pch_Lighthouse_Section = "driver_lighthouse"; +static const char *k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; +static const char *k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; +static const char *k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; +static const char *k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; +static const char *k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; +static const char *k_pch_Null_Section = "driver_null"; +static const char *k_pch_Null_SerialNumber_String = "serialNumber"; +static const char *k_pch_Null_ModelNumber_String = "modelNumber"; +static const char *k_pch_Null_WindowX_Int32 = "windowX"; +static const char *k_pch_Null_WindowY_Int32 = "windowY"; +static const char *k_pch_Null_WindowWidth_Int32 = "windowWidth"; +static const char *k_pch_Null_WindowHeight_Int32 = "windowHeight"; +static const char *k_pch_Null_RenderWidth_Int32 = "renderWidth"; +static const char *k_pch_Null_RenderHeight_Int32 = "renderHeight"; +static const char *k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; +static const char *k_pch_Null_DisplayFrequency_Float = "displayFrequency"; +static const char *k_pch_UserInterface_Section = "userinterface"; +static const char *k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; +static const char *k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; +static const char *k_pch_UserInterface_Screenshots_Bool = "screenshots"; +static const char *k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; +static const char *k_pch_Notifications_Section = "notifications"; +static const char *k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; +static const char *k_pch_Keyboard_Section = "keyboard"; +static const char *k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; +static const char *k_pch_Keyboard_ScaleX = "ScaleX"; +static const char *k_pch_Keyboard_ScaleY = "ScaleY"; +static const char *k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; +static const char *k_pch_Keyboard_OffsetRightX = "OffsetRightX"; +static const char *k_pch_Keyboard_OffsetY = "OffsetY"; +static const char *k_pch_Keyboard_Smoothing = "Smoothing"; +static const char *k_pch_Perf_Section = "perfcheck"; +static const char *k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; +static const char *k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; +static const char *k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; +static const char *k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; +static const char *k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; +static const char *k_pch_Perf_TestData_Float = "perfTestData"; +static const char *k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; +static const char *k_pch_CollisionBounds_Section = "collisionBounds"; +static const char *k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; +static const char *k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; +static const char *k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; +static const char *k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; +static const char *k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; +static const char *k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; +static const char *k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; +static const char *k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; +static const char *k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; +static const char *k_pch_Camera_Section = "camera"; +static const char *k_pch_Camera_EnableCamera_Bool = "enableCamera"; +static const char *k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; +static const char *k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; +static const char *k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; +static const char *k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; +static const char *k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; +static const char *k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; +static const char *k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; +static const char *k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; +static const char *k_pch_audio_Section = "audio"; +static const char *k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; +static const char *k_pch_audio_OnRecordDevice_String = "onRecordDevice"; +static const char *k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; +static const char *k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; +static const char *k_pch_audio_OffRecordDevice_String = "offRecordDevice"; +static const char *k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; +static const char *k_pch_Power_Section = "power"; +static const char *k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; +static const char *k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; +static const char *k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; +static const char *k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; +static const char *k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; +static const char *k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; +static const char *k_pch_Dashboard_Section = "dashboard"; +static const char *k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; +static const char *k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; +static const char *k_pch_modelskin_Section = "modelskins"; +static const char *k_pch_Driver_Enable_Bool = "enable"; +static const char *IVRScreenshots_Version = "IVRScreenshots_001"; +static const char *IVRResources_Version = "IVRResources_001"; +static const char *IVRDriverManager_Version = "IVRDriverManager_001"; // OpenVR Enums @@ -1062,14 +1061,13 @@ typedef enum EVRScreenshotError EVRScreenshotError_VRScreenshotError_ScreenshotAlreadyInProgress = 108, } EVRScreenshotError; - // OpenVR typedefs typedef uint32_t TrackedDeviceIndex_t; typedef uint32_t VRNotificationId; typedef uint64_t VROverlayHandle_t; -typedef void * glSharedTextureHandle_t; +typedef void *glSharedTextureHandle_t; typedef int32_t glInt_t; typedef uint32_t glUInt_t; typedef uint64_t SharedTextureHandle_t; @@ -1103,32 +1101,32 @@ typedef EVRScreenshotError VRScreenshotsError; typedef struct HmdMatrix34_t { - float m[3][4]; //float[3][4] + float m[3][4]; //float[3][4] } HmdMatrix34_t; typedef struct HmdMatrix44_t { - float m[4][4]; //float[4][4] + float m[4][4]; //float[4][4] } HmdMatrix44_t; typedef struct HmdVector3_t { - float v[3]; //float[3] + float v[3]; //float[3] } HmdVector3_t; typedef struct HmdVector4_t { - float v[4]; //float[4] + float v[4]; //float[4] } HmdVector4_t; typedef struct HmdVector3d_t { - double v[3]; //double[3] + double v[3]; //double[3] } HmdVector3d_t; typedef struct HmdVector2_t { - float v[2]; //float[2] + float v[2]; //float[2] } HmdVector2_t; typedef struct HmdQuaternion_t @@ -1149,7 +1147,7 @@ typedef struct HmdColor_t typedef struct HmdQuad_t { - struct HmdVector3_t vCorners[4]; //struct vr::HmdVector3_t[4] + struct HmdVector3_t vCorners[4]; //struct vr::HmdVector3_t[4] } HmdQuad_t; typedef struct HmdRect2_t @@ -1160,14 +1158,14 @@ typedef struct HmdRect2_t typedef struct DistortionCoordinates_t { - float rfRed[2]; //float[2] - float rfGreen[2]; //float[2] - float rfBlue[2]; //float[2] + float rfRed[2]; //float[2] + float rfGreen[2]; //float[2] + float rfBlue[2]; //float[2] } DistortionCoordinates_t; typedef struct Texture_t { - void * handle; // void * + void *handle; // void * enum ETextureType eType; enum EColorSpace eColorSpace; } Texture_t; @@ -1198,10 +1196,10 @@ typedef struct VRTextureWithPose_t typedef struct VRVulkanTextureData_t { uint64_t m_nImage; - struct VkDevice_T * m_pDevice; // struct VkDevice_T * - struct VkPhysicalDevice_T * m_pPhysicalDevice; // struct VkPhysicalDevice_T * - struct VkInstance_T * m_pInstance; // struct VkInstance_T * - struct VkQueue_T * m_pQueue; // struct VkQueue_T * + struct VkDevice_T *m_pDevice; // struct VkDevice_T * + struct VkPhysicalDevice_T *m_pPhysicalDevice; // struct VkPhysicalDevice_T * + struct VkInstance_T *m_pInstance; // struct VkInstance_T * + struct VkQueue_T *m_pQueue; // struct VkQueue_T * uint32_t m_nQueueFamilyIndex; uint32_t m_nWidth; uint32_t m_nHeight; @@ -1211,8 +1209,8 @@ typedef struct VRVulkanTextureData_t typedef struct D3D12TextureData_t { - struct ID3D12Resource * m_pResource; // struct ID3D12Resource * - struct ID3D12CommandQueue * m_pCommandQueue; // struct ID3D12CommandQueue * + struct ID3D12Resource *m_pResource; // struct ID3D12Resource * + struct ID3D12CommandQueue *m_pCommandQueue; // struct ID3D12CommandQueue * uint32_t m_nNodeMask; } D3D12TextureData_t; @@ -1270,7 +1268,7 @@ typedef struct VREvent_Status_t typedef struct VREvent_Keyboard_t { - char * cNewInput[8]; //char[8] + char *cNewInput[8]; //char[8] uint64_t uUserValue; } VREvent_Keyboard_t; @@ -1337,7 +1335,7 @@ typedef struct VREvent_Property_t typedef struct HiddenAreaMesh_t { - struct HmdVector2_t * pVertexData; // const struct vr::HmdVector2_t * + struct HmdVector2_t *pVertexData; // const struct vr::HmdVector2_t * uint32_t unTriangleCount; } HiddenAreaMesh_t; @@ -1352,7 +1350,7 @@ typedef struct VRControllerState_t uint32_t unPacketNum; uint64_t ulButtonPressed; uint64_t ulButtonTouched; - struct VRControllerAxis_t rAxis[5]; //struct vr::VRControllerAxis_t[5] + struct VRControllerAxis_t rAxis[5]; //struct vr::VRControllerAxis_t[5] } VRControllerState_t; typedef struct Compositor_OverlaySettings @@ -1385,8 +1383,8 @@ typedef struct CameraVideoStreamFrameHeader_t typedef struct AppOverrideKeys_t { - char * pchKey; // const char * - char * pchValue; // const char * + char *pchKey; // const char * + char *pchValue; // const char * } AppOverrideKeys_t; typedef struct Compositor_FrameTiming @@ -1477,36 +1475,36 @@ typedef struct RenderModel_Vertex_t { struct HmdVector3_t vPosition; struct HmdVector3_t vNormal; - float rfTextureCoord[2]; //float[2] + float rfTextureCoord[2]; //float[2] } RenderModel_Vertex_t; #if defined(__linux__) || defined(__APPLE__) -#pragma pack( push, 4 ) +#pragma pack(push, 4) #endif typedef struct RenderModel_TextureMap_t { uint16_t unWidth; uint16_t unHeight; - uint8_t * rubTextureMapData; // const uint8_t * + uint8_t *rubTextureMapData; // const uint8_t * } RenderModel_TextureMap_t; #if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#pragma pack(pop) #endif #if defined(__linux__) || defined(__APPLE__) -#pragma pack( push, 4 ) +#pragma pack(push, 4) #endif typedef struct RenderModel_t { - struct RenderModel_Vertex_t * rVertexData; // const struct vr::RenderModel_Vertex_t * + struct RenderModel_Vertex_t *rVertexData; // const struct vr::RenderModel_Vertex_t * uint32_t unVertexCount; - uint16_t * rIndexData; // const uint16_t * + uint16_t *rIndexData; // const uint16_t * uint32_t unTriangleCount; TextureID_t diffuseTextureId; } RenderModel_t; #if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#pragma pack(pop) #endif typedef struct RenderModel_ControllerMode_State_t { @@ -1515,7 +1513,7 @@ typedef struct RenderModel_ControllerMode_State_t typedef struct NotificationBitmap_t { - void * m_pImageData; // void * + void *m_pImageData; // void * int32_t m_nWidth; int32_t m_nHeight; int32_t m_nBytesPerPixel; @@ -1523,24 +1521,22 @@ typedef struct NotificationBitmap_t typedef struct COpenVRContext { - intptr_t m_pVRSystem; // class vr::IVRSystem * - intptr_t m_pVRChaperone; // class vr::IVRChaperone * - intptr_t m_pVRChaperoneSetup; // class vr::IVRChaperoneSetup * - intptr_t m_pVRCompositor; // class vr::IVRCompositor * - intptr_t m_pVROverlay; // class vr::IVROverlay * - intptr_t m_pVRResources; // class vr::IVRResources * - intptr_t m_pVRRenderModels; // class vr::IVRRenderModels * - intptr_t m_pVRExtendedDisplay; // class vr::IVRExtendedDisplay * - intptr_t m_pVRSettings; // class vr::IVRSettings * - intptr_t m_pVRApplications; // class vr::IVRApplications * - intptr_t m_pVRTrackedCamera; // class vr::IVRTrackedCamera * - intptr_t m_pVRScreenshots; // class vr::IVRScreenshots * - intptr_t m_pVRDriverManager; // class vr::IVRDriverManager * + intptr_t m_pVRSystem; // class vr::IVRSystem * + intptr_t m_pVRChaperone; // class vr::IVRChaperone * + intptr_t m_pVRChaperoneSetup; // class vr::IVRChaperoneSetup * + intptr_t m_pVRCompositor; // class vr::IVRCompositor * + intptr_t m_pVROverlay; // class vr::IVROverlay * + intptr_t m_pVRResources; // class vr::IVRResources * + intptr_t m_pVRRenderModels; // class vr::IVRRenderModels * + intptr_t m_pVRExtendedDisplay; // class vr::IVRExtendedDisplay * + intptr_t m_pVRSettings; // class vr::IVRSettings * + intptr_t m_pVRApplications; // class vr::IVRApplications * + intptr_t m_pVRTrackedCamera; // class vr::IVRTrackedCamera * + intptr_t m_pVRScreenshots; // class vr::IVRScreenshots * + intptr_t m_pVRDriverManager; // class vr::IVRDriverManager * } COpenVRContext; - -typedef union -{ +typedef union { VREvent_Reserved_t reserved; VREvent_Controller_t controller; VREvent_Mouse_t mouse; @@ -1560,16 +1556,14 @@ typedef union /** An event posted by the server to all running applications */ struct VREvent_t { - uint32_t eventType; // EVREventType enum + uint32_t eventType; // EVREventType enum TrackedDeviceIndex_t trackedDeviceIndex; float eventAgeSeconds; // event data must be the end of the struct as its size is variable VREvent_Data_t data; }; - -typedef union -{ +typedef union { IntersectionMaskRectangle_t m_Rectangle; IntersectionMaskCircle_t m_Circle; } VROverlayIntersectionMaskPrimitive_Data_t; @@ -1580,352 +1574,350 @@ struct VROverlayIntersectionMaskPrimitive_t VROverlayIntersectionMaskPrimitive_Data_t m_Primitive; }; - // OpenVR Function Pointer Tables struct VR_IVRSystem_FnTable { - void (OPENVR_FNTABLE_CALLTYPE *GetRecommendedRenderTargetSize)(uint32_t * pnWidth, uint32_t * pnHeight); - struct HmdMatrix44_t (OPENVR_FNTABLE_CALLTYPE *GetProjectionMatrix)(EVREye eEye, float fNearZ, float fFarZ); - void (OPENVR_FNTABLE_CALLTYPE *GetProjectionRaw)(EVREye eEye, float * pfLeft, float * pfRight, float * pfTop, float * pfBottom); - bool (OPENVR_FNTABLE_CALLTYPE *ComputeDistortion)(EVREye eEye, float fU, float fV, struct DistortionCoordinates_t * pDistortionCoordinates); - struct HmdMatrix34_t (OPENVR_FNTABLE_CALLTYPE *GetEyeToHeadTransform)(EVREye eEye); - bool (OPENVR_FNTABLE_CALLTYPE *GetTimeSinceLastVsync)(float * pfSecondsSinceLastVsync, uint64_t * pulFrameCounter); - int32_t (OPENVR_FNTABLE_CALLTYPE *GetD3D9AdapterIndex)(); - void (OPENVR_FNTABLE_CALLTYPE *GetDXGIOutputInfo)(int32_t * pnAdapterIndex); - void (OPENVR_FNTABLE_CALLTYPE *GetOutputDevice)(uint64_t * pnDevice, ETextureType textureType, struct VkInstance_T * pInstance); - bool (OPENVR_FNTABLE_CALLTYPE *IsDisplayOnDesktop)(); - bool (OPENVR_FNTABLE_CALLTYPE *SetDisplayVisibility)(bool bIsVisibleOnDesktop); - void (OPENVR_FNTABLE_CALLTYPE *GetDeviceToAbsoluteTrackingPose)(ETrackingUniverseOrigin eOrigin, float fPredictedSecondsToPhotonsFromNow, struct TrackedDevicePose_t * pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount); - void (OPENVR_FNTABLE_CALLTYPE *ResetSeatedZeroPose)(); - struct HmdMatrix34_t (OPENVR_FNTABLE_CALLTYPE *GetSeatedZeroPoseToStandingAbsoluteTrackingPose)(); - struct HmdMatrix34_t (OPENVR_FNTABLE_CALLTYPE *GetRawZeroPoseToStandingAbsoluteTrackingPose)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetSortedTrackedDeviceIndicesOfClass)(ETrackedDeviceClass eTrackedDeviceClass, TrackedDeviceIndex_t * punTrackedDeviceIndexArray, uint32_t unTrackedDeviceIndexArrayCount, TrackedDeviceIndex_t unRelativeToTrackedDeviceIndex); - EDeviceActivityLevel (OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceActivityLevel)(TrackedDeviceIndex_t unDeviceId); - void (OPENVR_FNTABLE_CALLTYPE *ApplyTransform)(struct TrackedDevicePose_t * pOutputPose, struct TrackedDevicePose_t * pTrackedDevicePose, struct HmdMatrix34_t * pTransform); - TrackedDeviceIndex_t (OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceIndexForControllerRole)(ETrackedControllerRole unDeviceType); - ETrackedControllerRole (OPENVR_FNTABLE_CALLTYPE *GetControllerRoleForTrackedDeviceIndex)(TrackedDeviceIndex_t unDeviceIndex); - ETrackedDeviceClass (OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceClass)(TrackedDeviceIndex_t unDeviceIndex); - bool (OPENVR_FNTABLE_CALLTYPE *IsTrackedDeviceConnected)(TrackedDeviceIndex_t unDeviceIndex); - bool (OPENVR_FNTABLE_CALLTYPE *GetBoolTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); - float (OPENVR_FNTABLE_CALLTYPE *GetFloatTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); - int32_t (OPENVR_FNTABLE_CALLTYPE *GetInt32TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); - uint64_t (OPENVR_FNTABLE_CALLTYPE *GetUint64TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); - struct HmdMatrix34_t (OPENVR_FNTABLE_CALLTYPE *GetMatrix34TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetStringTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, char * pchValue, uint32_t unBufferSize, ETrackedPropertyError * pError); - char * (OPENVR_FNTABLE_CALLTYPE *GetPropErrorNameFromEnum)(ETrackedPropertyError error); - bool (OPENVR_FNTABLE_CALLTYPE *PollNextEvent)(struct VREvent_t * pEvent, uint32_t uncbVREvent); - bool (OPENVR_FNTABLE_CALLTYPE *PollNextEventWithPose)(ETrackingUniverseOrigin eOrigin, struct VREvent_t * pEvent, uint32_t uncbVREvent, TrackedDevicePose_t * pTrackedDevicePose); - char * (OPENVR_FNTABLE_CALLTYPE *GetEventTypeNameFromEnum)(EVREventType eType); - struct HiddenAreaMesh_t (OPENVR_FNTABLE_CALLTYPE *GetHiddenAreaMesh)(EVREye eEye, EHiddenAreaMeshType type); - bool (OPENVR_FNTABLE_CALLTYPE *GetControllerState)(TrackedDeviceIndex_t unControllerDeviceIndex, VRControllerState_t * pControllerState, uint32_t unControllerStateSize); - bool (OPENVR_FNTABLE_CALLTYPE *GetControllerStateWithPose)(ETrackingUniverseOrigin eOrigin, TrackedDeviceIndex_t unControllerDeviceIndex, VRControllerState_t * pControllerState, uint32_t unControllerStateSize, struct TrackedDevicePose_t * pTrackedDevicePose); - void (OPENVR_FNTABLE_CALLTYPE *TriggerHapticPulse)(TrackedDeviceIndex_t unControllerDeviceIndex, uint32_t unAxisId, unsigned short usDurationMicroSec); - char * (OPENVR_FNTABLE_CALLTYPE *GetButtonIdNameFromEnum)(EVRButtonId eButtonId); - char * (OPENVR_FNTABLE_CALLTYPE *GetControllerAxisTypeNameFromEnum)(EVRControllerAxisType eAxisType); - bool (OPENVR_FNTABLE_CALLTYPE *CaptureInputFocus)(); - void (OPENVR_FNTABLE_CALLTYPE *ReleaseInputFocus)(); - bool (OPENVR_FNTABLE_CALLTYPE *IsInputFocusCapturedByAnotherProcess)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *DriverDebugRequest)(TrackedDeviceIndex_t unDeviceIndex, char * pchRequest, char * pchResponseBuffer, uint32_t unResponseBufferSize); - EVRFirmwareError (OPENVR_FNTABLE_CALLTYPE *PerformFirmwareUpdate)(TrackedDeviceIndex_t unDeviceIndex); - void (OPENVR_FNTABLE_CALLTYPE *AcknowledgeQuit_Exiting)(); - void (OPENVR_FNTABLE_CALLTYPE *AcknowledgeQuit_UserPrompt)(); + void(OPENVR_FNTABLE_CALLTYPE *GetRecommendedRenderTargetSize)(uint32_t *pnWidth, uint32_t *pnHeight); + struct HmdMatrix44_t(OPENVR_FNTABLE_CALLTYPE *GetProjectionMatrix)(EVREye eEye, float fNearZ, float fFarZ); + void(OPENVR_FNTABLE_CALLTYPE *GetProjectionRaw)(EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom); + bool(OPENVR_FNTABLE_CALLTYPE *ComputeDistortion)(EVREye eEye, float fU, float fV, struct DistortionCoordinates_t *pDistortionCoordinates); + struct HmdMatrix34_t(OPENVR_FNTABLE_CALLTYPE *GetEyeToHeadTransform)(EVREye eEye); + bool(OPENVR_FNTABLE_CALLTYPE *GetTimeSinceLastVsync)(float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter); + int32_t(OPENVR_FNTABLE_CALLTYPE *GetD3D9AdapterIndex)(); + void(OPENVR_FNTABLE_CALLTYPE *GetDXGIOutputInfo)(int32_t *pnAdapterIndex); + void(OPENVR_FNTABLE_CALLTYPE *GetOutputDevice)(uint64_t *pnDevice, ETextureType textureType, struct VkInstance_T *pInstance); + bool(OPENVR_FNTABLE_CALLTYPE *IsDisplayOnDesktop)(); + bool(OPENVR_FNTABLE_CALLTYPE *SetDisplayVisibility)(bool bIsVisibleOnDesktop); + void(OPENVR_FNTABLE_CALLTYPE *GetDeviceToAbsoluteTrackingPose)(ETrackingUniverseOrigin eOrigin, float fPredictedSecondsToPhotonsFromNow, struct TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount); + void(OPENVR_FNTABLE_CALLTYPE *ResetSeatedZeroPose)(); + struct HmdMatrix34_t(OPENVR_FNTABLE_CALLTYPE *GetSeatedZeroPoseToStandingAbsoluteTrackingPose)(); + struct HmdMatrix34_t(OPENVR_FNTABLE_CALLTYPE *GetRawZeroPoseToStandingAbsoluteTrackingPose)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetSortedTrackedDeviceIndicesOfClass)(ETrackedDeviceClass eTrackedDeviceClass, TrackedDeviceIndex_t *punTrackedDeviceIndexArray, uint32_t unTrackedDeviceIndexArrayCount, TrackedDeviceIndex_t unRelativeToTrackedDeviceIndex); + EDeviceActivityLevel(OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceActivityLevel)(TrackedDeviceIndex_t unDeviceId); + void(OPENVR_FNTABLE_CALLTYPE *ApplyTransform)(struct TrackedDevicePose_t *pOutputPose, struct TrackedDevicePose_t *pTrackedDevicePose, struct HmdMatrix34_t *pTransform); + TrackedDeviceIndex_t(OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceIndexForControllerRole)(ETrackedControllerRole unDeviceType); + ETrackedControllerRole(OPENVR_FNTABLE_CALLTYPE *GetControllerRoleForTrackedDeviceIndex)(TrackedDeviceIndex_t unDeviceIndex); + ETrackedDeviceClass(OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceClass)(TrackedDeviceIndex_t unDeviceIndex); + bool(OPENVR_FNTABLE_CALLTYPE *IsTrackedDeviceConnected)(TrackedDeviceIndex_t unDeviceIndex); + bool(OPENVR_FNTABLE_CALLTYPE *GetBoolTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError); + float(OPENVR_FNTABLE_CALLTYPE *GetFloatTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError); + int32_t(OPENVR_FNTABLE_CALLTYPE *GetInt32TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError); + uint64_t(OPENVR_FNTABLE_CALLTYPE *GetUint64TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError); + struct HmdMatrix34_t(OPENVR_FNTABLE_CALLTYPE *GetMatrix34TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetStringTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError); + char *(OPENVR_FNTABLE_CALLTYPE *GetPropErrorNameFromEnum)(ETrackedPropertyError error); + bool(OPENVR_FNTABLE_CALLTYPE *PollNextEvent)(struct VREvent_t *pEvent, uint32_t uncbVREvent); + bool(OPENVR_FNTABLE_CALLTYPE *PollNextEventWithPose)(ETrackingUniverseOrigin eOrigin, struct VREvent_t *pEvent, uint32_t uncbVREvent, TrackedDevicePose_t *pTrackedDevicePose); + char *(OPENVR_FNTABLE_CALLTYPE *GetEventTypeNameFromEnum)(EVREventType eType); + struct HiddenAreaMesh_t(OPENVR_FNTABLE_CALLTYPE *GetHiddenAreaMesh)(EVREye eEye, EHiddenAreaMeshType type); + bool(OPENVR_FNTABLE_CALLTYPE *GetControllerState)(TrackedDeviceIndex_t unControllerDeviceIndex, VRControllerState_t *pControllerState, uint32_t unControllerStateSize); + bool(OPENVR_FNTABLE_CALLTYPE *GetControllerStateWithPose)(ETrackingUniverseOrigin eOrigin, TrackedDeviceIndex_t unControllerDeviceIndex, VRControllerState_t *pControllerState, uint32_t unControllerStateSize, struct TrackedDevicePose_t *pTrackedDevicePose); + void(OPENVR_FNTABLE_CALLTYPE *TriggerHapticPulse)(TrackedDeviceIndex_t unControllerDeviceIndex, uint32_t unAxisId, unsigned short usDurationMicroSec); + char *(OPENVR_FNTABLE_CALLTYPE *GetButtonIdNameFromEnum)(EVRButtonId eButtonId); + char *(OPENVR_FNTABLE_CALLTYPE *GetControllerAxisTypeNameFromEnum)(EVRControllerAxisType eAxisType); + bool(OPENVR_FNTABLE_CALLTYPE *CaptureInputFocus)(); + void(OPENVR_FNTABLE_CALLTYPE *ReleaseInputFocus)(); + bool(OPENVR_FNTABLE_CALLTYPE *IsInputFocusCapturedByAnotherProcess)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *DriverDebugRequest)(TrackedDeviceIndex_t unDeviceIndex, char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize); + EVRFirmwareError(OPENVR_FNTABLE_CALLTYPE *PerformFirmwareUpdate)(TrackedDeviceIndex_t unDeviceIndex); + void(OPENVR_FNTABLE_CALLTYPE *AcknowledgeQuit_Exiting)(); + void(OPENVR_FNTABLE_CALLTYPE *AcknowledgeQuit_UserPrompt)(); }; struct VR_IVRExtendedDisplay_FnTable { - void (OPENVR_FNTABLE_CALLTYPE *GetWindowBounds)(int32_t * pnX, int32_t * pnY, uint32_t * pnWidth, uint32_t * pnHeight); - void (OPENVR_FNTABLE_CALLTYPE *GetEyeOutputViewport)(EVREye eEye, uint32_t * pnX, uint32_t * pnY, uint32_t * pnWidth, uint32_t * pnHeight); - void (OPENVR_FNTABLE_CALLTYPE *GetDXGIOutputInfo)(int32_t * pnAdapterIndex, int32_t * pnAdapterOutputIndex); + void(OPENVR_FNTABLE_CALLTYPE *GetWindowBounds)(int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight); + void(OPENVR_FNTABLE_CALLTYPE *GetEyeOutputViewport)(EVREye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight); + void(OPENVR_FNTABLE_CALLTYPE *GetDXGIOutputInfo)(int32_t *pnAdapterIndex, int32_t *pnAdapterOutputIndex); }; struct VR_IVRTrackedCamera_FnTable { - char * (OPENVR_FNTABLE_CALLTYPE *GetCameraErrorNameFromEnum)(EVRTrackedCameraError eCameraError); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *HasCamera)(TrackedDeviceIndex_t nDeviceIndex, bool * pHasCamera); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetCameraFrameSize)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, uint32_t * pnWidth, uint32_t * pnHeight, uint32_t * pnFrameBufferSize); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetCameraIntrinsics)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, HmdVector2_t * pFocalLength, HmdVector2_t * pCenter); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetCameraProjection)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, HmdMatrix44_t * pProjection); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *AcquireVideoStreamingService)(TrackedDeviceIndex_t nDeviceIndex, TrackedCameraHandle_t * pHandle); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *ReleaseVideoStreamingService)(TrackedCameraHandle_t hTrackedCamera); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetVideoStreamFrameBuffer)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, void * pFrameBuffer, uint32_t nFrameBufferSize, CameraVideoStreamFrameHeader_t * pFrameHeader, uint32_t nFrameHeaderSize); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureSize)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, VRTextureBounds_t * pTextureBounds, uint32_t * pnWidth, uint32_t * pnHeight); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureD3D11)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, void * pD3D11DeviceOrResource, void ** ppD3D11ShaderResourceView, CameraVideoStreamFrameHeader_t * pFrameHeader, uint32_t nFrameHeaderSize); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureGL)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, glUInt_t * pglTextureId, CameraVideoStreamFrameHeader_t * pFrameHeader, uint32_t nFrameHeaderSize); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *ReleaseVideoStreamTextureGL)(TrackedCameraHandle_t hTrackedCamera, glUInt_t glTextureId); + char *(OPENVR_FNTABLE_CALLTYPE *GetCameraErrorNameFromEnum)(EVRTrackedCameraError eCameraError); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *HasCamera)(TrackedDeviceIndex_t nDeviceIndex, bool *pHasCamera); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetCameraFrameSize)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, uint32_t *pnWidth, uint32_t *pnHeight, uint32_t *pnFrameBufferSize); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetCameraIntrinsics)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, HmdVector2_t *pFocalLength, HmdVector2_t *pCenter); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetCameraProjection)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, HmdMatrix44_t *pProjection); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *AcquireVideoStreamingService)(TrackedDeviceIndex_t nDeviceIndex, TrackedCameraHandle_t *pHandle); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *ReleaseVideoStreamingService)(TrackedCameraHandle_t hTrackedCamera); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetVideoStreamFrameBuffer)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, void *pFrameBuffer, uint32_t nFrameBufferSize, CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureSize)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, VRTextureBounds_t *pTextureBounds, uint32_t *pnWidth, uint32_t *pnHeight); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureD3D11)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView, CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureGL)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, glUInt_t *pglTextureId, CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *ReleaseVideoStreamTextureGL)(TrackedCameraHandle_t hTrackedCamera, glUInt_t glTextureId); }; struct VR_IVRApplications_FnTable { - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *AddApplicationManifest)(char * pchApplicationManifestFullPath, bool bTemporary); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *RemoveApplicationManifest)(char * pchApplicationManifestFullPath); - bool (OPENVR_FNTABLE_CALLTYPE *IsApplicationInstalled)(char * pchAppKey); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationCount)(); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *GetApplicationKeyByIndex)(uint32_t unApplicationIndex, char * pchAppKeyBuffer, uint32_t unAppKeyBufferLen); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *GetApplicationKeyByProcessId)(uint32_t unProcessId, char * pchAppKeyBuffer, uint32_t unAppKeyBufferLen); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchApplication)(char * pchAppKey); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchTemplateApplication)(char * pchTemplateAppKey, char * pchNewAppKey, struct AppOverrideKeys_t * pKeys, uint32_t unKeys); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchApplicationFromMimeType)(char * pchMimeType, char * pchArgs); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchDashboardOverlay)(char * pchAppKey); - bool (OPENVR_FNTABLE_CALLTYPE *CancelApplicationLaunch)(char * pchAppKey); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *IdentifyApplication)(uint32_t unProcessId, char * pchAppKey); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationProcessId)(char * pchAppKey); - char * (OPENVR_FNTABLE_CALLTYPE *GetApplicationsErrorNameFromEnum)(EVRApplicationError error); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyString)(char * pchAppKey, EVRApplicationProperty eProperty, char * pchPropertyValueBuffer, uint32_t unPropertyValueBufferLen, EVRApplicationError * peError); - bool (OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyBool)(char * pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError * peError); - uint64_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyUint64)(char * pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError * peError); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *SetApplicationAutoLaunch)(char * pchAppKey, bool bAutoLaunch); - bool (OPENVR_FNTABLE_CALLTYPE *GetApplicationAutoLaunch)(char * pchAppKey); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *SetDefaultApplicationForMimeType)(char * pchAppKey, char * pchMimeType); - bool (OPENVR_FNTABLE_CALLTYPE *GetDefaultApplicationForMimeType)(char * pchMimeType, char * pchAppKeyBuffer, uint32_t unAppKeyBufferLen); - bool (OPENVR_FNTABLE_CALLTYPE *GetApplicationSupportedMimeTypes)(char * pchAppKey, char * pchMimeTypesBuffer, uint32_t unMimeTypesBuffer); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationsThatSupportMimeType)(char * pchMimeType, char * pchAppKeysThatSupportBuffer, uint32_t unAppKeysThatSupportBuffer); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationLaunchArguments)(uint32_t unHandle, char * pchArgs, uint32_t unArgs); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *GetStartingApplication)(char * pchAppKeyBuffer, uint32_t unAppKeyBufferLen); - EVRApplicationTransitionState (OPENVR_FNTABLE_CALLTYPE *GetTransitionState)(); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *PerformApplicationPrelaunchCheck)(char * pchAppKey); - char * (OPENVR_FNTABLE_CALLTYPE *GetApplicationsTransitionStateNameFromEnum)(EVRApplicationTransitionState state); - bool (OPENVR_FNTABLE_CALLTYPE *IsQuitUserPromptRequested)(); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchInternalProcess)(char * pchBinaryPath, char * pchArguments, char * pchWorkingDirectory); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetCurrentSceneProcessId)(); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *AddApplicationManifest)(char *pchApplicationManifestFullPath, bool bTemporary); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *RemoveApplicationManifest)(char *pchApplicationManifestFullPath); + bool(OPENVR_FNTABLE_CALLTYPE *IsApplicationInstalled)(char *pchAppKey); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationCount)(); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *GetApplicationKeyByIndex)(uint32_t unApplicationIndex, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *GetApplicationKeyByProcessId)(uint32_t unProcessId, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *LaunchApplication)(char *pchAppKey); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *LaunchTemplateApplication)(char *pchTemplateAppKey, char *pchNewAppKey, struct AppOverrideKeys_t *pKeys, uint32_t unKeys); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *LaunchApplicationFromMimeType)(char *pchMimeType, char *pchArgs); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *LaunchDashboardOverlay)(char *pchAppKey); + bool(OPENVR_FNTABLE_CALLTYPE *CancelApplicationLaunch)(char *pchAppKey); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *IdentifyApplication)(uint32_t unProcessId, char *pchAppKey); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationProcessId)(char *pchAppKey); + char *(OPENVR_FNTABLE_CALLTYPE *GetApplicationsErrorNameFromEnum)(EVRApplicationError error); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyString)(char *pchAppKey, EVRApplicationProperty eProperty, char *pchPropertyValueBuffer, uint32_t unPropertyValueBufferLen, EVRApplicationError *peError); + bool(OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyBool)(char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError); + uint64_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyUint64)(char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *SetApplicationAutoLaunch)(char *pchAppKey, bool bAutoLaunch); + bool(OPENVR_FNTABLE_CALLTYPE *GetApplicationAutoLaunch)(char *pchAppKey); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *SetDefaultApplicationForMimeType)(char *pchAppKey, char *pchMimeType); + bool(OPENVR_FNTABLE_CALLTYPE *GetDefaultApplicationForMimeType)(char *pchMimeType, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen); + bool(OPENVR_FNTABLE_CALLTYPE *GetApplicationSupportedMimeTypes)(char *pchAppKey, char *pchMimeTypesBuffer, uint32_t unMimeTypesBuffer); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationsThatSupportMimeType)(char *pchMimeType, char *pchAppKeysThatSupportBuffer, uint32_t unAppKeysThatSupportBuffer); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationLaunchArguments)(uint32_t unHandle, char *pchArgs, uint32_t unArgs); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *GetStartingApplication)(char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen); + EVRApplicationTransitionState(OPENVR_FNTABLE_CALLTYPE *GetTransitionState)(); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *PerformApplicationPrelaunchCheck)(char *pchAppKey); + char *(OPENVR_FNTABLE_CALLTYPE *GetApplicationsTransitionStateNameFromEnum)(EVRApplicationTransitionState state); + bool(OPENVR_FNTABLE_CALLTYPE *IsQuitUserPromptRequested)(); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *LaunchInternalProcess)(char *pchBinaryPath, char *pchArguments, char *pchWorkingDirectory); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetCurrentSceneProcessId)(); }; struct VR_IVRChaperone_FnTable { - ChaperoneCalibrationState (OPENVR_FNTABLE_CALLTYPE *GetCalibrationState)(); - bool (OPENVR_FNTABLE_CALLTYPE *GetPlayAreaSize)(float * pSizeX, float * pSizeZ); - bool (OPENVR_FNTABLE_CALLTYPE *GetPlayAreaRect)(struct HmdQuad_t * rect); - void (OPENVR_FNTABLE_CALLTYPE *ReloadInfo)(); - void (OPENVR_FNTABLE_CALLTYPE *SetSceneColor)(struct HmdColor_t color); - void (OPENVR_FNTABLE_CALLTYPE *GetBoundsColor)(struct HmdColor_t * pOutputColorArray, int nNumOutputColors, float flCollisionBoundsFadeDistance, struct HmdColor_t * pOutputCameraColor); - bool (OPENVR_FNTABLE_CALLTYPE *AreBoundsVisible)(); - void (OPENVR_FNTABLE_CALLTYPE *ForceBoundsVisible)(bool bForce); + ChaperoneCalibrationState(OPENVR_FNTABLE_CALLTYPE *GetCalibrationState)(); + bool(OPENVR_FNTABLE_CALLTYPE *GetPlayAreaSize)(float *pSizeX, float *pSizeZ); + bool(OPENVR_FNTABLE_CALLTYPE *GetPlayAreaRect)(struct HmdQuad_t *rect); + void(OPENVR_FNTABLE_CALLTYPE *ReloadInfo)(); + void(OPENVR_FNTABLE_CALLTYPE *SetSceneColor)(struct HmdColor_t color); + void(OPENVR_FNTABLE_CALLTYPE *GetBoundsColor)(struct HmdColor_t *pOutputColorArray, int nNumOutputColors, float flCollisionBoundsFadeDistance, struct HmdColor_t *pOutputCameraColor); + bool(OPENVR_FNTABLE_CALLTYPE *AreBoundsVisible)(); + void(OPENVR_FNTABLE_CALLTYPE *ForceBoundsVisible)(bool bForce); }; struct VR_IVRChaperoneSetup_FnTable { - bool (OPENVR_FNTABLE_CALLTYPE *CommitWorkingCopy)(EChaperoneConfigFile configFile); - void (OPENVR_FNTABLE_CALLTYPE *RevertWorkingCopy)(); - bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingPlayAreaSize)(float * pSizeX, float * pSizeZ); - bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingPlayAreaRect)(struct HmdQuad_t * rect); - bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingCollisionBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t * punQuadsCount); - bool (OPENVR_FNTABLE_CALLTYPE *GetLiveCollisionBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t * punQuadsCount); - bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pmatSeatedZeroPoseToRawTrackingPose); - bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingStandingZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pmatStandingZeroPoseToRawTrackingPose); - void (OPENVR_FNTABLE_CALLTYPE *SetWorkingPlayAreaSize)(float sizeX, float sizeZ); - void (OPENVR_FNTABLE_CALLTYPE *SetWorkingCollisionBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t unQuadsCount); - void (OPENVR_FNTABLE_CALLTYPE *SetWorkingSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pMatSeatedZeroPoseToRawTrackingPose); - void (OPENVR_FNTABLE_CALLTYPE *SetWorkingStandingZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pMatStandingZeroPoseToRawTrackingPose); - void (OPENVR_FNTABLE_CALLTYPE *ReloadFromDisk)(EChaperoneConfigFile configFile); - bool (OPENVR_FNTABLE_CALLTYPE *GetLiveSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pmatSeatedZeroPoseToRawTrackingPose); - void (OPENVR_FNTABLE_CALLTYPE *SetWorkingCollisionBoundsTagsInfo)(uint8_t * pTagsBuffer, uint32_t unTagCount); - bool (OPENVR_FNTABLE_CALLTYPE *GetLiveCollisionBoundsTagsInfo)(uint8_t * pTagsBuffer, uint32_t * punTagCount); - bool (OPENVR_FNTABLE_CALLTYPE *SetWorkingPhysicalBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t unQuadsCount); - bool (OPENVR_FNTABLE_CALLTYPE *GetLivePhysicalBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t * punQuadsCount); - bool (OPENVR_FNTABLE_CALLTYPE *ExportLiveToBuffer)(char * pBuffer, uint32_t * pnBufferLength); - bool (OPENVR_FNTABLE_CALLTYPE *ImportFromBufferToWorking)(char * pBuffer, uint32_t nImportFlags); + bool(OPENVR_FNTABLE_CALLTYPE *CommitWorkingCopy)(EChaperoneConfigFile configFile); + void(OPENVR_FNTABLE_CALLTYPE *RevertWorkingCopy)(); + bool(OPENVR_FNTABLE_CALLTYPE *GetWorkingPlayAreaSize)(float *pSizeX, float *pSizeZ); + bool(OPENVR_FNTABLE_CALLTYPE *GetWorkingPlayAreaRect)(struct HmdQuad_t *rect); + bool(OPENVR_FNTABLE_CALLTYPE *GetWorkingCollisionBoundsInfo)(struct HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount); + bool(OPENVR_FNTABLE_CALLTYPE *GetLiveCollisionBoundsInfo)(struct HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount); + bool(OPENVR_FNTABLE_CALLTYPE *GetWorkingSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose); + bool(OPENVR_FNTABLE_CALLTYPE *GetWorkingStandingZeroPoseToRawTrackingPose)(struct HmdMatrix34_t *pmatStandingZeroPoseToRawTrackingPose); + void(OPENVR_FNTABLE_CALLTYPE *SetWorkingPlayAreaSize)(float sizeX, float sizeZ); + void(OPENVR_FNTABLE_CALLTYPE *SetWorkingCollisionBoundsInfo)(struct HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount); + void(OPENVR_FNTABLE_CALLTYPE *SetWorkingSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t *pMatSeatedZeroPoseToRawTrackingPose); + void(OPENVR_FNTABLE_CALLTYPE *SetWorkingStandingZeroPoseToRawTrackingPose)(struct HmdMatrix34_t *pMatStandingZeroPoseToRawTrackingPose); + void(OPENVR_FNTABLE_CALLTYPE *ReloadFromDisk)(EChaperoneConfigFile configFile); + bool(OPENVR_FNTABLE_CALLTYPE *GetLiveSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose); + void(OPENVR_FNTABLE_CALLTYPE *SetWorkingCollisionBoundsTagsInfo)(uint8_t *pTagsBuffer, uint32_t unTagCount); + bool(OPENVR_FNTABLE_CALLTYPE *GetLiveCollisionBoundsTagsInfo)(uint8_t *pTagsBuffer, uint32_t *punTagCount); + bool(OPENVR_FNTABLE_CALLTYPE *SetWorkingPhysicalBoundsInfo)(struct HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount); + bool(OPENVR_FNTABLE_CALLTYPE *GetLivePhysicalBoundsInfo)(struct HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount); + bool(OPENVR_FNTABLE_CALLTYPE *ExportLiveToBuffer)(char *pBuffer, uint32_t *pnBufferLength); + bool(OPENVR_FNTABLE_CALLTYPE *ImportFromBufferToWorking)(char *pBuffer, uint32_t nImportFlags); }; struct VR_IVRCompositor_FnTable { - void (OPENVR_FNTABLE_CALLTYPE *SetTrackingSpace)(ETrackingUniverseOrigin eOrigin); - ETrackingUniverseOrigin (OPENVR_FNTABLE_CALLTYPE *GetTrackingSpace)(); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *WaitGetPoses)(struct TrackedDevicePose_t * pRenderPoseArray, uint32_t unRenderPoseArrayCount, struct TrackedDevicePose_t * pGamePoseArray, uint32_t unGamePoseArrayCount); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *GetLastPoses)(struct TrackedDevicePose_t * pRenderPoseArray, uint32_t unRenderPoseArrayCount, struct TrackedDevicePose_t * pGamePoseArray, uint32_t unGamePoseArrayCount); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *GetLastPoseForTrackedDeviceIndex)(TrackedDeviceIndex_t unDeviceIndex, struct TrackedDevicePose_t * pOutputPose, struct TrackedDevicePose_t * pOutputGamePose); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *Submit)(EVREye eEye, struct Texture_t * pTexture, struct VRTextureBounds_t * pBounds, EVRSubmitFlags nSubmitFlags); - void (OPENVR_FNTABLE_CALLTYPE *ClearLastSubmittedFrame)(); - void (OPENVR_FNTABLE_CALLTYPE *PostPresentHandoff)(); - bool (OPENVR_FNTABLE_CALLTYPE *GetFrameTiming)(struct Compositor_FrameTiming * pTiming, uint32_t unFramesAgo); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetFrameTimings)(struct Compositor_FrameTiming * pTiming, uint32_t nFrames); - float (OPENVR_FNTABLE_CALLTYPE *GetFrameTimeRemaining)(); - void (OPENVR_FNTABLE_CALLTYPE *GetCumulativeStats)(struct Compositor_CumulativeStats * pStats, uint32_t nStatsSizeInBytes); - void (OPENVR_FNTABLE_CALLTYPE *FadeToColor)(float fSeconds, float fRed, float fGreen, float fBlue, float fAlpha, bool bBackground); - struct HmdColor_t (OPENVR_FNTABLE_CALLTYPE *GetCurrentFadeColor)(bool bBackground); - void (OPENVR_FNTABLE_CALLTYPE *FadeGrid)(float fSeconds, bool bFadeIn); - float (OPENVR_FNTABLE_CALLTYPE *GetCurrentGridAlpha)(); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *SetSkyboxOverride)(struct Texture_t * pTextures, uint32_t unTextureCount); - void (OPENVR_FNTABLE_CALLTYPE *ClearSkyboxOverride)(); - void (OPENVR_FNTABLE_CALLTYPE *CompositorBringToFront)(); - void (OPENVR_FNTABLE_CALLTYPE *CompositorGoToBack)(); - void (OPENVR_FNTABLE_CALLTYPE *CompositorQuit)(); - bool (OPENVR_FNTABLE_CALLTYPE *IsFullscreen)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetCurrentSceneFocusProcess)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetLastFrameRenderer)(); - bool (OPENVR_FNTABLE_CALLTYPE *CanRenderScene)(); - void (OPENVR_FNTABLE_CALLTYPE *ShowMirrorWindow)(); - void (OPENVR_FNTABLE_CALLTYPE *HideMirrorWindow)(); - bool (OPENVR_FNTABLE_CALLTYPE *IsMirrorWindowVisible)(); - void (OPENVR_FNTABLE_CALLTYPE *CompositorDumpImages)(); - bool (OPENVR_FNTABLE_CALLTYPE *ShouldAppRenderWithLowResources)(); - void (OPENVR_FNTABLE_CALLTYPE *ForceInterleavedReprojectionOn)(bool bOverride); - void (OPENVR_FNTABLE_CALLTYPE *ForceReconnectProcess)(); - void (OPENVR_FNTABLE_CALLTYPE *SuspendRendering)(bool bSuspend); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *GetMirrorTextureD3D11)(EVREye eEye, void * pD3D11DeviceOrResource, void ** ppD3D11ShaderResourceView); - void (OPENVR_FNTABLE_CALLTYPE *ReleaseMirrorTextureD3D11)(void * pD3D11ShaderResourceView); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *GetMirrorTextureGL)(EVREye eEye, glUInt_t * pglTextureId, glSharedTextureHandle_t * pglSharedTextureHandle); - bool (OPENVR_FNTABLE_CALLTYPE *ReleaseSharedGLTexture)(glUInt_t glTextureId, glSharedTextureHandle_t glSharedTextureHandle); - void (OPENVR_FNTABLE_CALLTYPE *LockGLSharedTextureForAccess)(glSharedTextureHandle_t glSharedTextureHandle); - void (OPENVR_FNTABLE_CALLTYPE *UnlockGLSharedTextureForAccess)(glSharedTextureHandle_t glSharedTextureHandle); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetVulkanInstanceExtensionsRequired)(char * pchValue, uint32_t unBufferSize); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetVulkanDeviceExtensionsRequired)(struct VkPhysicalDevice_T * pPhysicalDevice, char * pchValue, uint32_t unBufferSize); - void (OPENVR_FNTABLE_CALLTYPE *SetExplicitTimingMode)(bool bExplicitTimingMode); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *SubmitExplicitTimingData)(); + void(OPENVR_FNTABLE_CALLTYPE *SetTrackingSpace)(ETrackingUniverseOrigin eOrigin); + ETrackingUniverseOrigin(OPENVR_FNTABLE_CALLTYPE *GetTrackingSpace)(); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *WaitGetPoses)(struct TrackedDevicePose_t *pRenderPoseArray, uint32_t unRenderPoseArrayCount, struct TrackedDevicePose_t *pGamePoseArray, uint32_t unGamePoseArrayCount); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *GetLastPoses)(struct TrackedDevicePose_t *pRenderPoseArray, uint32_t unRenderPoseArrayCount, struct TrackedDevicePose_t *pGamePoseArray, uint32_t unGamePoseArrayCount); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *GetLastPoseForTrackedDeviceIndex)(TrackedDeviceIndex_t unDeviceIndex, struct TrackedDevicePose_t *pOutputPose, struct TrackedDevicePose_t *pOutputGamePose); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *Submit)(EVREye eEye, struct Texture_t *pTexture, struct VRTextureBounds_t *pBounds, EVRSubmitFlags nSubmitFlags); + void(OPENVR_FNTABLE_CALLTYPE *ClearLastSubmittedFrame)(); + void(OPENVR_FNTABLE_CALLTYPE *PostPresentHandoff)(); + bool(OPENVR_FNTABLE_CALLTYPE *GetFrameTiming)(struct Compositor_FrameTiming *pTiming, uint32_t unFramesAgo); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetFrameTimings)(struct Compositor_FrameTiming *pTiming, uint32_t nFrames); + float(OPENVR_FNTABLE_CALLTYPE *GetFrameTimeRemaining)(); + void(OPENVR_FNTABLE_CALLTYPE *GetCumulativeStats)(struct Compositor_CumulativeStats *pStats, uint32_t nStatsSizeInBytes); + void(OPENVR_FNTABLE_CALLTYPE *FadeToColor)(float fSeconds, float fRed, float fGreen, float fBlue, float fAlpha, bool bBackground); + struct HmdColor_t(OPENVR_FNTABLE_CALLTYPE *GetCurrentFadeColor)(bool bBackground); + void(OPENVR_FNTABLE_CALLTYPE *FadeGrid)(float fSeconds, bool bFadeIn); + float(OPENVR_FNTABLE_CALLTYPE *GetCurrentGridAlpha)(); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *SetSkyboxOverride)(struct Texture_t *pTextures, uint32_t unTextureCount); + void(OPENVR_FNTABLE_CALLTYPE *ClearSkyboxOverride)(); + void(OPENVR_FNTABLE_CALLTYPE *CompositorBringToFront)(); + void(OPENVR_FNTABLE_CALLTYPE *CompositorGoToBack)(); + void(OPENVR_FNTABLE_CALLTYPE *CompositorQuit)(); + bool(OPENVR_FNTABLE_CALLTYPE *IsFullscreen)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetCurrentSceneFocusProcess)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetLastFrameRenderer)(); + bool(OPENVR_FNTABLE_CALLTYPE *CanRenderScene)(); + void(OPENVR_FNTABLE_CALLTYPE *ShowMirrorWindow)(); + void(OPENVR_FNTABLE_CALLTYPE *HideMirrorWindow)(); + bool(OPENVR_FNTABLE_CALLTYPE *IsMirrorWindowVisible)(); + void(OPENVR_FNTABLE_CALLTYPE *CompositorDumpImages)(); + bool(OPENVR_FNTABLE_CALLTYPE *ShouldAppRenderWithLowResources)(); + void(OPENVR_FNTABLE_CALLTYPE *ForceInterleavedReprojectionOn)(bool bOverride); + void(OPENVR_FNTABLE_CALLTYPE *ForceReconnectProcess)(); + void(OPENVR_FNTABLE_CALLTYPE *SuspendRendering)(bool bSuspend); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *GetMirrorTextureD3D11)(EVREye eEye, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView); + void(OPENVR_FNTABLE_CALLTYPE *ReleaseMirrorTextureD3D11)(void *pD3D11ShaderResourceView); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *GetMirrorTextureGL)(EVREye eEye, glUInt_t *pglTextureId, glSharedTextureHandle_t *pglSharedTextureHandle); + bool(OPENVR_FNTABLE_CALLTYPE *ReleaseSharedGLTexture)(glUInt_t glTextureId, glSharedTextureHandle_t glSharedTextureHandle); + void(OPENVR_FNTABLE_CALLTYPE *LockGLSharedTextureForAccess)(glSharedTextureHandle_t glSharedTextureHandle); + void(OPENVR_FNTABLE_CALLTYPE *UnlockGLSharedTextureForAccess)(glSharedTextureHandle_t glSharedTextureHandle); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetVulkanInstanceExtensionsRequired)(char *pchValue, uint32_t unBufferSize); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetVulkanDeviceExtensionsRequired)(struct VkPhysicalDevice_T *pPhysicalDevice, char *pchValue, uint32_t unBufferSize); + void(OPENVR_FNTABLE_CALLTYPE *SetExplicitTimingMode)(bool bExplicitTimingMode); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *SubmitExplicitTimingData)(); }; struct VR_IVROverlay_FnTable { - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *FindOverlay)(char * pchOverlayKey, VROverlayHandle_t * pOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *CreateOverlay)(char * pchOverlayKey, char * pchOverlayName, VROverlayHandle_t * pOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *DestroyOverlay)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetHighQualityOverlay)(VROverlayHandle_t ulOverlayHandle); - VROverlayHandle_t (OPENVR_FNTABLE_CALLTYPE *GetHighQualityOverlay)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayKey)(VROverlayHandle_t ulOverlayHandle, char * pchValue, uint32_t unBufferSize, EVROverlayError * pError); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayName)(VROverlayHandle_t ulOverlayHandle, char * pchValue, uint32_t unBufferSize, EVROverlayError * pError); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayName)(VROverlayHandle_t ulOverlayHandle, char * pchName); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayImageData)(VROverlayHandle_t ulOverlayHandle, void * pvBuffer, uint32_t unBufferSize, uint32_t * punWidth, uint32_t * punHeight); - char * (OPENVR_FNTABLE_CALLTYPE *GetOverlayErrorNameFromEnum)(EVROverlayError error); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayRenderingPid)(VROverlayHandle_t ulOverlayHandle, uint32_t unPID); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayRenderingPid)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayFlag)(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool bEnabled); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayFlag)(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool * pbEnabled); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayColor)(VROverlayHandle_t ulOverlayHandle, float fRed, float fGreen, float fBlue); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayColor)(VROverlayHandle_t ulOverlayHandle, float * pfRed, float * pfGreen, float * pfBlue); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayAlpha)(VROverlayHandle_t ulOverlayHandle, float fAlpha); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayAlpha)(VROverlayHandle_t ulOverlayHandle, float * pfAlpha); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTexelAspect)(VROverlayHandle_t ulOverlayHandle, float fTexelAspect); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTexelAspect)(VROverlayHandle_t ulOverlayHandle, float * pfTexelAspect); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlaySortOrder)(VROverlayHandle_t ulOverlayHandle, uint32_t unSortOrder); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlaySortOrder)(VROverlayHandle_t ulOverlayHandle, uint32_t * punSortOrder); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayWidthInMeters)(VROverlayHandle_t ulOverlayHandle, float fWidthInMeters); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayWidthInMeters)(VROverlayHandle_t ulOverlayHandle, float * pfWidthInMeters); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayAutoCurveDistanceRangeInMeters)(VROverlayHandle_t ulOverlayHandle, float fMinDistanceInMeters, float fMaxDistanceInMeters); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayAutoCurveDistanceRangeInMeters)(VROverlayHandle_t ulOverlayHandle, float * pfMinDistanceInMeters, float * pfMaxDistanceInMeters); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTextureColorSpace)(VROverlayHandle_t ulOverlayHandle, EColorSpace eTextureColorSpace); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureColorSpace)(VROverlayHandle_t ulOverlayHandle, EColorSpace * peTextureColorSpace); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTextureBounds)(VROverlayHandle_t ulOverlayHandle, struct VRTextureBounds_t * pOverlayTextureBounds); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureBounds)(VROverlayHandle_t ulOverlayHandle, struct VRTextureBounds_t * pOverlayTextureBounds); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayRenderModel)(VROverlayHandle_t ulOverlayHandle, char * pchValue, uint32_t unBufferSize, struct HmdColor_t * pColor, EVROverlayError * pError); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayRenderModel)(VROverlayHandle_t ulOverlayHandle, char * pchRenderModel, struct HmdColor_t * pColor); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformType)(VROverlayHandle_t ulOverlayHandle, VROverlayTransformType * peTransformType); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformAbsolute)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, struct HmdMatrix34_t * pmatTrackingOriginToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformAbsolute)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin * peTrackingOrigin, struct HmdMatrix34_t * pmatTrackingOriginToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformTrackedDeviceRelative)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unTrackedDevice, struct HmdMatrix34_t * pmatTrackedDeviceToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformTrackedDeviceRelative)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t * punTrackedDevice, struct HmdMatrix34_t * pmatTrackedDeviceToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformTrackedDeviceComponent)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unDeviceIndex, char * pchComponentName); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformTrackedDeviceComponent)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t * punDeviceIndex, char * pchComponentName, uint32_t unComponentNameSize); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformOverlayRelative)(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t * ulOverlayHandleParent, struct HmdMatrix34_t * pmatParentOverlayToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformOverlayRelative)(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t ulOverlayHandleParent, struct HmdMatrix34_t * pmatParentOverlayToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ShowOverlay)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *HideOverlay)(VROverlayHandle_t ulOverlayHandle); - bool (OPENVR_FNTABLE_CALLTYPE *IsOverlayVisible)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetTransformForOverlayCoordinates)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, struct HmdVector2_t coordinatesInOverlay, struct HmdMatrix34_t * pmatTransform); - bool (OPENVR_FNTABLE_CALLTYPE *PollNextOverlayEvent)(VROverlayHandle_t ulOverlayHandle, struct VREvent_t * pEvent, uint32_t uncbVREvent); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayInputMethod)(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod * peInputMethod); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayInputMethod)(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod eInputMethod); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayMouseScale)(VROverlayHandle_t ulOverlayHandle, struct HmdVector2_t * pvecMouseScale); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayMouseScale)(VROverlayHandle_t ulOverlayHandle, struct HmdVector2_t * pvecMouseScale); - bool (OPENVR_FNTABLE_CALLTYPE *ComputeOverlayIntersection)(VROverlayHandle_t ulOverlayHandle, struct VROverlayIntersectionParams_t * pParams, struct VROverlayIntersectionResults_t * pResults); - bool (OPENVR_FNTABLE_CALLTYPE *HandleControllerOverlayInteractionAsMouse)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unControllerDeviceIndex); - bool (OPENVR_FNTABLE_CALLTYPE *IsHoverTargetOverlay)(VROverlayHandle_t ulOverlayHandle); - VROverlayHandle_t (OPENVR_FNTABLE_CALLTYPE *GetGamepadFocusOverlay)(); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetGamepadFocusOverlay)(VROverlayHandle_t ulNewFocusOverlay); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayNeighbor)(EOverlayDirection eDirection, VROverlayHandle_t ulFrom, VROverlayHandle_t ulTo); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *MoveGamepadFocusToNeighbor)(EOverlayDirection eDirection, VROverlayHandle_t ulFrom); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTexture)(VROverlayHandle_t ulOverlayHandle, struct Texture_t * pTexture); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ClearOverlayTexture)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayRaw)(VROverlayHandle_t ulOverlayHandle, void * pvBuffer, uint32_t unWidth, uint32_t unHeight, uint32_t unDepth); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayFromFile)(VROverlayHandle_t ulOverlayHandle, char * pchFilePath); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTexture)(VROverlayHandle_t ulOverlayHandle, void ** pNativeTextureHandle, void * pNativeTextureRef, uint32_t * pWidth, uint32_t * pHeight, uint32_t * pNativeFormat, ETextureType * pAPIType, EColorSpace * pColorSpace, struct VRTextureBounds_t * pTextureBounds); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ReleaseNativeOverlayHandle)(VROverlayHandle_t ulOverlayHandle, void * pNativeTextureHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureSize)(VROverlayHandle_t ulOverlayHandle, uint32_t * pWidth, uint32_t * pHeight); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *CreateDashboardOverlay)(char * pchOverlayKey, char * pchOverlayFriendlyName, VROverlayHandle_t * pMainHandle, VROverlayHandle_t * pThumbnailHandle); - bool (OPENVR_FNTABLE_CALLTYPE *IsDashboardVisible)(); - bool (OPENVR_FNTABLE_CALLTYPE *IsActiveDashboardOverlay)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetDashboardOverlaySceneProcess)(VROverlayHandle_t ulOverlayHandle, uint32_t unProcessId); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetDashboardOverlaySceneProcess)(VROverlayHandle_t ulOverlayHandle, uint32_t * punProcessId); - void (OPENVR_FNTABLE_CALLTYPE *ShowDashboard)(char * pchOverlayToShow); - TrackedDeviceIndex_t (OPENVR_FNTABLE_CALLTYPE *GetPrimaryDashboardDevice)(); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ShowKeyboard)(EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, char * pchDescription, uint32_t unCharMax, char * pchExistingText, bool bUseMinimalMode, uint64_t uUserValue); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ShowKeyboardForOverlay)(VROverlayHandle_t ulOverlayHandle, EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, char * pchDescription, uint32_t unCharMax, char * pchExistingText, bool bUseMinimalMode, uint64_t uUserValue); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetKeyboardText)(char * pchText, uint32_t cchText); - void (OPENVR_FNTABLE_CALLTYPE *HideKeyboard)(); - void (OPENVR_FNTABLE_CALLTYPE *SetKeyboardTransformAbsolute)(ETrackingUniverseOrigin eTrackingOrigin, struct HmdMatrix34_t * pmatTrackingOriginToKeyboardTransform); - void (OPENVR_FNTABLE_CALLTYPE *SetKeyboardPositionForOverlay)(VROverlayHandle_t ulOverlayHandle, struct HmdRect2_t avoidRect); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayIntersectionMask)(VROverlayHandle_t ulOverlayHandle, struct VROverlayIntersectionMaskPrimitive_t * pMaskPrimitives, uint32_t unNumMaskPrimitives, uint32_t unPrimitiveSize); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayFlags)(VROverlayHandle_t ulOverlayHandle, uint32_t * pFlags); - VRMessageOverlayResponse (OPENVR_FNTABLE_CALLTYPE *ShowMessageOverlay)(char * pchText, char * pchCaption, char * pchButton0Text, char * pchButton1Text, char * pchButton2Text, char * pchButton3Text); - void (OPENVR_FNTABLE_CALLTYPE *CloseMessageOverlay)(); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *FindOverlay)(char *pchOverlayKey, VROverlayHandle_t *pOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *CreateOverlay)(char *pchOverlayKey, char *pchOverlayName, VROverlayHandle_t *pOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *DestroyOverlay)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetHighQualityOverlay)(VROverlayHandle_t ulOverlayHandle); + VROverlayHandle_t(OPENVR_FNTABLE_CALLTYPE *GetHighQualityOverlay)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetOverlayKey)(VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, EVROverlayError *pError); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetOverlayName)(VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, EVROverlayError *pError); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayName)(VROverlayHandle_t ulOverlayHandle, char *pchName); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayImageData)(VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unBufferSize, uint32_t *punWidth, uint32_t *punHeight); + char *(OPENVR_FNTABLE_CALLTYPE *GetOverlayErrorNameFromEnum)(EVROverlayError error); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayRenderingPid)(VROverlayHandle_t ulOverlayHandle, uint32_t unPID); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetOverlayRenderingPid)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayFlag)(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool bEnabled); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayFlag)(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool *pbEnabled); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayColor)(VROverlayHandle_t ulOverlayHandle, float fRed, float fGreen, float fBlue); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayColor)(VROverlayHandle_t ulOverlayHandle, float *pfRed, float *pfGreen, float *pfBlue); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayAlpha)(VROverlayHandle_t ulOverlayHandle, float fAlpha); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayAlpha)(VROverlayHandle_t ulOverlayHandle, float *pfAlpha); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTexelAspect)(VROverlayHandle_t ulOverlayHandle, float fTexelAspect); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTexelAspect)(VROverlayHandle_t ulOverlayHandle, float *pfTexelAspect); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlaySortOrder)(VROverlayHandle_t ulOverlayHandle, uint32_t unSortOrder); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlaySortOrder)(VROverlayHandle_t ulOverlayHandle, uint32_t *punSortOrder); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayWidthInMeters)(VROverlayHandle_t ulOverlayHandle, float fWidthInMeters); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayWidthInMeters)(VROverlayHandle_t ulOverlayHandle, float *pfWidthInMeters); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayAutoCurveDistanceRangeInMeters)(VROverlayHandle_t ulOverlayHandle, float fMinDistanceInMeters, float fMaxDistanceInMeters); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayAutoCurveDistanceRangeInMeters)(VROverlayHandle_t ulOverlayHandle, float *pfMinDistanceInMeters, float *pfMaxDistanceInMeters); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTextureColorSpace)(VROverlayHandle_t ulOverlayHandle, EColorSpace eTextureColorSpace); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureColorSpace)(VROverlayHandle_t ulOverlayHandle, EColorSpace *peTextureColorSpace); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTextureBounds)(VROverlayHandle_t ulOverlayHandle, struct VRTextureBounds_t *pOverlayTextureBounds); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureBounds)(VROverlayHandle_t ulOverlayHandle, struct VRTextureBounds_t *pOverlayTextureBounds); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetOverlayRenderModel)(VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, struct HmdColor_t *pColor, EVROverlayError *pError); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayRenderModel)(VROverlayHandle_t ulOverlayHandle, char *pchRenderModel, struct HmdColor_t *pColor); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformType)(VROverlayHandle_t ulOverlayHandle, VROverlayTransformType *peTransformType); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformAbsolute)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, struct HmdMatrix34_t *pmatTrackingOriginToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformAbsolute)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin *peTrackingOrigin, struct HmdMatrix34_t *pmatTrackingOriginToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformTrackedDeviceRelative)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unTrackedDevice, struct HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformTrackedDeviceRelative)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punTrackedDevice, struct HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformTrackedDeviceComponent)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unDeviceIndex, char *pchComponentName); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformTrackedDeviceComponent)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punDeviceIndex, char *pchComponentName, uint32_t unComponentNameSize); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformOverlayRelative)(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t *ulOverlayHandleParent, struct HmdMatrix34_t *pmatParentOverlayToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformOverlayRelative)(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t ulOverlayHandleParent, struct HmdMatrix34_t *pmatParentOverlayToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *ShowOverlay)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *HideOverlay)(VROverlayHandle_t ulOverlayHandle); + bool(OPENVR_FNTABLE_CALLTYPE *IsOverlayVisible)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetTransformForOverlayCoordinates)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, struct HmdVector2_t coordinatesInOverlay, struct HmdMatrix34_t *pmatTransform); + bool(OPENVR_FNTABLE_CALLTYPE *PollNextOverlayEvent)(VROverlayHandle_t ulOverlayHandle, struct VREvent_t *pEvent, uint32_t uncbVREvent); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayInputMethod)(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod *peInputMethod); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayInputMethod)(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod eInputMethod); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayMouseScale)(VROverlayHandle_t ulOverlayHandle, struct HmdVector2_t *pvecMouseScale); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayMouseScale)(VROverlayHandle_t ulOverlayHandle, struct HmdVector2_t *pvecMouseScale); + bool(OPENVR_FNTABLE_CALLTYPE *ComputeOverlayIntersection)(VROverlayHandle_t ulOverlayHandle, struct VROverlayIntersectionParams_t *pParams, struct VROverlayIntersectionResults_t *pResults); + bool(OPENVR_FNTABLE_CALLTYPE *HandleControllerOverlayInteractionAsMouse)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unControllerDeviceIndex); + bool(OPENVR_FNTABLE_CALLTYPE *IsHoverTargetOverlay)(VROverlayHandle_t ulOverlayHandle); + VROverlayHandle_t(OPENVR_FNTABLE_CALLTYPE *GetGamepadFocusOverlay)(); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetGamepadFocusOverlay)(VROverlayHandle_t ulNewFocusOverlay); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayNeighbor)(EOverlayDirection eDirection, VROverlayHandle_t ulFrom, VROverlayHandle_t ulTo); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *MoveGamepadFocusToNeighbor)(EOverlayDirection eDirection, VROverlayHandle_t ulFrom); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTexture)(VROverlayHandle_t ulOverlayHandle, struct Texture_t *pTexture); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *ClearOverlayTexture)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayRaw)(VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unWidth, uint32_t unHeight, uint32_t unDepth); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayFromFile)(VROverlayHandle_t ulOverlayHandle, char *pchFilePath); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTexture)(VROverlayHandle_t ulOverlayHandle, void **pNativeTextureHandle, void *pNativeTextureRef, uint32_t *pWidth, uint32_t *pHeight, uint32_t *pNativeFormat, ETextureType *pAPIType, EColorSpace *pColorSpace, struct VRTextureBounds_t *pTextureBounds); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *ReleaseNativeOverlayHandle)(VROverlayHandle_t ulOverlayHandle, void *pNativeTextureHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureSize)(VROverlayHandle_t ulOverlayHandle, uint32_t *pWidth, uint32_t *pHeight); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *CreateDashboardOverlay)(char *pchOverlayKey, char *pchOverlayFriendlyName, VROverlayHandle_t *pMainHandle, VROverlayHandle_t *pThumbnailHandle); + bool(OPENVR_FNTABLE_CALLTYPE *IsDashboardVisible)(); + bool(OPENVR_FNTABLE_CALLTYPE *IsActiveDashboardOverlay)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetDashboardOverlaySceneProcess)(VROverlayHandle_t ulOverlayHandle, uint32_t unProcessId); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetDashboardOverlaySceneProcess)(VROverlayHandle_t ulOverlayHandle, uint32_t *punProcessId); + void(OPENVR_FNTABLE_CALLTYPE *ShowDashboard)(char *pchOverlayToShow); + TrackedDeviceIndex_t(OPENVR_FNTABLE_CALLTYPE *GetPrimaryDashboardDevice)(); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *ShowKeyboard)(EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, char *pchDescription, uint32_t unCharMax, char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *ShowKeyboardForOverlay)(VROverlayHandle_t ulOverlayHandle, EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, char *pchDescription, uint32_t unCharMax, char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetKeyboardText)(char *pchText, uint32_t cchText); + void(OPENVR_FNTABLE_CALLTYPE *HideKeyboard)(); + void(OPENVR_FNTABLE_CALLTYPE *SetKeyboardTransformAbsolute)(ETrackingUniverseOrigin eTrackingOrigin, struct HmdMatrix34_t *pmatTrackingOriginToKeyboardTransform); + void(OPENVR_FNTABLE_CALLTYPE *SetKeyboardPositionForOverlay)(VROverlayHandle_t ulOverlayHandle, struct HmdRect2_t avoidRect); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayIntersectionMask)(VROverlayHandle_t ulOverlayHandle, struct VROverlayIntersectionMaskPrimitive_t *pMaskPrimitives, uint32_t unNumMaskPrimitives, uint32_t unPrimitiveSize); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayFlags)(VROverlayHandle_t ulOverlayHandle, uint32_t *pFlags); + VRMessageOverlayResponse(OPENVR_FNTABLE_CALLTYPE *ShowMessageOverlay)(char *pchText, char *pchCaption, char *pchButton0Text, char *pchButton1Text, char *pchButton2Text, char *pchButton3Text); + void(OPENVR_FNTABLE_CALLTYPE *CloseMessageOverlay)(); }; struct VR_IVRRenderModels_FnTable { - EVRRenderModelError (OPENVR_FNTABLE_CALLTYPE *LoadRenderModel_Async)(char * pchRenderModelName, struct RenderModel_t ** ppRenderModel); - void (OPENVR_FNTABLE_CALLTYPE *FreeRenderModel)(struct RenderModel_t * pRenderModel); - EVRRenderModelError (OPENVR_FNTABLE_CALLTYPE *LoadTexture_Async)(TextureID_t textureId, struct RenderModel_TextureMap_t ** ppTexture); - void (OPENVR_FNTABLE_CALLTYPE *FreeTexture)(struct RenderModel_TextureMap_t * pTexture); - EVRRenderModelError (OPENVR_FNTABLE_CALLTYPE *LoadTextureD3D11_Async)(TextureID_t textureId, void * pD3D11Device, void ** ppD3D11Texture2D); - EVRRenderModelError (OPENVR_FNTABLE_CALLTYPE *LoadIntoTextureD3D11_Async)(TextureID_t textureId, void * pDstTexture); - void (OPENVR_FNTABLE_CALLTYPE *FreeTextureD3D11)(void * pD3D11Texture2D); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetRenderModelName)(uint32_t unRenderModelIndex, char * pchRenderModelName, uint32_t unRenderModelNameLen); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetRenderModelCount)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetComponentCount)(char * pchRenderModelName); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetComponentName)(char * pchRenderModelName, uint32_t unComponentIndex, char * pchComponentName, uint32_t unComponentNameLen); - uint64_t (OPENVR_FNTABLE_CALLTYPE *GetComponentButtonMask)(char * pchRenderModelName, char * pchComponentName); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetComponentRenderModelName)(char * pchRenderModelName, char * pchComponentName, char * pchComponentRenderModelName, uint32_t unComponentRenderModelNameLen); - bool (OPENVR_FNTABLE_CALLTYPE *GetComponentState)(char * pchRenderModelName, char * pchComponentName, VRControllerState_t * pControllerState, struct RenderModel_ControllerMode_State_t * pState, struct RenderModel_ComponentState_t * pComponentState); - bool (OPENVR_FNTABLE_CALLTYPE *RenderModelHasComponent)(char * pchRenderModelName, char * pchComponentName); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetRenderModelThumbnailURL)(char * pchRenderModelName, char * pchThumbnailURL, uint32_t unThumbnailURLLen, EVRRenderModelError * peError); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetRenderModelOriginalPath)(char * pchRenderModelName, char * pchOriginalPath, uint32_t unOriginalPathLen, EVRRenderModelError * peError); - char * (OPENVR_FNTABLE_CALLTYPE *GetRenderModelErrorNameFromEnum)(EVRRenderModelError error); + EVRRenderModelError(OPENVR_FNTABLE_CALLTYPE *LoadRenderModel_Async)(char *pchRenderModelName, struct RenderModel_t **ppRenderModel); + void(OPENVR_FNTABLE_CALLTYPE *FreeRenderModel)(struct RenderModel_t *pRenderModel); + EVRRenderModelError(OPENVR_FNTABLE_CALLTYPE *LoadTexture_Async)(TextureID_t textureId, struct RenderModel_TextureMap_t **ppTexture); + void(OPENVR_FNTABLE_CALLTYPE *FreeTexture)(struct RenderModel_TextureMap_t *pTexture); + EVRRenderModelError(OPENVR_FNTABLE_CALLTYPE *LoadTextureD3D11_Async)(TextureID_t textureId, void *pD3D11Device, void **ppD3D11Texture2D); + EVRRenderModelError(OPENVR_FNTABLE_CALLTYPE *LoadIntoTextureD3D11_Async)(TextureID_t textureId, void *pDstTexture); + void(OPENVR_FNTABLE_CALLTYPE *FreeTextureD3D11)(void *pD3D11Texture2D); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetRenderModelName)(uint32_t unRenderModelIndex, char *pchRenderModelName, uint32_t unRenderModelNameLen); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetRenderModelCount)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetComponentCount)(char *pchRenderModelName); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetComponentName)(char *pchRenderModelName, uint32_t unComponentIndex, char *pchComponentName, uint32_t unComponentNameLen); + uint64_t(OPENVR_FNTABLE_CALLTYPE *GetComponentButtonMask)(char *pchRenderModelName, char *pchComponentName); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetComponentRenderModelName)(char *pchRenderModelName, char *pchComponentName, char *pchComponentRenderModelName, uint32_t unComponentRenderModelNameLen); + bool(OPENVR_FNTABLE_CALLTYPE *GetComponentState)(char *pchRenderModelName, char *pchComponentName, VRControllerState_t *pControllerState, struct RenderModel_ControllerMode_State_t *pState, struct RenderModel_ComponentState_t *pComponentState); + bool(OPENVR_FNTABLE_CALLTYPE *RenderModelHasComponent)(char *pchRenderModelName, char *pchComponentName); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetRenderModelThumbnailURL)(char *pchRenderModelName, char *pchThumbnailURL, uint32_t unThumbnailURLLen, EVRRenderModelError *peError); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetRenderModelOriginalPath)(char *pchRenderModelName, char *pchOriginalPath, uint32_t unOriginalPathLen, EVRRenderModelError *peError); + char *(OPENVR_FNTABLE_CALLTYPE *GetRenderModelErrorNameFromEnum)(EVRRenderModelError error); }; struct VR_IVRNotifications_FnTable { - EVRNotificationError (OPENVR_FNTABLE_CALLTYPE *CreateNotification)(VROverlayHandle_t ulOverlayHandle, uint64_t ulUserValue, EVRNotificationType type, char * pchText, EVRNotificationStyle style, struct NotificationBitmap_t * pImage, VRNotificationId * pNotificationId); - EVRNotificationError (OPENVR_FNTABLE_CALLTYPE *RemoveNotification)(VRNotificationId notificationId); + EVRNotificationError(OPENVR_FNTABLE_CALLTYPE *CreateNotification)(VROverlayHandle_t ulOverlayHandle, uint64_t ulUserValue, EVRNotificationType type, char *pchText, EVRNotificationStyle style, struct NotificationBitmap_t *pImage, VRNotificationId *pNotificationId); + EVRNotificationError(OPENVR_FNTABLE_CALLTYPE *RemoveNotification)(VRNotificationId notificationId); }; struct VR_IVRSettings_FnTable { - char * (OPENVR_FNTABLE_CALLTYPE *GetSettingsErrorNameFromEnum)(EVRSettingsError eError); - bool (OPENVR_FNTABLE_CALLTYPE *Sync)(bool bForce, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *SetBool)(char * pchSection, char * pchSettingsKey, bool bValue, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *SetInt32)(char * pchSection, char * pchSettingsKey, int32_t nValue, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *SetFloat)(char * pchSection, char * pchSettingsKey, float flValue, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *SetString)(char * pchSection, char * pchSettingsKey, char * pchValue, EVRSettingsError * peError); - bool (OPENVR_FNTABLE_CALLTYPE *GetBool)(char * pchSection, char * pchSettingsKey, EVRSettingsError * peError); - int32_t (OPENVR_FNTABLE_CALLTYPE *GetInt32)(char * pchSection, char * pchSettingsKey, EVRSettingsError * peError); - float (OPENVR_FNTABLE_CALLTYPE *GetFloat)(char * pchSection, char * pchSettingsKey, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *GetString)(char * pchSection, char * pchSettingsKey, char * pchValue, uint32_t unValueLen, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *RemoveSection)(char * pchSection, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *RemoveKeyInSection)(char * pchSection, char * pchSettingsKey, EVRSettingsError * peError); + char *(OPENVR_FNTABLE_CALLTYPE *GetSettingsErrorNameFromEnum)(EVRSettingsError eError); + bool(OPENVR_FNTABLE_CALLTYPE *Sync)(bool bForce, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *SetBool)(char *pchSection, char *pchSettingsKey, bool bValue, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *SetInt32)(char *pchSection, char *pchSettingsKey, int32_t nValue, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *SetFloat)(char *pchSection, char *pchSettingsKey, float flValue, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *SetString)(char *pchSection, char *pchSettingsKey, char *pchValue, EVRSettingsError *peError); + bool(OPENVR_FNTABLE_CALLTYPE *GetBool)(char *pchSection, char *pchSettingsKey, EVRSettingsError *peError); + int32_t(OPENVR_FNTABLE_CALLTYPE *GetInt32)(char *pchSection, char *pchSettingsKey, EVRSettingsError *peError); + float(OPENVR_FNTABLE_CALLTYPE *GetFloat)(char *pchSection, char *pchSettingsKey, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *GetString)(char *pchSection, char *pchSettingsKey, char *pchValue, uint32_t unValueLen, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *RemoveSection)(char *pchSection, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *RemoveKeyInSection)(char *pchSection, char *pchSettingsKey, EVRSettingsError *peError); }; struct VR_IVRScreenshots_FnTable { - EVRScreenshotError (OPENVR_FNTABLE_CALLTYPE *RequestScreenshot)(ScreenshotHandle_t * pOutScreenshotHandle, EVRScreenshotType type, char * pchPreviewFilename, char * pchVRFilename); - EVRScreenshotError (OPENVR_FNTABLE_CALLTYPE *HookScreenshot)(EVRScreenshotType * pSupportedTypes, int numTypes); - EVRScreenshotType (OPENVR_FNTABLE_CALLTYPE *GetScreenshotPropertyType)(ScreenshotHandle_t screenshotHandle, EVRScreenshotError * pError); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetScreenshotPropertyFilename)(ScreenshotHandle_t screenshotHandle, EVRScreenshotPropertyFilenames filenameType, char * pchFilename, uint32_t cchFilename, EVRScreenshotError * pError); - EVRScreenshotError (OPENVR_FNTABLE_CALLTYPE *UpdateScreenshotProgress)(ScreenshotHandle_t screenshotHandle, float flProgress); - EVRScreenshotError (OPENVR_FNTABLE_CALLTYPE *TakeStereoScreenshot)(ScreenshotHandle_t * pOutScreenshotHandle, char * pchPreviewFilename, char * pchVRFilename); - EVRScreenshotError (OPENVR_FNTABLE_CALLTYPE *SubmitScreenshot)(ScreenshotHandle_t screenshotHandle, EVRScreenshotType type, char * pchSourcePreviewFilename, char * pchSourceVRFilename); + EVRScreenshotError(OPENVR_FNTABLE_CALLTYPE *RequestScreenshot)(ScreenshotHandle_t *pOutScreenshotHandle, EVRScreenshotType type, char *pchPreviewFilename, char *pchVRFilename); + EVRScreenshotError(OPENVR_FNTABLE_CALLTYPE *HookScreenshot)(EVRScreenshotType *pSupportedTypes, int numTypes); + EVRScreenshotType(OPENVR_FNTABLE_CALLTYPE *GetScreenshotPropertyType)(ScreenshotHandle_t screenshotHandle, EVRScreenshotError *pError); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetScreenshotPropertyFilename)(ScreenshotHandle_t screenshotHandle, EVRScreenshotPropertyFilenames filenameType, char *pchFilename, uint32_t cchFilename, EVRScreenshotError *pError); + EVRScreenshotError(OPENVR_FNTABLE_CALLTYPE *UpdateScreenshotProgress)(ScreenshotHandle_t screenshotHandle, float flProgress); + EVRScreenshotError(OPENVR_FNTABLE_CALLTYPE *TakeStereoScreenshot)(ScreenshotHandle_t *pOutScreenshotHandle, char *pchPreviewFilename, char *pchVRFilename); + EVRScreenshotError(OPENVR_FNTABLE_CALLTYPE *SubmitScreenshot)(ScreenshotHandle_t screenshotHandle, EVRScreenshotType type, char *pchSourcePreviewFilename, char *pchSourceVRFilename); }; struct VR_IVRResources_FnTable { - uint32_t (OPENVR_FNTABLE_CALLTYPE *LoadSharedResource)(char * pchResourceName, char * pchBuffer, uint32_t unBufferLen); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetResourceFullPath)(char * pchResourceName, char * pchResourceTypeDirectory, char * pchPathBuffer, uint32_t unBufferLen); + uint32_t(OPENVR_FNTABLE_CALLTYPE *LoadSharedResource)(char *pchResourceName, char *pchBuffer, uint32_t unBufferLen); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetResourceFullPath)(char *pchResourceName, char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen); }; struct VR_IVRDriverManager_FnTable { - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetDriverCount)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetDriverName)(DriverId_t nDriver, char * pchValue, uint32_t unBufferSize); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetDriverCount)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetDriverName)(DriverId_t nDriver, char *pchValue, uint32_t unBufferSize); }; - #if 0 // Global entry points S_API intptr_t VR_InitInternal( EVRInitError *peError, EVRApplicationType eType ); @@ -1937,6 +1929,4 @@ S_API const char * VR_GetVRInitErrorAsSymbol( EVRInitError error ); S_API const char * VR_GetVRInitErrorAsEnglishDescription( EVRInitError error ); #endif -#endif // __OPENVR_API_FLAT_H__ - - +#endif // __OPENVR_API_FLAT_H__ diff --git a/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/A/Headers/openvr_driver.h b/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/A/Headers/openvr_driver.h index 7ab997e25..b07699f82 100644 --- a/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/A/Headers/openvr_driver.h +++ b/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/A/Headers/openvr_driver.h @@ -9,8 +9,6 @@ #include - - // vrtypes.h #ifndef _INCLUDE_VRTYPES_H #define _INCLUDE_VRTYPES_H @@ -27,9 +25,9 @@ struct ID3D12CommandQueue; namespace vr { -#pragma pack( push, 8 ) +#pragma pack(push, 8) -typedef void* glSharedTextureHandle_t; +typedef void *glSharedTextureHandle_t; typedef int32_t glInt_t; typedef uint32_t glUInt_t; @@ -80,7 +78,7 @@ struct HmdColor_t struct HmdQuad_t { - HmdVector3_t vCorners[ 4 ]; + HmdVector3_t vCorners[4]; }; struct HmdRect2_t @@ -107,40 +105,40 @@ enum EVREye enum ETextureType { - TextureType_DirectX = 0, // Handle is an ID3D11Texture - TextureType_OpenGL = 1, // Handle is an OpenGL texture name or an OpenGL render buffer name, depending on submit flags - TextureType_Vulkan = 2, // Handle is a pointer to a VRVulkanTextureData_t structure - TextureType_IOSurface = 3, // Handle is a macOS cross-process-sharable IOSurfaceRef - TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure + TextureType_DirectX = 0, // Handle is an ID3D11Texture + TextureType_OpenGL = 1, // Handle is an OpenGL texture name or an OpenGL render buffer name, depending on submit flags + TextureType_Vulkan = 2, // Handle is a pointer to a VRVulkanTextureData_t structure + TextureType_IOSurface = 3, // Handle is a macOS cross-process-sharable IOSurfaceRef + TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure }; enum EColorSpace { - ColorSpace_Auto = 0, // Assumes 'gamma' for 8-bit per component formats, otherwise 'linear'. This mirrors the DXGI formats which have _SRGB variants. - ColorSpace_Gamma = 1, // Texture data can be displayed directly on the display without any conversion (a.k.a. display native format). - ColorSpace_Linear = 2, // Same as gamma but has been converted to a linear representation using DXGI's sRGB conversion algorithm. + ColorSpace_Auto = 0, // Assumes 'gamma' for 8-bit per component formats, otherwise 'linear'. This mirrors the DXGI formats which have _SRGB variants. + ColorSpace_Gamma = 1, // Texture data can be displayed directly on the display without any conversion (a.k.a. display native format). + ColorSpace_Linear = 2, // Same as gamma but has been converted to a linear representation using DXGI's sRGB conversion algorithm. }; struct Texture_t { - void* handle; // See ETextureType definition above + void *handle; // See ETextureType definition above ETextureType eType; EColorSpace eColorSpace; }; // Handle to a shared texture (HANDLE on Windows obtained using OpenSharedResource). typedef uint64_t SharedTextureHandle_t; -#define INVALID_SHARED_TEXTURE_HANDLE ((vr::SharedTextureHandle_t)0) +#define INVALID_SHARED_TEXTURE_HANDLE ((vr::SharedTextureHandle_t)0) enum ETrackingResult { - TrackingResult_Uninitialized = 1, + TrackingResult_Uninitialized = 1, - TrackingResult_Calibrating_InProgress = 100, - TrackingResult_Calibrating_OutOfRange = 101, + TrackingResult_Calibrating_InProgress = 100, + TrackingResult_Calibrating_OutOfRange = 101, - TrackingResult_Running_OK = 200, - TrackingResult_Running_OutOfRange = 201, + TrackingResult_Running_OK = 200, + TrackingResult_Running_OutOfRange = 201, }; typedef uint32_t DriverId_t; @@ -158,30 +156,28 @@ static const uint32_t k_unTrackedDeviceIndexInvalid = 0xFFFFFFFF; /** Describes what kind of object is being tracked at a given ID */ enum ETrackedDeviceClass { - TrackedDeviceClass_Invalid = 0, // the ID was not valid. - TrackedDeviceClass_HMD = 1, // Head-Mounted Displays - TrackedDeviceClass_Controller = 2, // Tracked controllers - TrackedDeviceClass_GenericTracker = 3, // Generic trackers, similar to controllers - TrackedDeviceClass_TrackingReference = 4, // Camera and base stations that serve as tracking reference points - TrackedDeviceClass_DisplayRedirect = 5, // Accessories that aren't necessarily tracked themselves, but may redirect video output from other tracked devices + TrackedDeviceClass_Invalid = 0, // the ID was not valid. + TrackedDeviceClass_HMD = 1, // Head-Mounted Displays + TrackedDeviceClass_Controller = 2, // Tracked controllers + TrackedDeviceClass_GenericTracker = 3, // Generic trackers, similar to controllers + TrackedDeviceClass_TrackingReference = 4, // Camera and base stations that serve as tracking reference points + TrackedDeviceClass_DisplayRedirect = 5, // Accessories that aren't necessarily tracked themselves, but may redirect video output from other tracked devices }; - /** Describes what specific role associated with a tracked device */ enum ETrackedControllerRole { - TrackedControllerRole_Invalid = 0, // Invalid value for controller type - TrackedControllerRole_LeftHand = 1, // Tracked device associated with the left hand - TrackedControllerRole_RightHand = 2, // Tracked device associated with the right hand + TrackedControllerRole_Invalid = 0, // Invalid value for controller type + TrackedControllerRole_LeftHand = 1, // Tracked device associated with the left hand + TrackedControllerRole_RightHand = 2, // Tracked device associated with the right hand }; - /** describes a single pose for a tracked object */ struct TrackedDevicePose_t { HmdMatrix34_t mDeviceToAbsoluteTracking; - HmdVector3_t vVelocity; // velocity in tracker space in m/s - HmdVector3_t vAngularVelocity; // angular velocity in radians/s (?) + HmdVector3_t vVelocity; // velocity in tracker space in m/s + HmdVector3_t vAngularVelocity; // angular velocity in radians/s (?) ETrackingResult eTrackingResult; bool bPoseIsValid; @@ -194,9 +190,9 @@ struct TrackedDevicePose_t * for the poses it is requesting */ enum ETrackingUniverseOrigin { - TrackingUniverseSeated = 0, // Poses are provided relative to the seated zero pose - TrackingUniverseStanding = 1, // Poses are provided relative to the safe bounds configured by the user - TrackingUniverseRawAndUncalibrated = 2, // Poses are provided in the coordinate system defined by the driver. It has Y up and is unified for devices of the same driver. You usually don't want this one. + TrackingUniverseSeated = 0, // Poses are provided relative to the seated zero pose + TrackingUniverseStanding = 1, // Poses are provided relative to the safe bounds configured by the user + TrackingUniverseRawAndUncalibrated = 2, // Poses are provided in the coordinate system defined by the driver. It has Y up and is unified for devices of the same driver. You usually don't want this one. }; // Refers to a single container of properties @@ -223,146 +219,145 @@ static const PropertyTypeTag_t k_unHiddenAreaPropertyTag = 30; static const PropertyTypeTag_t k_unOpenVRInternalReserved_Start = 1000; static const PropertyTypeTag_t k_unOpenVRInternalReserved_End = 10000; - /** Each entry in this enum represents a property that can be retrieved about a * tracked device. Many fields are only valid for one ETrackedDeviceClass. */ enum ETrackedDeviceProperty { - Prop_Invalid = 0, + Prop_Invalid = 0, // general properties that apply to all device classes - Prop_TrackingSystemName_String = 1000, - Prop_ModelNumber_String = 1001, - Prop_SerialNumber_String = 1002, - Prop_RenderModelName_String = 1003, - Prop_WillDriftInYaw_Bool = 1004, - Prop_ManufacturerName_String = 1005, - Prop_TrackingFirmwareVersion_String = 1006, - Prop_HardwareRevision_String = 1007, - Prop_AllWirelessDongleDescriptions_String = 1008, - Prop_ConnectedWirelessDongle_String = 1009, - Prop_DeviceIsWireless_Bool = 1010, - Prop_DeviceIsCharging_Bool = 1011, - Prop_DeviceBatteryPercentage_Float = 1012, // 0 is empty, 1 is full - Prop_StatusDisplayTransform_Matrix34 = 1013, - Prop_Firmware_UpdateAvailable_Bool = 1014, - Prop_Firmware_ManualUpdate_Bool = 1015, - Prop_Firmware_ManualUpdateURL_String = 1016, - Prop_HardwareRevision_Uint64 = 1017, - Prop_FirmwareVersion_Uint64 = 1018, - Prop_FPGAVersion_Uint64 = 1019, - Prop_VRCVersion_Uint64 = 1020, - Prop_RadioVersion_Uint64 = 1021, - Prop_DongleVersion_Uint64 = 1022, - Prop_BlockServerShutdown_Bool = 1023, - Prop_CanUnifyCoordinateSystemWithHmd_Bool = 1024, - Prop_ContainsProximitySensor_Bool = 1025, - Prop_DeviceProvidesBatteryStatus_Bool = 1026, - Prop_DeviceCanPowerOff_Bool = 1027, - Prop_Firmware_ProgrammingTarget_String = 1028, - Prop_DeviceClass_Int32 = 1029, - Prop_HasCamera_Bool = 1030, - Prop_DriverVersion_String = 1031, - Prop_Firmware_ForceUpdateRequired_Bool = 1032, - Prop_ViveSystemButtonFixRequired_Bool = 1033, - Prop_ParentDriver_Uint64 = 1034, - Prop_ResourceRoot_String = 1035, + Prop_TrackingSystemName_String = 1000, + Prop_ModelNumber_String = 1001, + Prop_SerialNumber_String = 1002, + Prop_RenderModelName_String = 1003, + Prop_WillDriftInYaw_Bool = 1004, + Prop_ManufacturerName_String = 1005, + Prop_TrackingFirmwareVersion_String = 1006, + Prop_HardwareRevision_String = 1007, + Prop_AllWirelessDongleDescriptions_String = 1008, + Prop_ConnectedWirelessDongle_String = 1009, + Prop_DeviceIsWireless_Bool = 1010, + Prop_DeviceIsCharging_Bool = 1011, + Prop_DeviceBatteryPercentage_Float = 1012, // 0 is empty, 1 is full + Prop_StatusDisplayTransform_Matrix34 = 1013, + Prop_Firmware_UpdateAvailable_Bool = 1014, + Prop_Firmware_ManualUpdate_Bool = 1015, + Prop_Firmware_ManualUpdateURL_String = 1016, + Prop_HardwareRevision_Uint64 = 1017, + Prop_FirmwareVersion_Uint64 = 1018, + Prop_FPGAVersion_Uint64 = 1019, + Prop_VRCVersion_Uint64 = 1020, + Prop_RadioVersion_Uint64 = 1021, + Prop_DongleVersion_Uint64 = 1022, + Prop_BlockServerShutdown_Bool = 1023, + Prop_CanUnifyCoordinateSystemWithHmd_Bool = 1024, + Prop_ContainsProximitySensor_Bool = 1025, + Prop_DeviceProvidesBatteryStatus_Bool = 1026, + Prop_DeviceCanPowerOff_Bool = 1027, + Prop_Firmware_ProgrammingTarget_String = 1028, + Prop_DeviceClass_Int32 = 1029, + Prop_HasCamera_Bool = 1030, + Prop_DriverVersion_String = 1031, + Prop_Firmware_ForceUpdateRequired_Bool = 1032, + Prop_ViveSystemButtonFixRequired_Bool = 1033, + Prop_ParentDriver_Uint64 = 1034, + Prop_ResourceRoot_String = 1035, // Properties that are unique to TrackedDeviceClass_HMD - Prop_ReportsTimeSinceVSync_Bool = 2000, - Prop_SecondsFromVsyncToPhotons_Float = 2001, - Prop_DisplayFrequency_Float = 2002, - Prop_UserIpdMeters_Float = 2003, - Prop_CurrentUniverseId_Uint64 = 2004, - Prop_PreviousUniverseId_Uint64 = 2005, - Prop_DisplayFirmwareVersion_Uint64 = 2006, - Prop_IsOnDesktop_Bool = 2007, - Prop_DisplayMCType_Int32 = 2008, - Prop_DisplayMCOffset_Float = 2009, - Prop_DisplayMCScale_Float = 2010, - Prop_EdidVendorID_Int32 = 2011, - Prop_DisplayMCImageLeft_String = 2012, - Prop_DisplayMCImageRight_String = 2013, - Prop_DisplayGCBlackClamp_Float = 2014, - Prop_EdidProductID_Int32 = 2015, - Prop_CameraToHeadTransform_Matrix34 = 2016, - Prop_DisplayGCType_Int32 = 2017, - Prop_DisplayGCOffset_Float = 2018, - Prop_DisplayGCScale_Float = 2019, - Prop_DisplayGCPrescale_Float = 2020, - Prop_DisplayGCImage_String = 2021, - Prop_LensCenterLeftU_Float = 2022, - Prop_LensCenterLeftV_Float = 2023, - Prop_LensCenterRightU_Float = 2024, - Prop_LensCenterRightV_Float = 2025, - Prop_UserHeadToEyeDepthMeters_Float = 2026, - Prop_CameraFirmwareVersion_Uint64 = 2027, - Prop_CameraFirmwareDescription_String = 2028, - Prop_DisplayFPGAVersion_Uint64 = 2029, - Prop_DisplayBootloaderVersion_Uint64 = 2030, - Prop_DisplayHardwareVersion_Uint64 = 2031, - Prop_AudioFirmwareVersion_Uint64 = 2032, - Prop_CameraCompatibilityMode_Int32 = 2033, + Prop_ReportsTimeSinceVSync_Bool = 2000, + Prop_SecondsFromVsyncToPhotons_Float = 2001, + Prop_DisplayFrequency_Float = 2002, + Prop_UserIpdMeters_Float = 2003, + Prop_CurrentUniverseId_Uint64 = 2004, + Prop_PreviousUniverseId_Uint64 = 2005, + Prop_DisplayFirmwareVersion_Uint64 = 2006, + Prop_IsOnDesktop_Bool = 2007, + Prop_DisplayMCType_Int32 = 2008, + Prop_DisplayMCOffset_Float = 2009, + Prop_DisplayMCScale_Float = 2010, + Prop_EdidVendorID_Int32 = 2011, + Prop_DisplayMCImageLeft_String = 2012, + Prop_DisplayMCImageRight_String = 2013, + Prop_DisplayGCBlackClamp_Float = 2014, + Prop_EdidProductID_Int32 = 2015, + Prop_CameraToHeadTransform_Matrix34 = 2016, + Prop_DisplayGCType_Int32 = 2017, + Prop_DisplayGCOffset_Float = 2018, + Prop_DisplayGCScale_Float = 2019, + Prop_DisplayGCPrescale_Float = 2020, + Prop_DisplayGCImage_String = 2021, + Prop_LensCenterLeftU_Float = 2022, + Prop_LensCenterLeftV_Float = 2023, + Prop_LensCenterRightU_Float = 2024, + Prop_LensCenterRightV_Float = 2025, + Prop_UserHeadToEyeDepthMeters_Float = 2026, + Prop_CameraFirmwareVersion_Uint64 = 2027, + Prop_CameraFirmwareDescription_String = 2028, + Prop_DisplayFPGAVersion_Uint64 = 2029, + Prop_DisplayBootloaderVersion_Uint64 = 2030, + Prop_DisplayHardwareVersion_Uint64 = 2031, + Prop_AudioFirmwareVersion_Uint64 = 2032, + Prop_CameraCompatibilityMode_Int32 = 2033, Prop_ScreenshotHorizontalFieldOfViewDegrees_Float = 2034, Prop_ScreenshotVerticalFieldOfViewDegrees_Float = 2035, - Prop_DisplaySuppressed_Bool = 2036, - Prop_DisplayAllowNightMode_Bool = 2037, - Prop_DisplayMCImageWidth_Int32 = 2038, - Prop_DisplayMCImageHeight_Int32 = 2039, - Prop_DisplayMCImageNumChannels_Int32 = 2040, - Prop_DisplayMCImageData_Binary = 2041, - Prop_SecondsFromPhotonsToVblank_Float = 2042, - Prop_DriverDirectModeSendsVsyncEvents_Bool = 2043, - Prop_DisplayDebugMode_Bool = 2044, - Prop_GraphicsAdapterLuid_Uint64 = 2045, - Prop_DriverProvidedChaperonePath_String = 2048, + Prop_DisplaySuppressed_Bool = 2036, + Prop_DisplayAllowNightMode_Bool = 2037, + Prop_DisplayMCImageWidth_Int32 = 2038, + Prop_DisplayMCImageHeight_Int32 = 2039, + Prop_DisplayMCImageNumChannels_Int32 = 2040, + Prop_DisplayMCImageData_Binary = 2041, + Prop_SecondsFromPhotonsToVblank_Float = 2042, + Prop_DriverDirectModeSendsVsyncEvents_Bool = 2043, + Prop_DisplayDebugMode_Bool = 2044, + Prop_GraphicsAdapterLuid_Uint64 = 2045, + Prop_DriverProvidedChaperonePath_String = 2048, // Properties that are unique to TrackedDeviceClass_Controller - Prop_AttachedDeviceId_String = 3000, - Prop_SupportedButtons_Uint64 = 3001, - Prop_Axis0Type_Int32 = 3002, // Return value is of type EVRControllerAxisType - Prop_Axis1Type_Int32 = 3003, // Return value is of type EVRControllerAxisType - Prop_Axis2Type_Int32 = 3004, // Return value is of type EVRControllerAxisType - Prop_Axis3Type_Int32 = 3005, // Return value is of type EVRControllerAxisType - Prop_Axis4Type_Int32 = 3006, // Return value is of type EVRControllerAxisType - Prop_ControllerRoleHint_Int32 = 3007, // Return value is of type ETrackedControllerRole + Prop_AttachedDeviceId_String = 3000, + Prop_SupportedButtons_Uint64 = 3001, + Prop_Axis0Type_Int32 = 3002, // Return value is of type EVRControllerAxisType + Prop_Axis1Type_Int32 = 3003, // Return value is of type EVRControllerAxisType + Prop_Axis2Type_Int32 = 3004, // Return value is of type EVRControllerAxisType + Prop_Axis3Type_Int32 = 3005, // Return value is of type EVRControllerAxisType + Prop_Axis4Type_Int32 = 3006, // Return value is of type EVRControllerAxisType + Prop_ControllerRoleHint_Int32 = 3007, // Return value is of type ETrackedControllerRole // Properties that are unique to TrackedDeviceClass_TrackingReference - Prop_FieldOfViewLeftDegrees_Float = 4000, - Prop_FieldOfViewRightDegrees_Float = 4001, - Prop_FieldOfViewTopDegrees_Float = 4002, - Prop_FieldOfViewBottomDegrees_Float = 4003, - Prop_TrackingRangeMinimumMeters_Float = 4004, - Prop_TrackingRangeMaximumMeters_Float = 4005, - Prop_ModeLabel_String = 4006, + Prop_FieldOfViewLeftDegrees_Float = 4000, + Prop_FieldOfViewRightDegrees_Float = 4001, + Prop_FieldOfViewTopDegrees_Float = 4002, + Prop_FieldOfViewBottomDegrees_Float = 4003, + Prop_TrackingRangeMinimumMeters_Float = 4004, + Prop_TrackingRangeMaximumMeters_Float = 4005, + Prop_ModeLabel_String = 4006, // Properties that are used for user interface like icons names - Prop_IconPathName_String = 5000, // DEPRECATED. Value not referenced. Now expected to be part of icon path properties. - Prop_NamedIconPathDeviceOff_String = 5001, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceSearching_String = 5002, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceSearchingAlert_String = 5003, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceReady_String = 5004, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceReadyAlert_String = 5005, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceNotReady_String = 5006, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceStandby_String = 5007, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceAlertLow_String = 5008, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_IconPathName_String = 5000, // DEPRECATED. Value not referenced. Now expected to be part of icon path properties. + Prop_NamedIconPathDeviceOff_String = 5001, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceSearching_String = 5002, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceSearchingAlert_String = 5003, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceReady_String = 5004, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceReadyAlert_String = 5005, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceNotReady_String = 5006, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceStandby_String = 5007, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceAlertLow_String = 5008, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others // Properties that are used by helpers, but are opaque to applications - Prop_DisplayHiddenArea_Binary_Start = 5100, - Prop_DisplayHiddenArea_Binary_End = 5150, + Prop_DisplayHiddenArea_Binary_Start = 5100, + Prop_DisplayHiddenArea_Binary_End = 5150, // Properties that are unique to drivers - Prop_UserConfigPath_String = 6000, - Prop_InstallPath_String = 6001, - Prop_HasDisplayComponent_Bool = 6002, - Prop_HasControllerComponent_Bool = 6003, - Prop_HasCameraComponent_Bool = 6004, - Prop_HasDriverDirectModeComponent_Bool = 6005, - Prop_HasVirtualDisplayComponent_Bool = 6006, + Prop_UserConfigPath_String = 6000, + Prop_InstallPath_String = 6001, + Prop_HasDisplayComponent_Bool = 6002, + Prop_HasControllerComponent_Bool = 6003, + Prop_HasCameraComponent_Bool = 6004, + Prop_HasDriverDirectModeComponent_Bool = 6005, + Prop_HasVirtualDisplayComponent_Bool = 6006, // Vendors are free to expose private debug data in this reserved region - Prop_VendorSpecific_Reserved_Start = 10000, - Prop_VendorSpecific_Reserved_End = 10999, + Prop_VendorSpecific_Reserved_Start = 10000, + Prop_VendorSpecific_Reserved_End = 10999, }; /** No string property will ever be longer than this length */ @@ -371,18 +366,18 @@ static const uint32_t k_unMaxPropertyStringSize = 32 * 1024; /** Used to return errors that occur when reading properties. */ enum ETrackedPropertyError { - TrackedProp_Success = 0, - TrackedProp_WrongDataType = 1, - TrackedProp_WrongDeviceClass = 2, - TrackedProp_BufferTooSmall = 3, - TrackedProp_UnknownProperty = 4, // Driver has not set the property (and may not ever). - TrackedProp_InvalidDevice = 5, - TrackedProp_CouldNotContactServer = 6, - TrackedProp_ValueNotProvidedByDevice = 7, - TrackedProp_StringExceedsMaximumLength = 8, - TrackedProp_NotYetAvailable = 9, // The property value isn't known yet, but is expected soon. Call again later. - TrackedProp_PermissionDenied = 10, - TrackedProp_InvalidOperation = 11, + TrackedProp_Success = 0, + TrackedProp_WrongDataType = 1, + TrackedProp_WrongDeviceClass = 2, + TrackedProp_BufferTooSmall = 3, + TrackedProp_UnknownProperty = 4, // Driver has not set the property (and may not ever). + TrackedProp_InvalidDevice = 5, + TrackedProp_CouldNotContactServer = 6, + TrackedProp_ValueNotProvidedByDevice = 7, + TrackedProp_StringExceedsMaximumLength = 8, + TrackedProp_NotYetAvailable = 9, // The property value isn't known yet, but is expected soon. Call again later. + TrackedProp_PermissionDenied = 10, + TrackedProp_InvalidOperation = 11, }; /** Allows the application to control what part of the provided texture will be used in the @@ -396,7 +391,7 @@ struct VRTextureBounds_t /** Allows specifying pose used to render provided scene texture (if different from value returned by WaitGetPoses). */ struct VRTextureWithPose_t : public Texture_t { - HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures. + HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures. }; /** Allows the application to control how scene textures are used by the compositor when calling Submit. */ @@ -424,7 +419,7 @@ enum EVRSubmitFlags * Be sure to call OpenVR_Shutdown before destroying these resources. */ struct VRVulkanTextureData_t { - uint64_t m_nImage; // VkImage + uint64_t m_nImage; // VkImage VkDevice_T *m_pDevice; VkPhysicalDevice_T *m_pPhysicalDevice; VkInstance_T *m_pInstance; @@ -461,220 +456,216 @@ enum EVREventType { VREvent_None = 0, - VREvent_TrackedDeviceActivated = 100, - VREvent_TrackedDeviceDeactivated = 101, - VREvent_TrackedDeviceUpdated = 102, - VREvent_TrackedDeviceUserInteractionStarted = 103, - VREvent_TrackedDeviceUserInteractionEnded = 104, - VREvent_IpdChanged = 105, - VREvent_EnterStandbyMode = 106, - VREvent_LeaveStandbyMode = 107, - VREvent_TrackedDeviceRoleChanged = 108, - VREvent_WatchdogWakeUpRequested = 109, - VREvent_LensDistortionChanged = 110, - VREvent_PropertyChanged = 111, - VREvent_WirelessDisconnect = 112, - VREvent_WirelessReconnect = 113, + VREvent_TrackedDeviceActivated = 100, + VREvent_TrackedDeviceDeactivated = 101, + VREvent_TrackedDeviceUpdated = 102, + VREvent_TrackedDeviceUserInteractionStarted = 103, + VREvent_TrackedDeviceUserInteractionEnded = 104, + VREvent_IpdChanged = 105, + VREvent_EnterStandbyMode = 106, + VREvent_LeaveStandbyMode = 107, + VREvent_TrackedDeviceRoleChanged = 108, + VREvent_WatchdogWakeUpRequested = 109, + VREvent_LensDistortionChanged = 110, + VREvent_PropertyChanged = 111, + VREvent_WirelessDisconnect = 112, + VREvent_WirelessReconnect = 113, - VREvent_ButtonPress = 200, // data is controller - VREvent_ButtonUnpress = 201, // data is controller - VREvent_ButtonTouch = 202, // data is controller - VREvent_ButtonUntouch = 203, // data is controller + VREvent_ButtonPress = 200, // data is controller + VREvent_ButtonUnpress = 201, // data is controller + VREvent_ButtonTouch = 202, // data is controller + VREvent_ButtonUntouch = 203, // data is controller - VREvent_MouseMove = 300, // data is mouse - VREvent_MouseButtonDown = 301, // data is mouse - VREvent_MouseButtonUp = 302, // data is mouse - VREvent_FocusEnter = 303, // data is overlay - VREvent_FocusLeave = 304, // data is overlay - VREvent_Scroll = 305, // data is mouse - VREvent_TouchPadMove = 306, // data is mouse - VREvent_OverlayFocusChanged = 307, // data is overlay, global event + VREvent_MouseMove = 300, // data is mouse + VREvent_MouseButtonDown = 301, // data is mouse + VREvent_MouseButtonUp = 302, // data is mouse + VREvent_FocusEnter = 303, // data is overlay + VREvent_FocusLeave = 304, // data is overlay + VREvent_Scroll = 305, // data is mouse + VREvent_TouchPadMove = 306, // data is mouse + VREvent_OverlayFocusChanged = 307, // data is overlay, global event - VREvent_InputFocusCaptured = 400, // data is process DEPRECATED - VREvent_InputFocusReleased = 401, // data is process DEPRECATED - VREvent_SceneFocusLost = 402, // data is process - VREvent_SceneFocusGained = 403, // data is process - VREvent_SceneApplicationChanged = 404, // data is process - The App actually drawing the scene changed (usually to or from the compositor) - VREvent_SceneFocusChanged = 405, // data is process - New app got access to draw the scene - VREvent_InputFocusChanged = 406, // data is process - VREvent_SceneApplicationSecondaryRenderingStarted = 407, // data is process + VREvent_InputFocusCaptured = 400, // data is process DEPRECATED + VREvent_InputFocusReleased = 401, // data is process DEPRECATED + VREvent_SceneFocusLost = 402, // data is process + VREvent_SceneFocusGained = 403, // data is process + VREvent_SceneApplicationChanged = 404, // data is process - The App actually drawing the scene changed (usually to or from the compositor) + VREvent_SceneFocusChanged = 405, // data is process - New app got access to draw the scene + VREvent_InputFocusChanged = 406, // data is process + VREvent_SceneApplicationSecondaryRenderingStarted = 407, // data is process - VREvent_HideRenderModels = 410, // Sent to the scene application to request hiding render models temporarily - VREvent_ShowRenderModels = 411, // Sent to the scene application to request restoring render model visibility + VREvent_HideRenderModels = 410, // Sent to the scene application to request hiding render models temporarily + VREvent_ShowRenderModels = 411, // Sent to the scene application to request restoring render model visibility - VREvent_OverlayShown = 500, - VREvent_OverlayHidden = 501, - VREvent_DashboardActivated = 502, - VREvent_DashboardDeactivated = 503, - VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay - VREvent_DashboardRequested = 505, // Sent to the overlay manager - data is overlay - VREvent_ResetDashboard = 506, // Send to the overlay manager - VREvent_RenderToast = 507, // Send to the dashboard to render a toast - data is the notification ID - VREvent_ImageLoaded = 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading - VREvent_ShowKeyboard = 509, // Sent to keyboard renderer in the dashboard to invoke it - VREvent_HideKeyboard = 510, // Sent to keyboard renderer in the dashboard to hide it - VREvent_OverlayGamepadFocusGained = 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it - VREvent_OverlayGamepadFocusLost = 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else + VREvent_OverlayShown = 500, + VREvent_OverlayHidden = 501, + VREvent_DashboardActivated = 502, + VREvent_DashboardDeactivated = 503, + VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay + VREvent_DashboardRequested = 505, // Sent to the overlay manager - data is overlay + VREvent_ResetDashboard = 506, // Send to the overlay manager + VREvent_RenderToast = 507, // Send to the dashboard to render a toast - data is the notification ID + VREvent_ImageLoaded = 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading + VREvent_ShowKeyboard = 509, // Sent to keyboard renderer in the dashboard to invoke it + VREvent_HideKeyboard = 510, // Sent to keyboard renderer in the dashboard to hide it + VREvent_OverlayGamepadFocusGained = 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it + VREvent_OverlayGamepadFocusLost = 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else VREvent_OverlaySharedTextureChanged = 513, - VREvent_DashboardGuideButtonDown = 514, - VREvent_DashboardGuideButtonUp = 515, - VREvent_ScreenshotTriggered = 516, // Screenshot button combo was pressed, Dashboard should request a screenshot - VREvent_ImageFailed = 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load - VREvent_DashboardOverlayCreated = 518, + VREvent_DashboardGuideButtonDown = 514, + VREvent_DashboardGuideButtonUp = 515, + VREvent_ScreenshotTriggered = 516, // Screenshot button combo was pressed, Dashboard should request a screenshot + VREvent_ImageFailed = 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load + VREvent_DashboardOverlayCreated = 518, // Screenshot API - VREvent_RequestScreenshot = 520, // Sent by vrclient application to compositor to take a screenshot - VREvent_ScreenshotTaken = 521, // Sent by compositor to the application that the screenshot has been taken - VREvent_ScreenshotFailed = 522, // Sent by compositor to the application that the screenshot failed to be taken - VREvent_SubmitScreenshotToDashboard = 523, // Sent by compositor to the dashboard that a completed screenshot was submitted - VREvent_ScreenshotProgressToDashboard = 524, // Sent by compositor to the dashboard that a completed screenshot was submitted + VREvent_RequestScreenshot = 520, // Sent by vrclient application to compositor to take a screenshot + VREvent_ScreenshotTaken = 521, // Sent by compositor to the application that the screenshot has been taken + VREvent_ScreenshotFailed = 522, // Sent by compositor to the application that the screenshot failed to be taken + VREvent_SubmitScreenshotToDashboard = 523, // Sent by compositor to the dashboard that a completed screenshot was submitted + VREvent_ScreenshotProgressToDashboard = 524, // Sent by compositor to the dashboard that a completed screenshot was submitted - VREvent_PrimaryDashboardDeviceChanged = 525, + VREvent_PrimaryDashboardDeviceChanged = 525, - VREvent_Notification_Shown = 600, - VREvent_Notification_Hidden = 601, - VREvent_Notification_BeginInteraction = 602, - VREvent_Notification_Destroyed = 603, + VREvent_Notification_Shown = 600, + VREvent_Notification_Hidden = 601, + VREvent_Notification_BeginInteraction = 602, + VREvent_Notification_Destroyed = 603, - VREvent_Quit = 700, // data is process - VREvent_ProcessQuit = 701, // data is process - VREvent_QuitAborted_UserPrompt = 702, // data is process - VREvent_QuitAcknowledged = 703, // data is process - VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down + VREvent_Quit = 700, // data is process + VREvent_ProcessQuit = 701, // data is process + VREvent_QuitAborted_UserPrompt = 702, // data is process + VREvent_QuitAcknowledged = 703, // data is process + VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down - VREvent_ChaperoneDataHasChanged = 800, - VREvent_ChaperoneUniverseHasChanged = 801, - VREvent_ChaperoneTempDataHasChanged = 802, - VREvent_ChaperoneSettingsHaveChanged = 803, - VREvent_SeatedZeroPoseReset = 804, + VREvent_ChaperoneDataHasChanged = 800, + VREvent_ChaperoneUniverseHasChanged = 801, + VREvent_ChaperoneTempDataHasChanged = 802, + VREvent_ChaperoneSettingsHaveChanged = 803, + VREvent_SeatedZeroPoseReset = 804, - VREvent_AudioSettingsHaveChanged = 820, + VREvent_AudioSettingsHaveChanged = 820, - VREvent_BackgroundSettingHasChanged = 850, - VREvent_CameraSettingsHaveChanged = 851, - VREvent_ReprojectionSettingHasChanged = 852, - VREvent_ModelSkinSettingsHaveChanged = 853, - VREvent_EnvironmentSettingsHaveChanged = 854, - VREvent_PowerSettingsHaveChanged = 855, + VREvent_BackgroundSettingHasChanged = 850, + VREvent_CameraSettingsHaveChanged = 851, + VREvent_ReprojectionSettingHasChanged = 852, + VREvent_ModelSkinSettingsHaveChanged = 853, + VREvent_EnvironmentSettingsHaveChanged = 854, + VREvent_PowerSettingsHaveChanged = 855, VREvent_EnableHomeAppSettingsHaveChanged = 856, - VREvent_StatusUpdate = 900, + VREvent_StatusUpdate = 900, - VREvent_MCImageUpdated = 1000, + VREvent_MCImageUpdated = 1000, - VREvent_FirmwareUpdateStarted = 1100, - VREvent_FirmwareUpdateFinished = 1101, + VREvent_FirmwareUpdateStarted = 1100, + VREvent_FirmwareUpdateFinished = 1101, - VREvent_KeyboardClosed = 1200, - VREvent_KeyboardCharInput = 1201, - VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard + VREvent_KeyboardClosed = 1200, + VREvent_KeyboardCharInput = 1201, + VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard - VREvent_ApplicationTransitionStarted = 1300, - VREvent_ApplicationTransitionAborted = 1301, - VREvent_ApplicationTransitionNewAppStarted = 1302, - VREvent_ApplicationListUpdated = 1303, - VREvent_ApplicationMimeTypeLoad = 1304, + VREvent_ApplicationTransitionStarted = 1300, + VREvent_ApplicationTransitionAborted = 1301, + VREvent_ApplicationTransitionNewAppStarted = 1302, + VREvent_ApplicationListUpdated = 1303, + VREvent_ApplicationMimeTypeLoad = 1304, VREvent_ApplicationTransitionNewAppLaunchComplete = 1305, - VREvent_ProcessConnected = 1306, - VREvent_ProcessDisconnected = 1307, + VREvent_ProcessConnected = 1306, + VREvent_ProcessDisconnected = 1307, - VREvent_Compositor_MirrorWindowShown = 1400, - VREvent_Compositor_MirrorWindowHidden = 1401, - VREvent_Compositor_ChaperoneBoundsShown = 1410, - VREvent_Compositor_ChaperoneBoundsHidden = 1411, + VREvent_Compositor_MirrorWindowShown = 1400, + VREvent_Compositor_MirrorWindowHidden = 1401, + VREvent_Compositor_ChaperoneBoundsShown = 1410, + VREvent_Compositor_ChaperoneBoundsHidden = 1411, - VREvent_TrackedCamera_StartVideoStream = 1500, - VREvent_TrackedCamera_StopVideoStream = 1501, - VREvent_TrackedCamera_PauseVideoStream = 1502, + VREvent_TrackedCamera_StartVideoStream = 1500, + VREvent_TrackedCamera_StopVideoStream = 1501, + VREvent_TrackedCamera_PauseVideoStream = 1502, VREvent_TrackedCamera_ResumeVideoStream = 1503, - VREvent_TrackedCamera_EditingSurface = 1550, + VREvent_TrackedCamera_EditingSurface = 1550, - VREvent_PerformanceTest_EnableCapture = 1600, - VREvent_PerformanceTest_DisableCapture = 1601, - VREvent_PerformanceTest_FidelityLevel = 1602, + VREvent_PerformanceTest_EnableCapture = 1600, + VREvent_PerformanceTest_DisableCapture = 1601, + VREvent_PerformanceTest_FidelityLevel = 1602, + + VREvent_MessageOverlay_Closed = 1650, + VREvent_MessageOverlayCloseRequested = 1651, - VREvent_MessageOverlay_Closed = 1650, - VREvent_MessageOverlayCloseRequested = 1651, - // Vendors are free to expose private events in this reserved region - VREvent_VendorSpecific_Reserved_Start = 10000, - VREvent_VendorSpecific_Reserved_End = 19999, + VREvent_VendorSpecific_Reserved_Start = 10000, + VREvent_VendorSpecific_Reserved_End = 19999, }; - /** Level of Hmd activity */ // UserInteraction_Timeout means the device is in the process of timing out. // InUse = ( k_EDeviceActivityLevel_UserInteraction || k_EDeviceActivityLevel_UserInteraction_Timeout ) // VREvent_TrackedDeviceUserInteractionStarted fires when the devices transitions from Standby -> UserInteraction or Idle -> UserInteraction. // VREvent_TrackedDeviceUserInteractionEnded fires when the devices transitions from UserInteraction_Timeout -> Idle enum EDeviceActivityLevel -{ - k_EDeviceActivityLevel_Unknown = -1, - k_EDeviceActivityLevel_Idle = 0, // No activity for the last 10 seconds - k_EDeviceActivityLevel_UserInteraction = 1, // Activity (movement or prox sensor) is happening now - k_EDeviceActivityLevel_UserInteraction_Timeout = 2, // No activity for the last 0.5 seconds - k_EDeviceActivityLevel_Standby = 3, // Idle for at least 5 seconds (configurable in Settings -> Power Management) +{ + k_EDeviceActivityLevel_Unknown = -1, + k_EDeviceActivityLevel_Idle = 0, // No activity for the last 10 seconds + k_EDeviceActivityLevel_UserInteraction = 1, // Activity (movement or prox sensor) is happening now + k_EDeviceActivityLevel_UserInteraction_Timeout = 2, // No activity for the last 0.5 seconds + k_EDeviceActivityLevel_Standby = 3, // Idle for at least 5 seconds (configurable in Settings -> Power Management) }; - /** VR controller button and axis IDs */ enum EVRButtonId { - k_EButton_System = 0, - k_EButton_ApplicationMenu = 1, - k_EButton_Grip = 2, - k_EButton_DPad_Left = 3, - k_EButton_DPad_Up = 4, - k_EButton_DPad_Right = 5, - k_EButton_DPad_Down = 6, - k_EButton_A = 7, - - k_EButton_ProximitySensor = 31, + k_EButton_System = 0, + k_EButton_ApplicationMenu = 1, + k_EButton_Grip = 2, + k_EButton_DPad_Left = 3, + k_EButton_DPad_Up = 4, + k_EButton_DPad_Right = 5, + k_EButton_DPad_Down = 6, + k_EButton_A = 7, - k_EButton_Axis0 = 32, - k_EButton_Axis1 = 33, - k_EButton_Axis2 = 34, - k_EButton_Axis3 = 35, - k_EButton_Axis4 = 36, + k_EButton_ProximitySensor = 31, + + k_EButton_Axis0 = 32, + k_EButton_Axis1 = 33, + k_EButton_Axis2 = 34, + k_EButton_Axis3 = 35, + k_EButton_Axis4 = 36, // aliases for well known controllers - k_EButton_SteamVR_Touchpad = k_EButton_Axis0, - k_EButton_SteamVR_Trigger = k_EButton_Axis1, + k_EButton_SteamVR_Touchpad = k_EButton_Axis0, + k_EButton_SteamVR_Trigger = k_EButton_Axis1, - k_EButton_Dashboard_Back = k_EButton_Grip, + k_EButton_Dashboard_Back = k_EButton_Grip, - k_EButton_Max = 64 + k_EButton_Max = 64 }; -inline uint64_t ButtonMaskFromId( EVRButtonId id ) { return 1ull << id; } +inline uint64_t ButtonMaskFromId(EVRButtonId id) { return 1ull << id; } /** used for controller button events */ struct VREvent_Controller_t { - uint32_t button; // EVRButtonId enum + uint32_t button; // EVRButtonId enum }; - /** used for simulated mouse events in overlay space */ enum EVRMouseButton { - VRMouseButton_Left = 0x0001, - VRMouseButton_Right = 0x0002, - VRMouseButton_Middle = 0x0004, + VRMouseButton_Left = 0x0001, + VRMouseButton_Right = 0x0002, + VRMouseButton_Middle = 0x0004, }; - /** used for simulated mouse events in overlay space */ struct VREvent_Mouse_t { - float x, y; // co-ords are in GL space, bottom left of the texture is 0,0 - uint32_t button; // EVRMouseButton enum + float x, y; // co-ords are in GL space, bottom left of the texture is 0,0 + uint32_t button; // EVRMouseButton enum }; /** used for simulated mouse wheel scroll in overlay space */ struct VREvent_Scroll_t { - float xdelta, ydelta; // movement in fraction of the pad traversed since last delta, 1.0 for a full swipe + float xdelta, ydelta; // movement in fraction of the pad traversed since last delta, 1.0 for a full swipe uint32_t repeatCount; }; @@ -713,25 +704,23 @@ struct VREvent_Process_t bool bForced; }; - /** Used for a few events about overlays */ struct VREvent_Overlay_t { uint64_t overlayHandle; }; - /** Used for a few events about overlays */ struct VREvent_Status_t { - uint32_t statusState; // EVRState enum + uint32_t statusState; // EVRState enum }; /** Used for keyboard events **/ struct VREvent_Keyboard_t { - char cNewInput[8]; // Up to 11 bytes of new input - uint64_t uUserValue; // Possible flags about the new input + char cNewInput[8]; // Up to 11 bytes of new input + uint64_t uUserValue; // Possible flags about the new input }; struct VREvent_Ipd_t @@ -787,7 +776,7 @@ struct VREvent_EditingCameraSurface_t struct VREvent_MessageOverlay_t { - uint32_t unVRMessageOverlayResponse; // vr::VRMessageOverlayResponse enum + uint32_t unVRMessageOverlayResponse; // vr::VRMessageOverlayResponse enum }; struct VREvent_Property_t @@ -797,8 +786,7 @@ struct VREvent_Property_t }; /** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py */ -typedef union -{ +typedef union { VREvent_Reserved_t reserved; VREvent_Controller_t controller; VREvent_Mouse_t mouse; @@ -821,25 +809,24 @@ typedef union VREvent_Property_t property; } VREvent_Data_t; - -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif /** An event posted by the server to all running applications */ struct VREvent_t { - uint32_t eventType; // EVREventType enum + uint32_t eventType; // EVREventType enum TrackedDeviceIndex_t trackedDeviceIndex; float eventAgeSeconds; // event data must be the end of the struct as its size is variable VREvent_Data_t data; }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif /** The mesh to draw into the stencil (or depth) buffer to perform @@ -854,7 +841,6 @@ struct HiddenAreaMesh_t uint32_t unTriangleCount; }; - enum EHiddenAreaMeshType { k_eHiddenAreaMesh_Standard = 0, @@ -864,7 +850,6 @@ enum EHiddenAreaMeshType k_eHiddenAreaMesh_Max = 3, }; - /** Identifies what kind of axis is on the controller at index n. Read this type * with pVRSystem->Get( nControllerDeviceIndex, Prop_Axis0Type_Int32 + n ); */ @@ -873,32 +858,29 @@ enum EVRControllerAxisType k_eControllerAxis_None = 0, k_eControllerAxis_TrackPad = 1, k_eControllerAxis_Joystick = 2, - k_eControllerAxis_Trigger = 3, // Analog trigger data is in the X axis + k_eControllerAxis_Trigger = 3, // Analog trigger data is in the X axis }; - /** contains information about one axis on the controller */ struct VRControllerAxis_t { - float x; // Ranges from -1.0 to 1.0 for joysticks and track pads. Ranges from 0.0 to 1.0 for triggers were 0 is fully released. - float y; // Ranges from -1.0 to 1.0 for joysticks and track pads. Is always 0.0 for triggers. + float x; // Ranges from -1.0 to 1.0 for joysticks and track pads. Ranges from 0.0 to 1.0 for triggers were 0 is fully released. + float y; // Ranges from -1.0 to 1.0 for joysticks and track pads. Is always 0.0 for triggers. }; - /** the number of axes in the controller state */ static const uint32_t k_unControllerStateAxisCount = 5; - -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif /** Holds all the state of a controller at one moment in time. */ struct VRControllerState001_t { - // If packet num matches that on your prior call, then the controller state hasn't been changed since + // If packet num matches that on your prior call, then the controller state hasn't been changed since // your last call and there is no need to process it uint32_t unPacketNum; @@ -907,16 +889,14 @@ struct VRControllerState001_t uint64_t ulButtonTouched; // Axis data for the controller's analog inputs - VRControllerAxis_t rAxis[ k_unControllerStateAxisCount ]; + VRControllerAxis_t rAxis[k_unControllerStateAxisCount]; }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif - typedef VRControllerState001_t VRControllerState_t; - /** determines how to provide output to the application of various event processing functions. */ enum EVRControllerEventOutputType { @@ -924,8 +904,6 @@ enum EVRControllerEventOutputType ControllerEventOutput_VREvents = 1, }; - - /** Collision Bounds Style */ enum ECollisionBoundsStyle { @@ -941,7 +919,7 @@ enum ECollisionBoundsStyle /** Allows the application to customize how the overlay appears in the compositor */ struct Compositor_OverlaySettings { - uint32_t size; // sizeof(Compositor_OverlaySettings) + uint32_t size; // sizeof(Compositor_OverlaySettings) bool curved, antialias; float scale, distance, alpha; float uOffset, vOffset, uScale, vScale; @@ -957,49 +935,48 @@ static const VROverlayHandle_t k_ulOverlayHandleInvalid = 0; /** Errors that can occur around VR overlays */ enum EVROverlayError { - VROverlayError_None = 0, + VROverlayError_None = 0, - VROverlayError_UnknownOverlay = 10, - VROverlayError_InvalidHandle = 11, - VROverlayError_PermissionDenied = 12, - VROverlayError_OverlayLimitExceeded = 13, // No more overlays could be created because the maximum number already exist - VROverlayError_WrongVisibilityType = 14, - VROverlayError_KeyTooLong = 15, - VROverlayError_NameTooLong = 16, - VROverlayError_KeyInUse = 17, - VROverlayError_WrongTransformType = 18, - VROverlayError_InvalidTrackedDevice = 19, - VROverlayError_InvalidParameter = 20, - VROverlayError_ThumbnailCantBeDestroyed = 21, - VROverlayError_ArrayTooSmall = 22, - VROverlayError_RequestFailed = 23, - VROverlayError_InvalidTexture = 24, - VROverlayError_UnableToLoadFile = 25, - VROverlayError_KeyboardAlreadyInUse = 26, - VROverlayError_NoNeighbor = 27, - VROverlayError_TooManyMaskPrimitives = 29, - VROverlayError_BadMaskPrimitive = 30, + VROverlayError_UnknownOverlay = 10, + VROverlayError_InvalidHandle = 11, + VROverlayError_PermissionDenied = 12, + VROverlayError_OverlayLimitExceeded = 13, // No more overlays could be created because the maximum number already exist + VROverlayError_WrongVisibilityType = 14, + VROverlayError_KeyTooLong = 15, + VROverlayError_NameTooLong = 16, + VROverlayError_KeyInUse = 17, + VROverlayError_WrongTransformType = 18, + VROverlayError_InvalidTrackedDevice = 19, + VROverlayError_InvalidParameter = 20, + VROverlayError_ThumbnailCantBeDestroyed = 21, + VROverlayError_ArrayTooSmall = 22, + VROverlayError_RequestFailed = 23, + VROverlayError_InvalidTexture = 24, + VROverlayError_UnableToLoadFile = 25, + VROverlayError_KeyboardAlreadyInUse = 26, + VROverlayError_NoNeighbor = 27, + VROverlayError_TooManyMaskPrimitives = 29, + VROverlayError_BadMaskPrimitive = 30, }; /** enum values to pass in to VR_Init to identify whether the application will * draw a 3D scene. */ enum EVRApplicationType { - VRApplication_Other = 0, // Some other kind of application that isn't covered by the other entries - VRApplication_Scene = 1, // Application will submit 3D frames - VRApplication_Overlay = 2, // Application only interacts with overlays - VRApplication_Background = 3, // Application should not start SteamVR if it's not already running, and should not - // keep it running if everything else quits. - VRApplication_Utility = 4, // Init should not try to load any drivers. The application needs access to utility - // interfaces (like IVRSettings and IVRApplications) but not hardware. - VRApplication_VRMonitor = 5, // Reserved for vrmonitor - VRApplication_SteamWatchdog = 6,// Reserved for Steam - VRApplication_Bootstrapper = 7, // Start up SteamVR + VRApplication_Other = 0, // Some other kind of application that isn't covered by the other entries + VRApplication_Scene = 1, // Application will submit 3D frames + VRApplication_Overlay = 2, // Application only interacts with overlays + VRApplication_Background = 3, // Application should not start SteamVR if it's not already running, and should not + // keep it running if everything else quits. + VRApplication_Utility = 4, // Init should not try to load any drivers. The application needs access to utility + // interfaces (like IVRSettings and IVRApplications) but not hardware. + VRApplication_VRMonitor = 5, // Reserved for vrmonitor + VRApplication_SteamWatchdog = 6, // Reserved for Steam + VRApplication_Bootstrapper = 7, // Start up SteamVR VRApplication_Max }; - /** error codes for firmware */ enum EVRFirmwareError { @@ -1008,7 +985,6 @@ enum EVRFirmwareError VRFirmwareError_Fail = 2, }; - /** error codes for notifications */ enum EVRNotificationError { @@ -1019,103 +995,101 @@ enum EVRNotificationError VRNotificationError_SystemWithUserValueAlreadyExists = 103, }; - /** error codes returned by Vr_Init */ // Please add adequate error description to https://developer.valvesoftware.com/w/index.php?title=Category:SteamVRHelp enum EVRInitError { - VRInitError_None = 0, + VRInitError_None = 0, VRInitError_Unknown = 1, - VRInitError_Init_InstallationNotFound = 100, - VRInitError_Init_InstallationCorrupt = 101, - VRInitError_Init_VRClientDLLNotFound = 102, - VRInitError_Init_FileNotFound = 103, - VRInitError_Init_FactoryNotFound = 104, - VRInitError_Init_InterfaceNotFound = 105, - VRInitError_Init_InvalidInterface = 106, - VRInitError_Init_UserConfigDirectoryInvalid = 107, - VRInitError_Init_HmdNotFound = 108, - VRInitError_Init_NotInitialized = 109, - VRInitError_Init_PathRegistryNotFound = 110, - VRInitError_Init_NoConfigPath = 111, - VRInitError_Init_NoLogPath = 112, - VRInitError_Init_PathRegistryNotWritable = 113, - VRInitError_Init_AppInfoInitFailed = 114, - VRInitError_Init_Retry = 115, // Used internally to cause retries to vrserver - VRInitError_Init_InitCanceledByUser = 116, // The calling application should silently exit. The user canceled app startup - VRInitError_Init_AnotherAppLaunching = 117, - VRInitError_Init_SettingsInitFailed = 118, - VRInitError_Init_ShuttingDown = 119, - VRInitError_Init_TooManyObjects = 120, - VRInitError_Init_NoServerForBackgroundApp = 121, - VRInitError_Init_NotSupportedWithCompositor = 122, - VRInitError_Init_NotAvailableToUtilityApps = 123, - VRInitError_Init_Internal = 124, - VRInitError_Init_HmdDriverIdIsNone = 125, - VRInitError_Init_HmdNotFoundPresenceFailed = 126, - VRInitError_Init_VRMonitorNotFound = 127, - VRInitError_Init_VRMonitorStartupFailed = 128, - VRInitError_Init_LowPowerWatchdogNotSupported = 129, - VRInitError_Init_InvalidApplicationType = 130, - VRInitError_Init_NotAvailableToWatchdogApps = 131, - VRInitError_Init_WatchdogDisabledInSettings = 132, - VRInitError_Init_VRDashboardNotFound = 133, - VRInitError_Init_VRDashboardStartupFailed = 134, - VRInitError_Init_VRHomeNotFound = 135, - VRInitError_Init_VRHomeStartupFailed = 136, - VRInitError_Init_RebootingBusy = 137, - VRInitError_Init_FirmwareUpdateBusy = 138, - VRInitError_Init_FirmwareRecoveryBusy = 139, + VRInitError_Init_InstallationNotFound = 100, + VRInitError_Init_InstallationCorrupt = 101, + VRInitError_Init_VRClientDLLNotFound = 102, + VRInitError_Init_FileNotFound = 103, + VRInitError_Init_FactoryNotFound = 104, + VRInitError_Init_InterfaceNotFound = 105, + VRInitError_Init_InvalidInterface = 106, + VRInitError_Init_UserConfigDirectoryInvalid = 107, + VRInitError_Init_HmdNotFound = 108, + VRInitError_Init_NotInitialized = 109, + VRInitError_Init_PathRegistryNotFound = 110, + VRInitError_Init_NoConfigPath = 111, + VRInitError_Init_NoLogPath = 112, + VRInitError_Init_PathRegistryNotWritable = 113, + VRInitError_Init_AppInfoInitFailed = 114, + VRInitError_Init_Retry = 115, // Used internally to cause retries to vrserver + VRInitError_Init_InitCanceledByUser = 116, // The calling application should silently exit. The user canceled app startup + VRInitError_Init_AnotherAppLaunching = 117, + VRInitError_Init_SettingsInitFailed = 118, + VRInitError_Init_ShuttingDown = 119, + VRInitError_Init_TooManyObjects = 120, + VRInitError_Init_NoServerForBackgroundApp = 121, + VRInitError_Init_NotSupportedWithCompositor = 122, + VRInitError_Init_NotAvailableToUtilityApps = 123, + VRInitError_Init_Internal = 124, + VRInitError_Init_HmdDriverIdIsNone = 125, + VRInitError_Init_HmdNotFoundPresenceFailed = 126, + VRInitError_Init_VRMonitorNotFound = 127, + VRInitError_Init_VRMonitorStartupFailed = 128, + VRInitError_Init_LowPowerWatchdogNotSupported = 129, + VRInitError_Init_InvalidApplicationType = 130, + VRInitError_Init_NotAvailableToWatchdogApps = 131, + VRInitError_Init_WatchdogDisabledInSettings = 132, + VRInitError_Init_VRDashboardNotFound = 133, + VRInitError_Init_VRDashboardStartupFailed = 134, + VRInitError_Init_VRHomeNotFound = 135, + VRInitError_Init_VRHomeStartupFailed = 136, + VRInitError_Init_RebootingBusy = 137, + VRInitError_Init_FirmwareUpdateBusy = 138, + VRInitError_Init_FirmwareRecoveryBusy = 139, - - VRInitError_Driver_Failed = 200, - VRInitError_Driver_Unknown = 201, - VRInitError_Driver_HmdUnknown = 202, - VRInitError_Driver_NotLoaded = 203, - VRInitError_Driver_RuntimeOutOfDate = 204, - VRInitError_Driver_HmdInUse = 205, - VRInitError_Driver_NotCalibrated = 206, - VRInitError_Driver_CalibrationInvalid = 207, - VRInitError_Driver_HmdDisplayNotFound = 208, + VRInitError_Driver_Failed = 200, + VRInitError_Driver_Unknown = 201, + VRInitError_Driver_HmdUnknown = 202, + VRInitError_Driver_NotLoaded = 203, + VRInitError_Driver_RuntimeOutOfDate = 204, + VRInitError_Driver_HmdInUse = 205, + VRInitError_Driver_NotCalibrated = 206, + VRInitError_Driver_CalibrationInvalid = 207, + VRInitError_Driver_HmdDisplayNotFound = 208, VRInitError_Driver_TrackedDeviceInterfaceUnknown = 209, // VRInitError_Driver_HmdDisplayNotFoundAfterFix = 210, // not needed: here for historic reasons - VRInitError_Driver_HmdDriverIdOutOfBounds = 211, - VRInitError_Driver_HmdDisplayMirrored = 212, + VRInitError_Driver_HmdDriverIdOutOfBounds = 211, + VRInitError_Driver_HmdDisplayMirrored = 212, - VRInitError_IPC_ServerInitFailed = 300, - VRInitError_IPC_ConnectFailed = 301, - VRInitError_IPC_SharedStateInitFailed = 302, - VRInitError_IPC_CompositorInitFailed = 303, - VRInitError_IPC_MutexInitFailed = 304, - VRInitError_IPC_Failed = 305, - VRInitError_IPC_CompositorConnectFailed = 306, + VRInitError_IPC_ServerInitFailed = 300, + VRInitError_IPC_ConnectFailed = 301, + VRInitError_IPC_SharedStateInitFailed = 302, + VRInitError_IPC_CompositorInitFailed = 303, + VRInitError_IPC_MutexInitFailed = 304, + VRInitError_IPC_Failed = 305, + VRInitError_IPC_CompositorConnectFailed = 306, VRInitError_IPC_CompositorInvalidConnectResponse = 307, VRInitError_IPC_ConnectFailedAfterMultipleAttempts = 308, - VRInitError_Compositor_Failed = 400, - VRInitError_Compositor_D3D11HardwareRequired = 401, - VRInitError_Compositor_FirmwareRequiresUpdate = 402, - VRInitError_Compositor_OverlayInitFailed = 403, - VRInitError_Compositor_ScreenshotsInitFailed = 404, - VRInitError_Compositor_UnableToCreateDevice = 405, + VRInitError_Compositor_Failed = 400, + VRInitError_Compositor_D3D11HardwareRequired = 401, + VRInitError_Compositor_FirmwareRequiresUpdate = 402, + VRInitError_Compositor_OverlayInitFailed = 403, + VRInitError_Compositor_ScreenshotsInitFailed = 404, + VRInitError_Compositor_UnableToCreateDevice = 405, - VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000, + VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000, - VRInitError_VendorSpecific_HmdFound_CantOpenDevice = 1101, - VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102, - VRInitError_VendorSpecific_HmdFound_NoStoredConfig = 1103, - VRInitError_VendorSpecific_HmdFound_ConfigTooBig = 1104, - VRInitError_VendorSpecific_HmdFound_ConfigTooSmall = 1105, - VRInitError_VendorSpecific_HmdFound_UnableToInitZLib = 1106, - VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion = 1107, - VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart = 1108, - VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart = 1109, - VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext = 1110, - VRInitError_VendorSpecific_HmdFound_UserDataAddressRange = 1111, - VRInitError_VendorSpecific_HmdFound_UserDataError = 1112, - VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck = 1113, + VRInitError_VendorSpecific_HmdFound_CantOpenDevice = 1101, + VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102, + VRInitError_VendorSpecific_HmdFound_NoStoredConfig = 1103, + VRInitError_VendorSpecific_HmdFound_ConfigTooBig = 1104, + VRInitError_VendorSpecific_HmdFound_ConfigTooSmall = 1105, + VRInitError_VendorSpecific_HmdFound_UnableToInitZLib = 1106, + VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion = 1107, + VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart = 1108, + VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart = 1109, + VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext = 1110, + VRInitError_VendorSpecific_HmdFound_UserDataAddressRange = 1111, + VRInitError_VendorSpecific_HmdFound_UserDataError = 1112, + VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck = 1113, VRInitError_Steam_SteamInstallationNotFound = 2000, }; @@ -1123,7 +1097,7 @@ enum EVRInitError enum EVRScreenshotType { VRScreenshotType_None = 0, - VRScreenshotType_Mono = 1, // left eye only + VRScreenshotType_Mono = 1, // left eye only VRScreenshotType_Stereo = 2, VRScreenshotType_Cubemap = 3, VRScreenshotType_MonoPanorama = 4, @@ -1138,35 +1112,35 @@ enum EVRScreenshotPropertyFilenames enum EVRTrackedCameraError { - VRTrackedCameraError_None = 0, - VRTrackedCameraError_OperationFailed = 100, - VRTrackedCameraError_InvalidHandle = 101, - VRTrackedCameraError_InvalidFrameHeaderVersion = 102, - VRTrackedCameraError_OutOfHandles = 103, - VRTrackedCameraError_IPCFailure = 104, - VRTrackedCameraError_NotSupportedForThisDevice = 105, - VRTrackedCameraError_SharedMemoryFailure = 106, - VRTrackedCameraError_FrameBufferingFailure = 107, - VRTrackedCameraError_StreamSetupFailure = 108, - VRTrackedCameraError_InvalidGLTextureId = 109, + VRTrackedCameraError_None = 0, + VRTrackedCameraError_OperationFailed = 100, + VRTrackedCameraError_InvalidHandle = 101, + VRTrackedCameraError_InvalidFrameHeaderVersion = 102, + VRTrackedCameraError_OutOfHandles = 103, + VRTrackedCameraError_IPCFailure = 104, + VRTrackedCameraError_NotSupportedForThisDevice = 105, + VRTrackedCameraError_SharedMemoryFailure = 106, + VRTrackedCameraError_FrameBufferingFailure = 107, + VRTrackedCameraError_StreamSetupFailure = 108, + VRTrackedCameraError_InvalidGLTextureId = 109, VRTrackedCameraError_InvalidSharedTextureHandle = 110, - VRTrackedCameraError_FailedToGetGLTextureId = 111, - VRTrackedCameraError_SharedTextureFailure = 112, - VRTrackedCameraError_NoFrameAvailable = 113, - VRTrackedCameraError_InvalidArgument = 114, - VRTrackedCameraError_InvalidFrameBufferSize = 115, + VRTrackedCameraError_FailedToGetGLTextureId = 111, + VRTrackedCameraError_SharedTextureFailure = 112, + VRTrackedCameraError_NoFrameAvailable = 113, + VRTrackedCameraError_InvalidArgument = 114, + VRTrackedCameraError_InvalidFrameBufferSize = 115, }; enum EVRTrackedCameraFrameType { - VRTrackedCameraFrameType_Distorted = 0, // This is the camera video frame size in pixels, still distorted. - VRTrackedCameraFrameType_Undistorted, // In pixels, an undistorted inscribed rectangle region without invalid regions. This size is subject to changes shortly. - VRTrackedCameraFrameType_MaximumUndistorted, // In pixels, maximum undistorted with invalid regions. Non zero alpha component identifies valid regions. + VRTrackedCameraFrameType_Distorted = 0, // This is the camera video frame size in pixels, still distorted. + VRTrackedCameraFrameType_Undistorted, // In pixels, an undistorted inscribed rectangle region without invalid regions. This size is subject to changes shortly. + VRTrackedCameraFrameType_MaximumUndistorted, // In pixels, maximum undistorted with invalid regions. Non zero alpha component identifies valid regions. MAX_CAMERA_FRAME_TYPES }; typedef uint64_t TrackedCameraHandle_t; -#define INVALID_TRACKED_CAMERA_HANDLE ((vr::TrackedCameraHandle_t)0) +#define INVALID_TRACKED_CAMERA_HANDLE ((vr::TrackedCameraHandle_t)0) struct CameraVideoStreamFrameHeader_t { @@ -1186,15 +1160,15 @@ typedef uint32_t ScreenshotHandle_t; static const uint32_t k_unScreenshotHandleInvalid = 0; -#pragma pack( pop ) +#pragma pack(pop) // figure out how to import from the VR API dll #if defined(_WIN32) #ifdef VR_API_EXPORT -#define VR_INTERFACE extern "C" __declspec( dllexport ) +#define VR_INTERFACE extern "C" __declspec(dllexport) #else -#define VR_INTERFACE extern "C" __declspec( dllimport ) +#define VR_INTERFACE extern "C" __declspec(dllimport) #endif #elif defined(__GNUC__) || defined(COMPILER_GCC) || defined(__APPLE__) @@ -1202,59 +1176,56 @@ static const uint32_t k_unScreenshotHandleInvalid = 0; #ifdef VR_API_EXPORT #define VR_INTERFACE extern "C" __attribute__((visibility("default"))) #else -#define VR_INTERFACE extern "C" +#define VR_INTERFACE extern "C" #endif #else #error "Unsupported Platform." #endif - -#if defined( _WIN32 ) +#if defined(_WIN32) #define VR_CALLTYPE __cdecl #else -#define VR_CALLTYPE +#define VR_CALLTYPE #endif -} // namespace vr - -#endif // _INCLUDE_VRTYPES_H +} // namespace vr +#endif // _INCLUDE_VRTYPES_H // vrannotation.h #ifdef API_GEN -# define VR_CLANG_ATTR(ATTR) __attribute__((annotate( ATTR ))) +#define VR_CLANG_ATTR(ATTR) __attribute__((annotate(ATTR))) #else -# define VR_CLANG_ATTR(ATTR) +#define VR_CLANG_ATTR(ATTR) #endif -#define VR_METHOD_DESC(DESC) VR_CLANG_ATTR( "desc:" #DESC ";" ) -#define VR_IGNOREATTR() VR_CLANG_ATTR( "ignore" ) -#define VR_OUT_STRUCT() VR_CLANG_ATTR( "out_struct: ;" ) -#define VR_OUT_STRING() VR_CLANG_ATTR( "out_string: ;" ) -#define VR_OUT_ARRAY_CALL(COUNTER,FUNCTION,PARAMS) VR_CLANG_ATTR( "out_array_call:" #COUNTER "," #FUNCTION "," #PARAMS ";" ) -#define VR_OUT_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR( "out_array_count:" #COUNTER ";" ) -#define VR_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR( "array_count:" #COUNTER ";" ) -#define VR_ARRAY_COUNT_D(COUNTER, DESC) VR_CLANG_ATTR( "array_count:" #COUNTER ";desc:" #DESC ) -#define VR_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR( "buffer_count:" #COUNTER ";" ) -#define VR_OUT_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR( "out_buffer_count:" #COUNTER ";" ) -#define VR_OUT_STRING_COUNT(COUNTER) VR_CLANG_ATTR( "out_string_count:" #COUNTER ";" ) +#define VR_METHOD_DESC(DESC) VR_CLANG_ATTR("desc:" #DESC ";") +#define VR_IGNOREATTR() VR_CLANG_ATTR("ignore") +#define VR_OUT_STRUCT() VR_CLANG_ATTR("out_struct: ;") +#define VR_OUT_STRING() VR_CLANG_ATTR("out_string: ;") +#define VR_OUT_ARRAY_CALL(COUNTER, FUNCTION, PARAMS) VR_CLANG_ATTR("out_array_call:" #COUNTER "," #FUNCTION "," #PARAMS ";") +#define VR_OUT_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR("out_array_count:" #COUNTER ";") +#define VR_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR("array_count:" #COUNTER ";") +#define VR_ARRAY_COUNT_D(COUNTER, DESC) VR_CLANG_ATTR("array_count:" #COUNTER ";desc:" #DESC) +#define VR_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR("buffer_count:" #COUNTER ";") +#define VR_OUT_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR("out_buffer_count:" #COUNTER ";") +#define VR_OUT_STRING_COUNT(COUNTER) VR_CLANG_ATTR("out_string_count:" #COUNTER ";") // vrtrackedcameratypes.h #ifndef _VRTRACKEDCAMERATYPES_H -#define _VRTRACKEDCAMERATYPES_H +#define _VRTRACKEDCAMERATYPES_H namespace vr { - -#pragma pack( push, 8 ) +#pragma pack(push, 8) enum ECameraVideoStreamFormat { CVS_FORMAT_UNKNOWN = 0, - CVS_FORMAT_RAW10 = 1, // 10 bits per pixel - CVS_FORMAT_NV12 = 2, // 12 bits per pixel - CVS_FORMAT_RGB24 = 3, // 24 bits per pixel + CVS_FORMAT_RAW10 = 1, // 10 bits per pixel + CVS_FORMAT_NV12 = 2, // 12 bits per pixel + CVS_FORMAT_RGB24 = 3, // 24 bits per pixel CVS_MAX_FORMATS }; @@ -1277,30 +1248,31 @@ enum ECameraCompatibilityMode }; #ifdef _MSC_VER -#define VR_CAMERA_DECL_ALIGN( x ) __declspec( align( x ) ) +#define VR_CAMERA_DECL_ALIGN(x) __declspec(align(x)) #else -#define VR_CAMERA_DECL_ALIGN( x ) // +#define VR_CAMERA_DECL_ALIGN(x) // #endif -#define MAX_CAMERA_FRAME_SHARED_HANDLES 4 +#define MAX_CAMERA_FRAME_SHARED_HANDLES 4 -VR_CAMERA_DECL_ALIGN( 8 ) struct CameraVideoStreamFrame_t +VR_CAMERA_DECL_ALIGN(8) +struct CameraVideoStreamFrame_t { ECameraVideoStreamFormat m_nStreamFormat; uint32_t m_nWidth; uint32_t m_nHeight; - uint32_t m_nImageDataSize; // Based on stream format, width, height + uint32_t m_nImageDataSize; // Based on stream format, width, height - uint32_t m_nFrameSequence; // Starts from 0 when stream starts. + uint32_t m_nFrameSequence; // Starts from 0 when stream starts. - uint32_t m_nBufferIndex; // Identifies which buffer the image data is hosted - uint32_t m_nBufferCount; // Total number of configured buffers + uint32_t m_nBufferIndex; // Identifies which buffer the image data is hosted + uint32_t m_nBufferCount; // Total number of configured buffers uint32_t m_nExposureTime; - uint32_t m_nISPFrameTimeStamp; // Driver provided time stamp per driver centric time base + uint32_t m_nISPFrameTimeStamp; // Driver provided time stamp per driver centric time base uint32_t m_nISPReferenceTimeStamp; uint32_t m_nSyncCounter; @@ -1309,241 +1281,239 @@ VR_CAMERA_DECL_ALIGN( 8 ) struct CameraVideoStreamFrame_t double m_flReferenceCamSyncTime; - double m_flFrameElapsedTime; // Starts from 0 when stream starts. In seconds. + double m_flFrameElapsedTime; // Starts from 0 when stream starts. In seconds. double m_flFrameDeliveryRate; - double m_flFrameCaptureTime_DriverAbsolute; // In USB time, via AuxEvent - double m_flFrameCaptureTime_ServerRelative; // In System time within the server - uint64_t m_nFrameCaptureTicks_ServerAbsolute; // In system ticks within the server - double m_flFrameCaptureTime_ClientRelative; // At the client, relative to when the frame was exposed/captured. + double m_flFrameCaptureTime_DriverAbsolute; // In USB time, via AuxEvent + double m_flFrameCaptureTime_ServerRelative; // In System time within the server + uint64_t m_nFrameCaptureTicks_ServerAbsolute; // In system ticks within the server + double m_flFrameCaptureTime_ClientRelative; // At the client, relative to when the frame was exposed/captured. double m_flSyncMarkerError; - TrackedDevicePose_t m_StandingTrackedDevicePose; // Supplied by HMD layer when used as a tracked camera + TrackedDevicePose_t m_StandingTrackedDevicePose; // Supplied by HMD layer when used as a tracked camera uint64_t m_pImageData; }; -#pragma pack( pop ) +#pragma pack(pop) -} +} // namespace vr -#endif // _VRTRACKEDCAMERATYPES_H +#endif // _VRTRACKEDCAMERATYPES_H // ivrsettings.h namespace vr { - enum EVRSettingsError - { - VRSettingsError_None = 0, - VRSettingsError_IPCFailed = 1, - VRSettingsError_WriteFailed = 2, - VRSettingsError_ReadFailed = 3, - VRSettingsError_JsonParseFailed = 4, - VRSettingsError_UnsetSettingHasNoDefault = 5, // This will be returned if the setting does not appear in the appropriate default file and has not been set - }; +enum EVRSettingsError +{ + VRSettingsError_None = 0, + VRSettingsError_IPCFailed = 1, + VRSettingsError_WriteFailed = 2, + VRSettingsError_ReadFailed = 3, + VRSettingsError_JsonParseFailed = 4, + VRSettingsError_UnsetSettingHasNoDefault = 5, // This will be returned if the setting does not appear in the appropriate default file and has not been set +}; - // The maximum length of a settings key - static const uint32_t k_unMaxSettingsKeyLength = 128; +// The maximum length of a settings key +static const uint32_t k_unMaxSettingsKeyLength = 128; - class IVRSettings - { - public: - virtual const char *GetSettingsErrorNameFromEnum( EVRSettingsError eError ) = 0; +class IVRSettings +{ +public: + virtual const char *GetSettingsErrorNameFromEnum(EVRSettingsError eError) = 0; - // Returns true if file sync occurred (force or settings dirty) - virtual bool Sync( bool bForce = false, EVRSettingsError *peError = nullptr ) = 0; + // Returns true if file sync occurred (force or settings dirty) + virtual bool Sync(bool bForce = false, EVRSettingsError *peError = nullptr) = 0; - virtual void SetBool( const char *pchSection, const char *pchSettingsKey, bool bValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetInt32( const char *pchSection, const char *pchSettingsKey, int32_t nValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetFloat( const char *pchSection, const char *pchSettingsKey, float flValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetString( const char *pchSection, const char *pchSettingsKey, const char *pchValue, EVRSettingsError *peError = nullptr ) = 0; + virtual void SetBool(const char *pchSection, const char *pchSettingsKey, bool bValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetInt32(const char *pchSection, const char *pchSettingsKey, int32_t nValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetFloat(const char *pchSection, const char *pchSettingsKey, float flValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetString(const char *pchSection, const char *pchSettingsKey, const char *pchValue, EVRSettingsError *peError = nullptr) = 0; - // Users of the system need to provide a proper default in default.vrsettings in the resources/settings/ directory - // of either the runtime or the driver_xxx directory. Otherwise the default will be false, 0, 0.0 or "" - virtual bool GetBool( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual int32_t GetInt32( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual float GetFloat( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual void GetString( const char *pchSection, const char *pchSettingsKey, VR_OUT_STRING() char *pchValue, uint32_t unValueLen, EVRSettingsError *peError = nullptr ) = 0; + // Users of the system need to provide a proper default in default.vrsettings in the resources/settings/ directory + // of either the runtime or the driver_xxx directory. Otherwise the default will be false, 0, 0.0 or "" + virtual bool GetBool(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual int32_t GetInt32(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual float GetFloat(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual void GetString(const char *pchSection, const char *pchSettingsKey, VR_OUT_STRING() char *pchValue, uint32_t unValueLen, EVRSettingsError *peError = nullptr) = 0; - virtual void RemoveSection( const char *pchSection, EVRSettingsError *peError = nullptr ) = 0; - virtual void RemoveKeyInSection( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - }; + virtual void RemoveSection(const char *pchSection, EVRSettingsError *peError = nullptr) = 0; + virtual void RemoveKeyInSection(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; +}; - //----------------------------------------------------------------------------- - static const char * const IVRSettings_Version = "IVRSettings_002"; +//----------------------------------------------------------------------------- +static const char *const IVRSettings_Version = "IVRSettings_002"; - //----------------------------------------------------------------------------- - // steamvr keys - static const char * const k_pch_SteamVR_Section = "steamvr"; - static const char * const k_pch_SteamVR_RequireHmd_String = "requireHmd"; - static const char * const k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; - static const char * const k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; - static const char * const k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; - static const char * const k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; - static const char * const k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; - static const char * const k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; - static const char * const k_pch_SteamVR_SendSystemButtonToAllApps_Bool= "sendSystemButtonToAllApps"; - static const char * const k_pch_SteamVR_LogLevel_Int32 = "loglevel"; - static const char * const k_pch_SteamVR_IPD_Float = "ipd"; - static const char * const k_pch_SteamVR_Background_String = "background"; - static const char * const k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; - static const char * const k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; - static const char * const k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; - static const char * const k_pch_SteamVR_GridColor_String = "gridColor"; - static const char * const k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; - static const char * const k_pch_SteamVR_ShowStage_Bool = "showStage"; - static const char * const k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; - static const char * const k_pch_SteamVR_DirectMode_Bool = "directMode"; - static const char * const k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; - static const char * const k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; - static const char * const k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; - static const char * const k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; - static const char * const k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; - static const char * const k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; - static const char * const k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; - static const char * const k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; - static const char * const k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; - static const char * const k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; - static const char * const k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; - static const char * const k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; - static const char * const k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; - static const char * const k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; - static const char * const k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; - static const char * const k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; - static const char * const k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; - static const char * const k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; - static const char * const k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; - static const char * const k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; - static const char * const k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; - static const char * const k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; - static const char * const k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; - static const char * const k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; +//----------------------------------------------------------------------------- +// steamvr keys +static const char *const k_pch_SteamVR_Section = "steamvr"; +static const char *const k_pch_SteamVR_RequireHmd_String = "requireHmd"; +static const char *const k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; +static const char *const k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; +static const char *const k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; +static const char *const k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; +static const char *const k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; +static const char *const k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; +static const char *const k_pch_SteamVR_SendSystemButtonToAllApps_Bool = "sendSystemButtonToAllApps"; +static const char *const k_pch_SteamVR_LogLevel_Int32 = "loglevel"; +static const char *const k_pch_SteamVR_IPD_Float = "ipd"; +static const char *const k_pch_SteamVR_Background_String = "background"; +static const char *const k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; +static const char *const k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; +static const char *const k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; +static const char *const k_pch_SteamVR_GridColor_String = "gridColor"; +static const char *const k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; +static const char *const k_pch_SteamVR_ShowStage_Bool = "showStage"; +static const char *const k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; +static const char *const k_pch_SteamVR_DirectMode_Bool = "directMode"; +static const char *const k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; +static const char *const k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; +static const char *const k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; +static const char *const k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; +static const char *const k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; +static const char *const k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; +static const char *const k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; +static const char *const k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; +static const char *const k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; +static const char *const k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; +static const char *const k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; +static const char *const k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; +static const char *const k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; +static const char *const k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; +static const char *const k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; +static const char *const k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; +static const char *const k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; +static const char *const k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; +static const char *const k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; +static const char *const k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; +static const char *const k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; +static const char *const k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; +static const char *const k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; +static const char *const k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; - //----------------------------------------------------------------------------- - // lighthouse keys - static const char * const k_pch_Lighthouse_Section = "driver_lighthouse"; - static const char * const k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; - static const char * const k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; - static const char * const k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; - static const char * const k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; - static const char * const k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; +//----------------------------------------------------------------------------- +// lighthouse keys +static const char *const k_pch_Lighthouse_Section = "driver_lighthouse"; +static const char *const k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; +static const char *const k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; +static const char *const k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; +static const char *const k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; +static const char *const k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; - //----------------------------------------------------------------------------- - // null keys - static const char * const k_pch_Null_Section = "driver_null"; - static const char * const k_pch_Null_SerialNumber_String = "serialNumber"; - static const char * const k_pch_Null_ModelNumber_String = "modelNumber"; - static const char * const k_pch_Null_WindowX_Int32 = "windowX"; - static const char * const k_pch_Null_WindowY_Int32 = "windowY"; - static const char * const k_pch_Null_WindowWidth_Int32 = "windowWidth"; - static const char * const k_pch_Null_WindowHeight_Int32 = "windowHeight"; - static const char * const k_pch_Null_RenderWidth_Int32 = "renderWidth"; - static const char * const k_pch_Null_RenderHeight_Int32 = "renderHeight"; - static const char * const k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; - static const char * const k_pch_Null_DisplayFrequency_Float = "displayFrequency"; +//----------------------------------------------------------------------------- +// null keys +static const char *const k_pch_Null_Section = "driver_null"; +static const char *const k_pch_Null_SerialNumber_String = "serialNumber"; +static const char *const k_pch_Null_ModelNumber_String = "modelNumber"; +static const char *const k_pch_Null_WindowX_Int32 = "windowX"; +static const char *const k_pch_Null_WindowY_Int32 = "windowY"; +static const char *const k_pch_Null_WindowWidth_Int32 = "windowWidth"; +static const char *const k_pch_Null_WindowHeight_Int32 = "windowHeight"; +static const char *const k_pch_Null_RenderWidth_Int32 = "renderWidth"; +static const char *const k_pch_Null_RenderHeight_Int32 = "renderHeight"; +static const char *const k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; +static const char *const k_pch_Null_DisplayFrequency_Float = "displayFrequency"; - //----------------------------------------------------------------------------- - // user interface keys - static const char * const k_pch_UserInterface_Section = "userinterface"; - static const char * const k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; - static const char * const k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; - static const char * const k_pch_UserInterface_Screenshots_Bool = "screenshots"; - static const char * const k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; +//----------------------------------------------------------------------------- +// user interface keys +static const char *const k_pch_UserInterface_Section = "userinterface"; +static const char *const k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; +static const char *const k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; +static const char *const k_pch_UserInterface_Screenshots_Bool = "screenshots"; +static const char *const k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; - //----------------------------------------------------------------------------- - // notification keys - static const char * const k_pch_Notifications_Section = "notifications"; - static const char * const k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; +//----------------------------------------------------------------------------- +// notification keys +static const char *const k_pch_Notifications_Section = "notifications"; +static const char *const k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; - //----------------------------------------------------------------------------- - // keyboard keys - static const char * const k_pch_Keyboard_Section = "keyboard"; - static const char * const k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; - static const char * const k_pch_Keyboard_ScaleX = "ScaleX"; - static const char * const k_pch_Keyboard_ScaleY = "ScaleY"; - static const char * const k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; - static const char * const k_pch_Keyboard_OffsetRightX = "OffsetRightX"; - static const char * const k_pch_Keyboard_OffsetY = "OffsetY"; - static const char * const k_pch_Keyboard_Smoothing = "Smoothing"; +//----------------------------------------------------------------------------- +// keyboard keys +static const char *const k_pch_Keyboard_Section = "keyboard"; +static const char *const k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; +static const char *const k_pch_Keyboard_ScaleX = "ScaleX"; +static const char *const k_pch_Keyboard_ScaleY = "ScaleY"; +static const char *const k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; +static const char *const k_pch_Keyboard_OffsetRightX = "OffsetRightX"; +static const char *const k_pch_Keyboard_OffsetY = "OffsetY"; +static const char *const k_pch_Keyboard_Smoothing = "Smoothing"; - //----------------------------------------------------------------------------- - // perf keys - static const char * const k_pch_Perf_Section = "perfcheck"; - static const char * const k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; - static const char * const k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; - static const char * const k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; - static const char * const k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; - static const char * const k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; - static const char * const k_pch_Perf_TestData_Float = "perfTestData"; - static const char * const k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; +//----------------------------------------------------------------------------- +// perf keys +static const char *const k_pch_Perf_Section = "perfcheck"; +static const char *const k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; +static const char *const k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; +static const char *const k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; +static const char *const k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; +static const char *const k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; +static const char *const k_pch_Perf_TestData_Float = "perfTestData"; +static const char *const k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; - //----------------------------------------------------------------------------- - // collision bounds keys - static const char * const k_pch_CollisionBounds_Section = "collisionBounds"; - static const char * const k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; - static const char * const k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; - static const char * const k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; - static const char * const k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; - static const char * const k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; - static const char * const k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; - static const char * const k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; - static const char * const k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; - static const char * const k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; +//----------------------------------------------------------------------------- +// collision bounds keys +static const char *const k_pch_CollisionBounds_Section = "collisionBounds"; +static const char *const k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; +static const char *const k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; +static const char *const k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; +static const char *const k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; +static const char *const k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; +static const char *const k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; +static const char *const k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; +static const char *const k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; +static const char *const k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; - //----------------------------------------------------------------------------- - // camera keys - static const char * const k_pch_Camera_Section = "camera"; - static const char * const k_pch_Camera_EnableCamera_Bool = "enableCamera"; - static const char * const k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; - static const char * const k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; - static const char * const k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; - static const char * const k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; - static const char * const k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; - static const char * const k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; - static const char * const k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; - static const char * const k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; +//----------------------------------------------------------------------------- +// camera keys +static const char *const k_pch_Camera_Section = "camera"; +static const char *const k_pch_Camera_EnableCamera_Bool = "enableCamera"; +static const char *const k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; +static const char *const k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; +static const char *const k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; +static const char *const k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; +static const char *const k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; +static const char *const k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; +static const char *const k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; +static const char *const k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; - //----------------------------------------------------------------------------- - // audio keys - static const char * const k_pch_audio_Section = "audio"; - static const char * const k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; - static const char * const k_pch_audio_OnRecordDevice_String = "onRecordDevice"; - static const char * const k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; - static const char * const k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; - static const char * const k_pch_audio_OffRecordDevice_String = "offRecordDevice"; - static const char * const k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; +//----------------------------------------------------------------------------- +// audio keys +static const char *const k_pch_audio_Section = "audio"; +static const char *const k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; +static const char *const k_pch_audio_OnRecordDevice_String = "onRecordDevice"; +static const char *const k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; +static const char *const k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; +static const char *const k_pch_audio_OffRecordDevice_String = "offRecordDevice"; +static const char *const k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; - //----------------------------------------------------------------------------- - // power management keys - static const char * const k_pch_Power_Section = "power"; - static const char * const k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; - static const char * const k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; - static const char * const k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; - static const char * const k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; - static const char * const k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; - static const char * const k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; +//----------------------------------------------------------------------------- +// power management keys +static const char *const k_pch_Power_Section = "power"; +static const char *const k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; +static const char *const k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; +static const char *const k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; +static const char *const k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; +static const char *const k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; +static const char *const k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; - //----------------------------------------------------------------------------- - // dashboard keys - static const char * const k_pch_Dashboard_Section = "dashboard"; - static const char * const k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; - static const char * const k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; +//----------------------------------------------------------------------------- +// dashboard keys +static const char *const k_pch_Dashboard_Section = "dashboard"; +static const char *const k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; +static const char *const k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; - //----------------------------------------------------------------------------- - // model skin keys - static const char * const k_pch_modelskin_Section = "modelskins"; +//----------------------------------------------------------------------------- +// model skin keys +static const char *const k_pch_modelskin_Section = "modelskins"; - //----------------------------------------------------------------------------- - // driver keys - These could be checked in any driver_ section - static const char * const k_pch_Driver_Enable_Bool = "enable"; +//----------------------------------------------------------------------------- +// driver keys - These could be checked in any driver_ section +static const char *const k_pch_Driver_Enable_Bool = "enable"; -} // namespace vr +} // namespace vr // iservertrackeddevicedriver.h namespace vr { - - struct DriverPoseQuaternion_t { double w, x, y, z; @@ -1573,10 +1543,10 @@ struct DriverPose_t * lagged due to the filtering required to reduce noise to an acceptable level. */ vr::HmdQuaternion_t qWorldFromDriverRotation; - double vecWorldFromDriverTranslation[ 3 ]; + double vecWorldFromDriverTranslation[3]; vr::HmdQuaternion_t qDriverFromHeadRotation; - double vecDriverFromHeadTranslation[ 3 ]; + double vecDriverFromHeadTranslation[3]; /* State of driver pose, in meters and radians. */ /* Position of the driver tracking reference in driver world space @@ -1584,13 +1554,13 @@ struct DriverPose_t * +[1] (y) is up * -[2] (z) is forward */ - double vecPosition[ 3 ]; + double vecPosition[3]; /* Velocity of the pose in meters/second */ - double vecVelocity[ 3 ]; + double vecVelocity[3]; /* Acceleration of the pose in meters/second */ - double vecAcceleration[ 3 ]; + double vecAcceleration[3]; /* Orientation of the tracker, represented as a quaternion */ vr::HmdQuaternion_t qRotation; @@ -1599,13 +1569,13 @@ struct DriverPose_t * representation. The direction is the angle of * rotation and the magnitude is the angle around * that axis in radians/second. */ - double vecAngularVelocity[ 3 ]; + double vecAngularVelocity[3]; /* Angular acceleration of the pose in axis-angle * representation. The direction is the angle of * rotation and the magnitude is the angle around * that axis in radians/second^2. */ - double vecAngularAcceleration[ 3 ]; + double vecAngularAcceleration[3]; ETrackingResult result; @@ -1615,14 +1585,12 @@ struct DriverPose_t bool deviceIsConnected; }; - // ---------------------------------------------------------------------------------------------- // Purpose: Represents a single tracked device in a driver // ---------------------------------------------------------------------------------------------- class ITrackedDeviceServerDriver { public: - // ------------------------------------ // Management Methods // ------------------------------------ @@ -1631,7 +1599,7 @@ public: * ITrackedDeviceServerDriver object should be kept to a minimum until it is activated. * The pose listener is guaranteed to be valid until Deactivate is called, but * should not be used after that point. */ - virtual EVRInitError Activate( uint32_t unObjectId ) = 0; + virtual EVRInitError Activate(uint32_t unObjectId) = 0; /** This is called when The VR system is switching from this Hmd being the active display * to another Hmd being the active display. The driver should clean whatever memory @@ -1643,12 +1611,12 @@ public: /** Requests a component interface of the driver for device-specific functionality. The driver should return NULL * if the requested interface or version is not supported. */ - virtual void *GetComponent( const char *pchComponentNameAndVersion ) = 0; + virtual void *GetComponent(const char *pchComponentNameAndVersion) = 0; /** A VR Client has made this debug request of the driver. The set of valid requests is entirely * up to the driver and the client to figure out, as is the format of the response. Responses that * exceed the length of the supplied buffer should be truncated and null terminated */ - virtual void DebugRequest( const char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize ) = 0; + virtual void DebugRequest(const char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize) = 0; // ------------------------------------ // Tracking Methods @@ -1656,177 +1624,160 @@ public: virtual DriverPose_t GetPose() = 0; }; - - static const char *ITrackedDeviceServerDriver_Version = "ITrackedDeviceServerDriver_005"; -} +} // namespace vr // ivrdisplaycomponent.h namespace vr { +// ---------------------------------------------------------------------------------------------- +// Purpose: The display component on a single tracked device +// ---------------------------------------------------------------------------------------------- +class IVRDisplayComponent +{ +public: + // ------------------------------------ + // Display Methods + // ------------------------------------ + /** Size and position that the window needs to be on the VR display. */ + virtual void GetWindowBounds(int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight) = 0; - // ---------------------------------------------------------------------------------------------- - // Purpose: The display component on a single tracked device - // ---------------------------------------------------------------------------------------------- - class IVRDisplayComponent - { - public: + /** Returns true if the display is extending the desktop. */ + virtual bool IsDisplayOnDesktop() = 0; - // ------------------------------------ - // Display Methods - // ------------------------------------ + /** Returns true if the display is real and not a fictional display. */ + virtual bool IsDisplayRealDisplay() = 0; - /** Size and position that the window needs to be on the VR display. */ - virtual void GetWindowBounds( int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; + /** Suggested size for the intermediate render target that the distortion pulls from. */ + virtual void GetRecommendedRenderTargetSize(uint32_t *pnWidth, uint32_t *pnHeight) = 0; - /** Returns true if the display is extending the desktop. */ - virtual bool IsDisplayOnDesktop( ) = 0; + /** Gets the viewport in the frame buffer to draw the output of the distortion into */ + virtual void GetEyeOutputViewport(EVREye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight) = 0; - /** Returns true if the display is real and not a fictional display. */ - virtual bool IsDisplayRealDisplay( ) = 0; - - /** Suggested size for the intermediate render target that the distortion pulls from. */ - virtual void GetRecommendedRenderTargetSize( uint32_t *pnWidth, uint32_t *pnHeight ) = 0; - - /** Gets the viewport in the frame buffer to draw the output of the distortion into */ - virtual void GetEyeOutputViewport( EVREye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; - - /** The components necessary to build your own projection matrix in case your + /** The components necessary to build your own projection matrix in case your * application is doing something fancy like infinite Z */ - virtual void GetProjectionRaw( EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom ) = 0; + virtual void GetProjectionRaw(EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom) = 0; - /** Returns the result of the distortion function for the specified eye and input UVs. UVs go from 0,0 in + /** Returns the result of the distortion function for the specified eye and input UVs. UVs go from 0,0 in * the upper left of that eye's viewport and 1,1 in the lower right of that eye's viewport. */ - virtual DistortionCoordinates_t ComputeDistortion( EVREye eEye, float fU, float fV ) = 0; + virtual DistortionCoordinates_t ComputeDistortion(EVREye eEye, float fU, float fV) = 0; +}; - }; +static const char *IVRDisplayComponent_Version = "IVRDisplayComponent_002"; - static const char *IVRDisplayComponent_Version = "IVRDisplayComponent_002"; - -} +} // namespace vr // ivrdriverdirectmodecomponent.h namespace vr { +// ---------------------------------------------------------------------------------------------- +// Purpose: This component is used for drivers that implement direct mode entirely on their own +// without allowing the VR Compositor to own the window/device. Chances are you don't +// need to implement this component in your driver. +// ---------------------------------------------------------------------------------------------- +class IVRDriverDirectModeComponent +{ +public: + // ----------------------------------- + // Direct mode methods + // ----------------------------------- + /** Specific to Oculus compositor support, textures supplied must be created using this method. */ + virtual void CreateSwapTextureSet(uint32_t unPid, uint32_t unFormat, uint32_t unWidth, uint32_t unHeight, vr::SharedTextureHandle_t (*pSharedTextureHandles)[3]) {} - // ---------------------------------------------------------------------------------------------- - // Purpose: This component is used for drivers that implement direct mode entirely on their own - // without allowing the VR Compositor to own the window/device. Chances are you don't - // need to implement this component in your driver. - // ---------------------------------------------------------------------------------------------- - class IVRDriverDirectModeComponent - { - public: + /** Used to textures created using CreateSwapTextureSet. Only one of the set's handles needs to be used to destroy the entire set. */ + virtual void DestroySwapTextureSet(vr::SharedTextureHandle_t sharedTextureHandle) {} - // ----------------------------------- - // Direct mode methods - // ----------------------------------- + /** Used to purge all texture sets for a given process. */ + virtual void DestroyAllSwapTextureSets(uint32_t unPid) {} - /** Specific to Oculus compositor support, textures supplied must be created using this method. */ - virtual void CreateSwapTextureSet( uint32_t unPid, uint32_t unFormat, uint32_t unWidth, uint32_t unHeight, vr::SharedTextureHandle_t( *pSharedTextureHandles )[ 3 ] ) {} + /** After Present returns, calls this to get the next index to use for rendering. */ + virtual void GetNextSwapTextureSetIndex(vr::SharedTextureHandle_t sharedTextureHandles[2], uint32_t (*pIndices)[2]) {} - /** Used to textures created using CreateSwapTextureSet. Only one of the set's handles needs to be used to destroy the entire set. */ - virtual void DestroySwapTextureSet( vr::SharedTextureHandle_t sharedTextureHandle ) {} - - /** Used to purge all texture sets for a given process. */ - virtual void DestroyAllSwapTextureSets( uint32_t unPid ) {} - - /** After Present returns, calls this to get the next index to use for rendering. */ - virtual void GetNextSwapTextureSetIndex( vr::SharedTextureHandle_t sharedTextureHandles[ 2 ], uint32_t( *pIndices )[ 2 ] ) {} - - /** Call once per layer to draw for this frame. One shared texture handle per eye. Textures must be created + /** Call once per layer to draw for this frame. One shared texture handle per eye. Textures must be created * using CreateSwapTextureSet and should be alternated per frame. Call Present once all layers have been submitted. */ - virtual void SubmitLayer( vr::SharedTextureHandle_t sharedTextureHandles[ 2 ], const vr::VRTextureBounds_t( &bounds )[ 2 ], const vr::HmdMatrix34_t *pPose ) {} + virtual void SubmitLayer(vr::SharedTextureHandle_t sharedTextureHandles[2], const vr::VRTextureBounds_t (&bounds)[2], const vr::HmdMatrix34_t *pPose) {} - /** Submits queued layers for display. */ - virtual void Present( vr::SharedTextureHandle_t syncTexture ) {} + /** Submits queued layers for display. */ + virtual void Present(vr::SharedTextureHandle_t syncTexture) {} +}; - }; +static const char *IVRDriverDirectModeComponent_Version = "IVRDriverDirectModeComponent_002"; - static const char *IVRDriverDirectModeComponent_Version = "IVRDriverDirectModeComponent_002"; - -} +} // namespace vr // ivrcontrollercomponent.h namespace vr { +// ---------------------------------------------------------------------------------------------- +// Purpose: Controller access on a single tracked device. +// ---------------------------------------------------------------------------------------------- +class IVRControllerComponent +{ +public: + // ------------------------------------ + // Controller Methods + // ------------------------------------ + /** Gets the current state of a controller. */ + virtual VRControllerState_t GetControllerState() = 0; - // ---------------------------------------------------------------------------------------------- - // Purpose: Controller access on a single tracked device. - // ---------------------------------------------------------------------------------------------- - class IVRControllerComponent - { - public: + /** Returns a uint64 property. If the property is not available this function will return 0. */ + virtual bool TriggerHapticPulse(uint32_t unAxisId, uint16_t usPulseDurationMicroseconds) = 0; +}; - // ------------------------------------ - // Controller Methods - // ------------------------------------ +static const char *IVRControllerComponent_Version = "IVRControllerComponent_001"; - /** Gets the current state of a controller. */ - virtual VRControllerState_t GetControllerState( ) = 0; - - /** Returns a uint64 property. If the property is not available this function will return 0. */ - virtual bool TriggerHapticPulse( uint32_t unAxisId, uint16_t usPulseDurationMicroseconds ) = 0; - - }; - - - - static const char *IVRControllerComponent_Version = "IVRControllerComponent_001"; - -} +} // namespace vr // ivrcameracomponent.h namespace vr { - //----------------------------------------------------------------------------- - //----------------------------------------------------------------------------- - class ICameraVideoSinkCallback - { - public: - virtual void OnCameraVideoSinkCallback() = 0; - }; +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +class ICameraVideoSinkCallback +{ +public: + virtual void OnCameraVideoSinkCallback() = 0; +}; - // ---------------------------------------------------------------------------------------------- - // Purpose: The camera on a single tracked device - // ---------------------------------------------------------------------------------------------- - class IVRCameraComponent - { - public: - // ------------------------------------ - // Camera Methods - // ------------------------------------ - virtual bool GetCameraFrameDimensions( vr::ECameraVideoStreamFormat nVideoStreamFormat, uint32_t *pWidth, uint32_t *pHeight ) = 0; - virtual bool GetCameraFrameBufferingRequirements( int *pDefaultFrameQueueSize, uint32_t *pFrameBufferDataSize ) = 0; - virtual bool SetCameraFrameBuffering( int nFrameBufferCount, void **ppFrameBuffers, uint32_t nFrameBufferDataSize ) = 0; - virtual bool SetCameraVideoStreamFormat( vr::ECameraVideoStreamFormat nVideoStreamFormat ) = 0; - virtual vr::ECameraVideoStreamFormat GetCameraVideoStreamFormat() = 0; - virtual bool StartVideoStream() = 0; - virtual void StopVideoStream() = 0; - virtual bool IsVideoStreamActive( bool *pbPaused, float *pflElapsedTime ) = 0; - virtual const vr::CameraVideoStreamFrame_t *GetVideoStreamFrame() = 0; - virtual void ReleaseVideoStreamFrame( const vr::CameraVideoStreamFrame_t *pFrameImage ) = 0; - virtual bool SetAutoExposure( bool bEnable ) = 0; - virtual bool PauseVideoStream() = 0; - virtual bool ResumeVideoStream() = 0; - virtual bool GetCameraDistortion( float flInputU, float flInputV, float *pflOutputU, float *pflOutputV ) = 0; - virtual bool GetCameraProjection( vr::EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, vr::HmdMatrix44_t *pProjection ) = 0; - virtual bool SetFrameRate( int nISPFrameRate, int nSensorFrameRate ) = 0; - virtual bool SetCameraVideoSinkCallback( vr::ICameraVideoSinkCallback *pCameraVideoSinkCallback ) = 0; - virtual bool GetCameraCompatibilityMode( vr::ECameraCompatibilityMode *pCameraCompatibilityMode ) = 0; - virtual bool SetCameraCompatibilityMode( vr::ECameraCompatibilityMode nCameraCompatibilityMode ) = 0; - virtual bool GetCameraFrameBounds( vr::EVRTrackedCameraFrameType eFrameType, uint32_t *pLeft, uint32_t *pTop, uint32_t *pWidth, uint32_t *pHeight ) = 0; - virtual bool GetCameraIntrinsics( vr::EVRTrackedCameraFrameType eFrameType, HmdVector2_t *pFocalLength, HmdVector2_t *pCenter ) = 0; - }; +// ---------------------------------------------------------------------------------------------- +// Purpose: The camera on a single tracked device +// ---------------------------------------------------------------------------------------------- +class IVRCameraComponent +{ +public: + // ------------------------------------ + // Camera Methods + // ------------------------------------ + virtual bool GetCameraFrameDimensions(vr::ECameraVideoStreamFormat nVideoStreamFormat, uint32_t *pWidth, uint32_t *pHeight) = 0; + virtual bool GetCameraFrameBufferingRequirements(int *pDefaultFrameQueueSize, uint32_t *pFrameBufferDataSize) = 0; + virtual bool SetCameraFrameBuffering(int nFrameBufferCount, void **ppFrameBuffers, uint32_t nFrameBufferDataSize) = 0; + virtual bool SetCameraVideoStreamFormat(vr::ECameraVideoStreamFormat nVideoStreamFormat) = 0; + virtual vr::ECameraVideoStreamFormat GetCameraVideoStreamFormat() = 0; + virtual bool StartVideoStream() = 0; + virtual void StopVideoStream() = 0; + virtual bool IsVideoStreamActive(bool *pbPaused, float *pflElapsedTime) = 0; + virtual const vr::CameraVideoStreamFrame_t *GetVideoStreamFrame() = 0; + virtual void ReleaseVideoStreamFrame(const vr::CameraVideoStreamFrame_t *pFrameImage) = 0; + virtual bool SetAutoExposure(bool bEnable) = 0; + virtual bool PauseVideoStream() = 0; + virtual bool ResumeVideoStream() = 0; + virtual bool GetCameraDistortion(float flInputU, float flInputV, float *pflOutputU, float *pflOutputV) = 0; + virtual bool GetCameraProjection(vr::EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, vr::HmdMatrix44_t *pProjection) = 0; + virtual bool SetFrameRate(int nISPFrameRate, int nSensorFrameRate) = 0; + virtual bool SetCameraVideoSinkCallback(vr::ICameraVideoSinkCallback *pCameraVideoSinkCallback) = 0; + virtual bool GetCameraCompatibilityMode(vr::ECameraCompatibilityMode *pCameraCompatibilityMode) = 0; + virtual bool SetCameraCompatibilityMode(vr::ECameraCompatibilityMode nCameraCompatibilityMode) = 0; + virtual bool GetCameraFrameBounds(vr::EVRTrackedCameraFrameType eFrameType, uint32_t *pLeft, uint32_t *pTop, uint32_t *pWidth, uint32_t *pHeight) = 0; + virtual bool GetCameraIntrinsics(vr::EVRTrackedCameraFrameType eFrameType, HmdVector2_t *pFocalLength, HmdVector2_t *pCenter) = 0; +}; - static const char *IVRCameraComponent_Version = "IVRCameraComponent_002"; -} +static const char *IVRCameraComponent_Version = "IVRCameraComponent_002"; +} // namespace vr // itrackeddevicedriverprovider.h namespace vr { - class ITrackedDeviceServerDriver; struct TrackedDeviceDriverInfo_t; struct DriverPose_t; @@ -1841,13 +1792,12 @@ class IVRDriverContext public: /** Returns the requested interface. If the interface was not available it will return NULL and fill * out the error. */ - virtual void *GetGenericInterface( const char *pchInterfaceVersion, EVRInitError *peError = nullptr ) = 0; + virtual void *GetGenericInterface(const char *pchInterfaceVersion, EVRInitError *peError = nullptr) = 0; /** Returns the property container handle for this driver */ virtual DriverHandle_t GetDriverHandle() = 0; }; - /** This interface must be implemented in each driver. It will be loaded in vrserver.exe */ class IServerTrackedDeviceProvider { @@ -1861,18 +1811,17 @@ public: * config files. * pchDriverInstallDir - The absolute path of the root directory for the driver. */ - virtual EVRInitError Init( IVRDriverContext *pDriverContext ) = 0; + virtual EVRInitError Init(IVRDriverContext *pDriverContext) = 0; /** cleans up the driver right before it is unloaded */ virtual void Cleanup() = 0; /** Returns the version of the ITrackedDeviceServerDriver interface used by this driver */ - virtual const char * const *GetInterfaceVersions() = 0; + virtual const char *const *GetInterfaceVersions() = 0; /** Allows the driver do to some work in the main loop of the server. */ virtual void RunFrame() = 0; - // ------------ Power State Functions ----------------------- // /** Returns true if the driver wants to block Standby mode. */ @@ -1885,21 +1834,16 @@ public: /** Called when the system is leaving Standby mode. The driver should switch itself back to full operation. */ virtual void LeaveStandby() = 0; - }; - static const char *IServerTrackedDeviceProvider_Version = "IServerTrackedDeviceProvider_004"; - - - /** This interface must be implemented in each driver. It will be loaded in vrclient.dll */ class IVRWatchdogProvider { public: /** initializes the driver in watchdog mode. */ - virtual EVRInitError Init( IVRDriverContext *pDriverContext ) = 0; + virtual EVRInitError Init(IVRDriverContext *pDriverContext) = 0; /** cleans up the driver right before it is unloaded */ virtual void Cleanup() = 0; @@ -1907,134 +1851,128 @@ public: static const char *IVRWatchdogProvider_Version = "IVRWatchdogProvider_001"; -} +} // namespace vr // ivrproperties.h #include namespace vr { +enum EPropertyWriteType +{ + PropertyWrite_Set = 0, + PropertyWrite_Erase = 1, + PropertyWrite_SetError = 2 +}; - enum EPropertyWriteType - { - PropertyWrite_Set = 0, - PropertyWrite_Erase = 1, - PropertyWrite_SetError = 2 - }; - - struct PropertyWrite_t - { - ETrackedDeviceProperty prop; - EPropertyWriteType writeType; - ETrackedPropertyError eSetError; - void *pvBuffer; - uint32_t unBufferSize; - PropertyTypeTag_t unTag; - ETrackedPropertyError eError; - }; - - struct PropertyRead_t - { - ETrackedDeviceProperty prop; - void *pvBuffer; - uint32_t unBufferSize; - PropertyTypeTag_t unTag; - uint32_t unRequiredBufferSize; - ETrackedPropertyError eError; - }; +struct PropertyWrite_t +{ + ETrackedDeviceProperty prop; + EPropertyWriteType writeType; + ETrackedPropertyError eSetError; + void *pvBuffer; + uint32_t unBufferSize; + PropertyTypeTag_t unTag; + ETrackedPropertyError eError; +}; +struct PropertyRead_t +{ + ETrackedDeviceProperty prop; + void *pvBuffer; + uint32_t unBufferSize; + PropertyTypeTag_t unTag; + uint32_t unRequiredBufferSize; + ETrackedPropertyError eError; +}; class IVRProperties { public: - /** Reads a set of properties atomically. See the PropertyReadBatch_t struct for more information. */ - virtual ETrackedPropertyError ReadPropertyBatch( PropertyContainerHandle_t ulContainerHandle, PropertyRead_t *pBatch, uint32_t unBatchEntryCount ) = 0; + virtual ETrackedPropertyError ReadPropertyBatch(PropertyContainerHandle_t ulContainerHandle, PropertyRead_t *pBatch, uint32_t unBatchEntryCount) = 0; /** Writes a set of properties atomically. See the PropertyWriteBatch_t struct for more information. */ - virtual ETrackedPropertyError WritePropertyBatch( PropertyContainerHandle_t ulContainerHandle, PropertyWrite_t *pBatch, uint32_t unBatchEntryCount ) = 0; + virtual ETrackedPropertyError WritePropertyBatch(PropertyContainerHandle_t ulContainerHandle, PropertyWrite_t *pBatch, uint32_t unBatchEntryCount) = 0; /** returns a string that corresponds with the specified property error. The string will be the name * of the error enum value for all valid error codes */ - virtual const char *GetPropErrorNameFromEnum( ETrackedPropertyError error ) = 0; + virtual const char *GetPropErrorNameFromEnum(ETrackedPropertyError error) = 0; /** Returns a container handle given a tracked device index */ - virtual PropertyContainerHandle_t TrackedDeviceToPropertyContainer( TrackedDeviceIndex_t nDevice ) = 0; - + virtual PropertyContainerHandle_t TrackedDeviceToPropertyContainer(TrackedDeviceIndex_t nDevice) = 0; }; -static const char * const IVRProperties_Version = "IVRProperties_001"; +static const char *const IVRProperties_Version = "IVRProperties_001"; class CVRPropertyHelpers { public: - CVRPropertyHelpers( IVRProperties * pProperties ) : m_pProperties( pProperties ) {} + CVRPropertyHelpers(IVRProperties *pProperties) : m_pProperties(pProperties) {} /** Returns a scaler property. If the device index is not valid or the property value type does not match, * this function will return false. */ - bool GetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ); - float GetFloatProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ); - int32_t GetInt32Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ); - uint64_t GetUint64Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ); + bool GetBoolProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L); + float GetFloatProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L); + int32_t GetInt32Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L); + uint64_t GetUint64Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L); /** Returns a single typed property. If the device index is not valid or the property is not a string type this function will * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */ - uint32_t GetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() void *pvBuffer, uint32_t unBufferSize, PropertyTypeTag_t *punTag, ETrackedPropertyError *pError = 0L ); - + uint32_t GetProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() void *pvBuffer, uint32_t unBufferSize, PropertyTypeTag_t *punTag, ETrackedPropertyError *pError = 0L); /** Returns a string property. If the device index is not valid or the property is not a string type this function will * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */ - uint32_t GetStringProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L ); + uint32_t GetStringProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L); /** Returns a string property as a std::string. If the device index is not valid or the property is not a string type this function will * return an empty string. */ - std::string GetStringProperty( vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError = nullptr ); + std::string GetStringProperty(vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError = nullptr); /** Sets a scaler property. The new value will be returned on any subsequent call to get this property in any process. */ - ETrackedPropertyError SetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, bool bNewValue ); - ETrackedPropertyError SetFloatProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, float fNewValue ); - ETrackedPropertyError SetInt32Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, int32_t nNewValue ); - ETrackedPropertyError SetUint64Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, uint64_t ulNewValue ); + ETrackedPropertyError SetBoolProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, bool bNewValue); + ETrackedPropertyError SetFloatProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, float fNewValue); + ETrackedPropertyError SetInt32Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, int32_t nNewValue); + ETrackedPropertyError SetUint64Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, uint64_t ulNewValue); /** Sets a string property. The new value will be returned on any subsequent call to get this property in any process. */ - ETrackedPropertyError SetStringProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, const char *pchNewValue ); + ETrackedPropertyError SetStringProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, const char *pchNewValue); /** Sets a single typed property. The new value will be returned on any subsequent call to get this property in any process. */ - ETrackedPropertyError SetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, void *pvNewValue, uint32_t unNewValueSize, PropertyTypeTag_t unTag ); + ETrackedPropertyError SetProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, void *pvNewValue, uint32_t unNewValueSize, PropertyTypeTag_t unTag); /** Sets the error return value for a property. This value will be returned on all subsequent requests to get the property */ - ETrackedPropertyError SetPropertyError( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError eError ); + ETrackedPropertyError SetPropertyError(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError eError); /** Clears any value or error set for the property. */ - ETrackedPropertyError EraseProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop ); + ETrackedPropertyError EraseProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop); /* Turns a device index into a property container handle. */ - PropertyContainerHandle_t TrackedDeviceToPropertyContainer( TrackedDeviceIndex_t nDevice ) { return m_pProperties->TrackedDeviceToPropertyContainer( nDevice ); } + PropertyContainerHandle_t TrackedDeviceToPropertyContainer(TrackedDeviceIndex_t nDevice) { return m_pProperties->TrackedDeviceToPropertyContainer(nDevice); } private: - template - T GetPropertyHelper( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError, T bDefault, PropertyTypeTag_t unTypeTag ); + template + T GetPropertyHelper(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError, T bDefault, PropertyTypeTag_t unTypeTag); IVRProperties *m_pProperties; }; - -inline uint32_t CVRPropertyHelpers::GetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() void *pvBuffer, uint32_t unBufferSize, PropertyTypeTag_t *punTag, ETrackedPropertyError *pError ) +inline uint32_t CVRPropertyHelpers::GetProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() void *pvBuffer, uint32_t unBufferSize, PropertyTypeTag_t *punTag, ETrackedPropertyError *pError) { PropertyRead_t batch; batch.prop = prop; batch.pvBuffer = pvBuffer; batch.unBufferSize = unBufferSize; - m_pProperties->ReadPropertyBatch( ulContainerHandle, &batch, 1 ); + m_pProperties->ReadPropertyBatch(ulContainerHandle, &batch, 1); - if ( pError ) + if (pError) { *pError = batch.eError; } - if ( punTag ) + if (punTag) { *punTag = batch.unTag; } @@ -2042,9 +1980,8 @@ inline uint32_t CVRPropertyHelpers::GetProperty( PropertyContainerHandle_t ulCon return batch.unRequiredBufferSize; } - /** Sets a single typed property. The new value will be returned on any subsequent call to get this property in any process. */ -inline ETrackedPropertyError CVRPropertyHelpers::SetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, void *pvNewValue, uint32_t unNewValueSize, PropertyTypeTag_t unTag ) +inline ETrackedPropertyError CVRPropertyHelpers::SetProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, void *pvNewValue, uint32_t unNewValueSize, PropertyTypeTag_t unTag) { PropertyWrite_t batch; batch.writeType = PropertyWrite_Set; @@ -2053,33 +1990,32 @@ inline ETrackedPropertyError CVRPropertyHelpers::SetProperty( PropertyContainerH batch.unBufferSize = unNewValueSize; batch.unTag = unTag; - m_pProperties->WritePropertyBatch( ulContainerHandle, &batch, 1 ); + m_pProperties->WritePropertyBatch(ulContainerHandle, &batch, 1); return batch.eError; } - /** Returns a string property. If the device index is not valid or the property is not a string type this function will * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */ -inline uint32_t CVRPropertyHelpers::GetStringProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError ) +inline uint32_t CVRPropertyHelpers::GetStringProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError) { PropertyTypeTag_t unTag; ETrackedPropertyError error; - uint32_t unRequiredSize = GetProperty( ulContainerHandle, prop, pchValue, unBufferSize, &unTag, &error ); - if ( unTag != k_unStringPropertyTag && error == TrackedProp_Success ) + uint32_t unRequiredSize = GetProperty(ulContainerHandle, prop, pchValue, unBufferSize, &unTag, &error); + if (unTag != k_unStringPropertyTag && error == TrackedProp_Success) { error = TrackedProp_WrongDataType; } - if ( pError ) + if (pError) { *pError = error; } - if ( error != TrackedProp_Success ) + if (error != TrackedProp_Success) { - if ( pchValue && unBufferSize ) + if (pchValue && unBufferSize) { *pchValue = '\0'; } @@ -2088,30 +2024,29 @@ inline uint32_t CVRPropertyHelpers::GetStringProperty( PropertyContainerHandle_t return unRequiredSize; } - /** Returns a string property as a std::string. If the device index is not valid or the property is not a string type this function will * return an empty string. */ -inline std::string CVRPropertyHelpers::GetStringProperty( vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError ) +inline std::string CVRPropertyHelpers::GetStringProperty(vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError) { char buf[1024]; vr::ETrackedPropertyError err; - uint32_t unRequiredBufferLen = GetStringProperty( ulContainer, prop, buf, sizeof(buf), &err ); + uint32_t unRequiredBufferLen = GetStringProperty(ulContainer, prop, buf, sizeof(buf), &err); std::string sResult; - if ( err == TrackedProp_Success ) + if (err == TrackedProp_Success) { sResult = buf; } - else if ( err == TrackedProp_BufferTooSmall ) + else if (err == TrackedProp_BufferTooSmall) { char *pchBuffer = new char[unRequiredBufferLen]; - unRequiredBufferLen = GetStringProperty( ulContainer, prop, pchBuffer, unRequiredBufferLen, &err ); + unRequiredBufferLen = GetStringProperty(ulContainer, prop, pchBuffer, unRequiredBufferLen, &err); sResult = pchBuffer; delete[] pchBuffer; } - if ( peError ) + if (peError) { *peError = err; } @@ -2119,39 +2054,37 @@ inline std::string CVRPropertyHelpers::GetStringProperty( vr::PropertyContainerH return sResult; } - /** Sets a string property. The new value will be returned on any subsequent call to get this property in any process. */ -inline ETrackedPropertyError CVRPropertyHelpers::SetStringProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, const char *pchNewValue ) +inline ETrackedPropertyError CVRPropertyHelpers::SetStringProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, const char *pchNewValue) { - if ( !pchNewValue ) + if (!pchNewValue) return TrackedProp_InvalidOperation; // this is strlen without the dependency on string.h const char *pchCurr = pchNewValue; - while ( *pchCurr ) + while (*pchCurr) { pchCurr++; } - return SetProperty( ulContainerHandle, prop, (void *)pchNewValue, (uint32_t)(pchCurr - pchNewValue) + 1, k_unStringPropertyTag ); + return SetProperty(ulContainerHandle, prop, (void *)pchNewValue, (uint32_t)(pchCurr - pchNewValue) + 1, k_unStringPropertyTag); } - -template -inline T CVRPropertyHelpers::GetPropertyHelper( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError, T bDefault, PropertyTypeTag_t unTypeTag ) +template +inline T CVRPropertyHelpers::GetPropertyHelper(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError, T bDefault, PropertyTypeTag_t unTypeTag) { T bValue; ETrackedPropertyError eError; PropertyTypeTag_t unReadTag; - GetProperty( ulContainerHandle, prop, &bValue, sizeof( bValue ), &unReadTag, &eError ); - if ( unReadTag != unTypeTag && eError == TrackedProp_Success ) + GetProperty(ulContainerHandle, prop, &bValue, sizeof(bValue), &unReadTag, &eError); + if (unReadTag != unTypeTag && eError == TrackedProp_Success) { eError = TrackedProp_WrongDataType; }; - if ( pError ) + if (pError) *pError = eError; - if ( eError != TrackedProp_Success ) + if (eError != TrackedProp_Success) { return bDefault; } @@ -2161,96 +2094,89 @@ inline T CVRPropertyHelpers::GetPropertyHelper( PropertyContainerHandle_t ulCont } } - -inline bool CVRPropertyHelpers::GetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) +inline bool CVRPropertyHelpers::GetBoolProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError) { - return GetPropertyHelper( ulContainerHandle, prop, pError, false, k_unBoolPropertyTag ); + return GetPropertyHelper(ulContainerHandle, prop, pError, false, k_unBoolPropertyTag); } - -inline float CVRPropertyHelpers::GetFloatProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) +inline float CVRPropertyHelpers::GetFloatProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError) { - return GetPropertyHelper( ulContainerHandle, prop, pError, 0.f, k_unFloatPropertyTag ); + return GetPropertyHelper(ulContainerHandle, prop, pError, 0.f, k_unFloatPropertyTag); } -inline int32_t CVRPropertyHelpers::GetInt32Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) +inline int32_t CVRPropertyHelpers::GetInt32Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError) { - return GetPropertyHelper( ulContainerHandle, prop, pError, 0, k_unInt32PropertyTag ); + return GetPropertyHelper(ulContainerHandle, prop, pError, 0, k_unInt32PropertyTag); } -inline uint64_t CVRPropertyHelpers::GetUint64Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) +inline uint64_t CVRPropertyHelpers::GetUint64Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError) { - return GetPropertyHelper( ulContainerHandle, prop, pError, 0, k_unUint64PropertyTag ); + return GetPropertyHelper(ulContainerHandle, prop, pError, 0, k_unUint64PropertyTag); } -inline ETrackedPropertyError CVRPropertyHelpers::SetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, bool bNewValue ) +inline ETrackedPropertyError CVRPropertyHelpers::SetBoolProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, bool bNewValue) { - return SetProperty( ulContainerHandle, prop, &bNewValue, sizeof( bNewValue ), k_unBoolPropertyTag ); + return SetProperty(ulContainerHandle, prop, &bNewValue, sizeof(bNewValue), k_unBoolPropertyTag); } -inline ETrackedPropertyError CVRPropertyHelpers::SetFloatProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, float fNewValue ) +inline ETrackedPropertyError CVRPropertyHelpers::SetFloatProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, float fNewValue) { - return SetProperty( ulContainerHandle, prop, &fNewValue, sizeof( fNewValue ), k_unFloatPropertyTag ); + return SetProperty(ulContainerHandle, prop, &fNewValue, sizeof(fNewValue), k_unFloatPropertyTag); } -inline ETrackedPropertyError CVRPropertyHelpers::SetInt32Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, int32_t nNewValue ) +inline ETrackedPropertyError CVRPropertyHelpers::SetInt32Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, int32_t nNewValue) { - return SetProperty( ulContainerHandle, prop, &nNewValue, sizeof( nNewValue ), k_unInt32PropertyTag ); + return SetProperty(ulContainerHandle, prop, &nNewValue, sizeof(nNewValue), k_unInt32PropertyTag); } -inline ETrackedPropertyError CVRPropertyHelpers::SetUint64Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, uint64_t ulNewValue ) +inline ETrackedPropertyError CVRPropertyHelpers::SetUint64Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, uint64_t ulNewValue) { - return SetProperty( ulContainerHandle, prop, &ulNewValue, sizeof( ulNewValue ), k_unUint64PropertyTag ); + return SetProperty(ulContainerHandle, prop, &ulNewValue, sizeof(ulNewValue), k_unUint64PropertyTag); } /** Sets the error return value for a property. This value will be returned on all subsequent requests to get the property */ -inline ETrackedPropertyError CVRPropertyHelpers::SetPropertyError( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError eError ) +inline ETrackedPropertyError CVRPropertyHelpers::SetPropertyError(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError eError) { PropertyWrite_t batch; batch.writeType = PropertyWrite_SetError; batch.prop = prop; batch.eSetError = eError; - m_pProperties->WritePropertyBatch( ulContainerHandle, &batch, 1 ); + m_pProperties->WritePropertyBatch(ulContainerHandle, &batch, 1); return batch.eError; } /** Clears any value or error set for the property. */ -inline ETrackedPropertyError CVRPropertyHelpers::EraseProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop ) +inline ETrackedPropertyError CVRPropertyHelpers::EraseProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop) { PropertyWrite_t batch; batch.writeType = PropertyWrite_Erase; batch.prop = prop; - m_pProperties->WritePropertyBatch( ulContainerHandle, &batch, 1 ); + m_pProperties->WritePropertyBatch(ulContainerHandle, &batch, 1); return batch.eError; - -} - } +} // namespace vr // ivrdriverlog.h namespace vr { - class IVRDriverLog { public: /** Writes a log message to the log file prefixed with the driver name */ - virtual void Log( const char *pchLogMessage ) = 0; + virtual void Log(const char *pchLogMessage) = 0; }; - static const char *IVRDriverLog_Version = "IVRDriverLog_001"; -} +} // namespace vr // ivrserverdriverhost.h namespace vr { - class ITrackedDeviceServerDriver; struct TrackedDeviceDriverInfo_t; struct DriverPose_t; @@ -2265,74 +2191,73 @@ public: /** Notifies the server that a tracked device has been added. If this function returns true * the server will call Activate on the device. If it returns false some kind of error * has occurred and the device will not be activated. */ - virtual bool TrackedDeviceAdded( const char *pchDeviceSerialNumber, ETrackedDeviceClass eDeviceClass, ITrackedDeviceServerDriver *pDriver ) = 0; + virtual bool TrackedDeviceAdded(const char *pchDeviceSerialNumber, ETrackedDeviceClass eDeviceClass, ITrackedDeviceServerDriver *pDriver) = 0; /** Notifies the server that a tracked device's pose has been updated */ - virtual void TrackedDevicePoseUpdated( uint32_t unWhichDevice, const DriverPose_t & newPose, uint32_t unPoseStructSize ) = 0; + virtual void TrackedDevicePoseUpdated(uint32_t unWhichDevice, const DriverPose_t &newPose, uint32_t unPoseStructSize) = 0; /** Notifies the server that vsync has occurred on the the display attached to the device. This is * only permitted on devices of the HMD class. */ - virtual void VsyncEvent( double vsyncTimeOffsetSeconds ) = 0; + virtual void VsyncEvent(double vsyncTimeOffsetSeconds) = 0; /** notifies the server that the button was pressed */ - virtual void TrackedDeviceButtonPressed( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; + virtual void TrackedDeviceButtonPressed(uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset) = 0; /** notifies the server that the button was unpressed */ - virtual void TrackedDeviceButtonUnpressed( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; + virtual void TrackedDeviceButtonUnpressed(uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset) = 0; /** notifies the server that the button was pressed */ - virtual void TrackedDeviceButtonTouched( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; + virtual void TrackedDeviceButtonTouched(uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset) = 0; /** notifies the server that the button was unpressed */ - virtual void TrackedDeviceButtonUntouched( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; + virtual void TrackedDeviceButtonUntouched(uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset) = 0; /** notifies the server than a controller axis changed */ - virtual void TrackedDeviceAxisUpdated( uint32_t unWhichDevice, uint32_t unWhichAxis, const VRControllerAxis_t & axisState ) = 0; + virtual void TrackedDeviceAxisUpdated(uint32_t unWhichDevice, uint32_t unWhichAxis, const VRControllerAxis_t &axisState) = 0; /** Notifies the server that the proximity sensor on the specified device */ - virtual void ProximitySensorState( uint32_t unWhichDevice, bool bProximitySensorTriggered ) = 0; + virtual void ProximitySensorState(uint32_t unWhichDevice, bool bProximitySensorTriggered) = 0; /** Sends a vendor specific event (VREvent_VendorSpecific_Reserved_Start..VREvent_VendorSpecific_Reserved_End */ - virtual void VendorSpecificEvent( uint32_t unWhichDevice, vr::EVREventType eventType, const VREvent_Data_t & eventData, double eventTimeOffset ) = 0; + virtual void VendorSpecificEvent(uint32_t unWhichDevice, vr::EVREventType eventType, const VREvent_Data_t &eventData, double eventTimeOffset) = 0; /** Returns true if SteamVR is exiting */ virtual bool IsExiting() = 0; /** Returns true and fills the event with the next event on the queue if there is one. If there are no events * this method returns false. uncbVREvent should be the size in bytes of the VREvent_t struct */ - virtual bool PollNextEvent( VREvent_t *pEvent, uint32_t uncbVREvent ) = 0; + virtual bool PollNextEvent(VREvent_t *pEvent, uint32_t uncbVREvent) = 0; /** Provides access to device poses for drivers. Poses are in their "raw" tracking space which is uniquely * defined by each driver providing poses for its devices. It is up to clients of this function to correlate * poses across different drivers. Poses are indexed by their device id, and their associated driver and * other properties can be looked up via IVRProperties. */ - virtual void GetRawTrackedDevicePoses( float fPredictedSecondsFromNow, TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount ) = 0; + virtual void GetRawTrackedDevicePoses(float fPredictedSecondsFromNow, TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount) = 0; /** Notifies the server that a tracked device's display component transforms have been updated. */ - virtual void TrackedDeviceDisplayTransformUpdated( uint32_t unWhichDevice, HmdMatrix34_t eyeToHeadLeft, HmdMatrix34_t eyeToHeadRight ) = 0; + virtual void TrackedDeviceDisplayTransformUpdated(uint32_t unWhichDevice, HmdMatrix34_t eyeToHeadLeft, HmdMatrix34_t eyeToHeadRight) = 0; }; static const char *IVRServerDriverHost_Version = "IVRServerDriverHost_004"; -} +} // namespace vr // ivrhiddenarea.h namespace vr { - class CVRHiddenAreaHelpers { public: - CVRHiddenAreaHelpers( IVRProperties *pProperties ) : m_pProperties( pProperties ) {} + CVRHiddenAreaHelpers(IVRProperties *pProperties) : m_pProperties(pProperties) {} /** Stores a hidden area mesh in a property */ - ETrackedPropertyError SetHiddenArea( EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount ); + ETrackedPropertyError SetHiddenArea(EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount); /** retrieves a hidden area mesh from a property. Returns the vert count read out of the property. */ - uint32_t GetHiddenArea( EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount, ETrackedPropertyError *peError ); + uint32_t GetHiddenArea(EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount, ETrackedPropertyError *peError); private: - ETrackedDeviceProperty GetPropertyEnum( EVREye eEye, EHiddenAreaMeshType type ) + ETrackedDeviceProperty GetPropertyEnum(EVREye eEye, EHiddenAreaMeshType type) { return (ETrackedDeviceProperty)(Prop_DisplayHiddenArea_Binary_Start + ((int)type * 2) + (int)eEye); } @@ -2340,41 +2265,38 @@ private: IVRProperties *m_pProperties; }; - -inline ETrackedPropertyError CVRHiddenAreaHelpers::SetHiddenArea( EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount ) +inline ETrackedPropertyError CVRHiddenAreaHelpers::SetHiddenArea(EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount) { - ETrackedDeviceProperty prop = GetPropertyEnum( eEye, type ); - CVRPropertyHelpers propHelpers( m_pProperties ); - return propHelpers.SetProperty( propHelpers.TrackedDeviceToPropertyContainer( k_unTrackedDeviceIndex_Hmd ), prop, pVerts, sizeof( HmdVector2_t ) * unVertCount, k_unHiddenAreaPropertyTag ); + ETrackedDeviceProperty prop = GetPropertyEnum(eEye, type); + CVRPropertyHelpers propHelpers(m_pProperties); + return propHelpers.SetProperty(propHelpers.TrackedDeviceToPropertyContainer(k_unTrackedDeviceIndex_Hmd), prop, pVerts, sizeof(HmdVector2_t) * unVertCount, k_unHiddenAreaPropertyTag); } - -inline uint32_t CVRHiddenAreaHelpers::GetHiddenArea( EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount, ETrackedPropertyError *peError ) +inline uint32_t CVRHiddenAreaHelpers::GetHiddenArea(EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount, ETrackedPropertyError *peError) { - ETrackedDeviceProperty prop = GetPropertyEnum( eEye, type ); - CVRPropertyHelpers propHelpers( m_pProperties ); + ETrackedDeviceProperty prop = GetPropertyEnum(eEye, type); + CVRPropertyHelpers propHelpers(m_pProperties); ETrackedPropertyError propError; PropertyTypeTag_t unTag; - uint32_t unBytesNeeded = propHelpers.GetProperty( propHelpers.TrackedDeviceToPropertyContainer( k_unTrackedDeviceIndex_Hmd ), prop, pVerts, sizeof( HmdVector2_t )*unVertCount, &unTag, &propError ); - if ( propError == TrackedProp_Success && unTag != k_unHiddenAreaPropertyTag ) + uint32_t unBytesNeeded = propHelpers.GetProperty(propHelpers.TrackedDeviceToPropertyContainer(k_unTrackedDeviceIndex_Hmd), prop, pVerts, sizeof(HmdVector2_t) * unVertCount, &unTag, &propError); + if (propError == TrackedProp_Success && unTag != k_unHiddenAreaPropertyTag) { propError = TrackedProp_WrongDataType; unBytesNeeded = 0; } - if ( peError ) + if (peError) { *peError = propError; } - return unBytesNeeded / sizeof( HmdVector2_t ); + return unBytesNeeded / sizeof(HmdVector2_t); } -} +} // namespace vr // ivrwatchdoghost.h namespace vr { - /** This interface is provided by vrclient to allow the driver to make everything wake up */ class IVRWatchdogHost { @@ -2386,87 +2308,75 @@ public: static const char *IVRWatchdogHost_Version = "IVRWatchdogHost_001"; -}; - - +}; // namespace vr // ivrvirtualdisplay.h namespace vr { - // ---------------------------------------------------------------------------------------------- - // Purpose: This component is used for drivers that implement a virtual display (e.g. wireless). - // ---------------------------------------------------------------------------------------------- - class IVRVirtualDisplay - { - public: +// ---------------------------------------------------------------------------------------------- +// Purpose: This component is used for drivers that implement a virtual display (e.g. wireless). +// ---------------------------------------------------------------------------------------------- +class IVRVirtualDisplay +{ +public: + /** Submits final backbuffer for display. */ + virtual void Present(vr::SharedTextureHandle_t backbufferTextureHandle) = 0; - /** Submits final backbuffer for display. */ - virtual void Present( vr::SharedTextureHandle_t backbufferTextureHandle ) = 0; + /** Block until the last presented buffer start scanning out. */ + virtual void WaitForPresent() = 0; - /** Block until the last presented buffer start scanning out. */ - virtual void WaitForPresent() = 0; + /** Provides timing data for synchronizing with display. */ + virtual bool GetTimeSinceLastVsync(float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter) = 0; +}; - /** Provides timing data for synchronizing with display. */ - virtual bool GetTimeSinceLastVsync( float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter ) = 0; - }; - - static const char *IVRVirtualDisplay_Version = "IVRVirtualDisplay_001"; - - /** Returns the current IVRVirtualDisplay pointer or NULL the interface could not be found. */ - VR_INTERFACE vr::IVRVirtualDisplay *VR_CALLTYPE VRVirtualDisplay(); -} +static const char *IVRVirtualDisplay_Version = "IVRVirtualDisplay_001"; +/** Returns the current IVRVirtualDisplay pointer or NULL the interface could not be found. */ +VR_INTERFACE vr::IVRVirtualDisplay *VR_CALLTYPE VRVirtualDisplay(); +} // namespace vr // ivrresources.h namespace vr { - class IVRResources { public: - // ------------------------------------ // Shared Resource Methods // ------------------------------------ /** Loads the specified resource into the provided buffer if large enough. * Returns the size in bytes of the buffer required to hold the specified resource. */ - virtual uint32_t LoadSharedResource( const char *pchResourceName, char *pchBuffer, uint32_t unBufferLen ) = 0; + virtual uint32_t LoadSharedResource(const char *pchResourceName, char *pchBuffer, uint32_t unBufferLen) = 0; /** Provides the full path to the specified resource. Resource names can include named directories for * drivers and other things, and this resolves all of those and returns the actual physical path. * pchResourceTypeDirectory is the subdirectory of resources to look in. */ - virtual uint32_t GetResourceFullPath( const char *pchResourceName, const char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen ) = 0; + virtual uint32_t GetResourceFullPath(const char *pchResourceName, const char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen) = 0; }; -static const char * const IVRResources_Version = "IVRResources_001"; +static const char *const IVRResources_Version = "IVRResources_001"; - -} +} // namespace vr // ivrdrivermanager.h namespace vr { - class IVRDriverManager { public: virtual uint32_t GetDriverCount() const = 0; /** Returns the length of the number of bytes necessary to hold this string including the trailing null. */ - virtual uint32_t GetDriverName( vr::DriverId_t nDriver, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize ) = 0; + virtual uint32_t GetDriverName(vr::DriverId_t nDriver, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize) = 0; }; -static const char * const IVRDriverManager_Version = "IVRDriverManager_001"; - -} // namespace vr - - - +static const char *const IVRDriverManager_Version = "IVRDriverManager_001"; +} // namespace vr namespace vr { - static const char * const k_InterfaceVersions[] = +static const char *const k_InterfaceVersions[] = { IVRSettings_Version, ITrackedDeviceServerDriver_Version, @@ -2479,217 +2389,207 @@ namespace vr IVRVirtualDisplay_Version, IVRDriverManager_Version, IVRResources_Version, - nullptr - }; + nullptr}; - inline IVRDriverContext *&VRDriverContext() - { - static IVRDriverContext *pHost; - return pHost; - } - - class COpenVRDriverContext - { - public: - COpenVRDriverContext() : m_propertyHelpers(nullptr), m_hiddenAreaHelpers(nullptr) { Clear(); } - void Clear(); - - EVRInitError InitServer(); - EVRInitError InitWatchdog(); - - IVRSettings *VRSettings() - { - if ( m_pVRSettings == nullptr ) - { - EVRInitError eError; - m_pVRSettings = (IVRSettings *)VRDriverContext()->GetGenericInterface( IVRSettings_Version, &eError ); - } - return m_pVRSettings; - } - - IVRProperties *VRPropertiesRaw() - { - if ( m_pVRProperties == nullptr ) - { - EVRInitError eError; - m_pVRProperties = (IVRProperties *)VRDriverContext()->GetGenericInterface( IVRProperties_Version, &eError ); - m_propertyHelpers = CVRPropertyHelpers( m_pVRProperties ); - m_hiddenAreaHelpers = CVRHiddenAreaHelpers( m_pVRProperties ); - } - return m_pVRProperties; - } - - CVRPropertyHelpers *VRProperties() - { - VRPropertiesRaw(); - return &m_propertyHelpers; - } - - CVRHiddenAreaHelpers *VRHiddenArea() - { - VRPropertiesRaw(); - return &m_hiddenAreaHelpers; - } - - IVRServerDriverHost *VRServerDriverHost() - { - if ( m_pVRServerDriverHost == nullptr ) - { - EVRInitError eError; - m_pVRServerDriverHost = (IVRServerDriverHost *)VRDriverContext()->GetGenericInterface( IVRServerDriverHost_Version, &eError ); - } - return m_pVRServerDriverHost; - } - - IVRWatchdogHost *VRWatchdogHost() - { - if ( m_pVRWatchdogHost == nullptr ) - { - EVRInitError eError; - m_pVRWatchdogHost = (IVRWatchdogHost *)VRDriverContext()->GetGenericInterface( IVRWatchdogHost_Version, &eError ); - } - return m_pVRWatchdogHost; - } - - IVRDriverLog *VRDriverLog() - { - if ( m_pVRDriverLog == nullptr ) - { - EVRInitError eError; - m_pVRDriverLog = (IVRDriverLog *)VRDriverContext()->GetGenericInterface( IVRDriverLog_Version, &eError ); - } - return m_pVRDriverLog; - } - - DriverHandle_t VR_CALLTYPE VRDriverHandle() - { - return VRDriverContext()->GetDriverHandle(); - } - - IVRDriverManager *VRDriverManager() - { - if ( !m_pVRDriverManager ) - { - EVRInitError eError; - m_pVRDriverManager = (IVRDriverManager *)VRDriverContext()->GetGenericInterface( IVRDriverManager_Version, &eError ); - } - return m_pVRDriverManager; - } - - IVRResources *VRResources() - { - if ( !m_pVRResources ) - { - EVRInitError eError; - m_pVRResources = (IVRResources *)VRDriverContext()->GetGenericInterface( IVRResources_Version, &eError ); - } - return m_pVRResources; - } - - private: - CVRPropertyHelpers m_propertyHelpers; - CVRHiddenAreaHelpers m_hiddenAreaHelpers; - - IVRSettings *m_pVRSettings; - IVRProperties *m_pVRProperties; - IVRServerDriverHost *m_pVRServerDriverHost; - IVRWatchdogHost *m_pVRWatchdogHost; - IVRDriverLog *m_pVRDriverLog; - IVRDriverManager *m_pVRDriverManager; - IVRResources *m_pVRResources; - }; - - inline COpenVRDriverContext &OpenVRInternal_ModuleServerDriverContext() - { - static void *ctx[sizeof( COpenVRDriverContext ) / sizeof( void * )]; - return *(COpenVRDriverContext *)ctx; // bypass zero-init constructor - } - - inline IVRSettings *VR_CALLTYPE VRSettings() { return OpenVRInternal_ModuleServerDriverContext().VRSettings(); } - inline IVRProperties *VR_CALLTYPE VRPropertiesRaw() { return OpenVRInternal_ModuleServerDriverContext().VRPropertiesRaw(); } - inline CVRPropertyHelpers *VR_CALLTYPE VRProperties() { return OpenVRInternal_ModuleServerDriverContext().VRProperties(); } - inline CVRHiddenAreaHelpers *VR_CALLTYPE VRHiddenArea() { return OpenVRInternal_ModuleServerDriverContext().VRHiddenArea(); } - inline IVRDriverLog *VR_CALLTYPE VRDriverLog() { return OpenVRInternal_ModuleServerDriverContext().VRDriverLog(); } - inline IVRServerDriverHost *VR_CALLTYPE VRServerDriverHost() { return OpenVRInternal_ModuleServerDriverContext().VRServerDriverHost(); } - inline IVRWatchdogHost *VR_CALLTYPE VRWatchdogHost() { return OpenVRInternal_ModuleServerDriverContext().VRWatchdogHost(); } - inline DriverHandle_t VR_CALLTYPE VRDriverHandle() { return OpenVRInternal_ModuleServerDriverContext().VRDriverHandle(); } - inline IVRDriverManager *VR_CALLTYPE VRDriverManager() { return OpenVRInternal_ModuleServerDriverContext().VRDriverManager(); } - inline IVRResources *VR_CALLTYPE VRResources() { return OpenVRInternal_ModuleServerDriverContext().VRResources(); } - - inline void COpenVRDriverContext::Clear() - { - m_pVRSettings = nullptr; - m_pVRProperties = nullptr; - m_pVRServerDriverHost = nullptr; - m_pVRDriverLog = nullptr; - m_pVRWatchdogHost = nullptr; - m_pVRDriverManager = nullptr; - m_pVRResources = nullptr; - } - - inline EVRInitError COpenVRDriverContext::InitServer() - { - Clear(); - if ( !VRServerDriverHost() - || !VRSettings() - || !VRProperties() - || !VRDriverLog() - || !VRDriverManager() - || !VRResources() ) - return VRInitError_Init_InterfaceNotFound; - return VRInitError_None; - } - - inline EVRInitError COpenVRDriverContext::InitWatchdog() - { - Clear(); - if ( !VRWatchdogHost() - || !VRSettings() - || !VRDriverLog() ) - return VRInitError_Init_InterfaceNotFound; - return VRInitError_None; - } - - inline EVRInitError InitServerDriverContext( IVRDriverContext *pContext ) - { - VRDriverContext() = pContext; - return OpenVRInternal_ModuleServerDriverContext().InitServer(); - } - - inline EVRInitError InitWatchdogDriverContext( IVRDriverContext *pContext ) - { - VRDriverContext() = pContext; - return OpenVRInternal_ModuleServerDriverContext().InitWatchdog(); - } - - inline void CleanupDriverContext() - { - VRDriverContext() = nullptr; - OpenVRInternal_ModuleServerDriverContext().Clear(); - } - - #define VR_INIT_SERVER_DRIVER_CONTEXT( pContext ) \ - { \ - vr::EVRInitError eError = vr::InitServerDriverContext( pContext ); \ - if( eError != vr::VRInitError_None ) \ - return eError; \ - } - - #define VR_CLEANUP_SERVER_DRIVER_CONTEXT() \ - vr::CleanupDriverContext(); - - #define VR_INIT_WATCHDOG_DRIVER_CONTEXT( pContext ) \ - { \ - vr::EVRInitError eError = vr::InitWatchdogDriverContext( pContext ); \ - if( eError != vr::VRInitError_None ) \ - return eError; \ - } - - #define VR_CLEANUP_WATCHDOG_DRIVER_CONTEXT() \ - vr::CleanupDriverContext(); +inline IVRDriverContext *&VRDriverContext() +{ + static IVRDriverContext *pHost; + return pHost; } + +class COpenVRDriverContext +{ +public: + COpenVRDriverContext() : m_propertyHelpers(nullptr), m_hiddenAreaHelpers(nullptr) { Clear(); } + void Clear(); + + EVRInitError InitServer(); + EVRInitError InitWatchdog(); + + IVRSettings *VRSettings() + { + if (m_pVRSettings == nullptr) + { + EVRInitError eError; + m_pVRSettings = (IVRSettings *)VRDriverContext()->GetGenericInterface(IVRSettings_Version, &eError); + } + return m_pVRSettings; + } + + IVRProperties *VRPropertiesRaw() + { + if (m_pVRProperties == nullptr) + { + EVRInitError eError; + m_pVRProperties = (IVRProperties *)VRDriverContext()->GetGenericInterface(IVRProperties_Version, &eError); + m_propertyHelpers = CVRPropertyHelpers(m_pVRProperties); + m_hiddenAreaHelpers = CVRHiddenAreaHelpers(m_pVRProperties); + } + return m_pVRProperties; + } + + CVRPropertyHelpers *VRProperties() + { + VRPropertiesRaw(); + return &m_propertyHelpers; + } + + CVRHiddenAreaHelpers *VRHiddenArea() + { + VRPropertiesRaw(); + return &m_hiddenAreaHelpers; + } + + IVRServerDriverHost *VRServerDriverHost() + { + if (m_pVRServerDriverHost == nullptr) + { + EVRInitError eError; + m_pVRServerDriverHost = (IVRServerDriverHost *)VRDriverContext()->GetGenericInterface(IVRServerDriverHost_Version, &eError); + } + return m_pVRServerDriverHost; + } + + IVRWatchdogHost *VRWatchdogHost() + { + if (m_pVRWatchdogHost == nullptr) + { + EVRInitError eError; + m_pVRWatchdogHost = (IVRWatchdogHost *)VRDriverContext()->GetGenericInterface(IVRWatchdogHost_Version, &eError); + } + return m_pVRWatchdogHost; + } + + IVRDriverLog *VRDriverLog() + { + if (m_pVRDriverLog == nullptr) + { + EVRInitError eError; + m_pVRDriverLog = (IVRDriverLog *)VRDriverContext()->GetGenericInterface(IVRDriverLog_Version, &eError); + } + return m_pVRDriverLog; + } + + DriverHandle_t VR_CALLTYPE VRDriverHandle() + { + return VRDriverContext()->GetDriverHandle(); + } + + IVRDriverManager *VRDriverManager() + { + if (!m_pVRDriverManager) + { + EVRInitError eError; + m_pVRDriverManager = (IVRDriverManager *)VRDriverContext()->GetGenericInterface(IVRDriverManager_Version, &eError); + } + return m_pVRDriverManager; + } + + IVRResources *VRResources() + { + if (!m_pVRResources) + { + EVRInitError eError; + m_pVRResources = (IVRResources *)VRDriverContext()->GetGenericInterface(IVRResources_Version, &eError); + } + return m_pVRResources; + } + +private: + CVRPropertyHelpers m_propertyHelpers; + CVRHiddenAreaHelpers m_hiddenAreaHelpers; + + IVRSettings *m_pVRSettings; + IVRProperties *m_pVRProperties; + IVRServerDriverHost *m_pVRServerDriverHost; + IVRWatchdogHost *m_pVRWatchdogHost; + IVRDriverLog *m_pVRDriverLog; + IVRDriverManager *m_pVRDriverManager; + IVRResources *m_pVRResources; +}; + +inline COpenVRDriverContext &OpenVRInternal_ModuleServerDriverContext() +{ + static void *ctx[sizeof(COpenVRDriverContext) / sizeof(void *)]; + return *(COpenVRDriverContext *)ctx; // bypass zero-init constructor +} + +inline IVRSettings *VR_CALLTYPE VRSettings() { return OpenVRInternal_ModuleServerDriverContext().VRSettings(); } +inline IVRProperties *VR_CALLTYPE VRPropertiesRaw() { return OpenVRInternal_ModuleServerDriverContext().VRPropertiesRaw(); } +inline CVRPropertyHelpers *VR_CALLTYPE VRProperties() { return OpenVRInternal_ModuleServerDriverContext().VRProperties(); } +inline CVRHiddenAreaHelpers *VR_CALLTYPE VRHiddenArea() { return OpenVRInternal_ModuleServerDriverContext().VRHiddenArea(); } +inline IVRDriverLog *VR_CALLTYPE VRDriverLog() { return OpenVRInternal_ModuleServerDriverContext().VRDriverLog(); } +inline IVRServerDriverHost *VR_CALLTYPE VRServerDriverHost() { return OpenVRInternal_ModuleServerDriverContext().VRServerDriverHost(); } +inline IVRWatchdogHost *VR_CALLTYPE VRWatchdogHost() { return OpenVRInternal_ModuleServerDriverContext().VRWatchdogHost(); } +inline DriverHandle_t VR_CALLTYPE VRDriverHandle() { return OpenVRInternal_ModuleServerDriverContext().VRDriverHandle(); } +inline IVRDriverManager *VR_CALLTYPE VRDriverManager() { return OpenVRInternal_ModuleServerDriverContext().VRDriverManager(); } +inline IVRResources *VR_CALLTYPE VRResources() { return OpenVRInternal_ModuleServerDriverContext().VRResources(); } + +inline void COpenVRDriverContext::Clear() +{ + m_pVRSettings = nullptr; + m_pVRProperties = nullptr; + m_pVRServerDriverHost = nullptr; + m_pVRDriverLog = nullptr; + m_pVRWatchdogHost = nullptr; + m_pVRDriverManager = nullptr; + m_pVRResources = nullptr; +} + +inline EVRInitError COpenVRDriverContext::InitServer() +{ + Clear(); + if (!VRServerDriverHost() || !VRSettings() || !VRProperties() || !VRDriverLog() || !VRDriverManager() || !VRResources()) + return VRInitError_Init_InterfaceNotFound; + return VRInitError_None; +} + +inline EVRInitError COpenVRDriverContext::InitWatchdog() +{ + Clear(); + if (!VRWatchdogHost() || !VRSettings() || !VRDriverLog()) + return VRInitError_Init_InterfaceNotFound; + return VRInitError_None; +} + +inline EVRInitError InitServerDriverContext(IVRDriverContext *pContext) +{ + VRDriverContext() = pContext; + return OpenVRInternal_ModuleServerDriverContext().InitServer(); +} + +inline EVRInitError InitWatchdogDriverContext(IVRDriverContext *pContext) +{ + VRDriverContext() = pContext; + return OpenVRInternal_ModuleServerDriverContext().InitWatchdog(); +} + +inline void CleanupDriverContext() +{ + VRDriverContext() = nullptr; + OpenVRInternal_ModuleServerDriverContext().Clear(); +} + +#define VR_INIT_SERVER_DRIVER_CONTEXT(pContext) \ + { \ + vr::EVRInitError eError = vr::InitServerDriverContext(pContext); \ + if (eError != vr::VRInitError_None) \ + return eError; \ + } + +#define VR_CLEANUP_SERVER_DRIVER_CONTEXT() \ + vr::CleanupDriverContext(); + +#define VR_INIT_WATCHDOG_DRIVER_CONTEXT(pContext) \ + { \ + vr::EVRInitError eError = vr::InitWatchdogDriverContext(pContext); \ + if (eError != vr::VRInitError_None) \ + return eError; \ + } + +#define VR_CLEANUP_WATCHDOG_DRIVER_CONTEXT() \ + vr::CleanupDriverContext(); +} // namespace vr // End -#endif // _OPENVR_DRIVER_API - - +#endif // _OPENVR_DRIVER_API diff --git a/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/Current/Headers/openvr.h b/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/Current/Headers/openvr.h index f945dbc1a..80461f968 100644 --- a/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/Current/Headers/openvr.h +++ b/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/Current/Headers/openvr.h @@ -9,8 +9,6 @@ #include - - // vrtypes.h #ifndef _INCLUDE_VRTYPES_H #define _INCLUDE_VRTYPES_H @@ -27,9 +25,9 @@ struct ID3D12CommandQueue; namespace vr { -#pragma pack( push, 8 ) +#pragma pack(push, 8) -typedef void* glSharedTextureHandle_t; +typedef void *glSharedTextureHandle_t; typedef int32_t glInt_t; typedef uint32_t glUInt_t; @@ -80,7 +78,7 @@ struct HmdColor_t struct HmdQuad_t { - HmdVector3_t vCorners[ 4 ]; + HmdVector3_t vCorners[4]; }; struct HmdRect2_t @@ -107,40 +105,40 @@ enum EVREye enum ETextureType { - TextureType_DirectX = 0, // Handle is an ID3D11Texture - TextureType_OpenGL = 1, // Handle is an OpenGL texture name or an OpenGL render buffer name, depending on submit flags - TextureType_Vulkan = 2, // Handle is a pointer to a VRVulkanTextureData_t structure - TextureType_IOSurface = 3, // Handle is a macOS cross-process-sharable IOSurfaceRef - TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure + TextureType_DirectX = 0, // Handle is an ID3D11Texture + TextureType_OpenGL = 1, // Handle is an OpenGL texture name or an OpenGL render buffer name, depending on submit flags + TextureType_Vulkan = 2, // Handle is a pointer to a VRVulkanTextureData_t structure + TextureType_IOSurface = 3, // Handle is a macOS cross-process-sharable IOSurfaceRef + TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure }; enum EColorSpace { - ColorSpace_Auto = 0, // Assumes 'gamma' for 8-bit per component formats, otherwise 'linear'. This mirrors the DXGI formats which have _SRGB variants. - ColorSpace_Gamma = 1, // Texture data can be displayed directly on the display without any conversion (a.k.a. display native format). - ColorSpace_Linear = 2, // Same as gamma but has been converted to a linear representation using DXGI's sRGB conversion algorithm. + ColorSpace_Auto = 0, // Assumes 'gamma' for 8-bit per component formats, otherwise 'linear'. This mirrors the DXGI formats which have _SRGB variants. + ColorSpace_Gamma = 1, // Texture data can be displayed directly on the display without any conversion (a.k.a. display native format). + ColorSpace_Linear = 2, // Same as gamma but has been converted to a linear representation using DXGI's sRGB conversion algorithm. }; struct Texture_t { - void* handle; // See ETextureType definition above + void *handle; // See ETextureType definition above ETextureType eType; EColorSpace eColorSpace; }; // Handle to a shared texture (HANDLE on Windows obtained using OpenSharedResource). typedef uint64_t SharedTextureHandle_t; -#define INVALID_SHARED_TEXTURE_HANDLE ((vr::SharedTextureHandle_t)0) +#define INVALID_SHARED_TEXTURE_HANDLE ((vr::SharedTextureHandle_t)0) enum ETrackingResult { - TrackingResult_Uninitialized = 1, + TrackingResult_Uninitialized = 1, - TrackingResult_Calibrating_InProgress = 100, - TrackingResult_Calibrating_OutOfRange = 101, + TrackingResult_Calibrating_InProgress = 100, + TrackingResult_Calibrating_OutOfRange = 101, - TrackingResult_Running_OK = 200, - TrackingResult_Running_OutOfRange = 201, + TrackingResult_Running_OK = 200, + TrackingResult_Running_OutOfRange = 201, }; typedef uint32_t DriverId_t; @@ -158,30 +156,28 @@ static const uint32_t k_unTrackedDeviceIndexInvalid = 0xFFFFFFFF; /** Describes what kind of object is being tracked at a given ID */ enum ETrackedDeviceClass { - TrackedDeviceClass_Invalid = 0, // the ID was not valid. - TrackedDeviceClass_HMD = 1, // Head-Mounted Displays - TrackedDeviceClass_Controller = 2, // Tracked controllers - TrackedDeviceClass_GenericTracker = 3, // Generic trackers, similar to controllers - TrackedDeviceClass_TrackingReference = 4, // Camera and base stations that serve as tracking reference points - TrackedDeviceClass_DisplayRedirect = 5, // Accessories that aren't necessarily tracked themselves, but may redirect video output from other tracked devices + TrackedDeviceClass_Invalid = 0, // the ID was not valid. + TrackedDeviceClass_HMD = 1, // Head-Mounted Displays + TrackedDeviceClass_Controller = 2, // Tracked controllers + TrackedDeviceClass_GenericTracker = 3, // Generic trackers, similar to controllers + TrackedDeviceClass_TrackingReference = 4, // Camera and base stations that serve as tracking reference points + TrackedDeviceClass_DisplayRedirect = 5, // Accessories that aren't necessarily tracked themselves, but may redirect video output from other tracked devices }; - /** Describes what specific role associated with a tracked device */ enum ETrackedControllerRole { - TrackedControllerRole_Invalid = 0, // Invalid value for controller type - TrackedControllerRole_LeftHand = 1, // Tracked device associated with the left hand - TrackedControllerRole_RightHand = 2, // Tracked device associated with the right hand + TrackedControllerRole_Invalid = 0, // Invalid value for controller type + TrackedControllerRole_LeftHand = 1, // Tracked device associated with the left hand + TrackedControllerRole_RightHand = 2, // Tracked device associated with the right hand }; - /** describes a single pose for a tracked object */ struct TrackedDevicePose_t { HmdMatrix34_t mDeviceToAbsoluteTracking; - HmdVector3_t vVelocity; // velocity in tracker space in m/s - HmdVector3_t vAngularVelocity; // angular velocity in radians/s (?) + HmdVector3_t vVelocity; // velocity in tracker space in m/s + HmdVector3_t vAngularVelocity; // angular velocity in radians/s (?) ETrackingResult eTrackingResult; bool bPoseIsValid; @@ -194,9 +190,9 @@ struct TrackedDevicePose_t * for the poses it is requesting */ enum ETrackingUniverseOrigin { - TrackingUniverseSeated = 0, // Poses are provided relative to the seated zero pose - TrackingUniverseStanding = 1, // Poses are provided relative to the safe bounds configured by the user - TrackingUniverseRawAndUncalibrated = 2, // Poses are provided in the coordinate system defined by the driver. It has Y up and is unified for devices of the same driver. You usually don't want this one. + TrackingUniverseSeated = 0, // Poses are provided relative to the seated zero pose + TrackingUniverseStanding = 1, // Poses are provided relative to the safe bounds configured by the user + TrackingUniverseRawAndUncalibrated = 2, // Poses are provided in the coordinate system defined by the driver. It has Y up and is unified for devices of the same driver. You usually don't want this one. }; // Refers to a single container of properties @@ -223,146 +219,145 @@ static const PropertyTypeTag_t k_unHiddenAreaPropertyTag = 30; static const PropertyTypeTag_t k_unOpenVRInternalReserved_Start = 1000; static const PropertyTypeTag_t k_unOpenVRInternalReserved_End = 10000; - /** Each entry in this enum represents a property that can be retrieved about a * tracked device. Many fields are only valid for one ETrackedDeviceClass. */ enum ETrackedDeviceProperty { - Prop_Invalid = 0, + Prop_Invalid = 0, // general properties that apply to all device classes - Prop_TrackingSystemName_String = 1000, - Prop_ModelNumber_String = 1001, - Prop_SerialNumber_String = 1002, - Prop_RenderModelName_String = 1003, - Prop_WillDriftInYaw_Bool = 1004, - Prop_ManufacturerName_String = 1005, - Prop_TrackingFirmwareVersion_String = 1006, - Prop_HardwareRevision_String = 1007, - Prop_AllWirelessDongleDescriptions_String = 1008, - Prop_ConnectedWirelessDongle_String = 1009, - Prop_DeviceIsWireless_Bool = 1010, - Prop_DeviceIsCharging_Bool = 1011, - Prop_DeviceBatteryPercentage_Float = 1012, // 0 is empty, 1 is full - Prop_StatusDisplayTransform_Matrix34 = 1013, - Prop_Firmware_UpdateAvailable_Bool = 1014, - Prop_Firmware_ManualUpdate_Bool = 1015, - Prop_Firmware_ManualUpdateURL_String = 1016, - Prop_HardwareRevision_Uint64 = 1017, - Prop_FirmwareVersion_Uint64 = 1018, - Prop_FPGAVersion_Uint64 = 1019, - Prop_VRCVersion_Uint64 = 1020, - Prop_RadioVersion_Uint64 = 1021, - Prop_DongleVersion_Uint64 = 1022, - Prop_BlockServerShutdown_Bool = 1023, - Prop_CanUnifyCoordinateSystemWithHmd_Bool = 1024, - Prop_ContainsProximitySensor_Bool = 1025, - Prop_DeviceProvidesBatteryStatus_Bool = 1026, - Prop_DeviceCanPowerOff_Bool = 1027, - Prop_Firmware_ProgrammingTarget_String = 1028, - Prop_DeviceClass_Int32 = 1029, - Prop_HasCamera_Bool = 1030, - Prop_DriverVersion_String = 1031, - Prop_Firmware_ForceUpdateRequired_Bool = 1032, - Prop_ViveSystemButtonFixRequired_Bool = 1033, - Prop_ParentDriver_Uint64 = 1034, - Prop_ResourceRoot_String = 1035, + Prop_TrackingSystemName_String = 1000, + Prop_ModelNumber_String = 1001, + Prop_SerialNumber_String = 1002, + Prop_RenderModelName_String = 1003, + Prop_WillDriftInYaw_Bool = 1004, + Prop_ManufacturerName_String = 1005, + Prop_TrackingFirmwareVersion_String = 1006, + Prop_HardwareRevision_String = 1007, + Prop_AllWirelessDongleDescriptions_String = 1008, + Prop_ConnectedWirelessDongle_String = 1009, + Prop_DeviceIsWireless_Bool = 1010, + Prop_DeviceIsCharging_Bool = 1011, + Prop_DeviceBatteryPercentage_Float = 1012, // 0 is empty, 1 is full + Prop_StatusDisplayTransform_Matrix34 = 1013, + Prop_Firmware_UpdateAvailable_Bool = 1014, + Prop_Firmware_ManualUpdate_Bool = 1015, + Prop_Firmware_ManualUpdateURL_String = 1016, + Prop_HardwareRevision_Uint64 = 1017, + Prop_FirmwareVersion_Uint64 = 1018, + Prop_FPGAVersion_Uint64 = 1019, + Prop_VRCVersion_Uint64 = 1020, + Prop_RadioVersion_Uint64 = 1021, + Prop_DongleVersion_Uint64 = 1022, + Prop_BlockServerShutdown_Bool = 1023, + Prop_CanUnifyCoordinateSystemWithHmd_Bool = 1024, + Prop_ContainsProximitySensor_Bool = 1025, + Prop_DeviceProvidesBatteryStatus_Bool = 1026, + Prop_DeviceCanPowerOff_Bool = 1027, + Prop_Firmware_ProgrammingTarget_String = 1028, + Prop_DeviceClass_Int32 = 1029, + Prop_HasCamera_Bool = 1030, + Prop_DriverVersion_String = 1031, + Prop_Firmware_ForceUpdateRequired_Bool = 1032, + Prop_ViveSystemButtonFixRequired_Bool = 1033, + Prop_ParentDriver_Uint64 = 1034, + Prop_ResourceRoot_String = 1035, // Properties that are unique to TrackedDeviceClass_HMD - Prop_ReportsTimeSinceVSync_Bool = 2000, - Prop_SecondsFromVsyncToPhotons_Float = 2001, - Prop_DisplayFrequency_Float = 2002, - Prop_UserIpdMeters_Float = 2003, - Prop_CurrentUniverseId_Uint64 = 2004, - Prop_PreviousUniverseId_Uint64 = 2005, - Prop_DisplayFirmwareVersion_Uint64 = 2006, - Prop_IsOnDesktop_Bool = 2007, - Prop_DisplayMCType_Int32 = 2008, - Prop_DisplayMCOffset_Float = 2009, - Prop_DisplayMCScale_Float = 2010, - Prop_EdidVendorID_Int32 = 2011, - Prop_DisplayMCImageLeft_String = 2012, - Prop_DisplayMCImageRight_String = 2013, - Prop_DisplayGCBlackClamp_Float = 2014, - Prop_EdidProductID_Int32 = 2015, - Prop_CameraToHeadTransform_Matrix34 = 2016, - Prop_DisplayGCType_Int32 = 2017, - Prop_DisplayGCOffset_Float = 2018, - Prop_DisplayGCScale_Float = 2019, - Prop_DisplayGCPrescale_Float = 2020, - Prop_DisplayGCImage_String = 2021, - Prop_LensCenterLeftU_Float = 2022, - Prop_LensCenterLeftV_Float = 2023, - Prop_LensCenterRightU_Float = 2024, - Prop_LensCenterRightV_Float = 2025, - Prop_UserHeadToEyeDepthMeters_Float = 2026, - Prop_CameraFirmwareVersion_Uint64 = 2027, - Prop_CameraFirmwareDescription_String = 2028, - Prop_DisplayFPGAVersion_Uint64 = 2029, - Prop_DisplayBootloaderVersion_Uint64 = 2030, - Prop_DisplayHardwareVersion_Uint64 = 2031, - Prop_AudioFirmwareVersion_Uint64 = 2032, - Prop_CameraCompatibilityMode_Int32 = 2033, + Prop_ReportsTimeSinceVSync_Bool = 2000, + Prop_SecondsFromVsyncToPhotons_Float = 2001, + Prop_DisplayFrequency_Float = 2002, + Prop_UserIpdMeters_Float = 2003, + Prop_CurrentUniverseId_Uint64 = 2004, + Prop_PreviousUniverseId_Uint64 = 2005, + Prop_DisplayFirmwareVersion_Uint64 = 2006, + Prop_IsOnDesktop_Bool = 2007, + Prop_DisplayMCType_Int32 = 2008, + Prop_DisplayMCOffset_Float = 2009, + Prop_DisplayMCScale_Float = 2010, + Prop_EdidVendorID_Int32 = 2011, + Prop_DisplayMCImageLeft_String = 2012, + Prop_DisplayMCImageRight_String = 2013, + Prop_DisplayGCBlackClamp_Float = 2014, + Prop_EdidProductID_Int32 = 2015, + Prop_CameraToHeadTransform_Matrix34 = 2016, + Prop_DisplayGCType_Int32 = 2017, + Prop_DisplayGCOffset_Float = 2018, + Prop_DisplayGCScale_Float = 2019, + Prop_DisplayGCPrescale_Float = 2020, + Prop_DisplayGCImage_String = 2021, + Prop_LensCenterLeftU_Float = 2022, + Prop_LensCenterLeftV_Float = 2023, + Prop_LensCenterRightU_Float = 2024, + Prop_LensCenterRightV_Float = 2025, + Prop_UserHeadToEyeDepthMeters_Float = 2026, + Prop_CameraFirmwareVersion_Uint64 = 2027, + Prop_CameraFirmwareDescription_String = 2028, + Prop_DisplayFPGAVersion_Uint64 = 2029, + Prop_DisplayBootloaderVersion_Uint64 = 2030, + Prop_DisplayHardwareVersion_Uint64 = 2031, + Prop_AudioFirmwareVersion_Uint64 = 2032, + Prop_CameraCompatibilityMode_Int32 = 2033, Prop_ScreenshotHorizontalFieldOfViewDegrees_Float = 2034, Prop_ScreenshotVerticalFieldOfViewDegrees_Float = 2035, - Prop_DisplaySuppressed_Bool = 2036, - Prop_DisplayAllowNightMode_Bool = 2037, - Prop_DisplayMCImageWidth_Int32 = 2038, - Prop_DisplayMCImageHeight_Int32 = 2039, - Prop_DisplayMCImageNumChannels_Int32 = 2040, - Prop_DisplayMCImageData_Binary = 2041, - Prop_SecondsFromPhotonsToVblank_Float = 2042, - Prop_DriverDirectModeSendsVsyncEvents_Bool = 2043, - Prop_DisplayDebugMode_Bool = 2044, - Prop_GraphicsAdapterLuid_Uint64 = 2045, - Prop_DriverProvidedChaperonePath_String = 2048, + Prop_DisplaySuppressed_Bool = 2036, + Prop_DisplayAllowNightMode_Bool = 2037, + Prop_DisplayMCImageWidth_Int32 = 2038, + Prop_DisplayMCImageHeight_Int32 = 2039, + Prop_DisplayMCImageNumChannels_Int32 = 2040, + Prop_DisplayMCImageData_Binary = 2041, + Prop_SecondsFromPhotonsToVblank_Float = 2042, + Prop_DriverDirectModeSendsVsyncEvents_Bool = 2043, + Prop_DisplayDebugMode_Bool = 2044, + Prop_GraphicsAdapterLuid_Uint64 = 2045, + Prop_DriverProvidedChaperonePath_String = 2048, // Properties that are unique to TrackedDeviceClass_Controller - Prop_AttachedDeviceId_String = 3000, - Prop_SupportedButtons_Uint64 = 3001, - Prop_Axis0Type_Int32 = 3002, // Return value is of type EVRControllerAxisType - Prop_Axis1Type_Int32 = 3003, // Return value is of type EVRControllerAxisType - Prop_Axis2Type_Int32 = 3004, // Return value is of type EVRControllerAxisType - Prop_Axis3Type_Int32 = 3005, // Return value is of type EVRControllerAxisType - Prop_Axis4Type_Int32 = 3006, // Return value is of type EVRControllerAxisType - Prop_ControllerRoleHint_Int32 = 3007, // Return value is of type ETrackedControllerRole + Prop_AttachedDeviceId_String = 3000, + Prop_SupportedButtons_Uint64 = 3001, + Prop_Axis0Type_Int32 = 3002, // Return value is of type EVRControllerAxisType + Prop_Axis1Type_Int32 = 3003, // Return value is of type EVRControllerAxisType + Prop_Axis2Type_Int32 = 3004, // Return value is of type EVRControllerAxisType + Prop_Axis3Type_Int32 = 3005, // Return value is of type EVRControllerAxisType + Prop_Axis4Type_Int32 = 3006, // Return value is of type EVRControllerAxisType + Prop_ControllerRoleHint_Int32 = 3007, // Return value is of type ETrackedControllerRole // Properties that are unique to TrackedDeviceClass_TrackingReference - Prop_FieldOfViewLeftDegrees_Float = 4000, - Prop_FieldOfViewRightDegrees_Float = 4001, - Prop_FieldOfViewTopDegrees_Float = 4002, - Prop_FieldOfViewBottomDegrees_Float = 4003, - Prop_TrackingRangeMinimumMeters_Float = 4004, - Prop_TrackingRangeMaximumMeters_Float = 4005, - Prop_ModeLabel_String = 4006, + Prop_FieldOfViewLeftDegrees_Float = 4000, + Prop_FieldOfViewRightDegrees_Float = 4001, + Prop_FieldOfViewTopDegrees_Float = 4002, + Prop_FieldOfViewBottomDegrees_Float = 4003, + Prop_TrackingRangeMinimumMeters_Float = 4004, + Prop_TrackingRangeMaximumMeters_Float = 4005, + Prop_ModeLabel_String = 4006, // Properties that are used for user interface like icons names - Prop_IconPathName_String = 5000, // DEPRECATED. Value not referenced. Now expected to be part of icon path properties. - Prop_NamedIconPathDeviceOff_String = 5001, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceSearching_String = 5002, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceSearchingAlert_String = 5003, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceReady_String = 5004, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceReadyAlert_String = 5005, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceNotReady_String = 5006, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceStandby_String = 5007, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceAlertLow_String = 5008, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_IconPathName_String = 5000, // DEPRECATED. Value not referenced. Now expected to be part of icon path properties. + Prop_NamedIconPathDeviceOff_String = 5001, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceSearching_String = 5002, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceSearchingAlert_String = 5003, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceReady_String = 5004, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceReadyAlert_String = 5005, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceNotReady_String = 5006, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceStandby_String = 5007, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceAlertLow_String = 5008, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others // Properties that are used by helpers, but are opaque to applications - Prop_DisplayHiddenArea_Binary_Start = 5100, - Prop_DisplayHiddenArea_Binary_End = 5150, + Prop_DisplayHiddenArea_Binary_Start = 5100, + Prop_DisplayHiddenArea_Binary_End = 5150, // Properties that are unique to drivers - Prop_UserConfigPath_String = 6000, - Prop_InstallPath_String = 6001, - Prop_HasDisplayComponent_Bool = 6002, - Prop_HasControllerComponent_Bool = 6003, - Prop_HasCameraComponent_Bool = 6004, - Prop_HasDriverDirectModeComponent_Bool = 6005, - Prop_HasVirtualDisplayComponent_Bool = 6006, + Prop_UserConfigPath_String = 6000, + Prop_InstallPath_String = 6001, + Prop_HasDisplayComponent_Bool = 6002, + Prop_HasControllerComponent_Bool = 6003, + Prop_HasCameraComponent_Bool = 6004, + Prop_HasDriverDirectModeComponent_Bool = 6005, + Prop_HasVirtualDisplayComponent_Bool = 6006, // Vendors are free to expose private debug data in this reserved region - Prop_VendorSpecific_Reserved_Start = 10000, - Prop_VendorSpecific_Reserved_End = 10999, + Prop_VendorSpecific_Reserved_Start = 10000, + Prop_VendorSpecific_Reserved_End = 10999, }; /** No string property will ever be longer than this length */ @@ -371,18 +366,18 @@ static const uint32_t k_unMaxPropertyStringSize = 32 * 1024; /** Used to return errors that occur when reading properties. */ enum ETrackedPropertyError { - TrackedProp_Success = 0, - TrackedProp_WrongDataType = 1, - TrackedProp_WrongDeviceClass = 2, - TrackedProp_BufferTooSmall = 3, - TrackedProp_UnknownProperty = 4, // Driver has not set the property (and may not ever). - TrackedProp_InvalidDevice = 5, - TrackedProp_CouldNotContactServer = 6, - TrackedProp_ValueNotProvidedByDevice = 7, - TrackedProp_StringExceedsMaximumLength = 8, - TrackedProp_NotYetAvailable = 9, // The property value isn't known yet, but is expected soon. Call again later. - TrackedProp_PermissionDenied = 10, - TrackedProp_InvalidOperation = 11, + TrackedProp_Success = 0, + TrackedProp_WrongDataType = 1, + TrackedProp_WrongDeviceClass = 2, + TrackedProp_BufferTooSmall = 3, + TrackedProp_UnknownProperty = 4, // Driver has not set the property (and may not ever). + TrackedProp_InvalidDevice = 5, + TrackedProp_CouldNotContactServer = 6, + TrackedProp_ValueNotProvidedByDevice = 7, + TrackedProp_StringExceedsMaximumLength = 8, + TrackedProp_NotYetAvailable = 9, // The property value isn't known yet, but is expected soon. Call again later. + TrackedProp_PermissionDenied = 10, + TrackedProp_InvalidOperation = 11, }; /** Allows the application to control what part of the provided texture will be used in the @@ -396,7 +391,7 @@ struct VRTextureBounds_t /** Allows specifying pose used to render provided scene texture (if different from value returned by WaitGetPoses). */ struct VRTextureWithPose_t : public Texture_t { - HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures. + HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures. }; /** Allows the application to control how scene textures are used by the compositor when calling Submit. */ @@ -424,7 +419,7 @@ enum EVRSubmitFlags * Be sure to call OpenVR_Shutdown before destroying these resources. */ struct VRVulkanTextureData_t { - uint64_t m_nImage; // VkImage + uint64_t m_nImage; // VkImage VkDevice_T *m_pDevice; VkPhysicalDevice_T *m_pPhysicalDevice; VkInstance_T *m_pInstance; @@ -461,220 +456,216 @@ enum EVREventType { VREvent_None = 0, - VREvent_TrackedDeviceActivated = 100, - VREvent_TrackedDeviceDeactivated = 101, - VREvent_TrackedDeviceUpdated = 102, - VREvent_TrackedDeviceUserInteractionStarted = 103, - VREvent_TrackedDeviceUserInteractionEnded = 104, - VREvent_IpdChanged = 105, - VREvent_EnterStandbyMode = 106, - VREvent_LeaveStandbyMode = 107, - VREvent_TrackedDeviceRoleChanged = 108, - VREvent_WatchdogWakeUpRequested = 109, - VREvent_LensDistortionChanged = 110, - VREvent_PropertyChanged = 111, - VREvent_WirelessDisconnect = 112, - VREvent_WirelessReconnect = 113, + VREvent_TrackedDeviceActivated = 100, + VREvent_TrackedDeviceDeactivated = 101, + VREvent_TrackedDeviceUpdated = 102, + VREvent_TrackedDeviceUserInteractionStarted = 103, + VREvent_TrackedDeviceUserInteractionEnded = 104, + VREvent_IpdChanged = 105, + VREvent_EnterStandbyMode = 106, + VREvent_LeaveStandbyMode = 107, + VREvent_TrackedDeviceRoleChanged = 108, + VREvent_WatchdogWakeUpRequested = 109, + VREvent_LensDistortionChanged = 110, + VREvent_PropertyChanged = 111, + VREvent_WirelessDisconnect = 112, + VREvent_WirelessReconnect = 113, - VREvent_ButtonPress = 200, // data is controller - VREvent_ButtonUnpress = 201, // data is controller - VREvent_ButtonTouch = 202, // data is controller - VREvent_ButtonUntouch = 203, // data is controller + VREvent_ButtonPress = 200, // data is controller + VREvent_ButtonUnpress = 201, // data is controller + VREvent_ButtonTouch = 202, // data is controller + VREvent_ButtonUntouch = 203, // data is controller - VREvent_MouseMove = 300, // data is mouse - VREvent_MouseButtonDown = 301, // data is mouse - VREvent_MouseButtonUp = 302, // data is mouse - VREvent_FocusEnter = 303, // data is overlay - VREvent_FocusLeave = 304, // data is overlay - VREvent_Scroll = 305, // data is mouse - VREvent_TouchPadMove = 306, // data is mouse - VREvent_OverlayFocusChanged = 307, // data is overlay, global event + VREvent_MouseMove = 300, // data is mouse + VREvent_MouseButtonDown = 301, // data is mouse + VREvent_MouseButtonUp = 302, // data is mouse + VREvent_FocusEnter = 303, // data is overlay + VREvent_FocusLeave = 304, // data is overlay + VREvent_Scroll = 305, // data is mouse + VREvent_TouchPadMove = 306, // data is mouse + VREvent_OverlayFocusChanged = 307, // data is overlay, global event - VREvent_InputFocusCaptured = 400, // data is process DEPRECATED - VREvent_InputFocusReleased = 401, // data is process DEPRECATED - VREvent_SceneFocusLost = 402, // data is process - VREvent_SceneFocusGained = 403, // data is process - VREvent_SceneApplicationChanged = 404, // data is process - The App actually drawing the scene changed (usually to or from the compositor) - VREvent_SceneFocusChanged = 405, // data is process - New app got access to draw the scene - VREvent_InputFocusChanged = 406, // data is process - VREvent_SceneApplicationSecondaryRenderingStarted = 407, // data is process + VREvent_InputFocusCaptured = 400, // data is process DEPRECATED + VREvent_InputFocusReleased = 401, // data is process DEPRECATED + VREvent_SceneFocusLost = 402, // data is process + VREvent_SceneFocusGained = 403, // data is process + VREvent_SceneApplicationChanged = 404, // data is process - The App actually drawing the scene changed (usually to or from the compositor) + VREvent_SceneFocusChanged = 405, // data is process - New app got access to draw the scene + VREvent_InputFocusChanged = 406, // data is process + VREvent_SceneApplicationSecondaryRenderingStarted = 407, // data is process - VREvent_HideRenderModels = 410, // Sent to the scene application to request hiding render models temporarily - VREvent_ShowRenderModels = 411, // Sent to the scene application to request restoring render model visibility + VREvent_HideRenderModels = 410, // Sent to the scene application to request hiding render models temporarily + VREvent_ShowRenderModels = 411, // Sent to the scene application to request restoring render model visibility - VREvent_OverlayShown = 500, - VREvent_OverlayHidden = 501, - VREvent_DashboardActivated = 502, - VREvent_DashboardDeactivated = 503, - VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay - VREvent_DashboardRequested = 505, // Sent to the overlay manager - data is overlay - VREvent_ResetDashboard = 506, // Send to the overlay manager - VREvent_RenderToast = 507, // Send to the dashboard to render a toast - data is the notification ID - VREvent_ImageLoaded = 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading - VREvent_ShowKeyboard = 509, // Sent to keyboard renderer in the dashboard to invoke it - VREvent_HideKeyboard = 510, // Sent to keyboard renderer in the dashboard to hide it - VREvent_OverlayGamepadFocusGained = 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it - VREvent_OverlayGamepadFocusLost = 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else + VREvent_OverlayShown = 500, + VREvent_OverlayHidden = 501, + VREvent_DashboardActivated = 502, + VREvent_DashboardDeactivated = 503, + VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay + VREvent_DashboardRequested = 505, // Sent to the overlay manager - data is overlay + VREvent_ResetDashboard = 506, // Send to the overlay manager + VREvent_RenderToast = 507, // Send to the dashboard to render a toast - data is the notification ID + VREvent_ImageLoaded = 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading + VREvent_ShowKeyboard = 509, // Sent to keyboard renderer in the dashboard to invoke it + VREvent_HideKeyboard = 510, // Sent to keyboard renderer in the dashboard to hide it + VREvent_OverlayGamepadFocusGained = 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it + VREvent_OverlayGamepadFocusLost = 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else VREvent_OverlaySharedTextureChanged = 513, - VREvent_DashboardGuideButtonDown = 514, - VREvent_DashboardGuideButtonUp = 515, - VREvent_ScreenshotTriggered = 516, // Screenshot button combo was pressed, Dashboard should request a screenshot - VREvent_ImageFailed = 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load - VREvent_DashboardOverlayCreated = 518, + VREvent_DashboardGuideButtonDown = 514, + VREvent_DashboardGuideButtonUp = 515, + VREvent_ScreenshotTriggered = 516, // Screenshot button combo was pressed, Dashboard should request a screenshot + VREvent_ImageFailed = 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load + VREvent_DashboardOverlayCreated = 518, // Screenshot API - VREvent_RequestScreenshot = 520, // Sent by vrclient application to compositor to take a screenshot - VREvent_ScreenshotTaken = 521, // Sent by compositor to the application that the screenshot has been taken - VREvent_ScreenshotFailed = 522, // Sent by compositor to the application that the screenshot failed to be taken - VREvent_SubmitScreenshotToDashboard = 523, // Sent by compositor to the dashboard that a completed screenshot was submitted - VREvent_ScreenshotProgressToDashboard = 524, // Sent by compositor to the dashboard that a completed screenshot was submitted + VREvent_RequestScreenshot = 520, // Sent by vrclient application to compositor to take a screenshot + VREvent_ScreenshotTaken = 521, // Sent by compositor to the application that the screenshot has been taken + VREvent_ScreenshotFailed = 522, // Sent by compositor to the application that the screenshot failed to be taken + VREvent_SubmitScreenshotToDashboard = 523, // Sent by compositor to the dashboard that a completed screenshot was submitted + VREvent_ScreenshotProgressToDashboard = 524, // Sent by compositor to the dashboard that a completed screenshot was submitted - VREvent_PrimaryDashboardDeviceChanged = 525, + VREvent_PrimaryDashboardDeviceChanged = 525, - VREvent_Notification_Shown = 600, - VREvent_Notification_Hidden = 601, - VREvent_Notification_BeginInteraction = 602, - VREvent_Notification_Destroyed = 603, + VREvent_Notification_Shown = 600, + VREvent_Notification_Hidden = 601, + VREvent_Notification_BeginInteraction = 602, + VREvent_Notification_Destroyed = 603, - VREvent_Quit = 700, // data is process - VREvent_ProcessQuit = 701, // data is process - VREvent_QuitAborted_UserPrompt = 702, // data is process - VREvent_QuitAcknowledged = 703, // data is process - VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down + VREvent_Quit = 700, // data is process + VREvent_ProcessQuit = 701, // data is process + VREvent_QuitAborted_UserPrompt = 702, // data is process + VREvent_QuitAcknowledged = 703, // data is process + VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down - VREvent_ChaperoneDataHasChanged = 800, - VREvent_ChaperoneUniverseHasChanged = 801, - VREvent_ChaperoneTempDataHasChanged = 802, - VREvent_ChaperoneSettingsHaveChanged = 803, - VREvent_SeatedZeroPoseReset = 804, + VREvent_ChaperoneDataHasChanged = 800, + VREvent_ChaperoneUniverseHasChanged = 801, + VREvent_ChaperoneTempDataHasChanged = 802, + VREvent_ChaperoneSettingsHaveChanged = 803, + VREvent_SeatedZeroPoseReset = 804, - VREvent_AudioSettingsHaveChanged = 820, + VREvent_AudioSettingsHaveChanged = 820, - VREvent_BackgroundSettingHasChanged = 850, - VREvent_CameraSettingsHaveChanged = 851, - VREvent_ReprojectionSettingHasChanged = 852, - VREvent_ModelSkinSettingsHaveChanged = 853, - VREvent_EnvironmentSettingsHaveChanged = 854, - VREvent_PowerSettingsHaveChanged = 855, + VREvent_BackgroundSettingHasChanged = 850, + VREvent_CameraSettingsHaveChanged = 851, + VREvent_ReprojectionSettingHasChanged = 852, + VREvent_ModelSkinSettingsHaveChanged = 853, + VREvent_EnvironmentSettingsHaveChanged = 854, + VREvent_PowerSettingsHaveChanged = 855, VREvent_EnableHomeAppSettingsHaveChanged = 856, - VREvent_StatusUpdate = 900, + VREvent_StatusUpdate = 900, - VREvent_MCImageUpdated = 1000, + VREvent_MCImageUpdated = 1000, - VREvent_FirmwareUpdateStarted = 1100, - VREvent_FirmwareUpdateFinished = 1101, + VREvent_FirmwareUpdateStarted = 1100, + VREvent_FirmwareUpdateFinished = 1101, - VREvent_KeyboardClosed = 1200, - VREvent_KeyboardCharInput = 1201, - VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard + VREvent_KeyboardClosed = 1200, + VREvent_KeyboardCharInput = 1201, + VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard - VREvent_ApplicationTransitionStarted = 1300, - VREvent_ApplicationTransitionAborted = 1301, - VREvent_ApplicationTransitionNewAppStarted = 1302, - VREvent_ApplicationListUpdated = 1303, - VREvent_ApplicationMimeTypeLoad = 1304, + VREvent_ApplicationTransitionStarted = 1300, + VREvent_ApplicationTransitionAborted = 1301, + VREvent_ApplicationTransitionNewAppStarted = 1302, + VREvent_ApplicationListUpdated = 1303, + VREvent_ApplicationMimeTypeLoad = 1304, VREvent_ApplicationTransitionNewAppLaunchComplete = 1305, - VREvent_ProcessConnected = 1306, - VREvent_ProcessDisconnected = 1307, + VREvent_ProcessConnected = 1306, + VREvent_ProcessDisconnected = 1307, - VREvent_Compositor_MirrorWindowShown = 1400, - VREvent_Compositor_MirrorWindowHidden = 1401, - VREvent_Compositor_ChaperoneBoundsShown = 1410, - VREvent_Compositor_ChaperoneBoundsHidden = 1411, + VREvent_Compositor_MirrorWindowShown = 1400, + VREvent_Compositor_MirrorWindowHidden = 1401, + VREvent_Compositor_ChaperoneBoundsShown = 1410, + VREvent_Compositor_ChaperoneBoundsHidden = 1411, - VREvent_TrackedCamera_StartVideoStream = 1500, - VREvent_TrackedCamera_StopVideoStream = 1501, - VREvent_TrackedCamera_PauseVideoStream = 1502, + VREvent_TrackedCamera_StartVideoStream = 1500, + VREvent_TrackedCamera_StopVideoStream = 1501, + VREvent_TrackedCamera_PauseVideoStream = 1502, VREvent_TrackedCamera_ResumeVideoStream = 1503, - VREvent_TrackedCamera_EditingSurface = 1550, + VREvent_TrackedCamera_EditingSurface = 1550, - VREvent_PerformanceTest_EnableCapture = 1600, - VREvent_PerformanceTest_DisableCapture = 1601, - VREvent_PerformanceTest_FidelityLevel = 1602, + VREvent_PerformanceTest_EnableCapture = 1600, + VREvent_PerformanceTest_DisableCapture = 1601, + VREvent_PerformanceTest_FidelityLevel = 1602, + + VREvent_MessageOverlay_Closed = 1650, + VREvent_MessageOverlayCloseRequested = 1651, - VREvent_MessageOverlay_Closed = 1650, - VREvent_MessageOverlayCloseRequested = 1651, - // Vendors are free to expose private events in this reserved region - VREvent_VendorSpecific_Reserved_Start = 10000, - VREvent_VendorSpecific_Reserved_End = 19999, + VREvent_VendorSpecific_Reserved_Start = 10000, + VREvent_VendorSpecific_Reserved_End = 19999, }; - /** Level of Hmd activity */ // UserInteraction_Timeout means the device is in the process of timing out. // InUse = ( k_EDeviceActivityLevel_UserInteraction || k_EDeviceActivityLevel_UserInteraction_Timeout ) // VREvent_TrackedDeviceUserInteractionStarted fires when the devices transitions from Standby -> UserInteraction or Idle -> UserInteraction. // VREvent_TrackedDeviceUserInteractionEnded fires when the devices transitions from UserInteraction_Timeout -> Idle enum EDeviceActivityLevel -{ - k_EDeviceActivityLevel_Unknown = -1, - k_EDeviceActivityLevel_Idle = 0, // No activity for the last 10 seconds - k_EDeviceActivityLevel_UserInteraction = 1, // Activity (movement or prox sensor) is happening now - k_EDeviceActivityLevel_UserInteraction_Timeout = 2, // No activity for the last 0.5 seconds - k_EDeviceActivityLevel_Standby = 3, // Idle for at least 5 seconds (configurable in Settings -> Power Management) +{ + k_EDeviceActivityLevel_Unknown = -1, + k_EDeviceActivityLevel_Idle = 0, // No activity for the last 10 seconds + k_EDeviceActivityLevel_UserInteraction = 1, // Activity (movement or prox sensor) is happening now + k_EDeviceActivityLevel_UserInteraction_Timeout = 2, // No activity for the last 0.5 seconds + k_EDeviceActivityLevel_Standby = 3, // Idle for at least 5 seconds (configurable in Settings -> Power Management) }; - /** VR controller button and axis IDs */ enum EVRButtonId { - k_EButton_System = 0, - k_EButton_ApplicationMenu = 1, - k_EButton_Grip = 2, - k_EButton_DPad_Left = 3, - k_EButton_DPad_Up = 4, - k_EButton_DPad_Right = 5, - k_EButton_DPad_Down = 6, - k_EButton_A = 7, - - k_EButton_ProximitySensor = 31, + k_EButton_System = 0, + k_EButton_ApplicationMenu = 1, + k_EButton_Grip = 2, + k_EButton_DPad_Left = 3, + k_EButton_DPad_Up = 4, + k_EButton_DPad_Right = 5, + k_EButton_DPad_Down = 6, + k_EButton_A = 7, - k_EButton_Axis0 = 32, - k_EButton_Axis1 = 33, - k_EButton_Axis2 = 34, - k_EButton_Axis3 = 35, - k_EButton_Axis4 = 36, + k_EButton_ProximitySensor = 31, + + k_EButton_Axis0 = 32, + k_EButton_Axis1 = 33, + k_EButton_Axis2 = 34, + k_EButton_Axis3 = 35, + k_EButton_Axis4 = 36, // aliases for well known controllers - k_EButton_SteamVR_Touchpad = k_EButton_Axis0, - k_EButton_SteamVR_Trigger = k_EButton_Axis1, + k_EButton_SteamVR_Touchpad = k_EButton_Axis0, + k_EButton_SteamVR_Trigger = k_EButton_Axis1, - k_EButton_Dashboard_Back = k_EButton_Grip, + k_EButton_Dashboard_Back = k_EButton_Grip, - k_EButton_Max = 64 + k_EButton_Max = 64 }; -inline uint64_t ButtonMaskFromId( EVRButtonId id ) { return 1ull << id; } +inline uint64_t ButtonMaskFromId(EVRButtonId id) { return 1ull << id; } /** used for controller button events */ struct VREvent_Controller_t { - uint32_t button; // EVRButtonId enum + uint32_t button; // EVRButtonId enum }; - /** used for simulated mouse events in overlay space */ enum EVRMouseButton { - VRMouseButton_Left = 0x0001, - VRMouseButton_Right = 0x0002, - VRMouseButton_Middle = 0x0004, + VRMouseButton_Left = 0x0001, + VRMouseButton_Right = 0x0002, + VRMouseButton_Middle = 0x0004, }; - /** used for simulated mouse events in overlay space */ struct VREvent_Mouse_t { - float x, y; // co-ords are in GL space, bottom left of the texture is 0,0 - uint32_t button; // EVRMouseButton enum + float x, y; // co-ords are in GL space, bottom left of the texture is 0,0 + uint32_t button; // EVRMouseButton enum }; /** used for simulated mouse wheel scroll in overlay space */ struct VREvent_Scroll_t { - float xdelta, ydelta; // movement in fraction of the pad traversed since last delta, 1.0 for a full swipe + float xdelta, ydelta; // movement in fraction of the pad traversed since last delta, 1.0 for a full swipe uint32_t repeatCount; }; @@ -713,25 +704,23 @@ struct VREvent_Process_t bool bForced; }; - /** Used for a few events about overlays */ struct VREvent_Overlay_t { uint64_t overlayHandle; }; - /** Used for a few events about overlays */ struct VREvent_Status_t { - uint32_t statusState; // EVRState enum + uint32_t statusState; // EVRState enum }; /** Used for keyboard events **/ struct VREvent_Keyboard_t { - char cNewInput[8]; // Up to 11 bytes of new input - uint64_t uUserValue; // Possible flags about the new input + char cNewInput[8]; // Up to 11 bytes of new input + uint64_t uUserValue; // Possible flags about the new input }; struct VREvent_Ipd_t @@ -787,7 +776,7 @@ struct VREvent_EditingCameraSurface_t struct VREvent_MessageOverlay_t { - uint32_t unVRMessageOverlayResponse; // vr::VRMessageOverlayResponse enum + uint32_t unVRMessageOverlayResponse; // vr::VRMessageOverlayResponse enum }; struct VREvent_Property_t @@ -797,8 +786,7 @@ struct VREvent_Property_t }; /** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py */ -typedef union -{ +typedef union { VREvent_Reserved_t reserved; VREvent_Controller_t controller; VREvent_Mouse_t mouse; @@ -821,25 +809,24 @@ typedef union VREvent_Property_t property; } VREvent_Data_t; - -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif /** An event posted by the server to all running applications */ struct VREvent_t { - uint32_t eventType; // EVREventType enum + uint32_t eventType; // EVREventType enum TrackedDeviceIndex_t trackedDeviceIndex; float eventAgeSeconds; // event data must be the end of the struct as its size is variable VREvent_Data_t data; }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif /** The mesh to draw into the stencil (or depth) buffer to perform @@ -854,7 +841,6 @@ struct HiddenAreaMesh_t uint32_t unTriangleCount; }; - enum EHiddenAreaMeshType { k_eHiddenAreaMesh_Standard = 0, @@ -864,7 +850,6 @@ enum EHiddenAreaMeshType k_eHiddenAreaMesh_Max = 3, }; - /** Identifies what kind of axis is on the controller at index n. Read this type * with pVRSystem->Get( nControllerDeviceIndex, Prop_Axis0Type_Int32 + n ); */ @@ -873,32 +858,29 @@ enum EVRControllerAxisType k_eControllerAxis_None = 0, k_eControllerAxis_TrackPad = 1, k_eControllerAxis_Joystick = 2, - k_eControllerAxis_Trigger = 3, // Analog trigger data is in the X axis + k_eControllerAxis_Trigger = 3, // Analog trigger data is in the X axis }; - /** contains information about one axis on the controller */ struct VRControllerAxis_t { - float x; // Ranges from -1.0 to 1.0 for joysticks and track pads. Ranges from 0.0 to 1.0 for triggers were 0 is fully released. - float y; // Ranges from -1.0 to 1.0 for joysticks and track pads. Is always 0.0 for triggers. + float x; // Ranges from -1.0 to 1.0 for joysticks and track pads. Ranges from 0.0 to 1.0 for triggers were 0 is fully released. + float y; // Ranges from -1.0 to 1.0 for joysticks and track pads. Is always 0.0 for triggers. }; - /** the number of axes in the controller state */ static const uint32_t k_unControllerStateAxisCount = 5; - -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif /** Holds all the state of a controller at one moment in time. */ struct VRControllerState001_t { - // If packet num matches that on your prior call, then the controller state hasn't been changed since + // If packet num matches that on your prior call, then the controller state hasn't been changed since // your last call and there is no need to process it uint32_t unPacketNum; @@ -907,16 +889,14 @@ struct VRControllerState001_t uint64_t ulButtonTouched; // Axis data for the controller's analog inputs - VRControllerAxis_t rAxis[ k_unControllerStateAxisCount ]; + VRControllerAxis_t rAxis[k_unControllerStateAxisCount]; }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif - typedef VRControllerState001_t VRControllerState_t; - /** determines how to provide output to the application of various event processing functions. */ enum EVRControllerEventOutputType { @@ -924,8 +904,6 @@ enum EVRControllerEventOutputType ControllerEventOutput_VREvents = 1, }; - - /** Collision Bounds Style */ enum ECollisionBoundsStyle { @@ -941,7 +919,7 @@ enum ECollisionBoundsStyle /** Allows the application to customize how the overlay appears in the compositor */ struct Compositor_OverlaySettings { - uint32_t size; // sizeof(Compositor_OverlaySettings) + uint32_t size; // sizeof(Compositor_OverlaySettings) bool curved, antialias; float scale, distance, alpha; float uOffset, vOffset, uScale, vScale; @@ -957,49 +935,48 @@ static const VROverlayHandle_t k_ulOverlayHandleInvalid = 0; /** Errors that can occur around VR overlays */ enum EVROverlayError { - VROverlayError_None = 0, + VROverlayError_None = 0, - VROverlayError_UnknownOverlay = 10, - VROverlayError_InvalidHandle = 11, - VROverlayError_PermissionDenied = 12, - VROverlayError_OverlayLimitExceeded = 13, // No more overlays could be created because the maximum number already exist - VROverlayError_WrongVisibilityType = 14, - VROverlayError_KeyTooLong = 15, - VROverlayError_NameTooLong = 16, - VROverlayError_KeyInUse = 17, - VROverlayError_WrongTransformType = 18, - VROverlayError_InvalidTrackedDevice = 19, - VROverlayError_InvalidParameter = 20, - VROverlayError_ThumbnailCantBeDestroyed = 21, - VROverlayError_ArrayTooSmall = 22, - VROverlayError_RequestFailed = 23, - VROverlayError_InvalidTexture = 24, - VROverlayError_UnableToLoadFile = 25, - VROverlayError_KeyboardAlreadyInUse = 26, - VROverlayError_NoNeighbor = 27, - VROverlayError_TooManyMaskPrimitives = 29, - VROverlayError_BadMaskPrimitive = 30, + VROverlayError_UnknownOverlay = 10, + VROverlayError_InvalidHandle = 11, + VROverlayError_PermissionDenied = 12, + VROverlayError_OverlayLimitExceeded = 13, // No more overlays could be created because the maximum number already exist + VROverlayError_WrongVisibilityType = 14, + VROverlayError_KeyTooLong = 15, + VROverlayError_NameTooLong = 16, + VROverlayError_KeyInUse = 17, + VROverlayError_WrongTransformType = 18, + VROverlayError_InvalidTrackedDevice = 19, + VROverlayError_InvalidParameter = 20, + VROverlayError_ThumbnailCantBeDestroyed = 21, + VROverlayError_ArrayTooSmall = 22, + VROverlayError_RequestFailed = 23, + VROverlayError_InvalidTexture = 24, + VROverlayError_UnableToLoadFile = 25, + VROverlayError_KeyboardAlreadyInUse = 26, + VROverlayError_NoNeighbor = 27, + VROverlayError_TooManyMaskPrimitives = 29, + VROverlayError_BadMaskPrimitive = 30, }; /** enum values to pass in to VR_Init to identify whether the application will * draw a 3D scene. */ enum EVRApplicationType { - VRApplication_Other = 0, // Some other kind of application that isn't covered by the other entries - VRApplication_Scene = 1, // Application will submit 3D frames - VRApplication_Overlay = 2, // Application only interacts with overlays - VRApplication_Background = 3, // Application should not start SteamVR if it's not already running, and should not - // keep it running if everything else quits. - VRApplication_Utility = 4, // Init should not try to load any drivers. The application needs access to utility - // interfaces (like IVRSettings and IVRApplications) but not hardware. - VRApplication_VRMonitor = 5, // Reserved for vrmonitor - VRApplication_SteamWatchdog = 6,// Reserved for Steam - VRApplication_Bootstrapper = 7, // Start up SteamVR + VRApplication_Other = 0, // Some other kind of application that isn't covered by the other entries + VRApplication_Scene = 1, // Application will submit 3D frames + VRApplication_Overlay = 2, // Application only interacts with overlays + VRApplication_Background = 3, // Application should not start SteamVR if it's not already running, and should not + // keep it running if everything else quits. + VRApplication_Utility = 4, // Init should not try to load any drivers. The application needs access to utility + // interfaces (like IVRSettings and IVRApplications) but not hardware. + VRApplication_VRMonitor = 5, // Reserved for vrmonitor + VRApplication_SteamWatchdog = 6, // Reserved for Steam + VRApplication_Bootstrapper = 7, // Start up SteamVR VRApplication_Max }; - /** error codes for firmware */ enum EVRFirmwareError { @@ -1008,7 +985,6 @@ enum EVRFirmwareError VRFirmwareError_Fail = 2, }; - /** error codes for notifications */ enum EVRNotificationError { @@ -1019,103 +995,101 @@ enum EVRNotificationError VRNotificationError_SystemWithUserValueAlreadyExists = 103, }; - /** error codes returned by Vr_Init */ // Please add adequate error description to https://developer.valvesoftware.com/w/index.php?title=Category:SteamVRHelp enum EVRInitError { - VRInitError_None = 0, + VRInitError_None = 0, VRInitError_Unknown = 1, - VRInitError_Init_InstallationNotFound = 100, - VRInitError_Init_InstallationCorrupt = 101, - VRInitError_Init_VRClientDLLNotFound = 102, - VRInitError_Init_FileNotFound = 103, - VRInitError_Init_FactoryNotFound = 104, - VRInitError_Init_InterfaceNotFound = 105, - VRInitError_Init_InvalidInterface = 106, - VRInitError_Init_UserConfigDirectoryInvalid = 107, - VRInitError_Init_HmdNotFound = 108, - VRInitError_Init_NotInitialized = 109, - VRInitError_Init_PathRegistryNotFound = 110, - VRInitError_Init_NoConfigPath = 111, - VRInitError_Init_NoLogPath = 112, - VRInitError_Init_PathRegistryNotWritable = 113, - VRInitError_Init_AppInfoInitFailed = 114, - VRInitError_Init_Retry = 115, // Used internally to cause retries to vrserver - VRInitError_Init_InitCanceledByUser = 116, // The calling application should silently exit. The user canceled app startup - VRInitError_Init_AnotherAppLaunching = 117, - VRInitError_Init_SettingsInitFailed = 118, - VRInitError_Init_ShuttingDown = 119, - VRInitError_Init_TooManyObjects = 120, - VRInitError_Init_NoServerForBackgroundApp = 121, - VRInitError_Init_NotSupportedWithCompositor = 122, - VRInitError_Init_NotAvailableToUtilityApps = 123, - VRInitError_Init_Internal = 124, - VRInitError_Init_HmdDriverIdIsNone = 125, - VRInitError_Init_HmdNotFoundPresenceFailed = 126, - VRInitError_Init_VRMonitorNotFound = 127, - VRInitError_Init_VRMonitorStartupFailed = 128, - VRInitError_Init_LowPowerWatchdogNotSupported = 129, - VRInitError_Init_InvalidApplicationType = 130, - VRInitError_Init_NotAvailableToWatchdogApps = 131, - VRInitError_Init_WatchdogDisabledInSettings = 132, - VRInitError_Init_VRDashboardNotFound = 133, - VRInitError_Init_VRDashboardStartupFailed = 134, - VRInitError_Init_VRHomeNotFound = 135, - VRInitError_Init_VRHomeStartupFailed = 136, - VRInitError_Init_RebootingBusy = 137, - VRInitError_Init_FirmwareUpdateBusy = 138, - VRInitError_Init_FirmwareRecoveryBusy = 139, + VRInitError_Init_InstallationNotFound = 100, + VRInitError_Init_InstallationCorrupt = 101, + VRInitError_Init_VRClientDLLNotFound = 102, + VRInitError_Init_FileNotFound = 103, + VRInitError_Init_FactoryNotFound = 104, + VRInitError_Init_InterfaceNotFound = 105, + VRInitError_Init_InvalidInterface = 106, + VRInitError_Init_UserConfigDirectoryInvalid = 107, + VRInitError_Init_HmdNotFound = 108, + VRInitError_Init_NotInitialized = 109, + VRInitError_Init_PathRegistryNotFound = 110, + VRInitError_Init_NoConfigPath = 111, + VRInitError_Init_NoLogPath = 112, + VRInitError_Init_PathRegistryNotWritable = 113, + VRInitError_Init_AppInfoInitFailed = 114, + VRInitError_Init_Retry = 115, // Used internally to cause retries to vrserver + VRInitError_Init_InitCanceledByUser = 116, // The calling application should silently exit. The user canceled app startup + VRInitError_Init_AnotherAppLaunching = 117, + VRInitError_Init_SettingsInitFailed = 118, + VRInitError_Init_ShuttingDown = 119, + VRInitError_Init_TooManyObjects = 120, + VRInitError_Init_NoServerForBackgroundApp = 121, + VRInitError_Init_NotSupportedWithCompositor = 122, + VRInitError_Init_NotAvailableToUtilityApps = 123, + VRInitError_Init_Internal = 124, + VRInitError_Init_HmdDriverIdIsNone = 125, + VRInitError_Init_HmdNotFoundPresenceFailed = 126, + VRInitError_Init_VRMonitorNotFound = 127, + VRInitError_Init_VRMonitorStartupFailed = 128, + VRInitError_Init_LowPowerWatchdogNotSupported = 129, + VRInitError_Init_InvalidApplicationType = 130, + VRInitError_Init_NotAvailableToWatchdogApps = 131, + VRInitError_Init_WatchdogDisabledInSettings = 132, + VRInitError_Init_VRDashboardNotFound = 133, + VRInitError_Init_VRDashboardStartupFailed = 134, + VRInitError_Init_VRHomeNotFound = 135, + VRInitError_Init_VRHomeStartupFailed = 136, + VRInitError_Init_RebootingBusy = 137, + VRInitError_Init_FirmwareUpdateBusy = 138, + VRInitError_Init_FirmwareRecoveryBusy = 139, - - VRInitError_Driver_Failed = 200, - VRInitError_Driver_Unknown = 201, - VRInitError_Driver_HmdUnknown = 202, - VRInitError_Driver_NotLoaded = 203, - VRInitError_Driver_RuntimeOutOfDate = 204, - VRInitError_Driver_HmdInUse = 205, - VRInitError_Driver_NotCalibrated = 206, - VRInitError_Driver_CalibrationInvalid = 207, - VRInitError_Driver_HmdDisplayNotFound = 208, + VRInitError_Driver_Failed = 200, + VRInitError_Driver_Unknown = 201, + VRInitError_Driver_HmdUnknown = 202, + VRInitError_Driver_NotLoaded = 203, + VRInitError_Driver_RuntimeOutOfDate = 204, + VRInitError_Driver_HmdInUse = 205, + VRInitError_Driver_NotCalibrated = 206, + VRInitError_Driver_CalibrationInvalid = 207, + VRInitError_Driver_HmdDisplayNotFound = 208, VRInitError_Driver_TrackedDeviceInterfaceUnknown = 209, // VRInitError_Driver_HmdDisplayNotFoundAfterFix = 210, // not needed: here for historic reasons - VRInitError_Driver_HmdDriverIdOutOfBounds = 211, - VRInitError_Driver_HmdDisplayMirrored = 212, + VRInitError_Driver_HmdDriverIdOutOfBounds = 211, + VRInitError_Driver_HmdDisplayMirrored = 212, - VRInitError_IPC_ServerInitFailed = 300, - VRInitError_IPC_ConnectFailed = 301, - VRInitError_IPC_SharedStateInitFailed = 302, - VRInitError_IPC_CompositorInitFailed = 303, - VRInitError_IPC_MutexInitFailed = 304, - VRInitError_IPC_Failed = 305, - VRInitError_IPC_CompositorConnectFailed = 306, + VRInitError_IPC_ServerInitFailed = 300, + VRInitError_IPC_ConnectFailed = 301, + VRInitError_IPC_SharedStateInitFailed = 302, + VRInitError_IPC_CompositorInitFailed = 303, + VRInitError_IPC_MutexInitFailed = 304, + VRInitError_IPC_Failed = 305, + VRInitError_IPC_CompositorConnectFailed = 306, VRInitError_IPC_CompositorInvalidConnectResponse = 307, VRInitError_IPC_ConnectFailedAfterMultipleAttempts = 308, - VRInitError_Compositor_Failed = 400, - VRInitError_Compositor_D3D11HardwareRequired = 401, - VRInitError_Compositor_FirmwareRequiresUpdate = 402, - VRInitError_Compositor_OverlayInitFailed = 403, - VRInitError_Compositor_ScreenshotsInitFailed = 404, - VRInitError_Compositor_UnableToCreateDevice = 405, + VRInitError_Compositor_Failed = 400, + VRInitError_Compositor_D3D11HardwareRequired = 401, + VRInitError_Compositor_FirmwareRequiresUpdate = 402, + VRInitError_Compositor_OverlayInitFailed = 403, + VRInitError_Compositor_ScreenshotsInitFailed = 404, + VRInitError_Compositor_UnableToCreateDevice = 405, - VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000, + VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000, - VRInitError_VendorSpecific_HmdFound_CantOpenDevice = 1101, - VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102, - VRInitError_VendorSpecific_HmdFound_NoStoredConfig = 1103, - VRInitError_VendorSpecific_HmdFound_ConfigTooBig = 1104, - VRInitError_VendorSpecific_HmdFound_ConfigTooSmall = 1105, - VRInitError_VendorSpecific_HmdFound_UnableToInitZLib = 1106, - VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion = 1107, - VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart = 1108, - VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart = 1109, - VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext = 1110, - VRInitError_VendorSpecific_HmdFound_UserDataAddressRange = 1111, - VRInitError_VendorSpecific_HmdFound_UserDataError = 1112, - VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck = 1113, + VRInitError_VendorSpecific_HmdFound_CantOpenDevice = 1101, + VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102, + VRInitError_VendorSpecific_HmdFound_NoStoredConfig = 1103, + VRInitError_VendorSpecific_HmdFound_ConfigTooBig = 1104, + VRInitError_VendorSpecific_HmdFound_ConfigTooSmall = 1105, + VRInitError_VendorSpecific_HmdFound_UnableToInitZLib = 1106, + VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion = 1107, + VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart = 1108, + VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart = 1109, + VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext = 1110, + VRInitError_VendorSpecific_HmdFound_UserDataAddressRange = 1111, + VRInitError_VendorSpecific_HmdFound_UserDataError = 1112, + VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck = 1113, VRInitError_Steam_SteamInstallationNotFound = 2000, }; @@ -1123,7 +1097,7 @@ enum EVRInitError enum EVRScreenshotType { VRScreenshotType_None = 0, - VRScreenshotType_Mono = 1, // left eye only + VRScreenshotType_Mono = 1, // left eye only VRScreenshotType_Stereo = 2, VRScreenshotType_Cubemap = 3, VRScreenshotType_MonoPanorama = 4, @@ -1138,35 +1112,35 @@ enum EVRScreenshotPropertyFilenames enum EVRTrackedCameraError { - VRTrackedCameraError_None = 0, - VRTrackedCameraError_OperationFailed = 100, - VRTrackedCameraError_InvalidHandle = 101, - VRTrackedCameraError_InvalidFrameHeaderVersion = 102, - VRTrackedCameraError_OutOfHandles = 103, - VRTrackedCameraError_IPCFailure = 104, - VRTrackedCameraError_NotSupportedForThisDevice = 105, - VRTrackedCameraError_SharedMemoryFailure = 106, - VRTrackedCameraError_FrameBufferingFailure = 107, - VRTrackedCameraError_StreamSetupFailure = 108, - VRTrackedCameraError_InvalidGLTextureId = 109, + VRTrackedCameraError_None = 0, + VRTrackedCameraError_OperationFailed = 100, + VRTrackedCameraError_InvalidHandle = 101, + VRTrackedCameraError_InvalidFrameHeaderVersion = 102, + VRTrackedCameraError_OutOfHandles = 103, + VRTrackedCameraError_IPCFailure = 104, + VRTrackedCameraError_NotSupportedForThisDevice = 105, + VRTrackedCameraError_SharedMemoryFailure = 106, + VRTrackedCameraError_FrameBufferingFailure = 107, + VRTrackedCameraError_StreamSetupFailure = 108, + VRTrackedCameraError_InvalidGLTextureId = 109, VRTrackedCameraError_InvalidSharedTextureHandle = 110, - VRTrackedCameraError_FailedToGetGLTextureId = 111, - VRTrackedCameraError_SharedTextureFailure = 112, - VRTrackedCameraError_NoFrameAvailable = 113, - VRTrackedCameraError_InvalidArgument = 114, - VRTrackedCameraError_InvalidFrameBufferSize = 115, + VRTrackedCameraError_FailedToGetGLTextureId = 111, + VRTrackedCameraError_SharedTextureFailure = 112, + VRTrackedCameraError_NoFrameAvailable = 113, + VRTrackedCameraError_InvalidArgument = 114, + VRTrackedCameraError_InvalidFrameBufferSize = 115, }; enum EVRTrackedCameraFrameType { - VRTrackedCameraFrameType_Distorted = 0, // This is the camera video frame size in pixels, still distorted. - VRTrackedCameraFrameType_Undistorted, // In pixels, an undistorted inscribed rectangle region without invalid regions. This size is subject to changes shortly. - VRTrackedCameraFrameType_MaximumUndistorted, // In pixels, maximum undistorted with invalid regions. Non zero alpha component identifies valid regions. + VRTrackedCameraFrameType_Distorted = 0, // This is the camera video frame size in pixels, still distorted. + VRTrackedCameraFrameType_Undistorted, // In pixels, an undistorted inscribed rectangle region without invalid regions. This size is subject to changes shortly. + VRTrackedCameraFrameType_MaximumUndistorted, // In pixels, maximum undistorted with invalid regions. Non zero alpha component identifies valid regions. MAX_CAMERA_FRAME_TYPES }; typedef uint64_t TrackedCameraHandle_t; -#define INVALID_TRACKED_CAMERA_HANDLE ((vr::TrackedCameraHandle_t)0) +#define INVALID_TRACKED_CAMERA_HANDLE ((vr::TrackedCameraHandle_t)0) struct CameraVideoStreamFrameHeader_t { @@ -1186,15 +1160,15 @@ typedef uint32_t ScreenshotHandle_t; static const uint32_t k_unScreenshotHandleInvalid = 0; -#pragma pack( pop ) +#pragma pack(pop) // figure out how to import from the VR API dll #if defined(_WIN32) #ifdef VR_API_EXPORT -#define VR_INTERFACE extern "C" __declspec( dllexport ) +#define VR_INTERFACE extern "C" __declspec(dllexport) #else -#define VR_INTERFACE extern "C" __declspec( dllimport ) +#define VR_INTERFACE extern "C" __declspec(dllimport) #endif #elif defined(__GNUC__) || defined(COMPILER_GCC) || defined(__APPLE__) @@ -1202,83 +1176,78 @@ static const uint32_t k_unScreenshotHandleInvalid = 0; #ifdef VR_API_EXPORT #define VR_INTERFACE extern "C" __attribute__((visibility("default"))) #else -#define VR_INTERFACE extern "C" +#define VR_INTERFACE extern "C" #endif #else #error "Unsupported Platform." #endif - -#if defined( _WIN32 ) +#if defined(_WIN32) #define VR_CALLTYPE __cdecl #else -#define VR_CALLTYPE +#define VR_CALLTYPE #endif -} // namespace vr - -#endif // _INCLUDE_VRTYPES_H +} // namespace vr +#endif // _INCLUDE_VRTYPES_H // vrannotation.h #ifdef API_GEN -# define VR_CLANG_ATTR(ATTR) __attribute__((annotate( ATTR ))) +#define VR_CLANG_ATTR(ATTR) __attribute__((annotate(ATTR))) #else -# define VR_CLANG_ATTR(ATTR) +#define VR_CLANG_ATTR(ATTR) #endif -#define VR_METHOD_DESC(DESC) VR_CLANG_ATTR( "desc:" #DESC ";" ) -#define VR_IGNOREATTR() VR_CLANG_ATTR( "ignore" ) -#define VR_OUT_STRUCT() VR_CLANG_ATTR( "out_struct: ;" ) -#define VR_OUT_STRING() VR_CLANG_ATTR( "out_string: ;" ) -#define VR_OUT_ARRAY_CALL(COUNTER,FUNCTION,PARAMS) VR_CLANG_ATTR( "out_array_call:" #COUNTER "," #FUNCTION "," #PARAMS ";" ) -#define VR_OUT_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR( "out_array_count:" #COUNTER ";" ) -#define VR_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR( "array_count:" #COUNTER ";" ) -#define VR_ARRAY_COUNT_D(COUNTER, DESC) VR_CLANG_ATTR( "array_count:" #COUNTER ";desc:" #DESC ) -#define VR_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR( "buffer_count:" #COUNTER ";" ) -#define VR_OUT_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR( "out_buffer_count:" #COUNTER ";" ) -#define VR_OUT_STRING_COUNT(COUNTER) VR_CLANG_ATTR( "out_string_count:" #COUNTER ";" ) +#define VR_METHOD_DESC(DESC) VR_CLANG_ATTR("desc:" #DESC ";") +#define VR_IGNOREATTR() VR_CLANG_ATTR("ignore") +#define VR_OUT_STRUCT() VR_CLANG_ATTR("out_struct: ;") +#define VR_OUT_STRING() VR_CLANG_ATTR("out_string: ;") +#define VR_OUT_ARRAY_CALL(COUNTER, FUNCTION, PARAMS) VR_CLANG_ATTR("out_array_call:" #COUNTER "," #FUNCTION "," #PARAMS ";") +#define VR_OUT_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR("out_array_count:" #COUNTER ";") +#define VR_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR("array_count:" #COUNTER ";") +#define VR_ARRAY_COUNT_D(COUNTER, DESC) VR_CLANG_ATTR("array_count:" #COUNTER ";desc:" #DESC) +#define VR_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR("buffer_count:" #COUNTER ";") +#define VR_OUT_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR("out_buffer_count:" #COUNTER ";") +#define VR_OUT_STRING_COUNT(COUNTER) VR_CLANG_ATTR("out_string_count:" #COUNTER ";") // ivrsystem.h namespace vr { - class IVRSystem { public: - - // ------------------------------------ // Display Methods // ------------------------------------ /** Suggested size for the intermediate render target that the distortion pulls from. */ - virtual void GetRecommendedRenderTargetSize( uint32_t *pnWidth, uint32_t *pnHeight ) = 0; + virtual void GetRecommendedRenderTargetSize(uint32_t *pnWidth, uint32_t *pnHeight) = 0; /** The projection matrix for the specified eye */ - virtual HmdMatrix44_t GetProjectionMatrix( EVREye eEye, float fNearZ, float fFarZ ) = 0; + virtual HmdMatrix44_t GetProjectionMatrix(EVREye eEye, float fNearZ, float fFarZ) = 0; /** The components necessary to build your own projection matrix in case your * application is doing something fancy like infinite Z */ - virtual void GetProjectionRaw( EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom ) = 0; + virtual void GetProjectionRaw(EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom) = 0; /** Gets the result of the distortion function for the specified eye and input UVs. UVs go from 0,0 in * the upper left of that eye's viewport and 1,1 in the lower right of that eye's viewport. * Returns true for success. Otherwise, returns false, and distortion coordinates are not suitable. */ - virtual bool ComputeDistortion( EVREye eEye, float fU, float fV, DistortionCoordinates_t *pDistortionCoordinates ) = 0; + virtual bool ComputeDistortion(EVREye eEye, float fU, float fV, DistortionCoordinates_t *pDistortionCoordinates) = 0; /** Returns the transform from eye space to the head space. Eye space is the per-eye flavor of head * space that provides stereo disparity. Instead of Model * View * Projection the sequence is Model * View * Eye^-1 * Projection. * Normally View and Eye^-1 will be multiplied together and treated as View in your application. */ - virtual HmdMatrix34_t GetEyeToHeadTransform( EVREye eEye ) = 0; + virtual HmdMatrix34_t GetEyeToHeadTransform(EVREye eEye) = 0; /** Returns the number of elapsed seconds since the last recorded vsync event. This * will come from a vsync timer event in the timer if possible or from the application-reported * time if that is not available. If no vsync times are available the function will * return zero for vsync time and frame counter and return false from the method. */ - virtual bool GetTimeSinceLastVsync( float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter ) = 0; + virtual bool GetTimeSinceLastVsync(float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter) = 0; /** [D3D9 Only] * Returns the adapter index that the user should pass into CreateDevice to set up D3D9 in such @@ -1290,8 +1259,8 @@ public: * Returns the adapter index that the user should pass into EnumAdapters to create the device * and swap chain in DX10 and DX11. If an error occurs the index will be set to -1. */ - virtual void GetDXGIOutputInfo( int32_t *pnAdapterIndex ) = 0; - + virtual void GetDXGIOutputInfo(int32_t *pnAdapterIndex) = 0; + /** * Returns platform- and texture-type specific adapter identification so that applications and the * compositor are creating textures and swap chains on the same GPU. If an error occurs the device @@ -1309,7 +1278,7 @@ public: * [macOS Only] * Returns an id that should be used by the application. */ - virtual void GetOutputDevice( uint64_t *pnDevice, ETextureType textureType, VkInstance_T *pInstance = nullptr ) = 0; + virtual void GetOutputDevice(uint64_t *pnDevice, ETextureType textureType, VkInstance_T *pInstance = nullptr) = 0; // ------------------------------------ // Display Mode methods @@ -1319,7 +1288,7 @@ public: virtual bool IsDisplayOnDesktop() = 0; /** Set the display visibility (true = extended, false = direct mode). Return value of true indicates that the change was successful. */ - virtual bool SetDisplayVisibility( bool bIsVisibleOnDesktop ) = 0; + virtual bool SetDisplayVisibility(bool bIsVisibleOnDesktop) = 0; // ------------------------------------ // Tracking Methods @@ -1342,7 +1311,7 @@ public: * probably not be used unless the application is the Chaperone calibration tool itself, but will provide * poses relative to the hardware-specific coordinate system in the driver. */ - virtual void GetDeviceToAbsoluteTrackingPose( ETrackingUniverseOrigin eOrigin, float fPredictedSecondsToPhotonsFromNow, VR_ARRAY_COUNT(unTrackedDevicePoseArrayCount) TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount ) = 0; + virtual void GetDeviceToAbsoluteTrackingPose(ETrackingUniverseOrigin eOrigin, float fPredictedSecondsToPhotonsFromNow, VR_ARRAY_COUNT(unTrackedDevicePoseArrayCount) TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount) = 0; /** Sets the zero pose for the seated tracker coordinate system to the current position and yaw of the HMD. After * ResetSeatedZeroPose all GetDeviceToAbsoluteTrackingPose calls that pass TrackingUniverseSeated as the origin @@ -1370,21 +1339,21 @@ public: /** Get a sorted array of device indices of a given class of tracked devices (e.g. controllers). Devices are sorted right to left * relative to the specified tracked device (default: hmd -- pass in -1 for absolute tracking space). Returns the number of devices * in the list, or the size of the array needed if not large enough. */ - virtual uint32_t GetSortedTrackedDeviceIndicesOfClass( ETrackedDeviceClass eTrackedDeviceClass, VR_ARRAY_COUNT(unTrackedDeviceIndexArrayCount) vr::TrackedDeviceIndex_t *punTrackedDeviceIndexArray, uint32_t unTrackedDeviceIndexArrayCount, vr::TrackedDeviceIndex_t unRelativeToTrackedDeviceIndex = k_unTrackedDeviceIndex_Hmd ) = 0; + virtual uint32_t GetSortedTrackedDeviceIndicesOfClass(ETrackedDeviceClass eTrackedDeviceClass, VR_ARRAY_COUNT(unTrackedDeviceIndexArrayCount) vr::TrackedDeviceIndex_t *punTrackedDeviceIndexArray, uint32_t unTrackedDeviceIndexArrayCount, vr::TrackedDeviceIndex_t unRelativeToTrackedDeviceIndex = k_unTrackedDeviceIndex_Hmd) = 0; /** Returns the level of activity on the device. */ - virtual EDeviceActivityLevel GetTrackedDeviceActivityLevel( vr::TrackedDeviceIndex_t unDeviceId ) = 0; + virtual EDeviceActivityLevel GetTrackedDeviceActivityLevel(vr::TrackedDeviceIndex_t unDeviceId) = 0; /** Convenience utility to apply the specified transform to the specified pose. * This properly transforms all pose components, including velocity and angular velocity */ - virtual void ApplyTransform( TrackedDevicePose_t *pOutputPose, const TrackedDevicePose_t *pTrackedDevicePose, const HmdMatrix34_t *pTransform ) = 0; + virtual void ApplyTransform(TrackedDevicePose_t *pOutputPose, const TrackedDevicePose_t *pTrackedDevicePose, const HmdMatrix34_t *pTransform) = 0; /** Returns the device index associated with a specific role, for example the left hand or the right hand. */ - virtual vr::TrackedDeviceIndex_t GetTrackedDeviceIndexForControllerRole( vr::ETrackedControllerRole unDeviceType ) = 0; + virtual vr::TrackedDeviceIndex_t GetTrackedDeviceIndexForControllerRole(vr::ETrackedControllerRole unDeviceType) = 0; /** Returns the controller type associated with a device index. */ - virtual vr::ETrackedControllerRole GetControllerRoleForTrackedDeviceIndex( vr::TrackedDeviceIndex_t unDeviceIndex ) = 0; + virtual vr::ETrackedControllerRole GetControllerRoleForTrackedDeviceIndex(vr::TrackedDeviceIndex_t unDeviceIndex) = 0; // ------------------------------------ // Property methods @@ -1397,34 +1366,34 @@ public: * To determine which devices exist on the system, just loop from 0 to k_unMaxTrackedDeviceCount and check * the device class. Every device with something other than TrackedDevice_Invalid is associated with an * actual tracked device. */ - virtual ETrackedDeviceClass GetTrackedDeviceClass( vr::TrackedDeviceIndex_t unDeviceIndex ) = 0; + virtual ETrackedDeviceClass GetTrackedDeviceClass(vr::TrackedDeviceIndex_t unDeviceIndex) = 0; /** Returns true if there is a device connected in this slot. */ - virtual bool IsTrackedDeviceConnected( vr::TrackedDeviceIndex_t unDeviceIndex ) = 0; + virtual bool IsTrackedDeviceConnected(vr::TrackedDeviceIndex_t unDeviceIndex) = 0; /** Returns a bool property. If the device index is not valid or the property is not a bool type this function will return false. */ - virtual bool GetBoolTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + virtual bool GetBoolTrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L) = 0; /** Returns a float property. If the device index is not valid or the property is not a float type this function will return 0. */ - virtual float GetFloatTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + virtual float GetFloatTrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L) = 0; /** Returns an int property. If the device index is not valid or the property is not a int type this function will return 0. */ - virtual int32_t GetInt32TrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + virtual int32_t GetInt32TrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L) = 0; /** Returns a uint64 property. If the device index is not valid or the property is not a uint64 type this function will return 0. */ - virtual uint64_t GetUint64TrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + virtual uint64_t GetUint64TrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L) = 0; /** Returns a matrix property. If the device index is not valid or the property is not a matrix type, this function will return identity. */ - virtual HmdMatrix34_t GetMatrix34TrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + virtual HmdMatrix34_t GetMatrix34TrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L) = 0; /** Returns a string property. If the device index is not valid or the property is not a string type this function will * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */ - virtual uint32_t GetStringTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L ) = 0; + virtual uint32_t GetStringTrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L) = 0; /** returns a string that corresponds with the specified property error. The string will be the name * of the error enum value for all valid error codes */ - virtual const char *GetPropErrorNameFromEnum( ETrackedPropertyError error ) = 0; + virtual const char *GetPropErrorNameFromEnum(ETrackedPropertyError error) = 0; // ------------------------------------ // Event methods @@ -1432,16 +1401,16 @@ public: /** Returns true and fills the event with the next event on the queue if there is one. If there are no events * this method returns false. uncbVREvent should be the size in bytes of the VREvent_t struct */ - virtual bool PollNextEvent( VREvent_t *pEvent, uint32_t uncbVREvent ) = 0; + virtual bool PollNextEvent(VREvent_t *pEvent, uint32_t uncbVREvent) = 0; /** Returns true and fills the event with the next event on the queue if there is one. If there are no events * this method returns false. Fills in the pose of the associated tracked device in the provided pose struct. * This pose will always be older than the call to this function and should not be used to render the device. uncbVREvent should be the size in bytes of the VREvent_t struct */ - virtual bool PollNextEventWithPose( ETrackingUniverseOrigin eOrigin, VREvent_t *pEvent, uint32_t uncbVREvent, vr::TrackedDevicePose_t *pTrackedDevicePose ) = 0; + virtual bool PollNextEventWithPose(ETrackingUniverseOrigin eOrigin, VREvent_t *pEvent, uint32_t uncbVREvent, vr::TrackedDevicePose_t *pTrackedDevicePose) = 0; /** returns the name of an EVREvent enum value */ - virtual const char *GetEventTypeNameFromEnum( EVREventType eType ) = 0; + virtual const char *GetEventTypeNameFromEnum(EVREventType eType) = 0; // ------------------------------------ // Rendering helper methods @@ -1455,7 +1424,7 @@ public: * Setting the bInverse argument to true will produce the visible area mesh that is commonly used in place of full-screen quads. The visible area mesh covers all of the pixels the hidden area mesh does not cover. * Setting the bLineLoop argument will return a line loop of vertices in HiddenAreaMesh_t->pVertexData with HiddenAreaMesh_t->unTriangleCount set to the number of vertices. */ - virtual HiddenAreaMesh_t GetHiddenAreaMesh( EVREye eEye, EHiddenAreaMeshType type = k_eHiddenAreaMesh_Standard ) = 0; + virtual HiddenAreaMesh_t GetHiddenAreaMesh(EVREye eEye, EHiddenAreaMeshType type = k_eHiddenAreaMesh_Standard) = 0; // ------------------------------------ // Controller methods @@ -1463,22 +1432,22 @@ public: /** Fills the supplied struct with the current state of the controller. Returns false if the controller index * is invalid. */ - virtual bool GetControllerState( vr::TrackedDeviceIndex_t unControllerDeviceIndex, vr::VRControllerState_t *pControllerState, uint32_t unControllerStateSize ) = 0; + virtual bool GetControllerState(vr::TrackedDeviceIndex_t unControllerDeviceIndex, vr::VRControllerState_t *pControllerState, uint32_t unControllerStateSize) = 0; /** fills the supplied struct with the current state of the controller and the provided pose with the pose of * the controller when the controller state was updated most recently. Use this form if you need a precise controller * pose as input to your application when the user presses or releases a button. */ - virtual bool GetControllerStateWithPose( ETrackingUniverseOrigin eOrigin, vr::TrackedDeviceIndex_t unControllerDeviceIndex, vr::VRControllerState_t *pControllerState, uint32_t unControllerStateSize, TrackedDevicePose_t *pTrackedDevicePose ) = 0; + virtual bool GetControllerStateWithPose(ETrackingUniverseOrigin eOrigin, vr::TrackedDeviceIndex_t unControllerDeviceIndex, vr::VRControllerState_t *pControllerState, uint32_t unControllerStateSize, TrackedDevicePose_t *pTrackedDevicePose) = 0; /** Trigger a single haptic pulse on a controller. After this call the application may not trigger another haptic pulse on this controller * and axis combination for 5ms. */ - virtual void TriggerHapticPulse( vr::TrackedDeviceIndex_t unControllerDeviceIndex, uint32_t unAxisId, unsigned short usDurationMicroSec ) = 0; + virtual void TriggerHapticPulse(vr::TrackedDeviceIndex_t unControllerDeviceIndex, uint32_t unAxisId, unsigned short usDurationMicroSec) = 0; /** returns the name of an EVRButtonId enum value */ - virtual const char *GetButtonIdNameFromEnum( EVRButtonId eButtonId ) = 0; + virtual const char *GetButtonIdNameFromEnum(EVRButtonId eButtonId) = 0; /** returns the name of an EVRControllerAxisType enum value */ - virtual const char *GetControllerAxisTypeNameFromEnum( EVRControllerAxisType eAxisType ) = 0; + virtual const char *GetControllerAxisTypeNameFromEnum(EVRControllerAxisType eAxisType) = 0; /** Tells OpenVR that this process wants exclusive access to controller button states and button events. Other apps will be notified that * they have lost input focus with a VREvent_InputFocusCaptured event. Returns false if input focus could not be captured for @@ -1499,18 +1468,18 @@ public: /** Sends a request to the driver for the specified device and returns the response. The maximum response size is 32k, * but this method can be called with a smaller buffer. If the response exceeds the size of the buffer, it is truncated. * The size of the response including its terminating null is returned. */ - virtual uint32_t DriverDebugRequest( vr::TrackedDeviceIndex_t unDeviceIndex, const char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize ) = 0; + virtual uint32_t DriverDebugRequest(vr::TrackedDeviceIndex_t unDeviceIndex, const char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize) = 0; // ------------------------------------ // Firmware methods // ------------------------------------ - + /** Performs the actual firmware update if applicable. * The following events will be sent, if VRFirmwareError_None was returned: VREvent_FirmwareUpdateStarted, VREvent_FirmwareUpdateFinished * Use the properties Prop_Firmware_UpdateAvailable_Bool, Prop_Firmware_ManualUpdate_Bool, and Prop_Firmware_ManualUpdateURL_String * to figure our whether a firmware update is available, and to figure out whether its a manual update * Prop_Firmware_ManualUpdateURL_String should point to an URL describing the manual update process */ - virtual vr::EVRFirmwareError PerformFirmwareUpdate( vr::TrackedDeviceIndex_t unDeviceIndex ) = 0; + virtual vr::EVRFirmwareError PerformFirmwareUpdate(vr::TrackedDeviceIndex_t unDeviceIndex) = 0; // ------------------------------------ // Application life cycle methods @@ -1524,195 +1493,191 @@ public: * halts the timeout and dismisses the dashboard (if it was up). Applications should be sure to actually * prompt the user to save and then exit afterward, otherwise the user will be left in a confusing state. */ virtual void AcknowledgeQuit_UserPrompt() = 0; - }; -static const char * const IVRSystem_Version = "IVRSystem_017"; - -} +static const char *const IVRSystem_Version = "IVRSystem_017"; +} // namespace vr // ivrapplications.h namespace vr { +/** Used for all errors reported by the IVRApplications interface */ +enum EVRApplicationError +{ + VRApplicationError_None = 0, - /** Used for all errors reported by the IVRApplications interface */ - enum EVRApplicationError - { - VRApplicationError_None = 0, + VRApplicationError_AppKeyAlreadyExists = 100, // Only one application can use any given key + VRApplicationError_NoManifest = 101, // the running application does not have a manifest + VRApplicationError_NoApplication = 102, // No application is running + VRApplicationError_InvalidIndex = 103, + VRApplicationError_UnknownApplication = 104, // the application could not be found + VRApplicationError_IPCFailed = 105, // An IPC failure caused the request to fail + VRApplicationError_ApplicationAlreadyRunning = 106, + VRApplicationError_InvalidManifest = 107, + VRApplicationError_InvalidApplication = 108, + VRApplicationError_LaunchFailed = 109, // the process didn't start + VRApplicationError_ApplicationAlreadyStarting = 110, // the system was already starting the same application + VRApplicationError_LaunchInProgress = 111, // The system was already starting a different application + VRApplicationError_OldApplicationQuitting = 112, + VRApplicationError_TransitionAborted = 113, + VRApplicationError_IsTemplate = 114, // error when you try to call LaunchApplication() on a template type app (use LaunchTemplateApplication) + VRApplicationError_SteamVRIsExiting = 115, - VRApplicationError_AppKeyAlreadyExists = 100, // Only one application can use any given key - VRApplicationError_NoManifest = 101, // the running application does not have a manifest - VRApplicationError_NoApplication = 102, // No application is running - VRApplicationError_InvalidIndex = 103, - VRApplicationError_UnknownApplication = 104, // the application could not be found - VRApplicationError_IPCFailed = 105, // An IPC failure caused the request to fail - VRApplicationError_ApplicationAlreadyRunning = 106, - VRApplicationError_InvalidManifest = 107, - VRApplicationError_InvalidApplication = 108, - VRApplicationError_LaunchFailed = 109, // the process didn't start - VRApplicationError_ApplicationAlreadyStarting = 110, // the system was already starting the same application - VRApplicationError_LaunchInProgress = 111, // The system was already starting a different application - VRApplicationError_OldApplicationQuitting = 112, - VRApplicationError_TransitionAborted = 113, - VRApplicationError_IsTemplate = 114, // error when you try to call LaunchApplication() on a template type app (use LaunchTemplateApplication) - VRApplicationError_SteamVRIsExiting = 115, + VRApplicationError_BufferTooSmall = 200, // The provided buffer was too small to fit the requested data + VRApplicationError_PropertyNotSet = 201, // The requested property was not set + VRApplicationError_UnknownProperty = 202, + VRApplicationError_InvalidParameter = 203, +}; - VRApplicationError_BufferTooSmall = 200, // The provided buffer was too small to fit the requested data - VRApplicationError_PropertyNotSet = 201, // The requested property was not set - VRApplicationError_UnknownProperty = 202, - VRApplicationError_InvalidParameter = 203, - }; +/** The maximum length of an application key */ +static const uint32_t k_unMaxApplicationKeyLength = 128; - /** The maximum length of an application key */ - static const uint32_t k_unMaxApplicationKeyLength = 128; +/** these are the properties available on applications. */ +enum EVRApplicationProperty +{ + VRApplicationProperty_Name_String = 0, - /** these are the properties available on applications. */ - enum EVRApplicationProperty - { - VRApplicationProperty_Name_String = 0, + VRApplicationProperty_LaunchType_String = 11, + VRApplicationProperty_WorkingDirectory_String = 12, + VRApplicationProperty_BinaryPath_String = 13, + VRApplicationProperty_Arguments_String = 14, + VRApplicationProperty_URL_String = 15, - VRApplicationProperty_LaunchType_String = 11, - VRApplicationProperty_WorkingDirectory_String = 12, - VRApplicationProperty_BinaryPath_String = 13, - VRApplicationProperty_Arguments_String = 14, - VRApplicationProperty_URL_String = 15, + VRApplicationProperty_Description_String = 50, + VRApplicationProperty_NewsURL_String = 51, + VRApplicationProperty_ImagePath_String = 52, + VRApplicationProperty_Source_String = 53, - VRApplicationProperty_Description_String = 50, - VRApplicationProperty_NewsURL_String = 51, - VRApplicationProperty_ImagePath_String = 52, - VRApplicationProperty_Source_String = 53, + VRApplicationProperty_IsDashboardOverlay_Bool = 60, + VRApplicationProperty_IsTemplate_Bool = 61, + VRApplicationProperty_IsInstanced_Bool = 62, + VRApplicationProperty_IsInternal_Bool = 63, + VRApplicationProperty_WantsCompositorPauseInStandby_Bool = 64, - VRApplicationProperty_IsDashboardOverlay_Bool = 60, - VRApplicationProperty_IsTemplate_Bool = 61, - VRApplicationProperty_IsInstanced_Bool = 62, - VRApplicationProperty_IsInternal_Bool = 63, - VRApplicationProperty_WantsCompositorPauseInStandby_Bool = 64, + VRApplicationProperty_LastLaunchTime_Uint64 = 70, +}; - VRApplicationProperty_LastLaunchTime_Uint64 = 70, - }; +/** These are states the scene application startup process will go through. */ +enum EVRApplicationTransitionState +{ + VRApplicationTransition_None = 0, - /** These are states the scene application startup process will go through. */ - enum EVRApplicationTransitionState - { - VRApplicationTransition_None = 0, + VRApplicationTransition_OldAppQuitSent = 10, + VRApplicationTransition_WaitingForExternalLaunch = 11, - VRApplicationTransition_OldAppQuitSent = 10, - VRApplicationTransition_WaitingForExternalLaunch = 11, - - VRApplicationTransition_NewAppLaunched = 20, - }; + VRApplicationTransition_NewAppLaunched = 20, +}; - struct AppOverrideKeys_t - { - const char *pchKey; - const char *pchValue; - }; +struct AppOverrideKeys_t +{ + const char *pchKey; + const char *pchValue; +}; - /** Currently recognized mime types */ - static const char * const k_pch_MimeType_HomeApp = "vr/home"; - static const char * const k_pch_MimeType_GameTheater = "vr/game_theater"; +/** Currently recognized mime types */ +static const char *const k_pch_MimeType_HomeApp = "vr/home"; +static const char *const k_pch_MimeType_GameTheater = "vr/game_theater"; - class IVRApplications - { - public: +class IVRApplications +{ +public: + // --------------- Application management --------------- // - // --------------- Application management --------------- // - - /** Adds an application manifest to the list to load when building the list of installed applications. + /** Adds an application manifest to the list to load when building the list of installed applications. * Temporary manifests are not automatically loaded */ - virtual EVRApplicationError AddApplicationManifest( const char *pchApplicationManifestFullPath, bool bTemporary = false ) = 0; + virtual EVRApplicationError AddApplicationManifest(const char *pchApplicationManifestFullPath, bool bTemporary = false) = 0; - /** Removes an application manifest from the list to load when building the list of installed applications. */ - virtual EVRApplicationError RemoveApplicationManifest( const char *pchApplicationManifestFullPath ) = 0; + /** Removes an application manifest from the list to load when building the list of installed applications. */ + virtual EVRApplicationError RemoveApplicationManifest(const char *pchApplicationManifestFullPath) = 0; - /** Returns true if an application is installed */ - virtual bool IsApplicationInstalled( const char *pchAppKey ) = 0; + /** Returns true if an application is installed */ + virtual bool IsApplicationInstalled(const char *pchAppKey) = 0; - /** Returns the number of applications available in the list */ - virtual uint32_t GetApplicationCount() = 0; + /** Returns the number of applications available in the list */ + virtual uint32_t GetApplicationCount() = 0; - /** Returns the key of the specified application. The index is at least 0 and is less than the return + /** Returns the key of the specified application. The index is at least 0 and is less than the return * value of GetApplicationCount(). The buffer should be at least k_unMaxApplicationKeyLength in order to * fit the key. */ - virtual EVRApplicationError GetApplicationKeyByIndex( uint32_t unApplicationIndex, VR_OUT_STRING() char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0; + virtual EVRApplicationError GetApplicationKeyByIndex(uint32_t unApplicationIndex, VR_OUT_STRING() char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen) = 0; - /** Returns the key of the application for the specified Process Id. The buffer should be at least + /** Returns the key of the application for the specified Process Id. The buffer should be at least * k_unMaxApplicationKeyLength in order to fit the key. */ - virtual EVRApplicationError GetApplicationKeyByProcessId( uint32_t unProcessId, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0; + virtual EVRApplicationError GetApplicationKeyByProcessId(uint32_t unProcessId, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen) = 0; - /** Launches the application. The existing scene application will exit and then the new application will start. + /** Launches the application. The existing scene application will exit and then the new application will start. * This call is not valid for dashboard overlay applications. */ - virtual EVRApplicationError LaunchApplication( const char *pchAppKey ) = 0; + virtual EVRApplicationError LaunchApplication(const char *pchAppKey) = 0; - /** Launches an instance of an application of type template, with its app key being pchNewAppKey (which must be unique) and optionally override sections + /** Launches an instance of an application of type template, with its app key being pchNewAppKey (which must be unique) and optionally override sections * from the manifest file via AppOverrideKeys_t */ - virtual EVRApplicationError LaunchTemplateApplication( const char *pchTemplateAppKey, const char *pchNewAppKey, VR_ARRAY_COUNT( unKeys ) const AppOverrideKeys_t *pKeys, uint32_t unKeys ) = 0; + virtual EVRApplicationError LaunchTemplateApplication(const char *pchTemplateAppKey, const char *pchNewAppKey, VR_ARRAY_COUNT(unKeys) const AppOverrideKeys_t *pKeys, uint32_t unKeys) = 0; - /** launches the application currently associated with this mime type and passes it the option args, typically the filename or object name of the item being launched */ - virtual vr::EVRApplicationError LaunchApplicationFromMimeType( const char *pchMimeType, const char *pchArgs ) = 0; + /** launches the application currently associated with this mime type and passes it the option args, typically the filename or object name of the item being launched */ + virtual vr::EVRApplicationError LaunchApplicationFromMimeType(const char *pchMimeType, const char *pchArgs) = 0; - /** Launches the dashboard overlay application if it is not already running. This call is only valid for + /** Launches the dashboard overlay application if it is not already running. This call is only valid for * dashboard overlay applications. */ - virtual EVRApplicationError LaunchDashboardOverlay( const char *pchAppKey ) = 0; + virtual EVRApplicationError LaunchDashboardOverlay(const char *pchAppKey) = 0; - /** Cancel a pending launch for an application */ - virtual bool CancelApplicationLaunch( const char *pchAppKey ) = 0; + /** Cancel a pending launch for an application */ + virtual bool CancelApplicationLaunch(const char *pchAppKey) = 0; - /** Identifies a running application. OpenVR can't always tell which process started in response + /** Identifies a running application. OpenVR can't always tell which process started in response * to a URL. This function allows a URL handler (or the process itself) to identify the app key * for the now running application. Passing a process ID of 0 identifies the calling process. * The application must be one that's known to the system via a call to AddApplicationManifest. */ - virtual EVRApplicationError IdentifyApplication( uint32_t unProcessId, const char *pchAppKey ) = 0; + virtual EVRApplicationError IdentifyApplication(uint32_t unProcessId, const char *pchAppKey) = 0; - /** Returns the process ID for an application. Return 0 if the application was not found or is not running. */ - virtual uint32_t GetApplicationProcessId( const char *pchAppKey ) = 0; + /** Returns the process ID for an application. Return 0 if the application was not found or is not running. */ + virtual uint32_t GetApplicationProcessId(const char *pchAppKey) = 0; - /** Returns a string for an applications error */ - virtual const char *GetApplicationsErrorNameFromEnum( EVRApplicationError error ) = 0; + /** Returns a string for an applications error */ + virtual const char *GetApplicationsErrorNameFromEnum(EVRApplicationError error) = 0; - // --------------- Application properties --------------- // + // --------------- Application properties --------------- // - /** Returns a value for an application property. The required buffer size to fit this value will be returned. */ - virtual uint32_t GetApplicationPropertyString( const char *pchAppKey, EVRApplicationProperty eProperty, VR_OUT_STRING() char *pchPropertyValueBuffer, uint32_t unPropertyValueBufferLen, EVRApplicationError *peError = nullptr ) = 0; + /** Returns a value for an application property. The required buffer size to fit this value will be returned. */ + virtual uint32_t GetApplicationPropertyString(const char *pchAppKey, EVRApplicationProperty eProperty, VR_OUT_STRING() char *pchPropertyValueBuffer, uint32_t unPropertyValueBufferLen, EVRApplicationError *peError = nullptr) = 0; - /** Returns a bool value for an application property. Returns false in all error cases. */ - virtual bool GetApplicationPropertyBool( const char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError = nullptr ) = 0; + /** Returns a bool value for an application property. Returns false in all error cases. */ + virtual bool GetApplicationPropertyBool(const char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError = nullptr) = 0; - /** Returns a uint64 value for an application property. Returns 0 in all error cases. */ - virtual uint64_t GetApplicationPropertyUint64( const char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError = nullptr ) = 0; + /** Returns a uint64 value for an application property. Returns 0 in all error cases. */ + virtual uint64_t GetApplicationPropertyUint64(const char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError = nullptr) = 0; - /** Sets the application auto-launch flag. This is only valid for applications which return true for VRApplicationProperty_IsDashboardOverlay_Bool. */ - virtual EVRApplicationError SetApplicationAutoLaunch( const char *pchAppKey, bool bAutoLaunch ) = 0; + /** Sets the application auto-launch flag. This is only valid for applications which return true for VRApplicationProperty_IsDashboardOverlay_Bool. */ + virtual EVRApplicationError SetApplicationAutoLaunch(const char *pchAppKey, bool bAutoLaunch) = 0; - /** Gets the application auto-launch flag. This is only valid for applications which return true for VRApplicationProperty_IsDashboardOverlay_Bool. */ - virtual bool GetApplicationAutoLaunch( const char *pchAppKey ) = 0; + /** Gets the application auto-launch flag. This is only valid for applications which return true for VRApplicationProperty_IsDashboardOverlay_Bool. */ + virtual bool GetApplicationAutoLaunch(const char *pchAppKey) = 0; - /** Adds this mime-type to the list of supported mime types for this application*/ - virtual EVRApplicationError SetDefaultApplicationForMimeType( const char *pchAppKey, const char *pchMimeType ) = 0; + /** Adds this mime-type to the list of supported mime types for this application*/ + virtual EVRApplicationError SetDefaultApplicationForMimeType(const char *pchAppKey, const char *pchMimeType) = 0; - /** return the app key that will open this mime type */ - virtual bool GetDefaultApplicationForMimeType( const char *pchMimeType, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0; + /** return the app key that will open this mime type */ + virtual bool GetDefaultApplicationForMimeType(const char *pchMimeType, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen) = 0; - /** Get the list of supported mime types for this application, comma-delimited */ - virtual bool GetApplicationSupportedMimeTypes( const char *pchAppKey, char *pchMimeTypesBuffer, uint32_t unMimeTypesBuffer ) = 0; + /** Get the list of supported mime types for this application, comma-delimited */ + virtual bool GetApplicationSupportedMimeTypes(const char *pchAppKey, char *pchMimeTypesBuffer, uint32_t unMimeTypesBuffer) = 0; - /** Get the list of app-keys that support this mime type, comma-delimited, the return value is number of bytes you need to return the full string */ - virtual uint32_t GetApplicationsThatSupportMimeType( const char *pchMimeType, char *pchAppKeysThatSupportBuffer, uint32_t unAppKeysThatSupportBuffer ) = 0; + /** Get the list of app-keys that support this mime type, comma-delimited, the return value is number of bytes you need to return the full string */ + virtual uint32_t GetApplicationsThatSupportMimeType(const char *pchMimeType, char *pchAppKeysThatSupportBuffer, uint32_t unAppKeysThatSupportBuffer) = 0; - /** Get the args list from an app launch that had the process already running, you call this when you get a VREvent_ApplicationMimeTypeLoad */ - virtual uint32_t GetApplicationLaunchArguments( uint32_t unHandle, char *pchArgs, uint32_t unArgs ) = 0; + /** Get the args list from an app launch that had the process already running, you call this when you get a VREvent_ApplicationMimeTypeLoad */ + virtual uint32_t GetApplicationLaunchArguments(uint32_t unHandle, char *pchArgs, uint32_t unArgs) = 0; - // --------------- Transition methods --------------- // + // --------------- Transition methods --------------- // - /** Returns the app key for the application that is starting up */ - virtual EVRApplicationError GetStartingApplication( char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0; + /** Returns the app key for the application that is starting up */ + virtual EVRApplicationError GetStartingApplication(char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen) = 0; - /** Returns the application transition state */ - virtual EVRApplicationTransitionState GetTransitionState() = 0; + /** Returns the application transition state */ + virtual EVRApplicationTransitionState GetTransitionState() = 0; - /** Returns errors that would prevent the specified application from launching immediately. Calling this function will + /** Returns errors that would prevent the specified application from launching immediately. Calling this function will * cause the current scene application to quit, so only call it when you are actually about to launch something else. * What the caller should do about these failures depends on the failure: * VRApplicationError_OldApplicationQuitting - An existing application has been told to quit. Wait for a VREvent_ProcessQuit @@ -1721,267 +1686,265 @@ namespace vr * VRApplicationError_LaunchInProgress - A different application is already starting. This is a permanent failure. * VRApplicationError_None - Go ahead and launch. Everything is clear. */ - virtual EVRApplicationError PerformApplicationPrelaunchCheck( const char *pchAppKey ) = 0; + virtual EVRApplicationError PerformApplicationPrelaunchCheck(const char *pchAppKey) = 0; - /** Returns a string for an application transition state */ - virtual const char *GetApplicationsTransitionStateNameFromEnum( EVRApplicationTransitionState state ) = 0; + /** Returns a string for an application transition state */ + virtual const char *GetApplicationsTransitionStateNameFromEnum(EVRApplicationTransitionState state) = 0; - /** Returns true if the outgoing scene app has requested a save prompt before exiting */ - virtual bool IsQuitUserPromptRequested() = 0; + /** Returns true if the outgoing scene app has requested a save prompt before exiting */ + virtual bool IsQuitUserPromptRequested() = 0; - /** Starts a subprocess within the calling application. This + /** Starts a subprocess within the calling application. This * suppresses all application transition UI and automatically identifies the new executable * as part of the same application. On success the calling process should exit immediately. * If working directory is NULL or "" the directory portion of the binary path will be * the working directory. */ - virtual EVRApplicationError LaunchInternalProcess( const char *pchBinaryPath, const char *pchArguments, const char *pchWorkingDirectory ) = 0; + virtual EVRApplicationError LaunchInternalProcess(const char *pchBinaryPath, const char *pchArguments, const char *pchWorkingDirectory) = 0; - /** Returns the current scene process ID according to the application system. A scene process will get scene + /** Returns the current scene process ID according to the application system. A scene process will get scene * focus once it starts rendering, but it will appear here once it calls VR_Init with the Scene application * type. */ - virtual uint32_t GetCurrentSceneProcessId() = 0; - }; + virtual uint32_t GetCurrentSceneProcessId() = 0; +}; - static const char * const IVRApplications_Version = "IVRApplications_006"; +static const char *const IVRApplications_Version = "IVRApplications_006"; -} // namespace vr +} // namespace vr // ivrsettings.h namespace vr { - enum EVRSettingsError - { - VRSettingsError_None = 0, - VRSettingsError_IPCFailed = 1, - VRSettingsError_WriteFailed = 2, - VRSettingsError_ReadFailed = 3, - VRSettingsError_JsonParseFailed = 4, - VRSettingsError_UnsetSettingHasNoDefault = 5, // This will be returned if the setting does not appear in the appropriate default file and has not been set - }; +enum EVRSettingsError +{ + VRSettingsError_None = 0, + VRSettingsError_IPCFailed = 1, + VRSettingsError_WriteFailed = 2, + VRSettingsError_ReadFailed = 3, + VRSettingsError_JsonParseFailed = 4, + VRSettingsError_UnsetSettingHasNoDefault = 5, // This will be returned if the setting does not appear in the appropriate default file and has not been set +}; - // The maximum length of a settings key - static const uint32_t k_unMaxSettingsKeyLength = 128; +// The maximum length of a settings key +static const uint32_t k_unMaxSettingsKeyLength = 128; - class IVRSettings - { - public: - virtual const char *GetSettingsErrorNameFromEnum( EVRSettingsError eError ) = 0; +class IVRSettings +{ +public: + virtual const char *GetSettingsErrorNameFromEnum(EVRSettingsError eError) = 0; - // Returns true if file sync occurred (force or settings dirty) - virtual bool Sync( bool bForce = false, EVRSettingsError *peError = nullptr ) = 0; + // Returns true if file sync occurred (force or settings dirty) + virtual bool Sync(bool bForce = false, EVRSettingsError *peError = nullptr) = 0; - virtual void SetBool( const char *pchSection, const char *pchSettingsKey, bool bValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetInt32( const char *pchSection, const char *pchSettingsKey, int32_t nValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetFloat( const char *pchSection, const char *pchSettingsKey, float flValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetString( const char *pchSection, const char *pchSettingsKey, const char *pchValue, EVRSettingsError *peError = nullptr ) = 0; + virtual void SetBool(const char *pchSection, const char *pchSettingsKey, bool bValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetInt32(const char *pchSection, const char *pchSettingsKey, int32_t nValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetFloat(const char *pchSection, const char *pchSettingsKey, float flValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetString(const char *pchSection, const char *pchSettingsKey, const char *pchValue, EVRSettingsError *peError = nullptr) = 0; - // Users of the system need to provide a proper default in default.vrsettings in the resources/settings/ directory - // of either the runtime or the driver_xxx directory. Otherwise the default will be false, 0, 0.0 or "" - virtual bool GetBool( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual int32_t GetInt32( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual float GetFloat( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual void GetString( const char *pchSection, const char *pchSettingsKey, VR_OUT_STRING() char *pchValue, uint32_t unValueLen, EVRSettingsError *peError = nullptr ) = 0; + // Users of the system need to provide a proper default in default.vrsettings in the resources/settings/ directory + // of either the runtime or the driver_xxx directory. Otherwise the default will be false, 0, 0.0 or "" + virtual bool GetBool(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual int32_t GetInt32(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual float GetFloat(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual void GetString(const char *pchSection, const char *pchSettingsKey, VR_OUT_STRING() char *pchValue, uint32_t unValueLen, EVRSettingsError *peError = nullptr) = 0; - virtual void RemoveSection( const char *pchSection, EVRSettingsError *peError = nullptr ) = 0; - virtual void RemoveKeyInSection( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - }; + virtual void RemoveSection(const char *pchSection, EVRSettingsError *peError = nullptr) = 0; + virtual void RemoveKeyInSection(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; +}; - //----------------------------------------------------------------------------- - static const char * const IVRSettings_Version = "IVRSettings_002"; +//----------------------------------------------------------------------------- +static const char *const IVRSettings_Version = "IVRSettings_002"; - //----------------------------------------------------------------------------- - // steamvr keys - static const char * const k_pch_SteamVR_Section = "steamvr"; - static const char * const k_pch_SteamVR_RequireHmd_String = "requireHmd"; - static const char * const k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; - static const char * const k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; - static const char * const k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; - static const char * const k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; - static const char * const k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; - static const char * const k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; - static const char * const k_pch_SteamVR_SendSystemButtonToAllApps_Bool= "sendSystemButtonToAllApps"; - static const char * const k_pch_SteamVR_LogLevel_Int32 = "loglevel"; - static const char * const k_pch_SteamVR_IPD_Float = "ipd"; - static const char * const k_pch_SteamVR_Background_String = "background"; - static const char * const k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; - static const char * const k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; - static const char * const k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; - static const char * const k_pch_SteamVR_GridColor_String = "gridColor"; - static const char * const k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; - static const char * const k_pch_SteamVR_ShowStage_Bool = "showStage"; - static const char * const k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; - static const char * const k_pch_SteamVR_DirectMode_Bool = "directMode"; - static const char * const k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; - static const char * const k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; - static const char * const k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; - static const char * const k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; - static const char * const k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; - static const char * const k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; - static const char * const k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; - static const char * const k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; - static const char * const k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; - static const char * const k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; - static const char * const k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; - static const char * const k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; - static const char * const k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; - static const char * const k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; - static const char * const k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; - static const char * const k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; - static const char * const k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; - static const char * const k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; - static const char * const k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; - static const char * const k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; - static const char * const k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; - static const char * const k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; - static const char * const k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; - static const char * const k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; +//----------------------------------------------------------------------------- +// steamvr keys +static const char *const k_pch_SteamVR_Section = "steamvr"; +static const char *const k_pch_SteamVR_RequireHmd_String = "requireHmd"; +static const char *const k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; +static const char *const k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; +static const char *const k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; +static const char *const k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; +static const char *const k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; +static const char *const k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; +static const char *const k_pch_SteamVR_SendSystemButtonToAllApps_Bool = "sendSystemButtonToAllApps"; +static const char *const k_pch_SteamVR_LogLevel_Int32 = "loglevel"; +static const char *const k_pch_SteamVR_IPD_Float = "ipd"; +static const char *const k_pch_SteamVR_Background_String = "background"; +static const char *const k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; +static const char *const k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; +static const char *const k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; +static const char *const k_pch_SteamVR_GridColor_String = "gridColor"; +static const char *const k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; +static const char *const k_pch_SteamVR_ShowStage_Bool = "showStage"; +static const char *const k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; +static const char *const k_pch_SteamVR_DirectMode_Bool = "directMode"; +static const char *const k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; +static const char *const k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; +static const char *const k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; +static const char *const k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; +static const char *const k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; +static const char *const k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; +static const char *const k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; +static const char *const k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; +static const char *const k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; +static const char *const k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; +static const char *const k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; +static const char *const k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; +static const char *const k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; +static const char *const k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; +static const char *const k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; +static const char *const k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; +static const char *const k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; +static const char *const k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; +static const char *const k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; +static const char *const k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; +static const char *const k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; +static const char *const k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; +static const char *const k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; +static const char *const k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; - //----------------------------------------------------------------------------- - // lighthouse keys - static const char * const k_pch_Lighthouse_Section = "driver_lighthouse"; - static const char * const k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; - static const char * const k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; - static const char * const k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; - static const char * const k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; - static const char * const k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; +//----------------------------------------------------------------------------- +// lighthouse keys +static const char *const k_pch_Lighthouse_Section = "driver_lighthouse"; +static const char *const k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; +static const char *const k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; +static const char *const k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; +static const char *const k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; +static const char *const k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; - //----------------------------------------------------------------------------- - // null keys - static const char * const k_pch_Null_Section = "driver_null"; - static const char * const k_pch_Null_SerialNumber_String = "serialNumber"; - static const char * const k_pch_Null_ModelNumber_String = "modelNumber"; - static const char * const k_pch_Null_WindowX_Int32 = "windowX"; - static const char * const k_pch_Null_WindowY_Int32 = "windowY"; - static const char * const k_pch_Null_WindowWidth_Int32 = "windowWidth"; - static const char * const k_pch_Null_WindowHeight_Int32 = "windowHeight"; - static const char * const k_pch_Null_RenderWidth_Int32 = "renderWidth"; - static const char * const k_pch_Null_RenderHeight_Int32 = "renderHeight"; - static const char * const k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; - static const char * const k_pch_Null_DisplayFrequency_Float = "displayFrequency"; +//----------------------------------------------------------------------------- +// null keys +static const char *const k_pch_Null_Section = "driver_null"; +static const char *const k_pch_Null_SerialNumber_String = "serialNumber"; +static const char *const k_pch_Null_ModelNumber_String = "modelNumber"; +static const char *const k_pch_Null_WindowX_Int32 = "windowX"; +static const char *const k_pch_Null_WindowY_Int32 = "windowY"; +static const char *const k_pch_Null_WindowWidth_Int32 = "windowWidth"; +static const char *const k_pch_Null_WindowHeight_Int32 = "windowHeight"; +static const char *const k_pch_Null_RenderWidth_Int32 = "renderWidth"; +static const char *const k_pch_Null_RenderHeight_Int32 = "renderHeight"; +static const char *const k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; +static const char *const k_pch_Null_DisplayFrequency_Float = "displayFrequency"; - //----------------------------------------------------------------------------- - // user interface keys - static const char * const k_pch_UserInterface_Section = "userinterface"; - static const char * const k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; - static const char * const k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; - static const char * const k_pch_UserInterface_Screenshots_Bool = "screenshots"; - static const char * const k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; +//----------------------------------------------------------------------------- +// user interface keys +static const char *const k_pch_UserInterface_Section = "userinterface"; +static const char *const k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; +static const char *const k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; +static const char *const k_pch_UserInterface_Screenshots_Bool = "screenshots"; +static const char *const k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; - //----------------------------------------------------------------------------- - // notification keys - static const char * const k_pch_Notifications_Section = "notifications"; - static const char * const k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; +//----------------------------------------------------------------------------- +// notification keys +static const char *const k_pch_Notifications_Section = "notifications"; +static const char *const k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; - //----------------------------------------------------------------------------- - // keyboard keys - static const char * const k_pch_Keyboard_Section = "keyboard"; - static const char * const k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; - static const char * const k_pch_Keyboard_ScaleX = "ScaleX"; - static const char * const k_pch_Keyboard_ScaleY = "ScaleY"; - static const char * const k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; - static const char * const k_pch_Keyboard_OffsetRightX = "OffsetRightX"; - static const char * const k_pch_Keyboard_OffsetY = "OffsetY"; - static const char * const k_pch_Keyboard_Smoothing = "Smoothing"; +//----------------------------------------------------------------------------- +// keyboard keys +static const char *const k_pch_Keyboard_Section = "keyboard"; +static const char *const k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; +static const char *const k_pch_Keyboard_ScaleX = "ScaleX"; +static const char *const k_pch_Keyboard_ScaleY = "ScaleY"; +static const char *const k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; +static const char *const k_pch_Keyboard_OffsetRightX = "OffsetRightX"; +static const char *const k_pch_Keyboard_OffsetY = "OffsetY"; +static const char *const k_pch_Keyboard_Smoothing = "Smoothing"; - //----------------------------------------------------------------------------- - // perf keys - static const char * const k_pch_Perf_Section = "perfcheck"; - static const char * const k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; - static const char * const k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; - static const char * const k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; - static const char * const k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; - static const char * const k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; - static const char * const k_pch_Perf_TestData_Float = "perfTestData"; - static const char * const k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; +//----------------------------------------------------------------------------- +// perf keys +static const char *const k_pch_Perf_Section = "perfcheck"; +static const char *const k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; +static const char *const k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; +static const char *const k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; +static const char *const k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; +static const char *const k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; +static const char *const k_pch_Perf_TestData_Float = "perfTestData"; +static const char *const k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; - //----------------------------------------------------------------------------- - // collision bounds keys - static const char * const k_pch_CollisionBounds_Section = "collisionBounds"; - static const char * const k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; - static const char * const k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; - static const char * const k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; - static const char * const k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; - static const char * const k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; - static const char * const k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; - static const char * const k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; - static const char * const k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; - static const char * const k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; +//----------------------------------------------------------------------------- +// collision bounds keys +static const char *const k_pch_CollisionBounds_Section = "collisionBounds"; +static const char *const k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; +static const char *const k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; +static const char *const k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; +static const char *const k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; +static const char *const k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; +static const char *const k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; +static const char *const k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; +static const char *const k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; +static const char *const k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; - //----------------------------------------------------------------------------- - // camera keys - static const char * const k_pch_Camera_Section = "camera"; - static const char * const k_pch_Camera_EnableCamera_Bool = "enableCamera"; - static const char * const k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; - static const char * const k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; - static const char * const k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; - static const char * const k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; - static const char * const k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; - static const char * const k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; - static const char * const k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; - static const char * const k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; +//----------------------------------------------------------------------------- +// camera keys +static const char *const k_pch_Camera_Section = "camera"; +static const char *const k_pch_Camera_EnableCamera_Bool = "enableCamera"; +static const char *const k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; +static const char *const k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; +static const char *const k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; +static const char *const k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; +static const char *const k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; +static const char *const k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; +static const char *const k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; +static const char *const k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; - //----------------------------------------------------------------------------- - // audio keys - static const char * const k_pch_audio_Section = "audio"; - static const char * const k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; - static const char * const k_pch_audio_OnRecordDevice_String = "onRecordDevice"; - static const char * const k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; - static const char * const k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; - static const char * const k_pch_audio_OffRecordDevice_String = "offRecordDevice"; - static const char * const k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; +//----------------------------------------------------------------------------- +// audio keys +static const char *const k_pch_audio_Section = "audio"; +static const char *const k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; +static const char *const k_pch_audio_OnRecordDevice_String = "onRecordDevice"; +static const char *const k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; +static const char *const k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; +static const char *const k_pch_audio_OffRecordDevice_String = "offRecordDevice"; +static const char *const k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; - //----------------------------------------------------------------------------- - // power management keys - static const char * const k_pch_Power_Section = "power"; - static const char * const k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; - static const char * const k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; - static const char * const k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; - static const char * const k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; - static const char * const k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; - static const char * const k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; +//----------------------------------------------------------------------------- +// power management keys +static const char *const k_pch_Power_Section = "power"; +static const char *const k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; +static const char *const k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; +static const char *const k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; +static const char *const k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; +static const char *const k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; +static const char *const k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; - //----------------------------------------------------------------------------- - // dashboard keys - static const char * const k_pch_Dashboard_Section = "dashboard"; - static const char * const k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; - static const char * const k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; +//----------------------------------------------------------------------------- +// dashboard keys +static const char *const k_pch_Dashboard_Section = "dashboard"; +static const char *const k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; +static const char *const k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; - //----------------------------------------------------------------------------- - // model skin keys - static const char * const k_pch_modelskin_Section = "modelskins"; +//----------------------------------------------------------------------------- +// model skin keys +static const char *const k_pch_modelskin_Section = "modelskins"; - //----------------------------------------------------------------------------- - // driver keys - These could be checked in any driver_ section - static const char * const k_pch_Driver_Enable_Bool = "enable"; +//----------------------------------------------------------------------------- +// driver keys - These could be checked in any driver_ section +static const char *const k_pch_Driver_Enable_Bool = "enable"; -} // namespace vr +} // namespace vr // ivrchaperone.h namespace vr { - -#pragma pack( push, 8 ) +#pragma pack(push, 8) enum ChaperoneCalibrationState { // OK! - ChaperoneCalibrationState_OK = 1, // Chaperone is fully calibrated and working correctly + ChaperoneCalibrationState_OK = 1, // Chaperone is fully calibrated and working correctly // Warnings ChaperoneCalibrationState_Warning = 100, - ChaperoneCalibrationState_Warning_BaseStationMayHaveMoved = 101, // A base station thinks that it might have moved - ChaperoneCalibrationState_Warning_BaseStationRemoved = 102, // There are less base stations than when calibrated - ChaperoneCalibrationState_Warning_SeatedBoundsInvalid = 103, // Seated bounds haven't been calibrated for the current tracking center + ChaperoneCalibrationState_Warning_BaseStationMayHaveMoved = 101, // A base station thinks that it might have moved + ChaperoneCalibrationState_Warning_BaseStationRemoved = 102, // There are less base stations than when calibrated + ChaperoneCalibrationState_Warning_SeatedBoundsInvalid = 103, // Seated bounds haven't been calibrated for the current tracking center // Errors - ChaperoneCalibrationState_Error = 200, // The UniverseID is invalid - ChaperoneCalibrationState_Error_BaseStationUninitialized = 201, // Tracking center hasn't be calibrated for at least one of the base stations - ChaperoneCalibrationState_Error_BaseStationConflict = 202, // Tracking center is calibrated, but base stations disagree on the tracking space - ChaperoneCalibrationState_Error_PlayAreaInvalid = 203, // Play Area hasn't been calibrated for the current tracking center - ChaperoneCalibrationState_Error_CollisionBoundsInvalid = 204, // Collision Bounds haven't been calibrated for the current tracking center + ChaperoneCalibrationState_Error = 200, // The UniverseID is invalid + ChaperoneCalibrationState_Error_BaseStationUninitialized = 201, // Tracking center hasn't be calibrated for at least one of the base stations + ChaperoneCalibrationState_Error_BaseStationConflict = 202, // Tracking center is calibrated, but base stations disagree on the tracking space + ChaperoneCalibrationState_Error_PlayAreaInvalid = 203, // Play Area hasn't been calibrated for the current tracking center + ChaperoneCalibrationState_Error_CollisionBoundsInvalid = 204, // Collision Bounds haven't been calibrated for the current tracking center }; - /** HIGH LEVEL TRACKING SPACE ASSUMPTIONS: * 0,0,0 is the preferred standing area center. * 0Y is the floor height. @@ -1989,13 +1952,12 @@ enum ChaperoneCalibrationState class IVRChaperone { public: - /** Get the current state of Chaperone calibration. This state can change at any time during a session due to physical base station changes. **/ virtual ChaperoneCalibrationState GetCalibrationState() = 0; /** Returns the width and depth of the Play Area (formerly named Soft Bounds) in X and Z. * Tracking space center (0,0,0) is the center of the Play Area. **/ - virtual bool GetPlayAreaSize( float *pSizeX, float *pSizeZ ) = 0; + virtual bool GetPlayAreaSize(float *pSizeX, float *pSizeZ) = 0; /** Returns the 4 corner positions of the Play Area (formerly named Soft Bounds). * Corners are in counter-clockwise order. @@ -2003,38 +1965,37 @@ public: * It's a rectangle. * 2 sides are parallel to the X axis and 2 sides are parallel to the Z axis. * Height of every corner is 0Y (on the floor). **/ - virtual bool GetPlayAreaRect( HmdQuad_t *rect ) = 0; + virtual bool GetPlayAreaRect(HmdQuad_t *rect) = 0; /** Reload Chaperone data from the .vrchap file on disk. */ - virtual void ReloadInfo( void ) = 0; + virtual void ReloadInfo(void) = 0; /** Optionally give the chaperone system a hit about the color and brightness in the scene **/ - virtual void SetSceneColor( HmdColor_t color ) = 0; + virtual void SetSceneColor(HmdColor_t color) = 0; /** Get the current chaperone bounds draw color and brightness **/ - virtual void GetBoundsColor( HmdColor_t *pOutputColorArray, int nNumOutputColors, float flCollisionBoundsFadeDistance, HmdColor_t *pOutputCameraColor ) = 0; + virtual void GetBoundsColor(HmdColor_t *pOutputColorArray, int nNumOutputColors, float flCollisionBoundsFadeDistance, HmdColor_t *pOutputCameraColor) = 0; /** Determine whether the bounds are showing right now **/ virtual bool AreBoundsVisible() = 0; /** Force the bounds to show, mostly for utilities **/ - virtual void ForceBoundsVisible( bool bForce ) = 0; + virtual void ForceBoundsVisible(bool bForce) = 0; }; -static const char * const IVRChaperone_Version = "IVRChaperone_003"; +static const char *const IVRChaperone_Version = "IVRChaperone_003"; -#pragma pack( pop ) +#pragma pack(pop) -} +} // namespace vr // ivrchaperonesetup.h namespace vr { - enum EChaperoneConfigFile { - EChaperoneConfigFile_Live = 1, // The live chaperone config, used by most applications and games - EChaperoneConfigFile_Temp = 2, // The temporary chaperone config, used to live-preview collision bounds in room setup + EChaperoneConfigFile_Live = 1, // The live chaperone config, used by most applications and games + EChaperoneConfigFile_Temp = 2, // The temporary chaperone config, used to live-preview collision bounds in room setup }; enum EChaperoneImportFlags @@ -2049,9 +2010,8 @@ enum EChaperoneImportFlags class IVRChaperoneSetup { public: - /** Saves the current working copy to disk */ - virtual bool CommitWorkingCopy( EChaperoneConfigFile configFile ) = 0; + virtual bool CommitWorkingCopy(EChaperoneConfigFile configFile) = 0; /** Reverts the working copy to match the live chaperone calibration. * To modify existing data this MUST be do WHILE getting a non-error ChaperoneCalibrationStatus. @@ -2060,7 +2020,7 @@ public: /** Returns the width and depth of the Play Area (formerly named Soft Bounds) in X and Z from the working copy. * Tracking space center (0,0,0) is the center of the Play Area. */ - virtual bool GetWorkingPlayAreaSize( float *pSizeX, float *pSizeZ ) = 0; + virtual bool GetWorkingPlayAreaSize(float *pSizeX, float *pSizeZ) = 0; /** Returns the 4 corner positions of the Play Area (formerly named Soft Bounds) from the working copy. * Corners are in clockwise order. @@ -2068,95 +2028,93 @@ public: * It's a rectangle. * 2 sides are parallel to the X axis and 2 sides are parallel to the Z axis. * Height of every corner is 0Y (on the floor). **/ - virtual bool GetWorkingPlayAreaRect( HmdQuad_t *rect ) = 0; + virtual bool GetWorkingPlayAreaRect(HmdQuad_t *rect) = 0; /** Returns the number of Quads if the buffer points to null. Otherwise it returns Quads * into the buffer up to the max specified from the working copy. */ - virtual bool GetWorkingCollisionBoundsInfo( VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t* punQuadsCount ) = 0; + virtual bool GetWorkingCollisionBoundsInfo(VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount) = 0; /** Returns the number of Quads if the buffer points to null. Otherwise it returns Quads * into the buffer up to the max specified. */ - virtual bool GetLiveCollisionBoundsInfo( VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t* punQuadsCount ) = 0; + virtual bool GetLiveCollisionBoundsInfo(VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount) = 0; /** Returns the preferred seated position from the working copy. */ - virtual bool GetWorkingSeatedZeroPoseToRawTrackingPose( HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose ) = 0; + virtual bool GetWorkingSeatedZeroPoseToRawTrackingPose(HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose) = 0; /** Returns the standing origin from the working copy. */ - virtual bool GetWorkingStandingZeroPoseToRawTrackingPose( HmdMatrix34_t *pmatStandingZeroPoseToRawTrackingPose ) = 0; + virtual bool GetWorkingStandingZeroPoseToRawTrackingPose(HmdMatrix34_t *pmatStandingZeroPoseToRawTrackingPose) = 0; /** Sets the Play Area in the working copy. */ - virtual void SetWorkingPlayAreaSize( float sizeX, float sizeZ ) = 0; + virtual void SetWorkingPlayAreaSize(float sizeX, float sizeZ) = 0; /** Sets the Collision Bounds in the working copy. */ - virtual void SetWorkingCollisionBoundsInfo( VR_ARRAY_COUNT(unQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount ) = 0; + virtual void SetWorkingCollisionBoundsInfo(VR_ARRAY_COUNT(unQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount) = 0; /** Sets the preferred seated position in the working copy. */ - virtual void SetWorkingSeatedZeroPoseToRawTrackingPose( const HmdMatrix34_t *pMatSeatedZeroPoseToRawTrackingPose ) = 0; + virtual void SetWorkingSeatedZeroPoseToRawTrackingPose(const HmdMatrix34_t *pMatSeatedZeroPoseToRawTrackingPose) = 0; /** Sets the preferred standing position in the working copy. */ - virtual void SetWorkingStandingZeroPoseToRawTrackingPose( const HmdMatrix34_t *pMatStandingZeroPoseToRawTrackingPose ) = 0; + virtual void SetWorkingStandingZeroPoseToRawTrackingPose(const HmdMatrix34_t *pMatStandingZeroPoseToRawTrackingPose) = 0; /** Tear everything down and reload it from the file on disk */ - virtual void ReloadFromDisk( EChaperoneConfigFile configFile ) = 0; + virtual void ReloadFromDisk(EChaperoneConfigFile configFile) = 0; /** Returns the preferred seated position. */ - virtual bool GetLiveSeatedZeroPoseToRawTrackingPose( HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose ) = 0; + virtual bool GetLiveSeatedZeroPoseToRawTrackingPose(HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose) = 0; - virtual void SetWorkingCollisionBoundsTagsInfo( VR_ARRAY_COUNT(unTagCount) uint8_t *pTagsBuffer, uint32_t unTagCount ) = 0; - virtual bool GetLiveCollisionBoundsTagsInfo( VR_OUT_ARRAY_COUNT(punTagCount) uint8_t *pTagsBuffer, uint32_t *punTagCount ) = 0; + virtual void SetWorkingCollisionBoundsTagsInfo(VR_ARRAY_COUNT(unTagCount) uint8_t *pTagsBuffer, uint32_t unTagCount) = 0; + virtual bool GetLiveCollisionBoundsTagsInfo(VR_OUT_ARRAY_COUNT(punTagCount) uint8_t *pTagsBuffer, uint32_t *punTagCount) = 0; - virtual bool SetWorkingPhysicalBoundsInfo( VR_ARRAY_COUNT(unQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount ) = 0; - virtual bool GetLivePhysicalBoundsInfo( VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t* punQuadsCount ) = 0; + virtual bool SetWorkingPhysicalBoundsInfo(VR_ARRAY_COUNT(unQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount) = 0; + virtual bool GetLivePhysicalBoundsInfo(VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount) = 0; - virtual bool ExportLiveToBuffer( VR_OUT_STRING() char *pBuffer, uint32_t *pnBufferLength ) = 0; - virtual bool ImportFromBufferToWorking( const char *pBuffer, uint32_t nImportFlags ) = 0; + virtual bool ExportLiveToBuffer(VR_OUT_STRING() char *pBuffer, uint32_t *pnBufferLength) = 0; + virtual bool ImportFromBufferToWorking(const char *pBuffer, uint32_t nImportFlags) = 0; }; -static const char * const IVRChaperoneSetup_Version = "IVRChaperoneSetup_005"; +static const char *const IVRChaperoneSetup_Version = "IVRChaperoneSetup_005"; - -} +} // namespace vr // ivrcompositor.h namespace vr { - -#pragma pack( push, 8 ) +#pragma pack(push, 8) /** Errors that can occur with the VR compositor */ enum EVRCompositorError { - VRCompositorError_None = 0, - VRCompositorError_RequestFailed = 1, - VRCompositorError_IncompatibleVersion = 100, - VRCompositorError_DoNotHaveFocus = 101, - VRCompositorError_InvalidTexture = 102, - VRCompositorError_IsNotSceneApplication = 103, - VRCompositorError_TextureIsOnWrongDevice = 104, + VRCompositorError_None = 0, + VRCompositorError_RequestFailed = 1, + VRCompositorError_IncompatibleVersion = 100, + VRCompositorError_DoNotHaveFocus = 101, + VRCompositorError_InvalidTexture = 102, + VRCompositorError_IsNotSceneApplication = 103, + VRCompositorError_TextureIsOnWrongDevice = 104, VRCompositorError_TextureUsesUnsupportedFormat = 105, VRCompositorError_SharedTexturesNotSupported = 106, - VRCompositorError_IndexOutOfRange = 107, - VRCompositorError_AlreadySubmitted = 108, - VRCompositorError_InvalidBounds = 109, + VRCompositorError_IndexOutOfRange = 107, + VRCompositorError_AlreadySubmitted = 108, + VRCompositorError_InvalidBounds = 109, }; const uint32_t VRCompositor_ReprojectionReason_Cpu = 0x01; const uint32_t VRCompositor_ReprojectionReason_Gpu = 0x02; -const uint32_t VRCompositor_ReprojectionAsync = 0x04; // This flag indicates the async reprojection mode is active, - // but does not indicate if reprojection actually happened or not. - // Use the ReprojectionReason flags above to check if reprojection - // was actually applied (i.e. scene texture was reused). - // NumFramePresents > 1 also indicates the scene texture was reused, - // and also the number of times that it was presented in total. +const uint32_t VRCompositor_ReprojectionAsync = 0x04; // This flag indicates the async reprojection mode is active, + // but does not indicate if reprojection actually happened or not. + // Use the ReprojectionReason flags above to check if reprojection + // was actually applied (i.e. scene texture was reused). + // NumFramePresents > 1 also indicates the scene texture was reused, + // and also the number of times that it was presented in total. /** Provides a single frame's timing information to the app */ struct Compositor_FrameTiming { - uint32_t m_nSize; // Set to sizeof( Compositor_FrameTiming ) + uint32_t m_nSize; // Set to sizeof( Compositor_FrameTiming ) uint32_t m_nFrameIndex; - uint32_t m_nNumFramePresents; // number of times this frame was presented - uint32_t m_nNumMisPresented; // number of times this frame was presented on a vsync other than it was originally predicted to - uint32_t m_nNumDroppedFrames; // number of additional times previous frame was scanned out + uint32_t m_nNumFramePresents; // number of times this frame was presented + uint32_t m_nNumMisPresented; // number of times this frame was presented on a vsync other than it was originally predicted to + uint32_t m_nNumDroppedFrames; // number of additional times previous frame was scanned out uint32_t m_nReprojectionFlags; /** Absolute time reference for comparing frames. This aligns with the vsync that running start is relative to. */ @@ -2166,38 +2124,38 @@ struct Compositor_FrameTiming * The fewer packets of work these are broken up into, the less likely this will happen. * GPU work can be broken up by calling Flush. This can sometimes be useful to get the GPU started * processing that work earlier in the frame. */ - float m_flPreSubmitGpuMs; // time spent rendering the scene (gpu work submitted between WaitGetPoses and second Submit) - float m_flPostSubmitGpuMs; // additional time spent rendering by application (e.g. companion window) - float m_flTotalRenderGpuMs; // time between work submitted immediately after present (ideally vsync) until the end of compositor submitted work - float m_flCompositorRenderGpuMs; // time spend performing distortion correction, rendering chaperone, overlays, etc. - float m_flCompositorRenderCpuMs; // time spent on cpu submitting the above work for this frame - float m_flCompositorIdleCpuMs; // time spent waiting for running start (application could have used this much more time) + float m_flPreSubmitGpuMs; // time spent rendering the scene (gpu work submitted between WaitGetPoses and second Submit) + float m_flPostSubmitGpuMs; // additional time spent rendering by application (e.g. companion window) + float m_flTotalRenderGpuMs; // time between work submitted immediately after present (ideally vsync) until the end of compositor submitted work + float m_flCompositorRenderGpuMs; // time spend performing distortion correction, rendering chaperone, overlays, etc. + float m_flCompositorRenderCpuMs; // time spent on cpu submitting the above work for this frame + float m_flCompositorIdleCpuMs; // time spent waiting for running start (application could have used this much more time) /** Miscellaneous measured intervals. */ - float m_flClientFrameIntervalMs; // time between calls to WaitGetPoses - float m_flPresentCallCpuMs; // time blocked on call to present (usually 0.0, but can go long) - float m_flWaitForPresentCpuMs; // time spent spin-waiting for frame index to change (not near-zero indicates wait object failure) - float m_flSubmitFrameMs; // time spent in IVRCompositor::Submit (not near-zero indicates driver issue) + float m_flClientFrameIntervalMs; // time between calls to WaitGetPoses + float m_flPresentCallCpuMs; // time blocked on call to present (usually 0.0, but can go long) + float m_flWaitForPresentCpuMs; // time spent spin-waiting for frame index to change (not near-zero indicates wait object failure) + float m_flSubmitFrameMs; // time spent in IVRCompositor::Submit (not near-zero indicates driver issue) /** The following are all relative to this frame's SystemTimeInSeconds */ float m_flWaitGetPosesCalledMs; float m_flNewPosesReadyMs; - float m_flNewFrameReadyMs; // second call to IVRCompositor::Submit + float m_flNewFrameReadyMs; // second call to IVRCompositor::Submit float m_flCompositorUpdateStartMs; float m_flCompositorUpdateEndMs; float m_flCompositorRenderStartMs; - vr::TrackedDevicePose_t m_HmdPose; // pose used by app to render this frame + vr::TrackedDevicePose_t m_HmdPose; // pose used by app to render this frame }; /** Cumulative stats for current application. These are not cleared until a new app connects, * but they do stop accumulating once the associated app disconnects. */ struct Compositor_CumulativeStats { - uint32_t m_nPid; // Process id associated with these stats (may no longer be running). - uint32_t m_nNumFramePresents; // total number of times we called present (includes reprojected frames) - uint32_t m_nNumDroppedFrames; // total number of times an old frame was re-scanned out (without reprojection) - uint32_t m_nNumReprojectedFrames; // total number of times a frame was scanned out a second time (with reprojection) + uint32_t m_nPid; // Process id associated with these stats (may no longer be running). + uint32_t m_nNumFramePresents; // total number of times we called present (includes reprojected frames) + uint32_t m_nNumDroppedFrames; // total number of times an old frame was re-scanned out (without reprojection) + uint32_t m_nNumReprojectedFrames; // total number of times a frame was scanned out a second time (with reprojection) /** Values recorded at startup before application has fully faded in the first time. */ uint32_t m_nNumFramePresentsOnStartup; @@ -2220,14 +2178,14 @@ struct Compositor_CumulativeStats uint32_t m_nNumReprojectedFramesTimedOut; }; -#pragma pack( pop ) +#pragma pack(pop) /** Allows the application to interact with the compositor */ class IVRCompositor { public: /** Sets tracking space returned by WaitGetPoses */ - virtual void SetTrackingSpace( ETrackingUniverseOrigin eOrigin ) = 0; + virtual void SetTrackingSpace(ETrackingUniverseOrigin eOrigin) = 0; /** Gets current tracking space returned by WaitGetPoses */ virtual ETrackingUniverseOrigin GetTrackingSpace() = 0; @@ -2240,17 +2198,17 @@ public: * - IsNotSceneApplication (make sure to call VR_Init with VRApplicaiton_Scene) * - DoNotHaveFocus (some other app has taken focus - this will throttle the call to 10hz to reduce the impact on that app) */ - virtual EVRCompositorError WaitGetPoses( VR_ARRAY_COUNT(unRenderPoseArrayCount) TrackedDevicePose_t* pRenderPoseArray, uint32_t unRenderPoseArrayCount, - VR_ARRAY_COUNT(unGamePoseArrayCount) TrackedDevicePose_t* pGamePoseArray, uint32_t unGamePoseArrayCount ) = 0; + virtual EVRCompositorError WaitGetPoses(VR_ARRAY_COUNT(unRenderPoseArrayCount) TrackedDevicePose_t *pRenderPoseArray, uint32_t unRenderPoseArrayCount, + VR_ARRAY_COUNT(unGamePoseArrayCount) TrackedDevicePose_t *pGamePoseArray, uint32_t unGamePoseArrayCount) = 0; /** Get the last set of poses returned by WaitGetPoses. */ - virtual EVRCompositorError GetLastPoses( VR_ARRAY_COUNT( unRenderPoseArrayCount ) TrackedDevicePose_t* pRenderPoseArray, uint32_t unRenderPoseArrayCount, - VR_ARRAY_COUNT( unGamePoseArrayCount ) TrackedDevicePose_t* pGamePoseArray, uint32_t unGamePoseArrayCount ) = 0; + virtual EVRCompositorError GetLastPoses(VR_ARRAY_COUNT(unRenderPoseArrayCount) TrackedDevicePose_t *pRenderPoseArray, uint32_t unRenderPoseArrayCount, + VR_ARRAY_COUNT(unGamePoseArrayCount) TrackedDevicePose_t *pGamePoseArray, uint32_t unGamePoseArrayCount) = 0; /** Interface for accessing last set of poses returned by WaitGetPoses one at a time. * Returns VRCompositorError_IndexOutOfRange if unDeviceIndex not less than k_unMaxTrackedDeviceCount otherwise VRCompositorError_None. * It is okay to pass NULL for either pose if you only want one of the values. */ - virtual EVRCompositorError GetLastPoseForTrackedDeviceIndex( TrackedDeviceIndex_t unDeviceIndex, TrackedDevicePose_t *pOutputPose, TrackedDevicePose_t *pOutputGamePose ) = 0; + virtual EVRCompositorError GetLastPoseForTrackedDeviceIndex(TrackedDeviceIndex_t unDeviceIndex, TrackedDevicePose_t *pOutputPose, TrackedDevicePose_t *pOutputGamePose) = 0; /** Updated scene texture to display. If pBounds is NULL the entire texture will be used. If called from an OpenGL app, consider adding a glFlush after * Submitting both frames to signal the driver to start processing, otherwise it may wait until the command buffer fills up, causing the app to miss frames. @@ -2267,7 +2225,7 @@ public: * - InvalidTexture (usually means bad arguments passed in) * - AlreadySubmitted (app has submitted two left textures or two right textures in a single frame - i.e. before calling WaitGetPoses again) */ - virtual EVRCompositorError Submit( EVREye eEye, const Texture_t *pTexture, const VRTextureBounds_t* pBounds = 0, EVRSubmitFlags nSubmitFlags = Submit_Default ) = 0; + virtual EVRCompositorError Submit(EVREye eEye, const Texture_t *pTexture, const VRTextureBounds_t *pBounds = 0, EVRSubmitFlags nSubmitFlags = Submit_Default) = 0; /** Clears the frame that was sent with the last call to Submit. This will cause the * compositor to show the grid until Submit is called again. */ @@ -2282,29 +2240,29 @@ public: /** Returns true if timing data is filled it. Sets oldest timing info if nFramesAgo is larger than the stored history. * Be sure to set timing.size = sizeof(Compositor_FrameTiming) on struct passed in before calling this function. */ - virtual bool GetFrameTiming( Compositor_FrameTiming *pTiming, uint32_t unFramesAgo = 0 ) = 0; + virtual bool GetFrameTiming(Compositor_FrameTiming *pTiming, uint32_t unFramesAgo = 0) = 0; /** Interface for copying a range of timing data. Frames are returned in ascending order (oldest to newest) with the last being the most recent frame. * Only the first entry's m_nSize needs to be set, as the rest will be inferred from that. Returns total number of entries filled out. */ - virtual uint32_t GetFrameTimings( Compositor_FrameTiming *pTiming, uint32_t nFrames ) = 0; + virtual uint32_t GetFrameTimings(Compositor_FrameTiming *pTiming, uint32_t nFrames) = 0; /** Returns the time in seconds left in the current (as identified by FrameTiming's frameIndex) frame. * Due to "running start", this value may roll over to the next frame before ever reaching 0.0. */ virtual float GetFrameTimeRemaining() = 0; /** Fills out stats accumulated for the last connected application. Pass in sizeof( Compositor_CumulativeStats ) as second parameter. */ - virtual void GetCumulativeStats( Compositor_CumulativeStats *pStats, uint32_t nStatsSizeInBytes ) = 0; + virtual void GetCumulativeStats(Compositor_CumulativeStats *pStats, uint32_t nStatsSizeInBytes) = 0; /** Fades the view on the HMD to the specified color. The fade will take fSeconds, and the color values are between * 0.0 and 1.0. This color is faded on top of the scene based on the alpha parameter. Removing the fade color instantly * would be FadeToColor( 0.0, 0.0, 0.0, 0.0, 0.0 ). Values are in un-premultiplied alpha space. */ - virtual void FadeToColor( float fSeconds, float fRed, float fGreen, float fBlue, float fAlpha, bool bBackground = false ) = 0; + virtual void FadeToColor(float fSeconds, float fRed, float fGreen, float fBlue, float fAlpha, bool bBackground = false) = 0; /** Get current fade color value. */ - virtual HmdColor_t GetCurrentFadeColor( bool bBackground = false ) = 0; + virtual HmdColor_t GetCurrentFadeColor(bool bBackground = false) = 0; /** Fading the Grid in or out in fSeconds */ - virtual void FadeGrid( float fSeconds, bool bFadeIn ) = 0; + virtual void FadeGrid(float fSeconds, bool bFadeIn) = 0; /** Get current alpha value of grid. */ virtual float GetCurrentGridAlpha() = 0; @@ -2312,7 +2270,7 @@ public: /** Override the skybox used in the compositor (e.g. for during level loads when the app can't feed scene images fast enough) * Order is Front, Back, Left, Right, Top, Bottom. If only a single texture is passed, it is assumed in lat-long format. * If two are passed, it is assumed a lat-long stereo pair. */ - virtual EVRCompositorError SetSkyboxOverride( VR_ARRAY_COUNT( unTextureCount ) const Texture_t *pTextures, uint32_t unTextureCount ) = 0; + virtual EVRCompositorError SetSkyboxOverride(VR_ARRAY_COUNT(unTextureCount) const Texture_t *pTextures, uint32_t unTextureCount) = 0; /** Resets compositor skybox back to defaults. */ virtual void ClearSkyboxOverride() = 0; @@ -2327,7 +2285,7 @@ public: /** Tells the compositor process to clean up and exit. You do not need to call this function at shutdown. Under normal * circumstances the compositor will manage its own life cycle based on what applications are running. */ virtual void CompositorQuit() = 0; - + /** Return whether the compositor is fullscreen */ virtual bool IsFullscreen() = 0; @@ -2357,34 +2315,34 @@ public: virtual bool ShouldAppRenderWithLowResources() = 0; /** Override interleaved reprojection logic to force on. */ - virtual void ForceInterleavedReprojectionOn( bool bOverride ) = 0; + virtual void ForceInterleavedReprojectionOn(bool bOverride) = 0; /** Force reconnecting to the compositor process. */ virtual void ForceReconnectProcess() = 0; /** Temporarily suspends rendering (useful for finer control over scene transitions). */ - virtual void SuspendRendering( bool bSuspend ) = 0; + virtual void SuspendRendering(bool bSuspend) = 0; /** Opens a shared D3D11 texture with the undistorted composited image for each eye. Use ReleaseMirrorTextureD3D11 when finished * instead of calling Release on the resource itself. */ - virtual vr::EVRCompositorError GetMirrorTextureD3D11( vr::EVREye eEye, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView ) = 0; - virtual void ReleaseMirrorTextureD3D11( void *pD3D11ShaderResourceView ) = 0; + virtual vr::EVRCompositorError GetMirrorTextureD3D11(vr::EVREye eEye, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView) = 0; + virtual void ReleaseMirrorTextureD3D11(void *pD3D11ShaderResourceView) = 0; /** Access to mirror textures from OpenGL. */ - virtual vr::EVRCompositorError GetMirrorTextureGL( vr::EVREye eEye, vr::glUInt_t *pglTextureId, vr::glSharedTextureHandle_t *pglSharedTextureHandle ) = 0; - virtual bool ReleaseSharedGLTexture( vr::glUInt_t glTextureId, vr::glSharedTextureHandle_t glSharedTextureHandle ) = 0; - virtual void LockGLSharedTextureForAccess( vr::glSharedTextureHandle_t glSharedTextureHandle ) = 0; - virtual void UnlockGLSharedTextureForAccess( vr::glSharedTextureHandle_t glSharedTextureHandle ) = 0; + virtual vr::EVRCompositorError GetMirrorTextureGL(vr::EVREye eEye, vr::glUInt_t *pglTextureId, vr::glSharedTextureHandle_t *pglSharedTextureHandle) = 0; + virtual bool ReleaseSharedGLTexture(vr::glUInt_t glTextureId, vr::glSharedTextureHandle_t glSharedTextureHandle) = 0; + virtual void LockGLSharedTextureForAccess(vr::glSharedTextureHandle_t glSharedTextureHandle) = 0; + virtual void UnlockGLSharedTextureForAccess(vr::glSharedTextureHandle_t glSharedTextureHandle) = 0; /** [Vulkan Only] * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. The string will be a space separated list of-required instance extensions to enable in VkCreateInstance */ - virtual uint32_t GetVulkanInstanceExtensionsRequired( VR_OUT_STRING() char *pchValue, uint32_t unBufferSize ) = 0; + virtual uint32_t GetVulkanInstanceExtensionsRequired(VR_OUT_STRING() char *pchValue, uint32_t unBufferSize) = 0; /** [Vulkan only] * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. The string will be a space separated list of required device extensions to enable in VkCreateDevice */ - virtual uint32_t GetVulkanDeviceExtensionsRequired( VkPhysicalDevice_T *pPhysicalDevice, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize ) = 0; + virtual uint32_t GetVulkanDeviceExtensionsRequired(VkPhysicalDevice_T *pPhysicalDevice, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize) = 0; /** [ Vulkan/D3D12 Only ] * There are two purposes for SetExplicitTimingMode: @@ -2404,7 +2362,7 @@ public: * application calls PostPresentHandoff, then WaitGetPoses is guaranteed not to access the queue. Note that PostPresentHandoff * and SubmitExplicitTimingData will access the queue, so only WaitGetPoses becomes safe for accessing the queue from another * thread. */ - virtual void SetExplicitTimingMode( bool bExplicitTimingMode ) = 0; + virtual void SetExplicitTimingMode(bool bExplicitTimingMode) = 0; /** [ Vulkan/D3D12 Only ] * Submit explicit timing data. When SetExplicitTimingMode is true, this must be called immediately before @@ -2415,28 +2373,20 @@ public: virtual EVRCompositorError SubmitExplicitTimingData() = 0; }; -static const char * const IVRCompositor_Version = "IVRCompositor_021"; - -} // namespace vr - +static const char *const IVRCompositor_Version = "IVRCompositor_021"; +} // namespace vr // ivrnotifications.h namespace vr { - -#pragma pack( push, 8 ) +#pragma pack(push, 8) // Used for passing graphic data struct NotificationBitmap_t { NotificationBitmap_t() - : m_pImageData( nullptr ) - , m_nWidth( 0 ) - , m_nHeight( 0 ) - , m_nBytesPerPixel( 0 ) - { - }; + : m_pImageData(nullptr), m_nWidth(0), m_nHeight(0), m_nBytesPerPixel(0){}; void *m_pImageData; int32_t m_nWidth; @@ -2444,7 +2394,6 @@ struct NotificationBitmap_t int32_t m_nBytesPerPixel; }; - /** Be aware that the notification type is used as 'priority' to pick the next notification */ enum EVRNotificationType { @@ -2484,9 +2433,7 @@ static const uint32_t k_unNotificationTextMaxSize = 256; typedef uint32_t VRNotificationId; - - -#pragma pack( pop ) +#pragma pack(pop) /** Allows notification sources to interact with the VR system This current interface is not yet implemented. Do not use yet. */ @@ -2497,267 +2444,261 @@ public: * An overlay handle is required to create a notification, as otherwise it would be impossible for a user to act on it. * To create a two-line notification, use a line break ('\n') to split the text into two lines. * The pImage argument may be NULL, in which case the specified overlay's icon will be used instead. */ - virtual EVRNotificationError CreateNotification( VROverlayHandle_t ulOverlayHandle, uint64_t ulUserValue, EVRNotificationType type, const char *pchText, EVRNotificationStyle style, const NotificationBitmap_t *pImage, /* out */ VRNotificationId *pNotificationId ) = 0; + virtual EVRNotificationError CreateNotification(VROverlayHandle_t ulOverlayHandle, uint64_t ulUserValue, EVRNotificationType type, const char *pchText, EVRNotificationStyle style, const NotificationBitmap_t *pImage, /* out */ VRNotificationId *pNotificationId) = 0; /** Destroy a notification, hiding it first if it currently shown to the user. */ - virtual EVRNotificationError RemoveNotification( VRNotificationId notificationId ) = 0; - + virtual EVRNotificationError RemoveNotification(VRNotificationId notificationId) = 0; }; -static const char * const IVRNotifications_Version = "IVRNotifications_002"; - -} // namespace vr - +static const char *const IVRNotifications_Version = "IVRNotifications_002"; +} // namespace vr // ivroverlay.h namespace vr { +/** The maximum length of an overlay key in bytes, counting the terminating null character. */ +static const uint32_t k_unVROverlayMaxKeyLength = 128; - /** The maximum length of an overlay key in bytes, counting the terminating null character. */ - static const uint32_t k_unVROverlayMaxKeyLength = 128; +/** The maximum length of an overlay name in bytes, counting the terminating null character. */ +static const uint32_t k_unVROverlayMaxNameLength = 128; - /** The maximum length of an overlay name in bytes, counting the terminating null character. */ - static const uint32_t k_unVROverlayMaxNameLength = 128; +/** The maximum number of overlays that can exist in the system at one time. */ +static const uint32_t k_unMaxOverlayCount = 64; - /** The maximum number of overlays that can exist in the system at one time. */ - static const uint32_t k_unMaxOverlayCount = 64; +/** The maximum number of overlay intersection mask primitives per overlay */ +static const uint32_t k_unMaxOverlayIntersectionMaskPrimitivesCount = 32; - /** The maximum number of overlay intersection mask primitives per overlay */ - static const uint32_t k_unMaxOverlayIntersectionMaskPrimitivesCount = 32; +/** Types of input supported by VR Overlays */ +enum VROverlayInputMethod +{ + VROverlayInputMethod_None = 0, // No input events will be generated automatically for this overlay + VROverlayInputMethod_Mouse = 1, // Tracked controllers will get mouse events automatically +}; - /** Types of input supported by VR Overlays */ - enum VROverlayInputMethod - { - VROverlayInputMethod_None = 0, // No input events will be generated automatically for this overlay - VROverlayInputMethod_Mouse = 1, // Tracked controllers will get mouse events automatically - }; +/** Allows the caller to figure out which overlay transform getter to call. */ +enum VROverlayTransformType +{ + VROverlayTransform_Absolute = 0, + VROverlayTransform_TrackedDeviceRelative = 1, + VROverlayTransform_SystemOverlay = 2, + VROverlayTransform_TrackedComponent = 3, +}; - /** Allows the caller to figure out which overlay transform getter to call. */ - enum VROverlayTransformType - { - VROverlayTransform_Absolute = 0, - VROverlayTransform_TrackedDeviceRelative = 1, - VROverlayTransform_SystemOverlay = 2, - VROverlayTransform_TrackedComponent = 3, - }; +/** Overlay control settings */ +enum VROverlayFlags +{ + VROverlayFlags_None = 0, - /** Overlay control settings */ - enum VROverlayFlags - { - VROverlayFlags_None = 0, + // The following only take effect when rendered using the high quality render path (see SetHighQualityOverlay). + VROverlayFlags_Curved = 1, + VROverlayFlags_RGSS4X = 2, - // The following only take effect when rendered using the high quality render path (see SetHighQualityOverlay). - VROverlayFlags_Curved = 1, - VROverlayFlags_RGSS4X = 2, + // Set this flag on a dashboard overlay to prevent a tab from showing up for that overlay + VROverlayFlags_NoDashboardTab = 3, - // Set this flag on a dashboard overlay to prevent a tab from showing up for that overlay - VROverlayFlags_NoDashboardTab = 3, + // Set this flag on a dashboard that is able to deal with gamepad focus events + VROverlayFlags_AcceptsGamepadEvents = 4, - // Set this flag on a dashboard that is able to deal with gamepad focus events - VROverlayFlags_AcceptsGamepadEvents = 4, + // Indicates that the overlay should dim/brighten to show gamepad focus + VROverlayFlags_ShowGamepadFocus = 5, - // Indicates that the overlay should dim/brighten to show gamepad focus - VROverlayFlags_ShowGamepadFocus = 5, + // When in VROverlayInputMethod_Mouse you can optionally enable sending VRScroll_t + VROverlayFlags_SendVRScrollEvents = 6, + VROverlayFlags_SendVRTouchpadEvents = 7, - // When in VROverlayInputMethod_Mouse you can optionally enable sending VRScroll_t - VROverlayFlags_SendVRScrollEvents = 6, - VROverlayFlags_SendVRTouchpadEvents = 7, + // If set this will render a vertical scroll wheel on the primary controller, + // only needed if not using VROverlayFlags_SendVRScrollEvents but you still want to represent a scroll wheel + VROverlayFlags_ShowTouchPadScrollWheel = 8, - // If set this will render a vertical scroll wheel on the primary controller, - // only needed if not using VROverlayFlags_SendVRScrollEvents but you still want to represent a scroll wheel - VROverlayFlags_ShowTouchPadScrollWheel = 8, + // If this is set ownership and render access to the overlay are transferred + // to the new scene process on a call to IVRApplications::LaunchInternalProcess + VROverlayFlags_TransferOwnershipToInternalProcess = 9, - // If this is set ownership and render access to the overlay are transferred - // to the new scene process on a call to IVRApplications::LaunchInternalProcess - VROverlayFlags_TransferOwnershipToInternalProcess = 9, + // If set, renders 50% of the texture in each eye, side by side + VROverlayFlags_SideBySide_Parallel = 10, // Texture is left/right + VROverlayFlags_SideBySide_Crossed = 11, // Texture is crossed and right/left - // If set, renders 50% of the texture in each eye, side by side - VROverlayFlags_SideBySide_Parallel = 10, // Texture is left/right - VROverlayFlags_SideBySide_Crossed = 11, // Texture is crossed and right/left + VROverlayFlags_Panorama = 12, // Texture is a panorama + VROverlayFlags_StereoPanorama = 13, // Texture is a stereo panorama - VROverlayFlags_Panorama = 12, // Texture is a panorama - VROverlayFlags_StereoPanorama = 13, // Texture is a stereo panorama + // If this is set on an overlay owned by the scene application that overlay + // will be sorted with the "Other" overlays on top of all other scene overlays + VROverlayFlags_SortWithNonSceneOverlays = 14, - // If this is set on an overlay owned by the scene application that overlay - // will be sorted with the "Other" overlays on top of all other scene overlays - VROverlayFlags_SortWithNonSceneOverlays = 14, + // If set, the overlay will be shown in the dashboard, otherwise it will be hidden. + VROverlayFlags_VisibleInDashboard = 15, +}; - // If set, the overlay will be shown in the dashboard, otherwise it will be hidden. - VROverlayFlags_VisibleInDashboard = 15, - }; +enum VRMessageOverlayResponse +{ + VRMessageOverlayResponse_ButtonPress_0 = 0, + VRMessageOverlayResponse_ButtonPress_1 = 1, + VRMessageOverlayResponse_ButtonPress_2 = 2, + VRMessageOverlayResponse_ButtonPress_3 = 3, + VRMessageOverlayResponse_CouldntFindSystemOverlay = 4, + VRMessageOverlayResponse_CouldntFindOrCreateClientOverlay = 5, + VRMessageOverlayResponse_ApplicationQuit = 6 +}; - enum VRMessageOverlayResponse - { - VRMessageOverlayResponse_ButtonPress_0 = 0, - VRMessageOverlayResponse_ButtonPress_1 = 1, - VRMessageOverlayResponse_ButtonPress_2 = 2, - VRMessageOverlayResponse_ButtonPress_3 = 3, - VRMessageOverlayResponse_CouldntFindSystemOverlay = 4, - VRMessageOverlayResponse_CouldntFindOrCreateClientOverlay= 5, - VRMessageOverlayResponse_ApplicationQuit = 6 - }; +struct VROverlayIntersectionParams_t +{ + HmdVector3_t vSource; + HmdVector3_t vDirection; + ETrackingUniverseOrigin eOrigin; +}; - struct VROverlayIntersectionParams_t - { - HmdVector3_t vSource; - HmdVector3_t vDirection; - ETrackingUniverseOrigin eOrigin; - }; +struct VROverlayIntersectionResults_t +{ + HmdVector3_t vPoint; + HmdVector3_t vNormal; + HmdVector2_t vUVs; + float fDistance; +}; - struct VROverlayIntersectionResults_t - { - HmdVector3_t vPoint; - HmdVector3_t vNormal; - HmdVector2_t vUVs; - float fDistance; - }; +// Input modes for the Big Picture gamepad text entry +enum EGamepadTextInputMode +{ + k_EGamepadTextInputModeNormal = 0, + k_EGamepadTextInputModePassword = 1, + k_EGamepadTextInputModeSubmit = 2, +}; - // Input modes for the Big Picture gamepad text entry - enum EGamepadTextInputMode - { - k_EGamepadTextInputModeNormal = 0, - k_EGamepadTextInputModePassword = 1, - k_EGamepadTextInputModeSubmit = 2, - }; +// Controls number of allowed lines for the Big Picture gamepad text entry +enum EGamepadTextInputLineMode +{ + k_EGamepadTextInputLineModeSingleLine = 0, + k_EGamepadTextInputLineModeMultipleLines = 1 +}; - // Controls number of allowed lines for the Big Picture gamepad text entry - enum EGamepadTextInputLineMode - { - k_EGamepadTextInputLineModeSingleLine = 0, - k_EGamepadTextInputLineModeMultipleLines = 1 - }; +/** Directions for changing focus between overlays with the gamepad */ +enum EOverlayDirection +{ + OverlayDirection_Up = 0, + OverlayDirection_Down = 1, + OverlayDirection_Left = 2, + OverlayDirection_Right = 3, - /** Directions for changing focus between overlays with the gamepad */ - enum EOverlayDirection - { - OverlayDirection_Up = 0, - OverlayDirection_Down = 1, - OverlayDirection_Left = 2, - OverlayDirection_Right = 3, - - OverlayDirection_Count = 4, - }; + OverlayDirection_Count = 4, +}; - enum EVROverlayIntersectionMaskPrimitiveType - { - OverlayIntersectionPrimitiveType_Rectangle, - OverlayIntersectionPrimitiveType_Circle, - }; +enum EVROverlayIntersectionMaskPrimitiveType +{ + OverlayIntersectionPrimitiveType_Rectangle, + OverlayIntersectionPrimitiveType_Circle, +}; - struct IntersectionMaskRectangle_t - { - float m_flTopLeftX; - float m_flTopLeftY; - float m_flWidth; - float m_flHeight; - }; +struct IntersectionMaskRectangle_t +{ + float m_flTopLeftX; + float m_flTopLeftY; + float m_flWidth; + float m_flHeight; +}; - struct IntersectionMaskCircle_t - { - float m_flCenterX; - float m_flCenterY; - float m_flRadius; - }; +struct IntersectionMaskCircle_t +{ + float m_flCenterX; + float m_flCenterY; + float m_flRadius; +}; - /** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py and openvr_api_flat.h.py */ - typedef union - { - IntersectionMaskRectangle_t m_Rectangle; - IntersectionMaskCircle_t m_Circle; - } VROverlayIntersectionMaskPrimitive_Data_t; +/** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py and openvr_api_flat.h.py */ +typedef union { + IntersectionMaskRectangle_t m_Rectangle; + IntersectionMaskCircle_t m_Circle; +} VROverlayIntersectionMaskPrimitive_Data_t; - struct VROverlayIntersectionMaskPrimitive_t - { - EVROverlayIntersectionMaskPrimitiveType m_nPrimitiveType; - VROverlayIntersectionMaskPrimitive_Data_t m_Primitive; - }; +struct VROverlayIntersectionMaskPrimitive_t +{ + EVROverlayIntersectionMaskPrimitiveType m_nPrimitiveType; + VROverlayIntersectionMaskPrimitive_Data_t m_Primitive; +}; - class IVROverlay - { - public: +class IVROverlay +{ +public: + // --------------------------------------------- + // Overlay management methods + // --------------------------------------------- - // --------------------------------------------- - // Overlay management methods - // --------------------------------------------- + /** Finds an existing overlay with the specified key. */ + virtual EVROverlayError FindOverlay(const char *pchOverlayKey, VROverlayHandle_t *pOverlayHandle) = 0; - /** Finds an existing overlay with the specified key. */ - virtual EVROverlayError FindOverlay( const char *pchOverlayKey, VROverlayHandle_t * pOverlayHandle ) = 0; + /** Creates a new named overlay. All overlays start hidden and with default settings. */ + virtual EVROverlayError CreateOverlay(const char *pchOverlayKey, const char *pchOverlayName, VROverlayHandle_t *pOverlayHandle) = 0; - /** Creates a new named overlay. All overlays start hidden and with default settings. */ - virtual EVROverlayError CreateOverlay( const char *pchOverlayKey, const char *pchOverlayName, VROverlayHandle_t * pOverlayHandle ) = 0; - - /** Destroys the specified overlay. When an application calls VR_Shutdown all overlays created by that app are + /** Destroys the specified overlay. When an application calls VR_Shutdown all overlays created by that app are * automatically destroyed. */ - virtual EVROverlayError DestroyOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + virtual EVROverlayError DestroyOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Specify which overlay to use the high quality render path. This overlay will be composited in during the distortion pass which + /** Specify which overlay to use the high quality render path. This overlay will be composited in during the distortion pass which * results in it drawing on top of everything else, but also at a higher quality as it samples the source texture directly rather than * rasterizing into each eye's render texture first. Because if this, only one of these is supported at any given time. It is most useful * for overlays that are expected to take up most of the user's view (e.g. streaming video). * This mode does not support mouse input to your overlay. */ - virtual EVROverlayError SetHighQualityOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + virtual EVROverlayError SetHighQualityOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Returns the overlay handle of the current overlay being rendered using the single high quality overlay render path. + /** Returns the overlay handle of the current overlay being rendered using the single high quality overlay render path. * Otherwise it will return k_ulOverlayHandleInvalid. */ - virtual vr::VROverlayHandle_t GetHighQualityOverlay() = 0; + virtual vr::VROverlayHandle_t GetHighQualityOverlay() = 0; - /** Fills the provided buffer with the string key of the overlay. Returns the size of buffer required to store the key, including + /** Fills the provided buffer with the string key of the overlay. Returns the size of buffer required to store the key, including * the terminating null character. k_unVROverlayMaxKeyLength will be enough bytes to fit the string. */ - virtual uint32_t GetOverlayKey( VROverlayHandle_t ulOverlayHandle, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, EVROverlayError *pError = 0L ) = 0; + virtual uint32_t GetOverlayKey(VROverlayHandle_t ulOverlayHandle, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, EVROverlayError *pError = 0L) = 0; - /** Fills the provided buffer with the friendly name of the overlay. Returns the size of buffer required to store the key, including + /** Fills the provided buffer with the friendly name of the overlay. Returns the size of buffer required to store the key, including * the terminating null character. k_unVROverlayMaxNameLength will be enough bytes to fit the string. */ - virtual uint32_t GetOverlayName( VROverlayHandle_t ulOverlayHandle, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, EVROverlayError *pError = 0L ) = 0; + virtual uint32_t GetOverlayName(VROverlayHandle_t ulOverlayHandle, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, EVROverlayError *pError = 0L) = 0; - /** set the name to use for this overlay */ - virtual EVROverlayError SetOverlayName( VROverlayHandle_t ulOverlayHandle, const char *pchName ) = 0; + /** set the name to use for this overlay */ + virtual EVROverlayError SetOverlayName(VROverlayHandle_t ulOverlayHandle, const char *pchName) = 0; - /** Gets the raw image data from an overlay. Overlay image data is always returned as RGBA data, 4 bytes per pixel. If the buffer is not large enough, width and height + /** Gets the raw image data from an overlay. Overlay image data is always returned as RGBA data, 4 bytes per pixel. If the buffer is not large enough, width and height * will be set and VROverlayError_ArrayTooSmall is returned. */ - virtual EVROverlayError GetOverlayImageData( VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unBufferSize, uint32_t *punWidth, uint32_t *punHeight ) = 0; + virtual EVROverlayError GetOverlayImageData(VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unBufferSize, uint32_t *punWidth, uint32_t *punHeight) = 0; - /** returns a string that corresponds with the specified overlay error. The string will be the name + /** returns a string that corresponds with the specified overlay error. The string will be the name * of the error enum value for all valid error codes */ - virtual const char *GetOverlayErrorNameFromEnum( EVROverlayError error ) = 0; + virtual const char *GetOverlayErrorNameFromEnum(EVROverlayError error) = 0; - // --------------------------------------------- - // Overlay rendering methods - // --------------------------------------------- + // --------------------------------------------- + // Overlay rendering methods + // --------------------------------------------- - /** Sets the pid that is allowed to render to this overlay (the creator pid is always allow to render), + /** Sets the pid that is allowed to render to this overlay (the creator pid is always allow to render), * by default this is the pid of the process that made the overlay */ - virtual EVROverlayError SetOverlayRenderingPid( VROverlayHandle_t ulOverlayHandle, uint32_t unPID ) = 0; + virtual EVROverlayError SetOverlayRenderingPid(VROverlayHandle_t ulOverlayHandle, uint32_t unPID) = 0; - /** Gets the pid that is allowed to render to this overlay */ - virtual uint32_t GetOverlayRenderingPid( VROverlayHandle_t ulOverlayHandle ) = 0; + /** Gets the pid that is allowed to render to this overlay */ + virtual uint32_t GetOverlayRenderingPid(VROverlayHandle_t ulOverlayHandle) = 0; - /** Specify flag setting for a given overlay */ - virtual EVROverlayError SetOverlayFlag( VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool bEnabled ) = 0; + /** Specify flag setting for a given overlay */ + virtual EVROverlayError SetOverlayFlag(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool bEnabled) = 0; - /** Sets flag setting for a given overlay */ - virtual EVROverlayError GetOverlayFlag( VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool *pbEnabled ) = 0; + /** Sets flag setting for a given overlay */ + virtual EVROverlayError GetOverlayFlag(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool *pbEnabled) = 0; - /** Sets the color tint of the overlay quad. Use 0.0 to 1.0 per channel. */ - virtual EVROverlayError SetOverlayColor( VROverlayHandle_t ulOverlayHandle, float fRed, float fGreen, float fBlue ) = 0; + /** Sets the color tint of the overlay quad. Use 0.0 to 1.0 per channel. */ + virtual EVROverlayError SetOverlayColor(VROverlayHandle_t ulOverlayHandle, float fRed, float fGreen, float fBlue) = 0; - /** Gets the color tint of the overlay quad. */ - virtual EVROverlayError GetOverlayColor( VROverlayHandle_t ulOverlayHandle, float *pfRed, float *pfGreen, float *pfBlue ) = 0; + /** Gets the color tint of the overlay quad. */ + virtual EVROverlayError GetOverlayColor(VROverlayHandle_t ulOverlayHandle, float *pfRed, float *pfGreen, float *pfBlue) = 0; - /** Sets the alpha of the overlay quad. Use 1.0 for 100 percent opacity to 0.0 for 0 percent opacity. */ - virtual EVROverlayError SetOverlayAlpha( VROverlayHandle_t ulOverlayHandle, float fAlpha ) = 0; + /** Sets the alpha of the overlay quad. Use 1.0 for 100 percent opacity to 0.0 for 0 percent opacity. */ + virtual EVROverlayError SetOverlayAlpha(VROverlayHandle_t ulOverlayHandle, float fAlpha) = 0; - /** Gets the alpha of the overlay quad. By default overlays are rendering at 100 percent alpha (1.0). */ - virtual EVROverlayError GetOverlayAlpha( VROverlayHandle_t ulOverlayHandle, float *pfAlpha ) = 0; + /** Gets the alpha of the overlay quad. By default overlays are rendering at 100 percent alpha (1.0). */ + virtual EVROverlayError GetOverlayAlpha(VROverlayHandle_t ulOverlayHandle, float *pfAlpha) = 0; - /** Sets the aspect ratio of the texels in the overlay. 1.0 means the texels are square. 2.0 means the texels + /** Sets the aspect ratio of the texels in the overlay. 1.0 means the texels are square. 2.0 means the texels * are twice as wide as they are tall. Defaults to 1.0. */ - virtual EVROverlayError SetOverlayTexelAspect( VROverlayHandle_t ulOverlayHandle, float fTexelAspect ) = 0; + virtual EVROverlayError SetOverlayTexelAspect(VROverlayHandle_t ulOverlayHandle, float fTexelAspect) = 0; - /** Gets the aspect ratio of the texels in the overlay. Defaults to 1.0 */ - virtual EVROverlayError GetOverlayTexelAspect( VROverlayHandle_t ulOverlayHandle, float *pfTexelAspect ) = 0; + /** Gets the aspect ratio of the texels in the overlay. Defaults to 1.0 */ + virtual EVROverlayError GetOverlayTexelAspect(VROverlayHandle_t ulOverlayHandle, float *pfTexelAspect) = 0; - /** Sets the rendering sort order for the overlay. Overlays are rendered this order: + /** Sets the rendering sort order for the overlay. Overlays are rendered this order: * Overlays owned by the scene application * Overlays owned by some other application * @@ -2765,160 +2706,160 @@ namespace vr * sort order are rendered back to front base on distance from the HMD. * * Sort order defaults to 0. */ - virtual EVROverlayError SetOverlaySortOrder( VROverlayHandle_t ulOverlayHandle, uint32_t unSortOrder ) = 0; + virtual EVROverlayError SetOverlaySortOrder(VROverlayHandle_t ulOverlayHandle, uint32_t unSortOrder) = 0; - /** Gets the sort order of the overlay. See SetOverlaySortOrder for how this works. */ - virtual EVROverlayError GetOverlaySortOrder( VROverlayHandle_t ulOverlayHandle, uint32_t *punSortOrder ) = 0; + /** Gets the sort order of the overlay. See SetOverlaySortOrder for how this works. */ + virtual EVROverlayError GetOverlaySortOrder(VROverlayHandle_t ulOverlayHandle, uint32_t *punSortOrder) = 0; - /** Sets the width of the overlay quad in meters. By default overlays are rendered on a quad that is 1 meter across */ - virtual EVROverlayError SetOverlayWidthInMeters( VROverlayHandle_t ulOverlayHandle, float fWidthInMeters ) = 0; + /** Sets the width of the overlay quad in meters. By default overlays are rendered on a quad that is 1 meter across */ + virtual EVROverlayError SetOverlayWidthInMeters(VROverlayHandle_t ulOverlayHandle, float fWidthInMeters) = 0; - /** Returns the width of the overlay quad in meters. By default overlays are rendered on a quad that is 1 meter across */ - virtual EVROverlayError GetOverlayWidthInMeters( VROverlayHandle_t ulOverlayHandle, float *pfWidthInMeters ) = 0; + /** Returns the width of the overlay quad in meters. By default overlays are rendered on a quad that is 1 meter across */ + virtual EVROverlayError GetOverlayWidthInMeters(VROverlayHandle_t ulOverlayHandle, float *pfWidthInMeters) = 0; - /** For high-quality curved overlays only, sets the distance range in meters from the overlay used to automatically curve + /** For high-quality curved overlays only, sets the distance range in meters from the overlay used to automatically curve * the surface around the viewer. Min is distance is when the surface will be most curved. Max is when least curved. */ - virtual EVROverlayError SetOverlayAutoCurveDistanceRangeInMeters( VROverlayHandle_t ulOverlayHandle, float fMinDistanceInMeters, float fMaxDistanceInMeters ) = 0; + virtual EVROverlayError SetOverlayAutoCurveDistanceRangeInMeters(VROverlayHandle_t ulOverlayHandle, float fMinDistanceInMeters, float fMaxDistanceInMeters) = 0; - /** For high-quality curved overlays only, gets the distance range in meters from the overlay used to automatically curve + /** For high-quality curved overlays only, gets the distance range in meters from the overlay used to automatically curve * the surface around the viewer. Min is distance is when the surface will be most curved. Max is when least curved. */ - virtual EVROverlayError GetOverlayAutoCurveDistanceRangeInMeters( VROverlayHandle_t ulOverlayHandle, float *pfMinDistanceInMeters, float *pfMaxDistanceInMeters ) = 0; + virtual EVROverlayError GetOverlayAutoCurveDistanceRangeInMeters(VROverlayHandle_t ulOverlayHandle, float *pfMinDistanceInMeters, float *pfMaxDistanceInMeters) = 0; - /** Sets the colorspace the overlay texture's data is in. Defaults to 'auto'. + /** Sets the colorspace the overlay texture's data is in. Defaults to 'auto'. * If the texture needs to be resolved, you should call SetOverlayTexture with the appropriate colorspace instead. */ - virtual EVROverlayError SetOverlayTextureColorSpace( VROverlayHandle_t ulOverlayHandle, EColorSpace eTextureColorSpace ) = 0; + virtual EVROverlayError SetOverlayTextureColorSpace(VROverlayHandle_t ulOverlayHandle, EColorSpace eTextureColorSpace) = 0; - /** Gets the overlay's current colorspace setting. */ - virtual EVROverlayError GetOverlayTextureColorSpace( VROverlayHandle_t ulOverlayHandle, EColorSpace *peTextureColorSpace ) = 0; + /** Gets the overlay's current colorspace setting. */ + virtual EVROverlayError GetOverlayTextureColorSpace(VROverlayHandle_t ulOverlayHandle, EColorSpace *peTextureColorSpace) = 0; - /** Sets the part of the texture to use for the overlay. UV Min is the upper left corner and UV Max is the lower right corner. */ - virtual EVROverlayError SetOverlayTextureBounds( VROverlayHandle_t ulOverlayHandle, const VRTextureBounds_t *pOverlayTextureBounds ) = 0; + /** Sets the part of the texture to use for the overlay. UV Min is the upper left corner and UV Max is the lower right corner. */ + virtual EVROverlayError SetOverlayTextureBounds(VROverlayHandle_t ulOverlayHandle, const VRTextureBounds_t *pOverlayTextureBounds) = 0; - /** Gets the part of the texture to use for the overlay. UV Min is the upper left corner and UV Max is the lower right corner. */ - virtual EVROverlayError GetOverlayTextureBounds( VROverlayHandle_t ulOverlayHandle, VRTextureBounds_t *pOverlayTextureBounds ) = 0; + /** Gets the part of the texture to use for the overlay. UV Min is the upper left corner and UV Max is the lower right corner. */ + virtual EVROverlayError GetOverlayTextureBounds(VROverlayHandle_t ulOverlayHandle, VRTextureBounds_t *pOverlayTextureBounds) = 0; - /** Gets render model to draw behind this overlay */ - virtual uint32_t GetOverlayRenderModel( vr::VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, HmdColor_t *pColor, vr::EVROverlayError *pError ) = 0; + /** Gets render model to draw behind this overlay */ + virtual uint32_t GetOverlayRenderModel(vr::VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, HmdColor_t *pColor, vr::EVROverlayError *pError) = 0; - /** Sets render model to draw behind this overlay and the vertex color to use, pass null for pColor to match the overlays vertex color. + /** Sets render model to draw behind this overlay and the vertex color to use, pass null for pColor to match the overlays vertex color. The model is scaled by the same amount as the overlay, with a default of 1m. */ - virtual vr::EVROverlayError SetOverlayRenderModel( vr::VROverlayHandle_t ulOverlayHandle, const char *pchRenderModel, const HmdColor_t *pColor ) = 0; + virtual vr::EVROverlayError SetOverlayRenderModel(vr::VROverlayHandle_t ulOverlayHandle, const char *pchRenderModel, const HmdColor_t *pColor) = 0; - /** Returns the transform type of this overlay. */ - virtual EVROverlayError GetOverlayTransformType( VROverlayHandle_t ulOverlayHandle, VROverlayTransformType *peTransformType ) = 0; + /** Returns the transform type of this overlay. */ + virtual EVROverlayError GetOverlayTransformType(VROverlayHandle_t ulOverlayHandle, VROverlayTransformType *peTransformType) = 0; - /** Sets the transform to absolute tracking origin. */ - virtual EVROverlayError SetOverlayTransformAbsolute( VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, const HmdMatrix34_t *pmatTrackingOriginToOverlayTransform ) = 0; + /** Sets the transform to absolute tracking origin. */ + virtual EVROverlayError SetOverlayTransformAbsolute(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, const HmdMatrix34_t *pmatTrackingOriginToOverlayTransform) = 0; - /** Gets the transform if it is absolute. Returns an error if the transform is some other type. */ - virtual EVROverlayError GetOverlayTransformAbsolute( VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin *peTrackingOrigin, HmdMatrix34_t *pmatTrackingOriginToOverlayTransform ) = 0; + /** Gets the transform if it is absolute. Returns an error if the transform is some other type. */ + virtual EVROverlayError GetOverlayTransformAbsolute(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin *peTrackingOrigin, HmdMatrix34_t *pmatTrackingOriginToOverlayTransform) = 0; - /** Sets the transform to relative to the transform of the specified tracked device. */ - virtual EVROverlayError SetOverlayTransformTrackedDeviceRelative( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unTrackedDevice, const HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform ) = 0; + /** Sets the transform to relative to the transform of the specified tracked device. */ + virtual EVROverlayError SetOverlayTransformTrackedDeviceRelative(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unTrackedDevice, const HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform) = 0; - /** Gets the transform if it is relative to a tracked device. Returns an error if the transform is some other type. */ - virtual EVROverlayError GetOverlayTransformTrackedDeviceRelative( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punTrackedDevice, HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform ) = 0; + /** Gets the transform if it is relative to a tracked device. Returns an error if the transform is some other type. */ + virtual EVROverlayError GetOverlayTransformTrackedDeviceRelative(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punTrackedDevice, HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform) = 0; - /** Sets the transform to draw the overlay on a rendermodel component mesh instead of a quad. This will only draw when the system is + /** Sets the transform to draw the overlay on a rendermodel component mesh instead of a quad. This will only draw when the system is * drawing the device. Overlays with this transform type cannot receive mouse events. */ - virtual EVROverlayError SetOverlayTransformTrackedDeviceComponent( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unDeviceIndex, const char *pchComponentName ) = 0; + virtual EVROverlayError SetOverlayTransformTrackedDeviceComponent(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unDeviceIndex, const char *pchComponentName) = 0; - /** Gets the transform information when the overlay is rendering on a component. */ - virtual EVROverlayError GetOverlayTransformTrackedDeviceComponent( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punDeviceIndex, char *pchComponentName, uint32_t unComponentNameSize ) = 0; + /** Gets the transform information when the overlay is rendering on a component. */ + virtual EVROverlayError GetOverlayTransformTrackedDeviceComponent(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punDeviceIndex, char *pchComponentName, uint32_t unComponentNameSize) = 0; - /** Gets the transform if it is relative to another overlay. Returns an error if the transform is some other type. */ - virtual vr::EVROverlayError GetOverlayTransformOverlayRelative( VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t *ulOverlayHandleParent, HmdMatrix34_t *pmatParentOverlayToOverlayTransform ) = 0; - - /** Sets the transform to relative to the transform of the specified overlay. This overlays visibility will also track the parents visibility */ - virtual vr::EVROverlayError SetOverlayTransformOverlayRelative( VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t ulOverlayHandleParent, const HmdMatrix34_t *pmatParentOverlayToOverlayTransform ) = 0; + /** Gets the transform if it is relative to another overlay. Returns an error if the transform is some other type. */ + virtual vr::EVROverlayError GetOverlayTransformOverlayRelative(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t *ulOverlayHandleParent, HmdMatrix34_t *pmatParentOverlayToOverlayTransform) = 0; - /** Shows the VR overlay. For dashboard overlays, only the Dashboard Manager is allowed to call this. */ - virtual EVROverlayError ShowOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + /** Sets the transform to relative to the transform of the specified overlay. This overlays visibility will also track the parents visibility */ + virtual vr::EVROverlayError SetOverlayTransformOverlayRelative(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t ulOverlayHandleParent, const HmdMatrix34_t *pmatParentOverlayToOverlayTransform) = 0; - /** Hides the VR overlay. For dashboard overlays, only the Dashboard Manager is allowed to call this. */ - virtual EVROverlayError HideOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + /** Shows the VR overlay. For dashboard overlays, only the Dashboard Manager is allowed to call this. */ + virtual EVROverlayError ShowOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Returns true if the overlay is visible. */ - virtual bool IsOverlayVisible( VROverlayHandle_t ulOverlayHandle ) = 0; + /** Hides the VR overlay. For dashboard overlays, only the Dashboard Manager is allowed to call this. */ + virtual EVROverlayError HideOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Get the transform in 3d space associated with a specific 2d point in the overlay's coordinate space (where 0,0 is the lower left). -Z points out of the overlay */ - virtual EVROverlayError GetTransformForOverlayCoordinates( VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, HmdVector2_t coordinatesInOverlay, HmdMatrix34_t *pmatTransform ) = 0; + /** Returns true if the overlay is visible. */ + virtual bool IsOverlayVisible(VROverlayHandle_t ulOverlayHandle) = 0; - // --------------------------------------------- - // Overlay input methods - // --------------------------------------------- + /** Get the transform in 3d space associated with a specific 2d point in the overlay's coordinate space (where 0,0 is the lower left). -Z points out of the overlay */ + virtual EVROverlayError GetTransformForOverlayCoordinates(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, HmdVector2_t coordinatesInOverlay, HmdMatrix34_t *pmatTransform) = 0; - /** Returns true and fills the event with the next event on the overlay's event queue, if there is one. + // --------------------------------------------- + // Overlay input methods + // --------------------------------------------- + + /** Returns true and fills the event with the next event on the overlay's event queue, if there is one. * If there are no events this method returns false. uncbVREvent should be the size in bytes of the VREvent_t struct */ - virtual bool PollNextOverlayEvent( VROverlayHandle_t ulOverlayHandle, VREvent_t *pEvent, uint32_t uncbVREvent ) = 0; + virtual bool PollNextOverlayEvent(VROverlayHandle_t ulOverlayHandle, VREvent_t *pEvent, uint32_t uncbVREvent) = 0; - /** Returns the current input settings for the specified overlay. */ - virtual EVROverlayError GetOverlayInputMethod( VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod *peInputMethod ) = 0; + /** Returns the current input settings for the specified overlay. */ + virtual EVROverlayError GetOverlayInputMethod(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod *peInputMethod) = 0; - /** Sets the input settings for the specified overlay. */ - virtual EVROverlayError SetOverlayInputMethod( VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod eInputMethod ) = 0; + /** Sets the input settings for the specified overlay. */ + virtual EVROverlayError SetOverlayInputMethod(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod eInputMethod) = 0; - /** Gets the mouse scaling factor that is used for mouse events. The actual texture may be a different size, but this is + /** Gets the mouse scaling factor that is used for mouse events. The actual texture may be a different size, but this is * typically the size of the underlying UI in pixels. */ - virtual EVROverlayError GetOverlayMouseScale( VROverlayHandle_t ulOverlayHandle, HmdVector2_t *pvecMouseScale ) = 0; + virtual EVROverlayError GetOverlayMouseScale(VROverlayHandle_t ulOverlayHandle, HmdVector2_t *pvecMouseScale) = 0; - /** Sets the mouse scaling factor that is used for mouse events. The actual texture may be a different size, but this is + /** Sets the mouse scaling factor that is used for mouse events. The actual texture may be a different size, but this is * typically the size of the underlying UI in pixels (not in world space). */ - virtual EVROverlayError SetOverlayMouseScale( VROverlayHandle_t ulOverlayHandle, const HmdVector2_t *pvecMouseScale ) = 0; + virtual EVROverlayError SetOverlayMouseScale(VROverlayHandle_t ulOverlayHandle, const HmdVector2_t *pvecMouseScale) = 0; - /** Computes the overlay-space pixel coordinates of where the ray intersects the overlay with the + /** Computes the overlay-space pixel coordinates of where the ray intersects the overlay with the * specified settings. Returns false if there is no intersection. */ - virtual bool ComputeOverlayIntersection( VROverlayHandle_t ulOverlayHandle, const VROverlayIntersectionParams_t *pParams, VROverlayIntersectionResults_t *pResults ) = 0; + virtual bool ComputeOverlayIntersection(VROverlayHandle_t ulOverlayHandle, const VROverlayIntersectionParams_t *pParams, VROverlayIntersectionResults_t *pResults) = 0; - /** Processes mouse input from the specified controller as though it were a mouse pointed at a compositor overlay with the + /** Processes mouse input from the specified controller as though it were a mouse pointed at a compositor overlay with the * specified settings. The controller is treated like a laser pointer on the -z axis. The point where the laser pointer would * intersect with the overlay is the mouse position, the trigger is left mouse, and the track pad is right mouse. * * Return true if the controller is pointed at the overlay and an event was generated. */ - virtual bool HandleControllerOverlayInteractionAsMouse( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unControllerDeviceIndex ) = 0; + virtual bool HandleControllerOverlayInteractionAsMouse(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unControllerDeviceIndex) = 0; - /** Returns true if the specified overlay is the hover target. An overlay is the hover target when it is the last overlay "moused over" + /** Returns true if the specified overlay is the hover target. An overlay is the hover target when it is the last overlay "moused over" * by the virtual mouse pointer */ - virtual bool IsHoverTargetOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + virtual bool IsHoverTargetOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Returns the current Gamepad focus overlay */ - virtual vr::VROverlayHandle_t GetGamepadFocusOverlay() = 0; + /** Returns the current Gamepad focus overlay */ + virtual vr::VROverlayHandle_t GetGamepadFocusOverlay() = 0; - /** Sets the current Gamepad focus overlay */ - virtual EVROverlayError SetGamepadFocusOverlay( VROverlayHandle_t ulNewFocusOverlay ) = 0; + /** Sets the current Gamepad focus overlay */ + virtual EVROverlayError SetGamepadFocusOverlay(VROverlayHandle_t ulNewFocusOverlay) = 0; - /** Sets an overlay's neighbor. This will also set the neighbor of the "to" overlay + /** Sets an overlay's neighbor. This will also set the neighbor of the "to" overlay * to point back to the "from" overlay. If an overlay's neighbor is set to invalid both * ends will be cleared */ - virtual EVROverlayError SetOverlayNeighbor( EOverlayDirection eDirection, VROverlayHandle_t ulFrom, VROverlayHandle_t ulTo ) = 0; + virtual EVROverlayError SetOverlayNeighbor(EOverlayDirection eDirection, VROverlayHandle_t ulFrom, VROverlayHandle_t ulTo) = 0; - /** Changes the Gamepad focus from one overlay to one of its neighbors. Returns VROverlayError_NoNeighbor if there is no + /** Changes the Gamepad focus from one overlay to one of its neighbors. Returns VROverlayError_NoNeighbor if there is no * neighbor in that direction */ - virtual EVROverlayError MoveGamepadFocusToNeighbor( EOverlayDirection eDirection, VROverlayHandle_t ulFrom ) = 0; + virtual EVROverlayError MoveGamepadFocusToNeighbor(EOverlayDirection eDirection, VROverlayHandle_t ulFrom) = 0; - // --------------------------------------------- - // Overlay texture methods - // --------------------------------------------- + // --------------------------------------------- + // Overlay texture methods + // --------------------------------------------- - /** Texture to draw for the overlay. This function can only be called by the overlay's creator or renderer process (see SetOverlayRenderingPid) . + /** Texture to draw for the overlay. This function can only be called by the overlay's creator or renderer process (see SetOverlayRenderingPid) . * * OpenGL dirty state: * glBindTexture */ - virtual EVROverlayError SetOverlayTexture( VROverlayHandle_t ulOverlayHandle, const Texture_t *pTexture ) = 0; + virtual EVROverlayError SetOverlayTexture(VROverlayHandle_t ulOverlayHandle, const Texture_t *pTexture) = 0; - /** Use this to tell the overlay system to release the texture set for this overlay. */ - virtual EVROverlayError ClearOverlayTexture( VROverlayHandle_t ulOverlayHandle ) = 0; + /** Use this to tell the overlay system to release the texture set for this overlay. */ + virtual EVROverlayError ClearOverlayTexture(VROverlayHandle_t ulOverlayHandle) = 0; - /** Separate interface for providing the data as a stream of bytes, but there is an upper bound on data + /** Separate interface for providing the data as a stream of bytes, but there is an upper bound on data * that can be sent. This function can only be called by the overlay's renderer process. */ - virtual EVROverlayError SetOverlayRaw( VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unWidth, uint32_t unHeight, uint32_t unDepth ) = 0; + virtual EVROverlayError SetOverlayRaw(VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unWidth, uint32_t unHeight, uint32_t unDepth) = 0; - /** Separate interface for providing the image through a filename: can be png or jpg, and should not be bigger than 1920x1080. + /** Separate interface for providing the image through a filename: can be png or jpg, and should not be bigger than 1920x1080. * This function can only be called by the overlay's renderer process */ - virtual EVROverlayError SetOverlayFromFile( VROverlayHandle_t ulOverlayHandle, const char *pchFilePath ) = 0; + virtual EVROverlayError SetOverlayFromFile(VROverlayHandle_t ulOverlayHandle, const char *pchFilePath) = 0; - /** Get the native texture handle/device for an overlay you have created. + /** Get the native texture handle/device for an overlay you have created. * On windows this handle will be a ID3D11ShaderResourceView with a ID3D11Texture2D bound. * * The texture will always be sized to match the backing texture you supplied in SetOverlayTexture above. @@ -2928,98 +2869,97 @@ namespace vr * pNativeTextureHandle is an OUTPUT, it will be a pointer to a ID3D11ShaderResourceView *. * pNativeTextureRef is an INPUT and should be a ID3D11Resource *. The device used by pNativeTextureRef will be used to bind pNativeTextureHandle. */ - virtual EVROverlayError GetOverlayTexture( VROverlayHandle_t ulOverlayHandle, void **pNativeTextureHandle, void *pNativeTextureRef, uint32_t *pWidth, uint32_t *pHeight, uint32_t *pNativeFormat, ETextureType *pAPIType, EColorSpace *pColorSpace, VRTextureBounds_t *pTextureBounds ) = 0; + virtual EVROverlayError GetOverlayTexture(VROverlayHandle_t ulOverlayHandle, void **pNativeTextureHandle, void *pNativeTextureRef, uint32_t *pWidth, uint32_t *pHeight, uint32_t *pNativeFormat, ETextureType *pAPIType, EColorSpace *pColorSpace, VRTextureBounds_t *pTextureBounds) = 0; - /** Release the pNativeTextureHandle provided from the GetOverlayTexture call, this allows the system to free the underlying GPU resources for this object, + /** Release the pNativeTextureHandle provided from the GetOverlayTexture call, this allows the system to free the underlying GPU resources for this object, * so only do it once you stop rendering this texture. */ - virtual EVROverlayError ReleaseNativeOverlayHandle( VROverlayHandle_t ulOverlayHandle, void *pNativeTextureHandle ) = 0; + virtual EVROverlayError ReleaseNativeOverlayHandle(VROverlayHandle_t ulOverlayHandle, void *pNativeTextureHandle) = 0; - /** Get the size of the overlay texture */ - virtual EVROverlayError GetOverlayTextureSize( VROverlayHandle_t ulOverlayHandle, uint32_t *pWidth, uint32_t *pHeight ) = 0; + /** Get the size of the overlay texture */ + virtual EVROverlayError GetOverlayTextureSize(VROverlayHandle_t ulOverlayHandle, uint32_t *pWidth, uint32_t *pHeight) = 0; - // ---------------------------------------------- - // Dashboard Overlay Methods - // ---------------------------------------------- + // ---------------------------------------------- + // Dashboard Overlay Methods + // ---------------------------------------------- - /** Creates a dashboard overlay and returns its handle */ - virtual EVROverlayError CreateDashboardOverlay( const char *pchOverlayKey, const char *pchOverlayFriendlyName, VROverlayHandle_t * pMainHandle, VROverlayHandle_t *pThumbnailHandle ) = 0; + /** Creates a dashboard overlay and returns its handle */ + virtual EVROverlayError CreateDashboardOverlay(const char *pchOverlayKey, const char *pchOverlayFriendlyName, VROverlayHandle_t *pMainHandle, VROverlayHandle_t *pThumbnailHandle) = 0; - /** Returns true if the dashboard is visible */ - virtual bool IsDashboardVisible() = 0; + /** Returns true if the dashboard is visible */ + virtual bool IsDashboardVisible() = 0; - /** returns true if the dashboard is visible and the specified overlay is the active system Overlay */ - virtual bool IsActiveDashboardOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + /** returns true if the dashboard is visible and the specified overlay is the active system Overlay */ + virtual bool IsActiveDashboardOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Sets the dashboard overlay to only appear when the specified process ID has scene focus */ - virtual EVROverlayError SetDashboardOverlaySceneProcess( VROverlayHandle_t ulOverlayHandle, uint32_t unProcessId ) = 0; + /** Sets the dashboard overlay to only appear when the specified process ID has scene focus */ + virtual EVROverlayError SetDashboardOverlaySceneProcess(VROverlayHandle_t ulOverlayHandle, uint32_t unProcessId) = 0; - /** Gets the process ID that this dashboard overlay requires to have scene focus */ - virtual EVROverlayError GetDashboardOverlaySceneProcess( VROverlayHandle_t ulOverlayHandle, uint32_t *punProcessId ) = 0; + /** Gets the process ID that this dashboard overlay requires to have scene focus */ + virtual EVROverlayError GetDashboardOverlaySceneProcess(VROverlayHandle_t ulOverlayHandle, uint32_t *punProcessId) = 0; - /** Shows the dashboard. */ - virtual void ShowDashboard( const char *pchOverlayToShow ) = 0; + /** Shows the dashboard. */ + virtual void ShowDashboard(const char *pchOverlayToShow) = 0; - /** Returns the tracked device that has the laser pointer in the dashboard */ - virtual vr::TrackedDeviceIndex_t GetPrimaryDashboardDevice() = 0; + /** Returns the tracked device that has the laser pointer in the dashboard */ + virtual vr::TrackedDeviceIndex_t GetPrimaryDashboardDevice() = 0; - // --------------------------------------------- - // Keyboard methods - // --------------------------------------------- - - /** Show the virtual keyboard to accept input **/ - virtual EVROverlayError ShowKeyboard( EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32_t unCharMax, const char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue ) = 0; + // --------------------------------------------- + // Keyboard methods + // --------------------------------------------- - virtual EVROverlayError ShowKeyboardForOverlay( VROverlayHandle_t ulOverlayHandle, EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32_t unCharMax, const char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue ) = 0; + /** Show the virtual keyboard to accept input **/ + virtual EVROverlayError ShowKeyboard(EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32_t unCharMax, const char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue) = 0; - /** Get the text that was entered into the text input **/ - virtual uint32_t GetKeyboardText( VR_OUT_STRING() char *pchText, uint32_t cchText ) = 0; + virtual EVROverlayError ShowKeyboardForOverlay(VROverlayHandle_t ulOverlayHandle, EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32_t unCharMax, const char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue) = 0; - /** Hide the virtual keyboard **/ - virtual void HideKeyboard() = 0; + /** Get the text that was entered into the text input **/ + virtual uint32_t GetKeyboardText(VR_OUT_STRING() char *pchText, uint32_t cchText) = 0; - /** Set the position of the keyboard in world space **/ - virtual void SetKeyboardTransformAbsolute( ETrackingUniverseOrigin eTrackingOrigin, const HmdMatrix34_t *pmatTrackingOriginToKeyboardTransform ) = 0; + /** Hide the virtual keyboard **/ + virtual void HideKeyboard() = 0; - /** Set the position of the keyboard in overlay space by telling it to avoid a rectangle in the overlay. Rectangle coords have (0,0) in the bottom left **/ - virtual void SetKeyboardPositionForOverlay( VROverlayHandle_t ulOverlayHandle, HmdRect2_t avoidRect ) = 0; + /** Set the position of the keyboard in world space **/ + virtual void SetKeyboardTransformAbsolute(ETrackingUniverseOrigin eTrackingOrigin, const HmdMatrix34_t *pmatTrackingOriginToKeyboardTransform) = 0; - // --------------------------------------------- - // Overlay input methods - // --------------------------------------------- + /** Set the position of the keyboard in overlay space by telling it to avoid a rectangle in the overlay. Rectangle coords have (0,0) in the bottom left **/ + virtual void SetKeyboardPositionForOverlay(VROverlayHandle_t ulOverlayHandle, HmdRect2_t avoidRect) = 0; - /** Sets a list of primitives to be used for controller ray intersection + // --------------------------------------------- + // Overlay input methods + // --------------------------------------------- + + /** Sets a list of primitives to be used for controller ray intersection * typically the size of the underlying UI in pixels (not in world space). */ - virtual EVROverlayError SetOverlayIntersectionMask( VROverlayHandle_t ulOverlayHandle, VROverlayIntersectionMaskPrimitive_t *pMaskPrimitives, uint32_t unNumMaskPrimitives, uint32_t unPrimitiveSize = sizeof( VROverlayIntersectionMaskPrimitive_t ) ) = 0; + virtual EVROverlayError SetOverlayIntersectionMask(VROverlayHandle_t ulOverlayHandle, VROverlayIntersectionMaskPrimitive_t *pMaskPrimitives, uint32_t unNumMaskPrimitives, uint32_t unPrimitiveSize = sizeof(VROverlayIntersectionMaskPrimitive_t)) = 0; - virtual EVROverlayError GetOverlayFlags( VROverlayHandle_t ulOverlayHandle, uint32_t *pFlags ) = 0; + virtual EVROverlayError GetOverlayFlags(VROverlayHandle_t ulOverlayHandle, uint32_t *pFlags) = 0; - // --------------------------------------------- - // Message box methods - // --------------------------------------------- + // --------------------------------------------- + // Message box methods + // --------------------------------------------- - /** Show the message overlay. This will block and return you a result. **/ - virtual VRMessageOverlayResponse ShowMessageOverlay( const char* pchText, const char* pchCaption, const char* pchButton0Text, const char* pchButton1Text = nullptr, const char* pchButton2Text = nullptr, const char* pchButton3Text = nullptr ) = 0; + /** Show the message overlay. This will block and return you a result. **/ + virtual VRMessageOverlayResponse ShowMessageOverlay(const char *pchText, const char *pchCaption, const char *pchButton0Text, const char *pchButton1Text = nullptr, const char *pchButton2Text = nullptr, const char *pchButton3Text = nullptr) = 0; - /** If the calling process owns the overlay and it's open, this will close it. **/ - virtual void CloseMessageOverlay() = 0; - }; + /** If the calling process owns the overlay and it's open, this will close it. **/ + virtual void CloseMessageOverlay() = 0; +}; - static const char * const IVROverlay_Version = "IVROverlay_016"; +static const char *const IVROverlay_Version = "IVROverlay_016"; -} // namespace vr +} // namespace vr // ivrrendermodels.h namespace vr { +static const char *const k_pch_Controller_Component_GDC2015 = "gdc2015"; // Canonical coordinate system of the gdc 2015 wired controller, provided for backwards compatibility +static const char *const k_pch_Controller_Component_Base = "base"; // For controllers with an unambiguous 'base'. +static const char *const k_pch_Controller_Component_Tip = "tip"; // For controllers with an unambiguous 'tip' (used for 'laser-pointing') +static const char *const k_pch_Controller_Component_HandGrip = "handgrip"; // Neutral, ambidextrous hand-pose when holding controller. On plane between neutrally posed index finger and thumb +static const char *const k_pch_Controller_Component_Status = "status"; // 1:1 aspect ratio status area, with canonical [0,1] uv mapping -static const char * const k_pch_Controller_Component_GDC2015 = "gdc2015"; // Canonical coordinate system of the gdc 2015 wired controller, provided for backwards compatibility -static const char * const k_pch_Controller_Component_Base = "base"; // For controllers with an unambiguous 'base'. -static const char * const k_pch_Controller_Component_Tip = "tip"; // For controllers with an unambiguous 'tip' (used for 'laser-pointing') -static const char * const k_pch_Controller_Component_HandGrip = "handgrip"; // Neutral, ambidextrous hand-pose when holding controller. On plane between neutrally posed index finger and thumb -static const char * const k_pch_Controller_Component_Status = "status"; // 1:1 aspect ratio status area, with canonical [0,1] uv mapping - -#pragma pack( push, 8 ) +#pragma pack(push, 8) /** Errors that can occur with the VR compositor */ enum EVRRenderModelError @@ -3062,25 +3002,25 @@ struct RenderModel_ComponentState_t /** A single vertex in a render model */ struct RenderModel_Vertex_t { - HmdVector3_t vPosition; // position in meters in device space + HmdVector3_t vPosition; // position in meters in device space HmdVector3_t vNormal; float rfTextureCoord[2]; }; /** A texture map for use on a render model */ -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif struct RenderModel_TextureMap_t { - uint16_t unWidth, unHeight; // width and height of the texture map in pixels - const uint8_t *rubTextureMapData; // Map texture data. All textures are RGBA with 8 bits per channel per pixel. Data size is width * height * 4ub + uint16_t unWidth, unHeight; // width and height of the texture map in pixels + const uint8_t *rubTextureMapData; // Map texture data. All textures are RGBA with 8 bits per channel per pixel. Data size is width * height * 4ub }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif /** Session unique texture identifier. Rendermodels which share the same texture will have the same id. @@ -3090,36 +3030,34 @@ typedef int32_t TextureID_t; const TextureID_t INVALID_TEXTURE_ID = -1; -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif struct RenderModel_t { - const RenderModel_Vertex_t *rVertexData; // Vertex data for the mesh - uint32_t unVertexCount; // Number of vertices in the vertex data - const uint16_t *rIndexData; // Indices into the vertex data for each triangle - uint32_t unTriangleCount; // Number of triangles in the mesh. Index count is 3 * TriangleCount - TextureID_t diffuseTextureId; // Session unique texture identifier. Rendermodels which share the same texture will have the same id. <0 == texture not present + const RenderModel_Vertex_t *rVertexData; // Vertex data for the mesh + uint32_t unVertexCount; // Number of vertices in the vertex data + const uint16_t *rIndexData; // Indices into the vertex data for each triangle + uint32_t unTriangleCount; // Number of triangles in the mesh. Index count is 3 * TriangleCount + TextureID_t diffuseTextureId; // Session unique texture identifier. Rendermodels which share the same texture will have the same id. <0 == texture not present }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif - struct RenderModel_ControllerMode_State_t { - bool bScrollWheelVisible; // is this controller currently set to be in a scroll wheel mode + bool bScrollWheelVisible; // is this controller currently set to be in a scroll wheel mode }; -#pragma pack( pop ) +#pragma pack(pop) class IVRRenderModels { public: - /** Loads and returns a render model for use in the application. pchRenderModelName should be a render model name * from the Prop_RenderModelName_String property or an absolute path name to a render model on disk. * @@ -3129,37 +3067,36 @@ public: * * The method returns VRRenderModelError_Loading while the render model is still being loaded. * The method returns VRRenderModelError_None once loaded successfully, otherwise will return an error. */ - virtual EVRRenderModelError LoadRenderModel_Async( const char *pchRenderModelName, RenderModel_t **ppRenderModel ) = 0; + virtual EVRRenderModelError LoadRenderModel_Async(const char *pchRenderModelName, RenderModel_t **ppRenderModel) = 0; /** Frees a previously returned render model * It is safe to call this on a null ptr. */ - virtual void FreeRenderModel( RenderModel_t *pRenderModel ) = 0; + virtual void FreeRenderModel(RenderModel_t *pRenderModel) = 0; /** Loads and returns a texture for use in the application. */ - virtual EVRRenderModelError LoadTexture_Async( TextureID_t textureId, RenderModel_TextureMap_t **ppTexture ) = 0; + virtual EVRRenderModelError LoadTexture_Async(TextureID_t textureId, RenderModel_TextureMap_t **ppTexture) = 0; /** Frees a previously returned texture * It is safe to call this on a null ptr. */ - virtual void FreeTexture( RenderModel_TextureMap_t *pTexture ) = 0; + virtual void FreeTexture(RenderModel_TextureMap_t *pTexture) = 0; /** Creates a D3D11 texture and loads data into it. */ - virtual EVRRenderModelError LoadTextureD3D11_Async( TextureID_t textureId, void *pD3D11Device, void **ppD3D11Texture2D ) = 0; + virtual EVRRenderModelError LoadTextureD3D11_Async(TextureID_t textureId, void *pD3D11Device, void **ppD3D11Texture2D) = 0; /** Helper function to copy the bits into an existing texture. */ - virtual EVRRenderModelError LoadIntoTextureD3D11_Async( TextureID_t textureId, void *pDstTexture ) = 0; + virtual EVRRenderModelError LoadIntoTextureD3D11_Async(TextureID_t textureId, void *pDstTexture) = 0; /** Use this to free textures created with LoadTextureD3D11_Async instead of calling Release on them. */ - virtual void FreeTextureD3D11( void *pD3D11Texture2D ) = 0; + virtual void FreeTextureD3D11(void *pD3D11Texture2D) = 0; /** Use this to get the names of available render models. Index does not correlate to a tracked device index, but * is only used for iterating over all available render models. If the index is out of range, this function will return 0. * Otherwise, it will return the size of the buffer required for the name. */ - virtual uint32_t GetRenderModelName( uint32_t unRenderModelIndex, VR_OUT_STRING() char *pchRenderModelName, uint32_t unRenderModelNameLen ) = 0; + virtual uint32_t GetRenderModelName(uint32_t unRenderModelIndex, VR_OUT_STRING() char *pchRenderModelName, uint32_t unRenderModelNameLen) = 0; /** Returns the number of available render models. */ virtual uint32_t GetRenderModelCount() = 0; - /** Returns the number of components of the specified render model. * Components are useful when client application wish to draw, label, or otherwise interact with components of tracked objects. * Examples controller components: @@ -3167,23 +3104,23 @@ public: * non-renderable things which include coordinate systems such as 'tip', 'base', a neutral controller agnostic hand-pose * If all controller components are enumerated and rendered, it will be equivalent to drawing the traditional render model * Returns 0 if components not supported, >0 otherwise */ - virtual uint32_t GetComponentCount( const char *pchRenderModelName ) = 0; + virtual uint32_t GetComponentCount(const char *pchRenderModelName) = 0; /** Use this to get the names of available components. Index does not correlate to a tracked device index, but * is only used for iterating over all available components. If the index is out of range, this function will return 0. * Otherwise, it will return the size of the buffer required for the name. */ - virtual uint32_t GetComponentName( const char *pchRenderModelName, uint32_t unComponentIndex, VR_OUT_STRING( ) char *pchComponentName, uint32_t unComponentNameLen ) = 0; + virtual uint32_t GetComponentName(const char *pchRenderModelName, uint32_t unComponentIndex, VR_OUT_STRING() char *pchComponentName, uint32_t unComponentNameLen) = 0; /** Get the button mask for all buttons associated with this component * If no buttons (or axes) are associated with this component, return 0 * Note: multiple components may be associated with the same button. Ex: two grip buttons on a single controller. * Note: A single component may be associated with multiple buttons. Ex: A trackpad which also provides "D-pad" functionality */ - virtual uint64_t GetComponentButtonMask( const char *pchRenderModelName, const char *pchComponentName ) = 0; + virtual uint64_t GetComponentButtonMask(const char *pchRenderModelName, const char *pchComponentName) = 0; /** Use this to get the render model name for the specified rendermode/component combination, to be passed to LoadRenderModel. * If the component name is out of range, this function will return 0. * Otherwise, it will return the size of the buffer required for the name. */ - virtual uint32_t GetComponentRenderModelName( const char *pchRenderModelName, const char *pchComponentName, VR_OUT_STRING( ) char *pchComponentRenderModelName, uint32_t unComponentRenderModelNameLen ) = 0; + virtual uint32_t GetComponentRenderModelName(const char *pchRenderModelName, const char *pchComponentName, VR_OUT_STRING() char *pchComponentRenderModelName, uint32_t unComponentRenderModelNameLen) = 0; /** Use this to query information about the component, as a function of the controller state. * @@ -3193,93 +3130,87 @@ public: * If the pchRenderModelName or pchComponentName is invalid, this will return false (and transforms will be set to identity). * Otherwise, return true * Note: For dynamic objects, visibility may be dynamic. (I.e., true/false will be returned based on controller state and controller mode state ) */ - virtual bool GetComponentState( const char *pchRenderModelName, const char *pchComponentName, const vr::VRControllerState_t *pControllerState, const RenderModel_ControllerMode_State_t *pState, RenderModel_ComponentState_t *pComponentState ) = 0; + virtual bool GetComponentState(const char *pchRenderModelName, const char *pchComponentName, const vr::VRControllerState_t *pControllerState, const RenderModel_ControllerMode_State_t *pState, RenderModel_ComponentState_t *pComponentState) = 0; /** Returns true if the render model has a component with the specified name */ - virtual bool RenderModelHasComponent( const char *pchRenderModelName, const char *pchComponentName ) = 0; + virtual bool RenderModelHasComponent(const char *pchRenderModelName, const char *pchComponentName) = 0; /** Returns the URL of the thumbnail image for this rendermodel */ - virtual uint32_t GetRenderModelThumbnailURL( const char *pchRenderModelName, VR_OUT_STRING() char *pchThumbnailURL, uint32_t unThumbnailURLLen, vr::EVRRenderModelError *peError ) = 0; + virtual uint32_t GetRenderModelThumbnailURL(const char *pchRenderModelName, VR_OUT_STRING() char *pchThumbnailURL, uint32_t unThumbnailURLLen, vr::EVRRenderModelError *peError) = 0; /** Provides a render model path that will load the unskinned model if the model name provided has been replace by the user. If the model * hasn't been replaced the path value will still be a valid path to load the model. Pass this to LoadRenderModel_Async, etc. to load the * model. */ - virtual uint32_t GetRenderModelOriginalPath( const char *pchRenderModelName, VR_OUT_STRING() char *pchOriginalPath, uint32_t unOriginalPathLen, vr::EVRRenderModelError *peError ) = 0; + virtual uint32_t GetRenderModelOriginalPath(const char *pchRenderModelName, VR_OUT_STRING() char *pchOriginalPath, uint32_t unOriginalPathLen, vr::EVRRenderModelError *peError) = 0; /** Returns a string for a render model error */ - virtual const char *GetRenderModelErrorNameFromEnum( vr::EVRRenderModelError error ) = 0; + virtual const char *GetRenderModelErrorNameFromEnum(vr::EVRRenderModelError error) = 0; }; -static const char * const IVRRenderModels_Version = "IVRRenderModels_005"; - -} +static const char *const IVRRenderModels_Version = "IVRRenderModels_005"; +} // namespace vr // ivrextendeddisplay.h namespace vr { - - /** NOTE: Use of this interface is not recommended in production applications. It will not work for displays which use +/** NOTE: Use of this interface is not recommended in production applications. It will not work for displays which use * direct-to-display mode. Creating our own window is also incompatible with the VR compositor and is not available when the compositor is running. */ - class IVRExtendedDisplay - { - public: +class IVRExtendedDisplay +{ +public: + /** Size and position that the window needs to be on the VR display. */ + virtual void GetWindowBounds(int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight) = 0; - /** Size and position that the window needs to be on the VR display. */ - virtual void GetWindowBounds( int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; + /** Gets the viewport in the frame buffer to draw the output of the distortion into */ + virtual void GetEyeOutputViewport(EVREye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight) = 0; - /** Gets the viewport in the frame buffer to draw the output of the distortion into */ - virtual void GetEyeOutputViewport( EVREye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; - - /** [D3D10/11 Only] + /** [D3D10/11 Only] * Returns the adapter index and output index that the user should pass into EnumAdapters and EnumOutputs * to create the device and swap chain in DX10 and DX11. If an error occurs both indices will be set to -1. */ - virtual void GetDXGIOutputInfo( int32_t *pnAdapterIndex, int32_t *pnAdapterOutputIndex ) = 0; + virtual void GetDXGIOutputInfo(int32_t *pnAdapterIndex, int32_t *pnAdapterOutputIndex) = 0; +}; - }; - - static const char * const IVRExtendedDisplay_Version = "IVRExtendedDisplay_001"; - -} +static const char *const IVRExtendedDisplay_Version = "IVRExtendedDisplay_001"; +} // namespace vr // ivrtrackedcamera.h namespace vr { - class IVRTrackedCamera { public: /** Returns a string for an error */ - virtual const char *GetCameraErrorNameFromEnum( vr::EVRTrackedCameraError eCameraError ) = 0; + virtual const char *GetCameraErrorNameFromEnum(vr::EVRTrackedCameraError eCameraError) = 0; /** For convenience, same as tracked property request Prop_HasCamera_Bool */ - virtual vr::EVRTrackedCameraError HasCamera( vr::TrackedDeviceIndex_t nDeviceIndex, bool *pHasCamera ) = 0; + virtual vr::EVRTrackedCameraError HasCamera(vr::TrackedDeviceIndex_t nDeviceIndex, bool *pHasCamera) = 0; /** Gets size of the image frame. */ - virtual vr::EVRTrackedCameraError GetCameraFrameSize( vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, uint32_t *pnWidth, uint32_t *pnHeight, uint32_t *pnFrameBufferSize ) = 0; + virtual vr::EVRTrackedCameraError GetCameraFrameSize(vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, uint32_t *pnWidth, uint32_t *pnHeight, uint32_t *pnFrameBufferSize) = 0; - virtual vr::EVRTrackedCameraError GetCameraIntrinsics( vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, vr::HmdVector2_t *pFocalLength, vr::HmdVector2_t *pCenter ) = 0; + virtual vr::EVRTrackedCameraError GetCameraIntrinsics(vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, vr::HmdVector2_t *pFocalLength, vr::HmdVector2_t *pCenter) = 0; - virtual vr::EVRTrackedCameraError GetCameraProjection( vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, vr::HmdMatrix44_t *pProjection ) = 0; + virtual vr::EVRTrackedCameraError GetCameraProjection(vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, vr::HmdMatrix44_t *pProjection) = 0; /** Acquiring streaming service permits video streaming for the caller. Releasing hints the system that video services do not need to be maintained for this client. * If the camera has not already been activated, a one time spin up may incur some auto exposure as well as initial streaming frame delays. * The camera should be considered a global resource accessible for shared consumption but not exclusive to any caller. * The camera may go inactive due to lack of active consumers or headset idleness. */ - virtual vr::EVRTrackedCameraError AcquireVideoStreamingService( vr::TrackedDeviceIndex_t nDeviceIndex, vr::TrackedCameraHandle_t *pHandle ) = 0; - virtual vr::EVRTrackedCameraError ReleaseVideoStreamingService( vr::TrackedCameraHandle_t hTrackedCamera ) = 0; + virtual vr::EVRTrackedCameraError AcquireVideoStreamingService(vr::TrackedDeviceIndex_t nDeviceIndex, vr::TrackedCameraHandle_t *pHandle) = 0; + virtual vr::EVRTrackedCameraError ReleaseVideoStreamingService(vr::TrackedCameraHandle_t hTrackedCamera) = 0; /** Copies the image frame into a caller's provided buffer. The image data is currently provided as RGBA data, 4 bytes per pixel. * A caller can provide null for the framebuffer or frameheader if not desired. Requesting the frame header first, followed by the frame buffer allows * the caller to determine if the frame as advanced per the frame header sequence. * If there is no frame available yet, due to initial camera spinup or re-activation, the error will be VRTrackedCameraError_NoFrameAvailable. * Ideally a caller should be polling at ~16ms intervals */ - virtual vr::EVRTrackedCameraError GetVideoStreamFrameBuffer( vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, void *pFrameBuffer, uint32_t nFrameBufferSize, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize ) = 0; + virtual vr::EVRTrackedCameraError GetVideoStreamFrameBuffer(vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, void *pFrameBuffer, uint32_t nFrameBufferSize, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize) = 0; /** Gets size of the image frame. */ - virtual vr::EVRTrackedCameraError GetVideoStreamTextureSize( vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, vr::VRTextureBounds_t *pTextureBounds, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; + virtual vr::EVRTrackedCameraError GetVideoStreamTextureSize(vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, vr::VRTextureBounds_t *pTextureBounds, uint32_t *pnWidth, uint32_t *pnHeight) = 0; /** Access a shared D3D11 texture for the specified tracked camera stream. * The camera frame type VRTrackedCameraFrameType_Undistorted is not supported directly as a shared texture. It is an interior subregion of the shared texture VRTrackedCameraFrameType_MaximumUndistorted. @@ -3287,31 +3218,29 @@ public: * VRTrackedCameraFrameType_MaximumUndistorted to provide the texture. The VRTrackedCameraFrameType_MaximumUndistorted will yield an image where the invalid regions are decoded * by the alpha channel having a zero component. The valid regions all have a non-zero alpha component. The subregion as described by VRTrackedCameraFrameType_Undistorted * guarantees a rectangle where all pixels are valid. */ - virtual vr::EVRTrackedCameraError GetVideoStreamTextureD3D11( vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize ) = 0; + virtual vr::EVRTrackedCameraError GetVideoStreamTextureD3D11(vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize) = 0; /** Access a shared GL texture for the specified tracked camera stream */ - virtual vr::EVRTrackedCameraError GetVideoStreamTextureGL( vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, vr::glUInt_t *pglTextureId, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize ) = 0; - virtual vr::EVRTrackedCameraError ReleaseVideoStreamTextureGL( vr::TrackedCameraHandle_t hTrackedCamera, vr::glUInt_t glTextureId ) = 0; + virtual vr::EVRTrackedCameraError GetVideoStreamTextureGL(vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, vr::glUInt_t *pglTextureId, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize) = 0; + virtual vr::EVRTrackedCameraError ReleaseVideoStreamTextureGL(vr::TrackedCameraHandle_t hTrackedCamera, vr::glUInt_t glTextureId) = 0; }; -static const char * const IVRTrackedCamera_Version = "IVRTrackedCamera_003"; - -} // namespace vr +static const char *const IVRTrackedCamera_Version = "IVRTrackedCamera_003"; +} // namespace vr // ivrscreenshots.h namespace vr { - /** Errors that can occur with the VR compositor */ enum EVRScreenshotError { - VRScreenshotError_None = 0, - VRScreenshotError_RequestFailed = 1, - VRScreenshotError_IncompatibleVersion = 100, - VRScreenshotError_NotFound = 101, - VRScreenshotError_BufferTooSmall = 102, - VRScreenshotError_ScreenshotAlreadyInProgress = 108, + VRScreenshotError_None = 0, + VRScreenshotError_RequestFailed = 1, + VRScreenshotError_IncompatibleVersion = 100, + VRScreenshotError_NotFound = 101, + VRScreenshotError_BufferTooSmall = 102, + VRScreenshotError_ScreenshotAlreadyInProgress = 108, }; /** Allows the application to generate screenshots */ @@ -3349,7 +3278,7 @@ public: * The destination file names do not need an extension, * will be replaced with the correct one for the format * which is currently .png. */ - virtual vr::EVRScreenshotError RequestScreenshot( vr::ScreenshotHandle_t *pOutScreenshotHandle, vr::EVRScreenshotType type, const char *pchPreviewFilename, const char *pchVRFilename ) = 0; + virtual vr::EVRScreenshotError RequestScreenshot(vr::ScreenshotHandle_t *pOutScreenshotHandle, vr::EVRScreenshotType type, const char *pchPreviewFilename, const char *pchVRFilename) = 0; /** Called by the running VR application to indicate that it * wishes to be in charge of screenshots. If the @@ -3359,23 +3288,23 @@ public: * Once hooked your application will receive a * VREvent_RequestScreenshot event when the user presses the * buttons to take a screenshot. */ - virtual vr::EVRScreenshotError HookScreenshot( VR_ARRAY_COUNT( numTypes ) const vr::EVRScreenshotType *pSupportedTypes, int numTypes ) = 0; + virtual vr::EVRScreenshotError HookScreenshot(VR_ARRAY_COUNT(numTypes) const vr::EVRScreenshotType *pSupportedTypes, int numTypes) = 0; /** When your application receives a * VREvent_RequestScreenshot event, call these functions to get * the details of the screenshot request. */ - virtual vr::EVRScreenshotType GetScreenshotPropertyType( vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotError *pError ) = 0; + virtual vr::EVRScreenshotType GetScreenshotPropertyType(vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotError *pError) = 0; /** Get the filename for the preview or vr image (see * vr::EScreenshotPropertyFilenames). The return value is * the size of the string. */ - virtual uint32_t GetScreenshotPropertyFilename( vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotPropertyFilenames filenameType, VR_OUT_STRING() char *pchFilename, uint32_t cchFilename, vr::EVRScreenshotError *pError ) = 0; + virtual uint32_t GetScreenshotPropertyFilename(vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotPropertyFilenames filenameType, VR_OUT_STRING() char *pchFilename, uint32_t cchFilename, vr::EVRScreenshotError *pError) = 0; /** Call this if the application is taking the screen shot * will take more than a few ms processing. This will result * in an overlay being presented that shows a completion * bar. */ - virtual vr::EVRScreenshotError UpdateScreenshotProgress( vr::ScreenshotHandle_t screenshotHandle, float flProgress ) = 0; + virtual vr::EVRScreenshotError UpdateScreenshotProgress(vr::ScreenshotHandle_t screenshotHandle, float flProgress) = 0; /** Tells the compositor to take an internal screenshot of * type VRScreenshotType_Stereo. It will take the current @@ -3384,7 +3313,7 @@ public: * for the VR image. * This is similar to request screenshot, but doesn't ever * talk to the application, just takes the shot and submits. */ - virtual vr::EVRScreenshotError TakeStereoScreenshot( vr::ScreenshotHandle_t *pOutScreenshotHandle, const char *pchPreviewFilename, const char *pchVRFilename ) = 0; + virtual vr::EVRScreenshotError TakeStereoScreenshot(vr::ScreenshotHandle_t *pOutScreenshotHandle, const char *pchPreviewFilename, const char *pchVRFilename) = 0; /** Submit the completed screenshot. If Steam is running * this will call into the Steam client and upload the @@ -3397,67 +3326,59 @@ public: * screenshotHandle can be k_unScreenshotHandleInvalid if this * was a new shot taking by the app to be saved and not * initiated by a user (achievement earned or something) */ - virtual vr::EVRScreenshotError SubmitScreenshot( vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotType type, const char *pchSourcePreviewFilename, const char *pchSourceVRFilename ) = 0; + virtual vr::EVRScreenshotError SubmitScreenshot(vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotType type, const char *pchSourcePreviewFilename, const char *pchSourceVRFilename) = 0; }; -static const char * const IVRScreenshots_Version = "IVRScreenshots_001"; - -} // namespace vr - +static const char *const IVRScreenshots_Version = "IVRScreenshots_001"; +} // namespace vr // ivrresources.h namespace vr { - class IVRResources { public: - // ------------------------------------ // Shared Resource Methods // ------------------------------------ /** Loads the specified resource into the provided buffer if large enough. * Returns the size in bytes of the buffer required to hold the specified resource. */ - virtual uint32_t LoadSharedResource( const char *pchResourceName, char *pchBuffer, uint32_t unBufferLen ) = 0; + virtual uint32_t LoadSharedResource(const char *pchResourceName, char *pchBuffer, uint32_t unBufferLen) = 0; /** Provides the full path to the specified resource. Resource names can include named directories for * drivers and other things, and this resolves all of those and returns the actual physical path. * pchResourceTypeDirectory is the subdirectory of resources to look in. */ - virtual uint32_t GetResourceFullPath( const char *pchResourceName, const char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen ) = 0; + virtual uint32_t GetResourceFullPath(const char *pchResourceName, const char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen) = 0; }; -static const char * const IVRResources_Version = "IVRResources_001"; +static const char *const IVRResources_Version = "IVRResources_001"; - -} +} // namespace vr // ivrdrivermanager.h namespace vr { - class IVRDriverManager { public: virtual uint32_t GetDriverCount() const = 0; /** Returns the length of the number of bytes necessary to hold this string including the trailing null. */ - virtual uint32_t GetDriverName( vr::DriverId_t nDriver, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize ) = 0; + virtual uint32_t GetDriverName(vr::DriverId_t nDriver, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize) = 0; }; -static const char * const IVRDriverManager_Version = "IVRDriverManager_001"; - -} // namespace vr +static const char *const IVRDriverManager_Version = "IVRDriverManager_001"; +} // namespace vr // End -#endif // _OPENVR_API - +#endif // _OPENVR_API namespace vr { - /** Finds the active installation of the VR API and initializes it. The provided path must be absolute +/** Finds the active installation of the VR API and initializes it. The provided path must be absolute * or relative to the current working directory. These are the local install versions of the equivalent * functions in steamvr.h and will work without a local Steam install. * @@ -3466,312 +3387,312 @@ namespace vr * * pStartupInfo is reserved for future use. */ - inline IVRSystem *VR_Init( EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo = nullptr ); +inline IVRSystem *VR_Init(EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo = nullptr); - /** unloads vrclient.dll. Any interface pointers from the interface are +/** unloads vrclient.dll. Any interface pointers from the interface are * invalid after this point */ - inline void VR_Shutdown(); +inline void VR_Shutdown(); - /** Returns true if there is an HMD attached. This check is as lightweight as possible and +/** Returns true if there is an HMD attached. This check is as lightweight as possible and * can be called outside of VR_Init/VR_Shutdown. It should be used when an application wants * to know if initializing VR is a possibility but isn't ready to take that step yet. */ - VR_INTERFACE bool VR_CALLTYPE VR_IsHmdPresent(); +VR_INTERFACE bool VR_CALLTYPE VR_IsHmdPresent(); - /** Returns true if the OpenVR runtime is installed. */ - VR_INTERFACE bool VR_CALLTYPE VR_IsRuntimeInstalled(); +/** Returns true if the OpenVR runtime is installed. */ +VR_INTERFACE bool VR_CALLTYPE VR_IsRuntimeInstalled(); - /** Returns where the OpenVR runtime is installed. */ - VR_INTERFACE const char *VR_CALLTYPE VR_RuntimePath(); +/** Returns where the OpenVR runtime is installed. */ +VR_INTERFACE const char *VR_CALLTYPE VR_RuntimePath(); - /** Returns the name of the enum value for an EVRInitError. This function may be called outside of VR_Init()/VR_Shutdown(). */ - VR_INTERFACE const char *VR_CALLTYPE VR_GetVRInitErrorAsSymbol( EVRInitError error ); +/** Returns the name of the enum value for an EVRInitError. This function may be called outside of VR_Init()/VR_Shutdown(). */ +VR_INTERFACE const char *VR_CALLTYPE VR_GetVRInitErrorAsSymbol(EVRInitError error); - /** Returns an English string for an EVRInitError. Applications should call VR_GetVRInitErrorAsSymbol instead and +/** Returns an English string for an EVRInitError. Applications should call VR_GetVRInitErrorAsSymbol instead and * use that as a key to look up their own localized error message. This function may be called outside of VR_Init()/VR_Shutdown(). */ - VR_INTERFACE const char *VR_CALLTYPE VR_GetVRInitErrorAsEnglishDescription( EVRInitError error ); +VR_INTERFACE const char *VR_CALLTYPE VR_GetVRInitErrorAsEnglishDescription(EVRInitError error); - /** Returns the interface of the specified version. This method must be called after VR_Init. The +/** Returns the interface of the specified version. This method must be called after VR_Init. The * pointer returned is valid until VR_Shutdown is called. */ - VR_INTERFACE void *VR_CALLTYPE VR_GetGenericInterface( const char *pchInterfaceVersion, EVRInitError *peError ); +VR_INTERFACE void *VR_CALLTYPE VR_GetGenericInterface(const char *pchInterfaceVersion, EVRInitError *peError); - /** Returns whether the interface of the specified version exists. +/** Returns whether the interface of the specified version exists. */ - VR_INTERFACE bool VR_CALLTYPE VR_IsInterfaceVersionValid( const char *pchInterfaceVersion ); +VR_INTERFACE bool VR_CALLTYPE VR_IsInterfaceVersionValid(const char *pchInterfaceVersion); - /** Returns a token that represents whether the VR interface handles need to be reloaded */ - VR_INTERFACE uint32_t VR_CALLTYPE VR_GetInitToken(); +/** Returns a token that represents whether the VR interface handles need to be reloaded */ +VR_INTERFACE uint32_t VR_CALLTYPE VR_GetInitToken(); - // These typedefs allow old enum names from SDK 0.9.11 to be used in applications. - // They will go away in the future. - typedef EVRInitError HmdError; - typedef EVREye Hmd_Eye; - typedef EColorSpace ColorSpace; - typedef ETrackingResult HmdTrackingResult; - typedef ETrackedDeviceClass TrackedDeviceClass; - typedef ETrackingUniverseOrigin TrackingUniverseOrigin; - typedef ETrackedDeviceProperty TrackedDeviceProperty; - typedef ETrackedPropertyError TrackedPropertyError; - typedef EVRSubmitFlags VRSubmitFlags_t; - typedef EVRState VRState_t; - typedef ECollisionBoundsStyle CollisionBoundsStyle_t; - typedef EVROverlayError VROverlayError; - typedef EVRFirmwareError VRFirmwareError; - typedef EVRCompositorError VRCompositorError; - typedef EVRScreenshotError VRScreenshotsError; +// These typedefs allow old enum names from SDK 0.9.11 to be used in applications. +// They will go away in the future. +typedef EVRInitError HmdError; +typedef EVREye Hmd_Eye; +typedef EColorSpace ColorSpace; +typedef ETrackingResult HmdTrackingResult; +typedef ETrackedDeviceClass TrackedDeviceClass; +typedef ETrackingUniverseOrigin TrackingUniverseOrigin; +typedef ETrackedDeviceProperty TrackedDeviceProperty; +typedef ETrackedPropertyError TrackedPropertyError; +typedef EVRSubmitFlags VRSubmitFlags_t; +typedef EVRState VRState_t; +typedef ECollisionBoundsStyle CollisionBoundsStyle_t; +typedef EVROverlayError VROverlayError; +typedef EVRFirmwareError VRFirmwareError; +typedef EVRCompositorError VRCompositorError; +typedef EVRScreenshotError VRScreenshotsError; - inline uint32_t &VRToken() - { - static uint32_t token; - return token; - } - - class COpenVRContext - { - public: - COpenVRContext() { Clear(); } - void Clear(); - - inline void CheckClear() - { - if ( VRToken() != VR_GetInitToken() ) - { - Clear(); - VRToken() = VR_GetInitToken(); - } - } - - IVRSystem *VRSystem() - { - CheckClear(); - if ( m_pVRSystem == nullptr ) - { - EVRInitError eError; - m_pVRSystem = ( IVRSystem * )VR_GetGenericInterface( IVRSystem_Version, &eError ); - } - return m_pVRSystem; - } - IVRChaperone *VRChaperone() - { - CheckClear(); - if ( m_pVRChaperone == nullptr ) - { - EVRInitError eError; - m_pVRChaperone = ( IVRChaperone * )VR_GetGenericInterface( IVRChaperone_Version, &eError ); - } - return m_pVRChaperone; - } - - IVRChaperoneSetup *VRChaperoneSetup() - { - CheckClear(); - if ( m_pVRChaperoneSetup == nullptr ) - { - EVRInitError eError; - m_pVRChaperoneSetup = ( IVRChaperoneSetup * )VR_GetGenericInterface( IVRChaperoneSetup_Version, &eError ); - } - return m_pVRChaperoneSetup; - } - - IVRCompositor *VRCompositor() - { - CheckClear(); - if ( m_pVRCompositor == nullptr ) - { - EVRInitError eError; - m_pVRCompositor = ( IVRCompositor * )VR_GetGenericInterface( IVRCompositor_Version, &eError ); - } - return m_pVRCompositor; - } - - IVROverlay *VROverlay() - { - CheckClear(); - if ( m_pVROverlay == nullptr ) - { - EVRInitError eError; - m_pVROverlay = ( IVROverlay * )VR_GetGenericInterface( IVROverlay_Version, &eError ); - } - return m_pVROverlay; - } - - IVRResources *VRResources() - { - CheckClear(); - if ( m_pVRResources == nullptr ) - { - EVRInitError eError; - m_pVRResources = (IVRResources *)VR_GetGenericInterface( IVRResources_Version, &eError ); - } - return m_pVRResources; - } - - IVRScreenshots *VRScreenshots() - { - CheckClear(); - if ( m_pVRScreenshots == nullptr ) - { - EVRInitError eError; - m_pVRScreenshots = ( IVRScreenshots * )VR_GetGenericInterface( IVRScreenshots_Version, &eError ); - } - return m_pVRScreenshots; - } - - IVRRenderModels *VRRenderModels() - { - CheckClear(); - if ( m_pVRRenderModels == nullptr ) - { - EVRInitError eError; - m_pVRRenderModels = ( IVRRenderModels * )VR_GetGenericInterface( IVRRenderModels_Version, &eError ); - } - return m_pVRRenderModels; - } - - IVRExtendedDisplay *VRExtendedDisplay() - { - CheckClear(); - if ( m_pVRExtendedDisplay == nullptr ) - { - EVRInitError eError; - m_pVRExtendedDisplay = ( IVRExtendedDisplay * )VR_GetGenericInterface( IVRExtendedDisplay_Version, &eError ); - } - return m_pVRExtendedDisplay; - } - - IVRSettings *VRSettings() - { - CheckClear(); - if ( m_pVRSettings == nullptr ) - { - EVRInitError eError; - m_pVRSettings = ( IVRSettings * )VR_GetGenericInterface( IVRSettings_Version, &eError ); - } - return m_pVRSettings; - } - - IVRApplications *VRApplications() - { - CheckClear(); - if ( m_pVRApplications == nullptr ) - { - EVRInitError eError; - m_pVRApplications = ( IVRApplications * )VR_GetGenericInterface( IVRApplications_Version, &eError ); - } - return m_pVRApplications; - } - - IVRTrackedCamera *VRTrackedCamera() - { - CheckClear(); - if ( m_pVRTrackedCamera == nullptr ) - { - EVRInitError eError; - m_pVRTrackedCamera = ( IVRTrackedCamera * )VR_GetGenericInterface( IVRTrackedCamera_Version, &eError ); - } - return m_pVRTrackedCamera; - } - - IVRDriverManager *VRDriverManager() - { - CheckClear(); - if ( !m_pVRDriverManager ) - { - EVRInitError eError; - m_pVRDriverManager = ( IVRDriverManager * )VR_GetGenericInterface( IVRDriverManager_Version, &eError ); - } - return m_pVRDriverManager; - } - - private: - IVRSystem *m_pVRSystem; - IVRChaperone *m_pVRChaperone; - IVRChaperoneSetup *m_pVRChaperoneSetup; - IVRCompositor *m_pVRCompositor; - IVROverlay *m_pVROverlay; - IVRResources *m_pVRResources; - IVRRenderModels *m_pVRRenderModels; - IVRExtendedDisplay *m_pVRExtendedDisplay; - IVRSettings *m_pVRSettings; - IVRApplications *m_pVRApplications; - IVRTrackedCamera *m_pVRTrackedCamera; - IVRScreenshots *m_pVRScreenshots; - IVRDriverManager *m_pVRDriverManager; - }; - - inline COpenVRContext &OpenVRInternal_ModuleContext() - { - static void *ctx[ sizeof( COpenVRContext ) / sizeof( void * ) ]; - return *( COpenVRContext * )ctx; // bypass zero-init constructor - } - - inline IVRSystem *VR_CALLTYPE VRSystem() { return OpenVRInternal_ModuleContext().VRSystem(); } - inline IVRChaperone *VR_CALLTYPE VRChaperone() { return OpenVRInternal_ModuleContext().VRChaperone(); } - inline IVRChaperoneSetup *VR_CALLTYPE VRChaperoneSetup() { return OpenVRInternal_ModuleContext().VRChaperoneSetup(); } - inline IVRCompositor *VR_CALLTYPE VRCompositor() { return OpenVRInternal_ModuleContext().VRCompositor(); } - inline IVROverlay *VR_CALLTYPE VROverlay() { return OpenVRInternal_ModuleContext().VROverlay(); } - inline IVRScreenshots *VR_CALLTYPE VRScreenshots() { return OpenVRInternal_ModuleContext().VRScreenshots(); } - inline IVRRenderModels *VR_CALLTYPE VRRenderModels() { return OpenVRInternal_ModuleContext().VRRenderModels(); } - inline IVRApplications *VR_CALLTYPE VRApplications() { return OpenVRInternal_ModuleContext().VRApplications(); } - inline IVRSettings *VR_CALLTYPE VRSettings() { return OpenVRInternal_ModuleContext().VRSettings(); } - inline IVRResources *VR_CALLTYPE VRResources() { return OpenVRInternal_ModuleContext().VRResources(); } - inline IVRExtendedDisplay *VR_CALLTYPE VRExtendedDisplay() { return OpenVRInternal_ModuleContext().VRExtendedDisplay(); } - inline IVRTrackedCamera *VR_CALLTYPE VRTrackedCamera() { return OpenVRInternal_ModuleContext().VRTrackedCamera(); } - inline IVRDriverManager *VR_CALLTYPE VRDriverManager() { return OpenVRInternal_ModuleContext().VRDriverManager(); } - - inline void COpenVRContext::Clear() - { - m_pVRSystem = nullptr; - m_pVRChaperone = nullptr; - m_pVRChaperoneSetup = nullptr; - m_pVRCompositor = nullptr; - m_pVROverlay = nullptr; - m_pVRRenderModels = nullptr; - m_pVRExtendedDisplay = nullptr; - m_pVRSettings = nullptr; - m_pVRApplications = nullptr; - m_pVRTrackedCamera = nullptr; - m_pVRResources = nullptr; - m_pVRScreenshots = nullptr; - m_pVRDriverManager = nullptr; - } - - VR_INTERFACE uint32_t VR_CALLTYPE VR_InitInternal2( EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo ); - VR_INTERFACE void VR_CALLTYPE VR_ShutdownInternal(); - - /** Finds the active installation of vrclient.dll and initializes it */ - inline IVRSystem *VR_Init( EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo ) - { - IVRSystem *pVRSystem = nullptr; - - EVRInitError eError; - VRToken() = VR_InitInternal2( &eError, eApplicationType, pStartupInfo ); - COpenVRContext &ctx = OpenVRInternal_ModuleContext(); - ctx.Clear(); - - if ( eError == VRInitError_None ) - { - if ( VR_IsInterfaceVersionValid( IVRSystem_Version ) ) - { - pVRSystem = VRSystem(); - } - else - { - VR_ShutdownInternal(); - eError = VRInitError_Init_InterfaceNotFound; - } - } - - if ( peError ) - *peError = eError; - return pVRSystem; - } - - /** unloads vrclient.dll. Any interface pointers from the interface are - * invalid after this point */ - inline void VR_Shutdown() - { - VR_ShutdownInternal(); - } +inline uint32_t &VRToken() +{ + static uint32_t token; + return token; } + +class COpenVRContext +{ +public: + COpenVRContext() { Clear(); } + void Clear(); + + inline void CheckClear() + { + if (VRToken() != VR_GetInitToken()) + { + Clear(); + VRToken() = VR_GetInitToken(); + } + } + + IVRSystem *VRSystem() + { + CheckClear(); + if (m_pVRSystem == nullptr) + { + EVRInitError eError; + m_pVRSystem = (IVRSystem *)VR_GetGenericInterface(IVRSystem_Version, &eError); + } + return m_pVRSystem; + } + IVRChaperone *VRChaperone() + { + CheckClear(); + if (m_pVRChaperone == nullptr) + { + EVRInitError eError; + m_pVRChaperone = (IVRChaperone *)VR_GetGenericInterface(IVRChaperone_Version, &eError); + } + return m_pVRChaperone; + } + + IVRChaperoneSetup *VRChaperoneSetup() + { + CheckClear(); + if (m_pVRChaperoneSetup == nullptr) + { + EVRInitError eError; + m_pVRChaperoneSetup = (IVRChaperoneSetup *)VR_GetGenericInterface(IVRChaperoneSetup_Version, &eError); + } + return m_pVRChaperoneSetup; + } + + IVRCompositor *VRCompositor() + { + CheckClear(); + if (m_pVRCompositor == nullptr) + { + EVRInitError eError; + m_pVRCompositor = (IVRCompositor *)VR_GetGenericInterface(IVRCompositor_Version, &eError); + } + return m_pVRCompositor; + } + + IVROverlay *VROverlay() + { + CheckClear(); + if (m_pVROverlay == nullptr) + { + EVRInitError eError; + m_pVROverlay = (IVROverlay *)VR_GetGenericInterface(IVROverlay_Version, &eError); + } + return m_pVROverlay; + } + + IVRResources *VRResources() + { + CheckClear(); + if (m_pVRResources == nullptr) + { + EVRInitError eError; + m_pVRResources = (IVRResources *)VR_GetGenericInterface(IVRResources_Version, &eError); + } + return m_pVRResources; + } + + IVRScreenshots *VRScreenshots() + { + CheckClear(); + if (m_pVRScreenshots == nullptr) + { + EVRInitError eError; + m_pVRScreenshots = (IVRScreenshots *)VR_GetGenericInterface(IVRScreenshots_Version, &eError); + } + return m_pVRScreenshots; + } + + IVRRenderModels *VRRenderModels() + { + CheckClear(); + if (m_pVRRenderModels == nullptr) + { + EVRInitError eError; + m_pVRRenderModels = (IVRRenderModels *)VR_GetGenericInterface(IVRRenderModels_Version, &eError); + } + return m_pVRRenderModels; + } + + IVRExtendedDisplay *VRExtendedDisplay() + { + CheckClear(); + if (m_pVRExtendedDisplay == nullptr) + { + EVRInitError eError; + m_pVRExtendedDisplay = (IVRExtendedDisplay *)VR_GetGenericInterface(IVRExtendedDisplay_Version, &eError); + } + return m_pVRExtendedDisplay; + } + + IVRSettings *VRSettings() + { + CheckClear(); + if (m_pVRSettings == nullptr) + { + EVRInitError eError; + m_pVRSettings = (IVRSettings *)VR_GetGenericInterface(IVRSettings_Version, &eError); + } + return m_pVRSettings; + } + + IVRApplications *VRApplications() + { + CheckClear(); + if (m_pVRApplications == nullptr) + { + EVRInitError eError; + m_pVRApplications = (IVRApplications *)VR_GetGenericInterface(IVRApplications_Version, &eError); + } + return m_pVRApplications; + } + + IVRTrackedCamera *VRTrackedCamera() + { + CheckClear(); + if (m_pVRTrackedCamera == nullptr) + { + EVRInitError eError; + m_pVRTrackedCamera = (IVRTrackedCamera *)VR_GetGenericInterface(IVRTrackedCamera_Version, &eError); + } + return m_pVRTrackedCamera; + } + + IVRDriverManager *VRDriverManager() + { + CheckClear(); + if (!m_pVRDriverManager) + { + EVRInitError eError; + m_pVRDriverManager = (IVRDriverManager *)VR_GetGenericInterface(IVRDriverManager_Version, &eError); + } + return m_pVRDriverManager; + } + +private: + IVRSystem *m_pVRSystem; + IVRChaperone *m_pVRChaperone; + IVRChaperoneSetup *m_pVRChaperoneSetup; + IVRCompositor *m_pVRCompositor; + IVROverlay *m_pVROverlay; + IVRResources *m_pVRResources; + IVRRenderModels *m_pVRRenderModels; + IVRExtendedDisplay *m_pVRExtendedDisplay; + IVRSettings *m_pVRSettings; + IVRApplications *m_pVRApplications; + IVRTrackedCamera *m_pVRTrackedCamera; + IVRScreenshots *m_pVRScreenshots; + IVRDriverManager *m_pVRDriverManager; +}; + +inline COpenVRContext &OpenVRInternal_ModuleContext() +{ + static void *ctx[sizeof(COpenVRContext) / sizeof(void *)]; + return *(COpenVRContext *)ctx; // bypass zero-init constructor +} + +inline IVRSystem *VR_CALLTYPE VRSystem() { return OpenVRInternal_ModuleContext().VRSystem(); } +inline IVRChaperone *VR_CALLTYPE VRChaperone() { return OpenVRInternal_ModuleContext().VRChaperone(); } +inline IVRChaperoneSetup *VR_CALLTYPE VRChaperoneSetup() { return OpenVRInternal_ModuleContext().VRChaperoneSetup(); } +inline IVRCompositor *VR_CALLTYPE VRCompositor() { return OpenVRInternal_ModuleContext().VRCompositor(); } +inline IVROverlay *VR_CALLTYPE VROverlay() { return OpenVRInternal_ModuleContext().VROverlay(); } +inline IVRScreenshots *VR_CALLTYPE VRScreenshots() { return OpenVRInternal_ModuleContext().VRScreenshots(); } +inline IVRRenderModels *VR_CALLTYPE VRRenderModels() { return OpenVRInternal_ModuleContext().VRRenderModels(); } +inline IVRApplications *VR_CALLTYPE VRApplications() { return OpenVRInternal_ModuleContext().VRApplications(); } +inline IVRSettings *VR_CALLTYPE VRSettings() { return OpenVRInternal_ModuleContext().VRSettings(); } +inline IVRResources *VR_CALLTYPE VRResources() { return OpenVRInternal_ModuleContext().VRResources(); } +inline IVRExtendedDisplay *VR_CALLTYPE VRExtendedDisplay() { return OpenVRInternal_ModuleContext().VRExtendedDisplay(); } +inline IVRTrackedCamera *VR_CALLTYPE VRTrackedCamera() { return OpenVRInternal_ModuleContext().VRTrackedCamera(); } +inline IVRDriverManager *VR_CALLTYPE VRDriverManager() { return OpenVRInternal_ModuleContext().VRDriverManager(); } + +inline void COpenVRContext::Clear() +{ + m_pVRSystem = nullptr; + m_pVRChaperone = nullptr; + m_pVRChaperoneSetup = nullptr; + m_pVRCompositor = nullptr; + m_pVROverlay = nullptr; + m_pVRRenderModels = nullptr; + m_pVRExtendedDisplay = nullptr; + m_pVRSettings = nullptr; + m_pVRApplications = nullptr; + m_pVRTrackedCamera = nullptr; + m_pVRResources = nullptr; + m_pVRScreenshots = nullptr; + m_pVRDriverManager = nullptr; +} + +VR_INTERFACE uint32_t VR_CALLTYPE VR_InitInternal2(EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo); +VR_INTERFACE void VR_CALLTYPE VR_ShutdownInternal(); + +/** Finds the active installation of vrclient.dll and initializes it */ +inline IVRSystem *VR_Init(EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo) +{ + IVRSystem *pVRSystem = nullptr; + + EVRInitError eError; + VRToken() = VR_InitInternal2(&eError, eApplicationType, pStartupInfo); + COpenVRContext &ctx = OpenVRInternal_ModuleContext(); + ctx.Clear(); + + if (eError == VRInitError_None) + { + if (VR_IsInterfaceVersionValid(IVRSystem_Version)) + { + pVRSystem = VRSystem(); + } + else + { + VR_ShutdownInternal(); + eError = VRInitError_Init_InterfaceNotFound; + } + } + + if (peError) + *peError = eError; + return pVRSystem; +} + +/** unloads vrclient.dll. Any interface pointers from the interface are + * invalid after this point */ +inline void VR_Shutdown() +{ + VR_ShutdownInternal(); +} +} // namespace vr diff --git a/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/Current/Headers/openvr_capi.h b/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/Current/Headers/openvr_capi.h index 50f895869..245365f4e 100644 --- a/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/Current/Headers/openvr_capi.h +++ b/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/Current/Headers/openvr_capi.h @@ -7,7 +7,7 @@ #ifndef __OPENVR_API_FLAT_H__ #define __OPENVR_API_FLAT_H__ -#if defined( _WIN32 ) || defined( __clang__ ) +#if defined(_WIN32) || defined(__clang__) #pragma once #endif @@ -17,38 +17,38 @@ #define EXTERN_C #endif -#if defined( _WIN32 ) +#if defined(_WIN32) #define OPENVR_FNTABLE_CALLTYPE __stdcall #else -#define OPENVR_FNTABLE_CALLTYPE +#define OPENVR_FNTABLE_CALLTYPE #endif // OPENVR API export macro -#if defined( _WIN32 ) && !defined( _X360 ) - #if defined( OPENVR_API_EXPORTS ) - #define S_API EXTERN_C __declspec( dllexport ) - #elif defined( OPENVR_API_NODLL ) - #define S_API EXTERN_C - #else - #define S_API extern "C" __declspec( dllimport ) - #endif // OPENVR_API_EXPORTS -#elif defined( __GNUC__ ) - #if defined( OPENVR_API_EXPORTS ) - #define S_API EXTERN_C __attribute__ ((visibility("default"))) - #else - #define S_API EXTERN_C - #endif // OPENVR_API_EXPORTS -#else // !WIN32 - #if defined( OPENVR_API_EXPORTS ) - #define S_API EXTERN_C - #else - #define S_API EXTERN_C - #endif // OPENVR_API_EXPORTS +#if defined(_WIN32) && !defined(_X360) +#if defined(OPENVR_API_EXPORTS) +#define S_API EXTERN_C __declspec(dllexport) +#elif defined(OPENVR_API_NODLL) +#define S_API EXTERN_C +#else +#define S_API extern "C" __declspec(dllimport) +#endif // OPENVR_API_EXPORTS +#elif defined(__GNUC__) +#if defined(OPENVR_API_EXPORTS) +#define S_API EXTERN_C __attribute__((visibility("default"))) +#else +#define S_API EXTERN_C +#endif // OPENVR_API_EXPORTS +#else // !WIN32 +#if defined(OPENVR_API_EXPORTS) +#define S_API EXTERN_C +#else +#define S_API EXTERN_C +#endif // OPENVR_API_EXPORTS #endif #include -#if defined( __WIN32 ) +#if defined(__WIN32) typedef char bool; #else #include @@ -60,7 +60,6 @@ typedef uint64_t VRActionHandle_t; typedef uint64_t VRActionSetHandle_t; typedef uint64_t VRInputOriginHandle_t; - // OpenVR Constants static const unsigned int k_nDriverNone = 4294967295; @@ -87,157 +86,157 @@ static const unsigned int k_unMaxPropertyStringSize = 32768; static const unsigned int k_unControllerStateAxisCount = 5; static const unsigned long k_ulOverlayHandleInvalid = 0; static const unsigned int k_unScreenshotHandleInvalid = 0; -static const char * IVRSystem_Version = "IVRSystem_017"; -static const char * IVRExtendedDisplay_Version = "IVRExtendedDisplay_001"; -static const char * IVRTrackedCamera_Version = "IVRTrackedCamera_003"; +static const char *IVRSystem_Version = "IVRSystem_017"; +static const char *IVRExtendedDisplay_Version = "IVRExtendedDisplay_001"; +static const char *IVRTrackedCamera_Version = "IVRTrackedCamera_003"; static const unsigned int k_unMaxApplicationKeyLength = 128; -static const char * k_pch_MimeType_HomeApp = "vr/home"; -static const char * k_pch_MimeType_GameTheater = "vr/game_theater"; -static const char * IVRApplications_Version = "IVRApplications_006"; -static const char * IVRChaperone_Version = "IVRChaperone_003"; -static const char * IVRChaperoneSetup_Version = "IVRChaperoneSetup_005"; -static const char * IVRCompositor_Version = "IVRCompositor_021"; +static const char *k_pch_MimeType_HomeApp = "vr/home"; +static const char *k_pch_MimeType_GameTheater = "vr/game_theater"; +static const char *IVRApplications_Version = "IVRApplications_006"; +static const char *IVRChaperone_Version = "IVRChaperone_003"; +static const char *IVRChaperoneSetup_Version = "IVRChaperoneSetup_005"; +static const char *IVRCompositor_Version = "IVRCompositor_021"; static const unsigned int k_unVROverlayMaxKeyLength = 128; static const unsigned int k_unVROverlayMaxNameLength = 128; static const unsigned int k_unMaxOverlayCount = 64; static const unsigned int k_unMaxOverlayIntersectionMaskPrimitivesCount = 32; -static const char * IVROverlay_Version = "IVROverlay_016"; -static const char * k_pch_Controller_Component_GDC2015 = "gdc2015"; -static const char * k_pch_Controller_Component_Base = "base"; -static const char * k_pch_Controller_Component_Tip = "tip"; -static const char * k_pch_Controller_Component_HandGrip = "handgrip"; -static const char * k_pch_Controller_Component_Status = "status"; -static const char * IVRRenderModels_Version = "IVRRenderModels_005"; +static const char *IVROverlay_Version = "IVROverlay_016"; +static const char *k_pch_Controller_Component_GDC2015 = "gdc2015"; +static const char *k_pch_Controller_Component_Base = "base"; +static const char *k_pch_Controller_Component_Tip = "tip"; +static const char *k_pch_Controller_Component_HandGrip = "handgrip"; +static const char *k_pch_Controller_Component_Status = "status"; +static const char *IVRRenderModels_Version = "IVRRenderModels_005"; static const unsigned int k_unNotificationTextMaxSize = 256; -static const char * IVRNotifications_Version = "IVRNotifications_002"; +static const char *IVRNotifications_Version = "IVRNotifications_002"; static const unsigned int k_unMaxSettingsKeyLength = 128; -static const char * IVRSettings_Version = "IVRSettings_002"; -static const char * k_pch_SteamVR_Section = "steamvr"; -static const char * k_pch_SteamVR_RequireHmd_String = "requireHmd"; -static const char * k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; -static const char * k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; -static const char * k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; -static const char * k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; -static const char * k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; -static const char * k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; -static const char * k_pch_SteamVR_SendSystemButtonToAllApps_Bool = "sendSystemButtonToAllApps"; -static const char * k_pch_SteamVR_LogLevel_Int32 = "loglevel"; -static const char * k_pch_SteamVR_IPD_Float = "ipd"; -static const char * k_pch_SteamVR_Background_String = "background"; -static const char * k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; -static const char * k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; -static const char * k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; -static const char * k_pch_SteamVR_GridColor_String = "gridColor"; -static const char * k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; -static const char * k_pch_SteamVR_ShowStage_Bool = "showStage"; -static const char * k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; -static const char * k_pch_SteamVR_DirectMode_Bool = "directMode"; -static const char * k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; -static const char * k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; -static const char * k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; -static const char * k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; -static const char * k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; -static const char * k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; -static const char * k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; -static const char * k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; -static const char * k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; -static const char * k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; -static const char * k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; -static const char * k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; -static const char * k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; -static const char * k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; -static const char * k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; -static const char * k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; -static const char * k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; -static const char * k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; -static const char * k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; -static const char * k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; -static const char * k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; -static const char * k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; -static const char * k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; -static const char * k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; -static const char * k_pch_Lighthouse_Section = "driver_lighthouse"; -static const char * k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; -static const char * k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; -static const char * k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; -static const char * k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; -static const char * k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; -static const char * k_pch_Null_Section = "driver_null"; -static const char * k_pch_Null_SerialNumber_String = "serialNumber"; -static const char * k_pch_Null_ModelNumber_String = "modelNumber"; -static const char * k_pch_Null_WindowX_Int32 = "windowX"; -static const char * k_pch_Null_WindowY_Int32 = "windowY"; -static const char * k_pch_Null_WindowWidth_Int32 = "windowWidth"; -static const char * k_pch_Null_WindowHeight_Int32 = "windowHeight"; -static const char * k_pch_Null_RenderWidth_Int32 = "renderWidth"; -static const char * k_pch_Null_RenderHeight_Int32 = "renderHeight"; -static const char * k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; -static const char * k_pch_Null_DisplayFrequency_Float = "displayFrequency"; -static const char * k_pch_UserInterface_Section = "userinterface"; -static const char * k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; -static const char * k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; -static const char * k_pch_UserInterface_Screenshots_Bool = "screenshots"; -static const char * k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; -static const char * k_pch_Notifications_Section = "notifications"; -static const char * k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; -static const char * k_pch_Keyboard_Section = "keyboard"; -static const char * k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; -static const char * k_pch_Keyboard_ScaleX = "ScaleX"; -static const char * k_pch_Keyboard_ScaleY = "ScaleY"; -static const char * k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; -static const char * k_pch_Keyboard_OffsetRightX = "OffsetRightX"; -static const char * k_pch_Keyboard_OffsetY = "OffsetY"; -static const char * k_pch_Keyboard_Smoothing = "Smoothing"; -static const char * k_pch_Perf_Section = "perfcheck"; -static const char * k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; -static const char * k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; -static const char * k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; -static const char * k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; -static const char * k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; -static const char * k_pch_Perf_TestData_Float = "perfTestData"; -static const char * k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; -static const char * k_pch_CollisionBounds_Section = "collisionBounds"; -static const char * k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; -static const char * k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; -static const char * k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; -static const char * k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; -static const char * k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; -static const char * k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; -static const char * k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; -static const char * k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; -static const char * k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; -static const char * k_pch_Camera_Section = "camera"; -static const char * k_pch_Camera_EnableCamera_Bool = "enableCamera"; -static const char * k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; -static const char * k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; -static const char * k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; -static const char * k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; -static const char * k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; -static const char * k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; -static const char * k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; -static const char * k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; -static const char * k_pch_audio_Section = "audio"; -static const char * k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; -static const char * k_pch_audio_OnRecordDevice_String = "onRecordDevice"; -static const char * k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; -static const char * k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; -static const char * k_pch_audio_OffRecordDevice_String = "offRecordDevice"; -static const char * k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; -static const char * k_pch_Power_Section = "power"; -static const char * k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; -static const char * k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; -static const char * k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; -static const char * k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; -static const char * k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; -static const char * k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; -static const char * k_pch_Dashboard_Section = "dashboard"; -static const char * k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; -static const char * k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; -static const char * k_pch_modelskin_Section = "modelskins"; -static const char * k_pch_Driver_Enable_Bool = "enable"; -static const char * IVRScreenshots_Version = "IVRScreenshots_001"; -static const char * IVRResources_Version = "IVRResources_001"; -static const char * IVRDriverManager_Version = "IVRDriverManager_001"; +static const char *IVRSettings_Version = "IVRSettings_002"; +static const char *k_pch_SteamVR_Section = "steamvr"; +static const char *k_pch_SteamVR_RequireHmd_String = "requireHmd"; +static const char *k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; +static const char *k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; +static const char *k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; +static const char *k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; +static const char *k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; +static const char *k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; +static const char *k_pch_SteamVR_SendSystemButtonToAllApps_Bool = "sendSystemButtonToAllApps"; +static const char *k_pch_SteamVR_LogLevel_Int32 = "loglevel"; +static const char *k_pch_SteamVR_IPD_Float = "ipd"; +static const char *k_pch_SteamVR_Background_String = "background"; +static const char *k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; +static const char *k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; +static const char *k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; +static const char *k_pch_SteamVR_GridColor_String = "gridColor"; +static const char *k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; +static const char *k_pch_SteamVR_ShowStage_Bool = "showStage"; +static const char *k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; +static const char *k_pch_SteamVR_DirectMode_Bool = "directMode"; +static const char *k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; +static const char *k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; +static const char *k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; +static const char *k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; +static const char *k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; +static const char *k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; +static const char *k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; +static const char *k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; +static const char *k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; +static const char *k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; +static const char *k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; +static const char *k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; +static const char *k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; +static const char *k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; +static const char *k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; +static const char *k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; +static const char *k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; +static const char *k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; +static const char *k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; +static const char *k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; +static const char *k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; +static const char *k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; +static const char *k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; +static const char *k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; +static const char *k_pch_Lighthouse_Section = "driver_lighthouse"; +static const char *k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; +static const char *k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; +static const char *k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; +static const char *k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; +static const char *k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; +static const char *k_pch_Null_Section = "driver_null"; +static const char *k_pch_Null_SerialNumber_String = "serialNumber"; +static const char *k_pch_Null_ModelNumber_String = "modelNumber"; +static const char *k_pch_Null_WindowX_Int32 = "windowX"; +static const char *k_pch_Null_WindowY_Int32 = "windowY"; +static const char *k_pch_Null_WindowWidth_Int32 = "windowWidth"; +static const char *k_pch_Null_WindowHeight_Int32 = "windowHeight"; +static const char *k_pch_Null_RenderWidth_Int32 = "renderWidth"; +static const char *k_pch_Null_RenderHeight_Int32 = "renderHeight"; +static const char *k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; +static const char *k_pch_Null_DisplayFrequency_Float = "displayFrequency"; +static const char *k_pch_UserInterface_Section = "userinterface"; +static const char *k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; +static const char *k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; +static const char *k_pch_UserInterface_Screenshots_Bool = "screenshots"; +static const char *k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; +static const char *k_pch_Notifications_Section = "notifications"; +static const char *k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; +static const char *k_pch_Keyboard_Section = "keyboard"; +static const char *k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; +static const char *k_pch_Keyboard_ScaleX = "ScaleX"; +static const char *k_pch_Keyboard_ScaleY = "ScaleY"; +static const char *k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; +static const char *k_pch_Keyboard_OffsetRightX = "OffsetRightX"; +static const char *k_pch_Keyboard_OffsetY = "OffsetY"; +static const char *k_pch_Keyboard_Smoothing = "Smoothing"; +static const char *k_pch_Perf_Section = "perfcheck"; +static const char *k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; +static const char *k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; +static const char *k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; +static const char *k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; +static const char *k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; +static const char *k_pch_Perf_TestData_Float = "perfTestData"; +static const char *k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; +static const char *k_pch_CollisionBounds_Section = "collisionBounds"; +static const char *k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; +static const char *k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; +static const char *k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; +static const char *k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; +static const char *k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; +static const char *k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; +static const char *k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; +static const char *k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; +static const char *k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; +static const char *k_pch_Camera_Section = "camera"; +static const char *k_pch_Camera_EnableCamera_Bool = "enableCamera"; +static const char *k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; +static const char *k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; +static const char *k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; +static const char *k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; +static const char *k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; +static const char *k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; +static const char *k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; +static const char *k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; +static const char *k_pch_audio_Section = "audio"; +static const char *k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; +static const char *k_pch_audio_OnRecordDevice_String = "onRecordDevice"; +static const char *k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; +static const char *k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; +static const char *k_pch_audio_OffRecordDevice_String = "offRecordDevice"; +static const char *k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; +static const char *k_pch_Power_Section = "power"; +static const char *k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; +static const char *k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; +static const char *k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; +static const char *k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; +static const char *k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; +static const char *k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; +static const char *k_pch_Dashboard_Section = "dashboard"; +static const char *k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; +static const char *k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; +static const char *k_pch_modelskin_Section = "modelskins"; +static const char *k_pch_Driver_Enable_Bool = "enable"; +static const char *IVRScreenshots_Version = "IVRScreenshots_001"; +static const char *IVRResources_Version = "IVRResources_001"; +static const char *IVRDriverManager_Version = "IVRDriverManager_001"; // OpenVR Enums @@ -1062,14 +1061,13 @@ typedef enum EVRScreenshotError EVRScreenshotError_VRScreenshotError_ScreenshotAlreadyInProgress = 108, } EVRScreenshotError; - // OpenVR typedefs typedef uint32_t TrackedDeviceIndex_t; typedef uint32_t VRNotificationId; typedef uint64_t VROverlayHandle_t; -typedef void * glSharedTextureHandle_t; +typedef void *glSharedTextureHandle_t; typedef int32_t glInt_t; typedef uint32_t glUInt_t; typedef uint64_t SharedTextureHandle_t; @@ -1103,32 +1101,32 @@ typedef EVRScreenshotError VRScreenshotsError; typedef struct HmdMatrix34_t { - float m[3][4]; //float[3][4] + float m[3][4]; //float[3][4] } HmdMatrix34_t; typedef struct HmdMatrix44_t { - float m[4][4]; //float[4][4] + float m[4][4]; //float[4][4] } HmdMatrix44_t; typedef struct HmdVector3_t { - float v[3]; //float[3] + float v[3]; //float[3] } HmdVector3_t; typedef struct HmdVector4_t { - float v[4]; //float[4] + float v[4]; //float[4] } HmdVector4_t; typedef struct HmdVector3d_t { - double v[3]; //double[3] + double v[3]; //double[3] } HmdVector3d_t; typedef struct HmdVector2_t { - float v[2]; //float[2] + float v[2]; //float[2] } HmdVector2_t; typedef struct HmdQuaternion_t @@ -1149,7 +1147,7 @@ typedef struct HmdColor_t typedef struct HmdQuad_t { - struct HmdVector3_t vCorners[4]; //struct vr::HmdVector3_t[4] + struct HmdVector3_t vCorners[4]; //struct vr::HmdVector3_t[4] } HmdQuad_t; typedef struct HmdRect2_t @@ -1160,14 +1158,14 @@ typedef struct HmdRect2_t typedef struct DistortionCoordinates_t { - float rfRed[2]; //float[2] - float rfGreen[2]; //float[2] - float rfBlue[2]; //float[2] + float rfRed[2]; //float[2] + float rfGreen[2]; //float[2] + float rfBlue[2]; //float[2] } DistortionCoordinates_t; typedef struct Texture_t { - void * handle; // void * + void *handle; // void * enum ETextureType eType; enum EColorSpace eColorSpace; } Texture_t; @@ -1198,10 +1196,10 @@ typedef struct VRTextureWithPose_t typedef struct VRVulkanTextureData_t { uint64_t m_nImage; - struct VkDevice_T * m_pDevice; // struct VkDevice_T * - struct VkPhysicalDevice_T * m_pPhysicalDevice; // struct VkPhysicalDevice_T * - struct VkInstance_T * m_pInstance; // struct VkInstance_T * - struct VkQueue_T * m_pQueue; // struct VkQueue_T * + struct VkDevice_T *m_pDevice; // struct VkDevice_T * + struct VkPhysicalDevice_T *m_pPhysicalDevice; // struct VkPhysicalDevice_T * + struct VkInstance_T *m_pInstance; // struct VkInstance_T * + struct VkQueue_T *m_pQueue; // struct VkQueue_T * uint32_t m_nQueueFamilyIndex; uint32_t m_nWidth; uint32_t m_nHeight; @@ -1211,8 +1209,8 @@ typedef struct VRVulkanTextureData_t typedef struct D3D12TextureData_t { - struct ID3D12Resource * m_pResource; // struct ID3D12Resource * - struct ID3D12CommandQueue * m_pCommandQueue; // struct ID3D12CommandQueue * + struct ID3D12Resource *m_pResource; // struct ID3D12Resource * + struct ID3D12CommandQueue *m_pCommandQueue; // struct ID3D12CommandQueue * uint32_t m_nNodeMask; } D3D12TextureData_t; @@ -1270,7 +1268,7 @@ typedef struct VREvent_Status_t typedef struct VREvent_Keyboard_t { - char * cNewInput[8]; //char[8] + char *cNewInput[8]; //char[8] uint64_t uUserValue; } VREvent_Keyboard_t; @@ -1337,7 +1335,7 @@ typedef struct VREvent_Property_t typedef struct HiddenAreaMesh_t { - struct HmdVector2_t * pVertexData; // const struct vr::HmdVector2_t * + struct HmdVector2_t *pVertexData; // const struct vr::HmdVector2_t * uint32_t unTriangleCount; } HiddenAreaMesh_t; @@ -1352,7 +1350,7 @@ typedef struct VRControllerState_t uint32_t unPacketNum; uint64_t ulButtonPressed; uint64_t ulButtonTouched; - struct VRControllerAxis_t rAxis[5]; //struct vr::VRControllerAxis_t[5] + struct VRControllerAxis_t rAxis[5]; //struct vr::VRControllerAxis_t[5] } VRControllerState_t; typedef struct Compositor_OverlaySettings @@ -1385,8 +1383,8 @@ typedef struct CameraVideoStreamFrameHeader_t typedef struct AppOverrideKeys_t { - char * pchKey; // const char * - char * pchValue; // const char * + char *pchKey; // const char * + char *pchValue; // const char * } AppOverrideKeys_t; typedef struct Compositor_FrameTiming @@ -1477,36 +1475,36 @@ typedef struct RenderModel_Vertex_t { struct HmdVector3_t vPosition; struct HmdVector3_t vNormal; - float rfTextureCoord[2]; //float[2] + float rfTextureCoord[2]; //float[2] } RenderModel_Vertex_t; #if defined(__linux__) || defined(__APPLE__) -#pragma pack( push, 4 ) +#pragma pack(push, 4) #endif typedef struct RenderModel_TextureMap_t { uint16_t unWidth; uint16_t unHeight; - uint8_t * rubTextureMapData; // const uint8_t * + uint8_t *rubTextureMapData; // const uint8_t * } RenderModel_TextureMap_t; #if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#pragma pack(pop) #endif #if defined(__linux__) || defined(__APPLE__) -#pragma pack( push, 4 ) +#pragma pack(push, 4) #endif typedef struct RenderModel_t { - struct RenderModel_Vertex_t * rVertexData; // const struct vr::RenderModel_Vertex_t * + struct RenderModel_Vertex_t *rVertexData; // const struct vr::RenderModel_Vertex_t * uint32_t unVertexCount; - uint16_t * rIndexData; // const uint16_t * + uint16_t *rIndexData; // const uint16_t * uint32_t unTriangleCount; TextureID_t diffuseTextureId; } RenderModel_t; #if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#pragma pack(pop) #endif typedef struct RenderModel_ControllerMode_State_t { @@ -1515,7 +1513,7 @@ typedef struct RenderModel_ControllerMode_State_t typedef struct NotificationBitmap_t { - void * m_pImageData; // void * + void *m_pImageData; // void * int32_t m_nWidth; int32_t m_nHeight; int32_t m_nBytesPerPixel; @@ -1523,24 +1521,22 @@ typedef struct NotificationBitmap_t typedef struct COpenVRContext { - intptr_t m_pVRSystem; // class vr::IVRSystem * - intptr_t m_pVRChaperone; // class vr::IVRChaperone * - intptr_t m_pVRChaperoneSetup; // class vr::IVRChaperoneSetup * - intptr_t m_pVRCompositor; // class vr::IVRCompositor * - intptr_t m_pVROverlay; // class vr::IVROverlay * - intptr_t m_pVRResources; // class vr::IVRResources * - intptr_t m_pVRRenderModels; // class vr::IVRRenderModels * - intptr_t m_pVRExtendedDisplay; // class vr::IVRExtendedDisplay * - intptr_t m_pVRSettings; // class vr::IVRSettings * - intptr_t m_pVRApplications; // class vr::IVRApplications * - intptr_t m_pVRTrackedCamera; // class vr::IVRTrackedCamera * - intptr_t m_pVRScreenshots; // class vr::IVRScreenshots * - intptr_t m_pVRDriverManager; // class vr::IVRDriverManager * + intptr_t m_pVRSystem; // class vr::IVRSystem * + intptr_t m_pVRChaperone; // class vr::IVRChaperone * + intptr_t m_pVRChaperoneSetup; // class vr::IVRChaperoneSetup * + intptr_t m_pVRCompositor; // class vr::IVRCompositor * + intptr_t m_pVROverlay; // class vr::IVROverlay * + intptr_t m_pVRResources; // class vr::IVRResources * + intptr_t m_pVRRenderModels; // class vr::IVRRenderModels * + intptr_t m_pVRExtendedDisplay; // class vr::IVRExtendedDisplay * + intptr_t m_pVRSettings; // class vr::IVRSettings * + intptr_t m_pVRApplications; // class vr::IVRApplications * + intptr_t m_pVRTrackedCamera; // class vr::IVRTrackedCamera * + intptr_t m_pVRScreenshots; // class vr::IVRScreenshots * + intptr_t m_pVRDriverManager; // class vr::IVRDriverManager * } COpenVRContext; - -typedef union -{ +typedef union { VREvent_Reserved_t reserved; VREvent_Controller_t controller; VREvent_Mouse_t mouse; @@ -1560,16 +1556,14 @@ typedef union /** An event posted by the server to all running applications */ struct VREvent_t { - uint32_t eventType; // EVREventType enum + uint32_t eventType; // EVREventType enum TrackedDeviceIndex_t trackedDeviceIndex; float eventAgeSeconds; // event data must be the end of the struct as its size is variable VREvent_Data_t data; }; - -typedef union -{ +typedef union { IntersectionMaskRectangle_t m_Rectangle; IntersectionMaskCircle_t m_Circle; } VROverlayIntersectionMaskPrimitive_Data_t; @@ -1580,352 +1574,350 @@ struct VROverlayIntersectionMaskPrimitive_t VROverlayIntersectionMaskPrimitive_Data_t m_Primitive; }; - // OpenVR Function Pointer Tables struct VR_IVRSystem_FnTable { - void (OPENVR_FNTABLE_CALLTYPE *GetRecommendedRenderTargetSize)(uint32_t * pnWidth, uint32_t * pnHeight); - struct HmdMatrix44_t (OPENVR_FNTABLE_CALLTYPE *GetProjectionMatrix)(EVREye eEye, float fNearZ, float fFarZ); - void (OPENVR_FNTABLE_CALLTYPE *GetProjectionRaw)(EVREye eEye, float * pfLeft, float * pfRight, float * pfTop, float * pfBottom); - bool (OPENVR_FNTABLE_CALLTYPE *ComputeDistortion)(EVREye eEye, float fU, float fV, struct DistortionCoordinates_t * pDistortionCoordinates); - struct HmdMatrix34_t (OPENVR_FNTABLE_CALLTYPE *GetEyeToHeadTransform)(EVREye eEye); - bool (OPENVR_FNTABLE_CALLTYPE *GetTimeSinceLastVsync)(float * pfSecondsSinceLastVsync, uint64_t * pulFrameCounter); - int32_t (OPENVR_FNTABLE_CALLTYPE *GetD3D9AdapterIndex)(); - void (OPENVR_FNTABLE_CALLTYPE *GetDXGIOutputInfo)(int32_t * pnAdapterIndex); - void (OPENVR_FNTABLE_CALLTYPE *GetOutputDevice)(uint64_t * pnDevice, ETextureType textureType, struct VkInstance_T * pInstance); - bool (OPENVR_FNTABLE_CALLTYPE *IsDisplayOnDesktop)(); - bool (OPENVR_FNTABLE_CALLTYPE *SetDisplayVisibility)(bool bIsVisibleOnDesktop); - void (OPENVR_FNTABLE_CALLTYPE *GetDeviceToAbsoluteTrackingPose)(ETrackingUniverseOrigin eOrigin, float fPredictedSecondsToPhotonsFromNow, struct TrackedDevicePose_t * pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount); - void (OPENVR_FNTABLE_CALLTYPE *ResetSeatedZeroPose)(); - struct HmdMatrix34_t (OPENVR_FNTABLE_CALLTYPE *GetSeatedZeroPoseToStandingAbsoluteTrackingPose)(); - struct HmdMatrix34_t (OPENVR_FNTABLE_CALLTYPE *GetRawZeroPoseToStandingAbsoluteTrackingPose)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetSortedTrackedDeviceIndicesOfClass)(ETrackedDeviceClass eTrackedDeviceClass, TrackedDeviceIndex_t * punTrackedDeviceIndexArray, uint32_t unTrackedDeviceIndexArrayCount, TrackedDeviceIndex_t unRelativeToTrackedDeviceIndex); - EDeviceActivityLevel (OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceActivityLevel)(TrackedDeviceIndex_t unDeviceId); - void (OPENVR_FNTABLE_CALLTYPE *ApplyTransform)(struct TrackedDevicePose_t * pOutputPose, struct TrackedDevicePose_t * pTrackedDevicePose, struct HmdMatrix34_t * pTransform); - TrackedDeviceIndex_t (OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceIndexForControllerRole)(ETrackedControllerRole unDeviceType); - ETrackedControllerRole (OPENVR_FNTABLE_CALLTYPE *GetControllerRoleForTrackedDeviceIndex)(TrackedDeviceIndex_t unDeviceIndex); - ETrackedDeviceClass (OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceClass)(TrackedDeviceIndex_t unDeviceIndex); - bool (OPENVR_FNTABLE_CALLTYPE *IsTrackedDeviceConnected)(TrackedDeviceIndex_t unDeviceIndex); - bool (OPENVR_FNTABLE_CALLTYPE *GetBoolTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); - float (OPENVR_FNTABLE_CALLTYPE *GetFloatTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); - int32_t (OPENVR_FNTABLE_CALLTYPE *GetInt32TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); - uint64_t (OPENVR_FNTABLE_CALLTYPE *GetUint64TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); - struct HmdMatrix34_t (OPENVR_FNTABLE_CALLTYPE *GetMatrix34TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetStringTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, char * pchValue, uint32_t unBufferSize, ETrackedPropertyError * pError); - char * (OPENVR_FNTABLE_CALLTYPE *GetPropErrorNameFromEnum)(ETrackedPropertyError error); - bool (OPENVR_FNTABLE_CALLTYPE *PollNextEvent)(struct VREvent_t * pEvent, uint32_t uncbVREvent); - bool (OPENVR_FNTABLE_CALLTYPE *PollNextEventWithPose)(ETrackingUniverseOrigin eOrigin, struct VREvent_t * pEvent, uint32_t uncbVREvent, TrackedDevicePose_t * pTrackedDevicePose); - char * (OPENVR_FNTABLE_CALLTYPE *GetEventTypeNameFromEnum)(EVREventType eType); - struct HiddenAreaMesh_t (OPENVR_FNTABLE_CALLTYPE *GetHiddenAreaMesh)(EVREye eEye, EHiddenAreaMeshType type); - bool (OPENVR_FNTABLE_CALLTYPE *GetControllerState)(TrackedDeviceIndex_t unControllerDeviceIndex, VRControllerState_t * pControllerState, uint32_t unControllerStateSize); - bool (OPENVR_FNTABLE_CALLTYPE *GetControllerStateWithPose)(ETrackingUniverseOrigin eOrigin, TrackedDeviceIndex_t unControllerDeviceIndex, VRControllerState_t * pControllerState, uint32_t unControllerStateSize, struct TrackedDevicePose_t * pTrackedDevicePose); - void (OPENVR_FNTABLE_CALLTYPE *TriggerHapticPulse)(TrackedDeviceIndex_t unControllerDeviceIndex, uint32_t unAxisId, unsigned short usDurationMicroSec); - char * (OPENVR_FNTABLE_CALLTYPE *GetButtonIdNameFromEnum)(EVRButtonId eButtonId); - char * (OPENVR_FNTABLE_CALLTYPE *GetControllerAxisTypeNameFromEnum)(EVRControllerAxisType eAxisType); - bool (OPENVR_FNTABLE_CALLTYPE *CaptureInputFocus)(); - void (OPENVR_FNTABLE_CALLTYPE *ReleaseInputFocus)(); - bool (OPENVR_FNTABLE_CALLTYPE *IsInputFocusCapturedByAnotherProcess)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *DriverDebugRequest)(TrackedDeviceIndex_t unDeviceIndex, char * pchRequest, char * pchResponseBuffer, uint32_t unResponseBufferSize); - EVRFirmwareError (OPENVR_FNTABLE_CALLTYPE *PerformFirmwareUpdate)(TrackedDeviceIndex_t unDeviceIndex); - void (OPENVR_FNTABLE_CALLTYPE *AcknowledgeQuit_Exiting)(); - void (OPENVR_FNTABLE_CALLTYPE *AcknowledgeQuit_UserPrompt)(); + void(OPENVR_FNTABLE_CALLTYPE *GetRecommendedRenderTargetSize)(uint32_t *pnWidth, uint32_t *pnHeight); + struct HmdMatrix44_t(OPENVR_FNTABLE_CALLTYPE *GetProjectionMatrix)(EVREye eEye, float fNearZ, float fFarZ); + void(OPENVR_FNTABLE_CALLTYPE *GetProjectionRaw)(EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom); + bool(OPENVR_FNTABLE_CALLTYPE *ComputeDistortion)(EVREye eEye, float fU, float fV, struct DistortionCoordinates_t *pDistortionCoordinates); + struct HmdMatrix34_t(OPENVR_FNTABLE_CALLTYPE *GetEyeToHeadTransform)(EVREye eEye); + bool(OPENVR_FNTABLE_CALLTYPE *GetTimeSinceLastVsync)(float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter); + int32_t(OPENVR_FNTABLE_CALLTYPE *GetD3D9AdapterIndex)(); + void(OPENVR_FNTABLE_CALLTYPE *GetDXGIOutputInfo)(int32_t *pnAdapterIndex); + void(OPENVR_FNTABLE_CALLTYPE *GetOutputDevice)(uint64_t *pnDevice, ETextureType textureType, struct VkInstance_T *pInstance); + bool(OPENVR_FNTABLE_CALLTYPE *IsDisplayOnDesktop)(); + bool(OPENVR_FNTABLE_CALLTYPE *SetDisplayVisibility)(bool bIsVisibleOnDesktop); + void(OPENVR_FNTABLE_CALLTYPE *GetDeviceToAbsoluteTrackingPose)(ETrackingUniverseOrigin eOrigin, float fPredictedSecondsToPhotonsFromNow, struct TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount); + void(OPENVR_FNTABLE_CALLTYPE *ResetSeatedZeroPose)(); + struct HmdMatrix34_t(OPENVR_FNTABLE_CALLTYPE *GetSeatedZeroPoseToStandingAbsoluteTrackingPose)(); + struct HmdMatrix34_t(OPENVR_FNTABLE_CALLTYPE *GetRawZeroPoseToStandingAbsoluteTrackingPose)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetSortedTrackedDeviceIndicesOfClass)(ETrackedDeviceClass eTrackedDeviceClass, TrackedDeviceIndex_t *punTrackedDeviceIndexArray, uint32_t unTrackedDeviceIndexArrayCount, TrackedDeviceIndex_t unRelativeToTrackedDeviceIndex); + EDeviceActivityLevel(OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceActivityLevel)(TrackedDeviceIndex_t unDeviceId); + void(OPENVR_FNTABLE_CALLTYPE *ApplyTransform)(struct TrackedDevicePose_t *pOutputPose, struct TrackedDevicePose_t *pTrackedDevicePose, struct HmdMatrix34_t *pTransform); + TrackedDeviceIndex_t(OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceIndexForControllerRole)(ETrackedControllerRole unDeviceType); + ETrackedControllerRole(OPENVR_FNTABLE_CALLTYPE *GetControllerRoleForTrackedDeviceIndex)(TrackedDeviceIndex_t unDeviceIndex); + ETrackedDeviceClass(OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceClass)(TrackedDeviceIndex_t unDeviceIndex); + bool(OPENVR_FNTABLE_CALLTYPE *IsTrackedDeviceConnected)(TrackedDeviceIndex_t unDeviceIndex); + bool(OPENVR_FNTABLE_CALLTYPE *GetBoolTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError); + float(OPENVR_FNTABLE_CALLTYPE *GetFloatTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError); + int32_t(OPENVR_FNTABLE_CALLTYPE *GetInt32TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError); + uint64_t(OPENVR_FNTABLE_CALLTYPE *GetUint64TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError); + struct HmdMatrix34_t(OPENVR_FNTABLE_CALLTYPE *GetMatrix34TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetStringTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError); + char *(OPENVR_FNTABLE_CALLTYPE *GetPropErrorNameFromEnum)(ETrackedPropertyError error); + bool(OPENVR_FNTABLE_CALLTYPE *PollNextEvent)(struct VREvent_t *pEvent, uint32_t uncbVREvent); + bool(OPENVR_FNTABLE_CALLTYPE *PollNextEventWithPose)(ETrackingUniverseOrigin eOrigin, struct VREvent_t *pEvent, uint32_t uncbVREvent, TrackedDevicePose_t *pTrackedDevicePose); + char *(OPENVR_FNTABLE_CALLTYPE *GetEventTypeNameFromEnum)(EVREventType eType); + struct HiddenAreaMesh_t(OPENVR_FNTABLE_CALLTYPE *GetHiddenAreaMesh)(EVREye eEye, EHiddenAreaMeshType type); + bool(OPENVR_FNTABLE_CALLTYPE *GetControllerState)(TrackedDeviceIndex_t unControllerDeviceIndex, VRControllerState_t *pControllerState, uint32_t unControllerStateSize); + bool(OPENVR_FNTABLE_CALLTYPE *GetControllerStateWithPose)(ETrackingUniverseOrigin eOrigin, TrackedDeviceIndex_t unControllerDeviceIndex, VRControllerState_t *pControllerState, uint32_t unControllerStateSize, struct TrackedDevicePose_t *pTrackedDevicePose); + void(OPENVR_FNTABLE_CALLTYPE *TriggerHapticPulse)(TrackedDeviceIndex_t unControllerDeviceIndex, uint32_t unAxisId, unsigned short usDurationMicroSec); + char *(OPENVR_FNTABLE_CALLTYPE *GetButtonIdNameFromEnum)(EVRButtonId eButtonId); + char *(OPENVR_FNTABLE_CALLTYPE *GetControllerAxisTypeNameFromEnum)(EVRControllerAxisType eAxisType); + bool(OPENVR_FNTABLE_CALLTYPE *CaptureInputFocus)(); + void(OPENVR_FNTABLE_CALLTYPE *ReleaseInputFocus)(); + bool(OPENVR_FNTABLE_CALLTYPE *IsInputFocusCapturedByAnotherProcess)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *DriverDebugRequest)(TrackedDeviceIndex_t unDeviceIndex, char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize); + EVRFirmwareError(OPENVR_FNTABLE_CALLTYPE *PerformFirmwareUpdate)(TrackedDeviceIndex_t unDeviceIndex); + void(OPENVR_FNTABLE_CALLTYPE *AcknowledgeQuit_Exiting)(); + void(OPENVR_FNTABLE_CALLTYPE *AcknowledgeQuit_UserPrompt)(); }; struct VR_IVRExtendedDisplay_FnTable { - void (OPENVR_FNTABLE_CALLTYPE *GetWindowBounds)(int32_t * pnX, int32_t * pnY, uint32_t * pnWidth, uint32_t * pnHeight); - void (OPENVR_FNTABLE_CALLTYPE *GetEyeOutputViewport)(EVREye eEye, uint32_t * pnX, uint32_t * pnY, uint32_t * pnWidth, uint32_t * pnHeight); - void (OPENVR_FNTABLE_CALLTYPE *GetDXGIOutputInfo)(int32_t * pnAdapterIndex, int32_t * pnAdapterOutputIndex); + void(OPENVR_FNTABLE_CALLTYPE *GetWindowBounds)(int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight); + void(OPENVR_FNTABLE_CALLTYPE *GetEyeOutputViewport)(EVREye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight); + void(OPENVR_FNTABLE_CALLTYPE *GetDXGIOutputInfo)(int32_t *pnAdapterIndex, int32_t *pnAdapterOutputIndex); }; struct VR_IVRTrackedCamera_FnTable { - char * (OPENVR_FNTABLE_CALLTYPE *GetCameraErrorNameFromEnum)(EVRTrackedCameraError eCameraError); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *HasCamera)(TrackedDeviceIndex_t nDeviceIndex, bool * pHasCamera); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetCameraFrameSize)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, uint32_t * pnWidth, uint32_t * pnHeight, uint32_t * pnFrameBufferSize); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetCameraIntrinsics)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, HmdVector2_t * pFocalLength, HmdVector2_t * pCenter); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetCameraProjection)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, HmdMatrix44_t * pProjection); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *AcquireVideoStreamingService)(TrackedDeviceIndex_t nDeviceIndex, TrackedCameraHandle_t * pHandle); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *ReleaseVideoStreamingService)(TrackedCameraHandle_t hTrackedCamera); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetVideoStreamFrameBuffer)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, void * pFrameBuffer, uint32_t nFrameBufferSize, CameraVideoStreamFrameHeader_t * pFrameHeader, uint32_t nFrameHeaderSize); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureSize)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, VRTextureBounds_t * pTextureBounds, uint32_t * pnWidth, uint32_t * pnHeight); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureD3D11)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, void * pD3D11DeviceOrResource, void ** ppD3D11ShaderResourceView, CameraVideoStreamFrameHeader_t * pFrameHeader, uint32_t nFrameHeaderSize); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureGL)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, glUInt_t * pglTextureId, CameraVideoStreamFrameHeader_t * pFrameHeader, uint32_t nFrameHeaderSize); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *ReleaseVideoStreamTextureGL)(TrackedCameraHandle_t hTrackedCamera, glUInt_t glTextureId); + char *(OPENVR_FNTABLE_CALLTYPE *GetCameraErrorNameFromEnum)(EVRTrackedCameraError eCameraError); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *HasCamera)(TrackedDeviceIndex_t nDeviceIndex, bool *pHasCamera); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetCameraFrameSize)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, uint32_t *pnWidth, uint32_t *pnHeight, uint32_t *pnFrameBufferSize); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetCameraIntrinsics)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, HmdVector2_t *pFocalLength, HmdVector2_t *pCenter); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetCameraProjection)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, HmdMatrix44_t *pProjection); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *AcquireVideoStreamingService)(TrackedDeviceIndex_t nDeviceIndex, TrackedCameraHandle_t *pHandle); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *ReleaseVideoStreamingService)(TrackedCameraHandle_t hTrackedCamera); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetVideoStreamFrameBuffer)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, void *pFrameBuffer, uint32_t nFrameBufferSize, CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureSize)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, VRTextureBounds_t *pTextureBounds, uint32_t *pnWidth, uint32_t *pnHeight); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureD3D11)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView, CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureGL)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, glUInt_t *pglTextureId, CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *ReleaseVideoStreamTextureGL)(TrackedCameraHandle_t hTrackedCamera, glUInt_t glTextureId); }; struct VR_IVRApplications_FnTable { - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *AddApplicationManifest)(char * pchApplicationManifestFullPath, bool bTemporary); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *RemoveApplicationManifest)(char * pchApplicationManifestFullPath); - bool (OPENVR_FNTABLE_CALLTYPE *IsApplicationInstalled)(char * pchAppKey); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationCount)(); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *GetApplicationKeyByIndex)(uint32_t unApplicationIndex, char * pchAppKeyBuffer, uint32_t unAppKeyBufferLen); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *GetApplicationKeyByProcessId)(uint32_t unProcessId, char * pchAppKeyBuffer, uint32_t unAppKeyBufferLen); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchApplication)(char * pchAppKey); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchTemplateApplication)(char * pchTemplateAppKey, char * pchNewAppKey, struct AppOverrideKeys_t * pKeys, uint32_t unKeys); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchApplicationFromMimeType)(char * pchMimeType, char * pchArgs); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchDashboardOverlay)(char * pchAppKey); - bool (OPENVR_FNTABLE_CALLTYPE *CancelApplicationLaunch)(char * pchAppKey); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *IdentifyApplication)(uint32_t unProcessId, char * pchAppKey); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationProcessId)(char * pchAppKey); - char * (OPENVR_FNTABLE_CALLTYPE *GetApplicationsErrorNameFromEnum)(EVRApplicationError error); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyString)(char * pchAppKey, EVRApplicationProperty eProperty, char * pchPropertyValueBuffer, uint32_t unPropertyValueBufferLen, EVRApplicationError * peError); - bool (OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyBool)(char * pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError * peError); - uint64_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyUint64)(char * pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError * peError); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *SetApplicationAutoLaunch)(char * pchAppKey, bool bAutoLaunch); - bool (OPENVR_FNTABLE_CALLTYPE *GetApplicationAutoLaunch)(char * pchAppKey); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *SetDefaultApplicationForMimeType)(char * pchAppKey, char * pchMimeType); - bool (OPENVR_FNTABLE_CALLTYPE *GetDefaultApplicationForMimeType)(char * pchMimeType, char * pchAppKeyBuffer, uint32_t unAppKeyBufferLen); - bool (OPENVR_FNTABLE_CALLTYPE *GetApplicationSupportedMimeTypes)(char * pchAppKey, char * pchMimeTypesBuffer, uint32_t unMimeTypesBuffer); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationsThatSupportMimeType)(char * pchMimeType, char * pchAppKeysThatSupportBuffer, uint32_t unAppKeysThatSupportBuffer); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationLaunchArguments)(uint32_t unHandle, char * pchArgs, uint32_t unArgs); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *GetStartingApplication)(char * pchAppKeyBuffer, uint32_t unAppKeyBufferLen); - EVRApplicationTransitionState (OPENVR_FNTABLE_CALLTYPE *GetTransitionState)(); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *PerformApplicationPrelaunchCheck)(char * pchAppKey); - char * (OPENVR_FNTABLE_CALLTYPE *GetApplicationsTransitionStateNameFromEnum)(EVRApplicationTransitionState state); - bool (OPENVR_FNTABLE_CALLTYPE *IsQuitUserPromptRequested)(); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchInternalProcess)(char * pchBinaryPath, char * pchArguments, char * pchWorkingDirectory); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetCurrentSceneProcessId)(); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *AddApplicationManifest)(char *pchApplicationManifestFullPath, bool bTemporary); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *RemoveApplicationManifest)(char *pchApplicationManifestFullPath); + bool(OPENVR_FNTABLE_CALLTYPE *IsApplicationInstalled)(char *pchAppKey); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationCount)(); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *GetApplicationKeyByIndex)(uint32_t unApplicationIndex, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *GetApplicationKeyByProcessId)(uint32_t unProcessId, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *LaunchApplication)(char *pchAppKey); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *LaunchTemplateApplication)(char *pchTemplateAppKey, char *pchNewAppKey, struct AppOverrideKeys_t *pKeys, uint32_t unKeys); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *LaunchApplicationFromMimeType)(char *pchMimeType, char *pchArgs); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *LaunchDashboardOverlay)(char *pchAppKey); + bool(OPENVR_FNTABLE_CALLTYPE *CancelApplicationLaunch)(char *pchAppKey); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *IdentifyApplication)(uint32_t unProcessId, char *pchAppKey); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationProcessId)(char *pchAppKey); + char *(OPENVR_FNTABLE_CALLTYPE *GetApplicationsErrorNameFromEnum)(EVRApplicationError error); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyString)(char *pchAppKey, EVRApplicationProperty eProperty, char *pchPropertyValueBuffer, uint32_t unPropertyValueBufferLen, EVRApplicationError *peError); + bool(OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyBool)(char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError); + uint64_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyUint64)(char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *SetApplicationAutoLaunch)(char *pchAppKey, bool bAutoLaunch); + bool(OPENVR_FNTABLE_CALLTYPE *GetApplicationAutoLaunch)(char *pchAppKey); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *SetDefaultApplicationForMimeType)(char *pchAppKey, char *pchMimeType); + bool(OPENVR_FNTABLE_CALLTYPE *GetDefaultApplicationForMimeType)(char *pchMimeType, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen); + bool(OPENVR_FNTABLE_CALLTYPE *GetApplicationSupportedMimeTypes)(char *pchAppKey, char *pchMimeTypesBuffer, uint32_t unMimeTypesBuffer); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationsThatSupportMimeType)(char *pchMimeType, char *pchAppKeysThatSupportBuffer, uint32_t unAppKeysThatSupportBuffer); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationLaunchArguments)(uint32_t unHandle, char *pchArgs, uint32_t unArgs); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *GetStartingApplication)(char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen); + EVRApplicationTransitionState(OPENVR_FNTABLE_CALLTYPE *GetTransitionState)(); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *PerformApplicationPrelaunchCheck)(char *pchAppKey); + char *(OPENVR_FNTABLE_CALLTYPE *GetApplicationsTransitionStateNameFromEnum)(EVRApplicationTransitionState state); + bool(OPENVR_FNTABLE_CALLTYPE *IsQuitUserPromptRequested)(); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *LaunchInternalProcess)(char *pchBinaryPath, char *pchArguments, char *pchWorkingDirectory); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetCurrentSceneProcessId)(); }; struct VR_IVRChaperone_FnTable { - ChaperoneCalibrationState (OPENVR_FNTABLE_CALLTYPE *GetCalibrationState)(); - bool (OPENVR_FNTABLE_CALLTYPE *GetPlayAreaSize)(float * pSizeX, float * pSizeZ); - bool (OPENVR_FNTABLE_CALLTYPE *GetPlayAreaRect)(struct HmdQuad_t * rect); - void (OPENVR_FNTABLE_CALLTYPE *ReloadInfo)(); - void (OPENVR_FNTABLE_CALLTYPE *SetSceneColor)(struct HmdColor_t color); - void (OPENVR_FNTABLE_CALLTYPE *GetBoundsColor)(struct HmdColor_t * pOutputColorArray, int nNumOutputColors, float flCollisionBoundsFadeDistance, struct HmdColor_t * pOutputCameraColor); - bool (OPENVR_FNTABLE_CALLTYPE *AreBoundsVisible)(); - void (OPENVR_FNTABLE_CALLTYPE *ForceBoundsVisible)(bool bForce); + ChaperoneCalibrationState(OPENVR_FNTABLE_CALLTYPE *GetCalibrationState)(); + bool(OPENVR_FNTABLE_CALLTYPE *GetPlayAreaSize)(float *pSizeX, float *pSizeZ); + bool(OPENVR_FNTABLE_CALLTYPE *GetPlayAreaRect)(struct HmdQuad_t *rect); + void(OPENVR_FNTABLE_CALLTYPE *ReloadInfo)(); + void(OPENVR_FNTABLE_CALLTYPE *SetSceneColor)(struct HmdColor_t color); + void(OPENVR_FNTABLE_CALLTYPE *GetBoundsColor)(struct HmdColor_t *pOutputColorArray, int nNumOutputColors, float flCollisionBoundsFadeDistance, struct HmdColor_t *pOutputCameraColor); + bool(OPENVR_FNTABLE_CALLTYPE *AreBoundsVisible)(); + void(OPENVR_FNTABLE_CALLTYPE *ForceBoundsVisible)(bool bForce); }; struct VR_IVRChaperoneSetup_FnTable { - bool (OPENVR_FNTABLE_CALLTYPE *CommitWorkingCopy)(EChaperoneConfigFile configFile); - void (OPENVR_FNTABLE_CALLTYPE *RevertWorkingCopy)(); - bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingPlayAreaSize)(float * pSizeX, float * pSizeZ); - bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingPlayAreaRect)(struct HmdQuad_t * rect); - bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingCollisionBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t * punQuadsCount); - bool (OPENVR_FNTABLE_CALLTYPE *GetLiveCollisionBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t * punQuadsCount); - bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pmatSeatedZeroPoseToRawTrackingPose); - bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingStandingZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pmatStandingZeroPoseToRawTrackingPose); - void (OPENVR_FNTABLE_CALLTYPE *SetWorkingPlayAreaSize)(float sizeX, float sizeZ); - void (OPENVR_FNTABLE_CALLTYPE *SetWorkingCollisionBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t unQuadsCount); - void (OPENVR_FNTABLE_CALLTYPE *SetWorkingSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pMatSeatedZeroPoseToRawTrackingPose); - void (OPENVR_FNTABLE_CALLTYPE *SetWorkingStandingZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pMatStandingZeroPoseToRawTrackingPose); - void (OPENVR_FNTABLE_CALLTYPE *ReloadFromDisk)(EChaperoneConfigFile configFile); - bool (OPENVR_FNTABLE_CALLTYPE *GetLiveSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pmatSeatedZeroPoseToRawTrackingPose); - void (OPENVR_FNTABLE_CALLTYPE *SetWorkingCollisionBoundsTagsInfo)(uint8_t * pTagsBuffer, uint32_t unTagCount); - bool (OPENVR_FNTABLE_CALLTYPE *GetLiveCollisionBoundsTagsInfo)(uint8_t * pTagsBuffer, uint32_t * punTagCount); - bool (OPENVR_FNTABLE_CALLTYPE *SetWorkingPhysicalBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t unQuadsCount); - bool (OPENVR_FNTABLE_CALLTYPE *GetLivePhysicalBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t * punQuadsCount); - bool (OPENVR_FNTABLE_CALLTYPE *ExportLiveToBuffer)(char * pBuffer, uint32_t * pnBufferLength); - bool (OPENVR_FNTABLE_CALLTYPE *ImportFromBufferToWorking)(char * pBuffer, uint32_t nImportFlags); + bool(OPENVR_FNTABLE_CALLTYPE *CommitWorkingCopy)(EChaperoneConfigFile configFile); + void(OPENVR_FNTABLE_CALLTYPE *RevertWorkingCopy)(); + bool(OPENVR_FNTABLE_CALLTYPE *GetWorkingPlayAreaSize)(float *pSizeX, float *pSizeZ); + bool(OPENVR_FNTABLE_CALLTYPE *GetWorkingPlayAreaRect)(struct HmdQuad_t *rect); + bool(OPENVR_FNTABLE_CALLTYPE *GetWorkingCollisionBoundsInfo)(struct HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount); + bool(OPENVR_FNTABLE_CALLTYPE *GetLiveCollisionBoundsInfo)(struct HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount); + bool(OPENVR_FNTABLE_CALLTYPE *GetWorkingSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose); + bool(OPENVR_FNTABLE_CALLTYPE *GetWorkingStandingZeroPoseToRawTrackingPose)(struct HmdMatrix34_t *pmatStandingZeroPoseToRawTrackingPose); + void(OPENVR_FNTABLE_CALLTYPE *SetWorkingPlayAreaSize)(float sizeX, float sizeZ); + void(OPENVR_FNTABLE_CALLTYPE *SetWorkingCollisionBoundsInfo)(struct HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount); + void(OPENVR_FNTABLE_CALLTYPE *SetWorkingSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t *pMatSeatedZeroPoseToRawTrackingPose); + void(OPENVR_FNTABLE_CALLTYPE *SetWorkingStandingZeroPoseToRawTrackingPose)(struct HmdMatrix34_t *pMatStandingZeroPoseToRawTrackingPose); + void(OPENVR_FNTABLE_CALLTYPE *ReloadFromDisk)(EChaperoneConfigFile configFile); + bool(OPENVR_FNTABLE_CALLTYPE *GetLiveSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose); + void(OPENVR_FNTABLE_CALLTYPE *SetWorkingCollisionBoundsTagsInfo)(uint8_t *pTagsBuffer, uint32_t unTagCount); + bool(OPENVR_FNTABLE_CALLTYPE *GetLiveCollisionBoundsTagsInfo)(uint8_t *pTagsBuffer, uint32_t *punTagCount); + bool(OPENVR_FNTABLE_CALLTYPE *SetWorkingPhysicalBoundsInfo)(struct HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount); + bool(OPENVR_FNTABLE_CALLTYPE *GetLivePhysicalBoundsInfo)(struct HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount); + bool(OPENVR_FNTABLE_CALLTYPE *ExportLiveToBuffer)(char *pBuffer, uint32_t *pnBufferLength); + bool(OPENVR_FNTABLE_CALLTYPE *ImportFromBufferToWorking)(char *pBuffer, uint32_t nImportFlags); }; struct VR_IVRCompositor_FnTable { - void (OPENVR_FNTABLE_CALLTYPE *SetTrackingSpace)(ETrackingUniverseOrigin eOrigin); - ETrackingUniverseOrigin (OPENVR_FNTABLE_CALLTYPE *GetTrackingSpace)(); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *WaitGetPoses)(struct TrackedDevicePose_t * pRenderPoseArray, uint32_t unRenderPoseArrayCount, struct TrackedDevicePose_t * pGamePoseArray, uint32_t unGamePoseArrayCount); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *GetLastPoses)(struct TrackedDevicePose_t * pRenderPoseArray, uint32_t unRenderPoseArrayCount, struct TrackedDevicePose_t * pGamePoseArray, uint32_t unGamePoseArrayCount); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *GetLastPoseForTrackedDeviceIndex)(TrackedDeviceIndex_t unDeviceIndex, struct TrackedDevicePose_t * pOutputPose, struct TrackedDevicePose_t * pOutputGamePose); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *Submit)(EVREye eEye, struct Texture_t * pTexture, struct VRTextureBounds_t * pBounds, EVRSubmitFlags nSubmitFlags); - void (OPENVR_FNTABLE_CALLTYPE *ClearLastSubmittedFrame)(); - void (OPENVR_FNTABLE_CALLTYPE *PostPresentHandoff)(); - bool (OPENVR_FNTABLE_CALLTYPE *GetFrameTiming)(struct Compositor_FrameTiming * pTiming, uint32_t unFramesAgo); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetFrameTimings)(struct Compositor_FrameTiming * pTiming, uint32_t nFrames); - float (OPENVR_FNTABLE_CALLTYPE *GetFrameTimeRemaining)(); - void (OPENVR_FNTABLE_CALLTYPE *GetCumulativeStats)(struct Compositor_CumulativeStats * pStats, uint32_t nStatsSizeInBytes); - void (OPENVR_FNTABLE_CALLTYPE *FadeToColor)(float fSeconds, float fRed, float fGreen, float fBlue, float fAlpha, bool bBackground); - struct HmdColor_t (OPENVR_FNTABLE_CALLTYPE *GetCurrentFadeColor)(bool bBackground); - void (OPENVR_FNTABLE_CALLTYPE *FadeGrid)(float fSeconds, bool bFadeIn); - float (OPENVR_FNTABLE_CALLTYPE *GetCurrentGridAlpha)(); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *SetSkyboxOverride)(struct Texture_t * pTextures, uint32_t unTextureCount); - void (OPENVR_FNTABLE_CALLTYPE *ClearSkyboxOverride)(); - void (OPENVR_FNTABLE_CALLTYPE *CompositorBringToFront)(); - void (OPENVR_FNTABLE_CALLTYPE *CompositorGoToBack)(); - void (OPENVR_FNTABLE_CALLTYPE *CompositorQuit)(); - bool (OPENVR_FNTABLE_CALLTYPE *IsFullscreen)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetCurrentSceneFocusProcess)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetLastFrameRenderer)(); - bool (OPENVR_FNTABLE_CALLTYPE *CanRenderScene)(); - void (OPENVR_FNTABLE_CALLTYPE *ShowMirrorWindow)(); - void (OPENVR_FNTABLE_CALLTYPE *HideMirrorWindow)(); - bool (OPENVR_FNTABLE_CALLTYPE *IsMirrorWindowVisible)(); - void (OPENVR_FNTABLE_CALLTYPE *CompositorDumpImages)(); - bool (OPENVR_FNTABLE_CALLTYPE *ShouldAppRenderWithLowResources)(); - void (OPENVR_FNTABLE_CALLTYPE *ForceInterleavedReprojectionOn)(bool bOverride); - void (OPENVR_FNTABLE_CALLTYPE *ForceReconnectProcess)(); - void (OPENVR_FNTABLE_CALLTYPE *SuspendRendering)(bool bSuspend); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *GetMirrorTextureD3D11)(EVREye eEye, void * pD3D11DeviceOrResource, void ** ppD3D11ShaderResourceView); - void (OPENVR_FNTABLE_CALLTYPE *ReleaseMirrorTextureD3D11)(void * pD3D11ShaderResourceView); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *GetMirrorTextureGL)(EVREye eEye, glUInt_t * pglTextureId, glSharedTextureHandle_t * pglSharedTextureHandle); - bool (OPENVR_FNTABLE_CALLTYPE *ReleaseSharedGLTexture)(glUInt_t glTextureId, glSharedTextureHandle_t glSharedTextureHandle); - void (OPENVR_FNTABLE_CALLTYPE *LockGLSharedTextureForAccess)(glSharedTextureHandle_t glSharedTextureHandle); - void (OPENVR_FNTABLE_CALLTYPE *UnlockGLSharedTextureForAccess)(glSharedTextureHandle_t glSharedTextureHandle); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetVulkanInstanceExtensionsRequired)(char * pchValue, uint32_t unBufferSize); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetVulkanDeviceExtensionsRequired)(struct VkPhysicalDevice_T * pPhysicalDevice, char * pchValue, uint32_t unBufferSize); - void (OPENVR_FNTABLE_CALLTYPE *SetExplicitTimingMode)(bool bExplicitTimingMode); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *SubmitExplicitTimingData)(); + void(OPENVR_FNTABLE_CALLTYPE *SetTrackingSpace)(ETrackingUniverseOrigin eOrigin); + ETrackingUniverseOrigin(OPENVR_FNTABLE_CALLTYPE *GetTrackingSpace)(); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *WaitGetPoses)(struct TrackedDevicePose_t *pRenderPoseArray, uint32_t unRenderPoseArrayCount, struct TrackedDevicePose_t *pGamePoseArray, uint32_t unGamePoseArrayCount); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *GetLastPoses)(struct TrackedDevicePose_t *pRenderPoseArray, uint32_t unRenderPoseArrayCount, struct TrackedDevicePose_t *pGamePoseArray, uint32_t unGamePoseArrayCount); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *GetLastPoseForTrackedDeviceIndex)(TrackedDeviceIndex_t unDeviceIndex, struct TrackedDevicePose_t *pOutputPose, struct TrackedDevicePose_t *pOutputGamePose); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *Submit)(EVREye eEye, struct Texture_t *pTexture, struct VRTextureBounds_t *pBounds, EVRSubmitFlags nSubmitFlags); + void(OPENVR_FNTABLE_CALLTYPE *ClearLastSubmittedFrame)(); + void(OPENVR_FNTABLE_CALLTYPE *PostPresentHandoff)(); + bool(OPENVR_FNTABLE_CALLTYPE *GetFrameTiming)(struct Compositor_FrameTiming *pTiming, uint32_t unFramesAgo); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetFrameTimings)(struct Compositor_FrameTiming *pTiming, uint32_t nFrames); + float(OPENVR_FNTABLE_CALLTYPE *GetFrameTimeRemaining)(); + void(OPENVR_FNTABLE_CALLTYPE *GetCumulativeStats)(struct Compositor_CumulativeStats *pStats, uint32_t nStatsSizeInBytes); + void(OPENVR_FNTABLE_CALLTYPE *FadeToColor)(float fSeconds, float fRed, float fGreen, float fBlue, float fAlpha, bool bBackground); + struct HmdColor_t(OPENVR_FNTABLE_CALLTYPE *GetCurrentFadeColor)(bool bBackground); + void(OPENVR_FNTABLE_CALLTYPE *FadeGrid)(float fSeconds, bool bFadeIn); + float(OPENVR_FNTABLE_CALLTYPE *GetCurrentGridAlpha)(); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *SetSkyboxOverride)(struct Texture_t *pTextures, uint32_t unTextureCount); + void(OPENVR_FNTABLE_CALLTYPE *ClearSkyboxOverride)(); + void(OPENVR_FNTABLE_CALLTYPE *CompositorBringToFront)(); + void(OPENVR_FNTABLE_CALLTYPE *CompositorGoToBack)(); + void(OPENVR_FNTABLE_CALLTYPE *CompositorQuit)(); + bool(OPENVR_FNTABLE_CALLTYPE *IsFullscreen)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetCurrentSceneFocusProcess)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetLastFrameRenderer)(); + bool(OPENVR_FNTABLE_CALLTYPE *CanRenderScene)(); + void(OPENVR_FNTABLE_CALLTYPE *ShowMirrorWindow)(); + void(OPENVR_FNTABLE_CALLTYPE *HideMirrorWindow)(); + bool(OPENVR_FNTABLE_CALLTYPE *IsMirrorWindowVisible)(); + void(OPENVR_FNTABLE_CALLTYPE *CompositorDumpImages)(); + bool(OPENVR_FNTABLE_CALLTYPE *ShouldAppRenderWithLowResources)(); + void(OPENVR_FNTABLE_CALLTYPE *ForceInterleavedReprojectionOn)(bool bOverride); + void(OPENVR_FNTABLE_CALLTYPE *ForceReconnectProcess)(); + void(OPENVR_FNTABLE_CALLTYPE *SuspendRendering)(bool bSuspend); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *GetMirrorTextureD3D11)(EVREye eEye, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView); + void(OPENVR_FNTABLE_CALLTYPE *ReleaseMirrorTextureD3D11)(void *pD3D11ShaderResourceView); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *GetMirrorTextureGL)(EVREye eEye, glUInt_t *pglTextureId, glSharedTextureHandle_t *pglSharedTextureHandle); + bool(OPENVR_FNTABLE_CALLTYPE *ReleaseSharedGLTexture)(glUInt_t glTextureId, glSharedTextureHandle_t glSharedTextureHandle); + void(OPENVR_FNTABLE_CALLTYPE *LockGLSharedTextureForAccess)(glSharedTextureHandle_t glSharedTextureHandle); + void(OPENVR_FNTABLE_CALLTYPE *UnlockGLSharedTextureForAccess)(glSharedTextureHandle_t glSharedTextureHandle); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetVulkanInstanceExtensionsRequired)(char *pchValue, uint32_t unBufferSize); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetVulkanDeviceExtensionsRequired)(struct VkPhysicalDevice_T *pPhysicalDevice, char *pchValue, uint32_t unBufferSize); + void(OPENVR_FNTABLE_CALLTYPE *SetExplicitTimingMode)(bool bExplicitTimingMode); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *SubmitExplicitTimingData)(); }; struct VR_IVROverlay_FnTable { - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *FindOverlay)(char * pchOverlayKey, VROverlayHandle_t * pOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *CreateOverlay)(char * pchOverlayKey, char * pchOverlayName, VROverlayHandle_t * pOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *DestroyOverlay)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetHighQualityOverlay)(VROverlayHandle_t ulOverlayHandle); - VROverlayHandle_t (OPENVR_FNTABLE_CALLTYPE *GetHighQualityOverlay)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayKey)(VROverlayHandle_t ulOverlayHandle, char * pchValue, uint32_t unBufferSize, EVROverlayError * pError); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayName)(VROverlayHandle_t ulOverlayHandle, char * pchValue, uint32_t unBufferSize, EVROverlayError * pError); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayName)(VROverlayHandle_t ulOverlayHandle, char * pchName); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayImageData)(VROverlayHandle_t ulOverlayHandle, void * pvBuffer, uint32_t unBufferSize, uint32_t * punWidth, uint32_t * punHeight); - char * (OPENVR_FNTABLE_CALLTYPE *GetOverlayErrorNameFromEnum)(EVROverlayError error); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayRenderingPid)(VROverlayHandle_t ulOverlayHandle, uint32_t unPID); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayRenderingPid)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayFlag)(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool bEnabled); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayFlag)(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool * pbEnabled); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayColor)(VROverlayHandle_t ulOverlayHandle, float fRed, float fGreen, float fBlue); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayColor)(VROverlayHandle_t ulOverlayHandle, float * pfRed, float * pfGreen, float * pfBlue); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayAlpha)(VROverlayHandle_t ulOverlayHandle, float fAlpha); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayAlpha)(VROverlayHandle_t ulOverlayHandle, float * pfAlpha); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTexelAspect)(VROverlayHandle_t ulOverlayHandle, float fTexelAspect); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTexelAspect)(VROverlayHandle_t ulOverlayHandle, float * pfTexelAspect); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlaySortOrder)(VROverlayHandle_t ulOverlayHandle, uint32_t unSortOrder); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlaySortOrder)(VROverlayHandle_t ulOverlayHandle, uint32_t * punSortOrder); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayWidthInMeters)(VROverlayHandle_t ulOverlayHandle, float fWidthInMeters); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayWidthInMeters)(VROverlayHandle_t ulOverlayHandle, float * pfWidthInMeters); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayAutoCurveDistanceRangeInMeters)(VROverlayHandle_t ulOverlayHandle, float fMinDistanceInMeters, float fMaxDistanceInMeters); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayAutoCurveDistanceRangeInMeters)(VROverlayHandle_t ulOverlayHandle, float * pfMinDistanceInMeters, float * pfMaxDistanceInMeters); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTextureColorSpace)(VROverlayHandle_t ulOverlayHandle, EColorSpace eTextureColorSpace); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureColorSpace)(VROverlayHandle_t ulOverlayHandle, EColorSpace * peTextureColorSpace); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTextureBounds)(VROverlayHandle_t ulOverlayHandle, struct VRTextureBounds_t * pOverlayTextureBounds); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureBounds)(VROverlayHandle_t ulOverlayHandle, struct VRTextureBounds_t * pOverlayTextureBounds); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayRenderModel)(VROverlayHandle_t ulOverlayHandle, char * pchValue, uint32_t unBufferSize, struct HmdColor_t * pColor, EVROverlayError * pError); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayRenderModel)(VROverlayHandle_t ulOverlayHandle, char * pchRenderModel, struct HmdColor_t * pColor); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformType)(VROverlayHandle_t ulOverlayHandle, VROverlayTransformType * peTransformType); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformAbsolute)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, struct HmdMatrix34_t * pmatTrackingOriginToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformAbsolute)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin * peTrackingOrigin, struct HmdMatrix34_t * pmatTrackingOriginToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformTrackedDeviceRelative)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unTrackedDevice, struct HmdMatrix34_t * pmatTrackedDeviceToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformTrackedDeviceRelative)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t * punTrackedDevice, struct HmdMatrix34_t * pmatTrackedDeviceToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformTrackedDeviceComponent)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unDeviceIndex, char * pchComponentName); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformTrackedDeviceComponent)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t * punDeviceIndex, char * pchComponentName, uint32_t unComponentNameSize); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformOverlayRelative)(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t * ulOverlayHandleParent, struct HmdMatrix34_t * pmatParentOverlayToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformOverlayRelative)(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t ulOverlayHandleParent, struct HmdMatrix34_t * pmatParentOverlayToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ShowOverlay)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *HideOverlay)(VROverlayHandle_t ulOverlayHandle); - bool (OPENVR_FNTABLE_CALLTYPE *IsOverlayVisible)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetTransformForOverlayCoordinates)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, struct HmdVector2_t coordinatesInOverlay, struct HmdMatrix34_t * pmatTransform); - bool (OPENVR_FNTABLE_CALLTYPE *PollNextOverlayEvent)(VROverlayHandle_t ulOverlayHandle, struct VREvent_t * pEvent, uint32_t uncbVREvent); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayInputMethod)(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod * peInputMethod); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayInputMethod)(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod eInputMethod); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayMouseScale)(VROverlayHandle_t ulOverlayHandle, struct HmdVector2_t * pvecMouseScale); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayMouseScale)(VROverlayHandle_t ulOverlayHandle, struct HmdVector2_t * pvecMouseScale); - bool (OPENVR_FNTABLE_CALLTYPE *ComputeOverlayIntersection)(VROverlayHandle_t ulOverlayHandle, struct VROverlayIntersectionParams_t * pParams, struct VROverlayIntersectionResults_t * pResults); - bool (OPENVR_FNTABLE_CALLTYPE *HandleControllerOverlayInteractionAsMouse)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unControllerDeviceIndex); - bool (OPENVR_FNTABLE_CALLTYPE *IsHoverTargetOverlay)(VROverlayHandle_t ulOverlayHandle); - VROverlayHandle_t (OPENVR_FNTABLE_CALLTYPE *GetGamepadFocusOverlay)(); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetGamepadFocusOverlay)(VROverlayHandle_t ulNewFocusOverlay); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayNeighbor)(EOverlayDirection eDirection, VROverlayHandle_t ulFrom, VROverlayHandle_t ulTo); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *MoveGamepadFocusToNeighbor)(EOverlayDirection eDirection, VROverlayHandle_t ulFrom); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTexture)(VROverlayHandle_t ulOverlayHandle, struct Texture_t * pTexture); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ClearOverlayTexture)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayRaw)(VROverlayHandle_t ulOverlayHandle, void * pvBuffer, uint32_t unWidth, uint32_t unHeight, uint32_t unDepth); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayFromFile)(VROverlayHandle_t ulOverlayHandle, char * pchFilePath); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTexture)(VROverlayHandle_t ulOverlayHandle, void ** pNativeTextureHandle, void * pNativeTextureRef, uint32_t * pWidth, uint32_t * pHeight, uint32_t * pNativeFormat, ETextureType * pAPIType, EColorSpace * pColorSpace, struct VRTextureBounds_t * pTextureBounds); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ReleaseNativeOverlayHandle)(VROverlayHandle_t ulOverlayHandle, void * pNativeTextureHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureSize)(VROverlayHandle_t ulOverlayHandle, uint32_t * pWidth, uint32_t * pHeight); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *CreateDashboardOverlay)(char * pchOverlayKey, char * pchOverlayFriendlyName, VROverlayHandle_t * pMainHandle, VROverlayHandle_t * pThumbnailHandle); - bool (OPENVR_FNTABLE_CALLTYPE *IsDashboardVisible)(); - bool (OPENVR_FNTABLE_CALLTYPE *IsActiveDashboardOverlay)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetDashboardOverlaySceneProcess)(VROverlayHandle_t ulOverlayHandle, uint32_t unProcessId); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetDashboardOverlaySceneProcess)(VROverlayHandle_t ulOverlayHandle, uint32_t * punProcessId); - void (OPENVR_FNTABLE_CALLTYPE *ShowDashboard)(char * pchOverlayToShow); - TrackedDeviceIndex_t (OPENVR_FNTABLE_CALLTYPE *GetPrimaryDashboardDevice)(); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ShowKeyboard)(EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, char * pchDescription, uint32_t unCharMax, char * pchExistingText, bool bUseMinimalMode, uint64_t uUserValue); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ShowKeyboardForOverlay)(VROverlayHandle_t ulOverlayHandle, EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, char * pchDescription, uint32_t unCharMax, char * pchExistingText, bool bUseMinimalMode, uint64_t uUserValue); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetKeyboardText)(char * pchText, uint32_t cchText); - void (OPENVR_FNTABLE_CALLTYPE *HideKeyboard)(); - void (OPENVR_FNTABLE_CALLTYPE *SetKeyboardTransformAbsolute)(ETrackingUniverseOrigin eTrackingOrigin, struct HmdMatrix34_t * pmatTrackingOriginToKeyboardTransform); - void (OPENVR_FNTABLE_CALLTYPE *SetKeyboardPositionForOverlay)(VROverlayHandle_t ulOverlayHandle, struct HmdRect2_t avoidRect); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayIntersectionMask)(VROverlayHandle_t ulOverlayHandle, struct VROverlayIntersectionMaskPrimitive_t * pMaskPrimitives, uint32_t unNumMaskPrimitives, uint32_t unPrimitiveSize); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayFlags)(VROverlayHandle_t ulOverlayHandle, uint32_t * pFlags); - VRMessageOverlayResponse (OPENVR_FNTABLE_CALLTYPE *ShowMessageOverlay)(char * pchText, char * pchCaption, char * pchButton0Text, char * pchButton1Text, char * pchButton2Text, char * pchButton3Text); - void (OPENVR_FNTABLE_CALLTYPE *CloseMessageOverlay)(); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *FindOverlay)(char *pchOverlayKey, VROverlayHandle_t *pOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *CreateOverlay)(char *pchOverlayKey, char *pchOverlayName, VROverlayHandle_t *pOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *DestroyOverlay)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetHighQualityOverlay)(VROverlayHandle_t ulOverlayHandle); + VROverlayHandle_t(OPENVR_FNTABLE_CALLTYPE *GetHighQualityOverlay)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetOverlayKey)(VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, EVROverlayError *pError); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetOverlayName)(VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, EVROverlayError *pError); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayName)(VROverlayHandle_t ulOverlayHandle, char *pchName); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayImageData)(VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unBufferSize, uint32_t *punWidth, uint32_t *punHeight); + char *(OPENVR_FNTABLE_CALLTYPE *GetOverlayErrorNameFromEnum)(EVROverlayError error); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayRenderingPid)(VROverlayHandle_t ulOverlayHandle, uint32_t unPID); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetOverlayRenderingPid)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayFlag)(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool bEnabled); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayFlag)(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool *pbEnabled); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayColor)(VROverlayHandle_t ulOverlayHandle, float fRed, float fGreen, float fBlue); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayColor)(VROverlayHandle_t ulOverlayHandle, float *pfRed, float *pfGreen, float *pfBlue); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayAlpha)(VROverlayHandle_t ulOverlayHandle, float fAlpha); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayAlpha)(VROverlayHandle_t ulOverlayHandle, float *pfAlpha); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTexelAspect)(VROverlayHandle_t ulOverlayHandle, float fTexelAspect); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTexelAspect)(VROverlayHandle_t ulOverlayHandle, float *pfTexelAspect); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlaySortOrder)(VROverlayHandle_t ulOverlayHandle, uint32_t unSortOrder); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlaySortOrder)(VROverlayHandle_t ulOverlayHandle, uint32_t *punSortOrder); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayWidthInMeters)(VROverlayHandle_t ulOverlayHandle, float fWidthInMeters); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayWidthInMeters)(VROverlayHandle_t ulOverlayHandle, float *pfWidthInMeters); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayAutoCurveDistanceRangeInMeters)(VROverlayHandle_t ulOverlayHandle, float fMinDistanceInMeters, float fMaxDistanceInMeters); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayAutoCurveDistanceRangeInMeters)(VROverlayHandle_t ulOverlayHandle, float *pfMinDistanceInMeters, float *pfMaxDistanceInMeters); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTextureColorSpace)(VROverlayHandle_t ulOverlayHandle, EColorSpace eTextureColorSpace); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureColorSpace)(VROverlayHandle_t ulOverlayHandle, EColorSpace *peTextureColorSpace); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTextureBounds)(VROverlayHandle_t ulOverlayHandle, struct VRTextureBounds_t *pOverlayTextureBounds); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureBounds)(VROverlayHandle_t ulOverlayHandle, struct VRTextureBounds_t *pOverlayTextureBounds); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetOverlayRenderModel)(VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, struct HmdColor_t *pColor, EVROverlayError *pError); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayRenderModel)(VROverlayHandle_t ulOverlayHandle, char *pchRenderModel, struct HmdColor_t *pColor); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformType)(VROverlayHandle_t ulOverlayHandle, VROverlayTransformType *peTransformType); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformAbsolute)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, struct HmdMatrix34_t *pmatTrackingOriginToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformAbsolute)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin *peTrackingOrigin, struct HmdMatrix34_t *pmatTrackingOriginToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformTrackedDeviceRelative)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unTrackedDevice, struct HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformTrackedDeviceRelative)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punTrackedDevice, struct HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformTrackedDeviceComponent)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unDeviceIndex, char *pchComponentName); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformTrackedDeviceComponent)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punDeviceIndex, char *pchComponentName, uint32_t unComponentNameSize); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformOverlayRelative)(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t *ulOverlayHandleParent, struct HmdMatrix34_t *pmatParentOverlayToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformOverlayRelative)(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t ulOverlayHandleParent, struct HmdMatrix34_t *pmatParentOverlayToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *ShowOverlay)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *HideOverlay)(VROverlayHandle_t ulOverlayHandle); + bool(OPENVR_FNTABLE_CALLTYPE *IsOverlayVisible)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetTransformForOverlayCoordinates)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, struct HmdVector2_t coordinatesInOverlay, struct HmdMatrix34_t *pmatTransform); + bool(OPENVR_FNTABLE_CALLTYPE *PollNextOverlayEvent)(VROverlayHandle_t ulOverlayHandle, struct VREvent_t *pEvent, uint32_t uncbVREvent); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayInputMethod)(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod *peInputMethod); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayInputMethod)(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod eInputMethod); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayMouseScale)(VROverlayHandle_t ulOverlayHandle, struct HmdVector2_t *pvecMouseScale); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayMouseScale)(VROverlayHandle_t ulOverlayHandle, struct HmdVector2_t *pvecMouseScale); + bool(OPENVR_FNTABLE_CALLTYPE *ComputeOverlayIntersection)(VROverlayHandle_t ulOverlayHandle, struct VROverlayIntersectionParams_t *pParams, struct VROverlayIntersectionResults_t *pResults); + bool(OPENVR_FNTABLE_CALLTYPE *HandleControllerOverlayInteractionAsMouse)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unControllerDeviceIndex); + bool(OPENVR_FNTABLE_CALLTYPE *IsHoverTargetOverlay)(VROverlayHandle_t ulOverlayHandle); + VROverlayHandle_t(OPENVR_FNTABLE_CALLTYPE *GetGamepadFocusOverlay)(); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetGamepadFocusOverlay)(VROverlayHandle_t ulNewFocusOverlay); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayNeighbor)(EOverlayDirection eDirection, VROverlayHandle_t ulFrom, VROverlayHandle_t ulTo); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *MoveGamepadFocusToNeighbor)(EOverlayDirection eDirection, VROverlayHandle_t ulFrom); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTexture)(VROverlayHandle_t ulOverlayHandle, struct Texture_t *pTexture); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *ClearOverlayTexture)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayRaw)(VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unWidth, uint32_t unHeight, uint32_t unDepth); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayFromFile)(VROverlayHandle_t ulOverlayHandle, char *pchFilePath); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTexture)(VROverlayHandle_t ulOverlayHandle, void **pNativeTextureHandle, void *pNativeTextureRef, uint32_t *pWidth, uint32_t *pHeight, uint32_t *pNativeFormat, ETextureType *pAPIType, EColorSpace *pColorSpace, struct VRTextureBounds_t *pTextureBounds); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *ReleaseNativeOverlayHandle)(VROverlayHandle_t ulOverlayHandle, void *pNativeTextureHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureSize)(VROverlayHandle_t ulOverlayHandle, uint32_t *pWidth, uint32_t *pHeight); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *CreateDashboardOverlay)(char *pchOverlayKey, char *pchOverlayFriendlyName, VROverlayHandle_t *pMainHandle, VROverlayHandle_t *pThumbnailHandle); + bool(OPENVR_FNTABLE_CALLTYPE *IsDashboardVisible)(); + bool(OPENVR_FNTABLE_CALLTYPE *IsActiveDashboardOverlay)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetDashboardOverlaySceneProcess)(VROverlayHandle_t ulOverlayHandle, uint32_t unProcessId); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetDashboardOverlaySceneProcess)(VROverlayHandle_t ulOverlayHandle, uint32_t *punProcessId); + void(OPENVR_FNTABLE_CALLTYPE *ShowDashboard)(char *pchOverlayToShow); + TrackedDeviceIndex_t(OPENVR_FNTABLE_CALLTYPE *GetPrimaryDashboardDevice)(); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *ShowKeyboard)(EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, char *pchDescription, uint32_t unCharMax, char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *ShowKeyboardForOverlay)(VROverlayHandle_t ulOverlayHandle, EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, char *pchDescription, uint32_t unCharMax, char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetKeyboardText)(char *pchText, uint32_t cchText); + void(OPENVR_FNTABLE_CALLTYPE *HideKeyboard)(); + void(OPENVR_FNTABLE_CALLTYPE *SetKeyboardTransformAbsolute)(ETrackingUniverseOrigin eTrackingOrigin, struct HmdMatrix34_t *pmatTrackingOriginToKeyboardTransform); + void(OPENVR_FNTABLE_CALLTYPE *SetKeyboardPositionForOverlay)(VROverlayHandle_t ulOverlayHandle, struct HmdRect2_t avoidRect); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayIntersectionMask)(VROverlayHandle_t ulOverlayHandle, struct VROverlayIntersectionMaskPrimitive_t *pMaskPrimitives, uint32_t unNumMaskPrimitives, uint32_t unPrimitiveSize); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayFlags)(VROverlayHandle_t ulOverlayHandle, uint32_t *pFlags); + VRMessageOverlayResponse(OPENVR_FNTABLE_CALLTYPE *ShowMessageOverlay)(char *pchText, char *pchCaption, char *pchButton0Text, char *pchButton1Text, char *pchButton2Text, char *pchButton3Text); + void(OPENVR_FNTABLE_CALLTYPE *CloseMessageOverlay)(); }; struct VR_IVRRenderModels_FnTable { - EVRRenderModelError (OPENVR_FNTABLE_CALLTYPE *LoadRenderModel_Async)(char * pchRenderModelName, struct RenderModel_t ** ppRenderModel); - void (OPENVR_FNTABLE_CALLTYPE *FreeRenderModel)(struct RenderModel_t * pRenderModel); - EVRRenderModelError (OPENVR_FNTABLE_CALLTYPE *LoadTexture_Async)(TextureID_t textureId, struct RenderModel_TextureMap_t ** ppTexture); - void (OPENVR_FNTABLE_CALLTYPE *FreeTexture)(struct RenderModel_TextureMap_t * pTexture); - EVRRenderModelError (OPENVR_FNTABLE_CALLTYPE *LoadTextureD3D11_Async)(TextureID_t textureId, void * pD3D11Device, void ** ppD3D11Texture2D); - EVRRenderModelError (OPENVR_FNTABLE_CALLTYPE *LoadIntoTextureD3D11_Async)(TextureID_t textureId, void * pDstTexture); - void (OPENVR_FNTABLE_CALLTYPE *FreeTextureD3D11)(void * pD3D11Texture2D); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetRenderModelName)(uint32_t unRenderModelIndex, char * pchRenderModelName, uint32_t unRenderModelNameLen); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetRenderModelCount)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetComponentCount)(char * pchRenderModelName); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetComponentName)(char * pchRenderModelName, uint32_t unComponentIndex, char * pchComponentName, uint32_t unComponentNameLen); - uint64_t (OPENVR_FNTABLE_CALLTYPE *GetComponentButtonMask)(char * pchRenderModelName, char * pchComponentName); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetComponentRenderModelName)(char * pchRenderModelName, char * pchComponentName, char * pchComponentRenderModelName, uint32_t unComponentRenderModelNameLen); - bool (OPENVR_FNTABLE_CALLTYPE *GetComponentState)(char * pchRenderModelName, char * pchComponentName, VRControllerState_t * pControllerState, struct RenderModel_ControllerMode_State_t * pState, struct RenderModel_ComponentState_t * pComponentState); - bool (OPENVR_FNTABLE_CALLTYPE *RenderModelHasComponent)(char * pchRenderModelName, char * pchComponentName); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetRenderModelThumbnailURL)(char * pchRenderModelName, char * pchThumbnailURL, uint32_t unThumbnailURLLen, EVRRenderModelError * peError); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetRenderModelOriginalPath)(char * pchRenderModelName, char * pchOriginalPath, uint32_t unOriginalPathLen, EVRRenderModelError * peError); - char * (OPENVR_FNTABLE_CALLTYPE *GetRenderModelErrorNameFromEnum)(EVRRenderModelError error); + EVRRenderModelError(OPENVR_FNTABLE_CALLTYPE *LoadRenderModel_Async)(char *pchRenderModelName, struct RenderModel_t **ppRenderModel); + void(OPENVR_FNTABLE_CALLTYPE *FreeRenderModel)(struct RenderModel_t *pRenderModel); + EVRRenderModelError(OPENVR_FNTABLE_CALLTYPE *LoadTexture_Async)(TextureID_t textureId, struct RenderModel_TextureMap_t **ppTexture); + void(OPENVR_FNTABLE_CALLTYPE *FreeTexture)(struct RenderModel_TextureMap_t *pTexture); + EVRRenderModelError(OPENVR_FNTABLE_CALLTYPE *LoadTextureD3D11_Async)(TextureID_t textureId, void *pD3D11Device, void **ppD3D11Texture2D); + EVRRenderModelError(OPENVR_FNTABLE_CALLTYPE *LoadIntoTextureD3D11_Async)(TextureID_t textureId, void *pDstTexture); + void(OPENVR_FNTABLE_CALLTYPE *FreeTextureD3D11)(void *pD3D11Texture2D); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetRenderModelName)(uint32_t unRenderModelIndex, char *pchRenderModelName, uint32_t unRenderModelNameLen); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetRenderModelCount)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetComponentCount)(char *pchRenderModelName); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetComponentName)(char *pchRenderModelName, uint32_t unComponentIndex, char *pchComponentName, uint32_t unComponentNameLen); + uint64_t(OPENVR_FNTABLE_CALLTYPE *GetComponentButtonMask)(char *pchRenderModelName, char *pchComponentName); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetComponentRenderModelName)(char *pchRenderModelName, char *pchComponentName, char *pchComponentRenderModelName, uint32_t unComponentRenderModelNameLen); + bool(OPENVR_FNTABLE_CALLTYPE *GetComponentState)(char *pchRenderModelName, char *pchComponentName, VRControllerState_t *pControllerState, struct RenderModel_ControllerMode_State_t *pState, struct RenderModel_ComponentState_t *pComponentState); + bool(OPENVR_FNTABLE_CALLTYPE *RenderModelHasComponent)(char *pchRenderModelName, char *pchComponentName); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetRenderModelThumbnailURL)(char *pchRenderModelName, char *pchThumbnailURL, uint32_t unThumbnailURLLen, EVRRenderModelError *peError); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetRenderModelOriginalPath)(char *pchRenderModelName, char *pchOriginalPath, uint32_t unOriginalPathLen, EVRRenderModelError *peError); + char *(OPENVR_FNTABLE_CALLTYPE *GetRenderModelErrorNameFromEnum)(EVRRenderModelError error); }; struct VR_IVRNotifications_FnTable { - EVRNotificationError (OPENVR_FNTABLE_CALLTYPE *CreateNotification)(VROverlayHandle_t ulOverlayHandle, uint64_t ulUserValue, EVRNotificationType type, char * pchText, EVRNotificationStyle style, struct NotificationBitmap_t * pImage, VRNotificationId * pNotificationId); - EVRNotificationError (OPENVR_FNTABLE_CALLTYPE *RemoveNotification)(VRNotificationId notificationId); + EVRNotificationError(OPENVR_FNTABLE_CALLTYPE *CreateNotification)(VROverlayHandle_t ulOverlayHandle, uint64_t ulUserValue, EVRNotificationType type, char *pchText, EVRNotificationStyle style, struct NotificationBitmap_t *pImage, VRNotificationId *pNotificationId); + EVRNotificationError(OPENVR_FNTABLE_CALLTYPE *RemoveNotification)(VRNotificationId notificationId); }; struct VR_IVRSettings_FnTable { - char * (OPENVR_FNTABLE_CALLTYPE *GetSettingsErrorNameFromEnum)(EVRSettingsError eError); - bool (OPENVR_FNTABLE_CALLTYPE *Sync)(bool bForce, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *SetBool)(char * pchSection, char * pchSettingsKey, bool bValue, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *SetInt32)(char * pchSection, char * pchSettingsKey, int32_t nValue, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *SetFloat)(char * pchSection, char * pchSettingsKey, float flValue, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *SetString)(char * pchSection, char * pchSettingsKey, char * pchValue, EVRSettingsError * peError); - bool (OPENVR_FNTABLE_CALLTYPE *GetBool)(char * pchSection, char * pchSettingsKey, EVRSettingsError * peError); - int32_t (OPENVR_FNTABLE_CALLTYPE *GetInt32)(char * pchSection, char * pchSettingsKey, EVRSettingsError * peError); - float (OPENVR_FNTABLE_CALLTYPE *GetFloat)(char * pchSection, char * pchSettingsKey, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *GetString)(char * pchSection, char * pchSettingsKey, char * pchValue, uint32_t unValueLen, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *RemoveSection)(char * pchSection, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *RemoveKeyInSection)(char * pchSection, char * pchSettingsKey, EVRSettingsError * peError); + char *(OPENVR_FNTABLE_CALLTYPE *GetSettingsErrorNameFromEnum)(EVRSettingsError eError); + bool(OPENVR_FNTABLE_CALLTYPE *Sync)(bool bForce, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *SetBool)(char *pchSection, char *pchSettingsKey, bool bValue, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *SetInt32)(char *pchSection, char *pchSettingsKey, int32_t nValue, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *SetFloat)(char *pchSection, char *pchSettingsKey, float flValue, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *SetString)(char *pchSection, char *pchSettingsKey, char *pchValue, EVRSettingsError *peError); + bool(OPENVR_FNTABLE_CALLTYPE *GetBool)(char *pchSection, char *pchSettingsKey, EVRSettingsError *peError); + int32_t(OPENVR_FNTABLE_CALLTYPE *GetInt32)(char *pchSection, char *pchSettingsKey, EVRSettingsError *peError); + float(OPENVR_FNTABLE_CALLTYPE *GetFloat)(char *pchSection, char *pchSettingsKey, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *GetString)(char *pchSection, char *pchSettingsKey, char *pchValue, uint32_t unValueLen, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *RemoveSection)(char *pchSection, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *RemoveKeyInSection)(char *pchSection, char *pchSettingsKey, EVRSettingsError *peError); }; struct VR_IVRScreenshots_FnTable { - EVRScreenshotError (OPENVR_FNTABLE_CALLTYPE *RequestScreenshot)(ScreenshotHandle_t * pOutScreenshotHandle, EVRScreenshotType type, char * pchPreviewFilename, char * pchVRFilename); - EVRScreenshotError (OPENVR_FNTABLE_CALLTYPE *HookScreenshot)(EVRScreenshotType * pSupportedTypes, int numTypes); - EVRScreenshotType (OPENVR_FNTABLE_CALLTYPE *GetScreenshotPropertyType)(ScreenshotHandle_t screenshotHandle, EVRScreenshotError * pError); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetScreenshotPropertyFilename)(ScreenshotHandle_t screenshotHandle, EVRScreenshotPropertyFilenames filenameType, char * pchFilename, uint32_t cchFilename, EVRScreenshotError * pError); - EVRScreenshotError (OPENVR_FNTABLE_CALLTYPE *UpdateScreenshotProgress)(ScreenshotHandle_t screenshotHandle, float flProgress); - EVRScreenshotError (OPENVR_FNTABLE_CALLTYPE *TakeStereoScreenshot)(ScreenshotHandle_t * pOutScreenshotHandle, char * pchPreviewFilename, char * pchVRFilename); - EVRScreenshotError (OPENVR_FNTABLE_CALLTYPE *SubmitScreenshot)(ScreenshotHandle_t screenshotHandle, EVRScreenshotType type, char * pchSourcePreviewFilename, char * pchSourceVRFilename); + EVRScreenshotError(OPENVR_FNTABLE_CALLTYPE *RequestScreenshot)(ScreenshotHandle_t *pOutScreenshotHandle, EVRScreenshotType type, char *pchPreviewFilename, char *pchVRFilename); + EVRScreenshotError(OPENVR_FNTABLE_CALLTYPE *HookScreenshot)(EVRScreenshotType *pSupportedTypes, int numTypes); + EVRScreenshotType(OPENVR_FNTABLE_CALLTYPE *GetScreenshotPropertyType)(ScreenshotHandle_t screenshotHandle, EVRScreenshotError *pError); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetScreenshotPropertyFilename)(ScreenshotHandle_t screenshotHandle, EVRScreenshotPropertyFilenames filenameType, char *pchFilename, uint32_t cchFilename, EVRScreenshotError *pError); + EVRScreenshotError(OPENVR_FNTABLE_CALLTYPE *UpdateScreenshotProgress)(ScreenshotHandle_t screenshotHandle, float flProgress); + EVRScreenshotError(OPENVR_FNTABLE_CALLTYPE *TakeStereoScreenshot)(ScreenshotHandle_t *pOutScreenshotHandle, char *pchPreviewFilename, char *pchVRFilename); + EVRScreenshotError(OPENVR_FNTABLE_CALLTYPE *SubmitScreenshot)(ScreenshotHandle_t screenshotHandle, EVRScreenshotType type, char *pchSourcePreviewFilename, char *pchSourceVRFilename); }; struct VR_IVRResources_FnTable { - uint32_t (OPENVR_FNTABLE_CALLTYPE *LoadSharedResource)(char * pchResourceName, char * pchBuffer, uint32_t unBufferLen); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetResourceFullPath)(char * pchResourceName, char * pchResourceTypeDirectory, char * pchPathBuffer, uint32_t unBufferLen); + uint32_t(OPENVR_FNTABLE_CALLTYPE *LoadSharedResource)(char *pchResourceName, char *pchBuffer, uint32_t unBufferLen); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetResourceFullPath)(char *pchResourceName, char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen); }; struct VR_IVRDriverManager_FnTable { - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetDriverCount)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetDriverName)(DriverId_t nDriver, char * pchValue, uint32_t unBufferSize); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetDriverCount)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetDriverName)(DriverId_t nDriver, char *pchValue, uint32_t unBufferSize); }; - #if 0 // Global entry points S_API intptr_t VR_InitInternal( EVRInitError *peError, EVRApplicationType eType ); @@ -1937,6 +1929,4 @@ S_API const char * VR_GetVRInitErrorAsSymbol( EVRInitError error ); S_API const char * VR_GetVRInitErrorAsEnglishDescription( EVRInitError error ); #endif -#endif // __OPENVR_API_FLAT_H__ - - +#endif // __OPENVR_API_FLAT_H__ diff --git a/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/Current/Headers/openvr_driver.h b/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/Current/Headers/openvr_driver.h index 7ab997e25..b07699f82 100644 --- a/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/Current/Headers/openvr_driver.h +++ b/examples/ThirdPartyLibs/openvr/bin/osx64/OpenVR.framework/Versions/Current/Headers/openvr_driver.h @@ -9,8 +9,6 @@ #include - - // vrtypes.h #ifndef _INCLUDE_VRTYPES_H #define _INCLUDE_VRTYPES_H @@ -27,9 +25,9 @@ struct ID3D12CommandQueue; namespace vr { -#pragma pack( push, 8 ) +#pragma pack(push, 8) -typedef void* glSharedTextureHandle_t; +typedef void *glSharedTextureHandle_t; typedef int32_t glInt_t; typedef uint32_t glUInt_t; @@ -80,7 +78,7 @@ struct HmdColor_t struct HmdQuad_t { - HmdVector3_t vCorners[ 4 ]; + HmdVector3_t vCorners[4]; }; struct HmdRect2_t @@ -107,40 +105,40 @@ enum EVREye enum ETextureType { - TextureType_DirectX = 0, // Handle is an ID3D11Texture - TextureType_OpenGL = 1, // Handle is an OpenGL texture name or an OpenGL render buffer name, depending on submit flags - TextureType_Vulkan = 2, // Handle is a pointer to a VRVulkanTextureData_t structure - TextureType_IOSurface = 3, // Handle is a macOS cross-process-sharable IOSurfaceRef - TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure + TextureType_DirectX = 0, // Handle is an ID3D11Texture + TextureType_OpenGL = 1, // Handle is an OpenGL texture name or an OpenGL render buffer name, depending on submit flags + TextureType_Vulkan = 2, // Handle is a pointer to a VRVulkanTextureData_t structure + TextureType_IOSurface = 3, // Handle is a macOS cross-process-sharable IOSurfaceRef + TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure }; enum EColorSpace { - ColorSpace_Auto = 0, // Assumes 'gamma' for 8-bit per component formats, otherwise 'linear'. This mirrors the DXGI formats which have _SRGB variants. - ColorSpace_Gamma = 1, // Texture data can be displayed directly on the display without any conversion (a.k.a. display native format). - ColorSpace_Linear = 2, // Same as gamma but has been converted to a linear representation using DXGI's sRGB conversion algorithm. + ColorSpace_Auto = 0, // Assumes 'gamma' for 8-bit per component formats, otherwise 'linear'. This mirrors the DXGI formats which have _SRGB variants. + ColorSpace_Gamma = 1, // Texture data can be displayed directly on the display without any conversion (a.k.a. display native format). + ColorSpace_Linear = 2, // Same as gamma but has been converted to a linear representation using DXGI's sRGB conversion algorithm. }; struct Texture_t { - void* handle; // See ETextureType definition above + void *handle; // See ETextureType definition above ETextureType eType; EColorSpace eColorSpace; }; // Handle to a shared texture (HANDLE on Windows obtained using OpenSharedResource). typedef uint64_t SharedTextureHandle_t; -#define INVALID_SHARED_TEXTURE_HANDLE ((vr::SharedTextureHandle_t)0) +#define INVALID_SHARED_TEXTURE_HANDLE ((vr::SharedTextureHandle_t)0) enum ETrackingResult { - TrackingResult_Uninitialized = 1, + TrackingResult_Uninitialized = 1, - TrackingResult_Calibrating_InProgress = 100, - TrackingResult_Calibrating_OutOfRange = 101, + TrackingResult_Calibrating_InProgress = 100, + TrackingResult_Calibrating_OutOfRange = 101, - TrackingResult_Running_OK = 200, - TrackingResult_Running_OutOfRange = 201, + TrackingResult_Running_OK = 200, + TrackingResult_Running_OutOfRange = 201, }; typedef uint32_t DriverId_t; @@ -158,30 +156,28 @@ static const uint32_t k_unTrackedDeviceIndexInvalid = 0xFFFFFFFF; /** Describes what kind of object is being tracked at a given ID */ enum ETrackedDeviceClass { - TrackedDeviceClass_Invalid = 0, // the ID was not valid. - TrackedDeviceClass_HMD = 1, // Head-Mounted Displays - TrackedDeviceClass_Controller = 2, // Tracked controllers - TrackedDeviceClass_GenericTracker = 3, // Generic trackers, similar to controllers - TrackedDeviceClass_TrackingReference = 4, // Camera and base stations that serve as tracking reference points - TrackedDeviceClass_DisplayRedirect = 5, // Accessories that aren't necessarily tracked themselves, but may redirect video output from other tracked devices + TrackedDeviceClass_Invalid = 0, // the ID was not valid. + TrackedDeviceClass_HMD = 1, // Head-Mounted Displays + TrackedDeviceClass_Controller = 2, // Tracked controllers + TrackedDeviceClass_GenericTracker = 3, // Generic trackers, similar to controllers + TrackedDeviceClass_TrackingReference = 4, // Camera and base stations that serve as tracking reference points + TrackedDeviceClass_DisplayRedirect = 5, // Accessories that aren't necessarily tracked themselves, but may redirect video output from other tracked devices }; - /** Describes what specific role associated with a tracked device */ enum ETrackedControllerRole { - TrackedControllerRole_Invalid = 0, // Invalid value for controller type - TrackedControllerRole_LeftHand = 1, // Tracked device associated with the left hand - TrackedControllerRole_RightHand = 2, // Tracked device associated with the right hand + TrackedControllerRole_Invalid = 0, // Invalid value for controller type + TrackedControllerRole_LeftHand = 1, // Tracked device associated with the left hand + TrackedControllerRole_RightHand = 2, // Tracked device associated with the right hand }; - /** describes a single pose for a tracked object */ struct TrackedDevicePose_t { HmdMatrix34_t mDeviceToAbsoluteTracking; - HmdVector3_t vVelocity; // velocity in tracker space in m/s - HmdVector3_t vAngularVelocity; // angular velocity in radians/s (?) + HmdVector3_t vVelocity; // velocity in tracker space in m/s + HmdVector3_t vAngularVelocity; // angular velocity in radians/s (?) ETrackingResult eTrackingResult; bool bPoseIsValid; @@ -194,9 +190,9 @@ struct TrackedDevicePose_t * for the poses it is requesting */ enum ETrackingUniverseOrigin { - TrackingUniverseSeated = 0, // Poses are provided relative to the seated zero pose - TrackingUniverseStanding = 1, // Poses are provided relative to the safe bounds configured by the user - TrackingUniverseRawAndUncalibrated = 2, // Poses are provided in the coordinate system defined by the driver. It has Y up and is unified for devices of the same driver. You usually don't want this one. + TrackingUniverseSeated = 0, // Poses are provided relative to the seated zero pose + TrackingUniverseStanding = 1, // Poses are provided relative to the safe bounds configured by the user + TrackingUniverseRawAndUncalibrated = 2, // Poses are provided in the coordinate system defined by the driver. It has Y up and is unified for devices of the same driver. You usually don't want this one. }; // Refers to a single container of properties @@ -223,146 +219,145 @@ static const PropertyTypeTag_t k_unHiddenAreaPropertyTag = 30; static const PropertyTypeTag_t k_unOpenVRInternalReserved_Start = 1000; static const PropertyTypeTag_t k_unOpenVRInternalReserved_End = 10000; - /** Each entry in this enum represents a property that can be retrieved about a * tracked device. Many fields are only valid for one ETrackedDeviceClass. */ enum ETrackedDeviceProperty { - Prop_Invalid = 0, + Prop_Invalid = 0, // general properties that apply to all device classes - Prop_TrackingSystemName_String = 1000, - Prop_ModelNumber_String = 1001, - Prop_SerialNumber_String = 1002, - Prop_RenderModelName_String = 1003, - Prop_WillDriftInYaw_Bool = 1004, - Prop_ManufacturerName_String = 1005, - Prop_TrackingFirmwareVersion_String = 1006, - Prop_HardwareRevision_String = 1007, - Prop_AllWirelessDongleDescriptions_String = 1008, - Prop_ConnectedWirelessDongle_String = 1009, - Prop_DeviceIsWireless_Bool = 1010, - Prop_DeviceIsCharging_Bool = 1011, - Prop_DeviceBatteryPercentage_Float = 1012, // 0 is empty, 1 is full - Prop_StatusDisplayTransform_Matrix34 = 1013, - Prop_Firmware_UpdateAvailable_Bool = 1014, - Prop_Firmware_ManualUpdate_Bool = 1015, - Prop_Firmware_ManualUpdateURL_String = 1016, - Prop_HardwareRevision_Uint64 = 1017, - Prop_FirmwareVersion_Uint64 = 1018, - Prop_FPGAVersion_Uint64 = 1019, - Prop_VRCVersion_Uint64 = 1020, - Prop_RadioVersion_Uint64 = 1021, - Prop_DongleVersion_Uint64 = 1022, - Prop_BlockServerShutdown_Bool = 1023, - Prop_CanUnifyCoordinateSystemWithHmd_Bool = 1024, - Prop_ContainsProximitySensor_Bool = 1025, - Prop_DeviceProvidesBatteryStatus_Bool = 1026, - Prop_DeviceCanPowerOff_Bool = 1027, - Prop_Firmware_ProgrammingTarget_String = 1028, - Prop_DeviceClass_Int32 = 1029, - Prop_HasCamera_Bool = 1030, - Prop_DriverVersion_String = 1031, - Prop_Firmware_ForceUpdateRequired_Bool = 1032, - Prop_ViveSystemButtonFixRequired_Bool = 1033, - Prop_ParentDriver_Uint64 = 1034, - Prop_ResourceRoot_String = 1035, + Prop_TrackingSystemName_String = 1000, + Prop_ModelNumber_String = 1001, + Prop_SerialNumber_String = 1002, + Prop_RenderModelName_String = 1003, + Prop_WillDriftInYaw_Bool = 1004, + Prop_ManufacturerName_String = 1005, + Prop_TrackingFirmwareVersion_String = 1006, + Prop_HardwareRevision_String = 1007, + Prop_AllWirelessDongleDescriptions_String = 1008, + Prop_ConnectedWirelessDongle_String = 1009, + Prop_DeviceIsWireless_Bool = 1010, + Prop_DeviceIsCharging_Bool = 1011, + Prop_DeviceBatteryPercentage_Float = 1012, // 0 is empty, 1 is full + Prop_StatusDisplayTransform_Matrix34 = 1013, + Prop_Firmware_UpdateAvailable_Bool = 1014, + Prop_Firmware_ManualUpdate_Bool = 1015, + Prop_Firmware_ManualUpdateURL_String = 1016, + Prop_HardwareRevision_Uint64 = 1017, + Prop_FirmwareVersion_Uint64 = 1018, + Prop_FPGAVersion_Uint64 = 1019, + Prop_VRCVersion_Uint64 = 1020, + Prop_RadioVersion_Uint64 = 1021, + Prop_DongleVersion_Uint64 = 1022, + Prop_BlockServerShutdown_Bool = 1023, + Prop_CanUnifyCoordinateSystemWithHmd_Bool = 1024, + Prop_ContainsProximitySensor_Bool = 1025, + Prop_DeviceProvidesBatteryStatus_Bool = 1026, + Prop_DeviceCanPowerOff_Bool = 1027, + Prop_Firmware_ProgrammingTarget_String = 1028, + Prop_DeviceClass_Int32 = 1029, + Prop_HasCamera_Bool = 1030, + Prop_DriverVersion_String = 1031, + Prop_Firmware_ForceUpdateRequired_Bool = 1032, + Prop_ViveSystemButtonFixRequired_Bool = 1033, + Prop_ParentDriver_Uint64 = 1034, + Prop_ResourceRoot_String = 1035, // Properties that are unique to TrackedDeviceClass_HMD - Prop_ReportsTimeSinceVSync_Bool = 2000, - Prop_SecondsFromVsyncToPhotons_Float = 2001, - Prop_DisplayFrequency_Float = 2002, - Prop_UserIpdMeters_Float = 2003, - Prop_CurrentUniverseId_Uint64 = 2004, - Prop_PreviousUniverseId_Uint64 = 2005, - Prop_DisplayFirmwareVersion_Uint64 = 2006, - Prop_IsOnDesktop_Bool = 2007, - Prop_DisplayMCType_Int32 = 2008, - Prop_DisplayMCOffset_Float = 2009, - Prop_DisplayMCScale_Float = 2010, - Prop_EdidVendorID_Int32 = 2011, - Prop_DisplayMCImageLeft_String = 2012, - Prop_DisplayMCImageRight_String = 2013, - Prop_DisplayGCBlackClamp_Float = 2014, - Prop_EdidProductID_Int32 = 2015, - Prop_CameraToHeadTransform_Matrix34 = 2016, - Prop_DisplayGCType_Int32 = 2017, - Prop_DisplayGCOffset_Float = 2018, - Prop_DisplayGCScale_Float = 2019, - Prop_DisplayGCPrescale_Float = 2020, - Prop_DisplayGCImage_String = 2021, - Prop_LensCenterLeftU_Float = 2022, - Prop_LensCenterLeftV_Float = 2023, - Prop_LensCenterRightU_Float = 2024, - Prop_LensCenterRightV_Float = 2025, - Prop_UserHeadToEyeDepthMeters_Float = 2026, - Prop_CameraFirmwareVersion_Uint64 = 2027, - Prop_CameraFirmwareDescription_String = 2028, - Prop_DisplayFPGAVersion_Uint64 = 2029, - Prop_DisplayBootloaderVersion_Uint64 = 2030, - Prop_DisplayHardwareVersion_Uint64 = 2031, - Prop_AudioFirmwareVersion_Uint64 = 2032, - Prop_CameraCompatibilityMode_Int32 = 2033, + Prop_ReportsTimeSinceVSync_Bool = 2000, + Prop_SecondsFromVsyncToPhotons_Float = 2001, + Prop_DisplayFrequency_Float = 2002, + Prop_UserIpdMeters_Float = 2003, + Prop_CurrentUniverseId_Uint64 = 2004, + Prop_PreviousUniverseId_Uint64 = 2005, + Prop_DisplayFirmwareVersion_Uint64 = 2006, + Prop_IsOnDesktop_Bool = 2007, + Prop_DisplayMCType_Int32 = 2008, + Prop_DisplayMCOffset_Float = 2009, + Prop_DisplayMCScale_Float = 2010, + Prop_EdidVendorID_Int32 = 2011, + Prop_DisplayMCImageLeft_String = 2012, + Prop_DisplayMCImageRight_String = 2013, + Prop_DisplayGCBlackClamp_Float = 2014, + Prop_EdidProductID_Int32 = 2015, + Prop_CameraToHeadTransform_Matrix34 = 2016, + Prop_DisplayGCType_Int32 = 2017, + Prop_DisplayGCOffset_Float = 2018, + Prop_DisplayGCScale_Float = 2019, + Prop_DisplayGCPrescale_Float = 2020, + Prop_DisplayGCImage_String = 2021, + Prop_LensCenterLeftU_Float = 2022, + Prop_LensCenterLeftV_Float = 2023, + Prop_LensCenterRightU_Float = 2024, + Prop_LensCenterRightV_Float = 2025, + Prop_UserHeadToEyeDepthMeters_Float = 2026, + Prop_CameraFirmwareVersion_Uint64 = 2027, + Prop_CameraFirmwareDescription_String = 2028, + Prop_DisplayFPGAVersion_Uint64 = 2029, + Prop_DisplayBootloaderVersion_Uint64 = 2030, + Prop_DisplayHardwareVersion_Uint64 = 2031, + Prop_AudioFirmwareVersion_Uint64 = 2032, + Prop_CameraCompatibilityMode_Int32 = 2033, Prop_ScreenshotHorizontalFieldOfViewDegrees_Float = 2034, Prop_ScreenshotVerticalFieldOfViewDegrees_Float = 2035, - Prop_DisplaySuppressed_Bool = 2036, - Prop_DisplayAllowNightMode_Bool = 2037, - Prop_DisplayMCImageWidth_Int32 = 2038, - Prop_DisplayMCImageHeight_Int32 = 2039, - Prop_DisplayMCImageNumChannels_Int32 = 2040, - Prop_DisplayMCImageData_Binary = 2041, - Prop_SecondsFromPhotonsToVblank_Float = 2042, - Prop_DriverDirectModeSendsVsyncEvents_Bool = 2043, - Prop_DisplayDebugMode_Bool = 2044, - Prop_GraphicsAdapterLuid_Uint64 = 2045, - Prop_DriverProvidedChaperonePath_String = 2048, + Prop_DisplaySuppressed_Bool = 2036, + Prop_DisplayAllowNightMode_Bool = 2037, + Prop_DisplayMCImageWidth_Int32 = 2038, + Prop_DisplayMCImageHeight_Int32 = 2039, + Prop_DisplayMCImageNumChannels_Int32 = 2040, + Prop_DisplayMCImageData_Binary = 2041, + Prop_SecondsFromPhotonsToVblank_Float = 2042, + Prop_DriverDirectModeSendsVsyncEvents_Bool = 2043, + Prop_DisplayDebugMode_Bool = 2044, + Prop_GraphicsAdapterLuid_Uint64 = 2045, + Prop_DriverProvidedChaperonePath_String = 2048, // Properties that are unique to TrackedDeviceClass_Controller - Prop_AttachedDeviceId_String = 3000, - Prop_SupportedButtons_Uint64 = 3001, - Prop_Axis0Type_Int32 = 3002, // Return value is of type EVRControllerAxisType - Prop_Axis1Type_Int32 = 3003, // Return value is of type EVRControllerAxisType - Prop_Axis2Type_Int32 = 3004, // Return value is of type EVRControllerAxisType - Prop_Axis3Type_Int32 = 3005, // Return value is of type EVRControllerAxisType - Prop_Axis4Type_Int32 = 3006, // Return value is of type EVRControllerAxisType - Prop_ControllerRoleHint_Int32 = 3007, // Return value is of type ETrackedControllerRole + Prop_AttachedDeviceId_String = 3000, + Prop_SupportedButtons_Uint64 = 3001, + Prop_Axis0Type_Int32 = 3002, // Return value is of type EVRControllerAxisType + Prop_Axis1Type_Int32 = 3003, // Return value is of type EVRControllerAxisType + Prop_Axis2Type_Int32 = 3004, // Return value is of type EVRControllerAxisType + Prop_Axis3Type_Int32 = 3005, // Return value is of type EVRControllerAxisType + Prop_Axis4Type_Int32 = 3006, // Return value is of type EVRControllerAxisType + Prop_ControllerRoleHint_Int32 = 3007, // Return value is of type ETrackedControllerRole // Properties that are unique to TrackedDeviceClass_TrackingReference - Prop_FieldOfViewLeftDegrees_Float = 4000, - Prop_FieldOfViewRightDegrees_Float = 4001, - Prop_FieldOfViewTopDegrees_Float = 4002, - Prop_FieldOfViewBottomDegrees_Float = 4003, - Prop_TrackingRangeMinimumMeters_Float = 4004, - Prop_TrackingRangeMaximumMeters_Float = 4005, - Prop_ModeLabel_String = 4006, + Prop_FieldOfViewLeftDegrees_Float = 4000, + Prop_FieldOfViewRightDegrees_Float = 4001, + Prop_FieldOfViewTopDegrees_Float = 4002, + Prop_FieldOfViewBottomDegrees_Float = 4003, + Prop_TrackingRangeMinimumMeters_Float = 4004, + Prop_TrackingRangeMaximumMeters_Float = 4005, + Prop_ModeLabel_String = 4006, // Properties that are used for user interface like icons names - Prop_IconPathName_String = 5000, // DEPRECATED. Value not referenced. Now expected to be part of icon path properties. - Prop_NamedIconPathDeviceOff_String = 5001, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceSearching_String = 5002, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceSearchingAlert_String = 5003, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceReady_String = 5004, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceReadyAlert_String = 5005, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceNotReady_String = 5006, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceStandby_String = 5007, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceAlertLow_String = 5008, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_IconPathName_String = 5000, // DEPRECATED. Value not referenced. Now expected to be part of icon path properties. + Prop_NamedIconPathDeviceOff_String = 5001, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceSearching_String = 5002, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceSearchingAlert_String = 5003, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceReady_String = 5004, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceReadyAlert_String = 5005, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceNotReady_String = 5006, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceStandby_String = 5007, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceAlertLow_String = 5008, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others // Properties that are used by helpers, but are opaque to applications - Prop_DisplayHiddenArea_Binary_Start = 5100, - Prop_DisplayHiddenArea_Binary_End = 5150, + Prop_DisplayHiddenArea_Binary_Start = 5100, + Prop_DisplayHiddenArea_Binary_End = 5150, // Properties that are unique to drivers - Prop_UserConfigPath_String = 6000, - Prop_InstallPath_String = 6001, - Prop_HasDisplayComponent_Bool = 6002, - Prop_HasControllerComponent_Bool = 6003, - Prop_HasCameraComponent_Bool = 6004, - Prop_HasDriverDirectModeComponent_Bool = 6005, - Prop_HasVirtualDisplayComponent_Bool = 6006, + Prop_UserConfigPath_String = 6000, + Prop_InstallPath_String = 6001, + Prop_HasDisplayComponent_Bool = 6002, + Prop_HasControllerComponent_Bool = 6003, + Prop_HasCameraComponent_Bool = 6004, + Prop_HasDriverDirectModeComponent_Bool = 6005, + Prop_HasVirtualDisplayComponent_Bool = 6006, // Vendors are free to expose private debug data in this reserved region - Prop_VendorSpecific_Reserved_Start = 10000, - Prop_VendorSpecific_Reserved_End = 10999, + Prop_VendorSpecific_Reserved_Start = 10000, + Prop_VendorSpecific_Reserved_End = 10999, }; /** No string property will ever be longer than this length */ @@ -371,18 +366,18 @@ static const uint32_t k_unMaxPropertyStringSize = 32 * 1024; /** Used to return errors that occur when reading properties. */ enum ETrackedPropertyError { - TrackedProp_Success = 0, - TrackedProp_WrongDataType = 1, - TrackedProp_WrongDeviceClass = 2, - TrackedProp_BufferTooSmall = 3, - TrackedProp_UnknownProperty = 4, // Driver has not set the property (and may not ever). - TrackedProp_InvalidDevice = 5, - TrackedProp_CouldNotContactServer = 6, - TrackedProp_ValueNotProvidedByDevice = 7, - TrackedProp_StringExceedsMaximumLength = 8, - TrackedProp_NotYetAvailable = 9, // The property value isn't known yet, but is expected soon. Call again later. - TrackedProp_PermissionDenied = 10, - TrackedProp_InvalidOperation = 11, + TrackedProp_Success = 0, + TrackedProp_WrongDataType = 1, + TrackedProp_WrongDeviceClass = 2, + TrackedProp_BufferTooSmall = 3, + TrackedProp_UnknownProperty = 4, // Driver has not set the property (and may not ever). + TrackedProp_InvalidDevice = 5, + TrackedProp_CouldNotContactServer = 6, + TrackedProp_ValueNotProvidedByDevice = 7, + TrackedProp_StringExceedsMaximumLength = 8, + TrackedProp_NotYetAvailable = 9, // The property value isn't known yet, but is expected soon. Call again later. + TrackedProp_PermissionDenied = 10, + TrackedProp_InvalidOperation = 11, }; /** Allows the application to control what part of the provided texture will be used in the @@ -396,7 +391,7 @@ struct VRTextureBounds_t /** Allows specifying pose used to render provided scene texture (if different from value returned by WaitGetPoses). */ struct VRTextureWithPose_t : public Texture_t { - HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures. + HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures. }; /** Allows the application to control how scene textures are used by the compositor when calling Submit. */ @@ -424,7 +419,7 @@ enum EVRSubmitFlags * Be sure to call OpenVR_Shutdown before destroying these resources. */ struct VRVulkanTextureData_t { - uint64_t m_nImage; // VkImage + uint64_t m_nImage; // VkImage VkDevice_T *m_pDevice; VkPhysicalDevice_T *m_pPhysicalDevice; VkInstance_T *m_pInstance; @@ -461,220 +456,216 @@ enum EVREventType { VREvent_None = 0, - VREvent_TrackedDeviceActivated = 100, - VREvent_TrackedDeviceDeactivated = 101, - VREvent_TrackedDeviceUpdated = 102, - VREvent_TrackedDeviceUserInteractionStarted = 103, - VREvent_TrackedDeviceUserInteractionEnded = 104, - VREvent_IpdChanged = 105, - VREvent_EnterStandbyMode = 106, - VREvent_LeaveStandbyMode = 107, - VREvent_TrackedDeviceRoleChanged = 108, - VREvent_WatchdogWakeUpRequested = 109, - VREvent_LensDistortionChanged = 110, - VREvent_PropertyChanged = 111, - VREvent_WirelessDisconnect = 112, - VREvent_WirelessReconnect = 113, + VREvent_TrackedDeviceActivated = 100, + VREvent_TrackedDeviceDeactivated = 101, + VREvent_TrackedDeviceUpdated = 102, + VREvent_TrackedDeviceUserInteractionStarted = 103, + VREvent_TrackedDeviceUserInteractionEnded = 104, + VREvent_IpdChanged = 105, + VREvent_EnterStandbyMode = 106, + VREvent_LeaveStandbyMode = 107, + VREvent_TrackedDeviceRoleChanged = 108, + VREvent_WatchdogWakeUpRequested = 109, + VREvent_LensDistortionChanged = 110, + VREvent_PropertyChanged = 111, + VREvent_WirelessDisconnect = 112, + VREvent_WirelessReconnect = 113, - VREvent_ButtonPress = 200, // data is controller - VREvent_ButtonUnpress = 201, // data is controller - VREvent_ButtonTouch = 202, // data is controller - VREvent_ButtonUntouch = 203, // data is controller + VREvent_ButtonPress = 200, // data is controller + VREvent_ButtonUnpress = 201, // data is controller + VREvent_ButtonTouch = 202, // data is controller + VREvent_ButtonUntouch = 203, // data is controller - VREvent_MouseMove = 300, // data is mouse - VREvent_MouseButtonDown = 301, // data is mouse - VREvent_MouseButtonUp = 302, // data is mouse - VREvent_FocusEnter = 303, // data is overlay - VREvent_FocusLeave = 304, // data is overlay - VREvent_Scroll = 305, // data is mouse - VREvent_TouchPadMove = 306, // data is mouse - VREvent_OverlayFocusChanged = 307, // data is overlay, global event + VREvent_MouseMove = 300, // data is mouse + VREvent_MouseButtonDown = 301, // data is mouse + VREvent_MouseButtonUp = 302, // data is mouse + VREvent_FocusEnter = 303, // data is overlay + VREvent_FocusLeave = 304, // data is overlay + VREvent_Scroll = 305, // data is mouse + VREvent_TouchPadMove = 306, // data is mouse + VREvent_OverlayFocusChanged = 307, // data is overlay, global event - VREvent_InputFocusCaptured = 400, // data is process DEPRECATED - VREvent_InputFocusReleased = 401, // data is process DEPRECATED - VREvent_SceneFocusLost = 402, // data is process - VREvent_SceneFocusGained = 403, // data is process - VREvent_SceneApplicationChanged = 404, // data is process - The App actually drawing the scene changed (usually to or from the compositor) - VREvent_SceneFocusChanged = 405, // data is process - New app got access to draw the scene - VREvent_InputFocusChanged = 406, // data is process - VREvent_SceneApplicationSecondaryRenderingStarted = 407, // data is process + VREvent_InputFocusCaptured = 400, // data is process DEPRECATED + VREvent_InputFocusReleased = 401, // data is process DEPRECATED + VREvent_SceneFocusLost = 402, // data is process + VREvent_SceneFocusGained = 403, // data is process + VREvent_SceneApplicationChanged = 404, // data is process - The App actually drawing the scene changed (usually to or from the compositor) + VREvent_SceneFocusChanged = 405, // data is process - New app got access to draw the scene + VREvent_InputFocusChanged = 406, // data is process + VREvent_SceneApplicationSecondaryRenderingStarted = 407, // data is process - VREvent_HideRenderModels = 410, // Sent to the scene application to request hiding render models temporarily - VREvent_ShowRenderModels = 411, // Sent to the scene application to request restoring render model visibility + VREvent_HideRenderModels = 410, // Sent to the scene application to request hiding render models temporarily + VREvent_ShowRenderModels = 411, // Sent to the scene application to request restoring render model visibility - VREvent_OverlayShown = 500, - VREvent_OverlayHidden = 501, - VREvent_DashboardActivated = 502, - VREvent_DashboardDeactivated = 503, - VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay - VREvent_DashboardRequested = 505, // Sent to the overlay manager - data is overlay - VREvent_ResetDashboard = 506, // Send to the overlay manager - VREvent_RenderToast = 507, // Send to the dashboard to render a toast - data is the notification ID - VREvent_ImageLoaded = 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading - VREvent_ShowKeyboard = 509, // Sent to keyboard renderer in the dashboard to invoke it - VREvent_HideKeyboard = 510, // Sent to keyboard renderer in the dashboard to hide it - VREvent_OverlayGamepadFocusGained = 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it - VREvent_OverlayGamepadFocusLost = 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else + VREvent_OverlayShown = 500, + VREvent_OverlayHidden = 501, + VREvent_DashboardActivated = 502, + VREvent_DashboardDeactivated = 503, + VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay + VREvent_DashboardRequested = 505, // Sent to the overlay manager - data is overlay + VREvent_ResetDashboard = 506, // Send to the overlay manager + VREvent_RenderToast = 507, // Send to the dashboard to render a toast - data is the notification ID + VREvent_ImageLoaded = 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading + VREvent_ShowKeyboard = 509, // Sent to keyboard renderer in the dashboard to invoke it + VREvent_HideKeyboard = 510, // Sent to keyboard renderer in the dashboard to hide it + VREvent_OverlayGamepadFocusGained = 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it + VREvent_OverlayGamepadFocusLost = 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else VREvent_OverlaySharedTextureChanged = 513, - VREvent_DashboardGuideButtonDown = 514, - VREvent_DashboardGuideButtonUp = 515, - VREvent_ScreenshotTriggered = 516, // Screenshot button combo was pressed, Dashboard should request a screenshot - VREvent_ImageFailed = 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load - VREvent_DashboardOverlayCreated = 518, + VREvent_DashboardGuideButtonDown = 514, + VREvent_DashboardGuideButtonUp = 515, + VREvent_ScreenshotTriggered = 516, // Screenshot button combo was pressed, Dashboard should request a screenshot + VREvent_ImageFailed = 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load + VREvent_DashboardOverlayCreated = 518, // Screenshot API - VREvent_RequestScreenshot = 520, // Sent by vrclient application to compositor to take a screenshot - VREvent_ScreenshotTaken = 521, // Sent by compositor to the application that the screenshot has been taken - VREvent_ScreenshotFailed = 522, // Sent by compositor to the application that the screenshot failed to be taken - VREvent_SubmitScreenshotToDashboard = 523, // Sent by compositor to the dashboard that a completed screenshot was submitted - VREvent_ScreenshotProgressToDashboard = 524, // Sent by compositor to the dashboard that a completed screenshot was submitted + VREvent_RequestScreenshot = 520, // Sent by vrclient application to compositor to take a screenshot + VREvent_ScreenshotTaken = 521, // Sent by compositor to the application that the screenshot has been taken + VREvent_ScreenshotFailed = 522, // Sent by compositor to the application that the screenshot failed to be taken + VREvent_SubmitScreenshotToDashboard = 523, // Sent by compositor to the dashboard that a completed screenshot was submitted + VREvent_ScreenshotProgressToDashboard = 524, // Sent by compositor to the dashboard that a completed screenshot was submitted - VREvent_PrimaryDashboardDeviceChanged = 525, + VREvent_PrimaryDashboardDeviceChanged = 525, - VREvent_Notification_Shown = 600, - VREvent_Notification_Hidden = 601, - VREvent_Notification_BeginInteraction = 602, - VREvent_Notification_Destroyed = 603, + VREvent_Notification_Shown = 600, + VREvent_Notification_Hidden = 601, + VREvent_Notification_BeginInteraction = 602, + VREvent_Notification_Destroyed = 603, - VREvent_Quit = 700, // data is process - VREvent_ProcessQuit = 701, // data is process - VREvent_QuitAborted_UserPrompt = 702, // data is process - VREvent_QuitAcknowledged = 703, // data is process - VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down + VREvent_Quit = 700, // data is process + VREvent_ProcessQuit = 701, // data is process + VREvent_QuitAborted_UserPrompt = 702, // data is process + VREvent_QuitAcknowledged = 703, // data is process + VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down - VREvent_ChaperoneDataHasChanged = 800, - VREvent_ChaperoneUniverseHasChanged = 801, - VREvent_ChaperoneTempDataHasChanged = 802, - VREvent_ChaperoneSettingsHaveChanged = 803, - VREvent_SeatedZeroPoseReset = 804, + VREvent_ChaperoneDataHasChanged = 800, + VREvent_ChaperoneUniverseHasChanged = 801, + VREvent_ChaperoneTempDataHasChanged = 802, + VREvent_ChaperoneSettingsHaveChanged = 803, + VREvent_SeatedZeroPoseReset = 804, - VREvent_AudioSettingsHaveChanged = 820, + VREvent_AudioSettingsHaveChanged = 820, - VREvent_BackgroundSettingHasChanged = 850, - VREvent_CameraSettingsHaveChanged = 851, - VREvent_ReprojectionSettingHasChanged = 852, - VREvent_ModelSkinSettingsHaveChanged = 853, - VREvent_EnvironmentSettingsHaveChanged = 854, - VREvent_PowerSettingsHaveChanged = 855, + VREvent_BackgroundSettingHasChanged = 850, + VREvent_CameraSettingsHaveChanged = 851, + VREvent_ReprojectionSettingHasChanged = 852, + VREvent_ModelSkinSettingsHaveChanged = 853, + VREvent_EnvironmentSettingsHaveChanged = 854, + VREvent_PowerSettingsHaveChanged = 855, VREvent_EnableHomeAppSettingsHaveChanged = 856, - VREvent_StatusUpdate = 900, + VREvent_StatusUpdate = 900, - VREvent_MCImageUpdated = 1000, + VREvent_MCImageUpdated = 1000, - VREvent_FirmwareUpdateStarted = 1100, - VREvent_FirmwareUpdateFinished = 1101, + VREvent_FirmwareUpdateStarted = 1100, + VREvent_FirmwareUpdateFinished = 1101, - VREvent_KeyboardClosed = 1200, - VREvent_KeyboardCharInput = 1201, - VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard + VREvent_KeyboardClosed = 1200, + VREvent_KeyboardCharInput = 1201, + VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard - VREvent_ApplicationTransitionStarted = 1300, - VREvent_ApplicationTransitionAborted = 1301, - VREvent_ApplicationTransitionNewAppStarted = 1302, - VREvent_ApplicationListUpdated = 1303, - VREvent_ApplicationMimeTypeLoad = 1304, + VREvent_ApplicationTransitionStarted = 1300, + VREvent_ApplicationTransitionAborted = 1301, + VREvent_ApplicationTransitionNewAppStarted = 1302, + VREvent_ApplicationListUpdated = 1303, + VREvent_ApplicationMimeTypeLoad = 1304, VREvent_ApplicationTransitionNewAppLaunchComplete = 1305, - VREvent_ProcessConnected = 1306, - VREvent_ProcessDisconnected = 1307, + VREvent_ProcessConnected = 1306, + VREvent_ProcessDisconnected = 1307, - VREvent_Compositor_MirrorWindowShown = 1400, - VREvent_Compositor_MirrorWindowHidden = 1401, - VREvent_Compositor_ChaperoneBoundsShown = 1410, - VREvent_Compositor_ChaperoneBoundsHidden = 1411, + VREvent_Compositor_MirrorWindowShown = 1400, + VREvent_Compositor_MirrorWindowHidden = 1401, + VREvent_Compositor_ChaperoneBoundsShown = 1410, + VREvent_Compositor_ChaperoneBoundsHidden = 1411, - VREvent_TrackedCamera_StartVideoStream = 1500, - VREvent_TrackedCamera_StopVideoStream = 1501, - VREvent_TrackedCamera_PauseVideoStream = 1502, + VREvent_TrackedCamera_StartVideoStream = 1500, + VREvent_TrackedCamera_StopVideoStream = 1501, + VREvent_TrackedCamera_PauseVideoStream = 1502, VREvent_TrackedCamera_ResumeVideoStream = 1503, - VREvent_TrackedCamera_EditingSurface = 1550, + VREvent_TrackedCamera_EditingSurface = 1550, - VREvent_PerformanceTest_EnableCapture = 1600, - VREvent_PerformanceTest_DisableCapture = 1601, - VREvent_PerformanceTest_FidelityLevel = 1602, + VREvent_PerformanceTest_EnableCapture = 1600, + VREvent_PerformanceTest_DisableCapture = 1601, + VREvent_PerformanceTest_FidelityLevel = 1602, + + VREvent_MessageOverlay_Closed = 1650, + VREvent_MessageOverlayCloseRequested = 1651, - VREvent_MessageOverlay_Closed = 1650, - VREvent_MessageOverlayCloseRequested = 1651, - // Vendors are free to expose private events in this reserved region - VREvent_VendorSpecific_Reserved_Start = 10000, - VREvent_VendorSpecific_Reserved_End = 19999, + VREvent_VendorSpecific_Reserved_Start = 10000, + VREvent_VendorSpecific_Reserved_End = 19999, }; - /** Level of Hmd activity */ // UserInteraction_Timeout means the device is in the process of timing out. // InUse = ( k_EDeviceActivityLevel_UserInteraction || k_EDeviceActivityLevel_UserInteraction_Timeout ) // VREvent_TrackedDeviceUserInteractionStarted fires when the devices transitions from Standby -> UserInteraction or Idle -> UserInteraction. // VREvent_TrackedDeviceUserInteractionEnded fires when the devices transitions from UserInteraction_Timeout -> Idle enum EDeviceActivityLevel -{ - k_EDeviceActivityLevel_Unknown = -1, - k_EDeviceActivityLevel_Idle = 0, // No activity for the last 10 seconds - k_EDeviceActivityLevel_UserInteraction = 1, // Activity (movement or prox sensor) is happening now - k_EDeviceActivityLevel_UserInteraction_Timeout = 2, // No activity for the last 0.5 seconds - k_EDeviceActivityLevel_Standby = 3, // Idle for at least 5 seconds (configurable in Settings -> Power Management) +{ + k_EDeviceActivityLevel_Unknown = -1, + k_EDeviceActivityLevel_Idle = 0, // No activity for the last 10 seconds + k_EDeviceActivityLevel_UserInteraction = 1, // Activity (movement or prox sensor) is happening now + k_EDeviceActivityLevel_UserInteraction_Timeout = 2, // No activity for the last 0.5 seconds + k_EDeviceActivityLevel_Standby = 3, // Idle for at least 5 seconds (configurable in Settings -> Power Management) }; - /** VR controller button and axis IDs */ enum EVRButtonId { - k_EButton_System = 0, - k_EButton_ApplicationMenu = 1, - k_EButton_Grip = 2, - k_EButton_DPad_Left = 3, - k_EButton_DPad_Up = 4, - k_EButton_DPad_Right = 5, - k_EButton_DPad_Down = 6, - k_EButton_A = 7, - - k_EButton_ProximitySensor = 31, + k_EButton_System = 0, + k_EButton_ApplicationMenu = 1, + k_EButton_Grip = 2, + k_EButton_DPad_Left = 3, + k_EButton_DPad_Up = 4, + k_EButton_DPad_Right = 5, + k_EButton_DPad_Down = 6, + k_EButton_A = 7, - k_EButton_Axis0 = 32, - k_EButton_Axis1 = 33, - k_EButton_Axis2 = 34, - k_EButton_Axis3 = 35, - k_EButton_Axis4 = 36, + k_EButton_ProximitySensor = 31, + + k_EButton_Axis0 = 32, + k_EButton_Axis1 = 33, + k_EButton_Axis2 = 34, + k_EButton_Axis3 = 35, + k_EButton_Axis4 = 36, // aliases for well known controllers - k_EButton_SteamVR_Touchpad = k_EButton_Axis0, - k_EButton_SteamVR_Trigger = k_EButton_Axis1, + k_EButton_SteamVR_Touchpad = k_EButton_Axis0, + k_EButton_SteamVR_Trigger = k_EButton_Axis1, - k_EButton_Dashboard_Back = k_EButton_Grip, + k_EButton_Dashboard_Back = k_EButton_Grip, - k_EButton_Max = 64 + k_EButton_Max = 64 }; -inline uint64_t ButtonMaskFromId( EVRButtonId id ) { return 1ull << id; } +inline uint64_t ButtonMaskFromId(EVRButtonId id) { return 1ull << id; } /** used for controller button events */ struct VREvent_Controller_t { - uint32_t button; // EVRButtonId enum + uint32_t button; // EVRButtonId enum }; - /** used for simulated mouse events in overlay space */ enum EVRMouseButton { - VRMouseButton_Left = 0x0001, - VRMouseButton_Right = 0x0002, - VRMouseButton_Middle = 0x0004, + VRMouseButton_Left = 0x0001, + VRMouseButton_Right = 0x0002, + VRMouseButton_Middle = 0x0004, }; - /** used for simulated mouse events in overlay space */ struct VREvent_Mouse_t { - float x, y; // co-ords are in GL space, bottom left of the texture is 0,0 - uint32_t button; // EVRMouseButton enum + float x, y; // co-ords are in GL space, bottom left of the texture is 0,0 + uint32_t button; // EVRMouseButton enum }; /** used for simulated mouse wheel scroll in overlay space */ struct VREvent_Scroll_t { - float xdelta, ydelta; // movement in fraction of the pad traversed since last delta, 1.0 for a full swipe + float xdelta, ydelta; // movement in fraction of the pad traversed since last delta, 1.0 for a full swipe uint32_t repeatCount; }; @@ -713,25 +704,23 @@ struct VREvent_Process_t bool bForced; }; - /** Used for a few events about overlays */ struct VREvent_Overlay_t { uint64_t overlayHandle; }; - /** Used for a few events about overlays */ struct VREvent_Status_t { - uint32_t statusState; // EVRState enum + uint32_t statusState; // EVRState enum }; /** Used for keyboard events **/ struct VREvent_Keyboard_t { - char cNewInput[8]; // Up to 11 bytes of new input - uint64_t uUserValue; // Possible flags about the new input + char cNewInput[8]; // Up to 11 bytes of new input + uint64_t uUserValue; // Possible flags about the new input }; struct VREvent_Ipd_t @@ -787,7 +776,7 @@ struct VREvent_EditingCameraSurface_t struct VREvent_MessageOverlay_t { - uint32_t unVRMessageOverlayResponse; // vr::VRMessageOverlayResponse enum + uint32_t unVRMessageOverlayResponse; // vr::VRMessageOverlayResponse enum }; struct VREvent_Property_t @@ -797,8 +786,7 @@ struct VREvent_Property_t }; /** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py */ -typedef union -{ +typedef union { VREvent_Reserved_t reserved; VREvent_Controller_t controller; VREvent_Mouse_t mouse; @@ -821,25 +809,24 @@ typedef union VREvent_Property_t property; } VREvent_Data_t; - -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif /** An event posted by the server to all running applications */ struct VREvent_t { - uint32_t eventType; // EVREventType enum + uint32_t eventType; // EVREventType enum TrackedDeviceIndex_t trackedDeviceIndex; float eventAgeSeconds; // event data must be the end of the struct as its size is variable VREvent_Data_t data; }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif /** The mesh to draw into the stencil (or depth) buffer to perform @@ -854,7 +841,6 @@ struct HiddenAreaMesh_t uint32_t unTriangleCount; }; - enum EHiddenAreaMeshType { k_eHiddenAreaMesh_Standard = 0, @@ -864,7 +850,6 @@ enum EHiddenAreaMeshType k_eHiddenAreaMesh_Max = 3, }; - /** Identifies what kind of axis is on the controller at index n. Read this type * with pVRSystem->Get( nControllerDeviceIndex, Prop_Axis0Type_Int32 + n ); */ @@ -873,32 +858,29 @@ enum EVRControllerAxisType k_eControllerAxis_None = 0, k_eControllerAxis_TrackPad = 1, k_eControllerAxis_Joystick = 2, - k_eControllerAxis_Trigger = 3, // Analog trigger data is in the X axis + k_eControllerAxis_Trigger = 3, // Analog trigger data is in the X axis }; - /** contains information about one axis on the controller */ struct VRControllerAxis_t { - float x; // Ranges from -1.0 to 1.0 for joysticks and track pads. Ranges from 0.0 to 1.0 for triggers were 0 is fully released. - float y; // Ranges from -1.0 to 1.0 for joysticks and track pads. Is always 0.0 for triggers. + float x; // Ranges from -1.0 to 1.0 for joysticks and track pads. Ranges from 0.0 to 1.0 for triggers were 0 is fully released. + float y; // Ranges from -1.0 to 1.0 for joysticks and track pads. Is always 0.0 for triggers. }; - /** the number of axes in the controller state */ static const uint32_t k_unControllerStateAxisCount = 5; - -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif /** Holds all the state of a controller at one moment in time. */ struct VRControllerState001_t { - // If packet num matches that on your prior call, then the controller state hasn't been changed since + // If packet num matches that on your prior call, then the controller state hasn't been changed since // your last call and there is no need to process it uint32_t unPacketNum; @@ -907,16 +889,14 @@ struct VRControllerState001_t uint64_t ulButtonTouched; // Axis data for the controller's analog inputs - VRControllerAxis_t rAxis[ k_unControllerStateAxisCount ]; + VRControllerAxis_t rAxis[k_unControllerStateAxisCount]; }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif - typedef VRControllerState001_t VRControllerState_t; - /** determines how to provide output to the application of various event processing functions. */ enum EVRControllerEventOutputType { @@ -924,8 +904,6 @@ enum EVRControllerEventOutputType ControllerEventOutput_VREvents = 1, }; - - /** Collision Bounds Style */ enum ECollisionBoundsStyle { @@ -941,7 +919,7 @@ enum ECollisionBoundsStyle /** Allows the application to customize how the overlay appears in the compositor */ struct Compositor_OverlaySettings { - uint32_t size; // sizeof(Compositor_OverlaySettings) + uint32_t size; // sizeof(Compositor_OverlaySettings) bool curved, antialias; float scale, distance, alpha; float uOffset, vOffset, uScale, vScale; @@ -957,49 +935,48 @@ static const VROverlayHandle_t k_ulOverlayHandleInvalid = 0; /** Errors that can occur around VR overlays */ enum EVROverlayError { - VROverlayError_None = 0, + VROverlayError_None = 0, - VROverlayError_UnknownOverlay = 10, - VROverlayError_InvalidHandle = 11, - VROverlayError_PermissionDenied = 12, - VROverlayError_OverlayLimitExceeded = 13, // No more overlays could be created because the maximum number already exist - VROverlayError_WrongVisibilityType = 14, - VROverlayError_KeyTooLong = 15, - VROverlayError_NameTooLong = 16, - VROverlayError_KeyInUse = 17, - VROverlayError_WrongTransformType = 18, - VROverlayError_InvalidTrackedDevice = 19, - VROverlayError_InvalidParameter = 20, - VROverlayError_ThumbnailCantBeDestroyed = 21, - VROverlayError_ArrayTooSmall = 22, - VROverlayError_RequestFailed = 23, - VROverlayError_InvalidTexture = 24, - VROverlayError_UnableToLoadFile = 25, - VROverlayError_KeyboardAlreadyInUse = 26, - VROverlayError_NoNeighbor = 27, - VROverlayError_TooManyMaskPrimitives = 29, - VROverlayError_BadMaskPrimitive = 30, + VROverlayError_UnknownOverlay = 10, + VROverlayError_InvalidHandle = 11, + VROverlayError_PermissionDenied = 12, + VROverlayError_OverlayLimitExceeded = 13, // No more overlays could be created because the maximum number already exist + VROverlayError_WrongVisibilityType = 14, + VROverlayError_KeyTooLong = 15, + VROverlayError_NameTooLong = 16, + VROverlayError_KeyInUse = 17, + VROverlayError_WrongTransformType = 18, + VROverlayError_InvalidTrackedDevice = 19, + VROverlayError_InvalidParameter = 20, + VROverlayError_ThumbnailCantBeDestroyed = 21, + VROverlayError_ArrayTooSmall = 22, + VROverlayError_RequestFailed = 23, + VROverlayError_InvalidTexture = 24, + VROverlayError_UnableToLoadFile = 25, + VROverlayError_KeyboardAlreadyInUse = 26, + VROverlayError_NoNeighbor = 27, + VROverlayError_TooManyMaskPrimitives = 29, + VROverlayError_BadMaskPrimitive = 30, }; /** enum values to pass in to VR_Init to identify whether the application will * draw a 3D scene. */ enum EVRApplicationType { - VRApplication_Other = 0, // Some other kind of application that isn't covered by the other entries - VRApplication_Scene = 1, // Application will submit 3D frames - VRApplication_Overlay = 2, // Application only interacts with overlays - VRApplication_Background = 3, // Application should not start SteamVR if it's not already running, and should not - // keep it running if everything else quits. - VRApplication_Utility = 4, // Init should not try to load any drivers. The application needs access to utility - // interfaces (like IVRSettings and IVRApplications) but not hardware. - VRApplication_VRMonitor = 5, // Reserved for vrmonitor - VRApplication_SteamWatchdog = 6,// Reserved for Steam - VRApplication_Bootstrapper = 7, // Start up SteamVR + VRApplication_Other = 0, // Some other kind of application that isn't covered by the other entries + VRApplication_Scene = 1, // Application will submit 3D frames + VRApplication_Overlay = 2, // Application only interacts with overlays + VRApplication_Background = 3, // Application should not start SteamVR if it's not already running, and should not + // keep it running if everything else quits. + VRApplication_Utility = 4, // Init should not try to load any drivers. The application needs access to utility + // interfaces (like IVRSettings and IVRApplications) but not hardware. + VRApplication_VRMonitor = 5, // Reserved for vrmonitor + VRApplication_SteamWatchdog = 6, // Reserved for Steam + VRApplication_Bootstrapper = 7, // Start up SteamVR VRApplication_Max }; - /** error codes for firmware */ enum EVRFirmwareError { @@ -1008,7 +985,6 @@ enum EVRFirmwareError VRFirmwareError_Fail = 2, }; - /** error codes for notifications */ enum EVRNotificationError { @@ -1019,103 +995,101 @@ enum EVRNotificationError VRNotificationError_SystemWithUserValueAlreadyExists = 103, }; - /** error codes returned by Vr_Init */ // Please add adequate error description to https://developer.valvesoftware.com/w/index.php?title=Category:SteamVRHelp enum EVRInitError { - VRInitError_None = 0, + VRInitError_None = 0, VRInitError_Unknown = 1, - VRInitError_Init_InstallationNotFound = 100, - VRInitError_Init_InstallationCorrupt = 101, - VRInitError_Init_VRClientDLLNotFound = 102, - VRInitError_Init_FileNotFound = 103, - VRInitError_Init_FactoryNotFound = 104, - VRInitError_Init_InterfaceNotFound = 105, - VRInitError_Init_InvalidInterface = 106, - VRInitError_Init_UserConfigDirectoryInvalid = 107, - VRInitError_Init_HmdNotFound = 108, - VRInitError_Init_NotInitialized = 109, - VRInitError_Init_PathRegistryNotFound = 110, - VRInitError_Init_NoConfigPath = 111, - VRInitError_Init_NoLogPath = 112, - VRInitError_Init_PathRegistryNotWritable = 113, - VRInitError_Init_AppInfoInitFailed = 114, - VRInitError_Init_Retry = 115, // Used internally to cause retries to vrserver - VRInitError_Init_InitCanceledByUser = 116, // The calling application should silently exit. The user canceled app startup - VRInitError_Init_AnotherAppLaunching = 117, - VRInitError_Init_SettingsInitFailed = 118, - VRInitError_Init_ShuttingDown = 119, - VRInitError_Init_TooManyObjects = 120, - VRInitError_Init_NoServerForBackgroundApp = 121, - VRInitError_Init_NotSupportedWithCompositor = 122, - VRInitError_Init_NotAvailableToUtilityApps = 123, - VRInitError_Init_Internal = 124, - VRInitError_Init_HmdDriverIdIsNone = 125, - VRInitError_Init_HmdNotFoundPresenceFailed = 126, - VRInitError_Init_VRMonitorNotFound = 127, - VRInitError_Init_VRMonitorStartupFailed = 128, - VRInitError_Init_LowPowerWatchdogNotSupported = 129, - VRInitError_Init_InvalidApplicationType = 130, - VRInitError_Init_NotAvailableToWatchdogApps = 131, - VRInitError_Init_WatchdogDisabledInSettings = 132, - VRInitError_Init_VRDashboardNotFound = 133, - VRInitError_Init_VRDashboardStartupFailed = 134, - VRInitError_Init_VRHomeNotFound = 135, - VRInitError_Init_VRHomeStartupFailed = 136, - VRInitError_Init_RebootingBusy = 137, - VRInitError_Init_FirmwareUpdateBusy = 138, - VRInitError_Init_FirmwareRecoveryBusy = 139, + VRInitError_Init_InstallationNotFound = 100, + VRInitError_Init_InstallationCorrupt = 101, + VRInitError_Init_VRClientDLLNotFound = 102, + VRInitError_Init_FileNotFound = 103, + VRInitError_Init_FactoryNotFound = 104, + VRInitError_Init_InterfaceNotFound = 105, + VRInitError_Init_InvalidInterface = 106, + VRInitError_Init_UserConfigDirectoryInvalid = 107, + VRInitError_Init_HmdNotFound = 108, + VRInitError_Init_NotInitialized = 109, + VRInitError_Init_PathRegistryNotFound = 110, + VRInitError_Init_NoConfigPath = 111, + VRInitError_Init_NoLogPath = 112, + VRInitError_Init_PathRegistryNotWritable = 113, + VRInitError_Init_AppInfoInitFailed = 114, + VRInitError_Init_Retry = 115, // Used internally to cause retries to vrserver + VRInitError_Init_InitCanceledByUser = 116, // The calling application should silently exit. The user canceled app startup + VRInitError_Init_AnotherAppLaunching = 117, + VRInitError_Init_SettingsInitFailed = 118, + VRInitError_Init_ShuttingDown = 119, + VRInitError_Init_TooManyObjects = 120, + VRInitError_Init_NoServerForBackgroundApp = 121, + VRInitError_Init_NotSupportedWithCompositor = 122, + VRInitError_Init_NotAvailableToUtilityApps = 123, + VRInitError_Init_Internal = 124, + VRInitError_Init_HmdDriverIdIsNone = 125, + VRInitError_Init_HmdNotFoundPresenceFailed = 126, + VRInitError_Init_VRMonitorNotFound = 127, + VRInitError_Init_VRMonitorStartupFailed = 128, + VRInitError_Init_LowPowerWatchdogNotSupported = 129, + VRInitError_Init_InvalidApplicationType = 130, + VRInitError_Init_NotAvailableToWatchdogApps = 131, + VRInitError_Init_WatchdogDisabledInSettings = 132, + VRInitError_Init_VRDashboardNotFound = 133, + VRInitError_Init_VRDashboardStartupFailed = 134, + VRInitError_Init_VRHomeNotFound = 135, + VRInitError_Init_VRHomeStartupFailed = 136, + VRInitError_Init_RebootingBusy = 137, + VRInitError_Init_FirmwareUpdateBusy = 138, + VRInitError_Init_FirmwareRecoveryBusy = 139, - - VRInitError_Driver_Failed = 200, - VRInitError_Driver_Unknown = 201, - VRInitError_Driver_HmdUnknown = 202, - VRInitError_Driver_NotLoaded = 203, - VRInitError_Driver_RuntimeOutOfDate = 204, - VRInitError_Driver_HmdInUse = 205, - VRInitError_Driver_NotCalibrated = 206, - VRInitError_Driver_CalibrationInvalid = 207, - VRInitError_Driver_HmdDisplayNotFound = 208, + VRInitError_Driver_Failed = 200, + VRInitError_Driver_Unknown = 201, + VRInitError_Driver_HmdUnknown = 202, + VRInitError_Driver_NotLoaded = 203, + VRInitError_Driver_RuntimeOutOfDate = 204, + VRInitError_Driver_HmdInUse = 205, + VRInitError_Driver_NotCalibrated = 206, + VRInitError_Driver_CalibrationInvalid = 207, + VRInitError_Driver_HmdDisplayNotFound = 208, VRInitError_Driver_TrackedDeviceInterfaceUnknown = 209, // VRInitError_Driver_HmdDisplayNotFoundAfterFix = 210, // not needed: here for historic reasons - VRInitError_Driver_HmdDriverIdOutOfBounds = 211, - VRInitError_Driver_HmdDisplayMirrored = 212, + VRInitError_Driver_HmdDriverIdOutOfBounds = 211, + VRInitError_Driver_HmdDisplayMirrored = 212, - VRInitError_IPC_ServerInitFailed = 300, - VRInitError_IPC_ConnectFailed = 301, - VRInitError_IPC_SharedStateInitFailed = 302, - VRInitError_IPC_CompositorInitFailed = 303, - VRInitError_IPC_MutexInitFailed = 304, - VRInitError_IPC_Failed = 305, - VRInitError_IPC_CompositorConnectFailed = 306, + VRInitError_IPC_ServerInitFailed = 300, + VRInitError_IPC_ConnectFailed = 301, + VRInitError_IPC_SharedStateInitFailed = 302, + VRInitError_IPC_CompositorInitFailed = 303, + VRInitError_IPC_MutexInitFailed = 304, + VRInitError_IPC_Failed = 305, + VRInitError_IPC_CompositorConnectFailed = 306, VRInitError_IPC_CompositorInvalidConnectResponse = 307, VRInitError_IPC_ConnectFailedAfterMultipleAttempts = 308, - VRInitError_Compositor_Failed = 400, - VRInitError_Compositor_D3D11HardwareRequired = 401, - VRInitError_Compositor_FirmwareRequiresUpdate = 402, - VRInitError_Compositor_OverlayInitFailed = 403, - VRInitError_Compositor_ScreenshotsInitFailed = 404, - VRInitError_Compositor_UnableToCreateDevice = 405, + VRInitError_Compositor_Failed = 400, + VRInitError_Compositor_D3D11HardwareRequired = 401, + VRInitError_Compositor_FirmwareRequiresUpdate = 402, + VRInitError_Compositor_OverlayInitFailed = 403, + VRInitError_Compositor_ScreenshotsInitFailed = 404, + VRInitError_Compositor_UnableToCreateDevice = 405, - VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000, + VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000, - VRInitError_VendorSpecific_HmdFound_CantOpenDevice = 1101, - VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102, - VRInitError_VendorSpecific_HmdFound_NoStoredConfig = 1103, - VRInitError_VendorSpecific_HmdFound_ConfigTooBig = 1104, - VRInitError_VendorSpecific_HmdFound_ConfigTooSmall = 1105, - VRInitError_VendorSpecific_HmdFound_UnableToInitZLib = 1106, - VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion = 1107, - VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart = 1108, - VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart = 1109, - VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext = 1110, - VRInitError_VendorSpecific_HmdFound_UserDataAddressRange = 1111, - VRInitError_VendorSpecific_HmdFound_UserDataError = 1112, - VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck = 1113, + VRInitError_VendorSpecific_HmdFound_CantOpenDevice = 1101, + VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102, + VRInitError_VendorSpecific_HmdFound_NoStoredConfig = 1103, + VRInitError_VendorSpecific_HmdFound_ConfigTooBig = 1104, + VRInitError_VendorSpecific_HmdFound_ConfigTooSmall = 1105, + VRInitError_VendorSpecific_HmdFound_UnableToInitZLib = 1106, + VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion = 1107, + VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart = 1108, + VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart = 1109, + VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext = 1110, + VRInitError_VendorSpecific_HmdFound_UserDataAddressRange = 1111, + VRInitError_VendorSpecific_HmdFound_UserDataError = 1112, + VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck = 1113, VRInitError_Steam_SteamInstallationNotFound = 2000, }; @@ -1123,7 +1097,7 @@ enum EVRInitError enum EVRScreenshotType { VRScreenshotType_None = 0, - VRScreenshotType_Mono = 1, // left eye only + VRScreenshotType_Mono = 1, // left eye only VRScreenshotType_Stereo = 2, VRScreenshotType_Cubemap = 3, VRScreenshotType_MonoPanorama = 4, @@ -1138,35 +1112,35 @@ enum EVRScreenshotPropertyFilenames enum EVRTrackedCameraError { - VRTrackedCameraError_None = 0, - VRTrackedCameraError_OperationFailed = 100, - VRTrackedCameraError_InvalidHandle = 101, - VRTrackedCameraError_InvalidFrameHeaderVersion = 102, - VRTrackedCameraError_OutOfHandles = 103, - VRTrackedCameraError_IPCFailure = 104, - VRTrackedCameraError_NotSupportedForThisDevice = 105, - VRTrackedCameraError_SharedMemoryFailure = 106, - VRTrackedCameraError_FrameBufferingFailure = 107, - VRTrackedCameraError_StreamSetupFailure = 108, - VRTrackedCameraError_InvalidGLTextureId = 109, + VRTrackedCameraError_None = 0, + VRTrackedCameraError_OperationFailed = 100, + VRTrackedCameraError_InvalidHandle = 101, + VRTrackedCameraError_InvalidFrameHeaderVersion = 102, + VRTrackedCameraError_OutOfHandles = 103, + VRTrackedCameraError_IPCFailure = 104, + VRTrackedCameraError_NotSupportedForThisDevice = 105, + VRTrackedCameraError_SharedMemoryFailure = 106, + VRTrackedCameraError_FrameBufferingFailure = 107, + VRTrackedCameraError_StreamSetupFailure = 108, + VRTrackedCameraError_InvalidGLTextureId = 109, VRTrackedCameraError_InvalidSharedTextureHandle = 110, - VRTrackedCameraError_FailedToGetGLTextureId = 111, - VRTrackedCameraError_SharedTextureFailure = 112, - VRTrackedCameraError_NoFrameAvailable = 113, - VRTrackedCameraError_InvalidArgument = 114, - VRTrackedCameraError_InvalidFrameBufferSize = 115, + VRTrackedCameraError_FailedToGetGLTextureId = 111, + VRTrackedCameraError_SharedTextureFailure = 112, + VRTrackedCameraError_NoFrameAvailable = 113, + VRTrackedCameraError_InvalidArgument = 114, + VRTrackedCameraError_InvalidFrameBufferSize = 115, }; enum EVRTrackedCameraFrameType { - VRTrackedCameraFrameType_Distorted = 0, // This is the camera video frame size in pixels, still distorted. - VRTrackedCameraFrameType_Undistorted, // In pixels, an undistorted inscribed rectangle region without invalid regions. This size is subject to changes shortly. - VRTrackedCameraFrameType_MaximumUndistorted, // In pixels, maximum undistorted with invalid regions. Non zero alpha component identifies valid regions. + VRTrackedCameraFrameType_Distorted = 0, // This is the camera video frame size in pixels, still distorted. + VRTrackedCameraFrameType_Undistorted, // In pixels, an undistorted inscribed rectangle region without invalid regions. This size is subject to changes shortly. + VRTrackedCameraFrameType_MaximumUndistorted, // In pixels, maximum undistorted with invalid regions. Non zero alpha component identifies valid regions. MAX_CAMERA_FRAME_TYPES }; typedef uint64_t TrackedCameraHandle_t; -#define INVALID_TRACKED_CAMERA_HANDLE ((vr::TrackedCameraHandle_t)0) +#define INVALID_TRACKED_CAMERA_HANDLE ((vr::TrackedCameraHandle_t)0) struct CameraVideoStreamFrameHeader_t { @@ -1186,15 +1160,15 @@ typedef uint32_t ScreenshotHandle_t; static const uint32_t k_unScreenshotHandleInvalid = 0; -#pragma pack( pop ) +#pragma pack(pop) // figure out how to import from the VR API dll #if defined(_WIN32) #ifdef VR_API_EXPORT -#define VR_INTERFACE extern "C" __declspec( dllexport ) +#define VR_INTERFACE extern "C" __declspec(dllexport) #else -#define VR_INTERFACE extern "C" __declspec( dllimport ) +#define VR_INTERFACE extern "C" __declspec(dllimport) #endif #elif defined(__GNUC__) || defined(COMPILER_GCC) || defined(__APPLE__) @@ -1202,59 +1176,56 @@ static const uint32_t k_unScreenshotHandleInvalid = 0; #ifdef VR_API_EXPORT #define VR_INTERFACE extern "C" __attribute__((visibility("default"))) #else -#define VR_INTERFACE extern "C" +#define VR_INTERFACE extern "C" #endif #else #error "Unsupported Platform." #endif - -#if defined( _WIN32 ) +#if defined(_WIN32) #define VR_CALLTYPE __cdecl #else -#define VR_CALLTYPE +#define VR_CALLTYPE #endif -} // namespace vr - -#endif // _INCLUDE_VRTYPES_H +} // namespace vr +#endif // _INCLUDE_VRTYPES_H // vrannotation.h #ifdef API_GEN -# define VR_CLANG_ATTR(ATTR) __attribute__((annotate( ATTR ))) +#define VR_CLANG_ATTR(ATTR) __attribute__((annotate(ATTR))) #else -# define VR_CLANG_ATTR(ATTR) +#define VR_CLANG_ATTR(ATTR) #endif -#define VR_METHOD_DESC(DESC) VR_CLANG_ATTR( "desc:" #DESC ";" ) -#define VR_IGNOREATTR() VR_CLANG_ATTR( "ignore" ) -#define VR_OUT_STRUCT() VR_CLANG_ATTR( "out_struct: ;" ) -#define VR_OUT_STRING() VR_CLANG_ATTR( "out_string: ;" ) -#define VR_OUT_ARRAY_CALL(COUNTER,FUNCTION,PARAMS) VR_CLANG_ATTR( "out_array_call:" #COUNTER "," #FUNCTION "," #PARAMS ";" ) -#define VR_OUT_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR( "out_array_count:" #COUNTER ";" ) -#define VR_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR( "array_count:" #COUNTER ";" ) -#define VR_ARRAY_COUNT_D(COUNTER, DESC) VR_CLANG_ATTR( "array_count:" #COUNTER ";desc:" #DESC ) -#define VR_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR( "buffer_count:" #COUNTER ";" ) -#define VR_OUT_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR( "out_buffer_count:" #COUNTER ";" ) -#define VR_OUT_STRING_COUNT(COUNTER) VR_CLANG_ATTR( "out_string_count:" #COUNTER ";" ) +#define VR_METHOD_DESC(DESC) VR_CLANG_ATTR("desc:" #DESC ";") +#define VR_IGNOREATTR() VR_CLANG_ATTR("ignore") +#define VR_OUT_STRUCT() VR_CLANG_ATTR("out_struct: ;") +#define VR_OUT_STRING() VR_CLANG_ATTR("out_string: ;") +#define VR_OUT_ARRAY_CALL(COUNTER, FUNCTION, PARAMS) VR_CLANG_ATTR("out_array_call:" #COUNTER "," #FUNCTION "," #PARAMS ";") +#define VR_OUT_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR("out_array_count:" #COUNTER ";") +#define VR_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR("array_count:" #COUNTER ";") +#define VR_ARRAY_COUNT_D(COUNTER, DESC) VR_CLANG_ATTR("array_count:" #COUNTER ";desc:" #DESC) +#define VR_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR("buffer_count:" #COUNTER ";") +#define VR_OUT_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR("out_buffer_count:" #COUNTER ";") +#define VR_OUT_STRING_COUNT(COUNTER) VR_CLANG_ATTR("out_string_count:" #COUNTER ";") // vrtrackedcameratypes.h #ifndef _VRTRACKEDCAMERATYPES_H -#define _VRTRACKEDCAMERATYPES_H +#define _VRTRACKEDCAMERATYPES_H namespace vr { - -#pragma pack( push, 8 ) +#pragma pack(push, 8) enum ECameraVideoStreamFormat { CVS_FORMAT_UNKNOWN = 0, - CVS_FORMAT_RAW10 = 1, // 10 bits per pixel - CVS_FORMAT_NV12 = 2, // 12 bits per pixel - CVS_FORMAT_RGB24 = 3, // 24 bits per pixel + CVS_FORMAT_RAW10 = 1, // 10 bits per pixel + CVS_FORMAT_NV12 = 2, // 12 bits per pixel + CVS_FORMAT_RGB24 = 3, // 24 bits per pixel CVS_MAX_FORMATS }; @@ -1277,30 +1248,31 @@ enum ECameraCompatibilityMode }; #ifdef _MSC_VER -#define VR_CAMERA_DECL_ALIGN( x ) __declspec( align( x ) ) +#define VR_CAMERA_DECL_ALIGN(x) __declspec(align(x)) #else -#define VR_CAMERA_DECL_ALIGN( x ) // +#define VR_CAMERA_DECL_ALIGN(x) // #endif -#define MAX_CAMERA_FRAME_SHARED_HANDLES 4 +#define MAX_CAMERA_FRAME_SHARED_HANDLES 4 -VR_CAMERA_DECL_ALIGN( 8 ) struct CameraVideoStreamFrame_t +VR_CAMERA_DECL_ALIGN(8) +struct CameraVideoStreamFrame_t { ECameraVideoStreamFormat m_nStreamFormat; uint32_t m_nWidth; uint32_t m_nHeight; - uint32_t m_nImageDataSize; // Based on stream format, width, height + uint32_t m_nImageDataSize; // Based on stream format, width, height - uint32_t m_nFrameSequence; // Starts from 0 when stream starts. + uint32_t m_nFrameSequence; // Starts from 0 when stream starts. - uint32_t m_nBufferIndex; // Identifies which buffer the image data is hosted - uint32_t m_nBufferCount; // Total number of configured buffers + uint32_t m_nBufferIndex; // Identifies which buffer the image data is hosted + uint32_t m_nBufferCount; // Total number of configured buffers uint32_t m_nExposureTime; - uint32_t m_nISPFrameTimeStamp; // Driver provided time stamp per driver centric time base + uint32_t m_nISPFrameTimeStamp; // Driver provided time stamp per driver centric time base uint32_t m_nISPReferenceTimeStamp; uint32_t m_nSyncCounter; @@ -1309,241 +1281,239 @@ VR_CAMERA_DECL_ALIGN( 8 ) struct CameraVideoStreamFrame_t double m_flReferenceCamSyncTime; - double m_flFrameElapsedTime; // Starts from 0 when stream starts. In seconds. + double m_flFrameElapsedTime; // Starts from 0 when stream starts. In seconds. double m_flFrameDeliveryRate; - double m_flFrameCaptureTime_DriverAbsolute; // In USB time, via AuxEvent - double m_flFrameCaptureTime_ServerRelative; // In System time within the server - uint64_t m_nFrameCaptureTicks_ServerAbsolute; // In system ticks within the server - double m_flFrameCaptureTime_ClientRelative; // At the client, relative to when the frame was exposed/captured. + double m_flFrameCaptureTime_DriverAbsolute; // In USB time, via AuxEvent + double m_flFrameCaptureTime_ServerRelative; // In System time within the server + uint64_t m_nFrameCaptureTicks_ServerAbsolute; // In system ticks within the server + double m_flFrameCaptureTime_ClientRelative; // At the client, relative to when the frame was exposed/captured. double m_flSyncMarkerError; - TrackedDevicePose_t m_StandingTrackedDevicePose; // Supplied by HMD layer when used as a tracked camera + TrackedDevicePose_t m_StandingTrackedDevicePose; // Supplied by HMD layer when used as a tracked camera uint64_t m_pImageData; }; -#pragma pack( pop ) +#pragma pack(pop) -} +} // namespace vr -#endif // _VRTRACKEDCAMERATYPES_H +#endif // _VRTRACKEDCAMERATYPES_H // ivrsettings.h namespace vr { - enum EVRSettingsError - { - VRSettingsError_None = 0, - VRSettingsError_IPCFailed = 1, - VRSettingsError_WriteFailed = 2, - VRSettingsError_ReadFailed = 3, - VRSettingsError_JsonParseFailed = 4, - VRSettingsError_UnsetSettingHasNoDefault = 5, // This will be returned if the setting does not appear in the appropriate default file and has not been set - }; +enum EVRSettingsError +{ + VRSettingsError_None = 0, + VRSettingsError_IPCFailed = 1, + VRSettingsError_WriteFailed = 2, + VRSettingsError_ReadFailed = 3, + VRSettingsError_JsonParseFailed = 4, + VRSettingsError_UnsetSettingHasNoDefault = 5, // This will be returned if the setting does not appear in the appropriate default file and has not been set +}; - // The maximum length of a settings key - static const uint32_t k_unMaxSettingsKeyLength = 128; +// The maximum length of a settings key +static const uint32_t k_unMaxSettingsKeyLength = 128; - class IVRSettings - { - public: - virtual const char *GetSettingsErrorNameFromEnum( EVRSettingsError eError ) = 0; +class IVRSettings +{ +public: + virtual const char *GetSettingsErrorNameFromEnum(EVRSettingsError eError) = 0; - // Returns true if file sync occurred (force or settings dirty) - virtual bool Sync( bool bForce = false, EVRSettingsError *peError = nullptr ) = 0; + // Returns true if file sync occurred (force or settings dirty) + virtual bool Sync(bool bForce = false, EVRSettingsError *peError = nullptr) = 0; - virtual void SetBool( const char *pchSection, const char *pchSettingsKey, bool bValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetInt32( const char *pchSection, const char *pchSettingsKey, int32_t nValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetFloat( const char *pchSection, const char *pchSettingsKey, float flValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetString( const char *pchSection, const char *pchSettingsKey, const char *pchValue, EVRSettingsError *peError = nullptr ) = 0; + virtual void SetBool(const char *pchSection, const char *pchSettingsKey, bool bValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetInt32(const char *pchSection, const char *pchSettingsKey, int32_t nValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetFloat(const char *pchSection, const char *pchSettingsKey, float flValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetString(const char *pchSection, const char *pchSettingsKey, const char *pchValue, EVRSettingsError *peError = nullptr) = 0; - // Users of the system need to provide a proper default in default.vrsettings in the resources/settings/ directory - // of either the runtime or the driver_xxx directory. Otherwise the default will be false, 0, 0.0 or "" - virtual bool GetBool( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual int32_t GetInt32( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual float GetFloat( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual void GetString( const char *pchSection, const char *pchSettingsKey, VR_OUT_STRING() char *pchValue, uint32_t unValueLen, EVRSettingsError *peError = nullptr ) = 0; + // Users of the system need to provide a proper default in default.vrsettings in the resources/settings/ directory + // of either the runtime or the driver_xxx directory. Otherwise the default will be false, 0, 0.0 or "" + virtual bool GetBool(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual int32_t GetInt32(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual float GetFloat(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual void GetString(const char *pchSection, const char *pchSettingsKey, VR_OUT_STRING() char *pchValue, uint32_t unValueLen, EVRSettingsError *peError = nullptr) = 0; - virtual void RemoveSection( const char *pchSection, EVRSettingsError *peError = nullptr ) = 0; - virtual void RemoveKeyInSection( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - }; + virtual void RemoveSection(const char *pchSection, EVRSettingsError *peError = nullptr) = 0; + virtual void RemoveKeyInSection(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; +}; - //----------------------------------------------------------------------------- - static const char * const IVRSettings_Version = "IVRSettings_002"; +//----------------------------------------------------------------------------- +static const char *const IVRSettings_Version = "IVRSettings_002"; - //----------------------------------------------------------------------------- - // steamvr keys - static const char * const k_pch_SteamVR_Section = "steamvr"; - static const char * const k_pch_SteamVR_RequireHmd_String = "requireHmd"; - static const char * const k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; - static const char * const k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; - static const char * const k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; - static const char * const k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; - static const char * const k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; - static const char * const k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; - static const char * const k_pch_SteamVR_SendSystemButtonToAllApps_Bool= "sendSystemButtonToAllApps"; - static const char * const k_pch_SteamVR_LogLevel_Int32 = "loglevel"; - static const char * const k_pch_SteamVR_IPD_Float = "ipd"; - static const char * const k_pch_SteamVR_Background_String = "background"; - static const char * const k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; - static const char * const k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; - static const char * const k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; - static const char * const k_pch_SteamVR_GridColor_String = "gridColor"; - static const char * const k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; - static const char * const k_pch_SteamVR_ShowStage_Bool = "showStage"; - static const char * const k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; - static const char * const k_pch_SteamVR_DirectMode_Bool = "directMode"; - static const char * const k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; - static const char * const k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; - static const char * const k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; - static const char * const k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; - static const char * const k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; - static const char * const k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; - static const char * const k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; - static const char * const k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; - static const char * const k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; - static const char * const k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; - static const char * const k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; - static const char * const k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; - static const char * const k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; - static const char * const k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; - static const char * const k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; - static const char * const k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; - static const char * const k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; - static const char * const k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; - static const char * const k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; - static const char * const k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; - static const char * const k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; - static const char * const k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; - static const char * const k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; - static const char * const k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; +//----------------------------------------------------------------------------- +// steamvr keys +static const char *const k_pch_SteamVR_Section = "steamvr"; +static const char *const k_pch_SteamVR_RequireHmd_String = "requireHmd"; +static const char *const k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; +static const char *const k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; +static const char *const k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; +static const char *const k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; +static const char *const k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; +static const char *const k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; +static const char *const k_pch_SteamVR_SendSystemButtonToAllApps_Bool = "sendSystemButtonToAllApps"; +static const char *const k_pch_SteamVR_LogLevel_Int32 = "loglevel"; +static const char *const k_pch_SteamVR_IPD_Float = "ipd"; +static const char *const k_pch_SteamVR_Background_String = "background"; +static const char *const k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; +static const char *const k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; +static const char *const k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; +static const char *const k_pch_SteamVR_GridColor_String = "gridColor"; +static const char *const k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; +static const char *const k_pch_SteamVR_ShowStage_Bool = "showStage"; +static const char *const k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; +static const char *const k_pch_SteamVR_DirectMode_Bool = "directMode"; +static const char *const k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; +static const char *const k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; +static const char *const k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; +static const char *const k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; +static const char *const k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; +static const char *const k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; +static const char *const k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; +static const char *const k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; +static const char *const k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; +static const char *const k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; +static const char *const k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; +static const char *const k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; +static const char *const k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; +static const char *const k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; +static const char *const k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; +static const char *const k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; +static const char *const k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; +static const char *const k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; +static const char *const k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; +static const char *const k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; +static const char *const k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; +static const char *const k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; +static const char *const k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; +static const char *const k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; - //----------------------------------------------------------------------------- - // lighthouse keys - static const char * const k_pch_Lighthouse_Section = "driver_lighthouse"; - static const char * const k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; - static const char * const k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; - static const char * const k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; - static const char * const k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; - static const char * const k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; +//----------------------------------------------------------------------------- +// lighthouse keys +static const char *const k_pch_Lighthouse_Section = "driver_lighthouse"; +static const char *const k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; +static const char *const k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; +static const char *const k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; +static const char *const k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; +static const char *const k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; - //----------------------------------------------------------------------------- - // null keys - static const char * const k_pch_Null_Section = "driver_null"; - static const char * const k_pch_Null_SerialNumber_String = "serialNumber"; - static const char * const k_pch_Null_ModelNumber_String = "modelNumber"; - static const char * const k_pch_Null_WindowX_Int32 = "windowX"; - static const char * const k_pch_Null_WindowY_Int32 = "windowY"; - static const char * const k_pch_Null_WindowWidth_Int32 = "windowWidth"; - static const char * const k_pch_Null_WindowHeight_Int32 = "windowHeight"; - static const char * const k_pch_Null_RenderWidth_Int32 = "renderWidth"; - static const char * const k_pch_Null_RenderHeight_Int32 = "renderHeight"; - static const char * const k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; - static const char * const k_pch_Null_DisplayFrequency_Float = "displayFrequency"; +//----------------------------------------------------------------------------- +// null keys +static const char *const k_pch_Null_Section = "driver_null"; +static const char *const k_pch_Null_SerialNumber_String = "serialNumber"; +static const char *const k_pch_Null_ModelNumber_String = "modelNumber"; +static const char *const k_pch_Null_WindowX_Int32 = "windowX"; +static const char *const k_pch_Null_WindowY_Int32 = "windowY"; +static const char *const k_pch_Null_WindowWidth_Int32 = "windowWidth"; +static const char *const k_pch_Null_WindowHeight_Int32 = "windowHeight"; +static const char *const k_pch_Null_RenderWidth_Int32 = "renderWidth"; +static const char *const k_pch_Null_RenderHeight_Int32 = "renderHeight"; +static const char *const k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; +static const char *const k_pch_Null_DisplayFrequency_Float = "displayFrequency"; - //----------------------------------------------------------------------------- - // user interface keys - static const char * const k_pch_UserInterface_Section = "userinterface"; - static const char * const k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; - static const char * const k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; - static const char * const k_pch_UserInterface_Screenshots_Bool = "screenshots"; - static const char * const k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; +//----------------------------------------------------------------------------- +// user interface keys +static const char *const k_pch_UserInterface_Section = "userinterface"; +static const char *const k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; +static const char *const k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; +static const char *const k_pch_UserInterface_Screenshots_Bool = "screenshots"; +static const char *const k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; - //----------------------------------------------------------------------------- - // notification keys - static const char * const k_pch_Notifications_Section = "notifications"; - static const char * const k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; +//----------------------------------------------------------------------------- +// notification keys +static const char *const k_pch_Notifications_Section = "notifications"; +static const char *const k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; - //----------------------------------------------------------------------------- - // keyboard keys - static const char * const k_pch_Keyboard_Section = "keyboard"; - static const char * const k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; - static const char * const k_pch_Keyboard_ScaleX = "ScaleX"; - static const char * const k_pch_Keyboard_ScaleY = "ScaleY"; - static const char * const k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; - static const char * const k_pch_Keyboard_OffsetRightX = "OffsetRightX"; - static const char * const k_pch_Keyboard_OffsetY = "OffsetY"; - static const char * const k_pch_Keyboard_Smoothing = "Smoothing"; +//----------------------------------------------------------------------------- +// keyboard keys +static const char *const k_pch_Keyboard_Section = "keyboard"; +static const char *const k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; +static const char *const k_pch_Keyboard_ScaleX = "ScaleX"; +static const char *const k_pch_Keyboard_ScaleY = "ScaleY"; +static const char *const k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; +static const char *const k_pch_Keyboard_OffsetRightX = "OffsetRightX"; +static const char *const k_pch_Keyboard_OffsetY = "OffsetY"; +static const char *const k_pch_Keyboard_Smoothing = "Smoothing"; - //----------------------------------------------------------------------------- - // perf keys - static const char * const k_pch_Perf_Section = "perfcheck"; - static const char * const k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; - static const char * const k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; - static const char * const k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; - static const char * const k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; - static const char * const k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; - static const char * const k_pch_Perf_TestData_Float = "perfTestData"; - static const char * const k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; +//----------------------------------------------------------------------------- +// perf keys +static const char *const k_pch_Perf_Section = "perfcheck"; +static const char *const k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; +static const char *const k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; +static const char *const k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; +static const char *const k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; +static const char *const k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; +static const char *const k_pch_Perf_TestData_Float = "perfTestData"; +static const char *const k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; - //----------------------------------------------------------------------------- - // collision bounds keys - static const char * const k_pch_CollisionBounds_Section = "collisionBounds"; - static const char * const k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; - static const char * const k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; - static const char * const k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; - static const char * const k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; - static const char * const k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; - static const char * const k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; - static const char * const k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; - static const char * const k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; - static const char * const k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; +//----------------------------------------------------------------------------- +// collision bounds keys +static const char *const k_pch_CollisionBounds_Section = "collisionBounds"; +static const char *const k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; +static const char *const k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; +static const char *const k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; +static const char *const k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; +static const char *const k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; +static const char *const k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; +static const char *const k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; +static const char *const k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; +static const char *const k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; - //----------------------------------------------------------------------------- - // camera keys - static const char * const k_pch_Camera_Section = "camera"; - static const char * const k_pch_Camera_EnableCamera_Bool = "enableCamera"; - static const char * const k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; - static const char * const k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; - static const char * const k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; - static const char * const k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; - static const char * const k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; - static const char * const k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; - static const char * const k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; - static const char * const k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; +//----------------------------------------------------------------------------- +// camera keys +static const char *const k_pch_Camera_Section = "camera"; +static const char *const k_pch_Camera_EnableCamera_Bool = "enableCamera"; +static const char *const k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; +static const char *const k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; +static const char *const k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; +static const char *const k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; +static const char *const k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; +static const char *const k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; +static const char *const k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; +static const char *const k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; - //----------------------------------------------------------------------------- - // audio keys - static const char * const k_pch_audio_Section = "audio"; - static const char * const k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; - static const char * const k_pch_audio_OnRecordDevice_String = "onRecordDevice"; - static const char * const k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; - static const char * const k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; - static const char * const k_pch_audio_OffRecordDevice_String = "offRecordDevice"; - static const char * const k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; +//----------------------------------------------------------------------------- +// audio keys +static const char *const k_pch_audio_Section = "audio"; +static const char *const k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; +static const char *const k_pch_audio_OnRecordDevice_String = "onRecordDevice"; +static const char *const k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; +static const char *const k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; +static const char *const k_pch_audio_OffRecordDevice_String = "offRecordDevice"; +static const char *const k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; - //----------------------------------------------------------------------------- - // power management keys - static const char * const k_pch_Power_Section = "power"; - static const char * const k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; - static const char * const k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; - static const char * const k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; - static const char * const k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; - static const char * const k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; - static const char * const k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; +//----------------------------------------------------------------------------- +// power management keys +static const char *const k_pch_Power_Section = "power"; +static const char *const k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; +static const char *const k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; +static const char *const k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; +static const char *const k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; +static const char *const k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; +static const char *const k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; - //----------------------------------------------------------------------------- - // dashboard keys - static const char * const k_pch_Dashboard_Section = "dashboard"; - static const char * const k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; - static const char * const k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; +//----------------------------------------------------------------------------- +// dashboard keys +static const char *const k_pch_Dashboard_Section = "dashboard"; +static const char *const k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; +static const char *const k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; - //----------------------------------------------------------------------------- - // model skin keys - static const char * const k_pch_modelskin_Section = "modelskins"; +//----------------------------------------------------------------------------- +// model skin keys +static const char *const k_pch_modelskin_Section = "modelskins"; - //----------------------------------------------------------------------------- - // driver keys - These could be checked in any driver_ section - static const char * const k_pch_Driver_Enable_Bool = "enable"; +//----------------------------------------------------------------------------- +// driver keys - These could be checked in any driver_ section +static const char *const k_pch_Driver_Enable_Bool = "enable"; -} // namespace vr +} // namespace vr // iservertrackeddevicedriver.h namespace vr { - - struct DriverPoseQuaternion_t { double w, x, y, z; @@ -1573,10 +1543,10 @@ struct DriverPose_t * lagged due to the filtering required to reduce noise to an acceptable level. */ vr::HmdQuaternion_t qWorldFromDriverRotation; - double vecWorldFromDriverTranslation[ 3 ]; + double vecWorldFromDriverTranslation[3]; vr::HmdQuaternion_t qDriverFromHeadRotation; - double vecDriverFromHeadTranslation[ 3 ]; + double vecDriverFromHeadTranslation[3]; /* State of driver pose, in meters and radians. */ /* Position of the driver tracking reference in driver world space @@ -1584,13 +1554,13 @@ struct DriverPose_t * +[1] (y) is up * -[2] (z) is forward */ - double vecPosition[ 3 ]; + double vecPosition[3]; /* Velocity of the pose in meters/second */ - double vecVelocity[ 3 ]; + double vecVelocity[3]; /* Acceleration of the pose in meters/second */ - double vecAcceleration[ 3 ]; + double vecAcceleration[3]; /* Orientation of the tracker, represented as a quaternion */ vr::HmdQuaternion_t qRotation; @@ -1599,13 +1569,13 @@ struct DriverPose_t * representation. The direction is the angle of * rotation and the magnitude is the angle around * that axis in radians/second. */ - double vecAngularVelocity[ 3 ]; + double vecAngularVelocity[3]; /* Angular acceleration of the pose in axis-angle * representation. The direction is the angle of * rotation and the magnitude is the angle around * that axis in radians/second^2. */ - double vecAngularAcceleration[ 3 ]; + double vecAngularAcceleration[3]; ETrackingResult result; @@ -1615,14 +1585,12 @@ struct DriverPose_t bool deviceIsConnected; }; - // ---------------------------------------------------------------------------------------------- // Purpose: Represents a single tracked device in a driver // ---------------------------------------------------------------------------------------------- class ITrackedDeviceServerDriver { public: - // ------------------------------------ // Management Methods // ------------------------------------ @@ -1631,7 +1599,7 @@ public: * ITrackedDeviceServerDriver object should be kept to a minimum until it is activated. * The pose listener is guaranteed to be valid until Deactivate is called, but * should not be used after that point. */ - virtual EVRInitError Activate( uint32_t unObjectId ) = 0; + virtual EVRInitError Activate(uint32_t unObjectId) = 0; /** This is called when The VR system is switching from this Hmd being the active display * to another Hmd being the active display. The driver should clean whatever memory @@ -1643,12 +1611,12 @@ public: /** Requests a component interface of the driver for device-specific functionality. The driver should return NULL * if the requested interface or version is not supported. */ - virtual void *GetComponent( const char *pchComponentNameAndVersion ) = 0; + virtual void *GetComponent(const char *pchComponentNameAndVersion) = 0; /** A VR Client has made this debug request of the driver. The set of valid requests is entirely * up to the driver and the client to figure out, as is the format of the response. Responses that * exceed the length of the supplied buffer should be truncated and null terminated */ - virtual void DebugRequest( const char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize ) = 0; + virtual void DebugRequest(const char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize) = 0; // ------------------------------------ // Tracking Methods @@ -1656,177 +1624,160 @@ public: virtual DriverPose_t GetPose() = 0; }; - - static const char *ITrackedDeviceServerDriver_Version = "ITrackedDeviceServerDriver_005"; -} +} // namespace vr // ivrdisplaycomponent.h namespace vr { +// ---------------------------------------------------------------------------------------------- +// Purpose: The display component on a single tracked device +// ---------------------------------------------------------------------------------------------- +class IVRDisplayComponent +{ +public: + // ------------------------------------ + // Display Methods + // ------------------------------------ + /** Size and position that the window needs to be on the VR display. */ + virtual void GetWindowBounds(int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight) = 0; - // ---------------------------------------------------------------------------------------------- - // Purpose: The display component on a single tracked device - // ---------------------------------------------------------------------------------------------- - class IVRDisplayComponent - { - public: + /** Returns true if the display is extending the desktop. */ + virtual bool IsDisplayOnDesktop() = 0; - // ------------------------------------ - // Display Methods - // ------------------------------------ + /** Returns true if the display is real and not a fictional display. */ + virtual bool IsDisplayRealDisplay() = 0; - /** Size and position that the window needs to be on the VR display. */ - virtual void GetWindowBounds( int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; + /** Suggested size for the intermediate render target that the distortion pulls from. */ + virtual void GetRecommendedRenderTargetSize(uint32_t *pnWidth, uint32_t *pnHeight) = 0; - /** Returns true if the display is extending the desktop. */ - virtual bool IsDisplayOnDesktop( ) = 0; + /** Gets the viewport in the frame buffer to draw the output of the distortion into */ + virtual void GetEyeOutputViewport(EVREye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight) = 0; - /** Returns true if the display is real and not a fictional display. */ - virtual bool IsDisplayRealDisplay( ) = 0; - - /** Suggested size for the intermediate render target that the distortion pulls from. */ - virtual void GetRecommendedRenderTargetSize( uint32_t *pnWidth, uint32_t *pnHeight ) = 0; - - /** Gets the viewport in the frame buffer to draw the output of the distortion into */ - virtual void GetEyeOutputViewport( EVREye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; - - /** The components necessary to build your own projection matrix in case your + /** The components necessary to build your own projection matrix in case your * application is doing something fancy like infinite Z */ - virtual void GetProjectionRaw( EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom ) = 0; + virtual void GetProjectionRaw(EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom) = 0; - /** Returns the result of the distortion function for the specified eye and input UVs. UVs go from 0,0 in + /** Returns the result of the distortion function for the specified eye and input UVs. UVs go from 0,0 in * the upper left of that eye's viewport and 1,1 in the lower right of that eye's viewport. */ - virtual DistortionCoordinates_t ComputeDistortion( EVREye eEye, float fU, float fV ) = 0; + virtual DistortionCoordinates_t ComputeDistortion(EVREye eEye, float fU, float fV) = 0; +}; - }; +static const char *IVRDisplayComponent_Version = "IVRDisplayComponent_002"; - static const char *IVRDisplayComponent_Version = "IVRDisplayComponent_002"; - -} +} // namespace vr // ivrdriverdirectmodecomponent.h namespace vr { +// ---------------------------------------------------------------------------------------------- +// Purpose: This component is used for drivers that implement direct mode entirely on their own +// without allowing the VR Compositor to own the window/device. Chances are you don't +// need to implement this component in your driver. +// ---------------------------------------------------------------------------------------------- +class IVRDriverDirectModeComponent +{ +public: + // ----------------------------------- + // Direct mode methods + // ----------------------------------- + /** Specific to Oculus compositor support, textures supplied must be created using this method. */ + virtual void CreateSwapTextureSet(uint32_t unPid, uint32_t unFormat, uint32_t unWidth, uint32_t unHeight, vr::SharedTextureHandle_t (*pSharedTextureHandles)[3]) {} - // ---------------------------------------------------------------------------------------------- - // Purpose: This component is used for drivers that implement direct mode entirely on their own - // without allowing the VR Compositor to own the window/device. Chances are you don't - // need to implement this component in your driver. - // ---------------------------------------------------------------------------------------------- - class IVRDriverDirectModeComponent - { - public: + /** Used to textures created using CreateSwapTextureSet. Only one of the set's handles needs to be used to destroy the entire set. */ + virtual void DestroySwapTextureSet(vr::SharedTextureHandle_t sharedTextureHandle) {} - // ----------------------------------- - // Direct mode methods - // ----------------------------------- + /** Used to purge all texture sets for a given process. */ + virtual void DestroyAllSwapTextureSets(uint32_t unPid) {} - /** Specific to Oculus compositor support, textures supplied must be created using this method. */ - virtual void CreateSwapTextureSet( uint32_t unPid, uint32_t unFormat, uint32_t unWidth, uint32_t unHeight, vr::SharedTextureHandle_t( *pSharedTextureHandles )[ 3 ] ) {} + /** After Present returns, calls this to get the next index to use for rendering. */ + virtual void GetNextSwapTextureSetIndex(vr::SharedTextureHandle_t sharedTextureHandles[2], uint32_t (*pIndices)[2]) {} - /** Used to textures created using CreateSwapTextureSet. Only one of the set's handles needs to be used to destroy the entire set. */ - virtual void DestroySwapTextureSet( vr::SharedTextureHandle_t sharedTextureHandle ) {} - - /** Used to purge all texture sets for a given process. */ - virtual void DestroyAllSwapTextureSets( uint32_t unPid ) {} - - /** After Present returns, calls this to get the next index to use for rendering. */ - virtual void GetNextSwapTextureSetIndex( vr::SharedTextureHandle_t sharedTextureHandles[ 2 ], uint32_t( *pIndices )[ 2 ] ) {} - - /** Call once per layer to draw for this frame. One shared texture handle per eye. Textures must be created + /** Call once per layer to draw for this frame. One shared texture handle per eye. Textures must be created * using CreateSwapTextureSet and should be alternated per frame. Call Present once all layers have been submitted. */ - virtual void SubmitLayer( vr::SharedTextureHandle_t sharedTextureHandles[ 2 ], const vr::VRTextureBounds_t( &bounds )[ 2 ], const vr::HmdMatrix34_t *pPose ) {} + virtual void SubmitLayer(vr::SharedTextureHandle_t sharedTextureHandles[2], const vr::VRTextureBounds_t (&bounds)[2], const vr::HmdMatrix34_t *pPose) {} - /** Submits queued layers for display. */ - virtual void Present( vr::SharedTextureHandle_t syncTexture ) {} + /** Submits queued layers for display. */ + virtual void Present(vr::SharedTextureHandle_t syncTexture) {} +}; - }; +static const char *IVRDriverDirectModeComponent_Version = "IVRDriverDirectModeComponent_002"; - static const char *IVRDriverDirectModeComponent_Version = "IVRDriverDirectModeComponent_002"; - -} +} // namespace vr // ivrcontrollercomponent.h namespace vr { +// ---------------------------------------------------------------------------------------------- +// Purpose: Controller access on a single tracked device. +// ---------------------------------------------------------------------------------------------- +class IVRControllerComponent +{ +public: + // ------------------------------------ + // Controller Methods + // ------------------------------------ + /** Gets the current state of a controller. */ + virtual VRControllerState_t GetControllerState() = 0; - // ---------------------------------------------------------------------------------------------- - // Purpose: Controller access on a single tracked device. - // ---------------------------------------------------------------------------------------------- - class IVRControllerComponent - { - public: + /** Returns a uint64 property. If the property is not available this function will return 0. */ + virtual bool TriggerHapticPulse(uint32_t unAxisId, uint16_t usPulseDurationMicroseconds) = 0; +}; - // ------------------------------------ - // Controller Methods - // ------------------------------------ +static const char *IVRControllerComponent_Version = "IVRControllerComponent_001"; - /** Gets the current state of a controller. */ - virtual VRControllerState_t GetControllerState( ) = 0; - - /** Returns a uint64 property. If the property is not available this function will return 0. */ - virtual bool TriggerHapticPulse( uint32_t unAxisId, uint16_t usPulseDurationMicroseconds ) = 0; - - }; - - - - static const char *IVRControllerComponent_Version = "IVRControllerComponent_001"; - -} +} // namespace vr // ivrcameracomponent.h namespace vr { - //----------------------------------------------------------------------------- - //----------------------------------------------------------------------------- - class ICameraVideoSinkCallback - { - public: - virtual void OnCameraVideoSinkCallback() = 0; - }; +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +class ICameraVideoSinkCallback +{ +public: + virtual void OnCameraVideoSinkCallback() = 0; +}; - // ---------------------------------------------------------------------------------------------- - // Purpose: The camera on a single tracked device - // ---------------------------------------------------------------------------------------------- - class IVRCameraComponent - { - public: - // ------------------------------------ - // Camera Methods - // ------------------------------------ - virtual bool GetCameraFrameDimensions( vr::ECameraVideoStreamFormat nVideoStreamFormat, uint32_t *pWidth, uint32_t *pHeight ) = 0; - virtual bool GetCameraFrameBufferingRequirements( int *pDefaultFrameQueueSize, uint32_t *pFrameBufferDataSize ) = 0; - virtual bool SetCameraFrameBuffering( int nFrameBufferCount, void **ppFrameBuffers, uint32_t nFrameBufferDataSize ) = 0; - virtual bool SetCameraVideoStreamFormat( vr::ECameraVideoStreamFormat nVideoStreamFormat ) = 0; - virtual vr::ECameraVideoStreamFormat GetCameraVideoStreamFormat() = 0; - virtual bool StartVideoStream() = 0; - virtual void StopVideoStream() = 0; - virtual bool IsVideoStreamActive( bool *pbPaused, float *pflElapsedTime ) = 0; - virtual const vr::CameraVideoStreamFrame_t *GetVideoStreamFrame() = 0; - virtual void ReleaseVideoStreamFrame( const vr::CameraVideoStreamFrame_t *pFrameImage ) = 0; - virtual bool SetAutoExposure( bool bEnable ) = 0; - virtual bool PauseVideoStream() = 0; - virtual bool ResumeVideoStream() = 0; - virtual bool GetCameraDistortion( float flInputU, float flInputV, float *pflOutputU, float *pflOutputV ) = 0; - virtual bool GetCameraProjection( vr::EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, vr::HmdMatrix44_t *pProjection ) = 0; - virtual bool SetFrameRate( int nISPFrameRate, int nSensorFrameRate ) = 0; - virtual bool SetCameraVideoSinkCallback( vr::ICameraVideoSinkCallback *pCameraVideoSinkCallback ) = 0; - virtual bool GetCameraCompatibilityMode( vr::ECameraCompatibilityMode *pCameraCompatibilityMode ) = 0; - virtual bool SetCameraCompatibilityMode( vr::ECameraCompatibilityMode nCameraCompatibilityMode ) = 0; - virtual bool GetCameraFrameBounds( vr::EVRTrackedCameraFrameType eFrameType, uint32_t *pLeft, uint32_t *pTop, uint32_t *pWidth, uint32_t *pHeight ) = 0; - virtual bool GetCameraIntrinsics( vr::EVRTrackedCameraFrameType eFrameType, HmdVector2_t *pFocalLength, HmdVector2_t *pCenter ) = 0; - }; +// ---------------------------------------------------------------------------------------------- +// Purpose: The camera on a single tracked device +// ---------------------------------------------------------------------------------------------- +class IVRCameraComponent +{ +public: + // ------------------------------------ + // Camera Methods + // ------------------------------------ + virtual bool GetCameraFrameDimensions(vr::ECameraVideoStreamFormat nVideoStreamFormat, uint32_t *pWidth, uint32_t *pHeight) = 0; + virtual bool GetCameraFrameBufferingRequirements(int *pDefaultFrameQueueSize, uint32_t *pFrameBufferDataSize) = 0; + virtual bool SetCameraFrameBuffering(int nFrameBufferCount, void **ppFrameBuffers, uint32_t nFrameBufferDataSize) = 0; + virtual bool SetCameraVideoStreamFormat(vr::ECameraVideoStreamFormat nVideoStreamFormat) = 0; + virtual vr::ECameraVideoStreamFormat GetCameraVideoStreamFormat() = 0; + virtual bool StartVideoStream() = 0; + virtual void StopVideoStream() = 0; + virtual bool IsVideoStreamActive(bool *pbPaused, float *pflElapsedTime) = 0; + virtual const vr::CameraVideoStreamFrame_t *GetVideoStreamFrame() = 0; + virtual void ReleaseVideoStreamFrame(const vr::CameraVideoStreamFrame_t *pFrameImage) = 0; + virtual bool SetAutoExposure(bool bEnable) = 0; + virtual bool PauseVideoStream() = 0; + virtual bool ResumeVideoStream() = 0; + virtual bool GetCameraDistortion(float flInputU, float flInputV, float *pflOutputU, float *pflOutputV) = 0; + virtual bool GetCameraProjection(vr::EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, vr::HmdMatrix44_t *pProjection) = 0; + virtual bool SetFrameRate(int nISPFrameRate, int nSensorFrameRate) = 0; + virtual bool SetCameraVideoSinkCallback(vr::ICameraVideoSinkCallback *pCameraVideoSinkCallback) = 0; + virtual bool GetCameraCompatibilityMode(vr::ECameraCompatibilityMode *pCameraCompatibilityMode) = 0; + virtual bool SetCameraCompatibilityMode(vr::ECameraCompatibilityMode nCameraCompatibilityMode) = 0; + virtual bool GetCameraFrameBounds(vr::EVRTrackedCameraFrameType eFrameType, uint32_t *pLeft, uint32_t *pTop, uint32_t *pWidth, uint32_t *pHeight) = 0; + virtual bool GetCameraIntrinsics(vr::EVRTrackedCameraFrameType eFrameType, HmdVector2_t *pFocalLength, HmdVector2_t *pCenter) = 0; +}; - static const char *IVRCameraComponent_Version = "IVRCameraComponent_002"; -} +static const char *IVRCameraComponent_Version = "IVRCameraComponent_002"; +} // namespace vr // itrackeddevicedriverprovider.h namespace vr { - class ITrackedDeviceServerDriver; struct TrackedDeviceDriverInfo_t; struct DriverPose_t; @@ -1841,13 +1792,12 @@ class IVRDriverContext public: /** Returns the requested interface. If the interface was not available it will return NULL and fill * out the error. */ - virtual void *GetGenericInterface( const char *pchInterfaceVersion, EVRInitError *peError = nullptr ) = 0; + virtual void *GetGenericInterface(const char *pchInterfaceVersion, EVRInitError *peError = nullptr) = 0; /** Returns the property container handle for this driver */ virtual DriverHandle_t GetDriverHandle() = 0; }; - /** This interface must be implemented in each driver. It will be loaded in vrserver.exe */ class IServerTrackedDeviceProvider { @@ -1861,18 +1811,17 @@ public: * config files. * pchDriverInstallDir - The absolute path of the root directory for the driver. */ - virtual EVRInitError Init( IVRDriverContext *pDriverContext ) = 0; + virtual EVRInitError Init(IVRDriverContext *pDriverContext) = 0; /** cleans up the driver right before it is unloaded */ virtual void Cleanup() = 0; /** Returns the version of the ITrackedDeviceServerDriver interface used by this driver */ - virtual const char * const *GetInterfaceVersions() = 0; + virtual const char *const *GetInterfaceVersions() = 0; /** Allows the driver do to some work in the main loop of the server. */ virtual void RunFrame() = 0; - // ------------ Power State Functions ----------------------- // /** Returns true if the driver wants to block Standby mode. */ @@ -1885,21 +1834,16 @@ public: /** Called when the system is leaving Standby mode. The driver should switch itself back to full operation. */ virtual void LeaveStandby() = 0; - }; - static const char *IServerTrackedDeviceProvider_Version = "IServerTrackedDeviceProvider_004"; - - - /** This interface must be implemented in each driver. It will be loaded in vrclient.dll */ class IVRWatchdogProvider { public: /** initializes the driver in watchdog mode. */ - virtual EVRInitError Init( IVRDriverContext *pDriverContext ) = 0; + virtual EVRInitError Init(IVRDriverContext *pDriverContext) = 0; /** cleans up the driver right before it is unloaded */ virtual void Cleanup() = 0; @@ -1907,134 +1851,128 @@ public: static const char *IVRWatchdogProvider_Version = "IVRWatchdogProvider_001"; -} +} // namespace vr // ivrproperties.h #include namespace vr { +enum EPropertyWriteType +{ + PropertyWrite_Set = 0, + PropertyWrite_Erase = 1, + PropertyWrite_SetError = 2 +}; - enum EPropertyWriteType - { - PropertyWrite_Set = 0, - PropertyWrite_Erase = 1, - PropertyWrite_SetError = 2 - }; - - struct PropertyWrite_t - { - ETrackedDeviceProperty prop; - EPropertyWriteType writeType; - ETrackedPropertyError eSetError; - void *pvBuffer; - uint32_t unBufferSize; - PropertyTypeTag_t unTag; - ETrackedPropertyError eError; - }; - - struct PropertyRead_t - { - ETrackedDeviceProperty prop; - void *pvBuffer; - uint32_t unBufferSize; - PropertyTypeTag_t unTag; - uint32_t unRequiredBufferSize; - ETrackedPropertyError eError; - }; +struct PropertyWrite_t +{ + ETrackedDeviceProperty prop; + EPropertyWriteType writeType; + ETrackedPropertyError eSetError; + void *pvBuffer; + uint32_t unBufferSize; + PropertyTypeTag_t unTag; + ETrackedPropertyError eError; +}; +struct PropertyRead_t +{ + ETrackedDeviceProperty prop; + void *pvBuffer; + uint32_t unBufferSize; + PropertyTypeTag_t unTag; + uint32_t unRequiredBufferSize; + ETrackedPropertyError eError; +}; class IVRProperties { public: - /** Reads a set of properties atomically. See the PropertyReadBatch_t struct for more information. */ - virtual ETrackedPropertyError ReadPropertyBatch( PropertyContainerHandle_t ulContainerHandle, PropertyRead_t *pBatch, uint32_t unBatchEntryCount ) = 0; + virtual ETrackedPropertyError ReadPropertyBatch(PropertyContainerHandle_t ulContainerHandle, PropertyRead_t *pBatch, uint32_t unBatchEntryCount) = 0; /** Writes a set of properties atomically. See the PropertyWriteBatch_t struct for more information. */ - virtual ETrackedPropertyError WritePropertyBatch( PropertyContainerHandle_t ulContainerHandle, PropertyWrite_t *pBatch, uint32_t unBatchEntryCount ) = 0; + virtual ETrackedPropertyError WritePropertyBatch(PropertyContainerHandle_t ulContainerHandle, PropertyWrite_t *pBatch, uint32_t unBatchEntryCount) = 0; /** returns a string that corresponds with the specified property error. The string will be the name * of the error enum value for all valid error codes */ - virtual const char *GetPropErrorNameFromEnum( ETrackedPropertyError error ) = 0; + virtual const char *GetPropErrorNameFromEnum(ETrackedPropertyError error) = 0; /** Returns a container handle given a tracked device index */ - virtual PropertyContainerHandle_t TrackedDeviceToPropertyContainer( TrackedDeviceIndex_t nDevice ) = 0; - + virtual PropertyContainerHandle_t TrackedDeviceToPropertyContainer(TrackedDeviceIndex_t nDevice) = 0; }; -static const char * const IVRProperties_Version = "IVRProperties_001"; +static const char *const IVRProperties_Version = "IVRProperties_001"; class CVRPropertyHelpers { public: - CVRPropertyHelpers( IVRProperties * pProperties ) : m_pProperties( pProperties ) {} + CVRPropertyHelpers(IVRProperties *pProperties) : m_pProperties(pProperties) {} /** Returns a scaler property. If the device index is not valid or the property value type does not match, * this function will return false. */ - bool GetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ); - float GetFloatProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ); - int32_t GetInt32Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ); - uint64_t GetUint64Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ); + bool GetBoolProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L); + float GetFloatProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L); + int32_t GetInt32Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L); + uint64_t GetUint64Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L); /** Returns a single typed property. If the device index is not valid or the property is not a string type this function will * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */ - uint32_t GetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() void *pvBuffer, uint32_t unBufferSize, PropertyTypeTag_t *punTag, ETrackedPropertyError *pError = 0L ); - + uint32_t GetProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() void *pvBuffer, uint32_t unBufferSize, PropertyTypeTag_t *punTag, ETrackedPropertyError *pError = 0L); /** Returns a string property. If the device index is not valid or the property is not a string type this function will * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */ - uint32_t GetStringProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L ); + uint32_t GetStringProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L); /** Returns a string property as a std::string. If the device index is not valid or the property is not a string type this function will * return an empty string. */ - std::string GetStringProperty( vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError = nullptr ); + std::string GetStringProperty(vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError = nullptr); /** Sets a scaler property. The new value will be returned on any subsequent call to get this property in any process. */ - ETrackedPropertyError SetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, bool bNewValue ); - ETrackedPropertyError SetFloatProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, float fNewValue ); - ETrackedPropertyError SetInt32Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, int32_t nNewValue ); - ETrackedPropertyError SetUint64Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, uint64_t ulNewValue ); + ETrackedPropertyError SetBoolProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, bool bNewValue); + ETrackedPropertyError SetFloatProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, float fNewValue); + ETrackedPropertyError SetInt32Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, int32_t nNewValue); + ETrackedPropertyError SetUint64Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, uint64_t ulNewValue); /** Sets a string property. The new value will be returned on any subsequent call to get this property in any process. */ - ETrackedPropertyError SetStringProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, const char *pchNewValue ); + ETrackedPropertyError SetStringProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, const char *pchNewValue); /** Sets a single typed property. The new value will be returned on any subsequent call to get this property in any process. */ - ETrackedPropertyError SetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, void *pvNewValue, uint32_t unNewValueSize, PropertyTypeTag_t unTag ); + ETrackedPropertyError SetProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, void *pvNewValue, uint32_t unNewValueSize, PropertyTypeTag_t unTag); /** Sets the error return value for a property. This value will be returned on all subsequent requests to get the property */ - ETrackedPropertyError SetPropertyError( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError eError ); + ETrackedPropertyError SetPropertyError(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError eError); /** Clears any value or error set for the property. */ - ETrackedPropertyError EraseProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop ); + ETrackedPropertyError EraseProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop); /* Turns a device index into a property container handle. */ - PropertyContainerHandle_t TrackedDeviceToPropertyContainer( TrackedDeviceIndex_t nDevice ) { return m_pProperties->TrackedDeviceToPropertyContainer( nDevice ); } + PropertyContainerHandle_t TrackedDeviceToPropertyContainer(TrackedDeviceIndex_t nDevice) { return m_pProperties->TrackedDeviceToPropertyContainer(nDevice); } private: - template - T GetPropertyHelper( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError, T bDefault, PropertyTypeTag_t unTypeTag ); + template + T GetPropertyHelper(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError, T bDefault, PropertyTypeTag_t unTypeTag); IVRProperties *m_pProperties; }; - -inline uint32_t CVRPropertyHelpers::GetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() void *pvBuffer, uint32_t unBufferSize, PropertyTypeTag_t *punTag, ETrackedPropertyError *pError ) +inline uint32_t CVRPropertyHelpers::GetProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() void *pvBuffer, uint32_t unBufferSize, PropertyTypeTag_t *punTag, ETrackedPropertyError *pError) { PropertyRead_t batch; batch.prop = prop; batch.pvBuffer = pvBuffer; batch.unBufferSize = unBufferSize; - m_pProperties->ReadPropertyBatch( ulContainerHandle, &batch, 1 ); + m_pProperties->ReadPropertyBatch(ulContainerHandle, &batch, 1); - if ( pError ) + if (pError) { *pError = batch.eError; } - if ( punTag ) + if (punTag) { *punTag = batch.unTag; } @@ -2042,9 +1980,8 @@ inline uint32_t CVRPropertyHelpers::GetProperty( PropertyContainerHandle_t ulCon return batch.unRequiredBufferSize; } - /** Sets a single typed property. The new value will be returned on any subsequent call to get this property in any process. */ -inline ETrackedPropertyError CVRPropertyHelpers::SetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, void *pvNewValue, uint32_t unNewValueSize, PropertyTypeTag_t unTag ) +inline ETrackedPropertyError CVRPropertyHelpers::SetProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, void *pvNewValue, uint32_t unNewValueSize, PropertyTypeTag_t unTag) { PropertyWrite_t batch; batch.writeType = PropertyWrite_Set; @@ -2053,33 +1990,32 @@ inline ETrackedPropertyError CVRPropertyHelpers::SetProperty( PropertyContainerH batch.unBufferSize = unNewValueSize; batch.unTag = unTag; - m_pProperties->WritePropertyBatch( ulContainerHandle, &batch, 1 ); + m_pProperties->WritePropertyBatch(ulContainerHandle, &batch, 1); return batch.eError; } - /** Returns a string property. If the device index is not valid or the property is not a string type this function will * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */ -inline uint32_t CVRPropertyHelpers::GetStringProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError ) +inline uint32_t CVRPropertyHelpers::GetStringProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError) { PropertyTypeTag_t unTag; ETrackedPropertyError error; - uint32_t unRequiredSize = GetProperty( ulContainerHandle, prop, pchValue, unBufferSize, &unTag, &error ); - if ( unTag != k_unStringPropertyTag && error == TrackedProp_Success ) + uint32_t unRequiredSize = GetProperty(ulContainerHandle, prop, pchValue, unBufferSize, &unTag, &error); + if (unTag != k_unStringPropertyTag && error == TrackedProp_Success) { error = TrackedProp_WrongDataType; } - if ( pError ) + if (pError) { *pError = error; } - if ( error != TrackedProp_Success ) + if (error != TrackedProp_Success) { - if ( pchValue && unBufferSize ) + if (pchValue && unBufferSize) { *pchValue = '\0'; } @@ -2088,30 +2024,29 @@ inline uint32_t CVRPropertyHelpers::GetStringProperty( PropertyContainerHandle_t return unRequiredSize; } - /** Returns a string property as a std::string. If the device index is not valid or the property is not a string type this function will * return an empty string. */ -inline std::string CVRPropertyHelpers::GetStringProperty( vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError ) +inline std::string CVRPropertyHelpers::GetStringProperty(vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError) { char buf[1024]; vr::ETrackedPropertyError err; - uint32_t unRequiredBufferLen = GetStringProperty( ulContainer, prop, buf, sizeof(buf), &err ); + uint32_t unRequiredBufferLen = GetStringProperty(ulContainer, prop, buf, sizeof(buf), &err); std::string sResult; - if ( err == TrackedProp_Success ) + if (err == TrackedProp_Success) { sResult = buf; } - else if ( err == TrackedProp_BufferTooSmall ) + else if (err == TrackedProp_BufferTooSmall) { char *pchBuffer = new char[unRequiredBufferLen]; - unRequiredBufferLen = GetStringProperty( ulContainer, prop, pchBuffer, unRequiredBufferLen, &err ); + unRequiredBufferLen = GetStringProperty(ulContainer, prop, pchBuffer, unRequiredBufferLen, &err); sResult = pchBuffer; delete[] pchBuffer; } - if ( peError ) + if (peError) { *peError = err; } @@ -2119,39 +2054,37 @@ inline std::string CVRPropertyHelpers::GetStringProperty( vr::PropertyContainerH return sResult; } - /** Sets a string property. The new value will be returned on any subsequent call to get this property in any process. */ -inline ETrackedPropertyError CVRPropertyHelpers::SetStringProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, const char *pchNewValue ) +inline ETrackedPropertyError CVRPropertyHelpers::SetStringProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, const char *pchNewValue) { - if ( !pchNewValue ) + if (!pchNewValue) return TrackedProp_InvalidOperation; // this is strlen without the dependency on string.h const char *pchCurr = pchNewValue; - while ( *pchCurr ) + while (*pchCurr) { pchCurr++; } - return SetProperty( ulContainerHandle, prop, (void *)pchNewValue, (uint32_t)(pchCurr - pchNewValue) + 1, k_unStringPropertyTag ); + return SetProperty(ulContainerHandle, prop, (void *)pchNewValue, (uint32_t)(pchCurr - pchNewValue) + 1, k_unStringPropertyTag); } - -template -inline T CVRPropertyHelpers::GetPropertyHelper( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError, T bDefault, PropertyTypeTag_t unTypeTag ) +template +inline T CVRPropertyHelpers::GetPropertyHelper(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError, T bDefault, PropertyTypeTag_t unTypeTag) { T bValue; ETrackedPropertyError eError; PropertyTypeTag_t unReadTag; - GetProperty( ulContainerHandle, prop, &bValue, sizeof( bValue ), &unReadTag, &eError ); - if ( unReadTag != unTypeTag && eError == TrackedProp_Success ) + GetProperty(ulContainerHandle, prop, &bValue, sizeof(bValue), &unReadTag, &eError); + if (unReadTag != unTypeTag && eError == TrackedProp_Success) { eError = TrackedProp_WrongDataType; }; - if ( pError ) + if (pError) *pError = eError; - if ( eError != TrackedProp_Success ) + if (eError != TrackedProp_Success) { return bDefault; } @@ -2161,96 +2094,89 @@ inline T CVRPropertyHelpers::GetPropertyHelper( PropertyContainerHandle_t ulCont } } - -inline bool CVRPropertyHelpers::GetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) +inline bool CVRPropertyHelpers::GetBoolProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError) { - return GetPropertyHelper( ulContainerHandle, prop, pError, false, k_unBoolPropertyTag ); + return GetPropertyHelper(ulContainerHandle, prop, pError, false, k_unBoolPropertyTag); } - -inline float CVRPropertyHelpers::GetFloatProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) +inline float CVRPropertyHelpers::GetFloatProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError) { - return GetPropertyHelper( ulContainerHandle, prop, pError, 0.f, k_unFloatPropertyTag ); + return GetPropertyHelper(ulContainerHandle, prop, pError, 0.f, k_unFloatPropertyTag); } -inline int32_t CVRPropertyHelpers::GetInt32Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) +inline int32_t CVRPropertyHelpers::GetInt32Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError) { - return GetPropertyHelper( ulContainerHandle, prop, pError, 0, k_unInt32PropertyTag ); + return GetPropertyHelper(ulContainerHandle, prop, pError, 0, k_unInt32PropertyTag); } -inline uint64_t CVRPropertyHelpers::GetUint64Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) +inline uint64_t CVRPropertyHelpers::GetUint64Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError) { - return GetPropertyHelper( ulContainerHandle, prop, pError, 0, k_unUint64PropertyTag ); + return GetPropertyHelper(ulContainerHandle, prop, pError, 0, k_unUint64PropertyTag); } -inline ETrackedPropertyError CVRPropertyHelpers::SetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, bool bNewValue ) +inline ETrackedPropertyError CVRPropertyHelpers::SetBoolProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, bool bNewValue) { - return SetProperty( ulContainerHandle, prop, &bNewValue, sizeof( bNewValue ), k_unBoolPropertyTag ); + return SetProperty(ulContainerHandle, prop, &bNewValue, sizeof(bNewValue), k_unBoolPropertyTag); } -inline ETrackedPropertyError CVRPropertyHelpers::SetFloatProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, float fNewValue ) +inline ETrackedPropertyError CVRPropertyHelpers::SetFloatProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, float fNewValue) { - return SetProperty( ulContainerHandle, prop, &fNewValue, sizeof( fNewValue ), k_unFloatPropertyTag ); + return SetProperty(ulContainerHandle, prop, &fNewValue, sizeof(fNewValue), k_unFloatPropertyTag); } -inline ETrackedPropertyError CVRPropertyHelpers::SetInt32Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, int32_t nNewValue ) +inline ETrackedPropertyError CVRPropertyHelpers::SetInt32Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, int32_t nNewValue) { - return SetProperty( ulContainerHandle, prop, &nNewValue, sizeof( nNewValue ), k_unInt32PropertyTag ); + return SetProperty(ulContainerHandle, prop, &nNewValue, sizeof(nNewValue), k_unInt32PropertyTag); } -inline ETrackedPropertyError CVRPropertyHelpers::SetUint64Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, uint64_t ulNewValue ) +inline ETrackedPropertyError CVRPropertyHelpers::SetUint64Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, uint64_t ulNewValue) { - return SetProperty( ulContainerHandle, prop, &ulNewValue, sizeof( ulNewValue ), k_unUint64PropertyTag ); + return SetProperty(ulContainerHandle, prop, &ulNewValue, sizeof(ulNewValue), k_unUint64PropertyTag); } /** Sets the error return value for a property. This value will be returned on all subsequent requests to get the property */ -inline ETrackedPropertyError CVRPropertyHelpers::SetPropertyError( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError eError ) +inline ETrackedPropertyError CVRPropertyHelpers::SetPropertyError(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError eError) { PropertyWrite_t batch; batch.writeType = PropertyWrite_SetError; batch.prop = prop; batch.eSetError = eError; - m_pProperties->WritePropertyBatch( ulContainerHandle, &batch, 1 ); + m_pProperties->WritePropertyBatch(ulContainerHandle, &batch, 1); return batch.eError; } /** Clears any value or error set for the property. */ -inline ETrackedPropertyError CVRPropertyHelpers::EraseProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop ) +inline ETrackedPropertyError CVRPropertyHelpers::EraseProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop) { PropertyWrite_t batch; batch.writeType = PropertyWrite_Erase; batch.prop = prop; - m_pProperties->WritePropertyBatch( ulContainerHandle, &batch, 1 ); + m_pProperties->WritePropertyBatch(ulContainerHandle, &batch, 1); return batch.eError; - -} - } +} // namespace vr // ivrdriverlog.h namespace vr { - class IVRDriverLog { public: /** Writes a log message to the log file prefixed with the driver name */ - virtual void Log( const char *pchLogMessage ) = 0; + virtual void Log(const char *pchLogMessage) = 0; }; - static const char *IVRDriverLog_Version = "IVRDriverLog_001"; -} +} // namespace vr // ivrserverdriverhost.h namespace vr { - class ITrackedDeviceServerDriver; struct TrackedDeviceDriverInfo_t; struct DriverPose_t; @@ -2265,74 +2191,73 @@ public: /** Notifies the server that a tracked device has been added. If this function returns true * the server will call Activate on the device. If it returns false some kind of error * has occurred and the device will not be activated. */ - virtual bool TrackedDeviceAdded( const char *pchDeviceSerialNumber, ETrackedDeviceClass eDeviceClass, ITrackedDeviceServerDriver *pDriver ) = 0; + virtual bool TrackedDeviceAdded(const char *pchDeviceSerialNumber, ETrackedDeviceClass eDeviceClass, ITrackedDeviceServerDriver *pDriver) = 0; /** Notifies the server that a tracked device's pose has been updated */ - virtual void TrackedDevicePoseUpdated( uint32_t unWhichDevice, const DriverPose_t & newPose, uint32_t unPoseStructSize ) = 0; + virtual void TrackedDevicePoseUpdated(uint32_t unWhichDevice, const DriverPose_t &newPose, uint32_t unPoseStructSize) = 0; /** Notifies the server that vsync has occurred on the the display attached to the device. This is * only permitted on devices of the HMD class. */ - virtual void VsyncEvent( double vsyncTimeOffsetSeconds ) = 0; + virtual void VsyncEvent(double vsyncTimeOffsetSeconds) = 0; /** notifies the server that the button was pressed */ - virtual void TrackedDeviceButtonPressed( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; + virtual void TrackedDeviceButtonPressed(uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset) = 0; /** notifies the server that the button was unpressed */ - virtual void TrackedDeviceButtonUnpressed( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; + virtual void TrackedDeviceButtonUnpressed(uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset) = 0; /** notifies the server that the button was pressed */ - virtual void TrackedDeviceButtonTouched( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; + virtual void TrackedDeviceButtonTouched(uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset) = 0; /** notifies the server that the button was unpressed */ - virtual void TrackedDeviceButtonUntouched( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; + virtual void TrackedDeviceButtonUntouched(uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset) = 0; /** notifies the server than a controller axis changed */ - virtual void TrackedDeviceAxisUpdated( uint32_t unWhichDevice, uint32_t unWhichAxis, const VRControllerAxis_t & axisState ) = 0; + virtual void TrackedDeviceAxisUpdated(uint32_t unWhichDevice, uint32_t unWhichAxis, const VRControllerAxis_t &axisState) = 0; /** Notifies the server that the proximity sensor on the specified device */ - virtual void ProximitySensorState( uint32_t unWhichDevice, bool bProximitySensorTriggered ) = 0; + virtual void ProximitySensorState(uint32_t unWhichDevice, bool bProximitySensorTriggered) = 0; /** Sends a vendor specific event (VREvent_VendorSpecific_Reserved_Start..VREvent_VendorSpecific_Reserved_End */ - virtual void VendorSpecificEvent( uint32_t unWhichDevice, vr::EVREventType eventType, const VREvent_Data_t & eventData, double eventTimeOffset ) = 0; + virtual void VendorSpecificEvent(uint32_t unWhichDevice, vr::EVREventType eventType, const VREvent_Data_t &eventData, double eventTimeOffset) = 0; /** Returns true if SteamVR is exiting */ virtual bool IsExiting() = 0; /** Returns true and fills the event with the next event on the queue if there is one. If there are no events * this method returns false. uncbVREvent should be the size in bytes of the VREvent_t struct */ - virtual bool PollNextEvent( VREvent_t *pEvent, uint32_t uncbVREvent ) = 0; + virtual bool PollNextEvent(VREvent_t *pEvent, uint32_t uncbVREvent) = 0; /** Provides access to device poses for drivers. Poses are in their "raw" tracking space which is uniquely * defined by each driver providing poses for its devices. It is up to clients of this function to correlate * poses across different drivers. Poses are indexed by their device id, and their associated driver and * other properties can be looked up via IVRProperties. */ - virtual void GetRawTrackedDevicePoses( float fPredictedSecondsFromNow, TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount ) = 0; + virtual void GetRawTrackedDevicePoses(float fPredictedSecondsFromNow, TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount) = 0; /** Notifies the server that a tracked device's display component transforms have been updated. */ - virtual void TrackedDeviceDisplayTransformUpdated( uint32_t unWhichDevice, HmdMatrix34_t eyeToHeadLeft, HmdMatrix34_t eyeToHeadRight ) = 0; + virtual void TrackedDeviceDisplayTransformUpdated(uint32_t unWhichDevice, HmdMatrix34_t eyeToHeadLeft, HmdMatrix34_t eyeToHeadRight) = 0; }; static const char *IVRServerDriverHost_Version = "IVRServerDriverHost_004"; -} +} // namespace vr // ivrhiddenarea.h namespace vr { - class CVRHiddenAreaHelpers { public: - CVRHiddenAreaHelpers( IVRProperties *pProperties ) : m_pProperties( pProperties ) {} + CVRHiddenAreaHelpers(IVRProperties *pProperties) : m_pProperties(pProperties) {} /** Stores a hidden area mesh in a property */ - ETrackedPropertyError SetHiddenArea( EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount ); + ETrackedPropertyError SetHiddenArea(EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount); /** retrieves a hidden area mesh from a property. Returns the vert count read out of the property. */ - uint32_t GetHiddenArea( EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount, ETrackedPropertyError *peError ); + uint32_t GetHiddenArea(EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount, ETrackedPropertyError *peError); private: - ETrackedDeviceProperty GetPropertyEnum( EVREye eEye, EHiddenAreaMeshType type ) + ETrackedDeviceProperty GetPropertyEnum(EVREye eEye, EHiddenAreaMeshType type) { return (ETrackedDeviceProperty)(Prop_DisplayHiddenArea_Binary_Start + ((int)type * 2) + (int)eEye); } @@ -2340,41 +2265,38 @@ private: IVRProperties *m_pProperties; }; - -inline ETrackedPropertyError CVRHiddenAreaHelpers::SetHiddenArea( EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount ) +inline ETrackedPropertyError CVRHiddenAreaHelpers::SetHiddenArea(EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount) { - ETrackedDeviceProperty prop = GetPropertyEnum( eEye, type ); - CVRPropertyHelpers propHelpers( m_pProperties ); - return propHelpers.SetProperty( propHelpers.TrackedDeviceToPropertyContainer( k_unTrackedDeviceIndex_Hmd ), prop, pVerts, sizeof( HmdVector2_t ) * unVertCount, k_unHiddenAreaPropertyTag ); + ETrackedDeviceProperty prop = GetPropertyEnum(eEye, type); + CVRPropertyHelpers propHelpers(m_pProperties); + return propHelpers.SetProperty(propHelpers.TrackedDeviceToPropertyContainer(k_unTrackedDeviceIndex_Hmd), prop, pVerts, sizeof(HmdVector2_t) * unVertCount, k_unHiddenAreaPropertyTag); } - -inline uint32_t CVRHiddenAreaHelpers::GetHiddenArea( EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount, ETrackedPropertyError *peError ) +inline uint32_t CVRHiddenAreaHelpers::GetHiddenArea(EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount, ETrackedPropertyError *peError) { - ETrackedDeviceProperty prop = GetPropertyEnum( eEye, type ); - CVRPropertyHelpers propHelpers( m_pProperties ); + ETrackedDeviceProperty prop = GetPropertyEnum(eEye, type); + CVRPropertyHelpers propHelpers(m_pProperties); ETrackedPropertyError propError; PropertyTypeTag_t unTag; - uint32_t unBytesNeeded = propHelpers.GetProperty( propHelpers.TrackedDeviceToPropertyContainer( k_unTrackedDeviceIndex_Hmd ), prop, pVerts, sizeof( HmdVector2_t )*unVertCount, &unTag, &propError ); - if ( propError == TrackedProp_Success && unTag != k_unHiddenAreaPropertyTag ) + uint32_t unBytesNeeded = propHelpers.GetProperty(propHelpers.TrackedDeviceToPropertyContainer(k_unTrackedDeviceIndex_Hmd), prop, pVerts, sizeof(HmdVector2_t) * unVertCount, &unTag, &propError); + if (propError == TrackedProp_Success && unTag != k_unHiddenAreaPropertyTag) { propError = TrackedProp_WrongDataType; unBytesNeeded = 0; } - if ( peError ) + if (peError) { *peError = propError; } - return unBytesNeeded / sizeof( HmdVector2_t ); + return unBytesNeeded / sizeof(HmdVector2_t); } -} +} // namespace vr // ivrwatchdoghost.h namespace vr { - /** This interface is provided by vrclient to allow the driver to make everything wake up */ class IVRWatchdogHost { @@ -2386,87 +2308,75 @@ public: static const char *IVRWatchdogHost_Version = "IVRWatchdogHost_001"; -}; - - +}; // namespace vr // ivrvirtualdisplay.h namespace vr { - // ---------------------------------------------------------------------------------------------- - // Purpose: This component is used for drivers that implement a virtual display (e.g. wireless). - // ---------------------------------------------------------------------------------------------- - class IVRVirtualDisplay - { - public: +// ---------------------------------------------------------------------------------------------- +// Purpose: This component is used for drivers that implement a virtual display (e.g. wireless). +// ---------------------------------------------------------------------------------------------- +class IVRVirtualDisplay +{ +public: + /** Submits final backbuffer for display. */ + virtual void Present(vr::SharedTextureHandle_t backbufferTextureHandle) = 0; - /** Submits final backbuffer for display. */ - virtual void Present( vr::SharedTextureHandle_t backbufferTextureHandle ) = 0; + /** Block until the last presented buffer start scanning out. */ + virtual void WaitForPresent() = 0; - /** Block until the last presented buffer start scanning out. */ - virtual void WaitForPresent() = 0; + /** Provides timing data for synchronizing with display. */ + virtual bool GetTimeSinceLastVsync(float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter) = 0; +}; - /** Provides timing data for synchronizing with display. */ - virtual bool GetTimeSinceLastVsync( float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter ) = 0; - }; - - static const char *IVRVirtualDisplay_Version = "IVRVirtualDisplay_001"; - - /** Returns the current IVRVirtualDisplay pointer or NULL the interface could not be found. */ - VR_INTERFACE vr::IVRVirtualDisplay *VR_CALLTYPE VRVirtualDisplay(); -} +static const char *IVRVirtualDisplay_Version = "IVRVirtualDisplay_001"; +/** Returns the current IVRVirtualDisplay pointer or NULL the interface could not be found. */ +VR_INTERFACE vr::IVRVirtualDisplay *VR_CALLTYPE VRVirtualDisplay(); +} // namespace vr // ivrresources.h namespace vr { - class IVRResources { public: - // ------------------------------------ // Shared Resource Methods // ------------------------------------ /** Loads the specified resource into the provided buffer if large enough. * Returns the size in bytes of the buffer required to hold the specified resource. */ - virtual uint32_t LoadSharedResource( const char *pchResourceName, char *pchBuffer, uint32_t unBufferLen ) = 0; + virtual uint32_t LoadSharedResource(const char *pchResourceName, char *pchBuffer, uint32_t unBufferLen) = 0; /** Provides the full path to the specified resource. Resource names can include named directories for * drivers and other things, and this resolves all of those and returns the actual physical path. * pchResourceTypeDirectory is the subdirectory of resources to look in. */ - virtual uint32_t GetResourceFullPath( const char *pchResourceName, const char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen ) = 0; + virtual uint32_t GetResourceFullPath(const char *pchResourceName, const char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen) = 0; }; -static const char * const IVRResources_Version = "IVRResources_001"; +static const char *const IVRResources_Version = "IVRResources_001"; - -} +} // namespace vr // ivrdrivermanager.h namespace vr { - class IVRDriverManager { public: virtual uint32_t GetDriverCount() const = 0; /** Returns the length of the number of bytes necessary to hold this string including the trailing null. */ - virtual uint32_t GetDriverName( vr::DriverId_t nDriver, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize ) = 0; + virtual uint32_t GetDriverName(vr::DriverId_t nDriver, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize) = 0; }; -static const char * const IVRDriverManager_Version = "IVRDriverManager_001"; - -} // namespace vr - - - +static const char *const IVRDriverManager_Version = "IVRDriverManager_001"; +} // namespace vr namespace vr { - static const char * const k_InterfaceVersions[] = +static const char *const k_InterfaceVersions[] = { IVRSettings_Version, ITrackedDeviceServerDriver_Version, @@ -2479,217 +2389,207 @@ namespace vr IVRVirtualDisplay_Version, IVRDriverManager_Version, IVRResources_Version, - nullptr - }; + nullptr}; - inline IVRDriverContext *&VRDriverContext() - { - static IVRDriverContext *pHost; - return pHost; - } - - class COpenVRDriverContext - { - public: - COpenVRDriverContext() : m_propertyHelpers(nullptr), m_hiddenAreaHelpers(nullptr) { Clear(); } - void Clear(); - - EVRInitError InitServer(); - EVRInitError InitWatchdog(); - - IVRSettings *VRSettings() - { - if ( m_pVRSettings == nullptr ) - { - EVRInitError eError; - m_pVRSettings = (IVRSettings *)VRDriverContext()->GetGenericInterface( IVRSettings_Version, &eError ); - } - return m_pVRSettings; - } - - IVRProperties *VRPropertiesRaw() - { - if ( m_pVRProperties == nullptr ) - { - EVRInitError eError; - m_pVRProperties = (IVRProperties *)VRDriverContext()->GetGenericInterface( IVRProperties_Version, &eError ); - m_propertyHelpers = CVRPropertyHelpers( m_pVRProperties ); - m_hiddenAreaHelpers = CVRHiddenAreaHelpers( m_pVRProperties ); - } - return m_pVRProperties; - } - - CVRPropertyHelpers *VRProperties() - { - VRPropertiesRaw(); - return &m_propertyHelpers; - } - - CVRHiddenAreaHelpers *VRHiddenArea() - { - VRPropertiesRaw(); - return &m_hiddenAreaHelpers; - } - - IVRServerDriverHost *VRServerDriverHost() - { - if ( m_pVRServerDriverHost == nullptr ) - { - EVRInitError eError; - m_pVRServerDriverHost = (IVRServerDriverHost *)VRDriverContext()->GetGenericInterface( IVRServerDriverHost_Version, &eError ); - } - return m_pVRServerDriverHost; - } - - IVRWatchdogHost *VRWatchdogHost() - { - if ( m_pVRWatchdogHost == nullptr ) - { - EVRInitError eError; - m_pVRWatchdogHost = (IVRWatchdogHost *)VRDriverContext()->GetGenericInterface( IVRWatchdogHost_Version, &eError ); - } - return m_pVRWatchdogHost; - } - - IVRDriverLog *VRDriverLog() - { - if ( m_pVRDriverLog == nullptr ) - { - EVRInitError eError; - m_pVRDriverLog = (IVRDriverLog *)VRDriverContext()->GetGenericInterface( IVRDriverLog_Version, &eError ); - } - return m_pVRDriverLog; - } - - DriverHandle_t VR_CALLTYPE VRDriverHandle() - { - return VRDriverContext()->GetDriverHandle(); - } - - IVRDriverManager *VRDriverManager() - { - if ( !m_pVRDriverManager ) - { - EVRInitError eError; - m_pVRDriverManager = (IVRDriverManager *)VRDriverContext()->GetGenericInterface( IVRDriverManager_Version, &eError ); - } - return m_pVRDriverManager; - } - - IVRResources *VRResources() - { - if ( !m_pVRResources ) - { - EVRInitError eError; - m_pVRResources = (IVRResources *)VRDriverContext()->GetGenericInterface( IVRResources_Version, &eError ); - } - return m_pVRResources; - } - - private: - CVRPropertyHelpers m_propertyHelpers; - CVRHiddenAreaHelpers m_hiddenAreaHelpers; - - IVRSettings *m_pVRSettings; - IVRProperties *m_pVRProperties; - IVRServerDriverHost *m_pVRServerDriverHost; - IVRWatchdogHost *m_pVRWatchdogHost; - IVRDriverLog *m_pVRDriverLog; - IVRDriverManager *m_pVRDriverManager; - IVRResources *m_pVRResources; - }; - - inline COpenVRDriverContext &OpenVRInternal_ModuleServerDriverContext() - { - static void *ctx[sizeof( COpenVRDriverContext ) / sizeof( void * )]; - return *(COpenVRDriverContext *)ctx; // bypass zero-init constructor - } - - inline IVRSettings *VR_CALLTYPE VRSettings() { return OpenVRInternal_ModuleServerDriverContext().VRSettings(); } - inline IVRProperties *VR_CALLTYPE VRPropertiesRaw() { return OpenVRInternal_ModuleServerDriverContext().VRPropertiesRaw(); } - inline CVRPropertyHelpers *VR_CALLTYPE VRProperties() { return OpenVRInternal_ModuleServerDriverContext().VRProperties(); } - inline CVRHiddenAreaHelpers *VR_CALLTYPE VRHiddenArea() { return OpenVRInternal_ModuleServerDriverContext().VRHiddenArea(); } - inline IVRDriverLog *VR_CALLTYPE VRDriverLog() { return OpenVRInternal_ModuleServerDriverContext().VRDriverLog(); } - inline IVRServerDriverHost *VR_CALLTYPE VRServerDriverHost() { return OpenVRInternal_ModuleServerDriverContext().VRServerDriverHost(); } - inline IVRWatchdogHost *VR_CALLTYPE VRWatchdogHost() { return OpenVRInternal_ModuleServerDriverContext().VRWatchdogHost(); } - inline DriverHandle_t VR_CALLTYPE VRDriverHandle() { return OpenVRInternal_ModuleServerDriverContext().VRDriverHandle(); } - inline IVRDriverManager *VR_CALLTYPE VRDriverManager() { return OpenVRInternal_ModuleServerDriverContext().VRDriverManager(); } - inline IVRResources *VR_CALLTYPE VRResources() { return OpenVRInternal_ModuleServerDriverContext().VRResources(); } - - inline void COpenVRDriverContext::Clear() - { - m_pVRSettings = nullptr; - m_pVRProperties = nullptr; - m_pVRServerDriverHost = nullptr; - m_pVRDriverLog = nullptr; - m_pVRWatchdogHost = nullptr; - m_pVRDriverManager = nullptr; - m_pVRResources = nullptr; - } - - inline EVRInitError COpenVRDriverContext::InitServer() - { - Clear(); - if ( !VRServerDriverHost() - || !VRSettings() - || !VRProperties() - || !VRDriverLog() - || !VRDriverManager() - || !VRResources() ) - return VRInitError_Init_InterfaceNotFound; - return VRInitError_None; - } - - inline EVRInitError COpenVRDriverContext::InitWatchdog() - { - Clear(); - if ( !VRWatchdogHost() - || !VRSettings() - || !VRDriverLog() ) - return VRInitError_Init_InterfaceNotFound; - return VRInitError_None; - } - - inline EVRInitError InitServerDriverContext( IVRDriverContext *pContext ) - { - VRDriverContext() = pContext; - return OpenVRInternal_ModuleServerDriverContext().InitServer(); - } - - inline EVRInitError InitWatchdogDriverContext( IVRDriverContext *pContext ) - { - VRDriverContext() = pContext; - return OpenVRInternal_ModuleServerDriverContext().InitWatchdog(); - } - - inline void CleanupDriverContext() - { - VRDriverContext() = nullptr; - OpenVRInternal_ModuleServerDriverContext().Clear(); - } - - #define VR_INIT_SERVER_DRIVER_CONTEXT( pContext ) \ - { \ - vr::EVRInitError eError = vr::InitServerDriverContext( pContext ); \ - if( eError != vr::VRInitError_None ) \ - return eError; \ - } - - #define VR_CLEANUP_SERVER_DRIVER_CONTEXT() \ - vr::CleanupDriverContext(); - - #define VR_INIT_WATCHDOG_DRIVER_CONTEXT( pContext ) \ - { \ - vr::EVRInitError eError = vr::InitWatchdogDriverContext( pContext ); \ - if( eError != vr::VRInitError_None ) \ - return eError; \ - } - - #define VR_CLEANUP_WATCHDOG_DRIVER_CONTEXT() \ - vr::CleanupDriverContext(); +inline IVRDriverContext *&VRDriverContext() +{ + static IVRDriverContext *pHost; + return pHost; } + +class COpenVRDriverContext +{ +public: + COpenVRDriverContext() : m_propertyHelpers(nullptr), m_hiddenAreaHelpers(nullptr) { Clear(); } + void Clear(); + + EVRInitError InitServer(); + EVRInitError InitWatchdog(); + + IVRSettings *VRSettings() + { + if (m_pVRSettings == nullptr) + { + EVRInitError eError; + m_pVRSettings = (IVRSettings *)VRDriverContext()->GetGenericInterface(IVRSettings_Version, &eError); + } + return m_pVRSettings; + } + + IVRProperties *VRPropertiesRaw() + { + if (m_pVRProperties == nullptr) + { + EVRInitError eError; + m_pVRProperties = (IVRProperties *)VRDriverContext()->GetGenericInterface(IVRProperties_Version, &eError); + m_propertyHelpers = CVRPropertyHelpers(m_pVRProperties); + m_hiddenAreaHelpers = CVRHiddenAreaHelpers(m_pVRProperties); + } + return m_pVRProperties; + } + + CVRPropertyHelpers *VRProperties() + { + VRPropertiesRaw(); + return &m_propertyHelpers; + } + + CVRHiddenAreaHelpers *VRHiddenArea() + { + VRPropertiesRaw(); + return &m_hiddenAreaHelpers; + } + + IVRServerDriverHost *VRServerDriverHost() + { + if (m_pVRServerDriverHost == nullptr) + { + EVRInitError eError; + m_pVRServerDriverHost = (IVRServerDriverHost *)VRDriverContext()->GetGenericInterface(IVRServerDriverHost_Version, &eError); + } + return m_pVRServerDriverHost; + } + + IVRWatchdogHost *VRWatchdogHost() + { + if (m_pVRWatchdogHost == nullptr) + { + EVRInitError eError; + m_pVRWatchdogHost = (IVRWatchdogHost *)VRDriverContext()->GetGenericInterface(IVRWatchdogHost_Version, &eError); + } + return m_pVRWatchdogHost; + } + + IVRDriverLog *VRDriverLog() + { + if (m_pVRDriverLog == nullptr) + { + EVRInitError eError; + m_pVRDriverLog = (IVRDriverLog *)VRDriverContext()->GetGenericInterface(IVRDriverLog_Version, &eError); + } + return m_pVRDriverLog; + } + + DriverHandle_t VR_CALLTYPE VRDriverHandle() + { + return VRDriverContext()->GetDriverHandle(); + } + + IVRDriverManager *VRDriverManager() + { + if (!m_pVRDriverManager) + { + EVRInitError eError; + m_pVRDriverManager = (IVRDriverManager *)VRDriverContext()->GetGenericInterface(IVRDriverManager_Version, &eError); + } + return m_pVRDriverManager; + } + + IVRResources *VRResources() + { + if (!m_pVRResources) + { + EVRInitError eError; + m_pVRResources = (IVRResources *)VRDriverContext()->GetGenericInterface(IVRResources_Version, &eError); + } + return m_pVRResources; + } + +private: + CVRPropertyHelpers m_propertyHelpers; + CVRHiddenAreaHelpers m_hiddenAreaHelpers; + + IVRSettings *m_pVRSettings; + IVRProperties *m_pVRProperties; + IVRServerDriverHost *m_pVRServerDriverHost; + IVRWatchdogHost *m_pVRWatchdogHost; + IVRDriverLog *m_pVRDriverLog; + IVRDriverManager *m_pVRDriverManager; + IVRResources *m_pVRResources; +}; + +inline COpenVRDriverContext &OpenVRInternal_ModuleServerDriverContext() +{ + static void *ctx[sizeof(COpenVRDriverContext) / sizeof(void *)]; + return *(COpenVRDriverContext *)ctx; // bypass zero-init constructor +} + +inline IVRSettings *VR_CALLTYPE VRSettings() { return OpenVRInternal_ModuleServerDriverContext().VRSettings(); } +inline IVRProperties *VR_CALLTYPE VRPropertiesRaw() { return OpenVRInternal_ModuleServerDriverContext().VRPropertiesRaw(); } +inline CVRPropertyHelpers *VR_CALLTYPE VRProperties() { return OpenVRInternal_ModuleServerDriverContext().VRProperties(); } +inline CVRHiddenAreaHelpers *VR_CALLTYPE VRHiddenArea() { return OpenVRInternal_ModuleServerDriverContext().VRHiddenArea(); } +inline IVRDriverLog *VR_CALLTYPE VRDriverLog() { return OpenVRInternal_ModuleServerDriverContext().VRDriverLog(); } +inline IVRServerDriverHost *VR_CALLTYPE VRServerDriverHost() { return OpenVRInternal_ModuleServerDriverContext().VRServerDriverHost(); } +inline IVRWatchdogHost *VR_CALLTYPE VRWatchdogHost() { return OpenVRInternal_ModuleServerDriverContext().VRWatchdogHost(); } +inline DriverHandle_t VR_CALLTYPE VRDriverHandle() { return OpenVRInternal_ModuleServerDriverContext().VRDriverHandle(); } +inline IVRDriverManager *VR_CALLTYPE VRDriverManager() { return OpenVRInternal_ModuleServerDriverContext().VRDriverManager(); } +inline IVRResources *VR_CALLTYPE VRResources() { return OpenVRInternal_ModuleServerDriverContext().VRResources(); } + +inline void COpenVRDriverContext::Clear() +{ + m_pVRSettings = nullptr; + m_pVRProperties = nullptr; + m_pVRServerDriverHost = nullptr; + m_pVRDriverLog = nullptr; + m_pVRWatchdogHost = nullptr; + m_pVRDriverManager = nullptr; + m_pVRResources = nullptr; +} + +inline EVRInitError COpenVRDriverContext::InitServer() +{ + Clear(); + if (!VRServerDriverHost() || !VRSettings() || !VRProperties() || !VRDriverLog() || !VRDriverManager() || !VRResources()) + return VRInitError_Init_InterfaceNotFound; + return VRInitError_None; +} + +inline EVRInitError COpenVRDriverContext::InitWatchdog() +{ + Clear(); + if (!VRWatchdogHost() || !VRSettings() || !VRDriverLog()) + return VRInitError_Init_InterfaceNotFound; + return VRInitError_None; +} + +inline EVRInitError InitServerDriverContext(IVRDriverContext *pContext) +{ + VRDriverContext() = pContext; + return OpenVRInternal_ModuleServerDriverContext().InitServer(); +} + +inline EVRInitError InitWatchdogDriverContext(IVRDriverContext *pContext) +{ + VRDriverContext() = pContext; + return OpenVRInternal_ModuleServerDriverContext().InitWatchdog(); +} + +inline void CleanupDriverContext() +{ + VRDriverContext() = nullptr; + OpenVRInternal_ModuleServerDriverContext().Clear(); +} + +#define VR_INIT_SERVER_DRIVER_CONTEXT(pContext) \ + { \ + vr::EVRInitError eError = vr::InitServerDriverContext(pContext); \ + if (eError != vr::VRInitError_None) \ + return eError; \ + } + +#define VR_CLEANUP_SERVER_DRIVER_CONTEXT() \ + vr::CleanupDriverContext(); + +#define VR_INIT_WATCHDOG_DRIVER_CONTEXT(pContext) \ + { \ + vr::EVRInitError eError = vr::InitWatchdogDriverContext(pContext); \ + if (eError != vr::VRInitError_None) \ + return eError; \ + } + +#define VR_CLEANUP_WATCHDOG_DRIVER_CONTEXT() \ + vr::CleanupDriverContext(); +} // namespace vr // End -#endif // _OPENVR_DRIVER_API - - +#endif // _OPENVR_DRIVER_API diff --git a/examples/ThirdPartyLibs/openvr/headers/openvr.h b/examples/ThirdPartyLibs/openvr/headers/openvr.h index f945dbc1a..80461f968 100644 --- a/examples/ThirdPartyLibs/openvr/headers/openvr.h +++ b/examples/ThirdPartyLibs/openvr/headers/openvr.h @@ -9,8 +9,6 @@ #include - - // vrtypes.h #ifndef _INCLUDE_VRTYPES_H #define _INCLUDE_VRTYPES_H @@ -27,9 +25,9 @@ struct ID3D12CommandQueue; namespace vr { -#pragma pack( push, 8 ) +#pragma pack(push, 8) -typedef void* glSharedTextureHandle_t; +typedef void *glSharedTextureHandle_t; typedef int32_t glInt_t; typedef uint32_t glUInt_t; @@ -80,7 +78,7 @@ struct HmdColor_t struct HmdQuad_t { - HmdVector3_t vCorners[ 4 ]; + HmdVector3_t vCorners[4]; }; struct HmdRect2_t @@ -107,40 +105,40 @@ enum EVREye enum ETextureType { - TextureType_DirectX = 0, // Handle is an ID3D11Texture - TextureType_OpenGL = 1, // Handle is an OpenGL texture name or an OpenGL render buffer name, depending on submit flags - TextureType_Vulkan = 2, // Handle is a pointer to a VRVulkanTextureData_t structure - TextureType_IOSurface = 3, // Handle is a macOS cross-process-sharable IOSurfaceRef - TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure + TextureType_DirectX = 0, // Handle is an ID3D11Texture + TextureType_OpenGL = 1, // Handle is an OpenGL texture name or an OpenGL render buffer name, depending on submit flags + TextureType_Vulkan = 2, // Handle is a pointer to a VRVulkanTextureData_t structure + TextureType_IOSurface = 3, // Handle is a macOS cross-process-sharable IOSurfaceRef + TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure }; enum EColorSpace { - ColorSpace_Auto = 0, // Assumes 'gamma' for 8-bit per component formats, otherwise 'linear'. This mirrors the DXGI formats which have _SRGB variants. - ColorSpace_Gamma = 1, // Texture data can be displayed directly on the display without any conversion (a.k.a. display native format). - ColorSpace_Linear = 2, // Same as gamma but has been converted to a linear representation using DXGI's sRGB conversion algorithm. + ColorSpace_Auto = 0, // Assumes 'gamma' for 8-bit per component formats, otherwise 'linear'. This mirrors the DXGI formats which have _SRGB variants. + ColorSpace_Gamma = 1, // Texture data can be displayed directly on the display without any conversion (a.k.a. display native format). + ColorSpace_Linear = 2, // Same as gamma but has been converted to a linear representation using DXGI's sRGB conversion algorithm. }; struct Texture_t { - void* handle; // See ETextureType definition above + void *handle; // See ETextureType definition above ETextureType eType; EColorSpace eColorSpace; }; // Handle to a shared texture (HANDLE on Windows obtained using OpenSharedResource). typedef uint64_t SharedTextureHandle_t; -#define INVALID_SHARED_TEXTURE_HANDLE ((vr::SharedTextureHandle_t)0) +#define INVALID_SHARED_TEXTURE_HANDLE ((vr::SharedTextureHandle_t)0) enum ETrackingResult { - TrackingResult_Uninitialized = 1, + TrackingResult_Uninitialized = 1, - TrackingResult_Calibrating_InProgress = 100, - TrackingResult_Calibrating_OutOfRange = 101, + TrackingResult_Calibrating_InProgress = 100, + TrackingResult_Calibrating_OutOfRange = 101, - TrackingResult_Running_OK = 200, - TrackingResult_Running_OutOfRange = 201, + TrackingResult_Running_OK = 200, + TrackingResult_Running_OutOfRange = 201, }; typedef uint32_t DriverId_t; @@ -158,30 +156,28 @@ static const uint32_t k_unTrackedDeviceIndexInvalid = 0xFFFFFFFF; /** Describes what kind of object is being tracked at a given ID */ enum ETrackedDeviceClass { - TrackedDeviceClass_Invalid = 0, // the ID was not valid. - TrackedDeviceClass_HMD = 1, // Head-Mounted Displays - TrackedDeviceClass_Controller = 2, // Tracked controllers - TrackedDeviceClass_GenericTracker = 3, // Generic trackers, similar to controllers - TrackedDeviceClass_TrackingReference = 4, // Camera and base stations that serve as tracking reference points - TrackedDeviceClass_DisplayRedirect = 5, // Accessories that aren't necessarily tracked themselves, but may redirect video output from other tracked devices + TrackedDeviceClass_Invalid = 0, // the ID was not valid. + TrackedDeviceClass_HMD = 1, // Head-Mounted Displays + TrackedDeviceClass_Controller = 2, // Tracked controllers + TrackedDeviceClass_GenericTracker = 3, // Generic trackers, similar to controllers + TrackedDeviceClass_TrackingReference = 4, // Camera and base stations that serve as tracking reference points + TrackedDeviceClass_DisplayRedirect = 5, // Accessories that aren't necessarily tracked themselves, but may redirect video output from other tracked devices }; - /** Describes what specific role associated with a tracked device */ enum ETrackedControllerRole { - TrackedControllerRole_Invalid = 0, // Invalid value for controller type - TrackedControllerRole_LeftHand = 1, // Tracked device associated with the left hand - TrackedControllerRole_RightHand = 2, // Tracked device associated with the right hand + TrackedControllerRole_Invalid = 0, // Invalid value for controller type + TrackedControllerRole_LeftHand = 1, // Tracked device associated with the left hand + TrackedControllerRole_RightHand = 2, // Tracked device associated with the right hand }; - /** describes a single pose for a tracked object */ struct TrackedDevicePose_t { HmdMatrix34_t mDeviceToAbsoluteTracking; - HmdVector3_t vVelocity; // velocity in tracker space in m/s - HmdVector3_t vAngularVelocity; // angular velocity in radians/s (?) + HmdVector3_t vVelocity; // velocity in tracker space in m/s + HmdVector3_t vAngularVelocity; // angular velocity in radians/s (?) ETrackingResult eTrackingResult; bool bPoseIsValid; @@ -194,9 +190,9 @@ struct TrackedDevicePose_t * for the poses it is requesting */ enum ETrackingUniverseOrigin { - TrackingUniverseSeated = 0, // Poses are provided relative to the seated zero pose - TrackingUniverseStanding = 1, // Poses are provided relative to the safe bounds configured by the user - TrackingUniverseRawAndUncalibrated = 2, // Poses are provided in the coordinate system defined by the driver. It has Y up and is unified for devices of the same driver. You usually don't want this one. + TrackingUniverseSeated = 0, // Poses are provided relative to the seated zero pose + TrackingUniverseStanding = 1, // Poses are provided relative to the safe bounds configured by the user + TrackingUniverseRawAndUncalibrated = 2, // Poses are provided in the coordinate system defined by the driver. It has Y up and is unified for devices of the same driver. You usually don't want this one. }; // Refers to a single container of properties @@ -223,146 +219,145 @@ static const PropertyTypeTag_t k_unHiddenAreaPropertyTag = 30; static const PropertyTypeTag_t k_unOpenVRInternalReserved_Start = 1000; static const PropertyTypeTag_t k_unOpenVRInternalReserved_End = 10000; - /** Each entry in this enum represents a property that can be retrieved about a * tracked device. Many fields are only valid for one ETrackedDeviceClass. */ enum ETrackedDeviceProperty { - Prop_Invalid = 0, + Prop_Invalid = 0, // general properties that apply to all device classes - Prop_TrackingSystemName_String = 1000, - Prop_ModelNumber_String = 1001, - Prop_SerialNumber_String = 1002, - Prop_RenderModelName_String = 1003, - Prop_WillDriftInYaw_Bool = 1004, - Prop_ManufacturerName_String = 1005, - Prop_TrackingFirmwareVersion_String = 1006, - Prop_HardwareRevision_String = 1007, - Prop_AllWirelessDongleDescriptions_String = 1008, - Prop_ConnectedWirelessDongle_String = 1009, - Prop_DeviceIsWireless_Bool = 1010, - Prop_DeviceIsCharging_Bool = 1011, - Prop_DeviceBatteryPercentage_Float = 1012, // 0 is empty, 1 is full - Prop_StatusDisplayTransform_Matrix34 = 1013, - Prop_Firmware_UpdateAvailable_Bool = 1014, - Prop_Firmware_ManualUpdate_Bool = 1015, - Prop_Firmware_ManualUpdateURL_String = 1016, - Prop_HardwareRevision_Uint64 = 1017, - Prop_FirmwareVersion_Uint64 = 1018, - Prop_FPGAVersion_Uint64 = 1019, - Prop_VRCVersion_Uint64 = 1020, - Prop_RadioVersion_Uint64 = 1021, - Prop_DongleVersion_Uint64 = 1022, - Prop_BlockServerShutdown_Bool = 1023, - Prop_CanUnifyCoordinateSystemWithHmd_Bool = 1024, - Prop_ContainsProximitySensor_Bool = 1025, - Prop_DeviceProvidesBatteryStatus_Bool = 1026, - Prop_DeviceCanPowerOff_Bool = 1027, - Prop_Firmware_ProgrammingTarget_String = 1028, - Prop_DeviceClass_Int32 = 1029, - Prop_HasCamera_Bool = 1030, - Prop_DriverVersion_String = 1031, - Prop_Firmware_ForceUpdateRequired_Bool = 1032, - Prop_ViveSystemButtonFixRequired_Bool = 1033, - Prop_ParentDriver_Uint64 = 1034, - Prop_ResourceRoot_String = 1035, + Prop_TrackingSystemName_String = 1000, + Prop_ModelNumber_String = 1001, + Prop_SerialNumber_String = 1002, + Prop_RenderModelName_String = 1003, + Prop_WillDriftInYaw_Bool = 1004, + Prop_ManufacturerName_String = 1005, + Prop_TrackingFirmwareVersion_String = 1006, + Prop_HardwareRevision_String = 1007, + Prop_AllWirelessDongleDescriptions_String = 1008, + Prop_ConnectedWirelessDongle_String = 1009, + Prop_DeviceIsWireless_Bool = 1010, + Prop_DeviceIsCharging_Bool = 1011, + Prop_DeviceBatteryPercentage_Float = 1012, // 0 is empty, 1 is full + Prop_StatusDisplayTransform_Matrix34 = 1013, + Prop_Firmware_UpdateAvailable_Bool = 1014, + Prop_Firmware_ManualUpdate_Bool = 1015, + Prop_Firmware_ManualUpdateURL_String = 1016, + Prop_HardwareRevision_Uint64 = 1017, + Prop_FirmwareVersion_Uint64 = 1018, + Prop_FPGAVersion_Uint64 = 1019, + Prop_VRCVersion_Uint64 = 1020, + Prop_RadioVersion_Uint64 = 1021, + Prop_DongleVersion_Uint64 = 1022, + Prop_BlockServerShutdown_Bool = 1023, + Prop_CanUnifyCoordinateSystemWithHmd_Bool = 1024, + Prop_ContainsProximitySensor_Bool = 1025, + Prop_DeviceProvidesBatteryStatus_Bool = 1026, + Prop_DeviceCanPowerOff_Bool = 1027, + Prop_Firmware_ProgrammingTarget_String = 1028, + Prop_DeviceClass_Int32 = 1029, + Prop_HasCamera_Bool = 1030, + Prop_DriverVersion_String = 1031, + Prop_Firmware_ForceUpdateRequired_Bool = 1032, + Prop_ViveSystemButtonFixRequired_Bool = 1033, + Prop_ParentDriver_Uint64 = 1034, + Prop_ResourceRoot_String = 1035, // Properties that are unique to TrackedDeviceClass_HMD - Prop_ReportsTimeSinceVSync_Bool = 2000, - Prop_SecondsFromVsyncToPhotons_Float = 2001, - Prop_DisplayFrequency_Float = 2002, - Prop_UserIpdMeters_Float = 2003, - Prop_CurrentUniverseId_Uint64 = 2004, - Prop_PreviousUniverseId_Uint64 = 2005, - Prop_DisplayFirmwareVersion_Uint64 = 2006, - Prop_IsOnDesktop_Bool = 2007, - Prop_DisplayMCType_Int32 = 2008, - Prop_DisplayMCOffset_Float = 2009, - Prop_DisplayMCScale_Float = 2010, - Prop_EdidVendorID_Int32 = 2011, - Prop_DisplayMCImageLeft_String = 2012, - Prop_DisplayMCImageRight_String = 2013, - Prop_DisplayGCBlackClamp_Float = 2014, - Prop_EdidProductID_Int32 = 2015, - Prop_CameraToHeadTransform_Matrix34 = 2016, - Prop_DisplayGCType_Int32 = 2017, - Prop_DisplayGCOffset_Float = 2018, - Prop_DisplayGCScale_Float = 2019, - Prop_DisplayGCPrescale_Float = 2020, - Prop_DisplayGCImage_String = 2021, - Prop_LensCenterLeftU_Float = 2022, - Prop_LensCenterLeftV_Float = 2023, - Prop_LensCenterRightU_Float = 2024, - Prop_LensCenterRightV_Float = 2025, - Prop_UserHeadToEyeDepthMeters_Float = 2026, - Prop_CameraFirmwareVersion_Uint64 = 2027, - Prop_CameraFirmwareDescription_String = 2028, - Prop_DisplayFPGAVersion_Uint64 = 2029, - Prop_DisplayBootloaderVersion_Uint64 = 2030, - Prop_DisplayHardwareVersion_Uint64 = 2031, - Prop_AudioFirmwareVersion_Uint64 = 2032, - Prop_CameraCompatibilityMode_Int32 = 2033, + Prop_ReportsTimeSinceVSync_Bool = 2000, + Prop_SecondsFromVsyncToPhotons_Float = 2001, + Prop_DisplayFrequency_Float = 2002, + Prop_UserIpdMeters_Float = 2003, + Prop_CurrentUniverseId_Uint64 = 2004, + Prop_PreviousUniverseId_Uint64 = 2005, + Prop_DisplayFirmwareVersion_Uint64 = 2006, + Prop_IsOnDesktop_Bool = 2007, + Prop_DisplayMCType_Int32 = 2008, + Prop_DisplayMCOffset_Float = 2009, + Prop_DisplayMCScale_Float = 2010, + Prop_EdidVendorID_Int32 = 2011, + Prop_DisplayMCImageLeft_String = 2012, + Prop_DisplayMCImageRight_String = 2013, + Prop_DisplayGCBlackClamp_Float = 2014, + Prop_EdidProductID_Int32 = 2015, + Prop_CameraToHeadTransform_Matrix34 = 2016, + Prop_DisplayGCType_Int32 = 2017, + Prop_DisplayGCOffset_Float = 2018, + Prop_DisplayGCScale_Float = 2019, + Prop_DisplayGCPrescale_Float = 2020, + Prop_DisplayGCImage_String = 2021, + Prop_LensCenterLeftU_Float = 2022, + Prop_LensCenterLeftV_Float = 2023, + Prop_LensCenterRightU_Float = 2024, + Prop_LensCenterRightV_Float = 2025, + Prop_UserHeadToEyeDepthMeters_Float = 2026, + Prop_CameraFirmwareVersion_Uint64 = 2027, + Prop_CameraFirmwareDescription_String = 2028, + Prop_DisplayFPGAVersion_Uint64 = 2029, + Prop_DisplayBootloaderVersion_Uint64 = 2030, + Prop_DisplayHardwareVersion_Uint64 = 2031, + Prop_AudioFirmwareVersion_Uint64 = 2032, + Prop_CameraCompatibilityMode_Int32 = 2033, Prop_ScreenshotHorizontalFieldOfViewDegrees_Float = 2034, Prop_ScreenshotVerticalFieldOfViewDegrees_Float = 2035, - Prop_DisplaySuppressed_Bool = 2036, - Prop_DisplayAllowNightMode_Bool = 2037, - Prop_DisplayMCImageWidth_Int32 = 2038, - Prop_DisplayMCImageHeight_Int32 = 2039, - Prop_DisplayMCImageNumChannels_Int32 = 2040, - Prop_DisplayMCImageData_Binary = 2041, - Prop_SecondsFromPhotonsToVblank_Float = 2042, - Prop_DriverDirectModeSendsVsyncEvents_Bool = 2043, - Prop_DisplayDebugMode_Bool = 2044, - Prop_GraphicsAdapterLuid_Uint64 = 2045, - Prop_DriverProvidedChaperonePath_String = 2048, + Prop_DisplaySuppressed_Bool = 2036, + Prop_DisplayAllowNightMode_Bool = 2037, + Prop_DisplayMCImageWidth_Int32 = 2038, + Prop_DisplayMCImageHeight_Int32 = 2039, + Prop_DisplayMCImageNumChannels_Int32 = 2040, + Prop_DisplayMCImageData_Binary = 2041, + Prop_SecondsFromPhotonsToVblank_Float = 2042, + Prop_DriverDirectModeSendsVsyncEvents_Bool = 2043, + Prop_DisplayDebugMode_Bool = 2044, + Prop_GraphicsAdapterLuid_Uint64 = 2045, + Prop_DriverProvidedChaperonePath_String = 2048, // Properties that are unique to TrackedDeviceClass_Controller - Prop_AttachedDeviceId_String = 3000, - Prop_SupportedButtons_Uint64 = 3001, - Prop_Axis0Type_Int32 = 3002, // Return value is of type EVRControllerAxisType - Prop_Axis1Type_Int32 = 3003, // Return value is of type EVRControllerAxisType - Prop_Axis2Type_Int32 = 3004, // Return value is of type EVRControllerAxisType - Prop_Axis3Type_Int32 = 3005, // Return value is of type EVRControllerAxisType - Prop_Axis4Type_Int32 = 3006, // Return value is of type EVRControllerAxisType - Prop_ControllerRoleHint_Int32 = 3007, // Return value is of type ETrackedControllerRole + Prop_AttachedDeviceId_String = 3000, + Prop_SupportedButtons_Uint64 = 3001, + Prop_Axis0Type_Int32 = 3002, // Return value is of type EVRControllerAxisType + Prop_Axis1Type_Int32 = 3003, // Return value is of type EVRControllerAxisType + Prop_Axis2Type_Int32 = 3004, // Return value is of type EVRControllerAxisType + Prop_Axis3Type_Int32 = 3005, // Return value is of type EVRControllerAxisType + Prop_Axis4Type_Int32 = 3006, // Return value is of type EVRControllerAxisType + Prop_ControllerRoleHint_Int32 = 3007, // Return value is of type ETrackedControllerRole // Properties that are unique to TrackedDeviceClass_TrackingReference - Prop_FieldOfViewLeftDegrees_Float = 4000, - Prop_FieldOfViewRightDegrees_Float = 4001, - Prop_FieldOfViewTopDegrees_Float = 4002, - Prop_FieldOfViewBottomDegrees_Float = 4003, - Prop_TrackingRangeMinimumMeters_Float = 4004, - Prop_TrackingRangeMaximumMeters_Float = 4005, - Prop_ModeLabel_String = 4006, + Prop_FieldOfViewLeftDegrees_Float = 4000, + Prop_FieldOfViewRightDegrees_Float = 4001, + Prop_FieldOfViewTopDegrees_Float = 4002, + Prop_FieldOfViewBottomDegrees_Float = 4003, + Prop_TrackingRangeMinimumMeters_Float = 4004, + Prop_TrackingRangeMaximumMeters_Float = 4005, + Prop_ModeLabel_String = 4006, // Properties that are used for user interface like icons names - Prop_IconPathName_String = 5000, // DEPRECATED. Value not referenced. Now expected to be part of icon path properties. - Prop_NamedIconPathDeviceOff_String = 5001, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceSearching_String = 5002, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceSearchingAlert_String = 5003, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceReady_String = 5004, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceReadyAlert_String = 5005, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceNotReady_String = 5006, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceStandby_String = 5007, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceAlertLow_String = 5008, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_IconPathName_String = 5000, // DEPRECATED. Value not referenced. Now expected to be part of icon path properties. + Prop_NamedIconPathDeviceOff_String = 5001, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceSearching_String = 5002, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceSearchingAlert_String = 5003, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceReady_String = 5004, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceReadyAlert_String = 5005, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceNotReady_String = 5006, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceStandby_String = 5007, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceAlertLow_String = 5008, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others // Properties that are used by helpers, but are opaque to applications - Prop_DisplayHiddenArea_Binary_Start = 5100, - Prop_DisplayHiddenArea_Binary_End = 5150, + Prop_DisplayHiddenArea_Binary_Start = 5100, + Prop_DisplayHiddenArea_Binary_End = 5150, // Properties that are unique to drivers - Prop_UserConfigPath_String = 6000, - Prop_InstallPath_String = 6001, - Prop_HasDisplayComponent_Bool = 6002, - Prop_HasControllerComponent_Bool = 6003, - Prop_HasCameraComponent_Bool = 6004, - Prop_HasDriverDirectModeComponent_Bool = 6005, - Prop_HasVirtualDisplayComponent_Bool = 6006, + Prop_UserConfigPath_String = 6000, + Prop_InstallPath_String = 6001, + Prop_HasDisplayComponent_Bool = 6002, + Prop_HasControllerComponent_Bool = 6003, + Prop_HasCameraComponent_Bool = 6004, + Prop_HasDriverDirectModeComponent_Bool = 6005, + Prop_HasVirtualDisplayComponent_Bool = 6006, // Vendors are free to expose private debug data in this reserved region - Prop_VendorSpecific_Reserved_Start = 10000, - Prop_VendorSpecific_Reserved_End = 10999, + Prop_VendorSpecific_Reserved_Start = 10000, + Prop_VendorSpecific_Reserved_End = 10999, }; /** No string property will ever be longer than this length */ @@ -371,18 +366,18 @@ static const uint32_t k_unMaxPropertyStringSize = 32 * 1024; /** Used to return errors that occur when reading properties. */ enum ETrackedPropertyError { - TrackedProp_Success = 0, - TrackedProp_WrongDataType = 1, - TrackedProp_WrongDeviceClass = 2, - TrackedProp_BufferTooSmall = 3, - TrackedProp_UnknownProperty = 4, // Driver has not set the property (and may not ever). - TrackedProp_InvalidDevice = 5, - TrackedProp_CouldNotContactServer = 6, - TrackedProp_ValueNotProvidedByDevice = 7, - TrackedProp_StringExceedsMaximumLength = 8, - TrackedProp_NotYetAvailable = 9, // The property value isn't known yet, but is expected soon. Call again later. - TrackedProp_PermissionDenied = 10, - TrackedProp_InvalidOperation = 11, + TrackedProp_Success = 0, + TrackedProp_WrongDataType = 1, + TrackedProp_WrongDeviceClass = 2, + TrackedProp_BufferTooSmall = 3, + TrackedProp_UnknownProperty = 4, // Driver has not set the property (and may not ever). + TrackedProp_InvalidDevice = 5, + TrackedProp_CouldNotContactServer = 6, + TrackedProp_ValueNotProvidedByDevice = 7, + TrackedProp_StringExceedsMaximumLength = 8, + TrackedProp_NotYetAvailable = 9, // The property value isn't known yet, but is expected soon. Call again later. + TrackedProp_PermissionDenied = 10, + TrackedProp_InvalidOperation = 11, }; /** Allows the application to control what part of the provided texture will be used in the @@ -396,7 +391,7 @@ struct VRTextureBounds_t /** Allows specifying pose used to render provided scene texture (if different from value returned by WaitGetPoses). */ struct VRTextureWithPose_t : public Texture_t { - HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures. + HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures. }; /** Allows the application to control how scene textures are used by the compositor when calling Submit. */ @@ -424,7 +419,7 @@ enum EVRSubmitFlags * Be sure to call OpenVR_Shutdown before destroying these resources. */ struct VRVulkanTextureData_t { - uint64_t m_nImage; // VkImage + uint64_t m_nImage; // VkImage VkDevice_T *m_pDevice; VkPhysicalDevice_T *m_pPhysicalDevice; VkInstance_T *m_pInstance; @@ -461,220 +456,216 @@ enum EVREventType { VREvent_None = 0, - VREvent_TrackedDeviceActivated = 100, - VREvent_TrackedDeviceDeactivated = 101, - VREvent_TrackedDeviceUpdated = 102, - VREvent_TrackedDeviceUserInteractionStarted = 103, - VREvent_TrackedDeviceUserInteractionEnded = 104, - VREvent_IpdChanged = 105, - VREvent_EnterStandbyMode = 106, - VREvent_LeaveStandbyMode = 107, - VREvent_TrackedDeviceRoleChanged = 108, - VREvent_WatchdogWakeUpRequested = 109, - VREvent_LensDistortionChanged = 110, - VREvent_PropertyChanged = 111, - VREvent_WirelessDisconnect = 112, - VREvent_WirelessReconnect = 113, + VREvent_TrackedDeviceActivated = 100, + VREvent_TrackedDeviceDeactivated = 101, + VREvent_TrackedDeviceUpdated = 102, + VREvent_TrackedDeviceUserInteractionStarted = 103, + VREvent_TrackedDeviceUserInteractionEnded = 104, + VREvent_IpdChanged = 105, + VREvent_EnterStandbyMode = 106, + VREvent_LeaveStandbyMode = 107, + VREvent_TrackedDeviceRoleChanged = 108, + VREvent_WatchdogWakeUpRequested = 109, + VREvent_LensDistortionChanged = 110, + VREvent_PropertyChanged = 111, + VREvent_WirelessDisconnect = 112, + VREvent_WirelessReconnect = 113, - VREvent_ButtonPress = 200, // data is controller - VREvent_ButtonUnpress = 201, // data is controller - VREvent_ButtonTouch = 202, // data is controller - VREvent_ButtonUntouch = 203, // data is controller + VREvent_ButtonPress = 200, // data is controller + VREvent_ButtonUnpress = 201, // data is controller + VREvent_ButtonTouch = 202, // data is controller + VREvent_ButtonUntouch = 203, // data is controller - VREvent_MouseMove = 300, // data is mouse - VREvent_MouseButtonDown = 301, // data is mouse - VREvent_MouseButtonUp = 302, // data is mouse - VREvent_FocusEnter = 303, // data is overlay - VREvent_FocusLeave = 304, // data is overlay - VREvent_Scroll = 305, // data is mouse - VREvent_TouchPadMove = 306, // data is mouse - VREvent_OverlayFocusChanged = 307, // data is overlay, global event + VREvent_MouseMove = 300, // data is mouse + VREvent_MouseButtonDown = 301, // data is mouse + VREvent_MouseButtonUp = 302, // data is mouse + VREvent_FocusEnter = 303, // data is overlay + VREvent_FocusLeave = 304, // data is overlay + VREvent_Scroll = 305, // data is mouse + VREvent_TouchPadMove = 306, // data is mouse + VREvent_OverlayFocusChanged = 307, // data is overlay, global event - VREvent_InputFocusCaptured = 400, // data is process DEPRECATED - VREvent_InputFocusReleased = 401, // data is process DEPRECATED - VREvent_SceneFocusLost = 402, // data is process - VREvent_SceneFocusGained = 403, // data is process - VREvent_SceneApplicationChanged = 404, // data is process - The App actually drawing the scene changed (usually to or from the compositor) - VREvent_SceneFocusChanged = 405, // data is process - New app got access to draw the scene - VREvent_InputFocusChanged = 406, // data is process - VREvent_SceneApplicationSecondaryRenderingStarted = 407, // data is process + VREvent_InputFocusCaptured = 400, // data is process DEPRECATED + VREvent_InputFocusReleased = 401, // data is process DEPRECATED + VREvent_SceneFocusLost = 402, // data is process + VREvent_SceneFocusGained = 403, // data is process + VREvent_SceneApplicationChanged = 404, // data is process - The App actually drawing the scene changed (usually to or from the compositor) + VREvent_SceneFocusChanged = 405, // data is process - New app got access to draw the scene + VREvent_InputFocusChanged = 406, // data is process + VREvent_SceneApplicationSecondaryRenderingStarted = 407, // data is process - VREvent_HideRenderModels = 410, // Sent to the scene application to request hiding render models temporarily - VREvent_ShowRenderModels = 411, // Sent to the scene application to request restoring render model visibility + VREvent_HideRenderModels = 410, // Sent to the scene application to request hiding render models temporarily + VREvent_ShowRenderModels = 411, // Sent to the scene application to request restoring render model visibility - VREvent_OverlayShown = 500, - VREvent_OverlayHidden = 501, - VREvent_DashboardActivated = 502, - VREvent_DashboardDeactivated = 503, - VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay - VREvent_DashboardRequested = 505, // Sent to the overlay manager - data is overlay - VREvent_ResetDashboard = 506, // Send to the overlay manager - VREvent_RenderToast = 507, // Send to the dashboard to render a toast - data is the notification ID - VREvent_ImageLoaded = 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading - VREvent_ShowKeyboard = 509, // Sent to keyboard renderer in the dashboard to invoke it - VREvent_HideKeyboard = 510, // Sent to keyboard renderer in the dashboard to hide it - VREvent_OverlayGamepadFocusGained = 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it - VREvent_OverlayGamepadFocusLost = 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else + VREvent_OverlayShown = 500, + VREvent_OverlayHidden = 501, + VREvent_DashboardActivated = 502, + VREvent_DashboardDeactivated = 503, + VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay + VREvent_DashboardRequested = 505, // Sent to the overlay manager - data is overlay + VREvent_ResetDashboard = 506, // Send to the overlay manager + VREvent_RenderToast = 507, // Send to the dashboard to render a toast - data is the notification ID + VREvent_ImageLoaded = 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading + VREvent_ShowKeyboard = 509, // Sent to keyboard renderer in the dashboard to invoke it + VREvent_HideKeyboard = 510, // Sent to keyboard renderer in the dashboard to hide it + VREvent_OverlayGamepadFocusGained = 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it + VREvent_OverlayGamepadFocusLost = 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else VREvent_OverlaySharedTextureChanged = 513, - VREvent_DashboardGuideButtonDown = 514, - VREvent_DashboardGuideButtonUp = 515, - VREvent_ScreenshotTriggered = 516, // Screenshot button combo was pressed, Dashboard should request a screenshot - VREvent_ImageFailed = 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load - VREvent_DashboardOverlayCreated = 518, + VREvent_DashboardGuideButtonDown = 514, + VREvent_DashboardGuideButtonUp = 515, + VREvent_ScreenshotTriggered = 516, // Screenshot button combo was pressed, Dashboard should request a screenshot + VREvent_ImageFailed = 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load + VREvent_DashboardOverlayCreated = 518, // Screenshot API - VREvent_RequestScreenshot = 520, // Sent by vrclient application to compositor to take a screenshot - VREvent_ScreenshotTaken = 521, // Sent by compositor to the application that the screenshot has been taken - VREvent_ScreenshotFailed = 522, // Sent by compositor to the application that the screenshot failed to be taken - VREvent_SubmitScreenshotToDashboard = 523, // Sent by compositor to the dashboard that a completed screenshot was submitted - VREvent_ScreenshotProgressToDashboard = 524, // Sent by compositor to the dashboard that a completed screenshot was submitted + VREvent_RequestScreenshot = 520, // Sent by vrclient application to compositor to take a screenshot + VREvent_ScreenshotTaken = 521, // Sent by compositor to the application that the screenshot has been taken + VREvent_ScreenshotFailed = 522, // Sent by compositor to the application that the screenshot failed to be taken + VREvent_SubmitScreenshotToDashboard = 523, // Sent by compositor to the dashboard that a completed screenshot was submitted + VREvent_ScreenshotProgressToDashboard = 524, // Sent by compositor to the dashboard that a completed screenshot was submitted - VREvent_PrimaryDashboardDeviceChanged = 525, + VREvent_PrimaryDashboardDeviceChanged = 525, - VREvent_Notification_Shown = 600, - VREvent_Notification_Hidden = 601, - VREvent_Notification_BeginInteraction = 602, - VREvent_Notification_Destroyed = 603, + VREvent_Notification_Shown = 600, + VREvent_Notification_Hidden = 601, + VREvent_Notification_BeginInteraction = 602, + VREvent_Notification_Destroyed = 603, - VREvent_Quit = 700, // data is process - VREvent_ProcessQuit = 701, // data is process - VREvent_QuitAborted_UserPrompt = 702, // data is process - VREvent_QuitAcknowledged = 703, // data is process - VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down + VREvent_Quit = 700, // data is process + VREvent_ProcessQuit = 701, // data is process + VREvent_QuitAborted_UserPrompt = 702, // data is process + VREvent_QuitAcknowledged = 703, // data is process + VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down - VREvent_ChaperoneDataHasChanged = 800, - VREvent_ChaperoneUniverseHasChanged = 801, - VREvent_ChaperoneTempDataHasChanged = 802, - VREvent_ChaperoneSettingsHaveChanged = 803, - VREvent_SeatedZeroPoseReset = 804, + VREvent_ChaperoneDataHasChanged = 800, + VREvent_ChaperoneUniverseHasChanged = 801, + VREvent_ChaperoneTempDataHasChanged = 802, + VREvent_ChaperoneSettingsHaveChanged = 803, + VREvent_SeatedZeroPoseReset = 804, - VREvent_AudioSettingsHaveChanged = 820, + VREvent_AudioSettingsHaveChanged = 820, - VREvent_BackgroundSettingHasChanged = 850, - VREvent_CameraSettingsHaveChanged = 851, - VREvent_ReprojectionSettingHasChanged = 852, - VREvent_ModelSkinSettingsHaveChanged = 853, - VREvent_EnvironmentSettingsHaveChanged = 854, - VREvent_PowerSettingsHaveChanged = 855, + VREvent_BackgroundSettingHasChanged = 850, + VREvent_CameraSettingsHaveChanged = 851, + VREvent_ReprojectionSettingHasChanged = 852, + VREvent_ModelSkinSettingsHaveChanged = 853, + VREvent_EnvironmentSettingsHaveChanged = 854, + VREvent_PowerSettingsHaveChanged = 855, VREvent_EnableHomeAppSettingsHaveChanged = 856, - VREvent_StatusUpdate = 900, + VREvent_StatusUpdate = 900, - VREvent_MCImageUpdated = 1000, + VREvent_MCImageUpdated = 1000, - VREvent_FirmwareUpdateStarted = 1100, - VREvent_FirmwareUpdateFinished = 1101, + VREvent_FirmwareUpdateStarted = 1100, + VREvent_FirmwareUpdateFinished = 1101, - VREvent_KeyboardClosed = 1200, - VREvent_KeyboardCharInput = 1201, - VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard + VREvent_KeyboardClosed = 1200, + VREvent_KeyboardCharInput = 1201, + VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard - VREvent_ApplicationTransitionStarted = 1300, - VREvent_ApplicationTransitionAborted = 1301, - VREvent_ApplicationTransitionNewAppStarted = 1302, - VREvent_ApplicationListUpdated = 1303, - VREvent_ApplicationMimeTypeLoad = 1304, + VREvent_ApplicationTransitionStarted = 1300, + VREvent_ApplicationTransitionAborted = 1301, + VREvent_ApplicationTransitionNewAppStarted = 1302, + VREvent_ApplicationListUpdated = 1303, + VREvent_ApplicationMimeTypeLoad = 1304, VREvent_ApplicationTransitionNewAppLaunchComplete = 1305, - VREvent_ProcessConnected = 1306, - VREvent_ProcessDisconnected = 1307, + VREvent_ProcessConnected = 1306, + VREvent_ProcessDisconnected = 1307, - VREvent_Compositor_MirrorWindowShown = 1400, - VREvent_Compositor_MirrorWindowHidden = 1401, - VREvent_Compositor_ChaperoneBoundsShown = 1410, - VREvent_Compositor_ChaperoneBoundsHidden = 1411, + VREvent_Compositor_MirrorWindowShown = 1400, + VREvent_Compositor_MirrorWindowHidden = 1401, + VREvent_Compositor_ChaperoneBoundsShown = 1410, + VREvent_Compositor_ChaperoneBoundsHidden = 1411, - VREvent_TrackedCamera_StartVideoStream = 1500, - VREvent_TrackedCamera_StopVideoStream = 1501, - VREvent_TrackedCamera_PauseVideoStream = 1502, + VREvent_TrackedCamera_StartVideoStream = 1500, + VREvent_TrackedCamera_StopVideoStream = 1501, + VREvent_TrackedCamera_PauseVideoStream = 1502, VREvent_TrackedCamera_ResumeVideoStream = 1503, - VREvent_TrackedCamera_EditingSurface = 1550, + VREvent_TrackedCamera_EditingSurface = 1550, - VREvent_PerformanceTest_EnableCapture = 1600, - VREvent_PerformanceTest_DisableCapture = 1601, - VREvent_PerformanceTest_FidelityLevel = 1602, + VREvent_PerformanceTest_EnableCapture = 1600, + VREvent_PerformanceTest_DisableCapture = 1601, + VREvent_PerformanceTest_FidelityLevel = 1602, + + VREvent_MessageOverlay_Closed = 1650, + VREvent_MessageOverlayCloseRequested = 1651, - VREvent_MessageOverlay_Closed = 1650, - VREvent_MessageOverlayCloseRequested = 1651, - // Vendors are free to expose private events in this reserved region - VREvent_VendorSpecific_Reserved_Start = 10000, - VREvent_VendorSpecific_Reserved_End = 19999, + VREvent_VendorSpecific_Reserved_Start = 10000, + VREvent_VendorSpecific_Reserved_End = 19999, }; - /** Level of Hmd activity */ // UserInteraction_Timeout means the device is in the process of timing out. // InUse = ( k_EDeviceActivityLevel_UserInteraction || k_EDeviceActivityLevel_UserInteraction_Timeout ) // VREvent_TrackedDeviceUserInteractionStarted fires when the devices transitions from Standby -> UserInteraction or Idle -> UserInteraction. // VREvent_TrackedDeviceUserInteractionEnded fires when the devices transitions from UserInteraction_Timeout -> Idle enum EDeviceActivityLevel -{ - k_EDeviceActivityLevel_Unknown = -1, - k_EDeviceActivityLevel_Idle = 0, // No activity for the last 10 seconds - k_EDeviceActivityLevel_UserInteraction = 1, // Activity (movement or prox sensor) is happening now - k_EDeviceActivityLevel_UserInteraction_Timeout = 2, // No activity for the last 0.5 seconds - k_EDeviceActivityLevel_Standby = 3, // Idle for at least 5 seconds (configurable in Settings -> Power Management) +{ + k_EDeviceActivityLevel_Unknown = -1, + k_EDeviceActivityLevel_Idle = 0, // No activity for the last 10 seconds + k_EDeviceActivityLevel_UserInteraction = 1, // Activity (movement or prox sensor) is happening now + k_EDeviceActivityLevel_UserInteraction_Timeout = 2, // No activity for the last 0.5 seconds + k_EDeviceActivityLevel_Standby = 3, // Idle for at least 5 seconds (configurable in Settings -> Power Management) }; - /** VR controller button and axis IDs */ enum EVRButtonId { - k_EButton_System = 0, - k_EButton_ApplicationMenu = 1, - k_EButton_Grip = 2, - k_EButton_DPad_Left = 3, - k_EButton_DPad_Up = 4, - k_EButton_DPad_Right = 5, - k_EButton_DPad_Down = 6, - k_EButton_A = 7, - - k_EButton_ProximitySensor = 31, + k_EButton_System = 0, + k_EButton_ApplicationMenu = 1, + k_EButton_Grip = 2, + k_EButton_DPad_Left = 3, + k_EButton_DPad_Up = 4, + k_EButton_DPad_Right = 5, + k_EButton_DPad_Down = 6, + k_EButton_A = 7, - k_EButton_Axis0 = 32, - k_EButton_Axis1 = 33, - k_EButton_Axis2 = 34, - k_EButton_Axis3 = 35, - k_EButton_Axis4 = 36, + k_EButton_ProximitySensor = 31, + + k_EButton_Axis0 = 32, + k_EButton_Axis1 = 33, + k_EButton_Axis2 = 34, + k_EButton_Axis3 = 35, + k_EButton_Axis4 = 36, // aliases for well known controllers - k_EButton_SteamVR_Touchpad = k_EButton_Axis0, - k_EButton_SteamVR_Trigger = k_EButton_Axis1, + k_EButton_SteamVR_Touchpad = k_EButton_Axis0, + k_EButton_SteamVR_Trigger = k_EButton_Axis1, - k_EButton_Dashboard_Back = k_EButton_Grip, + k_EButton_Dashboard_Back = k_EButton_Grip, - k_EButton_Max = 64 + k_EButton_Max = 64 }; -inline uint64_t ButtonMaskFromId( EVRButtonId id ) { return 1ull << id; } +inline uint64_t ButtonMaskFromId(EVRButtonId id) { return 1ull << id; } /** used for controller button events */ struct VREvent_Controller_t { - uint32_t button; // EVRButtonId enum + uint32_t button; // EVRButtonId enum }; - /** used for simulated mouse events in overlay space */ enum EVRMouseButton { - VRMouseButton_Left = 0x0001, - VRMouseButton_Right = 0x0002, - VRMouseButton_Middle = 0x0004, + VRMouseButton_Left = 0x0001, + VRMouseButton_Right = 0x0002, + VRMouseButton_Middle = 0x0004, }; - /** used for simulated mouse events in overlay space */ struct VREvent_Mouse_t { - float x, y; // co-ords are in GL space, bottom left of the texture is 0,0 - uint32_t button; // EVRMouseButton enum + float x, y; // co-ords are in GL space, bottom left of the texture is 0,0 + uint32_t button; // EVRMouseButton enum }; /** used for simulated mouse wheel scroll in overlay space */ struct VREvent_Scroll_t { - float xdelta, ydelta; // movement in fraction of the pad traversed since last delta, 1.0 for a full swipe + float xdelta, ydelta; // movement in fraction of the pad traversed since last delta, 1.0 for a full swipe uint32_t repeatCount; }; @@ -713,25 +704,23 @@ struct VREvent_Process_t bool bForced; }; - /** Used for a few events about overlays */ struct VREvent_Overlay_t { uint64_t overlayHandle; }; - /** Used for a few events about overlays */ struct VREvent_Status_t { - uint32_t statusState; // EVRState enum + uint32_t statusState; // EVRState enum }; /** Used for keyboard events **/ struct VREvent_Keyboard_t { - char cNewInput[8]; // Up to 11 bytes of new input - uint64_t uUserValue; // Possible flags about the new input + char cNewInput[8]; // Up to 11 bytes of new input + uint64_t uUserValue; // Possible flags about the new input }; struct VREvent_Ipd_t @@ -787,7 +776,7 @@ struct VREvent_EditingCameraSurface_t struct VREvent_MessageOverlay_t { - uint32_t unVRMessageOverlayResponse; // vr::VRMessageOverlayResponse enum + uint32_t unVRMessageOverlayResponse; // vr::VRMessageOverlayResponse enum }; struct VREvent_Property_t @@ -797,8 +786,7 @@ struct VREvent_Property_t }; /** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py */ -typedef union -{ +typedef union { VREvent_Reserved_t reserved; VREvent_Controller_t controller; VREvent_Mouse_t mouse; @@ -821,25 +809,24 @@ typedef union VREvent_Property_t property; } VREvent_Data_t; - -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif /** An event posted by the server to all running applications */ struct VREvent_t { - uint32_t eventType; // EVREventType enum + uint32_t eventType; // EVREventType enum TrackedDeviceIndex_t trackedDeviceIndex; float eventAgeSeconds; // event data must be the end of the struct as its size is variable VREvent_Data_t data; }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif /** The mesh to draw into the stencil (or depth) buffer to perform @@ -854,7 +841,6 @@ struct HiddenAreaMesh_t uint32_t unTriangleCount; }; - enum EHiddenAreaMeshType { k_eHiddenAreaMesh_Standard = 0, @@ -864,7 +850,6 @@ enum EHiddenAreaMeshType k_eHiddenAreaMesh_Max = 3, }; - /** Identifies what kind of axis is on the controller at index n. Read this type * with pVRSystem->Get( nControllerDeviceIndex, Prop_Axis0Type_Int32 + n ); */ @@ -873,32 +858,29 @@ enum EVRControllerAxisType k_eControllerAxis_None = 0, k_eControllerAxis_TrackPad = 1, k_eControllerAxis_Joystick = 2, - k_eControllerAxis_Trigger = 3, // Analog trigger data is in the X axis + k_eControllerAxis_Trigger = 3, // Analog trigger data is in the X axis }; - /** contains information about one axis on the controller */ struct VRControllerAxis_t { - float x; // Ranges from -1.0 to 1.0 for joysticks and track pads. Ranges from 0.0 to 1.0 for triggers were 0 is fully released. - float y; // Ranges from -1.0 to 1.0 for joysticks and track pads. Is always 0.0 for triggers. + float x; // Ranges from -1.0 to 1.0 for joysticks and track pads. Ranges from 0.0 to 1.0 for triggers were 0 is fully released. + float y; // Ranges from -1.0 to 1.0 for joysticks and track pads. Is always 0.0 for triggers. }; - /** the number of axes in the controller state */ static const uint32_t k_unControllerStateAxisCount = 5; - -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif /** Holds all the state of a controller at one moment in time. */ struct VRControllerState001_t { - // If packet num matches that on your prior call, then the controller state hasn't been changed since + // If packet num matches that on your prior call, then the controller state hasn't been changed since // your last call and there is no need to process it uint32_t unPacketNum; @@ -907,16 +889,14 @@ struct VRControllerState001_t uint64_t ulButtonTouched; // Axis data for the controller's analog inputs - VRControllerAxis_t rAxis[ k_unControllerStateAxisCount ]; + VRControllerAxis_t rAxis[k_unControllerStateAxisCount]; }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif - typedef VRControllerState001_t VRControllerState_t; - /** determines how to provide output to the application of various event processing functions. */ enum EVRControllerEventOutputType { @@ -924,8 +904,6 @@ enum EVRControllerEventOutputType ControllerEventOutput_VREvents = 1, }; - - /** Collision Bounds Style */ enum ECollisionBoundsStyle { @@ -941,7 +919,7 @@ enum ECollisionBoundsStyle /** Allows the application to customize how the overlay appears in the compositor */ struct Compositor_OverlaySettings { - uint32_t size; // sizeof(Compositor_OverlaySettings) + uint32_t size; // sizeof(Compositor_OverlaySettings) bool curved, antialias; float scale, distance, alpha; float uOffset, vOffset, uScale, vScale; @@ -957,49 +935,48 @@ static const VROverlayHandle_t k_ulOverlayHandleInvalid = 0; /** Errors that can occur around VR overlays */ enum EVROverlayError { - VROverlayError_None = 0, + VROverlayError_None = 0, - VROverlayError_UnknownOverlay = 10, - VROverlayError_InvalidHandle = 11, - VROverlayError_PermissionDenied = 12, - VROverlayError_OverlayLimitExceeded = 13, // No more overlays could be created because the maximum number already exist - VROverlayError_WrongVisibilityType = 14, - VROverlayError_KeyTooLong = 15, - VROverlayError_NameTooLong = 16, - VROverlayError_KeyInUse = 17, - VROverlayError_WrongTransformType = 18, - VROverlayError_InvalidTrackedDevice = 19, - VROverlayError_InvalidParameter = 20, - VROverlayError_ThumbnailCantBeDestroyed = 21, - VROverlayError_ArrayTooSmall = 22, - VROverlayError_RequestFailed = 23, - VROverlayError_InvalidTexture = 24, - VROverlayError_UnableToLoadFile = 25, - VROverlayError_KeyboardAlreadyInUse = 26, - VROverlayError_NoNeighbor = 27, - VROverlayError_TooManyMaskPrimitives = 29, - VROverlayError_BadMaskPrimitive = 30, + VROverlayError_UnknownOverlay = 10, + VROverlayError_InvalidHandle = 11, + VROverlayError_PermissionDenied = 12, + VROverlayError_OverlayLimitExceeded = 13, // No more overlays could be created because the maximum number already exist + VROverlayError_WrongVisibilityType = 14, + VROverlayError_KeyTooLong = 15, + VROverlayError_NameTooLong = 16, + VROverlayError_KeyInUse = 17, + VROverlayError_WrongTransformType = 18, + VROverlayError_InvalidTrackedDevice = 19, + VROverlayError_InvalidParameter = 20, + VROverlayError_ThumbnailCantBeDestroyed = 21, + VROverlayError_ArrayTooSmall = 22, + VROverlayError_RequestFailed = 23, + VROverlayError_InvalidTexture = 24, + VROverlayError_UnableToLoadFile = 25, + VROverlayError_KeyboardAlreadyInUse = 26, + VROverlayError_NoNeighbor = 27, + VROverlayError_TooManyMaskPrimitives = 29, + VROverlayError_BadMaskPrimitive = 30, }; /** enum values to pass in to VR_Init to identify whether the application will * draw a 3D scene. */ enum EVRApplicationType { - VRApplication_Other = 0, // Some other kind of application that isn't covered by the other entries - VRApplication_Scene = 1, // Application will submit 3D frames - VRApplication_Overlay = 2, // Application only interacts with overlays - VRApplication_Background = 3, // Application should not start SteamVR if it's not already running, and should not - // keep it running if everything else quits. - VRApplication_Utility = 4, // Init should not try to load any drivers. The application needs access to utility - // interfaces (like IVRSettings and IVRApplications) but not hardware. - VRApplication_VRMonitor = 5, // Reserved for vrmonitor - VRApplication_SteamWatchdog = 6,// Reserved for Steam - VRApplication_Bootstrapper = 7, // Start up SteamVR + VRApplication_Other = 0, // Some other kind of application that isn't covered by the other entries + VRApplication_Scene = 1, // Application will submit 3D frames + VRApplication_Overlay = 2, // Application only interacts with overlays + VRApplication_Background = 3, // Application should not start SteamVR if it's not already running, and should not + // keep it running if everything else quits. + VRApplication_Utility = 4, // Init should not try to load any drivers. The application needs access to utility + // interfaces (like IVRSettings and IVRApplications) but not hardware. + VRApplication_VRMonitor = 5, // Reserved for vrmonitor + VRApplication_SteamWatchdog = 6, // Reserved for Steam + VRApplication_Bootstrapper = 7, // Start up SteamVR VRApplication_Max }; - /** error codes for firmware */ enum EVRFirmwareError { @@ -1008,7 +985,6 @@ enum EVRFirmwareError VRFirmwareError_Fail = 2, }; - /** error codes for notifications */ enum EVRNotificationError { @@ -1019,103 +995,101 @@ enum EVRNotificationError VRNotificationError_SystemWithUserValueAlreadyExists = 103, }; - /** error codes returned by Vr_Init */ // Please add adequate error description to https://developer.valvesoftware.com/w/index.php?title=Category:SteamVRHelp enum EVRInitError { - VRInitError_None = 0, + VRInitError_None = 0, VRInitError_Unknown = 1, - VRInitError_Init_InstallationNotFound = 100, - VRInitError_Init_InstallationCorrupt = 101, - VRInitError_Init_VRClientDLLNotFound = 102, - VRInitError_Init_FileNotFound = 103, - VRInitError_Init_FactoryNotFound = 104, - VRInitError_Init_InterfaceNotFound = 105, - VRInitError_Init_InvalidInterface = 106, - VRInitError_Init_UserConfigDirectoryInvalid = 107, - VRInitError_Init_HmdNotFound = 108, - VRInitError_Init_NotInitialized = 109, - VRInitError_Init_PathRegistryNotFound = 110, - VRInitError_Init_NoConfigPath = 111, - VRInitError_Init_NoLogPath = 112, - VRInitError_Init_PathRegistryNotWritable = 113, - VRInitError_Init_AppInfoInitFailed = 114, - VRInitError_Init_Retry = 115, // Used internally to cause retries to vrserver - VRInitError_Init_InitCanceledByUser = 116, // The calling application should silently exit. The user canceled app startup - VRInitError_Init_AnotherAppLaunching = 117, - VRInitError_Init_SettingsInitFailed = 118, - VRInitError_Init_ShuttingDown = 119, - VRInitError_Init_TooManyObjects = 120, - VRInitError_Init_NoServerForBackgroundApp = 121, - VRInitError_Init_NotSupportedWithCompositor = 122, - VRInitError_Init_NotAvailableToUtilityApps = 123, - VRInitError_Init_Internal = 124, - VRInitError_Init_HmdDriverIdIsNone = 125, - VRInitError_Init_HmdNotFoundPresenceFailed = 126, - VRInitError_Init_VRMonitorNotFound = 127, - VRInitError_Init_VRMonitorStartupFailed = 128, - VRInitError_Init_LowPowerWatchdogNotSupported = 129, - VRInitError_Init_InvalidApplicationType = 130, - VRInitError_Init_NotAvailableToWatchdogApps = 131, - VRInitError_Init_WatchdogDisabledInSettings = 132, - VRInitError_Init_VRDashboardNotFound = 133, - VRInitError_Init_VRDashboardStartupFailed = 134, - VRInitError_Init_VRHomeNotFound = 135, - VRInitError_Init_VRHomeStartupFailed = 136, - VRInitError_Init_RebootingBusy = 137, - VRInitError_Init_FirmwareUpdateBusy = 138, - VRInitError_Init_FirmwareRecoveryBusy = 139, + VRInitError_Init_InstallationNotFound = 100, + VRInitError_Init_InstallationCorrupt = 101, + VRInitError_Init_VRClientDLLNotFound = 102, + VRInitError_Init_FileNotFound = 103, + VRInitError_Init_FactoryNotFound = 104, + VRInitError_Init_InterfaceNotFound = 105, + VRInitError_Init_InvalidInterface = 106, + VRInitError_Init_UserConfigDirectoryInvalid = 107, + VRInitError_Init_HmdNotFound = 108, + VRInitError_Init_NotInitialized = 109, + VRInitError_Init_PathRegistryNotFound = 110, + VRInitError_Init_NoConfigPath = 111, + VRInitError_Init_NoLogPath = 112, + VRInitError_Init_PathRegistryNotWritable = 113, + VRInitError_Init_AppInfoInitFailed = 114, + VRInitError_Init_Retry = 115, // Used internally to cause retries to vrserver + VRInitError_Init_InitCanceledByUser = 116, // The calling application should silently exit. The user canceled app startup + VRInitError_Init_AnotherAppLaunching = 117, + VRInitError_Init_SettingsInitFailed = 118, + VRInitError_Init_ShuttingDown = 119, + VRInitError_Init_TooManyObjects = 120, + VRInitError_Init_NoServerForBackgroundApp = 121, + VRInitError_Init_NotSupportedWithCompositor = 122, + VRInitError_Init_NotAvailableToUtilityApps = 123, + VRInitError_Init_Internal = 124, + VRInitError_Init_HmdDriverIdIsNone = 125, + VRInitError_Init_HmdNotFoundPresenceFailed = 126, + VRInitError_Init_VRMonitorNotFound = 127, + VRInitError_Init_VRMonitorStartupFailed = 128, + VRInitError_Init_LowPowerWatchdogNotSupported = 129, + VRInitError_Init_InvalidApplicationType = 130, + VRInitError_Init_NotAvailableToWatchdogApps = 131, + VRInitError_Init_WatchdogDisabledInSettings = 132, + VRInitError_Init_VRDashboardNotFound = 133, + VRInitError_Init_VRDashboardStartupFailed = 134, + VRInitError_Init_VRHomeNotFound = 135, + VRInitError_Init_VRHomeStartupFailed = 136, + VRInitError_Init_RebootingBusy = 137, + VRInitError_Init_FirmwareUpdateBusy = 138, + VRInitError_Init_FirmwareRecoveryBusy = 139, - - VRInitError_Driver_Failed = 200, - VRInitError_Driver_Unknown = 201, - VRInitError_Driver_HmdUnknown = 202, - VRInitError_Driver_NotLoaded = 203, - VRInitError_Driver_RuntimeOutOfDate = 204, - VRInitError_Driver_HmdInUse = 205, - VRInitError_Driver_NotCalibrated = 206, - VRInitError_Driver_CalibrationInvalid = 207, - VRInitError_Driver_HmdDisplayNotFound = 208, + VRInitError_Driver_Failed = 200, + VRInitError_Driver_Unknown = 201, + VRInitError_Driver_HmdUnknown = 202, + VRInitError_Driver_NotLoaded = 203, + VRInitError_Driver_RuntimeOutOfDate = 204, + VRInitError_Driver_HmdInUse = 205, + VRInitError_Driver_NotCalibrated = 206, + VRInitError_Driver_CalibrationInvalid = 207, + VRInitError_Driver_HmdDisplayNotFound = 208, VRInitError_Driver_TrackedDeviceInterfaceUnknown = 209, // VRInitError_Driver_HmdDisplayNotFoundAfterFix = 210, // not needed: here for historic reasons - VRInitError_Driver_HmdDriverIdOutOfBounds = 211, - VRInitError_Driver_HmdDisplayMirrored = 212, + VRInitError_Driver_HmdDriverIdOutOfBounds = 211, + VRInitError_Driver_HmdDisplayMirrored = 212, - VRInitError_IPC_ServerInitFailed = 300, - VRInitError_IPC_ConnectFailed = 301, - VRInitError_IPC_SharedStateInitFailed = 302, - VRInitError_IPC_CompositorInitFailed = 303, - VRInitError_IPC_MutexInitFailed = 304, - VRInitError_IPC_Failed = 305, - VRInitError_IPC_CompositorConnectFailed = 306, + VRInitError_IPC_ServerInitFailed = 300, + VRInitError_IPC_ConnectFailed = 301, + VRInitError_IPC_SharedStateInitFailed = 302, + VRInitError_IPC_CompositorInitFailed = 303, + VRInitError_IPC_MutexInitFailed = 304, + VRInitError_IPC_Failed = 305, + VRInitError_IPC_CompositorConnectFailed = 306, VRInitError_IPC_CompositorInvalidConnectResponse = 307, VRInitError_IPC_ConnectFailedAfterMultipleAttempts = 308, - VRInitError_Compositor_Failed = 400, - VRInitError_Compositor_D3D11HardwareRequired = 401, - VRInitError_Compositor_FirmwareRequiresUpdate = 402, - VRInitError_Compositor_OverlayInitFailed = 403, - VRInitError_Compositor_ScreenshotsInitFailed = 404, - VRInitError_Compositor_UnableToCreateDevice = 405, + VRInitError_Compositor_Failed = 400, + VRInitError_Compositor_D3D11HardwareRequired = 401, + VRInitError_Compositor_FirmwareRequiresUpdate = 402, + VRInitError_Compositor_OverlayInitFailed = 403, + VRInitError_Compositor_ScreenshotsInitFailed = 404, + VRInitError_Compositor_UnableToCreateDevice = 405, - VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000, + VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000, - VRInitError_VendorSpecific_HmdFound_CantOpenDevice = 1101, - VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102, - VRInitError_VendorSpecific_HmdFound_NoStoredConfig = 1103, - VRInitError_VendorSpecific_HmdFound_ConfigTooBig = 1104, - VRInitError_VendorSpecific_HmdFound_ConfigTooSmall = 1105, - VRInitError_VendorSpecific_HmdFound_UnableToInitZLib = 1106, - VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion = 1107, - VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart = 1108, - VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart = 1109, - VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext = 1110, - VRInitError_VendorSpecific_HmdFound_UserDataAddressRange = 1111, - VRInitError_VendorSpecific_HmdFound_UserDataError = 1112, - VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck = 1113, + VRInitError_VendorSpecific_HmdFound_CantOpenDevice = 1101, + VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102, + VRInitError_VendorSpecific_HmdFound_NoStoredConfig = 1103, + VRInitError_VendorSpecific_HmdFound_ConfigTooBig = 1104, + VRInitError_VendorSpecific_HmdFound_ConfigTooSmall = 1105, + VRInitError_VendorSpecific_HmdFound_UnableToInitZLib = 1106, + VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion = 1107, + VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart = 1108, + VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart = 1109, + VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext = 1110, + VRInitError_VendorSpecific_HmdFound_UserDataAddressRange = 1111, + VRInitError_VendorSpecific_HmdFound_UserDataError = 1112, + VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck = 1113, VRInitError_Steam_SteamInstallationNotFound = 2000, }; @@ -1123,7 +1097,7 @@ enum EVRInitError enum EVRScreenshotType { VRScreenshotType_None = 0, - VRScreenshotType_Mono = 1, // left eye only + VRScreenshotType_Mono = 1, // left eye only VRScreenshotType_Stereo = 2, VRScreenshotType_Cubemap = 3, VRScreenshotType_MonoPanorama = 4, @@ -1138,35 +1112,35 @@ enum EVRScreenshotPropertyFilenames enum EVRTrackedCameraError { - VRTrackedCameraError_None = 0, - VRTrackedCameraError_OperationFailed = 100, - VRTrackedCameraError_InvalidHandle = 101, - VRTrackedCameraError_InvalidFrameHeaderVersion = 102, - VRTrackedCameraError_OutOfHandles = 103, - VRTrackedCameraError_IPCFailure = 104, - VRTrackedCameraError_NotSupportedForThisDevice = 105, - VRTrackedCameraError_SharedMemoryFailure = 106, - VRTrackedCameraError_FrameBufferingFailure = 107, - VRTrackedCameraError_StreamSetupFailure = 108, - VRTrackedCameraError_InvalidGLTextureId = 109, + VRTrackedCameraError_None = 0, + VRTrackedCameraError_OperationFailed = 100, + VRTrackedCameraError_InvalidHandle = 101, + VRTrackedCameraError_InvalidFrameHeaderVersion = 102, + VRTrackedCameraError_OutOfHandles = 103, + VRTrackedCameraError_IPCFailure = 104, + VRTrackedCameraError_NotSupportedForThisDevice = 105, + VRTrackedCameraError_SharedMemoryFailure = 106, + VRTrackedCameraError_FrameBufferingFailure = 107, + VRTrackedCameraError_StreamSetupFailure = 108, + VRTrackedCameraError_InvalidGLTextureId = 109, VRTrackedCameraError_InvalidSharedTextureHandle = 110, - VRTrackedCameraError_FailedToGetGLTextureId = 111, - VRTrackedCameraError_SharedTextureFailure = 112, - VRTrackedCameraError_NoFrameAvailable = 113, - VRTrackedCameraError_InvalidArgument = 114, - VRTrackedCameraError_InvalidFrameBufferSize = 115, + VRTrackedCameraError_FailedToGetGLTextureId = 111, + VRTrackedCameraError_SharedTextureFailure = 112, + VRTrackedCameraError_NoFrameAvailable = 113, + VRTrackedCameraError_InvalidArgument = 114, + VRTrackedCameraError_InvalidFrameBufferSize = 115, }; enum EVRTrackedCameraFrameType { - VRTrackedCameraFrameType_Distorted = 0, // This is the camera video frame size in pixels, still distorted. - VRTrackedCameraFrameType_Undistorted, // In pixels, an undistorted inscribed rectangle region without invalid regions. This size is subject to changes shortly. - VRTrackedCameraFrameType_MaximumUndistorted, // In pixels, maximum undistorted with invalid regions. Non zero alpha component identifies valid regions. + VRTrackedCameraFrameType_Distorted = 0, // This is the camera video frame size in pixels, still distorted. + VRTrackedCameraFrameType_Undistorted, // In pixels, an undistorted inscribed rectangle region without invalid regions. This size is subject to changes shortly. + VRTrackedCameraFrameType_MaximumUndistorted, // In pixels, maximum undistorted with invalid regions. Non zero alpha component identifies valid regions. MAX_CAMERA_FRAME_TYPES }; typedef uint64_t TrackedCameraHandle_t; -#define INVALID_TRACKED_CAMERA_HANDLE ((vr::TrackedCameraHandle_t)0) +#define INVALID_TRACKED_CAMERA_HANDLE ((vr::TrackedCameraHandle_t)0) struct CameraVideoStreamFrameHeader_t { @@ -1186,15 +1160,15 @@ typedef uint32_t ScreenshotHandle_t; static const uint32_t k_unScreenshotHandleInvalid = 0; -#pragma pack( pop ) +#pragma pack(pop) // figure out how to import from the VR API dll #if defined(_WIN32) #ifdef VR_API_EXPORT -#define VR_INTERFACE extern "C" __declspec( dllexport ) +#define VR_INTERFACE extern "C" __declspec(dllexport) #else -#define VR_INTERFACE extern "C" __declspec( dllimport ) +#define VR_INTERFACE extern "C" __declspec(dllimport) #endif #elif defined(__GNUC__) || defined(COMPILER_GCC) || defined(__APPLE__) @@ -1202,83 +1176,78 @@ static const uint32_t k_unScreenshotHandleInvalid = 0; #ifdef VR_API_EXPORT #define VR_INTERFACE extern "C" __attribute__((visibility("default"))) #else -#define VR_INTERFACE extern "C" +#define VR_INTERFACE extern "C" #endif #else #error "Unsupported Platform." #endif - -#if defined( _WIN32 ) +#if defined(_WIN32) #define VR_CALLTYPE __cdecl #else -#define VR_CALLTYPE +#define VR_CALLTYPE #endif -} // namespace vr - -#endif // _INCLUDE_VRTYPES_H +} // namespace vr +#endif // _INCLUDE_VRTYPES_H // vrannotation.h #ifdef API_GEN -# define VR_CLANG_ATTR(ATTR) __attribute__((annotate( ATTR ))) +#define VR_CLANG_ATTR(ATTR) __attribute__((annotate(ATTR))) #else -# define VR_CLANG_ATTR(ATTR) +#define VR_CLANG_ATTR(ATTR) #endif -#define VR_METHOD_DESC(DESC) VR_CLANG_ATTR( "desc:" #DESC ";" ) -#define VR_IGNOREATTR() VR_CLANG_ATTR( "ignore" ) -#define VR_OUT_STRUCT() VR_CLANG_ATTR( "out_struct: ;" ) -#define VR_OUT_STRING() VR_CLANG_ATTR( "out_string: ;" ) -#define VR_OUT_ARRAY_CALL(COUNTER,FUNCTION,PARAMS) VR_CLANG_ATTR( "out_array_call:" #COUNTER "," #FUNCTION "," #PARAMS ";" ) -#define VR_OUT_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR( "out_array_count:" #COUNTER ";" ) -#define VR_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR( "array_count:" #COUNTER ";" ) -#define VR_ARRAY_COUNT_D(COUNTER, DESC) VR_CLANG_ATTR( "array_count:" #COUNTER ";desc:" #DESC ) -#define VR_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR( "buffer_count:" #COUNTER ";" ) -#define VR_OUT_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR( "out_buffer_count:" #COUNTER ";" ) -#define VR_OUT_STRING_COUNT(COUNTER) VR_CLANG_ATTR( "out_string_count:" #COUNTER ";" ) +#define VR_METHOD_DESC(DESC) VR_CLANG_ATTR("desc:" #DESC ";") +#define VR_IGNOREATTR() VR_CLANG_ATTR("ignore") +#define VR_OUT_STRUCT() VR_CLANG_ATTR("out_struct: ;") +#define VR_OUT_STRING() VR_CLANG_ATTR("out_string: ;") +#define VR_OUT_ARRAY_CALL(COUNTER, FUNCTION, PARAMS) VR_CLANG_ATTR("out_array_call:" #COUNTER "," #FUNCTION "," #PARAMS ";") +#define VR_OUT_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR("out_array_count:" #COUNTER ";") +#define VR_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR("array_count:" #COUNTER ";") +#define VR_ARRAY_COUNT_D(COUNTER, DESC) VR_CLANG_ATTR("array_count:" #COUNTER ";desc:" #DESC) +#define VR_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR("buffer_count:" #COUNTER ";") +#define VR_OUT_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR("out_buffer_count:" #COUNTER ";") +#define VR_OUT_STRING_COUNT(COUNTER) VR_CLANG_ATTR("out_string_count:" #COUNTER ";") // ivrsystem.h namespace vr { - class IVRSystem { public: - - // ------------------------------------ // Display Methods // ------------------------------------ /** Suggested size for the intermediate render target that the distortion pulls from. */ - virtual void GetRecommendedRenderTargetSize( uint32_t *pnWidth, uint32_t *pnHeight ) = 0; + virtual void GetRecommendedRenderTargetSize(uint32_t *pnWidth, uint32_t *pnHeight) = 0; /** The projection matrix for the specified eye */ - virtual HmdMatrix44_t GetProjectionMatrix( EVREye eEye, float fNearZ, float fFarZ ) = 0; + virtual HmdMatrix44_t GetProjectionMatrix(EVREye eEye, float fNearZ, float fFarZ) = 0; /** The components necessary to build your own projection matrix in case your * application is doing something fancy like infinite Z */ - virtual void GetProjectionRaw( EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom ) = 0; + virtual void GetProjectionRaw(EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom) = 0; /** Gets the result of the distortion function for the specified eye and input UVs. UVs go from 0,0 in * the upper left of that eye's viewport and 1,1 in the lower right of that eye's viewport. * Returns true for success. Otherwise, returns false, and distortion coordinates are not suitable. */ - virtual bool ComputeDistortion( EVREye eEye, float fU, float fV, DistortionCoordinates_t *pDistortionCoordinates ) = 0; + virtual bool ComputeDistortion(EVREye eEye, float fU, float fV, DistortionCoordinates_t *pDistortionCoordinates) = 0; /** Returns the transform from eye space to the head space. Eye space is the per-eye flavor of head * space that provides stereo disparity. Instead of Model * View * Projection the sequence is Model * View * Eye^-1 * Projection. * Normally View and Eye^-1 will be multiplied together and treated as View in your application. */ - virtual HmdMatrix34_t GetEyeToHeadTransform( EVREye eEye ) = 0; + virtual HmdMatrix34_t GetEyeToHeadTransform(EVREye eEye) = 0; /** Returns the number of elapsed seconds since the last recorded vsync event. This * will come from a vsync timer event in the timer if possible or from the application-reported * time if that is not available. If no vsync times are available the function will * return zero for vsync time and frame counter and return false from the method. */ - virtual bool GetTimeSinceLastVsync( float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter ) = 0; + virtual bool GetTimeSinceLastVsync(float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter) = 0; /** [D3D9 Only] * Returns the adapter index that the user should pass into CreateDevice to set up D3D9 in such @@ -1290,8 +1259,8 @@ public: * Returns the adapter index that the user should pass into EnumAdapters to create the device * and swap chain in DX10 and DX11. If an error occurs the index will be set to -1. */ - virtual void GetDXGIOutputInfo( int32_t *pnAdapterIndex ) = 0; - + virtual void GetDXGIOutputInfo(int32_t *pnAdapterIndex) = 0; + /** * Returns platform- and texture-type specific adapter identification so that applications and the * compositor are creating textures and swap chains on the same GPU. If an error occurs the device @@ -1309,7 +1278,7 @@ public: * [macOS Only] * Returns an id that should be used by the application. */ - virtual void GetOutputDevice( uint64_t *pnDevice, ETextureType textureType, VkInstance_T *pInstance = nullptr ) = 0; + virtual void GetOutputDevice(uint64_t *pnDevice, ETextureType textureType, VkInstance_T *pInstance = nullptr) = 0; // ------------------------------------ // Display Mode methods @@ -1319,7 +1288,7 @@ public: virtual bool IsDisplayOnDesktop() = 0; /** Set the display visibility (true = extended, false = direct mode). Return value of true indicates that the change was successful. */ - virtual bool SetDisplayVisibility( bool bIsVisibleOnDesktop ) = 0; + virtual bool SetDisplayVisibility(bool bIsVisibleOnDesktop) = 0; // ------------------------------------ // Tracking Methods @@ -1342,7 +1311,7 @@ public: * probably not be used unless the application is the Chaperone calibration tool itself, but will provide * poses relative to the hardware-specific coordinate system in the driver. */ - virtual void GetDeviceToAbsoluteTrackingPose( ETrackingUniverseOrigin eOrigin, float fPredictedSecondsToPhotonsFromNow, VR_ARRAY_COUNT(unTrackedDevicePoseArrayCount) TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount ) = 0; + virtual void GetDeviceToAbsoluteTrackingPose(ETrackingUniverseOrigin eOrigin, float fPredictedSecondsToPhotonsFromNow, VR_ARRAY_COUNT(unTrackedDevicePoseArrayCount) TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount) = 0; /** Sets the zero pose for the seated tracker coordinate system to the current position and yaw of the HMD. After * ResetSeatedZeroPose all GetDeviceToAbsoluteTrackingPose calls that pass TrackingUniverseSeated as the origin @@ -1370,21 +1339,21 @@ public: /** Get a sorted array of device indices of a given class of tracked devices (e.g. controllers). Devices are sorted right to left * relative to the specified tracked device (default: hmd -- pass in -1 for absolute tracking space). Returns the number of devices * in the list, or the size of the array needed if not large enough. */ - virtual uint32_t GetSortedTrackedDeviceIndicesOfClass( ETrackedDeviceClass eTrackedDeviceClass, VR_ARRAY_COUNT(unTrackedDeviceIndexArrayCount) vr::TrackedDeviceIndex_t *punTrackedDeviceIndexArray, uint32_t unTrackedDeviceIndexArrayCount, vr::TrackedDeviceIndex_t unRelativeToTrackedDeviceIndex = k_unTrackedDeviceIndex_Hmd ) = 0; + virtual uint32_t GetSortedTrackedDeviceIndicesOfClass(ETrackedDeviceClass eTrackedDeviceClass, VR_ARRAY_COUNT(unTrackedDeviceIndexArrayCount) vr::TrackedDeviceIndex_t *punTrackedDeviceIndexArray, uint32_t unTrackedDeviceIndexArrayCount, vr::TrackedDeviceIndex_t unRelativeToTrackedDeviceIndex = k_unTrackedDeviceIndex_Hmd) = 0; /** Returns the level of activity on the device. */ - virtual EDeviceActivityLevel GetTrackedDeviceActivityLevel( vr::TrackedDeviceIndex_t unDeviceId ) = 0; + virtual EDeviceActivityLevel GetTrackedDeviceActivityLevel(vr::TrackedDeviceIndex_t unDeviceId) = 0; /** Convenience utility to apply the specified transform to the specified pose. * This properly transforms all pose components, including velocity and angular velocity */ - virtual void ApplyTransform( TrackedDevicePose_t *pOutputPose, const TrackedDevicePose_t *pTrackedDevicePose, const HmdMatrix34_t *pTransform ) = 0; + virtual void ApplyTransform(TrackedDevicePose_t *pOutputPose, const TrackedDevicePose_t *pTrackedDevicePose, const HmdMatrix34_t *pTransform) = 0; /** Returns the device index associated with a specific role, for example the left hand or the right hand. */ - virtual vr::TrackedDeviceIndex_t GetTrackedDeviceIndexForControllerRole( vr::ETrackedControllerRole unDeviceType ) = 0; + virtual vr::TrackedDeviceIndex_t GetTrackedDeviceIndexForControllerRole(vr::ETrackedControllerRole unDeviceType) = 0; /** Returns the controller type associated with a device index. */ - virtual vr::ETrackedControllerRole GetControllerRoleForTrackedDeviceIndex( vr::TrackedDeviceIndex_t unDeviceIndex ) = 0; + virtual vr::ETrackedControllerRole GetControllerRoleForTrackedDeviceIndex(vr::TrackedDeviceIndex_t unDeviceIndex) = 0; // ------------------------------------ // Property methods @@ -1397,34 +1366,34 @@ public: * To determine which devices exist on the system, just loop from 0 to k_unMaxTrackedDeviceCount and check * the device class. Every device with something other than TrackedDevice_Invalid is associated with an * actual tracked device. */ - virtual ETrackedDeviceClass GetTrackedDeviceClass( vr::TrackedDeviceIndex_t unDeviceIndex ) = 0; + virtual ETrackedDeviceClass GetTrackedDeviceClass(vr::TrackedDeviceIndex_t unDeviceIndex) = 0; /** Returns true if there is a device connected in this slot. */ - virtual bool IsTrackedDeviceConnected( vr::TrackedDeviceIndex_t unDeviceIndex ) = 0; + virtual bool IsTrackedDeviceConnected(vr::TrackedDeviceIndex_t unDeviceIndex) = 0; /** Returns a bool property. If the device index is not valid or the property is not a bool type this function will return false. */ - virtual bool GetBoolTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + virtual bool GetBoolTrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L) = 0; /** Returns a float property. If the device index is not valid or the property is not a float type this function will return 0. */ - virtual float GetFloatTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + virtual float GetFloatTrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L) = 0; /** Returns an int property. If the device index is not valid or the property is not a int type this function will return 0. */ - virtual int32_t GetInt32TrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + virtual int32_t GetInt32TrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L) = 0; /** Returns a uint64 property. If the device index is not valid or the property is not a uint64 type this function will return 0. */ - virtual uint64_t GetUint64TrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + virtual uint64_t GetUint64TrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L) = 0; /** Returns a matrix property. If the device index is not valid or the property is not a matrix type, this function will return identity. */ - virtual HmdMatrix34_t GetMatrix34TrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ) = 0; + virtual HmdMatrix34_t GetMatrix34TrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L) = 0; /** Returns a string property. If the device index is not valid or the property is not a string type this function will * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */ - virtual uint32_t GetStringTrackedDeviceProperty( vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L ) = 0; + virtual uint32_t GetStringTrackedDeviceProperty(vr::TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L) = 0; /** returns a string that corresponds with the specified property error. The string will be the name * of the error enum value for all valid error codes */ - virtual const char *GetPropErrorNameFromEnum( ETrackedPropertyError error ) = 0; + virtual const char *GetPropErrorNameFromEnum(ETrackedPropertyError error) = 0; // ------------------------------------ // Event methods @@ -1432,16 +1401,16 @@ public: /** Returns true and fills the event with the next event on the queue if there is one. If there are no events * this method returns false. uncbVREvent should be the size in bytes of the VREvent_t struct */ - virtual bool PollNextEvent( VREvent_t *pEvent, uint32_t uncbVREvent ) = 0; + virtual bool PollNextEvent(VREvent_t *pEvent, uint32_t uncbVREvent) = 0; /** Returns true and fills the event with the next event on the queue if there is one. If there are no events * this method returns false. Fills in the pose of the associated tracked device in the provided pose struct. * This pose will always be older than the call to this function and should not be used to render the device. uncbVREvent should be the size in bytes of the VREvent_t struct */ - virtual bool PollNextEventWithPose( ETrackingUniverseOrigin eOrigin, VREvent_t *pEvent, uint32_t uncbVREvent, vr::TrackedDevicePose_t *pTrackedDevicePose ) = 0; + virtual bool PollNextEventWithPose(ETrackingUniverseOrigin eOrigin, VREvent_t *pEvent, uint32_t uncbVREvent, vr::TrackedDevicePose_t *pTrackedDevicePose) = 0; /** returns the name of an EVREvent enum value */ - virtual const char *GetEventTypeNameFromEnum( EVREventType eType ) = 0; + virtual const char *GetEventTypeNameFromEnum(EVREventType eType) = 0; // ------------------------------------ // Rendering helper methods @@ -1455,7 +1424,7 @@ public: * Setting the bInverse argument to true will produce the visible area mesh that is commonly used in place of full-screen quads. The visible area mesh covers all of the pixels the hidden area mesh does not cover. * Setting the bLineLoop argument will return a line loop of vertices in HiddenAreaMesh_t->pVertexData with HiddenAreaMesh_t->unTriangleCount set to the number of vertices. */ - virtual HiddenAreaMesh_t GetHiddenAreaMesh( EVREye eEye, EHiddenAreaMeshType type = k_eHiddenAreaMesh_Standard ) = 0; + virtual HiddenAreaMesh_t GetHiddenAreaMesh(EVREye eEye, EHiddenAreaMeshType type = k_eHiddenAreaMesh_Standard) = 0; // ------------------------------------ // Controller methods @@ -1463,22 +1432,22 @@ public: /** Fills the supplied struct with the current state of the controller. Returns false if the controller index * is invalid. */ - virtual bool GetControllerState( vr::TrackedDeviceIndex_t unControllerDeviceIndex, vr::VRControllerState_t *pControllerState, uint32_t unControllerStateSize ) = 0; + virtual bool GetControllerState(vr::TrackedDeviceIndex_t unControllerDeviceIndex, vr::VRControllerState_t *pControllerState, uint32_t unControllerStateSize) = 0; /** fills the supplied struct with the current state of the controller and the provided pose with the pose of * the controller when the controller state was updated most recently. Use this form if you need a precise controller * pose as input to your application when the user presses or releases a button. */ - virtual bool GetControllerStateWithPose( ETrackingUniverseOrigin eOrigin, vr::TrackedDeviceIndex_t unControllerDeviceIndex, vr::VRControllerState_t *pControllerState, uint32_t unControllerStateSize, TrackedDevicePose_t *pTrackedDevicePose ) = 0; + virtual bool GetControllerStateWithPose(ETrackingUniverseOrigin eOrigin, vr::TrackedDeviceIndex_t unControllerDeviceIndex, vr::VRControllerState_t *pControllerState, uint32_t unControllerStateSize, TrackedDevicePose_t *pTrackedDevicePose) = 0; /** Trigger a single haptic pulse on a controller. After this call the application may not trigger another haptic pulse on this controller * and axis combination for 5ms. */ - virtual void TriggerHapticPulse( vr::TrackedDeviceIndex_t unControllerDeviceIndex, uint32_t unAxisId, unsigned short usDurationMicroSec ) = 0; + virtual void TriggerHapticPulse(vr::TrackedDeviceIndex_t unControllerDeviceIndex, uint32_t unAxisId, unsigned short usDurationMicroSec) = 0; /** returns the name of an EVRButtonId enum value */ - virtual const char *GetButtonIdNameFromEnum( EVRButtonId eButtonId ) = 0; + virtual const char *GetButtonIdNameFromEnum(EVRButtonId eButtonId) = 0; /** returns the name of an EVRControllerAxisType enum value */ - virtual const char *GetControllerAxisTypeNameFromEnum( EVRControllerAxisType eAxisType ) = 0; + virtual const char *GetControllerAxisTypeNameFromEnum(EVRControllerAxisType eAxisType) = 0; /** Tells OpenVR that this process wants exclusive access to controller button states and button events. Other apps will be notified that * they have lost input focus with a VREvent_InputFocusCaptured event. Returns false if input focus could not be captured for @@ -1499,18 +1468,18 @@ public: /** Sends a request to the driver for the specified device and returns the response. The maximum response size is 32k, * but this method can be called with a smaller buffer. If the response exceeds the size of the buffer, it is truncated. * The size of the response including its terminating null is returned. */ - virtual uint32_t DriverDebugRequest( vr::TrackedDeviceIndex_t unDeviceIndex, const char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize ) = 0; + virtual uint32_t DriverDebugRequest(vr::TrackedDeviceIndex_t unDeviceIndex, const char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize) = 0; // ------------------------------------ // Firmware methods // ------------------------------------ - + /** Performs the actual firmware update if applicable. * The following events will be sent, if VRFirmwareError_None was returned: VREvent_FirmwareUpdateStarted, VREvent_FirmwareUpdateFinished * Use the properties Prop_Firmware_UpdateAvailable_Bool, Prop_Firmware_ManualUpdate_Bool, and Prop_Firmware_ManualUpdateURL_String * to figure our whether a firmware update is available, and to figure out whether its a manual update * Prop_Firmware_ManualUpdateURL_String should point to an URL describing the manual update process */ - virtual vr::EVRFirmwareError PerformFirmwareUpdate( vr::TrackedDeviceIndex_t unDeviceIndex ) = 0; + virtual vr::EVRFirmwareError PerformFirmwareUpdate(vr::TrackedDeviceIndex_t unDeviceIndex) = 0; // ------------------------------------ // Application life cycle methods @@ -1524,195 +1493,191 @@ public: * halts the timeout and dismisses the dashboard (if it was up). Applications should be sure to actually * prompt the user to save and then exit afterward, otherwise the user will be left in a confusing state. */ virtual void AcknowledgeQuit_UserPrompt() = 0; - }; -static const char * const IVRSystem_Version = "IVRSystem_017"; - -} +static const char *const IVRSystem_Version = "IVRSystem_017"; +} // namespace vr // ivrapplications.h namespace vr { +/** Used for all errors reported by the IVRApplications interface */ +enum EVRApplicationError +{ + VRApplicationError_None = 0, - /** Used for all errors reported by the IVRApplications interface */ - enum EVRApplicationError - { - VRApplicationError_None = 0, + VRApplicationError_AppKeyAlreadyExists = 100, // Only one application can use any given key + VRApplicationError_NoManifest = 101, // the running application does not have a manifest + VRApplicationError_NoApplication = 102, // No application is running + VRApplicationError_InvalidIndex = 103, + VRApplicationError_UnknownApplication = 104, // the application could not be found + VRApplicationError_IPCFailed = 105, // An IPC failure caused the request to fail + VRApplicationError_ApplicationAlreadyRunning = 106, + VRApplicationError_InvalidManifest = 107, + VRApplicationError_InvalidApplication = 108, + VRApplicationError_LaunchFailed = 109, // the process didn't start + VRApplicationError_ApplicationAlreadyStarting = 110, // the system was already starting the same application + VRApplicationError_LaunchInProgress = 111, // The system was already starting a different application + VRApplicationError_OldApplicationQuitting = 112, + VRApplicationError_TransitionAborted = 113, + VRApplicationError_IsTemplate = 114, // error when you try to call LaunchApplication() on a template type app (use LaunchTemplateApplication) + VRApplicationError_SteamVRIsExiting = 115, - VRApplicationError_AppKeyAlreadyExists = 100, // Only one application can use any given key - VRApplicationError_NoManifest = 101, // the running application does not have a manifest - VRApplicationError_NoApplication = 102, // No application is running - VRApplicationError_InvalidIndex = 103, - VRApplicationError_UnknownApplication = 104, // the application could not be found - VRApplicationError_IPCFailed = 105, // An IPC failure caused the request to fail - VRApplicationError_ApplicationAlreadyRunning = 106, - VRApplicationError_InvalidManifest = 107, - VRApplicationError_InvalidApplication = 108, - VRApplicationError_LaunchFailed = 109, // the process didn't start - VRApplicationError_ApplicationAlreadyStarting = 110, // the system was already starting the same application - VRApplicationError_LaunchInProgress = 111, // The system was already starting a different application - VRApplicationError_OldApplicationQuitting = 112, - VRApplicationError_TransitionAborted = 113, - VRApplicationError_IsTemplate = 114, // error when you try to call LaunchApplication() on a template type app (use LaunchTemplateApplication) - VRApplicationError_SteamVRIsExiting = 115, + VRApplicationError_BufferTooSmall = 200, // The provided buffer was too small to fit the requested data + VRApplicationError_PropertyNotSet = 201, // The requested property was not set + VRApplicationError_UnknownProperty = 202, + VRApplicationError_InvalidParameter = 203, +}; - VRApplicationError_BufferTooSmall = 200, // The provided buffer was too small to fit the requested data - VRApplicationError_PropertyNotSet = 201, // The requested property was not set - VRApplicationError_UnknownProperty = 202, - VRApplicationError_InvalidParameter = 203, - }; +/** The maximum length of an application key */ +static const uint32_t k_unMaxApplicationKeyLength = 128; - /** The maximum length of an application key */ - static const uint32_t k_unMaxApplicationKeyLength = 128; +/** these are the properties available on applications. */ +enum EVRApplicationProperty +{ + VRApplicationProperty_Name_String = 0, - /** these are the properties available on applications. */ - enum EVRApplicationProperty - { - VRApplicationProperty_Name_String = 0, + VRApplicationProperty_LaunchType_String = 11, + VRApplicationProperty_WorkingDirectory_String = 12, + VRApplicationProperty_BinaryPath_String = 13, + VRApplicationProperty_Arguments_String = 14, + VRApplicationProperty_URL_String = 15, - VRApplicationProperty_LaunchType_String = 11, - VRApplicationProperty_WorkingDirectory_String = 12, - VRApplicationProperty_BinaryPath_String = 13, - VRApplicationProperty_Arguments_String = 14, - VRApplicationProperty_URL_String = 15, + VRApplicationProperty_Description_String = 50, + VRApplicationProperty_NewsURL_String = 51, + VRApplicationProperty_ImagePath_String = 52, + VRApplicationProperty_Source_String = 53, - VRApplicationProperty_Description_String = 50, - VRApplicationProperty_NewsURL_String = 51, - VRApplicationProperty_ImagePath_String = 52, - VRApplicationProperty_Source_String = 53, + VRApplicationProperty_IsDashboardOverlay_Bool = 60, + VRApplicationProperty_IsTemplate_Bool = 61, + VRApplicationProperty_IsInstanced_Bool = 62, + VRApplicationProperty_IsInternal_Bool = 63, + VRApplicationProperty_WantsCompositorPauseInStandby_Bool = 64, - VRApplicationProperty_IsDashboardOverlay_Bool = 60, - VRApplicationProperty_IsTemplate_Bool = 61, - VRApplicationProperty_IsInstanced_Bool = 62, - VRApplicationProperty_IsInternal_Bool = 63, - VRApplicationProperty_WantsCompositorPauseInStandby_Bool = 64, + VRApplicationProperty_LastLaunchTime_Uint64 = 70, +}; - VRApplicationProperty_LastLaunchTime_Uint64 = 70, - }; +/** These are states the scene application startup process will go through. */ +enum EVRApplicationTransitionState +{ + VRApplicationTransition_None = 0, - /** These are states the scene application startup process will go through. */ - enum EVRApplicationTransitionState - { - VRApplicationTransition_None = 0, + VRApplicationTransition_OldAppQuitSent = 10, + VRApplicationTransition_WaitingForExternalLaunch = 11, - VRApplicationTransition_OldAppQuitSent = 10, - VRApplicationTransition_WaitingForExternalLaunch = 11, - - VRApplicationTransition_NewAppLaunched = 20, - }; + VRApplicationTransition_NewAppLaunched = 20, +}; - struct AppOverrideKeys_t - { - const char *pchKey; - const char *pchValue; - }; +struct AppOverrideKeys_t +{ + const char *pchKey; + const char *pchValue; +}; - /** Currently recognized mime types */ - static const char * const k_pch_MimeType_HomeApp = "vr/home"; - static const char * const k_pch_MimeType_GameTheater = "vr/game_theater"; +/** Currently recognized mime types */ +static const char *const k_pch_MimeType_HomeApp = "vr/home"; +static const char *const k_pch_MimeType_GameTheater = "vr/game_theater"; - class IVRApplications - { - public: +class IVRApplications +{ +public: + // --------------- Application management --------------- // - // --------------- Application management --------------- // - - /** Adds an application manifest to the list to load when building the list of installed applications. + /** Adds an application manifest to the list to load when building the list of installed applications. * Temporary manifests are not automatically loaded */ - virtual EVRApplicationError AddApplicationManifest( const char *pchApplicationManifestFullPath, bool bTemporary = false ) = 0; + virtual EVRApplicationError AddApplicationManifest(const char *pchApplicationManifestFullPath, bool bTemporary = false) = 0; - /** Removes an application manifest from the list to load when building the list of installed applications. */ - virtual EVRApplicationError RemoveApplicationManifest( const char *pchApplicationManifestFullPath ) = 0; + /** Removes an application manifest from the list to load when building the list of installed applications. */ + virtual EVRApplicationError RemoveApplicationManifest(const char *pchApplicationManifestFullPath) = 0; - /** Returns true if an application is installed */ - virtual bool IsApplicationInstalled( const char *pchAppKey ) = 0; + /** Returns true if an application is installed */ + virtual bool IsApplicationInstalled(const char *pchAppKey) = 0; - /** Returns the number of applications available in the list */ - virtual uint32_t GetApplicationCount() = 0; + /** Returns the number of applications available in the list */ + virtual uint32_t GetApplicationCount() = 0; - /** Returns the key of the specified application. The index is at least 0 and is less than the return + /** Returns the key of the specified application. The index is at least 0 and is less than the return * value of GetApplicationCount(). The buffer should be at least k_unMaxApplicationKeyLength in order to * fit the key. */ - virtual EVRApplicationError GetApplicationKeyByIndex( uint32_t unApplicationIndex, VR_OUT_STRING() char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0; + virtual EVRApplicationError GetApplicationKeyByIndex(uint32_t unApplicationIndex, VR_OUT_STRING() char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen) = 0; - /** Returns the key of the application for the specified Process Id. The buffer should be at least + /** Returns the key of the application for the specified Process Id. The buffer should be at least * k_unMaxApplicationKeyLength in order to fit the key. */ - virtual EVRApplicationError GetApplicationKeyByProcessId( uint32_t unProcessId, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0; + virtual EVRApplicationError GetApplicationKeyByProcessId(uint32_t unProcessId, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen) = 0; - /** Launches the application. The existing scene application will exit and then the new application will start. + /** Launches the application. The existing scene application will exit and then the new application will start. * This call is not valid for dashboard overlay applications. */ - virtual EVRApplicationError LaunchApplication( const char *pchAppKey ) = 0; + virtual EVRApplicationError LaunchApplication(const char *pchAppKey) = 0; - /** Launches an instance of an application of type template, with its app key being pchNewAppKey (which must be unique) and optionally override sections + /** Launches an instance of an application of type template, with its app key being pchNewAppKey (which must be unique) and optionally override sections * from the manifest file via AppOverrideKeys_t */ - virtual EVRApplicationError LaunchTemplateApplication( const char *pchTemplateAppKey, const char *pchNewAppKey, VR_ARRAY_COUNT( unKeys ) const AppOverrideKeys_t *pKeys, uint32_t unKeys ) = 0; + virtual EVRApplicationError LaunchTemplateApplication(const char *pchTemplateAppKey, const char *pchNewAppKey, VR_ARRAY_COUNT(unKeys) const AppOverrideKeys_t *pKeys, uint32_t unKeys) = 0; - /** launches the application currently associated with this mime type and passes it the option args, typically the filename or object name of the item being launched */ - virtual vr::EVRApplicationError LaunchApplicationFromMimeType( const char *pchMimeType, const char *pchArgs ) = 0; + /** launches the application currently associated with this mime type and passes it the option args, typically the filename or object name of the item being launched */ + virtual vr::EVRApplicationError LaunchApplicationFromMimeType(const char *pchMimeType, const char *pchArgs) = 0; - /** Launches the dashboard overlay application if it is not already running. This call is only valid for + /** Launches the dashboard overlay application if it is not already running. This call is only valid for * dashboard overlay applications. */ - virtual EVRApplicationError LaunchDashboardOverlay( const char *pchAppKey ) = 0; + virtual EVRApplicationError LaunchDashboardOverlay(const char *pchAppKey) = 0; - /** Cancel a pending launch for an application */ - virtual bool CancelApplicationLaunch( const char *pchAppKey ) = 0; + /** Cancel a pending launch for an application */ + virtual bool CancelApplicationLaunch(const char *pchAppKey) = 0; - /** Identifies a running application. OpenVR can't always tell which process started in response + /** Identifies a running application. OpenVR can't always tell which process started in response * to a URL. This function allows a URL handler (or the process itself) to identify the app key * for the now running application. Passing a process ID of 0 identifies the calling process. * The application must be one that's known to the system via a call to AddApplicationManifest. */ - virtual EVRApplicationError IdentifyApplication( uint32_t unProcessId, const char *pchAppKey ) = 0; + virtual EVRApplicationError IdentifyApplication(uint32_t unProcessId, const char *pchAppKey) = 0; - /** Returns the process ID for an application. Return 0 if the application was not found or is not running. */ - virtual uint32_t GetApplicationProcessId( const char *pchAppKey ) = 0; + /** Returns the process ID for an application. Return 0 if the application was not found or is not running. */ + virtual uint32_t GetApplicationProcessId(const char *pchAppKey) = 0; - /** Returns a string for an applications error */ - virtual const char *GetApplicationsErrorNameFromEnum( EVRApplicationError error ) = 0; + /** Returns a string for an applications error */ + virtual const char *GetApplicationsErrorNameFromEnum(EVRApplicationError error) = 0; - // --------------- Application properties --------------- // + // --------------- Application properties --------------- // - /** Returns a value for an application property. The required buffer size to fit this value will be returned. */ - virtual uint32_t GetApplicationPropertyString( const char *pchAppKey, EVRApplicationProperty eProperty, VR_OUT_STRING() char *pchPropertyValueBuffer, uint32_t unPropertyValueBufferLen, EVRApplicationError *peError = nullptr ) = 0; + /** Returns a value for an application property. The required buffer size to fit this value will be returned. */ + virtual uint32_t GetApplicationPropertyString(const char *pchAppKey, EVRApplicationProperty eProperty, VR_OUT_STRING() char *pchPropertyValueBuffer, uint32_t unPropertyValueBufferLen, EVRApplicationError *peError = nullptr) = 0; - /** Returns a bool value for an application property. Returns false in all error cases. */ - virtual bool GetApplicationPropertyBool( const char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError = nullptr ) = 0; + /** Returns a bool value for an application property. Returns false in all error cases. */ + virtual bool GetApplicationPropertyBool(const char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError = nullptr) = 0; - /** Returns a uint64 value for an application property. Returns 0 in all error cases. */ - virtual uint64_t GetApplicationPropertyUint64( const char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError = nullptr ) = 0; + /** Returns a uint64 value for an application property. Returns 0 in all error cases. */ + virtual uint64_t GetApplicationPropertyUint64(const char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError = nullptr) = 0; - /** Sets the application auto-launch flag. This is only valid for applications which return true for VRApplicationProperty_IsDashboardOverlay_Bool. */ - virtual EVRApplicationError SetApplicationAutoLaunch( const char *pchAppKey, bool bAutoLaunch ) = 0; + /** Sets the application auto-launch flag. This is only valid for applications which return true for VRApplicationProperty_IsDashboardOverlay_Bool. */ + virtual EVRApplicationError SetApplicationAutoLaunch(const char *pchAppKey, bool bAutoLaunch) = 0; - /** Gets the application auto-launch flag. This is only valid for applications which return true for VRApplicationProperty_IsDashboardOverlay_Bool. */ - virtual bool GetApplicationAutoLaunch( const char *pchAppKey ) = 0; + /** Gets the application auto-launch flag. This is only valid for applications which return true for VRApplicationProperty_IsDashboardOverlay_Bool. */ + virtual bool GetApplicationAutoLaunch(const char *pchAppKey) = 0; - /** Adds this mime-type to the list of supported mime types for this application*/ - virtual EVRApplicationError SetDefaultApplicationForMimeType( const char *pchAppKey, const char *pchMimeType ) = 0; + /** Adds this mime-type to the list of supported mime types for this application*/ + virtual EVRApplicationError SetDefaultApplicationForMimeType(const char *pchAppKey, const char *pchMimeType) = 0; - /** return the app key that will open this mime type */ - virtual bool GetDefaultApplicationForMimeType( const char *pchMimeType, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0; + /** return the app key that will open this mime type */ + virtual bool GetDefaultApplicationForMimeType(const char *pchMimeType, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen) = 0; - /** Get the list of supported mime types for this application, comma-delimited */ - virtual bool GetApplicationSupportedMimeTypes( const char *pchAppKey, char *pchMimeTypesBuffer, uint32_t unMimeTypesBuffer ) = 0; + /** Get the list of supported mime types for this application, comma-delimited */ + virtual bool GetApplicationSupportedMimeTypes(const char *pchAppKey, char *pchMimeTypesBuffer, uint32_t unMimeTypesBuffer) = 0; - /** Get the list of app-keys that support this mime type, comma-delimited, the return value is number of bytes you need to return the full string */ - virtual uint32_t GetApplicationsThatSupportMimeType( const char *pchMimeType, char *pchAppKeysThatSupportBuffer, uint32_t unAppKeysThatSupportBuffer ) = 0; + /** Get the list of app-keys that support this mime type, comma-delimited, the return value is number of bytes you need to return the full string */ + virtual uint32_t GetApplicationsThatSupportMimeType(const char *pchMimeType, char *pchAppKeysThatSupportBuffer, uint32_t unAppKeysThatSupportBuffer) = 0; - /** Get the args list from an app launch that had the process already running, you call this when you get a VREvent_ApplicationMimeTypeLoad */ - virtual uint32_t GetApplicationLaunchArguments( uint32_t unHandle, char *pchArgs, uint32_t unArgs ) = 0; + /** Get the args list from an app launch that had the process already running, you call this when you get a VREvent_ApplicationMimeTypeLoad */ + virtual uint32_t GetApplicationLaunchArguments(uint32_t unHandle, char *pchArgs, uint32_t unArgs) = 0; - // --------------- Transition methods --------------- // + // --------------- Transition methods --------------- // - /** Returns the app key for the application that is starting up */ - virtual EVRApplicationError GetStartingApplication( char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen ) = 0; + /** Returns the app key for the application that is starting up */ + virtual EVRApplicationError GetStartingApplication(char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen) = 0; - /** Returns the application transition state */ - virtual EVRApplicationTransitionState GetTransitionState() = 0; + /** Returns the application transition state */ + virtual EVRApplicationTransitionState GetTransitionState() = 0; - /** Returns errors that would prevent the specified application from launching immediately. Calling this function will + /** Returns errors that would prevent the specified application from launching immediately. Calling this function will * cause the current scene application to quit, so only call it when you are actually about to launch something else. * What the caller should do about these failures depends on the failure: * VRApplicationError_OldApplicationQuitting - An existing application has been told to quit. Wait for a VREvent_ProcessQuit @@ -1721,267 +1686,265 @@ namespace vr * VRApplicationError_LaunchInProgress - A different application is already starting. This is a permanent failure. * VRApplicationError_None - Go ahead and launch. Everything is clear. */ - virtual EVRApplicationError PerformApplicationPrelaunchCheck( const char *pchAppKey ) = 0; + virtual EVRApplicationError PerformApplicationPrelaunchCheck(const char *pchAppKey) = 0; - /** Returns a string for an application transition state */ - virtual const char *GetApplicationsTransitionStateNameFromEnum( EVRApplicationTransitionState state ) = 0; + /** Returns a string for an application transition state */ + virtual const char *GetApplicationsTransitionStateNameFromEnum(EVRApplicationTransitionState state) = 0; - /** Returns true if the outgoing scene app has requested a save prompt before exiting */ - virtual bool IsQuitUserPromptRequested() = 0; + /** Returns true if the outgoing scene app has requested a save prompt before exiting */ + virtual bool IsQuitUserPromptRequested() = 0; - /** Starts a subprocess within the calling application. This + /** Starts a subprocess within the calling application. This * suppresses all application transition UI and automatically identifies the new executable * as part of the same application. On success the calling process should exit immediately. * If working directory is NULL or "" the directory portion of the binary path will be * the working directory. */ - virtual EVRApplicationError LaunchInternalProcess( const char *pchBinaryPath, const char *pchArguments, const char *pchWorkingDirectory ) = 0; + virtual EVRApplicationError LaunchInternalProcess(const char *pchBinaryPath, const char *pchArguments, const char *pchWorkingDirectory) = 0; - /** Returns the current scene process ID according to the application system. A scene process will get scene + /** Returns the current scene process ID according to the application system. A scene process will get scene * focus once it starts rendering, but it will appear here once it calls VR_Init with the Scene application * type. */ - virtual uint32_t GetCurrentSceneProcessId() = 0; - }; + virtual uint32_t GetCurrentSceneProcessId() = 0; +}; - static const char * const IVRApplications_Version = "IVRApplications_006"; +static const char *const IVRApplications_Version = "IVRApplications_006"; -} // namespace vr +} // namespace vr // ivrsettings.h namespace vr { - enum EVRSettingsError - { - VRSettingsError_None = 0, - VRSettingsError_IPCFailed = 1, - VRSettingsError_WriteFailed = 2, - VRSettingsError_ReadFailed = 3, - VRSettingsError_JsonParseFailed = 4, - VRSettingsError_UnsetSettingHasNoDefault = 5, // This will be returned if the setting does not appear in the appropriate default file and has not been set - }; +enum EVRSettingsError +{ + VRSettingsError_None = 0, + VRSettingsError_IPCFailed = 1, + VRSettingsError_WriteFailed = 2, + VRSettingsError_ReadFailed = 3, + VRSettingsError_JsonParseFailed = 4, + VRSettingsError_UnsetSettingHasNoDefault = 5, // This will be returned if the setting does not appear in the appropriate default file and has not been set +}; - // The maximum length of a settings key - static const uint32_t k_unMaxSettingsKeyLength = 128; +// The maximum length of a settings key +static const uint32_t k_unMaxSettingsKeyLength = 128; - class IVRSettings - { - public: - virtual const char *GetSettingsErrorNameFromEnum( EVRSettingsError eError ) = 0; +class IVRSettings +{ +public: + virtual const char *GetSettingsErrorNameFromEnum(EVRSettingsError eError) = 0; - // Returns true if file sync occurred (force or settings dirty) - virtual bool Sync( bool bForce = false, EVRSettingsError *peError = nullptr ) = 0; + // Returns true if file sync occurred (force or settings dirty) + virtual bool Sync(bool bForce = false, EVRSettingsError *peError = nullptr) = 0; - virtual void SetBool( const char *pchSection, const char *pchSettingsKey, bool bValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetInt32( const char *pchSection, const char *pchSettingsKey, int32_t nValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetFloat( const char *pchSection, const char *pchSettingsKey, float flValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetString( const char *pchSection, const char *pchSettingsKey, const char *pchValue, EVRSettingsError *peError = nullptr ) = 0; + virtual void SetBool(const char *pchSection, const char *pchSettingsKey, bool bValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetInt32(const char *pchSection, const char *pchSettingsKey, int32_t nValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetFloat(const char *pchSection, const char *pchSettingsKey, float flValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetString(const char *pchSection, const char *pchSettingsKey, const char *pchValue, EVRSettingsError *peError = nullptr) = 0; - // Users of the system need to provide a proper default in default.vrsettings in the resources/settings/ directory - // of either the runtime or the driver_xxx directory. Otherwise the default will be false, 0, 0.0 or "" - virtual bool GetBool( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual int32_t GetInt32( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual float GetFloat( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual void GetString( const char *pchSection, const char *pchSettingsKey, VR_OUT_STRING() char *pchValue, uint32_t unValueLen, EVRSettingsError *peError = nullptr ) = 0; + // Users of the system need to provide a proper default in default.vrsettings in the resources/settings/ directory + // of either the runtime or the driver_xxx directory. Otherwise the default will be false, 0, 0.0 or "" + virtual bool GetBool(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual int32_t GetInt32(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual float GetFloat(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual void GetString(const char *pchSection, const char *pchSettingsKey, VR_OUT_STRING() char *pchValue, uint32_t unValueLen, EVRSettingsError *peError = nullptr) = 0; - virtual void RemoveSection( const char *pchSection, EVRSettingsError *peError = nullptr ) = 0; - virtual void RemoveKeyInSection( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - }; + virtual void RemoveSection(const char *pchSection, EVRSettingsError *peError = nullptr) = 0; + virtual void RemoveKeyInSection(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; +}; - //----------------------------------------------------------------------------- - static const char * const IVRSettings_Version = "IVRSettings_002"; +//----------------------------------------------------------------------------- +static const char *const IVRSettings_Version = "IVRSettings_002"; - //----------------------------------------------------------------------------- - // steamvr keys - static const char * const k_pch_SteamVR_Section = "steamvr"; - static const char * const k_pch_SteamVR_RequireHmd_String = "requireHmd"; - static const char * const k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; - static const char * const k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; - static const char * const k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; - static const char * const k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; - static const char * const k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; - static const char * const k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; - static const char * const k_pch_SteamVR_SendSystemButtonToAllApps_Bool= "sendSystemButtonToAllApps"; - static const char * const k_pch_SteamVR_LogLevel_Int32 = "loglevel"; - static const char * const k_pch_SteamVR_IPD_Float = "ipd"; - static const char * const k_pch_SteamVR_Background_String = "background"; - static const char * const k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; - static const char * const k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; - static const char * const k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; - static const char * const k_pch_SteamVR_GridColor_String = "gridColor"; - static const char * const k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; - static const char * const k_pch_SteamVR_ShowStage_Bool = "showStage"; - static const char * const k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; - static const char * const k_pch_SteamVR_DirectMode_Bool = "directMode"; - static const char * const k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; - static const char * const k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; - static const char * const k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; - static const char * const k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; - static const char * const k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; - static const char * const k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; - static const char * const k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; - static const char * const k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; - static const char * const k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; - static const char * const k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; - static const char * const k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; - static const char * const k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; - static const char * const k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; - static const char * const k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; - static const char * const k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; - static const char * const k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; - static const char * const k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; - static const char * const k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; - static const char * const k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; - static const char * const k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; - static const char * const k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; - static const char * const k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; - static const char * const k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; - static const char * const k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; +//----------------------------------------------------------------------------- +// steamvr keys +static const char *const k_pch_SteamVR_Section = "steamvr"; +static const char *const k_pch_SteamVR_RequireHmd_String = "requireHmd"; +static const char *const k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; +static const char *const k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; +static const char *const k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; +static const char *const k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; +static const char *const k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; +static const char *const k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; +static const char *const k_pch_SteamVR_SendSystemButtonToAllApps_Bool = "sendSystemButtonToAllApps"; +static const char *const k_pch_SteamVR_LogLevel_Int32 = "loglevel"; +static const char *const k_pch_SteamVR_IPD_Float = "ipd"; +static const char *const k_pch_SteamVR_Background_String = "background"; +static const char *const k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; +static const char *const k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; +static const char *const k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; +static const char *const k_pch_SteamVR_GridColor_String = "gridColor"; +static const char *const k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; +static const char *const k_pch_SteamVR_ShowStage_Bool = "showStage"; +static const char *const k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; +static const char *const k_pch_SteamVR_DirectMode_Bool = "directMode"; +static const char *const k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; +static const char *const k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; +static const char *const k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; +static const char *const k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; +static const char *const k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; +static const char *const k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; +static const char *const k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; +static const char *const k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; +static const char *const k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; +static const char *const k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; +static const char *const k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; +static const char *const k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; +static const char *const k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; +static const char *const k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; +static const char *const k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; +static const char *const k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; +static const char *const k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; +static const char *const k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; +static const char *const k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; +static const char *const k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; +static const char *const k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; +static const char *const k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; +static const char *const k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; +static const char *const k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; - //----------------------------------------------------------------------------- - // lighthouse keys - static const char * const k_pch_Lighthouse_Section = "driver_lighthouse"; - static const char * const k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; - static const char * const k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; - static const char * const k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; - static const char * const k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; - static const char * const k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; +//----------------------------------------------------------------------------- +// lighthouse keys +static const char *const k_pch_Lighthouse_Section = "driver_lighthouse"; +static const char *const k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; +static const char *const k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; +static const char *const k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; +static const char *const k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; +static const char *const k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; - //----------------------------------------------------------------------------- - // null keys - static const char * const k_pch_Null_Section = "driver_null"; - static const char * const k_pch_Null_SerialNumber_String = "serialNumber"; - static const char * const k_pch_Null_ModelNumber_String = "modelNumber"; - static const char * const k_pch_Null_WindowX_Int32 = "windowX"; - static const char * const k_pch_Null_WindowY_Int32 = "windowY"; - static const char * const k_pch_Null_WindowWidth_Int32 = "windowWidth"; - static const char * const k_pch_Null_WindowHeight_Int32 = "windowHeight"; - static const char * const k_pch_Null_RenderWidth_Int32 = "renderWidth"; - static const char * const k_pch_Null_RenderHeight_Int32 = "renderHeight"; - static const char * const k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; - static const char * const k_pch_Null_DisplayFrequency_Float = "displayFrequency"; +//----------------------------------------------------------------------------- +// null keys +static const char *const k_pch_Null_Section = "driver_null"; +static const char *const k_pch_Null_SerialNumber_String = "serialNumber"; +static const char *const k_pch_Null_ModelNumber_String = "modelNumber"; +static const char *const k_pch_Null_WindowX_Int32 = "windowX"; +static const char *const k_pch_Null_WindowY_Int32 = "windowY"; +static const char *const k_pch_Null_WindowWidth_Int32 = "windowWidth"; +static const char *const k_pch_Null_WindowHeight_Int32 = "windowHeight"; +static const char *const k_pch_Null_RenderWidth_Int32 = "renderWidth"; +static const char *const k_pch_Null_RenderHeight_Int32 = "renderHeight"; +static const char *const k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; +static const char *const k_pch_Null_DisplayFrequency_Float = "displayFrequency"; - //----------------------------------------------------------------------------- - // user interface keys - static const char * const k_pch_UserInterface_Section = "userinterface"; - static const char * const k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; - static const char * const k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; - static const char * const k_pch_UserInterface_Screenshots_Bool = "screenshots"; - static const char * const k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; +//----------------------------------------------------------------------------- +// user interface keys +static const char *const k_pch_UserInterface_Section = "userinterface"; +static const char *const k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; +static const char *const k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; +static const char *const k_pch_UserInterface_Screenshots_Bool = "screenshots"; +static const char *const k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; - //----------------------------------------------------------------------------- - // notification keys - static const char * const k_pch_Notifications_Section = "notifications"; - static const char * const k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; +//----------------------------------------------------------------------------- +// notification keys +static const char *const k_pch_Notifications_Section = "notifications"; +static const char *const k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; - //----------------------------------------------------------------------------- - // keyboard keys - static const char * const k_pch_Keyboard_Section = "keyboard"; - static const char * const k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; - static const char * const k_pch_Keyboard_ScaleX = "ScaleX"; - static const char * const k_pch_Keyboard_ScaleY = "ScaleY"; - static const char * const k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; - static const char * const k_pch_Keyboard_OffsetRightX = "OffsetRightX"; - static const char * const k_pch_Keyboard_OffsetY = "OffsetY"; - static const char * const k_pch_Keyboard_Smoothing = "Smoothing"; +//----------------------------------------------------------------------------- +// keyboard keys +static const char *const k_pch_Keyboard_Section = "keyboard"; +static const char *const k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; +static const char *const k_pch_Keyboard_ScaleX = "ScaleX"; +static const char *const k_pch_Keyboard_ScaleY = "ScaleY"; +static const char *const k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; +static const char *const k_pch_Keyboard_OffsetRightX = "OffsetRightX"; +static const char *const k_pch_Keyboard_OffsetY = "OffsetY"; +static const char *const k_pch_Keyboard_Smoothing = "Smoothing"; - //----------------------------------------------------------------------------- - // perf keys - static const char * const k_pch_Perf_Section = "perfcheck"; - static const char * const k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; - static const char * const k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; - static const char * const k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; - static const char * const k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; - static const char * const k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; - static const char * const k_pch_Perf_TestData_Float = "perfTestData"; - static const char * const k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; +//----------------------------------------------------------------------------- +// perf keys +static const char *const k_pch_Perf_Section = "perfcheck"; +static const char *const k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; +static const char *const k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; +static const char *const k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; +static const char *const k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; +static const char *const k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; +static const char *const k_pch_Perf_TestData_Float = "perfTestData"; +static const char *const k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; - //----------------------------------------------------------------------------- - // collision bounds keys - static const char * const k_pch_CollisionBounds_Section = "collisionBounds"; - static const char * const k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; - static const char * const k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; - static const char * const k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; - static const char * const k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; - static const char * const k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; - static const char * const k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; - static const char * const k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; - static const char * const k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; - static const char * const k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; +//----------------------------------------------------------------------------- +// collision bounds keys +static const char *const k_pch_CollisionBounds_Section = "collisionBounds"; +static const char *const k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; +static const char *const k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; +static const char *const k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; +static const char *const k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; +static const char *const k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; +static const char *const k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; +static const char *const k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; +static const char *const k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; +static const char *const k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; - //----------------------------------------------------------------------------- - // camera keys - static const char * const k_pch_Camera_Section = "camera"; - static const char * const k_pch_Camera_EnableCamera_Bool = "enableCamera"; - static const char * const k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; - static const char * const k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; - static const char * const k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; - static const char * const k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; - static const char * const k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; - static const char * const k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; - static const char * const k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; - static const char * const k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; +//----------------------------------------------------------------------------- +// camera keys +static const char *const k_pch_Camera_Section = "camera"; +static const char *const k_pch_Camera_EnableCamera_Bool = "enableCamera"; +static const char *const k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; +static const char *const k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; +static const char *const k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; +static const char *const k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; +static const char *const k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; +static const char *const k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; +static const char *const k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; +static const char *const k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; - //----------------------------------------------------------------------------- - // audio keys - static const char * const k_pch_audio_Section = "audio"; - static const char * const k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; - static const char * const k_pch_audio_OnRecordDevice_String = "onRecordDevice"; - static const char * const k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; - static const char * const k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; - static const char * const k_pch_audio_OffRecordDevice_String = "offRecordDevice"; - static const char * const k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; +//----------------------------------------------------------------------------- +// audio keys +static const char *const k_pch_audio_Section = "audio"; +static const char *const k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; +static const char *const k_pch_audio_OnRecordDevice_String = "onRecordDevice"; +static const char *const k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; +static const char *const k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; +static const char *const k_pch_audio_OffRecordDevice_String = "offRecordDevice"; +static const char *const k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; - //----------------------------------------------------------------------------- - // power management keys - static const char * const k_pch_Power_Section = "power"; - static const char * const k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; - static const char * const k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; - static const char * const k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; - static const char * const k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; - static const char * const k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; - static const char * const k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; +//----------------------------------------------------------------------------- +// power management keys +static const char *const k_pch_Power_Section = "power"; +static const char *const k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; +static const char *const k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; +static const char *const k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; +static const char *const k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; +static const char *const k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; +static const char *const k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; - //----------------------------------------------------------------------------- - // dashboard keys - static const char * const k_pch_Dashboard_Section = "dashboard"; - static const char * const k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; - static const char * const k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; +//----------------------------------------------------------------------------- +// dashboard keys +static const char *const k_pch_Dashboard_Section = "dashboard"; +static const char *const k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; +static const char *const k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; - //----------------------------------------------------------------------------- - // model skin keys - static const char * const k_pch_modelskin_Section = "modelskins"; +//----------------------------------------------------------------------------- +// model skin keys +static const char *const k_pch_modelskin_Section = "modelskins"; - //----------------------------------------------------------------------------- - // driver keys - These could be checked in any driver_ section - static const char * const k_pch_Driver_Enable_Bool = "enable"; +//----------------------------------------------------------------------------- +// driver keys - These could be checked in any driver_ section +static const char *const k_pch_Driver_Enable_Bool = "enable"; -} // namespace vr +} // namespace vr // ivrchaperone.h namespace vr { - -#pragma pack( push, 8 ) +#pragma pack(push, 8) enum ChaperoneCalibrationState { // OK! - ChaperoneCalibrationState_OK = 1, // Chaperone is fully calibrated and working correctly + ChaperoneCalibrationState_OK = 1, // Chaperone is fully calibrated and working correctly // Warnings ChaperoneCalibrationState_Warning = 100, - ChaperoneCalibrationState_Warning_BaseStationMayHaveMoved = 101, // A base station thinks that it might have moved - ChaperoneCalibrationState_Warning_BaseStationRemoved = 102, // There are less base stations than when calibrated - ChaperoneCalibrationState_Warning_SeatedBoundsInvalid = 103, // Seated bounds haven't been calibrated for the current tracking center + ChaperoneCalibrationState_Warning_BaseStationMayHaveMoved = 101, // A base station thinks that it might have moved + ChaperoneCalibrationState_Warning_BaseStationRemoved = 102, // There are less base stations than when calibrated + ChaperoneCalibrationState_Warning_SeatedBoundsInvalid = 103, // Seated bounds haven't been calibrated for the current tracking center // Errors - ChaperoneCalibrationState_Error = 200, // The UniverseID is invalid - ChaperoneCalibrationState_Error_BaseStationUninitialized = 201, // Tracking center hasn't be calibrated for at least one of the base stations - ChaperoneCalibrationState_Error_BaseStationConflict = 202, // Tracking center is calibrated, but base stations disagree on the tracking space - ChaperoneCalibrationState_Error_PlayAreaInvalid = 203, // Play Area hasn't been calibrated for the current tracking center - ChaperoneCalibrationState_Error_CollisionBoundsInvalid = 204, // Collision Bounds haven't been calibrated for the current tracking center + ChaperoneCalibrationState_Error = 200, // The UniverseID is invalid + ChaperoneCalibrationState_Error_BaseStationUninitialized = 201, // Tracking center hasn't be calibrated for at least one of the base stations + ChaperoneCalibrationState_Error_BaseStationConflict = 202, // Tracking center is calibrated, but base stations disagree on the tracking space + ChaperoneCalibrationState_Error_PlayAreaInvalid = 203, // Play Area hasn't been calibrated for the current tracking center + ChaperoneCalibrationState_Error_CollisionBoundsInvalid = 204, // Collision Bounds haven't been calibrated for the current tracking center }; - /** HIGH LEVEL TRACKING SPACE ASSUMPTIONS: * 0,0,0 is the preferred standing area center. * 0Y is the floor height. @@ -1989,13 +1952,12 @@ enum ChaperoneCalibrationState class IVRChaperone { public: - /** Get the current state of Chaperone calibration. This state can change at any time during a session due to physical base station changes. **/ virtual ChaperoneCalibrationState GetCalibrationState() = 0; /** Returns the width and depth of the Play Area (formerly named Soft Bounds) in X and Z. * Tracking space center (0,0,0) is the center of the Play Area. **/ - virtual bool GetPlayAreaSize( float *pSizeX, float *pSizeZ ) = 0; + virtual bool GetPlayAreaSize(float *pSizeX, float *pSizeZ) = 0; /** Returns the 4 corner positions of the Play Area (formerly named Soft Bounds). * Corners are in counter-clockwise order. @@ -2003,38 +1965,37 @@ public: * It's a rectangle. * 2 sides are parallel to the X axis and 2 sides are parallel to the Z axis. * Height of every corner is 0Y (on the floor). **/ - virtual bool GetPlayAreaRect( HmdQuad_t *rect ) = 0; + virtual bool GetPlayAreaRect(HmdQuad_t *rect) = 0; /** Reload Chaperone data from the .vrchap file on disk. */ - virtual void ReloadInfo( void ) = 0; + virtual void ReloadInfo(void) = 0; /** Optionally give the chaperone system a hit about the color and brightness in the scene **/ - virtual void SetSceneColor( HmdColor_t color ) = 0; + virtual void SetSceneColor(HmdColor_t color) = 0; /** Get the current chaperone bounds draw color and brightness **/ - virtual void GetBoundsColor( HmdColor_t *pOutputColorArray, int nNumOutputColors, float flCollisionBoundsFadeDistance, HmdColor_t *pOutputCameraColor ) = 0; + virtual void GetBoundsColor(HmdColor_t *pOutputColorArray, int nNumOutputColors, float flCollisionBoundsFadeDistance, HmdColor_t *pOutputCameraColor) = 0; /** Determine whether the bounds are showing right now **/ virtual bool AreBoundsVisible() = 0; /** Force the bounds to show, mostly for utilities **/ - virtual void ForceBoundsVisible( bool bForce ) = 0; + virtual void ForceBoundsVisible(bool bForce) = 0; }; -static const char * const IVRChaperone_Version = "IVRChaperone_003"; +static const char *const IVRChaperone_Version = "IVRChaperone_003"; -#pragma pack( pop ) +#pragma pack(pop) -} +} // namespace vr // ivrchaperonesetup.h namespace vr { - enum EChaperoneConfigFile { - EChaperoneConfigFile_Live = 1, // The live chaperone config, used by most applications and games - EChaperoneConfigFile_Temp = 2, // The temporary chaperone config, used to live-preview collision bounds in room setup + EChaperoneConfigFile_Live = 1, // The live chaperone config, used by most applications and games + EChaperoneConfigFile_Temp = 2, // The temporary chaperone config, used to live-preview collision bounds in room setup }; enum EChaperoneImportFlags @@ -2049,9 +2010,8 @@ enum EChaperoneImportFlags class IVRChaperoneSetup { public: - /** Saves the current working copy to disk */ - virtual bool CommitWorkingCopy( EChaperoneConfigFile configFile ) = 0; + virtual bool CommitWorkingCopy(EChaperoneConfigFile configFile) = 0; /** Reverts the working copy to match the live chaperone calibration. * To modify existing data this MUST be do WHILE getting a non-error ChaperoneCalibrationStatus. @@ -2060,7 +2020,7 @@ public: /** Returns the width and depth of the Play Area (formerly named Soft Bounds) in X and Z from the working copy. * Tracking space center (0,0,0) is the center of the Play Area. */ - virtual bool GetWorkingPlayAreaSize( float *pSizeX, float *pSizeZ ) = 0; + virtual bool GetWorkingPlayAreaSize(float *pSizeX, float *pSizeZ) = 0; /** Returns the 4 corner positions of the Play Area (formerly named Soft Bounds) from the working copy. * Corners are in clockwise order. @@ -2068,95 +2028,93 @@ public: * It's a rectangle. * 2 sides are parallel to the X axis and 2 sides are parallel to the Z axis. * Height of every corner is 0Y (on the floor). **/ - virtual bool GetWorkingPlayAreaRect( HmdQuad_t *rect ) = 0; + virtual bool GetWorkingPlayAreaRect(HmdQuad_t *rect) = 0; /** Returns the number of Quads if the buffer points to null. Otherwise it returns Quads * into the buffer up to the max specified from the working copy. */ - virtual bool GetWorkingCollisionBoundsInfo( VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t* punQuadsCount ) = 0; + virtual bool GetWorkingCollisionBoundsInfo(VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount) = 0; /** Returns the number of Quads if the buffer points to null. Otherwise it returns Quads * into the buffer up to the max specified. */ - virtual bool GetLiveCollisionBoundsInfo( VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t* punQuadsCount ) = 0; + virtual bool GetLiveCollisionBoundsInfo(VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount) = 0; /** Returns the preferred seated position from the working copy. */ - virtual bool GetWorkingSeatedZeroPoseToRawTrackingPose( HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose ) = 0; + virtual bool GetWorkingSeatedZeroPoseToRawTrackingPose(HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose) = 0; /** Returns the standing origin from the working copy. */ - virtual bool GetWorkingStandingZeroPoseToRawTrackingPose( HmdMatrix34_t *pmatStandingZeroPoseToRawTrackingPose ) = 0; + virtual bool GetWorkingStandingZeroPoseToRawTrackingPose(HmdMatrix34_t *pmatStandingZeroPoseToRawTrackingPose) = 0; /** Sets the Play Area in the working copy. */ - virtual void SetWorkingPlayAreaSize( float sizeX, float sizeZ ) = 0; + virtual void SetWorkingPlayAreaSize(float sizeX, float sizeZ) = 0; /** Sets the Collision Bounds in the working copy. */ - virtual void SetWorkingCollisionBoundsInfo( VR_ARRAY_COUNT(unQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount ) = 0; + virtual void SetWorkingCollisionBoundsInfo(VR_ARRAY_COUNT(unQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount) = 0; /** Sets the preferred seated position in the working copy. */ - virtual void SetWorkingSeatedZeroPoseToRawTrackingPose( const HmdMatrix34_t *pMatSeatedZeroPoseToRawTrackingPose ) = 0; + virtual void SetWorkingSeatedZeroPoseToRawTrackingPose(const HmdMatrix34_t *pMatSeatedZeroPoseToRawTrackingPose) = 0; /** Sets the preferred standing position in the working copy. */ - virtual void SetWorkingStandingZeroPoseToRawTrackingPose( const HmdMatrix34_t *pMatStandingZeroPoseToRawTrackingPose ) = 0; + virtual void SetWorkingStandingZeroPoseToRawTrackingPose(const HmdMatrix34_t *pMatStandingZeroPoseToRawTrackingPose) = 0; /** Tear everything down and reload it from the file on disk */ - virtual void ReloadFromDisk( EChaperoneConfigFile configFile ) = 0; + virtual void ReloadFromDisk(EChaperoneConfigFile configFile) = 0; /** Returns the preferred seated position. */ - virtual bool GetLiveSeatedZeroPoseToRawTrackingPose( HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose ) = 0; + virtual bool GetLiveSeatedZeroPoseToRawTrackingPose(HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose) = 0; - virtual void SetWorkingCollisionBoundsTagsInfo( VR_ARRAY_COUNT(unTagCount) uint8_t *pTagsBuffer, uint32_t unTagCount ) = 0; - virtual bool GetLiveCollisionBoundsTagsInfo( VR_OUT_ARRAY_COUNT(punTagCount) uint8_t *pTagsBuffer, uint32_t *punTagCount ) = 0; + virtual void SetWorkingCollisionBoundsTagsInfo(VR_ARRAY_COUNT(unTagCount) uint8_t *pTagsBuffer, uint32_t unTagCount) = 0; + virtual bool GetLiveCollisionBoundsTagsInfo(VR_OUT_ARRAY_COUNT(punTagCount) uint8_t *pTagsBuffer, uint32_t *punTagCount) = 0; - virtual bool SetWorkingPhysicalBoundsInfo( VR_ARRAY_COUNT(unQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount ) = 0; - virtual bool GetLivePhysicalBoundsInfo( VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t* punQuadsCount ) = 0; + virtual bool SetWorkingPhysicalBoundsInfo(VR_ARRAY_COUNT(unQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount) = 0; + virtual bool GetLivePhysicalBoundsInfo(VR_OUT_ARRAY_COUNT(punQuadsCount) HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount) = 0; - virtual bool ExportLiveToBuffer( VR_OUT_STRING() char *pBuffer, uint32_t *pnBufferLength ) = 0; - virtual bool ImportFromBufferToWorking( const char *pBuffer, uint32_t nImportFlags ) = 0; + virtual bool ExportLiveToBuffer(VR_OUT_STRING() char *pBuffer, uint32_t *pnBufferLength) = 0; + virtual bool ImportFromBufferToWorking(const char *pBuffer, uint32_t nImportFlags) = 0; }; -static const char * const IVRChaperoneSetup_Version = "IVRChaperoneSetup_005"; +static const char *const IVRChaperoneSetup_Version = "IVRChaperoneSetup_005"; - -} +} // namespace vr // ivrcompositor.h namespace vr { - -#pragma pack( push, 8 ) +#pragma pack(push, 8) /** Errors that can occur with the VR compositor */ enum EVRCompositorError { - VRCompositorError_None = 0, - VRCompositorError_RequestFailed = 1, - VRCompositorError_IncompatibleVersion = 100, - VRCompositorError_DoNotHaveFocus = 101, - VRCompositorError_InvalidTexture = 102, - VRCompositorError_IsNotSceneApplication = 103, - VRCompositorError_TextureIsOnWrongDevice = 104, + VRCompositorError_None = 0, + VRCompositorError_RequestFailed = 1, + VRCompositorError_IncompatibleVersion = 100, + VRCompositorError_DoNotHaveFocus = 101, + VRCompositorError_InvalidTexture = 102, + VRCompositorError_IsNotSceneApplication = 103, + VRCompositorError_TextureIsOnWrongDevice = 104, VRCompositorError_TextureUsesUnsupportedFormat = 105, VRCompositorError_SharedTexturesNotSupported = 106, - VRCompositorError_IndexOutOfRange = 107, - VRCompositorError_AlreadySubmitted = 108, - VRCompositorError_InvalidBounds = 109, + VRCompositorError_IndexOutOfRange = 107, + VRCompositorError_AlreadySubmitted = 108, + VRCompositorError_InvalidBounds = 109, }; const uint32_t VRCompositor_ReprojectionReason_Cpu = 0x01; const uint32_t VRCompositor_ReprojectionReason_Gpu = 0x02; -const uint32_t VRCompositor_ReprojectionAsync = 0x04; // This flag indicates the async reprojection mode is active, - // but does not indicate if reprojection actually happened or not. - // Use the ReprojectionReason flags above to check if reprojection - // was actually applied (i.e. scene texture was reused). - // NumFramePresents > 1 also indicates the scene texture was reused, - // and also the number of times that it was presented in total. +const uint32_t VRCompositor_ReprojectionAsync = 0x04; // This flag indicates the async reprojection mode is active, + // but does not indicate if reprojection actually happened or not. + // Use the ReprojectionReason flags above to check if reprojection + // was actually applied (i.e. scene texture was reused). + // NumFramePresents > 1 also indicates the scene texture was reused, + // and also the number of times that it was presented in total. /** Provides a single frame's timing information to the app */ struct Compositor_FrameTiming { - uint32_t m_nSize; // Set to sizeof( Compositor_FrameTiming ) + uint32_t m_nSize; // Set to sizeof( Compositor_FrameTiming ) uint32_t m_nFrameIndex; - uint32_t m_nNumFramePresents; // number of times this frame was presented - uint32_t m_nNumMisPresented; // number of times this frame was presented on a vsync other than it was originally predicted to - uint32_t m_nNumDroppedFrames; // number of additional times previous frame was scanned out + uint32_t m_nNumFramePresents; // number of times this frame was presented + uint32_t m_nNumMisPresented; // number of times this frame was presented on a vsync other than it was originally predicted to + uint32_t m_nNumDroppedFrames; // number of additional times previous frame was scanned out uint32_t m_nReprojectionFlags; /** Absolute time reference for comparing frames. This aligns with the vsync that running start is relative to. */ @@ -2166,38 +2124,38 @@ struct Compositor_FrameTiming * The fewer packets of work these are broken up into, the less likely this will happen. * GPU work can be broken up by calling Flush. This can sometimes be useful to get the GPU started * processing that work earlier in the frame. */ - float m_flPreSubmitGpuMs; // time spent rendering the scene (gpu work submitted between WaitGetPoses and second Submit) - float m_flPostSubmitGpuMs; // additional time spent rendering by application (e.g. companion window) - float m_flTotalRenderGpuMs; // time between work submitted immediately after present (ideally vsync) until the end of compositor submitted work - float m_flCompositorRenderGpuMs; // time spend performing distortion correction, rendering chaperone, overlays, etc. - float m_flCompositorRenderCpuMs; // time spent on cpu submitting the above work for this frame - float m_flCompositorIdleCpuMs; // time spent waiting for running start (application could have used this much more time) + float m_flPreSubmitGpuMs; // time spent rendering the scene (gpu work submitted between WaitGetPoses and second Submit) + float m_flPostSubmitGpuMs; // additional time spent rendering by application (e.g. companion window) + float m_flTotalRenderGpuMs; // time between work submitted immediately after present (ideally vsync) until the end of compositor submitted work + float m_flCompositorRenderGpuMs; // time spend performing distortion correction, rendering chaperone, overlays, etc. + float m_flCompositorRenderCpuMs; // time spent on cpu submitting the above work for this frame + float m_flCompositorIdleCpuMs; // time spent waiting for running start (application could have used this much more time) /** Miscellaneous measured intervals. */ - float m_flClientFrameIntervalMs; // time between calls to WaitGetPoses - float m_flPresentCallCpuMs; // time blocked on call to present (usually 0.0, but can go long) - float m_flWaitForPresentCpuMs; // time spent spin-waiting for frame index to change (not near-zero indicates wait object failure) - float m_flSubmitFrameMs; // time spent in IVRCompositor::Submit (not near-zero indicates driver issue) + float m_flClientFrameIntervalMs; // time between calls to WaitGetPoses + float m_flPresentCallCpuMs; // time blocked on call to present (usually 0.0, but can go long) + float m_flWaitForPresentCpuMs; // time spent spin-waiting for frame index to change (not near-zero indicates wait object failure) + float m_flSubmitFrameMs; // time spent in IVRCompositor::Submit (not near-zero indicates driver issue) /** The following are all relative to this frame's SystemTimeInSeconds */ float m_flWaitGetPosesCalledMs; float m_flNewPosesReadyMs; - float m_flNewFrameReadyMs; // second call to IVRCompositor::Submit + float m_flNewFrameReadyMs; // second call to IVRCompositor::Submit float m_flCompositorUpdateStartMs; float m_flCompositorUpdateEndMs; float m_flCompositorRenderStartMs; - vr::TrackedDevicePose_t m_HmdPose; // pose used by app to render this frame + vr::TrackedDevicePose_t m_HmdPose; // pose used by app to render this frame }; /** Cumulative stats for current application. These are not cleared until a new app connects, * but they do stop accumulating once the associated app disconnects. */ struct Compositor_CumulativeStats { - uint32_t m_nPid; // Process id associated with these stats (may no longer be running). - uint32_t m_nNumFramePresents; // total number of times we called present (includes reprojected frames) - uint32_t m_nNumDroppedFrames; // total number of times an old frame was re-scanned out (without reprojection) - uint32_t m_nNumReprojectedFrames; // total number of times a frame was scanned out a second time (with reprojection) + uint32_t m_nPid; // Process id associated with these stats (may no longer be running). + uint32_t m_nNumFramePresents; // total number of times we called present (includes reprojected frames) + uint32_t m_nNumDroppedFrames; // total number of times an old frame was re-scanned out (without reprojection) + uint32_t m_nNumReprojectedFrames; // total number of times a frame was scanned out a second time (with reprojection) /** Values recorded at startup before application has fully faded in the first time. */ uint32_t m_nNumFramePresentsOnStartup; @@ -2220,14 +2178,14 @@ struct Compositor_CumulativeStats uint32_t m_nNumReprojectedFramesTimedOut; }; -#pragma pack( pop ) +#pragma pack(pop) /** Allows the application to interact with the compositor */ class IVRCompositor { public: /** Sets tracking space returned by WaitGetPoses */ - virtual void SetTrackingSpace( ETrackingUniverseOrigin eOrigin ) = 0; + virtual void SetTrackingSpace(ETrackingUniverseOrigin eOrigin) = 0; /** Gets current tracking space returned by WaitGetPoses */ virtual ETrackingUniverseOrigin GetTrackingSpace() = 0; @@ -2240,17 +2198,17 @@ public: * - IsNotSceneApplication (make sure to call VR_Init with VRApplicaiton_Scene) * - DoNotHaveFocus (some other app has taken focus - this will throttle the call to 10hz to reduce the impact on that app) */ - virtual EVRCompositorError WaitGetPoses( VR_ARRAY_COUNT(unRenderPoseArrayCount) TrackedDevicePose_t* pRenderPoseArray, uint32_t unRenderPoseArrayCount, - VR_ARRAY_COUNT(unGamePoseArrayCount) TrackedDevicePose_t* pGamePoseArray, uint32_t unGamePoseArrayCount ) = 0; + virtual EVRCompositorError WaitGetPoses(VR_ARRAY_COUNT(unRenderPoseArrayCount) TrackedDevicePose_t *pRenderPoseArray, uint32_t unRenderPoseArrayCount, + VR_ARRAY_COUNT(unGamePoseArrayCount) TrackedDevicePose_t *pGamePoseArray, uint32_t unGamePoseArrayCount) = 0; /** Get the last set of poses returned by WaitGetPoses. */ - virtual EVRCompositorError GetLastPoses( VR_ARRAY_COUNT( unRenderPoseArrayCount ) TrackedDevicePose_t* pRenderPoseArray, uint32_t unRenderPoseArrayCount, - VR_ARRAY_COUNT( unGamePoseArrayCount ) TrackedDevicePose_t* pGamePoseArray, uint32_t unGamePoseArrayCount ) = 0; + virtual EVRCompositorError GetLastPoses(VR_ARRAY_COUNT(unRenderPoseArrayCount) TrackedDevicePose_t *pRenderPoseArray, uint32_t unRenderPoseArrayCount, + VR_ARRAY_COUNT(unGamePoseArrayCount) TrackedDevicePose_t *pGamePoseArray, uint32_t unGamePoseArrayCount) = 0; /** Interface for accessing last set of poses returned by WaitGetPoses one at a time. * Returns VRCompositorError_IndexOutOfRange if unDeviceIndex not less than k_unMaxTrackedDeviceCount otherwise VRCompositorError_None. * It is okay to pass NULL for either pose if you only want one of the values. */ - virtual EVRCompositorError GetLastPoseForTrackedDeviceIndex( TrackedDeviceIndex_t unDeviceIndex, TrackedDevicePose_t *pOutputPose, TrackedDevicePose_t *pOutputGamePose ) = 0; + virtual EVRCompositorError GetLastPoseForTrackedDeviceIndex(TrackedDeviceIndex_t unDeviceIndex, TrackedDevicePose_t *pOutputPose, TrackedDevicePose_t *pOutputGamePose) = 0; /** Updated scene texture to display. If pBounds is NULL the entire texture will be used. If called from an OpenGL app, consider adding a glFlush after * Submitting both frames to signal the driver to start processing, otherwise it may wait until the command buffer fills up, causing the app to miss frames. @@ -2267,7 +2225,7 @@ public: * - InvalidTexture (usually means bad arguments passed in) * - AlreadySubmitted (app has submitted two left textures or two right textures in a single frame - i.e. before calling WaitGetPoses again) */ - virtual EVRCompositorError Submit( EVREye eEye, const Texture_t *pTexture, const VRTextureBounds_t* pBounds = 0, EVRSubmitFlags nSubmitFlags = Submit_Default ) = 0; + virtual EVRCompositorError Submit(EVREye eEye, const Texture_t *pTexture, const VRTextureBounds_t *pBounds = 0, EVRSubmitFlags nSubmitFlags = Submit_Default) = 0; /** Clears the frame that was sent with the last call to Submit. This will cause the * compositor to show the grid until Submit is called again. */ @@ -2282,29 +2240,29 @@ public: /** Returns true if timing data is filled it. Sets oldest timing info if nFramesAgo is larger than the stored history. * Be sure to set timing.size = sizeof(Compositor_FrameTiming) on struct passed in before calling this function. */ - virtual bool GetFrameTiming( Compositor_FrameTiming *pTiming, uint32_t unFramesAgo = 0 ) = 0; + virtual bool GetFrameTiming(Compositor_FrameTiming *pTiming, uint32_t unFramesAgo = 0) = 0; /** Interface for copying a range of timing data. Frames are returned in ascending order (oldest to newest) with the last being the most recent frame. * Only the first entry's m_nSize needs to be set, as the rest will be inferred from that. Returns total number of entries filled out. */ - virtual uint32_t GetFrameTimings( Compositor_FrameTiming *pTiming, uint32_t nFrames ) = 0; + virtual uint32_t GetFrameTimings(Compositor_FrameTiming *pTiming, uint32_t nFrames) = 0; /** Returns the time in seconds left in the current (as identified by FrameTiming's frameIndex) frame. * Due to "running start", this value may roll over to the next frame before ever reaching 0.0. */ virtual float GetFrameTimeRemaining() = 0; /** Fills out stats accumulated for the last connected application. Pass in sizeof( Compositor_CumulativeStats ) as second parameter. */ - virtual void GetCumulativeStats( Compositor_CumulativeStats *pStats, uint32_t nStatsSizeInBytes ) = 0; + virtual void GetCumulativeStats(Compositor_CumulativeStats *pStats, uint32_t nStatsSizeInBytes) = 0; /** Fades the view on the HMD to the specified color. The fade will take fSeconds, and the color values are between * 0.0 and 1.0. This color is faded on top of the scene based on the alpha parameter. Removing the fade color instantly * would be FadeToColor( 0.0, 0.0, 0.0, 0.0, 0.0 ). Values are in un-premultiplied alpha space. */ - virtual void FadeToColor( float fSeconds, float fRed, float fGreen, float fBlue, float fAlpha, bool bBackground = false ) = 0; + virtual void FadeToColor(float fSeconds, float fRed, float fGreen, float fBlue, float fAlpha, bool bBackground = false) = 0; /** Get current fade color value. */ - virtual HmdColor_t GetCurrentFadeColor( bool bBackground = false ) = 0; + virtual HmdColor_t GetCurrentFadeColor(bool bBackground = false) = 0; /** Fading the Grid in or out in fSeconds */ - virtual void FadeGrid( float fSeconds, bool bFadeIn ) = 0; + virtual void FadeGrid(float fSeconds, bool bFadeIn) = 0; /** Get current alpha value of grid. */ virtual float GetCurrentGridAlpha() = 0; @@ -2312,7 +2270,7 @@ public: /** Override the skybox used in the compositor (e.g. for during level loads when the app can't feed scene images fast enough) * Order is Front, Back, Left, Right, Top, Bottom. If only a single texture is passed, it is assumed in lat-long format. * If two are passed, it is assumed a lat-long stereo pair. */ - virtual EVRCompositorError SetSkyboxOverride( VR_ARRAY_COUNT( unTextureCount ) const Texture_t *pTextures, uint32_t unTextureCount ) = 0; + virtual EVRCompositorError SetSkyboxOverride(VR_ARRAY_COUNT(unTextureCount) const Texture_t *pTextures, uint32_t unTextureCount) = 0; /** Resets compositor skybox back to defaults. */ virtual void ClearSkyboxOverride() = 0; @@ -2327,7 +2285,7 @@ public: /** Tells the compositor process to clean up and exit. You do not need to call this function at shutdown. Under normal * circumstances the compositor will manage its own life cycle based on what applications are running. */ virtual void CompositorQuit() = 0; - + /** Return whether the compositor is fullscreen */ virtual bool IsFullscreen() = 0; @@ -2357,34 +2315,34 @@ public: virtual bool ShouldAppRenderWithLowResources() = 0; /** Override interleaved reprojection logic to force on. */ - virtual void ForceInterleavedReprojectionOn( bool bOverride ) = 0; + virtual void ForceInterleavedReprojectionOn(bool bOverride) = 0; /** Force reconnecting to the compositor process. */ virtual void ForceReconnectProcess() = 0; /** Temporarily suspends rendering (useful for finer control over scene transitions). */ - virtual void SuspendRendering( bool bSuspend ) = 0; + virtual void SuspendRendering(bool bSuspend) = 0; /** Opens a shared D3D11 texture with the undistorted composited image for each eye. Use ReleaseMirrorTextureD3D11 when finished * instead of calling Release on the resource itself. */ - virtual vr::EVRCompositorError GetMirrorTextureD3D11( vr::EVREye eEye, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView ) = 0; - virtual void ReleaseMirrorTextureD3D11( void *pD3D11ShaderResourceView ) = 0; + virtual vr::EVRCompositorError GetMirrorTextureD3D11(vr::EVREye eEye, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView) = 0; + virtual void ReleaseMirrorTextureD3D11(void *pD3D11ShaderResourceView) = 0; /** Access to mirror textures from OpenGL. */ - virtual vr::EVRCompositorError GetMirrorTextureGL( vr::EVREye eEye, vr::glUInt_t *pglTextureId, vr::glSharedTextureHandle_t *pglSharedTextureHandle ) = 0; - virtual bool ReleaseSharedGLTexture( vr::glUInt_t glTextureId, vr::glSharedTextureHandle_t glSharedTextureHandle ) = 0; - virtual void LockGLSharedTextureForAccess( vr::glSharedTextureHandle_t glSharedTextureHandle ) = 0; - virtual void UnlockGLSharedTextureForAccess( vr::glSharedTextureHandle_t glSharedTextureHandle ) = 0; + virtual vr::EVRCompositorError GetMirrorTextureGL(vr::EVREye eEye, vr::glUInt_t *pglTextureId, vr::glSharedTextureHandle_t *pglSharedTextureHandle) = 0; + virtual bool ReleaseSharedGLTexture(vr::glUInt_t glTextureId, vr::glSharedTextureHandle_t glSharedTextureHandle) = 0; + virtual void LockGLSharedTextureForAccess(vr::glSharedTextureHandle_t glSharedTextureHandle) = 0; + virtual void UnlockGLSharedTextureForAccess(vr::glSharedTextureHandle_t glSharedTextureHandle) = 0; /** [Vulkan Only] * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. The string will be a space separated list of-required instance extensions to enable in VkCreateInstance */ - virtual uint32_t GetVulkanInstanceExtensionsRequired( VR_OUT_STRING() char *pchValue, uint32_t unBufferSize ) = 0; + virtual uint32_t GetVulkanInstanceExtensionsRequired(VR_OUT_STRING() char *pchValue, uint32_t unBufferSize) = 0; /** [Vulkan only] * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. The string will be a space separated list of required device extensions to enable in VkCreateDevice */ - virtual uint32_t GetVulkanDeviceExtensionsRequired( VkPhysicalDevice_T *pPhysicalDevice, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize ) = 0; + virtual uint32_t GetVulkanDeviceExtensionsRequired(VkPhysicalDevice_T *pPhysicalDevice, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize) = 0; /** [ Vulkan/D3D12 Only ] * There are two purposes for SetExplicitTimingMode: @@ -2404,7 +2362,7 @@ public: * application calls PostPresentHandoff, then WaitGetPoses is guaranteed not to access the queue. Note that PostPresentHandoff * and SubmitExplicitTimingData will access the queue, so only WaitGetPoses becomes safe for accessing the queue from another * thread. */ - virtual void SetExplicitTimingMode( bool bExplicitTimingMode ) = 0; + virtual void SetExplicitTimingMode(bool bExplicitTimingMode) = 0; /** [ Vulkan/D3D12 Only ] * Submit explicit timing data. When SetExplicitTimingMode is true, this must be called immediately before @@ -2415,28 +2373,20 @@ public: virtual EVRCompositorError SubmitExplicitTimingData() = 0; }; -static const char * const IVRCompositor_Version = "IVRCompositor_021"; - -} // namespace vr - +static const char *const IVRCompositor_Version = "IVRCompositor_021"; +} // namespace vr // ivrnotifications.h namespace vr { - -#pragma pack( push, 8 ) +#pragma pack(push, 8) // Used for passing graphic data struct NotificationBitmap_t { NotificationBitmap_t() - : m_pImageData( nullptr ) - , m_nWidth( 0 ) - , m_nHeight( 0 ) - , m_nBytesPerPixel( 0 ) - { - }; + : m_pImageData(nullptr), m_nWidth(0), m_nHeight(0), m_nBytesPerPixel(0){}; void *m_pImageData; int32_t m_nWidth; @@ -2444,7 +2394,6 @@ struct NotificationBitmap_t int32_t m_nBytesPerPixel; }; - /** Be aware that the notification type is used as 'priority' to pick the next notification */ enum EVRNotificationType { @@ -2484,9 +2433,7 @@ static const uint32_t k_unNotificationTextMaxSize = 256; typedef uint32_t VRNotificationId; - - -#pragma pack( pop ) +#pragma pack(pop) /** Allows notification sources to interact with the VR system This current interface is not yet implemented. Do not use yet. */ @@ -2497,267 +2444,261 @@ public: * An overlay handle is required to create a notification, as otherwise it would be impossible for a user to act on it. * To create a two-line notification, use a line break ('\n') to split the text into two lines. * The pImage argument may be NULL, in which case the specified overlay's icon will be used instead. */ - virtual EVRNotificationError CreateNotification( VROverlayHandle_t ulOverlayHandle, uint64_t ulUserValue, EVRNotificationType type, const char *pchText, EVRNotificationStyle style, const NotificationBitmap_t *pImage, /* out */ VRNotificationId *pNotificationId ) = 0; + virtual EVRNotificationError CreateNotification(VROverlayHandle_t ulOverlayHandle, uint64_t ulUserValue, EVRNotificationType type, const char *pchText, EVRNotificationStyle style, const NotificationBitmap_t *pImage, /* out */ VRNotificationId *pNotificationId) = 0; /** Destroy a notification, hiding it first if it currently shown to the user. */ - virtual EVRNotificationError RemoveNotification( VRNotificationId notificationId ) = 0; - + virtual EVRNotificationError RemoveNotification(VRNotificationId notificationId) = 0; }; -static const char * const IVRNotifications_Version = "IVRNotifications_002"; - -} // namespace vr - +static const char *const IVRNotifications_Version = "IVRNotifications_002"; +} // namespace vr // ivroverlay.h namespace vr { +/** The maximum length of an overlay key in bytes, counting the terminating null character. */ +static const uint32_t k_unVROverlayMaxKeyLength = 128; - /** The maximum length of an overlay key in bytes, counting the terminating null character. */ - static const uint32_t k_unVROverlayMaxKeyLength = 128; +/** The maximum length of an overlay name in bytes, counting the terminating null character. */ +static const uint32_t k_unVROverlayMaxNameLength = 128; - /** The maximum length of an overlay name in bytes, counting the terminating null character. */ - static const uint32_t k_unVROverlayMaxNameLength = 128; +/** The maximum number of overlays that can exist in the system at one time. */ +static const uint32_t k_unMaxOverlayCount = 64; - /** The maximum number of overlays that can exist in the system at one time. */ - static const uint32_t k_unMaxOverlayCount = 64; +/** The maximum number of overlay intersection mask primitives per overlay */ +static const uint32_t k_unMaxOverlayIntersectionMaskPrimitivesCount = 32; - /** The maximum number of overlay intersection mask primitives per overlay */ - static const uint32_t k_unMaxOverlayIntersectionMaskPrimitivesCount = 32; +/** Types of input supported by VR Overlays */ +enum VROverlayInputMethod +{ + VROverlayInputMethod_None = 0, // No input events will be generated automatically for this overlay + VROverlayInputMethod_Mouse = 1, // Tracked controllers will get mouse events automatically +}; - /** Types of input supported by VR Overlays */ - enum VROverlayInputMethod - { - VROverlayInputMethod_None = 0, // No input events will be generated automatically for this overlay - VROverlayInputMethod_Mouse = 1, // Tracked controllers will get mouse events automatically - }; +/** Allows the caller to figure out which overlay transform getter to call. */ +enum VROverlayTransformType +{ + VROverlayTransform_Absolute = 0, + VROverlayTransform_TrackedDeviceRelative = 1, + VROverlayTransform_SystemOverlay = 2, + VROverlayTransform_TrackedComponent = 3, +}; - /** Allows the caller to figure out which overlay transform getter to call. */ - enum VROverlayTransformType - { - VROverlayTransform_Absolute = 0, - VROverlayTransform_TrackedDeviceRelative = 1, - VROverlayTransform_SystemOverlay = 2, - VROverlayTransform_TrackedComponent = 3, - }; +/** Overlay control settings */ +enum VROverlayFlags +{ + VROverlayFlags_None = 0, - /** Overlay control settings */ - enum VROverlayFlags - { - VROverlayFlags_None = 0, + // The following only take effect when rendered using the high quality render path (see SetHighQualityOverlay). + VROverlayFlags_Curved = 1, + VROverlayFlags_RGSS4X = 2, - // The following only take effect when rendered using the high quality render path (see SetHighQualityOverlay). - VROverlayFlags_Curved = 1, - VROverlayFlags_RGSS4X = 2, + // Set this flag on a dashboard overlay to prevent a tab from showing up for that overlay + VROverlayFlags_NoDashboardTab = 3, - // Set this flag on a dashboard overlay to prevent a tab from showing up for that overlay - VROverlayFlags_NoDashboardTab = 3, + // Set this flag on a dashboard that is able to deal with gamepad focus events + VROverlayFlags_AcceptsGamepadEvents = 4, - // Set this flag on a dashboard that is able to deal with gamepad focus events - VROverlayFlags_AcceptsGamepadEvents = 4, + // Indicates that the overlay should dim/brighten to show gamepad focus + VROverlayFlags_ShowGamepadFocus = 5, - // Indicates that the overlay should dim/brighten to show gamepad focus - VROverlayFlags_ShowGamepadFocus = 5, + // When in VROverlayInputMethod_Mouse you can optionally enable sending VRScroll_t + VROverlayFlags_SendVRScrollEvents = 6, + VROverlayFlags_SendVRTouchpadEvents = 7, - // When in VROverlayInputMethod_Mouse you can optionally enable sending VRScroll_t - VROverlayFlags_SendVRScrollEvents = 6, - VROverlayFlags_SendVRTouchpadEvents = 7, + // If set this will render a vertical scroll wheel on the primary controller, + // only needed if not using VROverlayFlags_SendVRScrollEvents but you still want to represent a scroll wheel + VROverlayFlags_ShowTouchPadScrollWheel = 8, - // If set this will render a vertical scroll wheel on the primary controller, - // only needed if not using VROverlayFlags_SendVRScrollEvents but you still want to represent a scroll wheel - VROverlayFlags_ShowTouchPadScrollWheel = 8, + // If this is set ownership and render access to the overlay are transferred + // to the new scene process on a call to IVRApplications::LaunchInternalProcess + VROverlayFlags_TransferOwnershipToInternalProcess = 9, - // If this is set ownership and render access to the overlay are transferred - // to the new scene process on a call to IVRApplications::LaunchInternalProcess - VROverlayFlags_TransferOwnershipToInternalProcess = 9, + // If set, renders 50% of the texture in each eye, side by side + VROverlayFlags_SideBySide_Parallel = 10, // Texture is left/right + VROverlayFlags_SideBySide_Crossed = 11, // Texture is crossed and right/left - // If set, renders 50% of the texture in each eye, side by side - VROverlayFlags_SideBySide_Parallel = 10, // Texture is left/right - VROverlayFlags_SideBySide_Crossed = 11, // Texture is crossed and right/left + VROverlayFlags_Panorama = 12, // Texture is a panorama + VROverlayFlags_StereoPanorama = 13, // Texture is a stereo panorama - VROverlayFlags_Panorama = 12, // Texture is a panorama - VROverlayFlags_StereoPanorama = 13, // Texture is a stereo panorama + // If this is set on an overlay owned by the scene application that overlay + // will be sorted with the "Other" overlays on top of all other scene overlays + VROverlayFlags_SortWithNonSceneOverlays = 14, - // If this is set on an overlay owned by the scene application that overlay - // will be sorted with the "Other" overlays on top of all other scene overlays - VROverlayFlags_SortWithNonSceneOverlays = 14, + // If set, the overlay will be shown in the dashboard, otherwise it will be hidden. + VROverlayFlags_VisibleInDashboard = 15, +}; - // If set, the overlay will be shown in the dashboard, otherwise it will be hidden. - VROverlayFlags_VisibleInDashboard = 15, - }; +enum VRMessageOverlayResponse +{ + VRMessageOverlayResponse_ButtonPress_0 = 0, + VRMessageOverlayResponse_ButtonPress_1 = 1, + VRMessageOverlayResponse_ButtonPress_2 = 2, + VRMessageOverlayResponse_ButtonPress_3 = 3, + VRMessageOverlayResponse_CouldntFindSystemOverlay = 4, + VRMessageOverlayResponse_CouldntFindOrCreateClientOverlay = 5, + VRMessageOverlayResponse_ApplicationQuit = 6 +}; - enum VRMessageOverlayResponse - { - VRMessageOverlayResponse_ButtonPress_0 = 0, - VRMessageOverlayResponse_ButtonPress_1 = 1, - VRMessageOverlayResponse_ButtonPress_2 = 2, - VRMessageOverlayResponse_ButtonPress_3 = 3, - VRMessageOverlayResponse_CouldntFindSystemOverlay = 4, - VRMessageOverlayResponse_CouldntFindOrCreateClientOverlay= 5, - VRMessageOverlayResponse_ApplicationQuit = 6 - }; +struct VROverlayIntersectionParams_t +{ + HmdVector3_t vSource; + HmdVector3_t vDirection; + ETrackingUniverseOrigin eOrigin; +}; - struct VROverlayIntersectionParams_t - { - HmdVector3_t vSource; - HmdVector3_t vDirection; - ETrackingUniverseOrigin eOrigin; - }; +struct VROverlayIntersectionResults_t +{ + HmdVector3_t vPoint; + HmdVector3_t vNormal; + HmdVector2_t vUVs; + float fDistance; +}; - struct VROverlayIntersectionResults_t - { - HmdVector3_t vPoint; - HmdVector3_t vNormal; - HmdVector2_t vUVs; - float fDistance; - }; +// Input modes for the Big Picture gamepad text entry +enum EGamepadTextInputMode +{ + k_EGamepadTextInputModeNormal = 0, + k_EGamepadTextInputModePassword = 1, + k_EGamepadTextInputModeSubmit = 2, +}; - // Input modes for the Big Picture gamepad text entry - enum EGamepadTextInputMode - { - k_EGamepadTextInputModeNormal = 0, - k_EGamepadTextInputModePassword = 1, - k_EGamepadTextInputModeSubmit = 2, - }; +// Controls number of allowed lines for the Big Picture gamepad text entry +enum EGamepadTextInputLineMode +{ + k_EGamepadTextInputLineModeSingleLine = 0, + k_EGamepadTextInputLineModeMultipleLines = 1 +}; - // Controls number of allowed lines for the Big Picture gamepad text entry - enum EGamepadTextInputLineMode - { - k_EGamepadTextInputLineModeSingleLine = 0, - k_EGamepadTextInputLineModeMultipleLines = 1 - }; +/** Directions for changing focus between overlays with the gamepad */ +enum EOverlayDirection +{ + OverlayDirection_Up = 0, + OverlayDirection_Down = 1, + OverlayDirection_Left = 2, + OverlayDirection_Right = 3, - /** Directions for changing focus between overlays with the gamepad */ - enum EOverlayDirection - { - OverlayDirection_Up = 0, - OverlayDirection_Down = 1, - OverlayDirection_Left = 2, - OverlayDirection_Right = 3, - - OverlayDirection_Count = 4, - }; + OverlayDirection_Count = 4, +}; - enum EVROverlayIntersectionMaskPrimitiveType - { - OverlayIntersectionPrimitiveType_Rectangle, - OverlayIntersectionPrimitiveType_Circle, - }; +enum EVROverlayIntersectionMaskPrimitiveType +{ + OverlayIntersectionPrimitiveType_Rectangle, + OverlayIntersectionPrimitiveType_Circle, +}; - struct IntersectionMaskRectangle_t - { - float m_flTopLeftX; - float m_flTopLeftY; - float m_flWidth; - float m_flHeight; - }; +struct IntersectionMaskRectangle_t +{ + float m_flTopLeftX; + float m_flTopLeftY; + float m_flWidth; + float m_flHeight; +}; - struct IntersectionMaskCircle_t - { - float m_flCenterX; - float m_flCenterY; - float m_flRadius; - }; +struct IntersectionMaskCircle_t +{ + float m_flCenterX; + float m_flCenterY; + float m_flRadius; +}; - /** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py and openvr_api_flat.h.py */ - typedef union - { - IntersectionMaskRectangle_t m_Rectangle; - IntersectionMaskCircle_t m_Circle; - } VROverlayIntersectionMaskPrimitive_Data_t; +/** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py and openvr_api_flat.h.py */ +typedef union { + IntersectionMaskRectangle_t m_Rectangle; + IntersectionMaskCircle_t m_Circle; +} VROverlayIntersectionMaskPrimitive_Data_t; - struct VROverlayIntersectionMaskPrimitive_t - { - EVROverlayIntersectionMaskPrimitiveType m_nPrimitiveType; - VROverlayIntersectionMaskPrimitive_Data_t m_Primitive; - }; +struct VROverlayIntersectionMaskPrimitive_t +{ + EVROverlayIntersectionMaskPrimitiveType m_nPrimitiveType; + VROverlayIntersectionMaskPrimitive_Data_t m_Primitive; +}; - class IVROverlay - { - public: +class IVROverlay +{ +public: + // --------------------------------------------- + // Overlay management methods + // --------------------------------------------- - // --------------------------------------------- - // Overlay management methods - // --------------------------------------------- + /** Finds an existing overlay with the specified key. */ + virtual EVROverlayError FindOverlay(const char *pchOverlayKey, VROverlayHandle_t *pOverlayHandle) = 0; - /** Finds an existing overlay with the specified key. */ - virtual EVROverlayError FindOverlay( const char *pchOverlayKey, VROverlayHandle_t * pOverlayHandle ) = 0; + /** Creates a new named overlay. All overlays start hidden and with default settings. */ + virtual EVROverlayError CreateOverlay(const char *pchOverlayKey, const char *pchOverlayName, VROverlayHandle_t *pOverlayHandle) = 0; - /** Creates a new named overlay. All overlays start hidden and with default settings. */ - virtual EVROverlayError CreateOverlay( const char *pchOverlayKey, const char *pchOverlayName, VROverlayHandle_t * pOverlayHandle ) = 0; - - /** Destroys the specified overlay. When an application calls VR_Shutdown all overlays created by that app are + /** Destroys the specified overlay. When an application calls VR_Shutdown all overlays created by that app are * automatically destroyed. */ - virtual EVROverlayError DestroyOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + virtual EVROverlayError DestroyOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Specify which overlay to use the high quality render path. This overlay will be composited in during the distortion pass which + /** Specify which overlay to use the high quality render path. This overlay will be composited in during the distortion pass which * results in it drawing on top of everything else, but also at a higher quality as it samples the source texture directly rather than * rasterizing into each eye's render texture first. Because if this, only one of these is supported at any given time. It is most useful * for overlays that are expected to take up most of the user's view (e.g. streaming video). * This mode does not support mouse input to your overlay. */ - virtual EVROverlayError SetHighQualityOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + virtual EVROverlayError SetHighQualityOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Returns the overlay handle of the current overlay being rendered using the single high quality overlay render path. + /** Returns the overlay handle of the current overlay being rendered using the single high quality overlay render path. * Otherwise it will return k_ulOverlayHandleInvalid. */ - virtual vr::VROverlayHandle_t GetHighQualityOverlay() = 0; + virtual vr::VROverlayHandle_t GetHighQualityOverlay() = 0; - /** Fills the provided buffer with the string key of the overlay. Returns the size of buffer required to store the key, including + /** Fills the provided buffer with the string key of the overlay. Returns the size of buffer required to store the key, including * the terminating null character. k_unVROverlayMaxKeyLength will be enough bytes to fit the string. */ - virtual uint32_t GetOverlayKey( VROverlayHandle_t ulOverlayHandle, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, EVROverlayError *pError = 0L ) = 0; + virtual uint32_t GetOverlayKey(VROverlayHandle_t ulOverlayHandle, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, EVROverlayError *pError = 0L) = 0; - /** Fills the provided buffer with the friendly name of the overlay. Returns the size of buffer required to store the key, including + /** Fills the provided buffer with the friendly name of the overlay. Returns the size of buffer required to store the key, including * the terminating null character. k_unVROverlayMaxNameLength will be enough bytes to fit the string. */ - virtual uint32_t GetOverlayName( VROverlayHandle_t ulOverlayHandle, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, EVROverlayError *pError = 0L ) = 0; + virtual uint32_t GetOverlayName(VROverlayHandle_t ulOverlayHandle, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, EVROverlayError *pError = 0L) = 0; - /** set the name to use for this overlay */ - virtual EVROverlayError SetOverlayName( VROverlayHandle_t ulOverlayHandle, const char *pchName ) = 0; + /** set the name to use for this overlay */ + virtual EVROverlayError SetOverlayName(VROverlayHandle_t ulOverlayHandle, const char *pchName) = 0; - /** Gets the raw image data from an overlay. Overlay image data is always returned as RGBA data, 4 bytes per pixel. If the buffer is not large enough, width and height + /** Gets the raw image data from an overlay. Overlay image data is always returned as RGBA data, 4 bytes per pixel. If the buffer is not large enough, width and height * will be set and VROverlayError_ArrayTooSmall is returned. */ - virtual EVROverlayError GetOverlayImageData( VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unBufferSize, uint32_t *punWidth, uint32_t *punHeight ) = 0; + virtual EVROverlayError GetOverlayImageData(VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unBufferSize, uint32_t *punWidth, uint32_t *punHeight) = 0; - /** returns a string that corresponds with the specified overlay error. The string will be the name + /** returns a string that corresponds with the specified overlay error. The string will be the name * of the error enum value for all valid error codes */ - virtual const char *GetOverlayErrorNameFromEnum( EVROverlayError error ) = 0; + virtual const char *GetOverlayErrorNameFromEnum(EVROverlayError error) = 0; - // --------------------------------------------- - // Overlay rendering methods - // --------------------------------------------- + // --------------------------------------------- + // Overlay rendering methods + // --------------------------------------------- - /** Sets the pid that is allowed to render to this overlay (the creator pid is always allow to render), + /** Sets the pid that is allowed to render to this overlay (the creator pid is always allow to render), * by default this is the pid of the process that made the overlay */ - virtual EVROverlayError SetOverlayRenderingPid( VROverlayHandle_t ulOverlayHandle, uint32_t unPID ) = 0; + virtual EVROverlayError SetOverlayRenderingPid(VROverlayHandle_t ulOverlayHandle, uint32_t unPID) = 0; - /** Gets the pid that is allowed to render to this overlay */ - virtual uint32_t GetOverlayRenderingPid( VROverlayHandle_t ulOverlayHandle ) = 0; + /** Gets the pid that is allowed to render to this overlay */ + virtual uint32_t GetOverlayRenderingPid(VROverlayHandle_t ulOverlayHandle) = 0; - /** Specify flag setting for a given overlay */ - virtual EVROverlayError SetOverlayFlag( VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool bEnabled ) = 0; + /** Specify flag setting for a given overlay */ + virtual EVROverlayError SetOverlayFlag(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool bEnabled) = 0; - /** Sets flag setting for a given overlay */ - virtual EVROverlayError GetOverlayFlag( VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool *pbEnabled ) = 0; + /** Sets flag setting for a given overlay */ + virtual EVROverlayError GetOverlayFlag(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool *pbEnabled) = 0; - /** Sets the color tint of the overlay quad. Use 0.0 to 1.0 per channel. */ - virtual EVROverlayError SetOverlayColor( VROverlayHandle_t ulOverlayHandle, float fRed, float fGreen, float fBlue ) = 0; + /** Sets the color tint of the overlay quad. Use 0.0 to 1.0 per channel. */ + virtual EVROverlayError SetOverlayColor(VROverlayHandle_t ulOverlayHandle, float fRed, float fGreen, float fBlue) = 0; - /** Gets the color tint of the overlay quad. */ - virtual EVROverlayError GetOverlayColor( VROverlayHandle_t ulOverlayHandle, float *pfRed, float *pfGreen, float *pfBlue ) = 0; + /** Gets the color tint of the overlay quad. */ + virtual EVROverlayError GetOverlayColor(VROverlayHandle_t ulOverlayHandle, float *pfRed, float *pfGreen, float *pfBlue) = 0; - /** Sets the alpha of the overlay quad. Use 1.0 for 100 percent opacity to 0.0 for 0 percent opacity. */ - virtual EVROverlayError SetOverlayAlpha( VROverlayHandle_t ulOverlayHandle, float fAlpha ) = 0; + /** Sets the alpha of the overlay quad. Use 1.0 for 100 percent opacity to 0.0 for 0 percent opacity. */ + virtual EVROverlayError SetOverlayAlpha(VROverlayHandle_t ulOverlayHandle, float fAlpha) = 0; - /** Gets the alpha of the overlay quad. By default overlays are rendering at 100 percent alpha (1.0). */ - virtual EVROverlayError GetOverlayAlpha( VROverlayHandle_t ulOverlayHandle, float *pfAlpha ) = 0; + /** Gets the alpha of the overlay quad. By default overlays are rendering at 100 percent alpha (1.0). */ + virtual EVROverlayError GetOverlayAlpha(VROverlayHandle_t ulOverlayHandle, float *pfAlpha) = 0; - /** Sets the aspect ratio of the texels in the overlay. 1.0 means the texels are square. 2.0 means the texels + /** Sets the aspect ratio of the texels in the overlay. 1.0 means the texels are square. 2.0 means the texels * are twice as wide as they are tall. Defaults to 1.0. */ - virtual EVROverlayError SetOverlayTexelAspect( VROverlayHandle_t ulOverlayHandle, float fTexelAspect ) = 0; + virtual EVROverlayError SetOverlayTexelAspect(VROverlayHandle_t ulOverlayHandle, float fTexelAspect) = 0; - /** Gets the aspect ratio of the texels in the overlay. Defaults to 1.0 */ - virtual EVROverlayError GetOverlayTexelAspect( VROverlayHandle_t ulOverlayHandle, float *pfTexelAspect ) = 0; + /** Gets the aspect ratio of the texels in the overlay. Defaults to 1.0 */ + virtual EVROverlayError GetOverlayTexelAspect(VROverlayHandle_t ulOverlayHandle, float *pfTexelAspect) = 0; - /** Sets the rendering sort order for the overlay. Overlays are rendered this order: + /** Sets the rendering sort order for the overlay. Overlays are rendered this order: * Overlays owned by the scene application * Overlays owned by some other application * @@ -2765,160 +2706,160 @@ namespace vr * sort order are rendered back to front base on distance from the HMD. * * Sort order defaults to 0. */ - virtual EVROverlayError SetOverlaySortOrder( VROverlayHandle_t ulOverlayHandle, uint32_t unSortOrder ) = 0; + virtual EVROverlayError SetOverlaySortOrder(VROverlayHandle_t ulOverlayHandle, uint32_t unSortOrder) = 0; - /** Gets the sort order of the overlay. See SetOverlaySortOrder for how this works. */ - virtual EVROverlayError GetOverlaySortOrder( VROverlayHandle_t ulOverlayHandle, uint32_t *punSortOrder ) = 0; + /** Gets the sort order of the overlay. See SetOverlaySortOrder for how this works. */ + virtual EVROverlayError GetOverlaySortOrder(VROverlayHandle_t ulOverlayHandle, uint32_t *punSortOrder) = 0; - /** Sets the width of the overlay quad in meters. By default overlays are rendered on a quad that is 1 meter across */ - virtual EVROverlayError SetOverlayWidthInMeters( VROverlayHandle_t ulOverlayHandle, float fWidthInMeters ) = 0; + /** Sets the width of the overlay quad in meters. By default overlays are rendered on a quad that is 1 meter across */ + virtual EVROverlayError SetOverlayWidthInMeters(VROverlayHandle_t ulOverlayHandle, float fWidthInMeters) = 0; - /** Returns the width of the overlay quad in meters. By default overlays are rendered on a quad that is 1 meter across */ - virtual EVROverlayError GetOverlayWidthInMeters( VROverlayHandle_t ulOverlayHandle, float *pfWidthInMeters ) = 0; + /** Returns the width of the overlay quad in meters. By default overlays are rendered on a quad that is 1 meter across */ + virtual EVROverlayError GetOverlayWidthInMeters(VROverlayHandle_t ulOverlayHandle, float *pfWidthInMeters) = 0; - /** For high-quality curved overlays only, sets the distance range in meters from the overlay used to automatically curve + /** For high-quality curved overlays only, sets the distance range in meters from the overlay used to automatically curve * the surface around the viewer. Min is distance is when the surface will be most curved. Max is when least curved. */ - virtual EVROverlayError SetOverlayAutoCurveDistanceRangeInMeters( VROverlayHandle_t ulOverlayHandle, float fMinDistanceInMeters, float fMaxDistanceInMeters ) = 0; + virtual EVROverlayError SetOverlayAutoCurveDistanceRangeInMeters(VROverlayHandle_t ulOverlayHandle, float fMinDistanceInMeters, float fMaxDistanceInMeters) = 0; - /** For high-quality curved overlays only, gets the distance range in meters from the overlay used to automatically curve + /** For high-quality curved overlays only, gets the distance range in meters from the overlay used to automatically curve * the surface around the viewer. Min is distance is when the surface will be most curved. Max is when least curved. */ - virtual EVROverlayError GetOverlayAutoCurveDistanceRangeInMeters( VROverlayHandle_t ulOverlayHandle, float *pfMinDistanceInMeters, float *pfMaxDistanceInMeters ) = 0; + virtual EVROverlayError GetOverlayAutoCurveDistanceRangeInMeters(VROverlayHandle_t ulOverlayHandle, float *pfMinDistanceInMeters, float *pfMaxDistanceInMeters) = 0; - /** Sets the colorspace the overlay texture's data is in. Defaults to 'auto'. + /** Sets the colorspace the overlay texture's data is in. Defaults to 'auto'. * If the texture needs to be resolved, you should call SetOverlayTexture with the appropriate colorspace instead. */ - virtual EVROverlayError SetOverlayTextureColorSpace( VROverlayHandle_t ulOverlayHandle, EColorSpace eTextureColorSpace ) = 0; + virtual EVROverlayError SetOverlayTextureColorSpace(VROverlayHandle_t ulOverlayHandle, EColorSpace eTextureColorSpace) = 0; - /** Gets the overlay's current colorspace setting. */ - virtual EVROverlayError GetOverlayTextureColorSpace( VROverlayHandle_t ulOverlayHandle, EColorSpace *peTextureColorSpace ) = 0; + /** Gets the overlay's current colorspace setting. */ + virtual EVROverlayError GetOverlayTextureColorSpace(VROverlayHandle_t ulOverlayHandle, EColorSpace *peTextureColorSpace) = 0; - /** Sets the part of the texture to use for the overlay. UV Min is the upper left corner and UV Max is the lower right corner. */ - virtual EVROverlayError SetOverlayTextureBounds( VROverlayHandle_t ulOverlayHandle, const VRTextureBounds_t *pOverlayTextureBounds ) = 0; + /** Sets the part of the texture to use for the overlay. UV Min is the upper left corner and UV Max is the lower right corner. */ + virtual EVROverlayError SetOverlayTextureBounds(VROverlayHandle_t ulOverlayHandle, const VRTextureBounds_t *pOverlayTextureBounds) = 0; - /** Gets the part of the texture to use for the overlay. UV Min is the upper left corner and UV Max is the lower right corner. */ - virtual EVROverlayError GetOverlayTextureBounds( VROverlayHandle_t ulOverlayHandle, VRTextureBounds_t *pOverlayTextureBounds ) = 0; + /** Gets the part of the texture to use for the overlay. UV Min is the upper left corner and UV Max is the lower right corner. */ + virtual EVROverlayError GetOverlayTextureBounds(VROverlayHandle_t ulOverlayHandle, VRTextureBounds_t *pOverlayTextureBounds) = 0; - /** Gets render model to draw behind this overlay */ - virtual uint32_t GetOverlayRenderModel( vr::VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, HmdColor_t *pColor, vr::EVROverlayError *pError ) = 0; + /** Gets render model to draw behind this overlay */ + virtual uint32_t GetOverlayRenderModel(vr::VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, HmdColor_t *pColor, vr::EVROverlayError *pError) = 0; - /** Sets render model to draw behind this overlay and the vertex color to use, pass null for pColor to match the overlays vertex color. + /** Sets render model to draw behind this overlay and the vertex color to use, pass null for pColor to match the overlays vertex color. The model is scaled by the same amount as the overlay, with a default of 1m. */ - virtual vr::EVROverlayError SetOverlayRenderModel( vr::VROverlayHandle_t ulOverlayHandle, const char *pchRenderModel, const HmdColor_t *pColor ) = 0; + virtual vr::EVROverlayError SetOverlayRenderModel(vr::VROverlayHandle_t ulOverlayHandle, const char *pchRenderModel, const HmdColor_t *pColor) = 0; - /** Returns the transform type of this overlay. */ - virtual EVROverlayError GetOverlayTransformType( VROverlayHandle_t ulOverlayHandle, VROverlayTransformType *peTransformType ) = 0; + /** Returns the transform type of this overlay. */ + virtual EVROverlayError GetOverlayTransformType(VROverlayHandle_t ulOverlayHandle, VROverlayTransformType *peTransformType) = 0; - /** Sets the transform to absolute tracking origin. */ - virtual EVROverlayError SetOverlayTransformAbsolute( VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, const HmdMatrix34_t *pmatTrackingOriginToOverlayTransform ) = 0; + /** Sets the transform to absolute tracking origin. */ + virtual EVROverlayError SetOverlayTransformAbsolute(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, const HmdMatrix34_t *pmatTrackingOriginToOverlayTransform) = 0; - /** Gets the transform if it is absolute. Returns an error if the transform is some other type. */ - virtual EVROverlayError GetOverlayTransformAbsolute( VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin *peTrackingOrigin, HmdMatrix34_t *pmatTrackingOriginToOverlayTransform ) = 0; + /** Gets the transform if it is absolute. Returns an error if the transform is some other type. */ + virtual EVROverlayError GetOverlayTransformAbsolute(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin *peTrackingOrigin, HmdMatrix34_t *pmatTrackingOriginToOverlayTransform) = 0; - /** Sets the transform to relative to the transform of the specified tracked device. */ - virtual EVROverlayError SetOverlayTransformTrackedDeviceRelative( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unTrackedDevice, const HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform ) = 0; + /** Sets the transform to relative to the transform of the specified tracked device. */ + virtual EVROverlayError SetOverlayTransformTrackedDeviceRelative(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unTrackedDevice, const HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform) = 0; - /** Gets the transform if it is relative to a tracked device. Returns an error if the transform is some other type. */ - virtual EVROverlayError GetOverlayTransformTrackedDeviceRelative( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punTrackedDevice, HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform ) = 0; + /** Gets the transform if it is relative to a tracked device. Returns an error if the transform is some other type. */ + virtual EVROverlayError GetOverlayTransformTrackedDeviceRelative(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punTrackedDevice, HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform) = 0; - /** Sets the transform to draw the overlay on a rendermodel component mesh instead of a quad. This will only draw when the system is + /** Sets the transform to draw the overlay on a rendermodel component mesh instead of a quad. This will only draw when the system is * drawing the device. Overlays with this transform type cannot receive mouse events. */ - virtual EVROverlayError SetOverlayTransformTrackedDeviceComponent( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unDeviceIndex, const char *pchComponentName ) = 0; + virtual EVROverlayError SetOverlayTransformTrackedDeviceComponent(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unDeviceIndex, const char *pchComponentName) = 0; - /** Gets the transform information when the overlay is rendering on a component. */ - virtual EVROverlayError GetOverlayTransformTrackedDeviceComponent( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punDeviceIndex, char *pchComponentName, uint32_t unComponentNameSize ) = 0; + /** Gets the transform information when the overlay is rendering on a component. */ + virtual EVROverlayError GetOverlayTransformTrackedDeviceComponent(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punDeviceIndex, char *pchComponentName, uint32_t unComponentNameSize) = 0; - /** Gets the transform if it is relative to another overlay. Returns an error if the transform is some other type. */ - virtual vr::EVROverlayError GetOverlayTransformOverlayRelative( VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t *ulOverlayHandleParent, HmdMatrix34_t *pmatParentOverlayToOverlayTransform ) = 0; - - /** Sets the transform to relative to the transform of the specified overlay. This overlays visibility will also track the parents visibility */ - virtual vr::EVROverlayError SetOverlayTransformOverlayRelative( VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t ulOverlayHandleParent, const HmdMatrix34_t *pmatParentOverlayToOverlayTransform ) = 0; + /** Gets the transform if it is relative to another overlay. Returns an error if the transform is some other type. */ + virtual vr::EVROverlayError GetOverlayTransformOverlayRelative(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t *ulOverlayHandleParent, HmdMatrix34_t *pmatParentOverlayToOverlayTransform) = 0; - /** Shows the VR overlay. For dashboard overlays, only the Dashboard Manager is allowed to call this. */ - virtual EVROverlayError ShowOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + /** Sets the transform to relative to the transform of the specified overlay. This overlays visibility will also track the parents visibility */ + virtual vr::EVROverlayError SetOverlayTransformOverlayRelative(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t ulOverlayHandleParent, const HmdMatrix34_t *pmatParentOverlayToOverlayTransform) = 0; - /** Hides the VR overlay. For dashboard overlays, only the Dashboard Manager is allowed to call this. */ - virtual EVROverlayError HideOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + /** Shows the VR overlay. For dashboard overlays, only the Dashboard Manager is allowed to call this. */ + virtual EVROverlayError ShowOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Returns true if the overlay is visible. */ - virtual bool IsOverlayVisible( VROverlayHandle_t ulOverlayHandle ) = 0; + /** Hides the VR overlay. For dashboard overlays, only the Dashboard Manager is allowed to call this. */ + virtual EVROverlayError HideOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Get the transform in 3d space associated with a specific 2d point in the overlay's coordinate space (where 0,0 is the lower left). -Z points out of the overlay */ - virtual EVROverlayError GetTransformForOverlayCoordinates( VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, HmdVector2_t coordinatesInOverlay, HmdMatrix34_t *pmatTransform ) = 0; + /** Returns true if the overlay is visible. */ + virtual bool IsOverlayVisible(VROverlayHandle_t ulOverlayHandle) = 0; - // --------------------------------------------- - // Overlay input methods - // --------------------------------------------- + /** Get the transform in 3d space associated with a specific 2d point in the overlay's coordinate space (where 0,0 is the lower left). -Z points out of the overlay */ + virtual EVROverlayError GetTransformForOverlayCoordinates(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, HmdVector2_t coordinatesInOverlay, HmdMatrix34_t *pmatTransform) = 0; - /** Returns true and fills the event with the next event on the overlay's event queue, if there is one. + // --------------------------------------------- + // Overlay input methods + // --------------------------------------------- + + /** Returns true and fills the event with the next event on the overlay's event queue, if there is one. * If there are no events this method returns false. uncbVREvent should be the size in bytes of the VREvent_t struct */ - virtual bool PollNextOverlayEvent( VROverlayHandle_t ulOverlayHandle, VREvent_t *pEvent, uint32_t uncbVREvent ) = 0; + virtual bool PollNextOverlayEvent(VROverlayHandle_t ulOverlayHandle, VREvent_t *pEvent, uint32_t uncbVREvent) = 0; - /** Returns the current input settings for the specified overlay. */ - virtual EVROverlayError GetOverlayInputMethod( VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod *peInputMethod ) = 0; + /** Returns the current input settings for the specified overlay. */ + virtual EVROverlayError GetOverlayInputMethod(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod *peInputMethod) = 0; - /** Sets the input settings for the specified overlay. */ - virtual EVROverlayError SetOverlayInputMethod( VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod eInputMethod ) = 0; + /** Sets the input settings for the specified overlay. */ + virtual EVROverlayError SetOverlayInputMethod(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod eInputMethod) = 0; - /** Gets the mouse scaling factor that is used for mouse events. The actual texture may be a different size, but this is + /** Gets the mouse scaling factor that is used for mouse events. The actual texture may be a different size, but this is * typically the size of the underlying UI in pixels. */ - virtual EVROverlayError GetOverlayMouseScale( VROverlayHandle_t ulOverlayHandle, HmdVector2_t *pvecMouseScale ) = 0; + virtual EVROverlayError GetOverlayMouseScale(VROverlayHandle_t ulOverlayHandle, HmdVector2_t *pvecMouseScale) = 0; - /** Sets the mouse scaling factor that is used for mouse events. The actual texture may be a different size, but this is + /** Sets the mouse scaling factor that is used for mouse events. The actual texture may be a different size, but this is * typically the size of the underlying UI in pixels (not in world space). */ - virtual EVROverlayError SetOverlayMouseScale( VROverlayHandle_t ulOverlayHandle, const HmdVector2_t *pvecMouseScale ) = 0; + virtual EVROverlayError SetOverlayMouseScale(VROverlayHandle_t ulOverlayHandle, const HmdVector2_t *pvecMouseScale) = 0; - /** Computes the overlay-space pixel coordinates of where the ray intersects the overlay with the + /** Computes the overlay-space pixel coordinates of where the ray intersects the overlay with the * specified settings. Returns false if there is no intersection. */ - virtual bool ComputeOverlayIntersection( VROverlayHandle_t ulOverlayHandle, const VROverlayIntersectionParams_t *pParams, VROverlayIntersectionResults_t *pResults ) = 0; + virtual bool ComputeOverlayIntersection(VROverlayHandle_t ulOverlayHandle, const VROverlayIntersectionParams_t *pParams, VROverlayIntersectionResults_t *pResults) = 0; - /** Processes mouse input from the specified controller as though it were a mouse pointed at a compositor overlay with the + /** Processes mouse input from the specified controller as though it were a mouse pointed at a compositor overlay with the * specified settings. The controller is treated like a laser pointer on the -z axis. The point where the laser pointer would * intersect with the overlay is the mouse position, the trigger is left mouse, and the track pad is right mouse. * * Return true if the controller is pointed at the overlay and an event was generated. */ - virtual bool HandleControllerOverlayInteractionAsMouse( VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unControllerDeviceIndex ) = 0; + virtual bool HandleControllerOverlayInteractionAsMouse(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unControllerDeviceIndex) = 0; - /** Returns true if the specified overlay is the hover target. An overlay is the hover target when it is the last overlay "moused over" + /** Returns true if the specified overlay is the hover target. An overlay is the hover target when it is the last overlay "moused over" * by the virtual mouse pointer */ - virtual bool IsHoverTargetOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + virtual bool IsHoverTargetOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Returns the current Gamepad focus overlay */ - virtual vr::VROverlayHandle_t GetGamepadFocusOverlay() = 0; + /** Returns the current Gamepad focus overlay */ + virtual vr::VROverlayHandle_t GetGamepadFocusOverlay() = 0; - /** Sets the current Gamepad focus overlay */ - virtual EVROverlayError SetGamepadFocusOverlay( VROverlayHandle_t ulNewFocusOverlay ) = 0; + /** Sets the current Gamepad focus overlay */ + virtual EVROverlayError SetGamepadFocusOverlay(VROverlayHandle_t ulNewFocusOverlay) = 0; - /** Sets an overlay's neighbor. This will also set the neighbor of the "to" overlay + /** Sets an overlay's neighbor. This will also set the neighbor of the "to" overlay * to point back to the "from" overlay. If an overlay's neighbor is set to invalid both * ends will be cleared */ - virtual EVROverlayError SetOverlayNeighbor( EOverlayDirection eDirection, VROverlayHandle_t ulFrom, VROverlayHandle_t ulTo ) = 0; + virtual EVROverlayError SetOverlayNeighbor(EOverlayDirection eDirection, VROverlayHandle_t ulFrom, VROverlayHandle_t ulTo) = 0; - /** Changes the Gamepad focus from one overlay to one of its neighbors. Returns VROverlayError_NoNeighbor if there is no + /** Changes the Gamepad focus from one overlay to one of its neighbors. Returns VROverlayError_NoNeighbor if there is no * neighbor in that direction */ - virtual EVROverlayError MoveGamepadFocusToNeighbor( EOverlayDirection eDirection, VROverlayHandle_t ulFrom ) = 0; + virtual EVROverlayError MoveGamepadFocusToNeighbor(EOverlayDirection eDirection, VROverlayHandle_t ulFrom) = 0; - // --------------------------------------------- - // Overlay texture methods - // --------------------------------------------- + // --------------------------------------------- + // Overlay texture methods + // --------------------------------------------- - /** Texture to draw for the overlay. This function can only be called by the overlay's creator or renderer process (see SetOverlayRenderingPid) . + /** Texture to draw for the overlay. This function can only be called by the overlay's creator or renderer process (see SetOverlayRenderingPid) . * * OpenGL dirty state: * glBindTexture */ - virtual EVROverlayError SetOverlayTexture( VROverlayHandle_t ulOverlayHandle, const Texture_t *pTexture ) = 0; + virtual EVROverlayError SetOverlayTexture(VROverlayHandle_t ulOverlayHandle, const Texture_t *pTexture) = 0; - /** Use this to tell the overlay system to release the texture set for this overlay. */ - virtual EVROverlayError ClearOverlayTexture( VROverlayHandle_t ulOverlayHandle ) = 0; + /** Use this to tell the overlay system to release the texture set for this overlay. */ + virtual EVROverlayError ClearOverlayTexture(VROverlayHandle_t ulOverlayHandle) = 0; - /** Separate interface for providing the data as a stream of bytes, but there is an upper bound on data + /** Separate interface for providing the data as a stream of bytes, but there is an upper bound on data * that can be sent. This function can only be called by the overlay's renderer process. */ - virtual EVROverlayError SetOverlayRaw( VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unWidth, uint32_t unHeight, uint32_t unDepth ) = 0; + virtual EVROverlayError SetOverlayRaw(VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unWidth, uint32_t unHeight, uint32_t unDepth) = 0; - /** Separate interface for providing the image through a filename: can be png or jpg, and should not be bigger than 1920x1080. + /** Separate interface for providing the image through a filename: can be png or jpg, and should not be bigger than 1920x1080. * This function can only be called by the overlay's renderer process */ - virtual EVROverlayError SetOverlayFromFile( VROverlayHandle_t ulOverlayHandle, const char *pchFilePath ) = 0; + virtual EVROverlayError SetOverlayFromFile(VROverlayHandle_t ulOverlayHandle, const char *pchFilePath) = 0; - /** Get the native texture handle/device for an overlay you have created. + /** Get the native texture handle/device for an overlay you have created. * On windows this handle will be a ID3D11ShaderResourceView with a ID3D11Texture2D bound. * * The texture will always be sized to match the backing texture you supplied in SetOverlayTexture above. @@ -2928,98 +2869,97 @@ namespace vr * pNativeTextureHandle is an OUTPUT, it will be a pointer to a ID3D11ShaderResourceView *. * pNativeTextureRef is an INPUT and should be a ID3D11Resource *. The device used by pNativeTextureRef will be used to bind pNativeTextureHandle. */ - virtual EVROverlayError GetOverlayTexture( VROverlayHandle_t ulOverlayHandle, void **pNativeTextureHandle, void *pNativeTextureRef, uint32_t *pWidth, uint32_t *pHeight, uint32_t *pNativeFormat, ETextureType *pAPIType, EColorSpace *pColorSpace, VRTextureBounds_t *pTextureBounds ) = 0; + virtual EVROverlayError GetOverlayTexture(VROverlayHandle_t ulOverlayHandle, void **pNativeTextureHandle, void *pNativeTextureRef, uint32_t *pWidth, uint32_t *pHeight, uint32_t *pNativeFormat, ETextureType *pAPIType, EColorSpace *pColorSpace, VRTextureBounds_t *pTextureBounds) = 0; - /** Release the pNativeTextureHandle provided from the GetOverlayTexture call, this allows the system to free the underlying GPU resources for this object, + /** Release the pNativeTextureHandle provided from the GetOverlayTexture call, this allows the system to free the underlying GPU resources for this object, * so only do it once you stop rendering this texture. */ - virtual EVROverlayError ReleaseNativeOverlayHandle( VROverlayHandle_t ulOverlayHandle, void *pNativeTextureHandle ) = 0; + virtual EVROverlayError ReleaseNativeOverlayHandle(VROverlayHandle_t ulOverlayHandle, void *pNativeTextureHandle) = 0; - /** Get the size of the overlay texture */ - virtual EVROverlayError GetOverlayTextureSize( VROverlayHandle_t ulOverlayHandle, uint32_t *pWidth, uint32_t *pHeight ) = 0; + /** Get the size of the overlay texture */ + virtual EVROverlayError GetOverlayTextureSize(VROverlayHandle_t ulOverlayHandle, uint32_t *pWidth, uint32_t *pHeight) = 0; - // ---------------------------------------------- - // Dashboard Overlay Methods - // ---------------------------------------------- + // ---------------------------------------------- + // Dashboard Overlay Methods + // ---------------------------------------------- - /** Creates a dashboard overlay and returns its handle */ - virtual EVROverlayError CreateDashboardOverlay( const char *pchOverlayKey, const char *pchOverlayFriendlyName, VROverlayHandle_t * pMainHandle, VROverlayHandle_t *pThumbnailHandle ) = 0; + /** Creates a dashboard overlay and returns its handle */ + virtual EVROverlayError CreateDashboardOverlay(const char *pchOverlayKey, const char *pchOverlayFriendlyName, VROverlayHandle_t *pMainHandle, VROverlayHandle_t *pThumbnailHandle) = 0; - /** Returns true if the dashboard is visible */ - virtual bool IsDashboardVisible() = 0; + /** Returns true if the dashboard is visible */ + virtual bool IsDashboardVisible() = 0; - /** returns true if the dashboard is visible and the specified overlay is the active system Overlay */ - virtual bool IsActiveDashboardOverlay( VROverlayHandle_t ulOverlayHandle ) = 0; + /** returns true if the dashboard is visible and the specified overlay is the active system Overlay */ + virtual bool IsActiveDashboardOverlay(VROverlayHandle_t ulOverlayHandle) = 0; - /** Sets the dashboard overlay to only appear when the specified process ID has scene focus */ - virtual EVROverlayError SetDashboardOverlaySceneProcess( VROverlayHandle_t ulOverlayHandle, uint32_t unProcessId ) = 0; + /** Sets the dashboard overlay to only appear when the specified process ID has scene focus */ + virtual EVROverlayError SetDashboardOverlaySceneProcess(VROverlayHandle_t ulOverlayHandle, uint32_t unProcessId) = 0; - /** Gets the process ID that this dashboard overlay requires to have scene focus */ - virtual EVROverlayError GetDashboardOverlaySceneProcess( VROverlayHandle_t ulOverlayHandle, uint32_t *punProcessId ) = 0; + /** Gets the process ID that this dashboard overlay requires to have scene focus */ + virtual EVROverlayError GetDashboardOverlaySceneProcess(VROverlayHandle_t ulOverlayHandle, uint32_t *punProcessId) = 0; - /** Shows the dashboard. */ - virtual void ShowDashboard( const char *pchOverlayToShow ) = 0; + /** Shows the dashboard. */ + virtual void ShowDashboard(const char *pchOverlayToShow) = 0; - /** Returns the tracked device that has the laser pointer in the dashboard */ - virtual vr::TrackedDeviceIndex_t GetPrimaryDashboardDevice() = 0; + /** Returns the tracked device that has the laser pointer in the dashboard */ + virtual vr::TrackedDeviceIndex_t GetPrimaryDashboardDevice() = 0; - // --------------------------------------------- - // Keyboard methods - // --------------------------------------------- - - /** Show the virtual keyboard to accept input **/ - virtual EVROverlayError ShowKeyboard( EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32_t unCharMax, const char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue ) = 0; + // --------------------------------------------- + // Keyboard methods + // --------------------------------------------- - virtual EVROverlayError ShowKeyboardForOverlay( VROverlayHandle_t ulOverlayHandle, EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32_t unCharMax, const char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue ) = 0; + /** Show the virtual keyboard to accept input **/ + virtual EVROverlayError ShowKeyboard(EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32_t unCharMax, const char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue) = 0; - /** Get the text that was entered into the text input **/ - virtual uint32_t GetKeyboardText( VR_OUT_STRING() char *pchText, uint32_t cchText ) = 0; + virtual EVROverlayError ShowKeyboardForOverlay(VROverlayHandle_t ulOverlayHandle, EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, const char *pchDescription, uint32_t unCharMax, const char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue) = 0; - /** Hide the virtual keyboard **/ - virtual void HideKeyboard() = 0; + /** Get the text that was entered into the text input **/ + virtual uint32_t GetKeyboardText(VR_OUT_STRING() char *pchText, uint32_t cchText) = 0; - /** Set the position of the keyboard in world space **/ - virtual void SetKeyboardTransformAbsolute( ETrackingUniverseOrigin eTrackingOrigin, const HmdMatrix34_t *pmatTrackingOriginToKeyboardTransform ) = 0; + /** Hide the virtual keyboard **/ + virtual void HideKeyboard() = 0; - /** Set the position of the keyboard in overlay space by telling it to avoid a rectangle in the overlay. Rectangle coords have (0,0) in the bottom left **/ - virtual void SetKeyboardPositionForOverlay( VROverlayHandle_t ulOverlayHandle, HmdRect2_t avoidRect ) = 0; + /** Set the position of the keyboard in world space **/ + virtual void SetKeyboardTransformAbsolute(ETrackingUniverseOrigin eTrackingOrigin, const HmdMatrix34_t *pmatTrackingOriginToKeyboardTransform) = 0; - // --------------------------------------------- - // Overlay input methods - // --------------------------------------------- + /** Set the position of the keyboard in overlay space by telling it to avoid a rectangle in the overlay. Rectangle coords have (0,0) in the bottom left **/ + virtual void SetKeyboardPositionForOverlay(VROverlayHandle_t ulOverlayHandle, HmdRect2_t avoidRect) = 0; - /** Sets a list of primitives to be used for controller ray intersection + // --------------------------------------------- + // Overlay input methods + // --------------------------------------------- + + /** Sets a list of primitives to be used for controller ray intersection * typically the size of the underlying UI in pixels (not in world space). */ - virtual EVROverlayError SetOverlayIntersectionMask( VROverlayHandle_t ulOverlayHandle, VROverlayIntersectionMaskPrimitive_t *pMaskPrimitives, uint32_t unNumMaskPrimitives, uint32_t unPrimitiveSize = sizeof( VROverlayIntersectionMaskPrimitive_t ) ) = 0; + virtual EVROverlayError SetOverlayIntersectionMask(VROverlayHandle_t ulOverlayHandle, VROverlayIntersectionMaskPrimitive_t *pMaskPrimitives, uint32_t unNumMaskPrimitives, uint32_t unPrimitiveSize = sizeof(VROverlayIntersectionMaskPrimitive_t)) = 0; - virtual EVROverlayError GetOverlayFlags( VROverlayHandle_t ulOverlayHandle, uint32_t *pFlags ) = 0; + virtual EVROverlayError GetOverlayFlags(VROverlayHandle_t ulOverlayHandle, uint32_t *pFlags) = 0; - // --------------------------------------------- - // Message box methods - // --------------------------------------------- + // --------------------------------------------- + // Message box methods + // --------------------------------------------- - /** Show the message overlay. This will block and return you a result. **/ - virtual VRMessageOverlayResponse ShowMessageOverlay( const char* pchText, const char* pchCaption, const char* pchButton0Text, const char* pchButton1Text = nullptr, const char* pchButton2Text = nullptr, const char* pchButton3Text = nullptr ) = 0; + /** Show the message overlay. This will block and return you a result. **/ + virtual VRMessageOverlayResponse ShowMessageOverlay(const char *pchText, const char *pchCaption, const char *pchButton0Text, const char *pchButton1Text = nullptr, const char *pchButton2Text = nullptr, const char *pchButton3Text = nullptr) = 0; - /** If the calling process owns the overlay and it's open, this will close it. **/ - virtual void CloseMessageOverlay() = 0; - }; + /** If the calling process owns the overlay and it's open, this will close it. **/ + virtual void CloseMessageOverlay() = 0; +}; - static const char * const IVROverlay_Version = "IVROverlay_016"; +static const char *const IVROverlay_Version = "IVROverlay_016"; -} // namespace vr +} // namespace vr // ivrrendermodels.h namespace vr { +static const char *const k_pch_Controller_Component_GDC2015 = "gdc2015"; // Canonical coordinate system of the gdc 2015 wired controller, provided for backwards compatibility +static const char *const k_pch_Controller_Component_Base = "base"; // For controllers with an unambiguous 'base'. +static const char *const k_pch_Controller_Component_Tip = "tip"; // For controllers with an unambiguous 'tip' (used for 'laser-pointing') +static const char *const k_pch_Controller_Component_HandGrip = "handgrip"; // Neutral, ambidextrous hand-pose when holding controller. On plane between neutrally posed index finger and thumb +static const char *const k_pch_Controller_Component_Status = "status"; // 1:1 aspect ratio status area, with canonical [0,1] uv mapping -static const char * const k_pch_Controller_Component_GDC2015 = "gdc2015"; // Canonical coordinate system of the gdc 2015 wired controller, provided for backwards compatibility -static const char * const k_pch_Controller_Component_Base = "base"; // For controllers with an unambiguous 'base'. -static const char * const k_pch_Controller_Component_Tip = "tip"; // For controllers with an unambiguous 'tip' (used for 'laser-pointing') -static const char * const k_pch_Controller_Component_HandGrip = "handgrip"; // Neutral, ambidextrous hand-pose when holding controller. On plane between neutrally posed index finger and thumb -static const char * const k_pch_Controller_Component_Status = "status"; // 1:1 aspect ratio status area, with canonical [0,1] uv mapping - -#pragma pack( push, 8 ) +#pragma pack(push, 8) /** Errors that can occur with the VR compositor */ enum EVRRenderModelError @@ -3062,25 +3002,25 @@ struct RenderModel_ComponentState_t /** A single vertex in a render model */ struct RenderModel_Vertex_t { - HmdVector3_t vPosition; // position in meters in device space + HmdVector3_t vPosition; // position in meters in device space HmdVector3_t vNormal; float rfTextureCoord[2]; }; /** A texture map for use on a render model */ -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif struct RenderModel_TextureMap_t { - uint16_t unWidth, unHeight; // width and height of the texture map in pixels - const uint8_t *rubTextureMapData; // Map texture data. All textures are RGBA with 8 bits per channel per pixel. Data size is width * height * 4ub + uint16_t unWidth, unHeight; // width and height of the texture map in pixels + const uint8_t *rubTextureMapData; // Map texture data. All textures are RGBA with 8 bits per channel per pixel. Data size is width * height * 4ub }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif /** Session unique texture identifier. Rendermodels which share the same texture will have the same id. @@ -3090,36 +3030,34 @@ typedef int32_t TextureID_t; const TextureID_t INVALID_TEXTURE_ID = -1; -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif struct RenderModel_t { - const RenderModel_Vertex_t *rVertexData; // Vertex data for the mesh - uint32_t unVertexCount; // Number of vertices in the vertex data - const uint16_t *rIndexData; // Indices into the vertex data for each triangle - uint32_t unTriangleCount; // Number of triangles in the mesh. Index count is 3 * TriangleCount - TextureID_t diffuseTextureId; // Session unique texture identifier. Rendermodels which share the same texture will have the same id. <0 == texture not present + const RenderModel_Vertex_t *rVertexData; // Vertex data for the mesh + uint32_t unVertexCount; // Number of vertices in the vertex data + const uint16_t *rIndexData; // Indices into the vertex data for each triangle + uint32_t unTriangleCount; // Number of triangles in the mesh. Index count is 3 * TriangleCount + TextureID_t diffuseTextureId; // Session unique texture identifier. Rendermodels which share the same texture will have the same id. <0 == texture not present }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif - struct RenderModel_ControllerMode_State_t { - bool bScrollWheelVisible; // is this controller currently set to be in a scroll wheel mode + bool bScrollWheelVisible; // is this controller currently set to be in a scroll wheel mode }; -#pragma pack( pop ) +#pragma pack(pop) class IVRRenderModels { public: - /** Loads and returns a render model for use in the application. pchRenderModelName should be a render model name * from the Prop_RenderModelName_String property or an absolute path name to a render model on disk. * @@ -3129,37 +3067,36 @@ public: * * The method returns VRRenderModelError_Loading while the render model is still being loaded. * The method returns VRRenderModelError_None once loaded successfully, otherwise will return an error. */ - virtual EVRRenderModelError LoadRenderModel_Async( const char *pchRenderModelName, RenderModel_t **ppRenderModel ) = 0; + virtual EVRRenderModelError LoadRenderModel_Async(const char *pchRenderModelName, RenderModel_t **ppRenderModel) = 0; /** Frees a previously returned render model * It is safe to call this on a null ptr. */ - virtual void FreeRenderModel( RenderModel_t *pRenderModel ) = 0; + virtual void FreeRenderModel(RenderModel_t *pRenderModel) = 0; /** Loads and returns a texture for use in the application. */ - virtual EVRRenderModelError LoadTexture_Async( TextureID_t textureId, RenderModel_TextureMap_t **ppTexture ) = 0; + virtual EVRRenderModelError LoadTexture_Async(TextureID_t textureId, RenderModel_TextureMap_t **ppTexture) = 0; /** Frees a previously returned texture * It is safe to call this on a null ptr. */ - virtual void FreeTexture( RenderModel_TextureMap_t *pTexture ) = 0; + virtual void FreeTexture(RenderModel_TextureMap_t *pTexture) = 0; /** Creates a D3D11 texture and loads data into it. */ - virtual EVRRenderModelError LoadTextureD3D11_Async( TextureID_t textureId, void *pD3D11Device, void **ppD3D11Texture2D ) = 0; + virtual EVRRenderModelError LoadTextureD3D11_Async(TextureID_t textureId, void *pD3D11Device, void **ppD3D11Texture2D) = 0; /** Helper function to copy the bits into an existing texture. */ - virtual EVRRenderModelError LoadIntoTextureD3D11_Async( TextureID_t textureId, void *pDstTexture ) = 0; + virtual EVRRenderModelError LoadIntoTextureD3D11_Async(TextureID_t textureId, void *pDstTexture) = 0; /** Use this to free textures created with LoadTextureD3D11_Async instead of calling Release on them. */ - virtual void FreeTextureD3D11( void *pD3D11Texture2D ) = 0; + virtual void FreeTextureD3D11(void *pD3D11Texture2D) = 0; /** Use this to get the names of available render models. Index does not correlate to a tracked device index, but * is only used for iterating over all available render models. If the index is out of range, this function will return 0. * Otherwise, it will return the size of the buffer required for the name. */ - virtual uint32_t GetRenderModelName( uint32_t unRenderModelIndex, VR_OUT_STRING() char *pchRenderModelName, uint32_t unRenderModelNameLen ) = 0; + virtual uint32_t GetRenderModelName(uint32_t unRenderModelIndex, VR_OUT_STRING() char *pchRenderModelName, uint32_t unRenderModelNameLen) = 0; /** Returns the number of available render models. */ virtual uint32_t GetRenderModelCount() = 0; - /** Returns the number of components of the specified render model. * Components are useful when client application wish to draw, label, or otherwise interact with components of tracked objects. * Examples controller components: @@ -3167,23 +3104,23 @@ public: * non-renderable things which include coordinate systems such as 'tip', 'base', a neutral controller agnostic hand-pose * If all controller components are enumerated and rendered, it will be equivalent to drawing the traditional render model * Returns 0 if components not supported, >0 otherwise */ - virtual uint32_t GetComponentCount( const char *pchRenderModelName ) = 0; + virtual uint32_t GetComponentCount(const char *pchRenderModelName) = 0; /** Use this to get the names of available components. Index does not correlate to a tracked device index, but * is only used for iterating over all available components. If the index is out of range, this function will return 0. * Otherwise, it will return the size of the buffer required for the name. */ - virtual uint32_t GetComponentName( const char *pchRenderModelName, uint32_t unComponentIndex, VR_OUT_STRING( ) char *pchComponentName, uint32_t unComponentNameLen ) = 0; + virtual uint32_t GetComponentName(const char *pchRenderModelName, uint32_t unComponentIndex, VR_OUT_STRING() char *pchComponentName, uint32_t unComponentNameLen) = 0; /** Get the button mask for all buttons associated with this component * If no buttons (or axes) are associated with this component, return 0 * Note: multiple components may be associated with the same button. Ex: two grip buttons on a single controller. * Note: A single component may be associated with multiple buttons. Ex: A trackpad which also provides "D-pad" functionality */ - virtual uint64_t GetComponentButtonMask( const char *pchRenderModelName, const char *pchComponentName ) = 0; + virtual uint64_t GetComponentButtonMask(const char *pchRenderModelName, const char *pchComponentName) = 0; /** Use this to get the render model name for the specified rendermode/component combination, to be passed to LoadRenderModel. * If the component name is out of range, this function will return 0. * Otherwise, it will return the size of the buffer required for the name. */ - virtual uint32_t GetComponentRenderModelName( const char *pchRenderModelName, const char *pchComponentName, VR_OUT_STRING( ) char *pchComponentRenderModelName, uint32_t unComponentRenderModelNameLen ) = 0; + virtual uint32_t GetComponentRenderModelName(const char *pchRenderModelName, const char *pchComponentName, VR_OUT_STRING() char *pchComponentRenderModelName, uint32_t unComponentRenderModelNameLen) = 0; /** Use this to query information about the component, as a function of the controller state. * @@ -3193,93 +3130,87 @@ public: * If the pchRenderModelName or pchComponentName is invalid, this will return false (and transforms will be set to identity). * Otherwise, return true * Note: For dynamic objects, visibility may be dynamic. (I.e., true/false will be returned based on controller state and controller mode state ) */ - virtual bool GetComponentState( const char *pchRenderModelName, const char *pchComponentName, const vr::VRControllerState_t *pControllerState, const RenderModel_ControllerMode_State_t *pState, RenderModel_ComponentState_t *pComponentState ) = 0; + virtual bool GetComponentState(const char *pchRenderModelName, const char *pchComponentName, const vr::VRControllerState_t *pControllerState, const RenderModel_ControllerMode_State_t *pState, RenderModel_ComponentState_t *pComponentState) = 0; /** Returns true if the render model has a component with the specified name */ - virtual bool RenderModelHasComponent( const char *pchRenderModelName, const char *pchComponentName ) = 0; + virtual bool RenderModelHasComponent(const char *pchRenderModelName, const char *pchComponentName) = 0; /** Returns the URL of the thumbnail image for this rendermodel */ - virtual uint32_t GetRenderModelThumbnailURL( const char *pchRenderModelName, VR_OUT_STRING() char *pchThumbnailURL, uint32_t unThumbnailURLLen, vr::EVRRenderModelError *peError ) = 0; + virtual uint32_t GetRenderModelThumbnailURL(const char *pchRenderModelName, VR_OUT_STRING() char *pchThumbnailURL, uint32_t unThumbnailURLLen, vr::EVRRenderModelError *peError) = 0; /** Provides a render model path that will load the unskinned model if the model name provided has been replace by the user. If the model * hasn't been replaced the path value will still be a valid path to load the model. Pass this to LoadRenderModel_Async, etc. to load the * model. */ - virtual uint32_t GetRenderModelOriginalPath( const char *pchRenderModelName, VR_OUT_STRING() char *pchOriginalPath, uint32_t unOriginalPathLen, vr::EVRRenderModelError *peError ) = 0; + virtual uint32_t GetRenderModelOriginalPath(const char *pchRenderModelName, VR_OUT_STRING() char *pchOriginalPath, uint32_t unOriginalPathLen, vr::EVRRenderModelError *peError) = 0; /** Returns a string for a render model error */ - virtual const char *GetRenderModelErrorNameFromEnum( vr::EVRRenderModelError error ) = 0; + virtual const char *GetRenderModelErrorNameFromEnum(vr::EVRRenderModelError error) = 0; }; -static const char * const IVRRenderModels_Version = "IVRRenderModels_005"; - -} +static const char *const IVRRenderModels_Version = "IVRRenderModels_005"; +} // namespace vr // ivrextendeddisplay.h namespace vr { - - /** NOTE: Use of this interface is not recommended in production applications. It will not work for displays which use +/** NOTE: Use of this interface is not recommended in production applications. It will not work for displays which use * direct-to-display mode. Creating our own window is also incompatible with the VR compositor and is not available when the compositor is running. */ - class IVRExtendedDisplay - { - public: +class IVRExtendedDisplay +{ +public: + /** Size and position that the window needs to be on the VR display. */ + virtual void GetWindowBounds(int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight) = 0; - /** Size and position that the window needs to be on the VR display. */ - virtual void GetWindowBounds( int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; + /** Gets the viewport in the frame buffer to draw the output of the distortion into */ + virtual void GetEyeOutputViewport(EVREye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight) = 0; - /** Gets the viewport in the frame buffer to draw the output of the distortion into */ - virtual void GetEyeOutputViewport( EVREye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; - - /** [D3D10/11 Only] + /** [D3D10/11 Only] * Returns the adapter index and output index that the user should pass into EnumAdapters and EnumOutputs * to create the device and swap chain in DX10 and DX11. If an error occurs both indices will be set to -1. */ - virtual void GetDXGIOutputInfo( int32_t *pnAdapterIndex, int32_t *pnAdapterOutputIndex ) = 0; + virtual void GetDXGIOutputInfo(int32_t *pnAdapterIndex, int32_t *pnAdapterOutputIndex) = 0; +}; - }; - - static const char * const IVRExtendedDisplay_Version = "IVRExtendedDisplay_001"; - -} +static const char *const IVRExtendedDisplay_Version = "IVRExtendedDisplay_001"; +} // namespace vr // ivrtrackedcamera.h namespace vr { - class IVRTrackedCamera { public: /** Returns a string for an error */ - virtual const char *GetCameraErrorNameFromEnum( vr::EVRTrackedCameraError eCameraError ) = 0; + virtual const char *GetCameraErrorNameFromEnum(vr::EVRTrackedCameraError eCameraError) = 0; /** For convenience, same as tracked property request Prop_HasCamera_Bool */ - virtual vr::EVRTrackedCameraError HasCamera( vr::TrackedDeviceIndex_t nDeviceIndex, bool *pHasCamera ) = 0; + virtual vr::EVRTrackedCameraError HasCamera(vr::TrackedDeviceIndex_t nDeviceIndex, bool *pHasCamera) = 0; /** Gets size of the image frame. */ - virtual vr::EVRTrackedCameraError GetCameraFrameSize( vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, uint32_t *pnWidth, uint32_t *pnHeight, uint32_t *pnFrameBufferSize ) = 0; + virtual vr::EVRTrackedCameraError GetCameraFrameSize(vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, uint32_t *pnWidth, uint32_t *pnHeight, uint32_t *pnFrameBufferSize) = 0; - virtual vr::EVRTrackedCameraError GetCameraIntrinsics( vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, vr::HmdVector2_t *pFocalLength, vr::HmdVector2_t *pCenter ) = 0; + virtual vr::EVRTrackedCameraError GetCameraIntrinsics(vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, vr::HmdVector2_t *pFocalLength, vr::HmdVector2_t *pCenter) = 0; - virtual vr::EVRTrackedCameraError GetCameraProjection( vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, vr::HmdMatrix44_t *pProjection ) = 0; + virtual vr::EVRTrackedCameraError GetCameraProjection(vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, vr::HmdMatrix44_t *pProjection) = 0; /** Acquiring streaming service permits video streaming for the caller. Releasing hints the system that video services do not need to be maintained for this client. * If the camera has not already been activated, a one time spin up may incur some auto exposure as well as initial streaming frame delays. * The camera should be considered a global resource accessible for shared consumption but not exclusive to any caller. * The camera may go inactive due to lack of active consumers or headset idleness. */ - virtual vr::EVRTrackedCameraError AcquireVideoStreamingService( vr::TrackedDeviceIndex_t nDeviceIndex, vr::TrackedCameraHandle_t *pHandle ) = 0; - virtual vr::EVRTrackedCameraError ReleaseVideoStreamingService( vr::TrackedCameraHandle_t hTrackedCamera ) = 0; + virtual vr::EVRTrackedCameraError AcquireVideoStreamingService(vr::TrackedDeviceIndex_t nDeviceIndex, vr::TrackedCameraHandle_t *pHandle) = 0; + virtual vr::EVRTrackedCameraError ReleaseVideoStreamingService(vr::TrackedCameraHandle_t hTrackedCamera) = 0; /** Copies the image frame into a caller's provided buffer. The image data is currently provided as RGBA data, 4 bytes per pixel. * A caller can provide null for the framebuffer or frameheader if not desired. Requesting the frame header first, followed by the frame buffer allows * the caller to determine if the frame as advanced per the frame header sequence. * If there is no frame available yet, due to initial camera spinup or re-activation, the error will be VRTrackedCameraError_NoFrameAvailable. * Ideally a caller should be polling at ~16ms intervals */ - virtual vr::EVRTrackedCameraError GetVideoStreamFrameBuffer( vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, void *pFrameBuffer, uint32_t nFrameBufferSize, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize ) = 0; + virtual vr::EVRTrackedCameraError GetVideoStreamFrameBuffer(vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, void *pFrameBuffer, uint32_t nFrameBufferSize, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize) = 0; /** Gets size of the image frame. */ - virtual vr::EVRTrackedCameraError GetVideoStreamTextureSize( vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, vr::VRTextureBounds_t *pTextureBounds, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; + virtual vr::EVRTrackedCameraError GetVideoStreamTextureSize(vr::TrackedDeviceIndex_t nDeviceIndex, vr::EVRTrackedCameraFrameType eFrameType, vr::VRTextureBounds_t *pTextureBounds, uint32_t *pnWidth, uint32_t *pnHeight) = 0; /** Access a shared D3D11 texture for the specified tracked camera stream. * The camera frame type VRTrackedCameraFrameType_Undistorted is not supported directly as a shared texture. It is an interior subregion of the shared texture VRTrackedCameraFrameType_MaximumUndistorted. @@ -3287,31 +3218,29 @@ public: * VRTrackedCameraFrameType_MaximumUndistorted to provide the texture. The VRTrackedCameraFrameType_MaximumUndistorted will yield an image where the invalid regions are decoded * by the alpha channel having a zero component. The valid regions all have a non-zero alpha component. The subregion as described by VRTrackedCameraFrameType_Undistorted * guarantees a rectangle where all pixels are valid. */ - virtual vr::EVRTrackedCameraError GetVideoStreamTextureD3D11( vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize ) = 0; + virtual vr::EVRTrackedCameraError GetVideoStreamTextureD3D11(vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize) = 0; /** Access a shared GL texture for the specified tracked camera stream */ - virtual vr::EVRTrackedCameraError GetVideoStreamTextureGL( vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, vr::glUInt_t *pglTextureId, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize ) = 0; - virtual vr::EVRTrackedCameraError ReleaseVideoStreamTextureGL( vr::TrackedCameraHandle_t hTrackedCamera, vr::glUInt_t glTextureId ) = 0; + virtual vr::EVRTrackedCameraError GetVideoStreamTextureGL(vr::TrackedCameraHandle_t hTrackedCamera, vr::EVRTrackedCameraFrameType eFrameType, vr::glUInt_t *pglTextureId, vr::CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize) = 0; + virtual vr::EVRTrackedCameraError ReleaseVideoStreamTextureGL(vr::TrackedCameraHandle_t hTrackedCamera, vr::glUInt_t glTextureId) = 0; }; -static const char * const IVRTrackedCamera_Version = "IVRTrackedCamera_003"; - -} // namespace vr +static const char *const IVRTrackedCamera_Version = "IVRTrackedCamera_003"; +} // namespace vr // ivrscreenshots.h namespace vr { - /** Errors that can occur with the VR compositor */ enum EVRScreenshotError { - VRScreenshotError_None = 0, - VRScreenshotError_RequestFailed = 1, - VRScreenshotError_IncompatibleVersion = 100, - VRScreenshotError_NotFound = 101, - VRScreenshotError_BufferTooSmall = 102, - VRScreenshotError_ScreenshotAlreadyInProgress = 108, + VRScreenshotError_None = 0, + VRScreenshotError_RequestFailed = 1, + VRScreenshotError_IncompatibleVersion = 100, + VRScreenshotError_NotFound = 101, + VRScreenshotError_BufferTooSmall = 102, + VRScreenshotError_ScreenshotAlreadyInProgress = 108, }; /** Allows the application to generate screenshots */ @@ -3349,7 +3278,7 @@ public: * The destination file names do not need an extension, * will be replaced with the correct one for the format * which is currently .png. */ - virtual vr::EVRScreenshotError RequestScreenshot( vr::ScreenshotHandle_t *pOutScreenshotHandle, vr::EVRScreenshotType type, const char *pchPreviewFilename, const char *pchVRFilename ) = 0; + virtual vr::EVRScreenshotError RequestScreenshot(vr::ScreenshotHandle_t *pOutScreenshotHandle, vr::EVRScreenshotType type, const char *pchPreviewFilename, const char *pchVRFilename) = 0; /** Called by the running VR application to indicate that it * wishes to be in charge of screenshots. If the @@ -3359,23 +3288,23 @@ public: * Once hooked your application will receive a * VREvent_RequestScreenshot event when the user presses the * buttons to take a screenshot. */ - virtual vr::EVRScreenshotError HookScreenshot( VR_ARRAY_COUNT( numTypes ) const vr::EVRScreenshotType *pSupportedTypes, int numTypes ) = 0; + virtual vr::EVRScreenshotError HookScreenshot(VR_ARRAY_COUNT(numTypes) const vr::EVRScreenshotType *pSupportedTypes, int numTypes) = 0; /** When your application receives a * VREvent_RequestScreenshot event, call these functions to get * the details of the screenshot request. */ - virtual vr::EVRScreenshotType GetScreenshotPropertyType( vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotError *pError ) = 0; + virtual vr::EVRScreenshotType GetScreenshotPropertyType(vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotError *pError) = 0; /** Get the filename for the preview or vr image (see * vr::EScreenshotPropertyFilenames). The return value is * the size of the string. */ - virtual uint32_t GetScreenshotPropertyFilename( vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotPropertyFilenames filenameType, VR_OUT_STRING() char *pchFilename, uint32_t cchFilename, vr::EVRScreenshotError *pError ) = 0; + virtual uint32_t GetScreenshotPropertyFilename(vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotPropertyFilenames filenameType, VR_OUT_STRING() char *pchFilename, uint32_t cchFilename, vr::EVRScreenshotError *pError) = 0; /** Call this if the application is taking the screen shot * will take more than a few ms processing. This will result * in an overlay being presented that shows a completion * bar. */ - virtual vr::EVRScreenshotError UpdateScreenshotProgress( vr::ScreenshotHandle_t screenshotHandle, float flProgress ) = 0; + virtual vr::EVRScreenshotError UpdateScreenshotProgress(vr::ScreenshotHandle_t screenshotHandle, float flProgress) = 0; /** Tells the compositor to take an internal screenshot of * type VRScreenshotType_Stereo. It will take the current @@ -3384,7 +3313,7 @@ public: * for the VR image. * This is similar to request screenshot, but doesn't ever * talk to the application, just takes the shot and submits. */ - virtual vr::EVRScreenshotError TakeStereoScreenshot( vr::ScreenshotHandle_t *pOutScreenshotHandle, const char *pchPreviewFilename, const char *pchVRFilename ) = 0; + virtual vr::EVRScreenshotError TakeStereoScreenshot(vr::ScreenshotHandle_t *pOutScreenshotHandle, const char *pchPreviewFilename, const char *pchVRFilename) = 0; /** Submit the completed screenshot. If Steam is running * this will call into the Steam client and upload the @@ -3397,67 +3326,59 @@ public: * screenshotHandle can be k_unScreenshotHandleInvalid if this * was a new shot taking by the app to be saved and not * initiated by a user (achievement earned or something) */ - virtual vr::EVRScreenshotError SubmitScreenshot( vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotType type, const char *pchSourcePreviewFilename, const char *pchSourceVRFilename ) = 0; + virtual vr::EVRScreenshotError SubmitScreenshot(vr::ScreenshotHandle_t screenshotHandle, vr::EVRScreenshotType type, const char *pchSourcePreviewFilename, const char *pchSourceVRFilename) = 0; }; -static const char * const IVRScreenshots_Version = "IVRScreenshots_001"; - -} // namespace vr - +static const char *const IVRScreenshots_Version = "IVRScreenshots_001"; +} // namespace vr // ivrresources.h namespace vr { - class IVRResources { public: - // ------------------------------------ // Shared Resource Methods // ------------------------------------ /** Loads the specified resource into the provided buffer if large enough. * Returns the size in bytes of the buffer required to hold the specified resource. */ - virtual uint32_t LoadSharedResource( const char *pchResourceName, char *pchBuffer, uint32_t unBufferLen ) = 0; + virtual uint32_t LoadSharedResource(const char *pchResourceName, char *pchBuffer, uint32_t unBufferLen) = 0; /** Provides the full path to the specified resource. Resource names can include named directories for * drivers and other things, and this resolves all of those and returns the actual physical path. * pchResourceTypeDirectory is the subdirectory of resources to look in. */ - virtual uint32_t GetResourceFullPath( const char *pchResourceName, const char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen ) = 0; + virtual uint32_t GetResourceFullPath(const char *pchResourceName, const char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen) = 0; }; -static const char * const IVRResources_Version = "IVRResources_001"; +static const char *const IVRResources_Version = "IVRResources_001"; - -} +} // namespace vr // ivrdrivermanager.h namespace vr { - class IVRDriverManager { public: virtual uint32_t GetDriverCount() const = 0; /** Returns the length of the number of bytes necessary to hold this string including the trailing null. */ - virtual uint32_t GetDriverName( vr::DriverId_t nDriver, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize ) = 0; + virtual uint32_t GetDriverName(vr::DriverId_t nDriver, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize) = 0; }; -static const char * const IVRDriverManager_Version = "IVRDriverManager_001"; - -} // namespace vr +static const char *const IVRDriverManager_Version = "IVRDriverManager_001"; +} // namespace vr // End -#endif // _OPENVR_API - +#endif // _OPENVR_API namespace vr { - /** Finds the active installation of the VR API and initializes it. The provided path must be absolute +/** Finds the active installation of the VR API and initializes it. The provided path must be absolute * or relative to the current working directory. These are the local install versions of the equivalent * functions in steamvr.h and will work without a local Steam install. * @@ -3466,312 +3387,312 @@ namespace vr * * pStartupInfo is reserved for future use. */ - inline IVRSystem *VR_Init( EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo = nullptr ); +inline IVRSystem *VR_Init(EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo = nullptr); - /** unloads vrclient.dll. Any interface pointers from the interface are +/** unloads vrclient.dll. Any interface pointers from the interface are * invalid after this point */ - inline void VR_Shutdown(); +inline void VR_Shutdown(); - /** Returns true if there is an HMD attached. This check is as lightweight as possible and +/** Returns true if there is an HMD attached. This check is as lightweight as possible and * can be called outside of VR_Init/VR_Shutdown. It should be used when an application wants * to know if initializing VR is a possibility but isn't ready to take that step yet. */ - VR_INTERFACE bool VR_CALLTYPE VR_IsHmdPresent(); +VR_INTERFACE bool VR_CALLTYPE VR_IsHmdPresent(); - /** Returns true if the OpenVR runtime is installed. */ - VR_INTERFACE bool VR_CALLTYPE VR_IsRuntimeInstalled(); +/** Returns true if the OpenVR runtime is installed. */ +VR_INTERFACE bool VR_CALLTYPE VR_IsRuntimeInstalled(); - /** Returns where the OpenVR runtime is installed. */ - VR_INTERFACE const char *VR_CALLTYPE VR_RuntimePath(); +/** Returns where the OpenVR runtime is installed. */ +VR_INTERFACE const char *VR_CALLTYPE VR_RuntimePath(); - /** Returns the name of the enum value for an EVRInitError. This function may be called outside of VR_Init()/VR_Shutdown(). */ - VR_INTERFACE const char *VR_CALLTYPE VR_GetVRInitErrorAsSymbol( EVRInitError error ); +/** Returns the name of the enum value for an EVRInitError. This function may be called outside of VR_Init()/VR_Shutdown(). */ +VR_INTERFACE const char *VR_CALLTYPE VR_GetVRInitErrorAsSymbol(EVRInitError error); - /** Returns an English string for an EVRInitError. Applications should call VR_GetVRInitErrorAsSymbol instead and +/** Returns an English string for an EVRInitError. Applications should call VR_GetVRInitErrorAsSymbol instead and * use that as a key to look up their own localized error message. This function may be called outside of VR_Init()/VR_Shutdown(). */ - VR_INTERFACE const char *VR_CALLTYPE VR_GetVRInitErrorAsEnglishDescription( EVRInitError error ); +VR_INTERFACE const char *VR_CALLTYPE VR_GetVRInitErrorAsEnglishDescription(EVRInitError error); - /** Returns the interface of the specified version. This method must be called after VR_Init. The +/** Returns the interface of the specified version. This method must be called after VR_Init. The * pointer returned is valid until VR_Shutdown is called. */ - VR_INTERFACE void *VR_CALLTYPE VR_GetGenericInterface( const char *pchInterfaceVersion, EVRInitError *peError ); +VR_INTERFACE void *VR_CALLTYPE VR_GetGenericInterface(const char *pchInterfaceVersion, EVRInitError *peError); - /** Returns whether the interface of the specified version exists. +/** Returns whether the interface of the specified version exists. */ - VR_INTERFACE bool VR_CALLTYPE VR_IsInterfaceVersionValid( const char *pchInterfaceVersion ); +VR_INTERFACE bool VR_CALLTYPE VR_IsInterfaceVersionValid(const char *pchInterfaceVersion); - /** Returns a token that represents whether the VR interface handles need to be reloaded */ - VR_INTERFACE uint32_t VR_CALLTYPE VR_GetInitToken(); +/** Returns a token that represents whether the VR interface handles need to be reloaded */ +VR_INTERFACE uint32_t VR_CALLTYPE VR_GetInitToken(); - // These typedefs allow old enum names from SDK 0.9.11 to be used in applications. - // They will go away in the future. - typedef EVRInitError HmdError; - typedef EVREye Hmd_Eye; - typedef EColorSpace ColorSpace; - typedef ETrackingResult HmdTrackingResult; - typedef ETrackedDeviceClass TrackedDeviceClass; - typedef ETrackingUniverseOrigin TrackingUniverseOrigin; - typedef ETrackedDeviceProperty TrackedDeviceProperty; - typedef ETrackedPropertyError TrackedPropertyError; - typedef EVRSubmitFlags VRSubmitFlags_t; - typedef EVRState VRState_t; - typedef ECollisionBoundsStyle CollisionBoundsStyle_t; - typedef EVROverlayError VROverlayError; - typedef EVRFirmwareError VRFirmwareError; - typedef EVRCompositorError VRCompositorError; - typedef EVRScreenshotError VRScreenshotsError; +// These typedefs allow old enum names from SDK 0.9.11 to be used in applications. +// They will go away in the future. +typedef EVRInitError HmdError; +typedef EVREye Hmd_Eye; +typedef EColorSpace ColorSpace; +typedef ETrackingResult HmdTrackingResult; +typedef ETrackedDeviceClass TrackedDeviceClass; +typedef ETrackingUniverseOrigin TrackingUniverseOrigin; +typedef ETrackedDeviceProperty TrackedDeviceProperty; +typedef ETrackedPropertyError TrackedPropertyError; +typedef EVRSubmitFlags VRSubmitFlags_t; +typedef EVRState VRState_t; +typedef ECollisionBoundsStyle CollisionBoundsStyle_t; +typedef EVROverlayError VROverlayError; +typedef EVRFirmwareError VRFirmwareError; +typedef EVRCompositorError VRCompositorError; +typedef EVRScreenshotError VRScreenshotsError; - inline uint32_t &VRToken() - { - static uint32_t token; - return token; - } - - class COpenVRContext - { - public: - COpenVRContext() { Clear(); } - void Clear(); - - inline void CheckClear() - { - if ( VRToken() != VR_GetInitToken() ) - { - Clear(); - VRToken() = VR_GetInitToken(); - } - } - - IVRSystem *VRSystem() - { - CheckClear(); - if ( m_pVRSystem == nullptr ) - { - EVRInitError eError; - m_pVRSystem = ( IVRSystem * )VR_GetGenericInterface( IVRSystem_Version, &eError ); - } - return m_pVRSystem; - } - IVRChaperone *VRChaperone() - { - CheckClear(); - if ( m_pVRChaperone == nullptr ) - { - EVRInitError eError; - m_pVRChaperone = ( IVRChaperone * )VR_GetGenericInterface( IVRChaperone_Version, &eError ); - } - return m_pVRChaperone; - } - - IVRChaperoneSetup *VRChaperoneSetup() - { - CheckClear(); - if ( m_pVRChaperoneSetup == nullptr ) - { - EVRInitError eError; - m_pVRChaperoneSetup = ( IVRChaperoneSetup * )VR_GetGenericInterface( IVRChaperoneSetup_Version, &eError ); - } - return m_pVRChaperoneSetup; - } - - IVRCompositor *VRCompositor() - { - CheckClear(); - if ( m_pVRCompositor == nullptr ) - { - EVRInitError eError; - m_pVRCompositor = ( IVRCompositor * )VR_GetGenericInterface( IVRCompositor_Version, &eError ); - } - return m_pVRCompositor; - } - - IVROverlay *VROverlay() - { - CheckClear(); - if ( m_pVROverlay == nullptr ) - { - EVRInitError eError; - m_pVROverlay = ( IVROverlay * )VR_GetGenericInterface( IVROverlay_Version, &eError ); - } - return m_pVROverlay; - } - - IVRResources *VRResources() - { - CheckClear(); - if ( m_pVRResources == nullptr ) - { - EVRInitError eError; - m_pVRResources = (IVRResources *)VR_GetGenericInterface( IVRResources_Version, &eError ); - } - return m_pVRResources; - } - - IVRScreenshots *VRScreenshots() - { - CheckClear(); - if ( m_pVRScreenshots == nullptr ) - { - EVRInitError eError; - m_pVRScreenshots = ( IVRScreenshots * )VR_GetGenericInterface( IVRScreenshots_Version, &eError ); - } - return m_pVRScreenshots; - } - - IVRRenderModels *VRRenderModels() - { - CheckClear(); - if ( m_pVRRenderModels == nullptr ) - { - EVRInitError eError; - m_pVRRenderModels = ( IVRRenderModels * )VR_GetGenericInterface( IVRRenderModels_Version, &eError ); - } - return m_pVRRenderModels; - } - - IVRExtendedDisplay *VRExtendedDisplay() - { - CheckClear(); - if ( m_pVRExtendedDisplay == nullptr ) - { - EVRInitError eError; - m_pVRExtendedDisplay = ( IVRExtendedDisplay * )VR_GetGenericInterface( IVRExtendedDisplay_Version, &eError ); - } - return m_pVRExtendedDisplay; - } - - IVRSettings *VRSettings() - { - CheckClear(); - if ( m_pVRSettings == nullptr ) - { - EVRInitError eError; - m_pVRSettings = ( IVRSettings * )VR_GetGenericInterface( IVRSettings_Version, &eError ); - } - return m_pVRSettings; - } - - IVRApplications *VRApplications() - { - CheckClear(); - if ( m_pVRApplications == nullptr ) - { - EVRInitError eError; - m_pVRApplications = ( IVRApplications * )VR_GetGenericInterface( IVRApplications_Version, &eError ); - } - return m_pVRApplications; - } - - IVRTrackedCamera *VRTrackedCamera() - { - CheckClear(); - if ( m_pVRTrackedCamera == nullptr ) - { - EVRInitError eError; - m_pVRTrackedCamera = ( IVRTrackedCamera * )VR_GetGenericInterface( IVRTrackedCamera_Version, &eError ); - } - return m_pVRTrackedCamera; - } - - IVRDriverManager *VRDriverManager() - { - CheckClear(); - if ( !m_pVRDriverManager ) - { - EVRInitError eError; - m_pVRDriverManager = ( IVRDriverManager * )VR_GetGenericInterface( IVRDriverManager_Version, &eError ); - } - return m_pVRDriverManager; - } - - private: - IVRSystem *m_pVRSystem; - IVRChaperone *m_pVRChaperone; - IVRChaperoneSetup *m_pVRChaperoneSetup; - IVRCompositor *m_pVRCompositor; - IVROverlay *m_pVROverlay; - IVRResources *m_pVRResources; - IVRRenderModels *m_pVRRenderModels; - IVRExtendedDisplay *m_pVRExtendedDisplay; - IVRSettings *m_pVRSettings; - IVRApplications *m_pVRApplications; - IVRTrackedCamera *m_pVRTrackedCamera; - IVRScreenshots *m_pVRScreenshots; - IVRDriverManager *m_pVRDriverManager; - }; - - inline COpenVRContext &OpenVRInternal_ModuleContext() - { - static void *ctx[ sizeof( COpenVRContext ) / sizeof( void * ) ]; - return *( COpenVRContext * )ctx; // bypass zero-init constructor - } - - inline IVRSystem *VR_CALLTYPE VRSystem() { return OpenVRInternal_ModuleContext().VRSystem(); } - inline IVRChaperone *VR_CALLTYPE VRChaperone() { return OpenVRInternal_ModuleContext().VRChaperone(); } - inline IVRChaperoneSetup *VR_CALLTYPE VRChaperoneSetup() { return OpenVRInternal_ModuleContext().VRChaperoneSetup(); } - inline IVRCompositor *VR_CALLTYPE VRCompositor() { return OpenVRInternal_ModuleContext().VRCompositor(); } - inline IVROverlay *VR_CALLTYPE VROverlay() { return OpenVRInternal_ModuleContext().VROverlay(); } - inline IVRScreenshots *VR_CALLTYPE VRScreenshots() { return OpenVRInternal_ModuleContext().VRScreenshots(); } - inline IVRRenderModels *VR_CALLTYPE VRRenderModels() { return OpenVRInternal_ModuleContext().VRRenderModels(); } - inline IVRApplications *VR_CALLTYPE VRApplications() { return OpenVRInternal_ModuleContext().VRApplications(); } - inline IVRSettings *VR_CALLTYPE VRSettings() { return OpenVRInternal_ModuleContext().VRSettings(); } - inline IVRResources *VR_CALLTYPE VRResources() { return OpenVRInternal_ModuleContext().VRResources(); } - inline IVRExtendedDisplay *VR_CALLTYPE VRExtendedDisplay() { return OpenVRInternal_ModuleContext().VRExtendedDisplay(); } - inline IVRTrackedCamera *VR_CALLTYPE VRTrackedCamera() { return OpenVRInternal_ModuleContext().VRTrackedCamera(); } - inline IVRDriverManager *VR_CALLTYPE VRDriverManager() { return OpenVRInternal_ModuleContext().VRDriverManager(); } - - inline void COpenVRContext::Clear() - { - m_pVRSystem = nullptr; - m_pVRChaperone = nullptr; - m_pVRChaperoneSetup = nullptr; - m_pVRCompositor = nullptr; - m_pVROverlay = nullptr; - m_pVRRenderModels = nullptr; - m_pVRExtendedDisplay = nullptr; - m_pVRSettings = nullptr; - m_pVRApplications = nullptr; - m_pVRTrackedCamera = nullptr; - m_pVRResources = nullptr; - m_pVRScreenshots = nullptr; - m_pVRDriverManager = nullptr; - } - - VR_INTERFACE uint32_t VR_CALLTYPE VR_InitInternal2( EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo ); - VR_INTERFACE void VR_CALLTYPE VR_ShutdownInternal(); - - /** Finds the active installation of vrclient.dll and initializes it */ - inline IVRSystem *VR_Init( EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo ) - { - IVRSystem *pVRSystem = nullptr; - - EVRInitError eError; - VRToken() = VR_InitInternal2( &eError, eApplicationType, pStartupInfo ); - COpenVRContext &ctx = OpenVRInternal_ModuleContext(); - ctx.Clear(); - - if ( eError == VRInitError_None ) - { - if ( VR_IsInterfaceVersionValid( IVRSystem_Version ) ) - { - pVRSystem = VRSystem(); - } - else - { - VR_ShutdownInternal(); - eError = VRInitError_Init_InterfaceNotFound; - } - } - - if ( peError ) - *peError = eError; - return pVRSystem; - } - - /** unloads vrclient.dll. Any interface pointers from the interface are - * invalid after this point */ - inline void VR_Shutdown() - { - VR_ShutdownInternal(); - } +inline uint32_t &VRToken() +{ + static uint32_t token; + return token; } + +class COpenVRContext +{ +public: + COpenVRContext() { Clear(); } + void Clear(); + + inline void CheckClear() + { + if (VRToken() != VR_GetInitToken()) + { + Clear(); + VRToken() = VR_GetInitToken(); + } + } + + IVRSystem *VRSystem() + { + CheckClear(); + if (m_pVRSystem == nullptr) + { + EVRInitError eError; + m_pVRSystem = (IVRSystem *)VR_GetGenericInterface(IVRSystem_Version, &eError); + } + return m_pVRSystem; + } + IVRChaperone *VRChaperone() + { + CheckClear(); + if (m_pVRChaperone == nullptr) + { + EVRInitError eError; + m_pVRChaperone = (IVRChaperone *)VR_GetGenericInterface(IVRChaperone_Version, &eError); + } + return m_pVRChaperone; + } + + IVRChaperoneSetup *VRChaperoneSetup() + { + CheckClear(); + if (m_pVRChaperoneSetup == nullptr) + { + EVRInitError eError; + m_pVRChaperoneSetup = (IVRChaperoneSetup *)VR_GetGenericInterface(IVRChaperoneSetup_Version, &eError); + } + return m_pVRChaperoneSetup; + } + + IVRCompositor *VRCompositor() + { + CheckClear(); + if (m_pVRCompositor == nullptr) + { + EVRInitError eError; + m_pVRCompositor = (IVRCompositor *)VR_GetGenericInterface(IVRCompositor_Version, &eError); + } + return m_pVRCompositor; + } + + IVROverlay *VROverlay() + { + CheckClear(); + if (m_pVROverlay == nullptr) + { + EVRInitError eError; + m_pVROverlay = (IVROverlay *)VR_GetGenericInterface(IVROverlay_Version, &eError); + } + return m_pVROverlay; + } + + IVRResources *VRResources() + { + CheckClear(); + if (m_pVRResources == nullptr) + { + EVRInitError eError; + m_pVRResources = (IVRResources *)VR_GetGenericInterface(IVRResources_Version, &eError); + } + return m_pVRResources; + } + + IVRScreenshots *VRScreenshots() + { + CheckClear(); + if (m_pVRScreenshots == nullptr) + { + EVRInitError eError; + m_pVRScreenshots = (IVRScreenshots *)VR_GetGenericInterface(IVRScreenshots_Version, &eError); + } + return m_pVRScreenshots; + } + + IVRRenderModels *VRRenderModels() + { + CheckClear(); + if (m_pVRRenderModels == nullptr) + { + EVRInitError eError; + m_pVRRenderModels = (IVRRenderModels *)VR_GetGenericInterface(IVRRenderModels_Version, &eError); + } + return m_pVRRenderModels; + } + + IVRExtendedDisplay *VRExtendedDisplay() + { + CheckClear(); + if (m_pVRExtendedDisplay == nullptr) + { + EVRInitError eError; + m_pVRExtendedDisplay = (IVRExtendedDisplay *)VR_GetGenericInterface(IVRExtendedDisplay_Version, &eError); + } + return m_pVRExtendedDisplay; + } + + IVRSettings *VRSettings() + { + CheckClear(); + if (m_pVRSettings == nullptr) + { + EVRInitError eError; + m_pVRSettings = (IVRSettings *)VR_GetGenericInterface(IVRSettings_Version, &eError); + } + return m_pVRSettings; + } + + IVRApplications *VRApplications() + { + CheckClear(); + if (m_pVRApplications == nullptr) + { + EVRInitError eError; + m_pVRApplications = (IVRApplications *)VR_GetGenericInterface(IVRApplications_Version, &eError); + } + return m_pVRApplications; + } + + IVRTrackedCamera *VRTrackedCamera() + { + CheckClear(); + if (m_pVRTrackedCamera == nullptr) + { + EVRInitError eError; + m_pVRTrackedCamera = (IVRTrackedCamera *)VR_GetGenericInterface(IVRTrackedCamera_Version, &eError); + } + return m_pVRTrackedCamera; + } + + IVRDriverManager *VRDriverManager() + { + CheckClear(); + if (!m_pVRDriverManager) + { + EVRInitError eError; + m_pVRDriverManager = (IVRDriverManager *)VR_GetGenericInterface(IVRDriverManager_Version, &eError); + } + return m_pVRDriverManager; + } + +private: + IVRSystem *m_pVRSystem; + IVRChaperone *m_pVRChaperone; + IVRChaperoneSetup *m_pVRChaperoneSetup; + IVRCompositor *m_pVRCompositor; + IVROverlay *m_pVROverlay; + IVRResources *m_pVRResources; + IVRRenderModels *m_pVRRenderModels; + IVRExtendedDisplay *m_pVRExtendedDisplay; + IVRSettings *m_pVRSettings; + IVRApplications *m_pVRApplications; + IVRTrackedCamera *m_pVRTrackedCamera; + IVRScreenshots *m_pVRScreenshots; + IVRDriverManager *m_pVRDriverManager; +}; + +inline COpenVRContext &OpenVRInternal_ModuleContext() +{ + static void *ctx[sizeof(COpenVRContext) / sizeof(void *)]; + return *(COpenVRContext *)ctx; // bypass zero-init constructor +} + +inline IVRSystem *VR_CALLTYPE VRSystem() { return OpenVRInternal_ModuleContext().VRSystem(); } +inline IVRChaperone *VR_CALLTYPE VRChaperone() { return OpenVRInternal_ModuleContext().VRChaperone(); } +inline IVRChaperoneSetup *VR_CALLTYPE VRChaperoneSetup() { return OpenVRInternal_ModuleContext().VRChaperoneSetup(); } +inline IVRCompositor *VR_CALLTYPE VRCompositor() { return OpenVRInternal_ModuleContext().VRCompositor(); } +inline IVROverlay *VR_CALLTYPE VROverlay() { return OpenVRInternal_ModuleContext().VROverlay(); } +inline IVRScreenshots *VR_CALLTYPE VRScreenshots() { return OpenVRInternal_ModuleContext().VRScreenshots(); } +inline IVRRenderModels *VR_CALLTYPE VRRenderModels() { return OpenVRInternal_ModuleContext().VRRenderModels(); } +inline IVRApplications *VR_CALLTYPE VRApplications() { return OpenVRInternal_ModuleContext().VRApplications(); } +inline IVRSettings *VR_CALLTYPE VRSettings() { return OpenVRInternal_ModuleContext().VRSettings(); } +inline IVRResources *VR_CALLTYPE VRResources() { return OpenVRInternal_ModuleContext().VRResources(); } +inline IVRExtendedDisplay *VR_CALLTYPE VRExtendedDisplay() { return OpenVRInternal_ModuleContext().VRExtendedDisplay(); } +inline IVRTrackedCamera *VR_CALLTYPE VRTrackedCamera() { return OpenVRInternal_ModuleContext().VRTrackedCamera(); } +inline IVRDriverManager *VR_CALLTYPE VRDriverManager() { return OpenVRInternal_ModuleContext().VRDriverManager(); } + +inline void COpenVRContext::Clear() +{ + m_pVRSystem = nullptr; + m_pVRChaperone = nullptr; + m_pVRChaperoneSetup = nullptr; + m_pVRCompositor = nullptr; + m_pVROverlay = nullptr; + m_pVRRenderModels = nullptr; + m_pVRExtendedDisplay = nullptr; + m_pVRSettings = nullptr; + m_pVRApplications = nullptr; + m_pVRTrackedCamera = nullptr; + m_pVRResources = nullptr; + m_pVRScreenshots = nullptr; + m_pVRDriverManager = nullptr; +} + +VR_INTERFACE uint32_t VR_CALLTYPE VR_InitInternal2(EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo); +VR_INTERFACE void VR_CALLTYPE VR_ShutdownInternal(); + +/** Finds the active installation of vrclient.dll and initializes it */ +inline IVRSystem *VR_Init(EVRInitError *peError, EVRApplicationType eApplicationType, const char *pStartupInfo) +{ + IVRSystem *pVRSystem = nullptr; + + EVRInitError eError; + VRToken() = VR_InitInternal2(&eError, eApplicationType, pStartupInfo); + COpenVRContext &ctx = OpenVRInternal_ModuleContext(); + ctx.Clear(); + + if (eError == VRInitError_None) + { + if (VR_IsInterfaceVersionValid(IVRSystem_Version)) + { + pVRSystem = VRSystem(); + } + else + { + VR_ShutdownInternal(); + eError = VRInitError_Init_InterfaceNotFound; + } + } + + if (peError) + *peError = eError; + return pVRSystem; +} + +/** unloads vrclient.dll. Any interface pointers from the interface are + * invalid after this point */ +inline void VR_Shutdown() +{ + VR_ShutdownInternal(); +} +} // namespace vr diff --git a/examples/ThirdPartyLibs/openvr/headers/openvr_capi.h b/examples/ThirdPartyLibs/openvr/headers/openvr_capi.h index 50f895869..245365f4e 100644 --- a/examples/ThirdPartyLibs/openvr/headers/openvr_capi.h +++ b/examples/ThirdPartyLibs/openvr/headers/openvr_capi.h @@ -7,7 +7,7 @@ #ifndef __OPENVR_API_FLAT_H__ #define __OPENVR_API_FLAT_H__ -#if defined( _WIN32 ) || defined( __clang__ ) +#if defined(_WIN32) || defined(__clang__) #pragma once #endif @@ -17,38 +17,38 @@ #define EXTERN_C #endif -#if defined( _WIN32 ) +#if defined(_WIN32) #define OPENVR_FNTABLE_CALLTYPE __stdcall #else -#define OPENVR_FNTABLE_CALLTYPE +#define OPENVR_FNTABLE_CALLTYPE #endif // OPENVR API export macro -#if defined( _WIN32 ) && !defined( _X360 ) - #if defined( OPENVR_API_EXPORTS ) - #define S_API EXTERN_C __declspec( dllexport ) - #elif defined( OPENVR_API_NODLL ) - #define S_API EXTERN_C - #else - #define S_API extern "C" __declspec( dllimport ) - #endif // OPENVR_API_EXPORTS -#elif defined( __GNUC__ ) - #if defined( OPENVR_API_EXPORTS ) - #define S_API EXTERN_C __attribute__ ((visibility("default"))) - #else - #define S_API EXTERN_C - #endif // OPENVR_API_EXPORTS -#else // !WIN32 - #if defined( OPENVR_API_EXPORTS ) - #define S_API EXTERN_C - #else - #define S_API EXTERN_C - #endif // OPENVR_API_EXPORTS +#if defined(_WIN32) && !defined(_X360) +#if defined(OPENVR_API_EXPORTS) +#define S_API EXTERN_C __declspec(dllexport) +#elif defined(OPENVR_API_NODLL) +#define S_API EXTERN_C +#else +#define S_API extern "C" __declspec(dllimport) +#endif // OPENVR_API_EXPORTS +#elif defined(__GNUC__) +#if defined(OPENVR_API_EXPORTS) +#define S_API EXTERN_C __attribute__((visibility("default"))) +#else +#define S_API EXTERN_C +#endif // OPENVR_API_EXPORTS +#else // !WIN32 +#if defined(OPENVR_API_EXPORTS) +#define S_API EXTERN_C +#else +#define S_API EXTERN_C +#endif // OPENVR_API_EXPORTS #endif #include -#if defined( __WIN32 ) +#if defined(__WIN32) typedef char bool; #else #include @@ -60,7 +60,6 @@ typedef uint64_t VRActionHandle_t; typedef uint64_t VRActionSetHandle_t; typedef uint64_t VRInputOriginHandle_t; - // OpenVR Constants static const unsigned int k_nDriverNone = 4294967295; @@ -87,157 +86,157 @@ static const unsigned int k_unMaxPropertyStringSize = 32768; static const unsigned int k_unControllerStateAxisCount = 5; static const unsigned long k_ulOverlayHandleInvalid = 0; static const unsigned int k_unScreenshotHandleInvalid = 0; -static const char * IVRSystem_Version = "IVRSystem_017"; -static const char * IVRExtendedDisplay_Version = "IVRExtendedDisplay_001"; -static const char * IVRTrackedCamera_Version = "IVRTrackedCamera_003"; +static const char *IVRSystem_Version = "IVRSystem_017"; +static const char *IVRExtendedDisplay_Version = "IVRExtendedDisplay_001"; +static const char *IVRTrackedCamera_Version = "IVRTrackedCamera_003"; static const unsigned int k_unMaxApplicationKeyLength = 128; -static const char * k_pch_MimeType_HomeApp = "vr/home"; -static const char * k_pch_MimeType_GameTheater = "vr/game_theater"; -static const char * IVRApplications_Version = "IVRApplications_006"; -static const char * IVRChaperone_Version = "IVRChaperone_003"; -static const char * IVRChaperoneSetup_Version = "IVRChaperoneSetup_005"; -static const char * IVRCompositor_Version = "IVRCompositor_021"; +static const char *k_pch_MimeType_HomeApp = "vr/home"; +static const char *k_pch_MimeType_GameTheater = "vr/game_theater"; +static const char *IVRApplications_Version = "IVRApplications_006"; +static const char *IVRChaperone_Version = "IVRChaperone_003"; +static const char *IVRChaperoneSetup_Version = "IVRChaperoneSetup_005"; +static const char *IVRCompositor_Version = "IVRCompositor_021"; static const unsigned int k_unVROverlayMaxKeyLength = 128; static const unsigned int k_unVROverlayMaxNameLength = 128; static const unsigned int k_unMaxOverlayCount = 64; static const unsigned int k_unMaxOverlayIntersectionMaskPrimitivesCount = 32; -static const char * IVROverlay_Version = "IVROverlay_016"; -static const char * k_pch_Controller_Component_GDC2015 = "gdc2015"; -static const char * k_pch_Controller_Component_Base = "base"; -static const char * k_pch_Controller_Component_Tip = "tip"; -static const char * k_pch_Controller_Component_HandGrip = "handgrip"; -static const char * k_pch_Controller_Component_Status = "status"; -static const char * IVRRenderModels_Version = "IVRRenderModels_005"; +static const char *IVROverlay_Version = "IVROverlay_016"; +static const char *k_pch_Controller_Component_GDC2015 = "gdc2015"; +static const char *k_pch_Controller_Component_Base = "base"; +static const char *k_pch_Controller_Component_Tip = "tip"; +static const char *k_pch_Controller_Component_HandGrip = "handgrip"; +static const char *k_pch_Controller_Component_Status = "status"; +static const char *IVRRenderModels_Version = "IVRRenderModels_005"; static const unsigned int k_unNotificationTextMaxSize = 256; -static const char * IVRNotifications_Version = "IVRNotifications_002"; +static const char *IVRNotifications_Version = "IVRNotifications_002"; static const unsigned int k_unMaxSettingsKeyLength = 128; -static const char * IVRSettings_Version = "IVRSettings_002"; -static const char * k_pch_SteamVR_Section = "steamvr"; -static const char * k_pch_SteamVR_RequireHmd_String = "requireHmd"; -static const char * k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; -static const char * k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; -static const char * k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; -static const char * k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; -static const char * k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; -static const char * k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; -static const char * k_pch_SteamVR_SendSystemButtonToAllApps_Bool = "sendSystemButtonToAllApps"; -static const char * k_pch_SteamVR_LogLevel_Int32 = "loglevel"; -static const char * k_pch_SteamVR_IPD_Float = "ipd"; -static const char * k_pch_SteamVR_Background_String = "background"; -static const char * k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; -static const char * k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; -static const char * k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; -static const char * k_pch_SteamVR_GridColor_String = "gridColor"; -static const char * k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; -static const char * k_pch_SteamVR_ShowStage_Bool = "showStage"; -static const char * k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; -static const char * k_pch_SteamVR_DirectMode_Bool = "directMode"; -static const char * k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; -static const char * k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; -static const char * k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; -static const char * k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; -static const char * k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; -static const char * k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; -static const char * k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; -static const char * k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; -static const char * k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; -static const char * k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; -static const char * k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; -static const char * k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; -static const char * k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; -static const char * k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; -static const char * k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; -static const char * k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; -static const char * k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; -static const char * k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; -static const char * k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; -static const char * k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; -static const char * k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; -static const char * k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; -static const char * k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; -static const char * k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; -static const char * k_pch_Lighthouse_Section = "driver_lighthouse"; -static const char * k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; -static const char * k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; -static const char * k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; -static const char * k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; -static const char * k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; -static const char * k_pch_Null_Section = "driver_null"; -static const char * k_pch_Null_SerialNumber_String = "serialNumber"; -static const char * k_pch_Null_ModelNumber_String = "modelNumber"; -static const char * k_pch_Null_WindowX_Int32 = "windowX"; -static const char * k_pch_Null_WindowY_Int32 = "windowY"; -static const char * k_pch_Null_WindowWidth_Int32 = "windowWidth"; -static const char * k_pch_Null_WindowHeight_Int32 = "windowHeight"; -static const char * k_pch_Null_RenderWidth_Int32 = "renderWidth"; -static const char * k_pch_Null_RenderHeight_Int32 = "renderHeight"; -static const char * k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; -static const char * k_pch_Null_DisplayFrequency_Float = "displayFrequency"; -static const char * k_pch_UserInterface_Section = "userinterface"; -static const char * k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; -static const char * k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; -static const char * k_pch_UserInterface_Screenshots_Bool = "screenshots"; -static const char * k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; -static const char * k_pch_Notifications_Section = "notifications"; -static const char * k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; -static const char * k_pch_Keyboard_Section = "keyboard"; -static const char * k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; -static const char * k_pch_Keyboard_ScaleX = "ScaleX"; -static const char * k_pch_Keyboard_ScaleY = "ScaleY"; -static const char * k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; -static const char * k_pch_Keyboard_OffsetRightX = "OffsetRightX"; -static const char * k_pch_Keyboard_OffsetY = "OffsetY"; -static const char * k_pch_Keyboard_Smoothing = "Smoothing"; -static const char * k_pch_Perf_Section = "perfcheck"; -static const char * k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; -static const char * k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; -static const char * k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; -static const char * k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; -static const char * k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; -static const char * k_pch_Perf_TestData_Float = "perfTestData"; -static const char * k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; -static const char * k_pch_CollisionBounds_Section = "collisionBounds"; -static const char * k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; -static const char * k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; -static const char * k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; -static const char * k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; -static const char * k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; -static const char * k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; -static const char * k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; -static const char * k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; -static const char * k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; -static const char * k_pch_Camera_Section = "camera"; -static const char * k_pch_Camera_EnableCamera_Bool = "enableCamera"; -static const char * k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; -static const char * k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; -static const char * k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; -static const char * k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; -static const char * k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; -static const char * k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; -static const char * k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; -static const char * k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; -static const char * k_pch_audio_Section = "audio"; -static const char * k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; -static const char * k_pch_audio_OnRecordDevice_String = "onRecordDevice"; -static const char * k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; -static const char * k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; -static const char * k_pch_audio_OffRecordDevice_String = "offRecordDevice"; -static const char * k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; -static const char * k_pch_Power_Section = "power"; -static const char * k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; -static const char * k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; -static const char * k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; -static const char * k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; -static const char * k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; -static const char * k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; -static const char * k_pch_Dashboard_Section = "dashboard"; -static const char * k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; -static const char * k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; -static const char * k_pch_modelskin_Section = "modelskins"; -static const char * k_pch_Driver_Enable_Bool = "enable"; -static const char * IVRScreenshots_Version = "IVRScreenshots_001"; -static const char * IVRResources_Version = "IVRResources_001"; -static const char * IVRDriverManager_Version = "IVRDriverManager_001"; +static const char *IVRSettings_Version = "IVRSettings_002"; +static const char *k_pch_SteamVR_Section = "steamvr"; +static const char *k_pch_SteamVR_RequireHmd_String = "requireHmd"; +static const char *k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; +static const char *k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; +static const char *k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; +static const char *k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; +static const char *k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; +static const char *k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; +static const char *k_pch_SteamVR_SendSystemButtonToAllApps_Bool = "sendSystemButtonToAllApps"; +static const char *k_pch_SteamVR_LogLevel_Int32 = "loglevel"; +static const char *k_pch_SteamVR_IPD_Float = "ipd"; +static const char *k_pch_SteamVR_Background_String = "background"; +static const char *k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; +static const char *k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; +static const char *k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; +static const char *k_pch_SteamVR_GridColor_String = "gridColor"; +static const char *k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; +static const char *k_pch_SteamVR_ShowStage_Bool = "showStage"; +static const char *k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; +static const char *k_pch_SteamVR_DirectMode_Bool = "directMode"; +static const char *k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; +static const char *k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; +static const char *k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; +static const char *k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; +static const char *k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; +static const char *k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; +static const char *k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; +static const char *k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; +static const char *k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; +static const char *k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; +static const char *k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; +static const char *k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; +static const char *k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; +static const char *k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; +static const char *k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; +static const char *k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; +static const char *k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; +static const char *k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; +static const char *k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; +static const char *k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; +static const char *k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; +static const char *k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; +static const char *k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; +static const char *k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; +static const char *k_pch_Lighthouse_Section = "driver_lighthouse"; +static const char *k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; +static const char *k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; +static const char *k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; +static const char *k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; +static const char *k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; +static const char *k_pch_Null_Section = "driver_null"; +static const char *k_pch_Null_SerialNumber_String = "serialNumber"; +static const char *k_pch_Null_ModelNumber_String = "modelNumber"; +static const char *k_pch_Null_WindowX_Int32 = "windowX"; +static const char *k_pch_Null_WindowY_Int32 = "windowY"; +static const char *k_pch_Null_WindowWidth_Int32 = "windowWidth"; +static const char *k_pch_Null_WindowHeight_Int32 = "windowHeight"; +static const char *k_pch_Null_RenderWidth_Int32 = "renderWidth"; +static const char *k_pch_Null_RenderHeight_Int32 = "renderHeight"; +static const char *k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; +static const char *k_pch_Null_DisplayFrequency_Float = "displayFrequency"; +static const char *k_pch_UserInterface_Section = "userinterface"; +static const char *k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; +static const char *k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; +static const char *k_pch_UserInterface_Screenshots_Bool = "screenshots"; +static const char *k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; +static const char *k_pch_Notifications_Section = "notifications"; +static const char *k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; +static const char *k_pch_Keyboard_Section = "keyboard"; +static const char *k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; +static const char *k_pch_Keyboard_ScaleX = "ScaleX"; +static const char *k_pch_Keyboard_ScaleY = "ScaleY"; +static const char *k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; +static const char *k_pch_Keyboard_OffsetRightX = "OffsetRightX"; +static const char *k_pch_Keyboard_OffsetY = "OffsetY"; +static const char *k_pch_Keyboard_Smoothing = "Smoothing"; +static const char *k_pch_Perf_Section = "perfcheck"; +static const char *k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; +static const char *k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; +static const char *k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; +static const char *k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; +static const char *k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; +static const char *k_pch_Perf_TestData_Float = "perfTestData"; +static const char *k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; +static const char *k_pch_CollisionBounds_Section = "collisionBounds"; +static const char *k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; +static const char *k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; +static const char *k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; +static const char *k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; +static const char *k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; +static const char *k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; +static const char *k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; +static const char *k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; +static const char *k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; +static const char *k_pch_Camera_Section = "camera"; +static const char *k_pch_Camera_EnableCamera_Bool = "enableCamera"; +static const char *k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; +static const char *k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; +static const char *k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; +static const char *k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; +static const char *k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; +static const char *k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; +static const char *k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; +static const char *k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; +static const char *k_pch_audio_Section = "audio"; +static const char *k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; +static const char *k_pch_audio_OnRecordDevice_String = "onRecordDevice"; +static const char *k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; +static const char *k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; +static const char *k_pch_audio_OffRecordDevice_String = "offRecordDevice"; +static const char *k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; +static const char *k_pch_Power_Section = "power"; +static const char *k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; +static const char *k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; +static const char *k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; +static const char *k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; +static const char *k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; +static const char *k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; +static const char *k_pch_Dashboard_Section = "dashboard"; +static const char *k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; +static const char *k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; +static const char *k_pch_modelskin_Section = "modelskins"; +static const char *k_pch_Driver_Enable_Bool = "enable"; +static const char *IVRScreenshots_Version = "IVRScreenshots_001"; +static const char *IVRResources_Version = "IVRResources_001"; +static const char *IVRDriverManager_Version = "IVRDriverManager_001"; // OpenVR Enums @@ -1062,14 +1061,13 @@ typedef enum EVRScreenshotError EVRScreenshotError_VRScreenshotError_ScreenshotAlreadyInProgress = 108, } EVRScreenshotError; - // OpenVR typedefs typedef uint32_t TrackedDeviceIndex_t; typedef uint32_t VRNotificationId; typedef uint64_t VROverlayHandle_t; -typedef void * glSharedTextureHandle_t; +typedef void *glSharedTextureHandle_t; typedef int32_t glInt_t; typedef uint32_t glUInt_t; typedef uint64_t SharedTextureHandle_t; @@ -1103,32 +1101,32 @@ typedef EVRScreenshotError VRScreenshotsError; typedef struct HmdMatrix34_t { - float m[3][4]; //float[3][4] + float m[3][4]; //float[3][4] } HmdMatrix34_t; typedef struct HmdMatrix44_t { - float m[4][4]; //float[4][4] + float m[4][4]; //float[4][4] } HmdMatrix44_t; typedef struct HmdVector3_t { - float v[3]; //float[3] + float v[3]; //float[3] } HmdVector3_t; typedef struct HmdVector4_t { - float v[4]; //float[4] + float v[4]; //float[4] } HmdVector4_t; typedef struct HmdVector3d_t { - double v[3]; //double[3] + double v[3]; //double[3] } HmdVector3d_t; typedef struct HmdVector2_t { - float v[2]; //float[2] + float v[2]; //float[2] } HmdVector2_t; typedef struct HmdQuaternion_t @@ -1149,7 +1147,7 @@ typedef struct HmdColor_t typedef struct HmdQuad_t { - struct HmdVector3_t vCorners[4]; //struct vr::HmdVector3_t[4] + struct HmdVector3_t vCorners[4]; //struct vr::HmdVector3_t[4] } HmdQuad_t; typedef struct HmdRect2_t @@ -1160,14 +1158,14 @@ typedef struct HmdRect2_t typedef struct DistortionCoordinates_t { - float rfRed[2]; //float[2] - float rfGreen[2]; //float[2] - float rfBlue[2]; //float[2] + float rfRed[2]; //float[2] + float rfGreen[2]; //float[2] + float rfBlue[2]; //float[2] } DistortionCoordinates_t; typedef struct Texture_t { - void * handle; // void * + void *handle; // void * enum ETextureType eType; enum EColorSpace eColorSpace; } Texture_t; @@ -1198,10 +1196,10 @@ typedef struct VRTextureWithPose_t typedef struct VRVulkanTextureData_t { uint64_t m_nImage; - struct VkDevice_T * m_pDevice; // struct VkDevice_T * - struct VkPhysicalDevice_T * m_pPhysicalDevice; // struct VkPhysicalDevice_T * - struct VkInstance_T * m_pInstance; // struct VkInstance_T * - struct VkQueue_T * m_pQueue; // struct VkQueue_T * + struct VkDevice_T *m_pDevice; // struct VkDevice_T * + struct VkPhysicalDevice_T *m_pPhysicalDevice; // struct VkPhysicalDevice_T * + struct VkInstance_T *m_pInstance; // struct VkInstance_T * + struct VkQueue_T *m_pQueue; // struct VkQueue_T * uint32_t m_nQueueFamilyIndex; uint32_t m_nWidth; uint32_t m_nHeight; @@ -1211,8 +1209,8 @@ typedef struct VRVulkanTextureData_t typedef struct D3D12TextureData_t { - struct ID3D12Resource * m_pResource; // struct ID3D12Resource * - struct ID3D12CommandQueue * m_pCommandQueue; // struct ID3D12CommandQueue * + struct ID3D12Resource *m_pResource; // struct ID3D12Resource * + struct ID3D12CommandQueue *m_pCommandQueue; // struct ID3D12CommandQueue * uint32_t m_nNodeMask; } D3D12TextureData_t; @@ -1270,7 +1268,7 @@ typedef struct VREvent_Status_t typedef struct VREvent_Keyboard_t { - char * cNewInput[8]; //char[8] + char *cNewInput[8]; //char[8] uint64_t uUserValue; } VREvent_Keyboard_t; @@ -1337,7 +1335,7 @@ typedef struct VREvent_Property_t typedef struct HiddenAreaMesh_t { - struct HmdVector2_t * pVertexData; // const struct vr::HmdVector2_t * + struct HmdVector2_t *pVertexData; // const struct vr::HmdVector2_t * uint32_t unTriangleCount; } HiddenAreaMesh_t; @@ -1352,7 +1350,7 @@ typedef struct VRControllerState_t uint32_t unPacketNum; uint64_t ulButtonPressed; uint64_t ulButtonTouched; - struct VRControllerAxis_t rAxis[5]; //struct vr::VRControllerAxis_t[5] + struct VRControllerAxis_t rAxis[5]; //struct vr::VRControllerAxis_t[5] } VRControllerState_t; typedef struct Compositor_OverlaySettings @@ -1385,8 +1383,8 @@ typedef struct CameraVideoStreamFrameHeader_t typedef struct AppOverrideKeys_t { - char * pchKey; // const char * - char * pchValue; // const char * + char *pchKey; // const char * + char *pchValue; // const char * } AppOverrideKeys_t; typedef struct Compositor_FrameTiming @@ -1477,36 +1475,36 @@ typedef struct RenderModel_Vertex_t { struct HmdVector3_t vPosition; struct HmdVector3_t vNormal; - float rfTextureCoord[2]; //float[2] + float rfTextureCoord[2]; //float[2] } RenderModel_Vertex_t; #if defined(__linux__) || defined(__APPLE__) -#pragma pack( push, 4 ) +#pragma pack(push, 4) #endif typedef struct RenderModel_TextureMap_t { uint16_t unWidth; uint16_t unHeight; - uint8_t * rubTextureMapData; // const uint8_t * + uint8_t *rubTextureMapData; // const uint8_t * } RenderModel_TextureMap_t; #if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#pragma pack(pop) #endif #if defined(__linux__) || defined(__APPLE__) -#pragma pack( push, 4 ) +#pragma pack(push, 4) #endif typedef struct RenderModel_t { - struct RenderModel_Vertex_t * rVertexData; // const struct vr::RenderModel_Vertex_t * + struct RenderModel_Vertex_t *rVertexData; // const struct vr::RenderModel_Vertex_t * uint32_t unVertexCount; - uint16_t * rIndexData; // const uint16_t * + uint16_t *rIndexData; // const uint16_t * uint32_t unTriangleCount; TextureID_t diffuseTextureId; } RenderModel_t; #if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#pragma pack(pop) #endif typedef struct RenderModel_ControllerMode_State_t { @@ -1515,7 +1513,7 @@ typedef struct RenderModel_ControllerMode_State_t typedef struct NotificationBitmap_t { - void * m_pImageData; // void * + void *m_pImageData; // void * int32_t m_nWidth; int32_t m_nHeight; int32_t m_nBytesPerPixel; @@ -1523,24 +1521,22 @@ typedef struct NotificationBitmap_t typedef struct COpenVRContext { - intptr_t m_pVRSystem; // class vr::IVRSystem * - intptr_t m_pVRChaperone; // class vr::IVRChaperone * - intptr_t m_pVRChaperoneSetup; // class vr::IVRChaperoneSetup * - intptr_t m_pVRCompositor; // class vr::IVRCompositor * - intptr_t m_pVROverlay; // class vr::IVROverlay * - intptr_t m_pVRResources; // class vr::IVRResources * - intptr_t m_pVRRenderModels; // class vr::IVRRenderModels * - intptr_t m_pVRExtendedDisplay; // class vr::IVRExtendedDisplay * - intptr_t m_pVRSettings; // class vr::IVRSettings * - intptr_t m_pVRApplications; // class vr::IVRApplications * - intptr_t m_pVRTrackedCamera; // class vr::IVRTrackedCamera * - intptr_t m_pVRScreenshots; // class vr::IVRScreenshots * - intptr_t m_pVRDriverManager; // class vr::IVRDriverManager * + intptr_t m_pVRSystem; // class vr::IVRSystem * + intptr_t m_pVRChaperone; // class vr::IVRChaperone * + intptr_t m_pVRChaperoneSetup; // class vr::IVRChaperoneSetup * + intptr_t m_pVRCompositor; // class vr::IVRCompositor * + intptr_t m_pVROverlay; // class vr::IVROverlay * + intptr_t m_pVRResources; // class vr::IVRResources * + intptr_t m_pVRRenderModels; // class vr::IVRRenderModels * + intptr_t m_pVRExtendedDisplay; // class vr::IVRExtendedDisplay * + intptr_t m_pVRSettings; // class vr::IVRSettings * + intptr_t m_pVRApplications; // class vr::IVRApplications * + intptr_t m_pVRTrackedCamera; // class vr::IVRTrackedCamera * + intptr_t m_pVRScreenshots; // class vr::IVRScreenshots * + intptr_t m_pVRDriverManager; // class vr::IVRDriverManager * } COpenVRContext; - -typedef union -{ +typedef union { VREvent_Reserved_t reserved; VREvent_Controller_t controller; VREvent_Mouse_t mouse; @@ -1560,16 +1556,14 @@ typedef union /** An event posted by the server to all running applications */ struct VREvent_t { - uint32_t eventType; // EVREventType enum + uint32_t eventType; // EVREventType enum TrackedDeviceIndex_t trackedDeviceIndex; float eventAgeSeconds; // event data must be the end of the struct as its size is variable VREvent_Data_t data; }; - -typedef union -{ +typedef union { IntersectionMaskRectangle_t m_Rectangle; IntersectionMaskCircle_t m_Circle; } VROverlayIntersectionMaskPrimitive_Data_t; @@ -1580,352 +1574,350 @@ struct VROverlayIntersectionMaskPrimitive_t VROverlayIntersectionMaskPrimitive_Data_t m_Primitive; }; - // OpenVR Function Pointer Tables struct VR_IVRSystem_FnTable { - void (OPENVR_FNTABLE_CALLTYPE *GetRecommendedRenderTargetSize)(uint32_t * pnWidth, uint32_t * pnHeight); - struct HmdMatrix44_t (OPENVR_FNTABLE_CALLTYPE *GetProjectionMatrix)(EVREye eEye, float fNearZ, float fFarZ); - void (OPENVR_FNTABLE_CALLTYPE *GetProjectionRaw)(EVREye eEye, float * pfLeft, float * pfRight, float * pfTop, float * pfBottom); - bool (OPENVR_FNTABLE_CALLTYPE *ComputeDistortion)(EVREye eEye, float fU, float fV, struct DistortionCoordinates_t * pDistortionCoordinates); - struct HmdMatrix34_t (OPENVR_FNTABLE_CALLTYPE *GetEyeToHeadTransform)(EVREye eEye); - bool (OPENVR_FNTABLE_CALLTYPE *GetTimeSinceLastVsync)(float * pfSecondsSinceLastVsync, uint64_t * pulFrameCounter); - int32_t (OPENVR_FNTABLE_CALLTYPE *GetD3D9AdapterIndex)(); - void (OPENVR_FNTABLE_CALLTYPE *GetDXGIOutputInfo)(int32_t * pnAdapterIndex); - void (OPENVR_FNTABLE_CALLTYPE *GetOutputDevice)(uint64_t * pnDevice, ETextureType textureType, struct VkInstance_T * pInstance); - bool (OPENVR_FNTABLE_CALLTYPE *IsDisplayOnDesktop)(); - bool (OPENVR_FNTABLE_CALLTYPE *SetDisplayVisibility)(bool bIsVisibleOnDesktop); - void (OPENVR_FNTABLE_CALLTYPE *GetDeviceToAbsoluteTrackingPose)(ETrackingUniverseOrigin eOrigin, float fPredictedSecondsToPhotonsFromNow, struct TrackedDevicePose_t * pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount); - void (OPENVR_FNTABLE_CALLTYPE *ResetSeatedZeroPose)(); - struct HmdMatrix34_t (OPENVR_FNTABLE_CALLTYPE *GetSeatedZeroPoseToStandingAbsoluteTrackingPose)(); - struct HmdMatrix34_t (OPENVR_FNTABLE_CALLTYPE *GetRawZeroPoseToStandingAbsoluteTrackingPose)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetSortedTrackedDeviceIndicesOfClass)(ETrackedDeviceClass eTrackedDeviceClass, TrackedDeviceIndex_t * punTrackedDeviceIndexArray, uint32_t unTrackedDeviceIndexArrayCount, TrackedDeviceIndex_t unRelativeToTrackedDeviceIndex); - EDeviceActivityLevel (OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceActivityLevel)(TrackedDeviceIndex_t unDeviceId); - void (OPENVR_FNTABLE_CALLTYPE *ApplyTransform)(struct TrackedDevicePose_t * pOutputPose, struct TrackedDevicePose_t * pTrackedDevicePose, struct HmdMatrix34_t * pTransform); - TrackedDeviceIndex_t (OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceIndexForControllerRole)(ETrackedControllerRole unDeviceType); - ETrackedControllerRole (OPENVR_FNTABLE_CALLTYPE *GetControllerRoleForTrackedDeviceIndex)(TrackedDeviceIndex_t unDeviceIndex); - ETrackedDeviceClass (OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceClass)(TrackedDeviceIndex_t unDeviceIndex); - bool (OPENVR_FNTABLE_CALLTYPE *IsTrackedDeviceConnected)(TrackedDeviceIndex_t unDeviceIndex); - bool (OPENVR_FNTABLE_CALLTYPE *GetBoolTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); - float (OPENVR_FNTABLE_CALLTYPE *GetFloatTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); - int32_t (OPENVR_FNTABLE_CALLTYPE *GetInt32TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); - uint64_t (OPENVR_FNTABLE_CALLTYPE *GetUint64TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); - struct HmdMatrix34_t (OPENVR_FNTABLE_CALLTYPE *GetMatrix34TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError * pError); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetStringTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, char * pchValue, uint32_t unBufferSize, ETrackedPropertyError * pError); - char * (OPENVR_FNTABLE_CALLTYPE *GetPropErrorNameFromEnum)(ETrackedPropertyError error); - bool (OPENVR_FNTABLE_CALLTYPE *PollNextEvent)(struct VREvent_t * pEvent, uint32_t uncbVREvent); - bool (OPENVR_FNTABLE_CALLTYPE *PollNextEventWithPose)(ETrackingUniverseOrigin eOrigin, struct VREvent_t * pEvent, uint32_t uncbVREvent, TrackedDevicePose_t * pTrackedDevicePose); - char * (OPENVR_FNTABLE_CALLTYPE *GetEventTypeNameFromEnum)(EVREventType eType); - struct HiddenAreaMesh_t (OPENVR_FNTABLE_CALLTYPE *GetHiddenAreaMesh)(EVREye eEye, EHiddenAreaMeshType type); - bool (OPENVR_FNTABLE_CALLTYPE *GetControllerState)(TrackedDeviceIndex_t unControllerDeviceIndex, VRControllerState_t * pControllerState, uint32_t unControllerStateSize); - bool (OPENVR_FNTABLE_CALLTYPE *GetControllerStateWithPose)(ETrackingUniverseOrigin eOrigin, TrackedDeviceIndex_t unControllerDeviceIndex, VRControllerState_t * pControllerState, uint32_t unControllerStateSize, struct TrackedDevicePose_t * pTrackedDevicePose); - void (OPENVR_FNTABLE_CALLTYPE *TriggerHapticPulse)(TrackedDeviceIndex_t unControllerDeviceIndex, uint32_t unAxisId, unsigned short usDurationMicroSec); - char * (OPENVR_FNTABLE_CALLTYPE *GetButtonIdNameFromEnum)(EVRButtonId eButtonId); - char * (OPENVR_FNTABLE_CALLTYPE *GetControllerAxisTypeNameFromEnum)(EVRControllerAxisType eAxisType); - bool (OPENVR_FNTABLE_CALLTYPE *CaptureInputFocus)(); - void (OPENVR_FNTABLE_CALLTYPE *ReleaseInputFocus)(); - bool (OPENVR_FNTABLE_CALLTYPE *IsInputFocusCapturedByAnotherProcess)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *DriverDebugRequest)(TrackedDeviceIndex_t unDeviceIndex, char * pchRequest, char * pchResponseBuffer, uint32_t unResponseBufferSize); - EVRFirmwareError (OPENVR_FNTABLE_CALLTYPE *PerformFirmwareUpdate)(TrackedDeviceIndex_t unDeviceIndex); - void (OPENVR_FNTABLE_CALLTYPE *AcknowledgeQuit_Exiting)(); - void (OPENVR_FNTABLE_CALLTYPE *AcknowledgeQuit_UserPrompt)(); + void(OPENVR_FNTABLE_CALLTYPE *GetRecommendedRenderTargetSize)(uint32_t *pnWidth, uint32_t *pnHeight); + struct HmdMatrix44_t(OPENVR_FNTABLE_CALLTYPE *GetProjectionMatrix)(EVREye eEye, float fNearZ, float fFarZ); + void(OPENVR_FNTABLE_CALLTYPE *GetProjectionRaw)(EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom); + bool(OPENVR_FNTABLE_CALLTYPE *ComputeDistortion)(EVREye eEye, float fU, float fV, struct DistortionCoordinates_t *pDistortionCoordinates); + struct HmdMatrix34_t(OPENVR_FNTABLE_CALLTYPE *GetEyeToHeadTransform)(EVREye eEye); + bool(OPENVR_FNTABLE_CALLTYPE *GetTimeSinceLastVsync)(float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter); + int32_t(OPENVR_FNTABLE_CALLTYPE *GetD3D9AdapterIndex)(); + void(OPENVR_FNTABLE_CALLTYPE *GetDXGIOutputInfo)(int32_t *pnAdapterIndex); + void(OPENVR_FNTABLE_CALLTYPE *GetOutputDevice)(uint64_t *pnDevice, ETextureType textureType, struct VkInstance_T *pInstance); + bool(OPENVR_FNTABLE_CALLTYPE *IsDisplayOnDesktop)(); + bool(OPENVR_FNTABLE_CALLTYPE *SetDisplayVisibility)(bool bIsVisibleOnDesktop); + void(OPENVR_FNTABLE_CALLTYPE *GetDeviceToAbsoluteTrackingPose)(ETrackingUniverseOrigin eOrigin, float fPredictedSecondsToPhotonsFromNow, struct TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount); + void(OPENVR_FNTABLE_CALLTYPE *ResetSeatedZeroPose)(); + struct HmdMatrix34_t(OPENVR_FNTABLE_CALLTYPE *GetSeatedZeroPoseToStandingAbsoluteTrackingPose)(); + struct HmdMatrix34_t(OPENVR_FNTABLE_CALLTYPE *GetRawZeroPoseToStandingAbsoluteTrackingPose)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetSortedTrackedDeviceIndicesOfClass)(ETrackedDeviceClass eTrackedDeviceClass, TrackedDeviceIndex_t *punTrackedDeviceIndexArray, uint32_t unTrackedDeviceIndexArrayCount, TrackedDeviceIndex_t unRelativeToTrackedDeviceIndex); + EDeviceActivityLevel(OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceActivityLevel)(TrackedDeviceIndex_t unDeviceId); + void(OPENVR_FNTABLE_CALLTYPE *ApplyTransform)(struct TrackedDevicePose_t *pOutputPose, struct TrackedDevicePose_t *pTrackedDevicePose, struct HmdMatrix34_t *pTransform); + TrackedDeviceIndex_t(OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceIndexForControllerRole)(ETrackedControllerRole unDeviceType); + ETrackedControllerRole(OPENVR_FNTABLE_CALLTYPE *GetControllerRoleForTrackedDeviceIndex)(TrackedDeviceIndex_t unDeviceIndex); + ETrackedDeviceClass(OPENVR_FNTABLE_CALLTYPE *GetTrackedDeviceClass)(TrackedDeviceIndex_t unDeviceIndex); + bool(OPENVR_FNTABLE_CALLTYPE *IsTrackedDeviceConnected)(TrackedDeviceIndex_t unDeviceIndex); + bool(OPENVR_FNTABLE_CALLTYPE *GetBoolTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError); + float(OPENVR_FNTABLE_CALLTYPE *GetFloatTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError); + int32_t(OPENVR_FNTABLE_CALLTYPE *GetInt32TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError); + uint64_t(OPENVR_FNTABLE_CALLTYPE *GetUint64TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError); + struct HmdMatrix34_t(OPENVR_FNTABLE_CALLTYPE *GetMatrix34TrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, ETrackedPropertyError *pError); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetStringTrackedDeviceProperty)(TrackedDeviceIndex_t unDeviceIndex, ETrackedDeviceProperty prop, char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError); + char *(OPENVR_FNTABLE_CALLTYPE *GetPropErrorNameFromEnum)(ETrackedPropertyError error); + bool(OPENVR_FNTABLE_CALLTYPE *PollNextEvent)(struct VREvent_t *pEvent, uint32_t uncbVREvent); + bool(OPENVR_FNTABLE_CALLTYPE *PollNextEventWithPose)(ETrackingUniverseOrigin eOrigin, struct VREvent_t *pEvent, uint32_t uncbVREvent, TrackedDevicePose_t *pTrackedDevicePose); + char *(OPENVR_FNTABLE_CALLTYPE *GetEventTypeNameFromEnum)(EVREventType eType); + struct HiddenAreaMesh_t(OPENVR_FNTABLE_CALLTYPE *GetHiddenAreaMesh)(EVREye eEye, EHiddenAreaMeshType type); + bool(OPENVR_FNTABLE_CALLTYPE *GetControllerState)(TrackedDeviceIndex_t unControllerDeviceIndex, VRControllerState_t *pControllerState, uint32_t unControllerStateSize); + bool(OPENVR_FNTABLE_CALLTYPE *GetControllerStateWithPose)(ETrackingUniverseOrigin eOrigin, TrackedDeviceIndex_t unControllerDeviceIndex, VRControllerState_t *pControllerState, uint32_t unControllerStateSize, struct TrackedDevicePose_t *pTrackedDevicePose); + void(OPENVR_FNTABLE_CALLTYPE *TriggerHapticPulse)(TrackedDeviceIndex_t unControllerDeviceIndex, uint32_t unAxisId, unsigned short usDurationMicroSec); + char *(OPENVR_FNTABLE_CALLTYPE *GetButtonIdNameFromEnum)(EVRButtonId eButtonId); + char *(OPENVR_FNTABLE_CALLTYPE *GetControllerAxisTypeNameFromEnum)(EVRControllerAxisType eAxisType); + bool(OPENVR_FNTABLE_CALLTYPE *CaptureInputFocus)(); + void(OPENVR_FNTABLE_CALLTYPE *ReleaseInputFocus)(); + bool(OPENVR_FNTABLE_CALLTYPE *IsInputFocusCapturedByAnotherProcess)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *DriverDebugRequest)(TrackedDeviceIndex_t unDeviceIndex, char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize); + EVRFirmwareError(OPENVR_FNTABLE_CALLTYPE *PerformFirmwareUpdate)(TrackedDeviceIndex_t unDeviceIndex); + void(OPENVR_FNTABLE_CALLTYPE *AcknowledgeQuit_Exiting)(); + void(OPENVR_FNTABLE_CALLTYPE *AcknowledgeQuit_UserPrompt)(); }; struct VR_IVRExtendedDisplay_FnTable { - void (OPENVR_FNTABLE_CALLTYPE *GetWindowBounds)(int32_t * pnX, int32_t * pnY, uint32_t * pnWidth, uint32_t * pnHeight); - void (OPENVR_FNTABLE_CALLTYPE *GetEyeOutputViewport)(EVREye eEye, uint32_t * pnX, uint32_t * pnY, uint32_t * pnWidth, uint32_t * pnHeight); - void (OPENVR_FNTABLE_CALLTYPE *GetDXGIOutputInfo)(int32_t * pnAdapterIndex, int32_t * pnAdapterOutputIndex); + void(OPENVR_FNTABLE_CALLTYPE *GetWindowBounds)(int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight); + void(OPENVR_FNTABLE_CALLTYPE *GetEyeOutputViewport)(EVREye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight); + void(OPENVR_FNTABLE_CALLTYPE *GetDXGIOutputInfo)(int32_t *pnAdapterIndex, int32_t *pnAdapterOutputIndex); }; struct VR_IVRTrackedCamera_FnTable { - char * (OPENVR_FNTABLE_CALLTYPE *GetCameraErrorNameFromEnum)(EVRTrackedCameraError eCameraError); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *HasCamera)(TrackedDeviceIndex_t nDeviceIndex, bool * pHasCamera); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetCameraFrameSize)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, uint32_t * pnWidth, uint32_t * pnHeight, uint32_t * pnFrameBufferSize); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetCameraIntrinsics)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, HmdVector2_t * pFocalLength, HmdVector2_t * pCenter); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetCameraProjection)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, HmdMatrix44_t * pProjection); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *AcquireVideoStreamingService)(TrackedDeviceIndex_t nDeviceIndex, TrackedCameraHandle_t * pHandle); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *ReleaseVideoStreamingService)(TrackedCameraHandle_t hTrackedCamera); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetVideoStreamFrameBuffer)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, void * pFrameBuffer, uint32_t nFrameBufferSize, CameraVideoStreamFrameHeader_t * pFrameHeader, uint32_t nFrameHeaderSize); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureSize)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, VRTextureBounds_t * pTextureBounds, uint32_t * pnWidth, uint32_t * pnHeight); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureD3D11)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, void * pD3D11DeviceOrResource, void ** ppD3D11ShaderResourceView, CameraVideoStreamFrameHeader_t * pFrameHeader, uint32_t nFrameHeaderSize); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureGL)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, glUInt_t * pglTextureId, CameraVideoStreamFrameHeader_t * pFrameHeader, uint32_t nFrameHeaderSize); - EVRTrackedCameraError (OPENVR_FNTABLE_CALLTYPE *ReleaseVideoStreamTextureGL)(TrackedCameraHandle_t hTrackedCamera, glUInt_t glTextureId); + char *(OPENVR_FNTABLE_CALLTYPE *GetCameraErrorNameFromEnum)(EVRTrackedCameraError eCameraError); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *HasCamera)(TrackedDeviceIndex_t nDeviceIndex, bool *pHasCamera); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetCameraFrameSize)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, uint32_t *pnWidth, uint32_t *pnHeight, uint32_t *pnFrameBufferSize); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetCameraIntrinsics)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, HmdVector2_t *pFocalLength, HmdVector2_t *pCenter); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetCameraProjection)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, HmdMatrix44_t *pProjection); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *AcquireVideoStreamingService)(TrackedDeviceIndex_t nDeviceIndex, TrackedCameraHandle_t *pHandle); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *ReleaseVideoStreamingService)(TrackedCameraHandle_t hTrackedCamera); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetVideoStreamFrameBuffer)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, void *pFrameBuffer, uint32_t nFrameBufferSize, CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureSize)(TrackedDeviceIndex_t nDeviceIndex, EVRTrackedCameraFrameType eFrameType, VRTextureBounds_t *pTextureBounds, uint32_t *pnWidth, uint32_t *pnHeight); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureD3D11)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView, CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *GetVideoStreamTextureGL)(TrackedCameraHandle_t hTrackedCamera, EVRTrackedCameraFrameType eFrameType, glUInt_t *pglTextureId, CameraVideoStreamFrameHeader_t *pFrameHeader, uint32_t nFrameHeaderSize); + EVRTrackedCameraError(OPENVR_FNTABLE_CALLTYPE *ReleaseVideoStreamTextureGL)(TrackedCameraHandle_t hTrackedCamera, glUInt_t glTextureId); }; struct VR_IVRApplications_FnTable { - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *AddApplicationManifest)(char * pchApplicationManifestFullPath, bool bTemporary); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *RemoveApplicationManifest)(char * pchApplicationManifestFullPath); - bool (OPENVR_FNTABLE_CALLTYPE *IsApplicationInstalled)(char * pchAppKey); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationCount)(); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *GetApplicationKeyByIndex)(uint32_t unApplicationIndex, char * pchAppKeyBuffer, uint32_t unAppKeyBufferLen); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *GetApplicationKeyByProcessId)(uint32_t unProcessId, char * pchAppKeyBuffer, uint32_t unAppKeyBufferLen); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchApplication)(char * pchAppKey); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchTemplateApplication)(char * pchTemplateAppKey, char * pchNewAppKey, struct AppOverrideKeys_t * pKeys, uint32_t unKeys); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchApplicationFromMimeType)(char * pchMimeType, char * pchArgs); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchDashboardOverlay)(char * pchAppKey); - bool (OPENVR_FNTABLE_CALLTYPE *CancelApplicationLaunch)(char * pchAppKey); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *IdentifyApplication)(uint32_t unProcessId, char * pchAppKey); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationProcessId)(char * pchAppKey); - char * (OPENVR_FNTABLE_CALLTYPE *GetApplicationsErrorNameFromEnum)(EVRApplicationError error); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyString)(char * pchAppKey, EVRApplicationProperty eProperty, char * pchPropertyValueBuffer, uint32_t unPropertyValueBufferLen, EVRApplicationError * peError); - bool (OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyBool)(char * pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError * peError); - uint64_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyUint64)(char * pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError * peError); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *SetApplicationAutoLaunch)(char * pchAppKey, bool bAutoLaunch); - bool (OPENVR_FNTABLE_CALLTYPE *GetApplicationAutoLaunch)(char * pchAppKey); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *SetDefaultApplicationForMimeType)(char * pchAppKey, char * pchMimeType); - bool (OPENVR_FNTABLE_CALLTYPE *GetDefaultApplicationForMimeType)(char * pchMimeType, char * pchAppKeyBuffer, uint32_t unAppKeyBufferLen); - bool (OPENVR_FNTABLE_CALLTYPE *GetApplicationSupportedMimeTypes)(char * pchAppKey, char * pchMimeTypesBuffer, uint32_t unMimeTypesBuffer); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationsThatSupportMimeType)(char * pchMimeType, char * pchAppKeysThatSupportBuffer, uint32_t unAppKeysThatSupportBuffer); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetApplicationLaunchArguments)(uint32_t unHandle, char * pchArgs, uint32_t unArgs); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *GetStartingApplication)(char * pchAppKeyBuffer, uint32_t unAppKeyBufferLen); - EVRApplicationTransitionState (OPENVR_FNTABLE_CALLTYPE *GetTransitionState)(); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *PerformApplicationPrelaunchCheck)(char * pchAppKey); - char * (OPENVR_FNTABLE_CALLTYPE *GetApplicationsTransitionStateNameFromEnum)(EVRApplicationTransitionState state); - bool (OPENVR_FNTABLE_CALLTYPE *IsQuitUserPromptRequested)(); - EVRApplicationError (OPENVR_FNTABLE_CALLTYPE *LaunchInternalProcess)(char * pchBinaryPath, char * pchArguments, char * pchWorkingDirectory); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetCurrentSceneProcessId)(); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *AddApplicationManifest)(char *pchApplicationManifestFullPath, bool bTemporary); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *RemoveApplicationManifest)(char *pchApplicationManifestFullPath); + bool(OPENVR_FNTABLE_CALLTYPE *IsApplicationInstalled)(char *pchAppKey); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationCount)(); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *GetApplicationKeyByIndex)(uint32_t unApplicationIndex, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *GetApplicationKeyByProcessId)(uint32_t unProcessId, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *LaunchApplication)(char *pchAppKey); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *LaunchTemplateApplication)(char *pchTemplateAppKey, char *pchNewAppKey, struct AppOverrideKeys_t *pKeys, uint32_t unKeys); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *LaunchApplicationFromMimeType)(char *pchMimeType, char *pchArgs); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *LaunchDashboardOverlay)(char *pchAppKey); + bool(OPENVR_FNTABLE_CALLTYPE *CancelApplicationLaunch)(char *pchAppKey); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *IdentifyApplication)(uint32_t unProcessId, char *pchAppKey); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationProcessId)(char *pchAppKey); + char *(OPENVR_FNTABLE_CALLTYPE *GetApplicationsErrorNameFromEnum)(EVRApplicationError error); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyString)(char *pchAppKey, EVRApplicationProperty eProperty, char *pchPropertyValueBuffer, uint32_t unPropertyValueBufferLen, EVRApplicationError *peError); + bool(OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyBool)(char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError); + uint64_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationPropertyUint64)(char *pchAppKey, EVRApplicationProperty eProperty, EVRApplicationError *peError); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *SetApplicationAutoLaunch)(char *pchAppKey, bool bAutoLaunch); + bool(OPENVR_FNTABLE_CALLTYPE *GetApplicationAutoLaunch)(char *pchAppKey); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *SetDefaultApplicationForMimeType)(char *pchAppKey, char *pchMimeType); + bool(OPENVR_FNTABLE_CALLTYPE *GetDefaultApplicationForMimeType)(char *pchMimeType, char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen); + bool(OPENVR_FNTABLE_CALLTYPE *GetApplicationSupportedMimeTypes)(char *pchAppKey, char *pchMimeTypesBuffer, uint32_t unMimeTypesBuffer); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationsThatSupportMimeType)(char *pchMimeType, char *pchAppKeysThatSupportBuffer, uint32_t unAppKeysThatSupportBuffer); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetApplicationLaunchArguments)(uint32_t unHandle, char *pchArgs, uint32_t unArgs); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *GetStartingApplication)(char *pchAppKeyBuffer, uint32_t unAppKeyBufferLen); + EVRApplicationTransitionState(OPENVR_FNTABLE_CALLTYPE *GetTransitionState)(); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *PerformApplicationPrelaunchCheck)(char *pchAppKey); + char *(OPENVR_FNTABLE_CALLTYPE *GetApplicationsTransitionStateNameFromEnum)(EVRApplicationTransitionState state); + bool(OPENVR_FNTABLE_CALLTYPE *IsQuitUserPromptRequested)(); + EVRApplicationError(OPENVR_FNTABLE_CALLTYPE *LaunchInternalProcess)(char *pchBinaryPath, char *pchArguments, char *pchWorkingDirectory); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetCurrentSceneProcessId)(); }; struct VR_IVRChaperone_FnTable { - ChaperoneCalibrationState (OPENVR_FNTABLE_CALLTYPE *GetCalibrationState)(); - bool (OPENVR_FNTABLE_CALLTYPE *GetPlayAreaSize)(float * pSizeX, float * pSizeZ); - bool (OPENVR_FNTABLE_CALLTYPE *GetPlayAreaRect)(struct HmdQuad_t * rect); - void (OPENVR_FNTABLE_CALLTYPE *ReloadInfo)(); - void (OPENVR_FNTABLE_CALLTYPE *SetSceneColor)(struct HmdColor_t color); - void (OPENVR_FNTABLE_CALLTYPE *GetBoundsColor)(struct HmdColor_t * pOutputColorArray, int nNumOutputColors, float flCollisionBoundsFadeDistance, struct HmdColor_t * pOutputCameraColor); - bool (OPENVR_FNTABLE_CALLTYPE *AreBoundsVisible)(); - void (OPENVR_FNTABLE_CALLTYPE *ForceBoundsVisible)(bool bForce); + ChaperoneCalibrationState(OPENVR_FNTABLE_CALLTYPE *GetCalibrationState)(); + bool(OPENVR_FNTABLE_CALLTYPE *GetPlayAreaSize)(float *pSizeX, float *pSizeZ); + bool(OPENVR_FNTABLE_CALLTYPE *GetPlayAreaRect)(struct HmdQuad_t *rect); + void(OPENVR_FNTABLE_CALLTYPE *ReloadInfo)(); + void(OPENVR_FNTABLE_CALLTYPE *SetSceneColor)(struct HmdColor_t color); + void(OPENVR_FNTABLE_CALLTYPE *GetBoundsColor)(struct HmdColor_t *pOutputColorArray, int nNumOutputColors, float flCollisionBoundsFadeDistance, struct HmdColor_t *pOutputCameraColor); + bool(OPENVR_FNTABLE_CALLTYPE *AreBoundsVisible)(); + void(OPENVR_FNTABLE_CALLTYPE *ForceBoundsVisible)(bool bForce); }; struct VR_IVRChaperoneSetup_FnTable { - bool (OPENVR_FNTABLE_CALLTYPE *CommitWorkingCopy)(EChaperoneConfigFile configFile); - void (OPENVR_FNTABLE_CALLTYPE *RevertWorkingCopy)(); - bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingPlayAreaSize)(float * pSizeX, float * pSizeZ); - bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingPlayAreaRect)(struct HmdQuad_t * rect); - bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingCollisionBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t * punQuadsCount); - bool (OPENVR_FNTABLE_CALLTYPE *GetLiveCollisionBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t * punQuadsCount); - bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pmatSeatedZeroPoseToRawTrackingPose); - bool (OPENVR_FNTABLE_CALLTYPE *GetWorkingStandingZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pmatStandingZeroPoseToRawTrackingPose); - void (OPENVR_FNTABLE_CALLTYPE *SetWorkingPlayAreaSize)(float sizeX, float sizeZ); - void (OPENVR_FNTABLE_CALLTYPE *SetWorkingCollisionBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t unQuadsCount); - void (OPENVR_FNTABLE_CALLTYPE *SetWorkingSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pMatSeatedZeroPoseToRawTrackingPose); - void (OPENVR_FNTABLE_CALLTYPE *SetWorkingStandingZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pMatStandingZeroPoseToRawTrackingPose); - void (OPENVR_FNTABLE_CALLTYPE *ReloadFromDisk)(EChaperoneConfigFile configFile); - bool (OPENVR_FNTABLE_CALLTYPE *GetLiveSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t * pmatSeatedZeroPoseToRawTrackingPose); - void (OPENVR_FNTABLE_CALLTYPE *SetWorkingCollisionBoundsTagsInfo)(uint8_t * pTagsBuffer, uint32_t unTagCount); - bool (OPENVR_FNTABLE_CALLTYPE *GetLiveCollisionBoundsTagsInfo)(uint8_t * pTagsBuffer, uint32_t * punTagCount); - bool (OPENVR_FNTABLE_CALLTYPE *SetWorkingPhysicalBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t unQuadsCount); - bool (OPENVR_FNTABLE_CALLTYPE *GetLivePhysicalBoundsInfo)(struct HmdQuad_t * pQuadsBuffer, uint32_t * punQuadsCount); - bool (OPENVR_FNTABLE_CALLTYPE *ExportLiveToBuffer)(char * pBuffer, uint32_t * pnBufferLength); - bool (OPENVR_FNTABLE_CALLTYPE *ImportFromBufferToWorking)(char * pBuffer, uint32_t nImportFlags); + bool(OPENVR_FNTABLE_CALLTYPE *CommitWorkingCopy)(EChaperoneConfigFile configFile); + void(OPENVR_FNTABLE_CALLTYPE *RevertWorkingCopy)(); + bool(OPENVR_FNTABLE_CALLTYPE *GetWorkingPlayAreaSize)(float *pSizeX, float *pSizeZ); + bool(OPENVR_FNTABLE_CALLTYPE *GetWorkingPlayAreaRect)(struct HmdQuad_t *rect); + bool(OPENVR_FNTABLE_CALLTYPE *GetWorkingCollisionBoundsInfo)(struct HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount); + bool(OPENVR_FNTABLE_CALLTYPE *GetLiveCollisionBoundsInfo)(struct HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount); + bool(OPENVR_FNTABLE_CALLTYPE *GetWorkingSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose); + bool(OPENVR_FNTABLE_CALLTYPE *GetWorkingStandingZeroPoseToRawTrackingPose)(struct HmdMatrix34_t *pmatStandingZeroPoseToRawTrackingPose); + void(OPENVR_FNTABLE_CALLTYPE *SetWorkingPlayAreaSize)(float sizeX, float sizeZ); + void(OPENVR_FNTABLE_CALLTYPE *SetWorkingCollisionBoundsInfo)(struct HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount); + void(OPENVR_FNTABLE_CALLTYPE *SetWorkingSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t *pMatSeatedZeroPoseToRawTrackingPose); + void(OPENVR_FNTABLE_CALLTYPE *SetWorkingStandingZeroPoseToRawTrackingPose)(struct HmdMatrix34_t *pMatStandingZeroPoseToRawTrackingPose); + void(OPENVR_FNTABLE_CALLTYPE *ReloadFromDisk)(EChaperoneConfigFile configFile); + bool(OPENVR_FNTABLE_CALLTYPE *GetLiveSeatedZeroPoseToRawTrackingPose)(struct HmdMatrix34_t *pmatSeatedZeroPoseToRawTrackingPose); + void(OPENVR_FNTABLE_CALLTYPE *SetWorkingCollisionBoundsTagsInfo)(uint8_t *pTagsBuffer, uint32_t unTagCount); + bool(OPENVR_FNTABLE_CALLTYPE *GetLiveCollisionBoundsTagsInfo)(uint8_t *pTagsBuffer, uint32_t *punTagCount); + bool(OPENVR_FNTABLE_CALLTYPE *SetWorkingPhysicalBoundsInfo)(struct HmdQuad_t *pQuadsBuffer, uint32_t unQuadsCount); + bool(OPENVR_FNTABLE_CALLTYPE *GetLivePhysicalBoundsInfo)(struct HmdQuad_t *pQuadsBuffer, uint32_t *punQuadsCount); + bool(OPENVR_FNTABLE_CALLTYPE *ExportLiveToBuffer)(char *pBuffer, uint32_t *pnBufferLength); + bool(OPENVR_FNTABLE_CALLTYPE *ImportFromBufferToWorking)(char *pBuffer, uint32_t nImportFlags); }; struct VR_IVRCompositor_FnTable { - void (OPENVR_FNTABLE_CALLTYPE *SetTrackingSpace)(ETrackingUniverseOrigin eOrigin); - ETrackingUniverseOrigin (OPENVR_FNTABLE_CALLTYPE *GetTrackingSpace)(); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *WaitGetPoses)(struct TrackedDevicePose_t * pRenderPoseArray, uint32_t unRenderPoseArrayCount, struct TrackedDevicePose_t * pGamePoseArray, uint32_t unGamePoseArrayCount); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *GetLastPoses)(struct TrackedDevicePose_t * pRenderPoseArray, uint32_t unRenderPoseArrayCount, struct TrackedDevicePose_t * pGamePoseArray, uint32_t unGamePoseArrayCount); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *GetLastPoseForTrackedDeviceIndex)(TrackedDeviceIndex_t unDeviceIndex, struct TrackedDevicePose_t * pOutputPose, struct TrackedDevicePose_t * pOutputGamePose); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *Submit)(EVREye eEye, struct Texture_t * pTexture, struct VRTextureBounds_t * pBounds, EVRSubmitFlags nSubmitFlags); - void (OPENVR_FNTABLE_CALLTYPE *ClearLastSubmittedFrame)(); - void (OPENVR_FNTABLE_CALLTYPE *PostPresentHandoff)(); - bool (OPENVR_FNTABLE_CALLTYPE *GetFrameTiming)(struct Compositor_FrameTiming * pTiming, uint32_t unFramesAgo); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetFrameTimings)(struct Compositor_FrameTiming * pTiming, uint32_t nFrames); - float (OPENVR_FNTABLE_CALLTYPE *GetFrameTimeRemaining)(); - void (OPENVR_FNTABLE_CALLTYPE *GetCumulativeStats)(struct Compositor_CumulativeStats * pStats, uint32_t nStatsSizeInBytes); - void (OPENVR_FNTABLE_CALLTYPE *FadeToColor)(float fSeconds, float fRed, float fGreen, float fBlue, float fAlpha, bool bBackground); - struct HmdColor_t (OPENVR_FNTABLE_CALLTYPE *GetCurrentFadeColor)(bool bBackground); - void (OPENVR_FNTABLE_CALLTYPE *FadeGrid)(float fSeconds, bool bFadeIn); - float (OPENVR_FNTABLE_CALLTYPE *GetCurrentGridAlpha)(); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *SetSkyboxOverride)(struct Texture_t * pTextures, uint32_t unTextureCount); - void (OPENVR_FNTABLE_CALLTYPE *ClearSkyboxOverride)(); - void (OPENVR_FNTABLE_CALLTYPE *CompositorBringToFront)(); - void (OPENVR_FNTABLE_CALLTYPE *CompositorGoToBack)(); - void (OPENVR_FNTABLE_CALLTYPE *CompositorQuit)(); - bool (OPENVR_FNTABLE_CALLTYPE *IsFullscreen)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetCurrentSceneFocusProcess)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetLastFrameRenderer)(); - bool (OPENVR_FNTABLE_CALLTYPE *CanRenderScene)(); - void (OPENVR_FNTABLE_CALLTYPE *ShowMirrorWindow)(); - void (OPENVR_FNTABLE_CALLTYPE *HideMirrorWindow)(); - bool (OPENVR_FNTABLE_CALLTYPE *IsMirrorWindowVisible)(); - void (OPENVR_FNTABLE_CALLTYPE *CompositorDumpImages)(); - bool (OPENVR_FNTABLE_CALLTYPE *ShouldAppRenderWithLowResources)(); - void (OPENVR_FNTABLE_CALLTYPE *ForceInterleavedReprojectionOn)(bool bOverride); - void (OPENVR_FNTABLE_CALLTYPE *ForceReconnectProcess)(); - void (OPENVR_FNTABLE_CALLTYPE *SuspendRendering)(bool bSuspend); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *GetMirrorTextureD3D11)(EVREye eEye, void * pD3D11DeviceOrResource, void ** ppD3D11ShaderResourceView); - void (OPENVR_FNTABLE_CALLTYPE *ReleaseMirrorTextureD3D11)(void * pD3D11ShaderResourceView); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *GetMirrorTextureGL)(EVREye eEye, glUInt_t * pglTextureId, glSharedTextureHandle_t * pglSharedTextureHandle); - bool (OPENVR_FNTABLE_CALLTYPE *ReleaseSharedGLTexture)(glUInt_t glTextureId, glSharedTextureHandle_t glSharedTextureHandle); - void (OPENVR_FNTABLE_CALLTYPE *LockGLSharedTextureForAccess)(glSharedTextureHandle_t glSharedTextureHandle); - void (OPENVR_FNTABLE_CALLTYPE *UnlockGLSharedTextureForAccess)(glSharedTextureHandle_t glSharedTextureHandle); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetVulkanInstanceExtensionsRequired)(char * pchValue, uint32_t unBufferSize); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetVulkanDeviceExtensionsRequired)(struct VkPhysicalDevice_T * pPhysicalDevice, char * pchValue, uint32_t unBufferSize); - void (OPENVR_FNTABLE_CALLTYPE *SetExplicitTimingMode)(bool bExplicitTimingMode); - EVRCompositorError (OPENVR_FNTABLE_CALLTYPE *SubmitExplicitTimingData)(); + void(OPENVR_FNTABLE_CALLTYPE *SetTrackingSpace)(ETrackingUniverseOrigin eOrigin); + ETrackingUniverseOrigin(OPENVR_FNTABLE_CALLTYPE *GetTrackingSpace)(); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *WaitGetPoses)(struct TrackedDevicePose_t *pRenderPoseArray, uint32_t unRenderPoseArrayCount, struct TrackedDevicePose_t *pGamePoseArray, uint32_t unGamePoseArrayCount); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *GetLastPoses)(struct TrackedDevicePose_t *pRenderPoseArray, uint32_t unRenderPoseArrayCount, struct TrackedDevicePose_t *pGamePoseArray, uint32_t unGamePoseArrayCount); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *GetLastPoseForTrackedDeviceIndex)(TrackedDeviceIndex_t unDeviceIndex, struct TrackedDevicePose_t *pOutputPose, struct TrackedDevicePose_t *pOutputGamePose); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *Submit)(EVREye eEye, struct Texture_t *pTexture, struct VRTextureBounds_t *pBounds, EVRSubmitFlags nSubmitFlags); + void(OPENVR_FNTABLE_CALLTYPE *ClearLastSubmittedFrame)(); + void(OPENVR_FNTABLE_CALLTYPE *PostPresentHandoff)(); + bool(OPENVR_FNTABLE_CALLTYPE *GetFrameTiming)(struct Compositor_FrameTiming *pTiming, uint32_t unFramesAgo); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetFrameTimings)(struct Compositor_FrameTiming *pTiming, uint32_t nFrames); + float(OPENVR_FNTABLE_CALLTYPE *GetFrameTimeRemaining)(); + void(OPENVR_FNTABLE_CALLTYPE *GetCumulativeStats)(struct Compositor_CumulativeStats *pStats, uint32_t nStatsSizeInBytes); + void(OPENVR_FNTABLE_CALLTYPE *FadeToColor)(float fSeconds, float fRed, float fGreen, float fBlue, float fAlpha, bool bBackground); + struct HmdColor_t(OPENVR_FNTABLE_CALLTYPE *GetCurrentFadeColor)(bool bBackground); + void(OPENVR_FNTABLE_CALLTYPE *FadeGrid)(float fSeconds, bool bFadeIn); + float(OPENVR_FNTABLE_CALLTYPE *GetCurrentGridAlpha)(); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *SetSkyboxOverride)(struct Texture_t *pTextures, uint32_t unTextureCount); + void(OPENVR_FNTABLE_CALLTYPE *ClearSkyboxOverride)(); + void(OPENVR_FNTABLE_CALLTYPE *CompositorBringToFront)(); + void(OPENVR_FNTABLE_CALLTYPE *CompositorGoToBack)(); + void(OPENVR_FNTABLE_CALLTYPE *CompositorQuit)(); + bool(OPENVR_FNTABLE_CALLTYPE *IsFullscreen)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetCurrentSceneFocusProcess)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetLastFrameRenderer)(); + bool(OPENVR_FNTABLE_CALLTYPE *CanRenderScene)(); + void(OPENVR_FNTABLE_CALLTYPE *ShowMirrorWindow)(); + void(OPENVR_FNTABLE_CALLTYPE *HideMirrorWindow)(); + bool(OPENVR_FNTABLE_CALLTYPE *IsMirrorWindowVisible)(); + void(OPENVR_FNTABLE_CALLTYPE *CompositorDumpImages)(); + bool(OPENVR_FNTABLE_CALLTYPE *ShouldAppRenderWithLowResources)(); + void(OPENVR_FNTABLE_CALLTYPE *ForceInterleavedReprojectionOn)(bool bOverride); + void(OPENVR_FNTABLE_CALLTYPE *ForceReconnectProcess)(); + void(OPENVR_FNTABLE_CALLTYPE *SuspendRendering)(bool bSuspend); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *GetMirrorTextureD3D11)(EVREye eEye, void *pD3D11DeviceOrResource, void **ppD3D11ShaderResourceView); + void(OPENVR_FNTABLE_CALLTYPE *ReleaseMirrorTextureD3D11)(void *pD3D11ShaderResourceView); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *GetMirrorTextureGL)(EVREye eEye, glUInt_t *pglTextureId, glSharedTextureHandle_t *pglSharedTextureHandle); + bool(OPENVR_FNTABLE_CALLTYPE *ReleaseSharedGLTexture)(glUInt_t glTextureId, glSharedTextureHandle_t glSharedTextureHandle); + void(OPENVR_FNTABLE_CALLTYPE *LockGLSharedTextureForAccess)(glSharedTextureHandle_t glSharedTextureHandle); + void(OPENVR_FNTABLE_CALLTYPE *UnlockGLSharedTextureForAccess)(glSharedTextureHandle_t glSharedTextureHandle); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetVulkanInstanceExtensionsRequired)(char *pchValue, uint32_t unBufferSize); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetVulkanDeviceExtensionsRequired)(struct VkPhysicalDevice_T *pPhysicalDevice, char *pchValue, uint32_t unBufferSize); + void(OPENVR_FNTABLE_CALLTYPE *SetExplicitTimingMode)(bool bExplicitTimingMode); + EVRCompositorError(OPENVR_FNTABLE_CALLTYPE *SubmitExplicitTimingData)(); }; struct VR_IVROverlay_FnTable { - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *FindOverlay)(char * pchOverlayKey, VROverlayHandle_t * pOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *CreateOverlay)(char * pchOverlayKey, char * pchOverlayName, VROverlayHandle_t * pOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *DestroyOverlay)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetHighQualityOverlay)(VROverlayHandle_t ulOverlayHandle); - VROverlayHandle_t (OPENVR_FNTABLE_CALLTYPE *GetHighQualityOverlay)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayKey)(VROverlayHandle_t ulOverlayHandle, char * pchValue, uint32_t unBufferSize, EVROverlayError * pError); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayName)(VROverlayHandle_t ulOverlayHandle, char * pchValue, uint32_t unBufferSize, EVROverlayError * pError); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayName)(VROverlayHandle_t ulOverlayHandle, char * pchName); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayImageData)(VROverlayHandle_t ulOverlayHandle, void * pvBuffer, uint32_t unBufferSize, uint32_t * punWidth, uint32_t * punHeight); - char * (OPENVR_FNTABLE_CALLTYPE *GetOverlayErrorNameFromEnum)(EVROverlayError error); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayRenderingPid)(VROverlayHandle_t ulOverlayHandle, uint32_t unPID); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayRenderingPid)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayFlag)(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool bEnabled); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayFlag)(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool * pbEnabled); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayColor)(VROverlayHandle_t ulOverlayHandle, float fRed, float fGreen, float fBlue); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayColor)(VROverlayHandle_t ulOverlayHandle, float * pfRed, float * pfGreen, float * pfBlue); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayAlpha)(VROverlayHandle_t ulOverlayHandle, float fAlpha); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayAlpha)(VROverlayHandle_t ulOverlayHandle, float * pfAlpha); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTexelAspect)(VROverlayHandle_t ulOverlayHandle, float fTexelAspect); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTexelAspect)(VROverlayHandle_t ulOverlayHandle, float * pfTexelAspect); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlaySortOrder)(VROverlayHandle_t ulOverlayHandle, uint32_t unSortOrder); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlaySortOrder)(VROverlayHandle_t ulOverlayHandle, uint32_t * punSortOrder); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayWidthInMeters)(VROverlayHandle_t ulOverlayHandle, float fWidthInMeters); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayWidthInMeters)(VROverlayHandle_t ulOverlayHandle, float * pfWidthInMeters); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayAutoCurveDistanceRangeInMeters)(VROverlayHandle_t ulOverlayHandle, float fMinDistanceInMeters, float fMaxDistanceInMeters); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayAutoCurveDistanceRangeInMeters)(VROverlayHandle_t ulOverlayHandle, float * pfMinDistanceInMeters, float * pfMaxDistanceInMeters); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTextureColorSpace)(VROverlayHandle_t ulOverlayHandle, EColorSpace eTextureColorSpace); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureColorSpace)(VROverlayHandle_t ulOverlayHandle, EColorSpace * peTextureColorSpace); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTextureBounds)(VROverlayHandle_t ulOverlayHandle, struct VRTextureBounds_t * pOverlayTextureBounds); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureBounds)(VROverlayHandle_t ulOverlayHandle, struct VRTextureBounds_t * pOverlayTextureBounds); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetOverlayRenderModel)(VROverlayHandle_t ulOverlayHandle, char * pchValue, uint32_t unBufferSize, struct HmdColor_t * pColor, EVROverlayError * pError); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayRenderModel)(VROverlayHandle_t ulOverlayHandle, char * pchRenderModel, struct HmdColor_t * pColor); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformType)(VROverlayHandle_t ulOverlayHandle, VROverlayTransformType * peTransformType); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformAbsolute)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, struct HmdMatrix34_t * pmatTrackingOriginToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformAbsolute)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin * peTrackingOrigin, struct HmdMatrix34_t * pmatTrackingOriginToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformTrackedDeviceRelative)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unTrackedDevice, struct HmdMatrix34_t * pmatTrackedDeviceToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformTrackedDeviceRelative)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t * punTrackedDevice, struct HmdMatrix34_t * pmatTrackedDeviceToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformTrackedDeviceComponent)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unDeviceIndex, char * pchComponentName); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformTrackedDeviceComponent)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t * punDeviceIndex, char * pchComponentName, uint32_t unComponentNameSize); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformOverlayRelative)(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t * ulOverlayHandleParent, struct HmdMatrix34_t * pmatParentOverlayToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformOverlayRelative)(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t ulOverlayHandleParent, struct HmdMatrix34_t * pmatParentOverlayToOverlayTransform); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ShowOverlay)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *HideOverlay)(VROverlayHandle_t ulOverlayHandle); - bool (OPENVR_FNTABLE_CALLTYPE *IsOverlayVisible)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetTransformForOverlayCoordinates)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, struct HmdVector2_t coordinatesInOverlay, struct HmdMatrix34_t * pmatTransform); - bool (OPENVR_FNTABLE_CALLTYPE *PollNextOverlayEvent)(VROverlayHandle_t ulOverlayHandle, struct VREvent_t * pEvent, uint32_t uncbVREvent); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayInputMethod)(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod * peInputMethod); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayInputMethod)(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod eInputMethod); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayMouseScale)(VROverlayHandle_t ulOverlayHandle, struct HmdVector2_t * pvecMouseScale); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayMouseScale)(VROverlayHandle_t ulOverlayHandle, struct HmdVector2_t * pvecMouseScale); - bool (OPENVR_FNTABLE_CALLTYPE *ComputeOverlayIntersection)(VROverlayHandle_t ulOverlayHandle, struct VROverlayIntersectionParams_t * pParams, struct VROverlayIntersectionResults_t * pResults); - bool (OPENVR_FNTABLE_CALLTYPE *HandleControllerOverlayInteractionAsMouse)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unControllerDeviceIndex); - bool (OPENVR_FNTABLE_CALLTYPE *IsHoverTargetOverlay)(VROverlayHandle_t ulOverlayHandle); - VROverlayHandle_t (OPENVR_FNTABLE_CALLTYPE *GetGamepadFocusOverlay)(); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetGamepadFocusOverlay)(VROverlayHandle_t ulNewFocusOverlay); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayNeighbor)(EOverlayDirection eDirection, VROverlayHandle_t ulFrom, VROverlayHandle_t ulTo); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *MoveGamepadFocusToNeighbor)(EOverlayDirection eDirection, VROverlayHandle_t ulFrom); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayTexture)(VROverlayHandle_t ulOverlayHandle, struct Texture_t * pTexture); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ClearOverlayTexture)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayRaw)(VROverlayHandle_t ulOverlayHandle, void * pvBuffer, uint32_t unWidth, uint32_t unHeight, uint32_t unDepth); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayFromFile)(VROverlayHandle_t ulOverlayHandle, char * pchFilePath); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTexture)(VROverlayHandle_t ulOverlayHandle, void ** pNativeTextureHandle, void * pNativeTextureRef, uint32_t * pWidth, uint32_t * pHeight, uint32_t * pNativeFormat, ETextureType * pAPIType, EColorSpace * pColorSpace, struct VRTextureBounds_t * pTextureBounds); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ReleaseNativeOverlayHandle)(VROverlayHandle_t ulOverlayHandle, void * pNativeTextureHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureSize)(VROverlayHandle_t ulOverlayHandle, uint32_t * pWidth, uint32_t * pHeight); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *CreateDashboardOverlay)(char * pchOverlayKey, char * pchOverlayFriendlyName, VROverlayHandle_t * pMainHandle, VROverlayHandle_t * pThumbnailHandle); - bool (OPENVR_FNTABLE_CALLTYPE *IsDashboardVisible)(); - bool (OPENVR_FNTABLE_CALLTYPE *IsActiveDashboardOverlay)(VROverlayHandle_t ulOverlayHandle); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetDashboardOverlaySceneProcess)(VROverlayHandle_t ulOverlayHandle, uint32_t unProcessId); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetDashboardOverlaySceneProcess)(VROverlayHandle_t ulOverlayHandle, uint32_t * punProcessId); - void (OPENVR_FNTABLE_CALLTYPE *ShowDashboard)(char * pchOverlayToShow); - TrackedDeviceIndex_t (OPENVR_FNTABLE_CALLTYPE *GetPrimaryDashboardDevice)(); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ShowKeyboard)(EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, char * pchDescription, uint32_t unCharMax, char * pchExistingText, bool bUseMinimalMode, uint64_t uUserValue); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *ShowKeyboardForOverlay)(VROverlayHandle_t ulOverlayHandle, EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, char * pchDescription, uint32_t unCharMax, char * pchExistingText, bool bUseMinimalMode, uint64_t uUserValue); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetKeyboardText)(char * pchText, uint32_t cchText); - void (OPENVR_FNTABLE_CALLTYPE *HideKeyboard)(); - void (OPENVR_FNTABLE_CALLTYPE *SetKeyboardTransformAbsolute)(ETrackingUniverseOrigin eTrackingOrigin, struct HmdMatrix34_t * pmatTrackingOriginToKeyboardTransform); - void (OPENVR_FNTABLE_CALLTYPE *SetKeyboardPositionForOverlay)(VROverlayHandle_t ulOverlayHandle, struct HmdRect2_t avoidRect); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *SetOverlayIntersectionMask)(VROverlayHandle_t ulOverlayHandle, struct VROverlayIntersectionMaskPrimitive_t * pMaskPrimitives, uint32_t unNumMaskPrimitives, uint32_t unPrimitiveSize); - EVROverlayError (OPENVR_FNTABLE_CALLTYPE *GetOverlayFlags)(VROverlayHandle_t ulOverlayHandle, uint32_t * pFlags); - VRMessageOverlayResponse (OPENVR_FNTABLE_CALLTYPE *ShowMessageOverlay)(char * pchText, char * pchCaption, char * pchButton0Text, char * pchButton1Text, char * pchButton2Text, char * pchButton3Text); - void (OPENVR_FNTABLE_CALLTYPE *CloseMessageOverlay)(); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *FindOverlay)(char *pchOverlayKey, VROverlayHandle_t *pOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *CreateOverlay)(char *pchOverlayKey, char *pchOverlayName, VROverlayHandle_t *pOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *DestroyOverlay)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetHighQualityOverlay)(VROverlayHandle_t ulOverlayHandle); + VROverlayHandle_t(OPENVR_FNTABLE_CALLTYPE *GetHighQualityOverlay)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetOverlayKey)(VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, EVROverlayError *pError); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetOverlayName)(VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, EVROverlayError *pError); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayName)(VROverlayHandle_t ulOverlayHandle, char *pchName); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayImageData)(VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unBufferSize, uint32_t *punWidth, uint32_t *punHeight); + char *(OPENVR_FNTABLE_CALLTYPE *GetOverlayErrorNameFromEnum)(EVROverlayError error); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayRenderingPid)(VROverlayHandle_t ulOverlayHandle, uint32_t unPID); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetOverlayRenderingPid)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayFlag)(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool bEnabled); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayFlag)(VROverlayHandle_t ulOverlayHandle, VROverlayFlags eOverlayFlag, bool *pbEnabled); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayColor)(VROverlayHandle_t ulOverlayHandle, float fRed, float fGreen, float fBlue); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayColor)(VROverlayHandle_t ulOverlayHandle, float *pfRed, float *pfGreen, float *pfBlue); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayAlpha)(VROverlayHandle_t ulOverlayHandle, float fAlpha); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayAlpha)(VROverlayHandle_t ulOverlayHandle, float *pfAlpha); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTexelAspect)(VROverlayHandle_t ulOverlayHandle, float fTexelAspect); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTexelAspect)(VROverlayHandle_t ulOverlayHandle, float *pfTexelAspect); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlaySortOrder)(VROverlayHandle_t ulOverlayHandle, uint32_t unSortOrder); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlaySortOrder)(VROverlayHandle_t ulOverlayHandle, uint32_t *punSortOrder); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayWidthInMeters)(VROverlayHandle_t ulOverlayHandle, float fWidthInMeters); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayWidthInMeters)(VROverlayHandle_t ulOverlayHandle, float *pfWidthInMeters); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayAutoCurveDistanceRangeInMeters)(VROverlayHandle_t ulOverlayHandle, float fMinDistanceInMeters, float fMaxDistanceInMeters); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayAutoCurveDistanceRangeInMeters)(VROverlayHandle_t ulOverlayHandle, float *pfMinDistanceInMeters, float *pfMaxDistanceInMeters); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTextureColorSpace)(VROverlayHandle_t ulOverlayHandle, EColorSpace eTextureColorSpace); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureColorSpace)(VROverlayHandle_t ulOverlayHandle, EColorSpace *peTextureColorSpace); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTextureBounds)(VROverlayHandle_t ulOverlayHandle, struct VRTextureBounds_t *pOverlayTextureBounds); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureBounds)(VROverlayHandle_t ulOverlayHandle, struct VRTextureBounds_t *pOverlayTextureBounds); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetOverlayRenderModel)(VROverlayHandle_t ulOverlayHandle, char *pchValue, uint32_t unBufferSize, struct HmdColor_t *pColor, EVROverlayError *pError); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayRenderModel)(VROverlayHandle_t ulOverlayHandle, char *pchRenderModel, struct HmdColor_t *pColor); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformType)(VROverlayHandle_t ulOverlayHandle, VROverlayTransformType *peTransformType); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformAbsolute)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, struct HmdMatrix34_t *pmatTrackingOriginToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformAbsolute)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin *peTrackingOrigin, struct HmdMatrix34_t *pmatTrackingOriginToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformTrackedDeviceRelative)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unTrackedDevice, struct HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformTrackedDeviceRelative)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punTrackedDevice, struct HmdMatrix34_t *pmatTrackedDeviceToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformTrackedDeviceComponent)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unDeviceIndex, char *pchComponentName); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformTrackedDeviceComponent)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t *punDeviceIndex, char *pchComponentName, uint32_t unComponentNameSize); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTransformOverlayRelative)(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t *ulOverlayHandleParent, struct HmdMatrix34_t *pmatParentOverlayToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTransformOverlayRelative)(VROverlayHandle_t ulOverlayHandle, VROverlayHandle_t ulOverlayHandleParent, struct HmdMatrix34_t *pmatParentOverlayToOverlayTransform); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *ShowOverlay)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *HideOverlay)(VROverlayHandle_t ulOverlayHandle); + bool(OPENVR_FNTABLE_CALLTYPE *IsOverlayVisible)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetTransformForOverlayCoordinates)(VROverlayHandle_t ulOverlayHandle, ETrackingUniverseOrigin eTrackingOrigin, struct HmdVector2_t coordinatesInOverlay, struct HmdMatrix34_t *pmatTransform); + bool(OPENVR_FNTABLE_CALLTYPE *PollNextOverlayEvent)(VROverlayHandle_t ulOverlayHandle, struct VREvent_t *pEvent, uint32_t uncbVREvent); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayInputMethod)(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod *peInputMethod); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayInputMethod)(VROverlayHandle_t ulOverlayHandle, VROverlayInputMethod eInputMethod); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayMouseScale)(VROverlayHandle_t ulOverlayHandle, struct HmdVector2_t *pvecMouseScale); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayMouseScale)(VROverlayHandle_t ulOverlayHandle, struct HmdVector2_t *pvecMouseScale); + bool(OPENVR_FNTABLE_CALLTYPE *ComputeOverlayIntersection)(VROverlayHandle_t ulOverlayHandle, struct VROverlayIntersectionParams_t *pParams, struct VROverlayIntersectionResults_t *pResults); + bool(OPENVR_FNTABLE_CALLTYPE *HandleControllerOverlayInteractionAsMouse)(VROverlayHandle_t ulOverlayHandle, TrackedDeviceIndex_t unControllerDeviceIndex); + bool(OPENVR_FNTABLE_CALLTYPE *IsHoverTargetOverlay)(VROverlayHandle_t ulOverlayHandle); + VROverlayHandle_t(OPENVR_FNTABLE_CALLTYPE *GetGamepadFocusOverlay)(); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetGamepadFocusOverlay)(VROverlayHandle_t ulNewFocusOverlay); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayNeighbor)(EOverlayDirection eDirection, VROverlayHandle_t ulFrom, VROverlayHandle_t ulTo); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *MoveGamepadFocusToNeighbor)(EOverlayDirection eDirection, VROverlayHandle_t ulFrom); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayTexture)(VROverlayHandle_t ulOverlayHandle, struct Texture_t *pTexture); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *ClearOverlayTexture)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayRaw)(VROverlayHandle_t ulOverlayHandle, void *pvBuffer, uint32_t unWidth, uint32_t unHeight, uint32_t unDepth); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayFromFile)(VROverlayHandle_t ulOverlayHandle, char *pchFilePath); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTexture)(VROverlayHandle_t ulOverlayHandle, void **pNativeTextureHandle, void *pNativeTextureRef, uint32_t *pWidth, uint32_t *pHeight, uint32_t *pNativeFormat, ETextureType *pAPIType, EColorSpace *pColorSpace, struct VRTextureBounds_t *pTextureBounds); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *ReleaseNativeOverlayHandle)(VROverlayHandle_t ulOverlayHandle, void *pNativeTextureHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayTextureSize)(VROverlayHandle_t ulOverlayHandle, uint32_t *pWidth, uint32_t *pHeight); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *CreateDashboardOverlay)(char *pchOverlayKey, char *pchOverlayFriendlyName, VROverlayHandle_t *pMainHandle, VROverlayHandle_t *pThumbnailHandle); + bool(OPENVR_FNTABLE_CALLTYPE *IsDashboardVisible)(); + bool(OPENVR_FNTABLE_CALLTYPE *IsActiveDashboardOverlay)(VROverlayHandle_t ulOverlayHandle); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetDashboardOverlaySceneProcess)(VROverlayHandle_t ulOverlayHandle, uint32_t unProcessId); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetDashboardOverlaySceneProcess)(VROverlayHandle_t ulOverlayHandle, uint32_t *punProcessId); + void(OPENVR_FNTABLE_CALLTYPE *ShowDashboard)(char *pchOverlayToShow); + TrackedDeviceIndex_t(OPENVR_FNTABLE_CALLTYPE *GetPrimaryDashboardDevice)(); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *ShowKeyboard)(EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, char *pchDescription, uint32_t unCharMax, char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *ShowKeyboardForOverlay)(VROverlayHandle_t ulOverlayHandle, EGamepadTextInputMode eInputMode, EGamepadTextInputLineMode eLineInputMode, char *pchDescription, uint32_t unCharMax, char *pchExistingText, bool bUseMinimalMode, uint64_t uUserValue); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetKeyboardText)(char *pchText, uint32_t cchText); + void(OPENVR_FNTABLE_CALLTYPE *HideKeyboard)(); + void(OPENVR_FNTABLE_CALLTYPE *SetKeyboardTransformAbsolute)(ETrackingUniverseOrigin eTrackingOrigin, struct HmdMatrix34_t *pmatTrackingOriginToKeyboardTransform); + void(OPENVR_FNTABLE_CALLTYPE *SetKeyboardPositionForOverlay)(VROverlayHandle_t ulOverlayHandle, struct HmdRect2_t avoidRect); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *SetOverlayIntersectionMask)(VROverlayHandle_t ulOverlayHandle, struct VROverlayIntersectionMaskPrimitive_t *pMaskPrimitives, uint32_t unNumMaskPrimitives, uint32_t unPrimitiveSize); + EVROverlayError(OPENVR_FNTABLE_CALLTYPE *GetOverlayFlags)(VROverlayHandle_t ulOverlayHandle, uint32_t *pFlags); + VRMessageOverlayResponse(OPENVR_FNTABLE_CALLTYPE *ShowMessageOverlay)(char *pchText, char *pchCaption, char *pchButton0Text, char *pchButton1Text, char *pchButton2Text, char *pchButton3Text); + void(OPENVR_FNTABLE_CALLTYPE *CloseMessageOverlay)(); }; struct VR_IVRRenderModels_FnTable { - EVRRenderModelError (OPENVR_FNTABLE_CALLTYPE *LoadRenderModel_Async)(char * pchRenderModelName, struct RenderModel_t ** ppRenderModel); - void (OPENVR_FNTABLE_CALLTYPE *FreeRenderModel)(struct RenderModel_t * pRenderModel); - EVRRenderModelError (OPENVR_FNTABLE_CALLTYPE *LoadTexture_Async)(TextureID_t textureId, struct RenderModel_TextureMap_t ** ppTexture); - void (OPENVR_FNTABLE_CALLTYPE *FreeTexture)(struct RenderModel_TextureMap_t * pTexture); - EVRRenderModelError (OPENVR_FNTABLE_CALLTYPE *LoadTextureD3D11_Async)(TextureID_t textureId, void * pD3D11Device, void ** ppD3D11Texture2D); - EVRRenderModelError (OPENVR_FNTABLE_CALLTYPE *LoadIntoTextureD3D11_Async)(TextureID_t textureId, void * pDstTexture); - void (OPENVR_FNTABLE_CALLTYPE *FreeTextureD3D11)(void * pD3D11Texture2D); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetRenderModelName)(uint32_t unRenderModelIndex, char * pchRenderModelName, uint32_t unRenderModelNameLen); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetRenderModelCount)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetComponentCount)(char * pchRenderModelName); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetComponentName)(char * pchRenderModelName, uint32_t unComponentIndex, char * pchComponentName, uint32_t unComponentNameLen); - uint64_t (OPENVR_FNTABLE_CALLTYPE *GetComponentButtonMask)(char * pchRenderModelName, char * pchComponentName); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetComponentRenderModelName)(char * pchRenderModelName, char * pchComponentName, char * pchComponentRenderModelName, uint32_t unComponentRenderModelNameLen); - bool (OPENVR_FNTABLE_CALLTYPE *GetComponentState)(char * pchRenderModelName, char * pchComponentName, VRControllerState_t * pControllerState, struct RenderModel_ControllerMode_State_t * pState, struct RenderModel_ComponentState_t * pComponentState); - bool (OPENVR_FNTABLE_CALLTYPE *RenderModelHasComponent)(char * pchRenderModelName, char * pchComponentName); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetRenderModelThumbnailURL)(char * pchRenderModelName, char * pchThumbnailURL, uint32_t unThumbnailURLLen, EVRRenderModelError * peError); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetRenderModelOriginalPath)(char * pchRenderModelName, char * pchOriginalPath, uint32_t unOriginalPathLen, EVRRenderModelError * peError); - char * (OPENVR_FNTABLE_CALLTYPE *GetRenderModelErrorNameFromEnum)(EVRRenderModelError error); + EVRRenderModelError(OPENVR_FNTABLE_CALLTYPE *LoadRenderModel_Async)(char *pchRenderModelName, struct RenderModel_t **ppRenderModel); + void(OPENVR_FNTABLE_CALLTYPE *FreeRenderModel)(struct RenderModel_t *pRenderModel); + EVRRenderModelError(OPENVR_FNTABLE_CALLTYPE *LoadTexture_Async)(TextureID_t textureId, struct RenderModel_TextureMap_t **ppTexture); + void(OPENVR_FNTABLE_CALLTYPE *FreeTexture)(struct RenderModel_TextureMap_t *pTexture); + EVRRenderModelError(OPENVR_FNTABLE_CALLTYPE *LoadTextureD3D11_Async)(TextureID_t textureId, void *pD3D11Device, void **ppD3D11Texture2D); + EVRRenderModelError(OPENVR_FNTABLE_CALLTYPE *LoadIntoTextureD3D11_Async)(TextureID_t textureId, void *pDstTexture); + void(OPENVR_FNTABLE_CALLTYPE *FreeTextureD3D11)(void *pD3D11Texture2D); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetRenderModelName)(uint32_t unRenderModelIndex, char *pchRenderModelName, uint32_t unRenderModelNameLen); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetRenderModelCount)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetComponentCount)(char *pchRenderModelName); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetComponentName)(char *pchRenderModelName, uint32_t unComponentIndex, char *pchComponentName, uint32_t unComponentNameLen); + uint64_t(OPENVR_FNTABLE_CALLTYPE *GetComponentButtonMask)(char *pchRenderModelName, char *pchComponentName); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetComponentRenderModelName)(char *pchRenderModelName, char *pchComponentName, char *pchComponentRenderModelName, uint32_t unComponentRenderModelNameLen); + bool(OPENVR_FNTABLE_CALLTYPE *GetComponentState)(char *pchRenderModelName, char *pchComponentName, VRControllerState_t *pControllerState, struct RenderModel_ControllerMode_State_t *pState, struct RenderModel_ComponentState_t *pComponentState); + bool(OPENVR_FNTABLE_CALLTYPE *RenderModelHasComponent)(char *pchRenderModelName, char *pchComponentName); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetRenderModelThumbnailURL)(char *pchRenderModelName, char *pchThumbnailURL, uint32_t unThumbnailURLLen, EVRRenderModelError *peError); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetRenderModelOriginalPath)(char *pchRenderModelName, char *pchOriginalPath, uint32_t unOriginalPathLen, EVRRenderModelError *peError); + char *(OPENVR_FNTABLE_CALLTYPE *GetRenderModelErrorNameFromEnum)(EVRRenderModelError error); }; struct VR_IVRNotifications_FnTable { - EVRNotificationError (OPENVR_FNTABLE_CALLTYPE *CreateNotification)(VROverlayHandle_t ulOverlayHandle, uint64_t ulUserValue, EVRNotificationType type, char * pchText, EVRNotificationStyle style, struct NotificationBitmap_t * pImage, VRNotificationId * pNotificationId); - EVRNotificationError (OPENVR_FNTABLE_CALLTYPE *RemoveNotification)(VRNotificationId notificationId); + EVRNotificationError(OPENVR_FNTABLE_CALLTYPE *CreateNotification)(VROverlayHandle_t ulOverlayHandle, uint64_t ulUserValue, EVRNotificationType type, char *pchText, EVRNotificationStyle style, struct NotificationBitmap_t *pImage, VRNotificationId *pNotificationId); + EVRNotificationError(OPENVR_FNTABLE_CALLTYPE *RemoveNotification)(VRNotificationId notificationId); }; struct VR_IVRSettings_FnTable { - char * (OPENVR_FNTABLE_CALLTYPE *GetSettingsErrorNameFromEnum)(EVRSettingsError eError); - bool (OPENVR_FNTABLE_CALLTYPE *Sync)(bool bForce, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *SetBool)(char * pchSection, char * pchSettingsKey, bool bValue, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *SetInt32)(char * pchSection, char * pchSettingsKey, int32_t nValue, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *SetFloat)(char * pchSection, char * pchSettingsKey, float flValue, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *SetString)(char * pchSection, char * pchSettingsKey, char * pchValue, EVRSettingsError * peError); - bool (OPENVR_FNTABLE_CALLTYPE *GetBool)(char * pchSection, char * pchSettingsKey, EVRSettingsError * peError); - int32_t (OPENVR_FNTABLE_CALLTYPE *GetInt32)(char * pchSection, char * pchSettingsKey, EVRSettingsError * peError); - float (OPENVR_FNTABLE_CALLTYPE *GetFloat)(char * pchSection, char * pchSettingsKey, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *GetString)(char * pchSection, char * pchSettingsKey, char * pchValue, uint32_t unValueLen, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *RemoveSection)(char * pchSection, EVRSettingsError * peError); - void (OPENVR_FNTABLE_CALLTYPE *RemoveKeyInSection)(char * pchSection, char * pchSettingsKey, EVRSettingsError * peError); + char *(OPENVR_FNTABLE_CALLTYPE *GetSettingsErrorNameFromEnum)(EVRSettingsError eError); + bool(OPENVR_FNTABLE_CALLTYPE *Sync)(bool bForce, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *SetBool)(char *pchSection, char *pchSettingsKey, bool bValue, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *SetInt32)(char *pchSection, char *pchSettingsKey, int32_t nValue, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *SetFloat)(char *pchSection, char *pchSettingsKey, float flValue, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *SetString)(char *pchSection, char *pchSettingsKey, char *pchValue, EVRSettingsError *peError); + bool(OPENVR_FNTABLE_CALLTYPE *GetBool)(char *pchSection, char *pchSettingsKey, EVRSettingsError *peError); + int32_t(OPENVR_FNTABLE_CALLTYPE *GetInt32)(char *pchSection, char *pchSettingsKey, EVRSettingsError *peError); + float(OPENVR_FNTABLE_CALLTYPE *GetFloat)(char *pchSection, char *pchSettingsKey, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *GetString)(char *pchSection, char *pchSettingsKey, char *pchValue, uint32_t unValueLen, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *RemoveSection)(char *pchSection, EVRSettingsError *peError); + void(OPENVR_FNTABLE_CALLTYPE *RemoveKeyInSection)(char *pchSection, char *pchSettingsKey, EVRSettingsError *peError); }; struct VR_IVRScreenshots_FnTable { - EVRScreenshotError (OPENVR_FNTABLE_CALLTYPE *RequestScreenshot)(ScreenshotHandle_t * pOutScreenshotHandle, EVRScreenshotType type, char * pchPreviewFilename, char * pchVRFilename); - EVRScreenshotError (OPENVR_FNTABLE_CALLTYPE *HookScreenshot)(EVRScreenshotType * pSupportedTypes, int numTypes); - EVRScreenshotType (OPENVR_FNTABLE_CALLTYPE *GetScreenshotPropertyType)(ScreenshotHandle_t screenshotHandle, EVRScreenshotError * pError); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetScreenshotPropertyFilename)(ScreenshotHandle_t screenshotHandle, EVRScreenshotPropertyFilenames filenameType, char * pchFilename, uint32_t cchFilename, EVRScreenshotError * pError); - EVRScreenshotError (OPENVR_FNTABLE_CALLTYPE *UpdateScreenshotProgress)(ScreenshotHandle_t screenshotHandle, float flProgress); - EVRScreenshotError (OPENVR_FNTABLE_CALLTYPE *TakeStereoScreenshot)(ScreenshotHandle_t * pOutScreenshotHandle, char * pchPreviewFilename, char * pchVRFilename); - EVRScreenshotError (OPENVR_FNTABLE_CALLTYPE *SubmitScreenshot)(ScreenshotHandle_t screenshotHandle, EVRScreenshotType type, char * pchSourcePreviewFilename, char * pchSourceVRFilename); + EVRScreenshotError(OPENVR_FNTABLE_CALLTYPE *RequestScreenshot)(ScreenshotHandle_t *pOutScreenshotHandle, EVRScreenshotType type, char *pchPreviewFilename, char *pchVRFilename); + EVRScreenshotError(OPENVR_FNTABLE_CALLTYPE *HookScreenshot)(EVRScreenshotType *pSupportedTypes, int numTypes); + EVRScreenshotType(OPENVR_FNTABLE_CALLTYPE *GetScreenshotPropertyType)(ScreenshotHandle_t screenshotHandle, EVRScreenshotError *pError); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetScreenshotPropertyFilename)(ScreenshotHandle_t screenshotHandle, EVRScreenshotPropertyFilenames filenameType, char *pchFilename, uint32_t cchFilename, EVRScreenshotError *pError); + EVRScreenshotError(OPENVR_FNTABLE_CALLTYPE *UpdateScreenshotProgress)(ScreenshotHandle_t screenshotHandle, float flProgress); + EVRScreenshotError(OPENVR_FNTABLE_CALLTYPE *TakeStereoScreenshot)(ScreenshotHandle_t *pOutScreenshotHandle, char *pchPreviewFilename, char *pchVRFilename); + EVRScreenshotError(OPENVR_FNTABLE_CALLTYPE *SubmitScreenshot)(ScreenshotHandle_t screenshotHandle, EVRScreenshotType type, char *pchSourcePreviewFilename, char *pchSourceVRFilename); }; struct VR_IVRResources_FnTable { - uint32_t (OPENVR_FNTABLE_CALLTYPE *LoadSharedResource)(char * pchResourceName, char * pchBuffer, uint32_t unBufferLen); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetResourceFullPath)(char * pchResourceName, char * pchResourceTypeDirectory, char * pchPathBuffer, uint32_t unBufferLen); + uint32_t(OPENVR_FNTABLE_CALLTYPE *LoadSharedResource)(char *pchResourceName, char *pchBuffer, uint32_t unBufferLen); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetResourceFullPath)(char *pchResourceName, char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen); }; struct VR_IVRDriverManager_FnTable { - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetDriverCount)(); - uint32_t (OPENVR_FNTABLE_CALLTYPE *GetDriverName)(DriverId_t nDriver, char * pchValue, uint32_t unBufferSize); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetDriverCount)(); + uint32_t(OPENVR_FNTABLE_CALLTYPE *GetDriverName)(DriverId_t nDriver, char *pchValue, uint32_t unBufferSize); }; - #if 0 // Global entry points S_API intptr_t VR_InitInternal( EVRInitError *peError, EVRApplicationType eType ); @@ -1937,6 +1929,4 @@ S_API const char * VR_GetVRInitErrorAsSymbol( EVRInitError error ); S_API const char * VR_GetVRInitErrorAsEnglishDescription( EVRInitError error ); #endif -#endif // __OPENVR_API_FLAT_H__ - - +#endif // __OPENVR_API_FLAT_H__ diff --git a/examples/ThirdPartyLibs/openvr/headers/openvr_driver.h b/examples/ThirdPartyLibs/openvr/headers/openvr_driver.h index 7ab997e25..b07699f82 100644 --- a/examples/ThirdPartyLibs/openvr/headers/openvr_driver.h +++ b/examples/ThirdPartyLibs/openvr/headers/openvr_driver.h @@ -9,8 +9,6 @@ #include - - // vrtypes.h #ifndef _INCLUDE_VRTYPES_H #define _INCLUDE_VRTYPES_H @@ -27,9 +25,9 @@ struct ID3D12CommandQueue; namespace vr { -#pragma pack( push, 8 ) +#pragma pack(push, 8) -typedef void* glSharedTextureHandle_t; +typedef void *glSharedTextureHandle_t; typedef int32_t glInt_t; typedef uint32_t glUInt_t; @@ -80,7 +78,7 @@ struct HmdColor_t struct HmdQuad_t { - HmdVector3_t vCorners[ 4 ]; + HmdVector3_t vCorners[4]; }; struct HmdRect2_t @@ -107,40 +105,40 @@ enum EVREye enum ETextureType { - TextureType_DirectX = 0, // Handle is an ID3D11Texture - TextureType_OpenGL = 1, // Handle is an OpenGL texture name or an OpenGL render buffer name, depending on submit flags - TextureType_Vulkan = 2, // Handle is a pointer to a VRVulkanTextureData_t structure - TextureType_IOSurface = 3, // Handle is a macOS cross-process-sharable IOSurfaceRef - TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure + TextureType_DirectX = 0, // Handle is an ID3D11Texture + TextureType_OpenGL = 1, // Handle is an OpenGL texture name or an OpenGL render buffer name, depending on submit flags + TextureType_Vulkan = 2, // Handle is a pointer to a VRVulkanTextureData_t structure + TextureType_IOSurface = 3, // Handle is a macOS cross-process-sharable IOSurfaceRef + TextureType_DirectX12 = 4, // Handle is a pointer to a D3D12TextureData_t structure }; enum EColorSpace { - ColorSpace_Auto = 0, // Assumes 'gamma' for 8-bit per component formats, otherwise 'linear'. This mirrors the DXGI formats which have _SRGB variants. - ColorSpace_Gamma = 1, // Texture data can be displayed directly on the display without any conversion (a.k.a. display native format). - ColorSpace_Linear = 2, // Same as gamma but has been converted to a linear representation using DXGI's sRGB conversion algorithm. + ColorSpace_Auto = 0, // Assumes 'gamma' for 8-bit per component formats, otherwise 'linear'. This mirrors the DXGI formats which have _SRGB variants. + ColorSpace_Gamma = 1, // Texture data can be displayed directly on the display without any conversion (a.k.a. display native format). + ColorSpace_Linear = 2, // Same as gamma but has been converted to a linear representation using DXGI's sRGB conversion algorithm. }; struct Texture_t { - void* handle; // See ETextureType definition above + void *handle; // See ETextureType definition above ETextureType eType; EColorSpace eColorSpace; }; // Handle to a shared texture (HANDLE on Windows obtained using OpenSharedResource). typedef uint64_t SharedTextureHandle_t; -#define INVALID_SHARED_TEXTURE_HANDLE ((vr::SharedTextureHandle_t)0) +#define INVALID_SHARED_TEXTURE_HANDLE ((vr::SharedTextureHandle_t)0) enum ETrackingResult { - TrackingResult_Uninitialized = 1, + TrackingResult_Uninitialized = 1, - TrackingResult_Calibrating_InProgress = 100, - TrackingResult_Calibrating_OutOfRange = 101, + TrackingResult_Calibrating_InProgress = 100, + TrackingResult_Calibrating_OutOfRange = 101, - TrackingResult_Running_OK = 200, - TrackingResult_Running_OutOfRange = 201, + TrackingResult_Running_OK = 200, + TrackingResult_Running_OutOfRange = 201, }; typedef uint32_t DriverId_t; @@ -158,30 +156,28 @@ static const uint32_t k_unTrackedDeviceIndexInvalid = 0xFFFFFFFF; /** Describes what kind of object is being tracked at a given ID */ enum ETrackedDeviceClass { - TrackedDeviceClass_Invalid = 0, // the ID was not valid. - TrackedDeviceClass_HMD = 1, // Head-Mounted Displays - TrackedDeviceClass_Controller = 2, // Tracked controllers - TrackedDeviceClass_GenericTracker = 3, // Generic trackers, similar to controllers - TrackedDeviceClass_TrackingReference = 4, // Camera and base stations that serve as tracking reference points - TrackedDeviceClass_DisplayRedirect = 5, // Accessories that aren't necessarily tracked themselves, but may redirect video output from other tracked devices + TrackedDeviceClass_Invalid = 0, // the ID was not valid. + TrackedDeviceClass_HMD = 1, // Head-Mounted Displays + TrackedDeviceClass_Controller = 2, // Tracked controllers + TrackedDeviceClass_GenericTracker = 3, // Generic trackers, similar to controllers + TrackedDeviceClass_TrackingReference = 4, // Camera and base stations that serve as tracking reference points + TrackedDeviceClass_DisplayRedirect = 5, // Accessories that aren't necessarily tracked themselves, but may redirect video output from other tracked devices }; - /** Describes what specific role associated with a tracked device */ enum ETrackedControllerRole { - TrackedControllerRole_Invalid = 0, // Invalid value for controller type - TrackedControllerRole_LeftHand = 1, // Tracked device associated with the left hand - TrackedControllerRole_RightHand = 2, // Tracked device associated with the right hand + TrackedControllerRole_Invalid = 0, // Invalid value for controller type + TrackedControllerRole_LeftHand = 1, // Tracked device associated with the left hand + TrackedControllerRole_RightHand = 2, // Tracked device associated with the right hand }; - /** describes a single pose for a tracked object */ struct TrackedDevicePose_t { HmdMatrix34_t mDeviceToAbsoluteTracking; - HmdVector3_t vVelocity; // velocity in tracker space in m/s - HmdVector3_t vAngularVelocity; // angular velocity in radians/s (?) + HmdVector3_t vVelocity; // velocity in tracker space in m/s + HmdVector3_t vAngularVelocity; // angular velocity in radians/s (?) ETrackingResult eTrackingResult; bool bPoseIsValid; @@ -194,9 +190,9 @@ struct TrackedDevicePose_t * for the poses it is requesting */ enum ETrackingUniverseOrigin { - TrackingUniverseSeated = 0, // Poses are provided relative to the seated zero pose - TrackingUniverseStanding = 1, // Poses are provided relative to the safe bounds configured by the user - TrackingUniverseRawAndUncalibrated = 2, // Poses are provided in the coordinate system defined by the driver. It has Y up and is unified for devices of the same driver. You usually don't want this one. + TrackingUniverseSeated = 0, // Poses are provided relative to the seated zero pose + TrackingUniverseStanding = 1, // Poses are provided relative to the safe bounds configured by the user + TrackingUniverseRawAndUncalibrated = 2, // Poses are provided in the coordinate system defined by the driver. It has Y up and is unified for devices of the same driver. You usually don't want this one. }; // Refers to a single container of properties @@ -223,146 +219,145 @@ static const PropertyTypeTag_t k_unHiddenAreaPropertyTag = 30; static const PropertyTypeTag_t k_unOpenVRInternalReserved_Start = 1000; static const PropertyTypeTag_t k_unOpenVRInternalReserved_End = 10000; - /** Each entry in this enum represents a property that can be retrieved about a * tracked device. Many fields are only valid for one ETrackedDeviceClass. */ enum ETrackedDeviceProperty { - Prop_Invalid = 0, + Prop_Invalid = 0, // general properties that apply to all device classes - Prop_TrackingSystemName_String = 1000, - Prop_ModelNumber_String = 1001, - Prop_SerialNumber_String = 1002, - Prop_RenderModelName_String = 1003, - Prop_WillDriftInYaw_Bool = 1004, - Prop_ManufacturerName_String = 1005, - Prop_TrackingFirmwareVersion_String = 1006, - Prop_HardwareRevision_String = 1007, - Prop_AllWirelessDongleDescriptions_String = 1008, - Prop_ConnectedWirelessDongle_String = 1009, - Prop_DeviceIsWireless_Bool = 1010, - Prop_DeviceIsCharging_Bool = 1011, - Prop_DeviceBatteryPercentage_Float = 1012, // 0 is empty, 1 is full - Prop_StatusDisplayTransform_Matrix34 = 1013, - Prop_Firmware_UpdateAvailable_Bool = 1014, - Prop_Firmware_ManualUpdate_Bool = 1015, - Prop_Firmware_ManualUpdateURL_String = 1016, - Prop_HardwareRevision_Uint64 = 1017, - Prop_FirmwareVersion_Uint64 = 1018, - Prop_FPGAVersion_Uint64 = 1019, - Prop_VRCVersion_Uint64 = 1020, - Prop_RadioVersion_Uint64 = 1021, - Prop_DongleVersion_Uint64 = 1022, - Prop_BlockServerShutdown_Bool = 1023, - Prop_CanUnifyCoordinateSystemWithHmd_Bool = 1024, - Prop_ContainsProximitySensor_Bool = 1025, - Prop_DeviceProvidesBatteryStatus_Bool = 1026, - Prop_DeviceCanPowerOff_Bool = 1027, - Prop_Firmware_ProgrammingTarget_String = 1028, - Prop_DeviceClass_Int32 = 1029, - Prop_HasCamera_Bool = 1030, - Prop_DriverVersion_String = 1031, - Prop_Firmware_ForceUpdateRequired_Bool = 1032, - Prop_ViveSystemButtonFixRequired_Bool = 1033, - Prop_ParentDriver_Uint64 = 1034, - Prop_ResourceRoot_String = 1035, + Prop_TrackingSystemName_String = 1000, + Prop_ModelNumber_String = 1001, + Prop_SerialNumber_String = 1002, + Prop_RenderModelName_String = 1003, + Prop_WillDriftInYaw_Bool = 1004, + Prop_ManufacturerName_String = 1005, + Prop_TrackingFirmwareVersion_String = 1006, + Prop_HardwareRevision_String = 1007, + Prop_AllWirelessDongleDescriptions_String = 1008, + Prop_ConnectedWirelessDongle_String = 1009, + Prop_DeviceIsWireless_Bool = 1010, + Prop_DeviceIsCharging_Bool = 1011, + Prop_DeviceBatteryPercentage_Float = 1012, // 0 is empty, 1 is full + Prop_StatusDisplayTransform_Matrix34 = 1013, + Prop_Firmware_UpdateAvailable_Bool = 1014, + Prop_Firmware_ManualUpdate_Bool = 1015, + Prop_Firmware_ManualUpdateURL_String = 1016, + Prop_HardwareRevision_Uint64 = 1017, + Prop_FirmwareVersion_Uint64 = 1018, + Prop_FPGAVersion_Uint64 = 1019, + Prop_VRCVersion_Uint64 = 1020, + Prop_RadioVersion_Uint64 = 1021, + Prop_DongleVersion_Uint64 = 1022, + Prop_BlockServerShutdown_Bool = 1023, + Prop_CanUnifyCoordinateSystemWithHmd_Bool = 1024, + Prop_ContainsProximitySensor_Bool = 1025, + Prop_DeviceProvidesBatteryStatus_Bool = 1026, + Prop_DeviceCanPowerOff_Bool = 1027, + Prop_Firmware_ProgrammingTarget_String = 1028, + Prop_DeviceClass_Int32 = 1029, + Prop_HasCamera_Bool = 1030, + Prop_DriverVersion_String = 1031, + Prop_Firmware_ForceUpdateRequired_Bool = 1032, + Prop_ViveSystemButtonFixRequired_Bool = 1033, + Prop_ParentDriver_Uint64 = 1034, + Prop_ResourceRoot_String = 1035, // Properties that are unique to TrackedDeviceClass_HMD - Prop_ReportsTimeSinceVSync_Bool = 2000, - Prop_SecondsFromVsyncToPhotons_Float = 2001, - Prop_DisplayFrequency_Float = 2002, - Prop_UserIpdMeters_Float = 2003, - Prop_CurrentUniverseId_Uint64 = 2004, - Prop_PreviousUniverseId_Uint64 = 2005, - Prop_DisplayFirmwareVersion_Uint64 = 2006, - Prop_IsOnDesktop_Bool = 2007, - Prop_DisplayMCType_Int32 = 2008, - Prop_DisplayMCOffset_Float = 2009, - Prop_DisplayMCScale_Float = 2010, - Prop_EdidVendorID_Int32 = 2011, - Prop_DisplayMCImageLeft_String = 2012, - Prop_DisplayMCImageRight_String = 2013, - Prop_DisplayGCBlackClamp_Float = 2014, - Prop_EdidProductID_Int32 = 2015, - Prop_CameraToHeadTransform_Matrix34 = 2016, - Prop_DisplayGCType_Int32 = 2017, - Prop_DisplayGCOffset_Float = 2018, - Prop_DisplayGCScale_Float = 2019, - Prop_DisplayGCPrescale_Float = 2020, - Prop_DisplayGCImage_String = 2021, - Prop_LensCenterLeftU_Float = 2022, - Prop_LensCenterLeftV_Float = 2023, - Prop_LensCenterRightU_Float = 2024, - Prop_LensCenterRightV_Float = 2025, - Prop_UserHeadToEyeDepthMeters_Float = 2026, - Prop_CameraFirmwareVersion_Uint64 = 2027, - Prop_CameraFirmwareDescription_String = 2028, - Prop_DisplayFPGAVersion_Uint64 = 2029, - Prop_DisplayBootloaderVersion_Uint64 = 2030, - Prop_DisplayHardwareVersion_Uint64 = 2031, - Prop_AudioFirmwareVersion_Uint64 = 2032, - Prop_CameraCompatibilityMode_Int32 = 2033, + Prop_ReportsTimeSinceVSync_Bool = 2000, + Prop_SecondsFromVsyncToPhotons_Float = 2001, + Prop_DisplayFrequency_Float = 2002, + Prop_UserIpdMeters_Float = 2003, + Prop_CurrentUniverseId_Uint64 = 2004, + Prop_PreviousUniverseId_Uint64 = 2005, + Prop_DisplayFirmwareVersion_Uint64 = 2006, + Prop_IsOnDesktop_Bool = 2007, + Prop_DisplayMCType_Int32 = 2008, + Prop_DisplayMCOffset_Float = 2009, + Prop_DisplayMCScale_Float = 2010, + Prop_EdidVendorID_Int32 = 2011, + Prop_DisplayMCImageLeft_String = 2012, + Prop_DisplayMCImageRight_String = 2013, + Prop_DisplayGCBlackClamp_Float = 2014, + Prop_EdidProductID_Int32 = 2015, + Prop_CameraToHeadTransform_Matrix34 = 2016, + Prop_DisplayGCType_Int32 = 2017, + Prop_DisplayGCOffset_Float = 2018, + Prop_DisplayGCScale_Float = 2019, + Prop_DisplayGCPrescale_Float = 2020, + Prop_DisplayGCImage_String = 2021, + Prop_LensCenterLeftU_Float = 2022, + Prop_LensCenterLeftV_Float = 2023, + Prop_LensCenterRightU_Float = 2024, + Prop_LensCenterRightV_Float = 2025, + Prop_UserHeadToEyeDepthMeters_Float = 2026, + Prop_CameraFirmwareVersion_Uint64 = 2027, + Prop_CameraFirmwareDescription_String = 2028, + Prop_DisplayFPGAVersion_Uint64 = 2029, + Prop_DisplayBootloaderVersion_Uint64 = 2030, + Prop_DisplayHardwareVersion_Uint64 = 2031, + Prop_AudioFirmwareVersion_Uint64 = 2032, + Prop_CameraCompatibilityMode_Int32 = 2033, Prop_ScreenshotHorizontalFieldOfViewDegrees_Float = 2034, Prop_ScreenshotVerticalFieldOfViewDegrees_Float = 2035, - Prop_DisplaySuppressed_Bool = 2036, - Prop_DisplayAllowNightMode_Bool = 2037, - Prop_DisplayMCImageWidth_Int32 = 2038, - Prop_DisplayMCImageHeight_Int32 = 2039, - Prop_DisplayMCImageNumChannels_Int32 = 2040, - Prop_DisplayMCImageData_Binary = 2041, - Prop_SecondsFromPhotonsToVblank_Float = 2042, - Prop_DriverDirectModeSendsVsyncEvents_Bool = 2043, - Prop_DisplayDebugMode_Bool = 2044, - Prop_GraphicsAdapterLuid_Uint64 = 2045, - Prop_DriverProvidedChaperonePath_String = 2048, + Prop_DisplaySuppressed_Bool = 2036, + Prop_DisplayAllowNightMode_Bool = 2037, + Prop_DisplayMCImageWidth_Int32 = 2038, + Prop_DisplayMCImageHeight_Int32 = 2039, + Prop_DisplayMCImageNumChannels_Int32 = 2040, + Prop_DisplayMCImageData_Binary = 2041, + Prop_SecondsFromPhotonsToVblank_Float = 2042, + Prop_DriverDirectModeSendsVsyncEvents_Bool = 2043, + Prop_DisplayDebugMode_Bool = 2044, + Prop_GraphicsAdapterLuid_Uint64 = 2045, + Prop_DriverProvidedChaperonePath_String = 2048, // Properties that are unique to TrackedDeviceClass_Controller - Prop_AttachedDeviceId_String = 3000, - Prop_SupportedButtons_Uint64 = 3001, - Prop_Axis0Type_Int32 = 3002, // Return value is of type EVRControllerAxisType - Prop_Axis1Type_Int32 = 3003, // Return value is of type EVRControllerAxisType - Prop_Axis2Type_Int32 = 3004, // Return value is of type EVRControllerAxisType - Prop_Axis3Type_Int32 = 3005, // Return value is of type EVRControllerAxisType - Prop_Axis4Type_Int32 = 3006, // Return value is of type EVRControllerAxisType - Prop_ControllerRoleHint_Int32 = 3007, // Return value is of type ETrackedControllerRole + Prop_AttachedDeviceId_String = 3000, + Prop_SupportedButtons_Uint64 = 3001, + Prop_Axis0Type_Int32 = 3002, // Return value is of type EVRControllerAxisType + Prop_Axis1Type_Int32 = 3003, // Return value is of type EVRControllerAxisType + Prop_Axis2Type_Int32 = 3004, // Return value is of type EVRControllerAxisType + Prop_Axis3Type_Int32 = 3005, // Return value is of type EVRControllerAxisType + Prop_Axis4Type_Int32 = 3006, // Return value is of type EVRControllerAxisType + Prop_ControllerRoleHint_Int32 = 3007, // Return value is of type ETrackedControllerRole // Properties that are unique to TrackedDeviceClass_TrackingReference - Prop_FieldOfViewLeftDegrees_Float = 4000, - Prop_FieldOfViewRightDegrees_Float = 4001, - Prop_FieldOfViewTopDegrees_Float = 4002, - Prop_FieldOfViewBottomDegrees_Float = 4003, - Prop_TrackingRangeMinimumMeters_Float = 4004, - Prop_TrackingRangeMaximumMeters_Float = 4005, - Prop_ModeLabel_String = 4006, + Prop_FieldOfViewLeftDegrees_Float = 4000, + Prop_FieldOfViewRightDegrees_Float = 4001, + Prop_FieldOfViewTopDegrees_Float = 4002, + Prop_FieldOfViewBottomDegrees_Float = 4003, + Prop_TrackingRangeMinimumMeters_Float = 4004, + Prop_TrackingRangeMaximumMeters_Float = 4005, + Prop_ModeLabel_String = 4006, // Properties that are used for user interface like icons names - Prop_IconPathName_String = 5000, // DEPRECATED. Value not referenced. Now expected to be part of icon path properties. - Prop_NamedIconPathDeviceOff_String = 5001, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceSearching_String = 5002, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceSearchingAlert_String = 5003, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceReady_String = 5004, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceReadyAlert_String = 5005, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceNotReady_String = 5006, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceStandby_String = 5007, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others - Prop_NamedIconPathDeviceAlertLow_String = 5008, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_IconPathName_String = 5000, // DEPRECATED. Value not referenced. Now expected to be part of icon path properties. + Prop_NamedIconPathDeviceOff_String = 5001, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceSearching_String = 5002, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceSearchingAlert_String = 5003, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceReady_String = 5004, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceReadyAlert_String = 5005, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceNotReady_String = 5006, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceStandby_String = 5007, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others + Prop_NamedIconPathDeviceAlertLow_String = 5008, // {driver}/icons/icon_filename - PNG for static icon, or GIF for animation, 50x32 for headsets and 32x32 for others // Properties that are used by helpers, but are opaque to applications - Prop_DisplayHiddenArea_Binary_Start = 5100, - Prop_DisplayHiddenArea_Binary_End = 5150, + Prop_DisplayHiddenArea_Binary_Start = 5100, + Prop_DisplayHiddenArea_Binary_End = 5150, // Properties that are unique to drivers - Prop_UserConfigPath_String = 6000, - Prop_InstallPath_String = 6001, - Prop_HasDisplayComponent_Bool = 6002, - Prop_HasControllerComponent_Bool = 6003, - Prop_HasCameraComponent_Bool = 6004, - Prop_HasDriverDirectModeComponent_Bool = 6005, - Prop_HasVirtualDisplayComponent_Bool = 6006, + Prop_UserConfigPath_String = 6000, + Prop_InstallPath_String = 6001, + Prop_HasDisplayComponent_Bool = 6002, + Prop_HasControllerComponent_Bool = 6003, + Prop_HasCameraComponent_Bool = 6004, + Prop_HasDriverDirectModeComponent_Bool = 6005, + Prop_HasVirtualDisplayComponent_Bool = 6006, // Vendors are free to expose private debug data in this reserved region - Prop_VendorSpecific_Reserved_Start = 10000, - Prop_VendorSpecific_Reserved_End = 10999, + Prop_VendorSpecific_Reserved_Start = 10000, + Prop_VendorSpecific_Reserved_End = 10999, }; /** No string property will ever be longer than this length */ @@ -371,18 +366,18 @@ static const uint32_t k_unMaxPropertyStringSize = 32 * 1024; /** Used to return errors that occur when reading properties. */ enum ETrackedPropertyError { - TrackedProp_Success = 0, - TrackedProp_WrongDataType = 1, - TrackedProp_WrongDeviceClass = 2, - TrackedProp_BufferTooSmall = 3, - TrackedProp_UnknownProperty = 4, // Driver has not set the property (and may not ever). - TrackedProp_InvalidDevice = 5, - TrackedProp_CouldNotContactServer = 6, - TrackedProp_ValueNotProvidedByDevice = 7, - TrackedProp_StringExceedsMaximumLength = 8, - TrackedProp_NotYetAvailable = 9, // The property value isn't known yet, but is expected soon. Call again later. - TrackedProp_PermissionDenied = 10, - TrackedProp_InvalidOperation = 11, + TrackedProp_Success = 0, + TrackedProp_WrongDataType = 1, + TrackedProp_WrongDeviceClass = 2, + TrackedProp_BufferTooSmall = 3, + TrackedProp_UnknownProperty = 4, // Driver has not set the property (and may not ever). + TrackedProp_InvalidDevice = 5, + TrackedProp_CouldNotContactServer = 6, + TrackedProp_ValueNotProvidedByDevice = 7, + TrackedProp_StringExceedsMaximumLength = 8, + TrackedProp_NotYetAvailable = 9, // The property value isn't known yet, but is expected soon. Call again later. + TrackedProp_PermissionDenied = 10, + TrackedProp_InvalidOperation = 11, }; /** Allows the application to control what part of the provided texture will be used in the @@ -396,7 +391,7 @@ struct VRTextureBounds_t /** Allows specifying pose used to render provided scene texture (if different from value returned by WaitGetPoses). */ struct VRTextureWithPose_t : public Texture_t { - HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures. + HmdMatrix34_t mDeviceToAbsoluteTracking; // Actual pose used to render scene textures. }; /** Allows the application to control how scene textures are used by the compositor when calling Submit. */ @@ -424,7 +419,7 @@ enum EVRSubmitFlags * Be sure to call OpenVR_Shutdown before destroying these resources. */ struct VRVulkanTextureData_t { - uint64_t m_nImage; // VkImage + uint64_t m_nImage; // VkImage VkDevice_T *m_pDevice; VkPhysicalDevice_T *m_pPhysicalDevice; VkInstance_T *m_pInstance; @@ -461,220 +456,216 @@ enum EVREventType { VREvent_None = 0, - VREvent_TrackedDeviceActivated = 100, - VREvent_TrackedDeviceDeactivated = 101, - VREvent_TrackedDeviceUpdated = 102, - VREvent_TrackedDeviceUserInteractionStarted = 103, - VREvent_TrackedDeviceUserInteractionEnded = 104, - VREvent_IpdChanged = 105, - VREvent_EnterStandbyMode = 106, - VREvent_LeaveStandbyMode = 107, - VREvent_TrackedDeviceRoleChanged = 108, - VREvent_WatchdogWakeUpRequested = 109, - VREvent_LensDistortionChanged = 110, - VREvent_PropertyChanged = 111, - VREvent_WirelessDisconnect = 112, - VREvent_WirelessReconnect = 113, + VREvent_TrackedDeviceActivated = 100, + VREvent_TrackedDeviceDeactivated = 101, + VREvent_TrackedDeviceUpdated = 102, + VREvent_TrackedDeviceUserInteractionStarted = 103, + VREvent_TrackedDeviceUserInteractionEnded = 104, + VREvent_IpdChanged = 105, + VREvent_EnterStandbyMode = 106, + VREvent_LeaveStandbyMode = 107, + VREvent_TrackedDeviceRoleChanged = 108, + VREvent_WatchdogWakeUpRequested = 109, + VREvent_LensDistortionChanged = 110, + VREvent_PropertyChanged = 111, + VREvent_WirelessDisconnect = 112, + VREvent_WirelessReconnect = 113, - VREvent_ButtonPress = 200, // data is controller - VREvent_ButtonUnpress = 201, // data is controller - VREvent_ButtonTouch = 202, // data is controller - VREvent_ButtonUntouch = 203, // data is controller + VREvent_ButtonPress = 200, // data is controller + VREvent_ButtonUnpress = 201, // data is controller + VREvent_ButtonTouch = 202, // data is controller + VREvent_ButtonUntouch = 203, // data is controller - VREvent_MouseMove = 300, // data is mouse - VREvent_MouseButtonDown = 301, // data is mouse - VREvent_MouseButtonUp = 302, // data is mouse - VREvent_FocusEnter = 303, // data is overlay - VREvent_FocusLeave = 304, // data is overlay - VREvent_Scroll = 305, // data is mouse - VREvent_TouchPadMove = 306, // data is mouse - VREvent_OverlayFocusChanged = 307, // data is overlay, global event + VREvent_MouseMove = 300, // data is mouse + VREvent_MouseButtonDown = 301, // data is mouse + VREvent_MouseButtonUp = 302, // data is mouse + VREvent_FocusEnter = 303, // data is overlay + VREvent_FocusLeave = 304, // data is overlay + VREvent_Scroll = 305, // data is mouse + VREvent_TouchPadMove = 306, // data is mouse + VREvent_OverlayFocusChanged = 307, // data is overlay, global event - VREvent_InputFocusCaptured = 400, // data is process DEPRECATED - VREvent_InputFocusReleased = 401, // data is process DEPRECATED - VREvent_SceneFocusLost = 402, // data is process - VREvent_SceneFocusGained = 403, // data is process - VREvent_SceneApplicationChanged = 404, // data is process - The App actually drawing the scene changed (usually to or from the compositor) - VREvent_SceneFocusChanged = 405, // data is process - New app got access to draw the scene - VREvent_InputFocusChanged = 406, // data is process - VREvent_SceneApplicationSecondaryRenderingStarted = 407, // data is process + VREvent_InputFocusCaptured = 400, // data is process DEPRECATED + VREvent_InputFocusReleased = 401, // data is process DEPRECATED + VREvent_SceneFocusLost = 402, // data is process + VREvent_SceneFocusGained = 403, // data is process + VREvent_SceneApplicationChanged = 404, // data is process - The App actually drawing the scene changed (usually to or from the compositor) + VREvent_SceneFocusChanged = 405, // data is process - New app got access to draw the scene + VREvent_InputFocusChanged = 406, // data is process + VREvent_SceneApplicationSecondaryRenderingStarted = 407, // data is process - VREvent_HideRenderModels = 410, // Sent to the scene application to request hiding render models temporarily - VREvent_ShowRenderModels = 411, // Sent to the scene application to request restoring render model visibility + VREvent_HideRenderModels = 410, // Sent to the scene application to request hiding render models temporarily + VREvent_ShowRenderModels = 411, // Sent to the scene application to request restoring render model visibility - VREvent_OverlayShown = 500, - VREvent_OverlayHidden = 501, - VREvent_DashboardActivated = 502, - VREvent_DashboardDeactivated = 503, - VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay - VREvent_DashboardRequested = 505, // Sent to the overlay manager - data is overlay - VREvent_ResetDashboard = 506, // Send to the overlay manager - VREvent_RenderToast = 507, // Send to the dashboard to render a toast - data is the notification ID - VREvent_ImageLoaded = 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading - VREvent_ShowKeyboard = 509, // Sent to keyboard renderer in the dashboard to invoke it - VREvent_HideKeyboard = 510, // Sent to keyboard renderer in the dashboard to hide it - VREvent_OverlayGamepadFocusGained = 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it - VREvent_OverlayGamepadFocusLost = 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else + VREvent_OverlayShown = 500, + VREvent_OverlayHidden = 501, + VREvent_DashboardActivated = 502, + VREvent_DashboardDeactivated = 503, + VREvent_DashboardThumbSelected = 504, // Sent to the overlay manager - data is overlay + VREvent_DashboardRequested = 505, // Sent to the overlay manager - data is overlay + VREvent_ResetDashboard = 506, // Send to the overlay manager + VREvent_RenderToast = 507, // Send to the dashboard to render a toast - data is the notification ID + VREvent_ImageLoaded = 508, // Sent to overlays when a SetOverlayRaw or SetOverlayFromFile call finishes loading + VREvent_ShowKeyboard = 509, // Sent to keyboard renderer in the dashboard to invoke it + VREvent_HideKeyboard = 510, // Sent to keyboard renderer in the dashboard to hide it + VREvent_OverlayGamepadFocusGained = 511, // Sent to an overlay when IVROverlay::SetFocusOverlay is called on it + VREvent_OverlayGamepadFocusLost = 512, // Send to an overlay when it previously had focus and IVROverlay::SetFocusOverlay is called on something else VREvent_OverlaySharedTextureChanged = 513, - VREvent_DashboardGuideButtonDown = 514, - VREvent_DashboardGuideButtonUp = 515, - VREvent_ScreenshotTriggered = 516, // Screenshot button combo was pressed, Dashboard should request a screenshot - VREvent_ImageFailed = 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load - VREvent_DashboardOverlayCreated = 518, + VREvent_DashboardGuideButtonDown = 514, + VREvent_DashboardGuideButtonUp = 515, + VREvent_ScreenshotTriggered = 516, // Screenshot button combo was pressed, Dashboard should request a screenshot + VREvent_ImageFailed = 517, // Sent to overlays when a SetOverlayRaw or SetOverlayfromFail fails to load + VREvent_DashboardOverlayCreated = 518, // Screenshot API - VREvent_RequestScreenshot = 520, // Sent by vrclient application to compositor to take a screenshot - VREvent_ScreenshotTaken = 521, // Sent by compositor to the application that the screenshot has been taken - VREvent_ScreenshotFailed = 522, // Sent by compositor to the application that the screenshot failed to be taken - VREvent_SubmitScreenshotToDashboard = 523, // Sent by compositor to the dashboard that a completed screenshot was submitted - VREvent_ScreenshotProgressToDashboard = 524, // Sent by compositor to the dashboard that a completed screenshot was submitted + VREvent_RequestScreenshot = 520, // Sent by vrclient application to compositor to take a screenshot + VREvent_ScreenshotTaken = 521, // Sent by compositor to the application that the screenshot has been taken + VREvent_ScreenshotFailed = 522, // Sent by compositor to the application that the screenshot failed to be taken + VREvent_SubmitScreenshotToDashboard = 523, // Sent by compositor to the dashboard that a completed screenshot was submitted + VREvent_ScreenshotProgressToDashboard = 524, // Sent by compositor to the dashboard that a completed screenshot was submitted - VREvent_PrimaryDashboardDeviceChanged = 525, + VREvent_PrimaryDashboardDeviceChanged = 525, - VREvent_Notification_Shown = 600, - VREvent_Notification_Hidden = 601, - VREvent_Notification_BeginInteraction = 602, - VREvent_Notification_Destroyed = 603, + VREvent_Notification_Shown = 600, + VREvent_Notification_Hidden = 601, + VREvent_Notification_BeginInteraction = 602, + VREvent_Notification_Destroyed = 603, - VREvent_Quit = 700, // data is process - VREvent_ProcessQuit = 701, // data is process - VREvent_QuitAborted_UserPrompt = 702, // data is process - VREvent_QuitAcknowledged = 703, // data is process - VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down + VREvent_Quit = 700, // data is process + VREvent_ProcessQuit = 701, // data is process + VREvent_QuitAborted_UserPrompt = 702, // data is process + VREvent_QuitAcknowledged = 703, // data is process + VREvent_DriverRequestedQuit = 704, // The driver has requested that SteamVR shut down - VREvent_ChaperoneDataHasChanged = 800, - VREvent_ChaperoneUniverseHasChanged = 801, - VREvent_ChaperoneTempDataHasChanged = 802, - VREvent_ChaperoneSettingsHaveChanged = 803, - VREvent_SeatedZeroPoseReset = 804, + VREvent_ChaperoneDataHasChanged = 800, + VREvent_ChaperoneUniverseHasChanged = 801, + VREvent_ChaperoneTempDataHasChanged = 802, + VREvent_ChaperoneSettingsHaveChanged = 803, + VREvent_SeatedZeroPoseReset = 804, - VREvent_AudioSettingsHaveChanged = 820, + VREvent_AudioSettingsHaveChanged = 820, - VREvent_BackgroundSettingHasChanged = 850, - VREvent_CameraSettingsHaveChanged = 851, - VREvent_ReprojectionSettingHasChanged = 852, - VREvent_ModelSkinSettingsHaveChanged = 853, - VREvent_EnvironmentSettingsHaveChanged = 854, - VREvent_PowerSettingsHaveChanged = 855, + VREvent_BackgroundSettingHasChanged = 850, + VREvent_CameraSettingsHaveChanged = 851, + VREvent_ReprojectionSettingHasChanged = 852, + VREvent_ModelSkinSettingsHaveChanged = 853, + VREvent_EnvironmentSettingsHaveChanged = 854, + VREvent_PowerSettingsHaveChanged = 855, VREvent_EnableHomeAppSettingsHaveChanged = 856, - VREvent_StatusUpdate = 900, + VREvent_StatusUpdate = 900, - VREvent_MCImageUpdated = 1000, + VREvent_MCImageUpdated = 1000, - VREvent_FirmwareUpdateStarted = 1100, - VREvent_FirmwareUpdateFinished = 1101, + VREvent_FirmwareUpdateStarted = 1100, + VREvent_FirmwareUpdateFinished = 1101, - VREvent_KeyboardClosed = 1200, - VREvent_KeyboardCharInput = 1201, - VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard + VREvent_KeyboardClosed = 1200, + VREvent_KeyboardCharInput = 1201, + VREvent_KeyboardDone = 1202, // Sent when DONE button clicked on keyboard - VREvent_ApplicationTransitionStarted = 1300, - VREvent_ApplicationTransitionAborted = 1301, - VREvent_ApplicationTransitionNewAppStarted = 1302, - VREvent_ApplicationListUpdated = 1303, - VREvent_ApplicationMimeTypeLoad = 1304, + VREvent_ApplicationTransitionStarted = 1300, + VREvent_ApplicationTransitionAborted = 1301, + VREvent_ApplicationTransitionNewAppStarted = 1302, + VREvent_ApplicationListUpdated = 1303, + VREvent_ApplicationMimeTypeLoad = 1304, VREvent_ApplicationTransitionNewAppLaunchComplete = 1305, - VREvent_ProcessConnected = 1306, - VREvent_ProcessDisconnected = 1307, + VREvent_ProcessConnected = 1306, + VREvent_ProcessDisconnected = 1307, - VREvent_Compositor_MirrorWindowShown = 1400, - VREvent_Compositor_MirrorWindowHidden = 1401, - VREvent_Compositor_ChaperoneBoundsShown = 1410, - VREvent_Compositor_ChaperoneBoundsHidden = 1411, + VREvent_Compositor_MirrorWindowShown = 1400, + VREvent_Compositor_MirrorWindowHidden = 1401, + VREvent_Compositor_ChaperoneBoundsShown = 1410, + VREvent_Compositor_ChaperoneBoundsHidden = 1411, - VREvent_TrackedCamera_StartVideoStream = 1500, - VREvent_TrackedCamera_StopVideoStream = 1501, - VREvent_TrackedCamera_PauseVideoStream = 1502, + VREvent_TrackedCamera_StartVideoStream = 1500, + VREvent_TrackedCamera_StopVideoStream = 1501, + VREvent_TrackedCamera_PauseVideoStream = 1502, VREvent_TrackedCamera_ResumeVideoStream = 1503, - VREvent_TrackedCamera_EditingSurface = 1550, + VREvent_TrackedCamera_EditingSurface = 1550, - VREvent_PerformanceTest_EnableCapture = 1600, - VREvent_PerformanceTest_DisableCapture = 1601, - VREvent_PerformanceTest_FidelityLevel = 1602, + VREvent_PerformanceTest_EnableCapture = 1600, + VREvent_PerformanceTest_DisableCapture = 1601, + VREvent_PerformanceTest_FidelityLevel = 1602, + + VREvent_MessageOverlay_Closed = 1650, + VREvent_MessageOverlayCloseRequested = 1651, - VREvent_MessageOverlay_Closed = 1650, - VREvent_MessageOverlayCloseRequested = 1651, - // Vendors are free to expose private events in this reserved region - VREvent_VendorSpecific_Reserved_Start = 10000, - VREvent_VendorSpecific_Reserved_End = 19999, + VREvent_VendorSpecific_Reserved_Start = 10000, + VREvent_VendorSpecific_Reserved_End = 19999, }; - /** Level of Hmd activity */ // UserInteraction_Timeout means the device is in the process of timing out. // InUse = ( k_EDeviceActivityLevel_UserInteraction || k_EDeviceActivityLevel_UserInteraction_Timeout ) // VREvent_TrackedDeviceUserInteractionStarted fires when the devices transitions from Standby -> UserInteraction or Idle -> UserInteraction. // VREvent_TrackedDeviceUserInteractionEnded fires when the devices transitions from UserInteraction_Timeout -> Idle enum EDeviceActivityLevel -{ - k_EDeviceActivityLevel_Unknown = -1, - k_EDeviceActivityLevel_Idle = 0, // No activity for the last 10 seconds - k_EDeviceActivityLevel_UserInteraction = 1, // Activity (movement or prox sensor) is happening now - k_EDeviceActivityLevel_UserInteraction_Timeout = 2, // No activity for the last 0.5 seconds - k_EDeviceActivityLevel_Standby = 3, // Idle for at least 5 seconds (configurable in Settings -> Power Management) +{ + k_EDeviceActivityLevel_Unknown = -1, + k_EDeviceActivityLevel_Idle = 0, // No activity for the last 10 seconds + k_EDeviceActivityLevel_UserInteraction = 1, // Activity (movement or prox sensor) is happening now + k_EDeviceActivityLevel_UserInteraction_Timeout = 2, // No activity for the last 0.5 seconds + k_EDeviceActivityLevel_Standby = 3, // Idle for at least 5 seconds (configurable in Settings -> Power Management) }; - /** VR controller button and axis IDs */ enum EVRButtonId { - k_EButton_System = 0, - k_EButton_ApplicationMenu = 1, - k_EButton_Grip = 2, - k_EButton_DPad_Left = 3, - k_EButton_DPad_Up = 4, - k_EButton_DPad_Right = 5, - k_EButton_DPad_Down = 6, - k_EButton_A = 7, - - k_EButton_ProximitySensor = 31, + k_EButton_System = 0, + k_EButton_ApplicationMenu = 1, + k_EButton_Grip = 2, + k_EButton_DPad_Left = 3, + k_EButton_DPad_Up = 4, + k_EButton_DPad_Right = 5, + k_EButton_DPad_Down = 6, + k_EButton_A = 7, - k_EButton_Axis0 = 32, - k_EButton_Axis1 = 33, - k_EButton_Axis2 = 34, - k_EButton_Axis3 = 35, - k_EButton_Axis4 = 36, + k_EButton_ProximitySensor = 31, + + k_EButton_Axis0 = 32, + k_EButton_Axis1 = 33, + k_EButton_Axis2 = 34, + k_EButton_Axis3 = 35, + k_EButton_Axis4 = 36, // aliases for well known controllers - k_EButton_SteamVR_Touchpad = k_EButton_Axis0, - k_EButton_SteamVR_Trigger = k_EButton_Axis1, + k_EButton_SteamVR_Touchpad = k_EButton_Axis0, + k_EButton_SteamVR_Trigger = k_EButton_Axis1, - k_EButton_Dashboard_Back = k_EButton_Grip, + k_EButton_Dashboard_Back = k_EButton_Grip, - k_EButton_Max = 64 + k_EButton_Max = 64 }; -inline uint64_t ButtonMaskFromId( EVRButtonId id ) { return 1ull << id; } +inline uint64_t ButtonMaskFromId(EVRButtonId id) { return 1ull << id; } /** used for controller button events */ struct VREvent_Controller_t { - uint32_t button; // EVRButtonId enum + uint32_t button; // EVRButtonId enum }; - /** used for simulated mouse events in overlay space */ enum EVRMouseButton { - VRMouseButton_Left = 0x0001, - VRMouseButton_Right = 0x0002, - VRMouseButton_Middle = 0x0004, + VRMouseButton_Left = 0x0001, + VRMouseButton_Right = 0x0002, + VRMouseButton_Middle = 0x0004, }; - /** used for simulated mouse events in overlay space */ struct VREvent_Mouse_t { - float x, y; // co-ords are in GL space, bottom left of the texture is 0,0 - uint32_t button; // EVRMouseButton enum + float x, y; // co-ords are in GL space, bottom left of the texture is 0,0 + uint32_t button; // EVRMouseButton enum }; /** used for simulated mouse wheel scroll in overlay space */ struct VREvent_Scroll_t { - float xdelta, ydelta; // movement in fraction of the pad traversed since last delta, 1.0 for a full swipe + float xdelta, ydelta; // movement in fraction of the pad traversed since last delta, 1.0 for a full swipe uint32_t repeatCount; }; @@ -713,25 +704,23 @@ struct VREvent_Process_t bool bForced; }; - /** Used for a few events about overlays */ struct VREvent_Overlay_t { uint64_t overlayHandle; }; - /** Used for a few events about overlays */ struct VREvent_Status_t { - uint32_t statusState; // EVRState enum + uint32_t statusState; // EVRState enum }; /** Used for keyboard events **/ struct VREvent_Keyboard_t { - char cNewInput[8]; // Up to 11 bytes of new input - uint64_t uUserValue; // Possible flags about the new input + char cNewInput[8]; // Up to 11 bytes of new input + uint64_t uUserValue; // Possible flags about the new input }; struct VREvent_Ipd_t @@ -787,7 +776,7 @@ struct VREvent_EditingCameraSurface_t struct VREvent_MessageOverlay_t { - uint32_t unVRMessageOverlayResponse; // vr::VRMessageOverlayResponse enum + uint32_t unVRMessageOverlayResponse; // vr::VRMessageOverlayResponse enum }; struct VREvent_Property_t @@ -797,8 +786,7 @@ struct VREvent_Property_t }; /** NOTE!!! If you change this you MUST manually update openvr_interop.cs.py */ -typedef union -{ +typedef union { VREvent_Reserved_t reserved; VREvent_Controller_t controller; VREvent_Mouse_t mouse; @@ -821,25 +809,24 @@ typedef union VREvent_Property_t property; } VREvent_Data_t; - -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif /** An event posted by the server to all running applications */ struct VREvent_t { - uint32_t eventType; // EVREventType enum + uint32_t eventType; // EVREventType enum TrackedDeviceIndex_t trackedDeviceIndex; float eventAgeSeconds; // event data must be the end of the struct as its size is variable VREvent_Data_t data; }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif /** The mesh to draw into the stencil (or depth) buffer to perform @@ -854,7 +841,6 @@ struct HiddenAreaMesh_t uint32_t unTriangleCount; }; - enum EHiddenAreaMeshType { k_eHiddenAreaMesh_Standard = 0, @@ -864,7 +850,6 @@ enum EHiddenAreaMeshType k_eHiddenAreaMesh_Max = 3, }; - /** Identifies what kind of axis is on the controller at index n. Read this type * with pVRSystem->Get( nControllerDeviceIndex, Prop_Axis0Type_Int32 + n ); */ @@ -873,32 +858,29 @@ enum EVRControllerAxisType k_eControllerAxis_None = 0, k_eControllerAxis_TrackPad = 1, k_eControllerAxis_Joystick = 2, - k_eControllerAxis_Trigger = 3, // Analog trigger data is in the X axis + k_eControllerAxis_Trigger = 3, // Analog trigger data is in the X axis }; - /** contains information about one axis on the controller */ struct VRControllerAxis_t { - float x; // Ranges from -1.0 to 1.0 for joysticks and track pads. Ranges from 0.0 to 1.0 for triggers were 0 is fully released. - float y; // Ranges from -1.0 to 1.0 for joysticks and track pads. Is always 0.0 for triggers. + float x; // Ranges from -1.0 to 1.0 for joysticks and track pads. Ranges from 0.0 to 1.0 for triggers were 0 is fully released. + float y; // Ranges from -1.0 to 1.0 for joysticks and track pads. Is always 0.0 for triggers. }; - /** the number of axes in the controller state */ static const uint32_t k_unControllerStateAxisCount = 5; - -#if defined(__linux__) || defined(__APPLE__) -// This structure was originally defined mis-packed on Linux, preserved for -// compatibility. -#pragma pack( push, 4 ) +#if defined(__linux__) || defined(__APPLE__) +// This structure was originally defined mis-packed on Linux, preserved for +// compatibility. +#pragma pack(push, 4) #endif /** Holds all the state of a controller at one moment in time. */ struct VRControllerState001_t { - // If packet num matches that on your prior call, then the controller state hasn't been changed since + // If packet num matches that on your prior call, then the controller state hasn't been changed since // your last call and there is no need to process it uint32_t unPacketNum; @@ -907,16 +889,14 @@ struct VRControllerState001_t uint64_t ulButtonTouched; // Axis data for the controller's analog inputs - VRControllerAxis_t rAxis[ k_unControllerStateAxisCount ]; + VRControllerAxis_t rAxis[k_unControllerStateAxisCount]; }; -#if defined(__linux__) || defined(__APPLE__) -#pragma pack( pop ) +#if defined(__linux__) || defined(__APPLE__) +#pragma pack(pop) #endif - typedef VRControllerState001_t VRControllerState_t; - /** determines how to provide output to the application of various event processing functions. */ enum EVRControllerEventOutputType { @@ -924,8 +904,6 @@ enum EVRControllerEventOutputType ControllerEventOutput_VREvents = 1, }; - - /** Collision Bounds Style */ enum ECollisionBoundsStyle { @@ -941,7 +919,7 @@ enum ECollisionBoundsStyle /** Allows the application to customize how the overlay appears in the compositor */ struct Compositor_OverlaySettings { - uint32_t size; // sizeof(Compositor_OverlaySettings) + uint32_t size; // sizeof(Compositor_OverlaySettings) bool curved, antialias; float scale, distance, alpha; float uOffset, vOffset, uScale, vScale; @@ -957,49 +935,48 @@ static const VROverlayHandle_t k_ulOverlayHandleInvalid = 0; /** Errors that can occur around VR overlays */ enum EVROverlayError { - VROverlayError_None = 0, + VROverlayError_None = 0, - VROverlayError_UnknownOverlay = 10, - VROverlayError_InvalidHandle = 11, - VROverlayError_PermissionDenied = 12, - VROverlayError_OverlayLimitExceeded = 13, // No more overlays could be created because the maximum number already exist - VROverlayError_WrongVisibilityType = 14, - VROverlayError_KeyTooLong = 15, - VROverlayError_NameTooLong = 16, - VROverlayError_KeyInUse = 17, - VROverlayError_WrongTransformType = 18, - VROverlayError_InvalidTrackedDevice = 19, - VROverlayError_InvalidParameter = 20, - VROverlayError_ThumbnailCantBeDestroyed = 21, - VROverlayError_ArrayTooSmall = 22, - VROverlayError_RequestFailed = 23, - VROverlayError_InvalidTexture = 24, - VROverlayError_UnableToLoadFile = 25, - VROverlayError_KeyboardAlreadyInUse = 26, - VROverlayError_NoNeighbor = 27, - VROverlayError_TooManyMaskPrimitives = 29, - VROverlayError_BadMaskPrimitive = 30, + VROverlayError_UnknownOverlay = 10, + VROverlayError_InvalidHandle = 11, + VROverlayError_PermissionDenied = 12, + VROverlayError_OverlayLimitExceeded = 13, // No more overlays could be created because the maximum number already exist + VROverlayError_WrongVisibilityType = 14, + VROverlayError_KeyTooLong = 15, + VROverlayError_NameTooLong = 16, + VROverlayError_KeyInUse = 17, + VROverlayError_WrongTransformType = 18, + VROverlayError_InvalidTrackedDevice = 19, + VROverlayError_InvalidParameter = 20, + VROverlayError_ThumbnailCantBeDestroyed = 21, + VROverlayError_ArrayTooSmall = 22, + VROverlayError_RequestFailed = 23, + VROverlayError_InvalidTexture = 24, + VROverlayError_UnableToLoadFile = 25, + VROverlayError_KeyboardAlreadyInUse = 26, + VROverlayError_NoNeighbor = 27, + VROverlayError_TooManyMaskPrimitives = 29, + VROverlayError_BadMaskPrimitive = 30, }; /** enum values to pass in to VR_Init to identify whether the application will * draw a 3D scene. */ enum EVRApplicationType { - VRApplication_Other = 0, // Some other kind of application that isn't covered by the other entries - VRApplication_Scene = 1, // Application will submit 3D frames - VRApplication_Overlay = 2, // Application only interacts with overlays - VRApplication_Background = 3, // Application should not start SteamVR if it's not already running, and should not - // keep it running if everything else quits. - VRApplication_Utility = 4, // Init should not try to load any drivers. The application needs access to utility - // interfaces (like IVRSettings and IVRApplications) but not hardware. - VRApplication_VRMonitor = 5, // Reserved for vrmonitor - VRApplication_SteamWatchdog = 6,// Reserved for Steam - VRApplication_Bootstrapper = 7, // Start up SteamVR + VRApplication_Other = 0, // Some other kind of application that isn't covered by the other entries + VRApplication_Scene = 1, // Application will submit 3D frames + VRApplication_Overlay = 2, // Application only interacts with overlays + VRApplication_Background = 3, // Application should not start SteamVR if it's not already running, and should not + // keep it running if everything else quits. + VRApplication_Utility = 4, // Init should not try to load any drivers. The application needs access to utility + // interfaces (like IVRSettings and IVRApplications) but not hardware. + VRApplication_VRMonitor = 5, // Reserved for vrmonitor + VRApplication_SteamWatchdog = 6, // Reserved for Steam + VRApplication_Bootstrapper = 7, // Start up SteamVR VRApplication_Max }; - /** error codes for firmware */ enum EVRFirmwareError { @@ -1008,7 +985,6 @@ enum EVRFirmwareError VRFirmwareError_Fail = 2, }; - /** error codes for notifications */ enum EVRNotificationError { @@ -1019,103 +995,101 @@ enum EVRNotificationError VRNotificationError_SystemWithUserValueAlreadyExists = 103, }; - /** error codes returned by Vr_Init */ // Please add adequate error description to https://developer.valvesoftware.com/w/index.php?title=Category:SteamVRHelp enum EVRInitError { - VRInitError_None = 0, + VRInitError_None = 0, VRInitError_Unknown = 1, - VRInitError_Init_InstallationNotFound = 100, - VRInitError_Init_InstallationCorrupt = 101, - VRInitError_Init_VRClientDLLNotFound = 102, - VRInitError_Init_FileNotFound = 103, - VRInitError_Init_FactoryNotFound = 104, - VRInitError_Init_InterfaceNotFound = 105, - VRInitError_Init_InvalidInterface = 106, - VRInitError_Init_UserConfigDirectoryInvalid = 107, - VRInitError_Init_HmdNotFound = 108, - VRInitError_Init_NotInitialized = 109, - VRInitError_Init_PathRegistryNotFound = 110, - VRInitError_Init_NoConfigPath = 111, - VRInitError_Init_NoLogPath = 112, - VRInitError_Init_PathRegistryNotWritable = 113, - VRInitError_Init_AppInfoInitFailed = 114, - VRInitError_Init_Retry = 115, // Used internally to cause retries to vrserver - VRInitError_Init_InitCanceledByUser = 116, // The calling application should silently exit. The user canceled app startup - VRInitError_Init_AnotherAppLaunching = 117, - VRInitError_Init_SettingsInitFailed = 118, - VRInitError_Init_ShuttingDown = 119, - VRInitError_Init_TooManyObjects = 120, - VRInitError_Init_NoServerForBackgroundApp = 121, - VRInitError_Init_NotSupportedWithCompositor = 122, - VRInitError_Init_NotAvailableToUtilityApps = 123, - VRInitError_Init_Internal = 124, - VRInitError_Init_HmdDriverIdIsNone = 125, - VRInitError_Init_HmdNotFoundPresenceFailed = 126, - VRInitError_Init_VRMonitorNotFound = 127, - VRInitError_Init_VRMonitorStartupFailed = 128, - VRInitError_Init_LowPowerWatchdogNotSupported = 129, - VRInitError_Init_InvalidApplicationType = 130, - VRInitError_Init_NotAvailableToWatchdogApps = 131, - VRInitError_Init_WatchdogDisabledInSettings = 132, - VRInitError_Init_VRDashboardNotFound = 133, - VRInitError_Init_VRDashboardStartupFailed = 134, - VRInitError_Init_VRHomeNotFound = 135, - VRInitError_Init_VRHomeStartupFailed = 136, - VRInitError_Init_RebootingBusy = 137, - VRInitError_Init_FirmwareUpdateBusy = 138, - VRInitError_Init_FirmwareRecoveryBusy = 139, + VRInitError_Init_InstallationNotFound = 100, + VRInitError_Init_InstallationCorrupt = 101, + VRInitError_Init_VRClientDLLNotFound = 102, + VRInitError_Init_FileNotFound = 103, + VRInitError_Init_FactoryNotFound = 104, + VRInitError_Init_InterfaceNotFound = 105, + VRInitError_Init_InvalidInterface = 106, + VRInitError_Init_UserConfigDirectoryInvalid = 107, + VRInitError_Init_HmdNotFound = 108, + VRInitError_Init_NotInitialized = 109, + VRInitError_Init_PathRegistryNotFound = 110, + VRInitError_Init_NoConfigPath = 111, + VRInitError_Init_NoLogPath = 112, + VRInitError_Init_PathRegistryNotWritable = 113, + VRInitError_Init_AppInfoInitFailed = 114, + VRInitError_Init_Retry = 115, // Used internally to cause retries to vrserver + VRInitError_Init_InitCanceledByUser = 116, // The calling application should silently exit. The user canceled app startup + VRInitError_Init_AnotherAppLaunching = 117, + VRInitError_Init_SettingsInitFailed = 118, + VRInitError_Init_ShuttingDown = 119, + VRInitError_Init_TooManyObjects = 120, + VRInitError_Init_NoServerForBackgroundApp = 121, + VRInitError_Init_NotSupportedWithCompositor = 122, + VRInitError_Init_NotAvailableToUtilityApps = 123, + VRInitError_Init_Internal = 124, + VRInitError_Init_HmdDriverIdIsNone = 125, + VRInitError_Init_HmdNotFoundPresenceFailed = 126, + VRInitError_Init_VRMonitorNotFound = 127, + VRInitError_Init_VRMonitorStartupFailed = 128, + VRInitError_Init_LowPowerWatchdogNotSupported = 129, + VRInitError_Init_InvalidApplicationType = 130, + VRInitError_Init_NotAvailableToWatchdogApps = 131, + VRInitError_Init_WatchdogDisabledInSettings = 132, + VRInitError_Init_VRDashboardNotFound = 133, + VRInitError_Init_VRDashboardStartupFailed = 134, + VRInitError_Init_VRHomeNotFound = 135, + VRInitError_Init_VRHomeStartupFailed = 136, + VRInitError_Init_RebootingBusy = 137, + VRInitError_Init_FirmwareUpdateBusy = 138, + VRInitError_Init_FirmwareRecoveryBusy = 139, - - VRInitError_Driver_Failed = 200, - VRInitError_Driver_Unknown = 201, - VRInitError_Driver_HmdUnknown = 202, - VRInitError_Driver_NotLoaded = 203, - VRInitError_Driver_RuntimeOutOfDate = 204, - VRInitError_Driver_HmdInUse = 205, - VRInitError_Driver_NotCalibrated = 206, - VRInitError_Driver_CalibrationInvalid = 207, - VRInitError_Driver_HmdDisplayNotFound = 208, + VRInitError_Driver_Failed = 200, + VRInitError_Driver_Unknown = 201, + VRInitError_Driver_HmdUnknown = 202, + VRInitError_Driver_NotLoaded = 203, + VRInitError_Driver_RuntimeOutOfDate = 204, + VRInitError_Driver_HmdInUse = 205, + VRInitError_Driver_NotCalibrated = 206, + VRInitError_Driver_CalibrationInvalid = 207, + VRInitError_Driver_HmdDisplayNotFound = 208, VRInitError_Driver_TrackedDeviceInterfaceUnknown = 209, // VRInitError_Driver_HmdDisplayNotFoundAfterFix = 210, // not needed: here for historic reasons - VRInitError_Driver_HmdDriverIdOutOfBounds = 211, - VRInitError_Driver_HmdDisplayMirrored = 212, + VRInitError_Driver_HmdDriverIdOutOfBounds = 211, + VRInitError_Driver_HmdDisplayMirrored = 212, - VRInitError_IPC_ServerInitFailed = 300, - VRInitError_IPC_ConnectFailed = 301, - VRInitError_IPC_SharedStateInitFailed = 302, - VRInitError_IPC_CompositorInitFailed = 303, - VRInitError_IPC_MutexInitFailed = 304, - VRInitError_IPC_Failed = 305, - VRInitError_IPC_CompositorConnectFailed = 306, + VRInitError_IPC_ServerInitFailed = 300, + VRInitError_IPC_ConnectFailed = 301, + VRInitError_IPC_SharedStateInitFailed = 302, + VRInitError_IPC_CompositorInitFailed = 303, + VRInitError_IPC_MutexInitFailed = 304, + VRInitError_IPC_Failed = 305, + VRInitError_IPC_CompositorConnectFailed = 306, VRInitError_IPC_CompositorInvalidConnectResponse = 307, VRInitError_IPC_ConnectFailedAfterMultipleAttempts = 308, - VRInitError_Compositor_Failed = 400, - VRInitError_Compositor_D3D11HardwareRequired = 401, - VRInitError_Compositor_FirmwareRequiresUpdate = 402, - VRInitError_Compositor_OverlayInitFailed = 403, - VRInitError_Compositor_ScreenshotsInitFailed = 404, - VRInitError_Compositor_UnableToCreateDevice = 405, + VRInitError_Compositor_Failed = 400, + VRInitError_Compositor_D3D11HardwareRequired = 401, + VRInitError_Compositor_FirmwareRequiresUpdate = 402, + VRInitError_Compositor_OverlayInitFailed = 403, + VRInitError_Compositor_ScreenshotsInitFailed = 404, + VRInitError_Compositor_UnableToCreateDevice = 405, - VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000, + VRInitError_VendorSpecific_UnableToConnectToOculusRuntime = 1000, - VRInitError_VendorSpecific_HmdFound_CantOpenDevice = 1101, - VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102, - VRInitError_VendorSpecific_HmdFound_NoStoredConfig = 1103, - VRInitError_VendorSpecific_HmdFound_ConfigTooBig = 1104, - VRInitError_VendorSpecific_HmdFound_ConfigTooSmall = 1105, - VRInitError_VendorSpecific_HmdFound_UnableToInitZLib = 1106, - VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion = 1107, - VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart = 1108, - VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart = 1109, - VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext = 1110, - VRInitError_VendorSpecific_HmdFound_UserDataAddressRange = 1111, - VRInitError_VendorSpecific_HmdFound_UserDataError = 1112, - VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck = 1113, + VRInitError_VendorSpecific_HmdFound_CantOpenDevice = 1101, + VRInitError_VendorSpecific_HmdFound_UnableToRequestConfigStart = 1102, + VRInitError_VendorSpecific_HmdFound_NoStoredConfig = 1103, + VRInitError_VendorSpecific_HmdFound_ConfigTooBig = 1104, + VRInitError_VendorSpecific_HmdFound_ConfigTooSmall = 1105, + VRInitError_VendorSpecific_HmdFound_UnableToInitZLib = 1106, + VRInitError_VendorSpecific_HmdFound_CantReadFirmwareVersion = 1107, + VRInitError_VendorSpecific_HmdFound_UnableToSendUserDataStart = 1108, + VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataStart = 1109, + VRInitError_VendorSpecific_HmdFound_UnableToGetUserDataNext = 1110, + VRInitError_VendorSpecific_HmdFound_UserDataAddressRange = 1111, + VRInitError_VendorSpecific_HmdFound_UserDataError = 1112, + VRInitError_VendorSpecific_HmdFound_ConfigFailedSanityCheck = 1113, VRInitError_Steam_SteamInstallationNotFound = 2000, }; @@ -1123,7 +1097,7 @@ enum EVRInitError enum EVRScreenshotType { VRScreenshotType_None = 0, - VRScreenshotType_Mono = 1, // left eye only + VRScreenshotType_Mono = 1, // left eye only VRScreenshotType_Stereo = 2, VRScreenshotType_Cubemap = 3, VRScreenshotType_MonoPanorama = 4, @@ -1138,35 +1112,35 @@ enum EVRScreenshotPropertyFilenames enum EVRTrackedCameraError { - VRTrackedCameraError_None = 0, - VRTrackedCameraError_OperationFailed = 100, - VRTrackedCameraError_InvalidHandle = 101, - VRTrackedCameraError_InvalidFrameHeaderVersion = 102, - VRTrackedCameraError_OutOfHandles = 103, - VRTrackedCameraError_IPCFailure = 104, - VRTrackedCameraError_NotSupportedForThisDevice = 105, - VRTrackedCameraError_SharedMemoryFailure = 106, - VRTrackedCameraError_FrameBufferingFailure = 107, - VRTrackedCameraError_StreamSetupFailure = 108, - VRTrackedCameraError_InvalidGLTextureId = 109, + VRTrackedCameraError_None = 0, + VRTrackedCameraError_OperationFailed = 100, + VRTrackedCameraError_InvalidHandle = 101, + VRTrackedCameraError_InvalidFrameHeaderVersion = 102, + VRTrackedCameraError_OutOfHandles = 103, + VRTrackedCameraError_IPCFailure = 104, + VRTrackedCameraError_NotSupportedForThisDevice = 105, + VRTrackedCameraError_SharedMemoryFailure = 106, + VRTrackedCameraError_FrameBufferingFailure = 107, + VRTrackedCameraError_StreamSetupFailure = 108, + VRTrackedCameraError_InvalidGLTextureId = 109, VRTrackedCameraError_InvalidSharedTextureHandle = 110, - VRTrackedCameraError_FailedToGetGLTextureId = 111, - VRTrackedCameraError_SharedTextureFailure = 112, - VRTrackedCameraError_NoFrameAvailable = 113, - VRTrackedCameraError_InvalidArgument = 114, - VRTrackedCameraError_InvalidFrameBufferSize = 115, + VRTrackedCameraError_FailedToGetGLTextureId = 111, + VRTrackedCameraError_SharedTextureFailure = 112, + VRTrackedCameraError_NoFrameAvailable = 113, + VRTrackedCameraError_InvalidArgument = 114, + VRTrackedCameraError_InvalidFrameBufferSize = 115, }; enum EVRTrackedCameraFrameType { - VRTrackedCameraFrameType_Distorted = 0, // This is the camera video frame size in pixels, still distorted. - VRTrackedCameraFrameType_Undistorted, // In pixels, an undistorted inscribed rectangle region without invalid regions. This size is subject to changes shortly. - VRTrackedCameraFrameType_MaximumUndistorted, // In pixels, maximum undistorted with invalid regions. Non zero alpha component identifies valid regions. + VRTrackedCameraFrameType_Distorted = 0, // This is the camera video frame size in pixels, still distorted. + VRTrackedCameraFrameType_Undistorted, // In pixels, an undistorted inscribed rectangle region without invalid regions. This size is subject to changes shortly. + VRTrackedCameraFrameType_MaximumUndistorted, // In pixels, maximum undistorted with invalid regions. Non zero alpha component identifies valid regions. MAX_CAMERA_FRAME_TYPES }; typedef uint64_t TrackedCameraHandle_t; -#define INVALID_TRACKED_CAMERA_HANDLE ((vr::TrackedCameraHandle_t)0) +#define INVALID_TRACKED_CAMERA_HANDLE ((vr::TrackedCameraHandle_t)0) struct CameraVideoStreamFrameHeader_t { @@ -1186,15 +1160,15 @@ typedef uint32_t ScreenshotHandle_t; static const uint32_t k_unScreenshotHandleInvalid = 0; -#pragma pack( pop ) +#pragma pack(pop) // figure out how to import from the VR API dll #if defined(_WIN32) #ifdef VR_API_EXPORT -#define VR_INTERFACE extern "C" __declspec( dllexport ) +#define VR_INTERFACE extern "C" __declspec(dllexport) #else -#define VR_INTERFACE extern "C" __declspec( dllimport ) +#define VR_INTERFACE extern "C" __declspec(dllimport) #endif #elif defined(__GNUC__) || defined(COMPILER_GCC) || defined(__APPLE__) @@ -1202,59 +1176,56 @@ static const uint32_t k_unScreenshotHandleInvalid = 0; #ifdef VR_API_EXPORT #define VR_INTERFACE extern "C" __attribute__((visibility("default"))) #else -#define VR_INTERFACE extern "C" +#define VR_INTERFACE extern "C" #endif #else #error "Unsupported Platform." #endif - -#if defined( _WIN32 ) +#if defined(_WIN32) #define VR_CALLTYPE __cdecl #else -#define VR_CALLTYPE +#define VR_CALLTYPE #endif -} // namespace vr - -#endif // _INCLUDE_VRTYPES_H +} // namespace vr +#endif // _INCLUDE_VRTYPES_H // vrannotation.h #ifdef API_GEN -# define VR_CLANG_ATTR(ATTR) __attribute__((annotate( ATTR ))) +#define VR_CLANG_ATTR(ATTR) __attribute__((annotate(ATTR))) #else -# define VR_CLANG_ATTR(ATTR) +#define VR_CLANG_ATTR(ATTR) #endif -#define VR_METHOD_DESC(DESC) VR_CLANG_ATTR( "desc:" #DESC ";" ) -#define VR_IGNOREATTR() VR_CLANG_ATTR( "ignore" ) -#define VR_OUT_STRUCT() VR_CLANG_ATTR( "out_struct: ;" ) -#define VR_OUT_STRING() VR_CLANG_ATTR( "out_string: ;" ) -#define VR_OUT_ARRAY_CALL(COUNTER,FUNCTION,PARAMS) VR_CLANG_ATTR( "out_array_call:" #COUNTER "," #FUNCTION "," #PARAMS ";" ) -#define VR_OUT_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR( "out_array_count:" #COUNTER ";" ) -#define VR_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR( "array_count:" #COUNTER ";" ) -#define VR_ARRAY_COUNT_D(COUNTER, DESC) VR_CLANG_ATTR( "array_count:" #COUNTER ";desc:" #DESC ) -#define VR_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR( "buffer_count:" #COUNTER ";" ) -#define VR_OUT_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR( "out_buffer_count:" #COUNTER ";" ) -#define VR_OUT_STRING_COUNT(COUNTER) VR_CLANG_ATTR( "out_string_count:" #COUNTER ";" ) +#define VR_METHOD_DESC(DESC) VR_CLANG_ATTR("desc:" #DESC ";") +#define VR_IGNOREATTR() VR_CLANG_ATTR("ignore") +#define VR_OUT_STRUCT() VR_CLANG_ATTR("out_struct: ;") +#define VR_OUT_STRING() VR_CLANG_ATTR("out_string: ;") +#define VR_OUT_ARRAY_CALL(COUNTER, FUNCTION, PARAMS) VR_CLANG_ATTR("out_array_call:" #COUNTER "," #FUNCTION "," #PARAMS ";") +#define VR_OUT_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR("out_array_count:" #COUNTER ";") +#define VR_ARRAY_COUNT(COUNTER) VR_CLANG_ATTR("array_count:" #COUNTER ";") +#define VR_ARRAY_COUNT_D(COUNTER, DESC) VR_CLANG_ATTR("array_count:" #COUNTER ";desc:" #DESC) +#define VR_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR("buffer_count:" #COUNTER ";") +#define VR_OUT_BUFFER_COUNT(COUNTER) VR_CLANG_ATTR("out_buffer_count:" #COUNTER ";") +#define VR_OUT_STRING_COUNT(COUNTER) VR_CLANG_ATTR("out_string_count:" #COUNTER ";") // vrtrackedcameratypes.h #ifndef _VRTRACKEDCAMERATYPES_H -#define _VRTRACKEDCAMERATYPES_H +#define _VRTRACKEDCAMERATYPES_H namespace vr { - -#pragma pack( push, 8 ) +#pragma pack(push, 8) enum ECameraVideoStreamFormat { CVS_FORMAT_UNKNOWN = 0, - CVS_FORMAT_RAW10 = 1, // 10 bits per pixel - CVS_FORMAT_NV12 = 2, // 12 bits per pixel - CVS_FORMAT_RGB24 = 3, // 24 bits per pixel + CVS_FORMAT_RAW10 = 1, // 10 bits per pixel + CVS_FORMAT_NV12 = 2, // 12 bits per pixel + CVS_FORMAT_RGB24 = 3, // 24 bits per pixel CVS_MAX_FORMATS }; @@ -1277,30 +1248,31 @@ enum ECameraCompatibilityMode }; #ifdef _MSC_VER -#define VR_CAMERA_DECL_ALIGN( x ) __declspec( align( x ) ) +#define VR_CAMERA_DECL_ALIGN(x) __declspec(align(x)) #else -#define VR_CAMERA_DECL_ALIGN( x ) // +#define VR_CAMERA_DECL_ALIGN(x) // #endif -#define MAX_CAMERA_FRAME_SHARED_HANDLES 4 +#define MAX_CAMERA_FRAME_SHARED_HANDLES 4 -VR_CAMERA_DECL_ALIGN( 8 ) struct CameraVideoStreamFrame_t +VR_CAMERA_DECL_ALIGN(8) +struct CameraVideoStreamFrame_t { ECameraVideoStreamFormat m_nStreamFormat; uint32_t m_nWidth; uint32_t m_nHeight; - uint32_t m_nImageDataSize; // Based on stream format, width, height + uint32_t m_nImageDataSize; // Based on stream format, width, height - uint32_t m_nFrameSequence; // Starts from 0 when stream starts. + uint32_t m_nFrameSequence; // Starts from 0 when stream starts. - uint32_t m_nBufferIndex; // Identifies which buffer the image data is hosted - uint32_t m_nBufferCount; // Total number of configured buffers + uint32_t m_nBufferIndex; // Identifies which buffer the image data is hosted + uint32_t m_nBufferCount; // Total number of configured buffers uint32_t m_nExposureTime; - uint32_t m_nISPFrameTimeStamp; // Driver provided time stamp per driver centric time base + uint32_t m_nISPFrameTimeStamp; // Driver provided time stamp per driver centric time base uint32_t m_nISPReferenceTimeStamp; uint32_t m_nSyncCounter; @@ -1309,241 +1281,239 @@ VR_CAMERA_DECL_ALIGN( 8 ) struct CameraVideoStreamFrame_t double m_flReferenceCamSyncTime; - double m_flFrameElapsedTime; // Starts from 0 when stream starts. In seconds. + double m_flFrameElapsedTime; // Starts from 0 when stream starts. In seconds. double m_flFrameDeliveryRate; - double m_flFrameCaptureTime_DriverAbsolute; // In USB time, via AuxEvent - double m_flFrameCaptureTime_ServerRelative; // In System time within the server - uint64_t m_nFrameCaptureTicks_ServerAbsolute; // In system ticks within the server - double m_flFrameCaptureTime_ClientRelative; // At the client, relative to when the frame was exposed/captured. + double m_flFrameCaptureTime_DriverAbsolute; // In USB time, via AuxEvent + double m_flFrameCaptureTime_ServerRelative; // In System time within the server + uint64_t m_nFrameCaptureTicks_ServerAbsolute; // In system ticks within the server + double m_flFrameCaptureTime_ClientRelative; // At the client, relative to when the frame was exposed/captured. double m_flSyncMarkerError; - TrackedDevicePose_t m_StandingTrackedDevicePose; // Supplied by HMD layer when used as a tracked camera + TrackedDevicePose_t m_StandingTrackedDevicePose; // Supplied by HMD layer when used as a tracked camera uint64_t m_pImageData; }; -#pragma pack( pop ) +#pragma pack(pop) -} +} // namespace vr -#endif // _VRTRACKEDCAMERATYPES_H +#endif // _VRTRACKEDCAMERATYPES_H // ivrsettings.h namespace vr { - enum EVRSettingsError - { - VRSettingsError_None = 0, - VRSettingsError_IPCFailed = 1, - VRSettingsError_WriteFailed = 2, - VRSettingsError_ReadFailed = 3, - VRSettingsError_JsonParseFailed = 4, - VRSettingsError_UnsetSettingHasNoDefault = 5, // This will be returned if the setting does not appear in the appropriate default file and has not been set - }; +enum EVRSettingsError +{ + VRSettingsError_None = 0, + VRSettingsError_IPCFailed = 1, + VRSettingsError_WriteFailed = 2, + VRSettingsError_ReadFailed = 3, + VRSettingsError_JsonParseFailed = 4, + VRSettingsError_UnsetSettingHasNoDefault = 5, // This will be returned if the setting does not appear in the appropriate default file and has not been set +}; - // The maximum length of a settings key - static const uint32_t k_unMaxSettingsKeyLength = 128; +// The maximum length of a settings key +static const uint32_t k_unMaxSettingsKeyLength = 128; - class IVRSettings - { - public: - virtual const char *GetSettingsErrorNameFromEnum( EVRSettingsError eError ) = 0; +class IVRSettings +{ +public: + virtual const char *GetSettingsErrorNameFromEnum(EVRSettingsError eError) = 0; - // Returns true if file sync occurred (force or settings dirty) - virtual bool Sync( bool bForce = false, EVRSettingsError *peError = nullptr ) = 0; + // Returns true if file sync occurred (force or settings dirty) + virtual bool Sync(bool bForce = false, EVRSettingsError *peError = nullptr) = 0; - virtual void SetBool( const char *pchSection, const char *pchSettingsKey, bool bValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetInt32( const char *pchSection, const char *pchSettingsKey, int32_t nValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetFloat( const char *pchSection, const char *pchSettingsKey, float flValue, EVRSettingsError *peError = nullptr ) = 0; - virtual void SetString( const char *pchSection, const char *pchSettingsKey, const char *pchValue, EVRSettingsError *peError = nullptr ) = 0; + virtual void SetBool(const char *pchSection, const char *pchSettingsKey, bool bValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetInt32(const char *pchSection, const char *pchSettingsKey, int32_t nValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetFloat(const char *pchSection, const char *pchSettingsKey, float flValue, EVRSettingsError *peError = nullptr) = 0; + virtual void SetString(const char *pchSection, const char *pchSettingsKey, const char *pchValue, EVRSettingsError *peError = nullptr) = 0; - // Users of the system need to provide a proper default in default.vrsettings in the resources/settings/ directory - // of either the runtime or the driver_xxx directory. Otherwise the default will be false, 0, 0.0 or "" - virtual bool GetBool( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual int32_t GetInt32( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual float GetFloat( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - virtual void GetString( const char *pchSection, const char *pchSettingsKey, VR_OUT_STRING() char *pchValue, uint32_t unValueLen, EVRSettingsError *peError = nullptr ) = 0; + // Users of the system need to provide a proper default in default.vrsettings in the resources/settings/ directory + // of either the runtime or the driver_xxx directory. Otherwise the default will be false, 0, 0.0 or "" + virtual bool GetBool(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual int32_t GetInt32(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual float GetFloat(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; + virtual void GetString(const char *pchSection, const char *pchSettingsKey, VR_OUT_STRING() char *pchValue, uint32_t unValueLen, EVRSettingsError *peError = nullptr) = 0; - virtual void RemoveSection( const char *pchSection, EVRSettingsError *peError = nullptr ) = 0; - virtual void RemoveKeyInSection( const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr ) = 0; - }; + virtual void RemoveSection(const char *pchSection, EVRSettingsError *peError = nullptr) = 0; + virtual void RemoveKeyInSection(const char *pchSection, const char *pchSettingsKey, EVRSettingsError *peError = nullptr) = 0; +}; - //----------------------------------------------------------------------------- - static const char * const IVRSettings_Version = "IVRSettings_002"; +//----------------------------------------------------------------------------- +static const char *const IVRSettings_Version = "IVRSettings_002"; - //----------------------------------------------------------------------------- - // steamvr keys - static const char * const k_pch_SteamVR_Section = "steamvr"; - static const char * const k_pch_SteamVR_RequireHmd_String = "requireHmd"; - static const char * const k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; - static const char * const k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; - static const char * const k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; - static const char * const k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; - static const char * const k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; - static const char * const k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; - static const char * const k_pch_SteamVR_SendSystemButtonToAllApps_Bool= "sendSystemButtonToAllApps"; - static const char * const k_pch_SteamVR_LogLevel_Int32 = "loglevel"; - static const char * const k_pch_SteamVR_IPD_Float = "ipd"; - static const char * const k_pch_SteamVR_Background_String = "background"; - static const char * const k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; - static const char * const k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; - static const char * const k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; - static const char * const k_pch_SteamVR_GridColor_String = "gridColor"; - static const char * const k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; - static const char * const k_pch_SteamVR_ShowStage_Bool = "showStage"; - static const char * const k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; - static const char * const k_pch_SteamVR_DirectMode_Bool = "directMode"; - static const char * const k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; - static const char * const k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; - static const char * const k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; - static const char * const k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; - static const char * const k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; - static const char * const k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; - static const char * const k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; - static const char * const k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; - static const char * const k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; - static const char * const k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; - static const char * const k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; - static const char * const k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; - static const char * const k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; - static const char * const k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; - static const char * const k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; - static const char * const k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; - static const char * const k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; - static const char * const k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; - static const char * const k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; - static const char * const k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; - static const char * const k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; - static const char * const k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; - static const char * const k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; - static const char * const k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; +//----------------------------------------------------------------------------- +// steamvr keys +static const char *const k_pch_SteamVR_Section = "steamvr"; +static const char *const k_pch_SteamVR_RequireHmd_String = "requireHmd"; +static const char *const k_pch_SteamVR_ForcedDriverKey_String = "forcedDriver"; +static const char *const k_pch_SteamVR_ForcedHmdKey_String = "forcedHmd"; +static const char *const k_pch_SteamVR_DisplayDebug_Bool = "displayDebug"; +static const char *const k_pch_SteamVR_DebugProcessPipe_String = "debugProcessPipe"; +static const char *const k_pch_SteamVR_DisplayDebugX_Int32 = "displayDebugX"; +static const char *const k_pch_SteamVR_DisplayDebugY_Int32 = "displayDebugY"; +static const char *const k_pch_SteamVR_SendSystemButtonToAllApps_Bool = "sendSystemButtonToAllApps"; +static const char *const k_pch_SteamVR_LogLevel_Int32 = "loglevel"; +static const char *const k_pch_SteamVR_IPD_Float = "ipd"; +static const char *const k_pch_SteamVR_Background_String = "background"; +static const char *const k_pch_SteamVR_BackgroundUseDomeProjection_Bool = "backgroundUseDomeProjection"; +static const char *const k_pch_SteamVR_BackgroundCameraHeight_Float = "backgroundCameraHeight"; +static const char *const k_pch_SteamVR_BackgroundDomeRadius_Float = "backgroundDomeRadius"; +static const char *const k_pch_SteamVR_GridColor_String = "gridColor"; +static const char *const k_pch_SteamVR_PlayAreaColor_String = "playAreaColor"; +static const char *const k_pch_SteamVR_ShowStage_Bool = "showStage"; +static const char *const k_pch_SteamVR_ActivateMultipleDrivers_Bool = "activateMultipleDrivers"; +static const char *const k_pch_SteamVR_DirectMode_Bool = "directMode"; +static const char *const k_pch_SteamVR_DirectModeEdidVid_Int32 = "directModeEdidVid"; +static const char *const k_pch_SteamVR_DirectModeEdidPid_Int32 = "directModeEdidPid"; +static const char *const k_pch_SteamVR_UsingSpeakers_Bool = "usingSpeakers"; +static const char *const k_pch_SteamVR_SpeakersForwardYawOffsetDegrees_Float = "speakersForwardYawOffsetDegrees"; +static const char *const k_pch_SteamVR_BaseStationPowerManagement_Bool = "basestationPowerManagement"; +static const char *const k_pch_SteamVR_NeverKillProcesses_Bool = "neverKillProcesses"; +static const char *const k_pch_SteamVR_SupersampleScale_Float = "supersampleScale"; +static const char *const k_pch_SteamVR_AllowAsyncReprojection_Bool = "allowAsyncReprojection"; +static const char *const k_pch_SteamVR_AllowReprojection_Bool = "allowInterleavedReprojection"; +static const char *const k_pch_SteamVR_ForceReprojection_Bool = "forceReprojection"; +static const char *const k_pch_SteamVR_ForceFadeOnBadTracking_Bool = "forceFadeOnBadTracking"; +static const char *const k_pch_SteamVR_DefaultMirrorView_Int32 = "defaultMirrorView"; +static const char *const k_pch_SteamVR_ShowMirrorView_Bool = "showMirrorView"; +static const char *const k_pch_SteamVR_MirrorViewGeometry_String = "mirrorViewGeometry"; +static const char *const k_pch_SteamVR_StartMonitorFromAppLaunch = "startMonitorFromAppLaunch"; +static const char *const k_pch_SteamVR_StartCompositorFromAppLaunch_Bool = "startCompositorFromAppLaunch"; +static const char *const k_pch_SteamVR_StartDashboardFromAppLaunch_Bool = "startDashboardFromAppLaunch"; +static const char *const k_pch_SteamVR_StartOverlayAppsFromDashboard_Bool = "startOverlayAppsFromDashboard"; +static const char *const k_pch_SteamVR_EnableHomeApp = "enableHomeApp"; +static const char *const k_pch_SteamVR_CycleBackgroundImageTimeSec_Int32 = "CycleBackgroundImageTimeSec"; +static const char *const k_pch_SteamVR_RetailDemo_Bool = "retailDemo"; +static const char *const k_pch_SteamVR_IpdOffset_Float = "ipdOffset"; +static const char *const k_pch_SteamVR_AllowSupersampleFiltering_Bool = "allowSupersampleFiltering"; +static const char *const k_pch_SteamVR_EnableLinuxVulkanAsync_Bool = "enableLinuxVulkanAsync"; - //----------------------------------------------------------------------------- - // lighthouse keys - static const char * const k_pch_Lighthouse_Section = "driver_lighthouse"; - static const char * const k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; - static const char * const k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; - static const char * const k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; - static const char * const k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; - static const char * const k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; +//----------------------------------------------------------------------------- +// lighthouse keys +static const char *const k_pch_Lighthouse_Section = "driver_lighthouse"; +static const char *const k_pch_Lighthouse_DisableIMU_Bool = "disableimu"; +static const char *const k_pch_Lighthouse_UseDisambiguation_String = "usedisambiguation"; +static const char *const k_pch_Lighthouse_DisambiguationDebug_Int32 = "disambiguationdebug"; +static const char *const k_pch_Lighthouse_PrimaryBasestation_Int32 = "primarybasestation"; +static const char *const k_pch_Lighthouse_DBHistory_Bool = "dbhistory"; - //----------------------------------------------------------------------------- - // null keys - static const char * const k_pch_Null_Section = "driver_null"; - static const char * const k_pch_Null_SerialNumber_String = "serialNumber"; - static const char * const k_pch_Null_ModelNumber_String = "modelNumber"; - static const char * const k_pch_Null_WindowX_Int32 = "windowX"; - static const char * const k_pch_Null_WindowY_Int32 = "windowY"; - static const char * const k_pch_Null_WindowWidth_Int32 = "windowWidth"; - static const char * const k_pch_Null_WindowHeight_Int32 = "windowHeight"; - static const char * const k_pch_Null_RenderWidth_Int32 = "renderWidth"; - static const char * const k_pch_Null_RenderHeight_Int32 = "renderHeight"; - static const char * const k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; - static const char * const k_pch_Null_DisplayFrequency_Float = "displayFrequency"; +//----------------------------------------------------------------------------- +// null keys +static const char *const k_pch_Null_Section = "driver_null"; +static const char *const k_pch_Null_SerialNumber_String = "serialNumber"; +static const char *const k_pch_Null_ModelNumber_String = "modelNumber"; +static const char *const k_pch_Null_WindowX_Int32 = "windowX"; +static const char *const k_pch_Null_WindowY_Int32 = "windowY"; +static const char *const k_pch_Null_WindowWidth_Int32 = "windowWidth"; +static const char *const k_pch_Null_WindowHeight_Int32 = "windowHeight"; +static const char *const k_pch_Null_RenderWidth_Int32 = "renderWidth"; +static const char *const k_pch_Null_RenderHeight_Int32 = "renderHeight"; +static const char *const k_pch_Null_SecondsFromVsyncToPhotons_Float = "secondsFromVsyncToPhotons"; +static const char *const k_pch_Null_DisplayFrequency_Float = "displayFrequency"; - //----------------------------------------------------------------------------- - // user interface keys - static const char * const k_pch_UserInterface_Section = "userinterface"; - static const char * const k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; - static const char * const k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; - static const char * const k_pch_UserInterface_Screenshots_Bool = "screenshots"; - static const char * const k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; +//----------------------------------------------------------------------------- +// user interface keys +static const char *const k_pch_UserInterface_Section = "userinterface"; +static const char *const k_pch_UserInterface_StatusAlwaysOnTop_Bool = "StatusAlwaysOnTop"; +static const char *const k_pch_UserInterface_MinimizeToTray_Bool = "MinimizeToTray"; +static const char *const k_pch_UserInterface_Screenshots_Bool = "screenshots"; +static const char *const k_pch_UserInterface_ScreenshotType_Int = "screenshotType"; - //----------------------------------------------------------------------------- - // notification keys - static const char * const k_pch_Notifications_Section = "notifications"; - static const char * const k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; +//----------------------------------------------------------------------------- +// notification keys +static const char *const k_pch_Notifications_Section = "notifications"; +static const char *const k_pch_Notifications_DoNotDisturb_Bool = "DoNotDisturb"; - //----------------------------------------------------------------------------- - // keyboard keys - static const char * const k_pch_Keyboard_Section = "keyboard"; - static const char * const k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; - static const char * const k_pch_Keyboard_ScaleX = "ScaleX"; - static const char * const k_pch_Keyboard_ScaleY = "ScaleY"; - static const char * const k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; - static const char * const k_pch_Keyboard_OffsetRightX = "OffsetRightX"; - static const char * const k_pch_Keyboard_OffsetY = "OffsetY"; - static const char * const k_pch_Keyboard_Smoothing = "Smoothing"; +//----------------------------------------------------------------------------- +// keyboard keys +static const char *const k_pch_Keyboard_Section = "keyboard"; +static const char *const k_pch_Keyboard_TutorialCompletions = "TutorialCompletions"; +static const char *const k_pch_Keyboard_ScaleX = "ScaleX"; +static const char *const k_pch_Keyboard_ScaleY = "ScaleY"; +static const char *const k_pch_Keyboard_OffsetLeftX = "OffsetLeftX"; +static const char *const k_pch_Keyboard_OffsetRightX = "OffsetRightX"; +static const char *const k_pch_Keyboard_OffsetY = "OffsetY"; +static const char *const k_pch_Keyboard_Smoothing = "Smoothing"; - //----------------------------------------------------------------------------- - // perf keys - static const char * const k_pch_Perf_Section = "perfcheck"; - static const char * const k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; - static const char * const k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; - static const char * const k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; - static const char * const k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; - static const char * const k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; - static const char * const k_pch_Perf_TestData_Float = "perfTestData"; - static const char * const k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; +//----------------------------------------------------------------------------- +// perf keys +static const char *const k_pch_Perf_Section = "perfcheck"; +static const char *const k_pch_Perf_HeuristicActive_Bool = "heuristicActive"; +static const char *const k_pch_Perf_NotifyInHMD_Bool = "warnInHMD"; +static const char *const k_pch_Perf_NotifyOnlyOnce_Bool = "warnOnlyOnce"; +static const char *const k_pch_Perf_AllowTimingStore_Bool = "allowTimingStore"; +static const char *const k_pch_Perf_SaveTimingsOnExit_Bool = "saveTimingsOnExit"; +static const char *const k_pch_Perf_TestData_Float = "perfTestData"; +static const char *const k_pch_Perf_LinuxGPUProfiling_Bool = "linuxGPUProfiling"; - //----------------------------------------------------------------------------- - // collision bounds keys - static const char * const k_pch_CollisionBounds_Section = "collisionBounds"; - static const char * const k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; - static const char * const k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; - static const char * const k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; - static const char * const k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; - static const char * const k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; - static const char * const k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; - static const char * const k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; - static const char * const k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; - static const char * const k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; +//----------------------------------------------------------------------------- +// collision bounds keys +static const char *const k_pch_CollisionBounds_Section = "collisionBounds"; +static const char *const k_pch_CollisionBounds_Style_Int32 = "CollisionBoundsStyle"; +static const char *const k_pch_CollisionBounds_GroundPerimeterOn_Bool = "CollisionBoundsGroundPerimeterOn"; +static const char *const k_pch_CollisionBounds_CenterMarkerOn_Bool = "CollisionBoundsCenterMarkerOn"; +static const char *const k_pch_CollisionBounds_PlaySpaceOn_Bool = "CollisionBoundsPlaySpaceOn"; +static const char *const k_pch_CollisionBounds_FadeDistance_Float = "CollisionBoundsFadeDistance"; +static const char *const k_pch_CollisionBounds_ColorGammaR_Int32 = "CollisionBoundsColorGammaR"; +static const char *const k_pch_CollisionBounds_ColorGammaG_Int32 = "CollisionBoundsColorGammaG"; +static const char *const k_pch_CollisionBounds_ColorGammaB_Int32 = "CollisionBoundsColorGammaB"; +static const char *const k_pch_CollisionBounds_ColorGammaA_Int32 = "CollisionBoundsColorGammaA"; - //----------------------------------------------------------------------------- - // camera keys - static const char * const k_pch_Camera_Section = "camera"; - static const char * const k_pch_Camera_EnableCamera_Bool = "enableCamera"; - static const char * const k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; - static const char * const k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; - static const char * const k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; - static const char * const k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; - static const char * const k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; - static const char * const k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; - static const char * const k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; - static const char * const k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; +//----------------------------------------------------------------------------- +// camera keys +static const char *const k_pch_Camera_Section = "camera"; +static const char *const k_pch_Camera_EnableCamera_Bool = "enableCamera"; +static const char *const k_pch_Camera_EnableCameraInDashboard_Bool = "enableCameraInDashboard"; +static const char *const k_pch_Camera_EnableCameraForCollisionBounds_Bool = "enableCameraForCollisionBounds"; +static const char *const k_pch_Camera_EnableCameraForRoomView_Bool = "enableCameraForRoomView"; +static const char *const k_pch_Camera_BoundsColorGammaR_Int32 = "cameraBoundsColorGammaR"; +static const char *const k_pch_Camera_BoundsColorGammaG_Int32 = "cameraBoundsColorGammaG"; +static const char *const k_pch_Camera_BoundsColorGammaB_Int32 = "cameraBoundsColorGammaB"; +static const char *const k_pch_Camera_BoundsColorGammaA_Int32 = "cameraBoundsColorGammaA"; +static const char *const k_pch_Camera_BoundsStrength_Int32 = "cameraBoundsStrength"; - //----------------------------------------------------------------------------- - // audio keys - static const char * const k_pch_audio_Section = "audio"; - static const char * const k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; - static const char * const k_pch_audio_OnRecordDevice_String = "onRecordDevice"; - static const char * const k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; - static const char * const k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; - static const char * const k_pch_audio_OffRecordDevice_String = "offRecordDevice"; - static const char * const k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; +//----------------------------------------------------------------------------- +// audio keys +static const char *const k_pch_audio_Section = "audio"; +static const char *const k_pch_audio_OnPlaybackDevice_String = "onPlaybackDevice"; +static const char *const k_pch_audio_OnRecordDevice_String = "onRecordDevice"; +static const char *const k_pch_audio_OnPlaybackMirrorDevice_String = "onPlaybackMirrorDevice"; +static const char *const k_pch_audio_OffPlaybackDevice_String = "offPlaybackDevice"; +static const char *const k_pch_audio_OffRecordDevice_String = "offRecordDevice"; +static const char *const k_pch_audio_VIVEHDMIGain = "viveHDMIGain"; - //----------------------------------------------------------------------------- - // power management keys - static const char * const k_pch_Power_Section = "power"; - static const char * const k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; - static const char * const k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; - static const char * const k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; - static const char * const k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; - static const char * const k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; - static const char * const k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; +//----------------------------------------------------------------------------- +// power management keys +static const char *const k_pch_Power_Section = "power"; +static const char *const k_pch_Power_PowerOffOnExit_Bool = "powerOffOnExit"; +static const char *const k_pch_Power_TurnOffScreensTimeout_Float = "turnOffScreensTimeout"; +static const char *const k_pch_Power_TurnOffControllersTimeout_Float = "turnOffControllersTimeout"; +static const char *const k_pch_Power_ReturnToWatchdogTimeout_Float = "returnToWatchdogTimeout"; +static const char *const k_pch_Power_AutoLaunchSteamVROnButtonPress = "autoLaunchSteamVROnButtonPress"; +static const char *const k_pch_Power_PauseCompositorOnStandby_Bool = "pauseCompositorOnStandby"; - //----------------------------------------------------------------------------- - // dashboard keys - static const char * const k_pch_Dashboard_Section = "dashboard"; - static const char * const k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; - static const char * const k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; +//----------------------------------------------------------------------------- +// dashboard keys +static const char *const k_pch_Dashboard_Section = "dashboard"; +static const char *const k_pch_Dashboard_EnableDashboard_Bool = "enableDashboard"; +static const char *const k_pch_Dashboard_ArcadeMode_Bool = "arcadeMode"; - //----------------------------------------------------------------------------- - // model skin keys - static const char * const k_pch_modelskin_Section = "modelskins"; +//----------------------------------------------------------------------------- +// model skin keys +static const char *const k_pch_modelskin_Section = "modelskins"; - //----------------------------------------------------------------------------- - // driver keys - These could be checked in any driver_ section - static const char * const k_pch_Driver_Enable_Bool = "enable"; +//----------------------------------------------------------------------------- +// driver keys - These could be checked in any driver_ section +static const char *const k_pch_Driver_Enable_Bool = "enable"; -} // namespace vr +} // namespace vr // iservertrackeddevicedriver.h namespace vr { - - struct DriverPoseQuaternion_t { double w, x, y, z; @@ -1573,10 +1543,10 @@ struct DriverPose_t * lagged due to the filtering required to reduce noise to an acceptable level. */ vr::HmdQuaternion_t qWorldFromDriverRotation; - double vecWorldFromDriverTranslation[ 3 ]; + double vecWorldFromDriverTranslation[3]; vr::HmdQuaternion_t qDriverFromHeadRotation; - double vecDriverFromHeadTranslation[ 3 ]; + double vecDriverFromHeadTranslation[3]; /* State of driver pose, in meters and radians. */ /* Position of the driver tracking reference in driver world space @@ -1584,13 +1554,13 @@ struct DriverPose_t * +[1] (y) is up * -[2] (z) is forward */ - double vecPosition[ 3 ]; + double vecPosition[3]; /* Velocity of the pose in meters/second */ - double vecVelocity[ 3 ]; + double vecVelocity[3]; /* Acceleration of the pose in meters/second */ - double vecAcceleration[ 3 ]; + double vecAcceleration[3]; /* Orientation of the tracker, represented as a quaternion */ vr::HmdQuaternion_t qRotation; @@ -1599,13 +1569,13 @@ struct DriverPose_t * representation. The direction is the angle of * rotation and the magnitude is the angle around * that axis in radians/second. */ - double vecAngularVelocity[ 3 ]; + double vecAngularVelocity[3]; /* Angular acceleration of the pose in axis-angle * representation. The direction is the angle of * rotation and the magnitude is the angle around * that axis in radians/second^2. */ - double vecAngularAcceleration[ 3 ]; + double vecAngularAcceleration[3]; ETrackingResult result; @@ -1615,14 +1585,12 @@ struct DriverPose_t bool deviceIsConnected; }; - // ---------------------------------------------------------------------------------------------- // Purpose: Represents a single tracked device in a driver // ---------------------------------------------------------------------------------------------- class ITrackedDeviceServerDriver { public: - // ------------------------------------ // Management Methods // ------------------------------------ @@ -1631,7 +1599,7 @@ public: * ITrackedDeviceServerDriver object should be kept to a minimum until it is activated. * The pose listener is guaranteed to be valid until Deactivate is called, but * should not be used after that point. */ - virtual EVRInitError Activate( uint32_t unObjectId ) = 0; + virtual EVRInitError Activate(uint32_t unObjectId) = 0; /** This is called when The VR system is switching from this Hmd being the active display * to another Hmd being the active display. The driver should clean whatever memory @@ -1643,12 +1611,12 @@ public: /** Requests a component interface of the driver for device-specific functionality. The driver should return NULL * if the requested interface or version is not supported. */ - virtual void *GetComponent( const char *pchComponentNameAndVersion ) = 0; + virtual void *GetComponent(const char *pchComponentNameAndVersion) = 0; /** A VR Client has made this debug request of the driver. The set of valid requests is entirely * up to the driver and the client to figure out, as is the format of the response. Responses that * exceed the length of the supplied buffer should be truncated and null terminated */ - virtual void DebugRequest( const char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize ) = 0; + virtual void DebugRequest(const char *pchRequest, char *pchResponseBuffer, uint32_t unResponseBufferSize) = 0; // ------------------------------------ // Tracking Methods @@ -1656,177 +1624,160 @@ public: virtual DriverPose_t GetPose() = 0; }; - - static const char *ITrackedDeviceServerDriver_Version = "ITrackedDeviceServerDriver_005"; -} +} // namespace vr // ivrdisplaycomponent.h namespace vr { +// ---------------------------------------------------------------------------------------------- +// Purpose: The display component on a single tracked device +// ---------------------------------------------------------------------------------------------- +class IVRDisplayComponent +{ +public: + // ------------------------------------ + // Display Methods + // ------------------------------------ + /** Size and position that the window needs to be on the VR display. */ + virtual void GetWindowBounds(int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight) = 0; - // ---------------------------------------------------------------------------------------------- - // Purpose: The display component on a single tracked device - // ---------------------------------------------------------------------------------------------- - class IVRDisplayComponent - { - public: + /** Returns true if the display is extending the desktop. */ + virtual bool IsDisplayOnDesktop() = 0; - // ------------------------------------ - // Display Methods - // ------------------------------------ + /** Returns true if the display is real and not a fictional display. */ + virtual bool IsDisplayRealDisplay() = 0; - /** Size and position that the window needs to be on the VR display. */ - virtual void GetWindowBounds( int32_t *pnX, int32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; + /** Suggested size for the intermediate render target that the distortion pulls from. */ + virtual void GetRecommendedRenderTargetSize(uint32_t *pnWidth, uint32_t *pnHeight) = 0; - /** Returns true if the display is extending the desktop. */ - virtual bool IsDisplayOnDesktop( ) = 0; + /** Gets the viewport in the frame buffer to draw the output of the distortion into */ + virtual void GetEyeOutputViewport(EVREye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight) = 0; - /** Returns true if the display is real and not a fictional display. */ - virtual bool IsDisplayRealDisplay( ) = 0; - - /** Suggested size for the intermediate render target that the distortion pulls from. */ - virtual void GetRecommendedRenderTargetSize( uint32_t *pnWidth, uint32_t *pnHeight ) = 0; - - /** Gets the viewport in the frame buffer to draw the output of the distortion into */ - virtual void GetEyeOutputViewport( EVREye eEye, uint32_t *pnX, uint32_t *pnY, uint32_t *pnWidth, uint32_t *pnHeight ) = 0; - - /** The components necessary to build your own projection matrix in case your + /** The components necessary to build your own projection matrix in case your * application is doing something fancy like infinite Z */ - virtual void GetProjectionRaw( EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom ) = 0; + virtual void GetProjectionRaw(EVREye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom) = 0; - /** Returns the result of the distortion function for the specified eye and input UVs. UVs go from 0,0 in + /** Returns the result of the distortion function for the specified eye and input UVs. UVs go from 0,0 in * the upper left of that eye's viewport and 1,1 in the lower right of that eye's viewport. */ - virtual DistortionCoordinates_t ComputeDistortion( EVREye eEye, float fU, float fV ) = 0; + virtual DistortionCoordinates_t ComputeDistortion(EVREye eEye, float fU, float fV) = 0; +}; - }; +static const char *IVRDisplayComponent_Version = "IVRDisplayComponent_002"; - static const char *IVRDisplayComponent_Version = "IVRDisplayComponent_002"; - -} +} // namespace vr // ivrdriverdirectmodecomponent.h namespace vr { +// ---------------------------------------------------------------------------------------------- +// Purpose: This component is used for drivers that implement direct mode entirely on their own +// without allowing the VR Compositor to own the window/device. Chances are you don't +// need to implement this component in your driver. +// ---------------------------------------------------------------------------------------------- +class IVRDriverDirectModeComponent +{ +public: + // ----------------------------------- + // Direct mode methods + // ----------------------------------- + /** Specific to Oculus compositor support, textures supplied must be created using this method. */ + virtual void CreateSwapTextureSet(uint32_t unPid, uint32_t unFormat, uint32_t unWidth, uint32_t unHeight, vr::SharedTextureHandle_t (*pSharedTextureHandles)[3]) {} - // ---------------------------------------------------------------------------------------------- - // Purpose: This component is used for drivers that implement direct mode entirely on their own - // without allowing the VR Compositor to own the window/device. Chances are you don't - // need to implement this component in your driver. - // ---------------------------------------------------------------------------------------------- - class IVRDriverDirectModeComponent - { - public: + /** Used to textures created using CreateSwapTextureSet. Only one of the set's handles needs to be used to destroy the entire set. */ + virtual void DestroySwapTextureSet(vr::SharedTextureHandle_t sharedTextureHandle) {} - // ----------------------------------- - // Direct mode methods - // ----------------------------------- + /** Used to purge all texture sets for a given process. */ + virtual void DestroyAllSwapTextureSets(uint32_t unPid) {} - /** Specific to Oculus compositor support, textures supplied must be created using this method. */ - virtual void CreateSwapTextureSet( uint32_t unPid, uint32_t unFormat, uint32_t unWidth, uint32_t unHeight, vr::SharedTextureHandle_t( *pSharedTextureHandles )[ 3 ] ) {} + /** After Present returns, calls this to get the next index to use for rendering. */ + virtual void GetNextSwapTextureSetIndex(vr::SharedTextureHandle_t sharedTextureHandles[2], uint32_t (*pIndices)[2]) {} - /** Used to textures created using CreateSwapTextureSet. Only one of the set's handles needs to be used to destroy the entire set. */ - virtual void DestroySwapTextureSet( vr::SharedTextureHandle_t sharedTextureHandle ) {} - - /** Used to purge all texture sets for a given process. */ - virtual void DestroyAllSwapTextureSets( uint32_t unPid ) {} - - /** After Present returns, calls this to get the next index to use for rendering. */ - virtual void GetNextSwapTextureSetIndex( vr::SharedTextureHandle_t sharedTextureHandles[ 2 ], uint32_t( *pIndices )[ 2 ] ) {} - - /** Call once per layer to draw for this frame. One shared texture handle per eye. Textures must be created + /** Call once per layer to draw for this frame. One shared texture handle per eye. Textures must be created * using CreateSwapTextureSet and should be alternated per frame. Call Present once all layers have been submitted. */ - virtual void SubmitLayer( vr::SharedTextureHandle_t sharedTextureHandles[ 2 ], const vr::VRTextureBounds_t( &bounds )[ 2 ], const vr::HmdMatrix34_t *pPose ) {} + virtual void SubmitLayer(vr::SharedTextureHandle_t sharedTextureHandles[2], const vr::VRTextureBounds_t (&bounds)[2], const vr::HmdMatrix34_t *pPose) {} - /** Submits queued layers for display. */ - virtual void Present( vr::SharedTextureHandle_t syncTexture ) {} + /** Submits queued layers for display. */ + virtual void Present(vr::SharedTextureHandle_t syncTexture) {} +}; - }; +static const char *IVRDriverDirectModeComponent_Version = "IVRDriverDirectModeComponent_002"; - static const char *IVRDriverDirectModeComponent_Version = "IVRDriverDirectModeComponent_002"; - -} +} // namespace vr // ivrcontrollercomponent.h namespace vr { +// ---------------------------------------------------------------------------------------------- +// Purpose: Controller access on a single tracked device. +// ---------------------------------------------------------------------------------------------- +class IVRControllerComponent +{ +public: + // ------------------------------------ + // Controller Methods + // ------------------------------------ + /** Gets the current state of a controller. */ + virtual VRControllerState_t GetControllerState() = 0; - // ---------------------------------------------------------------------------------------------- - // Purpose: Controller access on a single tracked device. - // ---------------------------------------------------------------------------------------------- - class IVRControllerComponent - { - public: + /** Returns a uint64 property. If the property is not available this function will return 0. */ + virtual bool TriggerHapticPulse(uint32_t unAxisId, uint16_t usPulseDurationMicroseconds) = 0; +}; - // ------------------------------------ - // Controller Methods - // ------------------------------------ +static const char *IVRControllerComponent_Version = "IVRControllerComponent_001"; - /** Gets the current state of a controller. */ - virtual VRControllerState_t GetControllerState( ) = 0; - - /** Returns a uint64 property. If the property is not available this function will return 0. */ - virtual bool TriggerHapticPulse( uint32_t unAxisId, uint16_t usPulseDurationMicroseconds ) = 0; - - }; - - - - static const char *IVRControllerComponent_Version = "IVRControllerComponent_001"; - -} +} // namespace vr // ivrcameracomponent.h namespace vr { - //----------------------------------------------------------------------------- - //----------------------------------------------------------------------------- - class ICameraVideoSinkCallback - { - public: - virtual void OnCameraVideoSinkCallback() = 0; - }; +//----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +class ICameraVideoSinkCallback +{ +public: + virtual void OnCameraVideoSinkCallback() = 0; +}; - // ---------------------------------------------------------------------------------------------- - // Purpose: The camera on a single tracked device - // ---------------------------------------------------------------------------------------------- - class IVRCameraComponent - { - public: - // ------------------------------------ - // Camera Methods - // ------------------------------------ - virtual bool GetCameraFrameDimensions( vr::ECameraVideoStreamFormat nVideoStreamFormat, uint32_t *pWidth, uint32_t *pHeight ) = 0; - virtual bool GetCameraFrameBufferingRequirements( int *pDefaultFrameQueueSize, uint32_t *pFrameBufferDataSize ) = 0; - virtual bool SetCameraFrameBuffering( int nFrameBufferCount, void **ppFrameBuffers, uint32_t nFrameBufferDataSize ) = 0; - virtual bool SetCameraVideoStreamFormat( vr::ECameraVideoStreamFormat nVideoStreamFormat ) = 0; - virtual vr::ECameraVideoStreamFormat GetCameraVideoStreamFormat() = 0; - virtual bool StartVideoStream() = 0; - virtual void StopVideoStream() = 0; - virtual bool IsVideoStreamActive( bool *pbPaused, float *pflElapsedTime ) = 0; - virtual const vr::CameraVideoStreamFrame_t *GetVideoStreamFrame() = 0; - virtual void ReleaseVideoStreamFrame( const vr::CameraVideoStreamFrame_t *pFrameImage ) = 0; - virtual bool SetAutoExposure( bool bEnable ) = 0; - virtual bool PauseVideoStream() = 0; - virtual bool ResumeVideoStream() = 0; - virtual bool GetCameraDistortion( float flInputU, float flInputV, float *pflOutputU, float *pflOutputV ) = 0; - virtual bool GetCameraProjection( vr::EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, vr::HmdMatrix44_t *pProjection ) = 0; - virtual bool SetFrameRate( int nISPFrameRate, int nSensorFrameRate ) = 0; - virtual bool SetCameraVideoSinkCallback( vr::ICameraVideoSinkCallback *pCameraVideoSinkCallback ) = 0; - virtual bool GetCameraCompatibilityMode( vr::ECameraCompatibilityMode *pCameraCompatibilityMode ) = 0; - virtual bool SetCameraCompatibilityMode( vr::ECameraCompatibilityMode nCameraCompatibilityMode ) = 0; - virtual bool GetCameraFrameBounds( vr::EVRTrackedCameraFrameType eFrameType, uint32_t *pLeft, uint32_t *pTop, uint32_t *pWidth, uint32_t *pHeight ) = 0; - virtual bool GetCameraIntrinsics( vr::EVRTrackedCameraFrameType eFrameType, HmdVector2_t *pFocalLength, HmdVector2_t *pCenter ) = 0; - }; +// ---------------------------------------------------------------------------------------------- +// Purpose: The camera on a single tracked device +// ---------------------------------------------------------------------------------------------- +class IVRCameraComponent +{ +public: + // ------------------------------------ + // Camera Methods + // ------------------------------------ + virtual bool GetCameraFrameDimensions(vr::ECameraVideoStreamFormat nVideoStreamFormat, uint32_t *pWidth, uint32_t *pHeight) = 0; + virtual bool GetCameraFrameBufferingRequirements(int *pDefaultFrameQueueSize, uint32_t *pFrameBufferDataSize) = 0; + virtual bool SetCameraFrameBuffering(int nFrameBufferCount, void **ppFrameBuffers, uint32_t nFrameBufferDataSize) = 0; + virtual bool SetCameraVideoStreamFormat(vr::ECameraVideoStreamFormat nVideoStreamFormat) = 0; + virtual vr::ECameraVideoStreamFormat GetCameraVideoStreamFormat() = 0; + virtual bool StartVideoStream() = 0; + virtual void StopVideoStream() = 0; + virtual bool IsVideoStreamActive(bool *pbPaused, float *pflElapsedTime) = 0; + virtual const vr::CameraVideoStreamFrame_t *GetVideoStreamFrame() = 0; + virtual void ReleaseVideoStreamFrame(const vr::CameraVideoStreamFrame_t *pFrameImage) = 0; + virtual bool SetAutoExposure(bool bEnable) = 0; + virtual bool PauseVideoStream() = 0; + virtual bool ResumeVideoStream() = 0; + virtual bool GetCameraDistortion(float flInputU, float flInputV, float *pflOutputU, float *pflOutputV) = 0; + virtual bool GetCameraProjection(vr::EVRTrackedCameraFrameType eFrameType, float flZNear, float flZFar, vr::HmdMatrix44_t *pProjection) = 0; + virtual bool SetFrameRate(int nISPFrameRate, int nSensorFrameRate) = 0; + virtual bool SetCameraVideoSinkCallback(vr::ICameraVideoSinkCallback *pCameraVideoSinkCallback) = 0; + virtual bool GetCameraCompatibilityMode(vr::ECameraCompatibilityMode *pCameraCompatibilityMode) = 0; + virtual bool SetCameraCompatibilityMode(vr::ECameraCompatibilityMode nCameraCompatibilityMode) = 0; + virtual bool GetCameraFrameBounds(vr::EVRTrackedCameraFrameType eFrameType, uint32_t *pLeft, uint32_t *pTop, uint32_t *pWidth, uint32_t *pHeight) = 0; + virtual bool GetCameraIntrinsics(vr::EVRTrackedCameraFrameType eFrameType, HmdVector2_t *pFocalLength, HmdVector2_t *pCenter) = 0; +}; - static const char *IVRCameraComponent_Version = "IVRCameraComponent_002"; -} +static const char *IVRCameraComponent_Version = "IVRCameraComponent_002"; +} // namespace vr // itrackeddevicedriverprovider.h namespace vr { - class ITrackedDeviceServerDriver; struct TrackedDeviceDriverInfo_t; struct DriverPose_t; @@ -1841,13 +1792,12 @@ class IVRDriverContext public: /** Returns the requested interface. If the interface was not available it will return NULL and fill * out the error. */ - virtual void *GetGenericInterface( const char *pchInterfaceVersion, EVRInitError *peError = nullptr ) = 0; + virtual void *GetGenericInterface(const char *pchInterfaceVersion, EVRInitError *peError = nullptr) = 0; /** Returns the property container handle for this driver */ virtual DriverHandle_t GetDriverHandle() = 0; }; - /** This interface must be implemented in each driver. It will be loaded in vrserver.exe */ class IServerTrackedDeviceProvider { @@ -1861,18 +1811,17 @@ public: * config files. * pchDriverInstallDir - The absolute path of the root directory for the driver. */ - virtual EVRInitError Init( IVRDriverContext *pDriverContext ) = 0; + virtual EVRInitError Init(IVRDriverContext *pDriverContext) = 0; /** cleans up the driver right before it is unloaded */ virtual void Cleanup() = 0; /** Returns the version of the ITrackedDeviceServerDriver interface used by this driver */ - virtual const char * const *GetInterfaceVersions() = 0; + virtual const char *const *GetInterfaceVersions() = 0; /** Allows the driver do to some work in the main loop of the server. */ virtual void RunFrame() = 0; - // ------------ Power State Functions ----------------------- // /** Returns true if the driver wants to block Standby mode. */ @@ -1885,21 +1834,16 @@ public: /** Called when the system is leaving Standby mode. The driver should switch itself back to full operation. */ virtual void LeaveStandby() = 0; - }; - static const char *IServerTrackedDeviceProvider_Version = "IServerTrackedDeviceProvider_004"; - - - /** This interface must be implemented in each driver. It will be loaded in vrclient.dll */ class IVRWatchdogProvider { public: /** initializes the driver in watchdog mode. */ - virtual EVRInitError Init( IVRDriverContext *pDriverContext ) = 0; + virtual EVRInitError Init(IVRDriverContext *pDriverContext) = 0; /** cleans up the driver right before it is unloaded */ virtual void Cleanup() = 0; @@ -1907,134 +1851,128 @@ public: static const char *IVRWatchdogProvider_Version = "IVRWatchdogProvider_001"; -} +} // namespace vr // ivrproperties.h #include namespace vr { +enum EPropertyWriteType +{ + PropertyWrite_Set = 0, + PropertyWrite_Erase = 1, + PropertyWrite_SetError = 2 +}; - enum EPropertyWriteType - { - PropertyWrite_Set = 0, - PropertyWrite_Erase = 1, - PropertyWrite_SetError = 2 - }; - - struct PropertyWrite_t - { - ETrackedDeviceProperty prop; - EPropertyWriteType writeType; - ETrackedPropertyError eSetError; - void *pvBuffer; - uint32_t unBufferSize; - PropertyTypeTag_t unTag; - ETrackedPropertyError eError; - }; - - struct PropertyRead_t - { - ETrackedDeviceProperty prop; - void *pvBuffer; - uint32_t unBufferSize; - PropertyTypeTag_t unTag; - uint32_t unRequiredBufferSize; - ETrackedPropertyError eError; - }; +struct PropertyWrite_t +{ + ETrackedDeviceProperty prop; + EPropertyWriteType writeType; + ETrackedPropertyError eSetError; + void *pvBuffer; + uint32_t unBufferSize; + PropertyTypeTag_t unTag; + ETrackedPropertyError eError; +}; +struct PropertyRead_t +{ + ETrackedDeviceProperty prop; + void *pvBuffer; + uint32_t unBufferSize; + PropertyTypeTag_t unTag; + uint32_t unRequiredBufferSize; + ETrackedPropertyError eError; +}; class IVRProperties { public: - /** Reads a set of properties atomically. See the PropertyReadBatch_t struct for more information. */ - virtual ETrackedPropertyError ReadPropertyBatch( PropertyContainerHandle_t ulContainerHandle, PropertyRead_t *pBatch, uint32_t unBatchEntryCount ) = 0; + virtual ETrackedPropertyError ReadPropertyBatch(PropertyContainerHandle_t ulContainerHandle, PropertyRead_t *pBatch, uint32_t unBatchEntryCount) = 0; /** Writes a set of properties atomically. See the PropertyWriteBatch_t struct for more information. */ - virtual ETrackedPropertyError WritePropertyBatch( PropertyContainerHandle_t ulContainerHandle, PropertyWrite_t *pBatch, uint32_t unBatchEntryCount ) = 0; + virtual ETrackedPropertyError WritePropertyBatch(PropertyContainerHandle_t ulContainerHandle, PropertyWrite_t *pBatch, uint32_t unBatchEntryCount) = 0; /** returns a string that corresponds with the specified property error. The string will be the name * of the error enum value for all valid error codes */ - virtual const char *GetPropErrorNameFromEnum( ETrackedPropertyError error ) = 0; + virtual const char *GetPropErrorNameFromEnum(ETrackedPropertyError error) = 0; /** Returns a container handle given a tracked device index */ - virtual PropertyContainerHandle_t TrackedDeviceToPropertyContainer( TrackedDeviceIndex_t nDevice ) = 0; - + virtual PropertyContainerHandle_t TrackedDeviceToPropertyContainer(TrackedDeviceIndex_t nDevice) = 0; }; -static const char * const IVRProperties_Version = "IVRProperties_001"; +static const char *const IVRProperties_Version = "IVRProperties_001"; class CVRPropertyHelpers { public: - CVRPropertyHelpers( IVRProperties * pProperties ) : m_pProperties( pProperties ) {} + CVRPropertyHelpers(IVRProperties *pProperties) : m_pProperties(pProperties) {} /** Returns a scaler property. If the device index is not valid or the property value type does not match, * this function will return false. */ - bool GetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ); - float GetFloatProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ); - int32_t GetInt32Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ); - uint64_t GetUint64Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L ); + bool GetBoolProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L); + float GetFloatProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L); + int32_t GetInt32Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L); + uint64_t GetUint64Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError = 0L); /** Returns a single typed property. If the device index is not valid or the property is not a string type this function will * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */ - uint32_t GetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() void *pvBuffer, uint32_t unBufferSize, PropertyTypeTag_t *punTag, ETrackedPropertyError *pError = 0L ); - + uint32_t GetProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() void *pvBuffer, uint32_t unBufferSize, PropertyTypeTag_t *punTag, ETrackedPropertyError *pError = 0L); /** Returns a string property. If the device index is not valid or the property is not a string type this function will * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */ - uint32_t GetStringProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L ); + uint32_t GetStringProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError = 0L); /** Returns a string property as a std::string. If the device index is not valid or the property is not a string type this function will * return an empty string. */ - std::string GetStringProperty( vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError = nullptr ); + std::string GetStringProperty(vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError = nullptr); /** Sets a scaler property. The new value will be returned on any subsequent call to get this property in any process. */ - ETrackedPropertyError SetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, bool bNewValue ); - ETrackedPropertyError SetFloatProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, float fNewValue ); - ETrackedPropertyError SetInt32Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, int32_t nNewValue ); - ETrackedPropertyError SetUint64Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, uint64_t ulNewValue ); + ETrackedPropertyError SetBoolProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, bool bNewValue); + ETrackedPropertyError SetFloatProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, float fNewValue); + ETrackedPropertyError SetInt32Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, int32_t nNewValue); + ETrackedPropertyError SetUint64Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, uint64_t ulNewValue); /** Sets a string property. The new value will be returned on any subsequent call to get this property in any process. */ - ETrackedPropertyError SetStringProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, const char *pchNewValue ); + ETrackedPropertyError SetStringProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, const char *pchNewValue); /** Sets a single typed property. The new value will be returned on any subsequent call to get this property in any process. */ - ETrackedPropertyError SetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, void *pvNewValue, uint32_t unNewValueSize, PropertyTypeTag_t unTag ); + ETrackedPropertyError SetProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, void *pvNewValue, uint32_t unNewValueSize, PropertyTypeTag_t unTag); /** Sets the error return value for a property. This value will be returned on all subsequent requests to get the property */ - ETrackedPropertyError SetPropertyError( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError eError ); + ETrackedPropertyError SetPropertyError(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError eError); /** Clears any value or error set for the property. */ - ETrackedPropertyError EraseProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop ); + ETrackedPropertyError EraseProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop); /* Turns a device index into a property container handle. */ - PropertyContainerHandle_t TrackedDeviceToPropertyContainer( TrackedDeviceIndex_t nDevice ) { return m_pProperties->TrackedDeviceToPropertyContainer( nDevice ); } + PropertyContainerHandle_t TrackedDeviceToPropertyContainer(TrackedDeviceIndex_t nDevice) { return m_pProperties->TrackedDeviceToPropertyContainer(nDevice); } private: - template - T GetPropertyHelper( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError, T bDefault, PropertyTypeTag_t unTypeTag ); + template + T GetPropertyHelper(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError, T bDefault, PropertyTypeTag_t unTypeTag); IVRProperties *m_pProperties; }; - -inline uint32_t CVRPropertyHelpers::GetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() void *pvBuffer, uint32_t unBufferSize, PropertyTypeTag_t *punTag, ETrackedPropertyError *pError ) +inline uint32_t CVRPropertyHelpers::GetProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() void *pvBuffer, uint32_t unBufferSize, PropertyTypeTag_t *punTag, ETrackedPropertyError *pError) { PropertyRead_t batch; batch.prop = prop; batch.pvBuffer = pvBuffer; batch.unBufferSize = unBufferSize; - m_pProperties->ReadPropertyBatch( ulContainerHandle, &batch, 1 ); + m_pProperties->ReadPropertyBatch(ulContainerHandle, &batch, 1); - if ( pError ) + if (pError) { *pError = batch.eError; } - if ( punTag ) + if (punTag) { *punTag = batch.unTag; } @@ -2042,9 +1980,8 @@ inline uint32_t CVRPropertyHelpers::GetProperty( PropertyContainerHandle_t ulCon return batch.unRequiredBufferSize; } - /** Sets a single typed property. The new value will be returned on any subsequent call to get this property in any process. */ -inline ETrackedPropertyError CVRPropertyHelpers::SetProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, void *pvNewValue, uint32_t unNewValueSize, PropertyTypeTag_t unTag ) +inline ETrackedPropertyError CVRPropertyHelpers::SetProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, void *pvNewValue, uint32_t unNewValueSize, PropertyTypeTag_t unTag) { PropertyWrite_t batch; batch.writeType = PropertyWrite_Set; @@ -2053,33 +1990,32 @@ inline ETrackedPropertyError CVRPropertyHelpers::SetProperty( PropertyContainerH batch.unBufferSize = unNewValueSize; batch.unTag = unTag; - m_pProperties->WritePropertyBatch( ulContainerHandle, &batch, 1 ); + m_pProperties->WritePropertyBatch(ulContainerHandle, &batch, 1); return batch.eError; } - /** Returns a string property. If the device index is not valid or the property is not a string type this function will * return 0. Otherwise it returns the length of the number of bytes necessary to hold this string including the trailing * null. Strings will always fit in buffers of k_unMaxPropertyStringSize characters. */ -inline uint32_t CVRPropertyHelpers::GetStringProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError ) +inline uint32_t CVRPropertyHelpers::GetStringProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize, ETrackedPropertyError *pError) { PropertyTypeTag_t unTag; ETrackedPropertyError error; - uint32_t unRequiredSize = GetProperty( ulContainerHandle, prop, pchValue, unBufferSize, &unTag, &error ); - if ( unTag != k_unStringPropertyTag && error == TrackedProp_Success ) + uint32_t unRequiredSize = GetProperty(ulContainerHandle, prop, pchValue, unBufferSize, &unTag, &error); + if (unTag != k_unStringPropertyTag && error == TrackedProp_Success) { error = TrackedProp_WrongDataType; } - if ( pError ) + if (pError) { *pError = error; } - if ( error != TrackedProp_Success ) + if (error != TrackedProp_Success) { - if ( pchValue && unBufferSize ) + if (pchValue && unBufferSize) { *pchValue = '\0'; } @@ -2088,30 +2024,29 @@ inline uint32_t CVRPropertyHelpers::GetStringProperty( PropertyContainerHandle_t return unRequiredSize; } - /** Returns a string property as a std::string. If the device index is not valid or the property is not a string type this function will * return an empty string. */ -inline std::string CVRPropertyHelpers::GetStringProperty( vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError ) +inline std::string CVRPropertyHelpers::GetStringProperty(vr::PropertyContainerHandle_t ulContainer, vr::ETrackedDeviceProperty prop, vr::ETrackedPropertyError *peError) { char buf[1024]; vr::ETrackedPropertyError err; - uint32_t unRequiredBufferLen = GetStringProperty( ulContainer, prop, buf, sizeof(buf), &err ); + uint32_t unRequiredBufferLen = GetStringProperty(ulContainer, prop, buf, sizeof(buf), &err); std::string sResult; - if ( err == TrackedProp_Success ) + if (err == TrackedProp_Success) { sResult = buf; } - else if ( err == TrackedProp_BufferTooSmall ) + else if (err == TrackedProp_BufferTooSmall) { char *pchBuffer = new char[unRequiredBufferLen]; - unRequiredBufferLen = GetStringProperty( ulContainer, prop, pchBuffer, unRequiredBufferLen, &err ); + unRequiredBufferLen = GetStringProperty(ulContainer, prop, pchBuffer, unRequiredBufferLen, &err); sResult = pchBuffer; delete[] pchBuffer; } - if ( peError ) + if (peError) { *peError = err; } @@ -2119,39 +2054,37 @@ inline std::string CVRPropertyHelpers::GetStringProperty( vr::PropertyContainerH return sResult; } - /** Sets a string property. The new value will be returned on any subsequent call to get this property in any process. */ -inline ETrackedPropertyError CVRPropertyHelpers::SetStringProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, const char *pchNewValue ) +inline ETrackedPropertyError CVRPropertyHelpers::SetStringProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, const char *pchNewValue) { - if ( !pchNewValue ) + if (!pchNewValue) return TrackedProp_InvalidOperation; // this is strlen without the dependency on string.h const char *pchCurr = pchNewValue; - while ( *pchCurr ) + while (*pchCurr) { pchCurr++; } - return SetProperty( ulContainerHandle, prop, (void *)pchNewValue, (uint32_t)(pchCurr - pchNewValue) + 1, k_unStringPropertyTag ); + return SetProperty(ulContainerHandle, prop, (void *)pchNewValue, (uint32_t)(pchCurr - pchNewValue) + 1, k_unStringPropertyTag); } - -template -inline T CVRPropertyHelpers::GetPropertyHelper( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError, T bDefault, PropertyTypeTag_t unTypeTag ) +template +inline T CVRPropertyHelpers::GetPropertyHelper(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError, T bDefault, PropertyTypeTag_t unTypeTag) { T bValue; ETrackedPropertyError eError; PropertyTypeTag_t unReadTag; - GetProperty( ulContainerHandle, prop, &bValue, sizeof( bValue ), &unReadTag, &eError ); - if ( unReadTag != unTypeTag && eError == TrackedProp_Success ) + GetProperty(ulContainerHandle, prop, &bValue, sizeof(bValue), &unReadTag, &eError); + if (unReadTag != unTypeTag && eError == TrackedProp_Success) { eError = TrackedProp_WrongDataType; }; - if ( pError ) + if (pError) *pError = eError; - if ( eError != TrackedProp_Success ) + if (eError != TrackedProp_Success) { return bDefault; } @@ -2161,96 +2094,89 @@ inline T CVRPropertyHelpers::GetPropertyHelper( PropertyContainerHandle_t ulCont } } - -inline bool CVRPropertyHelpers::GetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) +inline bool CVRPropertyHelpers::GetBoolProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError) { - return GetPropertyHelper( ulContainerHandle, prop, pError, false, k_unBoolPropertyTag ); + return GetPropertyHelper(ulContainerHandle, prop, pError, false, k_unBoolPropertyTag); } - -inline float CVRPropertyHelpers::GetFloatProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) +inline float CVRPropertyHelpers::GetFloatProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError) { - return GetPropertyHelper( ulContainerHandle, prop, pError, 0.f, k_unFloatPropertyTag ); + return GetPropertyHelper(ulContainerHandle, prop, pError, 0.f, k_unFloatPropertyTag); } -inline int32_t CVRPropertyHelpers::GetInt32Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) +inline int32_t CVRPropertyHelpers::GetInt32Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError) { - return GetPropertyHelper( ulContainerHandle, prop, pError, 0, k_unInt32PropertyTag ); + return GetPropertyHelper(ulContainerHandle, prop, pError, 0, k_unInt32PropertyTag); } -inline uint64_t CVRPropertyHelpers::GetUint64Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError ) +inline uint64_t CVRPropertyHelpers::GetUint64Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError *pError) { - return GetPropertyHelper( ulContainerHandle, prop, pError, 0, k_unUint64PropertyTag ); + return GetPropertyHelper(ulContainerHandle, prop, pError, 0, k_unUint64PropertyTag); } -inline ETrackedPropertyError CVRPropertyHelpers::SetBoolProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, bool bNewValue ) +inline ETrackedPropertyError CVRPropertyHelpers::SetBoolProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, bool bNewValue) { - return SetProperty( ulContainerHandle, prop, &bNewValue, sizeof( bNewValue ), k_unBoolPropertyTag ); + return SetProperty(ulContainerHandle, prop, &bNewValue, sizeof(bNewValue), k_unBoolPropertyTag); } -inline ETrackedPropertyError CVRPropertyHelpers::SetFloatProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, float fNewValue ) +inline ETrackedPropertyError CVRPropertyHelpers::SetFloatProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, float fNewValue) { - return SetProperty( ulContainerHandle, prop, &fNewValue, sizeof( fNewValue ), k_unFloatPropertyTag ); + return SetProperty(ulContainerHandle, prop, &fNewValue, sizeof(fNewValue), k_unFloatPropertyTag); } -inline ETrackedPropertyError CVRPropertyHelpers::SetInt32Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, int32_t nNewValue ) +inline ETrackedPropertyError CVRPropertyHelpers::SetInt32Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, int32_t nNewValue) { - return SetProperty( ulContainerHandle, prop, &nNewValue, sizeof( nNewValue ), k_unInt32PropertyTag ); + return SetProperty(ulContainerHandle, prop, &nNewValue, sizeof(nNewValue), k_unInt32PropertyTag); } -inline ETrackedPropertyError CVRPropertyHelpers::SetUint64Property( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, uint64_t ulNewValue ) +inline ETrackedPropertyError CVRPropertyHelpers::SetUint64Property(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, uint64_t ulNewValue) { - return SetProperty( ulContainerHandle, prop, &ulNewValue, sizeof( ulNewValue ), k_unUint64PropertyTag ); + return SetProperty(ulContainerHandle, prop, &ulNewValue, sizeof(ulNewValue), k_unUint64PropertyTag); } /** Sets the error return value for a property. This value will be returned on all subsequent requests to get the property */ -inline ETrackedPropertyError CVRPropertyHelpers::SetPropertyError( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError eError ) +inline ETrackedPropertyError CVRPropertyHelpers::SetPropertyError(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop, ETrackedPropertyError eError) { PropertyWrite_t batch; batch.writeType = PropertyWrite_SetError; batch.prop = prop; batch.eSetError = eError; - m_pProperties->WritePropertyBatch( ulContainerHandle, &batch, 1 ); + m_pProperties->WritePropertyBatch(ulContainerHandle, &batch, 1); return batch.eError; } /** Clears any value or error set for the property. */ -inline ETrackedPropertyError CVRPropertyHelpers::EraseProperty( PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop ) +inline ETrackedPropertyError CVRPropertyHelpers::EraseProperty(PropertyContainerHandle_t ulContainerHandle, ETrackedDeviceProperty prop) { PropertyWrite_t batch; batch.writeType = PropertyWrite_Erase; batch.prop = prop; - m_pProperties->WritePropertyBatch( ulContainerHandle, &batch, 1 ); + m_pProperties->WritePropertyBatch(ulContainerHandle, &batch, 1); return batch.eError; - -} - } +} // namespace vr // ivrdriverlog.h namespace vr { - class IVRDriverLog { public: /** Writes a log message to the log file prefixed with the driver name */ - virtual void Log( const char *pchLogMessage ) = 0; + virtual void Log(const char *pchLogMessage) = 0; }; - static const char *IVRDriverLog_Version = "IVRDriverLog_001"; -} +} // namespace vr // ivrserverdriverhost.h namespace vr { - class ITrackedDeviceServerDriver; struct TrackedDeviceDriverInfo_t; struct DriverPose_t; @@ -2265,74 +2191,73 @@ public: /** Notifies the server that a tracked device has been added. If this function returns true * the server will call Activate on the device. If it returns false some kind of error * has occurred and the device will not be activated. */ - virtual bool TrackedDeviceAdded( const char *pchDeviceSerialNumber, ETrackedDeviceClass eDeviceClass, ITrackedDeviceServerDriver *pDriver ) = 0; + virtual bool TrackedDeviceAdded(const char *pchDeviceSerialNumber, ETrackedDeviceClass eDeviceClass, ITrackedDeviceServerDriver *pDriver) = 0; /** Notifies the server that a tracked device's pose has been updated */ - virtual void TrackedDevicePoseUpdated( uint32_t unWhichDevice, const DriverPose_t & newPose, uint32_t unPoseStructSize ) = 0; + virtual void TrackedDevicePoseUpdated(uint32_t unWhichDevice, const DriverPose_t &newPose, uint32_t unPoseStructSize) = 0; /** Notifies the server that vsync has occurred on the the display attached to the device. This is * only permitted on devices of the HMD class. */ - virtual void VsyncEvent( double vsyncTimeOffsetSeconds ) = 0; + virtual void VsyncEvent(double vsyncTimeOffsetSeconds) = 0; /** notifies the server that the button was pressed */ - virtual void TrackedDeviceButtonPressed( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; + virtual void TrackedDeviceButtonPressed(uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset) = 0; /** notifies the server that the button was unpressed */ - virtual void TrackedDeviceButtonUnpressed( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; + virtual void TrackedDeviceButtonUnpressed(uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset) = 0; /** notifies the server that the button was pressed */ - virtual void TrackedDeviceButtonTouched( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; + virtual void TrackedDeviceButtonTouched(uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset) = 0; /** notifies the server that the button was unpressed */ - virtual void TrackedDeviceButtonUntouched( uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset ) = 0; + virtual void TrackedDeviceButtonUntouched(uint32_t unWhichDevice, EVRButtonId eButtonId, double eventTimeOffset) = 0; /** notifies the server than a controller axis changed */ - virtual void TrackedDeviceAxisUpdated( uint32_t unWhichDevice, uint32_t unWhichAxis, const VRControllerAxis_t & axisState ) = 0; + virtual void TrackedDeviceAxisUpdated(uint32_t unWhichDevice, uint32_t unWhichAxis, const VRControllerAxis_t &axisState) = 0; /** Notifies the server that the proximity sensor on the specified device */ - virtual void ProximitySensorState( uint32_t unWhichDevice, bool bProximitySensorTriggered ) = 0; + virtual void ProximitySensorState(uint32_t unWhichDevice, bool bProximitySensorTriggered) = 0; /** Sends a vendor specific event (VREvent_VendorSpecific_Reserved_Start..VREvent_VendorSpecific_Reserved_End */ - virtual void VendorSpecificEvent( uint32_t unWhichDevice, vr::EVREventType eventType, const VREvent_Data_t & eventData, double eventTimeOffset ) = 0; + virtual void VendorSpecificEvent(uint32_t unWhichDevice, vr::EVREventType eventType, const VREvent_Data_t &eventData, double eventTimeOffset) = 0; /** Returns true if SteamVR is exiting */ virtual bool IsExiting() = 0; /** Returns true and fills the event with the next event on the queue if there is one. If there are no events * this method returns false. uncbVREvent should be the size in bytes of the VREvent_t struct */ - virtual bool PollNextEvent( VREvent_t *pEvent, uint32_t uncbVREvent ) = 0; + virtual bool PollNextEvent(VREvent_t *pEvent, uint32_t uncbVREvent) = 0; /** Provides access to device poses for drivers. Poses are in their "raw" tracking space which is uniquely * defined by each driver providing poses for its devices. It is up to clients of this function to correlate * poses across different drivers. Poses are indexed by their device id, and their associated driver and * other properties can be looked up via IVRProperties. */ - virtual void GetRawTrackedDevicePoses( float fPredictedSecondsFromNow, TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount ) = 0; + virtual void GetRawTrackedDevicePoses(float fPredictedSecondsFromNow, TrackedDevicePose_t *pTrackedDevicePoseArray, uint32_t unTrackedDevicePoseArrayCount) = 0; /** Notifies the server that a tracked device's display component transforms have been updated. */ - virtual void TrackedDeviceDisplayTransformUpdated( uint32_t unWhichDevice, HmdMatrix34_t eyeToHeadLeft, HmdMatrix34_t eyeToHeadRight ) = 0; + virtual void TrackedDeviceDisplayTransformUpdated(uint32_t unWhichDevice, HmdMatrix34_t eyeToHeadLeft, HmdMatrix34_t eyeToHeadRight) = 0; }; static const char *IVRServerDriverHost_Version = "IVRServerDriverHost_004"; -} +} // namespace vr // ivrhiddenarea.h namespace vr { - class CVRHiddenAreaHelpers { public: - CVRHiddenAreaHelpers( IVRProperties *pProperties ) : m_pProperties( pProperties ) {} + CVRHiddenAreaHelpers(IVRProperties *pProperties) : m_pProperties(pProperties) {} /** Stores a hidden area mesh in a property */ - ETrackedPropertyError SetHiddenArea( EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount ); + ETrackedPropertyError SetHiddenArea(EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount); /** retrieves a hidden area mesh from a property. Returns the vert count read out of the property. */ - uint32_t GetHiddenArea( EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount, ETrackedPropertyError *peError ); + uint32_t GetHiddenArea(EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount, ETrackedPropertyError *peError); private: - ETrackedDeviceProperty GetPropertyEnum( EVREye eEye, EHiddenAreaMeshType type ) + ETrackedDeviceProperty GetPropertyEnum(EVREye eEye, EHiddenAreaMeshType type) { return (ETrackedDeviceProperty)(Prop_DisplayHiddenArea_Binary_Start + ((int)type * 2) + (int)eEye); } @@ -2340,41 +2265,38 @@ private: IVRProperties *m_pProperties; }; - -inline ETrackedPropertyError CVRHiddenAreaHelpers::SetHiddenArea( EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount ) +inline ETrackedPropertyError CVRHiddenAreaHelpers::SetHiddenArea(EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount) { - ETrackedDeviceProperty prop = GetPropertyEnum( eEye, type ); - CVRPropertyHelpers propHelpers( m_pProperties ); - return propHelpers.SetProperty( propHelpers.TrackedDeviceToPropertyContainer( k_unTrackedDeviceIndex_Hmd ), prop, pVerts, sizeof( HmdVector2_t ) * unVertCount, k_unHiddenAreaPropertyTag ); + ETrackedDeviceProperty prop = GetPropertyEnum(eEye, type); + CVRPropertyHelpers propHelpers(m_pProperties); + return propHelpers.SetProperty(propHelpers.TrackedDeviceToPropertyContainer(k_unTrackedDeviceIndex_Hmd), prop, pVerts, sizeof(HmdVector2_t) * unVertCount, k_unHiddenAreaPropertyTag); } - -inline uint32_t CVRHiddenAreaHelpers::GetHiddenArea( EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount, ETrackedPropertyError *peError ) +inline uint32_t CVRHiddenAreaHelpers::GetHiddenArea(EVREye eEye, EHiddenAreaMeshType type, HmdVector2_t *pVerts, uint32_t unVertCount, ETrackedPropertyError *peError) { - ETrackedDeviceProperty prop = GetPropertyEnum( eEye, type ); - CVRPropertyHelpers propHelpers( m_pProperties ); + ETrackedDeviceProperty prop = GetPropertyEnum(eEye, type); + CVRPropertyHelpers propHelpers(m_pProperties); ETrackedPropertyError propError; PropertyTypeTag_t unTag; - uint32_t unBytesNeeded = propHelpers.GetProperty( propHelpers.TrackedDeviceToPropertyContainer( k_unTrackedDeviceIndex_Hmd ), prop, pVerts, sizeof( HmdVector2_t )*unVertCount, &unTag, &propError ); - if ( propError == TrackedProp_Success && unTag != k_unHiddenAreaPropertyTag ) + uint32_t unBytesNeeded = propHelpers.GetProperty(propHelpers.TrackedDeviceToPropertyContainer(k_unTrackedDeviceIndex_Hmd), prop, pVerts, sizeof(HmdVector2_t) * unVertCount, &unTag, &propError); + if (propError == TrackedProp_Success && unTag != k_unHiddenAreaPropertyTag) { propError = TrackedProp_WrongDataType; unBytesNeeded = 0; } - if ( peError ) + if (peError) { *peError = propError; } - return unBytesNeeded / sizeof( HmdVector2_t ); + return unBytesNeeded / sizeof(HmdVector2_t); } -} +} // namespace vr // ivrwatchdoghost.h namespace vr { - /** This interface is provided by vrclient to allow the driver to make everything wake up */ class IVRWatchdogHost { @@ -2386,87 +2308,75 @@ public: static const char *IVRWatchdogHost_Version = "IVRWatchdogHost_001"; -}; - - +}; // namespace vr // ivrvirtualdisplay.h namespace vr { - // ---------------------------------------------------------------------------------------------- - // Purpose: This component is used for drivers that implement a virtual display (e.g. wireless). - // ---------------------------------------------------------------------------------------------- - class IVRVirtualDisplay - { - public: +// ---------------------------------------------------------------------------------------------- +// Purpose: This component is used for drivers that implement a virtual display (e.g. wireless). +// ---------------------------------------------------------------------------------------------- +class IVRVirtualDisplay +{ +public: + /** Submits final backbuffer for display. */ + virtual void Present(vr::SharedTextureHandle_t backbufferTextureHandle) = 0; - /** Submits final backbuffer for display. */ - virtual void Present( vr::SharedTextureHandle_t backbufferTextureHandle ) = 0; + /** Block until the last presented buffer start scanning out. */ + virtual void WaitForPresent() = 0; - /** Block until the last presented buffer start scanning out. */ - virtual void WaitForPresent() = 0; + /** Provides timing data for synchronizing with display. */ + virtual bool GetTimeSinceLastVsync(float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter) = 0; +}; - /** Provides timing data for synchronizing with display. */ - virtual bool GetTimeSinceLastVsync( float *pfSecondsSinceLastVsync, uint64_t *pulFrameCounter ) = 0; - }; - - static const char *IVRVirtualDisplay_Version = "IVRVirtualDisplay_001"; - - /** Returns the current IVRVirtualDisplay pointer or NULL the interface could not be found. */ - VR_INTERFACE vr::IVRVirtualDisplay *VR_CALLTYPE VRVirtualDisplay(); -} +static const char *IVRVirtualDisplay_Version = "IVRVirtualDisplay_001"; +/** Returns the current IVRVirtualDisplay pointer or NULL the interface could not be found. */ +VR_INTERFACE vr::IVRVirtualDisplay *VR_CALLTYPE VRVirtualDisplay(); +} // namespace vr // ivrresources.h namespace vr { - class IVRResources { public: - // ------------------------------------ // Shared Resource Methods // ------------------------------------ /** Loads the specified resource into the provided buffer if large enough. * Returns the size in bytes of the buffer required to hold the specified resource. */ - virtual uint32_t LoadSharedResource( const char *pchResourceName, char *pchBuffer, uint32_t unBufferLen ) = 0; + virtual uint32_t LoadSharedResource(const char *pchResourceName, char *pchBuffer, uint32_t unBufferLen) = 0; /** Provides the full path to the specified resource. Resource names can include named directories for * drivers and other things, and this resolves all of those and returns the actual physical path. * pchResourceTypeDirectory is the subdirectory of resources to look in. */ - virtual uint32_t GetResourceFullPath( const char *pchResourceName, const char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen ) = 0; + virtual uint32_t GetResourceFullPath(const char *pchResourceName, const char *pchResourceTypeDirectory, char *pchPathBuffer, uint32_t unBufferLen) = 0; }; -static const char * const IVRResources_Version = "IVRResources_001"; +static const char *const IVRResources_Version = "IVRResources_001"; - -} +} // namespace vr // ivrdrivermanager.h namespace vr { - class IVRDriverManager { public: virtual uint32_t GetDriverCount() const = 0; /** Returns the length of the number of bytes necessary to hold this string including the trailing null. */ - virtual uint32_t GetDriverName( vr::DriverId_t nDriver, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize ) = 0; + virtual uint32_t GetDriverName(vr::DriverId_t nDriver, VR_OUT_STRING() char *pchValue, uint32_t unBufferSize) = 0; }; -static const char * const IVRDriverManager_Version = "IVRDriverManager_001"; - -} // namespace vr - - - +static const char *const IVRDriverManager_Version = "IVRDriverManager_001"; +} // namespace vr namespace vr { - static const char * const k_InterfaceVersions[] = +static const char *const k_InterfaceVersions[] = { IVRSettings_Version, ITrackedDeviceServerDriver_Version, @@ -2479,217 +2389,207 @@ namespace vr IVRVirtualDisplay_Version, IVRDriverManager_Version, IVRResources_Version, - nullptr - }; + nullptr}; - inline IVRDriverContext *&VRDriverContext() - { - static IVRDriverContext *pHost; - return pHost; - } - - class COpenVRDriverContext - { - public: - COpenVRDriverContext() : m_propertyHelpers(nullptr), m_hiddenAreaHelpers(nullptr) { Clear(); } - void Clear(); - - EVRInitError InitServer(); - EVRInitError InitWatchdog(); - - IVRSettings *VRSettings() - { - if ( m_pVRSettings == nullptr ) - { - EVRInitError eError; - m_pVRSettings = (IVRSettings *)VRDriverContext()->GetGenericInterface( IVRSettings_Version, &eError ); - } - return m_pVRSettings; - } - - IVRProperties *VRPropertiesRaw() - { - if ( m_pVRProperties == nullptr ) - { - EVRInitError eError; - m_pVRProperties = (IVRProperties *)VRDriverContext()->GetGenericInterface( IVRProperties_Version, &eError ); - m_propertyHelpers = CVRPropertyHelpers( m_pVRProperties ); - m_hiddenAreaHelpers = CVRHiddenAreaHelpers( m_pVRProperties ); - } - return m_pVRProperties; - } - - CVRPropertyHelpers *VRProperties() - { - VRPropertiesRaw(); - return &m_propertyHelpers; - } - - CVRHiddenAreaHelpers *VRHiddenArea() - { - VRPropertiesRaw(); - return &m_hiddenAreaHelpers; - } - - IVRServerDriverHost *VRServerDriverHost() - { - if ( m_pVRServerDriverHost == nullptr ) - { - EVRInitError eError; - m_pVRServerDriverHost = (IVRServerDriverHost *)VRDriverContext()->GetGenericInterface( IVRServerDriverHost_Version, &eError ); - } - return m_pVRServerDriverHost; - } - - IVRWatchdogHost *VRWatchdogHost() - { - if ( m_pVRWatchdogHost == nullptr ) - { - EVRInitError eError; - m_pVRWatchdogHost = (IVRWatchdogHost *)VRDriverContext()->GetGenericInterface( IVRWatchdogHost_Version, &eError ); - } - return m_pVRWatchdogHost; - } - - IVRDriverLog *VRDriverLog() - { - if ( m_pVRDriverLog == nullptr ) - { - EVRInitError eError; - m_pVRDriverLog = (IVRDriverLog *)VRDriverContext()->GetGenericInterface( IVRDriverLog_Version, &eError ); - } - return m_pVRDriverLog; - } - - DriverHandle_t VR_CALLTYPE VRDriverHandle() - { - return VRDriverContext()->GetDriverHandle(); - } - - IVRDriverManager *VRDriverManager() - { - if ( !m_pVRDriverManager ) - { - EVRInitError eError; - m_pVRDriverManager = (IVRDriverManager *)VRDriverContext()->GetGenericInterface( IVRDriverManager_Version, &eError ); - } - return m_pVRDriverManager; - } - - IVRResources *VRResources() - { - if ( !m_pVRResources ) - { - EVRInitError eError; - m_pVRResources = (IVRResources *)VRDriverContext()->GetGenericInterface( IVRResources_Version, &eError ); - } - return m_pVRResources; - } - - private: - CVRPropertyHelpers m_propertyHelpers; - CVRHiddenAreaHelpers m_hiddenAreaHelpers; - - IVRSettings *m_pVRSettings; - IVRProperties *m_pVRProperties; - IVRServerDriverHost *m_pVRServerDriverHost; - IVRWatchdogHost *m_pVRWatchdogHost; - IVRDriverLog *m_pVRDriverLog; - IVRDriverManager *m_pVRDriverManager; - IVRResources *m_pVRResources; - }; - - inline COpenVRDriverContext &OpenVRInternal_ModuleServerDriverContext() - { - static void *ctx[sizeof( COpenVRDriverContext ) / sizeof( void * )]; - return *(COpenVRDriverContext *)ctx; // bypass zero-init constructor - } - - inline IVRSettings *VR_CALLTYPE VRSettings() { return OpenVRInternal_ModuleServerDriverContext().VRSettings(); } - inline IVRProperties *VR_CALLTYPE VRPropertiesRaw() { return OpenVRInternal_ModuleServerDriverContext().VRPropertiesRaw(); } - inline CVRPropertyHelpers *VR_CALLTYPE VRProperties() { return OpenVRInternal_ModuleServerDriverContext().VRProperties(); } - inline CVRHiddenAreaHelpers *VR_CALLTYPE VRHiddenArea() { return OpenVRInternal_ModuleServerDriverContext().VRHiddenArea(); } - inline IVRDriverLog *VR_CALLTYPE VRDriverLog() { return OpenVRInternal_ModuleServerDriverContext().VRDriverLog(); } - inline IVRServerDriverHost *VR_CALLTYPE VRServerDriverHost() { return OpenVRInternal_ModuleServerDriverContext().VRServerDriverHost(); } - inline IVRWatchdogHost *VR_CALLTYPE VRWatchdogHost() { return OpenVRInternal_ModuleServerDriverContext().VRWatchdogHost(); } - inline DriverHandle_t VR_CALLTYPE VRDriverHandle() { return OpenVRInternal_ModuleServerDriverContext().VRDriverHandle(); } - inline IVRDriverManager *VR_CALLTYPE VRDriverManager() { return OpenVRInternal_ModuleServerDriverContext().VRDriverManager(); } - inline IVRResources *VR_CALLTYPE VRResources() { return OpenVRInternal_ModuleServerDriverContext().VRResources(); } - - inline void COpenVRDriverContext::Clear() - { - m_pVRSettings = nullptr; - m_pVRProperties = nullptr; - m_pVRServerDriverHost = nullptr; - m_pVRDriverLog = nullptr; - m_pVRWatchdogHost = nullptr; - m_pVRDriverManager = nullptr; - m_pVRResources = nullptr; - } - - inline EVRInitError COpenVRDriverContext::InitServer() - { - Clear(); - if ( !VRServerDriverHost() - || !VRSettings() - || !VRProperties() - || !VRDriverLog() - || !VRDriverManager() - || !VRResources() ) - return VRInitError_Init_InterfaceNotFound; - return VRInitError_None; - } - - inline EVRInitError COpenVRDriverContext::InitWatchdog() - { - Clear(); - if ( !VRWatchdogHost() - || !VRSettings() - || !VRDriverLog() ) - return VRInitError_Init_InterfaceNotFound; - return VRInitError_None; - } - - inline EVRInitError InitServerDriverContext( IVRDriverContext *pContext ) - { - VRDriverContext() = pContext; - return OpenVRInternal_ModuleServerDriverContext().InitServer(); - } - - inline EVRInitError InitWatchdogDriverContext( IVRDriverContext *pContext ) - { - VRDriverContext() = pContext; - return OpenVRInternal_ModuleServerDriverContext().InitWatchdog(); - } - - inline void CleanupDriverContext() - { - VRDriverContext() = nullptr; - OpenVRInternal_ModuleServerDriverContext().Clear(); - } - - #define VR_INIT_SERVER_DRIVER_CONTEXT( pContext ) \ - { \ - vr::EVRInitError eError = vr::InitServerDriverContext( pContext ); \ - if( eError != vr::VRInitError_None ) \ - return eError; \ - } - - #define VR_CLEANUP_SERVER_DRIVER_CONTEXT() \ - vr::CleanupDriverContext(); - - #define VR_INIT_WATCHDOG_DRIVER_CONTEXT( pContext ) \ - { \ - vr::EVRInitError eError = vr::InitWatchdogDriverContext( pContext ); \ - if( eError != vr::VRInitError_None ) \ - return eError; \ - } - - #define VR_CLEANUP_WATCHDOG_DRIVER_CONTEXT() \ - vr::CleanupDriverContext(); +inline IVRDriverContext *&VRDriverContext() +{ + static IVRDriverContext *pHost; + return pHost; } + +class COpenVRDriverContext +{ +public: + COpenVRDriverContext() : m_propertyHelpers(nullptr), m_hiddenAreaHelpers(nullptr) { Clear(); } + void Clear(); + + EVRInitError InitServer(); + EVRInitError InitWatchdog(); + + IVRSettings *VRSettings() + { + if (m_pVRSettings == nullptr) + { + EVRInitError eError; + m_pVRSettings = (IVRSettings *)VRDriverContext()->GetGenericInterface(IVRSettings_Version, &eError); + } + return m_pVRSettings; + } + + IVRProperties *VRPropertiesRaw() + { + if (m_pVRProperties == nullptr) + { + EVRInitError eError; + m_pVRProperties = (IVRProperties *)VRDriverContext()->GetGenericInterface(IVRProperties_Version, &eError); + m_propertyHelpers = CVRPropertyHelpers(m_pVRProperties); + m_hiddenAreaHelpers = CVRHiddenAreaHelpers(m_pVRProperties); + } + return m_pVRProperties; + } + + CVRPropertyHelpers *VRProperties() + { + VRPropertiesRaw(); + return &m_propertyHelpers; + } + + CVRHiddenAreaHelpers *VRHiddenArea() + { + VRPropertiesRaw(); + return &m_hiddenAreaHelpers; + } + + IVRServerDriverHost *VRServerDriverHost() + { + if (m_pVRServerDriverHost == nullptr) + { + EVRInitError eError; + m_pVRServerDriverHost = (IVRServerDriverHost *)VRDriverContext()->GetGenericInterface(IVRServerDriverHost_Version, &eError); + } + return m_pVRServerDriverHost; + } + + IVRWatchdogHost *VRWatchdogHost() + { + if (m_pVRWatchdogHost == nullptr) + { + EVRInitError eError; + m_pVRWatchdogHost = (IVRWatchdogHost *)VRDriverContext()->GetGenericInterface(IVRWatchdogHost_Version, &eError); + } + return m_pVRWatchdogHost; + } + + IVRDriverLog *VRDriverLog() + { + if (m_pVRDriverLog == nullptr) + { + EVRInitError eError; + m_pVRDriverLog = (IVRDriverLog *)VRDriverContext()->GetGenericInterface(IVRDriverLog_Version, &eError); + } + return m_pVRDriverLog; + } + + DriverHandle_t VR_CALLTYPE VRDriverHandle() + { + return VRDriverContext()->GetDriverHandle(); + } + + IVRDriverManager *VRDriverManager() + { + if (!m_pVRDriverManager) + { + EVRInitError eError; + m_pVRDriverManager = (IVRDriverManager *)VRDriverContext()->GetGenericInterface(IVRDriverManager_Version, &eError); + } + return m_pVRDriverManager; + } + + IVRResources *VRResources() + { + if (!m_pVRResources) + { + EVRInitError eError; + m_pVRResources = (IVRResources *)VRDriverContext()->GetGenericInterface(IVRResources_Version, &eError); + } + return m_pVRResources; + } + +private: + CVRPropertyHelpers m_propertyHelpers; + CVRHiddenAreaHelpers m_hiddenAreaHelpers; + + IVRSettings *m_pVRSettings; + IVRProperties *m_pVRProperties; + IVRServerDriverHost *m_pVRServerDriverHost; + IVRWatchdogHost *m_pVRWatchdogHost; + IVRDriverLog *m_pVRDriverLog; + IVRDriverManager *m_pVRDriverManager; + IVRResources *m_pVRResources; +}; + +inline COpenVRDriverContext &OpenVRInternal_ModuleServerDriverContext() +{ + static void *ctx[sizeof(COpenVRDriverContext) / sizeof(void *)]; + return *(COpenVRDriverContext *)ctx; // bypass zero-init constructor +} + +inline IVRSettings *VR_CALLTYPE VRSettings() { return OpenVRInternal_ModuleServerDriverContext().VRSettings(); } +inline IVRProperties *VR_CALLTYPE VRPropertiesRaw() { return OpenVRInternal_ModuleServerDriverContext().VRPropertiesRaw(); } +inline CVRPropertyHelpers *VR_CALLTYPE VRProperties() { return OpenVRInternal_ModuleServerDriverContext().VRProperties(); } +inline CVRHiddenAreaHelpers *VR_CALLTYPE VRHiddenArea() { return OpenVRInternal_ModuleServerDriverContext().VRHiddenArea(); } +inline IVRDriverLog *VR_CALLTYPE VRDriverLog() { return OpenVRInternal_ModuleServerDriverContext().VRDriverLog(); } +inline IVRServerDriverHost *VR_CALLTYPE VRServerDriverHost() { return OpenVRInternal_ModuleServerDriverContext().VRServerDriverHost(); } +inline IVRWatchdogHost *VR_CALLTYPE VRWatchdogHost() { return OpenVRInternal_ModuleServerDriverContext().VRWatchdogHost(); } +inline DriverHandle_t VR_CALLTYPE VRDriverHandle() { return OpenVRInternal_ModuleServerDriverContext().VRDriverHandle(); } +inline IVRDriverManager *VR_CALLTYPE VRDriverManager() { return OpenVRInternal_ModuleServerDriverContext().VRDriverManager(); } +inline IVRResources *VR_CALLTYPE VRResources() { return OpenVRInternal_ModuleServerDriverContext().VRResources(); } + +inline void COpenVRDriverContext::Clear() +{ + m_pVRSettings = nullptr; + m_pVRProperties = nullptr; + m_pVRServerDriverHost = nullptr; + m_pVRDriverLog = nullptr; + m_pVRWatchdogHost = nullptr; + m_pVRDriverManager = nullptr; + m_pVRResources = nullptr; +} + +inline EVRInitError COpenVRDriverContext::InitServer() +{ + Clear(); + if (!VRServerDriverHost() || !VRSettings() || !VRProperties() || !VRDriverLog() || !VRDriverManager() || !VRResources()) + return VRInitError_Init_InterfaceNotFound; + return VRInitError_None; +} + +inline EVRInitError COpenVRDriverContext::InitWatchdog() +{ + Clear(); + if (!VRWatchdogHost() || !VRSettings() || !VRDriverLog()) + return VRInitError_Init_InterfaceNotFound; + return VRInitError_None; +} + +inline EVRInitError InitServerDriverContext(IVRDriverContext *pContext) +{ + VRDriverContext() = pContext; + return OpenVRInternal_ModuleServerDriverContext().InitServer(); +} + +inline EVRInitError InitWatchdogDriverContext(IVRDriverContext *pContext) +{ + VRDriverContext() = pContext; + return OpenVRInternal_ModuleServerDriverContext().InitWatchdog(); +} + +inline void CleanupDriverContext() +{ + VRDriverContext() = nullptr; + OpenVRInternal_ModuleServerDriverContext().Clear(); +} + +#define VR_INIT_SERVER_DRIVER_CONTEXT(pContext) \ + { \ + vr::EVRInitError eError = vr::InitServerDriverContext(pContext); \ + if (eError != vr::VRInitError_None) \ + return eError; \ + } + +#define VR_CLEANUP_SERVER_DRIVER_CONTEXT() \ + vr::CleanupDriverContext(); + +#define VR_INIT_WATCHDOG_DRIVER_CONTEXT(pContext) \ + { \ + vr::EVRInitError eError = vr::InitWatchdogDriverContext(pContext); \ + if (eError != vr::VRInitError_None) \ + return eError; \ + } + +#define VR_CLEANUP_WATCHDOG_DRIVER_CONTEXT() \ + vr::CleanupDriverContext(); +} // namespace vr // End -#endif // _OPENVR_DRIVER_API - - +#endif // _OPENVR_DRIVER_API diff --git a/examples/ThirdPartyLibs/openvr/samples/shared/Matrices.cpp b/examples/ThirdPartyLibs/openvr/samples/shared/Matrices.cpp index 582b2854e..916d0e454 100644 --- a/examples/ThirdPartyLibs/openvr/samples/shared/Matrices.cpp +++ b/examples/ThirdPartyLibs/openvr/samples/shared/Matrices.cpp @@ -23,164 +23,146 @@ const float DEG2RAD = 3.141593f / 180; const float EPSILON = 0.00001f; - - /////////////////////////////////////////////////////////////////////////////// // transpose 2x2 matrix /////////////////////////////////////////////////////////////////////////////// Matrix2& Matrix2::transpose() { - std::swap(m[1], m[2]); - return *this; + std::swap(m[1], m[2]); + return *this; } - - /////////////////////////////////////////////////////////////////////////////// // return the determinant of 2x2 matrix /////////////////////////////////////////////////////////////////////////////// float Matrix2::getDeterminant() { - return m[0] * m[3] - m[1] * m[2]; + return m[0] * m[3] - m[1] * m[2]; } - - /////////////////////////////////////////////////////////////////////////////// // inverse of 2x2 matrix // If cannot find inverse, set identity matrix /////////////////////////////////////////////////////////////////////////////// Matrix2& Matrix2::invert() { - float determinant = getDeterminant(); - if(fabs(determinant) <= EPSILON) - { - return identity(); - } + float determinant = getDeterminant(); + if (fabs(determinant) <= EPSILON) + { + return identity(); + } - float tmp = m[0]; // copy the first element - float invDeterminant = 1.0f / determinant; - m[0] = invDeterminant * m[3]; - m[1] = -invDeterminant * m[1]; - m[2] = -invDeterminant * m[2]; - m[3] = invDeterminant * tmp; + float tmp = m[0]; // copy the first element + float invDeterminant = 1.0f / determinant; + m[0] = invDeterminant * m[3]; + m[1] = -invDeterminant * m[1]; + m[2] = -invDeterminant * m[2]; + m[3] = invDeterminant * tmp; - return *this; + return *this; } - - /////////////////////////////////////////////////////////////////////////////// // transpose 3x3 matrix /////////////////////////////////////////////////////////////////////////////// Matrix3& Matrix3::transpose() { - std::swap(m[1], m[3]); - std::swap(m[2], m[6]); - std::swap(m[5], m[7]); + std::swap(m[1], m[3]); + std::swap(m[2], m[6]); + std::swap(m[5], m[7]); - return *this; + return *this; } - - /////////////////////////////////////////////////////////////////////////////// // return determinant of 3x3 matrix /////////////////////////////////////////////////////////////////////////////// float Matrix3::getDeterminant() { - return m[0] * (m[4] * m[8] - m[5] * m[7]) - - m[1] * (m[3] * m[8] - m[5] * m[6]) + - m[2] * (m[3] * m[7] - m[4] * m[6]); + return m[0] * (m[4] * m[8] - m[5] * m[7]) - + m[1] * (m[3] * m[8] - m[5] * m[6]) + + m[2] * (m[3] * m[7] - m[4] * m[6]); } - - /////////////////////////////////////////////////////////////////////////////// // inverse 3x3 matrix // If cannot find inverse, set identity matrix /////////////////////////////////////////////////////////////////////////////// Matrix3& Matrix3::invert() { - float determinant, invDeterminant; - float tmp[9]; + float determinant, invDeterminant; + float tmp[9]; - tmp[0] = m[4] * m[8] - m[5] * m[7]; - tmp[1] = m[2] * m[7] - m[1] * m[8]; - tmp[2] = m[1] * m[5] - m[2] * m[4]; - tmp[3] = m[5] * m[6] - m[3] * m[8]; - tmp[4] = m[0] * m[8] - m[2] * m[6]; - tmp[5] = m[2] * m[3] - m[0] * m[5]; - tmp[6] = m[3] * m[7] - m[4] * m[6]; - tmp[7] = m[1] * m[6] - m[0] * m[7]; - tmp[8] = m[0] * m[4] - m[1] * m[3]; + tmp[0] = m[4] * m[8] - m[5] * m[7]; + tmp[1] = m[2] * m[7] - m[1] * m[8]; + tmp[2] = m[1] * m[5] - m[2] * m[4]; + tmp[3] = m[5] * m[6] - m[3] * m[8]; + tmp[4] = m[0] * m[8] - m[2] * m[6]; + tmp[5] = m[2] * m[3] - m[0] * m[5]; + tmp[6] = m[3] * m[7] - m[4] * m[6]; + tmp[7] = m[1] * m[6] - m[0] * m[7]; + tmp[8] = m[0] * m[4] - m[1] * m[3]; - // check determinant if it is 0 - determinant = m[0] * tmp[0] + m[1] * tmp[3] + m[2] * tmp[6]; - if(fabs(determinant) <= EPSILON) - { - return identity(); // cannot inverse, make it idenety matrix - } + // check determinant if it is 0 + determinant = m[0] * tmp[0] + m[1] * tmp[3] + m[2] * tmp[6]; + if (fabs(determinant) <= EPSILON) + { + return identity(); // cannot inverse, make it idenety matrix + } - // divide by the determinant - invDeterminant = 1.0f / determinant; - m[0] = invDeterminant * tmp[0]; - m[1] = invDeterminant * tmp[1]; - m[2] = invDeterminant * tmp[2]; - m[3] = invDeterminant * tmp[3]; - m[4] = invDeterminant * tmp[4]; - m[5] = invDeterminant * tmp[5]; - m[6] = invDeterminant * tmp[6]; - m[7] = invDeterminant * tmp[7]; - m[8] = invDeterminant * tmp[8]; + // divide by the determinant + invDeterminant = 1.0f / determinant; + m[0] = invDeterminant * tmp[0]; + m[1] = invDeterminant * tmp[1]; + m[2] = invDeterminant * tmp[2]; + m[3] = invDeterminant * tmp[3]; + m[4] = invDeterminant * tmp[4]; + m[5] = invDeterminant * tmp[5]; + m[6] = invDeterminant * tmp[6]; + m[7] = invDeterminant * tmp[7]; + m[8] = invDeterminant * tmp[8]; - return *this; + return *this; } - - /////////////////////////////////////////////////////////////////////////////// // transpose 4x4 matrix /////////////////////////////////////////////////////////////////////////////// Matrix4& Matrix4::transpose() { - std::swap(m[1], m[4]); - std::swap(m[2], m[8]); - std::swap(m[3], m[12]); - std::swap(m[6], m[9]); - std::swap(m[7], m[13]); - std::swap(m[11], m[14]); + std::swap(m[1], m[4]); + std::swap(m[2], m[8]); + std::swap(m[3], m[12]); + std::swap(m[6], m[9]); + std::swap(m[7], m[13]); + std::swap(m[11], m[14]); - return *this; + return *this; } - - /////////////////////////////////////////////////////////////////////////////// // inverse 4x4 matrix /////////////////////////////////////////////////////////////////////////////// Matrix4& Matrix4::invert() { - // If the 4th row is [0,0,0,1] then it is affine matrix and - // it has no projective transformation. - if(m[3] == 0 && m[7] == 0 && m[11] == 0 && m[15] == 1) - this->invertAffine(); - else - { - this->invertGeneral(); - /*@@ invertProjective() is not optimized (slower than generic one) + // If the 4th row is [0,0,0,1] then it is affine matrix and + // it has no projective transformation. + if (m[3] == 0 && m[7] == 0 && m[11] == 0 && m[15] == 1) + this->invertAffine(); + else + { + this->invertGeneral(); + /*@@ invertProjective() is not optimized (slower than generic one) if(fabs(m[0]*m[5] - m[1]*m[4]) > EPSILON) this->invertProjective(); // inverse using matrix partition else this->invertGeneral(); // generalized inverse */ - } + } - return *this; + return *this; } - - /////////////////////////////////////////////////////////////////////////////// // compute the inverse of 4x4 Euclidean transformation matrix // @@ -204,33 +186,37 @@ Matrix4& Matrix4::invert() /////////////////////////////////////////////////////////////////////////////// Matrix4& Matrix4::invertEuclidean() { - // transpose 3x3 rotation matrix part - // | R^T | 0 | - // | ----+-- | - // | 0 | 1 | - float tmp; - tmp = m[1]; m[1] = m[4]; m[4] = tmp; - tmp = m[2]; m[2] = m[8]; m[8] = tmp; - tmp = m[6]; m[6] = m[9]; m[9] = tmp; + // transpose 3x3 rotation matrix part + // | R^T | 0 | + // | ----+-- | + // | 0 | 1 | + float tmp; + tmp = m[1]; + m[1] = m[4]; + m[4] = tmp; + tmp = m[2]; + m[2] = m[8]; + m[8] = tmp; + tmp = m[6]; + m[6] = m[9]; + m[9] = tmp; - // compute translation part -R^T * T - // | 0 | -R^T x | - // | --+------- | - // | 0 | 0 | - float x = m[12]; - float y = m[13]; - float z = m[14]; - m[12] = -(m[0] * x + m[4] * y + m[8] * z); - m[13] = -(m[1] * x + m[5] * y + m[9] * z); - m[14] = -(m[2] * x + m[6] * y + m[10]* z); + // compute translation part -R^T * T + // | 0 | -R^T x | + // | --+------- | + // | 0 | 0 | + float x = m[12]; + float y = m[13]; + float z = m[14]; + m[12] = -(m[0] * x + m[4] * y + m[8] * z); + m[13] = -(m[1] * x + m[5] * y + m[9] * z); + m[14] = -(m[2] * x + m[6] * y + m[10] * z); - // last row should be unchanged (0,0,0,1) + // last row should be unchanged (0,0,0,1) - return *this; + return *this; } - - /////////////////////////////////////////////////////////////////////////////// // compute the inverse of a 4x4 affine transformation matrix // @@ -249,30 +235,34 @@ Matrix4& Matrix4::invertEuclidean() /////////////////////////////////////////////////////////////////////////////// Matrix4& Matrix4::invertAffine() { - // R^-1 - Matrix3 r(m[0],m[1],m[2], m[4],m[5],m[6], m[8],m[9],m[10]); - r.invert(); - m[0] = r[0]; m[1] = r[1]; m[2] = r[2]; - m[4] = r[3]; m[5] = r[4]; m[6] = r[5]; - m[8] = r[6]; m[9] = r[7]; m[10]= r[8]; + // R^-1 + Matrix3 r(m[0], m[1], m[2], m[4], m[5], m[6], m[8], m[9], m[10]); + r.invert(); + m[0] = r[0]; + m[1] = r[1]; + m[2] = r[2]; + m[4] = r[3]; + m[5] = r[4]; + m[6] = r[5]; + m[8] = r[6]; + m[9] = r[7]; + m[10] = r[8]; - // -R^-1 * T - float x = m[12]; - float y = m[13]; - float z = m[14]; - m[12] = -(r[0] * x + r[3] * y + r[6] * z); - m[13] = -(r[1] * x + r[4] * y + r[7] * z); - m[14] = -(r[2] * x + r[5] * y + r[8] * z); + // -R^-1 * T + float x = m[12]; + float y = m[13]; + float z = m[14]; + m[12] = -(r[0] * x + r[3] * y + r[6] * z); + m[13] = -(r[1] * x + r[4] * y + r[7] * z); + m[14] = -(r[2] * x + r[5] * y + r[8] * z); - // last row should be unchanged (0,0,0,1) - //m[3] = m[7] = m[11] = 0.0f; - //m[15] = 1.0f; + // last row should be unchanged (0,0,0,1) + //m[3] = m[7] = m[11] = 0.0f; + //m[15] = 1.0f; - return * this; + return *this; } - - /////////////////////////////////////////////////////////////////////////////// // inverse matrix using matrix partitioning (blockwise inverse) // It devides a 4x4 matrix into 4 of 2x2 matrices. It works in case of where @@ -293,54 +283,64 @@ Matrix4& Matrix4::invertAffine() /////////////////////////////////////////////////////////////////////////////// Matrix4& Matrix4::invertProjective() { - // partition - Matrix2 a(m[0], m[1], m[4], m[5]); - Matrix2 b(m[8], m[9], m[12], m[13]); - Matrix2 c(m[2], m[3], m[6], m[7]); - Matrix2 d(m[10], m[11], m[14], m[15]); + // partition + Matrix2 a(m[0], m[1], m[4], m[5]); + Matrix2 b(m[8], m[9], m[12], m[13]); + Matrix2 c(m[2], m[3], m[6], m[7]); + Matrix2 d(m[10], m[11], m[14], m[15]); - // pre-compute repeated parts - a.invert(); // A^-1 - Matrix2 ab = a * b; // A^-1 * B - Matrix2 ca = c * a; // C * A^-1 - Matrix2 cab = ca * b; // C * A^-1 * B - Matrix2 dcab = d - cab; // D - C * A^-1 * B + // pre-compute repeated parts + a.invert(); // A^-1 + Matrix2 ab = a * b; // A^-1 * B + Matrix2 ca = c * a; // C * A^-1 + Matrix2 cab = ca * b; // C * A^-1 * B + Matrix2 dcab = d - cab; // D - C * A^-1 * B - // check determinant if |D - C * A^-1 * B| = 0 - //NOTE: this function assumes det(A) is already checked. if |A|=0 then, - // cannot use this function. - float determinant = dcab[0] * dcab[3] - dcab[1] * dcab[2]; - if(fabs(determinant) <= EPSILON) - { - return identity(); - } + // check determinant if |D - C * A^-1 * B| = 0 + //NOTE: this function assumes det(A) is already checked. if |A|=0 then, + // cannot use this function. + float determinant = dcab[0] * dcab[3] - dcab[1] * dcab[2]; + if (fabs(determinant) <= EPSILON) + { + return identity(); + } - // compute D' and -D' - Matrix2 d1 = dcab; // (D - C * A^-1 * B) - d1.invert(); // (D - C * A^-1 * B)^-1 - Matrix2 d2 = -d1; // -(D - C * A^-1 * B)^-1 + // compute D' and -D' + Matrix2 d1 = dcab; // (D - C * A^-1 * B) + d1.invert(); // (D - C * A^-1 * B)^-1 + Matrix2 d2 = -d1; // -(D - C * A^-1 * B)^-1 - // compute C' - Matrix2 c1 = d2 * ca; // -D' * (C * A^-1) + // compute C' + Matrix2 c1 = d2 * ca; // -D' * (C * A^-1) - // compute B' - Matrix2 b1 = ab * d2; // (A^-1 * B) * -D' + // compute B' + Matrix2 b1 = ab * d2; // (A^-1 * B) * -D' - // compute A' - Matrix2 a1 = a - (ab * c1); // A^-1 - (A^-1 * B) * C' + // compute A' + Matrix2 a1 = a - (ab * c1); // A^-1 - (A^-1 * B) * C' - // assemble inverse matrix - m[0] = a1[0]; m[4] = a1[2]; /*|*/ m[8] = b1[0]; m[12]= b1[2]; - m[1] = a1[1]; m[5] = a1[3]; /*|*/ m[9] = b1[1]; m[13]= b1[3]; - /*-----------------------------+-----------------------------*/ - m[2] = c1[0]; m[6] = c1[2]; /*|*/ m[10]= d1[0]; m[14]= d1[2]; - m[3] = c1[1]; m[7] = c1[3]; /*|*/ m[11]= d1[1]; m[15]= d1[3]; + // assemble inverse matrix + m[0] = a1[0]; + m[4] = a1[2]; /*|*/ + m[8] = b1[0]; + m[12] = b1[2]; + m[1] = a1[1]; + m[5] = a1[3]; /*|*/ + m[9] = b1[1]; + m[13] = b1[3]; + /*-----------------------------+-----------------------------*/ + m[2] = c1[0]; + m[6] = c1[2]; /*|*/ + m[10] = d1[0]; + m[14] = d1[2]; + m[3] = c1[1]; + m[7] = c1[3]; /*|*/ + m[11] = d1[1]; + m[15] = d1[3]; - return *this; + return *this; } - - /////////////////////////////////////////////////////////////////////////////// // compute the inverse of a general 4x4 matrix using Cramer's Rule // If cannot find inverse, return indentity matrix @@ -348,234 +348,242 @@ Matrix4& Matrix4::invertProjective() /////////////////////////////////////////////////////////////////////////////// Matrix4& Matrix4::invertGeneral() { - // get cofactors of minor matrices - float cofactor0 = getCofactor(m[5],m[6],m[7], m[9],m[10],m[11], m[13],m[14],m[15]); - float cofactor1 = getCofactor(m[4],m[6],m[7], m[8],m[10],m[11], m[12],m[14],m[15]); - float cofactor2 = getCofactor(m[4],m[5],m[7], m[8],m[9], m[11], m[12],m[13],m[15]); - float cofactor3 = getCofactor(m[4],m[5],m[6], m[8],m[9], m[10], m[12],m[13],m[14]); + // get cofactors of minor matrices + float cofactor0 = getCofactor(m[5], m[6], m[7], m[9], m[10], m[11], m[13], m[14], m[15]); + float cofactor1 = getCofactor(m[4], m[6], m[7], m[8], m[10], m[11], m[12], m[14], m[15]); + float cofactor2 = getCofactor(m[4], m[5], m[7], m[8], m[9], m[11], m[12], m[13], m[15]); + float cofactor3 = getCofactor(m[4], m[5], m[6], m[8], m[9], m[10], m[12], m[13], m[14]); - // get determinant - float determinant = m[0] * cofactor0 - m[1] * cofactor1 + m[2] * cofactor2 - m[3] * cofactor3; - if(fabs(determinant) <= EPSILON) - { - return identity(); - } + // get determinant + float determinant = m[0] * cofactor0 - m[1] * cofactor1 + m[2] * cofactor2 - m[3] * cofactor3; + if (fabs(determinant) <= EPSILON) + { + return identity(); + } - // get rest of cofactors for adj(M) - float cofactor4 = getCofactor(m[1],m[2],m[3], m[9],m[10],m[11], m[13],m[14],m[15]); - float cofactor5 = getCofactor(m[0],m[2],m[3], m[8],m[10],m[11], m[12],m[14],m[15]); - float cofactor6 = getCofactor(m[0],m[1],m[3], m[8],m[9], m[11], m[12],m[13],m[15]); - float cofactor7 = getCofactor(m[0],m[1],m[2], m[8],m[9], m[10], m[12],m[13],m[14]); + // get rest of cofactors for adj(M) + float cofactor4 = getCofactor(m[1], m[2], m[3], m[9], m[10], m[11], m[13], m[14], m[15]); + float cofactor5 = getCofactor(m[0], m[2], m[3], m[8], m[10], m[11], m[12], m[14], m[15]); + float cofactor6 = getCofactor(m[0], m[1], m[3], m[8], m[9], m[11], m[12], m[13], m[15]); + float cofactor7 = getCofactor(m[0], m[1], m[2], m[8], m[9], m[10], m[12], m[13], m[14]); - float cofactor8 = getCofactor(m[1],m[2],m[3], m[5],m[6], m[7], m[13],m[14],m[15]); - float cofactor9 = getCofactor(m[0],m[2],m[3], m[4],m[6], m[7], m[12],m[14],m[15]); - float cofactor10= getCofactor(m[0],m[1],m[3], m[4],m[5], m[7], m[12],m[13],m[15]); - float cofactor11= getCofactor(m[0],m[1],m[2], m[4],m[5], m[6], m[12],m[13],m[14]); + float cofactor8 = getCofactor(m[1], m[2], m[3], m[5], m[6], m[7], m[13], m[14], m[15]); + float cofactor9 = getCofactor(m[0], m[2], m[3], m[4], m[6], m[7], m[12], m[14], m[15]); + float cofactor10 = getCofactor(m[0], m[1], m[3], m[4], m[5], m[7], m[12], m[13], m[15]); + float cofactor11 = getCofactor(m[0], m[1], m[2], m[4], m[5], m[6], m[12], m[13], m[14]); - float cofactor12= getCofactor(m[1],m[2],m[3], m[5],m[6], m[7], m[9], m[10],m[11]); - float cofactor13= getCofactor(m[0],m[2],m[3], m[4],m[6], m[7], m[8], m[10],m[11]); - float cofactor14= getCofactor(m[0],m[1],m[3], m[4],m[5], m[7], m[8], m[9], m[11]); - float cofactor15= getCofactor(m[0],m[1],m[2], m[4],m[5], m[6], m[8], m[9], m[10]); + float cofactor12 = getCofactor(m[1], m[2], m[3], m[5], m[6], m[7], m[9], m[10], m[11]); + float cofactor13 = getCofactor(m[0], m[2], m[3], m[4], m[6], m[7], m[8], m[10], m[11]); + float cofactor14 = getCofactor(m[0], m[1], m[3], m[4], m[5], m[7], m[8], m[9], m[11]); + float cofactor15 = getCofactor(m[0], m[1], m[2], m[4], m[5], m[6], m[8], m[9], m[10]); - // build inverse matrix = adj(M) / det(M) - // adjugate of M is the transpose of the cofactor matrix of M - float invDeterminant = 1.0f / determinant; - m[0] = invDeterminant * cofactor0; - m[1] = -invDeterminant * cofactor4; - m[2] = invDeterminant * cofactor8; - m[3] = -invDeterminant * cofactor12; + // build inverse matrix = adj(M) / det(M) + // adjugate of M is the transpose of the cofactor matrix of M + float invDeterminant = 1.0f / determinant; + m[0] = invDeterminant * cofactor0; + m[1] = -invDeterminant * cofactor4; + m[2] = invDeterminant * cofactor8; + m[3] = -invDeterminant * cofactor12; - m[4] = -invDeterminant * cofactor1; - m[5] = invDeterminant * cofactor5; - m[6] = -invDeterminant * cofactor9; - m[7] = invDeterminant * cofactor13; + m[4] = -invDeterminant * cofactor1; + m[5] = invDeterminant * cofactor5; + m[6] = -invDeterminant * cofactor9; + m[7] = invDeterminant * cofactor13; - m[8] = invDeterminant * cofactor2; - m[9] = -invDeterminant * cofactor6; - m[10]= invDeterminant * cofactor10; - m[11]= -invDeterminant * cofactor14; + m[8] = invDeterminant * cofactor2; + m[9] = -invDeterminant * cofactor6; + m[10] = invDeterminant * cofactor10; + m[11] = -invDeterminant * cofactor14; - m[12]= -invDeterminant * cofactor3; - m[13]= invDeterminant * cofactor7; - m[14]= -invDeterminant * cofactor11; - m[15]= invDeterminant * cofactor15; + m[12] = -invDeterminant * cofactor3; + m[13] = invDeterminant * cofactor7; + m[14] = -invDeterminant * cofactor11; + m[15] = invDeterminant * cofactor15; - return *this; + return *this; } - - /////////////////////////////////////////////////////////////////////////////// // return determinant of 4x4 matrix /////////////////////////////////////////////////////////////////////////////// float Matrix4::getDeterminant() { - return m[0] * getCofactor(m[5],m[6],m[7], m[9],m[10],m[11], m[13],m[14],m[15]) - - m[1] * getCofactor(m[4],m[6],m[7], m[8],m[10],m[11], m[12],m[14],m[15]) + - m[2] * getCofactor(m[4],m[5],m[7], m[8],m[9], m[11], m[12],m[13],m[15]) - - m[3] * getCofactor(m[4],m[5],m[6], m[8],m[9], m[10], m[12],m[13],m[14]); + return m[0] * getCofactor(m[5], m[6], m[7], m[9], m[10], m[11], m[13], m[14], m[15]) - + m[1] * getCofactor(m[4], m[6], m[7], m[8], m[10], m[11], m[12], m[14], m[15]) + + m[2] * getCofactor(m[4], m[5], m[7], m[8], m[9], m[11], m[12], m[13], m[15]) - + m[3] * getCofactor(m[4], m[5], m[6], m[8], m[9], m[10], m[12], m[13], m[14]); } - - /////////////////////////////////////////////////////////////////////////////// // compute cofactor of 3x3 minor matrix without sign // input params are 9 elements of the minor matrix // NOTE: The caller must know its sign. /////////////////////////////////////////////////////////////////////////////// float Matrix4::getCofactor(float m0, float m1, float m2, - float m3, float m4, float m5, - float m6, float m7, float m8) + float m3, float m4, float m5, + float m6, float m7, float m8) { - return m0 * (m4 * m8 - m5 * m7) - - m1 * (m3 * m8 - m5 * m6) + - m2 * (m3 * m7 - m4 * m6); + return m0 * (m4 * m8 - m5 * m7) - + m1 * (m3 * m8 - m5 * m6) + + m2 * (m3 * m7 - m4 * m6); } - - /////////////////////////////////////////////////////////////////////////////// // translate this matrix by (x, y, z) /////////////////////////////////////////////////////////////////////////////// Matrix4& Matrix4::translate(const Vector3& v) { - return translate(v.x, v.y, v.z); + return translate(v.x, v.y, v.z); } Matrix4& Matrix4::translate(float x, float y, float z) { - m[0] += m[3] * x; m[4] += m[7] * x; m[8] += m[11]* x; m[12]+= m[15]* x; - m[1] += m[3] * y; m[5] += m[7] * y; m[9] += m[11]* y; m[13]+= m[15]* y; - m[2] += m[3] * z; m[6] += m[7] * z; m[10]+= m[11]* z; m[14]+= m[15]* z; + m[0] += m[3] * x; + m[4] += m[7] * x; + m[8] += m[11] * x; + m[12] += m[15] * x; + m[1] += m[3] * y; + m[5] += m[7] * y; + m[9] += m[11] * y; + m[13] += m[15] * y; + m[2] += m[3] * z; + m[6] += m[7] * z; + m[10] += m[11] * z; + m[14] += m[15] * z; - return *this; + return *this; } - - /////////////////////////////////////////////////////////////////////////////// // uniform scale /////////////////////////////////////////////////////////////////////////////// Matrix4& Matrix4::scale(float s) { - return scale(s, s, s); + return scale(s, s, s); } Matrix4& Matrix4::scale(float x, float y, float z) { - m[0] *= x; m[4] *= x; m[8] *= x; m[12] *= x; - m[1] *= y; m[5] *= y; m[9] *= y; m[13] *= y; - m[2] *= z; m[6] *= z; m[10]*= z; m[14] *= z; - return *this; + m[0] *= x; + m[4] *= x; + m[8] *= x; + m[12] *= x; + m[1] *= y; + m[5] *= y; + m[9] *= y; + m[13] *= y; + m[2] *= z; + m[6] *= z; + m[10] *= z; + m[14] *= z; + return *this; } - - /////////////////////////////////////////////////////////////////////////////// // build a rotation matrix with given angle(degree) and rotation axis, then // multiply it with this object /////////////////////////////////////////////////////////////////////////////// Matrix4& Matrix4::rotate(float angle, const Vector3& axis) { - return rotate(angle, axis.x, axis.y, axis.z); + return rotate(angle, axis.x, axis.y, axis.z); } Matrix4& Matrix4::rotate(float angle, float x, float y, float z) { - float c = cosf(angle * DEG2RAD); // cosine - float s = sinf(angle * DEG2RAD); // sine - float c1 = 1.0f - c; // 1 - c - float m0 = m[0], m4 = m[4], m8 = m[8], m12= m[12], - m1 = m[1], m5 = m[5], m9 = m[9], m13= m[13], - m2 = m[2], m6 = m[6], m10= m[10], m14= m[14]; + float c = cosf(angle * DEG2RAD); // cosine + float s = sinf(angle * DEG2RAD); // sine + float c1 = 1.0f - c; // 1 - c + float m0 = m[0], m4 = m[4], m8 = m[8], m12 = m[12], + m1 = m[1], m5 = m[5], m9 = m[9], m13 = m[13], + m2 = m[2], m6 = m[6], m10 = m[10], m14 = m[14]; - // build rotation matrix - float r0 = x * x * c1 + c; - float r1 = x * y * c1 + z * s; - float r2 = x * z * c1 - y * s; - float r4 = x * y * c1 - z * s; - float r5 = y * y * c1 + c; - float r6 = y * z * c1 + x * s; - float r8 = x * z * c1 + y * s; - float r9 = y * z * c1 - x * s; - float r10= z * z * c1 + c; + // build rotation matrix + float r0 = x * x * c1 + c; + float r1 = x * y * c1 + z * s; + float r2 = x * z * c1 - y * s; + float r4 = x * y * c1 - z * s; + float r5 = y * y * c1 + c; + float r6 = y * z * c1 + x * s; + float r8 = x * z * c1 + y * s; + float r9 = y * z * c1 - x * s; + float r10 = z * z * c1 + c; - // multiply rotation matrix - m[0] = r0 * m0 + r4 * m1 + r8 * m2; - m[1] = r1 * m0 + r5 * m1 + r9 * m2; - m[2] = r2 * m0 + r6 * m1 + r10* m2; - m[4] = r0 * m4 + r4 * m5 + r8 * m6; - m[5] = r1 * m4 + r5 * m5 + r9 * m6; - m[6] = r2 * m4 + r6 * m5 + r10* m6; - m[8] = r0 * m8 + r4 * m9 + r8 * m10; - m[9] = r1 * m8 + r5 * m9 + r9 * m10; - m[10]= r2 * m8 + r6 * m9 + r10* m10; - m[12]= r0 * m12+ r4 * m13+ r8 * m14; - m[13]= r1 * m12+ r5 * m13+ r9 * m14; - m[14]= r2 * m12+ r6 * m13+ r10* m14; + // multiply rotation matrix + m[0] = r0 * m0 + r4 * m1 + r8 * m2; + m[1] = r1 * m0 + r5 * m1 + r9 * m2; + m[2] = r2 * m0 + r6 * m1 + r10 * m2; + m[4] = r0 * m4 + r4 * m5 + r8 * m6; + m[5] = r1 * m4 + r5 * m5 + r9 * m6; + m[6] = r2 * m4 + r6 * m5 + r10 * m6; + m[8] = r0 * m8 + r4 * m9 + r8 * m10; + m[9] = r1 * m8 + r5 * m9 + r9 * m10; + m[10] = r2 * m8 + r6 * m9 + r10 * m10; + m[12] = r0 * m12 + r4 * m13 + r8 * m14; + m[13] = r1 * m12 + r5 * m13 + r9 * m14; + m[14] = r2 * m12 + r6 * m13 + r10 * m14; - return *this; + return *this; } Matrix4& Matrix4::rotateX(float angle) { - float c = cosf(angle * DEG2RAD); - float s = sinf(angle * DEG2RAD); - float m1 = m[1], m2 = m[2], - m5 = m[5], m6 = m[6], - m9 = m[9], m10= m[10], - m13= m[13], m14= m[14]; + float c = cosf(angle * DEG2RAD); + float s = sinf(angle * DEG2RAD); + float m1 = m[1], m2 = m[2], + m5 = m[5], m6 = m[6], + m9 = m[9], m10 = m[10], + m13 = m[13], m14 = m[14]; - m[1] = m1 * c + m2 *-s; - m[2] = m1 * s + m2 * c; - m[5] = m5 * c + m6 *-s; - m[6] = m5 * s + m6 * c; - m[9] = m9 * c + m10*-s; - m[10]= m9 * s + m10* c; - m[13]= m13* c + m14*-s; - m[14]= m13* s + m14* c; + m[1] = m1 * c + m2 * -s; + m[2] = m1 * s + m2 * c; + m[5] = m5 * c + m6 * -s; + m[6] = m5 * s + m6 * c; + m[9] = m9 * c + m10 * -s; + m[10] = m9 * s + m10 * c; + m[13] = m13 * c + m14 * -s; + m[14] = m13 * s + m14 * c; - return *this; + return *this; } Matrix4& Matrix4::rotateY(float angle) { - float c = cosf(angle * DEG2RAD); - float s = sinf(angle * DEG2RAD); - float m0 = m[0], m2 = m[2], - m4 = m[4], m6 = m[6], - m8 = m[8], m10= m[10], - m12= m[12], m14= m[14]; + float c = cosf(angle * DEG2RAD); + float s = sinf(angle * DEG2RAD); + float m0 = m[0], m2 = m[2], + m4 = m[4], m6 = m[6], + m8 = m[8], m10 = m[10], + m12 = m[12], m14 = m[14]; - m[0] = m0 * c + m2 * s; - m[2] = m0 *-s + m2 * c; - m[4] = m4 * c + m6 * s; - m[6] = m4 *-s + m6 * c; - m[8] = m8 * c + m10* s; - m[10]= m8 *-s + m10* c; - m[12]= m12* c + m14* s; - m[14]= m12*-s + m14* c; + m[0] = m0 * c + m2 * s; + m[2] = m0 * -s + m2 * c; + m[4] = m4 * c + m6 * s; + m[6] = m4 * -s + m6 * c; + m[8] = m8 * c + m10 * s; + m[10] = m8 * -s + m10 * c; + m[12] = m12 * c + m14 * s; + m[14] = m12 * -s + m14 * c; - return *this; + return *this; } Matrix4& Matrix4::rotateZ(float angle) { - float c = cosf(angle * DEG2RAD); - float s = sinf(angle * DEG2RAD); - float m0 = m[0], m1 = m[1], - m4 = m[4], m5 = m[5], - m8 = m[8], m9 = m[9], - m12= m[12], m13= m[13]; + float c = cosf(angle * DEG2RAD); + float s = sinf(angle * DEG2RAD); + float m0 = m[0], m1 = m[1], + m4 = m[4], m5 = m[5], + m8 = m[8], m9 = m[9], + m12 = m[12], m13 = m[13]; - m[0] = m0 * c + m1 *-s; - m[1] = m0 * s + m1 * c; - m[4] = m4 * c + m5 *-s; - m[5] = m4 * s + m5 * c; - m[8] = m8 * c + m9 *-s; - m[9] = m8 * s + m9 * c; - m[12]= m12* c + m13*-s; - m[13]= m12* s + m13* c; + m[0] = m0 * c + m1 * -s; + m[1] = m0 * s + m1 * c; + m[4] = m4 * c + m5 * -s; + m[5] = m4 * s + m5 * c; + m[8] = m8 * c + m9 * -s; + m[9] = m8 * s + m9 * c; + m[12] = m12 * c + m13 * -s; + m[13] = m12 * s + m13 * c; - return *this; + return *this; } diff --git a/examples/ThirdPartyLibs/openvr/samples/shared/Matrices.h b/examples/ThirdPartyLibs/openvr/samples/shared/Matrices.h index 3515f546d..6d1cf432d 100644 --- a/examples/ThirdPartyLibs/openvr/samples/shared/Matrices.h +++ b/examples/ThirdPartyLibs/openvr/samples/shared/Matrices.h @@ -29,881 +29,827 @@ class Matrix2 { public: - // constructors - Matrix2(); // init with identity - Matrix2(const float src[4]); - Matrix2(float m0, float m1, float m2, float m3); + // constructors + Matrix2(); // init with identity + Matrix2(const float src[4]); + Matrix2(float m0, float m1, float m2, float m3); - void set(const float src[4]); - void set(float m0, float m1, float m2, float m3); - void setRow(int index, const float row[2]); - void setRow(int index, const Vector2& v); - void setColumn(int index, const float col[2]); - void setColumn(int index, const Vector2& v); + void set(const float src[4]); + void set(float m0, float m1, float m2, float m3); + void setRow(int index, const float row[2]); + void setRow(int index, const Vector2& v); + void setColumn(int index, const float col[2]); + void setColumn(int index, const Vector2& v); - const float* get() const; - float getDeterminant(); + const float* get() const; + float getDeterminant(); - Matrix2& identity(); - Matrix2& transpose(); // transpose itself and return reference - Matrix2& invert(); + Matrix2& identity(); + Matrix2& transpose(); // transpose itself and return reference + Matrix2& invert(); - // operators - Matrix2 operator+(const Matrix2& rhs) const; // add rhs - Matrix2 operator-(const Matrix2& rhs) const; // subtract rhs - Matrix2& operator+=(const Matrix2& rhs); // add rhs and update this object - Matrix2& operator-=(const Matrix2& rhs); // subtract rhs and update this object - Vector2 operator*(const Vector2& rhs) const; // multiplication: v' = M * v - Matrix2 operator*(const Matrix2& rhs) const; // multiplication: M3 = M1 * M2 - Matrix2& operator*=(const Matrix2& rhs); // multiplication: M1' = M1 * M2 - bool operator==(const Matrix2& rhs) const; // exact compare, no epsilon - bool operator!=(const Matrix2& rhs) const; // exact compare, no epsilon - float operator[](int index) const; // subscript operator v[0], v[1] - float& operator[](int index); // subscript operator v[0], v[1] + // operators + Matrix2 operator+(const Matrix2& rhs) const; // add rhs + Matrix2 operator-(const Matrix2& rhs) const; // subtract rhs + Matrix2& operator+=(const Matrix2& rhs); // add rhs and update this object + Matrix2& operator-=(const Matrix2& rhs); // subtract rhs and update this object + Vector2 operator*(const Vector2& rhs) const; // multiplication: v' = M * v + Matrix2 operator*(const Matrix2& rhs) const; // multiplication: M3 = M1 * M2 + Matrix2& operator*=(const Matrix2& rhs); // multiplication: M1' = M1 * M2 + bool operator==(const Matrix2& rhs) const; // exact compare, no epsilon + bool operator!=(const Matrix2& rhs) const; // exact compare, no epsilon + float operator[](int index) const; // subscript operator v[0], v[1] + float& operator[](int index); // subscript operator v[0], v[1] - friend Matrix2 operator-(const Matrix2& m); // unary operator (-) - friend Matrix2 operator*(float scalar, const Matrix2& m); // pre-multiplication - friend Vector2 operator*(const Vector2& vec, const Matrix2& m); // pre-multiplication - friend std::ostream& operator<<(std::ostream& os, const Matrix2& m); + friend Matrix2 operator-(const Matrix2& m); // unary operator (-) + friend Matrix2 operator*(float scalar, const Matrix2& m); // pre-multiplication + friend Vector2 operator*(const Vector2& vec, const Matrix2& m); // pre-multiplication + friend std::ostream& operator<<(std::ostream& os, const Matrix2& m); protected: - private: - float m[4]; - + float m[4]; }; - - /////////////////////////////////////////////////////////////////////////// // 3x3 matrix /////////////////////////////////////////////////////////////////////////// class Matrix3 { public: - // constructors - Matrix3(); // init with identity - Matrix3(const float src[9]); - Matrix3(float m0, float m1, float m2, // 1st column - float m3, float m4, float m5, // 2nd column - float m6, float m7, float m8); // 3rd column + // constructors + Matrix3(); // init with identity + Matrix3(const float src[9]); + Matrix3(float m0, float m1, float m2, // 1st column + float m3, float m4, float m5, // 2nd column + float m6, float m7, float m8); // 3rd column - void set(const float src[9]); - void set(float m0, float m1, float m2, // 1st column - float m3, float m4, float m5, // 2nd column - float m6, float m7, float m8); // 3rd column - void setRow(int index, const float row[3]); - void setRow(int index, const Vector3& v); - void setColumn(int index, const float col[3]); - void setColumn(int index, const Vector3& v); + void set(const float src[9]); + void set(float m0, float m1, float m2, // 1st column + float m3, float m4, float m5, // 2nd column + float m6, float m7, float m8); // 3rd column + void setRow(int index, const float row[3]); + void setRow(int index, const Vector3& v); + void setColumn(int index, const float col[3]); + void setColumn(int index, const Vector3& v); - const float* get() const; - float getDeterminant(); + const float* get() const; + float getDeterminant(); - Matrix3& identity(); - Matrix3& transpose(); // transpose itself and return reference - Matrix3& invert(); + Matrix3& identity(); + Matrix3& transpose(); // transpose itself and return reference + Matrix3& invert(); - // operators - Matrix3 operator+(const Matrix3& rhs) const; // add rhs - Matrix3 operator-(const Matrix3& rhs) const; // subtract rhs - Matrix3& operator+=(const Matrix3& rhs); // add rhs and update this object - Matrix3& operator-=(const Matrix3& rhs); // subtract rhs and update this object - Vector3 operator*(const Vector3& rhs) const; // multiplication: v' = M * v - Matrix3 operator*(const Matrix3& rhs) const; // multiplication: M3 = M1 * M2 - Matrix3& operator*=(const Matrix3& rhs); // multiplication: M1' = M1 * M2 - bool operator==(const Matrix3& rhs) const; // exact compare, no epsilon - bool operator!=(const Matrix3& rhs) const; // exact compare, no epsilon - float operator[](int index) const; // subscript operator v[0], v[1] - float& operator[](int index); // subscript operator v[0], v[1] + // operators + Matrix3 operator+(const Matrix3& rhs) const; // add rhs + Matrix3 operator-(const Matrix3& rhs) const; // subtract rhs + Matrix3& operator+=(const Matrix3& rhs); // add rhs and update this object + Matrix3& operator-=(const Matrix3& rhs); // subtract rhs and update this object + Vector3 operator*(const Vector3& rhs) const; // multiplication: v' = M * v + Matrix3 operator*(const Matrix3& rhs) const; // multiplication: M3 = M1 * M2 + Matrix3& operator*=(const Matrix3& rhs); // multiplication: M1' = M1 * M2 + bool operator==(const Matrix3& rhs) const; // exact compare, no epsilon + bool operator!=(const Matrix3& rhs) const; // exact compare, no epsilon + float operator[](int index) const; // subscript operator v[0], v[1] + float& operator[](int index); // subscript operator v[0], v[1] - friend Matrix3 operator-(const Matrix3& m); // unary operator (-) - friend Matrix3 operator*(float scalar, const Matrix3& m); // pre-multiplication - friend Vector3 operator*(const Vector3& vec, const Matrix3& m); // pre-multiplication - friend std::ostream& operator<<(std::ostream& os, const Matrix3& m); + friend Matrix3 operator-(const Matrix3& m); // unary operator (-) + friend Matrix3 operator*(float scalar, const Matrix3& m); // pre-multiplication + friend Vector3 operator*(const Vector3& vec, const Matrix3& m); // pre-multiplication + friend std::ostream& operator<<(std::ostream& os, const Matrix3& m); protected: - private: - float m[9]; - + float m[9]; }; - - /////////////////////////////////////////////////////////////////////////// // 4x4 matrix /////////////////////////////////////////////////////////////////////////// class Matrix4 { public: - // constructors - Matrix4(); // init with identity - Matrix4(const float src[16]); - Matrix4(float m00, float m01, float m02, float m03, // 1st column - float m04, float m05, float m06, float m07, // 2nd column - float m08, float m09, float m10, float m11, // 3rd column - float m12, float m13, float m14, float m15);// 4th column + // constructors + Matrix4(); // init with identity + Matrix4(const float src[16]); + Matrix4(float m00, float m01, float m02, float m03, // 1st column + float m04, float m05, float m06, float m07, // 2nd column + float m08, float m09, float m10, float m11, // 3rd column + float m12, float m13, float m14, float m15); // 4th column - void set(const float src[16]); - void set(float m00, float m01, float m02, float m03, // 1st column - float m04, float m05, float m06, float m07, // 2nd column - float m08, float m09, float m10, float m11, // 3rd column - float m12, float m13, float m14, float m15);// 4th column - void setRow(int index, const float row[4]); - void setRow(int index, const Vector4& v); - void setRow(int index, const Vector3& v); - void setColumn(int index, const float col[4]); - void setColumn(int index, const Vector4& v); - void setColumn(int index, const Vector3& v); + void set(const float src[16]); + void set(float m00, float m01, float m02, float m03, // 1st column + float m04, float m05, float m06, float m07, // 2nd column + float m08, float m09, float m10, float m11, // 3rd column + float m12, float m13, float m14, float m15); // 4th column + void setRow(int index, const float row[4]); + void setRow(int index, const Vector4& v); + void setRow(int index, const Vector3& v); + void setColumn(int index, const float col[4]); + void setColumn(int index, const Vector4& v); + void setColumn(int index, const Vector3& v); - const float* get() const; - const float* getTranspose(); // return transposed matrix - float getDeterminant(); + const float* get() const; + const float* getTranspose(); // return transposed matrix + float getDeterminant(); - Matrix4& identity(); - Matrix4& transpose(); // transpose itself and return reference - Matrix4& invert(); // check best inverse method before inverse - Matrix4& invertEuclidean(); // inverse of Euclidean transform matrix - Matrix4& invertAffine(); // inverse of affine transform matrix - Matrix4& invertProjective(); // inverse of projective matrix using partitioning - Matrix4& invertGeneral(); // inverse of generic matrix + Matrix4& identity(); + Matrix4& transpose(); // transpose itself and return reference + Matrix4& invert(); // check best inverse method before inverse + Matrix4& invertEuclidean(); // inverse of Euclidean transform matrix + Matrix4& invertAffine(); // inverse of affine transform matrix + Matrix4& invertProjective(); // inverse of projective matrix using partitioning + Matrix4& invertGeneral(); // inverse of generic matrix - // transform matrix - Matrix4& translate(float x, float y, float z); // translation by (x,y,z) - Matrix4& translate(const Vector3& v); // - Matrix4& rotate(float angle, const Vector3& axis); // rotate angle(degree) along the given axix - Matrix4& rotate(float angle, float x, float y, float z); - Matrix4& rotateX(float angle); // rotate on X-axis with degree - Matrix4& rotateY(float angle); // rotate on Y-axis with degree - Matrix4& rotateZ(float angle); // rotate on Z-axis with degree - Matrix4& scale(float scale); // uniform scale - Matrix4& scale(float sx, float sy, float sz); // scale by (sx, sy, sz) on each axis + // transform matrix + Matrix4& translate(float x, float y, float z); // translation by (x,y,z) + Matrix4& translate(const Vector3& v); // + Matrix4& rotate(float angle, const Vector3& axis); // rotate angle(degree) along the given axix + Matrix4& rotate(float angle, float x, float y, float z); + Matrix4& rotateX(float angle); // rotate on X-axis with degree + Matrix4& rotateY(float angle); // rotate on Y-axis with degree + Matrix4& rotateZ(float angle); // rotate on Z-axis with degree + Matrix4& scale(float scale); // uniform scale + Matrix4& scale(float sx, float sy, float sz); // scale by (sx, sy, sz) on each axis - // operators - Matrix4 operator+(const Matrix4& rhs) const; // add rhs - Matrix4 operator-(const Matrix4& rhs) const; // subtract rhs - Matrix4& operator+=(const Matrix4& rhs); // add rhs and update this object - Matrix4& operator-=(const Matrix4& rhs); // subtract rhs and update this object - Vector4 operator*(const Vector4& rhs) const; // multiplication: v' = M * v - Vector3 operator*(const Vector3& rhs) const; // multiplication: v' = M * v - Matrix4 operator*(const Matrix4& rhs) const; // multiplication: M3 = M1 * M2 - Matrix4& operator*=(const Matrix4& rhs); // multiplication: M1' = M1 * M2 - bool operator==(const Matrix4& rhs) const; // exact compare, no epsilon - bool operator!=(const Matrix4& rhs) const; // exact compare, no epsilon - float operator[](int index) const; // subscript operator v[0], v[1] - float& operator[](int index); // subscript operator v[0], v[1] + // operators + Matrix4 operator+(const Matrix4& rhs) const; // add rhs + Matrix4 operator-(const Matrix4& rhs) const; // subtract rhs + Matrix4& operator+=(const Matrix4& rhs); // add rhs and update this object + Matrix4& operator-=(const Matrix4& rhs); // subtract rhs and update this object + Vector4 operator*(const Vector4& rhs) const; // multiplication: v' = M * v + Vector3 operator*(const Vector3& rhs) const; // multiplication: v' = M * v + Matrix4 operator*(const Matrix4& rhs) const; // multiplication: M3 = M1 * M2 + Matrix4& operator*=(const Matrix4& rhs); // multiplication: M1' = M1 * M2 + bool operator==(const Matrix4& rhs) const; // exact compare, no epsilon + bool operator!=(const Matrix4& rhs) const; // exact compare, no epsilon + float operator[](int index) const; // subscript operator v[0], v[1] + float& operator[](int index); // subscript operator v[0], v[1] - friend Matrix4 operator-(const Matrix4& m); // unary operator (-) - friend Matrix4 operator*(float scalar, const Matrix4& m); // pre-multiplication - friend Vector3 operator*(const Vector3& vec, const Matrix4& m); // pre-multiplication - friend Vector4 operator*(const Vector4& vec, const Matrix4& m); // pre-multiplication - friend std::ostream& operator<<(std::ostream& os, const Matrix4& m); + friend Matrix4 operator-(const Matrix4& m); // unary operator (-) + friend Matrix4 operator*(float scalar, const Matrix4& m); // pre-multiplication + friend Vector3 operator*(const Vector3& vec, const Matrix4& m); // pre-multiplication + friend Vector4 operator*(const Vector4& vec, const Matrix4& m); // pre-multiplication + friend std::ostream& operator<<(std::ostream& os, const Matrix4& m); protected: - private: - float getCofactor(float m0, float m1, float m2, - float m3, float m4, float m5, - float m6, float m7, float m8); - - float m[16]; - float tm[16]; // transpose m + float getCofactor(float m0, float m1, float m2, + float m3, float m4, float m5, + float m6, float m7, float m8); + float m[16]; + float tm[16]; // transpose m }; - - /////////////////////////////////////////////////////////////////////////// // inline functions for Matrix2 /////////////////////////////////////////////////////////////////////////// inline Matrix2::Matrix2() { - // initially identity matrix - identity(); + // initially identity matrix + identity(); } - - inline Matrix2::Matrix2(const float src[4]) { - set(src); + set(src); } - - inline Matrix2::Matrix2(float m0, float m1, float m2, float m3) { - set(m0, m1, m2, m3); + set(m0, m1, m2, m3); } - - inline void Matrix2::set(const float src[4]) { - m[0] = src[0]; m[1] = src[1]; m[2] = src[2]; m[3] = src[3]; + m[0] = src[0]; + m[1] = src[1]; + m[2] = src[2]; + m[3] = src[3]; } - - inline void Matrix2::set(float m0, float m1, float m2, float m3) { - m[0]= m0; m[1] = m1; m[2] = m2; m[3]= m3; + m[0] = m0; + m[1] = m1; + m[2] = m2; + m[3] = m3; } - - inline void Matrix2::setRow(int index, const float row[2]) { - m[index] = row[0]; m[index + 2] = row[1]; + m[index] = row[0]; + m[index + 2] = row[1]; } - - inline void Matrix2::setRow(int index, const Vector2& v) { - m[index] = v.x; m[index + 2] = v.y; + m[index] = v.x; + m[index + 2] = v.y; } - - inline void Matrix2::setColumn(int index, const float col[2]) { - m[index*2] = col[0]; m[index*2 + 1] = col[1]; + m[index * 2] = col[0]; + m[index * 2 + 1] = col[1]; } - - inline void Matrix2::setColumn(int index, const Vector2& v) { - m[index*2] = v.x; m[index*2 + 1] = v.y; + m[index * 2] = v.x; + m[index * 2 + 1] = v.y; } - - inline const float* Matrix2::get() const { - return m; + return m; } - - inline Matrix2& Matrix2::identity() { - m[0] = m[3] = 1.0f; - m[1] = m[2] = 0.0f; - return *this; + m[0] = m[3] = 1.0f; + m[1] = m[2] = 0.0f; + return *this; } - - inline Matrix2 Matrix2::operator+(const Matrix2& rhs) const { - return Matrix2(m[0]+rhs[0], m[1]+rhs[1], m[2]+rhs[2], m[3]+rhs[3]); + return Matrix2(m[0] + rhs[0], m[1] + rhs[1], m[2] + rhs[2], m[3] + rhs[3]); } - - inline Matrix2 Matrix2::operator-(const Matrix2& rhs) const { - return Matrix2(m[0]-rhs[0], m[1]-rhs[1], m[2]-rhs[2], m[3]-rhs[3]); + return Matrix2(m[0] - rhs[0], m[1] - rhs[1], m[2] - rhs[2], m[3] - rhs[3]); } - - inline Matrix2& Matrix2::operator+=(const Matrix2& rhs) { - m[0] += rhs[0]; m[1] += rhs[1]; m[2] += rhs[2]; m[3] += rhs[3]; - return *this; + m[0] += rhs[0]; + m[1] += rhs[1]; + m[2] += rhs[2]; + m[3] += rhs[3]; + return *this; } - - inline Matrix2& Matrix2::operator-=(const Matrix2& rhs) { - m[0] -= rhs[0]; m[1] -= rhs[1]; m[2] -= rhs[2]; m[3] -= rhs[3]; - return *this; + m[0] -= rhs[0]; + m[1] -= rhs[1]; + m[2] -= rhs[2]; + m[3] -= rhs[3]; + return *this; } - - inline Vector2 Matrix2::operator*(const Vector2& rhs) const { - return Vector2(m[0]*rhs.x + m[2]*rhs.y, m[1]*rhs.x + m[3]*rhs.y); + return Vector2(m[0] * rhs.x + m[2] * rhs.y, m[1] * rhs.x + m[3] * rhs.y); } - - inline Matrix2 Matrix2::operator*(const Matrix2& rhs) const { - return Matrix2(m[0]*rhs[0] + m[2]*rhs[1], m[1]*rhs[0] + m[3]*rhs[1], - m[0]*rhs[2] + m[2]*rhs[3], m[1]*rhs[2] + m[3]*rhs[3]); + return Matrix2(m[0] * rhs[0] + m[2] * rhs[1], m[1] * rhs[0] + m[3] * rhs[1], + m[0] * rhs[2] + m[2] * rhs[3], m[1] * rhs[2] + m[3] * rhs[3]); } - - inline Matrix2& Matrix2::operator*=(const Matrix2& rhs) { - *this = *this * rhs; - return *this; + *this = *this * rhs; + return *this; } - - inline bool Matrix2::operator==(const Matrix2& rhs) const { - return (m[0] == rhs[0]) && (m[1] == rhs[1]) && (m[2] == rhs[2]) && (m[3] == rhs[3]); + return (m[0] == rhs[0]) && (m[1] == rhs[1]) && (m[2] == rhs[2]) && (m[3] == rhs[3]); } - - inline bool Matrix2::operator!=(const Matrix2& rhs) const { - return (m[0] != rhs[0]) || (m[1] != rhs[1]) || (m[2] != rhs[2]) || (m[3] != rhs[3]); + return (m[0] != rhs[0]) || (m[1] != rhs[1]) || (m[2] != rhs[2]) || (m[3] != rhs[3]); } - - inline float Matrix2::operator[](int index) const { - return m[index]; + return m[index]; } - - inline float& Matrix2::operator[](int index) { - return m[index]; + return m[index]; } - - inline Matrix2 operator-(const Matrix2& rhs) { - return Matrix2(-rhs[0], -rhs[1], -rhs[2], -rhs[3]); + return Matrix2(-rhs[0], -rhs[1], -rhs[2], -rhs[3]); } - - inline Matrix2 operator*(float s, const Matrix2& rhs) { - return Matrix2(s*rhs[0], s*rhs[1], s*rhs[2], s*rhs[3]); + return Matrix2(s * rhs[0], s * rhs[1], s * rhs[2], s * rhs[3]); } - - inline Vector2 operator*(const Vector2& v, const Matrix2& rhs) { - return Vector2(v.x*rhs[0] + v.y*rhs[1], v.x*rhs[2] + v.y*rhs[3]); + return Vector2(v.x * rhs[0] + v.y * rhs[1], v.x * rhs[2] + v.y * rhs[3]); } - - inline std::ostream& operator<<(std::ostream& os, const Matrix2& m) { - os << std::fixed << std::setprecision(5); - os << "[" << std::setw(10) << m[0] << " " << std::setw(10) << m[2] << "]\n" - << "[" << std::setw(10) << m[1] << " " << std::setw(10) << m[3] << "]\n"; - os << std::resetiosflags(std::ios_base::fixed | std::ios_base::floatfield); - return os; + os << std::fixed << std::setprecision(5); + os << "[" << std::setw(10) << m[0] << " " << std::setw(10) << m[2] << "]\n" + << "[" << std::setw(10) << m[1] << " " << std::setw(10) << m[3] << "]\n"; + os << std::resetiosflags(std::ios_base::fixed | std::ios_base::floatfield); + return os; } // END OF MATRIX2 INLINE ////////////////////////////////////////////////////// - - - /////////////////////////////////////////////////////////////////////////// // inline functions for Matrix3 /////////////////////////////////////////////////////////////////////////// inline Matrix3::Matrix3() { - // initially identity matrix - identity(); + // initially identity matrix + identity(); } - - inline Matrix3::Matrix3(const float src[9]) { - set(src); + set(src); } - - inline Matrix3::Matrix3(float m0, float m1, float m2, - float m3, float m4, float m5, - float m6, float m7, float m8) + float m3, float m4, float m5, + float m6, float m7, float m8) { - set(m0, m1, m2, m3, m4, m5, m6, m7, m8); + set(m0, m1, m2, m3, m4, m5, m6, m7, m8); } - - inline void Matrix3::set(const float src[9]) { - m[0] = src[0]; m[1] = src[1]; m[2] = src[2]; - m[3] = src[3]; m[4] = src[4]; m[5] = src[5]; - m[6] = src[6]; m[7] = src[7]; m[8] = src[8]; + m[0] = src[0]; + m[1] = src[1]; + m[2] = src[2]; + m[3] = src[3]; + m[4] = src[4]; + m[5] = src[5]; + m[6] = src[6]; + m[7] = src[7]; + m[8] = src[8]; } - - inline void Matrix3::set(float m0, float m1, float m2, - float m3, float m4, float m5, - float m6, float m7, float m8) + float m3, float m4, float m5, + float m6, float m7, float m8) { - m[0] = m0; m[1] = m1; m[2] = m2; - m[3] = m3; m[4] = m4; m[5] = m5; - m[6] = m6; m[7] = m7; m[8] = m8; + m[0] = m0; + m[1] = m1; + m[2] = m2; + m[3] = m3; + m[4] = m4; + m[5] = m5; + m[6] = m6; + m[7] = m7; + m[8] = m8; } - - inline void Matrix3::setRow(int index, const float row[3]) { - m[index] = row[0]; m[index + 3] = row[1]; m[index + 6] = row[2]; + m[index] = row[0]; + m[index + 3] = row[1]; + m[index + 6] = row[2]; } - - inline void Matrix3::setRow(int index, const Vector3& v) { - m[index] = v.x; m[index + 3] = v.y; m[index + 6] = v.z; + m[index] = v.x; + m[index + 3] = v.y; + m[index + 6] = v.z; } - - inline void Matrix3::setColumn(int index, const float col[3]) { - m[index*3] = col[0]; m[index*3 + 1] = col[1]; m[index*3 + 2] = col[2]; + m[index * 3] = col[0]; + m[index * 3 + 1] = col[1]; + m[index * 3 + 2] = col[2]; } - - inline void Matrix3::setColumn(int index, const Vector3& v) { - m[index*3] = v.x; m[index*3 + 1] = v.y; m[index*3 + 2] = v.z; + m[index * 3] = v.x; + m[index * 3 + 1] = v.y; + m[index * 3 + 2] = v.z; } - - inline const float* Matrix3::get() const { - return m; + return m; } - - inline Matrix3& Matrix3::identity() { - m[0] = m[4] = m[8] = 1.0f; - m[1] = m[2] = m[3] = m[5] = m[6] = m[7] = 0.0f; - return *this; + m[0] = m[4] = m[8] = 1.0f; + m[1] = m[2] = m[3] = m[5] = m[6] = m[7] = 0.0f; + return *this; } - - inline Matrix3 Matrix3::operator+(const Matrix3& rhs) const { - return Matrix3(m[0]+rhs[0], m[1]+rhs[1], m[2]+rhs[2], - m[3]+rhs[3], m[4]+rhs[4], m[5]+rhs[5], - m[6]+rhs[6], m[7]+rhs[7], m[8]+rhs[8]); + return Matrix3(m[0] + rhs[0], m[1] + rhs[1], m[2] + rhs[2], + m[3] + rhs[3], m[4] + rhs[4], m[5] + rhs[5], + m[6] + rhs[6], m[7] + rhs[7], m[8] + rhs[8]); } - - inline Matrix3 Matrix3::operator-(const Matrix3& rhs) const { - return Matrix3(m[0]-rhs[0], m[1]-rhs[1], m[2]-rhs[2], - m[3]-rhs[3], m[4]-rhs[4], m[5]-rhs[5], - m[6]-rhs[6], m[7]-rhs[7], m[8]-rhs[8]); + return Matrix3(m[0] - rhs[0], m[1] - rhs[1], m[2] - rhs[2], + m[3] - rhs[3], m[4] - rhs[4], m[5] - rhs[5], + m[6] - rhs[6], m[7] - rhs[7], m[8] - rhs[8]); } - - inline Matrix3& Matrix3::operator+=(const Matrix3& rhs) { - m[0] += rhs[0]; m[1] += rhs[1]; m[2] += rhs[2]; - m[3] += rhs[3]; m[4] += rhs[4]; m[5] += rhs[5]; - m[6] += rhs[6]; m[7] += rhs[7]; m[8] += rhs[8]; - return *this; + m[0] += rhs[0]; + m[1] += rhs[1]; + m[2] += rhs[2]; + m[3] += rhs[3]; + m[4] += rhs[4]; + m[5] += rhs[5]; + m[6] += rhs[6]; + m[7] += rhs[7]; + m[8] += rhs[8]; + return *this; } - - inline Matrix3& Matrix3::operator-=(const Matrix3& rhs) { - m[0] -= rhs[0]; m[1] -= rhs[1]; m[2] -= rhs[2]; - m[3] -= rhs[3]; m[4] -= rhs[4]; m[5] -= rhs[5]; - m[6] -= rhs[6]; m[7] -= rhs[7]; m[8] -= rhs[8]; - return *this; + m[0] -= rhs[0]; + m[1] -= rhs[1]; + m[2] -= rhs[2]; + m[3] -= rhs[3]; + m[4] -= rhs[4]; + m[5] -= rhs[5]; + m[6] -= rhs[6]; + m[7] -= rhs[7]; + m[8] -= rhs[8]; + return *this; } - - inline Vector3 Matrix3::operator*(const Vector3& rhs) const { - return Vector3(m[0]*rhs.x + m[3]*rhs.y + m[6]*rhs.z, - m[1]*rhs.x + m[4]*rhs.y + m[7]*rhs.z, - m[2]*rhs.x + m[5]*rhs.y + m[8]*rhs.z); + return Vector3(m[0] * rhs.x + m[3] * rhs.y + m[6] * rhs.z, + m[1] * rhs.x + m[4] * rhs.y + m[7] * rhs.z, + m[2] * rhs.x + m[5] * rhs.y + m[8] * rhs.z); } - - inline Matrix3 Matrix3::operator*(const Matrix3& rhs) const { - return Matrix3(m[0]*rhs[0] + m[3]*rhs[1] + m[6]*rhs[2], m[1]*rhs[0] + m[4]*rhs[1] + m[7]*rhs[2], m[2]*rhs[0] + m[5]*rhs[1] + m[8]*rhs[2], - m[0]*rhs[3] + m[3]*rhs[4] + m[6]*rhs[5], m[1]*rhs[3] + m[4]*rhs[4] + m[7]*rhs[5], m[2]*rhs[3] + m[5]*rhs[4] + m[8]*rhs[5], - m[0]*rhs[6] + m[3]*rhs[7] + m[6]*rhs[8], m[1]*rhs[6] + m[4]*rhs[7] + m[7]*rhs[8], m[2]*rhs[6] + m[5]*rhs[7] + m[8]*rhs[8]); + return Matrix3(m[0] * rhs[0] + m[3] * rhs[1] + m[6] * rhs[2], m[1] * rhs[0] + m[4] * rhs[1] + m[7] * rhs[2], m[2] * rhs[0] + m[5] * rhs[1] + m[8] * rhs[2], + m[0] * rhs[3] + m[3] * rhs[4] + m[6] * rhs[5], m[1] * rhs[3] + m[4] * rhs[4] + m[7] * rhs[5], m[2] * rhs[3] + m[5] * rhs[4] + m[8] * rhs[5], + m[0] * rhs[6] + m[3] * rhs[7] + m[6] * rhs[8], m[1] * rhs[6] + m[4] * rhs[7] + m[7] * rhs[8], m[2] * rhs[6] + m[5] * rhs[7] + m[8] * rhs[8]); } - - inline Matrix3& Matrix3::operator*=(const Matrix3& rhs) { - *this = *this * rhs; - return *this; + *this = *this * rhs; + return *this; } - - inline bool Matrix3::operator==(const Matrix3& rhs) const { - return (m[0] == rhs[0]) && (m[1] == rhs[1]) && (m[2] == rhs[2]) && - (m[3] == rhs[3]) && (m[4] == rhs[4]) && (m[5] == rhs[5]) && - (m[6] == rhs[6]) && (m[7] == rhs[7]) && (m[8] == rhs[8]); + return (m[0] == rhs[0]) && (m[1] == rhs[1]) && (m[2] == rhs[2]) && + (m[3] == rhs[3]) && (m[4] == rhs[4]) && (m[5] == rhs[5]) && + (m[6] == rhs[6]) && (m[7] == rhs[7]) && (m[8] == rhs[8]); } - - inline bool Matrix3::operator!=(const Matrix3& rhs) const { - return (m[0] != rhs[0]) || (m[1] != rhs[1]) || (m[2] != rhs[2]) || - (m[3] != rhs[3]) || (m[4] != rhs[4]) || (m[5] != rhs[5]) || - (m[6] != rhs[6]) || (m[7] != rhs[7]) || (m[8] != rhs[8]); + return (m[0] != rhs[0]) || (m[1] != rhs[1]) || (m[2] != rhs[2]) || + (m[3] != rhs[3]) || (m[4] != rhs[4]) || (m[5] != rhs[5]) || + (m[6] != rhs[6]) || (m[7] != rhs[7]) || (m[8] != rhs[8]); } - - inline float Matrix3::operator[](int index) const { - return m[index]; + return m[index]; } - - inline float& Matrix3::operator[](int index) { - return m[index]; + return m[index]; } - - inline Matrix3 operator-(const Matrix3& rhs) { - return Matrix3(-rhs[0], -rhs[1], -rhs[2], -rhs[3], -rhs[4], -rhs[5], -rhs[6], -rhs[7], -rhs[8]); + return Matrix3(-rhs[0], -rhs[1], -rhs[2], -rhs[3], -rhs[4], -rhs[5], -rhs[6], -rhs[7], -rhs[8]); } - - inline Matrix3 operator*(float s, const Matrix3& rhs) { - return Matrix3(s*rhs[0], s*rhs[1], s*rhs[2], s*rhs[3], s*rhs[4], s*rhs[5], s*rhs[6], s*rhs[7], s*rhs[8]); + return Matrix3(s * rhs[0], s * rhs[1], s * rhs[2], s * rhs[3], s * rhs[4], s * rhs[5], s * rhs[6], s * rhs[7], s * rhs[8]); } - - inline Vector3 operator*(const Vector3& v, const Matrix3& m) { - return Vector3(v.x*m[0] + v.y*m[1] + v.z*m[2], v.x*m[3] + v.y*m[4] + v.z*m[5], v.x*m[6] + v.y*m[7] + v.z*m[8]); + return Vector3(v.x * m[0] + v.y * m[1] + v.z * m[2], v.x * m[3] + v.y * m[4] + v.z * m[5], v.x * m[6] + v.y * m[7] + v.z * m[8]); } - - inline std::ostream& operator<<(std::ostream& os, const Matrix3& m) { - os << std::fixed << std::setprecision(5); - os << "[" << std::setw(10) << m[0] << " " << std::setw(10) << m[3] << " " << std::setw(10) << m[6] << "]\n" - << "[" << std::setw(10) << m[1] << " " << std::setw(10) << m[4] << " " << std::setw(10) << m[7] << "]\n" - << "[" << std::setw(10) << m[2] << " " << std::setw(10) << m[5] << " " << std::setw(10) << m[8] << "]\n"; - os << std::resetiosflags(std::ios_base::fixed | std::ios_base::floatfield); - return os; + os << std::fixed << std::setprecision(5); + os << "[" << std::setw(10) << m[0] << " " << std::setw(10) << m[3] << " " << std::setw(10) << m[6] << "]\n" + << "[" << std::setw(10) << m[1] << " " << std::setw(10) << m[4] << " " << std::setw(10) << m[7] << "]\n" + << "[" << std::setw(10) << m[2] << " " << std::setw(10) << m[5] << " " << std::setw(10) << m[8] << "]\n"; + os << std::resetiosflags(std::ios_base::fixed | std::ios_base::floatfield); + return os; } // END OF MATRIX3 INLINE ////////////////////////////////////////////////////// - - - /////////////////////////////////////////////////////////////////////////// // inline functions for Matrix4 /////////////////////////////////////////////////////////////////////////// inline Matrix4::Matrix4() { - // initially identity matrix - identity(); + // initially identity matrix + identity(); } - - inline Matrix4::Matrix4(const float src[16]) { - set(src); + set(src); } - - inline Matrix4::Matrix4(float m00, float m01, float m02, float m03, - float m04, float m05, float m06, float m07, - float m08, float m09, float m10, float m11, - float m12, float m13, float m14, float m15) + float m04, float m05, float m06, float m07, + float m08, float m09, float m10, float m11, + float m12, float m13, float m14, float m15) { - set(m00, m01, m02, m03, m04, m05, m06, m07, m08, m09, m10, m11, m12, m13, m14, m15); + set(m00, m01, m02, m03, m04, m05, m06, m07, m08, m09, m10, m11, m12, m13, m14, m15); } - - inline void Matrix4::set(const float src[16]) { - m[0] = src[0]; m[1] = src[1]; m[2] = src[2]; m[3] = src[3]; - m[4] = src[4]; m[5] = src[5]; m[6] = src[6]; m[7] = src[7]; - m[8] = src[8]; m[9] = src[9]; m[10]= src[10]; m[11]= src[11]; - m[12]= src[12]; m[13]= src[13]; m[14]= src[14]; m[15]= src[15]; + m[0] = src[0]; + m[1] = src[1]; + m[2] = src[2]; + m[3] = src[3]; + m[4] = src[4]; + m[5] = src[5]; + m[6] = src[6]; + m[7] = src[7]; + m[8] = src[8]; + m[9] = src[9]; + m[10] = src[10]; + m[11] = src[11]; + m[12] = src[12]; + m[13] = src[13]; + m[14] = src[14]; + m[15] = src[15]; } - - inline void Matrix4::set(float m00, float m01, float m02, float m03, - float m04, float m05, float m06, float m07, - float m08, float m09, float m10, float m11, - float m12, float m13, float m14, float m15) + float m04, float m05, float m06, float m07, + float m08, float m09, float m10, float m11, + float m12, float m13, float m14, float m15) { - m[0] = m00; m[1] = m01; m[2] = m02; m[3] = m03; - m[4] = m04; m[5] = m05; m[6] = m06; m[7] = m07; - m[8] = m08; m[9] = m09; m[10]= m10; m[11]= m11; - m[12]= m12; m[13]= m13; m[14]= m14; m[15]= m15; + m[0] = m00; + m[1] = m01; + m[2] = m02; + m[3] = m03; + m[4] = m04; + m[5] = m05; + m[6] = m06; + m[7] = m07; + m[8] = m08; + m[9] = m09; + m[10] = m10; + m[11] = m11; + m[12] = m12; + m[13] = m13; + m[14] = m14; + m[15] = m15; } - - inline void Matrix4::setRow(int index, const float row[4]) { - m[index] = row[0]; m[index + 4] = row[1]; m[index + 8] = row[2]; m[index + 12] = row[3]; + m[index] = row[0]; + m[index + 4] = row[1]; + m[index + 8] = row[2]; + m[index + 12] = row[3]; } - - inline void Matrix4::setRow(int index, const Vector4& v) { - m[index] = v.x; m[index + 4] = v.y; m[index + 8] = v.z; m[index + 12] = v.w; + m[index] = v.x; + m[index + 4] = v.y; + m[index + 8] = v.z; + m[index + 12] = v.w; } - - inline void Matrix4::setRow(int index, const Vector3& v) { - m[index] = v.x; m[index + 4] = v.y; m[index + 8] = v.z; + m[index] = v.x; + m[index + 4] = v.y; + m[index + 8] = v.z; } - - inline void Matrix4::setColumn(int index, const float col[4]) { - m[index*4] = col[0]; m[index*4 + 1] = col[1]; m[index*4 + 2] = col[2]; m[index*4 + 3] = col[3]; + m[index * 4] = col[0]; + m[index * 4 + 1] = col[1]; + m[index * 4 + 2] = col[2]; + m[index * 4 + 3] = col[3]; } - - inline void Matrix4::setColumn(int index, const Vector4& v) { - m[index*4] = v.x; m[index*4 + 1] = v.y; m[index*4 + 2] = v.z; m[index*4 + 3] = v.w; + m[index * 4] = v.x; + m[index * 4 + 1] = v.y; + m[index * 4 + 2] = v.z; + m[index * 4 + 3] = v.w; } - - inline void Matrix4::setColumn(int index, const Vector3& v) { - m[index*4] = v.x; m[index*4 + 1] = v.y; m[index*4 + 2] = v.z; + m[index * 4] = v.x; + m[index * 4 + 1] = v.y; + m[index * 4 + 2] = v.z; } - - inline const float* Matrix4::get() const { - return m; + return m; } - - inline const float* Matrix4::getTranspose() { - tm[0] = m[0]; tm[1] = m[4]; tm[2] = m[8]; tm[3] = m[12]; - tm[4] = m[1]; tm[5] = m[5]; tm[6] = m[9]; tm[7] = m[13]; - tm[8] = m[2]; tm[9] = m[6]; tm[10]= m[10]; tm[11]= m[14]; - tm[12]= m[3]; tm[13]= m[7]; tm[14]= m[11]; tm[15]= m[15]; - return tm; + tm[0] = m[0]; + tm[1] = m[4]; + tm[2] = m[8]; + tm[3] = m[12]; + tm[4] = m[1]; + tm[5] = m[5]; + tm[6] = m[9]; + tm[7] = m[13]; + tm[8] = m[2]; + tm[9] = m[6]; + tm[10] = m[10]; + tm[11] = m[14]; + tm[12] = m[3]; + tm[13] = m[7]; + tm[14] = m[11]; + tm[15] = m[15]; + return tm; } - - inline Matrix4& Matrix4::identity() { - m[0] = m[5] = m[10] = m[15] = 1.0f; - m[1] = m[2] = m[3] = m[4] = m[6] = m[7] = m[8] = m[9] = m[11] = m[12] = m[13] = m[14] = 0.0f; - return *this; + m[0] = m[5] = m[10] = m[15] = 1.0f; + m[1] = m[2] = m[3] = m[4] = m[6] = m[7] = m[8] = m[9] = m[11] = m[12] = m[13] = m[14] = 0.0f; + return *this; } - - inline Matrix4 Matrix4::operator+(const Matrix4& rhs) const { - return Matrix4(m[0]+rhs[0], m[1]+rhs[1], m[2]+rhs[2], m[3]+rhs[3], - m[4]+rhs[4], m[5]+rhs[5], m[6]+rhs[6], m[7]+rhs[7], - m[8]+rhs[8], m[9]+rhs[9], m[10]+rhs[10], m[11]+rhs[11], - m[12]+rhs[12], m[13]+rhs[13], m[14]+rhs[14], m[15]+rhs[15]); + return Matrix4(m[0] + rhs[0], m[1] + rhs[1], m[2] + rhs[2], m[3] + rhs[3], + m[4] + rhs[4], m[5] + rhs[5], m[6] + rhs[6], m[7] + rhs[7], + m[8] + rhs[8], m[9] + rhs[9], m[10] + rhs[10], m[11] + rhs[11], + m[12] + rhs[12], m[13] + rhs[13], m[14] + rhs[14], m[15] + rhs[15]); } - - inline Matrix4 Matrix4::operator-(const Matrix4& rhs) const { - return Matrix4(m[0]-rhs[0], m[1]-rhs[1], m[2]-rhs[2], m[3]-rhs[3], - m[4]-rhs[4], m[5]-rhs[5], m[6]-rhs[6], m[7]-rhs[7], - m[8]-rhs[8], m[9]-rhs[9], m[10]-rhs[10], m[11]-rhs[11], - m[12]-rhs[12], m[13]-rhs[13], m[14]-rhs[14], m[15]-rhs[15]); + return Matrix4(m[0] - rhs[0], m[1] - rhs[1], m[2] - rhs[2], m[3] - rhs[3], + m[4] - rhs[4], m[5] - rhs[5], m[6] - rhs[6], m[7] - rhs[7], + m[8] - rhs[8], m[9] - rhs[9], m[10] - rhs[10], m[11] - rhs[11], + m[12] - rhs[12], m[13] - rhs[13], m[14] - rhs[14], m[15] - rhs[15]); } - - inline Matrix4& Matrix4::operator+=(const Matrix4& rhs) { - m[0] += rhs[0]; m[1] += rhs[1]; m[2] += rhs[2]; m[3] += rhs[3]; - m[4] += rhs[4]; m[5] += rhs[5]; m[6] += rhs[6]; m[7] += rhs[7]; - m[8] += rhs[8]; m[9] += rhs[9]; m[10]+= rhs[10]; m[11]+= rhs[11]; - m[12]+= rhs[12]; m[13]+= rhs[13]; m[14]+= rhs[14]; m[15]+= rhs[15]; - return *this; + m[0] += rhs[0]; + m[1] += rhs[1]; + m[2] += rhs[2]; + m[3] += rhs[3]; + m[4] += rhs[4]; + m[5] += rhs[5]; + m[6] += rhs[6]; + m[7] += rhs[7]; + m[8] += rhs[8]; + m[9] += rhs[9]; + m[10] += rhs[10]; + m[11] += rhs[11]; + m[12] += rhs[12]; + m[13] += rhs[13]; + m[14] += rhs[14]; + m[15] += rhs[15]; + return *this; } - - inline Matrix4& Matrix4::operator-=(const Matrix4& rhs) { - m[0] -= rhs[0]; m[1] -= rhs[1]; m[2] -= rhs[2]; m[3] -= rhs[3]; - m[4] -= rhs[4]; m[5] -= rhs[5]; m[6] -= rhs[6]; m[7] -= rhs[7]; - m[8] -= rhs[8]; m[9] -= rhs[9]; m[10]-= rhs[10]; m[11]-= rhs[11]; - m[12]-= rhs[12]; m[13]-= rhs[13]; m[14]-= rhs[14]; m[15]-= rhs[15]; - return *this; + m[0] -= rhs[0]; + m[1] -= rhs[1]; + m[2] -= rhs[2]; + m[3] -= rhs[3]; + m[4] -= rhs[4]; + m[5] -= rhs[5]; + m[6] -= rhs[6]; + m[7] -= rhs[7]; + m[8] -= rhs[8]; + m[9] -= rhs[9]; + m[10] -= rhs[10]; + m[11] -= rhs[11]; + m[12] -= rhs[12]; + m[13] -= rhs[13]; + m[14] -= rhs[14]; + m[15] -= rhs[15]; + return *this; } - - inline Vector4 Matrix4::operator*(const Vector4& rhs) const { - return Vector4(m[0]*rhs.x + m[4]*rhs.y + m[8]*rhs.z + m[12]*rhs.w, - m[1]*rhs.x + m[5]*rhs.y + m[9]*rhs.z + m[13]*rhs.w, - m[2]*rhs.x + m[6]*rhs.y + m[10]*rhs.z + m[14]*rhs.w, - m[3]*rhs.x + m[7]*rhs.y + m[11]*rhs.z + m[15]*rhs.w); + return Vector4(m[0] * rhs.x + m[4] * rhs.y + m[8] * rhs.z + m[12] * rhs.w, + m[1] * rhs.x + m[5] * rhs.y + m[9] * rhs.z + m[13] * rhs.w, + m[2] * rhs.x + m[6] * rhs.y + m[10] * rhs.z + m[14] * rhs.w, + m[3] * rhs.x + m[7] * rhs.y + m[11] * rhs.z + m[15] * rhs.w); } - - inline Vector3 Matrix4::operator*(const Vector3& rhs) const { - return Vector3(m[0]*rhs.x + m[4]*rhs.y + m[8]*rhs.z, - m[1]*rhs.x + m[5]*rhs.y + m[9]*rhs.z, - m[2]*rhs.x + m[6]*rhs.y + m[10]*rhs.z); + return Vector3(m[0] * rhs.x + m[4] * rhs.y + m[8] * rhs.z, + m[1] * rhs.x + m[5] * rhs.y + m[9] * rhs.z, + m[2] * rhs.x + m[6] * rhs.y + m[10] * rhs.z); } - - inline Matrix4 Matrix4::operator*(const Matrix4& n) const { - return Matrix4(m[0]*n[0] + m[4]*n[1] + m[8]*n[2] + m[12]*n[3], m[1]*n[0] + m[5]*n[1] + m[9]*n[2] + m[13]*n[3], m[2]*n[0] + m[6]*n[1] + m[10]*n[2] + m[14]*n[3], m[3]*n[0] + m[7]*n[1] + m[11]*n[2] + m[15]*n[3], - m[0]*n[4] + m[4]*n[5] + m[8]*n[6] + m[12]*n[7], m[1]*n[4] + m[5]*n[5] + m[9]*n[6] + m[13]*n[7], m[2]*n[4] + m[6]*n[5] + m[10]*n[6] + m[14]*n[7], m[3]*n[4] + m[7]*n[5] + m[11]*n[6] + m[15]*n[7], - m[0]*n[8] + m[4]*n[9] + m[8]*n[10] + m[12]*n[11], m[1]*n[8] + m[5]*n[9] + m[9]*n[10] + m[13]*n[11], m[2]*n[8] + m[6]*n[9] + m[10]*n[10] + m[14]*n[11], m[3]*n[8] + m[7]*n[9] + m[11]*n[10] + m[15]*n[11], - m[0]*n[12] + m[4]*n[13] + m[8]*n[14] + m[12]*n[15], m[1]*n[12] + m[5]*n[13] + m[9]*n[14] + m[13]*n[15], m[2]*n[12] + m[6]*n[13] + m[10]*n[14] + m[14]*n[15], m[3]*n[12] + m[7]*n[13] + m[11]*n[14] + m[15]*n[15]); + return Matrix4(m[0] * n[0] + m[4] * n[1] + m[8] * n[2] + m[12] * n[3], m[1] * n[0] + m[5] * n[1] + m[9] * n[2] + m[13] * n[3], m[2] * n[0] + m[6] * n[1] + m[10] * n[2] + m[14] * n[3], m[3] * n[0] + m[7] * n[1] + m[11] * n[2] + m[15] * n[3], + m[0] * n[4] + m[4] * n[5] + m[8] * n[6] + m[12] * n[7], m[1] * n[4] + m[5] * n[5] + m[9] * n[6] + m[13] * n[7], m[2] * n[4] + m[6] * n[5] + m[10] * n[6] + m[14] * n[7], m[3] * n[4] + m[7] * n[5] + m[11] * n[6] + m[15] * n[7], + m[0] * n[8] + m[4] * n[9] + m[8] * n[10] + m[12] * n[11], m[1] * n[8] + m[5] * n[9] + m[9] * n[10] + m[13] * n[11], m[2] * n[8] + m[6] * n[9] + m[10] * n[10] + m[14] * n[11], m[3] * n[8] + m[7] * n[9] + m[11] * n[10] + m[15] * n[11], + m[0] * n[12] + m[4] * n[13] + m[8] * n[14] + m[12] * n[15], m[1] * n[12] + m[5] * n[13] + m[9] * n[14] + m[13] * n[15], m[2] * n[12] + m[6] * n[13] + m[10] * n[14] + m[14] * n[15], m[3] * n[12] + m[7] * n[13] + m[11] * n[14] + m[15] * n[15]); } - - inline Matrix4& Matrix4::operator*=(const Matrix4& rhs) { - *this = *this * rhs; - return *this; + *this = *this * rhs; + return *this; } - - inline bool Matrix4::operator==(const Matrix4& n) const { - return (m[0] == n[0]) && (m[1] == n[1]) && (m[2] == n[2]) && (m[3] == n[3]) && - (m[4] == n[4]) && (m[5] == n[5]) && (m[6] == n[6]) && (m[7] == n[7]) && - (m[8] == n[8]) && (m[9] == n[9]) && (m[10]== n[10]) && (m[11]== n[11]) && - (m[12]== n[12]) && (m[13]== n[13]) && (m[14]== n[14]) && (m[15]== n[15]); + return (m[0] == n[0]) && (m[1] == n[1]) && (m[2] == n[2]) && (m[3] == n[3]) && + (m[4] == n[4]) && (m[5] == n[5]) && (m[6] == n[6]) && (m[7] == n[7]) && + (m[8] == n[8]) && (m[9] == n[9]) && (m[10] == n[10]) && (m[11] == n[11]) && + (m[12] == n[12]) && (m[13] == n[13]) && (m[14] == n[14]) && (m[15] == n[15]); } - - inline bool Matrix4::operator!=(const Matrix4& n) const { - return (m[0] != n[0]) || (m[1] != n[1]) || (m[2] != n[2]) || (m[3] != n[3]) || - (m[4] != n[4]) || (m[5] != n[5]) || (m[6] != n[6]) || (m[7] != n[7]) || - (m[8] != n[8]) || (m[9] != n[9]) || (m[10]!= n[10]) || (m[11]!= n[11]) || - (m[12]!= n[12]) || (m[13]!= n[13]) || (m[14]!= n[14]) || (m[15]!= n[15]); + return (m[0] != n[0]) || (m[1] != n[1]) || (m[2] != n[2]) || (m[3] != n[3]) || + (m[4] != n[4]) || (m[5] != n[5]) || (m[6] != n[6]) || (m[7] != n[7]) || + (m[8] != n[8]) || (m[9] != n[9]) || (m[10] != n[10]) || (m[11] != n[11]) || + (m[12] != n[12]) || (m[13] != n[13]) || (m[14] != n[14]) || (m[15] != n[15]); } - - inline float Matrix4::operator[](int index) const { - return m[index]; + return m[index]; } - - inline float& Matrix4::operator[](int index) { - return m[index]; + return m[index]; } - - inline Matrix4 operator-(const Matrix4& rhs) { - return Matrix4(-rhs[0], -rhs[1], -rhs[2], -rhs[3], -rhs[4], -rhs[5], -rhs[6], -rhs[7], -rhs[8], -rhs[9], -rhs[10], -rhs[11], -rhs[12], -rhs[13], -rhs[14], -rhs[15]); + return Matrix4(-rhs[0], -rhs[1], -rhs[2], -rhs[3], -rhs[4], -rhs[5], -rhs[6], -rhs[7], -rhs[8], -rhs[9], -rhs[10], -rhs[11], -rhs[12], -rhs[13], -rhs[14], -rhs[15]); } - - inline Matrix4 operator*(float s, const Matrix4& rhs) { - return Matrix4(s*rhs[0], s*rhs[1], s*rhs[2], s*rhs[3], s*rhs[4], s*rhs[5], s*rhs[6], s*rhs[7], s*rhs[8], s*rhs[9], s*rhs[10], s*rhs[11], s*rhs[12], s*rhs[13], s*rhs[14], s*rhs[15]); + return Matrix4(s * rhs[0], s * rhs[1], s * rhs[2], s * rhs[3], s * rhs[4], s * rhs[5], s * rhs[6], s * rhs[7], s * rhs[8], s * rhs[9], s * rhs[10], s * rhs[11], s * rhs[12], s * rhs[13], s * rhs[14], s * rhs[15]); } - - inline Vector4 operator*(const Vector4& v, const Matrix4& m) { - return Vector4(v.x*m[0] + v.y*m[1] + v.z*m[2] + v.w*m[3], v.x*m[4] + v.y*m[5] + v.z*m[6] + v.w*m[7], v.x*m[8] + v.y*m[9] + v.z*m[10] + v.w*m[11], v.x*m[12] + v.y*m[13] + v.z*m[14] + v.w*m[15]); + return Vector4(v.x * m[0] + v.y * m[1] + v.z * m[2] + v.w * m[3], v.x * m[4] + v.y * m[5] + v.z * m[6] + v.w * m[7], v.x * m[8] + v.y * m[9] + v.z * m[10] + v.w * m[11], v.x * m[12] + v.y * m[13] + v.z * m[14] + v.w * m[15]); } - - inline Vector3 operator*(const Vector3& v, const Matrix4& m) { - return Vector3(v.x*m[0] + v.y*m[1] + v.z*m[2], v.x*m[4] + v.y*m[5] + v.z*m[6], v.x*m[8] + v.y*m[9] + v.z*m[10]); + return Vector3(v.x * m[0] + v.y * m[1] + v.z * m[2], v.x * m[4] + v.y * m[5] + v.z * m[6], v.x * m[8] + v.y * m[9] + v.z * m[10]); } - - inline std::ostream& operator<<(std::ostream& os, const Matrix4& m) { - os << std::fixed << std::setprecision(5); - os << "[" << std::setw(10) << m[0] << " " << std::setw(10) << m[4] << " " << std::setw(10) << m[8] << " " << std::setw(10) << m[12] << "]\n" - << "[" << std::setw(10) << m[1] << " " << std::setw(10) << m[5] << " " << std::setw(10) << m[9] << " " << std::setw(10) << m[13] << "]\n" - << "[" << std::setw(10) << m[2] << " " << std::setw(10) << m[6] << " " << std::setw(10) << m[10] << " " << std::setw(10) << m[14] << "]\n" - << "[" << std::setw(10) << m[3] << " " << std::setw(10) << m[7] << " " << std::setw(10) << m[11] << " " << std::setw(10) << m[15] << "]\n"; - os << std::resetiosflags(std::ios_base::fixed | std::ios_base::floatfield); - return os; + os << std::fixed << std::setprecision(5); + os << "[" << std::setw(10) << m[0] << " " << std::setw(10) << m[4] << " " << std::setw(10) << m[8] << " " << std::setw(10) << m[12] << "]\n" + << "[" << std::setw(10) << m[1] << " " << std::setw(10) << m[5] << " " << std::setw(10) << m[9] << " " << std::setw(10) << m[13] << "]\n" + << "[" << std::setw(10) << m[2] << " " << std::setw(10) << m[6] << " " << std::setw(10) << m[10] << " " << std::setw(10) << m[14] << "]\n" + << "[" << std::setw(10) << m[3] << " " << std::setw(10) << m[7] << " " << std::setw(10) << m[11] << " " << std::setw(10) << m[15] << "]\n"; + os << std::resetiosflags(std::ios_base::fixed | std::ios_base::floatfield); + return os; } // END OF MATRIX4 INLINE ////////////////////////////////////////////////////// #endif diff --git a/examples/ThirdPartyLibs/openvr/samples/shared/Vectors.h b/examples/ThirdPartyLibs/openvr/samples/shared/Vectors.h index 2e08103c4..f0b346c9f 100644 --- a/examples/ThirdPartyLibs/openvr/samples/shared/Vectors.h +++ b/examples/ThirdPartyLibs/openvr/samples/shared/Vectors.h @@ -10,7 +10,6 @@ // Copyright (C) 2007-2013 Song Ho Ahn /////////////////////////////////////////////////////////////////////////////// - #ifndef VECTORS_H_DEF #define VECTORS_H_DEF @@ -22,508 +21,619 @@ /////////////////////////////////////////////////////////////////////////////// struct Vector2 { - float x; - float y; + float x; + float y; - // ctors - Vector2() : x(0), y(0) {}; - Vector2(float x, float y) : x(x), y(y) {}; + // ctors + Vector2() : x(0), y(0){}; + Vector2(float x, float y) : x(x), y(y){}; - // utils functions - void set(float x, float y); - float length() const; // - float distance(const Vector2& vec) const; // distance between two vectors - Vector2& normalize(); // - float dot(const Vector2& vec) const; // dot product - bool equal(const Vector2& vec, float e) const; // compare with epsilon + // utils functions + void set(float x, float y); + float length() const; // + float distance(const Vector2& vec) const; // distance between two vectors + Vector2& normalize(); // + float dot(const Vector2& vec) const; // dot product + bool equal(const Vector2& vec, float e) const; // compare with epsilon - // operators - Vector2 operator-() const; // unary operator (negate) - Vector2 operator+(const Vector2& rhs) const; // add rhs - Vector2 operator-(const Vector2& rhs) const; // subtract rhs - Vector2& operator+=(const Vector2& rhs); // add rhs and update this object - Vector2& operator-=(const Vector2& rhs); // subtract rhs and update this object - Vector2 operator*(const float scale) const; // scale - Vector2 operator*(const Vector2& rhs) const; // multiply each element - Vector2& operator*=(const float scale); // scale and update this object - Vector2& operator*=(const Vector2& rhs); // multiply each element and update this object - Vector2 operator/(const float scale) const; // inverse scale - Vector2& operator/=(const float scale); // scale and update this object - bool operator==(const Vector2& rhs) const; // exact compare, no epsilon - bool operator!=(const Vector2& rhs) const; // exact compare, no epsilon - bool operator<(const Vector2& rhs) const; // comparison for sort - float operator[](int index) const; // subscript operator v[0], v[1] - float& operator[](int index); // subscript operator v[0], v[1] + // operators + Vector2 operator-() const; // unary operator (negate) + Vector2 operator+(const Vector2& rhs) const; // add rhs + Vector2 operator-(const Vector2& rhs) const; // subtract rhs + Vector2& operator+=(const Vector2& rhs); // add rhs and update this object + Vector2& operator-=(const Vector2& rhs); // subtract rhs and update this object + Vector2 operator*(const float scale) const; // scale + Vector2 operator*(const Vector2& rhs) const; // multiply each element + Vector2& operator*=(const float scale); // scale and update this object + Vector2& operator*=(const Vector2& rhs); // multiply each element and update this object + Vector2 operator/(const float scale) const; // inverse scale + Vector2& operator/=(const float scale); // scale and update this object + bool operator==(const Vector2& rhs) const; // exact compare, no epsilon + bool operator!=(const Vector2& rhs) const; // exact compare, no epsilon + bool operator<(const Vector2& rhs) const; // comparison for sort + float operator[](int index) const; // subscript operator v[0], v[1] + float& operator[](int index); // subscript operator v[0], v[1] - friend Vector2 operator*(const float a, const Vector2 vec); - friend std::ostream& operator<<(std::ostream& os, const Vector2& vec); + friend Vector2 operator*(const float a, const Vector2 vec); + friend std::ostream& operator<<(std::ostream& os, const Vector2& vec); }; - - /////////////////////////////////////////////////////////////////////////////// // 3D vector /////////////////////////////////////////////////////////////////////////////// struct Vector3 { - float x; - float y; - float z; + float x; + float y; + float z; - // ctors - Vector3() : x(0), y(0), z(0) {}; - Vector3(float x, float y, float z) : x(x), y(y), z(z) {}; + // ctors + Vector3() : x(0), y(0), z(0){}; + Vector3(float x, float y, float z) : x(x), y(y), z(z){}; - // utils functions - void set(float x, float y, float z); - float length() const; // - float distance(const Vector3& vec) const; // distance between two vectors - Vector3& normalize(); // - float dot(const Vector3& vec) const; // dot product - Vector3 cross(const Vector3& vec) const; // cross product - bool equal(const Vector3& vec, float e) const; // compare with epsilon + // utils functions + void set(float x, float y, float z); + float length() const; // + float distance(const Vector3& vec) const; // distance between two vectors + Vector3& normalize(); // + float dot(const Vector3& vec) const; // dot product + Vector3 cross(const Vector3& vec) const; // cross product + bool equal(const Vector3& vec, float e) const; // compare with epsilon - // operators - Vector3 operator-() const; // unary operator (negate) - Vector3 operator+(const Vector3& rhs) const; // add rhs - Vector3 operator-(const Vector3& rhs) const; // subtract rhs - Vector3& operator+=(const Vector3& rhs); // add rhs and update this object - Vector3& operator-=(const Vector3& rhs); // subtract rhs and update this object - Vector3 operator*(const float scale) const; // scale - Vector3 operator*(const Vector3& rhs) const; // multiplay each element - Vector3& operator*=(const float scale); // scale and update this object - Vector3& operator*=(const Vector3& rhs); // product each element and update this object - Vector3 operator/(const float scale) const; // inverse scale - Vector3& operator/=(const float scale); // scale and update this object - bool operator==(const Vector3& rhs) const; // exact compare, no epsilon - bool operator!=(const Vector3& rhs) const; // exact compare, no epsilon - bool operator<(const Vector3& rhs) const; // comparison for sort - float operator[](int index) const; // subscript operator v[0], v[1] - float& operator[](int index); // subscript operator v[0], v[1] + // operators + Vector3 operator-() const; // unary operator (negate) + Vector3 operator+(const Vector3& rhs) const; // add rhs + Vector3 operator-(const Vector3& rhs) const; // subtract rhs + Vector3& operator+=(const Vector3& rhs); // add rhs and update this object + Vector3& operator-=(const Vector3& rhs); // subtract rhs and update this object + Vector3 operator*(const float scale) const; // scale + Vector3 operator*(const Vector3& rhs) const; // multiplay each element + Vector3& operator*=(const float scale); // scale and update this object + Vector3& operator*=(const Vector3& rhs); // product each element and update this object + Vector3 operator/(const float scale) const; // inverse scale + Vector3& operator/=(const float scale); // scale and update this object + bool operator==(const Vector3& rhs) const; // exact compare, no epsilon + bool operator!=(const Vector3& rhs) const; // exact compare, no epsilon + bool operator<(const Vector3& rhs) const; // comparison for sort + float operator[](int index) const; // subscript operator v[0], v[1] + float& operator[](int index); // subscript operator v[0], v[1] - friend Vector3 operator*(const float a, const Vector3 vec); - friend std::ostream& operator<<(std::ostream& os, const Vector3& vec); + friend Vector3 operator*(const float a, const Vector3 vec); + friend std::ostream& operator<<(std::ostream& os, const Vector3& vec); }; - - /////////////////////////////////////////////////////////////////////////////// // 4D vector /////////////////////////////////////////////////////////////////////////////// struct Vector4 { - float x; - float y; - float z; - float w; + float x; + float y; + float z; + float w; - // ctors - Vector4() : x(0), y(0), z(0), w(0) {}; - Vector4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) {}; + // ctors + Vector4() : x(0), y(0), z(0), w(0){}; + Vector4(float x, float y, float z, float w) : x(x), y(y), z(z), w(w){}; - // utils functions - void set(float x, float y, float z, float w); - float length() const; // - float distance(const Vector4& vec) const; // distance between two vectors - Vector4& normalize(); // - float dot(const Vector4& vec) const; // dot product - bool equal(const Vector4& vec, float e) const; // compare with epsilon + // utils functions + void set(float x, float y, float z, float w); + float length() const; // + float distance(const Vector4& vec) const; // distance between two vectors + Vector4& normalize(); // + float dot(const Vector4& vec) const; // dot product + bool equal(const Vector4& vec, float e) const; // compare with epsilon - // operators - Vector4 operator-() const; // unary operator (negate) - Vector4 operator+(const Vector4& rhs) const; // add rhs - Vector4 operator-(const Vector4& rhs) const; // subtract rhs - Vector4& operator+=(const Vector4& rhs); // add rhs and update this object - Vector4& operator-=(const Vector4& rhs); // subtract rhs and update this object - Vector4 operator*(const float scale) const; // scale - Vector4 operator*(const Vector4& rhs) const; // multiply each element - Vector4& operator*=(const float scale); // scale and update this object - Vector4& operator*=(const Vector4& rhs); // multiply each element and update this object - Vector4 operator/(const float scale) const; // inverse scale - Vector4& operator/=(const float scale); // scale and update this object - bool operator==(const Vector4& rhs) const; // exact compare, no epsilon - bool operator!=(const Vector4& rhs) const; // exact compare, no epsilon - bool operator<(const Vector4& rhs) const; // comparison for sort - float operator[](int index) const; // subscript operator v[0], v[1] - float& operator[](int index); // subscript operator v[0], v[1] + // operators + Vector4 operator-() const; // unary operator (negate) + Vector4 operator+(const Vector4& rhs) const; // add rhs + Vector4 operator-(const Vector4& rhs) const; // subtract rhs + Vector4& operator+=(const Vector4& rhs); // add rhs and update this object + Vector4& operator-=(const Vector4& rhs); // subtract rhs and update this object + Vector4 operator*(const float scale) const; // scale + Vector4 operator*(const Vector4& rhs) const; // multiply each element + Vector4& operator*=(const float scale); // scale and update this object + Vector4& operator*=(const Vector4& rhs); // multiply each element and update this object + Vector4 operator/(const float scale) const; // inverse scale + Vector4& operator/=(const float scale); // scale and update this object + bool operator==(const Vector4& rhs) const; // exact compare, no epsilon + bool operator!=(const Vector4& rhs) const; // exact compare, no epsilon + bool operator<(const Vector4& rhs) const; // comparison for sort + float operator[](int index) const; // subscript operator v[0], v[1] + float& operator[](int index); // subscript operator v[0], v[1] - friend Vector4 operator*(const float a, const Vector4 vec); - friend std::ostream& operator<<(std::ostream& os, const Vector4& vec); + friend Vector4 operator*(const float a, const Vector4 vec); + friend std::ostream& operator<<(std::ostream& os, const Vector4& vec); }; - - // fast math routines from Doom3 SDK inline float invSqrt(float x) { - float xhalf = 0.5f * x; - int i = *(int*)&x; // get bits for floating value - i = 0x5f3759df - (i>>1); // gives initial guess - x = *(float*)&i; // convert bits back to float - x = x * (1.5f - xhalf*x*x); // Newton step - return x; + float xhalf = 0.5f * x; + int i = *(int*)&x; // get bits for floating value + i = 0x5f3759df - (i >> 1); // gives initial guess + x = *(float*)&i; // convert bits back to float + x = x * (1.5f - xhalf * x * x); // Newton step + return x; } - - /////////////////////////////////////////////////////////////////////////////// // inline functions for Vector2 /////////////////////////////////////////////////////////////////////////////// -inline Vector2 Vector2::operator-() const { - return Vector2(-x, -y); +inline Vector2 Vector2::operator-() const +{ + return Vector2(-x, -y); } -inline Vector2 Vector2::operator+(const Vector2& rhs) const { - return Vector2(x+rhs.x, y+rhs.y); +inline Vector2 Vector2::operator+(const Vector2& rhs) const +{ + return Vector2(x + rhs.x, y + rhs.y); } -inline Vector2 Vector2::operator-(const Vector2& rhs) const { - return Vector2(x-rhs.x, y-rhs.y); +inline Vector2 Vector2::operator-(const Vector2& rhs) const +{ + return Vector2(x - rhs.x, y - rhs.y); } -inline Vector2& Vector2::operator+=(const Vector2& rhs) { - x += rhs.x; y += rhs.y; return *this; +inline Vector2& Vector2::operator+=(const Vector2& rhs) +{ + x += rhs.x; + y += rhs.y; + return *this; } -inline Vector2& Vector2::operator-=(const Vector2& rhs) { - x -= rhs.x; y -= rhs.y; return *this; +inline Vector2& Vector2::operator-=(const Vector2& rhs) +{ + x -= rhs.x; + y -= rhs.y; + return *this; } -inline Vector2 Vector2::operator*(const float a) const { - return Vector2(x*a, y*a); +inline Vector2 Vector2::operator*(const float a) const +{ + return Vector2(x * a, y * a); } -inline Vector2 Vector2::operator*(const Vector2& rhs) const { - return Vector2(x*rhs.x, y*rhs.y); +inline Vector2 Vector2::operator*(const Vector2& rhs) const +{ + return Vector2(x * rhs.x, y * rhs.y); } -inline Vector2& Vector2::operator*=(const float a) { - x *= a; y *= a; return *this; +inline Vector2& Vector2::operator*=(const float a) +{ + x *= a; + y *= a; + return *this; } -inline Vector2& Vector2::operator*=(const Vector2& rhs) { - x *= rhs.x; y *= rhs.y; return *this; +inline Vector2& Vector2::operator*=(const Vector2& rhs) +{ + x *= rhs.x; + y *= rhs.y; + return *this; } -inline Vector2 Vector2::operator/(const float a) const { - return Vector2(x/a, y/a); +inline Vector2 Vector2::operator/(const float a) const +{ + return Vector2(x / a, y / a); } -inline Vector2& Vector2::operator/=(const float a) { - x /= a; y /= a; return *this; +inline Vector2& Vector2::operator/=(const float a) +{ + x /= a; + y /= a; + return *this; } -inline bool Vector2::operator==(const Vector2& rhs) const { - return (x == rhs.x) && (y == rhs.y); +inline bool Vector2::operator==(const Vector2& rhs) const +{ + return (x == rhs.x) && (y == rhs.y); } -inline bool Vector2::operator!=(const Vector2& rhs) const { - return (x != rhs.x) || (y != rhs.y); +inline bool Vector2::operator!=(const Vector2& rhs) const +{ + return (x != rhs.x) || (y != rhs.y); } -inline bool Vector2::operator<(const Vector2& rhs) const { - if(x < rhs.x) return true; - if(x > rhs.x) return false; - if(y < rhs.y) return true; - if(y > rhs.y) return false; - return false; +inline bool Vector2::operator<(const Vector2& rhs) const +{ + if (x < rhs.x) return true; + if (x > rhs.x) return false; + if (y < rhs.y) return true; + if (y > rhs.y) return false; + return false; } -inline float Vector2::operator[](int index) const { - return (&x)[index]; +inline float Vector2::operator[](int index) const +{ + return (&x)[index]; } -inline float& Vector2::operator[](int index) { - return (&x)[index]; +inline float& Vector2::operator[](int index) +{ + return (&x)[index]; } -inline void Vector2::set(float x, float y) { - this->x = x; this->y = y; +inline void Vector2::set(float x, float y) +{ + this->x = x; + this->y = y; } -inline float Vector2::length() const { - return sqrtf(x*x + y*y); +inline float Vector2::length() const +{ + return sqrtf(x * x + y * y); } -inline float Vector2::distance(const Vector2& vec) const { - return sqrtf((vec.x-x)*(vec.x-x) + (vec.y-y)*(vec.y-y)); +inline float Vector2::distance(const Vector2& vec) const +{ + return sqrtf((vec.x - x) * (vec.x - x) + (vec.y - y) * (vec.y - y)); } -inline Vector2& Vector2::normalize() { - //@@const float EPSILON = 0.000001f; - float xxyy = x*x + y*y; - //@@if(xxyy < EPSILON) - //@@ return *this; +inline Vector2& Vector2::normalize() +{ + //@@const float EPSILON = 0.000001f; + float xxyy = x * x + y * y; + //@@if(xxyy < EPSILON) + //@@ return *this; - //float invLength = invSqrt(xxyy); - float invLength = 1.0f / sqrtf(xxyy); - x *= invLength; - y *= invLength; - return *this; + //float invLength = invSqrt(xxyy); + float invLength = 1.0f / sqrtf(xxyy); + x *= invLength; + y *= invLength; + return *this; } -inline float Vector2::dot(const Vector2& rhs) const { - return (x*rhs.x + y*rhs.y); +inline float Vector2::dot(const Vector2& rhs) const +{ + return (x * rhs.x + y * rhs.y); } -inline bool Vector2::equal(const Vector2& rhs, float epsilon) const { - return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon; +inline bool Vector2::equal(const Vector2& rhs, float epsilon) const +{ + return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon; } -inline Vector2 operator*(const float a, const Vector2 vec) { - return Vector2(a*vec.x, a*vec.y); +inline Vector2 operator*(const float a, const Vector2 vec) +{ + return Vector2(a * vec.x, a * vec.y); } -inline std::ostream& operator<<(std::ostream& os, const Vector2& vec) { - os << "(" << vec.x << ", " << vec.y << ")"; - return os; +inline std::ostream& operator<<(std::ostream& os, const Vector2& vec) +{ + os << "(" << vec.x << ", " << vec.y << ")"; + return os; } // END OF VECTOR2 ///////////////////////////////////////////////////////////// - - - /////////////////////////////////////////////////////////////////////////////// // inline functions for Vector3 /////////////////////////////////////////////////////////////////////////////// -inline Vector3 Vector3::operator-() const { - return Vector3(-x, -y, -z); +inline Vector3 Vector3::operator-() const +{ + return Vector3(-x, -y, -z); } -inline Vector3 Vector3::operator+(const Vector3& rhs) const { - return Vector3(x+rhs.x, y+rhs.y, z+rhs.z); +inline Vector3 Vector3::operator+(const Vector3& rhs) const +{ + return Vector3(x + rhs.x, y + rhs.y, z + rhs.z); } -inline Vector3 Vector3::operator-(const Vector3& rhs) const { - return Vector3(x-rhs.x, y-rhs.y, z-rhs.z); +inline Vector3 Vector3::operator-(const Vector3& rhs) const +{ + return Vector3(x - rhs.x, y - rhs.y, z - rhs.z); } -inline Vector3& Vector3::operator+=(const Vector3& rhs) { - x += rhs.x; y += rhs.y; z += rhs.z; return *this; +inline Vector3& Vector3::operator+=(const Vector3& rhs) +{ + x += rhs.x; + y += rhs.y; + z += rhs.z; + return *this; } -inline Vector3& Vector3::operator-=(const Vector3& rhs) { - x -= rhs.x; y -= rhs.y; z -= rhs.z; return *this; +inline Vector3& Vector3::operator-=(const Vector3& rhs) +{ + x -= rhs.x; + y -= rhs.y; + z -= rhs.z; + return *this; } -inline Vector3 Vector3::operator*(const float a) const { - return Vector3(x*a, y*a, z*a); +inline Vector3 Vector3::operator*(const float a) const +{ + return Vector3(x * a, y * a, z * a); } -inline Vector3 Vector3::operator*(const Vector3& rhs) const { - return Vector3(x*rhs.x, y*rhs.y, z*rhs.z); +inline Vector3 Vector3::operator*(const Vector3& rhs) const +{ + return Vector3(x * rhs.x, y * rhs.y, z * rhs.z); } -inline Vector3& Vector3::operator*=(const float a) { - x *= a; y *= a; z *= a; return *this; +inline Vector3& Vector3::operator*=(const float a) +{ + x *= a; + y *= a; + z *= a; + return *this; } -inline Vector3& Vector3::operator*=(const Vector3& rhs) { - x *= rhs.x; y *= rhs.y; z *= rhs.z; return *this; +inline Vector3& Vector3::operator*=(const Vector3& rhs) +{ + x *= rhs.x; + y *= rhs.y; + z *= rhs.z; + return *this; } -inline Vector3 Vector3::operator/(const float a) const { - return Vector3(x/a, y/a, z/a); +inline Vector3 Vector3::operator/(const float a) const +{ + return Vector3(x / a, y / a, z / a); } -inline Vector3& Vector3::operator/=(const float a) { - x /= a; y /= a; z /= a; return *this; +inline Vector3& Vector3::operator/=(const float a) +{ + x /= a; + y /= a; + z /= a; + return *this; } -inline bool Vector3::operator==(const Vector3& rhs) const { - return (x == rhs.x) && (y == rhs.y) && (z == rhs.z); +inline bool Vector3::operator==(const Vector3& rhs) const +{ + return (x == rhs.x) && (y == rhs.y) && (z == rhs.z); } -inline bool Vector3::operator!=(const Vector3& rhs) const { - return (x != rhs.x) || (y != rhs.y) || (z != rhs.z); +inline bool Vector3::operator!=(const Vector3& rhs) const +{ + return (x != rhs.x) || (y != rhs.y) || (z != rhs.z); } -inline bool Vector3::operator<(const Vector3& rhs) const { - if(x < rhs.x) return true; - if(x > rhs.x) return false; - if(y < rhs.y) return true; - if(y > rhs.y) return false; - if(z < rhs.z) return true; - if(z > rhs.z) return false; - return false; +inline bool Vector3::operator<(const Vector3& rhs) const +{ + if (x < rhs.x) return true; + if (x > rhs.x) return false; + if (y < rhs.y) return true; + if (y > rhs.y) return false; + if (z < rhs.z) return true; + if (z > rhs.z) return false; + return false; } -inline float Vector3::operator[](int index) const { - return (&x)[index]; +inline float Vector3::operator[](int index) const +{ + return (&x)[index]; } -inline float& Vector3::operator[](int index) { - return (&x)[index]; +inline float& Vector3::operator[](int index) +{ + return (&x)[index]; } -inline void Vector3::set(float x, float y, float z) { - this->x = x; this->y = y; this->z = z; +inline void Vector3::set(float x, float y, float z) +{ + this->x = x; + this->y = y; + this->z = z; } -inline float Vector3::length() const { - return sqrtf(x*x + y*y + z*z); +inline float Vector3::length() const +{ + return sqrtf(x * x + y * y + z * z); } -inline float Vector3::distance(const Vector3& vec) const { - return sqrtf((vec.x-x)*(vec.x-x) + (vec.y-y)*(vec.y-y) + (vec.z-z)*(vec.z-z)); +inline float Vector3::distance(const Vector3& vec) const +{ + return sqrtf((vec.x - x) * (vec.x - x) + (vec.y - y) * (vec.y - y) + (vec.z - z) * (vec.z - z)); } -inline Vector3& Vector3::normalize() { - //@@const float EPSILON = 0.000001f; - float xxyyzz = x*x + y*y + z*z; - //@@if(xxyyzz < EPSILON) - //@@ return *this; // do nothing if it is ~zero vector +inline Vector3& Vector3::normalize() +{ + //@@const float EPSILON = 0.000001f; + float xxyyzz = x * x + y * y + z * z; + //@@if(xxyyzz < EPSILON) + //@@ return *this; // do nothing if it is ~zero vector - //float invLength = invSqrt(xxyyzz); - float invLength = 1.0f / sqrtf(xxyyzz); - x *= invLength; - y *= invLength; - z *= invLength; - return *this; + //float invLength = invSqrt(xxyyzz); + float invLength = 1.0f / sqrtf(xxyyzz); + x *= invLength; + y *= invLength; + z *= invLength; + return *this; } -inline float Vector3::dot(const Vector3& rhs) const { - return (x*rhs.x + y*rhs.y + z*rhs.z); +inline float Vector3::dot(const Vector3& rhs) const +{ + return (x * rhs.x + y * rhs.y + z * rhs.z); } -inline Vector3 Vector3::cross(const Vector3& rhs) const { - return Vector3(y*rhs.z - z*rhs.y, z*rhs.x - x*rhs.z, x*rhs.y - y*rhs.x); +inline Vector3 Vector3::cross(const Vector3& rhs) const +{ + return Vector3(y * rhs.z - z * rhs.y, z * rhs.x - x * rhs.z, x * rhs.y - y * rhs.x); } -inline bool Vector3::equal(const Vector3& rhs, float epsilon) const { - return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon && fabs(z - rhs.z) < epsilon; +inline bool Vector3::equal(const Vector3& rhs, float epsilon) const +{ + return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon && fabs(z - rhs.z) < epsilon; } -inline Vector3 operator*(const float a, const Vector3 vec) { - return Vector3(a*vec.x, a*vec.y, a*vec.z); +inline Vector3 operator*(const float a, const Vector3 vec) +{ + return Vector3(a * vec.x, a * vec.y, a * vec.z); } -inline std::ostream& operator<<(std::ostream& os, const Vector3& vec) { - os << "(" << vec.x << ", " << vec.y << ", " << vec.z << ")"; - return os; +inline std::ostream& operator<<(std::ostream& os, const Vector3& vec) +{ + os << "(" << vec.x << ", " << vec.y << ", " << vec.z << ")"; + return os; } // END OF VECTOR3 ///////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////// // inline functions for Vector4 /////////////////////////////////////////////////////////////////////////////// -inline Vector4 Vector4::operator-() const { - return Vector4(-x, -y, -z, -w); +inline Vector4 Vector4::operator-() const +{ + return Vector4(-x, -y, -z, -w); } -inline Vector4 Vector4::operator+(const Vector4& rhs) const { - return Vector4(x+rhs.x, y+rhs.y, z+rhs.z, w+rhs.w); +inline Vector4 Vector4::operator+(const Vector4& rhs) const +{ + return Vector4(x + rhs.x, y + rhs.y, z + rhs.z, w + rhs.w); } -inline Vector4 Vector4::operator-(const Vector4& rhs) const { - return Vector4(x-rhs.x, y-rhs.y, z-rhs.z, w-rhs.w); +inline Vector4 Vector4::operator-(const Vector4& rhs) const +{ + return Vector4(x - rhs.x, y - rhs.y, z - rhs.z, w - rhs.w); } -inline Vector4& Vector4::operator+=(const Vector4& rhs) { - x += rhs.x; y += rhs.y; z += rhs.z; w += rhs.w; return *this; +inline Vector4& Vector4::operator+=(const Vector4& rhs) +{ + x += rhs.x; + y += rhs.y; + z += rhs.z; + w += rhs.w; + return *this; } -inline Vector4& Vector4::operator-=(const Vector4& rhs) { - x -= rhs.x; y -= rhs.y; z -= rhs.z; w -= rhs.w; return *this; +inline Vector4& Vector4::operator-=(const Vector4& rhs) +{ + x -= rhs.x; + y -= rhs.y; + z -= rhs.z; + w -= rhs.w; + return *this; } -inline Vector4 Vector4::operator*(const float a) const { - return Vector4(x*a, y*a, z*a, w*a); +inline Vector4 Vector4::operator*(const float a) const +{ + return Vector4(x * a, y * a, z * a, w * a); } -inline Vector4 Vector4::operator*(const Vector4& rhs) const { - return Vector4(x*rhs.x, y*rhs.y, z*rhs.z, w*rhs.w); +inline Vector4 Vector4::operator*(const Vector4& rhs) const +{ + return Vector4(x * rhs.x, y * rhs.y, z * rhs.z, w * rhs.w); } -inline Vector4& Vector4::operator*=(const float a) { - x *= a; y *= a; z *= a; w *= a; return *this; +inline Vector4& Vector4::operator*=(const float a) +{ + x *= a; + y *= a; + z *= a; + w *= a; + return *this; } -inline Vector4& Vector4::operator*=(const Vector4& rhs) { - x *= rhs.x; y *= rhs.y; z *= rhs.z; w *= rhs.w; return *this; +inline Vector4& Vector4::operator*=(const Vector4& rhs) +{ + x *= rhs.x; + y *= rhs.y; + z *= rhs.z; + w *= rhs.w; + return *this; } -inline Vector4 Vector4::operator/(const float a) const { - return Vector4(x/a, y/a, z/a, w/a); +inline Vector4 Vector4::operator/(const float a) const +{ + return Vector4(x / a, y / a, z / a, w / a); } -inline Vector4& Vector4::operator/=(const float a) { - x /= a; y /= a; z /= a; w /= a; return *this; +inline Vector4& Vector4::operator/=(const float a) +{ + x /= a; + y /= a; + z /= a; + w /= a; + return *this; } -inline bool Vector4::operator==(const Vector4& rhs) const { - return (x == rhs.x) && (y == rhs.y) && (z == rhs.z) && (w == rhs.w); +inline bool Vector4::operator==(const Vector4& rhs) const +{ + return (x == rhs.x) && (y == rhs.y) && (z == rhs.z) && (w == rhs.w); } -inline bool Vector4::operator!=(const Vector4& rhs) const { - return (x != rhs.x) || (y != rhs.y) || (z != rhs.z) || (w != rhs.w); +inline bool Vector4::operator!=(const Vector4& rhs) const +{ + return (x != rhs.x) || (y != rhs.y) || (z != rhs.z) || (w != rhs.w); } -inline bool Vector4::operator<(const Vector4& rhs) const { - if(x < rhs.x) return true; - if(x > rhs.x) return false; - if(y < rhs.y) return true; - if(y > rhs.y) return false; - if(z < rhs.z) return true; - if(z > rhs.z) return false; - if(w < rhs.w) return true; - if(w > rhs.w) return false; - return false; +inline bool Vector4::operator<(const Vector4& rhs) const +{ + if (x < rhs.x) return true; + if (x > rhs.x) return false; + if (y < rhs.y) return true; + if (y > rhs.y) return false; + if (z < rhs.z) return true; + if (z > rhs.z) return false; + if (w < rhs.w) return true; + if (w > rhs.w) return false; + return false; } -inline float Vector4::operator[](int index) const { - return (&x)[index]; +inline float Vector4::operator[](int index) const +{ + return (&x)[index]; } -inline float& Vector4::operator[](int index) { - return (&x)[index]; +inline float& Vector4::operator[](int index) +{ + return (&x)[index]; } -inline void Vector4::set(float x, float y, float z, float w) { - this->x = x; this->y = y; this->z = z; this->w = w; +inline void Vector4::set(float x, float y, float z, float w) +{ + this->x = x; + this->y = y; + this->z = z; + this->w = w; } -inline float Vector4::length() const { - return sqrtf(x*x + y*y + z*z + w*w); +inline float Vector4::length() const +{ + return sqrtf(x * x + y * y + z * z + w * w); } -inline float Vector4::distance(const Vector4& vec) const { - return sqrtf((vec.x-x)*(vec.x-x) + (vec.y-y)*(vec.y-y) + (vec.z-z)*(vec.z-z) + (vec.w-w)*(vec.w-w)); +inline float Vector4::distance(const Vector4& vec) const +{ + return sqrtf((vec.x - x) * (vec.x - x) + (vec.y - y) * (vec.y - y) + (vec.z - z) * (vec.z - z) + (vec.w - w) * (vec.w - w)); } -inline Vector4& Vector4::normalize() { - //NOTE: leave w-component untouched - //@@const float EPSILON = 0.000001f; - float xxyyzz = x*x + y*y + z*z; - //@@if(xxyyzz < EPSILON) - //@@ return *this; // do nothing if it is zero vector +inline Vector4& Vector4::normalize() +{ + //NOTE: leave w-component untouched + //@@const float EPSILON = 0.000001f; + float xxyyzz = x * x + y * y + z * z; + //@@if(xxyyzz < EPSILON) + //@@ return *this; // do nothing if it is zero vector - //float invLength = invSqrt(xxyyzz); - float invLength = 1.0f / sqrtf(xxyyzz); - x *= invLength; - y *= invLength; - z *= invLength; - return *this; + //float invLength = invSqrt(xxyyzz); + float invLength = 1.0f / sqrtf(xxyyzz); + x *= invLength; + y *= invLength; + z *= invLength; + return *this; } -inline float Vector4::dot(const Vector4& rhs) const { - return (x*rhs.x + y*rhs.y + z*rhs.z + w*rhs.w); +inline float Vector4::dot(const Vector4& rhs) const +{ + return (x * rhs.x + y * rhs.y + z * rhs.z + w * rhs.w); } -inline bool Vector4::equal(const Vector4& rhs, float epsilon) const { - return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon && - fabs(z - rhs.z) < epsilon && fabs(w - rhs.w) < epsilon; +inline bool Vector4::equal(const Vector4& rhs, float epsilon) const +{ + return fabs(x - rhs.x) < epsilon && fabs(y - rhs.y) < epsilon && + fabs(z - rhs.z) < epsilon && fabs(w - rhs.w) < epsilon; } -inline Vector4 operator*(const float a, const Vector4 vec) { - return Vector4(a*vec.x, a*vec.y, a*vec.z, a*vec.w); +inline Vector4 operator*(const float a, const Vector4 vec) +{ + return Vector4(a * vec.x, a * vec.y, a * vec.z, a * vec.w); } -inline std::ostream& operator<<(std::ostream& os, const Vector4& vec) { - os << "(" << vec.x << ", " << vec.y << ", " << vec.z << ", " << vec.w << ")"; - return os; +inline std::ostream& operator<<(std::ostream& os, const Vector4& vec) +{ + os << "(" << vec.x << ", " << vec.y << ", " << vec.z << ", " << vec.w << ")"; + return os; } // END OF VECTOR4 ///////////////////////////////////////////////////////////// diff --git a/examples/ThirdPartyLibs/openvr/samples/shared/compat.h b/examples/ThirdPartyLibs/openvr/samples/shared/compat.h index 154f8b072..a3b2f3215 100644 --- a/examples/ThirdPartyLibs/openvr/samples/shared/compat.h +++ b/examples/ThirdPartyLibs/openvr/samples/shared/compat.h @@ -11,14 +11,14 @@ #include #include -#define sprintf_s snprintf -#define vsprintf_s sprintf -#define _stricmp strcmp -#define stricmp strcmp -#define strnicmp strncasecmp -#define strcpy_s(dst, n, src) int(strncpy(dst, src, n) != nullptr) +#define sprintf_s snprintf +#define vsprintf_s sprintf +#define _stricmp strcmp +#define stricmp strcmp +#define strnicmp strncasecmp +#define strcpy_s(dst, n, src) int(strncpy(dst, src, n) != nullptr) #define fopen_s(fd, path, mode) int((*fd = fopen(path, mode)) != nullptr) -#define _vsnprintf_s(buffer, size, fmt, ap) vsnprintf(buffer, size, fmt, ap) +#define _vsnprintf_s(buffer, size, fmt, ap) vsnprintf(buffer, size, fmt, ap) #define OutputDebugStringA(x) fprintf(stderr, "%s\n", x) typedef int errno_t; diff --git a/examples/ThirdPartyLibs/openvr/samples/shared/lodepng.cpp b/examples/ThirdPartyLibs/openvr/samples/shared/lodepng.cpp index d57a9d945..5fffaa6b9 100644 --- a/examples/ThirdPartyLibs/openvr/samples/shared/lodepng.cpp +++ b/examples/ThirdPartyLibs/openvr/samples/shared/lodepng.cpp @@ -40,9 +40,9 @@ Rename this file to lodepng.cpp to use it for C++, or to lodepng.c to use it for #define VERSION_STRING "20140823" #if defined(_MSC_VER) && (_MSC_VER >= 1310) /*Visual Studio: A few warning types are not desired here.*/ -#pragma warning( disable : 4244 ) /*implicit conversions: not warned by gcc -Wall -Wextra and requires too much casts*/ -#pragma warning( disable : 4996 ) /*VS does not like fopen, but fopen_s is not standard C so unusable here*/ -#endif /*_MSC_VER */ +#pragma warning(disable : 4244) /*implicit conversions: not warned by gcc -Wall -Wextra and requires too much casts*/ +#pragma warning(disable : 4996) /*VS does not like fopen, but fopen_s is not standard C so unusable here*/ +#endif /*_MSC_VER */ /* This source file is built up in the following large parts. The code sections @@ -65,19 +65,19 @@ from here.*/ #ifdef LODEPNG_COMPILE_ALLOCATORS static void* lodepng_malloc(size_t size) { - return malloc(size); + return malloc(size); } static void* lodepng_realloc(void* ptr, size_t new_size) { - return realloc(ptr, new_size); + return realloc(ptr, new_size); } static void lodepng_free(void* ptr) { - free(ptr); + free(ptr); } -#else /*LODEPNG_COMPILE_ALLOCATORS*/ +#else /*LODEPNG_COMPILE_ALLOCATORS*/ void* lodepng_malloc(size_t size); void* lodepng_realloc(void* ptr, size_t new_size); void lodepng_free(void* ptr); @@ -96,28 +96,28 @@ It makes the error handling code shorter and more readable. Example: if(!uivector_resizev(&frequencies_ll, 286, 0)) ERROR_BREAK(83); */ -#define CERROR_BREAK(errorvar, code)\ -{\ - errorvar = code;\ - break;\ -} +#define CERROR_BREAK(errorvar, code) \ + { \ + errorvar = code; \ + break; \ + } /*version of CERROR_BREAK that assumes the common case where the error variable is named "error"*/ #define ERROR_BREAK(code) CERROR_BREAK(error, code) /*Set error var to the error code, and return it.*/ -#define CERROR_RETURN_ERROR(errorvar, code)\ -{\ - errorvar = code;\ - return code;\ -} +#define CERROR_RETURN_ERROR(errorvar, code) \ + { \ + errorvar = code; \ + return code; \ + } /*Try the code, if it returns error, also return the error.*/ -#define CERROR_TRY_RETURN(call)\ -{\ - unsigned error = call;\ - if(error) return error;\ -} +#define CERROR_TRY_RETURN(call) \ + { \ + unsigned error = call; \ + if (error) return error; \ + } /* About uivector, ucvector and string: @@ -132,74 +132,75 @@ About uivector, ucvector and string: /*dynamic vector of unsigned ints*/ typedef struct uivector { - unsigned* data; - size_t size; /*size in number of unsigned longs*/ - size_t allocsize; /*allocated size in bytes*/ + unsigned* data; + size_t size; /*size in number of unsigned longs*/ + size_t allocsize; /*allocated size in bytes*/ } uivector; static void uivector_cleanup(void* p) { - ((uivector*)p)->size = ((uivector*)p)->allocsize = 0; - lodepng_free(((uivector*)p)->data); - ((uivector*)p)->data = NULL; + ((uivector*)p)->size = ((uivector*)p)->allocsize = 0; + lodepng_free(((uivector*)p)->data); + ((uivector*)p)->data = NULL; } /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned uivector_reserve(uivector* p, size_t allocsize) { - if(allocsize > p->allocsize) - { - size_t newsize = (allocsize > p->allocsize * 2) ? allocsize : (allocsize * 3 / 2); - void* data = lodepng_realloc(p->data, newsize); - if(data) - { - p->allocsize = newsize; - p->data = (unsigned*)data; - } - else return 0; /*error: not enough memory*/ - } - return 1; + if (allocsize > p->allocsize) + { + size_t newsize = (allocsize > p->allocsize * 2) ? allocsize : (allocsize * 3 / 2); + void* data = lodepng_realloc(p->data, newsize); + if (data) + { + p->allocsize = newsize; + p->data = (unsigned*)data; + } + else + return 0; /*error: not enough memory*/ + } + return 1; } /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned uivector_resize(uivector* p, size_t size) { - if(!uivector_reserve(p, size * sizeof(unsigned))) return 0; - p->size = size; - return 1; /*success*/ + if (!uivector_reserve(p, size * sizeof(unsigned))) return 0; + p->size = size; + return 1; /*success*/ } /*resize and give all new elements the value*/ static unsigned uivector_resizev(uivector* p, size_t size, unsigned value) { - size_t oldsize = p->size, i; - if(!uivector_resize(p, size)) return 0; - for(i = oldsize; i < size; i++) p->data[i] = value; - return 1; + size_t oldsize = p->size, i; + if (!uivector_resize(p, size)) return 0; + for (i = oldsize; i < size; i++) p->data[i] = value; + return 1; } static void uivector_init(uivector* p) { - p->data = NULL; - p->size = p->allocsize = 0; + p->data = NULL; + p->size = p->allocsize = 0; } #ifdef LODEPNG_COMPILE_ENCODER /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned uivector_push_back(uivector* p, unsigned c) { - if(!uivector_resize(p, p->size + 1)) return 0; - p->data[p->size - 1] = c; - return 1; + if (!uivector_resize(p, p->size + 1)) return 0; + p->data[p->size - 1] = c; + return 1; } /*copy q to p, returns 1 if success, 0 if failure ==> nothing done*/ static unsigned uivector_copy(uivector* p, const uivector* q) { - size_t i; - if(!uivector_resize(p, q->size)) return 0; - for(i = 0; i < q->size; i++) p->data[i] = q->data[i]; - return 1; + size_t i; + if (!uivector_resize(p, q->size)) return 0; + for (i = 0; i < q->size; i++) p->data[i] = q->data[i]; + return 1; } #endif /*LODEPNG_COMPILE_ENCODER*/ #endif /*LODEPNG_COMPILE_ZLIB*/ @@ -209,59 +210,60 @@ static unsigned uivector_copy(uivector* p, const uivector* q) /*dynamic vector of unsigned chars*/ typedef struct ucvector { - unsigned char* data; - size_t size; /*used size*/ - size_t allocsize; /*allocated size*/ + unsigned char* data; + size_t size; /*used size*/ + size_t allocsize; /*allocated size*/ } ucvector; /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned ucvector_reserve(ucvector* p, size_t allocsize) { - if(allocsize > p->allocsize) - { - size_t newsize = (allocsize > p->allocsize * 2) ? allocsize : (allocsize * 3 / 2); - void* data = lodepng_realloc(p->data, newsize); - if(data) - { - p->allocsize = newsize; - p->data = (unsigned char*)data; - } - else return 0; /*error: not enough memory*/ - } - return 1; + if (allocsize > p->allocsize) + { + size_t newsize = (allocsize > p->allocsize * 2) ? allocsize : (allocsize * 3 / 2); + void* data = lodepng_realloc(p->data, newsize); + if (data) + { + p->allocsize = newsize; + p->data = (unsigned char*)data; + } + else + return 0; /*error: not enough memory*/ + } + return 1; } /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned ucvector_resize(ucvector* p, size_t size) { - if(!ucvector_reserve(p, size * sizeof(unsigned char))) return 0; - p->size = size; - return 1; /*success*/ + if (!ucvector_reserve(p, size * sizeof(unsigned char))) return 0; + p->size = size; + return 1; /*success*/ } #ifdef LODEPNG_COMPILE_PNG static void ucvector_cleanup(void* p) { - ((ucvector*)p)->size = ((ucvector*)p)->allocsize = 0; - lodepng_free(((ucvector*)p)->data); - ((ucvector*)p)->data = NULL; + ((ucvector*)p)->size = ((ucvector*)p)->allocsize = 0; + lodepng_free(((ucvector*)p)->data); + ((ucvector*)p)->data = NULL; } static void ucvector_init(ucvector* p) { - p->data = NULL; - p->size = p->allocsize = 0; + p->data = NULL; + p->size = p->allocsize = 0; } #ifdef LODEPNG_COMPILE_DECODER /*resize and give all new elements the value*/ static unsigned ucvector_resizev(ucvector* p, size_t size, unsigned char value) { - size_t oldsize = p->size, i; - if(!ucvector_resize(p, size)) return 0; - for(i = oldsize; i < size; i++) p->data[i] = value; - return 1; + size_t oldsize = p->size, i; + if (!ucvector_resize(p, size)) return 0; + for (i = oldsize; i < size; i++) p->data[i] = value; + return 1; } #endif /*LODEPNG_COMPILE_DECODER*/ #endif /*LODEPNG_COMPILE_PNG*/ @@ -271,8 +273,8 @@ static unsigned ucvector_resizev(ucvector* p, size_t size, unsigned char value) init_buffer to take over a buffer and size, it is not needed to use cleanup*/ static void ucvector_init_buffer(ucvector* p, unsigned char* buffer, size_t size) { - p->data = buffer; - p->allocsize = p->size = size; + p->data = buffer; + p->allocsize = p->size = size; } #endif /*LODEPNG_COMPILE_ZLIB*/ @@ -280,13 +282,12 @@ static void ucvector_init_buffer(ucvector* p, unsigned char* buffer, size_t size /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned ucvector_push_back(ucvector* p, unsigned char c) { - if(!ucvector_resize(p, p->size + 1)) return 0; - p->data[p->size - 1] = c; - return 1; + if (!ucvector_resize(p, p->size + 1)) return 0; + p->data[p->size - 1] = c; + return 1; } #endif /*defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)*/ - /* ////////////////////////////////////////////////////////////////////////// */ #ifdef LODEPNG_COMPILE_PNG @@ -294,39 +295,39 @@ static unsigned ucvector_push_back(ucvector* p, unsigned char c) /*returns 1 if success, 0 if failure ==> nothing done*/ static unsigned string_resize(char** out, size_t size) { - char* data = (char*)lodepng_realloc(*out, size + 1); - if(data) - { - data[size] = 0; /*null termination char*/ - *out = data; - } - return data != 0; + char* data = (char*)lodepng_realloc(*out, size + 1); + if (data) + { + data[size] = 0; /*null termination char*/ + *out = data; + } + return data != 0; } /*init a {char*, size_t} pair for use as string*/ static void string_init(char** out) { - *out = NULL; - string_resize(out, 0); + *out = NULL; + string_resize(out, 0); } /*free the above pair again*/ static void string_cleanup(char** out) { - lodepng_free(*out); - *out = NULL; + lodepng_free(*out); + *out = NULL; } static void string_set(char** out, const char* in) { - size_t insize = strlen(in), i = 0; - if(string_resize(out, insize)) - { - for(i = 0; i < insize; i++) - { - (*out)[i] = in[i]; - } - } + size_t insize = strlen(in), i = 0; + if (string_resize(out, insize)) + { + for (i = 0; i < insize; i++) + { + (*out)[i] = in[i]; + } + } } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ #endif /*LODEPNG_COMPILE_PNG*/ @@ -335,25 +336,25 @@ static void string_set(char** out, const char* in) unsigned lodepng_read32bitInt(const unsigned char* buffer) { - return (unsigned)((buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]); + return (unsigned)((buffer[0] << 24) | (buffer[1] << 16) | (buffer[2] << 8) | buffer[3]); } #if defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER) /*buffer must have at least 4 allocated bytes available*/ static void lodepng_set32bitInt(unsigned char* buffer, unsigned value) { - buffer[0] = (unsigned char)((value >> 24) & 0xff); - buffer[1] = (unsigned char)((value >> 16) & 0xff); - buffer[2] = (unsigned char)((value >> 8) & 0xff); - buffer[3] = (unsigned char)((value ) & 0xff); + buffer[0] = (unsigned char)((value >> 24) & 0xff); + buffer[1] = (unsigned char)((value >> 16) & 0xff); + buffer[2] = (unsigned char)((value >> 8) & 0xff); + buffer[3] = (unsigned char)((value)&0xff); } #endif /*defined(LODEPNG_COMPILE_PNG) || defined(LODEPNG_COMPILE_ENCODER)*/ #ifdef LODEPNG_COMPILE_ENCODER static void lodepng_add32bitInt(ucvector* buffer, unsigned value) { - ucvector_resize(buffer, buffer->size + 4); /*todo: give error if resize failed*/ - lodepng_set32bitInt(&buffer->data[buffer->size - 4], value); + ucvector_resize(buffer, buffer->size + 4); /*todo: give error if resize failed*/ + lodepng_set32bitInt(&buffer->data[buffer->size - 4], value); } #endif /*LODEPNG_COMPILE_ENCODER*/ @@ -365,40 +366,40 @@ static void lodepng_add32bitInt(ucvector* buffer, unsigned value) unsigned lodepng_load_file(unsigned char** out, size_t* outsize, const char* filename) { - FILE* file; - long size; + FILE* file; + long size; - /*provide some proper output values if error will happen*/ - *out = 0; - *outsize = 0; + /*provide some proper output values if error will happen*/ + *out = 0; + *outsize = 0; - file = fopen(filename, "rb"); - if(!file) return 78; + file = fopen(filename, "rb"); + if (!file) return 78; - /*get filesize:*/ - fseek(file , 0 , SEEK_END); - size = ftell(file); - rewind(file); + /*get filesize:*/ + fseek(file, 0, SEEK_END); + size = ftell(file); + rewind(file); - /*read contents of the file into the vector*/ - *outsize = 0; - *out = (unsigned char*)lodepng_malloc((size_t)size); - if(size && (*out)) (*outsize) = fread(*out, 1, (size_t)size, file); + /*read contents of the file into the vector*/ + *outsize = 0; + *out = (unsigned char*)lodepng_malloc((size_t)size); + if (size && (*out)) (*outsize) = fread(*out, 1, (size_t)size, file); - fclose(file); - if(!(*out) && size) return 83; /*the above malloc failed*/ - return 0; + fclose(file); + if (!(*out) && size) return 83; /*the above malloc failed*/ + return 0; } /*write given buffer to the file, overwriting the file, it doesn't append to it.*/ unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const char* filename) { - FILE* file; - file = fopen(filename, "wb" ); - if(!file) return 79; - fwrite((char*)buffer , 1 , buffersize, file); - fclose(file); - return 0; + FILE* file; + file = fopen(filename, "wb"); + if (!file) return 79; + fwrite((char*)buffer, 1, buffersize, file); + fclose(file); + return 0; } #endif /*LODEPNG_COMPILE_DISK*/ @@ -412,25 +413,25 @@ unsigned lodepng_save_file(const unsigned char* buffer, size_t buffersize, const #ifdef LODEPNG_COMPILE_ZLIB #ifdef LODEPNG_COMPILE_ENCODER /*TODO: this ignores potential out of memory errors*/ -#define addBitToStream(/*size_t**/ bitpointer, /*ucvector**/ bitstream, /*unsigned char*/ bit)\ -{\ - /*add a new byte at the end*/\ - if(((*bitpointer) & 7) == 0) ucvector_push_back(bitstream, (unsigned char)0);\ - /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/\ - (bitstream->data[bitstream->size - 1]) |= (bit << ((*bitpointer) & 0x7));\ - (*bitpointer)++;\ -} +#define addBitToStream(/*size_t**/ bitpointer, /*ucvector**/ bitstream, /*unsigned char*/ bit) \ + { \ + /*add a new byte at the end*/ \ + if (((*bitpointer) & 7) == 0) ucvector_push_back(bitstream, (unsigned char)0); \ + /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/ \ + (bitstream->data[bitstream->size - 1]) |= (bit << ((*bitpointer) & 0x7)); \ + (*bitpointer)++; \ + } static void addBitsToStream(size_t* bitpointer, ucvector* bitstream, unsigned value, size_t nbits) { - size_t i; - for(i = 0; i < nbits; i++) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> i) & 1)); + size_t i; + for (i = 0; i < nbits; i++) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> i) & 1)); } static void addBitsToStreamReversed(size_t* bitpointer, ucvector* bitstream, unsigned value, size_t nbits) { - size_t i; - for(i = 0; i < nbits; i++) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> (nbits - 1 - i)) & 1)); + size_t i; + for (i = 0; i < nbits; i++) addBitToStream(bitpointer, bitstream, (unsigned char)((value >> (nbits - 1 - i)) & 1)); } #endif /*LODEPNG_COMPILE_ENCODER*/ @@ -440,20 +441,20 @@ static void addBitsToStreamReversed(size_t* bitpointer, ucvector* bitstream, uns static unsigned char readBitFromStream(size_t* bitpointer, const unsigned char* bitstream) { - unsigned char result = (unsigned char)(READBIT(*bitpointer, bitstream)); - (*bitpointer)++; - return result; + unsigned char result = (unsigned char)(READBIT(*bitpointer, bitstream)); + (*bitpointer)++; + return result; } static unsigned readBitsFromStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits) { - unsigned result = 0, i; - for(i = 0; i < nbits; i++) - { - result += ((unsigned)READBIT(*bitpointer, bitstream)) << i; - (*bitpointer)++; - } - return result; + unsigned result = 0, i; + for (i = 0; i < nbits; i++) + { + result += ((unsigned)READBIT(*bitpointer, bitstream)) << i; + (*bitpointer)++; + } + return result; } #endif /*LODEPNG_COMPILE_DECODER*/ @@ -471,29 +472,24 @@ static unsigned readBitsFromStream(size_t* bitpointer, const unsigned char* bits #define NUM_CODE_LENGTH_CODES 19 /*the base lengths represented by codes 257-285*/ -static const unsigned LENGTHBASE[29] - = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, - 67, 83, 99, 115, 131, 163, 195, 227, 258}; +static const unsigned LENGTHBASE[29] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, + 67, 83, 99, 115, 131, 163, 195, 227, 258}; /*the extra bits used by codes 257-285 (added to base length)*/ -static const unsigned LENGTHEXTRA[29] - = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, - 4, 4, 4, 4, 5, 5, 5, 5, 0}; +static const unsigned LENGTHEXTRA[29] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 4, 4, 5, 5, 5, 5, 0}; /*the base backwards distances (the bits of distance codes appear after length codes and use their own huffman tree)*/ -static const unsigned DISTANCEBASE[30] - = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, - 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; +static const unsigned DISTANCEBASE[30] = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, + 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; /*the extra bits of backwards distances (added to base)*/ -static const unsigned DISTANCEEXTRA[30] - = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, - 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; +static const unsigned DISTANCEEXTRA[30] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, + 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; /*the order in which "code length alphabet code lengths" are stored, out of this the huffman tree of the dynamic huffman tree lengths is generated*/ -static const unsigned CLCL_ORDER[NUM_CODE_LENGTH_CODES] - = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; +static const unsigned CLCL_ORDER[NUM_CODE_LENGTH_CODES] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; /* ////////////////////////////////////////////////////////////////////////// */ @@ -502,11 +498,11 @@ Huffman tree struct, containing multiple representations of the tree */ typedef struct HuffmanTree { - unsigned* tree2d; - unsigned* tree1d; - unsigned* lengths; /*the lengths of the codes of the 1d-tree*/ - unsigned maxbitlen; /*maximum number of bits a single code can get*/ - unsigned numcodes; /*number of symbols in the alphabet = number of codes*/ + unsigned* tree2d; + unsigned* tree1d; + unsigned* lengths; /*the lengths of the codes of the 1d-tree*/ + unsigned maxbitlen; /*maximum number of bits a single code can get*/ + unsigned numcodes; /*number of symbols in the alphabet = number of codes*/ } HuffmanTree; /*function used for debug purposes to draw the tree in ascii art with C++*/ @@ -524,29 +520,29 @@ static void HuffmanTree_draw(HuffmanTree* tree) static void HuffmanTree_init(HuffmanTree* tree) { - tree->tree2d = 0; - tree->tree1d = 0; - tree->lengths = 0; + tree->tree2d = 0; + tree->tree1d = 0; + tree->lengths = 0; } static void HuffmanTree_cleanup(HuffmanTree* tree) { - lodepng_free(tree->tree2d); - lodepng_free(tree->tree1d); - lodepng_free(tree->lengths); + lodepng_free(tree->tree2d); + lodepng_free(tree->tree1d); + lodepng_free(tree->lengths); } /*the tree representation used by the decoder. return value is error*/ static unsigned HuffmanTree_make2DTree(HuffmanTree* tree) { - unsigned nodefilled = 0; /*up to which node it is filled*/ - unsigned treepos = 0; /*position in the tree (1 of the numcodes columns)*/ - unsigned n, i; + unsigned nodefilled = 0; /*up to which node it is filled*/ + unsigned treepos = 0; /*position in the tree (1 of the numcodes columns)*/ + unsigned n, i; - tree->tree2d = (unsigned*)lodepng_malloc(tree->numcodes * 2 * sizeof(unsigned)); - if(!tree->tree2d) return 83; /*alloc fail*/ + tree->tree2d = (unsigned*)lodepng_malloc(tree->numcodes * 2 * sizeof(unsigned)); + if (!tree->tree2d) return 83; /*alloc fail*/ - /* + /* convert tree1d[] to tree2d[][]. In the 2D array, a value of 32767 means uninited, a value >= numcodes is an address to another bit, a value < numcodes is a code. The 2 rows are the 2 possible bit values (0 or 1), there are as @@ -556,44 +552,45 @@ static unsigned HuffmanTree_make2DTree(HuffmanTree* tree) There is only memory for such good tree currently, if there are more nodes (due to too long length codes), error 55 will happen */ - for(n = 0; n < tree->numcodes * 2; n++) - { - tree->tree2d[n] = 32767; /*32767 here means the tree2d isn't filled there yet*/ - } + for (n = 0; n < tree->numcodes * 2; n++) + { + tree->tree2d[n] = 32767; /*32767 here means the tree2d isn't filled there yet*/ + } - for(n = 0; n < tree->numcodes; n++) /*the codes*/ - { - for(i = 0; i < tree->lengths[n]; i++) /*the bits for this code*/ - { - unsigned char bit = (unsigned char)((tree->tree1d[n] >> (tree->lengths[n] - i - 1)) & 1); - if(treepos > tree->numcodes - 2) return 55; /*oversubscribed, see comment in lodepng_error_text*/ - if(tree->tree2d[2 * treepos + bit] == 32767) /*not yet filled in*/ - { - if(i + 1 == tree->lengths[n]) /*last bit*/ - { - tree->tree2d[2 * treepos + bit] = n; /*put the current code in it*/ - treepos = 0; - } - else - { - /*put address of the next step in here, first that address has to be found of course + for (n = 0; n < tree->numcodes; n++) /*the codes*/ + { + for (i = 0; i < tree->lengths[n]; i++) /*the bits for this code*/ + { + unsigned char bit = (unsigned char)((tree->tree1d[n] >> (tree->lengths[n] - i - 1)) & 1); + if (treepos > tree->numcodes - 2) return 55; /*oversubscribed, see comment in lodepng_error_text*/ + if (tree->tree2d[2 * treepos + bit] == 32767) /*not yet filled in*/ + { + if (i + 1 == tree->lengths[n]) /*last bit*/ + { + tree->tree2d[2 * treepos + bit] = n; /*put the current code in it*/ + treepos = 0; + } + else + { + /*put address of the next step in here, first that address has to be found of course (it's just nodefilled + 1)...*/ - nodefilled++; - /*addresses encoded with numcodes added to it*/ - tree->tree2d[2 * treepos + bit] = nodefilled + tree->numcodes; - treepos = nodefilled; - } - } - else treepos = tree->tree2d[2 * treepos + bit] - tree->numcodes; - } - } + nodefilled++; + /*addresses encoded with numcodes added to it*/ + tree->tree2d[2 * treepos + bit] = nodefilled + tree->numcodes; + treepos = nodefilled; + } + } + else + treepos = tree->tree2d[2 * treepos + bit] - tree->numcodes; + } + } - for(n = 0; n < tree->numcodes * 2; n++) - { - if(tree->tree2d[n] == 32767) tree->tree2d[n] = 0; /*remove possible remaining 32767's*/ - } + for (n = 0; n < tree->numcodes * 2; n++) + { + if (tree->tree2d[n] == 32767) tree->tree2d[n] = 0; /*remove possible remaining 32767's*/ + } - return 0; + return 0; } /* @@ -603,41 +600,42 @@ value is error. */ static unsigned HuffmanTree_makeFromLengths2(HuffmanTree* tree) { - uivector blcount; - uivector nextcode; - unsigned bits, n, error = 0; + uivector blcount; + uivector nextcode; + unsigned bits, n, error = 0; - uivector_init(&blcount); - uivector_init(&nextcode); + uivector_init(&blcount); + uivector_init(&nextcode); - tree->tree1d = (unsigned*)lodepng_malloc(tree->numcodes * sizeof(unsigned)); - if(!tree->tree1d) error = 83; /*alloc fail*/ + tree->tree1d = (unsigned*)lodepng_malloc(tree->numcodes * sizeof(unsigned)); + if (!tree->tree1d) error = 83; /*alloc fail*/ - if(!uivector_resizev(&blcount, tree->maxbitlen + 1, 0) - || !uivector_resizev(&nextcode, tree->maxbitlen + 1, 0)) - error = 83; /*alloc fail*/ + if (!uivector_resizev(&blcount, tree->maxbitlen + 1, 0) || !uivector_resizev(&nextcode, tree->maxbitlen + 1, 0)) + error = 83; /*alloc fail*/ - if(!error) - { - /*step 1: count number of instances of each code length*/ - for(bits = 0; bits < tree->numcodes; bits++) blcount.data[tree->lengths[bits]]++; - /*step 2: generate the nextcode values*/ - for(bits = 1; bits <= tree->maxbitlen; bits++) - { - nextcode.data[bits] = (nextcode.data[bits - 1] + blcount.data[bits - 1]) << 1; - } - /*step 3: generate all the codes*/ - for(n = 0; n < tree->numcodes; n++) - { - if(tree->lengths[n] != 0) tree->tree1d[n] = nextcode.data[tree->lengths[n]]++; - } - } + if (!error) + { + /*step 1: count number of instances of each code length*/ + for (bits = 0; bits < tree->numcodes; bits++) blcount.data[tree->lengths[bits]]++; + /*step 2: generate the nextcode values*/ + for (bits = 1; bits <= tree->maxbitlen; bits++) + { + nextcode.data[bits] = (nextcode.data[bits - 1] + blcount.data[bits - 1]) << 1; + } + /*step 3: generate all the codes*/ + for (n = 0; n < tree->numcodes; n++) + { + if (tree->lengths[n] != 0) tree->tree1d[n] = nextcode.data[tree->lengths[n]]++; + } + } - uivector_cleanup(&blcount); - uivector_cleanup(&nextcode); + uivector_cleanup(&blcount); + uivector_cleanup(&nextcode); - if(!error) return HuffmanTree_make2DTree(tree); - else return error; + if (!error) + return HuffmanTree_make2DTree(tree); + else + return error; } /* @@ -646,15 +644,15 @@ by Deflate. maxbitlen is the maximum bits that a code in the tree can have. return value is error. */ static unsigned HuffmanTree_makeFromLengths(HuffmanTree* tree, const unsigned* bitlen, - size_t numcodes, unsigned maxbitlen) + size_t numcodes, unsigned maxbitlen) { - unsigned i; - tree->lengths = (unsigned*)lodepng_malloc(numcodes * sizeof(unsigned)); - if(!tree->lengths) return 83; /*alloc fail*/ - for(i = 0; i < numcodes; i++) tree->lengths[i] = bitlen[i]; - tree->numcodes = (unsigned)numcodes; /*number of symbols*/ - tree->maxbitlen = maxbitlen; - return HuffmanTree_makeFromLengths2(tree); + unsigned i; + tree->lengths = (unsigned*)lodepng_malloc(numcodes * sizeof(unsigned)); + if (!tree->lengths) return 83; /*alloc fail*/ + for (i = 0; i < numcodes; i++) tree->lengths[i] = bitlen[i]; + tree->numcodes = (unsigned)numcodes; /*number of symbols*/ + tree->maxbitlen = maxbitlen; + return HuffmanTree_makeFromLengths2(tree); } #ifdef LODEPNG_COMPILE_ENCODER @@ -666,248 +664,253 @@ A coin can be multiple coins (when they're merged) */ typedef struct Coin { - uivector symbols; - float weight; /*the sum of all weights in this coin*/ + uivector symbols; + float weight; /*the sum of all weights in this coin*/ } Coin; static void coin_init(Coin* c) { - uivector_init(&c->symbols); + uivector_init(&c->symbols); } /*argument c is void* so that this dtor can be given as function pointer to the vector resize function*/ static void coin_cleanup(void* c) { - uivector_cleanup(&((Coin*)c)->symbols); + uivector_cleanup(&((Coin*)c)->symbols); } static void coin_copy(Coin* c1, const Coin* c2) { - c1->weight = c2->weight; - uivector_copy(&c1->symbols, &c2->symbols); + c1->weight = c2->weight; + uivector_copy(&c1->symbols, &c2->symbols); } static void add_coins(Coin* c1, const Coin* c2) { - size_t i; - for(i = 0; i < c2->symbols.size; i++) uivector_push_back(&c1->symbols, c2->symbols.data[i]); - c1->weight += c2->weight; + size_t i; + for (i = 0; i < c2->symbols.size; i++) uivector_push_back(&c1->symbols, c2->symbols.data[i]); + c1->weight += c2->weight; } static void init_coins(Coin* coins, size_t num) { - size_t i; - for(i = 0; i < num; i++) coin_init(&coins[i]); + size_t i; + for (i = 0; i < num; i++) coin_init(&coins[i]); } static void cleanup_coins(Coin* coins, size_t num) { - size_t i; - for(i = 0; i < num; i++) coin_cleanup(&coins[i]); + size_t i; + for (i = 0; i < num; i++) coin_cleanup(&coins[i]); } -static int coin_compare(const void* a, const void* b) { - float wa = ((const Coin*)a)->weight; - float wb = ((const Coin*)b)->weight; - return wa > wb ? 1 : wa < wb ? -1 : 0; +static int coin_compare(const void* a, const void* b) +{ + float wa = ((const Coin*)a)->weight; + float wb = ((const Coin*)b)->weight; + return wa > wb ? 1 : wa < wb ? -1 : 0; } static unsigned append_symbol_coins(Coin* coins, const unsigned* frequencies, unsigned numcodes, size_t sum) { - unsigned i; - unsigned j = 0; /*index of present symbols*/ - for(i = 0; i < numcodes; i++) - { - if(frequencies[i] != 0) /*only include symbols that are present*/ - { - coins[j].weight = frequencies[i] / (float)sum; - uivector_push_back(&coins[j].symbols, i); - j++; - } - } - return 0; + unsigned i; + unsigned j = 0; /*index of present symbols*/ + for (i = 0; i < numcodes; i++) + { + if (frequencies[i] != 0) /*only include symbols that are present*/ + { + coins[j].weight = frequencies[i] / (float)sum; + uivector_push_back(&coins[j].symbols, i); + j++; + } + } + return 0; } unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies, - size_t numcodes, unsigned maxbitlen) + size_t numcodes, unsigned maxbitlen) { - unsigned i, j; - size_t sum = 0, numpresent = 0; - unsigned error = 0; - Coin* coins; /*the coins of the currently calculated row*/ - Coin* prev_row; /*the previous row of coins*/ - size_t numcoins; - size_t coinmem; + unsigned i, j; + size_t sum = 0, numpresent = 0; + unsigned error = 0; + Coin* coins; /*the coins of the currently calculated row*/ + Coin* prev_row; /*the previous row of coins*/ + size_t numcoins; + size_t coinmem; - if(numcodes == 0) return 80; /*error: a tree of 0 symbols is not supposed to be made*/ + if (numcodes == 0) return 80; /*error: a tree of 0 symbols is not supposed to be made*/ - for(i = 0; i < numcodes; i++) - { - if(frequencies[i] > 0) - { - numpresent++; - sum += frequencies[i]; - } - } + for (i = 0; i < numcodes; i++) + { + if (frequencies[i] > 0) + { + numpresent++; + sum += frequencies[i]; + } + } - for(i = 0; i < numcodes; i++) lengths[i] = 0; + for (i = 0; i < numcodes; i++) lengths[i] = 0; - /*ensure at least two present symbols. There should be at least one symbol + /*ensure at least two present symbols. There should be at least one symbol according to RFC 1951 section 3.2.7. To decoders incorrectly require two. To make these work as well ensure there are at least two symbols. The Package-Merge code below also doesn't work correctly if there's only one symbol, it'd give it the theoritical 0 bits but in practice zlib wants 1 bit*/ - if(numpresent == 0) - { - lengths[0] = lengths[1] = 1; /*note that for RFC 1951 section 3.2.7, only lengths[0] = 1 is needed*/ - } - else if(numpresent == 1) - { - for(i = 0; i < numcodes; i++) - { - if(frequencies[i]) - { - lengths[i] = 1; - lengths[i == 0 ? 1 : 0] = 1; - break; - } - } - } - else - { - /*Package-Merge algorithm represented by coin collector's problem + if (numpresent == 0) + { + lengths[0] = lengths[1] = 1; /*note that for RFC 1951 section 3.2.7, only lengths[0] = 1 is needed*/ + } + else if (numpresent == 1) + { + for (i = 0; i < numcodes; i++) + { + if (frequencies[i]) + { + lengths[i] = 1; + lengths[i == 0 ? 1 : 0] = 1; + break; + } + } + } + else + { + /*Package-Merge algorithm represented by coin collector's problem For every symbol, maxbitlen coins will be created*/ - coinmem = numpresent * 2; /*max amount of coins needed with the current algo*/ - coins = (Coin*)lodepng_malloc(sizeof(Coin) * coinmem); - prev_row = (Coin*)lodepng_malloc(sizeof(Coin) * coinmem); - if(!coins || !prev_row) - { - lodepng_free(coins); - lodepng_free(prev_row); - return 83; /*alloc fail*/ - } - init_coins(coins, coinmem); - init_coins(prev_row, coinmem); + coinmem = numpresent * 2; /*max amount of coins needed with the current algo*/ + coins = (Coin*)lodepng_malloc(sizeof(Coin) * coinmem); + prev_row = (Coin*)lodepng_malloc(sizeof(Coin) * coinmem); + if (!coins || !prev_row) + { + lodepng_free(coins); + lodepng_free(prev_row); + return 83; /*alloc fail*/ + } + init_coins(coins, coinmem); + init_coins(prev_row, coinmem); - /*first row, lowest denominator*/ - error = append_symbol_coins(coins, frequencies, numcodes, sum); - numcoins = numpresent; - qsort(coins, numcoins, sizeof(Coin), coin_compare); - if(!error) - { - unsigned numprev = 0; - for(j = 1; j <= maxbitlen && !error; j++) /*each of the remaining rows*/ - { - unsigned tempnum; - Coin* tempcoins; - /*swap prev_row and coins, and their amounts*/ - tempcoins = prev_row; prev_row = coins; coins = tempcoins; - tempnum = numprev; numprev = numcoins; numcoins = tempnum; + /*first row, lowest denominator*/ + error = append_symbol_coins(coins, frequencies, numcodes, sum); + numcoins = numpresent; + qsort(coins, numcoins, sizeof(Coin), coin_compare); + if (!error) + { + unsigned numprev = 0; + for (j = 1; j <= maxbitlen && !error; j++) /*each of the remaining rows*/ + { + unsigned tempnum; + Coin* tempcoins; + /*swap prev_row and coins, and their amounts*/ + tempcoins = prev_row; + prev_row = coins; + coins = tempcoins; + tempnum = numprev; + numprev = numcoins; + numcoins = tempnum; - cleanup_coins(coins, numcoins); - init_coins(coins, numcoins); + cleanup_coins(coins, numcoins); + init_coins(coins, numcoins); - numcoins = 0; + numcoins = 0; - /*fill in the merged coins of the previous row*/ - for(i = 0; i + 1 < numprev; i += 2) - { - /*merge prev_row[i] and prev_row[i + 1] into new coin*/ - Coin* coin = &coins[numcoins++]; - coin_copy(coin, &prev_row[i]); - add_coins(coin, &prev_row[i + 1]); - } - /*fill in all the original symbols again*/ - if(j < maxbitlen) - { - error = append_symbol_coins(coins + numcoins, frequencies, numcodes, sum); - numcoins += numpresent; - } - qsort(coins, numcoins, sizeof(Coin), coin_compare); - } - } + /*fill in the merged coins of the previous row*/ + for (i = 0; i + 1 < numprev; i += 2) + { + /*merge prev_row[i] and prev_row[i + 1] into new coin*/ + Coin* coin = &coins[numcoins++]; + coin_copy(coin, &prev_row[i]); + add_coins(coin, &prev_row[i + 1]); + } + /*fill in all the original symbols again*/ + if (j < maxbitlen) + { + error = append_symbol_coins(coins + numcoins, frequencies, numcodes, sum); + numcoins += numpresent; + } + qsort(coins, numcoins, sizeof(Coin), coin_compare); + } + } - if(!error) - { - /*calculate the lenghts of each symbol, as the amount of times a coin of each symbol is used*/ - for(i = 0; i < numpresent - 1; i++) - { - Coin* coin = &coins[i]; - for(j = 0; j < coin->symbols.size; j++) lengths[coin->symbols.data[j]]++; - } - } + if (!error) + { + /*calculate the lenghts of each symbol, as the amount of times a coin of each symbol is used*/ + for (i = 0; i < numpresent - 1; i++) + { + Coin* coin = &coins[i]; + for (j = 0; j < coin->symbols.size; j++) lengths[coin->symbols.data[j]]++; + } + } - cleanup_coins(coins, coinmem); - lodepng_free(coins); - cleanup_coins(prev_row, coinmem); - lodepng_free(prev_row); - } + cleanup_coins(coins, coinmem); + lodepng_free(coins); + cleanup_coins(prev_row, coinmem); + lodepng_free(prev_row); + } - return error; + return error; } /*Create the Huffman tree given the symbol frequencies*/ static unsigned HuffmanTree_makeFromFrequencies(HuffmanTree* tree, const unsigned* frequencies, - size_t mincodes, size_t numcodes, unsigned maxbitlen) + size_t mincodes, size_t numcodes, unsigned maxbitlen) { - unsigned error = 0; - while(!frequencies[numcodes - 1] && numcodes > mincodes) numcodes--; /*trim zeroes*/ - tree->maxbitlen = maxbitlen; - tree->numcodes = (unsigned)numcodes; /*number of symbols*/ - tree->lengths = (unsigned*)lodepng_realloc(tree->lengths, numcodes * sizeof(unsigned)); - if(!tree->lengths) return 83; /*alloc fail*/ - /*initialize all lengths to 0*/ - memset(tree->lengths, 0, numcodes * sizeof(unsigned)); + unsigned error = 0; + while (!frequencies[numcodes - 1] && numcodes > mincodes) numcodes--; /*trim zeroes*/ + tree->maxbitlen = maxbitlen; + tree->numcodes = (unsigned)numcodes; /*number of symbols*/ + tree->lengths = (unsigned*)lodepng_realloc(tree->lengths, numcodes * sizeof(unsigned)); + if (!tree->lengths) return 83; /*alloc fail*/ + /*initialize all lengths to 0*/ + memset(tree->lengths, 0, numcodes * sizeof(unsigned)); - error = lodepng_huffman_code_lengths(tree->lengths, frequencies, numcodes, maxbitlen); - if(!error) error = HuffmanTree_makeFromLengths2(tree); - return error; + error = lodepng_huffman_code_lengths(tree->lengths, frequencies, numcodes, maxbitlen); + if (!error) error = HuffmanTree_makeFromLengths2(tree); + return error; } static unsigned HuffmanTree_getCode(const HuffmanTree* tree, unsigned index) { - return tree->tree1d[index]; + return tree->tree1d[index]; } static unsigned HuffmanTree_getLength(const HuffmanTree* tree, unsigned index) { - return tree->lengths[index]; + return tree->lengths[index]; } #endif /*LODEPNG_COMPILE_ENCODER*/ /*get the literal and length code tree of a deflated block with fixed tree, as per the deflate specification*/ static unsigned generateFixedLitLenTree(HuffmanTree* tree) { - unsigned i, error = 0; - unsigned* bitlen = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned)); - if(!bitlen) return 83; /*alloc fail*/ + unsigned i, error = 0; + unsigned* bitlen = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned)); + if (!bitlen) return 83; /*alloc fail*/ - /*288 possible codes: 0-255=literals, 256=endcode, 257-285=lengthcodes, 286-287=unused*/ - for(i = 0; i <= 143; i++) bitlen[i] = 8; - for(i = 144; i <= 255; i++) bitlen[i] = 9; - for(i = 256; i <= 279; i++) bitlen[i] = 7; - for(i = 280; i <= 287; i++) bitlen[i] = 8; + /*288 possible codes: 0-255=literals, 256=endcode, 257-285=lengthcodes, 286-287=unused*/ + for (i = 0; i <= 143; i++) bitlen[i] = 8; + for (i = 144; i <= 255; i++) bitlen[i] = 9; + for (i = 256; i <= 279; i++) bitlen[i] = 7; + for (i = 280; i <= 287; i++) bitlen[i] = 8; - error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DEFLATE_CODE_SYMBOLS, 15); + error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DEFLATE_CODE_SYMBOLS, 15); - lodepng_free(bitlen); - return error; + lodepng_free(bitlen); + return error; } /*get the distance code tree of a deflated block with fixed tree, as specified in the deflate specification*/ static unsigned generateFixedDistanceTree(HuffmanTree* tree) { - unsigned i, error = 0; - unsigned* bitlen = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned)); - if(!bitlen) return 83; /*alloc fail*/ + unsigned i, error = 0; + unsigned* bitlen = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned)); + if (!bitlen) return 83; /*alloc fail*/ - /*there are 32 distance codes, but 30-31 are unused*/ - for(i = 0; i < NUM_DISTANCE_SYMBOLS; i++) bitlen[i] = 5; - error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DISTANCE_SYMBOLS, 15); + /*there are 32 distance codes, but 30-31 are unused*/ + for (i = 0; i < NUM_DISTANCE_SYMBOLS; i++) bitlen[i] = 5; + error = HuffmanTree_makeFromLengths(tree, bitlen, NUM_DISTANCE_SYMBOLS, 15); - lodepng_free(bitlen); - return error; + lodepng_free(bitlen); + return error; } #ifdef LODEPNG_COMPILE_DECODER @@ -917,23 +920,25 @@ returns the code, or (unsigned)(-1) if error happened inbitlength is the length of the complete buffer, in bits (so its byte length times 8) */ static unsigned huffmanDecodeSymbol(const unsigned char* in, size_t* bp, - const HuffmanTree* codetree, size_t inbitlength) + const HuffmanTree* codetree, size_t inbitlength) { - unsigned treepos = 0, ct; - for(;;) - { - if(*bp >= inbitlength) return (unsigned)(-1); /*error: end of input memory reached without endcode*/ - /* + unsigned treepos = 0, ct; + for (;;) + { + if (*bp >= inbitlength) return (unsigned)(-1); /*error: end of input memory reached without endcode*/ + /* decode the symbol from the tree. The "readBitFromStream" code is inlined in the expression below because this is the biggest bottleneck while decoding */ - ct = codetree->tree2d[(treepos << 1) + READBIT(*bp, in)]; - (*bp)++; - if(ct < codetree->numcodes) return ct; /*the symbol is decoded, return it*/ - else treepos = ct - codetree->numcodes; /*symbol not yet decoded, instead move tree position*/ + ct = codetree->tree2d[(treepos << 1) + READBIT(*bp, in)]; + (*bp)++; + if (ct < codetree->numcodes) + return ct; /*the symbol is decoded, return it*/ + else + treepos = ct - codetree->numcodes; /*symbol not yet decoded, instead move tree position*/ - if(treepos >= codetree->numcodes) return (unsigned)(-1); /*error: it appeared outside the codetree*/ - } + if (treepos >= codetree->numcodes) return (unsigned)(-1); /*error: it appeared outside the codetree*/ + } } #endif /*LODEPNG_COMPILE_DECODER*/ @@ -946,335 +951,356 @@ static unsigned huffmanDecodeSymbol(const unsigned char* in, size_t* bp, /*get the tree of a deflated block with fixed tree, as specified in the deflate specification*/ static void getTreeInflateFixed(HuffmanTree* tree_ll, HuffmanTree* tree_d) { - /*TODO: check for out of memory errors*/ - generateFixedLitLenTree(tree_ll); - generateFixedDistanceTree(tree_d); + /*TODO: check for out of memory errors*/ + generateFixedLitLenTree(tree_ll); + generateFixedDistanceTree(tree_d); } /*get the tree of a deflated block with dynamic tree, the tree itself is also Huffman compressed with a known tree*/ static unsigned getTreeInflateDynamic(HuffmanTree* tree_ll, HuffmanTree* tree_d, - const unsigned char* in, size_t* bp, size_t inlength) + const unsigned char* in, size_t* bp, size_t inlength) { - /*make sure that length values that aren't filled in will be 0, or a wrong tree will be generated*/ - unsigned error = 0; - unsigned n, HLIT, HDIST, HCLEN, i; - size_t inbitlength = inlength * 8; + /*make sure that length values that aren't filled in will be 0, or a wrong tree will be generated*/ + unsigned error = 0; + unsigned n, HLIT, HDIST, HCLEN, i; + size_t inbitlength = inlength * 8; - /*see comments in deflateDynamic for explanation of the context and these variables, it is analogous*/ - unsigned* bitlen_ll = 0; /*lit,len code lengths*/ - unsigned* bitlen_d = 0; /*dist code lengths*/ - /*code length code lengths ("clcl"), the bit lengths of the huffman tree used to compress bitlen_ll and bitlen_d*/ - unsigned* bitlen_cl = 0; - HuffmanTree tree_cl; /*the code tree for code length codes (the huffman tree for compressed huffman trees)*/ + /*see comments in deflateDynamic for explanation of the context and these variables, it is analogous*/ + unsigned* bitlen_ll = 0; /*lit,len code lengths*/ + unsigned* bitlen_d = 0; /*dist code lengths*/ + /*code length code lengths ("clcl"), the bit lengths of the huffman tree used to compress bitlen_ll and bitlen_d*/ + unsigned* bitlen_cl = 0; + HuffmanTree tree_cl; /*the code tree for code length codes (the huffman tree for compressed huffman trees)*/ - if((*bp) >> 3 >= inlength - 2) return 49; /*error: the bit pointer is or will go past the memory*/ + if ((*bp) >> 3 >= inlength - 2) return 49; /*error: the bit pointer is or will go past the memory*/ - /*number of literal/length codes + 257. Unlike the spec, the value 257 is added to it here already*/ - HLIT = readBitsFromStream(bp, in, 5) + 257; - /*number of distance codes. Unlike the spec, the value 1 is added to it here already*/ - HDIST = readBitsFromStream(bp, in, 5) + 1; - /*number of code length codes. Unlike the spec, the value 4 is added to it here already*/ - HCLEN = readBitsFromStream(bp, in, 4) + 4; + /*number of literal/length codes + 257. Unlike the spec, the value 257 is added to it here already*/ + HLIT = readBitsFromStream(bp, in, 5) + 257; + /*number of distance codes. Unlike the spec, the value 1 is added to it here already*/ + HDIST = readBitsFromStream(bp, in, 5) + 1; + /*number of code length codes. Unlike the spec, the value 4 is added to it here already*/ + HCLEN = readBitsFromStream(bp, in, 4) + 4; - HuffmanTree_init(&tree_cl); + HuffmanTree_init(&tree_cl); - while(!error) - { - /*read the code length codes out of 3 * (amount of code length codes) bits*/ + while (!error) + { + /*read the code length codes out of 3 * (amount of code length codes) bits*/ - bitlen_cl = (unsigned*)lodepng_malloc(NUM_CODE_LENGTH_CODES * sizeof(unsigned)); - if(!bitlen_cl) ERROR_BREAK(83 /*alloc fail*/); + bitlen_cl = (unsigned*)lodepng_malloc(NUM_CODE_LENGTH_CODES * sizeof(unsigned)); + if (!bitlen_cl) ERROR_BREAK(83 /*alloc fail*/); - for(i = 0; i < NUM_CODE_LENGTH_CODES; i++) - { - if(i < HCLEN) bitlen_cl[CLCL_ORDER[i]] = readBitsFromStream(bp, in, 3); - else bitlen_cl[CLCL_ORDER[i]] = 0; /*if not, it must stay 0*/ - } + for (i = 0; i < NUM_CODE_LENGTH_CODES; i++) + { + if (i < HCLEN) + bitlen_cl[CLCL_ORDER[i]] = readBitsFromStream(bp, in, 3); + else + bitlen_cl[CLCL_ORDER[i]] = 0; /*if not, it must stay 0*/ + } - error = HuffmanTree_makeFromLengths(&tree_cl, bitlen_cl, NUM_CODE_LENGTH_CODES, 7); - if(error) break; + error = HuffmanTree_makeFromLengths(&tree_cl, bitlen_cl, NUM_CODE_LENGTH_CODES, 7); + if (error) break; - /*now we can use this tree to read the lengths for the tree that this function will return*/ - bitlen_ll = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned)); - bitlen_d = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned)); - if(!bitlen_ll || !bitlen_d) ERROR_BREAK(83 /*alloc fail*/); - for(i = 0; i < NUM_DEFLATE_CODE_SYMBOLS; i++) bitlen_ll[i] = 0; - for(i = 0; i < NUM_DISTANCE_SYMBOLS; i++) bitlen_d[i] = 0; + /*now we can use this tree to read the lengths for the tree that this function will return*/ + bitlen_ll = (unsigned*)lodepng_malloc(NUM_DEFLATE_CODE_SYMBOLS * sizeof(unsigned)); + bitlen_d = (unsigned*)lodepng_malloc(NUM_DISTANCE_SYMBOLS * sizeof(unsigned)); + if (!bitlen_ll || !bitlen_d) ERROR_BREAK(83 /*alloc fail*/); + for (i = 0; i < NUM_DEFLATE_CODE_SYMBOLS; i++) bitlen_ll[i] = 0; + for (i = 0; i < NUM_DISTANCE_SYMBOLS; i++) bitlen_d[i] = 0; - /*i is the current symbol we're reading in the part that contains the code lengths of lit/len and dist codes*/ - i = 0; - while(i < HLIT + HDIST) - { - unsigned code = huffmanDecodeSymbol(in, bp, &tree_cl, inbitlength); - if(code <= 15) /*a length code*/ - { - if(i < HLIT) bitlen_ll[i] = code; - else bitlen_d[i - HLIT] = code; - i++; - } - else if(code == 16) /*repeat previous*/ - { - unsigned replength = 3; /*read in the 2 bits that indicate repeat length (3-6)*/ - unsigned value; /*set value to the previous code*/ + /*i is the current symbol we're reading in the part that contains the code lengths of lit/len and dist codes*/ + i = 0; + while (i < HLIT + HDIST) + { + unsigned code = huffmanDecodeSymbol(in, bp, &tree_cl, inbitlength); + if (code <= 15) /*a length code*/ + { + if (i < HLIT) + bitlen_ll[i] = code; + else + bitlen_d[i - HLIT] = code; + i++; + } + else if (code == 16) /*repeat previous*/ + { + unsigned replength = 3; /*read in the 2 bits that indicate repeat length (3-6)*/ + unsigned value; /*set value to the previous code*/ - if(*bp >= inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ - if (i == 0) ERROR_BREAK(54); /*can't repeat previous if i is 0*/ + if (*bp >= inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ + if (i == 0) ERROR_BREAK(54); /*can't repeat previous if i is 0*/ - replength += readBitsFromStream(bp, in, 2); + replength += readBitsFromStream(bp, in, 2); - if(i < HLIT + 1) value = bitlen_ll[i - 1]; - else value = bitlen_d[i - HLIT - 1]; - /*repeat this value in the next lengths*/ - for(n = 0; n < replength; n++) - { - if(i >= HLIT + HDIST) ERROR_BREAK(13); /*error: i is larger than the amount of codes*/ - if(i < HLIT) bitlen_ll[i] = value; - else bitlen_d[i - HLIT] = value; - i++; - } - } - else if(code == 17) /*repeat "0" 3-10 times*/ - { - unsigned replength = 3; /*read in the bits that indicate repeat length*/ - if(*bp >= inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ + if (i < HLIT + 1) + value = bitlen_ll[i - 1]; + else + value = bitlen_d[i - HLIT - 1]; + /*repeat this value in the next lengths*/ + for (n = 0; n < replength; n++) + { + if (i >= HLIT + HDIST) ERROR_BREAK(13); /*error: i is larger than the amount of codes*/ + if (i < HLIT) + bitlen_ll[i] = value; + else + bitlen_d[i - HLIT] = value; + i++; + } + } + else if (code == 17) /*repeat "0" 3-10 times*/ + { + unsigned replength = 3; /*read in the bits that indicate repeat length*/ + if (*bp >= inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ - replength += readBitsFromStream(bp, in, 3); + replength += readBitsFromStream(bp, in, 3); - /*repeat this value in the next lengths*/ - for(n = 0; n < replength; n++) - { - if(i >= HLIT + HDIST) ERROR_BREAK(14); /*error: i is larger than the amount of codes*/ + /*repeat this value in the next lengths*/ + for (n = 0; n < replength; n++) + { + if (i >= HLIT + HDIST) ERROR_BREAK(14); /*error: i is larger than the amount of codes*/ - if(i < HLIT) bitlen_ll[i] = 0; - else bitlen_d[i - HLIT] = 0; - i++; - } - } - else if(code == 18) /*repeat "0" 11-138 times*/ - { - unsigned replength = 11; /*read in the bits that indicate repeat length*/ - if(*bp >= inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ + if (i < HLIT) + bitlen_ll[i] = 0; + else + bitlen_d[i - HLIT] = 0; + i++; + } + } + else if (code == 18) /*repeat "0" 11-138 times*/ + { + unsigned replength = 11; /*read in the bits that indicate repeat length*/ + if (*bp >= inbitlength) ERROR_BREAK(50); /*error, bit pointer jumps past memory*/ - replength += readBitsFromStream(bp, in, 7); + replength += readBitsFromStream(bp, in, 7); - /*repeat this value in the next lengths*/ - for(n = 0; n < replength; n++) - { - if(i >= HLIT + HDIST) ERROR_BREAK(15); /*error: i is larger than the amount of codes*/ + /*repeat this value in the next lengths*/ + for (n = 0; n < replength; n++) + { + if (i >= HLIT + HDIST) ERROR_BREAK(15); /*error: i is larger than the amount of codes*/ - if(i < HLIT) bitlen_ll[i] = 0; - else bitlen_d[i - HLIT] = 0; - i++; - } - } - else /*if(code == (unsigned)(-1))*/ /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ - { - if(code == (unsigned)(-1)) - { - /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol + if (i < HLIT) + bitlen_ll[i] = 0; + else + bitlen_d[i - HLIT] = 0; + i++; + } + } + else /*if(code == (unsigned)(-1))*/ /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ + { + if (code == (unsigned)(-1)) + { + /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol (10=no endcode, 11=wrong jump outside of tree)*/ - error = (*bp) > inbitlength ? 10 : 11; - } - else error = 16; /*unexisting code, this can never happen*/ - break; - } - } - if(error) break; + error = (*bp) > inbitlength ? 10 : 11; + } + else + error = 16; /*unexisting code, this can never happen*/ + break; + } + } + if (error) break; - if(bitlen_ll[256] == 0) ERROR_BREAK(64); /*the length of the end code 256 must be larger than 0*/ + if (bitlen_ll[256] == 0) ERROR_BREAK(64); /*the length of the end code 256 must be larger than 0*/ - /*now we've finally got HLIT and HDIST, so generate the code trees, and the function is done*/ - error = HuffmanTree_makeFromLengths(tree_ll, bitlen_ll, NUM_DEFLATE_CODE_SYMBOLS, 15); - if(error) break; - error = HuffmanTree_makeFromLengths(tree_d, bitlen_d, NUM_DISTANCE_SYMBOLS, 15); + /*now we've finally got HLIT and HDIST, so generate the code trees, and the function is done*/ + error = HuffmanTree_makeFromLengths(tree_ll, bitlen_ll, NUM_DEFLATE_CODE_SYMBOLS, 15); + if (error) break; + error = HuffmanTree_makeFromLengths(tree_d, bitlen_d, NUM_DISTANCE_SYMBOLS, 15); - break; /*end of error-while*/ - } + break; /*end of error-while*/ + } - lodepng_free(bitlen_cl); - lodepng_free(bitlen_ll); - lodepng_free(bitlen_d); - HuffmanTree_cleanup(&tree_cl); + lodepng_free(bitlen_cl); + lodepng_free(bitlen_ll); + lodepng_free(bitlen_d); + HuffmanTree_cleanup(&tree_cl); - return error; + return error; } /*inflate a block with dynamic of fixed Huffman tree*/ static unsigned inflateHuffmanBlock(ucvector* out, const unsigned char* in, size_t* bp, - size_t* pos, size_t inlength, unsigned btype) + size_t* pos, size_t inlength, unsigned btype) { - unsigned error = 0; - HuffmanTree tree_ll; /*the huffman tree for literal and length codes*/ - HuffmanTree tree_d; /*the huffman tree for distance codes*/ - size_t inbitlength = inlength * 8; + unsigned error = 0; + HuffmanTree tree_ll; /*the huffman tree for literal and length codes*/ + HuffmanTree tree_d; /*the huffman tree for distance codes*/ + size_t inbitlength = inlength * 8; - HuffmanTree_init(&tree_ll); - HuffmanTree_init(&tree_d); + HuffmanTree_init(&tree_ll); + HuffmanTree_init(&tree_d); - if(btype == 1) getTreeInflateFixed(&tree_ll, &tree_d); - else if(btype == 2) error = getTreeInflateDynamic(&tree_ll, &tree_d, in, bp, inlength); + if (btype == 1) + getTreeInflateFixed(&tree_ll, &tree_d); + else if (btype == 2) + error = getTreeInflateDynamic(&tree_ll, &tree_d, in, bp, inlength); - while(!error) /*decode all symbols until end reached, breaks at end code*/ - { - /*code_ll is literal, length or end code*/ - unsigned code_ll = huffmanDecodeSymbol(in, bp, &tree_ll, inbitlength); - if(code_ll <= 255) /*literal symbol*/ - { - /*ucvector_push_back would do the same, but for some reason the two lines below run 10% faster*/ - if(!ucvector_resize(out, (*pos) + 1)) ERROR_BREAK(83 /*alloc fail*/); - out->data[*pos] = (unsigned char)code_ll; - (*pos)++; - } - else if(code_ll >= FIRST_LENGTH_CODE_INDEX && code_ll <= LAST_LENGTH_CODE_INDEX) /*length code*/ - { - unsigned code_d, distance; - unsigned numextrabits_l, numextrabits_d; /*extra bits for length and distance*/ - size_t start, forward, backward, length; + while (!error) /*decode all symbols until end reached, breaks at end code*/ + { + /*code_ll is literal, length or end code*/ + unsigned code_ll = huffmanDecodeSymbol(in, bp, &tree_ll, inbitlength); + if (code_ll <= 255) /*literal symbol*/ + { + /*ucvector_push_back would do the same, but for some reason the two lines below run 10% faster*/ + if (!ucvector_resize(out, (*pos) + 1)) ERROR_BREAK(83 /*alloc fail*/); + out->data[*pos] = (unsigned char)code_ll; + (*pos)++; + } + else if (code_ll >= FIRST_LENGTH_CODE_INDEX && code_ll <= LAST_LENGTH_CODE_INDEX) /*length code*/ + { + unsigned code_d, distance; + unsigned numextrabits_l, numextrabits_d; /*extra bits for length and distance*/ + size_t start, forward, backward, length; - /*part 1: get length base*/ - length = LENGTHBASE[code_ll - FIRST_LENGTH_CODE_INDEX]; + /*part 1: get length base*/ + length = LENGTHBASE[code_ll - FIRST_LENGTH_CODE_INDEX]; - /*part 2: get extra bits and add the value of that to length*/ - numextrabits_l = LENGTHEXTRA[code_ll - FIRST_LENGTH_CODE_INDEX]; - if(*bp >= inbitlength) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/ - length += readBitsFromStream(bp, in, numextrabits_l); + /*part 2: get extra bits and add the value of that to length*/ + numextrabits_l = LENGTHEXTRA[code_ll - FIRST_LENGTH_CODE_INDEX]; + if (*bp >= inbitlength) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/ + length += readBitsFromStream(bp, in, numextrabits_l); - /*part 3: get distance code*/ - code_d = huffmanDecodeSymbol(in, bp, &tree_d, inbitlength); - if(code_d > 29) - { - if(code_ll == (unsigned)(-1)) /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ - { - /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol + /*part 3: get distance code*/ + code_d = huffmanDecodeSymbol(in, bp, &tree_d, inbitlength); + if (code_d > 29) + { + if (code_ll == (unsigned)(-1)) /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ + { + /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol (10=no endcode, 11=wrong jump outside of tree)*/ - error = (*bp) > inlength * 8 ? 10 : 11; - } - else error = 18; /*error: invalid distance code (30-31 are never used)*/ - break; - } - distance = DISTANCEBASE[code_d]; + error = (*bp) > inlength * 8 ? 10 : 11; + } + else + error = 18; /*error: invalid distance code (30-31 are never used)*/ + break; + } + distance = DISTANCEBASE[code_d]; - /*part 4: get extra bits from distance*/ - numextrabits_d = DISTANCEEXTRA[code_d]; - if(*bp >= inbitlength) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/ + /*part 4: get extra bits from distance*/ + numextrabits_d = DISTANCEEXTRA[code_d]; + if (*bp >= inbitlength) ERROR_BREAK(51); /*error, bit pointer will jump past memory*/ - distance += readBitsFromStream(bp, in, numextrabits_d); + distance += readBitsFromStream(bp, in, numextrabits_d); - /*part 5: fill in all the out[n] values based on the length and dist*/ - start = (*pos); - if(distance > start) ERROR_BREAK(52); /*too long backward distance*/ - backward = start - distance; + /*part 5: fill in all the out[n] values based on the length and dist*/ + start = (*pos); + if (distance > start) ERROR_BREAK(52); /*too long backward distance*/ + backward = start - distance; - if(!ucvector_resize(out, (*pos) + length)) ERROR_BREAK(83 /*alloc fail*/); - for(forward = 0; forward < length; forward++) - { - out->data[(*pos)] = out->data[backward]; - (*pos)++; - backward++; - if(backward >= start) backward = start - distance; - } - } - else if(code_ll == 256) - { - break; /*end code, break the loop*/ - } - else /*if(code == (unsigned)(-1))*/ /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ - { - /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol + if (!ucvector_resize(out, (*pos) + length)) ERROR_BREAK(83 /*alloc fail*/); + for (forward = 0; forward < length; forward++) + { + out->data[(*pos)] = out->data[backward]; + (*pos)++; + backward++; + if (backward >= start) backward = start - distance; + } + } + else if (code_ll == 256) + { + break; /*end code, break the loop*/ + } + else /*if(code == (unsigned)(-1))*/ /*huffmanDecodeSymbol returns (unsigned)(-1) in case of error*/ + { + /*return error code 10 or 11 depending on the situation that happened in huffmanDecodeSymbol (10=no endcode, 11=wrong jump outside of tree)*/ - error = (*bp) > inlength * 8 ? 10 : 11; - break; - } - } + error = (*bp) > inlength * 8 ? 10 : 11; + break; + } + } - HuffmanTree_cleanup(&tree_ll); - HuffmanTree_cleanup(&tree_d); + HuffmanTree_cleanup(&tree_ll); + HuffmanTree_cleanup(&tree_d); - return error; + return error; } static unsigned inflateNoCompression(ucvector* out, const unsigned char* in, size_t* bp, size_t* pos, size_t inlength) { - /*go to first boundary of byte*/ - size_t p; - unsigned LEN, NLEN, n, error = 0; - while(((*bp) & 0x7) != 0) (*bp)++; - p = (*bp) / 8; /*byte position*/ + /*go to first boundary of byte*/ + size_t p; + unsigned LEN, NLEN, n, error = 0; + while (((*bp) & 0x7) != 0) (*bp)++; + p = (*bp) / 8; /*byte position*/ - /*read LEN (2 bytes) and NLEN (2 bytes)*/ - if(p >= inlength - 4) return 52; /*error, bit pointer will jump past memory*/ - LEN = in[p] + 256u * in[p + 1]; p += 2; - NLEN = in[p] + 256u * in[p + 1]; p += 2; + /*read LEN (2 bytes) and NLEN (2 bytes)*/ + if (p >= inlength - 4) return 52; /*error, bit pointer will jump past memory*/ + LEN = in[p] + 256u * in[p + 1]; + p += 2; + NLEN = in[p] + 256u * in[p + 1]; + p += 2; - /*check if 16-bit NLEN is really the one's complement of LEN*/ - if(LEN + NLEN != 65535) return 21; /*error: NLEN is not one's complement of LEN*/ + /*check if 16-bit NLEN is really the one's complement of LEN*/ + if (LEN + NLEN != 65535) return 21; /*error: NLEN is not one's complement of LEN*/ - if(!ucvector_resize(out, (*pos) + LEN)) return 83; /*alloc fail*/ + if (!ucvector_resize(out, (*pos) + LEN)) return 83; /*alloc fail*/ - /*read the literal data: LEN bytes are now stored in the out buffer*/ - if(p + LEN > inlength) return 23; /*error: reading outside of in buffer*/ - for(n = 0; n < LEN; n++) out->data[(*pos)++] = in[p++]; + /*read the literal data: LEN bytes are now stored in the out buffer*/ + if (p + LEN > inlength) return 23; /*error: reading outside of in buffer*/ + for (n = 0; n < LEN; n++) out->data[(*pos)++] = in[p++]; - (*bp) = p * 8; + (*bp) = p * 8; - return error; + return error; } static unsigned lodepng_inflatev(ucvector* out, - const unsigned char* in, size_t insize, - const LodePNGDecompressSettings* settings) + const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings) { - /*bit pointer in the "in" data, current byte is bp >> 3, current bit is bp & 0x7 (from lsb to msb of the byte)*/ - size_t bp = 0; - unsigned BFINAL = 0; - size_t pos = 0; /*byte position in the out buffer*/ - unsigned error = 0; + /*bit pointer in the "in" data, current byte is bp >> 3, current bit is bp & 0x7 (from lsb to msb of the byte)*/ + size_t bp = 0; + unsigned BFINAL = 0; + size_t pos = 0; /*byte position in the out buffer*/ + unsigned error = 0; - (void)settings; + (void)settings; - while(!BFINAL) - { - unsigned BTYPE; - if(bp + 2 >= insize * 8) return 52; /*error, bit pointer will jump past memory*/ - BFINAL = readBitFromStream(&bp, in); - BTYPE = 1u * readBitFromStream(&bp, in); - BTYPE += 2u * readBitFromStream(&bp, in); + while (!BFINAL) + { + unsigned BTYPE; + if (bp + 2 >= insize * 8) return 52; /*error, bit pointer will jump past memory*/ + BFINAL = readBitFromStream(&bp, in); + BTYPE = 1u * readBitFromStream(&bp, in); + BTYPE += 2u * readBitFromStream(&bp, in); - if(BTYPE == 3) return 20; /*error: invalid BTYPE*/ - else if(BTYPE == 0) error = inflateNoCompression(out, in, &bp, &pos, insize); /*no compression*/ - else error = inflateHuffmanBlock(out, in, &bp, &pos, insize, BTYPE); /*compression, BTYPE 01 or 10*/ + if (BTYPE == 3) + return 20; /*error: invalid BTYPE*/ + else if (BTYPE == 0) + error = inflateNoCompression(out, in, &bp, &pos, insize); /*no compression*/ + else + error = inflateHuffmanBlock(out, in, &bp, &pos, insize, BTYPE); /*compression, BTYPE 01 or 10*/ - if(error) return error; - } + if (error) return error; + } - return error; + return error; } unsigned lodepng_inflate(unsigned char** out, size_t* outsize, - const unsigned char* in, size_t insize, - const LodePNGDecompressSettings* settings) + const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings) { - unsigned error; - ucvector v; - ucvector_init_buffer(&v, *out, *outsize); - error = lodepng_inflatev(&v, in, insize, settings); - *out = v.data; - *outsize = v.size; - return error; + unsigned error; + ucvector v; + ucvector_init_buffer(&v, *out, *outsize); + error = lodepng_inflatev(&v, in, insize, settings); + *out = v.data; + *outsize = v.size; + return error; } static unsigned inflate(unsigned char** out, size_t* outsize, - const unsigned char* in, size_t insize, - const LodePNGDecompressSettings* settings) + const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings) { - if(settings->custom_inflate) - { - return settings->custom_inflate(out, outsize, in, insize, settings); - } - else - { - return lodepng_inflate(out, outsize, in, insize, settings); - } + if (settings->custom_inflate) + { + return settings->custom_inflate(out, outsize, in, insize, settings); + } + else + { + return lodepng_inflate(out, outsize, in, insize, settings); + } } #endif /*LODEPNG_COMPILE_DECODER*/ @@ -1290,47 +1316,50 @@ static const size_t MAX_SUPPORTED_DEFLATE_LENGTH = 258; /*bitlen is the size in bits of the code*/ static void addHuffmanSymbol(size_t* bp, ucvector* compressed, unsigned code, unsigned bitlen) { - addBitsToStreamReversed(bp, compressed, code, bitlen); + addBitsToStreamReversed(bp, compressed, code, bitlen); } /*search the index in the array, that has the largest value smaller than or equal to the given value, given array must be sorted (if no value is smaller, it returns the size of the given array)*/ static size_t searchCodeIndex(const unsigned* array, size_t array_size, size_t value) { - /*linear search implementation*/ - /*for(size_t i = 1; i < array_size; i++) if(array[i] > value) return i - 1; + /*linear search implementation*/ + /*for(size_t i = 1; i < array_size; i++) if(array[i] > value) return i - 1; return array_size - 1;*/ - /*binary search implementation (not that much faster) (precondition: array_size > 0)*/ - size_t left = 1; - size_t right = array_size - 1; - while(left <= right) - { - size_t mid = (left + right) / 2; - if(array[mid] <= value) left = mid + 1; /*the value to find is more to the right*/ - else if(array[mid - 1] > value) right = mid - 1; /*the value to find is more to the left*/ - else return mid - 1; - } - return array_size - 1; + /*binary search implementation (not that much faster) (precondition: array_size > 0)*/ + size_t left = 1; + size_t right = array_size - 1; + while (left <= right) + { + size_t mid = (left + right) / 2; + if (array[mid] <= value) + left = mid + 1; /*the value to find is more to the right*/ + else if (array[mid - 1] > value) + right = mid - 1; /*the value to find is more to the left*/ + else + return mid - 1; + } + return array_size - 1; } static void addLengthDistance(uivector* values, size_t length, size_t distance) { - /*values in encoded vector are those used by deflate: + /*values in encoded vector are those used by deflate: 0-255: literal bytes 256: end 257-285: length/distance pair (length code, followed by extra length bits, distance code, extra distance bits) 286-287: invalid*/ - unsigned length_code = (unsigned)searchCodeIndex(LENGTHBASE, 29, length); - unsigned extra_length = (unsigned)(length - LENGTHBASE[length_code]); - unsigned dist_code = (unsigned)searchCodeIndex(DISTANCEBASE, 30, distance); - unsigned extra_distance = (unsigned)(distance - DISTANCEBASE[dist_code]); + unsigned length_code = (unsigned)searchCodeIndex(LENGTHBASE, 29, length); + unsigned extra_length = (unsigned)(length - LENGTHBASE[length_code]); + unsigned dist_code = (unsigned)searchCodeIndex(DISTANCEBASE, 30, distance); + unsigned extra_distance = (unsigned)(distance - DISTANCEBASE[dist_code]); - uivector_push_back(values, length_code + FIRST_LENGTH_CODE_INDEX); - uivector_push_back(values, extra_length); - uivector_push_back(values, dist_code); - uivector_push_back(values, extra_distance); + uivector_push_back(values, length_code + FIRST_LENGTH_CODE_INDEX); + uivector_push_back(values, extra_length); + uivector_push_back(values, dist_code); + uivector_push_back(values, extra_distance); } /*3 bytes of data get encoded into two bytes. The hash cannot use more than 3 @@ -1340,100 +1369,100 @@ static const unsigned HASH_BIT_MASK = 65535; /*HASH_NUM_VALUES - 1, but C90 does typedef struct Hash { - int* head; /*hash value to head circular pos - can be outdated if went around window*/ - /*circular pos to prev circular pos*/ - unsigned short* chain; - int* val; /*circular pos to hash value*/ + int* head; /*hash value to head circular pos - can be outdated if went around window*/ + /*circular pos to prev circular pos*/ + unsigned short* chain; + int* val; /*circular pos to hash value*/ - /*TODO: do this not only for zeros but for any repeated byte. However for PNG + /*TODO: do this not only for zeros but for any repeated byte. However for PNG it's always going to be the zeros that dominate, so not important for PNG*/ - int* headz; /*similar to head, but for chainz*/ - unsigned short* chainz; /*those with same amount of zeros*/ - unsigned short* zeros; /*length of zeros streak, used as a second hash chain*/ + int* headz; /*similar to head, but for chainz*/ + unsigned short* chainz; /*those with same amount of zeros*/ + unsigned short* zeros; /*length of zeros streak, used as a second hash chain*/ } Hash; static unsigned hash_init(Hash* hash, unsigned windowsize) { - unsigned i; - hash->head = (int*)lodepng_malloc(sizeof(int) * HASH_NUM_VALUES); - hash->val = (int*)lodepng_malloc(sizeof(int) * windowsize); - hash->chain = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); + unsigned i; + hash->head = (int*)lodepng_malloc(sizeof(int) * HASH_NUM_VALUES); + hash->val = (int*)lodepng_malloc(sizeof(int) * windowsize); + hash->chain = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); - hash->zeros = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); - hash->headz = (int*)lodepng_malloc(sizeof(int) * (MAX_SUPPORTED_DEFLATE_LENGTH + 1)); - hash->chainz = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); + hash->zeros = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); + hash->headz = (int*)lodepng_malloc(sizeof(int) * (MAX_SUPPORTED_DEFLATE_LENGTH + 1)); + hash->chainz = (unsigned short*)lodepng_malloc(sizeof(unsigned short) * windowsize); - if(!hash->head || !hash->chain || !hash->val || !hash->headz|| !hash->chainz || !hash->zeros) - { - return 83; /*alloc fail*/ - } + if (!hash->head || !hash->chain || !hash->val || !hash->headz || !hash->chainz || !hash->zeros) + { + return 83; /*alloc fail*/ + } - /*initialize hash table*/ - for(i = 0; i < HASH_NUM_VALUES; i++) hash->head[i] = -1; - for(i = 0; i < windowsize; i++) hash->val[i] = -1; - for(i = 0; i < windowsize; i++) hash->chain[i] = i; /*same value as index indicates uninitialized*/ + /*initialize hash table*/ + for (i = 0; i < HASH_NUM_VALUES; i++) hash->head[i] = -1; + for (i = 0; i < windowsize; i++) hash->val[i] = -1; + for (i = 0; i < windowsize; i++) hash->chain[i] = i; /*same value as index indicates uninitialized*/ - for(i = 0; i <= MAX_SUPPORTED_DEFLATE_LENGTH; i++) hash->headz[i] = -1; - for(i = 0; i < windowsize; i++) hash->chainz[i] = i; /*same value as index indicates uninitialized*/ + for (i = 0; i <= MAX_SUPPORTED_DEFLATE_LENGTH; i++) hash->headz[i] = -1; + for (i = 0; i < windowsize; i++) hash->chainz[i] = i; /*same value as index indicates uninitialized*/ - return 0; + return 0; } static void hash_cleanup(Hash* hash) { - lodepng_free(hash->head); - lodepng_free(hash->val); - lodepng_free(hash->chain); + lodepng_free(hash->head); + lodepng_free(hash->val); + lodepng_free(hash->chain); - lodepng_free(hash->zeros); - lodepng_free(hash->headz); - lodepng_free(hash->chainz); + lodepng_free(hash->zeros); + lodepng_free(hash->headz); + lodepng_free(hash->chainz); } - - static unsigned getHash(const unsigned char* data, size_t size, size_t pos) { - unsigned result = 0; - if (pos + 2 < size) - { - /*A simple shift and xor hash is used. Since the data of PNGs is dominated + unsigned result = 0; + if (pos + 2 < size) + { + /*A simple shift and xor hash is used. Since the data of PNGs is dominated by zeroes due to the filters, a better hash does not have a significant effect on speed in traversing the chain, and causes more time spend on calculating the hash.*/ - result ^= (unsigned)(data[pos + 0] << 0u); - result ^= (unsigned)(data[pos + 1] << 4u); - result ^= (unsigned)(data[pos + 2] << 8u); - } else { - size_t amount, i; - if(pos >= size) return 0; - amount = size - pos; - for(i = 0; i < amount; i++) result ^= (unsigned)(data[pos + i] << (i * 8u)); - } - return result & HASH_BIT_MASK; + result ^= (unsigned)(data[pos + 0] << 0u); + result ^= (unsigned)(data[pos + 1] << 4u); + result ^= (unsigned)(data[pos + 2] << 8u); + } + else + { + size_t amount, i; + if (pos >= size) return 0; + amount = size - pos; + for (i = 0; i < amount; i++) result ^= (unsigned)(data[pos + i] << (i * 8u)); + } + return result & HASH_BIT_MASK; } static unsigned countZeros(const unsigned char* data, size_t size, size_t pos) { - const unsigned char* start = data + pos; - const unsigned char* end = start + MAX_SUPPORTED_DEFLATE_LENGTH; - if(end > data + size) end = data + size; - data = start; - while (data != end && *data == 0) data++; - /*subtracting two addresses returned as 32-bit number (max value is MAX_SUPPORTED_DEFLATE_LENGTH)*/ - return (unsigned)(data - start); + const unsigned char* start = data + pos; + const unsigned char* end = start + MAX_SUPPORTED_DEFLATE_LENGTH; + if (end > data + size) end = data + size; + data = start; + while (data != end && *data == 0) data++; + /*subtracting two addresses returned as 32-bit number (max value is MAX_SUPPORTED_DEFLATE_LENGTH)*/ + return (unsigned)(data - start); } /*wpos = pos & (windowsize - 1)*/ static void updateHashChain(Hash* hash, size_t wpos, unsigned hashval, unsigned short numzeros) { - hash->val[wpos] = (int)hashval; - if(hash->head[hashval] != -1) hash->chain[wpos] = hash->head[hashval]; - hash->head[hashval] = wpos; + hash->val[wpos] = (int)hashval; + if (hash->head[hashval] != -1) hash->chain[wpos] = hash->head[hashval]; + hash->head[hashval] = wpos; - hash->zeros[wpos] = numzeros; - if(hash->headz[numzeros] != -1) hash->chainz[wpos] = hash->headz[numzeros]; - hash->headz[numzeros] = wpos; + hash->zeros[wpos] = numzeros; + if (hash->headz[numzeros] != -1) hash->chainz[wpos] = hash->headz[numzeros]; + hash->headz[numzeros] = wpos; } /* @@ -1446,216 +1475,223 @@ the "dictionary". A brute force search through all possible distances would be s this hash technique is one out of several ways to speed this up. */ static unsigned encodeLZ77(uivector* out, Hash* hash, - const unsigned char* in, size_t inpos, size_t insize, unsigned windowsize, - unsigned minmatch, unsigned nicematch, unsigned lazymatching) + const unsigned char* in, size_t inpos, size_t insize, unsigned windowsize, + unsigned minmatch, unsigned nicematch, unsigned lazymatching) { - size_t pos; - unsigned i, error = 0; - /*for large window lengths, assume the user wants no compression loss. Otherwise, max hash chain length speedup.*/ - unsigned maxchainlength = windowsize >= 8192 ? windowsize : windowsize / 8; - unsigned maxlazymatch = windowsize >= 8192 ? MAX_SUPPORTED_DEFLATE_LENGTH : 64; + size_t pos; + unsigned i, error = 0; + /*for large window lengths, assume the user wants no compression loss. Otherwise, max hash chain length speedup.*/ + unsigned maxchainlength = windowsize >= 8192 ? windowsize : windowsize / 8; + unsigned maxlazymatch = windowsize >= 8192 ? MAX_SUPPORTED_DEFLATE_LENGTH : 64; - unsigned usezeros = 1; /*not sure if setting it to false for windowsize < 8192 is better or worse*/ - unsigned numzeros = 0; + unsigned usezeros = 1; /*not sure if setting it to false for windowsize < 8192 is better or worse*/ + unsigned numzeros = 0; - unsigned offset; /*the offset represents the distance in LZ77 terminology*/ - unsigned length; - unsigned lazy = 0; - unsigned lazylength = 0, lazyoffset = 0; - unsigned hashval; - unsigned current_offset, current_length; - unsigned prev_offset; - const unsigned char *lastptr, *foreptr, *backptr; - unsigned hashpos; + unsigned offset; /*the offset represents the distance in LZ77 terminology*/ + unsigned length; + unsigned lazy = 0; + unsigned lazylength = 0, lazyoffset = 0; + unsigned hashval; + unsigned current_offset, current_length; + unsigned prev_offset; + const unsigned char *lastptr, *foreptr, *backptr; + unsigned hashpos; - if(windowsize <= 0 || windowsize > 32768) return 60; /*error: windowsize smaller/larger than allowed*/ - if((windowsize & (windowsize - 1)) != 0) return 90; /*error: must be power of two*/ + if (windowsize <= 0 || windowsize > 32768) return 60; /*error: windowsize smaller/larger than allowed*/ + if ((windowsize & (windowsize - 1)) != 0) return 90; /*error: must be power of two*/ - if(nicematch > MAX_SUPPORTED_DEFLATE_LENGTH) nicematch = MAX_SUPPORTED_DEFLATE_LENGTH; + if (nicematch > MAX_SUPPORTED_DEFLATE_LENGTH) nicematch = MAX_SUPPORTED_DEFLATE_LENGTH; - for(pos = inpos; pos < insize; pos++) - { - size_t wpos = pos & (windowsize - 1); /*position for in 'circular' hash buffers*/ - unsigned chainlength = 0; + for (pos = inpos; pos < insize; pos++) + { + size_t wpos = pos & (windowsize - 1); /*position for in 'circular' hash buffers*/ + unsigned chainlength = 0; - hashval = getHash(in, insize, pos); + hashval = getHash(in, insize, pos); - if(usezeros && hashval == 0) - { - if (numzeros == 0) numzeros = countZeros(in, insize, pos); - else if (pos + numzeros > insize || in[pos + numzeros - 1] != 0) numzeros--; - } - else - { - numzeros = 0; - } + if (usezeros && hashval == 0) + { + if (numzeros == 0) + numzeros = countZeros(in, insize, pos); + else if (pos + numzeros > insize || in[pos + numzeros - 1] != 0) + numzeros--; + } + else + { + numzeros = 0; + } - updateHashChain(hash, wpos, hashval, numzeros); + updateHashChain(hash, wpos, hashval, numzeros); - /*the length and offset found for the current position*/ - length = 0; - offset = 0; + /*the length and offset found for the current position*/ + length = 0; + offset = 0; - hashpos = hash->chain[wpos]; + hashpos = hash->chain[wpos]; - lastptr = &in[insize < pos + MAX_SUPPORTED_DEFLATE_LENGTH ? insize : pos + MAX_SUPPORTED_DEFLATE_LENGTH]; + lastptr = &in[insize < pos + MAX_SUPPORTED_DEFLATE_LENGTH ? insize : pos + MAX_SUPPORTED_DEFLATE_LENGTH]; - /*search for the longest string*/ - prev_offset = 0; - for(;;) - { - if(chainlength++ >= maxchainlength) break; - current_offset = hashpos <= wpos ? wpos - hashpos : wpos - hashpos + windowsize; + /*search for the longest string*/ + prev_offset = 0; + for (;;) + { + if (chainlength++ >= maxchainlength) break; + current_offset = hashpos <= wpos ? wpos - hashpos : wpos - hashpos + windowsize; - if(current_offset < prev_offset) break; /*stop when went completely around the circular buffer*/ - prev_offset = current_offset; - if(current_offset > 0) - { - /*test the next characters*/ - foreptr = &in[pos]; - backptr = &in[pos - current_offset]; + if (current_offset < prev_offset) break; /*stop when went completely around the circular buffer*/ + prev_offset = current_offset; + if (current_offset > 0) + { + /*test the next characters*/ + foreptr = &in[pos]; + backptr = &in[pos - current_offset]; - /*common case in PNGs is lots of zeros. Quickly skip over them as a speedup*/ - if(numzeros >= 3) - { - unsigned skip = hash->zeros[hashpos]; - if(skip > numzeros) skip = numzeros; - backptr += skip; - foreptr += skip; - } + /*common case in PNGs is lots of zeros. Quickly skip over them as a speedup*/ + if (numzeros >= 3) + { + unsigned skip = hash->zeros[hashpos]; + if (skip > numzeros) skip = numzeros; + backptr += skip; + foreptr += skip; + } - while(foreptr != lastptr && *backptr == *foreptr) /*maximum supported length by deflate is max length*/ - { - ++backptr; - ++foreptr; - } - current_length = (unsigned)(foreptr - &in[pos]); + while (foreptr != lastptr && *backptr == *foreptr) /*maximum supported length by deflate is max length*/ + { + ++backptr; + ++foreptr; + } + current_length = (unsigned)(foreptr - &in[pos]); - if(current_length > length) - { - length = current_length; /*the longest length*/ - offset = current_offset; /*the offset that is related to this longest length*/ - /*jump out once a length of max length is found (speed gain). This also jumps + if (current_length > length) + { + length = current_length; /*the longest length*/ + offset = current_offset; /*the offset that is related to this longest length*/ + /*jump out once a length of max length is found (speed gain). This also jumps out if length is MAX_SUPPORTED_DEFLATE_LENGTH*/ - if(current_length >= nicematch) break; - } - } + if (current_length >= nicematch) break; + } + } - if(hashpos == hash->chain[hashpos]) break; - - if(numzeros >= 3 && length > numzeros) { - hashpos = hash->chainz[hashpos]; - if(hash->zeros[hashpos] != numzeros) break; - } else { - hashpos = hash->chain[hashpos]; - /*outdated hash value, happens if particular value was not encountered in whole last window*/ - if(hash->val[hashpos] != (int)hashval) break; - } - } + if (hashpos == hash->chain[hashpos]) break; - if(lazymatching) - { - if(!lazy && length >= 3 && length <= maxlazymatch && length < MAX_SUPPORTED_DEFLATE_LENGTH) - { - lazy = 1; - lazylength = length; - lazyoffset = offset; - continue; /*try the next byte*/ - } - if(lazy) - { - lazy = 0; - if(pos == 0) ERROR_BREAK(81); - if(length > lazylength + 1) - { - /*push the previous character as literal*/ - if(!uivector_push_back(out, in[pos - 1])) ERROR_BREAK(83 /*alloc fail*/); - } - else - { - length = lazylength; - offset = lazyoffset; - hash->head[hashval] = -1; /*the same hashchain update will be done, this ensures no wrong alteration*/ - hash->headz[numzeros] = -1; /*idem*/ - pos--; - } - } - } - if(length >= 3 && offset > windowsize) ERROR_BREAK(86 /*too big (or overflown negative) offset*/); + if (numzeros >= 3 && length > numzeros) + { + hashpos = hash->chainz[hashpos]; + if (hash->zeros[hashpos] != numzeros) break; + } + else + { + hashpos = hash->chain[hashpos]; + /*outdated hash value, happens if particular value was not encountered in whole last window*/ + if (hash->val[hashpos] != (int)hashval) break; + } + } - /*encode it as length/distance pair or literal value*/ - if(length < 3) /*only lengths of 3 or higher are supported as length/distance pair*/ - { - if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/); - } - else if(length < minmatch || (length == 3 && offset > 4096)) - { - /*compensate for the fact that longer offsets have more extra bits, a + if (lazymatching) + { + if (!lazy && length >= 3 && length <= maxlazymatch && length < MAX_SUPPORTED_DEFLATE_LENGTH) + { + lazy = 1; + lazylength = length; + lazyoffset = offset; + continue; /*try the next byte*/ + } + if (lazy) + { + lazy = 0; + if (pos == 0) ERROR_BREAK(81); + if (length > lazylength + 1) + { + /*push the previous character as literal*/ + if (!uivector_push_back(out, in[pos - 1])) ERROR_BREAK(83 /*alloc fail*/); + } + else + { + length = lazylength; + offset = lazyoffset; + hash->head[hashval] = -1; /*the same hashchain update will be done, this ensures no wrong alteration*/ + hash->headz[numzeros] = -1; /*idem*/ + pos--; + } + } + } + if (length >= 3 && offset > windowsize) ERROR_BREAK(86 /*too big (or overflown negative) offset*/); + + /*encode it as length/distance pair or literal value*/ + if (length < 3) /*only lengths of 3 or higher are supported as length/distance pair*/ + { + if (!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/); + } + else if (length < minmatch || (length == 3 && offset > 4096)) + { + /*compensate for the fact that longer offsets have more extra bits, a length of only 3 may be not worth it then*/ - if(!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/); - } - else - { - addLengthDistance(out, length, offset); - for(i = 1; i < length; i++) - { - pos++; - wpos = pos & (windowsize - 1); - hashval = getHash(in, insize, pos); - if(usezeros && hashval == 0) - { - if (numzeros == 0) numzeros = countZeros(in, insize, pos); - else if (pos + numzeros > insize || in[pos + numzeros - 1] != 0) numzeros--; - } - else - { - numzeros = 0; - } - updateHashChain(hash, wpos, hashval, numzeros); - } - } - } /*end of the loop through each character of input*/ + if (!uivector_push_back(out, in[pos])) ERROR_BREAK(83 /*alloc fail*/); + } + else + { + addLengthDistance(out, length, offset); + for (i = 1; i < length; i++) + { + pos++; + wpos = pos & (windowsize - 1); + hashval = getHash(in, insize, pos); + if (usezeros && hashval == 0) + { + if (numzeros == 0) + numzeros = countZeros(in, insize, pos); + else if (pos + numzeros > insize || in[pos + numzeros - 1] != 0) + numzeros--; + } + else + { + numzeros = 0; + } + updateHashChain(hash, wpos, hashval, numzeros); + } + } + } /*end of the loop through each character of input*/ - return error; + return error; } /* /////////////////////////////////////////////////////////////////////////// */ static unsigned deflateNoCompression(ucvector* out, const unsigned char* data, size_t datasize) { - /*non compressed deflate block data: 1 bit BFINAL,2 bits BTYPE,(5 bits): it jumps to start of next byte, + /*non compressed deflate block data: 1 bit BFINAL,2 bits BTYPE,(5 bits): it jumps to start of next byte, 2 bytes LEN, 2 bytes NLEN, LEN bytes literal DATA*/ - size_t i, j, numdeflateblocks = (datasize + 65534) / 65535; - unsigned datapos = 0; - for(i = 0; i < numdeflateblocks; i++) - { - unsigned BFINAL, BTYPE, LEN, NLEN; - unsigned char firstbyte; + size_t i, j, numdeflateblocks = (datasize + 65534) / 65535; + unsigned datapos = 0; + for (i = 0; i < numdeflateblocks; i++) + { + unsigned BFINAL, BTYPE, LEN, NLEN; + unsigned char firstbyte; - BFINAL = (i == numdeflateblocks - 1); - BTYPE = 0; + BFINAL = (i == numdeflateblocks - 1); + BTYPE = 0; - firstbyte = (unsigned char)(BFINAL + ((BTYPE & 1) << 1) + ((BTYPE & 2) << 1)); - ucvector_push_back(out, firstbyte); + firstbyte = (unsigned char)(BFINAL + ((BTYPE & 1) << 1) + ((BTYPE & 2) << 1)); + ucvector_push_back(out, firstbyte); - LEN = 65535; - if(datasize - datapos < 65535) LEN = (unsigned)datasize - datapos; - NLEN = 65535 - LEN; + LEN = 65535; + if (datasize - datapos < 65535) LEN = (unsigned)datasize - datapos; + NLEN = 65535 - LEN; - ucvector_push_back(out, (unsigned char)(LEN % 256)); - ucvector_push_back(out, (unsigned char)(LEN / 256)); - ucvector_push_back(out, (unsigned char)(NLEN % 256)); - ucvector_push_back(out, (unsigned char)(NLEN / 256)); + ucvector_push_back(out, (unsigned char)(LEN % 256)); + ucvector_push_back(out, (unsigned char)(LEN / 256)); + ucvector_push_back(out, (unsigned char)(NLEN % 256)); + ucvector_push_back(out, (unsigned char)(NLEN / 256)); - /*Decompressed data*/ - for(j = 0; j < 65535 && datapos < datasize; j++) - { - ucvector_push_back(out, data[datapos++]); - } - } + /*Decompressed data*/ + for (j = 0; j < 65535 && datapos < datasize; j++) + { + ucvector_push_back(out, data[datapos++]); + } + } - return 0; + return 0; } /* @@ -1664,41 +1700,41 @@ tree_ll: the tree for lit and len codes. tree_d: the tree for distance codes. */ static void writeLZ77data(size_t* bp, ucvector* out, const uivector* lz77_encoded, - const HuffmanTree* tree_ll, const HuffmanTree* tree_d) + const HuffmanTree* tree_ll, const HuffmanTree* tree_d) { - size_t i = 0; - for(i = 0; i < lz77_encoded->size; i++) - { - unsigned val = lz77_encoded->data[i]; - addHuffmanSymbol(bp, out, HuffmanTree_getCode(tree_ll, val), HuffmanTree_getLength(tree_ll, val)); - if(val > 256) /*for a length code, 3 more things have to be added*/ - { - unsigned length_index = val - FIRST_LENGTH_CODE_INDEX; - unsigned n_length_extra_bits = LENGTHEXTRA[length_index]; - unsigned length_extra_bits = lz77_encoded->data[++i]; + size_t i = 0; + for (i = 0; i < lz77_encoded->size; i++) + { + unsigned val = lz77_encoded->data[i]; + addHuffmanSymbol(bp, out, HuffmanTree_getCode(tree_ll, val), HuffmanTree_getLength(tree_ll, val)); + if (val > 256) /*for a length code, 3 more things have to be added*/ + { + unsigned length_index = val - FIRST_LENGTH_CODE_INDEX; + unsigned n_length_extra_bits = LENGTHEXTRA[length_index]; + unsigned length_extra_bits = lz77_encoded->data[++i]; - unsigned distance_code = lz77_encoded->data[++i]; + unsigned distance_code = lz77_encoded->data[++i]; - unsigned distance_index = distance_code; - unsigned n_distance_extra_bits = DISTANCEEXTRA[distance_index]; - unsigned distance_extra_bits = lz77_encoded->data[++i]; + unsigned distance_index = distance_code; + unsigned n_distance_extra_bits = DISTANCEEXTRA[distance_index]; + unsigned distance_extra_bits = lz77_encoded->data[++i]; - addBitsToStream(bp, out, length_extra_bits, n_length_extra_bits); - addHuffmanSymbol(bp, out, HuffmanTree_getCode(tree_d, distance_code), - HuffmanTree_getLength(tree_d, distance_code)); - addBitsToStream(bp, out, distance_extra_bits, n_distance_extra_bits); - } - } + addBitsToStream(bp, out, length_extra_bits, n_length_extra_bits); + addHuffmanSymbol(bp, out, HuffmanTree_getCode(tree_d, distance_code), + HuffmanTree_getLength(tree_d, distance_code)); + addBitsToStream(bp, out, distance_extra_bits, n_distance_extra_bits); + } + } } /*Deflate for a block of type "dynamic", that is, with freely, optimally, created huffman trees*/ static unsigned deflateDynamic(ucvector* out, size_t* bp, Hash* hash, - const unsigned char* data, size_t datapos, size_t dataend, - const LodePNGCompressSettings* settings, unsigned final) + const unsigned char* data, size_t datapos, size_t dataend, + const LodePNGCompressSettings* settings, unsigned final) { - unsigned error = 0; + unsigned error = 0; - /* + /* A block is compressed as follows: The PNG data is lz77 encoded, resulting in literal bytes and length/distance pairs. This is then huffman compressed with two huffman trees. One huffman tree is used for the lit and len values ("ll"), @@ -1709,166 +1745,169 @@ static unsigned deflateDynamic(ucvector* out, size_t* bp, Hash* hash, the code length code lengths ("clcl"). */ - /*The lz77 encoded data, represented with integers since there will also be length and distance codes in it*/ - uivector lz77_encoded; - HuffmanTree tree_ll; /*tree for lit,len values*/ - HuffmanTree tree_d; /*tree for distance codes*/ - HuffmanTree tree_cl; /*tree for encoding the code lengths representing tree_ll and tree_d*/ - uivector frequencies_ll; /*frequency of lit,len codes*/ - uivector frequencies_d; /*frequency of dist codes*/ - uivector frequencies_cl; /*frequency of code length codes*/ - uivector bitlen_lld; /*lit,len,dist code lenghts (int bits), literally (without repeat codes).*/ - uivector bitlen_lld_e; /*bitlen_lld encoded with repeat codes (this is a rudemtary run length compression)*/ - /*bitlen_cl is the code length code lengths ("clcl"). The bit lengths of codes to represent tree_cl + /*The lz77 encoded data, represented with integers since there will also be length and distance codes in it*/ + uivector lz77_encoded; + HuffmanTree tree_ll; /*tree for lit,len values*/ + HuffmanTree tree_d; /*tree for distance codes*/ + HuffmanTree tree_cl; /*tree for encoding the code lengths representing tree_ll and tree_d*/ + uivector frequencies_ll; /*frequency of lit,len codes*/ + uivector frequencies_d; /*frequency of dist codes*/ + uivector frequencies_cl; /*frequency of code length codes*/ + uivector bitlen_lld; /*lit,len,dist code lenghts (int bits), literally (without repeat codes).*/ + uivector bitlen_lld_e; /*bitlen_lld encoded with repeat codes (this is a rudemtary run length compression)*/ + /*bitlen_cl is the code length code lengths ("clcl"). The bit lengths of codes to represent tree_cl (these are written as is in the file, it would be crazy to compress these using yet another huffman tree that needs to be represented by yet another set of code lengths)*/ - uivector bitlen_cl; - size_t datasize = dataend - datapos; + uivector bitlen_cl; + size_t datasize = dataend - datapos; - /* + /* Due to the huffman compression of huffman tree representations ("two levels"), there are some anologies: bitlen_lld is to tree_cl what data is to tree_ll and tree_d. bitlen_lld_e is to bitlen_lld what lz77_encoded is to data. bitlen_cl is to bitlen_lld_e what bitlen_lld is to lz77_encoded. */ - unsigned BFINAL = final; - size_t numcodes_ll, numcodes_d, i; - unsigned HLIT, HDIST, HCLEN; + unsigned BFINAL = final; + size_t numcodes_ll, numcodes_d, i; + unsigned HLIT, HDIST, HCLEN; - uivector_init(&lz77_encoded); - HuffmanTree_init(&tree_ll); - HuffmanTree_init(&tree_d); - HuffmanTree_init(&tree_cl); - uivector_init(&frequencies_ll); - uivector_init(&frequencies_d); - uivector_init(&frequencies_cl); - uivector_init(&bitlen_lld); - uivector_init(&bitlen_lld_e); - uivector_init(&bitlen_cl); + uivector_init(&lz77_encoded); + HuffmanTree_init(&tree_ll); + HuffmanTree_init(&tree_d); + HuffmanTree_init(&tree_cl); + uivector_init(&frequencies_ll); + uivector_init(&frequencies_d); + uivector_init(&frequencies_cl); + uivector_init(&bitlen_lld); + uivector_init(&bitlen_lld_e); + uivector_init(&bitlen_cl); - /*This while loop never loops due to a break at the end, it is here to + /*This while loop never loops due to a break at the end, it is here to allow breaking out of it to the cleanup phase on error conditions.*/ - while(!error) - { - if(settings->use_lz77) - { - error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize, - settings->minmatch, settings->nicematch, settings->lazymatching); - if(error) break; - } - else - { - if(!uivector_resize(&lz77_encoded, datasize)) ERROR_BREAK(83 /*alloc fail*/); - for(i = datapos; i < dataend; i++) lz77_encoded.data[i] = data[i]; /*no LZ77, but still will be Huffman compressed*/ - } + while (!error) + { + if (settings->use_lz77) + { + error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize, + settings->minmatch, settings->nicematch, settings->lazymatching); + if (error) break; + } + else + { + if (!uivector_resize(&lz77_encoded, datasize)) ERROR_BREAK(83 /*alloc fail*/); + for (i = datapos; i < dataend; i++) lz77_encoded.data[i] = data[i]; /*no LZ77, but still will be Huffman compressed*/ + } - if(!uivector_resizev(&frequencies_ll, 286, 0)) ERROR_BREAK(83 /*alloc fail*/); - if(!uivector_resizev(&frequencies_d, 30, 0)) ERROR_BREAK(83 /*alloc fail*/); + if (!uivector_resizev(&frequencies_ll, 286, 0)) ERROR_BREAK(83 /*alloc fail*/); + if (!uivector_resizev(&frequencies_d, 30, 0)) ERROR_BREAK(83 /*alloc fail*/); - /*Count the frequencies of lit, len and dist codes*/ - for(i = 0; i < lz77_encoded.size; i++) - { - unsigned symbol = lz77_encoded.data[i]; - frequencies_ll.data[symbol]++; - if(symbol > 256) - { - unsigned dist = lz77_encoded.data[i + 2]; - frequencies_d.data[dist]++; - i += 3; - } - } - frequencies_ll.data[256] = 1; /*there will be exactly 1 end code, at the end of the block*/ + /*Count the frequencies of lit, len and dist codes*/ + for (i = 0; i < lz77_encoded.size; i++) + { + unsigned symbol = lz77_encoded.data[i]; + frequencies_ll.data[symbol]++; + if (symbol > 256) + { + unsigned dist = lz77_encoded.data[i + 2]; + frequencies_d.data[dist]++; + i += 3; + } + } + frequencies_ll.data[256] = 1; /*there will be exactly 1 end code, at the end of the block*/ - /*Make both huffman trees, one for the lit and len codes, one for the dist codes*/ - error = HuffmanTree_makeFromFrequencies(&tree_ll, frequencies_ll.data, 257, frequencies_ll.size, 15); - if(error) break; - /*2, not 1, is chosen for mincodes: some buggy PNG decoders require at least 2 symbols in the dist tree*/ - error = HuffmanTree_makeFromFrequencies(&tree_d, frequencies_d.data, 2, frequencies_d.size, 15); - if(error) break; + /*Make both huffman trees, one for the lit and len codes, one for the dist codes*/ + error = HuffmanTree_makeFromFrequencies(&tree_ll, frequencies_ll.data, 257, frequencies_ll.size, 15); + if (error) break; + /*2, not 1, is chosen for mincodes: some buggy PNG decoders require at least 2 symbols in the dist tree*/ + error = HuffmanTree_makeFromFrequencies(&tree_d, frequencies_d.data, 2, frequencies_d.size, 15); + if (error) break; - numcodes_ll = tree_ll.numcodes; if(numcodes_ll > 286) numcodes_ll = 286; - numcodes_d = tree_d.numcodes; if(numcodes_d > 30) numcodes_d = 30; - /*store the code lengths of both generated trees in bitlen_lld*/ - for(i = 0; i < numcodes_ll; i++) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_ll, (unsigned)i)); - for(i = 0; i < numcodes_d; i++) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_d, (unsigned)i)); + numcodes_ll = tree_ll.numcodes; + if (numcodes_ll > 286) numcodes_ll = 286; + numcodes_d = tree_d.numcodes; + if (numcodes_d > 30) numcodes_d = 30; + /*store the code lengths of both generated trees in bitlen_lld*/ + for (i = 0; i < numcodes_ll; i++) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_ll, (unsigned)i)); + for (i = 0; i < numcodes_d; i++) uivector_push_back(&bitlen_lld, HuffmanTree_getLength(&tree_d, (unsigned)i)); - /*run-length compress bitlen_ldd into bitlen_lld_e by using repeat codes 16 (copy length 3-6 times), + /*run-length compress bitlen_ldd into bitlen_lld_e by using repeat codes 16 (copy length 3-6 times), 17 (3-10 zeroes), 18 (11-138 zeroes)*/ - for(i = 0; i < (unsigned)bitlen_lld.size; i++) - { - unsigned j = 0; /*amount of repititions*/ - while(i + j + 1 < (unsigned)bitlen_lld.size && bitlen_lld.data[i + j + 1] == bitlen_lld.data[i]) j++; + for (i = 0; i < (unsigned)bitlen_lld.size; i++) + { + unsigned j = 0; /*amount of repititions*/ + while (i + j + 1 < (unsigned)bitlen_lld.size && bitlen_lld.data[i + j + 1] == bitlen_lld.data[i]) j++; - if(bitlen_lld.data[i] == 0 && j >= 2) /*repeat code for zeroes*/ - { - j++; /*include the first zero*/ - if(j <= 10) /*repeat code 17 supports max 10 zeroes*/ - { - uivector_push_back(&bitlen_lld_e, 17); - uivector_push_back(&bitlen_lld_e, j - 3); - } - else /*repeat code 18 supports max 138 zeroes*/ - { - if(j > 138) j = 138; - uivector_push_back(&bitlen_lld_e, 18); - uivector_push_back(&bitlen_lld_e, j - 11); - } - i += (j - 1); - } - else if(j >= 3) /*repeat code for value other than zero*/ - { - size_t k; - unsigned num = j / 6, rest = j % 6; - uivector_push_back(&bitlen_lld_e, bitlen_lld.data[i]); - for(k = 0; k < num; k++) - { - uivector_push_back(&bitlen_lld_e, 16); - uivector_push_back(&bitlen_lld_e, 6 - 3); - } - if(rest >= 3) - { - uivector_push_back(&bitlen_lld_e, 16); - uivector_push_back(&bitlen_lld_e, rest - 3); - } - else j -= rest; - i += j; - } - else /*too short to benefit from repeat code*/ - { - uivector_push_back(&bitlen_lld_e, bitlen_lld.data[i]); - } - } + if (bitlen_lld.data[i] == 0 && j >= 2) /*repeat code for zeroes*/ + { + j++; /*include the first zero*/ + if (j <= 10) /*repeat code 17 supports max 10 zeroes*/ + { + uivector_push_back(&bitlen_lld_e, 17); + uivector_push_back(&bitlen_lld_e, j - 3); + } + else /*repeat code 18 supports max 138 zeroes*/ + { + if (j > 138) j = 138; + uivector_push_back(&bitlen_lld_e, 18); + uivector_push_back(&bitlen_lld_e, j - 11); + } + i += (j - 1); + } + else if (j >= 3) /*repeat code for value other than zero*/ + { + size_t k; + unsigned num = j / 6, rest = j % 6; + uivector_push_back(&bitlen_lld_e, bitlen_lld.data[i]); + for (k = 0; k < num; k++) + { + uivector_push_back(&bitlen_lld_e, 16); + uivector_push_back(&bitlen_lld_e, 6 - 3); + } + if (rest >= 3) + { + uivector_push_back(&bitlen_lld_e, 16); + uivector_push_back(&bitlen_lld_e, rest - 3); + } + else + j -= rest; + i += j; + } + else /*too short to benefit from repeat code*/ + { + uivector_push_back(&bitlen_lld_e, bitlen_lld.data[i]); + } + } - /*generate tree_cl, the huffmantree of huffmantrees*/ + /*generate tree_cl, the huffmantree of huffmantrees*/ - if(!uivector_resizev(&frequencies_cl, NUM_CODE_LENGTH_CODES, 0)) ERROR_BREAK(83 /*alloc fail*/); - for(i = 0; i < bitlen_lld_e.size; i++) - { - frequencies_cl.data[bitlen_lld_e.data[i]]++; - /*after a repeat code come the bits that specify the number of repetitions, + if (!uivector_resizev(&frequencies_cl, NUM_CODE_LENGTH_CODES, 0)) ERROR_BREAK(83 /*alloc fail*/); + for (i = 0; i < bitlen_lld_e.size; i++) + { + frequencies_cl.data[bitlen_lld_e.data[i]]++; + /*after a repeat code come the bits that specify the number of repetitions, those don't need to be in the frequencies_cl calculation*/ - if(bitlen_lld_e.data[i] >= 16) i++; - } + if (bitlen_lld_e.data[i] >= 16) i++; + } - error = HuffmanTree_makeFromFrequencies(&tree_cl, frequencies_cl.data, - frequencies_cl.size, frequencies_cl.size, 7); - if(error) break; + error = HuffmanTree_makeFromFrequencies(&tree_cl, frequencies_cl.data, + frequencies_cl.size, frequencies_cl.size, 7); + if (error) break; - if(!uivector_resize(&bitlen_cl, tree_cl.numcodes)) ERROR_BREAK(83 /*alloc fail*/); - for(i = 0; i < tree_cl.numcodes; i++) - { - /*lenghts of code length tree is in the order as specified by deflate*/ - bitlen_cl.data[i] = HuffmanTree_getLength(&tree_cl, CLCL_ORDER[i]); - } - while(bitlen_cl.data[bitlen_cl.size - 1] == 0 && bitlen_cl.size > 4) - { - /*remove zeros at the end, but minimum size must be 4*/ - if(!uivector_resize(&bitlen_cl, bitlen_cl.size - 1)) ERROR_BREAK(83 /*alloc fail*/); - } - if(error) break; + if (!uivector_resize(&bitlen_cl, tree_cl.numcodes)) ERROR_BREAK(83 /*alloc fail*/); + for (i = 0; i < tree_cl.numcodes; i++) + { + /*lenghts of code length tree is in the order as specified by deflate*/ + bitlen_cl.data[i] = HuffmanTree_getLength(&tree_cl, CLCL_ORDER[i]); + } + while (bitlen_cl.data[bitlen_cl.size - 1] == 0 && bitlen_cl.size > 4) + { + /*remove zeros at the end, but minimum size must be 4*/ + if (!uivector_resize(&bitlen_cl, bitlen_cl.size - 1)) ERROR_BREAK(83 /*alloc fail*/); + } + if (error) break; - /* + /* Write everything into the output After the BFINAL and BTYPE, the dynamic block consists out of the following: @@ -1882,173 +1921,181 @@ static unsigned deflateDynamic(ucvector* out, size_t* bp, Hash* hash, - 256 (end code) */ - /*Write block type*/ - addBitToStream(bp, out, BFINAL); - addBitToStream(bp, out, 0); /*first bit of BTYPE "dynamic"*/ - addBitToStream(bp, out, 1); /*second bit of BTYPE "dynamic"*/ + /*Write block type*/ + addBitToStream(bp, out, BFINAL); + addBitToStream(bp, out, 0); /*first bit of BTYPE "dynamic"*/ + addBitToStream(bp, out, 1); /*second bit of BTYPE "dynamic"*/ - /*write the HLIT, HDIST and HCLEN values*/ - HLIT = (unsigned)(numcodes_ll - 257); - HDIST = (unsigned)(numcodes_d - 1); - HCLEN = (unsigned)bitlen_cl.size - 4; - /*trim zeroes for HCLEN. HLIT and HDIST were already trimmed at tree creation*/ - while(!bitlen_cl.data[HCLEN + 4 - 1] && HCLEN > 0) HCLEN--; - addBitsToStream(bp, out, HLIT, 5); - addBitsToStream(bp, out, HDIST, 5); - addBitsToStream(bp, out, HCLEN, 4); + /*write the HLIT, HDIST and HCLEN values*/ + HLIT = (unsigned)(numcodes_ll - 257); + HDIST = (unsigned)(numcodes_d - 1); + HCLEN = (unsigned)bitlen_cl.size - 4; + /*trim zeroes for HCLEN. HLIT and HDIST were already trimmed at tree creation*/ + while (!bitlen_cl.data[HCLEN + 4 - 1] && HCLEN > 0) HCLEN--; + addBitsToStream(bp, out, HLIT, 5); + addBitsToStream(bp, out, HDIST, 5); + addBitsToStream(bp, out, HCLEN, 4); - /*write the code lenghts of the code length alphabet*/ - for(i = 0; i < HCLEN + 4; i++) addBitsToStream(bp, out, bitlen_cl.data[i], 3); + /*write the code lenghts of the code length alphabet*/ + for (i = 0; i < HCLEN + 4; i++) addBitsToStream(bp, out, bitlen_cl.data[i], 3); - /*write the lenghts of the lit/len AND the dist alphabet*/ - for(i = 0; i < bitlen_lld_e.size; i++) - { - addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_cl, bitlen_lld_e.data[i]), - HuffmanTree_getLength(&tree_cl, bitlen_lld_e.data[i])); - /*extra bits of repeat codes*/ - if(bitlen_lld_e.data[i] == 16) addBitsToStream(bp, out, bitlen_lld_e.data[++i], 2); - else if(bitlen_lld_e.data[i] == 17) addBitsToStream(bp, out, bitlen_lld_e.data[++i], 3); - else if(bitlen_lld_e.data[i] == 18) addBitsToStream(bp, out, bitlen_lld_e.data[++i], 7); - } + /*write the lenghts of the lit/len AND the dist alphabet*/ + for (i = 0; i < bitlen_lld_e.size; i++) + { + addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_cl, bitlen_lld_e.data[i]), + HuffmanTree_getLength(&tree_cl, bitlen_lld_e.data[i])); + /*extra bits of repeat codes*/ + if (bitlen_lld_e.data[i] == 16) + addBitsToStream(bp, out, bitlen_lld_e.data[++i], 2); + else if (bitlen_lld_e.data[i] == 17) + addBitsToStream(bp, out, bitlen_lld_e.data[++i], 3); + else if (bitlen_lld_e.data[i] == 18) + addBitsToStream(bp, out, bitlen_lld_e.data[++i], 7); + } - /*write the compressed data symbols*/ - writeLZ77data(bp, out, &lz77_encoded, &tree_ll, &tree_d); - /*error: the length of the end code 256 must be larger than 0*/ - if(HuffmanTree_getLength(&tree_ll, 256) == 0) ERROR_BREAK(64); + /*write the compressed data symbols*/ + writeLZ77data(bp, out, &lz77_encoded, &tree_ll, &tree_d); + /*error: the length of the end code 256 must be larger than 0*/ + if (HuffmanTree_getLength(&tree_ll, 256) == 0) ERROR_BREAK(64); - /*write the end code*/ - addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, 256), HuffmanTree_getLength(&tree_ll, 256)); + /*write the end code*/ + addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, 256), HuffmanTree_getLength(&tree_ll, 256)); - break; /*end of error-while*/ - } + break; /*end of error-while*/ + } - /*cleanup*/ - uivector_cleanup(&lz77_encoded); - HuffmanTree_cleanup(&tree_ll); - HuffmanTree_cleanup(&tree_d); - HuffmanTree_cleanup(&tree_cl); - uivector_cleanup(&frequencies_ll); - uivector_cleanup(&frequencies_d); - uivector_cleanup(&frequencies_cl); - uivector_cleanup(&bitlen_lld_e); - uivector_cleanup(&bitlen_lld); - uivector_cleanup(&bitlen_cl); + /*cleanup*/ + uivector_cleanup(&lz77_encoded); + HuffmanTree_cleanup(&tree_ll); + HuffmanTree_cleanup(&tree_d); + HuffmanTree_cleanup(&tree_cl); + uivector_cleanup(&frequencies_ll); + uivector_cleanup(&frequencies_d); + uivector_cleanup(&frequencies_cl); + uivector_cleanup(&bitlen_lld_e); + uivector_cleanup(&bitlen_lld); + uivector_cleanup(&bitlen_cl); - return error; + return error; } static unsigned deflateFixed(ucvector* out, size_t* bp, Hash* hash, - const unsigned char* data, - size_t datapos, size_t dataend, - const LodePNGCompressSettings* settings, unsigned final) + const unsigned char* data, + size_t datapos, size_t dataend, + const LodePNGCompressSettings* settings, unsigned final) { - HuffmanTree tree_ll; /*tree for literal values and length codes*/ - HuffmanTree tree_d; /*tree for distance codes*/ + HuffmanTree tree_ll; /*tree for literal values and length codes*/ + HuffmanTree tree_d; /*tree for distance codes*/ - unsigned BFINAL = final; - unsigned error = 0; - size_t i; + unsigned BFINAL = final; + unsigned error = 0; + size_t i; - HuffmanTree_init(&tree_ll); - HuffmanTree_init(&tree_d); + HuffmanTree_init(&tree_ll); + HuffmanTree_init(&tree_d); - generateFixedLitLenTree(&tree_ll); - generateFixedDistanceTree(&tree_d); + generateFixedLitLenTree(&tree_ll); + generateFixedDistanceTree(&tree_d); - addBitToStream(bp, out, BFINAL); - addBitToStream(bp, out, 1); /*first bit of BTYPE*/ - addBitToStream(bp, out, 0); /*second bit of BTYPE*/ + addBitToStream(bp, out, BFINAL); + addBitToStream(bp, out, 1); /*first bit of BTYPE*/ + addBitToStream(bp, out, 0); /*second bit of BTYPE*/ - if(settings->use_lz77) /*LZ77 encoded*/ - { - uivector lz77_encoded; - uivector_init(&lz77_encoded); - error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize, - settings->minmatch, settings->nicematch, settings->lazymatching); - if(!error) writeLZ77data(bp, out, &lz77_encoded, &tree_ll, &tree_d); - uivector_cleanup(&lz77_encoded); - } - else /*no LZ77, but still will be Huffman compressed*/ - { - for(i = datapos; i < dataend; i++) - { - addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, data[i]), HuffmanTree_getLength(&tree_ll, data[i])); - } - } - /*add END code*/ - if(!error) addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, 256), HuffmanTree_getLength(&tree_ll, 256)); + if (settings->use_lz77) /*LZ77 encoded*/ + { + uivector lz77_encoded; + uivector_init(&lz77_encoded); + error = encodeLZ77(&lz77_encoded, hash, data, datapos, dataend, settings->windowsize, + settings->minmatch, settings->nicematch, settings->lazymatching); + if (!error) writeLZ77data(bp, out, &lz77_encoded, &tree_ll, &tree_d); + uivector_cleanup(&lz77_encoded); + } + else /*no LZ77, but still will be Huffman compressed*/ + { + for (i = datapos; i < dataend; i++) + { + addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, data[i]), HuffmanTree_getLength(&tree_ll, data[i])); + } + } + /*add END code*/ + if (!error) addHuffmanSymbol(bp, out, HuffmanTree_getCode(&tree_ll, 256), HuffmanTree_getLength(&tree_ll, 256)); - /*cleanup*/ - HuffmanTree_cleanup(&tree_ll); - HuffmanTree_cleanup(&tree_d); + /*cleanup*/ + HuffmanTree_cleanup(&tree_ll); + HuffmanTree_cleanup(&tree_d); - return error; + return error; } static unsigned lodepng_deflatev(ucvector* out, const unsigned char* in, size_t insize, - const LodePNGCompressSettings* settings) + const LodePNGCompressSettings* settings) { - unsigned error = 0; - size_t i, blocksize, numdeflateblocks; - size_t bp = 0; /*the bit pointer*/ - Hash hash; + unsigned error = 0; + size_t i, blocksize, numdeflateblocks; + size_t bp = 0; /*the bit pointer*/ + Hash hash; - if(settings->btype > 2) return 61; - else if(settings->btype == 0) return deflateNoCompression(out, in, insize); - else if(settings->btype == 1) blocksize = insize; - else /*if(settings->btype == 2)*/ - { - blocksize = insize / 8 + 8; - if(blocksize < 65535) blocksize = 65535; - } + if (settings->btype > 2) + return 61; + else if (settings->btype == 0) + return deflateNoCompression(out, in, insize); + else if (settings->btype == 1) + blocksize = insize; + else /*if(settings->btype == 2)*/ + { + blocksize = insize / 8 + 8; + if (blocksize < 65535) blocksize = 65535; + } - numdeflateblocks = (insize + blocksize - 1) / blocksize; - if(numdeflateblocks == 0) numdeflateblocks = 1; + numdeflateblocks = (insize + blocksize - 1) / blocksize; + if (numdeflateblocks == 0) numdeflateblocks = 1; - error = hash_init(&hash, settings->windowsize); - if(error) return error; + error = hash_init(&hash, settings->windowsize); + if (error) return error; - for(i = 0; i < numdeflateblocks && !error; i++) - { - unsigned final = (i == numdeflateblocks - 1); - size_t start = i * blocksize; - size_t end = start + blocksize; - if(end > insize) end = insize; + for (i = 0; i < numdeflateblocks && !error; i++) + { + unsigned final = (i == numdeflateblocks - 1); + size_t start = i * blocksize; + size_t end = start + blocksize; + if (end > insize) end = insize; - if(settings->btype == 1) error = deflateFixed(out, &bp, &hash, in, start, end, settings, final); - else if(settings->btype == 2) error = deflateDynamic(out, &bp, &hash, in, start, end, settings, final); - } + if (settings->btype == 1) + error = deflateFixed(out, &bp, &hash, in, start, end, settings, final); + else if (settings->btype == 2) + error = deflateDynamic(out, &bp, &hash, in, start, end, settings, final); + } - hash_cleanup(&hash); + hash_cleanup(&hash); - return error; + return error; } unsigned lodepng_deflate(unsigned char** out, size_t* outsize, - const unsigned char* in, size_t insize, - const LodePNGCompressSettings* settings) + const unsigned char* in, size_t insize, + const LodePNGCompressSettings* settings) { - unsigned error; - ucvector v; - ucvector_init_buffer(&v, *out, *outsize); - error = lodepng_deflatev(&v, in, insize, settings); - *out = v.data; - *outsize = v.size; - return error; + unsigned error; + ucvector v; + ucvector_init_buffer(&v, *out, *outsize); + error = lodepng_deflatev(&v, in, insize, settings); + *out = v.data; + *outsize = v.size; + return error; } static unsigned deflate(unsigned char** out, size_t* outsize, - const unsigned char* in, size_t insize, - const LodePNGCompressSettings* settings) + const unsigned char* in, size_t insize, + const LodePNGCompressSettings* settings) { - if(settings->custom_deflate) - { - return settings->custom_deflate(out, outsize, in, insize, settings); - } - else - { - return lodepng_deflate(out, outsize, in, insize, settings); - } + if (settings->custom_deflate) + { + return settings->custom_deflate(out, outsize, in, insize, settings); + } + else + { + return lodepng_deflate(out, outsize, in, insize, settings); + } } #endif /*LODEPNG_COMPILE_DECODER*/ @@ -2059,31 +2106,31 @@ static unsigned deflate(unsigned char** out, size_t* outsize, static unsigned update_adler32(unsigned adler, const unsigned char* data, unsigned len) { - unsigned s1 = adler & 0xffff; - unsigned s2 = (adler >> 16) & 0xffff; + unsigned s1 = adler & 0xffff; + unsigned s2 = (adler >> 16) & 0xffff; - while(len > 0) - { - /*at least 5550 sums can be done before the sums overflow, saving a lot of module divisions*/ - unsigned amount = len > 5550 ? 5550 : len; - len -= amount; - while(amount > 0) - { - s1 += (*data++); - s2 += s1; - amount--; - } - s1 %= 65521; - s2 %= 65521; - } + while (len > 0) + { + /*at least 5550 sums can be done before the sums overflow, saving a lot of module divisions*/ + unsigned amount = len > 5550 ? 5550 : len; + len -= amount; + while (amount > 0) + { + s1 += (*data++); + s2 += s1; + amount--; + } + s1 %= 65521; + s2 %= 65521; + } - return (s2 << 16) | s1; + return (s2 << 16) | s1; } /*Return the adler32 of the bytes data[0..len-1]*/ static unsigned adler32(const unsigned char* data, unsigned len) { - return update_adler32(1L, data, len); + return update_adler32(1L, data, len); } /* ////////////////////////////////////////////////////////////////////////// */ @@ -2093,61 +2140,61 @@ static unsigned adler32(const unsigned char* data, unsigned len) #ifdef LODEPNG_COMPILE_DECODER unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, - size_t insize, const LodePNGDecompressSettings* settings) + size_t insize, const LodePNGDecompressSettings* settings) { - unsigned error = 0; - unsigned CM, CINFO, FDICT; + unsigned error = 0; + unsigned CM, CINFO, FDICT; - if(insize < 2) return 53; /*error, size of zlib data too small*/ - /*read information from zlib header*/ - if((in[0] * 256 + in[1]) % 31 != 0) - { - /*error: 256 * in[0] + in[1] must be a multiple of 31, the FCHECK value is supposed to be made that way*/ - return 24; - } + if (insize < 2) return 53; /*error, size of zlib data too small*/ + /*read information from zlib header*/ + if ((in[0] * 256 + in[1]) % 31 != 0) + { + /*error: 256 * in[0] + in[1] must be a multiple of 31, the FCHECK value is supposed to be made that way*/ + return 24; + } - CM = in[0] & 15; - CINFO = (in[0] >> 4) & 15; - /*FCHECK = in[1] & 31;*/ /*FCHECK is already tested above*/ - FDICT = (in[1] >> 5) & 1; - /*FLEVEL = (in[1] >> 6) & 3;*/ /*FLEVEL is not used here*/ + CM = in[0] & 15; + CINFO = (in[0] >> 4) & 15; + /*FCHECK = in[1] & 31;*/ /*FCHECK is already tested above*/ + FDICT = (in[1] >> 5) & 1; + /*FLEVEL = (in[1] >> 6) & 3;*/ /*FLEVEL is not used here*/ - if(CM != 8 || CINFO > 7) - { - /*error: only compression method 8: inflate with sliding window of 32k is supported by the PNG spec*/ - return 25; - } - if(FDICT != 0) - { - /*error: the specification of PNG says about the zlib stream: + if (CM != 8 || CINFO > 7) + { + /*error: only compression method 8: inflate with sliding window of 32k is supported by the PNG spec*/ + return 25; + } + if (FDICT != 0) + { + /*error: the specification of PNG says about the zlib stream: "The additional flags shall not specify a preset dictionary."*/ - return 26; - } + return 26; + } - error = inflate(out, outsize, in + 2, insize - 2, settings); - if(error) return error; + error = inflate(out, outsize, in + 2, insize - 2, settings); + if (error) return error; - if(!settings->ignore_adler32) - { - unsigned ADLER32 = lodepng_read32bitInt(&in[insize - 4]); - unsigned checksum = adler32(*out, (unsigned)(*outsize)); - if(checksum != ADLER32) return 58; /*error, adler checksum not correct, data must be corrupted*/ - } + if (!settings->ignore_adler32) + { + unsigned ADLER32 = lodepng_read32bitInt(&in[insize - 4]); + unsigned checksum = adler32(*out, (unsigned)(*outsize)); + if (checksum != ADLER32) return 58; /*error, adler checksum not correct, data must be corrupted*/ + } - return 0; /*no error*/ + return 0; /*no error*/ } static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, - size_t insize, const LodePNGDecompressSettings* settings) + size_t insize, const LodePNGDecompressSettings* settings) { - if(settings->custom_zlib) - { - return settings->custom_zlib(out, outsize, in, insize, settings); - } - else - { - return lodepng_zlib_decompress(out, outsize, in, insize, settings); - } + if (settings->custom_zlib) + { + return settings->custom_zlib(out, outsize, in, insize, settings); + } + else + { + return lodepng_zlib_decompress(out, outsize, in, insize, settings); + } } #endif /*LODEPNG_COMPILE_DECODER*/ @@ -2155,59 +2202,59 @@ static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsi #ifdef LODEPNG_COMPILE_ENCODER unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, - size_t insize, const LodePNGCompressSettings* settings) + size_t insize, const LodePNGCompressSettings* settings) { - /*initially, *out must be NULL and outsize 0, if you just give some random *out + /*initially, *out must be NULL and outsize 0, if you just give some random *out that's pointing to a non allocated buffer, this'll crash*/ - ucvector outv; - size_t i; - unsigned error; - unsigned char* deflatedata = 0; - size_t deflatesize = 0; + ucvector outv; + size_t i; + unsigned error; + unsigned char* deflatedata = 0; + size_t deflatesize = 0; - unsigned ADLER32; - /*zlib data: 1 byte CMF (CM+CINFO), 1 byte FLG, deflate data, 4 byte ADLER32 checksum of the Decompressed data*/ - unsigned CMF = 120; /*0b01111000: CM 8, CINFO 7. With CINFO 7, any window size up to 32768 can be used.*/ - unsigned FLEVEL = 0; - unsigned FDICT = 0; - unsigned CMFFLG = 256 * CMF + FDICT * 32 + FLEVEL * 64; - unsigned FCHECK = 31 - CMFFLG % 31; - CMFFLG += FCHECK; + unsigned ADLER32; + /*zlib data: 1 byte CMF (CM+CINFO), 1 byte FLG, deflate data, 4 byte ADLER32 checksum of the Decompressed data*/ + unsigned CMF = 120; /*0b01111000: CM 8, CINFO 7. With CINFO 7, any window size up to 32768 can be used.*/ + unsigned FLEVEL = 0; + unsigned FDICT = 0; + unsigned CMFFLG = 256 * CMF + FDICT * 32 + FLEVEL * 64; + unsigned FCHECK = 31 - CMFFLG % 31; + CMFFLG += FCHECK; - /*ucvector-controlled version of the output buffer, for dynamic array*/ - ucvector_init_buffer(&outv, *out, *outsize); + /*ucvector-controlled version of the output buffer, for dynamic array*/ + ucvector_init_buffer(&outv, *out, *outsize); - ucvector_push_back(&outv, (unsigned char)(CMFFLG / 256)); - ucvector_push_back(&outv, (unsigned char)(CMFFLG % 256)); + ucvector_push_back(&outv, (unsigned char)(CMFFLG / 256)); + ucvector_push_back(&outv, (unsigned char)(CMFFLG % 256)); - error = deflate(&deflatedata, &deflatesize, in, insize, settings); + error = deflate(&deflatedata, &deflatesize, in, insize, settings); - if(!error) - { - ADLER32 = adler32(in, (unsigned)insize); - for(i = 0; i < deflatesize; i++) ucvector_push_back(&outv, deflatedata[i]); - lodepng_free(deflatedata); - lodepng_add32bitInt(&outv, ADLER32); - } + if (!error) + { + ADLER32 = adler32(in, (unsigned)insize); + for (i = 0; i < deflatesize; i++) ucvector_push_back(&outv, deflatedata[i]); + lodepng_free(deflatedata); + lodepng_add32bitInt(&outv, ADLER32); + } - *out = outv.data; - *outsize = outv.size; + *out = outv.data; + *outsize = outv.size; - return error; + return error; } /* compress using the default or custom zlib function */ static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, - size_t insize, const LodePNGCompressSettings* settings) + size_t insize, const LodePNGCompressSettings* settings) { - if(settings->custom_zlib) - { - return settings->custom_zlib(out, outsize, in, insize, settings); - } - else - { - return lodepng_zlib_compress(out, outsize, in, insize, settings); - } + if (settings->custom_zlib) + { + return settings->custom_zlib(out, outsize, in, insize, settings); + } + else + { + return lodepng_zlib_compress(out, outsize, in, insize, settings); + } } #endif /*LODEPNG_COMPILE_ENCODER*/ @@ -2216,18 +2263,18 @@ static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsign #ifdef LODEPNG_COMPILE_DECODER static unsigned zlib_decompress(unsigned char** out, size_t* outsize, const unsigned char* in, - size_t insize, const LodePNGDecompressSettings* settings) + size_t insize, const LodePNGDecompressSettings* settings) { - if (!settings->custom_zlib) return 87; /*no custom zlib function provided */ - return settings->custom_zlib(out, outsize, in, insize, settings); + if (!settings->custom_zlib) return 87; /*no custom zlib function provided */ + return settings->custom_zlib(out, outsize, in, insize, settings); } #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsigned char* in, - size_t insize, const LodePNGCompressSettings* settings) + size_t insize, const LodePNGCompressSettings* settings) { - if (!settings->custom_zlib) return 87; /*no custom zlib function provided */ - return settings->custom_zlib(out, outsize, in, insize, settings); + if (!settings->custom_zlib) return 87; /*no custom zlib function provided */ + return settings->custom_zlib(out, outsize, in, insize, settings); } #endif /*LODEPNG_COMPILE_ENCODER*/ @@ -2242,33 +2289,32 @@ static unsigned zlib_compress(unsigned char** out, size_t* outsize, const unsign void lodepng_compress_settings_init(LodePNGCompressSettings* settings) { - /*compress with dynamic huffman tree (not in the mathematical sense, just not the predefined one)*/ - settings->btype = 2; - settings->use_lz77 = 1; - settings->windowsize = DEFAULT_WINDOWSIZE; - settings->minmatch = 3; - settings->nicematch = 128; - settings->lazymatching = 1; + /*compress with dynamic huffman tree (not in the mathematical sense, just not the predefined one)*/ + settings->btype = 2; + settings->use_lz77 = 1; + settings->windowsize = DEFAULT_WINDOWSIZE; + settings->minmatch = 3; + settings->nicematch = 128; + settings->lazymatching = 1; - settings->custom_zlib = 0; - settings->custom_deflate = 0; - settings->custom_context = 0; + settings->custom_zlib = 0; + settings->custom_deflate = 0; + settings->custom_context = 0; } const LodePNGCompressSettings lodepng_default_compress_settings = {2, 1, DEFAULT_WINDOWSIZE, 3, 128, 1, 0, 0, 0}; - #endif /*LODEPNG_COMPILE_ENCODER*/ #ifdef LODEPNG_COMPILE_DECODER void lodepng_decompress_settings_init(LodePNGDecompressSettings* settings) { - settings->ignore_adler32 = 0; + settings->ignore_adler32 = 0; - settings->custom_zlib = 0; - settings->custom_inflate = 0; - settings->custom_context = 0; + settings->custom_zlib = 0; + settings->custom_inflate = 0; + settings->custom_context = 0; } const LodePNGDecompressSettings lodepng_default_decompress_settings = {0, 0, 0, 0}; @@ -2289,51 +2335,50 @@ const LodePNGDecompressSettings lodepng_default_decompress_settings = {0, 0, 0, /* CRC polynomial: 0xedb88320 */ static unsigned lodepng_crc32_table[256] = { - 0u, 1996959894u, 3993919788u, 2567524794u, 124634137u, 1886057615u, 3915621685u, 2657392035u, - 249268274u, 2044508324u, 3772115230u, 2547177864u, 162941995u, 2125561021u, 3887607047u, 2428444049u, - 498536548u, 1789927666u, 4089016648u, 2227061214u, 450548861u, 1843258603u, 4107580753u, 2211677639u, - 325883990u, 1684777152u, 4251122042u, 2321926636u, 335633487u, 1661365465u, 4195302755u, 2366115317u, - 997073096u, 1281953886u, 3579855332u, 2724688242u, 1006888145u, 1258607687u, 3524101629u, 2768942443u, - 901097722u, 1119000684u, 3686517206u, 2898065728u, 853044451u, 1172266101u, 3705015759u, 2882616665u, - 651767980u, 1373503546u, 3369554304u, 3218104598u, 565507253u, 1454621731u, 3485111705u, 3099436303u, - 671266974u, 1594198024u, 3322730930u, 2970347812u, 795835527u, 1483230225u, 3244367275u, 3060149565u, - 1994146192u, 31158534u, 2563907772u, 4023717930u, 1907459465u, 112637215u, 2680153253u, 3904427059u, - 2013776290u, 251722036u, 2517215374u, 3775830040u, 2137656763u, 141376813u, 2439277719u, 3865271297u, - 1802195444u, 476864866u, 2238001368u, 4066508878u, 1812370925u, 453092731u, 2181625025u, 4111451223u, - 1706088902u, 314042704u, 2344532202u, 4240017532u, 1658658271u, 366619977u, 2362670323u, 4224994405u, - 1303535960u, 984961486u, 2747007092u, 3569037538u, 1256170817u, 1037604311u, 2765210733u, 3554079995u, - 1131014506u, 879679996u, 2909243462u, 3663771856u, 1141124467u, 855842277u, 2852801631u, 3708648649u, - 1342533948u, 654459306u, 3188396048u, 3373015174u, 1466479909u, 544179635u, 3110523913u, 3462522015u, - 1591671054u, 702138776u, 2966460450u, 3352799412u, 1504918807u, 783551873u, 3082640443u, 3233442989u, - 3988292384u, 2596254646u, 62317068u, 1957810842u, 3939845945u, 2647816111u, 81470997u, 1943803523u, - 3814918930u, 2489596804u, 225274430u, 2053790376u, 3826175755u, 2466906013u, 167816743u, 2097651377u, - 4027552580u, 2265490386u, 503444072u, 1762050814u, 4150417245u, 2154129355u, 426522225u, 1852507879u, - 4275313526u, 2312317920u, 282753626u, 1742555852u, 4189708143u, 2394877945u, 397917763u, 1622183637u, - 3604390888u, 2714866558u, 953729732u, 1340076626u, 3518719985u, 2797360999u, 1068828381u, 1219638859u, - 3624741850u, 2936675148u, 906185462u, 1090812512u, 3747672003u, 2825379669u, 829329135u, 1181335161u, - 3412177804u, 3160834842u, 628085408u, 1382605366u, 3423369109u, 3138078467u, 570562233u, 1426400815u, - 3317316542u, 2998733608u, 733239954u, 1555261956u, 3268935591u, 3050360625u, 752459403u, 1541320221u, - 2607071920u, 3965973030u, 1969922972u, 40735498u, 2617837225u, 3943577151u, 1913087877u, 83908371u, - 2512341634u, 3803740692u, 2075208622u, 213261112u, 2463272603u, 3855990285u, 2094854071u, 198958881u, - 2262029012u, 4057260610u, 1759359992u, 534414190u, 2176718541u, 4139329115u, 1873836001u, 414664567u, - 2282248934u, 4279200368u, 1711684554u, 285281116u, 2405801727u, 4167216745u, 1634467795u, 376229701u, - 2685067896u, 3608007406u, 1308918612u, 956543938u, 2808555105u, 3495958263u, 1231636301u, 1047427035u, - 2932959818u, 3654703836u, 1088359270u, 936918000u, 2847714899u, 3736837829u, 1202900863u, 817233897u, - 3183342108u, 3401237130u, 1404277552u, 615818150u, 3134207493u, 3453421203u, 1423857449u, 601450431u, - 3009837614u, 3294710456u, 1567103746u, 711928724u, 3020668471u, 3272380065u, 1510334235u, 755167117u -}; + 0u, 1996959894u, 3993919788u, 2567524794u, 124634137u, 1886057615u, 3915621685u, 2657392035u, + 249268274u, 2044508324u, 3772115230u, 2547177864u, 162941995u, 2125561021u, 3887607047u, 2428444049u, + 498536548u, 1789927666u, 4089016648u, 2227061214u, 450548861u, 1843258603u, 4107580753u, 2211677639u, + 325883990u, 1684777152u, 4251122042u, 2321926636u, 335633487u, 1661365465u, 4195302755u, 2366115317u, + 997073096u, 1281953886u, 3579855332u, 2724688242u, 1006888145u, 1258607687u, 3524101629u, 2768942443u, + 901097722u, 1119000684u, 3686517206u, 2898065728u, 853044451u, 1172266101u, 3705015759u, 2882616665u, + 651767980u, 1373503546u, 3369554304u, 3218104598u, 565507253u, 1454621731u, 3485111705u, 3099436303u, + 671266974u, 1594198024u, 3322730930u, 2970347812u, 795835527u, 1483230225u, 3244367275u, 3060149565u, + 1994146192u, 31158534u, 2563907772u, 4023717930u, 1907459465u, 112637215u, 2680153253u, 3904427059u, + 2013776290u, 251722036u, 2517215374u, 3775830040u, 2137656763u, 141376813u, 2439277719u, 3865271297u, + 1802195444u, 476864866u, 2238001368u, 4066508878u, 1812370925u, 453092731u, 2181625025u, 4111451223u, + 1706088902u, 314042704u, 2344532202u, 4240017532u, 1658658271u, 366619977u, 2362670323u, 4224994405u, + 1303535960u, 984961486u, 2747007092u, 3569037538u, 1256170817u, 1037604311u, 2765210733u, 3554079995u, + 1131014506u, 879679996u, 2909243462u, 3663771856u, 1141124467u, 855842277u, 2852801631u, 3708648649u, + 1342533948u, 654459306u, 3188396048u, 3373015174u, 1466479909u, 544179635u, 3110523913u, 3462522015u, + 1591671054u, 702138776u, 2966460450u, 3352799412u, 1504918807u, 783551873u, 3082640443u, 3233442989u, + 3988292384u, 2596254646u, 62317068u, 1957810842u, 3939845945u, 2647816111u, 81470997u, 1943803523u, + 3814918930u, 2489596804u, 225274430u, 2053790376u, 3826175755u, 2466906013u, 167816743u, 2097651377u, + 4027552580u, 2265490386u, 503444072u, 1762050814u, 4150417245u, 2154129355u, 426522225u, 1852507879u, + 4275313526u, 2312317920u, 282753626u, 1742555852u, 4189708143u, 2394877945u, 397917763u, 1622183637u, + 3604390888u, 2714866558u, 953729732u, 1340076626u, 3518719985u, 2797360999u, 1068828381u, 1219638859u, + 3624741850u, 2936675148u, 906185462u, 1090812512u, 3747672003u, 2825379669u, 829329135u, 1181335161u, + 3412177804u, 3160834842u, 628085408u, 1382605366u, 3423369109u, 3138078467u, 570562233u, 1426400815u, + 3317316542u, 2998733608u, 733239954u, 1555261956u, 3268935591u, 3050360625u, 752459403u, 1541320221u, + 2607071920u, 3965973030u, 1969922972u, 40735498u, 2617837225u, 3943577151u, 1913087877u, 83908371u, + 2512341634u, 3803740692u, 2075208622u, 213261112u, 2463272603u, 3855990285u, 2094854071u, 198958881u, + 2262029012u, 4057260610u, 1759359992u, 534414190u, 2176718541u, 4139329115u, 1873836001u, 414664567u, + 2282248934u, 4279200368u, 1711684554u, 285281116u, 2405801727u, 4167216745u, 1634467795u, 376229701u, + 2685067896u, 3608007406u, 1308918612u, 956543938u, 2808555105u, 3495958263u, 1231636301u, 1047427035u, + 2932959818u, 3654703836u, 1088359270u, 936918000u, 2847714899u, 3736837829u, 1202900863u, 817233897u, + 3183342108u, 3401237130u, 1404277552u, 615818150u, 3134207493u, 3453421203u, 1423857449u, 601450431u, + 3009837614u, 3294710456u, 1567103746u, 711928724u, 3020668471u, 3272380065u, 1510334235u, 755167117u}; /*Return the CRC of the bytes buf[0..len-1].*/ unsigned lodepng_crc32(const unsigned char* buf, size_t len) { - unsigned c = 0xffffffffL; - size_t n; + unsigned c = 0xffffffffL; + size_t n; - for(n = 0; n < len; n++) - { - c = lodepng_crc32_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); - } - return c ^ 0xffffffffL; + for (n = 0; n < len; n++) + { + c = lodepng_crc32_table[(c ^ buf[n]) & 0xff] ^ (c >> 8); + } + return c ^ 0xffffffffL; } /* ////////////////////////////////////////////////////////////////////////// */ @@ -2342,41 +2387,43 @@ unsigned lodepng_crc32(const unsigned char* buf, size_t len) static unsigned char readBitFromReversedStream(size_t* bitpointer, const unsigned char* bitstream) { - unsigned char result = (unsigned char)((bitstream[(*bitpointer) >> 3] >> (7 - ((*bitpointer) & 0x7))) & 1); - (*bitpointer)++; - return result; + unsigned char result = (unsigned char)((bitstream[(*bitpointer) >> 3] >> (7 - ((*bitpointer) & 0x7))) & 1); + (*bitpointer)++; + return result; } static unsigned readBitsFromReversedStream(size_t* bitpointer, const unsigned char* bitstream, size_t nbits) { - unsigned result = 0; - size_t i; - for ( i = 1; i <= nbits; i++ ) - { - result += (unsigned)readBitFromReversedStream( bitpointer, bitstream ) << (nbits - i); - } - return result; + unsigned result = 0; + size_t i; + for (i = 1; i <= nbits; i++) + { + result += (unsigned)readBitFromReversedStream(bitpointer, bitstream) << (nbits - i); + } + return result; } #ifdef LODEPNG_COMPILE_DECODER static void setBitOfReversedStream0(size_t* bitpointer, unsigned char* bitstream, unsigned char bit) { - /*the current bit in bitstream must be 0 for this to work*/ - if(bit) - { - /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/ - bitstream[(*bitpointer) >> 3] |= (bit << (7 - ((*bitpointer) & 0x7))); - } - (*bitpointer)++; + /*the current bit in bitstream must be 0 for this to work*/ + if (bit) + { + /*earlier bit of huffman code is in a lesser significant bit of an earlier byte*/ + bitstream[(*bitpointer) >> 3] |= (bit << (7 - ((*bitpointer) & 0x7))); + } + (*bitpointer)++; } #endif /*LODEPNG_COMPILE_DECODER*/ static void setBitOfReversedStream(size_t* bitpointer, unsigned char* bitstream, unsigned char bit) { - /*the current bit in bitstream may be 0 or 1 for this to work*/ - if(bit == 0) bitstream[(*bitpointer) >> 3] &= (unsigned char)(~(1 << (7 - ((*bitpointer) & 0x7)))); - else bitstream[(*bitpointer) >> 3] |= (1 << (7 - ((*bitpointer) & 0x7))); - (*bitpointer)++; + /*the current bit in bitstream may be 0 or 1 for this to work*/ + if (bit == 0) + bitstream[(*bitpointer) >> 3] &= (unsigned char)(~(1 << (7 - ((*bitpointer) & 0x7)))); + else + bitstream[(*bitpointer) >> 3] |= (1 << (7 - ((*bitpointer) & 0x7))); + (*bitpointer)++; } /* ////////////////////////////////////////////////////////////////////////// */ @@ -2385,124 +2432,126 @@ static void setBitOfReversedStream(size_t* bitpointer, unsigned char* bitstream, unsigned lodepng_chunk_length(const unsigned char* chunk) { - return lodepng_read32bitInt(&chunk[0]); + return lodepng_read32bitInt(&chunk[0]); } void lodepng_chunk_type(char type[5], const unsigned char* chunk) { - unsigned i; - for(i = 0; i < 4; i++) type[i] = (char)chunk[4 + i]; - type[4] = 0; /*null termination char*/ + unsigned i; + for (i = 0; i < 4; i++) type[i] = (char)chunk[4 + i]; + type[4] = 0; /*null termination char*/ } unsigned char lodepng_chunk_type_equals(const unsigned char* chunk, const char* type) { - if(strlen(type) != 4) return 0; - return (chunk[4] == type[0] && chunk[5] == type[1] && chunk[6] == type[2] && chunk[7] == type[3]); + if (strlen(type) != 4) return 0; + return (chunk[4] == type[0] && chunk[5] == type[1] && chunk[6] == type[2] && chunk[7] == type[3]); } unsigned char lodepng_chunk_ancillary(const unsigned char* chunk) { - return((chunk[4] & 32) != 0); + return ((chunk[4] & 32) != 0); } unsigned char lodepng_chunk_private(const unsigned char* chunk) { - return((chunk[6] & 32) != 0); + return ((chunk[6] & 32) != 0); } unsigned char lodepng_chunk_safetocopy(const unsigned char* chunk) { - return((chunk[7] & 32) != 0); + return ((chunk[7] & 32) != 0); } unsigned char* lodepng_chunk_data(unsigned char* chunk) { - return &chunk[8]; + return &chunk[8]; } const unsigned char* lodepng_chunk_data_const(const unsigned char* chunk) { - return &chunk[8]; + return &chunk[8]; } unsigned lodepng_chunk_check_crc(const unsigned char* chunk) { - unsigned length = lodepng_chunk_length(chunk); - unsigned CRC = lodepng_read32bitInt(&chunk[length + 8]); - /*the CRC is taken of the data and the 4 chunk type letters, not the length*/ - unsigned checksum = lodepng_crc32(&chunk[4], length + 4); - if(CRC != checksum) return 1; - else return 0; + unsigned length = lodepng_chunk_length(chunk); + unsigned CRC = lodepng_read32bitInt(&chunk[length + 8]); + /*the CRC is taken of the data and the 4 chunk type letters, not the length*/ + unsigned checksum = lodepng_crc32(&chunk[4], length + 4); + if (CRC != checksum) + return 1; + else + return 0; } void lodepng_chunk_generate_crc(unsigned char* chunk) { - unsigned length = lodepng_chunk_length(chunk); - unsigned CRC = lodepng_crc32(&chunk[4], length + 4); - lodepng_set32bitInt(chunk + 8 + length, CRC); + unsigned length = lodepng_chunk_length(chunk); + unsigned CRC = lodepng_crc32(&chunk[4], length + 4); + lodepng_set32bitInt(chunk + 8 + length, CRC); } unsigned char* lodepng_chunk_next(unsigned char* chunk) { - unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12; - return &chunk[total_chunk_length]; + unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12; + return &chunk[total_chunk_length]; } const unsigned char* lodepng_chunk_next_const(const unsigned char* chunk) { - unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12; - return &chunk[total_chunk_length]; + unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12; + return &chunk[total_chunk_length]; } unsigned lodepng_chunk_append(unsigned char** out, size_t* outlength, const unsigned char* chunk) { - unsigned i; - unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12; - unsigned char *chunk_start, *new_buffer; - size_t new_length = (*outlength) + total_chunk_length; - if(new_length < total_chunk_length || new_length < (*outlength)) return 77; /*integer overflow happened*/ + unsigned i; + unsigned total_chunk_length = lodepng_chunk_length(chunk) + 12; + unsigned char *chunk_start, *new_buffer; + size_t new_length = (*outlength) + total_chunk_length; + if (new_length < total_chunk_length || new_length < (*outlength)) return 77; /*integer overflow happened*/ - new_buffer = (unsigned char*)lodepng_realloc(*out, new_length); - if(!new_buffer) return 83; /*alloc fail*/ - (*out) = new_buffer; - (*outlength) = new_length; - chunk_start = &(*out)[new_length - total_chunk_length]; + new_buffer = (unsigned char*)lodepng_realloc(*out, new_length); + if (!new_buffer) return 83; /*alloc fail*/ + (*out) = new_buffer; + (*outlength) = new_length; + chunk_start = &(*out)[new_length - total_chunk_length]; - for(i = 0; i < total_chunk_length; i++) chunk_start[i] = chunk[i]; + for (i = 0; i < total_chunk_length; i++) chunk_start[i] = chunk[i]; - return 0; + return 0; } unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length, - const char* type, const unsigned char* data) + const char* type, const unsigned char* data) { - unsigned i; - unsigned char *chunk, *new_buffer; - size_t new_length = (*outlength) + length + 12; - if(new_length < length + 12 || new_length < (*outlength)) return 77; /*integer overflow happened*/ - new_buffer = (unsigned char*)lodepng_realloc(*out, new_length); - if(!new_buffer) return 83; /*alloc fail*/ - (*out) = new_buffer; - (*outlength) = new_length; - chunk = &(*out)[(*outlength) - length - 12]; + unsigned i; + unsigned char *chunk, *new_buffer; + size_t new_length = (*outlength) + length + 12; + if (new_length < length + 12 || new_length < (*outlength)) return 77; /*integer overflow happened*/ + new_buffer = (unsigned char*)lodepng_realloc(*out, new_length); + if (!new_buffer) return 83; /*alloc fail*/ + (*out) = new_buffer; + (*outlength) = new_length; + chunk = &(*out)[(*outlength) - length - 12]; - /*1: length*/ - lodepng_set32bitInt(chunk, (unsigned)length); + /*1: length*/ + lodepng_set32bitInt(chunk, (unsigned)length); - /*2: chunk name (4 letters)*/ - chunk[4] = (unsigned char)type[0]; - chunk[5] = (unsigned char)type[1]; - chunk[6] = (unsigned char)type[2]; - chunk[7] = (unsigned char)type[3]; + /*2: chunk name (4 letters)*/ + chunk[4] = (unsigned char)type[0]; + chunk[5] = (unsigned char)type[1]; + chunk[6] = (unsigned char)type[2]; + chunk[7] = (unsigned char)type[3]; - /*3: the data*/ - for(i = 0; i < length; i++) chunk[8 + i] = data[i]; + /*3: the data*/ + for (i = 0; i < length; i++) chunk[8 + i] = data[i]; - /*4: CRC (of the chunkname characters and the data)*/ - lodepng_chunk_generate_crc(chunk); + /*4: CRC (of the chunkname characters and the data)*/ + lodepng_chunk_generate_crc(chunk); - return 0; + return 0; } /* ////////////////////////////////////////////////////////////////////////// */ @@ -2512,176 +2561,191 @@ unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned l /*return type is a LodePNG error code*/ static unsigned checkColorValidity(LodePNGColorType colortype, unsigned bd) /*bd = bitdepth*/ { - switch(colortype) - { - case 0: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16)) return 37; break; /*grey*/ - case 2: if(!( bd == 8 || bd == 16)) return 37; break; /*RGB*/ - case 3: if(!(bd == 1 || bd == 2 || bd == 4 || bd == 8 )) return 37; break; /*palette*/ - case 4: if(!( bd == 8 || bd == 16)) return 37; break; /*grey + alpha*/ - case 6: if(!( bd == 8 || bd == 16)) return 37; break; /*RGBA*/ - default: return 31; - } - return 0; /*allowed color type / bits combination*/ + switch (colortype) + { + case 0: + if (!(bd == 1 || bd == 2 || bd == 4 || bd == 8 || bd == 16)) return 37; + break; /*grey*/ + case 2: + if (!(bd == 8 || bd == 16)) return 37; + break; /*RGB*/ + case 3: + if (!(bd == 1 || bd == 2 || bd == 4 || bd == 8)) return 37; + break; /*palette*/ + case 4: + if (!(bd == 8 || bd == 16)) return 37; + break; /*grey + alpha*/ + case 6: + if (!(bd == 8 || bd == 16)) return 37; + break; /*RGBA*/ + default: + return 31; + } + return 0; /*allowed color type / bits combination*/ } static unsigned getNumColorChannels(LodePNGColorType colortype) { - switch(colortype) - { - case 0: return 1; /*grey*/ - case 2: return 3; /*RGB*/ - case 3: return 1; /*palette*/ - case 4: return 2; /*grey + alpha*/ - case 6: return 4; /*RGBA*/ - } - return 0; /*unexisting color type*/ + switch (colortype) + { + case 0: + return 1; /*grey*/ + case 2: + return 3; /*RGB*/ + case 3: + return 1; /*palette*/ + case 4: + return 2; /*grey + alpha*/ + case 6: + return 4; /*RGBA*/ + } + return 0; /*unexisting color type*/ } static unsigned lodepng_get_bpp_lct(LodePNGColorType colortype, unsigned bitdepth) { - /*bits per pixel is amount of channels * bits per channel*/ - return getNumColorChannels(colortype) * bitdepth; + /*bits per pixel is amount of channels * bits per channel*/ + return getNumColorChannels(colortype) * bitdepth; } /* ////////////////////////////////////////////////////////////////////////// */ void lodepng_color_mode_init(LodePNGColorMode* info) { - info->key_defined = 0; - info->key_r = info->key_g = info->key_b = 0; - info->colortype = LCT_RGBA; - info->bitdepth = 8; - info->palette = 0; - info->palettesize = 0; + info->key_defined = 0; + info->key_r = info->key_g = info->key_b = 0; + info->colortype = LCT_RGBA; + info->bitdepth = 8; + info->palette = 0; + info->palettesize = 0; } void lodepng_color_mode_cleanup(LodePNGColorMode* info) { - lodepng_palette_clear(info); + lodepng_palette_clear(info); } unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* source) { - size_t i; - lodepng_color_mode_cleanup(dest); - *dest = *source; - if(source->palette) - { - dest->palette = (unsigned char*)lodepng_malloc(1024); - if(!dest->palette && source->palettesize) return 83; /*alloc fail*/ - for(i = 0; i < source->palettesize * 4; i++) dest->palette[i] = source->palette[i]; - } - return 0; + size_t i; + lodepng_color_mode_cleanup(dest); + *dest = *source; + if (source->palette) + { + dest->palette = (unsigned char*)lodepng_malloc(1024); + if (!dest->palette && source->palettesize) return 83; /*alloc fail*/ + for (i = 0; i < source->palettesize * 4; i++) dest->palette[i] = source->palette[i]; + } + return 0; } static int lodepng_color_mode_equal(const LodePNGColorMode* a, const LodePNGColorMode* b) { - size_t i; - if(a->colortype != b->colortype) return 0; - if(a->bitdepth != b->bitdepth) return 0; - if(a->key_defined != b->key_defined) return 0; - if(a->key_defined) - { - if(a->key_r != b->key_r) return 0; - if(a->key_g != b->key_g) return 0; - if(a->key_b != b->key_b) return 0; - } - if(a->palettesize != b->palettesize) return 0; - for(i = 0; i < a->palettesize * 4; i++) - { - if(a->palette[i] != b->palette[i]) return 0; - } - return 1; + size_t i; + if (a->colortype != b->colortype) return 0; + if (a->bitdepth != b->bitdepth) return 0; + if (a->key_defined != b->key_defined) return 0; + if (a->key_defined) + { + if (a->key_r != b->key_r) return 0; + if (a->key_g != b->key_g) return 0; + if (a->key_b != b->key_b) return 0; + } + if (a->palettesize != b->palettesize) return 0; + for (i = 0; i < a->palettesize * 4; i++) + { + if (a->palette[i] != b->palette[i]) return 0; + } + return 1; } void lodepng_palette_clear(LodePNGColorMode* info) { - if(info->palette) lodepng_free(info->palette); - info->palette = 0; - info->palettesize = 0; + if (info->palette) lodepng_free(info->palette); + info->palette = 0; + info->palettesize = 0; } unsigned lodepng_palette_add(LodePNGColorMode* info, - unsigned char r, unsigned char g, unsigned char b, unsigned char a) + unsigned char r, unsigned char g, unsigned char b, unsigned char a) { - unsigned char* data; - /*the same resize technique as C++ std::vectors is used, and here it's made so that for a palette with + unsigned char* data; + /*the same resize technique as C++ std::vectors is used, and here it's made so that for a palette with the max of 256 colors, it'll have the exact alloc size*/ - if(!info->palette) /*allocate palette if empty*/ - { - /*room for 256 colors with 4 bytes each*/ - data = (unsigned char*)lodepng_realloc(info->palette, 1024); - if(!data) return 83; /*alloc fail*/ - else info->palette = data; - } - info->palette[4 * info->palettesize + 0] = r; - info->palette[4 * info->palettesize + 1] = g; - info->palette[4 * info->palettesize + 2] = b; - info->palette[4 * info->palettesize + 3] = a; - info->palettesize++; - return 0; + if (!info->palette) /*allocate palette if empty*/ + { + /*room for 256 colors with 4 bytes each*/ + data = (unsigned char*)lodepng_realloc(info->palette, 1024); + if (!data) + return 83; /*alloc fail*/ + else + info->palette = data; + } + info->palette[4 * info->palettesize + 0] = r; + info->palette[4 * info->palettesize + 1] = g; + info->palette[4 * info->palettesize + 2] = b; + info->palette[4 * info->palettesize + 3] = a; + info->palettesize++; + return 0; } unsigned lodepng_get_bpp(const LodePNGColorMode* info) { - /*calculate bits per pixel out of colortype and bitdepth*/ - return lodepng_get_bpp_lct(info->colortype, info->bitdepth); + /*calculate bits per pixel out of colortype and bitdepth*/ + return lodepng_get_bpp_lct(info->colortype, info->bitdepth); } unsigned lodepng_get_channels(const LodePNGColorMode* info) { - return getNumColorChannels(info->colortype); + return getNumColorChannels(info->colortype); } unsigned lodepng_is_greyscale_type(const LodePNGColorMode* info) { - return info->colortype == LCT_GREY || info->colortype == LCT_GREY_ALPHA; + return info->colortype == LCT_GREY || info->colortype == LCT_GREY_ALPHA; } unsigned lodepng_is_alpha_type(const LodePNGColorMode* info) { - return (info->colortype & 4) != 0; /*4 or 6*/ + return (info->colortype & 4) != 0; /*4 or 6*/ } unsigned lodepng_is_palette_type(const LodePNGColorMode* info) { - return info->colortype == LCT_PALETTE; + return info->colortype == LCT_PALETTE; } unsigned lodepng_has_palette_alpha(const LodePNGColorMode* info) { - size_t i; - for(i = 0; i < info->palettesize; i++) - { - if(info->palette[i * 4 + 3] < 255) return 1; - } - return 0; + size_t i; + for (i = 0; i < info->palettesize; i++) + { + if (info->palette[i * 4 + 3] < 255) return 1; + } + return 0; } unsigned lodepng_can_have_alpha(const LodePNGColorMode* info) { - return info->key_defined - || lodepng_is_alpha_type(info) - || lodepng_has_palette_alpha(info); + return info->key_defined || lodepng_is_alpha_type(info) || lodepng_has_palette_alpha(info); } size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* color) { - return (w * h * lodepng_get_bpp(color) + 7) / 8; + return (w * h * lodepng_get_bpp(color) + 7) / 8; } size_t lodepng_get_raw_size_lct(unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { - return (w * h * lodepng_get_bpp_lct(colortype, bitdepth) + 7) / 8; + return (w * h * lodepng_get_bpp_lct(colortype, bitdepth) + 7) / 8; } - #ifdef LODEPNG_COMPILE_PNG #ifdef LODEPNG_COMPILE_DECODER /*in an idat chunk, each scanline is a multiple of 8 bits, unlike the lodepng output buffer*/ static size_t lodepng_get_raw_size_idat(unsigned w, unsigned h, const LodePNGColorMode* color) { - return h * ((w * lodepng_get_bpp(color) + 7) / 8); + return h * ((w * lodepng_get_bpp(color) + 7) / 8); } #endif /*LODEPNG_COMPILE_DECODER*/ #endif /*LODEPNG_COMPILE_PNG*/ @@ -2690,240 +2754,240 @@ static size_t lodepng_get_raw_size_idat(unsigned w, unsigned h, const LodePNGCol static void LodePNGUnknownChunks_init(LodePNGInfo* info) { - unsigned i; - for(i = 0; i < 3; i++) info->unknown_chunks_data[i] = 0; - for(i = 0; i < 3; i++) info->unknown_chunks_size[i] = 0; + unsigned i; + for (i = 0; i < 3; i++) info->unknown_chunks_data[i] = 0; + for (i = 0; i < 3; i++) info->unknown_chunks_size[i] = 0; } static void LodePNGUnknownChunks_cleanup(LodePNGInfo* info) { - unsigned i; - for(i = 0; i < 3; i++) lodepng_free(info->unknown_chunks_data[i]); + unsigned i; + for (i = 0; i < 3; i++) lodepng_free(info->unknown_chunks_data[i]); } static unsigned LodePNGUnknownChunks_copy(LodePNGInfo* dest, const LodePNGInfo* src) { - unsigned i; + unsigned i; - LodePNGUnknownChunks_cleanup(dest); + LodePNGUnknownChunks_cleanup(dest); - for(i = 0; i < 3; i++) - { - size_t j; - dest->unknown_chunks_size[i] = src->unknown_chunks_size[i]; - dest->unknown_chunks_data[i] = (unsigned char*)lodepng_malloc(src->unknown_chunks_size[i]); - if(!dest->unknown_chunks_data[i] && dest->unknown_chunks_size[i]) return 83; /*alloc fail*/ - for(j = 0; j < src->unknown_chunks_size[i]; j++) - { - dest->unknown_chunks_data[i][j] = src->unknown_chunks_data[i][j]; - } - } + for (i = 0; i < 3; i++) + { + size_t j; + dest->unknown_chunks_size[i] = src->unknown_chunks_size[i]; + dest->unknown_chunks_data[i] = (unsigned char*)lodepng_malloc(src->unknown_chunks_size[i]); + if (!dest->unknown_chunks_data[i] && dest->unknown_chunks_size[i]) return 83; /*alloc fail*/ + for (j = 0; j < src->unknown_chunks_size[i]; j++) + { + dest->unknown_chunks_data[i][j] = src->unknown_chunks_data[i][j]; + } + } - return 0; + return 0; } /******************************************************************************/ static void LodePNGText_init(LodePNGInfo* info) { - info->text_num = 0; - info->text_keys = NULL; - info->text_strings = NULL; + info->text_num = 0; + info->text_keys = NULL; + info->text_strings = NULL; } static void LodePNGText_cleanup(LodePNGInfo* info) { - size_t i; - for(i = 0; i < info->text_num; i++) - { - string_cleanup(&info->text_keys[i]); - string_cleanup(&info->text_strings[i]); - } - lodepng_free(info->text_keys); - lodepng_free(info->text_strings); + size_t i; + for (i = 0; i < info->text_num; i++) + { + string_cleanup(&info->text_keys[i]); + string_cleanup(&info->text_strings[i]); + } + lodepng_free(info->text_keys); + lodepng_free(info->text_strings); } static unsigned LodePNGText_copy(LodePNGInfo* dest, const LodePNGInfo* source) { - size_t i = 0; - dest->text_keys = 0; - dest->text_strings = 0; - dest->text_num = 0; - for(i = 0; i < source->text_num; i++) - { - CERROR_TRY_RETURN(lodepng_add_text(dest, source->text_keys[i], source->text_strings[i])); - } - return 0; + size_t i = 0; + dest->text_keys = 0; + dest->text_strings = 0; + dest->text_num = 0; + for (i = 0; i < source->text_num; i++) + { + CERROR_TRY_RETURN(lodepng_add_text(dest, source->text_keys[i], source->text_strings[i])); + } + return 0; } void lodepng_clear_text(LodePNGInfo* info) { - LodePNGText_cleanup(info); + LodePNGText_cleanup(info); } unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str) { - char** new_keys = (char**)(lodepng_realloc(info->text_keys, sizeof(char*) * (info->text_num + 1))); - char** new_strings = (char**)(lodepng_realloc(info->text_strings, sizeof(char*) * (info->text_num + 1))); - if(!new_keys || !new_strings) - { - lodepng_free(new_keys); - lodepng_free(new_strings); - return 83; /*alloc fail*/ - } + char** new_keys = (char**)(lodepng_realloc(info->text_keys, sizeof(char*) * (info->text_num + 1))); + char** new_strings = (char**)(lodepng_realloc(info->text_strings, sizeof(char*) * (info->text_num + 1))); + if (!new_keys || !new_strings) + { + lodepng_free(new_keys); + lodepng_free(new_strings); + return 83; /*alloc fail*/ + } - info->text_num++; - info->text_keys = new_keys; - info->text_strings = new_strings; + info->text_num++; + info->text_keys = new_keys; + info->text_strings = new_strings; - string_init(&info->text_keys[info->text_num - 1]); - string_set(&info->text_keys[info->text_num - 1], key); + string_init(&info->text_keys[info->text_num - 1]); + string_set(&info->text_keys[info->text_num - 1], key); - string_init(&info->text_strings[info->text_num - 1]); - string_set(&info->text_strings[info->text_num - 1], str); + string_init(&info->text_strings[info->text_num - 1]); + string_set(&info->text_strings[info->text_num - 1], str); - return 0; + return 0; } /******************************************************************************/ static void LodePNGIText_init(LodePNGInfo* info) { - info->itext_num = 0; - info->itext_keys = NULL; - info->itext_langtags = NULL; - info->itext_transkeys = NULL; - info->itext_strings = NULL; + info->itext_num = 0; + info->itext_keys = NULL; + info->itext_langtags = NULL; + info->itext_transkeys = NULL; + info->itext_strings = NULL; } static void LodePNGIText_cleanup(LodePNGInfo* info) { - size_t i; - for(i = 0; i < info->itext_num; i++) - { - string_cleanup(&info->itext_keys[i]); - string_cleanup(&info->itext_langtags[i]); - string_cleanup(&info->itext_transkeys[i]); - string_cleanup(&info->itext_strings[i]); - } - lodepng_free(info->itext_keys); - lodepng_free(info->itext_langtags); - lodepng_free(info->itext_transkeys); - lodepng_free(info->itext_strings); + size_t i; + for (i = 0; i < info->itext_num; i++) + { + string_cleanup(&info->itext_keys[i]); + string_cleanup(&info->itext_langtags[i]); + string_cleanup(&info->itext_transkeys[i]); + string_cleanup(&info->itext_strings[i]); + } + lodepng_free(info->itext_keys); + lodepng_free(info->itext_langtags); + lodepng_free(info->itext_transkeys); + lodepng_free(info->itext_strings); } static unsigned LodePNGIText_copy(LodePNGInfo* dest, const LodePNGInfo* source) { - size_t i = 0; - dest->itext_keys = 0; - dest->itext_langtags = 0; - dest->itext_transkeys = 0; - dest->itext_strings = 0; - dest->itext_num = 0; - for(i = 0; i < source->itext_num; i++) - { - CERROR_TRY_RETURN(lodepng_add_itext(dest, source->itext_keys[i], source->itext_langtags[i], - source->itext_transkeys[i], source->itext_strings[i])); - } - return 0; + size_t i = 0; + dest->itext_keys = 0; + dest->itext_langtags = 0; + dest->itext_transkeys = 0; + dest->itext_strings = 0; + dest->itext_num = 0; + for (i = 0; i < source->itext_num; i++) + { + CERROR_TRY_RETURN(lodepng_add_itext(dest, source->itext_keys[i], source->itext_langtags[i], + source->itext_transkeys[i], source->itext_strings[i])); + } + return 0; } void lodepng_clear_itext(LodePNGInfo* info) { - LodePNGIText_cleanup(info); + LodePNGIText_cleanup(info); } unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag, - const char* transkey, const char* str) + const char* transkey, const char* str) { - char** new_keys = (char**)(lodepng_realloc(info->itext_keys, sizeof(char*) * (info->itext_num + 1))); - char** new_langtags = (char**)(lodepng_realloc(info->itext_langtags, sizeof(char*) * (info->itext_num + 1))); - char** new_transkeys = (char**)(lodepng_realloc(info->itext_transkeys, sizeof(char*) * (info->itext_num + 1))); - char** new_strings = (char**)(lodepng_realloc(info->itext_strings, sizeof(char*) * (info->itext_num + 1))); - if(!new_keys || !new_langtags || !new_transkeys || !new_strings) - { - lodepng_free(new_keys); - lodepng_free(new_langtags); - lodepng_free(new_transkeys); - lodepng_free(new_strings); - return 83; /*alloc fail*/ - } + char** new_keys = (char**)(lodepng_realloc(info->itext_keys, sizeof(char*) * (info->itext_num + 1))); + char** new_langtags = (char**)(lodepng_realloc(info->itext_langtags, sizeof(char*) * (info->itext_num + 1))); + char** new_transkeys = (char**)(lodepng_realloc(info->itext_transkeys, sizeof(char*) * (info->itext_num + 1))); + char** new_strings = (char**)(lodepng_realloc(info->itext_strings, sizeof(char*) * (info->itext_num + 1))); + if (!new_keys || !new_langtags || !new_transkeys || !new_strings) + { + lodepng_free(new_keys); + lodepng_free(new_langtags); + lodepng_free(new_transkeys); + lodepng_free(new_strings); + return 83; /*alloc fail*/ + } - info->itext_num++; - info->itext_keys = new_keys; - info->itext_langtags = new_langtags; - info->itext_transkeys = new_transkeys; - info->itext_strings = new_strings; + info->itext_num++; + info->itext_keys = new_keys; + info->itext_langtags = new_langtags; + info->itext_transkeys = new_transkeys; + info->itext_strings = new_strings; - string_init(&info->itext_keys[info->itext_num - 1]); - string_set(&info->itext_keys[info->itext_num - 1], key); + string_init(&info->itext_keys[info->itext_num - 1]); + string_set(&info->itext_keys[info->itext_num - 1], key); - string_init(&info->itext_langtags[info->itext_num - 1]); - string_set(&info->itext_langtags[info->itext_num - 1], langtag); + string_init(&info->itext_langtags[info->itext_num - 1]); + string_set(&info->itext_langtags[info->itext_num - 1], langtag); - string_init(&info->itext_transkeys[info->itext_num - 1]); - string_set(&info->itext_transkeys[info->itext_num - 1], transkey); + string_init(&info->itext_transkeys[info->itext_num - 1]); + string_set(&info->itext_transkeys[info->itext_num - 1], transkey); - string_init(&info->itext_strings[info->itext_num - 1]); - string_set(&info->itext_strings[info->itext_num - 1], str); + string_init(&info->itext_strings[info->itext_num - 1]); + string_set(&info->itext_strings[info->itext_num - 1], str); - return 0; + return 0; } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ void lodepng_info_init(LodePNGInfo* info) { - lodepng_color_mode_init(&info->color); - info->interlace_method = 0; - info->compression_method = 0; - info->filter_method = 0; + lodepng_color_mode_init(&info->color); + info->interlace_method = 0; + info->compression_method = 0; + info->filter_method = 0; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - info->background_defined = 0; - info->background_r = info->background_g = info->background_b = 0; + info->background_defined = 0; + info->background_r = info->background_g = info->background_b = 0; - LodePNGText_init(info); - LodePNGIText_init(info); + LodePNGText_init(info); + LodePNGIText_init(info); - info->time_defined = 0; - info->phys_defined = 0; + info->time_defined = 0; + info->phys_defined = 0; - LodePNGUnknownChunks_init(info); + LodePNGUnknownChunks_init(info); #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } void lodepng_info_cleanup(LodePNGInfo* info) { - lodepng_color_mode_cleanup(&info->color); + lodepng_color_mode_cleanup(&info->color); #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - LodePNGText_cleanup(info); - LodePNGIText_cleanup(info); + LodePNGText_cleanup(info); + LodePNGIText_cleanup(info); - LodePNGUnknownChunks_cleanup(info); + LodePNGUnknownChunks_cleanup(info); #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source) { - lodepng_info_cleanup(dest); - *dest = *source; - lodepng_color_mode_init(&dest->color); - CERROR_TRY_RETURN(lodepng_color_mode_copy(&dest->color, &source->color)); + lodepng_info_cleanup(dest); + *dest = *source; + lodepng_color_mode_init(&dest->color); + CERROR_TRY_RETURN(lodepng_color_mode_copy(&dest->color, &source->color)); #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - CERROR_TRY_RETURN(LodePNGText_copy(dest, source)); - CERROR_TRY_RETURN(LodePNGIText_copy(dest, source)); + CERROR_TRY_RETURN(LodePNGText_copy(dest, source)); + CERROR_TRY_RETURN(LodePNGIText_copy(dest, source)); - LodePNGUnknownChunks_init(dest); - CERROR_TRY_RETURN(LodePNGUnknownChunks_copy(dest, source)); + LodePNGUnknownChunks_init(dest); + CERROR_TRY_RETURN(LodePNGUnknownChunks_copy(dest, source)); #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - return 0; + return 0; } void lodepng_info_swap(LodePNGInfo* a, LodePNGInfo* b) { - LodePNGInfo temp = *a; - *a = *b; - *b = temp; + LodePNGInfo temp = *a; + *a = *b; + *b = temp; } /* ////////////////////////////////////////////////////////////////////////// */ @@ -2931,13 +2995,15 @@ void lodepng_info_swap(LodePNGInfo* a, LodePNGInfo* b) /*index: bitgroup index, bits: bitgroup size(1, 2 or 4), in: bitgroup value, out: octet array to add bits to*/ static void addColorBits(unsigned char* out, size_t index, unsigned bits, unsigned in) { - unsigned m = bits == 1 ? 7 : bits == 2 ? 3 : 1; /*8 / bits - 1*/ - /*p = the partial index in the byte, e.g. with 4 palettebits it is 0 for first half or 1 for second half*/ - unsigned p = index & m; - in &= (1u << bits) - 1u; /*filter out any other bits of the input value*/ - in = in << (bits * (m - p)); - if(p == 0) out[index * bits / 8] = in; - else out[index * bits / 8] |= in; + unsigned m = bits == 1 ? 7 : bits == 2 ? 3 : 1; /*8 / bits - 1*/ + /*p = the partial index in the byte, e.g. with 4 palettebits it is 0 for first half or 1 for second half*/ + unsigned p = index & m; + in &= (1u << bits) - 1u; /*filter out any other bits of the input value*/ + in = in << (bits * (m - p)); + if (p == 0) + out[index * bits / 8] = in; + else + out[index * bits / 8] |= in; } typedef struct ColorTree ColorTree; @@ -2950,288 +3016,309 @@ node has 16 instead of 8 children. */ struct ColorTree { - ColorTree* children[16]; /*up to 16 pointers to ColorTree of next level*/ - int index; /*the payload. Only has a meaningful value if this is in the last level*/ + ColorTree* children[16]; /*up to 16 pointers to ColorTree of next level*/ + int index; /*the payload. Only has a meaningful value if this is in the last level*/ }; static void color_tree_init(ColorTree* tree) { - int i; - for(i = 0; i < 16; i++) tree->children[i] = 0; - tree->index = -1; + int i; + for (i = 0; i < 16; i++) tree->children[i] = 0; + tree->index = -1; } static void color_tree_cleanup(ColorTree* tree) { - int i; - for(i = 0; i < 16; i++) - { - if(tree->children[i]) - { - color_tree_cleanup(tree->children[i]); - lodepng_free(tree->children[i]); - } - } + int i; + for (i = 0; i < 16; i++) + { + if (tree->children[i]) + { + color_tree_cleanup(tree->children[i]); + lodepng_free(tree->children[i]); + } + } } /*returns -1 if color not present, its index otherwise*/ static int color_tree_get(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { - int bit = 0; - for(bit = 0; bit < 8; bit++) - { - int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1); - if(!tree->children[i]) return -1; - else tree = tree->children[i]; - } - return tree ? tree->index : -1; + int bit = 0; + for (bit = 0; bit < 8; bit++) + { + int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1); + if (!tree->children[i]) + return -1; + else + tree = tree->children[i]; + } + return tree ? tree->index : -1; } #ifdef LODEPNG_COMPILE_ENCODER static int color_tree_has(ColorTree* tree, unsigned char r, unsigned char g, unsigned char b, unsigned char a) { - return color_tree_get(tree, r, g, b, a) >= 0; + return color_tree_get(tree, r, g, b, a) >= 0; } #endif /*LODEPNG_COMPILE_ENCODER*/ /*color is not allowed to already exist. Index should be >= 0 (it's signed to be compatible with using -1 for "doesn't exist")*/ static void color_tree_add(ColorTree* tree, - unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned index) + unsigned char r, unsigned char g, unsigned char b, unsigned char a, unsigned index) { - int bit; - for(bit = 0; bit < 8; bit++) - { - int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1); - if(!tree->children[i]) - { - tree->children[i] = (ColorTree*)lodepng_malloc(sizeof(ColorTree)); - color_tree_init(tree->children[i]); - } - tree = tree->children[i]; - } - tree->index = (int)index; + int bit; + for (bit = 0; bit < 8; bit++) + { + int i = 8 * ((r >> bit) & 1) + 4 * ((g >> bit) & 1) + 2 * ((b >> bit) & 1) + 1 * ((a >> bit) & 1); + if (!tree->children[i]) + { + tree->children[i] = (ColorTree*)lodepng_malloc(sizeof(ColorTree)); + color_tree_init(tree->children[i]); + } + tree = tree->children[i]; + } + tree->index = (int)index; } /*put a pixel, given its RGBA color, into image of any color type*/ static unsigned rgba8ToPixel(unsigned char* out, size_t i, - const LodePNGColorMode* mode, ColorTree* tree /*for palette*/, - unsigned char r, unsigned char g, unsigned char b, unsigned char a) + const LodePNGColorMode* mode, ColorTree* tree /*for palette*/, + unsigned char r, unsigned char g, unsigned char b, unsigned char a) { - if(mode->colortype == LCT_GREY) - { - unsigned char grey = r; /*((unsigned short)r + g + b) / 3*/; - if(mode->bitdepth == 8) out[i] = grey; - else if(mode->bitdepth == 16) out[i * 2 + 0] = out[i * 2 + 1] = grey; - else - { - /*take the most significant bits of grey*/ - grey = (grey >> (8 - mode->bitdepth)) & ((1 << mode->bitdepth) - 1); - addColorBits(out, i, mode->bitdepth, grey); - } - } - else if(mode->colortype == LCT_RGB) - { - if(mode->bitdepth == 8) - { - out[i * 3 + 0] = r; - out[i * 3 + 1] = g; - out[i * 3 + 2] = b; - } - else - { - out[i * 6 + 0] = out[i * 6 + 1] = r; - out[i * 6 + 2] = out[i * 6 + 3] = g; - out[i * 6 + 4] = out[i * 6 + 5] = b; - } - } - else if(mode->colortype == LCT_PALETTE) - { - int index = color_tree_get(tree, r, g, b, a); - if(index < 0) return 82; /*color not in palette*/ - if(mode->bitdepth == 8) out[i] = index; - else addColorBits(out, i, mode->bitdepth, (unsigned)index); - } - else if(mode->colortype == LCT_GREY_ALPHA) - { - unsigned char grey = r; /*((unsigned short)r + g + b) / 3*/; - if(mode->bitdepth == 8) - { - out[i * 2 + 0] = grey; - out[i * 2 + 1] = a; - } - else if(mode->bitdepth == 16) - { - out[i * 4 + 0] = out[i * 4 + 1] = grey; - out[i * 4 + 2] = out[i * 4 + 3] = a; - } - } - else if(mode->colortype == LCT_RGBA) - { - if(mode->bitdepth == 8) - { - out[i * 4 + 0] = r; - out[i * 4 + 1] = g; - out[i * 4 + 2] = b; - out[i * 4 + 3] = a; - } - else - { - out[i * 8 + 0] = out[i * 8 + 1] = r; - out[i * 8 + 2] = out[i * 8 + 3] = g; - out[i * 8 + 4] = out[i * 8 + 5] = b; - out[i * 8 + 6] = out[i * 8 + 7] = a; - } - } + if (mode->colortype == LCT_GREY) + { + unsigned char grey = r; /*((unsigned short)r + g + b) / 3*/ + ; + if (mode->bitdepth == 8) + out[i] = grey; + else if (mode->bitdepth == 16) + out[i * 2 + 0] = out[i * 2 + 1] = grey; + else + { + /*take the most significant bits of grey*/ + grey = (grey >> (8 - mode->bitdepth)) & ((1 << mode->bitdepth) - 1); + addColorBits(out, i, mode->bitdepth, grey); + } + } + else if (mode->colortype == LCT_RGB) + { + if (mode->bitdepth == 8) + { + out[i * 3 + 0] = r; + out[i * 3 + 1] = g; + out[i * 3 + 2] = b; + } + else + { + out[i * 6 + 0] = out[i * 6 + 1] = r; + out[i * 6 + 2] = out[i * 6 + 3] = g; + out[i * 6 + 4] = out[i * 6 + 5] = b; + } + } + else if (mode->colortype == LCT_PALETTE) + { + int index = color_tree_get(tree, r, g, b, a); + if (index < 0) return 82; /*color not in palette*/ + if (mode->bitdepth == 8) + out[i] = index; + else + addColorBits(out, i, mode->bitdepth, (unsigned)index); + } + else if (mode->colortype == LCT_GREY_ALPHA) + { + unsigned char grey = r; /*((unsigned short)r + g + b) / 3*/ + ; + if (mode->bitdepth == 8) + { + out[i * 2 + 0] = grey; + out[i * 2 + 1] = a; + } + else if (mode->bitdepth == 16) + { + out[i * 4 + 0] = out[i * 4 + 1] = grey; + out[i * 4 + 2] = out[i * 4 + 3] = a; + } + } + else if (mode->colortype == LCT_RGBA) + { + if (mode->bitdepth == 8) + { + out[i * 4 + 0] = r; + out[i * 4 + 1] = g; + out[i * 4 + 2] = b; + out[i * 4 + 3] = a; + } + else + { + out[i * 8 + 0] = out[i * 8 + 1] = r; + out[i * 8 + 2] = out[i * 8 + 3] = g; + out[i * 8 + 4] = out[i * 8 + 5] = b; + out[i * 8 + 6] = out[i * 8 + 7] = a; + } + } - return 0; /*no error*/ + return 0; /*no error*/ } /*put a pixel, given its RGBA16 color, into image of any color 16-bitdepth type*/ static void rgba16ToPixel(unsigned char* out, size_t i, - const LodePNGColorMode* mode, - unsigned short r, unsigned short g, unsigned short b, unsigned short a) + const LodePNGColorMode* mode, + unsigned short r, unsigned short g, unsigned short b, unsigned short a) { - if(mode->colortype == LCT_GREY) - { - unsigned short grey = r; /*((unsigned)r + g + b) / 3*/; - out[i * 2 + 0] = (grey >> 8) & 255; - out[i * 2 + 1] = grey & 255; - } - else if(mode->colortype == LCT_RGB) - { - out[i * 6 + 0] = (r >> 8) & 255; - out[i * 6 + 1] = r & 255; - out[i * 6 + 2] = (g >> 8) & 255; - out[i * 6 + 3] = g & 255; - out[i * 6 + 4] = (b >> 8) & 255; - out[i * 6 + 5] = b & 255; - } - else if(mode->colortype == LCT_GREY_ALPHA) - { - unsigned short grey = r; /*((unsigned)r + g + b) / 3*/; - out[i * 4 + 0] = (grey >> 8) & 255; - out[i * 4 + 1] = grey & 255; - out[i * 4 + 2] = (a >> 8) & 255; - out[i * 4 + 3] = a & 255; - } - else if(mode->colortype == LCT_RGBA) - { - out[i * 8 + 0] = (r >> 8) & 255; - out[i * 8 + 1] = r & 255; - out[i * 8 + 2] = (g >> 8) & 255; - out[i * 8 + 3] = g & 255; - out[i * 8 + 4] = (b >> 8) & 255; - out[i * 8 + 5] = b & 255; - out[i * 8 + 6] = (a >> 8) & 255; - out[i * 8 + 7] = a & 255; - } + if (mode->colortype == LCT_GREY) + { + unsigned short grey = r; /*((unsigned)r + g + b) / 3*/ + ; + out[i * 2 + 0] = (grey >> 8) & 255; + out[i * 2 + 1] = grey & 255; + } + else if (mode->colortype == LCT_RGB) + { + out[i * 6 + 0] = (r >> 8) & 255; + out[i * 6 + 1] = r & 255; + out[i * 6 + 2] = (g >> 8) & 255; + out[i * 6 + 3] = g & 255; + out[i * 6 + 4] = (b >> 8) & 255; + out[i * 6 + 5] = b & 255; + } + else if (mode->colortype == LCT_GREY_ALPHA) + { + unsigned short grey = r; /*((unsigned)r + g + b) / 3*/ + ; + out[i * 4 + 0] = (grey >> 8) & 255; + out[i * 4 + 1] = grey & 255; + out[i * 4 + 2] = (a >> 8) & 255; + out[i * 4 + 3] = a & 255; + } + else if (mode->colortype == LCT_RGBA) + { + out[i * 8 + 0] = (r >> 8) & 255; + out[i * 8 + 1] = r & 255; + out[i * 8 + 2] = (g >> 8) & 255; + out[i * 8 + 3] = g & 255; + out[i * 8 + 4] = (b >> 8) & 255; + out[i * 8 + 5] = b & 255; + out[i * 8 + 6] = (a >> 8) & 255; + out[i * 8 + 7] = a & 255; + } } /*Get RGBA8 color of pixel with index i (y * width + x) from the raw image with given color type.*/ static void getPixelColorRGBA8(unsigned char* r, unsigned char* g, - unsigned char* b, unsigned char* a, - const unsigned char* in, size_t i, - const LodePNGColorMode* mode) + unsigned char* b, unsigned char* a, + const unsigned char* in, size_t i, + const LodePNGColorMode* mode) { - if(mode->colortype == LCT_GREY) - { - if(mode->bitdepth == 8) - { - *r = *g = *b = in[i]; - if(mode->key_defined && *r == mode->key_r) *a = 0; - else *a = 255; - } - else if(mode->bitdepth == 16) - { - *r = *g = *b = in[i * 2 + 0]; - if(mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0; - else *a = 255; - } - else - { - unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/ - size_t j = i * mode->bitdepth; - unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); - *r = *g = *b = (value * 255) / highest; - if(mode->key_defined && value == mode->key_r) *a = 0; - else *a = 255; - } - } - else if(mode->colortype == LCT_RGB) - { - if(mode->bitdepth == 8) - { - *r = in[i * 3 + 0]; *g = in[i * 3 + 1]; *b = in[i * 3 + 2]; - if(mode->key_defined && *r == mode->key_r && *g == mode->key_g && *b == mode->key_b) *a = 0; - else *a = 255; - } - else - { - *r = in[i * 6 + 0]; - *g = in[i * 6 + 2]; - *b = in[i * 6 + 4]; - if(mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r - && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g - && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0; - else *a = 255; - } - } - else if(mode->colortype == LCT_PALETTE) - { - unsigned index; - if(mode->bitdepth == 8) index = in[i]; - else - { - size_t j = i * mode->bitdepth; - index = readBitsFromReversedStream(&j, in, mode->bitdepth); - } + if (mode->colortype == LCT_GREY) + { + if (mode->bitdepth == 8) + { + *r = *g = *b = in[i]; + if (mode->key_defined && *r == mode->key_r) + *a = 0; + else + *a = 255; + } + else if (mode->bitdepth == 16) + { + *r = *g = *b = in[i * 2 + 0]; + if (mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) + *a = 0; + else + *a = 255; + } + else + { + unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/ + size_t j = i * mode->bitdepth; + unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); + *r = *g = *b = (value * 255) / highest; + if (mode->key_defined && value == mode->key_r) + *a = 0; + else + *a = 255; + } + } + else if (mode->colortype == LCT_RGB) + { + if (mode->bitdepth == 8) + { + *r = in[i * 3 + 0]; + *g = in[i * 3 + 1]; + *b = in[i * 3 + 2]; + if (mode->key_defined && *r == mode->key_r && *g == mode->key_g && *b == mode->key_b) + *a = 0; + else + *a = 255; + } + else + { + *r = in[i * 6 + 0]; + *g = in[i * 6 + 2]; + *b = in[i * 6 + 4]; + if (mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) + *a = 0; + else + *a = 255; + } + } + else if (mode->colortype == LCT_PALETTE) + { + unsigned index; + if (mode->bitdepth == 8) + index = in[i]; + else + { + size_t j = i * mode->bitdepth; + index = readBitsFromReversedStream(&j, in, mode->bitdepth); + } - if(index >= mode->palettesize) - { - /*This is an error according to the PNG spec, but common PNG decoders make it black instead. + if (index >= mode->palettesize) + { + /*This is an error according to the PNG spec, but common PNG decoders make it black instead. Done here too, slightly faster due to no error handling needed.*/ - *r = *g = *b = 0; - *a = 255; - } - else - { - *r = mode->palette[index * 4 + 0]; - *g = mode->palette[index * 4 + 1]; - *b = mode->palette[index * 4 + 2]; - *a = mode->palette[index * 4 + 3]; - } - } - else if(mode->colortype == LCT_GREY_ALPHA) - { - if(mode->bitdepth == 8) - { - *r = *g = *b = in[i * 2 + 0]; - *a = in[i * 2 + 1]; - } - else - { - *r = *g = *b = in[i * 4 + 0]; - *a = in[i * 4 + 2]; - } - } - else if(mode->colortype == LCT_RGBA) - { - if(mode->bitdepth == 8) - { - *r = in[i * 4 + 0]; - *g = in[i * 4 + 1]; - *b = in[i * 4 + 2]; - *a = in[i * 4 + 3]; - } - else - { - *r = in[i * 8 + 0]; - *g = in[i * 8 + 2]; - *b = in[i * 8 + 4]; - *a = in[i * 8 + 6]; - } - } + *r = *g = *b = 0; + *a = 255; + } + else + { + *r = mode->palette[index * 4 + 0]; + *g = mode->palette[index * 4 + 1]; + *b = mode->palette[index * 4 + 2]; + *a = mode->palette[index * 4 + 3]; + } + } + else if (mode->colortype == LCT_GREY_ALPHA) + { + if (mode->bitdepth == 8) + { + *r = *g = *b = in[i * 2 + 0]; + *a = in[i * 2 + 1]; + } + else + { + *r = *g = *b = in[i * 4 + 0]; + *a = in[i * 4 + 2]; + } + } + else if (mode->colortype == LCT_RGBA) + { + if (mode->bitdepth == 8) + { + *r = in[i * 4 + 0]; + *g = in[i * 4 + 1]; + *b = in[i * 4 + 2]; + *a = in[i * 4 + 3]; + } + else + { + *r = in[i * 8 + 0]; + *g = in[i * 8 + 2]; + *b = in[i * 8 + 4]; + *a = in[i * 8 + 6]; + } + } } /*Similar to getPixelColorRGBA8, but with all the for loops inside of the color @@ -3240,244 +3327,244 @@ to RGBA or RGB with 8 bit per cannel. buffer must be RGBA or RGB output with enough memory, if has_alpha is true the output is RGBA. mode has the color mode of the input buffer.*/ static void getPixelColorsRGBA8(unsigned char* buffer, size_t numpixels, - unsigned has_alpha, const unsigned char* in, - const LodePNGColorMode* mode) + unsigned has_alpha, const unsigned char* in, + const LodePNGColorMode* mode) { - unsigned num_channels = has_alpha ? 4 : 3; - size_t i; - if(mode->colortype == LCT_GREY) - { - if(mode->bitdepth == 8) - { - for(i = 0; i < numpixels; i++, buffer += num_channels) - { - buffer[0] = buffer[1] = buffer[2] = in[i]; - if(has_alpha) buffer[3] = mode->key_defined && in[i] == mode->key_r ? 0 : 255; - } - } - else if(mode->bitdepth == 16) - { - for(i = 0; i < numpixels; i++, buffer += num_channels) - { - buffer[0] = buffer[1] = buffer[2] = in[i * 2]; - if(has_alpha) buffer[3] = mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r ? 0 : 255; - } - } - else - { - unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/ - size_t j = 0; - for(i = 0; i < numpixels; i++, buffer += num_channels) - { - unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); - buffer[0] = buffer[1] = buffer[2] = (value * 255) / highest; - if(has_alpha) buffer[3] = mode->key_defined && value == mode->key_r ? 0 : 255; - } - } - } - else if(mode->colortype == LCT_RGB) - { - if(mode->bitdepth == 8) - { - for(i = 0; i < numpixels; i++, buffer += num_channels) - { - buffer[0] = in[i * 3 + 0]; - buffer[1] = in[i * 3 + 1]; - buffer[2] = in[i * 3 + 2]; - if(has_alpha) buffer[3] = mode->key_defined && buffer[0] == mode->key_r - && buffer[1]== mode->key_g && buffer[2] == mode->key_b ? 0 : 255; - } - } - else - { - for(i = 0; i < numpixels; i++, buffer += num_channels) - { - buffer[0] = in[i * 6 + 0]; - buffer[1] = in[i * 6 + 2]; - buffer[2] = in[i * 6 + 4]; - if(has_alpha) buffer[3] = mode->key_defined - && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r - && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g - && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b ? 0 : 255; - } - } - } - else if(mode->colortype == LCT_PALETTE) - { - unsigned index; - size_t j = 0; - for(i = 0; i < numpixels; i++, buffer += num_channels) - { - if(mode->bitdepth == 8) index = in[i]; - else index = readBitsFromReversedStream(&j, in, mode->bitdepth); + unsigned num_channels = has_alpha ? 4 : 3; + size_t i; + if (mode->colortype == LCT_GREY) + { + if (mode->bitdepth == 8) + { + for (i = 0; i < numpixels; i++, buffer += num_channels) + { + buffer[0] = buffer[1] = buffer[2] = in[i]; + if (has_alpha) buffer[3] = mode->key_defined && in[i] == mode->key_r ? 0 : 255; + } + } + else if (mode->bitdepth == 16) + { + for (i = 0; i < numpixels; i++, buffer += num_channels) + { + buffer[0] = buffer[1] = buffer[2] = in[i * 2]; + if (has_alpha) buffer[3] = mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r ? 0 : 255; + } + } + else + { + unsigned highest = ((1U << mode->bitdepth) - 1U); /*highest possible value for this bit depth*/ + size_t j = 0; + for (i = 0; i < numpixels; i++, buffer += num_channels) + { + unsigned value = readBitsFromReversedStream(&j, in, mode->bitdepth); + buffer[0] = buffer[1] = buffer[2] = (value * 255) / highest; + if (has_alpha) buffer[3] = mode->key_defined && value == mode->key_r ? 0 : 255; + } + } + } + else if (mode->colortype == LCT_RGB) + { + if (mode->bitdepth == 8) + { + for (i = 0; i < numpixels; i++, buffer += num_channels) + { + buffer[0] = in[i * 3 + 0]; + buffer[1] = in[i * 3 + 1]; + buffer[2] = in[i * 3 + 2]; + if (has_alpha) buffer[3] = mode->key_defined && buffer[0] == mode->key_r && buffer[1] == mode->key_g && buffer[2] == mode->key_b ? 0 : 255; + } + } + else + { + for (i = 0; i < numpixels; i++, buffer += num_channels) + { + buffer[0] = in[i * 6 + 0]; + buffer[1] = in[i * 6 + 2]; + buffer[2] = in[i * 6 + 4]; + if (has_alpha) buffer[3] = mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b ? 0 : 255; + } + } + } + else if (mode->colortype == LCT_PALETTE) + { + unsigned index; + size_t j = 0; + for (i = 0; i < numpixels; i++, buffer += num_channels) + { + if (mode->bitdepth == 8) + index = in[i]; + else + index = readBitsFromReversedStream(&j, in, mode->bitdepth); - if(index >= mode->palettesize) - { - /*This is an error according to the PNG spec, but most PNG decoders make it black instead. + if (index >= mode->palettesize) + { + /*This is an error according to the PNG spec, but most PNG decoders make it black instead. Done here too, slightly faster due to no error handling needed.*/ - buffer[0] = buffer[1] = buffer[2] = 0; - if(has_alpha) buffer[3] = 255; - } - else - { - buffer[0] = mode->palette[index * 4 + 0]; - buffer[1] = mode->palette[index * 4 + 1]; - buffer[2] = mode->palette[index * 4 + 2]; - if(has_alpha) buffer[3] = mode->palette[index * 4 + 3]; - } - } - } - else if(mode->colortype == LCT_GREY_ALPHA) - { - if(mode->bitdepth == 8) - { - for(i = 0; i < numpixels; i++, buffer += num_channels) - { - buffer[0] = buffer[1] = buffer[2] = in[i * 2 + 0]; - if(has_alpha) buffer[3] = in[i * 2 + 1]; - } - } - else - { - for(i = 0; i < numpixels; i++, buffer += num_channels) - { - buffer[0] = buffer[1] = buffer[2] = in[i * 4 + 0]; - if(has_alpha) buffer[3] = in[i * 4 + 2]; - } - } - } - else if(mode->colortype == LCT_RGBA) - { - if(mode->bitdepth == 8) - { - for(i = 0; i < numpixels; i++, buffer += num_channels) - { - buffer[0] = in[i * 4 + 0]; - buffer[1] = in[i * 4 + 1]; - buffer[2] = in[i * 4 + 2]; - if(has_alpha) buffer[3] = in[i * 4 + 3]; - } - } - else - { - for(i = 0; i < numpixels; i++, buffer += num_channels) - { - buffer[0] = in[i * 8 + 0]; - buffer[1] = in[i * 8 + 2]; - buffer[2] = in[i * 8 + 4]; - if(has_alpha) buffer[3] = in[i * 8 + 6]; - } - } - } + buffer[0] = buffer[1] = buffer[2] = 0; + if (has_alpha) buffer[3] = 255; + } + else + { + buffer[0] = mode->palette[index * 4 + 0]; + buffer[1] = mode->palette[index * 4 + 1]; + buffer[2] = mode->palette[index * 4 + 2]; + if (has_alpha) buffer[3] = mode->palette[index * 4 + 3]; + } + } + } + else if (mode->colortype == LCT_GREY_ALPHA) + { + if (mode->bitdepth == 8) + { + for (i = 0; i < numpixels; i++, buffer += num_channels) + { + buffer[0] = buffer[1] = buffer[2] = in[i * 2 + 0]; + if (has_alpha) buffer[3] = in[i * 2 + 1]; + } + } + else + { + for (i = 0; i < numpixels; i++, buffer += num_channels) + { + buffer[0] = buffer[1] = buffer[2] = in[i * 4 + 0]; + if (has_alpha) buffer[3] = in[i * 4 + 2]; + } + } + } + else if (mode->colortype == LCT_RGBA) + { + if (mode->bitdepth == 8) + { + for (i = 0; i < numpixels; i++, buffer += num_channels) + { + buffer[0] = in[i * 4 + 0]; + buffer[1] = in[i * 4 + 1]; + buffer[2] = in[i * 4 + 2]; + if (has_alpha) buffer[3] = in[i * 4 + 3]; + } + } + else + { + for (i = 0; i < numpixels; i++, buffer += num_channels) + { + buffer[0] = in[i * 8 + 0]; + buffer[1] = in[i * 8 + 2]; + buffer[2] = in[i * 8 + 4]; + if (has_alpha) buffer[3] = in[i * 8 + 6]; + } + } + } } /*Get RGBA16 color of pixel with index i (y * width + x) from the raw image with given color type, but the given color type must be 16-bit itself.*/ static void getPixelColorRGBA16(unsigned short* r, unsigned short* g, unsigned short* b, unsigned short* a, - const unsigned char* in, size_t i, const LodePNGColorMode* mode) + const unsigned char* in, size_t i, const LodePNGColorMode* mode) { - if(mode->colortype == LCT_GREY) - { - *r = *g = *b = 256 * in[i * 2 + 0] + in[i * 2 + 1]; - if(mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) *a = 0; - else *a = 65535; - } - else if(mode->colortype == LCT_RGB) - { - *r = 256 * in[i * 6 + 0] + in[i * 6 + 1]; - *g = 256 * in[i * 6 + 2] + in[i * 6 + 3]; - *b = 256 * in[i * 6 + 4] + in[i * 6 + 5]; - if(mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r - && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g - && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) *a = 0; - else *a = 65535; - } - else if(mode->colortype == LCT_GREY_ALPHA) - { - *r = *g = *b = 256 * in[i * 4 + 0] + in[i * 4 + 1]; - *a = 256 * in[i * 4 + 2] + in[i * 4 + 3]; - } - else if(mode->colortype == LCT_RGBA) - { - *r = 256 * in[i * 8 + 0] + in[i * 8 + 1]; - *g = 256 * in[i * 8 + 2] + in[i * 8 + 3]; - *b = 256 * in[i * 8 + 4] + in[i * 8 + 5]; - *a = 256 * in[i * 8 + 6] + in[i * 8 + 7]; - } + if (mode->colortype == LCT_GREY) + { + *r = *g = *b = 256 * in[i * 2 + 0] + in[i * 2 + 1]; + if (mode->key_defined && 256U * in[i * 2 + 0] + in[i * 2 + 1] == mode->key_r) + *a = 0; + else + *a = 65535; + } + else if (mode->colortype == LCT_RGB) + { + *r = 256 * in[i * 6 + 0] + in[i * 6 + 1]; + *g = 256 * in[i * 6 + 2] + in[i * 6 + 3]; + *b = 256 * in[i * 6 + 4] + in[i * 6 + 5]; + if (mode->key_defined && 256U * in[i * 6 + 0] + in[i * 6 + 1] == mode->key_r && 256U * in[i * 6 + 2] + in[i * 6 + 3] == mode->key_g && 256U * in[i * 6 + 4] + in[i * 6 + 5] == mode->key_b) + *a = 0; + else + *a = 65535; + } + else if (mode->colortype == LCT_GREY_ALPHA) + { + *r = *g = *b = 256 * in[i * 4 + 0] + in[i * 4 + 1]; + *a = 256 * in[i * 4 + 2] + in[i * 4 + 3]; + } + else if (mode->colortype == LCT_RGBA) + { + *r = 256 * in[i * 8 + 0] + in[i * 8 + 1]; + *g = 256 * in[i * 8 + 2] + in[i * 8 + 3]; + *b = 256 * in[i * 8 + 4] + in[i * 8 + 5]; + *a = 256 * in[i * 8 + 6] + in[i * 8 + 7]; + } } unsigned lodepng_convert(unsigned char* out, const unsigned char* in, - LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, - unsigned w, unsigned h) + LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, + unsigned w, unsigned h) { - size_t i; - ColorTree tree; - size_t numpixels = w * h; + size_t i; + ColorTree tree; + size_t numpixels = w * h; - if(lodepng_color_mode_equal(mode_out, mode_in)) - { - size_t numbytes = lodepng_get_raw_size(w, h, mode_in); - for(i = 0; i < numbytes; i++) out[i] = in[i]; - return 0; - } + if (lodepng_color_mode_equal(mode_out, mode_in)) + { + size_t numbytes = lodepng_get_raw_size(w, h, mode_in); + for (i = 0; i < numbytes; i++) out[i] = in[i]; + return 0; + } - if(mode_out->colortype == LCT_PALETTE) - { - size_t palsize = 1u << mode_out->bitdepth; - if(mode_out->palettesize < palsize) palsize = mode_out->palettesize; - color_tree_init(&tree); - for(i = 0; i < palsize; i++) - { - unsigned char* p = &mode_out->palette[i * 4]; - color_tree_add(&tree, p[0], p[1], p[2], p[3], i); - } - } + if (mode_out->colortype == LCT_PALETTE) + { + size_t palsize = 1u << mode_out->bitdepth; + if (mode_out->palettesize < palsize) palsize = mode_out->palettesize; + color_tree_init(&tree); + for (i = 0; i < palsize; i++) + { + unsigned char* p = &mode_out->palette[i * 4]; + color_tree_add(&tree, p[0], p[1], p[2], p[3], i); + } + } - if(mode_in->bitdepth == 16 && mode_out->bitdepth == 16) - { - for(i = 0; i < numpixels; i++) - { - unsigned short r = 0, g = 0, b = 0, a = 0; - getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in); - rgba16ToPixel(out, i, mode_out, r, g, b, a); - } - } - else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGBA) - { - getPixelColorsRGBA8(out, numpixels, 1, in, mode_in); - } - else if(mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGB) - { - getPixelColorsRGBA8(out, numpixels, 0, in, mode_in); - } - else - { - unsigned char r = 0, g = 0, b = 0, a = 0; - for(i = 0; i < numpixels; i++) - { - getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in); - rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a); - } - } + if (mode_in->bitdepth == 16 && mode_out->bitdepth == 16) + { + for (i = 0; i < numpixels; i++) + { + unsigned short r = 0, g = 0, b = 0, a = 0; + getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode_in); + rgba16ToPixel(out, i, mode_out, r, g, b, a); + } + } + else if (mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGBA) + { + getPixelColorsRGBA8(out, numpixels, 1, in, mode_in); + } + else if (mode_out->bitdepth == 8 && mode_out->colortype == LCT_RGB) + { + getPixelColorsRGBA8(out, numpixels, 0, in, mode_in); + } + else + { + unsigned char r = 0, g = 0, b = 0, a = 0; + for (i = 0; i < numpixels; i++) + { + getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode_in); + rgba8ToPixel(out, i, mode_out, &tree, r, g, b, a); + } + } - if(mode_out->colortype == LCT_PALETTE) - { - color_tree_cleanup(&tree); - } + if (mode_out->colortype == LCT_PALETTE) + { + color_tree_cleanup(&tree); + } - return 0; /*no error (this function currently never has one, but maybe OOM detection added later.)*/ + return 0; /*no error (this function currently never has one, but maybe OOM detection added later.)*/ } #ifdef LODEPNG_COMPILE_ENCODER void lodepng_color_profile_init(LodePNGColorProfile* profile) { - profile->colored = 0; - profile->key = 0; - profile->alpha = 0; - profile->key_r = profile->key_g = profile->key_b = 0; - profile->numcolors = 0; - profile->bits = 1; + profile->colored = 0; + profile->key = 0; + profile->alpha = 0; + profile->key_r = profile->key_g = profile->key_b = 0; + profile->numcolors = 0; + profile->bits = 1; } /*function used for debug purposes with C++*/ @@ -3496,169 +3583,169 @@ void lodepng_color_profile_init(LodePNGColorProfile* profile) /*Returns how many bits needed to represent given value (max 8 bit)*/ unsigned getValueRequiredBits(unsigned char value) { - if(value == 0 || value == 255) return 1; - /*The scaling of 2-bit and 4-bit values uses multiples of 85 and 17*/ - if(value % 17 == 0) return value % 85 == 0 ? 2 : 4; - return 8; + if (value == 0 || value == 255) return 1; + /*The scaling of 2-bit and 4-bit values uses multiples of 85 and 17*/ + if (value % 17 == 0) return value % 85 == 0 ? 2 : 4; + return 8; } /*profile must already have been inited with mode. It's ok to set some parameters of profile to done already.*/ unsigned get_color_profile(LodePNGColorProfile* profile, - const unsigned char* in, unsigned w, unsigned h, - const LodePNGColorMode* mode) + const unsigned char* in, unsigned w, unsigned h, + const LodePNGColorMode* mode) { - unsigned error = 0; - size_t i; - ColorTree tree; - size_t numpixels = w * h; + unsigned error = 0; + size_t i; + ColorTree tree; + size_t numpixels = w * h; - unsigned colored_done = lodepng_is_greyscale_type(mode) ? 1 : 0; - unsigned alpha_done = lodepng_can_have_alpha(mode) ? 0 : 1; - unsigned numcolors_done = 0; - unsigned bpp = lodepng_get_bpp(mode); - unsigned bits_done = bpp == 1 ? 1 : 0; - unsigned maxnumcolors = 257; - unsigned sixteen = 0; - if(bpp <= 8) maxnumcolors = bpp == 1 ? 2 : (bpp == 2 ? 4 : (bpp == 4 ? 16 : 256)); + unsigned colored_done = lodepng_is_greyscale_type(mode) ? 1 : 0; + unsigned alpha_done = lodepng_can_have_alpha(mode) ? 0 : 1; + unsigned numcolors_done = 0; + unsigned bpp = lodepng_get_bpp(mode); + unsigned bits_done = bpp == 1 ? 1 : 0; + unsigned maxnumcolors = 257; + unsigned sixteen = 0; + if (bpp <= 8) maxnumcolors = bpp == 1 ? 2 : (bpp == 2 ? 4 : (bpp == 4 ? 16 : 256)); - color_tree_init(&tree); + color_tree_init(&tree); - /*Check if the 16-bit input is truly 16-bit*/ - if(mode->bitdepth == 16) - { - unsigned short r, g, b, a; - for(i = 0; i < numpixels; i++) - { - getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode); - if(r % 257u != 0 || g % 257u != 0 || b % 257u != 0 || a % 257u != 0) /*first and second byte differ*/ - { - sixteen = 1; - break; - } - } - } + /*Check if the 16-bit input is truly 16-bit*/ + if (mode->bitdepth == 16) + { + unsigned short r, g, b, a; + for (i = 0; i < numpixels; i++) + { + getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode); + if (r % 257u != 0 || g % 257u != 0 || b % 257u != 0 || a % 257u != 0) /*first and second byte differ*/ + { + sixteen = 1; + break; + } + } + } - if(sixteen) - { - unsigned short r = 0, g = 0, b = 0, a = 0; - profile->bits = 16; - bits_done = numcolors_done = 1; /*counting colors no longer useful, palette doesn't support 16-bit*/ + if (sixteen) + { + unsigned short r = 0, g = 0, b = 0, a = 0; + profile->bits = 16; + bits_done = numcolors_done = 1; /*counting colors no longer useful, palette doesn't support 16-bit*/ - for(i = 0; i < numpixels; i++) - { - getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode); - - if(!colored_done && (r != g || r != b)) - { - profile->colored = 1; - colored_done = 1; - } + for (i = 0; i < numpixels; i++) + { + getPixelColorRGBA16(&r, &g, &b, &a, in, i, mode); - if(!alpha_done) - { - unsigned matchkey = (r == profile->key_r && g == profile->key_g && b == profile->key_b); - if(a != 65535 && (a != 0 || (profile->key && !matchkey))) - { - profile->alpha = 1; - alpha_done = 1; - if(profile->bits < 8) profile->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ - } - else if(a == 0 && !profile->alpha && !profile->key) - { - profile->key = 1; - profile->key_r = r; - profile->key_g = g; - profile->key_b = b; - } - else if(a == 65535 && profile->key && matchkey) - { - /* Color key cannot be used if an opaque pixel also has that RGB color. */ - profile->alpha = 1; - alpha_done = 1; - } - } + if (!colored_done && (r != g || r != b)) + { + profile->colored = 1; + colored_done = 1; + } - if(alpha_done && numcolors_done && colored_done && bits_done) break; - } - } - else /* < 16-bit */ - { - for(i = 0; i < numpixels; i++) - { - unsigned char r = 0, g = 0, b = 0, a = 0; - getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode); + if (!alpha_done) + { + unsigned matchkey = (r == profile->key_r && g == profile->key_g && b == profile->key_b); + if (a != 65535 && (a != 0 || (profile->key && !matchkey))) + { + profile->alpha = 1; + alpha_done = 1; + if (profile->bits < 8) profile->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ + } + else if (a == 0 && !profile->alpha && !profile->key) + { + profile->key = 1; + profile->key_r = r; + profile->key_g = g; + profile->key_b = b; + } + else if (a == 65535 && profile->key && matchkey) + { + /* Color key cannot be used if an opaque pixel also has that RGB color. */ + profile->alpha = 1; + alpha_done = 1; + } + } - if(!bits_done && profile->bits < 8) - { - /*only r is checked, < 8 bits is only relevant for greyscale*/ - unsigned bits = getValueRequiredBits(r); - if(bits > profile->bits) profile->bits = bits; - } - bits_done = (profile->bits >= bpp); + if (alpha_done && numcolors_done && colored_done && bits_done) break; + } + } + else /* < 16-bit */ + { + for (i = 0; i < numpixels; i++) + { + unsigned char r = 0, g = 0, b = 0, a = 0; + getPixelColorRGBA8(&r, &g, &b, &a, in, i, mode); - if(!colored_done && (r != g || r != b)) - { - profile->colored = 1; - colored_done = 1; - if(profile->bits < 8) profile->bits = 8; /*PNG has no colored modes with less than 8-bit per channel*/ - } + if (!bits_done && profile->bits < 8) + { + /*only r is checked, < 8 bits is only relevant for greyscale*/ + unsigned bits = getValueRequiredBits(r); + if (bits > profile->bits) profile->bits = bits; + } + bits_done = (profile->bits >= bpp); - if(!alpha_done) - { - unsigned matchkey = (r == profile->key_r && g == profile->key_g && b == profile->key_b); - if(a != 255 && (a != 0 || (profile->key && !matchkey))) - { - profile->alpha = 1; - alpha_done = 1; - if(profile->bits < 8) profile->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ - } - else if(a == 0 && !profile->alpha && !profile->key) - { - profile->key = 1; - profile->key_r = r; - profile->key_g = g; - profile->key_b = b; - } - else if(a == 255 && profile->key && matchkey) - { - /* Color key cannot be used if an opaque pixel also has that RGB color. */ - profile->alpha = 1; - alpha_done = 1; - if(profile->bits < 8) profile->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ - } - } + if (!colored_done && (r != g || r != b)) + { + profile->colored = 1; + colored_done = 1; + if (profile->bits < 8) profile->bits = 8; /*PNG has no colored modes with less than 8-bit per channel*/ + } - if(!numcolors_done) - { - if(!color_tree_has(&tree, r, g, b, a)) - { - color_tree_add(&tree, r, g, b, a, profile->numcolors); - if(profile->numcolors < 256) - { - unsigned char* p = profile->palette; - unsigned n = profile->numcolors; - p[n * 4 + 0] = r; - p[n * 4 + 1] = g; - p[n * 4 + 2] = b; - p[n * 4 + 3] = a; - } - profile->numcolors++; - numcolors_done = profile->numcolors >= maxnumcolors; - } - } + if (!alpha_done) + { + unsigned matchkey = (r == profile->key_r && g == profile->key_g && b == profile->key_b); + if (a != 255 && (a != 0 || (profile->key && !matchkey))) + { + profile->alpha = 1; + alpha_done = 1; + if (profile->bits < 8) profile->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ + } + else if (a == 0 && !profile->alpha && !profile->key) + { + profile->key = 1; + profile->key_r = r; + profile->key_g = g; + profile->key_b = b; + } + else if (a == 255 && profile->key && matchkey) + { + /* Color key cannot be used if an opaque pixel also has that RGB color. */ + profile->alpha = 1; + alpha_done = 1; + if (profile->bits < 8) profile->bits = 8; /*PNG has no alphachannel modes with less than 8-bit per channel*/ + } + } - if(alpha_done && numcolors_done && colored_done && bits_done) break; - } + if (!numcolors_done) + { + if (!color_tree_has(&tree, r, g, b, a)) + { + color_tree_add(&tree, r, g, b, a, profile->numcolors); + if (profile->numcolors < 256) + { + unsigned char* p = profile->palette; + unsigned n = profile->numcolors; + p[n * 4 + 0] = r; + p[n * 4 + 1] = g; + p[n * 4 + 2] = b; + p[n * 4 + 3] = a; + } + profile->numcolors++; + numcolors_done = profile->numcolors >= maxnumcolors; + } + } - /*make the profile's key always 16-bit for consistency - repeat each byte twice*/ - profile->key_r *= 257; - profile->key_g *= 257; - profile->key_b *= 257; - } + if (alpha_done && numcolors_done && colored_done && bits_done) break; + } - color_tree_cleanup(&tree); - return error; + /*make the profile's key always 16-bit for consistency - repeat each byte twice*/ + profile->key_r *= 257; + profile->key_g *= 257; + profile->key_b *= 257; + } + + color_tree_cleanup(&tree); + return error; } /*Automatically chooses color type that gives smallest amount of bits in the @@ -3667,64 +3754,63 @@ are less than 256 colors, ... Updates values of mode with a potentially smaller color model. mode_out should contain the user chosen color model, but will be overwritten with the new chosen one.*/ unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out, - const unsigned char* image, unsigned w, unsigned h, - const LodePNGColorMode* mode_in) + const unsigned char* image, unsigned w, unsigned h, + const LodePNGColorMode* mode_in) { - LodePNGColorProfile prof; - unsigned error = 0; - unsigned i, n, palettebits, grey_ok, palette_ok; + LodePNGColorProfile prof; + unsigned error = 0; + unsigned i, n, palettebits, grey_ok, palette_ok; - lodepng_color_profile_init(&prof); - error = get_color_profile(&prof, image, w, h, mode_in); - if(error) return error; - mode_out->key_defined = 0; + lodepng_color_profile_init(&prof); + error = get_color_profile(&prof, image, w, h, mode_in); + if (error) return error; + mode_out->key_defined = 0; - if(prof.key && w * h <= 16) prof.alpha = 1; /*too few pixels to justify tRNS chunk overhead*/ - grey_ok = !prof.colored && !prof.alpha; /*grey without alpha, with potentially low bits*/ - n = prof.numcolors; - palettebits = n <= 2 ? 1 : (n <= 4 ? 2 : (n <= 16 ? 4 : 8)); - palette_ok = n <= 256 && (n * 2 < w * h) && prof.bits <= 8; - if(w * h < n * 2) palette_ok = 0; /*don't add palette overhead if image has only a few pixels*/ - if(grey_ok && prof.bits <= palettebits) palette_ok = 0; /*grey is less overhead*/ + if (prof.key && w * h <= 16) prof.alpha = 1; /*too few pixels to justify tRNS chunk overhead*/ + grey_ok = !prof.colored && !prof.alpha; /*grey without alpha, with potentially low bits*/ + n = prof.numcolors; + palettebits = n <= 2 ? 1 : (n <= 4 ? 2 : (n <= 16 ? 4 : 8)); + palette_ok = n <= 256 && (n * 2 < w * h) && prof.bits <= 8; + if (w * h < n * 2) palette_ok = 0; /*don't add palette overhead if image has only a few pixels*/ + if (grey_ok && prof.bits <= palettebits) palette_ok = 0; /*grey is less overhead*/ - if(palette_ok) - { - unsigned char* p = prof.palette; - lodepng_palette_clear(mode_out); /*remove potential earlier palette*/ - for(i = 0; i < prof.numcolors; i++) - { - error = lodepng_palette_add(mode_out, p[i * 4 + 0], p[i * 4 + 1], p[i * 4 + 2], p[i * 4 + 3]); - if(error) break; - } + if (palette_ok) + { + unsigned char* p = prof.palette; + lodepng_palette_clear(mode_out); /*remove potential earlier palette*/ + for (i = 0; i < prof.numcolors; i++) + { + error = lodepng_palette_add(mode_out, p[i * 4 + 0], p[i * 4 + 1], p[i * 4 + 2], p[i * 4 + 3]); + if (error) break; + } - mode_out->colortype = LCT_PALETTE; - mode_out->bitdepth = palettebits; + mode_out->colortype = LCT_PALETTE; + mode_out->bitdepth = palettebits; - if(mode_in->colortype == LCT_PALETTE && mode_in->palettesize >= mode_out->palettesize - && mode_in->bitdepth == mode_out->bitdepth) - { - /*If input should have same palette colors, keep original to preserve its order and prevent conversion*/ - lodepng_color_mode_cleanup(mode_out); - lodepng_color_mode_copy(mode_out, mode_in); - } - } - else /*8-bit or 16-bit per channel*/ - { - mode_out->bitdepth = prof.bits; - mode_out->colortype = prof.alpha ? (prof.colored ? LCT_RGBA : LCT_GREY_ALPHA) - : (prof.colored ? LCT_RGB : LCT_GREY); + if (mode_in->colortype == LCT_PALETTE && mode_in->palettesize >= mode_out->palettesize && mode_in->bitdepth == mode_out->bitdepth) + { + /*If input should have same palette colors, keep original to preserve its order and prevent conversion*/ + lodepng_color_mode_cleanup(mode_out); + lodepng_color_mode_copy(mode_out, mode_in); + } + } + else /*8-bit or 16-bit per channel*/ + { + mode_out->bitdepth = prof.bits; + mode_out->colortype = prof.alpha ? (prof.colored ? LCT_RGBA : LCT_GREY_ALPHA) + : (prof.colored ? LCT_RGB : LCT_GREY); - if(prof.key && !prof.alpha) - { - unsigned mask = (1u << mode_out->bitdepth) - 1u; /*profile always uses 16-bit, mask converts it*/ - mode_out->key_r = prof.key_r & mask; - mode_out->key_g = prof.key_g & mask; - mode_out->key_b = prof.key_b & mask; - mode_out->key_defined = 1; - } - } + if (prof.key && !prof.alpha) + { + unsigned mask = (1u << mode_out->bitdepth) - 1u; /*profile always uses 16-bit, mask converts it*/ + mode_out->key_r = prof.key_r & mask; + mode_out->key_g = prof.key_g & mask; + mode_out->key_b = prof.key_b & mask; + mode_out->key_defined = 1; + } + } - return error; + return error; } #endif /* #ifdef LODEPNG_COMPILE_ENCODER */ @@ -3736,21 +3822,24 @@ are only needed to make the paeth calculation correct. */ static unsigned char paethPredictor(short a, short b, short c) { - short pa = abs(b - c); - short pb = abs(a - c); - short pc = abs(a + b - c - c); + short pa = abs(b - c); + short pb = abs(a - c); + short pc = abs(a + b - c - c); - if(pc < pa && pc < pb) return (unsigned char)c; - else if(pb < pa) return (unsigned char)b; - else return (unsigned char)a; + if (pc < pa && pc < pb) + return (unsigned char)c; + else if (pb < pa) + return (unsigned char)b; + else + return (unsigned char)a; } /*shared values used by multiple Adam7 related functions*/ -static const unsigned ADAM7_IX[7] = { 0, 4, 0, 2, 0, 1, 0 }; /*x start values*/ -static const unsigned ADAM7_IY[7] = { 0, 0, 4, 0, 2, 0, 1 }; /*y start values*/ -static const unsigned ADAM7_DX[7] = { 8, 8, 4, 4, 2, 2, 1 }; /*x delta values*/ -static const unsigned ADAM7_DY[7] = { 8, 8, 8, 4, 4, 2, 2 }; /*y delta values*/ +static const unsigned ADAM7_IX[7] = {0, 4, 0, 2, 0, 1, 0}; /*x start values*/ +static const unsigned ADAM7_IY[7] = {0, 0, 4, 0, 2, 0, 1}; /*y start values*/ +static const unsigned ADAM7_DX[7] = {8, 8, 4, 4, 2, 2, 1}; /*x delta values*/ +static const unsigned ADAM7_DY[7] = {8, 8, 8, 4, 4, 2, 2}; /*y delta values*/ /* Outputs various dimensions and positions in the image related to the Adam7 reduced images. @@ -3768,31 +3857,30 @@ bpp: bits per pixel end at a full byte */ static void Adam7_getpassvalues(unsigned passw[7], unsigned passh[7], size_t filter_passstart[8], - size_t padded_passstart[8], size_t passstart[8], unsigned w, unsigned h, unsigned bpp) + size_t padded_passstart[8], size_t passstart[8], unsigned w, unsigned h, unsigned bpp) { - /*the passstart values have 8 values: the 8th one indicates the byte after the end of the 7th (= last) pass*/ - unsigned i; + /*the passstart values have 8 values: the 8th one indicates the byte after the end of the 7th (= last) pass*/ + unsigned i; - /*calculate width and height in pixels of each pass*/ - for(i = 0; i < 7; i++) - { - passw[i] = (w + ADAM7_DX[i] - ADAM7_IX[i] - 1) / ADAM7_DX[i]; - passh[i] = (h + ADAM7_DY[i] - ADAM7_IY[i] - 1) / ADAM7_DY[i]; - if(passw[i] == 0) passh[i] = 0; - if(passh[i] == 0) passw[i] = 0; - } + /*calculate width and height in pixels of each pass*/ + for (i = 0; i < 7; i++) + { + passw[i] = (w + ADAM7_DX[i] - ADAM7_IX[i] - 1) / ADAM7_DX[i]; + passh[i] = (h + ADAM7_DY[i] - ADAM7_IY[i] - 1) / ADAM7_DY[i]; + if (passw[i] == 0) passh[i] = 0; + if (passh[i] == 0) passw[i] = 0; + } - filter_passstart[0] = padded_passstart[0] = passstart[0] = 0; - for(i = 0; i < 7; i++) - { - /*if passw[i] is 0, it's 0 bytes, not 1 (no filtertype-byte)*/ - filter_passstart[i + 1] = filter_passstart[i] - + ((passw[i] && passh[i]) ? passh[i] * (1 + (passw[i] * bpp + 7) / 8) : 0); - /*bits padded if needed to fill full byte at end of each scanline*/ - padded_passstart[i + 1] = padded_passstart[i] + passh[i] * ((passw[i] * bpp + 7) / 8); - /*only padded at end of reduced image*/ - passstart[i + 1] = passstart[i] + (passh[i] * passw[i] * bpp + 7) / 8; - } + filter_passstart[0] = padded_passstart[0] = passstart[0] = 0; + for (i = 0; i < 7; i++) + { + /*if passw[i] is 0, it's 0 bytes, not 1 (no filtertype-byte)*/ + filter_passstart[i + 1] = filter_passstart[i] + ((passw[i] && passh[i]) ? passh[i] * (1 + (passw[i] * bpp + 7) / 8) : 0); + /*bits padded if needed to fill full byte at end of each scanline*/ + padded_passstart[i + 1] = padded_passstart[i] + passh[i] * ((passw[i] * bpp + 7) / 8); + /*only padded at end of reduced image*/ + passstart[i + 1] = passstart[i] + (passh[i] * passw[i] * bpp + 7) / 8; + } } #ifdef LODEPNG_COMPILE_DECODER @@ -3803,66 +3891,65 @@ static void Adam7_getpassvalues(unsigned passw[7], unsigned passh[7], size_t fil /*read the information from the header and store it in the LodePNGInfo. return value is error*/ unsigned lodepng_inspect(unsigned* w, unsigned* h, LodePNGState* state, - const unsigned char* in, size_t insize) + const unsigned char* in, size_t insize) { - LodePNGInfo* info = &state->info_png; - if(insize == 0 || in == 0) - { - CERROR_RETURN_ERROR(state->error, 48); /*error: the given data is empty*/ - } - if(insize < 29) - { - CERROR_RETURN_ERROR(state->error, 27); /*error: the data length is smaller than the length of a PNG header*/ - } + LodePNGInfo* info = &state->info_png; + if (insize == 0 || in == 0) + { + CERROR_RETURN_ERROR(state->error, 48); /*error: the given data is empty*/ + } + if (insize < 29) + { + CERROR_RETURN_ERROR(state->error, 27); /*error: the data length is smaller than the length of a PNG header*/ + } - /*when decoding a new PNG image, make sure all parameters created after previous decoding are reset*/ - lodepng_info_cleanup(info); - lodepng_info_init(info); + /*when decoding a new PNG image, make sure all parameters created after previous decoding are reset*/ + lodepng_info_cleanup(info); + lodepng_info_init(info); - if(in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71 - || in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10) - { - CERROR_RETURN_ERROR(state->error, 28); /*error: the first 8 bytes are not the correct PNG signature*/ - } - if(in[12] != 'I' || in[13] != 'H' || in[14] != 'D' || in[15] != 'R') - { - CERROR_RETURN_ERROR(state->error, 29); /*error: it doesn't start with a IHDR chunk!*/ - } + if (in[0] != 137 || in[1] != 80 || in[2] != 78 || in[3] != 71 || in[4] != 13 || in[5] != 10 || in[6] != 26 || in[7] != 10) + { + CERROR_RETURN_ERROR(state->error, 28); /*error: the first 8 bytes are not the correct PNG signature*/ + } + if (in[12] != 'I' || in[13] != 'H' || in[14] != 'D' || in[15] != 'R') + { + CERROR_RETURN_ERROR(state->error, 29); /*error: it doesn't start with a IHDR chunk!*/ + } - /*read the values given in the header*/ - *w = lodepng_read32bitInt(&in[16]); - *h = lodepng_read32bitInt(&in[20]); - info->color.bitdepth = in[24]; - info->color.colortype = (LodePNGColorType)in[25]; - info->compression_method = in[26]; - info->filter_method = in[27]; - info->interlace_method = in[28]; + /*read the values given in the header*/ + *w = lodepng_read32bitInt(&in[16]); + *h = lodepng_read32bitInt(&in[20]); + info->color.bitdepth = in[24]; + info->color.colortype = (LodePNGColorType)in[25]; + info->compression_method = in[26]; + info->filter_method = in[27]; + info->interlace_method = in[28]; - if(!state->decoder.ignore_crc) - { - unsigned CRC = lodepng_read32bitInt(&in[29]); - unsigned checksum = lodepng_crc32(&in[12], 17); - if(CRC != checksum) - { - CERROR_RETURN_ERROR(state->error, 57); /*invalid CRC*/ - } - } + if (!state->decoder.ignore_crc) + { + unsigned CRC = lodepng_read32bitInt(&in[29]); + unsigned checksum = lodepng_crc32(&in[12], 17); + if (CRC != checksum) + { + CERROR_RETURN_ERROR(state->error, 57); /*invalid CRC*/ + } + } - /*error: only compression method 0 is allowed in the specification*/ - if(info->compression_method != 0) CERROR_RETURN_ERROR(state->error, 32); - /*error: only filter method 0 is allowed in the specification*/ - if(info->filter_method != 0) CERROR_RETURN_ERROR(state->error, 33); - /*error: only interlace methods 0 and 1 exist in the specification*/ - if(info->interlace_method > 1) CERROR_RETURN_ERROR(state->error, 34); + /*error: only compression method 0 is allowed in the specification*/ + if (info->compression_method != 0) CERROR_RETURN_ERROR(state->error, 32); + /*error: only filter method 0 is allowed in the specification*/ + if (info->filter_method != 0) CERROR_RETURN_ERROR(state->error, 33); + /*error: only interlace methods 0 and 1 exist in the specification*/ + if (info->interlace_method > 1) CERROR_RETURN_ERROR(state->error, 34); - state->error = checkColorValidity(info->color.colortype, info->color.bitdepth); - return state->error; + state->error = checkColorValidity(info->color.colortype, info->color.bitdepth); + return state->error; } static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scanline, const unsigned char* precon, - size_t bytewidth, unsigned char filterType, size_t length) + size_t bytewidth, unsigned char filterType, size_t length) { - /* + /* For PNG filter method 0 unfilter a PNG image scanline by scanline. when the pixels are smaller than 1 byte, the filter works byte per byte (bytewidth = 1) @@ -3871,71 +3958,72 @@ static unsigned unfilterScanline(unsigned char* recon, const unsigned char* scan recon and scanline MAY be the same memory address! precon must be disjoint. */ - size_t i; - switch(filterType) - { - case 0: - for(i = 0; i < length; i++) recon[i] = scanline[i]; - break; - case 1: - for(i = 0; i < bytewidth; i++) recon[i] = scanline[i]; - for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + recon[i - bytewidth]; - break; - case 2: - if(precon) - { - for(i = 0; i < length; i++) recon[i] = scanline[i] + precon[i]; - } - else - { - for(i = 0; i < length; i++) recon[i] = scanline[i]; - } - break; - case 3: - if(precon) - { - for(i = 0; i < bytewidth; i++) recon[i] = scanline[i] + precon[i] / 2; - for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) / 2); - } - else - { - for(i = 0; i < bytewidth; i++) recon[i] = scanline[i]; - for(i = bytewidth; i < length; i++) recon[i] = scanline[i] + recon[i - bytewidth] / 2; - } - break; - case 4: - if(precon) - { - for(i = 0; i < bytewidth; i++) - { - recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/ - } - for(i = bytewidth; i < length; i++) - { - recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth])); - } - } - else - { - for(i = 0; i < bytewidth; i++) - { - recon[i] = scanline[i]; - } - for(i = bytewidth; i < length; i++) - { - /*paethPredictor(recon[i - bytewidth], 0, 0) is always recon[i - bytewidth]*/ - recon[i] = (scanline[i] + recon[i - bytewidth]); - } - } - break; - default: return 36; /*error: unexisting filter type given*/ - } - return 0; + size_t i; + switch (filterType) + { + case 0: + for (i = 0; i < length; i++) recon[i] = scanline[i]; + break; + case 1: + for (i = 0; i < bytewidth; i++) recon[i] = scanline[i]; + for (i = bytewidth; i < length; i++) recon[i] = scanline[i] + recon[i - bytewidth]; + break; + case 2: + if (precon) + { + for (i = 0; i < length; i++) recon[i] = scanline[i] + precon[i]; + } + else + { + for (i = 0; i < length; i++) recon[i] = scanline[i]; + } + break; + case 3: + if (precon) + { + for (i = 0; i < bytewidth; i++) recon[i] = scanline[i] + precon[i] / 2; + for (i = bytewidth; i < length; i++) recon[i] = scanline[i] + ((recon[i - bytewidth] + precon[i]) / 2); + } + else + { + for (i = 0; i < bytewidth; i++) recon[i] = scanline[i]; + for (i = bytewidth; i < length; i++) recon[i] = scanline[i] + recon[i - bytewidth] / 2; + } + break; + case 4: + if (precon) + { + for (i = 0; i < bytewidth; i++) + { + recon[i] = (scanline[i] + precon[i]); /*paethPredictor(0, precon[i], 0) is always precon[i]*/ + } + for (i = bytewidth; i < length; i++) + { + recon[i] = (scanline[i] + paethPredictor(recon[i - bytewidth], precon[i], precon[i - bytewidth])); + } + } + else + { + for (i = 0; i < bytewidth; i++) + { + recon[i] = scanline[i]; + } + for (i = bytewidth; i < length; i++) + { + /*paethPredictor(recon[i - bytewidth], 0, 0) is always recon[i - bytewidth]*/ + recon[i] = (scanline[i] + recon[i - bytewidth]); + } + } + break; + default: + return 36; /*error: unexisting filter type given*/ + } + return 0; } static unsigned unfilter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) { - /* + /* For PNG filter method 0 this function unfilters a single image (e.g. without interlacing this is called once, with Adam7 seven times) out must have enough bytes allocated already, in must have the scanlines + 1 filtertype byte per scanline @@ -3943,25 +4031,25 @@ static unsigned unfilter(unsigned char* out, const unsigned char* in, unsigned w in and out are allowed to be the same memory address (but aren't the same size since in has the extra filter bytes) */ - unsigned y; - unsigned char* prevline = 0; + unsigned y; + unsigned char* prevline = 0; - /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/ - size_t bytewidth = (bpp + 7) / 8; - size_t linebytes = (w * bpp + 7) / 8; + /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/ + size_t bytewidth = (bpp + 7) / 8; + size_t linebytes = (w * bpp + 7) / 8; - for(y = 0; y < h; y++) - { - size_t outindex = linebytes * y; - size_t inindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ - unsigned char filterType = in[inindex]; + for (y = 0; y < h; y++) + { + size_t outindex = linebytes * y; + size_t inindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ + unsigned char filterType = in[inindex]; - CERROR_TRY_RETURN(unfilterScanline(&out[outindex], &in[inindex + 1], prevline, bytewidth, filterType, linebytes)); + CERROR_TRY_RETURN(unfilterScanline(&out[outindex], &in[inindex + 1], prevline, bytewidth, filterType, linebytes)); - prevline = &out[outindex]; - } + prevline = &out[outindex]; + } - return 0; + return 0; } /* @@ -3977,58 +4065,58 @@ NOTE: comments about padding bits are only relevant if bpp < 8 */ static void Adam7_deinterlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) { - unsigned passw[7], passh[7]; - size_t filter_passstart[8], padded_passstart[8], passstart[8]; - unsigned i; + unsigned passw[7], passh[7]; + size_t filter_passstart[8], padded_passstart[8], passstart[8]; + unsigned i; - Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); + Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); - if(bpp >= 8) - { - for(i = 0; i < 7; i++) - { - unsigned x, y, b; - size_t bytewidth = bpp / 8; - for(y = 0; y < passh[i]; y++) - for(x = 0; x < passw[i]; x++) - { - size_t pixelinstart = passstart[i] + (y * passw[i] + x) * bytewidth; - size_t pixeloutstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth; - for(b = 0; b < bytewidth; b++) - { - out[pixeloutstart + b] = in[pixelinstart + b]; - } - } - } - } - else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ - { - for(i = 0; i < 7; i++) - { - unsigned x, y, b; - unsigned ilinebits = bpp * passw[i]; - unsigned olinebits = bpp * w; - size_t obp, ibp; /*bit pointers (for out and in buffer)*/ - for(y = 0; y < passh[i]; y++) - for(x = 0; x < passw[i]; x++) - { - ibp = (8 * passstart[i]) + (y * ilinebits + x * bpp); - obp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp; - for(b = 0; b < bpp; b++) - { - unsigned char bit = readBitFromReversedStream(&ibp, in); - /*note that this function assumes the out buffer is completely 0, use setBitOfReversedStream otherwise*/ - setBitOfReversedStream0(&obp, out, bit); - } - } - } - } + if (bpp >= 8) + { + for (i = 0; i < 7; i++) + { + unsigned x, y, b; + size_t bytewidth = bpp / 8; + for (y = 0; y < passh[i]; y++) + for (x = 0; x < passw[i]; x++) + { + size_t pixelinstart = passstart[i] + (y * passw[i] + x) * bytewidth; + size_t pixeloutstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth; + for (b = 0; b < bytewidth; b++) + { + out[pixeloutstart + b] = in[pixelinstart + b]; + } + } + } + } + else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ + { + for (i = 0; i < 7; i++) + { + unsigned x, y, b; + unsigned ilinebits = bpp * passw[i]; + unsigned olinebits = bpp * w; + size_t obp, ibp; /*bit pointers (for out and in buffer)*/ + for (y = 0; y < passh[i]; y++) + for (x = 0; x < passw[i]; x++) + { + ibp = (8 * passstart[i]) + (y * ilinebits + x * bpp); + obp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp; + for (b = 0; b < bpp; b++) + { + unsigned char bit = readBitFromReversedStream(&ibp, in); + /*note that this function assumes the out buffer is completely 0, use setBitOfReversedStream otherwise*/ + setBitOfReversedStream0(&obp, out, bit); + } + } + } + } } static void removePaddingBits(unsigned char* out, const unsigned char* in, - size_t olinebits, size_t ilinebits, unsigned h) + size_t olinebits, size_t ilinebits, unsigned h) { - /* + /* After filtering there are still padding bits if scanlines have non multiple of 8 bit amounts. They need to be removed (except at last scanline of (Adam7-reduced) image) before working with pure image buffers for the Adam7 code, the color convert code and the output to the user. @@ -4037,653 +4125,657 @@ static void removePaddingBits(unsigned char* out, const unsigned char* in, also used to move bits after earlier such operations happened, e.g. in a sequence of reduced images from Adam7 only useful if (ilinebits - olinebits) is a value in the range 1..7 */ - unsigned y; - size_t diff = ilinebits - olinebits; - size_t ibp = 0, obp = 0; /*input and output bit pointers*/ - for(y = 0; y < h; y++) - { - size_t x; - for(x = 0; x < olinebits; x++) - { - unsigned char bit = readBitFromReversedStream(&ibp, in); - setBitOfReversedStream(&obp, out, bit); - } - ibp += diff; - } + unsigned y; + size_t diff = ilinebits - olinebits; + size_t ibp = 0, obp = 0; /*input and output bit pointers*/ + for (y = 0; y < h; y++) + { + size_t x; + for (x = 0; x < olinebits; x++) + { + unsigned char bit = readBitFromReversedStream(&ibp, in); + setBitOfReversedStream(&obp, out, bit); + } + ibp += diff; + } } /*out must be buffer big enough to contain full image, and in must contain the full decompressed data from the IDAT chunks (with filter index bytes and possible padding bits) return value is error*/ static unsigned postProcessScanlines(unsigned char* out, unsigned char* in, - unsigned w, unsigned h, const LodePNGInfo* info_png) + unsigned w, unsigned h, const LodePNGInfo* info_png) { - /* + /* This function converts the filtered-padded-interlaced data into pure 2D image buffer with the PNG's colortype. Steps: *) if no Adam7: 1) unfilter 2) remove padding bits (= posible extra bits per scanline if bpp < 8) *) if adam7: 1) 7x unfilter 2) 7x remove padding bits 3) Adam7_deinterlace NOTE: the in buffer will be overwritten with intermediate data! */ - unsigned bpp = lodepng_get_bpp(&info_png->color); - if(bpp == 0) return 31; /*error: invalid colortype*/ + unsigned bpp = lodepng_get_bpp(&info_png->color); + if (bpp == 0) return 31; /*error: invalid colortype*/ - if(info_png->interlace_method == 0) - { - if(bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8) - { - CERROR_TRY_RETURN(unfilter(in, in, w, h, bpp)); - removePaddingBits(out, in, w * bpp, ((w * bpp + 7) / 8) * 8, h); - } - /*we can immediatly filter into the out buffer, no other steps needed*/ - else CERROR_TRY_RETURN(unfilter(out, in, w, h, bpp)); - } - else /*interlace_method is 1 (Adam7)*/ - { - unsigned passw[7], passh[7]; size_t filter_passstart[8], padded_passstart[8], passstart[8]; - unsigned i; + if (info_png->interlace_method == 0) + { + if (bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8) + { + CERROR_TRY_RETURN(unfilter(in, in, w, h, bpp)); + removePaddingBits(out, in, w * bpp, ((w * bpp + 7) / 8) * 8, h); + } + /*we can immediatly filter into the out buffer, no other steps needed*/ + else + CERROR_TRY_RETURN(unfilter(out, in, w, h, bpp)); + } + else /*interlace_method is 1 (Adam7)*/ + { + unsigned passw[7], passh[7]; + size_t filter_passstart[8], padded_passstart[8], passstart[8]; + unsigned i; - Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); + Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); - for(i = 0; i < 7; i++) - { - CERROR_TRY_RETURN(unfilter(&in[padded_passstart[i]], &in[filter_passstart[i]], passw[i], passh[i], bpp)); - /*TODO: possible efficiency improvement: if in this reduced image the bits fit nicely in 1 scanline, + for (i = 0; i < 7; i++) + { + CERROR_TRY_RETURN(unfilter(&in[padded_passstart[i]], &in[filter_passstart[i]], passw[i], passh[i], bpp)); + /*TODO: possible efficiency improvement: if in this reduced image the bits fit nicely in 1 scanline, move bytes instead of bits or move not at all*/ - if(bpp < 8) - { - /*remove padding bits in scanlines; after this there still may be padding + if (bpp < 8) + { + /*remove padding bits in scanlines; after this there still may be padding bits between the different reduced images: each reduced image still starts nicely at a byte*/ - removePaddingBits(&in[passstart[i]], &in[padded_passstart[i]], passw[i] * bpp, - ((passw[i] * bpp + 7) / 8) * 8, passh[i]); - } - } + removePaddingBits(&in[passstart[i]], &in[padded_passstart[i]], passw[i] * bpp, + ((passw[i] * bpp + 7) / 8) * 8, passh[i]); + } + } - Adam7_deinterlace(out, in, w, h, bpp); - } + Adam7_deinterlace(out, in, w, h, bpp); + } - return 0; + return 0; } static unsigned readChunk_PLTE(LodePNGColorMode* color, const unsigned char* data, size_t chunkLength) { - unsigned pos = 0, i; - if(color->palette) lodepng_free(color->palette); - color->palettesize = chunkLength / 3; - color->palette = (unsigned char*)lodepng_malloc(4 * color->palettesize); - if(!color->palette && color->palettesize) - { - color->palettesize = 0; - return 83; /*alloc fail*/ - } - if(color->palettesize > 256) return 38; /*error: palette too big*/ + unsigned pos = 0, i; + if (color->palette) lodepng_free(color->palette); + color->palettesize = chunkLength / 3; + color->palette = (unsigned char*)lodepng_malloc(4 * color->palettesize); + if (!color->palette && color->palettesize) + { + color->palettesize = 0; + return 83; /*alloc fail*/ + } + if (color->palettesize > 256) return 38; /*error: palette too big*/ - for(i = 0; i < color->palettesize; i++) - { - color->palette[4 * i + 0] = data[pos++]; /*R*/ - color->palette[4 * i + 1] = data[pos++]; /*G*/ - color->palette[4 * i + 2] = data[pos++]; /*B*/ - color->palette[4 * i + 3] = 255; /*alpha*/ - } + for (i = 0; i < color->palettesize; i++) + { + color->palette[4 * i + 0] = data[pos++]; /*R*/ + color->palette[4 * i + 1] = data[pos++]; /*G*/ + color->palette[4 * i + 2] = data[pos++]; /*B*/ + color->palette[4 * i + 3] = 255; /*alpha*/ + } - return 0; /* OK */ + return 0; /* OK */ } static unsigned readChunk_tRNS(LodePNGColorMode* color, const unsigned char* data, size_t chunkLength) { - unsigned i; - if(color->colortype == LCT_PALETTE) - { - /*error: more alpha values given than there are palette entries*/ - if(chunkLength > color->palettesize) return 38; + unsigned i; + if (color->colortype == LCT_PALETTE) + { + /*error: more alpha values given than there are palette entries*/ + if (chunkLength > color->palettesize) return 38; - for(i = 0; i < chunkLength; i++) color->palette[4 * i + 3] = data[i]; - } - else if(color->colortype == LCT_GREY) - { - /*error: this chunk must be 2 bytes for greyscale image*/ - if(chunkLength != 2) return 30; + for (i = 0; i < chunkLength; i++) color->palette[4 * i + 3] = data[i]; + } + else if (color->colortype == LCT_GREY) + { + /*error: this chunk must be 2 bytes for greyscale image*/ + if (chunkLength != 2) return 30; - color->key_defined = 1; - color->key_r = color->key_g = color->key_b = 256u * data[0] + data[1]; - } - else if(color->colortype == LCT_RGB) - { - /*error: this chunk must be 6 bytes for RGB image*/ - if(chunkLength != 6) return 41; + color->key_defined = 1; + color->key_r = color->key_g = color->key_b = 256u * data[0] + data[1]; + } + else if (color->colortype == LCT_RGB) + { + /*error: this chunk must be 6 bytes for RGB image*/ + if (chunkLength != 6) return 41; - color->key_defined = 1; - color->key_r = 256u * data[0] + data[1]; - color->key_g = 256u * data[2] + data[3]; - color->key_b = 256u * data[4] + data[5]; - } - else return 42; /*error: tRNS chunk not allowed for other color models*/ + color->key_defined = 1; + color->key_r = 256u * data[0] + data[1]; + color->key_g = 256u * data[2] + data[3]; + color->key_b = 256u * data[4] + data[5]; + } + else + return 42; /*error: tRNS chunk not allowed for other color models*/ - return 0; /* OK */ + return 0; /* OK */ } - #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS /*background color chunk (bKGD)*/ static unsigned readChunk_bKGD(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { - if(info->color.colortype == LCT_PALETTE) - { - /*error: this chunk must be 1 byte for indexed color image*/ - if(chunkLength != 1) return 43; + if (info->color.colortype == LCT_PALETTE) + { + /*error: this chunk must be 1 byte for indexed color image*/ + if (chunkLength != 1) return 43; - info->background_defined = 1; - info->background_r = info->background_g = info->background_b = data[0]; - } - else if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) - { - /*error: this chunk must be 2 bytes for greyscale image*/ - if(chunkLength != 2) return 44; + info->background_defined = 1; + info->background_r = info->background_g = info->background_b = data[0]; + } + else if (info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) + { + /*error: this chunk must be 2 bytes for greyscale image*/ + if (chunkLength != 2) return 44; - info->background_defined = 1; - info->background_r = info->background_g = info->background_b = 256u * data[0] + data[1]; - } - else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) - { - /*error: this chunk must be 6 bytes for greyscale image*/ - if(chunkLength != 6) return 45; + info->background_defined = 1; + info->background_r = info->background_g = info->background_b = 256u * data[0] + data[1]; + } + else if (info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) + { + /*error: this chunk must be 6 bytes for greyscale image*/ + if (chunkLength != 6) return 45; - info->background_defined = 1; - info->background_r = 256u * data[0] + data[1]; - info->background_g = 256u * data[2] + data[3]; - info->background_b = 256u * data[4] + data[5]; - } + info->background_defined = 1; + info->background_r = 256u * data[0] + data[1]; + info->background_g = 256u * data[2] + data[3]; + info->background_b = 256u * data[4] + data[5]; + } - return 0; /* OK */ + return 0; /* OK */ } /*text chunk (tEXt)*/ static unsigned readChunk_tEXt(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { - unsigned error = 0; - char *key = 0, *str = 0; - unsigned i; + unsigned error = 0; + char *key = 0, *str = 0; + unsigned i; - while(!error) /*not really a while loop, only used to break on error*/ - { - unsigned length, string2_begin; + while (!error) /*not really a while loop, only used to break on error*/ + { + unsigned length, string2_begin; - length = 0; - while(length < chunkLength && data[length] != 0) length++; - /*even though it's not allowed by the standard, no error is thrown if + length = 0; + while (length < chunkLength && data[length] != 0) length++; + /*even though it's not allowed by the standard, no error is thrown if there's no null termination char, if the text is empty*/ - if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ + if (length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ - key = (char*)lodepng_malloc(length + 1); - if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ + key = (char*)lodepng_malloc(length + 1); + if (!key) CERROR_BREAK(error, 83); /*alloc fail*/ - key[length] = 0; - for(i = 0; i < length; i++) key[i] = (char)data[i]; + key[length] = 0; + for (i = 0; i < length; i++) key[i] = (char)data[i]; - string2_begin = length + 1; /*skip keyword null terminator*/ + string2_begin = length + 1; /*skip keyword null terminator*/ - length = chunkLength < string2_begin ? 0 : chunkLength - string2_begin; - str = (char*)lodepng_malloc(length + 1); - if(!str) CERROR_BREAK(error, 83); /*alloc fail*/ + length = chunkLength < string2_begin ? 0 : chunkLength - string2_begin; + str = (char*)lodepng_malloc(length + 1); + if (!str) CERROR_BREAK(error, 83); /*alloc fail*/ - str[length] = 0; - for(i = 0; i < length; i++) str[i] = (char)data[string2_begin + i]; + str[length] = 0; + for (i = 0; i < length; i++) str[i] = (char)data[string2_begin + i]; - error = lodepng_add_text(info, key, str); + error = lodepng_add_text(info, key, str); - break; - } + break; + } - lodepng_free(key); - lodepng_free(str); + lodepng_free(key); + lodepng_free(str); - return error; + return error; } /*compressed text chunk (zTXt)*/ static unsigned readChunk_zTXt(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings, - const unsigned char* data, size_t chunkLength) + const unsigned char* data, size_t chunkLength) { - unsigned error = 0; - unsigned i; + unsigned error = 0; + unsigned i; - unsigned length, string2_begin; - char *key = 0; - ucvector decoded; + unsigned length, string2_begin; + char* key = 0; + ucvector decoded; - ucvector_init(&decoded); + ucvector_init(&decoded); - while(!error) /*not really a while loop, only used to break on error*/ - { - for(length = 0; length < chunkLength && data[length] != 0; length++) ; - if(length + 2 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/ - if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ + while (!error) /*not really a while loop, only used to break on error*/ + { + for (length = 0; length < chunkLength && data[length] != 0; length++) + ; + if (length + 2 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/ + if (length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ - key = (char*)lodepng_malloc(length + 1); - if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ + key = (char*)lodepng_malloc(length + 1); + if (!key) CERROR_BREAK(error, 83); /*alloc fail*/ - key[length] = 0; - for(i = 0; i < length; i++) key[i] = (char)data[i]; + key[length] = 0; + for (i = 0; i < length; i++) key[i] = (char)data[i]; - if(data[length + 1] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/ + if (data[length + 1] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/ - string2_begin = length + 2; - if(string2_begin > chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/ + string2_begin = length + 2; + if (string2_begin > chunkLength) CERROR_BREAK(error, 75); /*no null termination, corrupt?*/ - length = chunkLength - string2_begin; - /*will fail if zlib error, e.g. if length is too small*/ - error = zlib_decompress(&decoded.data, &decoded.size, - (unsigned char*)(&data[string2_begin]), - length, zlibsettings); - if(error) break; - ucvector_push_back(&decoded, 0); + length = chunkLength - string2_begin; + /*will fail if zlib error, e.g. if length is too small*/ + error = zlib_decompress(&decoded.data, &decoded.size, + (unsigned char*)(&data[string2_begin]), + length, zlibsettings); + if (error) break; + ucvector_push_back(&decoded, 0); - error = lodepng_add_text(info, key, (char*)decoded.data); + error = lodepng_add_text(info, key, (char*)decoded.data); - break; - } + break; + } - lodepng_free(key); - ucvector_cleanup(&decoded); + lodepng_free(key); + ucvector_cleanup(&decoded); - return error; + return error; } /*international text chunk (iTXt)*/ static unsigned readChunk_iTXt(LodePNGInfo* info, const LodePNGDecompressSettings* zlibsettings, - const unsigned char* data, size_t chunkLength) + const unsigned char* data, size_t chunkLength) { - unsigned error = 0; - unsigned i; + unsigned error = 0; + unsigned i; - unsigned length, begin, compressed; - char *key = 0, *langtag = 0, *transkey = 0; - ucvector decoded; - ucvector_init(&decoded); + unsigned length, begin, compressed; + char *key = 0, *langtag = 0, *transkey = 0; + ucvector decoded; + ucvector_init(&decoded); - while(!error) /*not really a while loop, only used to break on error*/ - { - /*Quick check if the chunk length isn't too small. Even without check + while (!error) /*not really a while loop, only used to break on error*/ + { + /*Quick check if the chunk length isn't too small. Even without check it'd still fail with other error checks below if it's too short. This just gives a different error code.*/ - if(chunkLength < 5) CERROR_BREAK(error, 30); /*iTXt chunk too short*/ + if (chunkLength < 5) CERROR_BREAK(error, 30); /*iTXt chunk too short*/ - /*read the key*/ - for(length = 0; length < chunkLength && data[length] != 0; length++) ; - if(length + 3 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination char, corrupt?*/ - if(length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ + /*read the key*/ + for (length = 0; length < chunkLength && data[length] != 0; length++) + ; + if (length + 3 >= chunkLength) CERROR_BREAK(error, 75); /*no null termination char, corrupt?*/ + if (length < 1 || length > 79) CERROR_BREAK(error, 89); /*keyword too short or long*/ - key = (char*)lodepng_malloc(length + 1); - if(!key) CERROR_BREAK(error, 83); /*alloc fail*/ + key = (char*)lodepng_malloc(length + 1); + if (!key) CERROR_BREAK(error, 83); /*alloc fail*/ - key[length] = 0; - for(i = 0; i < length; i++) key[i] = (char)data[i]; + key[length] = 0; + for (i = 0; i < length; i++) key[i] = (char)data[i]; - /*read the compression method*/ - compressed = data[length + 1]; - if(data[length + 2] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/ + /*read the compression method*/ + compressed = data[length + 1]; + if (data[length + 2] != 0) CERROR_BREAK(error, 72); /*the 0 byte indicating compression must be 0*/ - /*even though it's not allowed by the standard, no error is thrown if + /*even though it's not allowed by the standard, no error is thrown if there's no null termination char, if the text is empty for the next 3 texts*/ - /*read the langtag*/ - begin = length + 3; - length = 0; - for(i = begin; i < chunkLength && data[i] != 0; i++) length++; + /*read the langtag*/ + begin = length + 3; + length = 0; + for (i = begin; i < chunkLength && data[i] != 0; i++) length++; - langtag = (char*)lodepng_malloc(length + 1); - if(!langtag) CERROR_BREAK(error, 83); /*alloc fail*/ + langtag = (char*)lodepng_malloc(length + 1); + if (!langtag) CERROR_BREAK(error, 83); /*alloc fail*/ - langtag[length] = 0; - for(i = 0; i < length; i++) langtag[i] = (char)data[begin + i]; + langtag[length] = 0; + for (i = 0; i < length; i++) langtag[i] = (char)data[begin + i]; - /*read the transkey*/ - begin += length + 1; - length = 0; - for(i = begin; i < chunkLength && data[i] != 0; i++) length++; + /*read the transkey*/ + begin += length + 1; + length = 0; + for (i = begin; i < chunkLength && data[i] != 0; i++) length++; - transkey = (char*)lodepng_malloc(length + 1); - if(!transkey) CERROR_BREAK(error, 83); /*alloc fail*/ + transkey = (char*)lodepng_malloc(length + 1); + if (!transkey) CERROR_BREAK(error, 83); /*alloc fail*/ - transkey[length] = 0; - for(i = 0; i < length; i++) transkey[i] = (char)data[begin + i]; + transkey[length] = 0; + for (i = 0; i < length; i++) transkey[i] = (char)data[begin + i]; - /*read the actual text*/ - begin += length + 1; + /*read the actual text*/ + begin += length + 1; - length = chunkLength < begin ? 0 : chunkLength - begin; + length = chunkLength < begin ? 0 : chunkLength - begin; - if(compressed) - { - /*will fail if zlib error, e.g. if length is too small*/ - error = zlib_decompress(&decoded.data, &decoded.size, - (unsigned char*)(&data[begin]), - length, zlibsettings); - if(error) break; - if(decoded.allocsize < decoded.size) decoded.allocsize = decoded.size; - ucvector_push_back(&decoded, 0); - } - else - { - if(!ucvector_resize(&decoded, length + 1)) CERROR_BREAK(error, 83 /*alloc fail*/); + if (compressed) + { + /*will fail if zlib error, e.g. if length is too small*/ + error = zlib_decompress(&decoded.data, &decoded.size, + (unsigned char*)(&data[begin]), + length, zlibsettings); + if (error) break; + if (decoded.allocsize < decoded.size) decoded.allocsize = decoded.size; + ucvector_push_back(&decoded, 0); + } + else + { + if (!ucvector_resize(&decoded, length + 1)) CERROR_BREAK(error, 83 /*alloc fail*/); - decoded.data[length] = 0; - for(i = 0; i < length; i++) decoded.data[i] = data[begin + i]; - } + decoded.data[length] = 0; + for (i = 0; i < length; i++) decoded.data[i] = data[begin + i]; + } - error = lodepng_add_itext(info, key, langtag, transkey, (char*)decoded.data); + error = lodepng_add_itext(info, key, langtag, transkey, (char*)decoded.data); - break; - } + break; + } - lodepng_free(key); - lodepng_free(langtag); - lodepng_free(transkey); - ucvector_cleanup(&decoded); + lodepng_free(key); + lodepng_free(langtag); + lodepng_free(transkey); + ucvector_cleanup(&decoded); - return error; + return error; } static unsigned readChunk_tIME(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { - if(chunkLength != 7) return 73; /*invalid tIME chunk size*/ + if (chunkLength != 7) return 73; /*invalid tIME chunk size*/ - info->time_defined = 1; - info->time.year = 256u * data[0] + data[1]; - info->time.month = data[2]; - info->time.day = data[3]; - info->time.hour = data[4]; - info->time.minute = data[5]; - info->time.second = data[6]; + info->time_defined = 1; + info->time.year = 256u * data[0] + data[1]; + info->time.month = data[2]; + info->time.day = data[3]; + info->time.hour = data[4]; + info->time.minute = data[5]; + info->time.second = data[6]; - return 0; /* OK */ + return 0; /* OK */ } static unsigned readChunk_pHYs(LodePNGInfo* info, const unsigned char* data, size_t chunkLength) { - if(chunkLength != 9) return 74; /*invalid pHYs chunk size*/ + if (chunkLength != 9) return 74; /*invalid pHYs chunk size*/ - info->phys_defined = 1; - info->phys_x = 16777216u * data[0] + 65536u * data[1] + 256u * data[2] + data[3]; - info->phys_y = 16777216u * data[4] + 65536u * data[5] + 256u * data[6] + data[7]; - info->phys_unit = data[8]; + info->phys_defined = 1; + info->phys_x = 16777216u * data[0] + 65536u * data[1] + 256u * data[2] + data[3]; + info->phys_y = 16777216u * data[4] + 65536u * data[5] + 256u * data[6] + data[7]; + info->phys_unit = data[8]; - return 0; /* OK */ + return 0; /* OK */ } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ /*read a PNG, the result will be in the same color type as the PNG (hence "generic")*/ static void decodeGeneric(unsigned char** out, unsigned* w, unsigned* h, - LodePNGState* state, - const unsigned char* in, size_t insize) + LodePNGState* state, + const unsigned char* in, size_t insize) { - unsigned char IEND = 0; - const unsigned char* chunk; - size_t i; - ucvector idat; /*the data from idat chunks*/ - ucvector scanlines; - size_t predict; + unsigned char IEND = 0; + const unsigned char* chunk; + size_t i; + ucvector idat; /*the data from idat chunks*/ + ucvector scanlines; + size_t predict; - /*for unknown chunk order*/ - unsigned unknown = 0; + /*for unknown chunk order*/ + unsigned unknown = 0; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - unsigned critical_pos = 1; /*1 = after IHDR, 2 = after PLTE, 3 = after IDAT*/ -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + unsigned critical_pos = 1; /*1 = after IHDR, 2 = after PLTE, 3 = after IDAT*/ +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - /*provide some proper output values if error will happen*/ - *out = 0; + /*provide some proper output values if error will happen*/ + *out = 0; - state->error = lodepng_inspect(w, h, state, in, insize); /*reads header and resets other parameters in state->info_png*/ - if(state->error) return; + state->error = lodepng_inspect(w, h, state, in, insize); /*reads header and resets other parameters in state->info_png*/ + if (state->error) return; - ucvector_init(&idat); - chunk = &in[33]; /*first byte of the first chunk after the header*/ + ucvector_init(&idat); + chunk = &in[33]; /*first byte of the first chunk after the header*/ - /*loop through the chunks, ignoring unknown chunks and stopping at IEND chunk. + /*loop through the chunks, ignoring unknown chunks and stopping at IEND chunk. IDAT data is put at the start of the in buffer*/ - while(!IEND && !state->error) - { - unsigned chunkLength; - const unsigned char* data; /*the data in the chunk*/ + while (!IEND && !state->error) + { + unsigned chunkLength; + const unsigned char* data; /*the data in the chunk*/ - /*error: size of the in buffer too small to contain next chunk*/ - if((size_t)((chunk - in) + 12) > insize || chunk < in) CERROR_BREAK(state->error, 30); + /*error: size of the in buffer too small to contain next chunk*/ + if ((size_t)((chunk - in) + 12) > insize || chunk < in) CERROR_BREAK(state->error, 30); - /*length of the data of the chunk, excluding the length bytes, chunk type and CRC bytes*/ - chunkLength = lodepng_chunk_length(chunk); - /*error: chunk length larger than the max PNG chunk size*/ - if(chunkLength > 2147483647) CERROR_BREAK(state->error, 63); + /*length of the data of the chunk, excluding the length bytes, chunk type and CRC bytes*/ + chunkLength = lodepng_chunk_length(chunk); + /*error: chunk length larger than the max PNG chunk size*/ + if (chunkLength > 2147483647) CERROR_BREAK(state->error, 63); - if((size_t)((chunk - in) + chunkLength + 12) > insize || (chunk + chunkLength + 12) < in) - { - CERROR_BREAK(state->error, 64); /*error: size of the in buffer too small to contain next chunk*/ - } + if ((size_t)((chunk - in) + chunkLength + 12) > insize || (chunk + chunkLength + 12) < in) + { + CERROR_BREAK(state->error, 64); /*error: size of the in buffer too small to contain next chunk*/ + } - data = lodepng_chunk_data_const(chunk); + data = lodepng_chunk_data_const(chunk); - /*IDAT chunk, containing compressed image data*/ - if(lodepng_chunk_type_equals(chunk, "IDAT")) - { - size_t oldsize = idat.size; - if(!ucvector_resize(&idat, oldsize + chunkLength)) CERROR_BREAK(state->error, 83 /*alloc fail*/); - for(i = 0; i < chunkLength; i++) idat.data[oldsize + i] = data[i]; + /*IDAT chunk, containing compressed image data*/ + if (lodepng_chunk_type_equals(chunk, "IDAT")) + { + size_t oldsize = idat.size; + if (!ucvector_resize(&idat, oldsize + chunkLength)) CERROR_BREAK(state->error, 83 /*alloc fail*/); + for (i = 0; i < chunkLength; i++) idat.data[oldsize + i] = data[i]; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - critical_pos = 3; + critical_pos = 3; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - } - /*IEND chunk*/ - else if(lodepng_chunk_type_equals(chunk, "IEND")) - { - IEND = 1; - } - /*palette chunk (PLTE)*/ - else if(lodepng_chunk_type_equals(chunk, "PLTE")) - { - state->error = readChunk_PLTE(&state->info_png.color, data, chunkLength); - if(state->error) break; + } + /*IEND chunk*/ + else if (lodepng_chunk_type_equals(chunk, "IEND")) + { + IEND = 1; + } + /*palette chunk (PLTE)*/ + else if (lodepng_chunk_type_equals(chunk, "PLTE")) + { + state->error = readChunk_PLTE(&state->info_png.color, data, chunkLength); + if (state->error) break; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - critical_pos = 2; + critical_pos = 2; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - } - /*palette transparency chunk (tRNS)*/ - else if(lodepng_chunk_type_equals(chunk, "tRNS")) - { - state->error = readChunk_tRNS(&state->info_png.color, data, chunkLength); - if(state->error) break; - } + } + /*palette transparency chunk (tRNS)*/ + else if (lodepng_chunk_type_equals(chunk, "tRNS")) + { + state->error = readChunk_tRNS(&state->info_png.color, data, chunkLength); + if (state->error) break; + } #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - /*background color chunk (bKGD)*/ - else if(lodepng_chunk_type_equals(chunk, "bKGD")) - { - state->error = readChunk_bKGD(&state->info_png, data, chunkLength); - if(state->error) break; - } - /*text chunk (tEXt)*/ - else if(lodepng_chunk_type_equals(chunk, "tEXt")) - { - if(state->decoder.read_text_chunks) - { - state->error = readChunk_tEXt(&state->info_png, data, chunkLength); - if(state->error) break; - } - } - /*compressed text chunk (zTXt)*/ - else if(lodepng_chunk_type_equals(chunk, "zTXt")) - { - if(state->decoder.read_text_chunks) - { - state->error = readChunk_zTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength); - if(state->error) break; - } - } - /*international text chunk (iTXt)*/ - else if(lodepng_chunk_type_equals(chunk, "iTXt")) - { - if(state->decoder.read_text_chunks) - { - state->error = readChunk_iTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength); - if(state->error) break; - } - } - else if(lodepng_chunk_type_equals(chunk, "tIME")) - { - state->error = readChunk_tIME(&state->info_png, data, chunkLength); - if(state->error) break; - } - else if(lodepng_chunk_type_equals(chunk, "pHYs")) - { - state->error = readChunk_pHYs(&state->info_png, data, chunkLength); - if(state->error) break; - } -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - else /*it's not an implemented chunk type, so ignore it: skip over the data*/ - { - /*error: unknown critical chunk (5th bit of first byte of chunk type is 0)*/ - if(!lodepng_chunk_ancillary(chunk)) CERROR_BREAK(state->error, 69); + /*background color chunk (bKGD)*/ + else if (lodepng_chunk_type_equals(chunk, "bKGD")) + { + state->error = readChunk_bKGD(&state->info_png, data, chunkLength); + if (state->error) break; + } + /*text chunk (tEXt)*/ + else if (lodepng_chunk_type_equals(chunk, "tEXt")) + { + if (state->decoder.read_text_chunks) + { + state->error = readChunk_tEXt(&state->info_png, data, chunkLength); + if (state->error) break; + } + } + /*compressed text chunk (zTXt)*/ + else if (lodepng_chunk_type_equals(chunk, "zTXt")) + { + if (state->decoder.read_text_chunks) + { + state->error = readChunk_zTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength); + if (state->error) break; + } + } + /*international text chunk (iTXt)*/ + else if (lodepng_chunk_type_equals(chunk, "iTXt")) + { + if (state->decoder.read_text_chunks) + { + state->error = readChunk_iTXt(&state->info_png, &state->decoder.zlibsettings, data, chunkLength); + if (state->error) break; + } + } + else if (lodepng_chunk_type_equals(chunk, "tIME")) + { + state->error = readChunk_tIME(&state->info_png, data, chunkLength); + if (state->error) break; + } + else if (lodepng_chunk_type_equals(chunk, "pHYs")) + { + state->error = readChunk_pHYs(&state->info_png, data, chunkLength); + if (state->error) break; + } +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + else /*it's not an implemented chunk type, so ignore it: skip over the data*/ + { + /*error: unknown critical chunk (5th bit of first byte of chunk type is 0)*/ + if (!lodepng_chunk_ancillary(chunk)) CERROR_BREAK(state->error, 69); - unknown = 1; + unknown = 1; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - if(state->decoder.remember_unknown_chunks) - { - state->error = lodepng_chunk_append(&state->info_png.unknown_chunks_data[critical_pos - 1], - &state->info_png.unknown_chunks_size[critical_pos - 1], chunk); - if(state->error) break; - } + if (state->decoder.remember_unknown_chunks) + { + state->error = lodepng_chunk_append(&state->info_png.unknown_chunks_data[critical_pos - 1], + &state->info_png.unknown_chunks_size[critical_pos - 1], chunk); + if (state->error) break; + } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - } + } - if(!state->decoder.ignore_crc && !unknown) /*check CRC if wanted, only on known chunk types*/ - { - if(lodepng_chunk_check_crc(chunk)) CERROR_BREAK(state->error, 57); /*invalid CRC*/ - } + if (!state->decoder.ignore_crc && !unknown) /*check CRC if wanted, only on known chunk types*/ + { + if (lodepng_chunk_check_crc(chunk)) CERROR_BREAK(state->error, 57); /*invalid CRC*/ + } - if(!IEND) chunk = lodepng_chunk_next_const(chunk); - } + if (!IEND) chunk = lodepng_chunk_next_const(chunk); + } - ucvector_init(&scanlines); - /*predict output size, to allocate exact size for output buffer to avoid more dynamic allocation. + ucvector_init(&scanlines); + /*predict output size, to allocate exact size for output buffer to avoid more dynamic allocation. The prediction is currently not correct for interlaced PNG images.*/ - predict = lodepng_get_raw_size_idat(*w, *h, &state->info_png.color) + *h; - if(!state->error && !ucvector_reserve(&scanlines, predict)) state->error = 83; /*alloc fail*/ - if(!state->error) - { - state->error = zlib_decompress(&scanlines.data, &scanlines.size, idat.data, - idat.size, &state->decoder.zlibsettings); - } - ucvector_cleanup(&idat); + predict = lodepng_get_raw_size_idat(*w, *h, &state->info_png.color) + *h; + if (!state->error && !ucvector_reserve(&scanlines, predict)) state->error = 83; /*alloc fail*/ + if (!state->error) + { + state->error = zlib_decompress(&scanlines.data, &scanlines.size, idat.data, + idat.size, &state->decoder.zlibsettings); + } + ucvector_cleanup(&idat); - if(!state->error) - { - ucvector outv; - ucvector_init(&outv); - if(!ucvector_resizev(&outv, - lodepng_get_raw_size(*w, *h, &state->info_png.color), 0)) state->error = 83; /*alloc fail*/ - if(!state->error) state->error = postProcessScanlines(outv.data, scanlines.data, *w, *h, &state->info_png); - *out = outv.data; - } - ucvector_cleanup(&scanlines); + if (!state->error) + { + ucvector outv; + ucvector_init(&outv); + if (!ucvector_resizev(&outv, + lodepng_get_raw_size(*w, *h, &state->info_png.color), 0)) state->error = 83; /*alloc fail*/ + if (!state->error) state->error = postProcessScanlines(outv.data, scanlines.data, *w, *h, &state->info_png); + *out = outv.data; + } + ucvector_cleanup(&scanlines); } unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h, - LodePNGState* state, - const unsigned char* in, size_t insize) + LodePNGState* state, + const unsigned char* in, size_t insize) { - *out = 0; - decodeGeneric(out, w, h, state, in, insize); - if(state->error) return state->error; - if(!state->decoder.color_convert || lodepng_color_mode_equal(&state->info_raw, &state->info_png.color)) - { - /*same color type, no copying or converting of data needed*/ - /*store the info_png color settings on the info_raw so that the info_raw still reflects what colortype + *out = 0; + decodeGeneric(out, w, h, state, in, insize); + if (state->error) return state->error; + if (!state->decoder.color_convert || lodepng_color_mode_equal(&state->info_raw, &state->info_png.color)) + { + /*same color type, no copying or converting of data needed*/ + /*store the info_png color settings on the info_raw so that the info_raw still reflects what colortype the raw image has to the end user*/ - if(!state->decoder.color_convert) - { - state->error = lodepng_color_mode_copy(&state->info_raw, &state->info_png.color); - if(state->error) return state->error; - } - } - else - { - /*color conversion needed; sort of copy of the data*/ - unsigned char* data = *out; - size_t outsize; + if (!state->decoder.color_convert) + { + state->error = lodepng_color_mode_copy(&state->info_raw, &state->info_png.color); + if (state->error) return state->error; + } + } + else + { + /*color conversion needed; sort of copy of the data*/ + unsigned char* data = *out; + size_t outsize; - /*TODO: check if this works according to the statement in the documentation: "The converter can convert + /*TODO: check if this works according to the statement in the documentation: "The converter can convert from greyscale input color type, to 8-bit greyscale or greyscale with alpha"*/ - if(!(state->info_raw.colortype == LCT_RGB || state->info_raw.colortype == LCT_RGBA) - && !(state->info_raw.bitdepth == 8)) - { - return 56; /*unsupported color mode conversion*/ - } + if (!(state->info_raw.colortype == LCT_RGB || state->info_raw.colortype == LCT_RGBA) && !(state->info_raw.bitdepth == 8)) + { + return 56; /*unsupported color mode conversion*/ + } - outsize = lodepng_get_raw_size(*w, *h, &state->info_raw); - *out = (unsigned char*)lodepng_malloc(outsize); - if(!(*out)) - { - state->error = 83; /*alloc fail*/ - } - else state->error = lodepng_convert(*out, data, &state->info_raw, - &state->info_png.color, *w, *h); - lodepng_free(data); - } - return state->error; + outsize = lodepng_get_raw_size(*w, *h, &state->info_raw); + *out = (unsigned char*)lodepng_malloc(outsize); + if (!(*out)) + { + state->error = 83; /*alloc fail*/ + } + else + state->error = lodepng_convert(*out, data, &state->info_raw, + &state->info_png.color, *w, *h); + lodepng_free(data); + } + return state->error; } unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, - size_t insize, LodePNGColorType colortype, unsigned bitdepth) + size_t insize, LodePNGColorType colortype, unsigned bitdepth) { - unsigned error; - LodePNGState state; - lodepng_state_init(&state); - state.info_raw.colortype = colortype; - state.info_raw.bitdepth = bitdepth; - error = lodepng_decode(out, w, h, &state, in, insize); - lodepng_state_cleanup(&state); - return error; + unsigned error; + LodePNGState state; + lodepng_state_init(&state); + state.info_raw.colortype = colortype; + state.info_raw.bitdepth = bitdepth; + error = lodepng_decode(out, w, h, &state, in, insize); + lodepng_state_cleanup(&state); + return error; } unsigned lodepng_decode32(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize) { - return lodepng_decode_memory(out, w, h, in, insize, LCT_RGBA, 8); + return lodepng_decode_memory(out, w, h, in, insize, LCT_RGBA, 8); } unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h, const unsigned char* in, size_t insize) { - return lodepng_decode_memory(out, w, h, in, insize, LCT_RGB, 8); + return lodepng_decode_memory(out, w, h, in, insize, LCT_RGB, 8); } #ifdef LODEPNG_COMPILE_DISK unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename, - LodePNGColorType colortype, unsigned bitdepth) + LodePNGColorType colortype, unsigned bitdepth) { - unsigned char* buffer; - size_t buffersize; - unsigned error; - error = lodepng_load_file(&buffer, &buffersize, filename); - if(!error) error = lodepng_decode_memory(out, w, h, buffer, buffersize, colortype, bitdepth); - lodepng_free(buffer); - return error; + unsigned char* buffer; + size_t buffersize; + unsigned error; + error = lodepng_load_file(&buffer, &buffersize, filename); + if (!error) error = lodepng_decode_memory(out, w, h, buffer, buffersize, colortype, bitdepth); + lodepng_free(buffer); + return error; } unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename) { - return lodepng_decode_file(out, w, h, filename, LCT_RGBA, 8); + return lodepng_decode_file(out, w, h, filename, LCT_RGBA, 8); } unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h, const char* filename) { - return lodepng_decode_file(out, w, h, filename, LCT_RGB, 8); + return lodepng_decode_file(out, w, h, filename, LCT_RGB, 8); } #endif /*LODEPNG_COMPILE_DISK*/ void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings) { - settings->color_convert = 1; + settings->color_convert = 1; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - settings->read_text_chunks = 1; - settings->remember_unknown_chunks = 0; + settings->read_text_chunks = 1; + settings->remember_unknown_chunks = 0; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - settings->ignore_crc = 0; - lodepng_decompress_settings_init(&settings->zlibsettings); + settings->ignore_crc = 0; + lodepng_decompress_settings_init(&settings->zlibsettings); } #endif /*LODEPNG_COMPILE_DECODER*/ @@ -4693,30 +4785,32 @@ void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings) void lodepng_state_init(LodePNGState* state) { #ifdef LODEPNG_COMPILE_DECODER - lodepng_decoder_settings_init(&state->decoder); + lodepng_decoder_settings_init(&state->decoder); #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER - lodepng_encoder_settings_init(&state->encoder); + lodepng_encoder_settings_init(&state->encoder); #endif /*LODEPNG_COMPILE_ENCODER*/ - lodepng_color_mode_init(&state->info_raw); - lodepng_info_init(&state->info_png); - state->error = 1; + lodepng_color_mode_init(&state->info_raw); + lodepng_info_init(&state->info_png); + state->error = 1; } void lodepng_state_cleanup(LodePNGState* state) { - lodepng_color_mode_cleanup(&state->info_raw); - lodepng_info_cleanup(&state->info_png); + lodepng_color_mode_cleanup(&state->info_raw); + lodepng_info_cleanup(&state->info_png); } void lodepng_state_copy(LodePNGState* dest, const LodePNGState* source) { - lodepng_state_cleanup(dest); - *dest = *source; - lodepng_color_mode_init(&dest->info_raw); - lodepng_info_init(&dest->info_png); - dest->error = lodepng_color_mode_copy(&dest->info_raw, &source->info_raw); if(dest->error) return; - dest->error = lodepng_info_copy(&dest->info_png, &source->info_png); if(dest->error) return; + lodepng_state_cleanup(dest); + *dest = *source; + lodepng_color_mode_init(&dest->info_raw); + lodepng_info_init(&dest->info_png); + dest->error = lodepng_color_mode_copy(&dest->info_raw, &source->info_raw); + if (dest->error) return; + dest->error = lodepng_info_copy(&dest->info_png, &source->info_png); + if (dest->error) return; } #endif /* defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) */ @@ -4730,373 +4824,384 @@ void lodepng_state_copy(LodePNGState* dest, const LodePNGState* source) /*chunkName must be string of 4 characters*/ static unsigned addChunk(ucvector* out, const char* chunkName, const unsigned char* data, size_t length) { - CERROR_TRY_RETURN(lodepng_chunk_create(&out->data, &out->size, (unsigned)length, chunkName, data)); - out->allocsize = out->size; /*fix the allocsize again*/ - return 0; + CERROR_TRY_RETURN(lodepng_chunk_create(&out->data, &out->size, (unsigned)length, chunkName, data)); + out->allocsize = out->size; /*fix the allocsize again*/ + return 0; } static void writeSignature(ucvector* out) { - /*8 bytes PNG signature, aka the magic bytes*/ - ucvector_push_back(out, 137); - ucvector_push_back(out, 80); - ucvector_push_back(out, 78); - ucvector_push_back(out, 71); - ucvector_push_back(out, 13); - ucvector_push_back(out, 10); - ucvector_push_back(out, 26); - ucvector_push_back(out, 10); + /*8 bytes PNG signature, aka the magic bytes*/ + ucvector_push_back(out, 137); + ucvector_push_back(out, 80); + ucvector_push_back(out, 78); + ucvector_push_back(out, 71); + ucvector_push_back(out, 13); + ucvector_push_back(out, 10); + ucvector_push_back(out, 26); + ucvector_push_back(out, 10); } static unsigned addChunk_IHDR(ucvector* out, unsigned w, unsigned h, - LodePNGColorType colortype, unsigned bitdepth, unsigned interlace_method) + LodePNGColorType colortype, unsigned bitdepth, unsigned interlace_method) { - unsigned error = 0; - ucvector header; - ucvector_init(&header); + unsigned error = 0; + ucvector header; + ucvector_init(&header); - lodepng_add32bitInt(&header, w); /*width*/ - lodepng_add32bitInt(&header, h); /*height*/ - ucvector_push_back(&header, (unsigned char)bitdepth); /*bit depth*/ - ucvector_push_back(&header, (unsigned char)colortype); /*color type*/ - ucvector_push_back(&header, 0); /*compression method*/ - ucvector_push_back(&header, 0); /*filter method*/ - ucvector_push_back(&header, interlace_method); /*interlace method*/ + lodepng_add32bitInt(&header, w); /*width*/ + lodepng_add32bitInt(&header, h); /*height*/ + ucvector_push_back(&header, (unsigned char)bitdepth); /*bit depth*/ + ucvector_push_back(&header, (unsigned char)colortype); /*color type*/ + ucvector_push_back(&header, 0); /*compression method*/ + ucvector_push_back(&header, 0); /*filter method*/ + ucvector_push_back(&header, interlace_method); /*interlace method*/ - error = addChunk(out, "IHDR", header.data, header.size); - ucvector_cleanup(&header); + error = addChunk(out, "IHDR", header.data, header.size); + ucvector_cleanup(&header); - return error; + return error; } static unsigned addChunk_PLTE(ucvector* out, const LodePNGColorMode* info) { - unsigned error = 0; - size_t i; - ucvector PLTE; - ucvector_init(&PLTE); - for(i = 0; i < info->palettesize * 4; i++) - { - /*add all channels except alpha channel*/ - if(i % 4 != 3) ucvector_push_back(&PLTE, info->palette[i]); - } - error = addChunk(out, "PLTE", PLTE.data, PLTE.size); - ucvector_cleanup(&PLTE); + unsigned error = 0; + size_t i; + ucvector PLTE; + ucvector_init(&PLTE); + for (i = 0; i < info->palettesize * 4; i++) + { + /*add all channels except alpha channel*/ + if (i % 4 != 3) ucvector_push_back(&PLTE, info->palette[i]); + } + error = addChunk(out, "PLTE", PLTE.data, PLTE.size); + ucvector_cleanup(&PLTE); - return error; + return error; } static unsigned addChunk_tRNS(ucvector* out, const LodePNGColorMode* info) { - unsigned error = 0; - size_t i; - ucvector tRNS; - ucvector_init(&tRNS); - if(info->colortype == LCT_PALETTE) - { - size_t amount = info->palettesize; - /*the tail of palette values that all have 255 as alpha, does not have to be encoded*/ - for(i = info->palettesize; i > 0; i--) - { - if(info->palette[4 * (i - 1) + 3] == 255) amount--; - else break; - } - /*add only alpha channel*/ - for(i = 0; i < amount; i++) ucvector_push_back(&tRNS, info->palette[4 * i + 3]); - } - else if(info->colortype == LCT_GREY) - { - if(info->key_defined) - { - ucvector_push_back(&tRNS, (unsigned char)(info->key_r / 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_r % 256)); - } - } - else if(info->colortype == LCT_RGB) - { - if(info->key_defined) - { - ucvector_push_back(&tRNS, (unsigned char)(info->key_r / 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_r % 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_g / 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_g % 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_b / 256)); - ucvector_push_back(&tRNS, (unsigned char)(info->key_b % 256)); - } - } + unsigned error = 0; + size_t i; + ucvector tRNS; + ucvector_init(&tRNS); + if (info->colortype == LCT_PALETTE) + { + size_t amount = info->palettesize; + /*the tail of palette values that all have 255 as alpha, does not have to be encoded*/ + for (i = info->palettesize; i > 0; i--) + { + if (info->palette[4 * (i - 1) + 3] == 255) + amount--; + else + break; + } + /*add only alpha channel*/ + for (i = 0; i < amount; i++) ucvector_push_back(&tRNS, info->palette[4 * i + 3]); + } + else if (info->colortype == LCT_GREY) + { + if (info->key_defined) + { + ucvector_push_back(&tRNS, (unsigned char)(info->key_r / 256)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_r % 256)); + } + } + else if (info->colortype == LCT_RGB) + { + if (info->key_defined) + { + ucvector_push_back(&tRNS, (unsigned char)(info->key_r / 256)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_r % 256)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_g / 256)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_g % 256)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_b / 256)); + ucvector_push_back(&tRNS, (unsigned char)(info->key_b % 256)); + } + } - error = addChunk(out, "tRNS", tRNS.data, tRNS.size); - ucvector_cleanup(&tRNS); + error = addChunk(out, "tRNS", tRNS.data, tRNS.size); + ucvector_cleanup(&tRNS); - return error; + return error; } static unsigned addChunk_IDAT(ucvector* out, const unsigned char* data, size_t datasize, - LodePNGCompressSettings* zlibsettings) + LodePNGCompressSettings* zlibsettings) { - ucvector zlibdata; - unsigned error = 0; + ucvector zlibdata; + unsigned error = 0; - /*compress with the Zlib compressor*/ - ucvector_init(&zlibdata); - error = zlib_compress(&zlibdata.data, &zlibdata.size, data, datasize, zlibsettings); - if(!error) error = addChunk(out, "IDAT", zlibdata.data, zlibdata.size); - ucvector_cleanup(&zlibdata); + /*compress with the Zlib compressor*/ + ucvector_init(&zlibdata); + error = zlib_compress(&zlibdata.data, &zlibdata.size, data, datasize, zlibsettings); + if (!error) error = addChunk(out, "IDAT", zlibdata.data, zlibdata.size); + ucvector_cleanup(&zlibdata); - return error; + return error; } static unsigned addChunk_IEND(ucvector* out) { - unsigned error = 0; - error = addChunk(out, "IEND", 0, 0); - return error; + unsigned error = 0; + error = addChunk(out, "IEND", 0, 0); + return error; } #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS static unsigned addChunk_tEXt(ucvector* out, const char* keyword, const char* textstring) { - unsigned error = 0; - size_t i; - ucvector text; - ucvector_init(&text); - for(i = 0; keyword[i] != 0; i++) ucvector_push_back(&text, (unsigned char)keyword[i]); - if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/ - ucvector_push_back(&text, 0); /*0 termination char*/ - for(i = 0; textstring[i] != 0; i++) ucvector_push_back(&text, (unsigned char)textstring[i]); - error = addChunk(out, "tEXt", text.data, text.size); - ucvector_cleanup(&text); + unsigned error = 0; + size_t i; + ucvector text; + ucvector_init(&text); + for (i = 0; keyword[i] != 0; i++) ucvector_push_back(&text, (unsigned char)keyword[i]); + if (i < 1 || i > 79) return 89; /*error: invalid keyword size*/ + ucvector_push_back(&text, 0); /*0 termination char*/ + for (i = 0; textstring[i] != 0; i++) ucvector_push_back(&text, (unsigned char)textstring[i]); + error = addChunk(out, "tEXt", text.data, text.size); + ucvector_cleanup(&text); - return error; + return error; } static unsigned addChunk_zTXt(ucvector* out, const char* keyword, const char* textstring, - LodePNGCompressSettings* zlibsettings) + LodePNGCompressSettings* zlibsettings) { - unsigned error = 0; - ucvector data, compressed; - size_t i, textsize = strlen(textstring); + unsigned error = 0; + ucvector data, compressed; + size_t i, textsize = strlen(textstring); - ucvector_init(&data); - ucvector_init(&compressed); - for(i = 0; keyword[i] != 0; i++) ucvector_push_back(&data, (unsigned char)keyword[i]); - if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/ - ucvector_push_back(&data, 0); /*0 termination char*/ - ucvector_push_back(&data, 0); /*compression method: 0*/ + ucvector_init(&data); + ucvector_init(&compressed); + for (i = 0; keyword[i] != 0; i++) ucvector_push_back(&data, (unsigned char)keyword[i]); + if (i < 1 || i > 79) return 89; /*error: invalid keyword size*/ + ucvector_push_back(&data, 0); /*0 termination char*/ + ucvector_push_back(&data, 0); /*compression method: 0*/ - error = zlib_compress(&compressed.data, &compressed.size, - (unsigned char*)textstring, textsize, zlibsettings); - if(!error) - { - for(i = 0; i < compressed.size; i++) ucvector_push_back(&data, compressed.data[i]); - error = addChunk(out, "zTXt", data.data, data.size); - } + error = zlib_compress(&compressed.data, &compressed.size, + (unsigned char*)textstring, textsize, zlibsettings); + if (!error) + { + for (i = 0; i < compressed.size; i++) ucvector_push_back(&data, compressed.data[i]); + error = addChunk(out, "zTXt", data.data, data.size); + } - ucvector_cleanup(&compressed); - ucvector_cleanup(&data); - return error; + ucvector_cleanup(&compressed); + ucvector_cleanup(&data); + return error; } static unsigned addChunk_iTXt(ucvector* out, unsigned compressed, const char* keyword, const char* langtag, - const char* transkey, const char* textstring, LodePNGCompressSettings* zlibsettings) + const char* transkey, const char* textstring, LodePNGCompressSettings* zlibsettings) { - unsigned error = 0; - ucvector data; - size_t i, textsize = strlen(textstring); + unsigned error = 0; + ucvector data; + size_t i, textsize = strlen(textstring); - ucvector_init(&data); + ucvector_init(&data); - for(i = 0; keyword[i] != 0; i++) ucvector_push_back(&data, (unsigned char)keyword[i]); - if(i < 1 || i > 79) return 89; /*error: invalid keyword size*/ - ucvector_push_back(&data, 0); /*null termination char*/ - ucvector_push_back(&data, compressed ? 1 : 0); /*compression flag*/ - ucvector_push_back(&data, 0); /*compression method*/ - for(i = 0; langtag[i] != 0; i++) ucvector_push_back(&data, (unsigned char)langtag[i]); - ucvector_push_back(&data, 0); /*null termination char*/ - for(i = 0; transkey[i] != 0; i++) ucvector_push_back(&data, (unsigned char)transkey[i]); - ucvector_push_back(&data, 0); /*null termination char*/ + for (i = 0; keyword[i] != 0; i++) ucvector_push_back(&data, (unsigned char)keyword[i]); + if (i < 1 || i > 79) return 89; /*error: invalid keyword size*/ + ucvector_push_back(&data, 0); /*null termination char*/ + ucvector_push_back(&data, compressed ? 1 : 0); /*compression flag*/ + ucvector_push_back(&data, 0); /*compression method*/ + for (i = 0; langtag[i] != 0; i++) ucvector_push_back(&data, (unsigned char)langtag[i]); + ucvector_push_back(&data, 0); /*null termination char*/ + for (i = 0; transkey[i] != 0; i++) ucvector_push_back(&data, (unsigned char)transkey[i]); + ucvector_push_back(&data, 0); /*null termination char*/ - if(compressed) - { - ucvector compressed_data; - ucvector_init(&compressed_data); - error = zlib_compress(&compressed_data.data, &compressed_data.size, - (unsigned char*)textstring, textsize, zlibsettings); - if(!error) - { - for(i = 0; i < compressed_data.size; i++) ucvector_push_back(&data, compressed_data.data[i]); - } - ucvector_cleanup(&compressed_data); - } - else /*not compressed*/ - { - for(i = 0; textstring[i] != 0; i++) ucvector_push_back(&data, (unsigned char)textstring[i]); - } + if (compressed) + { + ucvector compressed_data; + ucvector_init(&compressed_data); + error = zlib_compress(&compressed_data.data, &compressed_data.size, + (unsigned char*)textstring, textsize, zlibsettings); + if (!error) + { + for (i = 0; i < compressed_data.size; i++) ucvector_push_back(&data, compressed_data.data[i]); + } + ucvector_cleanup(&compressed_data); + } + else /*not compressed*/ + { + for (i = 0; textstring[i] != 0; i++) ucvector_push_back(&data, (unsigned char)textstring[i]); + } - if(!error) error = addChunk(out, "iTXt", data.data, data.size); - ucvector_cleanup(&data); - return error; + if (!error) error = addChunk(out, "iTXt", data.data, data.size); + ucvector_cleanup(&data); + return error; } static unsigned addChunk_bKGD(ucvector* out, const LodePNGInfo* info) { - unsigned error = 0; - ucvector bKGD; - ucvector_init(&bKGD); - if(info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) - { - ucvector_push_back(&bKGD, (unsigned char)(info->background_r / 256)); - ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256)); - } - else if(info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) - { - ucvector_push_back(&bKGD, (unsigned char)(info->background_r / 256)); - ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256)); - ucvector_push_back(&bKGD, (unsigned char)(info->background_g / 256)); - ucvector_push_back(&bKGD, (unsigned char)(info->background_g % 256)); - ucvector_push_back(&bKGD, (unsigned char)(info->background_b / 256)); - ucvector_push_back(&bKGD, (unsigned char)(info->background_b % 256)); - } - else if(info->color.colortype == LCT_PALETTE) - { - ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256)); /*palette index*/ - } + unsigned error = 0; + ucvector bKGD; + ucvector_init(&bKGD); + if (info->color.colortype == LCT_GREY || info->color.colortype == LCT_GREY_ALPHA) + { + ucvector_push_back(&bKGD, (unsigned char)(info->background_r / 256)); + ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256)); + } + else if (info->color.colortype == LCT_RGB || info->color.colortype == LCT_RGBA) + { + ucvector_push_back(&bKGD, (unsigned char)(info->background_r / 256)); + ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256)); + ucvector_push_back(&bKGD, (unsigned char)(info->background_g / 256)); + ucvector_push_back(&bKGD, (unsigned char)(info->background_g % 256)); + ucvector_push_back(&bKGD, (unsigned char)(info->background_b / 256)); + ucvector_push_back(&bKGD, (unsigned char)(info->background_b % 256)); + } + else if (info->color.colortype == LCT_PALETTE) + { + ucvector_push_back(&bKGD, (unsigned char)(info->background_r % 256)); /*palette index*/ + } - error = addChunk(out, "bKGD", bKGD.data, bKGD.size); - ucvector_cleanup(&bKGD); + error = addChunk(out, "bKGD", bKGD.data, bKGD.size); + ucvector_cleanup(&bKGD); - return error; + return error; } static unsigned addChunk_tIME(ucvector* out, const LodePNGTime* time) { - unsigned error = 0; - unsigned char* data = (unsigned char*)lodepng_malloc(7); - if(!data) return 83; /*alloc fail*/ - data[0] = (unsigned char)(time->year / 256); - data[1] = (unsigned char)(time->year % 256); - data[2] = (unsigned char)time->month; - data[3] = (unsigned char)time->day; - data[4] = (unsigned char)time->hour; - data[5] = (unsigned char)time->minute; - data[6] = (unsigned char)time->second; - error = addChunk(out, "tIME", data, 7); - lodepng_free(data); - return error; + unsigned error = 0; + unsigned char* data = (unsigned char*)lodepng_malloc(7); + if (!data) return 83; /*alloc fail*/ + data[0] = (unsigned char)(time->year / 256); + data[1] = (unsigned char)(time->year % 256); + data[2] = (unsigned char)time->month; + data[3] = (unsigned char)time->day; + data[4] = (unsigned char)time->hour; + data[5] = (unsigned char)time->minute; + data[6] = (unsigned char)time->second; + error = addChunk(out, "tIME", data, 7); + lodepng_free(data); + return error; } static unsigned addChunk_pHYs(ucvector* out, const LodePNGInfo* info) { - unsigned error = 0; - ucvector data; - ucvector_init(&data); + unsigned error = 0; + ucvector data; + ucvector_init(&data); - lodepng_add32bitInt(&data, info->phys_x); - lodepng_add32bitInt(&data, info->phys_y); - ucvector_push_back(&data, info->phys_unit); + lodepng_add32bitInt(&data, info->phys_x); + lodepng_add32bitInt(&data, info->phys_y); + ucvector_push_back(&data, info->phys_unit); - error = addChunk(out, "pHYs", data.data, data.size); - ucvector_cleanup(&data); + error = addChunk(out, "pHYs", data.data, data.size); + ucvector_cleanup(&data); - return error; + return error; } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ static void filterScanline(unsigned char* out, const unsigned char* scanline, const unsigned char* prevline, - size_t length, size_t bytewidth, unsigned char filterType) + size_t length, size_t bytewidth, unsigned char filterType) { - size_t i; - switch(filterType) - { - case 0: /*None*/ - for(i = 0; i < length; i++) out[i] = scanline[i]; - break; - case 1: /*Sub*/ - if(prevline) - { - for(i = 0; i < bytewidth; i++) out[i] = scanline[i]; - for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth]; - } - else - { - for(i = 0; i < bytewidth; i++) out[i] = scanline[i]; - for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth]; - } - break; - case 2: /*Up*/ - if(prevline) - { - for(i = 0; i < length; i++) out[i] = scanline[i] - prevline[i]; - } - else - { - for(i = 0; i < length; i++) out[i] = scanline[i]; - } - break; - case 3: /*Average*/ - if(prevline) - { - for(i = 0; i < bytewidth; i++) out[i] = scanline[i] - prevline[i] / 2; - for(i = bytewidth; i < length; i++) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) / 2); - } - else - { - for(i = 0; i < bytewidth; i++) out[i] = scanline[i]; - for(i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth] / 2; - } - break; - case 4: /*Paeth*/ - if(prevline) - { - /*paethPredictor(0, prevline[i], 0) is always prevline[i]*/ - for(i = 0; i < bytewidth; i++) out[i] = (scanline[i] - prevline[i]); - for(i = bytewidth; i < length; i++) - { - out[i] = (scanline[i] - paethPredictor(scanline[i - bytewidth], prevline[i], prevline[i - bytewidth])); - } - } - else - { - for(i = 0; i < bytewidth; i++) out[i] = scanline[i]; - /*paethPredictor(scanline[i - bytewidth], 0, 0) is always scanline[i - bytewidth]*/ - for(i = bytewidth; i < length; i++) out[i] = (scanline[i] - scanline[i - bytewidth]); - } - break; - default: return; /*unexisting filter type given*/ - } + size_t i; + switch (filterType) + { + case 0: /*None*/ + for (i = 0; i < length; i++) out[i] = scanline[i]; + break; + case 1: /*Sub*/ + if (prevline) + { + for (i = 0; i < bytewidth; i++) out[i] = scanline[i]; + for (i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth]; + } + else + { + for (i = 0; i < bytewidth; i++) out[i] = scanline[i]; + for (i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth]; + } + break; + case 2: /*Up*/ + if (prevline) + { + for (i = 0; i < length; i++) out[i] = scanline[i] - prevline[i]; + } + else + { + for (i = 0; i < length; i++) out[i] = scanline[i]; + } + break; + case 3: /*Average*/ + if (prevline) + { + for (i = 0; i < bytewidth; i++) out[i] = scanline[i] - prevline[i] / 2; + for (i = bytewidth; i < length; i++) out[i] = scanline[i] - ((scanline[i - bytewidth] + prevline[i]) / 2); + } + else + { + for (i = 0; i < bytewidth; i++) out[i] = scanline[i]; + for (i = bytewidth; i < length; i++) out[i] = scanline[i] - scanline[i - bytewidth] / 2; + } + break; + case 4: /*Paeth*/ + if (prevline) + { + /*paethPredictor(0, prevline[i], 0) is always prevline[i]*/ + for (i = 0; i < bytewidth; i++) out[i] = (scanline[i] - prevline[i]); + for (i = bytewidth; i < length; i++) + { + out[i] = (scanline[i] - paethPredictor(scanline[i - bytewidth], prevline[i], prevline[i - bytewidth])); + } + } + else + { + for (i = 0; i < bytewidth; i++) out[i] = scanline[i]; + /*paethPredictor(scanline[i - bytewidth], 0, 0) is always scanline[i - bytewidth]*/ + for (i = bytewidth; i < length; i++) out[i] = (scanline[i] - scanline[i - bytewidth]); + } + break; + default: + return; /*unexisting filter type given*/ + } } /* log2 approximation. A slight bit faster than std::log. */ static float flog2(float f) { - float result = 0; - while(f > 32) { result += 4; f /= 16; } - while(f > 2) { result++; f /= 2; } - return result + 1.442695f * (f * f * f / 3 - 3 * f * f / 2 + 3 * f - 1.83333f); + float result = 0; + while (f > 32) + { + result += 4; + f /= 16; + } + while (f > 2) + { + result++; + f /= 2; + } + return result + 1.442695f * (f * f * f / 3 - 3 * f * f / 2 + 3 * f - 1.83333f); } static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, - const LodePNGColorMode* info, const LodePNGEncoderSettings* settings) + const LodePNGColorMode* info, const LodePNGEncoderSettings* settings) { - /* + /* For PNG filter method 0 out must be a buffer with as size: h + (w * h * bpp + 7) / 8, because there are the scanlines with 1 extra byte per scanline */ - unsigned bpp = lodepng_get_bpp(info); - /*the width of a scanline in bytes, not including the filter type*/ - size_t linebytes = (w * bpp + 7) / 8; - /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/ - size_t bytewidth = (bpp + 7) / 8; - const unsigned char* prevline = 0; - unsigned x, y; - unsigned error = 0; - LodePNGFilterStrategy strategy = settings->filter_strategy; + unsigned bpp = lodepng_get_bpp(info); + /*the width of a scanline in bytes, not including the filter type*/ + size_t linebytes = (w * bpp + 7) / 8; + /*bytewidth is used for filtering, is 1 when bpp < 8, number of bytes per pixel otherwise*/ + size_t bytewidth = (bpp + 7) / 8; + const unsigned char* prevline = 0; + unsigned x, y; + unsigned error = 0; + LodePNGFilterStrategy strategy = settings->filter_strategy; - /* + /* There is a heuristic called the minimum sum of absolute differences heuristic, suggested by the PNG standard: * If the image type is Palette, or the bit depth is smaller than 8, then do not filter the image (i.e. use fixed filtering, with the filter None). @@ -5109,214 +5214,215 @@ static unsigned filter(unsigned char* out, const unsigned char* in, unsigned w, but for "the other case", whatever strategy filter_strategy is set to instead of the minimum sum heuristic is used. */ - if(settings->filter_palette_zero && - (info->colortype == LCT_PALETTE || info->bitdepth < 8)) strategy = LFS_ZERO; + if (settings->filter_palette_zero && + (info->colortype == LCT_PALETTE || info->bitdepth < 8)) strategy = LFS_ZERO; - if(bpp == 0) return 31; /*error: invalid color type*/ + if (bpp == 0) return 31; /*error: invalid color type*/ - if(strategy == LFS_ZERO) - { - for(y = 0; y < h; y++) - { - size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ - size_t inindex = linebytes * y; - out[outindex] = 0; /*filter type byte*/ - filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, 0); - prevline = &in[inindex]; - } - } - else if(strategy == LFS_MINSUM) - { - /*adaptive filtering*/ - size_t sum[5]; - ucvector attempt[5]; /*five filtering attempts, one for each filter type*/ - size_t smallest = 0; - unsigned char type, bestType = 0; + if (strategy == LFS_ZERO) + { + for (y = 0; y < h; y++) + { + size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ + size_t inindex = linebytes * y; + out[outindex] = 0; /*filter type byte*/ + filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, 0); + prevline = &in[inindex]; + } + } + else if (strategy == LFS_MINSUM) + { + /*adaptive filtering*/ + size_t sum[5]; + ucvector attempt[5]; /*five filtering attempts, one for each filter type*/ + size_t smallest = 0; + unsigned char type, bestType = 0; - for(type = 0; type < 5; type++) - { - ucvector_init(&attempt[type]); - if(!ucvector_resize(&attempt[type], linebytes)) return 83; /*alloc fail*/ - } + for (type = 0; type < 5; type++) + { + ucvector_init(&attempt[type]); + if (!ucvector_resize(&attempt[type], linebytes)) return 83; /*alloc fail*/ + } - if(!error) - { - for(y = 0; y < h; y++) - { - /*try the 5 filter types*/ - for(type = 0; type < 5; type++) - { - filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type); + if (!error) + { + for (y = 0; y < h; y++) + { + /*try the 5 filter types*/ + for (type = 0; type < 5; type++) + { + filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type); - /*calculate the sum of the result*/ - sum[type] = 0; - if(type == 0) - { - for(x = 0; x < linebytes; x++) sum[type] += (unsigned char)(attempt[type].data[x]); - } - else - { - for(x = 0; x < linebytes; x++) - { - /*For differences, each byte should be treated as signed, values above 127 are negative + /*calculate the sum of the result*/ + sum[type] = 0; + if (type == 0) + { + for (x = 0; x < linebytes; x++) sum[type] += (unsigned char)(attempt[type].data[x]); + } + else + { + for (x = 0; x < linebytes; x++) + { + /*For differences, each byte should be treated as signed, values above 127 are negative (converted to signed char). Filtertype 0 isn't a difference though, so use unsigned there. This means filtertype 0 is almost never chosen, but that is justified.*/ - unsigned char s = attempt[type].data[x]; - sum[type] += s < 128 ? s : (255U - s); - } - } + unsigned char s = attempt[type].data[x]; + sum[type] += s < 128 ? s : (255U - s); + } + } - /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/ - if(type == 0 || sum[type] < smallest) - { - bestType = type; - smallest = sum[type]; - } - } + /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/ + if (type == 0 || sum[type] < smallest) + { + bestType = type; + smallest = sum[type]; + } + } - prevline = &in[y * linebytes]; + prevline = &in[y * linebytes]; - /*now fill the out values*/ - out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ - for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x]; - } - } + /*now fill the out values*/ + out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ + for (x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x]; + } + } - for(type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]); - } - else if(strategy == LFS_ENTROPY) - { - float sum[5]; - ucvector attempt[5]; /*five filtering attempts, one for each filter type*/ - float smallest = 0; - unsigned type, bestType = 0; - unsigned count[256]; + for (type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]); + } + else if (strategy == LFS_ENTROPY) + { + float sum[5]; + ucvector attempt[5]; /*five filtering attempts, one for each filter type*/ + float smallest = 0; + unsigned type, bestType = 0; + unsigned count[256]; - for(type = 0; type < 5; type++) - { - ucvector_init(&attempt[type]); - if(!ucvector_resize(&attempt[type], linebytes)) return 83; /*alloc fail*/ - } + for (type = 0; type < 5; type++) + { + ucvector_init(&attempt[type]); + if (!ucvector_resize(&attempt[type], linebytes)) return 83; /*alloc fail*/ + } - for(y = 0; y < h; y++) - { - /*try the 5 filter types*/ - for(type = 0; type < 5; type++) - { - filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type); - for(x = 0; x < 256; x++) count[x] = 0; - for(x = 0; x < linebytes; x++) count[attempt[type].data[x]]++; - count[type]++; /*the filter type itself is part of the scanline*/ - sum[type] = 0; - for(x = 0; x < 256; x++) - { - float p = count[x] / (float)(linebytes + 1); - sum[type] += count[x] == 0 ? 0 : flog2(1 / p) * p; - } - /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/ - if(type == 0 || sum[type] < smallest) - { - bestType = type; - smallest = sum[type]; - } - } + for (y = 0; y < h; y++) + { + /*try the 5 filter types*/ + for (type = 0; type < 5; type++) + { + filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type); + for (x = 0; x < 256; x++) count[x] = 0; + for (x = 0; x < linebytes; x++) count[attempt[type].data[x]]++; + count[type]++; /*the filter type itself is part of the scanline*/ + sum[type] = 0; + for (x = 0; x < 256; x++) + { + float p = count[x] / (float)(linebytes + 1); + sum[type] += count[x] == 0 ? 0 : flog2(1 / p) * p; + } + /*check if this is smallest sum (or if type == 0 it's the first case so always store the values)*/ + if (type == 0 || sum[type] < smallest) + { + bestType = type; + smallest = sum[type]; + } + } - prevline = &in[y * linebytes]; + prevline = &in[y * linebytes]; - /*now fill the out values*/ - out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ - for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x]; - } + /*now fill the out values*/ + out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ + for (x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x]; + } - for(type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]); - } - else if(strategy == LFS_PREDEFINED) - { - for(y = 0; y < h; y++) - { - size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ - size_t inindex = linebytes * y; - unsigned char type = settings->predefined_filters[y]; - out[outindex] = type; /*filter type byte*/ - filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, type); - prevline = &in[inindex]; - } - } - else if(strategy == LFS_BRUTE_FORCE) - { - /*brute force filter chooser. + for (type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]); + } + else if (strategy == LFS_PREDEFINED) + { + for (y = 0; y < h; y++) + { + size_t outindex = (1 + linebytes) * y; /*the extra filterbyte added to each row*/ + size_t inindex = linebytes * y; + unsigned char type = settings->predefined_filters[y]; + out[outindex] = type; /*filter type byte*/ + filterScanline(&out[outindex + 1], &in[inindex], prevline, linebytes, bytewidth, type); + prevline = &in[inindex]; + } + } + else if (strategy == LFS_BRUTE_FORCE) + { + /*brute force filter chooser. deflate the scanline after every filter attempt to see which one deflates best. This is very slow and gives only slightly smaller, sometimes even larger, result*/ - size_t size[5]; - ucvector attempt[5]; /*five filtering attempts, one for each filter type*/ - size_t smallest = 0; - unsigned type = 0, bestType = 0; - unsigned char* dummy; - LodePNGCompressSettings zlibsettings = settings->zlibsettings; - /*use fixed tree on the attempts so that the tree is not adapted to the filtertype on purpose, + size_t size[5]; + ucvector attempt[5]; /*five filtering attempts, one for each filter type*/ + size_t smallest = 0; + unsigned type = 0, bestType = 0; + unsigned char* dummy; + LodePNGCompressSettings zlibsettings = settings->zlibsettings; + /*use fixed tree on the attempts so that the tree is not adapted to the filtertype on purpose, to simulate the true case where the tree is the same for the whole image. Sometimes it gives better result with dynamic tree anyway. Using the fixed tree sometimes gives worse, but in rare cases better compression. It does make this a bit less slow, so it's worth doing this.*/ - zlibsettings.btype = 1; - /*a custom encoder likely doesn't read the btype setting and is optimized for complete PNG + zlibsettings.btype = 1; + /*a custom encoder likely doesn't read the btype setting and is optimized for complete PNG images only, so disable it*/ - zlibsettings.custom_zlib = 0; - zlibsettings.custom_deflate = 0; - for(type = 0; type < 5; type++) - { - ucvector_init(&attempt[type]); - ucvector_resize(&attempt[type], linebytes); /*todo: give error if resize failed*/ - } - for(y = 0; y < h; y++) /*try the 5 filter types*/ - { - for(type = 0; type < 5; type++) - { - unsigned testsize = attempt[type].size; - /*if(testsize > 8) testsize /= 8;*/ /*it already works good enough by testing a part of the row*/ + zlibsettings.custom_zlib = 0; + zlibsettings.custom_deflate = 0; + for (type = 0; type < 5; type++) + { + ucvector_init(&attempt[type]); + ucvector_resize(&attempt[type], linebytes); /*todo: give error if resize failed*/ + } + for (y = 0; y < h; y++) /*try the 5 filter types*/ + { + for (type = 0; type < 5; type++) + { + unsigned testsize = attempt[type].size; + /*if(testsize > 8) testsize /= 8;*/ /*it already works good enough by testing a part of the row*/ - filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type); - size[type] = 0; - dummy = 0; - zlib_compress(&dummy, &size[type], attempt[type].data, testsize, &zlibsettings); - lodepng_free(dummy); - /*check if this is smallest size (or if type == 0 it's the first case so always store the values)*/ - if(type == 0 || size[type] < smallest) - { - bestType = type; - smallest = size[type]; - } - } - prevline = &in[y * linebytes]; - out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ - for(x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x]; - } - for(type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]); - } - else return 88; /* unknown filter strategy */ + filterScanline(attempt[type].data, &in[y * linebytes], prevline, linebytes, bytewidth, type); + size[type] = 0; + dummy = 0; + zlib_compress(&dummy, &size[type], attempt[type].data, testsize, &zlibsettings); + lodepng_free(dummy); + /*check if this is smallest size (or if type == 0 it's the first case so always store the values)*/ + if (type == 0 || size[type] < smallest) + { + bestType = type; + smallest = size[type]; + } + } + prevline = &in[y * linebytes]; + out[y * (linebytes + 1)] = bestType; /*the first byte of a scanline will be the filter type*/ + for (x = 0; x < linebytes; x++) out[y * (linebytes + 1) + 1 + x] = attempt[bestType].data[x]; + } + for (type = 0; type < 5; type++) ucvector_cleanup(&attempt[type]); + } + else + return 88; /* unknown filter strategy */ - return error; + return error; } static void addPaddingBits(unsigned char* out, const unsigned char* in, - size_t olinebits, size_t ilinebits, unsigned h) + size_t olinebits, size_t ilinebits, unsigned h) { - /*The opposite of the removePaddingBits function + /*The opposite of the removePaddingBits function olinebits must be >= ilinebits*/ - unsigned y; - size_t diff = olinebits - ilinebits; - size_t obp = 0, ibp = 0; /*bit pointers*/ - for(y = 0; y < h; y++) - { - size_t x; - for(x = 0; x < ilinebits; x++) - { - unsigned char bit = readBitFromReversedStream(&ibp, in); - setBitOfReversedStream(&obp, out, bit); - } - /*obp += diff; --> no, fill in some value in the padding bits too, to avoid + unsigned y; + size_t diff = olinebits - ilinebits; + size_t obp = 0, ibp = 0; /*bit pointers*/ + for (y = 0; y < h; y++) + { + size_t x; + for (x = 0; x < ilinebits; x++) + { + unsigned char bit = readBitFromReversedStream(&ibp, in); + setBitOfReversedStream(&obp, out, bit); + } + /*obp += diff; --> no, fill in some value in the padding bits too, to avoid "Use of uninitialised value of size ###" warning from valgrind*/ - for(x = 0; x < diff; x++) setBitOfReversedStream(&obp, out, 0); - } + for (x = 0; x < diff; x++) setBitOfReversedStream(&obp, out, 0); + } } /* @@ -5332,140 +5438,140 @@ NOTE: comments about padding bits are only relevant if bpp < 8 */ static void Adam7_interlace(unsigned char* out, const unsigned char* in, unsigned w, unsigned h, unsigned bpp) { - unsigned passw[7], passh[7]; - size_t filter_passstart[8], padded_passstart[8], passstart[8]; - unsigned i; + unsigned passw[7], passh[7]; + size_t filter_passstart[8], padded_passstart[8], passstart[8]; + unsigned i; - Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); + Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); - if(bpp >= 8) - { - for(i = 0; i < 7; i++) - { - unsigned x, y, b; - size_t bytewidth = bpp / 8; - for(y = 0; y < passh[i]; y++) - for(x = 0; x < passw[i]; x++) - { - size_t pixelinstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth; - size_t pixeloutstart = passstart[i] + (y * passw[i] + x) * bytewidth; - for(b = 0; b < bytewidth; b++) - { - out[pixeloutstart + b] = in[pixelinstart + b]; - } - } - } - } - else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ - { - for(i = 0; i < 7; i++) - { - unsigned x, y, b; - unsigned ilinebits = bpp * passw[i]; - unsigned olinebits = bpp * w; - size_t obp, ibp; /*bit pointers (for out and in buffer)*/ - for(y = 0; y < passh[i]; y++) - for(x = 0; x < passw[i]; x++) - { - ibp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp; - obp = (8 * passstart[i]) + (y * ilinebits + x * bpp); - for(b = 0; b < bpp; b++) - { - unsigned char bit = readBitFromReversedStream(&ibp, in); - setBitOfReversedStream(&obp, out, bit); - } - } - } - } + if (bpp >= 8) + { + for (i = 0; i < 7; i++) + { + unsigned x, y, b; + size_t bytewidth = bpp / 8; + for (y = 0; y < passh[i]; y++) + for (x = 0; x < passw[i]; x++) + { + size_t pixelinstart = ((ADAM7_IY[i] + y * ADAM7_DY[i]) * w + ADAM7_IX[i] + x * ADAM7_DX[i]) * bytewidth; + size_t pixeloutstart = passstart[i] + (y * passw[i] + x) * bytewidth; + for (b = 0; b < bytewidth; b++) + { + out[pixeloutstart + b] = in[pixelinstart + b]; + } + } + } + } + else /*bpp < 8: Adam7 with pixels < 8 bit is a bit trickier: with bit pointers*/ + { + for (i = 0; i < 7; i++) + { + unsigned x, y, b; + unsigned ilinebits = bpp * passw[i]; + unsigned olinebits = bpp * w; + size_t obp, ibp; /*bit pointers (for out and in buffer)*/ + for (y = 0; y < passh[i]; y++) + for (x = 0; x < passw[i]; x++) + { + ibp = (ADAM7_IY[i] + y * ADAM7_DY[i]) * olinebits + (ADAM7_IX[i] + x * ADAM7_DX[i]) * bpp; + obp = (8 * passstart[i]) + (y * ilinebits + x * bpp); + for (b = 0; b < bpp; b++) + { + unsigned char bit = readBitFromReversedStream(&ibp, in); + setBitOfReversedStream(&obp, out, bit); + } + } + } + } } /*out must be buffer big enough to contain uncompressed IDAT chunk data, and in must contain the full image. return value is error**/ static unsigned preProcessScanlines(unsigned char** out, size_t* outsize, const unsigned char* in, - unsigned w, unsigned h, - const LodePNGInfo* info_png, const LodePNGEncoderSettings* settings) + unsigned w, unsigned h, + const LodePNGInfo* info_png, const LodePNGEncoderSettings* settings) { - /* + /* This function converts the pure 2D image with the PNG's colortype, into filtered-padded-interlaced data. Steps: *) if no Adam7: 1) add padding bits (= posible extra bits per scanline if bpp < 8) 2) filter *) if adam7: 1) Adam7_interlace 2) 7x add padding bits 3) 7x filter */ - unsigned bpp = lodepng_get_bpp(&info_png->color); - unsigned error = 0; + unsigned bpp = lodepng_get_bpp(&info_png->color); + unsigned error = 0; - if(info_png->interlace_method == 0) - { - *outsize = h + (h * ((w * bpp + 7) / 8)); /*image size plus an extra byte per scanline + possible padding bits*/ - *out = (unsigned char*)lodepng_malloc(*outsize); - if(!(*out) && (*outsize)) error = 83; /*alloc fail*/ + if (info_png->interlace_method == 0) + { + *outsize = h + (h * ((w * bpp + 7) / 8)); /*image size plus an extra byte per scanline + possible padding bits*/ + *out = (unsigned char*)lodepng_malloc(*outsize); + if (!(*out) && (*outsize)) error = 83; /*alloc fail*/ - if(!error) - { - /*non multiple of 8 bits per scanline, padding bits needed per scanline*/ - if(bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8) - { - unsigned char* padded = (unsigned char*)lodepng_malloc(h * ((w * bpp + 7) / 8)); - if(!padded) error = 83; /*alloc fail*/ - if(!error) - { - addPaddingBits(padded, in, ((w * bpp + 7) / 8) * 8, w * bpp, h); - error = filter(*out, padded, w, h, &info_png->color, settings); - } - lodepng_free(padded); - } - else - { - /*we can immediatly filter into the out buffer, no other steps needed*/ - error = filter(*out, in, w, h, &info_png->color, settings); - } - } - } - else /*interlace_method is 1 (Adam7)*/ - { - unsigned passw[7], passh[7]; - size_t filter_passstart[8], padded_passstart[8], passstart[8]; - unsigned char* adam7; + if (!error) + { + /*non multiple of 8 bits per scanline, padding bits needed per scanline*/ + if (bpp < 8 && w * bpp != ((w * bpp + 7) / 8) * 8) + { + unsigned char* padded = (unsigned char*)lodepng_malloc(h * ((w * bpp + 7) / 8)); + if (!padded) error = 83; /*alloc fail*/ + if (!error) + { + addPaddingBits(padded, in, ((w * bpp + 7) / 8) * 8, w * bpp, h); + error = filter(*out, padded, w, h, &info_png->color, settings); + } + lodepng_free(padded); + } + else + { + /*we can immediatly filter into the out buffer, no other steps needed*/ + error = filter(*out, in, w, h, &info_png->color, settings); + } + } + } + else /*interlace_method is 1 (Adam7)*/ + { + unsigned passw[7], passh[7]; + size_t filter_passstart[8], padded_passstart[8], passstart[8]; + unsigned char* adam7; - Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); + Adam7_getpassvalues(passw, passh, filter_passstart, padded_passstart, passstart, w, h, bpp); - *outsize = filter_passstart[7]; /*image size plus an extra byte per scanline + possible padding bits*/ - *out = (unsigned char*)lodepng_malloc(*outsize); - if(!(*out)) error = 83; /*alloc fail*/ + *outsize = filter_passstart[7]; /*image size plus an extra byte per scanline + possible padding bits*/ + *out = (unsigned char*)lodepng_malloc(*outsize); + if (!(*out)) error = 83; /*alloc fail*/ - adam7 = (unsigned char*)lodepng_malloc(passstart[7]); - if(!adam7 && passstart[7]) error = 83; /*alloc fail*/ + adam7 = (unsigned char*)lodepng_malloc(passstart[7]); + if (!adam7 && passstart[7]) error = 83; /*alloc fail*/ - if(!error) - { - unsigned i; + if (!error) + { + unsigned i; - Adam7_interlace(adam7, in, w, h, bpp); - for(i = 0; i < 7; i++) - { - if(bpp < 8) - { - unsigned char* padded = (unsigned char*)lodepng_malloc(padded_passstart[i + 1] - padded_passstart[i]); - if(!padded) ERROR_BREAK(83); /*alloc fail*/ - addPaddingBits(padded, &adam7[passstart[i]], - ((passw[i] * bpp + 7) / 8) * 8, passw[i] * bpp, passh[i]); - error = filter(&(*out)[filter_passstart[i]], padded, - passw[i], passh[i], &info_png->color, settings); - lodepng_free(padded); - } - else - { - error = filter(&(*out)[filter_passstart[i]], &adam7[padded_passstart[i]], - passw[i], passh[i], &info_png->color, settings); - } + Adam7_interlace(adam7, in, w, h, bpp); + for (i = 0; i < 7; i++) + { + if (bpp < 8) + { + unsigned char* padded = (unsigned char*)lodepng_malloc(padded_passstart[i + 1] - padded_passstart[i]); + if (!padded) ERROR_BREAK(83); /*alloc fail*/ + addPaddingBits(padded, &adam7[passstart[i]], + ((passw[i] * bpp + 7) / 8) * 8, passw[i] * bpp, passh[i]); + error = filter(&(*out)[filter_passstart[i]], padded, + passw[i], passh[i], &info_png->color, settings); + lodepng_free(padded); + } + else + { + error = filter(&(*out)[filter_passstart[i]], &adam7[padded_passstart[i]], + passw[i], passh[i], &info_png->color, settings); + } - if(error) break; - } - } + if (error) break; + } + } - lodepng_free(adam7); - } + lodepng_free(adam7); + } - return error; + return error; } /* @@ -5476,291 +5582,295 @@ returns 2 if the palette is semi-translucent. */ static unsigned getPaletteTranslucency(const unsigned char* palette, size_t palettesize) { - size_t i; - unsigned key = 0; - unsigned r = 0, g = 0, b = 0; /*the value of the color with alpha 0, so long as color keying is possible*/ - for(i = 0; i < palettesize; i++) - { - if(!key && palette[4 * i + 3] == 0) - { - r = palette[4 * i + 0]; g = palette[4 * i + 1]; b = palette[4 * i + 2]; - key = 1; - i = (size_t)(-1); /*restart from beginning, to detect earlier opaque colors with key's value*/ - } - else if(palette[4 * i + 3] != 255) return 2; - /*when key, no opaque RGB may have key's RGB*/ - else if(key && r == palette[i * 4 + 0] && g == palette[i * 4 + 1] && b == palette[i * 4 + 2]) return 2; - } - return key; + size_t i; + unsigned key = 0; + unsigned r = 0, g = 0, b = 0; /*the value of the color with alpha 0, so long as color keying is possible*/ + for (i = 0; i < palettesize; i++) + { + if (!key && palette[4 * i + 3] == 0) + { + r = palette[4 * i + 0]; + g = palette[4 * i + 1]; + b = palette[4 * i + 2]; + key = 1; + i = (size_t)(-1); /*restart from beginning, to detect earlier opaque colors with key's value*/ + } + else if (palette[4 * i + 3] != 255) + return 2; + /*when key, no opaque RGB may have key's RGB*/ + else if (key && r == palette[i * 4 + 0] && g == palette[i * 4 + 1] && b == palette[i * 4 + 2]) + return 2; + } + return key; } #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS static unsigned addUnknownChunks(ucvector* out, unsigned char* data, size_t datasize) { - unsigned char* inchunk = data; - while((size_t)(inchunk - data) < datasize) - { - CERROR_TRY_RETURN(lodepng_chunk_append(&out->data, &out->size, inchunk)); - out->allocsize = out->size; /*fix the allocsize again*/ - inchunk = lodepng_chunk_next(inchunk); - } - return 0; + unsigned char* inchunk = data; + while ((size_t)(inchunk - data) < datasize) + { + CERROR_TRY_RETURN(lodepng_chunk_append(&out->data, &out->size, inchunk)); + out->allocsize = out->size; /*fix the allocsize again*/ + inchunk = lodepng_chunk_next(inchunk); + } + return 0; } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ unsigned lodepng_encode(unsigned char** out, size_t* outsize, - const unsigned char* image, unsigned w, unsigned h, - LodePNGState* state) + const unsigned char* image, unsigned w, unsigned h, + LodePNGState* state) { - LodePNGInfo info; - ucvector outv; - unsigned char* data = 0; /*uncompressed version of the IDAT chunk data*/ - size_t datasize = 0; + LodePNGInfo info; + ucvector outv; + unsigned char* data = 0; /*uncompressed version of the IDAT chunk data*/ + size_t datasize = 0; - /*provide some proper output values if error will happen*/ - *out = 0; - *outsize = 0; - state->error = 0; + /*provide some proper output values if error will happen*/ + *out = 0; + *outsize = 0; + state->error = 0; - lodepng_info_init(&info); - lodepng_info_copy(&info, &state->info_png); + lodepng_info_init(&info); + lodepng_info_copy(&info, &state->info_png); - if((info.color.colortype == LCT_PALETTE || state->encoder.force_palette) - && (info.color.palettesize == 0 || info.color.palettesize > 256)) - { - state->error = 68; /*invalid palette size, it is only allowed to be 1-256*/ - return state->error; - } + if ((info.color.colortype == LCT_PALETTE || state->encoder.force_palette) && (info.color.palettesize == 0 || info.color.palettesize > 256)) + { + state->error = 68; /*invalid palette size, it is only allowed to be 1-256*/ + return state->error; + } - if(state->encoder.auto_convert) - { - state->error = lodepng_auto_choose_color(&info.color, image, w, h, &state->info_raw); - } - if(state->error) return state->error; + if (state->encoder.auto_convert) + { + state->error = lodepng_auto_choose_color(&info.color, image, w, h, &state->info_raw); + } + if (state->error) return state->error; - if(state->encoder.zlibsettings.btype > 2) - { - CERROR_RETURN_ERROR(state->error, 61); /*error: unexisting btype*/ - } - if(state->info_png.interlace_method > 1) - { - CERROR_RETURN_ERROR(state->error, 71); /*error: unexisting interlace mode*/ - } + if (state->encoder.zlibsettings.btype > 2) + { + CERROR_RETURN_ERROR(state->error, 61); /*error: unexisting btype*/ + } + if (state->info_png.interlace_method > 1) + { + CERROR_RETURN_ERROR(state->error, 71); /*error: unexisting interlace mode*/ + } - state->error = checkColorValidity(info.color.colortype, info.color.bitdepth); - if(state->error) return state->error; /*error: unexisting color type given*/ - state->error = checkColorValidity(state->info_raw.colortype, state->info_raw.bitdepth); - if(state->error) return state->error; /*error: unexisting color type given*/ + state->error = checkColorValidity(info.color.colortype, info.color.bitdepth); + if (state->error) return state->error; /*error: unexisting color type given*/ + state->error = checkColorValidity(state->info_raw.colortype, state->info_raw.bitdepth); + if (state->error) return state->error; /*error: unexisting color type given*/ - if(!lodepng_color_mode_equal(&state->info_raw, &info.color)) - { - unsigned char* converted; - size_t size = (w * h * lodepng_get_bpp(&info.color) + 7) / 8; + if (!lodepng_color_mode_equal(&state->info_raw, &info.color)) + { + unsigned char* converted; + size_t size = (w * h * lodepng_get_bpp(&info.color) + 7) / 8; - converted = (unsigned char*)lodepng_malloc(size); - if(!converted && size) state->error = 83; /*alloc fail*/ - if(!state->error) - { - state->error = lodepng_convert(converted, image, &info.color, &state->info_raw, w, h); - } - if(!state->error) preProcessScanlines(&data, &datasize, converted, w, h, &info, &state->encoder); - lodepng_free(converted); - } - else preProcessScanlines(&data, &datasize, image, w, h, &info, &state->encoder); + converted = (unsigned char*)lodepng_malloc(size); + if (!converted && size) state->error = 83; /*alloc fail*/ + if (!state->error) + { + state->error = lodepng_convert(converted, image, &info.color, &state->info_raw, w, h); + } + if (!state->error) preProcessScanlines(&data, &datasize, converted, w, h, &info, &state->encoder); + lodepng_free(converted); + } + else + preProcessScanlines(&data, &datasize, image, w, h, &info, &state->encoder); - ucvector_init(&outv); - while(!state->error) /*while only executed once, to break on error*/ - { + ucvector_init(&outv); + while (!state->error) /*while only executed once, to break on error*/ + { #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - size_t i; + size_t i; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - /*write signature and chunks*/ - writeSignature(&outv); - /*IHDR*/ - addChunk_IHDR(&outv, w, h, info.color.colortype, info.color.bitdepth, info.interlace_method); + /*write signature and chunks*/ + writeSignature(&outv); + /*IHDR*/ + addChunk_IHDR(&outv, w, h, info.color.colortype, info.color.bitdepth, info.interlace_method); #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - /*unknown chunks between IHDR and PLTE*/ - if(info.unknown_chunks_data[0]) - { - state->error = addUnknownChunks(&outv, info.unknown_chunks_data[0], info.unknown_chunks_size[0]); - if(state->error) break; - } + /*unknown chunks between IHDR and PLTE*/ + if (info.unknown_chunks_data[0]) + { + state->error = addUnknownChunks(&outv, info.unknown_chunks_data[0], info.unknown_chunks_size[0]); + if (state->error) break; + } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - /*PLTE*/ - if(info.color.colortype == LCT_PALETTE) - { - addChunk_PLTE(&outv, &info.color); - } - if(state->encoder.force_palette && (info.color.colortype == LCT_RGB || info.color.colortype == LCT_RGBA)) - { - addChunk_PLTE(&outv, &info.color); - } - /*tRNS*/ - if(info.color.colortype == LCT_PALETTE && getPaletteTranslucency(info.color.palette, info.color.palettesize) != 0) - { - addChunk_tRNS(&outv, &info.color); - } - if((info.color.colortype == LCT_GREY || info.color.colortype == LCT_RGB) && info.color.key_defined) - { - addChunk_tRNS(&outv, &info.color); - } + /*PLTE*/ + if (info.color.colortype == LCT_PALETTE) + { + addChunk_PLTE(&outv, &info.color); + } + if (state->encoder.force_palette && (info.color.colortype == LCT_RGB || info.color.colortype == LCT_RGBA)) + { + addChunk_PLTE(&outv, &info.color); + } + /*tRNS*/ + if (info.color.colortype == LCT_PALETTE && getPaletteTranslucency(info.color.palette, info.color.palettesize) != 0) + { + addChunk_tRNS(&outv, &info.color); + } + if ((info.color.colortype == LCT_GREY || info.color.colortype == LCT_RGB) && info.color.key_defined) + { + addChunk_tRNS(&outv, &info.color); + } #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - /*bKGD (must come between PLTE and the IDAt chunks*/ - if(info.background_defined) addChunk_bKGD(&outv, &info); - /*pHYs (must come before the IDAT chunks)*/ - if(info.phys_defined) addChunk_pHYs(&outv, &info); + /*bKGD (must come between PLTE and the IDAt chunks*/ + if (info.background_defined) addChunk_bKGD(&outv, &info); + /*pHYs (must come before the IDAT chunks)*/ + if (info.phys_defined) addChunk_pHYs(&outv, &info); - /*unknown chunks between PLTE and IDAT*/ - if(info.unknown_chunks_data[1]) - { - state->error = addUnknownChunks(&outv, info.unknown_chunks_data[1], info.unknown_chunks_size[1]); - if(state->error) break; - } + /*unknown chunks between PLTE and IDAT*/ + if (info.unknown_chunks_data[1]) + { + state->error = addUnknownChunks(&outv, info.unknown_chunks_data[1], info.unknown_chunks_size[1]); + if (state->error) break; + } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - /*IDAT (multiple IDAT chunks must be consecutive)*/ - state->error = addChunk_IDAT(&outv, data, datasize, &state->encoder.zlibsettings); - if(state->error) break; + /*IDAT (multiple IDAT chunks must be consecutive)*/ + state->error = addChunk_IDAT(&outv, data, datasize, &state->encoder.zlibsettings); + if (state->error) break; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - /*tIME*/ - if(info.time_defined) addChunk_tIME(&outv, &info.time); - /*tEXt and/or zTXt*/ - for(i = 0; i < info.text_num; i++) - { - if(strlen(info.text_keys[i]) > 79) - { - state->error = 66; /*text chunk too large*/ - break; - } - if(strlen(info.text_keys[i]) < 1) - { - state->error = 67; /*text chunk too small*/ - break; - } - if(state->encoder.text_compression) - { - addChunk_zTXt(&outv, info.text_keys[i], info.text_strings[i], &state->encoder.zlibsettings); - } - else - { - addChunk_tEXt(&outv, info.text_keys[i], info.text_strings[i]); - } - } - /*LodePNG version id in text chunk*/ - if(state->encoder.add_id) - { - unsigned alread_added_id_text = 0; - for(i = 0; i < info.text_num; i++) - { - if(!strcmp(info.text_keys[i], "LodePNG")) - { - alread_added_id_text = 1; - break; - } - } - if(alread_added_id_text == 0) - { - addChunk_tEXt(&outv, "LodePNG", VERSION_STRING); /*it's shorter as tEXt than as zTXt chunk*/ - } - } - /*iTXt*/ - for(i = 0; i < info.itext_num; i++) - { - if(strlen(info.itext_keys[i]) > 79) - { - state->error = 66; /*text chunk too large*/ - break; - } - if(strlen(info.itext_keys[i]) < 1) - { - state->error = 67; /*text chunk too small*/ - break; - } - addChunk_iTXt(&outv, state->encoder.text_compression, - info.itext_keys[i], info.itext_langtags[i], info.itext_transkeys[i], info.itext_strings[i], - &state->encoder.zlibsettings); - } + /*tIME*/ + if (info.time_defined) addChunk_tIME(&outv, &info.time); + /*tEXt and/or zTXt*/ + for (i = 0; i < info.text_num; i++) + { + if (strlen(info.text_keys[i]) > 79) + { + state->error = 66; /*text chunk too large*/ + break; + } + if (strlen(info.text_keys[i]) < 1) + { + state->error = 67; /*text chunk too small*/ + break; + } + if (state->encoder.text_compression) + { + addChunk_zTXt(&outv, info.text_keys[i], info.text_strings[i], &state->encoder.zlibsettings); + } + else + { + addChunk_tEXt(&outv, info.text_keys[i], info.text_strings[i]); + } + } + /*LodePNG version id in text chunk*/ + if (state->encoder.add_id) + { + unsigned alread_added_id_text = 0; + for (i = 0; i < info.text_num; i++) + { + if (!strcmp(info.text_keys[i], "LodePNG")) + { + alread_added_id_text = 1; + break; + } + } + if (alread_added_id_text == 0) + { + addChunk_tEXt(&outv, "LodePNG", VERSION_STRING); /*it's shorter as tEXt than as zTXt chunk*/ + } + } + /*iTXt*/ + for (i = 0; i < info.itext_num; i++) + { + if (strlen(info.itext_keys[i]) > 79) + { + state->error = 66; /*text chunk too large*/ + break; + } + if (strlen(info.itext_keys[i]) < 1) + { + state->error = 67; /*text chunk too small*/ + break; + } + addChunk_iTXt(&outv, state->encoder.text_compression, + info.itext_keys[i], info.itext_langtags[i], info.itext_transkeys[i], info.itext_strings[i], + &state->encoder.zlibsettings); + } - /*unknown chunks between IDAT and IEND*/ - if(info.unknown_chunks_data[2]) - { - state->error = addUnknownChunks(&outv, info.unknown_chunks_data[2], info.unknown_chunks_size[2]); - if(state->error) break; - } + /*unknown chunks between IDAT and IEND*/ + if (info.unknown_chunks_data[2]) + { + state->error = addUnknownChunks(&outv, info.unknown_chunks_data[2], info.unknown_chunks_size[2]); + if (state->error) break; + } #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ - addChunk_IEND(&outv); + addChunk_IEND(&outv); - break; /*this isn't really a while loop; no error happened so break out now!*/ - } + break; /*this isn't really a while loop; no error happened so break out now!*/ + } - lodepng_info_cleanup(&info); - lodepng_free(data); - /*instead of cleaning the vector up, give it to the output*/ - *out = outv.data; - *outsize = outv.size; + lodepng_info_cleanup(&info); + lodepng_free(data); + /*instead of cleaning the vector up, give it to the output*/ + *out = outv.data; + *outsize = outv.size; - return state->error; + return state->error; } unsigned lodepng_encode_memory(unsigned char** out, size_t* outsize, const unsigned char* image, - unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) + unsigned w, unsigned h, LodePNGColorType colortype, unsigned bitdepth) { - unsigned error; - LodePNGState state; - lodepng_state_init(&state); - state.info_raw.colortype = colortype; - state.info_raw.bitdepth = bitdepth; - state.info_png.color.colortype = colortype; - state.info_png.color.bitdepth = bitdepth; - lodepng_encode(out, outsize, image, w, h, &state); - error = state.error; - lodepng_state_cleanup(&state); - return error; + unsigned error; + LodePNGState state; + lodepng_state_init(&state); + state.info_raw.colortype = colortype; + state.info_raw.bitdepth = bitdepth; + state.info_png.color.colortype = colortype; + state.info_png.color.bitdepth = bitdepth; + lodepng_encode(out, outsize, image, w, h, &state); + error = state.error; + lodepng_state_cleanup(&state); + return error; } unsigned lodepng_encode32(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h) { - return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGBA, 8); + return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGBA, 8); } unsigned lodepng_encode24(unsigned char** out, size_t* outsize, const unsigned char* image, unsigned w, unsigned h) { - return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGB, 8); + return lodepng_encode_memory(out, outsize, image, w, h, LCT_RGB, 8); } #ifdef LODEPNG_COMPILE_DISK unsigned lodepng_encode_file(const char* filename, const unsigned char* image, unsigned w, unsigned h, - LodePNGColorType colortype, unsigned bitdepth) + LodePNGColorType colortype, unsigned bitdepth) { - unsigned char* buffer; - size_t buffersize; - unsigned error = lodepng_encode_memory(&buffer, &buffersize, image, w, h, colortype, bitdepth); - if(!error) error = lodepng_save_file(buffer, buffersize, filename); - lodepng_free(buffer); - return error; + unsigned char* buffer; + size_t buffersize; + unsigned error = lodepng_encode_memory(&buffer, &buffersize, image, w, h, colortype, bitdepth); + if (!error) error = lodepng_save_file(buffer, buffersize, filename); + lodepng_free(buffer); + return error; } unsigned lodepng_encode32_file(const char* filename, const unsigned char* image, unsigned w, unsigned h) { - return lodepng_encode_file(filename, image, w, h, LCT_RGBA, 8); + return lodepng_encode_file(filename, image, w, h, LCT_RGBA, 8); } unsigned lodepng_encode24_file(const char* filename, const unsigned char* image, unsigned w, unsigned h) { - return lodepng_encode_file(filename, image, w, h, LCT_RGB, 8); + return lodepng_encode_file(filename, image, w, h, LCT_RGB, 8); } #endif /*LODEPNG_COMPILE_DISK*/ void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings) { - lodepng_compress_settings_init(&settings->zlibsettings); - settings->filter_palette_zero = 1; - settings->filter_strategy = LFS_MINSUM; - settings->auto_convert = 1; - settings->force_palette = 0; - settings->predefined_filters = 0; + lodepng_compress_settings_init(&settings->zlibsettings); + settings->filter_palette_zero = 1; + settings->filter_strategy = LFS_MINSUM; + settings->auto_convert = 1; + settings->force_palette = 0; + settings->predefined_filters = 0; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - settings->add_id = 0; - settings->text_compression = 1; + settings->add_id = 0; + settings->text_compression = 1; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } @@ -5774,100 +5884,177 @@ the documentation of all the error codes. */ const char* lodepng_error_text(unsigned code) { - switch(code) - { - case 0: return "no error, everything went ok"; - case 1: return "nothing done yet"; /*the Encoder/Decoder has done nothing yet, error checking makes no sense yet*/ - case 10: return "end of input memory reached without huffman end code"; /*while huffman decoding*/ - case 11: return "error in code tree made it jump outside of huffman tree"; /*while huffman decoding*/ - case 13: return "problem while processing dynamic deflate block"; - case 14: return "problem while processing dynamic deflate block"; - case 15: return "problem while processing dynamic deflate block"; - case 16: return "unexisting code while processing dynamic deflate block"; - case 17: return "end of out buffer memory reached while inflating"; - case 18: return "invalid distance code while inflating"; - case 19: return "end of out buffer memory reached while inflating"; - case 20: return "invalid deflate block BTYPE encountered while decoding"; - case 21: return "NLEN is not ones complement of LEN in a deflate block"; - /*end of out buffer memory reached while inflating: + switch (code) + { + case 0: + return "no error, everything went ok"; + case 1: + return "nothing done yet"; /*the Encoder/Decoder has done nothing yet, error checking makes no sense yet*/ + case 10: + return "end of input memory reached without huffman end code"; /*while huffman decoding*/ + case 11: + return "error in code tree made it jump outside of huffman tree"; /*while huffman decoding*/ + case 13: + return "problem while processing dynamic deflate block"; + case 14: + return "problem while processing dynamic deflate block"; + case 15: + return "problem while processing dynamic deflate block"; + case 16: + return "unexisting code while processing dynamic deflate block"; + case 17: + return "end of out buffer memory reached while inflating"; + case 18: + return "invalid distance code while inflating"; + case 19: + return "end of out buffer memory reached while inflating"; + case 20: + return "invalid deflate block BTYPE encountered while decoding"; + case 21: + return "NLEN is not ones complement of LEN in a deflate block"; + /*end of out buffer memory reached while inflating: This can happen if the inflated deflate data is longer than the amount of bytes required to fill up all the pixels of the image, given the color depth and image dimensions. Something that doesn't happen in a normal, well encoded, PNG image.*/ - case 22: return "end of out buffer memory reached while inflating"; - case 23: return "end of in buffer memory reached while inflating"; - case 24: return "invalid FCHECK in zlib header"; - case 25: return "invalid compression method in zlib header"; - case 26: return "FDICT encountered in zlib header while it's not used for PNG"; - case 27: return "PNG file is smaller than a PNG header"; - /*Checks the magic file header, the first 8 bytes of the PNG file*/ - case 28: return "incorrect PNG signature, it's no PNG or corrupted"; - case 29: return "first chunk is not the header chunk"; - case 30: return "chunk length too large, chunk broken off at end of file"; - case 31: return "illegal PNG color type or bpp"; - case 32: return "illegal PNG compression method"; - case 33: return "illegal PNG filter method"; - case 34: return "illegal PNG interlace method"; - case 35: return "chunk length of a chunk is too large or the chunk too small"; - case 36: return "illegal PNG filter type encountered"; - case 37: return "illegal bit depth for this color type given"; - case 38: return "the palette is too big"; /*more than 256 colors*/ - case 39: return "more palette alpha values given in tRNS chunk than there are colors in the palette"; - case 40: return "tRNS chunk has wrong size for greyscale image"; - case 41: return "tRNS chunk has wrong size for RGB image"; - case 42: return "tRNS chunk appeared while it was not allowed for this color type"; - case 43: return "bKGD chunk has wrong size for palette image"; - case 44: return "bKGD chunk has wrong size for greyscale image"; - case 45: return "bKGD chunk has wrong size for RGB image"; - /*the input data is empty, maybe a PNG file doesn't exist or is in the wrong path*/ - case 48: return "empty input or file doesn't exist"; - case 49: return "jumped past memory while generating dynamic huffman tree"; - case 50: return "jumped past memory while generating dynamic huffman tree"; - case 51: return "jumped past memory while inflating huffman block"; - case 52: return "jumped past memory while inflating"; - case 53: return "size of zlib data too small"; - case 54: return "repeat symbol in tree while there was no value symbol yet"; - /*jumped past tree while generating huffman tree, this could be when the + case 22: + return "end of out buffer memory reached while inflating"; + case 23: + return "end of in buffer memory reached while inflating"; + case 24: + return "invalid FCHECK in zlib header"; + case 25: + return "invalid compression method in zlib header"; + case 26: + return "FDICT encountered in zlib header while it's not used for PNG"; + case 27: + return "PNG file is smaller than a PNG header"; + /*Checks the magic file header, the first 8 bytes of the PNG file*/ + case 28: + return "incorrect PNG signature, it's no PNG or corrupted"; + case 29: + return "first chunk is not the header chunk"; + case 30: + return "chunk length too large, chunk broken off at end of file"; + case 31: + return "illegal PNG color type or bpp"; + case 32: + return "illegal PNG compression method"; + case 33: + return "illegal PNG filter method"; + case 34: + return "illegal PNG interlace method"; + case 35: + return "chunk length of a chunk is too large or the chunk too small"; + case 36: + return "illegal PNG filter type encountered"; + case 37: + return "illegal bit depth for this color type given"; + case 38: + return "the palette is too big"; /*more than 256 colors*/ + case 39: + return "more palette alpha values given in tRNS chunk than there are colors in the palette"; + case 40: + return "tRNS chunk has wrong size for greyscale image"; + case 41: + return "tRNS chunk has wrong size for RGB image"; + case 42: + return "tRNS chunk appeared while it was not allowed for this color type"; + case 43: + return "bKGD chunk has wrong size for palette image"; + case 44: + return "bKGD chunk has wrong size for greyscale image"; + case 45: + return "bKGD chunk has wrong size for RGB image"; + /*the input data is empty, maybe a PNG file doesn't exist or is in the wrong path*/ + case 48: + return "empty input or file doesn't exist"; + case 49: + return "jumped past memory while generating dynamic huffman tree"; + case 50: + return "jumped past memory while generating dynamic huffman tree"; + case 51: + return "jumped past memory while inflating huffman block"; + case 52: + return "jumped past memory while inflating"; + case 53: + return "size of zlib data too small"; + case 54: + return "repeat symbol in tree while there was no value symbol yet"; + /*jumped past tree while generating huffman tree, this could be when the tree will have more leaves than symbols after generating it out of the given lenghts. They call this an oversubscribed dynamic bit lengths tree in zlib.*/ - case 55: return "jumped past tree while generating huffman tree"; - case 56: return "given output image colortype or bitdepth not supported for color conversion"; - case 57: return "invalid CRC encountered (checking CRC can be disabled)"; - case 58: return "invalid ADLER32 encountered (checking ADLER32 can be disabled)"; - case 59: return "requested color conversion not supported"; - case 60: return "invalid window size given in the settings of the encoder (must be 0-32768)"; - case 61: return "invalid BTYPE given in the settings of the encoder (only 0, 1 and 2 are allowed)"; - /*LodePNG leaves the choice of RGB to greyscale conversion formula to the user.*/ - case 62: return "conversion from color to greyscale not supported"; - case 63: return "length of a chunk too long, max allowed for PNG is 2147483647 bytes per chunk"; /*(2^31-1)*/ - /*this would result in the inability of a deflated block to ever contain an end code. It must be at least 1.*/ - case 64: return "the length of the END symbol 256 in the Huffman tree is 0"; - case 66: return "the length of a text chunk keyword given to the encoder is longer than the maximum of 79 bytes"; - case 67: return "the length of a text chunk keyword given to the encoder is smaller than the minimum of 1 byte"; - case 68: return "tried to encode a PLTE chunk with a palette that has less than 1 or more than 256 colors"; - case 69: return "unknown chunk type with 'critical' flag encountered by the decoder"; - case 71: return "unexisting interlace mode given to encoder (must be 0 or 1)"; - case 72: return "while decoding, unexisting compression method encountering in zTXt or iTXt chunk (it must be 0)"; - case 73: return "invalid tIME chunk size"; - case 74: return "invalid pHYs chunk size"; - /*length could be wrong, or data chopped off*/ - case 75: return "no null termination char found while decoding text chunk"; - case 76: return "iTXt chunk too short to contain required bytes"; - case 77: return "integer overflow in buffer size"; - case 78: return "failed to open file for reading"; /*file doesn't exist or couldn't be opened for reading*/ - case 79: return "failed to open file for writing"; - case 80: return "tried creating a tree of 0 symbols"; - case 81: return "lazy matching at pos 0 is impossible"; - case 82: return "color conversion to palette requested while a color isn't in palette"; - case 83: return "memory allocation failed"; - case 84: return "given image too small to contain all pixels to be encoded"; - case 86: return "impossible offset in lz77 encoding (internal bug)"; - case 87: return "must provide custom zlib function pointer if LODEPNG_COMPILE_ZLIB is not defined"; - case 88: return "invalid filter strategy given for LodePNGEncoderSettings.filter_strategy"; - case 89: return "text chunk keyword too short or long: must have size 1-79"; - /*the windowsize in the LodePNGCompressSettings. Requiring POT(==> & instead of %) makes encoding 12% faster.*/ - case 90: return "windowsize must be a power of two"; - } - return "unknown error code"; + case 55: + return "jumped past tree while generating huffman tree"; + case 56: + return "given output image colortype or bitdepth not supported for color conversion"; + case 57: + return "invalid CRC encountered (checking CRC can be disabled)"; + case 58: + return "invalid ADLER32 encountered (checking ADLER32 can be disabled)"; + case 59: + return "requested color conversion not supported"; + case 60: + return "invalid window size given in the settings of the encoder (must be 0-32768)"; + case 61: + return "invalid BTYPE given in the settings of the encoder (only 0, 1 and 2 are allowed)"; + /*LodePNG leaves the choice of RGB to greyscale conversion formula to the user.*/ + case 62: + return "conversion from color to greyscale not supported"; + case 63: + return "length of a chunk too long, max allowed for PNG is 2147483647 bytes per chunk"; /*(2^31-1)*/ + /*this would result in the inability of a deflated block to ever contain an end code. It must be at least 1.*/ + case 64: + return "the length of the END symbol 256 in the Huffman tree is 0"; + case 66: + return "the length of a text chunk keyword given to the encoder is longer than the maximum of 79 bytes"; + case 67: + return "the length of a text chunk keyword given to the encoder is smaller than the minimum of 1 byte"; + case 68: + return "tried to encode a PLTE chunk with a palette that has less than 1 or more than 256 colors"; + case 69: + return "unknown chunk type with 'critical' flag encountered by the decoder"; + case 71: + return "unexisting interlace mode given to encoder (must be 0 or 1)"; + case 72: + return "while decoding, unexisting compression method encountering in zTXt or iTXt chunk (it must be 0)"; + case 73: + return "invalid tIME chunk size"; + case 74: + return "invalid pHYs chunk size"; + /*length could be wrong, or data chopped off*/ + case 75: + return "no null termination char found while decoding text chunk"; + case 76: + return "iTXt chunk too short to contain required bytes"; + case 77: + return "integer overflow in buffer size"; + case 78: + return "failed to open file for reading"; /*file doesn't exist or couldn't be opened for reading*/ + case 79: + return "failed to open file for writing"; + case 80: + return "tried creating a tree of 0 symbols"; + case 81: + return "lazy matching at pos 0 is impossible"; + case 82: + return "color conversion to palette requested while a color isn't in palette"; + case 83: + return "memory allocation failed"; + case 84: + return "given image too small to contain all pixels to be encoded"; + case 86: + return "impossible offset in lz77 encoding (internal bug)"; + case 87: + return "must provide custom zlib function pointer if LODEPNG_COMPILE_ZLIB is not defined"; + case 88: + return "invalid filter strategy given for LodePNGEncoderSettings.filter_strategy"; + case 89: + return "text chunk keyword too short or long: must have size 1-79"; + /*the windowsize in the LodePNGCompressSettings. Requiring POT(==> & instead of %) makes encoding 12% faster.*/ + case 90: + return "windowsize must be a power of two"; + } + return "unknown error code"; } #endif /*LODEPNG_COMPILE_ERROR_TEXT*/ @@ -5880,225 +6067,223 @@ const char* lodepng_error_text(unsigned code) #ifdef LODEPNG_COMPILE_CPP namespace lodepng { - #ifdef LODEPNG_COMPILE_DISK void load_file(std::vector& buffer, const std::string& filename) { - std::ifstream file(filename.c_str(), std::ios::in|std::ios::binary|std::ios::ate); + std::ifstream file(filename.c_str(), std::ios::in | std::ios::binary | std::ios::ate); - /*get filesize*/ - std::streamsize size = 0; - if(file.seekg(0, std::ios::end).good()) size = file.tellg(); - if(file.seekg(0, std::ios::beg).good()) size -= file.tellg(); + /*get filesize*/ + std::streamsize size = 0; + if (file.seekg(0, std::ios::end).good()) size = file.tellg(); + if (file.seekg(0, std::ios::beg).good()) size -= file.tellg(); - /*read contents of the file into the vector*/ - buffer.resize(size_t(size)); - if(size > 0) file.read((char*)(&buffer[0]), size); + /*read contents of the file into the vector*/ + buffer.resize(size_t(size)); + if (size > 0) file.read((char*)(&buffer[0]), size); } /*write given buffer to the file, overwriting the file, it doesn't append to it.*/ void save_file(const std::vector& buffer, const std::string& filename) { - std::ofstream file(filename.c_str(), std::ios::out|std::ios::binary); - file.write(buffer.empty() ? 0 : (char*)&buffer[0], std::streamsize(buffer.size())); + std::ofstream file(filename.c_str(), std::ios::out | std::ios::binary); + file.write(buffer.empty() ? 0 : (char*)&buffer[0], std::streamsize(buffer.size())); } -#endif //LODEPNG_COMPILE_DISK +#endif //LODEPNG_COMPILE_DISK #ifdef LODEPNG_COMPILE_ZLIB #ifdef LODEPNG_COMPILE_DECODER unsigned decompress(std::vector& out, const unsigned char* in, size_t insize, - const LodePNGDecompressSettings& settings) + const LodePNGDecompressSettings& settings) { - unsigned char* buffer = 0; - size_t buffersize = 0; - unsigned error = zlib_decompress(&buffer, &buffersize, in, insize, &settings); - if(buffer) - { - out.insert(out.end(), &buffer[0], &buffer[buffersize]); - lodepng_free(buffer); - } - return error; + unsigned char* buffer = 0; + size_t buffersize = 0; + unsigned error = zlib_decompress(&buffer, &buffersize, in, insize, &settings); + if (buffer) + { + out.insert(out.end(), &buffer[0], &buffer[buffersize]); + lodepng_free(buffer); + } + return error; } unsigned decompress(std::vector& out, const std::vector& in, - const LodePNGDecompressSettings& settings) + const LodePNGDecompressSettings& settings) { - return decompress(out, in.empty() ? 0 : &in[0], in.size(), settings); + return decompress(out, in.empty() ? 0 : &in[0], in.size(), settings); } -#endif //LODEPNG_COMPILE_DECODER +#endif //LODEPNG_COMPILE_DECODER #ifdef LODEPNG_COMPILE_ENCODER unsigned compress(std::vector& out, const unsigned char* in, size_t insize, - const LodePNGCompressSettings& settings) + const LodePNGCompressSettings& settings) { - unsigned char* buffer = 0; - size_t buffersize = 0; - unsigned error = zlib_compress(&buffer, &buffersize, in, insize, &settings); - if(buffer) - { - out.insert(out.end(), &buffer[0], &buffer[buffersize]); - lodepng_free(buffer); - } - return error; + unsigned char* buffer = 0; + size_t buffersize = 0; + unsigned error = zlib_compress(&buffer, &buffersize, in, insize, &settings); + if (buffer) + { + out.insert(out.end(), &buffer[0], &buffer[buffersize]); + lodepng_free(buffer); + } + return error; } unsigned compress(std::vector& out, const std::vector& in, - const LodePNGCompressSettings& settings) + const LodePNGCompressSettings& settings) { - return compress(out, in.empty() ? 0 : &in[0], in.size(), settings); + return compress(out, in.empty() ? 0 : &in[0], in.size(), settings); } -#endif //LODEPNG_COMPILE_ENCODER -#endif //LODEPNG_COMPILE_ZLIB - +#endif //LODEPNG_COMPILE_ENCODER +#endif //LODEPNG_COMPILE_ZLIB #ifdef LODEPNG_COMPILE_PNG State::State() { - lodepng_state_init(this); + lodepng_state_init(this); } State::State(const State& other) { - lodepng_state_init(this); - lodepng_state_copy(this, &other); + lodepng_state_init(this); + lodepng_state_copy(this, &other); } State::~State() { - lodepng_state_cleanup(this); + lodepng_state_cleanup(this); } State& State::operator=(const State& other) { - lodepng_state_copy(this, &other); - return *this; + lodepng_state_copy(this, &other); + return *this; } #ifdef LODEPNG_COMPILE_DECODER unsigned decode(std::vector& out, unsigned& w, unsigned& h, const unsigned char* in, - size_t insize, LodePNGColorType colortype, unsigned bitdepth) + size_t insize, LodePNGColorType colortype, unsigned bitdepth) { - unsigned char* buffer; - unsigned error = lodepng_decode_memory(&buffer, &w, &h, in, insize, colortype, bitdepth); - if(buffer && !error) - { - State state; - state.info_raw.colortype = colortype; - state.info_raw.bitdepth = bitdepth; - size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw); - out.insert(out.end(), &buffer[0], &buffer[buffersize]); - lodepng_free(buffer); - } - return error; + unsigned char* buffer; + unsigned error = lodepng_decode_memory(&buffer, &w, &h, in, insize, colortype, bitdepth); + if (buffer && !error) + { + State state; + state.info_raw.colortype = colortype; + state.info_raw.bitdepth = bitdepth; + size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw); + out.insert(out.end(), &buffer[0], &buffer[buffersize]); + lodepng_free(buffer); + } + return error; } unsigned decode(std::vector& out, unsigned& w, unsigned& h, - const std::vector& in, LodePNGColorType colortype, unsigned bitdepth) + const std::vector& in, LodePNGColorType colortype, unsigned bitdepth) { - return decode(out, w, h, in.empty() ? 0 : &in[0], (unsigned)in.size(), colortype, bitdepth); + return decode(out, w, h, in.empty() ? 0 : &in[0], (unsigned)in.size(), colortype, bitdepth); } unsigned decode(std::vector& out, unsigned& w, unsigned& h, - State& state, - const unsigned char* in, size_t insize) + State& state, + const unsigned char* in, size_t insize) { - unsigned char* buffer = NULL; - unsigned error = lodepng_decode(&buffer, &w, &h, &state, in, insize); - if(buffer && !error) - { - size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw); - out.insert(out.end(), &buffer[0], &buffer[buffersize]); - } - lodepng_free(buffer); - return error; + unsigned char* buffer = NULL; + unsigned error = lodepng_decode(&buffer, &w, &h, &state, in, insize); + if (buffer && !error) + { + size_t buffersize = lodepng_get_raw_size(w, h, &state.info_raw); + out.insert(out.end(), &buffer[0], &buffer[buffersize]); + } + lodepng_free(buffer); + return error; } unsigned decode(std::vector& out, unsigned& w, unsigned& h, - State& state, - const std::vector& in) + State& state, + const std::vector& in) { - return decode(out, w, h, state, in.empty() ? 0 : &in[0], in.size()); + return decode(out, w, h, state, in.empty() ? 0 : &in[0], in.size()); } #ifdef LODEPNG_COMPILE_DISK unsigned decode(std::vector& out, unsigned& w, unsigned& h, const std::string& filename, - LodePNGColorType colortype, unsigned bitdepth) + LodePNGColorType colortype, unsigned bitdepth) { - std::vector buffer; - load_file(buffer, filename); - return decode(out, w, h, buffer, colortype, bitdepth); + std::vector buffer; + load_file(buffer, filename); + return decode(out, w, h, buffer, colortype, bitdepth); } -#endif //LODEPNG_COMPILE_DECODER -#endif //LODEPNG_COMPILE_DISK +#endif //LODEPNG_COMPILE_DECODER +#endif //LODEPNG_COMPILE_DISK #ifdef LODEPNG_COMPILE_ENCODER unsigned encode(std::vector& out, const unsigned char* in, unsigned w, unsigned h, - LodePNGColorType colortype, unsigned bitdepth) + LodePNGColorType colortype, unsigned bitdepth) { - unsigned char* buffer; - size_t buffersize; - unsigned error = lodepng_encode_memory(&buffer, &buffersize, in, w, h, colortype, bitdepth); - if(buffer) - { - out.insert(out.end(), &buffer[0], &buffer[buffersize]); - lodepng_free(buffer); - } - return error; + unsigned char* buffer; + size_t buffersize; + unsigned error = lodepng_encode_memory(&buffer, &buffersize, in, w, h, colortype, bitdepth); + if (buffer) + { + out.insert(out.end(), &buffer[0], &buffer[buffersize]); + lodepng_free(buffer); + } + return error; } unsigned encode(std::vector& out, - const std::vector& in, unsigned w, unsigned h, - LodePNGColorType colortype, unsigned bitdepth) + const std::vector& in, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth) { - if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84; - return encode(out, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth); + if (lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84; + return encode(out, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth); } unsigned encode(std::vector& out, - const unsigned char* in, unsigned w, unsigned h, - State& state) + const unsigned char* in, unsigned w, unsigned h, + State& state) { - unsigned char* buffer; - size_t buffersize; - unsigned error = lodepng_encode(&buffer, &buffersize, in, w, h, &state); - if(buffer) - { - out.insert(out.end(), &buffer[0], &buffer[buffersize]); - lodepng_free(buffer); - } - return error; + unsigned char* buffer; + size_t buffersize; + unsigned error = lodepng_encode(&buffer, &buffersize, in, w, h, &state); + if (buffer) + { + out.insert(out.end(), &buffer[0], &buffer[buffersize]); + lodepng_free(buffer); + } + return error; } unsigned encode(std::vector& out, - const std::vector& in, unsigned w, unsigned h, - State& state) + const std::vector& in, unsigned w, unsigned h, + State& state) { - if(lodepng_get_raw_size(w, h, &state.info_raw) > in.size()) return 84; - return encode(out, in.empty() ? 0 : &in[0], w, h, state); + if (lodepng_get_raw_size(w, h, &state.info_raw) > in.size()) return 84; + return encode(out, in.empty() ? 0 : &in[0], w, h, state); } #ifdef LODEPNG_COMPILE_DISK unsigned encode(const std::string& filename, - const unsigned char* in, unsigned w, unsigned h, - LodePNGColorType colortype, unsigned bitdepth) + const unsigned char* in, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth) { - std::vector buffer; - unsigned error = encode(buffer, in, w, h, colortype, bitdepth); - if(!error) save_file(buffer, filename); - return error; + std::vector buffer; + unsigned error = encode(buffer, in, w, h, colortype, bitdepth); + if (!error) save_file(buffer, filename); + return error; } unsigned encode(const std::string& filename, - const std::vector& in, unsigned w, unsigned h, - LodePNGColorType colortype, unsigned bitdepth) + const std::vector& in, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth) { - if(lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84; - return encode(filename, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth); + if (lodepng_get_raw_size_lct(w, h, colortype, bitdepth) > in.size()) return 84; + return encode(filename, in.empty() ? 0 : &in[0], w, h, colortype, bitdepth); } -#endif //LODEPNG_COMPILE_DISK -#endif //LODEPNG_COMPILE_ENCODER -#endif //LODEPNG_COMPILE_PNG -} //namespace lodepng +#endif //LODEPNG_COMPILE_DISK +#endif //LODEPNG_COMPILE_ENCODER +#endif //LODEPNG_COMPILE_PNG +} //namespace lodepng #endif /*LODEPNG_COMPILE_CPP*/ diff --git a/examples/ThirdPartyLibs/openvr/samples/shared/lodepng.h b/examples/ThirdPartyLibs/openvr/samples/shared/lodepng.h index ef2c82067..68eeef9ac 100644 --- a/examples/ThirdPartyLibs/openvr/samples/shared/lodepng.h +++ b/examples/ThirdPartyLibs/openvr/samples/shared/lodepng.h @@ -86,11 +86,11 @@ source files with custom allocators.*/ /*The PNG color types (also used for raw).*/ typedef enum LodePNGColorType { - LCT_GREY = 0, /*greyscale: 1,2,4,8,16 bit*/ - LCT_RGB = 2, /*RGB: 8,16 bit*/ - LCT_PALETTE = 3, /*palette: 1,2,4,8 bit*/ - LCT_GREY_ALPHA = 4, /*greyscale with alpha: 8,16 bit*/ - LCT_RGBA = 6 /*RGB with alpha: 8,16 bit*/ + LCT_GREY = 0, /*greyscale: 1,2,4,8,16 bit*/ + LCT_RGB = 2, /*RGB: 8,16 bit*/ + LCT_PALETTE = 3, /*palette: 1,2,4,8 bit*/ + LCT_GREY_ALPHA = 4, /*greyscale with alpha: 8,16 bit*/ + LCT_RGBA = 6 /*RGB with alpha: 8,16 bit*/ } LodePNGColorType; #ifdef LODEPNG_COMPILE_DECODER @@ -110,16 +110,16 @@ bitdepth: the desired bit depth for the raw output image. See explanation on PNG Return value: LodePNG error code (0 means no error). */ unsigned lodepng_decode_memory(unsigned char** out, unsigned* w, unsigned* h, - const unsigned char* in, size_t insize, - LodePNGColorType colortype, unsigned bitdepth); + const unsigned char* in, size_t insize, + LodePNGColorType colortype, unsigned bitdepth); /*Same as lodepng_decode_memory, but always decodes to 32-bit RGBA raw image*/ unsigned lodepng_decode32(unsigned char** out, unsigned* w, unsigned* h, - const unsigned char* in, size_t insize); + const unsigned char* in, size_t insize); /*Same as lodepng_decode_memory, but always decodes to 24-bit RGB raw image*/ unsigned lodepng_decode24(unsigned char** out, unsigned* w, unsigned* h, - const unsigned char* in, size_t insize); + const unsigned char* in, size_t insize); #ifdef LODEPNG_COMPILE_DISK /* @@ -127,20 +127,19 @@ Load PNG from disk, from file with given name. Same as the other decode functions, but instead takes a filename as input. */ unsigned lodepng_decode_file(unsigned char** out, unsigned* w, unsigned* h, - const char* filename, - LodePNGColorType colortype, unsigned bitdepth); + const char* filename, + LodePNGColorType colortype, unsigned bitdepth); /*Same as lodepng_decode_file, but always decodes to 32-bit RGBA raw image.*/ unsigned lodepng_decode32_file(unsigned char** out, unsigned* w, unsigned* h, - const char* filename); + const char* filename); /*Same as lodepng_decode_file, but always decodes to 24-bit RGB raw image.*/ unsigned lodepng_decode24_file(unsigned char** out, unsigned* w, unsigned* h, - const char* filename); + const char* filename); #endif /*LODEPNG_COMPILE_DISK*/ #endif /*LODEPNG_COMPILE_DECODER*/ - #ifdef LODEPNG_COMPILE_ENCODER /* Converts raw pixel data into a PNG image in memory. The colortype and bitdepth @@ -159,16 +158,16 @@ bitdepth: the bit depth of the raw input image. See explanation on PNG color typ Return value: LodePNG error code (0 means no error). */ unsigned lodepng_encode_memory(unsigned char** out, size_t* outsize, - const unsigned char* image, unsigned w, unsigned h, - LodePNGColorType colortype, unsigned bitdepth); + const unsigned char* image, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth); /*Same as lodepng_encode_memory, but always encodes from 32-bit RGBA raw image.*/ unsigned lodepng_encode32(unsigned char** out, size_t* outsize, - const unsigned char* image, unsigned w, unsigned h); + const unsigned char* image, unsigned w, unsigned h); /*Same as lodepng_encode_memory, but always encodes from 24-bit RGB raw image.*/ unsigned lodepng_encode24(unsigned char** out, size_t* outsize, - const unsigned char* image, unsigned w, unsigned h); + const unsigned char* image, unsigned w, unsigned h); #ifdef LODEPNG_COMPILE_DISK /* @@ -177,20 +176,19 @@ Same as the other encode functions, but instead takes a filename as output. NOTE: This overwrites existing files without warning! */ unsigned lodepng_encode_file(const char* filename, - const unsigned char* image, unsigned w, unsigned h, - LodePNGColorType colortype, unsigned bitdepth); + const unsigned char* image, unsigned w, unsigned h, + LodePNGColorType colortype, unsigned bitdepth); /*Same as lodepng_encode_file, but always encodes from 32-bit RGBA raw image.*/ unsigned lodepng_encode32_file(const char* filename, - const unsigned char* image, unsigned w, unsigned h); + const unsigned char* image, unsigned w, unsigned h); /*Same as lodepng_encode_file, but always encodes from 24-bit RGB raw image.*/ unsigned lodepng_encode24_file(const char* filename, - const unsigned char* image, unsigned w, unsigned h); + const unsigned char* image, unsigned w, unsigned h); #endif /*LODEPNG_COMPILE_DISK*/ #endif /*LODEPNG_COMPILE_ENCODER*/ - #ifdef LODEPNG_COMPILE_CPP namespace lodepng { @@ -198,31 +196,31 @@ namespace lodepng /*Same as lodepng_decode_memory, but decodes to an std::vector. The colortype is the format to output the pixels to. Default is RGBA 8-bit per channel.*/ unsigned decode(std::vector& out, unsigned& w, unsigned& h, - const unsigned char* in, size_t insize, - LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); + const unsigned char* in, size_t insize, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); unsigned decode(std::vector& out, unsigned& w, unsigned& h, - const std::vector& in, - LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); + const std::vector& in, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); #ifdef LODEPNG_COMPILE_DISK /* Converts PNG file from disk to raw pixel data in memory. Same as the other decode functions, but instead takes a filename as input. */ unsigned decode(std::vector& out, unsigned& w, unsigned& h, - const std::string& filename, - LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); -#endif //LODEPNG_COMPILE_DISK -#endif //LODEPNG_COMPILE_DECODER + const std::string& filename, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +#endif //LODEPNG_COMPILE_DISK +#endif //LODEPNG_COMPILE_DECODER #ifdef LODEPNG_COMPILE_ENCODER /*Same as lodepng_encode_memory, but encodes to an std::vector. colortype is that of the raw input data. The output PNG color type will be auto chosen.*/ unsigned encode(std::vector& out, - const unsigned char* in, unsigned w, unsigned h, - LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); + const unsigned char* in, unsigned w, unsigned h, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); unsigned encode(std::vector& out, - const std::vector& in, unsigned w, unsigned h, - LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); + const std::vector& in, unsigned w, unsigned h, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); #ifdef LODEPNG_COMPILE_DISK /* Converts 32-bit RGBA raw pixel data into a PNG file on disk. @@ -230,14 +228,14 @@ Same as the other encode functions, but instead takes a filename as output. NOTE: This overwrites existing files without warning! */ unsigned encode(const std::string& filename, - const unsigned char* in, unsigned w, unsigned h, - LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); + const unsigned char* in, unsigned w, unsigned h, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); unsigned encode(const std::string& filename, - const std::vector& in, unsigned w, unsigned h, - LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); -#endif //LODEPNG_COMPILE_DISK -#endif //LODEPNG_COMPILE_ENCODER -} //namespace lodepng + const std::vector& in, unsigned w, unsigned h, + LodePNGColorType colortype = LCT_RGBA, unsigned bitdepth = 8); +#endif //LODEPNG_COMPILE_DISK +#endif //LODEPNG_COMPILE_ENCODER +} //namespace lodepng #endif /*LODEPNG_COMPILE_CPP*/ #endif /*LODEPNG_COMPILE_PNG*/ @@ -251,20 +249,20 @@ const char* lodepng_error_text(unsigned code); typedef struct LodePNGDecompressSettings LodePNGDecompressSettings; struct LodePNGDecompressSettings { - unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/ + unsigned ignore_adler32; /*if 1, continue and don't give an error message if the Adler32 checksum is corrupted*/ - /*use custom zlib decoder instead of built in one (default: null)*/ - unsigned (*custom_zlib)(unsigned char**, size_t*, - const unsigned char*, size_t, - const LodePNGDecompressSettings*); - /*use custom deflate decoder instead of built in one (default: null) + /*use custom zlib decoder instead of built in one (default: null)*/ + unsigned (*custom_zlib)(unsigned char**, size_t*, + const unsigned char*, size_t, + const LodePNGDecompressSettings*); + /*use custom deflate decoder instead of built in one (default: null) if custom_zlib is used, custom_deflate is ignored since only the built in zlib function will call custom_deflate*/ - unsigned (*custom_inflate)(unsigned char**, size_t*, - const unsigned char*, size_t, - const LodePNGDecompressSettings*); + unsigned (*custom_inflate)(unsigned char**, size_t*, + const unsigned char*, size_t, + const LodePNGDecompressSettings*); - const void* custom_context; /*optional custom settings for custom functions*/ + const void* custom_context; /*optional custom settings for custom functions*/ }; extern const LodePNGDecompressSettings lodepng_default_decompress_settings; @@ -279,26 +277,26 @@ between speed and compression ratio. typedef struct LodePNGCompressSettings LodePNGCompressSettings; struct LodePNGCompressSettings /*deflate = compress*/ { - /*LZ77 related settings*/ - unsigned btype; /*the block type for LZ (0, 1, 2 or 3, see zlib standard). Should be 2 for proper compression.*/ - unsigned use_lz77; /*whether or not to use LZ77. Should be 1 for proper compression.*/ - unsigned windowsize; /*must be a power of two <= 32768. higher compresses more but is slower. Default value: 2048.*/ - unsigned minmatch; /*mininum lz77 length. 3 is normally best, 6 can be better for some PNGs. Default: 0*/ - unsigned nicematch; /*stop searching if >= this length found. Set to 258 for best compression. Default: 128*/ - unsigned lazymatching; /*use lazy matching: better compression but a bit slower. Default: true*/ + /*LZ77 related settings*/ + unsigned btype; /*the block type for LZ (0, 1, 2 or 3, see zlib standard). Should be 2 for proper compression.*/ + unsigned use_lz77; /*whether or not to use LZ77. Should be 1 for proper compression.*/ + unsigned windowsize; /*must be a power of two <= 32768. higher compresses more but is slower. Default value: 2048.*/ + unsigned minmatch; /*mininum lz77 length. 3 is normally best, 6 can be better for some PNGs. Default: 0*/ + unsigned nicematch; /*stop searching if >= this length found. Set to 258 for best compression. Default: 128*/ + unsigned lazymatching; /*use lazy matching: better compression but a bit slower. Default: true*/ - /*use custom zlib encoder instead of built in one (default: null)*/ - unsigned (*custom_zlib)(unsigned char**, size_t*, - const unsigned char*, size_t, - const LodePNGCompressSettings*); - /*use custom deflate encoder instead of built in one (default: null) + /*use custom zlib encoder instead of built in one (default: null)*/ + unsigned (*custom_zlib)(unsigned char**, size_t*, + const unsigned char*, size_t, + const LodePNGCompressSettings*); + /*use custom deflate encoder instead of built in one (default: null) if custom_zlib is used, custom_deflate is ignored since only the built in zlib function will call custom_deflate*/ - unsigned (*custom_deflate)(unsigned char**, size_t*, - const unsigned char*, size_t, - const LodePNGCompressSettings*); + unsigned (*custom_deflate)(unsigned char**, size_t*, + const unsigned char*, size_t, + const LodePNGCompressSettings*); - const void* custom_context; /*optional custom settings for custom functions*/ + const void* custom_context; /*optional custom settings for custom functions*/ }; extern const LodePNGCompressSettings lodepng_default_compress_settings; @@ -313,11 +311,11 @@ format, and is used both for PNG and raw image data in LodePNG. */ typedef struct LodePNGColorMode { - /*header (IHDR)*/ - LodePNGColorType colortype; /*color type, see PNG standard or documentation further in this header file*/ - unsigned bitdepth; /*bits per sample, see PNG standard or documentation further in this header file*/ + /*header (IHDR)*/ + LodePNGColorType colortype; /*color type, see PNG standard or documentation further in this header file*/ + unsigned bitdepth; /*bits per sample, see PNG standard or documentation further in this header file*/ - /* + /* palette (PLTE and tRNS) Dynamically allocated with the colors of the palette, including alpha. @@ -330,10 +328,10 @@ typedef struct LodePNGColorMode The palette is only supported for color type 3. */ - unsigned char* palette; /*palette in RGBARGBA... order. When allocated, must be either 0, or have size 1024*/ - size_t palettesize; /*palette size in number of colors (amount of bytes is 4 * palettesize)*/ + unsigned char* palette; /*palette in RGBARGBA... order. When allocated, must be either 0, or have size 1024*/ + size_t palettesize; /*palette size in number of colors (amount of bytes is 4 * palettesize)*/ - /* + /* transparent color key (tRNS) This color uses the same bit depth as the bitdepth value in this struct, which can be 1-bit to 16-bit. @@ -344,10 +342,10 @@ typedef struct LodePNGColorMode The color key is only supported for color types 0 and 2. */ - unsigned key_defined; /*is a transparent color key given? 0 = false, 1 = true*/ - unsigned key_r; /*red/greyscale component of color key*/ - unsigned key_g; /*green component of color key*/ - unsigned key_b; /*blue component of color key*/ + unsigned key_defined; /*is a transparent color key given? 0 = false, 1 = true*/ + unsigned key_r; /*red/greyscale component of color key*/ + unsigned key_g; /*green component of color key*/ + unsigned key_b; /*blue component of color key*/ } LodePNGColorMode; /*init, cleanup and copy functions to use with this struct*/ @@ -359,7 +357,7 @@ unsigned lodepng_color_mode_copy(LodePNGColorMode* dest, const LodePNGColorMode* void lodepng_palette_clear(LodePNGColorMode* info); /*add 1 color to the palette*/ unsigned lodepng_palette_add(LodePNGColorMode* info, - unsigned char r, unsigned char g, unsigned char b, unsigned char a); + unsigned char r, unsigned char g, unsigned char b, unsigned char a); /*get the total amount of bits per pixel, based on colortype and bitdepth in the struct*/ unsigned lodepng_get_bpp(const LodePNGColorMode* info); @@ -390,26 +388,26 @@ size_t lodepng_get_raw_size(unsigned w, unsigned h, const LodePNGColorMode* colo /*The information of a Time chunk in PNG.*/ typedef struct LodePNGTime { - unsigned year; /*2 bytes used (0-65535)*/ - unsigned month; /*1-12*/ - unsigned day; /*1-31*/ - unsigned hour; /*0-23*/ - unsigned minute; /*0-59*/ - unsigned second; /*0-60 (to allow for leap seconds)*/ + unsigned year; /*2 bytes used (0-65535)*/ + unsigned month; /*1-12*/ + unsigned day; /*1-31*/ + unsigned hour; /*0-23*/ + unsigned minute; /*0-59*/ + unsigned second; /*0-60 (to allow for leap seconds)*/ } LodePNGTime; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ /*Information about the PNG image, except pixels, width and height.*/ typedef struct LodePNGInfo { - /*header (IHDR), palette (PLTE) and transparency (tRNS) chunks*/ - unsigned compression_method;/*compression method of the original file. Always 0.*/ - unsigned filter_method; /*filter method of the original file*/ - unsigned interlace_method; /*interlace method of the original file*/ - LodePNGColorMode color; /*color type and bits, palette and transparency of the PNG file*/ + /*header (IHDR), palette (PLTE) and transparency (tRNS) chunks*/ + unsigned compression_method; /*compression method of the original file. Always 0.*/ + unsigned filter_method; /*filter method of the original file*/ + unsigned interlace_method; /*interlace method of the original file*/ + LodePNGColorMode color; /*color type and bits, palette and transparency of the PNG file*/ #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - /* + /* suggested background color chunk (bKGD) This color uses the same color mode as the PNG (except alpha channel), which can be 1-bit to 16-bit. @@ -420,12 +418,12 @@ typedef struct LodePNGInfo The decoder does not use this background color to edit the color of pixels. */ - unsigned background_defined; /*is a suggested background color given?*/ - unsigned background_r; /*red component of suggested background color*/ - unsigned background_g; /*green component of suggested background color*/ - unsigned background_b; /*blue component of suggested background color*/ + unsigned background_defined; /*is a suggested background color given?*/ + unsigned background_r; /*red component of suggested background color*/ + unsigned background_g; /*green component of suggested background color*/ + unsigned background_b; /*blue component of suggested background color*/ - /* + /* non-international text chunks (tEXt and zTXt) The char** arrays each contain num strings. The actual messages are in @@ -438,32 +436,32 @@ typedef struct LodePNGInfo Don't allocate these text buffers yourself. Use the init/cleanup functions correctly and use lodepng_add_text and lodepng_clear_text. */ - size_t text_num; /*the amount of texts in these char** buffers (there may be more texts in itext)*/ - char** text_keys; /*the keyword of a text chunk (e.g. "Comment")*/ - char** text_strings; /*the actual text*/ + size_t text_num; /*the amount of texts in these char** buffers (there may be more texts in itext)*/ + char** text_keys; /*the keyword of a text chunk (e.g. "Comment")*/ + char** text_strings; /*the actual text*/ - /* + /* international text chunks (iTXt) Similar to the non-international text chunks, but with additional strings "langtags" and "transkeys". */ - size_t itext_num; /*the amount of international texts in this PNG*/ - char** itext_keys; /*the English keyword of the text chunk (e.g. "Comment")*/ - char** itext_langtags; /*language tag for this text's language, ISO/IEC 646 string, e.g. ISO 639 language tag*/ - char** itext_transkeys; /*keyword translated to the international language - UTF-8 string*/ - char** itext_strings; /*the actual international text - UTF-8 string*/ + size_t itext_num; /*the amount of international texts in this PNG*/ + char** itext_keys; /*the English keyword of the text chunk (e.g. "Comment")*/ + char** itext_langtags; /*language tag for this text's language, ISO/IEC 646 string, e.g. ISO 639 language tag*/ + char** itext_transkeys; /*keyword translated to the international language - UTF-8 string*/ + char** itext_strings; /*the actual international text - UTF-8 string*/ - /*time chunk (tIME)*/ - unsigned time_defined; /*set to 1 to make the encoder generate a tIME chunk*/ - LodePNGTime time; + /*time chunk (tIME)*/ + unsigned time_defined; /*set to 1 to make the encoder generate a tIME chunk*/ + LodePNGTime time; - /*phys chunk (pHYs)*/ - unsigned phys_defined; /*if 0, there is no pHYs chunk and the values below are undefined, if 1 else there is one*/ - unsigned phys_x; /*pixels per unit in x direction*/ - unsigned phys_y; /*pixels per unit in y direction*/ - unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/ + /*phys chunk (pHYs)*/ + unsigned phys_defined; /*if 0, there is no pHYs chunk and the values below are undefined, if 1 else there is one*/ + unsigned phys_x; /*pixels per unit in x direction*/ + unsigned phys_y; /*pixels per unit in y direction*/ + unsigned phys_unit; /*may be 0 (unknown unit) or 1 (metre)*/ - /* + /* unknown chunks There are 3 buffers, one for each position in the PNG where unknown chunks can appear each buffer contains all unknown chunks for that position consecutively @@ -472,9 +470,9 @@ typedef struct LodePNGInfo Do not allocate or traverse this data yourself. Use the chunk traversing functions declared later, such as lodepng_chunk_next and lodepng_chunk_append, to read/write this struct. */ - unsigned char* unknown_chunks_data[3]; - size_t unknown_chunks_size[3]; /*size in bytes of the unknown chunks, given for protection*/ -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + unsigned char* unknown_chunks_data[3]; + size_t unknown_chunks_size[3]; /*size in bytes of the unknown chunks, given for protection*/ +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } LodePNGInfo; /*init, cleanup and copy functions to use with this struct*/ @@ -484,13 +482,13 @@ void lodepng_info_cleanup(LodePNGInfo* info); unsigned lodepng_info_copy(LodePNGInfo* dest, const LodePNGInfo* source); #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS -void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/ +void lodepng_clear_text(LodePNGInfo* info); /*use this to clear the texts again after you filled them in*/ unsigned lodepng_add_text(LodePNGInfo* info, const char* key, const char* str); /*push back both texts at once*/ void lodepng_clear_itext(LodePNGInfo* info); /*use this to clear the itexts again after you filled them in*/ unsigned lodepng_add_itext(LodePNGInfo* info, const char* key, const char* langtag, - const char* transkey, const char* str); /*push back the 4 texts of 1 chunk at once*/ -#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ + const char* transkey, const char* str); /*push back the 4 texts of 1 chunk at once*/ +#endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ /* Converts raw buffer from one color type to another color type, based on @@ -504,8 +502,8 @@ For 16-bit per channel colors, uses big endian format like PNG does. Return value is LodePNG error code */ unsigned lodepng_convert(unsigned char* out, const unsigned char* in, - LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, - unsigned w, unsigned h); + LodePNGColorMode* mode_out, const LodePNGColorMode* mode_in, + unsigned w, unsigned h); #ifdef LODEPNG_COMPILE_DECODER /* @@ -514,16 +512,16 @@ decoder, but not the Info settings from the Info structs. */ typedef struct LodePNGDecoderSettings { - LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/ + LodePNGDecompressSettings zlibsettings; /*in here is the setting to ignore Adler32 checksums*/ - unsigned ignore_crc; /*ignore CRC checksums*/ + unsigned ignore_crc; /*ignore CRC checksums*/ - unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/ + unsigned color_convert; /*whether to convert the PNG to the color type you want. Default: yes*/ #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - unsigned read_text_chunks; /*if false but remember_unknown_chunks is true, they're stored in the unknown chunks*/ - /*store all bytes from unknown chunks in the LodePNGInfo (off by default, useful for a png editor)*/ - unsigned remember_unknown_chunks; + unsigned read_text_chunks; /*if false but remember_unknown_chunks is true, they're stored in the unknown chunks*/ + /*store all bytes from unknown chunks in the LodePNGInfo (off by default, useful for a png editor)*/ + unsigned remember_unknown_chunks; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } LodePNGDecoderSettings; @@ -534,101 +532,100 @@ void lodepng_decoder_settings_init(LodePNGDecoderSettings* settings); /*automatically use color type with less bits per pixel if losslessly possible. Default: AUTO*/ typedef enum LodePNGFilterStrategy { - /*every filter at zero*/ - LFS_ZERO, - /*Use filter that gives minumum sum, as described in the official PNG filter heuristic.*/ - LFS_MINSUM, - /*Use the filter type that gives smallest Shannon entropy for this scanline. Depending + /*every filter at zero*/ + LFS_ZERO, + /*Use filter that gives minumum sum, as described in the official PNG filter heuristic.*/ + LFS_MINSUM, + /*Use the filter type that gives smallest Shannon entropy for this scanline. Depending on the image, this is better or worse than minsum.*/ - LFS_ENTROPY, - /* + LFS_ENTROPY, + /* Brute-force-search PNG filters by compressing each filter for each scanline. Experimental, very slow, and only rarely gives better compression than MINSUM. */ - LFS_BRUTE_FORCE, - /*use predefined_filters buffer: you specify the filter type for each scanline*/ - LFS_PREDEFINED + LFS_BRUTE_FORCE, + /*use predefined_filters buffer: you specify the filter type for each scanline*/ + LFS_PREDEFINED } LodePNGFilterStrategy; /*Gives characteristics about the colors of the image, which helps decide which color model to use for encoding. Used internally by default if "auto_convert" is enabled. Public because it's useful for custom algorithms.*/ typedef struct LodePNGColorProfile { - unsigned colored; /*not greyscale*/ - unsigned key; /*if true, image is not opaque. Only if true and alpha is false, color key is possible.*/ - unsigned short key_r; /*these values are always in 16-bit bitdepth in the profile*/ - unsigned short key_g; - unsigned short key_b; - unsigned alpha; /*alpha channel or alpha palette required*/ - unsigned numcolors; /*amount of colors, up to 257. Not valid if bits == 16.*/ - unsigned char palette[1024]; /*Remembers up to the first 256 RGBA colors, in no particular order*/ - unsigned bits; /*bits per channel (not for palette). 1,2 or 4 for greyscale only. 16 if 16-bit per channel required.*/ + unsigned colored; /*not greyscale*/ + unsigned key; /*if true, image is not opaque. Only if true and alpha is false, color key is possible.*/ + unsigned short key_r; /*these values are always in 16-bit bitdepth in the profile*/ + unsigned short key_g; + unsigned short key_b; + unsigned alpha; /*alpha channel or alpha palette required*/ + unsigned numcolors; /*amount of colors, up to 257. Not valid if bits == 16.*/ + unsigned char palette[1024]; /*Remembers up to the first 256 RGBA colors, in no particular order*/ + unsigned bits; /*bits per channel (not for palette). 1,2 or 4 for greyscale only. 16 if 16-bit per channel required.*/ } LodePNGColorProfile; void lodepng_color_profile_init(LodePNGColorProfile* profile); /*Get a LodePNGColorProfile of the image.*/ unsigned get_color_profile(LodePNGColorProfile* profile, - const unsigned char* image, unsigned w, unsigned h, - const LodePNGColorMode* mode_in); + const unsigned char* image, unsigned w, unsigned h, + const LodePNGColorMode* mode_in); /*The function LodePNG uses internally to decide the PNG color with auto_convert. Chooses an optimal color model, e.g. grey if only grey pixels, palette if < 256 colors, ...*/ unsigned lodepng_auto_choose_color(LodePNGColorMode* mode_out, - const unsigned char* image, unsigned w, unsigned h, - const LodePNGColorMode* mode_in); + const unsigned char* image, unsigned w, unsigned h, + const LodePNGColorMode* mode_in); /*Settings for the encoder.*/ typedef struct LodePNGEncoderSettings { - LodePNGCompressSettings zlibsettings; /*settings for the zlib encoder, such as window size, ...*/ + LodePNGCompressSettings zlibsettings; /*settings for the zlib encoder, such as window size, ...*/ - unsigned auto_convert; /*automatically choose output PNG color type. Default: true*/ + unsigned auto_convert; /*automatically choose output PNG color type. Default: true*/ - /*If true, follows the official PNG heuristic: if the PNG uses a palette or lower than + /*If true, follows the official PNG heuristic: if the PNG uses a palette or lower than 8 bit depth, set all filters to zero. Otherwise use the filter_strategy. Note that to completely follow the official PNG heuristic, filter_palette_zero must be true and filter_strategy must be LFS_MINSUM*/ - unsigned filter_palette_zero; - /*Which filter strategy to use when not using zeroes due to filter_palette_zero. + unsigned filter_palette_zero; + /*Which filter strategy to use when not using zeroes due to filter_palette_zero. Set filter_palette_zero to 0 to ensure always using your chosen strategy. Default: LFS_MINSUM*/ - LodePNGFilterStrategy filter_strategy; - /*used if filter_strategy is LFS_PREDEFINED. In that case, this must point to a buffer with + LodePNGFilterStrategy filter_strategy; + /*used if filter_strategy is LFS_PREDEFINED. In that case, this must point to a buffer with the same length as the amount of scanlines in the image, and each value must <= 5. You have to cleanup this buffer, LodePNG will never free it. Don't forget that filter_palette_zero must be set to 0 to ensure this is also used on palette or low bitdepth images.*/ - const unsigned char* predefined_filters; + const unsigned char* predefined_filters; - /*force creating a PLTE chunk if colortype is 2 or 6 (= a suggested palette). + /*force creating a PLTE chunk if colortype is 2 or 6 (= a suggested palette). If colortype is 3, PLTE is _always_ created.*/ - unsigned force_palette; + unsigned force_palette; #ifdef LODEPNG_COMPILE_ANCILLARY_CHUNKS - /*add LodePNG identifier and version as a text chunk, for debugging*/ - unsigned add_id; - /*encode text chunks as zTXt chunks instead of tEXt chunks, and use compression in iTXt chunks*/ - unsigned text_compression; + /*add LodePNG identifier and version as a text chunk, for debugging*/ + unsigned add_id; + /*encode text chunks as zTXt chunks instead of tEXt chunks, and use compression in iTXt chunks*/ + unsigned text_compression; #endif /*LODEPNG_COMPILE_ANCILLARY_CHUNKS*/ } LodePNGEncoderSettings; void lodepng_encoder_settings_init(LodePNGEncoderSettings* settings); #endif /*LODEPNG_COMPILE_ENCODER*/ - #if defined(LODEPNG_COMPILE_DECODER) || defined(LODEPNG_COMPILE_ENCODER) /*The settings, state and information for extended encoding and decoding.*/ typedef struct LodePNGState { #ifdef LODEPNG_COMPILE_DECODER - LodePNGDecoderSettings decoder; /*the decoding settings*/ -#endif /*LODEPNG_COMPILE_DECODER*/ + LodePNGDecoderSettings decoder; /*the decoding settings*/ +#endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER - LodePNGEncoderSettings encoder; /*the encoding settings*/ -#endif /*LODEPNG_COMPILE_ENCODER*/ - LodePNGColorMode info_raw; /*specifies the format in which you would like to get the raw pixel buffer*/ - LodePNGInfo info_png; /*info of the PNG image obtained after decoding*/ - unsigned error; + LodePNGEncoderSettings encoder; /*the encoding settings*/ +#endif /*LODEPNG_COMPILE_ENCODER*/ + LodePNGColorMode info_raw; /*specifies the format in which you would like to get the raw pixel buffer*/ + LodePNGInfo info_png; /*info of the PNG image obtained after decoding*/ + unsigned error; #ifdef LODEPNG_COMPILE_CPP - //For the lodepng::State subclass. - virtual ~LodePNGState(){} + //For the lodepng::State subclass. + virtual ~LodePNGState() {} #endif } LodePNGState; @@ -644,8 +641,8 @@ Same as lodepng_decode_memory, but uses a LodePNGState to allow custom settings getting much more information about the PNG image and color mode. */ unsigned lodepng_decode(unsigned char** out, unsigned* w, unsigned* h, - LodePNGState* state, - const unsigned char* in, size_t insize); + LodePNGState* state, + const unsigned char* in, size_t insize); /* Read the PNG header, but not the actual data. This returns only the information @@ -653,16 +650,15 @@ that is in the header chunk of the PNG, such as width, height and color type. Th information is placed in the info_png field of the LodePNGState. */ unsigned lodepng_inspect(unsigned* w, unsigned* h, - LodePNGState* state, - const unsigned char* in, size_t insize); + LodePNGState* state, + const unsigned char* in, size_t insize); #endif /*LODEPNG_COMPILE_DECODER*/ - #ifdef LODEPNG_COMPILE_ENCODER /*This function allocates the out buffer with standard malloc and stores the size in *outsize.*/ unsigned lodepng_encode(unsigned char** out, size_t* outsize, - const unsigned char* image, unsigned w, unsigned h, - LodePNGState* state); + const unsigned char* image, unsigned w, unsigned h, + LodePNGState* state); #endif /*LODEPNG_COMPILE_ENCODER*/ /* @@ -723,14 +719,12 @@ The out variable and outlength are updated to reflect the new reallocated buffer Returne error code (0 if it went ok) */ unsigned lodepng_chunk_create(unsigned char** out, size_t* outlength, unsigned length, - const char* type, const unsigned char* data); - + const char* type, const unsigned char* data); /*Calculate CRC32 of buffer*/ unsigned lodepng_crc32(const unsigned char* buf, size_t len); #endif /*LODEPNG_COMPILE_PNG*/ - #ifdef LODEPNG_COMPILE_ZLIB /* This zlib part can be used independently to zlib compress and decompress a @@ -741,8 +735,8 @@ part of zlib that is required for PNG, it does not support dictionaries. #ifdef LODEPNG_COMPILE_DECODER /*Inflate a buffer. Inflate is the decompression step of deflate. Out buffer must be freed after use.*/ unsigned lodepng_inflate(unsigned char** out, size_t* outsize, - const unsigned char* in, size_t insize, - const LodePNGDecompressSettings* settings); + const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings); /* Decompresses Zlib data. Reallocates the out buffer and appends the data. The @@ -751,8 +745,8 @@ Either, *out must be NULL and *outsize must be 0, or, *out must be a valid buffer and *outsize its size in bytes. out must be freed by user after usage. */ unsigned lodepng_zlib_decompress(unsigned char** out, size_t* outsize, - const unsigned char* in, size_t insize, - const LodePNGDecompressSettings* settings); + const unsigned char* in, size_t insize, + const LodePNGDecompressSettings* settings); #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER @@ -764,20 +758,20 @@ Either, *out must be NULL and *outsize must be 0, or, *out must be a valid buffer and *outsize its size in bytes. out must be freed by user after usage. */ unsigned lodepng_zlib_compress(unsigned char** out, size_t* outsize, - const unsigned char* in, size_t insize, - const LodePNGCompressSettings* settings); + const unsigned char* in, size_t insize, + const LodePNGCompressSettings* settings); /* Find length-limited Huffman code for given frequencies. This function is in the public interface only for tests, it's used internally by lodepng_deflate. */ unsigned lodepng_huffman_code_lengths(unsigned* lengths, const unsigned* frequencies, - size_t numcodes, unsigned maxbitlen); + size_t numcodes, unsigned maxbitlen); /*Compress a buffer with deflate. See RFC 1951. Out buffer must be freed after use.*/ unsigned lodepng_deflate(unsigned char** out, size_t* outsize, - const unsigned char* in, size_t insize, - const LodePNGCompressSettings* settings); + const unsigned char* in, size_t insize, + const LodePNGCompressSettings* settings); #endif /*LODEPNG_COMPILE_ENCODER*/ #endif /*LODEPNG_COMPILE_ZLIB*/ @@ -811,31 +805,31 @@ namespace lodepng #ifdef LODEPNG_COMPILE_PNG class State : public LodePNGState { - public: - State(); - State(const State& other); - virtual ~State(); - State& operator=(const State& other); +public: + State(); + State(const State& other); + virtual ~State(); + State& operator=(const State& other); }; #ifdef LODEPNG_COMPILE_DECODER //Same as other lodepng::decode, but using a State for more settings and information. unsigned decode(std::vector& out, unsigned& w, unsigned& h, - State& state, - const unsigned char* in, size_t insize); + State& state, + const unsigned char* in, size_t insize); unsigned decode(std::vector& out, unsigned& w, unsigned& h, - State& state, - const std::vector& in); + State& state, + const std::vector& in); #endif /*LODEPNG_COMPILE_DECODER*/ #ifdef LODEPNG_COMPILE_ENCODER //Same as other lodepng::encode, but using a State for more settings and information. unsigned encode(std::vector& out, - const unsigned char* in, unsigned w, unsigned h, - State& state); + const unsigned char* in, unsigned w, unsigned h, + State& state); unsigned encode(std::vector& out, - const std::vector& in, unsigned w, unsigned h, - State& state); + const std::vector& in, unsigned w, unsigned h, + State& state); #endif /*LODEPNG_COMPILE_ENCODER*/ #ifdef LODEPNG_COMPILE_DISK @@ -850,31 +844,31 @@ Save the binary data in an std::vector to a file on disk. The file is overwritte without warning. */ void save_file(const std::vector& buffer, const std::string& filename); -#endif //LODEPNG_COMPILE_DISK -#endif //LODEPNG_COMPILE_PNG +#endif //LODEPNG_COMPILE_DISK +#endif //LODEPNG_COMPILE_PNG #ifdef LODEPNG_COMPILE_ZLIB #ifdef LODEPNG_COMPILE_DECODER //Zlib-decompress an unsigned char buffer unsigned decompress(std::vector& out, const unsigned char* in, size_t insize, - const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); + const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); //Zlib-decompress an std::vector unsigned decompress(std::vector& out, const std::vector& in, - const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); -#endif //LODEPNG_COMPILE_DECODER + const LodePNGDecompressSettings& settings = lodepng_default_decompress_settings); +#endif //LODEPNG_COMPILE_DECODER #ifdef LODEPNG_COMPILE_ENCODER //Zlib-compress an unsigned char buffer unsigned compress(std::vector& out, const unsigned char* in, size_t insize, - const LodePNGCompressSettings& settings = lodepng_default_compress_settings); + const LodePNGCompressSettings& settings = lodepng_default_compress_settings); //Zlib-compress an std::vector unsigned compress(std::vector& out, const std::vector& in, - const LodePNGCompressSettings& settings = lodepng_default_compress_settings); -#endif //LODEPNG_COMPILE_ENCODER -#endif //LODEPNG_COMPILE_ZLIB -} //namespace lodepng + const LodePNGCompressSettings& settings = lodepng_default_compress_settings); +#endif //LODEPNG_COMPILE_ENCODER +#endif //LODEPNG_COMPILE_ZLIB +} //namespace lodepng #endif /*LODEPNG_COMPILE_CPP*/ /* diff --git a/examples/ThirdPartyLibs/openvr/samples/shared/pathtools.cpp b/examples/ThirdPartyLibs/openvr/samples/shared/pathtools.cpp index da2e8ce78..826ff24ee 100644 --- a/examples/ThirdPartyLibs/openvr/samples/shared/pathtools.cpp +++ b/examples/ThirdPartyLibs/openvr/samples/shared/pathtools.cpp @@ -3,7 +3,7 @@ #include "strtools.h" #include "pathtools.h" -#if defined( _WIN32) +#if defined(_WIN32) #include #include #include @@ -22,7 +22,7 @@ #include #include #include -#define _S_IFDIR S_IFDIR // really from tier0/platform.h which we dont have yet +#define _S_IFDIR S_IFDIR // really from tier0/platform.h which we dont have yet #endif #include @@ -32,32 +32,32 @@ /** Returns the path (including filename) to the current executable */ std::string Path_GetExecutablePath() { -#if defined( _WIN32 ) +#if defined(_WIN32) wchar_t *pwchPath = new wchar_t[MAX_UNICODE_PATH]; char *pchPath = new char[MAX_UNICODE_PATH_IN_UTF8]; - ::GetModuleFileNameW( NULL, pwchPath, MAX_UNICODE_PATH ); - WideCharToMultiByte( CP_UTF8, 0, pwchPath, -1, pchPath, MAX_UNICODE_PATH_IN_UTF8, NULL, NULL ); + ::GetModuleFileNameW(NULL, pwchPath, MAX_UNICODE_PATH); + WideCharToMultiByte(CP_UTF8, 0, pwchPath, -1, pchPath, MAX_UNICODE_PATH_IN_UTF8, NULL, NULL); delete[] pwchPath; std::string sPath = pchPath; delete[] pchPath; return sPath; -#elif defined( OSX ) +#elif defined(OSX) char rchPath[1024]; - uint32_t nBuff = sizeof( rchPath ); + uint32_t nBuff = sizeof(rchPath); bool bSuccess = _NSGetExecutablePath(rchPath, &nBuff) == 0; - rchPath[nBuff-1] = '\0'; - if( bSuccess ) + rchPath[nBuff - 1] = '\0'; + if (bSuccess) return rchPath; else return ""; #elif defined LINUX char rchPath[1024]; - size_t nBuff = sizeof( rchPath ); - ssize_t nRead = readlink("/proc/self/exe", rchPath, nBuff-1 ); - if ( nRead != -1 ) + size_t nBuff = sizeof(rchPath); + ssize_t nRead = readlink("/proc/self/exe", rchPath, nBuff - 1); + if (nRead != -1) { - rchPath[ nRead ] = 0; + rchPath[nRead] = 0; return rchPath; } else @@ -65,78 +65,77 @@ std::string Path_GetExecutablePath() return ""; } #else - AssertMsg( false, "Implement Plat_GetExecutablePath" ); + AssertMsg(false, "Implement Plat_GetExecutablePath"); return ""; #endif - } /** Returns the path of the current working directory */ std::string Path_GetWorkingDirectory() { std::string sPath; -#if defined( _WIN32 ) +#if defined(_WIN32) wchar_t buf[MAX_UNICODE_PATH]; - sPath = UTF16to8( _wgetcwd( buf, MAX_UNICODE_PATH ) ); + sPath = UTF16to8(_wgetcwd(buf, MAX_UNICODE_PATH)); #else - char buf[ 1024 ]; - sPath = getcwd( buf, sizeof( buf ) ); + char buf[1024]; + sPath = getcwd(buf, sizeof(buf)); #endif return sPath; } /** Sets the path of the current working directory. Returns true if this was successful. */ -bool Path_SetWorkingDirectory( const std::string & sPath ) +bool Path_SetWorkingDirectory(const std::string &sPath) { bool bSuccess; -#if defined( _WIN32 ) - std::wstring wsPath = UTF8to16( sPath.c_str() ); - bSuccess = 0 == _wchdir( wsPath.c_str() ); +#if defined(_WIN32) + std::wstring wsPath = UTF8to16(sPath.c_str()); + bSuccess = 0 == _wchdir(wsPath.c_str()); #else - bSuccess = 0 == chdir( sPath.c_str() ); + bSuccess = 0 == chdir(sPath.c_str()); #endif return bSuccess; } /** Returns the specified path without its filename */ -std::string Path_StripFilename( const std::string & sPath, char slash ) +std::string Path_StripFilename(const std::string &sPath, char slash) { - if( slash == 0 ) + if (slash == 0) slash = Path_GetSlash(); - std::string::size_type n = sPath.find_last_of( slash ); - if( n == std::string::npos ) + std::string::size_type n = sPath.find_last_of(slash); + if (n == std::string::npos) return sPath; else - return std::string( sPath.begin(), sPath.begin() + n ); + return std::string(sPath.begin(), sPath.begin() + n); } /** returns just the filename from the provided full or relative path. */ -std::string Path_StripDirectory( const std::string & sPath, char slash ) +std::string Path_StripDirectory(const std::string &sPath, char slash) { - if( slash == 0 ) + if (slash == 0) slash = Path_GetSlash(); - std::string::size_type n = sPath.find_last_of( slash ); - if( n == std::string::npos ) + std::string::size_type n = sPath.find_last_of(slash); + if (n == std::string::npos) return sPath; else - return std::string( sPath.begin() + n + 1, sPath.end() ); + return std::string(sPath.begin() + n + 1, sPath.end()); } /** returns just the filename with no extension of the provided filename. * If there is a path the path is left intact. */ -std::string Path_StripExtension( const std::string & sPath ) +std::string Path_StripExtension(const std::string &sPath) { - for( std::string::const_reverse_iterator i = sPath.rbegin(); i != sPath.rend(); i++ ) + for (std::string::const_reverse_iterator i = sPath.rbegin(); i != sPath.rend(); i++) { - if( *i == '.' ) + if (*i == '.') { - return std::string( sPath.begin(), i.base() - 1 ); + return std::string(sPath.begin(), i.base() - 1); } // if we find a slash there is no extension - if( *i == '\\' || *i == '/' ) + if (*i == '\\' || *i == '/') break; } @@ -145,17 +144,17 @@ std::string Path_StripExtension( const std::string & sPath ) } /** returns just extension of the provided filename (if any). */ -std::string Path_GetExtension( const std::string & sPath ) +std::string Path_GetExtension(const std::string &sPath) { - for ( std::string::const_reverse_iterator i = sPath.rbegin(); i != sPath.rend(); i++ ) + for (std::string::const_reverse_iterator i = sPath.rbegin(); i != sPath.rend(); i++) { - if ( *i == '.' ) + if (*i == '.') { - return std::string( i.base(), sPath.end() ); + return std::string(i.base(), sPath.end()); } // if we find a slash there is no extension - if ( *i == '\\' || *i == '/' ) + if (*i == '\\' || *i == '/') break; } @@ -163,70 +162,67 @@ std::string Path_GetExtension( const std::string & sPath ) return ""; } -bool Path_IsAbsolute( const std::string & sPath ) +bool Path_IsAbsolute(const std::string &sPath) { - if( sPath.empty() ) + if (sPath.empty()) return false; -#if defined( WIN32 ) - if ( sPath.size() < 3 ) // must be c:\x or \\x at least +#if defined(WIN32) + if (sPath.size() < 3) // must be c:\x or \\x at least return false; - if ( sPath[1] == ':' ) // drive letter plus slash, but must test both slash cases + if (sPath[1] == ':') // drive letter plus slash, but must test both slash cases { - if ( sPath[2] == '\\' || sPath[2] == '/' ) + if (sPath[2] == '\\' || sPath[2] == '/') return true; } - else if ( sPath[0] == '\\' && sPath[1] == '\\' ) // UNC path + else if (sPath[0] == '\\' && sPath[1] == '\\') // UNC path return true; #else - if( sPath[0] == '\\' || sPath[0] == '/' ) // any leading slash + if (sPath[0] == '\\' || sPath[0] == '/') // any leading slash return true; #endif return false; } - /** Makes an absolute path from a relative path and a base path */ -std::string Path_MakeAbsolute( const std::string & sRelativePath, const std::string & sBasePath, char slash ) +std::string Path_MakeAbsolute(const std::string &sRelativePath, const std::string &sBasePath, char slash) { - if( slash == 0 ) + if (slash == 0) slash = Path_GetSlash(); - if( Path_IsAbsolute( sRelativePath ) ) + if (Path_IsAbsolute(sRelativePath)) return sRelativePath; else { - if( !Path_IsAbsolute( sBasePath ) ) + if (!Path_IsAbsolute(sBasePath)) return ""; - std::string sCompacted = Path_Compact( Path_Join( sBasePath, sRelativePath, slash ), slash ); - if( Path_IsAbsolute( sCompacted ) ) + std::string sCompacted = Path_Compact(Path_Join(sBasePath, sRelativePath, slash), slash); + if (Path_IsAbsolute(sCompacted)) return sCompacted; else return ""; } } - /** Fixes the directory separators for the current platform */ -std::string Path_FixSlashes( const std::string & sPath, char slash ) +std::string Path_FixSlashes(const std::string &sPath, char slash) { - if( slash == 0 ) + if (slash == 0) slash = Path_GetSlash(); std::string sFixed = sPath; - for( std::string::iterator i = sFixed.begin(); i != sFixed.end(); i++ ) + for (std::string::iterator i = sFixed.begin(); i != sFixed.end(); i++) { - if( *i == '/' || *i == '\\' ) + if (*i == '/' || *i == '\\') *i = slash; } return sFixed; } - char Path_GetSlash() { #if defined(_WIN32) @@ -237,65 +233,63 @@ char Path_GetSlash() } /** Jams two paths together with the right kind of slash */ -std::string Path_Join( const std::string & first, const std::string & second, char slash ) +std::string Path_Join(const std::string &first, const std::string &second, char slash) { - if( slash == 0 ) + if (slash == 0) slash = Path_GetSlash(); // only insert a slash if we don't already have one std::string::size_type nLen = first.length(); - if( !nLen ) + if (!nLen) return second; #if defined(_WIN32) - if( first.back() == '\\' || first.back() == '/' ) - nLen--; + if (first.back() == '\\' || first.back() == '/') + nLen--; #else - char last_char = first[first.length()-1]; + char last_char = first[first.length() - 1]; if (last_char == '\\' || last_char == '/') - nLen--; + nLen--; #endif - return first.substr( 0, nLen ) + std::string( 1, slash ) + second; + return first.substr(0, nLen) + std::string(1, slash) + second; } - -std::string Path_Join( const std::string & first, const std::string & second, const std::string & third, char slash ) +std::string Path_Join(const std::string &first, const std::string &second, const std::string &third, char slash) { - return Path_Join( Path_Join( first, second, slash ), third, slash ); + return Path_Join(Path_Join(first, second, slash), third, slash); } -std::string Path_Join( const std::string & first, const std::string & second, const std::string & third, const std::string &fourth, char slash ) +std::string Path_Join(const std::string &first, const std::string &second, const std::string &third, const std::string &fourth, char slash) { - return Path_Join( Path_Join( Path_Join( first, second, slash ), third, slash ), fourth, slash ); + return Path_Join(Path_Join(Path_Join(first, second, slash), third, slash), fourth, slash); } -std::string Path_Join( - const std::string & first, - const std::string & second, - const std::string & third, - const std::string & fourth, - const std::string & fifth, - char slash ) +std::string Path_Join( + const std::string &first, + const std::string &second, + const std::string &third, + const std::string &fourth, + const std::string &fifth, + char slash) { - return Path_Join( Path_Join( Path_Join( Path_Join( first, second, slash ), third, slash ), fourth, slash ), fifth, slash ); + return Path_Join(Path_Join(Path_Join(Path_Join(first, second, slash), third, slash), fourth, slash), fifth, slash); } - -std::string Path_RemoveTrailingSlash( const std::string & sRawPath, char slash ) +std::string Path_RemoveTrailingSlash(const std::string &sRawPath, char slash) { - if ( slash == 0 ) + if (slash == 0) slash = Path_GetSlash(); std::string sPath = sRawPath; std::string::size_type nCurrent = sRawPath.length(); - if ( nCurrent == 0 ) + if (nCurrent == 0) return sPath; int nLastFound = -1; nCurrent--; - while( nCurrent != 0 ) + while (nCurrent != 0) { - if ( sRawPath[ nCurrent ] == slash ) + if (sRawPath[nCurrent] == slash) { nLastFound = (int)nCurrent; nCurrent--; @@ -305,32 +299,31 @@ std::string Path_RemoveTrailingSlash( const std::string & sRawPath, char slash ) break; } } - - if ( nLastFound >= 0 ) + + if (nLastFound >= 0) { - sPath.erase( nLastFound, std::string::npos ); + sPath.erase(nLastFound, std::string::npos); } - + return sPath; } - /** Removes redundant

/.. elements in the path. Returns an empty path if the * specified path has a broken number of directories for its number of ..s */ -std::string Path_Compact( const std::string & sRawPath, char slash ) +std::string Path_Compact(const std::string &sRawPath, char slash) { - if( slash == 0 ) + if (slash == 0) slash = Path_GetSlash(); - std::string sPath = Path_FixSlashes( sRawPath, slash ); - std::string sSlashString( 1, slash ); + std::string sPath = Path_FixSlashes(sRawPath, slash); + std::string sSlashString(1, slash); // strip out all /./ - for( std::string::size_type i = 0; (i + 3) < sPath.length(); ) + for (std::string::size_type i = 0; (i + 3) < sPath.length();) { - if( sPath[ i ] == slash && sPath[ i+1 ] == '.' && sPath[ i+2 ] == slash ) + if (sPath[i] == slash && sPath[i + 1] == '.' && sPath[i + 2] == slash) { - sPath.replace( i, 3, sSlashString ); + sPath.replace(i, 3, sSlashString); } else { @@ -338,49 +331,44 @@ std::string Path_Compact( const std::string & sRawPath, char slash ) } } - // get rid of trailing /. but leave the path separator - if( sPath.length() > 2 ) + if (sPath.length() > 2) { std::string::size_type len = sPath.length(); - if( sPath[ len-1 ] == '.' && sPath[ len-2 ] == slash ) + if (sPath[len - 1] == '.' && sPath[len - 2] == slash) { - // sPath.pop_back(); - sPath[len-1] = 0; // for now, at least + // sPath.pop_back(); + sPath[len - 1] = 0; // for now, at least } } - // get rid of leading ./ - if( sPath.length() > 2 ) + // get rid of leading ./ + if (sPath.length() > 2) { - if( sPath[ 0 ] == '.' && sPath[ 1 ] == slash ) + if (sPath[0] == '.' && sPath[1] == slash) { - sPath.replace( 0, 2, "" ); + sPath.replace(0, 2, ""); } } // each time we encounter .. back up until we've found the previous directory name // then get rid of both std::string::size_type i = 0; - while( i < sPath.length() ) + while (i < sPath.length()) { - if( i > 0 && sPath.length() - i >= 2 - && sPath[i] == '.' - && sPath[i+1] == '.' - && ( i + 2 == sPath.length() || sPath[ i+2 ] == slash ) - && sPath[ i-1 ] == slash ) + if (i > 0 && sPath.length() - i >= 2 && sPath[i] == '.' && sPath[i + 1] == '.' && (i + 2 == sPath.length() || sPath[i + 2] == slash) && sPath[i - 1] == slash) { // check if we've hit the start of the string and have a bogus path - if( i == 1 ) + if (i == 1) return ""; - + // find the separator before i-1 - std::string::size_type iDirStart = i-2; - while( iDirStart > 0 && sPath[ iDirStart - 1 ] != slash ) + std::string::size_type iDirStart = i - 2; + while (iDirStart > 0 && sPath[iDirStart - 1] != slash) --iDirStart; // remove everything from iDirStart to i+2 - sPath.replace( iDirStart, (i - iDirStart) + 3, "" ); + sPath.replace(iDirStart, (i - iDirStart) + 3, ""); // start over i = 0; @@ -394,7 +382,6 @@ std::string Path_Compact( const std::string & sRawPath, char slash ) return sPath; } - /** Returns the path to the current DLL or exe */ std::string Path_GetThisModulePath() { @@ -402,57 +389,55 @@ std::string Path_GetThisModulePath() #ifdef WIN32 HMODULE hmodule = NULL; - ::GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, reinterpret_cast(Path_GetThisModulePath), &hmodule ); + ::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, reinterpret_cast(Path_GetThisModulePath), &hmodule); wchar_t *pwchPath = new wchar_t[MAX_UNICODE_PATH]; - char *pchPath = new char[ MAX_UNICODE_PATH_IN_UTF8 ]; - ::GetModuleFileNameW( hmodule, pwchPath, MAX_UNICODE_PATH ); - WideCharToMultiByte( CP_UTF8, 0, pwchPath, -1, pchPath, MAX_UNICODE_PATH_IN_UTF8, NULL, NULL ); + char *pchPath = new char[MAX_UNICODE_PATH_IN_UTF8]; + ::GetModuleFileNameW(hmodule, pwchPath, MAX_UNICODE_PATH); + WideCharToMultiByte(CP_UTF8, 0, pwchPath, -1, pchPath, MAX_UNICODE_PATH_IN_UTF8, NULL, NULL); delete[] pwchPath; std::string sPath = pchPath; - delete [] pchPath; + delete[] pchPath; return sPath; -#elif defined( OSX ) || defined( LINUX ) +#elif defined(OSX) || defined(LINUX) // get the addr of a function in vrclient.so and then ask the dlopen system about it Dl_info info; - dladdr( (void *)Path_GetThisModulePath, &info ); + dladdr((void *)Path_GetThisModulePath, &info); return info.dli_fname; #endif - } - /** returns true if the specified path exists and is a directory */ -bool Path_IsDirectory( const std::string & sPath ) +bool Path_IsDirectory(const std::string &sPath) { - std::string sFixedPath = Path_FixSlashes( sPath ); - if( sFixedPath.empty() ) + std::string sFixedPath = Path_FixSlashes(sPath); + if (sFixedPath.empty()) return false; - char cLast = sFixedPath[ sFixedPath.length() - 1 ]; - if( cLast == '/' || cLast == '\\' ) - sFixedPath.erase( sFixedPath.end() - 1, sFixedPath.end() ); + char cLast = sFixedPath[sFixedPath.length() - 1]; + if (cLast == '/' || cLast == '\\') + sFixedPath.erase(sFixedPath.end() - 1, sFixedPath.end()); - // see if the specified path actually exists. + // see if the specified path actually exists. #if defined(POSIX) - struct stat buf; - if ( stat( sFixedPath.c_str(), &buf ) == -1 ) + struct stat buf; + if (stat(sFixedPath.c_str(), &buf) == -1) { return false; } -#if defined( LINUX ) || defined( OSX ) - return S_ISDIR( buf.st_mode ); +#if defined(LINUX) || defined(OSX) + return S_ISDIR(buf.st_mode); #else return (buf.st_mode & _S_IFDIR) != 0; #endif #else - struct _stat buf; - std::wstring wsFixedPath = UTF8to16( sFixedPath.c_str() ); - if ( _wstat( wsFixedPath.c_str(), &buf ) == -1 ) + struct _stat buf; + std::wstring wsFixedPath = UTF8to16(sFixedPath.c_str()); + if (_wstat(wsFixedPath.c_str(), &buf) == -1) { return false; } @@ -462,12 +447,12 @@ bool Path_IsDirectory( const std::string & sPath ) } /** returns true if the specified path represents an app bundle */ -bool Path_IsAppBundle( const std::string & sPath ) +bool Path_IsAppBundle(const std::string &sPath) { #if defined(OSX) - NSBundle *bundle = [ NSBundle bundleWithPath: [ NSString stringWithUTF8String:sPath.c_str() ] ]; - bool bisAppBundle = ( nullptr != bundle ); - [ bundle release ]; + NSBundle *bundle = [NSBundle bundleWithPath:[NSString stringWithUTF8String:sPath.c_str()]]; + bool bisAppBundle = (nullptr != bundle); + [bundle release]; return bisAppBundle; #else return false; @@ -477,22 +462,22 @@ bool Path_IsAppBundle( const std::string & sPath ) //----------------------------------------------------------------------------- // Purpose: returns true if the the path exists //----------------------------------------------------------------------------- -bool Path_Exists( const std::string & sPath ) +bool Path_Exists(const std::string &sPath) { - std::string sFixedPath = Path_FixSlashes( sPath ); - if( sFixedPath.empty() ) + std::string sFixedPath = Path_FixSlashes(sPath); + if (sFixedPath.empty()) return false; -#if defined( WIN32 ) - struct _stat buf; - std::wstring wsFixedPath = UTF8to16( sFixedPath.c_str() ); - if ( _wstat( wsFixedPath.c_str(), &buf ) == -1 ) +#if defined(WIN32) + struct _stat buf; + std::wstring wsFixedPath = UTF8to16(sFixedPath.c_str()); + if (_wstat(wsFixedPath.c_str(), &buf) == -1) { return false; } #else struct stat buf; - if ( stat ( sFixedPath.c_str(), &buf ) == -1) + if (stat(sFixedPath.c_str(), &buf) == -1) { return false; } @@ -501,78 +486,75 @@ bool Path_Exists( const std::string & sPath ) return true; } - //----------------------------------------------------------------------------- // Purpose: helper to find a directory upstream from a given path //----------------------------------------------------------------------------- -std::string Path_FindParentDirectoryRecursively( const std::string &strStartDirectory, const std::string &strDirectoryName ) +std::string Path_FindParentDirectoryRecursively(const std::string &strStartDirectory, const std::string &strDirectoryName) { std::string strFoundPath = ""; - std::string strCurrentPath = Path_FixSlashes( strStartDirectory ); - if ( strCurrentPath.length() == 0 ) + std::string strCurrentPath = Path_FixSlashes(strStartDirectory); + if (strCurrentPath.length() == 0) return ""; - bool bExists = Path_Exists( strCurrentPath ); - std::string strCurrentDirectoryName = Path_StripDirectory( strCurrentPath ); - if ( bExists && stricmp( strCurrentDirectoryName.c_str(), strDirectoryName.c_str() ) == 0 ) + bool bExists = Path_Exists(strCurrentPath); + std::string strCurrentDirectoryName = Path_StripDirectory(strCurrentPath); + if (bExists && stricmp(strCurrentDirectoryName.c_str(), strDirectoryName.c_str()) == 0) return strCurrentPath; - while( bExists && strCurrentPath.length() != 0 ) + while (bExists && strCurrentPath.length() != 0) { - strCurrentPath = Path_StripFilename( strCurrentPath ); - strCurrentDirectoryName = Path_StripDirectory( strCurrentPath ); - bExists = Path_Exists( strCurrentPath ); - if ( bExists && stricmp( strCurrentDirectoryName.c_str(), strDirectoryName.c_str() ) == 0 ) + strCurrentPath = Path_StripFilename(strCurrentPath); + strCurrentDirectoryName = Path_StripDirectory(strCurrentPath); + bExists = Path_Exists(strCurrentPath); + if (bExists && stricmp(strCurrentDirectoryName.c_str(), strDirectoryName.c_str()) == 0) return strCurrentPath; } return ""; } - //----------------------------------------------------------------------------- // Purpose: helper to find a subdirectory upstream from a given path //----------------------------------------------------------------------------- -std::string Path_FindParentSubDirectoryRecursively( const std::string &strStartDirectory, const std::string &strDirectoryName ) +std::string Path_FindParentSubDirectoryRecursively(const std::string &strStartDirectory, const std::string &strDirectoryName) { std::string strFoundPath = ""; - std::string strCurrentPath = Path_FixSlashes( strStartDirectory ); - if ( strCurrentPath.length() == 0 ) + std::string strCurrentPath = Path_FixSlashes(strStartDirectory); + if (strCurrentPath.length() == 0) return ""; - bool bExists = Path_Exists( strCurrentPath ); - while( bExists && strCurrentPath.length() != 0 ) + bool bExists = Path_Exists(strCurrentPath); + while (bExists && strCurrentPath.length() != 0) { - strCurrentPath = Path_StripFilename( strCurrentPath ); - bExists = Path_Exists( strCurrentPath ); + strCurrentPath = Path_StripFilename(strCurrentPath); + bExists = Path_Exists(strCurrentPath); - if( Path_Exists( Path_Join( strCurrentPath, strDirectoryName ) ) ) + if (Path_Exists(Path_Join(strCurrentPath, strDirectoryName))) { - strFoundPath = Path_Join( strCurrentPath, strDirectoryName ); + strFoundPath = Path_Join(strCurrentPath, strDirectoryName); break; } } return strFoundPath; } - //----------------------------------------------------------------------------- // Purpose: reading and writing files in the vortex directory //----------------------------------------------------------------------------- -unsigned char * Path_ReadBinaryFile( const std::string &strFilename, int *pSize ) +unsigned char *Path_ReadBinaryFile(const std::string &strFilename, int *pSize) { FILE *f; -#if defined( POSIX ) - f = fopen( strFilename.c_str(), "rb" ); +#if defined(POSIX) + f = fopen(strFilename.c_str(), "rb"); #else - std::wstring wstrFilename = UTF8to16( strFilename.c_str() ); + std::wstring wstrFilename = UTF8to16(strFilename.c_str()); // the open operation needs to be sharable, therefore use of _wfsopen instead of _wfopen_s - f = _wfsopen( wstrFilename.c_str(), L"rb", _SH_DENYNO ); + f = _wfsopen(wstrFilename.c_str(), L"rb", _SH_DENYNO); #endif - - unsigned char* buf = NULL; - if ( f != NULL ) + unsigned char *buf = NULL; + + if (f != NULL) { fseek(f, 0, SEEK_END); int size = ftell(f); @@ -596,15 +578,15 @@ unsigned char * Path_ReadBinaryFile( const std::string &strFilename, int *pSize return buf; } -uint32_t Path_ReadBinaryFile( const std::string &strFilename, unsigned char *pBuffer, uint32_t unSize ) +uint32_t Path_ReadBinaryFile(const std::string &strFilename, unsigned char *pBuffer, uint32_t unSize) { FILE *f; -#if defined( POSIX ) - f = fopen( strFilename.c_str(), "rb" ); +#if defined(POSIX) + f = fopen(strFilename.c_str(), "rb"); #else - std::wstring wstrFilename = UTF8to16( strFilename.c_str() ); - errno_t err = _wfopen_s( &f, wstrFilename.c_str(), L"rb" ); - if ( err != 0 ) + std::wstring wstrFilename = UTF8to16(strFilename.c_str()); + errno_t err = _wfopen_s(&f, wstrFilename.c_str(), L"rb"); + if (err != 0) { f = NULL; } @@ -612,25 +594,25 @@ uint32_t Path_ReadBinaryFile( const std::string &strFilename, unsigned char *pB uint32_t unSizeToReturn = 0; - if ( f != NULL ) + if (f != NULL) { - fseek( f, 0, SEEK_END ); - uint32_t size = (uint32_t)ftell( f ); - fseek( f, 0, SEEK_SET ); + fseek(f, 0, SEEK_END); + uint32_t size = (uint32_t)ftell(f); + fseek(f, 0, SEEK_SET); - if ( size > unSize || !pBuffer ) + if (size > unSize || !pBuffer) { unSizeToReturn = (uint32_t)size; } else { - if ( fread( pBuffer, size, 1, f ) == 1 ) + if (fread(pBuffer, size, 1, f) == 1) { unSizeToReturn = (uint32_t)size; } } - fclose( f ); + fclose(f); } return unSizeToReturn; @@ -639,11 +621,11 @@ uint32_t Path_ReadBinaryFile( const std::string &strFilename, unsigned char *pB bool Path_WriteBinaryFile(const std::string &strFilename, unsigned char *pData, unsigned nSize) { FILE *f; -#if defined( POSIX ) +#if defined(POSIX) f = fopen(strFilename.c_str(), "wb"); #else - std::wstring wstrFilename = UTF8to16( strFilename.c_str() ); - errno_t err = _wfopen_s( &f, wstrFilename.c_str(), L"wb" ); + std::wstring wstrFilename = UTF8to16(strFilename.c_str()); + errno_t err = _wfopen_s(&f, wstrFilename.c_str(), L"wb"); if (err != 0) { f = NULL; @@ -651,7 +633,8 @@ bool Path_WriteBinaryFile(const std::string &strFilename, unsigned char *pData, #endif size_t written = 0; - if (f != NULL) { + if (f != NULL) + { written = fwrite(pData, sizeof(unsigned char), nSize, f); fclose(f); } @@ -659,24 +642,24 @@ bool Path_WriteBinaryFile(const std::string &strFilename, unsigned char *pData, return written = nSize ? true : false; } -std::string Path_ReadTextFile( const std::string &strFilename ) +std::string Path_ReadTextFile(const std::string &strFilename) { // doing it this way seems backwards, but I don't // see an easy way to do this with C/C++ style IO // that isn't worse... int size; - unsigned char* buf = Path_ReadBinaryFile( strFilename, &size ); + unsigned char *buf = Path_ReadBinaryFile(strFilename, &size); if (!buf) return ""; // convert CRLF -> LF size_t outsize = 1; - for (int i=1; i < size; i++) + for (int i = 1; i < size; i++) { - if (buf[i] == '\n' && buf[i-1] == '\r') // CRLF - buf[outsize-1] = '\n'; // ->LF + if (buf[i] == '\n' && buf[i - 1] == '\r') // CRLF + buf[outsize - 1] = '\n'; // ->LF else - buf[outsize++] = buf[i]; // just copy + buf[outsize++] = buf[i]; // just copy } std::string ret((char *)buf, outsize); @@ -684,51 +667,50 @@ std::string Path_ReadTextFile( const std::string &strFilename ) return ret; } - -bool Path_WriteStringToTextFile( const std::string &strFilename, const char *pchData ) +bool Path_WriteStringToTextFile(const std::string &strFilename, const char *pchData) { FILE *f; -#if defined( POSIX ) - f = fopen( strFilename.c_str(), "w" ); +#if defined(POSIX) + f = fopen(strFilename.c_str(), "w"); #else - std::wstring wstrFilename = UTF8to16( strFilename.c_str() ); - errno_t err = _wfopen_s( &f, wstrFilename.c_str(), L"w" ); - if ( err != 0 ) + std::wstring wstrFilename = UTF8to16(strFilename.c_str()); + errno_t err = _wfopen_s(&f, wstrFilename.c_str(), L"w"); + if (err != 0) { f = NULL; } #endif - + bool ok = false; - if ( f != NULL ) + if (f != NULL) { - ok = fputs( pchData, f) >= 0; + ok = fputs(pchData, f) >= 0; fclose(f); } return ok; } -bool Path_WriteStringToTextFileAtomic( const std::string &strFilename, const char *pchData ) +bool Path_WriteStringToTextFileAtomic(const std::string &strFilename, const char *pchData) { std::string strTmpFilename = strFilename + ".tmp"; - if ( !Path_WriteStringToTextFile( strTmpFilename, pchData ) ) + if (!Path_WriteStringToTextFile(strTmpFilename, pchData)) return false; - // Platform specific atomic file replacement -#if defined( _WIN32 ) - std::wstring wsFilename = UTF8to16( strFilename.c_str() ); - std::wstring wsTmpFilename = UTF8to16( strTmpFilename.c_str() ); - if ( !::ReplaceFileW( wsFilename.c_str(), wsTmpFilename.c_str(), nullptr, 0, 0, 0 ) ) + // Platform specific atomic file replacement +#if defined(_WIN32) + std::wstring wsFilename = UTF8to16(strFilename.c_str()); + std::wstring wsTmpFilename = UTF8to16(strTmpFilename.c_str()); + if (!::ReplaceFileW(wsFilename.c_str(), wsTmpFilename.c_str(), nullptr, 0, 0, 0)) { // if we couldn't ReplaceFile, try a non-atomic write as a fallback - if ( !Path_WriteStringToTextFile( strFilename, pchData ) ) + if (!Path_WriteStringToTextFile(strFilename, pchData)) return false; } -#elif defined( POSIX ) - if ( rename( strTmpFilename.c_str(), strFilename.c_str() ) == -1 ) +#elif defined(POSIX) + if (rename(strTmpFilename.c_str(), strFilename.c_str()) == -1) return false; #else #error Do not know how to write atomic file @@ -737,7 +719,6 @@ bool Path_WriteStringToTextFileAtomic( const std::string &strFilename, const cha return true; } - #if defined(WIN32) #define FILE_URL_PREFIX "file:///" #else @@ -747,31 +728,29 @@ bool Path_WriteStringToTextFileAtomic( const std::string &strFilename, const cha // ---------------------------------------------------------------------------------------------------------------------------- // Purpose: Turns a path to a file on disk into a URL (or just returns the value if it's already a URL) // ---------------------------------------------------------------------------------------------------------------------------- -std::string Path_FilePathToUrl( const std::string & sRelativePath, const std::string & sBasePath ) +std::string Path_FilePathToUrl(const std::string &sRelativePath, const std::string &sBasePath) { - if ( !strnicmp( sRelativePath.c_str(), "http://", 7 ) - || !strnicmp( sRelativePath.c_str(), "https://", 8 ) - || !strnicmp( sRelativePath.c_str(), "file://", 7 ) ) + if (!strnicmp(sRelativePath.c_str(), "http://", 7) || !strnicmp(sRelativePath.c_str(), "https://", 8) || !strnicmp(sRelativePath.c_str(), "file://", 7)) { return sRelativePath; } else { - std::string sAbsolute = Path_MakeAbsolute( sRelativePath, sBasePath ); - if ( sAbsolute.empty() ) + std::string sAbsolute = Path_MakeAbsolute(sRelativePath, sBasePath); + if (sAbsolute.empty()) return sAbsolute; - return std::string( FILE_URL_PREFIX ) + sAbsolute; + return std::string(FILE_URL_PREFIX) + sAbsolute; } } // ----------------------------------------------------------------------------------------------------- // Purpose: Strips off file:// off a URL and returns the path. For other kinds of URLs an empty string is returned // ----------------------------------------------------------------------------------------------------- -std::string Path_UrlToFilePath( const std::string & sFileUrl ) +std::string Path_UrlToFilePath(const std::string &sFileUrl) { - if ( !strnicmp( sFileUrl.c_str(), FILE_URL_PREFIX, strlen( FILE_URL_PREFIX ) ) ) + if (!strnicmp(sFileUrl.c_str(), FILE_URL_PREFIX, strlen(FILE_URL_PREFIX))) { - return sFileUrl.c_str() + strlen( FILE_URL_PREFIX ); + return sFileUrl.c_str() + strlen(FILE_URL_PREFIX); } else { @@ -779,42 +758,41 @@ std::string Path_UrlToFilePath( const std::string & sFileUrl ) } } - // ----------------------------------------------------------------------------------------------------- // Purpose: Returns the root of the directory the system wants us to store user documents in // ----------------------------------------------------------------------------------------------------- std::string GetUserDocumentsPath() { -#if defined( WIN32 ) +#if defined(WIN32) WCHAR rwchPath[MAX_PATH]; - if ( !SUCCEEDED( SHGetFolderPathW( NULL, CSIDL_MYDOCUMENTS | CSIDL_FLAG_CREATE, NULL, 0, rwchPath ) ) ) + if (!SUCCEEDED(SHGetFolderPathW(NULL, CSIDL_MYDOCUMENTS | CSIDL_FLAG_CREATE, NULL, 0, rwchPath))) { return ""; } // Convert the path to UTF-8 and store in the output - std::string sUserPath = UTF16to8( rwchPath ); + std::string sUserPath = UTF16to8(rwchPath); return sUserPath; -#elif defined( OSX ) - @autoreleasepool { - NSArray *paths = NSSearchPathForDirectoriesInDomains( NSDocumentDirectory, NSUserDomainMask, YES ); - if ( [paths count] == 0 ) +#elif defined(OSX) + @autoreleasepool + { + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + if ([paths count] == 0) { return ""; } - + return [[paths objectAtIndex:0] UTF8String]; } -#elif defined( LINUX ) +#elif defined(LINUX) // @todo: not solved/changed as part of OSX - still not real - just removed old class based steam cut and paste - const char *pchHome = getenv( "HOME" ); - if ( pchHome == NULL ) + const char *pchHome = getenv("HOME"); + if (pchHome == NULL) { return ""; } return pchHome; #endif } - diff --git a/examples/ThirdPartyLibs/openvr/samples/shared/pathtools.h b/examples/ThirdPartyLibs/openvr/samples/shared/pathtools.h index 7c34a7175..7898a4a40 100644 --- a/examples/ThirdPartyLibs/openvr/samples/shared/pathtools.h +++ b/examples/ThirdPartyLibs/openvr/samples/shared/pathtools.h @@ -11,7 +11,7 @@ std::string Path_GetExecutablePath(); std::string Path_GetWorkingDirectory(); /** Sets the path of the current working directory. Returns true if this was successful. */ -bool Path_SetWorkingDirectory( const std::string & sPath ); +bool Path_SetWorkingDirectory(const std::string &sPath); /** returns the path (including filename) of the current shared lib or DLL */ std::string Path_GetThisModulePath(); @@ -19,111 +19,110 @@ std::string Path_GetThisModulePath(); /** Returns the specified path without its filename. * If slash is unspecified the native path separator of the current platform * will be used. */ -std::string Path_StripFilename( const std::string & sPath, char slash = 0 ); +std::string Path_StripFilename(const std::string &sPath, char slash = 0); /** returns just the filename from the provided full or relative path. */ -std::string Path_StripDirectory( const std::string & sPath, char slash = 0 ); +std::string Path_StripDirectory(const std::string &sPath, char slash = 0); /** returns just the filename with no extension of the provided filename. * If there is a path the path is left intact. */ -std::string Path_StripExtension( const std::string & sPath ); +std::string Path_StripExtension(const std::string &sPath); /** returns just extension of the provided filename (if any). */ -std::string Path_GetExtension( const std::string & sPath ); +std::string Path_GetExtension(const std::string &sPath); /** Returns true if the path is absolute */ -bool Path_IsAbsolute( const std::string & sPath ); +bool Path_IsAbsolute(const std::string &sPath); /** Makes an absolute path from a relative path and a base path */ -std::string Path_MakeAbsolute( const std::string & sRelativePath, const std::string & sBasePath, char slash = 0 ); +std::string Path_MakeAbsolute(const std::string &sRelativePath, const std::string &sBasePath, char slash = 0); /** Fixes the directory separators for the current platform. * If slash is unspecified the native path separator of the current platform * will be used. */ -std::string Path_FixSlashes( const std::string & sPath, char slash = 0 ); +std::string Path_FixSlashes(const std::string &sPath, char slash = 0); /** Returns the path separator for the current platform */ char Path_GetSlash(); /** Jams two paths together with the right kind of slash */ -std::string Path_Join( const std::string & first, const std::string & second, char slash = 0 ); -std::string Path_Join( const std::string & first, const std::string & second, const std::string & third, char slash = 0 ); -std::string Path_Join( const std::string & first, const std::string & second, const std::string & third, const std::string &fourth, char slash = 0 ); -std::string Path_Join( - const std::string & first, - const std::string & second, - const std::string & third, - const std::string & fourth, - const std::string & fifth, - char slash = 0 ); - +std::string Path_Join(const std::string &first, const std::string &second, char slash = 0); +std::string Path_Join(const std::string &first, const std::string &second, const std::string &third, char slash = 0); +std::string Path_Join(const std::string &first, const std::string &second, const std::string &third, const std::string &fourth, char slash = 0); +std::string Path_Join( + const std::string &first, + const std::string &second, + const std::string &third, + const std::string &fourth, + const std::string &fifth, + char slash = 0); /** Removes redundant /.. elements in the path. Returns an empty path if the * specified path has a broken number of directories for its number of ..s. * If slash is unspecified the native path separator of the current platform * will be used. */ -std::string Path_Compact( const std::string & sRawPath, char slash = 0 ); +std::string Path_Compact(const std::string &sRawPath, char slash = 0); //** Removed trailing slashes */ -std::string Path_RemoveTrailingSlash( const std::string & sRawPath, char slash = 0 ); +std::string Path_RemoveTrailingSlash(const std::string &sRawPath, char slash = 0); /** returns true if the specified path exists and is a directory */ -bool Path_IsDirectory( const std::string & sPath ); +bool Path_IsDirectory(const std::string &sPath); /** returns true if the specified path represents an app bundle */ -bool Path_IsAppBundle( const std::string & sPath ); +bool Path_IsAppBundle(const std::string &sPath); /** returns true if the the path exists */ -bool Path_Exists( const std::string & sPath ); +bool Path_Exists(const std::string &sPath); /** Helper functions to find parent directories or subdirectories of parent directories */ -std::string Path_FindParentDirectoryRecursively( const std::string &strStartDirectory, const std::string &strDirectoryName ); -std::string Path_FindParentSubDirectoryRecursively( const std::string &strStartDirectory, const std::string &strDirectoryName ); +std::string Path_FindParentDirectoryRecursively(const std::string &strStartDirectory, const std::string &strDirectoryName); +std::string Path_FindParentSubDirectoryRecursively(const std::string &strStartDirectory, const std::string &strDirectoryName); /** Path operations to read or write text/binary files */ -unsigned char * Path_ReadBinaryFile( const std::string &strFilename, int *pSize ); -uint32_t Path_ReadBinaryFile( const std::string &strFilename, unsigned char *pBuffer, uint32_t unSize ); -bool Path_WriteBinaryFile( const std::string &strFilename, unsigned char *pData, unsigned nSize ); -std::string Path_ReadTextFile( const std::string &strFilename ); -bool Path_WriteStringToTextFile( const std::string &strFilename, const char *pchData ); -bool Path_WriteStringToTextFileAtomic( const std::string &strFilename, const char *pchData ); +unsigned char *Path_ReadBinaryFile(const std::string &strFilename, int *pSize); +uint32_t Path_ReadBinaryFile(const std::string &strFilename, unsigned char *pBuffer, uint32_t unSize); +bool Path_WriteBinaryFile(const std::string &strFilename, unsigned char *pData, unsigned nSize); +std::string Path_ReadTextFile(const std::string &strFilename); +bool Path_WriteStringToTextFile(const std::string &strFilename, const char *pchData); +bool Path_WriteStringToTextFileAtomic(const std::string &strFilename, const char *pchData); /** Returns a file:// url for paths, or an http or https url if that's what was provided */ -std::string Path_FilePathToUrl( const std::string & sRelativePath, const std::string & sBasePath ); +std::string Path_FilePathToUrl(const std::string &sRelativePath, const std::string &sBasePath); /** Strips off file:// off a URL and returns the path. For other kinds of URLs an empty string is returned */ -std::string Path_UrlToFilePath( const std::string & sFileUrl ); +std::string Path_UrlToFilePath(const std::string &sFileUrl); /** Returns the root of the directory the system wants us to store user documents in */ std::string GetUserDocumentsPath(); #ifndef MAX_UNICODE_PATH - #define MAX_UNICODE_PATH 32767 +#define MAX_UNICODE_PATH 32767 #endif #ifndef MAX_UNICODE_PATH_IN_UTF8 - #define MAX_UNICODE_PATH_IN_UTF8 (MAX_UNICODE_PATH * 4) +#define MAX_UNICODE_PATH_IN_UTF8 (MAX_UNICODE_PATH * 4) #endif //----------------------------------------------------------------------------- #if defined(WIN32) -#define DYNAMIC_LIB_EXT ".dll" +#define DYNAMIC_LIB_EXT ".dll" #ifdef _WIN64 -#define PLATSUBDIR "win64" +#define PLATSUBDIR "win64" #else -#define PLATSUBDIR "win32" +#define PLATSUBDIR "win32" #endif #elif defined(OSX) -#define DYNAMIC_LIB_EXT ".dylib" -#define PLATSUBDIR "osx32" +#define DYNAMIC_LIB_EXT ".dylib" +#define PLATSUBDIR "osx32" #elif defined(LINUX) -#define DYNAMIC_LIB_EXT ".so" -#if defined( LINUX32 ) -#define PLATSUBDIR "linux32" +#define DYNAMIC_LIB_EXT ".so" +#if defined(LINUX32) +#define PLATSUBDIR "linux32" #else -#define PLATSUBDIR "linux64" +#define PLATSUBDIR "linux64" #endif #else #warning "Unknown platform for PLATSUBDIR" -#define PLATSUBDIR "unknown_platform" +#define PLATSUBDIR "unknown_platform" #endif diff --git a/examples/ThirdPartyLibs/openvr/samples/shared/strtools.cpp b/examples/ThirdPartyLibs/openvr/samples/shared/strtools.cpp index d47519224..9e1d77b5d 100644 --- a/examples/ThirdPartyLibs/openvr/samples/shared/strtools.cpp +++ b/examples/ThirdPartyLibs/openvr/samples/shared/strtools.cpp @@ -9,55 +9,53 @@ #define strnicmp strncasecmp #endif - //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -bool StringHasPrefix( const std::string & sString, const std::string & sPrefix ) +bool StringHasPrefix(const std::string &sString, const std::string &sPrefix) { - return 0 == strnicmp( sString.c_str(), sPrefix.c_str(), sPrefix.length() ); + return 0 == strnicmp(sString.c_str(), sPrefix.c_str(), sPrefix.length()); } -bool StringHasPrefixCaseSensitive( const std::string & sString, const std::string & sPrefix ) +bool StringHasPrefixCaseSensitive(const std::string &sString, const std::string &sPrefix) { - return 0 == strncmp( sString.c_str(), sPrefix.c_str(), sPrefix.length() ); + return 0 == strncmp(sString.c_str(), sPrefix.c_str(), sPrefix.length()); } - -bool StringHasSuffix( const std::string &sString, const std::string &sSuffix ) +bool StringHasSuffix(const std::string &sString, const std::string &sSuffix) { size_t cStrLen = sString.length(); size_t cSuffixLen = sSuffix.length(); - if ( cSuffixLen > cStrLen ) + if (cSuffixLen > cStrLen) return false; - std::string sStringSuffix = sString.substr( cStrLen - cSuffixLen, cSuffixLen ); + std::string sStringSuffix = sString.substr(cStrLen - cSuffixLen, cSuffixLen); - return 0 == stricmp( sStringSuffix.c_str(), sSuffix.c_str() ); + return 0 == stricmp(sStringSuffix.c_str(), sSuffix.c_str()); } -bool StringHasSuffixCaseSensitive( const std::string &sString, const std::string &sSuffix ) +bool StringHasSuffixCaseSensitive(const std::string &sString, const std::string &sSuffix) { size_t cStrLen = sString.length(); size_t cSuffixLen = sSuffix.length(); - if ( cSuffixLen > cStrLen ) + if (cSuffixLen > cStrLen) return false; - std::string sStringSuffix = sString.substr( cStrLen - cSuffixLen, cSuffixLen ); + std::string sStringSuffix = sString.substr(cStrLen - cSuffixLen, cSuffixLen); - return 0 == strncmp( sStringSuffix.c_str(), sSuffix.c_str(),cSuffixLen ); + return 0 == strncmp(sStringSuffix.c_str(), sSuffix.c_str(), cSuffixLen); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- -std::string UTF16to8(const wchar_t * in) +std::string UTF16to8(const wchar_t *in) { std::string out; unsigned int codepoint = 0; - for ( ; in && *in != 0; ++in ) + for (; in && *in != 0; ++in) { if (*in >= 0xd800 && *in <= 0xdbff) codepoint = ((*in - 0xd800) << 10) + 0x10000; @@ -94,12 +92,12 @@ std::string UTF16to8(const wchar_t * in) return out; } -std::wstring UTF8to16(const char * in) +std::wstring UTF8to16(const char *in) { std::wstring out; unsigned int codepoint = 0; int following = 0; - for ( ; in && *in != 0; ++in ) + for (; in && *in != 0; ++in) { unsigned char ch = *in; if (ch <= 0x7f) @@ -145,111 +143,106 @@ std::wstring UTF8to16(const char * in) return out; } - -void strcpy_safe( char *pchBuffer, size_t unBufferSizeBytes, const char *pchSource ) +void strcpy_safe(char *pchBuffer, size_t unBufferSizeBytes, const char *pchSource) { - pchBuffer[ unBufferSizeBytes - 1 ] = '\0'; - strncpy( pchBuffer, pchSource, unBufferSizeBytes - 1 ); + pchBuffer[unBufferSizeBytes - 1] = '\0'; + strncpy(pchBuffer, pchSource, unBufferSizeBytes - 1); } - // -------------------------------------------------------------------- // Purpose: converts a string to upper case // -------------------------------------------------------------------- -std::string StringToUpper( const std::string & sString ) +std::string StringToUpper(const std::string &sString) { std::string sOut; - sOut.reserve( sString.size() + 1 ); - for( std::string::const_iterator i = sString.begin(); i != sString.end(); i++ ) + sOut.reserve(sString.size() + 1); + for (std::string::const_iterator i = sString.begin(); i != sString.end(); i++) { - sOut.push_back( (char)toupper( *i ) ); + sOut.push_back((char)toupper(*i)); } return sOut; } - // -------------------------------------------------------------------- // Purpose: converts a string to lower case // -------------------------------------------------------------------- -std::string StringToLower( const std::string & sString ) +std::string StringToLower(const std::string &sString) { std::string sOut; - sOut.reserve( sString.size() + 1 ); - for( std::string::const_iterator i = sString.begin(); i != sString.end(); i++ ) + sOut.reserve(sString.size() + 1); + for (std::string::const_iterator i = sString.begin(); i != sString.end(); i++) { - sOut.push_back( (char)tolower( *i ) ); + sOut.push_back((char)tolower(*i)); } return sOut; } - -uint32_t ReturnStdString( const std::string & sValue, char *pchBuffer, uint32_t unBufferLen ) +uint32_t ReturnStdString(const std::string &sValue, char *pchBuffer, uint32_t unBufferLen) { uint32_t unLen = (uint32_t)sValue.length() + 1; - if( !pchBuffer || !unBufferLen ) + if (!pchBuffer || !unBufferLen) return unLen; - if( unBufferLen < unLen ) + if (unBufferLen < unLen) { pchBuffer[0] = '\0'; } else { - memcpy( pchBuffer, sValue.c_str(), unLen ); + memcpy(pchBuffer, sValue.c_str(), unLen); } return unLen; } -void BufferToStdString( std::string & sDest, const char *pchBuffer, uint32_t unBufferLen ) +void BufferToStdString(std::string &sDest, const char *pchBuffer, uint32_t unBufferLen) { - sDest.resize( unBufferLen + 1 ); - memcpy( const_cast< char* >( sDest.c_str() ), pchBuffer, unBufferLen ); - const_cast< char* >( sDest.c_str() )[ unBufferLen ] = '\0'; + sDest.resize(unBufferLen + 1); + memcpy(const_cast(sDest.c_str()), pchBuffer, unBufferLen); + const_cast(sDest.c_str())[unBufferLen] = '\0'; } /** Returns a std::string from a uint64_t */ -std::string Uint64ToString( uint64_t ulValue ) +std::string Uint64ToString(uint64_t ulValue) { - char buf[ 22 ]; -#if defined( _WIN32 ) - sprintf_s( buf, "%llu", ulValue ); + char buf[22]; +#if defined(_WIN32) + sprintf_s(buf, "%llu", ulValue); #else - snprintf( buf, sizeof( buf ), "%llu", (long long unsigned int ) ulValue ); + snprintf(buf, sizeof(buf), "%llu", (long long unsigned int)ulValue); #endif return buf; } - /** returns a uint64_t from a string */ -uint64_t StringToUint64( const std::string & sValue ) +uint64_t StringToUint64(const std::string &sValue) { - return strtoull( sValue.c_str(), NULL, 0 ); + return strtoull(sValue.c_str(), NULL, 0); } //----------------------------------------------------------------------------- // Purpose: Helper for converting a numeric value to a hex digit, value should be 0-15. //----------------------------------------------------------------------------- -char cIntToHexDigit( int nValue ) +char cIntToHexDigit(int nValue) { //Assert( nValue >= 0 && nValue <= 15 ); - return "0123456789ABCDEF"[ nValue & 15 ]; + return "0123456789ABCDEF"[nValue & 15]; } //----------------------------------------------------------------------------- // Purpose: Helper for converting a hex char value to numeric, return -1 if the char // is not a valid hex digit. //----------------------------------------------------------------------------- -int iHexCharToInt( char cValue ) +int iHexCharToInt(char cValue) { int32_t iValue = cValue; - if ( (uint32_t)( iValue - '0' ) < 10 ) + if ((uint32_t)(iValue - '0') < 10) return iValue - '0'; iValue |= 0x20; - if ( (uint32_t)( iValue - 'a' ) < 6 ) + if ((uint32_t)(iValue - 'a') < 6) return iValue - 'a' + 10; return -1; @@ -259,29 +252,27 @@ int iHexCharToInt( char cValue ) // Purpose: Internal implementation of encode, works in the strict RFC manner, or // with spaces turned to + like HTML form encoding. //----------------------------------------------------------------------------- -void V_URLEncodeInternal( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen, bool bUsePlusForSpace ) +void V_URLEncodeInternal(char *pchDest, int nDestLen, const char *pchSource, int nSourceLen, bool bUsePlusForSpace) { //AssertMsg( nDestLen > 3*nSourceLen, "Target buffer for V_URLEncode should be 3x source length, plus one for terminating null\n" ); - + int iDestPos = 0; - for ( int i=0; i < nSourceLen; ++i ) + for (int i = 0; i < nSourceLen; ++i) { // worst case we need 3 additional chars - if( (iDestPos+3) > nDestLen ) + if ((iDestPos + 3) > nDestLen) { pchDest[0] = '\0'; -// AssertMsg( false, "Target buffer too short\n" ); + // AssertMsg( false, "Target buffer too short\n" ); return; } // We allow only a-z, A-Z, 0-9, period, underscore, and hyphen to pass through unescaped. // These are the characters allowed by both the original RFC 1738 and the latest RFC 3986. // Current specs also allow '~', but that is forbidden under original RFC 1738. - if ( !( pchSource[i] >= 'a' && pchSource[i] <= 'z' ) && !( pchSource[i] >= 'A' && pchSource[i] <= 'Z' ) && !(pchSource[i] >= '0' && pchSource[i] <= '9' ) - && pchSource[i] != '-' && pchSource[i] != '_' && pchSource[i] != '.' - ) + if (!(pchSource[i] >= 'a' && pchSource[i] <= 'z') && !(pchSource[i] >= 'A' && pchSource[i] <= 'Z') && !(pchSource[i] >= '0' && pchSource[i] <= '9') && pchSource[i] != '-' && pchSource[i] != '_' && pchSource[i] != '.') { - if ( bUsePlusForSpace && pchSource[i] == ' ' ) + if (bUsePlusForSpace && pchSource[i] == ' ') { pchDest[iDestPos++] = '+'; } @@ -289,16 +280,16 @@ void V_URLEncodeInternal( char *pchDest, int nDestLen, const char *pchSource, in { pchDest[iDestPos++] = '%'; uint8_t iValue = pchSource[i]; - if ( iValue == 0 ) + if (iValue == 0) { pchDest[iDestPos++] = '0'; pchDest[iDestPos++] = '0'; } else { - char cHexDigit1 = cIntToHexDigit( iValue % 16 ); + char cHexDigit1 = cIntToHexDigit(iValue % 16); iValue /= 16; - char cHexDigit2 = cIntToHexDigit( iValue ); + char cHexDigit2 = cIntToHexDigit(iValue); pchDest[iDestPos++] = cHexDigit2; pchDest[iDestPos++] = cHexDigit1; } @@ -310,7 +301,7 @@ void V_URLEncodeInternal( char *pchDest, int nDestLen, const char *pchSource, in } } - if( (iDestPos+1) > nDestLen ) + if ((iDestPos + 1) > nDestLen) { pchDest[0] = '\0'; //AssertMsg( false, "Target buffer too short to terminate\n" ); @@ -321,61 +312,60 @@ void V_URLEncodeInternal( char *pchDest, int nDestLen, const char *pchSource, in pchDest[iDestPos++] = 0; } - //----------------------------------------------------------------------------- // Purpose: Internal implementation of decode, works in the strict RFC manner, or // with spaces turned to + like HTML form encoding. // // Returns the amount of space used in the output buffer. //----------------------------------------------------------------------------- -size_t V_URLDecodeInternal( char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen, bool bUsePlusForSpace ) +size_t V_URLDecodeInternal(char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen, bool bUsePlusForSpace) { - if ( nDecodeDestLen < nEncodedSourceLen ) + if (nDecodeDestLen < nEncodedSourceLen) { //AssertMsg( false, "V_URLDecode needs a dest buffer at least as large as the source" ); return 0; } int iDestPos = 0; - for( int i=0; i < nEncodedSourceLen; ++i ) + for (int i = 0; i < nEncodedSourceLen; ++i) { - if ( bUsePlusForSpace && pchEncodedSource[i] == '+' ) + if (bUsePlusForSpace && pchEncodedSource[i] == '+') { - pchDecodeDest[ iDestPos++ ] = ' '; + pchDecodeDest[iDestPos++] = ' '; } - else if ( pchEncodedSource[i] == '%' ) + else if (pchEncodedSource[i] == '%') { // Percent signifies an encoded value, look ahead for the hex code, convert to numeric, and use that // First make sure we have 2 more chars - if ( i < nEncodedSourceLen - 2 ) + if (i < nEncodedSourceLen - 2) { - char cHexDigit1 = pchEncodedSource[i+1]; - char cHexDigit2 = pchEncodedSource[i+2]; + char cHexDigit1 = pchEncodedSource[i + 1]; + char cHexDigit2 = pchEncodedSource[i + 2]; // Turn the chars into a hex value, if they are not valid, then we'll // just place the % and the following two chars direct into the string, // even though this really shouldn't happen, who knows what bad clients // may do with encoding. bool bValid = false; - int iValue = iHexCharToInt( cHexDigit1 ); - if ( iValue != -1 ) + int iValue = iHexCharToInt(cHexDigit1); + if (iValue != -1) { iValue *= 16; - int iValue2 = iHexCharToInt( cHexDigit2 ); - if ( iValue2 != -1 ) + int iValue2 = iHexCharToInt(cHexDigit2); + if (iValue2 != -1) { iValue += iValue2; - pchDecodeDest[ iDestPos++ ] = (char)iValue; + pchDecodeDest[iDestPos++] = (char)iValue; bValid = true; } } - if ( !bValid ) + if (!bValid) { - pchDecodeDest[ iDestPos++ ] = '%'; - pchDecodeDest[ iDestPos++ ] = cHexDigit1; - pchDecodeDest[ iDestPos++ ] = cHexDigit2; + pchDecodeDest[iDestPos++] = '%'; + pchDecodeDest[iDestPos++] = cHexDigit1; + pchDecodeDest[iDestPos++] = cHexDigit2; } } @@ -384,13 +374,13 @@ size_t V_URLDecodeInternal( char *pchDecodeDest, int nDecodeDestLen, const char } else { - pchDecodeDest[ iDestPos++ ] = pchEncodedSource[i]; + pchDecodeDest[iDestPos++] = pchEncodedSource[i]; } } // We may not have extra room to NULL terminate, since this can be used on raw data, but if we do // go ahead and do it as this can avoid bugs. - if ( iDestPos < nDecodeDestLen ) + if (iDestPos < nDecodeDestLen) { pchDecodeDest[iDestPos] = 0; } @@ -399,45 +389,43 @@ size_t V_URLDecodeInternal( char *pchDecodeDest, int nDecodeDestLen, const char } //----------------------------------------------------------------------------- -// Purpose: Encodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2. +// Purpose: Encodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2. // This version of the call isn't a strict RFC implementation, but uses + for space as is // the standard in HTML form encoding, despite it not being part of the RFC. // // Dest buffer should be at least as large as source buffer to guarantee room for decode. //----------------------------------------------------------------------------- -void V_URLEncode( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen ) +void V_URLEncode(char *pchDest, int nDestLen, const char *pchSource, int nSourceLen) { - return V_URLEncodeInternal( pchDest, nDestLen, pchSource, nSourceLen, true ); + return V_URLEncodeInternal(pchDest, nDestLen, pchSource, nSourceLen, true); } - //----------------------------------------------------------------------------- -// Purpose: Decodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2. +// Purpose: Decodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2. // This version of the call isn't a strict RFC implementation, but uses + for space as is // the standard in HTML form encoding, despite it not being part of the RFC. // // Dest buffer should be at least as large as source buffer to guarantee room for decode. // Dest buffer being the same as the source buffer (decode in-place) is explicitly allowed. //----------------------------------------------------------------------------- -size_t V_URLDecode( char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen ) +size_t V_URLDecode(char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen) { - return V_URLDecodeInternal( pchDecodeDest, nDecodeDestLen, pchEncodedSource, nEncodedSourceLen, true ); + return V_URLDecodeInternal(pchDecodeDest, nDecodeDestLen, pchEncodedSource, nEncodedSourceLen, true); } //----------------------------------------------------------------------------- -void V_StripExtension( std::string &in ) +void V_StripExtension(std::string &in) { - // Find the last dot. If it's followed by a dot or a slash, then it's part of a + // Find the last dot. If it's followed by a dot or a slash, then it's part of a // directory specifier like ../../somedir/./blah. - std::string::size_type test = in.rfind( '.' ); - if ( test != std::string::npos ) + std::string::size_type test = in.rfind('.'); + if (test != std::string::npos) { // This handles things like ".\blah" or "c:\my@email.com\abc\def\geh" // Which would otherwise wind up with "" and "c:\my@email", respectively. - if ( in.rfind( '\\' ) < test && in.rfind( '/' ) < test ) + if (in.rfind('\\') < test && in.rfind('/') < test) { - in.resize( test ); + in.resize(test); } } } - diff --git a/examples/ThirdPartyLibs/openvr/samples/shared/strtools.h b/examples/ThirdPartyLibs/openvr/samples/shared/strtools.h index 57e62714d..c3b310cc9 100644 --- a/examples/ThirdPartyLibs/openvr/samples/shared/strtools.h +++ b/examples/ThirdPartyLibs/openvr/samples/shared/strtools.h @@ -6,45 +6,50 @@ #include /** returns true if the string has the prefix */ -bool StringHasPrefix( const std::string & sString, const std::string & sPrefix ); -bool StringHasPrefixCaseSensitive( const std::string & sString, const std::string & sPrefix ); +bool StringHasPrefix(const std::string &sString, const std::string &sPrefix); +bool StringHasPrefixCaseSensitive(const std::string &sString, const std::string &sPrefix); /** returns if the string has the suffix */ -bool StringHasSuffix( const std::string &sString, const std::string &sSuffix ); -bool StringHasSuffixCaseSensitive( const std::string &sString, const std::string &sSuffix ); +bool StringHasSuffix(const std::string &sString, const std::string &sSuffix); +bool StringHasSuffixCaseSensitive(const std::string &sString, const std::string &sSuffix); /** converts a UTF-16 string to a UTF-8 string */ -std::string UTF16to8(const wchar_t * in); +std::string UTF16to8(const wchar_t *in); /** converts a UTF-8 string to a UTF-16 string */ -std::wstring UTF8to16(const char * in); +std::wstring UTF8to16(const char *in); #define Utf16FromUtf8 UTF8to16 /** safely copy a string into a buffer */ -void strcpy_safe( char *pchBuffer, size_t unBufferSizeBytes, const char *pchSource ); -template< size_t bufferSize > -void strcpy_safe( char (& buffer) [ bufferSize ], const char *pchSource ) +void strcpy_safe(char *pchBuffer, size_t unBufferSizeBytes, const char *pchSource); +template +void strcpy_safe(char (&buffer)[bufferSize], const char *pchSource) { - strcpy_safe( buffer, bufferSize, pchSource ); + strcpy_safe(buffer, bufferSize, pchSource); } - /** converts a string to upper case */ -std::string StringToUpper( const std::string & sString ); +std::string StringToUpper(const std::string &sString); /** converts a string to lower case */ -std::string StringToLower( const std::string & sString ); +std::string StringToLower(const std::string &sString); // we stricmp (from WIN) but it isn't POSIX - OSX/LINUX have strcasecmp so just inline bridge to it -#if defined( OSX ) || defined( LINUX ) -#ifndef __THROW // If __THROW is defined, these will clash with throw() versions on gcc - #include - inline int stricmp(const char *pStr1, const char *pStr2) { return strcasecmp(pStr1,pStr2); } - #ifndef _stricmp - #define _stricmp stricmp - #endif - inline int strnicmp( const char *pStr1, const char *pStr2, size_t unBufferLen ) { return strncasecmp( pStr1,pStr2, unBufferLen ); } - #define _strnicmp strnicmp +#if defined(OSX) || defined(LINUX) +#ifndef __THROW // If __THROW is defined, these will clash with throw() versions on gcc +#include +inline int stricmp(const char *pStr1, const char *pStr2) +{ + return strcasecmp(pStr1, pStr2); +} +#ifndef _stricmp +#define _stricmp stricmp +#endif +inline int strnicmp(const char *pStr1, const char *pStr2, size_t unBufferLen) +{ + return strncasecmp(pStr1, pStr2, unBufferLen); +} +#define _strnicmp strnicmp #endif #ifndef _vsnprintf_s @@ -53,9 +58,9 @@ std::string StringToLower( const std::string & sString ); #define _TRUNCATE ((size_t)-1) -#endif // defined( OSX ) || defined( LINUX ) +#endif // defined( OSX ) || defined( LINUX ) -#if defined( OSX ) +#if defined(OSX) // behaviors ensure NULL-termination at least as well as _TRUNCATE does, but // wcsncpy_s/strncpy_s can non-NULL-terminate, wcslcpy/strlcpy can not. inline errno_t wcsncpy_s(wchar_t *strDest, size_t numberOfElements, const wchar_t *strSource, size_t count) @@ -70,63 +75,64 @@ inline errno_t strncpy_s(char *strDest, size_t numberOfElements, const char *str #endif -#if defined( LINUX ) -// this implementation does not return whether or not the destination was +#if defined(LINUX) +// this implementation does not return whether or not the destination was // truncated, but that is straightforward to fix if anybody actually needs the -// return code. +// return code. #include "string.h" inline void wcsncpy_s(wchar_t *strDest, size_t numberOfElements, const wchar_t *strSource, size_t count) { wcsncpy(strDest, strSource, numberOfElements); - strDest[numberOfElements-1] = '\0'; + strDest[numberOfElements - 1] = '\0'; } inline void strncpy_s(char *strDest, size_t numberOfElements, const char *strSource, size_t count) { strncpy(strDest, strSource, numberOfElements); - strDest[numberOfElements-1] = '\0'; + strDest[numberOfElements - 1] = '\0'; } #endif -#if defined( _WIN32 ) && _MSC_VER < 1800 -inline uint64_t strtoull(const char *str, char **endptr, int base) { return _strtoui64( str, endptr, base ); } +#if defined(_WIN32) && _MSC_VER < 1800 +inline uint64_t strtoull(const char *str, char **endptr, int base) +{ + return _strtoui64(str, endptr, base); +} #endif /* Handles copying a std::string into a buffer as would be provided in an API */ -uint32_t ReturnStdString( const std::string & sValue, char *pchBuffer, uint32_t unBufferLen ); +uint32_t ReturnStdString(const std::string &sValue, char *pchBuffer, uint32_t unBufferLen); /* Handles copying a buffer into an std::string and auto adds null terminator */ -void BufferToStdString( std::string & sDest, const char *pchBuffer, uint32_t unBufferLen ); +void BufferToStdString(std::string &sDest, const char *pchBuffer, uint32_t unBufferLen); /** Returns a std::string from a uint64_t */ -std::string Uint64ToString( uint64_t ulValue ); +std::string Uint64ToString(uint64_t ulValue); /** returns a uint64_t from a string */ -uint64_t StringToUint64( const std::string & sValue ); +uint64_t StringToUint64(const std::string &sValue); //----------------------------------------------------------------------------- -// Purpose: Encodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2. +// Purpose: Encodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2. // This version of the call isn't a strict RFC implementation, but uses + for space as is // the standard in HTML form encoding, despite it not being part of the RFC. // // Dest buffer should be at least as large as source buffer to guarantee room for decode. //----------------------------------------------------------------------------- -void V_URLEncode( char *pchDest, int nDestLen, const char *pchSource, int nSourceLen ); +void V_URLEncode(char *pchDest, int nDestLen, const char *pchSource, int nSourceLen); //----------------------------------------------------------------------------- -// Purpose: Decodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2. +// Purpose: Decodes a string (or binary data) from URL encoding format, see rfc1738 section 2.2. // This version of the call isn't a strict RFC implementation, but uses + for space as is // the standard in HTML form encoding, despite it not being part of the RFC. // // Dest buffer should be at least as large as source buffer to guarantee room for decode. // Dest buffer being the same as the source buffer (decode in-place) is explicitly allowed. //----------------------------------------------------------------------------- -size_t V_URLDecode( char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen ); +size_t V_URLDecode(char *pchDecodeDest, int nDecodeDestLen, const char *pchEncodedSource, int nEncodedSourceLen); //----------------------------------------------------------------------------- // Purpose: strip extension from a path //----------------------------------------------------------------------------- -void V_StripExtension( std::string &in ); - - +void V_StripExtension(std::string &in); diff --git a/examples/ThirdPartyLibs/optionalX11/X11/X.h b/examples/ThirdPartyLibs/optionalX11/X11/X.h index 5cf695d7b..515666577 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/X.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/X.h @@ -50,8 +50,8 @@ SOFTWARE. ******************************************************************/ -#define X_PROTOCOL 11 /* current protocol version */ -#define X_PROTOCOL_REVISION 0 /* current minor version */ +#define X_PROTOCOL 11 /* current protocol version */ +#define X_PROTOCOL_REVISION 0 /* current minor version */ /* Resources */ @@ -61,34 +61,34 @@ SOFTWARE. * client or library code. */ #ifndef _XSERVER64 -# ifndef _XTYPEDEF_XID -# define _XTYPEDEF_XID +#ifndef _XTYPEDEF_XID +#define _XTYPEDEF_XID typedef unsigned long XID; -# endif -# ifndef _XTYPEDEF_MASK -# define _XTYPEDEF_MASK +#endif +#ifndef _XTYPEDEF_MASK +#define _XTYPEDEF_MASK typedef unsigned long Mask; -# endif -# ifndef _XTYPEDEF_ATOM -# define _XTYPEDEF_ATOM -typedef unsigned long Atom; /* Also in Xdefs.h */ -# endif +#endif +#ifndef _XTYPEDEF_ATOM +#define _XTYPEDEF_ATOM +typedef unsigned long Atom; /* Also in Xdefs.h */ +#endif typedef unsigned long VisualID; typedef unsigned long Time; #else -# include -# ifndef _XTYPEDEF_XID -# define _XTYPEDEF_XID +#include +#ifndef _XTYPEDEF_XID +#define _XTYPEDEF_XID typedef CARD32 XID; -# endif -# ifndef _XTYPEDEF_MASK -# define _XTYPEDEF_MASK +#endif +#ifndef _XTYPEDEF_MASK +#define _XTYPEDEF_MASK typedef CARD32 Mask; -# endif -# ifndef _XTYPEDEF_ATOM -# define _XTYPEDEF_ATOM +#endif +#ifndef _XTYPEDEF_ATOM +#define _XTYPEDEF_ATOM typedef CARD32 Atom; -# endif +#endif typedef CARD32 VisualID; typedef CARD32 Time; #endif @@ -96,7 +96,7 @@ typedef CARD32 Time; typedef XID Window; typedef XID Drawable; #ifndef _XTYPEDEF_FONT -# define _XTYPEDEF_FONT +#define _XTYPEDEF_FONT typedef XID Font; #endif typedef XID Pixmap; @@ -112,33 +112,33 @@ typedef unsigned char KeyCode; *****************************************************************/ #ifndef None -#define None 0L /* universal null resource or null atom */ +#define None 0L /* universal null resource or null atom */ #endif -#define ParentRelative 1L /* background pixmap in CreateWindow +#define ParentRelative 1L /* background pixmap in CreateWindow and ChangeWindowAttributes */ -#define CopyFromParent 0L /* border pixmap in CreateWindow +#define CopyFromParent 0L /* border pixmap in CreateWindow and ChangeWindowAttributes special VisualID and special window class passed to CreateWindow */ -#define PointerWindow 0L /* destination window in SendEvent */ -#define InputFocus 1L /* destination window in SendEvent */ +#define PointerWindow 0L /* destination window in SendEvent */ +#define InputFocus 1L /* destination window in SendEvent */ -#define PointerRoot 1L /* focus window in SetInputFocus */ +#define PointerRoot 1L /* focus window in SetInputFocus */ -#define AnyPropertyType 0L /* special Atom, passed to GetProperty */ +#define AnyPropertyType 0L /* special Atom, passed to GetProperty */ -#define AnyKey 0L /* special Key Code, passed to GrabKey */ +#define AnyKey 0L /* special Key Code, passed to GrabKey */ -#define AnyButton 0L /* special Button Code, passed to GrabButton */ +#define AnyButton 0L /* special Button Code, passed to GrabButton */ -#define AllTemporary 0L /* special Resource ID passed to KillClient */ +#define AllTemporary 0L /* special Resource ID passed to KillClient */ -#define CurrentTime 0L /* special Time */ +#define CurrentTime 0L /* special Time */ -#define NoSymbol 0L /* special KeySym */ +#define NoSymbol 0L /* special KeySym */ /***************************************************************** * EVENT DEFINITIONS @@ -147,217 +147,214 @@ typedef unsigned char KeyCode; /* Input Event Masks. Used as event-mask window attribute and as arguments to Grab requests. Not to be confused with event names. */ -#define NoEventMask 0L -#define KeyPressMask (1L<<0) -#define KeyReleaseMask (1L<<1) -#define ButtonPressMask (1L<<2) -#define ButtonReleaseMask (1L<<3) -#define EnterWindowMask (1L<<4) -#define LeaveWindowMask (1L<<5) -#define PointerMotionMask (1L<<6) -#define PointerMotionHintMask (1L<<7) -#define Button1MotionMask (1L<<8) -#define Button2MotionMask (1L<<9) -#define Button3MotionMask (1L<<10) -#define Button4MotionMask (1L<<11) -#define Button5MotionMask (1L<<12) -#define ButtonMotionMask (1L<<13) -#define KeymapStateMask (1L<<14) -#define ExposureMask (1L<<15) -#define VisibilityChangeMask (1L<<16) -#define StructureNotifyMask (1L<<17) -#define ResizeRedirectMask (1L<<18) -#define SubstructureNotifyMask (1L<<19) -#define SubstructureRedirectMask (1L<<20) -#define FocusChangeMask (1L<<21) -#define PropertyChangeMask (1L<<22) -#define ColormapChangeMask (1L<<23) -#define OwnerGrabButtonMask (1L<<24) +#define NoEventMask 0L +#define KeyPressMask (1L << 0) +#define KeyReleaseMask (1L << 1) +#define ButtonPressMask (1L << 2) +#define ButtonReleaseMask (1L << 3) +#define EnterWindowMask (1L << 4) +#define LeaveWindowMask (1L << 5) +#define PointerMotionMask (1L << 6) +#define PointerMotionHintMask (1L << 7) +#define Button1MotionMask (1L << 8) +#define Button2MotionMask (1L << 9) +#define Button3MotionMask (1L << 10) +#define Button4MotionMask (1L << 11) +#define Button5MotionMask (1L << 12) +#define ButtonMotionMask (1L << 13) +#define KeymapStateMask (1L << 14) +#define ExposureMask (1L << 15) +#define VisibilityChangeMask (1L << 16) +#define StructureNotifyMask (1L << 17) +#define ResizeRedirectMask (1L << 18) +#define SubstructureNotifyMask (1L << 19) +#define SubstructureRedirectMask (1L << 20) +#define FocusChangeMask (1L << 21) +#define PropertyChangeMask (1L << 22) +#define ColormapChangeMask (1L << 23) +#define OwnerGrabButtonMask (1L << 24) /* Event names. Used in "type" field in XEvent structures. Not to be confused with event masks above. They start from 2 because 0 and 1 are reserved in the protocol for errors and replies. */ -#define KeyPress 2 -#define KeyRelease 3 -#define ButtonPress 4 -#define ButtonRelease 5 -#define MotionNotify 6 -#define EnterNotify 7 -#define LeaveNotify 8 -#define FocusIn 9 -#define FocusOut 10 -#define KeymapNotify 11 -#define Expose 12 -#define GraphicsExpose 13 -#define NoExpose 14 -#define VisibilityNotify 15 -#define CreateNotify 16 -#define DestroyNotify 17 -#define UnmapNotify 18 -#define MapNotify 19 -#define MapRequest 20 -#define ReparentNotify 21 -#define ConfigureNotify 22 -#define ConfigureRequest 23 -#define GravityNotify 24 -#define ResizeRequest 25 -#define CirculateNotify 26 -#define CirculateRequest 27 -#define PropertyNotify 28 -#define SelectionClear 29 -#define SelectionRequest 30 -#define SelectionNotify 31 -#define ColormapNotify 32 -#define ClientMessage 33 -#define MappingNotify 34 -#define GenericEvent 35 -#define LASTEvent 36 /* must be bigger than any event # */ - +#define KeyPress 2 +#define KeyRelease 3 +#define ButtonPress 4 +#define ButtonRelease 5 +#define MotionNotify 6 +#define EnterNotify 7 +#define LeaveNotify 8 +#define FocusIn 9 +#define FocusOut 10 +#define KeymapNotify 11 +#define Expose 12 +#define GraphicsExpose 13 +#define NoExpose 14 +#define VisibilityNotify 15 +#define CreateNotify 16 +#define DestroyNotify 17 +#define UnmapNotify 18 +#define MapNotify 19 +#define MapRequest 20 +#define ReparentNotify 21 +#define ConfigureNotify 22 +#define ConfigureRequest 23 +#define GravityNotify 24 +#define ResizeRequest 25 +#define CirculateNotify 26 +#define CirculateRequest 27 +#define PropertyNotify 28 +#define SelectionClear 29 +#define SelectionRequest 30 +#define SelectionNotify 31 +#define ColormapNotify 32 +#define ClientMessage 33 +#define MappingNotify 34 +#define GenericEvent 35 +#define LASTEvent 36 /* must be bigger than any event # */ /* Key masks. Used as modifiers to GrabButton and GrabKey, results of QueryPointer, state in various key-, mouse-, and button-related events. */ -#define ShiftMask (1<<0) -#define LockMask (1<<1) -#define ControlMask (1<<2) -#define Mod1Mask (1<<3) -#define Mod2Mask (1<<4) -#define Mod3Mask (1<<5) -#define Mod4Mask (1<<6) -#define Mod5Mask (1<<7) +#define ShiftMask (1 << 0) +#define LockMask (1 << 1) +#define ControlMask (1 << 2) +#define Mod1Mask (1 << 3) +#define Mod2Mask (1 << 4) +#define Mod3Mask (1 << 5) +#define Mod4Mask (1 << 6) +#define Mod5Mask (1 << 7) /* modifier names. Used to build a SetModifierMapping request or to read a GetModifierMapping request. These correspond to the masks defined above. */ -#define ShiftMapIndex 0 -#define LockMapIndex 1 -#define ControlMapIndex 2 -#define Mod1MapIndex 3 -#define Mod2MapIndex 4 -#define Mod3MapIndex 5 -#define Mod4MapIndex 6 -#define Mod5MapIndex 7 - +#define ShiftMapIndex 0 +#define LockMapIndex 1 +#define ControlMapIndex 2 +#define Mod1MapIndex 3 +#define Mod2MapIndex 4 +#define Mod3MapIndex 5 +#define Mod4MapIndex 6 +#define Mod5MapIndex 7 /* button masks. Used in same manner as Key masks above. Not to be confused with button names below. */ -#define Button1Mask (1<<8) -#define Button2Mask (1<<9) -#define Button3Mask (1<<10) -#define Button4Mask (1<<11) -#define Button5Mask (1<<12) - -#define AnyModifier (1<<15) /* used in GrabButton, GrabKey */ +#define Button1Mask (1 << 8) +#define Button2Mask (1 << 9) +#define Button3Mask (1 << 10) +#define Button4Mask (1 << 11) +#define Button5Mask (1 << 12) +#define AnyModifier (1 << 15) /* used in GrabButton, GrabKey */ /* button names. Used as arguments to GrabButton and as detail in ButtonPress and ButtonRelease events. Not to be confused with button masks above. Note that 0 is already defined above as "AnyButton". */ -#define Button1 1 -#define Button2 2 -#define Button3 3 -#define Button4 4 -#define Button5 5 +#define Button1 1 +#define Button2 2 +#define Button3 3 +#define Button4 4 +#define Button5 5 /* Notify modes */ -#define NotifyNormal 0 -#define NotifyGrab 1 -#define NotifyUngrab 2 -#define NotifyWhileGrabbed 3 +#define NotifyNormal 0 +#define NotifyGrab 1 +#define NotifyUngrab 2 +#define NotifyWhileGrabbed 3 + +#define NotifyHint 1 /* for MotionNotify events */ -#define NotifyHint 1 /* for MotionNotify events */ - /* Notify detail */ -#define NotifyAncestor 0 -#define NotifyVirtual 1 -#define NotifyInferior 2 -#define NotifyNonlinear 3 -#define NotifyNonlinearVirtual 4 -#define NotifyPointer 5 -#define NotifyPointerRoot 6 -#define NotifyDetailNone 7 +#define NotifyAncestor 0 +#define NotifyVirtual 1 +#define NotifyInferior 2 +#define NotifyNonlinear 3 +#define NotifyNonlinearVirtual 4 +#define NotifyPointer 5 +#define NotifyPointerRoot 6 +#define NotifyDetailNone 7 /* Visibility notify */ -#define VisibilityUnobscured 0 -#define VisibilityPartiallyObscured 1 -#define VisibilityFullyObscured 2 +#define VisibilityUnobscured 0 +#define VisibilityPartiallyObscured 1 +#define VisibilityFullyObscured 2 /* Circulation request */ -#define PlaceOnTop 0 -#define PlaceOnBottom 1 +#define PlaceOnTop 0 +#define PlaceOnBottom 1 /* protocol families */ -#define FamilyInternet 0 /* IPv4 */ -#define FamilyDECnet 1 -#define FamilyChaos 2 -#define FamilyInternet6 6 /* IPv6 */ +#define FamilyInternet 0 /* IPv4 */ +#define FamilyDECnet 1 +#define FamilyChaos 2 +#define FamilyInternet6 6 /* IPv6 */ /* authentication families not tied to a specific protocol */ #define FamilyServerInterpreted 5 /* Property notification */ -#define PropertyNewValue 0 -#define PropertyDelete 1 +#define PropertyNewValue 0 +#define PropertyDelete 1 /* Color Map notification */ -#define ColormapUninstalled 0 -#define ColormapInstalled 1 +#define ColormapUninstalled 0 +#define ColormapInstalled 1 /* GrabPointer, GrabButton, GrabKeyboard, GrabKey Modes */ -#define GrabModeSync 0 -#define GrabModeAsync 1 +#define GrabModeSync 0 +#define GrabModeAsync 1 /* GrabPointer, GrabKeyboard reply status */ -#define GrabSuccess 0 -#define AlreadyGrabbed 1 -#define GrabInvalidTime 2 -#define GrabNotViewable 3 -#define GrabFrozen 4 +#define GrabSuccess 0 +#define AlreadyGrabbed 1 +#define GrabInvalidTime 2 +#define GrabNotViewable 3 +#define GrabFrozen 4 /* AllowEvents modes */ -#define AsyncPointer 0 -#define SyncPointer 1 -#define ReplayPointer 2 -#define AsyncKeyboard 3 -#define SyncKeyboard 4 -#define ReplayKeyboard 5 -#define AsyncBoth 6 -#define SyncBoth 7 +#define AsyncPointer 0 +#define SyncPointer 1 +#define ReplayPointer 2 +#define AsyncKeyboard 3 +#define SyncKeyboard 4 +#define ReplayKeyboard 5 +#define AsyncBoth 6 +#define SyncBoth 7 /* Used in SetInputFocus, GetInputFocus */ -#define RevertToNone (int)None -#define RevertToPointerRoot (int)PointerRoot -#define RevertToParent 2 +#define RevertToNone (int)None +#define RevertToPointerRoot (int)PointerRoot +#define RevertToParent 2 /***************************************************************** * ERROR CODES *****************************************************************/ -#define Success 0 /* everything's okay */ -#define BadRequest 1 /* bad request code */ -#define BadValue 2 /* int parameter out of range */ -#define BadWindow 3 /* parameter not a Window */ -#define BadPixmap 4 /* parameter not a Pixmap */ -#define BadAtom 5 /* parameter not an Atom */ -#define BadCursor 6 /* parameter not a Cursor */ -#define BadFont 7 /* parameter not a Font */ -#define BadMatch 8 /* parameter mismatch */ -#define BadDrawable 9 /* parameter not a Pixmap or Window */ -#define BadAccess 10 /* depending on context: +#define Success 0 /* everything's okay */ +#define BadRequest 1 /* bad request code */ +#define BadValue 2 /* int parameter out of range */ +#define BadWindow 3 /* parameter not a Window */ +#define BadPixmap 4 /* parameter not a Pixmap */ +#define BadAtom 5 /* parameter not an Atom */ +#define BadCursor 6 /* parameter not a Cursor */ +#define BadFont 7 /* parameter not a Font */ +#define BadMatch 8 /* parameter mismatch */ +#define BadDrawable 9 /* parameter not a Pixmap or Window */ +#define BadAccess 10 /* depending on context: - key/button already grabbed - attempt to free an illegal cmap entry @@ -366,16 +363,16 @@ are reserved in the protocol for errors and replies. */ - attempt to modify the access control list from other than the local host. */ -#define BadAlloc 11 /* insufficient resources */ -#define BadColor 12 /* no such colormap */ -#define BadGC 13 /* parameter not a GC */ -#define BadIDChoice 14 /* choice not in range or already used */ -#define BadName 15 /* font or color name doesn't exist */ -#define BadLength 16 /* Request length incorrect */ -#define BadImplementation 17 /* server is defective */ +#define BadAlloc 11 /* insufficient resources */ +#define BadColor 12 /* no such colormap */ +#define BadGC 13 /* parameter not a GC */ +#define BadIDChoice 14 /* choice not in range or already used */ +#define BadName 15 /* font or color name doesn't exist */ +#define BadLength 16 /* Request length incorrect */ +#define BadImplementation 17 /* server is defective */ -#define FirstExtensionError 128 -#define LastExtensionError 255 +#define FirstExtensionError 128 +#define LastExtensionError 255 /***************************************************************** * WINDOW DEFINITIONS @@ -384,97 +381,96 @@ are reserved in the protocol for errors and replies. */ /* Window classes used by CreateWindow */ /* Note that CopyFromParent is already defined as 0 above */ -#define InputOutput 1 -#define InputOnly 2 +#define InputOutput 1 +#define InputOnly 2 /* Window attributes for CreateWindow and ChangeWindowAttributes */ -#define CWBackPixmap (1L<<0) -#define CWBackPixel (1L<<1) -#define CWBorderPixmap (1L<<2) -#define CWBorderPixel (1L<<3) -#define CWBitGravity (1L<<4) -#define CWWinGravity (1L<<5) -#define CWBackingStore (1L<<6) -#define CWBackingPlanes (1L<<7) -#define CWBackingPixel (1L<<8) -#define CWOverrideRedirect (1L<<9) -#define CWSaveUnder (1L<<10) -#define CWEventMask (1L<<11) -#define CWDontPropagate (1L<<12) -#define CWColormap (1L<<13) -#define CWCursor (1L<<14) +#define CWBackPixmap (1L << 0) +#define CWBackPixel (1L << 1) +#define CWBorderPixmap (1L << 2) +#define CWBorderPixel (1L << 3) +#define CWBitGravity (1L << 4) +#define CWWinGravity (1L << 5) +#define CWBackingStore (1L << 6) +#define CWBackingPlanes (1L << 7) +#define CWBackingPixel (1L << 8) +#define CWOverrideRedirect (1L << 9) +#define CWSaveUnder (1L << 10) +#define CWEventMask (1L << 11) +#define CWDontPropagate (1L << 12) +#define CWColormap (1L << 13) +#define CWCursor (1L << 14) /* ConfigureWindow structure */ -#define CWX (1<<0) -#define CWY (1<<1) -#define CWWidth (1<<2) -#define CWHeight (1<<3) -#define CWBorderWidth (1<<4) -#define CWSibling (1<<5) -#define CWStackMode (1<<6) - +#define CWX (1 << 0) +#define CWY (1 << 1) +#define CWWidth (1 << 2) +#define CWHeight (1 << 3) +#define CWBorderWidth (1 << 4) +#define CWSibling (1 << 5) +#define CWStackMode (1 << 6) /* Bit Gravity */ -#define ForgetGravity 0 -#define NorthWestGravity 1 -#define NorthGravity 2 -#define NorthEastGravity 3 -#define WestGravity 4 -#define CenterGravity 5 -#define EastGravity 6 -#define SouthWestGravity 7 -#define SouthGravity 8 -#define SouthEastGravity 9 -#define StaticGravity 10 +#define ForgetGravity 0 +#define NorthWestGravity 1 +#define NorthGravity 2 +#define NorthEastGravity 3 +#define WestGravity 4 +#define CenterGravity 5 +#define EastGravity 6 +#define SouthWestGravity 7 +#define SouthGravity 8 +#define SouthEastGravity 9 +#define StaticGravity 10 /* Window gravity + bit gravity above */ -#define UnmapGravity 0 +#define UnmapGravity 0 /* Used in CreateWindow for backing-store hint */ -#define NotUseful 0 -#define WhenMapped 1 -#define Always 2 +#define NotUseful 0 +#define WhenMapped 1 +#define Always 2 /* Used in GetWindowAttributes reply */ -#define IsUnmapped 0 -#define IsUnviewable 1 -#define IsViewable 2 +#define IsUnmapped 0 +#define IsUnviewable 1 +#define IsViewable 2 /* Used in ChangeSaveSet */ -#define SetModeInsert 0 -#define SetModeDelete 1 +#define SetModeInsert 0 +#define SetModeDelete 1 /* Used in ChangeCloseDownMode */ -#define DestroyAll 0 -#define RetainPermanent 1 -#define RetainTemporary 2 +#define DestroyAll 0 +#define RetainPermanent 1 +#define RetainTemporary 2 /* Window stacking method (in configureWindow) */ -#define Above 0 -#define Below 1 -#define TopIf 2 -#define BottomIf 3 -#define Opposite 4 +#define Above 0 +#define Below 1 +#define TopIf 2 +#define BottomIf 3 +#define Opposite 4 /* Circulation direction */ -#define RaiseLowest 0 -#define LowerHighest 1 +#define RaiseLowest 0 +#define LowerHighest 1 /* Property modes */ -#define PropModeReplace 0 -#define PropModePrepend 1 -#define PropModeAppend 2 +#define PropModeReplace 0 +#define PropModePrepend 1 +#define PropModeAppend 2 /***************************************************************** * GRAPHICS DEFINITIONS @@ -482,120 +478,120 @@ are reserved in the protocol for errors and replies. */ /* graphics functions, as in GC.alu */ -#define GXclear 0x0 /* 0 */ -#define GXand 0x1 /* src AND dst */ -#define GXandReverse 0x2 /* src AND NOT dst */ -#define GXcopy 0x3 /* src */ -#define GXandInverted 0x4 /* NOT src AND dst */ -#define GXnoop 0x5 /* dst */ -#define GXxor 0x6 /* src XOR dst */ -#define GXor 0x7 /* src OR dst */ -#define GXnor 0x8 /* NOT src AND NOT dst */ -#define GXequiv 0x9 /* NOT src XOR dst */ -#define GXinvert 0xa /* NOT dst */ -#define GXorReverse 0xb /* src OR NOT dst */ -#define GXcopyInverted 0xc /* NOT src */ -#define GXorInverted 0xd /* NOT src OR dst */ -#define GXnand 0xe /* NOT src OR NOT dst */ -#define GXset 0xf /* 1 */ +#define GXclear 0x0 /* 0 */ +#define GXand 0x1 /* src AND dst */ +#define GXandReverse 0x2 /* src AND NOT dst */ +#define GXcopy 0x3 /* src */ +#define GXandInverted 0x4 /* NOT src AND dst */ +#define GXnoop 0x5 /* dst */ +#define GXxor 0x6 /* src XOR dst */ +#define GXor 0x7 /* src OR dst */ +#define GXnor 0x8 /* NOT src AND NOT dst */ +#define GXequiv 0x9 /* NOT src XOR dst */ +#define GXinvert 0xa /* NOT dst */ +#define GXorReverse 0xb /* src OR NOT dst */ +#define GXcopyInverted 0xc /* NOT src */ +#define GXorInverted 0xd /* NOT src OR dst */ +#define GXnand 0xe /* NOT src OR NOT dst */ +#define GXset 0xf /* 1 */ /* LineStyle */ -#define LineSolid 0 -#define LineOnOffDash 1 -#define LineDoubleDash 2 +#define LineSolid 0 +#define LineOnOffDash 1 +#define LineDoubleDash 2 /* capStyle */ -#define CapNotLast 0 -#define CapButt 1 -#define CapRound 2 -#define CapProjecting 3 +#define CapNotLast 0 +#define CapButt 1 +#define CapRound 2 +#define CapProjecting 3 /* joinStyle */ -#define JoinMiter 0 -#define JoinRound 1 -#define JoinBevel 2 +#define JoinMiter 0 +#define JoinRound 1 +#define JoinBevel 2 /* fillStyle */ -#define FillSolid 0 -#define FillTiled 1 -#define FillStippled 2 -#define FillOpaqueStippled 3 +#define FillSolid 0 +#define FillTiled 1 +#define FillStippled 2 +#define FillOpaqueStippled 3 /* fillRule */ -#define EvenOddRule 0 -#define WindingRule 1 +#define EvenOddRule 0 +#define WindingRule 1 /* subwindow mode */ -#define ClipByChildren 0 -#define IncludeInferiors 1 +#define ClipByChildren 0 +#define IncludeInferiors 1 /* SetClipRectangles ordering */ -#define Unsorted 0 -#define YSorted 1 -#define YXSorted 2 -#define YXBanded 3 +#define Unsorted 0 +#define YSorted 1 +#define YXSorted 2 +#define YXBanded 3 /* CoordinateMode for drawing routines */ -#define CoordModeOrigin 0 /* relative to the origin */ -#define CoordModePrevious 1 /* relative to previous point */ +#define CoordModeOrigin 0 /* relative to the origin */ +#define CoordModePrevious 1 /* relative to previous point */ /* Polygon shapes */ -#define Complex 0 /* paths may intersect */ -#define Nonconvex 1 /* no paths intersect, but not convex */ -#define Convex 2 /* wholly convex */ +#define Complex 0 /* paths may intersect */ +#define Nonconvex 1 /* no paths intersect, but not convex */ +#define Convex 2 /* wholly convex */ /* Arc modes for PolyFillArc */ -#define ArcChord 0 /* join endpoints of arc */ -#define ArcPieSlice 1 /* join endpoints to center of arc */ +#define ArcChord 0 /* join endpoints of arc */ +#define ArcPieSlice 1 /* join endpoints to center of arc */ /* GC components: masks used in CreateGC, CopyGC, ChangeGC, OR'ed into GC.stateChanges */ -#define GCFunction (1L<<0) -#define GCPlaneMask (1L<<1) -#define GCForeground (1L<<2) -#define GCBackground (1L<<3) -#define GCLineWidth (1L<<4) -#define GCLineStyle (1L<<5) -#define GCCapStyle (1L<<6) -#define GCJoinStyle (1L<<7) -#define GCFillStyle (1L<<8) -#define GCFillRule (1L<<9) -#define GCTile (1L<<10) -#define GCStipple (1L<<11) -#define GCTileStipXOrigin (1L<<12) -#define GCTileStipYOrigin (1L<<13) -#define GCFont (1L<<14) -#define GCSubwindowMode (1L<<15) -#define GCGraphicsExposures (1L<<16) -#define GCClipXOrigin (1L<<17) -#define GCClipYOrigin (1L<<18) -#define GCClipMask (1L<<19) -#define GCDashOffset (1L<<20) -#define GCDashList (1L<<21) -#define GCArcMode (1L<<22) +#define GCFunction (1L << 0) +#define GCPlaneMask (1L << 1) +#define GCForeground (1L << 2) +#define GCBackground (1L << 3) +#define GCLineWidth (1L << 4) +#define GCLineStyle (1L << 5) +#define GCCapStyle (1L << 6) +#define GCJoinStyle (1L << 7) +#define GCFillStyle (1L << 8) +#define GCFillRule (1L << 9) +#define GCTile (1L << 10) +#define GCStipple (1L << 11) +#define GCTileStipXOrigin (1L << 12) +#define GCTileStipYOrigin (1L << 13) +#define GCFont (1L << 14) +#define GCSubwindowMode (1L << 15) +#define GCGraphicsExposures (1L << 16) +#define GCClipXOrigin (1L << 17) +#define GCClipYOrigin (1L << 18) +#define GCClipMask (1L << 19) +#define GCDashOffset (1L << 20) +#define GCDashList (1L << 21) +#define GCArcMode (1L << 22) -#define GCLastBit 22 +#define GCLastBit 22 /***************************************************************** * FONTS *****************************************************************/ /* used in QueryFont -- draw direction */ -#define FontLeftToRight 0 -#define FontRightToLeft 1 +#define FontLeftToRight 0 +#define FontRightToLeft 1 -#define FontChange 255 +#define FontChange 255 /***************************************************************** * IMAGING @@ -603,9 +599,9 @@ are reserved in the protocol for errors and replies. */ /* ImageFormat -- PutImage, GetImage */ -#define XYBitmap 0 /* depth 1, XYFormat */ -#define XYPixmap 1 /* depth == drawable depth */ -#define ZPixmap 2 /* depth == drawable depth */ +#define XYBitmap 0 /* depth 1, XYFormat */ +#define XYPixmap 1 /* depth == drawable depth */ +#define ZPixmap 2 /* depth == drawable depth */ /***************************************************************** * COLOR MAP STUFF @@ -613,15 +609,14 @@ are reserved in the protocol for errors and replies. */ /* For CreateColormap */ -#define AllocNone 0 /* create map with no entries */ -#define AllocAll 1 /* allocate entire map writeable */ - +#define AllocNone 0 /* create map with no entries */ +#define AllocAll 1 /* allocate entire map writeable */ /* Flags used in StoreNamedColor, StoreColors */ -#define DoRed (1<<0) -#define DoGreen (1<<1) -#define DoBlue (1<<2) +#define DoRed (1 << 0) +#define DoGreen (1 << 1) +#define DoBlue (1 << 2) /***************************************************************** * CURSOR STUFF @@ -629,54 +624,54 @@ are reserved in the protocol for errors and replies. */ /* QueryBestSize Class */ -#define CursorShape 0 /* largest size that can be displayed */ -#define TileShape 1 /* size tiled fastest */ -#define StippleShape 2 /* size stippled fastest */ +#define CursorShape 0 /* largest size that can be displayed */ +#define TileShape 1 /* size tiled fastest */ +#define StippleShape 2 /* size stippled fastest */ /***************************************************************** * KEYBOARD/POINTER STUFF *****************************************************************/ -#define AutoRepeatModeOff 0 -#define AutoRepeatModeOn 1 -#define AutoRepeatModeDefault 2 +#define AutoRepeatModeOff 0 +#define AutoRepeatModeOn 1 +#define AutoRepeatModeDefault 2 -#define LedModeOff 0 -#define LedModeOn 1 +#define LedModeOff 0 +#define LedModeOn 1 /* masks for ChangeKeyboardControl */ -#define KBKeyClickPercent (1L<<0) -#define KBBellPercent (1L<<1) -#define KBBellPitch (1L<<2) -#define KBBellDuration (1L<<3) -#define KBLed (1L<<4) -#define KBLedMode (1L<<5) -#define KBKey (1L<<6) -#define KBAutoRepeatMode (1L<<7) +#define KBKeyClickPercent (1L << 0) +#define KBBellPercent (1L << 1) +#define KBBellPitch (1L << 2) +#define KBBellDuration (1L << 3) +#define KBLed (1L << 4) +#define KBLedMode (1L << 5) +#define KBKey (1L << 6) +#define KBAutoRepeatMode (1L << 7) -#define MappingSuccess 0 -#define MappingBusy 1 -#define MappingFailed 2 +#define MappingSuccess 0 +#define MappingBusy 1 +#define MappingFailed 2 -#define MappingModifier 0 -#define MappingKeyboard 1 -#define MappingPointer 2 +#define MappingModifier 0 +#define MappingKeyboard 1 +#define MappingPointer 2 /***************************************************************** * SCREEN SAVER STUFF *****************************************************************/ -#define DontPreferBlanking 0 -#define PreferBlanking 1 -#define DefaultBlanking 2 +#define DontPreferBlanking 0 +#define PreferBlanking 1 +#define DefaultBlanking 2 -#define DisableScreenSaver 0 -#define DisableScreenInterval 0 +#define DisableScreenSaver 0 +#define DisableScreenInterval 0 -#define DontAllowExposures 0 -#define AllowExposures 1 -#define DefaultExposures 2 +#define DontAllowExposures 0 +#define AllowExposures 1 +#define DefaultExposures 2 /* for ForceScreenSaver */ @@ -689,29 +684,28 @@ are reserved in the protocol for errors and replies. */ /* for ChangeHosts */ -#define HostInsert 0 -#define HostDelete 1 +#define HostInsert 0 +#define HostDelete 1 /* for ChangeAccessControl */ -#define EnableAccess 1 -#define DisableAccess 0 +#define EnableAccess 1 +#define DisableAccess 0 /* Display classes used in opening the connection * Note that the statically allocated ones are even numbered and the * dynamically changeable ones are odd numbered */ -#define StaticGray 0 -#define GrayScale 1 -#define StaticColor 2 -#define PseudoColor 3 -#define TrueColor 4 -#define DirectColor 5 - +#define StaticGray 0 +#define GrayScale 1 +#define StaticColor 2 +#define PseudoColor 3 +#define TrueColor 4 +#define DirectColor 5 /* Byte order used in imageByteOrder and bitmapBitOrder */ -#define LSBFirst 0 -#define MSBFirst 1 +#define LSBFirst 0 +#define MSBFirst 1 #endif /* X_H */ diff --git a/examples/ThirdPartyLibs/optionalX11/X11/XKBlib.h b/examples/ThirdPartyLibs/optionalX11/X11/XKBlib.h index 8f6c72c12..3607db0cb 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/XKBlib.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/XKBlib.h @@ -30,1118 +30,1126 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. #include #include -typedef struct _XkbAnyEvent { - int type; /* XkbAnyEvent */ - unsigned long serial; /* # of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XKB event minor code */ - unsigned int device; /* device ID */ +typedef struct _XkbAnyEvent +{ + int type; /* XkbAnyEvent */ + unsigned long serial; /* # of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display* display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XKB event minor code */ + unsigned int device; /* device ID */ } XkbAnyEvent; -typedef struct _XkbNewKeyboardNotify { - int type; /* XkbAnyEvent */ - unsigned long serial; /* of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbNewKeyboardNotify */ - int device; /* device ID */ - int old_device; /* device ID of previous keyboard */ - int min_key_code; /* minimum key code */ - int max_key_code; /* maximum key code */ - int old_min_key_code;/* min key code of previous kbd */ - int old_max_key_code;/* max key code of previous kbd */ - unsigned int changed; /* changed aspects of the keyboard */ - char req_major; /* major and minor opcode of req */ - char req_minor; /* that caused change, if applicable */ +typedef struct _XkbNewKeyboardNotify +{ + int type; /* XkbAnyEvent */ + unsigned long serial; /* of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display* display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbNewKeyboardNotify */ + int device; /* device ID */ + int old_device; /* device ID of previous keyboard */ + int min_key_code; /* minimum key code */ + int max_key_code; /* maximum key code */ + int old_min_key_code; /* min key code of previous kbd */ + int old_max_key_code; /* max key code of previous kbd */ + unsigned int changed; /* changed aspects of the keyboard */ + char req_major; /* major and minor opcode of req */ + char req_minor; /* that caused change, if applicable */ } XkbNewKeyboardNotifyEvent; -typedef struct _XkbMapNotifyEvent { - int type; /* XkbAnyEvent */ - unsigned long serial; /* of last req processed by server */ - Bool send_event; /* is this from a SendEvent request */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbMapNotify */ - int device; /* device ID */ - unsigned int changed; /* fields which have been changed */ - unsigned int flags; /* reserved */ - int first_type; /* first changed key type */ - int num_types; /* number of changed key types */ - KeyCode min_key_code; - KeyCode max_key_code; - KeyCode first_key_sym; - KeyCode first_key_act; - KeyCode first_key_behavior; - KeyCode first_key_explicit; - KeyCode first_modmap_key; - KeyCode first_vmodmap_key; - int num_key_syms; - int num_key_acts; - int num_key_behaviors; - int num_key_explicit; - int num_modmap_keys; - int num_vmodmap_keys; - unsigned int vmods; /* mask of changed virtual mods */ +typedef struct _XkbMapNotifyEvent +{ + int type; /* XkbAnyEvent */ + unsigned long serial; /* of last req processed by server */ + Bool send_event; /* is this from a SendEvent request */ + Display* display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbMapNotify */ + int device; /* device ID */ + unsigned int changed; /* fields which have been changed */ + unsigned int flags; /* reserved */ + int first_type; /* first changed key type */ + int num_types; /* number of changed key types */ + KeyCode min_key_code; + KeyCode max_key_code; + KeyCode first_key_sym; + KeyCode first_key_act; + KeyCode first_key_behavior; + KeyCode first_key_explicit; + KeyCode first_modmap_key; + KeyCode first_vmodmap_key; + int num_key_syms; + int num_key_acts; + int num_key_behaviors; + int num_key_explicit; + int num_modmap_keys; + int num_vmodmap_keys; + unsigned int vmods; /* mask of changed virtual mods */ } XkbMapNotifyEvent; -typedef struct _XkbStateNotifyEvent { - int type; /* XkbAnyEvent */ - unsigned long serial; /* # of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbStateNotify */ - int device; /* device ID */ - unsigned int changed; /* mask of changed state components */ - int group; /* keyboard group */ - int base_group; /* base keyboard group */ - int latched_group; /* latched keyboard group */ - int locked_group; /* locked keyboard group */ - unsigned int mods; /* modifier state */ - unsigned int base_mods; /* base modifier state */ - unsigned int latched_mods; /* latched modifiers */ - unsigned int locked_mods; /* locked modifiers */ - int compat_state; /* compatibility state */ - unsigned char grab_mods; /* mods used for grabs */ - unsigned char compat_grab_mods;/* grab mods for non-XKB clients */ - unsigned char lookup_mods; /* mods sent to clients */ - unsigned char compat_lookup_mods; /* mods sent to non-XKB clients */ - int ptr_buttons; /* pointer button state */ - KeyCode keycode; /* keycode that caused the change */ - char event_type; /* KeyPress or KeyRelease */ - char req_major; /* Major opcode of request */ - char req_minor; /* Minor opcode of request */ +typedef struct _XkbStateNotifyEvent +{ + int type; /* XkbAnyEvent */ + unsigned long serial; /* # of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display* display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbStateNotify */ + int device; /* device ID */ + unsigned int changed; /* mask of changed state components */ + int group; /* keyboard group */ + int base_group; /* base keyboard group */ + int latched_group; /* latched keyboard group */ + int locked_group; /* locked keyboard group */ + unsigned int mods; /* modifier state */ + unsigned int base_mods; /* base modifier state */ + unsigned int latched_mods; /* latched modifiers */ + unsigned int locked_mods; /* locked modifiers */ + int compat_state; /* compatibility state */ + unsigned char grab_mods; /* mods used for grabs */ + unsigned char compat_grab_mods; /* grab mods for non-XKB clients */ + unsigned char lookup_mods; /* mods sent to clients */ + unsigned char compat_lookup_mods; /* mods sent to non-XKB clients */ + int ptr_buttons; /* pointer button state */ + KeyCode keycode; /* keycode that caused the change */ + char event_type; /* KeyPress or KeyRelease */ + char req_major; /* Major opcode of request */ + char req_minor; /* Minor opcode of request */ } XkbStateNotifyEvent; -typedef struct _XkbControlsNotify { - int type; /* XkbAnyEvent */ - unsigned long serial; /* of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbControlsNotify */ - int device; /* device ID */ - unsigned int changed_ctrls; /* controls with changed sub-values */ - unsigned int enabled_ctrls; /* controls currently enabled */ - unsigned int enabled_ctrl_changes;/* controls just {en,dis}abled */ - int num_groups; /* total groups on keyboard */ - KeyCode keycode; /* key that caused change or 0 */ - char event_type; /* type of event that caused change */ - char req_major; /* if keycode==0, major and minor */ - char req_minor; /* opcode of req that caused change */ +typedef struct _XkbControlsNotify +{ + int type; /* XkbAnyEvent */ + unsigned long serial; /* of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display* display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbControlsNotify */ + int device; /* device ID */ + unsigned int changed_ctrls; /* controls with changed sub-values */ + unsigned int enabled_ctrls; /* controls currently enabled */ + unsigned int enabled_ctrl_changes; /* controls just {en,dis}abled */ + int num_groups; /* total groups on keyboard */ + KeyCode keycode; /* key that caused change or 0 */ + char event_type; /* type of event that caused change */ + char req_major; /* if keycode==0, major and minor */ + char req_minor; /* opcode of req that caused change */ } XkbControlsNotifyEvent; -typedef struct _XkbIndicatorNotify { - int type; /* XkbAnyEvent */ - unsigned long serial; /* of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbIndicatorNotify */ - int device; /* device ID */ - unsigned int changed; /* indicators with new state or map */ - unsigned int state; /* current state of all indicators */ +typedef struct _XkbIndicatorNotify +{ + int type; /* XkbAnyEvent */ + unsigned long serial; /* of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display* display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbIndicatorNotify */ + int device; /* device ID */ + unsigned int changed; /* indicators with new state or map */ + unsigned int state; /* current state of all indicators */ } XkbIndicatorNotifyEvent; -typedef struct _XkbNamesNotify { - int type; /* XkbAnyEvent */ - unsigned long serial; /* of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbNamesNotify */ - int device; /* device ID */ - unsigned int changed; /* names that have changed */ - int first_type; /* first key type with new name */ - int num_types; /* number of key types with new names */ - int first_lvl; /* first key type new new level names */ - int num_lvls; /* # of key types w/new level names */ - int num_aliases; /* total number of key aliases*/ - int num_radio_groups;/* total number of radio groups */ - unsigned int changed_vmods; /* virtual modifiers with new names */ - unsigned int changed_groups; /* groups with new names */ - unsigned int changed_indicators;/* indicators with new names */ - int first_key; /* first key with new name */ - int num_keys; /* number of keys with new names */ +typedef struct _XkbNamesNotify +{ + int type; /* XkbAnyEvent */ + unsigned long serial; /* of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display* display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbNamesNotify */ + int device; /* device ID */ + unsigned int changed; /* names that have changed */ + int first_type; /* first key type with new name */ + int num_types; /* number of key types with new names */ + int first_lvl; /* first key type new new level names */ + int num_lvls; /* # of key types w/new level names */ + int num_aliases; /* total number of key aliases*/ + int num_radio_groups; /* total number of radio groups */ + unsigned int changed_vmods; /* virtual modifiers with new names */ + unsigned int changed_groups; /* groups with new names */ + unsigned int changed_indicators; /* indicators with new names */ + int first_key; /* first key with new name */ + int num_keys; /* number of keys with new names */ } XkbNamesNotifyEvent; -typedef struct _XkbCompatMapNotify { - int type; /* XkbAnyEvent */ - unsigned long serial; /* of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbCompatMapNotify */ - int device; /* device ID */ - unsigned int changed_groups; /* groups with new compat maps */ - int first_si; /* first new symbol interp */ - int num_si; /* number of new symbol interps */ - int num_total_si; /* total # of symbol interps */ +typedef struct _XkbCompatMapNotify +{ + int type; /* XkbAnyEvent */ + unsigned long serial; /* of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display* display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbCompatMapNotify */ + int device; /* device ID */ + unsigned int changed_groups; /* groups with new compat maps */ + int first_si; /* first new symbol interp */ + int num_si; /* number of new symbol interps */ + int num_total_si; /* total # of symbol interps */ } XkbCompatMapNotifyEvent; -typedef struct _XkbBellNotify { - int type; /* XkbAnyEvent */ - unsigned long serial; /* of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbBellNotify */ - int device; /* device ID */ - int percent; /* requested volume as a % of maximum */ - int pitch; /* requested pitch in Hz */ - int duration; /* requested duration in useconds */ - int bell_class; /* (input extension) feedback class */ - int bell_id; /* (input extension) ID of feedback */ - Atom name; /* "name" of requested bell */ - Window window; /* window associated with event */ - Bool event_only; /* "event only" requested */ +typedef struct _XkbBellNotify +{ + int type; /* XkbAnyEvent */ + unsigned long serial; /* of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display* display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbBellNotify */ + int device; /* device ID */ + int percent; /* requested volume as a % of maximum */ + int pitch; /* requested pitch in Hz */ + int duration; /* requested duration in useconds */ + int bell_class; /* (input extension) feedback class */ + int bell_id; /* (input extension) ID of feedback */ + Atom name; /* "name" of requested bell */ + Window window; /* window associated with event */ + Bool event_only; /* "event only" requested */ } XkbBellNotifyEvent; -typedef struct _XkbActionMessage { - int type; /* XkbAnyEvent */ - unsigned long serial; /* of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbActionMessage */ - int device; /* device ID */ - KeyCode keycode; /* key that generated the event */ - Bool press; /* true if act caused by key press */ - Bool key_event_follows;/* true if key event also generated */ - int group; /* effective group */ - unsigned int mods; /* effective mods */ - char message[XkbActionMessageLength+1]; - /* message -- leave space for NUL */ +typedef struct _XkbActionMessage +{ + int type; /* XkbAnyEvent */ + unsigned long serial; /* of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display* display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbActionMessage */ + int device; /* device ID */ + KeyCode keycode; /* key that generated the event */ + Bool press; /* true if act caused by key press */ + Bool key_event_follows; /* true if key event also generated */ + int group; /* effective group */ + unsigned int mods; /* effective mods */ + char message[XkbActionMessageLength + 1]; + /* message -- leave space for NUL */ } XkbActionMessageEvent; -typedef struct _XkbAccessXNotify { - int type; /* XkbAnyEvent */ - unsigned long serial; /* of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbAccessXNotify */ - int device; /* device ID */ - int detail; /* XkbAXN_* */ - int keycode; /* key of event */ - int sk_delay; /* current slow keys delay */ - int debounce_delay; /* current debounce delay */ +typedef struct _XkbAccessXNotify +{ + int type; /* XkbAnyEvent */ + unsigned long serial; /* of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display* display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbAccessXNotify */ + int device; /* device ID */ + int detail; /* XkbAXN_* */ + int keycode; /* key of event */ + int sk_delay; /* current slow keys delay */ + int debounce_delay; /* current debounce delay */ } XkbAccessXNotifyEvent; -typedef struct _XkbExtensionDeviceNotify { - int type; /* XkbAnyEvent */ - unsigned long serial; /* of last req processed by server */ - Bool send_event; /* is this from a SendEvent request? */ - Display * display; /* Display the event was read from */ - Time time; /* milliseconds */ - int xkb_type; /* XkbExtensionDeviceNotify */ - int device; /* device ID */ - unsigned int reason; /* reason for the event */ - unsigned int supported; /* mask of supported features */ - unsigned int unsupported; /* mask of unsupported features */ - /* that some app tried to use */ - int first_btn; /* first button that changed */ - int num_btns; /* range of buttons changed */ - unsigned int leds_defined; /* indicators with names or maps */ - unsigned int led_state; /* current state of the indicators */ - int led_class; /* feedback class for led changes */ - int led_id; /* feedback id for led changes */ +typedef struct _XkbExtensionDeviceNotify +{ + int type; /* XkbAnyEvent */ + unsigned long serial; /* of last req processed by server */ + Bool send_event; /* is this from a SendEvent request? */ + Display* display; /* Display the event was read from */ + Time time; /* milliseconds */ + int xkb_type; /* XkbExtensionDeviceNotify */ + int device; /* device ID */ + unsigned int reason; /* reason for the event */ + unsigned int supported; /* mask of supported features */ + unsigned int unsupported; /* mask of unsupported features */ + /* that some app tried to use */ + int first_btn; /* first button that changed */ + int num_btns; /* range of buttons changed */ + unsigned int leds_defined; /* indicators with names or maps */ + unsigned int led_state; /* current state of the indicators */ + int led_class; /* feedback class for led changes */ + int led_id; /* feedback id for led changes */ } XkbExtensionDeviceNotifyEvent; typedef union _XkbEvent { - int type; - XkbAnyEvent any; - XkbNewKeyboardNotifyEvent new_kbd; - XkbMapNotifyEvent map; - XkbStateNotifyEvent state; - XkbControlsNotifyEvent ctrls; - XkbIndicatorNotifyEvent indicators; - XkbNamesNotifyEvent names; - XkbCompatMapNotifyEvent compat; - XkbBellNotifyEvent bell; - XkbActionMessageEvent message; - XkbAccessXNotifyEvent accessx; - XkbExtensionDeviceNotifyEvent device; - XEvent core; + int type; + XkbAnyEvent any; + XkbNewKeyboardNotifyEvent new_kbd; + XkbMapNotifyEvent map; + XkbStateNotifyEvent state; + XkbControlsNotifyEvent ctrls; + XkbIndicatorNotifyEvent indicators; + XkbNamesNotifyEvent names; + XkbCompatMapNotifyEvent compat; + XkbBellNotifyEvent bell; + XkbActionMessageEvent message; + XkbAccessXNotifyEvent accessx; + XkbExtensionDeviceNotifyEvent device; + XEvent core; } XkbEvent; -typedef struct _XkbKbdDpyState XkbKbdDpyStateRec,*XkbKbdDpyStatePtr; +typedef struct _XkbKbdDpyState XkbKbdDpyStateRec, *XkbKbdDpyStatePtr; - /* XkbOpenDisplay error codes */ -#define XkbOD_Success 0 -#define XkbOD_BadLibraryVersion 1 -#define XkbOD_ConnectionRefused 2 -#define XkbOD_NonXkbServer 3 -#define XkbOD_BadServerVersion 4 +/* XkbOpenDisplay error codes */ +#define XkbOD_Success 0 +#define XkbOD_BadLibraryVersion 1 +#define XkbOD_ConnectionRefused 2 +#define XkbOD_NonXkbServer 3 +#define XkbOD_BadServerVersion 4 - /* Values for XlibFlags */ -#define XkbLC_ForceLatin1Lookup (1<<0) -#define XkbLC_ConsumeLookupMods (1<<1) -#define XkbLC_AlwaysConsumeShiftAndLock (1<<2) -#define XkbLC_IgnoreNewKeyboards (1<<3) -#define XkbLC_ControlFallback (1<<4) -#define XkbLC_ConsumeKeysOnComposeFail (1<<29) -#define XkbLC_ComposeLED (1<<30) -#define XkbLC_BeepOnComposeFail (1<<31) +/* Values for XlibFlags */ +#define XkbLC_ForceLatin1Lookup (1 << 0) +#define XkbLC_ConsumeLookupMods (1 << 1) +#define XkbLC_AlwaysConsumeShiftAndLock (1 << 2) +#define XkbLC_IgnoreNewKeyboards (1 << 3) +#define XkbLC_ControlFallback (1 << 4) +#define XkbLC_ConsumeKeysOnComposeFail (1 << 29) +#define XkbLC_ComposeLED (1 << 30) +#define XkbLC_BeepOnComposeFail (1 << 31) -#define XkbLC_AllComposeControls (0xc0000000) -#define XkbLC_AllControls (0xc000001f) +#define XkbLC_AllComposeControls (0xc0000000) +#define XkbLC_AllControls (0xc000001f) _XFUNCPROTOBEGIN -extern Bool XkbIgnoreExtension( - Bool /* ignore */ +extern Bool XkbIgnoreExtension( + Bool /* ignore */ ); -extern Display *XkbOpenDisplay( - char * /* name */, - int * /* ev_rtrn */, - int * /* err_rtrn */, - int * /* major_rtrn */, - int * /* minor_rtrn */, - int * /* reason */ +extern Display* XkbOpenDisplay( + char* /* name */, + int* /* ev_rtrn */, + int* /* err_rtrn */, + int* /* major_rtrn */, + int* /* minor_rtrn */, + int* /* reason */ ); -extern Bool XkbQueryExtension( - Display * /* dpy */, - int * /* opcodeReturn */, - int * /* eventBaseReturn */, - int * /* errorBaseReturn */, - int * /* majorRtrn */, - int * /* minorRtrn */ +extern Bool XkbQueryExtension( + Display* /* dpy */, + int* /* opcodeReturn */, + int* /* eventBaseReturn */, + int* /* errorBaseReturn */, + int* /* majorRtrn */, + int* /* minorRtrn */ ); -extern Bool XkbUseExtension( - Display * /* dpy */, - int * /* major_rtrn */, - int * /* minor_rtrn */ +extern Bool XkbUseExtension( + Display* /* dpy */, + int* /* major_rtrn */, + int* /* minor_rtrn */ ); -extern Bool XkbLibraryVersion( - int * /* libMajorRtrn */, - int * /* libMinorRtrn */ +extern Bool XkbLibraryVersion( + int* /* libMajorRtrn */, + int* /* libMinorRtrn */ ); -extern unsigned int XkbSetXlibControls( - Display* /* dpy */, - unsigned int /* affect */, - unsigned int /* values */ +extern unsigned int XkbSetXlibControls( + Display* /* dpy */, + unsigned int /* affect */, + unsigned int /* values */ ); -extern unsigned int XkbGetXlibControls( - Display* /* dpy */ +extern unsigned int XkbGetXlibControls( + Display* /* dpy */ ); -extern unsigned int XkbXlibControlsImplemented(void); +extern unsigned int XkbXlibControlsImplemented(void); -typedef Atom (*XkbInternAtomFunc)( - Display * /* dpy */, - _Xconst char * /* name */, - Bool /* only_if_exists */ +typedef Atom (*XkbInternAtomFunc)( + Display* /* dpy */, + _Xconst char* /* name */, + Bool /* only_if_exists */ ); -typedef char * (*XkbGetAtomNameFunc)( - Display * /* dpy */, - Atom /* atom */ +typedef char* (*XkbGetAtomNameFunc)( + Display* /* dpy */, + Atom /* atom */ ); -extern void XkbSetAtomFuncs( - XkbInternAtomFunc /* getAtom */, - XkbGetAtomNameFunc /* getName */ +extern void XkbSetAtomFuncs( + XkbInternAtomFunc /* getAtom */, + XkbGetAtomNameFunc /* getName */ ); -extern KeySym XkbKeycodeToKeysym( - Display * /* dpy */, +extern KeySym XkbKeycodeToKeysym( + Display* /* dpy */, #if NeedWidePrototypes - unsigned int /* kc */, + unsigned int /* kc */, #else - KeyCode /* kc */, + KeyCode /* kc */, #endif - int /* group */, - int /* level */ + int /* group */, + int /* level */ ); -extern unsigned int XkbKeysymToModifiers( - Display * /* dpy */, - KeySym /* ks */ +extern unsigned int XkbKeysymToModifiers( + Display* /* dpy */, + KeySym /* ks */ ); -extern Bool XkbLookupKeySym( - Display * /* dpy */, - KeyCode /* keycode */, - unsigned int /* modifiers */, - unsigned int * /* modifiers_return */, - KeySym * /* keysym_return */ +extern Bool XkbLookupKeySym( + Display* /* dpy */, + KeyCode /* keycode */, + unsigned int /* modifiers */, + unsigned int* /* modifiers_return */, + KeySym* /* keysym_return */ ); -extern int XkbLookupKeyBinding( - Display * /* dpy */, - KeySym /* sym_rtrn */, - unsigned int /* mods */, - char * /* buffer */, - int /* nbytes */, - int * /* extra_rtrn */ +extern int XkbLookupKeyBinding( + Display* /* dpy */, + KeySym /* sym_rtrn */, + unsigned int /* mods */, + char* /* buffer */, + int /* nbytes */, + int* /* extra_rtrn */ ); -extern Bool XkbTranslateKeyCode( - XkbDescPtr /* xkb */, - KeyCode /* keycode */, - unsigned int /* modifiers */, - unsigned int * /* modifiers_return */, - KeySym * /* keysym_return */ +extern Bool XkbTranslateKeyCode( + XkbDescPtr /* xkb */, + KeyCode /* keycode */, + unsigned int /* modifiers */, + unsigned int* /* modifiers_return */, + KeySym* /* keysym_return */ ); -extern int XkbTranslateKeySym( - Display * /* dpy */, - register KeySym * /* sym_return */, - unsigned int /* modifiers */, - char * /* buffer */, - int /* nbytes */, - int * /* extra_rtrn */ +extern int XkbTranslateKeySym( + Display* /* dpy */, + register KeySym* /* sym_return */, + unsigned int /* modifiers */, + char* /* buffer */, + int /* nbytes */, + int* /* extra_rtrn */ ); -extern Bool XkbSetAutoRepeatRate( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* delay */, - unsigned int /* interval */ +extern Bool XkbSetAutoRepeatRate( + Display* /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* delay */, + unsigned int /* interval */ ); -extern Bool XkbGetAutoRepeatRate( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int * /* delayRtrn */, - unsigned int * /* intervalRtrn */ +extern Bool XkbGetAutoRepeatRate( + Display* /* dpy */, + unsigned int /* deviceSpec */, + unsigned int* /* delayRtrn */, + unsigned int* /* intervalRtrn */ ); -extern Bool XkbChangeEnabledControls( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* affect */, - unsigned int /* values */ +extern Bool XkbChangeEnabledControls( + Display* /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* affect */, + unsigned int /* values */ ); -extern Bool XkbDeviceBell( - Display * /* dpy */, - Window /* win */, - int /* deviceSpec */, - int /* bellClass */, - int /* bellID */, - int /* percent */, - Atom /* name */ +extern Bool XkbDeviceBell( + Display* /* dpy */, + Window /* win */, + int /* deviceSpec */, + int /* bellClass */, + int /* bellID */, + int /* percent */, + Atom /* name */ ); -extern Bool XkbForceDeviceBell( - Display * /* dpy */, - int /* deviceSpec */, - int /* bellClass */, - int /* bellID */, - int /* percent */ +extern Bool XkbForceDeviceBell( + Display* /* dpy */, + int /* deviceSpec */, + int /* bellClass */, + int /* bellID */, + int /* percent */ ); -extern Bool XkbDeviceBellEvent( - Display * /* dpy */, - Window /* win */, - int /* deviceSpec */, - int /* bellClass */, - int /* bellID */, - int /* percent */, - Atom /* name */ +extern Bool XkbDeviceBellEvent( + Display* /* dpy */, + Window /* win */, + int /* deviceSpec */, + int /* bellClass */, + int /* bellID */, + int /* percent */, + Atom /* name */ ); -extern Bool XkbBell( - Display * /* dpy */, - Window /* win */, - int /* percent */, - Atom /* name */ +extern Bool XkbBell( + Display* /* dpy */, + Window /* win */, + int /* percent */, + Atom /* name */ ); -extern Bool XkbForceBell( - Display * /* dpy */, - int /* percent */ +extern Bool XkbForceBell( + Display* /* dpy */, + int /* percent */ ); -extern Bool XkbBellEvent( - Display * /* dpy */, - Window /* win */, - int /* percent */, - Atom /* name */ +extern Bool XkbBellEvent( + Display* /* dpy */, + Window /* win */, + int /* percent */, + Atom /* name */ ); -extern Bool XkbSelectEvents( - Display * /* dpy */, - unsigned int /* deviceID */, - unsigned int /* affect */, - unsigned int /* values */ +extern Bool XkbSelectEvents( + Display* /* dpy */, + unsigned int /* deviceID */, + unsigned int /* affect */, + unsigned int /* values */ ); -extern Bool XkbSelectEventDetails( - Display * /* dpy */, - unsigned int /* deviceID */, - unsigned int /* eventType */, - unsigned long /* affect */, - unsigned long /* details */ +extern Bool XkbSelectEventDetails( + Display* /* dpy */, + unsigned int /* deviceID */, + unsigned int /* eventType */, + unsigned long /* affect */, + unsigned long /* details */ ); -extern void XkbNoteMapChanges( - XkbMapChangesPtr /* old */, - XkbMapNotifyEvent * /* new */, - unsigned int /* wanted */ +extern void XkbNoteMapChanges( + XkbMapChangesPtr /* old */, + XkbMapNotifyEvent* /* new */, + unsigned int /* wanted */ ); -extern void XkbNoteNameChanges( - XkbNameChangesPtr /* old */, - XkbNamesNotifyEvent * /* new */, - unsigned int /* wanted */ +extern void XkbNoteNameChanges( + XkbNameChangesPtr /* old */, + XkbNamesNotifyEvent* /* new */, + unsigned int /* wanted */ ); -extern Status XkbGetIndicatorState( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int * /* pStateRtrn */ +extern Status XkbGetIndicatorState( + Display* /* dpy */, + unsigned int /* deviceSpec */, + unsigned int* /* pStateRtrn */ ); -extern Status XkbGetDeviceIndicatorState( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* ledClass */, - unsigned int /* ledID */, - unsigned int * /* pStateRtrn */ +extern Status XkbGetDeviceIndicatorState( + Display* /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* ledClass */, + unsigned int /* ledID */, + unsigned int* /* pStateRtrn */ ); -extern Status XkbGetIndicatorMap( - Display * /* dpy */, - unsigned long /* which */, - XkbDescPtr /* desc */ +extern Status XkbGetIndicatorMap( + Display* /* dpy */, + unsigned long /* which */, + XkbDescPtr /* desc */ ); -extern Bool XkbSetIndicatorMap( - Display * /* dpy */, - unsigned long /* which */, - XkbDescPtr /* desc */ +extern Bool XkbSetIndicatorMap( + Display* /* dpy */, + unsigned long /* which */, + XkbDescPtr /* desc */ ); -#define XkbNoteIndicatorMapChanges(o,n,w) \ - ((o)->map_changes|=((n)->map_changes&(w))) -#define XkbNoteIndicatorStateChanges(o,n,w)\ - ((o)->state_changes|=((n)->state_changes&(w))) -#define XkbGetIndicatorMapChanges(d,x,c) \ - (XkbGetIndicatorMap((d),(c)->map_changes,x)) -#define XkbChangeIndicatorMaps(d,x,c) \ - (XkbSetIndicatorMap((d),(c)->map_changes,x)) +#define XkbNoteIndicatorMapChanges(o, n, w) \ + ((o)->map_changes |= ((n)->map_changes & (w))) +#define XkbNoteIndicatorStateChanges(o, n, w) \ + ((o)->state_changes |= ((n)->state_changes & (w))) +#define XkbGetIndicatorMapChanges(d, x, c) \ + (XkbGetIndicatorMap((d), (c)->map_changes, x)) +#define XkbChangeIndicatorMaps(d, x, c) \ + (XkbSetIndicatorMap((d), (c)->map_changes, x)) -extern Bool XkbGetNamedIndicator( - Display * /* dpy */, - Atom /* name */, - int * /* pNdxRtrn */, - Bool * /* pStateRtrn */, - XkbIndicatorMapPtr /* pMapRtrn */, - Bool * /* pRealRtrn */ +extern Bool XkbGetNamedIndicator( + Display* /* dpy */, + Atom /* name */, + int* /* pNdxRtrn */, + Bool* /* pStateRtrn */, + XkbIndicatorMapPtr /* pMapRtrn */, + Bool* /* pRealRtrn */ ); -extern Bool XkbGetNamedDeviceIndicator( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* ledClass */, - unsigned int /* ledID */, - Atom /* name */, - int * /* pNdxRtrn */, - Bool * /* pStateRtrn */, - XkbIndicatorMapPtr /* pMapRtrn */, - Bool * /* pRealRtrn */ +extern Bool XkbGetNamedDeviceIndicator( + Display* /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* ledClass */, + unsigned int /* ledID */, + Atom /* name */, + int* /* pNdxRtrn */, + Bool* /* pStateRtrn */, + XkbIndicatorMapPtr /* pMapRtrn */, + Bool* /* pRealRtrn */ ); -extern Bool XkbSetNamedIndicator( - Display * /* dpy */, - Atom /* name */, - Bool /* changeState */, - Bool /* state */, - Bool /* createNewMap */, - XkbIndicatorMapPtr /* pMap */ +extern Bool XkbSetNamedIndicator( + Display* /* dpy */, + Atom /* name */, + Bool /* changeState */, + Bool /* state */, + Bool /* createNewMap */, + XkbIndicatorMapPtr /* pMap */ ); -extern Bool XkbSetNamedDeviceIndicator( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* ledClass */, - unsigned int /* ledID */, - Atom /* name */, - Bool /* changeState */, - Bool /* state */, - Bool /* createNewMap */, - XkbIndicatorMapPtr /* pMap */ +extern Bool XkbSetNamedDeviceIndicator( + Display* /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* ledClass */, + unsigned int /* ledID */, + Atom /* name */, + Bool /* changeState */, + Bool /* state */, + Bool /* createNewMap */, + XkbIndicatorMapPtr /* pMap */ ); -extern Bool XkbLockModifiers( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* affect */, - unsigned int /* values */ +extern Bool XkbLockModifiers( + Display* /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* affect */, + unsigned int /* values */ ); -extern Bool XkbLatchModifiers( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* affect */, - unsigned int /* values */ +extern Bool XkbLatchModifiers( + Display* /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* affect */, + unsigned int /* values */ ); -extern Bool XkbLockGroup( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* group */ +extern Bool XkbLockGroup( + Display* /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* group */ ); -extern Bool XkbLatchGroup( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* group */ +extern Bool XkbLatchGroup( + Display* /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* group */ ); -extern Bool XkbSetServerInternalMods( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* affectReal */, - unsigned int /* realValues */, - unsigned int /* affectVirtual */, - unsigned int /* virtualValues */ +extern Bool XkbSetServerInternalMods( + Display* /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* affectReal */, + unsigned int /* realValues */, + unsigned int /* affectVirtual */, + unsigned int /* virtualValues */ ); -extern Bool XkbSetIgnoreLockMods( - Display * /* dpy */, - unsigned int /* deviceSpec */, - unsigned int /* affectReal */, - unsigned int /* realValues */, - unsigned int /* affectVirtual */, - unsigned int /* virtualValues */ +extern Bool XkbSetIgnoreLockMods( + Display* /* dpy */, + unsigned int /* deviceSpec */, + unsigned int /* affectReal */, + unsigned int /* realValues */, + unsigned int /* affectVirtual */, + unsigned int /* virtualValues */ ); - -extern Bool XkbVirtualModsToReal( - XkbDescPtr /* xkb */, - unsigned int /* virtual_mask */, - unsigned int * /* mask_rtrn */ +extern Bool XkbVirtualModsToReal( + XkbDescPtr /* xkb */, + unsigned int /* virtual_mask */, + unsigned int* /* mask_rtrn */ ); -extern Bool XkbComputeEffectiveMap( - XkbDescPtr /* xkb */, - XkbKeyTypePtr /* type */, - unsigned char * /* map_rtrn */ +extern Bool XkbComputeEffectiveMap( + XkbDescPtr /* xkb */, + XkbKeyTypePtr /* type */, + unsigned char* /* map_rtrn */ ); -extern Status XkbInitCanonicalKeyTypes( - XkbDescPtr /* xkb */, - unsigned int /* which */, - int /* keypadVMod */ +extern Status XkbInitCanonicalKeyTypes( + XkbDescPtr /* xkb */, + unsigned int /* which */, + int /* keypadVMod */ ); -extern XkbDescPtr XkbAllocKeyboard( - void +extern XkbDescPtr XkbAllocKeyboard( + void); + +extern void XkbFreeKeyboard( + XkbDescPtr /* xkb */, + unsigned int /* which */, + Bool /* freeDesc */ ); -extern void XkbFreeKeyboard( - XkbDescPtr /* xkb */, - unsigned int /* which */, - Bool /* freeDesc */ +extern Status XkbAllocClientMap( + XkbDescPtr /* xkb */, + unsigned int /* which */, + unsigned int /* nTypes */ ); -extern Status XkbAllocClientMap( - XkbDescPtr /* xkb */, - unsigned int /* which */, - unsigned int /* nTypes */ +extern Status XkbAllocServerMap( + XkbDescPtr /* xkb */, + unsigned int /* which */, + unsigned int /* nActions */ ); -extern Status XkbAllocServerMap( - XkbDescPtr /* xkb */, - unsigned int /* which */, - unsigned int /* nActions */ +extern void XkbFreeClientMap( + XkbDescPtr /* xkb */, + unsigned int /* what */, + Bool /* freeMap */ ); -extern void XkbFreeClientMap( - XkbDescPtr /* xkb */, - unsigned int /* what */, - Bool /* freeMap */ +extern void XkbFreeServerMap( + XkbDescPtr /* xkb */, + unsigned int /* what */, + Bool /* freeMap */ ); -extern void XkbFreeServerMap( - XkbDescPtr /* xkb */, - unsigned int /* what */, - Bool /* freeMap */ +extern XkbKeyTypePtr XkbAddKeyType( + XkbDescPtr /* xkb */, + Atom /* name */, + int /* map_count */, + Bool /* want_preserve */, + int /* num_lvls */ ); -extern XkbKeyTypePtr XkbAddKeyType( - XkbDescPtr /* xkb */, - Atom /* name */, - int /* map_count */, - Bool /* want_preserve */, - int /* num_lvls */ +extern Status XkbAllocIndicatorMaps( + XkbDescPtr /* xkb */ ); -extern Status XkbAllocIndicatorMaps( - XkbDescPtr /* xkb */ +extern void XkbFreeIndicatorMaps( + XkbDescPtr /* xkb */ ); -extern void XkbFreeIndicatorMaps( - XkbDescPtr /* xkb */ +extern XkbDescPtr XkbGetMap( + Display* /* dpy */, + unsigned int /* which */, + unsigned int /* deviceSpec */ ); -extern XkbDescPtr XkbGetMap( - Display * /* dpy */, - unsigned int /* which */, - unsigned int /* deviceSpec */ +extern Status XkbGetUpdatedMap( + Display* /* dpy */, + unsigned int /* which */, + XkbDescPtr /* desc */ ); -extern Status XkbGetUpdatedMap( - Display * /* dpy */, - unsigned int /* which */, - XkbDescPtr /* desc */ +extern Status XkbGetMapChanges( + Display* /* dpy */, + XkbDescPtr /* xkb */, + XkbMapChangesPtr /* changes */ ); -extern Status XkbGetMapChanges( - Display * /* dpy */, - XkbDescPtr /* xkb */, - XkbMapChangesPtr /* changes */ +extern Status XkbRefreshKeyboardMapping( + XkbMapNotifyEvent* /* event */ ); - -extern Status XkbRefreshKeyboardMapping( - XkbMapNotifyEvent * /* event */ +extern Status XkbGetKeyTypes( + Display* /* dpy */, + unsigned int /* first */, + unsigned int /* num */, + XkbDescPtr /* xkb */ ); -extern Status XkbGetKeyTypes( - Display * /* dpy */, - unsigned int /* first */, - unsigned int /* num */, - XkbDescPtr /* xkb */ +extern Status XkbGetKeySyms( + Display* /* dpy */, + unsigned int /* first */, + unsigned int /* num */, + XkbDescPtr /* xkb */ ); -extern Status XkbGetKeySyms( - Display * /* dpy */, - unsigned int /* first */, - unsigned int /* num */, - XkbDescPtr /* xkb */ +extern Status XkbGetKeyActions( + Display* /* dpy */, + unsigned int /* first */, + unsigned int /* num */, + XkbDescPtr /* xkb */ ); -extern Status XkbGetKeyActions( - Display * /* dpy */, - unsigned int /* first */, - unsigned int /* num */, - XkbDescPtr /* xkb */ +extern Status XkbGetKeyBehaviors( + Display* /* dpy */, + unsigned int /* firstKey */, + unsigned int /* nKeys */, + XkbDescPtr /* desc */ ); -extern Status XkbGetKeyBehaviors( - Display * /* dpy */, - unsigned int /* firstKey */, - unsigned int /* nKeys */, - XkbDescPtr /* desc */ +extern Status XkbGetVirtualMods( + Display* /* dpy */, + unsigned int /* which */, + XkbDescPtr /* desc */ ); -extern Status XkbGetVirtualMods( - Display * /* dpy */, - unsigned int /* which */, - XkbDescPtr /* desc */ +extern Status XkbGetKeyExplicitComponents( + Display* /* dpy */, + unsigned int /* firstKey */, + unsigned int /* nKeys */, + XkbDescPtr /* desc */ ); -extern Status XkbGetKeyExplicitComponents( - Display * /* dpy */, - unsigned int /* firstKey */, - unsigned int /* nKeys */, - XkbDescPtr /* desc */ +extern Status XkbGetKeyModifierMap( + Display* /* dpy */, + unsigned int /* firstKey */, + unsigned int /* nKeys */, + XkbDescPtr /* desc */ ); -extern Status XkbGetKeyModifierMap( - Display * /* dpy */, - unsigned int /* firstKey */, - unsigned int /* nKeys */, - XkbDescPtr /* desc */ +extern Status XkbGetKeyVirtualModMap( + Display* /* dpy */, + unsigned int /* first */, + unsigned int /* num */, + XkbDescPtr /* xkb */ ); -extern Status XkbGetKeyVirtualModMap( - Display * /* dpy */, - unsigned int /* first */, - unsigned int /* num */, - XkbDescPtr /* xkb */ +extern Status XkbAllocControls( + XkbDescPtr /* xkb */, + unsigned int /* which*/ ); -extern Status XkbAllocControls( - XkbDescPtr /* xkb */, - unsigned int /* which*/ +extern void XkbFreeControls( + XkbDescPtr /* xkb */, + unsigned int /* which */, + Bool /* freeMap */ ); -extern void XkbFreeControls( - XkbDescPtr /* xkb */, - unsigned int /* which */, - Bool /* freeMap */ +extern Status XkbGetControls( + Display* /* dpy */, + unsigned long /* which */, + XkbDescPtr /* desc */ ); -extern Status XkbGetControls( - Display * /* dpy */, - unsigned long /* which */, - XkbDescPtr /* desc */ +extern Bool XkbSetControls( + Display* /* dpy */, + unsigned long /* which */, + XkbDescPtr /* desc */ ); -extern Bool XkbSetControls( - Display * /* dpy */, - unsigned long /* which */, - XkbDescPtr /* desc */ +extern void XkbNoteControlsChanges( + XkbControlsChangesPtr /* old */, + XkbControlsNotifyEvent* /* new */, + unsigned int /* wanted */ ); -extern void XkbNoteControlsChanges( - XkbControlsChangesPtr /* old */, - XkbControlsNotifyEvent * /* new */, - unsigned int /* wanted */ +#define XkbGetControlsChanges(d, x, c) XkbGetControls(d, (c)->changed_ctrls, x) +#define XkbChangeControls(d, x, c) XkbSetControls(d, (c)->changed_ctrls, x) + +extern Status XkbAllocCompatMap( + XkbDescPtr /* xkb */, + unsigned int /* which */, + unsigned int /* nInterpret */ ); -#define XkbGetControlsChanges(d,x,c) XkbGetControls(d,(c)->changed_ctrls,x) -#define XkbChangeControls(d,x,c) XkbSetControls(d,(c)->changed_ctrls,x) - -extern Status XkbAllocCompatMap( - XkbDescPtr /* xkb */, - unsigned int /* which */, - unsigned int /* nInterpret */ -); - -extern void XkbFreeCompatMap( - XkbDescPtr /* xkb */, - unsigned int /* which */, - Bool /* freeMap */ +extern void XkbFreeCompatMap( + XkbDescPtr /* xkb */, + unsigned int /* which */, + Bool /* freeMap */ ); extern Status XkbGetCompatMap( - Display * /* dpy */, - unsigned int /* which */, - XkbDescPtr /* xkb */ + Display* /* dpy */, + unsigned int /* which */, + XkbDescPtr /* xkb */ ); extern Bool XkbSetCompatMap( - Display * /* dpy */, - unsigned int /* which */, - XkbDescPtr /* xkb */, - Bool /* updateActions */ + Display* /* dpy */, + unsigned int /* which */, + XkbDescPtr /* xkb */, + Bool /* updateActions */ ); -extern XkbSymInterpretPtr XkbAddSymInterpret( - XkbDescPtr /* xkb */, - XkbSymInterpretPtr /* si */, - Bool /* updateMap */, - XkbChangesPtr /* changes */ +extern XkbSymInterpretPtr XkbAddSymInterpret( + XkbDescPtr /* xkb */, + XkbSymInterpretPtr /* si */, + Bool /* updateMap */, + XkbChangesPtr /* changes */ ); -extern Status XkbAllocNames( - XkbDescPtr /* xkb */, - unsigned int /* which */, - int /* nTotalRG */, - int /* nTotalAliases */ +extern Status XkbAllocNames( + XkbDescPtr /* xkb */, + unsigned int /* which */, + int /* nTotalRG */, + int /* nTotalAliases */ ); -extern Status XkbGetNames( - Display * /* dpy */, - unsigned int /* which */, - XkbDescPtr /* desc */ +extern Status XkbGetNames( + Display* /* dpy */, + unsigned int /* which */, + XkbDescPtr /* desc */ ); -extern Bool XkbSetNames( - Display * /* dpy */, - unsigned int /* which */, - unsigned int /* firstType */, - unsigned int /* nTypes */, - XkbDescPtr /* desc */ +extern Bool XkbSetNames( + Display* /* dpy */, + unsigned int /* which */, + unsigned int /* firstType */, + unsigned int /* nTypes */, + XkbDescPtr /* desc */ ); -extern Bool XkbChangeNames( - Display * /* dpy */, - XkbDescPtr /* xkb */, - XkbNameChangesPtr /* changes */ +extern Bool XkbChangeNames( + Display* /* dpy */, + XkbDescPtr /* xkb */, + XkbNameChangesPtr /* changes */ ); -extern void XkbFreeNames( - XkbDescPtr /* xkb */, - unsigned int /* which */, - Bool /* freeMap */ +extern void XkbFreeNames( + XkbDescPtr /* xkb */, + unsigned int /* which */, + Bool /* freeMap */ ); - -extern Status XkbGetState( - Display * /* dpy */, - unsigned int /* deviceSpec */, - XkbStatePtr /* rtrnState */ +extern Status XkbGetState( + Display* /* dpy */, + unsigned int /* deviceSpec */, + XkbStatePtr /* rtrnState */ ); -extern Bool XkbSetMap( - Display * /* dpy */, - unsigned int /* which */, - XkbDescPtr /* desc */ +extern Bool XkbSetMap( + Display* /* dpy */, + unsigned int /* which */, + XkbDescPtr /* desc */ ); -extern Bool XkbChangeMap( - Display* /* dpy */, - XkbDescPtr /* desc */, - XkbMapChangesPtr /* changes */ +extern Bool XkbChangeMap( + Display* /* dpy */, + XkbDescPtr /* desc */, + XkbMapChangesPtr /* changes */ ); -extern Bool XkbSetDetectableAutoRepeat( - Display * /* dpy */, - Bool /* detectable */, - Bool * /* supported */ +extern Bool XkbSetDetectableAutoRepeat( + Display* /* dpy */, + Bool /* detectable */, + Bool* /* supported */ ); -extern Bool XkbGetDetectableAutoRepeat( - Display * /* dpy */, - Bool * /* supported */ +extern Bool XkbGetDetectableAutoRepeat( + Display* /* dpy */, + Bool* /* supported */ ); -extern Bool XkbSetAutoResetControls( - Display * /* dpy */, - unsigned int /* changes */, - unsigned int * /* auto_ctrls */, - unsigned int * /* auto_values */ +extern Bool XkbSetAutoResetControls( + Display* /* dpy */, + unsigned int /* changes */, + unsigned int* /* auto_ctrls */, + unsigned int* /* auto_values */ ); -extern Bool XkbGetAutoResetControls( - Display * /* dpy */, - unsigned int * /* auto_ctrls */, - unsigned int * /* auto_ctrl_values */ +extern Bool XkbGetAutoResetControls( + Display* /* dpy */, + unsigned int* /* auto_ctrls */, + unsigned int* /* auto_ctrl_values */ ); -extern Bool XkbSetPerClientControls( - Display * /* dpy */, - unsigned int /* change */, - unsigned int * /* values */ +extern Bool XkbSetPerClientControls( + Display* /* dpy */, + unsigned int /* change */, + unsigned int* /* values */ ); -extern Bool XkbGetPerClientControls( - Display * /* dpy */, - unsigned int * /* ctrls */ +extern Bool XkbGetPerClientControls( + Display* /* dpy */, + unsigned int* /* ctrls */ ); extern Status XkbCopyKeyType( - XkbKeyTypePtr /* from */, - XkbKeyTypePtr /* into */ + XkbKeyTypePtr /* from */, + XkbKeyTypePtr /* into */ ); extern Status XkbCopyKeyTypes( - XkbKeyTypePtr /* from */, - XkbKeyTypePtr /* into */, - int /* num_types */ + XkbKeyTypePtr /* from */, + XkbKeyTypePtr /* into */, + int /* num_types */ ); -extern Status XkbResizeKeyType( - XkbDescPtr /* xkb */, - int /* type_ndx */, - int /* map_count */, - Bool /* want_preserve */, - int /* new_num_lvls */ +extern Status XkbResizeKeyType( + XkbDescPtr /* xkb */, + int /* type_ndx */, + int /* map_count */, + Bool /* want_preserve */, + int /* new_num_lvls */ ); -extern KeySym *XkbResizeKeySyms( - XkbDescPtr /* desc */, - int /* forKey */, - int /* symsNeeded */ +extern KeySym* XkbResizeKeySyms( + XkbDescPtr /* desc */, + int /* forKey */, + int /* symsNeeded */ ); -extern XkbAction *XkbResizeKeyActions( - XkbDescPtr /* desc */, - int /* forKey */, - int /* actsNeeded */ +extern XkbAction* XkbResizeKeyActions( + XkbDescPtr /* desc */, + int /* forKey */, + int /* actsNeeded */ ); -extern Status XkbChangeTypesOfKey( - XkbDescPtr /* xkb */, - int /* key */, - int /* num_groups */, - unsigned int /* groups */, - int * /* newTypes */, - XkbMapChangesPtr /* pChanges */ +extern Status XkbChangeTypesOfKey( + XkbDescPtr /* xkb */, + int /* key */, + int /* num_groups */, + unsigned int /* groups */, + int* /* newTypes */, + XkbMapChangesPtr /* pChanges */ ); -extern Status XkbChangeKeycodeRange( - XkbDescPtr /* xkb */, - int /* minKC */, - int /* maxKC */, - XkbChangesPtr /* changes */ +extern Status XkbChangeKeycodeRange( + XkbDescPtr /* xkb */, + int /* minKC */, + int /* maxKC */, + XkbChangesPtr /* changes */ ); /***====================================================================***/ -extern XkbComponentListPtr XkbListComponents( - Display * /* dpy */, - unsigned int /* deviceSpec */, - XkbComponentNamesPtr /* ptrns */, - int * /* max_inout */ +extern XkbComponentListPtr XkbListComponents( + Display* /* dpy */, + unsigned int /* deviceSpec */, + XkbComponentNamesPtr /* ptrns */, + int* /* max_inout */ ); -extern void XkbFreeComponentList( - XkbComponentListPtr /* list */ +extern void XkbFreeComponentList( + XkbComponentListPtr /* list */ ); -extern XkbDescPtr XkbGetKeyboard( - Display * /* dpy */, - unsigned int /* which */, - unsigned int /* deviceSpec */ +extern XkbDescPtr XkbGetKeyboard( + Display* /* dpy */, + unsigned int /* which */, + unsigned int /* deviceSpec */ ); extern XkbDescPtr XkbGetKeyboardByName( - Display * /* dpy */, - unsigned int /* deviceSpec */, - XkbComponentNamesPtr /* names */, - unsigned int /* want */, - unsigned int /* need */, - Bool /* load */ + Display* /* dpy */, + unsigned int /* deviceSpec */, + XkbComponentNamesPtr /* names */, + unsigned int /* want */, + unsigned int /* need */, + Bool /* load */ ); /***====================================================================***/ -extern int XkbKeyTypesForCoreSymbols( /* returns # of groups */ - XkbDescPtr /* xkb */, /* keyboard device */ - int /* map_width */, /* width of core KeySym array */ - KeySym * /* core_syms */, /* always mapWidth symbols */ - unsigned int /* protected */, /* explicit key types */ - int * /* types_inout */, /* always four type indices */ - KeySym * /* xkb_syms_rtrn */ /* must have enough space */ +extern int XkbKeyTypesForCoreSymbols( /* returns # of groups */ + XkbDescPtr /* xkb */, /* keyboard device */ + int /* map_width */, /* width of core KeySym array */ + KeySym* /* core_syms */, /* always mapWidth symbols */ + unsigned int /* protected */, /* explicit key types */ + int* /* types_inout */, /* always four type indices */ + KeySym* /* xkb_syms_rtrn */ /* must have enough space */ ); -extern Bool XkbApplyCompatMapToKey( /* False only on error */ - XkbDescPtr /* xkb */, /* keymap to be edited */ - KeyCode /* key */, /* key to be updated */ - XkbChangesPtr /* changes */ /* resulting changes to map */ +extern Bool XkbApplyCompatMapToKey( /* False only on error */ + XkbDescPtr /* xkb */, /* keymap to be edited */ + KeyCode /* key */, /* key to be updated */ + XkbChangesPtr /* changes */ /* resulting changes to map */ ); -extern Bool XkbUpdateMapFromCore( /* False only on error */ - XkbDescPtr /* xkb */, /* XKB keyboard to be edited */ - KeyCode /* first_key */, /* first changed key */ - int /* num_keys */, /* number of changed keys */ - int /* map_width */, /* width of core keymap */ - KeySym * /* core_keysyms */, /* symbols from core keymap */ - XkbChangesPtr /* changes */ /* resulting changes */ +extern Bool XkbUpdateMapFromCore( /* False only on error */ + XkbDescPtr /* xkb */, /* XKB keyboard to be edited */ + KeyCode /* first_key */, /* first changed key */ + int /* num_keys */, /* number of changed keys */ + int /* map_width */, /* width of core keymap */ + KeySym* /* core_keysyms */, /* symbols from core keymap */ + XkbChangesPtr /* changes */ /* resulting changes */ ); /***====================================================================***/ -extern XkbDeviceLedInfoPtr XkbAddDeviceLedInfo( - XkbDeviceInfoPtr /* devi */, - unsigned int /* ledClass */, - unsigned int /* ledId */ +extern XkbDeviceLedInfoPtr XkbAddDeviceLedInfo( + XkbDeviceInfoPtr /* devi */, + unsigned int /* ledClass */, + unsigned int /* ledId */ ); -extern Status XkbResizeDeviceButtonActions( - XkbDeviceInfoPtr /* devi */, - unsigned int /* newTotal */ +extern Status XkbResizeDeviceButtonActions( + XkbDeviceInfoPtr /* devi */, + unsigned int /* newTotal */ ); -extern XkbDeviceInfoPtr XkbAllocDeviceInfo( - unsigned int /* deviceSpec */, - unsigned int /* nButtons */, - unsigned int /* szLeds */ +extern XkbDeviceInfoPtr XkbAllocDeviceInfo( + unsigned int /* deviceSpec */, + unsigned int /* nButtons */, + unsigned int /* szLeds */ ); -extern void XkbFreeDeviceInfo( - XkbDeviceInfoPtr /* devi */, - unsigned int /* which */, - Bool /* freeDevI */ +extern void XkbFreeDeviceInfo( + XkbDeviceInfoPtr /* devi */, + unsigned int /* which */, + Bool /* freeDevI */ ); -extern void XkbNoteDeviceChanges( - XkbDeviceChangesPtr /* old */, - XkbExtensionDeviceNotifyEvent * /* new */, - unsigned int /* wanted */ +extern void XkbNoteDeviceChanges( + XkbDeviceChangesPtr /* old */, + XkbExtensionDeviceNotifyEvent* /* new */, + unsigned int /* wanted */ ); -extern XkbDeviceInfoPtr XkbGetDeviceInfo( - Display * /* dpy */, - unsigned int /* which */, - unsigned int /* deviceSpec */, - unsigned int /* ledClass */, - unsigned int /* ledID */ +extern XkbDeviceInfoPtr XkbGetDeviceInfo( + Display* /* dpy */, + unsigned int /* which */, + unsigned int /* deviceSpec */, + unsigned int /* ledClass */, + unsigned int /* ledID */ ); -extern Status XkbGetDeviceInfoChanges( - Display * /* dpy */, - XkbDeviceInfoPtr /* devi */, - XkbDeviceChangesPtr /* changes */ +extern Status XkbGetDeviceInfoChanges( + Display* /* dpy */, + XkbDeviceInfoPtr /* devi */, + XkbDeviceChangesPtr /* changes */ ); -extern Status XkbGetDeviceButtonActions( - Display * /* dpy */, - XkbDeviceInfoPtr /* devi */, - Bool /* all */, - unsigned int /* first */, - unsigned int /* nBtns */ +extern Status XkbGetDeviceButtonActions( + Display* /* dpy */, + XkbDeviceInfoPtr /* devi */, + Bool /* all */, + unsigned int /* first */, + unsigned int /* nBtns */ ); -extern Status XkbGetDeviceLedInfo( - Display * /* dpy */, - XkbDeviceInfoPtr /* devi */, - unsigned int /* ledClass (class, XIDflt, XIAll) */, - unsigned int /* ledId (id, XIDflt, XIAll) */, - unsigned int /* which (XkbXI_Indicator{Names,Map}Mask */ +extern Status XkbGetDeviceLedInfo( + Display* /* dpy */, + XkbDeviceInfoPtr /* devi */, + unsigned int /* ledClass (class, XIDflt, XIAll) */, + unsigned int /* ledId (id, XIDflt, XIAll) */, + unsigned int /* which (XkbXI_Indicator{Names,Map}Mask */ ); -extern Bool XkbSetDeviceInfo( - Display * /* dpy */, - unsigned int /* which */, - XkbDeviceInfoPtr /* devi */ +extern Bool XkbSetDeviceInfo( + Display* /* dpy */, + unsigned int /* which */, + XkbDeviceInfoPtr /* devi */ ); -extern Bool XkbChangeDeviceInfo( - Display* /* dpy */, - XkbDeviceInfoPtr /* desc */, - XkbDeviceChangesPtr /* changes */ +extern Bool XkbChangeDeviceInfo( + Display* /* dpy */, + XkbDeviceInfoPtr /* desc */, + XkbDeviceChangesPtr /* changes */ ); -extern Bool XkbSetDeviceLedInfo( - Display * /* dpy */, - XkbDeviceInfoPtr /* devi */, - unsigned int /* ledClass */, - unsigned int /* ledID */, - unsigned int /* which */ +extern Bool XkbSetDeviceLedInfo( + Display* /* dpy */, + XkbDeviceInfoPtr /* devi */, + unsigned int /* ledClass */, + unsigned int /* ledID */, + unsigned int /* which */ ); -extern Bool XkbSetDeviceButtonActions( - Display * /* dpy */, - XkbDeviceInfoPtr /* devi */, - unsigned int /* first */, - unsigned int /* nBtns */ +extern Bool XkbSetDeviceButtonActions( + Display* /* dpy */, + XkbDeviceInfoPtr /* devi */, + unsigned int /* first */, + unsigned int /* nBtns */ ); /***====================================================================***/ -extern char XkbToControl( - char /* c */ +extern char XkbToControl( + char /* c */ ); /***====================================================================***/ -extern Bool XkbSetDebuggingFlags( - Display * /* dpy */, - unsigned int /* mask */, - unsigned int /* flags */, - char * /* msg */, - unsigned int /* ctrls_mask */, - unsigned int /* ctrls */, - unsigned int * /* rtrn_flags */, - unsigned int * /* rtrn_ctrls */ +extern Bool XkbSetDebuggingFlags( + Display* /* dpy */, + unsigned int /* mask */, + unsigned int /* flags */, + char* /* msg */, + unsigned int /* ctrls_mask */, + unsigned int /* ctrls */, + unsigned int* /* rtrn_flags */, + unsigned int* /* rtrn_ctrls */ ); -extern Bool XkbApplyVirtualModChanges( - XkbDescPtr /* xkb */, - unsigned int /* changed */, - XkbChangesPtr /* changes */ +extern Bool XkbApplyVirtualModChanges( + XkbDescPtr /* xkb */, + unsigned int /* changed */, + XkbChangesPtr /* changes */ ); extern Bool XkbUpdateActionVirtualMods( - XkbDescPtr /* xkb */, - XkbAction * /* act */, - unsigned int /* changed */ + XkbDescPtr /* xkb */, + XkbAction* /* act */, + unsigned int /* changed */ ); extern void XkbUpdateKeyTypeVirtualMods( - XkbDescPtr /* xkb */, - XkbKeyTypePtr /* type */, - unsigned int /* changed */, - XkbChangesPtr /* changes */ + XkbDescPtr /* xkb */, + XkbKeyTypePtr /* type */, + unsigned int /* changed */, + XkbChangesPtr /* changes */ ); _XFUNCPROTOEND diff --git a/examples/ThirdPartyLibs/optionalX11/X11/Xatom.h b/examples/ThirdPartyLibs/optionalX11/X11/Xatom.h index 485a4236d..c587d97cb 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/Xatom.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/Xatom.h @@ -6,74 +6,74 @@ * Do not change! Changing this file implies a protocol change! */ -#define XA_PRIMARY ((Atom) 1) -#define XA_SECONDARY ((Atom) 2) -#define XA_ARC ((Atom) 3) -#define XA_ATOM ((Atom) 4) -#define XA_BITMAP ((Atom) 5) -#define XA_CARDINAL ((Atom) 6) -#define XA_COLORMAP ((Atom) 7) -#define XA_CURSOR ((Atom) 8) -#define XA_CUT_BUFFER0 ((Atom) 9) -#define XA_CUT_BUFFER1 ((Atom) 10) -#define XA_CUT_BUFFER2 ((Atom) 11) -#define XA_CUT_BUFFER3 ((Atom) 12) -#define XA_CUT_BUFFER4 ((Atom) 13) -#define XA_CUT_BUFFER5 ((Atom) 14) -#define XA_CUT_BUFFER6 ((Atom) 15) -#define XA_CUT_BUFFER7 ((Atom) 16) -#define XA_DRAWABLE ((Atom) 17) -#define XA_FONT ((Atom) 18) -#define XA_INTEGER ((Atom) 19) -#define XA_PIXMAP ((Atom) 20) -#define XA_POINT ((Atom) 21) -#define XA_RECTANGLE ((Atom) 22) -#define XA_RESOURCE_MANAGER ((Atom) 23) -#define XA_RGB_COLOR_MAP ((Atom) 24) -#define XA_RGB_BEST_MAP ((Atom) 25) -#define XA_RGB_BLUE_MAP ((Atom) 26) -#define XA_RGB_DEFAULT_MAP ((Atom) 27) -#define XA_RGB_GRAY_MAP ((Atom) 28) -#define XA_RGB_GREEN_MAP ((Atom) 29) -#define XA_RGB_RED_MAP ((Atom) 30) -#define XA_STRING ((Atom) 31) -#define XA_VISUALID ((Atom) 32) -#define XA_WINDOW ((Atom) 33) -#define XA_WM_COMMAND ((Atom) 34) -#define XA_WM_HINTS ((Atom) 35) -#define XA_WM_CLIENT_MACHINE ((Atom) 36) -#define XA_WM_ICON_NAME ((Atom) 37) -#define XA_WM_ICON_SIZE ((Atom) 38) -#define XA_WM_NAME ((Atom) 39) -#define XA_WM_NORMAL_HINTS ((Atom) 40) -#define XA_WM_SIZE_HINTS ((Atom) 41) -#define XA_WM_ZOOM_HINTS ((Atom) 42) -#define XA_MIN_SPACE ((Atom) 43) -#define XA_NORM_SPACE ((Atom) 44) -#define XA_MAX_SPACE ((Atom) 45) -#define XA_END_SPACE ((Atom) 46) -#define XA_SUPERSCRIPT_X ((Atom) 47) -#define XA_SUPERSCRIPT_Y ((Atom) 48) -#define XA_SUBSCRIPT_X ((Atom) 49) -#define XA_SUBSCRIPT_Y ((Atom) 50) -#define XA_UNDERLINE_POSITION ((Atom) 51) -#define XA_UNDERLINE_THICKNESS ((Atom) 52) -#define XA_STRIKEOUT_ASCENT ((Atom) 53) -#define XA_STRIKEOUT_DESCENT ((Atom) 54) -#define XA_ITALIC_ANGLE ((Atom) 55) -#define XA_X_HEIGHT ((Atom) 56) -#define XA_QUAD_WIDTH ((Atom) 57) -#define XA_WEIGHT ((Atom) 58) -#define XA_POINT_SIZE ((Atom) 59) -#define XA_RESOLUTION ((Atom) 60) -#define XA_COPYRIGHT ((Atom) 61) -#define XA_NOTICE ((Atom) 62) -#define XA_FONT_NAME ((Atom) 63) -#define XA_FAMILY_NAME ((Atom) 64) -#define XA_FULL_NAME ((Atom) 65) -#define XA_CAP_HEIGHT ((Atom) 66) -#define XA_WM_CLASS ((Atom) 67) -#define XA_WM_TRANSIENT_FOR ((Atom) 68) +#define XA_PRIMARY ((Atom)1) +#define XA_SECONDARY ((Atom)2) +#define XA_ARC ((Atom)3) +#define XA_ATOM ((Atom)4) +#define XA_BITMAP ((Atom)5) +#define XA_CARDINAL ((Atom)6) +#define XA_COLORMAP ((Atom)7) +#define XA_CURSOR ((Atom)8) +#define XA_CUT_BUFFER0 ((Atom)9) +#define XA_CUT_BUFFER1 ((Atom)10) +#define XA_CUT_BUFFER2 ((Atom)11) +#define XA_CUT_BUFFER3 ((Atom)12) +#define XA_CUT_BUFFER4 ((Atom)13) +#define XA_CUT_BUFFER5 ((Atom)14) +#define XA_CUT_BUFFER6 ((Atom)15) +#define XA_CUT_BUFFER7 ((Atom)16) +#define XA_DRAWABLE ((Atom)17) +#define XA_FONT ((Atom)18) +#define XA_INTEGER ((Atom)19) +#define XA_PIXMAP ((Atom)20) +#define XA_POINT ((Atom)21) +#define XA_RECTANGLE ((Atom)22) +#define XA_RESOURCE_MANAGER ((Atom)23) +#define XA_RGB_COLOR_MAP ((Atom)24) +#define XA_RGB_BEST_MAP ((Atom)25) +#define XA_RGB_BLUE_MAP ((Atom)26) +#define XA_RGB_DEFAULT_MAP ((Atom)27) +#define XA_RGB_GRAY_MAP ((Atom)28) +#define XA_RGB_GREEN_MAP ((Atom)29) +#define XA_RGB_RED_MAP ((Atom)30) +#define XA_STRING ((Atom)31) +#define XA_VISUALID ((Atom)32) +#define XA_WINDOW ((Atom)33) +#define XA_WM_COMMAND ((Atom)34) +#define XA_WM_HINTS ((Atom)35) +#define XA_WM_CLIENT_MACHINE ((Atom)36) +#define XA_WM_ICON_NAME ((Atom)37) +#define XA_WM_ICON_SIZE ((Atom)38) +#define XA_WM_NAME ((Atom)39) +#define XA_WM_NORMAL_HINTS ((Atom)40) +#define XA_WM_SIZE_HINTS ((Atom)41) +#define XA_WM_ZOOM_HINTS ((Atom)42) +#define XA_MIN_SPACE ((Atom)43) +#define XA_NORM_SPACE ((Atom)44) +#define XA_MAX_SPACE ((Atom)45) +#define XA_END_SPACE ((Atom)46) +#define XA_SUPERSCRIPT_X ((Atom)47) +#define XA_SUPERSCRIPT_Y ((Atom)48) +#define XA_SUBSCRIPT_X ((Atom)49) +#define XA_SUBSCRIPT_Y ((Atom)50) +#define XA_UNDERLINE_POSITION ((Atom)51) +#define XA_UNDERLINE_THICKNESS ((Atom)52) +#define XA_STRIKEOUT_ASCENT ((Atom)53) +#define XA_STRIKEOUT_DESCENT ((Atom)54) +#define XA_ITALIC_ANGLE ((Atom)55) +#define XA_X_HEIGHT ((Atom)56) +#define XA_QUAD_WIDTH ((Atom)57) +#define XA_WEIGHT ((Atom)58) +#define XA_POINT_SIZE ((Atom)59) +#define XA_RESOLUTION ((Atom)60) +#define XA_COPYRIGHT ((Atom)61) +#define XA_NOTICE ((Atom)62) +#define XA_FONT_NAME ((Atom)63) +#define XA_FAMILY_NAME ((Atom)64) +#define XA_FULL_NAME ((Atom)65) +#define XA_CAP_HEIGHT ((Atom)66) +#define XA_WM_CLASS ((Atom)67) +#define XA_WM_TRANSIENT_FOR ((Atom)68) -#define XA_LAST_PREDEFINED ((Atom) 68) +#define XA_LAST_PREDEFINED ((Atom)68) #endif /* XATOM_H */ diff --git a/examples/ThirdPartyLibs/optionalX11/X11/Xfuncproto.h b/examples/ThirdPartyLibs/optionalX11/X11/Xfuncproto.h index 3a074aaab..db6d41f4b 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/Xfuncproto.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/Xfuncproto.h @@ -60,7 +60,7 @@ in this Software without prior written authorization from The Open Group. #ifdef NARROWPROTO #define NeedWidePrototypes 0 #else -#define NeedWidePrototypes 1 /* default to make interropt. easier */ +#define NeedWidePrototypes 1 /* default to make interropt. easier */ #endif #endif /* NeedWidePrototypes */ @@ -68,7 +68,9 @@ in this Software without prior written authorization from The Open Group. #ifndef _XFUNCPROTOBEGIN #if defined(__cplusplus) || defined(c_plusplus) /* for C++ V2.0 */ -#define _XFUNCPROTOBEGIN extern "C" { /* do not leave open across includes */ +#define _XFUNCPROTOBEGIN \ + extern "C" \ + { /* do not leave open across includes */ #define _XFUNCPROTOEND } #else #define _XFUNCPROTOBEGIN @@ -78,98 +80,97 @@ in this Software without prior written authorization from The Open Group. /* Added in X11R6.9, so available in any version of modular xproto */ #if defined(__GNUC__) && (__GNUC__ >= 4) -# define _X_SENTINEL(x) __attribute__ ((__sentinel__(x))) +#define _X_SENTINEL(x) __attribute__((__sentinel__(x))) #else -# define _X_SENTINEL(x) +#define _X_SENTINEL(x) #endif /* GNUC >= 4 */ /* Added in X11R6.9, so available in any version of modular xproto */ #if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(__CYGWIN__) && !defined(__MINGW32__) -# define _X_EXPORT __attribute__((visibility("default"))) -# define _X_HIDDEN __attribute__((visibility("hidden"))) -# define _X_INTERNAL __attribute__((visibility("internal"))) +#define _X_EXPORT __attribute__((visibility("default"))) +#define _X_HIDDEN __attribute__((visibility("hidden"))) +#define _X_INTERNAL __attribute__((visibility("internal"))) #elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550) -# define _X_EXPORT __global -# define _X_HIDDEN __hidden -# define _X_INTERNAL __hidden +#define _X_EXPORT __global +#define _X_HIDDEN __hidden +#define _X_INTERNAL __hidden #else /* not gcc >= 4 and not Sun Studio >= 8 */ -# define _X_EXPORT -# define _X_HIDDEN -# define _X_INTERNAL +#define _X_EXPORT +#define _X_HIDDEN +#define _X_INTERNAL #endif /* GNUC >= 4 */ /* requires xproto >= 7.0.9 */ #if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 303) -# define _X_LIKELY(x) __builtin_expect(!!(x), 1) -# define _X_UNLIKELY(x) __builtin_expect(!!(x), 0) +#define _X_LIKELY(x) __builtin_expect(!!(x), 1) +#define _X_UNLIKELY(x) __builtin_expect(!!(x), 0) #else /* not gcc >= 3.3 */ -# define _X_LIKELY(x) (x) -# define _X_UNLIKELY(x) (x) +#define _X_LIKELY(x) (x) +#define _X_UNLIKELY(x) (x) #endif /* Added in X11R6.9, so available in any version of modular xproto */ #if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 301) -# define _X_DEPRECATED __attribute__((deprecated)) +#define _X_DEPRECATED __attribute__((deprecated)) #else /* not gcc >= 3.1 */ -# define _X_DEPRECATED +#define _X_DEPRECATED #endif /* requires xproto >= 7.0.17 */ -#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) \ - || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) -# define _X_NORETURN __attribute((noreturn)) +#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205)) || (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)) +#define _X_NORETURN __attribute((noreturn)) #else -# define _X_NORETURN +#define _X_NORETURN #endif /* GNUC */ /* Added in X11R6.9, so available in any version of modular xproto */ #if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 203) -# define _X_ATTRIBUTE_PRINTF(x,y) __attribute__((__format__(__printf__,x,y))) +#define _X_ATTRIBUTE_PRINTF(x, y) __attribute__((__format__(__printf__, x, y))) #else /* not gcc >= 2.3 */ -# define _X_ATTRIBUTE_PRINTF(x,y) +#define _X_ATTRIBUTE_PRINTF(x, y) #endif /* requires xproto >= 7.0.22 - since this uses either gcc or C99 variable argument macros, must be only used inside #ifdef _X_NONNULL guards, as many legacy X clients are compiled in C89 mode still. */ -#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 303) -#define _X_NONNULL(args...) __attribute__((nonnull(args))) +#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 303) +#define _X_NONNULL(args...) __attribute__((nonnull(args))) #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L) /* C99 */ -#define _X_NONNULL(...) /* */ +#define _X_NONNULL(...) /* */ #endif /* requires xproto >= 7.0.22 */ -#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205) -#define _X_UNUSED __attribute__((__unused__)) +#if defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 205) +#define _X_UNUSED __attribute__((__unused__)) #else -#define _X_UNUSED /* */ +#define _X_UNUSED /* */ #endif /* C99 keyword "inline" or equivalent extensions in pre-C99 compilers */ /* requires xproto >= 7.0.9 (introduced in 7.0.8 but didn't support all compilers until 7.0.9) */ -#if defined(inline) /* assume autoconf set it correctly */ || \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L)) /* C99 */ || \ - (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)) -# define _X_INLINE inline +#if defined(inline) /* assume autoconf set it correctly */ || \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L)) /* C99 */ || \ + (defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)) +#define _X_INLINE inline #elif defined(__GNUC__) && !defined(__STRICT_ANSI__) /* gcc w/C89+extensions */ -# define _X_INLINE __inline__ +#define _X_INLINE __inline__ #else -# define _X_INLINE +#define _X_INLINE #endif /* C99 keyword "restrict" or equivalent extensions in pre-C99 compilers */ /* requires xproto >= 7.0.21 */ #ifndef _X_RESTRICT_KYWD -# if defined(restrict) /* assume autoconf set it correctly */ || \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L) /* C99 */ \ - && !defined(__cplusplus)) /* Workaround g++ issue on Solaris */ -# define _X_RESTRICT_KYWD restrict -# elif defined(__GNUC__) && !defined(__STRICT_ANSI__) /* gcc w/C89+extensions */ -# define _X_RESTRICT_KYWD __restrict__ -# else -# define _X_RESTRICT_KYWD -# endif +#if defined(restrict) /* assume autoconf set it correctly */ || \ + (defined(__STDC_VERSION__) && (__STDC_VERSION__ - 0 >= 199901L) /* C99 */ \ + && !defined(__cplusplus)) /* Workaround g++ issue on Solaris */ +#define _X_RESTRICT_KYWD restrict +#elif defined(__GNUC__) && !defined(__STRICT_ANSI__) /* gcc w/C89+extensions */ +#define _X_RESTRICT_KYWD __restrict__ +#else +#define _X_RESTRICT_KYWD +#endif #endif #endif /* _XFUNCPROTO_H_ */ diff --git a/examples/ThirdPartyLibs/optionalX11/X11/Xfuncs.h b/examples/ThirdPartyLibs/optionalX11/X11/Xfuncs.h index 2bcf991a9..eef93a2d0 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/Xfuncs.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/Xfuncs.h @@ -25,45 +25,45 @@ in this Software without prior written authorization from The Open Group. */ #ifndef _XFUNCS_H_ -# define _XFUNCS_H_ +#define _XFUNCS_H_ -# include +#include /* the old Xfuncs.h, for pre-R6 */ -# if !(defined(XFree86LOADER) && defined(IN_MODULE)) +#if !(defined(XFree86LOADER) && defined(IN_MODULE)) -# ifdef X_USEBFUNCS +#ifdef X_USEBFUNCS void bcopy(); void bzero(); int bcmp(); -# else -# if defined(SYSV) && !defined(__SCO__) && !defined(__sun) && !defined(__UNIXWARE__) -# include +#else +#if defined(SYSV) && !defined(__SCO__) && !defined(__sun) && !defined(__UNIXWARE__) +#include void bcopy(); -# define bzero(b,len) memset(b, 0, len) -# define bcmp(b1,b2,len) memcmp(b1, b2, len) -# else -# include -# if defined(__SCO__) || defined(__sun) || defined(__UNIXWARE__) || defined(__CYGWIN__) -# include -# endif -# define _XFUNCS_H_INCLUDED_STRING_H -# endif -# endif /* X_USEBFUNCS */ +#define bzero(b, len) memset(b, 0, len) +#define bcmp(b1, b2, len) memcmp(b1, b2, len) +#else +#include +#if defined(__SCO__) || defined(__sun) || defined(__UNIXWARE__) || defined(__CYGWIN__) +#include +#endif +#define _XFUNCS_H_INCLUDED_STRING_H +#endif +#endif /* X_USEBFUNCS */ /* the new Xfuncs.h */ /* the ANSI C way */ -# ifndef _XFUNCS_H_INCLUDED_STRING_H -# include -# endif -# undef bzero -# define bzero(b,len) memset(b,0,len) +#ifndef _XFUNCS_H_INCLUDED_STRING_H +#include +#endif +#undef bzero +#define bzero(b, len) memset(b, 0, len) -# if defined WIN32 && defined __MINGW32__ -# define bcopy(b1,b2,len) memmove(b2, b1, (size_t)(len)) -# endif +#if defined WIN32 && defined __MINGW32__ +#define bcopy(b1, b2, len) memmove(b2, b1, (size_t)(len)) +#endif -# endif /* !(defined(XFree86LOADER) && defined(IN_MODULE)) */ +#endif /* !(defined(XFree86LOADER) && defined(IN_MODULE)) */ #endif /* _XFUNCS_H_ */ diff --git a/examples/ThirdPartyLibs/optionalX11/X11/Xlib.h b/examples/ThirdPartyLibs/optionalX11/X11/Xlib.h index 65f253cd4..3cd69177d 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/Xlib.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/Xlib.h @@ -24,7 +24,6 @@ in this Software without prior written authorization from The Open Group. */ - /* * Xlib.h - Header definition and support file for the C subroutine * interface library (Xlib) to the X Window System Protocol (V11). @@ -59,23 +58,23 @@ typedef unsigned long wchar_t; #endif #if defined(ISC) && defined(USE_XMBTOWC) -#define wctomb(a,b) _Xwctomb(a,b) -#define mblen(a,b) _Xmblen(a,b) +#define wctomb(a, b) _Xwctomb(a, b) +#define mblen(a, b) _Xmblen(a, b) #ifndef USE_XWCHAR_STRING -#define mbtowc(a,b,c) _Xmbtowc(a,b,c) +#define mbtowc(a, b, c) _Xmbtowc(a, b, c) #endif #endif extern int _Xmblen( #ifdef ISC - char const *str, - size_t len + char const* str, + size_t len #else - char *str, - int len + char* str, + int len #endif - ); +); /* API mentioning "UTF8" or "utf8" is an XFree86 extension, introduced in November 2000. Its presence is indicated through the following macro. */ @@ -89,7 +88,7 @@ _Xmblen( #pragma clang diagnostic ignored "-Wpadded" #endif -typedef char *XPointer; +typedef char* XPointer; #define Bool int #define Status int @@ -100,121 +99,123 @@ typedef char *XPointer; #define QueuedAfterReading 1 #define QueuedAfterFlush 2 -#define ConnectionNumber(dpy) (((_XPrivDisplay)dpy)->fd) -#define RootWindow(dpy, scr) (ScreenOfDisplay(dpy,scr)->root) -#define DefaultScreen(dpy) (((_XPrivDisplay)dpy)->default_screen) -#define DefaultRootWindow(dpy) (ScreenOfDisplay(dpy,DefaultScreen(dpy))->root) -#define DefaultVisual(dpy, scr) (ScreenOfDisplay(dpy,scr)->root_visual) -#define DefaultGC(dpy, scr) (ScreenOfDisplay(dpy,scr)->default_gc) -#define BlackPixel(dpy, scr) (ScreenOfDisplay(dpy,scr)->black_pixel) -#define WhitePixel(dpy, scr) (ScreenOfDisplay(dpy,scr)->white_pixel) -#define AllPlanes ((unsigned long)~0L) -#define QLength(dpy) (((_XPrivDisplay)dpy)->qlen) -#define DisplayWidth(dpy, scr) (ScreenOfDisplay(dpy,scr)->width) -#define DisplayHeight(dpy, scr) (ScreenOfDisplay(dpy,scr)->height) -#define DisplayWidthMM(dpy, scr)(ScreenOfDisplay(dpy,scr)->mwidth) -#define DisplayHeightMM(dpy, scr)(ScreenOfDisplay(dpy,scr)->mheight) -#define DisplayPlanes(dpy, scr) (ScreenOfDisplay(dpy,scr)->root_depth) -#define DisplayCells(dpy, scr) (DefaultVisual(dpy,scr)->map_entries) -#define ScreenCount(dpy) (((_XPrivDisplay)dpy)->nscreens) -#define ServerVendor(dpy) (((_XPrivDisplay)dpy)->vendor) -#define ProtocolVersion(dpy) (((_XPrivDisplay)dpy)->proto_major_version) -#define ProtocolRevision(dpy) (((_XPrivDisplay)dpy)->proto_minor_version) -#define VendorRelease(dpy) (((_XPrivDisplay)dpy)->release) -#define DisplayString(dpy) (((_XPrivDisplay)dpy)->display_name) -#define DefaultDepth(dpy, scr) (ScreenOfDisplay(dpy,scr)->root_depth) -#define DefaultColormap(dpy, scr)(ScreenOfDisplay(dpy,scr)->cmap) -#define BitmapUnit(dpy) (((_XPrivDisplay)dpy)->bitmap_unit) -#define BitmapBitOrder(dpy) (((_XPrivDisplay)dpy)->bitmap_bit_order) -#define BitmapPad(dpy) (((_XPrivDisplay)dpy)->bitmap_pad) -#define ImageByteOrder(dpy) (((_XPrivDisplay)dpy)->byte_order) -#define NextRequest(dpy) (((_XPrivDisplay)dpy)->request + 1) -#define LastKnownRequestProcessed(dpy) (((_XPrivDisplay)dpy)->last_request_read) +#define ConnectionNumber(dpy) (((_XPrivDisplay)dpy)->fd) +#define RootWindow(dpy, scr) (ScreenOfDisplay(dpy, scr)->root) +#define DefaultScreen(dpy) (((_XPrivDisplay)dpy)->default_screen) +#define DefaultRootWindow(dpy) (ScreenOfDisplay(dpy, DefaultScreen(dpy))->root) +#define DefaultVisual(dpy, scr) (ScreenOfDisplay(dpy, scr)->root_visual) +#define DefaultGC(dpy, scr) (ScreenOfDisplay(dpy, scr)->default_gc) +#define BlackPixel(dpy, scr) (ScreenOfDisplay(dpy, scr)->black_pixel) +#define WhitePixel(dpy, scr) (ScreenOfDisplay(dpy, scr)->white_pixel) +#define AllPlanes ((unsigned long)~0L) +#define QLength(dpy) (((_XPrivDisplay)dpy)->qlen) +#define DisplayWidth(dpy, scr) (ScreenOfDisplay(dpy, scr)->width) +#define DisplayHeight(dpy, scr) (ScreenOfDisplay(dpy, scr)->height) +#define DisplayWidthMM(dpy, scr) (ScreenOfDisplay(dpy, scr)->mwidth) +#define DisplayHeightMM(dpy, scr) (ScreenOfDisplay(dpy, scr)->mheight) +#define DisplayPlanes(dpy, scr) (ScreenOfDisplay(dpy, scr)->root_depth) +#define DisplayCells(dpy, scr) (DefaultVisual(dpy, scr)->map_entries) +#define ScreenCount(dpy) (((_XPrivDisplay)dpy)->nscreens) +#define ServerVendor(dpy) (((_XPrivDisplay)dpy)->vendor) +#define ProtocolVersion(dpy) (((_XPrivDisplay)dpy)->proto_major_version) +#define ProtocolRevision(dpy) (((_XPrivDisplay)dpy)->proto_minor_version) +#define VendorRelease(dpy) (((_XPrivDisplay)dpy)->release) +#define DisplayString(dpy) (((_XPrivDisplay)dpy)->display_name) +#define DefaultDepth(dpy, scr) (ScreenOfDisplay(dpy, scr)->root_depth) +#define DefaultColormap(dpy, scr) (ScreenOfDisplay(dpy, scr)->cmap) +#define BitmapUnit(dpy) (((_XPrivDisplay)dpy)->bitmap_unit) +#define BitmapBitOrder(dpy) (((_XPrivDisplay)dpy)->bitmap_bit_order) +#define BitmapPad(dpy) (((_XPrivDisplay)dpy)->bitmap_pad) +#define ImageByteOrder(dpy) (((_XPrivDisplay)dpy)->byte_order) +#define NextRequest(dpy) (((_XPrivDisplay)dpy)->request + 1) +#define LastKnownRequestProcessed(dpy) (((_XPrivDisplay)dpy)->last_request_read) /* macros for screen oriented applications (toolkit) */ -#define ScreenOfDisplay(dpy, scr)(&((_XPrivDisplay)dpy)->screens[scr]) -#define DefaultScreenOfDisplay(dpy) ScreenOfDisplay(dpy,DefaultScreen(dpy)) -#define DisplayOfScreen(s) ((s)->display) -#define RootWindowOfScreen(s) ((s)->root) -#define BlackPixelOfScreen(s) ((s)->black_pixel) -#define WhitePixelOfScreen(s) ((s)->white_pixel) -#define DefaultColormapOfScreen(s)((s)->cmap) -#define DefaultDepthOfScreen(s) ((s)->root_depth) -#define DefaultGCOfScreen(s) ((s)->default_gc) -#define DefaultVisualOfScreen(s)((s)->root_visual) -#define WidthOfScreen(s) ((s)->width) -#define HeightOfScreen(s) ((s)->height) -#define WidthMMOfScreen(s) ((s)->mwidth) -#define HeightMMOfScreen(s) ((s)->mheight) -#define PlanesOfScreen(s) ((s)->root_depth) -#define CellsOfScreen(s) (DefaultVisualOfScreen((s))->map_entries) -#define MinCmapsOfScreen(s) ((s)->min_maps) -#define MaxCmapsOfScreen(s) ((s)->max_maps) -#define DoesSaveUnders(s) ((s)->save_unders) -#define DoesBackingStore(s) ((s)->backing_store) -#define EventMaskOfScreen(s) ((s)->root_input_mask) +#define ScreenOfDisplay(dpy, scr) (&((_XPrivDisplay)dpy)->screens[scr]) +#define DefaultScreenOfDisplay(dpy) ScreenOfDisplay(dpy, DefaultScreen(dpy)) +#define DisplayOfScreen(s) ((s)->display) +#define RootWindowOfScreen(s) ((s)->root) +#define BlackPixelOfScreen(s) ((s)->black_pixel) +#define WhitePixelOfScreen(s) ((s)->white_pixel) +#define DefaultColormapOfScreen(s) ((s)->cmap) +#define DefaultDepthOfScreen(s) ((s)->root_depth) +#define DefaultGCOfScreen(s) ((s)->default_gc) +#define DefaultVisualOfScreen(s) ((s)->root_visual) +#define WidthOfScreen(s) ((s)->width) +#define HeightOfScreen(s) ((s)->height) +#define WidthMMOfScreen(s) ((s)->mwidth) +#define HeightMMOfScreen(s) ((s)->mheight) +#define PlanesOfScreen(s) ((s)->root_depth) +#define CellsOfScreen(s) (DefaultVisualOfScreen((s))->map_entries) +#define MinCmapsOfScreen(s) ((s)->min_maps) +#define MaxCmapsOfScreen(s) ((s)->max_maps) +#define DoesSaveUnders(s) ((s)->save_unders) +#define DoesBackingStore(s) ((s)->backing_store) +#define EventMaskOfScreen(s) ((s)->root_input_mask) /* * Extensions need a way to hang private data on some structures. */ -typedef struct _XExtData { - int number; /* number returned by XRegisterExtension */ - struct _XExtData *next; /* next item on list of data for structure */ - int (*free_private)( /* called to free private storage */ - struct _XExtData *extension - ); - XPointer private_data; /* data private to this extension. */ +typedef struct _XExtData +{ + int number; /* number returned by XRegisterExtension */ + struct _XExtData* next; /* next item on list of data for structure */ + int (*free_private)( /* called to free private storage */ + struct _XExtData* extension); + XPointer private_data; /* data private to this extension. */ } XExtData; /* * This file contains structures used by the extension mechanism. */ -typedef struct { /* public to extension, cannot be changed */ - int extension; /* extension number */ - int major_opcode; /* major op-code assigned by server */ - int first_event; /* first event number for the extension */ - int first_error; /* first error number for the extension */ +typedef struct +{ /* public to extension, cannot be changed */ + int extension; /* extension number */ + int major_opcode; /* major op-code assigned by server */ + int first_event; /* first event number for the extension */ + int first_error; /* first error number for the extension */ } XExtCodes; /* * Data structure for retrieving info about pixmap formats. */ -typedef struct { - int depth; - int bits_per_pixel; - int scanline_pad; +typedef struct +{ + int depth; + int bits_per_pixel; + int scanline_pad; } XPixmapFormatValues; - /* * Data structure for setting graphics context. */ -typedef struct { - int function; /* logical operation */ - unsigned long plane_mask;/* plane mask */ - unsigned long foreground;/* foreground pixel */ - unsigned long background;/* background pixel */ - int line_width; /* line width */ - int line_style; /* LineSolid, LineOnOffDash, LineDoubleDash */ - int cap_style; /* CapNotLast, CapButt, +typedef struct +{ + int function; /* logical operation */ + unsigned long plane_mask; /* plane mask */ + unsigned long foreground; /* foreground pixel */ + unsigned long background; /* background pixel */ + int line_width; /* line width */ + int line_style; /* LineSolid, LineOnOffDash, LineDoubleDash */ + int cap_style; /* CapNotLast, CapButt, CapRound, CapProjecting */ - int join_style; /* JoinMiter, JoinRound, JoinBevel */ - int fill_style; /* FillSolid, FillTiled, + int join_style; /* JoinMiter, JoinRound, JoinBevel */ + int fill_style; /* FillSolid, FillTiled, FillStippled, FillOpaeueStippled */ - int fill_rule; /* EvenOddRule, WindingRule */ - int arc_mode; /* ArcChord, ArcPieSlice */ - Pixmap tile; /* tile pixmap for tiling operations */ - Pixmap stipple; /* stipple 1 plane pixmap for stipping */ - int ts_x_origin; /* offset for tile or stipple operations */ + int fill_rule; /* EvenOddRule, WindingRule */ + int arc_mode; /* ArcChord, ArcPieSlice */ + Pixmap tile; /* tile pixmap for tiling operations */ + Pixmap stipple; /* stipple 1 plane pixmap for stipping */ + int ts_x_origin; /* offset for tile or stipple operations */ int ts_y_origin; - Font font; /* default text font for text operations */ - int subwindow_mode; /* ClipByChildren, IncludeInferiors */ - Bool graphics_exposures;/* boolean, should exposures be generated */ - int clip_x_origin; /* origin for clipping */ + Font font; /* default text font for text operations */ + int subwindow_mode; /* ClipByChildren, IncludeInferiors */ + Bool graphics_exposures; /* boolean, should exposures be generated */ + int clip_x_origin; /* origin for clipping */ int clip_y_origin; - Pixmap clip_mask; /* bitmap clipping; other calls for rects */ - int dash_offset; /* patterned/dashed line information */ + Pixmap clip_mask; /* bitmap clipping; other calls for rects */ + int dash_offset; /* patterned/dashed line information */ char dashes; } XGCValues; @@ -226,36 +227,38 @@ typedef struct { typedef struct _XGC #ifdef XLIB_ILLEGAL_ACCESS { - XExtData *ext_data; /* hook for extension to hang data */ - GContext gid; /* protocol ID for graphics context */ - /* there is more to this structure, but it is private to Xlib */ + XExtData* ext_data; /* hook for extension to hang data */ + GContext gid; /* protocol ID for graphics context */ + /* there is more to this structure, but it is private to Xlib */ } #endif -*GC; + * GC; /* * Visual structure; contains information about colormapping possible. */ -typedef struct { - XExtData *ext_data; /* hook for extension to hang data */ - VisualID visualid; /* visual id of this visual */ +typedef struct +{ + XExtData* ext_data; /* hook for extension to hang data */ + VisualID visualid; /* visual id of this visual */ #if defined(__cplusplus) || defined(c_plusplus) - int c_class; /* C++ class of screen (monochrome, etc.) */ + int c_class; /* C++ class of screen (monochrome, etc.) */ #else - int class; /* class of screen (monochrome, etc.) */ + int class; /* class of screen (monochrome, etc.) */ #endif - unsigned long red_mask, green_mask, blue_mask; /* mask values */ - int bits_per_rgb; /* log base 2 of distinct color values */ - int map_entries; /* color map entries */ + unsigned long red_mask, green_mask, blue_mask; /* mask values */ + int bits_per_rgb; /* log base 2 of distinct color values */ + int map_entries; /* color map entries */ } Visual; /* * Depth structure; contains information for each possible depth. */ -typedef struct { - int depth; /* this depth (Z) of the depth */ - int nvisuals; /* number of Visual types at this depth */ - Visual *visuals; /* list of visuals possible at this depth */ +typedef struct +{ + int depth; /* this depth (Z) of the depth */ + int nvisuals; /* number of Visual types at this depth */ + Visual* visuals; /* list of visuals possible at this depth */ } Depth; /* @@ -264,85 +267,89 @@ typedef struct { * by application code. */ -struct _XDisplay; /* Forward declare before use for C++ */ +struct _XDisplay; /* Forward declare before use for C++ */ -typedef struct { - XExtData *ext_data; /* hook for extension to hang data */ - struct _XDisplay *display;/* back pointer to display structure */ - Window root; /* Root window id. */ - int width, height; /* width and height of screen */ - int mwidth, mheight; /* width and height of in millimeters */ - int ndepths; /* number of depths possible */ - Depth *depths; /* list of allowable depths on the screen */ - int root_depth; /* bits per pixel */ - Visual *root_visual; /* root visual */ - GC default_gc; /* GC for the root root visual */ - Colormap cmap; /* default color map */ +typedef struct +{ + XExtData* ext_data; /* hook for extension to hang data */ + struct _XDisplay* display; /* back pointer to display structure */ + Window root; /* Root window id. */ + int width, height; /* width and height of screen */ + int mwidth, mheight; /* width and height of in millimeters */ + int ndepths; /* number of depths possible */ + Depth* depths; /* list of allowable depths on the screen */ + int root_depth; /* bits per pixel */ + Visual* root_visual; /* root visual */ + GC default_gc; /* GC for the root root visual */ + Colormap cmap; /* default color map */ unsigned long white_pixel; - unsigned long black_pixel; /* White and Black pixel values */ - int max_maps, min_maps; /* max and min color maps */ - int backing_store; /* Never, WhenMapped, Always */ + unsigned long black_pixel; /* White and Black pixel values */ + int max_maps, min_maps; /* max and min color maps */ + int backing_store; /* Never, WhenMapped, Always */ Bool save_unders; - long root_input_mask; /* initial root input mask */ + long root_input_mask; /* initial root input mask */ } Screen; /* * Format structure; describes ZFormat data the screen will understand. */ -typedef struct { - XExtData *ext_data; /* hook for extension to hang data */ - int depth; /* depth of this image format */ - int bits_per_pixel; /* bits/pixel at this depth */ - int scanline_pad; /* scanline must padded to this multiple */ +typedef struct +{ + XExtData* ext_data; /* hook for extension to hang data */ + int depth; /* depth of this image format */ + int bits_per_pixel; /* bits/pixel at this depth */ + int scanline_pad; /* scanline must padded to this multiple */ } ScreenFormat; /* * Data structure for setting window attributes. */ -typedef struct { - Pixmap background_pixmap; /* background or None or ParentRelative */ - unsigned long background_pixel; /* background pixel */ - Pixmap border_pixmap; /* border of the window */ - unsigned long border_pixel; /* border pixel value */ - int bit_gravity; /* one of bit gravity values */ - int win_gravity; /* one of the window gravity values */ - int backing_store; /* NotUseful, WhenMapped, Always */ - unsigned long backing_planes;/* planes to be preseved if possible */ - unsigned long backing_pixel;/* value to use in restoring planes */ - Bool save_under; /* should bits under be saved? (popups) */ - long event_mask; /* set of events that should be saved */ - long do_not_propagate_mask; /* set of events that should not propagate */ - Bool override_redirect; /* boolean value for override-redirect */ - Colormap colormap; /* color map to be associated with window */ - Cursor cursor; /* cursor to be displayed (or None) */ +typedef struct +{ + Pixmap background_pixmap; /* background or None or ParentRelative */ + unsigned long background_pixel; /* background pixel */ + Pixmap border_pixmap; /* border of the window */ + unsigned long border_pixel; /* border pixel value */ + int bit_gravity; /* one of bit gravity values */ + int win_gravity; /* one of the window gravity values */ + int backing_store; /* NotUseful, WhenMapped, Always */ + unsigned long backing_planes; /* planes to be preseved if possible */ + unsigned long backing_pixel; /* value to use in restoring planes */ + Bool save_under; /* should bits under be saved? (popups) */ + long event_mask; /* set of events that should be saved */ + long do_not_propagate_mask; /* set of events that should not propagate */ + Bool override_redirect; /* boolean value for override-redirect */ + Colormap colormap; /* color map to be associated with window */ + Cursor cursor; /* cursor to be displayed (or None) */ } XSetWindowAttributes; -typedef struct { - int x, y; /* location of window */ - int width, height; /* width and height of window */ - int border_width; /* border width of window */ - int depth; /* depth of window */ - Visual *visual; /* the associated visual structure */ - Window root; /* root of screen containing window */ +typedef struct +{ + int x, y; /* location of window */ + int width, height; /* width and height of window */ + int border_width; /* border width of window */ + int depth; /* depth of window */ + Visual* visual; /* the associated visual structure */ + Window root; /* root of screen containing window */ #if defined(__cplusplus) || defined(c_plusplus) - int c_class; /* C++ InputOutput, InputOnly*/ + int c_class; /* C++ InputOutput, InputOnly*/ #else - int class; /* InputOutput, InputOnly*/ + int class; /* InputOutput, InputOnly*/ #endif - int bit_gravity; /* one of bit gravity values */ - int win_gravity; /* one of the window gravity values */ - int backing_store; /* NotUseful, WhenMapped, Always */ - unsigned long backing_planes;/* planes to be preserved if possible */ - unsigned long backing_pixel;/* value to be used when restoring planes */ - Bool save_under; /* boolean, should bits under be saved? */ - Colormap colormap; /* color map to be associated with window */ - Bool map_installed; /* boolean, is color map currently installed*/ - int map_state; /* IsUnmapped, IsUnviewable, IsViewable */ - long all_event_masks; /* set of events all people have interest in*/ - long your_event_mask; /* my event mask */ - long do_not_propagate_mask; /* set of events that should not propagate */ - Bool override_redirect; /* boolean value for override-redirect */ - Screen *screen; /* back pointer to correct screen */ + int bit_gravity; /* one of bit gravity values */ + int win_gravity; /* one of the window gravity values */ + int backing_store; /* NotUseful, WhenMapped, Always */ + unsigned long backing_planes; /* planes to be preserved if possible */ + unsigned long backing_pixel; /* value to be used when restoring planes */ + Bool save_under; /* boolean, should bits under be saved? */ + Colormap colormap; /* color map to be associated with window */ + Bool map_installed; /* boolean, is color map currently installed*/ + int map_state; /* IsUnmapped, IsUnviewable, IsViewable */ + long all_event_masks; /* set of events all people have interest in*/ + long your_event_mask; /* my event mask */ + long do_not_propagate_mask; /* set of events that should not propagate */ + Bool override_redirect; /* boolean value for override-redirect */ + Screen* screen; /* back pointer to correct screen */ } XWindowAttributes; /* @@ -350,79 +357,85 @@ typedef struct { * */ -typedef struct { - int family; /* for example FamilyInternet */ - int length; /* length of address, in bytes */ - char *address; /* pointer to where to find the bytes */ +typedef struct +{ + int family; /* for example FamilyInternet */ + int length; /* length of address, in bytes */ + char* address; /* pointer to where to find the bytes */ } XHostAddress; /* * Data structure for ServerFamilyInterpreted addresses in host routines */ -typedef struct { - int typelength; /* length of type string, in bytes */ - int valuelength; /* length of value string, in bytes */ - char *type; /* pointer to where to find the type string */ - char *value; /* pointer to where to find the address */ +typedef struct +{ + int typelength; /* length of type string, in bytes */ + int valuelength; /* length of value string, in bytes */ + char* type; /* pointer to where to find the type string */ + char* value; /* pointer to where to find the address */ } XServerInterpretedAddress; /* * Data structure for "image" data, used by image manipulation routines. */ -typedef struct _XImage { - int width, height; /* size of image */ - int xoffset; /* number of pixels offset in X direction */ - int format; /* XYBitmap, XYPixmap, ZPixmap */ - char *data; /* pointer to image data */ - int byte_order; /* data byte order, LSBFirst, MSBFirst */ - int bitmap_unit; /* quant. of scanline 8, 16, 32 */ - int bitmap_bit_order; /* LSBFirst, MSBFirst */ - int bitmap_pad; /* 8, 16, 32 either XY or ZPixmap */ - int depth; /* depth of image */ - int bytes_per_line; /* accelarator to next line */ - int bits_per_pixel; /* bits per pixel (ZPixmap) */ - unsigned long red_mask; /* bits in z arrangment */ - unsigned long green_mask; - unsigned long blue_mask; - XPointer obdata; /* hook for the object routines to hang on */ - struct funcs { /* image manipulation routines */ - struct _XImage *(*create_image)( - struct _XDisplay* /* display */, - Visual* /* visual */, - unsigned int /* depth */, - int /* format */, - int /* offset */, - char* /* data */, - unsigned int /* width */, - unsigned int /* height */, - int /* bitmap_pad */, - int /* bytes_per_line */); - int (*destroy_image) (struct _XImage *); - unsigned long (*get_pixel) (struct _XImage *, int, int); - int (*put_pixel) (struct _XImage *, int, int, unsigned long); - struct _XImage *(*sub_image)(struct _XImage *, int, int, unsigned int, unsigned int); - int (*add_pixel) (struct _XImage *, long); +typedef struct _XImage +{ + int width, height; /* size of image */ + int xoffset; /* number of pixels offset in X direction */ + int format; /* XYBitmap, XYPixmap, ZPixmap */ + char* data; /* pointer to image data */ + int byte_order; /* data byte order, LSBFirst, MSBFirst */ + int bitmap_unit; /* quant. of scanline 8, 16, 32 */ + int bitmap_bit_order; /* LSBFirst, MSBFirst */ + int bitmap_pad; /* 8, 16, 32 either XY or ZPixmap */ + int depth; /* depth of image */ + int bytes_per_line; /* accelarator to next line */ + int bits_per_pixel; /* bits per pixel (ZPixmap) */ + unsigned long red_mask; /* bits in z arrangment */ + unsigned long green_mask; + unsigned long blue_mask; + XPointer obdata; /* hook for the object routines to hang on */ + struct funcs + { /* image manipulation routines */ + struct _XImage* (*create_image)( + struct _XDisplay* /* display */, + Visual* /* visual */, + unsigned int /* depth */, + int /* format */, + int /* offset */, + char* /* data */, + unsigned int /* width */, + unsigned int /* height */, + int /* bitmap_pad */, + int /* bytes_per_line */); + int (*destroy_image)(struct _XImage*); + unsigned long (*get_pixel)(struct _XImage*, int, int); + int (*put_pixel)(struct _XImage*, int, int, unsigned long); + struct _XImage* (*sub_image)(struct _XImage*, int, int, unsigned int, unsigned int); + int (*add_pixel)(struct _XImage*, long); } f; } XImage; /* * Data structure for XReconfigureWindow */ -typedef struct { - int x, y; - int width, height; - int border_width; - Window sibling; - int stack_mode; +typedef struct +{ + int x, y; + int width, height; + int border_width; + Window sibling; + int stack_mode; } XWindowChanges; /* * Data structure used by color operations */ -typedef struct { +typedef struct +{ unsigned long pixel; unsigned short red, green, blue; - char flags; /* do_red, do_green, do_blue */ + char flags; /* do_red, do_green, do_blue */ char pad; } XColor; @@ -431,43 +444,48 @@ typedef struct { * congruent with the wire protocol structures, so reformatting the data * can be avoided on these architectures. */ -typedef struct { - short x1, y1, x2, y2; +typedef struct +{ + short x1, y1, x2, y2; } XSegment; -typedef struct { - short x, y; +typedef struct +{ + short x, y; } XPoint; -typedef struct { - short x, y; - unsigned short width, height; +typedef struct +{ + short x, y; + unsigned short width, height; } XRectangle; -typedef struct { - short x, y; - unsigned short width, height; - short angle1, angle2; +typedef struct +{ + short x, y; + unsigned short width, height; + short angle1, angle2; } XArc; - /* Data structure for XChangeKeyboardControl */ -typedef struct { - int key_click_percent; - int bell_percent; - int bell_pitch; - int bell_duration; - int led; - int led_mode; - int key; - int auto_repeat_mode; /* On, Off, Default */ +typedef struct +{ + int key_click_percent; + int bell_percent; + int bell_pitch; + int bell_duration; + int led; + int led_mode; + int key; + int auto_repeat_mode; /* On, Off, Default */ } XKeyboardControl; /* Data structure for XGetKeyboardControl */ -typedef struct { - int key_click_percent; +typedef struct +{ + int key_click_percent; int bell_percent; unsigned int bell_pitch, bell_duration; unsigned long led_mask; @@ -477,19 +495,20 @@ typedef struct { /* Data structure for XGetMotionEvents. */ -typedef struct { - Time time; +typedef struct +{ + Time time; short x, y; } XTimeCoord; /* Data structure for X{Set,Get}ModifierMapping */ -typedef struct { - int max_keypermod; /* The server's max # of keys per modifier */ - KeyCode *modifiermap; /* An 8 by max_keypermod array of modifiers */ +typedef struct +{ + int max_keypermod; /* The server's max # of keys per modifier */ + KeyCode* modifiermap; /* An 8 by max_keypermod array of modifiers */ } XModifierKeymap; - /* * Display datatype maintaining display specific data. * The contents of this structure are implementation dependent. @@ -499,157 +518,161 @@ typedef struct { typedef struct _XDisplay Display; #endif -struct _XPrivate; /* Forward declare before use for C++ */ +struct _XPrivate; /* Forward declare before use for C++ */ struct _XrmHashBucketRec; typedef struct #ifdef XLIB_ILLEGAL_ACCESS -_XDisplay + _XDisplay #endif { - XExtData *ext_data; /* hook for extension to hang data */ - struct _XPrivate *private1; - int fd; /* Network socket. */ + XExtData* ext_data; /* hook for extension to hang data */ + struct _XPrivate* private1; + int fd; /* Network socket. */ int private2; - int proto_major_version;/* major version of server's X protocol */ - int proto_minor_version;/* minor version of servers X protocol */ - char *vendor; /* vendor of the server hardware */ - XID private3; + int proto_major_version; /* major version of server's X protocol */ + int proto_minor_version; /* minor version of servers X protocol */ + char* vendor; /* vendor of the server hardware */ + XID private3; XID private4; XID private5; int private6; - XID (*resource_alloc)( /* allocator function */ - struct _XDisplay* - ); - int byte_order; /* screen byte order, LSBFirst, MSBFirst */ - int bitmap_unit; /* padding and data requirements */ - int bitmap_pad; /* padding requirements on bitmaps */ - int bitmap_bit_order; /* LeastSignificant or MostSignificant */ - int nformats; /* number of pixmap formats in list */ - ScreenFormat *pixmap_format; /* pixmap format list */ + XID(*resource_alloc) + (/* allocator function */ + struct _XDisplay*); + int byte_order; /* screen byte order, LSBFirst, MSBFirst */ + int bitmap_unit; /* padding and data requirements */ + int bitmap_pad; /* padding requirements on bitmaps */ + int bitmap_bit_order; /* LeastSignificant or MostSignificant */ + int nformats; /* number of pixmap formats in list */ + ScreenFormat* pixmap_format; /* pixmap format list */ int private8; - int release; /* release of the server */ + int release; /* release of the server */ struct _XPrivate *private9, *private10; - int qlen; /* Length of input event queue */ + int qlen; /* Length of input event queue */ unsigned long last_request_read; /* seq number of last event read */ - unsigned long request; /* sequence number of last request. */ + unsigned long request; /* sequence number of last request. */ XPointer private11; XPointer private12; XPointer private13; XPointer private14; unsigned max_request_size; /* maximum number 32 bit words in request*/ - struct _XrmHashBucketRec *db; + struct _XrmHashBucketRec* db; int (*private15)( - struct _XDisplay* - ); - char *display_name; /* "host:display" string used on this connect*/ - int default_screen; /* default screen for operations */ - int nscreens; /* number of screens on this server*/ - Screen *screens; /* pointer to list of screens */ - unsigned long motion_buffer; /* size of motion buffer */ + struct _XDisplay*); + char* display_name; /* "host:display" string used on this connect*/ + int default_screen; /* default screen for operations */ + int nscreens; /* number of screens on this server*/ + Screen* screens; /* pointer to list of screens */ + unsigned long motion_buffer; /* size of motion buffer */ unsigned long private16; - int min_keycode; /* minimum defined keycode */ - int max_keycode; /* maximum defined keycode */ + int min_keycode; /* minimum defined keycode */ + int max_keycode; /* maximum defined keycode */ XPointer private17; XPointer private18; int private19; - char *xdefaults; /* contents of defaults from server */ - /* there is more to this structure, but it is private to Xlib */ + char* xdefaults; /* contents of defaults from server */ + /* there is more to this structure, but it is private to Xlib */ } #ifdef XLIB_ILLEGAL_ACCESS Display, #endif -*_XPrivDisplay; + *_XPrivDisplay; #undef _XEVENT_ #ifndef _XEVENT_ /* * Definitions of specific events. */ -typedef struct { - int type; /* of event */ - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; /* "event" window it is reported relative to */ - Window root; /* root window that the event occurred on */ - Window subwindow; /* child window */ - Time time; /* milliseconds */ - int x, y; /* pointer x, y coordinates in event window */ - int x_root, y_root; /* coordinates relative to root */ - unsigned int state; /* key or button mask */ - unsigned int keycode; /* detail */ - Bool same_screen; /* same screen flag */ +typedef struct +{ + int type; /* of event */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ + Window window; /* "event" window it is reported relative to */ + Window root; /* root window that the event occurred on */ + Window subwindow; /* child window */ + Time time; /* milliseconds */ + int x, y; /* pointer x, y coordinates in event window */ + int x_root, y_root; /* coordinates relative to root */ + unsigned int state; /* key or button mask */ + unsigned int keycode; /* detail */ + Bool same_screen; /* same screen flag */ } XKeyEvent; typedef XKeyEvent XKeyPressedEvent; typedef XKeyEvent XKeyReleasedEvent; -typedef struct { - int type; /* of event */ - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; /* "event" window it is reported relative to */ - Window root; /* root window that the event occurred on */ - Window subwindow; /* child window */ - Time time; /* milliseconds */ - int x, y; /* pointer x, y coordinates in event window */ - int x_root, y_root; /* coordinates relative to root */ - unsigned int state; /* key or button mask */ - unsigned int button; /* detail */ - Bool same_screen; /* same screen flag */ +typedef struct +{ + int type; /* of event */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ + Window window; /* "event" window it is reported relative to */ + Window root; /* root window that the event occurred on */ + Window subwindow; /* child window */ + Time time; /* milliseconds */ + int x, y; /* pointer x, y coordinates in event window */ + int x_root, y_root; /* coordinates relative to root */ + unsigned int state; /* key or button mask */ + unsigned int button; /* detail */ + Bool same_screen; /* same screen flag */ } XButtonEvent; typedef XButtonEvent XButtonPressedEvent; typedef XButtonEvent XButtonReleasedEvent; -typedef struct { - int type; /* of event */ - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; /* "event" window reported relative to */ - Window root; /* root window that the event occurred on */ - Window subwindow; /* child window */ - Time time; /* milliseconds */ - int x, y; /* pointer x, y coordinates in event window */ - int x_root, y_root; /* coordinates relative to root */ - unsigned int state; /* key or button mask */ - char is_hint; /* detail */ - Bool same_screen; /* same screen flag */ +typedef struct +{ + int type; /* of event */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ + Window window; /* "event" window reported relative to */ + Window root; /* root window that the event occurred on */ + Window subwindow; /* child window */ + Time time; /* milliseconds */ + int x, y; /* pointer x, y coordinates in event window */ + int x_root, y_root; /* coordinates relative to root */ + unsigned int state; /* key or button mask */ + char is_hint; /* detail */ + Bool same_screen; /* same screen flag */ } XMotionEvent; typedef XMotionEvent XPointerMovedEvent; -typedef struct { - int type; /* of event */ - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; /* "event" window reported relative to */ - Window root; /* root window that the event occurred on */ - Window subwindow; /* child window */ - Time time; /* milliseconds */ - int x, y; /* pointer x, y coordinates in event window */ - int x_root, y_root; /* coordinates relative to root */ - int mode; /* NotifyNormal, NotifyGrab, NotifyUngrab */ +typedef struct +{ + int type; /* of event */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ + Window window; /* "event" window reported relative to */ + Window root; /* root window that the event occurred on */ + Window subwindow; /* child window */ + Time time; /* milliseconds */ + int x, y; /* pointer x, y coordinates in event window */ + int x_root, y_root; /* coordinates relative to root */ + int mode; /* NotifyNormal, NotifyGrab, NotifyUngrab */ int detail; /* * NotifyAncestor, NotifyVirtual, NotifyInferior, * NotifyNonlinear,NotifyNonlinearVirtual */ - Bool same_screen; /* same screen flag */ - Bool focus; /* boolean focus */ - unsigned int state; /* key or button mask */ + Bool same_screen; /* same screen flag */ + Bool focus; /* boolean focus */ + unsigned int state; /* key or button mask */ } XCrossingEvent; typedef XCrossingEvent XEnterWindowEvent; typedef XCrossingEvent XLeaveWindowEvent; -typedef struct { - int type; /* FocusIn or FocusOut */ - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; /* window of event */ - int mode; /* NotifyNormal, NotifyWhileGrabbed, +typedef struct +{ + int type; /* FocusIn or FocusOut */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ + Window window; /* window of event */ + int mode; /* NotifyNormal, NotifyWhileGrabbed, NotifyGrab, NotifyUngrab */ int detail; /* @@ -662,114 +685,125 @@ typedef XFocusChangeEvent XFocusInEvent; typedef XFocusChangeEvent XFocusOutEvent; /* generated on EnterWindow and FocusIn when KeyMapState selected */ -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Window window; char key_vector[32]; } XKeymapEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Window window; int x, y; int width, height; - int count; /* if non-zero, at least this many more */ + int count; /* if non-zero, at least this many more */ } XExposeEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Drawable drawable; int x, y; int width, height; - int count; /* if non-zero, at least this many more */ - int major_code; /* core is CopyArea or CopyPlane */ - int minor_code; /* not defined in the core */ + int count; /* if non-zero, at least this many more */ + int major_code; /* core is CopyArea or CopyPlane */ + int minor_code; /* not defined in the core */ } XGraphicsExposeEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Drawable drawable; - int major_code; /* core is CopyArea or CopyPlane */ - int minor_code; /* not defined in the core */ + int major_code; /* core is CopyArea or CopyPlane */ + int minor_code; /* not defined in the core */ } XNoExposeEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Window window; - int state; /* Visibility state */ + int state; /* Visibility state */ } XVisibilityEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window parent; /* parent of the window */ - Window window; /* window id of window created */ - int x, y; /* window location */ - int width, height; /* size of window */ - int border_width; /* border width */ - Bool override_redirect; /* creation should be overridden */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ + Window parent; /* parent of the window */ + Window window; /* window id of window created */ + int x, y; /* window location */ + int width, height; /* size of window */ + int border_width; /* border width */ + Bool override_redirect; /* creation should be overridden */ } XCreateWindowEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Window event; Window window; } XDestroyWindowEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Window event; Window window; Bool from_configure; } XUnmapEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Window event; Window window; - Bool override_redirect; /* boolean, is override set... */ + Bool override_redirect; /* boolean, is override set... */ } XMapEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Window parent; Window window; } XMapRequestEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Window event; Window window; Window parent; @@ -777,11 +811,12 @@ typedef struct { Bool override_redirect; } XReparentEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Window event; Window window; int x, y; @@ -791,86 +826,94 @@ typedef struct { Bool override_redirect; } XConfigureEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Window event; Window window; int x, y; } XGravityEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Window window; int width, height; } XResizeRequestEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Window parent; Window window; int x, y; int width, height; int border_width; Window above; - int detail; /* Above, Below, TopIf, BottomIf, Opposite */ + int detail; /* Above, Below, TopIf, BottomIf, Opposite */ unsigned long value_mask; } XConfigureRequestEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Window event; Window window; - int place; /* PlaceOnTop, PlaceOnBottom */ + int place; /* PlaceOnTop, PlaceOnBottom */ } XCirculateEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Window parent; Window window; - int place; /* PlaceOnTop, PlaceOnBottom */ + int place; /* PlaceOnTop, PlaceOnBottom */ } XCirculateRequestEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Window window; Atom atom; Time time; - int state; /* NewValue, Deleted */ + int state; /* NewValue, Deleted */ } XPropertyEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Window window; Atom selection; Time time; } XSelectionClearEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Window owner; Window requestor; Atom selection; @@ -879,38 +922,41 @@ typedef struct { Time time; } XSelectionRequestEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Window requestor; Atom selection; Atom target; - Atom property; /* ATOM or None */ + Atom property; /* ATOM or None */ Time time; } XSelectionEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Window window; - Colormap colormap; /* COLORMAP or None */ + Colormap colormap; /* COLORMAP or None */ #if defined(__cplusplus) || defined(c_plusplus) - Bool c_new; /* C++ */ + Bool c_new; /* C++ */ #else Bool new; #endif - int state; /* ColormapInstalled, ColormapUninstalled */ + int state; /* ColormapInstalled, ColormapUninstalled */ } XColormapEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ Window window; Atom message_type; int format; @@ -918,64 +964,67 @@ typedef struct { char b[20]; short s[10]; long l[5]; - } data; + } data; } XClientMessageEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; /* unused */ - int request; /* one of MappingModifier, MappingKeyboard, + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ + Window window; /* unused */ + int request; /* one of MappingModifier, MappingKeyboard, MappingPointer */ - int first_keycode; /* first keycode */ - int count; /* defines range of change w. first_keycode*/ + int first_keycode; /* first keycode */ + int count; /* defines range of change w. first_keycode*/ } XMappingEvent; -typedef struct { +typedef struct +{ int type; - Display *display; /* Display the event was read from */ - XID resourceid; /* resource id */ - unsigned long serial; /* serial number of failed request */ - unsigned char error_code; /* error code of failed request */ - unsigned char request_code; /* Major op-code of failed request */ - unsigned char minor_code; /* Minor op-code of failed request */ + Display* display; /* Display the event was read from */ + XID resourceid; /* resource id */ + unsigned long serial; /* serial number of failed request */ + unsigned char error_code; /* error code of failed request */ + unsigned char request_code; /* Major op-code of failed request */ + unsigned char minor_code; /* Minor op-code of failed request */ } XErrorEvent; -typedef struct { +typedef struct +{ int type; - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came from a SendEvent request */ - Display *display;/* Display the event was read from */ - Window window; /* window on which event was requested in event mask */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display* display; /* Display the event was read from */ + Window window; /* window on which event was requested in event mask */ } XAnyEvent; - /*************************************************************** * * GenericEvent. This event is the standard event for all newer extensions. */ typedef struct - { - int type; /* of event. Always GenericEvent */ - unsigned long serial; /* # of last request processed */ - Bool send_event; /* true if from SendEvent request */ - Display *display; /* Display the event was read from */ - int extension; /* major opcode of extension that caused the event */ - int evtype; /* actual event type. */ - } XGenericEvent; +{ + int type; /* of event. Always GenericEvent */ + unsigned long serial; /* # of last request processed */ + Bool send_event; /* true if from SendEvent request */ + Display* display; /* Display the event was read from */ + int extension; /* major opcode of extension that caused the event */ + int evtype; /* actual event type. */ +} XGenericEvent; -typedef struct { - int type; /* of event. Always GenericEvent */ - unsigned long serial; /* # of last request processed */ - Bool send_event; /* true if from SendEvent request */ - Display *display; /* Display the event was read from */ - int extension; /* major opcode of extension that caused the event */ - int evtype; /* actual event type. */ - unsigned int cookie; - void *data; +typedef struct +{ + int type; /* of event. Always GenericEvent */ + unsigned long serial; /* # of last request processed */ + Bool send_event; /* true if from SendEvent request */ + Display* display; /* Display the event was read from */ + int extension; /* major opcode of extension that caused the event */ + int evtype; /* actual event type. */ + unsigned int cookie; + void* data; } XGenericEventCookie; /* @@ -983,7 +1032,7 @@ typedef struct { * event structure internally, to avoid memory fragmentation. */ typedef union _XEvent { - int type; /* must not be changed; first element */ + int type; /* must not be changed; first element */ XAnyEvent xany; XKeyEvent xkey; XButtonEvent xbutton; @@ -1026,97 +1075,107 @@ typedef union _XEvent { /* * per character font metric information. */ -typedef struct { - short lbearing; /* origin to left edge of raster */ - short rbearing; /* origin to right edge of raster */ - short width; /* advance to next char's origin */ - short ascent; /* baseline to top edge of raster */ - short descent; /* baseline to bottom edge of raster */ - unsigned short attributes; /* per char flags (not predefined) */ +typedef struct +{ + short lbearing; /* origin to left edge of raster */ + short rbearing; /* origin to right edge of raster */ + short width; /* advance to next char's origin */ + short ascent; /* baseline to top edge of raster */ + short descent; /* baseline to bottom edge of raster */ + unsigned short attributes; /* per char flags (not predefined) */ } XCharStruct; /* * To allow arbitrary information with fonts, there are additional properties * returned. */ -typedef struct { - Atom name; - unsigned long card32; +typedef struct +{ + Atom name; + unsigned long card32; } XFontProp; -typedef struct { - XExtData *ext_data; /* hook for extension to hang data */ - Font fid; /* Font id for this font */ - unsigned direction; /* hint about direction the font is painted */ - unsigned min_char_or_byte2;/* first character */ - unsigned max_char_or_byte2;/* last character */ - unsigned min_byte1; /* first row that exists */ - unsigned max_byte1; /* last row that exists */ - Bool all_chars_exist;/* flag if all characters have non-zero size*/ - unsigned default_char; /* char to print for undefined character */ - int n_properties; /* how many properties there are */ - XFontProp *properties; /* pointer to array of additional properties*/ - XCharStruct min_bounds; /* minimum bounds over all existing char*/ - XCharStruct max_bounds; /* maximum bounds over all existing char*/ - XCharStruct *per_char; /* first_char to last_char information */ - int ascent; /* log. extent above baseline for spacing */ - int descent; /* log. descent below baseline for spacing */ +typedef struct +{ + XExtData* ext_data; /* hook for extension to hang data */ + Font fid; /* Font id for this font */ + unsigned direction; /* hint about direction the font is painted */ + unsigned min_char_or_byte2; /* first character */ + unsigned max_char_or_byte2; /* last character */ + unsigned min_byte1; /* first row that exists */ + unsigned max_byte1; /* last row that exists */ + Bool all_chars_exist; /* flag if all characters have non-zero size*/ + unsigned default_char; /* char to print for undefined character */ + int n_properties; /* how many properties there are */ + XFontProp* properties; /* pointer to array of additional properties*/ + XCharStruct min_bounds; /* minimum bounds over all existing char*/ + XCharStruct max_bounds; /* maximum bounds over all existing char*/ + XCharStruct* per_char; /* first_char to last_char information */ + int ascent; /* log. extent above baseline for spacing */ + int descent; /* log. descent below baseline for spacing */ } XFontStruct; /* * PolyText routines take these as arguments. */ -typedef struct { - char *chars; /* pointer to string */ - int nchars; /* number of characters */ - int delta; /* delta between strings */ - Font font; /* font to print it in, None don't change */ +typedef struct +{ + char* chars; /* pointer to string */ + int nchars; /* number of characters */ + int delta; /* delta between strings */ + Font font; /* font to print it in, None don't change */ } XTextItem; -typedef struct { /* normal 16 bit characters are two bytes */ - unsigned char byte1; - unsigned char byte2; +typedef struct +{ /* normal 16 bit characters are two bytes */ + unsigned char byte1; + unsigned char byte2; } XChar2b; -typedef struct { - XChar2b *chars; /* two byte characters */ - int nchars; /* number of characters */ - int delta; /* delta between strings */ - Font font; /* font to print it in, None don't change */ +typedef struct +{ + XChar2b* chars; /* two byte characters */ + int nchars; /* number of characters */ + int delta; /* delta between strings */ + Font font; /* font to print it in, None don't change */ } XTextItem16; +typedef union { + Display* display; + GC gc; + Visual* visual; + Screen* screen; + ScreenFormat* pixmap_format; + XFontStruct* font; +} XEDataObject; -typedef union { Display *display; - GC gc; - Visual *visual; - Screen *screen; - ScreenFormat *pixmap_format; - XFontStruct *font; } XEDataObject; - -typedef struct { - XRectangle max_ink_extent; - XRectangle max_logical_extent; +typedef struct +{ + XRectangle max_ink_extent; + XRectangle max_logical_extent; } XFontSetExtents; /* unused: typedef void (*XOMProc)(); */ -typedef struct _XOM *XOM; +typedef struct _XOM* XOM; typedef struct _XOC *XOC, *XFontSet; -typedef struct { - char *chars; - int nchars; - int delta; - XFontSet font_set; +typedef struct +{ + char* chars; + int nchars; + int delta; + XFontSet font_set; } XmbTextItem; -typedef struct { - wchar_t *chars; - int nchars; - int delta; - XFontSet font_set; +typedef struct +{ + wchar_t* chars; + int nchars; + int delta; + XFontSet font_set; } XwcTextItem; #define XNRequiredCharSet "requiredCharSet" @@ -1130,67 +1189,69 @@ typedef struct { #define XNContextualDrawing "contextualDrawing" #define XNFontInfo "fontInfo" -typedef struct { - int charset_count; - char **charset_list; +typedef struct +{ + int charset_count; + char** charset_list; } XOMCharSetList; -typedef enum { - XOMOrientation_LTR_TTB, - XOMOrientation_RTL_TTB, - XOMOrientation_TTB_LTR, - XOMOrientation_TTB_RTL, - XOMOrientation_Context +typedef enum +{ + XOMOrientation_LTR_TTB, + XOMOrientation_RTL_TTB, + XOMOrientation_TTB_LTR, + XOMOrientation_TTB_RTL, + XOMOrientation_Context } XOrientation; -typedef struct { - int num_orientation; - XOrientation *orientation; /* Input Text description */ +typedef struct +{ + int num_orientation; + XOrientation* orientation; /* Input Text description */ } XOMOrientation; -typedef struct { - int num_font; - XFontStruct **font_struct_list; - char **font_name_list; +typedef struct +{ + int num_font; + XFontStruct** font_struct_list; + char** font_name_list; } XOMFontInfo; -typedef struct _XIM *XIM; -typedef struct _XIC *XIC; +typedef struct _XIM* XIM; +typedef struct _XIC* XIC; typedef void (*XIMProc)( - XIM, - XPointer, - XPointer -); + XIM, + XPointer, + XPointer); typedef Bool (*XICProc)( - XIC, - XPointer, - XPointer -); + XIC, + XPointer, + XPointer); typedef void (*XIDProc)( - Display*, - XPointer, - XPointer -); + Display*, + XPointer, + XPointer); typedef unsigned long XIMStyle; -typedef struct { - unsigned short count_styles; - XIMStyle *supported_styles; +typedef struct +{ + unsigned short count_styles; + XIMStyle* supported_styles; } XIMStyles; -#define XIMPreeditArea 0x0001L -#define XIMPreeditCallbacks 0x0002L -#define XIMPreeditPosition 0x0004L -#define XIMPreeditNothing 0x0008L -#define XIMPreeditNone 0x0010L -#define XIMStatusArea 0x0100L -#define XIMStatusCallbacks 0x0200L -#define XIMStatusNothing 0x0400L -#define XIMStatusNone 0x0800L +#define XIMPreeditArea 0x0001L +#define XIMPreeditCallbacks 0x0002L +#define XIMPreeditPosition 0x0004L +#define XIMPreeditNothing 0x0008L +#define XIMPreeditNone 0x0010L +#define XIMStatusArea 0x0100L +#define XIMStatusCallbacks 0x0200L +#define XIMStatusNothing 0x0400L +#define XIMStatusNone 0x0800L #define XNVaNestedList "XNVaNestedList" #define XNQueryInputStyle "queryInputStyle" @@ -1236,163 +1297,183 @@ typedef struct { #define XNPreeditState "preeditState" #define XNSeparatorofNestedList "separatorofNestedList" -#define XBufferOverflow -1 -#define XLookupNone 1 -#define XLookupChars 2 -#define XLookupKeySym 3 -#define XLookupBoth 4 +#define XBufferOverflow -1 +#define XLookupNone 1 +#define XLookupChars 2 +#define XLookupKeySym 3 +#define XLookupBoth 4 -typedef void *XVaNestedList; +typedef void* XVaNestedList; -typedef struct { - XPointer client_data; - XIMProc callback; +typedef struct +{ + XPointer client_data; + XIMProc callback; } XIMCallback; -typedef struct { - XPointer client_data; - XICProc callback; +typedef struct +{ + XPointer client_data; + XICProc callback; } XICCallback; typedef unsigned long XIMFeedback; -#define XIMReverse 1L -#define XIMUnderline (1L<<1) -#define XIMHighlight (1L<<2) -#define XIMPrimary (1L<<5) -#define XIMSecondary (1L<<6) -#define XIMTertiary (1L<<7) -#define XIMVisibleToForward (1L<<8) -#define XIMVisibleToBackword (1L<<9) -#define XIMVisibleToCenter (1L<<10) +#define XIMReverse 1L +#define XIMUnderline (1L << 1) +#define XIMHighlight (1L << 2) +#define XIMPrimary (1L << 5) +#define XIMSecondary (1L << 6) +#define XIMTertiary (1L << 7) +#define XIMVisibleToForward (1L << 8) +#define XIMVisibleToBackword (1L << 9) +#define XIMVisibleToCenter (1L << 10) -typedef struct _XIMText { - unsigned short length; - XIMFeedback *feedback; - Bool encoding_is_wchar; - union { - char *multi_byte; - wchar_t *wide_char; - } string; +typedef struct _XIMText +{ + unsigned short length; + XIMFeedback* feedback; + Bool encoding_is_wchar; + union { + char* multi_byte; + wchar_t* wide_char; + } string; } XIMText; -typedef unsigned long XIMPreeditState; +typedef unsigned long XIMPreeditState; -#define XIMPreeditUnKnown 0L -#define XIMPreeditEnable 1L -#define XIMPreeditDisable (1L<<1) +#define XIMPreeditUnKnown 0L +#define XIMPreeditEnable 1L +#define XIMPreeditDisable (1L << 1) -typedef struct _XIMPreeditStateNotifyCallbackStruct { - XIMPreeditState state; +typedef struct _XIMPreeditStateNotifyCallbackStruct +{ + XIMPreeditState state; } XIMPreeditStateNotifyCallbackStruct; -typedef unsigned long XIMResetState; +typedef unsigned long XIMResetState; -#define XIMInitialState 1L -#define XIMPreserveState (1L<<1) +#define XIMInitialState 1L +#define XIMPreserveState (1L << 1) typedef unsigned long XIMStringConversionFeedback; -#define XIMStringConversionLeftEdge (0x00000001) -#define XIMStringConversionRightEdge (0x00000002) -#define XIMStringConversionTopEdge (0x00000004) -#define XIMStringConversionBottomEdge (0x00000008) -#define XIMStringConversionConcealed (0x00000010) -#define XIMStringConversionWrapped (0x00000020) +#define XIMStringConversionLeftEdge (0x00000001) +#define XIMStringConversionRightEdge (0x00000002) +#define XIMStringConversionTopEdge (0x00000004) +#define XIMStringConversionBottomEdge (0x00000008) +#define XIMStringConversionConcealed (0x00000010) +#define XIMStringConversionWrapped (0x00000020) -typedef struct _XIMStringConversionText { - unsigned short length; - XIMStringConversionFeedback *feedback; - Bool encoding_is_wchar; - union { - char *mbs; - wchar_t *wcs; - } string; +typedef struct _XIMStringConversionText +{ + unsigned short length; + XIMStringConversionFeedback* feedback; + Bool encoding_is_wchar; + union { + char* mbs; + wchar_t* wcs; + } string; } XIMStringConversionText; -typedef unsigned short XIMStringConversionPosition; +typedef unsigned short XIMStringConversionPosition; -typedef unsigned short XIMStringConversionType; +typedef unsigned short XIMStringConversionType; -#define XIMStringConversionBuffer (0x0001) -#define XIMStringConversionLine (0x0002) -#define XIMStringConversionWord (0x0003) -#define XIMStringConversionChar (0x0004) +#define XIMStringConversionBuffer (0x0001) +#define XIMStringConversionLine (0x0002) +#define XIMStringConversionWord (0x0003) +#define XIMStringConversionChar (0x0004) -typedef unsigned short XIMStringConversionOperation; +typedef unsigned short XIMStringConversionOperation; -#define XIMStringConversionSubstitution (0x0001) -#define XIMStringConversionRetrieval (0x0002) +#define XIMStringConversionSubstitution (0x0001) +#define XIMStringConversionRetrieval (0x0002) -typedef enum { - XIMForwardChar, XIMBackwardChar, - XIMForwardWord, XIMBackwardWord, - XIMCaretUp, XIMCaretDown, - XIMNextLine, XIMPreviousLine, - XIMLineStart, XIMLineEnd, - XIMAbsolutePosition, - XIMDontChange +typedef enum +{ + XIMForwardChar, + XIMBackwardChar, + XIMForwardWord, + XIMBackwardWord, + XIMCaretUp, + XIMCaretDown, + XIMNextLine, + XIMPreviousLine, + XIMLineStart, + XIMLineEnd, + XIMAbsolutePosition, + XIMDontChange } XIMCaretDirection; -typedef struct _XIMStringConversionCallbackStruct { - XIMStringConversionPosition position; - XIMCaretDirection direction; - XIMStringConversionOperation operation; - unsigned short factor; - XIMStringConversionText *text; +typedef struct _XIMStringConversionCallbackStruct +{ + XIMStringConversionPosition position; + XIMCaretDirection direction; + XIMStringConversionOperation operation; + unsigned short factor; + XIMStringConversionText* text; } XIMStringConversionCallbackStruct; -typedef struct _XIMPreeditDrawCallbackStruct { - int caret; /* Cursor offset within pre-edit string */ - int chg_first; /* Starting change position */ - int chg_length; /* Length of the change in character count */ - XIMText *text; +typedef struct _XIMPreeditDrawCallbackStruct +{ + int caret; /* Cursor offset within pre-edit string */ + int chg_first; /* Starting change position */ + int chg_length; /* Length of the change in character count */ + XIMText* text; } XIMPreeditDrawCallbackStruct; -typedef enum { - XIMIsInvisible, /* Disable caret feedback */ - XIMIsPrimary, /* UI defined caret feedback */ - XIMIsSecondary /* UI defined caret feedback */ +typedef enum +{ + XIMIsInvisible, /* Disable caret feedback */ + XIMIsPrimary, /* UI defined caret feedback */ + XIMIsSecondary /* UI defined caret feedback */ } XIMCaretStyle; -typedef struct _XIMPreeditCaretCallbackStruct { - int position; /* Caret offset within pre-edit string */ - XIMCaretDirection direction; /* Caret moves direction */ - XIMCaretStyle style; /* Feedback of the caret */ +typedef struct _XIMPreeditCaretCallbackStruct +{ + int position; /* Caret offset within pre-edit string */ + XIMCaretDirection direction; /* Caret moves direction */ + XIMCaretStyle style; /* Feedback of the caret */ } XIMPreeditCaretCallbackStruct; -typedef enum { - XIMTextType, - XIMBitmapType +typedef enum +{ + XIMTextType, + XIMBitmapType } XIMStatusDataType; -typedef struct _XIMStatusDrawCallbackStruct { - XIMStatusDataType type; - union { - XIMText *text; - Pixmap bitmap; - } data; +typedef struct _XIMStatusDrawCallbackStruct +{ + XIMStatusDataType type; + union { + XIMText* text; + Pixmap bitmap; + } data; } XIMStatusDrawCallbackStruct; -typedef struct _XIMHotKeyTrigger { - KeySym keysym; - int modifier; - int modifier_mask; +typedef struct _XIMHotKeyTrigger +{ + KeySym keysym; + int modifier; + int modifier_mask; } XIMHotKeyTrigger; -typedef struct _XIMHotKeyTriggers { - int num_hot_key; - XIMHotKeyTrigger *key; +typedef struct _XIMHotKeyTriggers +{ + int num_hot_key; + XIMHotKeyTrigger* key; } XIMHotKeyTriggers; -typedef unsigned long XIMHotKeyState; +typedef unsigned long XIMHotKeyState; -#define XIMHotKeyStateON (0x0001L) -#define XIMHotKeyStateOFF (0x0002L) +#define XIMHotKeyStateON (0x0001L) +#define XIMHotKeyStateOFF (0x0002L) -typedef struct { - unsigned short count_values; - char **supported_values; +typedef struct +{ + unsigned short count_values; + char** supported_values; } XIMValuesList; _XFUNCPROTOBEGIN @@ -1403,2624 +1484,2604 @@ _XFUNCPROTOBEGIN extern int _Xdebug; -extern XFontStruct *XLoadQueryFont( - Display* /* display */, - _Xconst char* /* name */ +extern XFontStruct* XLoadQueryFont( + Display* /* display */, + _Xconst char* /* name */ ); -extern XFontStruct *XQueryFont( - Display* /* display */, - XID /* font_ID */ +extern XFontStruct* XQueryFont( + Display* /* display */, + XID /* font_ID */ ); - -extern XTimeCoord *XGetMotionEvents( - Display* /* display */, - Window /* w */, - Time /* start */, - Time /* stop */, - int* /* nevents_return */ +extern XTimeCoord* XGetMotionEvents( + Display* /* display */, + Window /* w */, + Time /* start */, + Time /* stop */, + int* /* nevents_return */ ); -extern XModifierKeymap *XDeleteModifiermapEntry( - XModifierKeymap* /* modmap */, +extern XModifierKeymap* XDeleteModifiermapEntry( + XModifierKeymap* /* modmap */, #if NeedWidePrototypes - unsigned int /* keycode_entry */, + unsigned int /* keycode_entry */, #else - KeyCode /* keycode_entry */, + KeyCode /* keycode_entry */, #endif - int /* modifier */ + int /* modifier */ ); -extern XModifierKeymap *XGetModifierMapping( - Display* /* display */ +extern XModifierKeymap* XGetModifierMapping( + Display* /* display */ ); -extern XModifierKeymap *XInsertModifiermapEntry( - XModifierKeymap* /* modmap */, +extern XModifierKeymap* XInsertModifiermapEntry( + XModifierKeymap* /* modmap */, #if NeedWidePrototypes - unsigned int /* keycode_entry */, + unsigned int /* keycode_entry */, #else - KeyCode /* keycode_entry */, + KeyCode /* keycode_entry */, #endif - int /* modifier */ + int /* modifier */ ); -extern XModifierKeymap *XNewModifiermap( - int /* max_keys_per_mod */ +extern XModifierKeymap* XNewModifiermap( + int /* max_keys_per_mod */ ); -extern XImage *XCreateImage( - Display* /* display */, - Visual* /* visual */, - unsigned int /* depth */, - int /* format */, - int /* offset */, - char* /* data */, - unsigned int /* width */, - unsigned int /* height */, - int /* bitmap_pad */, - int /* bytes_per_line */ +extern XImage* XCreateImage( + Display* /* display */, + Visual* /* visual */, + unsigned int /* depth */, + int /* format */, + int /* offset */, + char* /* data */, + unsigned int /* width */, + unsigned int /* height */, + int /* bitmap_pad */, + int /* bytes_per_line */ ); extern Status XInitImage( - XImage* /* image */ + XImage* /* image */ ); -extern XImage *XGetImage( - Display* /* display */, - Drawable /* d */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */, - unsigned long /* plane_mask */, - int /* format */ +extern XImage* XGetImage( + Display* /* display */, + Drawable /* d */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */, + unsigned long /* plane_mask */, + int /* format */ ); -extern XImage *XGetSubImage( - Display* /* display */, - Drawable /* d */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */, - unsigned long /* plane_mask */, - int /* format */, - XImage* /* dest_image */, - int /* dest_x */, - int /* dest_y */ +extern XImage* XGetSubImage( + Display* /* display */, + Drawable /* d */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */, + unsigned long /* plane_mask */, + int /* format */, + XImage* /* dest_image */, + int /* dest_x */, + int /* dest_y */ ); /* * X function declarations. */ -extern Display *XOpenDisplay( - _Xconst char* /* display_name */ +extern Display* XOpenDisplay( + _Xconst char* /* display_name */ ); extern void XrmInitialize( - void -); + void); -extern char *XFetchBytes( - Display* /* display */, - int* /* nbytes_return */ +extern char* XFetchBytes( + Display* /* display */, + int* /* nbytes_return */ ); -extern char *XFetchBuffer( - Display* /* display */, - int* /* nbytes_return */, - int /* buffer */ +extern char* XFetchBuffer( + Display* /* display */, + int* /* nbytes_return */, + int /* buffer */ ); -extern char *XGetAtomName( - Display* /* display */, - Atom /* atom */ +extern char* XGetAtomName( + Display* /* display */, + Atom /* atom */ ); extern Status XGetAtomNames( - Display* /* dpy */, - Atom* /* atoms */, - int /* count */, - char** /* names_return */ + Display* /* dpy */, + Atom* /* atoms */, + int /* count */, + char** /* names_return */ ); -extern char *XGetDefault( - Display* /* display */, - _Xconst char* /* program */, - _Xconst char* /* option */ +extern char* XGetDefault( + Display* /* display */, + _Xconst char* /* program */, + _Xconst char* /* option */ ); -extern char *XDisplayName( - _Xconst char* /* string */ +extern char* XDisplayName( + _Xconst char* /* string */ ); -extern char *XKeysymToString( - KeySym /* keysym */ +extern char* XKeysymToString( + KeySym /* keysym */ ); extern int (*XSynchronize( - Display* /* display */, - Bool /* onoff */ -))( - Display* /* display */ + Display* /* display */, + Bool /* onoff */ + ))( + Display* /* display */ ); extern int (*XSetAfterFunction( - Display* /* display */, - int (*) ( - Display* /* display */ - ) /* procedure */ -))( - Display* /* display */ + Display* /* display */, + int (*)( + Display* /* display */ + ) /* procedure */ + ))( + Display* /* display */ ); extern Atom XInternAtom( - Display* /* display */, - _Xconst char* /* atom_name */, - Bool /* only_if_exists */ + Display* /* display */, + _Xconst char* /* atom_name */, + Bool /* only_if_exists */ ); extern Status XInternAtoms( - Display* /* dpy */, - char** /* names */, - int /* count */, - Bool /* onlyIfExists */, - Atom* /* atoms_return */ + Display* /* dpy */, + char** /* names */, + int /* count */, + Bool /* onlyIfExists */, + Atom* /* atoms_return */ ); extern Colormap XCopyColormapAndFree( - Display* /* display */, - Colormap /* colormap */ + Display* /* display */, + Colormap /* colormap */ ); extern Colormap XCreateColormap( - Display* /* display */, - Window /* w */, - Visual* /* visual */, - int /* alloc */ + Display* /* display */, + Window /* w */, + Visual* /* visual */, + int /* alloc */ ); extern Cursor XCreatePixmapCursor( - Display* /* display */, - Pixmap /* source */, - Pixmap /* mask */, - XColor* /* foreground_color */, - XColor* /* background_color */, - unsigned int /* x */, - unsigned int /* y */ + Display* /* display */, + Pixmap /* source */, + Pixmap /* mask */, + XColor* /* foreground_color */, + XColor* /* background_color */, + unsigned int /* x */, + unsigned int /* y */ ); extern Cursor XCreateGlyphCursor( - Display* /* display */, - Font /* source_font */, - Font /* mask_font */, - unsigned int /* source_char */, - unsigned int /* mask_char */, - XColor _Xconst * /* foreground_color */, - XColor _Xconst * /* background_color */ + Display* /* display */, + Font /* source_font */, + Font /* mask_font */, + unsigned int /* source_char */, + unsigned int /* mask_char */, + XColor _Xconst* /* foreground_color */, + XColor _Xconst* /* background_color */ ); extern Cursor XCreateFontCursor( - Display* /* display */, - unsigned int /* shape */ + Display* /* display */, + unsigned int /* shape */ ); extern Font XLoadFont( - Display* /* display */, - _Xconst char* /* name */ + Display* /* display */, + _Xconst char* /* name */ ); extern GC XCreateGC( - Display* /* display */, - Drawable /* d */, - unsigned long /* valuemask */, - XGCValues* /* values */ + Display* /* display */, + Drawable /* d */, + unsigned long /* valuemask */, + XGCValues* /* values */ ); extern GContext XGContextFromGC( - GC /* gc */ + GC /* gc */ ); extern void XFlushGC( - Display* /* display */, - GC /* gc */ + Display* /* display */, + GC /* gc */ ); extern Pixmap XCreatePixmap( - Display* /* display */, - Drawable /* d */, - unsigned int /* width */, - unsigned int /* height */, - unsigned int /* depth */ + Display* /* display */, + Drawable /* d */, + unsigned int /* width */, + unsigned int /* height */, + unsigned int /* depth */ ); extern Pixmap XCreateBitmapFromData( - Display* /* display */, - Drawable /* d */, - _Xconst char* /* data */, - unsigned int /* width */, - unsigned int /* height */ + Display* /* display */, + Drawable /* d */, + _Xconst char* /* data */, + unsigned int /* width */, + unsigned int /* height */ ); extern Pixmap XCreatePixmapFromBitmapData( - Display* /* display */, - Drawable /* d */, - char* /* data */, - unsigned int /* width */, - unsigned int /* height */, - unsigned long /* fg */, - unsigned long /* bg */, - unsigned int /* depth */ + Display* /* display */, + Drawable /* d */, + char* /* data */, + unsigned int /* width */, + unsigned int /* height */, + unsigned long /* fg */, + unsigned long /* bg */, + unsigned int /* depth */ ); extern Window XCreateSimpleWindow( - Display* /* display */, - Window /* parent */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */, - unsigned int /* border_width */, - unsigned long /* border */, - unsigned long /* background */ + Display* /* display */, + Window /* parent */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */, + unsigned int /* border_width */, + unsigned long /* border */, + unsigned long /* background */ ); extern Window XGetSelectionOwner( - Display* /* display */, - Atom /* selection */ + Display* /* display */, + Atom /* selection */ ); extern Window XCreateWindow( - Display* /* display */, - Window /* parent */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */, - unsigned int /* border_width */, - int /* depth */, - unsigned int /* class */, - Visual* /* visual */, - unsigned long /* valuemask */, - XSetWindowAttributes* /* attributes */ + Display* /* display */, + Window /* parent */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */, + unsigned int /* border_width */, + int /* depth */, + unsigned int /* class */, + Visual* /* visual */, + unsigned long /* valuemask */, + XSetWindowAttributes* /* attributes */ ); -extern Colormap *XListInstalledColormaps( - Display* /* display */, - Window /* w */, - int* /* num_return */ +extern Colormap* XListInstalledColormaps( + Display* /* display */, + Window /* w */, + int* /* num_return */ ); -extern char **XListFonts( - Display* /* display */, - _Xconst char* /* pattern */, - int /* maxnames */, - int* /* actual_count_return */ +extern char** XListFonts( + Display* /* display */, + _Xconst char* /* pattern */, + int /* maxnames */, + int* /* actual_count_return */ ); -extern char **XListFontsWithInfo( - Display* /* display */, - _Xconst char* /* pattern */, - int /* maxnames */, - int* /* count_return */, - XFontStruct** /* info_return */ +extern char** XListFontsWithInfo( + Display* /* display */, + _Xconst char* /* pattern */, + int /* maxnames */, + int* /* count_return */, + XFontStruct** /* info_return */ ); -extern char **XGetFontPath( - Display* /* display */, - int* /* npaths_return */ +extern char** XGetFontPath( + Display* /* display */, + int* /* npaths_return */ ); -extern char **XListExtensions( - Display* /* display */, - int* /* nextensions_return */ +extern char** XListExtensions( + Display* /* display */, + int* /* nextensions_return */ ); -extern Atom *XListProperties( - Display* /* display */, - Window /* w */, - int* /* num_prop_return */ +extern Atom* XListProperties( + Display* /* display */, + Window /* w */, + int* /* num_prop_return */ ); -extern XHostAddress *XListHosts( - Display* /* display */, - int* /* nhosts_return */, - Bool* /* state_return */ +extern XHostAddress* XListHosts( + Display* /* display */, + int* /* nhosts_return */, + Bool* /* state_return */ ); _X_DEPRECATED extern KeySym XKeycodeToKeysym( - Display* /* display */, + Display* /* display */, #if NeedWidePrototypes - unsigned int /* keycode */, + unsigned int /* keycode */, #else - KeyCode /* keycode */, + KeyCode /* keycode */, #endif - int /* index */ + int /* index */ ); extern KeySym XLookupKeysym( - XKeyEvent* /* key_event */, - int /* index */ + XKeyEvent* /* key_event */, + int /* index */ ); -extern KeySym *XGetKeyboardMapping( - Display* /* display */, +extern KeySym* XGetKeyboardMapping( + Display* /* display */, #if NeedWidePrototypes - unsigned int /* first_keycode */, + unsigned int /* first_keycode */, #else - KeyCode /* first_keycode */, + KeyCode /* first_keycode */, #endif - int /* keycode_count */, - int* /* keysyms_per_keycode_return */ + int /* keycode_count */, + int* /* keysyms_per_keycode_return */ ); extern KeySym XStringToKeysym( - _Xconst char* /* string */ + _Xconst char* /* string */ ); extern long XMaxRequestSize( - Display* /* display */ + Display* /* display */ ); extern long XExtendedMaxRequestSize( - Display* /* display */ + Display* /* display */ ); -extern char *XResourceManagerString( - Display* /* display */ +extern char* XResourceManagerString( + Display* /* display */ ); -extern char *XScreenResourceString( - Screen* /* screen */ +extern char* XScreenResourceString( + Screen* /* screen */ ); extern unsigned long XDisplayMotionBufferSize( - Display* /* display */ + Display* /* display */ ); extern VisualID XVisualIDFromVisual( - Visual* /* visual */ + Visual* /* visual */ ); /* multithread routines */ extern Status XInitThreads( - void -); + void); extern void XLockDisplay( - Display* /* display */ + Display* /* display */ ); extern void XUnlockDisplay( - Display* /* display */ + Display* /* display */ ); /* routines for dealing with extensions */ -extern XExtCodes *XInitExtension( - Display* /* display */, - _Xconst char* /* name */ +extern XExtCodes* XInitExtension( + Display* /* display */, + _Xconst char* /* name */ ); -extern XExtCodes *XAddExtension( - Display* /* display */ +extern XExtCodes* XAddExtension( + Display* /* display */ ); -extern XExtData *XFindOnExtensionList( - XExtData** /* structure */, - int /* number */ +extern XExtData* XFindOnExtensionList( + XExtData** /* structure */, + int /* number */ ); -extern XExtData **XEHeadOfExtensionList( - XEDataObject /* object */ +extern XExtData** XEHeadOfExtensionList( + XEDataObject /* object */ ); /* these are routines for which there are also macros */ extern Window XRootWindow( - Display* /* display */, - int /* screen_number */ + Display* /* display */, + int /* screen_number */ ); extern Window XDefaultRootWindow( - Display* /* display */ + Display* /* display */ ); extern Window XRootWindowOfScreen( - Screen* /* screen */ + Screen* /* screen */ ); -extern Visual *XDefaultVisual( - Display* /* display */, - int /* screen_number */ +extern Visual* XDefaultVisual( + Display* /* display */, + int /* screen_number */ ); -extern Visual *XDefaultVisualOfScreen( - Screen* /* screen */ +extern Visual* XDefaultVisualOfScreen( + Screen* /* screen */ ); extern GC XDefaultGC( - Display* /* display */, - int /* screen_number */ + Display* /* display */, + int /* screen_number */ ); extern GC XDefaultGCOfScreen( - Screen* /* screen */ + Screen* /* screen */ ); extern unsigned long XBlackPixel( - Display* /* display */, - int /* screen_number */ + Display* /* display */, + int /* screen_number */ ); extern unsigned long XWhitePixel( - Display* /* display */, - int /* screen_number */ + Display* /* display */, + int /* screen_number */ ); extern unsigned long XAllPlanes( - void -); + void); extern unsigned long XBlackPixelOfScreen( - Screen* /* screen */ + Screen* /* screen */ ); extern unsigned long XWhitePixelOfScreen( - Screen* /* screen */ + Screen* /* screen */ ); extern unsigned long XNextRequest( - Display* /* display */ + Display* /* display */ ); extern unsigned long XLastKnownRequestProcessed( - Display* /* display */ + Display* /* display */ ); -extern char *XServerVendor( - Display* /* display */ +extern char* XServerVendor( + Display* /* display */ ); -extern char *XDisplayString( - Display* /* display */ +extern char* XDisplayString( + Display* /* display */ ); extern Colormap XDefaultColormap( - Display* /* display */, - int /* screen_number */ + Display* /* display */, + int /* screen_number */ ); extern Colormap XDefaultColormapOfScreen( - Screen* /* screen */ + Screen* /* screen */ ); -extern Display *XDisplayOfScreen( - Screen* /* screen */ +extern Display* XDisplayOfScreen( + Screen* /* screen */ ); -extern Screen *XScreenOfDisplay( - Display* /* display */, - int /* screen_number */ +extern Screen* XScreenOfDisplay( + Display* /* display */, + int /* screen_number */ ); -extern Screen *XDefaultScreenOfDisplay( - Display* /* display */ +extern Screen* XDefaultScreenOfDisplay( + Display* /* display */ ); extern long XEventMaskOfScreen( - Screen* /* screen */ + Screen* /* screen */ ); extern int XScreenNumberOfScreen( - Screen* /* screen */ + Screen* /* screen */ ); -typedef int (*XErrorHandler) ( /* WARNING, this type not in Xlib spec */ - Display* /* display */, - XErrorEvent* /* error_event */ +typedef int (*XErrorHandler)(/* WARNING, this type not in Xlib spec */ + Display* /* display */, + XErrorEvent* /* error_event */ ); -extern XErrorHandler XSetErrorHandler ( - XErrorHandler /* handler */ +extern XErrorHandler XSetErrorHandler( + XErrorHandler /* handler */ ); - -typedef int (*XIOErrorHandler) ( /* WARNING, this type not in Xlib spec */ - Display* /* display */ +typedef int (*XIOErrorHandler)( /* WARNING, this type not in Xlib spec */ + Display* /* display */ ); -extern XIOErrorHandler XSetIOErrorHandler ( - XIOErrorHandler /* handler */ +extern XIOErrorHandler XSetIOErrorHandler( + XIOErrorHandler /* handler */ ); - -extern XPixmapFormatValues *XListPixmapFormats( - Display* /* display */, - int* /* count_return */ +extern XPixmapFormatValues* XListPixmapFormats( + Display* /* display */, + int* /* count_return */ ); -extern int *XListDepths( - Display* /* display */, - int /* screen_number */, - int* /* count_return */ +extern int* XListDepths( + Display* /* display */, + int /* screen_number */, + int* /* count_return */ ); /* ICCCM routines for things that don't require special include files; */ /* other declarations are given in Xutil.h */ extern Status XReconfigureWMWindow( - Display* /* display */, - Window /* w */, - int /* screen_number */, - unsigned int /* mask */, - XWindowChanges* /* changes */ + Display* /* display */, + Window /* w */, + int /* screen_number */, + unsigned int /* mask */, + XWindowChanges* /* changes */ ); extern Status XGetWMProtocols( - Display* /* display */, - Window /* w */, - Atom** /* protocols_return */, - int* /* count_return */ + Display* /* display */, + Window /* w */, + Atom** /* protocols_return */, + int* /* count_return */ ); extern Status XSetWMProtocols( - Display* /* display */, - Window /* w */, - Atom* /* protocols */, - int /* count */ + Display* /* display */, + Window /* w */, + Atom* /* protocols */, + int /* count */ ); extern Status XIconifyWindow( - Display* /* display */, - Window /* w */, - int /* screen_number */ + Display* /* display */, + Window /* w */, + int /* screen_number */ ); extern Status XWithdrawWindow( - Display* /* display */, - Window /* w */, - int /* screen_number */ + Display* /* display */, + Window /* w */, + int /* screen_number */ ); extern Status XGetCommand( - Display* /* display */, - Window /* w */, - char*** /* argv_return */, - int* /* argc_return */ + Display* /* display */, + Window /* w */, + char*** /* argv_return */, + int* /* argc_return */ ); extern Status XGetWMColormapWindows( - Display* /* display */, - Window /* w */, - Window** /* windows_return */, - int* /* count_return */ + Display* /* display */, + Window /* w */, + Window** /* windows_return */, + int* /* count_return */ ); extern Status XSetWMColormapWindows( - Display* /* display */, - Window /* w */, - Window* /* colormap_windows */, - int /* count */ + Display* /* display */, + Window /* w */, + Window* /* colormap_windows */, + int /* count */ ); extern void XFreeStringList( - char** /* list */ + char** /* list */ ); extern int XSetTransientForHint( - Display* /* display */, - Window /* w */, - Window /* prop_window */ + Display* /* display */, + Window /* w */, + Window /* prop_window */ ); /* The following are given in alphabetical order */ extern int XActivateScreenSaver( - Display* /* display */ + Display* /* display */ ); extern int XAddHost( - Display* /* display */, - XHostAddress* /* host */ + Display* /* display */, + XHostAddress* /* host */ ); extern int XAddHosts( - Display* /* display */, - XHostAddress* /* hosts */, - int /* num_hosts */ + Display* /* display */, + XHostAddress* /* hosts */, + int /* num_hosts */ ); extern int XAddToExtensionList( - struct _XExtData** /* structure */, - XExtData* /* ext_data */ + struct _XExtData** /* structure */, + XExtData* /* ext_data */ ); extern int XAddToSaveSet( - Display* /* display */, - Window /* w */ + Display* /* display */, + Window /* w */ ); extern Status XAllocColor( - Display* /* display */, - Colormap /* colormap */, - XColor* /* screen_in_out */ + Display* /* display */, + Colormap /* colormap */, + XColor* /* screen_in_out */ ); extern Status XAllocColorCells( - Display* /* display */, - Colormap /* colormap */, - Bool /* contig */, - unsigned long* /* plane_masks_return */, - unsigned int /* nplanes */, - unsigned long* /* pixels_return */, - unsigned int /* npixels */ + Display* /* display */, + Colormap /* colormap */, + Bool /* contig */, + unsigned long* /* plane_masks_return */, + unsigned int /* nplanes */, + unsigned long* /* pixels_return */, + unsigned int /* npixels */ ); extern Status XAllocColorPlanes( - Display* /* display */, - Colormap /* colormap */, - Bool /* contig */, - unsigned long* /* pixels_return */, - int /* ncolors */, - int /* nreds */, - int /* ngreens */, - int /* nblues */, - unsigned long* /* rmask_return */, - unsigned long* /* gmask_return */, - unsigned long* /* bmask_return */ + Display* /* display */, + Colormap /* colormap */, + Bool /* contig */, + unsigned long* /* pixels_return */, + int /* ncolors */, + int /* nreds */, + int /* ngreens */, + int /* nblues */, + unsigned long* /* rmask_return */, + unsigned long* /* gmask_return */, + unsigned long* /* bmask_return */ ); extern Status XAllocNamedColor( - Display* /* display */, - Colormap /* colormap */, - _Xconst char* /* color_name */, - XColor* /* screen_def_return */, - XColor* /* exact_def_return */ + Display* /* display */, + Colormap /* colormap */, + _Xconst char* /* color_name */, + XColor* /* screen_def_return */, + XColor* /* exact_def_return */ ); extern int XAllowEvents( - Display* /* display */, - int /* event_mode */, - Time /* time */ + Display* /* display */, + int /* event_mode */, + Time /* time */ ); extern int XAutoRepeatOff( - Display* /* display */ + Display* /* display */ ); extern int XAutoRepeatOn( - Display* /* display */ + Display* /* display */ ); extern int XBell( - Display* /* display */, - int /* percent */ + Display* /* display */, + int /* percent */ ); extern int XBitmapBitOrder( - Display* /* display */ + Display* /* display */ ); extern int XBitmapPad( - Display* /* display */ + Display* /* display */ ); extern int XBitmapUnit( - Display* /* display */ + Display* /* display */ ); extern int XCellsOfScreen( - Screen* /* screen */ + Screen* /* screen */ ); extern int XChangeActivePointerGrab( - Display* /* display */, - unsigned int /* event_mask */, - Cursor /* cursor */, - Time /* time */ + Display* /* display */, + unsigned int /* event_mask */, + Cursor /* cursor */, + Time /* time */ ); extern int XChangeGC( - Display* /* display */, - GC /* gc */, - unsigned long /* valuemask */, - XGCValues* /* values */ + Display* /* display */, + GC /* gc */, + unsigned long /* valuemask */, + XGCValues* /* values */ ); extern int XChangeKeyboardControl( - Display* /* display */, - unsigned long /* value_mask */, - XKeyboardControl* /* values */ + Display* /* display */, + unsigned long /* value_mask */, + XKeyboardControl* /* values */ ); extern int XChangeKeyboardMapping( - Display* /* display */, - int /* first_keycode */, - int /* keysyms_per_keycode */, - KeySym* /* keysyms */, - int /* num_codes */ + Display* /* display */, + int /* first_keycode */, + int /* keysyms_per_keycode */, + KeySym* /* keysyms */, + int /* num_codes */ ); extern int XChangePointerControl( - Display* /* display */, - Bool /* do_accel */, - Bool /* do_threshold */, - int /* accel_numerator */, - int /* accel_denominator */, - int /* threshold */ + Display* /* display */, + Bool /* do_accel */, + Bool /* do_threshold */, + int /* accel_numerator */, + int /* accel_denominator */, + int /* threshold */ ); extern int XChangeProperty( - Display* /* display */, - Window /* w */, - Atom /* property */, - Atom /* type */, - int /* format */, - int /* mode */, - _Xconst unsigned char* /* data */, - int /* nelements */ + Display* /* display */, + Window /* w */, + Atom /* property */, + Atom /* type */, + int /* format */, + int /* mode */, + _Xconst unsigned char* /* data */, + int /* nelements */ ); extern int XChangeSaveSet( - Display* /* display */, - Window /* w */, - int /* change_mode */ + Display* /* display */, + Window /* w */, + int /* change_mode */ ); extern int XChangeWindowAttributes( - Display* /* display */, - Window /* w */, - unsigned long /* valuemask */, - XSetWindowAttributes* /* attributes */ + Display* /* display */, + Window /* w */, + unsigned long /* valuemask */, + XSetWindowAttributes* /* attributes */ ); extern Bool XCheckIfEvent( - Display* /* display */, - XEvent* /* event_return */, - Bool (*) ( - Display* /* display */, - XEvent* /* event */, - XPointer /* arg */ - ) /* predicate */, - XPointer /* arg */ + Display* /* display */, + XEvent* /* event_return */, + Bool (*)( + Display* /* display */, + XEvent* /* event */, + XPointer /* arg */ + ) /* predicate */, + XPointer /* arg */ ); extern Bool XCheckMaskEvent( - Display* /* display */, - long /* event_mask */, - XEvent* /* event_return */ + Display* /* display */, + long /* event_mask */, + XEvent* /* event_return */ ); extern Bool XCheckTypedEvent( - Display* /* display */, - int /* event_type */, - XEvent* /* event_return */ + Display* /* display */, + int /* event_type */, + XEvent* /* event_return */ ); extern Bool XCheckTypedWindowEvent( - Display* /* display */, - Window /* w */, - int /* event_type */, - XEvent* /* event_return */ + Display* /* display */, + Window /* w */, + int /* event_type */, + XEvent* /* event_return */ ); extern Bool XCheckWindowEvent( - Display* /* display */, - Window /* w */, - long /* event_mask */, - XEvent* /* event_return */ + Display* /* display */, + Window /* w */, + long /* event_mask */, + XEvent* /* event_return */ ); extern int XCirculateSubwindows( - Display* /* display */, - Window /* w */, - int /* direction */ + Display* /* display */, + Window /* w */, + int /* direction */ ); extern int XCirculateSubwindowsDown( - Display* /* display */, - Window /* w */ + Display* /* display */, + Window /* w */ ); extern int XCirculateSubwindowsUp( - Display* /* display */, - Window /* w */ + Display* /* display */, + Window /* w */ ); extern int XClearArea( - Display* /* display */, - Window /* w */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */, - Bool /* exposures */ + Display* /* display */, + Window /* w */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */, + Bool /* exposures */ ); extern int XClearWindow( - Display* /* display */, - Window /* w */ + Display* /* display */, + Window /* w */ ); extern int XCloseDisplay( - Display* /* display */ + Display* /* display */ ); extern int XConfigureWindow( - Display* /* display */, - Window /* w */, - unsigned int /* value_mask */, - XWindowChanges* /* values */ + Display* /* display */, + Window /* w */, + unsigned int /* value_mask */, + XWindowChanges* /* values */ ); extern int XConnectionNumber( - Display* /* display */ + Display* /* display */ ); extern int XConvertSelection( - Display* /* display */, - Atom /* selection */, - Atom /* target */, - Atom /* property */, - Window /* requestor */, - Time /* time */ + Display* /* display */, + Atom /* selection */, + Atom /* target */, + Atom /* property */, + Window /* requestor */, + Time /* time */ ); extern int XCopyArea( - Display* /* display */, - Drawable /* src */, - Drawable /* dest */, - GC /* gc */, - int /* src_x */, - int /* src_y */, - unsigned int /* width */, - unsigned int /* height */, - int /* dest_x */, - int /* dest_y */ + Display* /* display */, + Drawable /* src */, + Drawable /* dest */, + GC /* gc */, + int /* src_x */, + int /* src_y */, + unsigned int /* width */, + unsigned int /* height */, + int /* dest_x */, + int /* dest_y */ ); extern int XCopyGC( - Display* /* display */, - GC /* src */, - unsigned long /* valuemask */, - GC /* dest */ + Display* /* display */, + GC /* src */, + unsigned long /* valuemask */, + GC /* dest */ ); extern int XCopyPlane( - Display* /* display */, - Drawable /* src */, - Drawable /* dest */, - GC /* gc */, - int /* src_x */, - int /* src_y */, - unsigned int /* width */, - unsigned int /* height */, - int /* dest_x */, - int /* dest_y */, - unsigned long /* plane */ + Display* /* display */, + Drawable /* src */, + Drawable /* dest */, + GC /* gc */, + int /* src_x */, + int /* src_y */, + unsigned int /* width */, + unsigned int /* height */, + int /* dest_x */, + int /* dest_y */, + unsigned long /* plane */ ); extern int XDefaultDepth( - Display* /* display */, - int /* screen_number */ + Display* /* display */, + int /* screen_number */ ); extern int XDefaultDepthOfScreen( - Screen* /* screen */ + Screen* /* screen */ ); extern int XDefaultScreen( - Display* /* display */ + Display* /* display */ ); extern int XDefineCursor( - Display* /* display */, - Window /* w */, - Cursor /* cursor */ + Display* /* display */, + Window /* w */, + Cursor /* cursor */ ); extern int XDeleteProperty( - Display* /* display */, - Window /* w */, - Atom /* property */ + Display* /* display */, + Window /* w */, + Atom /* property */ ); extern int XDestroyWindow( - Display* /* display */, - Window /* w */ + Display* /* display */, + Window /* w */ ); extern int XDestroySubwindows( - Display* /* display */, - Window /* w */ + Display* /* display */, + Window /* w */ ); extern int XDoesBackingStore( - Screen* /* screen */ + Screen* /* screen */ ); extern Bool XDoesSaveUnders( - Screen* /* screen */ + Screen* /* screen */ ); extern int XDisableAccessControl( - Display* /* display */ + Display* /* display */ ); - extern int XDisplayCells( - Display* /* display */, - int /* screen_number */ + Display* /* display */, + int /* screen_number */ ); extern int XDisplayHeight( - Display* /* display */, - int /* screen_number */ + Display* /* display */, + int /* screen_number */ ); extern int XDisplayHeightMM( - Display* /* display */, - int /* screen_number */ + Display* /* display */, + int /* screen_number */ ); extern int XDisplayKeycodes( - Display* /* display */, - int* /* min_keycodes_return */, - int* /* max_keycodes_return */ + Display* /* display */, + int* /* min_keycodes_return */, + int* /* max_keycodes_return */ ); extern int XDisplayPlanes( - Display* /* display */, - int /* screen_number */ + Display* /* display */, + int /* screen_number */ ); extern int XDisplayWidth( - Display* /* display */, - int /* screen_number */ + Display* /* display */, + int /* screen_number */ ); extern int XDisplayWidthMM( - Display* /* display */, - int /* screen_number */ + Display* /* display */, + int /* screen_number */ ); extern int XDrawArc( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */, - int /* angle1 */, - int /* angle2 */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */, + int /* angle1 */, + int /* angle2 */ ); extern int XDrawArcs( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - XArc* /* arcs */, - int /* narcs */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + XArc* /* arcs */, + int /* narcs */ ); extern int XDrawImageString( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - _Xconst char* /* string */, - int /* length */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst char* /* string */, + int /* length */ ); extern int XDrawImageString16( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - _Xconst XChar2b* /* string */, - int /* length */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst XChar2b* /* string */, + int /* length */ ); extern int XDrawLine( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x1 */, - int /* y1 */, - int /* x2 */, - int /* y2 */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x1 */, + int /* y1 */, + int /* x2 */, + int /* y2 */ ); extern int XDrawLines( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - XPoint* /* points */, - int /* npoints */, - int /* mode */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + XPoint* /* points */, + int /* npoints */, + int /* mode */ ); extern int XDrawPoint( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */ ); extern int XDrawPoints( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - XPoint* /* points */, - int /* npoints */, - int /* mode */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + XPoint* /* points */, + int /* npoints */, + int /* mode */ ); extern int XDrawRectangle( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */ ); extern int XDrawRectangles( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - XRectangle* /* rectangles */, - int /* nrectangles */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + XRectangle* /* rectangles */, + int /* nrectangles */ ); extern int XDrawSegments( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - XSegment* /* segments */, - int /* nsegments */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + XSegment* /* segments */, + int /* nsegments */ ); extern int XDrawString( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - _Xconst char* /* string */, - int /* length */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst char* /* string */, + int /* length */ ); extern int XDrawString16( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - _Xconst XChar2b* /* string */, - int /* length */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst XChar2b* /* string */, + int /* length */ ); extern int XDrawText( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - XTextItem* /* items */, - int /* nitems */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + XTextItem* /* items */, + int /* nitems */ ); extern int XDrawText16( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - XTextItem16* /* items */, - int /* nitems */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + XTextItem16* /* items */, + int /* nitems */ ); extern int XEnableAccessControl( - Display* /* display */ + Display* /* display */ ); extern int XEventsQueued( - Display* /* display */, - int /* mode */ + Display* /* display */, + int /* mode */ ); extern Status XFetchName( - Display* /* display */, - Window /* w */, - char** /* window_name_return */ + Display* /* display */, + Window /* w */, + char** /* window_name_return */ ); extern int XFillArc( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */, - int /* angle1 */, - int /* angle2 */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */, + int /* angle1 */, + int /* angle2 */ ); extern int XFillArcs( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - XArc* /* arcs */, - int /* narcs */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + XArc* /* arcs */, + int /* narcs */ ); extern int XFillPolygon( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - XPoint* /* points */, - int /* npoints */, - int /* shape */, - int /* mode */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + XPoint* /* points */, + int /* npoints */, + int /* shape */, + int /* mode */ ); extern int XFillRectangle( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */ ); extern int XFillRectangles( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - XRectangle* /* rectangles */, - int /* nrectangles */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + XRectangle* /* rectangles */, + int /* nrectangles */ ); extern int XFlush( - Display* /* display */ + Display* /* display */ ); extern int XForceScreenSaver( - Display* /* display */, - int /* mode */ + Display* /* display */, + int /* mode */ ); extern int XFree( - void* /* data */ + void* /* data */ ); extern int XFreeColormap( - Display* /* display */, - Colormap /* colormap */ + Display* /* display */, + Colormap /* colormap */ ); extern int XFreeColors( - Display* /* display */, - Colormap /* colormap */, - unsigned long* /* pixels */, - int /* npixels */, - unsigned long /* planes */ + Display* /* display */, + Colormap /* colormap */, + unsigned long* /* pixels */, + int /* npixels */, + unsigned long /* planes */ ); extern int XFreeCursor( - Display* /* display */, - Cursor /* cursor */ + Display* /* display */, + Cursor /* cursor */ ); extern int XFreeExtensionList( - char** /* list */ + char** /* list */ ); extern int XFreeFont( - Display* /* display */, - XFontStruct* /* font_struct */ + Display* /* display */, + XFontStruct* /* font_struct */ ); extern int XFreeFontInfo( - char** /* names */, - XFontStruct* /* free_info */, - int /* actual_count */ + char** /* names */, + XFontStruct* /* free_info */, + int /* actual_count */ ); extern int XFreeFontNames( - char** /* list */ + char** /* list */ ); extern int XFreeFontPath( - char** /* list */ + char** /* list */ ); extern int XFreeGC( - Display* /* display */, - GC /* gc */ + Display* /* display */, + GC /* gc */ ); extern int XFreeModifiermap( - XModifierKeymap* /* modmap */ + XModifierKeymap* /* modmap */ ); extern int XFreePixmap( - Display* /* display */, - Pixmap /* pixmap */ + Display* /* display */, + Pixmap /* pixmap */ ); extern int XGeometry( - Display* /* display */, - int /* screen */, - _Xconst char* /* position */, - _Xconst char* /* default_position */, - unsigned int /* bwidth */, - unsigned int /* fwidth */, - unsigned int /* fheight */, - int /* xadder */, - int /* yadder */, - int* /* x_return */, - int* /* y_return */, - int* /* width_return */, - int* /* height_return */ + Display* /* display */, + int /* screen */, + _Xconst char* /* position */, + _Xconst char* /* default_position */, + unsigned int /* bwidth */, + unsigned int /* fwidth */, + unsigned int /* fheight */, + int /* xadder */, + int /* yadder */, + int* /* x_return */, + int* /* y_return */, + int* /* width_return */, + int* /* height_return */ ); extern int XGetErrorDatabaseText( - Display* /* display */, - _Xconst char* /* name */, - _Xconst char* /* message */, - _Xconst char* /* default_string */, - char* /* buffer_return */, - int /* length */ + Display* /* display */, + _Xconst char* /* name */, + _Xconst char* /* message */, + _Xconst char* /* default_string */, + char* /* buffer_return */, + int /* length */ ); extern int XGetErrorText( - Display* /* display */, - int /* code */, - char* /* buffer_return */, - int /* length */ + Display* /* display */, + int /* code */, + char* /* buffer_return */, + int /* length */ ); extern Bool XGetFontProperty( - XFontStruct* /* font_struct */, - Atom /* atom */, - unsigned long* /* value_return */ + XFontStruct* /* font_struct */, + Atom /* atom */, + unsigned long* /* value_return */ ); extern Status XGetGCValues( - Display* /* display */, - GC /* gc */, - unsigned long /* valuemask */, - XGCValues* /* values_return */ + Display* /* display */, + GC /* gc */, + unsigned long /* valuemask */, + XGCValues* /* values_return */ ); extern Status XGetGeometry( - Display* /* display */, - Drawable /* d */, - Window* /* root_return */, - int* /* x_return */, - int* /* y_return */, - unsigned int* /* width_return */, - unsigned int* /* height_return */, - unsigned int* /* border_width_return */, - unsigned int* /* depth_return */ + Display* /* display */, + Drawable /* d */, + Window* /* root_return */, + int* /* x_return */, + int* /* y_return */, + unsigned int* /* width_return */, + unsigned int* /* height_return */, + unsigned int* /* border_width_return */, + unsigned int* /* depth_return */ ); extern Status XGetIconName( - Display* /* display */, - Window /* w */, - char** /* icon_name_return */ + Display* /* display */, + Window /* w */, + char** /* icon_name_return */ ); extern int XGetInputFocus( - Display* /* display */, - Window* /* focus_return */, - int* /* revert_to_return */ + Display* /* display */, + Window* /* focus_return */, + int* /* revert_to_return */ ); extern int XGetKeyboardControl( - Display* /* display */, - XKeyboardState* /* values_return */ + Display* /* display */, + XKeyboardState* /* values_return */ ); extern int XGetPointerControl( - Display* /* display */, - int* /* accel_numerator_return */, - int* /* accel_denominator_return */, - int* /* threshold_return */ + Display* /* display */, + int* /* accel_numerator_return */, + int* /* accel_denominator_return */, + int* /* threshold_return */ ); extern int XGetPointerMapping( - Display* /* display */, - unsigned char* /* map_return */, - int /* nmap */ + Display* /* display */, + unsigned char* /* map_return */, + int /* nmap */ ); extern int XGetScreenSaver( - Display* /* display */, - int* /* timeout_return */, - int* /* interval_return */, - int* /* prefer_blanking_return */, - int* /* allow_exposures_return */ + Display* /* display */, + int* /* timeout_return */, + int* /* interval_return */, + int* /* prefer_blanking_return */, + int* /* allow_exposures_return */ ); extern Status XGetTransientForHint( - Display* /* display */, - Window /* w */, - Window* /* prop_window_return */ + Display* /* display */, + Window /* w */, + Window* /* prop_window_return */ ); extern int XGetWindowProperty( - Display* /* display */, - Window /* w */, - Atom /* property */, - long /* long_offset */, - long /* long_length */, - Bool /* delete */, - Atom /* req_type */, - Atom* /* actual_type_return */, - int* /* actual_format_return */, - unsigned long* /* nitems_return */, - unsigned long* /* bytes_after_return */, - unsigned char** /* prop_return */ + Display* /* display */, + Window /* w */, + Atom /* property */, + long /* long_offset */, + long /* long_length */, + Bool /* delete */, + Atom /* req_type */, + Atom* /* actual_type_return */, + int* /* actual_format_return */, + unsigned long* /* nitems_return */, + unsigned long* /* bytes_after_return */, + unsigned char** /* prop_return */ ); extern Status XGetWindowAttributes( - Display* /* display */, - Window /* w */, - XWindowAttributes* /* window_attributes_return */ + Display* /* display */, + Window /* w */, + XWindowAttributes* /* window_attributes_return */ ); extern int XGrabButton( - Display* /* display */, - unsigned int /* button */, - unsigned int /* modifiers */, - Window /* grab_window */, - Bool /* owner_events */, - unsigned int /* event_mask */, - int /* pointer_mode */, - int /* keyboard_mode */, - Window /* confine_to */, - Cursor /* cursor */ + Display* /* display */, + unsigned int /* button */, + unsigned int /* modifiers */, + Window /* grab_window */, + Bool /* owner_events */, + unsigned int /* event_mask */, + int /* pointer_mode */, + int /* keyboard_mode */, + Window /* confine_to */, + Cursor /* cursor */ ); extern int XGrabKey( - Display* /* display */, - int /* keycode */, - unsigned int /* modifiers */, - Window /* grab_window */, - Bool /* owner_events */, - int /* pointer_mode */, - int /* keyboard_mode */ + Display* /* display */, + int /* keycode */, + unsigned int /* modifiers */, + Window /* grab_window */, + Bool /* owner_events */, + int /* pointer_mode */, + int /* keyboard_mode */ ); extern int XGrabKeyboard( - Display* /* display */, - Window /* grab_window */, - Bool /* owner_events */, - int /* pointer_mode */, - int /* keyboard_mode */, - Time /* time */ + Display* /* display */, + Window /* grab_window */, + Bool /* owner_events */, + int /* pointer_mode */, + int /* keyboard_mode */, + Time /* time */ ); extern int XGrabPointer( - Display* /* display */, - Window /* grab_window */, - Bool /* owner_events */, - unsigned int /* event_mask */, - int /* pointer_mode */, - int /* keyboard_mode */, - Window /* confine_to */, - Cursor /* cursor */, - Time /* time */ + Display* /* display */, + Window /* grab_window */, + Bool /* owner_events */, + unsigned int /* event_mask */, + int /* pointer_mode */, + int /* keyboard_mode */, + Window /* confine_to */, + Cursor /* cursor */, + Time /* time */ ); extern int XGrabServer( - Display* /* display */ + Display* /* display */ ); extern int XHeightMMOfScreen( - Screen* /* screen */ + Screen* /* screen */ ); extern int XHeightOfScreen( - Screen* /* screen */ + Screen* /* screen */ ); extern int XIfEvent( - Display* /* display */, - XEvent* /* event_return */, - Bool (*) ( - Display* /* display */, - XEvent* /* event */, - XPointer /* arg */ - ) /* predicate */, - XPointer /* arg */ + Display* /* display */, + XEvent* /* event_return */, + Bool (*)( + Display* /* display */, + XEvent* /* event */, + XPointer /* arg */ + ) /* predicate */, + XPointer /* arg */ ); extern int XImageByteOrder( - Display* /* display */ + Display* /* display */ ); extern int XInstallColormap( - Display* /* display */, - Colormap /* colormap */ + Display* /* display */, + Colormap /* colormap */ ); extern KeyCode XKeysymToKeycode( - Display* /* display */, - KeySym /* keysym */ + Display* /* display */, + KeySym /* keysym */ ); extern int XKillClient( - Display* /* display */, - XID /* resource */ + Display* /* display */, + XID /* resource */ ); extern Status XLookupColor( - Display* /* display */, - Colormap /* colormap */, - _Xconst char* /* color_name */, - XColor* /* exact_def_return */, - XColor* /* screen_def_return */ + Display* /* display */, + Colormap /* colormap */, + _Xconst char* /* color_name */, + XColor* /* exact_def_return */, + XColor* /* screen_def_return */ ); extern int XLowerWindow( - Display* /* display */, - Window /* w */ + Display* /* display */, + Window /* w */ ); extern int XMapRaised( - Display* /* display */, - Window /* w */ + Display* /* display */, + Window /* w */ ); extern int XMapSubwindows( - Display* /* display */, - Window /* w */ + Display* /* display */, + Window /* w */ ); extern int XMapWindow( - Display* /* display */, - Window /* w */ + Display* /* display */, + Window /* w */ ); extern int XMaskEvent( - Display* /* display */, - long /* event_mask */, - XEvent* /* event_return */ + Display* /* display */, + long /* event_mask */, + XEvent* /* event_return */ ); extern int XMaxCmapsOfScreen( - Screen* /* screen */ + Screen* /* screen */ ); extern int XMinCmapsOfScreen( - Screen* /* screen */ + Screen* /* screen */ ); extern int XMoveResizeWindow( - Display* /* display */, - Window /* w */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */ + Display* /* display */, + Window /* w */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */ ); extern int XMoveWindow( - Display* /* display */, - Window /* w */, - int /* x */, - int /* y */ + Display* /* display */, + Window /* w */, + int /* x */, + int /* y */ ); extern int XNextEvent( - Display* /* display */, - XEvent* /* event_return */ + Display* /* display */, + XEvent* /* event_return */ ); extern int XNoOp( - Display* /* display */ + Display* /* display */ ); extern Status XParseColor( - Display* /* display */, - Colormap /* colormap */, - _Xconst char* /* spec */, - XColor* /* exact_def_return */ + Display* /* display */, + Colormap /* colormap */, + _Xconst char* /* spec */, + XColor* /* exact_def_return */ ); extern int XParseGeometry( - _Xconst char* /* parsestring */, - int* /* x_return */, - int* /* y_return */, - unsigned int* /* width_return */, - unsigned int* /* height_return */ + _Xconst char* /* parsestring */, + int* /* x_return */, + int* /* y_return */, + unsigned int* /* width_return */, + unsigned int* /* height_return */ ); extern int XPeekEvent( - Display* /* display */, - XEvent* /* event_return */ + Display* /* display */, + XEvent* /* event_return */ ); extern int XPeekIfEvent( - Display* /* display */, - XEvent* /* event_return */, - Bool (*) ( - Display* /* display */, - XEvent* /* event */, - XPointer /* arg */ - ) /* predicate */, - XPointer /* arg */ + Display* /* display */, + XEvent* /* event_return */, + Bool (*)( + Display* /* display */, + XEvent* /* event */, + XPointer /* arg */ + ) /* predicate */, + XPointer /* arg */ ); extern int XPending( - Display* /* display */ + Display* /* display */ ); extern int XPlanesOfScreen( - Screen* /* screen */ + Screen* /* screen */ ); extern int XProtocolRevision( - Display* /* display */ + Display* /* display */ ); extern int XProtocolVersion( - Display* /* display */ + Display* /* display */ ); - extern int XPutBackEvent( - Display* /* display */, - XEvent* /* event */ + Display* /* display */, + XEvent* /* event */ ); extern int XPutImage( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - XImage* /* image */, - int /* src_x */, - int /* src_y */, - int /* dest_x */, - int /* dest_y */, - unsigned int /* width */, - unsigned int /* height */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + XImage* /* image */, + int /* src_x */, + int /* src_y */, + int /* dest_x */, + int /* dest_y */, + unsigned int /* width */, + unsigned int /* height */ ); extern int XQLength( - Display* /* display */ + Display* /* display */ ); extern Status XQueryBestCursor( - Display* /* display */, - Drawable /* d */, - unsigned int /* width */, - unsigned int /* height */, - unsigned int* /* width_return */, - unsigned int* /* height_return */ + Display* /* display */, + Drawable /* d */, + unsigned int /* width */, + unsigned int /* height */, + unsigned int* /* width_return */, + unsigned int* /* height_return */ ); extern Status XQueryBestSize( - Display* /* display */, - int /* class */, - Drawable /* which_screen */, - unsigned int /* width */, - unsigned int /* height */, - unsigned int* /* width_return */, - unsigned int* /* height_return */ + Display* /* display */, + int /* class */, + Drawable /* which_screen */, + unsigned int /* width */, + unsigned int /* height */, + unsigned int* /* width_return */, + unsigned int* /* height_return */ ); extern Status XQueryBestStipple( - Display* /* display */, - Drawable /* which_screen */, - unsigned int /* width */, - unsigned int /* height */, - unsigned int* /* width_return */, - unsigned int* /* height_return */ + Display* /* display */, + Drawable /* which_screen */, + unsigned int /* width */, + unsigned int /* height */, + unsigned int* /* width_return */, + unsigned int* /* height_return */ ); extern Status XQueryBestTile( - Display* /* display */, - Drawable /* which_screen */, - unsigned int /* width */, - unsigned int /* height */, - unsigned int* /* width_return */, - unsigned int* /* height_return */ + Display* /* display */, + Drawable /* which_screen */, + unsigned int /* width */, + unsigned int /* height */, + unsigned int* /* width_return */, + unsigned int* /* height_return */ ); extern int XQueryColor( - Display* /* display */, - Colormap /* colormap */, - XColor* /* def_in_out */ + Display* /* display */, + Colormap /* colormap */, + XColor* /* def_in_out */ ); extern int XQueryColors( - Display* /* display */, - Colormap /* colormap */, - XColor* /* defs_in_out */, - int /* ncolors */ + Display* /* display */, + Colormap /* colormap */, + XColor* /* defs_in_out */, + int /* ncolors */ ); extern Bool XQueryExtension( - Display* /* display */, - _Xconst char* /* name */, - int* /* major_opcode_return */, - int* /* first_event_return */, - int* /* first_error_return */ + Display* /* display */, + _Xconst char* /* name */, + int* /* major_opcode_return */, + int* /* first_event_return */, + int* /* first_error_return */ ); extern int XQueryKeymap( - Display* /* display */, - char [32] /* keys_return */ + Display* /* display */, + char[32] /* keys_return */ ); extern Bool XQueryPointer( - Display* /* display */, - Window /* w */, - Window* /* root_return */, - Window* /* child_return */, - int* /* root_x_return */, - int* /* root_y_return */, - int* /* win_x_return */, - int* /* win_y_return */, - unsigned int* /* mask_return */ + Display* /* display */, + Window /* w */, + Window* /* root_return */, + Window* /* child_return */, + int* /* root_x_return */, + int* /* root_y_return */, + int* /* win_x_return */, + int* /* win_y_return */, + unsigned int* /* mask_return */ ); extern int XQueryTextExtents( - Display* /* display */, - XID /* font_ID */, - _Xconst char* /* string */, - int /* nchars */, - int* /* direction_return */, - int* /* font_ascent_return */, - int* /* font_descent_return */, - XCharStruct* /* overall_return */ + Display* /* display */, + XID /* font_ID */, + _Xconst char* /* string */, + int /* nchars */, + int* /* direction_return */, + int* /* font_ascent_return */, + int* /* font_descent_return */, + XCharStruct* /* overall_return */ ); extern int XQueryTextExtents16( - Display* /* display */, - XID /* font_ID */, - _Xconst XChar2b* /* string */, - int /* nchars */, - int* /* direction_return */, - int* /* font_ascent_return */, - int* /* font_descent_return */, - XCharStruct* /* overall_return */ + Display* /* display */, + XID /* font_ID */, + _Xconst XChar2b* /* string */, + int /* nchars */, + int* /* direction_return */, + int* /* font_ascent_return */, + int* /* font_descent_return */, + XCharStruct* /* overall_return */ ); extern Status XQueryTree( - Display* /* display */, - Window /* w */, - Window* /* root_return */, - Window* /* parent_return */, - Window** /* children_return */, - unsigned int* /* nchildren_return */ + Display* /* display */, + Window /* w */, + Window* /* root_return */, + Window* /* parent_return */, + Window** /* children_return */, + unsigned int* /* nchildren_return */ ); extern int XRaiseWindow( - Display* /* display */, - Window /* w */ + Display* /* display */, + Window /* w */ ); extern int XReadBitmapFile( - Display* /* display */, - Drawable /* d */, - _Xconst char* /* filename */, - unsigned int* /* width_return */, - unsigned int* /* height_return */, - Pixmap* /* bitmap_return */, - int* /* x_hot_return */, - int* /* y_hot_return */ + Display* /* display */, + Drawable /* d */, + _Xconst char* /* filename */, + unsigned int* /* width_return */, + unsigned int* /* height_return */, + Pixmap* /* bitmap_return */, + int* /* x_hot_return */, + int* /* y_hot_return */ ); extern int XReadBitmapFileData( - _Xconst char* /* filename */, - unsigned int* /* width_return */, - unsigned int* /* height_return */, - unsigned char** /* data_return */, - int* /* x_hot_return */, - int* /* y_hot_return */ + _Xconst char* /* filename */, + unsigned int* /* width_return */, + unsigned int* /* height_return */, + unsigned char** /* data_return */, + int* /* x_hot_return */, + int* /* y_hot_return */ ); extern int XRebindKeysym( - Display* /* display */, - KeySym /* keysym */, - KeySym* /* list */, - int /* mod_count */, - _Xconst unsigned char* /* string */, - int /* bytes_string */ + Display* /* display */, + KeySym /* keysym */, + KeySym* /* list */, + int /* mod_count */, + _Xconst unsigned char* /* string */, + int /* bytes_string */ ); extern int XRecolorCursor( - Display* /* display */, - Cursor /* cursor */, - XColor* /* foreground_color */, - XColor* /* background_color */ + Display* /* display */, + Cursor /* cursor */, + XColor* /* foreground_color */, + XColor* /* background_color */ ); extern int XRefreshKeyboardMapping( - XMappingEvent* /* event_map */ + XMappingEvent* /* event_map */ ); extern int XRemoveFromSaveSet( - Display* /* display */, - Window /* w */ + Display* /* display */, + Window /* w */ ); extern int XRemoveHost( - Display* /* display */, - XHostAddress* /* host */ + Display* /* display */, + XHostAddress* /* host */ ); extern int XRemoveHosts( - Display* /* display */, - XHostAddress* /* hosts */, - int /* num_hosts */ + Display* /* display */, + XHostAddress* /* hosts */, + int /* num_hosts */ ); extern int XReparentWindow( - Display* /* display */, - Window /* w */, - Window /* parent */, - int /* x */, - int /* y */ + Display* /* display */, + Window /* w */, + Window /* parent */, + int /* x */, + int /* y */ ); extern int XResetScreenSaver( - Display* /* display */ + Display* /* display */ ); extern int XResizeWindow( - Display* /* display */, - Window /* w */, - unsigned int /* width */, - unsigned int /* height */ + Display* /* display */, + Window /* w */, + unsigned int /* width */, + unsigned int /* height */ ); extern int XRestackWindows( - Display* /* display */, - Window* /* windows */, - int /* nwindows */ + Display* /* display */, + Window* /* windows */, + int /* nwindows */ ); extern int XRotateBuffers( - Display* /* display */, - int /* rotate */ + Display* /* display */, + int /* rotate */ ); extern int XRotateWindowProperties( - Display* /* display */, - Window /* w */, - Atom* /* properties */, - int /* num_prop */, - int /* npositions */ + Display* /* display */, + Window /* w */, + Atom* /* properties */, + int /* num_prop */, + int /* npositions */ ); extern int XScreenCount( - Display* /* display */ + Display* /* display */ ); extern int XSelectInput( - Display* /* display */, - Window /* w */, - long /* event_mask */ + Display* /* display */, + Window /* w */, + long /* event_mask */ ); extern Status XSendEvent( - Display* /* display */, - Window /* w */, - Bool /* propagate */, - long /* event_mask */, - XEvent* /* event_send */ + Display* /* display */, + Window /* w */, + Bool /* propagate */, + long /* event_mask */, + XEvent* /* event_send */ ); extern int XSetAccessControl( - Display* /* display */, - int /* mode */ + Display* /* display */, + int /* mode */ ); extern int XSetArcMode( - Display* /* display */, - GC /* gc */, - int /* arc_mode */ + Display* /* display */, + GC /* gc */, + int /* arc_mode */ ); extern int XSetBackground( - Display* /* display */, - GC /* gc */, - unsigned long /* background */ + Display* /* display */, + GC /* gc */, + unsigned long /* background */ ); extern int XSetClipMask( - Display* /* display */, - GC /* gc */, - Pixmap /* pixmap */ + Display* /* display */, + GC /* gc */, + Pixmap /* pixmap */ ); extern int XSetClipOrigin( - Display* /* display */, - GC /* gc */, - int /* clip_x_origin */, - int /* clip_y_origin */ + Display* /* display */, + GC /* gc */, + int /* clip_x_origin */, + int /* clip_y_origin */ ); extern int XSetClipRectangles( - Display* /* display */, - GC /* gc */, - int /* clip_x_origin */, - int /* clip_y_origin */, - XRectangle* /* rectangles */, - int /* n */, - int /* ordering */ + Display* /* display */, + GC /* gc */, + int /* clip_x_origin */, + int /* clip_y_origin */, + XRectangle* /* rectangles */, + int /* n */, + int /* ordering */ ); extern int XSetCloseDownMode( - Display* /* display */, - int /* close_mode */ + Display* /* display */, + int /* close_mode */ ); extern int XSetCommand( - Display* /* display */, - Window /* w */, - char** /* argv */, - int /* argc */ + Display* /* display */, + Window /* w */, + char** /* argv */, + int /* argc */ ); extern int XSetDashes( - Display* /* display */, - GC /* gc */, - int /* dash_offset */, - _Xconst char* /* dash_list */, - int /* n */ + Display* /* display */, + GC /* gc */, + int /* dash_offset */, + _Xconst char* /* dash_list */, + int /* n */ ); extern int XSetFillRule( - Display* /* display */, - GC /* gc */, - int /* fill_rule */ + Display* /* display */, + GC /* gc */, + int /* fill_rule */ ); extern int XSetFillStyle( - Display* /* display */, - GC /* gc */, - int /* fill_style */ + Display* /* display */, + GC /* gc */, + int /* fill_style */ ); extern int XSetFont( - Display* /* display */, - GC /* gc */, - Font /* font */ + Display* /* display */, + GC /* gc */, + Font /* font */ ); extern int XSetFontPath( - Display* /* display */, - char** /* directories */, - int /* ndirs */ + Display* /* display */, + char** /* directories */, + int /* ndirs */ ); extern int XSetForeground( - Display* /* display */, - GC /* gc */, - unsigned long /* foreground */ + Display* /* display */, + GC /* gc */, + unsigned long /* foreground */ ); extern int XSetFunction( - Display* /* display */, - GC /* gc */, - int /* function */ + Display* /* display */, + GC /* gc */, + int /* function */ ); extern int XSetGraphicsExposures( - Display* /* display */, - GC /* gc */, - Bool /* graphics_exposures */ + Display* /* display */, + GC /* gc */, + Bool /* graphics_exposures */ ); extern int XSetIconName( - Display* /* display */, - Window /* w */, - _Xconst char* /* icon_name */ + Display* /* display */, + Window /* w */, + _Xconst char* /* icon_name */ ); extern int XSetInputFocus( - Display* /* display */, - Window /* focus */, - int /* revert_to */, - Time /* time */ + Display* /* display */, + Window /* focus */, + int /* revert_to */, + Time /* time */ ); extern int XSetLineAttributes( - Display* /* display */, - GC /* gc */, - unsigned int /* line_width */, - int /* line_style */, - int /* cap_style */, - int /* join_style */ + Display* /* display */, + GC /* gc */, + unsigned int /* line_width */, + int /* line_style */, + int /* cap_style */, + int /* join_style */ ); extern int XSetModifierMapping( - Display* /* display */, - XModifierKeymap* /* modmap */ + Display* /* display */, + XModifierKeymap* /* modmap */ ); extern int XSetPlaneMask( - Display* /* display */, - GC /* gc */, - unsigned long /* plane_mask */ + Display* /* display */, + GC /* gc */, + unsigned long /* plane_mask */ ); extern int XSetPointerMapping( - Display* /* display */, - _Xconst unsigned char* /* map */, - int /* nmap */ + Display* /* display */, + _Xconst unsigned char* /* map */, + int /* nmap */ ); extern int XSetScreenSaver( - Display* /* display */, - int /* timeout */, - int /* interval */, - int /* prefer_blanking */, - int /* allow_exposures */ + Display* /* display */, + int /* timeout */, + int /* interval */, + int /* prefer_blanking */, + int /* allow_exposures */ ); extern int XSetSelectionOwner( - Display* /* display */, - Atom /* selection */, - Window /* owner */, - Time /* time */ + Display* /* display */, + Atom /* selection */, + Window /* owner */, + Time /* time */ ); extern int XSetState( - Display* /* display */, - GC /* gc */, - unsigned long /* foreground */, - unsigned long /* background */, - int /* function */, - unsigned long /* plane_mask */ + Display* /* display */, + GC /* gc */, + unsigned long /* foreground */, + unsigned long /* background */, + int /* function */, + unsigned long /* plane_mask */ ); extern int XSetStipple( - Display* /* display */, - GC /* gc */, - Pixmap /* stipple */ + Display* /* display */, + GC /* gc */, + Pixmap /* stipple */ ); extern int XSetSubwindowMode( - Display* /* display */, - GC /* gc */, - int /* subwindow_mode */ + Display* /* display */, + GC /* gc */, + int /* subwindow_mode */ ); extern int XSetTSOrigin( - Display* /* display */, - GC /* gc */, - int /* ts_x_origin */, - int /* ts_y_origin */ + Display* /* display */, + GC /* gc */, + int /* ts_x_origin */, + int /* ts_y_origin */ ); extern int XSetTile( - Display* /* display */, - GC /* gc */, - Pixmap /* tile */ + Display* /* display */, + GC /* gc */, + Pixmap /* tile */ ); extern int XSetWindowBackground( - Display* /* display */, - Window /* w */, - unsigned long /* background_pixel */ + Display* /* display */, + Window /* w */, + unsigned long /* background_pixel */ ); extern int XSetWindowBackgroundPixmap( - Display* /* display */, - Window /* w */, - Pixmap /* background_pixmap */ + Display* /* display */, + Window /* w */, + Pixmap /* background_pixmap */ ); extern int XSetWindowBorder( - Display* /* display */, - Window /* w */, - unsigned long /* border_pixel */ + Display* /* display */, + Window /* w */, + unsigned long /* border_pixel */ ); extern int XSetWindowBorderPixmap( - Display* /* display */, - Window /* w */, - Pixmap /* border_pixmap */ + Display* /* display */, + Window /* w */, + Pixmap /* border_pixmap */ ); extern int XSetWindowBorderWidth( - Display* /* display */, - Window /* w */, - unsigned int /* width */ + Display* /* display */, + Window /* w */, + unsigned int /* width */ ); extern int XSetWindowColormap( - Display* /* display */, - Window /* w */, - Colormap /* colormap */ + Display* /* display */, + Window /* w */, + Colormap /* colormap */ ); extern int XStoreBuffer( - Display* /* display */, - _Xconst char* /* bytes */, - int /* nbytes */, - int /* buffer */ + Display* /* display */, + _Xconst char* /* bytes */, + int /* nbytes */, + int /* buffer */ ); extern int XStoreBytes( - Display* /* display */, - _Xconst char* /* bytes */, - int /* nbytes */ + Display* /* display */, + _Xconst char* /* bytes */, + int /* nbytes */ ); extern int XStoreColor( - Display* /* display */, - Colormap /* colormap */, - XColor* /* color */ + Display* /* display */, + Colormap /* colormap */, + XColor* /* color */ ); extern int XStoreColors( - Display* /* display */, - Colormap /* colormap */, - XColor* /* color */, - int /* ncolors */ + Display* /* display */, + Colormap /* colormap */, + XColor* /* color */, + int /* ncolors */ ); extern int XStoreName( - Display* /* display */, - Window /* w */, - _Xconst char* /* window_name */ + Display* /* display */, + Window /* w */, + _Xconst char* /* window_name */ ); extern int XStoreNamedColor( - Display* /* display */, - Colormap /* colormap */, - _Xconst char* /* color */, - unsigned long /* pixel */, - int /* flags */ + Display* /* display */, + Colormap /* colormap */, + _Xconst char* /* color */, + unsigned long /* pixel */, + int /* flags */ ); extern int XSync( - Display* /* display */, - Bool /* discard */ + Display* /* display */, + Bool /* discard */ ); extern int XTextExtents( - XFontStruct* /* font_struct */, - _Xconst char* /* string */, - int /* nchars */, - int* /* direction_return */, - int* /* font_ascent_return */, - int* /* font_descent_return */, - XCharStruct* /* overall_return */ + XFontStruct* /* font_struct */, + _Xconst char* /* string */, + int /* nchars */, + int* /* direction_return */, + int* /* font_ascent_return */, + int* /* font_descent_return */, + XCharStruct* /* overall_return */ ); extern int XTextExtents16( - XFontStruct* /* font_struct */, - _Xconst XChar2b* /* string */, - int /* nchars */, - int* /* direction_return */, - int* /* font_ascent_return */, - int* /* font_descent_return */, - XCharStruct* /* overall_return */ + XFontStruct* /* font_struct */, + _Xconst XChar2b* /* string */, + int /* nchars */, + int* /* direction_return */, + int* /* font_ascent_return */, + int* /* font_descent_return */, + XCharStruct* /* overall_return */ ); extern int XTextWidth( - XFontStruct* /* font_struct */, - _Xconst char* /* string */, - int /* count */ + XFontStruct* /* font_struct */, + _Xconst char* /* string */, + int /* count */ ); extern int XTextWidth16( - XFontStruct* /* font_struct */, - _Xconst XChar2b* /* string */, - int /* count */ + XFontStruct* /* font_struct */, + _Xconst XChar2b* /* string */, + int /* count */ ); extern Bool XTranslateCoordinates( - Display* /* display */, - Window /* src_w */, - Window /* dest_w */, - int /* src_x */, - int /* src_y */, - int* /* dest_x_return */, - int* /* dest_y_return */, - Window* /* child_return */ + Display* /* display */, + Window /* src_w */, + Window /* dest_w */, + int /* src_x */, + int /* src_y */, + int* /* dest_x_return */, + int* /* dest_y_return */, + Window* /* child_return */ ); extern int XUndefineCursor( - Display* /* display */, - Window /* w */ + Display* /* display */, + Window /* w */ ); extern int XUngrabButton( - Display* /* display */, - unsigned int /* button */, - unsigned int /* modifiers */, - Window /* grab_window */ + Display* /* display */, + unsigned int /* button */, + unsigned int /* modifiers */, + Window /* grab_window */ ); extern int XUngrabKey( - Display* /* display */, - int /* keycode */, - unsigned int /* modifiers */, - Window /* grab_window */ + Display* /* display */, + int /* keycode */, + unsigned int /* modifiers */, + Window /* grab_window */ ); extern int XUngrabKeyboard( - Display* /* display */, - Time /* time */ + Display* /* display */, + Time /* time */ ); extern int XUngrabPointer( - Display* /* display */, - Time /* time */ + Display* /* display */, + Time /* time */ ); extern int XUngrabServer( - Display* /* display */ + Display* /* display */ ); extern int XUninstallColormap( - Display* /* display */, - Colormap /* colormap */ + Display* /* display */, + Colormap /* colormap */ ); extern int XUnloadFont( - Display* /* display */, - Font /* font */ + Display* /* display */, + Font /* font */ ); extern int XUnmapSubwindows( - Display* /* display */, - Window /* w */ + Display* /* display */, + Window /* w */ ); extern int XUnmapWindow( - Display* /* display */, - Window /* w */ + Display* /* display */, + Window /* w */ ); extern int XVendorRelease( - Display* /* display */ + Display* /* display */ ); extern int XWarpPointer( - Display* /* display */, - Window /* src_w */, - Window /* dest_w */, - int /* src_x */, - int /* src_y */, - unsigned int /* src_width */, - unsigned int /* src_height */, - int /* dest_x */, - int /* dest_y */ + Display* /* display */, + Window /* src_w */, + Window /* dest_w */, + int /* src_x */, + int /* src_y */, + unsigned int /* src_width */, + unsigned int /* src_height */, + int /* dest_x */, + int /* dest_y */ ); extern int XWidthMMOfScreen( - Screen* /* screen */ + Screen* /* screen */ ); extern int XWidthOfScreen( - Screen* /* screen */ + Screen* /* screen */ ); extern int XWindowEvent( - Display* /* display */, - Window /* w */, - long /* event_mask */, - XEvent* /* event_return */ + Display* /* display */, + Window /* w */, + long /* event_mask */, + XEvent* /* event_return */ ); extern int XWriteBitmapFile( - Display* /* display */, - _Xconst char* /* filename */, - Pixmap /* bitmap */, - unsigned int /* width */, - unsigned int /* height */, - int /* x_hot */, - int /* y_hot */ + Display* /* display */, + _Xconst char* /* filename */, + Pixmap /* bitmap */, + unsigned int /* width */, + unsigned int /* height */, + int /* x_hot */, + int /* y_hot */ ); -extern Bool XSupportsLocale (void); +extern Bool XSupportsLocale(void); -extern char *XSetLocaleModifiers( - const char* /* modifier_list */ +extern char* XSetLocaleModifiers( + const char* /* modifier_list */ ); extern XOM XOpenOM( - Display* /* display */, - struct _XrmHashBucketRec* /* rdb */, - _Xconst char* /* res_name */, - _Xconst char* /* res_class */ + Display* /* display */, + struct _XrmHashBucketRec* /* rdb */, + _Xconst char* /* res_name */, + _Xconst char* /* res_class */ ); extern Status XCloseOM( - XOM /* om */ + XOM /* om */ ); -extern char *XSetOMValues( - XOM /* om */, - ... -) _X_SENTINEL(0); +extern char* XSetOMValues( + XOM /* om */, + ...) _X_SENTINEL(0); -extern char *XGetOMValues( - XOM /* om */, - ... -) _X_SENTINEL(0); +extern char* XGetOMValues( + XOM /* om */, + ...) _X_SENTINEL(0); -extern Display *XDisplayOfOM( - XOM /* om */ +extern Display* XDisplayOfOM( + XOM /* om */ ); -extern char *XLocaleOfOM( - XOM /* om */ +extern char* XLocaleOfOM( + XOM /* om */ ); extern XOC XCreateOC( - XOM /* om */, - ... -) _X_SENTINEL(0); + XOM /* om */, + ...) _X_SENTINEL(0); extern void XDestroyOC( - XOC /* oc */ + XOC /* oc */ ); extern XOM XOMOfOC( - XOC /* oc */ + XOC /* oc */ ); -extern char *XSetOCValues( - XOC /* oc */, - ... -) _X_SENTINEL(0); +extern char* XSetOCValues( + XOC /* oc */, + ...) _X_SENTINEL(0); -extern char *XGetOCValues( - XOC /* oc */, - ... -) _X_SENTINEL(0); +extern char* XGetOCValues( + XOC /* oc */, + ...) _X_SENTINEL(0); extern XFontSet XCreateFontSet( - Display* /* display */, - _Xconst char* /* base_font_name_list */, - char*** /* missing_charset_list */, - int* /* missing_charset_count */, - char** /* def_string */ + Display* /* display */, + _Xconst char* /* base_font_name_list */, + char*** /* missing_charset_list */, + int* /* missing_charset_count */, + char** /* def_string */ ); extern void XFreeFontSet( - Display* /* display */, - XFontSet /* font_set */ + Display* /* display */, + XFontSet /* font_set */ ); extern int XFontsOfFontSet( - XFontSet /* font_set */, - XFontStruct*** /* font_struct_list */, - char*** /* font_name_list */ + XFontSet /* font_set */, + XFontStruct*** /* font_struct_list */, + char*** /* font_name_list */ ); -extern char *XBaseFontNameListOfFontSet( - XFontSet /* font_set */ +extern char* XBaseFontNameListOfFontSet( + XFontSet /* font_set */ ); -extern char *XLocaleOfFontSet( - XFontSet /* font_set */ +extern char* XLocaleOfFontSet( + XFontSet /* font_set */ ); extern Bool XContextDependentDrawing( - XFontSet /* font_set */ + XFontSet /* font_set */ ); extern Bool XDirectionalDependentDrawing( - XFontSet /* font_set */ + XFontSet /* font_set */ ); extern Bool XContextualDrawing( - XFontSet /* font_set */ + XFontSet /* font_set */ ); -extern XFontSetExtents *XExtentsOfFontSet( - XFontSet /* font_set */ +extern XFontSetExtents* XExtentsOfFontSet( + XFontSet /* font_set */ ); extern int XmbTextEscapement( - XFontSet /* font_set */, - _Xconst char* /* text */, - int /* bytes_text */ + XFontSet /* font_set */, + _Xconst char* /* text */, + int /* bytes_text */ ); extern int XwcTextEscapement( - XFontSet /* font_set */, - _Xconst wchar_t* /* text */, - int /* num_wchars */ + XFontSet /* font_set */, + _Xconst wchar_t* /* text */, + int /* num_wchars */ ); extern int Xutf8TextEscapement( - XFontSet /* font_set */, - _Xconst char* /* text */, - int /* bytes_text */ + XFontSet /* font_set */, + _Xconst char* /* text */, + int /* bytes_text */ ); extern int XmbTextExtents( - XFontSet /* font_set */, - _Xconst char* /* text */, - int /* bytes_text */, - XRectangle* /* overall_ink_return */, - XRectangle* /* overall_logical_return */ + XFontSet /* font_set */, + _Xconst char* /* text */, + int /* bytes_text */, + XRectangle* /* overall_ink_return */, + XRectangle* /* overall_logical_return */ ); extern int XwcTextExtents( - XFontSet /* font_set */, - _Xconst wchar_t* /* text */, - int /* num_wchars */, - XRectangle* /* overall_ink_return */, - XRectangle* /* overall_logical_return */ + XFontSet /* font_set */, + _Xconst wchar_t* /* text */, + int /* num_wchars */, + XRectangle* /* overall_ink_return */, + XRectangle* /* overall_logical_return */ ); extern int Xutf8TextExtents( - XFontSet /* font_set */, - _Xconst char* /* text */, - int /* bytes_text */, - XRectangle* /* overall_ink_return */, - XRectangle* /* overall_logical_return */ + XFontSet /* font_set */, + _Xconst char* /* text */, + int /* bytes_text */, + XRectangle* /* overall_ink_return */, + XRectangle* /* overall_logical_return */ ); extern Status XmbTextPerCharExtents( - XFontSet /* font_set */, - _Xconst char* /* text */, - int /* bytes_text */, - XRectangle* /* ink_extents_buffer */, - XRectangle* /* logical_extents_buffer */, - int /* buffer_size */, - int* /* num_chars */, - XRectangle* /* overall_ink_return */, - XRectangle* /* overall_logical_return */ + XFontSet /* font_set */, + _Xconst char* /* text */, + int /* bytes_text */, + XRectangle* /* ink_extents_buffer */, + XRectangle* /* logical_extents_buffer */, + int /* buffer_size */, + int* /* num_chars */, + XRectangle* /* overall_ink_return */, + XRectangle* /* overall_logical_return */ ); extern Status XwcTextPerCharExtents( - XFontSet /* font_set */, - _Xconst wchar_t* /* text */, - int /* num_wchars */, - XRectangle* /* ink_extents_buffer */, - XRectangle* /* logical_extents_buffer */, - int /* buffer_size */, - int* /* num_chars */, - XRectangle* /* overall_ink_return */, - XRectangle* /* overall_logical_return */ + XFontSet /* font_set */, + _Xconst wchar_t* /* text */, + int /* num_wchars */, + XRectangle* /* ink_extents_buffer */, + XRectangle* /* logical_extents_buffer */, + int /* buffer_size */, + int* /* num_chars */, + XRectangle* /* overall_ink_return */, + XRectangle* /* overall_logical_return */ ); extern Status Xutf8TextPerCharExtents( - XFontSet /* font_set */, - _Xconst char* /* text */, - int /* bytes_text */, - XRectangle* /* ink_extents_buffer */, - XRectangle* /* logical_extents_buffer */, - int /* buffer_size */, - int* /* num_chars */, - XRectangle* /* overall_ink_return */, - XRectangle* /* overall_logical_return */ + XFontSet /* font_set */, + _Xconst char* /* text */, + int /* bytes_text */, + XRectangle* /* ink_extents_buffer */, + XRectangle* /* logical_extents_buffer */, + int /* buffer_size */, + int* /* num_chars */, + XRectangle* /* overall_ink_return */, + XRectangle* /* overall_logical_return */ ); extern void XmbDrawText( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - XmbTextItem* /* text_items */, - int /* nitems */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + XmbTextItem* /* text_items */, + int /* nitems */ ); extern void XwcDrawText( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - XwcTextItem* /* text_items */, - int /* nitems */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + XwcTextItem* /* text_items */, + int /* nitems */ ); extern void Xutf8DrawText( - Display* /* display */, - Drawable /* d */, - GC /* gc */, - int /* x */, - int /* y */, - XmbTextItem* /* text_items */, - int /* nitems */ + Display* /* display */, + Drawable /* d */, + GC /* gc */, + int /* x */, + int /* y */, + XmbTextItem* /* text_items */, + int /* nitems */ ); extern void XmbDrawString( - Display* /* display */, - Drawable /* d */, - XFontSet /* font_set */, - GC /* gc */, - int /* x */, - int /* y */, - _Xconst char* /* text */, - int /* bytes_text */ + Display* /* display */, + Drawable /* d */, + XFontSet /* font_set */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst char* /* text */, + int /* bytes_text */ ); extern void XwcDrawString( - Display* /* display */, - Drawable /* d */, - XFontSet /* font_set */, - GC /* gc */, - int /* x */, - int /* y */, - _Xconst wchar_t* /* text */, - int /* num_wchars */ + Display* /* display */, + Drawable /* d */, + XFontSet /* font_set */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst wchar_t* /* text */, + int /* num_wchars */ ); extern void Xutf8DrawString( - Display* /* display */, - Drawable /* d */, - XFontSet /* font_set */, - GC /* gc */, - int /* x */, - int /* y */, - _Xconst char* /* text */, - int /* bytes_text */ + Display* /* display */, + Drawable /* d */, + XFontSet /* font_set */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst char* /* text */, + int /* bytes_text */ ); extern void XmbDrawImageString( - Display* /* display */, - Drawable /* d */, - XFontSet /* font_set */, - GC /* gc */, - int /* x */, - int /* y */, - _Xconst char* /* text */, - int /* bytes_text */ + Display* /* display */, + Drawable /* d */, + XFontSet /* font_set */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst char* /* text */, + int /* bytes_text */ ); extern void XwcDrawImageString( - Display* /* display */, - Drawable /* d */, - XFontSet /* font_set */, - GC /* gc */, - int /* x */, - int /* y */, - _Xconst wchar_t* /* text */, - int /* num_wchars */ + Display* /* display */, + Drawable /* d */, + XFontSet /* font_set */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst wchar_t* /* text */, + int /* num_wchars */ ); extern void Xutf8DrawImageString( - Display* /* display */, - Drawable /* d */, - XFontSet /* font_set */, - GC /* gc */, - int /* x */, - int /* y */, - _Xconst char* /* text */, - int /* bytes_text */ + Display* /* display */, + Drawable /* d */, + XFontSet /* font_set */, + GC /* gc */, + int /* x */, + int /* y */, + _Xconst char* /* text */, + int /* bytes_text */ ); extern XIM XOpenIM( - Display* /* dpy */, - struct _XrmHashBucketRec* /* rdb */, - char* /* res_name */, - char* /* res_class */ + Display* /* dpy */, + struct _XrmHashBucketRec* /* rdb */, + char* /* res_name */, + char* /* res_class */ ); extern Status XCloseIM( - XIM /* im */ + XIM /* im */ ); -extern char *XGetIMValues( - XIM /* im */, ... -) _X_SENTINEL(0); +extern char* XGetIMValues( + XIM /* im */, ...) _X_SENTINEL(0); -extern char *XSetIMValues( - XIM /* im */, ... -) _X_SENTINEL(0); +extern char* XSetIMValues( + XIM /* im */, ...) _X_SENTINEL(0); -extern Display *XDisplayOfIM( - XIM /* im */ +extern Display* XDisplayOfIM( + XIM /* im */ ); -extern char *XLocaleOfIM( - XIM /* im*/ +extern char* XLocaleOfIM( + XIM /* im*/ ); extern XIC XCreateIC( - XIM /* im */, ... -) _X_SENTINEL(0); + XIM /* im */, ...) _X_SENTINEL(0); extern void XDestroyIC( - XIC /* ic */ + XIC /* ic */ ); extern void XSetICFocus( - XIC /* ic */ + XIC /* ic */ ); extern void XUnsetICFocus( - XIC /* ic */ + XIC /* ic */ ); -extern wchar_t *XwcResetIC( - XIC /* ic */ +extern wchar_t* XwcResetIC( + XIC /* ic */ ); -extern char *XmbResetIC( - XIC /* ic */ +extern char* XmbResetIC( + XIC /* ic */ ); -extern char *Xutf8ResetIC( - XIC /* ic */ +extern char* Xutf8ResetIC( + XIC /* ic */ ); -extern char *XSetICValues( - XIC /* ic */, ... -) _X_SENTINEL(0); +extern char* XSetICValues( + XIC /* ic */, ...) _X_SENTINEL(0); -extern char *XGetICValues( - XIC /* ic */, ... -) _X_SENTINEL(0); +extern char* XGetICValues( + XIC /* ic */, ...) _X_SENTINEL(0); extern XIM XIMOfIC( - XIC /* ic */ + XIC /* ic */ ); extern Bool XFilterEvent( - XEvent* /* event */, - Window /* window */ + XEvent* /* event */, + Window /* window */ ); extern int XmbLookupString( - XIC /* ic */, - XKeyPressedEvent* /* event */, - char* /* buffer_return */, - int /* bytes_buffer */, - KeySym* /* keysym_return */, - Status* /* status_return */ + XIC /* ic */, + XKeyPressedEvent* /* event */, + char* /* buffer_return */, + int /* bytes_buffer */, + KeySym* /* keysym_return */, + Status* /* status_return */ ); extern int XwcLookupString( - XIC /* ic */, - XKeyPressedEvent* /* event */, - wchar_t* /* buffer_return */, - int /* wchars_buffer */, - KeySym* /* keysym_return */, - Status* /* status_return */ + XIC /* ic */, + XKeyPressedEvent* /* event */, + wchar_t* /* buffer_return */, + int /* wchars_buffer */, + KeySym* /* keysym_return */, + Status* /* status_return */ ); extern int Xutf8LookupString( - XIC /* ic */, - XKeyPressedEvent* /* event */, - char* /* buffer_return */, - int /* bytes_buffer */, - KeySym* /* keysym_return */, - Status* /* status_return */ + XIC /* ic */, + XKeyPressedEvent* /* event */, + char* /* buffer_return */, + int /* bytes_buffer */, + KeySym* /* keysym_return */, + Status* /* status_return */ ); extern XVaNestedList XVaCreateNestedList( - int /*unused*/, ... -) _X_SENTINEL(0); + int /*unused*/, ...) _X_SENTINEL(0); /* internal connections for IMs */ extern Bool XRegisterIMInstantiateCallback( - Display* /* dpy */, - struct _XrmHashBucketRec* /* rdb */, - char* /* res_name */, - char* /* res_class */, - XIDProc /* callback */, - XPointer /* client_data */ + Display* /* dpy */, + struct _XrmHashBucketRec* /* rdb */, + char* /* res_name */, + char* /* res_class */, + XIDProc /* callback */, + XPointer /* client_data */ ); extern Bool XUnregisterIMInstantiateCallback( - Display* /* dpy */, - struct _XrmHashBucketRec* /* rdb */, - char* /* res_name */, - char* /* res_class */, - XIDProc /* callback */, - XPointer /* client_data */ + Display* /* dpy */, + struct _XrmHashBucketRec* /* rdb */, + char* /* res_name */, + char* /* res_class */, + XIDProc /* callback */, + XPointer /* client_data */ ); typedef void (*XConnectionWatchProc)( - Display* /* dpy */, - XPointer /* client_data */, - int /* fd */, - Bool /* opening */, /* open or close flag */ - XPointer* /* watch_data */ /* open sets, close uses */ + Display* /* dpy */, + XPointer /* client_data */, + int /* fd */, + Bool /* opening */, /* open or close flag */ + XPointer* /* watch_data */ /* open sets, close uses */ ); - extern Status XInternalConnectionNumbers( - Display* /* dpy */, - int** /* fd_return */, - int* /* count_return */ + Display* /* dpy */, + int** /* fd_return */, + int* /* count_return */ ); extern void XProcessInternalConnection( - Display* /* dpy */, - int /* fd */ + Display* /* dpy */, + int /* fd */ ); extern Status XAddConnectionWatch( - Display* /* dpy */, - XConnectionWatchProc /* callback */, - XPointer /* client_data */ + Display* /* dpy */, + XConnectionWatchProc /* callback */, + XPointer /* client_data */ ); extern void XRemoveConnectionWatch( - Display* /* dpy */, - XConnectionWatchProc /* callback */, - XPointer /* client_data */ + Display* /* dpy */, + XConnectionWatchProc /* callback */, + XPointer /* client_data */ ); extern void XSetAuthorization( - char * /* name */, - int /* namelen */, - char * /* data */, - int /* datalen */ + char* /* name */, + int /* namelen */, + char* /* data */, + int /* datalen */ ); extern int _Xmbtowc( - wchar_t * /* wstr */, + wchar_t* /* wstr */, #ifdef ISC - char const * /* str */, - size_t /* len */ + char const* /* str */, + size_t /* len */ #else - char * /* str */, - int /* len */ + char* /* str */, + int /* len */ #endif ); extern int _Xwctomb( - char * /* str */, - wchar_t /* wc */ + char* /* str */, + wchar_t /* wc */ ); extern Bool XGetEventData( - Display* /* dpy */, - XGenericEventCookie* /* cookie*/ + Display* /* dpy */, + XGenericEventCookie* /* cookie*/ ); extern void XFreeEventData( - Display* /* dpy */, - XGenericEventCookie* /* cookie*/ + Display* /* dpy */, + XGenericEventCookie* /* cookie*/ ); #ifdef __clang__ diff --git a/examples/ThirdPartyLibs/optionalX11/X11/Xlibint.h b/examples/ThirdPartyLibs/optionalX11/X11/Xlibint.h index 443155964..f46bd1bdf 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/Xlibint.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/Xlibint.h @@ -39,8 +39,8 @@ from The Open Group. */ #include -#include /* to declare xEvent */ -#include /* for configured options like XTHREADS */ +#include /* to declare xEvent */ +#include /* for configured options like XTHREADS */ /* The Xlib structs are full of implicit padding to properly align members. We can't clean that up without breaking ABI, so tell clang not to bother @@ -64,67 +64,66 @@ from The Open Group. struct _XGC { - XExtData *ext_data; /* hook for extension to hang data */ - GContext gid; /* protocol ID for graphics context */ - Bool rects; /* boolean: TRUE if clipmask is list of rectangles */ - Bool dashes; /* boolean: TRUE if dash-list is really a list */ - unsigned long dirty;/* cache dirty bits */ - XGCValues values; /* shadow structure of values */ + XExtData* ext_data; /* hook for extension to hang data */ + GContext gid; /* protocol ID for graphics context */ + Bool rects; /* boolean: TRUE if clipmask is list of rectangles */ + Bool dashes; /* boolean: TRUE if dash-list is really a list */ + unsigned long dirty; /* cache dirty bits */ + XGCValues values; /* shadow structure of values */ }; struct _XDisplay { - XExtData *ext_data; /* hook for extension to hang data */ - struct _XFreeFuncs *free_funcs; /* internal free functions */ - int fd; /* Network socket. */ - int conn_checker; /* ugly thing used by _XEventsQueued */ - int proto_major_version;/* maj. version of server's X protocol */ - int proto_minor_version;/* minor version of server's X protocol */ - char *vendor; /* vendor of the server hardware */ - XID resource_base; /* resource ID base */ - XID resource_mask; /* resource ID mask bits */ - XID resource_id; /* allocator current ID */ - int resource_shift; /* allocator shift to correct bits */ - XID (*resource_alloc)( /* allocator function */ - struct _XDisplay* - ); - int byte_order; /* screen byte order, LSBFirst, MSBFirst */ - int bitmap_unit; /* padding and data requirements */ - int bitmap_pad; /* padding requirements on bitmaps */ - int bitmap_bit_order; /* LeastSignificant or MostSignificant */ - int nformats; /* number of pixmap formats in list */ - ScreenFormat *pixmap_format; /* pixmap format list */ - int vnumber; /* Xlib's X protocol version number. */ - int release; /* release of the server */ - struct _XSQEvent *head, *tail; /* Input event queue. */ - int qlen; /* Length of input event queue */ + XExtData* ext_data; /* hook for extension to hang data */ + struct _XFreeFuncs* free_funcs; /* internal free functions */ + int fd; /* Network socket. */ + int conn_checker; /* ugly thing used by _XEventsQueued */ + int proto_major_version; /* maj. version of server's X protocol */ + int proto_minor_version; /* minor version of server's X protocol */ + char* vendor; /* vendor of the server hardware */ + XID resource_base; /* resource ID base */ + XID resource_mask; /* resource ID mask bits */ + XID resource_id; /* allocator current ID */ + int resource_shift; /* allocator shift to correct bits */ + XID(*resource_alloc) + (/* allocator function */ + struct _XDisplay*); + int byte_order; /* screen byte order, LSBFirst, MSBFirst */ + int bitmap_unit; /* padding and data requirements */ + int bitmap_pad; /* padding requirements on bitmaps */ + int bitmap_bit_order; /* LeastSignificant or MostSignificant */ + int nformats; /* number of pixmap formats in list */ + ScreenFormat* pixmap_format; /* pixmap format list */ + int vnumber; /* Xlib's X protocol version number. */ + int release; /* release of the server */ + struct _XSQEvent *head, *tail; /* Input event queue. */ + int qlen; /* Length of input event queue */ unsigned long last_request_read; /* seq number of last event read */ - unsigned long request; /* sequence number of last request. */ - char *last_req; /* beginning of last request, or dummy */ - char *buffer; /* Output buffer starting address. */ - char *bufptr; /* Output buffer index pointer. */ - char *bufmax; /* Output buffer maximum+1 address. */ - unsigned max_request_size; /* maximum number 32 bit words in request*/ - struct _XrmHashBucketRec *db; - int (*synchandler)( /* Synchronization handler */ - struct _XDisplay* - ); - char *display_name; /* "host:display" string used on this connect*/ - int default_screen; /* default screen for operations */ - int nscreens; /* number of screens on this server*/ - Screen *screens; /* pointer to list of screens */ - unsigned long motion_buffer; /* size of motion buffer */ - volatile unsigned long flags; /* internal connection flags */ - int min_keycode; /* minimum defined keycode */ - int max_keycode; /* maximum defined keycode */ - KeySym *keysyms; /* This server's keysyms */ - XModifierKeymap *modifiermap; /* This server's modifier keymap */ - int keysyms_per_keycode;/* number of rows */ - char *xdefaults; /* contents of defaults from server */ - char *scratch_buffer; /* place to hang scratch buffer */ - unsigned long scratch_length; /* length of scratch buffer */ - int ext_number; /* extension number on this display */ - struct _XExten *ext_procs; /* extensions initialized on this display */ + unsigned long request; /* sequence number of last request. */ + char* last_req; /* beginning of last request, or dummy */ + char* buffer; /* Output buffer starting address. */ + char* bufptr; /* Output buffer index pointer. */ + char* bufmax; /* Output buffer maximum+1 address. */ + unsigned max_request_size; /* maximum number 32 bit words in request*/ + struct _XrmHashBucketRec* db; + int (*synchandler)(/* Synchronization handler */ + struct _XDisplay*); + char* display_name; /* "host:display" string used on this connect*/ + int default_screen; /* default screen for operations */ + int nscreens; /* number of screens on this server*/ + Screen* screens; /* pointer to list of screens */ + unsigned long motion_buffer; /* size of motion buffer */ + volatile unsigned long flags; /* internal connection flags */ + int min_keycode; /* minimum defined keycode */ + int max_keycode; /* maximum defined keycode */ + KeySym* keysyms; /* This server's keysyms */ + XModifierKeymap* modifiermap; /* This server's modifier keymap */ + int keysyms_per_keycode; /* number of rows */ + char* xdefaults; /* contents of defaults from server */ + char* scratch_buffer; /* place to hang scratch buffer */ + unsigned long scratch_length; /* length of scratch buffer */ + int ext_number; /* extension number on this display */ + struct _XExten* ext_procs; /* extensions initialized on this display */ /* * the following can be fixed size, as the protocol defines how * much address space is available. @@ -133,81 +132,82 @@ struct _XDisplay * list to find the right procedure for each event might be * expensive if many extensions are being used. */ - Bool (*event_vec[128])( /* vector for wire to event */ - Display * /* dpy */, - XEvent * /* re */, - xEvent * /* event */ - ); - Status (*wire_vec[128])( /* vector for event to wire */ - Display * /* dpy */, - XEvent * /* re */, - xEvent * /* event */ - ); - KeySym lock_meaning; /* for XLookupString */ - struct _XLockInfo *lock; /* multi-thread state, display lock */ - struct _XInternalAsync *async_handlers; /* for internal async */ - unsigned long bigreq_size; /* max size of big requests */ - struct _XLockPtrs *lock_fns; /* pointers to threads functions */ - void (*idlist_alloc)( /* XID list allocator function */ - Display * /* dpy */, - XID * /* ids */, - int /* count */ - ); + Bool (*event_vec[128])(/* vector for wire to event */ + Display* /* dpy */, + XEvent* /* re */, + xEvent* /* event */ + ); + Status (*wire_vec[128])(/* vector for event to wire */ + Display* /* dpy */, + XEvent* /* re */, + xEvent* /* event */ + ); + KeySym lock_meaning; /* for XLookupString */ + struct _XLockInfo* lock; /* multi-thread state, display lock */ + struct _XInternalAsync* async_handlers; /* for internal async */ + unsigned long bigreq_size; /* max size of big requests */ + struct _XLockPtrs* lock_fns; /* pointers to threads functions */ + void (*idlist_alloc)( /* XID list allocator function */ + Display* /* dpy */, + XID* /* ids */, + int /* count */ + ); /* things above this line should not move, for binary compatibility */ - struct _XKeytrans *key_bindings; /* for XLookupString */ - Font cursor_font; /* for XCreateFontCursor */ - struct _XDisplayAtoms *atoms; /* for XInternAtom */ - unsigned int mode_switch; /* keyboard group modifiers */ - unsigned int num_lock; /* keyboard numlock modifiers */ - struct _XContextDB *context_db; /* context database */ - Bool (**error_vec)( /* vector for wire to error */ - Display * /* display */, - XErrorEvent * /* he */, - xError * /* we */ - ); + struct _XKeytrans* key_bindings; /* for XLookupString */ + Font cursor_font; /* for XCreateFontCursor */ + struct _XDisplayAtoms* atoms; /* for XInternAtom */ + unsigned int mode_switch; /* keyboard group modifiers */ + unsigned int num_lock; /* keyboard numlock modifiers */ + struct _XContextDB* context_db; /* context database */ + Bool (**error_vec)( /* vector for wire to error */ + Display* /* display */, + XErrorEvent* /* he */, + xError* /* we */ + ); /* * Xcms information */ - struct { - XPointer defaultCCCs; /* pointer to an array of default XcmsCCC */ - XPointer clientCmaps; /* pointer to linked list of XcmsCmapRec */ - XPointer perVisualIntensityMaps; - /* linked list of XcmsIntensityMap */ + struct + { + XPointer defaultCCCs; /* pointer to an array of default XcmsCCC */ + XPointer clientCmaps; /* pointer to linked list of XcmsCmapRec */ + XPointer perVisualIntensityMaps; + /* linked list of XcmsIntensityMap */ } cms; - struct _XIMFilter *im_filters; - struct _XSQEvent *qfree; /* unallocated event queue elements */ - unsigned long next_event_serial_num; /* inserted into next queue elt */ - struct _XExten *flushes; /* Flush hooks */ - struct _XConnectionInfo *im_fd_info; /* _XRegisterInternalConnection */ - int im_fd_length; /* number of im_fd_info */ - struct _XConnWatchInfo *conn_watchers; /* XAddConnectionWatch */ - int watcher_count; /* number of conn_watchers */ - XPointer filedes; /* struct pollfd cache for _XWaitForReadable */ - int (*savedsynchandler)( /* user synchandler when Xlib usurps */ - Display * /* dpy */ - ); - XID resource_max; /* allocator max ID */ - int xcmisc_opcode; /* major opcode for XC-MISC */ - struct _XkbInfoRec *xkb_info; /* XKB info */ - struct _XtransConnInfo *trans_conn; /* transport connection object */ - struct _X11XCBPrivate *xcb; /* XCB glue private data */ + struct _XIMFilter* im_filters; + struct _XSQEvent* qfree; /* unallocated event queue elements */ + unsigned long next_event_serial_num; /* inserted into next queue elt */ + struct _XExten* flushes; /* Flush hooks */ + struct _XConnectionInfo* im_fd_info; /* _XRegisterInternalConnection */ + int im_fd_length; /* number of im_fd_info */ + struct _XConnWatchInfo* conn_watchers; /* XAddConnectionWatch */ + int watcher_count; /* number of conn_watchers */ + XPointer filedes; /* struct pollfd cache for _XWaitForReadable */ + int (*savedsynchandler)( /* user synchandler when Xlib usurps */ + Display* /* dpy */ + ); + XID resource_max; /* allocator max ID */ + int xcmisc_opcode; /* major opcode for XC-MISC */ + struct _XkbInfoRec* xkb_info; /* XKB info */ + struct _XtransConnInfo* trans_conn; /* transport connection object */ + struct _X11XCBPrivate* xcb; /* XCB glue private data */ /* Generic event cookie handling */ unsigned int next_cookie; /* next event cookie */ /* vector for wire to generic event, index is (extension - 128) */ Bool (*generic_event_vec[128])( - Display * /* dpy */, - XGenericEventCookie * /* Xlib event */, - xEvent * /* wire event */); + Display* /* dpy */, + XGenericEventCookie* /* Xlib event */, + xEvent* /* wire event */); /* vector for event copy, index is (extension - 128) */ Bool (*generic_event_copy_vec[128])( - Display * /* dpy */, - XGenericEventCookie * /* in */, - XGenericEventCookie * /* out*/); - void *cookiejar; /* cookie events returned but not claimed */ + Display* /* dpy */, + XGenericEventCookie* /* in */, + XGenericEventCookie* /* out*/); + void* cookiejar; /* cookie events returned but not claimed */ }; -#define XAllocIDs(dpy,ids,n) (*(dpy)->idlist_alloc)(dpy,ids,n) +#define XAllocIDs(dpy, ids, n) (*(dpy)->idlist_alloc)(dpy, ids, n) #ifndef _XEVENT_ /* @@ -215,15 +215,15 @@ struct _XDisplay */ typedef struct _XSQEvent { - struct _XSQEvent *next; - XEvent event; - unsigned long qserial_num; /* so multi-threaded code can find new ones */ + struct _XSQEvent* next; + XEvent event; + unsigned long qserial_num; /* so multi-threaded code can find new ones */ } _XQEvent; #endif #include #ifdef __sgi -#define _SGI_MP_SOURCE /* turn this on to get MP safe errno */ +#define _SGI_MP_SOURCE /* turn this on to get MP safe errno */ #endif #include #define _XBCOPYFUNC _Xbcopy @@ -252,23 +252,24 @@ _XFUNCPROTOBEGIN * declarations for C Threads locking */ -typedef struct _LockInfoRec *LockInfoPtr; +typedef struct _LockInfoRec* LockInfoPtr; /* interfaces for locking.c */ -struct _XLockPtrs { - /* used by all, including extensions; do not move */ - void (*lock_display)( - Display *dpy +struct _XLockPtrs +{ + /* used by all, including extensions; do not move */ + void (*lock_display)( + Display* dpy #if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) - , char *file - , int line + , + char* file, int line #endif ); - void (*unlock_display)( - Display *dpy + void (*unlock_display)( + Display* dpy #if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) - , char *file - , int line + , + char* file, int line #endif ); }; @@ -283,42 +284,56 @@ struct _XLockPtrs { /* in XlibInt.c */ extern void (*_XCreateMutex_fn)( - LockInfoPtr /* lock */ + LockInfoPtr /* lock */ ); extern void (*_XFreeMutex_fn)( - LockInfoPtr /* lock */ + LockInfoPtr /* lock */ ); extern void (*_XLockMutex_fn)( - LockInfoPtr /* lock */ + LockInfoPtr /* lock */ #if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) - , char * /* file */ - , int /* line */ + , + char* /* file */ + , + int /* line */ #endif ); extern void (*_XUnlockMutex_fn)( - LockInfoPtr /* lock */ + LockInfoPtr /* lock */ #if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) - , char * /* file */ - , int /* line */ + , + char* /* file */ + , + int /* line */ #endif ); extern LockInfoPtr _Xglobal_lock; #if defined(XTHREADS_WARN) || defined(XTHREADS_FILE_LINE) -#define LockDisplay(d) if ((d)->lock_fns) (*(d)->lock_fns->lock_display)((d),__FILE__,__LINE__) -#define UnlockDisplay(d) if ((d)->lock_fns) (*(d)->lock_fns->unlock_display)((d),__FILE__,__LINE__) -#define _XLockMutex(lock) if (_XLockMutex_fn) (*_XLockMutex_fn)(lock,__FILE__,__LINE__) -#define _XUnlockMutex(lock) if (_XUnlockMutex_fn) (*_XUnlockMutex_fn)(lock,__FILE__,__LINE__) +#define LockDisplay(d) \ + if ((d)->lock_fns) (*(d)->lock_fns->lock_display)((d), __FILE__, __LINE__) +#define UnlockDisplay(d) \ + if ((d)->lock_fns) (*(d)->lock_fns->unlock_display)((d), __FILE__, __LINE__) +#define _XLockMutex(lock) \ + if (_XLockMutex_fn) (*_XLockMutex_fn)(lock, __FILE__, __LINE__) +#define _XUnlockMutex(lock) \ + if (_XUnlockMutex_fn) (*_XUnlockMutex_fn)(lock, __FILE__, __LINE__) #else /* used everywhere, so must be fast if not using threads */ -#define LockDisplay(d) if ((d)->lock_fns) (*(d)->lock_fns->lock_display)(d) -#define UnlockDisplay(d) if ((d)->lock_fns) (*(d)->lock_fns->unlock_display)(d) -#define _XLockMutex(lock) if (_XLockMutex_fn) (*_XLockMutex_fn)(lock) -#define _XUnlockMutex(lock) if (_XUnlockMutex_fn) (*_XUnlockMutex_fn)(lock) +#define LockDisplay(d) \ + if ((d)->lock_fns) (*(d)->lock_fns->lock_display)(d) +#define UnlockDisplay(d) \ + if ((d)->lock_fns) (*(d)->lock_fns->unlock_display)(d) +#define _XLockMutex(lock) \ + if (_XLockMutex_fn) (*_XLockMutex_fn)(lock) +#define _XUnlockMutex(lock) \ + if (_XUnlockMutex_fn) (*_XUnlockMutex_fn)(lock) #endif -#define _XCreateMutex(lock) if (_XCreateMutex_fn) (*_XCreateMutex_fn)(lock); -#define _XFreeMutex(lock) if (_XFreeMutex_fn) (*_XFreeMutex_fn)(lock); +#define _XCreateMutex(lock) \ + if (_XCreateMutex_fn) (*_XCreateMutex_fn)(lock); +#define _XFreeMutex(lock) \ + if (_XFreeMutex_fn) (*_XFreeMutex_fn)(lock); #else /* XTHREADS */ #define LockDisplay(dis) @@ -339,15 +354,15 @@ extern LockInfoPtr _Xglobal_lock; */ #if defined(MALLOC_0_RETURNS_NULL) || defined(__clang_analyzer__) -# define Xmalloc(size) malloc(((size) == 0 ? 1 : (size))) -# define Xrealloc(ptr, size) realloc((ptr), ((size) == 0 ? 1 : (size))) -# define Xcalloc(nelem, elsize) calloc(((nelem) == 0 ? 1 : (nelem)), (elsize)) +#define Xmalloc(size) malloc(((size) == 0 ? 1 : (size))) +#define Xrealloc(ptr, size) realloc((ptr), ((size) == 0 ? 1 : (size))) +#define Xcalloc(nelem, elsize) calloc(((nelem) == 0 ? 1 : (nelem)), (elsize)) #else -# define Xmalloc(size) malloc((size)) -# define Xrealloc(ptr, size) realloc((ptr), (size)) -# define Xcalloc(nelem, elsize) calloc((nelem), (elsize)) +#define Xmalloc(size) malloc((size)) +#define Xrealloc(ptr, size) realloc((ptr), (size)) +#define Xcalloc(nelem, elsize) calloc((nelem), (elsize)) #endif @@ -357,45 +372,45 @@ extern LockInfoPtr _Xglobal_lock; #define UNLOCKED 0 #ifndef BUFSIZE -#define BUFSIZE 2048 /* X output buffer size. */ +#define BUFSIZE 2048 /* X output buffer size. */ #endif #ifndef PTSPERBATCH -#define PTSPERBATCH 1024 /* point batching */ +#define PTSPERBATCH 1024 /* point batching */ #endif #ifndef WLNSPERBATCH -#define WLNSPERBATCH 50 /* wide line batching */ +#define WLNSPERBATCH 50 /* wide line batching */ #endif #ifndef ZLNSPERBATCH -#define ZLNSPERBATCH 1024 /* thin line batching */ +#define ZLNSPERBATCH 1024 /* thin line batching */ #endif #ifndef WRCTSPERBATCH -#define WRCTSPERBATCH 10 /* wide line rectangle batching */ +#define WRCTSPERBATCH 10 /* wide line rectangle batching */ #endif #ifndef ZRCTSPERBATCH -#define ZRCTSPERBATCH 256 /* thin line rectangle batching */ +#define ZRCTSPERBATCH 256 /* thin line rectangle batching */ #endif #ifndef FRCTSPERBATCH -#define FRCTSPERBATCH 256 /* filled rectangle batching */ +#define FRCTSPERBATCH 256 /* filled rectangle batching */ #endif #ifndef FARCSPERBATCH -#define FARCSPERBATCH 256 /* filled arc batching */ +#define FARCSPERBATCH 256 /* filled arc batching */ #endif #ifndef CURSORFONT -#define CURSORFONT "cursor" /* standard cursor fonts */ +#define CURSORFONT "cursor" /* standard cursor fonts */ #endif /* * Display flags */ -#define XlibDisplayIOError (1L << 0) -#define XlibDisplayClosing (1L << 1) -#define XlibDisplayNoXkb (1L << 2) -#define XlibDisplayPrivSync (1L << 3) -#define XlibDisplayProcConni (1L << 4) /* in _XProcessInternalConnection */ -#define XlibDisplayReadEvents (1L << 5) /* in _XReadEvents */ -#define XlibDisplayReply (1L << 5) /* in _XReply */ -#define XlibDisplayWriting (1L << 6) /* in _XFlushInt, _XSend */ -#define XlibDisplayDfltRMDB (1L << 7) /* mark if RM db from XGetDefault */ +#define XlibDisplayIOError (1L << 0) +#define XlibDisplayClosing (1L << 1) +#define XlibDisplayNoXkb (1L << 2) +#define XlibDisplayPrivSync (1L << 3) +#define XlibDisplayProcConni (1L << 4) /* in _XProcessInternalConnection */ +#define XlibDisplayReadEvents (1L << 5) /* in _XReadEvents */ +#define XlibDisplayReply (1L << 5) /* in _XReply */ +#define XlibDisplayWriting (1L << 6) /* in _XFlushInt, _XSend */ +#define XlibDisplayDfltRMDB (1L << 7) /* mark if RM db from XGetDefault */ /* * X Protocol packetizing macros. @@ -415,13 +430,13 @@ extern LockInfoPtr _Xglobal_lock; * @returns A pointer to the request buffer with a few default values * initialized. */ -extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); +extern void* _XGetRequest(Display* dpy, CARD8 type, size_t len); /* GetReqSized is the same as GetReq but allows the caller to specify the * size in bytes. 'sz' must be a multiple of 4! */ #define GetReqSized(name, sz, req) \ - req = (x##name##Req *) _XGetRequest(dpy, X_##name, sz) + req = (x##name##Req*)_XGetRequest(dpy, X_##name, sz) /* * GetReq - Get the next available X request packet in the buffer and @@ -439,7 +454,7 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); bytes after the request. "n" must be a multiple of 4! */ #define GetReqExtra(name, n, req) \ - GetReqSized(name, SIZEOF(x##name##Req) + n, req) + GetReqSized(name, SIZEOF(x##name##Req) + n, req) /* * GetResReq is for those requests that have a resource ID @@ -447,8 +462,8 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); * "rid" is the name of the resource. */ -#define GetResReq(name, rid, req) \ - req = (xResourceReq *) _XGetRequest(dpy, X_##name, SIZEOF(xResourceReq)); \ +#define GetResReq(name, rid, req) \ + req = (xResourceReq*)_XGetRequest(dpy, X_##name, SIZEOF(xResourceReq)); \ req->id = (rid) /* @@ -457,7 +472,7 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); */ #define GetEmptyReq(name, req) \ - req = (xReq *) _XGetRequest(dpy, X_##name, SIZEOF(xReq)) + req = (xReq*)_XGetRequest(dpy, X_##name, SIZEOF(xReq)) /* * MakeBigReq sets the CARD16 "req->length" to 0 and inserts a new CARD32 @@ -468,27 +483,27 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); * req->length must already be >= 2. */ #ifdef LONG64 -#define MakeBigReq(req,n) \ - { \ - CARD64 _BRdat; \ - CARD32 _BRlen = req->length - 1; \ - req->length = 0; \ - _BRdat = ((CARD32 *)req)[_BRlen]; \ - memmove(((char *)req) + 8, ((char *)req) + 4, (_BRlen - 1) << 2); \ - ((CARD32 *)req)[1] = _BRlen + n + 2; \ - Data32(dpy, &_BRdat, 4); \ - } +#define MakeBigReq(req, n) \ + { \ + CARD64 _BRdat; \ + CARD32 _BRlen = req->length - 1; \ + req->length = 0; \ + _BRdat = ((CARD32*)req)[_BRlen]; \ + memmove(((char*)req) + 8, ((char*)req) + 4, (_BRlen - 1) << 2); \ + ((CARD32*)req)[1] = _BRlen + n + 2; \ + Data32(dpy, &_BRdat, 4); \ + } #else -#define MakeBigReq(req,n) \ - { \ - CARD32 _BRdat; \ - CARD32 _BRlen = req->length - 1; \ - req->length = 0; \ - _BRdat = ((CARD32 *)req)[_BRlen]; \ - memmove(((char *)req) + 8, ((char *)req) + 4, (_BRlen - 1) << 2); \ - ((CARD32 *)req)[1] = _BRlen + n + 2; \ - Data32(dpy, &_BRdat, 4); \ - } +#define MakeBigReq(req, n) \ + { \ + CARD32 _BRdat; \ + CARD32 _BRlen = req->length - 1; \ + req->length = 0; \ + _BRdat = ((CARD32*)req)[_BRlen]; \ + memmove(((char*)req) + 8, ((char*)req) + 4, (_BRlen - 1) << 2); \ + ((CARD32*)req)[1] = _BRlen + n + 2; \ + Data32(dpy, &_BRdat, 4); \ + } #endif /* @@ -499,25 +514,30 @@ extern void *_XGetRequest(Display *dpy, CARD8 type, size_t len); * xReq header. req->length must already be >= 2. */ #ifndef __clang_analyzer__ -#define SetReqLen(req,n,badlen) \ - if ((req->length + n) > (unsigned)65535) { \ - if (dpy->bigreq_size) { \ - MakeBigReq(req,n) \ - } else { \ - n = badlen; \ - req->length += n; \ - } \ - } else \ - req->length += n +#define SetReqLen(req, n, badlen) \ + if ((req->length + n) > (unsigned)65535) \ + { \ + if (dpy->bigreq_size) \ + { \ + MakeBigReq(req, n) \ + } \ + else \ + { \ + n = badlen; \ + req->length += n; \ + } \ + } \ + else \ + req->length += n #else -#define SetReqLen(req,n,badlen) \ - req->length += n +#define SetReqLen(req, n, badlen) \ + req->length += n #endif #define SyncHandle() \ if (dpy->synchandler) (*dpy->synchandler)(dpy) -extern void _XFlushGCCache(Display *dpy, GC gc); +extern void _XFlushGCCache(Display* dpy, GC gc); #define FlushGC(dpy, gc) \ if ((gc)->dirty) _XFlushGCCache((dpy), (gc)) /* @@ -529,16 +549,18 @@ extern void _XFlushGCCache(Display *dpy, GC gc); * "len" is the length of the data buffer. */ #ifndef DataRoutineIsProcedure -#define Data(dpy, data, len) {\ - if (dpy->bufptr + (len) <= dpy->bufmax) {\ - memcpy(dpy->bufptr, data, (int)len);\ - dpy->bufptr += ((len) + 3) & ~3;\ - } else\ - _XSend(dpy, data, len);\ -} +#define Data(dpy, data, len) \ + { \ + if (dpy->bufptr + (len) <= dpy->bufmax) \ + { \ + memcpy(dpy->bufptr, data, (int)len); \ + dpy->bufptr += ((len) + 3) & ~3; \ + } \ + else \ + _XSend(dpy, data, len); \ + } #endif /* DataRoutineIsProcedure */ - /* Allocate bytes from the buffer. No padding is done, so if * the length is not a multiple of 4, the caller must be * careful to leave the buffer aligned after sending the @@ -553,45 +575,43 @@ extern void _XFlushGCCache(Display *dpy, GC gc); * BufAlloc (xTextElt *, elt, nbytes) */ -#define BufAlloc(type, ptr, n) \ - if (dpy->bufptr + (n) > dpy->bufmax) \ - _XFlush (dpy); \ - ptr = (type) dpy->bufptr; \ - memset(ptr, '\0', n); \ - dpy->bufptr += (n); +#define BufAlloc(type, ptr, n) \ + if (dpy->bufptr + (n) > dpy->bufmax) \ + _XFlush(dpy); \ + ptr = (type)dpy->bufptr; \ + memset(ptr, '\0', n); \ + dpy->bufptr += (n); -#define Data16(dpy, data, len) Data((dpy), (_Xconst char *)(data), (len)) -#define _XRead16Pad(dpy, data, len) _XReadPad((dpy), (char *)(data), (len)) -#define _XRead16(dpy, data, len) _XRead((dpy), (char *)(data), (len)) +#define Data16(dpy, data, len) Data((dpy), (_Xconst char*)(data), (len)) +#define _XRead16Pad(dpy, data, len) _XReadPad((dpy), (char*)(data), (len)) +#define _XRead16(dpy, data, len) _XRead((dpy), (char*)(data), (len)) #ifdef LONG64 -#define Data32(dpy, data, len) _XData32(dpy, (_Xconst long *)data, len) +#define Data32(dpy, data, len) _XData32(dpy, (_Xconst long*)data, len) extern int _XData32( - Display *dpy, - register _Xconst long *data, - unsigned len -); + Display* dpy, + register _Xconst long* data, + unsigned len); extern void _XRead32( - Display *dpy, - register long *data, - long len -); + Display* dpy, + register long* data, + long len); #else -#define Data32(dpy, data, len) Data((dpy), (_Xconst char *)(data), (len)) -#define _XRead32(dpy, data, len) _XRead((dpy), (char *)(data), (len)) +#define Data32(dpy, data, len) Data((dpy), (_Xconst char*)(data), (len)) +#define _XRead32(dpy, data, len) _XRead((dpy), (char*)(data), (len)) #endif -#define PackData16(dpy,data,len) Data16 (dpy, data, len) -#define PackData32(dpy,data,len) Data32 (dpy, data, len) +#define PackData16(dpy, data, len) Data16(dpy, data, len) +#define PackData32(dpy, data, len) Data32(dpy, data, len) /* Xlib manual is bogus */ -#define PackData(dpy,data,len) PackData16 (dpy, data, len) +#define PackData(dpy, data, len) PackData16(dpy, data, len) -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#define max(a,b) (((a) > (b)) ? (a) : (b)) +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#define max(a, b) (((a) > (b)) ? (a) : (b)) -#define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \ - (((cs)->rbearing|(cs)->lbearing| \ - (cs)->ascent|(cs)->descent) == 0)) +#define CI_NONEXISTCHAR(cs) (((cs)->width == 0) && \ + (((cs)->rbearing | (cs)->lbearing | \ + (cs)->ascent | (cs)->descent) == 0)) /* * CI_GET_CHAR_INFO_1D - return the charinfo struct for the indicated 8bit @@ -600,61 +620,68 @@ extern void _XRead32( * return min_bounds). If none of these hold true, try again with the default * char. */ -#define CI_GET_CHAR_INFO_1D(fs,col,def,cs) \ -{ \ - cs = def; \ - if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \ - if (fs->per_char == NULL) { \ - cs = &fs->min_bounds; \ - } else { \ - cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \ - if (CI_NONEXISTCHAR(cs)) cs = def; \ - } \ - } \ -} - -#define CI_GET_DEFAULT_INFO_1D(fs,cs) \ - CI_GET_CHAR_INFO_1D (fs, fs->default_char, NULL, cs) - +#define CI_GET_CHAR_INFO_1D(fs, col, def, cs) \ + { \ + cs = def; \ + if (col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) \ + { \ + if (fs->per_char == NULL) \ + { \ + cs = &fs->min_bounds; \ + } \ + else \ + { \ + cs = &fs->per_char[(col - fs->min_char_or_byte2)]; \ + if (CI_NONEXISTCHAR(cs)) cs = def; \ + } \ + } \ + } +#define CI_GET_DEFAULT_INFO_1D(fs, cs) \ + CI_GET_CHAR_INFO_1D(fs, fs->default_char, NULL, cs) /* * CI_GET_CHAR_INFO_2D - return the charinfo struct for the indicated row and * column. This is used for fonts that have more than row zero. */ -#define CI_GET_CHAR_INFO_2D(fs,row,col,def,cs) \ -{ \ - cs = def; \ - if (row >= fs->min_byte1 && row <= fs->max_byte1 && \ - col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) { \ - if (fs->per_char == NULL) { \ - cs = &fs->min_bounds; \ - } else { \ - cs = &fs->per_char[((row - fs->min_byte1) * \ - (fs->max_char_or_byte2 - \ - fs->min_char_or_byte2 + 1)) + \ - (col - fs->min_char_or_byte2)]; \ - if (CI_NONEXISTCHAR(cs)) cs = def; \ - } \ - } \ -} - -#define CI_GET_DEFAULT_INFO_2D(fs,cs) \ -{ \ - unsigned int r = (fs->default_char >> 8); \ - unsigned int c = (fs->default_char & 0xff); \ - CI_GET_CHAR_INFO_2D (fs, r, c, NULL, cs); \ -} +#define CI_GET_CHAR_INFO_2D(fs, row, col, def, cs) \ + { \ + cs = def; \ + if (row >= fs->min_byte1 && row <= fs->max_byte1 && \ + col >= fs->min_char_or_byte2 && col <= fs->max_char_or_byte2) \ + { \ + if (fs->per_char == NULL) \ + { \ + cs = &fs->min_bounds; \ + } \ + else \ + { \ + cs = &fs->per_char[((row - fs->min_byte1) * \ + (fs->max_char_or_byte2 - \ + fs->min_char_or_byte2 + 1)) + \ + (col - fs->min_char_or_byte2)]; \ + if (CI_NONEXISTCHAR(cs)) cs = def; \ + } \ + } \ + } +#define CI_GET_DEFAULT_INFO_2D(fs, cs) \ + { \ + unsigned int r = (fs->default_char >> 8); \ + unsigned int c = (fs->default_char & 0xff); \ + CI_GET_CHAR_INFO_2D(fs, r, c, NULL, cs); \ + } /* srcvar must be a variable for large architecture version */ -#define OneDataCard32(dpy,dstaddr,srcvar) \ - { *(CARD32 *)(dstaddr) = (srcvar); } +#define OneDataCard32(dpy, dstaddr, srcvar) \ + { \ + *(CARD32*)(dstaddr) = (srcvar); \ + } - -typedef struct _XInternalAsync { - struct _XInternalAsync *next; - /* +typedef struct _XInternalAsync +{ + struct _XInternalAsync* next; + /* * handler arguments: * rep is the generic reply that caused this handler * to be invoked. It must also be passed to _XGetAsyncReply. @@ -663,667 +690,652 @@ typedef struct _XInternalAsync { * data is the closure stored in this struct. * The handler returns True iff it handled this reply. */ - Bool (*handler)( - Display* /* dpy */, - xReply* /* rep */, - char* /* buf */, - int /* len */, - XPointer /* data */ - ); - XPointer data; + Bool (*handler)( + Display* /* dpy */, + xReply* /* rep */, + char* /* buf */, + int /* len */, + XPointer /* data */ + ); + XPointer data; } _XAsyncHandler; -typedef struct _XAsyncEState { - unsigned long min_sequence_number; - unsigned long max_sequence_number; - unsigned char error_code; - unsigned char major_opcode; - unsigned short minor_opcode; - unsigned char last_error_received; - int error_count; +typedef struct _XAsyncEState +{ + unsigned long min_sequence_number; + unsigned long max_sequence_number; + unsigned char error_code; + unsigned char major_opcode; + unsigned short minor_opcode; + unsigned char last_error_received; + int error_count; } _XAsyncErrorState; -extern void _XDeqAsyncHandler(Display *dpy, _XAsyncHandler *handler); -#define DeqAsyncHandler(dpy,handler) { \ - if (dpy->async_handlers == (handler)) \ - dpy->async_handlers = (handler)->next; \ - else \ - _XDeqAsyncHandler(dpy, handler); \ - } +extern void _XDeqAsyncHandler(Display* dpy, _XAsyncHandler* handler); +#define DeqAsyncHandler(dpy, handler) \ + { \ + if (dpy->async_handlers == (handler)) \ + dpy->async_handlers = (handler)->next; \ + else \ + _XDeqAsyncHandler(dpy, handler); \ + } -typedef void (*FreeFuncType) ( - Display* /* display */ +typedef void (*FreeFuncType)( + Display* /* display */ ); -typedef int (*FreeModmapType) ( - XModifierKeymap* /* modmap */ +typedef int (*FreeModmapType)( + XModifierKeymap* /* modmap */ ); /* * This structure is private to the library. */ -typedef struct _XFreeFuncs { - FreeFuncType atoms; /* _XFreeAtomTable */ - FreeModmapType modifiermap; /* XFreeModifiermap */ - FreeFuncType key_bindings; /* _XFreeKeyBindings */ - FreeFuncType context_db; /* _XFreeContextDB */ - FreeFuncType defaultCCCs; /* _XcmsFreeDefaultCCCs */ - FreeFuncType clientCmaps; /* _XcmsFreeClientCmaps */ - FreeFuncType intensityMaps; /* _XcmsFreeIntensityMaps */ - FreeFuncType im_filters; /* _XFreeIMFilters */ - FreeFuncType xkb; /* _XkbFreeInfo */ +typedef struct _XFreeFuncs +{ + FreeFuncType atoms; /* _XFreeAtomTable */ + FreeModmapType modifiermap; /* XFreeModifiermap */ + FreeFuncType key_bindings; /* _XFreeKeyBindings */ + FreeFuncType context_db; /* _XFreeContextDB */ + FreeFuncType defaultCCCs; /* _XcmsFreeDefaultCCCs */ + FreeFuncType clientCmaps; /* _XcmsFreeClientCmaps */ + FreeFuncType intensityMaps; /* _XcmsFreeIntensityMaps */ + FreeFuncType im_filters; /* _XFreeIMFilters */ + FreeFuncType xkb; /* _XkbFreeInfo */ } _XFreeFuncRec; /* types for InitExt.c */ -typedef int (*CreateGCType) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ +typedef int (*CreateGCType)( + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ ); typedef int (*CopyGCType)( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ ); -typedef int (*FlushGCType) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ +typedef int (*FlushGCType)( + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ ); -typedef int (*FreeGCType) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ +typedef int (*FreeGCType)( + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ ); -typedef int (*CreateFontType) ( - Display* /* display */, - XFontStruct* /* fs */, - XExtCodes* /* codes */ +typedef int (*CreateFontType)( + Display* /* display */, + XFontStruct* /* fs */, + XExtCodes* /* codes */ ); -typedef int (*FreeFontType) ( - Display* /* display */, - XFontStruct* /* fs */, - XExtCodes* /* codes */ +typedef int (*FreeFontType)( + Display* /* display */, + XFontStruct* /* fs */, + XExtCodes* /* codes */ ); -typedef int (*CloseDisplayType) ( - Display* /* display */, - XExtCodes* /* codes */ +typedef int (*CloseDisplayType)( + Display* /* display */, + XExtCodes* /* codes */ ); -typedef int (*ErrorType) ( - Display* /* display */, - xError* /* err */, - XExtCodes* /* codes */, - int* /* ret_code */ +typedef int (*ErrorType)( + Display* /* display */, + xError* /* err */, + XExtCodes* /* codes */, + int* /* ret_code */ ); -typedef char* (*ErrorStringType) ( - Display* /* display */, - int /* code */, - XExtCodes* /* codes */, - char* /* buffer */, - int /* nbytes */ +typedef char* (*ErrorStringType)( + Display* /* display */, + int /* code */, + XExtCodes* /* codes */, + char* /* buffer */, + int /* nbytes */ ); typedef void (*PrintErrorType)( - Display* /* display */, - XErrorEvent* /* ev */, - void* /* fp */ + Display* /* display */, + XErrorEvent* /* ev */, + void* /* fp */ ); typedef void (*BeforeFlushType)( - Display* /* display */, - XExtCodes* /* codes */, - _Xconst char* /* data */, - long /* len */ + Display* /* display */, + XExtCodes* /* codes */, + _Xconst char* /* data */, + long /* len */ ); /* * This structure is private to the library. */ -typedef struct _XExten { /* private to extension mechanism */ - struct _XExten *next; /* next in list */ - XExtCodes codes; /* public information, all extension told */ - CreateGCType create_GC; /* routine to call when GC created */ - CopyGCType copy_GC; /* routine to call when GC copied */ - FlushGCType flush_GC; /* routine to call when GC flushed */ - FreeGCType free_GC; /* routine to call when GC freed */ - CreateFontType create_Font; /* routine to call when Font created */ - FreeFontType free_Font; /* routine to call when Font freed */ - CloseDisplayType close_display; /* routine to call when connection closed */ - ErrorType error; /* who to call when an error occurs */ - ErrorStringType error_string; /* routine to supply error string */ - char *name; /* name of this extension */ - PrintErrorType error_values; /* routine to supply error values */ - BeforeFlushType before_flush; /* routine to call when sending data */ - struct _XExten *next_flush; /* next in list of those with flushes */ +typedef struct _XExten +{ /* private to extension mechanism */ + struct _XExten* next; /* next in list */ + XExtCodes codes; /* public information, all extension told */ + CreateGCType create_GC; /* routine to call when GC created */ + CopyGCType copy_GC; /* routine to call when GC copied */ + FlushGCType flush_GC; /* routine to call when GC flushed */ + FreeGCType free_GC; /* routine to call when GC freed */ + CreateFontType create_Font; /* routine to call when Font created */ + FreeFontType free_Font; /* routine to call when Font freed */ + CloseDisplayType close_display; /* routine to call when connection closed */ + ErrorType error; /* who to call when an error occurs */ + ErrorStringType error_string; /* routine to supply error string */ + char* name; /* name of this extension */ + PrintErrorType error_values; /* routine to supply error values */ + BeforeFlushType before_flush; /* routine to call when sending data */ + struct _XExten* next_flush; /* next in list of those with flushes */ } _XExtension; /* Temporary definition until we can depend on an xproto release with it */ #ifdef _X_COLD -# define _XLIB_COLD _X_COLD +#define _XLIB_COLD _X_COLD #elif defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 403) /* 4.3+ */ -# define _XLIB_COLD __attribute__((__cold__)) +#define _XLIB_COLD __attribute__((__cold__)) #else -# define _XLIB_COLD /* nothing */ +#define _XLIB_COLD /* nothing */ #endif /* extension hooks */ #ifdef DataRoutineIsProcedure -extern void Data(Display *dpy, char *data, long len); +extern void Data(Display* dpy, char* data, long len); #endif extern int _XError( - Display* /* dpy */, - xError* /* rep */ + Display* /* dpy */, + xError* /* rep */ ); extern int _XIOError( - Display* /* dpy */ -) _X_NORETURN; + Display* /* dpy */ + ) _X_NORETURN; extern int (*_XIOErrorFunction)( - Display* /* dpy */ + Display* /* dpy */ ); extern int (*_XErrorFunction)( - Display* /* dpy */, - XErrorEvent* /* error_event */ + Display* /* dpy */, + XErrorEvent* /* error_event */ ); extern void _XEatData( - Display* /* dpy */, - unsigned long /* n */ -) _XLIB_COLD; + Display* /* dpy */, + unsigned long /* n */ + ) _XLIB_COLD; extern void _XEatDataWords( - Display* /* dpy */, - unsigned long /* n */ -) _XLIB_COLD; + Display* /* dpy */, + unsigned long /* n */ + ) _XLIB_COLD; #if defined(__SUNPRO_C) /* Studio compiler alternative to "cold" attribute */ -# pragma rarely_called(_XEatData, _XEatDataWords) +#pragma rarely_called(_XEatData, _XEatDataWords) #endif -extern char *_XAllocScratch( - Display* /* dpy */, - unsigned long /* nbytes */ +extern char* _XAllocScratch( + Display* /* dpy */, + unsigned long /* nbytes */ ); -extern char *_XAllocTemp( - Display* /* dpy */, - unsigned long /* nbytes */ +extern char* _XAllocTemp( + Display* /* dpy */, + unsigned long /* nbytes */ ); extern void _XFreeTemp( - Display* /* dpy */, - char* /* buf */, - unsigned long /* nbytes */ + Display* /* dpy */, + char* /* buf */, + unsigned long /* nbytes */ ); -extern Visual *_XVIDtoVisual( - Display* /* dpy */, - VisualID /* id */ +extern Visual* _XVIDtoVisual( + Display* /* dpy */, + VisualID /* id */ ); extern unsigned long _XSetLastRequestRead( - Display* /* dpy */, - xGenericReply* /* rep */ + Display* /* dpy */, + xGenericReply* /* rep */ ); extern int _XGetHostname( - char* /* buf */, - int /* maxlen */ + char* /* buf */, + int /* maxlen */ ); -extern Screen *_XScreenOfWindow( - Display* /* dpy */, - Window /* w */ +extern Screen* _XScreenOfWindow( + Display* /* dpy */, + Window /* w */ ); extern Bool _XAsyncErrorHandler( - Display* /* dpy */, - xReply* /* rep */, - char* /* buf */, - int /* len */, - XPointer /* data */ + Display* /* dpy */, + xReply* /* rep */, + char* /* buf */, + int /* len */, + XPointer /* data */ ); -extern char *_XGetAsyncReply( - Display* /* dpy */, - char* /* replbuf */, - xReply* /* rep */, - char* /* buf */, - int /* len */, - int /* extra */, - Bool /* discard */ +extern char* _XGetAsyncReply( + Display* /* dpy */, + char* /* replbuf */, + xReply* /* rep */, + char* /* buf */, + int /* len */, + int /* extra */, + Bool /* discard */ ); extern void _XGetAsyncData( - Display* /* dpy */, - char * /* data */, - char * /* buf */, - int /* len */, - int /* skip */, - int /* datalen */, - int /* discardtotal */ + Display* /* dpy */, + char* /* data */, + char* /* buf */, + int /* len */, + int /* skip */, + int /* datalen */, + int /* discardtotal */ ); extern void _XFlush( - Display* /* dpy */ + Display* /* dpy */ ); extern int _XEventsQueued( - Display* /* dpy */, - int /* mode */ + Display* /* dpy */, + int /* mode */ ); extern void _XReadEvents( - Display* /* dpy */ + Display* /* dpy */ ); extern int _XRead( - Display* /* dpy */, - char* /* data */, - long /* size */ + Display* /* dpy */, + char* /* data */, + long /* size */ ); extern void _XReadPad( - Display* /* dpy */, - char* /* data */, - long /* size */ + Display* /* dpy */, + char* /* data */, + long /* size */ ); extern void _XSend( - Display* /* dpy */, - _Xconst char* /* data */, - long /* size */ + Display* /* dpy */, + _Xconst char* /* data */, + long /* size */ ); extern Status _XReply( - Display* /* dpy */, - xReply* /* rep */, - int /* extra */, - Bool /* discard */ + Display* /* dpy */, + xReply* /* rep */, + int /* extra */, + Bool /* discard */ ); extern void _XEnq( - Display* /* dpy */, - xEvent* /* event */ + Display* /* dpy */, + xEvent* /* event */ ); extern void _XDeq( - Display* /* dpy */, - _XQEvent* /* prev */, - _XQEvent* /* qelt */ + Display* /* dpy */, + _XQEvent* /* prev */, + _XQEvent* /* qelt */ ); extern Bool _XUnknownWireEvent( - Display* /* dpy */, - XEvent* /* re */, - xEvent* /* event */ + Display* /* dpy */, + XEvent* /* re */, + xEvent* /* event */ ); extern Bool _XUnknownWireEventCookie( - Display* /* dpy */, - XGenericEventCookie* /* re */, - xEvent* /* event */ + Display* /* dpy */, + XGenericEventCookie* /* re */, + xEvent* /* event */ ); extern Bool _XUnknownCopyEventCookie( - Display* /* dpy */, - XGenericEventCookie* /* in */, - XGenericEventCookie* /* out */ + Display* /* dpy */, + XGenericEventCookie* /* in */, + XGenericEventCookie* /* out */ ); extern Status _XUnknownNativeEvent( - Display* /* dpy */, - XEvent* /* re */, - xEvent* /* event */ + Display* /* dpy */, + XEvent* /* re */, + xEvent* /* event */ ); -extern Bool _XWireToEvent(Display *dpy, XEvent *re, xEvent *event); -extern Bool _XDefaultWireError(Display *display, XErrorEvent *he, xError *we); -extern Bool _XPollfdCacheInit(Display *dpy); -extern void _XPollfdCacheAdd(Display *dpy, int fd); -extern void _XPollfdCacheDel(Display *dpy, int fd); -extern XID _XAllocID(Display *dpy); -extern void _XAllocIDs(Display *dpy, XID *ids, int count); +extern Bool _XWireToEvent(Display* dpy, XEvent* re, xEvent* event); +extern Bool _XDefaultWireError(Display* display, XErrorEvent* he, xError* we); +extern Bool _XPollfdCacheInit(Display* dpy); +extern void _XPollfdCacheAdd(Display* dpy, int fd); +extern void _XPollfdCacheDel(Display* dpy, int fd); +extern XID _XAllocID(Display* dpy); +extern void _XAllocIDs(Display* dpy, XID* ids, int count); extern int _XFreeExtData( - XExtData* /* extension */ + XExtData* /* extension */ ); extern int (*XESetCreateGC( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, GC, XExtCodes* -); + Display* /* display */, + int /* extension */, + int (*)( + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ + ) /* proc */ + ))( + Display*, GC, XExtCodes*); extern int (*XESetCopyGC( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, GC, XExtCodes* -); + Display* /* display */, + int /* extension */, + int (*)( + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ + ) /* proc */ + ))( + Display*, GC, XExtCodes*); extern int (*XESetFlushGC( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, GC, XExtCodes* -); + Display* /* display */, + int /* extension */, + int (*)( + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ + ) /* proc */ + ))( + Display*, GC, XExtCodes*); extern int (*XESetFreeGC( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, GC, XExtCodes* -); + Display* /* display */, + int /* extension */, + int (*)( + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ + ) /* proc */ + ))( + Display*, GC, XExtCodes*); extern int (*XESetCreateFont( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - XFontStruct* /* fs */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, XFontStruct*, XExtCodes* -); + Display* /* display */, + int /* extension */, + int (*)( + Display* /* display */, + XFontStruct* /* fs */, + XExtCodes* /* codes */ + ) /* proc */ + ))( + Display*, XFontStruct*, XExtCodes*); extern int (*XESetFreeFont( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - XFontStruct* /* fs */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, XFontStruct*, XExtCodes* -); + Display* /* display */, + int /* extension */, + int (*)( + Display* /* display */, + XFontStruct* /* fs */, + XExtCodes* /* codes */ + ) /* proc */ + ))( + Display*, XFontStruct*, XExtCodes*); extern int (*XESetCloseDisplay( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - XExtCodes* /* codes */ - ) /* proc */ -))( - Display*, XExtCodes* -); + Display* /* display */, + int /* extension */, + int (*)( + Display* /* display */, + XExtCodes* /* codes */ + ) /* proc */ + ))( + Display*, XExtCodes*); extern int (*XESetError( - Display* /* display */, - int /* extension */, - int (*) ( - Display* /* display */, - xError* /* err */, - XExtCodes* /* codes */, - int* /* ret_code */ - ) /* proc */ -))( - Display*, xError*, XExtCodes*, int* -); + Display* /* display */, + int /* extension */, + int (*)( + Display* /* display */, + xError* /* err */, + XExtCodes* /* codes */, + int* /* ret_code */ + ) /* proc */ + ))( + Display*, xError*, XExtCodes*, int*); extern char* (*XESetErrorString( - Display* /* display */, - int /* extension */, - char* (*) ( - Display* /* display */, - int /* code */, - XExtCodes* /* codes */, - char* /* buffer */, - int /* nbytes */ - ) /* proc */ -))( - Display*, int, XExtCodes*, char*, int -); + Display* /* display */, + int /* extension */, + char* (*)(Display* /* display */, + int /* code */, + XExtCodes* /* codes */, + char* /* buffer */, + int /* nbytes */ + ) /* proc */ + ))( + Display*, int, XExtCodes*, char*, int); -extern void (*XESetPrintErrorValues ( - Display* /* display */, - int /* extension */, - void (*)( - Display* /* display */, - XErrorEvent* /* ev */, - void* /* fp */ - ) /* proc */ -))( - Display*, XErrorEvent*, void* -); +extern void (*XESetPrintErrorValues( + Display* /* display */, + int /* extension */, + void (*)( + Display* /* display */, + XErrorEvent* /* ev */, + void* /* fp */ + ) /* proc */ + ))( + Display*, XErrorEvent*, void*); extern Bool (*XESetWireToEvent( - Display* /* display */, - int /* event_number */, - Bool (*) ( - Display* /* display */, - XEvent* /* re */, - xEvent* /* event */ - ) /* proc */ -))( - Display*, XEvent*, xEvent* -); + Display* /* display */, + int /* event_number */, + Bool (*)( + Display* /* display */, + XEvent* /* re */, + xEvent* /* event */ + ) /* proc */ + ))( + Display*, XEvent*, xEvent*); extern Bool (*XESetWireToEventCookie( - Display* /* display */, - int /* extension */, - Bool (*) ( - Display* /* display */, - XGenericEventCookie* /* re */, - xEvent* /* event */ - ) /* proc */ -))( - Display*, XGenericEventCookie*, xEvent* -); + Display* /* display */, + int /* extension */, + Bool (*)( + Display* /* display */, + XGenericEventCookie* /* re */, + xEvent* /* event */ + ) /* proc */ + ))( + Display*, XGenericEventCookie*, xEvent*); extern Bool (*XESetCopyEventCookie( - Display* /* display */, - int /* extension */, - Bool (*) ( - Display* /* display */, - XGenericEventCookie* /* in */, - XGenericEventCookie* /* out */ - ) /* proc */ -))( - Display*, XGenericEventCookie*, XGenericEventCookie* -); - + Display* /* display */, + int /* extension */, + Bool (*)( + Display* /* display */, + XGenericEventCookie* /* in */, + XGenericEventCookie* /* out */ + ) /* proc */ + ))( + Display*, XGenericEventCookie*, XGenericEventCookie*); extern Status (*XESetEventToWire( - Display* /* display */, - int /* event_number */, - Status (*) ( - Display* /* display */, - XEvent* /* re */, - xEvent* /* event */ - ) /* proc */ -))( - Display*, XEvent*, xEvent* -); + Display* /* display */, + int /* event_number */, + Status (*)( + Display* /* display */, + XEvent* /* re */, + xEvent* /* event */ + ) /* proc */ + ))( + Display*, XEvent*, xEvent*); extern Bool (*XESetWireToError( - Display* /* display */, - int /* error_number */, - Bool (*) ( - Display* /* display */, - XErrorEvent* /* he */, - xError* /* we */ - ) /* proc */ -))( - Display*, XErrorEvent*, xError* -); + Display* /* display */, + int /* error_number */, + Bool (*)( + Display* /* display */, + XErrorEvent* /* he */, + xError* /* we */ + ) /* proc */ + ))( + Display*, XErrorEvent*, xError*); extern void (*XESetBeforeFlush( - Display* /* display */, - int /* error_number */, - void (*) ( - Display* /* display */, - XExtCodes* /* codes */, - _Xconst char* /* data */, - long /* len */ - ) /* proc */ -))( - Display*, XExtCodes*, _Xconst char*, long -); + Display* /* display */, + int /* error_number */, + void (*)( + Display* /* display */, + XExtCodes* /* codes */, + _Xconst char* /* data */, + long /* len */ + ) /* proc */ + ))( + Display*, XExtCodes*, _Xconst char*, long); /* internal connections for IMs */ typedef void (*_XInternalConnectionProc)( - Display* /* dpy */, - int /* fd */, - XPointer /* call_data */ + Display* /* dpy */, + int /* fd */, + XPointer /* call_data */ ); - extern Status _XRegisterInternalConnection( - Display* /* dpy */, - int /* fd */, - _XInternalConnectionProc /* callback */, - XPointer /* call_data */ + Display* /* dpy */, + int /* fd */, + _XInternalConnectionProc /* callback */, + XPointer /* call_data */ ); extern void _XUnregisterInternalConnection( - Display* /* dpy */, - int /* fd */ + Display* /* dpy */, + int /* fd */ ); extern void _XProcessInternalConnection( - Display* /* dpy */, - struct _XConnectionInfo* /* conn_info */ + Display* /* dpy */, + struct _XConnectionInfo* /* conn_info */ ); /* Display structure has pointers to these */ -struct _XConnectionInfo { /* info from _XRegisterInternalConnection */ - int fd; - _XInternalConnectionProc read_callback; - XPointer call_data; - XPointer *watch_data; /* set/used by XConnectionWatchProc */ - struct _XConnectionInfo *next; +struct _XConnectionInfo +{ /* info from _XRegisterInternalConnection */ + int fd; + _XInternalConnectionProc read_callback; + XPointer call_data; + XPointer* watch_data; /* set/used by XConnectionWatchProc */ + struct _XConnectionInfo* next; }; -struct _XConnWatchInfo { /* info from XAddConnectionWatch */ - XConnectionWatchProc fn; - XPointer client_data; - struct _XConnWatchInfo *next; +struct _XConnWatchInfo +{ /* info from XAddConnectionWatch */ + XConnectionWatchProc fn; + XPointer client_data; + struct _XConnWatchInfo* next; }; #ifdef __UNIXOS2__ extern char* __XOS2RedirRoot( - char* -); + char*); #endif extern int _XTextHeight( - XFontStruct* /* font_struct */, - _Xconst char* /* string */, - int /* count */ + XFontStruct* /* font_struct */, + _Xconst char* /* string */, + int /* count */ ); extern int _XTextHeight16( - XFontStruct* /* font_struct */, - _Xconst XChar2b* /* string */, - int /* count */ + XFontStruct* /* font_struct */, + _Xconst XChar2b* /* string */, + int /* count */ ); #if defined(WIN32) extern int _XOpenFile( - _Xconst char* /* path */, - int /* flags */ + _Xconst char* /* path */, + int /* flags */ ); extern int _XOpenFileMode( - _Xconst char* /* path */, - int /* flags */, - mode_t /* mode */ + _Xconst char* /* path */, + int /* flags */, + mode_t /* mode */ ); extern void* _XFopenFile( - _Xconst char* /* path */, - _Xconst char* /* mode */ + _Xconst char* /* path */, + _Xconst char* /* mode */ ); extern int _XAccessFile( - _Xconst char* /* path */ + _Xconst char* /* path */ ); #else -#define _XOpenFile(path,flags) open(path,flags) -#define _XOpenFileMode(path,flags,mode) open(path,flags,mode) -#define _XFopenFile(path,mode) fopen(path,mode) +#define _XOpenFile(path, flags) open(path, flags) +#define _XOpenFileMode(path, flags, mode) open(path, flags, mode) +#define _XFopenFile(path, mode) fopen(path, mode) #endif /* EvToWire.c */ -extern Status _XEventToWire(Display *dpy, XEvent *re, xEvent *event); +extern Status _XEventToWire(Display* dpy, XEvent* re, xEvent* event); extern int _XF86LoadQueryLocaleFont( - Display* /* dpy */, - _Xconst char* /* name*/, - XFontStruct** /* xfp*/, - Font* /* fidp */ + Display* /* dpy */, + _Xconst char* /* name*/, + XFontStruct** /* xfp*/, + Font* /* fidp */ ); -extern void _XProcessWindowAttributes ( - register Display *dpy, - xChangeWindowAttributesReq *req, - register unsigned long valuemask, - register XSetWindowAttributes *attributes); +extern void _XProcessWindowAttributes( + register Display* dpy, + xChangeWindowAttributesReq* req, + register unsigned long valuemask, + register XSetWindowAttributes* attributes); extern int _XDefaultError( - Display *dpy, - XErrorEvent *event); + Display* dpy, + XErrorEvent* event); extern int _XDefaultIOError( - Display *dpy); + Display* dpy); -extern void _XSetClipRectangles ( - register Display *dpy, - GC gc, - int clip_x_origin, int clip_y_origin, - XRectangle *rectangles, - int n, - int ordering); +extern void _XSetClipRectangles( + register Display* dpy, + GC gc, + int clip_x_origin, int clip_y_origin, + XRectangle* rectangles, + int n, + int ordering); Status _XGetWindowAttributes( - register Display *dpy, - Window w, - XWindowAttributes *attr); + register Display* dpy, + Window w, + XWindowAttributes* attr); -int _XPutBackEvent ( - register Display *dpy, - register XEvent *event); +int _XPutBackEvent( + register Display* dpy, + register XEvent* event); extern Bool _XIsEventCookie( - Display *dpy, - XEvent *ev); + Display* dpy, + XEvent* ev); extern void _XFreeEventCookies( - Display *dpy); + Display* dpy); extern void _XStoreEventCookie( - Display *dpy, - XEvent *ev); + Display* dpy, + XEvent* ev); extern Bool _XFetchEventCookie( - Display *dpy, - XGenericEventCookie *ev); + Display* dpy, + XGenericEventCookie* ev); extern Bool _XCopyEventCookie( - Display *dpy, - XGenericEventCookie *in, - XGenericEventCookie *out); + Display* dpy, + XGenericEventCookie* in, + XGenericEventCookie* out); /* lcFile.c */ extern void xlocaledir( - char *buf, - int buf_len -); + char* buf, + int buf_len); #ifdef __clang__ #pragma clang diagnostic pop diff --git a/examples/ThirdPartyLibs/optionalX11/X11/Xmd.h b/examples/ThirdPartyLibs/optionalX11/X11/Xmd.h index 96cc08ffd..c74815a91 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/Xmd.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/Xmd.h @@ -45,7 +45,7 @@ SOFTWARE. ******************************************************************/ #ifndef XMD_H -# define XMD_H 1 +#define XMD_H 1 /* * Xmd.h: MACHINE DEPENDENT DECLARATIONS. */ @@ -53,30 +53,29 @@ SOFTWARE. /* * Special per-machine configuration flags. */ -# if defined(__sun) && defined(__SVR4) -# include /* Solaris: defines _LP64 if necessary */ -# endif +#if defined(__sun) && defined(__SVR4) +#include /* Solaris: defines _LP64 if necessary */ +#endif -# if defined (_LP64) || defined(__LP64__) || \ - defined(__alpha) || defined(__alpha__) || \ - defined(__ia64__) || defined(ia64) || \ - defined(__sparc64__) || \ - defined(__s390x__) || \ - defined(__amd64__) || defined(amd64) || \ - defined(__powerpc64__) -# if !defined(__ILP32__) /* amd64-x32 is 32bit */ -# define LONG64 /* 32/64-bit architecture */ -# endif /* !__ILP32__ */ -# endif +#if defined(_LP64) || defined(__LP64__) || \ + defined(__alpha) || defined(__alpha__) || \ + defined(__ia64__) || defined(ia64) || \ + defined(__sparc64__) || \ + defined(__s390x__) || \ + defined(__amd64__) || defined(amd64) || \ + defined(__powerpc64__) +#if !defined(__ILP32__) /* amd64-x32 is 32bit */ +#define LONG64 /* 32/64-bit architecture */ +#endif /* !__ILP32__ */ +#endif /* * Stuff to handle large architecture machines; the constants were generated * on a 32-bit machine and must correspond to the protocol. */ -# ifdef WORD64 -# define MUSTCOPY -# endif /* WORD64 */ - +#ifdef WORD64 +#define MUSTCOPY +#endif /* WORD64 */ /* * Definition of macro used to set constants for size of network structures; @@ -92,96 +91,94 @@ SOFTWARE. * The extra indirection is to get macro arguments to expand correctly before * the concatenation, rather than afterward. */ -# define _SIZEOF(x) sz_##x -# define SIZEOF(x) _SIZEOF(x) +#define _SIZEOF(x) sz_##x +#define SIZEOF(x) _SIZEOF(x) /* * Bitfield suffixes for the protocol structure elements, if you * need them. Note that bitfields are not guaranteed to be signed * (or even unsigned) according to ANSI C. */ -# ifdef WORD64 +#ifdef WORD64 typedef long INT64; typedef unsigned long CARD64; -# define B32 :32 -# define B16 :16 -# ifdef UNSIGNEDBITFIELDS +#define B32 :32 +#define B16 :16 +#ifdef UNSIGNEDBITFIELDS typedef unsigned int INT32; typedef unsigned int INT16; -# else +#else typedef signed int INT32; typedef signed int INT16; -# endif -# else -# define B32 -# define B16 -# ifdef LONG64 +#endif +#else +#define B32 +#define B16 +#ifdef LONG64 typedef long INT64; typedef int INT32; -# else +#else typedef long INT32; -# endif +#endif typedef short INT16; -# endif +#endif -typedef signed char INT8; +typedef signed char INT8; -# ifdef LONG64 +#ifdef LONG64 typedef unsigned long CARD64; typedef unsigned int CARD32; -# else +#else typedef unsigned long CARD32; -# endif -# if !defined(WORD64) && !defined(LONG64) +#endif +#if !defined(WORD64) && !defined(LONG64) typedef unsigned long long CARD64; -# endif +#endif typedef unsigned short CARD16; -typedef unsigned char CARD8; +typedef unsigned char CARD8; -typedef CARD32 BITS32; -typedef CARD16 BITS16; +typedef CARD32 BITS32; +typedef CARD16 BITS16; -typedef CARD8 BYTE; -typedef CARD8 BOOL; +typedef CARD8 BYTE; +typedef CARD8 BOOL; /* * definitions for sign-extending bitfields on 64-bit architectures */ -# if defined(WORD64) && defined(UNSIGNEDBITFIELDS) -# define cvtINT8toInt(val) (((val) & 0x00000080) ? ((val) | 0xffffffffffffff00) : (val)) -# define cvtINT16toInt(val) (((val) & 0x00008000) ? ((val) | 0xffffffffffff0000) : (val)) -# define cvtINT32toInt(val) (((val) & 0x80000000) ? ((val) | 0xffffffff00000000) : (val)) -# define cvtINT8toShort(val) cvtINT8toInt(val) -# define cvtINT16toShort(val) cvtINT16toInt(val) -# define cvtINT32toShort(val) cvtINT32toInt(val) -# define cvtINT8toLong(val) cvtINT8toInt(val) -# define cvtINT16toLong(val) cvtINT16toInt(val) -# define cvtINT32toLong(val) cvtINT32toInt(val) -# else -# define cvtINT8toInt(val) (val) -# define cvtINT16toInt(val) (val) -# define cvtINT32toInt(val) (val) -# define cvtINT8toShort(val) (val) -# define cvtINT16toShort(val) (val) -# define cvtINT32toShort(val) (val) -# define cvtINT8toLong(val) (val) -# define cvtINT16toLong(val) (val) -# define cvtINT32toLong(val) (val) -# endif /* WORD64 and UNSIGNEDBITFIELDS */ +#if defined(WORD64) && defined(UNSIGNEDBITFIELDS) +#define cvtINT8toInt(val) (((val)&0x00000080) ? ((val) | 0xffffffffffffff00) : (val)) +#define cvtINT16toInt(val) (((val)&0x00008000) ? ((val) | 0xffffffffffff0000) : (val)) +#define cvtINT32toInt(val) (((val)&0x80000000) ? ((val) | 0xffffffff00000000) : (val)) +#define cvtINT8toShort(val) cvtINT8toInt(val) +#define cvtINT16toShort(val) cvtINT16toInt(val) +#define cvtINT32toShort(val) cvtINT32toInt(val) +#define cvtINT8toLong(val) cvtINT8toInt(val) +#define cvtINT16toLong(val) cvtINT16toInt(val) +#define cvtINT32toLong(val) cvtINT32toInt(val) +#else +#define cvtINT8toInt(val) (val) +#define cvtINT16toInt(val) (val) +#define cvtINT32toInt(val) (val) +#define cvtINT8toShort(val) (val) +#define cvtINT16toShort(val) (val) +#define cvtINT32toShort(val) (val) +#define cvtINT8toLong(val) (val) +#define cvtINT16toLong(val) (val) +#define cvtINT32toLong(val) (val) +#endif /* WORD64 and UNSIGNEDBITFIELDS */ - - -# ifdef MUSTCOPY +#ifdef MUSTCOPY /* * This macro must not cast or else pointers will get aligned and be wrong */ -# define NEXTPTR(p,t) (((char *) p) + SIZEOF(t)) -# else /* else not MUSTCOPY, this is used for 32-bit machines */ +#define NEXTPTR(p, t) (((char *)p) + SIZEOF(t)) +#else /* else not MUSTCOPY, this is used for 32-bit machines */ /* * this version should leave result of type (t *), but that should only be * used when not in MUSTCOPY */ -# define NEXTPTR(p,t) (((t *)(p)) + 1) -# endif /* MUSTCOPY - used machines whose C structs don't line up with proto */ +#define NEXTPTR(p, t) (((t *)(p)) + 1) +#endif /* MUSTCOPY - used machines whose C structs don't line up with proto */ #endif /* XMD_H */ diff --git a/examples/ThirdPartyLibs/optionalX11/X11/Xosdefs.h b/examples/ThirdPartyLibs/optionalX11/X11/Xosdefs.h index 33eaee436..6314a809a 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/Xosdefs.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/Xosdefs.h @@ -25,7 +25,7 @@ in this Software without prior written authorization from The Open Group. */ #ifndef _XOSDEFS_H_ -# define _XOSDEFS_H_ +#define _XOSDEFS_H_ /* * X_NOT_POSIX means does not have POSIX header files. Lack of this @@ -33,84 +33,80 @@ in this Software without prior written authorization from The Open Group. * You may still have to define _POSIX_SOURCE to get it. */ +#ifdef _SCO_DS +#ifndef __SCO__ +#define __SCO__ +#endif +#endif -# ifdef _SCO_DS -# ifndef __SCO__ -# define __SCO__ -# endif -# endif - -# ifdef __i386__ -# ifdef SYSV -# if !defined(__SCO__) && \ +#ifdef __i386__ +#ifdef SYSV +#if !defined(__SCO__) && \ !defined(__UNIXWARE__) && !defined(__sun) -# if !defined(_POSIX_SOURCE) -# define X_NOT_POSIX -# endif -# endif -# endif -# endif +#if !defined(_POSIX_SOURCE) +#define X_NOT_POSIX +#endif +#endif +#endif +#endif -# ifdef __sun +#ifdef __sun /* Imake configs define SVR4 on Solaris, but cc & gcc only define __SVR4 * This check allows non-Imake configured programs to build correctly. */ -# if defined(__SVR4) && !defined(SVR4) -# define SVR4 1 -# endif -# ifdef SVR4 +#if defined(__SVR4) && !defined(SVR4) +#define SVR4 1 +#endif +#ifdef SVR4 /* define this to whatever it needs to be */ -# define X_POSIX_C_SOURCE 199300L -# endif -# endif +#define X_POSIX_C_SOURCE 199300L +#endif +#endif -# ifdef WIN32 -# ifndef _POSIX_ -# define X_NOT_POSIX -# endif -# endif +#ifdef WIN32 +#ifndef _POSIX_ +#define X_NOT_POSIX +#endif +#endif - -# ifdef __APPLE__ -# define NULL_NOT_ZERO +#ifdef __APPLE__ +#define NULL_NOT_ZERO /* Defining any of these will sanitize the namespace to JUST want is defined by * that particular standard. If that happens, we don't get some expected * prototypes, typedefs, etc (like fd_mask). We can define _DARWIN_C_SOURCE to * loosen our belts a tad. */ -# if defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) -# ifndef _DARWIN_C_SOURCE -# define _DARWIN_C_SOURCE -# endif -# endif +#if defined(_XOPEN_SOURCE) || defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) +#ifndef _DARWIN_C_SOURCE +#define _DARWIN_C_SOURCE +#endif +#endif -# endif +#endif -# ifdef __GNU__ -# ifndef PATH_MAX -# define PATH_MAX 4096 -# endif -# ifndef MAXPATHLEN -# define MAXPATHLEN 4096 -# endif -# endif +#ifdef __GNU__ +#ifndef PATH_MAX +#define PATH_MAX 4096 +#endif +#ifndef MAXPATHLEN +#define MAXPATHLEN 4096 +#endif +#endif -# if defined(__SCO__) || defined(__UNIXWARE__) -# ifndef PATH_MAX -# define PATH_MAX 1024 -# endif -# ifndef MAXPATHLEN -# define MAXPATHLEN 1024 -# endif -# endif +#if defined(__SCO__) || defined(__UNIXWARE__) +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif +#ifndef MAXPATHLEN +#define MAXPATHLEN 1024 +#endif +#endif -# if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) \ - || defined(__APPLE__) || defined(__DragonFly__) -# ifndef CSRG_BASED -# define CSRG_BASED -# endif -# endif +#if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__APPLE__) || defined(__DragonFly__) +#ifndef CSRG_BASED +#define CSRG_BASED +#endif +#endif #endif /* _XOSDEFS_H_ */ - diff --git a/examples/ThirdPartyLibs/optionalX11/X11/Xproto.h b/examples/ThirdPartyLibs/optionalX11/X11/Xproto.h index 495d44194..5c2b3d90f 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/Xproto.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/Xproto.h @@ -231,7 +231,6 @@ SOFTWARE. #define sz_xPropIconSize 24 #define sz_xChangeKeyboardMappingReq 8 - /* For the purpose of the structure definitions in this file, we must redefine the following types in terms of Xmd.h's types, which may include bit fields. All of these are #undef'd at the end of this file, @@ -250,11 +249,10 @@ restoring the definitions in X.h. */ #define KeyCode CARD8 #define KeySym CARD32 -#define X_TCP_PORT 6000 /* add display number */ - -#define xTrue 1 -#define xFalse 0 +#define X_TCP_PORT 6000 /* add display number */ +#define xTrue 1 +#define xFalse 0 typedef CARD16 KeyButMask; @@ -263,86 +261,91 @@ typedef CARD16 KeyButMask; numRoots xWindowRoot structs. *****************/ -typedef struct { - CARD8 byteOrder; - BYTE pad; - CARD16 majorVersion B16, minorVersion B16; - CARD16 nbytesAuthProto B16; /* Authorization protocol */ - CARD16 nbytesAuthString B16; /* Authorization string */ - CARD16 pad2 B16; +typedef struct +{ + CARD8 byteOrder; + BYTE pad; + CARD16 majorVersion B16, minorVersion B16; + CARD16 nbytesAuthProto B16; /* Authorization protocol */ + CARD16 nbytesAuthString B16; /* Authorization string */ + CARD16 pad2 B16; } xConnClientPrefix; -typedef struct { - CARD8 success; - BYTE lengthReason; /*num bytes in string following if failure */ - CARD16 majorVersion B16, - minorVersion B16; - CARD16 length B16; /* 1/4 additional bytes in setup info */ +typedef struct +{ + CARD8 success; + BYTE lengthReason; /*num bytes in string following if failure */ + CARD16 majorVersion B16, + minorVersion B16; + CARD16 length B16; /* 1/4 additional bytes in setup info */ } xConnSetupPrefix; - -typedef struct { - CARD32 release B32; - CARD32 ridBase B32, - ridMask B32; - CARD32 motionBufferSize B32; - CARD16 nbytesVendor B16; /* number of bytes in vendor string */ - CARD16 maxRequestSize B16; - CARD8 numRoots; /* number of roots structs to follow */ - CARD8 numFormats; /* number of pixmap formats */ - CARD8 imageByteOrder; /* LSBFirst, MSBFirst */ - CARD8 bitmapBitOrder; /* LeastSignificant, MostSign...*/ - CARD8 bitmapScanlineUnit, /* 8, 16, 32 */ - bitmapScanlinePad; /* 8, 16, 32 */ - KeyCode minKeyCode, maxKeyCode; - CARD32 pad2 B32; +typedef struct +{ + CARD32 release B32; + CARD32 ridBase B32, + ridMask B32; + CARD32 motionBufferSize B32; + CARD16 nbytesVendor B16; /* number of bytes in vendor string */ + CARD16 maxRequestSize B16; + CARD8 numRoots; /* number of roots structs to follow */ + CARD8 numFormats; /* number of pixmap formats */ + CARD8 imageByteOrder; /* LSBFirst, MSBFirst */ + CARD8 bitmapBitOrder; /* LeastSignificant, MostSign...*/ + CARD8 bitmapScanlineUnit, /* 8, 16, 32 */ + bitmapScanlinePad; /* 8, 16, 32 */ + KeyCode minKeyCode, maxKeyCode; + CARD32 pad2 B32; } xConnSetup; -typedef struct { - CARD8 depth; - CARD8 bitsPerPixel; - CARD8 scanLinePad; - CARD8 pad1; - CARD32 pad2 B32; +typedef struct +{ + CARD8 depth; + CARD8 bitsPerPixel; + CARD8 scanLinePad; + CARD8 pad1; + CARD32 pad2 B32; } xPixmapFormat; /* window root */ -typedef struct { - CARD8 depth; - CARD8 pad1; - CARD16 nVisuals B16; /* number of xVisualType structures following */ - CARD32 pad2 B32; - } xDepth; +typedef struct +{ + CARD8 depth; + CARD8 pad1; + CARD16 nVisuals B16; /* number of xVisualType structures following */ + CARD32 pad2 B32; +} xDepth; -typedef struct { - VisualID visualID B32; +typedef struct +{ + VisualID visualID B32; #if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; + CARD8 c_class; #else - CARD8 class; + CARD8 class; #endif - CARD8 bitsPerRGB; - CARD16 colormapEntries B16; - CARD32 redMask B32, greenMask B32, blueMask B32; - CARD32 pad B32; - } xVisualType; + CARD8 bitsPerRGB; + CARD16 colormapEntries B16; + CARD32 redMask B32, greenMask B32, blueMask B32; + CARD32 pad B32; +} xVisualType; -typedef struct { - Window windowId B32; - Colormap defaultColormap B32; - CARD32 whitePixel B32, blackPixel B32; - CARD32 currentInputMask B32; - CARD16 pixWidth B16, pixHeight B16; - CARD16 mmWidth B16, mmHeight B16; - CARD16 minInstalledMaps B16, maxInstalledMaps B16; - VisualID rootVisualID B32; - CARD8 backingStore; - BOOL saveUnders; - CARD8 rootDepth; - CARD8 nDepths; /* number of xDepth structures following */ +typedef struct +{ + Window windowId B32; + Colormap defaultColormap B32; + CARD32 whitePixel B32, blackPixel B32; + CARD32 currentInputMask B32; + CARD16 pixWidth B16, pixHeight B16; + CARD16 mmWidth B16, mmHeight B16; + CARD16 minInstalledMaps B16, maxInstalledMaps B16; + VisualID rootVisualID B32; + CARD8 backingStore; + BOOL saveUnders; + CARD8 rootDepth; + CARD8 nDepths; /* number of xDepth structures following */ } xWindowRoot; - /***************************************************************** * Structure Defns @@ -351,55 +354,59 @@ typedef struct { /* Used in GetMotionEvents */ -typedef struct { - CARD32 time B32; - INT16 x B16, y B16; +typedef struct +{ + CARD32 time B32; + INT16 x B16, y B16; } xTimecoord; -typedef struct { - CARD8 family; - BYTE pad; - CARD16 length B16; +typedef struct +{ + CARD8 family; + BYTE pad; + CARD16 length B16; } xHostEntry; -typedef struct { - INT16 leftSideBearing B16, - rightSideBearing B16, - characterWidth B16, - ascent B16, - descent B16; - CARD16 attributes B16; +typedef struct +{ + INT16 leftSideBearing B16, + rightSideBearing B16, + characterWidth B16, + ascent B16, + descent B16; + CARD16 attributes B16; } xCharInfo; -typedef struct { - Atom name B32; - CARD32 value B32; +typedef struct +{ + Atom name B32; + CARD32 value B32; } xFontProp; /* * non-aligned big-endian font ID follows this struct */ -typedef struct { /* followed by string */ - CARD8 len; /* number of *characters* in string, or FontChange (255) +typedef struct +{ /* followed by string */ + CARD8 len; /* number of *characters* in string, or FontChange (255) for font change, or 0 if just delta given */ - INT8 delta; + INT8 delta; } xTextElt; - -typedef struct { - CARD32 pixel B32; - CARD16 red B16, green B16, blue B16; - CARD8 flags; /* DoRed, DoGreen, DoBlue booleans */ - CARD8 pad; +typedef struct +{ + CARD32 pixel B32; + CARD16 red B16, green B16, blue B16; + CARD8 flags; /* DoRed, DoGreen, DoBlue booleans */ + CARD8 pad; } xColorItem; - -typedef struct { - CARD16 red B16, green B16, blue B16, pad B16; +typedef struct +{ + CARD16 red B16, green B16, blue B16, pad B16; } xrgb; typedef CARD8 KEYCODE; - /***************** * XRep: @@ -409,578 +416,614 @@ typedef CARD8 KEYCODE; /* GenericReply is the common format of all replies. The "data" items are specific to each individual reply type. */ -typedef struct { - BYTE type; /* X_Reply */ - BYTE data1; /* depends on reply type */ - CARD16 sequenceNumber B16; /* of last request received by server */ - CARD32 length B32; /* 4 byte quantities beyond size of GenericReply */ - CARD32 data00 B32; - CARD32 data01 B32; - CARD32 data02 B32; - CARD32 data03 B32; - CARD32 data04 B32; - CARD32 data05 B32; - } xGenericReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE data1; /* depends on reply type */ + CARD16 sequenceNumber B16; /* of last request received by server */ + CARD32 length B32; /* 4 byte quantities beyond size of GenericReply */ + CARD32 data00 B32; + CARD32 data01 B32; + CARD32 data02 B32; + CARD32 data03 B32; + CARD32 data04 B32; + CARD32 data05 B32; +} xGenericReply; /* Individual reply formats. */ -typedef struct { - BYTE type; /* X_Reply */ - CARD8 backingStore; - CARD16 sequenceNumber B16; - CARD32 length B32; /* NOT 0; this is an extra-large reply */ - VisualID visualID B32; +typedef struct +{ + BYTE type; /* X_Reply */ + CARD8 backingStore; + CARD16 sequenceNumber B16; + CARD32 length B32; /* NOT 0; this is an extra-large reply */ + VisualID visualID B32; #if defined(__cplusplus) || defined(c_plusplus) - CARD16 c_class B16; + CARD16 c_class B16; #else - CARD16 class B16; + CARD16 class B16; #endif - CARD8 bitGravity; - CARD8 winGravity; - CARD32 backingBitPlanes B32; - CARD32 backingPixel B32; - BOOL saveUnder; - BOOL mapInstalled; - CARD8 mapState; - BOOL override; - Colormap colormap B32; - CARD32 allEventMasks B32; - CARD32 yourEventMask B32; - CARD16 doNotPropagateMask B16; - CARD16 pad B16; - } xGetWindowAttributesReply; + CARD8 bitGravity; + CARD8 winGravity; + CARD32 backingBitPlanes B32; + CARD32 backingPixel B32; + BOOL saveUnder; + BOOL mapInstalled; + CARD8 mapState; + BOOL override; + Colormap colormap B32; + CARD32 allEventMasks B32; + CARD32 yourEventMask B32; + CARD16 doNotPropagateMask B16; + CARD16 pad B16; +} xGetWindowAttributesReply; -typedef struct { - BYTE type; /* X_Reply */ - CARD8 depth; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - Window root B32; - INT16 x B16, y B16; - CARD16 width B16, height B16; - CARD16 borderWidth B16; - CARD16 pad1 B16; - CARD32 pad2 B32; - CARD32 pad3 B32; - } xGetGeometryReply; +typedef struct +{ + BYTE type; /* X_Reply */ + CARD8 depth; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + Window root B32; + INT16 x B16, y B16; + CARD16 width B16, height B16; + CARD16 borderWidth B16; + CARD16 pad1 B16; + CARD32 pad2 B32; + CARD32 pad3 B32; +} xGetGeometryReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - Window root B32, parent B32; - CARD16 nChildren B16; - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - } xQueryTreeReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + Window root B32, parent B32; + CARD16 nChildren B16; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xQueryTreeReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - Atom atom B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - } xInternAtomReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + Atom atom B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xInternAtomReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* of additional bytes */ - CARD16 nameLength B16; /* # of characters in name */ - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xGetAtomNameReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* of additional bytes */ + CARD16 nameLength B16; /* # of characters in name */ + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xGetAtomNameReply; -typedef struct { - BYTE type; /* X_Reply */ - CARD8 format; - CARD16 sequenceNumber B16; - CARD32 length B32; /* of additional bytes */ - Atom propertyType B32; - CARD32 bytesAfter B32; - CARD32 nItems B32; /* # of 8, 16, or 32-bit entities in reply */ - CARD32 pad1 B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - } xGetPropertyReply; +typedef struct +{ + BYTE type; /* X_Reply */ + CARD8 format; + CARD16 sequenceNumber B16; + CARD32 length B32; /* of additional bytes */ + Atom propertyType B32; + CARD32 bytesAfter B32; + CARD32 nItems B32; /* # of 8, 16, or 32-bit entities in reply */ + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; +} xGetPropertyReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 nProperties B16; - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xListPropertiesReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 nProperties B16; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xListPropertiesReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - Window owner B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - } xGetSelectionOwnerReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + Window owner B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xGetSelectionOwnerReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE status; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - CARD32 pad1 B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - } xGrabPointerReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE status; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xGrabPointerReply; typedef xGrabPointerReply xGrabKeyboardReply; -typedef struct { - BYTE type; /* X_Reply */ - BOOL sameScreen; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - Window root B32, child B32; - INT16 rootX B16, rootY B16, winX B16, winY B16; - CARD16 mask B16; - CARD16 pad1 B16; - CARD32 pad B32; - } xQueryPointerReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL sameScreen; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + Window root B32, child B32; + INT16 rootX B16, rootY B16, winX B16, winY B16; + CARD16 mask B16; + CARD16 pad1 B16; + CARD32 pad B32; +} xQueryPointerReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 nEvents B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - } xGetMotionEventsReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 nEvents B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xGetMotionEventsReply; -typedef struct { - BYTE type; /* X_Reply */ - BOOL sameScreen; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - Window child B32; - INT16 dstX B16, dstY B16; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - } xTranslateCoordsReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL sameScreen; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + Window child B32; + INT16 dstX B16, dstY B16; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xTranslateCoordsReply; -typedef struct { - BYTE type; /* X_Reply */ - CARD8 revertTo; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - Window focus B32; - CARD32 pad1 B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - } xGetInputFocusReply; +typedef struct +{ + BYTE type; /* X_Reply */ + CARD8 revertTo; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + Window focus B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xGetInputFocusReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 2, NOT 0; this is an extra-large reply */ - BYTE map[32]; - } xQueryKeymapReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 2, NOT 0; this is an extra-large reply */ + BYTE map[32]; +} xQueryKeymapReply; /* Warning: this MUST match (up to component renaming) xListFontsWithInfoReply */ -typedef struct _xQueryFontReply { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* definitely > 0, even if "nCharInfos" is 0 */ - xCharInfo minBounds; +typedef struct _xQueryFontReply +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* definitely > 0, even if "nCharInfos" is 0 */ + xCharInfo minBounds; #ifndef WORD64 - CARD32 walign1 B32; + CARD32 walign1 B32; #endif - xCharInfo maxBounds; + xCharInfo maxBounds; #ifndef WORD64 - CARD32 walign2 B32; + CARD32 walign2 B32; #endif - CARD16 minCharOrByte2 B16, maxCharOrByte2 B16; - CARD16 defaultChar B16; - CARD16 nFontProps B16; /* followed by this many xFontProp structures */ - CARD8 drawDirection; - CARD8 minByte1, maxByte1; - BOOL allCharsExist; - INT16 fontAscent B16, fontDescent B16; - CARD32 nCharInfos B32; /* followed by this many xCharInfo structures */ + CARD16 minCharOrByte2 B16, maxCharOrByte2 B16; + CARD16 defaultChar B16; + CARD16 nFontProps B16; /* followed by this many xFontProp structures */ + CARD8 drawDirection; + CARD8 minByte1, maxByte1; + BOOL allCharsExist; + INT16 fontAscent B16, fontDescent B16; + CARD32 nCharInfos B32; /* followed by this many xCharInfo structures */ } xQueryFontReply; -typedef struct { - BYTE type; /* X_Reply */ - CARD8 drawDirection; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - INT16 fontAscent B16, fontDescent B16; - INT16 overallAscent B16, overallDescent B16; - INT32 overallWidth B32, overallLeft B32, overallRight B32; - CARD32 pad B32; - } xQueryTextExtentsReply; +typedef struct +{ + BYTE type; /* X_Reply */ + CARD8 drawDirection; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + INT16 fontAscent B16, fontDescent B16; + INT16 overallAscent B16, overallDescent B16; + INT32 overallWidth B32, overallLeft B32, overallRight B32; + CARD32 pad B32; +} xQueryTextExtentsReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 nFonts B16; - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xListFontsReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 nFonts B16; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xListFontsReply; /* Warning: this MUST match (up to component renaming) xQueryFontReply */ -typedef struct { - BYTE type; /* X_Reply */ - CARD8 nameLength; /* 0 indicates end-of-reply-sequence */ - CARD16 sequenceNumber B16; - CARD32 length B32; /* definitely > 0, even if "nameLength" is 0 */ - xCharInfo minBounds; +typedef struct +{ + BYTE type; /* X_Reply */ + CARD8 nameLength; /* 0 indicates end-of-reply-sequence */ + CARD16 sequenceNumber B16; + CARD32 length B32; /* definitely > 0, even if "nameLength" is 0 */ + xCharInfo minBounds; #ifndef WORD64 - CARD32 walign1 B32; + CARD32 walign1 B32; #endif - xCharInfo maxBounds; + xCharInfo maxBounds; #ifndef WORD64 - CARD32 walign2 B32; + CARD32 walign2 B32; #endif - CARD16 minCharOrByte2 B16, maxCharOrByte2 B16; - CARD16 defaultChar B16; - CARD16 nFontProps B16; /* followed by this many xFontProp structures */ - CARD8 drawDirection; - CARD8 minByte1, maxByte1; - BOOL allCharsExist; - INT16 fontAscent B16, fontDescent B16; - CARD32 nReplies B32; /* hint as to how many more replies might be coming */ + CARD16 minCharOrByte2 B16, maxCharOrByte2 B16; + CARD16 defaultChar B16; + CARD16 nFontProps B16; /* followed by this many xFontProp structures */ + CARD8 drawDirection; + CARD8 minByte1, maxByte1; + BOOL allCharsExist; + INT16 fontAscent B16, fontDescent B16; + CARD32 nReplies B32; /* hint as to how many more replies might be coming */ } xListFontsWithInfoReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 nPaths B16; - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xGetFontPathReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 nPaths B16; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xGetFontPathReply; -typedef struct { - BYTE type; /* X_Reply */ - CARD8 depth; - CARD16 sequenceNumber B16; - CARD32 length B32; - VisualID visual B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xGetImageReply; +typedef struct +{ + BYTE type; /* X_Reply */ + CARD8 depth; + CARD16 sequenceNumber B16; + CARD32 length B32; + VisualID visual B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xGetImageReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 nColormaps B16; - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xListInstalledColormapsReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 nColormaps B16; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xListInstalledColormapsReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - CARD16 red B16, green B16, blue B16; - CARD16 pad2 B16; - CARD32 pixel B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - } xAllocColorReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + CARD16 red B16, green B16, blue B16; + CARD16 pad2 B16; + CARD32 pixel B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xAllocColorReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - CARD32 pixel B32; - CARD16 exactRed B16, exactGreen B16, exactBlue B16; - CARD16 screenRed B16, screenGreen B16, screenBlue B16; - CARD32 pad2 B32; - CARD32 pad3 B32; - } xAllocNamedColorReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + CARD32 pixel B32; + CARD16 exactRed B16, exactGreen B16, exactBlue B16; + CARD16 screenRed B16, screenGreen B16, screenBlue B16; + CARD32 pad2 B32; + CARD32 pad3 B32; +} xAllocNamedColorReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 nPixels B16, nMasks B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xAllocColorCellsReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 nPixels B16, nMasks B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xAllocColorCellsReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 nPixels B16; - CARD16 pad2 B16; - CARD32 redMask B32, greenMask B32, blueMask B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - } xAllocColorPlanesReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 nPixels B16; + CARD16 pad2 B16; + CARD32 redMask B32, greenMask B32, blueMask B32; + CARD32 pad3 B32; + CARD32 pad4 B32; +} xAllocColorPlanesReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 nColors B16; - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xQueryColorsReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 nColors B16; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xQueryColorsReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - CARD16 exactRed B16, exactGreen B16, exactBlue B16; - CARD16 screenRed B16, screenGreen B16, screenBlue B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - } xLookupColorReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + CARD16 exactRed B16, exactGreen B16, exactBlue B16; + CARD16 screenRed B16, screenGreen B16, screenBlue B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; +} xLookupColorReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - CARD16 width B16, height B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xQueryBestSizeReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + CARD16 width B16, height B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xQueryBestSizeReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - BOOL present; - CARD8 major_opcode; - CARD8 first_event; - CARD8 first_error; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xQueryExtensionReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + BOOL present; + CARD8 major_opcode; + CARD8 first_event; + CARD8 first_error; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xQueryExtensionReply; -typedef struct { - BYTE type; /* X_Reply */ - CARD8 nExtensions; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xListExtensionsReply; +typedef struct +{ + BYTE type; /* X_Reply */ + CARD8 nExtensions; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xListExtensionsReply; - -typedef struct { - BYTE type; /* X_Reply */ - CARD8 success; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xSetMappingReply; +typedef struct +{ + BYTE type; /* X_Reply */ + CARD8 success; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xSetMappingReply; typedef xSetMappingReply xSetPointerMappingReply; typedef xSetMappingReply xSetModifierMappingReply; -typedef struct { - BYTE type; /* X_Reply */ - CARD8 nElts; /* how many elements does the map have */ - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xGetPointerMappingReply; +typedef struct +{ + BYTE type; /* X_Reply */ + CARD8 nElts; /* how many elements does the map have */ + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xGetPointerMappingReply; -typedef struct { - BYTE type; - CARD8 keySymsPerKeyCode; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; -} xGetKeyboardMappingReply; +typedef struct +{ + BYTE type; + CARD8 keySymsPerKeyCode; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xGetKeyboardMappingReply; -typedef struct { - BYTE type; - CARD8 numKeyPerModifier; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD32 pad1 B32; - CARD32 pad2 B32; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; +typedef struct +{ + BYTE type; + CARD8 numKeyPerModifier; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD32 pad1 B32; + CARD32 pad2 B32; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; } xGetModifierMappingReply; -typedef struct { - BYTE type; /* X_Reply */ - BOOL globalAutoRepeat; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 5 */ - CARD32 ledMask B32; - CARD8 keyClickPercent, bellPercent; - CARD16 bellPitch B16, bellDuration B16; - CARD16 pad B16; - BYTE map[32]; /* bit masks start here */ - } xGetKeyboardControlReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL globalAutoRepeat; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 5 */ + CARD32 ledMask B32; + CARD8 keyClickPercent, bellPercent; + CARD16 bellPitch B16, bellDuration B16; + CARD16 pad B16; + BYTE map[32]; /* bit masks start here */ +} xGetKeyboardControlReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - CARD16 accelNumerator B16, accelDenominator B16; - CARD16 threshold B16; - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - } xGetPointerControlReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + CARD16 accelNumerator B16, accelDenominator B16; + CARD16 threshold B16; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xGetPointerControlReply; -typedef struct { - BYTE type; /* X_Reply */ - BYTE pad1; - CARD16 sequenceNumber B16; - CARD32 length B32; /* 0 */ - CARD16 timeout B16, interval B16; - BOOL preferBlanking; - BOOL allowExposures; - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - } xGetScreenSaverReply; - -typedef struct { - BYTE type; /* X_Reply */ - BOOL enabled; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 nHosts B16; - CARD16 pad1 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; - } xListHostsReply; - - +typedef struct +{ + BYTE type; /* X_Reply */ + BYTE pad1; + CARD16 sequenceNumber B16; + CARD32 length B32; /* 0 */ + CARD16 timeout B16, interval B16; + BOOL preferBlanking; + BOOL allowExposures; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; +} xGetScreenSaverReply; +typedef struct +{ + BYTE type; /* X_Reply */ + BOOL enabled; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 nHosts B16; + CARD16 pad1 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; +} xListHostsReply; /***************************************************************** * Xerror * All errors are 32 bytes *****************************************************************/ -typedef struct { - BYTE type; /* X_Error */ - BYTE errorCode; - CARD16 sequenceNumber B16; /* the nth request from this client */ - CARD32 resourceID B32; - CARD16 minorCode B16; - CARD8 majorCode; - BYTE pad1; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; +typedef struct +{ + BYTE type; /* X_Error */ + BYTE errorCode; + CARD16 sequenceNumber B16; /* the nth request from this client */ + CARD32 resourceID B32; + CARD16 minorCode B16; + CARD8 majorCode; + BYTE pad1; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; } xError; /***************************************************************** @@ -988,77 +1031,87 @@ typedef struct { * All events are 32 bytes *****************************************************************/ -typedef struct _xEvent { - union { - struct { - BYTE type; - BYTE detail; - CARD16 sequenceNumber B16; - } u; - struct { - CARD32 pad00 B32; - Time time B32; - Window root B32, event B32, child B32; - INT16 rootX B16, rootY B16, eventX B16, eventY B16; - KeyButMask state B16; - BOOL sameScreen; - BYTE pad1; - } keyButtonPointer; - struct { - CARD32 pad00 B32; - Time time B32; - Window root B32, event B32, child B32; - INT16 rootX B16, rootY B16, eventX B16, eventY B16; - KeyButMask state B16; - BYTE mode; /* really XMode */ - BYTE flags; /* sameScreen and focus booleans, packed together */ -#define ELFlagFocus (1<<0) -#define ELFlagSameScreen (1<<1) - } enterLeave; - struct { - CARD32 pad00 B32; - Window window B32; - BYTE mode; /* really XMode */ - BYTE pad1, pad2, pad3; - } focus; - struct { - CARD32 pad00 B32; - Window window B32; - CARD16 x B16, y B16, width B16, height B16; - CARD16 count B16; - CARD16 pad2 B16; - } expose; - struct { - CARD32 pad00 B32; - Drawable drawable B32; - CARD16 x B16, y B16, width B16, height B16; - CARD16 minorEvent B16; - CARD16 count B16; - BYTE majorEvent; - BYTE pad1, pad2, pad3; - } graphicsExposure; - struct { - CARD32 pad00 B32; - Drawable drawable B32; - CARD16 minorEvent B16; - BYTE majorEvent; - BYTE bpad; - } noExposure; - struct { - CARD32 pad00 B32; - Window window B32; - CARD8 state; - BYTE pad1, pad2, pad3; - } visibility; - struct { - CARD32 pad00 B32; - Window parent B32, window B32; - INT16 x B16, y B16; - CARD16 width B16, height B16, borderWidth B16; - BOOL override; - BYTE bpad; - } createNotify; -/* +typedef struct _xEvent +{ + union { + struct + { + BYTE type; + BYTE detail; + CARD16 sequenceNumber B16; + } u; + struct + { + CARD32 pad00 B32; + Time time B32; + Window root B32, event B32, child B32; + INT16 rootX B16, rootY B16, eventX B16, eventY B16; + KeyButMask state B16; + BOOL sameScreen; + BYTE pad1; + } keyButtonPointer; + struct + { + CARD32 pad00 B32; + Time time B32; + Window root B32, event B32, child B32; + INT16 rootX B16, rootY B16, eventX B16, eventY B16; + KeyButMask state B16; + BYTE mode; /* really XMode */ + BYTE flags; /* sameScreen and focus booleans, packed together */ +#define ELFlagFocus (1 << 0) +#define ELFlagSameScreen (1 << 1) + } enterLeave; + struct + { + CARD32 pad00 B32; + Window window B32; + BYTE mode; /* really XMode */ + BYTE pad1, pad2, pad3; + } focus; + struct + { + CARD32 pad00 B32; + Window window B32; + CARD16 x B16, y B16, width B16, height B16; + CARD16 count B16; + CARD16 pad2 B16; + } expose; + struct + { + CARD32 pad00 B32; + Drawable drawable B32; + CARD16 x B16, y B16, width B16, height B16; + CARD16 minorEvent B16; + CARD16 count B16; + BYTE majorEvent; + BYTE pad1, pad2, pad3; + } graphicsExposure; + struct + { + CARD32 pad00 B32; + Drawable drawable B32; + CARD16 minorEvent B16; + BYTE majorEvent; + BYTE bpad; + } noExposure; + struct + { + CARD32 pad00 B32; + Window window B32; + CARD8 state; + BYTE pad1, pad2, pad3; + } visibility; + struct + { + CARD32 pad00 B32; + Window parent B32, window B32; + INT16 x B16, y B16; + CARD16 width B16, height B16, borderWidth B16; + BOOL override; + BYTE bpad; + } createNotify; + /* * The event fields in the structures for DestroyNotify, UnmapNotify, * MapNotify, ReparentNotify, ConfigureNotify, CirculateNotify, GravityNotify, * must be at the same offset because server internal code is depending upon @@ -1066,146 +1119,166 @@ typedef struct _xEvent { * Also note that MapRequest, ConfigureRequest and CirculateRequest have * the same offset for the event window. */ - struct { - CARD32 pad00 B32; - Window event B32, window B32; - } destroyNotify; - struct { - CARD32 pad00 B32; - Window event B32, window B32; - BOOL fromConfigure; - BYTE pad1, pad2, pad3; - } unmapNotify; - struct { - CARD32 pad00 B32; - Window event B32, window B32; - BOOL override; - BYTE pad1, pad2, pad3; - } mapNotify; - struct { - CARD32 pad00 B32; - Window parent B32, window B32; - } mapRequest; - struct { - CARD32 pad00 B32; - Window event B32, window B32, parent B32; - INT16 x B16, y B16; - BOOL override; - BYTE pad1, pad2, pad3; - } reparent; - struct { - CARD32 pad00 B32; - Window event B32, window B32, aboveSibling B32; - INT16 x B16, y B16; - CARD16 width B16, height B16, borderWidth B16; - BOOL override; - BYTE bpad; - } configureNotify; - struct { - CARD32 pad00 B32; - Window parent B32, window B32, sibling B32; - INT16 x B16, y B16; - CARD16 width B16, height B16, borderWidth B16; - CARD16 valueMask B16; - CARD32 pad1 B32; - } configureRequest; - struct { - CARD32 pad00 B32; - Window event B32, window B32; - INT16 x B16, y B16; - CARD32 pad1 B32, pad2 B32, pad3 B32, pad4 B32; - } gravity; - struct { - CARD32 pad00 B32; - Window window B32; - CARD16 width B16, height B16; - } resizeRequest; - struct { -/* The event field in the circulate record is really the parent when this + struct + { + CARD32 pad00 B32; + Window event B32, window B32; + } destroyNotify; + struct + { + CARD32 pad00 B32; + Window event B32, window B32; + BOOL fromConfigure; + BYTE pad1, pad2, pad3; + } unmapNotify; + struct + { + CARD32 pad00 B32; + Window event B32, window B32; + BOOL override; + BYTE pad1, pad2, pad3; + } mapNotify; + struct + { + CARD32 pad00 B32; + Window parent B32, window B32; + } mapRequest; + struct + { + CARD32 pad00 B32; + Window event B32, window B32, parent B32; + INT16 x B16, y B16; + BOOL override; + BYTE pad1, pad2, pad3; + } reparent; + struct + { + CARD32 pad00 B32; + Window event B32, window B32, aboveSibling B32; + INT16 x B16, y B16; + CARD16 width B16, height B16, borderWidth B16; + BOOL override; + BYTE bpad; + } configureNotify; + struct + { + CARD32 pad00 B32; + Window parent B32, window B32, sibling B32; + INT16 x B16, y B16; + CARD16 width B16, height B16, borderWidth B16; + CARD16 valueMask B16; + CARD32 pad1 B32; + } configureRequest; + struct + { + CARD32 pad00 B32; + Window event B32, window B32; + INT16 x B16, y B16; + CARD32 pad1 B32, pad2 B32, pad3 B32, pad4 B32; + } gravity; + struct + { + CARD32 pad00 B32; + Window window B32; + CARD16 width B16, height B16; + } resizeRequest; + struct + { + /* The event field in the circulate record is really the parent when this is used as a CirculateRequest instead of a CirculateNotify */ - CARD32 pad00 B32; - Window event B32, window B32, parent B32; - BYTE place; /* Top or Bottom */ - BYTE pad1, pad2, pad3; - } circulate; - struct { - CARD32 pad00 B32; - Window window B32; - Atom atom B32; - Time time B32; - BYTE state; /* NewValue or Deleted */ - BYTE pad1; - CARD16 pad2 B16; - } property; - struct { - CARD32 pad00 B32; - Time time B32; - Window window B32; - Atom atom B32; - } selectionClear; - struct { - CARD32 pad00 B32; - Time time B32; - Window owner B32, requestor B32; - Atom selection B32, target B32, property B32; - } selectionRequest; - struct { - CARD32 pad00 B32; - Time time B32; - Window requestor B32; - Atom selection B32, target B32, property B32; - } selectionNotify; - struct { - CARD32 pad00 B32; - Window window B32; - Colormap colormap B32; + CARD32 pad00 B32; + Window event B32, window B32, parent B32; + BYTE place; /* Top or Bottom */ + BYTE pad1, pad2, pad3; + } circulate; + struct + { + CARD32 pad00 B32; + Window window B32; + Atom atom B32; + Time time B32; + BYTE state; /* NewValue or Deleted */ + BYTE pad1; + CARD16 pad2 B16; + } property; + struct + { + CARD32 pad00 B32; + Time time B32; + Window window B32; + Atom atom B32; + } selectionClear; + struct + { + CARD32 pad00 B32; + Time time B32; + Window owner B32, requestor B32; + Atom selection B32, target B32, property B32; + } selectionRequest; + struct + { + CARD32 pad00 B32; + Time time B32; + Window requestor B32; + Atom selection B32, target B32, property B32; + } selectionNotify; + struct + { + CARD32 pad00 B32; + Window window B32; + Colormap colormap B32; #if defined(__cplusplus) || defined(c_plusplus) - BOOL c_new; + BOOL c_new; #else - BOOL new; + BOOL new; #endif - BYTE state; /* Installed or UnInstalled */ - BYTE pad1, pad2; - } colormap; - struct { - CARD32 pad00 B32; - CARD8 request; - KeyCode firstKeyCode; - CARD8 count; - BYTE pad1; - } mappingNotify; - struct { - CARD32 pad00 B32; - Window window B32; - union { - struct { - Atom type B32; - INT32 longs0 B32; - INT32 longs1 B32; - INT32 longs2 B32; - INT32 longs3 B32; - INT32 longs4 B32; - } l; - struct { - Atom type B32; - INT16 shorts0 B16; - INT16 shorts1 B16; - INT16 shorts2 B16; - INT16 shorts3 B16; - INT16 shorts4 B16; - INT16 shorts5 B16; - INT16 shorts6 B16; - INT16 shorts7 B16; - INT16 shorts8 B16; - INT16 shorts9 B16; - } s; - struct { - Atom type B32; - INT8 bytes[20]; - } b; - } u; - } clientMessage; - } u; + BYTE state; /* Installed or UnInstalled */ + BYTE pad1, pad2; + } colormap; + struct + { + CARD32 pad00 B32; + CARD8 request; + KeyCode firstKeyCode; + CARD8 count; + BYTE pad1; + } mappingNotify; + struct + { + CARD32 pad00 B32; + Window window B32; + union { + struct + { + Atom type B32; + INT32 longs0 B32; + INT32 longs1 B32; + INT32 longs2 B32; + INT32 longs3 B32; + INT32 longs4 B32; + } l; + struct + { + Atom type B32; + INT16 shorts0 B16; + INT16 shorts1 B16; + INT16 shorts2 B16; + INT16 shorts3 B16; + INT16 shorts4 B16; + INT16 shorts5 B16; + INT16 shorts6 B16; + INT16 shorts7 B16; + INT16 shorts8 B16; + INT16 shorts9 B16; + } s; + struct + { + Atom type B32; + INT8 bytes[20]; + } b; + } u; + } clientMessage; + } u; } xEvent; /********************************************************* @@ -1223,31 +1296,30 @@ typedef struct _xEvent { * * */ -typedef struct +typedef struct { - BYTE type; - CARD8 extension; - CARD16 sequenceNumber B16; - CARD32 length B32; - CARD16 evtype B16; - CARD16 pad2 B16; - CARD32 pad3 B32; - CARD32 pad4 B32; - CARD32 pad5 B32; - CARD32 pad6 B32; - CARD32 pad7 B32; + BYTE type; + CARD8 extension; + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD16 evtype B16; + CARD16 pad2 B16; + CARD32 pad3 B32; + CARD32 pad4 B32; + CARD32 pad5 B32; + CARD32 pad6 B32; + CARD32 pad7 B32; } xGenericEvent; - - /* KeymapNotify events are not included in the above union because they are different from all other events: they do not have a "detail" or "sequenceNumber", so there is room for a 248-bit key mask. */ -typedef struct { - BYTE type; - BYTE map[31]; - } xKeymapEvent; +typedef struct +{ + BYTE type; + BYTE map[31]; +} xKeymapEvent; #define XEventSize (sizeof(xEvent)) @@ -1257,59 +1329,57 @@ QueryFontReply, QueryKeymapReply, or GetKeyboardControlReply ListFontsWithInfoReply */ typedef union { - xGenericReply generic; - xGetGeometryReply geom; - xQueryTreeReply tree; - xInternAtomReply atom; - xGetAtomNameReply atomName; - xGetPropertyReply property; - xListPropertiesReply listProperties; - xGetSelectionOwnerReply selection; - xGrabPointerReply grabPointer; - xGrabKeyboardReply grabKeyboard; - xQueryPointerReply pointer; - xGetMotionEventsReply motionEvents; - xTranslateCoordsReply coords; - xGetInputFocusReply inputFocus; - xQueryTextExtentsReply textExtents; - xListFontsReply fonts; - xGetFontPathReply fontPath; - xGetImageReply image; - xListInstalledColormapsReply colormaps; - xAllocColorReply allocColor; - xAllocNamedColorReply allocNamedColor; - xAllocColorCellsReply colorCells; - xAllocColorPlanesReply colorPlanes; - xQueryColorsReply colors; - xLookupColorReply lookupColor; - xQueryBestSizeReply bestSize; - xQueryExtensionReply extension; - xListExtensionsReply extensions; - xSetModifierMappingReply setModifierMapping; - xGetModifierMappingReply getModifierMapping; - xSetPointerMappingReply setPointerMapping; - xGetKeyboardMappingReply getKeyboardMapping; - xGetPointerMappingReply getPointerMapping; - xGetPointerControlReply pointerControl; - xGetScreenSaverReply screenSaver; - xListHostsReply hosts; - xError error; - xEvent event; + xGenericReply generic; + xGetGeometryReply geom; + xQueryTreeReply tree; + xInternAtomReply atom; + xGetAtomNameReply atomName; + xGetPropertyReply property; + xListPropertiesReply listProperties; + xGetSelectionOwnerReply selection; + xGrabPointerReply grabPointer; + xGrabKeyboardReply grabKeyboard; + xQueryPointerReply pointer; + xGetMotionEventsReply motionEvents; + xTranslateCoordsReply coords; + xGetInputFocusReply inputFocus; + xQueryTextExtentsReply textExtents; + xListFontsReply fonts; + xGetFontPathReply fontPath; + xGetImageReply image; + xListInstalledColormapsReply colormaps; + xAllocColorReply allocColor; + xAllocNamedColorReply allocNamedColor; + xAllocColorCellsReply colorCells; + xAllocColorPlanesReply colorPlanes; + xQueryColorsReply colors; + xLookupColorReply lookupColor; + xQueryBestSizeReply bestSize; + xQueryExtensionReply extension; + xListExtensionsReply extensions; + xSetModifierMappingReply setModifierMapping; + xGetModifierMappingReply getModifierMapping; + xSetPointerMappingReply setPointerMapping; + xGetKeyboardMappingReply getKeyboardMapping; + xGetPointerMappingReply getPointerMapping; + xGetPointerControlReply pointerControl; + xGetScreenSaverReply screenSaver; + xListHostsReply hosts; + xError error; + xEvent event; } xReply; - - /***************************************************************** * REQUESTS *****************************************************************/ - /* Request structure */ -typedef struct _xReq { +typedef struct _xReq +{ CARD8 reqType; - CARD8 data; /* meaning depends on request type */ - CARD16 length B16; /* length in 4 bytes quantities + CARD8 data; /* meaning depends on request type */ + CARD16 length B16; /* length in 4 bytes quantities of whole request, including this header */ } xReq; @@ -1320,825 +1390,896 @@ typedef struct _xReq { /* ResourceReq is used for any request which has a resource ID (or Atom or Time) as its one and only argument. */ -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - CARD32 id B32; /* a Window, Drawable, Font, GContext, Pixmap, etc. */ - } xResourceReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + CARD32 id B32; /* a Window, Drawable, Font, GContext, Pixmap, etc. */ +} xResourceReq; -typedef struct { - CARD8 reqType; - CARD8 depth; - CARD16 length B16; - Window wid B32, parent B32; - INT16 x B16, y B16; - CARD16 width B16, height B16, borderWidth B16; +typedef struct +{ + CARD8 reqType; + CARD8 depth; + CARD16 length B16; + Window wid B32, parent B32; + INT16 x B16, y B16; + CARD16 width B16, height B16, borderWidth B16; #if defined(__cplusplus) || defined(c_plusplus) - CARD16 c_class B16; + CARD16 c_class B16; #else - CARD16 class B16; + CARD16 class B16; #endif - VisualID visual B32; - CARD32 mask B32; + VisualID visual B32; + CARD32 mask B32; } xCreateWindowReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Window window B32; - CARD32 valueMask B32; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Window window B32; + CARD32 valueMask B32; } xChangeWindowAttributesReq; -typedef struct { - CARD8 reqType; - BYTE mode; - CARD16 length B16; - Window window B32; +typedef struct +{ + CARD8 reqType; + BYTE mode; + CARD16 length B16; + Window window B32; } xChangeSaveSetReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Window window B32, parent B32; - INT16 x B16, y B16; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Window window B32, parent B32; + INT16 x B16, y B16; } xReparentWindowReq; -typedef struct { - CARD8 reqType; - CARD8 pad; - CARD16 length B16; - Window window B32; - CARD16 mask B16; - CARD16 pad2 B16; +typedef struct +{ + CARD8 reqType; + CARD8 pad; + CARD16 length B16; + Window window B32; + CARD16 mask B16; + CARD16 pad2 B16; } xConfigureWindowReq; -typedef struct { - CARD8 reqType; - CARD8 direction; - CARD16 length B16; - Window window B32; +typedef struct +{ + CARD8 reqType; + CARD8 direction; + CARD16 length B16; + Window window B32; } xCirculateWindowReq; -typedef struct { /* followed by padded string */ - CARD8 reqType; - BOOL onlyIfExists; - CARD16 length B16; - CARD16 nbytes B16; /* number of bytes in string */ - CARD16 pad B16; +typedef struct +{ /* followed by padded string */ + CARD8 reqType; + BOOL onlyIfExists; + CARD16 length B16; + CARD16 nbytes B16; /* number of bytes in string */ + CARD16 pad B16; } xInternAtomReq; -typedef struct { - CARD8 reqType; - CARD8 mode; - CARD16 length B16; - Window window B32; - Atom property B32, type B32; - CARD8 format; - BYTE pad[3]; - CARD32 nUnits B32; /* length of stuff following, depends on format */ +typedef struct +{ + CARD8 reqType; + CARD8 mode; + CARD16 length B16; + Window window B32; + Atom property B32, type B32; + CARD8 format; + BYTE pad[3]; + CARD32 nUnits B32; /* length of stuff following, depends on format */ } xChangePropertyReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Window window B32; - Atom property B32; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Window window B32; + Atom property B32; } xDeletePropertyReq; -typedef struct { - CARD8 reqType; +typedef struct +{ + CARD8 reqType; #if defined(__cplusplus) || defined(c_plusplus) - BOOL c_delete; + BOOL c_delete; #else - BOOL delete; + BOOL delete; #endif - CARD16 length B16; - Window window B32; - Atom property B32, type B32; - CARD32 longOffset B32; - CARD32 longLength B32; + CARD16 length B16; + Window window B32; + Atom property B32, type B32; + CARD32 longOffset B32; + CARD32 longLength B32; } xGetPropertyReq; - -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Window window B32; - Atom selection B32; - Time time B32; + +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Window window B32; + Atom selection B32; + Time time B32; } xSetSelectionOwnerReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Window requestor B32; - Atom selection B32, target B32, property B32; - Time time B32; - } xConvertSelectionReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Window requestor B32; + Atom selection B32, target B32, property B32; + Time time B32; +} xConvertSelectionReq; -typedef struct { - CARD8 reqType; - BOOL propagate; - CARD16 length B16; - Window destination B32; - CARD32 eventMask B32; +typedef struct +{ + CARD8 reqType; + BOOL propagate; + CARD16 length B16; + Window destination B32; + CARD32 eventMask B32; #ifdef WORD64 - /* the structure should have been quad-aligned */ - BYTE eventdata[SIZEOF(xEvent)]; + /* the structure should have been quad-aligned */ + BYTE eventdata[SIZEOF(xEvent)]; #else - xEvent event; + xEvent event; #endif /* WORD64 */ } xSendEventReq; -typedef struct { - CARD8 reqType; - BOOL ownerEvents; - CARD16 length B16; - Window grabWindow B32; - CARD16 eventMask B16; - BYTE pointerMode, keyboardMode; - Window confineTo B32; - Cursor cursor B32; - Time time B32; +typedef struct +{ + CARD8 reqType; + BOOL ownerEvents; + CARD16 length B16; + Window grabWindow B32; + CARD16 eventMask B16; + BYTE pointerMode, keyboardMode; + Window confineTo B32; + Cursor cursor B32; + Time time B32; } xGrabPointerReq; -typedef struct { - CARD8 reqType; - BOOL ownerEvents; - CARD16 length B16; - Window grabWindow B32; - CARD16 eventMask B16; - BYTE pointerMode, keyboardMode; - Window confineTo B32; - Cursor cursor B32; - CARD8 button; - BYTE pad; - CARD16 modifiers B16; +typedef struct +{ + CARD8 reqType; + BOOL ownerEvents; + CARD16 length B16; + Window grabWindow B32; + CARD16 eventMask B16; + BYTE pointerMode, keyboardMode; + Window confineTo B32; + Cursor cursor B32; + CARD8 button; + BYTE pad; + CARD16 modifiers B16; } xGrabButtonReq; -typedef struct { - CARD8 reqType; - CARD8 button; - CARD16 length B16; - Window grabWindow B32; - CARD16 modifiers B16; - CARD16 pad B16; +typedef struct +{ + CARD8 reqType; + CARD8 button; + CARD16 length B16; + Window grabWindow B32; + CARD16 modifiers B16; + CARD16 pad B16; } xUngrabButtonReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Cursor cursor B32; - Time time B32; - CARD16 eventMask B16; - CARD16 pad2 B16; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Cursor cursor B32; + Time time B32; + CARD16 eventMask B16; + CARD16 pad2 B16; } xChangeActivePointerGrabReq; -typedef struct { - CARD8 reqType; - BOOL ownerEvents; - CARD16 length B16; - Window grabWindow B32; - Time time B32; - BYTE pointerMode, keyboardMode; - CARD16 pad B16; +typedef struct +{ + CARD8 reqType; + BOOL ownerEvents; + CARD16 length B16; + Window grabWindow B32; + Time time B32; + BYTE pointerMode, keyboardMode; + CARD16 pad B16; } xGrabKeyboardReq; -typedef struct { - CARD8 reqType; - BOOL ownerEvents; - CARD16 length B16; - Window grabWindow B32; - CARD16 modifiers B16; - CARD8 key; - BYTE pointerMode, keyboardMode; - BYTE pad1, pad2, pad3; +typedef struct +{ + CARD8 reqType; + BOOL ownerEvents; + CARD16 length B16; + Window grabWindow B32; + CARD16 modifiers B16; + CARD8 key; + BYTE pointerMode, keyboardMode; + BYTE pad1, pad2, pad3; } xGrabKeyReq; -typedef struct { - CARD8 reqType; - CARD8 key; - CARD16 length B16; - Window grabWindow B32; - CARD16 modifiers B16; - CARD16 pad B16; +typedef struct +{ + CARD8 reqType; + CARD8 key; + CARD16 length B16; + Window grabWindow B32; + CARD16 modifiers B16; + CARD16 pad B16; } xUngrabKeyReq; -typedef struct { - CARD8 reqType; - CARD8 mode; - CARD16 length B16; - Time time B32; +typedef struct +{ + CARD8 reqType; + CARD8 mode; + CARD16 length B16; + Time time B32; } xAllowEventsReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Window window B32; - Time start B32, stop B32; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Window window B32; + Time start B32, stop B32; } xGetMotionEventsReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Window srcWid B32, dstWid B32; - INT16 srcX B16, srcY B16; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Window srcWid B32, dstWid B32; + INT16 srcX B16, srcY B16; } xTranslateCoordsReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Window srcWid B32, dstWid B32; - INT16 srcX B16, srcY B16; - CARD16 srcWidth B16, srcHeight B16; - INT16 dstX B16, dstY B16; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Window srcWid B32, dstWid B32; + INT16 srcX B16, srcY B16; + CARD16 srcWidth B16, srcHeight B16; + INT16 dstX B16, dstY B16; } xWarpPointerReq; -typedef struct { - CARD8 reqType; - CARD8 revertTo; - CARD16 length B16; - Window focus B32; - Time time B32; +typedef struct +{ + CARD8 reqType; + CARD8 revertTo; + CARD16 length B16; + Window focus B32; + Time time B32; } xSetInputFocusReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Font fid B32; - CARD16 nbytes B16; - BYTE pad1, pad2; /* string follows on word boundary */ +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Font fid B32; + CARD16 nbytes B16; + BYTE pad1, pad2; /* string follows on word boundary */ } xOpenFontReq; -typedef struct { - CARD8 reqType; - BOOL oddLength; - CARD16 length B16; - Font fid B32; - } xQueryTextExtentsReq; +typedef struct +{ + CARD8 reqType; + BOOL oddLength; + CARD16 length B16; + Font fid B32; +} xQueryTextExtentsReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - CARD16 maxNames B16; - CARD16 nbytes B16; /* followed immediately by string bytes */ +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + CARD16 maxNames B16; + CARD16 nbytes B16; /* followed immediately by string bytes */ } xListFontsReq; typedef xListFontsReq xListFontsWithInfoReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - CARD16 nFonts B16; - BYTE pad1, pad2; /* LISTofSTRING8 follows on word boundary */ +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + CARD16 nFonts B16; + BYTE pad1, pad2; /* LISTofSTRING8 follows on word boundary */ } xSetFontPathReq; -typedef struct { - CARD8 reqType; - CARD8 depth; - CARD16 length B16; - Pixmap pid B32; - Drawable drawable B32; - CARD16 width B16, height B16; +typedef struct +{ + CARD8 reqType; + CARD8 depth; + CARD16 length B16; + Pixmap pid B32; + Drawable drawable B32; + CARD16 width B16, height B16; } xCreatePixmapReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - GContext gc B32; - Drawable drawable B32; - CARD32 mask B32; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + GContext gc B32; + Drawable drawable B32; + CARD32 mask B32; } xCreateGCReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - GContext gc B32; - CARD32 mask B32; -} xChangeGCReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + GContext gc B32; + CARD32 mask B32; +} xChangeGCReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - GContext srcGC B32, dstGC B32; - CARD32 mask B32; -} xCopyGCReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + GContext srcGC B32, dstGC B32; + CARD32 mask B32; +} xCopyGCReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - GContext gc B32; - CARD16 dashOffset B16; - CARD16 nDashes B16; /* length LISTofCARD8 of values following */ -} xSetDashesReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + GContext gc B32; + CARD16 dashOffset B16; + CARD16 nDashes B16; /* length LISTofCARD8 of values following */ +} xSetDashesReq; -typedef struct { - CARD8 reqType; - BYTE ordering; - CARD16 length B16; - GContext gc B32; - INT16 xOrigin B16, yOrigin B16; -} xSetClipRectanglesReq; +typedef struct +{ + CARD8 reqType; + BYTE ordering; + CARD16 length B16; + GContext gc B32; + INT16 xOrigin B16, yOrigin B16; +} xSetClipRectanglesReq; -typedef struct { - CARD8 reqType; - BOOL exposures; - CARD16 length B16; - Window window B32; - INT16 x B16, y B16; - CARD16 width B16, height B16; +typedef struct +{ + CARD8 reqType; + BOOL exposures; + CARD16 length B16; + Window window B32; + INT16 x B16, y B16; + CARD16 width B16, height B16; } xClearAreaReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Drawable srcDrawable B32, dstDrawable B32; - GContext gc B32; - INT16 srcX B16, srcY B16, dstX B16, dstY B16; - CARD16 width B16, height B16; -} xCopyAreaReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Drawable srcDrawable B32, dstDrawable B32; + GContext gc B32; + INT16 srcX B16, srcY B16, dstX B16, dstY B16; + CARD16 width B16, height B16; +} xCopyAreaReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Drawable srcDrawable B32, dstDrawable B32; - GContext gc B32; - INT16 srcX B16, srcY B16, dstX B16, dstY B16; - CARD16 width B16, height B16; - CARD32 bitPlane B32; -} xCopyPlaneReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Drawable srcDrawable B32, dstDrawable B32; + GContext gc B32; + INT16 srcX B16, srcY B16, dstX B16, dstY B16; + CARD16 width B16, height B16; + CARD32 bitPlane B32; +} xCopyPlaneReq; -typedef struct { - CARD8 reqType; - BYTE coordMode; - CARD16 length B16; - Drawable drawable B32; - GContext gc B32; -} xPolyPointReq; +typedef struct +{ + CARD8 reqType; + BYTE coordMode; + CARD16 length B16; + Drawable drawable B32; + GContext gc B32; +} xPolyPointReq; -typedef xPolyPointReq xPolyLineReq; /* same request structure */ +typedef xPolyPointReq xPolyLineReq; /* same request structure */ /* The following used for PolySegment, PolyRectangle, PolyArc, PolyFillRectangle, PolyFillArc */ -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Drawable drawable B32; - GContext gc B32; -} xPolySegmentReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Drawable drawable B32; + GContext gc B32; +} xPolySegmentReq; typedef xPolySegmentReq xPolyArcReq; typedef xPolySegmentReq xPolyRectangleReq; typedef xPolySegmentReq xPolyFillRectangleReq; typedef xPolySegmentReq xPolyFillArcReq; -typedef struct _FillPolyReq { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Drawable drawable B32; - GContext gc B32; - BYTE shape; - BYTE coordMode; - CARD16 pad1 B16; -} xFillPolyReq; +typedef struct _FillPolyReq +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Drawable drawable B32; + GContext gc B32; + BYTE shape; + BYTE coordMode; + CARD16 pad1 B16; +} xFillPolyReq; +typedef struct _PutImageReq +{ + CARD8 reqType; + CARD8 format; + CARD16 length B16; + Drawable drawable B32; + GContext gc B32; + CARD16 width B16, height B16; + INT16 dstX B16, dstY B16; + CARD8 leftPad; + CARD8 depth; + CARD16 pad B16; +} xPutImageReq; -typedef struct _PutImageReq { - CARD8 reqType; - CARD8 format; - CARD16 length B16; - Drawable drawable B32; - GContext gc B32; - CARD16 width B16, height B16; - INT16 dstX B16, dstY B16; - CARD8 leftPad; - CARD8 depth; - CARD16 pad B16; -} xPutImageReq; - -typedef struct { - CARD8 reqType; - CARD8 format; - CARD16 length B16; - Drawable drawable B32; - INT16 x B16, y B16; - CARD16 width B16, height B16; - CARD32 planeMask B32; -} xGetImageReq; +typedef struct +{ + CARD8 reqType; + CARD8 format; + CARD16 length B16; + Drawable drawable B32; + INT16 x B16, y B16; + CARD16 width B16, height B16; + CARD32 planeMask B32; +} xGetImageReq; /* the following used by PolyText8 and PolyText16 */ -typedef struct { - CARD8 reqType; - CARD8 pad; - CARD16 length B16; - Drawable drawable B32; - GContext gc B32; - INT16 x B16, y B16; /* items (xTextElt) start after struct */ -} xPolyTextReq; +typedef struct +{ + CARD8 reqType; + CARD8 pad; + CARD16 length B16; + Drawable drawable B32; + GContext gc B32; + INT16 x B16, y B16; /* items (xTextElt) start after struct */ +} xPolyTextReq; typedef xPolyTextReq xPolyText8Req; typedef xPolyTextReq xPolyText16Req; -typedef struct { - CARD8 reqType; - BYTE nChars; - CARD16 length B16; - Drawable drawable B32; - GContext gc B32; - INT16 x B16, y B16; -} xImageTextReq; +typedef struct +{ + CARD8 reqType; + BYTE nChars; + CARD16 length B16; + Drawable drawable B32; + GContext gc B32; + INT16 x B16, y B16; +} xImageTextReq; typedef xImageTextReq xImageText8Req; typedef xImageTextReq xImageText16Req; -typedef struct { - CARD8 reqType; - BYTE alloc; - CARD16 length B16; - Colormap mid B32; - Window window B32; - VisualID visual B32; -} xCreateColormapReq; +typedef struct +{ + CARD8 reqType; + BYTE alloc; + CARD16 length B16; + Colormap mid B32; + Window window B32; + VisualID visual B32; +} xCreateColormapReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Colormap mid B32; - Colormap srcCmap B32; -} xCopyColormapAndFreeReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Colormap mid B32; + Colormap srcCmap B32; +} xCopyColormapAndFreeReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Colormap cmap B32; - CARD16 red B16, green B16, blue B16; - CARD16 pad2 B16; -} xAllocColorReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Colormap cmap B32; + CARD16 red B16, green B16, blue B16; + CARD16 pad2 B16; +} xAllocColorReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Colormap cmap B32; - CARD16 nbytes B16; /* followed by structure */ - BYTE pad1, pad2; -} xAllocNamedColorReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Colormap cmap B32; + CARD16 nbytes B16; /* followed by structure */ + BYTE pad1, pad2; +} xAllocNamedColorReq; -typedef struct { - CARD8 reqType; - BOOL contiguous; - CARD16 length B16; - Colormap cmap B32; - CARD16 colors B16, planes B16; -} xAllocColorCellsReq; +typedef struct +{ + CARD8 reqType; + BOOL contiguous; + CARD16 length B16; + Colormap cmap B32; + CARD16 colors B16, planes B16; +} xAllocColorCellsReq; -typedef struct { - CARD8 reqType; - BOOL contiguous; - CARD16 length B16; - Colormap cmap B32; - CARD16 colors B16, red B16, green B16, blue B16; -} xAllocColorPlanesReq; +typedef struct +{ + CARD8 reqType; + BOOL contiguous; + CARD16 length B16; + Colormap cmap B32; + CARD16 colors B16, red B16, green B16, blue B16; +} xAllocColorPlanesReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Colormap cmap B32; - CARD32 planeMask B32; -} xFreeColorsReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Colormap cmap B32; + CARD32 planeMask B32; +} xFreeColorsReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Colormap cmap B32; -} xStoreColorsReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Colormap cmap B32; +} xStoreColorsReq; -typedef struct { - CARD8 reqType; - CARD8 flags; /* DoRed, DoGreen, DoBlue, as in xColorItem */ - CARD16 length B16; - Colormap cmap B32; - CARD32 pixel B32; - CARD16 nbytes B16; /* number of name string bytes following structure */ - BYTE pad1, pad2; - } xStoreNamedColorReq; +typedef struct +{ + CARD8 reqType; + CARD8 flags; /* DoRed, DoGreen, DoBlue, as in xColorItem */ + CARD16 length B16; + Colormap cmap B32; + CARD32 pixel B32; + CARD16 nbytes B16; /* number of name string bytes following structure */ + BYTE pad1, pad2; +} xStoreNamedColorReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Colormap cmap B32; -} xQueryColorsReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Colormap cmap B32; +} xQueryColorsReq; -typedef struct { /* followed by string of length len */ - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Colormap cmap B32; - CARD16 nbytes B16; /* number of string bytes following structure*/ - BYTE pad1, pad2; -} xLookupColorReq; +typedef struct +{ /* followed by string of length len */ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Colormap cmap B32; + CARD16 nbytes B16; /* number of string bytes following structure*/ + BYTE pad1, pad2; +} xLookupColorReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Cursor cid B32; - Pixmap source B32, mask B32; - CARD16 foreRed B16, foreGreen B16, foreBlue B16; - CARD16 backRed B16, backGreen B16, backBlue B16; - CARD16 x B16, y B16; -} xCreateCursorReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Cursor cid B32; + Pixmap source B32, mask B32; + CARD16 foreRed B16, foreGreen B16, foreBlue B16; + CARD16 backRed B16, backGreen B16, backBlue B16; + CARD16 x B16, y B16; +} xCreateCursorReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Cursor cid B32; - Font source B32, mask B32; - CARD16 sourceChar B16, maskChar B16; - CARD16 foreRed B16, foreGreen B16, foreBlue B16; - CARD16 backRed B16, backGreen B16, backBlue B16; -} xCreateGlyphCursorReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Cursor cid B32; + Font source B32, mask B32; + CARD16 sourceChar B16, maskChar B16; + CARD16 foreRed B16, foreGreen B16, foreBlue B16; + CARD16 backRed B16, backGreen B16, backBlue B16; +} xCreateGlyphCursorReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Cursor cursor B32; - CARD16 foreRed B16, foreGreen B16, foreBlue B16; - CARD16 backRed B16, backGreen B16, backBlue B16; -} xRecolorCursorReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Cursor cursor B32; + CARD16 foreRed B16, foreGreen B16, foreBlue B16; + CARD16 backRed B16, backGreen B16, backBlue B16; +} xRecolorCursorReq; -typedef struct { - CARD8 reqType; +typedef struct +{ + CARD8 reqType; #if defined(__cplusplus) || defined(c_plusplus) - CARD8 c_class; + CARD8 c_class; #else - CARD8 class; + CARD8 class; #endif - CARD16 length B16; - Drawable drawable B32; - CARD16 width B16, height B16; -} xQueryBestSizeReq; + CARD16 length B16; + Drawable drawable B32; + CARD16 width B16, height B16; +} xQueryBestSizeReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - CARD16 nbytes B16; /* number of string bytes following structure */ - BYTE pad1, pad2; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + CARD16 nbytes B16; /* number of string bytes following structure */ + BYTE pad1, pad2; } xQueryExtensionReq; -typedef struct { - CARD8 reqType; - CARD8 numKeyPerModifier; - CARD16 length B16; +typedef struct +{ + CARD8 reqType; + CARD8 numKeyPerModifier; + CARD16 length B16; } xSetModifierMappingReq; -typedef struct { - CARD8 reqType; - CARD8 nElts; /* how many elements in the map */ - CARD16 length B16; +typedef struct +{ + CARD8 reqType; + CARD8 nElts; /* how many elements in the map */ + CARD16 length B16; } xSetPointerMappingReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - KeyCode firstKeyCode; - CARD8 count; - CARD16 pad1 B16; -} xGetKeyboardMappingReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + KeyCode firstKeyCode; + CARD8 count; + CARD16 pad1 B16; +} xGetKeyboardMappingReq; -typedef struct { - CARD8 reqType; - CARD8 keyCodes; - CARD16 length B16; - KeyCode firstKeyCode; - CARD8 keySymsPerKeyCode; - CARD16 pad1 B16; +typedef struct +{ + CARD8 reqType; + CARD8 keyCodes; + CARD16 length B16; + KeyCode firstKeyCode; + CARD8 keySymsPerKeyCode; + CARD16 pad1 B16; } xChangeKeyboardMappingReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - CARD32 mask B32; -} xChangeKeyboardControlReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + CARD32 mask B32; +} xChangeKeyboardControlReq; -typedef struct { - CARD8 reqType; - INT8 percent; /* -100 to 100 */ - CARD16 length B16; -} xBellReq; +typedef struct +{ + CARD8 reqType; + INT8 percent; /* -100 to 100 */ + CARD16 length B16; +} xBellReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - INT16 accelNum B16, accelDenum B16; - INT16 threshold B16; - BOOL doAccel, doThresh; -} xChangePointerControlReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + INT16 accelNum B16, accelDenum B16; + INT16 threshold B16; + BOOL doAccel, doThresh; +} xChangePointerControlReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - INT16 timeout B16, interval B16; - BYTE preferBlank, allowExpose; - CARD16 pad2 B16; -} xSetScreenSaverReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + INT16 timeout B16, interval B16; + BYTE preferBlank, allowExpose; + CARD16 pad2 B16; +} xSetScreenSaverReq; -typedef struct { - CARD8 reqType; - BYTE mode; - CARD16 length B16; - CARD8 hostFamily; - BYTE pad; - CARD16 hostLength B16; -} xChangeHostsReq; +typedef struct +{ + CARD8 reqType; + BYTE mode; + CARD16 length B16; + CARD8 hostFamily; + BYTE pad; + CARD16 hostLength B16; +} xChangeHostsReq; -typedef struct { - CARD8 reqType; - BYTE pad; - CARD16 length B16; - } xListHostsReq; +typedef struct +{ + CARD8 reqType; + BYTE pad; + CARD16 length B16; +} xListHostsReq; -typedef struct { - CARD8 reqType; - BYTE mode; - CARD16 length B16; - } xChangeModeReq; +typedef struct +{ + CARD8 reqType; + BYTE mode; + CARD16 length B16; +} xChangeModeReq; typedef xChangeModeReq xSetAccessControlReq; typedef xChangeModeReq xSetCloseDownModeReq; typedef xChangeModeReq xForceScreenSaverReq; -typedef struct { /* followed by LIST of ATOM */ - CARD8 reqType; - BYTE pad; - CARD16 length B16; - Window window B32; - CARD16 nAtoms B16; - INT16 nPositions B16; - } xRotatePropertiesReq; - - +typedef struct +{ /* followed by LIST of ATOM */ + CARD8 reqType; + BYTE pad; + CARD16 length B16; + Window window B32; + CARD16 nAtoms B16; + INT16 nPositions B16; +} xRotatePropertiesReq; /* Reply codes */ -#define X_Reply 1 /* Normal reply */ -#define X_Error 0 /* Error */ +#define X_Reply 1 /* Normal reply */ +#define X_Error 0 /* Error */ /* Request codes */ -#define X_CreateWindow 1 -#define X_ChangeWindowAttributes 2 -#define X_GetWindowAttributes 3 -#define X_DestroyWindow 4 -#define X_DestroySubwindows 5 -#define X_ChangeSaveSet 6 -#define X_ReparentWindow 7 -#define X_MapWindow 8 -#define X_MapSubwindows 9 -#define X_UnmapWindow 10 -#define X_UnmapSubwindows 11 -#define X_ConfigureWindow 12 -#define X_CirculateWindow 13 -#define X_GetGeometry 14 -#define X_QueryTree 15 -#define X_InternAtom 16 -#define X_GetAtomName 17 -#define X_ChangeProperty 18 -#define X_DeleteProperty 19 -#define X_GetProperty 20 -#define X_ListProperties 21 -#define X_SetSelectionOwner 22 -#define X_GetSelectionOwner 23 -#define X_ConvertSelection 24 -#define X_SendEvent 25 -#define X_GrabPointer 26 -#define X_UngrabPointer 27 -#define X_GrabButton 28 -#define X_UngrabButton 29 -#define X_ChangeActivePointerGrab 30 -#define X_GrabKeyboard 31 -#define X_UngrabKeyboard 32 -#define X_GrabKey 33 -#define X_UngrabKey 34 -#define X_AllowEvents 35 -#define X_GrabServer 36 -#define X_UngrabServer 37 -#define X_QueryPointer 38 -#define X_GetMotionEvents 39 -#define X_TranslateCoords 40 -#define X_WarpPointer 41 -#define X_SetInputFocus 42 -#define X_GetInputFocus 43 -#define X_QueryKeymap 44 -#define X_OpenFont 45 -#define X_CloseFont 46 -#define X_QueryFont 47 -#define X_QueryTextExtents 48 -#define X_ListFonts 49 -#define X_ListFontsWithInfo 50 -#define X_SetFontPath 51 -#define X_GetFontPath 52 -#define X_CreatePixmap 53 -#define X_FreePixmap 54 -#define X_CreateGC 55 -#define X_ChangeGC 56 -#define X_CopyGC 57 -#define X_SetDashes 58 -#define X_SetClipRectangles 59 -#define X_FreeGC 60 -#define X_ClearArea 61 -#define X_CopyArea 62 -#define X_CopyPlane 63 -#define X_PolyPoint 64 -#define X_PolyLine 65 -#define X_PolySegment 66 -#define X_PolyRectangle 67 -#define X_PolyArc 68 -#define X_FillPoly 69 -#define X_PolyFillRectangle 70 -#define X_PolyFillArc 71 -#define X_PutImage 72 -#define X_GetImage 73 -#define X_PolyText8 74 -#define X_PolyText16 75 -#define X_ImageText8 76 -#define X_ImageText16 77 -#define X_CreateColormap 78 -#define X_FreeColormap 79 -#define X_CopyColormapAndFree 80 -#define X_InstallColormap 81 -#define X_UninstallColormap 82 -#define X_ListInstalledColormaps 83 -#define X_AllocColor 84 -#define X_AllocNamedColor 85 -#define X_AllocColorCells 86 -#define X_AllocColorPlanes 87 -#define X_FreeColors 88 -#define X_StoreColors 89 -#define X_StoreNamedColor 90 -#define X_QueryColors 91 -#define X_LookupColor 92 -#define X_CreateCursor 93 -#define X_CreateGlyphCursor 94 -#define X_FreeCursor 95 -#define X_RecolorCursor 96 -#define X_QueryBestSize 97 -#define X_QueryExtension 98 -#define X_ListExtensions 99 -#define X_ChangeKeyboardMapping 100 -#define X_GetKeyboardMapping 101 -#define X_ChangeKeyboardControl 102 -#define X_GetKeyboardControl 103 -#define X_Bell 104 -#define X_ChangePointerControl 105 -#define X_GetPointerControl 106 -#define X_SetScreenSaver 107 -#define X_GetScreenSaver 108 -#define X_ChangeHosts 109 -#define X_ListHosts 110 -#define X_SetAccessControl 111 -#define X_SetCloseDownMode 112 -#define X_KillClient 113 -#define X_RotateProperties 114 -#define X_ForceScreenSaver 115 -#define X_SetPointerMapping 116 -#define X_GetPointerMapping 117 -#define X_SetModifierMapping 118 -#define X_GetModifierMapping 119 -#define X_NoOperation 127 +#define X_CreateWindow 1 +#define X_ChangeWindowAttributes 2 +#define X_GetWindowAttributes 3 +#define X_DestroyWindow 4 +#define X_DestroySubwindows 5 +#define X_ChangeSaveSet 6 +#define X_ReparentWindow 7 +#define X_MapWindow 8 +#define X_MapSubwindows 9 +#define X_UnmapWindow 10 +#define X_UnmapSubwindows 11 +#define X_ConfigureWindow 12 +#define X_CirculateWindow 13 +#define X_GetGeometry 14 +#define X_QueryTree 15 +#define X_InternAtom 16 +#define X_GetAtomName 17 +#define X_ChangeProperty 18 +#define X_DeleteProperty 19 +#define X_GetProperty 20 +#define X_ListProperties 21 +#define X_SetSelectionOwner 22 +#define X_GetSelectionOwner 23 +#define X_ConvertSelection 24 +#define X_SendEvent 25 +#define X_GrabPointer 26 +#define X_UngrabPointer 27 +#define X_GrabButton 28 +#define X_UngrabButton 29 +#define X_ChangeActivePointerGrab 30 +#define X_GrabKeyboard 31 +#define X_UngrabKeyboard 32 +#define X_GrabKey 33 +#define X_UngrabKey 34 +#define X_AllowEvents 35 +#define X_GrabServer 36 +#define X_UngrabServer 37 +#define X_QueryPointer 38 +#define X_GetMotionEvents 39 +#define X_TranslateCoords 40 +#define X_WarpPointer 41 +#define X_SetInputFocus 42 +#define X_GetInputFocus 43 +#define X_QueryKeymap 44 +#define X_OpenFont 45 +#define X_CloseFont 46 +#define X_QueryFont 47 +#define X_QueryTextExtents 48 +#define X_ListFonts 49 +#define X_ListFontsWithInfo 50 +#define X_SetFontPath 51 +#define X_GetFontPath 52 +#define X_CreatePixmap 53 +#define X_FreePixmap 54 +#define X_CreateGC 55 +#define X_ChangeGC 56 +#define X_CopyGC 57 +#define X_SetDashes 58 +#define X_SetClipRectangles 59 +#define X_FreeGC 60 +#define X_ClearArea 61 +#define X_CopyArea 62 +#define X_CopyPlane 63 +#define X_PolyPoint 64 +#define X_PolyLine 65 +#define X_PolySegment 66 +#define X_PolyRectangle 67 +#define X_PolyArc 68 +#define X_FillPoly 69 +#define X_PolyFillRectangle 70 +#define X_PolyFillArc 71 +#define X_PutImage 72 +#define X_GetImage 73 +#define X_PolyText8 74 +#define X_PolyText16 75 +#define X_ImageText8 76 +#define X_ImageText16 77 +#define X_CreateColormap 78 +#define X_FreeColormap 79 +#define X_CopyColormapAndFree 80 +#define X_InstallColormap 81 +#define X_UninstallColormap 82 +#define X_ListInstalledColormaps 83 +#define X_AllocColor 84 +#define X_AllocNamedColor 85 +#define X_AllocColorCells 86 +#define X_AllocColorPlanes 87 +#define X_FreeColors 88 +#define X_StoreColors 89 +#define X_StoreNamedColor 90 +#define X_QueryColors 91 +#define X_LookupColor 92 +#define X_CreateCursor 93 +#define X_CreateGlyphCursor 94 +#define X_FreeCursor 95 +#define X_RecolorCursor 96 +#define X_QueryBestSize 97 +#define X_QueryExtension 98 +#define X_ListExtensions 99 +#define X_ChangeKeyboardMapping 100 +#define X_GetKeyboardMapping 101 +#define X_ChangeKeyboardControl 102 +#define X_GetKeyboardControl 103 +#define X_Bell 104 +#define X_ChangePointerControl 105 +#define X_GetPointerControl 106 +#define X_SetScreenSaver 107 +#define X_GetScreenSaver 108 +#define X_ChangeHosts 109 +#define X_ListHosts 110 +#define X_SetAccessControl 111 +#define X_SetCloseDownMode 112 +#define X_KillClient 113 +#define X_RotateProperties 114 +#define X_ForceScreenSaver 115 +#define X_SetPointerMapping 116 +#define X_GetPointerMapping 117 +#define X_SetModifierMapping 118 +#define X_GetModifierMapping 119 +#define X_NoOperation 127 /* restore these definitions back to the typedefs in X.h */ #undef Window diff --git a/examples/ThirdPartyLibs/optionalX11/X11/Xprotostr.h b/examples/ThirdPartyLibs/optionalX11/X11/Xprotostr.h index a9e854d37..a07861e41 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/Xprotostr.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/Xprotostr.h @@ -51,27 +51,31 @@ SOFTWARE. /* Used by PolySegment */ -typedef struct _xSegment { - INT16 x1 B16, y1 B16, x2 B16, y2 B16; +typedef struct _xSegment +{ + INT16 x1 B16, y1 B16, x2 B16, y2 B16; } xSegment; /* POINT */ -typedef struct _xPoint { - INT16 x B16, y B16; +typedef struct _xPoint +{ + INT16 x B16, y B16; } xPoint; -typedef struct _xRectangle { - INT16 x B16, y B16; - CARD16 width B16, height B16; +typedef struct _xRectangle +{ + INT16 x B16, y B16; + CARD16 width B16, height B16; } xRectangle; /* ARC */ -typedef struct _xArc { - INT16 x B16, y B16; - CARD16 width B16, height B16; - INT16 angle1 B16, angle2 B16; +typedef struct _xArc +{ + INT16 x B16, y B16; + CARD16 width B16, height B16; + INT16 angle1 B16, angle2 B16; } xArc; #endif /* XPROTOSTRUCTS_H */ diff --git a/examples/ThirdPartyLibs/optionalX11/X11/Xutil.h b/examples/ThirdPartyLibs/optionalX11/X11/Xutil.h index 62cdf5556..b2c828c43 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/Xutil.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/Xutil.h @@ -65,32 +65,34 @@ SOFTWARE. * Bitmask returned by XParseGeometry(). Each bit tells if the corresponding * value (x, y, width, height) was found in the parsed string. */ -#define NoValue 0x0000 -#define XValue 0x0001 -#define YValue 0x0002 -#define WidthValue 0x0004 -#define HeightValue 0x0008 -#define AllValues 0x000F -#define XNegative 0x0010 -#define YNegative 0x0020 +#define NoValue 0x0000 +#define XValue 0x0001 +#define YValue 0x0002 +#define WidthValue 0x0004 +#define HeightValue 0x0008 +#define AllValues 0x000F +#define XNegative 0x0010 +#define YNegative 0x0020 /* * new version containing base_width, base_height, and win_gravity fields; * used with WM_NORMAL_HINTS. */ -typedef struct { - long flags; /* marks which fields in this structure are defined */ - int x, y; /* obsolete for new window mgrs, but clients */ - int width, height; /* should set so old wm's don't mess up */ +typedef struct +{ + long flags; /* marks which fields in this structure are defined */ + int x, y; /* obsolete for new window mgrs, but clients */ + int width, height; /* should set so old wm's don't mess up */ int min_width, min_height; int max_width, max_height; - int width_inc, height_inc; - struct { - int x; /* numerator */ - int y; /* denominator */ + int width_inc, height_inc; + struct + { + int x; /* numerator */ + int y; /* denominator */ } min_aspect, max_aspect; - int base_width, base_height; /* added by ICCCM version 1 */ - int win_gravity; /* added by ICCCM version 1 */ + int base_width, base_height; /* added by ICCCM version 1 */ + int win_gravity; /* added by ICCCM version 1 */ } XSizeHints; /* @@ -99,115 +101,117 @@ typedef struct { */ /* flags argument in size hints */ -#define USPosition (1L << 0) /* user specified x, y */ -#define USSize (1L << 1) /* user specified width, height */ +#define USPosition (1L << 0) /* user specified x, y */ +#define USSize (1L << 1) /* user specified width, height */ -#define PPosition (1L << 2) /* program specified position */ -#define PSize (1L << 3) /* program specified size */ -#define PMinSize (1L << 4) /* program specified minimum size */ -#define PMaxSize (1L << 5) /* program specified maximum size */ -#define PResizeInc (1L << 6) /* program specified resize increments */ -#define PAspect (1L << 7) /* program specified min and max aspect ratios */ -#define PBaseSize (1L << 8) /* program specified base for incrementing */ -#define PWinGravity (1L << 9) /* program specified window gravity */ +#define PPosition (1L << 2) /* program specified position */ +#define PSize (1L << 3) /* program specified size */ +#define PMinSize (1L << 4) /* program specified minimum size */ +#define PMaxSize (1L << 5) /* program specified maximum size */ +#define PResizeInc (1L << 6) /* program specified resize increments */ +#define PAspect (1L << 7) /* program specified min and max aspect ratios */ +#define PBaseSize (1L << 8) /* program specified base for incrementing */ +#define PWinGravity (1L << 9) /* program specified window gravity */ /* obsolete */ -#define PAllHints (PPosition|PSize|PMinSize|PMaxSize|PResizeInc|PAspect) +#define PAllHints (PPosition | PSize | PMinSize | PMaxSize | PResizeInc | PAspect) - - -typedef struct { - long flags; /* marks which fields in this structure are defined */ - Bool input; /* does this application rely on the window manager to +typedef struct +{ + long flags; /* marks which fields in this structure are defined */ + Bool input; /* does this application rely on the window manager to get keyboard input? */ - int initial_state; /* see below */ - Pixmap icon_pixmap; /* pixmap to be used as icon */ - Window icon_window; /* window to be used as icon */ - int icon_x, icon_y; /* initial position of icon */ - Pixmap icon_mask; /* icon mask bitmap */ - XID window_group; /* id of related window group */ - /* this structure may be extended in the future */ + int initial_state; /* see below */ + Pixmap icon_pixmap; /* pixmap to be used as icon */ + Window icon_window; /* window to be used as icon */ + int icon_x, icon_y; /* initial position of icon */ + Pixmap icon_mask; /* icon mask bitmap */ + XID window_group; /* id of related window group */ + /* this structure may be extended in the future */ } XWMHints; /* definition for flags of XWMHints */ -#define InputHint (1L << 0) -#define StateHint (1L << 1) -#define IconPixmapHint (1L << 2) -#define IconWindowHint (1L << 3) -#define IconPositionHint (1L << 4) -#define IconMaskHint (1L << 5) -#define WindowGroupHint (1L << 6) -#define AllHints (InputHint|StateHint|IconPixmapHint|IconWindowHint| \ -IconPositionHint|IconMaskHint|WindowGroupHint) -#define XUrgencyHint (1L << 8) +#define InputHint (1L << 0) +#define StateHint (1L << 1) +#define IconPixmapHint (1L << 2) +#define IconWindowHint (1L << 3) +#define IconPositionHint (1L << 4) +#define IconMaskHint (1L << 5) +#define WindowGroupHint (1L << 6) +#define AllHints (InputHint | StateHint | IconPixmapHint | IconWindowHint | \ + IconPositionHint | IconMaskHint | WindowGroupHint) +#define XUrgencyHint (1L << 8) /* definitions for initial window state */ -#define WithdrawnState 0 /* for windows that are not mapped */ -#define NormalState 1 /* most applications want to start this way */ -#define IconicState 3 /* application wants to start as an icon */ +#define WithdrawnState 0 /* for windows that are not mapped */ +#define NormalState 1 /* most applications want to start this way */ +#define IconicState 3 /* application wants to start as an icon */ /* * Obsolete states no longer defined by ICCCM */ -#define DontCareState 0 /* don't know or care */ -#define ZoomState 2 /* application wants to start zoomed */ -#define InactiveState 4 /* application believes it is seldom used; */ - /* some wm's may put it on inactive menu */ - +#define DontCareState 0 /* don't know or care */ +#define ZoomState 2 /* application wants to start zoomed */ +#define InactiveState 4 /* application believes it is seldom used; */ + /* some wm's may put it on inactive menu */ /* * new structure for manipulating TEXT properties; used with WM_NAME, * WM_ICON_NAME, WM_CLIENT_MACHINE, and WM_COMMAND. */ -typedef struct { - unsigned char *value; /* same as Property routines */ - Atom encoding; /* prop type */ - int format; /* prop data format: 8, 16, or 32 */ - unsigned long nitems; /* number of data items in value */ +typedef struct +{ + unsigned char* value; /* same as Property routines */ + Atom encoding; /* prop type */ + int format; /* prop data format: 8, 16, or 32 */ + unsigned long nitems; /* number of data items in value */ } XTextProperty; #define XNoMemory -1 #define XLocaleNotSupported -2 #define XConverterNotFound -3 -typedef enum { - XStringStyle, /* STRING */ - XCompoundTextStyle, /* COMPOUND_TEXT */ - XTextStyle, /* text in owner's encoding (current locale)*/ - XStdICCTextStyle, /* STRING, else COMPOUND_TEXT */ - /* The following is an XFree86 extension, introduced in November 2000 */ - XUTF8StringStyle /* UTF8_STRING */ +typedef enum +{ + XStringStyle, /* STRING */ + XCompoundTextStyle, /* COMPOUND_TEXT */ + XTextStyle, /* text in owner's encoding (current locale)*/ + XStdICCTextStyle, /* STRING, else COMPOUND_TEXT */ + /* The following is an XFree86 extension, introduced in November 2000 */ + XUTF8StringStyle /* UTF8_STRING */ } XICCEncodingStyle; -typedef struct { +typedef struct +{ int min_width, min_height; int max_width, max_height; int width_inc, height_inc; } XIconSize; -typedef struct { - char *res_name; - char *res_class; +typedef struct +{ + char* res_name; + char* res_class; } XClassHint; #ifdef XUTIL_DEFINE_FUNCTIONS extern int XDestroyImage( - XImage *ximage); + XImage* ximage); extern unsigned long XGetPixel( - XImage *ximage, - int x, int y); + XImage* ximage, + int x, int y); extern int XPutPixel( - XImage *ximage, - int x, int y, - unsigned long pixel); -extern XImage *XSubImage( - XImage *ximage, - int x, int y, - unsigned int width, unsigned int height); + XImage* ximage, + int x, int y, + unsigned long pixel); +extern XImage* XSubImage( + XImage* ximage, + int x, int y, + unsigned int width, unsigned int height); extern int XAddPixel( - XImage *ximage, - long value); + XImage* ximage, + long value); #else /* * These macros are used to give some sugar to the image routines so that @@ -219,7 +223,7 @@ extern int XAddPixel( ((*((ximage)->f.get_pixel))((ximage), (x), (y))) #define XPutPixel(ximage, x, y, pixel) \ ((*((ximage)->f.put_pixel))((ximage), (x), (y), (pixel))) -#define XSubImage(ximage, x, y, width, height) \ +#define XSubImage(ximage, x, y, width, height) \ ((*((ximage)->f.sub_image))((ximage), (x), (y), (width), (height))) #define XAddPixel(ximage, value) \ ((*((ximage)->f.add_pixel))((ximage), (value))) @@ -228,96 +232,92 @@ extern int XAddPixel( /* * Compose sequence status structure, used in calling XLookupString. */ -typedef struct _XComposeStatus { - XPointer compose_ptr; /* state table pointer */ - int chars_matched; /* match state */ +typedef struct _XComposeStatus +{ + XPointer compose_ptr; /* state table pointer */ + int chars_matched; /* match state */ } XComposeStatus; /* * Keysym macros, used on Keysyms to test for classes of symbols */ #define IsKeypadKey(keysym) \ - (((KeySym)(keysym) >= XK_KP_Space) && ((KeySym)(keysym) <= XK_KP_Equal)) + (((KeySym)(keysym) >= XK_KP_Space) && ((KeySym)(keysym) <= XK_KP_Equal)) #define IsPrivateKeypadKey(keysym) \ - (((KeySym)(keysym) >= 0x11000000) && ((KeySym)(keysym) <= 0x1100FFFF)) + (((KeySym)(keysym) >= 0x11000000) && ((KeySym)(keysym) <= 0x1100FFFF)) #define IsCursorKey(keysym) \ - (((KeySym)(keysym) >= XK_Home) && ((KeySym)(keysym) < XK_Select)) + (((KeySym)(keysym) >= XK_Home) && ((KeySym)(keysym) < XK_Select)) #define IsPFKey(keysym) \ - (((KeySym)(keysym) >= XK_KP_F1) && ((KeySym)(keysym) <= XK_KP_F4)) + (((KeySym)(keysym) >= XK_KP_F1) && ((KeySym)(keysym) <= XK_KP_F4)) #define IsFunctionKey(keysym) \ - (((KeySym)(keysym) >= XK_F1) && ((KeySym)(keysym) <= XK_F35)) + (((KeySym)(keysym) >= XK_F1) && ((KeySym)(keysym) <= XK_F35)) #define IsMiscFunctionKey(keysym) \ - (((KeySym)(keysym) >= XK_Select) && ((KeySym)(keysym) <= XK_Break)) + (((KeySym)(keysym) >= XK_Select) && ((KeySym)(keysym) <= XK_Break)) #ifdef XK_XKB_KEYS #define IsModifierKey(keysym) \ - ((((KeySym)(keysym) >= XK_Shift_L) && ((KeySym)(keysym) <= XK_Hyper_R)) \ - || (((KeySym)(keysym) >= XK_ISO_Lock) && \ - ((KeySym)(keysym) <= XK_ISO_Level5_Lock)) \ - || ((KeySym)(keysym) == XK_Mode_switch) \ - || ((KeySym)(keysym) == XK_Num_Lock)) + ((((KeySym)(keysym) >= XK_Shift_L) && ((KeySym)(keysym) <= XK_Hyper_R)) || (((KeySym)(keysym) >= XK_ISO_Lock) && ((KeySym)(keysym) <= XK_ISO_Level5_Lock)) || ((KeySym)(keysym) == XK_Mode_switch) || ((KeySym)(keysym) == XK_Num_Lock)) #else #define IsModifierKey(keysym) \ - ((((KeySym)(keysym) >= XK_Shift_L) && ((KeySym)(keysym) <= XK_Hyper_R)) \ - || ((KeySym)(keysym) == XK_Mode_switch) \ - || ((KeySym)(keysym) == XK_Num_Lock)) + ((((KeySym)(keysym) >= XK_Shift_L) && ((KeySym)(keysym) <= XK_Hyper_R)) || ((KeySym)(keysym) == XK_Mode_switch) || ((KeySym)(keysym) == XK_Num_Lock)) #endif /* * opaque reference to Region data type */ -typedef struct _XRegion *Region; +typedef struct _XRegion* Region; /* Return values from XRectInRegion() */ #define RectangleOut 0 -#define RectangleIn 1 +#define RectangleIn 1 #define RectanglePart 2 - /* * Information used by the visual utility routines to find desired visual * type from the many visuals a display may support. */ -typedef struct { - Visual *visual; - VisualID visualid; - int screen; - int depth; +typedef struct +{ + Visual* visual; + VisualID visualid; + int screen; + int depth; #if defined(__cplusplus) || defined(c_plusplus) - int c_class; /* C++ */ + int c_class; /* C++ */ #else - int class; + int class; #endif - unsigned long red_mask; - unsigned long green_mask; - unsigned long blue_mask; - int colormap_size; - int bits_per_rgb; + unsigned long red_mask; + unsigned long green_mask; + unsigned long blue_mask; + int colormap_size; + int bits_per_rgb; } XVisualInfo; -#define VisualNoMask 0x0 -#define VisualIDMask 0x1 -#define VisualScreenMask 0x2 -#define VisualDepthMask 0x4 -#define VisualClassMask 0x8 -#define VisualRedMaskMask 0x10 -#define VisualGreenMaskMask 0x20 -#define VisualBlueMaskMask 0x40 -#define VisualColormapSizeMask 0x80 -#define VisualBitsPerRGBMask 0x100 -#define VisualAllMask 0x1FF +#define VisualNoMask 0x0 +#define VisualIDMask 0x1 +#define VisualScreenMask 0x2 +#define VisualDepthMask 0x4 +#define VisualClassMask 0x8 +#define VisualRedMaskMask 0x10 +#define VisualGreenMaskMask 0x20 +#define VisualBlueMaskMask 0x40 +#define VisualColormapSizeMask 0x80 +#define VisualBitsPerRGBMask 0x100 +#define VisualAllMask 0x1FF /* * This defines a window manager property that clients may use to * share standard color maps of type RGB_COLOR_MAP: */ -typedef struct { +typedef struct +{ Colormap colormap; unsigned long red_max; unsigned long red_mult; @@ -326,20 +326,19 @@ typedef struct { unsigned long blue_max; unsigned long blue_mult; unsigned long base_pixel; - VisualID visualid; /* added by ICCCM version 1 */ - XID killid; /* added by ICCCM version 1 */ + VisualID visualid; /* added by ICCCM version 1 */ + XID killid; /* added by ICCCM version 1 */ } XStandardColormap; -#define ReleaseByFreeingColormap ((XID) 1L) /* for killid field above */ - +#define ReleaseByFreeingColormap ((XID)1L) /* for killid field above */ /* * return codes for XReadBitmapFile and XWriteBitmapFile */ -#define BitmapSuccess 0 -#define BitmapOpenFailed 1 -#define BitmapFileInvalid 2 -#define BitmapNoMemory 3 +#define BitmapSuccess 0 +#define BitmapOpenFailed 1 +#define BitmapFileInvalid 2 +#define BitmapNoMemory 3 /**************************************************************** * @@ -347,486 +346,472 @@ typedef struct { * ****************************************************************/ - /* Associative lookup table return codes */ -#define XCSUCCESS 0 /* No error. */ -#define XCNOMEM 1 /* Out of memory */ -#define XCNOENT 2 /* No entry in table */ +#define XCSUCCESS 0 /* No error. */ +#define XCNOMEM 1 /* Out of memory */ +#define XCNOENT 2 /* No entry in table */ typedef int XContext; -#define XUniqueContext() ((XContext) XrmUniqueQuark()) -#define XStringToContext(string) ((XContext) XrmStringToQuark(string)) +#define XUniqueContext() ((XContext)XrmUniqueQuark()) +#define XStringToContext(string) ((XContext)XrmStringToQuark(string)) _XFUNCPROTOBEGIN /* The following declarations are alphabetized. */ -extern XClassHint *XAllocClassHint ( - void -); +extern XClassHint* XAllocClassHint( + void); -extern XIconSize *XAllocIconSize ( - void -); +extern XIconSize* XAllocIconSize( + void); -extern XSizeHints *XAllocSizeHints ( - void -); +extern XSizeHints* XAllocSizeHints( + void); -extern XStandardColormap *XAllocStandardColormap ( - void -); +extern XStandardColormap* XAllocStandardColormap( + void); -extern XWMHints *XAllocWMHints ( - void -); +extern XWMHints* XAllocWMHints( + void); extern int XClipBox( - Region /* r */, - XRectangle* /* rect_return */ + Region /* r */, + XRectangle* /* rect_return */ ); extern Region XCreateRegion( - void -); + void); -extern const char *XDefaultString (void); +extern const char* XDefaultString(void); extern int XDeleteContext( - Display* /* display */, - XID /* rid */, - XContext /* context */ + Display* /* display */, + XID /* rid */, + XContext /* context */ ); extern int XDestroyRegion( - Region /* r */ + Region /* r */ ); extern int XEmptyRegion( - Region /* r */ + Region /* r */ ); extern int XEqualRegion( - Region /* r1 */, - Region /* r2 */ + Region /* r1 */, + Region /* r2 */ ); extern int XFindContext( - Display* /* display */, - XID /* rid */, - XContext /* context */, - XPointer* /* data_return */ + Display* /* display */, + XID /* rid */, + XContext /* context */, + XPointer* /* data_return */ ); extern Status XGetClassHint( - Display* /* display */, - Window /* w */, - XClassHint* /* class_hints_return */ + Display* /* display */, + Window /* w */, + XClassHint* /* class_hints_return */ ); extern Status XGetIconSizes( - Display* /* display */, - Window /* w */, - XIconSize** /* size_list_return */, - int* /* count_return */ + Display* /* display */, + Window /* w */, + XIconSize** /* size_list_return */, + int* /* count_return */ ); extern Status XGetNormalHints( - Display* /* display */, - Window /* w */, - XSizeHints* /* hints_return */ + Display* /* display */, + Window /* w */, + XSizeHints* /* hints_return */ ); extern Status XGetRGBColormaps( - Display* /* display */, - Window /* w */, - XStandardColormap** /* stdcmap_return */, - int* /* count_return */, - Atom /* property */ + Display* /* display */, + Window /* w */, + XStandardColormap** /* stdcmap_return */, + int* /* count_return */, + Atom /* property */ ); extern Status XGetSizeHints( - Display* /* display */, - Window /* w */, - XSizeHints* /* hints_return */, - Atom /* property */ + Display* /* display */, + Window /* w */, + XSizeHints* /* hints_return */, + Atom /* property */ ); extern Status XGetStandardColormap( - Display* /* display */, - Window /* w */, - XStandardColormap* /* colormap_return */, - Atom /* property */ + Display* /* display */, + Window /* w */, + XStandardColormap* /* colormap_return */, + Atom /* property */ ); extern Status XGetTextProperty( - Display* /* display */, - Window /* window */, - XTextProperty* /* text_prop_return */, - Atom /* property */ + Display* /* display */, + Window /* window */, + XTextProperty* /* text_prop_return */, + Atom /* property */ ); -extern XVisualInfo *XGetVisualInfo( - Display* /* display */, - long /* vinfo_mask */, - XVisualInfo* /* vinfo_template */, - int* /* nitems_return */ +extern XVisualInfo* XGetVisualInfo( + Display* /* display */, + long /* vinfo_mask */, + XVisualInfo* /* vinfo_template */, + int* /* nitems_return */ ); extern Status XGetWMClientMachine( - Display* /* display */, - Window /* w */, - XTextProperty* /* text_prop_return */ + Display* /* display */, + Window /* w */, + XTextProperty* /* text_prop_return */ ); -extern XWMHints *XGetWMHints( - Display* /* display */, - Window /* w */ +extern XWMHints* XGetWMHints( + Display* /* display */, + Window /* w */ ); extern Status XGetWMIconName( - Display* /* display */, - Window /* w */, - XTextProperty* /* text_prop_return */ + Display* /* display */, + Window /* w */, + XTextProperty* /* text_prop_return */ ); extern Status XGetWMName( - Display* /* display */, - Window /* w */, - XTextProperty* /* text_prop_return */ + Display* /* display */, + Window /* w */, + XTextProperty* /* text_prop_return */ ); extern Status XGetWMNormalHints( - Display* /* display */, - Window /* w */, - XSizeHints* /* hints_return */, - long* /* supplied_return */ + Display* /* display */, + Window /* w */, + XSizeHints* /* hints_return */, + long* /* supplied_return */ ); extern Status XGetWMSizeHints( - Display* /* display */, - Window /* w */, - XSizeHints* /* hints_return */, - long* /* supplied_return */, - Atom /* property */ + Display* /* display */, + Window /* w */, + XSizeHints* /* hints_return */, + long* /* supplied_return */, + Atom /* property */ ); extern Status XGetZoomHints( - Display* /* display */, - Window /* w */, - XSizeHints* /* zhints_return */ + Display* /* display */, + Window /* w */, + XSizeHints* /* zhints_return */ ); extern int XIntersectRegion( - Region /* sra */, - Region /* srb */, - Region /* dr_return */ + Region /* sra */, + Region /* srb */, + Region /* dr_return */ ); extern void XConvertCase( - KeySym /* sym */, - KeySym* /* lower */, - KeySym* /* upper */ + KeySym /* sym */, + KeySym* /* lower */, + KeySym* /* upper */ ); extern int XLookupString( - XKeyEvent* /* event_struct */, - char* /* buffer_return */, - int /* bytes_buffer */, - KeySym* /* keysym_return */, - XComposeStatus* /* status_in_out */ + XKeyEvent* /* event_struct */, + char* /* buffer_return */, + int /* bytes_buffer */, + KeySym* /* keysym_return */, + XComposeStatus* /* status_in_out */ ); extern Status XMatchVisualInfo( - Display* /* display */, - int /* screen */, - int /* depth */, - int /* class */, - XVisualInfo* /* vinfo_return */ + Display* /* display */, + int /* screen */, + int /* depth */, + int /* class */, + XVisualInfo* /* vinfo_return */ ); extern int XOffsetRegion( - Region /* r */, - int /* dx */, - int /* dy */ + Region /* r */, + int /* dx */, + int /* dy */ ); extern Bool XPointInRegion( - Region /* r */, - int /* x */, - int /* y */ + Region /* r */, + int /* x */, + int /* y */ ); extern Region XPolygonRegion( - XPoint* /* points */, - int /* n */, - int /* fill_rule */ + XPoint* /* points */, + int /* n */, + int /* fill_rule */ ); extern int XRectInRegion( - Region /* r */, - int /* x */, - int /* y */, - unsigned int /* width */, - unsigned int /* height */ + Region /* r */, + int /* x */, + int /* y */, + unsigned int /* width */, + unsigned int /* height */ ); extern int XSaveContext( - Display* /* display */, - XID /* rid */, - XContext /* context */, - _Xconst char* /* data */ + Display* /* display */, + XID /* rid */, + XContext /* context */, + _Xconst char* /* data */ ); extern int XSetClassHint( - Display* /* display */, - Window /* w */, - XClassHint* /* class_hints */ + Display* /* display */, + Window /* w */, + XClassHint* /* class_hints */ ); extern int XSetIconSizes( - Display* /* display */, - Window /* w */, - XIconSize* /* size_list */, - int /* count */ + Display* /* display */, + Window /* w */, + XIconSize* /* size_list */, + int /* count */ ); extern int XSetNormalHints( - Display* /* display */, - Window /* w */, - XSizeHints* /* hints */ + Display* /* display */, + Window /* w */, + XSizeHints* /* hints */ ); extern void XSetRGBColormaps( - Display* /* display */, - Window /* w */, - XStandardColormap* /* stdcmaps */, - int /* count */, - Atom /* property */ + Display* /* display */, + Window /* w */, + XStandardColormap* /* stdcmaps */, + int /* count */, + Atom /* property */ ); extern int XSetSizeHints( - Display* /* display */, - Window /* w */, - XSizeHints* /* hints */, - Atom /* property */ + Display* /* display */, + Window /* w */, + XSizeHints* /* hints */, + Atom /* property */ ); extern int XSetStandardProperties( - Display* /* display */, - Window /* w */, - _Xconst char* /* window_name */, - _Xconst char* /* icon_name */, - Pixmap /* icon_pixmap */, - char** /* argv */, - int /* argc */, - XSizeHints* /* hints */ + Display* /* display */, + Window /* w */, + _Xconst char* /* window_name */, + _Xconst char* /* icon_name */, + Pixmap /* icon_pixmap */, + char** /* argv */, + int /* argc */, + XSizeHints* /* hints */ ); extern void XSetTextProperty( - Display* /* display */, - Window /* w */, - XTextProperty* /* text_prop */, - Atom /* property */ + Display* /* display */, + Window /* w */, + XTextProperty* /* text_prop */, + Atom /* property */ ); extern void XSetWMClientMachine( - Display* /* display */, - Window /* w */, - XTextProperty* /* text_prop */ + Display* /* display */, + Window /* w */, + XTextProperty* /* text_prop */ ); extern int XSetWMHints( - Display* /* display */, - Window /* w */, - XWMHints* /* wm_hints */ + Display* /* display */, + Window /* w */, + XWMHints* /* wm_hints */ ); extern void XSetWMIconName( - Display* /* display */, - Window /* w */, - XTextProperty* /* text_prop */ + Display* /* display */, + Window /* w */, + XTextProperty* /* text_prop */ ); extern void XSetWMName( - Display* /* display */, - Window /* w */, - XTextProperty* /* text_prop */ + Display* /* display */, + Window /* w */, + XTextProperty* /* text_prop */ ); extern void XSetWMNormalHints( - Display* /* display */, - Window /* w */, - XSizeHints* /* hints */ + Display* /* display */, + Window /* w */, + XSizeHints* /* hints */ ); extern void XSetWMProperties( - Display* /* display */, - Window /* w */, - XTextProperty* /* window_name */, - XTextProperty* /* icon_name */, - char** /* argv */, - int /* argc */, - XSizeHints* /* normal_hints */, - XWMHints* /* wm_hints */, - XClassHint* /* class_hints */ + Display* /* display */, + Window /* w */, + XTextProperty* /* window_name */, + XTextProperty* /* icon_name */, + char** /* argv */, + int /* argc */, + XSizeHints* /* normal_hints */, + XWMHints* /* wm_hints */, + XClassHint* /* class_hints */ ); extern void XmbSetWMProperties( - Display* /* display */, - Window /* w */, - _Xconst char* /* window_name */, - _Xconst char* /* icon_name */, - char** /* argv */, - int /* argc */, - XSizeHints* /* normal_hints */, - XWMHints* /* wm_hints */, - XClassHint* /* class_hints */ + Display* /* display */, + Window /* w */, + _Xconst char* /* window_name */, + _Xconst char* /* icon_name */, + char** /* argv */, + int /* argc */, + XSizeHints* /* normal_hints */, + XWMHints* /* wm_hints */, + XClassHint* /* class_hints */ ); extern void Xutf8SetWMProperties( - Display* /* display */, - Window /* w */, - _Xconst char* /* window_name */, - _Xconst char* /* icon_name */, - char** /* argv */, - int /* argc */, - XSizeHints* /* normal_hints */, - XWMHints* /* wm_hints */, - XClassHint* /* class_hints */ + Display* /* display */, + Window /* w */, + _Xconst char* /* window_name */, + _Xconst char* /* icon_name */, + char** /* argv */, + int /* argc */, + XSizeHints* /* normal_hints */, + XWMHints* /* wm_hints */, + XClassHint* /* class_hints */ ); extern void XSetWMSizeHints( - Display* /* display */, - Window /* w */, - XSizeHints* /* hints */, - Atom /* property */ + Display* /* display */, + Window /* w */, + XSizeHints* /* hints */, + Atom /* property */ ); extern int XSetRegion( - Display* /* display */, - GC /* gc */, - Region /* r */ + Display* /* display */, + GC /* gc */, + Region /* r */ ); extern void XSetStandardColormap( - Display* /* display */, - Window /* w */, - XStandardColormap* /* colormap */, - Atom /* property */ + Display* /* display */, + Window /* w */, + XStandardColormap* /* colormap */, + Atom /* property */ ); extern int XSetZoomHints( - Display* /* display */, - Window /* w */, - XSizeHints* /* zhints */ + Display* /* display */, + Window /* w */, + XSizeHints* /* zhints */ ); extern int XShrinkRegion( - Region /* r */, - int /* dx */, - int /* dy */ + Region /* r */, + int /* dx */, + int /* dy */ ); extern Status XStringListToTextProperty( - char** /* list */, - int /* count */, - XTextProperty* /* text_prop_return */ + char** /* list */, + int /* count */, + XTextProperty* /* text_prop_return */ ); extern int XSubtractRegion( - Region /* sra */, - Region /* srb */, - Region /* dr_return */ + Region /* sra */, + Region /* srb */, + Region /* dr_return */ ); extern int XmbTextListToTextProperty( - Display* display, - char** list, - int count, - XICCEncodingStyle style, - XTextProperty* text_prop_return -); + Display* display, + char** list, + int count, + XICCEncodingStyle style, + XTextProperty* text_prop_return); extern int XwcTextListToTextProperty( - Display* display, - wchar_t** list, - int count, - XICCEncodingStyle style, - XTextProperty* text_prop_return -); + Display* display, + wchar_t** list, + int count, + XICCEncodingStyle style, + XTextProperty* text_prop_return); extern int Xutf8TextListToTextProperty( - Display* display, - char** list, - int count, - XICCEncodingStyle style, - XTextProperty* text_prop_return -); + Display* display, + char** list, + int count, + XICCEncodingStyle style, + XTextProperty* text_prop_return); extern void XwcFreeStringList( - wchar_t** list -); + wchar_t** list); extern Status XTextPropertyToStringList( - XTextProperty* /* text_prop */, - char*** /* list_return */, - int* /* count_return */ + XTextProperty* /* text_prop */, + char*** /* list_return */, + int* /* count_return */ ); extern int XmbTextPropertyToTextList( - Display* display, - const XTextProperty* text_prop, - char*** list_return, - int* count_return -); + Display* display, + const XTextProperty* text_prop, + char*** list_return, + int* count_return); extern int XwcTextPropertyToTextList( - Display* display, - const XTextProperty* text_prop, - wchar_t*** list_return, - int* count_return -); + Display* display, + const XTextProperty* text_prop, + wchar_t*** list_return, + int* count_return); extern int Xutf8TextPropertyToTextList( - Display* display, - const XTextProperty* text_prop, - char*** list_return, - int* count_return -); + Display* display, + const XTextProperty* text_prop, + char*** list_return, + int* count_return); extern int XUnionRectWithRegion( - XRectangle* /* rectangle */, - Region /* src_region */, - Region /* dest_region_return */ + XRectangle* /* rectangle */, + Region /* src_region */, + Region /* dest_region_return */ ); extern int XUnionRegion( - Region /* sra */, - Region /* srb */, - Region /* dr_return */ + Region /* sra */, + Region /* srb */, + Region /* dr_return */ ); extern int XWMGeometry( - Display* /* display */, - int /* screen_number */, - _Xconst char* /* user_geometry */, - _Xconst char* /* default_geometry */, - unsigned int /* border_width */, - XSizeHints* /* hints */, - int* /* x_return */, - int* /* y_return */, - int* /* width_return */, - int* /* height_return */, - int* /* gravity_return */ + Display* /* display */, + int /* screen_number */, + _Xconst char* /* user_geometry */, + _Xconst char* /* default_geometry */, + unsigned int /* border_width */, + XSizeHints* /* hints */, + int* /* x_return */, + int* /* y_return */, + int* /* width_return */, + int* /* height_return */, + int* /* gravity_return */ ); extern int XXorRegion( - Region /* sra */, - Region /* srb */, - Region /* dr_return */ + Region /* sra */, + Region /* srb */, + Region /* dr_return */ ); #ifdef __clang__ diff --git a/examples/ThirdPartyLibs/optionalX11/X11/extensions/XKB.h b/examples/ThirdPartyLibs/optionalX11/X11/extensions/XKB.h index ee4f74076..6b1c54eba 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/extensions/XKB.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/extensions/XKB.h @@ -25,135 +25,135 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. ********************************************************/ #ifndef _XKB_H_ -#define _XKB_H_ +#define _XKB_H_ - /* +/* * XKB request codes, used in: * - xkbReqType field of all requests * - requestMinor field of some events */ -#define X_kbUseExtension 0 -#define X_kbSelectEvents 1 -#define X_kbBell 3 -#define X_kbGetState 4 -#define X_kbLatchLockState 5 -#define X_kbGetControls 6 -#define X_kbSetControls 7 -#define X_kbGetMap 8 -#define X_kbSetMap 9 -#define X_kbGetCompatMap 10 -#define X_kbSetCompatMap 11 -#define X_kbGetIndicatorState 12 -#define X_kbGetIndicatorMap 13 -#define X_kbSetIndicatorMap 14 -#define X_kbGetNamedIndicator 15 -#define X_kbSetNamedIndicator 16 -#define X_kbGetNames 17 -#define X_kbSetNames 18 -#define X_kbGetGeometry 19 -#define X_kbSetGeometry 20 -#define X_kbPerClientFlags 21 -#define X_kbListComponents 22 -#define X_kbGetKbdByName 23 -#define X_kbGetDeviceInfo 24 -#define X_kbSetDeviceInfo 25 -#define X_kbSetDebuggingFlags 101 +#define X_kbUseExtension 0 +#define X_kbSelectEvents 1 +#define X_kbBell 3 +#define X_kbGetState 4 +#define X_kbLatchLockState 5 +#define X_kbGetControls 6 +#define X_kbSetControls 7 +#define X_kbGetMap 8 +#define X_kbSetMap 9 +#define X_kbGetCompatMap 10 +#define X_kbSetCompatMap 11 +#define X_kbGetIndicatorState 12 +#define X_kbGetIndicatorMap 13 +#define X_kbSetIndicatorMap 14 +#define X_kbGetNamedIndicator 15 +#define X_kbSetNamedIndicator 16 +#define X_kbGetNames 17 +#define X_kbSetNames 18 +#define X_kbGetGeometry 19 +#define X_kbSetGeometry 20 +#define X_kbPerClientFlags 21 +#define X_kbListComponents 22 +#define X_kbGetKbdByName 23 +#define X_kbGetDeviceInfo 24 +#define X_kbSetDeviceInfo 25 +#define X_kbSetDebuggingFlags 101 - /* +/* * In the X sense, XKB reports only one event. * The type field of all XKB events is XkbEventCode */ -#define XkbEventCode 0 -#define XkbNumberEvents (XkbEventCode+1) +#define XkbEventCode 0 +#define XkbNumberEvents (XkbEventCode + 1) - /* +/* * XKB has a minor event code so it can use one X event code for * multiple purposes. * - reported in the xkbType field of all XKB events. * - XkbSelectEventDetails: Indicates the event for which event details * are being changed */ -#define XkbNewKeyboardNotify 0 -#define XkbMapNotify 1 -#define XkbStateNotify 2 -#define XkbControlsNotify 3 -#define XkbIndicatorStateNotify 4 -#define XkbIndicatorMapNotify 5 -#define XkbNamesNotify 6 -#define XkbCompatMapNotify 7 -#define XkbBellNotify 8 -#define XkbActionMessage 9 -#define XkbAccessXNotify 10 -#define XkbExtensionDeviceNotify 11 +#define XkbNewKeyboardNotify 0 +#define XkbMapNotify 1 +#define XkbStateNotify 2 +#define XkbControlsNotify 3 +#define XkbIndicatorStateNotify 4 +#define XkbIndicatorMapNotify 5 +#define XkbNamesNotify 6 +#define XkbCompatMapNotify 7 +#define XkbBellNotify 8 +#define XkbActionMessage 9 +#define XkbAccessXNotify 10 +#define XkbExtensionDeviceNotify 11 - /* +/* * Event Mask: * - XkbSelectEvents: Specifies event interest. */ -#define XkbNewKeyboardNotifyMask (1L << 0) -#define XkbMapNotifyMask (1L << 1) -#define XkbStateNotifyMask (1L << 2) -#define XkbControlsNotifyMask (1L << 3) -#define XkbIndicatorStateNotifyMask (1L << 4) -#define XkbIndicatorMapNotifyMask (1L << 5) -#define XkbNamesNotifyMask (1L << 6) -#define XkbCompatMapNotifyMask (1L << 7) -#define XkbBellNotifyMask (1L << 8) -#define XkbActionMessageMask (1L << 9) -#define XkbAccessXNotifyMask (1L << 10) -#define XkbExtensionDeviceNotifyMask (1L << 11) -#define XkbAllEventsMask (0xFFF) +#define XkbNewKeyboardNotifyMask (1L << 0) +#define XkbMapNotifyMask (1L << 1) +#define XkbStateNotifyMask (1L << 2) +#define XkbControlsNotifyMask (1L << 3) +#define XkbIndicatorStateNotifyMask (1L << 4) +#define XkbIndicatorMapNotifyMask (1L << 5) +#define XkbNamesNotifyMask (1L << 6) +#define XkbCompatMapNotifyMask (1L << 7) +#define XkbBellNotifyMask (1L << 8) +#define XkbActionMessageMask (1L << 9) +#define XkbAccessXNotifyMask (1L << 10) +#define XkbExtensionDeviceNotifyMask (1L << 11) +#define XkbAllEventsMask (0xFFF) - /* +/* * NewKeyboardNotify event details: */ -#define XkbNKN_KeycodesMask (1L << 0) -#define XkbNKN_GeometryMask (1L << 1) -#define XkbNKN_DeviceIDMask (1L << 2) -#define XkbAllNewKeyboardEventsMask (0x7) +#define XkbNKN_KeycodesMask (1L << 0) +#define XkbNKN_GeometryMask (1L << 1) +#define XkbNKN_DeviceIDMask (1L << 2) +#define XkbAllNewKeyboardEventsMask (0x7) - /* +/* * AccessXNotify event types: * - The 'what' field of AccessXNotify events reports the * reason that the event was generated. */ -#define XkbAXN_SKPress 0 -#define XkbAXN_SKAccept 1 -#define XkbAXN_SKReject 2 -#define XkbAXN_SKRelease 3 -#define XkbAXN_BKAccept 4 -#define XkbAXN_BKReject 5 -#define XkbAXN_AXKWarning 6 +#define XkbAXN_SKPress 0 +#define XkbAXN_SKAccept 1 +#define XkbAXN_SKReject 2 +#define XkbAXN_SKRelease 3 +#define XkbAXN_BKAccept 4 +#define XkbAXN_BKReject 5 +#define XkbAXN_AXKWarning 6 - /* +/* * AccessXNotify details: * - Used as an event detail mask to limit the conditions under which * AccessXNotify events are reported */ -#define XkbAXN_SKPressMask (1L << 0) -#define XkbAXN_SKAcceptMask (1L << 1) -#define XkbAXN_SKRejectMask (1L << 2) -#define XkbAXN_SKReleaseMask (1L << 3) -#define XkbAXN_BKAcceptMask (1L << 4) -#define XkbAXN_BKRejectMask (1L << 5) -#define XkbAXN_AXKWarningMask (1L << 6) -#define XkbAllAccessXEventsMask (0x7f) +#define XkbAXN_SKPressMask (1L << 0) +#define XkbAXN_SKAcceptMask (1L << 1) +#define XkbAXN_SKRejectMask (1L << 2) +#define XkbAXN_SKReleaseMask (1L << 3) +#define XkbAXN_BKAcceptMask (1L << 4) +#define XkbAXN_BKRejectMask (1L << 5) +#define XkbAXN_AXKWarningMask (1L << 6) +#define XkbAllAccessXEventsMask (0x7f) - /* +/* * Miscellaneous event details: * - event detail masks for assorted events that don't reall * have any details. */ -#define XkbAllStateEventsMask XkbAllStateComponentsMask -#define XkbAllMapEventsMask XkbAllMapComponentsMask -#define XkbAllControlEventsMask XkbAllControlsMask -#define XkbAllIndicatorEventsMask XkbAllIndicatorsMask -#define XkbAllNameEventsMask XkbAllNamesMask -#define XkbAllCompatMapEventsMask XkbAllCompatMask -#define XkbAllBellEventsMask (1L << 0) -#define XkbAllActionMessagesMask (1L << 0) +#define XkbAllStateEventsMask XkbAllStateComponentsMask +#define XkbAllMapEventsMask XkbAllMapComponentsMask +#define XkbAllControlEventsMask XkbAllControlsMask +#define XkbAllIndicatorEventsMask XkbAllIndicatorsMask +#define XkbAllNameEventsMask XkbAllNamesMask +#define XkbAllCompatMapEventsMask XkbAllCompatMask +#define XkbAllBellEventsMask (1L << 0) +#define XkbAllActionMessagesMask (1L << 0) - /* +/* * XKB reports one error: BadKeyboard * A further reason for the error is encoded into to most significant * byte of the resourceID for the error: @@ -166,50 +166,50 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. * The low byte of the resourceID for this error contains the device * id, class specifier or feedback id that failed. */ -#define XkbKeyboard 0 -#define XkbNumberErrors 1 +#define XkbKeyboard 0 +#define XkbNumberErrors 1 -#define XkbErr_BadDevice 0xff -#define XkbErr_BadClass 0xfe -#define XkbErr_BadId 0xfd +#define XkbErr_BadDevice 0xff +#define XkbErr_BadClass 0xfe +#define XkbErr_BadId 0xfd - /* +/* * Keyboard Components Mask: * - Specifies the components that follow a GetKeyboardByNameReply */ -#define XkbClientMapMask (1L << 0) -#define XkbServerMapMask (1L << 1) -#define XkbCompatMapMask (1L << 2) -#define XkbIndicatorMapMask (1L << 3) -#define XkbNamesMask (1L << 4) -#define XkbGeometryMask (1L << 5) -#define XkbControlsMask (1L << 6) -#define XkbAllComponentsMask (0x7f) +#define XkbClientMapMask (1L << 0) +#define XkbServerMapMask (1L << 1) +#define XkbCompatMapMask (1L << 2) +#define XkbIndicatorMapMask (1L << 3) +#define XkbNamesMask (1L << 4) +#define XkbGeometryMask (1L << 5) +#define XkbControlsMask (1L << 6) +#define XkbAllComponentsMask (0x7f) - /* +/* * State detail mask: * - The 'changed' field of StateNotify events reports which of * the keyboard state components have changed. * - Used as an event detail mask to limit the conditions under * which StateNotify events are reported. */ -#define XkbModifierStateMask (1L << 0) -#define XkbModifierBaseMask (1L << 1) -#define XkbModifierLatchMask (1L << 2) -#define XkbModifierLockMask (1L << 3) -#define XkbGroupStateMask (1L << 4) -#define XkbGroupBaseMask (1L << 5) -#define XkbGroupLatchMask (1L << 6) -#define XkbGroupLockMask (1L << 7) -#define XkbCompatStateMask (1L << 8) -#define XkbGrabModsMask (1L << 9) -#define XkbCompatGrabModsMask (1L << 10) -#define XkbLookupModsMask (1L << 11) -#define XkbCompatLookupModsMask (1L << 12) -#define XkbPointerButtonMask (1L << 13) -#define XkbAllStateComponentsMask (0x3fff) +#define XkbModifierStateMask (1L << 0) +#define XkbModifierBaseMask (1L << 1) +#define XkbModifierLatchMask (1L << 2) +#define XkbModifierLockMask (1L << 3) +#define XkbGroupStateMask (1L << 4) +#define XkbGroupBaseMask (1L << 5) +#define XkbGroupLatchMask (1L << 6) +#define XkbGroupLockMask (1L << 7) +#define XkbCompatStateMask (1L << 8) +#define XkbGrabModsMask (1L << 9) +#define XkbCompatGrabModsMask (1L << 10) +#define XkbLookupModsMask (1L << 11) +#define XkbCompatLookupModsMask (1L << 12) +#define XkbPointerButtonMask (1L << 13) +#define XkbAllStateComponentsMask (0x3fff) - /* +/* * Controls detail masks: * The controls specified in XkbAllControlsMask: * - The 'changed' field of ControlsNotify events reports which of @@ -237,32 +237,32 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. * - Specifies the boolean controls affected by the SetControls and * LockControls key actions. */ -#define XkbRepeatKeysMask (1L << 0) -#define XkbSlowKeysMask (1L << 1) -#define XkbBounceKeysMask (1L << 2) -#define XkbStickyKeysMask (1L << 3) -#define XkbMouseKeysMask (1L << 4) -#define XkbMouseKeysAccelMask (1L << 5) -#define XkbAccessXKeysMask (1L << 6) -#define XkbAccessXTimeoutMask (1L << 7) -#define XkbAccessXFeedbackMask (1L << 8) -#define XkbAudibleBellMask (1L << 9) -#define XkbOverlay1Mask (1L << 10) -#define XkbOverlay2Mask (1L << 11) -#define XkbIgnoreGroupLockMask (1L << 12) -#define XkbGroupsWrapMask (1L << 27) -#define XkbInternalModsMask (1L << 28) -#define XkbIgnoreLockModsMask (1L << 29) -#define XkbPerKeyRepeatMask (1L << 30) -#define XkbControlsEnabledMask (1L << 31) +#define XkbRepeatKeysMask (1L << 0) +#define XkbSlowKeysMask (1L << 1) +#define XkbBounceKeysMask (1L << 2) +#define XkbStickyKeysMask (1L << 3) +#define XkbMouseKeysMask (1L << 4) +#define XkbMouseKeysAccelMask (1L << 5) +#define XkbAccessXKeysMask (1L << 6) +#define XkbAccessXTimeoutMask (1L << 7) +#define XkbAccessXFeedbackMask (1L << 8) +#define XkbAudibleBellMask (1L << 9) +#define XkbOverlay1Mask (1L << 10) +#define XkbOverlay2Mask (1L << 11) +#define XkbIgnoreGroupLockMask (1L << 12) +#define XkbGroupsWrapMask (1L << 27) +#define XkbInternalModsMask (1L << 28) +#define XkbIgnoreLockModsMask (1L << 29) +#define XkbPerKeyRepeatMask (1L << 30) +#define XkbControlsEnabledMask (1L << 31) -#define XkbAccessXOptionsMask (XkbStickyKeysMask|XkbAccessXFeedbackMask) +#define XkbAccessXOptionsMask (XkbStickyKeysMask | XkbAccessXFeedbackMask) -#define XkbAllBooleanCtrlsMask (0x00001FFF) -#define XkbAllControlsMask (0xF8001FFF) -#define XkbAllControlEventsMask XkbAllControlsMask +#define XkbAllBooleanCtrlsMask (0x00001FFF) +#define XkbAllControlsMask (0xF8001FFF) +#define XkbAllControlEventsMask XkbAllControlsMask - /* +/* * AccessX Options Mask * - The 'accessXOptions' field of an XkbControlsRec specifies the * AccessX options that are currently in effect. @@ -271,23 +271,23 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. * changed if the keyboard times out and the values to which they * should be changed. */ -#define XkbAX_SKPressFBMask (1L << 0) -#define XkbAX_SKAcceptFBMask (1L << 1) -#define XkbAX_FeatureFBMask (1L << 2) -#define XkbAX_SlowWarnFBMask (1L << 3) -#define XkbAX_IndicatorFBMask (1L << 4) -#define XkbAX_StickyKeysFBMask (1L << 5) -#define XkbAX_TwoKeysMask (1L << 6) -#define XkbAX_LatchToLockMask (1L << 7) -#define XkbAX_SKReleaseFBMask (1L << 8) -#define XkbAX_SKRejectFBMask (1L << 9) -#define XkbAX_BKRejectFBMask (1L << 10) -#define XkbAX_DumbBellFBMask (1L << 11) -#define XkbAX_FBOptionsMask (0xF3F) -#define XkbAX_SKOptionsMask (0x0C0) -#define XkbAX_AllOptionsMask (0xFFF) +#define XkbAX_SKPressFBMask (1L << 0) +#define XkbAX_SKAcceptFBMask (1L << 1) +#define XkbAX_FeatureFBMask (1L << 2) +#define XkbAX_SlowWarnFBMask (1L << 3) +#define XkbAX_IndicatorFBMask (1L << 4) +#define XkbAX_StickyKeysFBMask (1L << 5) +#define XkbAX_TwoKeysMask (1L << 6) +#define XkbAX_LatchToLockMask (1L << 7) +#define XkbAX_SKReleaseFBMask (1L << 8) +#define XkbAX_SKRejectFBMask (1L << 9) +#define XkbAX_BKRejectFBMask (1L << 10) +#define XkbAX_DumbBellFBMask (1L << 11) +#define XkbAX_FBOptionsMask (0xF3F) +#define XkbAX_SKOptionsMask (0x0C0) +#define XkbAX_AllOptionsMask (0xFFF) - /* +/* * XkbUseCoreKbd is used to specify the core keyboard without having * to look up its X input extension identifier. * XkbUseCorePtr is used to specify the core pointer without having @@ -314,73 +314,73 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. * XkbSingleXIId(i) True if 'i' specifies exactly one device * identifier, including the default. */ -#define XkbUseCoreKbd 0x0100 -#define XkbUseCorePtr 0x0200 -#define XkbDfltXIClass 0x0300 -#define XkbDfltXIId 0x0400 -#define XkbAllXIClasses 0x0500 -#define XkbAllXIIds 0x0600 -#define XkbXINone 0xff00 +#define XkbUseCoreKbd 0x0100 +#define XkbUseCorePtr 0x0200 +#define XkbDfltXIClass 0x0300 +#define XkbDfltXIId 0x0400 +#define XkbAllXIClasses 0x0500 +#define XkbAllXIIds 0x0600 +#define XkbXINone 0xff00 -#define XkbLegalXILedClass(c) (((c)==KbdFeedbackClass)||\ - ((c)==LedFeedbackClass)||\ - ((c)==XkbDfltXIClass)||\ - ((c)==XkbAllXIClasses)) -#define XkbLegalXIBellClass(c) (((c)==KbdFeedbackClass)||\ - ((c)==BellFeedbackClass)||\ - ((c)==XkbDfltXIClass)||\ - ((c)==XkbAllXIClasses)) -#define XkbExplicitXIDevice(c) (((c)&(~0xff))==0) -#define XkbExplicitXIClass(c) (((c)&(~0xff))==0) -#define XkbExplicitXIId(c) (((c)&(~0xff))==0) -#define XkbSingleXIClass(c) ((((c)&(~0xff))==0)||((c)==XkbDfltXIClass)) -#define XkbSingleXIId(c) ((((c)&(~0xff))==0)||((c)==XkbDfltXIId)) +#define XkbLegalXILedClass(c) (((c) == KbdFeedbackClass) || \ + ((c) == LedFeedbackClass) || \ + ((c) == XkbDfltXIClass) || \ + ((c) == XkbAllXIClasses)) +#define XkbLegalXIBellClass(c) (((c) == KbdFeedbackClass) || \ + ((c) == BellFeedbackClass) || \ + ((c) == XkbDfltXIClass) || \ + ((c) == XkbAllXIClasses)) +#define XkbExplicitXIDevice(c) (((c) & (~0xff)) == 0) +#define XkbExplicitXIClass(c) (((c) & (~0xff)) == 0) +#define XkbExplicitXIId(c) (((c) & (~0xff)) == 0) +#define XkbSingleXIClass(c) ((((c) & (~0xff)) == 0) || ((c) == XkbDfltXIClass)) +#define XkbSingleXIId(c) ((((c) & (~0xff)) == 0) || ((c) == XkbDfltXIId)) -#define XkbNoModifier 0xff -#define XkbNoShiftLevel 0xff -#define XkbNoShape 0xff -#define XkbNoIndicator 0xff +#define XkbNoModifier 0xff +#define XkbNoShiftLevel 0xff +#define XkbNoShape 0xff +#define XkbNoIndicator 0xff -#define XkbNoModifierMask 0 -#define XkbAllModifiersMask 0xff -#define XkbAllVirtualModsMask 0xffff +#define XkbNoModifierMask 0 +#define XkbAllModifiersMask 0xff +#define XkbAllVirtualModsMask 0xffff -#define XkbNumKbdGroups 4 -#define XkbMaxKbdGroup (XkbNumKbdGroups-1) +#define XkbNumKbdGroups 4 +#define XkbMaxKbdGroup (XkbNumKbdGroups - 1) -#define XkbMaxMouseKeysBtn 4 +#define XkbMaxMouseKeysBtn 4 - /* +/* * Group Index and Mask: * - Indices into the kt_index array of a key type. * - Mask specifies types to be changed for XkbChangeTypesOfKey */ -#define XkbGroup1Index 0 -#define XkbGroup2Index 1 -#define XkbGroup3Index 2 -#define XkbGroup4Index 3 -#define XkbAnyGroup 254 -#define XkbAllGroups 255 +#define XkbGroup1Index 0 +#define XkbGroup2Index 1 +#define XkbGroup3Index 2 +#define XkbGroup4Index 3 +#define XkbAnyGroup 254 +#define XkbAllGroups 255 -#define XkbGroup1Mask (1<<0) -#define XkbGroup2Mask (1<<1) -#define XkbGroup3Mask (1<<2) -#define XkbGroup4Mask (1<<3) -#define XkbAnyGroupMask (1<<7) -#define XkbAllGroupsMask (0xf) +#define XkbGroup1Mask (1 << 0) +#define XkbGroup2Mask (1 << 1) +#define XkbGroup3Mask (1 << 2) +#define XkbGroup4Mask (1 << 3) +#define XkbAnyGroupMask (1 << 7) +#define XkbAllGroupsMask (0xf) - /* +/* * BuildCoreState: Given a keyboard group and a modifier state, * construct the value to be reported an event. * GroupForCoreState: Given the state reported in an event, * determine the keyboard group. * IsLegalGroup: Returns TRUE if 'g' is a valid group index. */ -#define XkbBuildCoreState(m,g) ((((g)&0x3)<<13)|((m)&0xff)) -#define XkbGroupForCoreState(s) (((s)>>13)&0x3) -#define XkbIsLegalGroup(g) (((g)>=0)&&((g)> 13) & 0x3) +#define XkbIsLegalGroup(g) (((g) >= 0) && ((g) < XkbNumKbdGroups)) - /* +/* * GroupsWrap values: * - The 'groupsWrap' field of an XkbControlsRec specifies the * treatment of out of range groups. @@ -388,11 +388,11 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. * specify the interpretation of out of range groups for the * corresponding key. */ -#define XkbWrapIntoRange (0x00) -#define XkbClampIntoRange (0x40) -#define XkbRedirectIntoRange (0x80) +#define XkbWrapIntoRange (0x00) +#define XkbClampIntoRange (0x40) +#define XkbRedirectIntoRange (0x80) - /* +/* * Action flags: Reported in the 'flags' field of most key actions. * Interpretation depends on the type of the action; not all actions * accept all flags. @@ -423,103 +423,102 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. * SwitchAbsolute SwitchScreen */ -#define XkbSA_ClearLocks (1L << 0) -#define XkbSA_LatchToLock (1L << 1) +#define XkbSA_ClearLocks (1L << 0) +#define XkbSA_LatchToLock (1L << 1) -#define XkbSA_LockNoLock (1L << 0) -#define XkbSA_LockNoUnlock (1L << 1) +#define XkbSA_LockNoLock (1L << 0) +#define XkbSA_LockNoUnlock (1L << 1) -#define XkbSA_UseModMapMods (1L << 2) +#define XkbSA_UseModMapMods (1L << 2) -#define XkbSA_GroupAbsolute (1L << 2) -#define XkbSA_UseDfltButton 0 +#define XkbSA_GroupAbsolute (1L << 2) +#define XkbSA_UseDfltButton 0 -#define XkbSA_NoAcceleration (1L << 0) -#define XkbSA_MoveAbsoluteX (1L << 1) -#define XkbSA_MoveAbsoluteY (1L << 2) +#define XkbSA_NoAcceleration (1L << 0) +#define XkbSA_MoveAbsoluteX (1L << 1) +#define XkbSA_MoveAbsoluteY (1L << 2) -#define XkbSA_ISODfltIsGroup (1L << 7) -#define XkbSA_ISONoAffectMods (1L << 6) -#define XkbSA_ISONoAffectGroup (1L << 5) -#define XkbSA_ISONoAffectPtr (1L << 4) -#define XkbSA_ISONoAffectCtrls (1L << 3) -#define XkbSA_ISOAffectMask (0x78) +#define XkbSA_ISODfltIsGroup (1L << 7) +#define XkbSA_ISONoAffectMods (1L << 6) +#define XkbSA_ISONoAffectGroup (1L << 5) +#define XkbSA_ISONoAffectPtr (1L << 4) +#define XkbSA_ISONoAffectCtrls (1L << 3) +#define XkbSA_ISOAffectMask (0x78) -#define XkbSA_MessageOnPress (1L << 0) -#define XkbSA_MessageOnRelease (1L << 1) -#define XkbSA_MessageGenKeyEvent (1L << 2) +#define XkbSA_MessageOnPress (1L << 0) +#define XkbSA_MessageOnRelease (1L << 1) +#define XkbSA_MessageGenKeyEvent (1L << 2) -#define XkbSA_AffectDfltBtn 1 -#define XkbSA_DfltBtnAbsolute (1L << 2) +#define XkbSA_AffectDfltBtn 1 +#define XkbSA_DfltBtnAbsolute (1L << 2) -#define XkbSA_SwitchApplication (1L << 0) -#define XkbSA_SwitchAbsolute (1L << 2) +#define XkbSA_SwitchApplication (1L << 0) +#define XkbSA_SwitchAbsolute (1L << 2) - /* +/* * The following values apply to the SA_DeviceValuator * action only. Valuator operations specify the action * to be taken. Values specified in the action are * multiplied by 2^scale before they are applied. */ -#define XkbSA_IgnoreVal (0x00) -#define XkbSA_SetValMin (0x10) -#define XkbSA_SetValCenter (0x20) -#define XkbSA_SetValMax (0x30) -#define XkbSA_SetValRelative (0x40) -#define XkbSA_SetValAbsolute (0x50) -#define XkbSA_ValOpMask (0x70) -#define XkbSA_ValScaleMask (0x07) -#define XkbSA_ValOp(a) ((a)&XkbSA_ValOpMask) -#define XkbSA_ValScale(a) ((a)&XkbSA_ValScaleMask) +#define XkbSA_IgnoreVal (0x00) +#define XkbSA_SetValMin (0x10) +#define XkbSA_SetValCenter (0x20) +#define XkbSA_SetValMax (0x30) +#define XkbSA_SetValRelative (0x40) +#define XkbSA_SetValAbsolute (0x50) +#define XkbSA_ValOpMask (0x70) +#define XkbSA_ValScaleMask (0x07) +#define XkbSA_ValOp(a) ((a)&XkbSA_ValOpMask) +#define XkbSA_ValScale(a) ((a)&XkbSA_ValScaleMask) - /* +/* * Action types: specifies the type of a key action. Reported in the * type field of all key actions. */ -#define XkbSA_NoAction 0x00 -#define XkbSA_SetMods 0x01 -#define XkbSA_LatchMods 0x02 -#define XkbSA_LockMods 0x03 -#define XkbSA_SetGroup 0x04 -#define XkbSA_LatchGroup 0x05 -#define XkbSA_LockGroup 0x06 -#define XkbSA_MovePtr 0x07 -#define XkbSA_PtrBtn 0x08 -#define XkbSA_LockPtrBtn 0x09 -#define XkbSA_SetPtrDflt 0x0a -#define XkbSA_ISOLock 0x0b -#define XkbSA_Terminate 0x0c -#define XkbSA_SwitchScreen 0x0d -#define XkbSA_SetControls 0x0e -#define XkbSA_LockControls 0x0f -#define XkbSA_ActionMessage 0x10 -#define XkbSA_RedirectKey 0x11 -#define XkbSA_DeviceBtn 0x12 -#define XkbSA_LockDeviceBtn 0x13 -#define XkbSA_DeviceValuator 0x14 -#define XkbSA_LastAction XkbSA_DeviceValuator -#define XkbSA_NumActions (XkbSA_LastAction+1) +#define XkbSA_NoAction 0x00 +#define XkbSA_SetMods 0x01 +#define XkbSA_LatchMods 0x02 +#define XkbSA_LockMods 0x03 +#define XkbSA_SetGroup 0x04 +#define XkbSA_LatchGroup 0x05 +#define XkbSA_LockGroup 0x06 +#define XkbSA_MovePtr 0x07 +#define XkbSA_PtrBtn 0x08 +#define XkbSA_LockPtrBtn 0x09 +#define XkbSA_SetPtrDflt 0x0a +#define XkbSA_ISOLock 0x0b +#define XkbSA_Terminate 0x0c +#define XkbSA_SwitchScreen 0x0d +#define XkbSA_SetControls 0x0e +#define XkbSA_LockControls 0x0f +#define XkbSA_ActionMessage 0x10 +#define XkbSA_RedirectKey 0x11 +#define XkbSA_DeviceBtn 0x12 +#define XkbSA_LockDeviceBtn 0x13 +#define XkbSA_DeviceValuator 0x14 +#define XkbSA_LastAction XkbSA_DeviceValuator +#define XkbSA_NumActions (XkbSA_LastAction + 1) -#define XkbSA_XFree86Private 0x86 +#define XkbSA_XFree86Private 0x86 - /* +/* * Specifies the key actions that clear latched groups or modifiers. */ -#define XkbSA_BreakLatch \ - ((1<type>=Xkb_SASetMods)&&((a)->type<=XkbSA_LockMods)) -#define XkbIsGroupAction(a) (((a)->type>=XkbSA_SetGroup)&&((a)->type<=XkbSA_LockGroup)) -#define XkbIsPtrAction(a) (((a)->type>=XkbSA_MovePtr)&&((a)->type<=XkbSA_SetPtrDflt)) +#define XkbIsModAction(a) (((a)->type >= Xkb_SASetMods) && ((a)->type <= XkbSA_LockMods)) +#define XkbIsGroupAction(a) (((a)->type >= XkbSA_SetGroup) && ((a)->type <= XkbSA_LockGroup)) +#define XkbIsPtrAction(a) (((a)->type >= XkbSA_MovePtr) && ((a)->type <= XkbSA_SetPtrDflt)) - - /* +/* * Key Behavior Qualifier: * KB_Permanent indicates that the behavior describes an unalterable * characteristic of the keyboard, not an XKB software-simulation of @@ -527,93 +526,93 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. * Key Behavior Types: * Specifies the behavior of the underlying key. */ -#define XkbKB_Permanent 0x80 -#define XkbKB_OpMask 0x7f +#define XkbKB_Permanent 0x80 +#define XkbKB_OpMask 0x7f -#define XkbKB_Default 0x00 -#define XkbKB_Lock 0x01 -#define XkbKB_RadioGroup 0x02 -#define XkbKB_Overlay1 0x03 -#define XkbKB_Overlay2 0x04 +#define XkbKB_Default 0x00 +#define XkbKB_Lock 0x01 +#define XkbKB_RadioGroup 0x02 +#define XkbKB_Overlay1 0x03 +#define XkbKB_Overlay2 0x04 -#define XkbKB_RGAllowNone 0x80 +#define XkbKB_RGAllowNone 0x80 - /* +/* * Various macros which describe the range of legal keycodes. */ -#define XkbMinLegalKeyCode 8 -#define XkbMaxLegalKeyCode 255 -#define XkbMaxKeyCount (XkbMaxLegalKeyCode-XkbMinLegalKeyCode+1) -#define XkbPerKeyBitArraySize ((XkbMaxLegalKeyCode+1)/8) +#define XkbMinLegalKeyCode 8 +#define XkbMaxLegalKeyCode 255 +#define XkbMaxKeyCount (XkbMaxLegalKeyCode - XkbMinLegalKeyCode + 1) +#define XkbPerKeyBitArraySize ((XkbMaxLegalKeyCode + 1) / 8) /* Seems kinda silly to check that an unsigned char is <= 255... */ -#define XkbIsLegalKeycode(k) ((k)>=XkbMinLegalKeyCode) +#define XkbIsLegalKeycode(k) ((k) >= XkbMinLegalKeyCode) - /* +/* * Assorted constants and limits. */ -#define XkbNumModifiers 8 -#define XkbNumVirtualMods 16 -#define XkbNumIndicators 32 -#define XkbAllIndicatorsMask (0xffffffff) -#define XkbMaxRadioGroups 32 -#define XkbAllRadioGroupsMask (0xffffffff) -#define XkbMaxShiftLevel 63 -#define XkbMaxSymsPerKey (XkbMaxShiftLevel*XkbNumKbdGroups) -#define XkbRGMaxMembers 12 -#define XkbActionMessageLength 6 -#define XkbKeyNameLength 4 -#define XkbMaxRedirectCount 8 +#define XkbNumModifiers 8 +#define XkbNumVirtualMods 16 +#define XkbNumIndicators 32 +#define XkbAllIndicatorsMask (0xffffffff) +#define XkbMaxRadioGroups 32 +#define XkbAllRadioGroupsMask (0xffffffff) +#define XkbMaxShiftLevel 63 +#define XkbMaxSymsPerKey (XkbMaxShiftLevel * XkbNumKbdGroups) +#define XkbRGMaxMembers 12 +#define XkbActionMessageLength 6 +#define XkbKeyNameLength 4 +#define XkbMaxRedirectCount 8 -#define XkbGeomPtsPerMM 10 -#define XkbGeomMaxColors 32 -#define XkbGeomMaxLabelColors 3 -#define XkbGeomMaxPriority 255 +#define XkbGeomPtsPerMM 10 +#define XkbGeomMaxColors 32 +#define XkbGeomMaxLabelColors 3 +#define XkbGeomMaxPriority 255 - /* +/* * Key Type index and mask for the four standard key types. */ -#define XkbOneLevelIndex 0 -#define XkbTwoLevelIndex 1 -#define XkbAlphabeticIndex 2 -#define XkbKeypadIndex 3 -#define XkbLastRequiredType XkbKeypadIndex -#define XkbNumRequiredTypes (XkbLastRequiredType+1) -#define XkbMaxKeyTypes 255 +#define XkbOneLevelIndex 0 +#define XkbTwoLevelIndex 1 +#define XkbAlphabeticIndex 2 +#define XkbKeypadIndex 3 +#define XkbLastRequiredType XkbKeypadIndex +#define XkbNumRequiredTypes (XkbLastRequiredType + 1) +#define XkbMaxKeyTypes 255 -#define XkbOneLevelMask (1<<0) -#define XkbTwoLevelMask (1<<1) -#define XkbAlphabeticMask (1<<2) -#define XkbKeypadMask (1<<3) -#define XkbAllRequiredTypes (0xf) +#define XkbOneLevelMask (1 << 0) +#define XkbTwoLevelMask (1 << 1) +#define XkbAlphabeticMask (1 << 2) +#define XkbKeypadMask (1 << 3) +#define XkbAllRequiredTypes (0xf) -#define XkbShiftLevel(n) ((n)-1) -#define XkbShiftLevelMask(n) (1<<((n)-1)) +#define XkbShiftLevel(n) ((n)-1) +#define XkbShiftLevelMask(n) (1 << ((n)-1)) - /* +/* * Extension name and version information */ -#define XkbName "XKEYBOARD" -#define XkbMajorVersion 1 -#define XkbMinorVersion 0 +#define XkbName "XKEYBOARD" +#define XkbMajorVersion 1 +#define XkbMinorVersion 0 - /* +/* * Explicit map components: * - Used in the 'explicit' field of an XkbServerMap. Specifies * the keyboard components that should _not_ be updated automatically * in response to core protocol keyboard mapping requests. */ -#define XkbExplicitKeyTypesMask (0x0f) -#define XkbExplicitKeyType1Mask (1<<0) -#define XkbExplicitKeyType2Mask (1<<1) -#define XkbExplicitKeyType3Mask (1<<2) -#define XkbExplicitKeyType4Mask (1<<3) -#define XkbExplicitInterpretMask (1<<4) -#define XkbExplicitAutoRepeatMask (1<<5) -#define XkbExplicitBehaviorMask (1<<6) -#define XkbExplicitVModMapMask (1<<7) -#define XkbAllExplicitMask (0xff) +#define XkbExplicitKeyTypesMask (0x0f) +#define XkbExplicitKeyType1Mask (1 << 0) +#define XkbExplicitKeyType2Mask (1 << 1) +#define XkbExplicitKeyType3Mask (1 << 2) +#define XkbExplicitKeyType4Mask (1 << 3) +#define XkbExplicitInterpretMask (1 << 4) +#define XkbExplicitAutoRepeatMask (1 << 5) +#define XkbExplicitBehaviorMask (1 << 6) +#define XkbExplicitVModMapMask (1 << 7) +#define XkbAllExplicitMask (0xff) - /* +/* * Map components masks: * Those in AllMapComponentsMask: * - Specifies the individual fields to be loaded or changed for the @@ -623,128 +622,127 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. * Those in ServerInfoMask: * - Specifies the components to be allocated by XkbAllocServerMap. */ -#define XkbKeyTypesMask (1<<0) -#define XkbKeySymsMask (1<<1) -#define XkbModifierMapMask (1<<2) -#define XkbExplicitComponentsMask (1<<3) -#define XkbKeyActionsMask (1<<4) -#define XkbKeyBehaviorsMask (1<<5) -#define XkbVirtualModsMask (1<<6) -#define XkbVirtualModMapMask (1<<7) +#define XkbKeyTypesMask (1 << 0) +#define XkbKeySymsMask (1 << 1) +#define XkbModifierMapMask (1 << 2) +#define XkbExplicitComponentsMask (1 << 3) +#define XkbKeyActionsMask (1 << 4) +#define XkbKeyBehaviorsMask (1 << 5) +#define XkbVirtualModsMask (1 << 6) +#define XkbVirtualModMapMask (1 << 7) -#define XkbAllClientInfoMask (XkbKeyTypesMask|XkbKeySymsMask|XkbModifierMapMask) -#define XkbAllServerInfoMask (XkbExplicitComponentsMask|XkbKeyActionsMask|XkbKeyBehaviorsMask|XkbVirtualModsMask|XkbVirtualModMapMask) -#define XkbAllMapComponentsMask (XkbAllClientInfoMask|XkbAllServerInfoMask) +#define XkbAllClientInfoMask (XkbKeyTypesMask | XkbKeySymsMask | XkbModifierMapMask) +#define XkbAllServerInfoMask (XkbExplicitComponentsMask | XkbKeyActionsMask | XkbKeyBehaviorsMask | XkbVirtualModsMask | XkbVirtualModMapMask) +#define XkbAllMapComponentsMask (XkbAllClientInfoMask | XkbAllServerInfoMask) - /* +/* * Symbol interpretations flags: * - Used in the flags field of a symbol interpretation */ -#define XkbSI_AutoRepeat (1<<0) -#define XkbSI_LockingKey (1<<1) +#define XkbSI_AutoRepeat (1 << 0) +#define XkbSI_LockingKey (1 << 1) - /* +/* * Symbol interpretations match specification: * - Used in the match field of a symbol interpretation to specify * the conditions under which an interpretation is used. */ -#define XkbSI_LevelOneOnly (0x80) -#define XkbSI_OpMask (0x7f) -#define XkbSI_NoneOf (0) -#define XkbSI_AnyOfOrNone (1) -#define XkbSI_AnyOf (2) -#define XkbSI_AllOf (3) -#define XkbSI_Exactly (4) +#define XkbSI_LevelOneOnly (0x80) +#define XkbSI_OpMask (0x7f) +#define XkbSI_NoneOf (0) +#define XkbSI_AnyOfOrNone (1) +#define XkbSI_AnyOf (2) +#define XkbSI_AllOf (3) +#define XkbSI_Exactly (4) - /* +/* * Indicator map flags: * - Used in the flags field of an indicator map to indicate the * conditions under which and indicator can be changed and the * effects of changing the indicator. */ -#define XkbIM_NoExplicit (1L << 7) -#define XkbIM_NoAutomatic (1L << 6) -#define XkbIM_LEDDrivesKB (1L << 5) +#define XkbIM_NoExplicit (1L << 7) +#define XkbIM_NoAutomatic (1L << 6) +#define XkbIM_LEDDrivesKB (1L << 5) - /* +/* * Indicator map component specifications: * - Used by the 'which_groups' and 'which_mods' fields of an indicator * map to specify which keyboard components should be used to drive * the indicator. */ -#define XkbIM_UseBase (1L << 0) -#define XkbIM_UseLatched (1L << 1) -#define XkbIM_UseLocked (1L << 2) -#define XkbIM_UseEffective (1L << 3) -#define XkbIM_UseCompat (1L << 4) +#define XkbIM_UseBase (1L << 0) +#define XkbIM_UseLatched (1L << 1) +#define XkbIM_UseLocked (1L << 2) +#define XkbIM_UseEffective (1L << 3) +#define XkbIM_UseCompat (1L << 4) -#define XkbIM_UseNone 0 -#define XkbIM_UseAnyGroup (XkbIM_UseBase|XkbIM_UseLatched|XkbIM_UseLocked\ - |XkbIM_UseEffective) -#define XkbIM_UseAnyMods (XkbIM_UseAnyGroup|XkbIM_UseCompat) +#define XkbIM_UseNone 0 +#define XkbIM_UseAnyGroup (XkbIM_UseBase | XkbIM_UseLatched | XkbIM_UseLocked | XkbIM_UseEffective) +#define XkbIM_UseAnyMods (XkbIM_UseAnyGroup | XkbIM_UseCompat) - /* +/* * Compatibility Map Compontents: * - Specifies the components to be allocated in XkbAllocCompatMap. */ -#define XkbSymInterpMask (1<<0) -#define XkbGroupCompatMask (1<<1) -#define XkbAllCompatMask (0x3) +#define XkbSymInterpMask (1 << 0) +#define XkbGroupCompatMask (1 << 1) +#define XkbAllCompatMask (0x3) - /* +/* * Names component mask: * - Specifies the names to be loaded or changed for the GetNames and * SetNames requests. * - Specifies the names that have changed in a NamesNotify event. * - Specifies the names components to be allocated by XkbAllocNames. */ -#define XkbKeycodesNameMask (1<<0) -#define XkbGeometryNameMask (1<<1) -#define XkbSymbolsNameMask (1<<2) -#define XkbPhysSymbolsNameMask (1<<3) -#define XkbTypesNameMask (1<<4) -#define XkbCompatNameMask (1<<5) -#define XkbKeyTypeNamesMask (1<<6) -#define XkbKTLevelNamesMask (1<<7) -#define XkbIndicatorNamesMask (1<<8) -#define XkbKeyNamesMask (1<<9) -#define XkbKeyAliasesMask (1<<10) -#define XkbVirtualModNamesMask (1<<11) -#define XkbGroupNamesMask (1<<12) -#define XkbRGNamesMask (1<<13) -#define XkbComponentNamesMask (0x3f) -#define XkbAllNamesMask (0x3fff) +#define XkbKeycodesNameMask (1 << 0) +#define XkbGeometryNameMask (1 << 1) +#define XkbSymbolsNameMask (1 << 2) +#define XkbPhysSymbolsNameMask (1 << 3) +#define XkbTypesNameMask (1 << 4) +#define XkbCompatNameMask (1 << 5) +#define XkbKeyTypeNamesMask (1 << 6) +#define XkbKTLevelNamesMask (1 << 7) +#define XkbIndicatorNamesMask (1 << 8) +#define XkbKeyNamesMask (1 << 9) +#define XkbKeyAliasesMask (1 << 10) +#define XkbVirtualModNamesMask (1 << 11) +#define XkbGroupNamesMask (1 << 12) +#define XkbRGNamesMask (1 << 13) +#define XkbComponentNamesMask (0x3f) +#define XkbAllNamesMask (0x3fff) - /* +/* * GetByName components: * - Specifies desired or necessary components to GetKbdByName request. * - Reports the components that were found in a GetKbdByNameReply */ -#define XkbGBN_TypesMask (1L << 0) -#define XkbGBN_CompatMapMask (1L << 1) -#define XkbGBN_ClientSymbolsMask (1L << 2) -#define XkbGBN_ServerSymbolsMask (1L << 3) -#define XkbGBN_SymbolsMask (XkbGBN_ClientSymbolsMask|XkbGBN_ServerSymbolsMask) -#define XkbGBN_IndicatorMapMask (1L << 4) -#define XkbGBN_KeyNamesMask (1L << 5) -#define XkbGBN_GeometryMask (1L << 6) -#define XkbGBN_OtherNamesMask (1L << 7) -#define XkbGBN_AllComponentsMask (0xff) +#define XkbGBN_TypesMask (1L << 0) +#define XkbGBN_CompatMapMask (1L << 1) +#define XkbGBN_ClientSymbolsMask (1L << 2) +#define XkbGBN_ServerSymbolsMask (1L << 3) +#define XkbGBN_SymbolsMask (XkbGBN_ClientSymbolsMask | XkbGBN_ServerSymbolsMask) +#define XkbGBN_IndicatorMapMask (1L << 4) +#define XkbGBN_KeyNamesMask (1L << 5) +#define XkbGBN_GeometryMask (1L << 6) +#define XkbGBN_OtherNamesMask (1L << 7) +#define XkbGBN_AllComponentsMask (0xff) - /* +/* * ListComponents flags */ -#define XkbLC_Hidden (1L << 0) -#define XkbLC_Default (1L << 1) -#define XkbLC_Partial (1L << 2) +#define XkbLC_Hidden (1L << 0) +#define XkbLC_Default (1L << 1) +#define XkbLC_Partial (1L << 2) -#define XkbLC_AlphanumericKeys (1L << 8) -#define XkbLC_ModifierKeys (1L << 9) -#define XkbLC_KeypadKeys (1L << 10) -#define XkbLC_FunctionKeys (1L << 11) -#define XkbLC_AlternateGroup (1L << 12) +#define XkbLC_AlphanumericKeys (1L << 8) +#define XkbLC_ModifierKeys (1L << 9) +#define XkbLC_KeypadKeys (1L << 10) +#define XkbLC_FunctionKeys (1L << 11) +#define XkbLC_AlternateGroup (1L << 12) - /* +/* * X Input Extension Interactions * - Specifies the possible interactions between XKB and the X input * extension @@ -755,32 +753,32 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. * XkbXI_UnsupportedFeature is reported in XkbExtensionDeviceNotify * events to indicate an attempt to use an unsupported feature. */ -#define XkbXI_KeyboardsMask (1L << 0) -#define XkbXI_ButtonActionsMask (1L << 1) -#define XkbXI_IndicatorNamesMask (1L << 2) -#define XkbXI_IndicatorMapsMask (1L << 3) -#define XkbXI_IndicatorStateMask (1L << 4) -#define XkbXI_UnsupportedFeatureMask (1L << 15) -#define XkbXI_AllFeaturesMask (0x001f) -#define XkbXI_AllDeviceFeaturesMask (0x001e) +#define XkbXI_KeyboardsMask (1L << 0) +#define XkbXI_ButtonActionsMask (1L << 1) +#define XkbXI_IndicatorNamesMask (1L << 2) +#define XkbXI_IndicatorMapsMask (1L << 3) +#define XkbXI_IndicatorStateMask (1L << 4) +#define XkbXI_UnsupportedFeatureMask (1L << 15) +#define XkbXI_AllFeaturesMask (0x001f) +#define XkbXI_AllDeviceFeaturesMask (0x001e) -#define XkbXI_IndicatorsMask (0x001c) -#define XkbAllExtensionDeviceEventsMask (0x801f) +#define XkbXI_IndicatorsMask (0x001c) +#define XkbAllExtensionDeviceEventsMask (0x801f) - /* +/* * Per-Client Flags: * - Specifies flags to be changed by the PerClientFlags request. */ -#define XkbPCF_DetectableAutoRepeatMask (1L << 0) -#define XkbPCF_GrabsUseXKBStateMask (1L << 1) -#define XkbPCF_AutoResetControlsMask (1L << 2) -#define XkbPCF_LookupStateWhenGrabbed (1L << 3) -#define XkbPCF_SendEventUsesXKBState (1L << 4) -#define XkbPCF_AllFlagsMask (0x1F) +#define XkbPCF_DetectableAutoRepeatMask (1L << 0) +#define XkbPCF_GrabsUseXKBStateMask (1L << 1) +#define XkbPCF_AutoResetControlsMask (1L << 2) +#define XkbPCF_LookupStateWhenGrabbed (1L << 3) +#define XkbPCF_SendEventUsesXKBState (1L << 4) +#define XkbPCF_AllFlagsMask (0x1F) - /* +/* * Debugging flags and controls */ -#define XkbDF_DisableLocks (1<<0) +#define XkbDF_DisableLocks (1 << 0) #endif /* _XKB_H_ */ diff --git a/examples/ThirdPartyLibs/optionalX11/X11/extensions/XKBstr.h b/examples/ThirdPartyLibs/optionalX11/X11/extensions/XKBstr.h index e519e657d..138431afa 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/extensions/XKBstr.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/extensions/XKBstr.h @@ -25,589 +25,628 @@ THE USE OR PERFORMANCE OF THIS SOFTWARE. ********************************************************/ #ifndef _XKBSTR_H_ -#define _XKBSTR_H_ +#define _XKBSTR_H_ #include -#define XkbCharToInt(v) ((v)&0x80?(int)((v)|(~0xff)):(int)((v)&0x7f)) -#define XkbIntTo2Chars(i,h,l) (((h)=((i>>8)&0xff)),((l)=((i)&0xff))) +#define XkbCharToInt(v) ((v)&0x80 ? (int)((v) | (~0xff)) : (int)((v)&0x7f)) +#define XkbIntTo2Chars(i, h, l) (((h) = ((i >> 8) & 0xff)), ((l) = ((i)&0xff))) #if defined(WORD64) && defined(UNSIGNEDBITFIELDS) -#define Xkb2CharsToInt(h,l) ((h)&0x80?(int)(((h)<<8)|(l)|(~0xffff)):\ - (int)(((h)<<8)|(l)&0x7fff)) +#define Xkb2CharsToInt(h, l) ((h)&0x80 ? (int)(((h) << 8) | (l) | (~0xffff)) : (int)(((h) << 8) | (l)&0x7fff)) #else -#define Xkb2CharsToInt(h,l) ((short)(((h)<<8)|(l))) +#define Xkb2CharsToInt(h, l) ((short)(((h) << 8) | (l))) #endif - /* +/* * Common data structures and access macros */ -typedef struct _XkbStateRec { - unsigned char group; - unsigned char locked_group; - unsigned short base_group; - unsigned short latched_group; - unsigned char mods; - unsigned char base_mods; - unsigned char latched_mods; - unsigned char locked_mods; - unsigned char compat_state; - unsigned char grab_mods; - unsigned char compat_grab_mods; - unsigned char lookup_mods; - unsigned char compat_lookup_mods; - unsigned short ptr_buttons; -} XkbStateRec,*XkbStatePtr; -#define XkbModLocks(s) ((s)->locked_mods) -#define XkbStateMods(s) ((s)->base_mods|(s)->latched_mods|XkbModLocks(s)) -#define XkbGroupLock(s) ((s)->locked_group) -#define XkbStateGroup(s) ((s)->base_group+(s)->latched_group+XkbGroupLock(s)) -#define XkbStateFieldFromRec(s) XkbBuildCoreState((s)->lookup_mods,(s)->group) -#define XkbGrabStateFromRec(s) XkbBuildCoreState((s)->grab_mods,(s)->group) +typedef struct _XkbStateRec +{ + unsigned char group; + unsigned char locked_group; + unsigned short base_group; + unsigned short latched_group; + unsigned char mods; + unsigned char base_mods; + unsigned char latched_mods; + unsigned char locked_mods; + unsigned char compat_state; + unsigned char grab_mods; + unsigned char compat_grab_mods; + unsigned char lookup_mods; + unsigned char compat_lookup_mods; + unsigned short ptr_buttons; +} XkbStateRec, *XkbStatePtr; +#define XkbModLocks(s) ((s)->locked_mods) +#define XkbStateMods(s) ((s)->base_mods | (s)->latched_mods | XkbModLocks(s)) +#define XkbGroupLock(s) ((s)->locked_group) +#define XkbStateGroup(s) ((s)->base_group + (s)->latched_group + XkbGroupLock(s)) +#define XkbStateFieldFromRec(s) XkbBuildCoreState((s)->lookup_mods, (s)->group) +#define XkbGrabStateFromRec(s) XkbBuildCoreState((s)->grab_mods, (s)->group) -typedef struct _XkbMods { - unsigned char mask; /* effective mods */ - unsigned char real_mods; - unsigned short vmods; -} XkbModsRec,*XkbModsPtr; +typedef struct _XkbMods +{ + unsigned char mask; /* effective mods */ + unsigned char real_mods; + unsigned short vmods; +} XkbModsRec, *XkbModsPtr; -typedef struct _XkbKTMapEntry { - Bool active; - unsigned char level; - XkbModsRec mods; -} XkbKTMapEntryRec,*XkbKTMapEntryPtr; +typedef struct _XkbKTMapEntry +{ + Bool active; + unsigned char level; + XkbModsRec mods; +} XkbKTMapEntryRec, *XkbKTMapEntryPtr; -typedef struct _XkbKeyType { - XkbModsRec mods; - unsigned char num_levels; - unsigned char map_count; - XkbKTMapEntryPtr map; - XkbModsPtr preserve; - Atom name; - Atom * level_names; +typedef struct _XkbKeyType +{ + XkbModsRec mods; + unsigned char num_levels; + unsigned char map_count; + XkbKTMapEntryPtr map; + XkbModsPtr preserve; + Atom name; + Atom *level_names; } XkbKeyTypeRec, *XkbKeyTypePtr; -#define XkbNumGroups(g) ((g)&0x0f) -#define XkbOutOfRangeGroupInfo(g) ((g)&0xf0) -#define XkbOutOfRangeGroupAction(g) ((g)&0xc0) -#define XkbOutOfRangeGroupNumber(g) (((g)&0x30)>>4) -#define XkbSetGroupInfo(g,w,n) (((w)&0xc0)|(((n)&3)<<4)|((g)&0x0f)) -#define XkbSetNumGroups(g,n) (((g)&0xf0)|((n)&0x0f)) +#define XkbNumGroups(g) ((g)&0x0f) +#define XkbOutOfRangeGroupInfo(g) ((g)&0xf0) +#define XkbOutOfRangeGroupAction(g) ((g)&0xc0) +#define XkbOutOfRangeGroupNumber(g) (((g)&0x30) >> 4) +#define XkbSetGroupInfo(g, w, n) (((w)&0xc0) | (((n)&3) << 4) | ((g)&0x0f)) +#define XkbSetNumGroups(g, n) (((g)&0xf0) | ((n)&0x0f)) - /* +/* * Structures and access macros used primarily by the server */ -typedef struct _XkbBehavior { - unsigned char type; - unsigned char data; +typedef struct _XkbBehavior +{ + unsigned char type; + unsigned char data; } XkbBehavior; -#define XkbAnyActionDataSize 7 -typedef struct _XkbAnyAction { - unsigned char type; - unsigned char data[XkbAnyActionDataSize]; +#define XkbAnyActionDataSize 7 +typedef struct _XkbAnyAction +{ + unsigned char type; + unsigned char data[XkbAnyActionDataSize]; } XkbAnyAction; -typedef struct _XkbModAction { - unsigned char type; - unsigned char flags; - unsigned char mask; - unsigned char real_mods; - unsigned char vmods1; - unsigned char vmods2; +typedef struct _XkbModAction +{ + unsigned char type; + unsigned char flags; + unsigned char mask; + unsigned char real_mods; + unsigned char vmods1; + unsigned char vmods2; } XkbModAction; -#define XkbModActionVMods(a) \ - ((short)(((a)->vmods1<<8)|((a)->vmods2))) -#define XkbSetModActionVMods(a,v) \ - (((a)->vmods1=(((v)>>8)&0xff)),(a)->vmods2=((v)&0xff)) +#define XkbModActionVMods(a) \ + ((short)(((a)->vmods1 << 8) | ((a)->vmods2))) +#define XkbSetModActionVMods(a, v) \ + (((a)->vmods1 = (((v) >> 8) & 0xff)), (a)->vmods2 = ((v)&0xff)) -typedef struct _XkbGroupAction { - unsigned char type; - unsigned char flags; - char group_XXX; +typedef struct _XkbGroupAction +{ + unsigned char type; + unsigned char flags; + char group_XXX; } XkbGroupAction; -#define XkbSAGroup(a) (XkbCharToInt((a)->group_XXX)) -#define XkbSASetGroup(a,g) ((a)->group_XXX=(g)) +#define XkbSAGroup(a) (XkbCharToInt((a)->group_XXX)) +#define XkbSASetGroup(a, g) ((a)->group_XXX = (g)) -typedef struct _XkbISOAction { - unsigned char type; - unsigned char flags; - unsigned char mask; - unsigned char real_mods; - char group_XXX; - unsigned char affect; - unsigned char vmods1; - unsigned char vmods2; +typedef struct _XkbISOAction +{ + unsigned char type; + unsigned char flags; + unsigned char mask; + unsigned char real_mods; + char group_XXX; + unsigned char affect; + unsigned char vmods1; + unsigned char vmods2; } XkbISOAction; -typedef struct _XkbPtrAction { - unsigned char type; - unsigned char flags; - unsigned char high_XXX; - unsigned char low_XXX; - unsigned char high_YYY; - unsigned char low_YYY; +typedef struct _XkbPtrAction +{ + unsigned char type; + unsigned char flags; + unsigned char high_XXX; + unsigned char low_XXX; + unsigned char high_YYY; + unsigned char low_YYY; } XkbPtrAction; -#define XkbPtrActionX(a) (Xkb2CharsToInt((a)->high_XXX,(a)->low_XXX)) -#define XkbPtrActionY(a) (Xkb2CharsToInt((a)->high_YYY,(a)->low_YYY)) -#define XkbSetPtrActionX(a,x) (XkbIntTo2Chars(x,(a)->high_XXX,(a)->low_XXX)) -#define XkbSetPtrActionY(a,y) (XkbIntTo2Chars(y,(a)->high_YYY,(a)->low_YYY)) +#define XkbPtrActionX(a) (Xkb2CharsToInt((a)->high_XXX, (a)->low_XXX)) +#define XkbPtrActionY(a) (Xkb2CharsToInt((a)->high_YYY, (a)->low_YYY)) +#define XkbSetPtrActionX(a, x) (XkbIntTo2Chars(x, (a)->high_XXX, (a)->low_XXX)) +#define XkbSetPtrActionY(a, y) (XkbIntTo2Chars(y, (a)->high_YYY, (a)->low_YYY)) -typedef struct _XkbPtrBtnAction { - unsigned char type; - unsigned char flags; - unsigned char count; - unsigned char button; +typedef struct _XkbPtrBtnAction +{ + unsigned char type; + unsigned char flags; + unsigned char count; + unsigned char button; } XkbPtrBtnAction; -typedef struct _XkbPtrDfltAction { - unsigned char type; - unsigned char flags; - unsigned char affect; - char valueXXX; +typedef struct _XkbPtrDfltAction +{ + unsigned char type; + unsigned char flags; + unsigned char affect; + char valueXXX; } XkbPtrDfltAction; -#define XkbSAPtrDfltValue(a) (XkbCharToInt((a)->valueXXX)) -#define XkbSASetPtrDfltValue(a,c) ((a)->valueXXX= ((c)&0xff)) +#define XkbSAPtrDfltValue(a) (XkbCharToInt((a)->valueXXX)) +#define XkbSASetPtrDfltValue(a, c) ((a)->valueXXX = ((c)&0xff)) -typedef struct _XkbSwitchScreenAction { - unsigned char type; - unsigned char flags; - char screenXXX; +typedef struct _XkbSwitchScreenAction +{ + unsigned char type; + unsigned char flags; + char screenXXX; } XkbSwitchScreenAction; -#define XkbSAScreen(a) (XkbCharToInt((a)->screenXXX)) -#define XkbSASetScreen(a,s) ((a)->screenXXX= ((s)&0xff)) +#define XkbSAScreen(a) (XkbCharToInt((a)->screenXXX)) +#define XkbSASetScreen(a, s) ((a)->screenXXX = ((s)&0xff)) -typedef struct _XkbCtrlsAction { - unsigned char type; - unsigned char flags; - unsigned char ctrls3; - unsigned char ctrls2; - unsigned char ctrls1; - unsigned char ctrls0; +typedef struct _XkbCtrlsAction +{ + unsigned char type; + unsigned char flags; + unsigned char ctrls3; + unsigned char ctrls2; + unsigned char ctrls1; + unsigned char ctrls0; } XkbCtrlsAction; -#define XkbActionSetCtrls(a,c) (((a)->ctrls3=(((c)>>24)&0xff)),\ - ((a)->ctrls2=(((c)>>16)&0xff)),\ - ((a)->ctrls1=(((c)>>8)&0xff)),\ - ((a)->ctrls0=((c)&0xff))) -#define XkbActionCtrls(a) ((((unsigned int)(a)->ctrls3)<<24)|\ - (((unsigned int)(a)->ctrls2)<<16)|\ - (((unsigned int)(a)->ctrls1)<<8)|\ - ((unsigned int)((a)->ctrls0))) +#define XkbActionSetCtrls(a, c) (((a)->ctrls3 = (((c) >> 24) & 0xff)), \ + ((a)->ctrls2 = (((c) >> 16) & 0xff)), \ + ((a)->ctrls1 = (((c) >> 8) & 0xff)), \ + ((a)->ctrls0 = ((c)&0xff))) +#define XkbActionCtrls(a) ((((unsigned int)(a)->ctrls3) << 24) | \ + (((unsigned int)(a)->ctrls2) << 16) | \ + (((unsigned int)(a)->ctrls1) << 8) | \ + ((unsigned int)((a)->ctrls0))) -typedef struct _XkbMessageAction { - unsigned char type; - unsigned char flags; - unsigned char message[6]; +typedef struct _XkbMessageAction +{ + unsigned char type; + unsigned char flags; + unsigned char message[6]; } XkbMessageAction; -typedef struct _XkbRedirectKeyAction { - unsigned char type; - unsigned char new_key; - unsigned char mods_mask; - unsigned char mods; - unsigned char vmods_mask0; - unsigned char vmods_mask1; - unsigned char vmods0; - unsigned char vmods1; +typedef struct _XkbRedirectKeyAction +{ + unsigned char type; + unsigned char new_key; + unsigned char mods_mask; + unsigned char mods; + unsigned char vmods_mask0; + unsigned char vmods_mask1; + unsigned char vmods0; + unsigned char vmods1; } XkbRedirectKeyAction; -#define XkbSARedirectVMods(a) ((((unsigned int)(a)->vmods1)<<8)|\ - ((unsigned int)(a)->vmods0)) -#define XkbSARedirectSetVMods(a,m) (((a)->vmods_mask1=(((m)>>8)&0xff)),\ - ((a)->vmods_mask0=((m)&0xff))) -#define XkbSARedirectVModsMask(a) ((((unsigned int)(a)->vmods_mask1)<<8)|\ - ((unsigned int)(a)->vmods_mask0)) -#define XkbSARedirectSetVModsMask(a,m) (((a)->vmods_mask1=(((m)>>8)&0xff)),\ - ((a)->vmods_mask0=((m)&0xff))) +#define XkbSARedirectVMods(a) ((((unsigned int)(a)->vmods1) << 8) | \ + ((unsigned int)(a)->vmods0)) +#define XkbSARedirectSetVMods(a, m) (((a)->vmods_mask1 = (((m) >> 8) & 0xff)), \ + ((a)->vmods_mask0 = ((m)&0xff))) +#define XkbSARedirectVModsMask(a) ((((unsigned int)(a)->vmods_mask1) << 8) | \ + ((unsigned int)(a)->vmods_mask0)) +#define XkbSARedirectSetVModsMask(a, m) (((a)->vmods_mask1 = (((m) >> 8) & 0xff)), \ + ((a)->vmods_mask0 = ((m)&0xff))) -typedef struct _XkbDeviceBtnAction { - unsigned char type; - unsigned char flags; - unsigned char count; - unsigned char button; - unsigned char device; +typedef struct _XkbDeviceBtnAction +{ + unsigned char type; + unsigned char flags; + unsigned char count; + unsigned char button; + unsigned char device; } XkbDeviceBtnAction; -typedef struct _XkbDeviceValuatorAction { - unsigned char type; - unsigned char device; - unsigned char v1_what; - unsigned char v1_ndx; - unsigned char v1_value; - unsigned char v2_what; - unsigned char v2_ndx; - unsigned char v2_value; +typedef struct _XkbDeviceValuatorAction +{ + unsigned char type; + unsigned char device; + unsigned char v1_what; + unsigned char v1_ndx; + unsigned char v1_value; + unsigned char v2_what; + unsigned char v2_ndx; + unsigned char v2_value; } XkbDeviceValuatorAction; -typedef union _XkbAction { - XkbAnyAction any; - XkbModAction mods; - XkbGroupAction group; - XkbISOAction iso; - XkbPtrAction ptr; - XkbPtrBtnAction btn; - XkbPtrDfltAction dflt; - XkbSwitchScreenAction screen; - XkbCtrlsAction ctrls; - XkbMessageAction msg; - XkbRedirectKeyAction redirect; - XkbDeviceBtnAction devbtn; - XkbDeviceValuatorAction devval; - unsigned char type; +typedef union _XkbAction { + XkbAnyAction any; + XkbModAction mods; + XkbGroupAction group; + XkbISOAction iso; + XkbPtrAction ptr; + XkbPtrBtnAction btn; + XkbPtrDfltAction dflt; + XkbSwitchScreenAction screen; + XkbCtrlsAction ctrls; + XkbMessageAction msg; + XkbRedirectKeyAction redirect; + XkbDeviceBtnAction devbtn; + XkbDeviceValuatorAction devval; + unsigned char type; } XkbAction; -typedef struct _XkbControls { - unsigned char mk_dflt_btn; - unsigned char num_groups; - unsigned char groups_wrap; - XkbModsRec internal; - XkbModsRec ignore_lock; - unsigned int enabled_ctrls; - unsigned short repeat_delay; - unsigned short repeat_interval; - unsigned short slow_keys_delay; - unsigned short debounce_delay; - unsigned short mk_delay; - unsigned short mk_interval; - unsigned short mk_time_to_max; - unsigned short mk_max_speed; - short mk_curve; - unsigned short ax_options; - unsigned short ax_timeout; - unsigned short axt_opts_mask; - unsigned short axt_opts_values; - unsigned int axt_ctrls_mask; - unsigned int axt_ctrls_values; - unsigned char per_key_repeat[XkbPerKeyBitArraySize]; +typedef struct _XkbControls +{ + unsigned char mk_dflt_btn; + unsigned char num_groups; + unsigned char groups_wrap; + XkbModsRec internal; + XkbModsRec ignore_lock; + unsigned int enabled_ctrls; + unsigned short repeat_delay; + unsigned short repeat_interval; + unsigned short slow_keys_delay; + unsigned short debounce_delay; + unsigned short mk_delay; + unsigned short mk_interval; + unsigned short mk_time_to_max; + unsigned short mk_max_speed; + short mk_curve; + unsigned short ax_options; + unsigned short ax_timeout; + unsigned short axt_opts_mask; + unsigned short axt_opts_values; + unsigned int axt_ctrls_mask; + unsigned int axt_ctrls_values; + unsigned char per_key_repeat[XkbPerKeyBitArraySize]; } XkbControlsRec, *XkbControlsPtr; -#define XkbAX_AnyFeedback(c) ((c)->enabled_ctrls&XkbAccessXFeedbackMask) -#define XkbAX_NeedOption(c,w) ((c)->ax_options&(w)) -#define XkbAX_NeedFeedback(c,w) (XkbAX_AnyFeedback(c)&&XkbAX_NeedOption(c,w)) +#define XkbAX_AnyFeedback(c) ((c)->enabled_ctrls & XkbAccessXFeedbackMask) +#define XkbAX_NeedOption(c, w) ((c)->ax_options & (w)) +#define XkbAX_NeedFeedback(c, w) (XkbAX_AnyFeedback(c) && XkbAX_NeedOption(c, w)) -typedef struct _XkbServerMapRec { - unsigned short num_acts; - unsigned short size_acts; - XkbAction *acts; +typedef struct _XkbServerMapRec +{ + unsigned short num_acts; + unsigned short size_acts; + XkbAction *acts; - XkbBehavior *behaviors; - unsigned short *key_acts; + XkbBehavior *behaviors; + unsigned short *key_acts; #if defined(__cplusplus) || defined(c_plusplus) /* explicit is a C++ reserved word */ - unsigned char *c_explicit; + unsigned char *c_explicit; #else - unsigned char *explicit; + unsigned char *explicit; #endif - unsigned char vmods[XkbNumVirtualMods]; - unsigned short *vmodmap; + unsigned char vmods[XkbNumVirtualMods]; + unsigned short *vmodmap; } XkbServerMapRec, *XkbServerMapPtr; -#define XkbSMKeyActionsPtr(m,k) (&(m)->acts[(m)->key_acts[k]]) +#define XkbSMKeyActionsPtr(m, k) (&(m)->acts[(m)->key_acts[k]]) - /* +/* * Structures and access macros used primarily by clients */ -typedef struct _XkbSymMapRec { - unsigned char kt_index[XkbNumKbdGroups]; - unsigned char group_info; - unsigned char width; - unsigned short offset; +typedef struct _XkbSymMapRec +{ + unsigned char kt_index[XkbNumKbdGroups]; + unsigned char group_info; + unsigned char width; + unsigned short offset; } XkbSymMapRec, *XkbSymMapPtr; -typedef struct _XkbClientMapRec { - unsigned char size_types; - unsigned char num_types; - XkbKeyTypePtr types; +typedef struct _XkbClientMapRec +{ + unsigned char size_types; + unsigned char num_types; + XkbKeyTypePtr types; - unsigned short size_syms; - unsigned short num_syms; - KeySym *syms; - XkbSymMapPtr key_sym_map; + unsigned short size_syms; + unsigned short num_syms; + KeySym *syms; + XkbSymMapPtr key_sym_map; - unsigned char *modmap; + unsigned char *modmap; } XkbClientMapRec, *XkbClientMapPtr; -#define XkbCMKeyGroupInfo(m,k) ((m)->key_sym_map[k].group_info) -#define XkbCMKeyNumGroups(m,k) (XkbNumGroups((m)->key_sym_map[k].group_info)) -#define XkbCMKeyGroupWidth(m,k,g) (XkbCMKeyType(m,k,g)->num_levels) -#define XkbCMKeyGroupsWidth(m,k) ((m)->key_sym_map[k].width) -#define XkbCMKeyTypeIndex(m,k,g) ((m)->key_sym_map[k].kt_index[g&0x3]) -#define XkbCMKeyType(m,k,g) (&(m)->types[XkbCMKeyTypeIndex(m,k,g)]) -#define XkbCMKeyNumSyms(m,k) (XkbCMKeyGroupsWidth(m,k)*XkbCMKeyNumGroups(m,k)) -#define XkbCMKeySymsOffset(m,k) ((m)->key_sym_map[k].offset) -#define XkbCMKeySymsPtr(m,k) (&(m)->syms[XkbCMKeySymsOffset(m,k)]) +#define XkbCMKeyGroupInfo(m, k) ((m)->key_sym_map[k].group_info) +#define XkbCMKeyNumGroups(m, k) (XkbNumGroups((m)->key_sym_map[k].group_info)) +#define XkbCMKeyGroupWidth(m, k, g) (XkbCMKeyType(m, k, g)->num_levels) +#define XkbCMKeyGroupsWidth(m, k) ((m)->key_sym_map[k].width) +#define XkbCMKeyTypeIndex(m, k, g) ((m)->key_sym_map[k].kt_index[g & 0x3]) +#define XkbCMKeyType(m, k, g) (&(m)->types[XkbCMKeyTypeIndex(m, k, g)]) +#define XkbCMKeyNumSyms(m, k) (XkbCMKeyGroupsWidth(m, k) * XkbCMKeyNumGroups(m, k)) +#define XkbCMKeySymsOffset(m, k) ((m)->key_sym_map[k].offset) +#define XkbCMKeySymsPtr(m, k) (&(m)->syms[XkbCMKeySymsOffset(m, k)]) - /* +/* * Compatibility structures and access macros */ -typedef struct _XkbSymInterpretRec { - KeySym sym; - unsigned char flags; - unsigned char match; - unsigned char mods; - unsigned char virtual_mod; - XkbAnyAction act; -} XkbSymInterpretRec,*XkbSymInterpretPtr; +typedef struct _XkbSymInterpretRec +{ + KeySym sym; + unsigned char flags; + unsigned char match; + unsigned char mods; + unsigned char virtual_mod; + XkbAnyAction act; +} XkbSymInterpretRec, *XkbSymInterpretPtr; -typedef struct _XkbCompatMapRec { - XkbSymInterpretPtr sym_interpret; - XkbModsRec groups[XkbNumKbdGroups]; - unsigned short num_si; - unsigned short size_si; +typedef struct _XkbCompatMapRec +{ + XkbSymInterpretPtr sym_interpret; + XkbModsRec groups[XkbNumKbdGroups]; + unsigned short num_si; + unsigned short size_si; } XkbCompatMapRec, *XkbCompatMapPtr; -typedef struct _XkbIndicatorMapRec { - unsigned char flags; - unsigned char which_groups; - unsigned char groups; - unsigned char which_mods; - XkbModsRec mods; - unsigned int ctrls; +typedef struct _XkbIndicatorMapRec +{ + unsigned char flags; + unsigned char which_groups; + unsigned char groups; + unsigned char which_mods; + XkbModsRec mods; + unsigned int ctrls; } XkbIndicatorMapRec, *XkbIndicatorMapPtr; -#define XkbIM_IsAuto(i) ((((i)->flags&XkbIM_NoAutomatic)==0)&&\ - (((i)->which_groups&&(i)->groups)||\ - ((i)->which_mods&&(i)->mods.mask)||\ - ((i)->ctrls))) -#define XkbIM_InUse(i) (((i)->flags)||((i)->which_groups)||\ - ((i)->which_mods)||((i)->ctrls)) - +#define XkbIM_IsAuto(i) ((((i)->flags & XkbIM_NoAutomatic) == 0) && \ + (((i)->which_groups && (i)->groups) || \ + ((i)->which_mods && (i)->mods.mask) || \ + ((i)->ctrls))) +#define XkbIM_InUse(i) (((i)->flags) || ((i)->which_groups) || \ + ((i)->which_mods) || ((i)->ctrls)) -typedef struct _XkbIndicatorRec { - unsigned long phys_indicators; - XkbIndicatorMapRec maps[XkbNumIndicators]; -} XkbIndicatorRec,*XkbIndicatorPtr; +typedef struct _XkbIndicatorRec +{ + unsigned long phys_indicators; + XkbIndicatorMapRec maps[XkbNumIndicators]; +} XkbIndicatorRec, *XkbIndicatorPtr; -typedef struct _XkbKeyNameRec { - char name[XkbKeyNameLength]; -} XkbKeyNameRec,*XkbKeyNamePtr; +typedef struct _XkbKeyNameRec +{ + char name[XkbKeyNameLength]; +} XkbKeyNameRec, *XkbKeyNamePtr; -typedef struct _XkbKeyAliasRec { - char real[XkbKeyNameLength]; - char alias[XkbKeyNameLength]; -} XkbKeyAliasRec,*XkbKeyAliasPtr; +typedef struct _XkbKeyAliasRec +{ + char real[XkbKeyNameLength]; + char alias[XkbKeyNameLength]; +} XkbKeyAliasRec, *XkbKeyAliasPtr; - /* +/* * Names for everything */ -typedef struct _XkbNamesRec { - Atom keycodes; - Atom geometry; - Atom symbols; - Atom types; - Atom compat; - Atom vmods[XkbNumVirtualMods]; - Atom indicators[XkbNumIndicators]; - Atom groups[XkbNumKbdGroups]; - XkbKeyNamePtr keys; - XkbKeyAliasPtr key_aliases; - Atom *radio_groups; - Atom phys_symbols; +typedef struct _XkbNamesRec +{ + Atom keycodes; + Atom geometry; + Atom symbols; + Atom types; + Atom compat; + Atom vmods[XkbNumVirtualMods]; + Atom indicators[XkbNumIndicators]; + Atom groups[XkbNumKbdGroups]; + XkbKeyNamePtr keys; + XkbKeyAliasPtr key_aliases; + Atom *radio_groups; + Atom phys_symbols; - unsigned char num_keys; - unsigned char num_key_aliases; - unsigned short num_rg; -} XkbNamesRec,*XkbNamesPtr; + unsigned char num_keys; + unsigned char num_key_aliases; + unsigned short num_rg; +} XkbNamesRec, *XkbNamesPtr; -typedef struct _XkbGeometry *XkbGeometryPtr; - /* +typedef struct _XkbGeometry *XkbGeometryPtr; +/* * Tie it all together into one big keyboard description */ -typedef struct _XkbDesc { - struct _XDisplay * dpy; - unsigned short flags; - unsigned short device_spec; - KeyCode min_key_code; - KeyCode max_key_code; +typedef struct _XkbDesc +{ + struct _XDisplay *dpy; + unsigned short flags; + unsigned short device_spec; + KeyCode min_key_code; + KeyCode max_key_code; - XkbControlsPtr ctrls; - XkbServerMapPtr server; - XkbClientMapPtr map; - XkbIndicatorPtr indicators; - XkbNamesPtr names; - XkbCompatMapPtr compat; - XkbGeometryPtr geom; + XkbControlsPtr ctrls; + XkbServerMapPtr server; + XkbClientMapPtr map; + XkbIndicatorPtr indicators; + XkbNamesPtr names; + XkbCompatMapPtr compat; + XkbGeometryPtr geom; } XkbDescRec, *XkbDescPtr; -#define XkbKeyKeyTypeIndex(d,k,g) (XkbCMKeyTypeIndex((d)->map,k,g)) -#define XkbKeyKeyType(d,k,g) (XkbCMKeyType((d)->map,k,g)) -#define XkbKeyGroupWidth(d,k,g) (XkbCMKeyGroupWidth((d)->map,k,g)) -#define XkbKeyGroupsWidth(d,k) (XkbCMKeyGroupsWidth((d)->map,k)) -#define XkbKeyGroupInfo(d,k) (XkbCMKeyGroupInfo((d)->map,(k))) -#define XkbKeyNumGroups(d,k) (XkbCMKeyNumGroups((d)->map,(k))) -#define XkbKeyNumSyms(d,k) (XkbCMKeyNumSyms((d)->map,(k))) -#define XkbKeySymsPtr(d,k) (XkbCMKeySymsPtr((d)->map,(k))) -#define XkbKeySym(d,k,n) (XkbKeySymsPtr(d,k)[n]) -#define XkbKeySymEntry(d,k,sl,g) \ - (XkbKeySym(d,k,((XkbKeyGroupsWidth(d,k)*(g))+(sl)))) -#define XkbKeyAction(d,k,n) \ - (XkbKeyHasActions(d,k)?&XkbKeyActionsPtr(d,k)[n]:NULL) -#define XkbKeyActionEntry(d,k,sl,g) \ - (XkbKeyHasActions(d,k)?\ - XkbKeyAction(d,k,((XkbKeyGroupsWidth(d,k)*(g))+(sl))):NULL) +#define XkbKeyKeyTypeIndex(d, k, g) (XkbCMKeyTypeIndex((d)->map, k, g)) +#define XkbKeyKeyType(d, k, g) (XkbCMKeyType((d)->map, k, g)) +#define XkbKeyGroupWidth(d, k, g) (XkbCMKeyGroupWidth((d)->map, k, g)) +#define XkbKeyGroupsWidth(d, k) (XkbCMKeyGroupsWidth((d)->map, k)) +#define XkbKeyGroupInfo(d, k) (XkbCMKeyGroupInfo((d)->map, (k))) +#define XkbKeyNumGroups(d, k) (XkbCMKeyNumGroups((d)->map, (k))) +#define XkbKeyNumSyms(d, k) (XkbCMKeyNumSyms((d)->map, (k))) +#define XkbKeySymsPtr(d, k) (XkbCMKeySymsPtr((d)->map, (k))) +#define XkbKeySym(d, k, n) (XkbKeySymsPtr(d, k)[n]) +#define XkbKeySymEntry(d, k, sl, g) \ + (XkbKeySym(d, k, ((XkbKeyGroupsWidth(d, k) * (g)) + (sl)))) +#define XkbKeyAction(d, k, n) \ + (XkbKeyHasActions(d, k) ? &XkbKeyActionsPtr(d, k)[n] : NULL) +#define XkbKeyActionEntry(d, k, sl, g) \ + (XkbKeyHasActions(d, k) ? XkbKeyAction(d, k, ((XkbKeyGroupsWidth(d, k) * (g)) + (sl))) : NULL) -#define XkbKeyHasActions(d,k) ((d)->server->key_acts[k]!=0) -#define XkbKeyNumActions(d,k) (XkbKeyHasActions(d,k)?XkbKeyNumSyms(d,k):1) -#define XkbKeyActionsPtr(d,k) (XkbSMKeyActionsPtr((d)->server,k)) -#define XkbKeycodeInRange(d,k) (((k)>=(d)->min_key_code)&&\ - ((k)<=(d)->max_key_code)) -#define XkbNumKeys(d) ((d)->max_key_code-(d)->min_key_code+1) +#define XkbKeyHasActions(d, k) ((d)->server->key_acts[k] != 0) +#define XkbKeyNumActions(d, k) (XkbKeyHasActions(d, k) ? XkbKeyNumSyms(d, k) : 1) +#define XkbKeyActionsPtr(d, k) (XkbSMKeyActionsPtr((d)->server, k)) +#define XkbKeycodeInRange(d, k) (((k) >= (d)->min_key_code) && \ + ((k) <= (d)->max_key_code)) +#define XkbNumKeys(d) ((d)->max_key_code - (d)->min_key_code + 1) - - /* +/* * The following structures can be used to track changes * to a keyboard device */ -typedef struct _XkbMapChanges { - unsigned short changed; - KeyCode min_key_code; - KeyCode max_key_code; - unsigned char first_type; - unsigned char num_types; - KeyCode first_key_sym; - unsigned char num_key_syms; - KeyCode first_key_act; - unsigned char num_key_acts; - KeyCode first_key_behavior; - unsigned char num_key_behaviors; - KeyCode first_key_explicit; - unsigned char num_key_explicit; - KeyCode first_modmap_key; - unsigned char num_modmap_keys; - KeyCode first_vmodmap_key; - unsigned char num_vmodmap_keys; - unsigned char pad; - unsigned short vmods; -} XkbMapChangesRec,*XkbMapChangesPtr; +typedef struct _XkbMapChanges +{ + unsigned short changed; + KeyCode min_key_code; + KeyCode max_key_code; + unsigned char first_type; + unsigned char num_types; + KeyCode first_key_sym; + unsigned char num_key_syms; + KeyCode first_key_act; + unsigned char num_key_acts; + KeyCode first_key_behavior; + unsigned char num_key_behaviors; + KeyCode first_key_explicit; + unsigned char num_key_explicit; + KeyCode first_modmap_key; + unsigned char num_modmap_keys; + KeyCode first_vmodmap_key; + unsigned char num_vmodmap_keys; + unsigned char pad; + unsigned short vmods; +} XkbMapChangesRec, *XkbMapChangesPtr; -typedef struct _XkbControlsChanges { - unsigned int changed_ctrls; - unsigned int enabled_ctrls_changes; - Bool num_groups_changed; -} XkbControlsChangesRec,*XkbControlsChangesPtr; +typedef struct _XkbControlsChanges +{ + unsigned int changed_ctrls; + unsigned int enabled_ctrls_changes; + Bool num_groups_changed; +} XkbControlsChangesRec, *XkbControlsChangesPtr; -typedef struct _XkbIndicatorChanges { - unsigned int state_changes; - unsigned int map_changes; -} XkbIndicatorChangesRec,*XkbIndicatorChangesPtr; +typedef struct _XkbIndicatorChanges +{ + unsigned int state_changes; + unsigned int map_changes; +} XkbIndicatorChangesRec, *XkbIndicatorChangesPtr; -typedef struct _XkbNameChanges { - unsigned int changed; - unsigned char first_type; - unsigned char num_types; - unsigned char first_lvl; - unsigned char num_lvls; - unsigned char num_aliases; - unsigned char num_rg; - unsigned char first_key; - unsigned char num_keys; - unsigned short changed_vmods; - unsigned long changed_indicators; - unsigned char changed_groups; -} XkbNameChangesRec,*XkbNameChangesPtr; +typedef struct _XkbNameChanges +{ + unsigned int changed; + unsigned char first_type; + unsigned char num_types; + unsigned char first_lvl; + unsigned char num_lvls; + unsigned char num_aliases; + unsigned char num_rg; + unsigned char first_key; + unsigned char num_keys; + unsigned short changed_vmods; + unsigned long changed_indicators; + unsigned char changed_groups; +} XkbNameChangesRec, *XkbNameChangesPtr; -typedef struct _XkbCompatChanges { - unsigned char changed_groups; - unsigned short first_si; - unsigned short num_si; -} XkbCompatChangesRec,*XkbCompatChangesPtr; +typedef struct _XkbCompatChanges +{ + unsigned char changed_groups; + unsigned short first_si; + unsigned short num_si; +} XkbCompatChangesRec, *XkbCompatChangesPtr; -typedef struct _XkbChanges { - unsigned short device_spec; - unsigned short state_changes; - XkbMapChangesRec map; - XkbControlsChangesRec ctrls; - XkbIndicatorChangesRec indicators; - XkbNameChangesRec names; - XkbCompatChangesRec compat; +typedef struct _XkbChanges +{ + unsigned short device_spec; + unsigned short state_changes; + XkbMapChangesRec map; + XkbControlsChangesRec ctrls; + XkbIndicatorChangesRec indicators; + XkbNameChangesRec names; + XkbCompatChangesRec compat; } XkbChangesRec, *XkbChangesPtr; - /* +/* * These data structures are used to construct a keymap from * a set of components or to list components in the server * database. */ -typedef struct _XkbComponentNames { - char * keymap; - char * keycodes; - char * types; - char * compat; - char * symbols; - char * geometry; +typedef struct _XkbComponentNames +{ + char *keymap; + char *keycodes; + char *types; + char *compat; + char *symbols; + char *geometry; } XkbComponentNamesRec, *XkbComponentNamesPtr; -typedef struct _XkbComponentName { - unsigned short flags; - char * name; -} XkbComponentNameRec,*XkbComponentNamePtr; +typedef struct _XkbComponentName +{ + unsigned short flags; + char *name; +} XkbComponentNameRec, *XkbComponentNamePtr; -typedef struct _XkbComponentList { - int num_keymaps; - int num_keycodes; - int num_types; - int num_compat; - int num_symbols; - int num_geometry; - XkbComponentNamePtr keymaps; - XkbComponentNamePtr keycodes; - XkbComponentNamePtr types; - XkbComponentNamePtr compat; - XkbComponentNamePtr symbols; - XkbComponentNamePtr geometry; +typedef struct _XkbComponentList +{ + int num_keymaps; + int num_keycodes; + int num_types; + int num_compat; + int num_symbols; + int num_geometry; + XkbComponentNamePtr keymaps; + XkbComponentNamePtr keycodes; + XkbComponentNamePtr types; + XkbComponentNamePtr compat; + XkbComponentNamePtr symbols; + XkbComponentNamePtr geometry; } XkbComponentListRec, *XkbComponentListPtr; - /* +/* * The following data structures describe and track changes to a * non-keyboard extension device */ -typedef struct _XkbDeviceLedInfo { - unsigned short led_class; - unsigned short led_id; - unsigned int phys_indicators; - unsigned int maps_present; - unsigned int names_present; - unsigned int state; - Atom names[XkbNumIndicators]; - XkbIndicatorMapRec maps[XkbNumIndicators]; -} XkbDeviceLedInfoRec,*XkbDeviceLedInfoPtr; +typedef struct _XkbDeviceLedInfo +{ + unsigned short led_class; + unsigned short led_id; + unsigned int phys_indicators; + unsigned int maps_present; + unsigned int names_present; + unsigned int state; + Atom names[XkbNumIndicators]; + XkbIndicatorMapRec maps[XkbNumIndicators]; +} XkbDeviceLedInfoRec, *XkbDeviceLedInfoPtr; -typedef struct _XkbDeviceInfo { - char * name; - Atom type; - unsigned short device_spec; - Bool has_own_state; - unsigned short supported; - unsigned short unsupported; +typedef struct _XkbDeviceInfo +{ + char *name; + Atom type; + unsigned short device_spec; + Bool has_own_state; + unsigned short supported; + unsigned short unsupported; - unsigned short num_btns; - XkbAction * btn_acts; + unsigned short num_btns; + XkbAction *btn_acts; - unsigned short sz_leds; - unsigned short num_leds; - unsigned short dflt_kbd_fb; - unsigned short dflt_led_fb; - XkbDeviceLedInfoPtr leds; -} XkbDeviceInfoRec,*XkbDeviceInfoPtr; + unsigned short sz_leds; + unsigned short num_leds; + unsigned short dflt_kbd_fb; + unsigned short dflt_led_fb; + XkbDeviceLedInfoPtr leds; +} XkbDeviceInfoRec, *XkbDeviceInfoPtr; -#define XkbXI_DevHasBtnActs(d) (((d)->num_btns>0)&&((d)->btn_acts!=NULL)) -#define XkbXI_LegalDevBtn(d,b) (XkbXI_DevHasBtnActs(d)&&((b)<(d)->num_btns)) -#define XkbXI_DevHasLeds(d) (((d)->num_leds>0)&&((d)->leds!=NULL)) +#define XkbXI_DevHasBtnActs(d) (((d)->num_btns > 0) && ((d)->btn_acts != NULL)) +#define XkbXI_LegalDevBtn(d, b) (XkbXI_DevHasBtnActs(d) && ((b) < (d)->num_btns)) +#define XkbXI_DevHasLeds(d) (((d)->num_leds > 0) && ((d)->leds != NULL)) -typedef struct _XkbDeviceLedChanges { - unsigned short led_class; - unsigned short led_id; - unsigned int defined; /* names or maps changed */ +typedef struct _XkbDeviceLedChanges +{ + unsigned short led_class; + unsigned short led_id; + unsigned int defined; /* names or maps changed */ struct _XkbDeviceLedChanges *next; -} XkbDeviceLedChangesRec,*XkbDeviceLedChangesPtr; +} XkbDeviceLedChangesRec, *XkbDeviceLedChangesPtr; -typedef struct _XkbDeviceChanges { - unsigned int changed; - unsigned short first_btn; - unsigned short num_btns; - XkbDeviceLedChangesRec leds; -} XkbDeviceChangesRec,*XkbDeviceChangesPtr; +typedef struct _XkbDeviceChanges +{ + unsigned int changed; + unsigned short first_btn; + unsigned short num_btns; + XkbDeviceLedChangesRec leds; +} XkbDeviceChangesRec, *XkbDeviceChangesPtr; #endif /* _XKBSTR_H_ */ diff --git a/examples/ThirdPartyLibs/optionalX11/X11/extensions/XShm.h b/examples/ThirdPartyLibs/optionalX11/X11/extensions/XShm.h index 23f065115..54e95cadc 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/extensions/XShm.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/extensions/XShm.h @@ -35,98 +35,100 @@ in this Software without prior written authorization from The Open Group. #ifndef _XSHM_SERVER_ typedef unsigned long ShmSeg; -typedef struct { - int type; /* of event */ - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came frome a SendEvent request */ - Display *display; /* Display the event was read from */ - Drawable drawable; /* drawable of request */ - int major_code; /* ShmReqCode */ - int minor_code; /* X_ShmPutImage */ - ShmSeg shmseg; /* the ShmSeg used in the request */ - unsigned long offset; /* the offset into ShmSeg used in the request */ +typedef struct +{ + int type; /* of event */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came frome a SendEvent request */ + Display* display; /* Display the event was read from */ + Drawable drawable; /* drawable of request */ + int major_code; /* ShmReqCode */ + int minor_code; /* X_ShmPutImage */ + ShmSeg shmseg; /* the ShmSeg used in the request */ + unsigned long offset; /* the offset into ShmSeg used in the request */ } XShmCompletionEvent; -typedef struct { - ShmSeg shmseg; /* resource id */ - int shmid; /* kernel id */ - char *shmaddr; /* address in client */ - Bool readOnly; /* how the server should attach it */ +typedef struct +{ + ShmSeg shmseg; /* resource id */ + int shmid; /* kernel id */ + char* shmaddr; /* address in client */ + Bool readOnly; /* how the server should attach it */ } XShmSegmentInfo; _XFUNCPROTOBEGIN Bool XShmQueryExtension( - Display* /* dpy */ + Display* /* dpy */ ); int XShmGetEventBase( - Display* /* dpy */ + Display* /* dpy */ ); Bool XShmQueryVersion( - Display* /* dpy */, - int* /* majorVersion */, - int* /* minorVersion */, - Bool* /* sharedPixmaps */ + Display* /* dpy */, + int* /* majorVersion */, + int* /* minorVersion */, + Bool* /* sharedPixmaps */ ); int XShmPixmapFormat( - Display* /* dpy */ + Display* /* dpy */ ); Bool XShmAttach( - Display* /* dpy */, - XShmSegmentInfo* /* shminfo */ + Display* /* dpy */, + XShmSegmentInfo* /* shminfo */ ); Bool XShmDetach( - Display* /* dpy */, - XShmSegmentInfo* /* shminfo */ + Display* /* dpy */, + XShmSegmentInfo* /* shminfo */ ); Bool XShmPutImage( - Display* /* dpy */, - Drawable /* d */, - GC /* gc */, - XImage* /* image */, - int /* src_x */, - int /* src_y */, - int /* dst_x */, - int /* dst_y */, - unsigned int /* src_width */, - unsigned int /* src_height */, - Bool /* send_event */ + Display* /* dpy */, + Drawable /* d */, + GC /* gc */, + XImage* /* image */, + int /* src_x */, + int /* src_y */, + int /* dst_x */, + int /* dst_y */, + unsigned int /* src_width */, + unsigned int /* src_height */, + Bool /* send_event */ ); Bool XShmGetImage( - Display* /* dpy */, - Drawable /* d */, - XImage* /* image */, - int /* x */, - int /* y */, - unsigned long /* plane_mask */ + Display* /* dpy */, + Drawable /* d */, + XImage* /* image */, + int /* x */, + int /* y */, + unsigned long /* plane_mask */ ); -XImage *XShmCreateImage( - Display* /* dpy */, - Visual* /* visual */, - unsigned int /* depth */, - int /* format */, - char* /* data */, - XShmSegmentInfo* /* shminfo */, - unsigned int /* width */, - unsigned int /* height */ +XImage* XShmCreateImage( + Display* /* dpy */, + Visual* /* visual */, + unsigned int /* depth */, + int /* format */, + char* /* data */, + XShmSegmentInfo* /* shminfo */, + unsigned int /* width */, + unsigned int /* height */ ); Pixmap XShmCreatePixmap( - Display* /* dpy */, - Drawable /* d */, - char* /* data */, - XShmSegmentInfo* /* shminfo */, - unsigned int /* width */, - unsigned int /* height */, - unsigned int /* depth */ + Display* /* dpy */, + Drawable /* d */, + char* /* data */, + XShmSegmentInfo* /* shminfo */, + unsigned int /* width */, + unsigned int /* height */, + unsigned int /* depth */ ); _XFUNCPROTOEND diff --git a/examples/ThirdPartyLibs/optionalX11/X11/extensions/Xext.h b/examples/ThirdPartyLibs/optionalX11/X11/extensions/Xext.h index 858592b78..0cbda02e5 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/extensions/Xext.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/extensions/Xext.h @@ -30,19 +30,19 @@ in this Software without prior written authorization from The Open Group. _XFUNCPROTOBEGIN -typedef int (*XextErrorHandler) ( - Display * /* dpy */, - _Xconst char* /* ext_name */, - _Xconst char* /* reason */ +typedef int (*XextErrorHandler)( + Display* /* dpy */, + _Xconst char* /* ext_name */, + _Xconst char* /* reason */ ); extern XextErrorHandler XSetExtensionErrorHandler( - XextErrorHandler /* handler */ + XextErrorHandler /* handler */ ); extern int XMissingExtension( - Display* /* dpy */, - _Xconst char* /* ext_name */ + Display* /* dpy */, + _Xconst char* /* ext_name */ ); _XFUNCPROTOEND diff --git a/examples/ThirdPartyLibs/optionalX11/X11/extensions/extutil.h b/examples/ThirdPartyLibs/optionalX11/X11/extensions/extutil.h index 29404d5ae..7abe5ac1c 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/extensions/extutil.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/extensions/extutil.h @@ -41,108 +41,117 @@ in this Software without prior written authorization from The Open Group. * public. We also have to per-display info in a separate block since it isn't * stored directly in the Display structure. */ -typedef struct _XExtDisplayInfo { - struct _XExtDisplayInfo *next; /* keep a linked list */ - Display *display; /* which display this is */ - XExtCodes *codes; /* the extension protocol codes */ - XPointer data; /* extra data for extension to use */ +typedef struct _XExtDisplayInfo +{ + struct _XExtDisplayInfo* next; /* keep a linked list */ + Display* display; /* which display this is */ + XExtCodes* codes; /* the extension protocol codes */ + XPointer data; /* extra data for extension to use */ } XExtDisplayInfo; -typedef struct _XExtensionInfo { - XExtDisplayInfo *head; /* start of list */ - XExtDisplayInfo *cur; /* most recently used */ - int ndisplays; /* number of displays */ +typedef struct _XExtensionInfo +{ + XExtDisplayInfo* head; /* start of list */ + XExtDisplayInfo* cur; /* most recently used */ + int ndisplays; /* number of displays */ } XExtensionInfo; -typedef struct _XExtensionHooks { - int (*create_gc)( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ -); - int (*copy_gc)( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ -); - int (*flush_gc)( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ -); - int (*free_gc)( - Display* /* display */, - GC /* gc */, - XExtCodes* /* codes */ -); - int (*create_font)( - Display* /* display */, - XFontStruct* /* fs */, - XExtCodes* /* codes */ -); - int (*free_font)( - Display* /* display */, - XFontStruct* /* fs */, - XExtCodes* /* codes */ -); - int (*close_display)( - Display* /* display */, - XExtCodes* /* codes */ -); - Bool (*wire_to_event)( - Display* /* display */, - XEvent* /* re */, - xEvent* /* event */ -); - Status (*event_to_wire)( - Display* /* display */, - XEvent* /* re */, - xEvent* /* event */ -); - int (*error)( - Display* /* display */, - xError* /* err */, - XExtCodes* /* codes */, - int* /* ret_code */ -); - char *(*error_string)( - Display* /* display */, - int /* code */, - XExtCodes* /* codes */, - char* /* buffer */, - int /* nbytes */ -); +typedef struct _XExtensionHooks +{ + int (*create_gc)( + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ + ); + int (*copy_gc)( + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ + ); + int (*flush_gc)( + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ + ); + int (*free_gc)( + Display* /* display */, + GC /* gc */, + XExtCodes* /* codes */ + ); + int (*create_font)( + Display* /* display */, + XFontStruct* /* fs */, + XExtCodes* /* codes */ + ); + int (*free_font)( + Display* /* display */, + XFontStruct* /* fs */, + XExtCodes* /* codes */ + ); + int (*close_display)( + Display* /* display */, + XExtCodes* /* codes */ + ); + Bool (*wire_to_event)( + Display* /* display */, + XEvent* /* re */, + xEvent* /* event */ + ); + Status (*event_to_wire)( + Display* /* display */, + XEvent* /* re */, + xEvent* /* event */ + ); + int (*error)( + Display* /* display */, + xError* /* err */, + XExtCodes* /* codes */, + int* /* ret_code */ + ); + char* (*error_string)( + Display* /* display */, + int /* code */, + XExtCodes* /* codes */, + char* /* buffer */, + int /* nbytes */ + ); } XExtensionHooks; -extern XExtensionInfo *XextCreateExtension( - void -); +extern XExtensionInfo* XextCreateExtension( + void); extern void XextDestroyExtension( - XExtensionInfo* /* info */ + XExtensionInfo* /* info */ ); -extern XExtDisplayInfo *XextAddDisplay( - XExtensionInfo* /* extinfo */, - Display* /* dpy */, - _Xconst char* /* ext_name */, - XExtensionHooks* /* hooks */, - int /* nevents */, - XPointer /* data */ +extern XExtDisplayInfo* XextAddDisplay( + XExtensionInfo* /* extinfo */, + Display* /* dpy */, + _Xconst char* /* ext_name */, + XExtensionHooks* /* hooks */, + int /* nevents */, + XPointer /* data */ ); extern int XextRemoveDisplay( - XExtensionInfo* /* extinfo */, - Display* /* dpy */ + XExtensionInfo* /* extinfo */, + Display* /* dpy */ ); -extern XExtDisplayInfo *XextFindDisplay( - XExtensionInfo* /* extinfo */, - Display* /* dpy */ +extern XExtDisplayInfo* XextFindDisplay( + XExtensionInfo* /* extinfo */, + Display* /* dpy */ ); #define XextHasExtension(i) ((i) && ((i)->codes)) -#define XextCheckExtension(dpy,i,name,val) \ - if (!XextHasExtension(i)) { XMissingExtension (dpy, name); return val; } -#define XextSimpleCheckExtension(dpy,i,name) \ - if (!XextHasExtension(i)) { XMissingExtension (dpy, name); return; } - +#define XextCheckExtension(dpy, i, name, val) \ + if (!XextHasExtension(i)) \ + { \ + XMissingExtension(dpy, name); \ + return val; \ + } +#define XextSimpleCheckExtension(dpy, i, name) \ + if (!XextHasExtension(i)) \ + { \ + XMissingExtension(dpy, name); \ + return; \ + } /* * helper macros to generate code that is common to all extensions; caller @@ -150,41 +159,45 @@ extern XExtDisplayInfo *XextFindDisplay( * could be a utility function, but have to stack 6 unused arguments for * something that is called many, many times would be bad. */ -#define XEXT_GENERATE_FIND_DISPLAY(proc,extinfo,extname,hooks,nev,data) \ -XExtDisplayInfo *proc (Display *dpy) \ -{ \ - XExtDisplayInfo *dpyinfo; \ - if (!extinfo) { if (!(extinfo = XextCreateExtension())) return NULL; } \ - if (!(dpyinfo = XextFindDisplay (extinfo, dpy))) \ - dpyinfo = XextAddDisplay (extinfo,dpy,extname,hooks,nev,data); \ - return dpyinfo; \ -} +#define XEXT_GENERATE_FIND_DISPLAY(proc, extinfo, extname, hooks, nev, data) \ + XExtDisplayInfo* proc(Display* dpy) \ + { \ + XExtDisplayInfo* dpyinfo; \ + if (!extinfo) \ + { \ + if (!(extinfo = XextCreateExtension())) return NULL; \ + } \ + if (!(dpyinfo = XextFindDisplay(extinfo, dpy))) \ + dpyinfo = XextAddDisplay(extinfo, dpy, extname, hooks, nev, data); \ + return dpyinfo; \ + } #define XEXT_FIND_DISPLAY_PROTO(proc) \ - XExtDisplayInfo *proc(Display *dpy) + XExtDisplayInfo* proc(Display* dpy) -#define XEXT_GENERATE_CLOSE_DISPLAY(proc,extinfo) \ -int proc (Display *dpy, XExtCodes *codes) \ -{ \ - return XextRemoveDisplay (extinfo, dpy); \ -} +#define XEXT_GENERATE_CLOSE_DISPLAY(proc, extinfo) \ + int proc(Display* dpy, XExtCodes* codes) \ + { \ + return XextRemoveDisplay(extinfo, dpy); \ + } #define XEXT_CLOSE_DISPLAY_PROTO(proc) \ - int proc(Display *dpy, XExtCodes *codes) + int proc(Display* dpy, XExtCodes* codes) -#define XEXT_GENERATE_ERROR_STRING(proc,extname,nerr,errl) \ -char *proc (Display *dpy, int code, XExtCodes *codes, char *buf, int n) \ -{ \ - code -= codes->first_error; \ - if (code >= 0 && code < nerr) { \ - char tmp[256]; \ - sprintf (tmp, "%s.%d", extname, code); \ - XGetErrorDatabaseText (dpy, "XProtoError", tmp, errl[code], buf, n); \ - return buf; \ - } \ - return (char *)0; \ -} +#define XEXT_GENERATE_ERROR_STRING(proc, extname, nerr, errl) \ + char* proc(Display* dpy, int code, XExtCodes* codes, char* buf, int n) \ + { \ + code -= codes->first_error; \ + if (code >= 0 && code < nerr) \ + { \ + char tmp[256]; \ + sprintf(tmp, "%s.%d", extname, code); \ + XGetErrorDatabaseText(dpy, "XProtoError", tmp, errl[code], buf, n); \ + return buf; \ + } \ + return (char*)0; \ + } #define XEXT_ERROR_STRING_PROTO(proc) \ - char *proc(Display *dpy, int code, XExtCodes *codes, char *buf, int n) + char* proc(Display* dpy, int code, XExtCodes* codes, char* buf, int n) #endif diff --git a/examples/ThirdPartyLibs/optionalX11/X11/extensions/shape.h b/examples/ThirdPartyLibs/optionalX11/X11/extensions/shape.h index 66af5b1b4..b2887babd 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/extensions/shape.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/extensions/shape.h @@ -33,116 +33,117 @@ in this Software without prior written authorization from The Open Group. #ifndef _SHAPE_SERVER_ #include -typedef struct { - int type; /* of event */ - unsigned long serial; /* # of last request processed by server */ - Bool send_event; /* true if this came frome a SendEvent request */ - Display *display; /* Display the event was read from */ - Window window; /* window of event */ - int kind; /* ShapeBounding or ShapeClip */ - int x, y; /* extents of new region */ - unsigned width, height; - Time time; /* server timestamp when region changed */ - Bool shaped; /* true if the region exists */ +typedef struct +{ + int type; /* of event */ + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came frome a SendEvent request */ + Display* display; /* Display the event was read from */ + Window window; /* window of event */ + int kind; /* ShapeBounding or ShapeClip */ + int x, y; /* extents of new region */ + unsigned width, height; + Time time; /* server timestamp when region changed */ + Bool shaped; /* true if the region exists */ } XShapeEvent; _XFUNCPROTOBEGIN -extern Bool XShapeQueryExtension ( - Display* /* display */, - int* /* event_base */, - int* /* error_base */ +extern Bool XShapeQueryExtension( + Display* /* display */, + int* /* event_base */, + int* /* error_base */ ); -extern Status XShapeQueryVersion ( - Display* /* display */, - int* /* major_version */, - int* /* minor_version */ +extern Status XShapeQueryVersion( + Display* /* display */, + int* /* major_version */, + int* /* minor_version */ ); -extern void XShapeCombineRegion ( - Display* /* display */, - Window /* dest */, - int /* dest_kind */, - int /* x_off */, - int /* y_off */, - Region /* region */, - int /* op */ +extern void XShapeCombineRegion( + Display* /* display */, + Window /* dest */, + int /* dest_kind */, + int /* x_off */, + int /* y_off */, + Region /* region */, + int /* op */ ); -extern void XShapeCombineRectangles ( - Display* /* display */, - Window /* dest */, - int /* dest_kind */, - int /* x_off */, - int /* y_off */, - XRectangle* /* rectangles */, - int /* n_rects */, - int /* op */, - int /* ordering */ +extern void XShapeCombineRectangles( + Display* /* display */, + Window /* dest */, + int /* dest_kind */, + int /* x_off */, + int /* y_off */, + XRectangle* /* rectangles */, + int /* n_rects */, + int /* op */, + int /* ordering */ ); -extern void XShapeCombineMask ( - Display* /* display */, - Window /* dest */, - int /* dest_kind */, - int /* x_off */, - int /* y_off */, - Pixmap /* src */, - int /* op */ +extern void XShapeCombineMask( + Display* /* display */, + Window /* dest */, + int /* dest_kind */, + int /* x_off */, + int /* y_off */, + Pixmap /* src */, + int /* op */ ); -extern void XShapeCombineShape ( - Display* /* display */, - Window /* dest */, - int /* dest_kind */, - int /* x_off */, - int /* y_off */, - Window /* src */, - int /* src_kind */, - int /* op */ +extern void XShapeCombineShape( + Display* /* display */, + Window /* dest */, + int /* dest_kind */, + int /* x_off */, + int /* y_off */, + Window /* src */, + int /* src_kind */, + int /* op */ ); -extern void XShapeOffsetShape ( - Display* /* display */, - Window /* dest */, - int /* dest_kind */, - int /* x_off */, - int /* y_off */ +extern void XShapeOffsetShape( + Display* /* display */, + Window /* dest */, + int /* dest_kind */, + int /* x_off */, + int /* y_off */ ); -extern Status XShapeQueryExtents ( - Display* /* display */, - Window /* window */, - Bool* /* bounding_shaped */, - int* /* x_bounding */, - int* /* y_bounding */, - unsigned int* /* w_bounding */, - unsigned int* /* h_bounding */, - Bool* /* clip_shaped */, - int* /* x_clip */, - int* /* y_clip */, - unsigned int* /* w_clip */, - unsigned int* /* h_clip */ +extern Status XShapeQueryExtents( + Display* /* display */, + Window /* window */, + Bool* /* bounding_shaped */, + int* /* x_bounding */, + int* /* y_bounding */, + unsigned int* /* w_bounding */, + unsigned int* /* h_bounding */, + Bool* /* clip_shaped */, + int* /* x_clip */, + int* /* y_clip */, + unsigned int* /* w_clip */, + unsigned int* /* h_clip */ ); -extern void XShapeSelectInput ( - Display* /* display */, - Window /* window */, - unsigned long /* mask */ +extern void XShapeSelectInput( + Display* /* display */, + Window /* window */, + unsigned long /* mask */ ); -extern unsigned long XShapeInputSelected ( - Display* /* display */, - Window /* window */ +extern unsigned long XShapeInputSelected( + Display* /* display */, + Window /* window */ ); -extern XRectangle *XShapeGetRectangles ( - Display* /* display */, - Window /* window */, - int /* kind */, - int* /* count */, - int* /* ordering */ +extern XRectangle* XShapeGetRectangles( + Display* /* display */, + Window /* window */, + int /* kind */, + int* /* count */, + int* /* ordering */ ); _XFUNCPROTOEND diff --git a/examples/ThirdPartyLibs/optionalX11/X11/extensions/shapeconst.h b/examples/ThirdPartyLibs/optionalX11/X11/extensions/shapeconst.h index 9088956f1..d0a5d2bb9 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/extensions/shapeconst.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/extensions/shapeconst.h @@ -34,22 +34,22 @@ in this Software without prior written authorization from The Open Group. #define SHAPENAME "SHAPE" -#define SHAPE_MAJOR_VERSION 1 /* current version numbers */ -#define SHAPE_MINOR_VERSION 1 +#define SHAPE_MAJOR_VERSION 1 /* current version numbers */ +#define SHAPE_MINOR_VERSION 1 -#define ShapeSet 0 -#define ShapeUnion 1 -#define ShapeIntersect 2 -#define ShapeSubtract 3 -#define ShapeInvert 4 +#define ShapeSet 0 +#define ShapeUnion 1 +#define ShapeIntersect 2 +#define ShapeSubtract 3 +#define ShapeInvert 4 -#define ShapeBounding 0 -#define ShapeClip 1 -#define ShapeInput 2 +#define ShapeBounding 0 +#define ShapeClip 1 +#define ShapeInput 2 -#define ShapeNotifyMask (1L << 0) -#define ShapeNotify 0 +#define ShapeNotifyMask (1L << 0) +#define ShapeNotify 0 -#define ShapeNumberEvents (ShapeNotify + 1) +#define ShapeNumberEvents (ShapeNotify + 1) #endif /* _SHAPECONST_H_ */ diff --git a/examples/ThirdPartyLibs/optionalX11/X11/extensions/shm.h b/examples/ThirdPartyLibs/optionalX11/X11/extensions/shm.h index be49f5e97..58bf58582 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/extensions/shm.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/extensions/shm.h @@ -31,14 +31,13 @@ in this Software without prior written authorization from The Open Group. #define SHMNAME "MIT-SHM" -#define SHM_MAJOR_VERSION 1 /* current version numbers */ -#define SHM_MINOR_VERSION 2 +#define SHM_MAJOR_VERSION 1 /* current version numbers */ +#define SHM_MINOR_VERSION 2 -#define ShmCompletion 0 -#define ShmNumberEvents (ShmCompletion + 1) - -#define BadShmSeg 0 -#define ShmNumberErrors (BadShmSeg + 1) +#define ShmCompletion 0 +#define ShmNumberEvents (ShmCompletion + 1) +#define BadShmSeg 0 +#define ShmNumberErrors (BadShmSeg + 1) #endif /* _SHM_H_ */ diff --git a/examples/ThirdPartyLibs/optionalX11/X11/keysym.h b/examples/ThirdPartyLibs/optionalX11/X11/keysym.h index 4f584886c..c8c022e8e 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/keysym.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/keysym.h @@ -71,4 +71,3 @@ SOFTWARE. #define XK_SINHALA #include - diff --git a/examples/ThirdPartyLibs/optionalX11/X11/keysymdef.h b/examples/ThirdPartyLibs/optionalX11/X11/keysymdef.h index ae73977cb..f7b64c754 100644 --- a/examples/ThirdPartyLibs/optionalX11/X11/keysymdef.h +++ b/examples/ThirdPartyLibs/optionalX11/X11/keysymdef.h @@ -112,7 +112,7 @@ SOFTWARE. * */ -#define XK_VoidSymbol 0xffffff /* Void symbol */ +#define XK_VoidSymbol 0xffffff /* Void symbol */ #ifdef XK_MISCELLANY /* @@ -121,126 +121,121 @@ SOFTWARE. * tables in client code). */ -#define XK_BackSpace 0xff08 /* Back space, back char */ -#define XK_Tab 0xff09 -#define XK_Linefeed 0xff0a /* Linefeed, LF */ -#define XK_Clear 0xff0b -#define XK_Return 0xff0d /* Return, enter */ -#define XK_Pause 0xff13 /* Pause, hold */ -#define XK_Scroll_Lock 0xff14 -#define XK_Sys_Req 0xff15 -#define XK_Escape 0xff1b -#define XK_Delete 0xffff /* Delete, rubout */ - - +#define XK_BackSpace 0xff08 /* Back space, back char */ +#define XK_Tab 0xff09 +#define XK_Linefeed 0xff0a /* Linefeed, LF */ +#define XK_Clear 0xff0b +#define XK_Return 0xff0d /* Return, enter */ +#define XK_Pause 0xff13 /* Pause, hold */ +#define XK_Scroll_Lock 0xff14 +#define XK_Sys_Req 0xff15 +#define XK_Escape 0xff1b +#define XK_Delete 0xffff /* Delete, rubout */ /* International & multi-key character composition */ -#define XK_Multi_key 0xff20 /* Multi-key character compose */ -#define XK_Codeinput 0xff37 -#define XK_SingleCandidate 0xff3c -#define XK_MultipleCandidate 0xff3d -#define XK_PreviousCandidate 0xff3e +#define XK_Multi_key 0xff20 /* Multi-key character compose */ +#define XK_Codeinput 0xff37 +#define XK_SingleCandidate 0xff3c +#define XK_MultipleCandidate 0xff3d +#define XK_PreviousCandidate 0xff3e /* Japanese keyboard support */ -#define XK_Kanji 0xff21 /* Kanji, Kanji convert */ -#define XK_Muhenkan 0xff22 /* Cancel Conversion */ -#define XK_Henkan_Mode 0xff23 /* Start/Stop Conversion */ -#define XK_Henkan 0xff23 /* Alias for Henkan_Mode */ -#define XK_Romaji 0xff24 /* to Romaji */ -#define XK_Hiragana 0xff25 /* to Hiragana */ -#define XK_Katakana 0xff26 /* to Katakana */ -#define XK_Hiragana_Katakana 0xff27 /* Hiragana/Katakana toggle */ -#define XK_Zenkaku 0xff28 /* to Zenkaku */ -#define XK_Hankaku 0xff29 /* to Hankaku */ -#define XK_Zenkaku_Hankaku 0xff2a /* Zenkaku/Hankaku toggle */ -#define XK_Touroku 0xff2b /* Add to Dictionary */ -#define XK_Massyo 0xff2c /* Delete from Dictionary */ -#define XK_Kana_Lock 0xff2d /* Kana Lock */ -#define XK_Kana_Shift 0xff2e /* Kana Shift */ -#define XK_Eisu_Shift 0xff2f /* Alphanumeric Shift */ -#define XK_Eisu_toggle 0xff30 /* Alphanumeric toggle */ -#define XK_Kanji_Bangou 0xff37 /* Codeinput */ -#define XK_Zen_Koho 0xff3d /* Multiple/All Candidate(s) */ -#define XK_Mae_Koho 0xff3e /* Previous Candidate */ +#define XK_Kanji 0xff21 /* Kanji, Kanji convert */ +#define XK_Muhenkan 0xff22 /* Cancel Conversion */ +#define XK_Henkan_Mode 0xff23 /* Start/Stop Conversion */ +#define XK_Henkan 0xff23 /* Alias for Henkan_Mode */ +#define XK_Romaji 0xff24 /* to Romaji */ +#define XK_Hiragana 0xff25 /* to Hiragana */ +#define XK_Katakana 0xff26 /* to Katakana */ +#define XK_Hiragana_Katakana 0xff27 /* Hiragana/Katakana toggle */ +#define XK_Zenkaku 0xff28 /* to Zenkaku */ +#define XK_Hankaku 0xff29 /* to Hankaku */ +#define XK_Zenkaku_Hankaku 0xff2a /* Zenkaku/Hankaku toggle */ +#define XK_Touroku 0xff2b /* Add to Dictionary */ +#define XK_Massyo 0xff2c /* Delete from Dictionary */ +#define XK_Kana_Lock 0xff2d /* Kana Lock */ +#define XK_Kana_Shift 0xff2e /* Kana Shift */ +#define XK_Eisu_Shift 0xff2f /* Alphanumeric Shift */ +#define XK_Eisu_toggle 0xff30 /* Alphanumeric toggle */ +#define XK_Kanji_Bangou 0xff37 /* Codeinput */ +#define XK_Zen_Koho 0xff3d /* Multiple/All Candidate(s) */ +#define XK_Mae_Koho 0xff3e /* Previous Candidate */ /* 0xff31 thru 0xff3f are under XK_KOREAN */ /* Cursor control & motion */ -#define XK_Home 0xff50 -#define XK_Left 0xff51 /* Move left, left arrow */ -#define XK_Up 0xff52 /* Move up, up arrow */ -#define XK_Right 0xff53 /* Move right, right arrow */ -#define XK_Down 0xff54 /* Move down, down arrow */ -#define XK_Prior 0xff55 /* Prior, previous */ -#define XK_Page_Up 0xff55 -#define XK_Next 0xff56 /* Next */ -#define XK_Page_Down 0xff56 -#define XK_End 0xff57 /* EOL */ -#define XK_Begin 0xff58 /* BOL */ - +#define XK_Home 0xff50 +#define XK_Left 0xff51 /* Move left, left arrow */ +#define XK_Up 0xff52 /* Move up, up arrow */ +#define XK_Right 0xff53 /* Move right, right arrow */ +#define XK_Down 0xff54 /* Move down, down arrow */ +#define XK_Prior 0xff55 /* Prior, previous */ +#define XK_Page_Up 0xff55 +#define XK_Next 0xff56 /* Next */ +#define XK_Page_Down 0xff56 +#define XK_End 0xff57 /* EOL */ +#define XK_Begin 0xff58 /* BOL */ /* Misc functions */ -#define XK_Select 0xff60 /* Select, mark */ -#define XK_Print 0xff61 -#define XK_Execute 0xff62 /* Execute, run, do */ -#define XK_Insert 0xff63 /* Insert, insert here */ -#define XK_Undo 0xff65 -#define XK_Redo 0xff66 /* Redo, again */ -#define XK_Menu 0xff67 -#define XK_Find 0xff68 /* Find, search */ -#define XK_Cancel 0xff69 /* Cancel, stop, abort, exit */ -#define XK_Help 0xff6a /* Help */ -#define XK_Break 0xff6b -#define XK_Mode_switch 0xff7e /* Character set switch */ -#define XK_script_switch 0xff7e /* Alias for mode_switch */ -#define XK_Num_Lock 0xff7f +#define XK_Select 0xff60 /* Select, mark */ +#define XK_Print 0xff61 +#define XK_Execute 0xff62 /* Execute, run, do */ +#define XK_Insert 0xff63 /* Insert, insert here */ +#define XK_Undo 0xff65 +#define XK_Redo 0xff66 /* Redo, again */ +#define XK_Menu 0xff67 +#define XK_Find 0xff68 /* Find, search */ +#define XK_Cancel 0xff69 /* Cancel, stop, abort, exit */ +#define XK_Help 0xff6a /* Help */ +#define XK_Break 0xff6b +#define XK_Mode_switch 0xff7e /* Character set switch */ +#define XK_script_switch 0xff7e /* Alias for mode_switch */ +#define XK_Num_Lock 0xff7f /* Keypad functions, keypad numbers cleverly chosen to map to ASCII */ -#define XK_KP_Space 0xff80 /* Space */ -#define XK_KP_Tab 0xff89 -#define XK_KP_Enter 0xff8d /* Enter */ -#define XK_KP_F1 0xff91 /* PF1, KP_A, ... */ -#define XK_KP_F2 0xff92 -#define XK_KP_F3 0xff93 -#define XK_KP_F4 0xff94 -#define XK_KP_Home 0xff95 -#define XK_KP_Left 0xff96 -#define XK_KP_Up 0xff97 -#define XK_KP_Right 0xff98 -#define XK_KP_Down 0xff99 -#define XK_KP_Prior 0xff9a -#define XK_KP_Page_Up 0xff9a -#define XK_KP_Next 0xff9b -#define XK_KP_Page_Down 0xff9b -#define XK_KP_End 0xff9c -#define XK_KP_Begin 0xff9d -#define XK_KP_Insert 0xff9e -#define XK_KP_Delete 0xff9f -#define XK_KP_Equal 0xffbd /* Equals */ -#define XK_KP_Multiply 0xffaa -#define XK_KP_Add 0xffab -#define XK_KP_Separator 0xffac /* Separator, often comma */ -#define XK_KP_Subtract 0xffad -#define XK_KP_Decimal 0xffae -#define XK_KP_Divide 0xffaf - -#define XK_KP_0 0xffb0 -#define XK_KP_1 0xffb1 -#define XK_KP_2 0xffb2 -#define XK_KP_3 0xffb3 -#define XK_KP_4 0xffb4 -#define XK_KP_5 0xffb5 -#define XK_KP_6 0xffb6 -#define XK_KP_7 0xffb7 -#define XK_KP_8 0xffb8 -#define XK_KP_9 0xffb9 - +#define XK_KP_Space 0xff80 /* Space */ +#define XK_KP_Tab 0xff89 +#define XK_KP_Enter 0xff8d /* Enter */ +#define XK_KP_F1 0xff91 /* PF1, KP_A, ... */ +#define XK_KP_F2 0xff92 +#define XK_KP_F3 0xff93 +#define XK_KP_F4 0xff94 +#define XK_KP_Home 0xff95 +#define XK_KP_Left 0xff96 +#define XK_KP_Up 0xff97 +#define XK_KP_Right 0xff98 +#define XK_KP_Down 0xff99 +#define XK_KP_Prior 0xff9a +#define XK_KP_Page_Up 0xff9a +#define XK_KP_Next 0xff9b +#define XK_KP_Page_Down 0xff9b +#define XK_KP_End 0xff9c +#define XK_KP_Begin 0xff9d +#define XK_KP_Insert 0xff9e +#define XK_KP_Delete 0xff9f +#define XK_KP_Equal 0xffbd /* Equals */ +#define XK_KP_Multiply 0xffaa +#define XK_KP_Add 0xffab +#define XK_KP_Separator 0xffac /* Separator, often comma */ +#define XK_KP_Subtract 0xffad +#define XK_KP_Decimal 0xffae +#define XK_KP_Divide 0xffaf +#define XK_KP_0 0xffb0 +#define XK_KP_1 0xffb1 +#define XK_KP_2 0xffb2 +#define XK_KP_3 0xffb3 +#define XK_KP_4 0xffb4 +#define XK_KP_5 0xffb5 +#define XK_KP_6 0xffb6 +#define XK_KP_7 0xffb7 +#define XK_KP_8 0xffb8 +#define XK_KP_9 0xffb9 /* * Auxiliary functions; note the duplicate definitions for left and right @@ -249,85 +244,85 @@ SOFTWARE. * We've not found a keyboard with more than 35 function keys total. */ -#define XK_F1 0xffbe -#define XK_F2 0xffbf -#define XK_F3 0xffc0 -#define XK_F4 0xffc1 -#define XK_F5 0xffc2 -#define XK_F6 0xffc3 -#define XK_F7 0xffc4 -#define XK_F8 0xffc5 -#define XK_F9 0xffc6 -#define XK_F10 0xffc7 -#define XK_F11 0xffc8 -#define XK_L1 0xffc8 -#define XK_F12 0xffc9 -#define XK_L2 0xffc9 -#define XK_F13 0xffca -#define XK_L3 0xffca -#define XK_F14 0xffcb -#define XK_L4 0xffcb -#define XK_F15 0xffcc -#define XK_L5 0xffcc -#define XK_F16 0xffcd -#define XK_L6 0xffcd -#define XK_F17 0xffce -#define XK_L7 0xffce -#define XK_F18 0xffcf -#define XK_L8 0xffcf -#define XK_F19 0xffd0 -#define XK_L9 0xffd0 -#define XK_F20 0xffd1 -#define XK_L10 0xffd1 -#define XK_F21 0xffd2 -#define XK_R1 0xffd2 -#define XK_F22 0xffd3 -#define XK_R2 0xffd3 -#define XK_F23 0xffd4 -#define XK_R3 0xffd4 -#define XK_F24 0xffd5 -#define XK_R4 0xffd5 -#define XK_F25 0xffd6 -#define XK_R5 0xffd6 -#define XK_F26 0xffd7 -#define XK_R6 0xffd7 -#define XK_F27 0xffd8 -#define XK_R7 0xffd8 -#define XK_F28 0xffd9 -#define XK_R8 0xffd9 -#define XK_F29 0xffda -#define XK_R9 0xffda -#define XK_F30 0xffdb -#define XK_R10 0xffdb -#define XK_F31 0xffdc -#define XK_R11 0xffdc -#define XK_F32 0xffdd -#define XK_R12 0xffdd -#define XK_F33 0xffde -#define XK_R13 0xffde -#define XK_F34 0xffdf -#define XK_R14 0xffdf -#define XK_F35 0xffe0 -#define XK_R15 0xffe0 +#define XK_F1 0xffbe +#define XK_F2 0xffbf +#define XK_F3 0xffc0 +#define XK_F4 0xffc1 +#define XK_F5 0xffc2 +#define XK_F6 0xffc3 +#define XK_F7 0xffc4 +#define XK_F8 0xffc5 +#define XK_F9 0xffc6 +#define XK_F10 0xffc7 +#define XK_F11 0xffc8 +#define XK_L1 0xffc8 +#define XK_F12 0xffc9 +#define XK_L2 0xffc9 +#define XK_F13 0xffca +#define XK_L3 0xffca +#define XK_F14 0xffcb +#define XK_L4 0xffcb +#define XK_F15 0xffcc +#define XK_L5 0xffcc +#define XK_F16 0xffcd +#define XK_L6 0xffcd +#define XK_F17 0xffce +#define XK_L7 0xffce +#define XK_F18 0xffcf +#define XK_L8 0xffcf +#define XK_F19 0xffd0 +#define XK_L9 0xffd0 +#define XK_F20 0xffd1 +#define XK_L10 0xffd1 +#define XK_F21 0xffd2 +#define XK_R1 0xffd2 +#define XK_F22 0xffd3 +#define XK_R2 0xffd3 +#define XK_F23 0xffd4 +#define XK_R3 0xffd4 +#define XK_F24 0xffd5 +#define XK_R4 0xffd5 +#define XK_F25 0xffd6 +#define XK_R5 0xffd6 +#define XK_F26 0xffd7 +#define XK_R6 0xffd7 +#define XK_F27 0xffd8 +#define XK_R7 0xffd8 +#define XK_F28 0xffd9 +#define XK_R8 0xffd9 +#define XK_F29 0xffda +#define XK_R9 0xffda +#define XK_F30 0xffdb +#define XK_R10 0xffdb +#define XK_F31 0xffdc +#define XK_R11 0xffdc +#define XK_F32 0xffdd +#define XK_R12 0xffdd +#define XK_F33 0xffde +#define XK_R13 0xffde +#define XK_F34 0xffdf +#define XK_R14 0xffdf +#define XK_F35 0xffe0 +#define XK_R15 0xffe0 /* Modifiers */ -#define XK_Shift_L 0xffe1 /* Left shift */ -#define XK_Shift_R 0xffe2 /* Right shift */ -#define XK_Control_L 0xffe3 /* Left control */ -#define XK_Control_R 0xffe4 /* Right control */ -#define XK_Caps_Lock 0xffe5 /* Caps lock */ -#define XK_Shift_Lock 0xffe6 /* Shift lock */ +#define XK_Shift_L 0xffe1 /* Left shift */ +#define XK_Shift_R 0xffe2 /* Right shift */ +#define XK_Control_L 0xffe3 /* Left control */ +#define XK_Control_R 0xffe4 /* Right control */ +#define XK_Caps_Lock 0xffe5 /* Caps lock */ +#define XK_Shift_Lock 0xffe6 /* Shift lock */ -#define XK_Meta_L 0xffe7 /* Left meta */ -#define XK_Meta_R 0xffe8 /* Right meta */ -#define XK_Alt_L 0xffe9 /* Left alt */ -#define XK_Alt_R 0xffea /* Right alt */ -#define XK_Super_L 0xffeb /* Left super */ -#define XK_Super_R 0xffec /* Right super */ -#define XK_Hyper_L 0xffed /* Left hyper */ -#define XK_Hyper_R 0xffee /* Right hyper */ -#endif /* XK_MISCELLANY */ +#define XK_Meta_L 0xffe7 /* Left meta */ +#define XK_Meta_R 0xffe8 /* Right meta */ +#define XK_Alt_L 0xffe9 /* Left alt */ +#define XK_Alt_R 0xffea /* Right alt */ +#define XK_Super_L 0xffeb /* Left super */ +#define XK_Super_R 0xffec /* Right super */ +#define XK_Hyper_L 0xffed /* Left hyper */ +#define XK_Hyper_R 0xffee /* Right hyper */ +#endif /* XK_MISCELLANY */ /* * Keyboard (XKB) Extension function and modifier keys @@ -336,158 +331,158 @@ SOFTWARE. */ #ifdef XK_XKB_KEYS -#define XK_ISO_Lock 0xfe01 -#define XK_ISO_Level2_Latch 0xfe02 -#define XK_ISO_Level3_Shift 0xfe03 -#define XK_ISO_Level3_Latch 0xfe04 -#define XK_ISO_Level3_Lock 0xfe05 -#define XK_ISO_Level5_Shift 0xfe11 -#define XK_ISO_Level5_Latch 0xfe12 -#define XK_ISO_Level5_Lock 0xfe13 -#define XK_ISO_Group_Shift 0xff7e /* Alias for mode_switch */ -#define XK_ISO_Group_Latch 0xfe06 -#define XK_ISO_Group_Lock 0xfe07 -#define XK_ISO_Next_Group 0xfe08 -#define XK_ISO_Next_Group_Lock 0xfe09 -#define XK_ISO_Prev_Group 0xfe0a -#define XK_ISO_Prev_Group_Lock 0xfe0b -#define XK_ISO_First_Group 0xfe0c -#define XK_ISO_First_Group_Lock 0xfe0d -#define XK_ISO_Last_Group 0xfe0e -#define XK_ISO_Last_Group_Lock 0xfe0f +#define XK_ISO_Lock 0xfe01 +#define XK_ISO_Level2_Latch 0xfe02 +#define XK_ISO_Level3_Shift 0xfe03 +#define XK_ISO_Level3_Latch 0xfe04 +#define XK_ISO_Level3_Lock 0xfe05 +#define XK_ISO_Level5_Shift 0xfe11 +#define XK_ISO_Level5_Latch 0xfe12 +#define XK_ISO_Level5_Lock 0xfe13 +#define XK_ISO_Group_Shift 0xff7e /* Alias for mode_switch */ +#define XK_ISO_Group_Latch 0xfe06 +#define XK_ISO_Group_Lock 0xfe07 +#define XK_ISO_Next_Group 0xfe08 +#define XK_ISO_Next_Group_Lock 0xfe09 +#define XK_ISO_Prev_Group 0xfe0a +#define XK_ISO_Prev_Group_Lock 0xfe0b +#define XK_ISO_First_Group 0xfe0c +#define XK_ISO_First_Group_Lock 0xfe0d +#define XK_ISO_Last_Group 0xfe0e +#define XK_ISO_Last_Group_Lock 0xfe0f -#define XK_ISO_Left_Tab 0xfe20 -#define XK_ISO_Move_Line_Up 0xfe21 -#define XK_ISO_Move_Line_Down 0xfe22 -#define XK_ISO_Partial_Line_Up 0xfe23 -#define XK_ISO_Partial_Line_Down 0xfe24 -#define XK_ISO_Partial_Space_Left 0xfe25 -#define XK_ISO_Partial_Space_Right 0xfe26 -#define XK_ISO_Set_Margin_Left 0xfe27 -#define XK_ISO_Set_Margin_Right 0xfe28 -#define XK_ISO_Release_Margin_Left 0xfe29 -#define XK_ISO_Release_Margin_Right 0xfe2a -#define XK_ISO_Release_Both_Margins 0xfe2b -#define XK_ISO_Fast_Cursor_Left 0xfe2c -#define XK_ISO_Fast_Cursor_Right 0xfe2d -#define XK_ISO_Fast_Cursor_Up 0xfe2e -#define XK_ISO_Fast_Cursor_Down 0xfe2f -#define XK_ISO_Continuous_Underline 0xfe30 -#define XK_ISO_Discontinuous_Underline 0xfe31 -#define XK_ISO_Emphasize 0xfe32 -#define XK_ISO_Center_Object 0xfe33 -#define XK_ISO_Enter 0xfe34 +#define XK_ISO_Left_Tab 0xfe20 +#define XK_ISO_Move_Line_Up 0xfe21 +#define XK_ISO_Move_Line_Down 0xfe22 +#define XK_ISO_Partial_Line_Up 0xfe23 +#define XK_ISO_Partial_Line_Down 0xfe24 +#define XK_ISO_Partial_Space_Left 0xfe25 +#define XK_ISO_Partial_Space_Right 0xfe26 +#define XK_ISO_Set_Margin_Left 0xfe27 +#define XK_ISO_Set_Margin_Right 0xfe28 +#define XK_ISO_Release_Margin_Left 0xfe29 +#define XK_ISO_Release_Margin_Right 0xfe2a +#define XK_ISO_Release_Both_Margins 0xfe2b +#define XK_ISO_Fast_Cursor_Left 0xfe2c +#define XK_ISO_Fast_Cursor_Right 0xfe2d +#define XK_ISO_Fast_Cursor_Up 0xfe2e +#define XK_ISO_Fast_Cursor_Down 0xfe2f +#define XK_ISO_Continuous_Underline 0xfe30 +#define XK_ISO_Discontinuous_Underline 0xfe31 +#define XK_ISO_Emphasize 0xfe32 +#define XK_ISO_Center_Object 0xfe33 +#define XK_ISO_Enter 0xfe34 -#define XK_dead_grave 0xfe50 -#define XK_dead_acute 0xfe51 -#define XK_dead_circumflex 0xfe52 -#define XK_dead_tilde 0xfe53 -#define XK_dead_perispomeni 0xfe53 /* alias for dead_tilde */ -#define XK_dead_macron 0xfe54 -#define XK_dead_breve 0xfe55 -#define XK_dead_abovedot 0xfe56 -#define XK_dead_diaeresis 0xfe57 -#define XK_dead_abovering 0xfe58 -#define XK_dead_doubleacute 0xfe59 -#define XK_dead_caron 0xfe5a -#define XK_dead_cedilla 0xfe5b -#define XK_dead_ogonek 0xfe5c -#define XK_dead_iota 0xfe5d -#define XK_dead_voiced_sound 0xfe5e -#define XK_dead_semivoiced_sound 0xfe5f -#define XK_dead_belowdot 0xfe60 -#define XK_dead_hook 0xfe61 -#define XK_dead_horn 0xfe62 -#define XK_dead_stroke 0xfe63 -#define XK_dead_abovecomma 0xfe64 -#define XK_dead_psili 0xfe64 /* alias for dead_abovecomma */ -#define XK_dead_abovereversedcomma 0xfe65 -#define XK_dead_dasia 0xfe65 /* alias for dead_abovereversedcomma */ -#define XK_dead_doublegrave 0xfe66 -#define XK_dead_belowring 0xfe67 -#define XK_dead_belowmacron 0xfe68 -#define XK_dead_belowcircumflex 0xfe69 -#define XK_dead_belowtilde 0xfe6a -#define XK_dead_belowbreve 0xfe6b -#define XK_dead_belowdiaeresis 0xfe6c -#define XK_dead_invertedbreve 0xfe6d -#define XK_dead_belowcomma 0xfe6e -#define XK_dead_currency 0xfe6f +#define XK_dead_grave 0xfe50 +#define XK_dead_acute 0xfe51 +#define XK_dead_circumflex 0xfe52 +#define XK_dead_tilde 0xfe53 +#define XK_dead_perispomeni 0xfe53 /* alias for dead_tilde */ +#define XK_dead_macron 0xfe54 +#define XK_dead_breve 0xfe55 +#define XK_dead_abovedot 0xfe56 +#define XK_dead_diaeresis 0xfe57 +#define XK_dead_abovering 0xfe58 +#define XK_dead_doubleacute 0xfe59 +#define XK_dead_caron 0xfe5a +#define XK_dead_cedilla 0xfe5b +#define XK_dead_ogonek 0xfe5c +#define XK_dead_iota 0xfe5d +#define XK_dead_voiced_sound 0xfe5e +#define XK_dead_semivoiced_sound 0xfe5f +#define XK_dead_belowdot 0xfe60 +#define XK_dead_hook 0xfe61 +#define XK_dead_horn 0xfe62 +#define XK_dead_stroke 0xfe63 +#define XK_dead_abovecomma 0xfe64 +#define XK_dead_psili 0xfe64 /* alias for dead_abovecomma */ +#define XK_dead_abovereversedcomma 0xfe65 +#define XK_dead_dasia 0xfe65 /* alias for dead_abovereversedcomma */ +#define XK_dead_doublegrave 0xfe66 +#define XK_dead_belowring 0xfe67 +#define XK_dead_belowmacron 0xfe68 +#define XK_dead_belowcircumflex 0xfe69 +#define XK_dead_belowtilde 0xfe6a +#define XK_dead_belowbreve 0xfe6b +#define XK_dead_belowdiaeresis 0xfe6c +#define XK_dead_invertedbreve 0xfe6d +#define XK_dead_belowcomma 0xfe6e +#define XK_dead_currency 0xfe6f /* dead vowels for universal syllable entry */ -#define XK_dead_a 0xfe80 -#define XK_dead_A 0xfe81 -#define XK_dead_e 0xfe82 -#define XK_dead_E 0xfe83 -#define XK_dead_i 0xfe84 -#define XK_dead_I 0xfe85 -#define XK_dead_o 0xfe86 -#define XK_dead_O 0xfe87 -#define XK_dead_u 0xfe88 -#define XK_dead_U 0xfe89 -#define XK_dead_small_schwa 0xfe8a -#define XK_dead_capital_schwa 0xfe8b +#define XK_dead_a 0xfe80 +#define XK_dead_A 0xfe81 +#define XK_dead_e 0xfe82 +#define XK_dead_E 0xfe83 +#define XK_dead_i 0xfe84 +#define XK_dead_I 0xfe85 +#define XK_dead_o 0xfe86 +#define XK_dead_O 0xfe87 +#define XK_dead_u 0xfe88 +#define XK_dead_U 0xfe89 +#define XK_dead_small_schwa 0xfe8a +#define XK_dead_capital_schwa 0xfe8b -#define XK_dead_greek 0xfe8c +#define XK_dead_greek 0xfe8c -#define XK_First_Virtual_Screen 0xfed0 -#define XK_Prev_Virtual_Screen 0xfed1 -#define XK_Next_Virtual_Screen 0xfed2 -#define XK_Last_Virtual_Screen 0xfed4 -#define XK_Terminate_Server 0xfed5 +#define XK_First_Virtual_Screen 0xfed0 +#define XK_Prev_Virtual_Screen 0xfed1 +#define XK_Next_Virtual_Screen 0xfed2 +#define XK_Last_Virtual_Screen 0xfed4 +#define XK_Terminate_Server 0xfed5 -#define XK_AccessX_Enable 0xfe70 -#define XK_AccessX_Feedback_Enable 0xfe71 -#define XK_RepeatKeys_Enable 0xfe72 -#define XK_SlowKeys_Enable 0xfe73 -#define XK_BounceKeys_Enable 0xfe74 -#define XK_StickyKeys_Enable 0xfe75 -#define XK_MouseKeys_Enable 0xfe76 -#define XK_MouseKeys_Accel_Enable 0xfe77 -#define XK_Overlay1_Enable 0xfe78 -#define XK_Overlay2_Enable 0xfe79 -#define XK_AudibleBell_Enable 0xfe7a +#define XK_AccessX_Enable 0xfe70 +#define XK_AccessX_Feedback_Enable 0xfe71 +#define XK_RepeatKeys_Enable 0xfe72 +#define XK_SlowKeys_Enable 0xfe73 +#define XK_BounceKeys_Enable 0xfe74 +#define XK_StickyKeys_Enable 0xfe75 +#define XK_MouseKeys_Enable 0xfe76 +#define XK_MouseKeys_Accel_Enable 0xfe77 +#define XK_Overlay1_Enable 0xfe78 +#define XK_Overlay2_Enable 0xfe79 +#define XK_AudibleBell_Enable 0xfe7a -#define XK_Pointer_Left 0xfee0 -#define XK_Pointer_Right 0xfee1 -#define XK_Pointer_Up 0xfee2 -#define XK_Pointer_Down 0xfee3 -#define XK_Pointer_UpLeft 0xfee4 -#define XK_Pointer_UpRight 0xfee5 -#define XK_Pointer_DownLeft 0xfee6 -#define XK_Pointer_DownRight 0xfee7 -#define XK_Pointer_Button_Dflt 0xfee8 -#define XK_Pointer_Button1 0xfee9 -#define XK_Pointer_Button2 0xfeea -#define XK_Pointer_Button3 0xfeeb -#define XK_Pointer_Button4 0xfeec -#define XK_Pointer_Button5 0xfeed -#define XK_Pointer_DblClick_Dflt 0xfeee -#define XK_Pointer_DblClick1 0xfeef -#define XK_Pointer_DblClick2 0xfef0 -#define XK_Pointer_DblClick3 0xfef1 -#define XK_Pointer_DblClick4 0xfef2 -#define XK_Pointer_DblClick5 0xfef3 -#define XK_Pointer_Drag_Dflt 0xfef4 -#define XK_Pointer_Drag1 0xfef5 -#define XK_Pointer_Drag2 0xfef6 -#define XK_Pointer_Drag3 0xfef7 -#define XK_Pointer_Drag4 0xfef8 -#define XK_Pointer_Drag5 0xfefd +#define XK_Pointer_Left 0xfee0 +#define XK_Pointer_Right 0xfee1 +#define XK_Pointer_Up 0xfee2 +#define XK_Pointer_Down 0xfee3 +#define XK_Pointer_UpLeft 0xfee4 +#define XK_Pointer_UpRight 0xfee5 +#define XK_Pointer_DownLeft 0xfee6 +#define XK_Pointer_DownRight 0xfee7 +#define XK_Pointer_Button_Dflt 0xfee8 +#define XK_Pointer_Button1 0xfee9 +#define XK_Pointer_Button2 0xfeea +#define XK_Pointer_Button3 0xfeeb +#define XK_Pointer_Button4 0xfeec +#define XK_Pointer_Button5 0xfeed +#define XK_Pointer_DblClick_Dflt 0xfeee +#define XK_Pointer_DblClick1 0xfeef +#define XK_Pointer_DblClick2 0xfef0 +#define XK_Pointer_DblClick3 0xfef1 +#define XK_Pointer_DblClick4 0xfef2 +#define XK_Pointer_DblClick5 0xfef3 +#define XK_Pointer_Drag_Dflt 0xfef4 +#define XK_Pointer_Drag1 0xfef5 +#define XK_Pointer_Drag2 0xfef6 +#define XK_Pointer_Drag3 0xfef7 +#define XK_Pointer_Drag4 0xfef8 +#define XK_Pointer_Drag5 0xfefd -#define XK_Pointer_EnableKeys 0xfef9 -#define XK_Pointer_Accelerate 0xfefa -#define XK_Pointer_DfltBtnNext 0xfefb -#define XK_Pointer_DfltBtnPrev 0xfefc +#define XK_Pointer_EnableKeys 0xfef9 +#define XK_Pointer_Accelerate 0xfefa +#define XK_Pointer_DfltBtnNext 0xfefb +#define XK_Pointer_DfltBtnPrev 0xfefc /* Single-Stroke Multiple-Character N-Graph Keysyms For The X Input Method */ -#define XK_ch 0xfea0 -#define XK_Ch 0xfea1 -#define XK_CH 0xfea2 -#define XK_c_h 0xfea3 -#define XK_C_h 0xfea4 -#define XK_C_H 0xfea5 +#define XK_ch 0xfea0 +#define XK_Ch 0xfea1 +#define XK_CH 0xfea2 +#define XK_c_h 0xfea3 +#define XK_C_h 0xfea4 +#define XK_C_H 0xfea5 #endif /* XK_XKB_KEYS */ @@ -497,36 +492,36 @@ SOFTWARE. */ #ifdef XK_3270 -#define XK_3270_Duplicate 0xfd01 -#define XK_3270_FieldMark 0xfd02 -#define XK_3270_Right2 0xfd03 -#define XK_3270_Left2 0xfd04 -#define XK_3270_BackTab 0xfd05 -#define XK_3270_EraseEOF 0xfd06 -#define XK_3270_EraseInput 0xfd07 -#define XK_3270_Reset 0xfd08 -#define XK_3270_Quit 0xfd09 -#define XK_3270_PA1 0xfd0a -#define XK_3270_PA2 0xfd0b -#define XK_3270_PA3 0xfd0c -#define XK_3270_Test 0xfd0d -#define XK_3270_Attn 0xfd0e -#define XK_3270_CursorBlink 0xfd0f -#define XK_3270_AltCursor 0xfd10 -#define XK_3270_KeyClick 0xfd11 -#define XK_3270_Jump 0xfd12 -#define XK_3270_Ident 0xfd13 -#define XK_3270_Rule 0xfd14 -#define XK_3270_Copy 0xfd15 -#define XK_3270_Play 0xfd16 -#define XK_3270_Setup 0xfd17 -#define XK_3270_Record 0xfd18 -#define XK_3270_ChangeScreen 0xfd19 -#define XK_3270_DeleteWord 0xfd1a -#define XK_3270_ExSelect 0xfd1b -#define XK_3270_CursorSelect 0xfd1c -#define XK_3270_PrintScreen 0xfd1d -#define XK_3270_Enter 0xfd1e +#define XK_3270_Duplicate 0xfd01 +#define XK_3270_FieldMark 0xfd02 +#define XK_3270_Right2 0xfd03 +#define XK_3270_Left2 0xfd04 +#define XK_3270_BackTab 0xfd05 +#define XK_3270_EraseEOF 0xfd06 +#define XK_3270_EraseInput 0xfd07 +#define XK_3270_Reset 0xfd08 +#define XK_3270_Quit 0xfd09 +#define XK_3270_PA1 0xfd0a +#define XK_3270_PA2 0xfd0b +#define XK_3270_PA3 0xfd0c +#define XK_3270_Test 0xfd0d +#define XK_3270_Attn 0xfd0e +#define XK_3270_CursorBlink 0xfd0f +#define XK_3270_AltCursor 0xfd10 +#define XK_3270_KeyClick 0xfd11 +#define XK_3270_Jump 0xfd12 +#define XK_3270_Ident 0xfd13 +#define XK_3270_Rule 0xfd14 +#define XK_3270_Copy 0xfd15 +#define XK_3270_Play 0xfd16 +#define XK_3270_Setup 0xfd17 +#define XK_3270_Record 0xfd18 +#define XK_3270_ChangeScreen 0xfd19 +#define XK_3270_DeleteWord 0xfd1a +#define XK_3270_ExSelect 0xfd1b +#define XK_3270_CursorSelect 0xfd1c +#define XK_3270_PrintScreen 0xfd1d +#define XK_3270_Enter 0xfd1e #endif /* XK_3270 */ /* @@ -535,205 +530,205 @@ SOFTWARE. * Byte 3 = 0 */ #ifdef XK_LATIN1 -#define XK_space 0x0020 /* U+0020 SPACE */ -#define XK_exclam 0x0021 /* U+0021 EXCLAMATION MARK */ -#define XK_quotedbl 0x0022 /* U+0022 QUOTATION MARK */ -#define XK_numbersign 0x0023 /* U+0023 NUMBER SIGN */ -#define XK_dollar 0x0024 /* U+0024 DOLLAR SIGN */ -#define XK_percent 0x0025 /* U+0025 PERCENT SIGN */ -#define XK_ampersand 0x0026 /* U+0026 AMPERSAND */ -#define XK_apostrophe 0x0027 /* U+0027 APOSTROPHE */ -#define XK_quoteright 0x0027 /* deprecated */ -#define XK_parenleft 0x0028 /* U+0028 LEFT PARENTHESIS */ -#define XK_parenright 0x0029 /* U+0029 RIGHT PARENTHESIS */ -#define XK_asterisk 0x002a /* U+002A ASTERISK */ -#define XK_plus 0x002b /* U+002B PLUS SIGN */ -#define XK_comma 0x002c /* U+002C COMMA */ -#define XK_minus 0x002d /* U+002D HYPHEN-MINUS */ -#define XK_period 0x002e /* U+002E FULL STOP */ -#define XK_slash 0x002f /* U+002F SOLIDUS */ -#define XK_0 0x0030 /* U+0030 DIGIT ZERO */ -#define XK_1 0x0031 /* U+0031 DIGIT ONE */ -#define XK_2 0x0032 /* U+0032 DIGIT TWO */ -#define XK_3 0x0033 /* U+0033 DIGIT THREE */ -#define XK_4 0x0034 /* U+0034 DIGIT FOUR */ -#define XK_5 0x0035 /* U+0035 DIGIT FIVE */ -#define XK_6 0x0036 /* U+0036 DIGIT SIX */ -#define XK_7 0x0037 /* U+0037 DIGIT SEVEN */ -#define XK_8 0x0038 /* U+0038 DIGIT EIGHT */ -#define XK_9 0x0039 /* U+0039 DIGIT NINE */ -#define XK_colon 0x003a /* U+003A COLON */ -#define XK_semicolon 0x003b /* U+003B SEMICOLON */ -#define XK_less 0x003c /* U+003C LESS-THAN SIGN */ -#define XK_equal 0x003d /* U+003D EQUALS SIGN */ -#define XK_greater 0x003e /* U+003E GREATER-THAN SIGN */ -#define XK_question 0x003f /* U+003F QUESTION MARK */ -#define XK_at 0x0040 /* U+0040 COMMERCIAL AT */ -#define XK_A 0x0041 /* U+0041 LATIN CAPITAL LETTER A */ -#define XK_B 0x0042 /* U+0042 LATIN CAPITAL LETTER B */ -#define XK_C 0x0043 /* U+0043 LATIN CAPITAL LETTER C */ -#define XK_D 0x0044 /* U+0044 LATIN CAPITAL LETTER D */ -#define XK_E 0x0045 /* U+0045 LATIN CAPITAL LETTER E */ -#define XK_F 0x0046 /* U+0046 LATIN CAPITAL LETTER F */ -#define XK_G 0x0047 /* U+0047 LATIN CAPITAL LETTER G */ -#define XK_H 0x0048 /* U+0048 LATIN CAPITAL LETTER H */ -#define XK_I 0x0049 /* U+0049 LATIN CAPITAL LETTER I */ -#define XK_J 0x004a /* U+004A LATIN CAPITAL LETTER J */ -#define XK_K 0x004b /* U+004B LATIN CAPITAL LETTER K */ -#define XK_L 0x004c /* U+004C LATIN CAPITAL LETTER L */ -#define XK_M 0x004d /* U+004D LATIN CAPITAL LETTER M */ -#define XK_N 0x004e /* U+004E LATIN CAPITAL LETTER N */ -#define XK_O 0x004f /* U+004F LATIN CAPITAL LETTER O */ -#define XK_P 0x0050 /* U+0050 LATIN CAPITAL LETTER P */ -#define XK_Q 0x0051 /* U+0051 LATIN CAPITAL LETTER Q */ -#define XK_R 0x0052 /* U+0052 LATIN CAPITAL LETTER R */ -#define XK_S 0x0053 /* U+0053 LATIN CAPITAL LETTER S */ -#define XK_T 0x0054 /* U+0054 LATIN CAPITAL LETTER T */ -#define XK_U 0x0055 /* U+0055 LATIN CAPITAL LETTER U */ -#define XK_V 0x0056 /* U+0056 LATIN CAPITAL LETTER V */ -#define XK_W 0x0057 /* U+0057 LATIN CAPITAL LETTER W */ -#define XK_X 0x0058 /* U+0058 LATIN CAPITAL LETTER X */ -#define XK_Y 0x0059 /* U+0059 LATIN CAPITAL LETTER Y */ -#define XK_Z 0x005a /* U+005A LATIN CAPITAL LETTER Z */ -#define XK_bracketleft 0x005b /* U+005B LEFT SQUARE BRACKET */ -#define XK_backslash 0x005c /* U+005C REVERSE SOLIDUS */ -#define XK_bracketright 0x005d /* U+005D RIGHT SQUARE BRACKET */ -#define XK_asciicircum 0x005e /* U+005E CIRCUMFLEX ACCENT */ -#define XK_underscore 0x005f /* U+005F LOW LINE */ -#define XK_grave 0x0060 /* U+0060 GRAVE ACCENT */ -#define XK_quoteleft 0x0060 /* deprecated */ -#define XK_a 0x0061 /* U+0061 LATIN SMALL LETTER A */ -#define XK_b 0x0062 /* U+0062 LATIN SMALL LETTER B */ -#define XK_c 0x0063 /* U+0063 LATIN SMALL LETTER C */ -#define XK_d 0x0064 /* U+0064 LATIN SMALL LETTER D */ -#define XK_e 0x0065 /* U+0065 LATIN SMALL LETTER E */ -#define XK_f 0x0066 /* U+0066 LATIN SMALL LETTER F */ -#define XK_g 0x0067 /* U+0067 LATIN SMALL LETTER G */ -#define XK_h 0x0068 /* U+0068 LATIN SMALL LETTER H */ -#define XK_i 0x0069 /* U+0069 LATIN SMALL LETTER I */ -#define XK_j 0x006a /* U+006A LATIN SMALL LETTER J */ -#define XK_k 0x006b /* U+006B LATIN SMALL LETTER K */ -#define XK_l 0x006c /* U+006C LATIN SMALL LETTER L */ -#define XK_m 0x006d /* U+006D LATIN SMALL LETTER M */ -#define XK_n 0x006e /* U+006E LATIN SMALL LETTER N */ -#define XK_o 0x006f /* U+006F LATIN SMALL LETTER O */ -#define XK_p 0x0070 /* U+0070 LATIN SMALL LETTER P */ -#define XK_q 0x0071 /* U+0071 LATIN SMALL LETTER Q */ -#define XK_r 0x0072 /* U+0072 LATIN SMALL LETTER R */ -#define XK_s 0x0073 /* U+0073 LATIN SMALL LETTER S */ -#define XK_t 0x0074 /* U+0074 LATIN SMALL LETTER T */ -#define XK_u 0x0075 /* U+0075 LATIN SMALL LETTER U */ -#define XK_v 0x0076 /* U+0076 LATIN SMALL LETTER V */ -#define XK_w 0x0077 /* U+0077 LATIN SMALL LETTER W */ -#define XK_x 0x0078 /* U+0078 LATIN SMALL LETTER X */ -#define XK_y 0x0079 /* U+0079 LATIN SMALL LETTER Y */ -#define XK_z 0x007a /* U+007A LATIN SMALL LETTER Z */ -#define XK_braceleft 0x007b /* U+007B LEFT CURLY BRACKET */ -#define XK_bar 0x007c /* U+007C VERTICAL LINE */ -#define XK_braceright 0x007d /* U+007D RIGHT CURLY BRACKET */ -#define XK_asciitilde 0x007e /* U+007E TILDE */ +#define XK_space 0x0020 /* U+0020 SPACE */ +#define XK_exclam 0x0021 /* U+0021 EXCLAMATION MARK */ +#define XK_quotedbl 0x0022 /* U+0022 QUOTATION MARK */ +#define XK_numbersign 0x0023 /* U+0023 NUMBER SIGN */ +#define XK_dollar 0x0024 /* U+0024 DOLLAR SIGN */ +#define XK_percent 0x0025 /* U+0025 PERCENT SIGN */ +#define XK_ampersand 0x0026 /* U+0026 AMPERSAND */ +#define XK_apostrophe 0x0027 /* U+0027 APOSTROPHE */ +#define XK_quoteright 0x0027 /* deprecated */ +#define XK_parenleft 0x0028 /* U+0028 LEFT PARENTHESIS */ +#define XK_parenright 0x0029 /* U+0029 RIGHT PARENTHESIS */ +#define XK_asterisk 0x002a /* U+002A ASTERISK */ +#define XK_plus 0x002b /* U+002B PLUS SIGN */ +#define XK_comma 0x002c /* U+002C COMMA */ +#define XK_minus 0x002d /* U+002D HYPHEN-MINUS */ +#define XK_period 0x002e /* U+002E FULL STOP */ +#define XK_slash 0x002f /* U+002F SOLIDUS */ +#define XK_0 0x0030 /* U+0030 DIGIT ZERO */ +#define XK_1 0x0031 /* U+0031 DIGIT ONE */ +#define XK_2 0x0032 /* U+0032 DIGIT TWO */ +#define XK_3 0x0033 /* U+0033 DIGIT THREE */ +#define XK_4 0x0034 /* U+0034 DIGIT FOUR */ +#define XK_5 0x0035 /* U+0035 DIGIT FIVE */ +#define XK_6 0x0036 /* U+0036 DIGIT SIX */ +#define XK_7 0x0037 /* U+0037 DIGIT SEVEN */ +#define XK_8 0x0038 /* U+0038 DIGIT EIGHT */ +#define XK_9 0x0039 /* U+0039 DIGIT NINE */ +#define XK_colon 0x003a /* U+003A COLON */ +#define XK_semicolon 0x003b /* U+003B SEMICOLON */ +#define XK_less 0x003c /* U+003C LESS-THAN SIGN */ +#define XK_equal 0x003d /* U+003D EQUALS SIGN */ +#define XK_greater 0x003e /* U+003E GREATER-THAN SIGN */ +#define XK_question 0x003f /* U+003F QUESTION MARK */ +#define XK_at 0x0040 /* U+0040 COMMERCIAL AT */ +#define XK_A 0x0041 /* U+0041 LATIN CAPITAL LETTER A */ +#define XK_B 0x0042 /* U+0042 LATIN CAPITAL LETTER B */ +#define XK_C 0x0043 /* U+0043 LATIN CAPITAL LETTER C */ +#define XK_D 0x0044 /* U+0044 LATIN CAPITAL LETTER D */ +#define XK_E 0x0045 /* U+0045 LATIN CAPITAL LETTER E */ +#define XK_F 0x0046 /* U+0046 LATIN CAPITAL LETTER F */ +#define XK_G 0x0047 /* U+0047 LATIN CAPITAL LETTER G */ +#define XK_H 0x0048 /* U+0048 LATIN CAPITAL LETTER H */ +#define XK_I 0x0049 /* U+0049 LATIN CAPITAL LETTER I */ +#define XK_J 0x004a /* U+004A LATIN CAPITAL LETTER J */ +#define XK_K 0x004b /* U+004B LATIN CAPITAL LETTER K */ +#define XK_L 0x004c /* U+004C LATIN CAPITAL LETTER L */ +#define XK_M 0x004d /* U+004D LATIN CAPITAL LETTER M */ +#define XK_N 0x004e /* U+004E LATIN CAPITAL LETTER N */ +#define XK_O 0x004f /* U+004F LATIN CAPITAL LETTER O */ +#define XK_P 0x0050 /* U+0050 LATIN CAPITAL LETTER P */ +#define XK_Q 0x0051 /* U+0051 LATIN CAPITAL LETTER Q */ +#define XK_R 0x0052 /* U+0052 LATIN CAPITAL LETTER R */ +#define XK_S 0x0053 /* U+0053 LATIN CAPITAL LETTER S */ +#define XK_T 0x0054 /* U+0054 LATIN CAPITAL LETTER T */ +#define XK_U 0x0055 /* U+0055 LATIN CAPITAL LETTER U */ +#define XK_V 0x0056 /* U+0056 LATIN CAPITAL LETTER V */ +#define XK_W 0x0057 /* U+0057 LATIN CAPITAL LETTER W */ +#define XK_X 0x0058 /* U+0058 LATIN CAPITAL LETTER X */ +#define XK_Y 0x0059 /* U+0059 LATIN CAPITAL LETTER Y */ +#define XK_Z 0x005a /* U+005A LATIN CAPITAL LETTER Z */ +#define XK_bracketleft 0x005b /* U+005B LEFT SQUARE BRACKET */ +#define XK_backslash 0x005c /* U+005C REVERSE SOLIDUS */ +#define XK_bracketright 0x005d /* U+005D RIGHT SQUARE BRACKET */ +#define XK_asciicircum 0x005e /* U+005E CIRCUMFLEX ACCENT */ +#define XK_underscore 0x005f /* U+005F LOW LINE */ +#define XK_grave 0x0060 /* U+0060 GRAVE ACCENT */ +#define XK_quoteleft 0x0060 /* deprecated */ +#define XK_a 0x0061 /* U+0061 LATIN SMALL LETTER A */ +#define XK_b 0x0062 /* U+0062 LATIN SMALL LETTER B */ +#define XK_c 0x0063 /* U+0063 LATIN SMALL LETTER C */ +#define XK_d 0x0064 /* U+0064 LATIN SMALL LETTER D */ +#define XK_e 0x0065 /* U+0065 LATIN SMALL LETTER E */ +#define XK_f 0x0066 /* U+0066 LATIN SMALL LETTER F */ +#define XK_g 0x0067 /* U+0067 LATIN SMALL LETTER G */ +#define XK_h 0x0068 /* U+0068 LATIN SMALL LETTER H */ +#define XK_i 0x0069 /* U+0069 LATIN SMALL LETTER I */ +#define XK_j 0x006a /* U+006A LATIN SMALL LETTER J */ +#define XK_k 0x006b /* U+006B LATIN SMALL LETTER K */ +#define XK_l 0x006c /* U+006C LATIN SMALL LETTER L */ +#define XK_m 0x006d /* U+006D LATIN SMALL LETTER M */ +#define XK_n 0x006e /* U+006E LATIN SMALL LETTER N */ +#define XK_o 0x006f /* U+006F LATIN SMALL LETTER O */ +#define XK_p 0x0070 /* U+0070 LATIN SMALL LETTER P */ +#define XK_q 0x0071 /* U+0071 LATIN SMALL LETTER Q */ +#define XK_r 0x0072 /* U+0072 LATIN SMALL LETTER R */ +#define XK_s 0x0073 /* U+0073 LATIN SMALL LETTER S */ +#define XK_t 0x0074 /* U+0074 LATIN SMALL LETTER T */ +#define XK_u 0x0075 /* U+0075 LATIN SMALL LETTER U */ +#define XK_v 0x0076 /* U+0076 LATIN SMALL LETTER V */ +#define XK_w 0x0077 /* U+0077 LATIN SMALL LETTER W */ +#define XK_x 0x0078 /* U+0078 LATIN SMALL LETTER X */ +#define XK_y 0x0079 /* U+0079 LATIN SMALL LETTER Y */ +#define XK_z 0x007a /* U+007A LATIN SMALL LETTER Z */ +#define XK_braceleft 0x007b /* U+007B LEFT CURLY BRACKET */ +#define XK_bar 0x007c /* U+007C VERTICAL LINE */ +#define XK_braceright 0x007d /* U+007D RIGHT CURLY BRACKET */ +#define XK_asciitilde 0x007e /* U+007E TILDE */ -#define XK_nobreakspace 0x00a0 /* U+00A0 NO-BREAK SPACE */ -#define XK_exclamdown 0x00a1 /* U+00A1 INVERTED EXCLAMATION MARK */ -#define XK_cent 0x00a2 /* U+00A2 CENT SIGN */ -#define XK_sterling 0x00a3 /* U+00A3 POUND SIGN */ -#define XK_currency 0x00a4 /* U+00A4 CURRENCY SIGN */ -#define XK_yen 0x00a5 /* U+00A5 YEN SIGN */ -#define XK_brokenbar 0x00a6 /* U+00A6 BROKEN BAR */ -#define XK_section 0x00a7 /* U+00A7 SECTION SIGN */ -#define XK_diaeresis 0x00a8 /* U+00A8 DIAERESIS */ -#define XK_copyright 0x00a9 /* U+00A9 COPYRIGHT SIGN */ -#define XK_ordfeminine 0x00aa /* U+00AA FEMININE ORDINAL INDICATOR */ -#define XK_guillemotleft 0x00ab /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ -#define XK_notsign 0x00ac /* U+00AC NOT SIGN */ -#define XK_hyphen 0x00ad /* U+00AD SOFT HYPHEN */ -#define XK_registered 0x00ae /* U+00AE REGISTERED SIGN */ -#define XK_macron 0x00af /* U+00AF MACRON */ -#define XK_degree 0x00b0 /* U+00B0 DEGREE SIGN */ -#define XK_plusminus 0x00b1 /* U+00B1 PLUS-MINUS SIGN */ -#define XK_twosuperior 0x00b2 /* U+00B2 SUPERSCRIPT TWO */ -#define XK_threesuperior 0x00b3 /* U+00B3 SUPERSCRIPT THREE */ -#define XK_acute 0x00b4 /* U+00B4 ACUTE ACCENT */ -#define XK_mu 0x00b5 /* U+00B5 MICRO SIGN */ -#define XK_paragraph 0x00b6 /* U+00B6 PILCROW SIGN */ -#define XK_periodcentered 0x00b7 /* U+00B7 MIDDLE DOT */ -#define XK_cedilla 0x00b8 /* U+00B8 CEDILLA */ -#define XK_onesuperior 0x00b9 /* U+00B9 SUPERSCRIPT ONE */ -#define XK_masculine 0x00ba /* U+00BA MASCULINE ORDINAL INDICATOR */ -#define XK_guillemotright 0x00bb /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ -#define XK_onequarter 0x00bc /* U+00BC VULGAR FRACTION ONE QUARTER */ -#define XK_onehalf 0x00bd /* U+00BD VULGAR FRACTION ONE HALF */ -#define XK_threequarters 0x00be /* U+00BE VULGAR FRACTION THREE QUARTERS */ -#define XK_questiondown 0x00bf /* U+00BF INVERTED QUESTION MARK */ -#define XK_Agrave 0x00c0 /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */ -#define XK_Aacute 0x00c1 /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */ -#define XK_Acircumflex 0x00c2 /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ -#define XK_Atilde 0x00c3 /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */ -#define XK_Adiaeresis 0x00c4 /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */ -#define XK_Aring 0x00c5 /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */ -#define XK_AE 0x00c6 /* U+00C6 LATIN CAPITAL LETTER AE */ -#define XK_Ccedilla 0x00c7 /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */ -#define XK_Egrave 0x00c8 /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */ -#define XK_Eacute 0x00c9 /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */ -#define XK_Ecircumflex 0x00ca /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ -#define XK_Ediaeresis 0x00cb /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */ -#define XK_Igrave 0x00cc /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */ -#define XK_Iacute 0x00cd /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */ -#define XK_Icircumflex 0x00ce /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ -#define XK_Idiaeresis 0x00cf /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */ -#define XK_ETH 0x00d0 /* U+00D0 LATIN CAPITAL LETTER ETH */ -#define XK_Eth 0x00d0 /* deprecated */ -#define XK_Ntilde 0x00d1 /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */ -#define XK_Ograve 0x00d2 /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */ -#define XK_Oacute 0x00d3 /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */ -#define XK_Ocircumflex 0x00d4 /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ -#define XK_Otilde 0x00d5 /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */ -#define XK_Odiaeresis 0x00d6 /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */ -#define XK_multiply 0x00d7 /* U+00D7 MULTIPLICATION SIGN */ -#define XK_Oslash 0x00d8 /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ -#define XK_Ooblique 0x00d8 /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ -#define XK_Ugrave 0x00d9 /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */ -#define XK_Uacute 0x00da /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */ -#define XK_Ucircumflex 0x00db /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ -#define XK_Udiaeresis 0x00dc /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */ -#define XK_Yacute 0x00dd /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */ -#define XK_THORN 0x00de /* U+00DE LATIN CAPITAL LETTER THORN */ -#define XK_Thorn 0x00de /* deprecated */ -#define XK_ssharp 0x00df /* U+00DF LATIN SMALL LETTER SHARP S */ -#define XK_agrave 0x00e0 /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */ -#define XK_aacute 0x00e1 /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */ -#define XK_acircumflex 0x00e2 /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */ -#define XK_atilde 0x00e3 /* U+00E3 LATIN SMALL LETTER A WITH TILDE */ -#define XK_adiaeresis 0x00e4 /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */ -#define XK_aring 0x00e5 /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */ -#define XK_ae 0x00e6 /* U+00E6 LATIN SMALL LETTER AE */ -#define XK_ccedilla 0x00e7 /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */ -#define XK_egrave 0x00e8 /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */ -#define XK_eacute 0x00e9 /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */ -#define XK_ecircumflex 0x00ea /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */ -#define XK_ediaeresis 0x00eb /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */ -#define XK_igrave 0x00ec /* U+00EC LATIN SMALL LETTER I WITH GRAVE */ -#define XK_iacute 0x00ed /* U+00ED LATIN SMALL LETTER I WITH ACUTE */ -#define XK_icircumflex 0x00ee /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */ -#define XK_idiaeresis 0x00ef /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */ -#define XK_eth 0x00f0 /* U+00F0 LATIN SMALL LETTER ETH */ -#define XK_ntilde 0x00f1 /* U+00F1 LATIN SMALL LETTER N WITH TILDE */ -#define XK_ograve 0x00f2 /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */ -#define XK_oacute 0x00f3 /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */ -#define XK_ocircumflex 0x00f4 /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */ -#define XK_otilde 0x00f5 /* U+00F5 LATIN SMALL LETTER O WITH TILDE */ -#define XK_odiaeresis 0x00f6 /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */ -#define XK_division 0x00f7 /* U+00F7 DIVISION SIGN */ -#define XK_oslash 0x00f8 /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ -#define XK_ooblique 0x00f8 /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ -#define XK_ugrave 0x00f9 /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */ -#define XK_uacute 0x00fa /* U+00FA LATIN SMALL LETTER U WITH ACUTE */ -#define XK_ucircumflex 0x00fb /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */ -#define XK_udiaeresis 0x00fc /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */ -#define XK_yacute 0x00fd /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */ -#define XK_thorn 0x00fe /* U+00FE LATIN SMALL LETTER THORN */ -#define XK_ydiaeresis 0x00ff /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */ -#endif /* XK_LATIN1 */ +#define XK_nobreakspace 0x00a0 /* U+00A0 NO-BREAK SPACE */ +#define XK_exclamdown 0x00a1 /* U+00A1 INVERTED EXCLAMATION MARK */ +#define XK_cent 0x00a2 /* U+00A2 CENT SIGN */ +#define XK_sterling 0x00a3 /* U+00A3 POUND SIGN */ +#define XK_currency 0x00a4 /* U+00A4 CURRENCY SIGN */ +#define XK_yen 0x00a5 /* U+00A5 YEN SIGN */ +#define XK_brokenbar 0x00a6 /* U+00A6 BROKEN BAR */ +#define XK_section 0x00a7 /* U+00A7 SECTION SIGN */ +#define XK_diaeresis 0x00a8 /* U+00A8 DIAERESIS */ +#define XK_copyright 0x00a9 /* U+00A9 COPYRIGHT SIGN */ +#define XK_ordfeminine 0x00aa /* U+00AA FEMININE ORDINAL INDICATOR */ +#define XK_guillemotleft 0x00ab /* U+00AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK */ +#define XK_notsign 0x00ac /* U+00AC NOT SIGN */ +#define XK_hyphen 0x00ad /* U+00AD SOFT HYPHEN */ +#define XK_registered 0x00ae /* U+00AE REGISTERED SIGN */ +#define XK_macron 0x00af /* U+00AF MACRON */ +#define XK_degree 0x00b0 /* U+00B0 DEGREE SIGN */ +#define XK_plusminus 0x00b1 /* U+00B1 PLUS-MINUS SIGN */ +#define XK_twosuperior 0x00b2 /* U+00B2 SUPERSCRIPT TWO */ +#define XK_threesuperior 0x00b3 /* U+00B3 SUPERSCRIPT THREE */ +#define XK_acute 0x00b4 /* U+00B4 ACUTE ACCENT */ +#define XK_mu 0x00b5 /* U+00B5 MICRO SIGN */ +#define XK_paragraph 0x00b6 /* U+00B6 PILCROW SIGN */ +#define XK_periodcentered 0x00b7 /* U+00B7 MIDDLE DOT */ +#define XK_cedilla 0x00b8 /* U+00B8 CEDILLA */ +#define XK_onesuperior 0x00b9 /* U+00B9 SUPERSCRIPT ONE */ +#define XK_masculine 0x00ba /* U+00BA MASCULINE ORDINAL INDICATOR */ +#define XK_guillemotright 0x00bb /* U+00BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK */ +#define XK_onequarter 0x00bc /* U+00BC VULGAR FRACTION ONE QUARTER */ +#define XK_onehalf 0x00bd /* U+00BD VULGAR FRACTION ONE HALF */ +#define XK_threequarters 0x00be /* U+00BE VULGAR FRACTION THREE QUARTERS */ +#define XK_questiondown 0x00bf /* U+00BF INVERTED QUESTION MARK */ +#define XK_Agrave 0x00c0 /* U+00C0 LATIN CAPITAL LETTER A WITH GRAVE */ +#define XK_Aacute 0x00c1 /* U+00C1 LATIN CAPITAL LETTER A WITH ACUTE */ +#define XK_Acircumflex 0x00c2 /* U+00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX */ +#define XK_Atilde 0x00c3 /* U+00C3 LATIN CAPITAL LETTER A WITH TILDE */ +#define XK_Adiaeresis 0x00c4 /* U+00C4 LATIN CAPITAL LETTER A WITH DIAERESIS */ +#define XK_Aring 0x00c5 /* U+00C5 LATIN CAPITAL LETTER A WITH RING ABOVE */ +#define XK_AE 0x00c6 /* U+00C6 LATIN CAPITAL LETTER AE */ +#define XK_Ccedilla 0x00c7 /* U+00C7 LATIN CAPITAL LETTER C WITH CEDILLA */ +#define XK_Egrave 0x00c8 /* U+00C8 LATIN CAPITAL LETTER E WITH GRAVE */ +#define XK_Eacute 0x00c9 /* U+00C9 LATIN CAPITAL LETTER E WITH ACUTE */ +#define XK_Ecircumflex 0x00ca /* U+00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX */ +#define XK_Ediaeresis 0x00cb /* U+00CB LATIN CAPITAL LETTER E WITH DIAERESIS */ +#define XK_Igrave 0x00cc /* U+00CC LATIN CAPITAL LETTER I WITH GRAVE */ +#define XK_Iacute 0x00cd /* U+00CD LATIN CAPITAL LETTER I WITH ACUTE */ +#define XK_Icircumflex 0x00ce /* U+00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX */ +#define XK_Idiaeresis 0x00cf /* U+00CF LATIN CAPITAL LETTER I WITH DIAERESIS */ +#define XK_ETH 0x00d0 /* U+00D0 LATIN CAPITAL LETTER ETH */ +#define XK_Eth 0x00d0 /* deprecated */ +#define XK_Ntilde 0x00d1 /* U+00D1 LATIN CAPITAL LETTER N WITH TILDE */ +#define XK_Ograve 0x00d2 /* U+00D2 LATIN CAPITAL LETTER O WITH GRAVE */ +#define XK_Oacute 0x00d3 /* U+00D3 LATIN CAPITAL LETTER O WITH ACUTE */ +#define XK_Ocircumflex 0x00d4 /* U+00D4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX */ +#define XK_Otilde 0x00d5 /* U+00D5 LATIN CAPITAL LETTER O WITH TILDE */ +#define XK_Odiaeresis 0x00d6 /* U+00D6 LATIN CAPITAL LETTER O WITH DIAERESIS */ +#define XK_multiply 0x00d7 /* U+00D7 MULTIPLICATION SIGN */ +#define XK_Oslash 0x00d8 /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ +#define XK_Ooblique 0x00d8 /* U+00D8 LATIN CAPITAL LETTER O WITH STROKE */ +#define XK_Ugrave 0x00d9 /* U+00D9 LATIN CAPITAL LETTER U WITH GRAVE */ +#define XK_Uacute 0x00da /* U+00DA LATIN CAPITAL LETTER U WITH ACUTE */ +#define XK_Ucircumflex 0x00db /* U+00DB LATIN CAPITAL LETTER U WITH CIRCUMFLEX */ +#define XK_Udiaeresis 0x00dc /* U+00DC LATIN CAPITAL LETTER U WITH DIAERESIS */ +#define XK_Yacute 0x00dd /* U+00DD LATIN CAPITAL LETTER Y WITH ACUTE */ +#define XK_THORN 0x00de /* U+00DE LATIN CAPITAL LETTER THORN */ +#define XK_Thorn 0x00de /* deprecated */ +#define XK_ssharp 0x00df /* U+00DF LATIN SMALL LETTER SHARP S */ +#define XK_agrave 0x00e0 /* U+00E0 LATIN SMALL LETTER A WITH GRAVE */ +#define XK_aacute 0x00e1 /* U+00E1 LATIN SMALL LETTER A WITH ACUTE */ +#define XK_acircumflex 0x00e2 /* U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX */ +#define XK_atilde 0x00e3 /* U+00E3 LATIN SMALL LETTER A WITH TILDE */ +#define XK_adiaeresis 0x00e4 /* U+00E4 LATIN SMALL LETTER A WITH DIAERESIS */ +#define XK_aring 0x00e5 /* U+00E5 LATIN SMALL LETTER A WITH RING ABOVE */ +#define XK_ae 0x00e6 /* U+00E6 LATIN SMALL LETTER AE */ +#define XK_ccedilla 0x00e7 /* U+00E7 LATIN SMALL LETTER C WITH CEDILLA */ +#define XK_egrave 0x00e8 /* U+00E8 LATIN SMALL LETTER E WITH GRAVE */ +#define XK_eacute 0x00e9 /* U+00E9 LATIN SMALL LETTER E WITH ACUTE */ +#define XK_ecircumflex 0x00ea /* U+00EA LATIN SMALL LETTER E WITH CIRCUMFLEX */ +#define XK_ediaeresis 0x00eb /* U+00EB LATIN SMALL LETTER E WITH DIAERESIS */ +#define XK_igrave 0x00ec /* U+00EC LATIN SMALL LETTER I WITH GRAVE */ +#define XK_iacute 0x00ed /* U+00ED LATIN SMALL LETTER I WITH ACUTE */ +#define XK_icircumflex 0x00ee /* U+00EE LATIN SMALL LETTER I WITH CIRCUMFLEX */ +#define XK_idiaeresis 0x00ef /* U+00EF LATIN SMALL LETTER I WITH DIAERESIS */ +#define XK_eth 0x00f0 /* U+00F0 LATIN SMALL LETTER ETH */ +#define XK_ntilde 0x00f1 /* U+00F1 LATIN SMALL LETTER N WITH TILDE */ +#define XK_ograve 0x00f2 /* U+00F2 LATIN SMALL LETTER O WITH GRAVE */ +#define XK_oacute 0x00f3 /* U+00F3 LATIN SMALL LETTER O WITH ACUTE */ +#define XK_ocircumflex 0x00f4 /* U+00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX */ +#define XK_otilde 0x00f5 /* U+00F5 LATIN SMALL LETTER O WITH TILDE */ +#define XK_odiaeresis 0x00f6 /* U+00F6 LATIN SMALL LETTER O WITH DIAERESIS */ +#define XK_division 0x00f7 /* U+00F7 DIVISION SIGN */ +#define XK_oslash 0x00f8 /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ +#define XK_ooblique 0x00f8 /* U+00F8 LATIN SMALL LETTER O WITH STROKE */ +#define XK_ugrave 0x00f9 /* U+00F9 LATIN SMALL LETTER U WITH GRAVE */ +#define XK_uacute 0x00fa /* U+00FA LATIN SMALL LETTER U WITH ACUTE */ +#define XK_ucircumflex 0x00fb /* U+00FB LATIN SMALL LETTER U WITH CIRCUMFLEX */ +#define XK_udiaeresis 0x00fc /* U+00FC LATIN SMALL LETTER U WITH DIAERESIS */ +#define XK_yacute 0x00fd /* U+00FD LATIN SMALL LETTER Y WITH ACUTE */ +#define XK_thorn 0x00fe /* U+00FE LATIN SMALL LETTER THORN */ +#define XK_ydiaeresis 0x00ff /* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */ +#endif /* XK_LATIN1 */ /* * Latin 2 @@ -741,64 +736,64 @@ SOFTWARE. */ #ifdef XK_LATIN2 -#define XK_Aogonek 0x01a1 /* U+0104 LATIN CAPITAL LETTER A WITH OGONEK */ -#define XK_breve 0x01a2 /* U+02D8 BREVE */ -#define XK_Lstroke 0x01a3 /* U+0141 LATIN CAPITAL LETTER L WITH STROKE */ -#define XK_Lcaron 0x01a5 /* U+013D LATIN CAPITAL LETTER L WITH CARON */ -#define XK_Sacute 0x01a6 /* U+015A LATIN CAPITAL LETTER S WITH ACUTE */ -#define XK_Scaron 0x01a9 /* U+0160 LATIN CAPITAL LETTER S WITH CARON */ -#define XK_Scedilla 0x01aa /* U+015E LATIN CAPITAL LETTER S WITH CEDILLA */ -#define XK_Tcaron 0x01ab /* U+0164 LATIN CAPITAL LETTER T WITH CARON */ -#define XK_Zacute 0x01ac /* U+0179 LATIN CAPITAL LETTER Z WITH ACUTE */ -#define XK_Zcaron 0x01ae /* U+017D LATIN CAPITAL LETTER Z WITH CARON */ -#define XK_Zabovedot 0x01af /* U+017B LATIN CAPITAL LETTER Z WITH DOT ABOVE */ -#define XK_aogonek 0x01b1 /* U+0105 LATIN SMALL LETTER A WITH OGONEK */ -#define XK_ogonek 0x01b2 /* U+02DB OGONEK */ -#define XK_lstroke 0x01b3 /* U+0142 LATIN SMALL LETTER L WITH STROKE */ -#define XK_lcaron 0x01b5 /* U+013E LATIN SMALL LETTER L WITH CARON */ -#define XK_sacute 0x01b6 /* U+015B LATIN SMALL LETTER S WITH ACUTE */ -#define XK_caron 0x01b7 /* U+02C7 CARON */ -#define XK_scaron 0x01b9 /* U+0161 LATIN SMALL LETTER S WITH CARON */ -#define XK_scedilla 0x01ba /* U+015F LATIN SMALL LETTER S WITH CEDILLA */ -#define XK_tcaron 0x01bb /* U+0165 LATIN SMALL LETTER T WITH CARON */ -#define XK_zacute 0x01bc /* U+017A LATIN SMALL LETTER Z WITH ACUTE */ -#define XK_doubleacute 0x01bd /* U+02DD DOUBLE ACUTE ACCENT */ -#define XK_zcaron 0x01be /* U+017E LATIN SMALL LETTER Z WITH CARON */ -#define XK_zabovedot 0x01bf /* U+017C LATIN SMALL LETTER Z WITH DOT ABOVE */ -#define XK_Racute 0x01c0 /* U+0154 LATIN CAPITAL LETTER R WITH ACUTE */ -#define XK_Abreve 0x01c3 /* U+0102 LATIN CAPITAL LETTER A WITH BREVE */ -#define XK_Lacute 0x01c5 /* U+0139 LATIN CAPITAL LETTER L WITH ACUTE */ -#define XK_Cacute 0x01c6 /* U+0106 LATIN CAPITAL LETTER C WITH ACUTE */ -#define XK_Ccaron 0x01c8 /* U+010C LATIN CAPITAL LETTER C WITH CARON */ -#define XK_Eogonek 0x01ca /* U+0118 LATIN CAPITAL LETTER E WITH OGONEK */ -#define XK_Ecaron 0x01cc /* U+011A LATIN CAPITAL LETTER E WITH CARON */ -#define XK_Dcaron 0x01cf /* U+010E LATIN CAPITAL LETTER D WITH CARON */ -#define XK_Dstroke 0x01d0 /* U+0110 LATIN CAPITAL LETTER D WITH STROKE */ -#define XK_Nacute 0x01d1 /* U+0143 LATIN CAPITAL LETTER N WITH ACUTE */ -#define XK_Ncaron 0x01d2 /* U+0147 LATIN CAPITAL LETTER N WITH CARON */ -#define XK_Odoubleacute 0x01d5 /* U+0150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ -#define XK_Rcaron 0x01d8 /* U+0158 LATIN CAPITAL LETTER R WITH CARON */ -#define XK_Uring 0x01d9 /* U+016E LATIN CAPITAL LETTER U WITH RING ABOVE */ -#define XK_Udoubleacute 0x01db /* U+0170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ -#define XK_Tcedilla 0x01de /* U+0162 LATIN CAPITAL LETTER T WITH CEDILLA */ -#define XK_racute 0x01e0 /* U+0155 LATIN SMALL LETTER R WITH ACUTE */ -#define XK_abreve 0x01e3 /* U+0103 LATIN SMALL LETTER A WITH BREVE */ -#define XK_lacute 0x01e5 /* U+013A LATIN SMALL LETTER L WITH ACUTE */ -#define XK_cacute 0x01e6 /* U+0107 LATIN SMALL LETTER C WITH ACUTE */ -#define XK_ccaron 0x01e8 /* U+010D LATIN SMALL LETTER C WITH CARON */ -#define XK_eogonek 0x01ea /* U+0119 LATIN SMALL LETTER E WITH OGONEK */ -#define XK_ecaron 0x01ec /* U+011B LATIN SMALL LETTER E WITH CARON */ -#define XK_dcaron 0x01ef /* U+010F LATIN SMALL LETTER D WITH CARON */ -#define XK_dstroke 0x01f0 /* U+0111 LATIN SMALL LETTER D WITH STROKE */ -#define XK_nacute 0x01f1 /* U+0144 LATIN SMALL LETTER N WITH ACUTE */ -#define XK_ncaron 0x01f2 /* U+0148 LATIN SMALL LETTER N WITH CARON */ -#define XK_odoubleacute 0x01f5 /* U+0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE */ -#define XK_rcaron 0x01f8 /* U+0159 LATIN SMALL LETTER R WITH CARON */ -#define XK_uring 0x01f9 /* U+016F LATIN SMALL LETTER U WITH RING ABOVE */ -#define XK_udoubleacute 0x01fb /* U+0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE */ -#define XK_tcedilla 0x01fe /* U+0163 LATIN SMALL LETTER T WITH CEDILLA */ -#define XK_abovedot 0x01ff /* U+02D9 DOT ABOVE */ -#endif /* XK_LATIN2 */ +#define XK_Aogonek 0x01a1 /* U+0104 LATIN CAPITAL LETTER A WITH OGONEK */ +#define XK_breve 0x01a2 /* U+02D8 BREVE */ +#define XK_Lstroke 0x01a3 /* U+0141 LATIN CAPITAL LETTER L WITH STROKE */ +#define XK_Lcaron 0x01a5 /* U+013D LATIN CAPITAL LETTER L WITH CARON */ +#define XK_Sacute 0x01a6 /* U+015A LATIN CAPITAL LETTER S WITH ACUTE */ +#define XK_Scaron 0x01a9 /* U+0160 LATIN CAPITAL LETTER S WITH CARON */ +#define XK_Scedilla 0x01aa /* U+015E LATIN CAPITAL LETTER S WITH CEDILLA */ +#define XK_Tcaron 0x01ab /* U+0164 LATIN CAPITAL LETTER T WITH CARON */ +#define XK_Zacute 0x01ac /* U+0179 LATIN CAPITAL LETTER Z WITH ACUTE */ +#define XK_Zcaron 0x01ae /* U+017D LATIN CAPITAL LETTER Z WITH CARON */ +#define XK_Zabovedot 0x01af /* U+017B LATIN CAPITAL LETTER Z WITH DOT ABOVE */ +#define XK_aogonek 0x01b1 /* U+0105 LATIN SMALL LETTER A WITH OGONEK */ +#define XK_ogonek 0x01b2 /* U+02DB OGONEK */ +#define XK_lstroke 0x01b3 /* U+0142 LATIN SMALL LETTER L WITH STROKE */ +#define XK_lcaron 0x01b5 /* U+013E LATIN SMALL LETTER L WITH CARON */ +#define XK_sacute 0x01b6 /* U+015B LATIN SMALL LETTER S WITH ACUTE */ +#define XK_caron 0x01b7 /* U+02C7 CARON */ +#define XK_scaron 0x01b9 /* U+0161 LATIN SMALL LETTER S WITH CARON */ +#define XK_scedilla 0x01ba /* U+015F LATIN SMALL LETTER S WITH CEDILLA */ +#define XK_tcaron 0x01bb /* U+0165 LATIN SMALL LETTER T WITH CARON */ +#define XK_zacute 0x01bc /* U+017A LATIN SMALL LETTER Z WITH ACUTE */ +#define XK_doubleacute 0x01bd /* U+02DD DOUBLE ACUTE ACCENT */ +#define XK_zcaron 0x01be /* U+017E LATIN SMALL LETTER Z WITH CARON */ +#define XK_zabovedot 0x01bf /* U+017C LATIN SMALL LETTER Z WITH DOT ABOVE */ +#define XK_Racute 0x01c0 /* U+0154 LATIN CAPITAL LETTER R WITH ACUTE */ +#define XK_Abreve 0x01c3 /* U+0102 LATIN CAPITAL LETTER A WITH BREVE */ +#define XK_Lacute 0x01c5 /* U+0139 LATIN CAPITAL LETTER L WITH ACUTE */ +#define XK_Cacute 0x01c6 /* U+0106 LATIN CAPITAL LETTER C WITH ACUTE */ +#define XK_Ccaron 0x01c8 /* U+010C LATIN CAPITAL LETTER C WITH CARON */ +#define XK_Eogonek 0x01ca /* U+0118 LATIN CAPITAL LETTER E WITH OGONEK */ +#define XK_Ecaron 0x01cc /* U+011A LATIN CAPITAL LETTER E WITH CARON */ +#define XK_Dcaron 0x01cf /* U+010E LATIN CAPITAL LETTER D WITH CARON */ +#define XK_Dstroke 0x01d0 /* U+0110 LATIN CAPITAL LETTER D WITH STROKE */ +#define XK_Nacute 0x01d1 /* U+0143 LATIN CAPITAL LETTER N WITH ACUTE */ +#define XK_Ncaron 0x01d2 /* U+0147 LATIN CAPITAL LETTER N WITH CARON */ +#define XK_Odoubleacute 0x01d5 /* U+0150 LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ +#define XK_Rcaron 0x01d8 /* U+0158 LATIN CAPITAL LETTER R WITH CARON */ +#define XK_Uring 0x01d9 /* U+016E LATIN CAPITAL LETTER U WITH RING ABOVE */ +#define XK_Udoubleacute 0x01db /* U+0170 LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ +#define XK_Tcedilla 0x01de /* U+0162 LATIN CAPITAL LETTER T WITH CEDILLA */ +#define XK_racute 0x01e0 /* U+0155 LATIN SMALL LETTER R WITH ACUTE */ +#define XK_abreve 0x01e3 /* U+0103 LATIN SMALL LETTER A WITH BREVE */ +#define XK_lacute 0x01e5 /* U+013A LATIN SMALL LETTER L WITH ACUTE */ +#define XK_cacute 0x01e6 /* U+0107 LATIN SMALL LETTER C WITH ACUTE */ +#define XK_ccaron 0x01e8 /* U+010D LATIN SMALL LETTER C WITH CARON */ +#define XK_eogonek 0x01ea /* U+0119 LATIN SMALL LETTER E WITH OGONEK */ +#define XK_ecaron 0x01ec /* U+011B LATIN SMALL LETTER E WITH CARON */ +#define XK_dcaron 0x01ef /* U+010F LATIN SMALL LETTER D WITH CARON */ +#define XK_dstroke 0x01f0 /* U+0111 LATIN SMALL LETTER D WITH STROKE */ +#define XK_nacute 0x01f1 /* U+0144 LATIN SMALL LETTER N WITH ACUTE */ +#define XK_ncaron 0x01f2 /* U+0148 LATIN SMALL LETTER N WITH CARON */ +#define XK_odoubleacute 0x01f5 /* U+0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE */ +#define XK_rcaron 0x01f8 /* U+0159 LATIN SMALL LETTER R WITH CARON */ +#define XK_uring 0x01f9 /* U+016F LATIN SMALL LETTER U WITH RING ABOVE */ +#define XK_udoubleacute 0x01fb /* U+0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE */ +#define XK_tcedilla 0x01fe /* U+0163 LATIN SMALL LETTER T WITH CEDILLA */ +#define XK_abovedot 0x01ff /* U+02D9 DOT ABOVE */ +#endif /* XK_LATIN2 */ /* * Latin 3 @@ -806,30 +801,29 @@ SOFTWARE. */ #ifdef XK_LATIN3 -#define XK_Hstroke 0x02a1 /* U+0126 LATIN CAPITAL LETTER H WITH STROKE */ -#define XK_Hcircumflex 0x02a6 /* U+0124 LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ -#define XK_Iabovedot 0x02a9 /* U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE */ -#define XK_Gbreve 0x02ab /* U+011E LATIN CAPITAL LETTER G WITH BREVE */ -#define XK_Jcircumflex 0x02ac /* U+0134 LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ -#define XK_hstroke 0x02b1 /* U+0127 LATIN SMALL LETTER H WITH STROKE */ -#define XK_hcircumflex 0x02b6 /* U+0125 LATIN SMALL LETTER H WITH CIRCUMFLEX */ -#define XK_idotless 0x02b9 /* U+0131 LATIN SMALL LETTER DOTLESS I */ -#define XK_gbreve 0x02bb /* U+011F LATIN SMALL LETTER G WITH BREVE */ -#define XK_jcircumflex 0x02bc /* U+0135 LATIN SMALL LETTER J WITH CIRCUMFLEX */ -#define XK_Cabovedot 0x02c5 /* U+010A LATIN CAPITAL LETTER C WITH DOT ABOVE */ -#define XK_Ccircumflex 0x02c6 /* U+0108 LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ -#define XK_Gabovedot 0x02d5 /* U+0120 LATIN CAPITAL LETTER G WITH DOT ABOVE */ -#define XK_Gcircumflex 0x02d8 /* U+011C LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ -#define XK_Ubreve 0x02dd /* U+016C LATIN CAPITAL LETTER U WITH BREVE */ -#define XK_Scircumflex 0x02de /* U+015C LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ -#define XK_cabovedot 0x02e5 /* U+010B LATIN SMALL LETTER C WITH DOT ABOVE */ -#define XK_ccircumflex 0x02e6 /* U+0109 LATIN SMALL LETTER C WITH CIRCUMFLEX */ -#define XK_gabovedot 0x02f5 /* U+0121 LATIN SMALL LETTER G WITH DOT ABOVE */ -#define XK_gcircumflex 0x02f8 /* U+011D LATIN SMALL LETTER G WITH CIRCUMFLEX */ -#define XK_ubreve 0x02fd /* U+016D LATIN SMALL LETTER U WITH BREVE */ -#define XK_scircumflex 0x02fe /* U+015D LATIN SMALL LETTER S WITH CIRCUMFLEX */ -#endif /* XK_LATIN3 */ - +#define XK_Hstroke 0x02a1 /* U+0126 LATIN CAPITAL LETTER H WITH STROKE */ +#define XK_Hcircumflex 0x02a6 /* U+0124 LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ +#define XK_Iabovedot 0x02a9 /* U+0130 LATIN CAPITAL LETTER I WITH DOT ABOVE */ +#define XK_Gbreve 0x02ab /* U+011E LATIN CAPITAL LETTER G WITH BREVE */ +#define XK_Jcircumflex 0x02ac /* U+0134 LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ +#define XK_hstroke 0x02b1 /* U+0127 LATIN SMALL LETTER H WITH STROKE */ +#define XK_hcircumflex 0x02b6 /* U+0125 LATIN SMALL LETTER H WITH CIRCUMFLEX */ +#define XK_idotless 0x02b9 /* U+0131 LATIN SMALL LETTER DOTLESS I */ +#define XK_gbreve 0x02bb /* U+011F LATIN SMALL LETTER G WITH BREVE */ +#define XK_jcircumflex 0x02bc /* U+0135 LATIN SMALL LETTER J WITH CIRCUMFLEX */ +#define XK_Cabovedot 0x02c5 /* U+010A LATIN CAPITAL LETTER C WITH DOT ABOVE */ +#define XK_Ccircumflex 0x02c6 /* U+0108 LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ +#define XK_Gabovedot 0x02d5 /* U+0120 LATIN CAPITAL LETTER G WITH DOT ABOVE */ +#define XK_Gcircumflex 0x02d8 /* U+011C LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ +#define XK_Ubreve 0x02dd /* U+016C LATIN CAPITAL LETTER U WITH BREVE */ +#define XK_Scircumflex 0x02de /* U+015C LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ +#define XK_cabovedot 0x02e5 /* U+010B LATIN SMALL LETTER C WITH DOT ABOVE */ +#define XK_ccircumflex 0x02e6 /* U+0109 LATIN SMALL LETTER C WITH CIRCUMFLEX */ +#define XK_gabovedot 0x02f5 /* U+0121 LATIN SMALL LETTER G WITH DOT ABOVE */ +#define XK_gcircumflex 0x02f8 /* U+011D LATIN SMALL LETTER G WITH CIRCUMFLEX */ +#define XK_ubreve 0x02fd /* U+016D LATIN SMALL LETTER U WITH BREVE */ +#define XK_scircumflex 0x02fe /* U+015D LATIN SMALL LETTER S WITH CIRCUMFLEX */ +#endif /* XK_LATIN3 */ /* * Latin 4 @@ -837,75 +831,75 @@ SOFTWARE. */ #ifdef XK_LATIN4 -#define XK_kra 0x03a2 /* U+0138 LATIN SMALL LETTER KRA */ -#define XK_kappa 0x03a2 /* deprecated */ -#define XK_Rcedilla 0x03a3 /* U+0156 LATIN CAPITAL LETTER R WITH CEDILLA */ -#define XK_Itilde 0x03a5 /* U+0128 LATIN CAPITAL LETTER I WITH TILDE */ -#define XK_Lcedilla 0x03a6 /* U+013B LATIN CAPITAL LETTER L WITH CEDILLA */ -#define XK_Emacron 0x03aa /* U+0112 LATIN CAPITAL LETTER E WITH MACRON */ -#define XK_Gcedilla 0x03ab /* U+0122 LATIN CAPITAL LETTER G WITH CEDILLA */ -#define XK_Tslash 0x03ac /* U+0166 LATIN CAPITAL LETTER T WITH STROKE */ -#define XK_rcedilla 0x03b3 /* U+0157 LATIN SMALL LETTER R WITH CEDILLA */ -#define XK_itilde 0x03b5 /* U+0129 LATIN SMALL LETTER I WITH TILDE */ -#define XK_lcedilla 0x03b6 /* U+013C LATIN SMALL LETTER L WITH CEDILLA */ -#define XK_emacron 0x03ba /* U+0113 LATIN SMALL LETTER E WITH MACRON */ -#define XK_gcedilla 0x03bb /* U+0123 LATIN SMALL LETTER G WITH CEDILLA */ -#define XK_tslash 0x03bc /* U+0167 LATIN SMALL LETTER T WITH STROKE */ -#define XK_ENG 0x03bd /* U+014A LATIN CAPITAL LETTER ENG */ -#define XK_eng 0x03bf /* U+014B LATIN SMALL LETTER ENG */ -#define XK_Amacron 0x03c0 /* U+0100 LATIN CAPITAL LETTER A WITH MACRON */ -#define XK_Iogonek 0x03c7 /* U+012E LATIN CAPITAL LETTER I WITH OGONEK */ -#define XK_Eabovedot 0x03cc /* U+0116 LATIN CAPITAL LETTER E WITH DOT ABOVE */ -#define XK_Imacron 0x03cf /* U+012A LATIN CAPITAL LETTER I WITH MACRON */ -#define XK_Ncedilla 0x03d1 /* U+0145 LATIN CAPITAL LETTER N WITH CEDILLA */ -#define XK_Omacron 0x03d2 /* U+014C LATIN CAPITAL LETTER O WITH MACRON */ -#define XK_Kcedilla 0x03d3 /* U+0136 LATIN CAPITAL LETTER K WITH CEDILLA */ -#define XK_Uogonek 0x03d9 /* U+0172 LATIN CAPITAL LETTER U WITH OGONEK */ -#define XK_Utilde 0x03dd /* U+0168 LATIN CAPITAL LETTER U WITH TILDE */ -#define XK_Umacron 0x03de /* U+016A LATIN CAPITAL LETTER U WITH MACRON */ -#define XK_amacron 0x03e0 /* U+0101 LATIN SMALL LETTER A WITH MACRON */ -#define XK_iogonek 0x03e7 /* U+012F LATIN SMALL LETTER I WITH OGONEK */ -#define XK_eabovedot 0x03ec /* U+0117 LATIN SMALL LETTER E WITH DOT ABOVE */ -#define XK_imacron 0x03ef /* U+012B LATIN SMALL LETTER I WITH MACRON */ -#define XK_ncedilla 0x03f1 /* U+0146 LATIN SMALL LETTER N WITH CEDILLA */ -#define XK_omacron 0x03f2 /* U+014D LATIN SMALL LETTER O WITH MACRON */ -#define XK_kcedilla 0x03f3 /* U+0137 LATIN SMALL LETTER K WITH CEDILLA */ -#define XK_uogonek 0x03f9 /* U+0173 LATIN SMALL LETTER U WITH OGONEK */ -#define XK_utilde 0x03fd /* U+0169 LATIN SMALL LETTER U WITH TILDE */ -#define XK_umacron 0x03fe /* U+016B LATIN SMALL LETTER U WITH MACRON */ -#endif /* XK_LATIN4 */ +#define XK_kra 0x03a2 /* U+0138 LATIN SMALL LETTER KRA */ +#define XK_kappa 0x03a2 /* deprecated */ +#define XK_Rcedilla 0x03a3 /* U+0156 LATIN CAPITAL LETTER R WITH CEDILLA */ +#define XK_Itilde 0x03a5 /* U+0128 LATIN CAPITAL LETTER I WITH TILDE */ +#define XK_Lcedilla 0x03a6 /* U+013B LATIN CAPITAL LETTER L WITH CEDILLA */ +#define XK_Emacron 0x03aa /* U+0112 LATIN CAPITAL LETTER E WITH MACRON */ +#define XK_Gcedilla 0x03ab /* U+0122 LATIN CAPITAL LETTER G WITH CEDILLA */ +#define XK_Tslash 0x03ac /* U+0166 LATIN CAPITAL LETTER T WITH STROKE */ +#define XK_rcedilla 0x03b3 /* U+0157 LATIN SMALL LETTER R WITH CEDILLA */ +#define XK_itilde 0x03b5 /* U+0129 LATIN SMALL LETTER I WITH TILDE */ +#define XK_lcedilla 0x03b6 /* U+013C LATIN SMALL LETTER L WITH CEDILLA */ +#define XK_emacron 0x03ba /* U+0113 LATIN SMALL LETTER E WITH MACRON */ +#define XK_gcedilla 0x03bb /* U+0123 LATIN SMALL LETTER G WITH CEDILLA */ +#define XK_tslash 0x03bc /* U+0167 LATIN SMALL LETTER T WITH STROKE */ +#define XK_ENG 0x03bd /* U+014A LATIN CAPITAL LETTER ENG */ +#define XK_eng 0x03bf /* U+014B LATIN SMALL LETTER ENG */ +#define XK_Amacron 0x03c0 /* U+0100 LATIN CAPITAL LETTER A WITH MACRON */ +#define XK_Iogonek 0x03c7 /* U+012E LATIN CAPITAL LETTER I WITH OGONEK */ +#define XK_Eabovedot 0x03cc /* U+0116 LATIN CAPITAL LETTER E WITH DOT ABOVE */ +#define XK_Imacron 0x03cf /* U+012A LATIN CAPITAL LETTER I WITH MACRON */ +#define XK_Ncedilla 0x03d1 /* U+0145 LATIN CAPITAL LETTER N WITH CEDILLA */ +#define XK_Omacron 0x03d2 /* U+014C LATIN CAPITAL LETTER O WITH MACRON */ +#define XK_Kcedilla 0x03d3 /* U+0136 LATIN CAPITAL LETTER K WITH CEDILLA */ +#define XK_Uogonek 0x03d9 /* U+0172 LATIN CAPITAL LETTER U WITH OGONEK */ +#define XK_Utilde 0x03dd /* U+0168 LATIN CAPITAL LETTER U WITH TILDE */ +#define XK_Umacron 0x03de /* U+016A LATIN CAPITAL LETTER U WITH MACRON */ +#define XK_amacron 0x03e0 /* U+0101 LATIN SMALL LETTER A WITH MACRON */ +#define XK_iogonek 0x03e7 /* U+012F LATIN SMALL LETTER I WITH OGONEK */ +#define XK_eabovedot 0x03ec /* U+0117 LATIN SMALL LETTER E WITH DOT ABOVE */ +#define XK_imacron 0x03ef /* U+012B LATIN SMALL LETTER I WITH MACRON */ +#define XK_ncedilla 0x03f1 /* U+0146 LATIN SMALL LETTER N WITH CEDILLA */ +#define XK_omacron 0x03f2 /* U+014D LATIN SMALL LETTER O WITH MACRON */ +#define XK_kcedilla 0x03f3 /* U+0137 LATIN SMALL LETTER K WITH CEDILLA */ +#define XK_uogonek 0x03f9 /* U+0173 LATIN SMALL LETTER U WITH OGONEK */ +#define XK_utilde 0x03fd /* U+0169 LATIN SMALL LETTER U WITH TILDE */ +#define XK_umacron 0x03fe /* U+016B LATIN SMALL LETTER U WITH MACRON */ +#endif /* XK_LATIN4 */ /* * Latin 8 */ #ifdef XK_LATIN8 -#define XK_Wcircumflex 0x1000174 /* U+0174 LATIN CAPITAL LETTER W WITH CIRCUMFLEX */ -#define XK_wcircumflex 0x1000175 /* U+0175 LATIN SMALL LETTER W WITH CIRCUMFLEX */ -#define XK_Ycircumflex 0x1000176 /* U+0176 LATIN CAPITAL LETTER Y WITH CIRCUMFLEX */ -#define XK_ycircumflex 0x1000177 /* U+0177 LATIN SMALL LETTER Y WITH CIRCUMFLEX */ -#define XK_Babovedot 0x1001e02 /* U+1E02 LATIN CAPITAL LETTER B WITH DOT ABOVE */ -#define XK_babovedot 0x1001e03 /* U+1E03 LATIN SMALL LETTER B WITH DOT ABOVE */ -#define XK_Dabovedot 0x1001e0a /* U+1E0A LATIN CAPITAL LETTER D WITH DOT ABOVE */ -#define XK_dabovedot 0x1001e0b /* U+1E0B LATIN SMALL LETTER D WITH DOT ABOVE */ -#define XK_Fabovedot 0x1001e1e /* U+1E1E LATIN CAPITAL LETTER F WITH DOT ABOVE */ -#define XK_fabovedot 0x1001e1f /* U+1E1F LATIN SMALL LETTER F WITH DOT ABOVE */ -#define XK_Mabovedot 0x1001e40 /* U+1E40 LATIN CAPITAL LETTER M WITH DOT ABOVE */ -#define XK_mabovedot 0x1001e41 /* U+1E41 LATIN SMALL LETTER M WITH DOT ABOVE */ -#define XK_Pabovedot 0x1001e56 /* U+1E56 LATIN CAPITAL LETTER P WITH DOT ABOVE */ -#define XK_pabovedot 0x1001e57 /* U+1E57 LATIN SMALL LETTER P WITH DOT ABOVE */ -#define XK_Sabovedot 0x1001e60 /* U+1E60 LATIN CAPITAL LETTER S WITH DOT ABOVE */ -#define XK_sabovedot 0x1001e61 /* U+1E61 LATIN SMALL LETTER S WITH DOT ABOVE */ -#define XK_Tabovedot 0x1001e6a /* U+1E6A LATIN CAPITAL LETTER T WITH DOT ABOVE */ -#define XK_tabovedot 0x1001e6b /* U+1E6B LATIN SMALL LETTER T WITH DOT ABOVE */ -#define XK_Wgrave 0x1001e80 /* U+1E80 LATIN CAPITAL LETTER W WITH GRAVE */ -#define XK_wgrave 0x1001e81 /* U+1E81 LATIN SMALL LETTER W WITH GRAVE */ -#define XK_Wacute 0x1001e82 /* U+1E82 LATIN CAPITAL LETTER W WITH ACUTE */ -#define XK_wacute 0x1001e83 /* U+1E83 LATIN SMALL LETTER W WITH ACUTE */ -#define XK_Wdiaeresis 0x1001e84 /* U+1E84 LATIN CAPITAL LETTER W WITH DIAERESIS */ -#define XK_wdiaeresis 0x1001e85 /* U+1E85 LATIN SMALL LETTER W WITH DIAERESIS */ -#define XK_Ygrave 0x1001ef2 /* U+1EF2 LATIN CAPITAL LETTER Y WITH GRAVE */ -#define XK_ygrave 0x1001ef3 /* U+1EF3 LATIN SMALL LETTER Y WITH GRAVE */ -#endif /* XK_LATIN8 */ +#define XK_Wcircumflex 0x1000174 /* U+0174 LATIN CAPITAL LETTER W WITH CIRCUMFLEX */ +#define XK_wcircumflex 0x1000175 /* U+0175 LATIN SMALL LETTER W WITH CIRCUMFLEX */ +#define XK_Ycircumflex 0x1000176 /* U+0176 LATIN CAPITAL LETTER Y WITH CIRCUMFLEX */ +#define XK_ycircumflex 0x1000177 /* U+0177 LATIN SMALL LETTER Y WITH CIRCUMFLEX */ +#define XK_Babovedot 0x1001e02 /* U+1E02 LATIN CAPITAL LETTER B WITH DOT ABOVE */ +#define XK_babovedot 0x1001e03 /* U+1E03 LATIN SMALL LETTER B WITH DOT ABOVE */ +#define XK_Dabovedot 0x1001e0a /* U+1E0A LATIN CAPITAL LETTER D WITH DOT ABOVE */ +#define XK_dabovedot 0x1001e0b /* U+1E0B LATIN SMALL LETTER D WITH DOT ABOVE */ +#define XK_Fabovedot 0x1001e1e /* U+1E1E LATIN CAPITAL LETTER F WITH DOT ABOVE */ +#define XK_fabovedot 0x1001e1f /* U+1E1F LATIN SMALL LETTER F WITH DOT ABOVE */ +#define XK_Mabovedot 0x1001e40 /* U+1E40 LATIN CAPITAL LETTER M WITH DOT ABOVE */ +#define XK_mabovedot 0x1001e41 /* U+1E41 LATIN SMALL LETTER M WITH DOT ABOVE */ +#define XK_Pabovedot 0x1001e56 /* U+1E56 LATIN CAPITAL LETTER P WITH DOT ABOVE */ +#define XK_pabovedot 0x1001e57 /* U+1E57 LATIN SMALL LETTER P WITH DOT ABOVE */ +#define XK_Sabovedot 0x1001e60 /* U+1E60 LATIN CAPITAL LETTER S WITH DOT ABOVE */ +#define XK_sabovedot 0x1001e61 /* U+1E61 LATIN SMALL LETTER S WITH DOT ABOVE */ +#define XK_Tabovedot 0x1001e6a /* U+1E6A LATIN CAPITAL LETTER T WITH DOT ABOVE */ +#define XK_tabovedot 0x1001e6b /* U+1E6B LATIN SMALL LETTER T WITH DOT ABOVE */ +#define XK_Wgrave 0x1001e80 /* U+1E80 LATIN CAPITAL LETTER W WITH GRAVE */ +#define XK_wgrave 0x1001e81 /* U+1E81 LATIN SMALL LETTER W WITH GRAVE */ +#define XK_Wacute 0x1001e82 /* U+1E82 LATIN CAPITAL LETTER W WITH ACUTE */ +#define XK_wacute 0x1001e83 /* U+1E83 LATIN SMALL LETTER W WITH ACUTE */ +#define XK_Wdiaeresis 0x1001e84 /* U+1E84 LATIN CAPITAL LETTER W WITH DIAERESIS */ +#define XK_wdiaeresis 0x1001e85 /* U+1E85 LATIN SMALL LETTER W WITH DIAERESIS */ +#define XK_Ygrave 0x1001ef2 /* U+1EF2 LATIN CAPITAL LETTER Y WITH GRAVE */ +#define XK_ygrave 0x1001ef3 /* U+1EF3 LATIN SMALL LETTER Y WITH GRAVE */ +#endif /* XK_LATIN8 */ /* * Latin 9 @@ -913,10 +907,10 @@ SOFTWARE. */ #ifdef XK_LATIN9 -#define XK_OE 0x13bc /* U+0152 LATIN CAPITAL LIGATURE OE */ -#define XK_oe 0x13bd /* U+0153 LATIN SMALL LIGATURE OE */ -#define XK_Ydiaeresis 0x13be /* U+0178 LATIN CAPITAL LETTER Y WITH DIAERESIS */ -#endif /* XK_LATIN9 */ +#define XK_OE 0x13bc /* U+0152 LATIN CAPITAL LIGATURE OE */ +#define XK_oe 0x13bd /* U+0153 LATIN SMALL LIGATURE OE */ +#define XK_Ydiaeresis 0x13be /* U+0178 LATIN CAPITAL LETTER Y WITH DIAERESIS */ +#endif /* XK_LATIN9 */ /* * Katakana @@ -924,77 +918,77 @@ SOFTWARE. */ #ifdef XK_KATAKANA -#define XK_overline 0x047e /* U+203E OVERLINE */ -#define XK_kana_fullstop 0x04a1 /* U+3002 IDEOGRAPHIC FULL STOP */ -#define XK_kana_openingbracket 0x04a2 /* U+300C LEFT CORNER BRACKET */ -#define XK_kana_closingbracket 0x04a3 /* U+300D RIGHT CORNER BRACKET */ -#define XK_kana_comma 0x04a4 /* U+3001 IDEOGRAPHIC COMMA */ -#define XK_kana_conjunctive 0x04a5 /* U+30FB KATAKANA MIDDLE DOT */ -#define XK_kana_middledot 0x04a5 /* deprecated */ -#define XK_kana_WO 0x04a6 /* U+30F2 KATAKANA LETTER WO */ -#define XK_kana_a 0x04a7 /* U+30A1 KATAKANA LETTER SMALL A */ -#define XK_kana_i 0x04a8 /* U+30A3 KATAKANA LETTER SMALL I */ -#define XK_kana_u 0x04a9 /* U+30A5 KATAKANA LETTER SMALL U */ -#define XK_kana_e 0x04aa /* U+30A7 KATAKANA LETTER SMALL E */ -#define XK_kana_o 0x04ab /* U+30A9 KATAKANA LETTER SMALL O */ -#define XK_kana_ya 0x04ac /* U+30E3 KATAKANA LETTER SMALL YA */ -#define XK_kana_yu 0x04ad /* U+30E5 KATAKANA LETTER SMALL YU */ -#define XK_kana_yo 0x04ae /* U+30E7 KATAKANA LETTER SMALL YO */ -#define XK_kana_tsu 0x04af /* U+30C3 KATAKANA LETTER SMALL TU */ -#define XK_kana_tu 0x04af /* deprecated */ -#define XK_prolongedsound 0x04b0 /* U+30FC KATAKANA-HIRAGANA PROLONGED SOUND MARK */ -#define XK_kana_A 0x04b1 /* U+30A2 KATAKANA LETTER A */ -#define XK_kana_I 0x04b2 /* U+30A4 KATAKANA LETTER I */ -#define XK_kana_U 0x04b3 /* U+30A6 KATAKANA LETTER U */ -#define XK_kana_E 0x04b4 /* U+30A8 KATAKANA LETTER E */ -#define XK_kana_O 0x04b5 /* U+30AA KATAKANA LETTER O */ -#define XK_kana_KA 0x04b6 /* U+30AB KATAKANA LETTER KA */ -#define XK_kana_KI 0x04b7 /* U+30AD KATAKANA LETTER KI */ -#define XK_kana_KU 0x04b8 /* U+30AF KATAKANA LETTER KU */ -#define XK_kana_KE 0x04b9 /* U+30B1 KATAKANA LETTER KE */ -#define XK_kana_KO 0x04ba /* U+30B3 KATAKANA LETTER KO */ -#define XK_kana_SA 0x04bb /* U+30B5 KATAKANA LETTER SA */ -#define XK_kana_SHI 0x04bc /* U+30B7 KATAKANA LETTER SI */ -#define XK_kana_SU 0x04bd /* U+30B9 KATAKANA LETTER SU */ -#define XK_kana_SE 0x04be /* U+30BB KATAKANA LETTER SE */ -#define XK_kana_SO 0x04bf /* U+30BD KATAKANA LETTER SO */ -#define XK_kana_TA 0x04c0 /* U+30BF KATAKANA LETTER TA */ -#define XK_kana_CHI 0x04c1 /* U+30C1 KATAKANA LETTER TI */ -#define XK_kana_TI 0x04c1 /* deprecated */ -#define XK_kana_TSU 0x04c2 /* U+30C4 KATAKANA LETTER TU */ -#define XK_kana_TU 0x04c2 /* deprecated */ -#define XK_kana_TE 0x04c3 /* U+30C6 KATAKANA LETTER TE */ -#define XK_kana_TO 0x04c4 /* U+30C8 KATAKANA LETTER TO */ -#define XK_kana_NA 0x04c5 /* U+30CA KATAKANA LETTER NA */ -#define XK_kana_NI 0x04c6 /* U+30CB KATAKANA LETTER NI */ -#define XK_kana_NU 0x04c7 /* U+30CC KATAKANA LETTER NU */ -#define XK_kana_NE 0x04c8 /* U+30CD KATAKANA LETTER NE */ -#define XK_kana_NO 0x04c9 /* U+30CE KATAKANA LETTER NO */ -#define XK_kana_HA 0x04ca /* U+30CF KATAKANA LETTER HA */ -#define XK_kana_HI 0x04cb /* U+30D2 KATAKANA LETTER HI */ -#define XK_kana_FU 0x04cc /* U+30D5 KATAKANA LETTER HU */ -#define XK_kana_HU 0x04cc /* deprecated */ -#define XK_kana_HE 0x04cd /* U+30D8 KATAKANA LETTER HE */ -#define XK_kana_HO 0x04ce /* U+30DB KATAKANA LETTER HO */ -#define XK_kana_MA 0x04cf /* U+30DE KATAKANA LETTER MA */ -#define XK_kana_MI 0x04d0 /* U+30DF KATAKANA LETTER MI */ -#define XK_kana_MU 0x04d1 /* U+30E0 KATAKANA LETTER MU */ -#define XK_kana_ME 0x04d2 /* U+30E1 KATAKANA LETTER ME */ -#define XK_kana_MO 0x04d3 /* U+30E2 KATAKANA LETTER MO */ -#define XK_kana_YA 0x04d4 /* U+30E4 KATAKANA LETTER YA */ -#define XK_kana_YU 0x04d5 /* U+30E6 KATAKANA LETTER YU */ -#define XK_kana_YO 0x04d6 /* U+30E8 KATAKANA LETTER YO */ -#define XK_kana_RA 0x04d7 /* U+30E9 KATAKANA LETTER RA */ -#define XK_kana_RI 0x04d8 /* U+30EA KATAKANA LETTER RI */ -#define XK_kana_RU 0x04d9 /* U+30EB KATAKANA LETTER RU */ -#define XK_kana_RE 0x04da /* U+30EC KATAKANA LETTER RE */ -#define XK_kana_RO 0x04db /* U+30ED KATAKANA LETTER RO */ -#define XK_kana_WA 0x04dc /* U+30EF KATAKANA LETTER WA */ -#define XK_kana_N 0x04dd /* U+30F3 KATAKANA LETTER N */ -#define XK_voicedsound 0x04de /* U+309B KATAKANA-HIRAGANA VOICED SOUND MARK */ -#define XK_semivoicedsound 0x04df /* U+309C KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ -#define XK_kana_switch 0xff7e /* Alias for mode_switch */ -#endif /* XK_KATAKANA */ +#define XK_overline 0x047e /* U+203E OVERLINE */ +#define XK_kana_fullstop 0x04a1 /* U+3002 IDEOGRAPHIC FULL STOP */ +#define XK_kana_openingbracket 0x04a2 /* U+300C LEFT CORNER BRACKET */ +#define XK_kana_closingbracket 0x04a3 /* U+300D RIGHT CORNER BRACKET */ +#define XK_kana_comma 0x04a4 /* U+3001 IDEOGRAPHIC COMMA */ +#define XK_kana_conjunctive 0x04a5 /* U+30FB KATAKANA MIDDLE DOT */ +#define XK_kana_middledot 0x04a5 /* deprecated */ +#define XK_kana_WO 0x04a6 /* U+30F2 KATAKANA LETTER WO */ +#define XK_kana_a 0x04a7 /* U+30A1 KATAKANA LETTER SMALL A */ +#define XK_kana_i 0x04a8 /* U+30A3 KATAKANA LETTER SMALL I */ +#define XK_kana_u 0x04a9 /* U+30A5 KATAKANA LETTER SMALL U */ +#define XK_kana_e 0x04aa /* U+30A7 KATAKANA LETTER SMALL E */ +#define XK_kana_o 0x04ab /* U+30A9 KATAKANA LETTER SMALL O */ +#define XK_kana_ya 0x04ac /* U+30E3 KATAKANA LETTER SMALL YA */ +#define XK_kana_yu 0x04ad /* U+30E5 KATAKANA LETTER SMALL YU */ +#define XK_kana_yo 0x04ae /* U+30E7 KATAKANA LETTER SMALL YO */ +#define XK_kana_tsu 0x04af /* U+30C3 KATAKANA LETTER SMALL TU */ +#define XK_kana_tu 0x04af /* deprecated */ +#define XK_prolongedsound 0x04b0 /* U+30FC KATAKANA-HIRAGANA PROLONGED SOUND MARK */ +#define XK_kana_A 0x04b1 /* U+30A2 KATAKANA LETTER A */ +#define XK_kana_I 0x04b2 /* U+30A4 KATAKANA LETTER I */ +#define XK_kana_U 0x04b3 /* U+30A6 KATAKANA LETTER U */ +#define XK_kana_E 0x04b4 /* U+30A8 KATAKANA LETTER E */ +#define XK_kana_O 0x04b5 /* U+30AA KATAKANA LETTER O */ +#define XK_kana_KA 0x04b6 /* U+30AB KATAKANA LETTER KA */ +#define XK_kana_KI 0x04b7 /* U+30AD KATAKANA LETTER KI */ +#define XK_kana_KU 0x04b8 /* U+30AF KATAKANA LETTER KU */ +#define XK_kana_KE 0x04b9 /* U+30B1 KATAKANA LETTER KE */ +#define XK_kana_KO 0x04ba /* U+30B3 KATAKANA LETTER KO */ +#define XK_kana_SA 0x04bb /* U+30B5 KATAKANA LETTER SA */ +#define XK_kana_SHI 0x04bc /* U+30B7 KATAKANA LETTER SI */ +#define XK_kana_SU 0x04bd /* U+30B9 KATAKANA LETTER SU */ +#define XK_kana_SE 0x04be /* U+30BB KATAKANA LETTER SE */ +#define XK_kana_SO 0x04bf /* U+30BD KATAKANA LETTER SO */ +#define XK_kana_TA 0x04c0 /* U+30BF KATAKANA LETTER TA */ +#define XK_kana_CHI 0x04c1 /* U+30C1 KATAKANA LETTER TI */ +#define XK_kana_TI 0x04c1 /* deprecated */ +#define XK_kana_TSU 0x04c2 /* U+30C4 KATAKANA LETTER TU */ +#define XK_kana_TU 0x04c2 /* deprecated */ +#define XK_kana_TE 0x04c3 /* U+30C6 KATAKANA LETTER TE */ +#define XK_kana_TO 0x04c4 /* U+30C8 KATAKANA LETTER TO */ +#define XK_kana_NA 0x04c5 /* U+30CA KATAKANA LETTER NA */ +#define XK_kana_NI 0x04c6 /* U+30CB KATAKANA LETTER NI */ +#define XK_kana_NU 0x04c7 /* U+30CC KATAKANA LETTER NU */ +#define XK_kana_NE 0x04c8 /* U+30CD KATAKANA LETTER NE */ +#define XK_kana_NO 0x04c9 /* U+30CE KATAKANA LETTER NO */ +#define XK_kana_HA 0x04ca /* U+30CF KATAKANA LETTER HA */ +#define XK_kana_HI 0x04cb /* U+30D2 KATAKANA LETTER HI */ +#define XK_kana_FU 0x04cc /* U+30D5 KATAKANA LETTER HU */ +#define XK_kana_HU 0x04cc /* deprecated */ +#define XK_kana_HE 0x04cd /* U+30D8 KATAKANA LETTER HE */ +#define XK_kana_HO 0x04ce /* U+30DB KATAKANA LETTER HO */ +#define XK_kana_MA 0x04cf /* U+30DE KATAKANA LETTER MA */ +#define XK_kana_MI 0x04d0 /* U+30DF KATAKANA LETTER MI */ +#define XK_kana_MU 0x04d1 /* U+30E0 KATAKANA LETTER MU */ +#define XK_kana_ME 0x04d2 /* U+30E1 KATAKANA LETTER ME */ +#define XK_kana_MO 0x04d3 /* U+30E2 KATAKANA LETTER MO */ +#define XK_kana_YA 0x04d4 /* U+30E4 KATAKANA LETTER YA */ +#define XK_kana_YU 0x04d5 /* U+30E6 KATAKANA LETTER YU */ +#define XK_kana_YO 0x04d6 /* U+30E8 KATAKANA LETTER YO */ +#define XK_kana_RA 0x04d7 /* U+30E9 KATAKANA LETTER RA */ +#define XK_kana_RI 0x04d8 /* U+30EA KATAKANA LETTER RI */ +#define XK_kana_RU 0x04d9 /* U+30EB KATAKANA LETTER RU */ +#define XK_kana_RE 0x04da /* U+30EC KATAKANA LETTER RE */ +#define XK_kana_RO 0x04db /* U+30ED KATAKANA LETTER RO */ +#define XK_kana_WA 0x04dc /* U+30EF KATAKANA LETTER WA */ +#define XK_kana_N 0x04dd /* U+30F3 KATAKANA LETTER N */ +#define XK_voicedsound 0x04de /* U+309B KATAKANA-HIRAGANA VOICED SOUND MARK */ +#define XK_semivoicedsound 0x04df /* U+309C KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ +#define XK_kana_switch 0xff7e /* Alias for mode_switch */ +#endif /* XK_KATAKANA */ /* * Arabic @@ -1002,246 +996,246 @@ SOFTWARE. */ #ifdef XK_ARABIC -#define XK_Farsi_0 0x10006f0 /* U+06F0 EXTENDED ARABIC-INDIC DIGIT ZERO */ -#define XK_Farsi_1 0x10006f1 /* U+06F1 EXTENDED ARABIC-INDIC DIGIT ONE */ -#define XK_Farsi_2 0x10006f2 /* U+06F2 EXTENDED ARABIC-INDIC DIGIT TWO */ -#define XK_Farsi_3 0x10006f3 /* U+06F3 EXTENDED ARABIC-INDIC DIGIT THREE */ -#define XK_Farsi_4 0x10006f4 /* U+06F4 EXTENDED ARABIC-INDIC DIGIT FOUR */ -#define XK_Farsi_5 0x10006f5 /* U+06F5 EXTENDED ARABIC-INDIC DIGIT FIVE */ -#define XK_Farsi_6 0x10006f6 /* U+06F6 EXTENDED ARABIC-INDIC DIGIT SIX */ -#define XK_Farsi_7 0x10006f7 /* U+06F7 EXTENDED ARABIC-INDIC DIGIT SEVEN */ -#define XK_Farsi_8 0x10006f8 /* U+06F8 EXTENDED ARABIC-INDIC DIGIT EIGHT */ -#define XK_Farsi_9 0x10006f9 /* U+06F9 EXTENDED ARABIC-INDIC DIGIT NINE */ -#define XK_Arabic_percent 0x100066a /* U+066A ARABIC PERCENT SIGN */ -#define XK_Arabic_superscript_alef 0x1000670 /* U+0670 ARABIC LETTER SUPERSCRIPT ALEF */ -#define XK_Arabic_tteh 0x1000679 /* U+0679 ARABIC LETTER TTEH */ -#define XK_Arabic_peh 0x100067e /* U+067E ARABIC LETTER PEH */ -#define XK_Arabic_tcheh 0x1000686 /* U+0686 ARABIC LETTER TCHEH */ -#define XK_Arabic_ddal 0x1000688 /* U+0688 ARABIC LETTER DDAL */ -#define XK_Arabic_rreh 0x1000691 /* U+0691 ARABIC LETTER RREH */ -#define XK_Arabic_comma 0x05ac /* U+060C ARABIC COMMA */ -#define XK_Arabic_fullstop 0x10006d4 /* U+06D4 ARABIC FULL STOP */ -#define XK_Arabic_0 0x1000660 /* U+0660 ARABIC-INDIC DIGIT ZERO */ -#define XK_Arabic_1 0x1000661 /* U+0661 ARABIC-INDIC DIGIT ONE */ -#define XK_Arabic_2 0x1000662 /* U+0662 ARABIC-INDIC DIGIT TWO */ -#define XK_Arabic_3 0x1000663 /* U+0663 ARABIC-INDIC DIGIT THREE */ -#define XK_Arabic_4 0x1000664 /* U+0664 ARABIC-INDIC DIGIT FOUR */ -#define XK_Arabic_5 0x1000665 /* U+0665 ARABIC-INDIC DIGIT FIVE */ -#define XK_Arabic_6 0x1000666 /* U+0666 ARABIC-INDIC DIGIT SIX */ -#define XK_Arabic_7 0x1000667 /* U+0667 ARABIC-INDIC DIGIT SEVEN */ -#define XK_Arabic_8 0x1000668 /* U+0668 ARABIC-INDIC DIGIT EIGHT */ -#define XK_Arabic_9 0x1000669 /* U+0669 ARABIC-INDIC DIGIT NINE */ -#define XK_Arabic_semicolon 0x05bb /* U+061B ARABIC SEMICOLON */ -#define XK_Arabic_question_mark 0x05bf /* U+061F ARABIC QUESTION MARK */ -#define XK_Arabic_hamza 0x05c1 /* U+0621 ARABIC LETTER HAMZA */ -#define XK_Arabic_maddaonalef 0x05c2 /* U+0622 ARABIC LETTER ALEF WITH MADDA ABOVE */ -#define XK_Arabic_hamzaonalef 0x05c3 /* U+0623 ARABIC LETTER ALEF WITH HAMZA ABOVE */ -#define XK_Arabic_hamzaonwaw 0x05c4 /* U+0624 ARABIC LETTER WAW WITH HAMZA ABOVE */ -#define XK_Arabic_hamzaunderalef 0x05c5 /* U+0625 ARABIC LETTER ALEF WITH HAMZA BELOW */ -#define XK_Arabic_hamzaonyeh 0x05c6 /* U+0626 ARABIC LETTER YEH WITH HAMZA ABOVE */ -#define XK_Arabic_alef 0x05c7 /* U+0627 ARABIC LETTER ALEF */ -#define XK_Arabic_beh 0x05c8 /* U+0628 ARABIC LETTER BEH */ -#define XK_Arabic_tehmarbuta 0x05c9 /* U+0629 ARABIC LETTER TEH MARBUTA */ -#define XK_Arabic_teh 0x05ca /* U+062A ARABIC LETTER TEH */ -#define XK_Arabic_theh 0x05cb /* U+062B ARABIC LETTER THEH */ -#define XK_Arabic_jeem 0x05cc /* U+062C ARABIC LETTER JEEM */ -#define XK_Arabic_hah 0x05cd /* U+062D ARABIC LETTER HAH */ -#define XK_Arabic_khah 0x05ce /* U+062E ARABIC LETTER KHAH */ -#define XK_Arabic_dal 0x05cf /* U+062F ARABIC LETTER DAL */ -#define XK_Arabic_thal 0x05d0 /* U+0630 ARABIC LETTER THAL */ -#define XK_Arabic_ra 0x05d1 /* U+0631 ARABIC LETTER REH */ -#define XK_Arabic_zain 0x05d2 /* U+0632 ARABIC LETTER ZAIN */ -#define XK_Arabic_seen 0x05d3 /* U+0633 ARABIC LETTER SEEN */ -#define XK_Arabic_sheen 0x05d4 /* U+0634 ARABIC LETTER SHEEN */ -#define XK_Arabic_sad 0x05d5 /* U+0635 ARABIC LETTER SAD */ -#define XK_Arabic_dad 0x05d6 /* U+0636 ARABIC LETTER DAD */ -#define XK_Arabic_tah 0x05d7 /* U+0637 ARABIC LETTER TAH */ -#define XK_Arabic_zah 0x05d8 /* U+0638 ARABIC LETTER ZAH */ -#define XK_Arabic_ain 0x05d9 /* U+0639 ARABIC LETTER AIN */ -#define XK_Arabic_ghain 0x05da /* U+063A ARABIC LETTER GHAIN */ -#define XK_Arabic_tatweel 0x05e0 /* U+0640 ARABIC TATWEEL */ -#define XK_Arabic_feh 0x05e1 /* U+0641 ARABIC LETTER FEH */ -#define XK_Arabic_qaf 0x05e2 /* U+0642 ARABIC LETTER QAF */ -#define XK_Arabic_kaf 0x05e3 /* U+0643 ARABIC LETTER KAF */ -#define XK_Arabic_lam 0x05e4 /* U+0644 ARABIC LETTER LAM */ -#define XK_Arabic_meem 0x05e5 /* U+0645 ARABIC LETTER MEEM */ -#define XK_Arabic_noon 0x05e6 /* U+0646 ARABIC LETTER NOON */ -#define XK_Arabic_ha 0x05e7 /* U+0647 ARABIC LETTER HEH */ -#define XK_Arabic_heh 0x05e7 /* deprecated */ -#define XK_Arabic_waw 0x05e8 /* U+0648 ARABIC LETTER WAW */ -#define XK_Arabic_alefmaksura 0x05e9 /* U+0649 ARABIC LETTER ALEF MAKSURA */ -#define XK_Arabic_yeh 0x05ea /* U+064A ARABIC LETTER YEH */ -#define XK_Arabic_fathatan 0x05eb /* U+064B ARABIC FATHATAN */ -#define XK_Arabic_dammatan 0x05ec /* U+064C ARABIC DAMMATAN */ -#define XK_Arabic_kasratan 0x05ed /* U+064D ARABIC KASRATAN */ -#define XK_Arabic_fatha 0x05ee /* U+064E ARABIC FATHA */ -#define XK_Arabic_damma 0x05ef /* U+064F ARABIC DAMMA */ -#define XK_Arabic_kasra 0x05f0 /* U+0650 ARABIC KASRA */ -#define XK_Arabic_shadda 0x05f1 /* U+0651 ARABIC SHADDA */ -#define XK_Arabic_sukun 0x05f2 /* U+0652 ARABIC SUKUN */ -#define XK_Arabic_madda_above 0x1000653 /* U+0653 ARABIC MADDAH ABOVE */ -#define XK_Arabic_hamza_above 0x1000654 /* U+0654 ARABIC HAMZA ABOVE */ -#define XK_Arabic_hamza_below 0x1000655 /* U+0655 ARABIC HAMZA BELOW */ -#define XK_Arabic_jeh 0x1000698 /* U+0698 ARABIC LETTER JEH */ -#define XK_Arabic_veh 0x10006a4 /* U+06A4 ARABIC LETTER VEH */ -#define XK_Arabic_keheh 0x10006a9 /* U+06A9 ARABIC LETTER KEHEH */ -#define XK_Arabic_gaf 0x10006af /* U+06AF ARABIC LETTER GAF */ -#define XK_Arabic_noon_ghunna 0x10006ba /* U+06BA ARABIC LETTER NOON GHUNNA */ -#define XK_Arabic_heh_doachashmee 0x10006be /* U+06BE ARABIC LETTER HEH DOACHASHMEE */ -#define XK_Farsi_yeh 0x10006cc /* U+06CC ARABIC LETTER FARSI YEH */ -#define XK_Arabic_farsi_yeh 0x10006cc /* U+06CC ARABIC LETTER FARSI YEH */ -#define XK_Arabic_yeh_baree 0x10006d2 /* U+06D2 ARABIC LETTER YEH BARREE */ -#define XK_Arabic_heh_goal 0x10006c1 /* U+06C1 ARABIC LETTER HEH GOAL */ -#define XK_Arabic_switch 0xff7e /* Alias for mode_switch */ -#endif /* XK_ARABIC */ +#define XK_Farsi_0 0x10006f0 /* U+06F0 EXTENDED ARABIC-INDIC DIGIT ZERO */ +#define XK_Farsi_1 0x10006f1 /* U+06F1 EXTENDED ARABIC-INDIC DIGIT ONE */ +#define XK_Farsi_2 0x10006f2 /* U+06F2 EXTENDED ARABIC-INDIC DIGIT TWO */ +#define XK_Farsi_3 0x10006f3 /* U+06F3 EXTENDED ARABIC-INDIC DIGIT THREE */ +#define XK_Farsi_4 0x10006f4 /* U+06F4 EXTENDED ARABIC-INDIC DIGIT FOUR */ +#define XK_Farsi_5 0x10006f5 /* U+06F5 EXTENDED ARABIC-INDIC DIGIT FIVE */ +#define XK_Farsi_6 0x10006f6 /* U+06F6 EXTENDED ARABIC-INDIC DIGIT SIX */ +#define XK_Farsi_7 0x10006f7 /* U+06F7 EXTENDED ARABIC-INDIC DIGIT SEVEN */ +#define XK_Farsi_8 0x10006f8 /* U+06F8 EXTENDED ARABIC-INDIC DIGIT EIGHT */ +#define XK_Farsi_9 0x10006f9 /* U+06F9 EXTENDED ARABIC-INDIC DIGIT NINE */ +#define XK_Arabic_percent 0x100066a /* U+066A ARABIC PERCENT SIGN */ +#define XK_Arabic_superscript_alef 0x1000670 /* U+0670 ARABIC LETTER SUPERSCRIPT ALEF */ +#define XK_Arabic_tteh 0x1000679 /* U+0679 ARABIC LETTER TTEH */ +#define XK_Arabic_peh 0x100067e /* U+067E ARABIC LETTER PEH */ +#define XK_Arabic_tcheh 0x1000686 /* U+0686 ARABIC LETTER TCHEH */ +#define XK_Arabic_ddal 0x1000688 /* U+0688 ARABIC LETTER DDAL */ +#define XK_Arabic_rreh 0x1000691 /* U+0691 ARABIC LETTER RREH */ +#define XK_Arabic_comma 0x05ac /* U+060C ARABIC COMMA */ +#define XK_Arabic_fullstop 0x10006d4 /* U+06D4 ARABIC FULL STOP */ +#define XK_Arabic_0 0x1000660 /* U+0660 ARABIC-INDIC DIGIT ZERO */ +#define XK_Arabic_1 0x1000661 /* U+0661 ARABIC-INDIC DIGIT ONE */ +#define XK_Arabic_2 0x1000662 /* U+0662 ARABIC-INDIC DIGIT TWO */ +#define XK_Arabic_3 0x1000663 /* U+0663 ARABIC-INDIC DIGIT THREE */ +#define XK_Arabic_4 0x1000664 /* U+0664 ARABIC-INDIC DIGIT FOUR */ +#define XK_Arabic_5 0x1000665 /* U+0665 ARABIC-INDIC DIGIT FIVE */ +#define XK_Arabic_6 0x1000666 /* U+0666 ARABIC-INDIC DIGIT SIX */ +#define XK_Arabic_7 0x1000667 /* U+0667 ARABIC-INDIC DIGIT SEVEN */ +#define XK_Arabic_8 0x1000668 /* U+0668 ARABIC-INDIC DIGIT EIGHT */ +#define XK_Arabic_9 0x1000669 /* U+0669 ARABIC-INDIC DIGIT NINE */ +#define XK_Arabic_semicolon 0x05bb /* U+061B ARABIC SEMICOLON */ +#define XK_Arabic_question_mark 0x05bf /* U+061F ARABIC QUESTION MARK */ +#define XK_Arabic_hamza 0x05c1 /* U+0621 ARABIC LETTER HAMZA */ +#define XK_Arabic_maddaonalef 0x05c2 /* U+0622 ARABIC LETTER ALEF WITH MADDA ABOVE */ +#define XK_Arabic_hamzaonalef 0x05c3 /* U+0623 ARABIC LETTER ALEF WITH HAMZA ABOVE */ +#define XK_Arabic_hamzaonwaw 0x05c4 /* U+0624 ARABIC LETTER WAW WITH HAMZA ABOVE */ +#define XK_Arabic_hamzaunderalef 0x05c5 /* U+0625 ARABIC LETTER ALEF WITH HAMZA BELOW */ +#define XK_Arabic_hamzaonyeh 0x05c6 /* U+0626 ARABIC LETTER YEH WITH HAMZA ABOVE */ +#define XK_Arabic_alef 0x05c7 /* U+0627 ARABIC LETTER ALEF */ +#define XK_Arabic_beh 0x05c8 /* U+0628 ARABIC LETTER BEH */ +#define XK_Arabic_tehmarbuta 0x05c9 /* U+0629 ARABIC LETTER TEH MARBUTA */ +#define XK_Arabic_teh 0x05ca /* U+062A ARABIC LETTER TEH */ +#define XK_Arabic_theh 0x05cb /* U+062B ARABIC LETTER THEH */ +#define XK_Arabic_jeem 0x05cc /* U+062C ARABIC LETTER JEEM */ +#define XK_Arabic_hah 0x05cd /* U+062D ARABIC LETTER HAH */ +#define XK_Arabic_khah 0x05ce /* U+062E ARABIC LETTER KHAH */ +#define XK_Arabic_dal 0x05cf /* U+062F ARABIC LETTER DAL */ +#define XK_Arabic_thal 0x05d0 /* U+0630 ARABIC LETTER THAL */ +#define XK_Arabic_ra 0x05d1 /* U+0631 ARABIC LETTER REH */ +#define XK_Arabic_zain 0x05d2 /* U+0632 ARABIC LETTER ZAIN */ +#define XK_Arabic_seen 0x05d3 /* U+0633 ARABIC LETTER SEEN */ +#define XK_Arabic_sheen 0x05d4 /* U+0634 ARABIC LETTER SHEEN */ +#define XK_Arabic_sad 0x05d5 /* U+0635 ARABIC LETTER SAD */ +#define XK_Arabic_dad 0x05d6 /* U+0636 ARABIC LETTER DAD */ +#define XK_Arabic_tah 0x05d7 /* U+0637 ARABIC LETTER TAH */ +#define XK_Arabic_zah 0x05d8 /* U+0638 ARABIC LETTER ZAH */ +#define XK_Arabic_ain 0x05d9 /* U+0639 ARABIC LETTER AIN */ +#define XK_Arabic_ghain 0x05da /* U+063A ARABIC LETTER GHAIN */ +#define XK_Arabic_tatweel 0x05e0 /* U+0640 ARABIC TATWEEL */ +#define XK_Arabic_feh 0x05e1 /* U+0641 ARABIC LETTER FEH */ +#define XK_Arabic_qaf 0x05e2 /* U+0642 ARABIC LETTER QAF */ +#define XK_Arabic_kaf 0x05e3 /* U+0643 ARABIC LETTER KAF */ +#define XK_Arabic_lam 0x05e4 /* U+0644 ARABIC LETTER LAM */ +#define XK_Arabic_meem 0x05e5 /* U+0645 ARABIC LETTER MEEM */ +#define XK_Arabic_noon 0x05e6 /* U+0646 ARABIC LETTER NOON */ +#define XK_Arabic_ha 0x05e7 /* U+0647 ARABIC LETTER HEH */ +#define XK_Arabic_heh 0x05e7 /* deprecated */ +#define XK_Arabic_waw 0x05e8 /* U+0648 ARABIC LETTER WAW */ +#define XK_Arabic_alefmaksura 0x05e9 /* U+0649 ARABIC LETTER ALEF MAKSURA */ +#define XK_Arabic_yeh 0x05ea /* U+064A ARABIC LETTER YEH */ +#define XK_Arabic_fathatan 0x05eb /* U+064B ARABIC FATHATAN */ +#define XK_Arabic_dammatan 0x05ec /* U+064C ARABIC DAMMATAN */ +#define XK_Arabic_kasratan 0x05ed /* U+064D ARABIC KASRATAN */ +#define XK_Arabic_fatha 0x05ee /* U+064E ARABIC FATHA */ +#define XK_Arabic_damma 0x05ef /* U+064F ARABIC DAMMA */ +#define XK_Arabic_kasra 0x05f0 /* U+0650 ARABIC KASRA */ +#define XK_Arabic_shadda 0x05f1 /* U+0651 ARABIC SHADDA */ +#define XK_Arabic_sukun 0x05f2 /* U+0652 ARABIC SUKUN */ +#define XK_Arabic_madda_above 0x1000653 /* U+0653 ARABIC MADDAH ABOVE */ +#define XK_Arabic_hamza_above 0x1000654 /* U+0654 ARABIC HAMZA ABOVE */ +#define XK_Arabic_hamza_below 0x1000655 /* U+0655 ARABIC HAMZA BELOW */ +#define XK_Arabic_jeh 0x1000698 /* U+0698 ARABIC LETTER JEH */ +#define XK_Arabic_veh 0x10006a4 /* U+06A4 ARABIC LETTER VEH */ +#define XK_Arabic_keheh 0x10006a9 /* U+06A9 ARABIC LETTER KEHEH */ +#define XK_Arabic_gaf 0x10006af /* U+06AF ARABIC LETTER GAF */ +#define XK_Arabic_noon_ghunna 0x10006ba /* U+06BA ARABIC LETTER NOON GHUNNA */ +#define XK_Arabic_heh_doachashmee 0x10006be /* U+06BE ARABIC LETTER HEH DOACHASHMEE */ +#define XK_Farsi_yeh 0x10006cc /* U+06CC ARABIC LETTER FARSI YEH */ +#define XK_Arabic_farsi_yeh 0x10006cc /* U+06CC ARABIC LETTER FARSI YEH */ +#define XK_Arabic_yeh_baree 0x10006d2 /* U+06D2 ARABIC LETTER YEH BARREE */ +#define XK_Arabic_heh_goal 0x10006c1 /* U+06C1 ARABIC LETTER HEH GOAL */ +#define XK_Arabic_switch 0xff7e /* Alias for mode_switch */ +#endif /* XK_ARABIC */ /* * Cyrillic * Byte 3 = 6 */ #ifdef XK_CYRILLIC -#define XK_Cyrillic_GHE_bar 0x1000492 /* U+0492 CYRILLIC CAPITAL LETTER GHE WITH STROKE */ -#define XK_Cyrillic_ghe_bar 0x1000493 /* U+0493 CYRILLIC SMALL LETTER GHE WITH STROKE */ -#define XK_Cyrillic_ZHE_descender 0x1000496 /* U+0496 CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER */ -#define XK_Cyrillic_zhe_descender 0x1000497 /* U+0497 CYRILLIC SMALL LETTER ZHE WITH DESCENDER */ -#define XK_Cyrillic_KA_descender 0x100049a /* U+049A CYRILLIC CAPITAL LETTER KA WITH DESCENDER */ -#define XK_Cyrillic_ka_descender 0x100049b /* U+049B CYRILLIC SMALL LETTER KA WITH DESCENDER */ -#define XK_Cyrillic_KA_vertstroke 0x100049c /* U+049C CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE */ -#define XK_Cyrillic_ka_vertstroke 0x100049d /* U+049D CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE */ -#define XK_Cyrillic_EN_descender 0x10004a2 /* U+04A2 CYRILLIC CAPITAL LETTER EN WITH DESCENDER */ -#define XK_Cyrillic_en_descender 0x10004a3 /* U+04A3 CYRILLIC SMALL LETTER EN WITH DESCENDER */ -#define XK_Cyrillic_U_straight 0x10004ae /* U+04AE CYRILLIC CAPITAL LETTER STRAIGHT U */ -#define XK_Cyrillic_u_straight 0x10004af /* U+04AF CYRILLIC SMALL LETTER STRAIGHT U */ -#define XK_Cyrillic_U_straight_bar 0x10004b0 /* U+04B0 CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE */ -#define XK_Cyrillic_u_straight_bar 0x10004b1 /* U+04B1 CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE */ -#define XK_Cyrillic_HA_descender 0x10004b2 /* U+04B2 CYRILLIC CAPITAL LETTER HA WITH DESCENDER */ -#define XK_Cyrillic_ha_descender 0x10004b3 /* U+04B3 CYRILLIC SMALL LETTER HA WITH DESCENDER */ -#define XK_Cyrillic_CHE_descender 0x10004b6 /* U+04B6 CYRILLIC CAPITAL LETTER CHE WITH DESCENDER */ -#define XK_Cyrillic_che_descender 0x10004b7 /* U+04B7 CYRILLIC SMALL LETTER CHE WITH DESCENDER */ -#define XK_Cyrillic_CHE_vertstroke 0x10004b8 /* U+04B8 CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE */ -#define XK_Cyrillic_che_vertstroke 0x10004b9 /* U+04B9 CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE */ -#define XK_Cyrillic_SHHA 0x10004ba /* U+04BA CYRILLIC CAPITAL LETTER SHHA */ -#define XK_Cyrillic_shha 0x10004bb /* U+04BB CYRILLIC SMALL LETTER SHHA */ +#define XK_Cyrillic_GHE_bar 0x1000492 /* U+0492 CYRILLIC CAPITAL LETTER GHE WITH STROKE */ +#define XK_Cyrillic_ghe_bar 0x1000493 /* U+0493 CYRILLIC SMALL LETTER GHE WITH STROKE */ +#define XK_Cyrillic_ZHE_descender 0x1000496 /* U+0496 CYRILLIC CAPITAL LETTER ZHE WITH DESCENDER */ +#define XK_Cyrillic_zhe_descender 0x1000497 /* U+0497 CYRILLIC SMALL LETTER ZHE WITH DESCENDER */ +#define XK_Cyrillic_KA_descender 0x100049a /* U+049A CYRILLIC CAPITAL LETTER KA WITH DESCENDER */ +#define XK_Cyrillic_ka_descender 0x100049b /* U+049B CYRILLIC SMALL LETTER KA WITH DESCENDER */ +#define XK_Cyrillic_KA_vertstroke 0x100049c /* U+049C CYRILLIC CAPITAL LETTER KA WITH VERTICAL STROKE */ +#define XK_Cyrillic_ka_vertstroke 0x100049d /* U+049D CYRILLIC SMALL LETTER KA WITH VERTICAL STROKE */ +#define XK_Cyrillic_EN_descender 0x10004a2 /* U+04A2 CYRILLIC CAPITAL LETTER EN WITH DESCENDER */ +#define XK_Cyrillic_en_descender 0x10004a3 /* U+04A3 CYRILLIC SMALL LETTER EN WITH DESCENDER */ +#define XK_Cyrillic_U_straight 0x10004ae /* U+04AE CYRILLIC CAPITAL LETTER STRAIGHT U */ +#define XK_Cyrillic_u_straight 0x10004af /* U+04AF CYRILLIC SMALL LETTER STRAIGHT U */ +#define XK_Cyrillic_U_straight_bar 0x10004b0 /* U+04B0 CYRILLIC CAPITAL LETTER STRAIGHT U WITH STROKE */ +#define XK_Cyrillic_u_straight_bar 0x10004b1 /* U+04B1 CYRILLIC SMALL LETTER STRAIGHT U WITH STROKE */ +#define XK_Cyrillic_HA_descender 0x10004b2 /* U+04B2 CYRILLIC CAPITAL LETTER HA WITH DESCENDER */ +#define XK_Cyrillic_ha_descender 0x10004b3 /* U+04B3 CYRILLIC SMALL LETTER HA WITH DESCENDER */ +#define XK_Cyrillic_CHE_descender 0x10004b6 /* U+04B6 CYRILLIC CAPITAL LETTER CHE WITH DESCENDER */ +#define XK_Cyrillic_che_descender 0x10004b7 /* U+04B7 CYRILLIC SMALL LETTER CHE WITH DESCENDER */ +#define XK_Cyrillic_CHE_vertstroke 0x10004b8 /* U+04B8 CYRILLIC CAPITAL LETTER CHE WITH VERTICAL STROKE */ +#define XK_Cyrillic_che_vertstroke 0x10004b9 /* U+04B9 CYRILLIC SMALL LETTER CHE WITH VERTICAL STROKE */ +#define XK_Cyrillic_SHHA 0x10004ba /* U+04BA CYRILLIC CAPITAL LETTER SHHA */ +#define XK_Cyrillic_shha 0x10004bb /* U+04BB CYRILLIC SMALL LETTER SHHA */ -#define XK_Cyrillic_SCHWA 0x10004d8 /* U+04D8 CYRILLIC CAPITAL LETTER SCHWA */ -#define XK_Cyrillic_schwa 0x10004d9 /* U+04D9 CYRILLIC SMALL LETTER SCHWA */ -#define XK_Cyrillic_I_macron 0x10004e2 /* U+04E2 CYRILLIC CAPITAL LETTER I WITH MACRON */ -#define XK_Cyrillic_i_macron 0x10004e3 /* U+04E3 CYRILLIC SMALL LETTER I WITH MACRON */ -#define XK_Cyrillic_O_bar 0x10004e8 /* U+04E8 CYRILLIC CAPITAL LETTER BARRED O */ -#define XK_Cyrillic_o_bar 0x10004e9 /* U+04E9 CYRILLIC SMALL LETTER BARRED O */ -#define XK_Cyrillic_U_macron 0x10004ee /* U+04EE CYRILLIC CAPITAL LETTER U WITH MACRON */ -#define XK_Cyrillic_u_macron 0x10004ef /* U+04EF CYRILLIC SMALL LETTER U WITH MACRON */ +#define XK_Cyrillic_SCHWA 0x10004d8 /* U+04D8 CYRILLIC CAPITAL LETTER SCHWA */ +#define XK_Cyrillic_schwa 0x10004d9 /* U+04D9 CYRILLIC SMALL LETTER SCHWA */ +#define XK_Cyrillic_I_macron 0x10004e2 /* U+04E2 CYRILLIC CAPITAL LETTER I WITH MACRON */ +#define XK_Cyrillic_i_macron 0x10004e3 /* U+04E3 CYRILLIC SMALL LETTER I WITH MACRON */ +#define XK_Cyrillic_O_bar 0x10004e8 /* U+04E8 CYRILLIC CAPITAL LETTER BARRED O */ +#define XK_Cyrillic_o_bar 0x10004e9 /* U+04E9 CYRILLIC SMALL LETTER BARRED O */ +#define XK_Cyrillic_U_macron 0x10004ee /* U+04EE CYRILLIC CAPITAL LETTER U WITH MACRON */ +#define XK_Cyrillic_u_macron 0x10004ef /* U+04EF CYRILLIC SMALL LETTER U WITH MACRON */ -#define XK_Serbian_dje 0x06a1 /* U+0452 CYRILLIC SMALL LETTER DJE */ -#define XK_Macedonia_gje 0x06a2 /* U+0453 CYRILLIC SMALL LETTER GJE */ -#define XK_Cyrillic_io 0x06a3 /* U+0451 CYRILLIC SMALL LETTER IO */ -#define XK_Ukrainian_ie 0x06a4 /* U+0454 CYRILLIC SMALL LETTER UKRAINIAN IE */ -#define XK_Ukranian_je 0x06a4 /* deprecated */ -#define XK_Macedonia_dse 0x06a5 /* U+0455 CYRILLIC SMALL LETTER DZE */ -#define XK_Ukrainian_i 0x06a6 /* U+0456 CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ -#define XK_Ukranian_i 0x06a6 /* deprecated */ -#define XK_Ukrainian_yi 0x06a7 /* U+0457 CYRILLIC SMALL LETTER YI */ -#define XK_Ukranian_yi 0x06a7 /* deprecated */ -#define XK_Cyrillic_je 0x06a8 /* U+0458 CYRILLIC SMALL LETTER JE */ -#define XK_Serbian_je 0x06a8 /* deprecated */ -#define XK_Cyrillic_lje 0x06a9 /* U+0459 CYRILLIC SMALL LETTER LJE */ -#define XK_Serbian_lje 0x06a9 /* deprecated */ -#define XK_Cyrillic_nje 0x06aa /* U+045A CYRILLIC SMALL LETTER NJE */ -#define XK_Serbian_nje 0x06aa /* deprecated */ -#define XK_Serbian_tshe 0x06ab /* U+045B CYRILLIC SMALL LETTER TSHE */ -#define XK_Macedonia_kje 0x06ac /* U+045C CYRILLIC SMALL LETTER KJE */ -#define XK_Ukrainian_ghe_with_upturn 0x06ad /* U+0491 CYRILLIC SMALL LETTER GHE WITH UPTURN */ -#define XK_Byelorussian_shortu 0x06ae /* U+045E CYRILLIC SMALL LETTER SHORT U */ -#define XK_Cyrillic_dzhe 0x06af /* U+045F CYRILLIC SMALL LETTER DZHE */ -#define XK_Serbian_dze 0x06af /* deprecated */ -#define XK_numerosign 0x06b0 /* U+2116 NUMERO SIGN */ -#define XK_Serbian_DJE 0x06b1 /* U+0402 CYRILLIC CAPITAL LETTER DJE */ -#define XK_Macedonia_GJE 0x06b2 /* U+0403 CYRILLIC CAPITAL LETTER GJE */ -#define XK_Cyrillic_IO 0x06b3 /* U+0401 CYRILLIC CAPITAL LETTER IO */ -#define XK_Ukrainian_IE 0x06b4 /* U+0404 CYRILLIC CAPITAL LETTER UKRAINIAN IE */ -#define XK_Ukranian_JE 0x06b4 /* deprecated */ -#define XK_Macedonia_DSE 0x06b5 /* U+0405 CYRILLIC CAPITAL LETTER DZE */ -#define XK_Ukrainian_I 0x06b6 /* U+0406 CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ -#define XK_Ukranian_I 0x06b6 /* deprecated */ -#define XK_Ukrainian_YI 0x06b7 /* U+0407 CYRILLIC CAPITAL LETTER YI */ -#define XK_Ukranian_YI 0x06b7 /* deprecated */ -#define XK_Cyrillic_JE 0x06b8 /* U+0408 CYRILLIC CAPITAL LETTER JE */ -#define XK_Serbian_JE 0x06b8 /* deprecated */ -#define XK_Cyrillic_LJE 0x06b9 /* U+0409 CYRILLIC CAPITAL LETTER LJE */ -#define XK_Serbian_LJE 0x06b9 /* deprecated */ -#define XK_Cyrillic_NJE 0x06ba /* U+040A CYRILLIC CAPITAL LETTER NJE */ -#define XK_Serbian_NJE 0x06ba /* deprecated */ -#define XK_Serbian_TSHE 0x06bb /* U+040B CYRILLIC CAPITAL LETTER TSHE */ -#define XK_Macedonia_KJE 0x06bc /* U+040C CYRILLIC CAPITAL LETTER KJE */ -#define XK_Ukrainian_GHE_WITH_UPTURN 0x06bd /* U+0490 CYRILLIC CAPITAL LETTER GHE WITH UPTURN */ -#define XK_Byelorussian_SHORTU 0x06be /* U+040E CYRILLIC CAPITAL LETTER SHORT U */ -#define XK_Cyrillic_DZHE 0x06bf /* U+040F CYRILLIC CAPITAL LETTER DZHE */ -#define XK_Serbian_DZE 0x06bf /* deprecated */ -#define XK_Cyrillic_yu 0x06c0 /* U+044E CYRILLIC SMALL LETTER YU */ -#define XK_Cyrillic_a 0x06c1 /* U+0430 CYRILLIC SMALL LETTER A */ -#define XK_Cyrillic_be 0x06c2 /* U+0431 CYRILLIC SMALL LETTER BE */ -#define XK_Cyrillic_tse 0x06c3 /* U+0446 CYRILLIC SMALL LETTER TSE */ -#define XK_Cyrillic_de 0x06c4 /* U+0434 CYRILLIC SMALL LETTER DE */ -#define XK_Cyrillic_ie 0x06c5 /* U+0435 CYRILLIC SMALL LETTER IE */ -#define XK_Cyrillic_ef 0x06c6 /* U+0444 CYRILLIC SMALL LETTER EF */ -#define XK_Cyrillic_ghe 0x06c7 /* U+0433 CYRILLIC SMALL LETTER GHE */ -#define XK_Cyrillic_ha 0x06c8 /* U+0445 CYRILLIC SMALL LETTER HA */ -#define XK_Cyrillic_i 0x06c9 /* U+0438 CYRILLIC SMALL LETTER I */ -#define XK_Cyrillic_shorti 0x06ca /* U+0439 CYRILLIC SMALL LETTER SHORT I */ -#define XK_Cyrillic_ka 0x06cb /* U+043A CYRILLIC SMALL LETTER KA */ -#define XK_Cyrillic_el 0x06cc /* U+043B CYRILLIC SMALL LETTER EL */ -#define XK_Cyrillic_em 0x06cd /* U+043C CYRILLIC SMALL LETTER EM */ -#define XK_Cyrillic_en 0x06ce /* U+043D CYRILLIC SMALL LETTER EN */ -#define XK_Cyrillic_o 0x06cf /* U+043E CYRILLIC SMALL LETTER O */ -#define XK_Cyrillic_pe 0x06d0 /* U+043F CYRILLIC SMALL LETTER PE */ -#define XK_Cyrillic_ya 0x06d1 /* U+044F CYRILLIC SMALL LETTER YA */ -#define XK_Cyrillic_er 0x06d2 /* U+0440 CYRILLIC SMALL LETTER ER */ -#define XK_Cyrillic_es 0x06d3 /* U+0441 CYRILLIC SMALL LETTER ES */ -#define XK_Cyrillic_te 0x06d4 /* U+0442 CYRILLIC SMALL LETTER TE */ -#define XK_Cyrillic_u 0x06d5 /* U+0443 CYRILLIC SMALL LETTER U */ -#define XK_Cyrillic_zhe 0x06d6 /* U+0436 CYRILLIC SMALL LETTER ZHE */ -#define XK_Cyrillic_ve 0x06d7 /* U+0432 CYRILLIC SMALL LETTER VE */ -#define XK_Cyrillic_softsign 0x06d8 /* U+044C CYRILLIC SMALL LETTER SOFT SIGN */ -#define XK_Cyrillic_yeru 0x06d9 /* U+044B CYRILLIC SMALL LETTER YERU */ -#define XK_Cyrillic_ze 0x06da /* U+0437 CYRILLIC SMALL LETTER ZE */ -#define XK_Cyrillic_sha 0x06db /* U+0448 CYRILLIC SMALL LETTER SHA */ -#define XK_Cyrillic_e 0x06dc /* U+044D CYRILLIC SMALL LETTER E */ -#define XK_Cyrillic_shcha 0x06dd /* U+0449 CYRILLIC SMALL LETTER SHCHA */ -#define XK_Cyrillic_che 0x06de /* U+0447 CYRILLIC SMALL LETTER CHE */ -#define XK_Cyrillic_hardsign 0x06df /* U+044A CYRILLIC SMALL LETTER HARD SIGN */ -#define XK_Cyrillic_YU 0x06e0 /* U+042E CYRILLIC CAPITAL LETTER YU */ -#define XK_Cyrillic_A 0x06e1 /* U+0410 CYRILLIC CAPITAL LETTER A */ -#define XK_Cyrillic_BE 0x06e2 /* U+0411 CYRILLIC CAPITAL LETTER BE */ -#define XK_Cyrillic_TSE 0x06e3 /* U+0426 CYRILLIC CAPITAL LETTER TSE */ -#define XK_Cyrillic_DE 0x06e4 /* U+0414 CYRILLIC CAPITAL LETTER DE */ -#define XK_Cyrillic_IE 0x06e5 /* U+0415 CYRILLIC CAPITAL LETTER IE */ -#define XK_Cyrillic_EF 0x06e6 /* U+0424 CYRILLIC CAPITAL LETTER EF */ -#define XK_Cyrillic_GHE 0x06e7 /* U+0413 CYRILLIC CAPITAL LETTER GHE */ -#define XK_Cyrillic_HA 0x06e8 /* U+0425 CYRILLIC CAPITAL LETTER HA */ -#define XK_Cyrillic_I 0x06e9 /* U+0418 CYRILLIC CAPITAL LETTER I */ -#define XK_Cyrillic_SHORTI 0x06ea /* U+0419 CYRILLIC CAPITAL LETTER SHORT I */ -#define XK_Cyrillic_KA 0x06eb /* U+041A CYRILLIC CAPITAL LETTER KA */ -#define XK_Cyrillic_EL 0x06ec /* U+041B CYRILLIC CAPITAL LETTER EL */ -#define XK_Cyrillic_EM 0x06ed /* U+041C CYRILLIC CAPITAL LETTER EM */ -#define XK_Cyrillic_EN 0x06ee /* U+041D CYRILLIC CAPITAL LETTER EN */ -#define XK_Cyrillic_O 0x06ef /* U+041E CYRILLIC CAPITAL LETTER O */ -#define XK_Cyrillic_PE 0x06f0 /* U+041F CYRILLIC CAPITAL LETTER PE */ -#define XK_Cyrillic_YA 0x06f1 /* U+042F CYRILLIC CAPITAL LETTER YA */ -#define XK_Cyrillic_ER 0x06f2 /* U+0420 CYRILLIC CAPITAL LETTER ER */ -#define XK_Cyrillic_ES 0x06f3 /* U+0421 CYRILLIC CAPITAL LETTER ES */ -#define XK_Cyrillic_TE 0x06f4 /* U+0422 CYRILLIC CAPITAL LETTER TE */ -#define XK_Cyrillic_U 0x06f5 /* U+0423 CYRILLIC CAPITAL LETTER U */ -#define XK_Cyrillic_ZHE 0x06f6 /* U+0416 CYRILLIC CAPITAL LETTER ZHE */ -#define XK_Cyrillic_VE 0x06f7 /* U+0412 CYRILLIC CAPITAL LETTER VE */ -#define XK_Cyrillic_SOFTSIGN 0x06f8 /* U+042C CYRILLIC CAPITAL LETTER SOFT SIGN */ -#define XK_Cyrillic_YERU 0x06f9 /* U+042B CYRILLIC CAPITAL LETTER YERU */ -#define XK_Cyrillic_ZE 0x06fa /* U+0417 CYRILLIC CAPITAL LETTER ZE */ -#define XK_Cyrillic_SHA 0x06fb /* U+0428 CYRILLIC CAPITAL LETTER SHA */ -#define XK_Cyrillic_E 0x06fc /* U+042D CYRILLIC CAPITAL LETTER E */ -#define XK_Cyrillic_SHCHA 0x06fd /* U+0429 CYRILLIC CAPITAL LETTER SHCHA */ -#define XK_Cyrillic_CHE 0x06fe /* U+0427 CYRILLIC CAPITAL LETTER CHE */ -#define XK_Cyrillic_HARDSIGN 0x06ff /* U+042A CYRILLIC CAPITAL LETTER HARD SIGN */ -#endif /* XK_CYRILLIC */ +#define XK_Serbian_dje 0x06a1 /* U+0452 CYRILLIC SMALL LETTER DJE */ +#define XK_Macedonia_gje 0x06a2 /* U+0453 CYRILLIC SMALL LETTER GJE */ +#define XK_Cyrillic_io 0x06a3 /* U+0451 CYRILLIC SMALL LETTER IO */ +#define XK_Ukrainian_ie 0x06a4 /* U+0454 CYRILLIC SMALL LETTER UKRAINIAN IE */ +#define XK_Ukranian_je 0x06a4 /* deprecated */ +#define XK_Macedonia_dse 0x06a5 /* U+0455 CYRILLIC SMALL LETTER DZE */ +#define XK_Ukrainian_i 0x06a6 /* U+0456 CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ +#define XK_Ukranian_i 0x06a6 /* deprecated */ +#define XK_Ukrainian_yi 0x06a7 /* U+0457 CYRILLIC SMALL LETTER YI */ +#define XK_Ukranian_yi 0x06a7 /* deprecated */ +#define XK_Cyrillic_je 0x06a8 /* U+0458 CYRILLIC SMALL LETTER JE */ +#define XK_Serbian_je 0x06a8 /* deprecated */ +#define XK_Cyrillic_lje 0x06a9 /* U+0459 CYRILLIC SMALL LETTER LJE */ +#define XK_Serbian_lje 0x06a9 /* deprecated */ +#define XK_Cyrillic_nje 0x06aa /* U+045A CYRILLIC SMALL LETTER NJE */ +#define XK_Serbian_nje 0x06aa /* deprecated */ +#define XK_Serbian_tshe 0x06ab /* U+045B CYRILLIC SMALL LETTER TSHE */ +#define XK_Macedonia_kje 0x06ac /* U+045C CYRILLIC SMALL LETTER KJE */ +#define XK_Ukrainian_ghe_with_upturn 0x06ad /* U+0491 CYRILLIC SMALL LETTER GHE WITH UPTURN */ +#define XK_Byelorussian_shortu 0x06ae /* U+045E CYRILLIC SMALL LETTER SHORT U */ +#define XK_Cyrillic_dzhe 0x06af /* U+045F CYRILLIC SMALL LETTER DZHE */ +#define XK_Serbian_dze 0x06af /* deprecated */ +#define XK_numerosign 0x06b0 /* U+2116 NUMERO SIGN */ +#define XK_Serbian_DJE 0x06b1 /* U+0402 CYRILLIC CAPITAL LETTER DJE */ +#define XK_Macedonia_GJE 0x06b2 /* U+0403 CYRILLIC CAPITAL LETTER GJE */ +#define XK_Cyrillic_IO 0x06b3 /* U+0401 CYRILLIC CAPITAL LETTER IO */ +#define XK_Ukrainian_IE 0x06b4 /* U+0404 CYRILLIC CAPITAL LETTER UKRAINIAN IE */ +#define XK_Ukranian_JE 0x06b4 /* deprecated */ +#define XK_Macedonia_DSE 0x06b5 /* U+0405 CYRILLIC CAPITAL LETTER DZE */ +#define XK_Ukrainian_I 0x06b6 /* U+0406 CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ +#define XK_Ukranian_I 0x06b6 /* deprecated */ +#define XK_Ukrainian_YI 0x06b7 /* U+0407 CYRILLIC CAPITAL LETTER YI */ +#define XK_Ukranian_YI 0x06b7 /* deprecated */ +#define XK_Cyrillic_JE 0x06b8 /* U+0408 CYRILLIC CAPITAL LETTER JE */ +#define XK_Serbian_JE 0x06b8 /* deprecated */ +#define XK_Cyrillic_LJE 0x06b9 /* U+0409 CYRILLIC CAPITAL LETTER LJE */ +#define XK_Serbian_LJE 0x06b9 /* deprecated */ +#define XK_Cyrillic_NJE 0x06ba /* U+040A CYRILLIC CAPITAL LETTER NJE */ +#define XK_Serbian_NJE 0x06ba /* deprecated */ +#define XK_Serbian_TSHE 0x06bb /* U+040B CYRILLIC CAPITAL LETTER TSHE */ +#define XK_Macedonia_KJE 0x06bc /* U+040C CYRILLIC CAPITAL LETTER KJE */ +#define XK_Ukrainian_GHE_WITH_UPTURN 0x06bd /* U+0490 CYRILLIC CAPITAL LETTER GHE WITH UPTURN */ +#define XK_Byelorussian_SHORTU 0x06be /* U+040E CYRILLIC CAPITAL LETTER SHORT U */ +#define XK_Cyrillic_DZHE 0x06bf /* U+040F CYRILLIC CAPITAL LETTER DZHE */ +#define XK_Serbian_DZE 0x06bf /* deprecated */ +#define XK_Cyrillic_yu 0x06c0 /* U+044E CYRILLIC SMALL LETTER YU */ +#define XK_Cyrillic_a 0x06c1 /* U+0430 CYRILLIC SMALL LETTER A */ +#define XK_Cyrillic_be 0x06c2 /* U+0431 CYRILLIC SMALL LETTER BE */ +#define XK_Cyrillic_tse 0x06c3 /* U+0446 CYRILLIC SMALL LETTER TSE */ +#define XK_Cyrillic_de 0x06c4 /* U+0434 CYRILLIC SMALL LETTER DE */ +#define XK_Cyrillic_ie 0x06c5 /* U+0435 CYRILLIC SMALL LETTER IE */ +#define XK_Cyrillic_ef 0x06c6 /* U+0444 CYRILLIC SMALL LETTER EF */ +#define XK_Cyrillic_ghe 0x06c7 /* U+0433 CYRILLIC SMALL LETTER GHE */ +#define XK_Cyrillic_ha 0x06c8 /* U+0445 CYRILLIC SMALL LETTER HA */ +#define XK_Cyrillic_i 0x06c9 /* U+0438 CYRILLIC SMALL LETTER I */ +#define XK_Cyrillic_shorti 0x06ca /* U+0439 CYRILLIC SMALL LETTER SHORT I */ +#define XK_Cyrillic_ka 0x06cb /* U+043A CYRILLIC SMALL LETTER KA */ +#define XK_Cyrillic_el 0x06cc /* U+043B CYRILLIC SMALL LETTER EL */ +#define XK_Cyrillic_em 0x06cd /* U+043C CYRILLIC SMALL LETTER EM */ +#define XK_Cyrillic_en 0x06ce /* U+043D CYRILLIC SMALL LETTER EN */ +#define XK_Cyrillic_o 0x06cf /* U+043E CYRILLIC SMALL LETTER O */ +#define XK_Cyrillic_pe 0x06d0 /* U+043F CYRILLIC SMALL LETTER PE */ +#define XK_Cyrillic_ya 0x06d1 /* U+044F CYRILLIC SMALL LETTER YA */ +#define XK_Cyrillic_er 0x06d2 /* U+0440 CYRILLIC SMALL LETTER ER */ +#define XK_Cyrillic_es 0x06d3 /* U+0441 CYRILLIC SMALL LETTER ES */ +#define XK_Cyrillic_te 0x06d4 /* U+0442 CYRILLIC SMALL LETTER TE */ +#define XK_Cyrillic_u 0x06d5 /* U+0443 CYRILLIC SMALL LETTER U */ +#define XK_Cyrillic_zhe 0x06d6 /* U+0436 CYRILLIC SMALL LETTER ZHE */ +#define XK_Cyrillic_ve 0x06d7 /* U+0432 CYRILLIC SMALL LETTER VE */ +#define XK_Cyrillic_softsign 0x06d8 /* U+044C CYRILLIC SMALL LETTER SOFT SIGN */ +#define XK_Cyrillic_yeru 0x06d9 /* U+044B CYRILLIC SMALL LETTER YERU */ +#define XK_Cyrillic_ze 0x06da /* U+0437 CYRILLIC SMALL LETTER ZE */ +#define XK_Cyrillic_sha 0x06db /* U+0448 CYRILLIC SMALL LETTER SHA */ +#define XK_Cyrillic_e 0x06dc /* U+044D CYRILLIC SMALL LETTER E */ +#define XK_Cyrillic_shcha 0x06dd /* U+0449 CYRILLIC SMALL LETTER SHCHA */ +#define XK_Cyrillic_che 0x06de /* U+0447 CYRILLIC SMALL LETTER CHE */ +#define XK_Cyrillic_hardsign 0x06df /* U+044A CYRILLIC SMALL LETTER HARD SIGN */ +#define XK_Cyrillic_YU 0x06e0 /* U+042E CYRILLIC CAPITAL LETTER YU */ +#define XK_Cyrillic_A 0x06e1 /* U+0410 CYRILLIC CAPITAL LETTER A */ +#define XK_Cyrillic_BE 0x06e2 /* U+0411 CYRILLIC CAPITAL LETTER BE */ +#define XK_Cyrillic_TSE 0x06e3 /* U+0426 CYRILLIC CAPITAL LETTER TSE */ +#define XK_Cyrillic_DE 0x06e4 /* U+0414 CYRILLIC CAPITAL LETTER DE */ +#define XK_Cyrillic_IE 0x06e5 /* U+0415 CYRILLIC CAPITAL LETTER IE */ +#define XK_Cyrillic_EF 0x06e6 /* U+0424 CYRILLIC CAPITAL LETTER EF */ +#define XK_Cyrillic_GHE 0x06e7 /* U+0413 CYRILLIC CAPITAL LETTER GHE */ +#define XK_Cyrillic_HA 0x06e8 /* U+0425 CYRILLIC CAPITAL LETTER HA */ +#define XK_Cyrillic_I 0x06e9 /* U+0418 CYRILLIC CAPITAL LETTER I */ +#define XK_Cyrillic_SHORTI 0x06ea /* U+0419 CYRILLIC CAPITAL LETTER SHORT I */ +#define XK_Cyrillic_KA 0x06eb /* U+041A CYRILLIC CAPITAL LETTER KA */ +#define XK_Cyrillic_EL 0x06ec /* U+041B CYRILLIC CAPITAL LETTER EL */ +#define XK_Cyrillic_EM 0x06ed /* U+041C CYRILLIC CAPITAL LETTER EM */ +#define XK_Cyrillic_EN 0x06ee /* U+041D CYRILLIC CAPITAL LETTER EN */ +#define XK_Cyrillic_O 0x06ef /* U+041E CYRILLIC CAPITAL LETTER O */ +#define XK_Cyrillic_PE 0x06f0 /* U+041F CYRILLIC CAPITAL LETTER PE */ +#define XK_Cyrillic_YA 0x06f1 /* U+042F CYRILLIC CAPITAL LETTER YA */ +#define XK_Cyrillic_ER 0x06f2 /* U+0420 CYRILLIC CAPITAL LETTER ER */ +#define XK_Cyrillic_ES 0x06f3 /* U+0421 CYRILLIC CAPITAL LETTER ES */ +#define XK_Cyrillic_TE 0x06f4 /* U+0422 CYRILLIC CAPITAL LETTER TE */ +#define XK_Cyrillic_U 0x06f5 /* U+0423 CYRILLIC CAPITAL LETTER U */ +#define XK_Cyrillic_ZHE 0x06f6 /* U+0416 CYRILLIC CAPITAL LETTER ZHE */ +#define XK_Cyrillic_VE 0x06f7 /* U+0412 CYRILLIC CAPITAL LETTER VE */ +#define XK_Cyrillic_SOFTSIGN 0x06f8 /* U+042C CYRILLIC CAPITAL LETTER SOFT SIGN */ +#define XK_Cyrillic_YERU 0x06f9 /* U+042B CYRILLIC CAPITAL LETTER YERU */ +#define XK_Cyrillic_ZE 0x06fa /* U+0417 CYRILLIC CAPITAL LETTER ZE */ +#define XK_Cyrillic_SHA 0x06fb /* U+0428 CYRILLIC CAPITAL LETTER SHA */ +#define XK_Cyrillic_E 0x06fc /* U+042D CYRILLIC CAPITAL LETTER E */ +#define XK_Cyrillic_SHCHA 0x06fd /* U+0429 CYRILLIC CAPITAL LETTER SHCHA */ +#define XK_Cyrillic_CHE 0x06fe /* U+0427 CYRILLIC CAPITAL LETTER CHE */ +#define XK_Cyrillic_HARDSIGN 0x06ff /* U+042A CYRILLIC CAPITAL LETTER HARD SIGN */ +#endif /* XK_CYRILLIC */ /* * Greek @@ -1250,82 +1244,82 @@ SOFTWARE. */ #ifdef XK_GREEK -#define XK_Greek_ALPHAaccent 0x07a1 /* U+0386 GREEK CAPITAL LETTER ALPHA WITH TONOS */ -#define XK_Greek_EPSILONaccent 0x07a2 /* U+0388 GREEK CAPITAL LETTER EPSILON WITH TONOS */ -#define XK_Greek_ETAaccent 0x07a3 /* U+0389 GREEK CAPITAL LETTER ETA WITH TONOS */ -#define XK_Greek_IOTAaccent 0x07a4 /* U+038A GREEK CAPITAL LETTER IOTA WITH TONOS */ -#define XK_Greek_IOTAdieresis 0x07a5 /* U+03AA GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ -#define XK_Greek_IOTAdiaeresis 0x07a5 /* old typo */ -#define XK_Greek_OMICRONaccent 0x07a7 /* U+038C GREEK CAPITAL LETTER OMICRON WITH TONOS */ -#define XK_Greek_UPSILONaccent 0x07a8 /* U+038E GREEK CAPITAL LETTER UPSILON WITH TONOS */ -#define XK_Greek_UPSILONdieresis 0x07a9 /* U+03AB GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ -#define XK_Greek_OMEGAaccent 0x07ab /* U+038F GREEK CAPITAL LETTER OMEGA WITH TONOS */ -#define XK_Greek_accentdieresis 0x07ae /* U+0385 GREEK DIALYTIKA TONOS */ -#define XK_Greek_horizbar 0x07af /* U+2015 HORIZONTAL BAR */ -#define XK_Greek_alphaaccent 0x07b1 /* U+03AC GREEK SMALL LETTER ALPHA WITH TONOS */ -#define XK_Greek_epsilonaccent 0x07b2 /* U+03AD GREEK SMALL LETTER EPSILON WITH TONOS */ -#define XK_Greek_etaaccent 0x07b3 /* U+03AE GREEK SMALL LETTER ETA WITH TONOS */ -#define XK_Greek_iotaaccent 0x07b4 /* U+03AF GREEK SMALL LETTER IOTA WITH TONOS */ -#define XK_Greek_iotadieresis 0x07b5 /* U+03CA GREEK SMALL LETTER IOTA WITH DIALYTIKA */ -#define XK_Greek_iotaaccentdieresis 0x07b6 /* U+0390 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ -#define XK_Greek_omicronaccent 0x07b7 /* U+03CC GREEK SMALL LETTER OMICRON WITH TONOS */ -#define XK_Greek_upsilonaccent 0x07b8 /* U+03CD GREEK SMALL LETTER UPSILON WITH TONOS */ -#define XK_Greek_upsilondieresis 0x07b9 /* U+03CB GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ -#define XK_Greek_upsilonaccentdieresis 0x07ba /* U+03B0 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ -#define XK_Greek_omegaaccent 0x07bb /* U+03CE GREEK SMALL LETTER OMEGA WITH TONOS */ -#define XK_Greek_ALPHA 0x07c1 /* U+0391 GREEK CAPITAL LETTER ALPHA */ -#define XK_Greek_BETA 0x07c2 /* U+0392 GREEK CAPITAL LETTER BETA */ -#define XK_Greek_GAMMA 0x07c3 /* U+0393 GREEK CAPITAL LETTER GAMMA */ -#define XK_Greek_DELTA 0x07c4 /* U+0394 GREEK CAPITAL LETTER DELTA */ -#define XK_Greek_EPSILON 0x07c5 /* U+0395 GREEK CAPITAL LETTER EPSILON */ -#define XK_Greek_ZETA 0x07c6 /* U+0396 GREEK CAPITAL LETTER ZETA */ -#define XK_Greek_ETA 0x07c7 /* U+0397 GREEK CAPITAL LETTER ETA */ -#define XK_Greek_THETA 0x07c8 /* U+0398 GREEK CAPITAL LETTER THETA */ -#define XK_Greek_IOTA 0x07c9 /* U+0399 GREEK CAPITAL LETTER IOTA */ -#define XK_Greek_KAPPA 0x07ca /* U+039A GREEK CAPITAL LETTER KAPPA */ -#define XK_Greek_LAMDA 0x07cb /* U+039B GREEK CAPITAL LETTER LAMDA */ -#define XK_Greek_LAMBDA 0x07cb /* U+039B GREEK CAPITAL LETTER LAMDA */ -#define XK_Greek_MU 0x07cc /* U+039C GREEK CAPITAL LETTER MU */ -#define XK_Greek_NU 0x07cd /* U+039D GREEK CAPITAL LETTER NU */ -#define XK_Greek_XI 0x07ce /* U+039E GREEK CAPITAL LETTER XI */ -#define XK_Greek_OMICRON 0x07cf /* U+039F GREEK CAPITAL LETTER OMICRON */ -#define XK_Greek_PI 0x07d0 /* U+03A0 GREEK CAPITAL LETTER PI */ -#define XK_Greek_RHO 0x07d1 /* U+03A1 GREEK CAPITAL LETTER RHO */ -#define XK_Greek_SIGMA 0x07d2 /* U+03A3 GREEK CAPITAL LETTER SIGMA */ -#define XK_Greek_TAU 0x07d4 /* U+03A4 GREEK CAPITAL LETTER TAU */ -#define XK_Greek_UPSILON 0x07d5 /* U+03A5 GREEK CAPITAL LETTER UPSILON */ -#define XK_Greek_PHI 0x07d6 /* U+03A6 GREEK CAPITAL LETTER PHI */ -#define XK_Greek_CHI 0x07d7 /* U+03A7 GREEK CAPITAL LETTER CHI */ -#define XK_Greek_PSI 0x07d8 /* U+03A8 GREEK CAPITAL LETTER PSI */ -#define XK_Greek_OMEGA 0x07d9 /* U+03A9 GREEK CAPITAL LETTER OMEGA */ -#define XK_Greek_alpha 0x07e1 /* U+03B1 GREEK SMALL LETTER ALPHA */ -#define XK_Greek_beta 0x07e2 /* U+03B2 GREEK SMALL LETTER BETA */ -#define XK_Greek_gamma 0x07e3 /* U+03B3 GREEK SMALL LETTER GAMMA */ -#define XK_Greek_delta 0x07e4 /* U+03B4 GREEK SMALL LETTER DELTA */ -#define XK_Greek_epsilon 0x07e5 /* U+03B5 GREEK SMALL LETTER EPSILON */ -#define XK_Greek_zeta 0x07e6 /* U+03B6 GREEK SMALL LETTER ZETA */ -#define XK_Greek_eta 0x07e7 /* U+03B7 GREEK SMALL LETTER ETA */ -#define XK_Greek_theta 0x07e8 /* U+03B8 GREEK SMALL LETTER THETA */ -#define XK_Greek_iota 0x07e9 /* U+03B9 GREEK SMALL LETTER IOTA */ -#define XK_Greek_kappa 0x07ea /* U+03BA GREEK SMALL LETTER KAPPA */ -#define XK_Greek_lamda 0x07eb /* U+03BB GREEK SMALL LETTER LAMDA */ -#define XK_Greek_lambda 0x07eb /* U+03BB GREEK SMALL LETTER LAMDA */ -#define XK_Greek_mu 0x07ec /* U+03BC GREEK SMALL LETTER MU */ -#define XK_Greek_nu 0x07ed /* U+03BD GREEK SMALL LETTER NU */ -#define XK_Greek_xi 0x07ee /* U+03BE GREEK SMALL LETTER XI */ -#define XK_Greek_omicron 0x07ef /* U+03BF GREEK SMALL LETTER OMICRON */ -#define XK_Greek_pi 0x07f0 /* U+03C0 GREEK SMALL LETTER PI */ -#define XK_Greek_rho 0x07f1 /* U+03C1 GREEK SMALL LETTER RHO */ -#define XK_Greek_sigma 0x07f2 /* U+03C3 GREEK SMALL LETTER SIGMA */ -#define XK_Greek_finalsmallsigma 0x07f3 /* U+03C2 GREEK SMALL LETTER FINAL SIGMA */ -#define XK_Greek_tau 0x07f4 /* U+03C4 GREEK SMALL LETTER TAU */ -#define XK_Greek_upsilon 0x07f5 /* U+03C5 GREEK SMALL LETTER UPSILON */ -#define XK_Greek_phi 0x07f6 /* U+03C6 GREEK SMALL LETTER PHI */ -#define XK_Greek_chi 0x07f7 /* U+03C7 GREEK SMALL LETTER CHI */ -#define XK_Greek_psi 0x07f8 /* U+03C8 GREEK SMALL LETTER PSI */ -#define XK_Greek_omega 0x07f9 /* U+03C9 GREEK SMALL LETTER OMEGA */ -#define XK_Greek_switch 0xff7e /* Alias for mode_switch */ -#endif /* XK_GREEK */ +#define XK_Greek_ALPHAaccent 0x07a1 /* U+0386 GREEK CAPITAL LETTER ALPHA WITH TONOS */ +#define XK_Greek_EPSILONaccent 0x07a2 /* U+0388 GREEK CAPITAL LETTER EPSILON WITH TONOS */ +#define XK_Greek_ETAaccent 0x07a3 /* U+0389 GREEK CAPITAL LETTER ETA WITH TONOS */ +#define XK_Greek_IOTAaccent 0x07a4 /* U+038A GREEK CAPITAL LETTER IOTA WITH TONOS */ +#define XK_Greek_IOTAdieresis 0x07a5 /* U+03AA GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ +#define XK_Greek_IOTAdiaeresis 0x07a5 /* old typo */ +#define XK_Greek_OMICRONaccent 0x07a7 /* U+038C GREEK CAPITAL LETTER OMICRON WITH TONOS */ +#define XK_Greek_UPSILONaccent 0x07a8 /* U+038E GREEK CAPITAL LETTER UPSILON WITH TONOS */ +#define XK_Greek_UPSILONdieresis 0x07a9 /* U+03AB GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ +#define XK_Greek_OMEGAaccent 0x07ab /* U+038F GREEK CAPITAL LETTER OMEGA WITH TONOS */ +#define XK_Greek_accentdieresis 0x07ae /* U+0385 GREEK DIALYTIKA TONOS */ +#define XK_Greek_horizbar 0x07af /* U+2015 HORIZONTAL BAR */ +#define XK_Greek_alphaaccent 0x07b1 /* U+03AC GREEK SMALL LETTER ALPHA WITH TONOS */ +#define XK_Greek_epsilonaccent 0x07b2 /* U+03AD GREEK SMALL LETTER EPSILON WITH TONOS */ +#define XK_Greek_etaaccent 0x07b3 /* U+03AE GREEK SMALL LETTER ETA WITH TONOS */ +#define XK_Greek_iotaaccent 0x07b4 /* U+03AF GREEK SMALL LETTER IOTA WITH TONOS */ +#define XK_Greek_iotadieresis 0x07b5 /* U+03CA GREEK SMALL LETTER IOTA WITH DIALYTIKA */ +#define XK_Greek_iotaaccentdieresis 0x07b6 /* U+0390 GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ +#define XK_Greek_omicronaccent 0x07b7 /* U+03CC GREEK SMALL LETTER OMICRON WITH TONOS */ +#define XK_Greek_upsilonaccent 0x07b8 /* U+03CD GREEK SMALL LETTER UPSILON WITH TONOS */ +#define XK_Greek_upsilondieresis 0x07b9 /* U+03CB GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ +#define XK_Greek_upsilonaccentdieresis 0x07ba /* U+03B0 GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ +#define XK_Greek_omegaaccent 0x07bb /* U+03CE GREEK SMALL LETTER OMEGA WITH TONOS */ +#define XK_Greek_ALPHA 0x07c1 /* U+0391 GREEK CAPITAL LETTER ALPHA */ +#define XK_Greek_BETA 0x07c2 /* U+0392 GREEK CAPITAL LETTER BETA */ +#define XK_Greek_GAMMA 0x07c3 /* U+0393 GREEK CAPITAL LETTER GAMMA */ +#define XK_Greek_DELTA 0x07c4 /* U+0394 GREEK CAPITAL LETTER DELTA */ +#define XK_Greek_EPSILON 0x07c5 /* U+0395 GREEK CAPITAL LETTER EPSILON */ +#define XK_Greek_ZETA 0x07c6 /* U+0396 GREEK CAPITAL LETTER ZETA */ +#define XK_Greek_ETA 0x07c7 /* U+0397 GREEK CAPITAL LETTER ETA */ +#define XK_Greek_THETA 0x07c8 /* U+0398 GREEK CAPITAL LETTER THETA */ +#define XK_Greek_IOTA 0x07c9 /* U+0399 GREEK CAPITAL LETTER IOTA */ +#define XK_Greek_KAPPA 0x07ca /* U+039A GREEK CAPITAL LETTER KAPPA */ +#define XK_Greek_LAMDA 0x07cb /* U+039B GREEK CAPITAL LETTER LAMDA */ +#define XK_Greek_LAMBDA 0x07cb /* U+039B GREEK CAPITAL LETTER LAMDA */ +#define XK_Greek_MU 0x07cc /* U+039C GREEK CAPITAL LETTER MU */ +#define XK_Greek_NU 0x07cd /* U+039D GREEK CAPITAL LETTER NU */ +#define XK_Greek_XI 0x07ce /* U+039E GREEK CAPITAL LETTER XI */ +#define XK_Greek_OMICRON 0x07cf /* U+039F GREEK CAPITAL LETTER OMICRON */ +#define XK_Greek_PI 0x07d0 /* U+03A0 GREEK CAPITAL LETTER PI */ +#define XK_Greek_RHO 0x07d1 /* U+03A1 GREEK CAPITAL LETTER RHO */ +#define XK_Greek_SIGMA 0x07d2 /* U+03A3 GREEK CAPITAL LETTER SIGMA */ +#define XK_Greek_TAU 0x07d4 /* U+03A4 GREEK CAPITAL LETTER TAU */ +#define XK_Greek_UPSILON 0x07d5 /* U+03A5 GREEK CAPITAL LETTER UPSILON */ +#define XK_Greek_PHI 0x07d6 /* U+03A6 GREEK CAPITAL LETTER PHI */ +#define XK_Greek_CHI 0x07d7 /* U+03A7 GREEK CAPITAL LETTER CHI */ +#define XK_Greek_PSI 0x07d8 /* U+03A8 GREEK CAPITAL LETTER PSI */ +#define XK_Greek_OMEGA 0x07d9 /* U+03A9 GREEK CAPITAL LETTER OMEGA */ +#define XK_Greek_alpha 0x07e1 /* U+03B1 GREEK SMALL LETTER ALPHA */ +#define XK_Greek_beta 0x07e2 /* U+03B2 GREEK SMALL LETTER BETA */ +#define XK_Greek_gamma 0x07e3 /* U+03B3 GREEK SMALL LETTER GAMMA */ +#define XK_Greek_delta 0x07e4 /* U+03B4 GREEK SMALL LETTER DELTA */ +#define XK_Greek_epsilon 0x07e5 /* U+03B5 GREEK SMALL LETTER EPSILON */ +#define XK_Greek_zeta 0x07e6 /* U+03B6 GREEK SMALL LETTER ZETA */ +#define XK_Greek_eta 0x07e7 /* U+03B7 GREEK SMALL LETTER ETA */ +#define XK_Greek_theta 0x07e8 /* U+03B8 GREEK SMALL LETTER THETA */ +#define XK_Greek_iota 0x07e9 /* U+03B9 GREEK SMALL LETTER IOTA */ +#define XK_Greek_kappa 0x07ea /* U+03BA GREEK SMALL LETTER KAPPA */ +#define XK_Greek_lamda 0x07eb /* U+03BB GREEK SMALL LETTER LAMDA */ +#define XK_Greek_lambda 0x07eb /* U+03BB GREEK SMALL LETTER LAMDA */ +#define XK_Greek_mu 0x07ec /* U+03BC GREEK SMALL LETTER MU */ +#define XK_Greek_nu 0x07ed /* U+03BD GREEK SMALL LETTER NU */ +#define XK_Greek_xi 0x07ee /* U+03BE GREEK SMALL LETTER XI */ +#define XK_Greek_omicron 0x07ef /* U+03BF GREEK SMALL LETTER OMICRON */ +#define XK_Greek_pi 0x07f0 /* U+03C0 GREEK SMALL LETTER PI */ +#define XK_Greek_rho 0x07f1 /* U+03C1 GREEK SMALL LETTER RHO */ +#define XK_Greek_sigma 0x07f2 /* U+03C3 GREEK SMALL LETTER SIGMA */ +#define XK_Greek_finalsmallsigma 0x07f3 /* U+03C2 GREEK SMALL LETTER FINAL SIGMA */ +#define XK_Greek_tau 0x07f4 /* U+03C4 GREEK SMALL LETTER TAU */ +#define XK_Greek_upsilon 0x07f5 /* U+03C5 GREEK SMALL LETTER UPSILON */ +#define XK_Greek_phi 0x07f6 /* U+03C6 GREEK SMALL LETTER PHI */ +#define XK_Greek_chi 0x07f7 /* U+03C7 GREEK SMALL LETTER CHI */ +#define XK_Greek_psi 0x07f8 /* U+03C8 GREEK SMALL LETTER PSI */ +#define XK_Greek_omega 0x07f9 /* U+03C9 GREEK SMALL LETTER OMEGA */ +#define XK_Greek_switch 0xff7e /* Alias for mode_switch */ +#endif /* XK_GREEK */ /* * Technical @@ -1334,56 +1328,56 @@ SOFTWARE. */ #ifdef XK_TECHNICAL -#define XK_leftradical 0x08a1 /* U+23B7 RADICAL SYMBOL BOTTOM */ -#define XK_topleftradical 0x08a2 /*(U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT)*/ -#define XK_horizconnector 0x08a3 /*(U+2500 BOX DRAWINGS LIGHT HORIZONTAL)*/ -#define XK_topintegral 0x08a4 /* U+2320 TOP HALF INTEGRAL */ -#define XK_botintegral 0x08a5 /* U+2321 BOTTOM HALF INTEGRAL */ -#define XK_vertconnector 0x08a6 /*(U+2502 BOX DRAWINGS LIGHT VERTICAL)*/ -#define XK_topleftsqbracket 0x08a7 /* U+23A1 LEFT SQUARE BRACKET UPPER CORNER */ -#define XK_botleftsqbracket 0x08a8 /* U+23A3 LEFT SQUARE BRACKET LOWER CORNER */ -#define XK_toprightsqbracket 0x08a9 /* U+23A4 RIGHT SQUARE BRACKET UPPER CORNER */ -#define XK_botrightsqbracket 0x08aa /* U+23A6 RIGHT SQUARE BRACKET LOWER CORNER */ -#define XK_topleftparens 0x08ab /* U+239B LEFT PARENTHESIS UPPER HOOK */ -#define XK_botleftparens 0x08ac /* U+239D LEFT PARENTHESIS LOWER HOOK */ -#define XK_toprightparens 0x08ad /* U+239E RIGHT PARENTHESIS UPPER HOOK */ -#define XK_botrightparens 0x08ae /* U+23A0 RIGHT PARENTHESIS LOWER HOOK */ -#define XK_leftmiddlecurlybrace 0x08af /* U+23A8 LEFT CURLY BRACKET MIDDLE PIECE */ -#define XK_rightmiddlecurlybrace 0x08b0 /* U+23AC RIGHT CURLY BRACKET MIDDLE PIECE */ -#define XK_topleftsummation 0x08b1 -#define XK_botleftsummation 0x08b2 -#define XK_topvertsummationconnector 0x08b3 -#define XK_botvertsummationconnector 0x08b4 -#define XK_toprightsummation 0x08b5 -#define XK_botrightsummation 0x08b6 -#define XK_rightmiddlesummation 0x08b7 -#define XK_lessthanequal 0x08bc /* U+2264 LESS-THAN OR EQUAL TO */ -#define XK_notequal 0x08bd /* U+2260 NOT EQUAL TO */ -#define XK_greaterthanequal 0x08be /* U+2265 GREATER-THAN OR EQUAL TO */ -#define XK_integral 0x08bf /* U+222B INTEGRAL */ -#define XK_therefore 0x08c0 /* U+2234 THEREFORE */ -#define XK_variation 0x08c1 /* U+221D PROPORTIONAL TO */ -#define XK_infinity 0x08c2 /* U+221E INFINITY */ -#define XK_nabla 0x08c5 /* U+2207 NABLA */ -#define XK_approximate 0x08c8 /* U+223C TILDE OPERATOR */ -#define XK_similarequal 0x08c9 /* U+2243 ASYMPTOTICALLY EQUAL TO */ -#define XK_ifonlyif 0x08cd /* U+21D4 LEFT RIGHT DOUBLE ARROW */ -#define XK_implies 0x08ce /* U+21D2 RIGHTWARDS DOUBLE ARROW */ -#define XK_identical 0x08cf /* U+2261 IDENTICAL TO */ -#define XK_radical 0x08d6 /* U+221A SQUARE ROOT */ -#define XK_includedin 0x08da /* U+2282 SUBSET OF */ -#define XK_includes 0x08db /* U+2283 SUPERSET OF */ -#define XK_intersection 0x08dc /* U+2229 INTERSECTION */ -#define XK_union 0x08dd /* U+222A UNION */ -#define XK_logicaland 0x08de /* U+2227 LOGICAL AND */ -#define XK_logicalor 0x08df /* U+2228 LOGICAL OR */ -#define XK_partialderivative 0x08ef /* U+2202 PARTIAL DIFFERENTIAL */ -#define XK_function 0x08f6 /* U+0192 LATIN SMALL LETTER F WITH HOOK */ -#define XK_leftarrow 0x08fb /* U+2190 LEFTWARDS ARROW */ -#define XK_uparrow 0x08fc /* U+2191 UPWARDS ARROW */ -#define XK_rightarrow 0x08fd /* U+2192 RIGHTWARDS ARROW */ -#define XK_downarrow 0x08fe /* U+2193 DOWNWARDS ARROW */ -#endif /* XK_TECHNICAL */ +#define XK_leftradical 0x08a1 /* U+23B7 RADICAL SYMBOL BOTTOM */ +#define XK_topleftradical 0x08a2 /*(U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT)*/ +#define XK_horizconnector 0x08a3 /*(U+2500 BOX DRAWINGS LIGHT HORIZONTAL)*/ +#define XK_topintegral 0x08a4 /* U+2320 TOP HALF INTEGRAL */ +#define XK_botintegral 0x08a5 /* U+2321 BOTTOM HALF INTEGRAL */ +#define XK_vertconnector 0x08a6 /*(U+2502 BOX DRAWINGS LIGHT VERTICAL)*/ +#define XK_topleftsqbracket 0x08a7 /* U+23A1 LEFT SQUARE BRACKET UPPER CORNER */ +#define XK_botleftsqbracket 0x08a8 /* U+23A3 LEFT SQUARE BRACKET LOWER CORNER */ +#define XK_toprightsqbracket 0x08a9 /* U+23A4 RIGHT SQUARE BRACKET UPPER CORNER */ +#define XK_botrightsqbracket 0x08aa /* U+23A6 RIGHT SQUARE BRACKET LOWER CORNER */ +#define XK_topleftparens 0x08ab /* U+239B LEFT PARENTHESIS UPPER HOOK */ +#define XK_botleftparens 0x08ac /* U+239D LEFT PARENTHESIS LOWER HOOK */ +#define XK_toprightparens 0x08ad /* U+239E RIGHT PARENTHESIS UPPER HOOK */ +#define XK_botrightparens 0x08ae /* U+23A0 RIGHT PARENTHESIS LOWER HOOK */ +#define XK_leftmiddlecurlybrace 0x08af /* U+23A8 LEFT CURLY BRACKET MIDDLE PIECE */ +#define XK_rightmiddlecurlybrace 0x08b0 /* U+23AC RIGHT CURLY BRACKET MIDDLE PIECE */ +#define XK_topleftsummation 0x08b1 +#define XK_botleftsummation 0x08b2 +#define XK_topvertsummationconnector 0x08b3 +#define XK_botvertsummationconnector 0x08b4 +#define XK_toprightsummation 0x08b5 +#define XK_botrightsummation 0x08b6 +#define XK_rightmiddlesummation 0x08b7 +#define XK_lessthanequal 0x08bc /* U+2264 LESS-THAN OR EQUAL TO */ +#define XK_notequal 0x08bd /* U+2260 NOT EQUAL TO */ +#define XK_greaterthanequal 0x08be /* U+2265 GREATER-THAN OR EQUAL TO */ +#define XK_integral 0x08bf /* U+222B INTEGRAL */ +#define XK_therefore 0x08c0 /* U+2234 THEREFORE */ +#define XK_variation 0x08c1 /* U+221D PROPORTIONAL TO */ +#define XK_infinity 0x08c2 /* U+221E INFINITY */ +#define XK_nabla 0x08c5 /* U+2207 NABLA */ +#define XK_approximate 0x08c8 /* U+223C TILDE OPERATOR */ +#define XK_similarequal 0x08c9 /* U+2243 ASYMPTOTICALLY EQUAL TO */ +#define XK_ifonlyif 0x08cd /* U+21D4 LEFT RIGHT DOUBLE ARROW */ +#define XK_implies 0x08ce /* U+21D2 RIGHTWARDS DOUBLE ARROW */ +#define XK_identical 0x08cf /* U+2261 IDENTICAL TO */ +#define XK_radical 0x08d6 /* U+221A SQUARE ROOT */ +#define XK_includedin 0x08da /* U+2282 SUBSET OF */ +#define XK_includes 0x08db /* U+2283 SUPERSET OF */ +#define XK_intersection 0x08dc /* U+2229 INTERSECTION */ +#define XK_union 0x08dd /* U+222A UNION */ +#define XK_logicaland 0x08de /* U+2227 LOGICAL AND */ +#define XK_logicalor 0x08df /* U+2228 LOGICAL OR */ +#define XK_partialderivative 0x08ef /* U+2202 PARTIAL DIFFERENTIAL */ +#define XK_function 0x08f6 /* U+0192 LATIN SMALL LETTER F WITH HOOK */ +#define XK_leftarrow 0x08fb /* U+2190 LEFTWARDS ARROW */ +#define XK_uparrow 0x08fc /* U+2191 UPWARDS ARROW */ +#define XK_rightarrow 0x08fd /* U+2192 RIGHTWARDS ARROW */ +#define XK_downarrow 0x08fe /* U+2193 DOWNWARDS ARROW */ +#endif /* XK_TECHNICAL */ /* * Special @@ -1392,31 +1386,31 @@ SOFTWARE. */ #ifdef XK_SPECIAL -#define XK_blank 0x09df -#define XK_soliddiamond 0x09e0 /* U+25C6 BLACK DIAMOND */ -#define XK_checkerboard 0x09e1 /* U+2592 MEDIUM SHADE */ -#define XK_ht 0x09e2 /* U+2409 SYMBOL FOR HORIZONTAL TABULATION */ -#define XK_ff 0x09e3 /* U+240C SYMBOL FOR FORM FEED */ -#define XK_cr 0x09e4 /* U+240D SYMBOL FOR CARRIAGE RETURN */ -#define XK_lf 0x09e5 /* U+240A SYMBOL FOR LINE FEED */ -#define XK_nl 0x09e8 /* U+2424 SYMBOL FOR NEWLINE */ -#define XK_vt 0x09e9 /* U+240B SYMBOL FOR VERTICAL TABULATION */ -#define XK_lowrightcorner 0x09ea /* U+2518 BOX DRAWINGS LIGHT UP AND LEFT */ -#define XK_uprightcorner 0x09eb /* U+2510 BOX DRAWINGS LIGHT DOWN AND LEFT */ -#define XK_upleftcorner 0x09ec /* U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT */ -#define XK_lowleftcorner 0x09ed /* U+2514 BOX DRAWINGS LIGHT UP AND RIGHT */ -#define XK_crossinglines 0x09ee /* U+253C BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ -#define XK_horizlinescan1 0x09ef /* U+23BA HORIZONTAL SCAN LINE-1 */ -#define XK_horizlinescan3 0x09f0 /* U+23BB HORIZONTAL SCAN LINE-3 */ -#define XK_horizlinescan5 0x09f1 /* U+2500 BOX DRAWINGS LIGHT HORIZONTAL */ -#define XK_horizlinescan7 0x09f2 /* U+23BC HORIZONTAL SCAN LINE-7 */ -#define XK_horizlinescan9 0x09f3 /* U+23BD HORIZONTAL SCAN LINE-9 */ -#define XK_leftt 0x09f4 /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ -#define XK_rightt 0x09f5 /* U+2524 BOX DRAWINGS LIGHT VERTICAL AND LEFT */ -#define XK_bott 0x09f6 /* U+2534 BOX DRAWINGS LIGHT UP AND HORIZONTAL */ -#define XK_topt 0x09f7 /* U+252C BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ -#define XK_vertbar 0x09f8 /* U+2502 BOX DRAWINGS LIGHT VERTICAL */ -#endif /* XK_SPECIAL */ +#define XK_blank 0x09df +#define XK_soliddiamond 0x09e0 /* U+25C6 BLACK DIAMOND */ +#define XK_checkerboard 0x09e1 /* U+2592 MEDIUM SHADE */ +#define XK_ht 0x09e2 /* U+2409 SYMBOL FOR HORIZONTAL TABULATION */ +#define XK_ff 0x09e3 /* U+240C SYMBOL FOR FORM FEED */ +#define XK_cr 0x09e4 /* U+240D SYMBOL FOR CARRIAGE RETURN */ +#define XK_lf 0x09e5 /* U+240A SYMBOL FOR LINE FEED */ +#define XK_nl 0x09e8 /* U+2424 SYMBOL FOR NEWLINE */ +#define XK_vt 0x09e9 /* U+240B SYMBOL FOR VERTICAL TABULATION */ +#define XK_lowrightcorner 0x09ea /* U+2518 BOX DRAWINGS LIGHT UP AND LEFT */ +#define XK_uprightcorner 0x09eb /* U+2510 BOX DRAWINGS LIGHT DOWN AND LEFT */ +#define XK_upleftcorner 0x09ec /* U+250C BOX DRAWINGS LIGHT DOWN AND RIGHT */ +#define XK_lowleftcorner 0x09ed /* U+2514 BOX DRAWINGS LIGHT UP AND RIGHT */ +#define XK_crossinglines 0x09ee /* U+253C BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ +#define XK_horizlinescan1 0x09ef /* U+23BA HORIZONTAL SCAN LINE-1 */ +#define XK_horizlinescan3 0x09f0 /* U+23BB HORIZONTAL SCAN LINE-3 */ +#define XK_horizlinescan5 0x09f1 /* U+2500 BOX DRAWINGS LIGHT HORIZONTAL */ +#define XK_horizlinescan7 0x09f2 /* U+23BC HORIZONTAL SCAN LINE-7 */ +#define XK_horizlinescan9 0x09f3 /* U+23BD HORIZONTAL SCAN LINE-9 */ +#define XK_leftt 0x09f4 /* U+251C BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ +#define XK_rightt 0x09f5 /* U+2524 BOX DRAWINGS LIGHT VERTICAL AND LEFT */ +#define XK_bott 0x09f6 /* U+2534 BOX DRAWINGS LIGHT UP AND HORIZONTAL */ +#define XK_topt 0x09f7 /* U+252C BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ +#define XK_vertbar 0x09f8 /* U+2502 BOX DRAWINGS LIGHT VERTICAL */ +#endif /* XK_SPECIAL */ /* * Publishing @@ -1426,90 +1420,90 @@ SOFTWARE. */ #ifdef XK_PUBLISHING -#define XK_emspace 0x0aa1 /* U+2003 EM SPACE */ -#define XK_enspace 0x0aa2 /* U+2002 EN SPACE */ -#define XK_em3space 0x0aa3 /* U+2004 THREE-PER-EM SPACE */ -#define XK_em4space 0x0aa4 /* U+2005 FOUR-PER-EM SPACE */ -#define XK_digitspace 0x0aa5 /* U+2007 FIGURE SPACE */ -#define XK_punctspace 0x0aa6 /* U+2008 PUNCTUATION SPACE */ -#define XK_thinspace 0x0aa7 /* U+2009 THIN SPACE */ -#define XK_hairspace 0x0aa8 /* U+200A HAIR SPACE */ -#define XK_emdash 0x0aa9 /* U+2014 EM DASH */ -#define XK_endash 0x0aaa /* U+2013 EN DASH */ -#define XK_signifblank 0x0aac /*(U+2423 OPEN BOX)*/ -#define XK_ellipsis 0x0aae /* U+2026 HORIZONTAL ELLIPSIS */ -#define XK_doubbaselinedot 0x0aaf /* U+2025 TWO DOT LEADER */ -#define XK_onethird 0x0ab0 /* U+2153 VULGAR FRACTION ONE THIRD */ -#define XK_twothirds 0x0ab1 /* U+2154 VULGAR FRACTION TWO THIRDS */ -#define XK_onefifth 0x0ab2 /* U+2155 VULGAR FRACTION ONE FIFTH */ -#define XK_twofifths 0x0ab3 /* U+2156 VULGAR FRACTION TWO FIFTHS */ -#define XK_threefifths 0x0ab4 /* U+2157 VULGAR FRACTION THREE FIFTHS */ -#define XK_fourfifths 0x0ab5 /* U+2158 VULGAR FRACTION FOUR FIFTHS */ -#define XK_onesixth 0x0ab6 /* U+2159 VULGAR FRACTION ONE SIXTH */ -#define XK_fivesixths 0x0ab7 /* U+215A VULGAR FRACTION FIVE SIXTHS */ -#define XK_careof 0x0ab8 /* U+2105 CARE OF */ -#define XK_figdash 0x0abb /* U+2012 FIGURE DASH */ -#define XK_leftanglebracket 0x0abc /*(U+27E8 MATHEMATICAL LEFT ANGLE BRACKET)*/ -#define XK_decimalpoint 0x0abd /*(U+002E FULL STOP)*/ -#define XK_rightanglebracket 0x0abe /*(U+27E9 MATHEMATICAL RIGHT ANGLE BRACKET)*/ -#define XK_marker 0x0abf -#define XK_oneeighth 0x0ac3 /* U+215B VULGAR FRACTION ONE EIGHTH */ -#define XK_threeeighths 0x0ac4 /* U+215C VULGAR FRACTION THREE EIGHTHS */ -#define XK_fiveeighths 0x0ac5 /* U+215D VULGAR FRACTION FIVE EIGHTHS */ -#define XK_seveneighths 0x0ac6 /* U+215E VULGAR FRACTION SEVEN EIGHTHS */ -#define XK_trademark 0x0ac9 /* U+2122 TRADE MARK SIGN */ -#define XK_signaturemark 0x0aca /*(U+2613 SALTIRE)*/ -#define XK_trademarkincircle 0x0acb -#define XK_leftopentriangle 0x0acc /*(U+25C1 WHITE LEFT-POINTING TRIANGLE)*/ -#define XK_rightopentriangle 0x0acd /*(U+25B7 WHITE RIGHT-POINTING TRIANGLE)*/ -#define XK_emopencircle 0x0ace /*(U+25CB WHITE CIRCLE)*/ -#define XK_emopenrectangle 0x0acf /*(U+25AF WHITE VERTICAL RECTANGLE)*/ -#define XK_leftsinglequotemark 0x0ad0 /* U+2018 LEFT SINGLE QUOTATION MARK */ -#define XK_rightsinglequotemark 0x0ad1 /* U+2019 RIGHT SINGLE QUOTATION MARK */ -#define XK_leftdoublequotemark 0x0ad2 /* U+201C LEFT DOUBLE QUOTATION MARK */ -#define XK_rightdoublequotemark 0x0ad3 /* U+201D RIGHT DOUBLE QUOTATION MARK */ -#define XK_prescription 0x0ad4 /* U+211E PRESCRIPTION TAKE */ -#define XK_permille 0x0ad5 /* U+2030 PER MILLE SIGN */ -#define XK_minutes 0x0ad6 /* U+2032 PRIME */ -#define XK_seconds 0x0ad7 /* U+2033 DOUBLE PRIME */ -#define XK_latincross 0x0ad9 /* U+271D LATIN CROSS */ -#define XK_hexagram 0x0ada -#define XK_filledrectbullet 0x0adb /*(U+25AC BLACK RECTANGLE)*/ -#define XK_filledlefttribullet 0x0adc /*(U+25C0 BLACK LEFT-POINTING TRIANGLE)*/ -#define XK_filledrighttribullet 0x0add /*(U+25B6 BLACK RIGHT-POINTING TRIANGLE)*/ -#define XK_emfilledcircle 0x0ade /*(U+25CF BLACK CIRCLE)*/ -#define XK_emfilledrect 0x0adf /*(U+25AE BLACK VERTICAL RECTANGLE)*/ -#define XK_enopencircbullet 0x0ae0 /*(U+25E6 WHITE BULLET)*/ -#define XK_enopensquarebullet 0x0ae1 /*(U+25AB WHITE SMALL SQUARE)*/ -#define XK_openrectbullet 0x0ae2 /*(U+25AD WHITE RECTANGLE)*/ -#define XK_opentribulletup 0x0ae3 /*(U+25B3 WHITE UP-POINTING TRIANGLE)*/ -#define XK_opentribulletdown 0x0ae4 /*(U+25BD WHITE DOWN-POINTING TRIANGLE)*/ -#define XK_openstar 0x0ae5 /*(U+2606 WHITE STAR)*/ -#define XK_enfilledcircbullet 0x0ae6 /*(U+2022 BULLET)*/ -#define XK_enfilledsqbullet 0x0ae7 /*(U+25AA BLACK SMALL SQUARE)*/ -#define XK_filledtribulletup 0x0ae8 /*(U+25B2 BLACK UP-POINTING TRIANGLE)*/ -#define XK_filledtribulletdown 0x0ae9 /*(U+25BC BLACK DOWN-POINTING TRIANGLE)*/ -#define XK_leftpointer 0x0aea /*(U+261C WHITE LEFT POINTING INDEX)*/ -#define XK_rightpointer 0x0aeb /*(U+261E WHITE RIGHT POINTING INDEX)*/ -#define XK_club 0x0aec /* U+2663 BLACK CLUB SUIT */ -#define XK_diamond 0x0aed /* U+2666 BLACK DIAMOND SUIT */ -#define XK_heart 0x0aee /* U+2665 BLACK HEART SUIT */ -#define XK_maltesecross 0x0af0 /* U+2720 MALTESE CROSS */ -#define XK_dagger 0x0af1 /* U+2020 DAGGER */ -#define XK_doubledagger 0x0af2 /* U+2021 DOUBLE DAGGER */ -#define XK_checkmark 0x0af3 /* U+2713 CHECK MARK */ -#define XK_ballotcross 0x0af4 /* U+2717 BALLOT X */ -#define XK_musicalsharp 0x0af5 /* U+266F MUSIC SHARP SIGN */ -#define XK_musicalflat 0x0af6 /* U+266D MUSIC FLAT SIGN */ -#define XK_malesymbol 0x0af7 /* U+2642 MALE SIGN */ -#define XK_femalesymbol 0x0af8 /* U+2640 FEMALE SIGN */ -#define XK_telephone 0x0af9 /* U+260E BLACK TELEPHONE */ -#define XK_telephonerecorder 0x0afa /* U+2315 TELEPHONE RECORDER */ -#define XK_phonographcopyright 0x0afb /* U+2117 SOUND RECORDING COPYRIGHT */ -#define XK_caret 0x0afc /* U+2038 CARET */ -#define XK_singlelowquotemark 0x0afd /* U+201A SINGLE LOW-9 QUOTATION MARK */ -#define XK_doublelowquotemark 0x0afe /* U+201E DOUBLE LOW-9 QUOTATION MARK */ -#define XK_cursor 0x0aff +#define XK_emspace 0x0aa1 /* U+2003 EM SPACE */ +#define XK_enspace 0x0aa2 /* U+2002 EN SPACE */ +#define XK_em3space 0x0aa3 /* U+2004 THREE-PER-EM SPACE */ +#define XK_em4space 0x0aa4 /* U+2005 FOUR-PER-EM SPACE */ +#define XK_digitspace 0x0aa5 /* U+2007 FIGURE SPACE */ +#define XK_punctspace 0x0aa6 /* U+2008 PUNCTUATION SPACE */ +#define XK_thinspace 0x0aa7 /* U+2009 THIN SPACE */ +#define XK_hairspace 0x0aa8 /* U+200A HAIR SPACE */ +#define XK_emdash 0x0aa9 /* U+2014 EM DASH */ +#define XK_endash 0x0aaa /* U+2013 EN DASH */ +#define XK_signifblank 0x0aac /*(U+2423 OPEN BOX)*/ +#define XK_ellipsis 0x0aae /* U+2026 HORIZONTAL ELLIPSIS */ +#define XK_doubbaselinedot 0x0aaf /* U+2025 TWO DOT LEADER */ +#define XK_onethird 0x0ab0 /* U+2153 VULGAR FRACTION ONE THIRD */ +#define XK_twothirds 0x0ab1 /* U+2154 VULGAR FRACTION TWO THIRDS */ +#define XK_onefifth 0x0ab2 /* U+2155 VULGAR FRACTION ONE FIFTH */ +#define XK_twofifths 0x0ab3 /* U+2156 VULGAR FRACTION TWO FIFTHS */ +#define XK_threefifths 0x0ab4 /* U+2157 VULGAR FRACTION THREE FIFTHS */ +#define XK_fourfifths 0x0ab5 /* U+2158 VULGAR FRACTION FOUR FIFTHS */ +#define XK_onesixth 0x0ab6 /* U+2159 VULGAR FRACTION ONE SIXTH */ +#define XK_fivesixths 0x0ab7 /* U+215A VULGAR FRACTION FIVE SIXTHS */ +#define XK_careof 0x0ab8 /* U+2105 CARE OF */ +#define XK_figdash 0x0abb /* U+2012 FIGURE DASH */ +#define XK_leftanglebracket 0x0abc /*(U+27E8 MATHEMATICAL LEFT ANGLE BRACKET)*/ +#define XK_decimalpoint 0x0abd /*(U+002E FULL STOP)*/ +#define XK_rightanglebracket 0x0abe /*(U+27E9 MATHEMATICAL RIGHT ANGLE BRACKET)*/ +#define XK_marker 0x0abf +#define XK_oneeighth 0x0ac3 /* U+215B VULGAR FRACTION ONE EIGHTH */ +#define XK_threeeighths 0x0ac4 /* U+215C VULGAR FRACTION THREE EIGHTHS */ +#define XK_fiveeighths 0x0ac5 /* U+215D VULGAR FRACTION FIVE EIGHTHS */ +#define XK_seveneighths 0x0ac6 /* U+215E VULGAR FRACTION SEVEN EIGHTHS */ +#define XK_trademark 0x0ac9 /* U+2122 TRADE MARK SIGN */ +#define XK_signaturemark 0x0aca /*(U+2613 SALTIRE)*/ +#define XK_trademarkincircle 0x0acb +#define XK_leftopentriangle 0x0acc /*(U+25C1 WHITE LEFT-POINTING TRIANGLE)*/ +#define XK_rightopentriangle 0x0acd /*(U+25B7 WHITE RIGHT-POINTING TRIANGLE)*/ +#define XK_emopencircle 0x0ace /*(U+25CB WHITE CIRCLE)*/ +#define XK_emopenrectangle 0x0acf /*(U+25AF WHITE VERTICAL RECTANGLE)*/ +#define XK_leftsinglequotemark 0x0ad0 /* U+2018 LEFT SINGLE QUOTATION MARK */ +#define XK_rightsinglequotemark 0x0ad1 /* U+2019 RIGHT SINGLE QUOTATION MARK */ +#define XK_leftdoublequotemark 0x0ad2 /* U+201C LEFT DOUBLE QUOTATION MARK */ +#define XK_rightdoublequotemark 0x0ad3 /* U+201D RIGHT DOUBLE QUOTATION MARK */ +#define XK_prescription 0x0ad4 /* U+211E PRESCRIPTION TAKE */ +#define XK_permille 0x0ad5 /* U+2030 PER MILLE SIGN */ +#define XK_minutes 0x0ad6 /* U+2032 PRIME */ +#define XK_seconds 0x0ad7 /* U+2033 DOUBLE PRIME */ +#define XK_latincross 0x0ad9 /* U+271D LATIN CROSS */ +#define XK_hexagram 0x0ada +#define XK_filledrectbullet 0x0adb /*(U+25AC BLACK RECTANGLE)*/ +#define XK_filledlefttribullet 0x0adc /*(U+25C0 BLACK LEFT-POINTING TRIANGLE)*/ +#define XK_filledrighttribullet 0x0add /*(U+25B6 BLACK RIGHT-POINTING TRIANGLE)*/ +#define XK_emfilledcircle 0x0ade /*(U+25CF BLACK CIRCLE)*/ +#define XK_emfilledrect 0x0adf /*(U+25AE BLACK VERTICAL RECTANGLE)*/ +#define XK_enopencircbullet 0x0ae0 /*(U+25E6 WHITE BULLET)*/ +#define XK_enopensquarebullet 0x0ae1 /*(U+25AB WHITE SMALL SQUARE)*/ +#define XK_openrectbullet 0x0ae2 /*(U+25AD WHITE RECTANGLE)*/ +#define XK_opentribulletup 0x0ae3 /*(U+25B3 WHITE UP-POINTING TRIANGLE)*/ +#define XK_opentribulletdown 0x0ae4 /*(U+25BD WHITE DOWN-POINTING TRIANGLE)*/ +#define XK_openstar 0x0ae5 /*(U+2606 WHITE STAR)*/ +#define XK_enfilledcircbullet 0x0ae6 /*(U+2022 BULLET)*/ +#define XK_enfilledsqbullet 0x0ae7 /*(U+25AA BLACK SMALL SQUARE)*/ +#define XK_filledtribulletup 0x0ae8 /*(U+25B2 BLACK UP-POINTING TRIANGLE)*/ +#define XK_filledtribulletdown 0x0ae9 /*(U+25BC BLACK DOWN-POINTING TRIANGLE)*/ +#define XK_leftpointer 0x0aea /*(U+261C WHITE LEFT POINTING INDEX)*/ +#define XK_rightpointer 0x0aeb /*(U+261E WHITE RIGHT POINTING INDEX)*/ +#define XK_club 0x0aec /* U+2663 BLACK CLUB SUIT */ +#define XK_diamond 0x0aed /* U+2666 BLACK DIAMOND SUIT */ +#define XK_heart 0x0aee /* U+2665 BLACK HEART SUIT */ +#define XK_maltesecross 0x0af0 /* U+2720 MALTESE CROSS */ +#define XK_dagger 0x0af1 /* U+2020 DAGGER */ +#define XK_doubledagger 0x0af2 /* U+2021 DOUBLE DAGGER */ +#define XK_checkmark 0x0af3 /* U+2713 CHECK MARK */ +#define XK_ballotcross 0x0af4 /* U+2717 BALLOT X */ +#define XK_musicalsharp 0x0af5 /* U+266F MUSIC SHARP SIGN */ +#define XK_musicalflat 0x0af6 /* U+266D MUSIC FLAT SIGN */ +#define XK_malesymbol 0x0af7 /* U+2642 MALE SIGN */ +#define XK_femalesymbol 0x0af8 /* U+2640 FEMALE SIGN */ +#define XK_telephone 0x0af9 /* U+260E BLACK TELEPHONE */ +#define XK_telephonerecorder 0x0afa /* U+2315 TELEPHONE RECORDER */ +#define XK_phonographcopyright 0x0afb /* U+2117 SOUND RECORDING COPYRIGHT */ +#define XK_caret 0x0afc /* U+2038 CARET */ +#define XK_singlelowquotemark 0x0afd /* U+201A SINGLE LOW-9 QUOTATION MARK */ +#define XK_doublelowquotemark 0x0afe /* U+201E DOUBLE LOW-9 QUOTATION MARK */ +#define XK_cursor 0x0aff #endif /* XK_PUBLISHING */ /* @@ -1518,26 +1512,26 @@ SOFTWARE. */ #ifdef XK_APL -#define XK_leftcaret 0x0ba3 /*(U+003C LESS-THAN SIGN)*/ -#define XK_rightcaret 0x0ba6 /*(U+003E GREATER-THAN SIGN)*/ -#define XK_downcaret 0x0ba8 /*(U+2228 LOGICAL OR)*/ -#define XK_upcaret 0x0ba9 /*(U+2227 LOGICAL AND)*/ -#define XK_overbar 0x0bc0 /*(U+00AF MACRON)*/ -#define XK_downtack 0x0bc2 /* U+22A4 DOWN TACK */ -#define XK_upshoe 0x0bc3 /*(U+2229 INTERSECTION)*/ -#define XK_downstile 0x0bc4 /* U+230A LEFT FLOOR */ -#define XK_underbar 0x0bc6 /*(U+005F LOW LINE)*/ -#define XK_jot 0x0bca /* U+2218 RING OPERATOR */ -#define XK_quad 0x0bcc /* U+2395 APL FUNCTIONAL SYMBOL QUAD */ -#define XK_uptack 0x0bce /* U+22A5 UP TACK */ -#define XK_circle 0x0bcf /* U+25CB WHITE CIRCLE */ -#define XK_upstile 0x0bd3 /* U+2308 LEFT CEILING */ -#define XK_downshoe 0x0bd6 /*(U+222A UNION)*/ -#define XK_rightshoe 0x0bd8 /*(U+2283 SUPERSET OF)*/ -#define XK_leftshoe 0x0bda /*(U+2282 SUBSET OF)*/ -#define XK_lefttack 0x0bdc /* U+22A3 LEFT TACK */ -#define XK_righttack 0x0bfc /* U+22A2 RIGHT TACK */ -#endif /* XK_APL */ +#define XK_leftcaret 0x0ba3 /*(U+003C LESS-THAN SIGN)*/ +#define XK_rightcaret 0x0ba6 /*(U+003E GREATER-THAN SIGN)*/ +#define XK_downcaret 0x0ba8 /*(U+2228 LOGICAL OR)*/ +#define XK_upcaret 0x0ba9 /*(U+2227 LOGICAL AND)*/ +#define XK_overbar 0x0bc0 /*(U+00AF MACRON)*/ +#define XK_downtack 0x0bc2 /* U+22A4 DOWN TACK */ +#define XK_upshoe 0x0bc3 /*(U+2229 INTERSECTION)*/ +#define XK_downstile 0x0bc4 /* U+230A LEFT FLOOR */ +#define XK_underbar 0x0bc6 /*(U+005F LOW LINE)*/ +#define XK_jot 0x0bca /* U+2218 RING OPERATOR */ +#define XK_quad 0x0bcc /* U+2395 APL FUNCTIONAL SYMBOL QUAD */ +#define XK_uptack 0x0bce /* U+22A5 UP TACK */ +#define XK_circle 0x0bcf /* U+25CB WHITE CIRCLE */ +#define XK_upstile 0x0bd3 /* U+2308 LEFT CEILING */ +#define XK_downshoe 0x0bd6 /*(U+222A UNION)*/ +#define XK_rightshoe 0x0bd8 /*(U+2283 SUPERSET OF)*/ +#define XK_leftshoe 0x0bda /*(U+2282 SUBSET OF)*/ +#define XK_lefttack 0x0bdc /* U+22A3 LEFT TACK */ +#define XK_righttack 0x0bfc /* U+22A2 RIGHT TACK */ +#endif /* XK_APL */ /* * Hebrew @@ -1545,47 +1539,47 @@ SOFTWARE. */ #ifdef XK_HEBREW -#define XK_hebrew_doublelowline 0x0cdf /* U+2017 DOUBLE LOW LINE */ -#define XK_hebrew_aleph 0x0ce0 /* U+05D0 HEBREW LETTER ALEF */ -#define XK_hebrew_bet 0x0ce1 /* U+05D1 HEBREW LETTER BET */ -#define XK_hebrew_beth 0x0ce1 /* deprecated */ -#define XK_hebrew_gimel 0x0ce2 /* U+05D2 HEBREW LETTER GIMEL */ -#define XK_hebrew_gimmel 0x0ce2 /* deprecated */ -#define XK_hebrew_dalet 0x0ce3 /* U+05D3 HEBREW LETTER DALET */ -#define XK_hebrew_daleth 0x0ce3 /* deprecated */ -#define XK_hebrew_he 0x0ce4 /* U+05D4 HEBREW LETTER HE */ -#define XK_hebrew_waw 0x0ce5 /* U+05D5 HEBREW LETTER VAV */ -#define XK_hebrew_zain 0x0ce6 /* U+05D6 HEBREW LETTER ZAYIN */ -#define XK_hebrew_zayin 0x0ce6 /* deprecated */ -#define XK_hebrew_chet 0x0ce7 /* U+05D7 HEBREW LETTER HET */ -#define XK_hebrew_het 0x0ce7 /* deprecated */ -#define XK_hebrew_tet 0x0ce8 /* U+05D8 HEBREW LETTER TET */ -#define XK_hebrew_teth 0x0ce8 /* deprecated */ -#define XK_hebrew_yod 0x0ce9 /* U+05D9 HEBREW LETTER YOD */ -#define XK_hebrew_finalkaph 0x0cea /* U+05DA HEBREW LETTER FINAL KAF */ -#define XK_hebrew_kaph 0x0ceb /* U+05DB HEBREW LETTER KAF */ -#define XK_hebrew_lamed 0x0cec /* U+05DC HEBREW LETTER LAMED */ -#define XK_hebrew_finalmem 0x0ced /* U+05DD HEBREW LETTER FINAL MEM */ -#define XK_hebrew_mem 0x0cee /* U+05DE HEBREW LETTER MEM */ -#define XK_hebrew_finalnun 0x0cef /* U+05DF HEBREW LETTER FINAL NUN */ -#define XK_hebrew_nun 0x0cf0 /* U+05E0 HEBREW LETTER NUN */ -#define XK_hebrew_samech 0x0cf1 /* U+05E1 HEBREW LETTER SAMEKH */ -#define XK_hebrew_samekh 0x0cf1 /* deprecated */ -#define XK_hebrew_ayin 0x0cf2 /* U+05E2 HEBREW LETTER AYIN */ -#define XK_hebrew_finalpe 0x0cf3 /* U+05E3 HEBREW LETTER FINAL PE */ -#define XK_hebrew_pe 0x0cf4 /* U+05E4 HEBREW LETTER PE */ -#define XK_hebrew_finalzade 0x0cf5 /* U+05E5 HEBREW LETTER FINAL TSADI */ -#define XK_hebrew_finalzadi 0x0cf5 /* deprecated */ -#define XK_hebrew_zade 0x0cf6 /* U+05E6 HEBREW LETTER TSADI */ -#define XK_hebrew_zadi 0x0cf6 /* deprecated */ -#define XK_hebrew_qoph 0x0cf7 /* U+05E7 HEBREW LETTER QOF */ -#define XK_hebrew_kuf 0x0cf7 /* deprecated */ -#define XK_hebrew_resh 0x0cf8 /* U+05E8 HEBREW LETTER RESH */ -#define XK_hebrew_shin 0x0cf9 /* U+05E9 HEBREW LETTER SHIN */ -#define XK_hebrew_taw 0x0cfa /* U+05EA HEBREW LETTER TAV */ -#define XK_hebrew_taf 0x0cfa /* deprecated */ -#define XK_Hebrew_switch 0xff7e /* Alias for mode_switch */ -#endif /* XK_HEBREW */ +#define XK_hebrew_doublelowline 0x0cdf /* U+2017 DOUBLE LOW LINE */ +#define XK_hebrew_aleph 0x0ce0 /* U+05D0 HEBREW LETTER ALEF */ +#define XK_hebrew_bet 0x0ce1 /* U+05D1 HEBREW LETTER BET */ +#define XK_hebrew_beth 0x0ce1 /* deprecated */ +#define XK_hebrew_gimel 0x0ce2 /* U+05D2 HEBREW LETTER GIMEL */ +#define XK_hebrew_gimmel 0x0ce2 /* deprecated */ +#define XK_hebrew_dalet 0x0ce3 /* U+05D3 HEBREW LETTER DALET */ +#define XK_hebrew_daleth 0x0ce3 /* deprecated */ +#define XK_hebrew_he 0x0ce4 /* U+05D4 HEBREW LETTER HE */ +#define XK_hebrew_waw 0x0ce5 /* U+05D5 HEBREW LETTER VAV */ +#define XK_hebrew_zain 0x0ce6 /* U+05D6 HEBREW LETTER ZAYIN */ +#define XK_hebrew_zayin 0x0ce6 /* deprecated */ +#define XK_hebrew_chet 0x0ce7 /* U+05D7 HEBREW LETTER HET */ +#define XK_hebrew_het 0x0ce7 /* deprecated */ +#define XK_hebrew_tet 0x0ce8 /* U+05D8 HEBREW LETTER TET */ +#define XK_hebrew_teth 0x0ce8 /* deprecated */ +#define XK_hebrew_yod 0x0ce9 /* U+05D9 HEBREW LETTER YOD */ +#define XK_hebrew_finalkaph 0x0cea /* U+05DA HEBREW LETTER FINAL KAF */ +#define XK_hebrew_kaph 0x0ceb /* U+05DB HEBREW LETTER KAF */ +#define XK_hebrew_lamed 0x0cec /* U+05DC HEBREW LETTER LAMED */ +#define XK_hebrew_finalmem 0x0ced /* U+05DD HEBREW LETTER FINAL MEM */ +#define XK_hebrew_mem 0x0cee /* U+05DE HEBREW LETTER MEM */ +#define XK_hebrew_finalnun 0x0cef /* U+05DF HEBREW LETTER FINAL NUN */ +#define XK_hebrew_nun 0x0cf0 /* U+05E0 HEBREW LETTER NUN */ +#define XK_hebrew_samech 0x0cf1 /* U+05E1 HEBREW LETTER SAMEKH */ +#define XK_hebrew_samekh 0x0cf1 /* deprecated */ +#define XK_hebrew_ayin 0x0cf2 /* U+05E2 HEBREW LETTER AYIN */ +#define XK_hebrew_finalpe 0x0cf3 /* U+05E3 HEBREW LETTER FINAL PE */ +#define XK_hebrew_pe 0x0cf4 /* U+05E4 HEBREW LETTER PE */ +#define XK_hebrew_finalzade 0x0cf5 /* U+05E5 HEBREW LETTER FINAL TSADI */ +#define XK_hebrew_finalzadi 0x0cf5 /* deprecated */ +#define XK_hebrew_zade 0x0cf6 /* U+05E6 HEBREW LETTER TSADI */ +#define XK_hebrew_zadi 0x0cf6 /* deprecated */ +#define XK_hebrew_qoph 0x0cf7 /* U+05E7 HEBREW LETTER QOF */ +#define XK_hebrew_kuf 0x0cf7 /* deprecated */ +#define XK_hebrew_resh 0x0cf8 /* U+05E8 HEBREW LETTER RESH */ +#define XK_hebrew_shin 0x0cf9 /* U+05E9 HEBREW LETTER SHIN */ +#define XK_hebrew_taw 0x0cfa /* U+05EA HEBREW LETTER TAV */ +#define XK_hebrew_taf 0x0cfa /* deprecated */ +#define XK_Hebrew_switch 0xff7e /* Alias for mode_switch */ +#endif /* XK_HEBREW */ /* * Thai @@ -1593,91 +1587,91 @@ SOFTWARE. */ #ifdef XK_THAI -#define XK_Thai_kokai 0x0da1 /* U+0E01 THAI CHARACTER KO KAI */ -#define XK_Thai_khokhai 0x0da2 /* U+0E02 THAI CHARACTER KHO KHAI */ -#define XK_Thai_khokhuat 0x0da3 /* U+0E03 THAI CHARACTER KHO KHUAT */ -#define XK_Thai_khokhwai 0x0da4 /* U+0E04 THAI CHARACTER KHO KHWAI */ -#define XK_Thai_khokhon 0x0da5 /* U+0E05 THAI CHARACTER KHO KHON */ -#define XK_Thai_khorakhang 0x0da6 /* U+0E06 THAI CHARACTER KHO RAKHANG */ -#define XK_Thai_ngongu 0x0da7 /* U+0E07 THAI CHARACTER NGO NGU */ -#define XK_Thai_chochan 0x0da8 /* U+0E08 THAI CHARACTER CHO CHAN */ -#define XK_Thai_choching 0x0da9 /* U+0E09 THAI CHARACTER CHO CHING */ -#define XK_Thai_chochang 0x0daa /* U+0E0A THAI CHARACTER CHO CHANG */ -#define XK_Thai_soso 0x0dab /* U+0E0B THAI CHARACTER SO SO */ -#define XK_Thai_chochoe 0x0dac /* U+0E0C THAI CHARACTER CHO CHOE */ -#define XK_Thai_yoying 0x0dad /* U+0E0D THAI CHARACTER YO YING */ -#define XK_Thai_dochada 0x0dae /* U+0E0E THAI CHARACTER DO CHADA */ -#define XK_Thai_topatak 0x0daf /* U+0E0F THAI CHARACTER TO PATAK */ -#define XK_Thai_thothan 0x0db0 /* U+0E10 THAI CHARACTER THO THAN */ -#define XK_Thai_thonangmontho 0x0db1 /* U+0E11 THAI CHARACTER THO NANGMONTHO */ -#define XK_Thai_thophuthao 0x0db2 /* U+0E12 THAI CHARACTER THO PHUTHAO */ -#define XK_Thai_nonen 0x0db3 /* U+0E13 THAI CHARACTER NO NEN */ -#define XK_Thai_dodek 0x0db4 /* U+0E14 THAI CHARACTER DO DEK */ -#define XK_Thai_totao 0x0db5 /* U+0E15 THAI CHARACTER TO TAO */ -#define XK_Thai_thothung 0x0db6 /* U+0E16 THAI CHARACTER THO THUNG */ -#define XK_Thai_thothahan 0x0db7 /* U+0E17 THAI CHARACTER THO THAHAN */ -#define XK_Thai_thothong 0x0db8 /* U+0E18 THAI CHARACTER THO THONG */ -#define XK_Thai_nonu 0x0db9 /* U+0E19 THAI CHARACTER NO NU */ -#define XK_Thai_bobaimai 0x0dba /* U+0E1A THAI CHARACTER BO BAIMAI */ -#define XK_Thai_popla 0x0dbb /* U+0E1B THAI CHARACTER PO PLA */ -#define XK_Thai_phophung 0x0dbc /* U+0E1C THAI CHARACTER PHO PHUNG */ -#define XK_Thai_fofa 0x0dbd /* U+0E1D THAI CHARACTER FO FA */ -#define XK_Thai_phophan 0x0dbe /* U+0E1E THAI CHARACTER PHO PHAN */ -#define XK_Thai_fofan 0x0dbf /* U+0E1F THAI CHARACTER FO FAN */ -#define XK_Thai_phosamphao 0x0dc0 /* U+0E20 THAI CHARACTER PHO SAMPHAO */ -#define XK_Thai_moma 0x0dc1 /* U+0E21 THAI CHARACTER MO MA */ -#define XK_Thai_yoyak 0x0dc2 /* U+0E22 THAI CHARACTER YO YAK */ -#define XK_Thai_rorua 0x0dc3 /* U+0E23 THAI CHARACTER RO RUA */ -#define XK_Thai_ru 0x0dc4 /* U+0E24 THAI CHARACTER RU */ -#define XK_Thai_loling 0x0dc5 /* U+0E25 THAI CHARACTER LO LING */ -#define XK_Thai_lu 0x0dc6 /* U+0E26 THAI CHARACTER LU */ -#define XK_Thai_wowaen 0x0dc7 /* U+0E27 THAI CHARACTER WO WAEN */ -#define XK_Thai_sosala 0x0dc8 /* U+0E28 THAI CHARACTER SO SALA */ -#define XK_Thai_sorusi 0x0dc9 /* U+0E29 THAI CHARACTER SO RUSI */ -#define XK_Thai_sosua 0x0dca /* U+0E2A THAI CHARACTER SO SUA */ -#define XK_Thai_hohip 0x0dcb /* U+0E2B THAI CHARACTER HO HIP */ -#define XK_Thai_lochula 0x0dcc /* U+0E2C THAI CHARACTER LO CHULA */ -#define XK_Thai_oang 0x0dcd /* U+0E2D THAI CHARACTER O ANG */ -#define XK_Thai_honokhuk 0x0dce /* U+0E2E THAI CHARACTER HO NOKHUK */ -#define XK_Thai_paiyannoi 0x0dcf /* U+0E2F THAI CHARACTER PAIYANNOI */ -#define XK_Thai_saraa 0x0dd0 /* U+0E30 THAI CHARACTER SARA A */ -#define XK_Thai_maihanakat 0x0dd1 /* U+0E31 THAI CHARACTER MAI HAN-AKAT */ -#define XK_Thai_saraaa 0x0dd2 /* U+0E32 THAI CHARACTER SARA AA */ -#define XK_Thai_saraam 0x0dd3 /* U+0E33 THAI CHARACTER SARA AM */ -#define XK_Thai_sarai 0x0dd4 /* U+0E34 THAI CHARACTER SARA I */ -#define XK_Thai_saraii 0x0dd5 /* U+0E35 THAI CHARACTER SARA II */ -#define XK_Thai_saraue 0x0dd6 /* U+0E36 THAI CHARACTER SARA UE */ -#define XK_Thai_sarauee 0x0dd7 /* U+0E37 THAI CHARACTER SARA UEE */ -#define XK_Thai_sarau 0x0dd8 /* U+0E38 THAI CHARACTER SARA U */ -#define XK_Thai_sarauu 0x0dd9 /* U+0E39 THAI CHARACTER SARA UU */ -#define XK_Thai_phinthu 0x0dda /* U+0E3A THAI CHARACTER PHINTHU */ -#define XK_Thai_maihanakat_maitho 0x0dde -#define XK_Thai_baht 0x0ddf /* U+0E3F THAI CURRENCY SYMBOL BAHT */ -#define XK_Thai_sarae 0x0de0 /* U+0E40 THAI CHARACTER SARA E */ -#define XK_Thai_saraae 0x0de1 /* U+0E41 THAI CHARACTER SARA AE */ -#define XK_Thai_sarao 0x0de2 /* U+0E42 THAI CHARACTER SARA O */ -#define XK_Thai_saraaimaimuan 0x0de3 /* U+0E43 THAI CHARACTER SARA AI MAIMUAN */ -#define XK_Thai_saraaimaimalai 0x0de4 /* U+0E44 THAI CHARACTER SARA AI MAIMALAI */ -#define XK_Thai_lakkhangyao 0x0de5 /* U+0E45 THAI CHARACTER LAKKHANGYAO */ -#define XK_Thai_maiyamok 0x0de6 /* U+0E46 THAI CHARACTER MAIYAMOK */ -#define XK_Thai_maitaikhu 0x0de7 /* U+0E47 THAI CHARACTER MAITAIKHU */ -#define XK_Thai_maiek 0x0de8 /* U+0E48 THAI CHARACTER MAI EK */ -#define XK_Thai_maitho 0x0de9 /* U+0E49 THAI CHARACTER MAI THO */ -#define XK_Thai_maitri 0x0dea /* U+0E4A THAI CHARACTER MAI TRI */ -#define XK_Thai_maichattawa 0x0deb /* U+0E4B THAI CHARACTER MAI CHATTAWA */ -#define XK_Thai_thanthakhat 0x0dec /* U+0E4C THAI CHARACTER THANTHAKHAT */ -#define XK_Thai_nikhahit 0x0ded /* U+0E4D THAI CHARACTER NIKHAHIT */ -#define XK_Thai_leksun 0x0df0 /* U+0E50 THAI DIGIT ZERO */ -#define XK_Thai_leknung 0x0df1 /* U+0E51 THAI DIGIT ONE */ -#define XK_Thai_leksong 0x0df2 /* U+0E52 THAI DIGIT TWO */ -#define XK_Thai_leksam 0x0df3 /* U+0E53 THAI DIGIT THREE */ -#define XK_Thai_leksi 0x0df4 /* U+0E54 THAI DIGIT FOUR */ -#define XK_Thai_lekha 0x0df5 /* U+0E55 THAI DIGIT FIVE */ -#define XK_Thai_lekhok 0x0df6 /* U+0E56 THAI DIGIT SIX */ -#define XK_Thai_lekchet 0x0df7 /* U+0E57 THAI DIGIT SEVEN */ -#define XK_Thai_lekpaet 0x0df8 /* U+0E58 THAI DIGIT EIGHT */ -#define XK_Thai_lekkao 0x0df9 /* U+0E59 THAI DIGIT NINE */ -#endif /* XK_THAI */ +#define XK_Thai_kokai 0x0da1 /* U+0E01 THAI CHARACTER KO KAI */ +#define XK_Thai_khokhai 0x0da2 /* U+0E02 THAI CHARACTER KHO KHAI */ +#define XK_Thai_khokhuat 0x0da3 /* U+0E03 THAI CHARACTER KHO KHUAT */ +#define XK_Thai_khokhwai 0x0da4 /* U+0E04 THAI CHARACTER KHO KHWAI */ +#define XK_Thai_khokhon 0x0da5 /* U+0E05 THAI CHARACTER KHO KHON */ +#define XK_Thai_khorakhang 0x0da6 /* U+0E06 THAI CHARACTER KHO RAKHANG */ +#define XK_Thai_ngongu 0x0da7 /* U+0E07 THAI CHARACTER NGO NGU */ +#define XK_Thai_chochan 0x0da8 /* U+0E08 THAI CHARACTER CHO CHAN */ +#define XK_Thai_choching 0x0da9 /* U+0E09 THAI CHARACTER CHO CHING */ +#define XK_Thai_chochang 0x0daa /* U+0E0A THAI CHARACTER CHO CHANG */ +#define XK_Thai_soso 0x0dab /* U+0E0B THAI CHARACTER SO SO */ +#define XK_Thai_chochoe 0x0dac /* U+0E0C THAI CHARACTER CHO CHOE */ +#define XK_Thai_yoying 0x0dad /* U+0E0D THAI CHARACTER YO YING */ +#define XK_Thai_dochada 0x0dae /* U+0E0E THAI CHARACTER DO CHADA */ +#define XK_Thai_topatak 0x0daf /* U+0E0F THAI CHARACTER TO PATAK */ +#define XK_Thai_thothan 0x0db0 /* U+0E10 THAI CHARACTER THO THAN */ +#define XK_Thai_thonangmontho 0x0db1 /* U+0E11 THAI CHARACTER THO NANGMONTHO */ +#define XK_Thai_thophuthao 0x0db2 /* U+0E12 THAI CHARACTER THO PHUTHAO */ +#define XK_Thai_nonen 0x0db3 /* U+0E13 THAI CHARACTER NO NEN */ +#define XK_Thai_dodek 0x0db4 /* U+0E14 THAI CHARACTER DO DEK */ +#define XK_Thai_totao 0x0db5 /* U+0E15 THAI CHARACTER TO TAO */ +#define XK_Thai_thothung 0x0db6 /* U+0E16 THAI CHARACTER THO THUNG */ +#define XK_Thai_thothahan 0x0db7 /* U+0E17 THAI CHARACTER THO THAHAN */ +#define XK_Thai_thothong 0x0db8 /* U+0E18 THAI CHARACTER THO THONG */ +#define XK_Thai_nonu 0x0db9 /* U+0E19 THAI CHARACTER NO NU */ +#define XK_Thai_bobaimai 0x0dba /* U+0E1A THAI CHARACTER BO BAIMAI */ +#define XK_Thai_popla 0x0dbb /* U+0E1B THAI CHARACTER PO PLA */ +#define XK_Thai_phophung 0x0dbc /* U+0E1C THAI CHARACTER PHO PHUNG */ +#define XK_Thai_fofa 0x0dbd /* U+0E1D THAI CHARACTER FO FA */ +#define XK_Thai_phophan 0x0dbe /* U+0E1E THAI CHARACTER PHO PHAN */ +#define XK_Thai_fofan 0x0dbf /* U+0E1F THAI CHARACTER FO FAN */ +#define XK_Thai_phosamphao 0x0dc0 /* U+0E20 THAI CHARACTER PHO SAMPHAO */ +#define XK_Thai_moma 0x0dc1 /* U+0E21 THAI CHARACTER MO MA */ +#define XK_Thai_yoyak 0x0dc2 /* U+0E22 THAI CHARACTER YO YAK */ +#define XK_Thai_rorua 0x0dc3 /* U+0E23 THAI CHARACTER RO RUA */ +#define XK_Thai_ru 0x0dc4 /* U+0E24 THAI CHARACTER RU */ +#define XK_Thai_loling 0x0dc5 /* U+0E25 THAI CHARACTER LO LING */ +#define XK_Thai_lu 0x0dc6 /* U+0E26 THAI CHARACTER LU */ +#define XK_Thai_wowaen 0x0dc7 /* U+0E27 THAI CHARACTER WO WAEN */ +#define XK_Thai_sosala 0x0dc8 /* U+0E28 THAI CHARACTER SO SALA */ +#define XK_Thai_sorusi 0x0dc9 /* U+0E29 THAI CHARACTER SO RUSI */ +#define XK_Thai_sosua 0x0dca /* U+0E2A THAI CHARACTER SO SUA */ +#define XK_Thai_hohip 0x0dcb /* U+0E2B THAI CHARACTER HO HIP */ +#define XK_Thai_lochula 0x0dcc /* U+0E2C THAI CHARACTER LO CHULA */ +#define XK_Thai_oang 0x0dcd /* U+0E2D THAI CHARACTER O ANG */ +#define XK_Thai_honokhuk 0x0dce /* U+0E2E THAI CHARACTER HO NOKHUK */ +#define XK_Thai_paiyannoi 0x0dcf /* U+0E2F THAI CHARACTER PAIYANNOI */ +#define XK_Thai_saraa 0x0dd0 /* U+0E30 THAI CHARACTER SARA A */ +#define XK_Thai_maihanakat 0x0dd1 /* U+0E31 THAI CHARACTER MAI HAN-AKAT */ +#define XK_Thai_saraaa 0x0dd2 /* U+0E32 THAI CHARACTER SARA AA */ +#define XK_Thai_saraam 0x0dd3 /* U+0E33 THAI CHARACTER SARA AM */ +#define XK_Thai_sarai 0x0dd4 /* U+0E34 THAI CHARACTER SARA I */ +#define XK_Thai_saraii 0x0dd5 /* U+0E35 THAI CHARACTER SARA II */ +#define XK_Thai_saraue 0x0dd6 /* U+0E36 THAI CHARACTER SARA UE */ +#define XK_Thai_sarauee 0x0dd7 /* U+0E37 THAI CHARACTER SARA UEE */ +#define XK_Thai_sarau 0x0dd8 /* U+0E38 THAI CHARACTER SARA U */ +#define XK_Thai_sarauu 0x0dd9 /* U+0E39 THAI CHARACTER SARA UU */ +#define XK_Thai_phinthu 0x0dda /* U+0E3A THAI CHARACTER PHINTHU */ +#define XK_Thai_maihanakat_maitho 0x0dde +#define XK_Thai_baht 0x0ddf /* U+0E3F THAI CURRENCY SYMBOL BAHT */ +#define XK_Thai_sarae 0x0de0 /* U+0E40 THAI CHARACTER SARA E */ +#define XK_Thai_saraae 0x0de1 /* U+0E41 THAI CHARACTER SARA AE */ +#define XK_Thai_sarao 0x0de2 /* U+0E42 THAI CHARACTER SARA O */ +#define XK_Thai_saraaimaimuan 0x0de3 /* U+0E43 THAI CHARACTER SARA AI MAIMUAN */ +#define XK_Thai_saraaimaimalai 0x0de4 /* U+0E44 THAI CHARACTER SARA AI MAIMALAI */ +#define XK_Thai_lakkhangyao 0x0de5 /* U+0E45 THAI CHARACTER LAKKHANGYAO */ +#define XK_Thai_maiyamok 0x0de6 /* U+0E46 THAI CHARACTER MAIYAMOK */ +#define XK_Thai_maitaikhu 0x0de7 /* U+0E47 THAI CHARACTER MAITAIKHU */ +#define XK_Thai_maiek 0x0de8 /* U+0E48 THAI CHARACTER MAI EK */ +#define XK_Thai_maitho 0x0de9 /* U+0E49 THAI CHARACTER MAI THO */ +#define XK_Thai_maitri 0x0dea /* U+0E4A THAI CHARACTER MAI TRI */ +#define XK_Thai_maichattawa 0x0deb /* U+0E4B THAI CHARACTER MAI CHATTAWA */ +#define XK_Thai_thanthakhat 0x0dec /* U+0E4C THAI CHARACTER THANTHAKHAT */ +#define XK_Thai_nikhahit 0x0ded /* U+0E4D THAI CHARACTER NIKHAHIT */ +#define XK_Thai_leksun 0x0df0 /* U+0E50 THAI DIGIT ZERO */ +#define XK_Thai_leknung 0x0df1 /* U+0E51 THAI DIGIT ONE */ +#define XK_Thai_leksong 0x0df2 /* U+0E52 THAI DIGIT TWO */ +#define XK_Thai_leksam 0x0df3 /* U+0E53 THAI DIGIT THREE */ +#define XK_Thai_leksi 0x0df4 /* U+0E54 THAI DIGIT FOUR */ +#define XK_Thai_lekha 0x0df5 /* U+0E55 THAI DIGIT FIVE */ +#define XK_Thai_lekhok 0x0df6 /* U+0E56 THAI DIGIT SIX */ +#define XK_Thai_lekchet 0x0df7 /* U+0E57 THAI DIGIT SEVEN */ +#define XK_Thai_lekpaet 0x0df8 /* U+0E58 THAI DIGIT EIGHT */ +#define XK_Thai_lekkao 0x0df9 /* U+0E59 THAI DIGIT NINE */ +#endif /* XK_THAI */ /* * Korean @@ -1686,127 +1680,127 @@ SOFTWARE. #ifdef XK_KOREAN -#define XK_Hangul 0xff31 /* Hangul start/stop(toggle) */ -#define XK_Hangul_Start 0xff32 /* Hangul start */ -#define XK_Hangul_End 0xff33 /* Hangul end, English start */ -#define XK_Hangul_Hanja 0xff34 /* Start Hangul->Hanja Conversion */ -#define XK_Hangul_Jamo 0xff35 /* Hangul Jamo mode */ -#define XK_Hangul_Romaja 0xff36 /* Hangul Romaja mode */ -#define XK_Hangul_Codeinput 0xff37 /* Hangul code input mode */ -#define XK_Hangul_Jeonja 0xff38 /* Jeonja mode */ -#define XK_Hangul_Banja 0xff39 /* Banja mode */ -#define XK_Hangul_PreHanja 0xff3a /* Pre Hanja conversion */ -#define XK_Hangul_PostHanja 0xff3b /* Post Hanja conversion */ -#define XK_Hangul_SingleCandidate 0xff3c /* Single candidate */ -#define XK_Hangul_MultipleCandidate 0xff3d /* Multiple candidate */ -#define XK_Hangul_PreviousCandidate 0xff3e /* Previous candidate */ -#define XK_Hangul_Special 0xff3f /* Special symbols */ -#define XK_Hangul_switch 0xff7e /* Alias for mode_switch */ +#define XK_Hangul 0xff31 /* Hangul start/stop(toggle) */ +#define XK_Hangul_Start 0xff32 /* Hangul start */ +#define XK_Hangul_End 0xff33 /* Hangul end, English start */ +#define XK_Hangul_Hanja 0xff34 /* Start Hangul->Hanja Conversion */ +#define XK_Hangul_Jamo 0xff35 /* Hangul Jamo mode */ +#define XK_Hangul_Romaja 0xff36 /* Hangul Romaja mode */ +#define XK_Hangul_Codeinput 0xff37 /* Hangul code input mode */ +#define XK_Hangul_Jeonja 0xff38 /* Jeonja mode */ +#define XK_Hangul_Banja 0xff39 /* Banja mode */ +#define XK_Hangul_PreHanja 0xff3a /* Pre Hanja conversion */ +#define XK_Hangul_PostHanja 0xff3b /* Post Hanja conversion */ +#define XK_Hangul_SingleCandidate 0xff3c /* Single candidate */ +#define XK_Hangul_MultipleCandidate 0xff3d /* Multiple candidate */ +#define XK_Hangul_PreviousCandidate 0xff3e /* Previous candidate */ +#define XK_Hangul_Special 0xff3f /* Special symbols */ +#define XK_Hangul_switch 0xff7e /* Alias for mode_switch */ /* Hangul Consonant Characters */ -#define XK_Hangul_Kiyeog 0x0ea1 -#define XK_Hangul_SsangKiyeog 0x0ea2 -#define XK_Hangul_KiyeogSios 0x0ea3 -#define XK_Hangul_Nieun 0x0ea4 -#define XK_Hangul_NieunJieuj 0x0ea5 -#define XK_Hangul_NieunHieuh 0x0ea6 -#define XK_Hangul_Dikeud 0x0ea7 -#define XK_Hangul_SsangDikeud 0x0ea8 -#define XK_Hangul_Rieul 0x0ea9 -#define XK_Hangul_RieulKiyeog 0x0eaa -#define XK_Hangul_RieulMieum 0x0eab -#define XK_Hangul_RieulPieub 0x0eac -#define XK_Hangul_RieulSios 0x0ead -#define XK_Hangul_RieulTieut 0x0eae -#define XK_Hangul_RieulPhieuf 0x0eaf -#define XK_Hangul_RieulHieuh 0x0eb0 -#define XK_Hangul_Mieum 0x0eb1 -#define XK_Hangul_Pieub 0x0eb2 -#define XK_Hangul_SsangPieub 0x0eb3 -#define XK_Hangul_PieubSios 0x0eb4 -#define XK_Hangul_Sios 0x0eb5 -#define XK_Hangul_SsangSios 0x0eb6 -#define XK_Hangul_Ieung 0x0eb7 -#define XK_Hangul_Jieuj 0x0eb8 -#define XK_Hangul_SsangJieuj 0x0eb9 -#define XK_Hangul_Cieuc 0x0eba -#define XK_Hangul_Khieuq 0x0ebb -#define XK_Hangul_Tieut 0x0ebc -#define XK_Hangul_Phieuf 0x0ebd -#define XK_Hangul_Hieuh 0x0ebe +#define XK_Hangul_Kiyeog 0x0ea1 +#define XK_Hangul_SsangKiyeog 0x0ea2 +#define XK_Hangul_KiyeogSios 0x0ea3 +#define XK_Hangul_Nieun 0x0ea4 +#define XK_Hangul_NieunJieuj 0x0ea5 +#define XK_Hangul_NieunHieuh 0x0ea6 +#define XK_Hangul_Dikeud 0x0ea7 +#define XK_Hangul_SsangDikeud 0x0ea8 +#define XK_Hangul_Rieul 0x0ea9 +#define XK_Hangul_RieulKiyeog 0x0eaa +#define XK_Hangul_RieulMieum 0x0eab +#define XK_Hangul_RieulPieub 0x0eac +#define XK_Hangul_RieulSios 0x0ead +#define XK_Hangul_RieulTieut 0x0eae +#define XK_Hangul_RieulPhieuf 0x0eaf +#define XK_Hangul_RieulHieuh 0x0eb0 +#define XK_Hangul_Mieum 0x0eb1 +#define XK_Hangul_Pieub 0x0eb2 +#define XK_Hangul_SsangPieub 0x0eb3 +#define XK_Hangul_PieubSios 0x0eb4 +#define XK_Hangul_Sios 0x0eb5 +#define XK_Hangul_SsangSios 0x0eb6 +#define XK_Hangul_Ieung 0x0eb7 +#define XK_Hangul_Jieuj 0x0eb8 +#define XK_Hangul_SsangJieuj 0x0eb9 +#define XK_Hangul_Cieuc 0x0eba +#define XK_Hangul_Khieuq 0x0ebb +#define XK_Hangul_Tieut 0x0ebc +#define XK_Hangul_Phieuf 0x0ebd +#define XK_Hangul_Hieuh 0x0ebe /* Hangul Vowel Characters */ -#define XK_Hangul_A 0x0ebf -#define XK_Hangul_AE 0x0ec0 -#define XK_Hangul_YA 0x0ec1 -#define XK_Hangul_YAE 0x0ec2 -#define XK_Hangul_EO 0x0ec3 -#define XK_Hangul_E 0x0ec4 -#define XK_Hangul_YEO 0x0ec5 -#define XK_Hangul_YE 0x0ec6 -#define XK_Hangul_O 0x0ec7 -#define XK_Hangul_WA 0x0ec8 -#define XK_Hangul_WAE 0x0ec9 -#define XK_Hangul_OE 0x0eca -#define XK_Hangul_YO 0x0ecb -#define XK_Hangul_U 0x0ecc -#define XK_Hangul_WEO 0x0ecd -#define XK_Hangul_WE 0x0ece -#define XK_Hangul_WI 0x0ecf -#define XK_Hangul_YU 0x0ed0 -#define XK_Hangul_EU 0x0ed1 -#define XK_Hangul_YI 0x0ed2 -#define XK_Hangul_I 0x0ed3 +#define XK_Hangul_A 0x0ebf +#define XK_Hangul_AE 0x0ec0 +#define XK_Hangul_YA 0x0ec1 +#define XK_Hangul_YAE 0x0ec2 +#define XK_Hangul_EO 0x0ec3 +#define XK_Hangul_E 0x0ec4 +#define XK_Hangul_YEO 0x0ec5 +#define XK_Hangul_YE 0x0ec6 +#define XK_Hangul_O 0x0ec7 +#define XK_Hangul_WA 0x0ec8 +#define XK_Hangul_WAE 0x0ec9 +#define XK_Hangul_OE 0x0eca +#define XK_Hangul_YO 0x0ecb +#define XK_Hangul_U 0x0ecc +#define XK_Hangul_WEO 0x0ecd +#define XK_Hangul_WE 0x0ece +#define XK_Hangul_WI 0x0ecf +#define XK_Hangul_YU 0x0ed0 +#define XK_Hangul_EU 0x0ed1 +#define XK_Hangul_YI 0x0ed2 +#define XK_Hangul_I 0x0ed3 /* Hangul syllable-final (JongSeong) Characters */ -#define XK_Hangul_J_Kiyeog 0x0ed4 -#define XK_Hangul_J_SsangKiyeog 0x0ed5 -#define XK_Hangul_J_KiyeogSios 0x0ed6 -#define XK_Hangul_J_Nieun 0x0ed7 -#define XK_Hangul_J_NieunJieuj 0x0ed8 -#define XK_Hangul_J_NieunHieuh 0x0ed9 -#define XK_Hangul_J_Dikeud 0x0eda -#define XK_Hangul_J_Rieul 0x0edb -#define XK_Hangul_J_RieulKiyeog 0x0edc -#define XK_Hangul_J_RieulMieum 0x0edd -#define XK_Hangul_J_RieulPieub 0x0ede -#define XK_Hangul_J_RieulSios 0x0edf -#define XK_Hangul_J_RieulTieut 0x0ee0 -#define XK_Hangul_J_RieulPhieuf 0x0ee1 -#define XK_Hangul_J_RieulHieuh 0x0ee2 -#define XK_Hangul_J_Mieum 0x0ee3 -#define XK_Hangul_J_Pieub 0x0ee4 -#define XK_Hangul_J_PieubSios 0x0ee5 -#define XK_Hangul_J_Sios 0x0ee6 -#define XK_Hangul_J_SsangSios 0x0ee7 -#define XK_Hangul_J_Ieung 0x0ee8 -#define XK_Hangul_J_Jieuj 0x0ee9 -#define XK_Hangul_J_Cieuc 0x0eea -#define XK_Hangul_J_Khieuq 0x0eeb -#define XK_Hangul_J_Tieut 0x0eec -#define XK_Hangul_J_Phieuf 0x0eed -#define XK_Hangul_J_Hieuh 0x0eee +#define XK_Hangul_J_Kiyeog 0x0ed4 +#define XK_Hangul_J_SsangKiyeog 0x0ed5 +#define XK_Hangul_J_KiyeogSios 0x0ed6 +#define XK_Hangul_J_Nieun 0x0ed7 +#define XK_Hangul_J_NieunJieuj 0x0ed8 +#define XK_Hangul_J_NieunHieuh 0x0ed9 +#define XK_Hangul_J_Dikeud 0x0eda +#define XK_Hangul_J_Rieul 0x0edb +#define XK_Hangul_J_RieulKiyeog 0x0edc +#define XK_Hangul_J_RieulMieum 0x0edd +#define XK_Hangul_J_RieulPieub 0x0ede +#define XK_Hangul_J_RieulSios 0x0edf +#define XK_Hangul_J_RieulTieut 0x0ee0 +#define XK_Hangul_J_RieulPhieuf 0x0ee1 +#define XK_Hangul_J_RieulHieuh 0x0ee2 +#define XK_Hangul_J_Mieum 0x0ee3 +#define XK_Hangul_J_Pieub 0x0ee4 +#define XK_Hangul_J_PieubSios 0x0ee5 +#define XK_Hangul_J_Sios 0x0ee6 +#define XK_Hangul_J_SsangSios 0x0ee7 +#define XK_Hangul_J_Ieung 0x0ee8 +#define XK_Hangul_J_Jieuj 0x0ee9 +#define XK_Hangul_J_Cieuc 0x0eea +#define XK_Hangul_J_Khieuq 0x0eeb +#define XK_Hangul_J_Tieut 0x0eec +#define XK_Hangul_J_Phieuf 0x0eed +#define XK_Hangul_J_Hieuh 0x0eee /* Ancient Hangul Consonant Characters */ -#define XK_Hangul_RieulYeorinHieuh 0x0eef -#define XK_Hangul_SunkyeongeumMieum 0x0ef0 -#define XK_Hangul_SunkyeongeumPieub 0x0ef1 -#define XK_Hangul_PanSios 0x0ef2 -#define XK_Hangul_KkogjiDalrinIeung 0x0ef3 -#define XK_Hangul_SunkyeongeumPhieuf 0x0ef4 -#define XK_Hangul_YeorinHieuh 0x0ef5 +#define XK_Hangul_RieulYeorinHieuh 0x0eef +#define XK_Hangul_SunkyeongeumMieum 0x0ef0 +#define XK_Hangul_SunkyeongeumPieub 0x0ef1 +#define XK_Hangul_PanSios 0x0ef2 +#define XK_Hangul_KkogjiDalrinIeung 0x0ef3 +#define XK_Hangul_SunkyeongeumPhieuf 0x0ef4 +#define XK_Hangul_YeorinHieuh 0x0ef5 /* Ancient Hangul Vowel Characters */ -#define XK_Hangul_AraeA 0x0ef6 -#define XK_Hangul_AraeAE 0x0ef7 +#define XK_Hangul_AraeA 0x0ef6 +#define XK_Hangul_AraeAE 0x0ef7 /* Ancient Hangul syllable-final (JongSeong) Characters */ -#define XK_Hangul_J_PanSios 0x0ef8 -#define XK_Hangul_J_KkogjiDalrinIeung 0x0ef9 -#define XK_Hangul_J_YeorinHieuh 0x0efa +#define XK_Hangul_J_PanSios 0x0ef8 +#define XK_Hangul_J_KkogjiDalrinIeung 0x0ef9 +#define XK_Hangul_J_YeorinHieuh 0x0efa /* Korean currency symbol */ -#define XK_Korean_Won 0x0eff /*(U+20A9 WON SIGN)*/ +#define XK_Korean_Won 0x0eff /*(U+20A9 WON SIGN)*/ #endif /* XK_KOREAN */ @@ -1815,143 +1809,143 @@ SOFTWARE. */ #ifdef XK_ARMENIAN -#define XK_Armenian_ligature_ew 0x1000587 /* U+0587 ARMENIAN SMALL LIGATURE ECH YIWN */ -#define XK_Armenian_full_stop 0x1000589 /* U+0589 ARMENIAN FULL STOP */ -#define XK_Armenian_verjaket 0x1000589 /* U+0589 ARMENIAN FULL STOP */ -#define XK_Armenian_separation_mark 0x100055d /* U+055D ARMENIAN COMMA */ -#define XK_Armenian_but 0x100055d /* U+055D ARMENIAN COMMA */ -#define XK_Armenian_hyphen 0x100058a /* U+058A ARMENIAN HYPHEN */ -#define XK_Armenian_yentamna 0x100058a /* U+058A ARMENIAN HYPHEN */ -#define XK_Armenian_exclam 0x100055c /* U+055C ARMENIAN EXCLAMATION MARK */ -#define XK_Armenian_amanak 0x100055c /* U+055C ARMENIAN EXCLAMATION MARK */ -#define XK_Armenian_accent 0x100055b /* U+055B ARMENIAN EMPHASIS MARK */ -#define XK_Armenian_shesht 0x100055b /* U+055B ARMENIAN EMPHASIS MARK */ -#define XK_Armenian_question 0x100055e /* U+055E ARMENIAN QUESTION MARK */ -#define XK_Armenian_paruyk 0x100055e /* U+055E ARMENIAN QUESTION MARK */ -#define XK_Armenian_AYB 0x1000531 /* U+0531 ARMENIAN CAPITAL LETTER AYB */ -#define XK_Armenian_ayb 0x1000561 /* U+0561 ARMENIAN SMALL LETTER AYB */ -#define XK_Armenian_BEN 0x1000532 /* U+0532 ARMENIAN CAPITAL LETTER BEN */ -#define XK_Armenian_ben 0x1000562 /* U+0562 ARMENIAN SMALL LETTER BEN */ -#define XK_Armenian_GIM 0x1000533 /* U+0533 ARMENIAN CAPITAL LETTER GIM */ -#define XK_Armenian_gim 0x1000563 /* U+0563 ARMENIAN SMALL LETTER GIM */ -#define XK_Armenian_DA 0x1000534 /* U+0534 ARMENIAN CAPITAL LETTER DA */ -#define XK_Armenian_da 0x1000564 /* U+0564 ARMENIAN SMALL LETTER DA */ -#define XK_Armenian_YECH 0x1000535 /* U+0535 ARMENIAN CAPITAL LETTER ECH */ -#define XK_Armenian_yech 0x1000565 /* U+0565 ARMENIAN SMALL LETTER ECH */ -#define XK_Armenian_ZA 0x1000536 /* U+0536 ARMENIAN CAPITAL LETTER ZA */ -#define XK_Armenian_za 0x1000566 /* U+0566 ARMENIAN SMALL LETTER ZA */ -#define XK_Armenian_E 0x1000537 /* U+0537 ARMENIAN CAPITAL LETTER EH */ -#define XK_Armenian_e 0x1000567 /* U+0567 ARMENIAN SMALL LETTER EH */ -#define XK_Armenian_AT 0x1000538 /* U+0538 ARMENIAN CAPITAL LETTER ET */ -#define XK_Armenian_at 0x1000568 /* U+0568 ARMENIAN SMALL LETTER ET */ -#define XK_Armenian_TO 0x1000539 /* U+0539 ARMENIAN CAPITAL LETTER TO */ -#define XK_Armenian_to 0x1000569 /* U+0569 ARMENIAN SMALL LETTER TO */ -#define XK_Armenian_ZHE 0x100053a /* U+053A ARMENIAN CAPITAL LETTER ZHE */ -#define XK_Armenian_zhe 0x100056a /* U+056A ARMENIAN SMALL LETTER ZHE */ -#define XK_Armenian_INI 0x100053b /* U+053B ARMENIAN CAPITAL LETTER INI */ -#define XK_Armenian_ini 0x100056b /* U+056B ARMENIAN SMALL LETTER INI */ -#define XK_Armenian_LYUN 0x100053c /* U+053C ARMENIAN CAPITAL LETTER LIWN */ -#define XK_Armenian_lyun 0x100056c /* U+056C ARMENIAN SMALL LETTER LIWN */ -#define XK_Armenian_KHE 0x100053d /* U+053D ARMENIAN CAPITAL LETTER XEH */ -#define XK_Armenian_khe 0x100056d /* U+056D ARMENIAN SMALL LETTER XEH */ -#define XK_Armenian_TSA 0x100053e /* U+053E ARMENIAN CAPITAL LETTER CA */ -#define XK_Armenian_tsa 0x100056e /* U+056E ARMENIAN SMALL LETTER CA */ -#define XK_Armenian_KEN 0x100053f /* U+053F ARMENIAN CAPITAL LETTER KEN */ -#define XK_Armenian_ken 0x100056f /* U+056F ARMENIAN SMALL LETTER KEN */ -#define XK_Armenian_HO 0x1000540 /* U+0540 ARMENIAN CAPITAL LETTER HO */ -#define XK_Armenian_ho 0x1000570 /* U+0570 ARMENIAN SMALL LETTER HO */ -#define XK_Armenian_DZA 0x1000541 /* U+0541 ARMENIAN CAPITAL LETTER JA */ -#define XK_Armenian_dza 0x1000571 /* U+0571 ARMENIAN SMALL LETTER JA */ -#define XK_Armenian_GHAT 0x1000542 /* U+0542 ARMENIAN CAPITAL LETTER GHAD */ -#define XK_Armenian_ghat 0x1000572 /* U+0572 ARMENIAN SMALL LETTER GHAD */ -#define XK_Armenian_TCHE 0x1000543 /* U+0543 ARMENIAN CAPITAL LETTER CHEH */ -#define XK_Armenian_tche 0x1000573 /* U+0573 ARMENIAN SMALL LETTER CHEH */ -#define XK_Armenian_MEN 0x1000544 /* U+0544 ARMENIAN CAPITAL LETTER MEN */ -#define XK_Armenian_men 0x1000574 /* U+0574 ARMENIAN SMALL LETTER MEN */ -#define XK_Armenian_HI 0x1000545 /* U+0545 ARMENIAN CAPITAL LETTER YI */ -#define XK_Armenian_hi 0x1000575 /* U+0575 ARMENIAN SMALL LETTER YI */ -#define XK_Armenian_NU 0x1000546 /* U+0546 ARMENIAN CAPITAL LETTER NOW */ -#define XK_Armenian_nu 0x1000576 /* U+0576 ARMENIAN SMALL LETTER NOW */ -#define XK_Armenian_SHA 0x1000547 /* U+0547 ARMENIAN CAPITAL LETTER SHA */ -#define XK_Armenian_sha 0x1000577 /* U+0577 ARMENIAN SMALL LETTER SHA */ -#define XK_Armenian_VO 0x1000548 /* U+0548 ARMENIAN CAPITAL LETTER VO */ -#define XK_Armenian_vo 0x1000578 /* U+0578 ARMENIAN SMALL LETTER VO */ -#define XK_Armenian_CHA 0x1000549 /* U+0549 ARMENIAN CAPITAL LETTER CHA */ -#define XK_Armenian_cha 0x1000579 /* U+0579 ARMENIAN SMALL LETTER CHA */ -#define XK_Armenian_PE 0x100054a /* U+054A ARMENIAN CAPITAL LETTER PEH */ -#define XK_Armenian_pe 0x100057a /* U+057A ARMENIAN SMALL LETTER PEH */ -#define XK_Armenian_JE 0x100054b /* U+054B ARMENIAN CAPITAL LETTER JHEH */ -#define XK_Armenian_je 0x100057b /* U+057B ARMENIAN SMALL LETTER JHEH */ -#define XK_Armenian_RA 0x100054c /* U+054C ARMENIAN CAPITAL LETTER RA */ -#define XK_Armenian_ra 0x100057c /* U+057C ARMENIAN SMALL LETTER RA */ -#define XK_Armenian_SE 0x100054d /* U+054D ARMENIAN CAPITAL LETTER SEH */ -#define XK_Armenian_se 0x100057d /* U+057D ARMENIAN SMALL LETTER SEH */ -#define XK_Armenian_VEV 0x100054e /* U+054E ARMENIAN CAPITAL LETTER VEW */ -#define XK_Armenian_vev 0x100057e /* U+057E ARMENIAN SMALL LETTER VEW */ -#define XK_Armenian_TYUN 0x100054f /* U+054F ARMENIAN CAPITAL LETTER TIWN */ -#define XK_Armenian_tyun 0x100057f /* U+057F ARMENIAN SMALL LETTER TIWN */ -#define XK_Armenian_RE 0x1000550 /* U+0550 ARMENIAN CAPITAL LETTER REH */ -#define XK_Armenian_re 0x1000580 /* U+0580 ARMENIAN SMALL LETTER REH */ -#define XK_Armenian_TSO 0x1000551 /* U+0551 ARMENIAN CAPITAL LETTER CO */ -#define XK_Armenian_tso 0x1000581 /* U+0581 ARMENIAN SMALL LETTER CO */ -#define XK_Armenian_VYUN 0x1000552 /* U+0552 ARMENIAN CAPITAL LETTER YIWN */ -#define XK_Armenian_vyun 0x1000582 /* U+0582 ARMENIAN SMALL LETTER YIWN */ -#define XK_Armenian_PYUR 0x1000553 /* U+0553 ARMENIAN CAPITAL LETTER PIWR */ -#define XK_Armenian_pyur 0x1000583 /* U+0583 ARMENIAN SMALL LETTER PIWR */ -#define XK_Armenian_KE 0x1000554 /* U+0554 ARMENIAN CAPITAL LETTER KEH */ -#define XK_Armenian_ke 0x1000584 /* U+0584 ARMENIAN SMALL LETTER KEH */ -#define XK_Armenian_O 0x1000555 /* U+0555 ARMENIAN CAPITAL LETTER OH */ -#define XK_Armenian_o 0x1000585 /* U+0585 ARMENIAN SMALL LETTER OH */ -#define XK_Armenian_FE 0x1000556 /* U+0556 ARMENIAN CAPITAL LETTER FEH */ -#define XK_Armenian_fe 0x1000586 /* U+0586 ARMENIAN SMALL LETTER FEH */ -#define XK_Armenian_apostrophe 0x100055a /* U+055A ARMENIAN APOSTROPHE */ -#endif /* XK_ARMENIAN */ +#define XK_Armenian_ligature_ew 0x1000587 /* U+0587 ARMENIAN SMALL LIGATURE ECH YIWN */ +#define XK_Armenian_full_stop 0x1000589 /* U+0589 ARMENIAN FULL STOP */ +#define XK_Armenian_verjaket 0x1000589 /* U+0589 ARMENIAN FULL STOP */ +#define XK_Armenian_separation_mark 0x100055d /* U+055D ARMENIAN COMMA */ +#define XK_Armenian_but 0x100055d /* U+055D ARMENIAN COMMA */ +#define XK_Armenian_hyphen 0x100058a /* U+058A ARMENIAN HYPHEN */ +#define XK_Armenian_yentamna 0x100058a /* U+058A ARMENIAN HYPHEN */ +#define XK_Armenian_exclam 0x100055c /* U+055C ARMENIAN EXCLAMATION MARK */ +#define XK_Armenian_amanak 0x100055c /* U+055C ARMENIAN EXCLAMATION MARK */ +#define XK_Armenian_accent 0x100055b /* U+055B ARMENIAN EMPHASIS MARK */ +#define XK_Armenian_shesht 0x100055b /* U+055B ARMENIAN EMPHASIS MARK */ +#define XK_Armenian_question 0x100055e /* U+055E ARMENIAN QUESTION MARK */ +#define XK_Armenian_paruyk 0x100055e /* U+055E ARMENIAN QUESTION MARK */ +#define XK_Armenian_AYB 0x1000531 /* U+0531 ARMENIAN CAPITAL LETTER AYB */ +#define XK_Armenian_ayb 0x1000561 /* U+0561 ARMENIAN SMALL LETTER AYB */ +#define XK_Armenian_BEN 0x1000532 /* U+0532 ARMENIAN CAPITAL LETTER BEN */ +#define XK_Armenian_ben 0x1000562 /* U+0562 ARMENIAN SMALL LETTER BEN */ +#define XK_Armenian_GIM 0x1000533 /* U+0533 ARMENIAN CAPITAL LETTER GIM */ +#define XK_Armenian_gim 0x1000563 /* U+0563 ARMENIAN SMALL LETTER GIM */ +#define XK_Armenian_DA 0x1000534 /* U+0534 ARMENIAN CAPITAL LETTER DA */ +#define XK_Armenian_da 0x1000564 /* U+0564 ARMENIAN SMALL LETTER DA */ +#define XK_Armenian_YECH 0x1000535 /* U+0535 ARMENIAN CAPITAL LETTER ECH */ +#define XK_Armenian_yech 0x1000565 /* U+0565 ARMENIAN SMALL LETTER ECH */ +#define XK_Armenian_ZA 0x1000536 /* U+0536 ARMENIAN CAPITAL LETTER ZA */ +#define XK_Armenian_za 0x1000566 /* U+0566 ARMENIAN SMALL LETTER ZA */ +#define XK_Armenian_E 0x1000537 /* U+0537 ARMENIAN CAPITAL LETTER EH */ +#define XK_Armenian_e 0x1000567 /* U+0567 ARMENIAN SMALL LETTER EH */ +#define XK_Armenian_AT 0x1000538 /* U+0538 ARMENIAN CAPITAL LETTER ET */ +#define XK_Armenian_at 0x1000568 /* U+0568 ARMENIAN SMALL LETTER ET */ +#define XK_Armenian_TO 0x1000539 /* U+0539 ARMENIAN CAPITAL LETTER TO */ +#define XK_Armenian_to 0x1000569 /* U+0569 ARMENIAN SMALL LETTER TO */ +#define XK_Armenian_ZHE 0x100053a /* U+053A ARMENIAN CAPITAL LETTER ZHE */ +#define XK_Armenian_zhe 0x100056a /* U+056A ARMENIAN SMALL LETTER ZHE */ +#define XK_Armenian_INI 0x100053b /* U+053B ARMENIAN CAPITAL LETTER INI */ +#define XK_Armenian_ini 0x100056b /* U+056B ARMENIAN SMALL LETTER INI */ +#define XK_Armenian_LYUN 0x100053c /* U+053C ARMENIAN CAPITAL LETTER LIWN */ +#define XK_Armenian_lyun 0x100056c /* U+056C ARMENIAN SMALL LETTER LIWN */ +#define XK_Armenian_KHE 0x100053d /* U+053D ARMENIAN CAPITAL LETTER XEH */ +#define XK_Armenian_khe 0x100056d /* U+056D ARMENIAN SMALL LETTER XEH */ +#define XK_Armenian_TSA 0x100053e /* U+053E ARMENIAN CAPITAL LETTER CA */ +#define XK_Armenian_tsa 0x100056e /* U+056E ARMENIAN SMALL LETTER CA */ +#define XK_Armenian_KEN 0x100053f /* U+053F ARMENIAN CAPITAL LETTER KEN */ +#define XK_Armenian_ken 0x100056f /* U+056F ARMENIAN SMALL LETTER KEN */ +#define XK_Armenian_HO 0x1000540 /* U+0540 ARMENIAN CAPITAL LETTER HO */ +#define XK_Armenian_ho 0x1000570 /* U+0570 ARMENIAN SMALL LETTER HO */ +#define XK_Armenian_DZA 0x1000541 /* U+0541 ARMENIAN CAPITAL LETTER JA */ +#define XK_Armenian_dza 0x1000571 /* U+0571 ARMENIAN SMALL LETTER JA */ +#define XK_Armenian_GHAT 0x1000542 /* U+0542 ARMENIAN CAPITAL LETTER GHAD */ +#define XK_Armenian_ghat 0x1000572 /* U+0572 ARMENIAN SMALL LETTER GHAD */ +#define XK_Armenian_TCHE 0x1000543 /* U+0543 ARMENIAN CAPITAL LETTER CHEH */ +#define XK_Armenian_tche 0x1000573 /* U+0573 ARMENIAN SMALL LETTER CHEH */ +#define XK_Armenian_MEN 0x1000544 /* U+0544 ARMENIAN CAPITAL LETTER MEN */ +#define XK_Armenian_men 0x1000574 /* U+0574 ARMENIAN SMALL LETTER MEN */ +#define XK_Armenian_HI 0x1000545 /* U+0545 ARMENIAN CAPITAL LETTER YI */ +#define XK_Armenian_hi 0x1000575 /* U+0575 ARMENIAN SMALL LETTER YI */ +#define XK_Armenian_NU 0x1000546 /* U+0546 ARMENIAN CAPITAL LETTER NOW */ +#define XK_Armenian_nu 0x1000576 /* U+0576 ARMENIAN SMALL LETTER NOW */ +#define XK_Armenian_SHA 0x1000547 /* U+0547 ARMENIAN CAPITAL LETTER SHA */ +#define XK_Armenian_sha 0x1000577 /* U+0577 ARMENIAN SMALL LETTER SHA */ +#define XK_Armenian_VO 0x1000548 /* U+0548 ARMENIAN CAPITAL LETTER VO */ +#define XK_Armenian_vo 0x1000578 /* U+0578 ARMENIAN SMALL LETTER VO */ +#define XK_Armenian_CHA 0x1000549 /* U+0549 ARMENIAN CAPITAL LETTER CHA */ +#define XK_Armenian_cha 0x1000579 /* U+0579 ARMENIAN SMALL LETTER CHA */ +#define XK_Armenian_PE 0x100054a /* U+054A ARMENIAN CAPITAL LETTER PEH */ +#define XK_Armenian_pe 0x100057a /* U+057A ARMENIAN SMALL LETTER PEH */ +#define XK_Armenian_JE 0x100054b /* U+054B ARMENIAN CAPITAL LETTER JHEH */ +#define XK_Armenian_je 0x100057b /* U+057B ARMENIAN SMALL LETTER JHEH */ +#define XK_Armenian_RA 0x100054c /* U+054C ARMENIAN CAPITAL LETTER RA */ +#define XK_Armenian_ra 0x100057c /* U+057C ARMENIAN SMALL LETTER RA */ +#define XK_Armenian_SE 0x100054d /* U+054D ARMENIAN CAPITAL LETTER SEH */ +#define XK_Armenian_se 0x100057d /* U+057D ARMENIAN SMALL LETTER SEH */ +#define XK_Armenian_VEV 0x100054e /* U+054E ARMENIAN CAPITAL LETTER VEW */ +#define XK_Armenian_vev 0x100057e /* U+057E ARMENIAN SMALL LETTER VEW */ +#define XK_Armenian_TYUN 0x100054f /* U+054F ARMENIAN CAPITAL LETTER TIWN */ +#define XK_Armenian_tyun 0x100057f /* U+057F ARMENIAN SMALL LETTER TIWN */ +#define XK_Armenian_RE 0x1000550 /* U+0550 ARMENIAN CAPITAL LETTER REH */ +#define XK_Armenian_re 0x1000580 /* U+0580 ARMENIAN SMALL LETTER REH */ +#define XK_Armenian_TSO 0x1000551 /* U+0551 ARMENIAN CAPITAL LETTER CO */ +#define XK_Armenian_tso 0x1000581 /* U+0581 ARMENIAN SMALL LETTER CO */ +#define XK_Armenian_VYUN 0x1000552 /* U+0552 ARMENIAN CAPITAL LETTER YIWN */ +#define XK_Armenian_vyun 0x1000582 /* U+0582 ARMENIAN SMALL LETTER YIWN */ +#define XK_Armenian_PYUR 0x1000553 /* U+0553 ARMENIAN CAPITAL LETTER PIWR */ +#define XK_Armenian_pyur 0x1000583 /* U+0583 ARMENIAN SMALL LETTER PIWR */ +#define XK_Armenian_KE 0x1000554 /* U+0554 ARMENIAN CAPITAL LETTER KEH */ +#define XK_Armenian_ke 0x1000584 /* U+0584 ARMENIAN SMALL LETTER KEH */ +#define XK_Armenian_O 0x1000555 /* U+0555 ARMENIAN CAPITAL LETTER OH */ +#define XK_Armenian_o 0x1000585 /* U+0585 ARMENIAN SMALL LETTER OH */ +#define XK_Armenian_FE 0x1000556 /* U+0556 ARMENIAN CAPITAL LETTER FEH */ +#define XK_Armenian_fe 0x1000586 /* U+0586 ARMENIAN SMALL LETTER FEH */ +#define XK_Armenian_apostrophe 0x100055a /* U+055A ARMENIAN APOSTROPHE */ +#endif /* XK_ARMENIAN */ /* * Georgian */ #ifdef XK_GEORGIAN -#define XK_Georgian_an 0x10010d0 /* U+10D0 GEORGIAN LETTER AN */ -#define XK_Georgian_ban 0x10010d1 /* U+10D1 GEORGIAN LETTER BAN */ -#define XK_Georgian_gan 0x10010d2 /* U+10D2 GEORGIAN LETTER GAN */ -#define XK_Georgian_don 0x10010d3 /* U+10D3 GEORGIAN LETTER DON */ -#define XK_Georgian_en 0x10010d4 /* U+10D4 GEORGIAN LETTER EN */ -#define XK_Georgian_vin 0x10010d5 /* U+10D5 GEORGIAN LETTER VIN */ -#define XK_Georgian_zen 0x10010d6 /* U+10D6 GEORGIAN LETTER ZEN */ -#define XK_Georgian_tan 0x10010d7 /* U+10D7 GEORGIAN LETTER TAN */ -#define XK_Georgian_in 0x10010d8 /* U+10D8 GEORGIAN LETTER IN */ -#define XK_Georgian_kan 0x10010d9 /* U+10D9 GEORGIAN LETTER KAN */ -#define XK_Georgian_las 0x10010da /* U+10DA GEORGIAN LETTER LAS */ -#define XK_Georgian_man 0x10010db /* U+10DB GEORGIAN LETTER MAN */ -#define XK_Georgian_nar 0x10010dc /* U+10DC GEORGIAN LETTER NAR */ -#define XK_Georgian_on 0x10010dd /* U+10DD GEORGIAN LETTER ON */ -#define XK_Georgian_par 0x10010de /* U+10DE GEORGIAN LETTER PAR */ -#define XK_Georgian_zhar 0x10010df /* U+10DF GEORGIAN LETTER ZHAR */ -#define XK_Georgian_rae 0x10010e0 /* U+10E0 GEORGIAN LETTER RAE */ -#define XK_Georgian_san 0x10010e1 /* U+10E1 GEORGIAN LETTER SAN */ -#define XK_Georgian_tar 0x10010e2 /* U+10E2 GEORGIAN LETTER TAR */ -#define XK_Georgian_un 0x10010e3 /* U+10E3 GEORGIAN LETTER UN */ -#define XK_Georgian_phar 0x10010e4 /* U+10E4 GEORGIAN LETTER PHAR */ -#define XK_Georgian_khar 0x10010e5 /* U+10E5 GEORGIAN LETTER KHAR */ -#define XK_Georgian_ghan 0x10010e6 /* U+10E6 GEORGIAN LETTER GHAN */ -#define XK_Georgian_qar 0x10010e7 /* U+10E7 GEORGIAN LETTER QAR */ -#define XK_Georgian_shin 0x10010e8 /* U+10E8 GEORGIAN LETTER SHIN */ -#define XK_Georgian_chin 0x10010e9 /* U+10E9 GEORGIAN LETTER CHIN */ -#define XK_Georgian_can 0x10010ea /* U+10EA GEORGIAN LETTER CAN */ -#define XK_Georgian_jil 0x10010eb /* U+10EB GEORGIAN LETTER JIL */ -#define XK_Georgian_cil 0x10010ec /* U+10EC GEORGIAN LETTER CIL */ -#define XK_Georgian_char 0x10010ed /* U+10ED GEORGIAN LETTER CHAR */ -#define XK_Georgian_xan 0x10010ee /* U+10EE GEORGIAN LETTER XAN */ -#define XK_Georgian_jhan 0x10010ef /* U+10EF GEORGIAN LETTER JHAN */ -#define XK_Georgian_hae 0x10010f0 /* U+10F0 GEORGIAN LETTER HAE */ -#define XK_Georgian_he 0x10010f1 /* U+10F1 GEORGIAN LETTER HE */ -#define XK_Georgian_hie 0x10010f2 /* U+10F2 GEORGIAN LETTER HIE */ -#define XK_Georgian_we 0x10010f3 /* U+10F3 GEORGIAN LETTER WE */ -#define XK_Georgian_har 0x10010f4 /* U+10F4 GEORGIAN LETTER HAR */ -#define XK_Georgian_hoe 0x10010f5 /* U+10F5 GEORGIAN LETTER HOE */ -#define XK_Georgian_fi 0x10010f6 /* U+10F6 GEORGIAN LETTER FI */ -#endif /* XK_GEORGIAN */ +#define XK_Georgian_an 0x10010d0 /* U+10D0 GEORGIAN LETTER AN */ +#define XK_Georgian_ban 0x10010d1 /* U+10D1 GEORGIAN LETTER BAN */ +#define XK_Georgian_gan 0x10010d2 /* U+10D2 GEORGIAN LETTER GAN */ +#define XK_Georgian_don 0x10010d3 /* U+10D3 GEORGIAN LETTER DON */ +#define XK_Georgian_en 0x10010d4 /* U+10D4 GEORGIAN LETTER EN */ +#define XK_Georgian_vin 0x10010d5 /* U+10D5 GEORGIAN LETTER VIN */ +#define XK_Georgian_zen 0x10010d6 /* U+10D6 GEORGIAN LETTER ZEN */ +#define XK_Georgian_tan 0x10010d7 /* U+10D7 GEORGIAN LETTER TAN */ +#define XK_Georgian_in 0x10010d8 /* U+10D8 GEORGIAN LETTER IN */ +#define XK_Georgian_kan 0x10010d9 /* U+10D9 GEORGIAN LETTER KAN */ +#define XK_Georgian_las 0x10010da /* U+10DA GEORGIAN LETTER LAS */ +#define XK_Georgian_man 0x10010db /* U+10DB GEORGIAN LETTER MAN */ +#define XK_Georgian_nar 0x10010dc /* U+10DC GEORGIAN LETTER NAR */ +#define XK_Georgian_on 0x10010dd /* U+10DD GEORGIAN LETTER ON */ +#define XK_Georgian_par 0x10010de /* U+10DE GEORGIAN LETTER PAR */ +#define XK_Georgian_zhar 0x10010df /* U+10DF GEORGIAN LETTER ZHAR */ +#define XK_Georgian_rae 0x10010e0 /* U+10E0 GEORGIAN LETTER RAE */ +#define XK_Georgian_san 0x10010e1 /* U+10E1 GEORGIAN LETTER SAN */ +#define XK_Georgian_tar 0x10010e2 /* U+10E2 GEORGIAN LETTER TAR */ +#define XK_Georgian_un 0x10010e3 /* U+10E3 GEORGIAN LETTER UN */ +#define XK_Georgian_phar 0x10010e4 /* U+10E4 GEORGIAN LETTER PHAR */ +#define XK_Georgian_khar 0x10010e5 /* U+10E5 GEORGIAN LETTER KHAR */ +#define XK_Georgian_ghan 0x10010e6 /* U+10E6 GEORGIAN LETTER GHAN */ +#define XK_Georgian_qar 0x10010e7 /* U+10E7 GEORGIAN LETTER QAR */ +#define XK_Georgian_shin 0x10010e8 /* U+10E8 GEORGIAN LETTER SHIN */ +#define XK_Georgian_chin 0x10010e9 /* U+10E9 GEORGIAN LETTER CHIN */ +#define XK_Georgian_can 0x10010ea /* U+10EA GEORGIAN LETTER CAN */ +#define XK_Georgian_jil 0x10010eb /* U+10EB GEORGIAN LETTER JIL */ +#define XK_Georgian_cil 0x10010ec /* U+10EC GEORGIAN LETTER CIL */ +#define XK_Georgian_char 0x10010ed /* U+10ED GEORGIAN LETTER CHAR */ +#define XK_Georgian_xan 0x10010ee /* U+10EE GEORGIAN LETTER XAN */ +#define XK_Georgian_jhan 0x10010ef /* U+10EF GEORGIAN LETTER JHAN */ +#define XK_Georgian_hae 0x10010f0 /* U+10F0 GEORGIAN LETTER HAE */ +#define XK_Georgian_he 0x10010f1 /* U+10F1 GEORGIAN LETTER HE */ +#define XK_Georgian_hie 0x10010f2 /* U+10F2 GEORGIAN LETTER HIE */ +#define XK_Georgian_we 0x10010f3 /* U+10F3 GEORGIAN LETTER WE */ +#define XK_Georgian_har 0x10010f4 /* U+10F4 GEORGIAN LETTER HAR */ +#define XK_Georgian_hoe 0x10010f5 /* U+10F5 GEORGIAN LETTER HOE */ +#define XK_Georgian_fi 0x10010f6 /* U+10F6 GEORGIAN LETTER FI */ +#endif /* XK_GEORGIAN */ /* * Azeri (and other Turkic or Caucasian languages) @@ -1959,448 +1953,448 @@ SOFTWARE. #ifdef XK_CAUCASUS /* latin */ -#define XK_Xabovedot 0x1001e8a /* U+1E8A LATIN CAPITAL LETTER X WITH DOT ABOVE */ -#define XK_Ibreve 0x100012c /* U+012C LATIN CAPITAL LETTER I WITH BREVE */ -#define XK_Zstroke 0x10001b5 /* U+01B5 LATIN CAPITAL LETTER Z WITH STROKE */ -#define XK_Gcaron 0x10001e6 /* U+01E6 LATIN CAPITAL LETTER G WITH CARON */ -#define XK_Ocaron 0x10001d1 /* U+01D2 LATIN CAPITAL LETTER O WITH CARON */ -#define XK_Obarred 0x100019f /* U+019F LATIN CAPITAL LETTER O WITH MIDDLE TILDE */ -#define XK_xabovedot 0x1001e8b /* U+1E8B LATIN SMALL LETTER X WITH DOT ABOVE */ -#define XK_ibreve 0x100012d /* U+012D LATIN SMALL LETTER I WITH BREVE */ -#define XK_zstroke 0x10001b6 /* U+01B6 LATIN SMALL LETTER Z WITH STROKE */ -#define XK_gcaron 0x10001e7 /* U+01E7 LATIN SMALL LETTER G WITH CARON */ -#define XK_ocaron 0x10001d2 /* U+01D2 LATIN SMALL LETTER O WITH CARON */ -#define XK_obarred 0x1000275 /* U+0275 LATIN SMALL LETTER BARRED O */ -#define XK_SCHWA 0x100018f /* U+018F LATIN CAPITAL LETTER SCHWA */ -#define XK_schwa 0x1000259 /* U+0259 LATIN SMALL LETTER SCHWA */ -#define XK_EZH 0x10001b7 /* U+01B7 LATIN CAPITAL LETTER EZH */ -#define XK_ezh 0x1000292 /* U+0292 LATIN SMALL LETTER EZH */ +#define XK_Xabovedot 0x1001e8a /* U+1E8A LATIN CAPITAL LETTER X WITH DOT ABOVE */ +#define XK_Ibreve 0x100012c /* U+012C LATIN CAPITAL LETTER I WITH BREVE */ +#define XK_Zstroke 0x10001b5 /* U+01B5 LATIN CAPITAL LETTER Z WITH STROKE */ +#define XK_Gcaron 0x10001e6 /* U+01E6 LATIN CAPITAL LETTER G WITH CARON */ +#define XK_Ocaron 0x10001d1 /* U+01D2 LATIN CAPITAL LETTER O WITH CARON */ +#define XK_Obarred 0x100019f /* U+019F LATIN CAPITAL LETTER O WITH MIDDLE TILDE */ +#define XK_xabovedot 0x1001e8b /* U+1E8B LATIN SMALL LETTER X WITH DOT ABOVE */ +#define XK_ibreve 0x100012d /* U+012D LATIN SMALL LETTER I WITH BREVE */ +#define XK_zstroke 0x10001b6 /* U+01B6 LATIN SMALL LETTER Z WITH STROKE */ +#define XK_gcaron 0x10001e7 /* U+01E7 LATIN SMALL LETTER G WITH CARON */ +#define XK_ocaron 0x10001d2 /* U+01D2 LATIN SMALL LETTER O WITH CARON */ +#define XK_obarred 0x1000275 /* U+0275 LATIN SMALL LETTER BARRED O */ +#define XK_SCHWA 0x100018f /* U+018F LATIN CAPITAL LETTER SCHWA */ +#define XK_schwa 0x1000259 /* U+0259 LATIN SMALL LETTER SCHWA */ +#define XK_EZH 0x10001b7 /* U+01B7 LATIN CAPITAL LETTER EZH */ +#define XK_ezh 0x1000292 /* U+0292 LATIN SMALL LETTER EZH */ /* those are not really Caucasus */ /* For Inupiak */ -#define XK_Lbelowdot 0x1001e36 /* U+1E36 LATIN CAPITAL LETTER L WITH DOT BELOW */ -#define XK_lbelowdot 0x1001e37 /* U+1E37 LATIN SMALL LETTER L WITH DOT BELOW */ -#endif /* XK_CAUCASUS */ +#define XK_Lbelowdot 0x1001e36 /* U+1E36 LATIN CAPITAL LETTER L WITH DOT BELOW */ +#define XK_lbelowdot 0x1001e37 /* U+1E37 LATIN SMALL LETTER L WITH DOT BELOW */ +#endif /* XK_CAUCASUS */ /* * Vietnamese */ - + #ifdef XK_VIETNAMESE -#define XK_Abelowdot 0x1001ea0 /* U+1EA0 LATIN CAPITAL LETTER A WITH DOT BELOW */ -#define XK_abelowdot 0x1001ea1 /* U+1EA1 LATIN SMALL LETTER A WITH DOT BELOW */ -#define XK_Ahook 0x1001ea2 /* U+1EA2 LATIN CAPITAL LETTER A WITH HOOK ABOVE */ -#define XK_ahook 0x1001ea3 /* U+1EA3 LATIN SMALL LETTER A WITH HOOK ABOVE */ -#define XK_Acircumflexacute 0x1001ea4 /* U+1EA4 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE */ -#define XK_acircumflexacute 0x1001ea5 /* U+1EA5 LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE */ -#define XK_Acircumflexgrave 0x1001ea6 /* U+1EA6 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE */ -#define XK_acircumflexgrave 0x1001ea7 /* U+1EA7 LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE */ -#define XK_Acircumflexhook 0x1001ea8 /* U+1EA8 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */ -#define XK_acircumflexhook 0x1001ea9 /* U+1EA9 LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */ -#define XK_Acircumflextilde 0x1001eaa /* U+1EAA LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE */ -#define XK_acircumflextilde 0x1001eab /* U+1EAB LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE */ -#define XK_Acircumflexbelowdot 0x1001eac /* U+1EAC LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW */ -#define XK_acircumflexbelowdot 0x1001ead /* U+1EAD LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW */ -#define XK_Abreveacute 0x1001eae /* U+1EAE LATIN CAPITAL LETTER A WITH BREVE AND ACUTE */ -#define XK_abreveacute 0x1001eaf /* U+1EAF LATIN SMALL LETTER A WITH BREVE AND ACUTE */ -#define XK_Abrevegrave 0x1001eb0 /* U+1EB0 LATIN CAPITAL LETTER A WITH BREVE AND GRAVE */ -#define XK_abrevegrave 0x1001eb1 /* U+1EB1 LATIN SMALL LETTER A WITH BREVE AND GRAVE */ -#define XK_Abrevehook 0x1001eb2 /* U+1EB2 LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE */ -#define XK_abrevehook 0x1001eb3 /* U+1EB3 LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE */ -#define XK_Abrevetilde 0x1001eb4 /* U+1EB4 LATIN CAPITAL LETTER A WITH BREVE AND TILDE */ -#define XK_abrevetilde 0x1001eb5 /* U+1EB5 LATIN SMALL LETTER A WITH BREVE AND TILDE */ -#define XK_Abrevebelowdot 0x1001eb6 /* U+1EB6 LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW */ -#define XK_abrevebelowdot 0x1001eb7 /* U+1EB7 LATIN SMALL LETTER A WITH BREVE AND DOT BELOW */ -#define XK_Ebelowdot 0x1001eb8 /* U+1EB8 LATIN CAPITAL LETTER E WITH DOT BELOW */ -#define XK_ebelowdot 0x1001eb9 /* U+1EB9 LATIN SMALL LETTER E WITH DOT BELOW */ -#define XK_Ehook 0x1001eba /* U+1EBA LATIN CAPITAL LETTER E WITH HOOK ABOVE */ -#define XK_ehook 0x1001ebb /* U+1EBB LATIN SMALL LETTER E WITH HOOK ABOVE */ -#define XK_Etilde 0x1001ebc /* U+1EBC LATIN CAPITAL LETTER E WITH TILDE */ -#define XK_etilde 0x1001ebd /* U+1EBD LATIN SMALL LETTER E WITH TILDE */ -#define XK_Ecircumflexacute 0x1001ebe /* U+1EBE LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE */ -#define XK_ecircumflexacute 0x1001ebf /* U+1EBF LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE */ -#define XK_Ecircumflexgrave 0x1001ec0 /* U+1EC0 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE */ -#define XK_ecircumflexgrave 0x1001ec1 /* U+1EC1 LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE */ -#define XK_Ecircumflexhook 0x1001ec2 /* U+1EC2 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */ -#define XK_ecircumflexhook 0x1001ec3 /* U+1EC3 LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */ -#define XK_Ecircumflextilde 0x1001ec4 /* U+1EC4 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE */ -#define XK_ecircumflextilde 0x1001ec5 /* U+1EC5 LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE */ -#define XK_Ecircumflexbelowdot 0x1001ec6 /* U+1EC6 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW */ -#define XK_ecircumflexbelowdot 0x1001ec7 /* U+1EC7 LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW */ -#define XK_Ihook 0x1001ec8 /* U+1EC8 LATIN CAPITAL LETTER I WITH HOOK ABOVE */ -#define XK_ihook 0x1001ec9 /* U+1EC9 LATIN SMALL LETTER I WITH HOOK ABOVE */ -#define XK_Ibelowdot 0x1001eca /* U+1ECA LATIN CAPITAL LETTER I WITH DOT BELOW */ -#define XK_ibelowdot 0x1001ecb /* U+1ECB LATIN SMALL LETTER I WITH DOT BELOW */ -#define XK_Obelowdot 0x1001ecc /* U+1ECC LATIN CAPITAL LETTER O WITH DOT BELOW */ -#define XK_obelowdot 0x1001ecd /* U+1ECD LATIN SMALL LETTER O WITH DOT BELOW */ -#define XK_Ohook 0x1001ece /* U+1ECE LATIN CAPITAL LETTER O WITH HOOK ABOVE */ -#define XK_ohook 0x1001ecf /* U+1ECF LATIN SMALL LETTER O WITH HOOK ABOVE */ -#define XK_Ocircumflexacute 0x1001ed0 /* U+1ED0 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE */ -#define XK_ocircumflexacute 0x1001ed1 /* U+1ED1 LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE */ -#define XK_Ocircumflexgrave 0x1001ed2 /* U+1ED2 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE */ -#define XK_ocircumflexgrave 0x1001ed3 /* U+1ED3 LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE */ -#define XK_Ocircumflexhook 0x1001ed4 /* U+1ED4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */ -#define XK_ocircumflexhook 0x1001ed5 /* U+1ED5 LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */ -#define XK_Ocircumflextilde 0x1001ed6 /* U+1ED6 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE */ -#define XK_ocircumflextilde 0x1001ed7 /* U+1ED7 LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE */ -#define XK_Ocircumflexbelowdot 0x1001ed8 /* U+1ED8 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW */ -#define XK_ocircumflexbelowdot 0x1001ed9 /* U+1ED9 LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW */ -#define XK_Ohornacute 0x1001eda /* U+1EDA LATIN CAPITAL LETTER O WITH HORN AND ACUTE */ -#define XK_ohornacute 0x1001edb /* U+1EDB LATIN SMALL LETTER O WITH HORN AND ACUTE */ -#define XK_Ohorngrave 0x1001edc /* U+1EDC LATIN CAPITAL LETTER O WITH HORN AND GRAVE */ -#define XK_ohorngrave 0x1001edd /* U+1EDD LATIN SMALL LETTER O WITH HORN AND GRAVE */ -#define XK_Ohornhook 0x1001ede /* U+1EDE LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE */ -#define XK_ohornhook 0x1001edf /* U+1EDF LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE */ -#define XK_Ohorntilde 0x1001ee0 /* U+1EE0 LATIN CAPITAL LETTER O WITH HORN AND TILDE */ -#define XK_ohorntilde 0x1001ee1 /* U+1EE1 LATIN SMALL LETTER O WITH HORN AND TILDE */ -#define XK_Ohornbelowdot 0x1001ee2 /* U+1EE2 LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW */ -#define XK_ohornbelowdot 0x1001ee3 /* U+1EE3 LATIN SMALL LETTER O WITH HORN AND DOT BELOW */ -#define XK_Ubelowdot 0x1001ee4 /* U+1EE4 LATIN CAPITAL LETTER U WITH DOT BELOW */ -#define XK_ubelowdot 0x1001ee5 /* U+1EE5 LATIN SMALL LETTER U WITH DOT BELOW */ -#define XK_Uhook 0x1001ee6 /* U+1EE6 LATIN CAPITAL LETTER U WITH HOOK ABOVE */ -#define XK_uhook 0x1001ee7 /* U+1EE7 LATIN SMALL LETTER U WITH HOOK ABOVE */ -#define XK_Uhornacute 0x1001ee8 /* U+1EE8 LATIN CAPITAL LETTER U WITH HORN AND ACUTE */ -#define XK_uhornacute 0x1001ee9 /* U+1EE9 LATIN SMALL LETTER U WITH HORN AND ACUTE */ -#define XK_Uhorngrave 0x1001eea /* U+1EEA LATIN CAPITAL LETTER U WITH HORN AND GRAVE */ -#define XK_uhorngrave 0x1001eeb /* U+1EEB LATIN SMALL LETTER U WITH HORN AND GRAVE */ -#define XK_Uhornhook 0x1001eec /* U+1EEC LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE */ -#define XK_uhornhook 0x1001eed /* U+1EED LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE */ -#define XK_Uhorntilde 0x1001eee /* U+1EEE LATIN CAPITAL LETTER U WITH HORN AND TILDE */ -#define XK_uhorntilde 0x1001eef /* U+1EEF LATIN SMALL LETTER U WITH HORN AND TILDE */ -#define XK_Uhornbelowdot 0x1001ef0 /* U+1EF0 LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW */ -#define XK_uhornbelowdot 0x1001ef1 /* U+1EF1 LATIN SMALL LETTER U WITH HORN AND DOT BELOW */ -#define XK_Ybelowdot 0x1001ef4 /* U+1EF4 LATIN CAPITAL LETTER Y WITH DOT BELOW */ -#define XK_ybelowdot 0x1001ef5 /* U+1EF5 LATIN SMALL LETTER Y WITH DOT BELOW */ -#define XK_Yhook 0x1001ef6 /* U+1EF6 LATIN CAPITAL LETTER Y WITH HOOK ABOVE */ -#define XK_yhook 0x1001ef7 /* U+1EF7 LATIN SMALL LETTER Y WITH HOOK ABOVE */ -#define XK_Ytilde 0x1001ef8 /* U+1EF8 LATIN CAPITAL LETTER Y WITH TILDE */ -#define XK_ytilde 0x1001ef9 /* U+1EF9 LATIN SMALL LETTER Y WITH TILDE */ -#define XK_Ohorn 0x10001a0 /* U+01A0 LATIN CAPITAL LETTER O WITH HORN */ -#define XK_ohorn 0x10001a1 /* U+01A1 LATIN SMALL LETTER O WITH HORN */ -#define XK_Uhorn 0x10001af /* U+01AF LATIN CAPITAL LETTER U WITH HORN */ -#define XK_uhorn 0x10001b0 /* U+01B0 LATIN SMALL LETTER U WITH HORN */ +#define XK_Abelowdot 0x1001ea0 /* U+1EA0 LATIN CAPITAL LETTER A WITH DOT BELOW */ +#define XK_abelowdot 0x1001ea1 /* U+1EA1 LATIN SMALL LETTER A WITH DOT BELOW */ +#define XK_Ahook 0x1001ea2 /* U+1EA2 LATIN CAPITAL LETTER A WITH HOOK ABOVE */ +#define XK_ahook 0x1001ea3 /* U+1EA3 LATIN SMALL LETTER A WITH HOOK ABOVE */ +#define XK_Acircumflexacute 0x1001ea4 /* U+1EA4 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND ACUTE */ +#define XK_acircumflexacute 0x1001ea5 /* U+1EA5 LATIN SMALL LETTER A WITH CIRCUMFLEX AND ACUTE */ +#define XK_Acircumflexgrave 0x1001ea6 /* U+1EA6 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND GRAVE */ +#define XK_acircumflexgrave 0x1001ea7 /* U+1EA7 LATIN SMALL LETTER A WITH CIRCUMFLEX AND GRAVE */ +#define XK_Acircumflexhook 0x1001ea8 /* U+1EA8 LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */ +#define XK_acircumflexhook 0x1001ea9 /* U+1EA9 LATIN SMALL LETTER A WITH CIRCUMFLEX AND HOOK ABOVE */ +#define XK_Acircumflextilde 0x1001eaa /* U+1EAA LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND TILDE */ +#define XK_acircumflextilde 0x1001eab /* U+1EAB LATIN SMALL LETTER A WITH CIRCUMFLEX AND TILDE */ +#define XK_Acircumflexbelowdot 0x1001eac /* U+1EAC LATIN CAPITAL LETTER A WITH CIRCUMFLEX AND DOT BELOW */ +#define XK_acircumflexbelowdot 0x1001ead /* U+1EAD LATIN SMALL LETTER A WITH CIRCUMFLEX AND DOT BELOW */ +#define XK_Abreveacute 0x1001eae /* U+1EAE LATIN CAPITAL LETTER A WITH BREVE AND ACUTE */ +#define XK_abreveacute 0x1001eaf /* U+1EAF LATIN SMALL LETTER A WITH BREVE AND ACUTE */ +#define XK_Abrevegrave 0x1001eb0 /* U+1EB0 LATIN CAPITAL LETTER A WITH BREVE AND GRAVE */ +#define XK_abrevegrave 0x1001eb1 /* U+1EB1 LATIN SMALL LETTER A WITH BREVE AND GRAVE */ +#define XK_Abrevehook 0x1001eb2 /* U+1EB2 LATIN CAPITAL LETTER A WITH BREVE AND HOOK ABOVE */ +#define XK_abrevehook 0x1001eb3 /* U+1EB3 LATIN SMALL LETTER A WITH BREVE AND HOOK ABOVE */ +#define XK_Abrevetilde 0x1001eb4 /* U+1EB4 LATIN CAPITAL LETTER A WITH BREVE AND TILDE */ +#define XK_abrevetilde 0x1001eb5 /* U+1EB5 LATIN SMALL LETTER A WITH BREVE AND TILDE */ +#define XK_Abrevebelowdot 0x1001eb6 /* U+1EB6 LATIN CAPITAL LETTER A WITH BREVE AND DOT BELOW */ +#define XK_abrevebelowdot 0x1001eb7 /* U+1EB7 LATIN SMALL LETTER A WITH BREVE AND DOT BELOW */ +#define XK_Ebelowdot 0x1001eb8 /* U+1EB8 LATIN CAPITAL LETTER E WITH DOT BELOW */ +#define XK_ebelowdot 0x1001eb9 /* U+1EB9 LATIN SMALL LETTER E WITH DOT BELOW */ +#define XK_Ehook 0x1001eba /* U+1EBA LATIN CAPITAL LETTER E WITH HOOK ABOVE */ +#define XK_ehook 0x1001ebb /* U+1EBB LATIN SMALL LETTER E WITH HOOK ABOVE */ +#define XK_Etilde 0x1001ebc /* U+1EBC LATIN CAPITAL LETTER E WITH TILDE */ +#define XK_etilde 0x1001ebd /* U+1EBD LATIN SMALL LETTER E WITH TILDE */ +#define XK_Ecircumflexacute 0x1001ebe /* U+1EBE LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND ACUTE */ +#define XK_ecircumflexacute 0x1001ebf /* U+1EBF LATIN SMALL LETTER E WITH CIRCUMFLEX AND ACUTE */ +#define XK_Ecircumflexgrave 0x1001ec0 /* U+1EC0 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND GRAVE */ +#define XK_ecircumflexgrave 0x1001ec1 /* U+1EC1 LATIN SMALL LETTER E WITH CIRCUMFLEX AND GRAVE */ +#define XK_Ecircumflexhook 0x1001ec2 /* U+1EC2 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */ +#define XK_ecircumflexhook 0x1001ec3 /* U+1EC3 LATIN SMALL LETTER E WITH CIRCUMFLEX AND HOOK ABOVE */ +#define XK_Ecircumflextilde 0x1001ec4 /* U+1EC4 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND TILDE */ +#define XK_ecircumflextilde 0x1001ec5 /* U+1EC5 LATIN SMALL LETTER E WITH CIRCUMFLEX AND TILDE */ +#define XK_Ecircumflexbelowdot 0x1001ec6 /* U+1EC6 LATIN CAPITAL LETTER E WITH CIRCUMFLEX AND DOT BELOW */ +#define XK_ecircumflexbelowdot 0x1001ec7 /* U+1EC7 LATIN SMALL LETTER E WITH CIRCUMFLEX AND DOT BELOW */ +#define XK_Ihook 0x1001ec8 /* U+1EC8 LATIN CAPITAL LETTER I WITH HOOK ABOVE */ +#define XK_ihook 0x1001ec9 /* U+1EC9 LATIN SMALL LETTER I WITH HOOK ABOVE */ +#define XK_Ibelowdot 0x1001eca /* U+1ECA LATIN CAPITAL LETTER I WITH DOT BELOW */ +#define XK_ibelowdot 0x1001ecb /* U+1ECB LATIN SMALL LETTER I WITH DOT BELOW */ +#define XK_Obelowdot 0x1001ecc /* U+1ECC LATIN CAPITAL LETTER O WITH DOT BELOW */ +#define XK_obelowdot 0x1001ecd /* U+1ECD LATIN SMALL LETTER O WITH DOT BELOW */ +#define XK_Ohook 0x1001ece /* U+1ECE LATIN CAPITAL LETTER O WITH HOOK ABOVE */ +#define XK_ohook 0x1001ecf /* U+1ECF LATIN SMALL LETTER O WITH HOOK ABOVE */ +#define XK_Ocircumflexacute 0x1001ed0 /* U+1ED0 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND ACUTE */ +#define XK_ocircumflexacute 0x1001ed1 /* U+1ED1 LATIN SMALL LETTER O WITH CIRCUMFLEX AND ACUTE */ +#define XK_Ocircumflexgrave 0x1001ed2 /* U+1ED2 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND GRAVE */ +#define XK_ocircumflexgrave 0x1001ed3 /* U+1ED3 LATIN SMALL LETTER O WITH CIRCUMFLEX AND GRAVE */ +#define XK_Ocircumflexhook 0x1001ed4 /* U+1ED4 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */ +#define XK_ocircumflexhook 0x1001ed5 /* U+1ED5 LATIN SMALL LETTER O WITH CIRCUMFLEX AND HOOK ABOVE */ +#define XK_Ocircumflextilde 0x1001ed6 /* U+1ED6 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND TILDE */ +#define XK_ocircumflextilde 0x1001ed7 /* U+1ED7 LATIN SMALL LETTER O WITH CIRCUMFLEX AND TILDE */ +#define XK_Ocircumflexbelowdot 0x1001ed8 /* U+1ED8 LATIN CAPITAL LETTER O WITH CIRCUMFLEX AND DOT BELOW */ +#define XK_ocircumflexbelowdot 0x1001ed9 /* U+1ED9 LATIN SMALL LETTER O WITH CIRCUMFLEX AND DOT BELOW */ +#define XK_Ohornacute 0x1001eda /* U+1EDA LATIN CAPITAL LETTER O WITH HORN AND ACUTE */ +#define XK_ohornacute 0x1001edb /* U+1EDB LATIN SMALL LETTER O WITH HORN AND ACUTE */ +#define XK_Ohorngrave 0x1001edc /* U+1EDC LATIN CAPITAL LETTER O WITH HORN AND GRAVE */ +#define XK_ohorngrave 0x1001edd /* U+1EDD LATIN SMALL LETTER O WITH HORN AND GRAVE */ +#define XK_Ohornhook 0x1001ede /* U+1EDE LATIN CAPITAL LETTER O WITH HORN AND HOOK ABOVE */ +#define XK_ohornhook 0x1001edf /* U+1EDF LATIN SMALL LETTER O WITH HORN AND HOOK ABOVE */ +#define XK_Ohorntilde 0x1001ee0 /* U+1EE0 LATIN CAPITAL LETTER O WITH HORN AND TILDE */ +#define XK_ohorntilde 0x1001ee1 /* U+1EE1 LATIN SMALL LETTER O WITH HORN AND TILDE */ +#define XK_Ohornbelowdot 0x1001ee2 /* U+1EE2 LATIN CAPITAL LETTER O WITH HORN AND DOT BELOW */ +#define XK_ohornbelowdot 0x1001ee3 /* U+1EE3 LATIN SMALL LETTER O WITH HORN AND DOT BELOW */ +#define XK_Ubelowdot 0x1001ee4 /* U+1EE4 LATIN CAPITAL LETTER U WITH DOT BELOW */ +#define XK_ubelowdot 0x1001ee5 /* U+1EE5 LATIN SMALL LETTER U WITH DOT BELOW */ +#define XK_Uhook 0x1001ee6 /* U+1EE6 LATIN CAPITAL LETTER U WITH HOOK ABOVE */ +#define XK_uhook 0x1001ee7 /* U+1EE7 LATIN SMALL LETTER U WITH HOOK ABOVE */ +#define XK_Uhornacute 0x1001ee8 /* U+1EE8 LATIN CAPITAL LETTER U WITH HORN AND ACUTE */ +#define XK_uhornacute 0x1001ee9 /* U+1EE9 LATIN SMALL LETTER U WITH HORN AND ACUTE */ +#define XK_Uhorngrave 0x1001eea /* U+1EEA LATIN CAPITAL LETTER U WITH HORN AND GRAVE */ +#define XK_uhorngrave 0x1001eeb /* U+1EEB LATIN SMALL LETTER U WITH HORN AND GRAVE */ +#define XK_Uhornhook 0x1001eec /* U+1EEC LATIN CAPITAL LETTER U WITH HORN AND HOOK ABOVE */ +#define XK_uhornhook 0x1001eed /* U+1EED LATIN SMALL LETTER U WITH HORN AND HOOK ABOVE */ +#define XK_Uhorntilde 0x1001eee /* U+1EEE LATIN CAPITAL LETTER U WITH HORN AND TILDE */ +#define XK_uhorntilde 0x1001eef /* U+1EEF LATIN SMALL LETTER U WITH HORN AND TILDE */ +#define XK_Uhornbelowdot 0x1001ef0 /* U+1EF0 LATIN CAPITAL LETTER U WITH HORN AND DOT BELOW */ +#define XK_uhornbelowdot 0x1001ef1 /* U+1EF1 LATIN SMALL LETTER U WITH HORN AND DOT BELOW */ +#define XK_Ybelowdot 0x1001ef4 /* U+1EF4 LATIN CAPITAL LETTER Y WITH DOT BELOW */ +#define XK_ybelowdot 0x1001ef5 /* U+1EF5 LATIN SMALL LETTER Y WITH DOT BELOW */ +#define XK_Yhook 0x1001ef6 /* U+1EF6 LATIN CAPITAL LETTER Y WITH HOOK ABOVE */ +#define XK_yhook 0x1001ef7 /* U+1EF7 LATIN SMALL LETTER Y WITH HOOK ABOVE */ +#define XK_Ytilde 0x1001ef8 /* U+1EF8 LATIN CAPITAL LETTER Y WITH TILDE */ +#define XK_ytilde 0x1001ef9 /* U+1EF9 LATIN SMALL LETTER Y WITH TILDE */ +#define XK_Ohorn 0x10001a0 /* U+01A0 LATIN CAPITAL LETTER O WITH HORN */ +#define XK_ohorn 0x10001a1 /* U+01A1 LATIN SMALL LETTER O WITH HORN */ +#define XK_Uhorn 0x10001af /* U+01AF LATIN CAPITAL LETTER U WITH HORN */ +#define XK_uhorn 0x10001b0 /* U+01B0 LATIN SMALL LETTER U WITH HORN */ #endif /* XK_VIETNAMESE */ #ifdef XK_CURRENCY -#define XK_EcuSign 0x10020a0 /* U+20A0 EURO-CURRENCY SIGN */ -#define XK_ColonSign 0x10020a1 /* U+20A1 COLON SIGN */ -#define XK_CruzeiroSign 0x10020a2 /* U+20A2 CRUZEIRO SIGN */ -#define XK_FFrancSign 0x10020a3 /* U+20A3 FRENCH FRANC SIGN */ -#define XK_LiraSign 0x10020a4 /* U+20A4 LIRA SIGN */ -#define XK_MillSign 0x10020a5 /* U+20A5 MILL SIGN */ -#define XK_NairaSign 0x10020a6 /* U+20A6 NAIRA SIGN */ -#define XK_PesetaSign 0x10020a7 /* U+20A7 PESETA SIGN */ -#define XK_RupeeSign 0x10020a8 /* U+20A8 RUPEE SIGN */ -#define XK_WonSign 0x10020a9 /* U+20A9 WON SIGN */ -#define XK_NewSheqelSign 0x10020aa /* U+20AA NEW SHEQEL SIGN */ -#define XK_DongSign 0x10020ab /* U+20AB DONG SIGN */ -#define XK_EuroSign 0x20ac /* U+20AC EURO SIGN */ -#endif /* XK_CURRENCY */ +#define XK_EcuSign 0x10020a0 /* U+20A0 EURO-CURRENCY SIGN */ +#define XK_ColonSign 0x10020a1 /* U+20A1 COLON SIGN */ +#define XK_CruzeiroSign 0x10020a2 /* U+20A2 CRUZEIRO SIGN */ +#define XK_FFrancSign 0x10020a3 /* U+20A3 FRENCH FRANC SIGN */ +#define XK_LiraSign 0x10020a4 /* U+20A4 LIRA SIGN */ +#define XK_MillSign 0x10020a5 /* U+20A5 MILL SIGN */ +#define XK_NairaSign 0x10020a6 /* U+20A6 NAIRA SIGN */ +#define XK_PesetaSign 0x10020a7 /* U+20A7 PESETA SIGN */ +#define XK_RupeeSign 0x10020a8 /* U+20A8 RUPEE SIGN */ +#define XK_WonSign 0x10020a9 /* U+20A9 WON SIGN */ +#define XK_NewSheqelSign 0x10020aa /* U+20AA NEW SHEQEL SIGN */ +#define XK_DongSign 0x10020ab /* U+20AB DONG SIGN */ +#define XK_EuroSign 0x20ac /* U+20AC EURO SIGN */ +#endif /* XK_CURRENCY */ #ifdef XK_MATHEMATICAL /* one, two and three are defined above. */ -#define XK_zerosuperior 0x1002070 /* U+2070 SUPERSCRIPT ZERO */ -#define XK_foursuperior 0x1002074 /* U+2074 SUPERSCRIPT FOUR */ -#define XK_fivesuperior 0x1002075 /* U+2075 SUPERSCRIPT FIVE */ -#define XK_sixsuperior 0x1002076 /* U+2076 SUPERSCRIPT SIX */ -#define XK_sevensuperior 0x1002077 /* U+2077 SUPERSCRIPT SEVEN */ -#define XK_eightsuperior 0x1002078 /* U+2078 SUPERSCRIPT EIGHT */ -#define XK_ninesuperior 0x1002079 /* U+2079 SUPERSCRIPT NINE */ -#define XK_zerosubscript 0x1002080 /* U+2080 SUBSCRIPT ZERO */ -#define XK_onesubscript 0x1002081 /* U+2081 SUBSCRIPT ONE */ -#define XK_twosubscript 0x1002082 /* U+2082 SUBSCRIPT TWO */ -#define XK_threesubscript 0x1002083 /* U+2083 SUBSCRIPT THREE */ -#define XK_foursubscript 0x1002084 /* U+2084 SUBSCRIPT FOUR */ -#define XK_fivesubscript 0x1002085 /* U+2085 SUBSCRIPT FIVE */ -#define XK_sixsubscript 0x1002086 /* U+2086 SUBSCRIPT SIX */ -#define XK_sevensubscript 0x1002087 /* U+2087 SUBSCRIPT SEVEN */ -#define XK_eightsubscript 0x1002088 /* U+2088 SUBSCRIPT EIGHT */ -#define XK_ninesubscript 0x1002089 /* U+2089 SUBSCRIPT NINE */ -#define XK_partdifferential 0x1002202 /* U+2202 PARTIAL DIFFERENTIAL */ -#define XK_emptyset 0x1002205 /* U+2205 NULL SET */ -#define XK_elementof 0x1002208 /* U+2208 ELEMENT OF */ -#define XK_notelementof 0x1002209 /* U+2209 NOT AN ELEMENT OF */ -#define XK_containsas 0x100220B /* U+220B CONTAINS AS MEMBER */ -#define XK_squareroot 0x100221A /* U+221A SQUARE ROOT */ -#define XK_cuberoot 0x100221B /* U+221B CUBE ROOT */ -#define XK_fourthroot 0x100221C /* U+221C FOURTH ROOT */ -#define XK_dintegral 0x100222C /* U+222C DOUBLE INTEGRAL */ -#define XK_tintegral 0x100222D /* U+222D TRIPLE INTEGRAL */ -#define XK_because 0x1002235 /* U+2235 BECAUSE */ -#define XK_approxeq 0x1002248 /* U+2245 ALMOST EQUAL TO */ -#define XK_notapproxeq 0x1002247 /* U+2247 NOT ALMOST EQUAL TO */ -#define XK_notidentical 0x1002262 /* U+2262 NOT IDENTICAL TO */ -#define XK_stricteq 0x1002263 /* U+2263 STRICTLY EQUIVALENT TO */ -#endif /* XK_MATHEMATICAL */ +#define XK_zerosuperior 0x1002070 /* U+2070 SUPERSCRIPT ZERO */ +#define XK_foursuperior 0x1002074 /* U+2074 SUPERSCRIPT FOUR */ +#define XK_fivesuperior 0x1002075 /* U+2075 SUPERSCRIPT FIVE */ +#define XK_sixsuperior 0x1002076 /* U+2076 SUPERSCRIPT SIX */ +#define XK_sevensuperior 0x1002077 /* U+2077 SUPERSCRIPT SEVEN */ +#define XK_eightsuperior 0x1002078 /* U+2078 SUPERSCRIPT EIGHT */ +#define XK_ninesuperior 0x1002079 /* U+2079 SUPERSCRIPT NINE */ +#define XK_zerosubscript 0x1002080 /* U+2080 SUBSCRIPT ZERO */ +#define XK_onesubscript 0x1002081 /* U+2081 SUBSCRIPT ONE */ +#define XK_twosubscript 0x1002082 /* U+2082 SUBSCRIPT TWO */ +#define XK_threesubscript 0x1002083 /* U+2083 SUBSCRIPT THREE */ +#define XK_foursubscript 0x1002084 /* U+2084 SUBSCRIPT FOUR */ +#define XK_fivesubscript 0x1002085 /* U+2085 SUBSCRIPT FIVE */ +#define XK_sixsubscript 0x1002086 /* U+2086 SUBSCRIPT SIX */ +#define XK_sevensubscript 0x1002087 /* U+2087 SUBSCRIPT SEVEN */ +#define XK_eightsubscript 0x1002088 /* U+2088 SUBSCRIPT EIGHT */ +#define XK_ninesubscript 0x1002089 /* U+2089 SUBSCRIPT NINE */ +#define XK_partdifferential 0x1002202 /* U+2202 PARTIAL DIFFERENTIAL */ +#define XK_emptyset 0x1002205 /* U+2205 NULL SET */ +#define XK_elementof 0x1002208 /* U+2208 ELEMENT OF */ +#define XK_notelementof 0x1002209 /* U+2209 NOT AN ELEMENT OF */ +#define XK_containsas 0x100220B /* U+220B CONTAINS AS MEMBER */ +#define XK_squareroot 0x100221A /* U+221A SQUARE ROOT */ +#define XK_cuberoot 0x100221B /* U+221B CUBE ROOT */ +#define XK_fourthroot 0x100221C /* U+221C FOURTH ROOT */ +#define XK_dintegral 0x100222C /* U+222C DOUBLE INTEGRAL */ +#define XK_tintegral 0x100222D /* U+222D TRIPLE INTEGRAL */ +#define XK_because 0x1002235 /* U+2235 BECAUSE */ +#define XK_approxeq 0x1002248 /* U+2245 ALMOST EQUAL TO */ +#define XK_notapproxeq 0x1002247 /* U+2247 NOT ALMOST EQUAL TO */ +#define XK_notidentical 0x1002262 /* U+2262 NOT IDENTICAL TO */ +#define XK_stricteq 0x1002263 /* U+2263 STRICTLY EQUIVALENT TO */ +#endif /* XK_MATHEMATICAL */ #ifdef XK_BRAILLE -#define XK_braille_dot_1 0xfff1 -#define XK_braille_dot_2 0xfff2 -#define XK_braille_dot_3 0xfff3 -#define XK_braille_dot_4 0xfff4 -#define XK_braille_dot_5 0xfff5 -#define XK_braille_dot_6 0xfff6 -#define XK_braille_dot_7 0xfff7 -#define XK_braille_dot_8 0xfff8 -#define XK_braille_dot_9 0xfff9 -#define XK_braille_dot_10 0xfffa -#define XK_braille_blank 0x1002800 /* U+2800 BRAILLE PATTERN BLANK */ -#define XK_braille_dots_1 0x1002801 /* U+2801 BRAILLE PATTERN DOTS-1 */ -#define XK_braille_dots_2 0x1002802 /* U+2802 BRAILLE PATTERN DOTS-2 */ -#define XK_braille_dots_12 0x1002803 /* U+2803 BRAILLE PATTERN DOTS-12 */ -#define XK_braille_dots_3 0x1002804 /* U+2804 BRAILLE PATTERN DOTS-3 */ -#define XK_braille_dots_13 0x1002805 /* U+2805 BRAILLE PATTERN DOTS-13 */ -#define XK_braille_dots_23 0x1002806 /* U+2806 BRAILLE PATTERN DOTS-23 */ -#define XK_braille_dots_123 0x1002807 /* U+2807 BRAILLE PATTERN DOTS-123 */ -#define XK_braille_dots_4 0x1002808 /* U+2808 BRAILLE PATTERN DOTS-4 */ -#define XK_braille_dots_14 0x1002809 /* U+2809 BRAILLE PATTERN DOTS-14 */ -#define XK_braille_dots_24 0x100280a /* U+280a BRAILLE PATTERN DOTS-24 */ -#define XK_braille_dots_124 0x100280b /* U+280b BRAILLE PATTERN DOTS-124 */ -#define XK_braille_dots_34 0x100280c /* U+280c BRAILLE PATTERN DOTS-34 */ -#define XK_braille_dots_134 0x100280d /* U+280d BRAILLE PATTERN DOTS-134 */ -#define XK_braille_dots_234 0x100280e /* U+280e BRAILLE PATTERN DOTS-234 */ -#define XK_braille_dots_1234 0x100280f /* U+280f BRAILLE PATTERN DOTS-1234 */ -#define XK_braille_dots_5 0x1002810 /* U+2810 BRAILLE PATTERN DOTS-5 */ -#define XK_braille_dots_15 0x1002811 /* U+2811 BRAILLE PATTERN DOTS-15 */ -#define XK_braille_dots_25 0x1002812 /* U+2812 BRAILLE PATTERN DOTS-25 */ -#define XK_braille_dots_125 0x1002813 /* U+2813 BRAILLE PATTERN DOTS-125 */ -#define XK_braille_dots_35 0x1002814 /* U+2814 BRAILLE PATTERN DOTS-35 */ -#define XK_braille_dots_135 0x1002815 /* U+2815 BRAILLE PATTERN DOTS-135 */ -#define XK_braille_dots_235 0x1002816 /* U+2816 BRAILLE PATTERN DOTS-235 */ -#define XK_braille_dots_1235 0x1002817 /* U+2817 BRAILLE PATTERN DOTS-1235 */ -#define XK_braille_dots_45 0x1002818 /* U+2818 BRAILLE PATTERN DOTS-45 */ -#define XK_braille_dots_145 0x1002819 /* U+2819 BRAILLE PATTERN DOTS-145 */ -#define XK_braille_dots_245 0x100281a /* U+281a BRAILLE PATTERN DOTS-245 */ -#define XK_braille_dots_1245 0x100281b /* U+281b BRAILLE PATTERN DOTS-1245 */ -#define XK_braille_dots_345 0x100281c /* U+281c BRAILLE PATTERN DOTS-345 */ -#define XK_braille_dots_1345 0x100281d /* U+281d BRAILLE PATTERN DOTS-1345 */ -#define XK_braille_dots_2345 0x100281e /* U+281e BRAILLE PATTERN DOTS-2345 */ -#define XK_braille_dots_12345 0x100281f /* U+281f BRAILLE PATTERN DOTS-12345 */ -#define XK_braille_dots_6 0x1002820 /* U+2820 BRAILLE PATTERN DOTS-6 */ -#define XK_braille_dots_16 0x1002821 /* U+2821 BRAILLE PATTERN DOTS-16 */ -#define XK_braille_dots_26 0x1002822 /* U+2822 BRAILLE PATTERN DOTS-26 */ -#define XK_braille_dots_126 0x1002823 /* U+2823 BRAILLE PATTERN DOTS-126 */ -#define XK_braille_dots_36 0x1002824 /* U+2824 BRAILLE PATTERN DOTS-36 */ -#define XK_braille_dots_136 0x1002825 /* U+2825 BRAILLE PATTERN DOTS-136 */ -#define XK_braille_dots_236 0x1002826 /* U+2826 BRAILLE PATTERN DOTS-236 */ -#define XK_braille_dots_1236 0x1002827 /* U+2827 BRAILLE PATTERN DOTS-1236 */ -#define XK_braille_dots_46 0x1002828 /* U+2828 BRAILLE PATTERN DOTS-46 */ -#define XK_braille_dots_146 0x1002829 /* U+2829 BRAILLE PATTERN DOTS-146 */ -#define XK_braille_dots_246 0x100282a /* U+282a BRAILLE PATTERN DOTS-246 */ -#define XK_braille_dots_1246 0x100282b /* U+282b BRAILLE PATTERN DOTS-1246 */ -#define XK_braille_dots_346 0x100282c /* U+282c BRAILLE PATTERN DOTS-346 */ -#define XK_braille_dots_1346 0x100282d /* U+282d BRAILLE PATTERN DOTS-1346 */ -#define XK_braille_dots_2346 0x100282e /* U+282e BRAILLE PATTERN DOTS-2346 */ -#define XK_braille_dots_12346 0x100282f /* U+282f BRAILLE PATTERN DOTS-12346 */ -#define XK_braille_dots_56 0x1002830 /* U+2830 BRAILLE PATTERN DOTS-56 */ -#define XK_braille_dots_156 0x1002831 /* U+2831 BRAILLE PATTERN DOTS-156 */ -#define XK_braille_dots_256 0x1002832 /* U+2832 BRAILLE PATTERN DOTS-256 */ -#define XK_braille_dots_1256 0x1002833 /* U+2833 BRAILLE PATTERN DOTS-1256 */ -#define XK_braille_dots_356 0x1002834 /* U+2834 BRAILLE PATTERN DOTS-356 */ -#define XK_braille_dots_1356 0x1002835 /* U+2835 BRAILLE PATTERN DOTS-1356 */ -#define XK_braille_dots_2356 0x1002836 /* U+2836 BRAILLE PATTERN DOTS-2356 */ -#define XK_braille_dots_12356 0x1002837 /* U+2837 BRAILLE PATTERN DOTS-12356 */ -#define XK_braille_dots_456 0x1002838 /* U+2838 BRAILLE PATTERN DOTS-456 */ -#define XK_braille_dots_1456 0x1002839 /* U+2839 BRAILLE PATTERN DOTS-1456 */ -#define XK_braille_dots_2456 0x100283a /* U+283a BRAILLE PATTERN DOTS-2456 */ -#define XK_braille_dots_12456 0x100283b /* U+283b BRAILLE PATTERN DOTS-12456 */ -#define XK_braille_dots_3456 0x100283c /* U+283c BRAILLE PATTERN DOTS-3456 */ -#define XK_braille_dots_13456 0x100283d /* U+283d BRAILLE PATTERN DOTS-13456 */ -#define XK_braille_dots_23456 0x100283e /* U+283e BRAILLE PATTERN DOTS-23456 */ -#define XK_braille_dots_123456 0x100283f /* U+283f BRAILLE PATTERN DOTS-123456 */ -#define XK_braille_dots_7 0x1002840 /* U+2840 BRAILLE PATTERN DOTS-7 */ -#define XK_braille_dots_17 0x1002841 /* U+2841 BRAILLE PATTERN DOTS-17 */ -#define XK_braille_dots_27 0x1002842 /* U+2842 BRAILLE PATTERN DOTS-27 */ -#define XK_braille_dots_127 0x1002843 /* U+2843 BRAILLE PATTERN DOTS-127 */ -#define XK_braille_dots_37 0x1002844 /* U+2844 BRAILLE PATTERN DOTS-37 */ -#define XK_braille_dots_137 0x1002845 /* U+2845 BRAILLE PATTERN DOTS-137 */ -#define XK_braille_dots_237 0x1002846 /* U+2846 BRAILLE PATTERN DOTS-237 */ -#define XK_braille_dots_1237 0x1002847 /* U+2847 BRAILLE PATTERN DOTS-1237 */ -#define XK_braille_dots_47 0x1002848 /* U+2848 BRAILLE PATTERN DOTS-47 */ -#define XK_braille_dots_147 0x1002849 /* U+2849 BRAILLE PATTERN DOTS-147 */ -#define XK_braille_dots_247 0x100284a /* U+284a BRAILLE PATTERN DOTS-247 */ -#define XK_braille_dots_1247 0x100284b /* U+284b BRAILLE PATTERN DOTS-1247 */ -#define XK_braille_dots_347 0x100284c /* U+284c BRAILLE PATTERN DOTS-347 */ -#define XK_braille_dots_1347 0x100284d /* U+284d BRAILLE PATTERN DOTS-1347 */ -#define XK_braille_dots_2347 0x100284e /* U+284e BRAILLE PATTERN DOTS-2347 */ -#define XK_braille_dots_12347 0x100284f /* U+284f BRAILLE PATTERN DOTS-12347 */ -#define XK_braille_dots_57 0x1002850 /* U+2850 BRAILLE PATTERN DOTS-57 */ -#define XK_braille_dots_157 0x1002851 /* U+2851 BRAILLE PATTERN DOTS-157 */ -#define XK_braille_dots_257 0x1002852 /* U+2852 BRAILLE PATTERN DOTS-257 */ -#define XK_braille_dots_1257 0x1002853 /* U+2853 BRAILLE PATTERN DOTS-1257 */ -#define XK_braille_dots_357 0x1002854 /* U+2854 BRAILLE PATTERN DOTS-357 */ -#define XK_braille_dots_1357 0x1002855 /* U+2855 BRAILLE PATTERN DOTS-1357 */ -#define XK_braille_dots_2357 0x1002856 /* U+2856 BRAILLE PATTERN DOTS-2357 */ -#define XK_braille_dots_12357 0x1002857 /* U+2857 BRAILLE PATTERN DOTS-12357 */ -#define XK_braille_dots_457 0x1002858 /* U+2858 BRAILLE PATTERN DOTS-457 */ -#define XK_braille_dots_1457 0x1002859 /* U+2859 BRAILLE PATTERN DOTS-1457 */ -#define XK_braille_dots_2457 0x100285a /* U+285a BRAILLE PATTERN DOTS-2457 */ -#define XK_braille_dots_12457 0x100285b /* U+285b BRAILLE PATTERN DOTS-12457 */ -#define XK_braille_dots_3457 0x100285c /* U+285c BRAILLE PATTERN DOTS-3457 */ -#define XK_braille_dots_13457 0x100285d /* U+285d BRAILLE PATTERN DOTS-13457 */ -#define XK_braille_dots_23457 0x100285e /* U+285e BRAILLE PATTERN DOTS-23457 */ -#define XK_braille_dots_123457 0x100285f /* U+285f BRAILLE PATTERN DOTS-123457 */ -#define XK_braille_dots_67 0x1002860 /* U+2860 BRAILLE PATTERN DOTS-67 */ -#define XK_braille_dots_167 0x1002861 /* U+2861 BRAILLE PATTERN DOTS-167 */ -#define XK_braille_dots_267 0x1002862 /* U+2862 BRAILLE PATTERN DOTS-267 */ -#define XK_braille_dots_1267 0x1002863 /* U+2863 BRAILLE PATTERN DOTS-1267 */ -#define XK_braille_dots_367 0x1002864 /* U+2864 BRAILLE PATTERN DOTS-367 */ -#define XK_braille_dots_1367 0x1002865 /* U+2865 BRAILLE PATTERN DOTS-1367 */ -#define XK_braille_dots_2367 0x1002866 /* U+2866 BRAILLE PATTERN DOTS-2367 */ -#define XK_braille_dots_12367 0x1002867 /* U+2867 BRAILLE PATTERN DOTS-12367 */ -#define XK_braille_dots_467 0x1002868 /* U+2868 BRAILLE PATTERN DOTS-467 */ -#define XK_braille_dots_1467 0x1002869 /* U+2869 BRAILLE PATTERN DOTS-1467 */ -#define XK_braille_dots_2467 0x100286a /* U+286a BRAILLE PATTERN DOTS-2467 */ -#define XK_braille_dots_12467 0x100286b /* U+286b BRAILLE PATTERN DOTS-12467 */ -#define XK_braille_dots_3467 0x100286c /* U+286c BRAILLE PATTERN DOTS-3467 */ -#define XK_braille_dots_13467 0x100286d /* U+286d BRAILLE PATTERN DOTS-13467 */ -#define XK_braille_dots_23467 0x100286e /* U+286e BRAILLE PATTERN DOTS-23467 */ -#define XK_braille_dots_123467 0x100286f /* U+286f BRAILLE PATTERN DOTS-123467 */ -#define XK_braille_dots_567 0x1002870 /* U+2870 BRAILLE PATTERN DOTS-567 */ -#define XK_braille_dots_1567 0x1002871 /* U+2871 BRAILLE PATTERN DOTS-1567 */ -#define XK_braille_dots_2567 0x1002872 /* U+2872 BRAILLE PATTERN DOTS-2567 */ -#define XK_braille_dots_12567 0x1002873 /* U+2873 BRAILLE PATTERN DOTS-12567 */ -#define XK_braille_dots_3567 0x1002874 /* U+2874 BRAILLE PATTERN DOTS-3567 */ -#define XK_braille_dots_13567 0x1002875 /* U+2875 BRAILLE PATTERN DOTS-13567 */ -#define XK_braille_dots_23567 0x1002876 /* U+2876 BRAILLE PATTERN DOTS-23567 */ -#define XK_braille_dots_123567 0x1002877 /* U+2877 BRAILLE PATTERN DOTS-123567 */ -#define XK_braille_dots_4567 0x1002878 /* U+2878 BRAILLE PATTERN DOTS-4567 */ -#define XK_braille_dots_14567 0x1002879 /* U+2879 BRAILLE PATTERN DOTS-14567 */ -#define XK_braille_dots_24567 0x100287a /* U+287a BRAILLE PATTERN DOTS-24567 */ -#define XK_braille_dots_124567 0x100287b /* U+287b BRAILLE PATTERN DOTS-124567 */ -#define XK_braille_dots_34567 0x100287c /* U+287c BRAILLE PATTERN DOTS-34567 */ -#define XK_braille_dots_134567 0x100287d /* U+287d BRAILLE PATTERN DOTS-134567 */ -#define XK_braille_dots_234567 0x100287e /* U+287e BRAILLE PATTERN DOTS-234567 */ -#define XK_braille_dots_1234567 0x100287f /* U+287f BRAILLE PATTERN DOTS-1234567 */ -#define XK_braille_dots_8 0x1002880 /* U+2880 BRAILLE PATTERN DOTS-8 */ -#define XK_braille_dots_18 0x1002881 /* U+2881 BRAILLE PATTERN DOTS-18 */ -#define XK_braille_dots_28 0x1002882 /* U+2882 BRAILLE PATTERN DOTS-28 */ -#define XK_braille_dots_128 0x1002883 /* U+2883 BRAILLE PATTERN DOTS-128 */ -#define XK_braille_dots_38 0x1002884 /* U+2884 BRAILLE PATTERN DOTS-38 */ -#define XK_braille_dots_138 0x1002885 /* U+2885 BRAILLE PATTERN DOTS-138 */ -#define XK_braille_dots_238 0x1002886 /* U+2886 BRAILLE PATTERN DOTS-238 */ -#define XK_braille_dots_1238 0x1002887 /* U+2887 BRAILLE PATTERN DOTS-1238 */ -#define XK_braille_dots_48 0x1002888 /* U+2888 BRAILLE PATTERN DOTS-48 */ -#define XK_braille_dots_148 0x1002889 /* U+2889 BRAILLE PATTERN DOTS-148 */ -#define XK_braille_dots_248 0x100288a /* U+288a BRAILLE PATTERN DOTS-248 */ -#define XK_braille_dots_1248 0x100288b /* U+288b BRAILLE PATTERN DOTS-1248 */ -#define XK_braille_dots_348 0x100288c /* U+288c BRAILLE PATTERN DOTS-348 */ -#define XK_braille_dots_1348 0x100288d /* U+288d BRAILLE PATTERN DOTS-1348 */ -#define XK_braille_dots_2348 0x100288e /* U+288e BRAILLE PATTERN DOTS-2348 */ -#define XK_braille_dots_12348 0x100288f /* U+288f BRAILLE PATTERN DOTS-12348 */ -#define XK_braille_dots_58 0x1002890 /* U+2890 BRAILLE PATTERN DOTS-58 */ -#define XK_braille_dots_158 0x1002891 /* U+2891 BRAILLE PATTERN DOTS-158 */ -#define XK_braille_dots_258 0x1002892 /* U+2892 BRAILLE PATTERN DOTS-258 */ -#define XK_braille_dots_1258 0x1002893 /* U+2893 BRAILLE PATTERN DOTS-1258 */ -#define XK_braille_dots_358 0x1002894 /* U+2894 BRAILLE PATTERN DOTS-358 */ -#define XK_braille_dots_1358 0x1002895 /* U+2895 BRAILLE PATTERN DOTS-1358 */ -#define XK_braille_dots_2358 0x1002896 /* U+2896 BRAILLE PATTERN DOTS-2358 */ -#define XK_braille_dots_12358 0x1002897 /* U+2897 BRAILLE PATTERN DOTS-12358 */ -#define XK_braille_dots_458 0x1002898 /* U+2898 BRAILLE PATTERN DOTS-458 */ -#define XK_braille_dots_1458 0x1002899 /* U+2899 BRAILLE PATTERN DOTS-1458 */ -#define XK_braille_dots_2458 0x100289a /* U+289a BRAILLE PATTERN DOTS-2458 */ -#define XK_braille_dots_12458 0x100289b /* U+289b BRAILLE PATTERN DOTS-12458 */ -#define XK_braille_dots_3458 0x100289c /* U+289c BRAILLE PATTERN DOTS-3458 */ -#define XK_braille_dots_13458 0x100289d /* U+289d BRAILLE PATTERN DOTS-13458 */ -#define XK_braille_dots_23458 0x100289e /* U+289e BRAILLE PATTERN DOTS-23458 */ -#define XK_braille_dots_123458 0x100289f /* U+289f BRAILLE PATTERN DOTS-123458 */ -#define XK_braille_dots_68 0x10028a0 /* U+28a0 BRAILLE PATTERN DOTS-68 */ -#define XK_braille_dots_168 0x10028a1 /* U+28a1 BRAILLE PATTERN DOTS-168 */ -#define XK_braille_dots_268 0x10028a2 /* U+28a2 BRAILLE PATTERN DOTS-268 */ -#define XK_braille_dots_1268 0x10028a3 /* U+28a3 BRAILLE PATTERN DOTS-1268 */ -#define XK_braille_dots_368 0x10028a4 /* U+28a4 BRAILLE PATTERN DOTS-368 */ -#define XK_braille_dots_1368 0x10028a5 /* U+28a5 BRAILLE PATTERN DOTS-1368 */ -#define XK_braille_dots_2368 0x10028a6 /* U+28a6 BRAILLE PATTERN DOTS-2368 */ -#define XK_braille_dots_12368 0x10028a7 /* U+28a7 BRAILLE PATTERN DOTS-12368 */ -#define XK_braille_dots_468 0x10028a8 /* U+28a8 BRAILLE PATTERN DOTS-468 */ -#define XK_braille_dots_1468 0x10028a9 /* U+28a9 BRAILLE PATTERN DOTS-1468 */ -#define XK_braille_dots_2468 0x10028aa /* U+28aa BRAILLE PATTERN DOTS-2468 */ -#define XK_braille_dots_12468 0x10028ab /* U+28ab BRAILLE PATTERN DOTS-12468 */ -#define XK_braille_dots_3468 0x10028ac /* U+28ac BRAILLE PATTERN DOTS-3468 */ -#define XK_braille_dots_13468 0x10028ad /* U+28ad BRAILLE PATTERN DOTS-13468 */ -#define XK_braille_dots_23468 0x10028ae /* U+28ae BRAILLE PATTERN DOTS-23468 */ -#define XK_braille_dots_123468 0x10028af /* U+28af BRAILLE PATTERN DOTS-123468 */ -#define XK_braille_dots_568 0x10028b0 /* U+28b0 BRAILLE PATTERN DOTS-568 */ -#define XK_braille_dots_1568 0x10028b1 /* U+28b1 BRAILLE PATTERN DOTS-1568 */ -#define XK_braille_dots_2568 0x10028b2 /* U+28b2 BRAILLE PATTERN DOTS-2568 */ -#define XK_braille_dots_12568 0x10028b3 /* U+28b3 BRAILLE PATTERN DOTS-12568 */ -#define XK_braille_dots_3568 0x10028b4 /* U+28b4 BRAILLE PATTERN DOTS-3568 */ -#define XK_braille_dots_13568 0x10028b5 /* U+28b5 BRAILLE PATTERN DOTS-13568 */ -#define XK_braille_dots_23568 0x10028b6 /* U+28b6 BRAILLE PATTERN DOTS-23568 */ -#define XK_braille_dots_123568 0x10028b7 /* U+28b7 BRAILLE PATTERN DOTS-123568 */ -#define XK_braille_dots_4568 0x10028b8 /* U+28b8 BRAILLE PATTERN DOTS-4568 */ -#define XK_braille_dots_14568 0x10028b9 /* U+28b9 BRAILLE PATTERN DOTS-14568 */ -#define XK_braille_dots_24568 0x10028ba /* U+28ba BRAILLE PATTERN DOTS-24568 */ -#define XK_braille_dots_124568 0x10028bb /* U+28bb BRAILLE PATTERN DOTS-124568 */ -#define XK_braille_dots_34568 0x10028bc /* U+28bc BRAILLE PATTERN DOTS-34568 */ -#define XK_braille_dots_134568 0x10028bd /* U+28bd BRAILLE PATTERN DOTS-134568 */ -#define XK_braille_dots_234568 0x10028be /* U+28be BRAILLE PATTERN DOTS-234568 */ -#define XK_braille_dots_1234568 0x10028bf /* U+28bf BRAILLE PATTERN DOTS-1234568 */ -#define XK_braille_dots_78 0x10028c0 /* U+28c0 BRAILLE PATTERN DOTS-78 */ -#define XK_braille_dots_178 0x10028c1 /* U+28c1 BRAILLE PATTERN DOTS-178 */ -#define XK_braille_dots_278 0x10028c2 /* U+28c2 BRAILLE PATTERN DOTS-278 */ -#define XK_braille_dots_1278 0x10028c3 /* U+28c3 BRAILLE PATTERN DOTS-1278 */ -#define XK_braille_dots_378 0x10028c4 /* U+28c4 BRAILLE PATTERN DOTS-378 */ -#define XK_braille_dots_1378 0x10028c5 /* U+28c5 BRAILLE PATTERN DOTS-1378 */ -#define XK_braille_dots_2378 0x10028c6 /* U+28c6 BRAILLE PATTERN DOTS-2378 */ -#define XK_braille_dots_12378 0x10028c7 /* U+28c7 BRAILLE PATTERN DOTS-12378 */ -#define XK_braille_dots_478 0x10028c8 /* U+28c8 BRAILLE PATTERN DOTS-478 */ -#define XK_braille_dots_1478 0x10028c9 /* U+28c9 BRAILLE PATTERN DOTS-1478 */ -#define XK_braille_dots_2478 0x10028ca /* U+28ca BRAILLE PATTERN DOTS-2478 */ -#define XK_braille_dots_12478 0x10028cb /* U+28cb BRAILLE PATTERN DOTS-12478 */ -#define XK_braille_dots_3478 0x10028cc /* U+28cc BRAILLE PATTERN DOTS-3478 */ -#define XK_braille_dots_13478 0x10028cd /* U+28cd BRAILLE PATTERN DOTS-13478 */ -#define XK_braille_dots_23478 0x10028ce /* U+28ce BRAILLE PATTERN DOTS-23478 */ -#define XK_braille_dots_123478 0x10028cf /* U+28cf BRAILLE PATTERN DOTS-123478 */ -#define XK_braille_dots_578 0x10028d0 /* U+28d0 BRAILLE PATTERN DOTS-578 */ -#define XK_braille_dots_1578 0x10028d1 /* U+28d1 BRAILLE PATTERN DOTS-1578 */ -#define XK_braille_dots_2578 0x10028d2 /* U+28d2 BRAILLE PATTERN DOTS-2578 */ -#define XK_braille_dots_12578 0x10028d3 /* U+28d3 BRAILLE PATTERN DOTS-12578 */ -#define XK_braille_dots_3578 0x10028d4 /* U+28d4 BRAILLE PATTERN DOTS-3578 */ -#define XK_braille_dots_13578 0x10028d5 /* U+28d5 BRAILLE PATTERN DOTS-13578 */ -#define XK_braille_dots_23578 0x10028d6 /* U+28d6 BRAILLE PATTERN DOTS-23578 */ -#define XK_braille_dots_123578 0x10028d7 /* U+28d7 BRAILLE PATTERN DOTS-123578 */ -#define XK_braille_dots_4578 0x10028d8 /* U+28d8 BRAILLE PATTERN DOTS-4578 */ -#define XK_braille_dots_14578 0x10028d9 /* U+28d9 BRAILLE PATTERN DOTS-14578 */ -#define XK_braille_dots_24578 0x10028da /* U+28da BRAILLE PATTERN DOTS-24578 */ -#define XK_braille_dots_124578 0x10028db /* U+28db BRAILLE PATTERN DOTS-124578 */ -#define XK_braille_dots_34578 0x10028dc /* U+28dc BRAILLE PATTERN DOTS-34578 */ -#define XK_braille_dots_134578 0x10028dd /* U+28dd BRAILLE PATTERN DOTS-134578 */ -#define XK_braille_dots_234578 0x10028de /* U+28de BRAILLE PATTERN DOTS-234578 */ -#define XK_braille_dots_1234578 0x10028df /* U+28df BRAILLE PATTERN DOTS-1234578 */ -#define XK_braille_dots_678 0x10028e0 /* U+28e0 BRAILLE PATTERN DOTS-678 */ -#define XK_braille_dots_1678 0x10028e1 /* U+28e1 BRAILLE PATTERN DOTS-1678 */ -#define XK_braille_dots_2678 0x10028e2 /* U+28e2 BRAILLE PATTERN DOTS-2678 */ -#define XK_braille_dots_12678 0x10028e3 /* U+28e3 BRAILLE PATTERN DOTS-12678 */ -#define XK_braille_dots_3678 0x10028e4 /* U+28e4 BRAILLE PATTERN DOTS-3678 */ -#define XK_braille_dots_13678 0x10028e5 /* U+28e5 BRAILLE PATTERN DOTS-13678 */ -#define XK_braille_dots_23678 0x10028e6 /* U+28e6 BRAILLE PATTERN DOTS-23678 */ -#define XK_braille_dots_123678 0x10028e7 /* U+28e7 BRAILLE PATTERN DOTS-123678 */ -#define XK_braille_dots_4678 0x10028e8 /* U+28e8 BRAILLE PATTERN DOTS-4678 */ -#define XK_braille_dots_14678 0x10028e9 /* U+28e9 BRAILLE PATTERN DOTS-14678 */ -#define XK_braille_dots_24678 0x10028ea /* U+28ea BRAILLE PATTERN DOTS-24678 */ -#define XK_braille_dots_124678 0x10028eb /* U+28eb BRAILLE PATTERN DOTS-124678 */ -#define XK_braille_dots_34678 0x10028ec /* U+28ec BRAILLE PATTERN DOTS-34678 */ -#define XK_braille_dots_134678 0x10028ed /* U+28ed BRAILLE PATTERN DOTS-134678 */ -#define XK_braille_dots_234678 0x10028ee /* U+28ee BRAILLE PATTERN DOTS-234678 */ -#define XK_braille_dots_1234678 0x10028ef /* U+28ef BRAILLE PATTERN DOTS-1234678 */ -#define XK_braille_dots_5678 0x10028f0 /* U+28f0 BRAILLE PATTERN DOTS-5678 */ -#define XK_braille_dots_15678 0x10028f1 /* U+28f1 BRAILLE PATTERN DOTS-15678 */ -#define XK_braille_dots_25678 0x10028f2 /* U+28f2 BRAILLE PATTERN DOTS-25678 */ -#define XK_braille_dots_125678 0x10028f3 /* U+28f3 BRAILLE PATTERN DOTS-125678 */ -#define XK_braille_dots_35678 0x10028f4 /* U+28f4 BRAILLE PATTERN DOTS-35678 */ -#define XK_braille_dots_135678 0x10028f5 /* U+28f5 BRAILLE PATTERN DOTS-135678 */ -#define XK_braille_dots_235678 0x10028f6 /* U+28f6 BRAILLE PATTERN DOTS-235678 */ -#define XK_braille_dots_1235678 0x10028f7 /* U+28f7 BRAILLE PATTERN DOTS-1235678 */ -#define XK_braille_dots_45678 0x10028f8 /* U+28f8 BRAILLE PATTERN DOTS-45678 */ -#define XK_braille_dots_145678 0x10028f9 /* U+28f9 BRAILLE PATTERN DOTS-145678 */ -#define XK_braille_dots_245678 0x10028fa /* U+28fa BRAILLE PATTERN DOTS-245678 */ -#define XK_braille_dots_1245678 0x10028fb /* U+28fb BRAILLE PATTERN DOTS-1245678 */ -#define XK_braille_dots_345678 0x10028fc /* U+28fc BRAILLE PATTERN DOTS-345678 */ -#define XK_braille_dots_1345678 0x10028fd /* U+28fd BRAILLE PATTERN DOTS-1345678 */ -#define XK_braille_dots_2345678 0x10028fe /* U+28fe BRAILLE PATTERN DOTS-2345678 */ -#define XK_braille_dots_12345678 0x10028ff /* U+28ff BRAILLE PATTERN DOTS-12345678 */ -#endif /* XK_BRAILLE */ +#define XK_braille_dot_1 0xfff1 +#define XK_braille_dot_2 0xfff2 +#define XK_braille_dot_3 0xfff3 +#define XK_braille_dot_4 0xfff4 +#define XK_braille_dot_5 0xfff5 +#define XK_braille_dot_6 0xfff6 +#define XK_braille_dot_7 0xfff7 +#define XK_braille_dot_8 0xfff8 +#define XK_braille_dot_9 0xfff9 +#define XK_braille_dot_10 0xfffa +#define XK_braille_blank 0x1002800 /* U+2800 BRAILLE PATTERN BLANK */ +#define XK_braille_dots_1 0x1002801 /* U+2801 BRAILLE PATTERN DOTS-1 */ +#define XK_braille_dots_2 0x1002802 /* U+2802 BRAILLE PATTERN DOTS-2 */ +#define XK_braille_dots_12 0x1002803 /* U+2803 BRAILLE PATTERN DOTS-12 */ +#define XK_braille_dots_3 0x1002804 /* U+2804 BRAILLE PATTERN DOTS-3 */ +#define XK_braille_dots_13 0x1002805 /* U+2805 BRAILLE PATTERN DOTS-13 */ +#define XK_braille_dots_23 0x1002806 /* U+2806 BRAILLE PATTERN DOTS-23 */ +#define XK_braille_dots_123 0x1002807 /* U+2807 BRAILLE PATTERN DOTS-123 */ +#define XK_braille_dots_4 0x1002808 /* U+2808 BRAILLE PATTERN DOTS-4 */ +#define XK_braille_dots_14 0x1002809 /* U+2809 BRAILLE PATTERN DOTS-14 */ +#define XK_braille_dots_24 0x100280a /* U+280a BRAILLE PATTERN DOTS-24 */ +#define XK_braille_dots_124 0x100280b /* U+280b BRAILLE PATTERN DOTS-124 */ +#define XK_braille_dots_34 0x100280c /* U+280c BRAILLE PATTERN DOTS-34 */ +#define XK_braille_dots_134 0x100280d /* U+280d BRAILLE PATTERN DOTS-134 */ +#define XK_braille_dots_234 0x100280e /* U+280e BRAILLE PATTERN DOTS-234 */ +#define XK_braille_dots_1234 0x100280f /* U+280f BRAILLE PATTERN DOTS-1234 */ +#define XK_braille_dots_5 0x1002810 /* U+2810 BRAILLE PATTERN DOTS-5 */ +#define XK_braille_dots_15 0x1002811 /* U+2811 BRAILLE PATTERN DOTS-15 */ +#define XK_braille_dots_25 0x1002812 /* U+2812 BRAILLE PATTERN DOTS-25 */ +#define XK_braille_dots_125 0x1002813 /* U+2813 BRAILLE PATTERN DOTS-125 */ +#define XK_braille_dots_35 0x1002814 /* U+2814 BRAILLE PATTERN DOTS-35 */ +#define XK_braille_dots_135 0x1002815 /* U+2815 BRAILLE PATTERN DOTS-135 */ +#define XK_braille_dots_235 0x1002816 /* U+2816 BRAILLE PATTERN DOTS-235 */ +#define XK_braille_dots_1235 0x1002817 /* U+2817 BRAILLE PATTERN DOTS-1235 */ +#define XK_braille_dots_45 0x1002818 /* U+2818 BRAILLE PATTERN DOTS-45 */ +#define XK_braille_dots_145 0x1002819 /* U+2819 BRAILLE PATTERN DOTS-145 */ +#define XK_braille_dots_245 0x100281a /* U+281a BRAILLE PATTERN DOTS-245 */ +#define XK_braille_dots_1245 0x100281b /* U+281b BRAILLE PATTERN DOTS-1245 */ +#define XK_braille_dots_345 0x100281c /* U+281c BRAILLE PATTERN DOTS-345 */ +#define XK_braille_dots_1345 0x100281d /* U+281d BRAILLE PATTERN DOTS-1345 */ +#define XK_braille_dots_2345 0x100281e /* U+281e BRAILLE PATTERN DOTS-2345 */ +#define XK_braille_dots_12345 0x100281f /* U+281f BRAILLE PATTERN DOTS-12345 */ +#define XK_braille_dots_6 0x1002820 /* U+2820 BRAILLE PATTERN DOTS-6 */ +#define XK_braille_dots_16 0x1002821 /* U+2821 BRAILLE PATTERN DOTS-16 */ +#define XK_braille_dots_26 0x1002822 /* U+2822 BRAILLE PATTERN DOTS-26 */ +#define XK_braille_dots_126 0x1002823 /* U+2823 BRAILLE PATTERN DOTS-126 */ +#define XK_braille_dots_36 0x1002824 /* U+2824 BRAILLE PATTERN DOTS-36 */ +#define XK_braille_dots_136 0x1002825 /* U+2825 BRAILLE PATTERN DOTS-136 */ +#define XK_braille_dots_236 0x1002826 /* U+2826 BRAILLE PATTERN DOTS-236 */ +#define XK_braille_dots_1236 0x1002827 /* U+2827 BRAILLE PATTERN DOTS-1236 */ +#define XK_braille_dots_46 0x1002828 /* U+2828 BRAILLE PATTERN DOTS-46 */ +#define XK_braille_dots_146 0x1002829 /* U+2829 BRAILLE PATTERN DOTS-146 */ +#define XK_braille_dots_246 0x100282a /* U+282a BRAILLE PATTERN DOTS-246 */ +#define XK_braille_dots_1246 0x100282b /* U+282b BRAILLE PATTERN DOTS-1246 */ +#define XK_braille_dots_346 0x100282c /* U+282c BRAILLE PATTERN DOTS-346 */ +#define XK_braille_dots_1346 0x100282d /* U+282d BRAILLE PATTERN DOTS-1346 */ +#define XK_braille_dots_2346 0x100282e /* U+282e BRAILLE PATTERN DOTS-2346 */ +#define XK_braille_dots_12346 0x100282f /* U+282f BRAILLE PATTERN DOTS-12346 */ +#define XK_braille_dots_56 0x1002830 /* U+2830 BRAILLE PATTERN DOTS-56 */ +#define XK_braille_dots_156 0x1002831 /* U+2831 BRAILLE PATTERN DOTS-156 */ +#define XK_braille_dots_256 0x1002832 /* U+2832 BRAILLE PATTERN DOTS-256 */ +#define XK_braille_dots_1256 0x1002833 /* U+2833 BRAILLE PATTERN DOTS-1256 */ +#define XK_braille_dots_356 0x1002834 /* U+2834 BRAILLE PATTERN DOTS-356 */ +#define XK_braille_dots_1356 0x1002835 /* U+2835 BRAILLE PATTERN DOTS-1356 */ +#define XK_braille_dots_2356 0x1002836 /* U+2836 BRAILLE PATTERN DOTS-2356 */ +#define XK_braille_dots_12356 0x1002837 /* U+2837 BRAILLE PATTERN DOTS-12356 */ +#define XK_braille_dots_456 0x1002838 /* U+2838 BRAILLE PATTERN DOTS-456 */ +#define XK_braille_dots_1456 0x1002839 /* U+2839 BRAILLE PATTERN DOTS-1456 */ +#define XK_braille_dots_2456 0x100283a /* U+283a BRAILLE PATTERN DOTS-2456 */ +#define XK_braille_dots_12456 0x100283b /* U+283b BRAILLE PATTERN DOTS-12456 */ +#define XK_braille_dots_3456 0x100283c /* U+283c BRAILLE PATTERN DOTS-3456 */ +#define XK_braille_dots_13456 0x100283d /* U+283d BRAILLE PATTERN DOTS-13456 */ +#define XK_braille_dots_23456 0x100283e /* U+283e BRAILLE PATTERN DOTS-23456 */ +#define XK_braille_dots_123456 0x100283f /* U+283f BRAILLE PATTERN DOTS-123456 */ +#define XK_braille_dots_7 0x1002840 /* U+2840 BRAILLE PATTERN DOTS-7 */ +#define XK_braille_dots_17 0x1002841 /* U+2841 BRAILLE PATTERN DOTS-17 */ +#define XK_braille_dots_27 0x1002842 /* U+2842 BRAILLE PATTERN DOTS-27 */ +#define XK_braille_dots_127 0x1002843 /* U+2843 BRAILLE PATTERN DOTS-127 */ +#define XK_braille_dots_37 0x1002844 /* U+2844 BRAILLE PATTERN DOTS-37 */ +#define XK_braille_dots_137 0x1002845 /* U+2845 BRAILLE PATTERN DOTS-137 */ +#define XK_braille_dots_237 0x1002846 /* U+2846 BRAILLE PATTERN DOTS-237 */ +#define XK_braille_dots_1237 0x1002847 /* U+2847 BRAILLE PATTERN DOTS-1237 */ +#define XK_braille_dots_47 0x1002848 /* U+2848 BRAILLE PATTERN DOTS-47 */ +#define XK_braille_dots_147 0x1002849 /* U+2849 BRAILLE PATTERN DOTS-147 */ +#define XK_braille_dots_247 0x100284a /* U+284a BRAILLE PATTERN DOTS-247 */ +#define XK_braille_dots_1247 0x100284b /* U+284b BRAILLE PATTERN DOTS-1247 */ +#define XK_braille_dots_347 0x100284c /* U+284c BRAILLE PATTERN DOTS-347 */ +#define XK_braille_dots_1347 0x100284d /* U+284d BRAILLE PATTERN DOTS-1347 */ +#define XK_braille_dots_2347 0x100284e /* U+284e BRAILLE PATTERN DOTS-2347 */ +#define XK_braille_dots_12347 0x100284f /* U+284f BRAILLE PATTERN DOTS-12347 */ +#define XK_braille_dots_57 0x1002850 /* U+2850 BRAILLE PATTERN DOTS-57 */ +#define XK_braille_dots_157 0x1002851 /* U+2851 BRAILLE PATTERN DOTS-157 */ +#define XK_braille_dots_257 0x1002852 /* U+2852 BRAILLE PATTERN DOTS-257 */ +#define XK_braille_dots_1257 0x1002853 /* U+2853 BRAILLE PATTERN DOTS-1257 */ +#define XK_braille_dots_357 0x1002854 /* U+2854 BRAILLE PATTERN DOTS-357 */ +#define XK_braille_dots_1357 0x1002855 /* U+2855 BRAILLE PATTERN DOTS-1357 */ +#define XK_braille_dots_2357 0x1002856 /* U+2856 BRAILLE PATTERN DOTS-2357 */ +#define XK_braille_dots_12357 0x1002857 /* U+2857 BRAILLE PATTERN DOTS-12357 */ +#define XK_braille_dots_457 0x1002858 /* U+2858 BRAILLE PATTERN DOTS-457 */ +#define XK_braille_dots_1457 0x1002859 /* U+2859 BRAILLE PATTERN DOTS-1457 */ +#define XK_braille_dots_2457 0x100285a /* U+285a BRAILLE PATTERN DOTS-2457 */ +#define XK_braille_dots_12457 0x100285b /* U+285b BRAILLE PATTERN DOTS-12457 */ +#define XK_braille_dots_3457 0x100285c /* U+285c BRAILLE PATTERN DOTS-3457 */ +#define XK_braille_dots_13457 0x100285d /* U+285d BRAILLE PATTERN DOTS-13457 */ +#define XK_braille_dots_23457 0x100285e /* U+285e BRAILLE PATTERN DOTS-23457 */ +#define XK_braille_dots_123457 0x100285f /* U+285f BRAILLE PATTERN DOTS-123457 */ +#define XK_braille_dots_67 0x1002860 /* U+2860 BRAILLE PATTERN DOTS-67 */ +#define XK_braille_dots_167 0x1002861 /* U+2861 BRAILLE PATTERN DOTS-167 */ +#define XK_braille_dots_267 0x1002862 /* U+2862 BRAILLE PATTERN DOTS-267 */ +#define XK_braille_dots_1267 0x1002863 /* U+2863 BRAILLE PATTERN DOTS-1267 */ +#define XK_braille_dots_367 0x1002864 /* U+2864 BRAILLE PATTERN DOTS-367 */ +#define XK_braille_dots_1367 0x1002865 /* U+2865 BRAILLE PATTERN DOTS-1367 */ +#define XK_braille_dots_2367 0x1002866 /* U+2866 BRAILLE PATTERN DOTS-2367 */ +#define XK_braille_dots_12367 0x1002867 /* U+2867 BRAILLE PATTERN DOTS-12367 */ +#define XK_braille_dots_467 0x1002868 /* U+2868 BRAILLE PATTERN DOTS-467 */ +#define XK_braille_dots_1467 0x1002869 /* U+2869 BRAILLE PATTERN DOTS-1467 */ +#define XK_braille_dots_2467 0x100286a /* U+286a BRAILLE PATTERN DOTS-2467 */ +#define XK_braille_dots_12467 0x100286b /* U+286b BRAILLE PATTERN DOTS-12467 */ +#define XK_braille_dots_3467 0x100286c /* U+286c BRAILLE PATTERN DOTS-3467 */ +#define XK_braille_dots_13467 0x100286d /* U+286d BRAILLE PATTERN DOTS-13467 */ +#define XK_braille_dots_23467 0x100286e /* U+286e BRAILLE PATTERN DOTS-23467 */ +#define XK_braille_dots_123467 0x100286f /* U+286f BRAILLE PATTERN DOTS-123467 */ +#define XK_braille_dots_567 0x1002870 /* U+2870 BRAILLE PATTERN DOTS-567 */ +#define XK_braille_dots_1567 0x1002871 /* U+2871 BRAILLE PATTERN DOTS-1567 */ +#define XK_braille_dots_2567 0x1002872 /* U+2872 BRAILLE PATTERN DOTS-2567 */ +#define XK_braille_dots_12567 0x1002873 /* U+2873 BRAILLE PATTERN DOTS-12567 */ +#define XK_braille_dots_3567 0x1002874 /* U+2874 BRAILLE PATTERN DOTS-3567 */ +#define XK_braille_dots_13567 0x1002875 /* U+2875 BRAILLE PATTERN DOTS-13567 */ +#define XK_braille_dots_23567 0x1002876 /* U+2876 BRAILLE PATTERN DOTS-23567 */ +#define XK_braille_dots_123567 0x1002877 /* U+2877 BRAILLE PATTERN DOTS-123567 */ +#define XK_braille_dots_4567 0x1002878 /* U+2878 BRAILLE PATTERN DOTS-4567 */ +#define XK_braille_dots_14567 0x1002879 /* U+2879 BRAILLE PATTERN DOTS-14567 */ +#define XK_braille_dots_24567 0x100287a /* U+287a BRAILLE PATTERN DOTS-24567 */ +#define XK_braille_dots_124567 0x100287b /* U+287b BRAILLE PATTERN DOTS-124567 */ +#define XK_braille_dots_34567 0x100287c /* U+287c BRAILLE PATTERN DOTS-34567 */ +#define XK_braille_dots_134567 0x100287d /* U+287d BRAILLE PATTERN DOTS-134567 */ +#define XK_braille_dots_234567 0x100287e /* U+287e BRAILLE PATTERN DOTS-234567 */ +#define XK_braille_dots_1234567 0x100287f /* U+287f BRAILLE PATTERN DOTS-1234567 */ +#define XK_braille_dots_8 0x1002880 /* U+2880 BRAILLE PATTERN DOTS-8 */ +#define XK_braille_dots_18 0x1002881 /* U+2881 BRAILLE PATTERN DOTS-18 */ +#define XK_braille_dots_28 0x1002882 /* U+2882 BRAILLE PATTERN DOTS-28 */ +#define XK_braille_dots_128 0x1002883 /* U+2883 BRAILLE PATTERN DOTS-128 */ +#define XK_braille_dots_38 0x1002884 /* U+2884 BRAILLE PATTERN DOTS-38 */ +#define XK_braille_dots_138 0x1002885 /* U+2885 BRAILLE PATTERN DOTS-138 */ +#define XK_braille_dots_238 0x1002886 /* U+2886 BRAILLE PATTERN DOTS-238 */ +#define XK_braille_dots_1238 0x1002887 /* U+2887 BRAILLE PATTERN DOTS-1238 */ +#define XK_braille_dots_48 0x1002888 /* U+2888 BRAILLE PATTERN DOTS-48 */ +#define XK_braille_dots_148 0x1002889 /* U+2889 BRAILLE PATTERN DOTS-148 */ +#define XK_braille_dots_248 0x100288a /* U+288a BRAILLE PATTERN DOTS-248 */ +#define XK_braille_dots_1248 0x100288b /* U+288b BRAILLE PATTERN DOTS-1248 */ +#define XK_braille_dots_348 0x100288c /* U+288c BRAILLE PATTERN DOTS-348 */ +#define XK_braille_dots_1348 0x100288d /* U+288d BRAILLE PATTERN DOTS-1348 */ +#define XK_braille_dots_2348 0x100288e /* U+288e BRAILLE PATTERN DOTS-2348 */ +#define XK_braille_dots_12348 0x100288f /* U+288f BRAILLE PATTERN DOTS-12348 */ +#define XK_braille_dots_58 0x1002890 /* U+2890 BRAILLE PATTERN DOTS-58 */ +#define XK_braille_dots_158 0x1002891 /* U+2891 BRAILLE PATTERN DOTS-158 */ +#define XK_braille_dots_258 0x1002892 /* U+2892 BRAILLE PATTERN DOTS-258 */ +#define XK_braille_dots_1258 0x1002893 /* U+2893 BRAILLE PATTERN DOTS-1258 */ +#define XK_braille_dots_358 0x1002894 /* U+2894 BRAILLE PATTERN DOTS-358 */ +#define XK_braille_dots_1358 0x1002895 /* U+2895 BRAILLE PATTERN DOTS-1358 */ +#define XK_braille_dots_2358 0x1002896 /* U+2896 BRAILLE PATTERN DOTS-2358 */ +#define XK_braille_dots_12358 0x1002897 /* U+2897 BRAILLE PATTERN DOTS-12358 */ +#define XK_braille_dots_458 0x1002898 /* U+2898 BRAILLE PATTERN DOTS-458 */ +#define XK_braille_dots_1458 0x1002899 /* U+2899 BRAILLE PATTERN DOTS-1458 */ +#define XK_braille_dots_2458 0x100289a /* U+289a BRAILLE PATTERN DOTS-2458 */ +#define XK_braille_dots_12458 0x100289b /* U+289b BRAILLE PATTERN DOTS-12458 */ +#define XK_braille_dots_3458 0x100289c /* U+289c BRAILLE PATTERN DOTS-3458 */ +#define XK_braille_dots_13458 0x100289d /* U+289d BRAILLE PATTERN DOTS-13458 */ +#define XK_braille_dots_23458 0x100289e /* U+289e BRAILLE PATTERN DOTS-23458 */ +#define XK_braille_dots_123458 0x100289f /* U+289f BRAILLE PATTERN DOTS-123458 */ +#define XK_braille_dots_68 0x10028a0 /* U+28a0 BRAILLE PATTERN DOTS-68 */ +#define XK_braille_dots_168 0x10028a1 /* U+28a1 BRAILLE PATTERN DOTS-168 */ +#define XK_braille_dots_268 0x10028a2 /* U+28a2 BRAILLE PATTERN DOTS-268 */ +#define XK_braille_dots_1268 0x10028a3 /* U+28a3 BRAILLE PATTERN DOTS-1268 */ +#define XK_braille_dots_368 0x10028a4 /* U+28a4 BRAILLE PATTERN DOTS-368 */ +#define XK_braille_dots_1368 0x10028a5 /* U+28a5 BRAILLE PATTERN DOTS-1368 */ +#define XK_braille_dots_2368 0x10028a6 /* U+28a6 BRAILLE PATTERN DOTS-2368 */ +#define XK_braille_dots_12368 0x10028a7 /* U+28a7 BRAILLE PATTERN DOTS-12368 */ +#define XK_braille_dots_468 0x10028a8 /* U+28a8 BRAILLE PATTERN DOTS-468 */ +#define XK_braille_dots_1468 0x10028a9 /* U+28a9 BRAILLE PATTERN DOTS-1468 */ +#define XK_braille_dots_2468 0x10028aa /* U+28aa BRAILLE PATTERN DOTS-2468 */ +#define XK_braille_dots_12468 0x10028ab /* U+28ab BRAILLE PATTERN DOTS-12468 */ +#define XK_braille_dots_3468 0x10028ac /* U+28ac BRAILLE PATTERN DOTS-3468 */ +#define XK_braille_dots_13468 0x10028ad /* U+28ad BRAILLE PATTERN DOTS-13468 */ +#define XK_braille_dots_23468 0x10028ae /* U+28ae BRAILLE PATTERN DOTS-23468 */ +#define XK_braille_dots_123468 0x10028af /* U+28af BRAILLE PATTERN DOTS-123468 */ +#define XK_braille_dots_568 0x10028b0 /* U+28b0 BRAILLE PATTERN DOTS-568 */ +#define XK_braille_dots_1568 0x10028b1 /* U+28b1 BRAILLE PATTERN DOTS-1568 */ +#define XK_braille_dots_2568 0x10028b2 /* U+28b2 BRAILLE PATTERN DOTS-2568 */ +#define XK_braille_dots_12568 0x10028b3 /* U+28b3 BRAILLE PATTERN DOTS-12568 */ +#define XK_braille_dots_3568 0x10028b4 /* U+28b4 BRAILLE PATTERN DOTS-3568 */ +#define XK_braille_dots_13568 0x10028b5 /* U+28b5 BRAILLE PATTERN DOTS-13568 */ +#define XK_braille_dots_23568 0x10028b6 /* U+28b6 BRAILLE PATTERN DOTS-23568 */ +#define XK_braille_dots_123568 0x10028b7 /* U+28b7 BRAILLE PATTERN DOTS-123568 */ +#define XK_braille_dots_4568 0x10028b8 /* U+28b8 BRAILLE PATTERN DOTS-4568 */ +#define XK_braille_dots_14568 0x10028b9 /* U+28b9 BRAILLE PATTERN DOTS-14568 */ +#define XK_braille_dots_24568 0x10028ba /* U+28ba BRAILLE PATTERN DOTS-24568 */ +#define XK_braille_dots_124568 0x10028bb /* U+28bb BRAILLE PATTERN DOTS-124568 */ +#define XK_braille_dots_34568 0x10028bc /* U+28bc BRAILLE PATTERN DOTS-34568 */ +#define XK_braille_dots_134568 0x10028bd /* U+28bd BRAILLE PATTERN DOTS-134568 */ +#define XK_braille_dots_234568 0x10028be /* U+28be BRAILLE PATTERN DOTS-234568 */ +#define XK_braille_dots_1234568 0x10028bf /* U+28bf BRAILLE PATTERN DOTS-1234568 */ +#define XK_braille_dots_78 0x10028c0 /* U+28c0 BRAILLE PATTERN DOTS-78 */ +#define XK_braille_dots_178 0x10028c1 /* U+28c1 BRAILLE PATTERN DOTS-178 */ +#define XK_braille_dots_278 0x10028c2 /* U+28c2 BRAILLE PATTERN DOTS-278 */ +#define XK_braille_dots_1278 0x10028c3 /* U+28c3 BRAILLE PATTERN DOTS-1278 */ +#define XK_braille_dots_378 0x10028c4 /* U+28c4 BRAILLE PATTERN DOTS-378 */ +#define XK_braille_dots_1378 0x10028c5 /* U+28c5 BRAILLE PATTERN DOTS-1378 */ +#define XK_braille_dots_2378 0x10028c6 /* U+28c6 BRAILLE PATTERN DOTS-2378 */ +#define XK_braille_dots_12378 0x10028c7 /* U+28c7 BRAILLE PATTERN DOTS-12378 */ +#define XK_braille_dots_478 0x10028c8 /* U+28c8 BRAILLE PATTERN DOTS-478 */ +#define XK_braille_dots_1478 0x10028c9 /* U+28c9 BRAILLE PATTERN DOTS-1478 */ +#define XK_braille_dots_2478 0x10028ca /* U+28ca BRAILLE PATTERN DOTS-2478 */ +#define XK_braille_dots_12478 0x10028cb /* U+28cb BRAILLE PATTERN DOTS-12478 */ +#define XK_braille_dots_3478 0x10028cc /* U+28cc BRAILLE PATTERN DOTS-3478 */ +#define XK_braille_dots_13478 0x10028cd /* U+28cd BRAILLE PATTERN DOTS-13478 */ +#define XK_braille_dots_23478 0x10028ce /* U+28ce BRAILLE PATTERN DOTS-23478 */ +#define XK_braille_dots_123478 0x10028cf /* U+28cf BRAILLE PATTERN DOTS-123478 */ +#define XK_braille_dots_578 0x10028d0 /* U+28d0 BRAILLE PATTERN DOTS-578 */ +#define XK_braille_dots_1578 0x10028d1 /* U+28d1 BRAILLE PATTERN DOTS-1578 */ +#define XK_braille_dots_2578 0x10028d2 /* U+28d2 BRAILLE PATTERN DOTS-2578 */ +#define XK_braille_dots_12578 0x10028d3 /* U+28d3 BRAILLE PATTERN DOTS-12578 */ +#define XK_braille_dots_3578 0x10028d4 /* U+28d4 BRAILLE PATTERN DOTS-3578 */ +#define XK_braille_dots_13578 0x10028d5 /* U+28d5 BRAILLE PATTERN DOTS-13578 */ +#define XK_braille_dots_23578 0x10028d6 /* U+28d6 BRAILLE PATTERN DOTS-23578 */ +#define XK_braille_dots_123578 0x10028d7 /* U+28d7 BRAILLE PATTERN DOTS-123578 */ +#define XK_braille_dots_4578 0x10028d8 /* U+28d8 BRAILLE PATTERN DOTS-4578 */ +#define XK_braille_dots_14578 0x10028d9 /* U+28d9 BRAILLE PATTERN DOTS-14578 */ +#define XK_braille_dots_24578 0x10028da /* U+28da BRAILLE PATTERN DOTS-24578 */ +#define XK_braille_dots_124578 0x10028db /* U+28db BRAILLE PATTERN DOTS-124578 */ +#define XK_braille_dots_34578 0x10028dc /* U+28dc BRAILLE PATTERN DOTS-34578 */ +#define XK_braille_dots_134578 0x10028dd /* U+28dd BRAILLE PATTERN DOTS-134578 */ +#define XK_braille_dots_234578 0x10028de /* U+28de BRAILLE PATTERN DOTS-234578 */ +#define XK_braille_dots_1234578 0x10028df /* U+28df BRAILLE PATTERN DOTS-1234578 */ +#define XK_braille_dots_678 0x10028e0 /* U+28e0 BRAILLE PATTERN DOTS-678 */ +#define XK_braille_dots_1678 0x10028e1 /* U+28e1 BRAILLE PATTERN DOTS-1678 */ +#define XK_braille_dots_2678 0x10028e2 /* U+28e2 BRAILLE PATTERN DOTS-2678 */ +#define XK_braille_dots_12678 0x10028e3 /* U+28e3 BRAILLE PATTERN DOTS-12678 */ +#define XK_braille_dots_3678 0x10028e4 /* U+28e4 BRAILLE PATTERN DOTS-3678 */ +#define XK_braille_dots_13678 0x10028e5 /* U+28e5 BRAILLE PATTERN DOTS-13678 */ +#define XK_braille_dots_23678 0x10028e6 /* U+28e6 BRAILLE PATTERN DOTS-23678 */ +#define XK_braille_dots_123678 0x10028e7 /* U+28e7 BRAILLE PATTERN DOTS-123678 */ +#define XK_braille_dots_4678 0x10028e8 /* U+28e8 BRAILLE PATTERN DOTS-4678 */ +#define XK_braille_dots_14678 0x10028e9 /* U+28e9 BRAILLE PATTERN DOTS-14678 */ +#define XK_braille_dots_24678 0x10028ea /* U+28ea BRAILLE PATTERN DOTS-24678 */ +#define XK_braille_dots_124678 0x10028eb /* U+28eb BRAILLE PATTERN DOTS-124678 */ +#define XK_braille_dots_34678 0x10028ec /* U+28ec BRAILLE PATTERN DOTS-34678 */ +#define XK_braille_dots_134678 0x10028ed /* U+28ed BRAILLE PATTERN DOTS-134678 */ +#define XK_braille_dots_234678 0x10028ee /* U+28ee BRAILLE PATTERN DOTS-234678 */ +#define XK_braille_dots_1234678 0x10028ef /* U+28ef BRAILLE PATTERN DOTS-1234678 */ +#define XK_braille_dots_5678 0x10028f0 /* U+28f0 BRAILLE PATTERN DOTS-5678 */ +#define XK_braille_dots_15678 0x10028f1 /* U+28f1 BRAILLE PATTERN DOTS-15678 */ +#define XK_braille_dots_25678 0x10028f2 /* U+28f2 BRAILLE PATTERN DOTS-25678 */ +#define XK_braille_dots_125678 0x10028f3 /* U+28f3 BRAILLE PATTERN DOTS-125678 */ +#define XK_braille_dots_35678 0x10028f4 /* U+28f4 BRAILLE PATTERN DOTS-35678 */ +#define XK_braille_dots_135678 0x10028f5 /* U+28f5 BRAILLE PATTERN DOTS-135678 */ +#define XK_braille_dots_235678 0x10028f6 /* U+28f6 BRAILLE PATTERN DOTS-235678 */ +#define XK_braille_dots_1235678 0x10028f7 /* U+28f7 BRAILLE PATTERN DOTS-1235678 */ +#define XK_braille_dots_45678 0x10028f8 /* U+28f8 BRAILLE PATTERN DOTS-45678 */ +#define XK_braille_dots_145678 0x10028f9 /* U+28f9 BRAILLE PATTERN DOTS-145678 */ +#define XK_braille_dots_245678 0x10028fa /* U+28fa BRAILLE PATTERN DOTS-245678 */ +#define XK_braille_dots_1245678 0x10028fb /* U+28fb BRAILLE PATTERN DOTS-1245678 */ +#define XK_braille_dots_345678 0x10028fc /* U+28fc BRAILLE PATTERN DOTS-345678 */ +#define XK_braille_dots_1345678 0x10028fd /* U+28fd BRAILLE PATTERN DOTS-1345678 */ +#define XK_braille_dots_2345678 0x10028fe /* U+28fe BRAILLE PATTERN DOTS-2345678 */ +#define XK_braille_dots_12345678 0x10028ff /* U+28ff BRAILLE PATTERN DOTS-12345678 */ +#endif /* XK_BRAILLE */ /* * Sinhala (http://unicode.org/charts/PDF/U0D80.pdf) @@ -2408,84 +2402,84 @@ SOFTWARE. */ #ifdef XK_SINHALA -#define XK_Sinh_ng 0x1000d82 /* U+0D82 SINHALA ANUSVARAYA */ -#define XK_Sinh_h2 0x1000d83 /* U+0D83 SINHALA VISARGAYA */ -#define XK_Sinh_a 0x1000d85 /* U+0D85 SINHALA AYANNA */ -#define XK_Sinh_aa 0x1000d86 /* U+0D86 SINHALA AAYANNA */ -#define XK_Sinh_ae 0x1000d87 /* U+0D87 SINHALA AEYANNA */ -#define XK_Sinh_aee 0x1000d88 /* U+0D88 SINHALA AEEYANNA */ -#define XK_Sinh_i 0x1000d89 /* U+0D89 SINHALA IYANNA */ -#define XK_Sinh_ii 0x1000d8a /* U+0D8A SINHALA IIYANNA */ -#define XK_Sinh_u 0x1000d8b /* U+0D8B SINHALA UYANNA */ -#define XK_Sinh_uu 0x1000d8c /* U+0D8C SINHALA UUYANNA */ -#define XK_Sinh_ri 0x1000d8d /* U+0D8D SINHALA IRUYANNA */ -#define XK_Sinh_rii 0x1000d8e /* U+0D8E SINHALA IRUUYANNA */ -#define XK_Sinh_lu 0x1000d8f /* U+0D8F SINHALA ILUYANNA */ -#define XK_Sinh_luu 0x1000d90 /* U+0D90 SINHALA ILUUYANNA */ -#define XK_Sinh_e 0x1000d91 /* U+0D91 SINHALA EYANNA */ -#define XK_Sinh_ee 0x1000d92 /* U+0D92 SINHALA EEYANNA */ -#define XK_Sinh_ai 0x1000d93 /* U+0D93 SINHALA AIYANNA */ -#define XK_Sinh_o 0x1000d94 /* U+0D94 SINHALA OYANNA */ -#define XK_Sinh_oo 0x1000d95 /* U+0D95 SINHALA OOYANNA */ -#define XK_Sinh_au 0x1000d96 /* U+0D96 SINHALA AUYANNA */ -#define XK_Sinh_ka 0x1000d9a /* U+0D9A SINHALA KAYANNA */ -#define XK_Sinh_kha 0x1000d9b /* U+0D9B SINHALA MAHA. KAYANNA */ -#define XK_Sinh_ga 0x1000d9c /* U+0D9C SINHALA GAYANNA */ -#define XK_Sinh_gha 0x1000d9d /* U+0D9D SINHALA MAHA. GAYANNA */ -#define XK_Sinh_ng2 0x1000d9e /* U+0D9E SINHALA KANTAJA NAASIKYAYA */ -#define XK_Sinh_nga 0x1000d9f /* U+0D9F SINHALA SANYAKA GAYANNA */ -#define XK_Sinh_ca 0x1000da0 /* U+0DA0 SINHALA CAYANNA */ -#define XK_Sinh_cha 0x1000da1 /* U+0DA1 SINHALA MAHA. CAYANNA */ -#define XK_Sinh_ja 0x1000da2 /* U+0DA2 SINHALA JAYANNA */ -#define XK_Sinh_jha 0x1000da3 /* U+0DA3 SINHALA MAHA. JAYANNA */ -#define XK_Sinh_nya 0x1000da4 /* U+0DA4 SINHALA TAALUJA NAASIKYAYA */ -#define XK_Sinh_jnya 0x1000da5 /* U+0DA5 SINHALA TAALUJA SANYOOGA NAASIKYAYA */ -#define XK_Sinh_nja 0x1000da6 /* U+0DA6 SINHALA SANYAKA JAYANNA */ -#define XK_Sinh_tta 0x1000da7 /* U+0DA7 SINHALA TTAYANNA */ -#define XK_Sinh_ttha 0x1000da8 /* U+0DA8 SINHALA MAHA. TTAYANNA */ -#define XK_Sinh_dda 0x1000da9 /* U+0DA9 SINHALA DDAYANNA */ -#define XK_Sinh_ddha 0x1000daa /* U+0DAA SINHALA MAHA. DDAYANNA */ -#define XK_Sinh_nna 0x1000dab /* U+0DAB SINHALA MUURDHAJA NAYANNA */ -#define XK_Sinh_ndda 0x1000dac /* U+0DAC SINHALA SANYAKA DDAYANNA */ -#define XK_Sinh_tha 0x1000dad /* U+0DAD SINHALA TAYANNA */ -#define XK_Sinh_thha 0x1000dae /* U+0DAE SINHALA MAHA. TAYANNA */ -#define XK_Sinh_dha 0x1000daf /* U+0DAF SINHALA DAYANNA */ -#define XK_Sinh_dhha 0x1000db0 /* U+0DB0 SINHALA MAHA. DAYANNA */ -#define XK_Sinh_na 0x1000db1 /* U+0DB1 SINHALA DANTAJA NAYANNA */ -#define XK_Sinh_ndha 0x1000db3 /* U+0DB3 SINHALA SANYAKA DAYANNA */ -#define XK_Sinh_pa 0x1000db4 /* U+0DB4 SINHALA PAYANNA */ -#define XK_Sinh_pha 0x1000db5 /* U+0DB5 SINHALA MAHA. PAYANNA */ -#define XK_Sinh_ba 0x1000db6 /* U+0DB6 SINHALA BAYANNA */ -#define XK_Sinh_bha 0x1000db7 /* U+0DB7 SINHALA MAHA. BAYANNA */ -#define XK_Sinh_ma 0x1000db8 /* U+0DB8 SINHALA MAYANNA */ -#define XK_Sinh_mba 0x1000db9 /* U+0DB9 SINHALA AMBA BAYANNA */ -#define XK_Sinh_ya 0x1000dba /* U+0DBA SINHALA YAYANNA */ -#define XK_Sinh_ra 0x1000dbb /* U+0DBB SINHALA RAYANNA */ -#define XK_Sinh_la 0x1000dbd /* U+0DBD SINHALA DANTAJA LAYANNA */ -#define XK_Sinh_va 0x1000dc0 /* U+0DC0 SINHALA VAYANNA */ -#define XK_Sinh_sha 0x1000dc1 /* U+0DC1 SINHALA TAALUJA SAYANNA */ -#define XK_Sinh_ssha 0x1000dc2 /* U+0DC2 SINHALA MUURDHAJA SAYANNA */ -#define XK_Sinh_sa 0x1000dc3 /* U+0DC3 SINHALA DANTAJA SAYANNA */ -#define XK_Sinh_ha 0x1000dc4 /* U+0DC4 SINHALA HAYANNA */ -#define XK_Sinh_lla 0x1000dc5 /* U+0DC5 SINHALA MUURDHAJA LAYANNA */ -#define XK_Sinh_fa 0x1000dc6 /* U+0DC6 SINHALA FAYANNA */ -#define XK_Sinh_al 0x1000dca /* U+0DCA SINHALA AL-LAKUNA */ -#define XK_Sinh_aa2 0x1000dcf /* U+0DCF SINHALA AELA-PILLA */ -#define XK_Sinh_ae2 0x1000dd0 /* U+0DD0 SINHALA AEDA-PILLA */ -#define XK_Sinh_aee2 0x1000dd1 /* U+0DD1 SINHALA DIGA AEDA-PILLA */ -#define XK_Sinh_i2 0x1000dd2 /* U+0DD2 SINHALA IS-PILLA */ -#define XK_Sinh_ii2 0x1000dd3 /* U+0DD3 SINHALA DIGA IS-PILLA */ -#define XK_Sinh_u2 0x1000dd4 /* U+0DD4 SINHALA PAA-PILLA */ -#define XK_Sinh_uu2 0x1000dd6 /* U+0DD6 SINHALA DIGA PAA-PILLA */ -#define XK_Sinh_ru2 0x1000dd8 /* U+0DD8 SINHALA GAETTA-PILLA */ -#define XK_Sinh_e2 0x1000dd9 /* U+0DD9 SINHALA KOMBUVA */ -#define XK_Sinh_ee2 0x1000dda /* U+0DDA SINHALA DIGA KOMBUVA */ -#define XK_Sinh_ai2 0x1000ddb /* U+0DDB SINHALA KOMBU DEKA */ -#define XK_Sinh_o2 0x1000ddc /* U+0DDC SINHALA KOMBUVA HAA AELA-PILLA*/ -#define XK_Sinh_oo2 0x1000ddd /* U+0DDD SINHALA KOMBUVA HAA DIGA AELA-PILLA*/ -#define XK_Sinh_au2 0x1000dde /* U+0DDE SINHALA KOMBUVA HAA GAYANUKITTA */ -#define XK_Sinh_lu2 0x1000ddf /* U+0DDF SINHALA GAYANUKITTA */ -#define XK_Sinh_ruu2 0x1000df2 /* U+0DF2 SINHALA DIGA GAETTA-PILLA */ -#define XK_Sinh_luu2 0x1000df3 /* U+0DF3 SINHALA DIGA GAYANUKITTA */ -#define XK_Sinh_kunddaliya 0x1000df4 /* U+0DF4 SINHALA KUNDDALIYA */ -#endif /* XK_SINHALA */ +#define XK_Sinh_ng 0x1000d82 /* U+0D82 SINHALA ANUSVARAYA */ +#define XK_Sinh_h2 0x1000d83 /* U+0D83 SINHALA VISARGAYA */ +#define XK_Sinh_a 0x1000d85 /* U+0D85 SINHALA AYANNA */ +#define XK_Sinh_aa 0x1000d86 /* U+0D86 SINHALA AAYANNA */ +#define XK_Sinh_ae 0x1000d87 /* U+0D87 SINHALA AEYANNA */ +#define XK_Sinh_aee 0x1000d88 /* U+0D88 SINHALA AEEYANNA */ +#define XK_Sinh_i 0x1000d89 /* U+0D89 SINHALA IYANNA */ +#define XK_Sinh_ii 0x1000d8a /* U+0D8A SINHALA IIYANNA */ +#define XK_Sinh_u 0x1000d8b /* U+0D8B SINHALA UYANNA */ +#define XK_Sinh_uu 0x1000d8c /* U+0D8C SINHALA UUYANNA */ +#define XK_Sinh_ri 0x1000d8d /* U+0D8D SINHALA IRUYANNA */ +#define XK_Sinh_rii 0x1000d8e /* U+0D8E SINHALA IRUUYANNA */ +#define XK_Sinh_lu 0x1000d8f /* U+0D8F SINHALA ILUYANNA */ +#define XK_Sinh_luu 0x1000d90 /* U+0D90 SINHALA ILUUYANNA */ +#define XK_Sinh_e 0x1000d91 /* U+0D91 SINHALA EYANNA */ +#define XK_Sinh_ee 0x1000d92 /* U+0D92 SINHALA EEYANNA */ +#define XK_Sinh_ai 0x1000d93 /* U+0D93 SINHALA AIYANNA */ +#define XK_Sinh_o 0x1000d94 /* U+0D94 SINHALA OYANNA */ +#define XK_Sinh_oo 0x1000d95 /* U+0D95 SINHALA OOYANNA */ +#define XK_Sinh_au 0x1000d96 /* U+0D96 SINHALA AUYANNA */ +#define XK_Sinh_ka 0x1000d9a /* U+0D9A SINHALA KAYANNA */ +#define XK_Sinh_kha 0x1000d9b /* U+0D9B SINHALA MAHA. KAYANNA */ +#define XK_Sinh_ga 0x1000d9c /* U+0D9C SINHALA GAYANNA */ +#define XK_Sinh_gha 0x1000d9d /* U+0D9D SINHALA MAHA. GAYANNA */ +#define XK_Sinh_ng2 0x1000d9e /* U+0D9E SINHALA KANTAJA NAASIKYAYA */ +#define XK_Sinh_nga 0x1000d9f /* U+0D9F SINHALA SANYAKA GAYANNA */ +#define XK_Sinh_ca 0x1000da0 /* U+0DA0 SINHALA CAYANNA */ +#define XK_Sinh_cha 0x1000da1 /* U+0DA1 SINHALA MAHA. CAYANNA */ +#define XK_Sinh_ja 0x1000da2 /* U+0DA2 SINHALA JAYANNA */ +#define XK_Sinh_jha 0x1000da3 /* U+0DA3 SINHALA MAHA. JAYANNA */ +#define XK_Sinh_nya 0x1000da4 /* U+0DA4 SINHALA TAALUJA NAASIKYAYA */ +#define XK_Sinh_jnya 0x1000da5 /* U+0DA5 SINHALA TAALUJA SANYOOGA NAASIKYAYA */ +#define XK_Sinh_nja 0x1000da6 /* U+0DA6 SINHALA SANYAKA JAYANNA */ +#define XK_Sinh_tta 0x1000da7 /* U+0DA7 SINHALA TTAYANNA */ +#define XK_Sinh_ttha 0x1000da8 /* U+0DA8 SINHALA MAHA. TTAYANNA */ +#define XK_Sinh_dda 0x1000da9 /* U+0DA9 SINHALA DDAYANNA */ +#define XK_Sinh_ddha 0x1000daa /* U+0DAA SINHALA MAHA. DDAYANNA */ +#define XK_Sinh_nna 0x1000dab /* U+0DAB SINHALA MUURDHAJA NAYANNA */ +#define XK_Sinh_ndda 0x1000dac /* U+0DAC SINHALA SANYAKA DDAYANNA */ +#define XK_Sinh_tha 0x1000dad /* U+0DAD SINHALA TAYANNA */ +#define XK_Sinh_thha 0x1000dae /* U+0DAE SINHALA MAHA. TAYANNA */ +#define XK_Sinh_dha 0x1000daf /* U+0DAF SINHALA DAYANNA */ +#define XK_Sinh_dhha 0x1000db0 /* U+0DB0 SINHALA MAHA. DAYANNA */ +#define XK_Sinh_na 0x1000db1 /* U+0DB1 SINHALA DANTAJA NAYANNA */ +#define XK_Sinh_ndha 0x1000db3 /* U+0DB3 SINHALA SANYAKA DAYANNA */ +#define XK_Sinh_pa 0x1000db4 /* U+0DB4 SINHALA PAYANNA */ +#define XK_Sinh_pha 0x1000db5 /* U+0DB5 SINHALA MAHA. PAYANNA */ +#define XK_Sinh_ba 0x1000db6 /* U+0DB6 SINHALA BAYANNA */ +#define XK_Sinh_bha 0x1000db7 /* U+0DB7 SINHALA MAHA. BAYANNA */ +#define XK_Sinh_ma 0x1000db8 /* U+0DB8 SINHALA MAYANNA */ +#define XK_Sinh_mba 0x1000db9 /* U+0DB9 SINHALA AMBA BAYANNA */ +#define XK_Sinh_ya 0x1000dba /* U+0DBA SINHALA YAYANNA */ +#define XK_Sinh_ra 0x1000dbb /* U+0DBB SINHALA RAYANNA */ +#define XK_Sinh_la 0x1000dbd /* U+0DBD SINHALA DANTAJA LAYANNA */ +#define XK_Sinh_va 0x1000dc0 /* U+0DC0 SINHALA VAYANNA */ +#define XK_Sinh_sha 0x1000dc1 /* U+0DC1 SINHALA TAALUJA SAYANNA */ +#define XK_Sinh_ssha 0x1000dc2 /* U+0DC2 SINHALA MUURDHAJA SAYANNA */ +#define XK_Sinh_sa 0x1000dc3 /* U+0DC3 SINHALA DANTAJA SAYANNA */ +#define XK_Sinh_ha 0x1000dc4 /* U+0DC4 SINHALA HAYANNA */ +#define XK_Sinh_lla 0x1000dc5 /* U+0DC5 SINHALA MUURDHAJA LAYANNA */ +#define XK_Sinh_fa 0x1000dc6 /* U+0DC6 SINHALA FAYANNA */ +#define XK_Sinh_al 0x1000dca /* U+0DCA SINHALA AL-LAKUNA */ +#define XK_Sinh_aa2 0x1000dcf /* U+0DCF SINHALA AELA-PILLA */ +#define XK_Sinh_ae2 0x1000dd0 /* U+0DD0 SINHALA AEDA-PILLA */ +#define XK_Sinh_aee2 0x1000dd1 /* U+0DD1 SINHALA DIGA AEDA-PILLA */ +#define XK_Sinh_i2 0x1000dd2 /* U+0DD2 SINHALA IS-PILLA */ +#define XK_Sinh_ii2 0x1000dd3 /* U+0DD3 SINHALA DIGA IS-PILLA */ +#define XK_Sinh_u2 0x1000dd4 /* U+0DD4 SINHALA PAA-PILLA */ +#define XK_Sinh_uu2 0x1000dd6 /* U+0DD6 SINHALA DIGA PAA-PILLA */ +#define XK_Sinh_ru2 0x1000dd8 /* U+0DD8 SINHALA GAETTA-PILLA */ +#define XK_Sinh_e2 0x1000dd9 /* U+0DD9 SINHALA KOMBUVA */ +#define XK_Sinh_ee2 0x1000dda /* U+0DDA SINHALA DIGA KOMBUVA */ +#define XK_Sinh_ai2 0x1000ddb /* U+0DDB SINHALA KOMBU DEKA */ +#define XK_Sinh_o2 0x1000ddc /* U+0DDC SINHALA KOMBUVA HAA AELA-PILLA*/ +#define XK_Sinh_oo2 0x1000ddd /* U+0DDD SINHALA KOMBUVA HAA DIGA AELA-PILLA*/ +#define XK_Sinh_au2 0x1000dde /* U+0DDE SINHALA KOMBUVA HAA GAYANUKITTA */ +#define XK_Sinh_lu2 0x1000ddf /* U+0DDF SINHALA GAYANUKITTA */ +#define XK_Sinh_ruu2 0x1000df2 /* U+0DF2 SINHALA DIGA GAETTA-PILLA */ +#define XK_Sinh_luu2 0x1000df3 /* U+0DF3 SINHALA DIGA GAYANUKITTA */ +#define XK_Sinh_kunddaliya 0x1000df4 /* U+0DF4 SINHALA KUNDDALIYA */ +#endif /* XK_SINHALA */ diff --git a/examples/ThirdPartyLibs/serial/include/serial/impl/unix.h b/examples/ThirdPartyLibs/serial/include/serial/impl/unix.h index 0fb38f244..94cf15cf0 100644 --- a/examples/ThirdPartyLibs/serial/include/serial/impl/unix.h +++ b/examples/ThirdPartyLibs/serial/include/serial/impl/unix.h @@ -44,178 +44,180 @@ #include -namespace serial { - +namespace serial +{ +using std::invalid_argument; using std::size_t; using std::string; -using std::invalid_argument; -using serial::SerialException; using serial::IOException; +using serial::SerialException; -class MillisecondTimer { +class MillisecondTimer +{ public: - MillisecondTimer(const uint32_t millis); - int64_t remaining(); + MillisecondTimer(const uint32_t millis); + int64_t remaining(); private: - static timespec timespec_now(); - timespec expiry; + static timespec timespec_now(); + timespec expiry; }; -class serial::Serial::SerialImpl { +class serial::Serial::SerialImpl +{ public: - SerialImpl (const string &port, - unsigned long baudrate, - bytesize_t bytesize, - parity_t parity, - stopbits_t stopbits, - flowcontrol_t flowcontrol); + SerialImpl(const string &port, + unsigned long baudrate, + bytesize_t bytesize, + parity_t parity, + stopbits_t stopbits, + flowcontrol_t flowcontrol); - virtual ~SerialImpl (); + virtual ~SerialImpl(); - void - open (); + void + open(); - void - close (); + void + close(); - bool - isOpen () const; + bool + isOpen() const; - size_t - available (); + size_t + available(); - bool - waitReadable (uint32_t timeout); + bool + waitReadable(uint32_t timeout); - void - waitByteTimes (size_t count); + void + waitByteTimes(size_t count); - size_t - read (uint8_t *buf, size_t size = 1); + size_t + read(uint8_t *buf, size_t size = 1); - size_t - write (const uint8_t *data, size_t length); + size_t + write(const uint8_t *data, size_t length); - void - flush (); + void + flush(); - void - flushInput (); + void + flushInput(); - void - flushOutput (); + void + flushOutput(); - void - sendBreak (int duration); + void + sendBreak(int duration); - void - setBreak (bool level); + void + setBreak(bool level); - void - setRTS (bool level); + void + setRTS(bool level); - void - setDTR (bool level); + void + setDTR(bool level); - bool - waitForChange (); + bool + waitForChange(); - bool - getCTS (); + bool + getCTS(); - bool - getDSR (); + bool + getDSR(); - bool - getRI (); + bool + getRI(); - bool - getCD (); + bool + getCD(); - void - setPort (const string &port); + void + setPort(const string &port); - string - getPort () const; + string + getPort() const; - void - setTimeout (Timeout &timeout); + void + setTimeout(Timeout &timeout); - Timeout - getTimeout () const; + Timeout + getTimeout() const; - void - setBaudrate (unsigned long baudrate); + void + setBaudrate(unsigned long baudrate); - unsigned long - getBaudrate () const; + unsigned long + getBaudrate() const; - void - setBytesize (bytesize_t bytesize); + void + setBytesize(bytesize_t bytesize); - bytesize_t - getBytesize () const; + bytesize_t + getBytesize() const; - void - setParity (parity_t parity); + void + setParity(parity_t parity); - parity_t - getParity () const; + parity_t + getParity() const; - void - setStopbits (stopbits_t stopbits); + void + setStopbits(stopbits_t stopbits); - stopbits_t - getStopbits () const; + stopbits_t + getStopbits() const; - void - setFlowcontrol (flowcontrol_t flowcontrol); + void + setFlowcontrol(flowcontrol_t flowcontrol); - flowcontrol_t - getFlowcontrol () const; + flowcontrol_t + getFlowcontrol() const; - void - readLock (); + void + readLock(); - void - readUnlock (); + void + readUnlock(); - void - writeLock (); + void + writeLock(); - void - writeUnlock (); + void + writeUnlock(); protected: - void reconfigurePort (); + void reconfigurePort(); private: - string port_; // Path to the file descriptor - int fd_; // The current file descriptor + string port_; // Path to the file descriptor + int fd_; // The current file descriptor - bool is_open_; - bool xonxoff_; - bool rtscts_; + bool is_open_; + bool xonxoff_; + bool rtscts_; - Timeout timeout_; // Timeout for read operations - unsigned long baudrate_; // Baudrate - uint32_t byte_time_ns_; // Nanoseconds to transmit/receive a single byte + Timeout timeout_; // Timeout for read operations + unsigned long baudrate_; // Baudrate + uint32_t byte_time_ns_; // Nanoseconds to transmit/receive a single byte - parity_t parity_; // Parity - bytesize_t bytesize_; // Size of the bytes - stopbits_t stopbits_; // Stop Bits - flowcontrol_t flowcontrol_; // Flow Control + parity_t parity_; // Parity + bytesize_t bytesize_; // Size of the bytes + stopbits_t stopbits_; // Stop Bits + flowcontrol_t flowcontrol_; // Flow Control - // Mutex used to lock the read functions - pthread_mutex_t read_mutex; - // Mutex used to lock the write functions - pthread_mutex_t write_mutex; + // Mutex used to lock the read functions + pthread_mutex_t read_mutex; + // Mutex used to lock the write functions + pthread_mutex_t write_mutex; }; -} +} // namespace serial -#endif // SERIAL_IMPL_UNIX_H +#endif // SERIAL_IMPL_UNIX_H -#endif // !defined(_WIN32) +#endif // !defined(_WIN32) diff --git a/examples/ThirdPartyLibs/serial/include/serial/impl/win.h b/examples/ThirdPartyLibs/serial/include/serial/impl/win.h index 2c0c6cde1..2e7b9749e 100644 --- a/examples/ThirdPartyLibs/serial/include/serial/impl/win.h +++ b/examples/ThirdPartyLibs/serial/include/serial/impl/win.h @@ -43,165 +43,166 @@ #include "windows.h" -namespace serial { - +namespace serial +{ +using std::invalid_argument; using std::string; using std::wstring; -using std::invalid_argument; -using serial::SerialException; using serial::IOException; +using serial::SerialException; -class serial::Serial::SerialImpl { +class serial::Serial::SerialImpl +{ public: - SerialImpl (const string &port, - unsigned long baudrate, - bytesize_t bytesize, - parity_t parity, - stopbits_t stopbits, - flowcontrol_t flowcontrol); + SerialImpl(const string &port, + unsigned long baudrate, + bytesize_t bytesize, + parity_t parity, + stopbits_t stopbits, + flowcontrol_t flowcontrol); - virtual ~SerialImpl (); + virtual ~SerialImpl(); - void - open (); + void + open(); - void - close (); + void + close(); - bool - isOpen () const; + bool + isOpen() const; - size_t - available (); - - bool - waitReadable (uint32_t timeout); + size_t + available(); - void - waitByteTimes (size_t count); + bool + waitReadable(uint32_t timeout); - size_t - read (uint8_t *buf, size_t size = 1); + void + waitByteTimes(size_t count); - size_t - write (const uint8_t *data, size_t length); + size_t + read(uint8_t *buf, size_t size = 1); - void - flush (); + size_t + write(const uint8_t *data, size_t length); - void - flushInput (); + void + flush(); - void - flushOutput (); + void + flushInput(); - void - sendBreak (int duration); + void + flushOutput(); - void - setBreak (bool level); + void + sendBreak(int duration); - void - setRTS (bool level); + void + setBreak(bool level); - void - setDTR (bool level); + void + setRTS(bool level); - bool - waitForChange (); + void + setDTR(bool level); - bool - getCTS (); + bool + waitForChange(); - bool - getDSR (); + bool + getCTS(); - bool - getRI (); + bool + getDSR(); - bool - getCD (); + bool + getRI(); - void - setPort (const string &port); + bool + getCD(); - string - getPort () const; + void + setPort(const string &port); - void - setTimeout (Timeout &timeout); + string + getPort() const; - Timeout - getTimeout () const; + void + setTimeout(Timeout &timeout); - void - setBaudrate (unsigned long baudrate); + Timeout + getTimeout() const; - unsigned long - getBaudrate () const; + void + setBaudrate(unsigned long baudrate); - void - setBytesize (bytesize_t bytesize); + unsigned long + getBaudrate() const; - bytesize_t - getBytesize () const; + void + setBytesize(bytesize_t bytesize); - void - setParity (parity_t parity); + bytesize_t + getBytesize() const; - parity_t - getParity () const; + void + setParity(parity_t parity); - void - setStopbits (stopbits_t stopbits); + parity_t + getParity() const; - stopbits_t - getStopbits () const; + void + setStopbits(stopbits_t stopbits); - void - setFlowcontrol (flowcontrol_t flowcontrol); + stopbits_t + getStopbits() const; - flowcontrol_t - getFlowcontrol () const; + void + setFlowcontrol(flowcontrol_t flowcontrol); - void - readLock (); + flowcontrol_t + getFlowcontrol() const; - void - readUnlock (); + void + readLock(); - void - writeLock (); + void + readUnlock(); - void - writeUnlock (); + void + writeLock(); + + void + writeUnlock(); protected: - void reconfigurePort (); + void reconfigurePort(); private: - wstring port_; // Path to the file descriptor - HANDLE fd_; + wstring port_; // Path to the file descriptor + HANDLE fd_; - bool is_open_; + bool is_open_; - Timeout timeout_; // Timeout for read operations - unsigned long baudrate_; // Baudrate + Timeout timeout_; // Timeout for read operations + unsigned long baudrate_; // Baudrate - parity_t parity_; // Parity - bytesize_t bytesize_; // Size of the bytes - stopbits_t stopbits_; // Stop Bits - flowcontrol_t flowcontrol_; // Flow Control + parity_t parity_; // Parity + bytesize_t bytesize_; // Size of the bytes + stopbits_t stopbits_; // Stop Bits + flowcontrol_t flowcontrol_; // Flow Control - // Mutex used to lock the read functions - HANDLE read_mutex; - // Mutex used to lock the write functions - HANDLE write_mutex; + // Mutex used to lock the read functions + HANDLE read_mutex; + // Mutex used to lock the write functions + HANDLE write_mutex; }; -} +} // namespace serial -#endif // SERIAL_IMPL_WINDOWS_H +#endif // SERIAL_IMPL_WINDOWS_H -#endif // if defined(_WIN32) +#endif // if defined(_WIN32) diff --git a/examples/ThirdPartyLibs/serial/include/serial/serial.h b/examples/ThirdPartyLibs/serial/include/serial/serial.h index 138565952..b38cb0a31 100644 --- a/examples/ThirdPartyLibs/serial/include/serial/serial.h +++ b/examples/ThirdPartyLibs/serial/include/serial/serial.h @@ -46,47 +46,51 @@ #include #define THROW(exceptionClass, message) throw exceptionClass(__FILE__, \ -__LINE__, (message) ) - -namespace serial { + __LINE__, (message)) +namespace serial +{ /*! * Enumeration defines the possible bytesizes for the serial port. */ -typedef enum { - fivebits = 5, - sixbits = 6, - sevenbits = 7, - eightbits = 8 +typedef enum +{ + fivebits = 5, + sixbits = 6, + sevenbits = 7, + eightbits = 8 } bytesize_t; /*! * Enumeration defines the possible parity types for the serial port. */ -typedef enum { - parity_none = 0, - parity_odd = 1, - parity_even = 2, - parity_mark = 3, - parity_space = 4 +typedef enum +{ + parity_none = 0, + parity_odd = 1, + parity_even = 2, + parity_mark = 3, + parity_space = 4 } parity_t; /*! * Enumeration defines the possible stopbit types for the serial port. */ -typedef enum { - stopbits_one = 1, - stopbits_two = 2, - stopbits_one_point_five +typedef enum +{ + stopbits_one = 1, + stopbits_two = 2, + stopbits_one_point_five } stopbits_t; /*! * Enumeration defines the possible flowcontrol types for the serial port. */ -typedef enum { - flowcontrol_none = 0, - flowcontrol_software, - flowcontrol_hardware +typedef enum +{ + flowcontrol_none = 0, + flowcontrol_software, + flowcontrol_hardware } flowcontrol_t; /*! @@ -95,12 +99,16 @@ typedef enum { * * In order to disable the interbyte timeout, set it to Timeout::max(). */ -struct Timeout { +struct Timeout +{ #ifdef max -# undef max +#undef max #endif - static uint32_t max() {return std::numeric_limits::max();} - /*! + static uint32_t max() + { + return std::numeric_limits::max(); + } + /*! * Convenience function to generate Timeout structs using a * single absolute timeout. * @@ -109,44 +117,47 @@ struct Timeout { * * \return Timeout struct that represents this simple timeout provided. */ - static Timeout simpleTimeout(uint32_t timeout) { - return Timeout(max(), timeout, 0, timeout, 0); - } + static Timeout simpleTimeout(uint32_t timeout) + { + return Timeout(max(), timeout, 0, timeout, 0); + } - /*! Number of milliseconds between bytes received to timeout on. */ - uint32_t inter_byte_timeout; - /*! A constant number of milliseconds to wait after calling read. */ - uint32_t read_timeout_constant; - /*! A multiplier against the number of requested bytes to wait after + /*! Number of milliseconds between bytes received to timeout on. */ + uint32_t inter_byte_timeout; + /*! A constant number of milliseconds to wait after calling read. */ + uint32_t read_timeout_constant; + /*! A multiplier against the number of requested bytes to wait after * calling read. */ - uint32_t read_timeout_multiplier; - /*! A constant number of milliseconds to wait after calling write. */ - uint32_t write_timeout_constant; - /*! A multiplier against the number of requested bytes to wait after + uint32_t read_timeout_multiplier; + /*! A constant number of milliseconds to wait after calling write. */ + uint32_t write_timeout_constant; + /*! A multiplier against the number of requested bytes to wait after * calling write. */ - uint32_t write_timeout_multiplier; + uint32_t write_timeout_multiplier; - explicit Timeout (uint32_t inter_byte_timeout_=0, - uint32_t read_timeout_constant_=0, - uint32_t read_timeout_multiplier_=0, - uint32_t write_timeout_constant_=0, - uint32_t write_timeout_multiplier_=0) - : inter_byte_timeout(inter_byte_timeout_), - read_timeout_constant(read_timeout_constant_), - read_timeout_multiplier(read_timeout_multiplier_), - write_timeout_constant(write_timeout_constant_), - write_timeout_multiplier(write_timeout_multiplier_) - {} + explicit Timeout(uint32_t inter_byte_timeout_ = 0, + uint32_t read_timeout_constant_ = 0, + uint32_t read_timeout_multiplier_ = 0, + uint32_t write_timeout_constant_ = 0, + uint32_t write_timeout_multiplier_ = 0) + : inter_byte_timeout(inter_byte_timeout_), + read_timeout_constant(read_timeout_constant_), + read_timeout_multiplier(read_timeout_multiplier_), + write_timeout_constant(write_timeout_constant_), + write_timeout_multiplier(write_timeout_multiplier_) + { + } }; /*! * Class that provides a portable serial port interface. */ -class Serial { +class Serial +{ public: - /*! + /*! * Creates a Serial object and opens the port if a port is specified, * otherwise it remains closed until serial::Serial::open is called. * @@ -177,18 +188,18 @@ public: * \throw serial::IOException * \throw std::invalid_argument */ - Serial (const std::string &port = "", - uint32_t baudrate = 9600, - Timeout timeout = Timeout(), - bytesize_t bytesize = eightbits, - parity_t parity = parity_none, - stopbits_t stopbits = stopbits_one, - flowcontrol_t flowcontrol = flowcontrol_none); + Serial(const std::string &port = "", + uint32_t baudrate = 9600, + Timeout timeout = Timeout(), + bytesize_t bytesize = eightbits, + parity_t parity = parity_none, + stopbits_t stopbits = stopbits_one, + flowcontrol_t flowcontrol = flowcontrol_none); - /*! Destructor */ - virtual ~Serial (); + /*! Destructor */ + virtual ~Serial(); - /*! + /*! * Opens the serial port as long as the port is set and the port isn't * already open. * @@ -201,39 +212,39 @@ public: * \throw serial::SerialException * \throw serial::IOException */ - void - open (); + void + open(); - /*! Gets the open status of the serial port. + /*! Gets the open status of the serial port. * * \return Returns true if the port is open, false otherwise. */ - bool - isOpen () const; + bool + isOpen() const; - /*! Closes the serial port. */ - void - close (); + /*! Closes the serial port. */ + void + close(); - /*! Return the number of characters in the buffer. */ - size_t - available (); + /*! Return the number of characters in the buffer. */ + size_t + available(); - /*! Block until there is serial data to read or read_timeout_constant + /*! Block until there is serial data to read or read_timeout_constant * number of milliseconds have elapsed. The return value is true when * the function exits with the port in a readable state, false otherwise * (due to timeout or select interruption). */ - bool - waitReadable (); + bool + waitReadable(); - /*! Block for a period of time corresponding to the transmission time of + /*! Block for a period of time corresponding to the transmission time of * count characters at present serial settings. This may be used in con- * junction with waitReadable to read larger blocks of data from the * port. */ - void - waitByteTimes (size_t count); + void + waitByteTimes(size_t count); - /*! Read a given amount of bytes from the serial port into a given buffer. + /*! Read a given amount of bytes from the serial port into a given buffer. * * The read function will return in one of three cases: * * The number of requested bytes was read. @@ -261,10 +272,10 @@ public: * \throw serial::PortNotOpenedException * \throw serial::SerialException */ - size_t - read (uint8_t *buffer, size_t size); + size_t + read(uint8_t *buffer, size_t size); - /*! Read a given amount of bytes from the serial port into a give buffer. + /*! Read a given amount of bytes from the serial port into a give buffer. * * \param buffer A reference to a std::vector of uint8_t. * \param size A size_t defining how many bytes to be read. @@ -275,10 +286,10 @@ public: * \throw serial::PortNotOpenedException * \throw serial::SerialException */ - size_t - read (std::vector &buffer, size_t size = 1); + size_t + read(std::vector &buffer, size_t size = 1); - /*! Read a given amount of bytes from the serial port into a give buffer. + /*! Read a given amount of bytes from the serial port into a give buffer. * * \param buffer A reference to a std::string. * \param size A size_t defining how many bytes to be read. @@ -289,10 +300,10 @@ public: * \throw serial::PortNotOpenedException * \throw serial::SerialException */ - size_t - read (std::string &buffer, size_t size = 1); + size_t + read(std::string &buffer, size_t size = 1); - /*! Read a given amount of bytes from the serial port and return a string + /*! Read a given amount of bytes from the serial port and return a string * containing the data. * * \param size A size_t defining how many bytes to be read. @@ -302,10 +313,10 @@ public: * \throw serial::PortNotOpenedException * \throw serial::SerialException */ - std::string - read (size_t size = 1); + std::string + read(size_t size = 1); - /*! Reads in a line or until a given delimiter has been processed. + /*! Reads in a line or until a given delimiter has been processed. * * Reads from the serial port until a single line has been read. * @@ -318,10 +329,10 @@ public: * \throw serial::PortNotOpenedException * \throw serial::SerialException */ - size_t - readline (std::string &buffer, size_t size = 65536, std::string eol = "\n"); + size_t + readline(std::string &buffer, size_t size = 65536, std::string eol = "\n"); - /*! Reads in a line or until a given delimiter has been processed. + /*! Reads in a line or until a given delimiter has been processed. * * Reads from the serial port until a single line has been read. * @@ -333,10 +344,10 @@ public: * \throw serial::PortNotOpenedException * \throw serial::SerialException */ - std::string - readline (size_t size = 65536, std::string eol = "\n"); + std::string + readline(size_t size = 65536, std::string eol = "\n"); - /*! Reads in multiple lines until the serial port times out. + /*! Reads in multiple lines until the serial port times out. * * This requires a timeout > 0 before it can be run. It will read until a * timeout occurs and return a list of strings. @@ -350,10 +361,10 @@ public: * \throw serial::PortNotOpenedException * \throw serial::SerialException */ - std::vector - readlines (size_t size = 65536, std::string eol = "\n"); + std::vector + readlines(size_t size = 65536, std::string eol = "\n"); - /*! Write a string to the serial port. + /*! Write a string to the serial port. * * \param data A const reference containing the data to be written * to the serial port. @@ -368,10 +379,10 @@ public: * \throw serial::SerialException * \throw serial::IOException */ - size_t - write (const uint8_t *data, size_t size); + size_t + write(const uint8_t *data, size_t size); - /*! Write a string to the serial port. + /*! Write a string to the serial port. * * \param data A const reference containing the data to be written * to the serial port. @@ -383,10 +394,10 @@ public: * \throw serial::SerialException * \throw serial::IOException */ - size_t - write (const std::vector &data); + size_t + write(const std::vector &data); - /*! Write a string to the serial port. + /*! Write a string to the serial port. * * \param data A const reference containing the data to be written * to the serial port. @@ -398,10 +409,10 @@ public: * \throw serial::SerialException * \throw serial::IOException */ - size_t - write (const std::string &data); + size_t + write(const std::string &data); - /*! Sets the serial port identifier. + /*! Sets the serial port identifier. * * \param port A const std::string reference containing the address of the * serial port, which would be something like 'COM1' on Windows and @@ -409,19 +420,19 @@ public: * * \throw std::invalid_argument */ - void - setPort (const std::string &port); + void + setPort(const std::string &port); - /*! Gets the serial port identifier. + /*! Gets the serial port identifier. * * \see Serial::setPort * * \throw std::invalid_argument */ - std::string - getPort () const; + std::string + getPort() const; - /*! Sets the timeout for reads and writes using the Timeout struct. + /*! Sets the timeout for reads and writes using the Timeout struct. * * There are two timeout conditions described here: * * The inter byte timeout: @@ -457,32 +468,32 @@ public: * * \see serial::Timeout */ - void - setTimeout (Timeout &timeout); + void + setTimeout(Timeout &timeout); - /*! Sets the timeout for reads and writes. */ - void - setTimeout (uint32_t inter_byte_timeout, uint32_t read_timeout_constant, - uint32_t read_timeout_multiplier, uint32_t write_timeout_constant, - uint32_t write_timeout_multiplier) - { - Timeout timeout(inter_byte_timeout, read_timeout_constant, - read_timeout_multiplier, write_timeout_constant, - write_timeout_multiplier); - return setTimeout(timeout); - } + /*! Sets the timeout for reads and writes. */ + void + setTimeout(uint32_t inter_byte_timeout, uint32_t read_timeout_constant, + uint32_t read_timeout_multiplier, uint32_t write_timeout_constant, + uint32_t write_timeout_multiplier) + { + Timeout timeout(inter_byte_timeout, read_timeout_constant, + read_timeout_multiplier, write_timeout_constant, + write_timeout_multiplier); + return setTimeout(timeout); + } - /*! Gets the timeout for reads in seconds. + /*! Gets the timeout for reads in seconds. * * \return A Timeout struct containing the inter_byte_timeout, and read * and write timeout constants and multipliers. * * \see Serial::setTimeout */ - Timeout - getTimeout () const; + Timeout + getTimeout() const; - /*! Sets the baudrate for the serial port. + /*! Sets the baudrate for the serial port. * * Possible baudrates depends on the system but some safe baudrates include: * 110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 56000, @@ -494,10 +505,10 @@ public: * * \throw std::invalid_argument */ - void - setBaudrate (uint32_t baudrate); + void + setBaudrate(uint32_t baudrate); - /*! Gets the baudrate for the serial port. + /*! Gets the baudrate for the serial port. * * \return An integer that sets the baud rate for the serial port. * @@ -505,10 +516,10 @@ public: * * \throw std::invalid_argument */ - uint32_t - getBaudrate () const; + uint32_t + getBaudrate() const; - /*! Sets the bytesize for the serial port. + /*! Sets the bytesize for the serial port. * * \param bytesize Size of each byte in the serial transmission of data, * default is eightbits, possible values are: fivebits, sixbits, sevenbits, @@ -516,57 +527,57 @@ public: * * \throw std::invalid_argument */ - void - setBytesize (bytesize_t bytesize); + void + setBytesize(bytesize_t bytesize); - /*! Gets the bytesize for the serial port. + /*! Gets the bytesize for the serial port. * * \see Serial::setBytesize * * \throw std::invalid_argument */ - bytesize_t - getBytesize () const; + bytesize_t + getBytesize() const; - /*! Sets the parity for the serial port. + /*! Sets the parity for the serial port. * * \param parity Method of parity, default is parity_none, possible values * are: parity_none, parity_odd, parity_even * * \throw std::invalid_argument */ - void - setParity (parity_t parity); + void + setParity(parity_t parity); - /*! Gets the parity for the serial port. + /*! Gets the parity for the serial port. * * \see Serial::setParity * * \throw std::invalid_argument */ - parity_t - getParity () const; + parity_t + getParity() const; - /*! Sets the stopbits for the serial port. + /*! Sets the stopbits for the serial port. * * \param stopbits Number of stop bits used, default is stopbits_one, * possible values are: stopbits_one, stopbits_one_point_five, stopbits_two * * \throw std::invalid_argument */ - void - setStopbits (stopbits_t stopbits); + void + setStopbits(stopbits_t stopbits); - /*! Gets the stopbits for the serial port. + /*! Gets the stopbits for the serial port. * * \see Serial::setStopbits * * \throw std::invalid_argument */ - stopbits_t - getStopbits () const; + stopbits_t + getStopbits() const; - /*! Sets the flow control for the serial port. + /*! Sets the flow control for the serial port. * * \param flowcontrol Type of flowcontrol used, default is flowcontrol_none, * possible values are: flowcontrol_none, flowcontrol_software, @@ -574,47 +585,47 @@ public: * * \throw std::invalid_argument */ - void - setFlowcontrol (flowcontrol_t flowcontrol); + void + setFlowcontrol(flowcontrol_t flowcontrol); - /*! Gets the flow control for the serial port. + /*! Gets the flow control for the serial port. * * \see Serial::setFlowcontrol * * \throw std::invalid_argument */ - flowcontrol_t - getFlowcontrol () const; + flowcontrol_t + getFlowcontrol() const; - /*! Flush the input and output buffers */ - void - flush (); + /*! Flush the input and output buffers */ + void + flush(); - /*! Flush only the input buffer */ - void - flushInput (); + /*! Flush only the input buffer */ + void + flushInput(); - /*! Flush only the output buffer */ - void - flushOutput (); + /*! Flush only the output buffer */ + void + flushOutput(); - /*! Sends the RS-232 break signal. See tcsendbreak(3). */ - void - sendBreak (int duration); + /*! Sends the RS-232 break signal. See tcsendbreak(3). */ + void + sendBreak(int duration); - /*! Set the break condition to a given level. Defaults to true. */ - void - setBreak (bool level = true); + /*! Set the break condition to a given level. Defaults to true. */ + void + setBreak(bool level = true); - /*! Set the RTS handshaking line to the given level. Defaults to true. */ - void - setRTS (bool level = true); + /*! Set the RTS handshaking line to the given level. Defaults to true. */ + void + setRTS(bool level = true); - /*! Set the DTR handshaking line to the given level. Defaults to true. */ - void - setDTR (bool level = true); + /*! Set the DTR handshaking line to the given level. Defaults to true. */ + void + setDTR(bool level = true); - /*! + /*! * Blocks until CTS, DSR, RI, CD changes or something interrupts it. * * Can throw an exception if an error occurs while waiting. @@ -628,136 +639,144 @@ public: * * \throw SerialException */ - bool - waitForChange (); + bool + waitForChange(); - /*! Returns the current status of the CTS line. */ - bool - getCTS (); + /*! Returns the current status of the CTS line. */ + bool + getCTS(); - /*! Returns the current status of the DSR line. */ - bool - getDSR (); + /*! Returns the current status of the DSR line. */ + bool + getDSR(); - /*! Returns the current status of the RI line. */ - bool - getRI (); + /*! Returns the current status of the RI line. */ + bool + getRI(); - /*! Returns the current status of the CD line. */ - bool - getCD (); + /*! Returns the current status of the CD line. */ + bool + getCD(); private: - // Disable copy constructors - Serial(const Serial&); - Serial& operator=(const Serial&); + // Disable copy constructors + Serial(const Serial &); + Serial &operator=(const Serial &); - // Pimpl idiom, d_pointer - class SerialImpl; - SerialImpl *pimpl_; + // Pimpl idiom, d_pointer + class SerialImpl; + SerialImpl *pimpl_; - // Scoped Lock Classes - class ScopedReadLock; - class ScopedWriteLock; - - // Read common function - size_t - read_ (uint8_t *buffer, size_t size); - // Write common function - size_t - write_ (const uint8_t *data, size_t length); + // Scoped Lock Classes + class ScopedReadLock; + class ScopedWriteLock; + // Read common function + size_t + read_(uint8_t *buffer, size_t size); + // Write common function + size_t + write_(const uint8_t *data, size_t length); }; class SerialException : public std::exception { - // Disable copy constructors - SerialException& operator=(const SerialException&); - std::string e_what_; + // Disable copy constructors + SerialException &operator=(const SerialException &); + std::string e_what_; + public: - SerialException (const char *description) { - std::stringstream ss; - ss << "SerialException " << description << " failed."; - e_what_ = ss.str(); - } - SerialException (const SerialException& other) : e_what_(other.e_what_) {} - virtual ~SerialException() throw() {} - virtual const char* what () const throw () { - return e_what_.c_str(); - } + SerialException(const char *description) + { + std::stringstream ss; + ss << "SerialException " << description << " failed."; + e_what_ = ss.str(); + } + SerialException(const SerialException &other) : e_what_(other.e_what_) {} + virtual ~SerialException() throw() {} + virtual const char *what() const throw() + { + return e_what_.c_str(); + } }; class IOException : public std::exception { - // Disable copy constructors - IOException& operator=(const IOException&); - std::string file_; - int line_; - std::string e_what_; - int errno_; + // Disable copy constructors + IOException &operator=(const IOException &); + std::string file_; + int line_; + std::string e_what_; + int errno_; + public: - explicit IOException (std::string file, int line, int errnum) - : file_(file), line_(line), errno_(errnum) { - std::stringstream ss; + explicit IOException(std::string file, int line, int errnum) + : file_(file), line_(line), errno_(errnum) + { + std::stringstream ss; #if defined(_WIN32) && !defined(__MINGW32__) - char error_str [1024]; - strerror_s(error_str, 1024, errnum); + char error_str[1024]; + strerror_s(error_str, 1024, errnum); #else - char * error_str = strerror(errnum); + char *error_str = strerror(errnum); #endif - ss << "IO Exception (" << errno_ << "): " << error_str; - ss << ", file " << file_ << ", line " << line_ << "."; - e_what_ = ss.str(); - } - explicit IOException (std::string file, int line, const char * description) - : file_(file), line_(line), errno_(0) { - std::stringstream ss; - ss << "IO Exception: " << description; - ss << ", file " << file_ << ", line " << line_ << "."; - e_what_ = ss.str(); - } - virtual ~IOException() throw() {} - IOException (const IOException& other) : line_(other.line_), e_what_(other.e_what_), errno_(other.errno_) {} + ss << "IO Exception (" << errno_ << "): " << error_str; + ss << ", file " << file_ << ", line " << line_ << "."; + e_what_ = ss.str(); + } + explicit IOException(std::string file, int line, const char *description) + : file_(file), line_(line), errno_(0) + { + std::stringstream ss; + ss << "IO Exception: " << description; + ss << ", file " << file_ << ", line " << line_ << "."; + e_what_ = ss.str(); + } + virtual ~IOException() throw() {} + IOException(const IOException &other) : line_(other.line_), e_what_(other.e_what_), errno_(other.errno_) {} - int getErrorNumber () const { return errno_; } + int getErrorNumber() const { return errno_; } - virtual const char* what () const throw () { - return e_what_.c_str(); - } + virtual const char *what() const throw() + { + return e_what_.c_str(); + } }; class PortNotOpenedException : public std::exception { - // Disable copy constructors - const PortNotOpenedException& operator=(PortNotOpenedException); - std::string e_what_; + // Disable copy constructors + const PortNotOpenedException &operator=(PortNotOpenedException); + std::string e_what_; + public: - PortNotOpenedException (const char * description) { - std::stringstream ss; - ss << "PortNotOpenedException " << description << " failed."; - e_what_ = ss.str(); - } - PortNotOpenedException (const PortNotOpenedException& other) : e_what_(other.e_what_) {} - virtual ~PortNotOpenedException() throw() {} - virtual const char* what () const throw () { - return e_what_.c_str(); - } + PortNotOpenedException(const char *description) + { + std::stringstream ss; + ss << "PortNotOpenedException " << description << " failed."; + e_what_ = ss.str(); + } + PortNotOpenedException(const PortNotOpenedException &other) : e_what_(other.e_what_) {} + virtual ~PortNotOpenedException() throw() {} + virtual const char *what() const throw() + { + return e_what_.c_str(); + } }; /*! * Structure that describes a serial device. */ -struct PortInfo { +struct PortInfo +{ + /*! Address of the serial port (this can be passed to the constructor of Serial). */ + std::string port; - /*! Address of the serial port (this can be passed to the constructor of Serial). */ - std::string port; - - /*! Human readable description of serial device if available. */ - std::string description; - - /*! Hardware ID (e.g. VID:PID of USB serial devices) or "n/a" if not available. */ - std::string hardware_id; + /*! Human readable description of serial device if available. */ + std::string description; + /*! Hardware ID (e.g. VID:PID of USB serial devices) or "n/a" if not available. */ + std::string hardware_id; }; /* Lists the serial ports available on the system @@ -770,6 +789,6 @@ struct PortInfo { std::vector list_ports(); -} // namespace serial +} // namespace serial #endif diff --git a/examples/ThirdPartyLibs/serial/include/serial/v8stdint.h b/examples/ThirdPartyLibs/serial/include/serial/v8stdint.h index f3be96b1c..082e1ece4 100644 --- a/examples/ThirdPartyLibs/serial/include/serial/v8stdint.h +++ b/examples/ThirdPartyLibs/serial/include/serial/v8stdint.h @@ -40,7 +40,7 @@ typedef signed char int8_t; typedef unsigned char uint8_t; -typedef short int16_t; // NOLINT +typedef short int16_t; // NOLINT typedef unsigned short uint16_t; // NOLINT typedef int int32_t; typedef unsigned int uint32_t; diff --git a/examples/ThirdPartyLibs/serial/src/impl/list_ports/list_ports_linux.cc b/examples/ThirdPartyLibs/serial/src/impl/list_ports/list_ports_linux.cc index 9779d5eb5..b0ea3061f 100644 --- a/examples/ThirdPartyLibs/serial/src/impl/list_ports/list_ports_linux.cc +++ b/examples/ThirdPartyLibs/serial/src/impl/list_ports/list_ports_linux.cc @@ -25,13 +25,13 @@ #include "serial/serial.h" using serial::PortInfo; -using std::istringstream; -using std::ifstream; -using std::getline; -using std::vector; -using std::string; using std::cout; using std::endl; +using std::getline; +using std::ifstream; +using std::istringstream; +using std::string; +using std::vector; static vector glob(const vector& patterns); static string basename(const string& path); @@ -47,289 +47,287 @@ static string format(const char* format, ...); vector glob(const vector& patterns) { - vector paths_found; + vector paths_found; - if(patterns.size() == 0) - return paths_found; + if (patterns.size() == 0) + return paths_found; - glob_t glob_results; + glob_t glob_results; - int glob_retval = glob(patterns[0].c_str(), 0, NULL, &glob_results); + int glob_retval = glob(patterns[0].c_str(), 0, NULL, &glob_results); - vector::const_iterator iter = patterns.begin(); + vector::const_iterator iter = patterns.begin(); - while(++iter != patterns.end()) - { - glob_retval = glob(iter->c_str(), GLOB_APPEND, NULL, &glob_results); - } + while (++iter != patterns.end()) + { + glob_retval = glob(iter->c_str(), GLOB_APPEND, NULL, &glob_results); + } - for(int path_index = 0; path_index < glob_results.gl_pathc; path_index++) - { - paths_found.push_back(glob_results.gl_pathv[path_index]); - } + for (int path_index = 0; path_index < glob_results.gl_pathc; path_index++) + { + paths_found.push_back(glob_results.gl_pathv[path_index]); + } - globfree(&glob_results); + globfree(&glob_results); - return paths_found; + return paths_found; } string basename(const string& path) { - size_t pos = path.rfind("/"); + size_t pos = path.rfind("/"); - if(pos == std::string::npos) - return path; + if (pos == std::string::npos) + return path; - return string(path, pos+1, string::npos); + return string(path, pos + 1, string::npos); } string dirname(const string& path) { - size_t pos = path.rfind("/"); + size_t pos = path.rfind("/"); - if(pos == std::string::npos) - return path; - else if(pos == 0) - return "/"; + if (pos == std::string::npos) + return path; + else if (pos == 0) + return "/"; - return string(path, 0, pos); + return string(path, 0, pos); } -bool -path_exists(const string& path) +bool path_exists(const string& path) { - struct stat sb; + struct stat sb; - if( stat(path.c_str(), &sb ) == 0 ) - return true; + if (stat(path.c_str(), &sb) == 0) + return true; - return false; + return false; } string realpath(const string& path) { - char* real_path = realpath(path.c_str(), NULL); + char* real_path = realpath(path.c_str(), NULL); - string result; + string result; - if(real_path != NULL) - { - result = real_path; + if (real_path != NULL) + { + result = real_path; - free(real_path); - } + free(real_path); + } - return result; + return result; } string usb_sysfs_friendly_name(const string& sys_usb_path) { - unsigned int device_number = 0; + unsigned int device_number = 0; - istringstream( read_line(sys_usb_path + "/devnum") ) >> device_number; + istringstream(read_line(sys_usb_path + "/devnum")) >> device_number; - string manufacturer = read_line( sys_usb_path + "/manufacturer" ); + string manufacturer = read_line(sys_usb_path + "/manufacturer"); - string product = read_line( sys_usb_path + "/product" ); + string product = read_line(sys_usb_path + "/product"); - string serial = read_line( sys_usb_path + "/serial" ); + string serial = read_line(sys_usb_path + "/serial"); - if( manufacturer.empty() && product.empty() && serial.empty() ) - return ""; + if (manufacturer.empty() && product.empty() && serial.empty()) + return ""; - return format("%s %s %s", manufacturer.c_str(), product.c_str(), serial.c_str() ); + return format("%s %s %s", manufacturer.c_str(), product.c_str(), serial.c_str()); } vector get_sysfs_info(const string& device_path) { - string device_name = basename( device_path ); + string device_name = basename(device_path); - string friendly_name; + string friendly_name; - string hardware_id; + string hardware_id; - string sys_device_path = format( "/sys/class/tty/%s/device", device_name.c_str() ); + string sys_device_path = format("/sys/class/tty/%s/device", device_name.c_str()); - if( device_name.compare(0,6,"ttyUSB") == 0 ) - { - sys_device_path = dirname( dirname( realpath( sys_device_path ) ) ); + if (device_name.compare(0, 6, "ttyUSB") == 0) + { + sys_device_path = dirname(dirname(realpath(sys_device_path))); - if( path_exists( sys_device_path ) ) - { - friendly_name = usb_sysfs_friendly_name( sys_device_path ); + if (path_exists(sys_device_path)) + { + friendly_name = usb_sysfs_friendly_name(sys_device_path); - hardware_id = usb_sysfs_hw_string( sys_device_path ); - } - } - else if( device_name.compare(0,6,"ttyACM") == 0 ) - { - sys_device_path = dirname( realpath( sys_device_path ) ); + hardware_id = usb_sysfs_hw_string(sys_device_path); + } + } + else if (device_name.compare(0, 6, "ttyACM") == 0) + { + sys_device_path = dirname(realpath(sys_device_path)); - if( path_exists( sys_device_path ) ) - { - friendly_name = usb_sysfs_friendly_name( sys_device_path ); + if (path_exists(sys_device_path)) + { + friendly_name = usb_sysfs_friendly_name(sys_device_path); - hardware_id = usb_sysfs_hw_string( sys_device_path ); - } - } - else - { - // Try to read ID string of PCI device + hardware_id = usb_sysfs_hw_string(sys_device_path); + } + } + else + { + // Try to read ID string of PCI device - string sys_id_path = sys_device_path + "/id"; + string sys_id_path = sys_device_path + "/id"; - if( path_exists( sys_id_path ) ) - hardware_id = read_line( sys_id_path ); - } + if (path_exists(sys_id_path)) + hardware_id = read_line(sys_id_path); + } - if( friendly_name.empty() ) - friendly_name = device_name; + if (friendly_name.empty()) + friendly_name = device_name; - if( hardware_id.empty() ) - hardware_id = "n/a"; + if (hardware_id.empty()) + hardware_id = "n/a"; - vector result; - result.push_back(friendly_name); - result.push_back(hardware_id); + vector result; + result.push_back(friendly_name); + result.push_back(hardware_id); - return result; + return result; } string read_line(const string& file) { - ifstream ifs(file.c_str(), ifstream::in); + ifstream ifs(file.c_str(), ifstream::in); - string line; + string line; - if(ifs) - { - getline(ifs, line); - } + if (ifs) + { + getline(ifs, line); + } - return line; + return line; } string format(const char* format, ...) { - va_list ap; + va_list ap; - size_t buffer_size_bytes = 256; + size_t buffer_size_bytes = 256; - string result; + string result; - char* buffer = (char*)malloc(buffer_size_bytes); + char* buffer = (char*)malloc(buffer_size_bytes); - if( buffer == NULL ) - return result; + if (buffer == NULL) + return result; - bool done = false; + bool done = false; - unsigned int loop_count = 0; + unsigned int loop_count = 0; - while(!done) - { - va_start(ap, format); + while (!done) + { + va_start(ap, format); - int return_value = vsnprintf(buffer, buffer_size_bytes, format, ap); + int return_value = vsnprintf(buffer, buffer_size_bytes, format, ap); - if( return_value < 0 ) - { - done = true; - } - else if( return_value >= buffer_size_bytes ) - { - // Realloc and try again. + if (return_value < 0) + { + done = true; + } + else if (return_value >= buffer_size_bytes) + { + // Realloc and try again. - buffer_size_bytes = return_value + 1; + buffer_size_bytes = return_value + 1; - char* new_buffer_ptr = (char*)realloc(buffer, buffer_size_bytes); + char* new_buffer_ptr = (char*)realloc(buffer, buffer_size_bytes); - if( new_buffer_ptr == NULL ) - { - done = true; - } - else - { - buffer = new_buffer_ptr; - } - } - else - { - result = buffer; - done = true; - } + if (new_buffer_ptr == NULL) + { + done = true; + } + else + { + buffer = new_buffer_ptr; + } + } + else + { + result = buffer; + done = true; + } - va_end(ap); + va_end(ap); - if( ++loop_count > 5 ) - done = true; - } + if (++loop_count > 5) + done = true; + } - free(buffer); + free(buffer); - return result; + return result; } string usb_sysfs_hw_string(const string& sysfs_path) { - string serial_number = read_line( sysfs_path + "/serial" ); + string serial_number = read_line(sysfs_path + "/serial"); - if( serial_number.length() > 0 ) - { - serial_number = format( "SNR=%s", serial_number.c_str() ); - } + if (serial_number.length() > 0) + { + serial_number = format("SNR=%s", serial_number.c_str()); + } - string vid = read_line( sysfs_path + "/idVendor" ); + string vid = read_line(sysfs_path + "/idVendor"); - string pid = read_line( sysfs_path + "/idProduct" ); + string pid = read_line(sysfs_path + "/idProduct"); - return format("USB VID:PID=%s:%s %s", vid.c_str(), pid.c_str(), serial_number.c_str() ); + return format("USB VID:PID=%s:%s %s", vid.c_str(), pid.c_str(), serial_number.c_str()); } vector serial::list_ports() { - vector results; + vector results; - vector search_globs; - search_globs.push_back("/dev/ttyACM*"); - search_globs.push_back("/dev/ttyS*"); - search_globs.push_back("/dev/ttyUSB*"); - search_globs.push_back("/dev/tty.*"); - search_globs.push_back("/dev/cu.*"); + vector search_globs; + search_globs.push_back("/dev/ttyACM*"); + search_globs.push_back("/dev/ttyS*"); + search_globs.push_back("/dev/ttyUSB*"); + search_globs.push_back("/dev/tty.*"); + search_globs.push_back("/dev/cu.*"); - vector devices_found = glob( search_globs ); + vector devices_found = glob(search_globs); - vector::iterator iter = devices_found.begin(); + vector::iterator iter = devices_found.begin(); - while( iter != devices_found.end() ) - { - string device = *iter++; + while (iter != devices_found.end()) + { + string device = *iter++; - vector sysfs_info = get_sysfs_info( device ); + vector sysfs_info = get_sysfs_info(device); - string friendly_name = sysfs_info[0]; + string friendly_name = sysfs_info[0]; - string hardware_id = sysfs_info[1]; + string hardware_id = sysfs_info[1]; - PortInfo device_entry; - device_entry.port = device; - device_entry.description = friendly_name; - device_entry.hardware_id = hardware_id; + PortInfo device_entry; + device_entry.port = device; + device_entry.description = friendly_name; + device_entry.hardware_id = hardware_id; - results.push_back( device_entry ); + results.push_back(device_entry); + } - } - - return results; + return results; } -#endif // defined(__linux__) +#endif // defined(__linux__) diff --git a/examples/ThirdPartyLibs/serial/src/impl/list_ports/list_ports_osx.cc b/examples/ThirdPartyLibs/serial/src/impl/list_ports/list_ports_osx.cc index 333c55c27..341370bfd 100644 --- a/examples/ThirdPartyLibs/serial/src/impl/list_ports/list_ports_osx.cc +++ b/examples/ThirdPartyLibs/serial/src/impl/list_ports/list_ports_osx.cc @@ -20,267 +20,266 @@ using std::vector; #define HARDWARE_ID_STRING_LENGTH 128 -string cfstring_to_string( CFStringRef cfstring ); -string get_device_path( io_object_t& serial_port ); -string get_class_name( io_object_t& obj ); -io_registry_entry_t get_parent_iousb_device( io_object_t& serial_port ); -string get_string_property( io_object_t& device, const char* property ); -uint16_t get_int_property( io_object_t& device, const char* property ); +string cfstring_to_string(CFStringRef cfstring); +string get_device_path(io_object_t& serial_port); +string get_class_name(io_object_t& obj); +io_registry_entry_t get_parent_iousb_device(io_object_t& serial_port); +string get_string_property(io_object_t& device, const char* property); +uint16_t get_int_property(io_object_t& device, const char* property); string rtrim(const string& str); string -cfstring_to_string( CFStringRef cfstring ) +cfstring_to_string(CFStringRef cfstring) { - char cstring[MAXPATHLEN]; - string result; + char cstring[MAXPATHLEN]; + string result; - if( cfstring ) - { - Boolean success = CFStringGetCString( cfstring, - cstring, - sizeof(cstring), - kCFStringEncodingASCII ); + if (cfstring) + { + Boolean success = CFStringGetCString(cfstring, + cstring, + sizeof(cstring), + kCFStringEncodingASCII); - if( success ) - result = cstring; - } + if (success) + result = cstring; + } - return result; + return result; } string -get_device_path( io_object_t& serial_port ) +get_device_path(io_object_t& serial_port) { - CFTypeRef callout_path; - string device_path; + CFTypeRef callout_path; + string device_path; - callout_path = IORegistryEntryCreateCFProperty( serial_port, - CFSTR(kIOCalloutDeviceKey), - kCFAllocatorDefault, - 0 ); + callout_path = IORegistryEntryCreateCFProperty(serial_port, + CFSTR(kIOCalloutDeviceKey), + kCFAllocatorDefault, + 0); - if (callout_path) - { - if( CFGetTypeID(callout_path) == CFStringGetTypeID() ) - device_path = cfstring_to_string( static_cast(callout_path) ); + if (callout_path) + { + if (CFGetTypeID(callout_path) == CFStringGetTypeID()) + device_path = cfstring_to_string(static_cast(callout_path)); - CFRelease(callout_path); - } + CFRelease(callout_path); + } - return device_path; + return device_path; } string -get_class_name( io_object_t& obj ) +get_class_name(io_object_t& obj) { - string result; - io_name_t class_name; - kern_return_t kern_result; + string result; + io_name_t class_name; + kern_return_t kern_result; - kern_result = IOObjectGetClass( obj, class_name ); + kern_result = IOObjectGetClass(obj, class_name); - if( kern_result == KERN_SUCCESS ) - result = class_name; + if (kern_result == KERN_SUCCESS) + result = class_name; - return result; + return result; } io_registry_entry_t -get_parent_iousb_device( io_object_t& serial_port ) +get_parent_iousb_device(io_object_t& serial_port) { - io_object_t device = serial_port; - io_registry_entry_t parent = 0; - io_registry_entry_t result = 0; - kern_return_t kern_result = KERN_FAILURE; - string name = get_class_name(device); + io_object_t device = serial_port; + io_registry_entry_t parent = 0; + io_registry_entry_t result = 0; + kern_return_t kern_result = KERN_FAILURE; + string name = get_class_name(device); - // Walk the IO Registry tree looking for this devices parent IOUSBDevice. - while( name != "IOUSBDevice" ) - { - kern_result = IORegistryEntryGetParentEntry( device, - kIOServicePlane, - &parent ); + // Walk the IO Registry tree looking for this devices parent IOUSBDevice. + while (name != "IOUSBDevice") + { + kern_result = IORegistryEntryGetParentEntry(device, + kIOServicePlane, + &parent); - if(kern_result != KERN_SUCCESS) - { - result = 0; - break; - } + if (kern_result != KERN_SUCCESS) + { + result = 0; + break; + } - device = parent; + device = parent; - name = get_class_name(device); - } + name = get_class_name(device); + } - if(kern_result == KERN_SUCCESS) - result = device; + if (kern_result == KERN_SUCCESS) + result = device; - return result; + return result; } string -get_string_property( io_object_t& device, const char* property ) +get_string_property(io_object_t& device, const char* property) { - string property_name; + string property_name; - if( device ) - { - CFStringRef property_as_cfstring = CFStringCreateWithCString ( - kCFAllocatorDefault, - property, - kCFStringEncodingASCII ); + if (device) + { + CFStringRef property_as_cfstring = CFStringCreateWithCString( + kCFAllocatorDefault, + property, + kCFStringEncodingASCII); - CFTypeRef name_as_cfstring = IORegistryEntryCreateCFProperty( - device, - property_as_cfstring, - kCFAllocatorDefault, - 0 ); + CFTypeRef name_as_cfstring = IORegistryEntryCreateCFProperty( + device, + property_as_cfstring, + kCFAllocatorDefault, + 0); - if( name_as_cfstring ) - { - if( CFGetTypeID(name_as_cfstring) == CFStringGetTypeID() ) - property_name = cfstring_to_string( static_cast(name_as_cfstring) ); + if (name_as_cfstring) + { + if (CFGetTypeID(name_as_cfstring) == CFStringGetTypeID()) + property_name = cfstring_to_string(static_cast(name_as_cfstring)); - CFRelease(name_as_cfstring); - } + CFRelease(name_as_cfstring); + } - if(property_as_cfstring) - CFRelease(property_as_cfstring); - } + if (property_as_cfstring) + CFRelease(property_as_cfstring); + } - return property_name; + return property_name; } uint16_t -get_int_property( io_object_t& device, const char* property ) +get_int_property(io_object_t& device, const char* property) { - uint16_t result = 0; + uint16_t result = 0; - if( device ) - { - CFStringRef property_as_cfstring = CFStringCreateWithCString ( - kCFAllocatorDefault, - property, - kCFStringEncodingASCII ); + if (device) + { + CFStringRef property_as_cfstring = CFStringCreateWithCString( + kCFAllocatorDefault, + property, + kCFStringEncodingASCII); - CFTypeRef number = IORegistryEntryCreateCFProperty( device, - property_as_cfstring, - kCFAllocatorDefault, - 0 ); + CFTypeRef number = IORegistryEntryCreateCFProperty(device, + property_as_cfstring, + kCFAllocatorDefault, + 0); - if(property_as_cfstring) - CFRelease(property_as_cfstring); + if (property_as_cfstring) + CFRelease(property_as_cfstring); - if( number ) - { - if( CFGetTypeID(number) == CFNumberGetTypeID() ) - { - bool success = CFNumberGetValue( static_cast(number), - kCFNumberSInt16Type, - &result ); + if (number) + { + if (CFGetTypeID(number) == CFNumberGetTypeID()) + { + bool success = CFNumberGetValue(static_cast(number), + kCFNumberSInt16Type, + &result); - if( !success ) - result = 0; - } + if (!success) + result = 0; + } - CFRelease(number); - } + CFRelease(number); + } + } - } - - return result; + return result; } string rtrim(const string& str) { - string result = str; + string result = str; - string whitespace = " \t\f\v\n\r"; + string whitespace = " \t\f\v\n\r"; - std::size_t found = result.find_last_not_of(whitespace); + std::size_t found = result.find_last_not_of(whitespace); - if (found != std::string::npos) - result.erase(found+1); - else - result.clear(); + if (found != std::string::npos) + result.erase(found + 1); + else + result.clear(); - return result; + return result; } vector serial::list_ports(void) { - vector devices_found; - CFMutableDictionaryRef classes_to_match; - io_iterator_t serial_port_iterator; - io_object_t serial_port; - mach_port_t master_port; - kern_return_t kern_result; + vector devices_found; + CFMutableDictionaryRef classes_to_match; + io_iterator_t serial_port_iterator; + io_object_t serial_port; + mach_port_t master_port; + kern_return_t kern_result; - kern_result = IOMasterPort(MACH_PORT_NULL, &master_port); + kern_result = IOMasterPort(MACH_PORT_NULL, &master_port); - if(kern_result != KERN_SUCCESS) - return devices_found; + if (kern_result != KERN_SUCCESS) + return devices_found; - classes_to_match = IOServiceMatching(kIOSerialBSDServiceValue); + classes_to_match = IOServiceMatching(kIOSerialBSDServiceValue); - if (classes_to_match == NULL) - return devices_found; + if (classes_to_match == NULL) + return devices_found; - CFDictionarySetValue( classes_to_match, - CFSTR(kIOSerialBSDTypeKey), - CFSTR(kIOSerialBSDAllTypes) ); + CFDictionarySetValue(classes_to_match, + CFSTR(kIOSerialBSDTypeKey), + CFSTR(kIOSerialBSDAllTypes)); - kern_result = IOServiceGetMatchingServices(master_port, classes_to_match, &serial_port_iterator); + kern_result = IOServiceGetMatchingServices(master_port, classes_to_match, &serial_port_iterator); - if (KERN_SUCCESS != kern_result) - return devices_found; + if (KERN_SUCCESS != kern_result) + return devices_found; - while ( (serial_port = IOIteratorNext(serial_port_iterator)) ) - { - string device_path = get_device_path( serial_port ); - io_registry_entry_t parent = get_parent_iousb_device( serial_port ); - IOObjectRelease(serial_port); + while ((serial_port = IOIteratorNext(serial_port_iterator))) + { + string device_path = get_device_path(serial_port); + io_registry_entry_t parent = get_parent_iousb_device(serial_port); + IOObjectRelease(serial_port); - if( device_path.empty() ) - continue; + if (device_path.empty()) + continue; - PortInfo port_info; - port_info.port = device_path; - port_info.description = "n/a"; - port_info.hardware_id = "n/a"; + PortInfo port_info; + port_info.port = device_path; + port_info.description = "n/a"; + port_info.hardware_id = "n/a"; - string device_name = rtrim( get_string_property( parent, "USB Product Name" ) ); - string vendor_name = rtrim( get_string_property( parent, "USB Vendor Name") ); - string description = rtrim( vendor_name + " " + device_name ); - if( !description.empty() ) - port_info.description = description; + string device_name = rtrim(get_string_property(parent, "USB Product Name")); + string vendor_name = rtrim(get_string_property(parent, "USB Vendor Name")); + string description = rtrim(vendor_name + " " + device_name); + if (!description.empty()) + port_info.description = description; - string serial_number = rtrim(get_string_property( parent, "USB Serial Number" ) ); - uint16_t vendor_id = get_int_property( parent, "idVendor" ); - uint16_t product_id = get_int_property( parent, "idProduct" ); + string serial_number = rtrim(get_string_property(parent, "USB Serial Number")); + uint16_t vendor_id = get_int_property(parent, "idVendor"); + uint16_t product_id = get_int_property(parent, "idProduct"); - if( vendor_id && product_id ) - { - char cstring[HARDWARE_ID_STRING_LENGTH]; + if (vendor_id && product_id) + { + char cstring[HARDWARE_ID_STRING_LENGTH]; - if(serial_number.empty()) - serial_number = "None"; + if (serial_number.empty()) + serial_number = "None"; - int ret = snprintf( cstring, HARDWARE_ID_STRING_LENGTH, "USB VID:PID=%04x:%04x SNR=%s", - vendor_id, - product_id, - serial_number.c_str() ); + int ret = snprintf(cstring, HARDWARE_ID_STRING_LENGTH, "USB VID:PID=%04x:%04x SNR=%s", + vendor_id, + product_id, + serial_number.c_str()); - if( (ret >= 0) && (ret < HARDWARE_ID_STRING_LENGTH) ) - port_info.hardware_id = cstring; - } + if ((ret >= 0) && (ret < HARDWARE_ID_STRING_LENGTH)) + port_info.hardware_id = cstring; + } - devices_found.push_back(port_info); - } + devices_found.push_back(port_info); + } - IOObjectRelease(serial_port_iterator); - return devices_found; + IOObjectRelease(serial_port_iterator); + return devices_found; } -#endif // defined(__APPLE__) +#endif // defined(__APPLE__) diff --git a/examples/ThirdPartyLibs/serial/src/impl/list_ports/list_ports_win.cc b/examples/ThirdPartyLibs/serial/src/impl/list_ports/list_ports_win.cc index 7da40c440..7d7c79a8f 100644 --- a/examples/ThirdPartyLibs/serial/src/impl/list_ports/list_ports_win.cc +++ b/examples/ThirdPartyLibs/serial/src/impl/list_ports/list_ports_win.cc @@ -16,8 +16,8 @@ #include using serial::PortInfo; -using std::vector; using std::string; +using std::vector; static const DWORD port_name_max_length = 256; static const DWORD friendly_name_max_length = 256; @@ -27,8 +27,8 @@ static const DWORD hardware_id_max_length = 256; std::string utf8_encode(const std::wstring &wstr) { int size_needed = WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), NULL, 0, NULL, NULL); - std::string strTo( size_needed, 0 ); - WideCharToMultiByte (CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL); + std::string strTo(size_needed, 0); + WideCharToMultiByte(CP_UTF8, 0, &wstr[0], (int)wstr.size(), &strTo[0], size_needed, NULL, NULL); return strTo; } @@ -38,7 +38,7 @@ serial::list_ports() vector devices_found; HDEVINFO device_info_set = SetupDiGetClassDevs( - (const GUID *) &GUID_DEVCLASS_PORTS, + (const GUID *)&GUID_DEVCLASS_PORTS, NULL, NULL, DIGCF_PRESENT); @@ -48,7 +48,7 @@ serial::list_ports() device_info_data.cbSize = sizeof(SP_DEVINFO_DATA); - while(SetupDiEnumDeviceInfo(device_info_set, device_info_set_index, &device_info_data)) + while (SetupDiEnumDeviceInfo(device_info_set, device_info_set_index, &device_info_data)) { device_info_set_index++; @@ -66,26 +66,26 @@ serial::list_ports() DWORD port_name_length = port_name_max_length; LONG return_code = RegQueryValueEx( - hkey, - _T("PortName"), - NULL, - NULL, - (LPBYTE)port_name, - &port_name_length); + hkey, + _T("PortName"), + NULL, + NULL, + (LPBYTE)port_name, + &port_name_length); RegCloseKey(hkey); - if(return_code != EXIT_SUCCESS) + if (return_code != EXIT_SUCCESS) continue; - if(port_name_length > 0 && port_name_length <= port_name_max_length) - port_name[port_name_length-1] = '\0'; + if (port_name_length > 0 && port_name_length <= port_name_max_length) + port_name[port_name_length - 1] = '\0'; else port_name[0] = '\0'; // Ignore parallel ports - if(_tcsstr(port_name, _T("LPT")) != NULL) + if (_tcsstr(port_name, _T("LPT")) != NULL) continue; // Get port friendly name @@ -94,16 +94,16 @@ serial::list_ports() DWORD friendly_name_actual_length = 0; BOOL got_friendly_name = SetupDiGetDeviceRegistryProperty( - device_info_set, - &device_info_data, - SPDRP_FRIENDLYNAME, - NULL, - (PBYTE)friendly_name, - friendly_name_max_length, - &friendly_name_actual_length); + device_info_set, + &device_info_data, + SPDRP_FRIENDLYNAME, + NULL, + (PBYTE)friendly_name, + friendly_name_max_length, + &friendly_name_actual_length); - if(got_friendly_name == TRUE && friendly_name_actual_length > 0) - friendly_name[friendly_name_actual_length-1] = '\0'; + if (got_friendly_name == TRUE && friendly_name_actual_length > 0) + friendly_name[friendly_name_actual_length - 1] = '\0'; else friendly_name[0] = '\0'; @@ -113,28 +113,28 @@ serial::list_ports() DWORD hardware_id_actual_length = 0; BOOL got_hardware_id = SetupDiGetDeviceRegistryProperty( - device_info_set, - &device_info_data, - SPDRP_HARDWAREID, - NULL, - (PBYTE)hardware_id, - hardware_id_max_length, - &hardware_id_actual_length); + device_info_set, + &device_info_data, + SPDRP_HARDWAREID, + NULL, + (PBYTE)hardware_id, + hardware_id_max_length, + &hardware_id_actual_length); - if(got_hardware_id == TRUE && hardware_id_actual_length > 0) - hardware_id[hardware_id_actual_length-1] = '\0'; + if (got_hardware_id == TRUE && hardware_id_actual_length > 0) + hardware_id[hardware_id_actual_length - 1] = '\0'; else hardware_id[0] = '\0'; - #ifdef UNICODE - std::string portName = utf8_encode(port_name); - std::string friendlyName = utf8_encode(friendly_name); - std::string hardwareId = utf8_encode(hardware_id); - #else - std::string portName = port_name; - std::string friendlyName = friendly_name; - std::string hardwareId = hardware_id; - #endif +#ifdef UNICODE + std::string portName = utf8_encode(port_name); + std::string friendlyName = utf8_encode(friendly_name); + std::string hardwareId = utf8_encode(hardware_id); +#else + std::string portName = port_name; + std::string friendlyName = friendly_name; + std::string hardwareId = hardware_id; +#endif PortInfo port_entry; port_entry.port = portName; @@ -149,4 +149,4 @@ serial::list_ports() return devices_found; } -#endif // #if defined(_WIN32) +#endif // #if defined(_WIN32) diff --git a/examples/ThirdPartyLibs/serial/src/impl/unix.cc b/examples/ThirdPartyLibs/serial/src/impl/unix.cc index 4ef6b32e1..4732dc561 100644 --- a/examples/ThirdPartyLibs/serial/src/impl/unix.cc +++ b/examples/ThirdPartyLibs/serial/src/impl/unix.cc @@ -20,7 +20,7 @@ #include #if defined(__linux__) -# include +#include #endif #include @@ -46,1018 +46,1151 @@ #include #endif -using std::string; -using std::stringstream; -using std::invalid_argument; +using serial::IOException; using serial::MillisecondTimer; +using serial::PortNotOpenedException; using serial::Serial; using serial::SerialException; -using serial::PortNotOpenedException; -using serial::IOException; +using std::invalid_argument; +using std::string; +using std::stringstream; - -MillisecondTimer::MillisecondTimer (const uint32_t millis) - : expiry(timespec_now()) +MillisecondTimer::MillisecondTimer(const uint32_t millis) + : expiry(timespec_now()) { - int64_t tv_nsec = expiry.tv_nsec + (millis * 1e6); - if (tv_nsec >= 1e9) { - int64_t sec_diff = tv_nsec / static_cast (1e9); - expiry.tv_nsec = tv_nsec % static_cast(1e9); - expiry.tv_sec += sec_diff; - } else { - expiry.tv_nsec = tv_nsec; - } + int64_t tv_nsec = expiry.tv_nsec + (millis * 1e6); + if (tv_nsec >= 1e9) + { + int64_t sec_diff = tv_nsec / static_cast(1e9); + expiry.tv_nsec = tv_nsec % static_cast(1e9); + expiry.tv_sec += sec_diff; + } + else + { + expiry.tv_nsec = tv_nsec; + } } int64_t -MillisecondTimer::remaining () +MillisecondTimer::remaining() { - timespec now(timespec_now()); - int64_t millis = (expiry.tv_sec - now.tv_sec) * 1e3; - millis += (expiry.tv_nsec - now.tv_nsec) / 1e6; - return millis; + timespec now(timespec_now()); + int64_t millis = (expiry.tv_sec - now.tv_sec) * 1e3; + millis += (expiry.tv_nsec - now.tv_nsec) / 1e6; + return millis; } timespec -MillisecondTimer::timespec_now () +MillisecondTimer::timespec_now() { - timespec time; -# ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time - clock_serv_t cclock; - mach_timespec_t mts; - host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock); - clock_get_time(cclock, &mts); - mach_port_deallocate(mach_task_self(), cclock); - time.tv_sec = mts.tv_sec; - time.tv_nsec = mts.tv_nsec; -# else - clock_gettime(CLOCK_MONOTONIC, &time); -# endif - return time; + timespec time; +#ifdef __MACH__ // OS X does not have clock_gettime, use clock_get_time + clock_serv_t cclock; + mach_timespec_t mts; + host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock); + clock_get_time(cclock, &mts); + mach_port_deallocate(mach_task_self(), cclock); + time.tv_sec = mts.tv_sec; + time.tv_nsec = mts.tv_nsec; +#else + clock_gettime(CLOCK_MONOTONIC, &time); +#endif + return time; } timespec -timespec_from_ms (const uint32_t millis) +timespec_from_ms(const uint32_t millis) { - timespec time; - time.tv_sec = millis / 1e3; - time.tv_nsec = (millis - (time.tv_sec * 1e3)) * 1e6; - return time; + timespec time; + time.tv_sec = millis / 1e3; + time.tv_nsec = (millis - (time.tv_sec * 1e3)) * 1e6; + return time; } -Serial::SerialImpl::SerialImpl (const string &port, unsigned long baudrate, - bytesize_t bytesize, - parity_t parity, stopbits_t stopbits, - flowcontrol_t flowcontrol) - : port_ (port), fd_ (-1), is_open_ (false), xonxoff_ (false), rtscts_ (false), - baudrate_ (baudrate), parity_ (parity), - bytesize_ (bytesize), stopbits_ (stopbits), flowcontrol_ (flowcontrol) +Serial::SerialImpl::SerialImpl(const string &port, unsigned long baudrate, + bytesize_t bytesize, + parity_t parity, stopbits_t stopbits, + flowcontrol_t flowcontrol) + : port_(port), fd_(-1), is_open_(false), xonxoff_(false), rtscts_(false), baudrate_(baudrate), parity_(parity), bytesize_(bytesize), stopbits_(stopbits), flowcontrol_(flowcontrol) { - pthread_mutex_init(&this->read_mutex, NULL); - pthread_mutex_init(&this->write_mutex, NULL); - if (port_.empty () == false) - open (); + pthread_mutex_init(&this->read_mutex, NULL); + pthread_mutex_init(&this->write_mutex, NULL); + if (port_.empty() == false) + open(); } -Serial::SerialImpl::~SerialImpl () +Serial::SerialImpl::~SerialImpl() { - close(); - pthread_mutex_destroy(&this->read_mutex); - pthread_mutex_destroy(&this->write_mutex); + close(); + pthread_mutex_destroy(&this->read_mutex); + pthread_mutex_destroy(&this->write_mutex); } -void -Serial::SerialImpl::open () +void Serial::SerialImpl::open() { - if (port_.empty ()) { - throw invalid_argument ("Empty port is invalid."); - } - if (is_open_ == true) { - throw SerialException ("Serial port already open."); - } + if (port_.empty()) + { + throw invalid_argument("Empty port is invalid."); + } + if (is_open_ == true) + { + throw SerialException("Serial port already open."); + } - fd_ = ::open (port_.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK); + fd_ = ::open(port_.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK); - if (fd_ == -1) { - switch (errno) { - case EINTR: - // Recurse because this is a recoverable error. - open (); - return; - case ENFILE: - case EMFILE: - THROW (IOException, "Too many file handles open."); - default: - THROW (IOException, errno); - } - } + if (fd_ == -1) + { + switch (errno) + { + case EINTR: + // Recurse because this is a recoverable error. + open(); + return; + case ENFILE: + case EMFILE: + THROW(IOException, "Too many file handles open."); + default: + THROW(IOException, errno); + } + } - reconfigurePort(); - is_open_ = true; + reconfigurePort(); + is_open_ = true; } -void -Serial::SerialImpl::reconfigurePort () +void Serial::SerialImpl::reconfigurePort() { - if (fd_ == -1) { - // Can only operate on a valid file descriptor - THROW (IOException, "Invalid file descriptor, is the serial port open?"); - } + if (fd_ == -1) + { + // Can only operate on a valid file descriptor + THROW(IOException, "Invalid file descriptor, is the serial port open?"); + } - struct termios options; // The options for the file descriptor + struct termios options; // The options for the file descriptor - if (tcgetattr(fd_, &options) == -1) { - THROW (IOException, "::tcgetattr"); - } + if (tcgetattr(fd_, &options) == -1) + { + THROW(IOException, "::tcgetattr"); + } - // set up raw mode / no echo / binary - options.c_cflag |= (tcflag_t) (CLOCAL | CREAD); - options.c_lflag &= (tcflag_t) ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | - ISIG | IEXTEN); //|ECHOPRT + // set up raw mode / no echo / binary + options.c_cflag |= (tcflag_t)(CLOCAL | CREAD); + options.c_lflag &= (tcflag_t) ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL | + ISIG | IEXTEN); //|ECHOPRT - options.c_oflag &= (tcflag_t) ~(OPOST); - options.c_iflag &= (tcflag_t) ~(INLCR | IGNCR | ICRNL | IGNBRK); + options.c_oflag &= (tcflag_t) ~(OPOST); + options.c_iflag &= (tcflag_t) ~(INLCR | IGNCR | ICRNL | IGNBRK); #ifdef IUCLC - options.c_iflag &= (tcflag_t) ~IUCLC; + options.c_iflag &= (tcflag_t)~IUCLC; #endif #ifdef PARMRK - options.c_iflag &= (tcflag_t) ~PARMRK; + options.c_iflag &= (tcflag_t)~PARMRK; #endif - // setup baud rate - bool custom_baud = false; - speed_t baud; - switch (baudrate_) { + // setup baud rate + bool custom_baud = false; + speed_t baud; + switch (baudrate_) + { #ifdef B0 - case 0: baud = B0; break; + case 0: + baud = B0; + break; #endif #ifdef B50 - case 50: baud = B50; break; + case 50: + baud = B50; + break; #endif #ifdef B75 - case 75: baud = B75; break; + case 75: + baud = B75; + break; #endif #ifdef B110 - case 110: baud = B110; break; + case 110: + baud = B110; + break; #endif #ifdef B134 - case 134: baud = B134; break; + case 134: + baud = B134; + break; #endif #ifdef B150 - case 150: baud = B150; break; + case 150: + baud = B150; + break; #endif #ifdef B200 - case 200: baud = B200; break; + case 200: + baud = B200; + break; #endif #ifdef B300 - case 300: baud = B300; break; + case 300: + baud = B300; + break; #endif #ifdef B600 - case 600: baud = B600; break; + case 600: + baud = B600; + break; #endif #ifdef B1200 - case 1200: baud = B1200; break; + case 1200: + baud = B1200; + break; #endif #ifdef B1800 - case 1800: baud = B1800; break; + case 1800: + baud = B1800; + break; #endif #ifdef B2400 - case 2400: baud = B2400; break; + case 2400: + baud = B2400; + break; #endif #ifdef B4800 - case 4800: baud = B4800; break; + case 4800: + baud = B4800; + break; #endif #ifdef B7200 - case 7200: baud = B7200; break; + case 7200: + baud = B7200; + break; #endif #ifdef B9600 - case 9600: baud = B9600; break; + case 9600: + baud = B9600; + break; #endif #ifdef B14400 - case 14400: baud = B14400; break; + case 14400: + baud = B14400; + break; #endif #ifdef B19200 - case 19200: baud = B19200; break; + case 19200: + baud = B19200; + break; #endif #ifdef B28800 - case 28800: baud = B28800; break; + case 28800: + baud = B28800; + break; #endif #ifdef B57600 - case 57600: baud = B57600; break; + case 57600: + baud = B57600; + break; #endif #ifdef B76800 - case 76800: baud = B76800; break; + case 76800: + baud = B76800; + break; #endif #ifdef B38400 - case 38400: baud = B38400; break; + case 38400: + baud = B38400; + break; #endif #ifdef B115200 - case 115200: baud = B115200; break; + case 115200: + baud = B115200; + break; #endif #ifdef B128000 - case 128000: baud = B128000; break; + case 128000: + baud = B128000; + break; #endif #ifdef B153600 - case 153600: baud = B153600; break; + case 153600: + baud = B153600; + break; #endif #ifdef B230400 - case 230400: baud = B230400; break; + case 230400: + baud = B230400; + break; #endif #ifdef B256000 - case 256000: baud = B256000; break; + case 256000: + baud = B256000; + break; #endif #ifdef B460800 - case 460800: baud = B460800; break; + case 460800: + baud = B460800; + break; #endif #ifdef B576000 - case 576000: baud = B576000; break; + case 576000: + baud = B576000; + break; #endif #ifdef B921600 - case 921600: baud = B921600; break; + case 921600: + baud = B921600; + break; #endif #ifdef B1000000 - case 1000000: baud = B1000000; break; + case 1000000: + baud = B1000000; + break; #endif #ifdef B1152000 - case 1152000: baud = B1152000; break; + case 1152000: + baud = B1152000; + break; #endif #ifdef B1500000 - case 1500000: baud = B1500000; break; + case 1500000: + baud = B1500000; + break; #endif #ifdef B2000000 - case 2000000: baud = B2000000; break; + case 2000000: + baud = B2000000; + break; #endif #ifdef B2500000 - case 2500000: baud = B2500000; break; + case 2500000: + baud = B2500000; + break; #endif #ifdef B3000000 - case 3000000: baud = B3000000; break; + case 3000000: + baud = B3000000; + break; #endif #ifdef B3500000 - case 3500000: baud = B3500000; break; + case 3500000: + baud = B3500000; + break; #endif #ifdef B4000000 - case 4000000: baud = B4000000; break; + case 4000000: + baud = B4000000; + break; #endif - default: - custom_baud = true; - // OS X support + default: + custom_baud = true; + // OS X support #if defined(MAC_OS_X_VERSION_10_4) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_4) - // Starting with Tiger, the IOSSIOSPEED ioctl can be used to set arbitrary baud rates - // other than those specified by POSIX. The driver for the underlying serial hardware - // ultimately determines which baud rates can be used. This ioctl sets both the input - // and output speed. - speed_t new_baud = static_cast (baudrate_); - if (-1 == ioctl (fd_, IOSSIOSPEED, &new_baud, 1)) { - THROW (IOException, errno); - } - // Linux Support -#elif defined(__linux__) && defined (TIOCSSERIAL) - struct serial_struct ser; + // Starting with Tiger, the IOSSIOSPEED ioctl can be used to set arbitrary baud rates + // other than those specified by POSIX. The driver for the underlying serial hardware + // ultimately determines which baud rates can be used. This ioctl sets both the input + // and output speed. + speed_t new_baud = static_cast(baudrate_); + if (-1 == ioctl(fd_, IOSSIOSPEED, &new_baud, 1)) + { + THROW(IOException, errno); + } + // Linux Support +#elif defined(__linux__) && defined(TIOCSSERIAL) + struct serial_struct ser; - if (-1 == ioctl (fd_, TIOCGSERIAL, &ser)) { - THROW (IOException, errno); - } + if (-1 == ioctl(fd_, TIOCGSERIAL, &ser)) + { + THROW(IOException, errno); + } - // set custom divisor - ser.custom_divisor = ser.baud_base / static_cast (baudrate_); - // update flags - ser.flags &= ~ASYNC_SPD_MASK; - ser.flags |= ASYNC_SPD_CUST; + // set custom divisor + ser.custom_divisor = ser.baud_base / static_cast(baudrate_); + // update flags + ser.flags &= ~ASYNC_SPD_MASK; + ser.flags |= ASYNC_SPD_CUST; - if (-1 == ioctl (fd_, TIOCSSERIAL, &ser)) { - THROW (IOException, errno); - } + if (-1 == ioctl(fd_, TIOCSSERIAL, &ser)) + { + THROW(IOException, errno); + } #else - throw invalid_argument ("OS does not currently support custom bauds"); + throw invalid_argument("OS does not currently support custom bauds"); #endif - } - if (custom_baud == false) { + } + if (custom_baud == false) + { #ifdef _BSD_SOURCE - ::cfsetspeed(&options, baud); + ::cfsetspeed(&options, baud); #else - ::cfsetispeed(&options, baud); - ::cfsetospeed(&options, baud); + ::cfsetispeed(&options, baud); + ::cfsetospeed(&options, baud); #endif - } + } - // setup char len - options.c_cflag &= (tcflag_t) ~CSIZE; - if (bytesize_ == eightbits) - options.c_cflag |= CS8; - else if (bytesize_ == sevenbits) - options.c_cflag |= CS7; - else if (bytesize_ == sixbits) - options.c_cflag |= CS6; - else if (bytesize_ == fivebits) - options.c_cflag |= CS5; - else - throw invalid_argument ("invalid char len"); - // setup stopbits - if (stopbits_ == stopbits_one) - options.c_cflag &= (tcflag_t) ~(CSTOPB); - else if (stopbits_ == stopbits_one_point_five) - // ONE POINT FIVE same as TWO.. there is no POSIX support for 1.5 - options.c_cflag |= (CSTOPB); - else if (stopbits_ == stopbits_two) - options.c_cflag |= (CSTOPB); - else - throw invalid_argument ("invalid stop bit"); - // setup parity - options.c_iflag &= (tcflag_t) ~(INPCK | ISTRIP); - if (parity_ == parity_none) { - options.c_cflag &= (tcflag_t) ~(PARENB | PARODD); - } else if (parity_ == parity_even) { - options.c_cflag &= (tcflag_t) ~(PARODD); - options.c_cflag |= (PARENB); - } else if (parity_ == parity_odd) { - options.c_cflag |= (PARENB | PARODD); - } + // setup char len + options.c_cflag &= (tcflag_t)~CSIZE; + if (bytesize_ == eightbits) + options.c_cflag |= CS8; + else if (bytesize_ == sevenbits) + options.c_cflag |= CS7; + else if (bytesize_ == sixbits) + options.c_cflag |= CS6; + else if (bytesize_ == fivebits) + options.c_cflag |= CS5; + else + throw invalid_argument("invalid char len"); + // setup stopbits + if (stopbits_ == stopbits_one) + options.c_cflag &= (tcflag_t) ~(CSTOPB); + else if (stopbits_ == stopbits_one_point_five) + // ONE POINT FIVE same as TWO.. there is no POSIX support for 1.5 + options.c_cflag |= (CSTOPB); + else if (stopbits_ == stopbits_two) + options.c_cflag |= (CSTOPB); + else + throw invalid_argument("invalid stop bit"); + // setup parity + options.c_iflag &= (tcflag_t) ~(INPCK | ISTRIP); + if (parity_ == parity_none) + { + options.c_cflag &= (tcflag_t) ~(PARENB | PARODD); + } + else if (parity_ == parity_even) + { + options.c_cflag &= (tcflag_t) ~(PARODD); + options.c_cflag |= (PARENB); + } + else if (parity_ == parity_odd) + { + options.c_cflag |= (PARENB | PARODD); + } #ifdef CMSPAR - else if (parity_ == parity_mark) { - options.c_cflag |= (PARENB | CMSPAR | PARODD); - } - else if (parity_ == parity_space) { - options.c_cflag |= (PARENB | CMSPAR); - options.c_cflag &= (tcflag_t) ~(PARODD); - } + else if (parity_ == parity_mark) + { + options.c_cflag |= (PARENB | CMSPAR | PARODD); + } + else if (parity_ == parity_space) + { + options.c_cflag |= (PARENB | CMSPAR); + options.c_cflag &= (tcflag_t) ~(PARODD); + } #else - // CMSPAR is not defined on OSX. So do not support mark or space parity. - else if (parity_ == parity_mark || parity_ == parity_space) { - throw invalid_argument ("OS does not support mark or space parity"); - } + // CMSPAR is not defined on OSX. So do not support mark or space parity. + else if (parity_ == parity_mark || parity_ == parity_space) + { + throw invalid_argument("OS does not support mark or space parity"); + } #endif // ifdef CMSPAR - else { - throw invalid_argument ("invalid parity"); - } - // setup flow control - if (flowcontrol_ == flowcontrol_none) { - xonxoff_ = false; - rtscts_ = false; - } - if (flowcontrol_ == flowcontrol_software) { - xonxoff_ = true; - rtscts_ = false; - } - if (flowcontrol_ == flowcontrol_hardware) { - xonxoff_ = false; - rtscts_ = true; - } - // xonxoff + else + { + throw invalid_argument("invalid parity"); + } + // setup flow control + if (flowcontrol_ == flowcontrol_none) + { + xonxoff_ = false; + rtscts_ = false; + } + if (flowcontrol_ == flowcontrol_software) + { + xonxoff_ = true; + rtscts_ = false; + } + if (flowcontrol_ == flowcontrol_hardware) + { + xonxoff_ = false; + rtscts_ = true; + } + // xonxoff #ifdef IXANY - if (xonxoff_) - options.c_iflag |= (IXON | IXOFF); //|IXANY) - else - options.c_iflag &= (tcflag_t) ~(IXON | IXOFF | IXANY); + if (xonxoff_) + options.c_iflag |= (IXON | IXOFF); //|IXANY) + else + options.c_iflag &= (tcflag_t) ~(IXON | IXOFF | IXANY); #else - if (xonxoff_) - options.c_iflag |= (IXON | IXOFF); - else - options.c_iflag &= (tcflag_t) ~(IXON | IXOFF); + if (xonxoff_) + options.c_iflag |= (IXON | IXOFF); + else + options.c_iflag &= (tcflag_t) ~(IXON | IXOFF); #endif - // rtscts + // rtscts #ifdef CRTSCTS - if (rtscts_) - options.c_cflag |= (CRTSCTS); - else - options.c_cflag &= (unsigned long) ~(CRTSCTS); + if (rtscts_) + options.c_cflag |= (CRTSCTS); + else + options.c_cflag &= (unsigned long)~(CRTSCTS); #elif defined CNEW_RTSCTS - if (rtscts_) - options.c_cflag |= (CNEW_RTSCTS); - else - options.c_cflag &= (unsigned long) ~(CNEW_RTSCTS); + if (rtscts_) + options.c_cflag |= (CNEW_RTSCTS); + else + options.c_cflag &= (unsigned long)~(CNEW_RTSCTS); #else #error "OS Support seems wrong." #endif - // http://www.unixwiz.net/techtips/termios-vmin-vtime.html - // this basically sets the read call up to be a polling read, - // but we are using select to ensure there is data available - // to read before each call, so we should never needlessly poll - options.c_cc[VMIN] = 0; - options.c_cc[VTIME] = 0; + // http://www.unixwiz.net/techtips/termios-vmin-vtime.html + // this basically sets the read call up to be a polling read, + // but we are using select to ensure there is data available + // to read before each call, so we should never needlessly poll + options.c_cc[VMIN] = 0; + options.c_cc[VTIME] = 0; - // activate settings - ::tcsetattr (fd_, TCSANOW, &options); + // activate settings + ::tcsetattr(fd_, TCSANOW, &options); - // Update byte_time_ based on the new settings. - uint32_t bit_time_ns = 1e9 / baudrate_; - byte_time_ns_ = bit_time_ns * (1 + bytesize_ + parity_ + stopbits_); + // Update byte_time_ based on the new settings. + uint32_t bit_time_ns = 1e9 / baudrate_; + byte_time_ns_ = bit_time_ns * (1 + bytesize_ + parity_ + stopbits_); - // Compensate for the stopbits_one_point_five enum being equal to int 3, - // and not 1.5. - if (stopbits_ == stopbits_one_point_five) { - byte_time_ns_ += ((1.5 - stopbits_one_point_five) * bit_time_ns); - } + // Compensate for the stopbits_one_point_five enum being equal to int 3, + // and not 1.5. + if (stopbits_ == stopbits_one_point_five) + { + byte_time_ns_ += ((1.5 - stopbits_one_point_five) * bit_time_ns); + } } -void -Serial::SerialImpl::close () +void Serial::SerialImpl::close() { - if (is_open_ == true) { - if (fd_ != -1) { - int ret; - ret = ::close (fd_); - if (ret == 0) { - fd_ = -1; - } else { - THROW (IOException, errno); - } - } - is_open_ = false; - } + if (is_open_ == true) + { + if (fd_ != -1) + { + int ret; + ret = ::close(fd_); + if (ret == 0) + { + fd_ = -1; + } + else + { + THROW(IOException, errno); + } + } + is_open_ = false; + } } -bool -Serial::SerialImpl::isOpen () const +bool Serial::SerialImpl::isOpen() const { - return is_open_; + return is_open_; } size_t -Serial::SerialImpl::available () +Serial::SerialImpl::available() { - if (!is_open_) { - return 0; - } - int count = 0; - if (-1 == ioctl (fd_, TIOCINQ, &count)) { - THROW (IOException, errno); - } else { - return static_cast (count); - } + if (!is_open_) + { + return 0; + } + int count = 0; + if (-1 == ioctl(fd_, TIOCINQ, &count)) + { + THROW(IOException, errno); + } + else + { + return static_cast(count); + } } -bool -Serial::SerialImpl::waitReadable (uint32_t timeout) +bool Serial::SerialImpl::waitReadable(uint32_t timeout) { - // Setup a select call to block for serial data or a timeout - fd_set readfds; - FD_ZERO (&readfds); - FD_SET (fd_, &readfds); - timespec timeout_ts (timespec_from_ms (timeout)); - int r = pselect (fd_ + 1, &readfds, NULL, NULL, &timeout_ts, NULL); + // Setup a select call to block for serial data or a timeout + fd_set readfds; + FD_ZERO(&readfds); + FD_SET(fd_, &readfds); + timespec timeout_ts(timespec_from_ms(timeout)); + int r = pselect(fd_ + 1, &readfds, NULL, NULL, &timeout_ts, NULL); - if (r < 0) { - // Select was interrupted - if (errno == EINTR) { - return false; - } - // Otherwise there was some error - THROW (IOException, errno); - } - // Timeout occurred - if (r == 0) { - return false; - } - // This shouldn't happen, if r > 0 our fd has to be in the list! - if (!FD_ISSET (fd_, &readfds)) { - THROW (IOException, "select reports ready to read, but our fd isn't" - " in the list, this shouldn't happen!"); - } - // Data available to read. - return true; + if (r < 0) + { + // Select was interrupted + if (errno == EINTR) + { + return false; + } + // Otherwise there was some error + THROW(IOException, errno); + } + // Timeout occurred + if (r == 0) + { + return false; + } + // This shouldn't happen, if r > 0 our fd has to be in the list! + if (!FD_ISSET(fd_, &readfds)) + { + THROW(IOException, + "select reports ready to read, but our fd isn't" + " in the list, this shouldn't happen!"); + } + // Data available to read. + return true; } -void -Serial::SerialImpl::waitByteTimes (size_t count) +void Serial::SerialImpl::waitByteTimes(size_t count) { - timespec wait_time = { 0, static_cast(byte_time_ns_ * count)}; - pselect (0, NULL, NULL, NULL, &wait_time, NULL); + timespec wait_time = {0, static_cast(byte_time_ns_ * count)}; + pselect(0, NULL, NULL, NULL, &wait_time, NULL); } size_t -Serial::SerialImpl::read (uint8_t *buf, size_t size) +Serial::SerialImpl::read(uint8_t *buf, size_t size) { - // If the port is not open, throw - if (!is_open_) { - throw PortNotOpenedException ("Serial::read"); - } - size_t bytes_read = 0; + // If the port is not open, throw + if (!is_open_) + { + throw PortNotOpenedException("Serial::read"); + } + size_t bytes_read = 0; - // Calculate total timeout in milliseconds t_c + (t_m * N) - long total_timeout_ms = timeout_.read_timeout_constant; - total_timeout_ms += timeout_.read_timeout_multiplier * static_cast (size); - MillisecondTimer total_timeout(total_timeout_ms); + // Calculate total timeout in milliseconds t_c + (t_m * N) + long total_timeout_ms = timeout_.read_timeout_constant; + total_timeout_ms += timeout_.read_timeout_multiplier * static_cast(size); + MillisecondTimer total_timeout(total_timeout_ms); - // Pre-fill buffer with available bytes - { - ssize_t bytes_read_now = ::read (fd_, buf, size); - if (bytes_read_now > 0) { - bytes_read = bytes_read_now; - } - } + // Pre-fill buffer with available bytes + { + ssize_t bytes_read_now = ::read(fd_, buf, size); + if (bytes_read_now > 0) + { + bytes_read = bytes_read_now; + } + } - while (bytes_read < size) { - int64_t timeout_remaining_ms = total_timeout.remaining(); - if (timeout_remaining_ms <= 0) { - // Timed out - break; - } - // Timeout for the next select is whichever is less of the remaining - // total read timeout and the inter-byte timeout. - uint32_t timeout = std::min(static_cast (timeout_remaining_ms), - timeout_.inter_byte_timeout); - // Wait for the device to be readable, and then attempt to read. - if (waitReadable(timeout)) { - // If it's a fixed-length multi-byte read, insert a wait here so that - // we can attempt to grab the whole thing in a single IO call. Skip - // this wait if a non-max inter_byte_timeout is specified. - if (size > 1 && timeout_.inter_byte_timeout == Timeout::max()) { - size_t bytes_available = available(); - if (bytes_available + bytes_read < size) { - waitByteTimes(size - (bytes_available + bytes_read)); - } - } - // This should be non-blocking returning only what is available now - // Then returning so that select can block again. - ssize_t bytes_read_now = - ::read (fd_, buf + bytes_read, size - bytes_read); - // read should always return some data as select reported it was - // ready to read when we get to this point. - if (bytes_read_now < 1) { - // Disconnected devices, at least on Linux, show the - // behavior that they are always ready to read immediately - // but reading returns nothing. - throw SerialException ("device reports readiness to read but " - "returned no data (device disconnected?)"); - } - // Update bytes_read - bytes_read += static_cast (bytes_read_now); - // If bytes_read == size then we have read everything we need - if (bytes_read == size) { - break; - } - // If bytes_read < size then we have more to read - if (bytes_read < size) { - continue; - } - // If bytes_read > size then we have over read, which shouldn't happen - if (bytes_read > size) { - throw SerialException ("read over read, too many bytes where " - "read, this shouldn't happen, might be " - "a logical error!"); - } - } - } - return bytes_read; + while (bytes_read < size) + { + int64_t timeout_remaining_ms = total_timeout.remaining(); + if (timeout_remaining_ms <= 0) + { + // Timed out + break; + } + // Timeout for the next select is whichever is less of the remaining + // total read timeout and the inter-byte timeout. + uint32_t timeout = std::min(static_cast(timeout_remaining_ms), + timeout_.inter_byte_timeout); + // Wait for the device to be readable, and then attempt to read. + if (waitReadable(timeout)) + { + // If it's a fixed-length multi-byte read, insert a wait here so that + // we can attempt to grab the whole thing in a single IO call. Skip + // this wait if a non-max inter_byte_timeout is specified. + if (size > 1 && timeout_.inter_byte_timeout == Timeout::max()) + { + size_t bytes_available = available(); + if (bytes_available + bytes_read < size) + { + waitByteTimes(size - (bytes_available + bytes_read)); + } + } + // This should be non-blocking returning only what is available now + // Then returning so that select can block again. + ssize_t bytes_read_now = + ::read(fd_, buf + bytes_read, size - bytes_read); + // read should always return some data as select reported it was + // ready to read when we get to this point. + if (bytes_read_now < 1) + { + // Disconnected devices, at least on Linux, show the + // behavior that they are always ready to read immediately + // but reading returns nothing. + throw SerialException( + "device reports readiness to read but " + "returned no data (device disconnected?)"); + } + // Update bytes_read + bytes_read += static_cast(bytes_read_now); + // If bytes_read == size then we have read everything we need + if (bytes_read == size) + { + break; + } + // If bytes_read < size then we have more to read + if (bytes_read < size) + { + continue; + } + // If bytes_read > size then we have over read, which shouldn't happen + if (bytes_read > size) + { + throw SerialException( + "read over read, too many bytes where " + "read, this shouldn't happen, might be " + "a logical error!"); + } + } + } + return bytes_read; } size_t -Serial::SerialImpl::write (const uint8_t *data, size_t length) +Serial::SerialImpl::write(const uint8_t *data, size_t length) { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::write"); - } - fd_set writefds; - size_t bytes_written = 0; + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::write"); + } + fd_set writefds; + size_t bytes_written = 0; - // Calculate total timeout in milliseconds t_c + (t_m * N) - long total_timeout_ms = timeout_.write_timeout_constant; - total_timeout_ms += timeout_.write_timeout_multiplier * static_cast (length); - MillisecondTimer total_timeout(total_timeout_ms); + // Calculate total timeout in milliseconds t_c + (t_m * N) + long total_timeout_ms = timeout_.write_timeout_constant; + total_timeout_ms += timeout_.write_timeout_multiplier * static_cast(length); + MillisecondTimer total_timeout(total_timeout_ms); - bool first_iteration = true; - while (bytes_written < length) { - int64_t timeout_remaining_ms = total_timeout.remaining(); - // Only consider the timeout if it's not the first iteration of the loop - // otherwise a timeout of 0 won't be allowed through - if (!first_iteration && (timeout_remaining_ms <= 0)) { - // Timed out - break; - } - first_iteration = false; + bool first_iteration = true; + while (bytes_written < length) + { + int64_t timeout_remaining_ms = total_timeout.remaining(); + // Only consider the timeout if it's not the first iteration of the loop + // otherwise a timeout of 0 won't be allowed through + if (!first_iteration && (timeout_remaining_ms <= 0)) + { + // Timed out + break; + } + first_iteration = false; - timespec timeout(timespec_from_ms(timeout_remaining_ms)); + timespec timeout(timespec_from_ms(timeout_remaining_ms)); - FD_ZERO (&writefds); - FD_SET (fd_, &writefds); + FD_ZERO(&writefds); + FD_SET(fd_, &writefds); - // Do the select - int r = pselect (fd_ + 1, NULL, &writefds, NULL, &timeout, NULL); + // Do the select + int r = pselect(fd_ + 1, NULL, &writefds, NULL, &timeout, NULL); - // Figure out what happened by looking at select's response 'r' - /** Error **/ - if (r < 0) { - // Select was interrupted, try again - if (errno == EINTR) { - continue; - } - // Otherwise there was some error - THROW (IOException, errno); - } - /** Timeout **/ - if (r == 0) { - break; - } - /** Port ready to write **/ - if (r > 0) { - // Make sure our file descriptor is in the ready to write list - if (FD_ISSET (fd_, &writefds)) { - // This will write some - ssize_t bytes_written_now = - ::write (fd_, data + bytes_written, length - bytes_written); - // write should always return some data as select reported it was - // ready to write when we get to this point. - if (bytes_written_now < 1) { - // Disconnected devices, at least on Linux, show the - // behavior that they are always ready to write immediately - // but writing returns nothing. - throw SerialException ("device reports readiness to write but " - "returned no data (device disconnected?)"); - } - // Update bytes_written - bytes_written += static_cast (bytes_written_now); - // If bytes_written == size then we have written everything we need to - if (bytes_written == length) { - break; - } - // If bytes_written < size then we have more to write - if (bytes_written < length) { - continue; - } - // If bytes_written > size then we have over written, which shouldn't happen - if (bytes_written > length) { - throw SerialException ("write over wrote, too many bytes where " - "written, this shouldn't happen, might be " - "a logical error!"); - } - } - // This shouldn't happen, if r > 0 our fd has to be in the list! - THROW (IOException, "select reports ready to write, but our fd isn't" - " in the list, this shouldn't happen!"); - } - } - return bytes_written; + // Figure out what happened by looking at select's response 'r' + /** Error **/ + if (r < 0) + { + // Select was interrupted, try again + if (errno == EINTR) + { + continue; + } + // Otherwise there was some error + THROW(IOException, errno); + } + /** Timeout **/ + if (r == 0) + { + break; + } + /** Port ready to write **/ + if (r > 0) + { + // Make sure our file descriptor is in the ready to write list + if (FD_ISSET(fd_, &writefds)) + { + // This will write some + ssize_t bytes_written_now = + ::write(fd_, data + bytes_written, length - bytes_written); + // write should always return some data as select reported it was + // ready to write when we get to this point. + if (bytes_written_now < 1) + { + // Disconnected devices, at least on Linux, show the + // behavior that they are always ready to write immediately + // but writing returns nothing. + throw SerialException( + "device reports readiness to write but " + "returned no data (device disconnected?)"); + } + // Update bytes_written + bytes_written += static_cast(bytes_written_now); + // If bytes_written == size then we have written everything we need to + if (bytes_written == length) + { + break; + } + // If bytes_written < size then we have more to write + if (bytes_written < length) + { + continue; + } + // If bytes_written > size then we have over written, which shouldn't happen + if (bytes_written > length) + { + throw SerialException( + "write over wrote, too many bytes where " + "written, this shouldn't happen, might be " + "a logical error!"); + } + } + // This shouldn't happen, if r > 0 our fd has to be in the list! + THROW(IOException, + "select reports ready to write, but our fd isn't" + " in the list, this shouldn't happen!"); + } + } + return bytes_written; } -void -Serial::SerialImpl::setPort (const string &port) +void Serial::SerialImpl::setPort(const string &port) { - port_ = port; + port_ = port; } string -Serial::SerialImpl::getPort () const +Serial::SerialImpl::getPort() const { - return port_; + return port_; } -void -Serial::SerialImpl::setTimeout (serial::Timeout &timeout) +void Serial::SerialImpl::setTimeout(serial::Timeout &timeout) { - timeout_ = timeout; + timeout_ = timeout; } serial::Timeout -Serial::SerialImpl::getTimeout () const +Serial::SerialImpl::getTimeout() const { - return timeout_; + return timeout_; } -void -Serial::SerialImpl::setBaudrate (unsigned long baudrate) +void Serial::SerialImpl::setBaudrate(unsigned long baudrate) { - baudrate_ = baudrate; - if (is_open_) - reconfigurePort (); + baudrate_ = baudrate; + if (is_open_) + reconfigurePort(); } unsigned long -Serial::SerialImpl::getBaudrate () const +Serial::SerialImpl::getBaudrate() const { - return baudrate_; + return baudrate_; } -void -Serial::SerialImpl::setBytesize (serial::bytesize_t bytesize) +void Serial::SerialImpl::setBytesize(serial::bytesize_t bytesize) { - bytesize_ = bytesize; - if (is_open_) - reconfigurePort (); + bytesize_ = bytesize; + if (is_open_) + reconfigurePort(); } serial::bytesize_t -Serial::SerialImpl::getBytesize () const +Serial::SerialImpl::getBytesize() const { - return bytesize_; + return bytesize_; } -void -Serial::SerialImpl::setParity (serial::parity_t parity) +void Serial::SerialImpl::setParity(serial::parity_t parity) { - parity_ = parity; - if (is_open_) - reconfigurePort (); + parity_ = parity; + if (is_open_) + reconfigurePort(); } serial::parity_t -Serial::SerialImpl::getParity () const +Serial::SerialImpl::getParity() const { - return parity_; + return parity_; } -void -Serial::SerialImpl::setStopbits (serial::stopbits_t stopbits) +void Serial::SerialImpl::setStopbits(serial::stopbits_t stopbits) { - stopbits_ = stopbits; - if (is_open_) - reconfigurePort (); + stopbits_ = stopbits; + if (is_open_) + reconfigurePort(); } serial::stopbits_t -Serial::SerialImpl::getStopbits () const +Serial::SerialImpl::getStopbits() const { - return stopbits_; + return stopbits_; } -void -Serial::SerialImpl::setFlowcontrol (serial::flowcontrol_t flowcontrol) +void Serial::SerialImpl::setFlowcontrol(serial::flowcontrol_t flowcontrol) { - flowcontrol_ = flowcontrol; - if (is_open_) - reconfigurePort (); + flowcontrol_ = flowcontrol; + if (is_open_) + reconfigurePort(); } serial::flowcontrol_t -Serial::SerialImpl::getFlowcontrol () const +Serial::SerialImpl::getFlowcontrol() const { - return flowcontrol_; + return flowcontrol_; } -void -Serial::SerialImpl::flush () +void Serial::SerialImpl::flush() { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::flush"); - } - tcdrain (fd_); + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::flush"); + } + tcdrain(fd_); } -void -Serial::SerialImpl::flushInput () +void Serial::SerialImpl::flushInput() { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::flushInput"); - } - tcflush (fd_, TCIFLUSH); + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::flushInput"); + } + tcflush(fd_, TCIFLUSH); } -void -Serial::SerialImpl::flushOutput () +void Serial::SerialImpl::flushOutput() { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::flushOutput"); - } - tcflush (fd_, TCOFLUSH); + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::flushOutput"); + } + tcflush(fd_, TCOFLUSH); } -void -Serial::SerialImpl::sendBreak (int duration) +void Serial::SerialImpl::sendBreak(int duration) { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::sendBreak"); - } - tcsendbreak (fd_, static_cast (duration / 4)); + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::sendBreak"); + } + tcsendbreak(fd_, static_cast(duration / 4)); } -void -Serial::SerialImpl::setBreak (bool level) +void Serial::SerialImpl::setBreak(bool level) { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::setBreak"); - } + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::setBreak"); + } - if (level) { - if (-1 == ioctl (fd_, TIOCSBRK)) - { - stringstream ss; - ss << "setBreak failed on a call to ioctl(TIOCSBRK): " << errno << " " << strerror(errno); - throw(SerialException(ss.str().c_str())); - } - } else { - if (-1 == ioctl (fd_, TIOCCBRK)) - { - stringstream ss; - ss << "setBreak failed on a call to ioctl(TIOCCBRK): " << errno << " " << strerror(errno); - throw(SerialException(ss.str().c_str())); - } - } + if (level) + { + if (-1 == ioctl(fd_, TIOCSBRK)) + { + stringstream ss; + ss << "setBreak failed on a call to ioctl(TIOCSBRK): " << errno << " " << strerror(errno); + throw(SerialException(ss.str().c_str())); + } + } + else + { + if (-1 == ioctl(fd_, TIOCCBRK)) + { + stringstream ss; + ss << "setBreak failed on a call to ioctl(TIOCCBRK): " << errno << " " << strerror(errno); + throw(SerialException(ss.str().c_str())); + } + } } -void -Serial::SerialImpl::setRTS (bool level) +void Serial::SerialImpl::setRTS(bool level) { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::setRTS"); - } + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::setRTS"); + } - int command = TIOCM_RTS; + int command = TIOCM_RTS; - if (level) { - if (-1 == ioctl (fd_, TIOCMBIS, &command)) - { - stringstream ss; - ss << "setRTS failed on a call to ioctl(TIOCMBIS): " << errno << " " << strerror(errno); - throw(SerialException(ss.str().c_str())); - } - } else { - if (-1 == ioctl (fd_, TIOCMBIC, &command)) - { - stringstream ss; - ss << "setRTS failed on a call to ioctl(TIOCMBIC): " << errno << " " << strerror(errno); - throw(SerialException(ss.str().c_str())); - } - } + if (level) + { + if (-1 == ioctl(fd_, TIOCMBIS, &command)) + { + stringstream ss; + ss << "setRTS failed on a call to ioctl(TIOCMBIS): " << errno << " " << strerror(errno); + throw(SerialException(ss.str().c_str())); + } + } + else + { + if (-1 == ioctl(fd_, TIOCMBIC, &command)) + { + stringstream ss; + ss << "setRTS failed on a call to ioctl(TIOCMBIC): " << errno << " " << strerror(errno); + throw(SerialException(ss.str().c_str())); + } + } } -void -Serial::SerialImpl::setDTR (bool level) +void Serial::SerialImpl::setDTR(bool level) { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::setDTR"); - } + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::setDTR"); + } - int command = TIOCM_DTR; + int command = TIOCM_DTR; - if (level) { - if (-1 == ioctl (fd_, TIOCMBIS, &command)) - { - stringstream ss; - ss << "setDTR failed on a call to ioctl(TIOCMBIS): " << errno << " " << strerror(errno); - throw(SerialException(ss.str().c_str())); - } - } else { - if (-1 == ioctl (fd_, TIOCMBIC, &command)) - { - stringstream ss; - ss << "setDTR failed on a call to ioctl(TIOCMBIC): " << errno << " " << strerror(errno); - throw(SerialException(ss.str().c_str())); - } - } + if (level) + { + if (-1 == ioctl(fd_, TIOCMBIS, &command)) + { + stringstream ss; + ss << "setDTR failed on a call to ioctl(TIOCMBIS): " << errno << " " << strerror(errno); + throw(SerialException(ss.str().c_str())); + } + } + else + { + if (-1 == ioctl(fd_, TIOCMBIC, &command)) + { + stringstream ss; + ss << "setDTR failed on a call to ioctl(TIOCMBIC): " << errno << " " << strerror(errno); + throw(SerialException(ss.str().c_str())); + } + } } -bool -Serial::SerialImpl::waitForChange () +bool Serial::SerialImpl::waitForChange() { #ifndef TIOCMIWAIT -while (is_open_ == true) { + while (is_open_ == true) + { + int status; - int status; + if (-1 == ioctl(fd_, TIOCMGET, &status)) + { + stringstream ss; + ss << "waitForChange failed on a call to ioctl(TIOCMGET): " << errno << " " << strerror(errno); + throw(SerialException(ss.str().c_str())); + } + else + { + if (0 != (status & TIOCM_CTS) || 0 != (status & TIOCM_DSR) || 0 != (status & TIOCM_RI) || 0 != (status & TIOCM_CD)) + { + return true; + } + } - if (-1 == ioctl (fd_, TIOCMGET, &status)) - { - stringstream ss; - ss << "waitForChange failed on a call to ioctl(TIOCMGET): " << errno << " " << strerror(errno); - throw(SerialException(ss.str().c_str())); - } - else - { - if (0 != (status & TIOCM_CTS) - || 0 != (status & TIOCM_DSR) - || 0 != (status & TIOCM_RI) - || 0 != (status & TIOCM_CD)) - { - return true; - } - } + usleep(1000); + } - usleep(1000); - } - - return false; + return false; #else - int command = (TIOCM_CD|TIOCM_DSR|TIOCM_RI|TIOCM_CTS); + int command = (TIOCM_CD | TIOCM_DSR | TIOCM_RI | TIOCM_CTS); - if (-1 == ioctl (fd_, TIOCMIWAIT, &command)) { - stringstream ss; - ss << "waitForDSR failed on a call to ioctl(TIOCMIWAIT): " - << errno << " " << strerror(errno); - throw(SerialException(ss.str().c_str())); - } - return true; + if (-1 == ioctl(fd_, TIOCMIWAIT, &command)) + { + stringstream ss; + ss << "waitForDSR failed on a call to ioctl(TIOCMIWAIT): " + << errno << " " << strerror(errno); + throw(SerialException(ss.str().c_str())); + } + return true; #endif } -bool -Serial::SerialImpl::getCTS () +bool Serial::SerialImpl::getCTS() { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::getCTS"); - } + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::getCTS"); + } - int status; + int status; - if (-1 == ioctl (fd_, TIOCMGET, &status)) - { - stringstream ss; - ss << "getCTS failed on a call to ioctl(TIOCMGET): " << errno << " " << strerror(errno); - throw(SerialException(ss.str().c_str())); - } - else - { - return 0 != (status & TIOCM_CTS); - } + if (-1 == ioctl(fd_, TIOCMGET, &status)) + { + stringstream ss; + ss << "getCTS failed on a call to ioctl(TIOCMGET): " << errno << " " << strerror(errno); + throw(SerialException(ss.str().c_str())); + } + else + { + return 0 != (status & TIOCM_CTS); + } } -bool -Serial::SerialImpl::getDSR () +bool Serial::SerialImpl::getDSR() { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::getDSR"); - } + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::getDSR"); + } - int status; + int status; - if (-1 == ioctl (fd_, TIOCMGET, &status)) - { - stringstream ss; - ss << "getDSR failed on a call to ioctl(TIOCMGET): " << errno << " " << strerror(errno); - throw(SerialException(ss.str().c_str())); - } - else - { - return 0 != (status & TIOCM_DSR); - } + if (-1 == ioctl(fd_, TIOCMGET, &status)) + { + stringstream ss; + ss << "getDSR failed on a call to ioctl(TIOCMGET): " << errno << " " << strerror(errno); + throw(SerialException(ss.str().c_str())); + } + else + { + return 0 != (status & TIOCM_DSR); + } } -bool -Serial::SerialImpl::getRI () +bool Serial::SerialImpl::getRI() { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::getRI"); - } + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::getRI"); + } - int status; + int status; - if (-1 == ioctl (fd_, TIOCMGET, &status)) - { - stringstream ss; - ss << "getRI failed on a call to ioctl(TIOCMGET): " << errno << " " << strerror(errno); - throw(SerialException(ss.str().c_str())); - } - else - { - return 0 != (status & TIOCM_RI); - } + if (-1 == ioctl(fd_, TIOCMGET, &status)) + { + stringstream ss; + ss << "getRI failed on a call to ioctl(TIOCMGET): " << errno << " " << strerror(errno); + throw(SerialException(ss.str().c_str())); + } + else + { + return 0 != (status & TIOCM_RI); + } } -bool -Serial::SerialImpl::getCD () +bool Serial::SerialImpl::getCD() { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::getCD"); - } + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::getCD"); + } - int status; + int status; - if (-1 == ioctl (fd_, TIOCMGET, &status)) - { - stringstream ss; - ss << "getCD failed on a call to ioctl(TIOCMGET): " << errno << " " << strerror(errno); - throw(SerialException(ss.str().c_str())); - } - else - { - return 0 != (status & TIOCM_CD); - } + if (-1 == ioctl(fd_, TIOCMGET, &status)) + { + stringstream ss; + ss << "getCD failed on a call to ioctl(TIOCMGET): " << errno << " " << strerror(errno); + throw(SerialException(ss.str().c_str())); + } + else + { + return 0 != (status & TIOCM_CD); + } } -void -Serial::SerialImpl::readLock () +void Serial::SerialImpl::readLock() { - int result = pthread_mutex_lock(&this->read_mutex); - if (result) { - THROW (IOException, result); - } + int result = pthread_mutex_lock(&this->read_mutex); + if (result) + { + THROW(IOException, result); + } } -void -Serial::SerialImpl::readUnlock () +void Serial::SerialImpl::readUnlock() { - int result = pthread_mutex_unlock(&this->read_mutex); - if (result) { - THROW (IOException, result); - } + int result = pthread_mutex_unlock(&this->read_mutex); + if (result) + { + THROW(IOException, result); + } } -void -Serial::SerialImpl::writeLock () +void Serial::SerialImpl::writeLock() { - int result = pthread_mutex_lock(&this->write_mutex); - if (result) { - THROW (IOException, result); - } + int result = pthread_mutex_lock(&this->write_mutex); + if (result) + { + THROW(IOException, result); + } } -void -Serial::SerialImpl::writeUnlock () +void Serial::SerialImpl::writeUnlock() { - int result = pthread_mutex_unlock(&this->write_mutex); - if (result) { - THROW (IOException, result); - } + int result = pthread_mutex_unlock(&this->write_mutex); + if (result) + { + THROW(IOException, result); + } } -#endif // !defined(_WIN32) +#endif // !defined(_WIN32) diff --git a/examples/ThirdPartyLibs/serial/src/impl/win.cc b/examples/ThirdPartyLibs/serial/src/impl/win.cc index 3446160fa..5a5b4547f 100644 --- a/examples/ThirdPartyLibs/serial/src/impl/win.cc +++ b/examples/ThirdPartyLibs/serial/src/impl/win.cc @@ -6,635 +6,731 @@ #include "serial/impl/win.h" -using std::string; -using std::wstring; -using std::stringstream; -using std::invalid_argument; -using serial::Serial; -using serial::Timeout; using serial::bytesize_t; -using serial::parity_t; -using serial::stopbits_t; using serial::flowcontrol_t; -using serial::SerialException; -using serial::PortNotOpenedException; using serial::IOException; +using serial::parity_t; +using serial::PortNotOpenedException; +using serial::Serial; +using serial::SerialException; +using serial::stopbits_t; +using serial::Timeout; +using std::invalid_argument; +using std::string; +using std::stringstream; +using std::wstring; inline wstring _prefix_port_if_needed(const wstring &input) { - static wstring windows_com_port_prefix = L"\\\\.\\"; - if (input.compare(windows_com_port_prefix) != 0) - { - return windows_com_port_prefix + input; - } - return input; + static wstring windows_com_port_prefix = L"\\\\.\\"; + if (input.compare(windows_com_port_prefix) != 0) + { + return windows_com_port_prefix + input; + } + return input; } -Serial::SerialImpl::SerialImpl (const string &port, unsigned long baudrate, - bytesize_t bytesize, - parity_t parity, stopbits_t stopbits, - flowcontrol_t flowcontrol) - : port_ (port.begin(), port.end()), fd_ (INVALID_HANDLE_VALUE), is_open_ (false), - baudrate_ (baudrate), parity_ (parity), - bytesize_ (bytesize), stopbits_ (stopbits), flowcontrol_ (flowcontrol) +Serial::SerialImpl::SerialImpl(const string &port, unsigned long baudrate, + bytesize_t bytesize, + parity_t parity, stopbits_t stopbits, + flowcontrol_t flowcontrol) + : port_(port.begin(), port.end()), fd_(INVALID_HANDLE_VALUE), is_open_(false), baudrate_(baudrate), parity_(parity), bytesize_(bytesize), stopbits_(stopbits), flowcontrol_(flowcontrol) { - if (port_.empty () == false) - open (); - read_mutex = CreateMutex(NULL, false, NULL); - write_mutex = CreateMutex(NULL, false, NULL); + if (port_.empty() == false) + open(); + read_mutex = CreateMutex(NULL, false, NULL); + write_mutex = CreateMutex(NULL, false, NULL); } -Serial::SerialImpl::~SerialImpl () +Serial::SerialImpl::~SerialImpl() { - this->close(); - CloseHandle(read_mutex); - CloseHandle(write_mutex); + this->close(); + CloseHandle(read_mutex); + CloseHandle(write_mutex); } -void -Serial::SerialImpl::open () +void Serial::SerialImpl::open() { - if (port_.empty ()) { - throw invalid_argument ("Empty port is invalid."); - } - if (is_open_ == true) { - throw SerialException ("Serial port already open."); - } + if (port_.empty()) + { + throw invalid_argument("Empty port is invalid."); + } + if (is_open_ == true) + { + throw SerialException("Serial port already open."); + } - // See: https://github.com/wjwwood/serial/issues/84 - wstring port_with_prefix = _prefix_port_if_needed(port_); - LPCWSTR lp_port = port_with_prefix.c_str(); - fd_ = CreateFileW(lp_port, - GENERIC_READ | GENERIC_WRITE, - 0, - 0, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, - 0); + // See: https://github.com/wjwwood/serial/issues/84 + wstring port_with_prefix = _prefix_port_if_needed(port_); + LPCWSTR lp_port = port_with_prefix.c_str(); + fd_ = CreateFileW(lp_port, + GENERIC_READ | GENERIC_WRITE, + 0, + 0, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + 0); - if (fd_ == INVALID_HANDLE_VALUE) { - DWORD errno_ = GetLastError(); - stringstream ss; - switch (errno_) { - case ERROR_FILE_NOT_FOUND: - // Use this->getPort to convert to a std::string - ss << "Specified port, " << this->getPort() << ", does not exist."; - THROW (IOException, ss.str().c_str()); - default: - ss << "Unknown error opening the serial port: " << errno; - THROW (IOException, ss.str().c_str()); - } - } + if (fd_ == INVALID_HANDLE_VALUE) + { + DWORD errno_ = GetLastError(); + stringstream ss; + switch (errno_) + { + case ERROR_FILE_NOT_FOUND: + // Use this->getPort to convert to a std::string + ss << "Specified port, " << this->getPort() << ", does not exist."; + THROW(IOException, ss.str().c_str()); + default: + ss << "Unknown error opening the serial port: " << errno; + THROW(IOException, ss.str().c_str()); + } + } - reconfigurePort(); - is_open_ = true; + reconfigurePort(); + is_open_ = true; } -void -Serial::SerialImpl::reconfigurePort () +void Serial::SerialImpl::reconfigurePort() { - if (fd_ == INVALID_HANDLE_VALUE) { - // Can only operate on a valid file descriptor - THROW (IOException, "Invalid file descriptor, is the serial port open?"); - } + if (fd_ == INVALID_HANDLE_VALUE) + { + // Can only operate on a valid file descriptor + THROW(IOException, "Invalid file descriptor, is the serial port open?"); + } - DCB dcbSerialParams = {0}; + DCB dcbSerialParams = {0}; - dcbSerialParams.DCBlength=sizeof(dcbSerialParams); + dcbSerialParams.DCBlength = sizeof(dcbSerialParams); - if (!GetCommState(fd_, &dcbSerialParams)) { - //error getting state - THROW (IOException, "Error getting the serial port state."); - } + if (!GetCommState(fd_, &dcbSerialParams)) + { + //error getting state + THROW(IOException, "Error getting the serial port state."); + } - // setup baud rate - switch (baudrate_) { + // setup baud rate + switch (baudrate_) + { #ifdef CBR_0 - case 0: dcbSerialParams.BaudRate = CBR_0; break; + case 0: + dcbSerialParams.BaudRate = CBR_0; + break; #endif #ifdef CBR_50 - case 50: dcbSerialParams.BaudRate = CBR_50; break; + case 50: + dcbSerialParams.BaudRate = CBR_50; + break; #endif #ifdef CBR_75 - case 75: dcbSerialParams.BaudRate = CBR_75; break; + case 75: + dcbSerialParams.BaudRate = CBR_75; + break; #endif #ifdef CBR_110 - case 110: dcbSerialParams.BaudRate = CBR_110; break; + case 110: + dcbSerialParams.BaudRate = CBR_110; + break; #endif #ifdef CBR_134 - case 134: dcbSerialParams.BaudRate = CBR_134; break; + case 134: + dcbSerialParams.BaudRate = CBR_134; + break; #endif #ifdef CBR_150 - case 150: dcbSerialParams.BaudRate = CBR_150; break; + case 150: + dcbSerialParams.BaudRate = CBR_150; + break; #endif #ifdef CBR_200 - case 200: dcbSerialParams.BaudRate = CBR_200; break; + case 200: + dcbSerialParams.BaudRate = CBR_200; + break; #endif #ifdef CBR_300 - case 300: dcbSerialParams.BaudRate = CBR_300; break; + case 300: + dcbSerialParams.BaudRate = CBR_300; + break; #endif #ifdef CBR_600 - case 600: dcbSerialParams.BaudRate = CBR_600; break; + case 600: + dcbSerialParams.BaudRate = CBR_600; + break; #endif #ifdef CBR_1200 - case 1200: dcbSerialParams.BaudRate = CBR_1200; break; + case 1200: + dcbSerialParams.BaudRate = CBR_1200; + break; #endif #ifdef CBR_1800 - case 1800: dcbSerialParams.BaudRate = CBR_1800; break; + case 1800: + dcbSerialParams.BaudRate = CBR_1800; + break; #endif #ifdef CBR_2400 - case 2400: dcbSerialParams.BaudRate = CBR_2400; break; + case 2400: + dcbSerialParams.BaudRate = CBR_2400; + break; #endif #ifdef CBR_4800 - case 4800: dcbSerialParams.BaudRate = CBR_4800; break; + case 4800: + dcbSerialParams.BaudRate = CBR_4800; + break; #endif #ifdef CBR_7200 - case 7200: dcbSerialParams.BaudRate = CBR_7200; break; + case 7200: + dcbSerialParams.BaudRate = CBR_7200; + break; #endif #ifdef CBR_9600 - case 9600: dcbSerialParams.BaudRate = CBR_9600; break; + case 9600: + dcbSerialParams.BaudRate = CBR_9600; + break; #endif #ifdef CBR_14400 - case 14400: dcbSerialParams.BaudRate = CBR_14400; break; + case 14400: + dcbSerialParams.BaudRate = CBR_14400; + break; #endif #ifdef CBR_19200 - case 19200: dcbSerialParams.BaudRate = CBR_19200; break; + case 19200: + dcbSerialParams.BaudRate = CBR_19200; + break; #endif #ifdef CBR_28800 - case 28800: dcbSerialParams.BaudRate = CBR_28800; break; + case 28800: + dcbSerialParams.BaudRate = CBR_28800; + break; #endif #ifdef CBR_57600 - case 57600: dcbSerialParams.BaudRate = CBR_57600; break; + case 57600: + dcbSerialParams.BaudRate = CBR_57600; + break; #endif #ifdef CBR_76800 - case 76800: dcbSerialParams.BaudRate = CBR_76800; break; + case 76800: + dcbSerialParams.BaudRate = CBR_76800; + break; #endif #ifdef CBR_38400 - case 38400: dcbSerialParams.BaudRate = CBR_38400; break; + case 38400: + dcbSerialParams.BaudRate = CBR_38400; + break; #endif #ifdef CBR_115200 - case 115200: dcbSerialParams.BaudRate = CBR_115200; break; + case 115200: + dcbSerialParams.BaudRate = CBR_115200; + break; #endif #ifdef CBR_128000 - case 128000: dcbSerialParams.BaudRate = CBR_128000; break; + case 128000: + dcbSerialParams.BaudRate = CBR_128000; + break; #endif #ifdef CBR_153600 - case 153600: dcbSerialParams.BaudRate = CBR_153600; break; + case 153600: + dcbSerialParams.BaudRate = CBR_153600; + break; #endif #ifdef CBR_230400 - case 230400: dcbSerialParams.BaudRate = CBR_230400; break; + case 230400: + dcbSerialParams.BaudRate = CBR_230400; + break; #endif #ifdef CBR_256000 - case 256000: dcbSerialParams.BaudRate = CBR_256000; break; + case 256000: + dcbSerialParams.BaudRate = CBR_256000; + break; #endif #ifdef CBR_460800 - case 460800: dcbSerialParams.BaudRate = CBR_460800; break; + case 460800: + dcbSerialParams.BaudRate = CBR_460800; + break; #endif #ifdef CBR_921600 - case 921600: dcbSerialParams.BaudRate = CBR_921600; break; + case 921600: + dcbSerialParams.BaudRate = CBR_921600; + break; #endif - default: - // Try to blindly assign it - dcbSerialParams.BaudRate = baudrate_; - } + default: + // Try to blindly assign it + dcbSerialParams.BaudRate = baudrate_; + } - // setup char len - if (bytesize_ == eightbits) - dcbSerialParams.ByteSize = 8; - else if (bytesize_ == sevenbits) - dcbSerialParams.ByteSize = 7; - else if (bytesize_ == sixbits) - dcbSerialParams.ByteSize = 6; - else if (bytesize_ == fivebits) - dcbSerialParams.ByteSize = 5; - else - throw invalid_argument ("invalid char len"); + // setup char len + if (bytesize_ == eightbits) + dcbSerialParams.ByteSize = 8; + else if (bytesize_ == sevenbits) + dcbSerialParams.ByteSize = 7; + else if (bytesize_ == sixbits) + dcbSerialParams.ByteSize = 6; + else if (bytesize_ == fivebits) + dcbSerialParams.ByteSize = 5; + else + throw invalid_argument("invalid char len"); - // setup stopbits - if (stopbits_ == stopbits_one) - dcbSerialParams.StopBits = ONESTOPBIT; - else if (stopbits_ == stopbits_one_point_five) - dcbSerialParams.StopBits = ONE5STOPBITS; - else if (stopbits_ == stopbits_two) - dcbSerialParams.StopBits = TWOSTOPBITS; - else - throw invalid_argument ("invalid stop bit"); + // setup stopbits + if (stopbits_ == stopbits_one) + dcbSerialParams.StopBits = ONESTOPBIT; + else if (stopbits_ == stopbits_one_point_five) + dcbSerialParams.StopBits = ONE5STOPBITS; + else if (stopbits_ == stopbits_two) + dcbSerialParams.StopBits = TWOSTOPBITS; + else + throw invalid_argument("invalid stop bit"); - // setup parity - if (parity_ == parity_none) { - dcbSerialParams.Parity = NOPARITY; - } else if (parity_ == parity_even) { - dcbSerialParams.Parity = EVENPARITY; - } else if (parity_ == parity_odd) { - dcbSerialParams.Parity = ODDPARITY; - } else if (parity_ == parity_mark) { - dcbSerialParams.Parity = MARKPARITY; - } else if (parity_ == parity_space) { - dcbSerialParams.Parity = SPACEPARITY; - } else { - throw invalid_argument ("invalid parity"); - } + // setup parity + if (parity_ == parity_none) + { + dcbSerialParams.Parity = NOPARITY; + } + else if (parity_ == parity_even) + { + dcbSerialParams.Parity = EVENPARITY; + } + else if (parity_ == parity_odd) + { + dcbSerialParams.Parity = ODDPARITY; + } + else if (parity_ == parity_mark) + { + dcbSerialParams.Parity = MARKPARITY; + } + else if (parity_ == parity_space) + { + dcbSerialParams.Parity = SPACEPARITY; + } + else + { + throw invalid_argument("invalid parity"); + } - // setup flowcontrol - if (flowcontrol_ == flowcontrol_none) { - dcbSerialParams.fOutxCtsFlow = false; - dcbSerialParams.fRtsControl = 0x00; - dcbSerialParams.fOutX = false; - dcbSerialParams.fInX = false; - } - if (flowcontrol_ == flowcontrol_software) { - dcbSerialParams.fOutxCtsFlow = false; - dcbSerialParams.fRtsControl = 0x00; - dcbSerialParams.fOutX = true; - dcbSerialParams.fInX = true; - } - if (flowcontrol_ == flowcontrol_hardware) { - dcbSerialParams.fOutxCtsFlow = true; - dcbSerialParams.fRtsControl = 0x03; - dcbSerialParams.fOutX = false; - dcbSerialParams.fInX = false; - } + // setup flowcontrol + if (flowcontrol_ == flowcontrol_none) + { + dcbSerialParams.fOutxCtsFlow = false; + dcbSerialParams.fRtsControl = 0x00; + dcbSerialParams.fOutX = false; + dcbSerialParams.fInX = false; + } + if (flowcontrol_ == flowcontrol_software) + { + dcbSerialParams.fOutxCtsFlow = false; + dcbSerialParams.fRtsControl = 0x00; + dcbSerialParams.fOutX = true; + dcbSerialParams.fInX = true; + } + if (flowcontrol_ == flowcontrol_hardware) + { + dcbSerialParams.fOutxCtsFlow = true; + dcbSerialParams.fRtsControl = 0x03; + dcbSerialParams.fOutX = false; + dcbSerialParams.fInX = false; + } - // activate settings - if (!SetCommState(fd_, &dcbSerialParams)){ - CloseHandle(fd_); - THROW (IOException, "Error setting serial port settings."); - } + // activate settings + if (!SetCommState(fd_, &dcbSerialParams)) + { + CloseHandle(fd_); + THROW(IOException, "Error setting serial port settings."); + } - // Setup timeouts - COMMTIMEOUTS timeouts = {0}; - timeouts.ReadIntervalTimeout = timeout_.inter_byte_timeout; - timeouts.ReadTotalTimeoutConstant = timeout_.read_timeout_constant; - timeouts.ReadTotalTimeoutMultiplier = timeout_.read_timeout_multiplier; - timeouts.WriteTotalTimeoutConstant = timeout_.write_timeout_constant; - timeouts.WriteTotalTimeoutMultiplier = timeout_.write_timeout_multiplier; - if (!SetCommTimeouts(fd_, &timeouts)) { - THROW (IOException, "Error setting timeouts."); - } + // Setup timeouts + COMMTIMEOUTS timeouts = {0}; + timeouts.ReadIntervalTimeout = timeout_.inter_byte_timeout; + timeouts.ReadTotalTimeoutConstant = timeout_.read_timeout_constant; + timeouts.ReadTotalTimeoutMultiplier = timeout_.read_timeout_multiplier; + timeouts.WriteTotalTimeoutConstant = timeout_.write_timeout_constant; + timeouts.WriteTotalTimeoutMultiplier = timeout_.write_timeout_multiplier; + if (!SetCommTimeouts(fd_, &timeouts)) + { + THROW(IOException, "Error setting timeouts."); + } } -void -Serial::SerialImpl::close () +void Serial::SerialImpl::close() { - if (is_open_ == true) { - if (fd_ != INVALID_HANDLE_VALUE) { - int ret; - ret = CloseHandle(fd_); - if (ret == 0) { - stringstream ss; - ss << "Error while closing serial port: " << GetLastError(); - THROW (IOException, ss.str().c_str()); - } else { - fd_ = INVALID_HANDLE_VALUE; - } - } - is_open_ = false; - } + if (is_open_ == true) + { + if (fd_ != INVALID_HANDLE_VALUE) + { + int ret; + ret = CloseHandle(fd_); + if (ret == 0) + { + stringstream ss; + ss << "Error while closing serial port: " << GetLastError(); + THROW(IOException, ss.str().c_str()); + } + else + { + fd_ = INVALID_HANDLE_VALUE; + } + } + is_open_ = false; + } +} + +bool Serial::SerialImpl::isOpen() const +{ + return is_open_; +} + +size_t +Serial::SerialImpl::available() +{ + if (!is_open_) + { + return 0; + } + COMSTAT cs; + if (!ClearCommError(fd_, NULL, &cs)) + { + stringstream ss; + ss << "Error while checking status of the serial port: " << GetLastError(); + THROW(IOException, ss.str().c_str()); + } + return static_cast(cs.cbInQue); } bool -Serial::SerialImpl::isOpen () const + Serial::SerialImpl::waitReadable(uint32_t /*timeout*/) { - return is_open_; -} - -size_t -Serial::SerialImpl::available () -{ - if (!is_open_) { - return 0; - } - COMSTAT cs; - if (!ClearCommError(fd_, NULL, &cs)) { - stringstream ss; - ss << "Error while checking status of the serial port: " << GetLastError(); - THROW (IOException, ss.str().c_str()); - } - return static_cast(cs.cbInQue); -} - -bool -Serial::SerialImpl::waitReadable (uint32_t /*timeout*/) -{ - THROW (IOException, "waitReadable is not implemented on Windows."); - return false; + THROW(IOException, "waitReadable is not implemented on Windows."); + return false; } void -Serial::SerialImpl::waitByteTimes (size_t /*count*/) + Serial::SerialImpl::waitByteTimes(size_t /*count*/) { - THROW (IOException, "waitByteTimes is not implemented on Windows."); + THROW(IOException, "waitByteTimes is not implemented on Windows."); } size_t -Serial::SerialImpl::read (uint8_t *buf, size_t size) +Serial::SerialImpl::read(uint8_t *buf, size_t size) { - if (!is_open_) { - throw PortNotOpenedException ("Serial::read"); - } - DWORD bytes_read; - if (!ReadFile(fd_, buf, static_cast(size), &bytes_read, NULL)) { - stringstream ss; - ss << "Error while reading from the serial port: " << GetLastError(); - THROW (IOException, ss.str().c_str()); - } - return (size_t) (bytes_read); + if (!is_open_) + { + throw PortNotOpenedException("Serial::read"); + } + DWORD bytes_read; + if (!ReadFile(fd_, buf, static_cast(size), &bytes_read, NULL)) + { + stringstream ss; + ss << "Error while reading from the serial port: " << GetLastError(); + THROW(IOException, ss.str().c_str()); + } + return (size_t)(bytes_read); } size_t -Serial::SerialImpl::write (const uint8_t *data, size_t length) +Serial::SerialImpl::write(const uint8_t *data, size_t length) { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::write"); - } - DWORD bytes_written; - if (!WriteFile(fd_, data, static_cast(length), &bytes_written, NULL)) { - stringstream ss; - ss << "Error while writing to the serial port: " << GetLastError(); - THROW (IOException, ss.str().c_str()); - } - return (size_t) (bytes_written); + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::write"); + } + DWORD bytes_written; + if (!WriteFile(fd_, data, static_cast(length), &bytes_written, NULL)) + { + stringstream ss; + ss << "Error while writing to the serial port: " << GetLastError(); + THROW(IOException, ss.str().c_str()); + } + return (size_t)(bytes_written); } -void -Serial::SerialImpl::setPort (const string &port) +void Serial::SerialImpl::setPort(const string &port) { - port_ = wstring(port.begin(), port.end()); + port_ = wstring(port.begin(), port.end()); } string -Serial::SerialImpl::getPort () const +Serial::SerialImpl::getPort() const { - return string(port_.begin(), port_.end()); + return string(port_.begin(), port_.end()); } -void -Serial::SerialImpl::setTimeout (serial::Timeout &timeout) +void Serial::SerialImpl::setTimeout(serial::Timeout &timeout) { - timeout_ = timeout; - if (is_open_) { - reconfigurePort (); - } + timeout_ = timeout; + if (is_open_) + { + reconfigurePort(); + } } serial::Timeout -Serial::SerialImpl::getTimeout () const +Serial::SerialImpl::getTimeout() const { - return timeout_; + return timeout_; } -void -Serial::SerialImpl::setBaudrate (unsigned long baudrate) +void Serial::SerialImpl::setBaudrate(unsigned long baudrate) { - baudrate_ = baudrate; - if (is_open_) { - reconfigurePort (); - } + baudrate_ = baudrate; + if (is_open_) + { + reconfigurePort(); + } } unsigned long -Serial::SerialImpl::getBaudrate () const +Serial::SerialImpl::getBaudrate() const { - return baudrate_; + return baudrate_; } -void -Serial::SerialImpl::setBytesize (serial::bytesize_t bytesize) +void Serial::SerialImpl::setBytesize(serial::bytesize_t bytesize) { - bytesize_ = bytesize; - if (is_open_) { - reconfigurePort (); - } + bytesize_ = bytesize; + if (is_open_) + { + reconfigurePort(); + } } serial::bytesize_t -Serial::SerialImpl::getBytesize () const +Serial::SerialImpl::getBytesize() const { - return bytesize_; + return bytesize_; } -void -Serial::SerialImpl::setParity (serial::parity_t parity) +void Serial::SerialImpl::setParity(serial::parity_t parity) { - parity_ = parity; - if (is_open_) { - reconfigurePort (); - } + parity_ = parity; + if (is_open_) + { + reconfigurePort(); + } } serial::parity_t -Serial::SerialImpl::getParity () const +Serial::SerialImpl::getParity() const { - return parity_; + return parity_; } -void -Serial::SerialImpl::setStopbits (serial::stopbits_t stopbits) +void Serial::SerialImpl::setStopbits(serial::stopbits_t stopbits) { - stopbits_ = stopbits; - if (is_open_) { - reconfigurePort (); - } + stopbits_ = stopbits; + if (is_open_) + { + reconfigurePort(); + } } serial::stopbits_t -Serial::SerialImpl::getStopbits () const +Serial::SerialImpl::getStopbits() const { - return stopbits_; + return stopbits_; } -void -Serial::SerialImpl::setFlowcontrol (serial::flowcontrol_t flowcontrol) +void Serial::SerialImpl::setFlowcontrol(serial::flowcontrol_t flowcontrol) { - flowcontrol_ = flowcontrol; - if (is_open_) { - reconfigurePort (); - } + flowcontrol_ = flowcontrol; + if (is_open_) + { + reconfigurePort(); + } } serial::flowcontrol_t -Serial::SerialImpl::getFlowcontrol () const +Serial::SerialImpl::getFlowcontrol() const { - return flowcontrol_; + return flowcontrol_; } -void -Serial::SerialImpl::flush () +void Serial::SerialImpl::flush() { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::flush"); - } - FlushFileBuffers (fd_); + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::flush"); + } + FlushFileBuffers(fd_); } -void -Serial::SerialImpl::flushInput () +void Serial::SerialImpl::flushInput() { - THROW (IOException, "flushInput is not supported on Windows."); + THROW(IOException, "flushInput is not supported on Windows."); } -void -Serial::SerialImpl::flushOutput () +void Serial::SerialImpl::flushOutput() { - THROW (IOException, "flushOutput is not supported on Windows."); + THROW(IOException, "flushOutput is not supported on Windows."); } -void -Serial::SerialImpl::sendBreak (int /*duration*/) +void Serial::SerialImpl::sendBreak(int /*duration*/) { - THROW (IOException, "sendBreak is not supported on Windows."); + THROW(IOException, "sendBreak is not supported on Windows."); } -void -Serial::SerialImpl::setBreak (bool level) +void Serial::SerialImpl::setBreak(bool level) { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::setBreak"); - } - if (level) { - EscapeCommFunction (fd_, SETBREAK); - } else { - EscapeCommFunction (fd_, CLRBREAK); - } + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::setBreak"); + } + if (level) + { + EscapeCommFunction(fd_, SETBREAK); + } + else + { + EscapeCommFunction(fd_, CLRBREAK); + } } -void -Serial::SerialImpl::setRTS (bool level) +void Serial::SerialImpl::setRTS(bool level) { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::setRTS"); - } - if (level) { - EscapeCommFunction (fd_, SETRTS); - } else { - EscapeCommFunction (fd_, CLRRTS); - } + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::setRTS"); + } + if (level) + { + EscapeCommFunction(fd_, SETRTS); + } + else + { + EscapeCommFunction(fd_, CLRRTS); + } } -void -Serial::SerialImpl::setDTR (bool level) +void Serial::SerialImpl::setDTR(bool level) { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::setDTR"); - } - if (level) { - EscapeCommFunction (fd_, SETDTR); - } else { - EscapeCommFunction (fd_, CLRDTR); - } + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::setDTR"); + } + if (level) + { + EscapeCommFunction(fd_, SETDTR); + } + else + { + EscapeCommFunction(fd_, CLRDTR); + } } -bool -Serial::SerialImpl::waitForChange () +bool Serial::SerialImpl::waitForChange() { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::waitForChange"); - } - DWORD dwCommEvent; + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::waitForChange"); + } + DWORD dwCommEvent; - if (!SetCommMask(fd_, EV_CTS | EV_DSR | EV_RING | EV_RLSD)) { - // Error setting communications mask - return false; - } + if (!SetCommMask(fd_, EV_CTS | EV_DSR | EV_RING | EV_RLSD)) + { + // Error setting communications mask + return false; + } - if (!WaitCommEvent(fd_, &dwCommEvent, NULL)) { - // An error occurred waiting for the event. - return false; - } else { - // Event has occurred. - return true; - } + if (!WaitCommEvent(fd_, &dwCommEvent, NULL)) + { + // An error occurred waiting for the event. + return false; + } + else + { + // Event has occurred. + return true; + } } -bool -Serial::SerialImpl::getCTS () +bool Serial::SerialImpl::getCTS() { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::getCTS"); - } - DWORD dwModemStatus; - if (!GetCommModemStatus(fd_, &dwModemStatus)) { - THROW (IOException, "Error getting the status of the CTS line."); - } + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::getCTS"); + } + DWORD dwModemStatus; + if (!GetCommModemStatus(fd_, &dwModemStatus)) + { + THROW(IOException, "Error getting the status of the CTS line."); + } - return (MS_CTS_ON & dwModemStatus) != 0; + return (MS_CTS_ON & dwModemStatus) != 0; } -bool -Serial::SerialImpl::getDSR () +bool Serial::SerialImpl::getDSR() { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::getDSR"); - } - DWORD dwModemStatus; - if (!GetCommModemStatus(fd_, &dwModemStatus)) { - THROW (IOException, "Error getting the status of the DSR line."); - } + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::getDSR"); + } + DWORD dwModemStatus; + if (!GetCommModemStatus(fd_, &dwModemStatus)) + { + THROW(IOException, "Error getting the status of the DSR line."); + } - return (MS_DSR_ON & dwModemStatus) != 0; + return (MS_DSR_ON & dwModemStatus) != 0; } -bool -Serial::SerialImpl::getRI() +bool Serial::SerialImpl::getRI() { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::getRI"); - } - DWORD dwModemStatus; - if (!GetCommModemStatus(fd_, &dwModemStatus)) { - THROW (IOException, "Error getting the status of the RI line."); - } + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::getRI"); + } + DWORD dwModemStatus; + if (!GetCommModemStatus(fd_, &dwModemStatus)) + { + THROW(IOException, "Error getting the status of the RI line."); + } - return (MS_RING_ON & dwModemStatus) != 0; + return (MS_RING_ON & dwModemStatus) != 0; } -bool -Serial::SerialImpl::getCD() +bool Serial::SerialImpl::getCD() { - if (is_open_ == false) { - throw PortNotOpenedException ("Serial::getCD"); - } - DWORD dwModemStatus; - if (!GetCommModemStatus(fd_, &dwModemStatus)) { - // Error in GetCommModemStatus; - THROW (IOException, "Error getting the status of the CD line."); - } + if (is_open_ == false) + { + throw PortNotOpenedException("Serial::getCD"); + } + DWORD dwModemStatus; + if (!GetCommModemStatus(fd_, &dwModemStatus)) + { + // Error in GetCommModemStatus; + THROW(IOException, "Error getting the status of the CD line."); + } - return (MS_RLSD_ON & dwModemStatus) != 0; + return (MS_RLSD_ON & dwModemStatus) != 0; } -void -Serial::SerialImpl::readLock() +void Serial::SerialImpl::readLock() { - if (WaitForSingleObject(read_mutex, INFINITE) != WAIT_OBJECT_0) { - THROW (IOException, "Error claiming read mutex."); - } + if (WaitForSingleObject(read_mutex, INFINITE) != WAIT_OBJECT_0) + { + THROW(IOException, "Error claiming read mutex."); + } } -void -Serial::SerialImpl::readUnlock() +void Serial::SerialImpl::readUnlock() { - if (!ReleaseMutex(read_mutex)) { - THROW (IOException, "Error releasing read mutex."); - } + if (!ReleaseMutex(read_mutex)) + { + THROW(IOException, "Error releasing read mutex."); + } } -void -Serial::SerialImpl::writeLock() +void Serial::SerialImpl::writeLock() { - if (WaitForSingleObject(write_mutex, INFINITE) != WAIT_OBJECT_0) { - THROW (IOException, "Error claiming write mutex."); - } + if (WaitForSingleObject(write_mutex, INFINITE) != WAIT_OBJECT_0) + { + THROW(IOException, "Error claiming write mutex."); + } } -void -Serial::SerialImpl::writeUnlock() +void Serial::SerialImpl::writeUnlock() { - if (!ReleaseMutex(write_mutex)) { - THROW (IOException, "Error releasing write mutex."); - } + if (!ReleaseMutex(write_mutex)) + { + THROW(IOException, "Error releasing write mutex."); + } } -#endif // #if defined(_WIN32) - +#endif // #if defined(_WIN32) diff --git a/examples/ThirdPartyLibs/serial/src/serial.cc b/examples/ThirdPartyLibs/serial/src/serial.cc index aab4caa7f..784482f38 100644 --- a/examples/ThirdPartyLibs/serial/src/serial.cc +++ b/examples/ThirdPartyLibs/serial/src/serial.cc @@ -2,11 +2,11 @@ #include #if !defined(_WIN32) && !defined(__OpenBSD__) && !defined(__FreeBSD__) -# include +#include #endif -#if defined (__MINGW32__) -# define alloca __builtin_alloca +#if defined(__MINGW32__) +#define alloca __builtin_alloca #endif #include "serial/serial.h" @@ -20,395 +20,397 @@ using std::invalid_argument; using std::min; using std::numeric_limits; -using std::vector; using std::size_t; using std::string; +using std::vector; +using serial::bytesize_t; +using serial::flowcontrol_t; +using serial::IOException; +using serial::parity_t; using serial::Serial; using serial::SerialException; -using serial::IOException; -using serial::bytesize_t; -using serial::parity_t; using serial::stopbits_t; -using serial::flowcontrol_t; -class Serial::ScopedReadLock { +class Serial::ScopedReadLock +{ public: - ScopedReadLock(SerialImpl *pimpl) : pimpl_(pimpl) { - this->pimpl_->readLock(); - } - ~ScopedReadLock() { - this->pimpl_->readUnlock(); - } -private: - // Disable copy constructors - ScopedReadLock(const ScopedReadLock&); - const ScopedReadLock& operator=(ScopedReadLock); + ScopedReadLock(SerialImpl *pimpl) : pimpl_(pimpl) + { + this->pimpl_->readLock(); + } + ~ScopedReadLock() + { + this->pimpl_->readUnlock(); + } - SerialImpl *pimpl_; +private: + // Disable copy constructors + ScopedReadLock(const ScopedReadLock &); + const ScopedReadLock &operator=(ScopedReadLock); + + SerialImpl *pimpl_; }; -class Serial::ScopedWriteLock { +class Serial::ScopedWriteLock +{ public: - ScopedWriteLock(SerialImpl *pimpl) : pimpl_(pimpl) { - this->pimpl_->writeLock(); - } - ~ScopedWriteLock() { - this->pimpl_->writeUnlock(); - } + ScopedWriteLock(SerialImpl *pimpl) : pimpl_(pimpl) + { + this->pimpl_->writeLock(); + } + ~ScopedWriteLock() + { + this->pimpl_->writeUnlock(); + } + private: - // Disable copy constructors - ScopedWriteLock(const ScopedWriteLock&); - const ScopedWriteLock& operator=(ScopedWriteLock); - SerialImpl *pimpl_; + // Disable copy constructors + ScopedWriteLock(const ScopedWriteLock &); + const ScopedWriteLock &operator=(ScopedWriteLock); + SerialImpl *pimpl_; }; -Serial::Serial (const string &port, uint32_t baudrate, serial::Timeout timeout, - bytesize_t bytesize, parity_t parity, stopbits_t stopbits, - flowcontrol_t flowcontrol) - : pimpl_(new SerialImpl (port, baudrate, bytesize, parity, - stopbits, flowcontrol)) +Serial::Serial(const string &port, uint32_t baudrate, serial::Timeout timeout, + bytesize_t bytesize, parity_t parity, stopbits_t stopbits, + flowcontrol_t flowcontrol) + : pimpl_(new SerialImpl(port, baudrate, bytesize, parity, + stopbits, flowcontrol)) { - pimpl_->setTimeout(timeout); + pimpl_->setTimeout(timeout); } -Serial::~Serial () +Serial::~Serial() { - delete pimpl_; + delete pimpl_; } -void -Serial::open () +void Serial::open() { - pimpl_->open (); + pimpl_->open(); } -void -Serial::close () +void Serial::close() { - pimpl_->close (); + pimpl_->close(); } -bool -Serial::isOpen () const +bool Serial::isOpen() const { - return pimpl_->isOpen (); + return pimpl_->isOpen(); } size_t -Serial::available () +Serial::available() { - return pimpl_->available (); + return pimpl_->available(); } -bool -Serial::waitReadable () +bool Serial::waitReadable() { - serial::Timeout timeout(pimpl_->getTimeout ()); - return pimpl_->waitReadable(timeout.read_timeout_constant); + serial::Timeout timeout(pimpl_->getTimeout()); + return pimpl_->waitReadable(timeout.read_timeout_constant); } -void -Serial::waitByteTimes (size_t count) +void Serial::waitByteTimes(size_t count) { - pimpl_->waitByteTimes(count); + pimpl_->waitByteTimes(count); } size_t -Serial::read_ (uint8_t *buffer, size_t size) +Serial::read_(uint8_t *buffer, size_t size) { - return this->pimpl_->read (buffer, size); + return this->pimpl_->read(buffer, size); } size_t -Serial::read (uint8_t *buffer, size_t size) +Serial::read(uint8_t *buffer, size_t size) { - ScopedReadLock lock(this->pimpl_); - return this->pimpl_->read (buffer, size); + ScopedReadLock lock(this->pimpl_); + return this->pimpl_->read(buffer, size); } size_t -Serial::read (std::vector &buffer, size_t size) +Serial::read(std::vector &buffer, size_t size) { - ScopedReadLock lock(this->pimpl_); - uint8_t *buffer_ = new uint8_t[size]; - size_t bytes_read = this->pimpl_->read (buffer_, size); - buffer.insert (buffer.end (), buffer_, buffer_+bytes_read); - delete[] buffer_; - return bytes_read; + ScopedReadLock lock(this->pimpl_); + uint8_t *buffer_ = new uint8_t[size]; + size_t bytes_read = this->pimpl_->read(buffer_, size); + buffer.insert(buffer.end(), buffer_, buffer_ + bytes_read); + delete[] buffer_; + return bytes_read; } size_t -Serial::read (std::string &buffer, size_t size) +Serial::read(std::string &buffer, size_t size) { - ScopedReadLock lock(this->pimpl_); - uint8_t *buffer_ = new uint8_t[size]; - size_t bytes_read = this->pimpl_->read (buffer_, size); - buffer.append (reinterpret_cast(buffer_), bytes_read); - delete[] buffer_; - return bytes_read; + ScopedReadLock lock(this->pimpl_); + uint8_t *buffer_ = new uint8_t[size]; + size_t bytes_read = this->pimpl_->read(buffer_, size); + buffer.append(reinterpret_cast(buffer_), bytes_read); + delete[] buffer_; + return bytes_read; } string -Serial::read (size_t size) +Serial::read(size_t size) { - std::string buffer; - this->read (buffer, size); - return buffer; + std::string buffer; + this->read(buffer, size); + return buffer; } size_t -Serial::readline (string &buffer, size_t size, string eol) +Serial::readline(string &buffer, size_t size, string eol) { - ScopedReadLock lock(this->pimpl_); - size_t eol_len = eol.length (); - uint8_t *buffer_ = static_cast - (alloca (size * sizeof (uint8_t))); - size_t read_so_far = 0; - while (true) - { - size_t bytes_read = this->read_ (buffer_ + read_so_far, 1); - read_so_far += bytes_read; - if (bytes_read == 0) { - break; // Timeout occured on reading 1 byte - } - if (string (reinterpret_cast - (buffer_ + read_so_far - eol_len), eol_len) == eol) { - break; // EOL found - } - if (read_so_far == size) { - break; // Reached the maximum read length - } - } - buffer.append(reinterpret_cast (buffer_), read_so_far); - return read_so_far; + ScopedReadLock lock(this->pimpl_); + size_t eol_len = eol.length(); + uint8_t *buffer_ = static_cast(alloca(size * sizeof(uint8_t))); + size_t read_so_far = 0; + while (true) + { + size_t bytes_read = this->read_(buffer_ + read_so_far, 1); + read_so_far += bytes_read; + if (bytes_read == 0) + { + break; // Timeout occured on reading 1 byte + } + if (string(reinterpret_cast(buffer_ + read_so_far - eol_len), eol_len) == eol) + { + break; // EOL found + } + if (read_so_far == size) + { + break; // Reached the maximum read length + } + } + buffer.append(reinterpret_cast(buffer_), read_so_far); + return read_so_far; } string -Serial::readline (size_t size, string eol) +Serial::readline(size_t size, string eol) { - std::string buffer; - this->readline (buffer, size, eol); - return buffer; + std::string buffer; + this->readline(buffer, size, eol); + return buffer; } vector -Serial::readlines (size_t size, string eol) +Serial::readlines(size_t size, string eol) { - ScopedReadLock lock(this->pimpl_); - std::vector lines; - size_t eol_len = eol.length (); - uint8_t *buffer_ = static_cast - (alloca (size * sizeof (uint8_t))); - size_t read_so_far = 0; - size_t start_of_line = 0; - while (read_so_far < size) { - size_t bytes_read = this->read_ (buffer_+read_so_far, 1); - read_so_far += bytes_read; - if (bytes_read == 0) { - if (start_of_line != read_so_far) { - lines.push_back ( - string (reinterpret_cast (buffer_ + start_of_line), - read_so_far - start_of_line)); - } - break; // Timeout occured on reading 1 byte - } - if (string (reinterpret_cast - (buffer_ + read_so_far - eol_len), eol_len) == eol) { - // EOL found - lines.push_back( - string(reinterpret_cast (buffer_ + start_of_line), - read_so_far - start_of_line)); - start_of_line = read_so_far; - } - if (read_so_far == size) { - if (start_of_line != read_so_far) { - lines.push_back( - string(reinterpret_cast (buffer_ + start_of_line), - read_so_far - start_of_line)); - } - break; // Reached the maximum read length - } - } - return lines; + ScopedReadLock lock(this->pimpl_); + std::vector lines; + size_t eol_len = eol.length(); + uint8_t *buffer_ = static_cast(alloca(size * sizeof(uint8_t))); + size_t read_so_far = 0; + size_t start_of_line = 0; + while (read_so_far < size) + { + size_t bytes_read = this->read_(buffer_ + read_so_far, 1); + read_so_far += bytes_read; + if (bytes_read == 0) + { + if (start_of_line != read_so_far) + { + lines.push_back( + string(reinterpret_cast(buffer_ + start_of_line), + read_so_far - start_of_line)); + } + break; // Timeout occured on reading 1 byte + } + if (string(reinterpret_cast(buffer_ + read_so_far - eol_len), eol_len) == eol) + { + // EOL found + lines.push_back( + string(reinterpret_cast(buffer_ + start_of_line), + read_so_far - start_of_line)); + start_of_line = read_so_far; + } + if (read_so_far == size) + { + if (start_of_line != read_so_far) + { + lines.push_back( + string(reinterpret_cast(buffer_ + start_of_line), + read_so_far - start_of_line)); + } + break; // Reached the maximum read length + } + } + return lines; } size_t -Serial::write (const string &data) +Serial::write(const string &data) { - ScopedWriteLock lock(this->pimpl_); - return this->write_ (reinterpret_cast(data.c_str()), - data.length()); + ScopedWriteLock lock(this->pimpl_); + return this->write_(reinterpret_cast(data.c_str()), + data.length()); } size_t -Serial::write (const std::vector &data) +Serial::write(const std::vector &data) { - ScopedWriteLock lock(this->pimpl_); - return this->write_ (&data[0], data.size()); + ScopedWriteLock lock(this->pimpl_); + return this->write_(&data[0], data.size()); } size_t -Serial::write (const uint8_t *data, size_t size) +Serial::write(const uint8_t *data, size_t size) { - ScopedWriteLock lock(this->pimpl_); - return this->write_(data, size); + ScopedWriteLock lock(this->pimpl_); + return this->write_(data, size); } size_t -Serial::write_ (const uint8_t *data, size_t length) +Serial::write_(const uint8_t *data, size_t length) { - return pimpl_->write (data, length); + return pimpl_->write(data, length); } -void -Serial::setPort (const string &port) +void Serial::setPort(const string &port) { - ScopedReadLock rlock(this->pimpl_); - ScopedWriteLock wlock(this->pimpl_); - bool was_open = pimpl_->isOpen (); - if (was_open) close(); - pimpl_->setPort (port); - if (was_open) open (); + ScopedReadLock rlock(this->pimpl_); + ScopedWriteLock wlock(this->pimpl_); + bool was_open = pimpl_->isOpen(); + if (was_open) close(); + pimpl_->setPort(port); + if (was_open) open(); } string -Serial::getPort () const +Serial::getPort() const { - return pimpl_->getPort (); + return pimpl_->getPort(); } -void -Serial::setTimeout (serial::Timeout &timeout) +void Serial::setTimeout(serial::Timeout &timeout) { - pimpl_->setTimeout (timeout); + pimpl_->setTimeout(timeout); } serial::Timeout -Serial::getTimeout () const { - return pimpl_->getTimeout (); +Serial::getTimeout() const +{ + return pimpl_->getTimeout(); } -void -Serial::setBaudrate (uint32_t baudrate) +void Serial::setBaudrate(uint32_t baudrate) { - pimpl_->setBaudrate (baudrate); + pimpl_->setBaudrate(baudrate); } uint32_t -Serial::getBaudrate () const +Serial::getBaudrate() const { - return uint32_t(pimpl_->getBaudrate ()); + return uint32_t(pimpl_->getBaudrate()); } -void -Serial::setBytesize (bytesize_t bytesize) +void Serial::setBytesize(bytesize_t bytesize) { - pimpl_->setBytesize (bytesize); + pimpl_->setBytesize(bytesize); } bytesize_t -Serial::getBytesize () const +Serial::getBytesize() const { - return pimpl_->getBytesize (); + return pimpl_->getBytesize(); } -void -Serial::setParity (parity_t parity) +void Serial::setParity(parity_t parity) { - pimpl_->setParity (parity); + pimpl_->setParity(parity); } parity_t -Serial::getParity () const +Serial::getParity() const { - return pimpl_->getParity (); + return pimpl_->getParity(); } -void -Serial::setStopbits (stopbits_t stopbits) +void Serial::setStopbits(stopbits_t stopbits) { - pimpl_->setStopbits (stopbits); + pimpl_->setStopbits(stopbits); } stopbits_t -Serial::getStopbits () const +Serial::getStopbits() const { - return pimpl_->getStopbits (); + return pimpl_->getStopbits(); } -void -Serial::setFlowcontrol (flowcontrol_t flowcontrol) +void Serial::setFlowcontrol(flowcontrol_t flowcontrol) { - pimpl_->setFlowcontrol (flowcontrol); + pimpl_->setFlowcontrol(flowcontrol); } flowcontrol_t -Serial::getFlowcontrol () const +Serial::getFlowcontrol() const { - return pimpl_->getFlowcontrol (); + return pimpl_->getFlowcontrol(); } -void Serial::flush () +void Serial::flush() { - ScopedReadLock rlock(this->pimpl_); - ScopedWriteLock wlock(this->pimpl_); - pimpl_->flush (); + ScopedReadLock rlock(this->pimpl_); + ScopedWriteLock wlock(this->pimpl_); + pimpl_->flush(); } -void Serial::flushInput () +void Serial::flushInput() { - ScopedReadLock lock(this->pimpl_); - pimpl_->flushInput (); + ScopedReadLock lock(this->pimpl_); + pimpl_->flushInput(); } -void Serial::flushOutput () +void Serial::flushOutput() { - ScopedWriteLock lock(this->pimpl_); - pimpl_->flushOutput (); + ScopedWriteLock lock(this->pimpl_); + pimpl_->flushOutput(); } -void Serial::sendBreak (int duration) +void Serial::sendBreak(int duration) { - pimpl_->sendBreak (duration); + pimpl_->sendBreak(duration); } -void Serial::setBreak (bool level) +void Serial::setBreak(bool level) { - pimpl_->setBreak (level); + pimpl_->setBreak(level); } -void Serial::setRTS (bool level) +void Serial::setRTS(bool level) { - pimpl_->setRTS (level); + pimpl_->setRTS(level); } -void Serial::setDTR (bool level) +void Serial::setDTR(bool level) { - pimpl_->setDTR (level); + pimpl_->setDTR(level); } bool Serial::waitForChange() { - return pimpl_->waitForChange(); + return pimpl_->waitForChange(); } -bool Serial::getCTS () +bool Serial::getCTS() { - return pimpl_->getCTS (); + return pimpl_->getCTS(); } -bool Serial::getDSR () +bool Serial::getDSR() { - return pimpl_->getDSR (); + return pimpl_->getDSR(); } -bool Serial::getRI () +bool Serial::getRI() { - return pimpl_->getRI (); + return pimpl_->getRI(); } -bool Serial::getCD () +bool Serial::getCD() { - return pimpl_->getCD (); + return pimpl_->getCD(); } diff --git a/examples/ThirdPartyLibs/stb_image/stb_image.cpp b/examples/ThirdPartyLibs/stb_image/stb_image.cpp index bbae0b0e4..6702658a3 100644 --- a/examples/ThirdPartyLibs/stb_image/stb_image.cpp +++ b/examples/ThirdPartyLibs/stb_image/stb_image.cpp @@ -3,8 +3,8 @@ #ifndef STBI_HEADER_FILE_ONLY #ifndef STBI_NO_HDR -#include // ldexp -#include // strcmp, strtok +#include // ldexp +#include // strcmp, strtok #endif #ifndef STBI_NO_STDIO @@ -16,41 +16,40 @@ #include #ifndef _MSC_VER - #ifdef __cplusplus - #define stbi_inline inline - #else - #define stbi_inline - #endif +#ifdef __cplusplus +#define stbi_inline inline #else - #define stbi_inline __forceinline +#define stbi_inline +#endif +#else +#define stbi_inline __forceinline #endif - // implementation: -typedef unsigned char uint8; +typedef unsigned char uint8; typedef unsigned short uint16; -typedef signed short int16; -typedef unsigned int uint32; -typedef signed int int32; -typedef unsigned int uint; +typedef signed short int16; +typedef unsigned int uint32; +typedef signed int int32; +typedef unsigned int uint; // should produce compiler error if size is wrong -typedef unsigned char validate_uint32[sizeof(uint32)==4 ? 1 : -1]; +typedef unsigned char validate_uint32[sizeof(uint32) == 4 ? 1 : -1]; #if defined(STBI_NO_STDIO) && !defined(STBI_NO_WRITE) #define STBI_NO_WRITE #endif -#define STBI_NOTUSED(v) (void)sizeof(v) +#define STBI_NOTUSED(v) (void)sizeof(v) #ifdef _MSC_VER #define STBI_HAS_LROTL #endif #ifdef STBI_HAS_LROTL - #define stbi_lrot(x,y) _lrotl(x,y) +#define stbi_lrot(x, y) _lrotl(x, y) #else - #define stbi_lrot(x,y) (((x) << (y)) | ((x) >> (32 - (y)))) +#define stbi_lrot(x, y) (((x) << (y)) | ((x) >> (32 - (y)))) #endif /////////////////////////////////////////////// @@ -61,118 +60,116 @@ typedef unsigned char validate_uint32[sizeof(uint32)==4 ? 1 : -1]; // contains all the IO context, plus some basic image information typedef struct { - uint32 img_x, img_y; - int img_n, img_out_n; - - stbi_io_callbacks io; - void *io_user_data; + uint32 img_x, img_y; + int img_n, img_out_n; - int read_from_callbacks; - int buflen; - uint8 buffer_start[128]; + stbi_io_callbacks io; + void *io_user_data; - uint8 *img_buffer, *img_buffer_end; - uint8 *img_buffer_original; + int read_from_callbacks; + int buflen; + uint8 buffer_start[128]; + + uint8 *img_buffer, *img_buffer_end; + uint8 *img_buffer_original; } stbi; - static void refill_buffer(stbi *s); // initialize a memory-decode context static void start_mem(stbi *s, uint8 const *buffer, int len) { - s->io.read = NULL; - s->read_from_callbacks = 0; - s->img_buffer = s->img_buffer_original = (uint8 *) buffer; - s->img_buffer_end = (uint8 *) buffer+len; + s->io.read = NULL; + s->read_from_callbacks = 0; + s->img_buffer = s->img_buffer_original = (uint8 *)buffer; + s->img_buffer_end = (uint8 *)buffer + len; } // initialize a callback-based context static void start_callbacks(stbi *s, stbi_io_callbacks *c, void *user) { - s->io = *c; - s->io_user_data = user; - s->buflen = sizeof(s->buffer_start); - s->read_from_callbacks = 1; - s->img_buffer_original = s->buffer_start; - refill_buffer(s); + s->io = *c; + s->io_user_data = user; + s->buflen = sizeof(s->buffer_start); + s->read_from_callbacks = 1; + s->img_buffer_original = s->buffer_start; + refill_buffer(s); } #ifndef STBI_NO_STDIO static int stdio_read(void *user, char *data, int size) { - return (int) fread(data,1,size,(FILE*) user); + return (int)fread(data, 1, size, (FILE *)user); } static void stdio_skip(void *user, unsigned n) { - fseek((FILE*) user, n, SEEK_CUR); + fseek((FILE *)user, n, SEEK_CUR); } static int stdio_eof(void *user) { - return feof((FILE*) user); + return feof((FILE *)user); } static stbi_io_callbacks stbi_stdio_callbacks = -{ - stdio_read, - stdio_skip, - stdio_eof, + { + stdio_read, + stdio_skip, + stdio_eof, }; static void start_file(stbi *s, FILE *f) { - start_callbacks(s, &stbi_stdio_callbacks, (void *) f); + start_callbacks(s, &stbi_stdio_callbacks, (void *)f); } //static void stop_file(stbi *s) { } -#endif // !STBI_NO_STDIO +#endif // !STBI_NO_STDIO static void stbi_rewind(stbi *s) { - // conceptually rewind SHOULD rewind to the beginning of the stream, - // but we just rewind to the beginning of the initial buffer, because - // we only use it after doing 'test', which only ever looks at at most 92 bytes - s->img_buffer = s->img_buffer_original; + // conceptually rewind SHOULD rewind to the beginning of the stream, + // but we just rewind to the beginning of the initial buffer, because + // we only use it after doing 'test', which only ever looks at at most 92 bytes + s->img_buffer = s->img_buffer_original; } -static int stbi_jpeg_test(stbi *s); +static int stbi_jpeg_test(stbi *s); static stbi_uc *stbi_jpeg_load(stbi *s, int *x, int *y, int *comp, int req_comp); -static int stbi_jpeg_info(stbi *s, int *x, int *y, int *comp); -static int stbi_png_test(stbi *s); +static int stbi_jpeg_info(stbi *s, int *x, int *y, int *comp); +static int stbi_png_test(stbi *s); static stbi_uc *stbi_png_load(stbi *s, int *x, int *y, int *comp, int req_comp); -static int stbi_png_info(stbi *s, int *x, int *y, int *comp); -static int stbi_bmp_test(stbi *s); +static int stbi_png_info(stbi *s, int *x, int *y, int *comp); +static int stbi_bmp_test(stbi *s); static stbi_uc *stbi_bmp_load(stbi *s, int *x, int *y, int *comp, int req_comp); -static int stbi_tga_test(stbi *s); +static int stbi_tga_test(stbi *s); static stbi_uc *stbi_tga_load(stbi *s, int *x, int *y, int *comp, int req_comp); -static int stbi_tga_info(stbi *s, int *x, int *y, int *comp); -static int stbi_psd_test(stbi *s); +static int stbi_tga_info(stbi *s, int *x, int *y, int *comp); +static int stbi_psd_test(stbi *s); static stbi_uc *stbi_psd_load(stbi *s, int *x, int *y, int *comp, int req_comp); -static int stbi_hdr_test(stbi *s); -static float *stbi_hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp); -static int stbi_pic_test(stbi *s); +static int stbi_hdr_test(stbi *s); +static float *stbi_hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp); +static int stbi_pic_test(stbi *s); static stbi_uc *stbi_pic_load(stbi *s, int *x, int *y, int *comp, int req_comp); -static int stbi_gif_test(stbi *s); +static int stbi_gif_test(stbi *s); static stbi_uc *stbi_gif_load(stbi *s, int *x, int *y, int *comp, int req_comp); -static int stbi_gif_info(stbi *s, int *x, int *y, int *comp); - +static int stbi_gif_info(stbi *s, int *x, int *y, int *comp); // this is not threadsafe static const char *failure_reason; const char *stbi_failure_reason(void) { - return failure_reason; + return failure_reason; } static int e(const char *str) { - failure_reason = str; - return 0; + failure_reason = str; + return 0; } // e - error @@ -180,130 +177,131 @@ static int e(const char *str) // epuc - error returning pointer to unsigned char #ifdef STBI_NO_FAILURE_STRINGS - #define e(x,y) 0 +#define e(x, y) 0 #elif defined(STBI_FAILURE_USERMSG) - #define e(x,y) e(y) +#define e(x, y) e(y) #else - #define e(x,y) e(x) +#define e(x, y) e(x) #endif -#define epf(x,y) ((float *) (e(x,y)?NULL:NULL)) -#define epuc(x,y) ((unsigned char *) (e(x,y)?NULL:NULL)) +#define epf(x, y) ((float *)(e(x, y) ? NULL : NULL)) +#define epuc(x, y) ((unsigned char *)(e(x, y) ? NULL : NULL)) void stbi_image_free(void *retval_from_stbi_load) { - free(retval_from_stbi_load); + free(retval_from_stbi_load); } #ifndef STBI_NO_HDR -static float *ldr_to_hdr(stbi_uc *data, int x, int y, int comp); -static stbi_uc *hdr_to_ldr(float *data, int x, int y, int comp); +static float *ldr_to_hdr(stbi_uc *data, int x, int y, int comp); +static stbi_uc *hdr_to_ldr(float *data, int x, int y, int comp); #endif static unsigned char *stbi_load_main(stbi *s, int *x, int *y, int *comp, int req_comp) { - if (stbi_jpeg_test(s)) return stbi_jpeg_load(s,x,y,comp,req_comp); - if (stbi_png_test(s)) return stbi_png_load(s,x,y,comp,req_comp); - if (stbi_bmp_test(s)) return stbi_bmp_load(s,x,y,comp,req_comp); - if (stbi_gif_test(s)) return stbi_gif_load(s,x,y,comp,req_comp); - if (stbi_psd_test(s)) return stbi_psd_load(s,x,y,comp,req_comp); - if (stbi_pic_test(s)) return stbi_pic_load(s,x,y,comp,req_comp); + if (stbi_jpeg_test(s)) return stbi_jpeg_load(s, x, y, comp, req_comp); + if (stbi_png_test(s)) return stbi_png_load(s, x, y, comp, req_comp); + if (stbi_bmp_test(s)) return stbi_bmp_load(s, x, y, comp, req_comp); + if (stbi_gif_test(s)) return stbi_gif_load(s, x, y, comp, req_comp); + if (stbi_psd_test(s)) return stbi_psd_load(s, x, y, comp, req_comp); + if (stbi_pic_test(s)) return stbi_pic_load(s, x, y, comp, req_comp); - #ifndef STBI_NO_HDR - if (stbi_hdr_test(s)) { - float *hdr = stbi_hdr_load(s, x,y,comp,req_comp); - return hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); - } - #endif +#ifndef STBI_NO_HDR + if (stbi_hdr_test(s)) + { + float *hdr = stbi_hdr_load(s, x, y, comp, req_comp); + return hdr_to_ldr(hdr, *x, *y, req_comp ? req_comp : *comp); + } +#endif - // test tga last because it's a crappy test! - if (stbi_tga_test(s)) - return stbi_tga_load(s,x,y,comp,req_comp); - return epuc("unknown image type", "Image not of any known type, or corrupt"); + // test tga last because it's a crappy test! + if (stbi_tga_test(s)) + return stbi_tga_load(s, x, y, comp, req_comp); + return epuc("unknown image type", "Image not of any known type, or corrupt"); } #ifndef STBI_NO_STDIO unsigned char *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp) { - FILE *f = fopen(filename, "rb"); - unsigned char *result; - if (!f) return epuc("can't fopen", "Unable to open file"); - result = stbi_load_from_file(f,x,y,comp,req_comp); - fclose(f); - return result; + FILE *f = fopen(filename, "rb"); + unsigned char *result; + if (!f) return epuc("can't fopen", "Unable to open file"); + result = stbi_load_from_file(f, x, y, comp, req_comp); + fclose(f); + return result; } unsigned char *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) { - stbi s; - start_file(&s,f); - return stbi_load_main(&s,x,y,comp,req_comp); + stbi s; + start_file(&s, f); + return stbi_load_main(&s, x, y, comp, req_comp); } -#endif //!STBI_NO_STDIO +#endif //!STBI_NO_STDIO unsigned char *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) { - stbi s; - start_mem(&s,buffer,len); - return stbi_load_main(&s,x,y,comp,req_comp); + stbi s; + start_mem(&s, buffer, len); + return stbi_load_main(&s, x, y, comp, req_comp); } unsigned char *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) { - stbi s; - start_callbacks(&s, (stbi_io_callbacks *) clbk, user); - return stbi_load_main(&s,x,y,comp,req_comp); + stbi s; + start_callbacks(&s, (stbi_io_callbacks *)clbk, user); + return stbi_load_main(&s, x, y, comp, req_comp); } #ifndef STBI_NO_HDR float *stbi_loadf_main(stbi *s, int *x, int *y, int *comp, int req_comp) { - unsigned char *data; - #ifndef STBI_NO_HDR - if (stbi_hdr_test(s)) - return stbi_hdr_load(s,x,y,comp,req_comp); - #endif - data = stbi_load_main(s, x, y, comp, req_comp); - if (data) - return ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); - return epf("unknown image type", "Image not of any known type, or corrupt"); + unsigned char *data; +#ifndef STBI_NO_HDR + if (stbi_hdr_test(s)) + return stbi_hdr_load(s, x, y, comp, req_comp); +#endif + data = stbi_load_main(s, x, y, comp, req_comp); + if (data) + return ldr_to_hdr(data, *x, *y, req_comp ? req_comp : *comp); + return epf("unknown image type", "Image not of any known type, or corrupt"); } float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp) { - stbi s; - start_mem(&s,buffer,len); - return stbi_loadf_main(&s,x,y,comp,req_comp); + stbi s; + start_mem(&s, buffer, len); + return stbi_loadf_main(&s, x, y, comp, req_comp); } float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp) { - stbi s; - start_callbacks(&s, (stbi_io_callbacks *) clbk, user); - return stbi_loadf_main(&s,x,y,comp,req_comp); + stbi s; + start_callbacks(&s, (stbi_io_callbacks *)clbk, user); + return stbi_loadf_main(&s, x, y, comp, req_comp); } #ifndef STBI_NO_STDIO float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp) { - FILE *f = fopen(filename, "rb"); - float *result; - if (!f) return epf("can't fopen", "Unable to open file"); - result = stbi_loadf_from_file(f,x,y,comp,req_comp); - fclose(f); - return result; + FILE *f = fopen(filename, "rb"); + float *result; + if (!f) return epf("can't fopen", "Unable to open file"); + result = stbi_loadf_from_file(f, x, y, comp, req_comp); + fclose(f); + return result; } float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) { - stbi s; - start_file(&s,f); - return stbi_loadf_main(&s,x,y,comp,req_comp); + stbi s; + start_file(&s, f); + return stbi_loadf_main(&s, x, y, comp, req_comp); } -#endif // !STBI_NO_STDIO +#endif // !STBI_NO_STDIO -#endif // !STBI_NO_HDR +#endif // !STBI_NO_HDR // these is-hdr-or-not is defined independent of whether STBI_NO_HDR is // defined, for API simplicity; if STBI_NO_HDR is defined, it always @@ -311,64 +309,64 @@ float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp) int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len) { - #ifndef STBI_NO_HDR - stbi s; - start_mem(&s,buffer,len); - return stbi_hdr_test(&s); - #else - STBI_NOTUSED(buffer); - STBI_NOTUSED(len); - return 0; - #endif +#ifndef STBI_NO_HDR + stbi s; + start_mem(&s, buffer, len); + return stbi_hdr_test(&s); +#else + STBI_NOTUSED(buffer); + STBI_NOTUSED(len); + return 0; +#endif } #ifndef STBI_NO_STDIO -extern int stbi_is_hdr (char const *filename) +extern int stbi_is_hdr(char const *filename) { - FILE *f = fopen(filename, "rb"); - int result=0; - if (f) { - result = stbi_is_hdr_from_file(f); - fclose(f); - } - return result; + FILE *f = fopen(filename, "rb"); + int result = 0; + if (f) + { + result = stbi_is_hdr_from_file(f); + fclose(f); + } + return result; } -extern int stbi_is_hdr_from_file(FILE *f) +extern int stbi_is_hdr_from_file(FILE *f) { - #ifndef STBI_NO_HDR - stbi s; - start_file(&s,f); - return stbi_hdr_test(&s); - #else - return 0; - #endif +#ifndef STBI_NO_HDR + stbi s; + start_file(&s, f); + return stbi_hdr_test(&s); +#else + return 0; +#endif } -#endif // !STBI_NO_STDIO +#endif // !STBI_NO_STDIO -extern int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user) +extern int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user) { - #ifndef STBI_NO_HDR - stbi s; - start_callbacks(&s, (stbi_io_callbacks *) clbk, user); - return stbi_hdr_test(&s); - #else - return 0; - #endif +#ifndef STBI_NO_HDR + stbi s; + start_callbacks(&s, (stbi_io_callbacks *)clbk, user); + return stbi_hdr_test(&s); +#else + return 0; +#endif } #ifndef STBI_NO_HDR -static float h2l_gamma_i=1.0f/2.2f, h2l_scale_i=1.0f; -static float l2h_gamma=2.2f, l2h_scale=1.0f; +static float h2l_gamma_i = 1.0f / 2.2f, h2l_scale_i = 1.0f; +static float l2h_gamma = 2.2f, l2h_scale = 1.0f; -void stbi_hdr_to_ldr_gamma(float gamma) { h2l_gamma_i = 1/gamma; } -void stbi_hdr_to_ldr_scale(float scale) { h2l_scale_i = 1/scale; } +void stbi_hdr_to_ldr_gamma(float gamma) { h2l_gamma_i = 1 / gamma; } +void stbi_hdr_to_ldr_scale(float scale) { h2l_scale_i = 1 / scale; } -void stbi_ldr_to_hdr_gamma(float gamma) { l2h_gamma = gamma; } -void stbi_ldr_to_hdr_scale(float scale) { l2h_scale = scale; } +void stbi_ldr_to_hdr_gamma(float gamma) { l2h_gamma = gamma; } +void stbi_ldr_to_hdr_scale(float scale) { l2h_scale = scale; } #endif - ////////////////////////////////////////////////////////////////////////////// // // Common code used by all image loaders @@ -376,112 +374,123 @@ void stbi_ldr_to_hdr_scale(float scale) { l2h_scale = scale; } enum { - SCAN_load=0, - SCAN_type, - SCAN_header + SCAN_load = 0, + SCAN_type, + SCAN_header }; static void refill_buffer(stbi *s) { - int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen); - if (n == 0) { - // at end of file, treat same as if from memory - s->read_from_callbacks = 0; - s->img_buffer = s->img_buffer_end-1; - *s->img_buffer = 0; - } else { - s->img_buffer = s->buffer_start; - s->img_buffer_end = s->buffer_start + n; - } + int n = (s->io.read)(s->io_user_data, (char *)s->buffer_start, s->buflen); + if (n == 0) + { + // at end of file, treat same as if from memory + s->read_from_callbacks = 0; + s->img_buffer = s->img_buffer_end - 1; + *s->img_buffer = 0; + } + else + { + s->img_buffer = s->buffer_start; + s->img_buffer_end = s->buffer_start + n; + } } stbi_inline static int get8(stbi *s) { - if (s->img_buffer < s->img_buffer_end) - return *s->img_buffer++; - if (s->read_from_callbacks) { - refill_buffer(s); - return *s->img_buffer++; - } - return 0; + if (s->img_buffer < s->img_buffer_end) + return *s->img_buffer++; + if (s->read_from_callbacks) + { + refill_buffer(s); + return *s->img_buffer++; + } + return 0; } stbi_inline static int at_eof(stbi *s) { - if (s->io.read) { - if (!(s->io.eof)(s->io_user_data)) return 0; - // if feof() is true, check if buffer = end - // special case: we've only got the special 0 character at the end - if (s->read_from_callbacks == 0) return 1; - } + if (s->io.read) + { + if (!(s->io.eof)(s->io_user_data)) return 0; + // if feof() is true, check if buffer = end + // special case: we've only got the special 0 character at the end + if (s->read_from_callbacks == 0) return 1; + } - return s->img_buffer >= s->img_buffer_end; + return s->img_buffer >= s->img_buffer_end; } stbi_inline static uint8 get8u(stbi *s) { - return (uint8) get8(s); + return (uint8)get8(s); } static void skip(stbi *s, int n) { - if (s->io.read) { - int blen = s->img_buffer_end - s->img_buffer; - if (blen < n) { - s->img_buffer = s->img_buffer_end; - (s->io.skip)(s->io_user_data, n - blen); - return; - } - } - s->img_buffer += n; + if (s->io.read) + { + int blen = s->img_buffer_end - s->img_buffer; + if (blen < n) + { + s->img_buffer = s->img_buffer_end; + (s->io.skip)(s->io_user_data, n - blen); + return; + } + } + s->img_buffer += n; } static int getn(stbi *s, stbi_uc *buffer, int n) { - if (s->io.read) { - int blen = s->img_buffer_end - s->img_buffer; - if (blen < n) { - int res, count; + if (s->io.read) + { + int blen = s->img_buffer_end - s->img_buffer; + if (blen < n) + { + int res, count; - memcpy(buffer, s->img_buffer, blen); - - count = (s->io.read)(s->io_user_data, (char*) buffer + blen, n - blen); - res = (count == (n-blen)); - s->img_buffer = s->img_buffer_end; - return res; - } - } + memcpy(buffer, s->img_buffer, blen); - if (s->img_buffer+n <= s->img_buffer_end) { - memcpy(buffer, s->img_buffer, n); - s->img_buffer += n; - return 1; - } else - return 0; + count = (s->io.read)(s->io_user_data, (char *)buffer + blen, n - blen); + res = (count == (n - blen)); + s->img_buffer = s->img_buffer_end; + return res; + } + } + + if (s->img_buffer + n <= s->img_buffer_end) + { + memcpy(buffer, s->img_buffer, n); + s->img_buffer += n; + return 1; + } + else + return 0; } static int get16(stbi *s) { - int z = get8(s); - return (z << 8) + get8(s); + int z = get8(s); + return (z << 8) + get8(s); } static uint32 get32(stbi *s) { - uint32 z = get16(s); - return (z << 16) + get16(s); + uint32 z = get16(s); + return (z << 16) + get16(s); } static int get16le(stbi *s) { - int z = get8(s); - return z + (get8(s) << 8); + int z = get8(s); + return z + (get8(s) << 8); } static uint32 get32le(stbi *s) { - uint32 z = get16le(s); - return z + (get16le(s) << 16); + uint32 z = get16le(s); + return z + (get16le(s) << 16); } ////////////////////////////////////////////////////////////////////////////// @@ -497,95 +506,151 @@ static uint32 get32le(stbi *s) static uint8 compute_y(int r, int g, int b) { - return (uint8) (((r*77) + (g*150) + (29*b)) >> 8); + return (uint8)(((r * 77) + (g * 150) + (29 * b)) >> 8); } static unsigned char *convert_format(unsigned char *data, int img_n, int req_comp, uint x, uint y) { - int i,j; - unsigned char *good; + int i, j; + unsigned char *good; - if (req_comp == img_n) return data; - assert(req_comp >= 1 && req_comp <= 4); + if (req_comp == img_n) return data; + assert(req_comp >= 1 && req_comp <= 4); - good = (unsigned char *) malloc(req_comp * x * y); - if (good == NULL) { - free(data); - return epuc("outofmem", "Out of memory"); - } + good = (unsigned char *)malloc(req_comp * x * y); + if (good == NULL) + { + free(data); + return epuc("outofmem", "Out of memory"); + } - for (j=0; j < (int) y; ++j) { - unsigned char *src = data + j * x * img_n ; - unsigned char *dest = good + j * x * req_comp; + for (j = 0; j < (int)y; ++j) + { + unsigned char *src = data + j * x * img_n; + unsigned char *dest = good + j * x * req_comp; - #define COMBO(a,b) ((a)*8+(b)) - #define CASE(a,b) case COMBO(a,b): for(i=x-1; i >= 0; --i, src += a, dest += b) - // convert source image with img_n components to one with req_comp components; - // avoid switch per pixel, so use switch per scanline and massive macros - switch (COMBO(img_n, req_comp)) { - CASE(1,2) dest[0]=src[0], dest[1]=255; break; - CASE(1,3) dest[0]=dest[1]=dest[2]=src[0]; break; - CASE(1,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=255; break; - CASE(2,1) dest[0]=src[0]; break; - CASE(2,3) dest[0]=dest[1]=dest[2]=src[0]; break; - CASE(2,4) dest[0]=dest[1]=dest[2]=src[0], dest[3]=src[1]; break; - CASE(3,4) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2],dest[3]=255; break; - CASE(3,1) dest[0]=compute_y(src[0],src[1],src[2]); break; - CASE(3,2) dest[0]=compute_y(src[0],src[1],src[2]), dest[1] = 255; break; - CASE(4,1) dest[0]=compute_y(src[0],src[1],src[2]); break; - CASE(4,2) dest[0]=compute_y(src[0],src[1],src[2]), dest[1] = src[3]; break; - CASE(4,3) dest[0]=src[0],dest[1]=src[1],dest[2]=src[2]; break; - default: assert(0); - } - #undef CASE - } +#define COMBO(a, b) ((a)*8 + (b)) +#define CASE(a, b) \ + case COMBO(a, b): \ + for (i = x - 1; i >= 0; --i, src += a, dest += b) + // convert source image with img_n components to one with req_comp components; + // avoid switch per pixel, so use switch per scanline and massive macros + switch (COMBO(img_n, req_comp)) + { + CASE(1, 2) + dest[0] = src[0], + dest[1] = 255; + break; + CASE(1, 3) + dest[0] = dest[1] = dest[2] = src[0]; + break; + CASE(1, 4) + dest[0] = dest[1] = dest[2] = src[0], + dest[3] = 255; + break; + CASE(2, 1) + dest[0] = src[0]; + break; + CASE(2, 3) + dest[0] = dest[1] = dest[2] = src[0]; + break; + CASE(2, 4) + dest[0] = dest[1] = dest[2] = src[0], + dest[3] = src[1]; + break; + CASE(3, 4) + dest[0] = src[0], + dest[1] = src[1], dest[2] = src[2], dest[3] = 255; + break; + CASE(3, 1) + dest[0] = compute_y(src[0], src[1], src[2]); + break; + CASE(3, 2) + dest[0] = compute_y(src[0], src[1], src[2]), + dest[1] = 255; + break; + CASE(4, 1) + dest[0] = compute_y(src[0], src[1], src[2]); + break; + CASE(4, 2) + dest[0] = compute_y(src[0], src[1], src[2]), + dest[1] = src[3]; + break; + CASE(4, 3) + dest[0] = src[0], + dest[1] = src[1], dest[2] = src[2]; + break; + default: + assert(0); + } +#undef CASE + } - free(data); - return good; + free(data); + return good; } #ifndef STBI_NO_HDR -static float *ldr_to_hdr(stbi_uc *data, int x, int y, int comp) +static float *ldr_to_hdr(stbi_uc *data, int x, int y, int comp) { - int i,k,n; - float *output = (float *) malloc(x * y * comp * sizeof(float)); - if (output == NULL) { free(data); return epf("outofmem", "Out of memory"); } - // compute number of non-alpha components - if (comp & 1) n = comp; else n = comp-1; - for (i=0; i < x*y; ++i) { - for (k=0; k < n; ++k) { - output[i*comp + k] = (float) pow(data[i*comp+k]/255.0f, l2h_gamma) * l2h_scale; - } - if (k < comp) output[i*comp + k] = data[i*comp+k]/255.0f; - } - free(data); - return output; + int i, k, n; + float *output = (float *)malloc(x * y * comp * sizeof(float)); + if (output == NULL) + { + free(data); + return epf("outofmem", "Out of memory"); + } + // compute number of non-alpha components + if (comp & 1) + n = comp; + else + n = comp - 1; + for (i = 0; i < x * y; ++i) + { + for (k = 0; k < n; ++k) + { + output[i * comp + k] = (float)pow(data[i * comp + k] / 255.0f, l2h_gamma) * l2h_scale; + } + if (k < comp) output[i * comp + k] = data[i * comp + k] / 255.0f; + } + free(data); + return output; } -#define float2int(x) ((int) (x)) -static stbi_uc *hdr_to_ldr(float *data, int x, int y, int comp) +#define float2int(x) ((int)(x)) +static stbi_uc *hdr_to_ldr(float *data, int x, int y, int comp) { - int i,k,n; - stbi_uc *output = (stbi_uc *) malloc(x * y * comp); - if (output == NULL) { free(data); return epuc("outofmem", "Out of memory"); } - // compute number of non-alpha components - if (comp & 1) n = comp; else n = comp-1; - for (i=0; i < x*y; ++i) { - for (k=0; k < n; ++k) { - float z = (float) pow(data[i*comp+k]*h2l_scale_i, h2l_gamma_i) * 255 + 0.5f; - if (z < 0) z = 0; - if (z > 255) z = 255; - output[i*comp + k] = (uint8) float2int(z); - } - if (k < comp) { - float z = data[i*comp+k] * 255 + 0.5f; - if (z < 0) z = 0; - if (z > 255) z = 255; - output[i*comp + k] = (uint8) float2int(z); - } - } - free(data); - return output; + int i, k, n; + stbi_uc *output = (stbi_uc *)malloc(x * y * comp); + if (output == NULL) + { + free(data); + return epuc("outofmem", "Out of memory"); + } + // compute number of non-alpha components + if (comp & 1) + n = comp; + else + n = comp - 1; + for (i = 0; i < x * y; ++i) + { + for (k = 0; k < n; ++k) + { + float z = (float)pow(data[i * comp + k] * h2l_scale_i, h2l_gamma_i) * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i * comp + k] = (uint8)float2int(z); + } + if (k < comp) + { + float z = data[i * comp + k] * 255 + 0.5f; + if (z < 0) z = 0; + if (z > 255) z = 255; + output[i * comp + k] = (uint8)float2int(z); + } + } + free(data); + return output; } #endif @@ -617,299 +682,313 @@ static stbi_uc *hdr_to_ldr(float *data, int x, int y, int comp) // IJG 1998: 0.95 seconds (MSVC6, makefile + proc=PPro) // huffman decoding acceleration -#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache +#define FAST_BITS 9 // larger handles more cases; smaller stomps less cache typedef struct { - uint8 fast[1 << FAST_BITS]; - // weirdly, repacking this into AoS is a 10% speed loss, instead of a win - uint16 code[256]; - uint8 values[256]; - uint8 size[257]; - unsigned int maxcode[18]; - int delta[17]; // old 'firstsymbol' - old 'firstcode' + uint8 fast[1 << FAST_BITS]; + // weirdly, repacking this into AoS is a 10% speed loss, instead of a win + uint16 code[256]; + uint8 values[256]; + uint8 size[257]; + unsigned int maxcode[18]; + int delta[17]; // old 'firstsymbol' - old 'firstcode' } huffman; typedef struct { - #ifdef STBI_SIMD - unsigned short dequant2[4][64]; - #endif - stbi *s; - huffman huff_dc[4]; - huffman huff_ac[4]; - uint8 dequant[4][64]; +#ifdef STBI_SIMD + unsigned short dequant2[4][64]; +#endif + stbi *s; + huffman huff_dc[4]; + huffman huff_ac[4]; + uint8 dequant[4][64]; -// sizes for components, interleaved MCUs - int img_h_max, img_v_max; - int img_mcu_x, img_mcu_y; - int img_mcu_w, img_mcu_h; + // sizes for components, interleaved MCUs + int img_h_max, img_v_max; + int img_mcu_x, img_mcu_y; + int img_mcu_w, img_mcu_h; -// definition of jpeg image component - struct - { - int id; - int h,v; - int tq; - int hd,ha; - int dc_pred; + // definition of jpeg image component + struct + { + int id; + int h, v; + int tq; + int hd, ha; + int dc_pred; - int x,y,w2,h2; - uint8 *data; - void *raw_data; - uint8 *linebuf; - } img_comp[4]; + int x, y, w2, h2; + uint8 *data; + void *raw_data; + uint8 *linebuf; + } img_comp[4]; - uint32 code_buffer; // jpeg entropy-coded buffer - int code_bits; // number of valid bits - unsigned char marker; // marker seen while filling entropy buffer - int nomore; // flag if we saw a marker so must stop + uint32 code_buffer; // jpeg entropy-coded buffer + int code_bits; // number of valid bits + unsigned char marker; // marker seen while filling entropy buffer + int nomore; // flag if we saw a marker so must stop - int scan_n, order[4]; - int restart_interval, todo; + int scan_n, order[4]; + int restart_interval, todo; } jpeg; static int build_huffman(huffman *h, int *count) { - int i,j,k=0,code; - // build size list for each symbol (from JPEG spec) - for (i=0; i < 16; ++i) - for (j=0; j < count[i]; ++j) - h->size[k++] = (uint8) (i+1); - h->size[k] = 0; + int i, j, k = 0, code; + // build size list for each symbol (from JPEG spec) + for (i = 0; i < 16; ++i) + for (j = 0; j < count[i]; ++j) + h->size[k++] = (uint8)(i + 1); + h->size[k] = 0; - // compute actual symbols (from jpeg spec) - code = 0; - k = 0; - for(j=1; j <= 16; ++j) { - // compute delta to add to code to compute symbol id - h->delta[j] = k - code; - if (h->size[k] == j) { - while (h->size[k] == j) - h->code[k++] = (uint16) (code++); - if (code-1 >= (1 << j)) return e("bad code lengths","Corrupt JPEG"); - } - // compute largest code + 1 for this size, preshifted as needed later - h->maxcode[j] = code << (16-j); - code <<= 1; - } - h->maxcode[j] = 0xffffffff; + // compute actual symbols (from jpeg spec) + code = 0; + k = 0; + for (j = 1; j <= 16; ++j) + { + // compute delta to add to code to compute symbol id + h->delta[j] = k - code; + if (h->size[k] == j) + { + while (h->size[k] == j) + h->code[k++] = (uint16)(code++); + if (code - 1 >= (1 << j)) return e("bad code lengths", "Corrupt JPEG"); + } + // compute largest code + 1 for this size, preshifted as needed later + h->maxcode[j] = code << (16 - j); + code <<= 1; + } + h->maxcode[j] = 0xffffffff; - // build non-spec acceleration table; 255 is flag for not-accelerated - memset(h->fast, 255, 1 << FAST_BITS); - for (i=0; i < k; ++i) { - int s = h->size[i]; - if (s <= FAST_BITS) { - int c = h->code[i] << (FAST_BITS-s); - int m = 1 << (FAST_BITS-s); - for (j=0; j < m; ++j) { - h->fast[c+j] = (uint8) i; - } - } - } - return 1; + // build non-spec acceleration table; 255 is flag for not-accelerated + memset(h->fast, 255, 1 << FAST_BITS); + for (i = 0; i < k; ++i) + { + int s = h->size[i]; + if (s <= FAST_BITS) + { + int c = h->code[i] << (FAST_BITS - s); + int m = 1 << (FAST_BITS - s); + for (j = 0; j < m; ++j) + { + h->fast[c + j] = (uint8)i; + } + } + } + return 1; } static void grow_buffer_unsafe(jpeg *j) { - do { - int b = j->nomore ? 0 : get8(j->s); - if (b == 0xff) { - int c = get8(j->s); - if (c != 0) { - j->marker = (unsigned char) c; - j->nomore = 1; - return; - } - } - j->code_buffer |= b << (24 - j->code_bits); - j->code_bits += 8; - } while (j->code_bits <= 24); + do + { + int b = j->nomore ? 0 : get8(j->s); + if (b == 0xff) + { + int c = get8(j->s); + if (c != 0) + { + j->marker = (unsigned char)c; + j->nomore = 1; + return; + } + } + j->code_buffer |= b << (24 - j->code_bits); + j->code_bits += 8; + } while (j->code_bits <= 24); } // (1 << n) - 1 -static uint32 bmask[17]={0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535}; +static uint32 bmask[17] = {0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535}; // decode a jpeg huffman value from the bitstream stbi_inline static int decode(jpeg *j, huffman *h) { - unsigned int temp; - int c,k; + unsigned int temp; + int c, k; - if (j->code_bits < 16) grow_buffer_unsafe(j); + if (j->code_bits < 16) grow_buffer_unsafe(j); - // look at the top FAST_BITS and determine what symbol ID it is, - // if the code is <= FAST_BITS - c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS)-1); - k = h->fast[c]; - if (k < 255) { - int s = h->size[k]; - if (s > j->code_bits) - return -1; - j->code_buffer <<= s; - j->code_bits -= s; - return h->values[k]; - } + // look at the top FAST_BITS and determine what symbol ID it is, + // if the code is <= FAST_BITS + c = (j->code_buffer >> (32 - FAST_BITS)) & ((1 << FAST_BITS) - 1); + k = h->fast[c]; + if (k < 255) + { + int s = h->size[k]; + if (s > j->code_bits) + return -1; + j->code_buffer <<= s; + j->code_bits -= s; + return h->values[k]; + } - // naive test is to shift the code_buffer down so k bits are - // valid, then test against maxcode. To speed this up, we've - // preshifted maxcode left so that it has (16-k) 0s at the - // end; in other words, regardless of the number of bits, it - // wants to be compared against something shifted to have 16; - // that way we don't need to shift inside the loop. - temp = j->code_buffer >> 16; - for (k=FAST_BITS+1 ; ; ++k) - if (temp < h->maxcode[k]) - break; - if (k == 17) { - // error! code not found - j->code_bits -= 16; - return -1; - } + // naive test is to shift the code_buffer down so k bits are + // valid, then test against maxcode. To speed this up, we've + // preshifted maxcode left so that it has (16-k) 0s at the + // end; in other words, regardless of the number of bits, it + // wants to be compared against something shifted to have 16; + // that way we don't need to shift inside the loop. + temp = j->code_buffer >> 16; + for (k = FAST_BITS + 1;; ++k) + if (temp < h->maxcode[k]) + break; + if (k == 17) + { + // error! code not found + j->code_bits -= 16; + return -1; + } - if (k > j->code_bits) - return -1; + if (k > j->code_bits) + return -1; - // convert the huffman code to the symbol id - c = ((j->code_buffer >> (32 - k)) & bmask[k]) + h->delta[k]; - assert((((j->code_buffer) >> (32 - h->size[c])) & bmask[h->size[c]]) == h->code[c]); + // convert the huffman code to the symbol id + c = ((j->code_buffer >> (32 - k)) & bmask[k]) + h->delta[k]; + assert((((j->code_buffer) >> (32 - h->size[c])) & bmask[h->size[c]]) == h->code[c]); - // convert the id to a symbol - j->code_bits -= k; - j->code_buffer <<= k; - return h->values[c]; + // convert the id to a symbol + j->code_bits -= k; + j->code_buffer <<= k; + return h->values[c]; } // combined JPEG 'receive' and JPEG 'extend', since baseline // always extends everything it receives. stbi_inline static int extend_receive(jpeg *j, int n) { - unsigned int m = 1 << (n-1); - unsigned int k; - if (j->code_bits < n) grow_buffer_unsafe(j); + unsigned int m = 1 << (n - 1); + unsigned int k; + if (j->code_bits < n) grow_buffer_unsafe(j); - #if 1 - k = stbi_lrot(j->code_buffer, n); - j->code_buffer = k & ~bmask[n]; - k &= bmask[n]; - j->code_bits -= n; - #else - k = (j->code_buffer >> (32 - n)) & bmask[n]; - j->code_bits -= n; - j->code_buffer <<= n; - #endif - // the following test is probably a random branch that won't - // predict well. I tried to table accelerate it but failed. - // maybe it's compiling as a conditional move? - if (k < m) - return (-1 << n) + k + 1; - else - return k; +#if 1 + k = stbi_lrot(j->code_buffer, n); + j->code_buffer = k & ~bmask[n]; + k &= bmask[n]; + j->code_bits -= n; +#else + k = (j->code_buffer >> (32 - n)) & bmask[n]; + j->code_bits -= n; + j->code_buffer <<= n; +#endif + // the following test is probably a random branch that won't + // predict well. I tried to table accelerate it but failed. + // maybe it's compiling as a conditional move? + if (k < m) + return (-1 << n) + k + 1; + else + return k; } // given a value that's at position X in the zigzag stream, // where does it appear in the 8x8 matrix coded as row-major? -static uint8 dezigzag[64+15] = -{ - 0, 1, 8, 16, 9, 2, 3, 10, - 17, 24, 32, 25, 18, 11, 4, 5, - 12, 19, 26, 33, 40, 48, 41, 34, - 27, 20, 13, 6, 7, 14, 21, 28, - 35, 42, 49, 56, 57, 50, 43, 36, - 29, 22, 15, 23, 30, 37, 44, 51, - 58, 59, 52, 45, 38, 31, 39, 46, - 53, 60, 61, 54, 47, 55, 62, 63, - // let corrupt input sample past end - 63, 63, 63, 63, 63, 63, 63, 63, - 63, 63, 63, 63, 63, 63, 63 -}; +static uint8 dezigzag[64 + 15] = + { + 0, 1, 8, 16, 9, 2, 3, 10, + 17, 24, 32, 25, 18, 11, 4, 5, + 12, 19, 26, 33, 40, 48, 41, 34, + 27, 20, 13, 6, 7, 14, 21, 28, + 35, 42, 49, 56, 57, 50, 43, 36, + 29, 22, 15, 23, 30, 37, 44, 51, + 58, 59, 52, 45, 38, 31, 39, 46, + 53, 60, 61, 54, 47, 55, 62, 63, + // let corrupt input sample past end + 63, 63, 63, 63, 63, 63, 63, 63, + 63, 63, 63, 63, 63, 63, 63}; // decode one 64-entry block-- static int decode_block(jpeg *j, short data[64], huffman *hdc, huffman *hac, int b) { - int diff,dc,k; - int t = decode(j, hdc); - if (t < 0) return e("bad huffman code","Corrupt JPEG"); + int diff, dc, k; + int t = decode(j, hdc); + if (t < 0) return e("bad huffman code", "Corrupt JPEG"); - // 0 all the ac values now so we can do it 32-bits at a time - memset(data,0,64*sizeof(data[0])); + // 0 all the ac values now so we can do it 32-bits at a time + memset(data, 0, 64 * sizeof(data[0])); - diff = t ? extend_receive(j, t) : 0; - dc = j->img_comp[b].dc_pred + diff; - j->img_comp[b].dc_pred = dc; - data[0] = (short) dc; + diff = t ? extend_receive(j, t) : 0; + dc = j->img_comp[b].dc_pred + diff; + j->img_comp[b].dc_pred = dc; + data[0] = (short)dc; - // decode AC components, see JPEG spec - k = 1; - do { - int r,s; - int rs = decode(j, hac); - if (rs < 0) return e("bad huffman code","Corrupt JPEG"); - s = rs & 15; - r = rs >> 4; - if (s == 0) { - if (rs != 0xf0) break; // end block - k += 16; - } else { - k += r; - // decode into unzigzag'd location - data[dezigzag[k++]] = (short) extend_receive(j,s); - } - } while (k < 64); - return 1; + // decode AC components, see JPEG spec + k = 1; + do + { + int r, s; + int rs = decode(j, hac); + if (rs < 0) return e("bad huffman code", "Corrupt JPEG"); + s = rs & 15; + r = rs >> 4; + if (s == 0) + { + if (rs != 0xf0) break; // end block + k += 16; + } + else + { + k += r; + // decode into unzigzag'd location + data[dezigzag[k++]] = (short)extend_receive(j, s); + } + } while (k < 64); + return 1; } // take a -128..127 value and clamp it and convert to 0..255 stbi_inline static uint8 clamp(int x) { - // trick to use a single test to catch both cases - if ((unsigned int) x > 255) { - if (x < 0) return 0; - if (x > 255) return 255; - } - return (uint8) x; + // trick to use a single test to catch both cases + if ((unsigned int)x > 255) + { + if (x < 0) return 0; + if (x > 255) return 255; + } + return (uint8)x; } -#define f2f(x) (int) (((x) * 4096 + 0.5)) -#define fsh(x) ((x) << 12) +#define f2f(x) (int)(((x)*4096 + 0.5)) +#define fsh(x) ((x) << 12) // derived from jidctint -- DCT_ISLOW -#define IDCT_1D(s0,s1,s2,s3,s4,s5,s6,s7) \ - int t0,t1,t2,t3,p1,p2,p3,p4,p5,x0,x1,x2,x3; \ - p2 = s2; \ - p3 = s6; \ - p1 = (p2+p3) * f2f(0.5411961f); \ - t2 = p1 + p3*f2f(-1.847759065f); \ - t3 = p1 + p2*f2f( 0.765366865f); \ - p2 = s0; \ - p3 = s4; \ - t0 = fsh(p2+p3); \ - t1 = fsh(p2-p3); \ - x0 = t0+t3; \ - x3 = t0-t3; \ - x1 = t1+t2; \ - x2 = t1-t2; \ - t0 = s7; \ - t1 = s5; \ - t2 = s3; \ - t3 = s1; \ - p3 = t0+t2; \ - p4 = t1+t3; \ - p1 = t0+t3; \ - p2 = t1+t2; \ - p5 = (p3+p4)*f2f( 1.175875602f); \ - t0 = t0*f2f( 0.298631336f); \ - t1 = t1*f2f( 2.053119869f); \ - t2 = t2*f2f( 3.072711026f); \ - t3 = t3*f2f( 1.501321110f); \ - p1 = p5 + p1*f2f(-0.899976223f); \ - p2 = p5 + p2*f2f(-2.562915447f); \ - p3 = p3*f2f(-1.961570560f); \ - p4 = p4*f2f(-0.390180644f); \ - t3 += p1+p4; \ - t2 += p2+p3; \ - t1 += p2+p4; \ - t0 += p1+p3; +#define IDCT_1D(s0, s1, s2, s3, s4, s5, s6, s7) \ + int t0, t1, t2, t3, p1, p2, p3, p4, p5, x0, x1, x2, x3; \ + p2 = s2; \ + p3 = s6; \ + p1 = (p2 + p3) * f2f(0.5411961f); \ + t2 = p1 + p3 * f2f(-1.847759065f); \ + t3 = p1 + p2 * f2f(0.765366865f); \ + p2 = s0; \ + p3 = s4; \ + t0 = fsh(p2 + p3); \ + t1 = fsh(p2 - p3); \ + x0 = t0 + t3; \ + x3 = t0 - t3; \ + x1 = t1 + t2; \ + x2 = t1 - t2; \ + t0 = s7; \ + t1 = s5; \ + t2 = s3; \ + t3 = s1; \ + p3 = t0 + t2; \ + p4 = t1 + t3; \ + p1 = t0 + t3; \ + p2 = t1 + t2; \ + p5 = (p3 + p4) * f2f(1.175875602f); \ + t0 = t0 * f2f(0.298631336f); \ + t1 = t1 * f2f(2.053119869f); \ + t2 = t2 * f2f(3.072711026f); \ + t3 = t3 * f2f(1.501321110f); \ + p1 = p5 + p1 * f2f(-0.899976223f); \ + p2 = p5 + p2 * f2f(-2.562915447f); \ + p3 = p3 * f2f(-1.961570560f); \ + p4 = p4 * f2f(-0.390180644f); \ + t3 += p1 + p4; \ + t2 += p2 + p3; \ + t1 += p2 + p4; \ + t0 += p1 + p3; #ifdef STBI_SIMD typedef unsigned short stbi_dequantize_t; @@ -920,63 +999,70 @@ typedef uint8 stbi_dequantize_t; // .344 seconds on 3*anemones.jpg static void idct_block(uint8 *out, int out_stride, short data[64], stbi_dequantize_t *dequantize) { - int i,val[64],*v=val; - stbi_dequantize_t *dq = dequantize; - uint8 *o; - short *d = data; + int i, val[64], *v = val; + stbi_dequantize_t *dq = dequantize; + uint8 *o; + short *d = data; - // columns - for (i=0; i < 8; ++i,++d,++dq, ++v) { - // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing - if (d[ 8]==0 && d[16]==0 && d[24]==0 && d[32]==0 - && d[40]==0 && d[48]==0 && d[56]==0) { - // no shortcut 0 seconds - // (1|2|3|4|5|6|7)==0 0 seconds - // all separate -0.047 seconds - // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds - int dcterm = d[0] * dq[0] << 2; - v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; - } else { - IDCT_1D(d[ 0]*dq[ 0],d[ 8]*dq[ 8],d[16]*dq[16],d[24]*dq[24], - d[32]*dq[32],d[40]*dq[40],d[48]*dq[48],d[56]*dq[56]) - // constants scaled things up by 1<<12; let's bring them back - // down, but keep 2 extra bits of precision - x0 += 512; x1 += 512; x2 += 512; x3 += 512; - v[ 0] = (x0+t3) >> 10; - v[56] = (x0-t3) >> 10; - v[ 8] = (x1+t2) >> 10; - v[48] = (x1-t2) >> 10; - v[16] = (x2+t1) >> 10; - v[40] = (x2-t1) >> 10; - v[24] = (x3+t0) >> 10; - v[32] = (x3-t0) >> 10; - } - } + // columns + for (i = 0; i < 8; ++i, ++d, ++dq, ++v) + { + // if all zeroes, shortcut -- this avoids dequantizing 0s and IDCTing + if (d[8] == 0 && d[16] == 0 && d[24] == 0 && d[32] == 0 && d[40] == 0 && d[48] == 0 && d[56] == 0) + { + // no shortcut 0 seconds + // (1|2|3|4|5|6|7)==0 0 seconds + // all separate -0.047 seconds + // 1 && 2|3 && 4|5 && 6|7: -0.047 seconds + int dcterm = d[0] * dq[0] << 2; + v[0] = v[8] = v[16] = v[24] = v[32] = v[40] = v[48] = v[56] = dcterm; + } + else + { + IDCT_1D(d[0] * dq[0], d[8] * dq[8], d[16] * dq[16], d[24] * dq[24], + d[32] * dq[32], d[40] * dq[40], d[48] * dq[48], d[56] * dq[56]) + // constants scaled things up by 1<<12; let's bring them back + // down, but keep 2 extra bits of precision + x0 += 512; + x1 += 512; + x2 += 512; + x3 += 512; + v[0] = (x0 + t3) >> 10; + v[56] = (x0 - t3) >> 10; + v[8] = (x1 + t2) >> 10; + v[48] = (x1 - t2) >> 10; + v[16] = (x2 + t1) >> 10; + v[40] = (x2 - t1) >> 10; + v[24] = (x3 + t0) >> 10; + v[32] = (x3 - t0) >> 10; + } + } - for (i=0, v=val, o=out; i < 8; ++i,v+=8,o+=out_stride) { - // no fast case since the first 1D IDCT spread components out - IDCT_1D(v[0],v[1],v[2],v[3],v[4],v[5],v[6],v[7]) - // constants scaled things up by 1<<12, plus we had 1<<2 from first - // loop, plus horizontal and vertical each scale by sqrt(8) so together - // we've got an extra 1<<3, so 1<<17 total we need to remove. - // so we want to round that, which means adding 0.5 * 1<<17, - // aka 65536. Also, we'll end up with -128 to 127 that we want - // to encode as 0..255 by adding 128, so we'll add that before the shift - x0 += 65536 + (128<<17); - x1 += 65536 + (128<<17); - x2 += 65536 + (128<<17); - x3 += 65536 + (128<<17); - // tried computing the shifts into temps, or'ing the temps to see - // if any were out of range, but that was slower - o[0] = clamp((x0+t3) >> 17); - o[7] = clamp((x0-t3) >> 17); - o[1] = clamp((x1+t2) >> 17); - o[6] = clamp((x1-t2) >> 17); - o[2] = clamp((x2+t1) >> 17); - o[5] = clamp((x2-t1) >> 17); - o[3] = clamp((x3+t0) >> 17); - o[4] = clamp((x3-t0) >> 17); - } + for (i = 0, v = val, o = out; i < 8; ++i, v += 8, o += out_stride) + { + // no fast case since the first 1D IDCT spread components out + IDCT_1D(v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]) + // constants scaled things up by 1<<12, plus we had 1<<2 from first + // loop, plus horizontal and vertical each scale by sqrt(8) so together + // we've got an extra 1<<3, so 1<<17 total we need to remove. + // so we want to round that, which means adding 0.5 * 1<<17, + // aka 65536. Also, we'll end up with -128 to 127 that we want + // to encode as 0..255 by adding 128, so we'll add that before the shift + x0 += 65536 + (128 << 17); + x1 += 65536 + (128 << 17); + x2 += 65536 + (128 << 17); + x3 += 65536 + (128 << 17); + // tried computing the shifts into temps, or'ing the temps to see + // if any were out of range, but that was slower + o[0] = clamp((x0 + t3) >> 17); + o[7] = clamp((x0 - t3) >> 17); + o[1] = clamp((x1 + t2) >> 17); + o[6] = clamp((x1 - t2) >> 17); + o[2] = clamp((x2 + t1) >> 17); + o[5] = clamp((x2 - t1) >> 17); + o[3] = clamp((x3 + t0) >> 17); + o[4] = clamp((x3 - t0) >> 17); + } } #ifdef STBI_SIMD @@ -984,457 +1070,532 @@ static stbi_idct_8x8 stbi_idct_installed = idct_block; void stbi_install_idct(stbi_idct_8x8 func) { - stbi_idct_installed = func; + stbi_idct_installed = func; } #endif -#define MARKER_none 0xff +#define MARKER_none 0xff // if there's a pending marker from the entropy stream, return that // otherwise, fetch from the stream and get a marker. if there's no // marker, return 0xff, which is never a valid marker value static uint8 get_marker(jpeg *j) { - uint8 x; - if (j->marker != MARKER_none) { x = j->marker; j->marker = MARKER_none; return x; } - x = get8u(j->s); - if (x != 0xff) return MARKER_none; - while (x == 0xff) - x = get8u(j->s); - return x; + uint8 x; + if (j->marker != MARKER_none) + { + x = j->marker; + j->marker = MARKER_none; + return x; + } + x = get8u(j->s); + if (x != 0xff) return MARKER_none; + while (x == 0xff) + x = get8u(j->s); + return x; } // in each scan, we'll have scan_n components, and the order // of the components is specified by order[] -#define RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) +#define RESTART(x) ((x) >= 0xd0 && (x) <= 0xd7) // after a restart interval, reset the entropy decoder and // the dc prediction static void reset(jpeg *j) { - j->code_bits = 0; - j->code_buffer = 0; - j->nomore = 0; - j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = 0; - j->marker = MARKER_none; - j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; - // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, - // since we don't even allow 1<<30 pixels + j->code_bits = 0; + j->code_buffer = 0; + j->nomore = 0; + j->img_comp[0].dc_pred = j->img_comp[1].dc_pred = j->img_comp[2].dc_pred = 0; + j->marker = MARKER_none; + j->todo = j->restart_interval ? j->restart_interval : 0x7fffffff; + // no more than 1<<31 MCUs if no restart_interal? that's plenty safe, + // since we don't even allow 1<<30 pixels } static int parse_entropy_coded_data(jpeg *z) { - reset(z); - if (z->scan_n == 1) { - int i,j; - #ifdef STBI_SIMD - __declspec(align(16)) - #endif - short data[64]; - int n = z->order[0]; - // non-interleaved data, we just need to process one block at a time, - // in trivial scanline order - // number of blocks to do just depends on how many actual "pixels" this - // component has, independent of interleaved MCU blocking and such - int w = (z->img_comp[n].x+7) >> 3; - int h = (z->img_comp[n].y+7) >> 3; - for (j=0; j < h; ++j) { - for (i=0; i < w; ++i) { - if (!decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+z->img_comp[n].ha, n)) return 0; - #ifdef STBI_SIMD - stbi_idct_installed(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data, z->dequant2[z->img_comp[n].tq]); - #else - idct_block(z->img_comp[n].data+z->img_comp[n].w2*j*8+i*8, z->img_comp[n].w2, data, z->dequant[z->img_comp[n].tq]); - #endif - // every data block is an MCU, so countdown the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) grow_buffer_unsafe(z); - // if it's NOT a restart, then just bail, so we get corrupt data - // rather than no data - if (!RESTART(z->marker)) return 1; - reset(z); - } - } - } - } else { // interleaved! - int i,j,k,x,y; - short data[64]; - for (j=0; j < z->img_mcu_y; ++j) { - for (i=0; i < z->img_mcu_x; ++i) { - // scan an interleaved mcu... process scan_n components in order - for (k=0; k < z->scan_n; ++k) { - int n = z->order[k]; - // scan out an mcu's worth of this component; that's just determined - // by the basic H and V specified for the component - for (y=0; y < z->img_comp[n].v; ++y) { - for (x=0; x < z->img_comp[n].h; ++x) { - int x2 = (i*z->img_comp[n].h + x)*8; - int y2 = (j*z->img_comp[n].v + y)*8; - if (!decode_block(z, data, z->huff_dc+z->img_comp[n].hd, z->huff_ac+z->img_comp[n].ha, n)) return 0; - #ifdef STBI_SIMD - stbi_idct_installed(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data, z->dequant2[z->img_comp[n].tq]); - #else - idct_block(z->img_comp[n].data+z->img_comp[n].w2*y2+x2, z->img_comp[n].w2, data, z->dequant[z->img_comp[n].tq]); - #endif - } - } - } - // after all interleaved components, that's an interleaved MCU, - // so now count down the restart interval - if (--z->todo <= 0) { - if (z->code_bits < 24) grow_buffer_unsafe(z); - // if it's NOT a restart, then just bail, so we get corrupt data - // rather than no data - if (!RESTART(z->marker)) return 1; - reset(z); - } - } - } - } - return 1; + reset(z); + if (z->scan_n == 1) + { + int i, j; +#ifdef STBI_SIMD + __declspec(align(16)) +#endif + short data[64]; + int n = z->order[0]; + // non-interleaved data, we just need to process one block at a time, + // in trivial scanline order + // number of blocks to do just depends on how many actual "pixels" this + // component has, independent of interleaved MCU blocking and such + int w = (z->img_comp[n].x + 7) >> 3; + int h = (z->img_comp[n].y + 7) >> 3; + for (j = 0; j < h; ++j) + { + for (i = 0; i < w; ++i) + { + if (!decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + z->img_comp[n].ha, n)) return 0; +#ifdef STBI_SIMD + stbi_idct_installed(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data, z->dequant2[z->img_comp[n].tq]); +#else + idct_block(z->img_comp[n].data + z->img_comp[n].w2 * j * 8 + i * 8, z->img_comp[n].w2, data, z->dequant[z->img_comp[n].tq]); +#endif + // every data block is an MCU, so countdown the restart interval + if (--z->todo <= 0) + { + if (z->code_bits < 24) grow_buffer_unsafe(z); + // if it's NOT a restart, then just bail, so we get corrupt data + // rather than no data + if (!RESTART(z->marker)) return 1; + reset(z); + } + } + } + } + else + { // interleaved! + int i, j, k, x, y; + short data[64]; + for (j = 0; j < z->img_mcu_y; ++j) + { + for (i = 0; i < z->img_mcu_x; ++i) + { + // scan an interleaved mcu... process scan_n components in order + for (k = 0; k < z->scan_n; ++k) + { + int n = z->order[k]; + // scan out an mcu's worth of this component; that's just determined + // by the basic H and V specified for the component + for (y = 0; y < z->img_comp[n].v; ++y) + { + for (x = 0; x < z->img_comp[n].h; ++x) + { + int x2 = (i * z->img_comp[n].h + x) * 8; + int y2 = (j * z->img_comp[n].v + y) * 8; + if (!decode_block(z, data, z->huff_dc + z->img_comp[n].hd, z->huff_ac + z->img_comp[n].ha, n)) return 0; +#ifdef STBI_SIMD + stbi_idct_installed(z->img_comp[n].data + z->img_comp[n].w2 * y2 + x2, z->img_comp[n].w2, data, z->dequant2[z->img_comp[n].tq]); +#else + idct_block(z->img_comp[n].data + z->img_comp[n].w2 * y2 + x2, z->img_comp[n].w2, data, z->dequant[z->img_comp[n].tq]); +#endif + } + } + } + // after all interleaved components, that's an interleaved MCU, + // so now count down the restart interval + if (--z->todo <= 0) + { + if (z->code_bits < 24) grow_buffer_unsafe(z); + // if it's NOT a restart, then just bail, so we get corrupt data + // rather than no data + if (!RESTART(z->marker)) return 1; + reset(z); + } + } + } + } + return 1; } static int process_marker(jpeg *z, int m) { - int L; - switch (m) { - case MARKER_none: // no marker found - return e("expected marker","Corrupt JPEG"); + int L; + switch (m) + { + case MARKER_none: // no marker found + return e("expected marker", "Corrupt JPEG"); - case 0xC2: // SOF - progressive - return e("progressive jpeg","JPEG format not supported (progressive)"); + case 0xC2: // SOF - progressive + return e("progressive jpeg", "JPEG format not supported (progressive)"); - case 0xDD: // DRI - specify restart interval - if (get16(z->s) != 4) return e("bad DRI len","Corrupt JPEG"); - z->restart_interval = get16(z->s); - return 1; + case 0xDD: // DRI - specify restart interval + if (get16(z->s) != 4) return e("bad DRI len", "Corrupt JPEG"); + z->restart_interval = get16(z->s); + return 1; - case 0xDB: // DQT - define quantization table - L = get16(z->s)-2; - while (L > 0) { - int q = get8(z->s); - int p = q >> 4; - int t = q & 15,i; - if (p != 0) return e("bad DQT type","Corrupt JPEG"); - if (t > 3) return e("bad DQT table","Corrupt JPEG"); - for (i=0; i < 64; ++i) - z->dequant[t][dezigzag[i]] = get8u(z->s); - #ifdef STBI_SIMD - for (i=0; i < 64; ++i) - z->dequant2[t][i] = z->dequant[t][i]; - #endif - L -= 65; - } - return L==0; + case 0xDB: // DQT - define quantization table + L = get16(z->s) - 2; + while (L > 0) + { + int q = get8(z->s); + int p = q >> 4; + int t = q & 15, i; + if (p != 0) return e("bad DQT type", "Corrupt JPEG"); + if (t > 3) return e("bad DQT table", "Corrupt JPEG"); + for (i = 0; i < 64; ++i) + z->dequant[t][dezigzag[i]] = get8u(z->s); +#ifdef STBI_SIMD + for (i = 0; i < 64; ++i) + z->dequant2[t][i] = z->dequant[t][i]; +#endif + L -= 65; + } + return L == 0; - case 0xC4: // DHT - define huffman table - L = get16(z->s)-2; - while (L > 0) { - uint8 *v; - int sizes[16],i,m=0; - int q = get8(z->s); - int tc = q >> 4; - int th = q & 15; - if (tc > 1 || th > 3) return e("bad DHT header","Corrupt JPEG"); - for (i=0; i < 16; ++i) { - sizes[i] = get8(z->s); - m += sizes[i]; - } - L -= 17; - if (tc == 0) { - if (!build_huffman(z->huff_dc+th, sizes)) return 0; - v = z->huff_dc[th].values; - } else { - if (!build_huffman(z->huff_ac+th, sizes)) return 0; - v = z->huff_ac[th].values; - } - for (i=0; i < m; ++i) - v[i] = get8u(z->s); - L -= m; - } - return L==0; - } - // check for comment block or APP blocks - if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) { - skip(z->s, get16(z->s)-2); - return 1; - } - return 0; + case 0xC4: // DHT - define huffman table + L = get16(z->s) - 2; + while (L > 0) + { + uint8 *v; + int sizes[16], i, m = 0; + int q = get8(z->s); + int tc = q >> 4; + int th = q & 15; + if (tc > 1 || th > 3) return e("bad DHT header", "Corrupt JPEG"); + for (i = 0; i < 16; ++i) + { + sizes[i] = get8(z->s); + m += sizes[i]; + } + L -= 17; + if (tc == 0) + { + if (!build_huffman(z->huff_dc + th, sizes)) return 0; + v = z->huff_dc[th].values; + } + else + { + if (!build_huffman(z->huff_ac + th, sizes)) return 0; + v = z->huff_ac[th].values; + } + for (i = 0; i < m; ++i) + v[i] = get8u(z->s); + L -= m; + } + return L == 0; + } + // check for comment block or APP blocks + if ((m >= 0xE0 && m <= 0xEF) || m == 0xFE) + { + skip(z->s, get16(z->s) - 2); + return 1; + } + return 0; } // after we see SOS static int process_scan_header(jpeg *z) { - int i; - int Ls = get16(z->s); - z->scan_n = get8(z->s); - if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int) z->s->img_n) return e("bad SOS component count","Corrupt JPEG"); - if (Ls != 6+2*z->scan_n) return e("bad SOS len","Corrupt JPEG"); - for (i=0; i < z->scan_n; ++i) { - int id = get8(z->s), which; - int q = get8(z->s); - for (which = 0; which < z->s->img_n; ++which) - if (z->img_comp[which].id == id) - break; - if (which == z->s->img_n) return 0; - z->img_comp[which].hd = q >> 4; if (z->img_comp[which].hd > 3) return e("bad DC huff","Corrupt JPEG"); - z->img_comp[which].ha = q & 15; if (z->img_comp[which].ha > 3) return e("bad AC huff","Corrupt JPEG"); - z->order[i] = which; - } - if (get8(z->s) != 0) return e("bad SOS","Corrupt JPEG"); - get8(z->s); // should be 63, but might be 0 - if (get8(z->s) != 0) return e("bad SOS","Corrupt JPEG"); + int i; + int Ls = get16(z->s); + z->scan_n = get8(z->s); + if (z->scan_n < 1 || z->scan_n > 4 || z->scan_n > (int)z->s->img_n) return e("bad SOS component count", "Corrupt JPEG"); + if (Ls != 6 + 2 * z->scan_n) return e("bad SOS len", "Corrupt JPEG"); + for (i = 0; i < z->scan_n; ++i) + { + int id = get8(z->s), which; + int q = get8(z->s); + for (which = 0; which < z->s->img_n; ++which) + if (z->img_comp[which].id == id) + break; + if (which == z->s->img_n) return 0; + z->img_comp[which].hd = q >> 4; + if (z->img_comp[which].hd > 3) return e("bad DC huff", "Corrupt JPEG"); + z->img_comp[which].ha = q & 15; + if (z->img_comp[which].ha > 3) return e("bad AC huff", "Corrupt JPEG"); + z->order[i] = which; + } + if (get8(z->s) != 0) return e("bad SOS", "Corrupt JPEG"); + get8(z->s); // should be 63, but might be 0 + if (get8(z->s) != 0) return e("bad SOS", "Corrupt JPEG"); - return 1; + return 1; } static int process_frame_header(jpeg *z, int scan) { - stbi *s = z->s; - int Lf,p,i,q, h_max=1,v_max=1,c; - Lf = get16(s); if (Lf < 11) return e("bad SOF len","Corrupt JPEG"); // JPEG - p = get8(s); if (p != 8) return e("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline - s->img_y = get16(s); if (s->img_y == 0) return e("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG - s->img_x = get16(s); if (s->img_x == 0) return e("0 width","Corrupt JPEG"); // JPEG requires - c = get8(s); - if (c != 3 && c != 1) return e("bad component count","Corrupt JPEG"); // JFIF requires - s->img_n = c; - for (i=0; i < c; ++i) { - z->img_comp[i].data = NULL; - z->img_comp[i].linebuf = NULL; - } + stbi *s = z->s; + int Lf, p, i, q, h_max = 1, v_max = 1, c; + Lf = get16(s); + if (Lf < 11) return e("bad SOF len", "Corrupt JPEG"); // JPEG + p = get8(s); + if (p != 8) return e("only 8-bit", "JPEG format not supported: 8-bit only"); // JPEG baseline + s->img_y = get16(s); + if (s->img_y == 0) return e("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG + s->img_x = get16(s); + if (s->img_x == 0) return e("0 width", "Corrupt JPEG"); // JPEG requires + c = get8(s); + if (c != 3 && c != 1) return e("bad component count", "Corrupt JPEG"); // JFIF requires + s->img_n = c; + for (i = 0; i < c; ++i) + { + z->img_comp[i].data = NULL; + z->img_comp[i].linebuf = NULL; + } - if (Lf != 8+3*s->img_n) return e("bad SOF len","Corrupt JPEG"); + if (Lf != 8 + 3 * s->img_n) return e("bad SOF len", "Corrupt JPEG"); - for (i=0; i < s->img_n; ++i) { - z->img_comp[i].id = get8(s); - if (z->img_comp[i].id != i+1) // JFIF requires - if (z->img_comp[i].id != i) // some version of jpegtran outputs non-JFIF-compliant files! - return e("bad component ID","Corrupt JPEG"); - q = get8(s); - z->img_comp[i].h = (q >> 4); if (!z->img_comp[i].h || z->img_comp[i].h > 4) return e("bad H","Corrupt JPEG"); - z->img_comp[i].v = q & 15; if (!z->img_comp[i].v || z->img_comp[i].v > 4) return e("bad V","Corrupt JPEG"); - z->img_comp[i].tq = get8(s); if (z->img_comp[i].tq > 3) return e("bad TQ","Corrupt JPEG"); - } + for (i = 0; i < s->img_n; ++i) + { + z->img_comp[i].id = get8(s); + if (z->img_comp[i].id != i + 1) // JFIF requires + if (z->img_comp[i].id != i) // some version of jpegtran outputs non-JFIF-compliant files! + return e("bad component ID", "Corrupt JPEG"); + q = get8(s); + z->img_comp[i].h = (q >> 4); + if (!z->img_comp[i].h || z->img_comp[i].h > 4) return e("bad H", "Corrupt JPEG"); + z->img_comp[i].v = q & 15; + if (!z->img_comp[i].v || z->img_comp[i].v > 4) return e("bad V", "Corrupt JPEG"); + z->img_comp[i].tq = get8(s); + if (z->img_comp[i].tq > 3) return e("bad TQ", "Corrupt JPEG"); + } - if (scan != SCAN_load) return 1; + if (scan != SCAN_load) return 1; - if ((1 << 30) / s->img_x / s->img_n < s->img_y) return e("too large", "Image too large to decode"); + if ((1 << 30) / s->img_x / s->img_n < s->img_y) return e("too large", "Image too large to decode"); - for (i=0; i < s->img_n; ++i) { - if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; - if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; - } + for (i = 0; i < s->img_n; ++i) + { + if (z->img_comp[i].h > h_max) h_max = z->img_comp[i].h; + if (z->img_comp[i].v > v_max) v_max = z->img_comp[i].v; + } - // compute interleaved mcu info - z->img_h_max = h_max; - z->img_v_max = v_max; - z->img_mcu_w = h_max * 8; - z->img_mcu_h = v_max * 8; - z->img_mcu_x = (s->img_x + z->img_mcu_w-1) / z->img_mcu_w; - z->img_mcu_y = (s->img_y + z->img_mcu_h-1) / z->img_mcu_h; + // compute interleaved mcu info + z->img_h_max = h_max; + z->img_v_max = v_max; + z->img_mcu_w = h_max * 8; + z->img_mcu_h = v_max * 8; + z->img_mcu_x = (s->img_x + z->img_mcu_w - 1) / z->img_mcu_w; + z->img_mcu_y = (s->img_y + z->img_mcu_h - 1) / z->img_mcu_h; - for (i=0; i < s->img_n; ++i) { - // number of effective pixels (e.g. for non-interleaved MCU) - z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max-1) / h_max; - z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max-1) / v_max; - // to simplify generation, we'll allocate enough memory to decode - // the bogus oversized data from using interleaved MCUs and their - // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't - // discard the extra data until colorspace conversion - z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; - z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; - z->img_comp[i].raw_data = malloc(z->img_comp[i].w2 * z->img_comp[i].h2+15); - if (z->img_comp[i].raw_data == NULL) { - for(--i; i >= 0; --i) { - free(z->img_comp[i].raw_data); - z->img_comp[i].data = NULL; - } - return e("outofmem", "Out of memory"); - } - // align blocks for installable-idct using mmx/sse - z->img_comp[i].data = (uint8*) (((size_t) z->img_comp[i].raw_data + 15) & ~15); - z->img_comp[i].linebuf = NULL; - } + for (i = 0; i < s->img_n; ++i) + { + // number of effective pixels (e.g. for non-interleaved MCU) + z->img_comp[i].x = (s->img_x * z->img_comp[i].h + h_max - 1) / h_max; + z->img_comp[i].y = (s->img_y * z->img_comp[i].v + v_max - 1) / v_max; + // to simplify generation, we'll allocate enough memory to decode + // the bogus oversized data from using interleaved MCUs and their + // big blocks (e.g. a 16x16 iMCU on an image of width 33); we won't + // discard the extra data until colorspace conversion + z->img_comp[i].w2 = z->img_mcu_x * z->img_comp[i].h * 8; + z->img_comp[i].h2 = z->img_mcu_y * z->img_comp[i].v * 8; + z->img_comp[i].raw_data = malloc(z->img_comp[i].w2 * z->img_comp[i].h2 + 15); + if (z->img_comp[i].raw_data == NULL) + { + for (--i; i >= 0; --i) + { + free(z->img_comp[i].raw_data); + z->img_comp[i].data = NULL; + } + return e("outofmem", "Out of memory"); + } + // align blocks for installable-idct using mmx/sse + z->img_comp[i].data = (uint8 *)(((size_t)z->img_comp[i].raw_data + 15) & ~15); + z->img_comp[i].linebuf = NULL; + } - return 1; + return 1; } // use comparisons since in some cases we handle more than one case (e.g. SOF) -#define DNL(x) ((x) == 0xdc) -#define SOI(x) ((x) == 0xd8) -#define EOI(x) ((x) == 0xd9) -#define SOF(x) ((x) == 0xc0 || (x) == 0xc1) -#define SOS(x) ((x) == 0xda) +#define DNL(x) ((x) == 0xdc) +#define SOI(x) ((x) == 0xd8) +#define EOI(x) ((x) == 0xd9) +#define SOF(x) ((x) == 0xc0 || (x) == 0xc1) +#define SOS(x) ((x) == 0xda) static int decode_jpeg_header(jpeg *z, int scan) { - int m; - z->marker = MARKER_none; // initialize cached marker to empty - m = get_marker(z); - if (!SOI(m)) return e("no SOI","Corrupt JPEG"); - if (scan == SCAN_type) return 1; - m = get_marker(z); - while (!SOF(m)) { - if (!process_marker(z,m)) return 0; - m = get_marker(z); - while (m == MARKER_none) { - // some files have extra padding after their blocks, so ok, we'll scan - if (at_eof(z->s)) return e("no SOF", "Corrupt JPEG"); - m = get_marker(z); - } - } - if (!process_frame_header(z, scan)) return 0; - return 1; + int m; + z->marker = MARKER_none; // initialize cached marker to empty + m = get_marker(z); + if (!SOI(m)) return e("no SOI", "Corrupt JPEG"); + if (scan == SCAN_type) return 1; + m = get_marker(z); + while (!SOF(m)) + { + if (!process_marker(z, m)) return 0; + m = get_marker(z); + while (m == MARKER_none) + { + // some files have extra padding after their blocks, so ok, we'll scan + if (at_eof(z->s)) return e("no SOF", "Corrupt JPEG"); + m = get_marker(z); + } + } + if (!process_frame_header(z, scan)) return 0; + return 1; } static int decode_jpeg_image(jpeg *j) { - int m; - j->restart_interval = 0; - if (!decode_jpeg_header(j, SCAN_load)) return 0; - m = get_marker(j); - while (!EOI(m)) { - if (SOS(m)) { - if (!process_scan_header(j)) return 0; - if (!parse_entropy_coded_data(j)) return 0; - if (j->marker == MARKER_none ) { - // handle 0s at the end of image data from IP Kamera 9060 - while (!at_eof(j->s)) { - int x = get8(j->s); - if (x == 255) { - j->marker = get8u(j->s); - break; - } else if (x != 0) { - return 0; - } - } - // if we reach eof without hitting a marker, get_marker() below will fail and we'll eventually return 0 - } - } else { - if (!process_marker(j, m)) return 0; - } - m = get_marker(j); - } - return 1; + int m; + j->restart_interval = 0; + if (!decode_jpeg_header(j, SCAN_load)) return 0; + m = get_marker(j); + while (!EOI(m)) + { + if (SOS(m)) + { + if (!process_scan_header(j)) return 0; + if (!parse_entropy_coded_data(j)) return 0; + if (j->marker == MARKER_none) + { + // handle 0s at the end of image data from IP Kamera 9060 + while (!at_eof(j->s)) + { + int x = get8(j->s); + if (x == 255) + { + j->marker = get8u(j->s); + break; + } + else if (x != 0) + { + return 0; + } + } + // if we reach eof without hitting a marker, get_marker() below will fail and we'll eventually return 0 + } + } + else + { + if (!process_marker(j, m)) return 0; + } + m = get_marker(j); + } + return 1; } // static jfif-centered resampling (across block boundaries) typedef uint8 *(*resample_row_func)(uint8 *out, uint8 *in0, uint8 *in1, - int w, int hs); + int w, int hs); -#define div4(x) ((uint8) ((x) >> 2)) +#define div4(x) ((uint8)((x) >> 2)) static uint8 *resample_row_1(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) { - STBI_NOTUSED(out); - STBI_NOTUSED(in_far); - STBI_NOTUSED(w); - STBI_NOTUSED(hs); - return in_near; + STBI_NOTUSED(out); + STBI_NOTUSED(in_far); + STBI_NOTUSED(w); + STBI_NOTUSED(hs); + return in_near; } -static uint8* resample_row_v_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) +static uint8 *resample_row_v_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) { - // need to generate two samples vertically for every one in input - int i; - STBI_NOTUSED(hs); - for (i=0; i < w; ++i) - out[i] = div4(3*in_near[i] + in_far[i] + 2); - return out; + // need to generate two samples vertically for every one in input + int i; + STBI_NOTUSED(hs); + for (i = 0; i < w; ++i) + out[i] = div4(3 * in_near[i] + in_far[i] + 2); + return out; } -static uint8* resample_row_h_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) +static uint8 *resample_row_h_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) { - // need to generate two samples horizontally for every one in input - int i; - uint8 *input = in_near; + // need to generate two samples horizontally for every one in input + int i; + uint8 *input = in_near; - if (w == 1) { - // if only one sample, can't do any interpolation - out[0] = out[1] = input[0]; - return out; - } + if (w == 1) + { + // if only one sample, can't do any interpolation + out[0] = out[1] = input[0]; + return out; + } - out[0] = input[0]; - out[1] = div4(input[0]*3 + input[1] + 2); - for (i=1; i < w-1; ++i) { - int n = 3*input[i]+2; - out[i*2+0] = div4(n+input[i-1]); - out[i*2+1] = div4(n+input[i+1]); - } - out[i*2+0] = div4(input[w-2]*3 + input[w-1] + 2); - out[i*2+1] = input[w-1]; + out[0] = input[0]; + out[1] = div4(input[0] * 3 + input[1] + 2); + for (i = 1; i < w - 1; ++i) + { + int n = 3 * input[i] + 2; + out[i * 2 + 0] = div4(n + input[i - 1]); + out[i * 2 + 1] = div4(n + input[i + 1]); + } + out[i * 2 + 0] = div4(input[w - 2] * 3 + input[w - 1] + 2); + out[i * 2 + 1] = input[w - 1]; - STBI_NOTUSED(in_far); - STBI_NOTUSED(hs); + STBI_NOTUSED(in_far); + STBI_NOTUSED(hs); - return out; + return out; } -#define div16(x) ((uint8) ((x) >> 4)) +#define div16(x) ((uint8)((x) >> 4)) static uint8 *resample_row_hv_2(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) { - // need to generate 2x2 samples for every one in input - int i,t0,t1; - if (w == 1) { - out[0] = out[1] = div4(3*in_near[0] + in_far[0] + 2); - return out; - } + // need to generate 2x2 samples for every one in input + int i, t0, t1; + if (w == 1) + { + out[0] = out[1] = div4(3 * in_near[0] + in_far[0] + 2); + return out; + } - t1 = 3*in_near[0] + in_far[0]; - out[0] = div4(t1+2); - for (i=1; i < w; ++i) { - t0 = t1; - t1 = 3*in_near[i]+in_far[i]; - out[i*2-1] = div16(3*t0 + t1 + 8); - out[i*2 ] = div16(3*t1 + t0 + 8); - } - out[w*2-1] = div4(t1+2); + t1 = 3 * in_near[0] + in_far[0]; + out[0] = div4(t1 + 2); + for (i = 1; i < w; ++i) + { + t0 = t1; + t1 = 3 * in_near[i] + in_far[i]; + out[i * 2 - 1] = div16(3 * t0 + t1 + 8); + out[i * 2] = div16(3 * t1 + t0 + 8); + } + out[w * 2 - 1] = div4(t1 + 2); - STBI_NOTUSED(hs); + STBI_NOTUSED(hs); - return out; + return out; } static uint8 *resample_row_generic(uint8 *out, uint8 *in_near, uint8 *in_far, int w, int hs) { - // resample with nearest-neighbor - int i,j; - for (i=0; i < w; ++i) - for (j=0; j < hs; ++j) - out[i*hs+j] = in_near[i]; - return out; + // resample with nearest-neighbor + int i, j; + for (i = 0; i < w; ++i) + for (j = 0; j < hs; ++j) + out[i * hs + j] = in_near[i]; + return out; } -#define float2fixed(x) ((int) ((x) * 65536 + 0.5)) +#define float2fixed(x) ((int)((x)*65536 + 0.5)) // 0.38 seconds on 3*anemones.jpg (0.25 with processor = Pro) // VC6 without processor=Pro is generating multiple LEAs per multiply! static void YCbCr_to_RGB_row(uint8 *out, const uint8 *y, const uint8 *pcb, const uint8 *pcr, int count, int step) { - int i; - for (i=0; i < count; ++i) { - int y_fixed = (y[i] << 16) + 32768; // rounding - int r,g,b; - int cr = pcr[i] - 128; - int cb = pcb[i] - 128; - r = y_fixed + cr*float2fixed(1.40200f); - g = y_fixed - cr*float2fixed(0.71414f) - cb*float2fixed(0.34414f); - b = y_fixed + cb*float2fixed(1.77200f); - r >>= 16; - g >>= 16; - b >>= 16; - if ((unsigned) r > 255) { if (r < 0) r = 0; else r = 255; } - if ((unsigned) g > 255) { if (g < 0) g = 0; else g = 255; } - if ((unsigned) b > 255) { if (b < 0) b = 0; else b = 255; } - out[0] = (uint8)r; - out[1] = (uint8)g; - out[2] = (uint8)b; - out[3] = 255; - out += step; - } + int i; + for (i = 0; i < count; ++i) + { + int y_fixed = (y[i] << 16) + 32768; // rounding + int r, g, b; + int cr = pcr[i] - 128; + int cb = pcb[i] - 128; + r = y_fixed + cr * float2fixed(1.40200f); + g = y_fixed - cr * float2fixed(0.71414f) - cb * float2fixed(0.34414f); + b = y_fixed + cb * float2fixed(1.77200f); + r >>= 16; + g >>= 16; + b >>= 16; + if ((unsigned)r > 255) + { + if (r < 0) + r = 0; + else + r = 255; + } + if ((unsigned)g > 255) + { + if (g < 0) + g = 0; + else + g = 255; + } + if ((unsigned)b > 255) + { + if (b < 0) + b = 0; + else + b = 255; + } + out[0] = (uint8)r; + out[1] = (uint8)g; + out[2] = (uint8)b; + out[3] = 255; + out += step; + } } #ifdef STBI_SIMD @@ -1442,171 +1603,201 @@ static stbi_YCbCr_to_RGB_run stbi_YCbCr_installed = YCbCr_to_RGB_row; void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func) { - stbi_YCbCr_installed = func; + stbi_YCbCr_installed = func; } #endif - // clean up the temporary component buffers static void cleanup_jpeg(jpeg *j) { - int i; - for (i=0; i < j->s->img_n; ++i) { - if (j->img_comp[i].data) { - free(j->img_comp[i].raw_data); - j->img_comp[i].data = NULL; - } - if (j->img_comp[i].linebuf) { - free(j->img_comp[i].linebuf); - j->img_comp[i].linebuf = NULL; - } - } + int i; + for (i = 0; i < j->s->img_n; ++i) + { + if (j->img_comp[i].data) + { + free(j->img_comp[i].raw_data); + j->img_comp[i].data = NULL; + } + if (j->img_comp[i].linebuf) + { + free(j->img_comp[i].linebuf); + j->img_comp[i].linebuf = NULL; + } + } } typedef struct { - resample_row_func resample; - uint8 *line0,*line1; - int hs,vs; // expansion factor in each axis - int w_lores; // horizontal pixels pre-expansion - int ystep; // how far through vertical expansion we are - int ypos; // which pre-expansion row we're on + resample_row_func resample; + uint8 *line0, *line1; + int hs, vs; // expansion factor in each axis + int w_lores; // horizontal pixels pre-expansion + int ystep; // how far through vertical expansion we are + int ypos; // which pre-expansion row we're on } stbi_resample; static uint8 *load_jpeg_image(jpeg *z, int *out_x, int *out_y, int *comp, int req_comp) { - int n, decode_n; - // validate req_comp - if (req_comp < 0 || req_comp > 4) return epuc("bad req_comp", "Internal error"); - z->s->img_n = 0; + int n, decode_n; + // validate req_comp + if (req_comp < 0 || req_comp > 4) return epuc("bad req_comp", "Internal error"); + z->s->img_n = 0; - // load a jpeg image from whichever source - if (!decode_jpeg_image(z)) { cleanup_jpeg(z); return NULL; } + // load a jpeg image from whichever source + if (!decode_jpeg_image(z)) + { + cleanup_jpeg(z); + return NULL; + } - // determine actual number of components to generate - n = req_comp ? req_comp : z->s->img_n; + // determine actual number of components to generate + n = req_comp ? req_comp : z->s->img_n; - if (z->s->img_n == 3 && n < 3) - decode_n = 1; - else - decode_n = z->s->img_n; + if (z->s->img_n == 3 && n < 3) + decode_n = 1; + else + decode_n = z->s->img_n; - // resample and color-convert - { - int k; - uint i,j; - uint8 *output; - uint8 *coutput[4]; + // resample and color-convert + { + int k; + uint i, j; + uint8 *output; + uint8 *coutput[4]; - stbi_resample res_comp[4]; + stbi_resample res_comp[4]; - for (k=0; k < decode_n; ++k) { - stbi_resample *r = &res_comp[k]; + for (k = 0; k < decode_n; ++k) + { + stbi_resample *r = &res_comp[k]; - // allocate line buffer big enough for upsampling off the edges - // with upsample factor of 4 - z->img_comp[k].linebuf = (uint8 *) malloc(z->s->img_x + 3); - if (!z->img_comp[k].linebuf) { cleanup_jpeg(z); return epuc("outofmem", "Out of memory"); } + // allocate line buffer big enough for upsampling off the edges + // with upsample factor of 4 + z->img_comp[k].linebuf = (uint8 *)malloc(z->s->img_x + 3); + if (!z->img_comp[k].linebuf) + { + cleanup_jpeg(z); + return epuc("outofmem", "Out of memory"); + } - r->hs = z->img_h_max / z->img_comp[k].h; - r->vs = z->img_v_max / z->img_comp[k].v; - r->ystep = r->vs >> 1; - r->w_lores = (z->s->img_x + r->hs-1) / r->hs; - r->ypos = 0; - r->line0 = r->line1 = z->img_comp[k].data; + r->hs = z->img_h_max / z->img_comp[k].h; + r->vs = z->img_v_max / z->img_comp[k].v; + r->ystep = r->vs >> 1; + r->w_lores = (z->s->img_x + r->hs - 1) / r->hs; + r->ypos = 0; + r->line0 = r->line1 = z->img_comp[k].data; - if (r->hs == 1 && r->vs == 1) r->resample = resample_row_1; - else if (r->hs == 1 && r->vs == 2) r->resample = resample_row_v_2; - else if (r->hs == 2 && r->vs == 1) r->resample = resample_row_h_2; - else if (r->hs == 2 && r->vs == 2) r->resample = resample_row_hv_2; - else r->resample = resample_row_generic; - } + if (r->hs == 1 && r->vs == 1) + r->resample = resample_row_1; + else if (r->hs == 1 && r->vs == 2) + r->resample = resample_row_v_2; + else if (r->hs == 2 && r->vs == 1) + r->resample = resample_row_h_2; + else if (r->hs == 2 && r->vs == 2) + r->resample = resample_row_hv_2; + else + r->resample = resample_row_generic; + } - // can't error after this so, this is safe - output = (uint8 *) malloc(n * z->s->img_x * z->s->img_y + 1); - if (!output) { cleanup_jpeg(z); return epuc("outofmem", "Out of memory"); } + // can't error after this so, this is safe + output = (uint8 *)malloc(n * z->s->img_x * z->s->img_y + 1); + if (!output) + { + cleanup_jpeg(z); + return epuc("outofmem", "Out of memory"); + } - // now go ahead and resample - for (j=0; j < z->s->img_y; ++j) { - uint8 *out = output + n * z->s->img_x * j; - for (k=0; k < decode_n; ++k) { - stbi_resample *r = &res_comp[k]; - int y_bot = r->ystep >= (r->vs >> 1); - coutput[k] = r->resample(z->img_comp[k].linebuf, - y_bot ? r->line1 : r->line0, - y_bot ? r->line0 : r->line1, - r->w_lores, r->hs); - if (++r->ystep >= r->vs) { - r->ystep = 0; - r->line0 = r->line1; - if (++r->ypos < z->img_comp[k].y) - r->line1 += z->img_comp[k].w2; - } - } - if (n >= 3) { - uint8 *y = coutput[0]; - if (z->s->img_n == 3) { - #ifdef STBI_SIMD - stbi_YCbCr_installed(out, y, coutput[1], coutput[2], z->s.img_x, n); - #else - YCbCr_to_RGB_row(out, y, coutput[1], coutput[2], z->s->img_x, n); - #endif - } else - for (i=0; i < z->s->img_x; ++i) { - out[0] = out[1] = out[2] = y[i]; - out[3] = 255; // not used if n==3 - out += n; - } - } else { - uint8 *y = coutput[0]; - if (n == 1) - for (i=0; i < z->s->img_x; ++i) out[i] = y[i]; - else - for (i=0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255; - } - } - cleanup_jpeg(z); - *out_x = z->s->img_x; - *out_y = z->s->img_y; - if (comp) *comp = z->s->img_n; // report original components, not output - return output; - } + // now go ahead and resample + for (j = 0; j < z->s->img_y; ++j) + { + uint8 *out = output + n * z->s->img_x * j; + for (k = 0; k < decode_n; ++k) + { + stbi_resample *r = &res_comp[k]; + int y_bot = r->ystep >= (r->vs >> 1); + coutput[k] = r->resample(z->img_comp[k].linebuf, + y_bot ? r->line1 : r->line0, + y_bot ? r->line0 : r->line1, + r->w_lores, r->hs); + if (++r->ystep >= r->vs) + { + r->ystep = 0; + r->line0 = r->line1; + if (++r->ypos < z->img_comp[k].y) + r->line1 += z->img_comp[k].w2; + } + } + if (n >= 3) + { + uint8 *y = coutput[0]; + if (z->s->img_n == 3) + { +#ifdef STBI_SIMD + stbi_YCbCr_installed(out, y, coutput[1], coutput[2], z->s.img_x, n); +#else + YCbCr_to_RGB_row(out, y, coutput[1], coutput[2], z->s->img_x, n); +#endif + } + else + for (i = 0; i < z->s->img_x; ++i) + { + out[0] = out[1] = out[2] = y[i]; + out[3] = 255; // not used if n==3 + out += n; + } + } + else + { + uint8 *y = coutput[0]; + if (n == 1) + for (i = 0; i < z->s->img_x; ++i) out[i] = y[i]; + else + for (i = 0; i < z->s->img_x; ++i) *out++ = y[i], *out++ = 255; + } + } + cleanup_jpeg(z); + *out_x = z->s->img_x; + *out_y = z->s->img_y; + if (comp) *comp = z->s->img_n; // report original components, not output + return output; + } } static unsigned char *stbi_jpeg_load(stbi *s, int *x, int *y, int *comp, int req_comp) { - jpeg j; - j.s = s; - return load_jpeg_image(&j, x,y,comp,req_comp); + jpeg j; + j.s = s; + return load_jpeg_image(&j, x, y, comp, req_comp); } static int stbi_jpeg_test(stbi *s) { - int r; - jpeg j; - j.s = s; - r = decode_jpeg_header(&j, SCAN_type); - stbi_rewind(s); - return r; + int r; + jpeg j; + j.s = s; + r = decode_jpeg_header(&j, SCAN_type); + stbi_rewind(s); + return r; } static int stbi_jpeg_info_raw(jpeg *j, int *x, int *y, int *comp) { - if (!decode_jpeg_header(j, SCAN_header)) { - stbi_rewind( j->s ); - return 0; - } - if (x) *x = j->s->img_x; - if (y) *y = j->s->img_y; - if (comp) *comp = j->s->img_n; - return 1; + if (!decode_jpeg_header(j, SCAN_header)) + { + stbi_rewind(j->s); + return 0; + } + if (x) *x = j->s->img_x; + if (y) *y = j->s->img_y; + if (comp) *comp = j->s->img_n; + return 1; } static int stbi_jpeg_info(stbi *s, int *x, int *y, int *comp) { - jpeg j; - j.s = s; - return stbi_jpeg_info_raw(&j, x, y, comp); + jpeg j; + j.s = s; + return stbi_jpeg_info_raw(&j, x, y, comp); } // public domain zlib decode v0.2 Sean Barrett 2006-11-18 @@ -1617,81 +1808,86 @@ static int stbi_jpeg_info(stbi *s, int *x, int *y, int *comp) // - fast huffman // fast-way is faster to check than jpeg huffman, but slow way is slower -#define ZFAST_BITS 9 // accelerate all cases in default tables -#define ZFAST_MASK ((1 << ZFAST_BITS) - 1) +#define ZFAST_BITS 9 // accelerate all cases in default tables +#define ZFAST_MASK ((1 << ZFAST_BITS) - 1) // zlib-style huffman encoding // (jpegs packs from left, zlib from right, so can't share code) typedef struct { - uint16 fast[1 << ZFAST_BITS]; - uint16 firstcode[16]; - int maxcode[17]; - uint16 firstsymbol[16]; - uint8 size[288]; - uint16 value[288]; + uint16 fast[1 << ZFAST_BITS]; + uint16 firstcode[16]; + int maxcode[17]; + uint16 firstsymbol[16]; + uint8 size[288]; + uint16 value[288]; } zhuffman; stbi_inline static int bitreverse16(int n) { - n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); - n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); - n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); - n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); - return n; + n = ((n & 0xAAAA) >> 1) | ((n & 0x5555) << 1); + n = ((n & 0xCCCC) >> 2) | ((n & 0x3333) << 2); + n = ((n & 0xF0F0) >> 4) | ((n & 0x0F0F) << 4); + n = ((n & 0xFF00) >> 8) | ((n & 0x00FF) << 8); + return n; } stbi_inline static int bit_reverse(int v, int bits) { - assert(bits <= 16); - // to bit reverse n bits, reverse 16 and shift - // e.g. 11 bits, bit reverse and shift away 5 - return bitreverse16(v) >> (16-bits); + assert(bits <= 16); + // to bit reverse n bits, reverse 16 and shift + // e.g. 11 bits, bit reverse and shift away 5 + return bitreverse16(v) >> (16 - bits); } static int zbuild_huffman(zhuffman *z, uint8 *sizelist, int num) { - int i,k=0; - int code, next_code[16], sizes[17]; + int i, k = 0; + int code, next_code[16], sizes[17]; - // DEFLATE spec for generating codes - memset(sizes, 0, sizeof(sizes)); - memset(z->fast, 255, sizeof(z->fast)); - for (i=0; i < num; ++i) - ++sizes[sizelist[i]]; - sizes[0] = 0; - for (i=1; i < 16; ++i) - assert(sizes[i] <= (1 << i)); - code = 0; - for (i=1; i < 16; ++i) { - next_code[i] = code; - z->firstcode[i] = (uint16) code; - z->firstsymbol[i] = (uint16) k; - code = (code + sizes[i]); - if (sizes[i]) - if (code-1 >= (1 << i)) return e("bad codelengths","Corrupt JPEG"); - z->maxcode[i] = code << (16-i); // preshift for inner loop - code <<= 1; - k += sizes[i]; - } - z->maxcode[16] = 0x10000; // sentinel - for (i=0; i < num; ++i) { - int s = sizelist[i]; - if (s) { - int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; - z->size[c] = (uint8)s; - z->value[c] = (uint16)i; - if (s <= ZFAST_BITS) { - int k = bit_reverse(next_code[s],s); - while (k < (1 << ZFAST_BITS)) { - z->fast[k] = (uint16) c; - k += (1 << s); - } - } - ++next_code[s]; - } - } - return 1; + // DEFLATE spec for generating codes + memset(sizes, 0, sizeof(sizes)); + memset(z->fast, 255, sizeof(z->fast)); + for (i = 0; i < num; ++i) + ++sizes[sizelist[i]]; + sizes[0] = 0; + for (i = 1; i < 16; ++i) + assert(sizes[i] <= (1 << i)); + code = 0; + for (i = 1; i < 16; ++i) + { + next_code[i] = code; + z->firstcode[i] = (uint16)code; + z->firstsymbol[i] = (uint16)k; + code = (code + sizes[i]); + if (sizes[i]) + if (code - 1 >= (1 << i)) return e("bad codelengths", "Corrupt JPEG"); + z->maxcode[i] = code << (16 - i); // preshift for inner loop + code <<= 1; + k += sizes[i]; + } + z->maxcode[16] = 0x10000; // sentinel + for (i = 0; i < num; ++i) + { + int s = sizelist[i]; + if (s) + { + int c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; + z->size[c] = (uint8)s; + z->value[c] = (uint16)i; + if (s <= ZFAST_BITS) + { + int k = bit_reverse(next_code[s], s); + while (k < (1 << ZFAST_BITS)) + { + z->fast[k] = (uint16)c; + k += (1 << s); + } + } + ++next_code[s]; + } + } + return 1; } // zlib-from-memory implementation for PNG reading @@ -1702,345 +1898,379 @@ static int zbuild_huffman(zhuffman *z, uint8 *sizelist, int num) typedef struct { - uint8 *zbuffer, *zbuffer_end; - int num_bits; - uint32 code_buffer; + uint8 *zbuffer, *zbuffer_end; + int num_bits; + uint32 code_buffer; - char *zout; - char *zout_start; - char *zout_end; - int z_expandable; + char *zout; + char *zout_start; + char *zout_end; + int z_expandable; - zhuffman z_length, z_distance; + zhuffman z_length, z_distance; } zbuf; stbi_inline static int zget8(zbuf *z) { - if (z->zbuffer >= z->zbuffer_end) return 0; - return *z->zbuffer++; + if (z->zbuffer >= z->zbuffer_end) return 0; + return *z->zbuffer++; } static void fill_bits(zbuf *z) { - do { - assert(z->code_buffer < (1U << z->num_bits)); - z->code_buffer |= zget8(z) << z->num_bits; - z->num_bits += 8; - } while (z->num_bits <= 24); + do + { + assert(z->code_buffer < (1U << z->num_bits)); + z->code_buffer |= zget8(z) << z->num_bits; + z->num_bits += 8; + } while (z->num_bits <= 24); } stbi_inline static unsigned int zreceive(zbuf *z, int n) { - unsigned int k; - if (z->num_bits < n) fill_bits(z); - k = z->code_buffer & ((1 << n) - 1); - z->code_buffer >>= n; - z->num_bits -= n; - return k; + unsigned int k; + if (z->num_bits < n) fill_bits(z); + k = z->code_buffer & ((1 << n) - 1); + z->code_buffer >>= n; + z->num_bits -= n; + return k; } stbi_inline static int zhuffman_decode(zbuf *a, zhuffman *z) { - int b,s,k; - if (a->num_bits < 16) fill_bits(a); - b = z->fast[a->code_buffer & ZFAST_MASK]; - if (b < 0xffff) { - s = z->size[b]; - a->code_buffer >>= s; - a->num_bits -= s; - return z->value[b]; - } + int b, s, k; + if (a->num_bits < 16) fill_bits(a); + b = z->fast[a->code_buffer & ZFAST_MASK]; + if (b < 0xffff) + { + s = z->size[b]; + a->code_buffer >>= s; + a->num_bits -= s; + return z->value[b]; + } - // not resolved by fast table, so compute it the slow way - // use jpeg approach, which requires MSbits at top - k = bit_reverse(a->code_buffer, 16); - for (s=ZFAST_BITS+1; ; ++s) - if (k < z->maxcode[s]) - break; - if (s == 16) return -1; // invalid code! - // code size is s, so: - b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s]; - assert(z->size[b] == s); - a->code_buffer >>= s; - a->num_bits -= s; - return z->value[b]; + // not resolved by fast table, so compute it the slow way + // use jpeg approach, which requires MSbits at top + k = bit_reverse(a->code_buffer, 16); + for (s = ZFAST_BITS + 1;; ++s) + if (k < z->maxcode[s]) + break; + if (s == 16) return -1; // invalid code! + // code size is s, so: + b = (k >> (16 - s)) - z->firstcode[s] + z->firstsymbol[s]; + assert(z->size[b] == s); + a->code_buffer >>= s; + a->num_bits -= s; + return z->value[b]; } static int expand(zbuf *z, int n) // need to make room for n bytes { - char *q; - int cur, limit; - if (!z->z_expandable) return e("output buffer limit","Corrupt PNG"); - cur = (int) (z->zout - z->zout_start); - limit = (int) (z->zout_end - z->zout_start); - while (cur + n > limit) - limit *= 2; - q = (char *) realloc(z->zout_start, limit); - if (q == NULL) return e("outofmem", "Out of memory"); - z->zout_start = q; - z->zout = q + cur; - z->zout_end = q + limit; - return 1; + char *q; + int cur, limit; + if (!z->z_expandable) return e("output buffer limit", "Corrupt PNG"); + cur = (int)(z->zout - z->zout_start); + limit = (int)(z->zout_end - z->zout_start); + while (cur + n > limit) + limit *= 2; + q = (char *)realloc(z->zout_start, limit); + if (q == NULL) return e("outofmem", "Out of memory"); + z->zout_start = q; + z->zout = q + cur; + z->zout_end = q + limit; + return 1; } static int length_base[31] = { - 3,4,5,6,7,8,9,10,11,13, - 15,17,19,23,27,31,35,43,51,59, - 67,83,99,115,131,163,195,227,258,0,0 }; + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, + 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, + 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; -static int length_extra[31]= -{ 0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0 }; +static int length_extra[31] = + {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 0, 0}; -static int dist_base[32] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193, -257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577,0,0}; +static int dist_base[32] = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 0, 0}; static int dist_extra[32] = -{ 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; static int parse_huffman_block(zbuf *a) { - for(;;) { - int z = zhuffman_decode(a, &a->z_length); - if (z < 256) { - if (z < 0) return e("bad huffman code","Corrupt PNG"); // error in huffman codes - if (a->zout >= a->zout_end) if (!expand(a, 1)) return 0; - *a->zout++ = (char) z; - } else { - uint8 *p; - int len,dist; - if (z == 256) return 1; - z -= 257; - len = length_base[z]; - if (length_extra[z]) len += zreceive(a, length_extra[z]); - z = zhuffman_decode(a, &a->z_distance); - if (z < 0) return e("bad huffman code","Corrupt PNG"); - dist = dist_base[z]; - if (dist_extra[z]) dist += zreceive(a, dist_extra[z]); - if (a->zout - a->zout_start < dist) return e("bad dist","Corrupt PNG"); - if (a->zout + len > a->zout_end) if (!expand(a, len)) return 0; - p = (uint8 *) (a->zout - dist); - while (len--) - *a->zout++ = *p++; - } - } + for (;;) + { + int z = zhuffman_decode(a, &a->z_length); + if (z < 256) + { + if (z < 0) return e("bad huffman code", "Corrupt PNG"); // error in huffman codes + if (a->zout >= a->zout_end) + if (!expand(a, 1)) return 0; + *a->zout++ = (char)z; + } + else + { + uint8 *p; + int len, dist; + if (z == 256) return 1; + z -= 257; + len = length_base[z]; + if (length_extra[z]) len += zreceive(a, length_extra[z]); + z = zhuffman_decode(a, &a->z_distance); + if (z < 0) return e("bad huffman code", "Corrupt PNG"); + dist = dist_base[z]; + if (dist_extra[z]) dist += zreceive(a, dist_extra[z]); + if (a->zout - a->zout_start < dist) return e("bad dist", "Corrupt PNG"); + if (a->zout + len > a->zout_end) + if (!expand(a, len)) return 0; + p = (uint8 *)(a->zout - dist); + while (len--) + *a->zout++ = *p++; + } + } } static int compute_huffman_codes(zbuf *a) { - static uint8 length_dezigzag[19] = { 16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15 }; - zhuffman z_codelength; - uint8 lencodes[286+32+137];//padding for maximum single op - uint8 codelength_sizes[19]; - int i,n; + static uint8 length_dezigzag[19] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + zhuffman z_codelength; + uint8 lencodes[286 + 32 + 137]; //padding for maximum single op + uint8 codelength_sizes[19]; + int i, n; - int hlit = zreceive(a,5) + 257; - int hdist = zreceive(a,5) + 1; - int hclen = zreceive(a,4) + 4; + int hlit = zreceive(a, 5) + 257; + int hdist = zreceive(a, 5) + 1; + int hclen = zreceive(a, 4) + 4; - memset(codelength_sizes, 0, sizeof(codelength_sizes)); - for (i=0; i < hclen; ++i) { - int s = zreceive(a,3); - codelength_sizes[length_dezigzag[i]] = (uint8) s; - } - if (!zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; + memset(codelength_sizes, 0, sizeof(codelength_sizes)); + for (i = 0; i < hclen; ++i) + { + int s = zreceive(a, 3); + codelength_sizes[length_dezigzag[i]] = (uint8)s; + } + if (!zbuild_huffman(&z_codelength, codelength_sizes, 19)) return 0; - n = 0; - while (n < hlit + hdist) { - int c = zhuffman_decode(a, &z_codelength); - assert(c >= 0 && c < 19); - if (c < 16) - lencodes[n++] = (uint8) c; - else if (c == 16) { - c = zreceive(a,2)+3; - memset(lencodes+n, lencodes[n-1], c); - n += c; - } else if (c == 17) { - c = zreceive(a,3)+3; - memset(lencodes+n, 0, c); - n += c; - } else { - assert(c == 18); - c = zreceive(a,7)+11; - memset(lencodes+n, 0, c); - n += c; - } - } - if (n != hlit+hdist) return e("bad codelengths","Corrupt PNG"); - if (!zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; - if (!zbuild_huffman(&a->z_distance, lencodes+hlit, hdist)) return 0; - return 1; + n = 0; + while (n < hlit + hdist) + { + int c = zhuffman_decode(a, &z_codelength); + assert(c >= 0 && c < 19); + if (c < 16) + lencodes[n++] = (uint8)c; + else if (c == 16) + { + c = zreceive(a, 2) + 3; + memset(lencodes + n, lencodes[n - 1], c); + n += c; + } + else if (c == 17) + { + c = zreceive(a, 3) + 3; + memset(lencodes + n, 0, c); + n += c; + } + else + { + assert(c == 18); + c = zreceive(a, 7) + 11; + memset(lencodes + n, 0, c); + n += c; + } + } + if (n != hlit + hdist) return e("bad codelengths", "Corrupt PNG"); + if (!zbuild_huffman(&a->z_length, lencodes, hlit)) return 0; + if (!zbuild_huffman(&a->z_distance, lencodes + hlit, hdist)) return 0; + return 1; } static int parse_uncompressed_block(zbuf *a) { - uint8 header[4]; - int len,nlen,k; - if (a->num_bits & 7) - zreceive(a, a->num_bits & 7); // discard - // drain the bit-packed data into header - k = 0; - while (a->num_bits > 0) { - header[k++] = (uint8) (a->code_buffer & 255); // wtf this warns? - a->code_buffer >>= 8; - a->num_bits -= 8; - } - assert(a->num_bits == 0); - // now fill header the normal way - while (k < 4) - header[k++] = (uint8) zget8(a); - len = header[1] * 256 + header[0]; - nlen = header[3] * 256 + header[2]; - if (nlen != (len ^ 0xffff)) return e("zlib corrupt","Corrupt PNG"); - if (a->zbuffer + len > a->zbuffer_end) return e("read past buffer","Corrupt PNG"); - if (a->zout + len > a->zout_end) - if (!expand(a, len)) return 0; - memcpy(a->zout, a->zbuffer, len); - a->zbuffer += len; - a->zout += len; - return 1; + uint8 header[4]; + int len, nlen, k; + if (a->num_bits & 7) + zreceive(a, a->num_bits & 7); // discard + // drain the bit-packed data into header + k = 0; + while (a->num_bits > 0) + { + header[k++] = (uint8)(a->code_buffer & 255); // wtf this warns? + a->code_buffer >>= 8; + a->num_bits -= 8; + } + assert(a->num_bits == 0); + // now fill header the normal way + while (k < 4) + header[k++] = (uint8)zget8(a); + len = header[1] * 256 + header[0]; + nlen = header[3] * 256 + header[2]; + if (nlen != (len ^ 0xffff)) return e("zlib corrupt", "Corrupt PNG"); + if (a->zbuffer + len > a->zbuffer_end) return e("read past buffer", "Corrupt PNG"); + if (a->zout + len > a->zout_end) + if (!expand(a, len)) return 0; + memcpy(a->zout, a->zbuffer, len); + a->zbuffer += len; + a->zout += len; + return 1; } static int parse_zlib_header(zbuf *a) { - int cmf = zget8(a); - int cm = cmf & 15; - /* int cinfo = cmf >> 4; */ - int flg = zget8(a); - if ((cmf*256+flg) % 31 != 0) return e("bad zlib header","Corrupt PNG"); // zlib spec - if (flg & 32) return e("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png - if (cm != 8) return e("bad compression","Corrupt PNG"); // DEFLATE required for png - // window = 1 << (8 + cinfo)... but who cares, we fully buffer output - return 1; + int cmf = zget8(a); + int cm = cmf & 15; + /* int cinfo = cmf >> 4; */ + int flg = zget8(a); + if ((cmf * 256 + flg) % 31 != 0) return e("bad zlib header", "Corrupt PNG"); // zlib spec + if (flg & 32) return e("no preset dict", "Corrupt PNG"); // preset dictionary not allowed in png + if (cm != 8) return e("bad compression", "Corrupt PNG"); // DEFLATE required for png + // window = 1 << (8 + cinfo)... but who cares, we fully buffer output + return 1; } // @TODO: should statically initialize these for optimal thread safety static uint8 default_length[288], default_distance[32]; static void init_defaults(void) { - int i; // use <= to match clearly with spec - for (i=0; i <= 143; ++i) default_length[i] = 8; - for ( ; i <= 255; ++i) default_length[i] = 9; - for ( ; i <= 279; ++i) default_length[i] = 7; - for ( ; i <= 287; ++i) default_length[i] = 8; + int i; // use <= to match clearly with spec + for (i = 0; i <= 143; ++i) default_length[i] = 8; + for (; i <= 255; ++i) default_length[i] = 9; + for (; i <= 279; ++i) default_length[i] = 7; + for (; i <= 287; ++i) default_length[i] = 8; - for (i=0; i <= 31; ++i) default_distance[i] = 5; + for (i = 0; i <= 31; ++i) default_distance[i] = 5; } -int stbi_png_partial; // a quick hack to only allow decoding some of a PNG... I should implement real streaming support instead +int stbi_png_partial; // a quick hack to only allow decoding some of a PNG... I should implement real streaming support instead static int parse_zlib(zbuf *a, int parse_header) { - int final, type; - if (parse_header) - if (!parse_zlib_header(a)) return 0; - a->num_bits = 0; - a->code_buffer = 0; - do { - final = zreceive(a,1); - type = zreceive(a,2); - if (type == 0) { - if (!parse_uncompressed_block(a)) return 0; - } else if (type == 3) { - return 0; - } else { - if (type == 1) { - // use fixed code lengths - if (!default_distance[31]) init_defaults(); - if (!zbuild_huffman(&a->z_length , default_length , 288)) return 0; - if (!zbuild_huffman(&a->z_distance, default_distance, 32)) return 0; - } else { - if (!compute_huffman_codes(a)) return 0; - } - if (!parse_huffman_block(a)) return 0; - } - if (stbi_png_partial && a->zout - a->zout_start > 65536) - break; - } while (!final); - return 1; + int final, type; + if (parse_header) + if (!parse_zlib_header(a)) return 0; + a->num_bits = 0; + a->code_buffer = 0; + do + { + final = zreceive(a, 1); + type = zreceive(a, 2); + if (type == 0) + { + if (!parse_uncompressed_block(a)) return 0; + } + else if (type == 3) + { + return 0; + } + else + { + if (type == 1) + { + // use fixed code lengths + if (!default_distance[31]) init_defaults(); + if (!zbuild_huffman(&a->z_length, default_length, 288)) return 0; + if (!zbuild_huffman(&a->z_distance, default_distance, 32)) return 0; + } + else + { + if (!compute_huffman_codes(a)) return 0; + } + if (!parse_huffman_block(a)) return 0; + } + if (stbi_png_partial && a->zout - a->zout_start > 65536) + break; + } while (!final); + return 1; } static int do_zlib(zbuf *a, char *obuf, int olen, int exp, int parse_header) { - a->zout_start = obuf; - a->zout = obuf; - a->zout_end = obuf + olen; - a->z_expandable = exp; + a->zout_start = obuf; + a->zout = obuf; + a->zout_end = obuf + olen; + a->z_expandable = exp; - return parse_zlib(a, parse_header); + return parse_zlib(a, parse_header); } char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen) { - zbuf a; - char *p = (char *) malloc(initial_size); - if (p == NULL) return NULL; - a.zbuffer = (uint8 *) buffer; - a.zbuffer_end = (uint8 *) buffer + len; - if (do_zlib(&a, p, initial_size, 1, 1)) { - if (outlen) *outlen = (int) (a.zout - a.zout_start); - return a.zout_start; - } else { - free(a.zout_start); - return NULL; - } + zbuf a; + char *p = (char *)malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (uint8 *)buffer; + a.zbuffer_end = (uint8 *)buffer + len; + if (do_zlib(&a, p, initial_size, 1, 1)) + { + if (outlen) *outlen = (int)(a.zout - a.zout_start); + return a.zout_start; + } + else + { + free(a.zout_start); + return NULL; + } } char *stbi_zlib_decode_malloc(char const *buffer, int len, int *outlen) { - return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); + return stbi_zlib_decode_malloc_guesssize(buffer, len, 16384, outlen); } char *stbi_zlib_decode_malloc_guesssize_headerflag(const char *buffer, int len, int initial_size, int *outlen, int parse_header) { - zbuf a; - char *p = (char *) malloc(initial_size); - if (p == NULL) return NULL; - a.zbuffer = (uint8 *) buffer; - a.zbuffer_end = (uint8 *) buffer + len; - if (do_zlib(&a, p, initial_size, 1, parse_header)) { - if (outlen) *outlen = (int) (a.zout - a.zout_start); - return a.zout_start; - } else { - free(a.zout_start); - return NULL; - } + zbuf a; + char *p = (char *)malloc(initial_size); + if (p == NULL) return NULL; + a.zbuffer = (uint8 *)buffer; + a.zbuffer_end = (uint8 *)buffer + len; + if (do_zlib(&a, p, initial_size, 1, parse_header)) + { + if (outlen) *outlen = (int)(a.zout - a.zout_start); + return a.zout_start; + } + else + { + free(a.zout_start); + return NULL; + } } int stbi_zlib_decode_buffer(char *obuffer, int olen, char const *ibuffer, int ilen) { - zbuf a; - a.zbuffer = (uint8 *) ibuffer; - a.zbuffer_end = (uint8 *) ibuffer + ilen; - if (do_zlib(&a, obuffer, olen, 0, 1)) - return (int) (a.zout - a.zout_start); - else - return -1; + zbuf a; + a.zbuffer = (uint8 *)ibuffer; + a.zbuffer_end = (uint8 *)ibuffer + ilen; + if (do_zlib(&a, obuffer, olen, 0, 1)) + return (int)(a.zout - a.zout_start); + else + return -1; } char *stbi_zlib_decode_noheader_malloc(char const *buffer, int len, int *outlen) { - zbuf a; - char *p = (char *) malloc(16384); - if (p == NULL) return NULL; - a.zbuffer = (uint8 *) buffer; - a.zbuffer_end = (uint8 *) buffer+len; - if (do_zlib(&a, p, 16384, 1, 0)) { - if (outlen) *outlen = (int) (a.zout - a.zout_start); - return a.zout_start; - } else { - free(a.zout_start); - return NULL; - } + zbuf a; + char *p = (char *)malloc(16384); + if (p == NULL) return NULL; + a.zbuffer = (uint8 *)buffer; + a.zbuffer_end = (uint8 *)buffer + len; + if (do_zlib(&a, p, 16384, 1, 0)) + { + if (outlen) *outlen = (int)(a.zout - a.zout_start); + return a.zout_start; + } + else + { + free(a.zout_start); + return NULL; + } } int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen) { - zbuf a; - a.zbuffer = (uint8 *) ibuffer; - a.zbuffer_end = (uint8 *) ibuffer + ilen; - if (do_zlib(&a, obuffer, olen, 0, 0)) - return (int) (a.zout - a.zout_start); - else - return -1; + zbuf a; + a.zbuffer = (uint8 *)ibuffer; + a.zbuffer_end = (uint8 *)ibuffer + ilen; + if (do_zlib(&a, obuffer, olen, 0, 0)) + return (int)(a.zout - a.zout_start); + else + return -1; } // public domain "baseline" PNG decoder v0.10 Sean Barrett 2006-11-18 @@ -2053,239 +2283,309 @@ int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffe // performance // - uses stb_zlib, a PD zlib implementation with fast huffman decoding - typedef struct { - uint32 length; - uint32 type; + uint32 length; + uint32 type; } chunk; -#define PNG_TYPE(a,b,c,d) (((a) << 24) + ((b) << 16) + ((c) << 8) + (d)) +#define PNG_TYPE(a, b, c, d) (((a) << 24) + ((b) << 16) + ((c) << 8) + (d)) static chunk get_chunk_header(stbi *s) { - chunk c; - c.length = get32(s); - c.type = get32(s); - return c; + chunk c; + c.length = get32(s); + c.type = get32(s); + return c; } static int check_png_header(stbi *s) { - static uint8 png_sig[8] = { 137,80,78,71,13,10,26,10 }; - int i; - for (i=0; i < 8; ++i) - if (get8u(s) != png_sig[i]) return e("bad png sig","Not a PNG"); - return 1; + static uint8 png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10}; + int i; + for (i = 0; i < 8; ++i) + if (get8u(s) != png_sig[i]) return e("bad png sig", "Not a PNG"); + return 1; } typedef struct { - stbi *s; - uint8 *idata, *expanded, *out; + stbi *s; + uint8 *idata, *expanded, *out; } png; - -enum { - F_none=0, F_sub=1, F_up=2, F_avg=3, F_paeth=4, - F_avg_first, F_paeth_first +enum +{ + F_none = 0, + F_sub = 1, + F_up = 2, + F_avg = 3, + F_paeth = 4, + F_avg_first, + F_paeth_first }; static uint8 first_row_filter[5] = -{ - F_none, F_sub, F_none, F_avg_first, F_paeth_first -}; + { + F_none, F_sub, F_none, F_avg_first, F_paeth_first}; static int paeth(int a, int b, int c) { - int p = a + b - c; - int pa = abs(p-a); - int pb = abs(p-b); - int pc = abs(p-c); - if (pa <= pb && pa <= pc) return a; - if (pb <= pc) return b; - return c; + int p = a + b - c; + int pa = abs(p - a); + int pb = abs(p - b); + int pc = abs(p - c); + if (pa <= pb && pa <= pc) return a; + if (pb <= pc) return b; + return c; } // create the png data from post-deflated data static int create_png_image_raw(png *a, uint8 *raw, uint32 raw_len, int out_n, uint32 x, uint32 y) { - stbi *s = a->s; - uint32 i,j,stride = x*out_n; - int k; - int img_n = s->img_n; // copy it into a local for later - assert(out_n == s->img_n || out_n == s->img_n+1); - if (stbi_png_partial) y = 1; - a->out = (uint8 *) malloc(x * y * out_n); - if (!a->out) return e("outofmem", "Out of memory"); - if (!stbi_png_partial) { - if (s->img_x == x && s->img_y == y) { - if (raw_len != (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG"); - } else { // interlaced: - if (raw_len < (img_n * x + 1) * y) return e("not enough pixels","Corrupt PNG"); - } - } - for (j=0; j < y; ++j) { - uint8 *cur = a->out + stride*j; - uint8 *prior = cur - stride; - int filter = *raw++; - if (filter > 4) return e("invalid filter","Corrupt PNG"); - // if first row, use special filter that doesn't sample previous row - if (j == 0) filter = first_row_filter[filter]; - // handle first pixel explicitly - for (k=0; k < img_n; ++k) { - switch (filter) { - case F_none : cur[k] = raw[k]; break; - case F_sub : cur[k] = raw[k]; break; - case F_up : cur[k] = raw[k] + prior[k]; break; - case F_avg : cur[k] = raw[k] + (prior[k]>>1); break; - case F_paeth : cur[k] = (uint8) (raw[k] + paeth(0,prior[k],0)); break; - case F_avg_first : cur[k] = raw[k]; break; - case F_paeth_first: cur[k] = raw[k]; break; - } - } - if (img_n != out_n) cur[img_n] = 255; - raw += img_n; - cur += out_n; - prior += out_n; - // this is a little gross, so that we don't switch per-pixel or per-component - if (img_n == out_n) { - #define CASE(f) \ - case f: \ - for (i=x-1; i >= 1; --i, raw+=img_n,cur+=img_n,prior+=img_n) \ - for (k=0; k < img_n; ++k) - switch (filter) { - CASE(F_none) cur[k] = raw[k]; break; - CASE(F_sub) cur[k] = raw[k] + cur[k-img_n]; break; - CASE(F_up) cur[k] = raw[k] + prior[k]; break; - CASE(F_avg) cur[k] = raw[k] + ((prior[k] + cur[k-img_n])>>1); break; - CASE(F_paeth) cur[k] = (uint8) (raw[k] + paeth(cur[k-img_n],prior[k],prior[k-img_n])); break; - CASE(F_avg_first) cur[k] = raw[k] + (cur[k-img_n] >> 1); break; - CASE(F_paeth_first) cur[k] = (uint8) (raw[k] + paeth(cur[k-img_n],0,0)); break; - } - #undef CASE - } else { - assert(img_n+1 == out_n); - #define CASE(f) \ - case f: \ - for (i=x-1; i >= 1; --i, cur[img_n]=255,raw+=img_n,cur+=out_n,prior+=out_n) \ - for (k=0; k < img_n; ++k) - switch (filter) { - CASE(F_none) cur[k] = raw[k]; break; - CASE(F_sub) cur[k] = raw[k] + cur[k-out_n]; break; - CASE(F_up) cur[k] = raw[k] + prior[k]; break; - CASE(F_avg) cur[k] = raw[k] + ((prior[k] + cur[k-out_n])>>1); break; - CASE(F_paeth) cur[k] = (uint8) (raw[k] + paeth(cur[k-out_n],prior[k],prior[k-out_n])); break; - CASE(F_avg_first) cur[k] = raw[k] + (cur[k-out_n] >> 1); break; - CASE(F_paeth_first) cur[k] = (uint8) (raw[k] + paeth(cur[k-out_n],0,0)); break; - } - #undef CASE - } - } - return 1; + stbi *s = a->s; + uint32 i, j, stride = x * out_n; + int k; + int img_n = s->img_n; // copy it into a local for later + assert(out_n == s->img_n || out_n == s->img_n + 1); + if (stbi_png_partial) y = 1; + a->out = (uint8 *)malloc(x * y * out_n); + if (!a->out) return e("outofmem", "Out of memory"); + if (!stbi_png_partial) + { + if (s->img_x == x && s->img_y == y) + { + if (raw_len != (img_n * x + 1) * y) return e("not enough pixels", "Corrupt PNG"); + } + else + { // interlaced: + if (raw_len < (img_n * x + 1) * y) return e("not enough pixels", "Corrupt PNG"); + } + } + for (j = 0; j < y; ++j) + { + uint8 *cur = a->out + stride * j; + uint8 *prior = cur - stride; + int filter = *raw++; + if (filter > 4) return e("invalid filter", "Corrupt PNG"); + // if first row, use special filter that doesn't sample previous row + if (j == 0) filter = first_row_filter[filter]; + // handle first pixel explicitly + for (k = 0; k < img_n; ++k) + { + switch (filter) + { + case F_none: + cur[k] = raw[k]; + break; + case F_sub: + cur[k] = raw[k]; + break; + case F_up: + cur[k] = raw[k] + prior[k]; + break; + case F_avg: + cur[k] = raw[k] + (prior[k] >> 1); + break; + case F_paeth: + cur[k] = (uint8)(raw[k] + paeth(0, prior[k], 0)); + break; + case F_avg_first: + cur[k] = raw[k]; + break; + case F_paeth_first: + cur[k] = raw[k]; + break; + } + } + if (img_n != out_n) cur[img_n] = 255; + raw += img_n; + cur += out_n; + prior += out_n; + // this is a little gross, so that we don't switch per-pixel or per-component + if (img_n == out_n) + { +#define CASE(f) \ + case f: \ + for (i = x - 1; i >= 1; --i, raw += img_n, cur += img_n, prior += img_n) \ + for (k = 0; k < img_n; ++k) + switch (filter) + { + CASE(F_none) + cur[k] = raw[k]; + break; + CASE(F_sub) + cur[k] = raw[k] + cur[k - img_n]; + break; + CASE(F_up) + cur[k] = raw[k] + prior[k]; + break; + CASE(F_avg) + cur[k] = raw[k] + ((prior[k] + cur[k - img_n]) >> 1); + break; + CASE(F_paeth) + cur[k] = (uint8)(raw[k] + paeth(cur[k - img_n], prior[k], prior[k - img_n])); + break; + CASE(F_avg_first) + cur[k] = raw[k] + (cur[k - img_n] >> 1); + break; + CASE(F_paeth_first) + cur[k] = (uint8)(raw[k] + paeth(cur[k - img_n], 0, 0)); + break; + } +#undef CASE + } + else + { + assert(img_n + 1 == out_n); +#define CASE(f) \ + case f: \ + for (i = x - 1; i >= 1; --i, cur[img_n] = 255, raw += img_n, cur += out_n, prior += out_n) \ + for (k = 0; k < img_n; ++k) + switch (filter) + { + CASE(F_none) + cur[k] = raw[k]; + break; + CASE(F_sub) + cur[k] = raw[k] + cur[k - out_n]; + break; + CASE(F_up) + cur[k] = raw[k] + prior[k]; + break; + CASE(F_avg) + cur[k] = raw[k] + ((prior[k] + cur[k - out_n]) >> 1); + break; + CASE(F_paeth) + cur[k] = (uint8)(raw[k] + paeth(cur[k - out_n], prior[k], prior[k - out_n])); + break; + CASE(F_avg_first) + cur[k] = raw[k] + (cur[k - out_n] >> 1); + break; + CASE(F_paeth_first) + cur[k] = (uint8)(raw[k] + paeth(cur[k - out_n], 0, 0)); + break; + } +#undef CASE + } + } + return 1; } static int create_png_image(png *a, uint8 *raw, uint32 raw_len, int out_n, int interlaced) { - uint8 *final; - int p; - int save; - if (!interlaced) - return create_png_image_raw(a, raw, raw_len, out_n, a->s->img_x, a->s->img_y); - save = stbi_png_partial; - stbi_png_partial = 0; + uint8 *final; + int p; + int save; + if (!interlaced) + return create_png_image_raw(a, raw, raw_len, out_n, a->s->img_x, a->s->img_y); + save = stbi_png_partial; + stbi_png_partial = 0; - // de-interlacing - final = (uint8 *) malloc(a->s->img_x * a->s->img_y * out_n); - for (p=0; p < 7; ++p) { - int xorig[] = { 0,4,0,2,0,1,0 }; - int yorig[] = { 0,0,4,0,2,0,1 }; - int xspc[] = { 8,8,4,4,2,2,1 }; - int yspc[] = { 8,8,8,4,4,2,2 }; - int i,j,x,y; - // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 - x = (a->s->img_x - xorig[p] + xspc[p]-1) / xspc[p]; - y = (a->s->img_y - yorig[p] + yspc[p]-1) / yspc[p]; - if (x && y) { - if (!create_png_image_raw(a, raw, raw_len, out_n, x, y)) { - free(final); - return 0; - } - for (j=0; j < y; ++j) - for (i=0; i < x; ++i) - memcpy(final + (j*yspc[p]+yorig[p])*a->s->img_x*out_n + (i*xspc[p]+xorig[p])*out_n, - a->out + (j*x+i)*out_n, out_n); - free(a->out); - raw += (x*out_n+1)*y; - raw_len -= (x*out_n+1)*y; - } - } - a->out = final; + // de-interlacing + final = (uint8 *)malloc(a->s->img_x * a->s->img_y * out_n); + for (p = 0; p < 7; ++p) + { + int xorig[] = {0, 4, 0, 2, 0, 1, 0}; + int yorig[] = {0, 0, 4, 0, 2, 0, 1}; + int xspc[] = {8, 8, 4, 4, 2, 2, 1}; + int yspc[] = {8, 8, 8, 4, 4, 2, 2}; + int i, j, x, y; + // pass1_x[4] = 0, pass1_x[5] = 1, pass1_x[12] = 1 + x = (a->s->img_x - xorig[p] + xspc[p] - 1) / xspc[p]; + y = (a->s->img_y - yorig[p] + yspc[p] - 1) / yspc[p]; + if (x && y) + { + if (!create_png_image_raw(a, raw, raw_len, out_n, x, y)) + { + free(final); + return 0; + } + for (j = 0; j < y; ++j) + for (i = 0; i < x; ++i) + memcpy(final + (j * yspc[p] + yorig[p]) * a->s->img_x * out_n + (i * xspc[p] + xorig[p]) * out_n, + a->out + (j * x + i) * out_n, out_n); + free(a->out); + raw += (x * out_n + 1) * y; + raw_len -= (x * out_n + 1) * y; + } + } + a->out = final; - stbi_png_partial = save; - return 1; + stbi_png_partial = save; + return 1; } static int compute_transparency(png *z, uint8 tc[3], int out_n) { - stbi *s = z->s; - uint32 i, pixel_count = s->img_x * s->img_y; - uint8 *p = z->out; + stbi *s = z->s; + uint32 i, pixel_count = s->img_x * s->img_y; + uint8 *p = z->out; - // compute color-based transparency, assuming we've - // already got 255 as the alpha value in the output - assert(out_n == 2 || out_n == 4); + // compute color-based transparency, assuming we've + // already got 255 as the alpha value in the output + assert(out_n == 2 || out_n == 4); - if (out_n == 2) { - for (i=0; i < pixel_count; ++i) { - p[1] = (p[0] == tc[0] ? 0 : 255); - p += 2; - } - } else { - for (i=0; i < pixel_count; ++i) { - if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) - p[3] = 0; - p += 4; - } - } - return 1; + if (out_n == 2) + { + for (i = 0; i < pixel_count; ++i) + { + p[1] = (p[0] == tc[0] ? 0 : 255); + p += 2; + } + } + else + { + for (i = 0; i < pixel_count; ++i) + { + if (p[0] == tc[0] && p[1] == tc[1] && p[2] == tc[2]) + p[3] = 0; + p += 4; + } + } + return 1; } static int expand_palette(png *a, uint8 *palette, int len, int pal_img_n) { - uint32 i, pixel_count = a->s->img_x * a->s->img_y; - uint8 *p, *temp_out, *orig = a->out; + uint32 i, pixel_count = a->s->img_x * a->s->img_y; + uint8 *p, *temp_out, *orig = a->out; - p = (uint8 *) malloc(pixel_count * pal_img_n); - if (p == NULL) return e("outofmem", "Out of memory"); + p = (uint8 *)malloc(pixel_count * pal_img_n); + if (p == NULL) return e("outofmem", "Out of memory"); - // between here and free(out) below, exitting would leak - temp_out = p; + // between here and free(out) below, exitting would leak + temp_out = p; - if (pal_img_n == 3) { - for (i=0; i < pixel_count; ++i) { - int n = orig[i]*4; - p[0] = palette[n ]; - p[1] = palette[n+1]; - p[2] = palette[n+2]; - p += 3; - } - } else { - for (i=0; i < pixel_count; ++i) { - int n = orig[i]*4; - p[0] = palette[n ]; - p[1] = palette[n+1]; - p[2] = palette[n+2]; - p[3] = palette[n+3]; - p += 4; - } - } - free(a->out); - a->out = temp_out; + if (pal_img_n == 3) + { + for (i = 0; i < pixel_count; ++i) + { + int n = orig[i] * 4; + p[0] = palette[n]; + p[1] = palette[n + 1]; + p[2] = palette[n + 2]; + p += 3; + } + } + else + { + for (i = 0; i < pixel_count; ++i) + { + int n = orig[i] * 4; + p[0] = palette[n]; + p[1] = palette[n + 1]; + p[2] = palette[n + 2]; + p[3] = palette[n + 3]; + p += 4; + } + } + free(a->out); + a->out = temp_out; - STBI_NOTUSED(len); + STBI_NOTUSED(len); - return 1; + return 1; } static int stbi_unpremultiply_on_load = 0; @@ -2293,1011 +2593,1157 @@ static int stbi_de_iphone_flag = 0; void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply) { - stbi_unpremultiply_on_load = flag_true_if_should_unpremultiply; + stbi_unpremultiply_on_load = flag_true_if_should_unpremultiply; } void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert) { - stbi_de_iphone_flag = flag_true_if_should_convert; + stbi_de_iphone_flag = flag_true_if_should_convert; } static void stbi_de_iphone(png *z) { - stbi *s = z->s; - uint32 i, pixel_count = s->img_x * s->img_y; - uint8 *p = z->out; + stbi *s = z->s; + uint32 i, pixel_count = s->img_x * s->img_y; + uint8 *p = z->out; - if (s->img_out_n == 3) { // convert bgr to rgb - for (i=0; i < pixel_count; ++i) { - uint8 t = p[0]; - p[0] = p[2]; - p[2] = t; - p += 3; - } - } else { - assert(s->img_out_n == 4); - if (stbi_unpremultiply_on_load) { - // convert bgr to rgb and unpremultiply - for (i=0; i < pixel_count; ++i) { - uint8 a = p[3]; - uint8 t = p[0]; - if (a) { - p[0] = p[2] * 255 / a; - p[1] = p[1] * 255 / a; - p[2] = t * 255 / a; - } else { - p[0] = p[2]; - p[2] = t; - } - p += 4; - } - } else { - // convert bgr to rgb - for (i=0; i < pixel_count; ++i) { - uint8 t = p[0]; - p[0] = p[2]; - p[2] = t; - p += 4; - } - } - } + if (s->img_out_n == 3) + { // convert bgr to rgb + for (i = 0; i < pixel_count; ++i) + { + uint8 t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 3; + } + } + else + { + assert(s->img_out_n == 4); + if (stbi_unpremultiply_on_load) + { + // convert bgr to rgb and unpremultiply + for (i = 0; i < pixel_count; ++i) + { + uint8 a = p[3]; + uint8 t = p[0]; + if (a) + { + p[0] = p[2] * 255 / a; + p[1] = p[1] * 255 / a; + p[2] = t * 255 / a; + } + else + { + p[0] = p[2]; + p[2] = t; + } + p += 4; + } + } + else + { + // convert bgr to rgb + for (i = 0; i < pixel_count; ++i) + { + uint8 t = p[0]; + p[0] = p[2]; + p[2] = t; + p += 4; + } + } + } } static int parse_png_file(png *z, int scan, int req_comp) { - uint8 palette[1024], pal_img_n=0; - uint8 has_trans=0, tc[3]; - uint32 ioff=0, idata_limit=0, i, pal_len=0; - int first=1,k,interlace=0, iphone=0; - stbi *s = z->s; + uint8 palette[1024], pal_img_n = 0; + uint8 has_trans = 0, tc[3]; + uint32 ioff = 0, idata_limit = 0, i, pal_len = 0; + int first = 1, k, interlace = 0, iphone = 0; + stbi *s = z->s; - z->expanded = NULL; - z->idata = NULL; - z->out = NULL; + z->expanded = NULL; + z->idata = NULL; + z->out = NULL; - if (!check_png_header(s)) return 0; + if (!check_png_header(s)) return 0; - if (scan == SCAN_type) return 1; + if (scan == SCAN_type) return 1; - for (;;) { - chunk c = get_chunk_header(s); - switch (c.type) { - case PNG_TYPE('C','g','B','I'): - iphone = stbi_de_iphone_flag; - skip(s, c.length); - break; - case PNG_TYPE('I','H','D','R'): { - int depth,color,comp,filter; - if (!first) return e("multiple IHDR","Corrupt PNG"); - first = 0; - if (c.length != 13) return e("bad IHDR len","Corrupt PNG"); - s->img_x = get32(s); if (s->img_x > (1 << 24)) return e("too large","Very large image (corrupt?)"); - s->img_y = get32(s); if (s->img_y > (1 << 24)) return e("too large","Very large image (corrupt?)"); - depth = get8(s); if (depth != 8) return e("8bit only","PNG not supported: 8-bit only"); - color = get8(s); if (color > 6) return e("bad ctype","Corrupt PNG"); - if (color == 3) pal_img_n = 3; else if (color & 1) return e("bad ctype","Corrupt PNG"); - comp = get8(s); if (comp) return e("bad comp method","Corrupt PNG"); - filter= get8(s); if (filter) return e("bad filter method","Corrupt PNG"); - interlace = get8(s); if (interlace>1) return e("bad interlace method","Corrupt PNG"); - if (!s->img_x || !s->img_y) return e("0-pixel image","Corrupt PNG"); - if (!pal_img_n) { - s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); - if ((1 << 30) / s->img_x / s->img_n < s->img_y) return e("too large", "Image too large to decode"); - if (scan == SCAN_header) return 1; - } else { - // if paletted, then pal_n is our final components, and - // img_n is # components to decompress/filter. - s->img_n = 1; - if ((1 << 30) / s->img_x / 4 < s->img_y) return e("too large","Corrupt PNG"); - // if SCAN_header, have to scan to see if we have a tRNS - } - break; - } + for (;;) + { + chunk c = get_chunk_header(s); + switch (c.type) + { + case PNG_TYPE('C', 'g', 'B', 'I'): + iphone = stbi_de_iphone_flag; + skip(s, c.length); + break; + case PNG_TYPE('I', 'H', 'D', 'R'): + { + int depth, color, comp, filter; + if (!first) return e("multiple IHDR", "Corrupt PNG"); + first = 0; + if (c.length != 13) return e("bad IHDR len", "Corrupt PNG"); + s->img_x = get32(s); + if (s->img_x > (1 << 24)) return e("too large", "Very large image (corrupt?)"); + s->img_y = get32(s); + if (s->img_y > (1 << 24)) return e("too large", "Very large image (corrupt?)"); + depth = get8(s); + if (depth != 8) return e("8bit only", "PNG not supported: 8-bit only"); + color = get8(s); + if (color > 6) return e("bad ctype", "Corrupt PNG"); + if (color == 3) + pal_img_n = 3; + else if (color & 1) + return e("bad ctype", "Corrupt PNG"); + comp = get8(s); + if (comp) return e("bad comp method", "Corrupt PNG"); + filter = get8(s); + if (filter) return e("bad filter method", "Corrupt PNG"); + interlace = get8(s); + if (interlace > 1) return e("bad interlace method", "Corrupt PNG"); + if (!s->img_x || !s->img_y) return e("0-pixel image", "Corrupt PNG"); + if (!pal_img_n) + { + s->img_n = (color & 2 ? 3 : 1) + (color & 4 ? 1 : 0); + if ((1 << 30) / s->img_x / s->img_n < s->img_y) return e("too large", "Image too large to decode"); + if (scan == SCAN_header) return 1; + } + else + { + // if paletted, then pal_n is our final components, and + // img_n is # components to decompress/filter. + s->img_n = 1; + if ((1 << 30) / s->img_x / 4 < s->img_y) return e("too large", "Corrupt PNG"); + // if SCAN_header, have to scan to see if we have a tRNS + } + break; + } - case PNG_TYPE('P','L','T','E'): { - if (first) return e("first not IHDR", "Corrupt PNG"); - if (c.length > 256*3) return e("invalid PLTE","Corrupt PNG"); - pal_len = c.length / 3; - if (pal_len * 3 != c.length) return e("invalid PLTE","Corrupt PNG"); - for (i=0; i < pal_len; ++i) { - palette[i*4+0] = get8u(s); - palette[i*4+1] = get8u(s); - palette[i*4+2] = get8u(s); - palette[i*4+3] = 255; - } - break; - } + case PNG_TYPE('P', 'L', 'T', 'E'): + { + if (first) return e("first not IHDR", "Corrupt PNG"); + if (c.length > 256 * 3) return e("invalid PLTE", "Corrupt PNG"); + pal_len = c.length / 3; + if (pal_len * 3 != c.length) return e("invalid PLTE", "Corrupt PNG"); + for (i = 0; i < pal_len; ++i) + { + palette[i * 4 + 0] = get8u(s); + palette[i * 4 + 1] = get8u(s); + palette[i * 4 + 2] = get8u(s); + palette[i * 4 + 3] = 255; + } + break; + } - case PNG_TYPE('t','R','N','S'): { - if (first) return e("first not IHDR", "Corrupt PNG"); - if (z->idata) return e("tRNS after IDAT","Corrupt PNG"); - if (pal_img_n) { - if (scan == SCAN_header) { s->img_n = 4; return 1; } - if (pal_len == 0) return e("tRNS before PLTE","Corrupt PNG"); - if (c.length > pal_len) return e("bad tRNS len","Corrupt PNG"); - pal_img_n = 4; - for (i=0; i < c.length; ++i) - palette[i*4+3] = get8u(s); - } else { - if (!(s->img_n & 1)) return e("tRNS with alpha","Corrupt PNG"); - if (c.length != (uint32) s->img_n*2) return e("bad tRNS len","Corrupt PNG"); - has_trans = 1; - for (k=0; k < s->img_n; ++k) - tc[k] = (uint8) get16(s); // non 8-bit images will be larger - } - break; - } + case PNG_TYPE('t', 'R', 'N', 'S'): + { + if (first) return e("first not IHDR", "Corrupt PNG"); + if (z->idata) return e("tRNS after IDAT", "Corrupt PNG"); + if (pal_img_n) + { + if (scan == SCAN_header) + { + s->img_n = 4; + return 1; + } + if (pal_len == 0) return e("tRNS before PLTE", "Corrupt PNG"); + if (c.length > pal_len) return e("bad tRNS len", "Corrupt PNG"); + pal_img_n = 4; + for (i = 0; i < c.length; ++i) + palette[i * 4 + 3] = get8u(s); + } + else + { + if (!(s->img_n & 1)) return e("tRNS with alpha", "Corrupt PNG"); + if (c.length != (uint32)s->img_n * 2) return e("bad tRNS len", "Corrupt PNG"); + has_trans = 1; + for (k = 0; k < s->img_n; ++k) + tc[k] = (uint8)get16(s); // non 8-bit images will be larger + } + break; + } - case PNG_TYPE('I','D','A','T'): { - if (first) return e("first not IHDR", "Corrupt PNG"); - if (pal_img_n && !pal_len) return e("no PLTE","Corrupt PNG"); - if (scan == SCAN_header) { s->img_n = pal_img_n; return 1; } - if (ioff + c.length > idata_limit) { - uint8 *p; - if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; - while (ioff + c.length > idata_limit) - idata_limit *= 2; - p = (uint8 *) realloc(z->idata, idata_limit); if (p == NULL) return e("outofmem", "Out of memory"); - z->idata = p; - } - if (!getn(s, z->idata+ioff,c.length)) return e("outofdata","Corrupt PNG"); - ioff += c.length; - break; - } + case PNG_TYPE('I', 'D', 'A', 'T'): + { + if (first) return e("first not IHDR", "Corrupt PNG"); + if (pal_img_n && !pal_len) return e("no PLTE", "Corrupt PNG"); + if (scan == SCAN_header) + { + s->img_n = pal_img_n; + return 1; + } + if (ioff + c.length > idata_limit) + { + uint8 *p; + if (idata_limit == 0) idata_limit = c.length > 4096 ? c.length : 4096; + while (ioff + c.length > idata_limit) + idata_limit *= 2; + p = (uint8 *)realloc(z->idata, idata_limit); + if (p == NULL) return e("outofmem", "Out of memory"); + z->idata = p; + } + if (!getn(s, z->idata + ioff, c.length)) return e("outofdata", "Corrupt PNG"); + ioff += c.length; + break; + } - case PNG_TYPE('I','E','N','D'): { - uint32 raw_len; - if (first) return e("first not IHDR", "Corrupt PNG"); - if (scan != SCAN_load) return 1; - if (z->idata == NULL) return e("no IDAT","Corrupt PNG"); - z->expanded = (uint8 *) stbi_zlib_decode_malloc_guesssize_headerflag((char *) z->idata, ioff, 16384, (int *) &raw_len, !iphone); - if (z->expanded == NULL) return 0; // zlib should set error - free(z->idata); z->idata = NULL; - if ((req_comp == s->img_n+1 && req_comp != 3 && !pal_img_n) || has_trans) - s->img_out_n = s->img_n+1; - else - s->img_out_n = s->img_n; - if (!create_png_image(z, z->expanded, raw_len, s->img_out_n, interlace)) return 0; - if (has_trans) - if (!compute_transparency(z, tc, s->img_out_n)) return 0; - if (iphone && s->img_out_n > 2) - stbi_de_iphone(z); - if (pal_img_n) { - // pal_img_n == 3 or 4 - s->img_n = pal_img_n; // record the actual colors we had - s->img_out_n = pal_img_n; - if (req_comp >= 3) s->img_out_n = req_comp; - if (!expand_palette(z, palette, pal_len, s->img_out_n)) - return 0; - } - free(z->expanded); z->expanded = NULL; - return 1; - } + case PNG_TYPE('I', 'E', 'N', 'D'): + { + uint32 raw_len; + if (first) return e("first not IHDR", "Corrupt PNG"); + if (scan != SCAN_load) return 1; + if (z->idata == NULL) return e("no IDAT", "Corrupt PNG"); + z->expanded = (uint8 *)stbi_zlib_decode_malloc_guesssize_headerflag((char *)z->idata, ioff, 16384, (int *)&raw_len, !iphone); + if (z->expanded == NULL) return 0; // zlib should set error + free(z->idata); + z->idata = NULL; + if ((req_comp == s->img_n + 1 && req_comp != 3 && !pal_img_n) || has_trans) + s->img_out_n = s->img_n + 1; + else + s->img_out_n = s->img_n; + if (!create_png_image(z, z->expanded, raw_len, s->img_out_n, interlace)) return 0; + if (has_trans) + if (!compute_transparency(z, tc, s->img_out_n)) return 0; + if (iphone && s->img_out_n > 2) + stbi_de_iphone(z); + if (pal_img_n) + { + // pal_img_n == 3 or 4 + s->img_n = pal_img_n; // record the actual colors we had + s->img_out_n = pal_img_n; + if (req_comp >= 3) s->img_out_n = req_comp; + if (!expand_palette(z, palette, pal_len, s->img_out_n)) + return 0; + } + free(z->expanded); + z->expanded = NULL; + return 1; + } - default: - // if critical, fail - if (first) return e("first not IHDR", "Corrupt PNG"); - if ((c.type & (1 << 29)) == 0) { - #ifndef STBI_NO_FAILURE_STRINGS - // not threadsafe - static char invalid_chunk[] = "XXXX chunk not known"; - invalid_chunk[0] = (uint8) (c.type >> 24); - invalid_chunk[1] = (uint8) (c.type >> 16); - invalid_chunk[2] = (uint8) (c.type >> 8); - invalid_chunk[3] = (uint8) (c.type >> 0); - #endif - return e(invalid_chunk, "PNG not supported: unknown chunk type"); - } - skip(s, c.length); - break; - } - // end of chunk, read and skip CRC - get32(s); - } + default: + // if critical, fail + if (first) return e("first not IHDR", "Corrupt PNG"); + if ((c.type & (1 << 29)) == 0) + { +#ifndef STBI_NO_FAILURE_STRINGS + // not threadsafe + static char invalid_chunk[] = "XXXX chunk not known"; + invalid_chunk[0] = (uint8)(c.type >> 24); + invalid_chunk[1] = (uint8)(c.type >> 16); + invalid_chunk[2] = (uint8)(c.type >> 8); + invalid_chunk[3] = (uint8)(c.type >> 0); +#endif + return e(invalid_chunk, "PNG not supported: unknown chunk type"); + } + skip(s, c.length); + break; + } + // end of chunk, read and skip CRC + get32(s); + } } static unsigned char *do_png(png *p, int *x, int *y, int *n, int req_comp) { - unsigned char *result=NULL; - if (req_comp < 0 || req_comp > 4) return epuc("bad req_comp", "Internal error"); - if (parse_png_file(p, SCAN_load, req_comp)) { - result = p->out; - p->out = NULL; - if (req_comp && req_comp != p->s->img_out_n) { - result = convert_format(result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); - p->s->img_out_n = req_comp; - if (result == NULL) return result; - } - *x = p->s->img_x; - *y = p->s->img_y; - if (n) *n = p->s->img_n; - } - free(p->out); p->out = NULL; - free(p->expanded); p->expanded = NULL; - free(p->idata); p->idata = NULL; + unsigned char *result = NULL; + if (req_comp < 0 || req_comp > 4) return epuc("bad req_comp", "Internal error"); + if (parse_png_file(p, SCAN_load, req_comp)) + { + result = p->out; + p->out = NULL; + if (req_comp && req_comp != p->s->img_out_n) + { + result = convert_format(result, p->s->img_out_n, req_comp, p->s->img_x, p->s->img_y); + p->s->img_out_n = req_comp; + if (result == NULL) return result; + } + *x = p->s->img_x; + *y = p->s->img_y; + if (n) *n = p->s->img_n; + } + free(p->out); + p->out = NULL; + free(p->expanded); + p->expanded = NULL; + free(p->idata); + p->idata = NULL; - return result; + return result; } static unsigned char *stbi_png_load(stbi *s, int *x, int *y, int *comp, int req_comp) { - png p; - p.s = s; - return do_png(&p, x,y,comp,req_comp); + png p; + p.s = s; + return do_png(&p, x, y, comp, req_comp); } static int stbi_png_test(stbi *s) { - int r; - r = check_png_header(s); - stbi_rewind(s); - return r; + int r; + r = check_png_header(s); + stbi_rewind(s); + return r; } static int stbi_png_info_raw(png *p, int *x, int *y, int *comp) { - if (!parse_png_file(p, SCAN_header, 0)) { - stbi_rewind( p->s ); - return 0; - } - if (x) *x = p->s->img_x; - if (y) *y = p->s->img_y; - if (comp) *comp = p->s->img_n; - return 1; + if (!parse_png_file(p, SCAN_header, 0)) + { + stbi_rewind(p->s); + return 0; + } + if (x) *x = p->s->img_x; + if (y) *y = p->s->img_y; + if (comp) *comp = p->s->img_n; + return 1; } -static int stbi_png_info(stbi *s, int *x, int *y, int *comp) +static int stbi_png_info(stbi *s, int *x, int *y, int *comp) { - png p; - p.s = s; - return stbi_png_info_raw(&p, x, y, comp); + png p; + p.s = s; + return stbi_png_info_raw(&p, x, y, comp); } // Microsoft/Windows BMP image static int bmp_test(stbi *s) { - int sz; - if (get8(s) != 'B') return 0; - if (get8(s) != 'M') return 0; - get32le(s); // discard filesize - get16le(s); // discard reserved - get16le(s); // discard reserved - get32le(s); // discard data offset - sz = get32le(s); - if (sz == 12 || sz == 40 || sz == 56 || sz == 108) return 1; - return 0; + int sz; + if (get8(s) != 'B') return 0; + if (get8(s) != 'M') return 0; + get32le(s); // discard filesize + get16le(s); // discard reserved + get16le(s); // discard reserved + get32le(s); // discard data offset + sz = get32le(s); + if (sz == 12 || sz == 40 || sz == 56 || sz == 108) return 1; + return 0; } static int stbi_bmp_test(stbi *s) { - int r = bmp_test(s); - stbi_rewind(s); - return r; + int r = bmp_test(s); + stbi_rewind(s); + return r; } - // returns 0..31 for the highest set bit static int high_bit(unsigned int z) { - int n=0; - if (z == 0) return -1; - if (z >= 0x10000) n += 16, z >>= 16; - if (z >= 0x00100) n += 8, z >>= 8; - if (z >= 0x00010) n += 4, z >>= 4; - if (z >= 0x00004) n += 2, z >>= 2; - if (z >= 0x00002) n += 1, z >>= 1; - return n; + int n = 0; + if (z == 0) return -1; + if (z >= 0x10000) n += 16, z >>= 16; + if (z >= 0x00100) n += 8, z >>= 8; + if (z >= 0x00010) n += 4, z >>= 4; + if (z >= 0x00004) n += 2, z >>= 2; + if (z >= 0x00002) n += 1, z >>= 1; + return n; } static int bitcount(unsigned int a) { - a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 - a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 - a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits - a = (a + (a >> 8)); // max 16 per 8 bits - a = (a + (a >> 16)); // max 32 per 8 bits - return a & 0xff; + a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2 + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4 + a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits + a = (a + (a >> 8)); // max 16 per 8 bits + a = (a + (a >> 16)); // max 32 per 8 bits + return a & 0xff; } static int shiftsigned(int v, int shift, int bits) { - int result; - int z=0; + int result; + int z = 0; - if (shift < 0) v <<= -shift; - else v >>= shift; - result = v; + if (shift < 0) + v <<= -shift; + else + v >>= shift; + result = v; - z = bits; - while (z < 8) { - result += v >> z; - z += bits; - } - return result; + z = bits; + while (z < 8) + { + result += v >> z; + z += bits; + } + return result; } static stbi_uc *bmp_load(stbi *s, int *x, int *y, int *comp, int req_comp) { - uint8 *out; - unsigned int mr=0,mg=0,mb=0,ma=0;//, fake_a=0; - stbi_uc pal[256][4]; - int psize=0,i,j,compress=0,width; - int bpp, flip_vertically, pad, target, offset, hsz; - if (get8(s) != 'B' || get8(s) != 'M') return epuc("not BMP", "Corrupt BMP"); - get32le(s); // discard filesize - get16le(s); // discard reserved - get16le(s); // discard reserved - offset = get32le(s); - hsz = get32le(s); - if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108) return epuc("unknown BMP", "BMP type not supported: unknown"); - if (hsz == 12) { - s->img_x = get16le(s); - s->img_y = get16le(s); - } else { - s->img_x = get32le(s); - s->img_y = get32le(s); - } - if (get16le(s) != 1) return epuc("bad BMP", "bad BMP"); - bpp = get16le(s); - if (bpp == 1) return epuc("monochrome", "BMP type not supported: 1-bit"); - flip_vertically = ((int) s->img_y) > 0; - s->img_y = abs((int) s->img_y); - if (hsz == 12) { - if (bpp < 24) - psize = (offset - 14 - 24) / 3; - } else { - compress = get32le(s); - if (compress == 1 || compress == 2) return epuc("BMP RLE", "BMP type not supported: RLE"); - get32le(s); // discard sizeof - get32le(s); // discard hres - get32le(s); // discard vres - get32le(s); // discard colorsused - get32le(s); // discard max important - if (hsz == 40 || hsz == 56) { - if (hsz == 56) { - get32le(s); - get32le(s); - get32le(s); - get32le(s); - } - if (bpp == 16 || bpp == 32) { - mr = mg = mb = 0; - if (compress == 0) { - if (bpp == 32) { - mr = 0xffu << 16; - mg = 0xffu << 8; - mb = 0xffu << 0; - ma = 0xffu << 24; - //fake_a = 1; // @TODO: check for cases like alpha value is all 0 and switch it to 255 - } else { - mr = 31u << 10; - mg = 31u << 5; - mb = 31u << 0; - } - } else if (compress == 3) { - mr = get32le(s); - mg = get32le(s); - mb = get32le(s); - // not documented, but generated by photoshop and handled by mspaint - if (mr == mg && mg == mb) { - // ?!?!? - return epuc("bad BMP", "bad BMP"); - } - } else - return epuc("bad BMP", "bad BMP"); - } - } else { - assert(hsz == 108); - mr = get32le(s); - mg = get32le(s); - mb = get32le(s); - ma = get32le(s); - get32le(s); // discard color space - for (i=0; i < 12; ++i) - get32le(s); // discard color space parameters - } - if (bpp < 16) - psize = (offset - 14 - hsz) >> 2; - } - s->img_n = ma ? 4 : 3; - if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 - target = req_comp; - else - target = s->img_n; // if they want monochrome, we'll post-convert - out = (stbi_uc *) malloc(target * s->img_x * s->img_y); - if (!out) return epuc("outofmem", "Out of memory"); - if (bpp < 16) { - int z=0; - if (psize == 0 || psize > 256) { free(out); return epuc("invalid", "Corrupt BMP"); } - for (i=0; i < psize; ++i) { - pal[i][2] = get8u(s); - pal[i][1] = get8u(s); - pal[i][0] = get8u(s); - if (hsz != 12) get8(s); - pal[i][3] = 255; - } - skip(s, offset - 14 - hsz - psize * (hsz == 12 ? 3 : 4)); - if (bpp == 4) width = (s->img_x + 1) >> 1; - else if (bpp == 8) width = s->img_x; - else { free(out); return epuc("bad bpp", "Corrupt BMP"); } - pad = (-width)&3; - for (j=0; j < (int) s->img_y; ++j) { - for (i=0; i < (int) s->img_x; i += 2) { - int v=get8(s),v2=0; - if (bpp == 4) { - v2 = v & 15; - v >>= 4; - } - out[z++] = pal[v][0]; - out[z++] = pal[v][1]; - out[z++] = pal[v][2]; - if (target == 4) out[z++] = 255; - if (i+1 == (int) s->img_x) break; - v = (bpp == 8) ? get8(s) : v2; - out[z++] = pal[v][0]; - out[z++] = pal[v][1]; - out[z++] = pal[v][2]; - if (target == 4) out[z++] = 255; - } - skip(s, pad); - } - } else { - int rshift=0,gshift=0,bshift=0,ashift=0,rcount=0,gcount=0,bcount=0,acount=0; - int z = 0; - int easy=0; - skip(s, offset - 14 - hsz); - if (bpp == 24) width = 3 * s->img_x; - else if (bpp == 16) width = 2*s->img_x; - else /* bpp = 32 and pad = 0 */ width=0; - pad = (-width) & 3; - if (bpp == 24) { - easy = 1; - } else if (bpp == 32) { - if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) - easy = 2; - } - if (!easy) { - if (!mr || !mg || !mb) { free(out); return epuc("bad masks", "Corrupt BMP"); } - // right shift amt to put high bit in position #7 - rshift = high_bit(mr)-7; rcount = bitcount(mr); - gshift = high_bit(mg)-7; gcount = bitcount(mr); - bshift = high_bit(mb)-7; bcount = bitcount(mr); - ashift = high_bit(ma)-7; acount = bitcount(mr); - } - for (j=0; j < (int) s->img_y; ++j) { - if (easy) { - for (i=0; i < (int) s->img_x; ++i) { - int a; - out[z+2] = get8u(s); - out[z+1] = get8u(s); - out[z+0] = get8u(s); - z += 3; - a = (easy == 2 ? get8(s) : 255); - if (target == 4) out[z++] = (uint8) a; - } - } else { - for (i=0; i < (int) s->img_x; ++i) { - uint32 v = (bpp == 16 ? get16le(s) : get32le(s)); - int a; - out[z++] = (uint8) shiftsigned(v & mr, rshift, rcount); - out[z++] = (uint8) shiftsigned(v & mg, gshift, gcount); - out[z++] = (uint8) shiftsigned(v & mb, bshift, bcount); - a = (ma ? shiftsigned(v & ma, ashift, acount) : 255); - if (target == 4) out[z++] = (uint8) a; - } - } - skip(s, pad); - } - } - if (flip_vertically) { - stbi_uc t; - for (j=0; j < (int) s->img_y>>1; ++j) { - stbi_uc *p1 = out + j *s->img_x*target; - stbi_uc *p2 = out + (s->img_y-1-j)*s->img_x*target; - for (i=0; i < (int) s->img_x*target; ++i) { - t = p1[i], p1[i] = p2[i], p2[i] = t; - } - } - } + uint8 *out; + unsigned int mr = 0, mg = 0, mb = 0, ma = 0; //, fake_a=0; + stbi_uc pal[256][4]; + int psize = 0, i, j, compress = 0, width; + int bpp, flip_vertically, pad, target, offset, hsz; + if (get8(s) != 'B' || get8(s) != 'M') return epuc("not BMP", "Corrupt BMP"); + get32le(s); // discard filesize + get16le(s); // discard reserved + get16le(s); // discard reserved + offset = get32le(s); + hsz = get32le(s); + if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108) return epuc("unknown BMP", "BMP type not supported: unknown"); + if (hsz == 12) + { + s->img_x = get16le(s); + s->img_y = get16le(s); + } + else + { + s->img_x = get32le(s); + s->img_y = get32le(s); + } + if (get16le(s) != 1) return epuc("bad BMP", "bad BMP"); + bpp = get16le(s); + if (bpp == 1) return epuc("monochrome", "BMP type not supported: 1-bit"); + flip_vertically = ((int)s->img_y) > 0; + s->img_y = abs((int)s->img_y); + if (hsz == 12) + { + if (bpp < 24) + psize = (offset - 14 - 24) / 3; + } + else + { + compress = get32le(s); + if (compress == 1 || compress == 2) return epuc("BMP RLE", "BMP type not supported: RLE"); + get32le(s); // discard sizeof + get32le(s); // discard hres + get32le(s); // discard vres + get32le(s); // discard colorsused + get32le(s); // discard max important + if (hsz == 40 || hsz == 56) + { + if (hsz == 56) + { + get32le(s); + get32le(s); + get32le(s); + get32le(s); + } + if (bpp == 16 || bpp == 32) + { + mr = mg = mb = 0; + if (compress == 0) + { + if (bpp == 32) + { + mr = 0xffu << 16; + mg = 0xffu << 8; + mb = 0xffu << 0; + ma = 0xffu << 24; + //fake_a = 1; // @TODO: check for cases like alpha value is all 0 and switch it to 255 + } + else + { + mr = 31u << 10; + mg = 31u << 5; + mb = 31u << 0; + } + } + else if (compress == 3) + { + mr = get32le(s); + mg = get32le(s); + mb = get32le(s); + // not documented, but generated by photoshop and handled by mspaint + if (mr == mg && mg == mb) + { + // ?!?!? + return epuc("bad BMP", "bad BMP"); + } + } + else + return epuc("bad BMP", "bad BMP"); + } + } + else + { + assert(hsz == 108); + mr = get32le(s); + mg = get32le(s); + mb = get32le(s); + ma = get32le(s); + get32le(s); // discard color space + for (i = 0; i < 12; ++i) + get32le(s); // discard color space parameters + } + if (bpp < 16) + psize = (offset - 14 - hsz) >> 2; + } + s->img_n = ma ? 4 : 3; + if (req_comp && req_comp >= 3) // we can directly decode 3 or 4 + target = req_comp; + else + target = s->img_n; // if they want monochrome, we'll post-convert + out = (stbi_uc *)malloc(target * s->img_x * s->img_y); + if (!out) return epuc("outofmem", "Out of memory"); + if (bpp < 16) + { + int z = 0; + if (psize == 0 || psize > 256) + { + free(out); + return epuc("invalid", "Corrupt BMP"); + } + for (i = 0; i < psize; ++i) + { + pal[i][2] = get8u(s); + pal[i][1] = get8u(s); + pal[i][0] = get8u(s); + if (hsz != 12) get8(s); + pal[i][3] = 255; + } + skip(s, offset - 14 - hsz - psize * (hsz == 12 ? 3 : 4)); + if (bpp == 4) + width = (s->img_x + 1) >> 1; + else if (bpp == 8) + width = s->img_x; + else + { + free(out); + return epuc("bad bpp", "Corrupt BMP"); + } + pad = (-width) & 3; + for (j = 0; j < (int)s->img_y; ++j) + { + for (i = 0; i < (int)s->img_x; i += 2) + { + int v = get8(s), v2 = 0; + if (bpp == 4) + { + v2 = v & 15; + v >>= 4; + } + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + if (i + 1 == (int)s->img_x) break; + v = (bpp == 8) ? get8(s) : v2; + out[z++] = pal[v][0]; + out[z++] = pal[v][1]; + out[z++] = pal[v][2]; + if (target == 4) out[z++] = 255; + } + skip(s, pad); + } + } + else + { + int rshift = 0, gshift = 0, bshift = 0, ashift = 0, rcount = 0, gcount = 0, bcount = 0, acount = 0; + int z = 0; + int easy = 0; + skip(s, offset - 14 - hsz); + if (bpp == 24) + width = 3 * s->img_x; + else if (bpp == 16) + width = 2 * s->img_x; + else /* bpp = 32 and pad = 0 */ + width = 0; + pad = (-width) & 3; + if (bpp == 24) + { + easy = 1; + } + else if (bpp == 32) + { + if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) + easy = 2; + } + if (!easy) + { + if (!mr || !mg || !mb) + { + free(out); + return epuc("bad masks", "Corrupt BMP"); + } + // right shift amt to put high bit in position #7 + rshift = high_bit(mr) - 7; + rcount = bitcount(mr); + gshift = high_bit(mg) - 7; + gcount = bitcount(mr); + bshift = high_bit(mb) - 7; + bcount = bitcount(mr); + ashift = high_bit(ma) - 7; + acount = bitcount(mr); + } + for (j = 0; j < (int)s->img_y; ++j) + { + if (easy) + { + for (i = 0; i < (int)s->img_x; ++i) + { + int a; + out[z + 2] = get8u(s); + out[z + 1] = get8u(s); + out[z + 0] = get8u(s); + z += 3; + a = (easy == 2 ? get8(s) : 255); + if (target == 4) out[z++] = (uint8)a; + } + } + else + { + for (i = 0; i < (int)s->img_x; ++i) + { + uint32 v = (bpp == 16 ? get16le(s) : get32le(s)); + int a; + out[z++] = (uint8)shiftsigned(v & mr, rshift, rcount); + out[z++] = (uint8)shiftsigned(v & mg, gshift, gcount); + out[z++] = (uint8)shiftsigned(v & mb, bshift, bcount); + a = (ma ? shiftsigned(v & ma, ashift, acount) : 255); + if (target == 4) out[z++] = (uint8)a; + } + } + skip(s, pad); + } + } + if (flip_vertically) + { + stbi_uc t; + for (j = 0; j<(int)s->img_y>> 1; ++j) + { + stbi_uc *p1 = out + j * s->img_x * target; + stbi_uc *p2 = out + (s->img_y - 1 - j) * s->img_x * target; + for (i = 0; i < (int)s->img_x * target; ++i) + { + t = p1[i], p1[i] = p2[i], p2[i] = t; + } + } + } - if (req_comp && req_comp != target) { - out = convert_format(out, target, req_comp, s->img_x, s->img_y); - if (out == NULL) return out; // convert_format frees input on failure - } + if (req_comp && req_comp != target) + { + out = convert_format(out, target, req_comp, s->img_x, s->img_y); + if (out == NULL) return out; // convert_format frees input on failure + } - *x = s->img_x; - *y = s->img_y; - if (comp) *comp = s->img_n; - return out; + *x = s->img_x; + *y = s->img_y; + if (comp) *comp = s->img_n; + return out; } -static stbi_uc *stbi_bmp_load(stbi *s,int *x, int *y, int *comp, int req_comp) +static stbi_uc *stbi_bmp_load(stbi *s, int *x, int *y, int *comp, int req_comp) { - return bmp_load(s, x,y,comp,req_comp); + return bmp_load(s, x, y, comp, req_comp); } - // Targa Truevision - TGA // by Jonathan Dummer static int tga_info(stbi *s, int *x, int *y, int *comp) { - int tga_w, tga_h, tga_comp; - int sz; - get8u(s); // discard Offset - sz = get8u(s); // color type - if( sz > 1 ) { - stbi_rewind(s); - return 0; // only RGB or indexed allowed - } - sz = get8u(s); // image type - // only RGB or grey allowed, +/- RLE - if ((sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11)) return 0; - skip(s,9); - tga_w = get16le(s); - if( tga_w < 1 ) { - stbi_rewind(s); - return 0; // test width - } - tga_h = get16le(s); - if( tga_h < 1 ) { - stbi_rewind(s); - return 0; // test height - } - sz = get8(s); // bits per pixel - // only RGB or RGBA or grey allowed - if ((sz != 8) && (sz != 16) && (sz != 24) && (sz != 32)) { - stbi_rewind(s); - return 0; - } - tga_comp = sz; - if (x) *x = tga_w; - if (y) *y = tga_h; - if (comp) *comp = tga_comp / 8; - return 1; // seems to have passed everything + int tga_w, tga_h, tga_comp; + int sz; + get8u(s); // discard Offset + sz = get8u(s); // color type + if (sz > 1) + { + stbi_rewind(s); + return 0; // only RGB or indexed allowed + } + sz = get8u(s); // image type + // only RGB or grey allowed, +/- RLE + if ((sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11)) return 0; + skip(s, 9); + tga_w = get16le(s); + if (tga_w < 1) + { + stbi_rewind(s); + return 0; // test width + } + tga_h = get16le(s); + if (tga_h < 1) + { + stbi_rewind(s); + return 0; // test height + } + sz = get8(s); // bits per pixel + // only RGB or RGBA or grey allowed + if ((sz != 8) && (sz != 16) && (sz != 24) && (sz != 32)) + { + stbi_rewind(s); + return 0; + } + tga_comp = sz; + if (x) *x = tga_w; + if (y) *y = tga_h; + if (comp) *comp = tga_comp / 8; + return 1; // seems to have passed everything } int stbi_tga_info(stbi *s, int *x, int *y, int *comp) { - return tga_info(s, x, y, comp); + return tga_info(s, x, y, comp); } static int tga_test(stbi *s) { - int sz; - get8u(s); // discard Offset - sz = get8u(s); // color type - if ( sz > 1 ) return 0; // only RGB or indexed allowed - sz = get8u(s); // image type - if ( (sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11) ) return 0; // only RGB or grey allowed, +/- RLE - get16(s); // discard palette start - get16(s); // discard palette length - get8(s); // discard bits per palette color entry - get16(s); // discard x origin - get16(s); // discard y origin - if ( get16(s) < 1 ) return 0; // test width - if ( get16(s) < 1 ) return 0; // test height - sz = get8(s); // bits per pixel - if ( (sz != 8) && (sz != 16) && (sz != 24) && (sz != 32) ) return 0; // only RGB or RGBA or grey allowed - return 1; // seems to have passed everything + int sz; + get8u(s); // discard Offset + sz = get8u(s); // color type + if (sz > 1) return 0; // only RGB or indexed allowed + sz = get8u(s); // image type + if ((sz != 1) && (sz != 2) && (sz != 3) && (sz != 9) && (sz != 10) && (sz != 11)) return 0; // only RGB or grey allowed, +/- RLE + get16(s); // discard palette start + get16(s); // discard palette length + get8(s); // discard bits per palette color entry + get16(s); // discard x origin + get16(s); // discard y origin + if (get16(s) < 1) return 0; // test width + if (get16(s) < 1) return 0; // test height + sz = get8(s); // bits per pixel + if ((sz != 8) && (sz != 16) && (sz != 24) && (sz != 32)) return 0; // only RGB or RGBA or grey allowed + return 1; // seems to have passed everything } static int stbi_tga_test(stbi *s) { - int res = tga_test(s); - stbi_rewind(s); - return res; + int res = tga_test(s); + stbi_rewind(s); + return res; } static stbi_uc *tga_load(stbi *s, int *x, int *y, int *comp, int req_comp) { - // read in the TGA header stuff - int tga_offset = get8u(s); - int tga_indexed = get8u(s); - int tga_image_type = get8u(s); - int tga_is_RLE = 0; - int tga_palette_start = get16le(s); - int tga_palette_len = get16le(s); - int tga_palette_bits = get8u(s); - int tga_x_origin = get16le(s); - int tga_y_origin = get16le(s); - int tga_width = get16le(s); - int tga_height = get16le(s); - int tga_bits_per_pixel = get8u(s); - int tga_inverted = get8u(s); - // image data - unsigned char *tga_data; - unsigned char *tga_palette = NULL; - int i, j; - unsigned char raw_data[4]; - unsigned char trans_data[4]; - int RLE_count = 0; - int RLE_repeating = 0; - int read_next_pixel = 1; + // read in the TGA header stuff + int tga_offset = get8u(s); + int tga_indexed = get8u(s); + int tga_image_type = get8u(s); + int tga_is_RLE = 0; + int tga_palette_start = get16le(s); + int tga_palette_len = get16le(s); + int tga_palette_bits = get8u(s); + int tga_x_origin = get16le(s); + int tga_y_origin = get16le(s); + int tga_width = get16le(s); + int tga_height = get16le(s); + int tga_bits_per_pixel = get8u(s); + int tga_inverted = get8u(s); + // image data + unsigned char *tga_data; + unsigned char *tga_palette = NULL; + int i, j; + unsigned char raw_data[4]; + unsigned char trans_data[4]; + int RLE_count = 0; + int RLE_repeating = 0; + int read_next_pixel = 1; - // do a tiny bit of precessing - if ( tga_image_type >= 8 ) - { - tga_image_type -= 8; - tga_is_RLE = 1; - } - /* int tga_alpha_bits = tga_inverted & 15; */ - tga_inverted = 1 - ((tga_inverted >> 5) & 1); + // do a tiny bit of precessing + if (tga_image_type >= 8) + { + tga_image_type -= 8; + tga_is_RLE = 1; + } + /* int tga_alpha_bits = tga_inverted & 15; */ + tga_inverted = 1 - ((tga_inverted >> 5) & 1); - // error check - if ( //(tga_indexed) || - (tga_width < 1) || (tga_height < 1) || - (tga_image_type < 1) || (tga_image_type > 3) || - ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16) && - (tga_bits_per_pixel != 24) && (tga_bits_per_pixel != 32)) - ) - { - return NULL; // we don't report this as a bad TGA because we don't even know if it's TGA - } + // error check + if ( //(tga_indexed) || + (tga_width < 1) || (tga_height < 1) || + (tga_image_type < 1) || (tga_image_type > 3) || + ((tga_bits_per_pixel != 8) && (tga_bits_per_pixel != 16) && + (tga_bits_per_pixel != 24) && (tga_bits_per_pixel != 32))) + { + return NULL; // we don't report this as a bad TGA because we don't even know if it's TGA + } - // If I'm paletted, then I'll use the number of bits from the palette - if ( tga_indexed ) - { - tga_bits_per_pixel = tga_palette_bits; - } + // If I'm paletted, then I'll use the number of bits from the palette + if (tga_indexed) + { + tga_bits_per_pixel = tga_palette_bits; + } - // tga info - *x = tga_width; - *y = tga_height; - if ( (req_comp < 1) || (req_comp > 4) ) - { - // just use whatever the file was - req_comp = tga_bits_per_pixel / 8; - *comp = req_comp; - } else - { - // force a new number of components - *comp = tga_bits_per_pixel/8; - } - tga_data = (unsigned char*)malloc( tga_width * tga_height * req_comp ); - if (!tga_data) return epuc("outofmem", "Out of memory"); + // tga info + *x = tga_width; + *y = tga_height; + if ((req_comp < 1) || (req_comp > 4)) + { + // just use whatever the file was + req_comp = tga_bits_per_pixel / 8; + *comp = req_comp; + } + else + { + // force a new number of components + *comp = tga_bits_per_pixel / 8; + } + tga_data = (unsigned char *)malloc(tga_width * tga_height * req_comp); + if (!tga_data) return epuc("outofmem", "Out of memory"); - // skip to the data's starting position (offset usually = 0) - skip(s, tga_offset ); - // do I need to load a palette? - if ( tga_indexed ) - { - // any data to skip? (offset usually = 0) - skip(s, tga_palette_start ); - // load the palette - tga_palette = (unsigned char*)malloc( tga_palette_len * tga_palette_bits / 8 ); - if (!tga_palette) return epuc("outofmem", "Out of memory"); - if (!getn(s, tga_palette, tga_palette_len * tga_palette_bits / 8 )) { - free(tga_data); - free(tga_palette); - return epuc("bad palette", "Corrupt TGA"); - } - } - // load the data - trans_data[0] = trans_data[1] = trans_data[2] = trans_data[3] = 0; - for (i=0; i < tga_width * tga_height; ++i) - { - // if I'm in RLE mode, do I need to get a RLE chunk? - if ( tga_is_RLE ) - { - if ( RLE_count == 0 ) - { - // yep, get the next byte as a RLE command - int RLE_cmd = get8u(s); - RLE_count = 1 + (RLE_cmd & 127); - RLE_repeating = RLE_cmd >> 7; - read_next_pixel = 1; - } else if ( !RLE_repeating ) - { - read_next_pixel = 1; - } - } else - { - read_next_pixel = 1; - } - // OK, if I need to read a pixel, do it now - if ( read_next_pixel ) - { - // load however much data we did have - if ( tga_indexed ) - { - // read in 1 byte, then perform the lookup - int pal_idx = get8u(s); - if ( pal_idx >= tga_palette_len ) - { - // invalid index - pal_idx = 0; - } - pal_idx *= tga_bits_per_pixel / 8; - for (j = 0; j*8 < tga_bits_per_pixel; ++j) - { - raw_data[j] = tga_palette[pal_idx+j]; - } - } else - { - // read in the data raw - for (j = 0; j*8 < tga_bits_per_pixel; ++j) - { - raw_data[j] = get8u(s); - } - } - // convert raw to the intermediate format - switch (tga_bits_per_pixel) - { - case 8: - // Luminous => RGBA - trans_data[0] = raw_data[0]; - trans_data[1] = raw_data[0]; - trans_data[2] = raw_data[0]; - trans_data[3] = 255; - break; - case 16: - // Luminous,Alpha => RGBA - trans_data[0] = raw_data[0]; - trans_data[1] = raw_data[0]; - trans_data[2] = raw_data[0]; - trans_data[3] = raw_data[1]; - break; - case 24: - // BGR => RGBA - trans_data[0] = raw_data[2]; - trans_data[1] = raw_data[1]; - trans_data[2] = raw_data[0]; - trans_data[3] = 255; - break; - case 32: - // BGRA => RGBA - trans_data[0] = raw_data[2]; - trans_data[1] = raw_data[1]; - trans_data[2] = raw_data[0]; - trans_data[3] = raw_data[3]; - break; - } - // clear the reading flag for the next pixel - read_next_pixel = 0; - } // end of reading a pixel - // convert to final format - switch (req_comp) - { - case 1: - // RGBA => Luminance - tga_data[i*req_comp+0] = compute_y(trans_data[0],trans_data[1],trans_data[2]); - break; - case 2: - // RGBA => Luminance,Alpha - tga_data[i*req_comp+0] = compute_y(trans_data[0],trans_data[1],trans_data[2]); - tga_data[i*req_comp+1] = trans_data[3]; - break; - case 3: - // RGBA => RGB - tga_data[i*req_comp+0] = trans_data[0]; - tga_data[i*req_comp+1] = trans_data[1]; - tga_data[i*req_comp+2] = trans_data[2]; - break; - case 4: - // RGBA => RGBA - tga_data[i*req_comp+0] = trans_data[0]; - tga_data[i*req_comp+1] = trans_data[1]; - tga_data[i*req_comp+2] = trans_data[2]; - tga_data[i*req_comp+3] = trans_data[3]; - break; - } - // in case we're in RLE mode, keep counting down - --RLE_count; - } - // do I need to invert the image? - if ( tga_inverted ) - { - for (j = 0; j*2 < tga_height; ++j) - { - int index1 = j * tga_width * req_comp; - int index2 = (tga_height - 1 - j) * tga_width * req_comp; - for (i = tga_width * req_comp; i > 0; --i) - { - unsigned char temp = tga_data[index1]; - tga_data[index1] = tga_data[index2]; - tga_data[index2] = temp; - ++index1; - ++index2; - } - } - } - // clear my palette, if I had one - if ( tga_palette != NULL ) - { - free( tga_palette ); - } - // the things I do to get rid of an error message, and yet keep - // Microsoft's C compilers happy... [8^( - tga_palette_start = tga_palette_len = tga_palette_bits = - tga_x_origin = tga_y_origin = 0; - // OK, done - return tga_data; + // skip to the data's starting position (offset usually = 0) + skip(s, tga_offset); + // do I need to load a palette? + if (tga_indexed) + { + // any data to skip? (offset usually = 0) + skip(s, tga_palette_start); + // load the palette + tga_palette = (unsigned char *)malloc(tga_palette_len * tga_palette_bits / 8); + if (!tga_palette) return epuc("outofmem", "Out of memory"); + if (!getn(s, tga_palette, tga_palette_len * tga_palette_bits / 8)) + { + free(tga_data); + free(tga_palette); + return epuc("bad palette", "Corrupt TGA"); + } + } + // load the data + trans_data[0] = trans_data[1] = trans_data[2] = trans_data[3] = 0; + for (i = 0; i < tga_width * tga_height; ++i) + { + // if I'm in RLE mode, do I need to get a RLE chunk? + if (tga_is_RLE) + { + if (RLE_count == 0) + { + // yep, get the next byte as a RLE command + int RLE_cmd = get8u(s); + RLE_count = 1 + (RLE_cmd & 127); + RLE_repeating = RLE_cmd >> 7; + read_next_pixel = 1; + } + else if (!RLE_repeating) + { + read_next_pixel = 1; + } + } + else + { + read_next_pixel = 1; + } + // OK, if I need to read a pixel, do it now + if (read_next_pixel) + { + // load however much data we did have + if (tga_indexed) + { + // read in 1 byte, then perform the lookup + int pal_idx = get8u(s); + if (pal_idx >= tga_palette_len) + { + // invalid index + pal_idx = 0; + } + pal_idx *= tga_bits_per_pixel / 8; + for (j = 0; j * 8 < tga_bits_per_pixel; ++j) + { + raw_data[j] = tga_palette[pal_idx + j]; + } + } + else + { + // read in the data raw + for (j = 0; j * 8 < tga_bits_per_pixel; ++j) + { + raw_data[j] = get8u(s); + } + } + // convert raw to the intermediate format + switch (tga_bits_per_pixel) + { + case 8: + // Luminous => RGBA + trans_data[0] = raw_data[0]; + trans_data[1] = raw_data[0]; + trans_data[2] = raw_data[0]; + trans_data[3] = 255; + break; + case 16: + // Luminous,Alpha => RGBA + trans_data[0] = raw_data[0]; + trans_data[1] = raw_data[0]; + trans_data[2] = raw_data[0]; + trans_data[3] = raw_data[1]; + break; + case 24: + // BGR => RGBA + trans_data[0] = raw_data[2]; + trans_data[1] = raw_data[1]; + trans_data[2] = raw_data[0]; + trans_data[3] = 255; + break; + case 32: + // BGRA => RGBA + trans_data[0] = raw_data[2]; + trans_data[1] = raw_data[1]; + trans_data[2] = raw_data[0]; + trans_data[3] = raw_data[3]; + break; + } + // clear the reading flag for the next pixel + read_next_pixel = 0; + } // end of reading a pixel + // convert to final format + switch (req_comp) + { + case 1: + // RGBA => Luminance + tga_data[i * req_comp + 0] = compute_y(trans_data[0], trans_data[1], trans_data[2]); + break; + case 2: + // RGBA => Luminance,Alpha + tga_data[i * req_comp + 0] = compute_y(trans_data[0], trans_data[1], trans_data[2]); + tga_data[i * req_comp + 1] = trans_data[3]; + break; + case 3: + // RGBA => RGB + tga_data[i * req_comp + 0] = trans_data[0]; + tga_data[i * req_comp + 1] = trans_data[1]; + tga_data[i * req_comp + 2] = trans_data[2]; + break; + case 4: + // RGBA => RGBA + tga_data[i * req_comp + 0] = trans_data[0]; + tga_data[i * req_comp + 1] = trans_data[1]; + tga_data[i * req_comp + 2] = trans_data[2]; + tga_data[i * req_comp + 3] = trans_data[3]; + break; + } + // in case we're in RLE mode, keep counting down + --RLE_count; + } + // do I need to invert the image? + if (tga_inverted) + { + for (j = 0; j * 2 < tga_height; ++j) + { + int index1 = j * tga_width * req_comp; + int index2 = (tga_height - 1 - j) * tga_width * req_comp; + for (i = tga_width * req_comp; i > 0; --i) + { + unsigned char temp = tga_data[index1]; + tga_data[index1] = tga_data[index2]; + tga_data[index2] = temp; + ++index1; + ++index2; + } + } + } + // clear my palette, if I had one + if (tga_palette != NULL) + { + free(tga_palette); + } + // the things I do to get rid of an error message, and yet keep + // Microsoft's C compilers happy... [8^( + tga_palette_start = tga_palette_len = tga_palette_bits = + tga_x_origin = tga_y_origin = 0; + // OK, done + return tga_data; } static stbi_uc *stbi_tga_load(stbi *s, int *x, int *y, int *comp, int req_comp) { - return tga_load(s,x,y,comp,req_comp); + return tga_load(s, x, y, comp, req_comp); } - // ************************************************************************************************* // Photoshop PSD loader -- PD by Thatcher Ulrich, integration by Nicolas Schulz, tweaked by STB static int psd_test(stbi *s) { - if (get32(s) != 0x38425053) return 0; // "8BPS" - else return 1; + if (get32(s) != 0x38425053) + return 0; // "8BPS" + else + return 1; } static int stbi_psd_test(stbi *s) { - int r = psd_test(s); - stbi_rewind(s); - return r; + int r = psd_test(s); + stbi_rewind(s); + return r; } static stbi_uc *psd_load(stbi *s, int *x, int *y, int *comp, int req_comp) { - int pixelCount; - int channelCount, compression; - int channel, i, count, len; - int w,h; - uint8 *out; + int pixelCount; + int channelCount, compression; + int channel, i, count, len; + int w, h; + uint8 *out; - // Check identifier - if (get32(s) != 0x38425053) // "8BPS" - return epuc("not PSD", "Corrupt PSD image"); + // Check identifier + if (get32(s) != 0x38425053) // "8BPS" + return epuc("not PSD", "Corrupt PSD image"); - // Check file type version. - if (get16(s) != 1) - return epuc("wrong version", "Unsupported version of PSD image"); + // Check file type version. + if (get16(s) != 1) + return epuc("wrong version", "Unsupported version of PSD image"); - // Skip 6 reserved bytes. - skip(s, 6 ); + // Skip 6 reserved bytes. + skip(s, 6); - // Read the number of channels (R, G, B, A, etc). - channelCount = get16(s); - if (channelCount < 0 || channelCount > 16) - return epuc("wrong channel count", "Unsupported number of channels in PSD image"); + // Read the number of channels (R, G, B, A, etc). + channelCount = get16(s); + if (channelCount < 0 || channelCount > 16) + return epuc("wrong channel count", "Unsupported number of channels in PSD image"); - // Read the rows and columns of the image. - h = get32(s); - w = get32(s); - - // Make sure the depth is 8 bits. - if (get16(s) != 8) - return epuc("unsupported bit depth", "PSD bit depth is not 8 bit"); + // Read the rows and columns of the image. + h = get32(s); + w = get32(s); - // Make sure the color mode is RGB. - // Valid options are: - // 0: Bitmap - // 1: Grayscale - // 2: Indexed color - // 3: RGB color - // 4: CMYK color - // 7: Multichannel - // 8: Duotone - // 9: Lab color - if (get16(s) != 3) - return epuc("wrong color format", "PSD is not in RGB color format"); + // Make sure the depth is 8 bits. + if (get16(s) != 8) + return epuc("unsupported bit depth", "PSD bit depth is not 8 bit"); - // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) - skip(s,get32(s) ); + // Make sure the color mode is RGB. + // Valid options are: + // 0: Bitmap + // 1: Grayscale + // 2: Indexed color + // 3: RGB color + // 4: CMYK color + // 7: Multichannel + // 8: Duotone + // 9: Lab color + if (get16(s) != 3) + return epuc("wrong color format", "PSD is not in RGB color format"); - // Skip the image resources. (resolution, pen tool paths, etc) - skip(s, get32(s) ); + // Skip the Mode Data. (It's the palette for indexed color; other info for other modes.) + skip(s, get32(s)); - // Skip the reserved data. - skip(s, get32(s) ); + // Skip the image resources. (resolution, pen tool paths, etc) + skip(s, get32(s)); - // Find out if the data is compressed. - // Known values: - // 0: no compression - // 1: RLE compressed - compression = get16(s); - if (compression > 1) - return epuc("bad compression", "PSD has an unknown compression format"); + // Skip the reserved data. + skip(s, get32(s)); - // Create the destination image. - out = (stbi_uc *) malloc(4 * w*h); - if (!out) return epuc("outofmem", "Out of memory"); - pixelCount = w*h; + // Find out if the data is compressed. + // Known values: + // 0: no compression + // 1: RLE compressed + compression = get16(s); + if (compression > 1) + return epuc("bad compression", "PSD has an unknown compression format"); - // Initialize the data to zero. - //memset( out, 0, pixelCount * 4 ); - - // Finally, the image data. - if (compression) { - // RLE as used by .PSD and .TIFF - // Loop until you get the number of unpacked bytes you are expecting: - // Read the next source byte into n. - // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. - // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. - // Else if n is 128, noop. - // Endloop + // Create the destination image. + out = (stbi_uc *)malloc(4 * w * h); + if (!out) return epuc("outofmem", "Out of memory"); + pixelCount = w * h; - // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data, - // which we're going to just skip. - skip(s, h * channelCount * 2 ); + // Initialize the data to zero. + //memset( out, 0, pixelCount * 4 ); - // Read the RLE data by channel. - for (channel = 0; channel < 4; channel++) { - uint8 *p; - - p = out+channel; - if (channel >= channelCount) { - // Fill this channel with default data. - for (i = 0; i < pixelCount; i++) *p = (channel == 3 ? 255 : 0), p += 4; - } else { - // Read the RLE data. - count = 0; - while (count < pixelCount) { - len = get8(s); - if (len == 128) { - // No-op. - } else if (len < 128) { - // Copy next len+1 bytes literally. - len++; - count += len; - while (len) { - *p = get8u(s); - p += 4; - len--; - } - } else if (len > 128) { - uint8 val; - // Next -len+1 bytes in the dest are replicated from next source byte. - // (Interpret len as a negative 8-bit int.) - len ^= 0x0FF; - len += 2; - val = get8u(s); - count += len; - while (len) { - *p = val; - p += 4; - len--; - } - } - } - } - } - - } else { - // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) - // where each channel consists of an 8-bit value for each pixel in the image. - - // Read the data by channel. - for (channel = 0; channel < 4; channel++) { - uint8 *p; - - p = out + channel; - if (channel > channelCount) { - // Fill this channel with default data. - for (i = 0; i < pixelCount; i++) *p = channel == 3 ? 255 : 0, p += 4; - } else { - // Read the data. - for (i = 0; i < pixelCount; i++) - *p = get8u(s), p += 4; - } - } - } + // Finally, the image data. + if (compression) + { + // RLE as used by .PSD and .TIFF + // Loop until you get the number of unpacked bytes you are expecting: + // Read the next source byte into n. + // If n is between 0 and 127 inclusive, copy the next n+1 bytes literally. + // Else if n is between -127 and -1 inclusive, copy the next byte -n+1 times. + // Else if n is 128, noop. + // Endloop - if (req_comp && req_comp != 4) { - out = convert_format(out, 4, req_comp, w, h); - if (out == NULL) return out; // convert_format frees input on failure - } + // The RLE-compressed data is preceeded by a 2-byte data count for each row in the data, + // which we're going to just skip. + skip(s, h * channelCount * 2); - if (comp) *comp = channelCount; - *y = h; - *x = w; - - return out; + // Read the RLE data by channel. + for (channel = 0; channel < 4; channel++) + { + uint8 *p; + + p = out + channel; + if (channel >= channelCount) + { + // Fill this channel with default data. + for (i = 0; i < pixelCount; i++) *p = (channel == 3 ? 255 : 0), p += 4; + } + else + { + // Read the RLE data. + count = 0; + while (count < pixelCount) + { + len = get8(s); + if (len == 128) + { + // No-op. + } + else if (len < 128) + { + // Copy next len+1 bytes literally. + len++; + count += len; + while (len) + { + *p = get8u(s); + p += 4; + len--; + } + } + else if (len > 128) + { + uint8 val; + // Next -len+1 bytes in the dest are replicated from next source byte. + // (Interpret len as a negative 8-bit int.) + len ^= 0x0FF; + len += 2; + val = get8u(s); + count += len; + while (len) + { + *p = val; + p += 4; + len--; + } + } + } + } + } + } + else + { + // We're at the raw image data. It's each channel in order (Red, Green, Blue, Alpha, ...) + // where each channel consists of an 8-bit value for each pixel in the image. + + // Read the data by channel. + for (channel = 0; channel < 4; channel++) + { + uint8 *p; + + p = out + channel; + if (channel > channelCount) + { + // Fill this channel with default data. + for (i = 0; i < pixelCount; i++) *p = channel == 3 ? 255 : 0, p += 4; + } + else + { + // Read the data. + for (i = 0; i < pixelCount; i++) + *p = get8u(s), p += 4; + } + } + } + + if (req_comp && req_comp != 4) + { + out = convert_format(out, 4, req_comp, w, h); + if (out == NULL) return out; // convert_format frees input on failure + } + + if (comp) *comp = channelCount; + *y = h; + *x = w; + + return out; } static stbi_uc *stbi_psd_load(stbi *s, int *x, int *y, int *comp, int req_comp) { - return psd_load(s,x,y,comp,req_comp); + return psd_load(s, x, y, comp, req_comp); } // ************************************************************************************************* @@ -3307,951 +3753,1053 @@ static stbi_uc *stbi_psd_load(stbi *s, int *x, int *y, int *comp, int req_comp) // See http://softimage.wiki.softimage.com/index.php/INFO:_PIC_file_format // See http://ozviz.wasp.uwa.edu.au/~pbourke/dataformats/softimagepic/ -static int pic_is4(stbi *s,const char *str) +static int pic_is4(stbi *s, const char *str) { - int i; - for (i=0; i<4; ++i) - if (get8(s) != (stbi_uc)str[i]) - return 0; + int i; + for (i = 0; i < 4; ++i) + if (get8(s) != (stbi_uc)str[i]) + return 0; - return 1; + return 1; } static int pic_test(stbi *s) { - int i; + int i; - if (!pic_is4(s,"\x53\x80\xF6\x34")) - return 0; + if (!pic_is4(s, "\x53\x80\xF6\x34")) + return 0; - for(i=0;i<84;++i) - get8(s); + for (i = 0; i < 84; ++i) + get8(s); - if (!pic_is4(s,"PICT")) - return 0; + if (!pic_is4(s, "PICT")) + return 0; - return 1; + return 1; } typedef struct { - stbi_uc size,type,channel; + stbi_uc size, type, channel; } pic_packet_t; static stbi_uc *pic_readval(stbi *s, int channel, stbi_uc *dest) { - int mask=0x80, i; + int mask = 0x80, i; - for (i=0; i<4; ++i, mask>>=1) { - if (channel & mask) { - if (at_eof(s)) return epuc("bad file","PIC file too short"); - dest[i]=get8u(s); - } - } + for (i = 0; i < 4; ++i, mask >>= 1) + { + if (channel & mask) + { + if (at_eof(s)) return epuc("bad file", "PIC file too short"); + dest[i] = get8u(s); + } + } - return dest; + return dest; } -static void pic_copyval(int channel,stbi_uc *dest,const stbi_uc *src) +static void pic_copyval(int channel, stbi_uc *dest, const stbi_uc *src) { - int mask=0x80,i; + int mask = 0x80, i; - for (i=0;i<4; ++i, mask>>=1) - if (channel&mask) - dest[i]=src[i]; + for (i = 0; i < 4; ++i, mask >>= 1) + if (channel & mask) + dest[i] = src[i]; } -static stbi_uc *pic_load2(stbi *s,int width,int height,int *comp, stbi_uc *result) +static stbi_uc *pic_load2(stbi *s, int width, int height, int *comp, stbi_uc *result) { - int act_comp=0,num_packets=0,y,chained; - pic_packet_t packets[10]; + int act_comp = 0, num_packets = 0, y, chained; + pic_packet_t packets[10]; - // this will (should...) cater for even some bizarre stuff like having data - // for the same channel in multiple packets. - do { - pic_packet_t *packet; + // this will (should...) cater for even some bizarre stuff like having data + // for the same channel in multiple packets. + do + { + pic_packet_t *packet; - if (num_packets==sizeof(packets)/sizeof(packets[0])) - return epuc("bad format","too many packets"); + if (num_packets == sizeof(packets) / sizeof(packets[0])) + return epuc("bad format", "too many packets"); - packet = &packets[num_packets++]; + packet = &packets[num_packets++]; - chained = get8(s); - packet->size = get8u(s); - packet->type = get8u(s); - packet->channel = get8u(s); + chained = get8(s); + packet->size = get8u(s); + packet->type = get8u(s); + packet->channel = get8u(s); - act_comp |= packet->channel; + act_comp |= packet->channel; - if (at_eof(s)) return epuc("bad file","file too short (reading packets)"); - if (packet->size != 8) return epuc("bad format","packet isn't 8bpp"); - } while (chained); + if (at_eof(s)) return epuc("bad file", "file too short (reading packets)"); + if (packet->size != 8) return epuc("bad format", "packet isn't 8bpp"); + } while (chained); - *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? + *comp = (act_comp & 0x10 ? 4 : 3); // has alpha channel? - for(y=0; ytype) { - default: - return epuc("bad format","packet has bad compression type"); + switch (packet->type) + { + default: + return epuc("bad format", "packet has bad compression type"); - case 0: {//uncompressed - int x; + case 0: + { //uncompressed + int x; - for(x=0;xchannel,dest)) - return 0; - break; - } + for (x = 0; x < width; ++x, dest += 4) + if (!pic_readval(s, packet->channel, dest)) + return 0; + break; + } - case 1://Pure RLE - { - int left=width, i; + case 1: //Pure RLE + { + int left = width, i; - while (left>0) { - stbi_uc count,value[4]; + while (left > 0) + { + stbi_uc count, value[4]; - count=get8u(s); - if (at_eof(s)) return epuc("bad file","file too short (pure read count)"); + count = get8u(s); + if (at_eof(s)) return epuc("bad file", "file too short (pure read count)"); - if (count > left) - count = (uint8) left; + if (count > left) + count = (uint8)left; - if (!pic_readval(s,packet->channel,value)) return 0; + if (!pic_readval(s, packet->channel, value)) return 0; - for(i=0; ichannel,dest,value); - left -= count; - } - } - break; + for (i = 0; i < count; ++i, dest += 4) + pic_copyval(packet->channel, dest, value); + left -= count; + } + } + break; - case 2: {//Mixed RLE - int left=width; - while (left>0) { - int count = get8(s), i; - if (at_eof(s)) return epuc("bad file","file too short (mixed read count)"); + case 2: + { //Mixed RLE + int left = width; + while (left > 0) + { + int count = get8(s), i; + if (at_eof(s)) return epuc("bad file", "file too short (mixed read count)"); - if (count >= 128) { // Repeated - stbi_uc value[4]; - int i; + if (count >= 128) + { // Repeated + stbi_uc value[4]; + int i; - if (count==128) - count = get16(s); - else - count -= 127; - if (count > left) - return epuc("bad file","scanline overrun"); + if (count == 128) + count = get16(s); + else + count -= 127; + if (count > left) + return epuc("bad file", "scanline overrun"); - if (!pic_readval(s,packet->channel,value)) - return 0; + if (!pic_readval(s, packet->channel, value)) + return 0; - for(i=0;ichannel,dest,value); - } else { // Raw - ++count; - if (count>left) return epuc("bad file","scanline overrun"); + for (i = 0; i < count; ++i, dest += 4) + pic_copyval(packet->channel, dest, value); + } + else + { // Raw + ++count; + if (count > left) return epuc("bad file", "scanline overrun"); - for(i=0;ichannel,dest)) - return 0; - } - left-=count; - } - break; - } - } - } - } + for (i = 0; i < count; ++i, dest += 4) + if (!pic_readval(s, packet->channel, dest)) + return 0; + } + left -= count; + } + break; + } + } + } + } - return result; + return result; } -static stbi_uc *pic_load(stbi *s,int *px,int *py,int *comp,int req_comp) +static stbi_uc *pic_load(stbi *s, int *px, int *py, int *comp, int req_comp) { - stbi_uc *result; - int i, x,y; + stbi_uc *result; + int i, x, y; - for (i=0; i<92; ++i) - get8(s); + for (i = 0; i < 92; ++i) + get8(s); - x = get16(s); - y = get16(s); - if (at_eof(s)) return epuc("bad file","file too short (pic header)"); - if ((1 << 28) / x < y) return epuc("too large", "Image too large to decode"); + x = get16(s); + y = get16(s); + if (at_eof(s)) return epuc("bad file", "file too short (pic header)"); + if ((1 << 28) / x < y) return epuc("too large", "Image too large to decode"); - get32(s); //skip `ratio' - get16(s); //skip `fields' - get16(s); //skip `pad' + get32(s); //skip `ratio' + get16(s); //skip `fields' + get16(s); //skip `pad' - // intermediate buffer is RGBA - result = (stbi_uc *) malloc(x*y*4); - memset(result, 0xff, x*y*4); + // intermediate buffer is RGBA + result = (stbi_uc *)malloc(x * y * 4); + memset(result, 0xff, x * y * 4); - if (!pic_load2(s,x,y,comp, result)) { - free(result); - result=0; - } - *px = x; - *py = y; - if (req_comp == 0) req_comp = *comp; - result=convert_format(result,4,req_comp,x,y); + if (!pic_load2(s, x, y, comp, result)) + { + free(result); + result = 0; + } + *px = x; + *py = y; + if (req_comp == 0) req_comp = *comp; + result = convert_format(result, 4, req_comp, x, y); - return result; + return result; } static int stbi_pic_test(stbi *s) { - int r = pic_test(s); - stbi_rewind(s); - return r; + int r = pic_test(s); + stbi_rewind(s); + return r; } static stbi_uc *stbi_pic_load(stbi *s, int *x, int *y, int *comp, int req_comp) { - return pic_load(s,x,y,comp,req_comp); + return pic_load(s, x, y, comp, req_comp); } // ************************************************************************************************* // GIF loader -- public domain by Jean-Marc Lienher -- simplified/shrunk by stb -typedef struct stbi_gif_lzw_struct { - int16 prefix; - uint8 first; - uint8 suffix; +typedef struct stbi_gif_lzw_struct +{ + int16 prefix; + uint8 first; + uint8 suffix; } stbi_gif_lzw; typedef struct stbi_gif_struct { - int w,h; - stbi_uc *out; // output buffer (always 4 components) - int flags, bgindex, ratio, transparent, eflags; - uint8 pal[256][4]; - uint8 lpal[256][4]; - stbi_gif_lzw codes[4096]; - uint8 *color_table; - int parse, step; - int lflags; - int start_x, start_y; - int max_x, max_y; - int cur_x, cur_y; - int line_size; + int w, h; + stbi_uc *out; // output buffer (always 4 components) + int flags, bgindex, ratio, transparent, eflags; + uint8 pal[256][4]; + uint8 lpal[256][4]; + stbi_gif_lzw codes[4096]; + uint8 *color_table; + int parse, step; + int lflags; + int start_x, start_y; + int max_x, max_y; + int cur_x, cur_y; + int line_size; } stbi_gif; static int gif_test(stbi *s) { - int sz; - if (get8(s) != 'G' || get8(s) != 'I' || get8(s) != 'F' || get8(s) != '8') return 0; - sz = get8(s); - if (sz != '9' && sz != '7') return 0; - if (get8(s) != 'a') return 0; - return 1; + int sz; + if (get8(s) != 'G' || get8(s) != 'I' || get8(s) != 'F' || get8(s) != '8') return 0; + sz = get8(s); + if (sz != '9' && sz != '7') return 0; + if (get8(s) != 'a') return 0; + return 1; } static int stbi_gif_test(stbi *s) { - int r = gif_test(s); - stbi_rewind(s); - return r; + int r = gif_test(s); + stbi_rewind(s); + return r; } static void stbi_gif_parse_colortable(stbi *s, uint8 pal[256][4], int num_entries, int transp) { - int i; - for (i=0; i < num_entries; ++i) { - pal[i][2] = get8u(s); - pal[i][1] = get8u(s); - pal[i][0] = get8u(s); - pal[i][3] = transp ? 0 : 255; - } + int i; + for (i = 0; i < num_entries; ++i) + { + pal[i][2] = get8u(s); + pal[i][1] = get8u(s); + pal[i][0] = get8u(s); + pal[i][3] = transp ? 0 : 255; + } } static int stbi_gif_header(stbi *s, stbi_gif *g, int *comp, int is_info) { - uint8 version; - if (get8(s) != 'G' || get8(s) != 'I' || get8(s) != 'F' || get8(s) != '8') - return e("not GIF", "Corrupt GIF"); + uint8 version; + if (get8(s) != 'G' || get8(s) != 'I' || get8(s) != 'F' || get8(s) != '8') + return e("not GIF", "Corrupt GIF"); - version = get8u(s); - if (version != '7' && version != '9') return e("not GIF", "Corrupt GIF"); - if (get8(s) != 'a') return e("not GIF", "Corrupt GIF"); - - failure_reason = ""; - g->w = get16le(s); - g->h = get16le(s); - g->flags = get8(s); - g->bgindex = get8(s); - g->ratio = get8(s); - g->transparent = -1; + version = get8u(s); + if (version != '7' && version != '9') return e("not GIF", "Corrupt GIF"); + if (get8(s) != 'a') return e("not GIF", "Corrupt GIF"); - if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments + failure_reason = ""; + g->w = get16le(s); + g->h = get16le(s); + g->flags = get8(s); + g->bgindex = get8(s); + g->ratio = get8(s); + g->transparent = -1; - if (is_info) return 1; + if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments - if (g->flags & 0x80) - stbi_gif_parse_colortable(s,g->pal, 2 << (g->flags & 7), -1); + if (is_info) return 1; - return 1; + if (g->flags & 0x80) + stbi_gif_parse_colortable(s, g->pal, 2 << (g->flags & 7), -1); + + return 1; } static int stbi_gif_info_raw(stbi *s, int *x, int *y, int *comp) { - stbi_gif g; - if (!stbi_gif_header(s, &g, comp, 1)) { - stbi_rewind( s ); - return 0; - } - if (x) *x = g.w; - if (y) *y = g.h; - return 1; + stbi_gif g; + if (!stbi_gif_header(s, &g, comp, 1)) + { + stbi_rewind(s); + return 0; + } + if (x) *x = g.w; + if (y) *y = g.h; + return 1; } static void stbi_out_gif_code(stbi_gif *g, uint16 code) { - uint8 *p, *c; + uint8 *p, *c; - // recurse to decode the prefixes, since the linked-list is backwards, - // and working backwards through an interleaved image would be nasty - if (g->codes[code].prefix >= 0) - stbi_out_gif_code(g, g->codes[code].prefix); + // recurse to decode the prefixes, since the linked-list is backwards, + // and working backwards through an interleaved image would be nasty + if (g->codes[code].prefix >= 0) + stbi_out_gif_code(g, g->codes[code].prefix); - if (g->cur_y >= g->max_y) return; - - p = &g->out[g->cur_x + g->cur_y]; - c = &g->color_table[g->codes[code].suffix * 4]; + if (g->cur_y >= g->max_y) return; - if (c[3] >= 128) { - p[0] = c[2]; - p[1] = c[1]; - p[2] = c[0]; - p[3] = c[3]; - } - g->cur_x += 4; + p = &g->out[g->cur_x + g->cur_y]; + c = &g->color_table[g->codes[code].suffix * 4]; - if (g->cur_x >= g->max_x) { - g->cur_x = g->start_x; - g->cur_y += g->step; + if (c[3] >= 128) + { + p[0] = c[2]; + p[1] = c[1]; + p[2] = c[0]; + p[3] = c[3]; + } + g->cur_x += 4; - while (g->cur_y >= g->max_y && g->parse > 0) { - g->step = (1 << g->parse) * g->line_size; - g->cur_y = g->start_y + (g->step >> 1); - --g->parse; - } - } + if (g->cur_x >= g->max_x) + { + g->cur_x = g->start_x; + g->cur_y += g->step; + + while (g->cur_y >= g->max_y && g->parse > 0) + { + g->step = (1 << g->parse) * g->line_size; + g->cur_y = g->start_y + (g->step >> 1); + --g->parse; + } + } } static uint8 *stbi_process_gif_raster(stbi *s, stbi_gif *g) { - uint8 lzw_cs; - int32 len, code; - uint32 first; - int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; - stbi_gif_lzw *p; + uint8 lzw_cs; + int32 len, code; + uint32 first; + int32 codesize, codemask, avail, oldcode, bits, valid_bits, clear; + stbi_gif_lzw *p; - lzw_cs = get8u(s); - clear = 1 << lzw_cs; - first = 1; - codesize = lzw_cs + 1; - codemask = (1 << codesize) - 1; - bits = 0; - valid_bits = 0; - for (code = 0; code < clear; code++) { - g->codes[code].prefix = -1; - g->codes[code].first = (uint8) code; - g->codes[code].suffix = (uint8) code; - } + lzw_cs = get8u(s); + clear = 1 << lzw_cs; + first = 1; + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + bits = 0; + valid_bits = 0; + for (code = 0; code < clear; code++) + { + g->codes[code].prefix = -1; + g->codes[code].first = (uint8)code; + g->codes[code].suffix = (uint8)code; + } - // support no starting clear code - avail = clear+2; - oldcode = -1; + // support no starting clear code + avail = clear + 2; + oldcode = -1; - len = 0; - for(;;) { - if (valid_bits < codesize) { - if (len == 0) { - len = get8(s); // start new block - if (len == 0) - return g->out; - } - --len; - bits |= (int32) get8(s) << valid_bits; - valid_bits += 8; - } else { - int32 code = bits & codemask; - bits >>= codesize; - valid_bits -= codesize; - // @OPTIMIZE: is there some way we can accelerate the non-clear path? - if (code == clear) { // clear code - codesize = lzw_cs + 1; - codemask = (1 << codesize) - 1; - avail = clear + 2; - oldcode = -1; - first = 0; - } else if (code == clear + 1) { // end of stream code - skip(s, len); - while ((len = get8(s)) > 0) - skip(s,len); - return g->out; - } else if (code <= avail) { - if (first) return epuc("no clear code", "Corrupt GIF"); + len = 0; + for (;;) + { + if (valid_bits < codesize) + { + if (len == 0) + { + len = get8(s); // start new block + if (len == 0) + return g->out; + } + --len; + bits |= (int32)get8(s) << valid_bits; + valid_bits += 8; + } + else + { + int32 code = bits & codemask; + bits >>= codesize; + valid_bits -= codesize; + // @OPTIMIZE: is there some way we can accelerate the non-clear path? + if (code == clear) + { // clear code + codesize = lzw_cs + 1; + codemask = (1 << codesize) - 1; + avail = clear + 2; + oldcode = -1; + first = 0; + } + else if (code == clear + 1) + { // end of stream code + skip(s, len); + while ((len = get8(s)) > 0) + skip(s, len); + return g->out; + } + else if (code <= avail) + { + if (first) return epuc("no clear code", "Corrupt GIF"); - if (oldcode >= 0) { - p = &g->codes[avail++]; - if (avail > 4096) return epuc("too many codes", "Corrupt GIF"); - p->prefix = (int16) oldcode; - p->first = g->codes[oldcode].first; - p->suffix = (code == avail) ? p->first : g->codes[code].first; - } else if (code == avail) - return epuc("illegal code in raster", "Corrupt GIF"); + if (oldcode >= 0) + { + p = &g->codes[avail++]; + if (avail > 4096) return epuc("too many codes", "Corrupt GIF"); + p->prefix = (int16)oldcode; + p->first = g->codes[oldcode].first; + p->suffix = (code == avail) ? p->first : g->codes[code].first; + } + else if (code == avail) + return epuc("illegal code in raster", "Corrupt GIF"); - stbi_out_gif_code(g, (uint16) code); + stbi_out_gif_code(g, (uint16)code); - if ((avail & codemask) == 0 && avail <= 0x0FFF) { - codesize++; - codemask = (1 << codesize) - 1; - } + if ((avail & codemask) == 0 && avail <= 0x0FFF) + { + codesize++; + codemask = (1 << codesize) - 1; + } - oldcode = code; - } else { - return epuc("illegal code in raster", "Corrupt GIF"); - } - } - } + oldcode = code; + } + else + { + return epuc("illegal code in raster", "Corrupt GIF"); + } + } + } } static void stbi_fill_gif_background(stbi_gif *g) { - int i; - uint8 *c = g->pal[g->bgindex]; - // @OPTIMIZE: write a dword at a time - for (i = 0; i < g->w * g->h * 4; i += 4) { - uint8 *p = &g->out[i]; - p[0] = c[2]; - p[1] = c[1]; - p[2] = c[0]; - p[3] = c[3]; - } + int i; + uint8 *c = g->pal[g->bgindex]; + // @OPTIMIZE: write a dword at a time + for (i = 0; i < g->w * g->h * 4; i += 4) + { + uint8 *p = &g->out[i]; + p[0] = c[2]; + p[1] = c[1]; + p[2] = c[0]; + p[3] = c[3]; + } } // this function is designed to support animated gifs, although stb_image doesn't support it static uint8 *stbi_gif_load_next(stbi *s, stbi_gif *g, int *comp, int req_comp) { - int i; - uint8 *old_out = 0; + int i; + uint8 *old_out = 0; - if (g->out == 0) { - if (!stbi_gif_header(s, g, comp,0)) return 0; // failure_reason set by stbi_gif_header - g->out = (uint8 *) malloc(4 * g->w * g->h); - if (g->out == 0) return epuc("outofmem", "Out of memory"); - stbi_fill_gif_background(g); - } else { - // animated-gif-only path - if (((g->eflags & 0x1C) >> 2) == 3) { - old_out = g->out; - g->out = (uint8 *) malloc(4 * g->w * g->h); - if (g->out == 0) return epuc("outofmem", "Out of memory"); - memcpy(g->out, old_out, g->w*g->h*4); - } - } - - for (;;) { - switch (get8(s)) { - case 0x2C: /* Image Descriptor */ - { - int32 x, y, w, h; - uint8 *o; + if (g->out == 0) + { + if (!stbi_gif_header(s, g, comp, 0)) return 0; // failure_reason set by stbi_gif_header + g->out = (uint8 *)malloc(4 * g->w * g->h); + if (g->out == 0) return epuc("outofmem", "Out of memory"); + stbi_fill_gif_background(g); + } + else + { + // animated-gif-only path + if (((g->eflags & 0x1C) >> 2) == 3) + { + old_out = g->out; + g->out = (uint8 *)malloc(4 * g->w * g->h); + if (g->out == 0) return epuc("outofmem", "Out of memory"); + memcpy(g->out, old_out, g->w * g->h * 4); + } + } - x = get16le(s); - y = get16le(s); - w = get16le(s); - h = get16le(s); - if (((x + w) > (g->w)) || ((y + h) > (g->h))) - return epuc("bad Image Descriptor", "Corrupt GIF"); + for (;;) + { + switch (get8(s)) + { + case 0x2C: /* Image Descriptor */ + { + int32 x, y, w, h; + uint8 *o; - g->line_size = g->w * 4; - g->start_x = x * 4; - g->start_y = y * g->line_size; - g->max_x = g->start_x + w * 4; - g->max_y = g->start_y + h * g->line_size; - g->cur_x = g->start_x; - g->cur_y = g->start_y; + x = get16le(s); + y = get16le(s); + w = get16le(s); + h = get16le(s); + if (((x + w) > (g->w)) || ((y + h) > (g->h))) + return epuc("bad Image Descriptor", "Corrupt GIF"); - g->lflags = get8(s); + g->line_size = g->w * 4; + g->start_x = x * 4; + g->start_y = y * g->line_size; + g->max_x = g->start_x + w * 4; + g->max_y = g->start_y + h * g->line_size; + g->cur_x = g->start_x; + g->cur_y = g->start_y; - if (g->lflags & 0x40) { - g->step = 8 * g->line_size; // first interlaced spacing - g->parse = 3; - } else { - g->step = g->line_size; - g->parse = 0; - } + g->lflags = get8(s); - if (g->lflags & 0x80) { - stbi_gif_parse_colortable(s,g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); - g->color_table = (uint8 *) g->lpal; - } else if (g->flags & 0x80) { - for (i=0; i < 256; ++i) // @OPTIMIZE: reset only the previous transparent - g->pal[i][3] = 255; - if (g->transparent >= 0 && (g->eflags & 0x01)) - g->pal[g->transparent][3] = 0; - g->color_table = (uint8 *) g->pal; - } else - return epuc("missing color table", "Corrupt GIF"); - - o = stbi_process_gif_raster(s, g); - if (o == NULL) return NULL; + if (g->lflags & 0x40) + { + g->step = 8 * g->line_size; // first interlaced spacing + g->parse = 3; + } + else + { + g->step = g->line_size; + g->parse = 0; + } - if (req_comp && req_comp != 4) - o = convert_format(o, 4, req_comp, g->w, g->h); - return o; - } + if (g->lflags & 0x80) + { + stbi_gif_parse_colortable(s, g->lpal, 2 << (g->lflags & 7), g->eflags & 0x01 ? g->transparent : -1); + g->color_table = (uint8 *)g->lpal; + } + else if (g->flags & 0x80) + { + for (i = 0; i < 256; ++i) // @OPTIMIZE: reset only the previous transparent + g->pal[i][3] = 255; + if (g->transparent >= 0 && (g->eflags & 0x01)) + g->pal[g->transparent][3] = 0; + g->color_table = (uint8 *)g->pal; + } + else + return epuc("missing color table", "Corrupt GIF"); - case 0x21: // Comment Extension. - { - int len; - if (get8(s) == 0xF9) { // Graphic Control Extension. - len = get8(s); - if (len == 4) { - g->eflags = get8(s); - get16le(s); // delay - g->transparent = get8(s); - } else { - skip(s, len); - break; - } - } - while ((len = get8(s)) != 0) - skip(s, len); - break; - } + o = stbi_process_gif_raster(s, g); + if (o == NULL) return NULL; - case 0x3B: // gif stream termination code - return (uint8 *) 1; + if (req_comp && req_comp != 4) + o = convert_format(o, 4, req_comp, g->w, g->h); + return o; + } - default: - return epuc("unknown code", "Corrupt GIF"); - } - } + case 0x21: // Comment Extension. + { + int len; + if (get8(s) == 0xF9) + { // Graphic Control Extension. + len = get8(s); + if (len == 4) + { + g->eflags = get8(s); + get16le(s); // delay + g->transparent = get8(s); + } + else + { + skip(s, len); + break; + } + } + while ((len = get8(s)) != 0) + skip(s, len); + break; + } + + case 0x3B: // gif stream termination code + return (uint8 *)1; + + default: + return epuc("unknown code", "Corrupt GIF"); + } + } } static stbi_uc *stbi_gif_load(stbi *s, int *x, int *y, int *comp, int req_comp) { - uint8 *u = 0; - stbi_gif g={0}; + uint8 *u = 0; + stbi_gif g = {0}; - u = stbi_gif_load_next(s, &g, comp, req_comp); - if (u == (void *) 1) u = 0; // end of animated gif marker - if (u) { - *x = g.w; - *y = g.h; - } + u = stbi_gif_load_next(s, &g, comp, req_comp); + if (u == (void *)1) u = 0; // end of animated gif marker + if (u) + { + *x = g.w; + *y = g.h; + } - return u; + return u; } static int stbi_gif_info(stbi *s, int *x, int *y, int *comp) { - return stbi_gif_info_raw(s,x,y,comp); + return stbi_gif_info_raw(s, x, y, comp); } - // ************************************************************************************************* // Radiance RGBE HDR loader // originally by Nicolas Schulz #ifndef STBI_NO_HDR static int hdr_test(stbi *s) { - const char *signature = "#?RADIANCE\n"; - int i; - for (i=0; signature[i]; ++i) - if (get8(s) != signature[i]) - return 0; - return 1; + const char *signature = "#?RADIANCE\n"; + int i; + for (i = 0; signature[i]; ++i) + if (get8(s) != signature[i]) + return 0; + return 1; } -static int stbi_hdr_test(stbi* s) +static int stbi_hdr_test(stbi *s) { - int r = hdr_test(s); - stbi_rewind(s); - return r; + int r = hdr_test(s); + stbi_rewind(s); + return r; } -#define HDR_BUFLEN 1024 +#define HDR_BUFLEN 1024 static char *hdr_gettoken(stbi *z, char *buffer) { - int len=0; - char c = '\0'; + int len = 0; + char c = '\0'; - c = (char) get8(z); + c = (char)get8(z); - while (!at_eof(z) && c != '\n') { - buffer[len++] = c; - if (len == HDR_BUFLEN-1) { - // flush to end of line - while (!at_eof(z) && get8(z) != '\n') - ; - break; - } - c = (char) get8(z); - } + while (!at_eof(z) && c != '\n') + { + buffer[len++] = c; + if (len == HDR_BUFLEN - 1) + { + // flush to end of line + while (!at_eof(z) && get8(z) != '\n') + ; + break; + } + c = (char)get8(z); + } - buffer[len] = 0; - return buffer; + buffer[len] = 0; + return buffer; } static void hdr_convert(float *output, stbi_uc *input, int req_comp) { - if ( input[3] != 0 ) { - float f1; - // Exponent - f1 = (float) ldexp(1.0f, input[3] - (int)(128 + 8)); - if (req_comp <= 2) - output[0] = (input[0] + input[1] + input[2]) * f1 / 3; - else { - output[0] = input[0] * f1; - output[1] = input[1] * f1; - output[2] = input[2] * f1; - } - if (req_comp == 2) output[1] = 1; - if (req_comp == 4) output[3] = 1; - } else { - switch (req_comp) { - case 4: output[3] = 1; /* fallthrough */ - case 3: output[0] = output[1] = output[2] = 0; - break; - case 2: output[1] = 1; /* fallthrough */ - case 1: output[0] = 0; - break; - } - } + if (input[3] != 0) + { + float f1; + // Exponent + f1 = (float)ldexp(1.0f, input[3] - (int)(128 + 8)); + if (req_comp <= 2) + output[0] = (input[0] + input[1] + input[2]) * f1 / 3; + else + { + output[0] = input[0] * f1; + output[1] = input[1] * f1; + output[2] = input[2] * f1; + } + if (req_comp == 2) output[1] = 1; + if (req_comp == 4) output[3] = 1; + } + else + { + switch (req_comp) + { + case 4: + output[3] = 1; /* fallthrough */ + case 3: + output[0] = output[1] = output[2] = 0; + break; + case 2: + output[1] = 1; /* fallthrough */ + case 1: + output[0] = 0; + break; + } + } } static float *hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp) { - char buffer[HDR_BUFLEN]; - char *token; - int valid = 0; - int width, height; - stbi_uc *scanline; - float *hdr_data; - int len; - unsigned char count, value; - int i, j, k, c1,c2, z; + char buffer[HDR_BUFLEN]; + char *token; + int valid = 0; + int width, height; + stbi_uc *scanline; + float *hdr_data; + int len; + unsigned char count, value; + int i, j, k, c1, c2, z; + // Check identifier + if (strcmp(hdr_gettoken(s, buffer), "#?RADIANCE") != 0) + return epf("not HDR", "Corrupt HDR image"); - // Check identifier - if (strcmp(hdr_gettoken(s,buffer), "#?RADIANCE") != 0) - return epf("not HDR", "Corrupt HDR image"); - - // Parse header - for(;;) { - token = hdr_gettoken(s,buffer); - if (token[0] == 0) break; - if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; - } + // Parse header + for (;;) + { + token = hdr_gettoken(s, buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } - if (!valid) return epf("unsupported format", "Unsupported HDR format"); + if (!valid) return epf("unsupported format", "Unsupported HDR format"); - // Parse width and height - // can't use sscanf() if we're not using stdio! - token = hdr_gettoken(s,buffer); - if (strncmp(token, "-Y ", 3)) return epf("unsupported data layout", "Unsupported HDR format"); - token += 3; - height = strtol(token, &token, 10); - while (*token == ' ') ++token; - if (strncmp(token, "+X ", 3)) return epf("unsupported data layout", "Unsupported HDR format"); - token += 3; - width = strtol(token, NULL, 10); + // Parse width and height + // can't use sscanf() if we're not using stdio! + token = hdr_gettoken(s, buffer); + if (strncmp(token, "-Y ", 3)) return epf("unsupported data layout", "Unsupported HDR format"); + token += 3; + height = strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) return epf("unsupported data layout", "Unsupported HDR format"); + token += 3; + width = strtol(token, NULL, 10); - *x = width; - *y = height; + *x = width; + *y = height; - *comp = 3; - if (req_comp == 0) req_comp = 3; + *comp = 3; + if (req_comp == 0) req_comp = 3; - // Read data - hdr_data = (float *) malloc(height * width * req_comp * sizeof(float)); + // Read data + hdr_data = (float *)malloc(height * width * req_comp * sizeof(float)); - // Load image data - // image data is stored as some number of sca - if ( width < 8 || width >= 32768) { - // Read flat data - for (j=0; j < height; ++j) { - for (i=0; i < width; ++i) { - stbi_uc rgbe[4]; - main_decode_loop: - getn(s, rgbe, 4); - hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); - } - } - } else { - // Read RLE-encoded data - scanline = NULL; + // Load image data + // image data is stored as some number of sca + if (width < 8 || width >= 32768) + { + // Read flat data + for (j = 0; j < height; ++j) + { + for (i = 0; i < width; ++i) + { + stbi_uc rgbe[4]; + main_decode_loop: + getn(s, rgbe, 4); + hdr_convert(hdr_data + j * width * req_comp + i * req_comp, rgbe, req_comp); + } + } + } + else + { + // Read RLE-encoded data + scanline = NULL; - for (j = 0; j < height; ++j) { - c1 = get8(s); - c2 = get8(s); - len = get8(s); - if (c1 != 2 || c2 != 2 || (len & 0x80)) { - // not run-length encoded, so we have to actually use THIS data as a decoded - // pixel (note this can't be a valid pixel--one of RGB must be >= 128) - uint8 rgbe[4]; - rgbe[0] = (uint8) c1; - rgbe[1] = (uint8) c2; - rgbe[2] = (uint8) len; - rgbe[3] = (uint8) get8u(s); - hdr_convert(hdr_data, rgbe, req_comp); - i = 1; - j = 0; - free(scanline); - goto main_decode_loop; // yes, this makes no sense - } - len <<= 8; - len |= get8(s); - if (len != width) { free(hdr_data); free(scanline); return epf("invalid decoded scanline length", "corrupt HDR"); } - if (scanline == NULL) scanline = (stbi_uc *) malloc(width * 4); - - for (k = 0; k < 4; ++k) { - i = 0; - while (i < width) { - count = get8u(s); - if (count > 128) { - // Run - value = get8u(s); - count -= 128; - for (z = 0; z < count; ++z) - scanline[i++ * 4 + k] = value; - } else { - // Dump - for (z = 0; z < count; ++z) - scanline[i++ * 4 + k] = get8u(s); - } - } - } - for (i=0; i < width; ++i) - hdr_convert(hdr_data+(j*width + i)*req_comp, scanline + i*4, req_comp); - } - free(scanline); - } + for (j = 0; j < height; ++j) + { + c1 = get8(s); + c2 = get8(s); + len = get8(s); + if (c1 != 2 || c2 != 2 || (len & 0x80)) + { + // not run-length encoded, so we have to actually use THIS data as a decoded + // pixel (note this can't be a valid pixel--one of RGB must be >= 128) + uint8 rgbe[4]; + rgbe[0] = (uint8)c1; + rgbe[1] = (uint8)c2; + rgbe[2] = (uint8)len; + rgbe[3] = (uint8)get8u(s); + hdr_convert(hdr_data, rgbe, req_comp); + i = 1; + j = 0; + free(scanline); + goto main_decode_loop; // yes, this makes no sense + } + len <<= 8; + len |= get8(s); + if (len != width) + { + free(hdr_data); + free(scanline); + return epf("invalid decoded scanline length", "corrupt HDR"); + } + if (scanline == NULL) scanline = (stbi_uc *)malloc(width * 4); - return hdr_data; + for (k = 0; k < 4; ++k) + { + i = 0; + while (i < width) + { + count = get8u(s); + if (count > 128) + { + // Run + value = get8u(s); + count -= 128; + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = value; + } + else + { + // Dump + for (z = 0; z < count; ++z) + scanline[i++ * 4 + k] = get8u(s); + } + } + } + for (i = 0; i < width; ++i) + hdr_convert(hdr_data + (j * width + i) * req_comp, scanline + i * 4, req_comp); + } + free(scanline); + } + + return hdr_data; } static float *stbi_hdr_load(stbi *s, int *x, int *y, int *comp, int req_comp) { - return hdr_load(s,x,y,comp,req_comp); + return hdr_load(s, x, y, comp, req_comp); } static int stbi_hdr_info(stbi *s, int *x, int *y, int *comp) { - char buffer[HDR_BUFLEN]; - char *token; - int valid = 0; + char buffer[HDR_BUFLEN]; + char *token; + int valid = 0; - if (strcmp(hdr_gettoken(s,buffer), "#?RADIANCE") != 0) { - stbi_rewind( s ); - return 0; - } + if (strcmp(hdr_gettoken(s, buffer), "#?RADIANCE") != 0) + { + stbi_rewind(s); + return 0; + } - for(;;) { - token = hdr_gettoken(s,buffer); - if (token[0] == 0) break; - if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; - } + for (;;) + { + token = hdr_gettoken(s, buffer); + if (token[0] == 0) break; + if (strcmp(token, "FORMAT=32-bit_rle_rgbe") == 0) valid = 1; + } - if (!valid) { - stbi_rewind( s ); - return 0; - } - token = hdr_gettoken(s,buffer); - if (strncmp(token, "-Y ", 3)) { - stbi_rewind( s ); - return 0; - } - token += 3; - *y = strtol(token, &token, 10); - while (*token == ' ') ++token; - if (strncmp(token, "+X ", 3)) { - stbi_rewind( s ); - return 0; - } - token += 3; - *x = strtol(token, NULL, 10); - *comp = 3; - return 1; + if (!valid) + { + stbi_rewind(s); + return 0; + } + token = hdr_gettoken(s, buffer); + if (strncmp(token, "-Y ", 3)) + { + stbi_rewind(s); + return 0; + } + token += 3; + *y = strtol(token, &token, 10); + while (*token == ' ') ++token; + if (strncmp(token, "+X ", 3)) + { + stbi_rewind(s); + return 0; + } + token += 3; + *x = strtol(token, NULL, 10); + *comp = 3; + return 1; } -#endif // STBI_NO_HDR +#endif // STBI_NO_HDR static int stbi_bmp_info(stbi *s, int *x, int *y, int *comp) { - int hsz; - if (get8(s) != 'B' || get8(s) != 'M') { - stbi_rewind( s ); - return 0; - } - skip(s,12); - hsz = get32le(s); - if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108) { - stbi_rewind( s ); - return 0; - } - if (hsz == 12) { - *x = get16le(s); - *y = get16le(s); - } else { - *x = get32le(s); - *y = get32le(s); - } - if (get16le(s) != 1) { - stbi_rewind( s ); - return 0; - } - *comp = get16le(s) / 8; - return 1; + int hsz; + if (get8(s) != 'B' || get8(s) != 'M') + { + stbi_rewind(s); + return 0; + } + skip(s, 12); + hsz = get32le(s); + if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108) + { + stbi_rewind(s); + return 0; + } + if (hsz == 12) + { + *x = get16le(s); + *y = get16le(s); + } + else + { + *x = get32le(s); + *y = get32le(s); + } + if (get16le(s) != 1) + { + stbi_rewind(s); + return 0; + } + *comp = get16le(s) / 8; + return 1; } static int stbi_psd_info(stbi *s, int *x, int *y, int *comp) { - int channelCount; - if (get32(s) != 0x38425053) { - stbi_rewind( s ); - return 0; - } - if (get16(s) != 1) { - stbi_rewind( s ); - return 0; - } - skip(s, 6); - channelCount = get16(s); - if (channelCount < 0 || channelCount > 16) { - stbi_rewind( s ); - return 0; - } - *y = get32(s); - *x = get32(s); - if (get16(s) != 8) { - stbi_rewind( s ); - return 0; - } - if (get16(s) != 3) { - stbi_rewind( s ); - return 0; - } - *comp = 4; - return 1; + int channelCount; + if (get32(s) != 0x38425053) + { + stbi_rewind(s); + return 0; + } + if (get16(s) != 1) + { + stbi_rewind(s); + return 0; + } + skip(s, 6); + channelCount = get16(s); + if (channelCount < 0 || channelCount > 16) + { + stbi_rewind(s); + return 0; + } + *y = get32(s); + *x = get32(s); + if (get16(s) != 8) + { + stbi_rewind(s); + return 0; + } + if (get16(s) != 3) + { + stbi_rewind(s); + return 0; + } + *comp = 4; + return 1; } static int stbi_pic_info(stbi *s, int *x, int *y, int *comp) { - int act_comp=0,num_packets=0,chained; - pic_packet_t packets[10]; + int act_comp = 0, num_packets = 0, chained; + pic_packet_t packets[10]; - skip(s, 92); + skip(s, 92); - *x = get16(s); - *y = get16(s); - if (at_eof(s)) return 0; - if ( (*x) != 0 && (1 << 28) / (*x) < (*y)) { - stbi_rewind( s ); - return 0; - } + *x = get16(s); + *y = get16(s); + if (at_eof(s)) return 0; + if ((*x) != 0 && (1 << 28) / (*x) < (*y)) + { + stbi_rewind(s); + return 0; + } - skip(s, 8); + skip(s, 8); - do { - pic_packet_t *packet; + do + { + pic_packet_t *packet; - if (num_packets==sizeof(packets)/sizeof(packets[0])) - return 0; + if (num_packets == sizeof(packets) / sizeof(packets[0])) + return 0; - packet = &packets[num_packets++]; - chained = get8(s); - packet->size = get8u(s); - packet->type = get8u(s); - packet->channel = get8u(s); - act_comp |= packet->channel; + packet = &packets[num_packets++]; + chained = get8(s); + packet->size = get8u(s); + packet->type = get8u(s); + packet->channel = get8u(s); + act_comp |= packet->channel; - if (at_eof(s)) { - stbi_rewind( s ); - return 0; - } - if (packet->size != 8) { - stbi_rewind( s ); - return 0; - } - } while (chained); + if (at_eof(s)) + { + stbi_rewind(s); + return 0; + } + if (packet->size != 8) + { + stbi_rewind(s); + return 0; + } + } while (chained); - *comp = (act_comp & 0x10 ? 4 : 3); + *comp = (act_comp & 0x10 ? 4 : 3); - return 1; + return 1; } static int stbi_info_main(stbi *s, int *x, int *y, int *comp) { - if (stbi_jpeg_info(s, x, y, comp)) - return 1; - if (stbi_png_info(s, x, y, comp)) - return 1; - if (stbi_gif_info(s, x, y, comp)) - return 1; - if (stbi_bmp_info(s, x, y, comp)) - return 1; - if (stbi_psd_info(s, x, y, comp)) - return 1; - if (stbi_pic_info(s, x, y, comp)) - return 1; - #ifndef STBI_NO_HDR - if (stbi_hdr_info(s, x, y, comp)) - return 1; - #endif - // test tga last because it's a crappy test! - if (stbi_tga_info(s, x, y, comp)) - return 1; - return e("unknown image type", "Image not of any known type, or corrupt"); + if (stbi_jpeg_info(s, x, y, comp)) + return 1; + if (stbi_png_info(s, x, y, comp)) + return 1; + if (stbi_gif_info(s, x, y, comp)) + return 1; + if (stbi_bmp_info(s, x, y, comp)) + return 1; + if (stbi_psd_info(s, x, y, comp)) + return 1; + if (stbi_pic_info(s, x, y, comp)) + return 1; +#ifndef STBI_NO_HDR + if (stbi_hdr_info(s, x, y, comp)) + return 1; +#endif + // test tga last because it's a crappy test! + if (stbi_tga_info(s, x, y, comp)) + return 1; + return e("unknown image type", "Image not of any known type, or corrupt"); } #ifndef STBI_NO_STDIO int stbi_info(char const *filename, int *x, int *y, int *comp) { - FILE *f = fopen(filename, "rb"); - int result; - if (!f) return e("can't fopen", "Unable to open file"); - result = stbi_info_from_file(f, x, y, comp); - fclose(f); - return result; + FILE *f = fopen(filename, "rb"); + int result; + if (!f) return e("can't fopen", "Unable to open file"); + result = stbi_info_from_file(f, x, y, comp); + fclose(f); + return result; } int stbi_info_from_file(FILE *f, int *x, int *y, int *comp) { - int r; - stbi s; - long pos = ftell(f); - start_file(&s, f); - r = stbi_info_main(&s,x,y,comp); - fseek(f,pos,SEEK_SET); - return r; + int r; + stbi s; + long pos = ftell(f); + start_file(&s, f); + r = stbi_info_main(&s, x, y, comp); + fseek(f, pos, SEEK_SET); + return r; } -#endif // !STBI_NO_STDIO +#endif // !STBI_NO_STDIO int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp) { - stbi s; - start_mem(&s,buffer,len); - return stbi_info_main(&s,x,y,comp); + stbi s; + start_mem(&s, buffer, len); + return stbi_info_main(&s, x, y, comp); } int stbi_info_from_callbacks(stbi_io_callbacks const *c, void *user, int *x, int *y, int *comp) { - stbi s; - start_callbacks(&s, (stbi_io_callbacks *) c, user); - return stbi_info_main(&s,x,y,comp); + stbi s; + start_callbacks(&s, (stbi_io_callbacks *)c, user); + return stbi_info_main(&s, x, y, comp); } -#endif // STBI_HEADER_FILE_ONLY +#endif // STBI_HEADER_FILE_ONLY /* revision history: diff --git a/examples/ThirdPartyLibs/stb_image/stb_image.h b/examples/ThirdPartyLibs/stb_image/stb_image.h index f66bfd12f..f7245c7cf 100644 --- a/examples/ThirdPartyLibs/stb_image/stb_image.h +++ b/examples/ThirdPartyLibs/stb_image/stb_image.h @@ -80,7 +80,7 @@ // Basic usage (see HDR discussion below): // int x,y,n; // unsigned char *data = stbi_load(filename, &x, &y, &n, 0); -// // ... process data if not NULL ... +// // ... process data if not NULL ... // // ... x = width, y = height, n = # 8-bit components per pixel ... // // ... replace '0' with '1'..'4' to force that many components per pixel // // ... but 'n' will always be the number that it would have been if you said 0 @@ -156,7 +156,7 @@ // (linear) floats to preserve the full dynamic range: // // float *data = stbi_loadf(filename, &x, &y, &n, 0); -// +// // If you load LDR images through this interface, those images will // be promoted to floating point values, run through the inverse of // constants corresponding to the above: @@ -178,16 +178,15 @@ // I/O callbacks allow you to read from arbitrary sources, like packaged // files or some other source. Data read from callbacks are processed // through a small internal buffer (currently 128 bytes) to try to reduce -// overhead. +// overhead. // // The three functions you must define are "read" (reads some bytes of data), // "skip" (skips some bytes of data), "eof" (reports if the stream is at the end). - #ifndef STBI_NO_STDIO #if defined(_MSC_VER) && _MSC_VER >= 0x1400 -#define _CRT_SECURE_NO_WARNINGS // suppress bogus warnings about fopen() +#define _CRT_SECURE_NO_WARNINGS // suppress bogus warnings about fopen() #endif #include @@ -197,130 +196,125 @@ enum { - STBI_default = 0, // only used for req_comp + STBI_default = 0, // only used for req_comp - STBI_grey = 1, - STBI_grey_alpha = 2, - STBI_rgb = 3, - STBI_rgb_alpha = 4 + STBI_grey = 1, + STBI_grey_alpha = 2, + STBI_rgb = 3, + STBI_rgb_alpha = 4 }; typedef unsigned char stbi_uc; #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -////////////////////////////////////////////////////////////////////////////// -// -// PRIMARY API - works on images of any type -// + ////////////////////////////////////////////////////////////////////////////// + // + // PRIMARY API - works on images of any type + // -// -// load image by filename, open file, or memory buffer -// + // + // load image by filename, open file, or memory buffer + // -extern stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); + extern stbi_uc *stbi_load_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); #ifndef STBI_NO_STDIO -extern stbi_uc *stbi_load (char const *filename, int *x, int *y, int *comp, int req_comp); -extern stbi_uc *stbi_load_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); + extern stbi_uc *stbi_load(char const *filename, int *x, int *y, int *comp, int req_comp); + extern stbi_uc *stbi_load_from_file(FILE *f, int *x, int *y, int *comp, int req_comp); // for stbi_load_from_file, file pointer is left pointing immediately after image #endif -typedef struct -{ - int (*read) (void *user,char *data,int size); // fill 'data' with 'size' bytes. return number of bytes actually read - void (*skip) (void *user,unsigned n); // skip the next 'n' bytes - int (*eof) (void *user); // returns nonzero if we are at end of file/data -} stbi_io_callbacks; + typedef struct + { + int (*read)(void *user, char *data, int size); // fill 'data' with 'size' bytes. return number of bytes actually read + void (*skip)(void *user, unsigned n); // skip the next 'n' bytes + int (*eof)(void *user); // returns nonzero if we are at end of file/data + } stbi_io_callbacks; -extern stbi_uc *stbi_load_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp); + extern stbi_uc *stbi_load_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp); #ifndef STBI_NO_HDR - extern float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); - - #ifndef STBI_NO_STDIO - extern float *stbi_loadf (char const *filename, int *x, int *y, int *comp, int req_comp); - extern float *stbi_loadf_from_file (FILE *f, int *x, int *y, int *comp, int req_comp); - #endif - - extern float *stbi_loadf_from_callbacks (stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp); - - extern void stbi_hdr_to_ldr_gamma(float gamma); - extern void stbi_hdr_to_ldr_scale(float scale); - - extern void stbi_ldr_to_hdr_gamma(float gamma); - extern void stbi_ldr_to_hdr_scale(float scale); -#endif // STBI_NO_HDR - -// stbi_is_hdr is always defined -extern int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); -extern int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); -#ifndef STBI_NO_STDIO -extern int stbi_is_hdr (char const *filename); -extern int stbi_is_hdr_from_file(FILE *f); -#endif // STBI_NO_STDIO - - -// get a VERY brief reason for failure -// NOT THREADSAFE -extern const char *stbi_failure_reason (void); - -// free the loaded image -- this is just free() -extern void stbi_image_free (void *retval_from_stbi_load); - -// get image dimensions & components without fully decoding -extern int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); -extern int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); + extern float *stbi_loadf_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp, int req_comp); #ifndef STBI_NO_STDIO -extern int stbi_info (char const *filename, int *x, int *y, int *comp); -extern int stbi_info_from_file (FILE *f, int *x, int *y, int *comp); + extern float *stbi_loadf(char const *filename, int *x, int *y, int *comp, int req_comp); + extern float *stbi_loadf_from_file(FILE *f, int *x, int *y, int *comp, int req_comp); +#endif + + extern float *stbi_loadf_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp, int req_comp); + + extern void stbi_hdr_to_ldr_gamma(float gamma); + extern void stbi_hdr_to_ldr_scale(float scale); + + extern void stbi_ldr_to_hdr_gamma(float gamma); + extern void stbi_ldr_to_hdr_scale(float scale); +#endif // STBI_NO_HDR + + // stbi_is_hdr is always defined + extern int stbi_is_hdr_from_callbacks(stbi_io_callbacks const *clbk, void *user); + extern int stbi_is_hdr_from_memory(stbi_uc const *buffer, int len); +#ifndef STBI_NO_STDIO + extern int stbi_is_hdr(char const *filename); + extern int stbi_is_hdr_from_file(FILE *f); +#endif // STBI_NO_STDIO + + // get a VERY brief reason for failure + // NOT THREADSAFE + extern const char *stbi_failure_reason(void); + + // free the loaded image -- this is just free() + extern void stbi_image_free(void *retval_from_stbi_load); + + // get image dimensions & components without fully decoding + extern int stbi_info_from_memory(stbi_uc const *buffer, int len, int *x, int *y, int *comp); + extern int stbi_info_from_callbacks(stbi_io_callbacks const *clbk, void *user, int *x, int *y, int *comp); + +#ifndef STBI_NO_STDIO + extern int stbi_info(char const *filename, int *x, int *y, int *comp); + extern int stbi_info_from_file(FILE *f, int *x, int *y, int *comp); #endif + // for image formats that explicitly notate that they have premultiplied alpha, + // we just return the colors as stored in the file. set this flag to force + // unpremultiplication. results are undefined if the unpremultiply overflow. + extern void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); + // indicate whether we should process iphone images back to canonical format, + // or just pass them through "as-is" + extern void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); -// for image formats that explicitly notate that they have premultiplied alpha, -// we just return the colors as stored in the file. set this flag to force -// unpremultiplication. results are undefined if the unpremultiply overflow. -extern void stbi_set_unpremultiply_on_load(int flag_true_if_should_unpremultiply); + // ZLIB client - used by PNG, available for other purposes -// indicate whether we should process iphone images back to canonical format, -// or just pass them through "as-is" -extern void stbi_convert_iphone_png_to_rgb(int flag_true_if_should_convert); - - -// ZLIB client - used by PNG, available for other purposes - -extern char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); -extern char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); -extern int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); - -extern char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); -extern int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + extern char *stbi_zlib_decode_malloc_guesssize(const char *buffer, int len, int initial_size, int *outlen); + extern char *stbi_zlib_decode_malloc(const char *buffer, int len, int *outlen); + extern int stbi_zlib_decode_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); + extern char *stbi_zlib_decode_noheader_malloc(const char *buffer, int len, int *outlen); + extern int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const char *ibuffer, int ilen); // define faster low-level operations (typically SIMD support) #ifdef STBI_SIMD -typedef void (*stbi_idct_8x8)(stbi_uc *out, int out_stride, short data[64], unsigned short *dequantize); -// compute an integer IDCT on "input" -// input[x] = data[x] * dequantize[x] -// write results to 'out': 64 samples, each run of 8 spaced by 'out_stride' -// CLAMP results to 0..255 -typedef void (*stbi_YCbCr_to_RGB_run)(stbi_uc *output, stbi_uc const *y, stbi_uc const *cb, stbi_uc const *cr, int count, int step); -// compute a conversion from YCbCr to RGB -// 'count' pixels -// write pixels to 'output'; each pixel is 'step' bytes (either 3 or 4; if 4, write '255' as 4th), order R,G,B -// y: Y input channel -// cb: Cb input channel; scale/biased to be 0..255 -// cr: Cr input channel; scale/biased to be 0..255 - -extern void stbi_install_idct(stbi_idct_8x8 func); -extern void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func); -#endif // STBI_SIMD + typedef void (*stbi_idct_8x8)(stbi_uc *out, int out_stride, short data[64], unsigned short *dequantize); + // compute an integer IDCT on "input" + // input[x] = data[x] * dequantize[x] + // write results to 'out': 64 samples, each run of 8 spaced by 'out_stride' + // CLAMP results to 0..255 + typedef void (*stbi_YCbCr_to_RGB_run)(stbi_uc *output, stbi_uc const *y, stbi_uc const *cb, stbi_uc const *cr, int count, int step); + // compute a conversion from YCbCr to RGB + // 'count' pixels + // write pixels to 'output'; each pixel is 'step' bytes (either 3 or 4; if 4, write '255' as 4th), order R,G,B + // y: Y input channel + // cb: Cb input channel; scale/biased to be 0..255 + // cr: Cr input channel; scale/biased to be 0..255 + extern void stbi_install_idct(stbi_idct_8x8 func); + extern void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func); +#endif // STBI_SIMD #ifdef __cplusplus } @@ -329,4 +323,4 @@ extern void stbi_install_YCbCr_to_RGB(stbi_YCbCr_to_RGB_run func); // // //// end header file ///////////////////////////////////////////////////// -#endif // STBI_INCLUDE_STB_IMAGE_H +#endif // STBI_INCLUDE_STB_IMAGE_H diff --git a/examples/ThirdPartyLibs/stb_image/stb_image_write.h b/examples/ThirdPartyLibs/stb_image/stb_image_write.h index 1a51a939f..50386388f 100644 --- a/examples/ThirdPartyLibs/stb_image/stb_image_write.h +++ b/examples/ThirdPartyLibs/stb_image/stb_image_write.h @@ -55,18 +55,19 @@ USAGE: #define INCLUDE_STB_IMAGE_WRITE_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -extern int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); -extern int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); -extern int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); + extern int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes); + extern int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data); + extern int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data); #ifdef __cplusplus } #endif -#endif//INCLUDE_STB_IMAGE_WRITE_H +#endif //INCLUDE_STB_IMAGE_WRITE_H #ifdef STB_IMAGE_WRITE_IMPLEMENTATION @@ -77,432 +78,525 @@ extern int stbi_write_tga(char const *filename, int w, int h, int comp, const vo #include typedef unsigned int stbiw_uint32; -typedef int stb_image_write_test[sizeof(stbiw_uint32)==4 ? 1 : -1]; +typedef int stb_image_write_test[sizeof(stbiw_uint32) == 4 ? 1 : -1]; static void writefv(FILE *f, const char *fmt, va_list v) { - while (*fmt) { - switch (*fmt++) { - case ' ': break; - case '1': { unsigned char x = (unsigned char) va_arg(v, int); fputc(x,f); break; } - case '2': { int x = va_arg(v,int); unsigned char b[2]; - b[0] = (unsigned char) x; b[1] = (unsigned char) (x>>8); - fwrite(b,2,1,f); break; } - case '4': { stbiw_uint32 x = va_arg(v,int); unsigned char b[4]; - b[0]=(unsigned char)x; b[1]=(unsigned char)(x>>8); - b[2]=(unsigned char)(x>>16); b[3]=(unsigned char)(x>>24); - fwrite(b,4,1,f); break; } - default: - assert(0); - return; - } - } + while (*fmt) + { + switch (*fmt++) + { + case ' ': + break; + case '1': + { + unsigned char x = (unsigned char)va_arg(v, int); + fputc(x, f); + break; + } + case '2': + { + int x = va_arg(v, int); + unsigned char b[2]; + b[0] = (unsigned char)x; + b[1] = (unsigned char)(x >> 8); + fwrite(b, 2, 1, f); + break; + } + case '4': + { + stbiw_uint32 x = va_arg(v, int); + unsigned char b[4]; + b[0] = (unsigned char)x; + b[1] = (unsigned char)(x >> 8); + b[2] = (unsigned char)(x >> 16); + b[3] = (unsigned char)(x >> 24); + fwrite(b, 4, 1, f); + break; + } + default: + assert(0); + return; + } + } } static void write3(FILE *f, unsigned char a, unsigned char b, unsigned char c) { - unsigned char arr[3]; - arr[0] = a, arr[1] = b, arr[2] = c; - fwrite(arr, 3, 1, f); + unsigned char arr[3]; + arr[0] = a, arr[1] = b, arr[2] = c; + fwrite(arr, 3, 1, f); } static void write_pixels(FILE *f, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad) { - unsigned char bg[3] = { 255, 0, 255}, px[3]; - stbiw_uint32 zero = 0; - int i,j,k, j_end; + unsigned char bg[3] = {255, 0, 255}, px[3]; + stbiw_uint32 zero = 0; + int i, j, k, j_end; - if (y <= 0) - return; + if (y <= 0) + return; - if (vdir < 0) - j_end = -1, j = y-1; - else - j_end = y, j = 0; + if (vdir < 0) + j_end = -1, j = y - 1; + else + j_end = y, j = 0; - for (; j != j_end; j += vdir) { - for (i=0; i < x; ++i) { - unsigned char *d = (unsigned char *) data + (j*x+i)*comp; - if (write_alpha < 0) - fwrite(&d[comp-1], 1, 1, f); - switch (comp) { - case 1: - case 2: write3(f, d[0],d[0],d[0]); - break; - case 4: - if (!write_alpha) { - // composite against pink background - for (k=0; k < 3; ++k) - px[k] = bg[k] + ((d[k] - bg[k]) * d[3])/255; - write3(f, px[1-rgb_dir],px[1],px[1+rgb_dir]); - break; - } - /* FALLTHROUGH */ - case 3: - write3(f, d[1-rgb_dir],d[1],d[1+rgb_dir]); - break; - } - if (write_alpha > 0) - fwrite(&d[comp-1], 1, 1, f); - } - fwrite(&zero,scanline_pad,1,f); - } + for (; j != j_end; j += vdir) + { + for (i = 0; i < x; ++i) + { + unsigned char *d = (unsigned char *)data + (j * x + i) * comp; + if (write_alpha < 0) + fwrite(&d[comp - 1], 1, 1, f); + switch (comp) + { + case 1: + case 2: + write3(f, d[0], d[0], d[0]); + break; + case 4: + if (!write_alpha) + { + // composite against pink background + for (k = 0; k < 3; ++k) + px[k] = bg[k] + ((d[k] - bg[k]) * d[3]) / 255; + write3(f, px[1 - rgb_dir], px[1], px[1 + rgb_dir]); + break; + } + /* FALLTHROUGH */ + case 3: + write3(f, d[1 - rgb_dir], d[1], d[1 + rgb_dir]); + break; + } + if (write_alpha > 0) + fwrite(&d[comp - 1], 1, 1, f); + } + fwrite(&zero, scanline_pad, 1, f); + } } static int outfile(char const *filename, int rgb_dir, int vdir, int x, int y, int comp, void *data, int alpha, int pad, const char *fmt, ...) { - FILE *f; - if (y < 0 || x < 0) return 0; - f = fopen(filename, "wb"); - if (f) { - va_list v; - va_start(v, fmt); - writefv(f, fmt, v); - va_end(v); - write_pixels(f,rgb_dir,vdir,x,y,comp,data,alpha,pad); - fclose(f); - } - return f != NULL; + FILE *f; + if (y < 0 || x < 0) return 0; + f = fopen(filename, "wb"); + if (f) + { + va_list v; + va_start(v, fmt); + writefv(f, fmt, v); + va_end(v); + write_pixels(f, rgb_dir, vdir, x, y, comp, data, alpha, pad); + fclose(f); + } + return f != NULL; } int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data) { - int pad = (-x*3) & 3; - return outfile(filename,-1,-1,x,y,comp,(void *) data,0,pad, - "11 4 22 4" "4 44 22 444444", - 'B', 'M', 14+40+(x*3+pad)*y, 0,0, 14+40, // file header - 40, x,y, 1,24, 0,0,0,0,0,0); // bitmap header + int pad = (-x * 3) & 3; + return outfile(filename, -1, -1, x, y, comp, (void *)data, 0, pad, + "11 4 22 4" + "4 44 22 444444", + 'B', 'M', 14 + 40 + (x * 3 + pad) * y, 0, 0, 14 + 40, // file header + 40, x, y, 1, 24, 0, 0, 0, 0, 0, 0); // bitmap header } int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data) { - int has_alpha = !(comp & 1); - return outfile(filename, -1,-1, x, y, comp, (void *) data, has_alpha, 0, - "111 221 2222 11", 0,0,2, 0,0,0, 0,0,x,y, 24+8*has_alpha, 8*has_alpha); + int has_alpha = !(comp & 1); + return outfile(filename, -1, -1, x, y, comp, (void *)data, has_alpha, 0, + "111 221 2222 11", 0, 0, 2, 0, 0, 0, 0, 0, x, y, 24 + 8 * has_alpha, 8 * has_alpha); } // stretchy buffer; stbi__sbpush() == vector<>::push_back() -- stbi__sbcount() == vector<>::size() -#define stbi__sbraw(a) ((int *) (a) - 2) -#define stbi__sbm(a) stbi__sbraw(a)[0] -#define stbi__sbn(a) stbi__sbraw(a)[1] +#define stbi__sbraw(a) ((int *)(a)-2) +#define stbi__sbm(a) stbi__sbraw(a)[0] +#define stbi__sbn(a) stbi__sbraw(a)[1] -#define stbi__sbneedgrow(a,n) ((a)==0 || stbi__sbn(a)+n >= stbi__sbm(a)) -#define stbi__sbmaybegrow(a,n) (stbi__sbneedgrow(a,(n)) ? stbi__sbgrow(a,n) : 0) -#define stbi__sbgrow(a,n) stbi__sbgrowf((void **) &(a), (n), sizeof(*(a))) +#define stbi__sbneedgrow(a, n) ((a) == 0 || stbi__sbn(a) + n >= stbi__sbm(a)) +#define stbi__sbmaybegrow(a, n) (stbi__sbneedgrow(a, (n)) ? stbi__sbgrow(a, n) : 0) +#define stbi__sbgrow(a, n) stbi__sbgrowf((void **)&(a), (n), sizeof(*(a))) -#define stbi__sbpush(a, v) (stbi__sbmaybegrow(a,1), (a)[stbi__sbn(a)++] = (v)) -#define stbi__sbcount(a) ((a) ? stbi__sbn(a) : 0) -#define stbi__sbfree(a) ((a) ? free(stbi__sbraw(a)),0 : 0) +#define stbi__sbpush(a, v) (stbi__sbmaybegrow(a, 1), (a)[stbi__sbn(a)++] = (v)) +#define stbi__sbcount(a) ((a) ? stbi__sbn(a) : 0) +#define stbi__sbfree(a) ((a) ? free(stbi__sbraw(a)), 0 : 0) static void *stbi__sbgrowf(void **arr, int increment, int itemsize) { - int m = *arr ? 2*stbi__sbm(*arr)+increment : increment+1; - void *p = realloc(*arr ? stbi__sbraw(*arr) : 0, itemsize * m + sizeof(int)*2); - assert(p); - if (p) { - if (!*arr) ((int *) p)[1] = 0; - *arr = (void *) ((int *) p + 2); - stbi__sbm(*arr) = m; - } - return *arr; + int m = *arr ? 2 * stbi__sbm(*arr) + increment : increment + 1; + void *p = realloc(*arr ? stbi__sbraw(*arr) : 0, itemsize * m + sizeof(int) * 2); + assert(p); + if (p) + { + if (!*arr) ((int *)p)[1] = 0; + *arr = (void *)((int *)p + 2); + stbi__sbm(*arr) = m; + } + return *arr; } static unsigned char *stbi__zlib_flushf(unsigned char *data, unsigned int *bitbuffer, int *bitcount) { - while (*bitcount >= 8) { - stbi__sbpush(data, (unsigned char) *bitbuffer); - *bitbuffer >>= 8; - *bitcount -= 8; - } - return data; + while (*bitcount >= 8) + { + stbi__sbpush(data, (unsigned char)*bitbuffer); + *bitbuffer >>= 8; + *bitcount -= 8; + } + return data; } static int stbi__zlib_bitrev(int code, int codebits) { - int res=0; - while (codebits--) { - res = (res << 1) | (code & 1); - code >>= 1; - } - return res; + int res = 0; + while (codebits--) + { + res = (res << 1) | (code & 1); + code >>= 1; + } + return res; } static unsigned int stbi__zlib_countm(unsigned char *a, unsigned char *b, int limit) { - int i; - for (i=0; i < limit && i < 258; ++i) - if (a[i] != b[i]) break; - return i; + int i; + for (i = 0; i < limit && i < 258; ++i) + if (a[i] != b[i]) break; + return i; } static unsigned int stbi__zhash(unsigned char *data) { - stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16); - hash ^= hash << 3; - hash += hash >> 5; - hash ^= hash << 4; - hash += hash >> 17; - hash ^= hash << 25; - hash += hash >> 6; - return hash; + stbiw_uint32 hash = data[0] + (data[1] << 8) + (data[2] << 16); + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + return hash; } #define stbi__zlib_flush() (out = stbi__zlib_flushf(out, &bitbuf, &bitcount)) -#define stbi__zlib_add(code,codebits) \ - (bitbuf |= (code) << bitcount, bitcount += (codebits), stbi__zlib_flush()) -#define stbi__zlib_huffa(b,c) stbi__zlib_add(stbi__zlib_bitrev(b,c),c) +#define stbi__zlib_add(code, codebits) \ + (bitbuf |= (code) << bitcount, bitcount += (codebits), stbi__zlib_flush()) +#define stbi__zlib_huffa(b, c) stbi__zlib_add(stbi__zlib_bitrev(b, c), c) // default huffman tables -#define stbi__zlib_huff1(n) stbi__zlib_huffa(0x30 + (n), 8) -#define stbi__zlib_huff2(n) stbi__zlib_huffa(0x190 + (n)-144, 9) -#define stbi__zlib_huff3(n) stbi__zlib_huffa(0 + (n)-256,7) -#define stbi__zlib_huff4(n) stbi__zlib_huffa(0xc0 + (n)-280,8) -#define stbi__zlib_huff(n) ((n) <= 143 ? stbi__zlib_huff1(n) : (n) <= 255 ? stbi__zlib_huff2(n) : (n) <= 279 ? stbi__zlib_huff3(n) : stbi__zlib_huff4(n)) +#define stbi__zlib_huff1(n) stbi__zlib_huffa(0x30 + (n), 8) +#define stbi__zlib_huff2(n) stbi__zlib_huffa(0x190 + (n)-144, 9) +#define stbi__zlib_huff3(n) stbi__zlib_huffa(0 + (n)-256, 7) +#define stbi__zlib_huff4(n) stbi__zlib_huffa(0xc0 + (n)-280, 8) +#define stbi__zlib_huff(n) ((n) <= 143 ? stbi__zlib_huff1(n) : (n) <= 255 ? stbi__zlib_huff2(n) : (n) <= 279 ? stbi__zlib_huff3(n) : stbi__zlib_huff4(n)) #define stbi__zlib_huffb(n) ((n) <= 143 ? stbi__zlib_huff1(n) : stbi__zlib_huff2(n)) -#define stbi__ZHASH 16384 +#define stbi__ZHASH 16384 -unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality) +unsigned char *stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality) { - static unsigned short lengthc[] = { 3,4,5,6,7,8,9,10,11,13,15,17,19,23,27,31,35,43,51,59,67,83,99,115,131,163,195,227,258, 259 }; - static unsigned char lengtheb[]= { 0,0,0,0,0,0,0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 }; - static unsigned short distc[] = { 1,2,3,4,5,7,9,13,17,25,33,49,65,97,129,193,257,385,513,769,1025,1537,2049,3073,4097,6145,8193,12289,16385,24577, 32768 }; - static unsigned char disteb[] = { 0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13 }; - unsigned int bitbuf=0; - int i,j, bitcount=0; - unsigned char *out = NULL; - unsigned char **hash_table[stbi__ZHASH]; // 64KB on the stack! - if (quality < 5) quality = 5; + static unsigned short lengthc[] = {3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 259}; + static unsigned char lengtheb[] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}; + static unsigned short distc[] = {1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 32768}; + static unsigned char disteb[] = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; + unsigned int bitbuf = 0; + int i, j, bitcount = 0; + unsigned char *out = NULL; + unsigned char **hash_table[stbi__ZHASH]; // 64KB on the stack! + if (quality < 5) quality = 5; - stbi__sbpush(out, 0x78); // DEFLATE 32K window - stbi__sbpush(out, 0x5e); // FLEVEL = 1 - stbi__zlib_add(1,1); // BFINAL = 1 - stbi__zlib_add(1,2); // B3YPE = 1 -- fixed huffman + stbi__sbpush(out, 0x78); // DEFLATE 32K window + stbi__sbpush(out, 0x5e); // FLEVEL = 1 + stbi__zlib_add(1, 1); // BFINAL = 1 + stbi__zlib_add(1, 2); // B3YPE = 1 -- fixed huffman - for (i=0; i < stbi__ZHASH; ++i) - hash_table[i] = NULL; + for (i = 0; i < stbi__ZHASH; ++i) + hash_table[i] = NULL; - i=0; - while (i < data_len-3) { - // hash next 3 bytes of data to be compressed - int h = stbi__zhash(data+i)&(stbi__ZHASH-1), best=3; - unsigned char *bestloc = 0; - unsigned char **hlist = hash_table[h]; - int n = stbi__sbcount(hlist); - for (j=0; j < n; ++j) { - if (hlist[j]-data > i-32768) { // if entry lies within window - int d = stbi__zlib_countm(hlist[j], data+i, data_len-i); - if (d >= best) best=d,bestloc=hlist[j]; - } - } - // when hash table entry is too long, delete half the entries - if (hash_table[h] && stbi__sbn(hash_table[h]) == 2*quality) { - memcpy(hash_table[h], hash_table[h]+quality, sizeof(hash_table[h][0])*quality); - stbi__sbn(hash_table[h]) = quality; - } - stbi__sbpush(hash_table[h],data+i); + i = 0; + while (i < data_len - 3) + { + // hash next 3 bytes of data to be compressed + int h = stbi__zhash(data + i) & (stbi__ZHASH - 1), best = 3; + unsigned char *bestloc = 0; + unsigned char **hlist = hash_table[h]; + int n = stbi__sbcount(hlist); + for (j = 0; j < n; ++j) + { + if (hlist[j] - data > i - 32768) + { // if entry lies within window + int d = stbi__zlib_countm(hlist[j], data + i, data_len - i); + if (d >= best) best = d, bestloc = hlist[j]; + } + } + // when hash table entry is too long, delete half the entries + if (hash_table[h] && stbi__sbn(hash_table[h]) == 2 * quality) + { + memcpy(hash_table[h], hash_table[h] + quality, sizeof(hash_table[h][0]) * quality); + stbi__sbn(hash_table[h]) = quality; + } + stbi__sbpush(hash_table[h], data + i); - if (bestloc) { - // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal - h = stbi__zhash(data+i+1)&(stbi__ZHASH-1); - hlist = hash_table[h]; - n = stbi__sbcount(hlist); - for (j=0; j < n; ++j) { - if (hlist[j]-data > i-32767) { - int e = stbi__zlib_countm(hlist[j], data+i+1, data_len-i-1); - if (e > best) { // if next match is better, bail on current match - bestloc = NULL; - break; - } - } - } - } + if (bestloc) + { + // "lazy matching" - check match at *next* byte, and if it's better, do cur byte as literal + h = stbi__zhash(data + i + 1) & (stbi__ZHASH - 1); + hlist = hash_table[h]; + n = stbi__sbcount(hlist); + for (j = 0; j < n; ++j) + { + if (hlist[j] - data > i - 32767) + { + int e = stbi__zlib_countm(hlist[j], data + i + 1, data_len - i - 1); + if (e > best) + { // if next match is better, bail on current match + bestloc = NULL; + break; + } + } + } + } - if (bestloc) { - int d = data+i - bestloc; // distance back - assert(d <= 32767 && best <= 258); - for (j=0; best > lengthc[j+1]-1; ++j); - stbi__zlib_huff(j+257); - if (lengtheb[j]) stbi__zlib_add(best - lengthc[j], lengtheb[j]); - for (j=0; d > distc[j+1]-1; ++j); - stbi__zlib_add(stbi__zlib_bitrev(j,5),5); - if (disteb[j]) stbi__zlib_add(d - distc[j], disteb[j]); - i += best; - } else { - stbi__zlib_huffb(data[i]); - ++i; - } - } - // write out final bytes - for (;i < data_len; ++i) - stbi__zlib_huffb(data[i]); - stbi__zlib_huff(256); // end of block - // pad with 0 bits to byte boundary - while (bitcount) - stbi__zlib_add(0,1); + if (bestloc) + { + int d = data + i - bestloc; // distance back + assert(d <= 32767 && best <= 258); + for (j = 0; best > lengthc[j + 1] - 1; ++j) + ; + stbi__zlib_huff(j + 257); + if (lengtheb[j]) stbi__zlib_add(best - lengthc[j], lengtheb[j]); + for (j = 0; d > distc[j + 1] - 1; ++j) + ; + stbi__zlib_add(stbi__zlib_bitrev(j, 5), 5); + if (disteb[j]) stbi__zlib_add(d - distc[j], disteb[j]); + i += best; + } + else + { + stbi__zlib_huffb(data[i]); + ++i; + } + } + // write out final bytes + for (; i < data_len; ++i) + stbi__zlib_huffb(data[i]); + stbi__zlib_huff(256); // end of block + // pad with 0 bits to byte boundary + while (bitcount) + stbi__zlib_add(0, 1); - for (i=0; i < stbi__ZHASH; ++i) - (void) stbi__sbfree(hash_table[i]); + for (i = 0; i < stbi__ZHASH; ++i) + (void)stbi__sbfree(hash_table[i]); - { - // compute adler32 on input - unsigned int i=0, s1=1, s2=0, blocklen = data_len % 5552; - int j=0; - while (j < data_len) { - for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1; - s1 %= 65521, s2 %= 65521; - j += blocklen; - blocklen = 5552; - } - stbi__sbpush(out, (unsigned char) (s2 >> 8)); - stbi__sbpush(out, (unsigned char) s2); - stbi__sbpush(out, (unsigned char) (s1 >> 8)); - stbi__sbpush(out, (unsigned char) s1); - } - *out_len = stbi__sbn(out); - // make returned pointer freeable - memmove(stbi__sbraw(out), out, *out_len); - return (unsigned char *) stbi__sbraw(out); + { + // compute adler32 on input + unsigned int i = 0, s1 = 1, s2 = 0, blocklen = data_len % 5552; + int j = 0; + while (j < data_len) + { + for (i = 0; i < blocklen; ++i) s1 += data[j + i], s2 += s1; + s1 %= 65521, s2 %= 65521; + j += blocklen; + blocklen = 5552; + } + stbi__sbpush(out, (unsigned char)(s2 >> 8)); + stbi__sbpush(out, (unsigned char)s2); + stbi__sbpush(out, (unsigned char)(s1 >> 8)); + stbi__sbpush(out, (unsigned char)s1); + } + *out_len = stbi__sbn(out); + // make returned pointer freeable + memmove(stbi__sbraw(out), out, *out_len); + return (unsigned char *)stbi__sbraw(out); } unsigned int stbi__crc32(unsigned char *buffer, int len) { - static unsigned int crc_table[256]; - unsigned int crc = ~0u; - int i,j; - if (crc_table[1] == 0) - for(i=0; i < 256; i++) - for (crc_table[i]=i, j=0; j < 8; ++j) - crc_table[i] = (crc_table[i] >> 1) ^ (crc_table[i] & 1 ? 0xedb88320 : 0); - for (i=0; i < len; ++i) - crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)]; - return ~crc; + static unsigned int crc_table[256]; + unsigned int crc = ~0u; + int i, j; + if (crc_table[1] == 0) + for (i = 0; i < 256; i++) + for (crc_table[i] = i, j = 0; j < 8; ++j) + crc_table[i] = (crc_table[i] >> 1) ^ (crc_table[i] & 1 ? 0xedb88320 : 0); + for (i = 0; i < len; ++i) + crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)]; + return ~crc; } -#define stbi__wpng4(o,a,b,c,d) ((o)[0]=(unsigned char)(a),(o)[1]=(unsigned char)(b),(o)[2]=(unsigned char)(c),(o)[3]=(unsigned char)(d),(o)+=4) -#define stbi__wp32(data,v) stbi__wpng4(data, (v)>>24,(v)>>16,(v)>>8,(v)); -#define stbi__wptag(data,s) stbi__wpng4(data, s[0],s[1],s[2],s[3]) +#define stbi__wpng4(o, a, b, c, d) ((o)[0] = (unsigned char)(a), (o)[1] = (unsigned char)(b), (o)[2] = (unsigned char)(c), (o)[3] = (unsigned char)(d), (o) += 4) +#define stbi__wp32(data, v) stbi__wpng4(data, (v) >> 24, (v) >> 16, (v) >> 8, (v)); +#define stbi__wptag(data, s) stbi__wpng4(data, s[0], s[1], s[2], s[3]) static void stbi__wpcrc(unsigned char **data, int len) { - unsigned int crc = stbi__crc32(*data - len - 4, len+4); - stbi__wp32(*data, crc); + unsigned int crc = stbi__crc32(*data - len - 4, len + 4); + stbi__wp32(*data, crc); } static unsigned char stbi__paeth(int a, int b, int c) { - int p = a + b - c, pa = abs(p-a), pb = abs(p-b), pc = abs(p-c); - if (pa <= pb && pa <= pc) return (unsigned char) a; - if (pb <= pc) return (unsigned char) b; - return (unsigned char) c; + int p = a + b - c, pa = abs(p - a), pb = abs(p - b), pc = abs(p - c); + if (pa <= pb && pa <= pc) return (unsigned char)a; + if (pb <= pc) return (unsigned char)b; + return (unsigned char)c; } unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len) { - int ctype[5] = { -1, 0, 4, 2, 6 }; - unsigned char sig[8] = { 137,80,78,71,13,10,26,10 }; - unsigned char *out,*o, *filt, *zlib; - signed char *line_buffer; - int i,j,k,p,zlen; + int ctype[5] = {-1, 0, 4, 2, 6}; + unsigned char sig[8] = {137, 80, 78, 71, 13, 10, 26, 10}; + unsigned char *out, *o, *filt, *zlib; + signed char *line_buffer; + int i, j, k, p, zlen; - if (stride_bytes == 0) - stride_bytes = x * n; + if (stride_bytes == 0) + stride_bytes = x * n; - filt = (unsigned char *) malloc((x*n+1) * y); if (!filt) return 0; - line_buffer = (signed char *) malloc(x * n); if (!line_buffer) { free(filt); return 0; } - for (j=0; j < y; ++j) { - static int mapping[] = { 0,1,2,3,4 }; - static int firstmap[] = { 0,1,0,5,6 }; - int *mymap = j ? mapping : firstmap; - int best = 0, bestval = 0x7fffffff; - for (p=0; p < 2; ++p) { - for (k= p?best:0; k < 5; ++k) { - int type = mymap[k],est=0; - unsigned char *z = pixels + stride_bytes*j; - for (i=0; i < n; ++i) - switch (type) { - case 0: line_buffer[i] = z[i]; break; - case 1: line_buffer[i] = z[i]; break; - case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break; - case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break; - case 4: line_buffer[i] = (signed char) (z[i] - stbi__paeth(0,z[i-stride_bytes],0)); break; - case 5: line_buffer[i] = z[i]; break; - case 6: line_buffer[i] = z[i]; break; - } - for (i=n; i < x*n; ++i) { - switch (type) { - case 0: line_buffer[i] = z[i]; break; - case 1: line_buffer[i] = z[i] - z[i-n]; break; - case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break; - case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break; - case 4: line_buffer[i] = z[i] - stbi__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break; - case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break; - case 6: line_buffer[i] = z[i] - stbi__paeth(z[i-n], 0,0); break; - } - } - if (p) break; - for (i=0; i < x*n; ++i) - est += abs((signed char) line_buffer[i]); - if (est < bestval) { bestval = est; best = k; } - } - } - // when we get here, best contains the filter type, and line_buffer contains the data - filt[j*(x*n+1)] = (unsigned char) best; - memcpy(filt+j*(x*n+1)+1, line_buffer, x*n); - } - free(line_buffer); - zlib = stbi_zlib_compress(filt, y*( x*n+1), &zlen, 8); // increase 8 to get smaller but use more memory - free(filt); - if (!zlib) return 0; + filt = (unsigned char *)malloc((x * n + 1) * y); + if (!filt) return 0; + line_buffer = (signed char *)malloc(x * n); + if (!line_buffer) + { + free(filt); + return 0; + } + for (j = 0; j < y; ++j) + { + static int mapping[] = {0, 1, 2, 3, 4}; + static int firstmap[] = {0, 1, 0, 5, 6}; + int *mymap = j ? mapping : firstmap; + int best = 0, bestval = 0x7fffffff; + for (p = 0; p < 2; ++p) + { + for (k = p ? best : 0; k < 5; ++k) + { + int type = mymap[k], est = 0; + unsigned char *z = pixels + stride_bytes * j; + for (i = 0; i < n; ++i) + switch (type) + { + case 0: + line_buffer[i] = z[i]; + break; + case 1: + line_buffer[i] = z[i]; + break; + case 2: + line_buffer[i] = z[i] - z[i - stride_bytes]; + break; + case 3: + line_buffer[i] = z[i] - (z[i - stride_bytes] >> 1); + break; + case 4: + line_buffer[i] = (signed char)(z[i] - stbi__paeth(0, z[i - stride_bytes], 0)); + break; + case 5: + line_buffer[i] = z[i]; + break; + case 6: + line_buffer[i] = z[i]; + break; + } + for (i = n; i < x * n; ++i) + { + switch (type) + { + case 0: + line_buffer[i] = z[i]; + break; + case 1: + line_buffer[i] = z[i] - z[i - n]; + break; + case 2: + line_buffer[i] = z[i] - z[i - stride_bytes]; + break; + case 3: + line_buffer[i] = z[i] - ((z[i - n] + z[i - stride_bytes]) >> 1); + break; + case 4: + line_buffer[i] = z[i] - stbi__paeth(z[i - n], z[i - stride_bytes], z[i - stride_bytes - n]); + break; + case 5: + line_buffer[i] = z[i] - (z[i - n] >> 1); + break; + case 6: + line_buffer[i] = z[i] - stbi__paeth(z[i - n], 0, 0); + break; + } + } + if (p) break; + for (i = 0; i < x * n; ++i) + est += abs((signed char)line_buffer[i]); + if (est < bestval) + { + bestval = est; + best = k; + } + } + } + // when we get here, best contains the filter type, and line_buffer contains the data + filt[j * (x * n + 1)] = (unsigned char)best; + memcpy(filt + j * (x * n + 1) + 1, line_buffer, x * n); + } + free(line_buffer); + zlib = stbi_zlib_compress(filt, y * (x * n + 1), &zlen, 8); // increase 8 to get smaller but use more memory + free(filt); + if (!zlib) return 0; - // each tag requires 12 bytes of overhead - out = (unsigned char *) malloc(8 + 12+13 + 12+zlen + 12); - if (!out) return 0; - *out_len = 8 + 12+13 + 12+zlen + 12; + // each tag requires 12 bytes of overhead + out = (unsigned char *)malloc(8 + 12 + 13 + 12 + zlen + 12); + if (!out) return 0; + *out_len = 8 + 12 + 13 + 12 + zlen + 12; - o=out; - memcpy(o,sig,8); o+= 8; - stbi__wp32(o, 13); // header length - stbi__wptag(o, "IHDR"); - stbi__wp32(o, x); - stbi__wp32(o, y); - *o++ = 8; - *o++ = (unsigned char) ctype[n]; - *o++ = 0; - *o++ = 0; - *o++ = 0; - stbi__wpcrc(&o,13); + o = out; + memcpy(o, sig, 8); + o += 8; + stbi__wp32(o, 13); // header length + stbi__wptag(o, "IHDR"); + stbi__wp32(o, x); + stbi__wp32(o, y); + *o++ = 8; + *o++ = (unsigned char)ctype[n]; + *o++ = 0; + *o++ = 0; + *o++ = 0; + stbi__wpcrc(&o, 13); - stbi__wp32(o, zlen); - stbi__wptag(o, "IDAT"); - memcpy(o, zlib, zlen); o += zlen; free(zlib); - stbi__wpcrc(&o, zlen); + stbi__wp32(o, zlen); + stbi__wptag(o, "IDAT"); + memcpy(o, zlib, zlen); + o += zlen; + free(zlib); + stbi__wpcrc(&o, zlen); - stbi__wp32(o,0); - stbi__wptag(o, "IEND"); - stbi__wpcrc(&o,0); + stbi__wp32(o, 0); + stbi__wptag(o, "IEND"); + stbi__wpcrc(&o, 0); - assert(o == out + *out_len); + assert(o == out + *out_len); - return out; + return out; } int stbi_write_png(char const *filename, int x, int y, int comp, const void *data, int stride_bytes) { - FILE *f; - int len; - unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len); - if (!png) return 0; - f = fopen(filename, "wb"); - if (!f) { - free(png); - return 0; - } - fwrite(png, 1, len, f); - fclose(f); - free(png); - return 1; + FILE *f; + int len; + unsigned char *png = stbi_write_png_to_mem((unsigned char *)data, stride_bytes, x, y, comp, &len); + if (!png) return 0; + f = fopen(filename, "wb"); + if (!f) + { + free(png); + return 0; + } + fwrite(png, 1, len, f); + fclose(f); + free(png); + return 1; } -#endif // STB_IMAGE_WRITE_IMPLEMENTATION +#endif // STB_IMAGE_WRITE_IMPLEMENTATION /* Revision history diff --git a/examples/ThirdPartyLibs/stb_image/stb_truetype.h b/examples/ThirdPartyLibs/stb_image/stb_truetype.h index 663aef4b6..4d84eb172 100644 --- a/examples/ThirdPartyLibs/stb_image/stb_truetype.h +++ b/examples/ThirdPartyLibs/stb_image/stb_truetype.h @@ -25,7 +25,7 @@ // "Zer" on mollyrocket (with fix) // Cass Everitt // stoiko (Haemimont Games) -// Brian Hook +// Brian Hook // Walter van Niftrik // David Gow // David Given @@ -229,7 +229,7 @@ // Curve tesselation 120 LOC \__ 550 LOC Bitmap creation // Bitmap management 100 LOC / // Baked bitmap interface 70 LOC / -// Font name matching & access 150 LOC ---- 150 +// Font name matching & access 150 LOC ---- 150 // C runtime library abstraction 60 LOC ---- 60 // // @@ -322,7 +322,7 @@ int main(int argc, char **argv) } return 0; } -#endif +#endif // // Output: // @@ -336,9 +336,9 @@ int main(int argc, char **argv) // :@@. M@M // @@@o@@@@ // :M@@V:@@. -// +// ////////////////////////////////////////////////////////////////////////////// -// +// // Complete program: print "Hello World!" banner, with bugs // #if 0 @@ -385,7 +385,6 @@ int main(int arg, char **argv) } #endif - ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //// @@ -395,53 +394,53 @@ int main(int arg, char **argv) //// of C library functions used by stb_truetype. #ifdef STB_TRUETYPE_IMPLEMENTATION - // #define your own (u)stbtt_int8/16/32 before including to override this - #ifndef stbtt_uint8 - typedef unsigned char stbtt_uint8; - typedef signed char stbtt_int8; - typedef unsigned short stbtt_uint16; - typedef signed short stbtt_int16; - typedef unsigned int stbtt_uint32; - typedef signed int stbtt_int32; - #endif +// #define your own (u)stbtt_int8/16/32 before including to override this +#ifndef stbtt_uint8 +typedef unsigned char stbtt_uint8; +typedef signed char stbtt_int8; +typedef unsigned short stbtt_uint16; +typedef signed short stbtt_int16; +typedef unsigned int stbtt_uint32; +typedef signed int stbtt_int32; +#endif - typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1]; - typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1]; +typedef char stbtt__check_size32[sizeof(stbtt_int32) == 4 ? 1 : -1]; +typedef char stbtt__check_size16[sizeof(stbtt_int16) == 2 ? 1 : -1]; - // #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h - #ifndef STBTT_ifloor - #include - #define STBTT_ifloor(x) ((int) floor(x)) - #define STBTT_iceil(x) ((int) ceil(x)) - #endif +// #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h +#ifndef STBTT_ifloor +#include +#define STBTT_ifloor(x) ((int)floor(x)) +#define STBTT_iceil(x) ((int)ceil(x)) +#endif - #ifndef STBTT_sqrt - #include - #define STBTT_sqrt(x) sqrt(x) - #endif +#ifndef STBTT_sqrt +#include +#define STBTT_sqrt(x) sqrt(x) +#endif - // #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h - #ifndef STBTT_malloc - #include - #define STBTT_malloc(x,u) ((void)(u),malloc(x)) - #define STBTT_free(x,u) ((void)(u),free(x)) - #endif +// #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h +#ifndef STBTT_malloc +#include +#define STBTT_malloc(x, u) ((void)(u), malloc(x)) +#define STBTT_free(x, u) ((void)(u), free(x)) +#endif - #ifndef STBTT_assert - #include - #define STBTT_assert(x) assert(x) - #endif +#ifndef STBTT_assert +#include +#define STBTT_assert(x) assert(x) +#endif - #ifndef STBTT_strlen - #include - #define STBTT_strlen(x) strlen(x) - #endif +#ifndef STBTT_strlen +#include +#define STBTT_strlen(x) strlen(x) +#endif - #ifndef STBTT_memcpy - #include - #define STBTT_memcpy memcpy - #define STBTT_memset memset - #endif +#ifndef STBTT_memcpy +#include +#define STBTT_memcpy memcpy +#define STBTT_memset memset +#endif #endif /////////////////////////////////////////////////////////////////////////////// @@ -461,445 +460,462 @@ int main(int arg, char **argv) #endif #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -////////////////////////////////////////////////////////////////////////////// -// -// TEXTURE BAKING API -// -// If you use this API, you only have to call two functions ever. -// + ////////////////////////////////////////////////////////////////////////////// + // + // TEXTURE BAKING API + // + // If you use this API, you only have to call two functions ever. + // -typedef struct -{ - unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap - float xoff,yoff,xadvance; -} stbtt_bakedchar; + typedef struct + { + unsigned short x0, y0, x1, y1; // coordinates of bbox in bitmap + float xoff, yoff, xadvance; + } stbtt_bakedchar; -STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) - float pixel_height, // height of font in pixels - unsigned char *pixels, int pw, int ph, // bitmap to be filled in - int first_char, int num_chars, // characters to bake - stbtt_bakedchar *chardata); // you allocate this, it's num_chars long -// if return is positive, the first unused row of the bitmap -// if return is negative, returns the negative of the number of characters that fit -// if return is 0, no characters fit and no rows were used -// This uses a very crappy packing. + STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) + float pixel_height, // height of font in pixels + unsigned char *pixels, int pw, int ph, // bitmap to be filled in + int first_char, int num_chars, // characters to bake + stbtt_bakedchar *chardata); // you allocate this, it's num_chars long + // if return is positive, the first unused row of the bitmap + // if return is negative, returns the negative of the number of characters that fit + // if return is 0, no characters fit and no rows were used + // This uses a very crappy packing. -typedef struct -{ - float x0,y0,s0,t0; // top-left - float x1,y1,s1,t1; // bottom-right -} stbtt_aligned_quad; + typedef struct + { + float x0, y0, s0, t0; // top-left + float x1, y1, s1, t1; // bottom-right + } stbtt_aligned_quad; -STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, // same data as above - int char_index, // character to display - float *xpos, float *ypos, // pointers to current position in screen pixel space - stbtt_aligned_quad *q, // output: quad to draw - int opengl_fillrule); // true if opengl fill rule; false if DX9 or earlier -// Call GetBakedQuad with char_index = 'character - first_char', and it -// creates the quad you need to draw and advances the current position. -// -// The coordinate system used assumes y increases downwards. -// -// Characters will extend both above and below the current position; -// see discussion of "BASELINE" above. -// -// It's inefficient; you might want to c&p it and optimize it. + STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, // same data as above + int char_index, // character to display + float *xpos, float *ypos, // pointers to current position in screen pixel space + stbtt_aligned_quad *q, // output: quad to draw + int opengl_fillrule); // true if opengl fill rule; false if DX9 or earlier + // Call GetBakedQuad with char_index = 'character - first_char', and it + // creates the quad you need to draw and advances the current position. + // + // The coordinate system used assumes y increases downwards. + // + // Characters will extend both above and below the current position; + // see discussion of "BASELINE" above. + // + // It's inefficient; you might want to c&p it and optimize it. + ////////////////////////////////////////////////////////////////////////////// + // + // NEW TEXTURE BAKING API + // + // This provides options for packing multiple fonts into one atlas, not + // perfectly but better than nothing. + typedef struct + { + unsigned short x0, y0, x1, y1; // coordinates of bbox in bitmap + float xoff, yoff, xadvance; + float xoff2, yoff2; + } stbtt_packedchar; -////////////////////////////////////////////////////////////////////////////// -// -// NEW TEXTURE BAKING API -// -// This provides options for packing multiple fonts into one atlas, not -// perfectly but better than nothing. + typedef struct stbtt_pack_context stbtt_pack_context; -typedef struct -{ - unsigned short x0,y0,x1,y1; // coordinates of bbox in bitmap - float xoff,yoff,xadvance; - float xoff2,yoff2; -} stbtt_packedchar; + STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context); + // Initializes a packing context stored in the passed-in stbtt_pack_context. + // Future calls using this context will pack characters into the bitmap passed + // in here: a 1-channel bitmap that is weight x height. stride_in_bytes is + // the distance from one row to the next (or 0 to mean they are packed tightly + // together). "padding" is // the amount of padding to leave between each + // character (normally you want '1' for bitmaps you'll use as textures with + // bilinear filtering). + // + // Returns 0 on failure, 1 on success. -typedef struct stbtt_pack_context stbtt_pack_context; + STBTT_DEF void stbtt_PackEnd(stbtt_pack_context *spc); + // Cleans up the packing context and frees all memory. -STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int width, int height, int stride_in_bytes, int padding, void *alloc_context); -// Initializes a packing context stored in the passed-in stbtt_pack_context. -// Future calls using this context will pack characters into the bitmap passed -// in here: a 1-channel bitmap that is weight x height. stride_in_bytes is -// the distance from one row to the next (or 0 to mean they are packed tightly -// together). "padding" is // the amount of padding to leave between each -// character (normally you want '1' for bitmaps you'll use as textures with -// bilinear filtering). -// -// Returns 0 on failure, 1 on success. +#define STBTT_POINT_SIZE(x) (-(x)) -STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc); -// Cleans up the packing context and frees all memory. + STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size, + int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range); + // Creates character bitmaps from the font_index'th font found in fontdata (use + // font_index=0 if you don't know what that is). It creates num_chars_in_range + // bitmaps for characters with unicode values starting at first_unicode_char_in_range + // and increasing. Data for how to render them is stored in chardata_for_range; + // pass these to stbtt_GetPackedQuad to get back renderable quads. + // + // font_size is the full height of the character from ascender to descender, + // as computed by stbtt_ScaleForPixelHeight. To use a point size as computed + // by stbtt_ScaleForMappingEmToPixels, wrap the point size in STBTT_POINT_SIZE() + // and pass that result as 'font_size': + // ..., 20 , ... // font max minus min y is 20 pixels tall + // ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall -#define STBTT_POINT_SIZE(x) (-(x)) + typedef struct + { + float font_size; + int first_unicode_char_in_range; + int num_chars_in_range; + stbtt_packedchar *chardata_for_range; // output + } stbtt_pack_range; -STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size, - int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range); -// Creates character bitmaps from the font_index'th font found in fontdata (use -// font_index=0 if you don't know what that is). It creates num_chars_in_range -// bitmaps for characters with unicode values starting at first_unicode_char_in_range -// and increasing. Data for how to render them is stored in chardata_for_range; -// pass these to stbtt_GetPackedQuad to get back renderable quads. -// -// font_size is the full height of the character from ascender to descender, -// as computed by stbtt_ScaleForPixelHeight. To use a point size as computed -// by stbtt_ScaleForMappingEmToPixels, wrap the point size in STBTT_POINT_SIZE() -// and pass that result as 'font_size': -// ..., 20 , ... // font max minus min y is 20 pixels tall -// ..., STBTT_POINT_SIZE(20), ... // 'M' is 20 pixels tall + STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges); + // Creates character bitmaps from multiple ranges of characters stored in + // ranges. This will usually create a better-packed bitmap than multiple + // calls to stbtt_PackFontRange. -typedef struct -{ - float font_size; - int first_unicode_char_in_range; - int num_chars_in_range; - stbtt_packedchar *chardata_for_range; // output -} stbtt_pack_range; + STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample); + // Oversampling a font increases the quality by allowing higher-quality subpixel + // positioning, and is especially valuable at smaller text sizes. + // + // This function sets the amount of oversampling for all following calls to + // stbtt_PackFontRange(s). The default (no oversampling) is achieved by + // h_oversample=1, v_oversample=1. The total number of pixels required is + // h_oversample*v_oversample larger than the default; for example, 2x2 + // oversampling requires 4x the storage of 1x1. For best results, render + // oversampled textures with bilinear filtering. Look at the readme in + // stb/tests/oversample for information about oversampled fonts -STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges); -// Creates character bitmaps from multiple ranges of characters stored in -// ranges. This will usually create a better-packed bitmap than multiple -// calls to stbtt_PackFontRange. + STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, // same data as above + int char_index, // character to display + float *xpos, float *ypos, // pointers to current position in screen pixel space + stbtt_aligned_quad *q, // output: quad to draw + int align_to_integer); + // this is an opaque structure that you shouldn't mess with which holds + // all the context needed from PackBegin to PackEnd. + struct stbtt_pack_context + { + void *user_allocator_context; + void *pack_info; + int width; + int height; + int stride_in_bytes; + int padding; + unsigned int h_oversample, v_oversample; + unsigned char *pixels; + void *nodes; + }; -STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample); -// Oversampling a font increases the quality by allowing higher-quality subpixel -// positioning, and is especially valuable at smaller text sizes. -// -// This function sets the amount of oversampling for all following calls to -// stbtt_PackFontRange(s). The default (no oversampling) is achieved by -// h_oversample=1, v_oversample=1. The total number of pixels required is -// h_oversample*v_oversample larger than the default; for example, 2x2 -// oversampling requires 4x the storage of 1x1. For best results, render -// oversampled textures with bilinear filtering. Look at the readme in -// stb/tests/oversample for information about oversampled fonts + ////////////////////////////////////////////////////////////////////////////// + // + // FONT LOADING + // + // -STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, // same data as above - int char_index, // character to display - float *xpos, float *ypos, // pointers to current position in screen pixel space - stbtt_aligned_quad *q, // output: quad to draw - int align_to_integer); + STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index); + // Each .ttf/.ttc file may have more than one font. Each font has a sequential + // index number starting from 0. Call this function to get the font offset for + // a given index; it returns -1 if the index is out of range. A regular .ttf + // file will only define one font and it always be at offset 0, so it will + // return '0' for index 0, and -1 for all other indices. You can just skip + // this step if you know it's that kind of font. -// this is an opaque structure that you shouldn't mess with which holds -// all the context needed from PackBegin to PackEnd. -struct stbtt_pack_context { - void *user_allocator_context; - void *pack_info; - int width; - int height; - int stride_in_bytes; - int padding; - unsigned int h_oversample, v_oversample; - unsigned char *pixels; - void *nodes; -}; + // The following structure is defined publically so you can declare one on + // the stack or as a global or etc, but you should treat it as opaque. + typedef struct stbtt_fontinfo + { + void *userdata; + unsigned char *data; // pointer to .ttf file + int fontstart; // offset of start of font -////////////////////////////////////////////////////////////////////////////// -// -// FONT LOADING -// -// + int numGlyphs; // number of glyphs, needed for range checking -STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index); -// Each .ttf/.ttc file may have more than one font. Each font has a sequential -// index number starting from 0. Call this function to get the font offset for -// a given index; it returns -1 if the index is out of range. A regular .ttf -// file will only define one font and it always be at offset 0, so it will -// return '0' for index 0, and -1 for all other indices. You can just skip -// this step if you know it's that kind of font. + int loca, head, glyf, hhea, hmtx, kern; // table locations as offset from start of .ttf + int index_map; // a cmap mapping for our chosen character encoding + int indexToLocFormat; // format needed to map from glyph index to glyph + } stbtt_fontinfo; + STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset); + // Given an offset into the file that defines a font, this function builds + // the necessary cached info for the rest of the system. You must allocate + // the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't + // need to do anything special to free it, because the contents are pure + // value data with no additional data structures. Returns 0 on failure. -// The following structure is defined publically so you can declare one on -// the stack or as a global or etc, but you should treat it as opaque. -typedef struct stbtt_fontinfo -{ - void * userdata; - unsigned char * data; // pointer to .ttf file - int fontstart; // offset of start of font + ////////////////////////////////////////////////////////////////////////////// + // + // CHARACTER TO GLYPH-INDEX CONVERSIOn - int numGlyphs; // number of glyphs, needed for range checking + STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint); + // If you're going to perform multiple operations on the same character + // and you want a speed-up, call this function with the character you're + // going to process, then use glyph-based functions instead of the + // codepoint-based functions. - int loca,head,glyf,hhea,hmtx,kern; // table locations as offset from start of .ttf - int index_map; // a cmap mapping for our chosen character encoding - int indexToLocFormat; // format needed to map from glyph index to glyph -} stbtt_fontinfo; + ////////////////////////////////////////////////////////////////////////////// + // + // CHARACTER PROPERTIES + // -STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset); -// Given an offset into the file that defines a font, this function builds -// the necessary cached info for the rest of the system. You must allocate -// the stbtt_fontinfo yourself, and stbtt_InitFont will fill it out. You don't -// need to do anything special to free it, because the contents are pure -// value data with no additional data structures. Returns 0 on failure. + STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels); + // computes a scale factor to produce a font whose "height" is 'pixels' tall. + // Height is measured as the distance from the highest ascender to the lowest + // descender; in other words, it's equivalent to calling stbtt_GetFontVMetrics + // and computing: + // scale = pixels / (ascent - descent) + // so if you prefer to measure height by the ascent only, use a similar calculation. + STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels); + // computes a scale factor to produce a font whose EM size is mapped to + // 'pixels' tall. This is probably what traditional APIs compute, but + // I'm not positive. -////////////////////////////////////////////////////////////////////////////// -// -// CHARACTER TO GLYPH-INDEX CONVERSIOn + STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap); + // ascent is the coordinate above the baseline the font extends; descent + // is the coordinate below the baseline the font extends (i.e. it is typically negative) + // lineGap is the spacing between one row's descent and the next row's ascent... + // so you should advance the vertical position by "*ascent - *descent + *lineGap" + // these are expressed in unscaled coordinates, so you must multiply by + // the scale factor for a given size -STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint); -// If you're going to perform multiple operations on the same character -// and you want a speed-up, call this function with the character you're -// going to process, then use glyph-based functions instead of the -// codepoint-based functions. + STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1); + // the bounding box around all possible characters + STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing); + // leftSideBearing is the offset from the current horizontal position to the left edge of the character + // advanceWidth is the offset from the current horizontal position to the next horizontal position + // these are expressed in unscaled coordinates -////////////////////////////////////////////////////////////////////////////// -// -// CHARACTER PROPERTIES -// + STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2); + // an additional amount to add to the 'advance' value between ch1 and ch2 -STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float pixels); -// computes a scale factor to produce a font whose "height" is 'pixels' tall. -// Height is measured as the distance from the highest ascender to the lowest -// descender; in other words, it's equivalent to calling stbtt_GetFontVMetrics -// and computing: -// scale = pixels / (ascent - descent) -// so if you prefer to measure height by the ascent only, use a similar calculation. + STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1); + // Gets the bounding box of the visible part of the glyph, in unscaled coordinates -STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels); -// computes a scale factor to produce a font whose EM size is mapped to -// 'pixels' tall. This is probably what traditional APIs compute, but -// I'm not positive. + STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing); + STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2); + STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); + // as above, but takes one or more glyph indices for greater efficiency -STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap); -// ascent is the coordinate above the baseline the font extends; descent -// is the coordinate below the baseline the font extends (i.e. it is typically negative) -// lineGap is the spacing between one row's descent and the next row's ascent... -// so you should advance the vertical position by "*ascent - *descent + *lineGap" -// these are expressed in unscaled coordinates, so you must multiply by -// the scale factor for a given size + ////////////////////////////////////////////////////////////////////////////// + // + // GLYPH SHAPES (you probably don't need these, but they have to go before + // the bitmaps for C declaration-order reasons) + // -STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1); -// the bounding box around all possible characters - -STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing); -// leftSideBearing is the offset from the current horizontal position to the left edge of the character -// advanceWidth is the offset from the current horizontal position to the next horizontal position -// these are expressed in unscaled coordinates - -STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2); -// an additional amount to add to the 'advance' value between ch1 and ch2 - -STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1); -// Gets the bounding box of the visible part of the glyph, in unscaled coordinates - -STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing); -STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2); -STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1); -// as above, but takes one or more glyph indices for greater efficiency - - -////////////////////////////////////////////////////////////////////////////// -// -// GLYPH SHAPES (you probably don't need these, but they have to go before -// the bitmaps for C declaration-order reasons) -// - -#ifndef STBTT_vmove // you can predefine these to use different values (but why?) - enum { - STBTT_vmove=1, - STBTT_vline, - STBTT_vcurve - }; +#ifndef STBTT_vmove // you can predefine these to use different values (but why?) + enum + { + STBTT_vmove = 1, + STBTT_vline, + STBTT_vcurve + }; #endif -#ifndef stbtt_vertex // you can predefine this to use different values - // (we share this with other code at RAD) - #define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file - typedef struct - { - stbtt_vertex_type x,y,cx,cy; - unsigned char type,padding; - } stbtt_vertex; +#ifndef stbtt_vertex // you can predefine this to use different values \ + // (we share this with other code at RAD) +#define stbtt_vertex_type short // can't use stbtt_int16 because that's not visible in the header file + typedef struct + { + stbtt_vertex_type x, y, cx, cy; + unsigned char type, padding; + } stbtt_vertex; #endif -STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index); -// returns non-zero if nothing is drawn for this glyph + STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index); + // returns non-zero if nothing is drawn for this glyph -STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices); -STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices); -// returns # of vertices and fills *vertices with the pointer to them -// these are expressed in "unscaled" coordinates -// -// The shape is a series of countours. Each one starts with -// a STBTT_moveto, then consists of a series of mixed -// STBTT_lineto and STBTT_curveto segments. A lineto -// draws a line from previous endpoint to its x,y; a curveto -// draws a quadratic bezier from previous endpoint to -// its x,y, using cx,cy as the bezier control point. + STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices); + STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **vertices); + // returns # of vertices and fills *vertices with the pointer to them + // these are expressed in "unscaled" coordinates + // + // The shape is a series of countours. Each one starts with + // a STBTT_moveto, then consists of a series of mixed + // STBTT_lineto and STBTT_curveto segments. A lineto + // draws a line from previous endpoint to its x,y; a curveto + // draws a quadratic bezier from previous endpoint to + // its x,y, using cx,cy as the bezier control point. -STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices); -// frees the data allocated above + STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *vertices); + // frees the data allocated above -////////////////////////////////////////////////////////////////////////////// -// -// BITMAP RENDERING -// + ////////////////////////////////////////////////////////////////////////////// + // + // BITMAP RENDERING + // -STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata); -// frees the bitmap allocated below + STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata); + // frees the bitmap allocated below -STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff); -// allocates a large-enough single-channel 8bpp bitmap and renders the -// specified character/glyph at the specified scale into it, with -// antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque). -// *width & *height are filled out with the width & height of the bitmap, -// which is stored left-to-right, top-to-bottom. -// -// xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap + STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff); + // allocates a large-enough single-channel 8bpp bitmap and renders the + // specified character/glyph at the specified scale into it, with + // antialiasing. 0 is no coverage (transparent), 255 is fully covered (opaque). + // *width & *height are filled out with the width & height of the bitmap, + // which is stored left-to-right, top-to-bottom. + // + // xoff/yoff are the offset it pixel space from the glyph origin to the top-left of the bitmap -STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff); -// the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel -// shift for the character + STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff); + // the same as stbtt_GetCodepoitnBitmap, but you can specify a subpixel + // shift for the character -STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint); -// the same as stbtt_GetCodepointBitmap, but you pass in storage for the bitmap -// in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap -// is clipped to out_w/out_h bytes. Call stbtt_GetCodepointBitmapBox to get the -// width and height and positioning info for it first. + STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint); + // the same as stbtt_GetCodepointBitmap, but you pass in storage for the bitmap + // in the form of 'output', with row spacing of 'out_stride' bytes. the bitmap + // is clipped to out_w/out_h bytes. Call stbtt_GetCodepointBitmapBox to get the + // width and height and positioning info for it first. -STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint); -// same as stbtt_MakeCodepointBitmap, but you can specify a subpixel -// shift for the character + STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint); + // same as stbtt_MakeCodepointBitmap, but you can specify a subpixel + // shift for the character -STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); -// get the bbox of the bitmap centered around the glyph origin; so the -// bitmap width is ix1-ix0, height is iy1-iy0, and location to place -// the bitmap top left is (leftSideBearing*scale,iy0). -// (Note that the bitmap uses y-increases-down, but the shape uses -// y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.) + STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); + // get the bbox of the bitmap centered around the glyph origin; so the + // bitmap width is ix1-ix0, height is iy1-iy0, and location to place + // the bitmap top left is (leftSideBearing*scale,iy0). + // (Note that the bitmap uses y-increases-down, but the shape uses + // y-increases-up, so CodepointBitmapBox and CodepointBox are inverted.) -STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); -// same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel -// shift for the character + STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); + // same as stbtt_GetCodepointBitmapBox, but you can specify a subpixel + // shift for the character -// the following functions are equivalent to the above functions, but operate -// on glyph indices instead of Unicode codepoints (for efficiency) -STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff); -STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff); -STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph); -STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph); -STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); -STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); + // the following functions are equivalent to the above functions, but operate + // on glyph indices instead of Unicode codepoints (for efficiency) + STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff); + STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff); + STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph); + STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph); + STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1); + STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1); + // @TODO: don't expose this structure + typedef struct + { + int w, h, stride; + unsigned char *pixels; + } stbtt__bitmap; -// @TODO: don't expose this structure -typedef struct -{ - int w,h,stride; - unsigned char *pixels; -} stbtt__bitmap; + STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata); -STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata); + ////////////////////////////////////////////////////////////////////////////// + // + // Finding the right font... + // + // You should really just solve this offline, keep your own tables + // of what font is what, and don't try to get it out of the .ttf file. + // That's because getting it out of the .ttf file is really hard, because + // the names in the file can appear in many possible encodings, in many + // possible languages, and e.g. if you need a case-insensitive comparison, + // the details of that depend on the encoding & language in a complex way + // (actually underspecified in truetype, but also gigantic). + // + // But you can use the provided functions in two possible ways: + // stbtt_FindMatchingFont() will use *case-sensitive* comparisons on + // unicode-encoded names to try to find the font you want; + // you can run this before calling stbtt_InitFont() + // + // stbtt_GetFontNameString() lets you get any of the various strings + // from the file yourself and do your own comparisons on them. + // You have to have called stbtt_InitFont() first. -////////////////////////////////////////////////////////////////////////////// -// -// Finding the right font... -// -// You should really just solve this offline, keep your own tables -// of what font is what, and don't try to get it out of the .ttf file. -// That's because getting it out of the .ttf file is really hard, because -// the names in the file can appear in many possible encodings, in many -// possible languages, and e.g. if you need a case-insensitive comparison, -// the details of that depend on the encoding & language in a complex way -// (actually underspecified in truetype, but also gigantic). -// -// But you can use the provided functions in two possible ways: -// stbtt_FindMatchingFont() will use *case-sensitive* comparisons on -// unicode-encoded names to try to find the font you want; -// you can run this before calling stbtt_InitFont() -// -// stbtt_GetFontNameString() lets you get any of the various strings -// from the file yourself and do your own comparisons on them. -// You have to have called stbtt_InitFont() first. - - -STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags); + STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *fontdata, const char *name, int flags); // returns the offset (not index) of the font that matches, or -1 if none // if you use STBTT_MACSTYLE_DONTCARE, use a font name like "Arial Bold". // if you use any other flag, use a font name like "Arial"; this checks // the 'macStyle' header field; i don't know if fonts set this consistently -#define STBTT_MACSTYLE_DONTCARE 0 -#define STBTT_MACSTYLE_BOLD 1 -#define STBTT_MACSTYLE_ITALIC 2 -#define STBTT_MACSTYLE_UNDERSCORE 4 -#define STBTT_MACSTYLE_NONE 8 // <= not same as 0, this makes us check the bitfield is 0 +#define STBTT_MACSTYLE_DONTCARE 0 +#define STBTT_MACSTYLE_BOLD 1 +#define STBTT_MACSTYLE_ITALIC 2 +#define STBTT_MACSTYLE_UNDERSCORE 4 +#define STBTT_MACSTYLE_NONE 8 // <= not same as 0, this makes us check the bitfield is 0 -STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2); -// returns 1/0 whether the first string interpreted as utf8 is identical to -// the second string interpreted as big-endian utf16... useful for strings from next func + STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2); + // returns 1/0 whether the first string interpreted as utf8 is identical to + // the second string interpreted as big-endian utf16... useful for strings from next func -STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID); -// returns the string (which may be big-endian double byte, e.g. for unicode) -// and puts the length in bytes in *length. -// -// some of the values for the IDs are below; for more see the truetype spec: -// http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html -// http://www.microsoft.com/typography/otspec/name.htm + STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID); + // returns the string (which may be big-endian double byte, e.g. for unicode) + // and puts the length in bytes in *length. + // + // some of the values for the IDs are below; for more see the truetype spec: + // http://developer.apple.com/textfonts/TTRefMan/RM06/Chap6name.html + // http://www.microsoft.com/typography/otspec/name.htm -enum { // platformID - STBTT_PLATFORM_ID_UNICODE =0, - STBTT_PLATFORM_ID_MAC =1, - STBTT_PLATFORM_ID_ISO =2, - STBTT_PLATFORM_ID_MICROSOFT =3 -}; + enum + { // platformID + STBTT_PLATFORM_ID_UNICODE = 0, + STBTT_PLATFORM_ID_MAC = 1, + STBTT_PLATFORM_ID_ISO = 2, + STBTT_PLATFORM_ID_MICROSOFT = 3 + }; -enum { // encodingID for STBTT_PLATFORM_ID_UNICODE - STBTT_UNICODE_EID_UNICODE_1_0 =0, - STBTT_UNICODE_EID_UNICODE_1_1 =1, - STBTT_UNICODE_EID_ISO_10646 =2, - STBTT_UNICODE_EID_UNICODE_2_0_BMP=3, - STBTT_UNICODE_EID_UNICODE_2_0_FULL=4 -}; + enum + { // encodingID for STBTT_PLATFORM_ID_UNICODE + STBTT_UNICODE_EID_UNICODE_1_0 = 0, + STBTT_UNICODE_EID_UNICODE_1_1 = 1, + STBTT_UNICODE_EID_ISO_10646 = 2, + STBTT_UNICODE_EID_UNICODE_2_0_BMP = 3, + STBTT_UNICODE_EID_UNICODE_2_0_FULL = 4 + }; -enum { // encodingID for STBTT_PLATFORM_ID_MICROSOFT - STBTT_MS_EID_SYMBOL =0, - STBTT_MS_EID_UNICODE_BMP =1, - STBTT_MS_EID_SHIFTJIS =2, - STBTT_MS_EID_UNICODE_FULL =10 -}; + enum + { // encodingID for STBTT_PLATFORM_ID_MICROSOFT + STBTT_MS_EID_SYMBOL = 0, + STBTT_MS_EID_UNICODE_BMP = 1, + STBTT_MS_EID_SHIFTJIS = 2, + STBTT_MS_EID_UNICODE_FULL = 10 + }; -enum { // encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes - STBTT_MAC_EID_ROMAN =0, STBTT_MAC_EID_ARABIC =4, - STBTT_MAC_EID_JAPANESE =1, STBTT_MAC_EID_HEBREW =5, - STBTT_MAC_EID_CHINESE_TRAD =2, STBTT_MAC_EID_GREEK =6, - STBTT_MAC_EID_KOREAN =3, STBTT_MAC_EID_RUSSIAN =7 -}; + enum + { // encodingID for STBTT_PLATFORM_ID_MAC; same as Script Manager codes + STBTT_MAC_EID_ROMAN = 0, + STBTT_MAC_EID_ARABIC = 4, + STBTT_MAC_EID_JAPANESE = 1, + STBTT_MAC_EID_HEBREW = 5, + STBTT_MAC_EID_CHINESE_TRAD = 2, + STBTT_MAC_EID_GREEK = 6, + STBTT_MAC_EID_KOREAN = 3, + STBTT_MAC_EID_RUSSIAN = 7 + }; -enum { // languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID... - // problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs - STBTT_MS_LANG_ENGLISH =0x0409, STBTT_MS_LANG_ITALIAN =0x0410, - STBTT_MS_LANG_CHINESE =0x0804, STBTT_MS_LANG_JAPANESE =0x0411, - STBTT_MS_LANG_DUTCH =0x0413, STBTT_MS_LANG_KOREAN =0x0412, - STBTT_MS_LANG_FRENCH =0x040c, STBTT_MS_LANG_RUSSIAN =0x0419, - STBTT_MS_LANG_GERMAN =0x0407, STBTT_MS_LANG_SPANISH =0x0409, - STBTT_MS_LANG_HEBREW =0x040d, STBTT_MS_LANG_SWEDISH =0x041D -}; + enum + { // languageID for STBTT_PLATFORM_ID_MICROSOFT; same as LCID... + // problematic because there are e.g. 16 english LCIDs and 16 arabic LCIDs + STBTT_MS_LANG_ENGLISH = 0x0409, + STBTT_MS_LANG_ITALIAN = 0x0410, + STBTT_MS_LANG_CHINESE = 0x0804, + STBTT_MS_LANG_JAPANESE = 0x0411, + STBTT_MS_LANG_DUTCH = 0x0413, + STBTT_MS_LANG_KOREAN = 0x0412, + STBTT_MS_LANG_FRENCH = 0x040c, + STBTT_MS_LANG_RUSSIAN = 0x0419, + STBTT_MS_LANG_GERMAN = 0x0407, + STBTT_MS_LANG_SPANISH = 0x0409, + STBTT_MS_LANG_HEBREW = 0x040d, + STBTT_MS_LANG_SWEDISH = 0x041D + }; -enum { // languageID for STBTT_PLATFORM_ID_MAC - STBTT_MAC_LANG_ENGLISH =0 , STBTT_MAC_LANG_JAPANESE =11, - STBTT_MAC_LANG_ARABIC =12, STBTT_MAC_LANG_KOREAN =23, - STBTT_MAC_LANG_DUTCH =4 , STBTT_MAC_LANG_RUSSIAN =32, - STBTT_MAC_LANG_FRENCH =1 , STBTT_MAC_LANG_SPANISH =6 , - STBTT_MAC_LANG_GERMAN =2 , STBTT_MAC_LANG_SWEDISH =5 , - STBTT_MAC_LANG_HEBREW =10, STBTT_MAC_LANG_CHINESE_SIMPLIFIED =33, - STBTT_MAC_LANG_ITALIAN =3 , STBTT_MAC_LANG_CHINESE_TRAD =19 -}; + enum + { // languageID for STBTT_PLATFORM_ID_MAC + STBTT_MAC_LANG_ENGLISH = 0, + STBTT_MAC_LANG_JAPANESE = 11, + STBTT_MAC_LANG_ARABIC = 12, + STBTT_MAC_LANG_KOREAN = 23, + STBTT_MAC_LANG_DUTCH = 4, + STBTT_MAC_LANG_RUSSIAN = 32, + STBTT_MAC_LANG_FRENCH = 1, + STBTT_MAC_LANG_SPANISH = 6, + STBTT_MAC_LANG_GERMAN = 2, + STBTT_MAC_LANG_SWEDISH = 5, + STBTT_MAC_LANG_HEBREW = 10, + STBTT_MAC_LANG_CHINESE_SIMPLIFIED = 33, + STBTT_MAC_LANG_ITALIAN = 3, + STBTT_MAC_LANG_CHINESE_TRAD = 19 + }; #ifdef __cplusplus } #endif -#endif // __STB_INCLUDE_STB_TRUETYPE_H__ +#endif // __STB_INCLUDE_STB_TRUETYPE_H__ /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// @@ -911,10 +927,10 @@ enum { // languageID for STBTT_PLATFORM_ID_MAC #ifdef STB_TRUETYPE_IMPLEMENTATION #ifndef STBTT_MAX_OVERSAMPLE -#define STBTT_MAX_OVERSAMPLE 8 +#define STBTT_MAX_OVERSAMPLE 8 #endif -typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE-1)) == 0 ? 1 : -1]; +typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERSAMPLE - 1)) == 0 ? 1 : -1]; #ifndef STBTT_RASTERIZER_VERSION #define STBTT_RASTERIZER_VERSION 2 @@ -928,606 +944,700 @@ typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERS // on platforms that don't allow misaligned reads, if we want to allow // truetype fonts that aren't padded to alignment, define ALLOW_UNALIGNED_TRUETYPE -#define ttBYTE(p) (* (stbtt_uint8 *) (p)) -#define ttCHAR(p) (* (stbtt_int8 *) (p)) -#define ttFixed(p) ttLONG(p) +#define ttBYTE(p) (*(stbtt_uint8 *)(p)) +#define ttCHAR(p) (*(stbtt_int8 *)(p)) +#define ttFixed(p) ttLONG(p) #if defined(STB_TRUETYPE_BIGENDIAN) && !defined(ALLOW_UNALIGNED_TRUETYPE) - #define ttUSHORT(p) (* (stbtt_uint16 *) (p)) - #define ttSHORT(p) (* (stbtt_int16 *) (p)) - #define ttULONG(p) (* (stbtt_uint32 *) (p)) - #define ttLONG(p) (* (stbtt_int32 *) (p)) +#define ttUSHORT(p) (*(stbtt_uint16 *)(p)) +#define ttSHORT(p) (*(stbtt_int16 *)(p)) +#define ttULONG(p) (*(stbtt_uint32 *)(p)) +#define ttLONG(p) (*(stbtt_int32 *)(p)) #else - static stbtt_uint16 ttUSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; } - static stbtt_int16 ttSHORT(const stbtt_uint8 *p) { return p[0]*256 + p[1]; } - static stbtt_uint32 ttULONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } - static stbtt_int32 ttLONG(const stbtt_uint8 *p) { return (p[0]<<24) + (p[1]<<16) + (p[2]<<8) + p[3]; } +static stbtt_uint16 ttUSHORT(const stbtt_uint8 *p) +{ + return p[0] * 256 + p[1]; +} +static stbtt_int16 ttSHORT(const stbtt_uint8 *p) { return p[0] * 256 + p[1]; } +static stbtt_uint32 ttULONG(const stbtt_uint8 *p) { return (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3]; } +static stbtt_int32 ttLONG(const stbtt_uint8 *p) { return (p[0] << 24) + (p[1] << 16) + (p[2] << 8) + p[3]; } #endif -#define stbtt_tag4(p,c0,c1,c2,c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3)) -#define stbtt_tag(p,str) stbtt_tag4(p,str[0],str[1],str[2],str[3]) +#define stbtt_tag4(p, c0, c1, c2, c3) ((p)[0] == (c0) && (p)[1] == (c1) && (p)[2] == (c2) && (p)[3] == (c3)) +#define stbtt_tag(p, str) stbtt_tag4(p, str[0], str[1], str[2], str[3]) static int stbtt__isfont(const stbtt_uint8 *font) { - // check the version number - if (stbtt_tag4(font, '1',0,0,0)) return 1; // TrueType 1 - if (stbtt_tag(font, "typ1")) return 1; // TrueType with type 1 font -- we don't support this! - if (stbtt_tag(font, "OTTO")) return 1; // OpenType with CFF - if (stbtt_tag4(font, 0,1,0,0)) return 1; // OpenType 1.0 - return 0; + // check the version number + if (stbtt_tag4(font, '1', 0, 0, 0)) return 1; // TrueType 1 + if (stbtt_tag(font, "typ1")) return 1; // TrueType with type 1 font -- we don't support this! + if (stbtt_tag(font, "OTTO")) return 1; // OpenType with CFF + if (stbtt_tag4(font, 0, 1, 0, 0)) return 1; // OpenType 1.0 + return 0; } // @OPTIMIZE: binary search static stbtt_uint32 stbtt__find_table(stbtt_uint8 *data, stbtt_uint32 fontstart, const char *tag) { - stbtt_int32 num_tables = ttUSHORT(data+fontstart+4); - stbtt_uint32 tabledir = fontstart + 12; - stbtt_int32 i; - for (i=0; i < num_tables; ++i) { - stbtt_uint32 loc = tabledir + 16*i; - if (stbtt_tag(data+loc+0, tag)) - return ttULONG(data+loc+8); - } - return 0; + stbtt_int32 num_tables = ttUSHORT(data + fontstart + 4); + stbtt_uint32 tabledir = fontstart + 12; + stbtt_int32 i; + for (i = 0; i < num_tables; ++i) + { + stbtt_uint32 loc = tabledir + 16 * i; + if (stbtt_tag(data + loc + 0, tag)) + return ttULONG(data + loc + 8); + } + return 0; } STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *font_collection, int index) { - // if it's just a font, there's only one valid index - if (stbtt__isfont(font_collection)) - return index == 0 ? 0 : -1; + // if it's just a font, there's only one valid index + if (stbtt__isfont(font_collection)) + return index == 0 ? 0 : -1; - // check if it's a TTC - if (stbtt_tag(font_collection, "ttcf")) { - // version 1? - if (ttULONG(font_collection+4) == 0x00010000 || ttULONG(font_collection+4) == 0x00020000) { - stbtt_int32 n = ttLONG(font_collection+8); - if (index >= n) - return -1; - return ttULONG(font_collection+12+index*14); - } - } - return -1; + // check if it's a TTC + if (stbtt_tag(font_collection, "ttcf")) + { + // version 1? + if (ttULONG(font_collection + 4) == 0x00010000 || ttULONG(font_collection + 4) == 0x00020000) + { + stbtt_int32 n = ttLONG(font_collection + 8); + if (index >= n) + return -1; + return ttULONG(font_collection + 12 + index * 14); + } + } + return -1; } STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data2, int fontstart) { - stbtt_uint8 *data = (stbtt_uint8 *) data2; - stbtt_uint32 cmap, t; - stbtt_int32 i,numTables; + stbtt_uint8 *data = (stbtt_uint8 *)data2; + stbtt_uint32 cmap, t; + stbtt_int32 i, numTables; - info->data = data; - info->fontstart = fontstart; + info->data = data; + info->fontstart = fontstart; - cmap = stbtt__find_table(data, fontstart, "cmap"); // required - info->loca = stbtt__find_table(data, fontstart, "loca"); // required - info->head = stbtt__find_table(data, fontstart, "head"); // required - info->glyf = stbtt__find_table(data, fontstart, "glyf"); // required - info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required - info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required - info->kern = stbtt__find_table(data, fontstart, "kern"); // not required - if (!cmap || !info->loca || !info->head || !info->glyf || !info->hhea || !info->hmtx) - return 0; + cmap = stbtt__find_table(data, fontstart, "cmap"); // required + info->loca = stbtt__find_table(data, fontstart, "loca"); // required + info->head = stbtt__find_table(data, fontstart, "head"); // required + info->glyf = stbtt__find_table(data, fontstart, "glyf"); // required + info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required + info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required + info->kern = stbtt__find_table(data, fontstart, "kern"); // not required + if (!cmap || !info->loca || !info->head || !info->glyf || !info->hhea || !info->hmtx) + return 0; - t = stbtt__find_table(data, fontstart, "maxp"); - if (t) - info->numGlyphs = ttUSHORT(data+t+4); - else - info->numGlyphs = 0xffff; + t = stbtt__find_table(data, fontstart, "maxp"); + if (t) + info->numGlyphs = ttUSHORT(data + t + 4); + else + info->numGlyphs = 0xffff; - // find a cmap encoding table we understand *now* to avoid searching - // later. (todo: could make this installable) - // the same regardless of glyph. - numTables = ttUSHORT(data + cmap + 2); - info->index_map = 0; - for (i=0; i < numTables; ++i) { - stbtt_uint32 encoding_record = cmap + 4 + 8 * i; - // find an encoding we understand: - switch(ttUSHORT(data+encoding_record)) { - case STBTT_PLATFORM_ID_MICROSOFT: - switch (ttUSHORT(data+encoding_record+2)) { - case STBTT_MS_EID_UNICODE_BMP: - case STBTT_MS_EID_UNICODE_FULL: - // MS/Unicode - info->index_map = cmap + ttULONG(data+encoding_record+4); - break; - } - break; - case STBTT_PLATFORM_ID_UNICODE: - // Mac/iOS has these - // all the encodingIDs are unicode, so we don't bother to check it - info->index_map = cmap + ttULONG(data+encoding_record+4); - break; - } - } - if (info->index_map == 0) - return 0; + // find a cmap encoding table we understand *now* to avoid searching + // later. (todo: could make this installable) + // the same regardless of glyph. + numTables = ttUSHORT(data + cmap + 2); + info->index_map = 0; + for (i = 0; i < numTables; ++i) + { + stbtt_uint32 encoding_record = cmap + 4 + 8 * i; + // find an encoding we understand: + switch (ttUSHORT(data + encoding_record)) + { + case STBTT_PLATFORM_ID_MICROSOFT: + switch (ttUSHORT(data + encoding_record + 2)) + { + case STBTT_MS_EID_UNICODE_BMP: + case STBTT_MS_EID_UNICODE_FULL: + // MS/Unicode + info->index_map = cmap + ttULONG(data + encoding_record + 4); + break; + } + break; + case STBTT_PLATFORM_ID_UNICODE: + // Mac/iOS has these + // all the encodingIDs are unicode, so we don't bother to check it + info->index_map = cmap + ttULONG(data + encoding_record + 4); + break; + } + } + if (info->index_map == 0) + return 0; - info->indexToLocFormat = ttUSHORT(data+info->head + 50); - return 1; + info->indexToLocFormat = ttUSHORT(data + info->head + 50); + return 1; } STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codepoint) { - stbtt_uint8 *data = info->data; - stbtt_uint32 index_map = info->index_map; + stbtt_uint8 *data = info->data; + stbtt_uint32 index_map = info->index_map; - stbtt_uint16 format = ttUSHORT(data + index_map + 0); - if (format == 0) { // apple byte encoding - stbtt_int32 bytes = ttUSHORT(data + index_map + 2); - if (unicode_codepoint < bytes-6) - return ttBYTE(data + index_map + 6 + unicode_codepoint); - return 0; - } else if (format == 6) { - stbtt_uint32 first = ttUSHORT(data + index_map + 6); - stbtt_uint32 count = ttUSHORT(data + index_map + 8); - if ((stbtt_uint32) unicode_codepoint >= first && (stbtt_uint32) unicode_codepoint < first+count) - return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first)*2); - return 0; - } else if (format == 2) { - STBTT_assert(0); // @TODO: high-byte mapping for japanese/chinese/korean - return 0; - } else if (format == 4) { // standard mapping for windows fonts: binary search collection of ranges - stbtt_uint16 segcount = ttUSHORT(data+index_map+6) >> 1; - stbtt_uint16 searchRange = ttUSHORT(data+index_map+8) >> 1; - stbtt_uint16 entrySelector = ttUSHORT(data+index_map+10); - stbtt_uint16 rangeShift = ttUSHORT(data+index_map+12) >> 1; + stbtt_uint16 format = ttUSHORT(data + index_map + 0); + if (format == 0) + { // apple byte encoding + stbtt_int32 bytes = ttUSHORT(data + index_map + 2); + if (unicode_codepoint < bytes - 6) + return ttBYTE(data + index_map + 6 + unicode_codepoint); + return 0; + } + else if (format == 6) + { + stbtt_uint32 first = ttUSHORT(data + index_map + 6); + stbtt_uint32 count = ttUSHORT(data + index_map + 8); + if ((stbtt_uint32)unicode_codepoint >= first && (stbtt_uint32)unicode_codepoint < first + count) + return ttUSHORT(data + index_map + 10 + (unicode_codepoint - first) * 2); + return 0; + } + else if (format == 2) + { + STBTT_assert(0); // @TODO: high-byte mapping for japanese/chinese/korean + return 0; + } + else if (format == 4) + { // standard mapping for windows fonts: binary search collection of ranges + stbtt_uint16 segcount = ttUSHORT(data + index_map + 6) >> 1; + stbtt_uint16 searchRange = ttUSHORT(data + index_map + 8) >> 1; + stbtt_uint16 entrySelector = ttUSHORT(data + index_map + 10); + stbtt_uint16 rangeShift = ttUSHORT(data + index_map + 12) >> 1; - // do a binary search of the segments - stbtt_uint32 endCount = index_map + 14; - stbtt_uint32 search = endCount; + // do a binary search of the segments + stbtt_uint32 endCount = index_map + 14; + stbtt_uint32 search = endCount; - if (unicode_codepoint > 0xffff) - return 0; + if (unicode_codepoint > 0xffff) + return 0; - // they lie from endCount .. endCount + segCount - // but searchRange is the nearest power of two, so... - if (unicode_codepoint >= ttUSHORT(data + search + rangeShift*2)) - search += rangeShift*2; + // they lie from endCount .. endCount + segCount + // but searchRange is the nearest power of two, so... + if (unicode_codepoint >= ttUSHORT(data + search + rangeShift * 2)) + search += rangeShift * 2; - // now decrement to bias correctly to find smallest - search -= 2; - while (entrySelector) { - stbtt_uint16 end; - searchRange >>= 1; - end = ttUSHORT(data + search + searchRange*2); - if (unicode_codepoint > end) - search += searchRange*2; - --entrySelector; - } - search += 2; + // now decrement to bias correctly to find smallest + search -= 2; + while (entrySelector) + { + stbtt_uint16 end; + searchRange >>= 1; + end = ttUSHORT(data + search + searchRange * 2); + if (unicode_codepoint > end) + search += searchRange * 2; + --entrySelector; + } + search += 2; - { - stbtt_uint16 offset, start; - stbtt_uint16 item = (stbtt_uint16) ((search - endCount) >> 1); + { + stbtt_uint16 offset, start; + stbtt_uint16 item = (stbtt_uint16)((search - endCount) >> 1); - STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2*item)); - start = ttUSHORT(data + index_map + 14 + segcount*2 + 2 + 2*item); - if (unicode_codepoint < start) - return 0; + STBTT_assert(unicode_codepoint <= ttUSHORT(data + endCount + 2 * item)); + start = ttUSHORT(data + index_map + 14 + segcount * 2 + 2 + 2 * item); + if (unicode_codepoint < start) + return 0; - offset = ttUSHORT(data + index_map + 14 + segcount*6 + 2 + 2*item); - if (offset == 0) - return (stbtt_uint16) (unicode_codepoint + ttSHORT(data + index_map + 14 + segcount*4 + 2 + 2*item)); + offset = ttUSHORT(data + index_map + 14 + segcount * 6 + 2 + 2 * item); + if (offset == 0) + return (stbtt_uint16)(unicode_codepoint + ttSHORT(data + index_map + 14 + segcount * 4 + 2 + 2 * item)); - return ttUSHORT(data + offset + (unicode_codepoint-start)*2 + index_map + 14 + segcount*6 + 2 + 2*item); - } - } else if (format == 12 || format == 13) { - stbtt_uint32 ngroups = ttULONG(data+index_map+12); - stbtt_int32 low,high; - low = 0; high = (stbtt_int32)ngroups; - // Binary search the right group. - while (low < high) { - stbtt_int32 mid = low + ((high-low) >> 1); // rounds down, so low <= mid < high - stbtt_uint32 start_char = ttULONG(data+index_map+16+mid*12); - stbtt_uint32 end_char = ttULONG(data+index_map+16+mid*12+4); - if ((stbtt_uint32) unicode_codepoint < start_char) - high = mid; - else if ((stbtt_uint32) unicode_codepoint > end_char) - low = mid+1; - else { - stbtt_uint32 start_glyph = ttULONG(data+index_map+16+mid*12+8); - if (format == 12) - return start_glyph + unicode_codepoint-start_char; - else // format == 13 - return start_glyph; - } - } - return 0; // not found - } - // @TODO - STBTT_assert(0); - return 0; + return ttUSHORT(data + offset + (unicode_codepoint - start) * 2 + index_map + 14 + segcount * 6 + 2 + 2 * item); + } + } + else if (format == 12 || format == 13) + { + stbtt_uint32 ngroups = ttULONG(data + index_map + 12); + stbtt_int32 low, high; + low = 0; + high = (stbtt_int32)ngroups; + // Binary search the right group. + while (low < high) + { + stbtt_int32 mid = low + ((high - low) >> 1); // rounds down, so low <= mid < high + stbtt_uint32 start_char = ttULONG(data + index_map + 16 + mid * 12); + stbtt_uint32 end_char = ttULONG(data + index_map + 16 + mid * 12 + 4); + if ((stbtt_uint32)unicode_codepoint < start_char) + high = mid; + else if ((stbtt_uint32)unicode_codepoint > end_char) + low = mid + 1; + else + { + stbtt_uint32 start_glyph = ttULONG(data + index_map + 16 + mid * 12 + 8); + if (format == 12) + return start_glyph + unicode_codepoint - start_char; + else // format == 13 + return start_glyph; + } + } + return 0; // not found + } + // @TODO + STBTT_assert(0); + return 0; } STBTT_DEF int stbtt_GetCodepointShape(const stbtt_fontinfo *info, int unicode_codepoint, stbtt_vertex **vertices) { - return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices); + return stbtt_GetGlyphShape(info, stbtt_FindGlyphIndex(info, unicode_codepoint), vertices); } static void stbtt_setvertex(stbtt_vertex *v, stbtt_uint8 type, stbtt_int32 x, stbtt_int32 y, stbtt_int32 cx, stbtt_int32 cy) { - v->type = type; - v->x = (stbtt_int16) x; - v->y = (stbtt_int16) y; - v->cx = (stbtt_int16) cx; - v->cy = (stbtt_int16) cy; + v->type = type; + v->x = (stbtt_int16)x; + v->y = (stbtt_int16)y; + v->cx = (stbtt_int16)cx; + v->cy = (stbtt_int16)cy; } static int stbtt__GetGlyfOffset(const stbtt_fontinfo *info, int glyph_index) { - int g1,g2; + int g1, g2; - if (glyph_index >= info->numGlyphs) return -1; // glyph index out of range - if (info->indexToLocFormat >= 2) return -1; // unknown index->glyph map format + if (glyph_index >= info->numGlyphs) return -1; // glyph index out of range + if (info->indexToLocFormat >= 2) return -1; // unknown index->glyph map format - if (info->indexToLocFormat == 0) { - g1 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2) * 2; - g2 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2; - } else { - g1 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4); - g2 = info->glyf + ttULONG (info->data + info->loca + glyph_index * 4 + 4); - } + if (info->indexToLocFormat == 0) + { + g1 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2) * 2; + g2 = info->glyf + ttUSHORT(info->data + info->loca + glyph_index * 2 + 2) * 2; + } + else + { + g1 = info->glyf + ttULONG(info->data + info->loca + glyph_index * 4); + g2 = info->glyf + ttULONG(info->data + info->loca + glyph_index * 4 + 4); + } - return g1==g2 ? -1 : g1; // if length is 0, return -1 + return g1 == g2 ? -1 : g1; // if length is 0, return -1 } STBTT_DEF int stbtt_GetGlyphBox(const stbtt_fontinfo *info, int glyph_index, int *x0, int *y0, int *x1, int *y1) { - int g = stbtt__GetGlyfOffset(info, glyph_index); - if (g < 0) return 0; + int g = stbtt__GetGlyfOffset(info, glyph_index); + if (g < 0) return 0; - if (x0) *x0 = ttSHORT(info->data + g + 2); - if (y0) *y0 = ttSHORT(info->data + g + 4); - if (x1) *x1 = ttSHORT(info->data + g + 6); - if (y1) *y1 = ttSHORT(info->data + g + 8); - return 1; + if (x0) *x0 = ttSHORT(info->data + g + 2); + if (y0) *y0 = ttSHORT(info->data + g + 4); + if (x1) *x1 = ttSHORT(info->data + g + 6); + if (y1) *y1 = ttSHORT(info->data + g + 8); + return 1; } STBTT_DEF int stbtt_GetCodepointBox(const stbtt_fontinfo *info, int codepoint, int *x0, int *y0, int *x1, int *y1) { - return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info,codepoint), x0,y0,x1,y1); + return stbtt_GetGlyphBox(info, stbtt_FindGlyphIndex(info, codepoint), x0, y0, x1, y1); } STBTT_DEF int stbtt_IsGlyphEmpty(const stbtt_fontinfo *info, int glyph_index) { - stbtt_int16 numberOfContours; - int g = stbtt__GetGlyfOffset(info, glyph_index); - if (g < 0) return 1; - numberOfContours = ttSHORT(info->data + g); - return numberOfContours == 0; + stbtt_int16 numberOfContours; + int g = stbtt__GetGlyfOffset(info, glyph_index); + if (g < 0) return 1; + numberOfContours = ttSHORT(info->data + g); + return numberOfContours == 0; } static int stbtt__close_shape(stbtt_vertex *vertices, int num_vertices, int was_off, int start_off, - stbtt_int32 sx, stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy) + stbtt_int32 sx, stbtt_int32 sy, stbtt_int32 scx, stbtt_int32 scy, stbtt_int32 cx, stbtt_int32 cy) { - if (start_off) { - if (was_off) - stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+scx)>>1, (cy+scy)>>1, cx,cy); - stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx,sy,scx,scy); - } else { - if (was_off) - stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve,sx,sy,cx,cy); - else - stbtt_setvertex(&vertices[num_vertices++], STBTT_vline,sx,sy,0,0); - } - return num_vertices; + if (start_off) + { + if (was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx + scx) >> 1, (cy + scy) >> 1, cx, cy); + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx, sy, scx, scy); + } + else + { + if (was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, sx, sy, cx, cy); + else + stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, sx, sy, 0, 0); + } + return num_vertices; } STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, stbtt_vertex **pvertices) { - stbtt_int16 numberOfContours; - stbtt_uint8 *endPtsOfContours; - stbtt_uint8 *data = info->data; - stbtt_vertex *vertices=0; - int num_vertices=0; - int g = stbtt__GetGlyfOffset(info, glyph_index); + stbtt_int16 numberOfContours; + stbtt_uint8 *endPtsOfContours; + stbtt_uint8 *data = info->data; + stbtt_vertex *vertices = 0; + int num_vertices = 0; + int g = stbtt__GetGlyfOffset(info, glyph_index); - *pvertices = NULL; + *pvertices = NULL; - if (g < 0) return 0; + if (g < 0) return 0; - numberOfContours = ttSHORT(data + g); + numberOfContours = ttSHORT(data + g); - if (numberOfContours > 0) { - stbtt_uint8 flags=0,flagcount; - stbtt_int32 ins, i,j=0,m,n, next_move, was_off=0, off, start_off=0; - stbtt_int32 x,y,cx,cy,sx,sy, scx,scy; - stbtt_uint8 *points; - endPtsOfContours = (data + g + 10); - ins = ttUSHORT(data + g + 10 + numberOfContours * 2); - points = data + g + 10 + numberOfContours * 2 + 2 + ins; + if (numberOfContours > 0) + { + stbtt_uint8 flags = 0, flagcount; + stbtt_int32 ins, i, j = 0, m, n, next_move, was_off = 0, off, start_off = 0; + stbtt_int32 x, y, cx, cy, sx, sy, scx, scy; + stbtt_uint8 *points; + endPtsOfContours = (data + g + 10); + ins = ttUSHORT(data + g + 10 + numberOfContours * 2); + points = data + g + 10 + numberOfContours * 2 + 2 + ins; - n = 1+ttUSHORT(endPtsOfContours + numberOfContours*2-2); + n = 1 + ttUSHORT(endPtsOfContours + numberOfContours * 2 - 2); - m = n + 2*numberOfContours; // a loose bound on how many vertices we might need - vertices = (stbtt_vertex *) STBTT_malloc(m * sizeof(vertices[0]), info->userdata); - if (vertices == 0) - return 0; + m = n + 2 * numberOfContours; // a loose bound on how many vertices we might need + vertices = (stbtt_vertex *)STBTT_malloc(m * sizeof(vertices[0]), info->userdata); + if (vertices == 0) + return 0; - next_move = 0; - flagcount=0; + next_move = 0; + flagcount = 0; - // in first pass, we load uninterpreted data into the allocated array - // above, shifted to the end of the array so we won't overwrite it when - // we create our final data starting from the front + // in first pass, we load uninterpreted data into the allocated array + // above, shifted to the end of the array so we won't overwrite it when + // we create our final data starting from the front - off = m - n; // starting offset for uninterpreted data, regardless of how m ends up being calculated + off = m - n; // starting offset for uninterpreted data, regardless of how m ends up being calculated - // first load flags + // first load flags - for (i=0; i < n; ++i) { - if (flagcount == 0) { - flags = *points++; - if (flags & 8) - flagcount = *points++; - } else - --flagcount; - vertices[off+i].type = flags; - } + for (i = 0; i < n; ++i) + { + if (flagcount == 0) + { + flags = *points++; + if (flags & 8) + flagcount = *points++; + } + else + --flagcount; + vertices[off + i].type = flags; + } - // now load x coordinates - x=0; - for (i=0; i < n; ++i) { - flags = vertices[off+i].type; - if (flags & 2) { - stbtt_int16 dx = *points++; - x += (flags & 16) ? dx : -dx; // ??? - } else { - if (!(flags & 16)) { - x = x + (stbtt_int16) (points[0]*256 + points[1]); - points += 2; - } - } - vertices[off+i].x = (stbtt_int16) x; - } + // now load x coordinates + x = 0; + for (i = 0; i < n; ++i) + { + flags = vertices[off + i].type; + if (flags & 2) + { + stbtt_int16 dx = *points++; + x += (flags & 16) ? dx : -dx; // ??? + } + else + { + if (!(flags & 16)) + { + x = x + (stbtt_int16)(points[0] * 256 + points[1]); + points += 2; + } + } + vertices[off + i].x = (stbtt_int16)x; + } - // now load y coordinates - y=0; - for (i=0; i < n; ++i) { - flags = vertices[off+i].type; - if (flags & 4) { - stbtt_int16 dy = *points++; - y += (flags & 32) ? dy : -dy; // ??? - } else { - if (!(flags & 32)) { - y = y + (stbtt_int16) (points[0]*256 + points[1]); - points += 2; - } - } - vertices[off+i].y = (stbtt_int16) y; - } + // now load y coordinates + y = 0; + for (i = 0; i < n; ++i) + { + flags = vertices[off + i].type; + if (flags & 4) + { + stbtt_int16 dy = *points++; + y += (flags & 32) ? dy : -dy; // ??? + } + else + { + if (!(flags & 32)) + { + y = y + (stbtt_int16)(points[0] * 256 + points[1]); + points += 2; + } + } + vertices[off + i].y = (stbtt_int16)y; + } - // now convert them to our format - num_vertices=0; - sx = sy = cx = cy = scx = scy = 0; - for (i=0; i < n; ++i) { - flags = vertices[off+i].type; - x = (stbtt_int16) vertices[off+i].x; - y = (stbtt_int16) vertices[off+i].y; + // now convert them to our format + num_vertices = 0; + sx = sy = cx = cy = scx = scy = 0; + for (i = 0; i < n; ++i) + { + flags = vertices[off + i].type; + x = (stbtt_int16)vertices[off + i].x; + y = (stbtt_int16)vertices[off + i].y; - if (next_move == i) { - if (i != 0) - num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); + if (next_move == i) + { + if (i != 0) + num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx, sy, scx, scy, cx, cy); - // now start the new one - start_off = !(flags & 1); - if (start_off) { - // if we start off with an off-curve point, then when we need to find a point on the curve - // where we can start, and we need to save some state for when we wraparound. - scx = x; - scy = y; - if (!(vertices[off+i+1].type & 1)) { - // next point is also a curve point, so interpolate an on-point curve - sx = (x + (stbtt_int32) vertices[off+i+1].x) >> 1; - sy = (y + (stbtt_int32) vertices[off+i+1].y) >> 1; - } else { - // otherwise just use the next point as our start point - sx = (stbtt_int32) vertices[off+i+1].x; - sy = (stbtt_int32) vertices[off+i+1].y; - ++i; // we're using point i+1 as the starting point, so skip it - } - } else { - sx = x; - sy = y; - } - stbtt_setvertex(&vertices[num_vertices++], STBTT_vmove,sx,sy,0,0); - was_off = 0; - next_move = 1 + ttUSHORT(endPtsOfContours+j*2); - ++j; - } else { - if (!(flags & 1)) { // if it's a curve - if (was_off) // two off-curve control points in a row means interpolate an on-curve midpoint - stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx+x)>>1, (cy+y)>>1, cx, cy); - cx = x; - cy = y; - was_off = 1; - } else { - if (was_off) - stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x,y, cx, cy); - else - stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, x,y,0,0); - was_off = 0; - } - } - } - num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx,sy,scx,scy,cx,cy); - } else if (numberOfContours == -1) { - // Compound shapes. - int more = 1; - stbtt_uint8 *comp = data + g + 10; - num_vertices = 0; - vertices = 0; - while (more) { - stbtt_uint16 flags, gidx; - int comp_num_verts = 0, i; - stbtt_vertex *comp_verts = 0, *tmp = 0; - float mtx[6] = {1,0,0,1,0,0}, m, n; - - flags = ttSHORT(comp); comp+=2; - gidx = ttSHORT(comp); comp+=2; + // now start the new one + start_off = !(flags & 1); + if (start_off) + { + // if we start off with an off-curve point, then when we need to find a point on the curve + // where we can start, and we need to save some state for when we wraparound. + scx = x; + scy = y; + if (!(vertices[off + i + 1].type & 1)) + { + // next point is also a curve point, so interpolate an on-point curve + sx = (x + (stbtt_int32)vertices[off + i + 1].x) >> 1; + sy = (y + (stbtt_int32)vertices[off + i + 1].y) >> 1; + } + else + { + // otherwise just use the next point as our start point + sx = (stbtt_int32)vertices[off + i + 1].x; + sy = (stbtt_int32)vertices[off + i + 1].y; + ++i; // we're using point i+1 as the starting point, so skip it + } + } + else + { + sx = x; + sy = y; + } + stbtt_setvertex(&vertices[num_vertices++], STBTT_vmove, sx, sy, 0, 0); + was_off = 0; + next_move = 1 + ttUSHORT(endPtsOfContours + j * 2); + ++j; + } + else + { + if (!(flags & 1)) + { // if it's a curve + if (was_off) // two off-curve control points in a row means interpolate an on-curve midpoint + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, (cx + x) >> 1, (cy + y) >> 1, cx, cy); + cx = x; + cy = y; + was_off = 1; + } + else + { + if (was_off) + stbtt_setvertex(&vertices[num_vertices++], STBTT_vcurve, x, y, cx, cy); + else + stbtt_setvertex(&vertices[num_vertices++], STBTT_vline, x, y, 0, 0); + was_off = 0; + } + } + } + num_vertices = stbtt__close_shape(vertices, num_vertices, was_off, start_off, sx, sy, scx, scy, cx, cy); + } + else if (numberOfContours == -1) + { + // Compound shapes. + int more = 1; + stbtt_uint8 *comp = data + g + 10; + num_vertices = 0; + vertices = 0; + while (more) + { + stbtt_uint16 flags, gidx; + int comp_num_verts = 0, i; + stbtt_vertex *comp_verts = 0, *tmp = 0; + float mtx[6] = {1, 0, 0, 1, 0, 0}, m, n; - if (flags & 2) { // XY values - if (flags & 1) { // shorts - mtx[4] = ttSHORT(comp); comp+=2; - mtx[5] = ttSHORT(comp); comp+=2; - } else { - mtx[4] = ttCHAR(comp); comp+=1; - mtx[5] = ttCHAR(comp); comp+=1; - } - } - else { - // @TODO handle matching point - STBTT_assert(0); - } - if (flags & (1<<3)) { // WE_HAVE_A_SCALE - mtx[0] = mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; - mtx[1] = mtx[2] = 0; - } else if (flags & (1<<6)) { // WE_HAVE_AN_X_AND_YSCALE - mtx[0] = ttSHORT(comp)/16384.0f; comp+=2; - mtx[1] = mtx[2] = 0; - mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; - } else if (flags & (1<<7)) { // WE_HAVE_A_TWO_BY_TWO - mtx[0] = ttSHORT(comp)/16384.0f; comp+=2; - mtx[1] = ttSHORT(comp)/16384.0f; comp+=2; - mtx[2] = ttSHORT(comp)/16384.0f; comp+=2; - mtx[3] = ttSHORT(comp)/16384.0f; comp+=2; - } - - // Find transformation scales. - m = (float) STBTT_sqrt(mtx[0]*mtx[0] + mtx[1]*mtx[1]); - n = (float) STBTT_sqrt(mtx[2]*mtx[2] + mtx[3]*mtx[3]); + flags = ttSHORT(comp); + comp += 2; + gidx = ttSHORT(comp); + comp += 2; - // Get indexed glyph. - comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts); - if (comp_num_verts > 0) { - // Transform vertices. - for (i = 0; i < comp_num_verts; ++i) { - stbtt_vertex* v = &comp_verts[i]; - stbtt_vertex_type x,y; - x=v->x; y=v->y; - v->x = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4])); - v->y = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5])); - x=v->cx; y=v->cy; - v->cx = (stbtt_vertex_type)(m * (mtx[0]*x + mtx[2]*y + mtx[4])); - v->cy = (stbtt_vertex_type)(n * (mtx[1]*x + mtx[3]*y + mtx[5])); - } - // Append vertices. - tmp = (stbtt_vertex*)STBTT_malloc((num_vertices+comp_num_verts)*sizeof(stbtt_vertex), info->userdata); - if (!tmp) { - if (vertices) STBTT_free(vertices, info->userdata); - if (comp_verts) STBTT_free(comp_verts, info->userdata); - return 0; - } - if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices*sizeof(stbtt_vertex)); - STBTT_memcpy(tmp+num_vertices, comp_verts, comp_num_verts*sizeof(stbtt_vertex)); - if (vertices) STBTT_free(vertices, info->userdata); - vertices = tmp; - STBTT_free(comp_verts, info->userdata); - num_vertices += comp_num_verts; - } - // More components ? - more = flags & (1<<5); - } - } else if (numberOfContours < 0) { - // @TODO other compound variations? - STBTT_assert(0); - } else { - // numberOfCounters == 0, do nothing - } + if (flags & 2) + { // XY values + if (flags & 1) + { // shorts + mtx[4] = ttSHORT(comp); + comp += 2; + mtx[5] = ttSHORT(comp); + comp += 2; + } + else + { + mtx[4] = ttCHAR(comp); + comp += 1; + mtx[5] = ttCHAR(comp); + comp += 1; + } + } + else + { + // @TODO handle matching point + STBTT_assert(0); + } + if (flags & (1 << 3)) + { // WE_HAVE_A_SCALE + mtx[0] = mtx[3] = ttSHORT(comp) / 16384.0f; + comp += 2; + mtx[1] = mtx[2] = 0; + } + else if (flags & (1 << 6)) + { // WE_HAVE_AN_X_AND_YSCALE + mtx[0] = ttSHORT(comp) / 16384.0f; + comp += 2; + mtx[1] = mtx[2] = 0; + mtx[3] = ttSHORT(comp) / 16384.0f; + comp += 2; + } + else if (flags & (1 << 7)) + { // WE_HAVE_A_TWO_BY_TWO + mtx[0] = ttSHORT(comp) / 16384.0f; + comp += 2; + mtx[1] = ttSHORT(comp) / 16384.0f; + comp += 2; + mtx[2] = ttSHORT(comp) / 16384.0f; + comp += 2; + mtx[3] = ttSHORT(comp) / 16384.0f; + comp += 2; + } - *pvertices = vertices; - return num_vertices; + // Find transformation scales. + m = (float)STBTT_sqrt(mtx[0] * mtx[0] + mtx[1] * mtx[1]); + n = (float)STBTT_sqrt(mtx[2] * mtx[2] + mtx[3] * mtx[3]); + + // Get indexed glyph. + comp_num_verts = stbtt_GetGlyphShape(info, gidx, &comp_verts); + if (comp_num_verts > 0) + { + // Transform vertices. + for (i = 0; i < comp_num_verts; ++i) + { + stbtt_vertex *v = &comp_verts[i]; + stbtt_vertex_type x, y; + x = v->x; + y = v->y; + v->x = (stbtt_vertex_type)(m * (mtx[0] * x + mtx[2] * y + mtx[4])); + v->y = (stbtt_vertex_type)(n * (mtx[1] * x + mtx[3] * y + mtx[5])); + x = v->cx; + y = v->cy; + v->cx = (stbtt_vertex_type)(m * (mtx[0] * x + mtx[2] * y + mtx[4])); + v->cy = (stbtt_vertex_type)(n * (mtx[1] * x + mtx[3] * y + mtx[5])); + } + // Append vertices. + tmp = (stbtt_vertex *)STBTT_malloc((num_vertices + comp_num_verts) * sizeof(stbtt_vertex), info->userdata); + if (!tmp) + { + if (vertices) STBTT_free(vertices, info->userdata); + if (comp_verts) STBTT_free(comp_verts, info->userdata); + return 0; + } + if (num_vertices > 0) STBTT_memcpy(tmp, vertices, num_vertices * sizeof(stbtt_vertex)); + STBTT_memcpy(tmp + num_vertices, comp_verts, comp_num_verts * sizeof(stbtt_vertex)); + if (vertices) STBTT_free(vertices, info->userdata); + vertices = tmp; + STBTT_free(comp_verts, info->userdata); + num_vertices += comp_num_verts; + } + // More components ? + more = flags & (1 << 5); + } + } + else if (numberOfContours < 0) + { + // @TODO other compound variations? + STBTT_assert(0); + } + else + { + // numberOfCounters == 0, do nothing + } + + *pvertices = vertices; + return num_vertices; } STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_index, int *advanceWidth, int *leftSideBearing) { - stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data+info->hhea + 34); - if (glyph_index < numOfLongHorMetrics) { - if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*glyph_index); - if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*glyph_index + 2); - } else { - if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4*(numOfLongHorMetrics-1)); - if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4*numOfLongHorMetrics + 2*(glyph_index - numOfLongHorMetrics)); - } + stbtt_uint16 numOfLongHorMetrics = ttUSHORT(info->data + info->hhea + 34); + if (glyph_index < numOfLongHorMetrics) + { + if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4 * glyph_index); + if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4 * glyph_index + 2); + } + else + { + if (advanceWidth) *advanceWidth = ttSHORT(info->data + info->hmtx + 4 * (numOfLongHorMetrics - 1)); + if (leftSideBearing) *leftSideBearing = ttSHORT(info->data + info->hmtx + 4 * numOfLongHorMetrics + 2 * (glyph_index - numOfLongHorMetrics)); + } } -STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) +STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2) { - stbtt_uint8 *data = info->data + info->kern; - stbtt_uint32 needle, straw; - int l, r, m; + stbtt_uint8 *data = info->data + info->kern; + stbtt_uint32 needle, straw; + int l, r, m; - // we only look at the first table. it must be 'horizontal' and format 0. - if (!info->kern) - return 0; - if (ttUSHORT(data+2) < 1) // number of tables, need at least 1 - return 0; - if (ttUSHORT(data+8) != 1) // horizontal flag must be set in format - return 0; + // we only look at the first table. it must be 'horizontal' and format 0. + if (!info->kern) + return 0; + if (ttUSHORT(data + 2) < 1) // number of tables, need at least 1 + return 0; + if (ttUSHORT(data + 8) != 1) // horizontal flag must be set in format + return 0; - l = 0; - r = ttUSHORT(data+10) - 1; - needle = glyph1 << 16 | glyph2; - while (l <= r) { - m = (l + r) >> 1; - straw = ttULONG(data+18+(m*6)); // note: unaligned read - if (needle < straw) - r = m - 1; - else if (needle > straw) - l = m + 1; - else - return ttSHORT(data+22+(m*6)); - } - return 0; + l = 0; + r = ttUSHORT(data + 10) - 1; + needle = glyph1 << 16 | glyph2; + while (l <= r) + { + m = (l + r) >> 1; + straw = ttULONG(data + 18 + (m * 6)); // note: unaligned read + if (needle < straw) + r = m - 1; + else if (needle > straw) + l = m + 1; + else + return ttSHORT(data + 22 + (m * 6)); + } + return 0; } -STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2) +STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2) { - if (!info->kern) // if no kerning table, don't waste time looking up both codepoint->glyphs - return 0; - return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2)); + if (!info->kern) // if no kerning table, don't waste time looking up both codepoint->glyphs + return 0; + return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info, ch1), stbtt_FindGlyphIndex(info, ch2)); } STBTT_DEF void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *info, int codepoint, int *advanceWidth, int *leftSideBearing) { - stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info,codepoint), advanceWidth, leftSideBearing); + stbtt_GetGlyphHMetrics(info, stbtt_FindGlyphIndex(info, codepoint), advanceWidth, leftSideBearing); } STBTT_DEF void stbtt_GetFontVMetrics(const stbtt_fontinfo *info, int *ascent, int *descent, int *lineGap) { - if (ascent ) *ascent = ttSHORT(info->data+info->hhea + 4); - if (descent) *descent = ttSHORT(info->data+info->hhea + 6); - if (lineGap) *lineGap = ttSHORT(info->data+info->hhea + 8); + if (ascent) *ascent = ttSHORT(info->data + info->hhea + 4); + if (descent) *descent = ttSHORT(info->data + info->hhea + 6); + if (lineGap) *lineGap = ttSHORT(info->data + info->hhea + 8); } STBTT_DEF void stbtt_GetFontBoundingBox(const stbtt_fontinfo *info, int *x0, int *y0, int *x1, int *y1) { - *x0 = ttSHORT(info->data + info->head + 36); - *y0 = ttSHORT(info->data + info->head + 38); - *x1 = ttSHORT(info->data + info->head + 40); - *y1 = ttSHORT(info->data + info->head + 42); + *x0 = ttSHORT(info->data + info->head + 36); + *y0 = ttSHORT(info->data + info->head + 38); + *x1 = ttSHORT(info->data + info->head + 40); + *y1 = ttSHORT(info->data + info->head + 42); } STBTT_DEF float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *info, float height) { - int fheight = ttSHORT(info->data + info->hhea + 4) - ttSHORT(info->data + info->hhea + 6); - return (float) height / fheight; + int fheight = ttSHORT(info->data + info->hhea + 4) - ttSHORT(info->data + info->hhea + 6); + return (float)height / fheight; } STBTT_DEF float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *info, float pixels) { - int unitsPerEm = ttUSHORT(info->data + info->head + 18); - return pixels / unitsPerEm; + int unitsPerEm = ttUSHORT(info->data + info->head + 18); + return pixels / unitsPerEm; } STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v) { - STBTT_free(v, info->userdata); + STBTT_free(v, info->userdata); } ////////////////////////////////////////////////////////////////////////////// @@ -1535,37 +1645,40 @@ STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v) // antialiasing software rasterizer // -STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) +STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) { - int x0,y0,x1,y1; - if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) { - // e.g. space character - if (ix0) *ix0 = 0; - if (iy0) *iy0 = 0; - if (ix1) *ix1 = 0; - if (iy1) *iy1 = 0; - } else { - // move to integral bboxes (treating pixels as little squares, what pixels get touched)? - if (ix0) *ix0 = STBTT_ifloor( x0 * scale_x + shift_x); - if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y); - if (ix1) *ix1 = STBTT_iceil ( x1 * scale_x + shift_x); - if (iy1) *iy1 = STBTT_iceil (-y0 * scale_y + shift_y); - } + int x0, y0, x1, y1; + if (!stbtt_GetGlyphBox(font, glyph, &x0, &y0, &x1, &y1)) + { + // e.g. space character + if (ix0) *ix0 = 0; + if (iy0) *iy0 = 0; + if (ix1) *ix1 = 0; + if (iy1) *iy1 = 0; + } + else + { + // move to integral bboxes (treating pixels as little squares, what pixels get touched)? + if (ix0) *ix0 = STBTT_ifloor(x0 * scale_x + shift_x); + if (iy0) *iy0 = STBTT_ifloor(-y1 * scale_y + shift_y); + if (ix1) *ix1 = STBTT_iceil(x1 * scale_x + shift_x); + if (iy1) *iy1 = STBTT_iceil(-y0 * scale_y + shift_y); + } } STBTT_DEF void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) { - stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y,0.0f,0.0f, ix0, iy0, ix1, iy1); + stbtt_GetGlyphBitmapBoxSubpixel(font, glyph, scale_x, scale_y, 0.0f, 0.0f, ix0, iy0, ix1, iy1); } STBTT_DEF void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1) { - stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font,codepoint), scale_x, scale_y,shift_x,shift_y, ix0,iy0,ix1,iy1); + stbtt_GetGlyphBitmapBoxSubpixel(font, stbtt_FindGlyphIndex(font, codepoint), scale_x, scale_y, shift_x, shift_y, ix0, iy0, ix1, iy1); } STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codepoint, float scale_x, float scale_y, int *ix0, int *iy0, int *ix1, int *iy1) { - stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y,0.0f,0.0f, ix0,iy0,ix1,iy1); + stbtt_GetCodepointBitmapBoxSubpixel(font, codepoint, scale_x, scale_y, 0.0f, 0.0f, ix0, iy0, ix1, iy1); } ////////////////////////////////////////////////////////////////////////////// @@ -1574,117 +1687,122 @@ STBTT_DEF void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *font, int codep typedef struct stbtt__hheap_chunk { - struct stbtt__hheap_chunk *next; + struct stbtt__hheap_chunk *next; } stbtt__hheap_chunk; typedef struct stbtt__hheap { - struct stbtt__hheap_chunk *head; - void *first_free; - int num_remaining_in_head_chunk; + struct stbtt__hheap_chunk *head; + void *first_free; + int num_remaining_in_head_chunk; } stbtt__hheap; static void *stbtt__hheap_alloc(stbtt__hheap *hh, size_t size, void *userdata) { - if (hh->first_free) { - void *p = hh->first_free; - hh->first_free = * (void **) p; - return p; - } else { - if (hh->num_remaining_in_head_chunk == 0) { - int count = (size < 32 ? 2000 : size < 128 ? 800 : 100); - stbtt__hheap_chunk *c = (stbtt__hheap_chunk *) STBTT_malloc(sizeof(stbtt__hheap_chunk) + size * count, userdata); - if (c == NULL) - return NULL; - c->next = hh->head; - hh->head = c; - hh->num_remaining_in_head_chunk = count; - } - --hh->num_remaining_in_head_chunk; - return (char *) (hh->head) + size * hh->num_remaining_in_head_chunk; - } + if (hh->first_free) + { + void *p = hh->first_free; + hh->first_free = *(void **)p; + return p; + } + else + { + if (hh->num_remaining_in_head_chunk == 0) + { + int count = (size < 32 ? 2000 : size < 128 ? 800 : 100); + stbtt__hheap_chunk *c = (stbtt__hheap_chunk *)STBTT_malloc(sizeof(stbtt__hheap_chunk) + size * count, userdata); + if (c == NULL) + return NULL; + c->next = hh->head; + hh->head = c; + hh->num_remaining_in_head_chunk = count; + } + --hh->num_remaining_in_head_chunk; + return (char *)(hh->head) + size * hh->num_remaining_in_head_chunk; + } } static void stbtt__hheap_free(stbtt__hheap *hh, void *p) { - *(void **) p = hh->first_free; - hh->first_free = p; + *(void **)p = hh->first_free; + hh->first_free = p; } static void stbtt__hheap_cleanup(stbtt__hheap *hh, void *userdata) { - stbtt__hheap_chunk *c = hh->head; - while (c) { - stbtt__hheap_chunk *n = c->next; - STBTT_free(c, userdata); - c = n; - } + stbtt__hheap_chunk *c = hh->head; + while (c) + { + stbtt__hheap_chunk *n = c->next; + STBTT_free(c, userdata); + c = n; + } } -typedef struct stbtt__edge { - float x0,y0, x1,y1; - int invert; +typedef struct stbtt__edge +{ + float x0, y0, x1, y1; + int invert; } stbtt__edge; - typedef struct stbtt__active_edge { - struct stbtt__active_edge *next; - #if STBTT_RASTERIZER_VERSION==1 - int x,dx; - float ey; - int direction; - #elif STBTT_RASTERIZER_VERSION==2 - float fx,fdx,fdy; - float direction; - float sy; - float ey; - #else - #error "Unrecognized value of STBTT_RASTERIZER_VERSION" - #endif + struct stbtt__active_edge *next; +#if STBTT_RASTERIZER_VERSION == 1 + int x, dx; + float ey; + int direction; +#elif STBTT_RASTERIZER_VERSION == 2 + float fx, fdx, fdy; + float direction; + float sy; + float ey; +#else +#error "Unrecognized value of STBTT_RASTERIZER_VERSION" +#endif } stbtt__active_edge; #if STBTT_RASTERIZER_VERSION == 1 -#define STBTT_FIXSHIFT 10 -#define STBTT_FIX (1 << STBTT_FIXSHIFT) -#define STBTT_FIXMASK (STBTT_FIX-1) +#define STBTT_FIXSHIFT 10 +#define STBTT_FIX (1 << STBTT_FIXSHIFT) +#define STBTT_FIXMASK (STBTT_FIX - 1) static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata) { - stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata); - float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); - if (!z) return z; - - // round dx down to avoid overshooting - if (dxdy < 0) - z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy); - else - z->dx = STBTT_ifloor(STBTT_FIX * dxdy); + stbtt__active_edge *z = (stbtt__active_edge *)stbtt__hheap_alloc(hh, sizeof(*z), userdata); + float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); + if (!z) return z; - z->x = STBTT_ifloor(STBTT_FIX * e->x0 + z->dx * (start_point - e->y0)); // use z->dx so when we offset later it's by the same amount - z->x -= off_x * STBTT_FIX; + // round dx down to avoid overshooting + if (dxdy < 0) + z->dx = -STBTT_ifloor(STBTT_FIX * -dxdy); + else + z->dx = STBTT_ifloor(STBTT_FIX * dxdy); - z->ey = e->y1; - z->next = 0; - z->direction = e->invert ? 1 : -1; - return z; + z->x = STBTT_ifloor(STBTT_FIX * e->x0 + z->dx * (start_point - e->y0)); // use z->dx so when we offset later it's by the same amount + z->x -= off_x * STBTT_FIX; + + z->ey = e->y1; + z->next = 0; + z->direction = e->invert ? 1 : -1; + return z; } #elif STBTT_RASTERIZER_VERSION == 2 static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, int off_x, float start_point, void *userdata) { - stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata); - float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); - //STBTT_assert(e->y0 <= start_point); - if (!z) return z; - z->fdx = dxdy; - z->fdy = (1/dxdy); - z->fx = e->x0 + dxdy * (start_point - e->y0); - z->fx -= off_x; - z->direction = e->invert ? 1.0f : -1.0f; - z->sy = e->y0; - z->ey = e->y1; - z->next = 0; - return z; + stbtt__active_edge *z = (stbtt__active_edge *)stbtt__hheap_alloc(hh, sizeof(*z), userdata); + float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); + //STBTT_assert(e->y0 <= start_point); + if (!z) return z; + z->fdx = dxdy; + z->fdy = (1 / dxdy); + z->fx = e->x0 + dxdy * (start_point - e->y0); + z->fx -= off_x; + z->direction = e->invert ? 1.0f : -1.0f; + z->sy = e->y0; + z->ey = e->y1; + z->next = 0; + return z; } #else #error "Unrecognized value of STBTT_RASTERIZER_VERSION" @@ -1696,142 +1814,167 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i // are wrong, or if the user supplies a too-small bitmap static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__active_edge *e, int max_weight) { - // non-zero winding fill - int x0=0, w=0; + // non-zero winding fill + int x0 = 0, w = 0; - while (e) { - if (w == 0) { - // if we're currently at zero, we need to record the edge start point - x0 = e->x; w += e->direction; - } else { - int x1 = e->x; w += e->direction; - // if we went to zero, we need to draw - if (w == 0) { - int i = x0 >> STBTT_FIXSHIFT; - int j = x1 >> STBTT_FIXSHIFT; + while (e) + { + if (w == 0) + { + // if we're currently at zero, we need to record the edge start point + x0 = e->x; + w += e->direction; + } + else + { + int x1 = e->x; + w += e->direction; + // if we went to zero, we need to draw + if (w == 0) + { + int i = x0 >> STBTT_FIXSHIFT; + int j = x1 >> STBTT_FIXSHIFT; - if (i < len && j >= 0) { - if (i == j) { - // x0,x1 are the same pixel, so compute combined coverage - scanline[i] = scanline[i] + (stbtt_uint8) ((x1 - x0) * max_weight >> STBTT_FIXSHIFT); - } else { - if (i >= 0) // add antialiasing for x0 - scanline[i] = scanline[i] + (stbtt_uint8) (((STBTT_FIX - (x0 & STBTT_FIXMASK)) * max_weight) >> STBTT_FIXSHIFT); - else - i = -1; // clip + if (i < len && j >= 0) + { + if (i == j) + { + // x0,x1 are the same pixel, so compute combined coverage + scanline[i] = scanline[i] + (stbtt_uint8)((x1 - x0) * max_weight >> STBTT_FIXSHIFT); + } + else + { + if (i >= 0) // add antialiasing for x0 + scanline[i] = scanline[i] + (stbtt_uint8)(((STBTT_FIX - (x0 & STBTT_FIXMASK)) * max_weight) >> STBTT_FIXSHIFT); + else + i = -1; // clip - if (j < len) // add antialiasing for x1 - scanline[j] = scanline[j] + (stbtt_uint8) (((x1 & STBTT_FIXMASK) * max_weight) >> STBTT_FIXSHIFT); - else - j = len; // clip + if (j < len) // add antialiasing for x1 + scanline[j] = scanline[j] + (stbtt_uint8)(((x1 & STBTT_FIXMASK) * max_weight) >> STBTT_FIXSHIFT); + else + j = len; // clip - for (++i; i < j; ++i) // fill pixels between x0 and x1 - scanline[i] = scanline[i] + (stbtt_uint8) max_weight; - } - } - } - } - - e = e->next; - } + for (++i; i < j; ++i) // fill pixels between x0 and x1 + scanline[i] = scanline[i] + (stbtt_uint8)max_weight; + } + } + } + } + + e = e->next; + } } static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata) { - stbtt__hheap hh = { 0 }; - stbtt__active_edge *active = NULL; - int y,j=0; - int max_weight = (255 / vsubsample); // weight per vertical scanline - int s; // vertical subsample index - unsigned char scanline_data[512], *scanline; + stbtt__hheap hh = {0}; + stbtt__active_edge *active = NULL; + int y, j = 0; + int max_weight = (255 / vsubsample); // weight per vertical scanline + int s; // vertical subsample index + unsigned char scanline_data[512], *scanline; - if (result->w > 512) - scanline = (unsigned char *) STBTT_malloc(result->w, userdata); - else - scanline = scanline_data; + if (result->w > 512) + scanline = (unsigned char *)STBTT_malloc(result->w, userdata); + else + scanline = scanline_data; - y = off_y * vsubsample; - e[n].y0 = (off_y + result->h) * (float) vsubsample + 1; + y = off_y * vsubsample; + e[n].y0 = (off_y + result->h) * (float)vsubsample + 1; - while (j < result->h) { - STBTT_memset(scanline, 0, result->w); - for (s=0; s < vsubsample; ++s) { - // find center of pixel for this scanline - float scan_y = y + 0.5f; - stbtt__active_edge **step = &active; + while (j < result->h) + { + STBTT_memset(scanline, 0, result->w); + for (s = 0; s < vsubsample; ++s) + { + // find center of pixel for this scanline + float scan_y = y + 0.5f; + stbtt__active_edge **step = &active; - // update all active edges; - // remove all active edges that terminate before the center of this scanline - while (*step) { - stbtt__active_edge * z = *step; - if (z->ey <= scan_y) { - *step = z->next; // delete from list - STBTT_assert(z->direction); - z->direction = 0; - stbtt__hheap_free(&hh, z); - } else { - z->x += z->dx; // advance to position for current scanline - step = &((*step)->next); // advance through list - } - } + // update all active edges; + // remove all active edges that terminate before the center of this scanline + while (*step) + { + stbtt__active_edge *z = *step; + if (z->ey <= scan_y) + { + *step = z->next; // delete from list + STBTT_assert(z->direction); + z->direction = 0; + stbtt__hheap_free(&hh, z); + } + else + { + z->x += z->dx; // advance to position for current scanline + step = &((*step)->next); // advance through list + } + } - // resort the list if needed - for(;;) { - int changed=0; - step = &active; - while (*step && (*step)->next) { - if ((*step)->x > (*step)->next->x) { - stbtt__active_edge *t = *step; - stbtt__active_edge *q = t->next; + // resort the list if needed + for (;;) + { + int changed = 0; + step = &active; + while (*step && (*step)->next) + { + if ((*step)->x > (*step)->next->x) + { + stbtt__active_edge *t = *step; + stbtt__active_edge *q = t->next; - t->next = q->next; - q->next = t; - *step = q; - changed = 1; - } - step = &(*step)->next; - } - if (!changed) break; - } + t->next = q->next; + q->next = t; + *step = q; + changed = 1; + } + step = &(*step)->next; + } + if (!changed) break; + } - // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline - while (e->y0 <= scan_y) { - if (e->y1 > scan_y) { - stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata); - // find insertion point - if (active == NULL) - active = z; - else if (z->x < active->x) { - // insert at front - z->next = active; - active = z; - } else { - // find thing to insert AFTER - stbtt__active_edge *p = active; - while (p->next && p->next->x < z->x) - p = p->next; - // at this point, p->next->x is NOT < z->x - z->next = p->next; - p->next = z; - } - } - ++e; - } + // insert all edges that start before the center of this scanline -- omit ones that also end on this scanline + while (e->y0 <= scan_y) + { + if (e->y1 > scan_y) + { + stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata); + // find insertion point + if (active == NULL) + active = z; + else if (z->x < active->x) + { + // insert at front + z->next = active; + active = z; + } + else + { + // find thing to insert AFTER + stbtt__active_edge *p = active; + while (p->next && p->next->x < z->x) + p = p->next; + // at this point, p->next->x is NOT < z->x + z->next = p->next; + p->next = z; + } + } + ++e; + } - // now process all active edges in XOR fashion - if (active) - stbtt__fill_active_edges(scanline, result->w, active, max_weight); + // now process all active edges in XOR fashion + if (active) + stbtt__fill_active_edges(scanline, result->w, active, max_weight); - ++y; - } - STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w); - ++j; - } + ++y; + } + STBTT_memcpy(result->pixels + j * result->stride, scanline, result->w); + ++j; + } - stbtt__hheap_cleanup(&hh, userdata); + stbtt__hheap_cleanup(&hh, userdata); - if (scanline != scanline_data) - STBTT_free(scanline, userdata); + if (scanline != scanline_data) + STBTT_free(scanline, userdata); } #elif STBTT_RASTERIZER_VERSION == 2 @@ -1840,628 +1983,694 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, // (i.e. it has already been clipped to those) static void stbtt__handle_clipped_edge(float *scanline, int x, stbtt__active_edge *e, float x0, float y0, float x1, float y1) { - if (y0 == y1) return; - assert(y0 < y1); - assert(e->sy <= e->ey); - if (y0 > e->ey) return; - if (y1 < e->sy) return; - if (y0 < e->sy) { - x0 += (x1-x0) * (e->sy - y0) / (y1-y0); - y0 = e->sy; - } - if (y1 > e->ey) { - x1 += (x1-x0) * (e->ey - y1) / (y1-y0); - y1 = e->ey; - } + if (y0 == y1) return; + assert(y0 < y1); + assert(e->sy <= e->ey); + if (y0 > e->ey) return; + if (y1 < e->sy) return; + if (y0 < e->sy) + { + x0 += (x1 - x0) * (e->sy - y0) / (y1 - y0); + y0 = e->sy; + } + if (y1 > e->ey) + { + x1 += (x1 - x0) * (e->ey - y1) / (y1 - y0); + y1 = e->ey; + } - if (x0 == x) - assert(x1 <= x+1); - else if (x0 == x+1) - assert(x1 >= x); - else if (x0 <= x) - assert(x1 <= x); - else if (x0 >= x+1) - assert(x1 >= x+1); - else - assert(x1 >= x && x1 <= x+1); + if (x0 == x) + assert(x1 <= x + 1); + else if (x0 == x + 1) + assert(x1 >= x); + else if (x0 <= x) + assert(x1 <= x); + else if (x0 >= x + 1) + assert(x1 >= x + 1); + else + assert(x1 >= x && x1 <= x + 1); - if (x0 <= x && x1 <= x) - scanline[x] += e->direction * (y1-y0); - else if (x0 >= x+1 && x1 >= x+1) - ; - else { - assert(x0 >= x && x0 <= x+1 && x1 >= x && x1 <= x+1); - scanline[x] += e->direction * (y1-y0) * (1-((x0-x)+(x1-x))/2); // coverage = 1 - average x position - } + if (x0 <= x && x1 <= x) + scanline[x] += e->direction * (y1 - y0); + else if (x0 >= x + 1 && x1 >= x + 1) + ; + else + { + assert(x0 >= x && x0 <= x + 1 && x1 >= x && x1 <= x + 1); + scanline[x] += e->direction * (y1 - y0) * (1 - ((x0 - x) + (x1 - x)) / 2); // coverage = 1 - average x position + } } static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, int len, stbtt__active_edge *e, float y_top) { - float y_bottom = y_top+1; + float y_bottom = y_top + 1; - while (e) { - // brute force every pixel + while (e) + { + // brute force every pixel - // compute intersection points with top & bottom - assert(e->ey >= y_top); + // compute intersection points with top & bottom + assert(e->ey >= y_top); - if (e->fdx == 0) { - float x0 = e->fx; - if (x0 < len) { - if (x0 >= 0) { - stbtt__handle_clipped_edge(scanline,(int) x0,e, x0,y_top, x0,y_bottom); - stbtt__handle_clipped_edge(scanline_fill-1,(int) x0+1,e, x0,y_top, x0,y_bottom); - } else { - stbtt__handle_clipped_edge(scanline_fill-1,0,e, x0,y_top, x0,y_bottom); - } - } - } else { - float x0 = e->fx; - float dx = e->fdx; - float xb = x0 + dx; - float x_top, x_bottom; - float y0,y1; - float dy = e->fdy; - assert(e->sy <= y_bottom && e->ey >= y_top); + if (e->fdx == 0) + { + float x0 = e->fx; + if (x0 < len) + { + if (x0 >= 0) + { + stbtt__handle_clipped_edge(scanline, (int)x0, e, x0, y_top, x0, y_bottom); + stbtt__handle_clipped_edge(scanline_fill - 1, (int)x0 + 1, e, x0, y_top, x0, y_bottom); + } + else + { + stbtt__handle_clipped_edge(scanline_fill - 1, 0, e, x0, y_top, x0, y_bottom); + } + } + } + else + { + float x0 = e->fx; + float dx = e->fdx; + float xb = x0 + dx; + float x_top, x_bottom; + float y0, y1; + float dy = e->fdy; + assert(e->sy <= y_bottom && e->ey >= y_top); - // compute endpoints of line segment clipped to this scanline (if the - // line segment starts on this scanline. x0 is the intersection of the - // line with y_top, but that may be off the line segment. - if (e->sy > y_top) { - x_top = x0 + dx * (e->sy - y_top); - y0 = e->sy; - } else { - x_top = x0; - y0 = y_top; - } - if (e->ey < y_bottom) { - x_bottom = x0 + dx * (e->ey - y_top); - y1 = e->ey; - } else { - x_bottom = xb; - y1 = y_bottom; - } + // compute endpoints of line segment clipped to this scanline (if the + // line segment starts on this scanline. x0 is the intersection of the + // line with y_top, but that may be off the line segment. + if (e->sy > y_top) + { + x_top = x0 + dx * (e->sy - y_top); + y0 = e->sy; + } + else + { + x_top = x0; + y0 = y_top; + } + if (e->ey < y_bottom) + { + x_bottom = x0 + dx * (e->ey - y_top); + y1 = e->ey; + } + else + { + x_bottom = xb; + y1 = y_bottom; + } - if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) { - // from here on, we don't have to range check x values + if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) + { + // from here on, we don't have to range check x values - if ((int) x_top == (int) x_bottom) { - float height; - // simple case, only spans one pixel - int x = (int) x_top; - height = y1 - y0; - assert(x >= 0 && x < len); - scanline[x] += e->direction * (1-((x_top - x) + (x_bottom-x))/2) * height; - scanline_fill[x] += e->direction * height; // everything right of this pixel is filled - } else { - int x,x1,x2; - float y_crossing, step, sign, area; - // covers 2+ pixels - if (x_top > x_bottom) { - // flip scanline vertically; signed area is the same - float t; - y0 = y_bottom - (y0 - y_top); - y1 = y_bottom - (y1 - y_top); - t = y0, y0 = y1, y1 = t; - t = x_bottom, x_bottom = x_top, x_top = t; - dx = -dx; - dy = -dy; - t = x0, x0 = xb, xb = t; - } + if ((int)x_top == (int)x_bottom) + { + float height; + // simple case, only spans one pixel + int x = (int)x_top; + height = y1 - y0; + assert(x >= 0 && x < len); + scanline[x] += e->direction * (1 - ((x_top - x) + (x_bottom - x)) / 2) * height; + scanline_fill[x] += e->direction * height; // everything right of this pixel is filled + } + else + { + int x, x1, x2; + float y_crossing, step, sign, area; + // covers 2+ pixels + if (x_top > x_bottom) + { + // flip scanline vertically; signed area is the same + float t; + y0 = y_bottom - (y0 - y_top); + y1 = y_bottom - (y1 - y_top); + t = y0, y0 = y1, y1 = t; + t = x_bottom, x_bottom = x_top, x_top = t; + dx = -dx; + dy = -dy; + t = x0, x0 = xb, xb = t; + } - x1 = (int) x_top; - x2 = (int) x_bottom; - // compute intersection with y axis at x1+1 - y_crossing = (x1+1 - x0) * dy + y_top; + x1 = (int)x_top; + x2 = (int)x_bottom; + // compute intersection with y axis at x1+1 + y_crossing = (x1 + 1 - x0) * dy + y_top; - sign = e->direction; - // area of the rectangle covered from y0..y_crossing - area = sign * (y_crossing-y0); - // area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing) - scanline[x1] += area * (1-((x_top - x1)+(x1+1-x1))/2); + sign = e->direction; + // area of the rectangle covered from y0..y_crossing + area = sign * (y_crossing - y0); + // area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing) + scanline[x1] += area * (1 - ((x_top - x1) + (x1 + 1 - x1)) / 2); - step = sign * dy; - for (x = x1+1; x < x2; ++x) { - scanline[x] += area + step/2; - area += step; - } - y_crossing += dy * (x2 - (x1+1)); + step = sign * dy; + for (x = x1 + 1; x < x2; ++x) + { + scanline[x] += area + step / 2; + area += step; + } + y_crossing += dy * (x2 - (x1 + 1)); - assert(fabs(area) <= 1.01f); + assert(fabs(area) <= 1.01f); - scanline[x2] += area + sign * (1-((x2-x2)+(x_bottom-x2))/2) * (y1-y_crossing); + scanline[x2] += area + sign * (1 - ((x2 - x2) + (x_bottom - x2)) / 2) * (y1 - y_crossing); - scanline_fill[x2] += sign * (y1-y0); - } - } else { - // if edge goes outside of box we're drawing, we require - // clipping logic. since this does not match the intended use - // of this library, we use a different, very slow brute - // force implementation - int x; - for (x=0; x < len; ++x) { - // cases: - // - // there can be up to two intersections with the pixel. any intersection - // with left or right edges can be handled by splitting into two (or three) - // regions. intersections with top & bottom do not necessitate case-wise logic. - float y0,y1; - float y_cur = y_top, x_cur = x0; - // x = e->x + e->dx * (y-y_top) - // (y-y_top) = (x - e->x) / e->dx - // y = (x - e->x) / e->dx + y_top - y0 = (x - x0) / dx + y_top; - y1 = (x+1 - x0) / dx + y_top; + scanline_fill[x2] += sign * (y1 - y0); + } + } + else + { + // if edge goes outside of box we're drawing, we require + // clipping logic. since this does not match the intended use + // of this library, we use a different, very slow brute + // force implementation + int x; + for (x = 0; x < len; ++x) + { + // cases: + // + // there can be up to two intersections with the pixel. any intersection + // with left or right edges can be handled by splitting into two (or three) + // regions. intersections with top & bottom do not necessitate case-wise logic. + float y0, y1; + float y_cur = y_top, x_cur = x0; + // x = e->x + e->dx * (y-y_top) + // (y-y_top) = (x - e->x) / e->dx + // y = (x - e->x) / e->dx + y_top + y0 = (x - x0) / dx + y_top; + y1 = (x + 1 - x0) / dx + y_top; - if (y0 < y1) { - if (y0 > y_top && y0 < y_bottom) { - stbtt__handle_clipped_edge(scanline,x,e, x_cur,y_cur, (float) x,y0); - y_cur = y0; - x_cur = (float) x; - } - if (y1 >= y_cur && y1 < y_bottom) { - stbtt__handle_clipped_edge(scanline,x,e, x_cur,y_cur, (float) x+1,y1); - y_cur = y1; - x_cur = (float) x+1; - } - } else { - if (y1 >= y_cur && y1 < y_bottom) { - stbtt__handle_clipped_edge(scanline,x,e, x_cur,y_cur, (float) x+1,y1); - y_cur = y1; - x_cur = (float) x+1; - } - if (y0 > y_top && y0 < y_bottom) { - stbtt__handle_clipped_edge(scanline,x,e, x_cur,y_cur, (float) x,y0); - y_cur = y0; - x_cur = (float) x; - } - } - stbtt__handle_clipped_edge(scanline,x,e, x_cur,y_cur, xb,y_bottom); - } - } - } - e = e->next; - } + if (y0 < y1) + { + if (y0 > y_top && y0 < y_bottom) + { + stbtt__handle_clipped_edge(scanline, x, e, x_cur, y_cur, (float)x, y0); + y_cur = y0; + x_cur = (float)x; + } + if (y1 >= y_cur && y1 < y_bottom) + { + stbtt__handle_clipped_edge(scanline, x, e, x_cur, y_cur, (float)x + 1, y1); + y_cur = y1; + x_cur = (float)x + 1; + } + } + else + { + if (y1 >= y_cur && y1 < y_bottom) + { + stbtt__handle_clipped_edge(scanline, x, e, x_cur, y_cur, (float)x + 1, y1); + y_cur = y1; + x_cur = (float)x + 1; + } + if (y0 > y_top && y0 < y_bottom) + { + stbtt__handle_clipped_edge(scanline, x, e, x_cur, y_cur, (float)x, y0); + y_cur = y0; + x_cur = (float)x; + } + } + stbtt__handle_clipped_edge(scanline, x, e, x_cur, y_cur, xb, y_bottom); + } + } + } + e = e->next; + } } // directly AA rasterize edges w/o supersampling static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata) { - stbtt__hheap hh = { 0 }; - stbtt__active_edge *active = NULL; - int y,j=0, i; - float scanline_data[129], *scanline, *scanline2; + stbtt__hheap hh = {0}; + stbtt__active_edge *active = NULL; + int y, j = 0, i; + float scanline_data[129], *scanline, *scanline2; - if (result->w > 64) - scanline = (float *) STBTT_malloc((result->w*2+1) * sizeof(float), userdata); - else - scanline = scanline_data; + if (result->w > 64) + scanline = (float *)STBTT_malloc((result->w * 2 + 1) * sizeof(float), userdata); + else + scanline = scanline_data; - scanline2 = scanline + result->w; + scanline2 = scanline + result->w; - y = off_y; - e[n].y0 = (float) (off_y + result->h) + 1; + y = off_y; + e[n].y0 = (float)(off_y + result->h) + 1; - while (j < result->h) { - // find center of pixel for this scanline - float scan_y_top = y + 0.0f; - float scan_y_bottom = y + 1.0f; - stbtt__active_edge **step = &active; + while (j < result->h) + { + // find center of pixel for this scanline + float scan_y_top = y + 0.0f; + float scan_y_bottom = y + 1.0f; + stbtt__active_edge **step = &active; - STBTT_memset(scanline , 0, result->w*sizeof(scanline[0])); - STBTT_memset(scanline2, 0, (result->w+1)*sizeof(scanline[0])); + STBTT_memset(scanline, 0, result->w * sizeof(scanline[0])); + STBTT_memset(scanline2, 0, (result->w + 1) * sizeof(scanline[0])); - // update all active edges; - // remove all active edges that terminate before the top of this scanline - while (*step) { - stbtt__active_edge * z = *step; - if (z->ey <= scan_y_top) { - *step = z->next; // delete from list - STBTT_assert(z->direction); - z->direction = 0; - stbtt__hheap_free(&hh, z); - } else { - step = &((*step)->next); // advance through list - } - } + // update all active edges; + // remove all active edges that terminate before the top of this scanline + while (*step) + { + stbtt__active_edge *z = *step; + if (z->ey <= scan_y_top) + { + *step = z->next; // delete from list + STBTT_assert(z->direction); + z->direction = 0; + stbtt__hheap_free(&hh, z); + } + else + { + step = &((*step)->next); // advance through list + } + } - // insert all edges that start before the bottom of this scanline - while (e->y0 <= scan_y_bottom) { - stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata); - assert(z->ey >= scan_y_top); - // insert at front - z->next = active; - active = z; - ++e; - } + // insert all edges that start before the bottom of this scanline + while (e->y0 <= scan_y_bottom) + { + stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata); + assert(z->ey >= scan_y_top); + // insert at front + z->next = active; + active = z; + ++e; + } - // now process all active edges - if (active) - stbtt__fill_active_edges_new(scanline, scanline2+1, result->w, active, scan_y_top); + // now process all active edges + if (active) + stbtt__fill_active_edges_new(scanline, scanline2 + 1, result->w, active, scan_y_top); - { - float sum = 0; - for (i=0; i < result->w; ++i) { - float k; - int m; - sum += scanline2[i]; - k = scanline[i] + sum; - k = (float) fabs(k)*255 + 0.5f; - m = (int) k; - if (m > 255) m = 255; - result->pixels[j*result->stride + i] = (unsigned char) m; - } - } - // advance all the edges - step = &active; - while (*step) { - stbtt__active_edge *z = *step; - z->fx += z->fdx; // advance to position for current scanline - step = &((*step)->next); // advance through list - } + { + float sum = 0; + for (i = 0; i < result->w; ++i) + { + float k; + int m; + sum += scanline2[i]; + k = scanline[i] + sum; + k = (float)fabs(k) * 255 + 0.5f; + m = (int)k; + if (m > 255) m = 255; + result->pixels[j * result->stride + i] = (unsigned char)m; + } + } + // advance all the edges + step = &active; + while (*step) + { + stbtt__active_edge *z = *step; + z->fx += z->fdx; // advance to position for current scanline + step = &((*step)->next); // advance through list + } - ++y; - ++j; - } + ++y; + ++j; + } - stbtt__hheap_cleanup(&hh, userdata); + stbtt__hheap_cleanup(&hh, userdata); - if (scanline != scanline_data) - STBTT_free(scanline, userdata); + if (scanline != scanline_data) + STBTT_free(scanline, userdata); } #else #error "Unrecognized value of STBTT_RASTERIZER_VERSION" #endif -#define STBTT__COMPARE(a,b) ((a)->y0 < (b)->y0) +#define STBTT__COMPARE(a, b) ((a)->y0 < (b)->y0) static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n) { - int i,j; - for (i=1; i < n; ++i) { - stbtt__edge t = p[i], *a = &t; - j = i; - while (j > 0) { - stbtt__edge *b = &p[j-1]; - int c = STBTT__COMPARE(a,b); - if (!c) break; - p[j] = p[j-1]; - --j; - } - if (i != j) - p[j] = t; - } + int i, j; + for (i = 1; i < n; ++i) + { + stbtt__edge t = p[i], *a = &t; + j = i; + while (j > 0) + { + stbtt__edge *b = &p[j - 1]; + int c = STBTT__COMPARE(a, b); + if (!c) break; + p[j] = p[j - 1]; + --j; + } + if (i != j) + p[j] = t; + } } static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n) { - /* threshhold for transitioning to insertion sort */ - while (n > 12) { - stbtt__edge t; - int c01,c12,c,m,i,j; + /* threshhold for transitioning to insertion sort */ + while (n > 12) + { + stbtt__edge t; + int c01, c12, c, m, i, j; - /* compute median of three */ - m = n >> 1; - c01 = STBTT__COMPARE(&p[0],&p[m]); - c12 = STBTT__COMPARE(&p[m],&p[n-1]); - /* if 0 >= mid >= end, or 0 < mid < end, then use mid */ - if (c01 != c12) { - /* otherwise, we'll need to swap something else to middle */ - int z; - c = STBTT__COMPARE(&p[0],&p[n-1]); - /* 0>mid && midn => n; 0 0 */ - /* 0n: 0>n => 0; 0 n */ - z = (c == c12) ? 0 : n-1; - t = p[z]; - p[z] = p[m]; - p[m] = t; - } - /* now p[m] is the median-of-three */ - /* swap it to the beginning so it won't move around */ - t = p[0]; - p[0] = p[m]; - p[m] = t; + /* compute median of three */ + m = n >> 1; + c01 = STBTT__COMPARE(&p[0], &p[m]); + c12 = STBTT__COMPARE(&p[m], &p[n - 1]); + /* if 0 >= mid >= end, or 0 < mid < end, then use mid */ + if (c01 != c12) + { + /* otherwise, we'll need to swap something else to middle */ + int z; + c = STBTT__COMPARE(&p[0], &p[n - 1]); + /* 0>mid && midn => n; 0 0 */ + /* 0n: 0>n => 0; 0 n */ + z = (c == c12) ? 0 : n - 1; + t = p[z]; + p[z] = p[m]; + p[m] = t; + } + /* now p[m] is the median-of-three */ + /* swap it to the beginning so it won't move around */ + t = p[0]; + p[0] = p[m]; + p[m] = t; - /* partition loop */ - i=1; - j=n-1; - for(;;) { - /* handling of equality is crucial here */ - /* for sentinels & efficiency with duplicates */ - for (;;++i) { - if (!STBTT__COMPARE(&p[i], &p[0])) break; - } - for (;;--j) { - if (!STBTT__COMPARE(&p[0], &p[j])) break; - } - /* make sure we haven't crossed */ - if (i >= j) break; - t = p[i]; - p[i] = p[j]; - p[j] = t; + /* partition loop */ + i = 1; + j = n - 1; + for (;;) + { + /* handling of equality is crucial here */ + /* for sentinels & efficiency with duplicates */ + for (;; ++i) + { + if (!STBTT__COMPARE(&p[i], &p[0])) break; + } + for (;; --j) + { + if (!STBTT__COMPARE(&p[0], &p[j])) break; + } + /* make sure we haven't crossed */ + if (i >= j) break; + t = p[i]; + p[i] = p[j]; + p[j] = t; - ++i; - --j; - } - /* recurse on smaller side, iterate on larger */ - if (j < (n-i)) { - stbtt__sort_edges_quicksort(p,j); - p = p+i; - n = n-i; - } else { - stbtt__sort_edges_quicksort(p+i, n-i); - n = j; - } - } + ++i; + --j; + } + /* recurse on smaller side, iterate on larger */ + if (j < (n - i)) + { + stbtt__sort_edges_quicksort(p, j); + p = p + i; + n = n - i; + } + else + { + stbtt__sort_edges_quicksort(p + i, n - i); + n = j; + } + } } static void stbtt__sort_edges(stbtt__edge *p, int n) { - stbtt__sort_edges_quicksort(p, n); - stbtt__sort_edges_ins_sort(p, n); + stbtt__sort_edges_quicksort(p, n); + stbtt__sort_edges_ins_sort(p, n); } typedef struct { - float x,y; + float x, y; } stbtt__point; static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcount, int windings, float scale_x, float scale_y, float shift_x, float shift_y, int off_x, int off_y, int invert, void *userdata) { - float y_scale_inv = invert ? -scale_y : scale_y; - stbtt__edge *e; - int n,i,j,k,m; + float y_scale_inv = invert ? -scale_y : scale_y; + stbtt__edge *e; + int n, i, j, k, m; #if STBTT_RASTERIZER_VERSION == 1 - int vsubsample = result->h < 8 ? 15 : 5; + int vsubsample = result->h < 8 ? 15 : 5; #elif STBTT_RASTERIZER_VERSION == 2 - int vsubsample = 1; + int vsubsample = 1; #else - #error "Unrecognized value of STBTT_RASTERIZER_VERSION" +#error "Unrecognized value of STBTT_RASTERIZER_VERSION" #endif - // vsubsample should divide 255 evenly; otherwise we won't reach full opacity + // vsubsample should divide 255 evenly; otherwise we won't reach full opacity - // now we have to blow out the windings into explicit edge lists - n = 0; - for (i=0; i < windings; ++i) - n += wcount[i]; + // now we have to blow out the windings into explicit edge lists + n = 0; + for (i = 0; i < windings; ++i) + n += wcount[i]; - e = (stbtt__edge *) STBTT_malloc(sizeof(*e) * (n+1), userdata); // add an extra one as a sentinel - if (e == 0) return; - n = 0; + e = (stbtt__edge *)STBTT_malloc(sizeof(*e) * (n + 1), userdata); // add an extra one as a sentinel + if (e == 0) return; + n = 0; - m=0; - for (i=0; i < windings; ++i) { - stbtt__point *p = pts + m; - m += wcount[i]; - j = wcount[i]-1; - for (k=0; k < wcount[i]; j=k++) { - int a=k,b=j; - // skip the edge if horizontal - if (p[j].y == p[k].y) - continue; - // add edge from j to k to the list - e[n].invert = 0; - if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) { - e[n].invert = 1; - a=j,b=k; - } - e[n].x0 = p[a].x * scale_x + shift_x; - e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample; - e[n].x1 = p[b].x * scale_x + shift_x; - e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample; - ++n; - } - } + m = 0; + for (i = 0; i < windings; ++i) + { + stbtt__point *p = pts + m; + m += wcount[i]; + j = wcount[i] - 1; + for (k = 0; k < wcount[i]; j = k++) + { + int a = k, b = j; + // skip the edge if horizontal + if (p[j].y == p[k].y) + continue; + // add edge from j to k to the list + e[n].invert = 0; + if (invert ? p[j].y > p[k].y : p[j].y < p[k].y) + { + e[n].invert = 1; + a = j, b = k; + } + e[n].x0 = p[a].x * scale_x + shift_x; + e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample; + e[n].x1 = p[b].x * scale_x + shift_x; + e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample; + ++n; + } + } - // now sort the edges by their highest point (should snap to integer, and then by x) - //STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare); - stbtt__sort_edges(e, n); + // now sort the edges by their highest point (should snap to integer, and then by x) + //STBTT_sort(e, n, sizeof(e[0]), stbtt__edge_compare); + stbtt__sort_edges(e, n); - // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule - stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata); + // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule + stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata); - STBTT_free(e, userdata); + STBTT_free(e, userdata); } static void stbtt__add_point(stbtt__point *points, int n, float x, float y) { - if (!points) return; // during first pass, it's unallocated - points[n].x = x; - points[n].y = y; + if (!points) return; // during first pass, it's unallocated + points[n].x = x; + points[n].y = y; } // tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n) { - // midpoint - float mx = (x0 + 2*x1 + x2)/4; - float my = (y0 + 2*y1 + y2)/4; - // versus directly drawn line - float dx = (x0+x2)/2 - mx; - float dy = (y0+y2)/2 - my; - if (n > 16) // 65536 segments on one curve better be enough! - return 1; - if (dx*dx+dy*dy > objspace_flatness_squared) { // half-pixel error allowed... need to be smaller if AA - stbtt__tesselate_curve(points, num_points, x0,y0, (x0+x1)/2.0f,(y0+y1)/2.0f, mx,my, objspace_flatness_squared,n+1); - stbtt__tesselate_curve(points, num_points, mx,my, (x1+x2)/2.0f,(y1+y2)/2.0f, x2,y2, objspace_flatness_squared,n+1); - } else { - stbtt__add_point(points, *num_points,x2,y2); - *num_points = *num_points+1; - } - return 1; + // midpoint + float mx = (x0 + 2 * x1 + x2) / 4; + float my = (y0 + 2 * y1 + y2) / 4; + // versus directly drawn line + float dx = (x0 + x2) / 2 - mx; + float dy = (y0 + y2) / 2 - my; + if (n > 16) // 65536 segments on one curve better be enough! + return 1; + if (dx * dx + dy * dy > objspace_flatness_squared) + { // half-pixel error allowed... need to be smaller if AA + stbtt__tesselate_curve(points, num_points, x0, y0, (x0 + x1) / 2.0f, (y0 + y1) / 2.0f, mx, my, objspace_flatness_squared, n + 1); + stbtt__tesselate_curve(points, num_points, mx, my, (x1 + x2) / 2.0f, (y1 + y2) / 2.0f, x2, y2, objspace_flatness_squared, n + 1); + } + else + { + stbtt__add_point(points, *num_points, x2, y2); + *num_points = *num_points + 1; + } + return 1; } // returns number of contours static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata) { - stbtt__point *points=0; - int num_points=0; + stbtt__point *points = 0; + int num_points = 0; - float objspace_flatness_squared = objspace_flatness * objspace_flatness; - int i,n=0,start=0, pass; + float objspace_flatness_squared = objspace_flatness * objspace_flatness; + int i, n = 0, start = 0, pass; - // count how many "moves" there are to get the contour count - for (i=0; i < num_verts; ++i) - if (vertices[i].type == STBTT_vmove) - ++n; + // count how many "moves" there are to get the contour count + for (i = 0; i < num_verts; ++i) + if (vertices[i].type == STBTT_vmove) + ++n; - *num_contours = n; - if (n == 0) return 0; + *num_contours = n; + if (n == 0) return 0; - *contour_lengths = (int *) STBTT_malloc(sizeof(**contour_lengths) * n, userdata); + *contour_lengths = (int *)STBTT_malloc(sizeof(**contour_lengths) * n, userdata); - if (*contour_lengths == 0) { - *num_contours = 0; - return 0; - } + if (*contour_lengths == 0) + { + *num_contours = 0; + return 0; + } - // make two passes through the points so we don't need to realloc - for (pass=0; pass < 2; ++pass) { - float x=0,y=0; - if (pass == 1) { - points = (stbtt__point *) STBTT_malloc(num_points * sizeof(points[0]), userdata); - if (points == NULL) goto error; - } - num_points = 0; - n= -1; - for (i=0; i < num_verts; ++i) { - switch (vertices[i].type) { - case STBTT_vmove: - // start the next contour - if (n >= 0) - (*contour_lengths)[n] = num_points - start; - ++n; - start = num_points; + // make two passes through the points so we don't need to realloc + for (pass = 0; pass < 2; ++pass) + { + float x = 0, y = 0; + if (pass == 1) + { + points = (stbtt__point *)STBTT_malloc(num_points * sizeof(points[0]), userdata); + if (points == NULL) goto error; + } + num_points = 0; + n = -1; + for (i = 0; i < num_verts; ++i) + { + switch (vertices[i].type) + { + case STBTT_vmove: + // start the next contour + if (n >= 0) + (*contour_lengths)[n] = num_points - start; + ++n; + start = num_points; - x = vertices[i].x, y = vertices[i].y; - stbtt__add_point(points, num_points++, x,y); - break; - case STBTT_vline: - x = vertices[i].x, y = vertices[i].y; - stbtt__add_point(points, num_points++, x, y); - break; - case STBTT_vcurve: - stbtt__tesselate_curve(points, &num_points, x,y, - vertices[i].cx, vertices[i].cy, - vertices[i].x, vertices[i].y, - objspace_flatness_squared, 0); - x = vertices[i].x, y = vertices[i].y; - break; - } - } - (*contour_lengths)[n] = num_points - start; - } + x = vertices[i].x, y = vertices[i].y; + stbtt__add_point(points, num_points++, x, y); + break; + case STBTT_vline: + x = vertices[i].x, y = vertices[i].y; + stbtt__add_point(points, num_points++, x, y); + break; + case STBTT_vcurve: + stbtt__tesselate_curve(points, &num_points, x, y, + vertices[i].cx, vertices[i].cy, + vertices[i].x, vertices[i].y, + objspace_flatness_squared, 0); + x = vertices[i].x, y = vertices[i].y; + break; + } + } + (*contour_lengths)[n] = num_points - start; + } - return points; + return points; error: - STBTT_free(points, userdata); - STBTT_free(*contour_lengths, userdata); - *contour_lengths = 0; - *num_contours = 0; - return NULL; + STBTT_free(points, userdata); + STBTT_free(*contour_lengths, userdata); + *contour_lengths = 0; + *num_contours = 0; + return NULL; } STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata) { - float scale = scale_x > scale_y ? scale_y : scale_x; - int winding_count, *winding_lengths; - stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata); - if (windings) { - stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata); - STBTT_free(winding_lengths, userdata); - STBTT_free(windings, userdata); - } + float scale = scale_x > scale_y ? scale_y : scale_x; + int winding_count, *winding_lengths; + stbtt__point *windings = stbtt_FlattenCurves(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata); + if (windings) + { + stbtt__rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata); + STBTT_free(winding_lengths, userdata); + STBTT_free(windings, userdata); + } } STBTT_DEF void stbtt_FreeBitmap(unsigned char *bitmap, void *userdata) { - STBTT_free(bitmap, userdata); + STBTT_free(bitmap, userdata); } STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int glyph, int *width, int *height, int *xoff, int *yoff) { - int ix0,iy0,ix1,iy1; - stbtt__bitmap gbm; - stbtt_vertex *vertices; - int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); + int ix0, iy0, ix1, iy1; + stbtt__bitmap gbm; + stbtt_vertex *vertices; + int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); - if (scale_x == 0) scale_x = scale_y; - if (scale_y == 0) { - if (scale_x == 0) return NULL; - scale_y = scale_x; - } + if (scale_x == 0) scale_x = scale_y; + if (scale_y == 0) + { + if (scale_x == 0) return NULL; + scale_y = scale_x; + } - stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,&ix1,&iy1); + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0, &iy0, &ix1, &iy1); - // now we get the size - gbm.w = (ix1 - ix0); - gbm.h = (iy1 - iy0); - gbm.pixels = NULL; // in case we error + // now we get the size + gbm.w = (ix1 - ix0); + gbm.h = (iy1 - iy0); + gbm.pixels = NULL; // in case we error - if (width ) *width = gbm.w; - if (height) *height = gbm.h; - if (xoff ) *xoff = ix0; - if (yoff ) *yoff = iy0; - - if (gbm.w && gbm.h) { - gbm.pixels = (unsigned char *) STBTT_malloc(gbm.w * gbm.h, info->userdata); - if (gbm.pixels) { - gbm.stride = gbm.w; + if (width) *width = gbm.w; + if (height) *height = gbm.h; + if (xoff) *xoff = ix0; + if (yoff) *yoff = iy0; - stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata); - } - } - STBTT_free(vertices, info->userdata); - return gbm.pixels; -} + if (gbm.w && gbm.h) + { + gbm.pixels = (unsigned char *)STBTT_malloc(gbm.w * gbm.h, info->userdata); + if (gbm.pixels) + { + gbm.stride = gbm.w; + + stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata); + } + } + STBTT_free(vertices, info->userdata); + return gbm.pixels; +} STBTT_DEF unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int glyph, int *width, int *height, int *xoff, int *yoff) { - return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff); + return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, glyph, width, height, xoff, yoff); } STBTT_DEF void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int glyph) { - int ix0,iy0; - stbtt_vertex *vertices; - int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); - stbtt__bitmap gbm; + int ix0, iy0; + stbtt_vertex *vertices; + int num_verts = stbtt_GetGlyphShape(info, glyph, &vertices); + stbtt__bitmap gbm; - stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0,&iy0,0,0); - gbm.pixels = output; - gbm.w = out_w; - gbm.h = out_h; - gbm.stride = out_stride; + stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale_x, scale_y, shift_x, shift_y, &ix0, &iy0, 0, 0); + gbm.pixels = output; + gbm.w = out_w; + gbm.h = out_h; + gbm.stride = out_stride; - if (gbm.w && gbm.h) - stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0,iy0, 1, info->userdata); + if (gbm.w && gbm.h) + stbtt_Rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata); - STBTT_free(vertices, info->userdata); + STBTT_free(vertices, info->userdata); } STBTT_DEF void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int glyph) { - stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, glyph); + stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f, 0.0f, glyph); } STBTT_DEF unsigned char *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *info, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint, int *width, int *height, int *xoff, int *yoff) { - return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y,shift_x,shift_y, stbtt_FindGlyphIndex(info,codepoint), width,height,xoff,yoff); -} + return stbtt_GetGlyphBitmapSubpixel(info, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info, codepoint), width, height, xoff, yoff); +} STBTT_DEF void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, float shift_x, float shift_y, int codepoint) { - stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info,codepoint)); + stbtt_MakeGlyphBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, shift_x, shift_y, stbtt_FindGlyphIndex(info, codepoint)); } STBTT_DEF unsigned char *stbtt_GetCodepointBitmap(const stbtt_fontinfo *info, float scale_x, float scale_y, int codepoint, int *width, int *height, int *xoff, int *yoff) { - return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f,0.0f, codepoint, width,height,xoff,yoff); -} + return stbtt_GetCodepointBitmapSubpixel(info, scale_x, scale_y, 0.0f, 0.0f, codepoint, width, height, xoff, yoff); +} STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned char *output, int out_w, int out_h, int out_stride, float scale_x, float scale_y, int codepoint) { - stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f,0.0f, codepoint); + stbtt_MakeCodepointBitmapSubpixel(info, output, out_w, out_h, out_stride, scale_x, scale_y, 0.0f, 0.0f, codepoint); } ////////////////////////////////////////////////////////////////////////////// @@ -2471,69 +2680,70 @@ STBTT_DEF void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *info, unsigned ch // This is SUPER-CRAPPY packing to keep source code small STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // font location (use offset=0 for plain .ttf) - float pixel_height, // height of font in pixels - unsigned char *pixels, int pw, int ph, // bitmap to be filled in - int first_char, int num_chars, // characters to bake - stbtt_bakedchar *chardata) + float pixel_height, // height of font in pixels + unsigned char *pixels, int pw, int ph, // bitmap to be filled in + int first_char, int num_chars, // characters to bake + stbtt_bakedchar *chardata) { - float scale; - int x,y,bottom_y, i; - stbtt_fontinfo f; - if (!stbtt_InitFont(&f, data, offset)) - return -1; - STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels - x=y=1; - bottom_y = 1; + float scale; + int x, y, bottom_y, i; + stbtt_fontinfo f; + if (!stbtt_InitFont(&f, data, offset)) + return -1; + STBTT_memset(pixels, 0, pw * ph); // background of 0 around pixels + x = y = 1; + bottom_y = 1; - scale = stbtt_ScaleForPixelHeight(&f, pixel_height); + scale = stbtt_ScaleForPixelHeight(&f, pixel_height); - for (i=0; i < num_chars; ++i) { - int advance, lsb, x0,y0,x1,y1,gw,gh; - int g = stbtt_FindGlyphIndex(&f, first_char + i); - stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb); - stbtt_GetGlyphBitmapBox(&f, g, scale,scale, &x0,&y0,&x1,&y1); - gw = x1-x0; - gh = y1-y0; - if (x + gw + 1 >= pw) - y = bottom_y, x = 1; // advance to next row - if (y + gh + 1 >= ph) // check if it fits vertically AFTER potentially moving to next row - return -i; - STBTT_assert(x+gw < pw); - STBTT_assert(y+gh < ph); - stbtt_MakeGlyphBitmap(&f, pixels+x+y*pw, gw,gh,pw, scale,scale, g); - chardata[i].x0 = (stbtt_int16) x; - chardata[i].y0 = (stbtt_int16) y; - chardata[i].x1 = (stbtt_int16) (x + gw); - chardata[i].y1 = (stbtt_int16) (y + gh); - chardata[i].xadvance = scale * advance; - chardata[i].xoff = (float) x0; - chardata[i].yoff = (float) y0; - x = x + gw + 1; - if (y+gh+1 > bottom_y) - bottom_y = y+gh+1; - } - return bottom_y; + for (i = 0; i < num_chars; ++i) + { + int advance, lsb, x0, y0, x1, y1, gw, gh; + int g = stbtt_FindGlyphIndex(&f, first_char + i); + stbtt_GetGlyphHMetrics(&f, g, &advance, &lsb); + stbtt_GetGlyphBitmapBox(&f, g, scale, scale, &x0, &y0, &x1, &y1); + gw = x1 - x0; + gh = y1 - y0; + if (x + gw + 1 >= pw) + y = bottom_y, x = 1; // advance to next row + if (y + gh + 1 >= ph) // check if it fits vertically AFTER potentially moving to next row + return -i; + STBTT_assert(x + gw < pw); + STBTT_assert(y + gh < ph); + stbtt_MakeGlyphBitmap(&f, pixels + x + y * pw, gw, gh, pw, scale, scale, g); + chardata[i].x0 = (stbtt_int16)x; + chardata[i].y0 = (stbtt_int16)y; + chardata[i].x1 = (stbtt_int16)(x + gw); + chardata[i].y1 = (stbtt_int16)(y + gh); + chardata[i].xadvance = scale * advance; + chardata[i].xoff = (float)x0; + chardata[i].yoff = (float)y0; + x = x + gw + 1; + if (y + gh + 1 > bottom_y) + bottom_y = y + gh + 1; + } + return bottom_y; } STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int opengl_fillrule) { - float d3d_bias = opengl_fillrule ? 0 : -0.5f; - float ipw = 1.0f / pw, iph = 1.0f / ph; - stbtt_bakedchar *b = chardata + char_index; - int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f); - int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f); + float d3d_bias = opengl_fillrule ? 0 : -0.5f; + float ipw = 1.0f / pw, iph = 1.0f / ph; + stbtt_bakedchar *b = chardata + char_index; + int round_x = STBTT_ifloor((*xpos + b->xoff) + 0.5f); + int round_y = STBTT_ifloor((*ypos + b->yoff) + 0.5f); - q->x0 = round_x + d3d_bias; - q->y0 = round_y + d3d_bias; - q->x1 = round_x + b->x1 - b->x0 + d3d_bias; - q->y1 = round_y + b->y1 - b->y0 + d3d_bias; + q->x0 = round_x + d3d_bias; + q->y0 = round_y + d3d_bias; + q->x1 = round_x + b->x1 - b->x0 + d3d_bias; + q->y1 = round_y + b->y1 - b->y0 + d3d_bias; - q->s0 = b->x0 * ipw; - q->t0 = b->y0 * iph; - q->s1 = b->x1 * ipw; - q->t1 = b->y1 * iph; + q->s0 = b->x0 * ipw; + q->t0 = b->y0 * iph; + q->s1 = b->x1 * ipw; + q->t1 = b->y1 * iph; - *xpos += b->xadvance; + *xpos += b->xadvance; } ////////////////////////////////////////////////////////////////////////////// @@ -2543,9 +2753,9 @@ STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int #ifndef STB_RECT_PACK_VERSION #ifdef _MSC_VER -#define STBTT__NOTUSED(v) (void)(v) +#define STBTT__NOTUSED(v) (void)(v) #else -#define STBTT__NOTUSED(v) (void)sizeof(v) +#define STBTT__NOTUSED(v) (void)sizeof(v) #endif typedef int stbrp_coord; @@ -2563,51 +2773,53 @@ typedef int stbrp_coord; typedef struct { - int width,height; - int x,y,bottom_y; + int width, height; + int x, y, bottom_y; } stbrp_context; typedef struct { - unsigned char x; + unsigned char x; } stbrp_node; typedef struct { - stbrp_coord x,y; - int id,w,h,was_packed; + stbrp_coord x, y; + int id, w, h, was_packed; } stbrp_rect; static void stbrp_init_target(stbrp_context *con, int pw, int ph, stbrp_node *nodes, int num_nodes) { - con->width = pw; - con->height = ph; - con->x = 0; - con->y = 0; - con->bottom_y = 0; - STBTT__NOTUSED(nodes); - STBTT__NOTUSED(num_nodes); + con->width = pw; + con->height = ph; + con->x = 0; + con->y = 0; + con->bottom_y = 0; + STBTT__NOTUSED(nodes); + STBTT__NOTUSED(num_nodes); } static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rects) { - int i; - for (i=0; i < num_rects; ++i) { - if (con->x + rects[i].w > con->width) { - con->x = 0; - con->y = con->bottom_y; - } - if (con->y + rects[i].h > con->height) - break; - rects[i].x = con->x; - rects[i].y = con->y; - rects[i].was_packed = 1; - con->x += rects[i].w; - if (con->y + rects[i].h > con->bottom_y) - con->bottom_y = con->y + rects[i].h; - } - for ( ; i < num_rects; ++i) - rects[i].was_packed = 0; + int i; + for (i = 0; i < num_rects; ++i) + { + if (con->x + rects[i].w > con->width) + { + con->x = 0; + con->y = con->bottom_y; + } + if (con->y + rects[i].h > con->height) + break; + rects[i].x = con->x; + rects[i].y = con->y; + rects[i].was_packed = 1; + con->x += rects[i].w; + if (con->y + rects[i].h > con->bottom_y) + con->bottom_y = con->y + rects[i].h; + } + for (; i < num_rects; ++i) + rects[i].was_packed = 0; } #endif @@ -2620,479 +2832,529 @@ static void stbrp_pack_rects(stbrp_context *con, stbrp_rect *rects, int num_rect STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, int pw, int ph, int stride_in_bytes, int padding, void *alloc_context) { - stbrp_context *context = (stbrp_context *) STBTT_malloc(sizeof(*context) ,alloc_context); - int num_nodes = pw - padding; - stbrp_node *nodes = (stbrp_node *) STBTT_malloc(sizeof(*nodes ) * num_nodes,alloc_context); + stbrp_context *context = (stbrp_context *)STBTT_malloc(sizeof(*context), alloc_context); + int num_nodes = pw - padding; + stbrp_node *nodes = (stbrp_node *)STBTT_malloc(sizeof(*nodes) * num_nodes, alloc_context); - if (context == NULL || nodes == NULL) { - if (context != NULL) STBTT_free(context, alloc_context); - if (nodes != NULL) STBTT_free(nodes , alloc_context); - return 0; - } + if (context == NULL || nodes == NULL) + { + if (context != NULL) STBTT_free(context, alloc_context); + if (nodes != NULL) STBTT_free(nodes, alloc_context); + return 0; + } - spc->user_allocator_context = alloc_context; - spc->width = pw; - spc->height = ph; - spc->pixels = pixels; - spc->pack_info = context; - spc->nodes = nodes; - spc->padding = padding; - spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw; - spc->h_oversample = 1; - spc->v_oversample = 1; + spc->user_allocator_context = alloc_context; + spc->width = pw; + spc->height = ph; + spc->pixels = pixels; + spc->pack_info = context; + spc->nodes = nodes; + spc->padding = padding; + spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw; + spc->h_oversample = 1; + spc->v_oversample = 1; - stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes); + stbrp_init_target(context, pw - padding, ph - padding, nodes, num_nodes); - STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels + STBTT_memset(pixels, 0, pw * ph); // background of 0 around pixels - return 1; + return 1; } -STBTT_DEF void stbtt_PackEnd (stbtt_pack_context *spc) +STBTT_DEF void stbtt_PackEnd(stbtt_pack_context *spc) { - STBTT_free(spc->nodes , spc->user_allocator_context); - STBTT_free(spc->pack_info, spc->user_allocator_context); + STBTT_free(spc->nodes, spc->user_allocator_context); + STBTT_free(spc->pack_info, spc->user_allocator_context); } STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h_oversample, unsigned int v_oversample) { - STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE); - STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE); - if (h_oversample <= STBTT_MAX_OVERSAMPLE) - spc->h_oversample = h_oversample; - if (v_oversample <= STBTT_MAX_OVERSAMPLE) - spc->v_oversample = v_oversample; + STBTT_assert(h_oversample <= STBTT_MAX_OVERSAMPLE); + STBTT_assert(v_oversample <= STBTT_MAX_OVERSAMPLE); + if (h_oversample <= STBTT_MAX_OVERSAMPLE) + spc->h_oversample = h_oversample; + if (v_oversample <= STBTT_MAX_OVERSAMPLE) + spc->v_oversample = v_oversample; } -#define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1) +#define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE - 1) static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) { - unsigned char buffer[STBTT_MAX_OVERSAMPLE]; - int safe_w = w - kernel_width; - int j; - for (j=0; j < h; ++j) { - int i; - unsigned int total; - STBTT_memset(buffer, 0, kernel_width); + unsigned char buffer[STBTT_MAX_OVERSAMPLE]; + int safe_w = w - kernel_width; + int j; + for (j = 0; j < h; ++j) + { + int i; + unsigned int total; + STBTT_memset(buffer, 0, kernel_width); - total = 0; + total = 0; - // make kernel_width a constant in common cases so compiler can optimize out the divide - switch (kernel_width) { - case 2: - for (i=0; i <= safe_w; ++i) { - total += pixels[i] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char) (total / 2); - } - break; - case 3: - for (i=0; i <= safe_w; ++i) { - total += pixels[i] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char) (total / 3); - } - break; - case 4: - for (i=0; i <= safe_w; ++i) { - total += pixels[i] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char) (total / 4); - } - break; - default: - for (i=0; i <= safe_w; ++i) { - total += pixels[i] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i]; - pixels[i] = (unsigned char) (total / kernel_width); - } - break; - } + // make kernel_width a constant in common cases so compiler can optimize out the divide + switch (kernel_width) + { + case 2: + for (i = 0; i <= safe_w; ++i) + { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char)(total / 2); + } + break; + case 3: + for (i = 0; i <= safe_w; ++i) + { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char)(total / 3); + } + break; + case 4: + for (i = 0; i <= safe_w; ++i) + { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char)(total / 4); + } + break; + default: + for (i = 0; i <= safe_w; ++i) + { + total += pixels[i] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i]; + pixels[i] = (unsigned char)(total / kernel_width); + } + break; + } - for (; i < w; ++i) { - STBTT_assert(pixels[i] == 0); - total -= buffer[i & STBTT__OVER_MASK]; - pixels[i] = (unsigned char) (total / kernel_width); - } + for (; i < w; ++i) + { + STBTT_assert(pixels[i] == 0); + total -= buffer[i & STBTT__OVER_MASK]; + pixels[i] = (unsigned char)(total / kernel_width); + } - pixels += stride_in_bytes; - } + pixels += stride_in_bytes; + } } static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width) { - unsigned char buffer[STBTT_MAX_OVERSAMPLE]; - int safe_h = h - kernel_width; - int j; - for (j=0; j < w; ++j) { - int i; - unsigned int total; - STBTT_memset(buffer, 0, kernel_width); + unsigned char buffer[STBTT_MAX_OVERSAMPLE]; + int safe_h = h - kernel_width; + int j; + for (j = 0; j < w; ++j) + { + int i; + unsigned int total; + STBTT_memset(buffer, 0, kernel_width); - total = 0; + total = 0; - // make kernel_width a constant in common cases so compiler can optimize out the divide - switch (kernel_width) { - case 2: - for (i=0; i <= safe_h; ++i) { - total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; - pixels[i*stride_in_bytes] = (unsigned char) (total / 2); - } - break; - case 3: - for (i=0; i <= safe_h; ++i) { - total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; - pixels[i*stride_in_bytes] = (unsigned char) (total / 3); - } - break; - case 4: - for (i=0; i <= safe_h; ++i) { - total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; - pixels[i*stride_in_bytes] = (unsigned char) (total / 4); - } - break; - default: - for (i=0; i <= safe_h; ++i) { - total += pixels[i*stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; - buffer[(i+kernel_width) & STBTT__OVER_MASK] = pixels[i*stride_in_bytes]; - pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width); - } - break; - } + // make kernel_width a constant in common cases so compiler can optimize out the divide + switch (kernel_width) + { + case 2: + for (i = 0; i <= safe_h; ++i) + { + total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes]; + pixels[i * stride_in_bytes] = (unsigned char)(total / 2); + } + break; + case 3: + for (i = 0; i <= safe_h; ++i) + { + total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes]; + pixels[i * stride_in_bytes] = (unsigned char)(total / 3); + } + break; + case 4: + for (i = 0; i <= safe_h; ++i) + { + total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes]; + pixels[i * stride_in_bytes] = (unsigned char)(total / 4); + } + break; + default: + for (i = 0; i <= safe_h; ++i) + { + total += pixels[i * stride_in_bytes] - buffer[i & STBTT__OVER_MASK]; + buffer[(i + kernel_width) & STBTT__OVER_MASK] = pixels[i * stride_in_bytes]; + pixels[i * stride_in_bytes] = (unsigned char)(total / kernel_width); + } + break; + } - for (; i < h; ++i) { - STBTT_assert(pixels[i*stride_in_bytes] == 0); - total -= buffer[i & STBTT__OVER_MASK]; - pixels[i*stride_in_bytes] = (unsigned char) (total / kernel_width); - } + for (; i < h; ++i) + { + STBTT_assert(pixels[i * stride_in_bytes] == 0); + total -= buffer[i & STBTT__OVER_MASK]; + pixels[i * stride_in_bytes] = (unsigned char)(total / kernel_width); + } - pixels += 1; - } + pixels += 1; + } } static float stbtt__oversample_shift(int oversample) { - if (!oversample) - return 0.0f; + if (!oversample) + return 0.0f; - // The prefilter is a box filter of width "oversample", - // which shifts phase by (oversample - 1)/2 pixels in - // oversampled space. We want to shift in the opposite - // direction to counter this. - return (float)-(oversample - 1) / (2.0f * (float)oversample); + // The prefilter is a box filter of width "oversample", + // which shifts phase by (oversample - 1)/2 pixels in + // oversampled space. We want to shift in the opposite + // direction to counter this. + return (float)-(oversample - 1) / (2.0f * (float)oversample); } STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) { - stbtt_fontinfo info; - float recip_h = 1.0f / spc->h_oversample; - float recip_v = 1.0f / spc->v_oversample; - float sub_x = stbtt__oversample_shift(spc->h_oversample); - float sub_y = stbtt__oversample_shift(spc->v_oversample); - int i,j,k,n, return_value = 1; - stbrp_context *context = (stbrp_context *) spc->pack_info; - stbrp_rect *rects; + stbtt_fontinfo info; + float recip_h = 1.0f / spc->h_oversample; + float recip_v = 1.0f / spc->v_oversample; + float sub_x = stbtt__oversample_shift(spc->h_oversample); + float sub_y = stbtt__oversample_shift(spc->v_oversample); + int i, j, k, n, return_value = 1; + stbrp_context *context = (stbrp_context *)spc->pack_info; + stbrp_rect *rects; - // flag all characters as NOT packed - for (i=0; i < num_ranges; ++i) - for (j=0; j < ranges[i].num_chars_in_range; ++j) - ranges[i].chardata_for_range[j].x0 = - ranges[i].chardata_for_range[j].y0 = - ranges[i].chardata_for_range[j].x1 = - ranges[i].chardata_for_range[j].y1 = 0; + // flag all characters as NOT packed + for (i = 0; i < num_ranges; ++i) + for (j = 0; j < ranges[i].num_chars_in_range; ++j) + ranges[i].chardata_for_range[j].x0 = + ranges[i].chardata_for_range[j].y0 = + ranges[i].chardata_for_range[j].x1 = + ranges[i].chardata_for_range[j].y1 = 0; - n = 0; - for (i=0; i < num_ranges; ++i) - n += ranges[i].num_chars_in_range; - - rects = (stbrp_rect *) STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context); - if (rects == NULL) - return 0; + n = 0; + for (i = 0; i < num_ranges; ++i) + n += ranges[i].num_chars_in_range; - stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index)); - k=0; - for (i=0; i < num_ranges; ++i) { - float fh = ranges[i].font_size; - float scale = fh > 0 ? stbtt_ScaleForPixelHeight(&info, fh) : stbtt_ScaleForMappingEmToPixels(&info, -fh); - for (j=0; j < ranges[i].num_chars_in_range; ++j) { - int x0,y0,x1,y1; - stbtt_GetCodepointBitmapBoxSubpixel(&info, ranges[i].first_unicode_char_in_range + j, - scale * spc->h_oversample, - scale * spc->v_oversample, - 0,0, - &x0,&y0,&x1,&y1); - rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1); - rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1); - ++k; - } - } + rects = (stbrp_rect *)STBTT_malloc(sizeof(*rects) * n, spc->user_allocator_context); + if (rects == NULL) + return 0; - stbrp_pack_rects(context, rects, k); + stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, font_index)); + k = 0; + for (i = 0; i < num_ranges; ++i) + { + float fh = ranges[i].font_size; + float scale = fh > 0 ? stbtt_ScaleForPixelHeight(&info, fh) : stbtt_ScaleForMappingEmToPixels(&info, -fh); + for (j = 0; j < ranges[i].num_chars_in_range; ++j) + { + int x0, y0, x1, y1; + stbtt_GetCodepointBitmapBoxSubpixel(&info, ranges[i].first_unicode_char_in_range + j, + scale * spc->h_oversample, + scale * spc->v_oversample, + 0, 0, + &x0, &y0, &x1, &y1); + rects[k].w = (stbrp_coord)(x1 - x0 + spc->padding + spc->h_oversample - 1); + rects[k].h = (stbrp_coord)(y1 - y0 + spc->padding + spc->v_oversample - 1); + ++k; + } + } - k = 0; - for (i=0; i < num_ranges; ++i) { - float fh = ranges[i].font_size; - float scale = fh > 0 ? stbtt_ScaleForPixelHeight(&info, fh) : stbtt_ScaleForMappingEmToPixels(&info, -fh); - for (j=0; j < ranges[i].num_chars_in_range; ++j) { - stbrp_rect *r = &rects[k]; - if (r->was_packed) { - stbtt_packedchar *bc = &ranges[i].chardata_for_range[j]; - int advance, lsb, x0,y0,x1,y1; - int glyph = stbtt_FindGlyphIndex(&info, ranges[i].first_unicode_char_in_range + j); - stbrp_coord pad = (stbrp_coord) spc->padding; + stbrp_pack_rects(context, rects, k); - // pad on left and top - r->x += pad; - r->y += pad; - r->w -= pad; - r->h -= pad; - stbtt_GetGlyphHMetrics(&info, glyph, &advance, &lsb); - stbtt_GetGlyphBitmapBox(&info, glyph, - scale * spc->h_oversample, - scale * spc->v_oversample, - &x0,&y0,&x1,&y1); - stbtt_MakeGlyphBitmapSubpixel(&info, - spc->pixels + r->x + r->y*spc->stride_in_bytes, - r->w - spc->h_oversample+1, - r->h - spc->v_oversample+1, - spc->stride_in_bytes, - scale * spc->h_oversample, - scale * spc->v_oversample, - 0,0, - glyph); + k = 0; + for (i = 0; i < num_ranges; ++i) + { + float fh = ranges[i].font_size; + float scale = fh > 0 ? stbtt_ScaleForPixelHeight(&info, fh) : stbtt_ScaleForMappingEmToPixels(&info, -fh); + for (j = 0; j < ranges[i].num_chars_in_range; ++j) + { + stbrp_rect *r = &rects[k]; + if (r->was_packed) + { + stbtt_packedchar *bc = &ranges[i].chardata_for_range[j]; + int advance, lsb, x0, y0, x1, y1; + int glyph = stbtt_FindGlyphIndex(&info, ranges[i].first_unicode_char_in_range + j); + stbrp_coord pad = (stbrp_coord)spc->padding; - if (spc->h_oversample > 1) - stbtt__h_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes, - r->w, r->h, spc->stride_in_bytes, - spc->h_oversample); + // pad on left and top + r->x += pad; + r->y += pad; + r->w -= pad; + r->h -= pad; + stbtt_GetGlyphHMetrics(&info, glyph, &advance, &lsb); + stbtt_GetGlyphBitmapBox(&info, glyph, + scale * spc->h_oversample, + scale * spc->v_oversample, + &x0, &y0, &x1, &y1); + stbtt_MakeGlyphBitmapSubpixel(&info, + spc->pixels + r->x + r->y * spc->stride_in_bytes, + r->w - spc->h_oversample + 1, + r->h - spc->v_oversample + 1, + spc->stride_in_bytes, + scale * spc->h_oversample, + scale * spc->v_oversample, + 0, 0, + glyph); - if (spc->v_oversample > 1) - stbtt__v_prefilter(spc->pixels + r->x + r->y*spc->stride_in_bytes, - r->w, r->h, spc->stride_in_bytes, - spc->v_oversample); + if (spc->h_oversample > 1) + stbtt__h_prefilter(spc->pixels + r->x + r->y * spc->stride_in_bytes, + r->w, r->h, spc->stride_in_bytes, + spc->h_oversample); - bc->x0 = (stbtt_int16) r->x; - bc->y0 = (stbtt_int16) r->y; - bc->x1 = (stbtt_int16) (r->x + r->w); - bc->y1 = (stbtt_int16) (r->y + r->h); - bc->xadvance = scale * advance; - bc->xoff = (float) x0 * recip_h + sub_x; - bc->yoff = (float) y0 * recip_v + sub_y; - bc->xoff2 = (x0 + r->w) * recip_h + sub_x; - bc->yoff2 = (y0 + r->h) * recip_v + sub_y; - } else { - return_value = 0; // if any fail, report failure - } + if (spc->v_oversample > 1) + stbtt__v_prefilter(spc->pixels + r->x + r->y * spc->stride_in_bytes, + r->w, r->h, spc->stride_in_bytes, + spc->v_oversample); - ++k; - } - } + bc->x0 = (stbtt_int16)r->x; + bc->y0 = (stbtt_int16)r->y; + bc->x1 = (stbtt_int16)(r->x + r->w); + bc->y1 = (stbtt_int16)(r->y + r->h); + bc->xadvance = scale * advance; + bc->xoff = (float)x0 * recip_h + sub_x; + bc->yoff = (float)y0 * recip_v + sub_y; + bc->xoff2 = (x0 + r->w) * recip_h + sub_x; + bc->yoff2 = (y0 + r->h) * recip_v + sub_y; + } + else + { + return_value = 0; // if any fail, report failure + } - STBTT_free(rects, spc->user_allocator_context); - return return_value; + ++k; + } + } + + STBTT_free(rects, spc->user_allocator_context); + return return_value; } STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, unsigned char *fontdata, int font_index, float font_size, - int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range) + int first_unicode_char_in_range, int num_chars_in_range, stbtt_packedchar *chardata_for_range) { - stbtt_pack_range range; - range.first_unicode_char_in_range = first_unicode_char_in_range; - range.num_chars_in_range = num_chars_in_range; - range.chardata_for_range = chardata_for_range; - range.font_size = font_size; - return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1); + stbtt_pack_range range; + range.first_unicode_char_in_range = first_unicode_char_in_range; + range.num_chars_in_range = num_chars_in_range; + range.chardata_for_range = chardata_for_range; + range.font_size = font_size; + return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1); } STBTT_DEF void stbtt_GetPackedQuad(stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer) { - float ipw = 1.0f / pw, iph = 1.0f / ph; - stbtt_packedchar *b = chardata + char_index; + float ipw = 1.0f / pw, iph = 1.0f / ph; + stbtt_packedchar *b = chardata + char_index; - if (align_to_integer) { - float x = (float) STBTT_ifloor((*xpos + b->xoff) + 0.5f); - float y = (float) STBTT_ifloor((*ypos + b->yoff) + 0.5f); - q->x0 = x; - q->y0 = y; - q->x1 = x + b->xoff2 - b->xoff; - q->y1 = y + b->yoff2 - b->yoff; - } else { - q->x0 = *xpos + b->xoff; - q->y0 = *ypos + b->yoff; - q->x1 = *xpos + b->xoff2; - q->y1 = *ypos + b->yoff2; - } + if (align_to_integer) + { + float x = (float)STBTT_ifloor((*xpos + b->xoff) + 0.5f); + float y = (float)STBTT_ifloor((*ypos + b->yoff) + 0.5f); + q->x0 = x; + q->y0 = y; + q->x1 = x + b->xoff2 - b->xoff; + q->y1 = y + b->yoff2 - b->yoff; + } + else + { + q->x0 = *xpos + b->xoff; + q->y0 = *ypos + b->yoff; + q->x1 = *xpos + b->xoff2; + q->y1 = *ypos + b->yoff2; + } - q->s0 = b->x0 * ipw; - q->t0 = b->y0 * iph; - q->s1 = b->x1 * ipw; - q->t1 = b->y1 * iph; + q->s0 = b->x0 * ipw; + q->t0 = b->y0 * iph; + q->s1 = b->x1 * ipw; + q->t1 = b->y1 * iph; - *xpos += b->xadvance; + *xpos += b->xadvance; } - ////////////////////////////////////////////////////////////////////////////// // // font name matching -- recommended not to use this // // check if a utf8 string contains a prefix which is the utf16 string; if so return length of matching utf8 string -static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8 *s1, stbtt_int32 len1, const stbtt_uint8 *s2, stbtt_int32 len2) +static stbtt_int32 stbtt__CompareUTF8toUTF16_bigendian_prefix(const stbtt_uint8 *s1, stbtt_int32 len1, const stbtt_uint8 *s2, stbtt_int32 len2) { - stbtt_int32 i=0; + stbtt_int32 i = 0; - // convert utf16 to utf8 and compare the results while converting - while (len2) { - stbtt_uint16 ch = s2[0]*256 + s2[1]; - if (ch < 0x80) { - if (i >= len1) return -1; - if (s1[i++] != ch) return -1; - } else if (ch < 0x800) { - if (i+1 >= len1) return -1; - if (s1[i++] != 0xc0 + (ch >> 6)) return -1; - if (s1[i++] != 0x80 + (ch & 0x3f)) return -1; - } else if (ch >= 0xd800 && ch < 0xdc00) { - stbtt_uint32 c; - stbtt_uint16 ch2 = s2[2]*256 + s2[3]; - if (i+3 >= len1) return -1; - c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000; - if (s1[i++] != 0xf0 + (c >> 18)) return -1; - if (s1[i++] != 0x80 + ((c >> 12) & 0x3f)) return -1; - if (s1[i++] != 0x80 + ((c >> 6) & 0x3f)) return -1; - if (s1[i++] != 0x80 + ((c ) & 0x3f)) return -1; - s2 += 2; // plus another 2 below - len2 -= 2; - } else if (ch >= 0xdc00 && ch < 0xe000) { - return -1; - } else { - if (i+2 >= len1) return -1; - if (s1[i++] != 0xe0 + (ch >> 12)) return -1; - if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f)) return -1; - if (s1[i++] != 0x80 + ((ch ) & 0x3f)) return -1; - } - s2 += 2; - len2 -= 2; - } - return i; + // convert utf16 to utf8 and compare the results while converting + while (len2) + { + stbtt_uint16 ch = s2[0] * 256 + s2[1]; + if (ch < 0x80) + { + if (i >= len1) return -1; + if (s1[i++] != ch) return -1; + } + else if (ch < 0x800) + { + if (i + 1 >= len1) return -1; + if (s1[i++] != 0xc0 + (ch >> 6)) return -1; + if (s1[i++] != 0x80 + (ch & 0x3f)) return -1; + } + else if (ch >= 0xd800 && ch < 0xdc00) + { + stbtt_uint32 c; + stbtt_uint16 ch2 = s2[2] * 256 + s2[3]; + if (i + 3 >= len1) return -1; + c = ((ch - 0xd800) << 10) + (ch2 - 0xdc00) + 0x10000; + if (s1[i++] != 0xf0 + (c >> 18)) return -1; + if (s1[i++] != 0x80 + ((c >> 12) & 0x3f)) return -1; + if (s1[i++] != 0x80 + ((c >> 6) & 0x3f)) return -1; + if (s1[i++] != 0x80 + ((c)&0x3f)) return -1; + s2 += 2; // plus another 2 below + len2 -= 2; + } + else if (ch >= 0xdc00 && ch < 0xe000) + { + return -1; + } + else + { + if (i + 2 >= len1) return -1; + if (s1[i++] != 0xe0 + (ch >> 12)) return -1; + if (s1[i++] != 0x80 + ((ch >> 6) & 0x3f)) return -1; + if (s1[i++] != 0x80 + ((ch)&0x3f)) return -1; + } + s2 += 2; + len2 -= 2; + } + return i; } -STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2) +STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const char *s2, int len2) { - return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((const stbtt_uint8*) s1, len1, (const stbtt_uint8*) s2, len2); + return len1 == stbtt__CompareUTF8toUTF16_bigendian_prefix((const stbtt_uint8 *)s1, len1, (const stbtt_uint8 *)s2, len2); } // returns results in whatever encoding you request... but note that 2-byte encodings // will be BIG-ENDIAN... use stbtt_CompareUTF8toUTF16_bigendian() to compare STBTT_DEF const char *stbtt_GetFontNameString(const stbtt_fontinfo *font, int *length, int platformID, int encodingID, int languageID, int nameID) { - stbtt_int32 i,count,stringOffset; - stbtt_uint8 *fc = font->data; - stbtt_uint32 offset = font->fontstart; - stbtt_uint32 nm = stbtt__find_table(fc, offset, "name"); - if (!nm) return NULL; + stbtt_int32 i, count, stringOffset; + stbtt_uint8 *fc = font->data; + stbtt_uint32 offset = font->fontstart; + stbtt_uint32 nm = stbtt__find_table(fc, offset, "name"); + if (!nm) return NULL; - count = ttUSHORT(fc+nm+2); - stringOffset = nm + ttUSHORT(fc+nm+4); - for (i=0; i < count; ++i) { - stbtt_uint32 loc = nm + 6 + 12 * i; - if (platformID == ttUSHORT(fc+loc+0) && encodingID == ttUSHORT(fc+loc+2) - && languageID == ttUSHORT(fc+loc+4) && nameID == ttUSHORT(fc+loc+6)) { - *length = ttUSHORT(fc+loc+8); - return (const char *) (fc+stringOffset+ttUSHORT(fc+loc+10)); - } - } - return NULL; + count = ttUSHORT(fc + nm + 2); + stringOffset = nm + ttUSHORT(fc + nm + 4); + for (i = 0; i < count; ++i) + { + stbtt_uint32 loc = nm + 6 + 12 * i; + if (platformID == ttUSHORT(fc + loc + 0) && encodingID == ttUSHORT(fc + loc + 2) && languageID == ttUSHORT(fc + loc + 4) && nameID == ttUSHORT(fc + loc + 6)) + { + *length = ttUSHORT(fc + loc + 8); + return (const char *)(fc + stringOffset + ttUSHORT(fc + loc + 10)); + } + } + return NULL; } static int stbtt__matchpair(stbtt_uint8 *fc, stbtt_uint32 nm, stbtt_uint8 *name, stbtt_int32 nlen, stbtt_int32 target_id, stbtt_int32 next_id) { - stbtt_int32 i; - stbtt_int32 count = ttUSHORT(fc+nm+2); - stbtt_int32 stringOffset = nm + ttUSHORT(fc+nm+4); + stbtt_int32 i; + stbtt_int32 count = ttUSHORT(fc + nm + 2); + stbtt_int32 stringOffset = nm + ttUSHORT(fc + nm + 4); - for (i=0; i < count; ++i) { - stbtt_uint32 loc = nm + 6 + 12 * i; - stbtt_int32 id = ttUSHORT(fc+loc+6); - if (id == target_id) { - // find the encoding - stbtt_int32 platform = ttUSHORT(fc+loc+0), encoding = ttUSHORT(fc+loc+2), language = ttUSHORT(fc+loc+4); + for (i = 0; i < count; ++i) + { + stbtt_uint32 loc = nm + 6 + 12 * i; + stbtt_int32 id = ttUSHORT(fc + loc + 6); + if (id == target_id) + { + // find the encoding + stbtt_int32 platform = ttUSHORT(fc + loc + 0), encoding = ttUSHORT(fc + loc + 2), language = ttUSHORT(fc + loc + 4); - // is this a Unicode encoding? - if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) { - stbtt_int32 slen = ttUSHORT(fc+loc+8); - stbtt_int32 off = ttUSHORT(fc+loc+10); + // is this a Unicode encoding? + if (platform == 0 || (platform == 3 && encoding == 1) || (platform == 3 && encoding == 10)) + { + stbtt_int32 slen = ttUSHORT(fc + loc + 8); + stbtt_int32 off = ttUSHORT(fc + loc + 10); - // check if there's a prefix match - stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc+stringOffset+off,slen); - if (matchlen >= 0) { - // check for target_id+1 immediately following, with same encoding & language - if (i+1 < count && ttUSHORT(fc+loc+12+6) == next_id && ttUSHORT(fc+loc+12) == platform && ttUSHORT(fc+loc+12+2) == encoding && ttUSHORT(fc+loc+12+4) == language) { - slen = ttUSHORT(fc+loc+12+8); - off = ttUSHORT(fc+loc+12+10); - if (slen == 0) { - if (matchlen == nlen) - return 1; - } else if (matchlen < nlen && name[matchlen] == ' ') { - ++matchlen; - if (stbtt_CompareUTF8toUTF16_bigendian((char*) (name+matchlen), nlen-matchlen, (char*)(fc+stringOffset+off),slen)) - return 1; - } - } else { - // if nothing immediately following - if (matchlen == nlen) - return 1; - } - } - } + // check if there's a prefix match + stbtt_int32 matchlen = stbtt__CompareUTF8toUTF16_bigendian_prefix(name, nlen, fc + stringOffset + off, slen); + if (matchlen >= 0) + { + // check for target_id+1 immediately following, with same encoding & language + if (i + 1 < count && ttUSHORT(fc + loc + 12 + 6) == next_id && ttUSHORT(fc + loc + 12) == platform && ttUSHORT(fc + loc + 12 + 2) == encoding && ttUSHORT(fc + loc + 12 + 4) == language) + { + slen = ttUSHORT(fc + loc + 12 + 8); + off = ttUSHORT(fc + loc + 12 + 10); + if (slen == 0) + { + if (matchlen == nlen) + return 1; + } + else if (matchlen < nlen && name[matchlen] == ' ') + { + ++matchlen; + if (stbtt_CompareUTF8toUTF16_bigendian((char *)(name + matchlen), nlen - matchlen, (char *)(fc + stringOffset + off), slen)) + return 1; + } + } + else + { + // if nothing immediately following + if (matchlen == nlen) + return 1; + } + } + } - // @TODO handle other encodings - } - } - return 0; + // @TODO handle other encodings + } + } + return 0; } static int stbtt__matches(stbtt_uint8 *fc, stbtt_uint32 offset, stbtt_uint8 *name, stbtt_int32 flags) { - stbtt_int32 nlen = (stbtt_int32) STBTT_strlen((char *) name); - stbtt_uint32 nm,hd; - if (!stbtt__isfont(fc+offset)) return 0; + stbtt_int32 nlen = (stbtt_int32)STBTT_strlen((char *)name); + stbtt_uint32 nm, hd; + if (!stbtt__isfont(fc + offset)) return 0; - // check italics/bold/underline flags in macStyle... - if (flags) { - hd = stbtt__find_table(fc, offset, "head"); - if ((ttUSHORT(fc+hd+44) & 7) != (flags & 7)) return 0; - } + // check italics/bold/underline flags in macStyle... + if (flags) + { + hd = stbtt__find_table(fc, offset, "head"); + if ((ttUSHORT(fc + hd + 44) & 7) != (flags & 7)) return 0; + } - nm = stbtt__find_table(fc, offset, "name"); - if (!nm) return 0; + nm = stbtt__find_table(fc, offset, "name"); + if (!nm) return 0; - if (flags) { - // if we checked the macStyle flags, then just check the family and ignore the subfamily - if (stbtt__matchpair(fc, nm, name, nlen, 16, -1)) return 1; - if (stbtt__matchpair(fc, nm, name, nlen, 1, -1)) return 1; - if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; - } else { - if (stbtt__matchpair(fc, nm, name, nlen, 16, 17)) return 1; - if (stbtt__matchpair(fc, nm, name, nlen, 1, 2)) return 1; - if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; - } + if (flags) + { + // if we checked the macStyle flags, then just check the family and ignore the subfamily + if (stbtt__matchpair(fc, nm, name, nlen, 16, -1)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 1, -1)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; + } + else + { + if (stbtt__matchpair(fc, nm, name, nlen, 16, 17)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 1, 2)) return 1; + if (stbtt__matchpair(fc, nm, name, nlen, 3, -1)) return 1; + } - return 0; + return 0; } STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const char *name_utf8, stbtt_int32 flags) { - stbtt_int32 i; - for (i=0;;++i) { - stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i); - if (off < 0) return off; - if (stbtt__matches((stbtt_uint8 *) font_collection, off, (stbtt_uint8*) name_utf8, flags)) - return off; - } + stbtt_int32 i; + for (i = 0;; ++i) + { + stbtt_int32 off = stbtt_GetFontOffsetForIndex(font_collection, i); + if (off < 0) return off; + if (stbtt__matches((stbtt_uint8 *)font_collection, off, (stbtt_uint8 *)name_utf8, flags)) + return off; + } } -#endif // STB_TRUETYPE_IMPLEMENTATION +#endif // STB_TRUETYPE_IMPLEMENTATION diff --git a/examples/ThirdPartyLibs/tinyxml2/tinyxml2.cpp b/examples/ThirdPartyLibs/tinyxml2/tinyxml2.cpp index b27612e90..d52784c25 100644 --- a/examples/ThirdPartyLibs/tinyxml2/tinyxml2.cpp +++ b/examples/ThirdPartyLibs/tinyxml2/tinyxml2.cpp @@ -23,90 +23,91 @@ distribution. #include "tinyxml2.h" -#include // yes, this one new style header, is in the Android SDK. +#include // yes, this one new style header, is in the Android SDK. #if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__) -# include -# include +#include +#include #else -# include -# include +#include +#include #endif -#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE) - // Microsoft Visual Studio, version 2005 and higher. Not WinCE. - /*int _snprintf_s( +#if defined(_MSC_VER) && (_MSC_VER >= 1400) && (!defined WINCE) +// Microsoft Visual Studio, version 2005 and higher. Not WinCE. +/*int _snprintf_s( char *buffer, size_t sizeOfBuffer, size_t count, const char *format [, argument] ... );*/ - static inline int TIXML_SNPRINTF( char* buffer, size_t size, const char* format, ... ) - { - va_list va; - va_start( va, format ); - int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va ); - va_end( va ); - return result; - } +static inline int TIXML_SNPRINTF(char* buffer, size_t size, const char* format, ...) +{ + va_list va; + va_start(va, format); + int result = vsnprintf_s(buffer, size, _TRUNCATE, format, va); + va_end(va); + return result; +} - static inline int TIXML_VSNPRINTF( char* buffer, size_t size, const char* format, va_list va ) - { - int result = vsnprintf_s( buffer, size, _TRUNCATE, format, va ); - return result; - } +static inline int TIXML_VSNPRINTF(char* buffer, size_t size, const char* format, va_list va) +{ + int result = vsnprintf_s(buffer, size, _TRUNCATE, format, va); + return result; +} - #define TIXML_VSCPRINTF _vscprintf - #define TIXML_SSCANF sscanf_s +#define TIXML_VSCPRINTF _vscprintf +#define TIXML_SSCANF sscanf_s #elif defined _MSC_VER - // Microsoft Visual Studio 2003 and earlier or WinCE - #define TIXML_SNPRINTF _snprintf - #define TIXML_VSNPRINTF _vsnprintf - #define TIXML_SSCANF sscanf - #if (_MSC_VER < 1400 ) && (!defined WINCE) - // Microsoft Visual Studio 2003 and not WinCE. - #define TIXML_VSCPRINTF _vscprintf // VS2003's C runtime has this, but VC6 C runtime or WinCE SDK doesn't have. - #else - // Microsoft Visual Studio 2003 and earlier or WinCE. - static inline int TIXML_VSCPRINTF( const char* format, va_list va ) - { - int len = 512; - for (;;) { - len = len*2; - char* str = new char[len](); - const int required = _vsnprintf(str, len, format, va); - delete[] str; - if ( required != -1 ) { - TIXMLASSERT( required >= 0 ); - len = required; - break; - } - } - TIXMLASSERT( len >= 0 ); - return len; - } - #endif +// Microsoft Visual Studio 2003 and earlier or WinCE +#define TIXML_SNPRINTF _snprintf +#define TIXML_VSNPRINTF _vsnprintf +#define TIXML_SSCANF sscanf +#if (_MSC_VER < 1400) && (!defined WINCE) +// Microsoft Visual Studio 2003 and not WinCE. +#define TIXML_VSCPRINTF _vscprintf // VS2003's C runtime has this, but VC6 C runtime or WinCE SDK doesn't have. #else - // GCC version 3 and higher - //#warning( "Using sn* functions." ) - #define TIXML_SNPRINTF snprintf - #define TIXML_VSNPRINTF vsnprintf - static inline int TIXML_VSCPRINTF( const char* format, va_list va ) +// Microsoft Visual Studio 2003 and earlier or WinCE. +static inline int TIXML_VSCPRINTF(const char* format, va_list va) +{ + int len = 512; + for (;;) { - int len = vsnprintf( 0, 0, format, va ); - TIXMLASSERT( len >= 0 ); - return len; + len = len * 2; + char* str = new char[len](); + const int required = _vsnprintf(str, len, format, va); + delete[] str; + if (required != -1) + { + TIXMLASSERT(required >= 0); + len = required; + break; + } } - #define TIXML_SSCANF sscanf + TIXMLASSERT(len >= 0); + return len; +} +#endif +#else +// GCC version 3 and higher +//#warning( "Using sn* functions." ) +#define TIXML_SNPRINTF snprintf +#define TIXML_VSNPRINTF vsnprintf +static inline int TIXML_VSCPRINTF(const char* format, va_list va) +{ + int len = vsnprintf(0, 0, format, va); + TIXMLASSERT(len >= 0); + return len; +} +#define TIXML_SSCANF sscanf #endif - -static const char LINE_FEED = (char)0x0a; // all line endings are normalized to LF +static const char LINE_FEED = (char)0x0a; // all line endings are normalized to LF static const char LF = LINE_FEED; -static const char CARRIAGE_RETURN = (char)0x0d; // CR gets filtered out +static const char CARRIAGE_RETURN = (char)0x0d; // CR gets filtered out static const char CR = CARRIAGE_RETURN; -static const char SINGLE_QUOTE = '\''; -static const char DOUBLE_QUOTE = '\"'; +static const char SINGLE_QUOTE = '\''; +static const char DOUBLE_QUOTE = '\"'; // Bunch of unicode info at: // http://www.unicode.org/faq/utf_bom.html @@ -118,664 +119,709 @@ static const unsigned char TIXML_UTF_LEAD_2 = 0xbfU; namespace tinyxml2 { - -struct Entity { - const char* pattern; - int length; - char value; +struct Entity +{ + const char* pattern; + int length; + char value; }; static const int NUM_ENTITIES = 5; static const Entity entities[NUM_ENTITIES] = { - { "quot", 4, DOUBLE_QUOTE }, - { "amp", 3, '&' }, - { "apos", 4, SINGLE_QUOTE }, - { "lt", 2, '<' }, - { "gt", 2, '>' } -}; - + {"quot", 4, DOUBLE_QUOTE}, + {"amp", 3, '&'}, + {"apos", 4, SINGLE_QUOTE}, + {"lt", 2, '<'}, + {"gt", 2, '>'}}; StrPair::~StrPair() { - Reset(); + Reset(); } - -void StrPair::TransferTo( StrPair* other ) +void StrPair::TransferTo(StrPair* other) { - if ( this == other ) { - return; - } - // This in effect implements the assignment operator by "moving" - // ownership (as in auto_ptr). + if (this == other) + { + return; + } + // This in effect implements the assignment operator by "moving" + // ownership (as in auto_ptr). - TIXMLASSERT( other != 0 ); - TIXMLASSERT( other->_flags == 0 ); - TIXMLASSERT( other->_start == 0 ); - TIXMLASSERT( other->_end == 0 ); + TIXMLASSERT(other != 0); + TIXMLASSERT(other->_flags == 0); + TIXMLASSERT(other->_start == 0); + TIXMLASSERT(other->_end == 0); - other->Reset(); + other->Reset(); - other->_flags = _flags; - other->_start = _start; - other->_end = _end; + other->_flags = _flags; + other->_start = _start; + other->_end = _end; - _flags = 0; - _start = 0; - _end = 0; + _flags = 0; + _start = 0; + _end = 0; } - void StrPair::Reset() { - if ( _flags & NEEDS_DELETE ) { - delete [] _start; - } - _flags = 0; - _start = 0; - _end = 0; + if (_flags & NEEDS_DELETE) + { + delete[] _start; + } + _flags = 0; + _start = 0; + _end = 0; } - -void StrPair::SetStr( const char* str, int flags ) +void StrPair::SetStr(const char* str, int flags) { - TIXMLASSERT( str ); - Reset(); - size_t len = strlen( str ); - TIXMLASSERT( _start == 0 ); - _start = new char[ len+1 ]; - memcpy( _start, str, len+1 ); - _end = _start + len; - _flags = flags | NEEDS_DELETE; + TIXMLASSERT(str); + Reset(); + size_t len = strlen(str); + TIXMLASSERT(_start == 0); + _start = new char[len + 1]; + memcpy(_start, str, len + 1); + _end = _start + len; + _flags = flags | NEEDS_DELETE; } - -char* StrPair::ParseText( char* p, const char* endTag, int strFlags, int* curLineNumPtr ) +char* StrPair::ParseText(char* p, const char* endTag, int strFlags, int* curLineNumPtr) { - TIXMLASSERT( p ); - TIXMLASSERT( endTag && *endTag ); + TIXMLASSERT(p); + TIXMLASSERT(endTag && *endTag); TIXMLASSERT(curLineNumPtr); - char* start = p; - char endChar = *endTag; - size_t length = strlen( endTag ); + char* start = p; + char endChar = *endTag; + size_t length = strlen(endTag); - // Inner loop of text parsing. - while ( *p ) { - if ( *p == endChar && strncmp( p, endTag, length ) == 0 ) { - Set( start, p, strFlags ); - return p + length; - } else if (*p == '\n') { - ++(*curLineNumPtr); - } - ++p; - TIXMLASSERT( p ); - } - return 0; + // Inner loop of text parsing. + while (*p) + { + if (*p == endChar && strncmp(p, endTag, length) == 0) + { + Set(start, p, strFlags); + return p + length; + } + else if (*p == '\n') + { + ++(*curLineNumPtr); + } + ++p; + TIXMLASSERT(p); + } + return 0; } - -char* StrPair::ParseName( char* p ) +char* StrPair::ParseName(char* p) { - if ( !p || !(*p) ) { - return 0; - } - if ( !XMLUtil::IsNameStartChar( *p ) ) { - return 0; - } + if (!p || !(*p)) + { + return 0; + } + if (!XMLUtil::IsNameStartChar(*p)) + { + return 0; + } - char* const start = p; - ++p; - while ( *p && XMLUtil::IsNameChar( *p ) ) { - ++p; - } + char* const start = p; + ++p; + while (*p && XMLUtil::IsNameChar(*p)) + { + ++p; + } - Set( start, p, 0 ); - return p; + Set(start, p, 0); + return p; } - void StrPair::CollapseWhitespace() { - // Adjusting _start would cause undefined behavior on delete[] - TIXMLASSERT( ( _flags & NEEDS_DELETE ) == 0 ); - // Trim leading space. - _start = XMLUtil::SkipWhiteSpace( _start, 0 ); + // Adjusting _start would cause undefined behavior on delete[] + TIXMLASSERT((_flags & NEEDS_DELETE) == 0); + // Trim leading space. + _start = XMLUtil::SkipWhiteSpace(_start, 0); - if ( *_start ) { - const char* p = _start; // the read pointer - char* q = _start; // the write pointer + if (*_start) + { + const char* p = _start; // the read pointer + char* q = _start; // the write pointer - while( *p ) { - if ( XMLUtil::IsWhiteSpace( *p )) { - p = XMLUtil::SkipWhiteSpace( p, 0 ); - if ( *p == 0 ) { - break; // don't write to q; this trims the trailing space. - } - *q = ' '; - ++q; - } - *q = *p; - ++q; - ++p; - } - *q = 0; - } + while (*p) + { + if (XMLUtil::IsWhiteSpace(*p)) + { + p = XMLUtil::SkipWhiteSpace(p, 0); + if (*p == 0) + { + break; // don't write to q; this trims the trailing space. + } + *q = ' '; + ++q; + } + *q = *p; + ++q; + ++p; + } + *q = 0; + } } - const char* StrPair::GetStr() { - TIXMLASSERT( _start ); - TIXMLASSERT( _end ); - if ( _flags & NEEDS_FLUSH ) { - *_end = 0; - _flags ^= NEEDS_FLUSH; + TIXMLASSERT(_start); + TIXMLASSERT(_end); + if (_flags & NEEDS_FLUSH) + { + *_end = 0; + _flags ^= NEEDS_FLUSH; - if ( _flags ) { - const char* p = _start; // the read pointer - char* q = _start; // the write pointer + if (_flags) + { + const char* p = _start; // the read pointer + char* q = _start; // the write pointer - while( p < _end ) { - if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == CR ) { - // CR-LF pair becomes LF - // CR alone becomes LF - // LF-CR becomes LF - if ( *(p+1) == LF ) { - p += 2; - } - else { - ++p; - } - *q = LF; - ++q; - } - else if ( (_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF ) { - if ( *(p+1) == CR ) { - p += 2; - } - else { - ++p; - } - *q = LF; - ++q; - } - else if ( (_flags & NEEDS_ENTITY_PROCESSING) && *p == '&' ) { - // Entities handled by tinyXML2: - // - special entities in the entity table [in/out] - // - numeric character reference [in] - // 中 or 中 + while (p < _end) + { + if ((_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == CR) + { + // CR-LF pair becomes LF + // CR alone becomes LF + // LF-CR becomes LF + if (*(p + 1) == LF) + { + p += 2; + } + else + { + ++p; + } + *q = LF; + ++q; + } + else if ((_flags & NEEDS_NEWLINE_NORMALIZATION) && *p == LF) + { + if (*(p + 1) == CR) + { + p += 2; + } + else + { + ++p; + } + *q = LF; + ++q; + } + else if ((_flags & NEEDS_ENTITY_PROCESSING) && *p == '&') + { + // Entities handled by tinyXML2: + // - special entities in the entity table [in/out] + // - numeric character reference [in] + // 中 or 中 - if ( *(p+1) == '#' ) { - const int buflen = 10; - char buf[buflen] = { 0 }; - int len = 0; - char* adjusted = const_cast( XMLUtil::GetCharacterRef( p, buf, &len ) ); - if ( adjusted == 0 ) { - *q = *p; - ++p; - ++q; - } - else { - TIXMLASSERT( 0 <= len && len <= buflen ); - TIXMLASSERT( q + len <= adjusted ); - p = adjusted; - memcpy( q, buf, len ); - q += len; - } - } - else { - bool entityFound = false; - for( int i = 0; i < NUM_ENTITIES; ++i ) { - const Entity& entity = entities[i]; - if ( strncmp( p + 1, entity.pattern, entity.length ) == 0 - && *( p + entity.length + 1 ) == ';' ) { - // Found an entity - convert. - *q = entity.value; - ++q; - p += entity.length + 2; - entityFound = true; - break; - } - } - if ( !entityFound ) { - // fixme: treat as error? - ++p; - ++q; - } - } - } - else { - *q = *p; - ++p; - ++q; - } - } - *q = 0; - } - // The loop below has plenty going on, and this - // is a less useful mode. Break it out. - if ( _flags & NEEDS_WHITESPACE_COLLAPSING ) { - CollapseWhitespace(); - } - _flags = (_flags & NEEDS_DELETE); - } - TIXMLASSERT( _start ); - return _start; + if (*(p + 1) == '#') + { + const int buflen = 10; + char buf[buflen] = {0}; + int len = 0; + char* adjusted = const_cast(XMLUtil::GetCharacterRef(p, buf, &len)); + if (adjusted == 0) + { + *q = *p; + ++p; + ++q; + } + else + { + TIXMLASSERT(0 <= len && len <= buflen); + TIXMLASSERT(q + len <= adjusted); + p = adjusted; + memcpy(q, buf, len); + q += len; + } + } + else + { + bool entityFound = false; + for (int i = 0; i < NUM_ENTITIES; ++i) + { + const Entity& entity = entities[i]; + if (strncmp(p + 1, entity.pattern, entity.length) == 0 && *(p + entity.length + 1) == ';') + { + // Found an entity - convert. + *q = entity.value; + ++q; + p += entity.length + 2; + entityFound = true; + break; + } + } + if (!entityFound) + { + // fixme: treat as error? + ++p; + ++q; + } + } + } + else + { + *q = *p; + ++p; + ++q; + } + } + *q = 0; + } + // The loop below has plenty going on, and this + // is a less useful mode. Break it out. + if (_flags & NEEDS_WHITESPACE_COLLAPSING) + { + CollapseWhitespace(); + } + _flags = (_flags & NEEDS_DELETE); + } + TIXMLASSERT(_start); + return _start; } - - - // --------- XMLUtil ----------- // -const char* XMLUtil::writeBoolTrue = "true"; +const char* XMLUtil::writeBoolTrue = "true"; const char* XMLUtil::writeBoolFalse = "false"; void XMLUtil::SetBoolSerialization(const char* writeTrue, const char* writeFalse) { - static const char* defTrue = "true"; + static const char* defTrue = "true"; static const char* defFalse = "false"; writeBoolTrue = (writeTrue) ? writeTrue : defTrue; writeBoolFalse = (writeFalse) ? writeFalse : defFalse; } - -const char* XMLUtil::ReadBOM( const char* p, bool* bom ) +const char* XMLUtil::ReadBOM(const char* p, bool* bom) { - TIXMLASSERT( p ); - TIXMLASSERT( bom ); - *bom = false; - const unsigned char* pu = reinterpret_cast(p); - // Check for BOM: - if ( *(pu+0) == TIXML_UTF_LEAD_0 - && *(pu+1) == TIXML_UTF_LEAD_1 - && *(pu+2) == TIXML_UTF_LEAD_2 ) { - *bom = true; - p += 3; - } - TIXMLASSERT( p ); - return p; + TIXMLASSERT(p); + TIXMLASSERT(bom); + *bom = false; + const unsigned char* pu = reinterpret_cast(p); + // Check for BOM: + if (*(pu + 0) == TIXML_UTF_LEAD_0 && *(pu + 1) == TIXML_UTF_LEAD_1 && *(pu + 2) == TIXML_UTF_LEAD_2) + { + *bom = true; + p += 3; + } + TIXMLASSERT(p); + return p; } - -void XMLUtil::ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ) +void XMLUtil::ConvertUTF32ToUTF8(unsigned long input, char* output, int* length) { - const unsigned long BYTE_MASK = 0xBF; - const unsigned long BYTE_MARK = 0x80; - const unsigned long FIRST_BYTE_MARK[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; + const unsigned long BYTE_MASK = 0xBF; + const unsigned long BYTE_MARK = 0x80; + const unsigned long FIRST_BYTE_MARK[7] = {0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC}; - if (input < 0x80) { - *length = 1; - } - else if ( input < 0x800 ) { - *length = 2; - } - else if ( input < 0x10000 ) { - *length = 3; - } - else if ( input < 0x200000 ) { - *length = 4; - } - else { - *length = 0; // This code won't convert this correctly anyway. - return; - } + if (input < 0x80) + { + *length = 1; + } + else if (input < 0x800) + { + *length = 2; + } + else if (input < 0x10000) + { + *length = 3; + } + else if (input < 0x200000) + { + *length = 4; + } + else + { + *length = 0; // This code won't convert this correctly anyway. + return; + } - output += *length; + output += *length; - // Scary scary fall throughs are annotated with carefully designed comments - // to suppress compiler warnings such as -Wimplicit-fallthrough in gcc - switch (*length) { - case 4: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - //fall through - case 3: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - //fall through - case 2: - --output; - *output = (char)((input | BYTE_MARK) & BYTE_MASK); - input >>= 6; - //fall through - case 1: - --output; - *output = (char)(input | FIRST_BYTE_MARK[*length]); - break; - default: - TIXMLASSERT( false ); - } + // Scary scary fall throughs are annotated with carefully designed comments + // to suppress compiler warnings such as -Wimplicit-fallthrough in gcc + switch (*length) + { + case 4: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + //fall through + case 3: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + //fall through + case 2: + --output; + *output = (char)((input | BYTE_MARK) & BYTE_MASK); + input >>= 6; + //fall through + case 1: + --output; + *output = (char)(input | FIRST_BYTE_MARK[*length]); + break; + default: + TIXMLASSERT(false); + } } - -const char* XMLUtil::GetCharacterRef( const char* p, char* value, int* length ) +const char* XMLUtil::GetCharacterRef(const char* p, char* value, int* length) { - // Presume an entity, and pull it out. - *length = 0; + // Presume an entity, and pull it out. + *length = 0; - if ( *(p+1) == '#' && *(p+2) ) { - unsigned long ucs = 0; - TIXMLASSERT( sizeof( ucs ) >= 4 ); - ptrdiff_t delta = 0; - unsigned mult = 1; - static const char SEMICOLON = ';'; + if (*(p + 1) == '#' && *(p + 2)) + { + unsigned long ucs = 0; + TIXMLASSERT(sizeof(ucs) >= 4); + ptrdiff_t delta = 0; + unsigned mult = 1; + static const char SEMICOLON = ';'; - if ( *(p+2) == 'x' ) { - // Hexadecimal. - const char* q = p+3; - if ( !(*q) ) { - return 0; - } + if (*(p + 2) == 'x') + { + // Hexadecimal. + const char* q = p + 3; + if (!(*q)) + { + return 0; + } - q = strchr( q, SEMICOLON ); + q = strchr(q, SEMICOLON); - if ( !q ) { - return 0; - } - TIXMLASSERT( *q == SEMICOLON ); + if (!q) + { + return 0; + } + TIXMLASSERT(*q == SEMICOLON); - delta = q-p; - --q; + delta = q - p; + --q; - while ( *q != 'x' ) { - unsigned int digit = 0; + while (*q != 'x') + { + unsigned int digit = 0; - if ( *q >= '0' && *q <= '9' ) { - digit = *q - '0'; - } - else if ( *q >= 'a' && *q <= 'f' ) { - digit = *q - 'a' + 10; - } - else if ( *q >= 'A' && *q <= 'F' ) { - digit = *q - 'A' + 10; - } - else { - return 0; - } - TIXMLASSERT( digit < 16 ); - TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit ); - const unsigned int digitScaled = mult * digit; - TIXMLASSERT( ucs <= ULONG_MAX - digitScaled ); - ucs += digitScaled; - TIXMLASSERT( mult <= UINT_MAX / 16 ); - mult *= 16; - --q; - } - } - else { - // Decimal. - const char* q = p+2; - if ( !(*q) ) { - return 0; - } + if (*q >= '0' && *q <= '9') + { + digit = *q - '0'; + } + else if (*q >= 'a' && *q <= 'f') + { + digit = *q - 'a' + 10; + } + else if (*q >= 'A' && *q <= 'F') + { + digit = *q - 'A' + 10; + } + else + { + return 0; + } + TIXMLASSERT(digit < 16); + TIXMLASSERT(digit == 0 || mult <= UINT_MAX / digit); + const unsigned int digitScaled = mult * digit; + TIXMLASSERT(ucs <= ULONG_MAX - digitScaled); + ucs += digitScaled; + TIXMLASSERT(mult <= UINT_MAX / 16); + mult *= 16; + --q; + } + } + else + { + // Decimal. + const char* q = p + 2; + if (!(*q)) + { + return 0; + } - q = strchr( q, SEMICOLON ); + q = strchr(q, SEMICOLON); - if ( !q ) { - return 0; - } - TIXMLASSERT( *q == SEMICOLON ); + if (!q) + { + return 0; + } + TIXMLASSERT(*q == SEMICOLON); - delta = q-p; - --q; + delta = q - p; + --q; - while ( *q != '#' ) { - if ( *q >= '0' && *q <= '9' ) { - const unsigned int digit = *q - '0'; - TIXMLASSERT( digit < 10 ); - TIXMLASSERT( digit == 0 || mult <= UINT_MAX / digit ); - const unsigned int digitScaled = mult * digit; - TIXMLASSERT( ucs <= ULONG_MAX - digitScaled ); - ucs += digitScaled; - } - else { - return 0; - } - TIXMLASSERT( mult <= UINT_MAX / 10 ); - mult *= 10; - --q; - } - } - // convert the UCS to UTF-8 - ConvertUTF32ToUTF8( ucs, value, length ); - return p + delta + 1; - } - return p+1; + while (*q != '#') + { + if (*q >= '0' && *q <= '9') + { + const unsigned int digit = *q - '0'; + TIXMLASSERT(digit < 10); + TIXMLASSERT(digit == 0 || mult <= UINT_MAX / digit); + const unsigned int digitScaled = mult * digit; + TIXMLASSERT(ucs <= ULONG_MAX - digitScaled); + ucs += digitScaled; + } + else + { + return 0; + } + TIXMLASSERT(mult <= UINT_MAX / 10); + mult *= 10; + --q; + } + } + // convert the UCS to UTF-8 + ConvertUTF32ToUTF8(ucs, value, length); + return p + delta + 1; + } + return p + 1; } - -void XMLUtil::ToStr( int v, char* buffer, int bufferSize ) +void XMLUtil::ToStr(int v, char* buffer, int bufferSize) { - TIXML_SNPRINTF( buffer, bufferSize, "%d", v ); + TIXML_SNPRINTF(buffer, bufferSize, "%d", v); } - -void XMLUtil::ToStr( unsigned v, char* buffer, int bufferSize ) +void XMLUtil::ToStr(unsigned v, char* buffer, int bufferSize) { - TIXML_SNPRINTF( buffer, bufferSize, "%u", v ); + TIXML_SNPRINTF(buffer, bufferSize, "%u", v); } - -void XMLUtil::ToStr( bool v, char* buffer, int bufferSize ) +void XMLUtil::ToStr(bool v, char* buffer, int bufferSize) { - TIXML_SNPRINTF( buffer, bufferSize, "%s", v ? writeBoolTrue : writeBoolFalse); + TIXML_SNPRINTF(buffer, bufferSize, "%s", v ? writeBoolTrue : writeBoolFalse); } /* ToStr() of a number is a very tricky topic. https://github.com/leethomason/tinyxml2/issues/106 */ -void XMLUtil::ToStr( float v, char* buffer, int bufferSize ) +void XMLUtil::ToStr(float v, char* buffer, int bufferSize) { - TIXML_SNPRINTF( buffer, bufferSize, "%.8g", v ); + TIXML_SNPRINTF(buffer, bufferSize, "%.8g", v); } - -void XMLUtil::ToStr( double v, char* buffer, int bufferSize ) +void XMLUtil::ToStr(double v, char* buffer, int bufferSize) { - TIXML_SNPRINTF( buffer, bufferSize, "%.17g", v ); + TIXML_SNPRINTF(buffer, bufferSize, "%.17g", v); } - void XMLUtil::ToStr(int64_t v, char* buffer, int bufferSize) { // horrible syntax trick to make the compiler happy about %lld TIXML_SNPRINTF(buffer, bufferSize, "%lld", (long long)v); } - -bool XMLUtil::ToInt( const char* str, int* value ) +bool XMLUtil::ToInt(const char* str, int* value) { - if ( TIXML_SSCANF( str, "%d", value ) == 1 ) { - return true; - } - return false; + if (TIXML_SSCANF(str, "%d", value) == 1) + { + return true; + } + return false; } -bool XMLUtil::ToUnsigned( const char* str, unsigned *value ) +bool XMLUtil::ToUnsigned(const char* str, unsigned* value) { - if ( TIXML_SSCANF( str, "%u", value ) == 1 ) { - return true; - } - return false; + if (TIXML_SSCANF(str, "%u", value) == 1) + { + return true; + } + return false; } -bool XMLUtil::ToBool( const char* str, bool* value ) +bool XMLUtil::ToBool(const char* str, bool* value) { - int ival = 0; - if ( ToInt( str, &ival )) { - *value = (ival==0) ? false : true; - return true; - } - if ( StringEqual( str, "true" ) ) { - *value = true; - return true; - } - else if ( StringEqual( str, "false" ) ) { - *value = false; - return true; - } - return false; + int ival = 0; + if (ToInt(str, &ival)) + { + *value = (ival == 0) ? false : true; + return true; + } + if (StringEqual(str, "true")) + { + *value = true; + return true; + } + else if (StringEqual(str, "false")) + { + *value = false; + return true; + } + return false; } - -bool XMLUtil::ToFloat( const char* str, float* value ) +bool XMLUtil::ToFloat(const char* str, float* value) { - if ( TIXML_SSCANF( str, "%f", value ) == 1 ) { - return true; - } - return false; + if (TIXML_SSCANF(str, "%f", value) == 1) + { + return true; + } + return false; } - -bool XMLUtil::ToDouble( const char* str, double* value ) +bool XMLUtil::ToDouble(const char* str, double* value) { - if ( TIXML_SSCANF( str, "%lf", value ) == 1 ) { - return true; - } - return false; + if (TIXML_SSCANF(str, "%lf", value) == 1) + { + return true; + } + return false; } - bool XMLUtil::ToInt64(const char* str, int64_t* value) { - long long v = 0; // horrible syntax trick to make the compiler happy about %lld - if (TIXML_SSCANF(str, "%lld", &v) == 1) { + long long v = 0; // horrible syntax trick to make the compiler happy about %lld + if (TIXML_SSCANF(str, "%lld", &v) == 1) + { *value = (int64_t)v; return true; } return false; } - -char* XMLDocument::Identify( char* p, XMLNode** node ) +char* XMLDocument::Identify(char* p, XMLNode** node) { - TIXMLASSERT( node ); - TIXMLASSERT( p ); - char* const start = p; - int const startLine = _parseCurLineNum; - p = XMLUtil::SkipWhiteSpace( p, &_parseCurLineNum ); - if( !*p ) { - *node = 0; - TIXMLASSERT( p ); - return p; - } + TIXMLASSERT(node); + TIXMLASSERT(p); + char* const start = p; + int const startLine = _parseCurLineNum; + p = XMLUtil::SkipWhiteSpace(p, &_parseCurLineNum); + if (!*p) + { + *node = 0; + TIXMLASSERT(p); + return p; + } - // These strings define the matching patterns: - static const char* xmlHeader = { "( _commentPool ); - returnNode->_parseLineNum = _parseCurLineNum; - p += xmlHeaderLen; - } - else if ( XMLUtil::StringEqual( p, commentHeader, commentHeaderLen ) ) { - returnNode = CreateUnlinkedNode( _commentPool ); - returnNode->_parseLineNum = _parseCurLineNum; - p += commentHeaderLen; - } - else if ( XMLUtil::StringEqual( p, cdataHeader, cdataHeaderLen ) ) { - XMLText* text = CreateUnlinkedNode( _textPool ); - returnNode = text; - returnNode->_parseLineNum = _parseCurLineNum; - p += cdataHeaderLen; - text->SetCData( true ); - } - else if ( XMLUtil::StringEqual( p, dtdHeader, dtdHeaderLen ) ) { - returnNode = CreateUnlinkedNode( _commentPool ); - returnNode->_parseLineNum = _parseCurLineNum; - p += dtdHeaderLen; - } - else if ( XMLUtil::StringEqual( p, elementHeader, elementHeaderLen ) ) { - returnNode = CreateUnlinkedNode( _elementPool ); - returnNode->_parseLineNum = _parseCurLineNum; - p += elementHeaderLen; - } - else { - returnNode = CreateUnlinkedNode( _textPool ); - returnNode->_parseLineNum = _parseCurLineNum; // Report line of first non-whitespace character - p = start; // Back it up, all the text counts. - _parseCurLineNum = startLine; - } + TIXMLASSERT(sizeof(XMLComment) == sizeof(XMLUnknown)); // use same memory pool + TIXMLASSERT(sizeof(XMLComment) == sizeof(XMLDeclaration)); // use same memory pool + XMLNode* returnNode = 0; + if (XMLUtil::StringEqual(p, xmlHeader, xmlHeaderLen)) + { + returnNode = CreateUnlinkedNode(_commentPool); + returnNode->_parseLineNum = _parseCurLineNum; + p += xmlHeaderLen; + } + else if (XMLUtil::StringEqual(p, commentHeader, commentHeaderLen)) + { + returnNode = CreateUnlinkedNode(_commentPool); + returnNode->_parseLineNum = _parseCurLineNum; + p += commentHeaderLen; + } + else if (XMLUtil::StringEqual(p, cdataHeader, cdataHeaderLen)) + { + XMLText* text = CreateUnlinkedNode(_textPool); + returnNode = text; + returnNode->_parseLineNum = _parseCurLineNum; + p += cdataHeaderLen; + text->SetCData(true); + } + else if (XMLUtil::StringEqual(p, dtdHeader, dtdHeaderLen)) + { + returnNode = CreateUnlinkedNode(_commentPool); + returnNode->_parseLineNum = _parseCurLineNum; + p += dtdHeaderLen; + } + else if (XMLUtil::StringEqual(p, elementHeader, elementHeaderLen)) + { + returnNode = CreateUnlinkedNode(_elementPool); + returnNode->_parseLineNum = _parseCurLineNum; + p += elementHeaderLen; + } + else + { + returnNode = CreateUnlinkedNode(_textPool); + returnNode->_parseLineNum = _parseCurLineNum; // Report line of first non-whitespace character + p = start; // Back it up, all the text counts. + _parseCurLineNum = startLine; + } - TIXMLASSERT( returnNode ); - TIXMLASSERT( p ); - *node = returnNode; - return p; + TIXMLASSERT(returnNode); + TIXMLASSERT(p); + *node = returnNode; + return p; } - -bool XMLDocument::Accept( XMLVisitor* visitor ) const +bool XMLDocument::Accept(XMLVisitor* visitor) const { - TIXMLASSERT( visitor ); - if ( visitor->VisitEnter( *this ) ) { - for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) { - if ( !node->Accept( visitor ) ) { - break; - } - } - } - return visitor->VisitExit( *this ); + TIXMLASSERT(visitor); + if (visitor->VisitEnter(*this)) + { + for (const XMLNode* node = FirstChild(); node; node = node->NextSibling()) + { + if (!node->Accept(visitor)) + { + break; + } + } + } + return visitor->VisitExit(*this); } - // --------- XMLNode ----------- // -XMLNode::XMLNode( XMLDocument* doc ) : - _document( doc ), - _parent( 0 ), - _value(), - _parseLineNum( 0 ), - _firstChild( 0 ), _lastChild( 0 ), - _prev( 0 ), _next( 0 ), - _userData( 0 ), - _memPool( 0 ) +XMLNode::XMLNode(XMLDocument* doc) : _document(doc), + _parent(0), + _value(), + _parseLineNum(0), + _firstChild(0), + _lastChild(0), + _prev(0), + _next(0), + _userData(0), + _memPool(0) { } - XMLNode::~XMLNode() { - DeleteChildren(); - if ( _parent ) { - _parent->Unlink( this ); - } + DeleteChildren(); + if (_parent) + { + _parent->Unlink(this); + } } const char* XMLNode::Value() const { - // Edge case: XMLDocuments don't have a Value. Return null. - if ( this->ToDocument() ) - return 0; - return _value.GetStr(); + // Edge case: XMLDocuments don't have a Value. Return null. + if (this->ToDocument()) + return 0; + return _value.GetStr(); } -void XMLNode::SetValue( const char* str, bool staticMem ) +void XMLNode::SetValue(const char* str, bool staticMem) { - if ( staticMem ) { - _value.SetInternedStr( str ); - } - else { - _value.SetStr( str ); - } + if (staticMem) + { + _value.SetInternedStr(str); + } + else + { + _value.SetStr(str); + } } XMLNode* XMLNode::DeepClone(XMLDocument* target) const @@ -783,7 +829,8 @@ XMLNode* XMLNode::DeepClone(XMLDocument* target) const XMLNode* clone = this->ShallowClone(target); if (!clone) return 0; - for (const XMLNode* child = this->FirstChild(); child; child = child->NextSibling()) { + for (const XMLNode* child = this->FirstChild(); child; child = child->NextSibling()) + { XMLNode* childClone = child->DeepClone(target); TIXMLASSERT(childClone); clone->InsertEndChild(childClone); @@ -793,665 +840,691 @@ XMLNode* XMLNode::DeepClone(XMLDocument* target) const void XMLNode::DeleteChildren() { - while( _firstChild ) { - TIXMLASSERT( _lastChild ); - DeleteChild( _firstChild ); - } - _firstChild = _lastChild = 0; + while (_firstChild) + { + TIXMLASSERT(_lastChild); + DeleteChild(_firstChild); + } + _firstChild = _lastChild = 0; } - -void XMLNode::Unlink( XMLNode* child ) +void XMLNode::Unlink(XMLNode* child) { - TIXMLASSERT( child ); - TIXMLASSERT( child->_document == _document ); - TIXMLASSERT( child->_parent == this ); - if ( child == _firstChild ) { - _firstChild = _firstChild->_next; - } - if ( child == _lastChild ) { - _lastChild = _lastChild->_prev; - } + TIXMLASSERT(child); + TIXMLASSERT(child->_document == _document); + TIXMLASSERT(child->_parent == this); + if (child == _firstChild) + { + _firstChild = _firstChild->_next; + } + if (child == _lastChild) + { + _lastChild = _lastChild->_prev; + } - if ( child->_prev ) { - child->_prev->_next = child->_next; - } - if ( child->_next ) { - child->_next->_prev = child->_prev; - } + if (child->_prev) + { + child->_prev->_next = child->_next; + } + if (child->_next) + { + child->_next->_prev = child->_prev; + } child->_next = 0; child->_prev = 0; child->_parent = 0; } - -void XMLNode::DeleteChild( XMLNode* node ) +void XMLNode::DeleteChild(XMLNode* node) { - TIXMLASSERT( node ); - TIXMLASSERT( node->_document == _document ); - TIXMLASSERT( node->_parent == this ); - Unlink( node ); + TIXMLASSERT(node); + TIXMLASSERT(node->_document == _document); + TIXMLASSERT(node->_parent == this); + Unlink(node); TIXMLASSERT(node->_prev == 0); TIXMLASSERT(node->_next == 0); TIXMLASSERT(node->_parent == 0); - DeleteNode( node ); + DeleteNode(node); } - -XMLNode* XMLNode::InsertEndChild( XMLNode* addThis ) +XMLNode* XMLNode::InsertEndChild(XMLNode* addThis) { - TIXMLASSERT( addThis ); - if ( addThis->_document != _document ) { - TIXMLASSERT( false ); - return 0; - } - InsertChildPreamble( addThis ); + TIXMLASSERT(addThis); + if (addThis->_document != _document) + { + TIXMLASSERT(false); + return 0; + } + InsertChildPreamble(addThis); - if ( _lastChild ) { - TIXMLASSERT( _firstChild ); - TIXMLASSERT( _lastChild->_next == 0 ); - _lastChild->_next = addThis; - addThis->_prev = _lastChild; - _lastChild = addThis; + if (_lastChild) + { + TIXMLASSERT(_firstChild); + TIXMLASSERT(_lastChild->_next == 0); + _lastChild->_next = addThis; + addThis->_prev = _lastChild; + _lastChild = addThis; - addThis->_next = 0; - } - else { - TIXMLASSERT( _firstChild == 0 ); - _firstChild = _lastChild = addThis; + addThis->_next = 0; + } + else + { + TIXMLASSERT(_firstChild == 0); + _firstChild = _lastChild = addThis; - addThis->_prev = 0; - addThis->_next = 0; - } - addThis->_parent = this; - return addThis; + addThis->_prev = 0; + addThis->_next = 0; + } + addThis->_parent = this; + return addThis; } - -XMLNode* XMLNode::InsertFirstChild( XMLNode* addThis ) +XMLNode* XMLNode::InsertFirstChild(XMLNode* addThis) { - TIXMLASSERT( addThis ); - if ( addThis->_document != _document ) { - TIXMLASSERT( false ); - return 0; - } - InsertChildPreamble( addThis ); + TIXMLASSERT(addThis); + if (addThis->_document != _document) + { + TIXMLASSERT(false); + return 0; + } + InsertChildPreamble(addThis); - if ( _firstChild ) { - TIXMLASSERT( _lastChild ); - TIXMLASSERT( _firstChild->_prev == 0 ); + if (_firstChild) + { + TIXMLASSERT(_lastChild); + TIXMLASSERT(_firstChild->_prev == 0); - _firstChild->_prev = addThis; - addThis->_next = _firstChild; - _firstChild = addThis; + _firstChild->_prev = addThis; + addThis->_next = _firstChild; + _firstChild = addThis; - addThis->_prev = 0; - } - else { - TIXMLASSERT( _lastChild == 0 ); - _firstChild = _lastChild = addThis; + addThis->_prev = 0; + } + else + { + TIXMLASSERT(_lastChild == 0); + _firstChild = _lastChild = addThis; - addThis->_prev = 0; - addThis->_next = 0; - } - addThis->_parent = this; - return addThis; + addThis->_prev = 0; + addThis->_next = 0; + } + addThis->_parent = this; + return addThis; } - -XMLNode* XMLNode::InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ) +XMLNode* XMLNode::InsertAfterChild(XMLNode* afterThis, XMLNode* addThis) { - TIXMLASSERT( addThis ); - if ( addThis->_document != _document ) { - TIXMLASSERT( false ); - return 0; - } + TIXMLASSERT(addThis); + if (addThis->_document != _document) + { + TIXMLASSERT(false); + return 0; + } - TIXMLASSERT( afterThis ); + TIXMLASSERT(afterThis); - if ( afterThis->_parent != this ) { - TIXMLASSERT( false ); - return 0; - } - if ( afterThis == addThis ) { - // Current state: BeforeThis -> AddThis -> OneAfterAddThis - // Now AddThis must disappear from it's location and then - // reappear between BeforeThis and OneAfterAddThis. - // So just leave it where it is. - return addThis; - } + if (afterThis->_parent != this) + { + TIXMLASSERT(false); + return 0; + } + if (afterThis == addThis) + { + // Current state: BeforeThis -> AddThis -> OneAfterAddThis + // Now AddThis must disappear from it's location and then + // reappear between BeforeThis and OneAfterAddThis. + // So just leave it where it is. + return addThis; + } - if ( afterThis->_next == 0 ) { - // The last node or the only node. - return InsertEndChild( addThis ); - } - InsertChildPreamble( addThis ); - addThis->_prev = afterThis; - addThis->_next = afterThis->_next; - afterThis->_next->_prev = addThis; - afterThis->_next = addThis; - addThis->_parent = this; - return addThis; + if (afterThis->_next == 0) + { + // The last node or the only node. + return InsertEndChild(addThis); + } + InsertChildPreamble(addThis); + addThis->_prev = afterThis; + addThis->_next = afterThis->_next; + afterThis->_next->_prev = addThis; + afterThis->_next = addThis; + addThis->_parent = this; + return addThis; } - - - -const XMLElement* XMLNode::FirstChildElement( const char* name ) const +const XMLElement* XMLNode::FirstChildElement(const char* name) const { - for( const XMLNode* node = _firstChild; node; node = node->_next ) { - const XMLElement* element = node->ToElementWithName( name ); - if ( element ) { - return element; - } - } - return 0; + for (const XMLNode* node = _firstChild; node; node = node->_next) + { + const XMLElement* element = node->ToElementWithName(name); + if (element) + { + return element; + } + } + return 0; } - -const XMLElement* XMLNode::LastChildElement( const char* name ) const +const XMLElement* XMLNode::LastChildElement(const char* name) const { - for( const XMLNode* node = _lastChild; node; node = node->_prev ) { - const XMLElement* element = node->ToElementWithName( name ); - if ( element ) { - return element; - } - } - return 0; + for (const XMLNode* node = _lastChild; node; node = node->_prev) + { + const XMLElement* element = node->ToElementWithName(name); + if (element) + { + return element; + } + } + return 0; } - -const XMLElement* XMLNode::NextSiblingElement( const char* name ) const +const XMLElement* XMLNode::NextSiblingElement(const char* name) const { - for( const XMLNode* node = _next; node; node = node->_next ) { - const XMLElement* element = node->ToElementWithName( name ); - if ( element ) { - return element; - } - } - return 0; + for (const XMLNode* node = _next; node; node = node->_next) + { + const XMLElement* element = node->ToElementWithName(name); + if (element) + { + return element; + } + } + return 0; } - -const XMLElement* XMLNode::PreviousSiblingElement( const char* name ) const +const XMLElement* XMLNode::PreviousSiblingElement(const char* name) const { - for( const XMLNode* node = _prev; node; node = node->_prev ) { - const XMLElement* element = node->ToElementWithName( name ); - if ( element ) { - return element; - } - } - return 0; + for (const XMLNode* node = _prev; node; node = node->_prev) + { + const XMLElement* element = node->ToElementWithName(name); + if (element) + { + return element; + } + } + return 0; } - -char* XMLNode::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) +char* XMLNode::ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr) { - // This is a recursive method, but thinking about it "at the current level" - // it is a pretty simple flat list: - // - // - // - // With a special case: - // - // - // - // - // Where the closing element (/foo) *must* be the next thing after the opening - // element, and the names must match. BUT the tricky bit is that the closing - // element will be read by the child. - // - // 'endTag' is the end tag for this node, it is returned by a call to a child. - // 'parentEnd' is the end tag for the parent, which is filled in and returned. + // This is a recursive method, but thinking about it "at the current level" + // it is a pretty simple flat list: + // + // + // + // With a special case: + // + // + // + // + // Where the closing element (/foo) *must* be the next thing after the opening + // element, and the names must match. BUT the tricky bit is that the closing + // element will be read by the child. + // + // 'endTag' is the end tag for this node, it is returned by a call to a child. + // 'parentEnd' is the end tag for the parent, which is filled in and returned. XMLDocument::DepthTracker tracker(_document); if (_document->Error()) return 0; - while( p && *p ) { - XMLNode* node = 0; + while (p && *p) + { + XMLNode* node = 0; - p = _document->Identify( p, &node ); - TIXMLASSERT( p ); - if ( node == 0 ) { - break; - } + p = _document->Identify(p, &node); + TIXMLASSERT(p); + if (node == 0) + { + break; + } - int initialLineNum = node->_parseLineNum; + int initialLineNum = node->_parseLineNum; - StrPair endTag; - p = node->ParseDeep( p, &endTag, curLineNumPtr ); - if ( !p ) { - DeleteNode( node ); - if ( !_document->Error() ) { - _document->SetError( XML_ERROR_PARSING, initialLineNum, 0); - } - break; - } + StrPair endTag; + p = node->ParseDeep(p, &endTag, curLineNumPtr); + if (!p) + { + DeleteNode(node); + if (!_document->Error()) + { + _document->SetError(XML_ERROR_PARSING, initialLineNum, 0); + } + break; + } - XMLDeclaration* decl = node->ToDeclaration(); - if ( decl ) { - // Declarations are only allowed at document level - bool wellLocated = ( ToDocument() != 0 ); - if ( wellLocated ) { - // Multiple declarations are allowed but all declarations - // must occur before anything else - for ( const XMLNode* existingNode = _document->FirstChild(); existingNode; existingNode = existingNode->NextSibling() ) { - if ( !existingNode->ToDeclaration() ) { - wellLocated = false; - break; - } - } - } - if ( !wellLocated ) { - _document->SetError( XML_ERROR_PARSING_DECLARATION, initialLineNum, "XMLDeclaration value=%s", decl->Value()); - DeleteNode( node ); - break; - } - } + XMLDeclaration* decl = node->ToDeclaration(); + if (decl) + { + // Declarations are only allowed at document level + bool wellLocated = (ToDocument() != 0); + if (wellLocated) + { + // Multiple declarations are allowed but all declarations + // must occur before anything else + for (const XMLNode* existingNode = _document->FirstChild(); existingNode; existingNode = existingNode->NextSibling()) + { + if (!existingNode->ToDeclaration()) + { + wellLocated = false; + break; + } + } + } + if (!wellLocated) + { + _document->SetError(XML_ERROR_PARSING_DECLARATION, initialLineNum, "XMLDeclaration value=%s", decl->Value()); + DeleteNode(node); + break; + } + } - XMLElement* ele = node->ToElement(); - if ( ele ) { - // We read the end tag. Return it to the parent. - if ( ele->ClosingType() == XMLElement::CLOSING ) { - if ( parentEndTag ) { - ele->_value.TransferTo( parentEndTag ); - } - node->_memPool->SetTracked(); // created and then immediately deleted. - DeleteNode( node ); - return p; - } + XMLElement* ele = node->ToElement(); + if (ele) + { + // We read the end tag. Return it to the parent. + if (ele->ClosingType() == XMLElement::CLOSING) + { + if (parentEndTag) + { + ele->_value.TransferTo(parentEndTag); + } + node->_memPool->SetTracked(); // created and then immediately deleted. + DeleteNode(node); + return p; + } - // Handle an end tag returned to this level. - // And handle a bunch of annoying errors. - bool mismatch = false; - if ( endTag.Empty() ) { - if ( ele->ClosingType() == XMLElement::OPEN ) { - mismatch = true; - } - } - else { - if ( ele->ClosingType() != XMLElement::OPEN ) { - mismatch = true; - } - else if ( !XMLUtil::StringEqual( endTag.GetStr(), ele->Name() ) ) { - mismatch = true; - } - } - if ( mismatch ) { - _document->SetError( XML_ERROR_MISMATCHED_ELEMENT, initialLineNum, "XMLElement name=%s", ele->Name()); - DeleteNode( node ); - break; - } - } - InsertEndChild( node ); - } - return 0; + // Handle an end tag returned to this level. + // And handle a bunch of annoying errors. + bool mismatch = false; + if (endTag.Empty()) + { + if (ele->ClosingType() == XMLElement::OPEN) + { + mismatch = true; + } + } + else + { + if (ele->ClosingType() != XMLElement::OPEN) + { + mismatch = true; + } + else if (!XMLUtil::StringEqual(endTag.GetStr(), ele->Name())) + { + mismatch = true; + } + } + if (mismatch) + { + _document->SetError(XML_ERROR_MISMATCHED_ELEMENT, initialLineNum, "XMLElement name=%s", ele->Name()); + DeleteNode(node); + break; + } + } + InsertEndChild(node); + } + return 0; } -/*static*/ void XMLNode::DeleteNode( XMLNode* node ) +/*static*/ void XMLNode::DeleteNode(XMLNode* node) { - if ( node == 0 ) { - return; - } + if (node == 0) + { + return; + } TIXMLASSERT(node->_document); - if (!node->ToDocument()) { + if (!node->ToDocument()) + { node->_document->MarkInUse(node); } - MemPool* pool = node->_memPool; - node->~XMLNode(); - pool->Free( node ); + MemPool* pool = node->_memPool; + node->~XMLNode(); + pool->Free(node); } -void XMLNode::InsertChildPreamble( XMLNode* insertThis ) const +void XMLNode::InsertChildPreamble(XMLNode* insertThis) const { - TIXMLASSERT( insertThis ); - TIXMLASSERT( insertThis->_document == _document ); + TIXMLASSERT(insertThis); + TIXMLASSERT(insertThis->_document == _document); - if (insertThis->_parent) { - insertThis->_parent->Unlink( insertThis ); + if (insertThis->_parent) + { + insertThis->_parent->Unlink(insertThis); } - else { + else + { insertThis->_document->MarkInUse(insertThis); - insertThis->_memPool->SetTracked(); + insertThis->_memPool->SetTracked(); } } -const XMLElement* XMLNode::ToElementWithName( const char* name ) const +const XMLElement* XMLNode::ToElementWithName(const char* name) const { - const XMLElement* element = this->ToElement(); - if ( element == 0 ) { - return 0; - } - if ( name == 0 ) { - return element; - } - if ( XMLUtil::StringEqual( element->Name(), name ) ) { - return element; - } - return 0; + const XMLElement* element = this->ToElement(); + if (element == 0) + { + return 0; + } + if (name == 0) + { + return element; + } + if (XMLUtil::StringEqual(element->Name(), name)) + { + return element; + } + return 0; } // --------- XMLText ---------- // -char* XMLText::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) +char* XMLText::ParseDeep(char* p, StrPair*, int* curLineNumPtr) { - if ( this->CData() ) { - p = _value.ParseText( p, "]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr ); - if ( !p ) { - _document->SetError( XML_ERROR_PARSING_CDATA, _parseLineNum, 0 ); - } - return p; - } - else { - int flags = _document->ProcessEntities() ? StrPair::TEXT_ELEMENT : StrPair::TEXT_ELEMENT_LEAVE_ENTITIES; - if ( _document->WhitespaceMode() == COLLAPSE_WHITESPACE ) { - flags |= StrPair::NEEDS_WHITESPACE_COLLAPSING; - } + if (this->CData()) + { + p = _value.ParseText(p, "]]>", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr); + if (!p) + { + _document->SetError(XML_ERROR_PARSING_CDATA, _parseLineNum, 0); + } + return p; + } + else + { + int flags = _document->ProcessEntities() ? StrPair::TEXT_ELEMENT : StrPair::TEXT_ELEMENT_LEAVE_ENTITIES; + if (_document->WhitespaceMode() == COLLAPSE_WHITESPACE) + { + flags |= StrPair::NEEDS_WHITESPACE_COLLAPSING; + } - p = _value.ParseText( p, "<", flags, curLineNumPtr ); - if ( p && *p ) { - return p-1; - } - if ( !p ) { - _document->SetError( XML_ERROR_PARSING_TEXT, _parseLineNum, 0 ); - } - } - return 0; + p = _value.ParseText(p, "<", flags, curLineNumPtr); + if (p && *p) + { + return p - 1; + } + if (!p) + { + _document->SetError(XML_ERROR_PARSING_TEXT, _parseLineNum, 0); + } + } + return 0; } - -XMLNode* XMLText::ShallowClone( XMLDocument* doc ) const +XMLNode* XMLText::ShallowClone(XMLDocument* doc) const { - if ( !doc ) { - doc = _document; - } - XMLText* text = doc->NewText( Value() ); // fixme: this will always allocate memory. Intern? - text->SetCData( this->CData() ); - return text; + if (!doc) + { + doc = _document; + } + XMLText* text = doc->NewText(Value()); // fixme: this will always allocate memory. Intern? + text->SetCData(this->CData()); + return text; } - -bool XMLText::ShallowEqual( const XMLNode* compare ) const +bool XMLText::ShallowEqual(const XMLNode* compare) const { - TIXMLASSERT( compare ); - const XMLText* text = compare->ToText(); - return ( text && XMLUtil::StringEqual( text->Value(), Value() ) ); + TIXMLASSERT(compare); + const XMLText* text = compare->ToText(); + return (text && XMLUtil::StringEqual(text->Value(), Value())); } - -bool XMLText::Accept( XMLVisitor* visitor ) const +bool XMLText::Accept(XMLVisitor* visitor) const { - TIXMLASSERT( visitor ); - return visitor->Visit( *this ); + TIXMLASSERT(visitor); + return visitor->Visit(*this); } - // --------- XMLComment ---------- // -XMLComment::XMLComment( XMLDocument* doc ) : XMLNode( doc ) +XMLComment::XMLComment(XMLDocument* doc) : XMLNode(doc) { } - XMLComment::~XMLComment() { } - -char* XMLComment::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) +char* XMLComment::ParseDeep(char* p, StrPair*, int* curLineNumPtr) { - // Comment parses as text. - p = _value.ParseText( p, "-->", StrPair::COMMENT, curLineNumPtr ); - if ( p == 0 ) { - _document->SetError( XML_ERROR_PARSING_COMMENT, _parseLineNum, 0 ); - } - return p; + // Comment parses as text. + p = _value.ParseText(p, "-->", StrPair::COMMENT, curLineNumPtr); + if (p == 0) + { + _document->SetError(XML_ERROR_PARSING_COMMENT, _parseLineNum, 0); + } + return p; } - -XMLNode* XMLComment::ShallowClone( XMLDocument* doc ) const +XMLNode* XMLComment::ShallowClone(XMLDocument* doc) const { - if ( !doc ) { - doc = _document; - } - XMLComment* comment = doc->NewComment( Value() ); // fixme: this will always allocate memory. Intern? - return comment; + if (!doc) + { + doc = _document; + } + XMLComment* comment = doc->NewComment(Value()); // fixme: this will always allocate memory. Intern? + return comment; } - -bool XMLComment::ShallowEqual( const XMLNode* compare ) const +bool XMLComment::ShallowEqual(const XMLNode* compare) const { - TIXMLASSERT( compare ); - const XMLComment* comment = compare->ToComment(); - return ( comment && XMLUtil::StringEqual( comment->Value(), Value() )); + TIXMLASSERT(compare); + const XMLComment* comment = compare->ToComment(); + return (comment && XMLUtil::StringEqual(comment->Value(), Value())); } - -bool XMLComment::Accept( XMLVisitor* visitor ) const +bool XMLComment::Accept(XMLVisitor* visitor) const { - TIXMLASSERT( visitor ); - return visitor->Visit( *this ); + TIXMLASSERT(visitor); + return visitor->Visit(*this); } - // --------- XMLDeclaration ---------- // -XMLDeclaration::XMLDeclaration( XMLDocument* doc ) : XMLNode( doc ) +XMLDeclaration::XMLDeclaration(XMLDocument* doc) : XMLNode(doc) { } - XMLDeclaration::~XMLDeclaration() { - //printf( "~XMLDeclaration\n" ); + //printf( "~XMLDeclaration\n" ); } - -char* XMLDeclaration::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) +char* XMLDeclaration::ParseDeep(char* p, StrPair*, int* curLineNumPtr) { - // Declaration parses as text. - p = _value.ParseText( p, "?>", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr ); - if ( p == 0 ) { - _document->SetError( XML_ERROR_PARSING_DECLARATION, _parseLineNum, 0 ); - } - return p; + // Declaration parses as text. + p = _value.ParseText(p, "?>", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr); + if (p == 0) + { + _document->SetError(XML_ERROR_PARSING_DECLARATION, _parseLineNum, 0); + } + return p; } - -XMLNode* XMLDeclaration::ShallowClone( XMLDocument* doc ) const +XMLNode* XMLDeclaration::ShallowClone(XMLDocument* doc) const { - if ( !doc ) { - doc = _document; - } - XMLDeclaration* dec = doc->NewDeclaration( Value() ); // fixme: this will always allocate memory. Intern? - return dec; + if (!doc) + { + doc = _document; + } + XMLDeclaration* dec = doc->NewDeclaration(Value()); // fixme: this will always allocate memory. Intern? + return dec; } - -bool XMLDeclaration::ShallowEqual( const XMLNode* compare ) const +bool XMLDeclaration::ShallowEqual(const XMLNode* compare) const { - TIXMLASSERT( compare ); - const XMLDeclaration* declaration = compare->ToDeclaration(); - return ( declaration && XMLUtil::StringEqual( declaration->Value(), Value() )); + TIXMLASSERT(compare); + const XMLDeclaration* declaration = compare->ToDeclaration(); + return (declaration && XMLUtil::StringEqual(declaration->Value(), Value())); } - - -bool XMLDeclaration::Accept( XMLVisitor* visitor ) const +bool XMLDeclaration::Accept(XMLVisitor* visitor) const { - TIXMLASSERT( visitor ); - return visitor->Visit( *this ); + TIXMLASSERT(visitor); + return visitor->Visit(*this); } // --------- XMLUnknown ---------- // -XMLUnknown::XMLUnknown( XMLDocument* doc ) : XMLNode( doc ) +XMLUnknown::XMLUnknown(XMLDocument* doc) : XMLNode(doc) { } - XMLUnknown::~XMLUnknown() { } - -char* XMLUnknown::ParseDeep( char* p, StrPair*, int* curLineNumPtr ) +char* XMLUnknown::ParseDeep(char* p, StrPair*, int* curLineNumPtr) { - // Unknown parses as text. - p = _value.ParseText( p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr ); - if ( !p ) { - _document->SetError( XML_ERROR_PARSING_UNKNOWN, _parseLineNum, 0 ); - } - return p; + // Unknown parses as text. + p = _value.ParseText(p, ">", StrPair::NEEDS_NEWLINE_NORMALIZATION, curLineNumPtr); + if (!p) + { + _document->SetError(XML_ERROR_PARSING_UNKNOWN, _parseLineNum, 0); + } + return p; } - -XMLNode* XMLUnknown::ShallowClone( XMLDocument* doc ) const +XMLNode* XMLUnknown::ShallowClone(XMLDocument* doc) const { - if ( !doc ) { - doc = _document; - } - XMLUnknown* text = doc->NewUnknown( Value() ); // fixme: this will always allocate memory. Intern? - return text; + if (!doc) + { + doc = _document; + } + XMLUnknown* text = doc->NewUnknown(Value()); // fixme: this will always allocate memory. Intern? + return text; } - -bool XMLUnknown::ShallowEqual( const XMLNode* compare ) const +bool XMLUnknown::ShallowEqual(const XMLNode* compare) const { - TIXMLASSERT( compare ); - const XMLUnknown* unknown = compare->ToUnknown(); - return ( unknown && XMLUtil::StringEqual( unknown->Value(), Value() )); + TIXMLASSERT(compare); + const XMLUnknown* unknown = compare->ToUnknown(); + return (unknown && XMLUtil::StringEqual(unknown->Value(), Value())); } - -bool XMLUnknown::Accept( XMLVisitor* visitor ) const +bool XMLUnknown::Accept(XMLVisitor* visitor) const { - TIXMLASSERT( visitor ); - return visitor->Visit( *this ); + TIXMLASSERT(visitor); + return visitor->Visit(*this); } // --------- XMLAttribute ---------- // const char* XMLAttribute::Name() const { - return _name.GetStr(); + return _name.GetStr(); } const char* XMLAttribute::Value() const { - return _value.GetStr(); + return _value.GetStr(); } -char* XMLAttribute::ParseDeep( char* p, bool processEntities, int* curLineNumPtr ) +char* XMLAttribute::ParseDeep(char* p, bool processEntities, int* curLineNumPtr) { - // Parse using the name rules: bug fix, was using ParseText before - p = _name.ParseName( p ); - if ( !p || !*p ) { - return 0; - } + // Parse using the name rules: bug fix, was using ParseText before + p = _name.ParseName(p); + if (!p || !*p) + { + return 0; + } - // Skip white space before = - p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); - if ( *p != '=' ) { - return 0; - } + // Skip white space before = + p = XMLUtil::SkipWhiteSpace(p, curLineNumPtr); + if (*p != '=') + { + return 0; + } - ++p; // move up to opening quote - p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); - if ( *p != '\"' && *p != '\'' ) { - return 0; - } + ++p; // move up to opening quote + p = XMLUtil::SkipWhiteSpace(p, curLineNumPtr); + if (*p != '\"' && *p != '\'') + { + return 0; + } - char endTag[2] = { *p, 0 }; - ++p; // move past opening quote + char endTag[2] = {*p, 0}; + ++p; // move past opening quote - p = _value.ParseText( p, endTag, processEntities ? StrPair::ATTRIBUTE_VALUE : StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES, curLineNumPtr ); - return p; + p = _value.ParseText(p, endTag, processEntities ? StrPair::ATTRIBUTE_VALUE : StrPair::ATTRIBUTE_VALUE_LEAVE_ENTITIES, curLineNumPtr); + return p; } - -void XMLAttribute::SetName( const char* n ) +void XMLAttribute::SetName(const char* n) { - _name.SetStr( n ); + _name.SetStr(n); } - -XMLError XMLAttribute::QueryIntValue( int* value ) const +XMLError XMLAttribute::QueryIntValue(int* value) const { - if ( XMLUtil::ToInt( Value(), value )) { - return XML_SUCCESS; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryUnsignedValue( unsigned int* value ) const -{ - if ( XMLUtil::ToUnsigned( Value(), value )) { - return XML_SUCCESS; - } - return XML_WRONG_ATTRIBUTE_TYPE; -} - - -XMLError XMLAttribute::QueryInt64Value(int64_t* value) const -{ - if (XMLUtil::ToInt64(Value(), value)) { + if (XMLUtil::ToInt(Value(), value)) + { return XML_SUCCESS; } return XML_WRONG_ATTRIBUTE_TYPE; } - -XMLError XMLAttribute::QueryBoolValue( bool* value ) const +XMLError XMLAttribute::QueryUnsignedValue(unsigned int* value) const { - if ( XMLUtil::ToBool( Value(), value )) { - return XML_SUCCESS; - } - return XML_WRONG_ATTRIBUTE_TYPE; + if (XMLUtil::ToUnsigned(Value(), value)) + { + return XML_SUCCESS; + } + return XML_WRONG_ATTRIBUTE_TYPE; } - -XMLError XMLAttribute::QueryFloatValue( float* value ) const +XMLError XMLAttribute::QueryInt64Value(int64_t* value) const { - if ( XMLUtil::ToFloat( Value(), value )) { - return XML_SUCCESS; - } - return XML_WRONG_ATTRIBUTE_TYPE; + if (XMLUtil::ToInt64(Value(), value)) + { + return XML_SUCCESS; + } + return XML_WRONG_ATTRIBUTE_TYPE; } - -XMLError XMLAttribute::QueryDoubleValue( double* value ) const +XMLError XMLAttribute::QueryBoolValue(bool* value) const { - if ( XMLUtil::ToDouble( Value(), value )) { - return XML_SUCCESS; - } - return XML_WRONG_ATTRIBUTE_TYPE; + if (XMLUtil::ToBool(Value(), value)) + { + return XML_SUCCESS; + } + return XML_WRONG_ATTRIBUTE_TYPE; } - -void XMLAttribute::SetAttribute( const char* v ) +XMLError XMLAttribute::QueryFloatValue(float* value) const { - _value.SetStr( v ); + if (XMLUtil::ToFloat(Value(), value)) + { + return XML_SUCCESS; + } + return XML_WRONG_ATTRIBUTE_TYPE; } - -void XMLAttribute::SetAttribute( int v ) +XMLError XMLAttribute::QueryDoubleValue(double* value) const { - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); + if (XMLUtil::ToDouble(Value(), value)) + { + return XML_SUCCESS; + } + return XML_WRONG_ATTRIBUTE_TYPE; } - -void XMLAttribute::SetAttribute( unsigned v ) +void XMLAttribute::SetAttribute(const char* v) { - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); + _value.SetStr(v); } +void XMLAttribute::SetAttribute(int v) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + _value.SetStr(buf); +} + +void XMLAttribute::SetAttribute(unsigned v) +{ + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + _value.SetStr(buf); +} void XMLAttribute::SetAttribute(int64_t v) { @@ -1460,69 +1533,68 @@ void XMLAttribute::SetAttribute(int64_t v) _value.SetStr(buf); } - - -void XMLAttribute::SetAttribute( bool v ) +void XMLAttribute::SetAttribute(bool v) { - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + _value.SetStr(buf); } -void XMLAttribute::SetAttribute( double v ) +void XMLAttribute::SetAttribute(double v) { - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + _value.SetStr(buf); } -void XMLAttribute::SetAttribute( float v ) +void XMLAttribute::SetAttribute(float v) { - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - _value.SetStr( buf ); + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + _value.SetStr(buf); } - // --------- XMLElement ---------- // -XMLElement::XMLElement( XMLDocument* doc ) : XMLNode( doc ), - _closingType( OPEN ), - _rootAttribute( 0 ) +XMLElement::XMLElement(XMLDocument* doc) : XMLNode(doc), + _closingType(OPEN), + _rootAttribute(0) { } - XMLElement::~XMLElement() { - while( _rootAttribute ) { - XMLAttribute* next = _rootAttribute->_next; - DeleteAttribute( _rootAttribute ); - _rootAttribute = next; - } + while (_rootAttribute) + { + XMLAttribute* next = _rootAttribute->_next; + DeleteAttribute(_rootAttribute); + _rootAttribute = next; + } } - -const XMLAttribute* XMLElement::FindAttribute( const char* name ) const +const XMLAttribute* XMLElement::FindAttribute(const char* name) const { - for( XMLAttribute* a = _rootAttribute; a; a = a->_next ) { - if ( XMLUtil::StringEqual( a->Name(), name ) ) { - return a; - } - } - return 0; + for (XMLAttribute* a = _rootAttribute; a; a = a->_next) + { + if (XMLUtil::StringEqual(a->Name(), name)) + { + return a; + } + } + return 0; } - -const char* XMLElement::Attribute( const char* name, const char* value ) const +const char* XMLElement::Attribute(const char* name, const char* value) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return 0; - } - if ( !value || XMLUtil::StringEqual( a->Value(), value )) { - return a->Value(); - } - return 0; + const XMLAttribute* a = FindAttribute(name); + if (!a) + { + return 0; + } + if (!value || XMLUtil::StringEqual(a->Value(), value)) + { + return a->Value(); + } + return 0; } int XMLElement::IntAttribute(const char* name, int defaultValue) const @@ -1569,40 +1641,38 @@ float XMLElement::FloatAttribute(const char* name, float defaultValue) const const char* XMLElement::GetText() const { - if ( FirstChild() && FirstChild()->ToText() ) { - return FirstChild()->Value(); - } - return 0; + if (FirstChild() && FirstChild()->ToText()) + { + return FirstChild()->Value(); + } + return 0; } - -void XMLElement::SetText( const char* inText ) +void XMLElement::SetText(const char* inText) { - if ( FirstChild() && FirstChild()->ToText() ) - FirstChild()->SetValue( inText ); - else { - XMLText* theText = GetDocument()->NewText( inText ); - InsertFirstChild( theText ); + if (FirstChild() && FirstChild()->ToText()) + FirstChild()->SetValue(inText); + else + { + XMLText* theText = GetDocument()->NewText(inText); + InsertFirstChild(theText); } } - -void XMLElement::SetText( int v ) +void XMLElement::SetText(int v) { - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - SetText( buf ); + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + SetText(buf); } - -void XMLElement::SetText( unsigned v ) +void XMLElement::SetText(unsigned v) { - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - SetText( buf ); + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + SetText(buf); } - void XMLElement::SetText(int64_t v) { char buf[BUF_SIZE]; @@ -1610,62 +1680,34 @@ void XMLElement::SetText(int64_t v) SetText(buf); } - -void XMLElement::SetText( bool v ) +void XMLElement::SetText(bool v) { - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - SetText( buf ); + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + SetText(buf); } - -void XMLElement::SetText( float v ) +void XMLElement::SetText(float v) { - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - SetText( buf ); + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + SetText(buf); } - -void XMLElement::SetText( double v ) +void XMLElement::SetText(double v) { - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - SetText( buf ); + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + SetText(buf); } - -XMLError XMLElement::QueryIntText( int* ival ) const +XMLError XMLElement::QueryIntText(int* ival) const { - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->Value(); - if ( XMLUtil::ToInt( t, ival ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryUnsignedText( unsigned* uval ) const -{ - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->Value(); - if ( XMLUtil::ToUnsigned( t, uval ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; -} - - -XMLError XMLElement::QueryInt64Text(int64_t* ival) const -{ - if (FirstChild() && FirstChild()->ToText()) { + if (FirstChild() && FirstChild()->ToText()) + { const char* t = FirstChild()->Value(); - if (XMLUtil::ToInt64(t, ival)) { + if (XMLUtil::ToInt(t, ival)) + { return XML_SUCCESS; } return XML_CAN_NOT_CONVERT_TEXT; @@ -1673,43 +1715,74 @@ XMLError XMLElement::QueryInt64Text(int64_t* ival) const return XML_NO_TEXT_NODE; } - -XMLError XMLElement::QueryBoolText( bool* bval ) const +XMLError XMLElement::QueryUnsignedText(unsigned* uval) const { - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->Value(); - if ( XMLUtil::ToBool( t, bval ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; + if (FirstChild() && FirstChild()->ToText()) + { + const char* t = FirstChild()->Value(); + if (XMLUtil::ToUnsigned(t, uval)) + { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; } - -XMLError XMLElement::QueryDoubleText( double* dval ) const +XMLError XMLElement::QueryInt64Text(int64_t* ival) const { - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->Value(); - if ( XMLUtil::ToDouble( t, dval ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; + if (FirstChild() && FirstChild()->ToText()) + { + const char* t = FirstChild()->Value(); + if (XMLUtil::ToInt64(t, ival)) + { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; } - -XMLError XMLElement::QueryFloatText( float* fval ) const +XMLError XMLElement::QueryBoolText(bool* bval) const { - if ( FirstChild() && FirstChild()->ToText() ) { - const char* t = FirstChild()->Value(); - if ( XMLUtil::ToFloat( t, fval ) ) { - return XML_SUCCESS; - } - return XML_CAN_NOT_CONVERT_TEXT; - } - return XML_NO_TEXT_NODE; + if (FirstChild() && FirstChild()->ToText()) + { + const char* t = FirstChild()->Value(); + if (XMLUtil::ToBool(t, bval)) + { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + +XMLError XMLElement::QueryDoubleText(double* dval) const +{ + if (FirstChild() && FirstChild()->ToText()) + { + const char* t = FirstChild()->Value(); + if (XMLUtil::ToDouble(t, dval)) + { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; +} + +XMLError XMLElement::QueryFloatText(float* fval) const +{ + if (FirstChild() && FirstChild()->ToText()) + { + const char* t = FirstChild()->Value(); + if (XMLUtil::ToFloat(t, fval)) + { + return XML_SUCCESS; + } + return XML_CAN_NOT_CONVERT_TEXT; + } + return XML_NO_TEXT_NODE; } int XMLElement::IntText(int defaultValue) const @@ -1754,282 +1827,301 @@ float XMLElement::FloatText(float defaultValue) const return f; } - -XMLAttribute* XMLElement::FindOrCreateAttribute( const char* name ) +XMLAttribute* XMLElement::FindOrCreateAttribute(const char* name) { - XMLAttribute* last = 0; - XMLAttribute* attrib = 0; - for( attrib = _rootAttribute; - attrib; - last = attrib, attrib = attrib->_next ) { - if ( XMLUtil::StringEqual( attrib->Name(), name ) ) { - break; - } - } - if ( !attrib ) { - attrib = CreateAttribute(); - TIXMLASSERT( attrib ); - if ( last ) { - TIXMLASSERT( last->_next == 0 ); - last->_next = attrib; - } - else { - TIXMLASSERT( _rootAttribute == 0 ); - _rootAttribute = attrib; - } - attrib->SetName( name ); - } - return attrib; + XMLAttribute* last = 0; + XMLAttribute* attrib = 0; + for (attrib = _rootAttribute; + attrib; + last = attrib, attrib = attrib->_next) + { + if (XMLUtil::StringEqual(attrib->Name(), name)) + { + break; + } + } + if (!attrib) + { + attrib = CreateAttribute(); + TIXMLASSERT(attrib); + if (last) + { + TIXMLASSERT(last->_next == 0); + last->_next = attrib; + } + else + { + TIXMLASSERT(_rootAttribute == 0); + _rootAttribute = attrib; + } + attrib->SetName(name); + } + return attrib; } - -void XMLElement::DeleteAttribute( const char* name ) +void XMLElement::DeleteAttribute(const char* name) { - XMLAttribute* prev = 0; - for( XMLAttribute* a=_rootAttribute; a; a=a->_next ) { - if ( XMLUtil::StringEqual( name, a->Name() ) ) { - if ( prev ) { - prev->_next = a->_next; - } - else { - _rootAttribute = a->_next; - } - DeleteAttribute( a ); - break; - } - prev = a; - } + XMLAttribute* prev = 0; + for (XMLAttribute* a = _rootAttribute; a; a = a->_next) + { + if (XMLUtil::StringEqual(name, a->Name())) + { + if (prev) + { + prev->_next = a->_next; + } + else + { + _rootAttribute = a->_next; + } + DeleteAttribute(a); + break; + } + prev = a; + } } - -char* XMLElement::ParseAttributes( char* p, int* curLineNumPtr ) +char* XMLElement::ParseAttributes(char* p, int* curLineNumPtr) { - XMLAttribute* prevAttribute = 0; + XMLAttribute* prevAttribute = 0; - // Read the attributes. - while( p ) { - p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); - if ( !(*p) ) { - _document->SetError( XML_ERROR_PARSING_ELEMENT, _parseLineNum, "XMLElement name=%s", Name() ); - return 0; - } + // Read the attributes. + while (p) + { + p = XMLUtil::SkipWhiteSpace(p, curLineNumPtr); + if (!(*p)) + { + _document->SetError(XML_ERROR_PARSING_ELEMENT, _parseLineNum, "XMLElement name=%s", Name()); + return 0; + } - // attribute. - if (XMLUtil::IsNameStartChar( *p ) ) { - XMLAttribute* attrib = CreateAttribute(); - TIXMLASSERT( attrib ); - attrib->_parseLineNum = _document->_parseCurLineNum; + // attribute. + if (XMLUtil::IsNameStartChar(*p)) + { + XMLAttribute* attrib = CreateAttribute(); + TIXMLASSERT(attrib); + attrib->_parseLineNum = _document->_parseCurLineNum; - int attrLineNum = attrib->_parseLineNum; + int attrLineNum = attrib->_parseLineNum; - p = attrib->ParseDeep( p, _document->ProcessEntities(), curLineNumPtr ); - if ( !p || Attribute( attrib->Name() ) ) { - DeleteAttribute( attrib ); - _document->SetError( XML_ERROR_PARSING_ATTRIBUTE, attrLineNum, "XMLElement name=%s", Name() ); - return 0; - } - // There is a minor bug here: if the attribute in the source xml - // document is duplicated, it will not be detected and the - // attribute will be doubly added. However, tracking the 'prevAttribute' - // avoids re-scanning the attribute list. Preferring performance for - // now, may reconsider in the future. - if ( prevAttribute ) { - TIXMLASSERT( prevAttribute->_next == 0 ); - prevAttribute->_next = attrib; - } - else { - TIXMLASSERT( _rootAttribute == 0 ); - _rootAttribute = attrib; - } - prevAttribute = attrib; - } - // end of the tag - else if ( *p == '>' ) { - ++p; - break; - } - // end of the tag - else if ( *p == '/' && *(p+1) == '>' ) { - _closingType = CLOSED; - return p+2; // done; sealed element. - } - else { - _document->SetError( XML_ERROR_PARSING_ELEMENT, _parseLineNum, 0 ); - return 0; - } - } - return p; + p = attrib->ParseDeep(p, _document->ProcessEntities(), curLineNumPtr); + if (!p || Attribute(attrib->Name())) + { + DeleteAttribute(attrib); + _document->SetError(XML_ERROR_PARSING_ATTRIBUTE, attrLineNum, "XMLElement name=%s", Name()); + return 0; + } + // There is a minor bug here: if the attribute in the source xml + // document is duplicated, it will not be detected and the + // attribute will be doubly added. However, tracking the 'prevAttribute' + // avoids re-scanning the attribute list. Preferring performance for + // now, may reconsider in the future. + if (prevAttribute) + { + TIXMLASSERT(prevAttribute->_next == 0); + prevAttribute->_next = attrib; + } + else + { + TIXMLASSERT(_rootAttribute == 0); + _rootAttribute = attrib; + } + prevAttribute = attrib; + } + // end of the tag + else if (*p == '>') + { + ++p; + break; + } + // end of the tag + else if (*p == '/' && *(p + 1) == '>') + { + _closingType = CLOSED; + return p + 2; // done; sealed element. + } + else + { + _document->SetError(XML_ERROR_PARSING_ELEMENT, _parseLineNum, 0); + return 0; + } + } + return p; } -void XMLElement::DeleteAttribute( XMLAttribute* attribute ) +void XMLElement::DeleteAttribute(XMLAttribute* attribute) { - if ( attribute == 0 ) { - return; - } - MemPool* pool = attribute->_memPool; - attribute->~XMLAttribute(); - pool->Free( attribute ); + if (attribute == 0) + { + return; + } + MemPool* pool = attribute->_memPool; + attribute->~XMLAttribute(); + pool->Free(attribute); } XMLAttribute* XMLElement::CreateAttribute() { - TIXMLASSERT( sizeof( XMLAttribute ) == _document->_attributePool.ItemSize() ); - XMLAttribute* attrib = new (_document->_attributePool.Alloc() ) XMLAttribute(); - TIXMLASSERT( attrib ); - attrib->_memPool = &_document->_attributePool; - attrib->_memPool->SetTracked(); - return attrib; + TIXMLASSERT(sizeof(XMLAttribute) == _document->_attributePool.ItemSize()); + XMLAttribute* attrib = new (_document->_attributePool.Alloc()) XMLAttribute(); + TIXMLASSERT(attrib); + attrib->_memPool = &_document->_attributePool; + attrib->_memPool->SetTracked(); + return attrib; } // // // foobar // -char* XMLElement::ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ) +char* XMLElement::ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr) { - // Read the element name. - p = XMLUtil::SkipWhiteSpace( p, curLineNumPtr ); + // Read the element name. + p = XMLUtil::SkipWhiteSpace(p, curLineNumPtr); - // The closing element is the form. It is - // parsed just like a regular element then deleted from - // the DOM. - if ( *p == '/' ) { - _closingType = CLOSING; - ++p; - } + // The closing element is the form. It is + // parsed just like a regular element then deleted from + // the DOM. + if (*p == '/') + { + _closingType = CLOSING; + ++p; + } - p = _value.ParseName( p ); - if ( _value.Empty() ) { - return 0; - } + p = _value.ParseName(p); + if (_value.Empty()) + { + return 0; + } - p = ParseAttributes( p, curLineNumPtr ); - if ( !p || !*p || _closingType != OPEN ) { - return p; - } + p = ParseAttributes(p, curLineNumPtr); + if (!p || !*p || _closingType != OPEN) + { + return p; + } - p = XMLNode::ParseDeep( p, parentEndTag, curLineNumPtr ); - return p; + p = XMLNode::ParseDeep(p, parentEndTag, curLineNumPtr); + return p; } - - -XMLNode* XMLElement::ShallowClone( XMLDocument* doc ) const +XMLNode* XMLElement::ShallowClone(XMLDocument* doc) const { - if ( !doc ) { - doc = _document; - } - XMLElement* element = doc->NewElement( Value() ); // fixme: this will always allocate memory. Intern? - for( const XMLAttribute* a=FirstAttribute(); a; a=a->Next() ) { - element->SetAttribute( a->Name(), a->Value() ); // fixme: this will always allocate memory. Intern? - } - return element; + if (!doc) + { + doc = _document; + } + XMLElement* element = doc->NewElement(Value()); // fixme: this will always allocate memory. Intern? + for (const XMLAttribute* a = FirstAttribute(); a; a = a->Next()) + { + element->SetAttribute(a->Name(), a->Value()); // fixme: this will always allocate memory. Intern? + } + return element; } - -bool XMLElement::ShallowEqual( const XMLNode* compare ) const +bool XMLElement::ShallowEqual(const XMLNode* compare) const { - TIXMLASSERT( compare ); - const XMLElement* other = compare->ToElement(); - if ( other && XMLUtil::StringEqual( other->Name(), Name() )) { + TIXMLASSERT(compare); + const XMLElement* other = compare->ToElement(); + if (other && XMLUtil::StringEqual(other->Name(), Name())) + { + const XMLAttribute* a = FirstAttribute(); + const XMLAttribute* b = other->FirstAttribute(); - const XMLAttribute* a=FirstAttribute(); - const XMLAttribute* b=other->FirstAttribute(); - - while ( a && b ) { - if ( !XMLUtil::StringEqual( a->Value(), b->Value() ) ) { - return false; - } - a = a->Next(); - b = b->Next(); - } - if ( a || b ) { - // different count - return false; - } - return true; - } - return false; + while (a && b) + { + if (!XMLUtil::StringEqual(a->Value(), b->Value())) + { + return false; + } + a = a->Next(); + b = b->Next(); + } + if (a || b) + { + // different count + return false; + } + return true; + } + return false; } - -bool XMLElement::Accept( XMLVisitor* visitor ) const +bool XMLElement::Accept(XMLVisitor* visitor) const { - TIXMLASSERT( visitor ); - if ( visitor->VisitEnter( *this, _rootAttribute ) ) { - for ( const XMLNode* node=FirstChild(); node; node=node->NextSibling() ) { - if ( !node->Accept( visitor ) ) { - break; - } - } - } - return visitor->VisitExit( *this ); + TIXMLASSERT(visitor); + if (visitor->VisitEnter(*this, _rootAttribute)) + { + for (const XMLNode* node = FirstChild(); node; node = node->NextSibling()) + { + if (!node->Accept(visitor)) + { + break; + } + } + } + return visitor->VisitExit(*this); } - // --------- XMLDocument ----------- // // Warning: List must match 'enum XMLError' const char* XMLDocument::_errorNames[XML_ERROR_COUNT] = { - "XML_SUCCESS", - "XML_NO_ATTRIBUTE", - "XML_WRONG_ATTRIBUTE_TYPE", - "XML_ERROR_FILE_NOT_FOUND", - "XML_ERROR_FILE_COULD_NOT_BE_OPENED", - "XML_ERROR_FILE_READ_ERROR", - "UNUSED_XML_ERROR_ELEMENT_MISMATCH", - "XML_ERROR_PARSING_ELEMENT", - "XML_ERROR_PARSING_ATTRIBUTE", - "UNUSED_XML_ERROR_IDENTIFYING_TAG", - "XML_ERROR_PARSING_TEXT", - "XML_ERROR_PARSING_CDATA", - "XML_ERROR_PARSING_COMMENT", - "XML_ERROR_PARSING_DECLARATION", - "XML_ERROR_PARSING_UNKNOWN", - "XML_ERROR_EMPTY_DOCUMENT", - "XML_ERROR_MISMATCHED_ELEMENT", - "XML_ERROR_PARSING", - "XML_CAN_NOT_CONVERT_TEXT", - "XML_NO_TEXT_NODE", - "XML_ELEMENT_DEPTH_EXCEEDED" -}; + "XML_SUCCESS", + "XML_NO_ATTRIBUTE", + "XML_WRONG_ATTRIBUTE_TYPE", + "XML_ERROR_FILE_NOT_FOUND", + "XML_ERROR_FILE_COULD_NOT_BE_OPENED", + "XML_ERROR_FILE_READ_ERROR", + "UNUSED_XML_ERROR_ELEMENT_MISMATCH", + "XML_ERROR_PARSING_ELEMENT", + "XML_ERROR_PARSING_ATTRIBUTE", + "UNUSED_XML_ERROR_IDENTIFYING_TAG", + "XML_ERROR_PARSING_TEXT", + "XML_ERROR_PARSING_CDATA", + "XML_ERROR_PARSING_COMMENT", + "XML_ERROR_PARSING_DECLARATION", + "XML_ERROR_PARSING_UNKNOWN", + "XML_ERROR_EMPTY_DOCUMENT", + "XML_ERROR_MISMATCHED_ELEMENT", + "XML_ERROR_PARSING", + "XML_CAN_NOT_CONVERT_TEXT", + "XML_NO_TEXT_NODE", + "XML_ELEMENT_DEPTH_EXCEEDED"}; - -XMLDocument::XMLDocument( bool processEntities, Whitespace whitespaceMode ) : - XMLNode( 0 ), - _writeBOM( false ), - _processEntities( processEntities ), - _errorID(XML_SUCCESS), - _whitespaceMode( whitespaceMode ), - _errorStr(), - _errorLineNum( 0 ), - _charBuffer( 0 ), - _parseCurLineNum( 0 ), - _parsingDepth(0), - _unlinked(), - _elementPool(), - _attributePool(), - _textPool(), - _commentPool() +XMLDocument::XMLDocument(bool processEntities, Whitespace whitespaceMode) : XMLNode(0), + _writeBOM(false), + _processEntities(processEntities), + _errorID(XML_SUCCESS), + _whitespaceMode(whitespaceMode), + _errorStr(), + _errorLineNum(0), + _charBuffer(0), + _parseCurLineNum(0), + _parsingDepth(0), + _unlinked(), + _elementPool(), + _attributePool(), + _textPool(), + _commentPool() { - // avoid VC++ C4355 warning about 'this' in initializer list (C4355 is off by default in VS2012+) - _document = this; + // avoid VC++ C4355 warning about 'this' in initializer list (C4355 is off by default in VS2012+) + _document = this; } - XMLDocument::~XMLDocument() { - Clear(); + Clear(); } - void XMLDocument::MarkInUse(XMLNode* node) { TIXMLASSERT(node); TIXMLASSERT(node->_parent == 0); - for (int i = 0; i < _unlinked.Size(); ++i) { - if (node == _unlinked[i]) { + for (int i = 0; i < _unlinked.Size(); ++i) + { + if (node == _unlinked[i]) + { _unlinked.SwapRemove(i); break; } @@ -2038,18 +2130,19 @@ void XMLDocument::MarkInUse(XMLNode* node) void XMLDocument::Clear() { - DeleteChildren(); - while( _unlinked.Size()) { - DeleteNode(_unlinked[0]); // Will remove from _unlinked as part of delete. + DeleteChildren(); + while (_unlinked.Size()) + { + DeleteNode(_unlinked[0]); // Will remove from _unlinked as part of delete. } #ifdef TINYXML2_DEBUG - const bool hadError = Error(); + const bool hadError = Error(); #endif - ClearError(); + ClearError(); - delete [] _charBuffer; - _charBuffer = 0; + delete[] _charBuffer; + _charBuffer = 0; _parsingDepth = 0; #if 0 @@ -2060,119 +2153,122 @@ void XMLDocument::Clear() #endif #ifdef TINYXML2_DEBUG - if ( !hadError ) { - TIXMLASSERT( _elementPool.CurrentAllocs() == _elementPool.Untracked() ); - TIXMLASSERT( _attributePool.CurrentAllocs() == _attributePool.Untracked() ); - TIXMLASSERT( _textPool.CurrentAllocs() == _textPool.Untracked() ); - TIXMLASSERT( _commentPool.CurrentAllocs() == _commentPool.Untracked() ); - } + if (!hadError) + { + TIXMLASSERT(_elementPool.CurrentAllocs() == _elementPool.Untracked()); + TIXMLASSERT(_attributePool.CurrentAllocs() == _attributePool.Untracked()); + TIXMLASSERT(_textPool.CurrentAllocs() == _textPool.Untracked()); + TIXMLASSERT(_commentPool.CurrentAllocs() == _commentPool.Untracked()); + } #endif } - void XMLDocument::DeepCopy(XMLDocument* target) const { TIXMLASSERT(target); - if (target == this) { - return; // technically success - a no-op. - } + if (target == this) + { + return; // technically success - a no-op. + } target->Clear(); - for (const XMLNode* node = this->FirstChild(); node; node = node->NextSibling()) { + for (const XMLNode* node = this->FirstChild(); node; node = node->NextSibling()) + { target->InsertEndChild(node->DeepClone(target)); } } -XMLElement* XMLDocument::NewElement( const char* name ) +XMLElement* XMLDocument::NewElement(const char* name) { - XMLElement* ele = CreateUnlinkedNode( _elementPool ); - ele->SetName( name ); - return ele; + XMLElement* ele = CreateUnlinkedNode(_elementPool); + ele->SetName(name); + return ele; } - -XMLComment* XMLDocument::NewComment( const char* str ) +XMLComment* XMLDocument::NewComment(const char* str) { - XMLComment* comment = CreateUnlinkedNode( _commentPool ); - comment->SetValue( str ); - return comment; + XMLComment* comment = CreateUnlinkedNode(_commentPool); + comment->SetValue(str); + return comment; } - -XMLText* XMLDocument::NewText( const char* str ) +XMLText* XMLDocument::NewText(const char* str) { - XMLText* text = CreateUnlinkedNode( _textPool ); - text->SetValue( str ); - return text; + XMLText* text = CreateUnlinkedNode(_textPool); + text->SetValue(str); + return text; } - -XMLDeclaration* XMLDocument::NewDeclaration( const char* str ) +XMLDeclaration* XMLDocument::NewDeclaration(const char* str) { - XMLDeclaration* dec = CreateUnlinkedNode( _commentPool ); - dec->SetValue( str ? str : "xml version=\"1.0\" encoding=\"UTF-8\"" ); - return dec; + XMLDeclaration* dec = CreateUnlinkedNode(_commentPool); + dec->SetValue(str ? str : "xml version=\"1.0\" encoding=\"UTF-8\""); + return dec; } - -XMLUnknown* XMLDocument::NewUnknown( const char* str ) +XMLUnknown* XMLDocument::NewUnknown(const char* str) { - XMLUnknown* unk = CreateUnlinkedNode( _commentPool ); - unk->SetValue( str ); - return unk; + XMLUnknown* unk = CreateUnlinkedNode(_commentPool); + unk->SetValue(str); + return unk; } -static FILE* callfopen( const char* filepath, const char* mode ) +static FILE* callfopen(const char* filepath, const char* mode) { - TIXMLASSERT( filepath ); - TIXMLASSERT( mode ); -#if defined(_MSC_VER) && (_MSC_VER >= 1400 ) && (!defined WINCE) - FILE* fp = 0; - errno_t err = fopen_s( &fp, filepath, mode ); - if ( err ) { - return 0; - } + TIXMLASSERT(filepath); + TIXMLASSERT(mode); +#if defined(_MSC_VER) && (_MSC_VER >= 1400) && (!defined WINCE) + FILE* fp = 0; + errno_t err = fopen_s(&fp, filepath, mode); + if (err) + { + return 0; + } #else - FILE* fp = fopen( filepath, mode ); + FILE* fp = fopen(filepath, mode); #endif - return fp; + return fp; } -void XMLDocument::DeleteNode( XMLNode* node ) { - TIXMLASSERT( node ); - TIXMLASSERT(node->_document == this ); - if (node->_parent) { - node->_parent->DeleteChild( node ); - } - else { - // Isn't in the tree. - // Use the parent delete. - // Also, we need to mark it tracked: we 'know' - // it was never used. - node->_memPool->SetTracked(); - // Call the static XMLNode version: - XMLNode::DeleteNode(node); - } -} - - -XMLError XMLDocument::LoadFile( const char* filename ) +void XMLDocument::DeleteNode(XMLNode* node) { - if ( !filename ) { - TIXMLASSERT( false ); - SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=" ); - return _errorID; - } + TIXMLASSERT(node); + TIXMLASSERT(node->_document == this); + if (node->_parent) + { + node->_parent->DeleteChild(node); + } + else + { + // Isn't in the tree. + // Use the parent delete. + // Also, we need to mark it tracked: we 'know' + // it was never used. + node->_memPool->SetTracked(); + // Call the static XMLNode version: + XMLNode::DeleteNode(node); + } +} - Clear(); - FILE* fp = callfopen( filename, "rb" ); - if ( !fp ) { - SetError( XML_ERROR_FILE_NOT_FOUND, 0, "filename=%s", filename ); - return _errorID; - } - LoadFile( fp ); - fclose( fp ); - return _errorID; +XMLError XMLDocument::LoadFile(const char* filename) +{ + if (!filename) + { + TIXMLASSERT(false); + SetError(XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename="); + return _errorID; + } + + Clear(); + FILE* fp = callfopen(filename, "rb"); + if (!fp) + { + SetError(XML_ERROR_FILE_NOT_FOUND, 0, "filename=%s", filename); + return _errorID; + } + LoadFile(fp); + fclose(fp); + return _errorID; } // This is likely overengineered template art to have a check that unsigned long value incremented @@ -2181,155 +2277,164 @@ XMLError XMLDocument::LoadFile( const char* filename ) // -Wtype-limits warning. This piece makes the compiler select code with a check when a check // is useful and code with no check when a check is redundant depending on how size_t and unsigned long // types sizes relate to each other. -template -= sizeof(size_t))> -struct LongFitsIntoSizeTMinusOne { - static bool Fits( unsigned long value ) - { - return value < (size_t)-1; - } +template = sizeof(size_t))> +struct LongFitsIntoSizeTMinusOne +{ + static bool Fits(unsigned long value) + { + return value < (size_t)-1; + } }; template <> -struct LongFitsIntoSizeTMinusOne { - static bool Fits( unsigned long ) - { - return true; - } +struct LongFitsIntoSizeTMinusOne +{ + static bool Fits(unsigned long) + { + return true; + } }; -XMLError XMLDocument::LoadFile( FILE* fp ) +XMLError XMLDocument::LoadFile(FILE* fp) { - Clear(); + Clear(); - fseek( fp, 0, SEEK_SET ); - if ( fgetc( fp ) == EOF && ferror( fp ) != 0 ) { - SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); - return _errorID; - } + fseek(fp, 0, SEEK_SET); + if (fgetc(fp) == EOF && ferror(fp) != 0) + { + SetError(XML_ERROR_FILE_READ_ERROR, 0, 0); + return _errorID; + } - fseek( fp, 0, SEEK_END ); - const long filelength = ftell( fp ); - fseek( fp, 0, SEEK_SET ); - if ( filelength == -1L ) { - SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); - return _errorID; - } - TIXMLASSERT( filelength >= 0 ); + fseek(fp, 0, SEEK_END); + const long filelength = ftell(fp); + fseek(fp, 0, SEEK_SET); + if (filelength == -1L) + { + SetError(XML_ERROR_FILE_READ_ERROR, 0, 0); + return _errorID; + } + TIXMLASSERT(filelength >= 0); - if ( !LongFitsIntoSizeTMinusOne<>::Fits( filelength ) ) { - // Cannot handle files which won't fit in buffer together with null terminator - SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); - return _errorID; - } + if (!LongFitsIntoSizeTMinusOne<>::Fits(filelength)) + { + // Cannot handle files which won't fit in buffer together with null terminator + SetError(XML_ERROR_FILE_READ_ERROR, 0, 0); + return _errorID; + } - if ( filelength == 0 ) { - SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); - return _errorID; - } + if (filelength == 0) + { + SetError(XML_ERROR_EMPTY_DOCUMENT, 0, 0); + return _errorID; + } - const size_t size = filelength; - TIXMLASSERT( _charBuffer == 0 ); - _charBuffer = new char[size+1]; - size_t read = fread( _charBuffer, 1, size, fp ); - if ( read != size ) { - SetError( XML_ERROR_FILE_READ_ERROR, 0, 0 ); - return _errorID; - } + const size_t size = filelength; + TIXMLASSERT(_charBuffer == 0); + _charBuffer = new char[size + 1]; + size_t read = fread(_charBuffer, 1, size, fp); + if (read != size) + { + SetError(XML_ERROR_FILE_READ_ERROR, 0, 0); + return _errorID; + } - _charBuffer[size] = 0; + _charBuffer[size] = 0; - Parse(); - return _errorID; + Parse(); + return _errorID; } - -XMLError XMLDocument::SaveFile( const char* filename, bool compact ) +XMLError XMLDocument::SaveFile(const char* filename, bool compact) { - if ( !filename ) { - TIXMLASSERT( false ); - SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=" ); - return _errorID; - } + if (!filename) + { + TIXMLASSERT(false); + SetError(XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename="); + return _errorID; + } - FILE* fp = callfopen( filename, "w" ); - if ( !fp ) { - SetError( XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=%s", filename ); - return _errorID; - } - SaveFile(fp, compact); - fclose( fp ); - return _errorID; + FILE* fp = callfopen(filename, "w"); + if (!fp) + { + SetError(XML_ERROR_FILE_COULD_NOT_BE_OPENED, 0, "filename=%s", filename); + return _errorID; + } + SaveFile(fp, compact); + fclose(fp); + return _errorID; } - -XMLError XMLDocument::SaveFile( FILE* fp, bool compact ) +XMLError XMLDocument::SaveFile(FILE* fp, bool compact) { - // Clear any error from the last save, otherwise it will get reported - // for *this* call. - ClearError(); - XMLPrinter stream( fp, compact ); - Print( &stream ); - return _errorID; + // Clear any error from the last save, otherwise it will get reported + // for *this* call. + ClearError(); + XMLPrinter stream(fp, compact); + Print(&stream); + return _errorID; } - -XMLError XMLDocument::Parse( const char* p, size_t len ) +XMLError XMLDocument::Parse(const char* p, size_t len) { - Clear(); + Clear(); - if ( len == 0 || !p || !*p ) { - SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); - return _errorID; - } - if ( len == (size_t)(-1) ) { - len = strlen( p ); - } - TIXMLASSERT( _charBuffer == 0 ); - _charBuffer = new char[ len+1 ]; - memcpy( _charBuffer, p, len ); - _charBuffer[len] = 0; + if (len == 0 || !p || !*p) + { + SetError(XML_ERROR_EMPTY_DOCUMENT, 0, 0); + return _errorID; + } + if (len == (size_t)(-1)) + { + len = strlen(p); + } + TIXMLASSERT(_charBuffer == 0); + _charBuffer = new char[len + 1]; + memcpy(_charBuffer, p, len); + _charBuffer[len] = 0; - Parse(); - if ( Error() ) { - // clean up now essentially dangling memory. - // and the parse fail can put objects in the - // pools that are dead and inaccessible. - DeleteChildren(); - _elementPool.Clear(); - _attributePool.Clear(); - _textPool.Clear(); - _commentPool.Clear(); - } - return _errorID; + Parse(); + if (Error()) + { + // clean up now essentially dangling memory. + // and the parse fail can put objects in the + // pools that are dead and inaccessible. + DeleteChildren(); + _elementPool.Clear(); + _attributePool.Clear(); + _textPool.Clear(); + _commentPool.Clear(); + } + return _errorID; } - -void XMLDocument::Print( XMLPrinter* streamer ) const +void XMLDocument::Print(XMLPrinter* streamer) const { - if ( streamer ) { - Accept( streamer ); - } - else { - XMLPrinter stdoutStreamer( stdout ); - Accept( &stdoutStreamer ); - } + if (streamer) + { + Accept(streamer); + } + else + { + XMLPrinter stdoutStreamer(stdout); + Accept(&stdoutStreamer); + } } - -void XMLDocument::SetError( XMLError error, int lineNum, const char* format, ... ) +void XMLDocument::SetError(XMLError error, int lineNum, const char* format, ...) { - TIXMLASSERT( error >= 0 && error < XML_ERROR_COUNT ); - _errorID = error; - _errorLineNum = lineNum; + TIXMLASSERT(error >= 0 && error < XML_ERROR_COUNT); + _errorID = error; + _errorLineNum = lineNum; _errorStr.Reset(); - size_t BUFFER_SIZE = 1000; - char* buffer = new char[BUFFER_SIZE]; + size_t BUFFER_SIZE = 1000; + char* buffer = new char[BUFFER_SIZE]; - TIXML_SNPRINTF(buffer, BUFFER_SIZE, "Error=%s ErrorID=%d (0x%x) Line number=%d", ErrorIDToName(error), int(error), int(error), lineNum); + TIXML_SNPRINTF(buffer, BUFFER_SIZE, "Error=%s ErrorID=%d (0x%x) Line number=%d", ErrorIDToName(error), int(error), int(error), lineNum); - if (format) { + if (format) + { size_t len = strlen(buffer); TIXML_SNPRINTF(buffer + len, BUFFER_SIZE - len, ": "); len = strlen(buffer); @@ -2343,13 +2448,12 @@ void XMLDocument::SetError( XMLError error, int lineNum, const char* format, ... delete[] buffer; } - /*static*/ const char* XMLDocument::ErrorIDToName(XMLError errorID) { - TIXMLASSERT( errorID >= 0 && errorID < XML_ERROR_COUNT ); - const char* errorName = _errorNames[errorID]; - TIXMLASSERT( errorName && errorName[0] ); - return errorName; + TIXMLASSERT(errorID >= 0 && errorID < XML_ERROR_COUNT); + const char* errorName = _errorNames[errorID]; + TIXMLASSERT(errorName && errorName[0]); + return errorName; } const char* XMLDocument::ErrorStr() const @@ -2357,38 +2461,39 @@ const char* XMLDocument::ErrorStr() const return _errorStr.Empty() ? "" : _errorStr.GetStr(); } - void XMLDocument::PrintError() const { - printf("%s\n", ErrorStr()); + printf("%s\n", ErrorStr()); } const char* XMLDocument::ErrorName() const { - return ErrorIDToName(_errorID); + return ErrorIDToName(_errorID); } void XMLDocument::Parse() { - TIXMLASSERT( NoChildren() ); // Clear() must have been called previously - TIXMLASSERT( _charBuffer ); - _parseCurLineNum = 1; - _parseLineNum = 1; - char* p = _charBuffer; - p = XMLUtil::SkipWhiteSpace( p, &_parseCurLineNum ); - p = const_cast( XMLUtil::ReadBOM( p, &_writeBOM ) ); - if ( !*p ) { - SetError( XML_ERROR_EMPTY_DOCUMENT, 0, 0 ); - return; - } - ParseDeep(p, 0, &_parseCurLineNum ); + TIXMLASSERT(NoChildren()); // Clear() must have been called previously + TIXMLASSERT(_charBuffer); + _parseCurLineNum = 1; + _parseLineNum = 1; + char* p = _charBuffer; + p = XMLUtil::SkipWhiteSpace(p, &_parseCurLineNum); + p = const_cast(XMLUtil::ReadBOM(p, &_writeBOM)); + if (!*p) + { + SetError(XML_ERROR_EMPTY_DOCUMENT, 0, 0); + return; + } + ParseDeep(p, 0, &_parseCurLineNum); } void XMLDocument::PushDepth() { _parsingDepth++; - if (_parsingDepth == TINYXML2_MAX_ELEMENT_DEPTH) { - SetError(XML_ELEMENT_DEPTH_EXCEEDED, _parseCurLineNum, "Element nesting is too deep." ); + if (_parsingDepth == TINYXML2_MAX_ELEMENT_DEPTH) + { + SetError(XML_ELEMENT_DEPTH_EXCEEDED, _parseCurLineNum, "Element nesting is too deep."); } } @@ -2398,203 +2503,213 @@ void XMLDocument::PopDepth() --_parsingDepth; } -XMLPrinter::XMLPrinter( FILE* file, bool compact, int depth ) : - _elementJustOpened( false ), - _stack(), - _firstElement( true ), - _fp( file ), - _depth( depth ), - _textDepth( -1 ), - _processEntities( true ), - _compactMode( compact ), - _buffer() +XMLPrinter::XMLPrinter(FILE* file, bool compact, int depth) : _elementJustOpened(false), + _stack(), + _firstElement(true), + _fp(file), + _depth(depth), + _textDepth(-1), + _processEntities(true), + _compactMode(compact), + _buffer() { - for( int i=0; i'] = true; // not required, but consistency is nice - _buffer.Push( 0 ); + for (int i = 0; i < ENTITY_RANGE; ++i) + { + _entityFlag[i] = false; + _restrictedEntityFlag[i] = false; + } + for (int i = 0; i < NUM_ENTITIES; ++i) + { + const char entityValue = entities[i].value; + const unsigned char flagIndex = (unsigned char)entityValue; + TIXMLASSERT(flagIndex < ENTITY_RANGE); + _entityFlag[flagIndex] = true; + } + _restrictedEntityFlag[(unsigned char)'&'] = true; + _restrictedEntityFlag[(unsigned char)'<'] = true; + _restrictedEntityFlag[(unsigned char)'>'] = true; // not required, but consistency is nice + _buffer.Push(0); } - -void XMLPrinter::Print( const char* format, ... ) +void XMLPrinter::Print(const char* format, ...) { - va_list va; - va_start( va, format ); + va_list va; + va_start(va, format); - if ( _fp ) { - vfprintf( _fp, format, va ); - } - else { - const int len = TIXML_VSCPRINTF( format, va ); - // Close out and re-start the va-args - va_end( va ); - TIXMLASSERT( len >= 0 ); - va_start( va, format ); - TIXMLASSERT( _buffer.Size() > 0 && _buffer[_buffer.Size() - 1] == 0 ); - char* p = _buffer.PushArr( len ) - 1; // back up over the null terminator. - TIXML_VSNPRINTF( p, len+1, format, va ); - } - va_end( va ); + if (_fp) + { + vfprintf(_fp, format, va); + } + else + { + const int len = TIXML_VSCPRINTF(format, va); + // Close out and re-start the va-args + va_end(va); + TIXMLASSERT(len >= 0); + va_start(va, format); + TIXMLASSERT(_buffer.Size() > 0 && _buffer[_buffer.Size() - 1] == 0); + char* p = _buffer.PushArr(len) - 1; // back up over the null terminator. + TIXML_VSNPRINTF(p, len + 1, format, va); + } + va_end(va); } - -void XMLPrinter::Write( const char* data, size_t size ) +void XMLPrinter::Write(const char* data, size_t size) { - if ( _fp ) { - fwrite ( data , sizeof(char), size, _fp); - } - else { - char* p = _buffer.PushArr( static_cast(size) ) - 1; // back up over the null terminator. - memcpy( p, data, size ); - p[size] = 0; - } + if (_fp) + { + fwrite(data, sizeof(char), size, _fp); + } + else + { + char* p = _buffer.PushArr(static_cast(size)) - 1; // back up over the null terminator. + memcpy(p, data, size); + p[size] = 0; + } } - -void XMLPrinter::Putc( char ch ) +void XMLPrinter::Putc(char ch) { - if ( _fp ) { - fputc ( ch, _fp); - } - else { - char* p = _buffer.PushArr( sizeof(char) ) - 1; // back up over the null terminator. - p[0] = ch; - p[1] = 0; - } + if (_fp) + { + fputc(ch, _fp); + } + else + { + char* p = _buffer.PushArr(sizeof(char)) - 1; // back up over the null terminator. + p[0] = ch; + p[1] = 0; + } } - -void XMLPrinter::PrintSpace( int depth ) +void XMLPrinter::PrintSpace(int depth) { - for( int i=0; i 0 && *q < ENTITY_RANGE ) { - // Check for entities. If one is found, flush - // the stream up until the entity, write the - // entity, and keep looking. - if ( flag[(unsigned char)(*q)] ) { - while ( p < q ) { - const size_t delta = q - p; - const int toPrint = ( INT_MAX < delta ) ? INT_MAX : (int)delta; - Write( p, toPrint ); - p += toPrint; - } - bool entityPatternPrinted = false; - for( int i=0; i 0 && *q < ENTITY_RANGE) + { + // Check for entities. If one is found, flush + // the stream up until the entity, write the + // entity, and keep looking. + if (flag[(unsigned char)(*q)]) + { + while (p < q) + { + const size_t delta = q - p; + const int toPrint = (INT_MAX < delta) ? INT_MAX : (int)delta; + Write(p, toPrint); + p += toPrint; + } + bool entityPatternPrinted = false; + for (int i = 0; i < NUM_ENTITIES; ++i) + { + if (entities[i].value == *q) + { + Putc('&'); + Write(entities[i].pattern, entities[i].length); + Putc(';'); + entityPatternPrinted = true; + break; + } + } + if (!entityPatternPrinted) + { + // TIXMLASSERT( entityPatternPrinted ) causes gcc -Wunused-but-set-variable in release + TIXMLASSERT(false); + } + ++p; + } + } + ++q; + TIXMLASSERT(p <= q); + } + } + // Flush the remaining string. This will be the entire + // string if an entity wasn't found. + TIXMLASSERT(p <= q); + if (!_processEntities || (p < q)) + { + const size_t delta = q - p; + const int toPrint = (INT_MAX < delta) ? INT_MAX : (int)delta; + Write(p, toPrint); + } } - -void XMLPrinter::PushHeader( bool writeBOM, bool writeDec ) +void XMLPrinter::PushHeader(bool writeBOM, bool writeDec) { - if ( writeBOM ) { - static const unsigned char bom[] = { TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0 }; - Write( reinterpret_cast< const char* >( bom ) ); - } - if ( writeDec ) { - PushDeclaration( "xml version=\"1.0\"" ); - } + if (writeBOM) + { + static const unsigned char bom[] = {TIXML_UTF_LEAD_0, TIXML_UTF_LEAD_1, TIXML_UTF_LEAD_2, 0}; + Write(reinterpret_cast(bom)); + } + if (writeDec) + { + PushDeclaration("xml version=\"1.0\""); + } } - -void XMLPrinter::OpenElement( const char* name, bool compactMode ) +void XMLPrinter::OpenElement(const char* name, bool compactMode) { - SealElementIfJustOpened(); - _stack.Push( name ); + SealElementIfJustOpened(); + _stack.Push(name); - if ( _textDepth < 0 && !_firstElement && !compactMode ) { - Putc( '\n' ); - } - if ( !compactMode ) { - PrintSpace( _depth ); - } + if (_textDepth < 0 && !_firstElement && !compactMode) + { + Putc('\n'); + } + if (!compactMode) + { + PrintSpace(_depth); + } - Write ( "<" ); - Write ( name ); + Write("<"); + Write(name); - _elementJustOpened = true; - _firstElement = false; - ++_depth; + _elementJustOpened = true; + _firstElement = false; + ++_depth; } - -void XMLPrinter::PushAttribute( const char* name, const char* value ) +void XMLPrinter::PushAttribute(const char* name, const char* value) { - TIXMLASSERT( _elementJustOpened ); - Putc ( ' ' ); - Write( name ); - Write( "=\"" ); - PrintString( value, false ); - Putc ( '\"' ); + TIXMLASSERT(_elementJustOpened); + Putc(' '); + Write(name); + Write("=\""); + PrintString(value, false); + Putc('\"'); } - -void XMLPrinter::PushAttribute( const char* name, int v ) +void XMLPrinter::PushAttribute(const char* name, int v) { - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - PushAttribute( name, buf ); + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + PushAttribute(name, buf); } - -void XMLPrinter::PushAttribute( const char* name, unsigned v ) +void XMLPrinter::PushAttribute(const char* name, unsigned v) { - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - PushAttribute( name, buf ); + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + PushAttribute(name, buf); } - void XMLPrinter::PushAttribute(const char* name, int64_t v) { char buf[BUF_SIZE]; @@ -2602,225 +2717,221 @@ void XMLPrinter::PushAttribute(const char* name, int64_t v) PushAttribute(name, buf); } - -void XMLPrinter::PushAttribute( const char* name, bool v ) +void XMLPrinter::PushAttribute(const char* name, bool v) { - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - PushAttribute( name, buf ); + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + PushAttribute(name, buf); } - -void XMLPrinter::PushAttribute( const char* name, double v ) +void XMLPrinter::PushAttribute(const char* name, double v) { - char buf[BUF_SIZE]; - XMLUtil::ToStr( v, buf, BUF_SIZE ); - PushAttribute( name, buf ); + char buf[BUF_SIZE]; + XMLUtil::ToStr(v, buf, BUF_SIZE); + PushAttribute(name, buf); } - -void XMLPrinter::CloseElement( bool compactMode ) +void XMLPrinter::CloseElement(bool compactMode) { - --_depth; - const char* name = _stack.Pop(); + --_depth; + const char* name = _stack.Pop(); - if ( _elementJustOpened ) { - Write( "/>" ); - } - else { - if ( _textDepth < 0 && !compactMode) { - Putc( '\n' ); - PrintSpace( _depth ); - } - Write ( "" ); - } + if (_elementJustOpened) + { + Write("/>"); + } + else + { + if (_textDepth < 0 && !compactMode) + { + Putc('\n'); + PrintSpace(_depth); + } + Write(""); + } - if ( _textDepth == _depth ) { - _textDepth = -1; - } - if ( _depth == 0 && !compactMode) { - Putc( '\n' ); - } - _elementJustOpened = false; + if (_textDepth == _depth) + { + _textDepth = -1; + } + if (_depth == 0 && !compactMode) + { + Putc('\n'); + } + _elementJustOpened = false; } - void XMLPrinter::SealElementIfJustOpened() { - if ( !_elementJustOpened ) { - return; - } - _elementJustOpened = false; - Putc( '>' ); + if (!_elementJustOpened) + { + return; + } + _elementJustOpened = false; + Putc('>'); } - -void XMLPrinter::PushText( const char* text, bool cdata ) +void XMLPrinter::PushText(const char* text, bool cdata) { - _textDepth = _depth-1; + _textDepth = _depth - 1; - SealElementIfJustOpened(); - if ( cdata ) { - Write( "" ); - } - else { - PrintString( text, true ); - } + SealElementIfJustOpened(); + if (cdata) + { + Write(""); + } + else + { + PrintString(text, true); + } } -void XMLPrinter::PushText( int64_t value ) +void XMLPrinter::PushText(int64_t value) { - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); + char buf[BUF_SIZE]; + XMLUtil::ToStr(value, buf, BUF_SIZE); + PushText(buf, false); } -void XMLPrinter::PushText( int value ) +void XMLPrinter::PushText(int value) { - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); + char buf[BUF_SIZE]; + XMLUtil::ToStr(value, buf, BUF_SIZE); + PushText(buf, false); } - -void XMLPrinter::PushText( unsigned value ) +void XMLPrinter::PushText(unsigned value) { - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); + char buf[BUF_SIZE]; + XMLUtil::ToStr(value, buf, BUF_SIZE); + PushText(buf, false); } - -void XMLPrinter::PushText( bool value ) +void XMLPrinter::PushText(bool value) { - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); + char buf[BUF_SIZE]; + XMLUtil::ToStr(value, buf, BUF_SIZE); + PushText(buf, false); } - -void XMLPrinter::PushText( float value ) +void XMLPrinter::PushText(float value) { - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); + char buf[BUF_SIZE]; + XMLUtil::ToStr(value, buf, BUF_SIZE); + PushText(buf, false); } - -void XMLPrinter::PushText( double value ) +void XMLPrinter::PushText(double value) { - char buf[BUF_SIZE]; - XMLUtil::ToStr( value, buf, BUF_SIZE ); - PushText( buf, false ); + char buf[BUF_SIZE]; + XMLUtil::ToStr(value, buf, BUF_SIZE); + PushText(buf, false); } - -void XMLPrinter::PushComment( const char* comment ) +void XMLPrinter::PushComment(const char* comment) { - SealElementIfJustOpened(); - if ( _textDepth < 0 && !_firstElement && !_compactMode) { - Putc( '\n' ); - PrintSpace( _depth ); - } - _firstElement = false; + SealElementIfJustOpened(); + if (_textDepth < 0 && !_firstElement && !_compactMode) + { + Putc('\n'); + PrintSpace(_depth); + } + _firstElement = false; - Write( "" ); + Write(""); } - -void XMLPrinter::PushDeclaration( const char* value ) +void XMLPrinter::PushDeclaration(const char* value) { - SealElementIfJustOpened(); - if ( _textDepth < 0 && !_firstElement && !_compactMode) { - Putc( '\n' ); - PrintSpace( _depth ); - } - _firstElement = false; + SealElementIfJustOpened(); + if (_textDepth < 0 && !_firstElement && !_compactMode) + { + Putc('\n'); + PrintSpace(_depth); + } + _firstElement = false; - Write( "" ); + Write(""); } - -void XMLPrinter::PushUnknown( const char* value ) +void XMLPrinter::PushUnknown(const char* value) { - SealElementIfJustOpened(); - if ( _textDepth < 0 && !_firstElement && !_compactMode) { - Putc( '\n' ); - PrintSpace( _depth ); - } - _firstElement = false; + SealElementIfJustOpened(); + if (_textDepth < 0 && !_firstElement && !_compactMode) + { + Putc('\n'); + PrintSpace(_depth); + } + _firstElement = false; - Write( "' ); + Write("'); } - -bool XMLPrinter::VisitEnter( const XMLDocument& doc ) +bool XMLPrinter::VisitEnter(const XMLDocument& doc) { - _processEntities = doc.ProcessEntities(); - if ( doc.HasBOM() ) { - PushHeader( true, false ); - } - return true; + _processEntities = doc.ProcessEntities(); + if (doc.HasBOM()) + { + PushHeader(true, false); + } + return true; } - -bool XMLPrinter::VisitEnter( const XMLElement& element, const XMLAttribute* attribute ) +bool XMLPrinter::VisitEnter(const XMLElement& element, const XMLAttribute* attribute) { - const XMLElement* parentElem = 0; - if ( element.Parent() ) { - parentElem = element.Parent()->ToElement(); - } - const bool compactMode = parentElem ? CompactMode( *parentElem ) : _compactMode; - OpenElement( element.Name(), compactMode ); - while ( attribute ) { - PushAttribute( attribute->Name(), attribute->Value() ); - attribute = attribute->Next(); - } - return true; + const XMLElement* parentElem = 0; + if (element.Parent()) + { + parentElem = element.Parent()->ToElement(); + } + const bool compactMode = parentElem ? CompactMode(*parentElem) : _compactMode; + OpenElement(element.Name(), compactMode); + while (attribute) + { + PushAttribute(attribute->Name(), attribute->Value()); + attribute = attribute->Next(); + } + return true; } - -bool XMLPrinter::VisitExit( const XMLElement& element ) +bool XMLPrinter::VisitExit(const XMLElement& element) { - CloseElement( CompactMode(element) ); - return true; + CloseElement(CompactMode(element)); + return true; } - -bool XMLPrinter::Visit( const XMLText& text ) +bool XMLPrinter::Visit(const XMLText& text) { - PushText( text.Value(), text.CData() ); - return true; + PushText(text.Value(), text.CData()); + return true; } - -bool XMLPrinter::Visit( const XMLComment& comment ) +bool XMLPrinter::Visit(const XMLComment& comment) { - PushComment( comment.Value() ); - return true; + PushComment(comment.Value()); + return true; } -bool XMLPrinter::Visit( const XMLDeclaration& declaration ) +bool XMLPrinter::Visit(const XMLDeclaration& declaration) { - PushDeclaration( declaration.Value() ); - return true; + PushDeclaration(declaration.Value()); + return true; } - -bool XMLPrinter::Visit( const XMLUnknown& unknown ) +bool XMLPrinter::Visit(const XMLUnknown& unknown) { - PushUnknown( unknown.Value() ); - return true; + PushUnknown(unknown.Value()); + return true; } -} // namespace tinyxml2 +} // namespace tinyxml2 diff --git a/examples/ThirdPartyLibs/tinyxml2/tinyxml2.h b/examples/ThirdPartyLibs/tinyxml2/tinyxml2.h index 1075eb2f2..bb030b99a 100644 --- a/examples/ThirdPartyLibs/tinyxml2/tinyxml2.h +++ b/examples/ThirdPartyLibs/tinyxml2/tinyxml2.h @@ -25,20 +25,20 @@ distribution. #define TINYXML2_INCLUDED #if defined(ANDROID_NDK) || defined(__BORLANDC__) || defined(__QNXNTO__) -# include -# include -# include -# include -# include -# if defined(__PS3__) -# include -# endif +#include +#include +#include +#include +#include +#if defined(__PS3__) +#include +#endif #else -# include -# include -# include -# include -# include +#include +#include +#include +#include +#include #endif #include @@ -53,47 +53,55 @@ distribution. AStyle.exe --style=1tbs --indent-switches --break-closing-brackets --indent-preprocessor tinyxml2.cpp tinyxml2.h */ -#if defined( _DEBUG ) || defined (__DEBUG__) -# ifndef TINYXML2_DEBUG -# define TINYXML2_DEBUG -# endif +#if defined(_DEBUG) || defined(__DEBUG__) +#ifndef TINYXML2_DEBUG +#define TINYXML2_DEBUG +#endif #endif #ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable: 4251) +#pragma warning(push) +#pragma warning(disable : 4251) #endif #ifdef _WIN32 -# ifdef TINYXML2_EXPORT -# define TINYXML2_LIB __declspec(dllexport) -# elif defined(TINYXML2_IMPORT) -# define TINYXML2_LIB __declspec(dllimport) -# else -# define TINYXML2_LIB -# endif -#elif __GNUC__ >= 4 -# define TINYXML2_LIB __attribute__((visibility("default"))) +#ifdef TINYXML2_EXPORT +#define TINYXML2_LIB __declspec(dllexport) +#elif defined(TINYXML2_IMPORT) +#define TINYXML2_LIB __declspec(dllimport) #else -# define TINYXML2_LIB +#define TINYXML2_LIB +#endif +#elif __GNUC__ >= 4 +#define TINYXML2_LIB __attribute__((visibility("default"))) +#else +#define TINYXML2_LIB #endif - #if defined(TINYXML2_DEBUG) -# if defined(_MSC_VER) -# // "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like -# define TIXMLASSERT( x ) if ( !((void)0,(x))) { __debugbreak(); } -# elif defined (ANDROID_NDK) -# include -# define TIXMLASSERT( x ) if ( !(x)) { __android_log_assert( "assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__ ); } -# else -# include -# define TIXMLASSERT assert -# endif +#if defined(_MSC_VER) +#// "(void)0," is for suppressing C4127 warning in "assert(false)", "assert(true)" and the like +#define TIXMLASSERT(x) \ + if (!((void)0, (x))) \ + { \ + __debugbreak(); \ + } +#elif defined(ANDROID_NDK) +#include +#define TIXMLASSERT(x) \ + if (!(x)) \ + { \ + __android_log_assert("assert", "grinliz", "ASSERT in '%s' at %d.", __FILE__, __LINE__); \ + } #else -# define TIXMLASSERT( x ) {} +#include +#define TIXMLASSERT assert +#endif +#else +#define TIXMLASSERT(x) \ + { \ + } #endif - /* Versioning, past 1.0.14: http://semver.org/ @@ -106,10 +114,10 @@ static const int TIXML2_PATCH_VERSION = 0; #define TINYXML2_MINOR_VERSION 2 #define TINYXML2_PATCH_VERSION 0 -// A fixed element depth limit is problematic. There needs to be a -// limit to avoid a stack overflow. However, that limit varies per -// system, and the capacity of the stack. On the other hand, it's a trivial -// attack that can result from ill, malicious, or even correctly formed XML, +// A fixed element depth limit is problematic. There needs to be a +// limit to avoid a stack overflow. However, that limit varies per +// system, and the capacity of the stack. On the other hand, it's a trivial +// attack that can result from ill, malicious, or even correctly formed XML, // so there needs to be a limit in place. static const int TINYXML2_MAX_ELEMENT_DEPTH = 100; @@ -133,67 +141,71 @@ class XMLPrinter; class StrPair { public: - enum { - NEEDS_ENTITY_PROCESSING = 0x01, - NEEDS_NEWLINE_NORMALIZATION = 0x02, - NEEDS_WHITESPACE_COLLAPSING = 0x04, + enum + { + NEEDS_ENTITY_PROCESSING = 0x01, + NEEDS_NEWLINE_NORMALIZATION = 0x02, + NEEDS_WHITESPACE_COLLAPSING = 0x04, - TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, - TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, - ATTRIBUTE_NAME = 0, - ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, - ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, - COMMENT = NEEDS_NEWLINE_NORMALIZATION - }; + TEXT_ELEMENT = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, + TEXT_ELEMENT_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, + ATTRIBUTE_NAME = 0, + ATTRIBUTE_VALUE = NEEDS_ENTITY_PROCESSING | NEEDS_NEWLINE_NORMALIZATION, + ATTRIBUTE_VALUE_LEAVE_ENTITIES = NEEDS_NEWLINE_NORMALIZATION, + COMMENT = NEEDS_NEWLINE_NORMALIZATION + }; - StrPair() : _flags( 0 ), _start( 0 ), _end( 0 ) {} - ~StrPair(); + StrPair() : _flags(0), _start(0), _end(0) {} + ~StrPair(); - void Set( char* start, char* end, int flags ) { - TIXMLASSERT( start ); - TIXMLASSERT( end ); - Reset(); - _start = start; - _end = end; - _flags = flags | NEEDS_FLUSH; - } + void Set(char* start, char* end, int flags) + { + TIXMLASSERT(start); + TIXMLASSERT(end); + Reset(); + _start = start; + _end = end; + _flags = flags | NEEDS_FLUSH; + } - const char* GetStr(); + const char* GetStr(); - bool Empty() const { - return _start == _end; - } + bool Empty() const + { + return _start == _end; + } - void SetInternedStr( const char* str ) { - Reset(); - _start = const_cast(str); - } + void SetInternedStr(const char* str) + { + Reset(); + _start = const_cast(str); + } - void SetStr( const char* str, int flags=0 ); + void SetStr(const char* str, int flags = 0); - char* ParseText( char* in, const char* endTag, int strFlags, int* curLineNumPtr ); - char* ParseName( char* in ); + char* ParseText(char* in, const char* endTag, int strFlags, int* curLineNumPtr); + char* ParseName(char* in); - void TransferTo( StrPair* other ); + void TransferTo(StrPair* other); void Reset(); private: - void CollapseWhitespace(); + void CollapseWhitespace(); - enum { - NEEDS_FLUSH = 0x100, - NEEDS_DELETE = 0x200 - }; + enum + { + NEEDS_FLUSH = 0x100, + NEEDS_DELETE = 0x200 + }; - int _flags; - char* _start; - char* _end; + int _flags; + char* _start; + char* _end; - StrPair( const StrPair& other ); // not supported - void operator=( StrPair& other ); // not supported, use TransferTo() + StrPair(const StrPair& other); // not supported + void operator=(StrPair& other); // not supported, use TransferTo() }; - /* A dynamic array of Plain Old Data. Doesn't support constructors, etc. Has a small initial memory pool, so that low or no usage will not @@ -203,123 +215,140 @@ template class DynArray { public: - DynArray() : - _mem( _pool ), - _allocated( INITIAL_SIZE ), - _size( 0 ) - { - } + DynArray() : _mem(_pool), + _allocated(INITIAL_SIZE), + _size(0) + { + } - ~DynArray() { - if ( _mem != _pool ) { - delete [] _mem; - } - } + ~DynArray() + { + if (_mem != _pool) + { + delete[] _mem; + } + } - void Clear() { - _size = 0; - } + void Clear() + { + _size = 0; + } - void Push( T t ) { - TIXMLASSERT( _size < INT_MAX ); - EnsureCapacity( _size+1 ); - _mem[_size] = t; - ++_size; - } + void Push(T t) + { + TIXMLASSERT(_size < INT_MAX); + EnsureCapacity(_size + 1); + _mem[_size] = t; + ++_size; + } - T* PushArr( int count ) { - TIXMLASSERT( count >= 0 ); - TIXMLASSERT( _size <= INT_MAX - count ); - EnsureCapacity( _size+count ); - T* ret = &_mem[_size]; - _size += count; - return ret; - } + T* PushArr(int count) + { + TIXMLASSERT(count >= 0); + TIXMLASSERT(_size <= INT_MAX - count); + EnsureCapacity(_size + count); + T* ret = &_mem[_size]; + _size += count; + return ret; + } - T Pop() { - TIXMLASSERT( _size > 0 ); - --_size; - return _mem[_size]; - } + T Pop() + { + TIXMLASSERT(_size > 0); + --_size; + return _mem[_size]; + } - void PopArr( int count ) { - TIXMLASSERT( _size >= count ); - _size -= count; - } + void PopArr(int count) + { + TIXMLASSERT(_size >= count); + _size -= count; + } - bool Empty() const { - return _size == 0; - } + bool Empty() const + { + return _size == 0; + } - T& operator[](int i) { - TIXMLASSERT( i>= 0 && i < _size ); - return _mem[i]; - } + T& operator[](int i) + { + TIXMLASSERT(i >= 0 && i < _size); + return _mem[i]; + } - const T& operator[](int i) const { - TIXMLASSERT( i>= 0 && i < _size ); - return _mem[i]; - } + const T& operator[](int i) const + { + TIXMLASSERT(i >= 0 && i < _size); + return _mem[i]; + } - const T& PeekTop() const { - TIXMLASSERT( _size > 0 ); - return _mem[ _size - 1]; - } + const T& PeekTop() const + { + TIXMLASSERT(_size > 0); + return _mem[_size - 1]; + } - int Size() const { - TIXMLASSERT( _size >= 0 ); - return _size; - } + int Size() const + { + TIXMLASSERT(_size >= 0); + return _size; + } - int Capacity() const { - TIXMLASSERT( _allocated >= INITIAL_SIZE ); - return _allocated; - } + int Capacity() const + { + TIXMLASSERT(_allocated >= INITIAL_SIZE); + return _allocated; + } - void SwapRemove(int i) { + void SwapRemove(int i) + { TIXMLASSERT(i >= 0 && i < _size); TIXMLASSERT(_size > 0); _mem[i] = _mem[_size - 1]; --_size; } - const T* Mem() const { - TIXMLASSERT( _mem ); - return _mem; - } + const T* Mem() const + { + TIXMLASSERT(_mem); + return _mem; + } - T* Mem() { - TIXMLASSERT( _mem ); - return _mem; - } + T* Mem() + { + TIXMLASSERT(_mem); + return _mem; + } private: - DynArray( const DynArray& ); // not supported - void operator=( const DynArray& ); // not supported + DynArray(const DynArray&); // not supported + void operator=(const DynArray&); // not supported - void EnsureCapacity( int cap ) { - TIXMLASSERT( cap > 0 ); - if ( cap > _allocated ) { - TIXMLASSERT( cap <= INT_MAX / 2 ); - int newAllocated = cap * 2; - T* newMem = new T[newAllocated]; - TIXMLASSERT( newAllocated >= _size ); - memcpy( newMem, _mem, sizeof(T)*_size ); // warning: not using constructors, only works for PODs - if ( _mem != _pool ) { - delete [] _mem; - } - _mem = newMem; - _allocated = newAllocated; - } - } + void EnsureCapacity(int cap) + { + TIXMLASSERT(cap > 0); + if (cap > _allocated) + { + TIXMLASSERT(cap <= INT_MAX / 2); + int newAllocated = cap * 2; + T* newMem = new T[newAllocated]; + TIXMLASSERT(newAllocated >= _size); + memcpy(newMem, _mem, sizeof(T) * _size); // warning: not using constructors, only works for PODs + if (_mem != _pool) + { + delete[] _mem; + } + _mem = newMem; + _allocated = newAllocated; + } + } - T* _mem; - T _pool[INITIAL_SIZE]; - int _allocated; // objects allocated - int _size; // number objects in use + T* _mem; + T _pool[INITIAL_SIZE]; + int _allocated; // objects allocated + int _size; // number objects in use }; - /* Parent virtual class of a pool for fast allocation and deallocation of objects. @@ -327,100 +356,113 @@ private: class MemPool { public: - MemPool() {} - virtual ~MemPool() {} + MemPool() {} + virtual ~MemPool() {} - virtual int ItemSize() const = 0; - virtual void* Alloc() = 0; - virtual void Free( void* ) = 0; - virtual void SetTracked() = 0; - virtual void Clear() = 0; + virtual int ItemSize() const = 0; + virtual void* Alloc() = 0; + virtual void Free(void*) = 0; + virtual void SetTracked() = 0; + virtual void Clear() = 0; }; - /* Template child class to create pools of the correct type. */ -template< int ITEM_SIZE > +template class MemPoolT : public MemPool { public: - MemPoolT() : _blockPtrs(), _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {} - ~MemPoolT() { - Clear(); - } - - void Clear() { - // Delete the blocks. - while( !_blockPtrs.Empty()) { - Block* lastBlock = _blockPtrs.Pop(); - delete lastBlock; - } - _root = 0; - _currentAllocs = 0; - _nAllocs = 0; - _maxAllocs = 0; - _nUntracked = 0; - } + MemPoolT() : _blockPtrs(), _root(0), _currentAllocs(0), _nAllocs(0), _maxAllocs(0), _nUntracked(0) {} + ~MemPoolT() + { + Clear(); + } - virtual int ItemSize() const { - return ITEM_SIZE; - } - int CurrentAllocs() const { - return _currentAllocs; - } + void Clear() + { + // Delete the blocks. + while (!_blockPtrs.Empty()) + { + Block* lastBlock = _blockPtrs.Pop(); + delete lastBlock; + } + _root = 0; + _currentAllocs = 0; + _nAllocs = 0; + _maxAllocs = 0; + _nUntracked = 0; + } - virtual void* Alloc() { - if ( !_root ) { - // Need a new block. - Block* block = new Block(); - _blockPtrs.Push( block ); + virtual int ItemSize() const + { + return ITEM_SIZE; + } + int CurrentAllocs() const + { + return _currentAllocs; + } - Item* blockItems = block->items; - for( int i = 0; i < ITEMS_PER_BLOCK - 1; ++i ) { - blockItems[i].next = &(blockItems[i + 1]); - } - blockItems[ITEMS_PER_BLOCK - 1].next = 0; - _root = blockItems; - } - Item* const result = _root; - TIXMLASSERT( result != 0 ); - _root = _root->next; + virtual void* Alloc() + { + if (!_root) + { + // Need a new block. + Block* block = new Block(); + _blockPtrs.Push(block); - ++_currentAllocs; - if ( _currentAllocs > _maxAllocs ) { - _maxAllocs = _currentAllocs; - } - ++_nAllocs; - ++_nUntracked; - return result; - } - - virtual void Free( void* mem ) { - if ( !mem ) { - return; - } - --_currentAllocs; - Item* item = static_cast( mem ); + Item* blockItems = block->items; + for (int i = 0; i < ITEMS_PER_BLOCK - 1; ++i) + { + blockItems[i].next = &(blockItems[i + 1]); + } + blockItems[ITEMS_PER_BLOCK - 1].next = 0; + _root = blockItems; + } + Item* const result = _root; + TIXMLASSERT(result != 0); + _root = _root->next; + + ++_currentAllocs; + if (_currentAllocs > _maxAllocs) + { + _maxAllocs = _currentAllocs; + } + ++_nAllocs; + ++_nUntracked; + return result; + } + + virtual void Free(void* mem) + { + if (!mem) + { + return; + } + --_currentAllocs; + Item* item = static_cast(mem); #ifdef TINYXML2_DEBUG - memset( item, 0xfe, sizeof( *item ) ); + memset(item, 0xfe, sizeof(*item)); #endif - item->next = _root; - _root = item; - } - void Trace( const char* name ) { - printf( "Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n", - name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs, - ITEM_SIZE, _nAllocs, _blockPtrs.Size() ); - } + item->next = _root; + _root = item; + } + void Trace(const char* name) + { + printf("Mempool %s watermark=%d [%dk] current=%d size=%d nAlloc=%d blocks=%d\n", + name, _maxAllocs, _maxAllocs * ITEM_SIZE / 1024, _currentAllocs, + ITEM_SIZE, _nAllocs, _blockPtrs.Size()); + } - void SetTracked() { - --_nUntracked; - } + void SetTracked() + { + --_nUntracked; + } - int Untracked() const { - return _nUntracked; - } + int Untracked() const + { + return _nUntracked; + } // This number is perf sensitive. 4k seems like a good tradeoff on my machine. // The test file is large, 170k. @@ -431,32 +473,34 @@ public: // 16k: 5200 // 32k: 4300 // 64k: 4000 21000 - // Declared public because some compilers do not accept to use ITEMS_PER_BLOCK - // in private part if ITEMS_PER_BLOCK is private - enum { ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE }; + // Declared public because some compilers do not accept to use ITEMS_PER_BLOCK + // in private part if ITEMS_PER_BLOCK is private + enum + { + ITEMS_PER_BLOCK = (4 * 1024) / ITEM_SIZE + }; private: - MemPoolT( const MemPoolT& ); // not supported - void operator=( const MemPoolT& ); // not supported + MemPoolT(const MemPoolT&); // not supported + void operator=(const MemPoolT&); // not supported - union Item { - Item* next; - char itemData[ITEM_SIZE]; - }; - struct Block { - Item items[ITEMS_PER_BLOCK]; - }; - DynArray< Block*, 10 > _blockPtrs; - Item* _root; + union Item { + Item* next; + char itemData[ITEM_SIZE]; + }; + struct Block + { + Item items[ITEMS_PER_BLOCK]; + }; + DynArray _blockPtrs; + Item* _root; - int _currentAllocs; - int _nAllocs; - int _maxAllocs; - int _nUntracked; + int _currentAllocs; + int _nAllocs; + int _maxAllocs; + int _nUntracked; }; - - /** Implements the interface to the "Visitor pattern" (see the Accept() method.) If you call the Accept() method, it requires being passed a XMLVisitor @@ -479,152 +523,169 @@ private: class TINYXML2_LIB XMLVisitor { public: - virtual ~XMLVisitor() {} + virtual ~XMLVisitor() {} - /// Visit a document. - virtual bool VisitEnter( const XMLDocument& /*doc*/ ) { - return true; - } - /// Visit a document. - virtual bool VisitExit( const XMLDocument& /*doc*/ ) { - return true; - } + /// Visit a document. + virtual bool VisitEnter(const XMLDocument& /*doc*/) + { + return true; + } + /// Visit a document. + virtual bool VisitExit(const XMLDocument& /*doc*/) + { + return true; + } - /// Visit an element. - virtual bool VisitEnter( const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/ ) { - return true; - } - /// Visit an element. - virtual bool VisitExit( const XMLElement& /*element*/ ) { - return true; - } + /// Visit an element. + virtual bool VisitEnter(const XMLElement& /*element*/, const XMLAttribute* /*firstAttribute*/) + { + return true; + } + /// Visit an element. + virtual bool VisitExit(const XMLElement& /*element*/) + { + return true; + } - /// Visit a declaration. - virtual bool Visit( const XMLDeclaration& /*declaration*/ ) { - return true; - } - /// Visit a text node. - virtual bool Visit( const XMLText& /*text*/ ) { - return true; - } - /// Visit a comment node. - virtual bool Visit( const XMLComment& /*comment*/ ) { - return true; - } - /// Visit an unknown node. - virtual bool Visit( const XMLUnknown& /*unknown*/ ) { - return true; - } + /// Visit a declaration. + virtual bool Visit(const XMLDeclaration& /*declaration*/) + { + return true; + } + /// Visit a text node. + virtual bool Visit(const XMLText& /*text*/) + { + return true; + } + /// Visit a comment node. + virtual bool Visit(const XMLComment& /*comment*/) + { + return true; + } + /// Visit an unknown node. + virtual bool Visit(const XMLUnknown& /*unknown*/) + { + return true; + } }; // WARNING: must match XMLDocument::_errorNames[] -enum XMLError { - XML_SUCCESS = 0, - XML_NO_ATTRIBUTE, - XML_WRONG_ATTRIBUTE_TYPE, - XML_ERROR_FILE_NOT_FOUND, - XML_ERROR_FILE_COULD_NOT_BE_OPENED, - XML_ERROR_FILE_READ_ERROR, - UNUSED_XML_ERROR_ELEMENT_MISMATCH, // remove at next major version - XML_ERROR_PARSING_ELEMENT, - XML_ERROR_PARSING_ATTRIBUTE, - UNUSED_XML_ERROR_IDENTIFYING_TAG, // remove at next major version - XML_ERROR_PARSING_TEXT, - XML_ERROR_PARSING_CDATA, - XML_ERROR_PARSING_COMMENT, - XML_ERROR_PARSING_DECLARATION, - XML_ERROR_PARSING_UNKNOWN, - XML_ERROR_EMPTY_DOCUMENT, - XML_ERROR_MISMATCHED_ELEMENT, - XML_ERROR_PARSING, - XML_CAN_NOT_CONVERT_TEXT, - XML_NO_TEXT_NODE, +enum XMLError +{ + XML_SUCCESS = 0, + XML_NO_ATTRIBUTE, + XML_WRONG_ATTRIBUTE_TYPE, + XML_ERROR_FILE_NOT_FOUND, + XML_ERROR_FILE_COULD_NOT_BE_OPENED, + XML_ERROR_FILE_READ_ERROR, + UNUSED_XML_ERROR_ELEMENT_MISMATCH, // remove at next major version + XML_ERROR_PARSING_ELEMENT, + XML_ERROR_PARSING_ATTRIBUTE, + UNUSED_XML_ERROR_IDENTIFYING_TAG, // remove at next major version + XML_ERROR_PARSING_TEXT, + XML_ERROR_PARSING_CDATA, + XML_ERROR_PARSING_COMMENT, + XML_ERROR_PARSING_DECLARATION, + XML_ERROR_PARSING_UNKNOWN, + XML_ERROR_EMPTY_DOCUMENT, + XML_ERROR_MISMATCHED_ELEMENT, + XML_ERROR_PARSING, + XML_CAN_NOT_CONVERT_TEXT, + XML_NO_TEXT_NODE, XML_ELEMENT_DEPTH_EXCEEDED, XML_ERROR_COUNT }; - /* Utility functionality. */ class TINYXML2_LIB XMLUtil { public: - static const char* SkipWhiteSpace( const char* p, int* curLineNumPtr ) { - TIXMLASSERT( p ); + static const char* SkipWhiteSpace(const char* p, int* curLineNumPtr) + { + TIXMLASSERT(p); - while( IsWhiteSpace(*p) ) { - if (curLineNumPtr && *p == '\n') { - ++(*curLineNumPtr); - } - ++p; - } - TIXMLASSERT( p ); - return p; - } - static char* SkipWhiteSpace( char* p, int* curLineNumPtr ) { - return const_cast( SkipWhiteSpace( const_cast(p), curLineNumPtr ) ); - } + while (IsWhiteSpace(*p)) + { + if (curLineNumPtr && *p == '\n') + { + ++(*curLineNumPtr); + } + ++p; + } + TIXMLASSERT(p); + return p; + } + static char* SkipWhiteSpace(char* p, int* curLineNumPtr) + { + return const_cast(SkipWhiteSpace(const_cast(p), curLineNumPtr)); + } - // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't - // correct, but simple, and usually works. - static bool IsWhiteSpace( char p ) { - return !IsUTF8Continuation(p) && isspace( static_cast(p) ); - } - - inline static bool IsNameStartChar( unsigned char ch ) { - if ( ch >= 128 ) { - // This is a heuristic guess in attempt to not implement Unicode-aware isalpha() - return true; - } - if ( isalpha( ch ) ) { - return true; - } - return ch == ':' || ch == '_'; - } - - inline static bool IsNameChar( unsigned char ch ) { - return IsNameStartChar( ch ) - || isdigit( ch ) - || ch == '.' - || ch == '-'; - } + // Anything in the high order range of UTF-8 is assumed to not be whitespace. This isn't + // correct, but simple, and usually works. + static bool IsWhiteSpace(char p) + { + return !IsUTF8Continuation(p) && isspace(static_cast(p)); + } - inline static bool StringEqual( const char* p, const char* q, int nChar=INT_MAX ) { - if ( p == q ) { - return true; - } - TIXMLASSERT( p ); - TIXMLASSERT( q ); - TIXMLASSERT( nChar >= 0 ); - return strncmp( p, q, nChar ) == 0; - } - - inline static bool IsUTF8Continuation( char p ) { - return ( p & 0x80 ) != 0; - } + inline static bool IsNameStartChar(unsigned char ch) + { + if (ch >= 128) + { + // This is a heuristic guess in attempt to not implement Unicode-aware isalpha() + return true; + } + if (isalpha(ch)) + { + return true; + } + return ch == ':' || ch == '_'; + } - static const char* ReadBOM( const char* p, bool* hasBOM ); - // p is the starting location, - // the UTF-8 value of the entity will be placed in value, and length filled in. - static const char* GetCharacterRef( const char* p, char* value, int* length ); - static void ConvertUTF32ToUTF8( unsigned long input, char* output, int* length ); + inline static bool IsNameChar(unsigned char ch) + { + return IsNameStartChar(ch) || isdigit(ch) || ch == '.' || ch == '-'; + } - // converts primitive types to strings - static void ToStr( int v, char* buffer, int bufferSize ); - static void ToStr( unsigned v, char* buffer, int bufferSize ); - static void ToStr( bool v, char* buffer, int bufferSize ); - static void ToStr( float v, char* buffer, int bufferSize ); - static void ToStr( double v, char* buffer, int bufferSize ); + inline static bool StringEqual(const char* p, const char* q, int nChar = INT_MAX) + { + if (p == q) + { + return true; + } + TIXMLASSERT(p); + TIXMLASSERT(q); + TIXMLASSERT(nChar >= 0); + return strncmp(p, q, nChar) == 0; + } + + inline static bool IsUTF8Continuation(char p) + { + return (p & 0x80) != 0; + } + + static const char* ReadBOM(const char* p, bool* hasBOM); + // p is the starting location, + // the UTF-8 value of the entity will be placed in value, and length filled in. + static const char* GetCharacterRef(const char* p, char* value, int* length); + static void ConvertUTF32ToUTF8(unsigned long input, char* output, int* length); + + // converts primitive types to strings + static void ToStr(int v, char* buffer, int bufferSize); + static void ToStr(unsigned v, char* buffer, int bufferSize); + static void ToStr(bool v, char* buffer, int bufferSize); + static void ToStr(float v, char* buffer, int bufferSize); + static void ToStr(double v, char* buffer, int bufferSize); static void ToStr(int64_t v, char* buffer, int bufferSize); - // converts strings to primitive types - static bool ToInt( const char* str, int* value ); - static bool ToUnsigned( const char* str, unsigned* value ); - static bool ToBool( const char* str, bool* value ); - static bool ToFloat( const char* str, float* value ); - static bool ToDouble( const char* str, double* value ); + // converts strings to primitive types + static bool ToInt(const char* str, int* value); + static bool ToUnsigned(const char* str, unsigned* value); + static bool ToBool(const char* str, bool* value); + static bool ToFloat(const char* str, float* value); + static bool ToDouble(const char* str, double* value); static bool ToInt64(const char* str, int64_t* value); // Changes what is serialized for a boolean value. @@ -639,7 +700,6 @@ private: static const char* writeBoolFalse; }; - /** XMLNode is a base class for every object that is in the XML Document Object Model (DOM), except XMLAttributes. Nodes have siblings, a parent, and children which can @@ -667,66 +727,80 @@ private: */ class TINYXML2_LIB XMLNode { - friend class XMLDocument; - friend class XMLElement; + friend class XMLDocument; + friend class XMLElement; + public: + /// Get the XMLDocument that owns this XMLNode. + const XMLDocument* GetDocument() const + { + TIXMLASSERT(_document); + return _document; + } + /// Get the XMLDocument that owns this XMLNode. + XMLDocument* GetDocument() + { + TIXMLASSERT(_document); + return _document; + } - /// Get the XMLDocument that owns this XMLNode. - const XMLDocument* GetDocument() const { - TIXMLASSERT( _document ); - return _document; - } - /// Get the XMLDocument that owns this XMLNode. - XMLDocument* GetDocument() { - TIXMLASSERT( _document ); - return _document; - } + /// Safely cast to an Element, or null. + virtual XMLElement* ToElement() + { + return 0; + } + /// Safely cast to Text, or null. + virtual XMLText* ToText() + { + return 0; + } + /// Safely cast to a Comment, or null. + virtual XMLComment* ToComment() + { + return 0; + } + /// Safely cast to a Document, or null. + virtual XMLDocument* ToDocument() + { + return 0; + } + /// Safely cast to a Declaration, or null. + virtual XMLDeclaration* ToDeclaration() + { + return 0; + } + /// Safely cast to an Unknown, or null. + virtual XMLUnknown* ToUnknown() + { + return 0; + } - /// Safely cast to an Element, or null. - virtual XMLElement* ToElement() { - return 0; - } - /// Safely cast to Text, or null. - virtual XMLText* ToText() { - return 0; - } - /// Safely cast to a Comment, or null. - virtual XMLComment* ToComment() { - return 0; - } - /// Safely cast to a Document, or null. - virtual XMLDocument* ToDocument() { - return 0; - } - /// Safely cast to a Declaration, or null. - virtual XMLDeclaration* ToDeclaration() { - return 0; - } - /// Safely cast to an Unknown, or null. - virtual XMLUnknown* ToUnknown() { - return 0; - } + virtual const XMLElement* ToElement() const + { + return 0; + } + virtual const XMLText* ToText() const + { + return 0; + } + virtual const XMLComment* ToComment() const + { + return 0; + } + virtual const XMLDocument* ToDocument() const + { + return 0; + } + virtual const XMLDeclaration* ToDeclaration() const + { + return 0; + } + virtual const XMLUnknown* ToUnknown() const + { + return 0; + } - virtual const XMLElement* ToElement() const { - return 0; - } - virtual const XMLText* ToText() const { - return 0; - } - virtual const XMLComment* ToComment() const { - return 0; - } - virtual const XMLDocument* ToDocument() const { - return 0; - } - virtual const XMLDeclaration* ToDeclaration() const { - return 0; - } - virtual const XMLUnknown* ToUnknown() const { - return 0; - } - - /** The meaning of 'value' changes for the specific type. + /** The meaning of 'value' changes for the specific type. @verbatim Document: empty (NULL is returned, not an empty string) Element: name of the element @@ -735,119 +809,135 @@ public: Text: the text string @endverbatim */ - const char* Value() const; + const char* Value() const; - /** Set the Value of an XML node. + /** Set the Value of an XML node. @sa Value() */ - void SetValue( const char* val, bool staticMem=false ); + void SetValue(const char* val, bool staticMem = false); - /// Gets the line number the node is in, if the document was parsed from a file. - int GetLineNum() const { return _parseLineNum; } + /// Gets the line number the node is in, if the document was parsed from a file. + int GetLineNum() const { return _parseLineNum; } - /// Get the parent of this node on the DOM. - const XMLNode* Parent() const { - return _parent; - } + /// Get the parent of this node on the DOM. + const XMLNode* Parent() const + { + return _parent; + } - XMLNode* Parent() { - return _parent; - } + XMLNode* Parent() + { + return _parent; + } - /// Returns true if this node has no children. - bool NoChildren() const { - return !_firstChild; - } + /// Returns true if this node has no children. + bool NoChildren() const + { + return !_firstChild; + } - /// Get the first child node, or null if none exists. - const XMLNode* FirstChild() const { - return _firstChild; - } + /// Get the first child node, or null if none exists. + const XMLNode* FirstChild() const + { + return _firstChild; + } - XMLNode* FirstChild() { - return _firstChild; - } + XMLNode* FirstChild() + { + return _firstChild; + } - /** Get the first child element, or optionally the first child + /** Get the first child element, or optionally the first child element with the specified name. */ - const XMLElement* FirstChildElement( const char* name = 0 ) const; + const XMLElement* FirstChildElement(const char* name = 0) const; - XMLElement* FirstChildElement( const char* name = 0 ) { - return const_cast(const_cast(this)->FirstChildElement( name )); - } + XMLElement* FirstChildElement(const char* name = 0) + { + return const_cast(const_cast(this)->FirstChildElement(name)); + } - /// Get the last child node, or null if none exists. - const XMLNode* LastChild() const { - return _lastChild; - } + /// Get the last child node, or null if none exists. + const XMLNode* LastChild() const + { + return _lastChild; + } - XMLNode* LastChild() { - return _lastChild; - } + XMLNode* LastChild() + { + return _lastChild; + } - /** Get the last child element or optionally the last child + /** Get the last child element or optionally the last child element with the specified name. */ - const XMLElement* LastChildElement( const char* name = 0 ) const; + const XMLElement* LastChildElement(const char* name = 0) const; - XMLElement* LastChildElement( const char* name = 0 ) { - return const_cast(const_cast(this)->LastChildElement(name) ); - } + XMLElement* LastChildElement(const char* name = 0) + { + return const_cast(const_cast(this)->LastChildElement(name)); + } - /// Get the previous (left) sibling node of this node. - const XMLNode* PreviousSibling() const { - return _prev; - } + /// Get the previous (left) sibling node of this node. + const XMLNode* PreviousSibling() const + { + return _prev; + } - XMLNode* PreviousSibling() { - return _prev; - } + XMLNode* PreviousSibling() + { + return _prev; + } - /// Get the previous (left) sibling element of this node, with an optionally supplied name. - const XMLElement* PreviousSiblingElement( const char* name = 0 ) const ; + /// Get the previous (left) sibling element of this node, with an optionally supplied name. + const XMLElement* PreviousSiblingElement(const char* name = 0) const; - XMLElement* PreviousSiblingElement( const char* name = 0 ) { - return const_cast(const_cast(this)->PreviousSiblingElement( name ) ); - } + XMLElement* PreviousSiblingElement(const char* name = 0) + { + return const_cast(const_cast(this)->PreviousSiblingElement(name)); + } - /// Get the next (right) sibling node of this node. - const XMLNode* NextSibling() const { - return _next; - } + /// Get the next (right) sibling node of this node. + const XMLNode* NextSibling() const + { + return _next; + } - XMLNode* NextSibling() { - return _next; - } + XMLNode* NextSibling() + { + return _next; + } - /// Get the next (right) sibling element of this node, with an optionally supplied name. - const XMLElement* NextSiblingElement( const char* name = 0 ) const; + /// Get the next (right) sibling element of this node, with an optionally supplied name. + const XMLElement* NextSiblingElement(const char* name = 0) const; - XMLElement* NextSiblingElement( const char* name = 0 ) { - return const_cast(const_cast(this)->NextSiblingElement( name ) ); - } + XMLElement* NextSiblingElement(const char* name = 0) + { + return const_cast(const_cast(this)->NextSiblingElement(name)); + } - /** + /** Add a child node as the last (right) child. If the child node is already part of the document, it is moved from its old location to the new location. Returns the addThis argument or 0 if the node does not belong to the same document. */ - XMLNode* InsertEndChild( XMLNode* addThis ); + XMLNode* InsertEndChild(XMLNode* addThis); - XMLNode* LinkEndChild( XMLNode* addThis ) { - return InsertEndChild( addThis ); - } - /** + XMLNode* LinkEndChild(XMLNode* addThis) + { + return InsertEndChild(addThis); + } + /** Add a child node as the first (left) child. If the child node is already part of the document, it is moved from its old location to the new location. Returns the addThis argument or 0 if the node does not belong to the same document. */ - XMLNode* InsertFirstChild( XMLNode* addThis ); - /** + XMLNode* InsertFirstChild(XMLNode* addThis); + /** Add a node after the specified child node. If the child node is already part of the document, it is moved from its old location to the new location. @@ -855,19 +945,19 @@ public: is not a child of this node, or if the node does not belong to the same document. */ - XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis ); + XMLNode* InsertAfterChild(XMLNode* afterThis, XMLNode* addThis); - /** + /** Delete all the children of this node. */ - void DeleteChildren(); + void DeleteChildren(); - /** + /** Delete a child of this node. */ - void DeleteChild( XMLNode* node ); + void DeleteChild(XMLNode* node); - /** + /** Make a copy of this node, but not its children. You may pass in a Document pointer that will be the owner of the new Node. If the 'document' is @@ -876,7 +966,7 @@ public: Note: if called on a XMLDocument, this will return null. */ - virtual XMLNode* ShallowClone( XMLDocument* document ) const = 0; + virtual XMLNode* ShallowClone(XMLDocument* document) const = 0; /** Make a copy of this node and all its children. @@ -891,17 +981,17 @@ public: top level XMLNodes. You probably want to use XMLDocument::DeepCopy() */ - XMLNode* DeepClone( XMLDocument* target ) const; + XMLNode* DeepClone(XMLDocument* target) const; - /** + /** Test if 2 nodes are the same, but don't test children. The 2 nodes do not need to be in the same Document. Note: if called on a XMLDocument, this will return false. */ - virtual bool ShallowEqual( const XMLNode* compare ) const = 0; + virtual bool ShallowEqual(const XMLNode* compare) const = 0; - /** Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the + /** Accept a hierarchical visit of the nodes in the TinyXML-2 DOM. Every node in the XML tree will be conditionally visited and the host will be called back via the XMLVisitor interface. @@ -923,53 +1013,52 @@ public: const char* xmlcstr = printer.CStr(); @endverbatim */ - virtual bool Accept( XMLVisitor* visitor ) const = 0; + virtual bool Accept(XMLVisitor* visitor) const = 0; /** Set user data into the XMLNode. TinyXML-2 in no way processes or interprets user data. It is initially 0. */ - void SetUserData(void* userData) { _userData = userData; } + void SetUserData(void* userData) { _userData = userData; } /** Get user data set into the XMLNode. TinyXML-2 in no way processes or interprets user data. It is initially 0. */ - void* GetUserData() const { return _userData; } + void* GetUserData() const { return _userData; } protected: - XMLNode( XMLDocument* ); - virtual ~XMLNode(); + XMLNode(XMLDocument*); + virtual ~XMLNode(); - virtual char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr); + virtual char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr); - XMLDocument* _document; - XMLNode* _parent; - mutable StrPair _value; - int _parseLineNum; + XMLDocument* _document; + XMLNode* _parent; + mutable StrPair _value; + int _parseLineNum; - XMLNode* _firstChild; - XMLNode* _lastChild; + XMLNode* _firstChild; + XMLNode* _lastChild; - XMLNode* _prev; - XMLNode* _next; + XMLNode* _prev; + XMLNode* _next; - void* _userData; + void* _userData; private: - MemPool* _memPool; - void Unlink( XMLNode* child ); - static void DeleteNode( XMLNode* node ); - void InsertChildPreamble( XMLNode* insertThis ) const; - const XMLElement* ToElementWithName( const char* name ) const; + MemPool* _memPool; + void Unlink(XMLNode* child); + static void DeleteNode(XMLNode* node); + void InsertChildPreamble(XMLNode* insertThis) const; + const XMLElement* ToElementWithName(const char* name) const; - XMLNode( const XMLNode& ); // not supported - XMLNode& operator=( const XMLNode& ); // not supported + XMLNode(const XMLNode&); // not supported + XMLNode& operator=(const XMLNode&); // not supported }; - /** XML text. Note that a text node can have child element nodes, for example: @@ -984,72 +1073,78 @@ private: */ class TINYXML2_LIB XMLText : public XMLNode { - friend class XMLDocument; + friend class XMLDocument; + public: - virtual bool Accept( XMLVisitor* visitor ) const; + virtual bool Accept(XMLVisitor* visitor) const; - virtual XMLText* ToText() { - return this; - } - virtual const XMLText* ToText() const { - return this; - } + virtual XMLText* ToText() + { + return this; + } + virtual const XMLText* ToText() const + { + return this; + } - /// Declare whether this should be CDATA or standard text. - void SetCData( bool isCData ) { - _isCData = isCData; - } - /// Returns true if this is a CDATA text element. - bool CData() const { - return _isCData; - } + /// Declare whether this should be CDATA or standard text. + void SetCData(bool isCData) + { + _isCData = isCData; + } + /// Returns true if this is a CDATA text element. + bool CData() const + { + return _isCData; + } - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; + virtual XMLNode* ShallowClone(XMLDocument* document) const; + virtual bool ShallowEqual(const XMLNode* compare) const; protected: - XMLText( XMLDocument* doc ) : XMLNode( doc ), _isCData( false ) {} - virtual ~XMLText() {} + XMLText(XMLDocument* doc) : XMLNode(doc), _isCData(false) {} + virtual ~XMLText() {} - char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); + char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr); private: - bool _isCData; + bool _isCData; - XMLText( const XMLText& ); // not supported - XMLText& operator=( const XMLText& ); // not supported + XMLText(const XMLText&); // not supported + XMLText& operator=(const XMLText&); // not supported }; - /** An XML Comment. */ class TINYXML2_LIB XMLComment : public XMLNode { - friend class XMLDocument; + friend class XMLDocument; + public: - virtual XMLComment* ToComment() { - return this; - } - virtual const XMLComment* ToComment() const { - return this; - } + virtual XMLComment* ToComment() + { + return this; + } + virtual const XMLComment* ToComment() const + { + return this; + } - virtual bool Accept( XMLVisitor* visitor ) const; + virtual bool Accept(XMLVisitor* visitor) const; - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; + virtual XMLNode* ShallowClone(XMLDocument* document) const; + virtual bool ShallowEqual(const XMLNode* compare) const; protected: - XMLComment( XMLDocument* doc ); - virtual ~XMLComment(); + XMLComment(XMLDocument* doc); + virtual ~XMLComment(); - char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr); + char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr); private: - XMLComment( const XMLComment& ); // not supported - XMLComment& operator=( const XMLComment& ); // not supported + XMLComment(const XMLComment&); // not supported + XMLComment& operator=(const XMLComment&); // not supported }; - /** In correct XML the declaration is the first entry in the file. @verbatim @@ -1063,32 +1158,34 @@ private: */ class TINYXML2_LIB XMLDeclaration : public XMLNode { - friend class XMLDocument; + friend class XMLDocument; + public: - virtual XMLDeclaration* ToDeclaration() { - return this; - } - virtual const XMLDeclaration* ToDeclaration() const { - return this; - } + virtual XMLDeclaration* ToDeclaration() + { + return this; + } + virtual const XMLDeclaration* ToDeclaration() const + { + return this; + } - virtual bool Accept( XMLVisitor* visitor ) const; + virtual bool Accept(XMLVisitor* visitor) const; - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; + virtual XMLNode* ShallowClone(XMLDocument* document) const; + virtual bool ShallowEqual(const XMLNode* compare) const; protected: - XMLDeclaration( XMLDocument* doc ); - virtual ~XMLDeclaration(); + XMLDeclaration(XMLDocument* doc); + virtual ~XMLDeclaration(); - char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); + char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr); private: - XMLDeclaration( const XMLDeclaration& ); // not supported - XMLDeclaration& operator=( const XMLDeclaration& ); // not supported + XMLDeclaration(const XMLDeclaration&); // not supported + XMLDeclaration& operator=(const XMLDeclaration&); // not supported }; - /** Any tag that TinyXML-2 doesn't recognize is saved as an unknown. It is a tag of text, but should not be modified. It will be written back to the XML, unchanged, when the file @@ -1098,33 +1195,34 @@ private: */ class TINYXML2_LIB XMLUnknown : public XMLNode { - friend class XMLDocument; + friend class XMLDocument; + public: - virtual XMLUnknown* ToUnknown() { - return this; - } - virtual const XMLUnknown* ToUnknown() const { - return this; - } + virtual XMLUnknown* ToUnknown() + { + return this; + } + virtual const XMLUnknown* ToUnknown() const + { + return this; + } - virtual bool Accept( XMLVisitor* visitor ) const; + virtual bool Accept(XMLVisitor* visitor) const; - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; + virtual XMLNode* ShallowClone(XMLDocument* document) const; + virtual bool ShallowEqual(const XMLNode* compare) const; protected: - XMLUnknown( XMLDocument* doc ); - virtual ~XMLUnknown(); + XMLUnknown(XMLDocument* doc); + virtual ~XMLUnknown(); - char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); + char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr); private: - XMLUnknown( const XMLUnknown& ); // not supported - XMLUnknown& operator=( const XMLUnknown& ); // not supported + XMLUnknown(const XMLUnknown&); // not supported + XMLUnknown& operator=(const XMLUnknown&); // not supported }; - - /** An attribute is a name-value pair. Elements have an arbitrary number of attributes, each with a unique name. @@ -1133,140 +1231,155 @@ private: */ class TINYXML2_LIB XMLAttribute { - friend class XMLElement; + friend class XMLElement; + public: - /// The name of the attribute. - const char* Name() const; + /// The name of the attribute. + const char* Name() const; - /// The value of the attribute. - const char* Value() const; + /// The value of the attribute. + const char* Value() const; - /// Gets the line number the attribute is in, if the document was parsed from a file. - int GetLineNum() const { return _parseLineNum; } + /// Gets the line number the attribute is in, if the document was parsed from a file. + int GetLineNum() const { return _parseLineNum; } - /// The next attribute in the list. - const XMLAttribute* Next() const { - return _next; - } + /// The next attribute in the list. + const XMLAttribute* Next() const + { + return _next; + } - /** IntValue interprets the attribute as an integer, and returns the value. + /** IntValue interprets the attribute as an integer, and returns the value. If the value isn't an integer, 0 will be returned. There is no error checking; use QueryIntValue() if you need error checking. */ - int IntValue() const { + int IntValue() const + { int i = 0; QueryIntValue(&i); return i; } - int64_t Int64Value() const { + int64_t Int64Value() const + { int64_t i = 0; QueryInt64Value(&i); return i; } - /// Query as an unsigned integer. See IntValue() - unsigned UnsignedValue() const { - unsigned i=0; - QueryUnsignedValue( &i ); - return i; - } - /// Query as a boolean. See IntValue() - bool BoolValue() const { - bool b=false; - QueryBoolValue( &b ); - return b; - } - /// Query as a double. See IntValue() - double DoubleValue() const { - double d=0; - QueryDoubleValue( &d ); - return d; - } - /// Query as a float. See IntValue() - float FloatValue() const { - float f=0; - QueryFloatValue( &f ); - return f; - } + /// Query as an unsigned integer. See IntValue() + unsigned UnsignedValue() const + { + unsigned i = 0; + QueryUnsignedValue(&i); + return i; + } + /// Query as a boolean. See IntValue() + bool BoolValue() const + { + bool b = false; + QueryBoolValue(&b); + return b; + } + /// Query as a double. See IntValue() + double DoubleValue() const + { + double d = 0; + QueryDoubleValue(&d); + return d; + } + /// Query as a float. See IntValue() + float FloatValue() const + { + float f = 0; + QueryFloatValue(&f); + return f; + } - /** QueryIntValue interprets the attribute as an integer, and returns the value + /** QueryIntValue interprets the attribute as an integer, and returns the value in the provided parameter. The function will return XML_SUCCESS on success, and XML_WRONG_ATTRIBUTE_TYPE if the conversion is not successful. */ - XMLError QueryIntValue( int* value ) const; - /// See QueryIntValue - XMLError QueryUnsignedValue( unsigned int* value ) const; + XMLError QueryIntValue(int* value) const; + /// See QueryIntValue + XMLError QueryUnsignedValue(unsigned int* value) const; /// See QueryIntValue XMLError QueryInt64Value(int64_t* value) const; /// See QueryIntValue - XMLError QueryBoolValue( bool* value ) const; - /// See QueryIntValue - XMLError QueryDoubleValue( double* value ) const; - /// See QueryIntValue - XMLError QueryFloatValue( float* value ) const; + XMLError QueryBoolValue(bool* value) const; + /// See QueryIntValue + XMLError QueryDoubleValue(double* value) const; + /// See QueryIntValue + XMLError QueryFloatValue(float* value) const; - /// Set the attribute to a string value. - void SetAttribute( const char* value ); - /// Set the attribute to value. - void SetAttribute( int value ); - /// Set the attribute to value. - void SetAttribute( unsigned value ); + /// Set the attribute to a string value. + void SetAttribute(const char* value); + /// Set the attribute to value. + void SetAttribute(int value); + /// Set the attribute to value. + void SetAttribute(unsigned value); /// Set the attribute to value. void SetAttribute(int64_t value); /// Set the attribute to value. - void SetAttribute( bool value ); - /// Set the attribute to value. - void SetAttribute( double value ); - /// Set the attribute to value. - void SetAttribute( float value ); + void SetAttribute(bool value); + /// Set the attribute to value. + void SetAttribute(double value); + /// Set the attribute to value. + void SetAttribute(float value); private: - enum { BUF_SIZE = 200 }; + enum + { + BUF_SIZE = 200 + }; - XMLAttribute() : _name(), _value(),_parseLineNum( 0 ), _next( 0 ), _memPool( 0 ) {} - virtual ~XMLAttribute() {} + XMLAttribute() : _name(), _value(), _parseLineNum(0), _next(0), _memPool(0) {} + virtual ~XMLAttribute() {} - XMLAttribute( const XMLAttribute& ); // not supported - void operator=( const XMLAttribute& ); // not supported - void SetName( const char* name ); + XMLAttribute(const XMLAttribute&); // not supported + void operator=(const XMLAttribute&); // not supported + void SetName(const char* name); - char* ParseDeep( char* p, bool processEntities, int* curLineNumPtr ); + char* ParseDeep(char* p, bool processEntities, int* curLineNumPtr); - mutable StrPair _name; - mutable StrPair _value; - int _parseLineNum; - XMLAttribute* _next; - MemPool* _memPool; + mutable StrPair _name; + mutable StrPair _value; + int _parseLineNum; + XMLAttribute* _next; + MemPool* _memPool; }; - /** The element is a container class. It has a value, the element name, and can contain other elements, text, comments, and unknowns. Elements also contain an arbitrary number of attributes. */ class TINYXML2_LIB XMLElement : public XMLNode { - friend class XMLDocument; + friend class XMLDocument; + public: - /// Get the name of an element (which is the Value() of the node.) - const char* Name() const { - return Value(); - } - /// Set the name of the element. - void SetName( const char* str, bool staticMem=false ) { - SetValue( str, staticMem ); - } + /// Get the name of an element (which is the Value() of the node.) + const char* Name() const + { + return Value(); + } + /// Set the name of the element. + void SetName(const char* str, bool staticMem = false) + { + SetValue(str, staticMem); + } - virtual XMLElement* ToElement() { - return this; - } - virtual const XMLElement* ToElement() const { - return this; - } - virtual bool Accept( XMLVisitor* visitor ) const; + virtual XMLElement* ToElement() + { + return this; + } + virtual const XMLElement* ToElement() const + { + return this; + } + virtual bool Accept(XMLVisitor* visitor) const; - /** Given an attribute name, Attribute() returns the value + /** Given an attribute name, Attribute() returns the value for the attribute of that name, or null if none exists. For example: @@ -1289,27 +1402,27 @@ public: } @endverbatim */ - const char* Attribute( const char* name, const char* value=0 ) const; + const char* Attribute(const char* name, const char* value = 0) const; - /** Given an attribute name, IntAttribute() returns the value + /** Given an attribute name, IntAttribute() returns the value of the attribute interpreted as an integer. The default value will be returned if the attribute isn't present, or if there is an error. (For a method with error checking, see QueryIntAttribute()). */ int IntAttribute(const char* name, int defaultValue = 0) const; - /// See IntAttribute() + /// See IntAttribute() unsigned UnsignedAttribute(const char* name, unsigned defaultValue = 0) const; /// See IntAttribute() int64_t Int64Attribute(const char* name, int64_t defaultValue = 0) const; /// See IntAttribute() bool BoolAttribute(const char* name, bool defaultValue = false) const; - /// See IntAttribute() + /// See IntAttribute() double DoubleAttribute(const char* name, double defaultValue = 0) const; - /// See IntAttribute() + /// See IntAttribute() float FloatAttribute(const char* name, float defaultValue = 0) const; - /** Given an attribute name, QueryIntAttribute() returns + /** Given an attribute name, QueryIntAttribute() returns XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion can't be performed, or XML_NO_ATTRIBUTE if the attribute doesn't exist. If successful, the result of the conversion @@ -1322,70 +1435,82 @@ public: QueryIntAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10 @endverbatim */ - XMLError QueryIntAttribute( const char* name, int* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryIntValue( value ); - } - - /// See QueryIntAttribute() - XMLError QueryUnsignedAttribute( const char* name, unsigned int* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryUnsignedValue( value ); - } - - /// See QueryIntAttribute() - XMLError QueryInt64Attribute(const char* name, int64_t* value) const { + XMLError QueryIntAttribute(const char* name, int* value) const + { const XMLAttribute* a = FindAttribute(name); - if (!a) { + if (!a) + { + return XML_NO_ATTRIBUTE; + } + return a->QueryIntValue(value); + } + + /// See QueryIntAttribute() + XMLError QueryUnsignedAttribute(const char* name, unsigned int* value) const + { + const XMLAttribute* a = FindAttribute(name); + if (!a) + { + return XML_NO_ATTRIBUTE; + } + return a->QueryUnsignedValue(value); + } + + /// See QueryIntAttribute() + XMLError QueryInt64Attribute(const char* name, int64_t* value) const + { + const XMLAttribute* a = FindAttribute(name); + if (!a) + { return XML_NO_ATTRIBUTE; } return a->QueryInt64Value(value); } /// See QueryIntAttribute() - XMLError QueryBoolAttribute( const char* name, bool* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryBoolValue( value ); - } - /// See QueryIntAttribute() - XMLError QueryDoubleAttribute( const char* name, double* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryDoubleValue( value ); - } - /// See QueryIntAttribute() - XMLError QueryFloatAttribute( const char* name, float* value ) const { - const XMLAttribute* a = FindAttribute( name ); - if ( !a ) { - return XML_NO_ATTRIBUTE; - } - return a->QueryFloatValue( value ); - } + XMLError QueryBoolAttribute(const char* name, bool* value) const + { + const XMLAttribute* a = FindAttribute(name); + if (!a) + { + return XML_NO_ATTRIBUTE; + } + return a->QueryBoolValue(value); + } + /// See QueryIntAttribute() + XMLError QueryDoubleAttribute(const char* name, double* value) const + { + const XMLAttribute* a = FindAttribute(name); + if (!a) + { + return XML_NO_ATTRIBUTE; + } + return a->QueryDoubleValue(value); + } + /// See QueryIntAttribute() + XMLError QueryFloatAttribute(const char* name, float* value) const + { + const XMLAttribute* a = FindAttribute(name); + if (!a) + { + return XML_NO_ATTRIBUTE; + } + return a->QueryFloatValue(value); + } /// See QueryIntAttribute() - XMLError QueryStringAttribute(const char* name, const char** value) const { + XMLError QueryStringAttribute(const char* name, const char** value) const + { const XMLAttribute* a = FindAttribute(name); - if (!a) { + if (!a) + { return XML_NO_ATTRIBUTE; } *value = a->Value(); return XML_SUCCESS; } - - - /** Given an attribute name, QueryAttribute() returns + /** Given an attribute name, QueryAttribute() returns XML_SUCCESS, XML_WRONG_ATTRIBUTE_TYPE if the conversion can't be performed, or XML_NO_ATTRIBUTE if the attribute doesn't exist. It is overloaded for the primitive types, @@ -1402,81 +1527,95 @@ public: QueryAttribute( "foo", &value ); // if "foo" isn't found, value will still be 10 @endverbatim */ - int QueryAttribute( const char* name, int* value ) const { - return QueryIntAttribute( name, value ); + int QueryAttribute(const char* name, int* value) const + { + return QueryIntAttribute(name, value); } - int QueryAttribute( const char* name, unsigned int* value ) const { - return QueryUnsignedAttribute( name, value ); + int QueryAttribute(const char* name, unsigned int* value) const + { + return QueryUnsignedAttribute(name, value); } - int QueryAttribute(const char* name, int64_t* value) const { + int QueryAttribute(const char* name, int64_t* value) const + { return QueryInt64Attribute(name, value); } - int QueryAttribute( const char* name, bool* value ) const { - return QueryBoolAttribute( name, value ); + int QueryAttribute(const char* name, bool* value) const + { + return QueryBoolAttribute(name, value); } - int QueryAttribute( const char* name, double* value ) const { - return QueryDoubleAttribute( name, value ); + int QueryAttribute(const char* name, double* value) const + { + return QueryDoubleAttribute(name, value); } - int QueryAttribute( const char* name, float* value ) const { - return QueryFloatAttribute( name, value ); + int QueryAttribute(const char* name, float* value) const + { + return QueryFloatAttribute(name, value); } /// Sets the named attribute to value. - void SetAttribute( const char* name, const char* value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, int value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, unsigned value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - + void SetAttribute(const char* name, const char* value) + { + XMLAttribute* a = FindOrCreateAttribute(name); + a->SetAttribute(value); + } /// Sets the named attribute to value. - void SetAttribute(const char* name, int64_t value) { + void SetAttribute(const char* name, int value) + { + XMLAttribute* a = FindOrCreateAttribute(name); + a->SetAttribute(value); + } + /// Sets the named attribute to value. + void SetAttribute(const char* name, unsigned value) + { XMLAttribute* a = FindOrCreateAttribute(name); a->SetAttribute(value); } /// Sets the named attribute to value. - void SetAttribute( const char* name, bool value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, double value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } - /// Sets the named attribute to value. - void SetAttribute( const char* name, float value ) { - XMLAttribute* a = FindOrCreateAttribute( name ); - a->SetAttribute( value ); - } + void SetAttribute(const char* name, int64_t value) + { + XMLAttribute* a = FindOrCreateAttribute(name); + a->SetAttribute(value); + } - /** + /// Sets the named attribute to value. + void SetAttribute(const char* name, bool value) + { + XMLAttribute* a = FindOrCreateAttribute(name); + a->SetAttribute(value); + } + /// Sets the named attribute to value. + void SetAttribute(const char* name, double value) + { + XMLAttribute* a = FindOrCreateAttribute(name); + a->SetAttribute(value); + } + /// Sets the named attribute to value. + void SetAttribute(const char* name, float value) + { + XMLAttribute* a = FindOrCreateAttribute(name); + a->SetAttribute(value); + } + + /** Delete an attribute. */ - void DeleteAttribute( const char* name ); + void DeleteAttribute(const char* name); - /// Return the first attribute in the list. - const XMLAttribute* FirstAttribute() const { - return _rootAttribute; - } - /// Query a specific attribute in the list. - const XMLAttribute* FindAttribute( const char* name ) const; + /// Return the first attribute in the list. + const XMLAttribute* FirstAttribute() const + { + return _rootAttribute; + } + /// Query a specific attribute in the list. + const XMLAttribute* FindAttribute(const char* name) const; - /** Convenience function for easy access to the text inside an element. Although easy + /** Convenience function for easy access to the text inside an element. Although easy and concise, GetText() is limited compared to getting the XMLText child and accessing it directly. @@ -1504,9 +1643,9 @@ public: @endverbatim GetText() will return "This is ". */ - const char* GetText() const; + const char* GetText() const; - /** Convenience function for easy access to the text inside an element. Although easy + /** Convenience function for easy access to the text inside an element. Although easy and concise, SetText() is limited compared to creating an XMLText child and mutating it directly. @@ -1540,21 +1679,21 @@ public: Hullaballoo! @endverbatim */ - void SetText( const char* inText ); - /// Convenience method for setting text inside an element. See SetText() for important limitations. - void SetText( int value ); - /// Convenience method for setting text inside an element. See SetText() for important limitations. - void SetText( unsigned value ); + void SetText(const char* inText); + /// Convenience method for setting text inside an element. See SetText() for important limitations. + void SetText(int value); + /// Convenience method for setting text inside an element. See SetText() for important limitations. + void SetText(unsigned value); /// Convenience method for setting text inside an element. See SetText() for important limitations. void SetText(int64_t value); /// Convenience method for setting text inside an element. See SetText() for important limitations. - void SetText( bool value ); - /// Convenience method for setting text inside an element. See SetText() for important limitations. - void SetText( double value ); - /// Convenience method for setting text inside an element. See SetText() for important limitations. - void SetText( float value ); + void SetText(bool value); + /// Convenience method for setting text inside an element. See SetText() for important limitations. + void SetText(double value); + /// Convenience method for setting text inside an element. See SetText() for important limitations. + void SetText(float value); - /** + /** Convenience method to query the value of a child text node. This is probably best shown by example. Given you have a document is this form: @verbatim @@ -1580,17 +1719,17 @@ public: to the requested type, and XML_NO_TEXT_NODE if there is no child text to query. */ - XMLError QueryIntText( int* ival ) const; - /// See QueryIntText() - XMLError QueryUnsignedText( unsigned* uval ) const; + XMLError QueryIntText(int* ival) const; + /// See QueryIntText() + XMLError QueryUnsignedText(unsigned* uval) const; /// See QueryIntText() XMLError QueryInt64Text(int64_t* uval) const; /// See QueryIntText() - XMLError QueryBoolText( bool* bval ) const; - /// See QueryIntText() - XMLError QueryDoubleText( double* dval ) const; - /// See QueryIntText() - XMLError QueryFloatText( float* fval ) const; + XMLError QueryBoolText(bool* bval) const; + /// See QueryIntText() + XMLError QueryDoubleText(double* dval) const; + /// See QueryIntText() + XMLError QueryFloatText(float* fval) const; int IntText(int defaultValue = 0) const; @@ -1605,51 +1744,56 @@ public: /// See QueryIntText() float FloatText(float defaultValue = 0) const; - // internal: - enum ElementClosingType { - OPEN, // - CLOSED, // - CLOSING // - }; - ElementClosingType ClosingType() const { - return _closingType; - } - virtual XMLNode* ShallowClone( XMLDocument* document ) const; - virtual bool ShallowEqual( const XMLNode* compare ) const; + // internal: + enum ElementClosingType + { + OPEN, // + CLOSED, // + CLOSING // + }; + ElementClosingType ClosingType() const + { + return _closingType; + } + virtual XMLNode* ShallowClone(XMLDocument* document) const; + virtual bool ShallowEqual(const XMLNode* compare) const; protected: - char* ParseDeep( char* p, StrPair* parentEndTag, int* curLineNumPtr ); + char* ParseDeep(char* p, StrPair* parentEndTag, int* curLineNumPtr); private: - XMLElement( XMLDocument* doc ); - virtual ~XMLElement(); - XMLElement( const XMLElement& ); // not supported - void operator=( const XMLElement& ); // not supported + XMLElement(XMLDocument* doc); + virtual ~XMLElement(); + XMLElement(const XMLElement&); // not supported + void operator=(const XMLElement&); // not supported - XMLAttribute* FindAttribute( const char* name ) { - return const_cast(const_cast(this)->FindAttribute( name )); - } - XMLAttribute* FindOrCreateAttribute( const char* name ); - //void LinkAttribute( XMLAttribute* attrib ); - char* ParseAttributes( char* p, int* curLineNumPtr ); - static void DeleteAttribute( XMLAttribute* attribute ); - XMLAttribute* CreateAttribute(); + XMLAttribute* FindAttribute(const char* name) + { + return const_cast(const_cast(this)->FindAttribute(name)); + } + XMLAttribute* FindOrCreateAttribute(const char* name); + //void LinkAttribute( XMLAttribute* attrib ); + char* ParseAttributes(char* p, int* curLineNumPtr); + static void DeleteAttribute(XMLAttribute* attribute); + XMLAttribute* CreateAttribute(); - enum { BUF_SIZE = 200 }; - ElementClosingType _closingType; - // The attribute list is ordered; there is no 'lastAttribute' - // because the list needs to be scanned for dupes before adding - // a new attribute. - XMLAttribute* _rootAttribute; + enum + { + BUF_SIZE = 200 + }; + ElementClosingType _closingType; + // The attribute list is ordered; there is no 'lastAttribute' + // because the list needs to be scanned for dupes before adding + // a new attribute. + XMLAttribute* _rootAttribute; }; - -enum Whitespace { - PRESERVE_WHITESPACE, - COLLAPSE_WHITESPACE +enum Whitespace +{ + PRESERVE_WHITESPACE, + COLLAPSE_WHITESPACE }; - /** A Document binds together all the functionality. It can be saved, loaded, and printed to the screen. All Nodes are connected and allocated to a Document. @@ -1657,29 +1801,32 @@ enum Whitespace { */ class TINYXML2_LIB XMLDocument : public XMLNode { - friend class XMLElement; - // Gives access to SetError and Push/PopDepth, but over-access for everything else. - // Wishing C++ had "internal" scope. - friend class XMLNode; - friend class XMLText; - friend class XMLComment; - friend class XMLDeclaration; - friend class XMLUnknown; + friend class XMLElement; + // Gives access to SetError and Push/PopDepth, but over-access for everything else. + // Wishing C++ had "internal" scope. + friend class XMLNode; + friend class XMLText; + friend class XMLComment; + friend class XMLDeclaration; + friend class XMLUnknown; + public: - /// constructor - XMLDocument( bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE ); - ~XMLDocument(); + /// constructor + XMLDocument(bool processEntities = true, Whitespace whitespaceMode = PRESERVE_WHITESPACE); + ~XMLDocument(); - virtual XMLDocument* ToDocument() { - TIXMLASSERT( this == _document ); - return this; - } - virtual const XMLDocument* ToDocument() const { - TIXMLASSERT( this == _document ); - return this; - } + virtual XMLDocument* ToDocument() + { + TIXMLASSERT(this == _document); + return this; + } + virtual const XMLDocument* ToDocument() const + { + TIXMLASSERT(this == _document); + return this; + } - /** + /** Parse an XML file from a character string. Returns XML_SUCCESS (0) on success, or an errorID. @@ -1689,16 +1836,16 @@ public: specified, TinyXML-2 will assume 'xml' points to a null terminated string. */ - XMLError Parse( const char* xml, size_t nBytes=(size_t)(-1) ); + XMLError Parse(const char* xml, size_t nBytes = (size_t)(-1)); - /** + /** Load an XML file from disk. Returns XML_SUCCESS (0) on success, or an errorID. */ - XMLError LoadFile( const char* filename ); + XMLError LoadFile(const char* filename); - /** + /** Load an XML file from disk. You are responsible for providing and closing the FILE*. @@ -1709,54 +1856,60 @@ public: Returns XML_SUCCESS (0) on success, or an errorID. */ - XMLError LoadFile( FILE* ); + XMLError LoadFile(FILE*); - /** + /** Save the XML file to disk. Returns XML_SUCCESS (0) on success, or an errorID. */ - XMLError SaveFile( const char* filename, bool compact = false ); + XMLError SaveFile(const char* filename, bool compact = false); - /** + /** Save the XML file to disk. You are responsible for providing and closing the FILE*. Returns XML_SUCCESS (0) on success, or an errorID. */ - XMLError SaveFile( FILE* fp, bool compact = false ); + XMLError SaveFile(FILE* fp, bool compact = false); - bool ProcessEntities() const { - return _processEntities; - } - Whitespace WhitespaceMode() const { - return _whitespaceMode; - } + bool ProcessEntities() const + { + return _processEntities; + } + Whitespace WhitespaceMode() const + { + return _whitespaceMode; + } - /** + /** Returns true if this document has a leading Byte Order Mark of UTF8. */ - bool HasBOM() const { - return _writeBOM; - } - /** Sets whether to write the BOM when writing the file. + bool HasBOM() const + { + return _writeBOM; + } + /** Sets whether to write the BOM when writing the file. */ - void SetBOM( bool useBOM ) { - _writeBOM = useBOM; - } + void SetBOM(bool useBOM) + { + _writeBOM = useBOM; + } - /** Return the root element of DOM. Equivalent to FirstChildElement(). + /** Return the root element of DOM. Equivalent to FirstChildElement(). To get the first node, use FirstChild(). */ - XMLElement* RootElement() { - return FirstChildElement(); - } - const XMLElement* RootElement() const { - return FirstChildElement(); - } + XMLElement* RootElement() + { + return FirstChildElement(); + } + const XMLElement* RootElement() const + { + return FirstChildElement(); + } - /** Print the Document. If the Printer is not provided, it will + /** Print the Document. If the Printer is not provided, it will print to stdout. If you provide Printer, this can print to a file: @verbatim XMLPrinter printer( fp ); @@ -1770,28 +1923,28 @@ public: // printer.CStr() has a const char* to the XML @endverbatim */ - void Print( XMLPrinter* streamer=0 ) const; - virtual bool Accept( XMLVisitor* visitor ) const; + void Print(XMLPrinter* streamer = 0) const; + virtual bool Accept(XMLVisitor* visitor) const; - /** + /** Create a new Element associated with this Document. The memory for the Element is managed by the Document. */ - XMLElement* NewElement( const char* name ); - /** + XMLElement* NewElement(const char* name); + /** Create a new Comment associated with this Document. The memory for the Comment is managed by the Document. */ - XMLComment* NewComment( const char* comment ); - /** + XMLComment* NewComment(const char* comment); + /** Create a new Text associated with this Document. The memory for the Text is managed by the Document. */ - XMLText* NewText( const char* text ); - /** + XMLText* NewText(const char* text); + /** Create a new Declaration associated with this Document. The memory for the object is managed by the Document. @@ -1802,51 +1955,54 @@ public: @endverbatim */ - XMLDeclaration* NewDeclaration( const char* text=0 ); - /** + XMLDeclaration* NewDeclaration(const char* text = 0); + /** Create a new Unknown associated with this Document. The memory for the object is managed by the Document. */ - XMLUnknown* NewUnknown( const char* text ); + XMLUnknown* NewUnknown(const char* text); - /** + /** Delete a node associated with this document. It will be unlinked from the DOM. */ - void DeleteNode( XMLNode* node ); + void DeleteNode(XMLNode* node); - void ClearError() { - SetError(XML_SUCCESS, 0, 0); - } + void ClearError() + { + SetError(XML_SUCCESS, 0, 0); + } - /// Return true if there was an error parsing the document. - bool Error() const { - return _errorID != XML_SUCCESS; - } - /// Return the errorID. - XMLError ErrorID() const { - return _errorID; - } + /// Return true if there was an error parsing the document. + bool Error() const + { + return _errorID != XML_SUCCESS; + } + /// Return the errorID. + XMLError ErrorID() const + { + return _errorID; + } const char* ErrorName() const; - static const char* ErrorIDToName(XMLError errorID); + static const char* ErrorIDToName(XMLError errorID); - /** Returns a "long form" error description. A hopefully helpful + /** Returns a "long form" error description. A hopefully helpful diagnostic with location, line number, and/or additional info. */ const char* ErrorStr() const; - /// A (trivial) utility function that prints the ErrorStr() to stdout. - void PrintError() const; + /// A (trivial) utility function that prints the ErrorStr() to stdout. + void PrintError() const; - /// Return the line where the error occured, or zero if unknown. - int ErrorLineNum() const - { - return _errorLineNum; - } - - /// Clear the document, resetting it to the initial state. - void Clear(); + /// Return the line where the error occured, or zero if unknown. + int ErrorLineNum() const + { + return _errorLineNum; + } + + /// Clear the document, resetting it to the initial state. + void Clear(); /** Copies this document to a target document. @@ -1858,31 +2014,33 @@ public: void DeepCopy(XMLDocument* target) const; // internal - char* Identify( char* p, XMLNode** node ); + char* Identify(char* p, XMLNode** node); // internal void MarkInUse(XMLNode*); - virtual XMLNode* ShallowClone( XMLDocument* /*document*/ ) const { - return 0; - } - virtual bool ShallowEqual( const XMLNode* /*compare*/ ) const { - return false; - } + virtual XMLNode* ShallowClone(XMLDocument* /*document*/) const + { + return 0; + } + virtual bool ShallowEqual(const XMLNode* /*compare*/) const + { + return false; + } private: - XMLDocument( const XMLDocument& ); // not supported - void operator=( const XMLDocument& ); // not supported + XMLDocument(const XMLDocument&); // not supported + void operator=(const XMLDocument&); // not supported - bool _writeBOM; - bool _processEntities; - XMLError _errorID; - Whitespace _whitespaceMode; - mutable StrPair _errorStr; - int _errorLineNum; - char* _charBuffer; - int _parseCurLineNum; - int _parsingDepth; + bool _writeBOM; + bool _processEntities; + XMLError _errorID; + Whitespace _whitespaceMode; + mutable StrPair _errorStr; + int _errorLineNum; + char* _charBuffer; + int _parseCurLineNum; + int _parsingDepth; // Memory tracking does add some overhead. // However, the code assumes that you don't // have a bunch of unlinked nodes around. @@ -1891,50 +2049,54 @@ private: // and the performance is the same. DynArray _unlinked; - MemPoolT< sizeof(XMLElement) > _elementPool; - MemPoolT< sizeof(XMLAttribute) > _attributePool; - MemPoolT< sizeof(XMLText) > _textPool; - MemPoolT< sizeof(XMLComment) > _commentPool; + MemPoolT _elementPool; + MemPoolT _attributePool; + MemPoolT _textPool; + MemPoolT _commentPool; static const char* _errorNames[XML_ERROR_COUNT]; - void Parse(); + void Parse(); - void SetError( XMLError error, int lineNum, const char* format, ... ); + void SetError(XMLError error, int lineNum, const char* format, ...); // Something of an obvious security hole, once it was discovered. // Either an ill-formed XML or an excessively deep one can overflow // the stack. Track stack depth, and error out if needed. - class DepthTracker { + class DepthTracker + { public: - DepthTracker(XMLDocument * document) { - this->_document = document; + DepthTracker(XMLDocument* document) + { + this->_document = document; document->PushDepth(); } - ~DepthTracker() { + ~DepthTracker() + { _document->PopDepth(); } + private: - XMLDocument * _document; + XMLDocument* _document; }; void PushDepth(); void PopDepth(); - template - NodeType* CreateUnlinkedNode( MemPoolT& pool ); + template + NodeType* CreateUnlinkedNode(MemPoolT& pool); }; -template -inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT& pool ) +template +inline NodeType* XMLDocument::CreateUnlinkedNode(MemPoolT& pool) { - TIXMLASSERT( sizeof( NodeType ) == PoolElementSize ); - TIXMLASSERT( sizeof( NodeType ) == pool.ItemSize() ); - NodeType* returnNode = new (pool.Alloc()) NodeType( this ); - TIXMLASSERT( returnNode ); - returnNode->_memPool = &pool; + TIXMLASSERT(sizeof(NodeType) == PoolElementSize); + TIXMLASSERT(sizeof(NodeType) == pool.ItemSize()); + NodeType* returnNode = new (pool.Alloc()) NodeType(this); + TIXMLASSERT(returnNode); + returnNode->_memPool = &pool; _unlinked.Push(returnNode); - return returnNode; + return returnNode; } /** @@ -1995,80 +2157,96 @@ inline NodeType* XMLDocument::CreateUnlinkedNode( MemPoolT& poo class TINYXML2_LIB XMLHandle { public: - /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. - XMLHandle( XMLNode* node ) : _node( node ) { - } - /// Create a handle from a node. - XMLHandle( XMLNode& node ) : _node( &node ) { - } - /// Copy constructor - XMLHandle( const XMLHandle& ref ) : _node( ref._node ) { - } - /// Assignment - XMLHandle& operator=( const XMLHandle& ref ) { - _node = ref._node; - return *this; - } + /// Create a handle from any node (at any depth of the tree.) This can be a null pointer. + XMLHandle(XMLNode* node) : _node(node) + { + } + /// Create a handle from a node. + XMLHandle(XMLNode& node) : _node(&node) + { + } + /// Copy constructor + XMLHandle(const XMLHandle& ref) : _node(ref._node) + { + } + /// Assignment + XMLHandle& operator=(const XMLHandle& ref) + { + _node = ref._node; + return *this; + } - /// Get the first child of this handle. - XMLHandle FirstChild() { - return XMLHandle( _node ? _node->FirstChild() : 0 ); - } - /// Get the first child element of this handle. - XMLHandle FirstChildElement( const char* name = 0 ) { - return XMLHandle( _node ? _node->FirstChildElement( name ) : 0 ); - } - /// Get the last child of this handle. - XMLHandle LastChild() { - return XMLHandle( _node ? _node->LastChild() : 0 ); - } - /// Get the last child element of this handle. - XMLHandle LastChildElement( const char* name = 0 ) { - return XMLHandle( _node ? _node->LastChildElement( name ) : 0 ); - } - /// Get the previous sibling of this handle. - XMLHandle PreviousSibling() { - return XMLHandle( _node ? _node->PreviousSibling() : 0 ); - } - /// Get the previous sibling element of this handle. - XMLHandle PreviousSiblingElement( const char* name = 0 ) { - return XMLHandle( _node ? _node->PreviousSiblingElement( name ) : 0 ); - } - /// Get the next sibling of this handle. - XMLHandle NextSibling() { - return XMLHandle( _node ? _node->NextSibling() : 0 ); - } - /// Get the next sibling element of this handle. - XMLHandle NextSiblingElement( const char* name = 0 ) { - return XMLHandle( _node ? _node->NextSiblingElement( name ) : 0 ); - } + /// Get the first child of this handle. + XMLHandle FirstChild() + { + return XMLHandle(_node ? _node->FirstChild() : 0); + } + /// Get the first child element of this handle. + XMLHandle FirstChildElement(const char* name = 0) + { + return XMLHandle(_node ? _node->FirstChildElement(name) : 0); + } + /// Get the last child of this handle. + XMLHandle LastChild() + { + return XMLHandle(_node ? _node->LastChild() : 0); + } + /// Get the last child element of this handle. + XMLHandle LastChildElement(const char* name = 0) + { + return XMLHandle(_node ? _node->LastChildElement(name) : 0); + } + /// Get the previous sibling of this handle. + XMLHandle PreviousSibling() + { + return XMLHandle(_node ? _node->PreviousSibling() : 0); + } + /// Get the previous sibling element of this handle. + XMLHandle PreviousSiblingElement(const char* name = 0) + { + return XMLHandle(_node ? _node->PreviousSiblingElement(name) : 0); + } + /// Get the next sibling of this handle. + XMLHandle NextSibling() + { + return XMLHandle(_node ? _node->NextSibling() : 0); + } + /// Get the next sibling element of this handle. + XMLHandle NextSiblingElement(const char* name = 0) + { + return XMLHandle(_node ? _node->NextSiblingElement(name) : 0); + } - /// Safe cast to XMLNode. This can return null. - XMLNode* ToNode() { - return _node; - } - /// Safe cast to XMLElement. This can return null. - XMLElement* ToElement() { - return ( _node ? _node->ToElement() : 0 ); - } - /// Safe cast to XMLText. This can return null. - XMLText* ToText() { - return ( _node ? _node->ToText() : 0 ); - } - /// Safe cast to XMLUnknown. This can return null. - XMLUnknown* ToUnknown() { - return ( _node ? _node->ToUnknown() : 0 ); - } - /// Safe cast to XMLDeclaration. This can return null. - XMLDeclaration* ToDeclaration() { - return ( _node ? _node->ToDeclaration() : 0 ); - } + /// Safe cast to XMLNode. This can return null. + XMLNode* ToNode() + { + return _node; + } + /// Safe cast to XMLElement. This can return null. + XMLElement* ToElement() + { + return (_node ? _node->ToElement() : 0); + } + /// Safe cast to XMLText. This can return null. + XMLText* ToText() + { + return (_node ? _node->ToText() : 0); + } + /// Safe cast to XMLUnknown. This can return null. + XMLUnknown* ToUnknown() + { + return (_node ? _node->ToUnknown() : 0); + } + /// Safe cast to XMLDeclaration. This can return null. + XMLDeclaration* ToDeclaration() + { + return (_node ? _node->ToDeclaration() : 0); + } private: - XMLNode* _node; + XMLNode* _node; }; - /** A variant of the XMLHandle class for working with const XMLNodes and Documents. It is the same in all regards, except for the 'const' qualifiers. See XMLHandle for API. @@ -2076,65 +2254,80 @@ private: class TINYXML2_LIB XMLConstHandle { public: - XMLConstHandle( const XMLNode* node ) : _node( node ) { - } - XMLConstHandle( const XMLNode& node ) : _node( &node ) { - } - XMLConstHandle( const XMLConstHandle& ref ) : _node( ref._node ) { - } + XMLConstHandle(const XMLNode* node) : _node(node) + { + } + XMLConstHandle(const XMLNode& node) : _node(&node) + { + } + XMLConstHandle(const XMLConstHandle& ref) : _node(ref._node) + { + } - XMLConstHandle& operator=( const XMLConstHandle& ref ) { - _node = ref._node; - return *this; - } + XMLConstHandle& operator=(const XMLConstHandle& ref) + { + _node = ref._node; + return *this; + } - const XMLConstHandle FirstChild() const { - return XMLConstHandle( _node ? _node->FirstChild() : 0 ); - } - const XMLConstHandle FirstChildElement( const char* name = 0 ) const { - return XMLConstHandle( _node ? _node->FirstChildElement( name ) : 0 ); - } - const XMLConstHandle LastChild() const { - return XMLConstHandle( _node ? _node->LastChild() : 0 ); - } - const XMLConstHandle LastChildElement( const char* name = 0 ) const { - return XMLConstHandle( _node ? _node->LastChildElement( name ) : 0 ); - } - const XMLConstHandle PreviousSibling() const { - return XMLConstHandle( _node ? _node->PreviousSibling() : 0 ); - } - const XMLConstHandle PreviousSiblingElement( const char* name = 0 ) const { - return XMLConstHandle( _node ? _node->PreviousSiblingElement( name ) : 0 ); - } - const XMLConstHandle NextSibling() const { - return XMLConstHandle( _node ? _node->NextSibling() : 0 ); - } - const XMLConstHandle NextSiblingElement( const char* name = 0 ) const { - return XMLConstHandle( _node ? _node->NextSiblingElement( name ) : 0 ); - } + const XMLConstHandle FirstChild() const + { + return XMLConstHandle(_node ? _node->FirstChild() : 0); + } + const XMLConstHandle FirstChildElement(const char* name = 0) const + { + return XMLConstHandle(_node ? _node->FirstChildElement(name) : 0); + } + const XMLConstHandle LastChild() const + { + return XMLConstHandle(_node ? _node->LastChild() : 0); + } + const XMLConstHandle LastChildElement(const char* name = 0) const + { + return XMLConstHandle(_node ? _node->LastChildElement(name) : 0); + } + const XMLConstHandle PreviousSibling() const + { + return XMLConstHandle(_node ? _node->PreviousSibling() : 0); + } + const XMLConstHandle PreviousSiblingElement(const char* name = 0) const + { + return XMLConstHandle(_node ? _node->PreviousSiblingElement(name) : 0); + } + const XMLConstHandle NextSibling() const + { + return XMLConstHandle(_node ? _node->NextSibling() : 0); + } + const XMLConstHandle NextSiblingElement(const char* name = 0) const + { + return XMLConstHandle(_node ? _node->NextSiblingElement(name) : 0); + } - - const XMLNode* ToNode() const { - return _node; - } - const XMLElement* ToElement() const { - return ( _node ? _node->ToElement() : 0 ); - } - const XMLText* ToText() const { - return ( _node ? _node->ToText() : 0 ); - } - const XMLUnknown* ToUnknown() const { - return ( _node ? _node->ToUnknown() : 0 ); - } - const XMLDeclaration* ToDeclaration() const { - return ( _node ? _node->ToDeclaration() : 0 ); - } + const XMLNode* ToNode() const + { + return _node; + } + const XMLElement* ToElement() const + { + return (_node ? _node->ToElement() : 0); + } + const XMLText* ToText() const + { + return (_node ? _node->ToText() : 0); + } + const XMLUnknown* ToUnknown() const + { + return (_node ? _node->ToUnknown() : 0); + } + const XMLDeclaration* ToDeclaration() const + { + return (_node ? _node->ToDeclaration() : 0); + } private: - const XMLNode* _node; + const XMLNode* _node; }; - /** Printing functionality. The XMLPrinter gives you more options than the XMLDocument::Print() method. @@ -2180,135 +2373,139 @@ private: class TINYXML2_LIB XMLPrinter : public XMLVisitor { public: - /** Construct the printer. If the FILE* is specified, + /** Construct the printer. If the FILE* is specified, this will print to the FILE. Else it will print to memory, and the result is available in CStr(). If 'compact' is set to true, then output is created with only required whitespace and newlines. */ - XMLPrinter( FILE* file=0, bool compact = false, int depth = 0 ); - virtual ~XMLPrinter() {} + XMLPrinter(FILE* file = 0, bool compact = false, int depth = 0); + virtual ~XMLPrinter() {} - /** If streaming, write the BOM and declaration. */ - void PushHeader( bool writeBOM, bool writeDeclaration ); - /** If streaming, start writing an element. + /** If streaming, write the BOM and declaration. */ + void PushHeader(bool writeBOM, bool writeDeclaration); + /** If streaming, start writing an element. The element must be closed with CloseElement() */ - void OpenElement( const char* name, bool compactMode=false ); - /// If streaming, add an attribute to an open element. - void PushAttribute( const char* name, const char* value ); - void PushAttribute( const char* name, int value ); - void PushAttribute( const char* name, unsigned value ); + void OpenElement(const char* name, bool compactMode = false); + /// If streaming, add an attribute to an open element. + void PushAttribute(const char* name, const char* value); + void PushAttribute(const char* name, int value); + void PushAttribute(const char* name, unsigned value); void PushAttribute(const char* name, int64_t value); - void PushAttribute( const char* name, bool value ); - void PushAttribute( const char* name, double value ); - /// If streaming, close the Element. - virtual void CloseElement( bool compactMode=false ); + void PushAttribute(const char* name, bool value); + void PushAttribute(const char* name, double value); + /// If streaming, close the Element. + virtual void CloseElement(bool compactMode = false); - /// Add a text node. - void PushText( const char* text, bool cdata=false ); - /// Add a text node from an integer. - void PushText( int value ); - /// Add a text node from an unsigned. - void PushText( unsigned value ); + /// Add a text node. + void PushText(const char* text, bool cdata = false); + /// Add a text node from an integer. + void PushText(int value); + /// Add a text node from an unsigned. + void PushText(unsigned value); /// Add a text node from an unsigned. void PushText(int64_t value); /// Add a text node from a bool. - void PushText( bool value ); - /// Add a text node from a float. - void PushText( float value ); - /// Add a text node from a double. - void PushText( double value ); + void PushText(bool value); + /// Add a text node from a float. + void PushText(float value); + /// Add a text node from a double. + void PushText(double value); - /// Add a comment - void PushComment( const char* comment ); + /// Add a comment + void PushComment(const char* comment); - void PushDeclaration( const char* value ); - void PushUnknown( const char* value ); + void PushDeclaration(const char* value); + void PushUnknown(const char* value); - virtual bool VisitEnter( const XMLDocument& /*doc*/ ); - virtual bool VisitExit( const XMLDocument& /*doc*/ ) { - return true; - } + virtual bool VisitEnter(const XMLDocument& /*doc*/); + virtual bool VisitExit(const XMLDocument& /*doc*/) + { + return true; + } - virtual bool VisitEnter( const XMLElement& element, const XMLAttribute* attribute ); - virtual bool VisitExit( const XMLElement& element ); + virtual bool VisitEnter(const XMLElement& element, const XMLAttribute* attribute); + virtual bool VisitExit(const XMLElement& element); - virtual bool Visit( const XMLText& text ); - virtual bool Visit( const XMLComment& comment ); - virtual bool Visit( const XMLDeclaration& declaration ); - virtual bool Visit( const XMLUnknown& unknown ); + virtual bool Visit(const XMLText& text); + virtual bool Visit(const XMLComment& comment); + virtual bool Visit(const XMLDeclaration& declaration); + virtual bool Visit(const XMLUnknown& unknown); - /** + /** If in print to memory mode, return a pointer to the XML file in memory. */ - const char* CStr() const { - return _buffer.Mem(); - } - /** + const char* CStr() const + { + return _buffer.Mem(); + } + /** If in print to memory mode, return the size of the XML file in memory. (Note the size returned includes the terminating null.) */ - int CStrSize() const { - return _buffer.Size(); - } - /** + int CStrSize() const + { + return _buffer.Size(); + } + /** If in print to memory mode, reset the buffer to the beginning. */ - void ClearBuffer() { - _buffer.Clear(); - _buffer.Push(0); + void ClearBuffer() + { + _buffer.Clear(); + _buffer.Push(0); _firstElement = true; - } + } protected: - virtual bool CompactMode( const XMLElement& ) { return _compactMode; } + virtual bool CompactMode(const XMLElement&) { return _compactMode; } /** Prints out the space before an element. You may override to change the space and tabs used. A PrintSpace() override should call Print(). */ - virtual void PrintSpace( int depth ); - void Print( const char* format, ... ); - void Write( const char* data, size_t size ); - inline void Write( const char* data ) { Write( data, strlen( data ) ); } - void Putc( char ch ); + virtual void PrintSpace(int depth); + void Print(const char* format, ...); + void Write(const char* data, size_t size); + inline void Write(const char* data) { Write(data, strlen(data)); } + void Putc(char ch); - void SealElementIfJustOpened(); - bool _elementJustOpened; - DynArray< const char*, 10 > _stack; + void SealElementIfJustOpened(); + bool _elementJustOpened; + DynArray _stack; private: - void PrintString( const char*, bool restrictedEntitySet ); // prints out, after detecting entities. + void PrintString(const char*, bool restrictedEntitySet); // prints out, after detecting entities. - bool _firstElement; - FILE* _fp; - int _depth; - int _textDepth; - bool _processEntities; + bool _firstElement; + FILE* _fp; + int _depth; + int _textDepth; + bool _processEntities; bool _compactMode; - enum { - ENTITY_RANGE = 64, - BUF_SIZE = 200 - }; - bool _entityFlag[ENTITY_RANGE]; - bool _restrictedEntityFlag[ENTITY_RANGE]; + enum + { + ENTITY_RANGE = 64, + BUF_SIZE = 200 + }; + bool _entityFlag[ENTITY_RANGE]; + bool _restrictedEntityFlag[ENTITY_RANGE]; - DynArray< char, 20 > _buffer; + DynArray _buffer; - // Prohibit cloning, intentionally not implemented - XMLPrinter( const XMLPrinter& ); - XMLPrinter& operator=( const XMLPrinter& ); + // Prohibit cloning, intentionally not implemented + XMLPrinter(const XMLPrinter&); + XMLPrinter& operator=(const XMLPrinter&); }; - -} // tinyxml2 +} // namespace tinyxml2 #if defined(_MSC_VER) -# pragma warning(pop) +#pragma warning(pop) #endif -#endif // TINYXML2_INCLUDED +#endif // TINYXML2_INCLUDED diff --git a/examples/ThirdPartyLibs/zlib/adler32.c b/examples/ThirdPartyLibs/zlib/adler32.c index a868f073d..d82464d82 100644 --- a/examples/ThirdPartyLibs/zlib/adler32.c +++ b/examples/ThirdPartyLibs/zlib/adler32.c @@ -11,169 +11,193 @@ local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2)); -#define BASE 65521 /* largest prime smaller than 65536 */ +#define BASE 65521 /* largest prime smaller than 65536 */ #define NMAX 5552 /* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ -#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); +#define DO1(buf, i) \ + { \ + adler += (buf)[i]; \ + sum2 += adler; \ + } +#define DO2(buf, i) \ + DO1(buf, i); \ + DO1(buf, i + 1); +#define DO4(buf, i) \ + DO2(buf, i); \ + DO2(buf, i + 2); +#define DO8(buf, i) \ + DO4(buf, i); \ + DO4(buf, i + 4); +#define DO16(buf) \ + DO8(buf, 0); \ + DO8(buf, 8); /* use NO_DIVIDE if your processor does not do division in hardware -- try it both ways to see which is faster */ #ifdef NO_DIVIDE /* note that this assumes BASE is 65521, where 65536 % 65521 == 15 (thank you to John Reiser for pointing this out) */ -# define CHOP(a) \ - do { \ - unsigned long tmp = a >> 16; \ - a &= 0xffffUL; \ - a += (tmp << 4) - tmp; \ - } while (0) -# define MOD28(a) \ - do { \ - CHOP(a); \ - if (a >= BASE) a -= BASE; \ - } while (0) -# define MOD(a) \ - do { \ - CHOP(a); \ - MOD28(a); \ - } while (0) -# define MOD63(a) \ - do { /* this assumes a is not negative */ \ - z_off64_t tmp = a >> 32; \ - a &= 0xffffffffL; \ - a += (tmp << 8) - (tmp << 5) + tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - tmp = a >> 16; \ - a &= 0xffffL; \ - a += (tmp << 4) - tmp; \ - if (a >= BASE) a -= BASE; \ - } while (0) +#define CHOP(a) \ + do \ + { \ + unsigned long tmp = a >> 16; \ + a &= 0xffffUL; \ + a += (tmp << 4) - tmp; \ + } while (0) +#define MOD28(a) \ + do \ + { \ + CHOP(a); \ + if (a >= BASE) a -= BASE; \ + } while (0) +#define MOD(a) \ + do \ + { \ + CHOP(a); \ + MOD28(a); \ + } while (0) +#define MOD63(a) \ + do \ + { /* this assumes a is not negative */ \ + z_off64_t tmp = a >> 32; \ + a &= 0xffffffffL; \ + a += (tmp << 8) - (tmp << 5) + tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + tmp = a >> 16; \ + a &= 0xffffL; \ + a += (tmp << 4) - tmp; \ + if (a >= BASE) a -= BASE; \ + } while (0) #else -# define MOD(a) a %= BASE -# define MOD28(a) a %= BASE -# define MOD63(a) a %= BASE +#define MOD(a) a %= BASE +#define MOD28(a) a %= BASE +#define MOD63(a) a %= BASE #endif /* ========================================================================= */ uLong ZEXPORT adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; + uLong adler; +const Bytef *buf; +uInt len; { - unsigned long sum2; - unsigned n; + unsigned long sum2; + unsigned n; - /* split Adler-32 into component sums */ - sum2 = (adler >> 16) & 0xffff; - adler &= 0xffff; + /* split Adler-32 into component sums */ + sum2 = (adler >> 16) & 0xffff; + adler &= 0xffff; - /* in case user likes doing a byte at a time, keep it fast */ - if (len == 1) { - adler += buf[0]; - if (adler >= BASE) - adler -= BASE; - sum2 += adler; - if (sum2 >= BASE) - sum2 -= BASE; - return adler | (sum2 << 16); - } + /* in case user likes doing a byte at a time, keep it fast */ + if (len == 1) + { + adler += buf[0]; + if (adler >= BASE) + adler -= BASE; + sum2 += adler; + if (sum2 >= BASE) + sum2 -= BASE; + return adler | (sum2 << 16); + } - /* initial Adler-32 value (deferred check for len == 1 speed) */ - if (buf == Z_NULL) - return 1L; + /* initial Adler-32 value (deferred check for len == 1 speed) */ + if (buf == Z_NULL) + return 1L; - /* in case short lengths are provided, keep it somewhat fast */ - if (len < 16) { - while (len--) { - adler += *buf++; - sum2 += adler; - } - if (adler >= BASE) - adler -= BASE; - MOD28(sum2); /* only added so many BASE's */ - return adler | (sum2 << 16); - } + /* in case short lengths are provided, keep it somewhat fast */ + if (len < 16) + { + while (len--) + { + adler += *buf++; + sum2 += adler; + } + if (adler >= BASE) + adler -= BASE; + MOD28(sum2); /* only added so many BASE's */ + return adler | (sum2 << 16); + } - /* do length NMAX blocks -- requires just one modulo operation */ - while (len >= NMAX) { - len -= NMAX; - n = NMAX / 16; /* NMAX is divisible by 16 */ - do { - DO16(buf); /* 16 sums unrolled */ - buf += 16; - } while (--n); - MOD(adler); - MOD(sum2); - } + /* do length NMAX blocks -- requires just one modulo operation */ + while (len >= NMAX) + { + len -= NMAX; + n = NMAX / 16; /* NMAX is divisible by 16 */ + do + { + DO16(buf); /* 16 sums unrolled */ + buf += 16; + } while (--n); + MOD(adler); + MOD(sum2); + } - /* do remaining bytes (less than NMAX, still just one modulo) */ - if (len) { /* avoid modulos if none remaining */ - while (len >= 16) { - len -= 16; - DO16(buf); - buf += 16; - } - while (len--) { - adler += *buf++; - sum2 += adler; - } - MOD(adler); - MOD(sum2); - } + /* do remaining bytes (less than NMAX, still just one modulo) */ + if (len) + { /* avoid modulos if none remaining */ + while (len >= 16) + { + len -= 16; + DO16(buf); + buf += 16; + } + while (len--) + { + adler += *buf++; + sum2 += adler; + } + MOD(adler); + MOD(sum2); + } - /* return recombined sums */ - return adler | (sum2 << 16); + /* return recombined sums */ + return adler | (sum2 << 16); } /* ========================================================================= */ local uLong adler32_combine_(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; + uLong adler1; +uLong adler2; +z_off64_t len2; { - unsigned long sum1; - unsigned long sum2; - unsigned rem; + unsigned long sum1; + unsigned long sum2; + unsigned rem; - /* for negative len, return invalid adler32 as a clue for debugging */ - if (len2 < 0) - return 0xffffffffUL; + /* for negative len, return invalid adler32 as a clue for debugging */ + if (len2 < 0) + return 0xffffffffUL; - /* the derivation of this formula is left as an exercise for the reader */ - MOD63(len2); /* assumes len2 >= 0 */ - rem = (unsigned)len2; - sum1 = adler1 & 0xffff; - sum2 = rem * sum1; - MOD(sum2); - sum1 += (adler2 & 0xffff) + BASE - 1; - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 >= BASE) sum1 -= BASE; - if (sum1 >= BASE) sum1 -= BASE; - if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); - if (sum2 >= BASE) sum2 -= BASE; - return sum1 | (sum2 << 16); + /* the derivation of this formula is left as an exercise for the reader */ + MOD63(len2); /* assumes len2 >= 0 */ + rem = (unsigned)len2; + sum1 = adler1 & 0xffff; + sum2 = rem * sum1; + MOD(sum2); + sum1 += (adler2 & 0xffff) + BASE - 1; + sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; + if (sum1 >= BASE) sum1 -= BASE; + if (sum1 >= BASE) sum1 -= BASE; + if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); + if (sum2 >= BASE) sum2 -= BASE; + return sum1 | (sum2 << 16); } /* ========================================================================= */ uLong ZEXPORT adler32_combine(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off_t len2; + uLong adler1; +uLong adler2; +z_off_t len2; { - return adler32_combine_(adler1, adler2, len2); + return adler32_combine_(adler1, adler2, len2); } uLong ZEXPORT adler32_combine64(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; + uLong adler1; +uLong adler2; +z_off64_t len2; { - return adler32_combine_(adler1, adler2, len2); + return adler32_combine_(adler1, adler2, len2); } diff --git a/examples/ThirdPartyLibs/zlib/compress.c b/examples/ThirdPartyLibs/zlib/compress.c index 6e9762676..fd82f7458 100644 --- a/examples/ThirdPartyLibs/zlib/compress.c +++ b/examples/ThirdPartyLibs/zlib/compress.c @@ -19,62 +19,63 @@ memory, Z_BUF_ERROR if there was not enough room in the output buffer, Z_STREAM_ERROR if the level parameter is invalid. */ -int ZEXPORT compress2 (dest, destLen, source, sourceLen, level) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; - int level; +int ZEXPORT compress2(dest, destLen, source, sourceLen, level) + Bytef *dest; +uLongf *destLen; +const Bytef *source; +uLong sourceLen; +int level; { - z_stream stream; - int err; + z_stream stream; + int err; - stream.next_in = (z_const Bytef *)source; - stream.avail_in = (uInt)sourceLen; + stream.next_in = (z_const Bytef *)source; + stream.avail_in = (uInt)sourceLen; #ifdef MAXSEG_64K - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; #endif - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; - stream.opaque = (voidpf)0; + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; + stream.opaque = (voidpf)0; - err = deflateInit(&stream, level); - if (err != Z_OK) return err; + err = deflateInit(&stream, level); + if (err != Z_OK) return err; - err = deflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - deflateEnd(&stream); - return err == Z_OK ? Z_BUF_ERROR : err; - } - *destLen = stream.total_out; + err = deflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) + { + deflateEnd(&stream); + return err == Z_OK ? Z_BUF_ERROR : err; + } + *destLen = stream.total_out; - err = deflateEnd(&stream); - return err; + err = deflateEnd(&stream); + return err; } /* =========================================================================== */ -int ZEXPORT compress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; +int ZEXPORT compress(dest, destLen, source, sourceLen) + Bytef *dest; +uLongf *destLen; +const Bytef *source; +uLong sourceLen; { - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); + return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION); } /* =========================================================================== If the default memLevel or windowBits for deflateInit() is changed, then this function needs to be updated. */ -uLong ZEXPORT compressBound (sourceLen) - uLong sourceLen; +uLong ZEXPORT compressBound(sourceLen) + uLong sourceLen; { - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13; + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13; } diff --git a/examples/ThirdPartyLibs/zlib/crc32.c b/examples/ThirdPartyLibs/zlib/crc32.c index 979a7190a..fa961731f 100644 --- a/examples/ThirdPartyLibs/zlib/crc32.c +++ b/examples/ThirdPartyLibs/zlib/crc32.c @@ -22,44 +22,43 @@ */ #ifdef MAKECRCH -# include -# ifndef DYNAMIC_CRC_TABLE -# define DYNAMIC_CRC_TABLE -# endif /* !DYNAMIC_CRC_TABLE */ +#include +#ifndef DYNAMIC_CRC_TABLE +#define DYNAMIC_CRC_TABLE +#endif /* !DYNAMIC_CRC_TABLE */ #endif /* MAKECRCH */ -#include "zutil.h" /* for STDC and FAR definitions */ +#include "zutil.h" /* for STDC and FAR definitions */ #define local static /* Definitions for doing the crc four data bytes at a time. */ #if !defined(NOBYFOUR) && defined(Z_U4) -# define BYFOUR +#define BYFOUR #endif #ifdef BYFOUR - local unsigned long crc32_little OF((unsigned long, - const unsigned char FAR *, unsigned)); - local unsigned long crc32_big OF((unsigned long, - const unsigned char FAR *, unsigned)); -# define TBLS 8 +local unsigned long crc32_little OF((unsigned long, + const unsigned char FAR *, unsigned)); +local unsigned long crc32_big OF((unsigned long, + const unsigned char FAR *, unsigned)); +#define TBLS 8 #else -# define TBLS 1 +#define TBLS 1 #endif /* BYFOUR */ /* Local functions for crc concatenation */ local unsigned long gf2_matrix_times OF((unsigned long *mat, - unsigned long vec)); + unsigned long vec)); local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2)); - #ifdef DYNAMIC_CRC_TABLE local volatile int crc_table_empty = 1; local z_crc_t FAR crc_table[TBLS][256]; local void make_crc_table OF((void)); #ifdef MAKECRCH - local void write_table OF((FILE *, const z_crc_t FAR *)); +local void write_table OF((FILE *, const z_crc_t FAR *)); #endif /* MAKECRCH */ /* Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: @@ -89,91 +88,97 @@ local void make_crc_table OF((void)); */ local void make_crc_table() { - z_crc_t c; - int n, k; - z_crc_t poly; /* polynomial exclusive-or pattern */ - /* terms of polynomial defining this crc (except x^32): */ - static volatile int first = 1; /* flag to limit concurrent making */ - static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; + z_crc_t c; + int n, k; + z_crc_t poly; /* polynomial exclusive-or pattern */ + /* terms of polynomial defining this crc (except x^32): */ + static volatile int first = 1; /* flag to limit concurrent making */ + static const unsigned char p[] = {0, 1, 2, 4, 5, 7, 8, 10, 11, 12, 16, 22, 23, 26}; - /* See if another task is already doing this (not thread-safe, but better + /* See if another task is already doing this (not thread-safe, but better than nothing -- significantly reduces duration of vulnerability in case the advice about DYNAMIC_CRC_TABLE is ignored) */ - if (first) { - first = 0; + if (first) + { + first = 0; - /* make exclusive-or pattern from polynomial (0xedb88320UL) */ - poly = 0; - for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++) - poly |= (z_crc_t)1 << (31 - p[n]); + /* make exclusive-or pattern from polynomial (0xedb88320UL) */ + poly = 0; + for (n = 0; n < (int)(sizeof(p) / sizeof(unsigned char)); n++) + poly |= (z_crc_t)1 << (31 - p[n]); - /* generate a crc for every 8-bit value */ - for (n = 0; n < 256; n++) { - c = (z_crc_t)n; - for (k = 0; k < 8; k++) - c = c & 1 ? poly ^ (c >> 1) : c >> 1; - crc_table[0][n] = c; - } + /* generate a crc for every 8-bit value */ + for (n = 0; n < 256; n++) + { + c = (z_crc_t)n; + for (k = 0; k < 8; k++) + c = c & 1 ? poly ^ (c >> 1) : c >> 1; + crc_table[0][n] = c; + } #ifdef BYFOUR - /* generate crc for each value followed by one, two, and three zeros, + /* generate crc for each value followed by one, two, and three zeros, and then the byte reversal of those as well as the first table */ - for (n = 0; n < 256; n++) { - c = crc_table[0][n]; - crc_table[4][n] = ZSWAP32(c); - for (k = 1; k < 4; k++) { - c = crc_table[0][c & 0xff] ^ (c >> 8); - crc_table[k][n] = c; - crc_table[k + 4][n] = ZSWAP32(c); - } - } + for (n = 0; n < 256; n++) + { + c = crc_table[0][n]; + crc_table[4][n] = ZSWAP32(c); + for (k = 1; k < 4; k++) + { + c = crc_table[0][c & 0xff] ^ (c >> 8); + crc_table[k][n] = c; + crc_table[k + 4][n] = ZSWAP32(c); + } + } #endif /* BYFOUR */ - crc_table_empty = 0; - } - else { /* not first */ - /* wait for the other guy to finish (not efficient, but rare) */ - while (crc_table_empty) - ; - } + crc_table_empty = 0; + } + else + { /* not first */ + /* wait for the other guy to finish (not efficient, but rare) */ + while (crc_table_empty) + ; + } #ifdef MAKECRCH - /* write out CRC tables to crc32.h */ - { - FILE *out; + /* write out CRC tables to crc32.h */ + { + FILE *out; - out = fopen("crc32.h", "w"); - if (out == NULL) return; - fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); - fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); - fprintf(out, "local const z_crc_t FAR "); - fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); - write_table(out, crc_table[0]); -# ifdef BYFOUR - fprintf(out, "#ifdef BYFOUR\n"); - for (k = 1; k < 8; k++) { - fprintf(out, " },\n {\n"); - write_table(out, crc_table[k]); - } - fprintf(out, "#endif\n"); -# endif /* BYFOUR */ - fprintf(out, " }\n};\n"); - fclose(out); - } + out = fopen("crc32.h", "w"); + if (out == NULL) return; + fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); + fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); + fprintf(out, "local const z_crc_t FAR "); + fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); + write_table(out, crc_table[0]); +#ifdef BYFOUR + fprintf(out, "#ifdef BYFOUR\n"); + for (k = 1; k < 8; k++) + { + fprintf(out, " },\n {\n"); + write_table(out, crc_table[k]); + } + fprintf(out, "#endif\n"); +#endif /* BYFOUR */ + fprintf(out, " }\n};\n"); + fclose(out); + } #endif /* MAKECRCH */ } #ifdef MAKECRCH local void write_table(out, table) - FILE *out; - const z_crc_t FAR *table; + FILE *out; +const z_crc_t FAR *table; { - int n; + int n; - for (n = 0; n < 256; n++) - fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", - (unsigned long)(table[n]), - n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); + for (n = 0; n < 256; n++) + fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", + (unsigned long)(table[n]), + n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); } #endif /* MAKECRCH */ @@ -187,239 +192,274 @@ local void write_table(out, table) /* ========================================================================= * This function can be used by asm versions of crc32() */ -const z_crc_t FAR * ZEXPORT get_crc_table() +const z_crc_t FAR *ZEXPORT get_crc_table() { #ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); + if (crc_table_empty) + make_crc_table(); #endif /* DYNAMIC_CRC_TABLE */ - return (const z_crc_t FAR *)crc_table; + return (const z_crc_t FAR *)crc_table; } /* ========================================================================= */ #define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) -#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 +#define DO8 \ + DO1; \ + DO1; \ + DO1; \ + DO1; \ + DO1; \ + DO1; \ + DO1; \ + DO1 /* ========================================================================= */ -unsigned long ZEXPORT crc32(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - uInt len; +unsigned long ZEXPORT crc32(crc, buf, len) unsigned long crc; +const unsigned char FAR *buf; +uInt len; { - if (buf == Z_NULL) return 0UL; + if (buf == Z_NULL) return 0UL; #ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); + if (crc_table_empty) + make_crc_table(); #endif /* DYNAMIC_CRC_TABLE */ #ifdef BYFOUR - if (sizeof(void *) == sizeof(ptrdiff_t)) { - z_crc_t endian; + if (sizeof(void *) == sizeof(ptrdiff_t)) + { + z_crc_t endian; - endian = 1; - if (*((unsigned char *)(&endian))) - return crc32_little(crc, buf, len); - else - return crc32_big(crc, buf, len); - } + endian = 1; + if (*((unsigned char *)(&endian))) + return crc32_little(crc, buf, len); + else + return crc32_big(crc, buf, len); + } #endif /* BYFOUR */ - crc = crc ^ 0xffffffffUL; - while (len >= 8) { - DO8; - len -= 8; - } - if (len) do { - DO1; - } while (--len); - return crc ^ 0xffffffffUL; + crc = crc ^ 0xffffffffUL; + while (len >= 8) + { + DO8; + len -= 8; + } + if (len) do + { + DO1; + } while (--len); + return crc ^ 0xffffffffUL; } #ifdef BYFOUR /* ========================================================================= */ -#define DOLIT4 c ^= *buf4++; \ - c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ - crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] -#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 +#define DOLIT4 \ + c ^= *buf4++; \ + c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ + crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] +#define DOLIT32 \ + DOLIT4; \ + DOLIT4; \ + DOLIT4; \ + DOLIT4; \ + DOLIT4; \ + DOLIT4; \ + DOLIT4; \ + DOLIT4 /* ========================================================================= */ -local unsigned long crc32_little(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; +local unsigned long crc32_little(crc, buf, len) unsigned long crc; +const unsigned char FAR *buf; +unsigned len; { - register z_crc_t c; - register const z_crc_t FAR *buf4; + register z_crc_t c; + register const z_crc_t FAR *buf4; - c = (z_crc_t)crc; - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - len--; - } + c = (z_crc_t)crc; + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) + { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + len--; + } - buf4 = (const z_crc_t FAR *)(const void FAR *)buf; - while (len >= 32) { - DOLIT32; - len -= 32; - } - while (len >= 4) { - DOLIT4; - len -= 4; - } - buf = (const unsigned char FAR *)buf4; + buf4 = (const z_crc_t FAR *)(const void FAR *)buf; + while (len >= 32) + { + DOLIT32; + len -= 32; + } + while (len >= 4) + { + DOLIT4; + len -= 4; + } + buf = (const unsigned char FAR *)buf4; - if (len) do { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - } while (--len); - c = ~c; - return (unsigned long)c; + if (len) do + { + c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); + } while (--len); + c = ~c; + return (unsigned long)c; } /* ========================================================================= */ -#define DOBIG4 c ^= *++buf4; \ - c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ - crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] -#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 +#define DOBIG4 \ + c ^= *++buf4; \ + c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ + crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] +#define DOBIG32 \ + DOBIG4; \ + DOBIG4; \ + DOBIG4; \ + DOBIG4; \ + DOBIG4; \ + DOBIG4; \ + DOBIG4; \ + DOBIG4 /* ========================================================================= */ -local unsigned long crc32_big(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; +local unsigned long crc32_big(crc, buf, len) unsigned long crc; +const unsigned char FAR *buf; +unsigned len; { - register z_crc_t c; - register const z_crc_t FAR *buf4; + register z_crc_t c; + register const z_crc_t FAR *buf4; - c = ZSWAP32((z_crc_t)crc); - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - len--; - } + c = ZSWAP32((z_crc_t)crc); + c = ~c; + while (len && ((ptrdiff_t)buf & 3)) + { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + len--; + } - buf4 = (const z_crc_t FAR *)(const void FAR *)buf; - buf4--; - while (len >= 32) { - DOBIG32; - len -= 32; - } - while (len >= 4) { - DOBIG4; - len -= 4; - } - buf4++; - buf = (const unsigned char FAR *)buf4; + buf4 = (const z_crc_t FAR *)(const void FAR *)buf; + buf4--; + while (len >= 32) + { + DOBIG32; + len -= 32; + } + while (len >= 4) + { + DOBIG4; + len -= 4; + } + buf4++; + buf = (const unsigned char FAR *)buf4; - if (len) do { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - } while (--len); - c = ~c; - return (unsigned long)(ZSWAP32(c)); + if (len) do + { + c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); + } while (--len); + c = ~c; + return (unsigned long)(ZSWAP32(c)); } #endif /* BYFOUR */ -#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ +#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ /* ========================================================================= */ -local unsigned long gf2_matrix_times(mat, vec) - unsigned long *mat; - unsigned long vec; +local unsigned long gf2_matrix_times(mat, vec) unsigned long *mat; +unsigned long vec; { - unsigned long sum; + unsigned long sum; - sum = 0; - while (vec) { - if (vec & 1) - sum ^= *mat; - vec >>= 1; - mat++; - } - return sum; + sum = 0; + while (vec) + { + if (vec & 1) + sum ^= *mat; + vec >>= 1; + mat++; + } + return sum; } /* ========================================================================= */ -local void gf2_matrix_square(square, mat) - unsigned long *square; - unsigned long *mat; +local void gf2_matrix_square(square, mat) unsigned long *square; +unsigned long *mat; { - int n; + int n; - for (n = 0; n < GF2_DIM; n++) - square[n] = gf2_matrix_times(mat, mat[n]); + for (n = 0; n < GF2_DIM; n++) + square[n] = gf2_matrix_times(mat, mat[n]); } /* ========================================================================= */ local uLong crc32_combine_(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; + uLong crc1; +uLong crc2; +z_off64_t len2; { - int n; - unsigned long row; - unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ - unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ + int n; + unsigned long row; + unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ + unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ - /* degenerate case (also disallow negative lengths) */ - if (len2 <= 0) - return crc1; + /* degenerate case (also disallow negative lengths) */ + if (len2 <= 0) + return crc1; - /* put operator for one zero bit in odd */ - odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ - row = 1; - for (n = 1; n < GF2_DIM; n++) { - odd[n] = row; - row <<= 1; - } + /* put operator for one zero bit in odd */ + odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ + row = 1; + for (n = 1; n < GF2_DIM; n++) + { + odd[n] = row; + row <<= 1; + } - /* put operator for two zero bits in even */ - gf2_matrix_square(even, odd); + /* put operator for two zero bits in even */ + gf2_matrix_square(even, odd); - /* put operator for four zero bits in odd */ - gf2_matrix_square(odd, even); + /* put operator for four zero bits in odd */ + gf2_matrix_square(odd, even); - /* apply len2 zeros to crc1 (first square will put the operator for one + /* apply len2 zeros to crc1 (first square will put the operator for one zero byte, eight zero bits, in even) */ - do { - /* apply zeros operator for this bit of len2 */ - gf2_matrix_square(even, odd); - if (len2 & 1) - crc1 = gf2_matrix_times(even, crc1); - len2 >>= 1; + do + { + /* apply zeros operator for this bit of len2 */ + gf2_matrix_square(even, odd); + if (len2 & 1) + crc1 = gf2_matrix_times(even, crc1); + len2 >>= 1; - /* if no more bits set, then done */ - if (len2 == 0) - break; + /* if no more bits set, then done */ + if (len2 == 0) + break; - /* another iteration of the loop with odd and even swapped */ - gf2_matrix_square(odd, even); - if (len2 & 1) - crc1 = gf2_matrix_times(odd, crc1); - len2 >>= 1; + /* another iteration of the loop with odd and even swapped */ + gf2_matrix_square(odd, even); + if (len2 & 1) + crc1 = gf2_matrix_times(odd, crc1); + len2 >>= 1; - /* if no more bits set, then done */ - } while (len2 != 0); + /* if no more bits set, then done */ + } while (len2 != 0); - /* return combined crc */ - crc1 ^= crc2; - return crc1; + /* return combined crc */ + crc1 ^= crc2; + return crc1; } /* ========================================================================= */ uLong ZEXPORT crc32_combine(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off_t len2; + uLong crc1; +uLong crc2; +z_off_t len2; { - return crc32_combine_(crc1, crc2, len2); + return crc32_combine_(crc1, crc2, len2); } uLong ZEXPORT crc32_combine64(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; + uLong crc1; +uLong crc2; +z_off64_t len2; { - return crc32_combine_(crc1, crc2, len2); + return crc32_combine_(crc1, crc2, len2); } diff --git a/examples/ThirdPartyLibs/zlib/crc32.h b/examples/ThirdPartyLibs/zlib/crc32.h index 9e0c77810..1ba41ad82 100644 --- a/examples/ThirdPartyLibs/zlib/crc32.h +++ b/examples/ThirdPartyLibs/zlib/crc32.h @@ -3,439 +3,424 @@ */ local const z_crc_t FAR crc_table[TBLS][256] = -{ - { - 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, - 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, - 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, - 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, - 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, - 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, - 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, - 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, - 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, - 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, - 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, - 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, - 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, - 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, - 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, - 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, - 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, - 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, - 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, - 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, - 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, - 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, - 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, - 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, - 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, - 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, - 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, - 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, - 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, - 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, - 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, - 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, - 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, - 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, - 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, - 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, - 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, - 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, - 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, - 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, - 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, - 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, - 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, - 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, - 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, - 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, - 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, - 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, - 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, - 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, - 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, - 0x2d02ef8dUL + { + {0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, + 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, + 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, + 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, + 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, + 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, + 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, + 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, + 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, + 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, + 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, + 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, + 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, + 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, + 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, + 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, + 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, + 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, + 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, + 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, + 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, + 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, + 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, + 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, + 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, + 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, + 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, + 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, + 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, + 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, + 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, + 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, + 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, + 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, + 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, + 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, + 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, + 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, + 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, + 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, + 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, + 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, + 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, + 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, + 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, + 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, + 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, + 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, + 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, + 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, + 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, + 0x2d02ef8dUL #ifdef BYFOUR - }, - { - 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, - 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, - 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, - 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, - 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, - 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, - 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, - 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, - 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, - 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, - 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, - 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, - 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, - 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, - 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, - 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, - 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, - 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, - 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, - 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, - 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, - 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, - 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, - 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, - 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, - 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, - 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, - 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, - 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, - 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, - 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, - 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, - 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, - 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, - 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, - 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, - 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, - 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, - 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, - 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, - 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, - 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, - 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, - 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, - 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, - 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, - 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, - 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, - 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, - 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, - 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, - 0x9324fd72UL - }, - { - 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, - 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, - 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, - 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, - 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, - 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, - 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, - 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, - 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, - 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, - 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, - 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, - 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, - 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, - 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, - 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, - 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, - 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, - 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, - 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, - 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, - 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, - 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, - 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, - 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, - 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, - 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, - 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, - 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, - 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, - 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, - 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, - 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, - 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, - 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, - 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, - 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, - 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, - 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, - 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, - 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, - 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, - 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, - 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, - 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, - 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, - 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, - 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, - 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, - 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, - 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, - 0xbe9834edUL - }, - { - 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, - 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, - 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, - 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, - 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, - 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, - 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, - 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, - 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, - 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, - 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, - 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, - 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, - 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, - 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, - 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, - 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, - 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, - 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, - 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, - 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, - 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, - 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, - 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, - 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, - 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, - 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, - 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, - 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, - 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, - 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, - 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, - 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, - 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, - 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, - 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, - 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, - 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, - 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, - 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, - 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, - 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, - 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, - 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, - 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, - 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, - 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, - 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, - 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, - 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, - 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, - 0xde0506f1UL - }, - { - 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, - 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, - 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, - 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, - 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, - 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, - 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, - 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, - 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, - 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, - 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, - 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, - 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, - 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, - 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, - 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, - 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, - 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, - 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, - 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, - 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, - 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, - 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, - 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, - 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, - 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, - 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, - 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, - 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, - 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, - 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, - 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, - 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, - 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, - 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, - 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, - 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, - 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, - 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, - 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, - 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, - 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, - 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, - 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, - 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, - 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, - 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, - 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, - 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, - 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, - 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, - 0x8def022dUL - }, - { - 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, - 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, - 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, - 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, - 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, - 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, - 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, - 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, - 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, - 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, - 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, - 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, - 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, - 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, - 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, - 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, - 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, - 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, - 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, - 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, - 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, - 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, - 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, - 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, - 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, - 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, - 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, - 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, - 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, - 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, - 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, - 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, - 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, - 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, - 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, - 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, - 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, - 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, - 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, - 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, - 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, - 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, - 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, - 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, - 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, - 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, - 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, - 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, - 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, - 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, - 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, - 0x72fd2493UL - }, - { - 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, - 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, - 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, - 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, - 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, - 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, - 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, - 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, - 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, - 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, - 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, - 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, - 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, - 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, - 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, - 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, - 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, - 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, - 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, - 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, - 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, - 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, - 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, - 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, - 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, - 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, - 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, - 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, - 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, - 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, - 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, - 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, - 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, - 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, - 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, - 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, - 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, - 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, - 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, - 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, - 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, - 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, - 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, - 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, - 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, - 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, - 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, - 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, - 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, - 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, - 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, - 0xed3498beUL - }, - { - 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, - 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, - 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, - 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, - 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, - 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, - 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, - 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, - 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, - 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, - 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, - 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, - 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, - 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, - 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, - 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, - 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, - 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, - 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, - 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, - 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, - 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, - 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, - 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, - 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, - 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, - 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, - 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, - 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, - 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, - 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, - 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, - 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, - 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, - 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, - 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, - 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, - 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, - 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, - 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, - 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, - 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, - 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, - 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, - 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, - 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, - 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, - 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, - 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, - 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, - 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, - 0xf10605deUL + }, + {0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, + 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, + 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, + 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, + 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, + 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, + 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, + 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, + 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, + 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, + 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, + 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, + 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, + 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, + 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, + 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, + 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, + 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, + 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, + 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, + 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, + 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, + 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, + 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, + 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, + 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, + 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, + 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, + 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, + 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, + 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, + 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, + 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, + 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, + 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, + 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, + 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, + 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, + 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, + 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, + 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, + 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, + 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, + 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, + 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, + 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, + 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, + 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, + 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, + 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, + 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, + 0x9324fd72UL}, + {0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, + 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, + 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, + 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, + 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, + 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, + 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, + 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, + 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, + 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, + 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, + 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, + 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, + 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, + 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, + 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, + 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, + 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, + 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, + 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, + 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, + 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, + 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, + 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, + 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, + 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, + 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, + 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, + 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, + 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, + 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, + 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, + 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, + 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, + 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, + 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, + 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, + 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, + 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, + 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, + 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, + 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, + 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, + 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, + 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, + 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, + 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, + 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, + 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, + 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, + 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, + 0xbe9834edUL}, + {0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, + 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, + 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, + 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, + 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, + 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, + 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, + 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, + 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, + 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, + 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, + 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, + 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, + 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, + 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, + 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, + 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, + 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, + 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, + 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, + 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, + 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, + 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, + 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, + 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, + 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, + 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, + 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, + 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, + 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, + 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, + 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, + 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, + 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, + 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, + 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, + 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, + 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, + 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, + 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, + 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, + 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, + 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, + 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, + 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, + 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, + 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, + 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, + 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, + 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, + 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, + 0xde0506f1UL}, + {0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, + 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, + 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, + 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, + 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, + 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, + 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, + 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, + 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, + 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, + 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, + 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, + 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, + 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, + 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, + 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, + 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, + 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, + 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, + 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, + 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, + 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, + 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, + 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, + 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, + 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, + 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, + 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, + 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, + 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, + 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, + 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, + 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, + 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, + 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, + 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, + 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, + 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, + 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, + 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, + 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, + 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, + 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, + 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, + 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, + 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, + 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, + 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, + 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, + 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, + 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, + 0x8def022dUL}, + {0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, + 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, + 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, + 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, + 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, + 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, + 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, + 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, + 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, + 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, + 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, + 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, + 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, + 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, + 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, + 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, + 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, + 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, + 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, + 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, + 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, + 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, + 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, + 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, + 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, + 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, + 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, + 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, + 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, + 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, + 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, + 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, + 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, + 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, + 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, + 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, + 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, + 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, + 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, + 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, + 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, + 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, + 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, + 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, + 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, + 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, + 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, + 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, + 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, + 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, + 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, + 0x72fd2493UL}, + {0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, + 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, + 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, + 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, + 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, + 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, + 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, + 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, + 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, + 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, + 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, + 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, + 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, + 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, + 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, + 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, + 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, + 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, + 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, + 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, + 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, + 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, + 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, + 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, + 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, + 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, + 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, + 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, + 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, + 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, + 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, + 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, + 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, + 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, + 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, + 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, + 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, + 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, + 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, + 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, + 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, + 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, + 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, + 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, + 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, + 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, + 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, + 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, + 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, + 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, + 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, + 0xed3498beUL}, + {0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, + 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, + 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, + 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, + 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, + 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, + 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, + 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, + 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, + 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, + 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, + 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, + 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, + 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, + 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, + 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, + 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, + 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, + 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, + 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, + 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, + 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, + 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, + 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, + 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, + 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, + 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, + 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, + 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, + 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, + 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, + 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, + 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, + 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, + 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, + 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, + 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, + 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, + 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, + 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, + 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, + 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, + 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, + 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, + 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, + 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, + 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, + 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, + 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, + 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, + 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, + 0xf10605deUL #endif - } -}; + }}; diff --git a/examples/ThirdPartyLibs/zlib/deflate.c b/examples/ThirdPartyLibs/zlib/deflate.c index 696957705..fa0ddbab4 100644 --- a/examples/ThirdPartyLibs/zlib/deflate.c +++ b/examples/ThirdPartyLibs/zlib/deflate.c @@ -52,7 +52,7 @@ #include "deflate.h" const char deflate_copyright[] = - " deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler "; + " deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -63,38 +63,39 @@ const char deflate_copyright[] = /* =========================================================================== * Function prototypes. */ -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ +typedef enum +{ + need_more, /* block not completed, need more input or more output */ + block_done, /* block flush performed */ + finish_started, /* finish started, need only more output at next deflate */ + finish_done /* finish done, accept no more input or output */ } block_state; -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); +typedef block_state(*compress_func) OF((deflate_state * s, int flush)); /* Compression function. Returns the block state after the call. */ -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); +local void fill_window OF((deflate_state * s)); +local block_state deflate_stored OF((deflate_state * s, int flush)); +local block_state deflate_fast OF((deflate_state * s, int flush)); #ifndef FASTEST -local block_state deflate_slow OF((deflate_state *s, int flush)); +local block_state deflate_slow OF((deflate_state * s, int flush)); #endif -local block_state deflate_rle OF((deflate_state *s, int flush)); -local block_state deflate_huff OF((deflate_state *s, int flush)); -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); +local block_state deflate_rle OF((deflate_state * s, int flush)); +local block_state deflate_huff OF((deflate_state * s, int flush)); +local void lm_init OF((deflate_state * s)); +local void putShortMSB OF((deflate_state * s, uInt b)); +local void flush_pending OF((z_streamp strm)); +local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); #ifdef ASMV - void match_init OF((void)); /* asm code initialization */ - uInt longest_match OF((deflate_state *s, IPos cur_match)); +void match_init OF((void)); /* asm code initialization */ +uInt longest_match OF((deflate_state * s, IPos cur_match)); #else -local uInt longest_match OF((deflate_state *s, IPos cur_match)); +local uInt longest_match OF((deflate_state * s, IPos cur_match)); #endif #ifdef DEBUG -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); +local void check_match OF((deflate_state * s, IPos start, IPos match, + int length)); #endif /* =========================================================================== @@ -105,7 +106,7 @@ local void check_match OF((deflate_state *s, IPos start, IPos match, /* Tail of hash chains */ #ifndef TOO_FAR -# define TOO_FAR 4096 +#define TOO_FAR 4096 #endif /* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ @@ -114,33 +115,34 @@ local void check_match OF((deflate_state *s, IPos start, IPos match, * exclude worst case performance for pathological files. Better values may be * found for specific files. */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; +typedef struct config_s +{ + ush good_length; /* reduce lazy search above this match length */ + ush max_lazy; /* do not perform lazy search above this match length */ + ush nice_length; /* quit search above this match length */ + ush max_chain; + compress_func func; } config; #ifdef FASTEST local const config configuration_table[2] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ + /* good lazy nice chain */ + /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ + /* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ #else local const config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -/* 3 */ {4, 6, 32, 32, deflate_fast}, + /* good lazy nice chain */ + /* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ + /* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ + /* 2 */ {4, 5, 16, 8, deflate_fast}, + /* 3 */ {4, 6, 32, 32, deflate_fast}, -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ + /* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ + /* 5 */ {8, 16, 32, 32, deflate_slow}, + /* 6 */ {8, 16, 128, 128, deflate_slow}, + /* 7 */ {8, 32, 128, 256, deflate_slow}, + /* 8 */ {32, 128, 258, 1024, deflate_slow}, + /* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ #endif /* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 @@ -152,7 +154,10 @@ local const config configuration_table[10] = { /* result of memcmp for equal strings */ #ifndef NO_DUMMY_DECL -struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ +struct static_tree_desc_s +{ + int dummy; +}; /* for buggy compilers */ #endif /* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */ @@ -164,8 +169,7 @@ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ * input characters, so that a running hash key can be computed from the * previous key instead of complete recalculation each time. */ -#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) - +#define UPDATE_HASH(s, h, c) (h = (((h) << s->hash_shift) ^ (c)) & s->hash_mask) /* =========================================================================== * Insert string str in the dictionary and set match_head to the previous head @@ -178,372 +182,387 @@ struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ * (except for the last MIN_MATCH-1 bytes of the input file). */ #ifdef FASTEST -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH - 1)]), \ + match_head = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) #else -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) +#define INSERT_STRING(s, str, match_head) \ + (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH - 1)]), \ + match_head = s->prev[(str)&s->w_mask] = s->head[s->ins_h], \ + s->head[s->ins_h] = (Pos)(str)) #endif /* =========================================================================== * Initialize the hash table (avoiding 64K overflow for 16 bit systems). * prev[] will be initialized on the fly. */ -#define CLEAR_HASH(s) \ - s->head[s->hash_size-1] = NIL; \ - zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); +#define CLEAR_HASH(s) \ + s->head[s->hash_size - 1] = NIL; \ + zmemzero((Bytef *)s->head, (unsigned)(s->hash_size - 1) * sizeof(*s->head)); /* ========================================================================= */ int ZEXPORT deflateInit_(strm, level, version, stream_size) - z_streamp strm; - int level; - const char *version; - int stream_size; + z_streamp strm; +int level; +const char *version; +int stream_size; { - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ + return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, + Z_DEFAULT_STRATEGY, version, stream_size); + /* To do: ignore strm->next_in if we use it as window */ } /* ========================================================================= */ int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - version, stream_size) - z_streamp strm; - int level; - int method; - int windowBits; - int memLevel; - int strategy; - const char *version; - int stream_size; + version, stream_size) + z_streamp strm; +int level; +int method; +int windowBits; +int memLevel; +int strategy; +const char *version; +int stream_size; { - deflate_state *s; - int wrap = 1; - static const char my_version[] = ZLIB_VERSION; + deflate_state *s; + int wrap = 1; + static const char my_version[] = ZLIB_VERSION; - ushf *overlay; - /* We overlay pending_buf and d_buf+l_buf. This works since the average + ushf *overlay; + /* We overlay pending_buf and d_buf+l_buf. This works since the average * output size for (length,distance) codes is <= 24 bits. */ - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; + if (version == Z_NULL || version[0] != my_version[0] || + stream_size != sizeof(z_stream)) + { + return Z_VERSION_ERROR; + } + if (strm == Z_NULL) return Z_STREAM_ERROR; - strm->msg = Z_NULL; - if (strm->zalloc == (alloc_func)0) { + strm->msg = Z_NULL; + if (strm->zalloc == (alloc_func)0) + { #ifdef Z_SOLO - return Z_STREAM_ERROR; + return Z_STREAM_ERROR; #else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; #endif - } - if (strm->zfree == (free_func)0) + } + if (strm->zfree == (free_func)0) #ifdef Z_SOLO - return Z_STREAM_ERROR; + return Z_STREAM_ERROR; #else - strm->zfree = zcfree; + strm->zfree = zcfree; #endif #ifdef FASTEST - if (level != 0) level = 1; + if (level != 0) level = 1; #else - if (level == Z_DEFAULT_COMPRESSION) level = 6; + if (level == Z_DEFAULT_COMPRESSION) level = 6; #endif - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } + if (windowBits < 0) + { /* suppress zlib wrapper */ + wrap = 0; + windowBits = -windowBits; + } #ifdef GZIP - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } + else if (windowBits > 15) + { + wrap = 2; /* write gzip wrapper instead */ + windowBits -= 16; + } #endif - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; + if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || + windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || + strategy < 0 || strategy > Z_FIXED) + { + return Z_STREAM_ERROR; + } + if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ + s = (deflate_state *)ZALLOC(strm, 1, sizeof(deflate_state)); + if (s == Z_NULL) return Z_MEM_ERROR; + strm->state = (struct internal_state FAR *)s; + s->strm = strm; - s->wrap = wrap; - s->gzhead = Z_NULL; - s->w_bits = windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; + s->wrap = wrap; + s->gzhead = Z_NULL; + s->w_bits = windowBits; + s->w_size = 1 << s->w_bits; + s->w_mask = s->w_size - 1; - s->hash_bits = memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); + s->hash_bits = memLevel + 7; + s->hash_size = 1 << s->hash_bits; + s->hash_mask = s->hash_size - 1; + s->hash_shift = ((s->hash_bits + MIN_MATCH - 1) / MIN_MATCH); - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); + s->window = (Bytef *)ZALLOC(strm, s->w_size, 2 * sizeof(Byte)); + s->prev = (Posf *)ZALLOC(strm, s->w_size, sizeof(Pos)); + s->head = (Posf *)ZALLOC(strm, s->hash_size, sizeof(Pos)); - s->high_water = 0; /* nothing written to s->window yet */ + s->high_water = 0; /* nothing written to s->window yet */ - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ + s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); - s->pending_buf = (uchf *) overlay; - s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); + overlay = (ushf *)ZALLOC(strm, s->lit_bufsize, sizeof(ush) + 2); + s->pending_buf = (uchf *)overlay; + s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush) + 2L); - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - s->status = FINISH_STATE; - strm->msg = ERR_MSG(Z_MEM_ERROR); - deflateEnd (strm); - return Z_MEM_ERROR; - } - s->d_buf = overlay + s->lit_bufsize/sizeof(ush); - s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; + if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || + s->pending_buf == Z_NULL) + { + s->status = FINISH_STATE; + strm->msg = ERR_MSG(Z_MEM_ERROR); + deflateEnd(strm); + return Z_MEM_ERROR; + } + s->d_buf = overlay + s->lit_bufsize / sizeof(ush); + s->l_buf = s->pending_buf + (1 + sizeof(ush)) * s->lit_bufsize; - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; + s->level = level; + s->strategy = strategy; + s->method = (Byte)method; - return deflateReset(strm); + return deflateReset(strm); } /* ========================================================================= */ -int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) - z_streamp strm; - const Bytef *dictionary; - uInt dictLength; +int ZEXPORT deflateSetDictionary(strm, dictionary, dictLength) + z_streamp strm; +const Bytef *dictionary; +uInt dictLength; { - deflate_state *s; - uInt str, n; - int wrap; - unsigned avail; - z_const unsigned char *next; + deflate_state *s; + uInt str, n; + int wrap; + unsigned avail; + z_const unsigned char *next; - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) - return Z_STREAM_ERROR; - s = strm->state; - wrap = s->wrap; - if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) - return Z_STREAM_ERROR; + if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL) + return Z_STREAM_ERROR; + s = strm->state; + wrap = s->wrap; + if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead) + return Z_STREAM_ERROR; - /* when using zlib wrappers, compute Adler-32 for provided dictionary */ - if (wrap == 1) - strm->adler = adler32(strm->adler, dictionary, dictLength); - s->wrap = 0; /* avoid computing Adler-32 in read_buf */ + /* when using zlib wrappers, compute Adler-32 for provided dictionary */ + if (wrap == 1) + strm->adler = adler32(strm->adler, dictionary, dictLength); + s->wrap = 0; /* avoid computing Adler-32 in read_buf */ - /* if dictionary would fill window, just replace the history */ - if (dictLength >= s->w_size) { - if (wrap == 0) { /* already empty otherwise */ - CLEAR_HASH(s); - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - dictionary += dictLength - s->w_size; /* use the tail */ - dictLength = s->w_size; - } + /* if dictionary would fill window, just replace the history */ + if (dictLength >= s->w_size) + { + if (wrap == 0) + { /* already empty otherwise */ + CLEAR_HASH(s); + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + dictionary += dictLength - s->w_size; /* use the tail */ + dictLength = s->w_size; + } - /* insert dictionary into window and hash */ - avail = strm->avail_in; - next = strm->next_in; - strm->avail_in = dictLength; - strm->next_in = (z_const Bytef *)dictionary; - fill_window(s); - while (s->lookahead >= MIN_MATCH) { - str = s->strstart; - n = s->lookahead - (MIN_MATCH-1); - do { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); + /* insert dictionary into window and hash */ + avail = strm->avail_in; + next = strm->next_in; + strm->avail_in = dictLength; + strm->next_in = (z_const Bytef *)dictionary; + fill_window(s); + while (s->lookahead >= MIN_MATCH) + { + str = s->strstart; + n = s->lookahead - (MIN_MATCH - 1); + do + { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH - 1]); #ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; + s->prev[str & s->w_mask] = s->head[s->ins_h]; #endif - s->head[s->ins_h] = (Pos)str; - str++; - } while (--n); - s->strstart = str; - s->lookahead = MIN_MATCH-1; - fill_window(s); - } - s->strstart += s->lookahead; - s->block_start = (long)s->strstart; - s->insert = s->lookahead; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - strm->next_in = next; - strm->avail_in = avail; - s->wrap = wrap; - return Z_OK; + s->head[s->ins_h] = (Pos)str; + str++; + } while (--n); + s->strstart = str; + s->lookahead = MIN_MATCH - 1; + fill_window(s); + } + s->strstart += s->lookahead; + s->block_start = (long)s->strstart; + s->insert = s->lookahead; + s->lookahead = 0; + s->match_length = s->prev_length = MIN_MATCH - 1; + s->match_available = 0; + strm->next_in = next; + strm->avail_in = avail; + s->wrap = wrap; + return Z_OK; } /* ========================================================================= */ -int ZEXPORT deflateResetKeep (strm) - z_streamp strm; +int ZEXPORT deflateResetKeep(strm) + z_streamp strm; { - deflate_state *s; + deflate_state *s; - if (strm == Z_NULL || strm->state == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { - return Z_STREAM_ERROR; - } + if (strm == Z_NULL || strm->state == Z_NULL || + strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) + { + return Z_STREAM_ERROR; + } - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; + strm->total_in = strm->total_out = 0; + strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ + strm->data_type = Z_UNKNOWN; - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; + s = (deflate_state *)strm->state; + s->pending = 0; + s->pending_out = s->pending_buf; - if (s->wrap < 0) { - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ - } - s->status = s->wrap ? INIT_STATE : BUSY_STATE; - strm->adler = + if (s->wrap < 0) + { + s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ + } + s->status = s->wrap ? INIT_STATE : BUSY_STATE; + strm->adler = #ifdef GZIP - s->wrap == 2 ? crc32(0L, Z_NULL, 0) : + s->wrap == 2 ? crc32(0L, Z_NULL, 0) : #endif - adler32(0L, Z_NULL, 0); - s->last_flush = Z_NO_FLUSH; + adler32(0L, Z_NULL, 0); + s->last_flush = Z_NO_FLUSH; - _tr_init(s); + _tr_init(s); - return Z_OK; + return Z_OK; } /* ========================================================================= */ -int ZEXPORT deflateReset (strm) - z_streamp strm; +int ZEXPORT deflateReset(strm) + z_streamp strm; { - int ret; + int ret; - ret = deflateResetKeep(strm); - if (ret == Z_OK) - lm_init(strm->state); - return ret; + ret = deflateResetKeep(strm); + if (ret == Z_OK) + lm_init(strm->state); + return ret; } /* ========================================================================= */ -int ZEXPORT deflateSetHeader (strm, head) - z_streamp strm; - gz_headerp head; +int ZEXPORT deflateSetHeader(strm, head) + z_streamp strm; +gz_headerp head; { - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - if (strm->state->wrap != 2) return Z_STREAM_ERROR; - strm->state->gzhead = head; - return Z_OK; + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (strm->state->wrap != 2) return Z_STREAM_ERROR; + strm->state->gzhead = head; + return Z_OK; } /* ========================================================================= */ -int ZEXPORT deflatePending (strm, pending, bits) - unsigned *pending; - int *bits; - z_streamp strm; +int ZEXPORT deflatePending(strm, pending, bits) unsigned *pending; +int *bits; +z_streamp strm; { - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - if (pending != Z_NULL) - *pending = strm->state->pending; - if (bits != Z_NULL) - *bits = strm->state->bi_valid; - return Z_OK; + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (pending != Z_NULL) + *pending = strm->state->pending; + if (bits != Z_NULL) + *bits = strm->state->bi_valid; + return Z_OK; } /* ========================================================================= */ -int ZEXPORT deflatePrime (strm, bits, value) - z_streamp strm; - int bits; - int value; +int ZEXPORT deflatePrime(strm, bits, value) + z_streamp strm; +int bits; +int value; { - deflate_state *s; - int put; + deflate_state *s; + int put; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) - return Z_BUF_ERROR; - do { - put = Buf_size - s->bi_valid; - if (put > bits) - put = bits; - s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); - s->bi_valid += put; - _tr_flush_bits(s); - value >>= put; - bits -= put; - } while (bits); - return Z_OK; + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3)) + return Z_BUF_ERROR; + do + { + put = Buf_size - s->bi_valid; + if (put > bits) + put = bits; + s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid); + s->bi_valid += put; + _tr_flush_bits(s); + value >>= put; + bits -= put; + } while (bits); + return Z_OK; } /* ========================================================================= */ int ZEXPORT deflateParams(strm, level, strategy) - z_streamp strm; - int level; - int strategy; + z_streamp strm; +int level; +int strategy; { - deflate_state *s; - compress_func func; - int err = Z_OK; + deflate_state *s; + compress_func func; + int err = Z_OK; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; #ifdef FASTEST - if (level != 0) level = 1; + if (level != 0) level = 1; #else - if (level == Z_DEFAULT_COMPRESSION) level = 6; + if (level == Z_DEFAULT_COMPRESSION) level = 6; #endif - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; + if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) + { + return Z_STREAM_ERROR; + } + func = configuration_table[s->level].func; - if ((strategy != s->strategy || func != configuration_table[level].func) && - strm->total_in != 0) { - /* Flush the last buffer: */ - err = deflate(strm, Z_BLOCK); - if (err == Z_BUF_ERROR && s->pending == 0) - err = Z_OK; - } - if (s->level != level) { - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return err; + if ((strategy != s->strategy || func != configuration_table[level].func) && + strm->total_in != 0) + { + /* Flush the last buffer: */ + err = deflate(strm, Z_BLOCK); + if (err == Z_BUF_ERROR && s->pending == 0) + err = Z_OK; + } + if (s->level != level) + { + s->level = level; + s->max_lazy_match = configuration_table[level].max_lazy; + s->good_match = configuration_table[level].good_length; + s->nice_match = configuration_table[level].nice_length; + s->max_chain_length = configuration_table[level].max_chain; + } + s->strategy = strategy; + return err; } /* ========================================================================= */ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) - z_streamp strm; - int good_length; - int max_lazy; - int nice_length; - int max_chain; + z_streamp strm; +int good_length; +int max_lazy; +int nice_length; +int max_chain; { - deflate_state *s; + deflate_state *s; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - s->good_match = good_length; - s->max_lazy_match = max_lazy; - s->nice_match = nice_length; - s->max_chain_length = max_chain; - return Z_OK; + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + s = strm->state; + s->good_match = good_length; + s->max_lazy_match = max_lazy; + s->nice_match = nice_length; + s->max_chain_length = max_chain; + return Z_OK; } /* ========================================================================= @@ -564,60 +583,64 @@ int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) * allocation. */ uLong ZEXPORT deflateBound(strm, sourceLen) - z_streamp strm; - uLong sourceLen; + z_streamp strm; +uLong sourceLen; { - deflate_state *s; - uLong complen, wraplen; - Bytef *str; + deflate_state *s; + uLong complen, wraplen; + Bytef *str; - /* conservative upper bound for compressed data */ - complen = sourceLen + - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; + /* conservative upper bound for compressed data */ + complen = sourceLen + + ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; - /* if can't get parameters, return conservative bound plus zlib wrapper */ - if (strm == Z_NULL || strm->state == Z_NULL) - return complen + 6; + /* if can't get parameters, return conservative bound plus zlib wrapper */ + if (strm == Z_NULL || strm->state == Z_NULL) + return complen + 6; - /* compute wrapper length */ - s = strm->state; - switch (s->wrap) { - case 0: /* raw deflate */ - wraplen = 0; - break; - case 1: /* zlib wrapper */ - wraplen = 6 + (s->strstart ? 4 : 0); - break; - case 2: /* gzip wrapper */ - wraplen = 18; - if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ - if (s->gzhead->extra != Z_NULL) - wraplen += 2 + s->gzhead->extra_len; - str = s->gzhead->name; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - str = s->gzhead->comment; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - if (s->gzhead->hcrc) - wraplen += 2; - } - break; - default: /* for compiler happiness */ - wraplen = 6; - } + /* compute wrapper length */ + s = strm->state; + switch (s->wrap) + { + case 0: /* raw deflate */ + wraplen = 0; + break; + case 1: /* zlib wrapper */ + wraplen = 6 + (s->strstart ? 4 : 0); + break; + case 2: /* gzip wrapper */ + wraplen = 18; + if (s->gzhead != Z_NULL) + { /* user-supplied gzip header */ + if (s->gzhead->extra != Z_NULL) + wraplen += 2 + s->gzhead->extra_len; + str = s->gzhead->name; + if (str != Z_NULL) + do + { + wraplen++; + } while (*str++); + str = s->gzhead->comment; + if (str != Z_NULL) + do + { + wraplen++; + } while (*str++); + if (s->gzhead->hcrc) + wraplen += 2; + } + break; + default: /* for compiler happiness */ + wraplen = 6; + } - /* if not default parameters, return conservative bound */ - if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return complen + wraplen; + /* if not default parameters, return conservative bound */ + if (s->w_bits != 15 || s->hash_bits != 8 + 7) + return complen + wraplen; - /* default settings: return tight bound for that case */ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13 - 6 + wraplen; + /* default settings: return tight bound for that case */ + return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + + (sourceLen >> 25) + 13 - 6 + wraplen; } /* ========================================================================= @@ -625,12 +648,12 @@ uLong ZEXPORT deflateBound(strm, sourceLen) * IN assertion: the stream state is correct and there is enough room in * pending_buf. */ -local void putShortMSB (s, b) - deflate_state *s; - uInt b; +local void putShortMSB(s, b) + deflate_state *s; +uInt b; { - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); + put_byte(s, (Byte)(b >> 8)); + put_byte(s, (Byte)(b & 0xff)); } /* ========================================================================= @@ -640,370 +663,409 @@ local void putShortMSB (s, b) * (See also read_buf()). */ local void flush_pending(strm) - z_streamp strm; + z_streamp strm; { - unsigned len; - deflate_state *s = strm->state; + unsigned len; + deflate_state *s = strm->state; - _tr_flush_bits(s); - len = s->pending; - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; + _tr_flush_bits(s); + len = s->pending; + if (len > strm->avail_out) len = strm->avail_out; + if (len == 0) return; - zmemcpy(strm->next_out, s->pending_out, len); - strm->next_out += len; - s->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - s->pending -= len; - if (s->pending == 0) { - s->pending_out = s->pending_buf; - } + zmemcpy(strm->next_out, s->pending_out, len); + strm->next_out += len; + s->pending_out += len; + strm->total_out += len; + strm->avail_out -= len; + s->pending -= len; + if (s->pending == 0) + { + s->pending_out = s->pending_buf; + } } /* ========================================================================= */ -int ZEXPORT deflate (strm, flush) - z_streamp strm; - int flush; +int ZEXPORT deflate(strm, flush) + z_streamp strm; +int flush; { - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; + int old_flush; /* value of flush param for previous deflate call */ + deflate_state *s; - if (strm == Z_NULL || strm->state == Z_NULL || - flush > Z_BLOCK || flush < 0) { - return Z_STREAM_ERROR; - } - s = strm->state; + if (strm == Z_NULL || strm->state == Z_NULL || + flush > Z_BLOCK || flush < 0) + { + return Z_STREAM_ERROR; + } + s = strm->state; - if (strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); + if (strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0) || + (s->status == FINISH_STATE && flush != Z_FINISH)) + { + ERR_RETURN(strm, Z_STREAM_ERROR); + } + if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - s->strm = strm; /* just in case */ - old_flush = s->last_flush; - s->last_flush = flush; + s->strm = strm; /* just in case */ + old_flush = s->last_flush; + s->last_flush = flush; - /* Write the header */ - if (s->status == INIT_STATE) { + /* Write the header */ + if (s->status == INIT_STATE) + { #ifdef GZIP - if (s->wrap == 2) { - strm->adler = crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (s->gzhead == Z_NULL) { - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s->status = BUSY_STATE; - } - else { - put_byte(s, (s->gzhead->text ? 1 : 0) + - (s->gzhead->hcrc ? 2 : 0) + - (s->gzhead->extra == Z_NULL ? 0 : 4) + - (s->gzhead->name == Z_NULL ? 0 : 8) + - (s->gzhead->comment == Z_NULL ? 0 : 16) - ); - put_byte(s, (Byte)(s->gzhead->time & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != Z_NULL) { - put_byte(s, s->gzhead->extra_len & 0xff); - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); - } - if (s->gzhead->hcrc) - strm->adler = crc32(strm->adler, s->pending_buf, - s->pending); - s->gzindex = 0; - s->status = EXTRA_STATE; - } - } - else + if (s->wrap == 2) + { + strm->adler = crc32(0L, Z_NULL, 0); + put_byte(s, 31); + put_byte(s, 139); + put_byte(s, 8); + if (s->gzhead == Z_NULL) + { + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, 0); + put_byte(s, s->level == 9 ? 2 : (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0)); + put_byte(s, OS_CODE); + s->status = BUSY_STATE; + } + else + { + put_byte(s, (s->gzhead->text ? 1 : 0) + + (s->gzhead->hcrc ? 2 : 0) + + (s->gzhead->extra == Z_NULL ? 0 : 4) + + (s->gzhead->name == Z_NULL ? 0 : 8) + + (s->gzhead->comment == Z_NULL ? 0 : 16)); + put_byte(s, (Byte)(s->gzhead->time & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); + put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); + put_byte(s, s->level == 9 ? 2 : (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? 4 : 0)); + put_byte(s, s->gzhead->os & 0xff); + if (s->gzhead->extra != Z_NULL) + { + put_byte(s, s->gzhead->extra_len & 0xff); + put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); + } + if (s->gzhead->hcrc) + strm->adler = crc32(strm->adler, s->pending_buf, + s->pending); + s->gzindex = 0; + s->status = EXTRA_STATE; + } + } + else #endif - { - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; - uInt level_flags; + { + uInt header = (Z_DEFLATED + ((s->w_bits - 8) << 4)) << 8; + uInt level_flags; - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); + if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) + level_flags = 0; + else if (s->level < 6) + level_flags = 1; + else if (s->level == 6) + level_flags = 2; + else + level_flags = 3; + header |= (level_flags << 6); + if (s->strstart != 0) header |= PRESET_DICT; + header += 31 - (header % 31); - s->status = BUSY_STATE; - putShortMSB(s, header); + s->status = BUSY_STATE; + putShortMSB(s, header); - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = adler32(0L, Z_NULL, 0); - } - } + /* Save the adler32 of the preset dictionary: */ + if (s->strstart != 0) + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + strm->adler = adler32(0L, Z_NULL, 0); + } + } #ifdef GZIP - if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ + if (s->status == EXTRA_STATE) + { + if (s->gzhead->extra != Z_NULL) + { + uInt beg = s->pending; /* start of bytes to update crc */ - while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) - break; - } - put_byte(s, s->gzhead->extra[s->gzindex]); - s->gzindex++; - } - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (s->gzindex == s->gzhead->extra_len) { - s->gzindex = 0; - s->status = NAME_STATE; - } - } - else - s->status = NAME_STATE; - } - if (s->status == NAME_STATE) { - if (s->gzhead->name != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; + while (s->gzindex < (s->gzhead->extra_len & 0xffff)) + { + if (s->pending == s->pending_buf_size) + { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) + break; + } + put_byte(s, s->gzhead->extra[s->gzindex]); + s->gzindex++; + } + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (s->gzindex == s->gzhead->extra_len) + { + s->gzindex = 0; + s->status = NAME_STATE; + } + } + else + s->status = NAME_STATE; + } + if (s->status == NAME_STATE) + { + if (s->gzhead->name != Z_NULL) + { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->name[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) { - s->gzindex = 0; - s->status = COMMENT_STATE; - } - } - else - s->status = COMMENT_STATE; - } - if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; + do + { + if (s->pending == s->pending_buf_size) + { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) + { + val = 1; + break; + } + } + val = s->gzhead->name[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) + { + s->gzindex = 0; + s->status = COMMENT_STATE; + } + } + else + s->status = COMMENT_STATE; + } + if (s->status == COMMENT_STATE) + { + if (s->gzhead->comment != Z_NULL) + { + uInt beg = s->pending; /* start of bytes to update crc */ + int val; - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->comment[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) - s->status = HCRC_STATE; - } - else - s->status = HCRC_STATE; - } - if (s->status == HCRC_STATE) { - if (s->gzhead->hcrc) { - if (s->pending + 2 > s->pending_buf_size) - flush_pending(strm); - if (s->pending + 2 <= s->pending_buf_size) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - strm->adler = crc32(0L, Z_NULL, 0); - s->status = BUSY_STATE; - } - } - else - s->status = BUSY_STATE; - } + do + { + if (s->pending == s->pending_buf_size) + { + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + flush_pending(strm); + beg = s->pending; + if (s->pending == s->pending_buf_size) + { + val = 1; + break; + } + } + val = s->gzhead->comment[s->gzindex++]; + put_byte(s, val); + } while (val != 0); + if (s->gzhead->hcrc && s->pending > beg) + strm->adler = crc32(strm->adler, s->pending_buf + beg, + s->pending - beg); + if (val == 0) + s->status = HCRC_STATE; + } + else + s->status = HCRC_STATE; + } + if (s->status == HCRC_STATE) + { + if (s->gzhead->hcrc) + { + if (s->pending + 2 > s->pending_buf_size) + flush_pending(strm); + if (s->pending + 2 <= s->pending_buf_size) + { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + strm->adler = crc32(0L, Z_NULL, 0); + s->status = BUSY_STATE; + } + } + else + s->status = BUSY_STATE; + } #endif - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with + /* Flush as much pending output as possible */ + if (s->pending != 0) + { + flush_pending(strm); + if (strm->avail_out == 0) + { + /* Since avail_out is 0, deflate will be called again with * more output space, but possibly with both pending and * avail_in equal to zero. There won't be anything to do, * but this is not an error situation so make sure we * return OK instead of BUF_ERROR at next call of deflate: */ - s->last_flush = -1; - return Z_OK; - } + s->last_flush = -1; + return Z_OK; + } - /* Make sure there is something to do and avoid duplicate consecutive + /* Make sure there is something to do and avoid duplicate consecutive * flushes. For repeated and useless calls with Z_FINISH, we keep * returning Z_STREAM_END instead of Z_BUF_ERROR. */ - } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } + } + else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) && + flush != Z_FINISH) + { + ERR_RETURN(strm, Z_BUF_ERROR); + } - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } + /* User must not provide more input after the first FINISH: */ + if (s->status == FINISH_STATE && strm->avail_in != 0) + { + ERR_RETURN(strm, Z_BUF_ERROR); + } - /* Start a new block or continue the current one. + /* Start a new block or continue the current one. */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; + if (strm->avail_in != 0 || s->lookahead != 0 || + (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) + { + block_state bstate; - bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - (s->strategy == Z_RLE ? deflate_rle(s, flush) : - (*(configuration_table[s->level].func))(s, flush)); + bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : (s->strategy == Z_RLE ? deflate_rle(s, flush) : (*(configuration_table[s->level].func))(s, flush)); - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call + if (bstate == finish_started || bstate == finish_done) + { + s->status = FINISH_STATE; + } + if (bstate == need_more || bstate == finish_started) + { + if (strm->avail_out == 0) + { + s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ + } + return Z_OK; + /* If flush != Z_NO_FLUSH && avail_out == 0, the next call * of deflate should use the same flush parameter to make sure * that the flush is complete. So we don't have to output an * empty block here, this will be done at next call. This also * ensures that for a very small output buffer, we emit at most * one empty block. */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized + } + if (bstate == block_done) + { + if (flush == Z_PARTIAL_FLUSH) + { + _tr_align(s); + } + else if (flush != Z_BLOCK) + { /* FULL_FLUSH or SYNC_FLUSH */ + _tr_stored_block(s, (char *)0, 0L, 0); + /* For a full flush, this empty block will be recognized * as a special marker by inflate_sync(). */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - if (s->lookahead == 0) { - s->strstart = 0; - s->block_start = 0L; - s->insert = 0; - } - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - Assert(strm->avail_out > 0, "bug2"); + if (flush == Z_FULL_FLUSH) + { + CLEAR_HASH(s); /* forget history */ + if (s->lookahead == 0) + { + s->strstart = 0; + s->block_start = 0L; + s->insert = 0; + } + } + } + flush_pending(strm); + if (strm->avail_out == 0) + { + s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ + return Z_OK; + } + } + } + Assert(strm->avail_out > 0, "bug2"); - if (flush != Z_FINISH) return Z_OK; - if (s->wrap <= 0) return Z_STREAM_END; + if (flush != Z_FINISH) return Z_OK; + if (s->wrap <= 0) return Z_STREAM_END; - /* Write the trailer */ + /* Write the trailer */ #ifdef GZIP - if (s->wrap == 2) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); - put_byte(s, (Byte)(strm->total_in & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); - } - else + if (s->wrap == 2) + { + put_byte(s, (Byte)(strm->adler & 0xff)); + put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); + put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); + put_byte(s, (Byte)(strm->total_in & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); + put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); + } + else #endif - { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again + { + putShortMSB(s, (uInt)(strm->adler >> 16)); + putShortMSB(s, (uInt)(strm->adler & 0xffff)); + } + flush_pending(strm); + /* If avail_out is zero, the application will call deflate again * to flush the rest. */ - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; + if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ + return s->pending != 0 ? Z_OK : Z_STREAM_END; } /* ========================================================================= */ -int ZEXPORT deflateEnd (strm) - z_streamp strm; +int ZEXPORT deflateEnd(strm) + z_streamp strm; { - int status; + int status; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - status = strm->state->status; - if (status != INIT_STATE && - status != EXTRA_STATE && - status != NAME_STATE && - status != COMMENT_STATE && - status != HCRC_STATE && - status != BUSY_STATE && - status != FINISH_STATE) { - return Z_STREAM_ERROR; - } + status = strm->state->status; + if (status != INIT_STATE && + status != EXTRA_STATE && + status != NAME_STATE && + status != COMMENT_STATE && + status != HCRC_STATE && + status != BUSY_STATE && + status != FINISH_STATE) + { + return Z_STREAM_ERROR; + } - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, strm->state->pending_buf); - TRY_FREE(strm, strm->state->head); - TRY_FREE(strm, strm->state->prev); - TRY_FREE(strm, strm->state->window); + /* Deallocate in reverse order of allocations: */ + TRY_FREE(strm, strm->state->pending_buf); + TRY_FREE(strm, strm->state->head); + TRY_FREE(strm, strm->state->prev); + TRY_FREE(strm, strm->state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; + ZFREE(strm, strm->state); + strm->state = Z_NULL; - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; + return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; } /* ========================================================================= @@ -1011,58 +1073,59 @@ int ZEXPORT deflateEnd (strm) * To simplify the source, this is not supported for 16-bit MSDOS (which * doesn't have enough memory anyway to duplicate compression states). */ -int ZEXPORT deflateCopy (dest, source) - z_streamp dest; - z_streamp source; +int ZEXPORT deflateCopy(dest, source) + z_streamp dest; +z_streamp source; { #ifdef MAXSEG_64K - return Z_STREAM_ERROR; + return Z_STREAM_ERROR; #else - deflate_state *ds; - deflate_state *ss; - ushf *overlay; + deflate_state *ds; + deflate_state *ss; + ushf *overlay; + if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) + { + return Z_STREAM_ERROR; + } - if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { - return Z_STREAM_ERROR; - } + ss = source->state; - ss = source->state; + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + ds = (deflate_state *)ZALLOC(dest, 1, sizeof(deflate_state)); + if (ds == Z_NULL) return Z_MEM_ERROR; + dest->state = (struct internal_state FAR *)ds; + zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); + ds->strm = dest; - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; - zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state)); - ds->strm = dest; + ds->window = (Bytef *)ZALLOC(dest, ds->w_size, 2 * sizeof(Byte)); + ds->prev = (Posf *)ZALLOC(dest, ds->w_size, sizeof(Pos)); + ds->head = (Posf *)ZALLOC(dest, ds->hash_size, sizeof(Pos)); + overlay = (ushf *)ZALLOC(dest, ds->lit_bufsize, sizeof(ush) + 2); + ds->pending_buf = (uchf *)overlay; - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); - ds->pending_buf = (uchf *) overlay; + if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || + ds->pending_buf == Z_NULL) + { + deflateEnd(dest); + return Z_MEM_ERROR; + } + /* following zmemcpy do not work for 16-bit MSDOS */ + zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); + zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); + zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); + zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd (dest); - return Z_MEM_ERROR; - } - /* following zmemcpy do not work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); + ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); + ds->d_buf = overlay + ds->lit_bufsize / sizeof(ush); + ds->l_buf = ds->pending_buf + (1 + sizeof(ush)) * ds->lit_bufsize; - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); - ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; + ds->l_desc.dyn_tree = ds->dyn_ltree; + ds->d_desc.dyn_tree = ds->dyn_dtree; + ds->bl_desc.dyn_tree = ds->bl_tree; - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; + return Z_OK; #endif /* MAXSEG_64K */ } @@ -1074,59 +1137,61 @@ int ZEXPORT deflateCopy (dest, source) * (See also flush_pending()). */ local int read_buf(strm, buf, size) - z_streamp strm; - Bytef *buf; - unsigned size; + z_streamp strm; +Bytef *buf; +unsigned size; { - unsigned len = strm->avail_in; + unsigned len = strm->avail_in; - if (len > size) len = size; - if (len == 0) return 0; + if (len > size) len = size; + if (len == 0) return 0; - strm->avail_in -= len; + strm->avail_in -= len; - zmemcpy(buf, strm->next_in, len); - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, buf, len); - } + zmemcpy(buf, strm->next_in, len); + if (strm->state->wrap == 1) + { + strm->adler = adler32(strm->adler, buf, len); + } #ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, buf, len); - } + else if (strm->state->wrap == 2) + { + strm->adler = crc32(strm->adler, buf, len); + } #endif - strm->next_in += len; - strm->total_in += len; + strm->next_in += len; + strm->total_in += len; - return (int)len; + return (int)len; } /* =========================================================================== * Initialize the "longest match" routines for a new zlib stream */ -local void lm_init (s) - deflate_state *s; +local void lm_init(s) + deflate_state *s; { - s->window_size = (ulg)2L*s->w_size; + s->window_size = (ulg)2L * s->w_size; - CLEAR_HASH(s); + CLEAR_HASH(s); - /* Set the default configuration parameters: + /* Set the default configuration parameters: */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; + s->max_lazy_match = configuration_table[s->level].max_lazy; + s->good_match = configuration_table[s->level].good_length; + s->nice_match = configuration_table[s->level].nice_length; + s->max_chain_length = configuration_table[s->level].max_chain; - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->insert = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; + s->strstart = 0; + s->block_start = 0L; + s->lookahead = 0; + s->insert = 0; + s->match_length = s->prev_length = MIN_MATCH - 1; + s->match_available = 0; + s->ins_h = 0; #ifndef FASTEST #ifdef ASMV - match_init(); /* initialize the asm code */ + match_init(); /* initialize the asm code */ #endif #endif } @@ -1146,57 +1211,58 @@ local void lm_init (s) * match.S. The code will be functionally equivalent. */ local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ + deflate_state *s; +IPos cur_match; /* current match */ { - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - int best_len = s->prev_length; /* best match length so far */ - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, + unsigned chain_length = s->max_chain_length; /* max hash chain length */ + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + int best_len = s->prev_length; /* best match length so far */ + int nice_match = s->nice_match; /* stop if match long enough */ + IPos limit = s->strstart > (IPos)MAX_DIST(s) ? s->strstart - (IPos)MAX_DIST(s) : NIL; + /* Stop when cur_match becomes <= limit. To simplify the code, * we prevent matches with the string of window index 0. */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; + Posf *prev = s->prev; + uInt wmask = s->w_mask; #ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. + /* Compare two bytes at a time. Note: this is not always beneficial. * Try with and without -DUNALIGNED_OK to check. */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan+best_len-1); + register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; + register ush scan_start = *(ushf *)scan; + register ush scan_end = *(ushf *)(scan + best_len - 1); #else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len-1]; - register Byte scan_end = scan[best_len]; + register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Byte scan_end1 = scan[best_len - 1]; + register Byte scan_end = scan[best_len]; #endif - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. * It is easy to get rid of this optimization if necessary. */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary + /* Do not waste too much time if we already have a good match: */ + if (s->prev_length >= s->good_match) + { + chain_length >>= 2; + } + /* Do not look for matches beyond the end of the input. This is necessary * to make deflate deterministic. */ - if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; + if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, "need lookahead"); - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; + do + { + Assert(cur_match < s->strstart, "no future"); + match = s->window + cur_match; - /* Skip to next match if the match length cannot increase + /* Skip to next match if the match length cannot increase * or if the match length is less than 2. Note that the checks below * for insufficient lookahead only occur occasionally for performance * reasons. Therefore uninitialized memory will be accessed, and @@ -1205,13 +1271,13 @@ local uInt longest_match(s, cur_match) * the output of deflate is not affected by the uninitialized values. */ #if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use + /* This code assumes sizeof(unsigned short) == 2. Do not use * UNALIGNED_OK if your compiler uses a different size. */ - if (*(ushf*)(match+best_len-1) != scan_end || - *(ushf*)match != scan_start) continue; + if (*(ushf *)(match + best_len - 1) != scan_end || + *(ushf *)match != scan_start) continue; - /* It is not necessary to compare scan[2] and match[2] since they are + /* It is not necessary to compare scan[2] and match[2] since they are * always equal when the other bytes match, given that the hash keys * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at * strstart+3, +5, ... up to strstart+257. We check for insufficient @@ -1220,72 +1286,74 @@ local uInt longest_match(s, cur_match) * necessary to put more guard bytes at the end of the window, or * to check more often for insufficient lookahead. */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ + Assert(scan[2] == match[2], "scan[2]?"); + scan++, match++; + do + { + } while (*(ushf *)(scan += 2) == *(ushf *)(match += 2) && + *(ushf *)(scan += 2) == *(ushf *)(match += 2) && + *(ushf *)(scan += 2) == *(ushf *)(match += 2) && + *(ushf *)(scan += 2) == *(ushf *)(match += 2) && + scan < strend); + /* The funny "do {}" generates better code on most compilers */ - /* Here, scan <= window+strstart+257 */ - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - if (*scan == *match) scan++; + /* Here, scan <= window+strstart+257 */ + Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan"); + if (*scan == *match) scan++; - len = (MAX_MATCH - 1) - (int)(strend-scan); - scan = strend - (MAX_MATCH-1); + len = (MAX_MATCH - 1) - (int)(strend - scan); + scan = strend - (MAX_MATCH - 1); #else /* UNALIGNED_OK */ - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; + if (match[best_len] != scan_end || + match[best_len - 1] != scan_end1 || + *match != *scan || + *++match != scan[1]) continue; - /* The check at best_len-1 can be removed because it will be made + /* The check at best_len-1 can be removed because it will be made * again later. (This heuristic is not always a win.) * It is not necessary to compare scan[2] and match[2] since they * are always equal when the other bytes match, given that * the hash keys are equal and that HASH_BITS >= 8. */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); + scan += 2, match++; + Assert(*scan == *match, "match[2]?"); - /* We check for insufficient lookahead only every 8th comparison; + /* We check for insufficient lookahead only every 8th comparison; * the 256th check will be made at strstart+258. */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); + do + { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan"); - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; + len = MAX_MATCH - (int)(strend - scan); + scan = strend - MAX_MATCH; #endif /* UNALIGNED_OK */ - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; + if (len > best_len) + { + s->match_start = cur_match; + best_len = len; + if (len >= nice_match) break; #ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan+best_len-1); + scan_end = *(ushf *)(scan + best_len - 1); #else - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; + scan_end1 = scan[best_len - 1]; + scan_end = scan[best_len]; #endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); + } + } while ((cur_match = prev[cur_match & wmask]) > limit && --chain_length != 0); - if ((uInt)best_len <= s->lookahead) return (uInt)best_len; - return s->lookahead; + if ((uInt)best_len <= s->lookahead) return (uInt)best_len; + return s->lookahead; } #endif /* ASMV */ @@ -1295,56 +1363,57 @@ local uInt longest_match(s, cur_match) * Optimized version for FASTEST only */ local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ + deflate_state *s; +IPos cur_match; /* current match */ { - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH; + register Bytef *scan = s->window + s->strstart; /* current string */ + register Bytef *match; /* matched string */ + register int len; /* length of current match */ + register Bytef *strend = s->window + s->strstart + MAX_MATCH; - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. + /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. * It is easy to get rid of this optimization if necessary. */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); + Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, "need lookahead"); - Assert(cur_match < s->strstart, "no future"); + Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; + match = s->window + cur_match; - /* Return failure if the match length is less than 2: + /* Return failure if the match length is less than 2: */ - if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; + if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH - 1; - /* The check at best_len-1 can be removed because it will be made + /* The check at best_len-1 can be removed because it will be made * again later. (This heuristic is not always a win.) * It is not necessary to compare scan[2] and match[2] since they * are always equal when the other bytes match, given that * the hash keys are equal and that HASH_BITS >= 8. */ - scan += 2, match += 2; - Assert(*scan == *match, "match[2]?"); + scan += 2, match += 2; + Assert(*scan == *match, "match[2]?"); - /* We check for insufficient lookahead only every 8th comparison; + /* We check for insufficient lookahead only every 8th comparison; * the 256th check will be made at strstart+258. */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); + do + { + } while (*++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + *++scan == *++match && *++scan == *++match && + scan < strend); - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); + Assert(scan <= s->window + (unsigned)(s->window_size - 1), "wild scan"); - len = MAX_MATCH - (int)(strend - scan); + len = MAX_MATCH - (int)(strend - scan); - if (len < MIN_MATCH) return MIN_MATCH - 1; + if (len < MIN_MATCH) return MIN_MATCH - 1; - s->match_start = cur_match; - return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; + s->match_start = cur_match; + return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; } #endif /* FASTEST */ @@ -1354,27 +1423,33 @@ local uInt longest_match(s, cur_match) * Check that the match at match_start is indeed a match. */ local void check_match(s, start, match, length) - deflate_state *s; - IPos start, match; - int length; + deflate_state *s; +IPos start, match; +int length; { - /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); - do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start-match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } + /* check that the match is indeed a match */ + if (zmemcmp(s->window + match, + s->window + start, length) != EQUAL) + { + fprintf(stderr, " start %u, match %u, length %d\n", + start, match, length); + do + { + fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); + } while (--length != 0); + z_error("invalid match"); + } + if (z_verbose > 1) + { + fprintf(stderr, "\\[%d,%d]", start - match, length); + do + { + putc(s->window[start++], stderr); + } while (--length != 0); + } } #else -# define check_match(s, start, match, length) +#define check_match(s, start, match, length) #endif /* DEBUG */ /* =========================================================================== @@ -1388,70 +1463,76 @@ local void check_match(s, start, match, length) * option -- not supported here). */ local void fill_window(s) - deflate_state *s; + deflate_state *s; { - register unsigned n, m; - register Posf *p; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; + register unsigned n, m; + register Posf *p; + unsigned more; /* Amount of free space at the end of the window. */ + uInt wsize = s->w_size; - Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); + Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead"); - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); + do + { + more = (unsigned)(s->window_size - (ulg)s->lookahead - (ulg)s->strstart); - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if + /* Deal with !@#$% 64K limit: */ + if (sizeof(int) <= 2) + { + if (more == 0 && s->strstart == 0 && s->lookahead == 0) + { + more = wsize; + } + else if (more == (unsigned)(-1)) + { + /* Very unlikely, but possible on 16 bit machine if * strstart == 0 && lookahead == 1 (input done a byte at time) */ - more--; - } - } + more--; + } + } - /* If the window is almost full and there is insufficient lookahead, + /* If the window is almost full and there is insufficient lookahead, * move the upper half to the lower one to make room in the upper half. */ - if (s->strstart >= wsize+MAX_DIST(s)) { + if (s->strstart >= wsize + MAX_DIST(s)) + { + zmemcpy(s->window, s->window + wsize, (unsigned)wsize); + s->match_start -= wsize; + s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ + s->block_start -= (long)wsize; - zmemcpy(s->window, s->window+wsize, (unsigned)wsize); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - - /* Slide the hash table (could be avoided with 32 bit values + /* Slide the hash table (could be avoided with 32 bit values at the expense of memory usage). We slide even when level == 0 to keep the hash table consistent if we switch back to level > 0 later. (Using level 0 permanently is not an optimal usage of zlib, so we don't care about this pathological case.) */ - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - } while (--n); + n = s->hash_size; + p = &s->head[n]; + do + { + m = *--p; + *p = (Pos)(m >= wsize ? m - wsize : NIL); + } while (--n); - n = wsize; + n = wsize; #ifndef FASTEST - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but + p = &s->prev[n]; + do + { + m = *--p; + *p = (Pos)(m >= wsize ? m - wsize : NIL); + /* If n is not on any hash chain, prev[n] is garbage but * its value will never be used. */ - } while (--n); + } while (--n); #endif - more += wsize; - } - if (s->strm->avail_in == 0) break; + more += wsize; + } + if (s->strm->avail_in == 0) break; - /* If there was no sliding: + /* If there was no sliding: * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && * more == window_size - lookahead - strstart * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) @@ -1462,95 +1543,100 @@ local void fill_window(s) * Otherwise, window_size == 2*WSIZE so more >= 2. * If there was sliding, more >= WSIZE. So in all cases, more >= 2. */ - Assert(more >= 2, "more < 2"); + Assert(more >= 2, "more < 2"); - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; + n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); + s->lookahead += n; - /* Initialize the hash value now that we have some input: */ - if (s->lookahead + s->insert >= MIN_MATCH) { - uInt str = s->strstart - s->insert; - s->ins_h = s->window[str]; - UPDATE_HASH(s, s->ins_h, s->window[str + 1]); + /* Initialize the hash value now that we have some input: */ + if (s->lookahead + s->insert >= MIN_MATCH) + { + uInt str = s->strstart - s->insert; + s->ins_h = s->window[str]; + UPDATE_HASH(s, s->ins_h, s->window[str + 1]); #if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times + Call UPDATE_HASH() MIN_MATCH - 3 more times #endif - while (s->insert) { - UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]); + while (s->insert) + { + UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH - 1]); #ifndef FASTEST - s->prev[str & s->w_mask] = s->head[s->ins_h]; + s->prev[str & s->w_mask] = s->head[s->ins_h]; #endif - s->head[s->ins_h] = (Pos)str; - str++; - s->insert--; - if (s->lookahead + s->insert < MIN_MATCH) - break; - } - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, + s->head[s->ins_h] = (Pos)str; + str++; + s->insert--; + if (s->lookahead + s->insert < MIN_MATCH) + break; + } + } + /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, * but this is not important since only literal bytes will be emitted. */ - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); + } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); - /* If the WIN_INIT bytes after the end of the current data have never been + /* If the WIN_INIT bytes after the end of the current data have never been * written, then zero those bytes in order to avoid memory check reports of * the use of uninitialized (or uninitialised as Julian writes) bytes by * the longest match routines. Update the high water mark for the next * time through here. WIN_INIT is set to MAX_MATCH since the longest match * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. */ - if (s->high_water < s->window_size) { - ulg curr = s->strstart + (ulg)(s->lookahead); - ulg init; + if (s->high_water < s->window_size) + { + ulg curr = s->strstart + (ulg)(s->lookahead); + ulg init; - if (s->high_water < curr) { - /* Previous high water mark below current data -- zero WIN_INIT + if (s->high_water < curr) + { + /* Previous high water mark below current data -- zero WIN_INIT * bytes or up to end of window, whichever is less. */ - init = s->window_size - curr; - if (init > WIN_INIT) - init = WIN_INIT; - zmemzero(s->window + curr, (unsigned)init); - s->high_water = curr + init; - } - else if (s->high_water < (ulg)curr + WIN_INIT) { - /* High water mark at or above current data, but below current data + init = s->window_size - curr; + if (init > WIN_INIT) + init = WIN_INIT; + zmemzero(s->window + curr, (unsigned)init); + s->high_water = curr + init; + } + else if (s->high_water < (ulg)curr + WIN_INIT) + { + /* High water mark at or above current data, but below current data * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up * to end of window, whichever is less. */ - init = (ulg)curr + WIN_INIT - s->high_water; - if (init > s->window_size - s->high_water) - init = s->window_size - s->high_water; - zmemzero(s->window + s->high_water, (unsigned)init); - s->high_water += init; - } - } + init = (ulg)curr + WIN_INIT - s->high_water; + if (init > s->window_size - s->high_water) + init = s->window_size - s->high_water; + zmemzero(s->window + s->high_water, (unsigned)init); + s->high_water += init; + } + } - Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, - "not enough room for search"); + Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD, + "not enough room for search"); } /* =========================================================================== * Flush the current block, with given end-of-file flag. * IN assertion: strstart is set to the end of the current match. */ -#define FLUSH_BLOCK_ONLY(s, last) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (last)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} +#define FLUSH_BLOCK_ONLY(s, last) \ + { \ + _tr_flush_block(s, (s->block_start >= 0L ? (charf *)&s->window[(unsigned)s->block_start] : (charf *)Z_NULL), \ + (ulg)((long)s->strstart - s->block_start), \ + (last)); \ + s->block_start = s->strstart; \ + flush_pending(s->strm); \ + Tracev((stderr, "[FLUSH]")); \ + } /* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, last) { \ - FLUSH_BLOCK_ONLY(s, last); \ - if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ -} +#define FLUSH_BLOCK(s, last) \ + { \ + FLUSH_BLOCK_ONLY(s, last); \ + if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ + } /* =========================================================================== * Copy without compression as much as possible from the input stream, return @@ -1562,60 +1648,66 @@ local void fill_window(s) * window to pending_buf. */ local block_state deflate_stored(s, flush) - deflate_state *s; - int flush; + deflate_state *s; +int flush; { - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited + /* Stored blocks are limited to 0xffff bytes, pending_buf is limited * to pending_buf_size, and each stored block has a 5 byte header: */ - ulg max_block_size = 0xffff; - ulg max_start; + ulg max_block_size = 0xffff; + ulg max_start; - if (max_block_size > s->pending_buf_size - 5) { - max_block_size = s->pending_buf_size - 5; - } + if (max_block_size > s->pending_buf_size - 5) + { + max_block_size = s->pending_buf_size - 5; + } - /* Copy as much as possible from input to output: */ - for (;;) { - /* Fill the window as much as possible: */ - if (s->lookahead <= 1) { + /* Copy as much as possible from input to output: */ + for (;;) + { + /* Fill the window as much as possible: */ + if (s->lookahead <= 1) + { + Assert(s->strstart < s->w_size + MAX_DIST(s) || + s->block_start >= (long)s->w_size, + "slide too late"); - Assert(s->strstart < s->w_size+MAX_DIST(s) || - s->block_start >= (long)s->w_size, "slide too late"); + fill_window(s); + if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; - fill_window(s); - if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; + if (s->lookahead == 0) break; /* flush the current block */ + } + Assert(s->block_start >= 0L, "block gone"); - if (s->lookahead == 0) break; /* flush the current block */ - } - Assert(s->block_start >= 0L, "block gone"); + s->strstart += s->lookahead; + s->lookahead = 0; - s->strstart += s->lookahead; - s->lookahead = 0; - - /* Emit a stored block if pending_buf will be full: */ - max_start = s->block_start + max_block_size; - if (s->strstart == 0 || (ulg)s->strstart >= max_start) { - /* strstart == 0 is possible when wraparound on 16-bit machine */ - s->lookahead = (uInt)(s->strstart - max_start); - s->strstart = (uInt)max_start; - FLUSH_BLOCK(s, 0); - } - /* Flush if we may have to slide, otherwise block_start may become + /* Emit a stored block if pending_buf will be full: */ + max_start = s->block_start + max_block_size; + if (s->strstart == 0 || (ulg)s->strstart >= max_start) + { + /* strstart == 0 is possible when wraparound on 16-bit machine */ + s->lookahead = (uInt)(s->strstart - max_start); + s->strstart = (uInt)max_start; + FLUSH_BLOCK(s, 0); + } + /* Flush if we may have to slide, otherwise block_start may become * negative and the data will be gone: */ - if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { - FLUSH_BLOCK(s, 0); - } - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if ((long)s->strstart > s->block_start) - FLUSH_BLOCK(s, 0); - return block_done; + if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) + { + FLUSH_BLOCK(s, 0); + } + } + s->insert = 0; + if (flush == Z_FINISH) + { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if ((long)s->strstart > s->block_start) + FLUSH_BLOCK(s, 0); + return block_done; } /* =========================================================================== @@ -1626,99 +1718,111 @@ local block_state deflate_stored(s, flush) * matches. It is used only for the fast compression options. */ local block_state deflate_fast(s, flush) - deflate_state *s; - int flush; + deflate_state *s; +int flush; { - IPos hash_head; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ + IPos hash_head; /* head of the hash chain */ + int bflush; /* set if current block must be flushed */ - for (;;) { - /* Make sure that we always have enough lookahead, except + for (;;) + { + /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } + if (s->lookahead < MIN_LOOKAHEAD) + { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) + { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } - /* Insert the string window[strstart .. strstart+2] in the + /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) + { + INSERT_STRING(s, s->strstart, hash_head); + } - /* Find the longest match, discarding those <= prev_length. + /* Find the longest match, discarding those <= prev_length. * At this point we have always match_length < MIN_MATCH */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string + if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) + { + /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); + s->match_length = longest_match(s, hash_head); + /* longest_match() sets match_start */ + } + if (s->match_length >= MIN_MATCH) + { + check_match(s, s->strstart, s->match_start, s->match_length); - _tr_tally_dist(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH, bflush); + _tr_tally_dist(s, s->strstart - s->match_start, + s->match_length - MIN_MATCH, bflush); - s->lookahead -= s->match_length; + s->lookahead -= s->match_length; - /* Insert new strings in the hash table only if the match length + /* Insert new strings in the hash table only if the match length * is not too large. This saves time but degrades compression. */ #ifndef FASTEST - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are + if (s->match_length <= s->max_insert_length && + s->lookahead >= MIN_MATCH) + { + s->match_length--; /* string at strstart already in table */ + do + { + s->strstart++; + INSERT_STRING(s, s->strstart, hash_head); + /* strstart never exceeds WSIZE-MAX_MATCH, so there are * always MIN_MATCH bytes ahead. */ - } while (--s->match_length != 0); - s->strstart++; - } else + } while (--s->match_length != 0); + s->strstart++; + } + else #endif - { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); + { + s->strstart += s->match_length; + s->match_length = 0; + s->ins_h = s->window[s->strstart]; + UPDATE_HASH(s, s->ins_h, s->window[s->strstart + 1]); #if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times + Call UPDATE_HASH() MIN_MATCH - 3 more times #endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not + /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not * matter since it will be recomputed at next deflate call. */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; + } + } + else + { + /* No match, output a literal byte */ + Tracevv((stderr, "%c", s->window[s->strstart])); + _tr_tally_lit(s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = s->strstart < MIN_MATCH - 1 ? s->strstart : MIN_MATCH - 1; + if (flush == Z_FINISH) + { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; } #ifndef FASTEST @@ -1728,128 +1832,142 @@ local block_state deflate_fast(s, flush) * no better match at the next window position. */ local block_state deflate_slow(s, flush) - deflate_state *s; - int flush; + deflate_state *s; +int flush; { - IPos hash_head; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ + IPos hash_head; /* head of hash chain */ + int bflush; /* set if current block must be flushed */ - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except + /* Process the input block. */ + for (;;) + { + /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the next match, plus MIN_MATCH bytes to insert the * string following the next match. */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } + if (s->lookahead < MIN_LOOKAHEAD) + { + fill_window(s); + if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) + { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } - /* Insert the string window[strstart .. strstart+2] in the + /* Insert the string window[strstart .. strstart+2] in the * dictionary, and set hash_head to the head of the hash chain: */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } + hash_head = NIL; + if (s->lookahead >= MIN_MATCH) + { + INSERT_STRING(s, s->strstart, hash_head); + } - /* Find the longest match, discarding those <= prev_length. + /* Find the longest match, discarding those <= prev_length. */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; + s->prev_length = s->match_length, s->prev_match = s->match_start; + s->match_length = MIN_MATCH - 1; - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string + if (hash_head != NIL && s->prev_length < s->max_lazy_match && + s->strstart - hash_head <= MAX_DIST(s)) + { + /* To simplify the code, we prevent matches with the string * of window index 0 (in particular we have to avoid a match * of the string with itself at the start of the input file). */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ + s->match_length = longest_match(s, hash_head); + /* longest_match() sets match_start */ - if (s->match_length <= 5 && (s->strategy == Z_FILTERED + if (s->match_length <= 5 && (s->strategy == Z_FILTERED #if TOO_FAR <= 32767 - || (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR) + || (s->match_length == MIN_MATCH && + s->strstart - s->match_start > TOO_FAR) #endif - )) { - - /* If prev_match is also MIN_MATCH, match_start is garbage + )) + { + /* If prev_match is also MIN_MATCH, match_start is garbage * but we will ignore the current match anyway. */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current + s->match_length = MIN_MATCH - 1; + } + } + /* If there was a match at the previous step and the current * match is not better, output the previous match: */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ + if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) + { + uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; + /* Do not insert strings in hash table beyond this. */ - check_match(s, s->strstart-1, s->prev_match, s->prev_length); + check_match(s, s->strstart - 1, s->prev_match, s->prev_length); - _tr_tally_dist(s, s->strstart -1 - s->prev_match, - s->prev_length - MIN_MATCH, bflush); + _tr_tally_dist(s, s->strstart - 1 - s->prev_match, + s->prev_length - MIN_MATCH, bflush); - /* Insert in hash table all strings up to the end of the match. + /* Insert in hash table all strings up to the end of the match. * strstart-1 and strstart are already inserted. If there is not * enough lookahead, the last two strings are not inserted in * the hash table. */ - s->lookahead -= s->prev_length-1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; + s->lookahead -= s->prev_length - 1; + s->prev_length -= 2; + do + { + if (++s->strstart <= max_insert) + { + INSERT_STRING(s, s->strstart, hash_head); + } + } while (--s->prev_length != 0); + s->match_available = 0; + s->match_length = MIN_MATCH - 1; + s->strstart++; - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a + if (bflush) FLUSH_BLOCK(s, 0); + } + else if (s->match_available) + { + /* If there was no match at the previous position, output a * single literal. If there was a match but the current match * is longer, truncate the previous match to a single literal. */ - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - if (bflush) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for + Tracevv((stderr, "%c", s->window[s->strstart - 1])); + _tr_tally_lit(s, s->window[s->strstart - 1], bflush); + if (bflush) + { + FLUSH_BLOCK_ONLY(s, 0); + } + s->strstart++; + s->lookahead--; + if (s->strm->avail_out == 0) return need_more; + } + else + { + /* There is no previous match to compare with, wait for * the next step to decide. */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - s->match_available = 0; - } - s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; + s->match_available = 1; + s->strstart++; + s->lookahead--; + } + } + Assert(flush != Z_NO_FLUSH, "no flush?"); + if (s->match_available) + { + Tracevv((stderr, "%c", s->window[s->strstart - 1])); + _tr_tally_lit(s, s->window[s->strstart - 1], bflush); + s->match_available = 0; + } + s->insert = s->strstart < MIN_MATCH - 1 ? s->strstart : MIN_MATCH - 1; + if (flush == Z_FINISH) + { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; } #endif /* FASTEST */ @@ -1859,72 +1977,82 @@ local block_state deflate_slow(s, flush) * deflate switches away from Z_RLE.) */ local block_state deflate_rle(s, flush) - deflate_state *s; - int flush; + deflate_state *s; +int flush; { - int bflush; /* set if current block must be flushed */ - uInt prev; /* byte at distance one to match */ - Bytef *scan, *strend; /* scan goes up to strend for length of run */ + int bflush; /* set if current block must be flushed */ + uInt prev; /* byte at distance one to match */ + Bytef *scan, *strend; /* scan goes up to strend for length of run */ - for (;;) { - /* Make sure that we always have enough lookahead, except + for (;;) + { + /* Make sure that we always have enough lookahead, except * at the end of the input file. We need MAX_MATCH bytes * for the longest run, plus one for the unrolled loop. */ - if (s->lookahead <= MAX_MATCH) { - fill_window(s); - if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } + if (s->lookahead <= MAX_MATCH) + { + fill_window(s); + if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) + { + return need_more; + } + if (s->lookahead == 0) break; /* flush the current block */ + } - /* See how many times the previous byte repeats */ - s->match_length = 0; - if (s->lookahead >= MIN_MATCH && s->strstart > 0) { - scan = s->window + s->strstart - 1; - prev = *scan; - if (prev == *++scan && prev == *++scan && prev == *++scan) { - strend = s->window + s->strstart + MAX_MATCH; - do { - } while (prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - scan < strend); - s->match_length = MAX_MATCH - (int)(strend - scan); - if (s->match_length > s->lookahead) - s->match_length = s->lookahead; - } - Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan"); - } + /* See how many times the previous byte repeats */ + s->match_length = 0; + if (s->lookahead >= MIN_MATCH && s->strstart > 0) + { + scan = s->window + s->strstart - 1; + prev = *scan; + if (prev == *++scan && prev == *++scan && prev == *++scan) + { + strend = s->window + s->strstart + MAX_MATCH; + do + { + } while (prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + prev == *++scan && prev == *++scan && + scan < strend); + s->match_length = MAX_MATCH - (int)(strend - scan); + if (s->match_length > s->lookahead) + s->match_length = s->lookahead; + } + Assert(scan <= s->window + (uInt)(s->window_size - 1), "wild scan"); + } - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, s->match_length); + /* Emit match if have run of MIN_MATCH or longer, else emit literal */ + if (s->match_length >= MIN_MATCH) + { + check_match(s, s->strstart, s->strstart - 1, s->match_length); - _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); + _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); - s->lookahead -= s->match_length; - s->strstart += s->match_length; - s->match_length = 0; - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; + s->lookahead -= s->match_length; + s->strstart += s->match_length; + s->match_length = 0; + } + else + { + /* No match, output a literal byte */ + Tracevv((stderr, "%c", s->window[s->strstart])); + _tr_tally_lit(s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + } + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) + { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; } /* =========================================================================== @@ -1932,36 +2060,40 @@ local block_state deflate_rle(s, flush) * (It will be regenerated if this run of deflate switches away from Huffman.) */ local block_state deflate_huff(s, flush) - deflate_state *s; - int flush; + deflate_state *s; +int flush; { - int bflush; /* set if current block must be flushed */ + int bflush; /* set if current block must be flushed */ - for (;;) { - /* Make sure that we have a literal to write. */ - if (s->lookahead == 0) { - fill_window(s); - if (s->lookahead == 0) { - if (flush == Z_NO_FLUSH) - return need_more; - break; /* flush the current block */ - } - } + for (;;) + { + /* Make sure that we have a literal to write. */ + if (s->lookahead == 0) + { + fill_window(s); + if (s->lookahead == 0) + { + if (flush == Z_NO_FLUSH) + return need_more; + break; /* flush the current block */ + } + } - /* Output a literal byte */ - s->match_length = 0; - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - if (bflush) FLUSH_BLOCK(s, 0); - } - s->insert = 0; - if (flush == Z_FINISH) { - FLUSH_BLOCK(s, 1); - return finish_done; - } - if (s->last_lit) - FLUSH_BLOCK(s, 0); - return block_done; + /* Output a literal byte */ + s->match_length = 0; + Tracevv((stderr, "%c", s->window[s->strstart])); + _tr_tally_lit(s, s->window[s->strstart], bflush); + s->lookahead--; + s->strstart++; + if (bflush) FLUSH_BLOCK(s, 0); + } + s->insert = 0; + if (flush == Z_FINISH) + { + FLUSH_BLOCK(s, 1); + return finish_done; + } + if (s->last_lit) + FLUSH_BLOCK(s, 0); + return block_done; } diff --git a/examples/ThirdPartyLibs/zlib/deflate.h b/examples/ThirdPartyLibs/zlib/deflate.h index ce0299edd..eb3ff791e 100644 --- a/examples/ThirdPartyLibs/zlib/deflate.h +++ b/examples/ThirdPartyLibs/zlib/deflate.h @@ -20,7 +20,7 @@ the crc code when it is not needed. For shared libraries, gzip encoding should be left enabled. */ #ifndef NO_GZIP -# define GZIP +#define GZIP #endif /* =========================================================================== @@ -30,19 +30,19 @@ #define LENGTH_CODES 29 /* number of length codes, not counting the special END_BLOCK code */ -#define LITERALS 256 +#define LITERALS 256 /* number of literal bytes 0..255 */ -#define L_CODES (LITERALS+1+LENGTH_CODES) +#define L_CODES (LITERALS + 1 + LENGTH_CODES) /* number of Literal or Length codes, including the END_BLOCK code */ -#define D_CODES 30 +#define D_CODES 30 /* number of distance codes */ -#define BL_CODES 19 +#define BL_CODES 19 /* number of codes used to transfer the bit lengths */ -#define HEAP_SIZE (2*L_CODES+1) +#define HEAP_SIZE (2 * L_CODES + 1) /* maximum heap size */ #define MAX_BITS 15 @@ -51,39 +51,40 @@ #define Buf_size 16 /* size of bit buffer in bi_buf */ -#define INIT_STATE 42 -#define EXTRA_STATE 69 -#define NAME_STATE 73 +#define INIT_STATE 42 +#define EXTRA_STATE 69 +#define NAME_STATE 73 #define COMMENT_STATE 91 -#define HCRC_STATE 103 -#define BUSY_STATE 113 +#define HCRC_STATE 103 +#define BUSY_STATE 113 #define FINISH_STATE 666 /* Stream status */ - /* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; +typedef struct ct_data_s +{ + union { + ush freq; /* frequency count */ + ush code; /* bit string */ + } fc; + union { + ush dad; /* father node in Huffman tree */ + ush len; /* length of bit string */ + } dl; } FAR ct_data; #define Freq fc.freq #define Code fc.code -#define Dad dl.dad -#define Len dl.len +#define Dad dl.dad +#define Len dl.len -typedef struct static_tree_desc_s static_tree_desc; +typedef struct static_tree_desc_s static_tree_desc; -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - static_tree_desc *stat_desc; /* the corresponding static tree */ +typedef struct tree_desc_s +{ + ct_data *dyn_tree; /* the dynamic tree */ + int max_code; /* largest code with non zero frequency */ + static_tree_desc *stat_desc; /* the corresponding static tree */ } FAR tree_desc; typedef ush Pos; @@ -94,27 +95,28 @@ typedef unsigned IPos; * save space in the various tables. IPos is used only for parameter passing. */ -typedef struct internal_state { - z_streamp strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - ulg pending_buf_size; /* size of pending_buf */ - Bytef *pending_out; /* next pending byte to output to the stream */ - uInt pending; /* nb of bytes in the pending buffer */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - gz_headerp gzhead; /* gzip header information to write */ - uInt gzindex; /* where in extra, name, or comment */ - Byte method; /* can only be DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ +typedef struct internal_state +{ + z_streamp strm; /* pointer back to this zlib stream */ + int status; /* as the name implies */ + Bytef *pending_buf; /* output still pending */ + ulg pending_buf_size; /* size of pending_buf */ + Bytef *pending_out; /* next pending byte to output to the stream */ + uInt pending; /* nb of bytes in the pending buffer */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + gz_headerp gzhead; /* gzip header information to write */ + uInt gzindex; /* where in extra, name, or comment */ + Byte method; /* can only be DEFLATED */ + int last_flush; /* value of flush param for previous deflate call */ - /* used by deflate.c: */ + /* used by deflate.c: */ - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ + uInt w_size; /* LZ77 window size (32K by default) */ + uInt w_bits; /* log2(w_size) (8..16) */ + uInt w_mask; /* w_size - 1 */ - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, + Bytef *window; + /* Sliding window. Input bytes are read into the second half of the window, * and move to the first half later to keep a dictionary of at least wSize * bytes. With this organization, matches are limited to a distance of * wSize-MAX_MATCH bytes, but this ensures that IO is always @@ -123,101 +125,101 @@ typedef struct internal_state { * To do: use the user input buffer as sliding window. */ - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer + ulg window_size; + /* Actual size of window: 2*wSize, except when the user input buffer * is directly used as sliding window. */ - Posf *prev; - /* Link to older string with same hash index. To limit the size of this + Posf *prev; + /* Link to older string with same hash index. To limit the size of this * array to 64K, this link is maintained only for the last 32K strings. * An index in this array is thus a window index modulo 32K. */ - Posf *head; /* Heads of the hash chains or NIL. */ + Posf *head; /* Heads of the hash chains or NIL. */ - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ + uInt ins_h; /* hash index of string to be inserted */ + uInt hash_size; /* number of elements in hash table */ + uInt hash_bits; /* log2(hash_size) */ + uInt hash_mask; /* hash_size-1 */ - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input + uInt hash_shift; + /* Number of bits by which ins_h must be shifted at each input * step. It must be such that after MIN_MATCH steps, the oldest * byte no longer takes part in the hash key, that is: * hash_shift * MIN_MATCH >= hash_bits */ - long block_start; - /* Window position at the beginning of the current output block. Gets + long block_start; + /* Window position at the beginning of the current output block. Gets * negative when the window is moved backwards. */ - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ + uInt match_length; /* length of best match */ + IPos prev_match; /* previous match */ + int match_available; /* set if previous match exists */ + uInt strstart; /* start of string to insert */ + uInt match_start; /* start of matching string */ + uInt lookahead; /* number of valid bytes ahead in window */ - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this + uInt prev_length; + /* Length of the best match at previous step. Matches not greater than this * are discarded. This is used in the lazy match evaluation. */ - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this + uInt max_chain_length; + /* To speed up deflation, hash chains are never searched beyond this * length. A higher limit improves compression ratio but degrades the * speed. */ - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly + uInt max_lazy_match; + /* Attempt to find a better match only when the current match is strictly * smaller than this value. This mechanism is used only for compression * levels >= 4. */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not +#define max_insert_length max_lazy_match + /* Insert new strings in the hash table only if the match length is not * greater than this length. This saves time but degrades compression. * max_insert_length is used only for compression levels <= 3. */ - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ + int level; /* compression level (1..9) */ + int strategy; /* favor or force Huffman coding*/ - uInt good_match; - /* Use a faster search when the previous match is longer than this */ + uInt good_match; + /* Use a faster search when the previous match is longer than this */ - int nice_match; /* Stop searching when current match exceeds this */ + int nice_match; /* Stop searching when current match exceeds this */ - /* used by trees.c: */ - /* Didn't use ct_data typedef below to suppress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ + /* used by trees.c: */ + /* Didn't use ct_data typedef below to suppress compiler warning */ + struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ + struct ct_data_s dyn_dtree[2 * D_CODES + 1]; /* distance tree */ + struct ct_data_s bl_tree[2 * BL_CODES + 1]; /* Huffman tree for bit lengths */ - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ + struct tree_desc_s l_desc; /* desc. for literal tree */ + struct tree_desc_s d_desc; /* desc. for distance tree */ + struct tree_desc_s bl_desc; /* desc. for bit length tree */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ + ush bl_count[MAX_BITS + 1]; + /* number of codes at each bit length for an optimal tree */ - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. + int heap[2 * L_CODES + 1]; /* heap used to build the Huffman trees */ + int heap_len; /* number of elements in the heap */ + int heap_max; /* element of largest frequency */ + /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. * The same heap array is used to build all trees. */ - uch depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency + uch depth[2 * L_CODES + 1]; + /* Depth of each subtree used as tie breaker for trees of equal frequency */ - uchf *l_buf; /* buffer for literals or lengths */ + uchf *l_buf; /* buffer for literals or lengths */ - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for + uInt lit_bufsize; + /* Size of match buffer for literals/lengths. There are 4 reasons for * limiting lit_bufsize to 64K: * - frequencies can be kept in 16 bit counters * - if compression is not successful for the first block, all input @@ -236,35 +238,35 @@ typedef struct internal_state { * - I can't count above 4 */ - uInt last_lit; /* running index in l_buf */ + uInt last_lit; /* running index in l_buf */ - ushf *d_buf; - /* Buffer for distances. To simplify the code, d_buf and l_buf have + ushf *d_buf; + /* Buffer for distances. To simplify the code, d_buf and l_buf have * the same number of elements. To use different lengths, an extra flag * array would be necessary. */ - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - uInt matches; /* number of string matches in current block */ - uInt insert; /* bytes at end of window left to insert */ + ulg opt_len; /* bit length of current block with optimal trees */ + ulg static_len; /* bit length of current block with static trees */ + uInt matches; /* number of string matches in current block */ + uInt insert; /* bytes at end of window left to insert */ #ifdef DEBUG - ulg compressed_len; /* total bit length of compressed file mod 2^32 */ - ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ + ulg compressed_len; /* total bit length of compressed file mod 2^32 */ + ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ #endif - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least + ush bi_buf; + /* Output buffer. bits are inserted starting at the bottom (least * significant bits). */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit + int bi_valid; + /* Number of valid bits in bi_buf. All bits above the last valid bit * are always zero. */ - ulg high_water; - /* High water mark offset in window for initialized bytes -- bytes above + ulg high_water; + /* High water mark offset in window for initialized bytes -- bytes above * this are set to zero in order to avoid memory check warnings when * longest match routines access bytes past the input. This is then * updated to the new high water mark. @@ -275,15 +277,17 @@ typedef struct internal_state { /* Output a byte on the stream. * IN assertion: there is enough room in pending_buf. */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} +#define put_byte(s, c) \ + { \ + s->pending_buf[s->pending++] = (c); \ + } - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) +#define MIN_LOOKAHEAD (MAX_MATCH + MIN_MATCH + 1) /* Minimum amount of lookahead, except at the end of the input file. * See deflate.c for comments about the MIN_MATCH+1. */ -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) +#define MAX_DIST(s) ((s)->w_size - MIN_LOOKAHEAD) /* In order to simplify the code, particularly on 16 bit machines, match * distances are limited to MAX_DIST instead of WSIZE. */ @@ -292,18 +296,18 @@ typedef struct internal_state { /* Number of bytes after end of data in window to initialize in order to avoid memory checker errors from longest match routines */ - /* in trees.c */ -void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); -int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); -void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); +/* in trees.c */ +void ZLIB_INTERNAL _tr_init OF((deflate_state * s)); +int ZLIB_INTERNAL _tr_tally OF((deflate_state * s, unsigned dist, unsigned lc)); +void ZLIB_INTERNAL _tr_flush_block OF((deflate_state * s, charf *buf, + ulg stored_len, int last)); +void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state * s)); +void ZLIB_INTERNAL _tr_align OF((deflate_state * s)); +void ZLIB_INTERNAL _tr_stored_block OF((deflate_state * s, charf *buf, + ulg stored_len, int last)); #define d_code(dist) \ - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) + ((dist) < 256 ? _dist_code[dist] : _dist_code[256 + ((dist) >> 7)]) /* Mapping from a distance to a distance code. dist is the distance - 1 and * must not have side effects. _dist_code[256] and _dist_code[257] are never * used. @@ -313,34 +317,36 @@ void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, /* Inline versions of _tr_tally for speed: */ #if defined(GEN_TREES_H) || !defined(STDC) - extern uch ZLIB_INTERNAL _length_code[]; - extern uch ZLIB_INTERNAL _dist_code[]; +extern uch ZLIB_INTERNAL _length_code[]; +extern uch ZLIB_INTERNAL _dist_code[]; #else - extern const uch ZLIB_INTERNAL _length_code[]; - extern const uch ZLIB_INTERNAL _dist_code[]; +extern const uch ZLIB_INTERNAL _length_code[]; +extern const uch ZLIB_INTERNAL _dist_code[]; #endif -# define _tr_tally_lit(s, c, flush) \ - { uch cc = (c); \ - s->d_buf[s->last_lit] = 0; \ - s->l_buf[s->last_lit++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (length); \ - ush dist = (distance); \ - s->d_buf[s->last_lit] = dist; \ - s->l_buf[s->last_lit++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } +#define _tr_tally_lit(s, c, flush) \ + { \ + uch cc = (c); \ + s->d_buf[s->last_lit] = 0; \ + s->l_buf[s->last_lit++] = cc; \ + s->dyn_ltree[cc].Freq++; \ + flush = (s->last_lit == s->lit_bufsize - 1); \ + } +#define _tr_tally_dist(s, distance, length, flush) \ + { \ + uch len = (length); \ + ush dist = (distance); \ + s->d_buf[s->last_lit] = dist; \ + s->l_buf[s->last_lit++] = len; \ + dist--; \ + s->dyn_ltree[_length_code[len] + LITERALS + 1].Freq++; \ + s->dyn_dtree[d_code(dist)].Freq++; \ + flush = (s->last_lit == s->lit_bufsize - 1); \ + } #else -# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) -# define _tr_tally_dist(s, distance, length, flush) \ - flush = _tr_tally(s, distance, length) +#define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) +#define _tr_tally_dist(s, distance, length, flush) \ + flush = _tr_tally(s, distance, length) #endif #endif /* DEFLATE_H */ diff --git a/examples/ThirdPartyLibs/zlib/gzclose.c b/examples/ThirdPartyLibs/zlib/gzclose.c index caeb99a31..05c10c065 100644 --- a/examples/ThirdPartyLibs/zlib/gzclose.c +++ b/examples/ThirdPartyLibs/zlib/gzclose.c @@ -9,17 +9,17 @@ That way the other gzclose functions can be used instead to avoid linking in unneeded compression or decompression routines. */ int ZEXPORT gzclose(file) - gzFile file; + gzFile file; { #ifndef NO_GZCOMPRESS - gz_statep state; + gz_statep state; - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; - return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); + return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file); #else - return gzclose_r(file); + return gzclose_r(file); #endif } diff --git a/examples/ThirdPartyLibs/zlib/gzguts.h b/examples/ThirdPartyLibs/zlib/gzguts.h index d87659d03..39274b8f5 100644 --- a/examples/ThirdPartyLibs/zlib/gzguts.h +++ b/examples/ThirdPartyLibs/zlib/gzguts.h @@ -4,95 +4,95 @@ */ #ifdef _LARGEFILE64_SOURCE -# ifndef _LARGEFILE_SOURCE -# define _LARGEFILE_SOURCE 1 -# endif -# ifdef _FILE_OFFSET_BITS -# undef _FILE_OFFSET_BITS -# endif +#ifndef _LARGEFILE_SOURCE +#define _LARGEFILE_SOURCE 1 +#endif +#ifdef _FILE_OFFSET_BITS +#undef _FILE_OFFSET_BITS +#endif #endif #ifdef HAVE_HIDDEN -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#define ZLIB_INTERNAL __attribute__((visibility("hidden"))) #else -# define ZLIB_INTERNAL +#define ZLIB_INTERNAL #endif #include #include "zlib.h" #ifdef STDC -# include -# include -# include +#include +#include +#include #endif #include #ifdef _WIN32 -# include +#include #endif #if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32) -# include +#include #endif #ifdef WINAPI_FAMILY -# define open _open -# define read _read -# define write _write -# define close _close +#define open _open +#define read _read +#define write _write +#define close _close #endif -#ifdef NO_DEFLATE /* for compatibility with old definition */ -# define NO_GZCOMPRESS +#ifdef NO_DEFLATE /* for compatibility with old definition */ +#define NO_GZCOMPRESS #endif #if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif +#ifndef HAVE_VSNPRINTF +#define HAVE_VSNPRINTF +#endif #endif #if defined(__CYGWIN__) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif +#ifndef HAVE_VSNPRINTF +#define HAVE_VSNPRINTF +#endif #endif #if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif +#ifndef HAVE_VSNPRINTF +#define HAVE_VSNPRINTF +#endif #endif #ifndef HAVE_VSNPRINTF -# ifdef MSDOS +#ifdef MSDOS /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), but for now we just assume it doesn't. */ -# define NO_vsnprintf -# endif -# ifdef __TURBOC__ -# define NO_vsnprintf -# endif -# ifdef WIN32 +#define NO_vsnprintf +#endif +#ifdef __TURBOC__ +#define NO_vsnprintf +#endif +#ifdef WIN32 /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ -# if !defined(vsnprintf) && !defined(NO_vsnprintf) -# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) -# define vsnprintf _vsnprintf -# endif -# endif -# endif -# ifdef __SASC -# define NO_vsnprintf -# endif -# ifdef VMS -# define NO_vsnprintf -# endif -# ifdef __OS400__ -# define NO_vsnprintf -# endif -# ifdef __MVS__ -# define NO_vsnprintf -# endif +#if !defined(vsnprintf) && !defined(NO_vsnprintf) +#if !defined(_MSC_VER) || (defined(_MSC_VER) && _MSC_VER < 1500) +#define vsnprintf _vsnprintf +#endif +#endif +#endif +#ifdef __SASC +#define NO_vsnprintf +#endif +#ifdef VMS +#define NO_vsnprintf +#endif +#ifdef __OS400__ +#define NO_vsnprintf +#endif +#ifdef __MVS__ +#define NO_vsnprintf +#endif #endif /* unlike snprintf (which is required in C99, yet still not supported by @@ -100,46 +100,46 @@ termination of the result -- however this is only used in gzlib.c where the result is assured to fit in the space provided */ #ifdef _MSC_VER -# define snprintf _snprintf +#define snprintf _snprintf #endif #ifndef local -# define local static +#define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ /* gz* functions always use library allocation functions */ #ifndef STDC - extern voidp malloc OF((uInt size)); - extern void free OF((voidpf ptr)); +extern voidp malloc OF((uInt size)); +extern void free OF((voidpf ptr)); #endif /* get errno and strerror definition */ #if defined UNDER_CE -# include -# define zstrerror() gz_strwinerror((DWORD)GetLastError()) +#include +#define zstrerror() gz_strwinerror((DWORD)GetLastError()) #else -# ifndef NO_STRERROR -# include -# define zstrerror() strerror(errno) -# else -# define zstrerror() "stdio error (consult errno)" -# endif +#ifndef NO_STRERROR +#include +#define zstrerror() strerror(errno) +#else +#define zstrerror() "stdio error (consult errno)" +#endif #endif /* provide prototypes for these when building zlib without LFS */ -#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); +#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE - 0 == 0 +ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); +ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); +ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); +ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); #endif /* default memLevel */ #if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 +#define DEF_MEM_LEVEL 8 #else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif /* default i/o buffer size -- double this for output when reading (this and @@ -150,45 +150,46 @@ #define GZ_NONE 0 #define GZ_READ 7247 #define GZ_WRITE 31153 -#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ +#define GZ_APPEND 1 /* mode set to GZ_WRITE after the file is opened */ /* values for gz_state how */ -#define LOOK 0 /* look for a gzip header */ -#define COPY 1 /* copy input directly */ -#define GZIP 2 /* decompress a gzip stream */ +#define LOOK 0 /* look for a gzip header */ +#define COPY 1 /* copy input directly */ +#define GZIP 2 /* decompress a gzip stream */ /* internal gzip file state data structure */ -typedef struct { - /* exposed contents for gzgetc() macro */ - struct gzFile_s x; /* "x" for exposed */ - /* x.have: number of bytes available at x.next */ - /* x.next: next output data to deliver or write */ - /* x.pos: current position in uncompressed data */ - /* used for both reading and writing */ - int mode; /* see gzip modes above */ - int fd; /* file descriptor */ - char *path; /* path or fd for error messages */ - unsigned size; /* buffer size, zero if not allocated yet */ - unsigned want; /* requested buffer size, default is GZBUFSIZE */ - unsigned char *in; /* input buffer */ - unsigned char *out; /* output buffer (double-sized when reading) */ - int direct; /* 0 if processing gzip, 1 if transparent */ - /* just for reading */ - int how; /* 0: get header, 1: copy, 2: decompress */ - z_off64_t start; /* where the gzip data started, for rewinding */ - int eof; /* true if end of input file reached */ - int past; /* true if read requested past end */ - /* just for writing */ - int level; /* compression level */ - int strategy; /* compression strategy */ - /* seek request */ - z_off64_t skip; /* amount to skip (already rewound if backwards) */ - int seek; /* true if seek request pending */ - /* error information */ - int err; /* error code */ - char *msg; /* error message */ - /* zlib inflate or deflate stream */ - z_stream strm; /* stream structure in-place (not a pointer) */ +typedef struct +{ + /* exposed contents for gzgetc() macro */ + struct gzFile_s x; /* "x" for exposed */ + /* x.have: number of bytes available at x.next */ + /* x.next: next output data to deliver or write */ + /* x.pos: current position in uncompressed data */ + /* used for both reading and writing */ + int mode; /* see gzip modes above */ + int fd; /* file descriptor */ + char *path; /* path or fd for error messages */ + unsigned size; /* buffer size, zero if not allocated yet */ + unsigned want; /* requested buffer size, default is GZBUFSIZE */ + unsigned char *in; /* input buffer */ + unsigned char *out; /* output buffer (double-sized when reading) */ + int direct; /* 0 if processing gzip, 1 if transparent */ + /* just for reading */ + int how; /* 0: get header, 1: copy, 2: decompress */ + z_off64_t start; /* where the gzip data started, for rewinding */ + int eof; /* true if end of input file reached */ + int past; /* true if read requested past end */ + /* just for writing */ + int level; /* compression level */ + int strategy; /* compression strategy */ + /* seek request */ + z_off64_t skip; /* amount to skip (already rewound if backwards) */ + int seek; /* true if seek request pending */ + /* error information */ + int err; /* error code */ + char *msg; /* error message */ + /* zlib inflate or deflate stream */ + z_stream strm; /* stream structure in-place (not a pointer) */ } gz_state; typedef gz_state FAR *gz_statep; @@ -202,8 +203,8 @@ char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error)); value -- needed when comparing unsigned to z_off64_t, which is signed (possible z_off64_t types off_t, off64_t, and long are all signed) */ #ifdef INT_MAX -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) +#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX) #else unsigned ZLIB_INTERNAL gz_intmax OF((void)); -# define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) +#define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax()) #endif diff --git a/examples/ThirdPartyLibs/zlib/gzlib.c b/examples/ThirdPartyLibs/zlib/gzlib.c index fae202ef8..1783e01c5 100644 --- a/examples/ThirdPartyLibs/zlib/gzlib.c +++ b/examples/ThirdPartyLibs/zlib/gzlib.c @@ -6,12 +6,12 @@ #include "gzguts.h" #if defined(_WIN32) && !defined(__BORLANDC__) -# define LSEEK _lseeki64 +#define LSEEK _lseeki64 #else -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 -# define LSEEK lseek64 +#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE - 0 +#define LSEEK lseek64 #else -# define LSEEK lseek +#define LSEEK lseek #endif #endif @@ -30,540 +30,550 @@ local gzFile gz_open OF((const void *, int, const char *)); The gz_strwinerror function does not change the current setting of GetLastError. */ -char ZLIB_INTERNAL *gz_strwinerror (error) - DWORD error; +char ZLIB_INTERNAL *gz_strwinerror(error) + DWORD error; { - static char buf[1024]; + static char buf[1024]; - wchar_t *msgbuf; - DWORD lasterr = GetLastError(); - DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM - | FORMAT_MESSAGE_ALLOCATE_BUFFER, - NULL, - error, - 0, /* Default language */ - (LPVOID)&msgbuf, - 0, - NULL); - if (chars != 0) { - /* If there is an \r\n appended, zap it. */ - if (chars >= 2 - && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') { - chars -= 2; - msgbuf[chars] = 0; - } + wchar_t *msgbuf; + DWORD lasterr = GetLastError(); + DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER, + NULL, + error, + 0, /* Default language */ + (LPVOID)&msgbuf, + 0, + NULL); + if (chars != 0) + { + /* If there is an \r\n appended, zap it. */ + if (chars >= 2 && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') + { + chars -= 2; + msgbuf[chars] = 0; + } - if (chars > sizeof (buf) - 1) { - chars = sizeof (buf) - 1; - msgbuf[chars] = 0; - } + if (chars > sizeof(buf) - 1) + { + chars = sizeof(buf) - 1; + msgbuf[chars] = 0; + } - wcstombs(buf, msgbuf, chars + 1); - LocalFree(msgbuf); - } - else { - sprintf(buf, "unknown win32 error (%ld)", error); - } + wcstombs(buf, msgbuf, chars + 1); + LocalFree(msgbuf); + } + else + { + sprintf(buf, "unknown win32 error (%ld)", error); + } - SetLastError(lasterr); - return buf; + SetLastError(lasterr); + return buf; } #endif /* UNDER_CE */ /* Reset gzip file state */ local void gz_reset(state) - gz_statep state; + gz_statep state; { - state->x.have = 0; /* no output data available */ - if (state->mode == GZ_READ) { /* for reading ... */ - state->eof = 0; /* not at end of file */ - state->past = 0; /* have not read past end yet */ - state->how = LOOK; /* look for gzip header */ - } - state->seek = 0; /* no seek request pending */ - gz_error(state, Z_OK, NULL); /* clear error */ - state->x.pos = 0; /* no uncompressed data yet */ - state->strm.avail_in = 0; /* no input data yet */ + state->x.have = 0; /* no output data available */ + if (state->mode == GZ_READ) + { /* for reading ... */ + state->eof = 0; /* not at end of file */ + state->past = 0; /* have not read past end yet */ + state->how = LOOK; /* look for gzip header */ + } + state->seek = 0; /* no seek request pending */ + gz_error(state, Z_OK, NULL); /* clear error */ + state->x.pos = 0; /* no uncompressed data yet */ + state->strm.avail_in = 0; /* no input data yet */ } /* Open a gzip file either by name or file descriptor. */ local gzFile gz_open(path, fd, mode) - const void *path; - int fd; - const char *mode; + const void *path; +int fd; +const char *mode; { - gz_statep state; - size_t len; - int oflag; + gz_statep state; + size_t len; + int oflag; #ifdef O_CLOEXEC - int cloexec = 0; + int cloexec = 0; #endif #ifdef O_EXCL - int exclusive = 0; + int exclusive = 0; #endif - /* check input */ - if (path == NULL) - return NULL; + /* check input */ + if (path == NULL) + return NULL; - /* allocate gzFile structure to return */ - state = (gz_statep)malloc(sizeof(gz_state)); - if (state == NULL) - return NULL; - state->size = 0; /* no buffers allocated yet */ - state->want = GZBUFSIZE; /* requested buffer size */ - state->msg = NULL; /* no error message yet */ + /* allocate gzFile structure to return */ + state = (gz_statep)malloc(sizeof(gz_state)); + if (state == NULL) + return NULL; + state->size = 0; /* no buffers allocated yet */ + state->want = GZBUFSIZE; /* requested buffer size */ + state->msg = NULL; /* no error message yet */ - /* interpret mode */ - state->mode = GZ_NONE; - state->level = Z_DEFAULT_COMPRESSION; - state->strategy = Z_DEFAULT_STRATEGY; - state->direct = 0; - while (*mode) { - if (*mode >= '0' && *mode <= '9') - state->level = *mode - '0'; - else - switch (*mode) { - case 'r': - state->mode = GZ_READ; - break; + /* interpret mode */ + state->mode = GZ_NONE; + state->level = Z_DEFAULT_COMPRESSION; + state->strategy = Z_DEFAULT_STRATEGY; + state->direct = 0; + while (*mode) + { + if (*mode >= '0' && *mode <= '9') + state->level = *mode - '0'; + else + switch (*mode) + { + case 'r': + state->mode = GZ_READ; + break; #ifndef NO_GZCOMPRESS - case 'w': - state->mode = GZ_WRITE; - break; - case 'a': - state->mode = GZ_APPEND; - break; + case 'w': + state->mode = GZ_WRITE; + break; + case 'a': + state->mode = GZ_APPEND; + break; #endif - case '+': /* can't read and write at the same time */ - free(state); - return NULL; - case 'b': /* ignore -- will request binary anyway */ - break; + case '+': /* can't read and write at the same time */ + free(state); + return NULL; + case 'b': /* ignore -- will request binary anyway */ + break; #ifdef O_CLOEXEC - case 'e': - cloexec = 1; - break; + case 'e': + cloexec = 1; + break; #endif #ifdef O_EXCL - case 'x': - exclusive = 1; - break; + case 'x': + exclusive = 1; + break; #endif - case 'f': - state->strategy = Z_FILTERED; - break; - case 'h': - state->strategy = Z_HUFFMAN_ONLY; - break; - case 'R': - state->strategy = Z_RLE; - break; - case 'F': - state->strategy = Z_FIXED; - break; - case 'T': - state->direct = 1; - break; - default: /* could consider as an error, but just ignore */ - ; - } - mode++; - } + case 'f': + state->strategy = Z_FILTERED; + break; + case 'h': + state->strategy = Z_HUFFMAN_ONLY; + break; + case 'R': + state->strategy = Z_RLE; + break; + case 'F': + state->strategy = Z_FIXED; + break; + case 'T': + state->direct = 1; + break; + default: /* could consider as an error, but just ignore */ + ; + } + mode++; + } - /* must provide an "r", "w", or "a" */ - if (state->mode == GZ_NONE) { - free(state); - return NULL; - } + /* must provide an "r", "w", or "a" */ + if (state->mode == GZ_NONE) + { + free(state); + return NULL; + } - /* can't force transparent read */ - if (state->mode == GZ_READ) { - if (state->direct) { - free(state); - return NULL; - } - state->direct = 1; /* for empty file */ - } + /* can't force transparent read */ + if (state->mode == GZ_READ) + { + if (state->direct) + { + free(state); + return NULL; + } + state->direct = 1; /* for empty file */ + } - /* save the path name for error messages */ + /* save the path name for error messages */ #ifdef _WIN32 - if (fd == -2) { - len = wcstombs(NULL, path, 0); - if (len == (size_t)-1) - len = 0; - } - else + if (fd == -2) + { + len = wcstombs(NULL, path, 0); + if (len == (size_t)-1) + len = 0; + } + else #endif - len = strlen((const char *)path); - state->path = (char *)malloc(len + 1); - if (state->path == NULL) { - free(state); - return NULL; - } + len = strlen((const char *)path); + state->path = (char *)malloc(len + 1); + if (state->path == NULL) + { + free(state); + return NULL; + } #ifdef _WIN32 - if (fd == -2) - if (len) - wcstombs(state->path, path, len + 1); - else - *(state->path) = 0; - else + if (fd == -2) + if (len) + wcstombs(state->path, path, len + 1); + else + *(state->path) = 0; + else #endif #if !defined(NO_snprintf) && !defined(NO_vsnprintf) - snprintf(state->path, len + 1, "%s", (const char *)path); + snprintf(state->path, len + 1, "%s", (const char *)path); #else - strcpy(state->path, path); + strcpy(state->path, path); #endif - /* compute the flags for open() */ - oflag = + /* compute the flags for open() */ + oflag = #ifdef O_LARGEFILE - O_LARGEFILE | + O_LARGEFILE | #endif #ifdef O_BINARY - O_BINARY | + O_BINARY | #endif #ifdef O_CLOEXEC - (cloexec ? O_CLOEXEC : 0) | + (cloexec ? O_CLOEXEC : 0) | #endif - (state->mode == GZ_READ ? - O_RDONLY : - (O_WRONLY | O_CREAT | + (state->mode == GZ_READ ? O_RDONLY : (O_WRONLY | O_CREAT | #ifdef O_EXCL - (exclusive ? O_EXCL : 0) | + (exclusive ? O_EXCL : 0) | #endif - (state->mode == GZ_WRITE ? - O_TRUNC : - O_APPEND))); + (state->mode == GZ_WRITE ? O_TRUNC : O_APPEND))); - /* open the file with the appropriate flags (or just use fd) */ - state->fd = fd > -1 ? fd : ( + /* open the file with the appropriate flags (or just use fd) */ + state->fd = fd > -1 ? fd : ( #ifdef _WIN32 - fd == -2 ? _wopen(path, oflag, 0666) : + fd == -2 ? _wopen(path, oflag, 0666) : #endif - open((const char *)path, oflag, 0666)); - if (state->fd == -1) { - free(state->path); - free(state); - return NULL; - } - if (state->mode == GZ_APPEND) - state->mode = GZ_WRITE; /* simplify later checks */ + open((const char *)path, oflag, 0666)); + if (state->fd == -1) + { + free(state->path); + free(state); + return NULL; + } + if (state->mode == GZ_APPEND) + state->mode = GZ_WRITE; /* simplify later checks */ - /* save the current position for rewinding (only if reading) */ - if (state->mode == GZ_READ) { - state->start = LSEEK(state->fd, 0, SEEK_CUR); - if (state->start == -1) state->start = 0; - } + /* save the current position for rewinding (only if reading) */ + if (state->mode == GZ_READ) + { + state->start = LSEEK(state->fd, 0, SEEK_CUR); + if (state->start == -1) state->start = 0; + } - /* initialize stream */ - gz_reset(state); + /* initialize stream */ + gz_reset(state); - /* return stream */ - return (gzFile)state; + /* return stream */ + return (gzFile)state; } /* -- see zlib.h -- */ gzFile ZEXPORT gzopen(path, mode) - const char *path; - const char *mode; + const char *path; +const char *mode; { - return gz_open(path, -1, mode); + return gz_open(path, -1, mode); } /* -- see zlib.h -- */ gzFile ZEXPORT gzopen64(path, mode) - const char *path; - const char *mode; + const char *path; +const char *mode; { - return gz_open(path, -1, mode); + return gz_open(path, -1, mode); } /* -- see zlib.h -- */ -gzFile ZEXPORT gzdopen(fd, mode) - int fd; - const char *mode; +gzFile ZEXPORT gzdopen(fd, mode) int fd; +const char *mode; { - char *path; /* identifier for error messages */ - gzFile gz; + char *path; /* identifier for error messages */ + gzFile gz; - if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) - return NULL; + if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL) + return NULL; #if !defined(NO_snprintf) && !defined(NO_vsnprintf) - snprintf(path, 7 + 3 * sizeof(int), "", fd); /* for debugging */ + snprintf(path, 7 + 3 * sizeof(int), "", fd); /* for debugging */ #else - sprintf(path, "", fd); /* for debugging */ + sprintf(path, "", fd); /* for debugging */ #endif - gz = gz_open(path, fd, mode); - free(path); - return gz; + gz = gz_open(path, fd, mode); + free(path); + return gz; } /* -- see zlib.h -- */ #ifdef _WIN32 gzFile ZEXPORT gzopen_w(path, mode) - const wchar_t *path; - const char *mode; + const wchar_t *path; +const char *mode; { - return gz_open(path, -2, mode); + return gz_open(path, -2, mode); } #endif /* -- see zlib.h -- */ int ZEXPORT gzbuffer(file, size) - gzFile file; - unsigned size; + gzFile file; +unsigned size; { - gz_statep state; + gz_statep state; - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; - /* make sure we haven't already allocated memory */ - if (state->size != 0) - return -1; + /* make sure we haven't already allocated memory */ + if (state->size != 0) + return -1; - /* check and set requested size */ - if (size < 2) - size = 2; /* need two bytes to check magic header */ - state->want = size; - return 0; + /* check and set requested size */ + if (size < 2) + size = 2; /* need two bytes to check magic header */ + state->want = size; + return 0; } /* -- see zlib.h -- */ int ZEXPORT gzrewind(file) - gzFile file; + gzFile file; { - gz_statep state; + gz_statep state; - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; - /* check that we're reading and that there's no error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; + /* check that we're reading and that there's no error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; - /* back up and start over */ - if (LSEEK(state->fd, state->start, SEEK_SET) == -1) - return -1; - gz_reset(state); - return 0; + /* back up and start over */ + if (LSEEK(state->fd, state->start, SEEK_SET) == -1) + return -1; + gz_reset(state); + return 0; } /* -- see zlib.h -- */ z_off64_t ZEXPORT gzseek64(file, offset, whence) - gzFile file; - z_off64_t offset; - int whence; + gzFile file; +z_off64_t offset; +int whence; { - unsigned n; - z_off64_t ret; - gz_statep state; + unsigned n; + z_off64_t ret; + gz_statep state; - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; - /* check that there's no error */ - if (state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; + /* check that there's no error */ + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; - /* can only seek from start or relative to current position */ - if (whence != SEEK_SET && whence != SEEK_CUR) - return -1; + /* can only seek from start or relative to current position */ + if (whence != SEEK_SET && whence != SEEK_CUR) + return -1; - /* normalize offset to a SEEK_CUR specification */ - if (whence == SEEK_SET) - offset -= state->x.pos; - else if (state->seek) - offset += state->skip; - state->seek = 0; + /* normalize offset to a SEEK_CUR specification */ + if (whence == SEEK_SET) + offset -= state->x.pos; + else if (state->seek) + offset += state->skip; + state->seek = 0; - /* if within raw area while reading, just go there */ - if (state->mode == GZ_READ && state->how == COPY && - state->x.pos + offset >= 0) { - ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); - if (ret == -1) - return -1; - state->x.have = 0; - state->eof = 0; - state->past = 0; - state->seek = 0; - gz_error(state, Z_OK, NULL); - state->strm.avail_in = 0; - state->x.pos += offset; - return state->x.pos; - } + /* if within raw area while reading, just go there */ + if (state->mode == GZ_READ && state->how == COPY && + state->x.pos + offset >= 0) + { + ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR); + if (ret == -1) + return -1; + state->x.have = 0; + state->eof = 0; + state->past = 0; + state->seek = 0; + gz_error(state, Z_OK, NULL); + state->strm.avail_in = 0; + state->x.pos += offset; + return state->x.pos; + } - /* calculate skip amount, rewinding if needed for back seek when reading */ - if (offset < 0) { - if (state->mode != GZ_READ) /* writing -- can't go backwards */ - return -1; - offset += state->x.pos; - if (offset < 0) /* before start of file! */ - return -1; - if (gzrewind(file) == -1) /* rewind, then skip to offset */ - return -1; - } + /* calculate skip amount, rewinding if needed for back seek when reading */ + if (offset < 0) + { + if (state->mode != GZ_READ) /* writing -- can't go backwards */ + return -1; + offset += state->x.pos; + if (offset < 0) /* before start of file! */ + return -1; + if (gzrewind(file) == -1) /* rewind, then skip to offset */ + return -1; + } - /* if reading, skip what's in output buffer (one less gzgetc() check) */ - if (state->mode == GZ_READ) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? - (unsigned)offset : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - offset -= n; - } + /* if reading, skip what's in output buffer (one less gzgetc() check) */ + if (state->mode == GZ_READ) + { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ? (unsigned)offset : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + offset -= n; + } - /* request skip (if not zero) */ - if (offset) { - state->seek = 1; - state->skip = offset; - } - return state->x.pos + offset; + /* request skip (if not zero) */ + if (offset) + { + state->seek = 1; + state->skip = offset; + } + return state->x.pos + offset; } /* -- see zlib.h -- */ z_off_t ZEXPORT gzseek(file, offset, whence) - gzFile file; - z_off_t offset; - int whence; + gzFile file; +z_off_t offset; +int whence; { - z_off64_t ret; + z_off64_t ret; - ret = gzseek64(file, (z_off64_t)offset, whence); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; + ret = gzseek64(file, (z_off64_t)offset, whence); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; } /* -- see zlib.h -- */ z_off64_t ZEXPORT gztell64(file) - gzFile file; + gzFile file; { - gz_statep state; + gz_statep state; - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; - /* return position */ - return state->x.pos + (state->seek ? state->skip : 0); + /* return position */ + return state->x.pos + (state->seek ? state->skip : 0); } /* -- see zlib.h -- */ z_off_t ZEXPORT gztell(file) - gzFile file; + gzFile file; { - z_off64_t ret; + z_off64_t ret; - ret = gztell64(file); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; + ret = gztell64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; } /* -- see zlib.h -- */ z_off64_t ZEXPORT gzoffset64(file) - gzFile file; + gzFile file; { - z_off64_t offset; - gz_statep state; + z_off64_t offset; + gz_statep state; - /* get internal structure and check integrity */ - if (file == NULL) - return -1; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return -1; + /* get internal structure and check integrity */ + if (file == NULL) + return -1; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return -1; - /* compute and return effective offset in file */ - offset = LSEEK(state->fd, 0, SEEK_CUR); - if (offset == -1) - return -1; - if (state->mode == GZ_READ) /* reading */ - offset -= state->strm.avail_in; /* don't count buffered input */ - return offset; + /* compute and return effective offset in file */ + offset = LSEEK(state->fd, 0, SEEK_CUR); + if (offset == -1) + return -1; + if (state->mode == GZ_READ) /* reading */ + offset -= state->strm.avail_in; /* don't count buffered input */ + return offset; } /* -- see zlib.h -- */ z_off_t ZEXPORT gzoffset(file) - gzFile file; + gzFile file; { - z_off64_t ret; + z_off64_t ret; - ret = gzoffset64(file); - return ret == (z_off_t)ret ? (z_off_t)ret : -1; + ret = gzoffset64(file); + return ret == (z_off_t)ret ? (z_off_t)ret : -1; } /* -- see zlib.h -- */ int ZEXPORT gzeof(file) - gzFile file; + gzFile file; { - gz_statep state; + gz_statep state; - /* get internal structure and check integrity */ - if (file == NULL) - return 0; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return 0; + /* get internal structure and check integrity */ + if (file == NULL) + return 0; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return 0; - /* return end-of-file state */ - return state->mode == GZ_READ ? state->past : 0; + /* return end-of-file state */ + return state->mode == GZ_READ ? state->past : 0; } /* -- see zlib.h -- */ -const char * ZEXPORT gzerror(file, errnum) - gzFile file; - int *errnum; +const char *ZEXPORT gzerror(file, errnum) + gzFile file; +int *errnum; { - gz_statep state; + gz_statep state; - /* get internal structure and check integrity */ - if (file == NULL) - return NULL; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return NULL; + /* get internal structure and check integrity */ + if (file == NULL) + return NULL; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return NULL; - /* return error information */ - if (errnum != NULL) - *errnum = state->err; - return state->err == Z_MEM_ERROR ? "out of memory" : - (state->msg == NULL ? "" : state->msg); + /* return error information */ + if (errnum != NULL) + *errnum = state->err; + return state->err == Z_MEM_ERROR ? "out of memory" : (state->msg == NULL ? "" : state->msg); } /* -- see zlib.h -- */ void ZEXPORT gzclearerr(file) - gzFile file; + gzFile file; { - gz_statep state; + gz_statep state; - /* get internal structure and check integrity */ - if (file == NULL) - return; - state = (gz_statep)file; - if (state->mode != GZ_READ && state->mode != GZ_WRITE) - return; + /* get internal structure and check integrity */ + if (file == NULL) + return; + state = (gz_statep)file; + if (state->mode != GZ_READ && state->mode != GZ_WRITE) + return; - /* clear error and end-of-file */ - if (state->mode == GZ_READ) { - state->eof = 0; - state->past = 0; - } - gz_error(state, Z_OK, NULL); + /* clear error and end-of-file */ + if (state->mode == GZ_READ) + { + state->eof = 0; + state->past = 0; + } + gz_error(state, Z_OK, NULL); } /* Create an error message in allocated memory and set state->err and @@ -573,45 +583,47 @@ void ZEXPORT gzclearerr(file) allocation failure constructing the error message, then convert the error to out of memory. */ void ZLIB_INTERNAL gz_error(state, err, msg) - gz_statep state; - int err; - const char *msg; + gz_statep state; +int err; +const char *msg; { - /* free previously allocated message and clear */ - if (state->msg != NULL) { - if (state->err != Z_MEM_ERROR) - free(state->msg); - state->msg = NULL; - } + /* free previously allocated message and clear */ + if (state->msg != NULL) + { + if (state->err != Z_MEM_ERROR) + free(state->msg); + state->msg = NULL; + } - /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ - if (err != Z_OK && err != Z_BUF_ERROR) - state->x.have = 0; + /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */ + if (err != Z_OK && err != Z_BUF_ERROR) + state->x.have = 0; - /* set error code, and if no message, then done */ - state->err = err; - if (msg == NULL) - return; + /* set error code, and if no message, then done */ + state->err = err; + if (msg == NULL) + return; - /* for an out of memory error, return literal string when requested */ - if (err == Z_MEM_ERROR) - return; + /* for an out of memory error, return literal string when requested */ + if (err == Z_MEM_ERROR) + return; - /* construct error message with path */ - if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == - NULL) { - state->err = Z_MEM_ERROR; - return; - } + /* construct error message with path */ + if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) == + NULL) + { + state->err = Z_MEM_ERROR; + return; + } #if !defined(NO_snprintf) && !defined(NO_vsnprintf) - snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, - "%s%s%s", state->path, ": ", msg); + snprintf(state->msg, strlen(state->path) + strlen(msg) + 3, + "%s%s%s", state->path, ": ", msg); #else - strcpy(state->msg, state->path); - strcat(state->msg, ": "); - strcat(state->msg, msg); + strcpy(state->msg, state->path); + strcat(state->msg, ": "); + strcat(state->msg, msg); #endif - return; + return; } #ifndef INT_MAX @@ -621,14 +633,15 @@ void ZLIB_INTERNAL gz_error(state, err, msg) otherwise we could just use ((unsigned)-1) >> 1 */ unsigned ZLIB_INTERNAL gz_intmax() { - unsigned p, q; + unsigned p, q; - p = 1; - do { - q = p; - p <<= 1; - p++; - } while (p > q); - return q >> 1; + p = 1; + do + { + q = p; + p <<= 1; + p++; + } while (p > q); + return q >> 1; } #endif diff --git a/examples/ThirdPartyLibs/zlib/gzread.c b/examples/ThirdPartyLibs/zlib/gzread.c index bf4538eb2..36de5eb94 100644 --- a/examples/ThirdPartyLibs/zlib/gzread.c +++ b/examples/ThirdPartyLibs/zlib/gzread.c @@ -18,27 +18,29 @@ local int gz_skip OF((gz_statep, z_off64_t)); This function needs to loop on read(), since read() is not guaranteed to read the number of bytes requested, depending on the type of descriptor. */ local int gz_load(state, buf, len, have) - gz_statep state; - unsigned char *buf; - unsigned len; - unsigned *have; + gz_statep state; +unsigned char *buf; +unsigned len; +unsigned *have; { - int ret; + int ret; - *have = 0; - do { - ret = read(state->fd, buf + *have, len - *have); - if (ret <= 0) - break; - *have += ret; - } while (*have < len); - if (ret < 0) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - if (ret == 0) - state->eof = 1; - return 0; + *have = 0; + do + { + ret = read(state->fd, buf + *have, len - *have); + if (ret <= 0) + break; + *have += ret; + } while (*have < len); + if (ret < 0) + { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (ret == 0) + state->eof = 1; + return 0; } /* Load up input buffer and set eof flag if last data loaded -- return -1 on @@ -49,29 +51,32 @@ local int gz_load(state, buf, len, have) the input buffer, and then the remainder of the buffer is loaded with the available data from the input file. */ local int gz_avail(state) - gz_statep state; + gz_statep state; { - unsigned got; - z_streamp strm = &(state->strm); + unsigned got; + z_streamp strm = &(state->strm); - if (state->err != Z_OK && state->err != Z_BUF_ERROR) - return -1; - if (state->eof == 0) { - if (strm->avail_in) { /* copy what's there to the start */ - unsigned char *p = state->in; - unsigned const char *q = strm->next_in; - unsigned n = strm->avail_in; - do { - *p++ = *q++; - } while (--n); - } - if (gz_load(state, state->in + strm->avail_in, - state->size - strm->avail_in, &got) == -1) - return -1; - strm->avail_in += got; - strm->next_in = state->in; - } - return 0; + if (state->err != Z_OK && state->err != Z_BUF_ERROR) + return -1; + if (state->eof == 0) + { + if (strm->avail_in) + { /* copy what's there to the start */ + unsigned char *p = state->in; + unsigned const char *q = strm->next_in; + unsigned n = strm->avail_in; + do + { + *p++ = *q++; + } while (--n); + } + if (gz_load(state, state->in + strm->avail_in, + state->size - strm->avail_in, &got) == -1) + return -1; + strm->avail_in += got; + strm->next_in = state->in; + } + return 0; } /* Look for gzip header, set up for inflate or copy. state->x.have must be 0. @@ -84,84 +89,91 @@ local int gz_avail(state) a user buffer. If decompressing, the inflate state will be initialized. gz_look() will return 0 on success or -1 on failure. */ local int gz_look(state) - gz_statep state; + gz_statep state; { - z_streamp strm = &(state->strm); + z_streamp strm = &(state->strm); - /* allocate read buffers and inflate memory */ - if (state->size == 0) { - /* allocate buffers */ - state->in = (unsigned char *)malloc(state->want); - state->out = (unsigned char *)malloc(state->want << 1); - if (state->in == NULL || state->out == NULL) { - if (state->out != NULL) - free(state->out); - if (state->in != NULL) - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - state->size = state->want; + /* allocate read buffers and inflate memory */ + if (state->size == 0) + { + /* allocate buffers */ + state->in = (unsigned char *)malloc(state->want); + state->out = (unsigned char *)malloc(state->want << 1); + if (state->in == NULL || state->out == NULL) + { + if (state->out != NULL) + free(state->out); + if (state->in != NULL) + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + state->size = state->want; - /* allocate inflate memory */ - state->strm.zalloc = Z_NULL; - state->strm.zfree = Z_NULL; - state->strm.opaque = Z_NULL; - state->strm.avail_in = 0; - state->strm.next_in = Z_NULL; - if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) { /* gunzip */ - free(state->out); - free(state->in); - state->size = 0; - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - } + /* allocate inflate memory */ + state->strm.zalloc = Z_NULL; + state->strm.zfree = Z_NULL; + state->strm.opaque = Z_NULL; + state->strm.avail_in = 0; + state->strm.next_in = Z_NULL; + if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) + { /* gunzip */ + free(state->out); + free(state->in); + state->size = 0; + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } - /* get at least the magic bytes in the input buffer */ - if (strm->avail_in < 2) { - if (gz_avail(state) == -1) - return -1; - if (strm->avail_in == 0) - return 0; - } + /* get at least the magic bytes in the input buffer */ + if (strm->avail_in < 2) + { + if (gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + return 0; + } - /* look for gzip magic bytes -- if there, do gzip decoding (note: there is + /* look for gzip magic bytes -- if there, do gzip decoding (note: there is a logical dilemma here when considering the case of a partially written gzip file, to wit, if a single 31 byte is written, then we cannot tell whether this is a single-byte file, or just a partially written gzip file -- for here we assume that if a gzip file is being written, then the header will be written in a single operation, so that reading a single byte is sufficient indication that it is not a gzip file) */ - if (strm->avail_in > 1 && - strm->next_in[0] == 31 && strm->next_in[1] == 139) { - inflateReset(strm); - state->how = GZIP; - state->direct = 0; - return 0; - } + if (strm->avail_in > 1 && + strm->next_in[0] == 31 && strm->next_in[1] == 139) + { + inflateReset(strm); + state->how = GZIP; + state->direct = 0; + return 0; + } - /* no gzip header -- if we were decoding gzip before, then this is trailing + /* no gzip header -- if we were decoding gzip before, then this is trailing garbage. Ignore the trailing garbage and finish. */ - if (state->direct == 0) { - strm->avail_in = 0; - state->eof = 1; - state->x.have = 0; - return 0; - } + if (state->direct == 0) + { + strm->avail_in = 0; + state->eof = 1; + state->x.have = 0; + return 0; + } - /* doing raw i/o, copy any leftover input to output -- this assumes that + /* doing raw i/o, copy any leftover input to output -- this assumes that the output buffer is larger than the input buffer, which also assures space for gzungetc() */ - state->x.next = state->out; - if (strm->avail_in) { - memcpy(state->x.next, strm->next_in, strm->avail_in); - state->x.have = strm->avail_in; - strm->avail_in = 0; - } - state->how = COPY; - state->direct = 1; - return 0; + state->x.next = state->out; + if (strm->avail_in) + { + memcpy(state->x.next, strm->next_in, strm->avail_in); + state->x.have = strm->avail_in; + strm->avail_in = 0; + } + state->how = COPY; + state->direct = 1; + return 0; } /* Decompress from input to the provided next_out and avail_out in the state. @@ -170,51 +182,56 @@ local int gz_look(state) the next gzip stream or raw data, once state->x.have is depleted. Returns 0 on success, -1 on failure. */ local int gz_decomp(state) - gz_statep state; + gz_statep state; { - int ret = Z_OK; - unsigned had; - z_streamp strm = &(state->strm); + int ret = Z_OK; + unsigned had; + z_streamp strm = &(state->strm); - /* fill output buffer up to end of deflate stream */ - had = strm->avail_out; - do { - /* get more input for inflate() */ - if (strm->avail_in == 0 && gz_avail(state) == -1) - return -1; - if (strm->avail_in == 0) { - gz_error(state, Z_BUF_ERROR, "unexpected end of file"); - break; - } + /* fill output buffer up to end of deflate stream */ + had = strm->avail_out; + do + { + /* get more input for inflate() */ + if (strm->avail_in == 0 && gz_avail(state) == -1) + return -1; + if (strm->avail_in == 0) + { + gz_error(state, Z_BUF_ERROR, "unexpected end of file"); + break; + } - /* decompress and handle errors */ - ret = inflate(strm, Z_NO_FLUSH); - if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) { - gz_error(state, Z_STREAM_ERROR, - "internal error: inflate stream corrupt"); - return -1; - } - if (ret == Z_MEM_ERROR) { - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - if (ret == Z_DATA_ERROR) { /* deflate stream invalid */ - gz_error(state, Z_DATA_ERROR, - strm->msg == NULL ? "compressed data error" : strm->msg); - return -1; - } - } while (strm->avail_out && ret != Z_STREAM_END); + /* decompress and handle errors */ + ret = inflate(strm, Z_NO_FLUSH); + if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) + { + gz_error(state, Z_STREAM_ERROR, + "internal error: inflate stream corrupt"); + return -1; + } + if (ret == Z_MEM_ERROR) + { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + if (ret == Z_DATA_ERROR) + { /* deflate stream invalid */ + gz_error(state, Z_DATA_ERROR, + strm->msg == NULL ? "compressed data error" : strm->msg); + return -1; + } + } while (strm->avail_out && ret != Z_STREAM_END); - /* update available output */ - state->x.have = had - strm->avail_out; - state->x.next = strm->next_out - state->x.have; + /* update available output */ + state->x.have = had - strm->avail_out; + state->x.next = strm->next_out - state->x.have; - /* if the gzip stream completed successfully, look for another */ - if (ret == Z_STREAM_END) - state->how = LOOK; + /* if the gzip stream completed successfully, look for another */ + if (ret == Z_STREAM_END) + state->how = LOOK; - /* good decompression */ - return 0; + /* good decompression */ + return 0; } /* Fetch data and put it in the output buffer. Assumes state->x.have is 0. @@ -224,371 +241,389 @@ local int gz_decomp(state) otherwise 0. gz_fetch() will leave state->how as COPY or GZIP unless the end of the input file has been reached and all data has been processed. */ local int gz_fetch(state) - gz_statep state; + gz_statep state; { - z_streamp strm = &(state->strm); + z_streamp strm = &(state->strm); - do { - switch(state->how) { - case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ - if (gz_look(state) == -1) - return -1; - if (state->how == LOOK) - return 0; - break; - case COPY: /* -> COPY */ - if (gz_load(state, state->out, state->size << 1, &(state->x.have)) - == -1) - return -1; - state->x.next = state->out; - return 0; - case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ - strm->avail_out = state->size << 1; - strm->next_out = state->out; - if (gz_decomp(state) == -1) - return -1; - } - } while (state->x.have == 0 && (!state->eof || strm->avail_in)); - return 0; + do + { + switch (state->how) + { + case LOOK: /* -> LOOK, COPY (only if never GZIP), or GZIP */ + if (gz_look(state) == -1) + return -1; + if (state->how == LOOK) + return 0; + break; + case COPY: /* -> COPY */ + if (gz_load(state, state->out, state->size << 1, &(state->x.have)) == -1) + return -1; + state->x.next = state->out; + return 0; + case GZIP: /* -> GZIP or LOOK (if end of gzip stream) */ + strm->avail_out = state->size << 1; + strm->next_out = state->out; + if (gz_decomp(state) == -1) + return -1; + } + } while (state->x.have == 0 && (!state->eof || strm->avail_in)); + return 0; } /* Skip len uncompressed bytes of output. Return -1 on error, 0 on success. */ local int gz_skip(state, len) - gz_statep state; - z_off64_t len; + gz_statep state; +z_off64_t len; { - unsigned n; + unsigned n; - /* skip over len bytes or reach end-of-file, whichever comes first */ - while (len) - /* skip over whatever is in output buffer */ - if (state->x.have) { - n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? - (unsigned)len : state->x.have; - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - len -= n; - } + /* skip over len bytes or reach end-of-file, whichever comes first */ + while (len) + /* skip over whatever is in output buffer */ + if (state->x.have) + { + n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ? (unsigned)len : state->x.have; + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + len -= n; + } - /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && state->strm.avail_in == 0) - break; + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && state->strm.avail_in == 0) + break; - /* need more data to skip -- load up output buffer */ - else { - /* get more output, looking for header if required */ - if (gz_fetch(state) == -1) - return -1; - } - return 0; + /* need more data to skip -- load up output buffer */ + else + { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + } + return 0; } /* -- see zlib.h -- */ int ZEXPORT gzread(file, buf, len) - gzFile file; - voidp buf; - unsigned len; + gzFile file; +voidp buf; +unsigned len; { - unsigned got, n; - gz_statep state; - z_streamp strm; + unsigned got, n; + gz_statep state; + z_streamp strm; - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; - /* since an int is returned, make sure len fits in one, otherwise return + /* since an int is returned, make sure len fits in one, otherwise return with an error (this avoids the flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); - return -1; - } + if ((int)len < 0) + { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return -1; + } - /* if len is zero, avoid unnecessary operations */ - if (len == 0) - return 0; + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return -1; - } + /* process a skip request */ + if (state->seek) + { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } - /* get len bytes to buf, or less than len if at the end */ - got = 0; - do { - /* first just try copying data from the output buffer */ - if (state->x.have) { - n = state->x.have > len ? len : state->x.have; - memcpy(buf, state->x.next, n); - state->x.next += n; - state->x.have -= n; - } + /* get len bytes to buf, or less than len if at the end */ + got = 0; + do + { + /* first just try copying data from the output buffer */ + if (state->x.have) + { + n = state->x.have > len ? len : state->x.have; + memcpy(buf, state->x.next, n); + state->x.next += n; + state->x.have -= n; + } - /* output buffer empty -- return if we're at the end of the input */ - else if (state->eof && strm->avail_in == 0) { - state->past = 1; /* tried to read past end */ - break; - } + /* output buffer empty -- return if we're at the end of the input */ + else if (state->eof && strm->avail_in == 0) + { + state->past = 1; /* tried to read past end */ + break; + } - /* need output data -- for small len or new stream load up our output + /* need output data -- for small len or new stream load up our output buffer */ - else if (state->how == LOOK || len < (state->size << 1)) { - /* get more output, looking for header if required */ - if (gz_fetch(state) == -1) - return -1; - continue; /* no progress yet -- go back to copy above */ - /* the copy above assures that we will leave with space in the + else if (state->how == LOOK || len < (state->size << 1)) + { + /* get more output, looking for header if required */ + if (gz_fetch(state) == -1) + return -1; + continue; /* no progress yet -- go back to copy above */ + /* the copy above assures that we will leave with space in the output buffer, allowing at least one gzungetc() to succeed */ - } + } - /* large len -- read directly into user buffer */ - else if (state->how == COPY) { /* read directly */ - if (gz_load(state, (unsigned char *)buf, len, &n) == -1) - return -1; - } + /* large len -- read directly into user buffer */ + else if (state->how == COPY) + { /* read directly */ + if (gz_load(state, (unsigned char *)buf, len, &n) == -1) + return -1; + } - /* large len -- decompress directly into user buffer */ - else { /* state->how == GZIP */ - strm->avail_out = len; - strm->next_out = (unsigned char *)buf; - if (gz_decomp(state) == -1) - return -1; - n = state->x.have; - state->x.have = 0; - } + /* large len -- decompress directly into user buffer */ + else + { /* state->how == GZIP */ + strm->avail_out = len; + strm->next_out = (unsigned char *)buf; + if (gz_decomp(state) == -1) + return -1; + n = state->x.have; + state->x.have = 0; + } - /* update progress */ - len -= n; - buf = (char *)buf + n; - got += n; - state->x.pos += n; - } while (len); + /* update progress */ + len -= n; + buf = (char *)buf + n; + got += n; + state->x.pos += n; + } while (len); - /* return number of bytes read into user buffer (will fit in int) */ - return (int)got; + /* return number of bytes read into user buffer (will fit in int) */ + return (int)got; } /* -- see zlib.h -- */ #ifdef Z_PREFIX_SET -# undef z_gzgetc +#undef z_gzgetc #else -# undef gzgetc +#undef gzgetc #endif int ZEXPORT gzgetc(file) - gzFile file; + gzFile file; { - int ret; - unsigned char buf[1]; - gz_statep state; + int ret; + unsigned char buf[1]; + gz_statep state; - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; - /* try output buffer (no need to check for skip request) */ - if (state->x.have) { - state->x.have--; - state->x.pos++; - return *(state->x.next)++; - } + /* try output buffer (no need to check for skip request) */ + if (state->x.have) + { + state->x.have--; + state->x.pos++; + return *(state->x.next)++; + } - /* nothing there -- try gzread() */ - ret = gzread(file, buf, 1); - return ret < 1 ? -1 : buf[0]; + /* nothing there -- try gzread() */ + ret = gzread(file, buf, 1); + return ret < 1 ? -1 : buf[0]; } int ZEXPORT gzgetc_(file) + gzFile file; +{ + return gzgetc(file); +} + +/* -- see zlib.h -- */ +int ZEXPORT gzungetc(c, file) int c; gzFile file; { - return gzgetc(file); + gz_statep state; + + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return -1; + + /* process a skip request */ + if (state->seek) + { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return -1; + } + + /* can't push EOF */ + if (c < 0) + return -1; + + /* if output buffer empty, put byte at end (allows more pushing) */ + if (state->x.have == 0) + { + state->x.have = 1; + state->x.next = state->out + (state->size << 1) - 1; + state->x.next[0] = c; + state->x.pos--; + state->past = 0; + return c; + } + + /* if no room, give up (must have already done a gzungetc()) */ + if (state->x.have == (state->size << 1)) + { + gz_error(state, Z_DATA_ERROR, "out of room to push characters"); + return -1; + } + + /* slide output data if needed and insert byte before existing data */ + if (state->x.next == state->out) + { + unsigned char *src = state->out + state->x.have; + unsigned char *dest = state->out + (state->size << 1); + while (src > state->out) + *--dest = *--src; + state->x.next = dest; + } + state->x.have++; + state->x.next--; + state->x.next[0] = c; + state->x.pos--; + state->past = 0; + return c; } /* -- see zlib.h -- */ -int ZEXPORT gzungetc(c, file) - int c; - gzFile file; +char *ZEXPORT gzgets(file, buf, len) + gzFile file; +char *buf; +int len; { - gz_statep state; + unsigned left, n; + char *str; + unsigned char *eol; + gz_statep state; - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; + /* check parameters and get internal structure */ + if (file == NULL || buf == NULL || len < 1) + return NULL; + state = (gz_statep)file; - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return -1; + /* check that we're reading and that there's no (serious) error */ + if (state->mode != GZ_READ || + (state->err != Z_OK && state->err != Z_BUF_ERROR)) + return NULL; - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return -1; - } + /* process a skip request */ + if (state->seek) + { + state->seek = 0; + if (gz_skip(state, state->skip) == -1) + return NULL; + } - /* can't push EOF */ - if (c < 0) - return -1; - - /* if output buffer empty, put byte at end (allows more pushing) */ - if (state->x.have == 0) { - state->x.have = 1; - state->x.next = state->out + (state->size << 1) - 1; - state->x.next[0] = c; - state->x.pos--; - state->past = 0; - return c; - } - - /* if no room, give up (must have already done a gzungetc()) */ - if (state->x.have == (state->size << 1)) { - gz_error(state, Z_DATA_ERROR, "out of room to push characters"); - return -1; - } - - /* slide output data if needed and insert byte before existing data */ - if (state->x.next == state->out) { - unsigned char *src = state->out + state->x.have; - unsigned char *dest = state->out + (state->size << 1); - while (src > state->out) - *--dest = *--src; - state->x.next = dest; - } - state->x.have++; - state->x.next--; - state->x.next[0] = c; - state->x.pos--; - state->past = 0; - return c; -} - -/* -- see zlib.h -- */ -char * ZEXPORT gzgets(file, buf, len) - gzFile file; - char *buf; - int len; -{ - unsigned left, n; - char *str; - unsigned char *eol; - gz_statep state; - - /* check parameters and get internal structure */ - if (file == NULL || buf == NULL || len < 1) - return NULL; - state = (gz_statep)file; - - /* check that we're reading and that there's no (serious) error */ - if (state->mode != GZ_READ || - (state->err != Z_OK && state->err != Z_BUF_ERROR)) - return NULL; - - /* process a skip request */ - if (state->seek) { - state->seek = 0; - if (gz_skip(state, state->skip) == -1) - return NULL; - } - - /* copy output bytes up to new line or len - 1, whichever comes first -- + /* copy output bytes up to new line or len - 1, whichever comes first -- append a terminating zero to the string (we don't check for a zero in the contents, let the user worry about that) */ - str = buf; - left = (unsigned)len - 1; - if (left) do { - /* assure that something is in the output buffer */ - if (state->x.have == 0 && gz_fetch(state) == -1) - return NULL; /* error */ - if (state->x.have == 0) { /* end of file */ - state->past = 1; /* read past end */ - break; /* return what we have */ - } + str = buf; + left = (unsigned)len - 1; + if (left) do + { + /* assure that something is in the output buffer */ + if (state->x.have == 0 && gz_fetch(state) == -1) + return NULL; /* error */ + if (state->x.have == 0) + { /* end of file */ + state->past = 1; /* read past end */ + break; /* return what we have */ + } - /* look for end-of-line in current output buffer */ - n = state->x.have > left ? left : state->x.have; - eol = (unsigned char *)memchr(state->x.next, '\n', n); - if (eol != NULL) - n = (unsigned)(eol - state->x.next) + 1; + /* look for end-of-line in current output buffer */ + n = state->x.have > left ? left : state->x.have; + eol = (unsigned char *)memchr(state->x.next, '\n', n); + if (eol != NULL) + n = (unsigned)(eol - state->x.next) + 1; - /* copy through end-of-line, or remainder if not found */ - memcpy(buf, state->x.next, n); - state->x.have -= n; - state->x.next += n; - state->x.pos += n; - left -= n; - buf += n; - } while (left && eol == NULL); + /* copy through end-of-line, or remainder if not found */ + memcpy(buf, state->x.next, n); + state->x.have -= n; + state->x.next += n; + state->x.pos += n; + left -= n; + buf += n; + } while (left && eol == NULL); - /* return terminated string, or if nothing, end of file */ - if (buf == str) - return NULL; - buf[0] = 0; - return str; + /* return terminated string, or if nothing, end of file */ + if (buf == str) + return NULL; + buf[0] = 0; + return str; } /* -- see zlib.h -- */ int ZEXPORT gzdirect(file) - gzFile file; + gzFile file; { - gz_statep state; + gz_statep state; - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; - /* if the state is not known, but we can find out, then do so (this is + /* if the state is not known, but we can find out, then do so (this is mainly for right after a gzopen() or gzdopen()) */ - if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) - (void)gz_look(state); + if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0) + (void)gz_look(state); - /* return 1 if transparent, 0 if processing a gzip stream */ - return state->direct; + /* return 1 if transparent, 0 if processing a gzip stream */ + return state->direct; } /* -- see zlib.h -- */ int ZEXPORT gzclose_r(file) - gzFile file; + gzFile file; { - int ret, err; - gz_statep state; + int ret, err; + gz_statep state; - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; - /* check that we're reading */ - if (state->mode != GZ_READ) - return Z_STREAM_ERROR; + /* check that we're reading */ + if (state->mode != GZ_READ) + return Z_STREAM_ERROR; - /* free memory and close file */ - if (state->size) { - inflateEnd(&(state->strm)); - free(state->out); - free(state->in); - } - err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; - gz_error(state, Z_OK, NULL); - free(state->path); - ret = close(state->fd); - free(state); - return ret ? Z_ERRNO : err; + /* free memory and close file */ + if (state->size) + { + inflateEnd(&(state->strm)); + free(state->out); + free(state->in); + } + err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK; + gz_error(state, Z_OK, NULL); + free(state->path); + ret = close(state->fd); + free(state); + return ret ? Z_ERRNO : err; } diff --git a/examples/ThirdPartyLibs/zlib/gzwrite.c b/examples/ThirdPartyLibs/zlib/gzwrite.c index aa767fbf6..fd97c1636 100644 --- a/examples/ThirdPartyLibs/zlib/gzwrite.c +++ b/examples/ThirdPartyLibs/zlib/gzwrite.c @@ -13,52 +13,57 @@ local int gz_zero OF((gz_statep, z_off64_t)); /* Initialize state for writing a gzip file. Mark initialization by setting state->size to non-zero. Return -1 on failure or 0 on success. */ local int gz_init(state) - gz_statep state; + gz_statep state; { - int ret; - z_streamp strm = &(state->strm); + int ret; + z_streamp strm = &(state->strm); - /* allocate input buffer */ - state->in = (unsigned char *)malloc(state->want); - if (state->in == NULL) { - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } + /* allocate input buffer */ + state->in = (unsigned char *)malloc(state->want); + if (state->in == NULL) + { + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } - /* only need output buffer and deflate state if compressing */ - if (!state->direct) { - /* allocate output buffer */ - state->out = (unsigned char *)malloc(state->want); - if (state->out == NULL) { - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } + /* only need output buffer and deflate state if compressing */ + if (!state->direct) + { + /* allocate output buffer */ + state->out = (unsigned char *)malloc(state->want); + if (state->out == NULL) + { + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } - /* allocate deflate memory, set up for gzip compression */ - strm->zalloc = Z_NULL; - strm->zfree = Z_NULL; - strm->opaque = Z_NULL; - ret = deflateInit2(strm, state->level, Z_DEFLATED, - MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); - if (ret != Z_OK) { - free(state->out); - free(state->in); - gz_error(state, Z_MEM_ERROR, "out of memory"); - return -1; - } - } + /* allocate deflate memory, set up for gzip compression */ + strm->zalloc = Z_NULL; + strm->zfree = Z_NULL; + strm->opaque = Z_NULL; + ret = deflateInit2(strm, state->level, Z_DEFLATED, + MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy); + if (ret != Z_OK) + { + free(state->out); + free(state->in); + gz_error(state, Z_MEM_ERROR, "out of memory"); + return -1; + } + } - /* mark state as initialized */ - state->size = state->want; + /* mark state as initialized */ + state->size = state->want; - /* initialize write buffer if compressing */ - if (!state->direct) { - strm->avail_out = state->size; - strm->next_out = state->out; - state->x.next = strm->next_out; - } - return 0; + /* initialize write buffer if compressing */ + if (!state->direct) + { + strm->avail_out = state->size; + strm->next_out = state->out; + state->x.next = strm->next_out; + } + return 0; } /* Compress whatever is at avail_in and next_in and write to the output file. @@ -68,239 +73,255 @@ local int gz_init(state) is true, then simply write to the output file without compressing, and ignore flush. */ local int gz_comp(state, flush) - gz_statep state; - int flush; + gz_statep state; +int flush; { - int ret, got; - unsigned have; - z_streamp strm = &(state->strm); + int ret, got; + unsigned have; + z_streamp strm = &(state->strm); - /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) - return -1; + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return -1; - /* write directly if requested */ - if (state->direct) { - got = write(state->fd, strm->next_in, strm->avail_in); - if (got < 0 || (unsigned)got != strm->avail_in) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - strm->avail_in = 0; - return 0; - } + /* write directly if requested */ + if (state->direct) + { + got = write(state->fd, strm->next_in, strm->avail_in); + if (got < 0 || (unsigned)got != strm->avail_in) + { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + strm->avail_in = 0; + return 0; + } - /* run deflate() on provided input until it produces no more output */ - ret = Z_OK; - do { - /* write out current buffer contents if full, or if flushing, but if + /* run deflate() on provided input until it produces no more output */ + ret = Z_OK; + do + { + /* write out current buffer contents if full, or if flushing, but if doing Z_FINISH then don't write until we get to Z_STREAM_END */ - if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && - (flush != Z_FINISH || ret == Z_STREAM_END))) { - have = (unsigned)(strm->next_out - state->x.next); - if (have && ((got = write(state->fd, state->x.next, have)) < 0 || - (unsigned)got != have)) { - gz_error(state, Z_ERRNO, zstrerror()); - return -1; - } - if (strm->avail_out == 0) { - strm->avail_out = state->size; - strm->next_out = state->out; - } - state->x.next = strm->next_out; - } + if (strm->avail_out == 0 || (flush != Z_NO_FLUSH && + (flush != Z_FINISH || ret == Z_STREAM_END))) + { + have = (unsigned)(strm->next_out - state->x.next); + if (have && ((got = write(state->fd, state->x.next, have)) < 0 || + (unsigned)got != have)) + { + gz_error(state, Z_ERRNO, zstrerror()); + return -1; + } + if (strm->avail_out == 0) + { + strm->avail_out = state->size; + strm->next_out = state->out; + } + state->x.next = strm->next_out; + } - /* compress */ - have = strm->avail_out; - ret = deflate(strm, flush); - if (ret == Z_STREAM_ERROR) { - gz_error(state, Z_STREAM_ERROR, - "internal error: deflate stream corrupt"); - return -1; - } - have -= strm->avail_out; - } while (have); + /* compress */ + have = strm->avail_out; + ret = deflate(strm, flush); + if (ret == Z_STREAM_ERROR) + { + gz_error(state, Z_STREAM_ERROR, + "internal error: deflate stream corrupt"); + return -1; + } + have -= strm->avail_out; + } while (have); - /* if that completed a deflate stream, allow another to start */ - if (flush == Z_FINISH) - deflateReset(strm); + /* if that completed a deflate stream, allow another to start */ + if (flush == Z_FINISH) + deflateReset(strm); - /* all done, no errors */ - return 0; + /* all done, no errors */ + return 0; } /* Compress len zeros to output. Return -1 on error, 0 on success. */ local int gz_zero(state, len) - gz_statep state; - z_off64_t len; + gz_statep state; +z_off64_t len; { - int first; - unsigned n; - z_streamp strm = &(state->strm); + int first; + unsigned n; + z_streamp strm = &(state->strm); - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return -1; + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return -1; - /* compress len zeros (len guaranteed > 0) */ - first = 1; - while (len) { - n = GT_OFF(state->size) || (z_off64_t)state->size > len ? - (unsigned)len : state->size; - if (first) { - memset(state->in, 0, n); - first = 0; - } - strm->avail_in = n; - strm->next_in = state->in; - state->x.pos += n; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return -1; - len -= n; - } - return 0; + /* compress len zeros (len guaranteed > 0) */ + first = 1; + while (len) + { + n = GT_OFF(state->size) || (z_off64_t)state->size > len ? (unsigned)len : state->size; + if (first) + { + memset(state->in, 0, n); + first = 0; + } + strm->avail_in = n; + strm->next_in = state->in; + state->x.pos += n; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return -1; + len -= n; + } + return 0; } /* -- see zlib.h -- */ int ZEXPORT gzwrite(file, buf, len) - gzFile file; - voidpc buf; - unsigned len; + gzFile file; +voidpc buf; +unsigned len; { - unsigned put = len; - gz_statep state; - z_streamp strm; + unsigned put = len; + gz_statep state; + z_streamp strm; - /* get internal structure */ - if (file == NULL) - return 0; - state = (gz_statep)file; - strm = &(state->strm); + /* get internal structure */ + if (file == NULL) + return 0; + state = (gz_statep)file; + strm = &(state->strm); - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; - /* since an int is returned, make sure len fits in one, otherwise return + /* since an int is returned, make sure len fits in one, otherwise return with an error (this avoids the flaw in the interface) */ - if ((int)len < 0) { - gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); - return 0; - } + if ((int)len < 0) + { + gz_error(state, Z_DATA_ERROR, "requested length does not fit in int"); + return 0; + } - /* if len is zero, avoid unnecessary operations */ - if (len == 0) - return 0; + /* if len is zero, avoid unnecessary operations */ + if (len == 0) + return 0; - /* allocate memory if this is the first time through */ - if (state->size == 0 && gz_init(state) == -1) - return 0; + /* allocate memory if this is the first time through */ + if (state->size == 0 && gz_init(state) == -1) + return 0; - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return 0; - } + /* check for seek request */ + if (state->seek) + { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } - /* for small len, copy to input buffer, otherwise compress directly */ - if (len < state->size) { - /* copy to input buffer, compress when full */ - do { - unsigned have, copy; + /* for small len, copy to input buffer, otherwise compress directly */ + if (len < state->size) + { + /* copy to input buffer, compress when full */ + do + { + unsigned have, copy; - if (strm->avail_in == 0) - strm->next_in = state->in; - have = (unsigned)((strm->next_in + strm->avail_in) - state->in); - copy = state->size - have; - if (copy > len) - copy = len; - memcpy(state->in + have, buf, copy); - strm->avail_in += copy; - state->x.pos += copy; - buf = (const char *)buf + copy; - len -= copy; - if (len && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - } while (len); - } - else { - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; + if (strm->avail_in == 0) + strm->next_in = state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + copy = state->size - have; + if (copy > len) + copy = len; + memcpy(state->in + have, buf, copy); + strm->avail_in += copy; + state->x.pos += copy; + buf = (const char *)buf + copy; + len -= copy; + if (len && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } while (len); + } + else + { + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; - /* directly compress user buffer to file */ - strm->avail_in = len; - strm->next_in = (z_const Bytef *)buf; - state->x.pos += len; - if (gz_comp(state, Z_NO_FLUSH) == -1) - return 0; - } + /* directly compress user buffer to file */ + strm->avail_in = len; + strm->next_in = (z_const Bytef *)buf; + state->x.pos += len; + if (gz_comp(state, Z_NO_FLUSH) == -1) + return 0; + } - /* input was all buffered or compressed (put will fit in int) */ - return (int)put; + /* input was all buffered or compressed (put will fit in int) */ + return (int)put; } /* -- see zlib.h -- */ int ZEXPORT gzputc(file, c) - gzFile file; - int c; + gzFile file; +int c; { - unsigned have; - unsigned char buf[1]; - gz_statep state; - z_streamp strm; + unsigned have; + unsigned char buf[1]; + gz_statep state; + z_streamp strm; - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return -1; + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return -1; - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return -1; - } + /* check for seek request */ + if (state->seek) + { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } - /* try writing to input buffer for speed (state->size == 0 if buffer not + /* try writing to input buffer for speed (state->size == 0 if buffer not initialized) */ - if (state->size) { - if (strm->avail_in == 0) - strm->next_in = state->in; - have = (unsigned)((strm->next_in + strm->avail_in) - state->in); - if (have < state->size) { - state->in[have] = c; - strm->avail_in++; - state->x.pos++; - return c & 0xff; - } - } + if (state->size) + { + if (strm->avail_in == 0) + strm->next_in = state->in; + have = (unsigned)((strm->next_in + strm->avail_in) - state->in); + if (have < state->size) + { + state->in[have] = c; + strm->avail_in++; + state->x.pos++; + return c & 0xff; + } + } - /* no room in buffer or not initialized, use gz_write() */ - buf[0] = c; - if (gzwrite(file, buf, 1) != 1) - return -1; - return c & 0xff; + /* no room in buffer or not initialized, use gz_write() */ + buf[0] = c; + if (gzwrite(file, buf, 1) != 1) + return -1; + return c & 0xff; } /* -- see zlib.h -- */ int ZEXPORT gzputs(file, str) - gzFile file; - const char *str; + gzFile file; +const char *str; { - int ret; - unsigned len; + int ret; + unsigned len; - /* write string */ - len = (unsigned)strlen(str); - ret = gzwrite(file, str, len); - return ret == 0 && len != 0 ? -1 : ret; + /* write string */ + len = (unsigned)strlen(str); + ret = gzwrite(file, str, len); + return ret == 0 && len != 0 ? -1 : ret; } #if defined(STDC) || defined(Z_HAVE_STDARG_H) @@ -309,269 +330,277 @@ int ZEXPORT gzputs(file, str) /* -- see zlib.h -- */ int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va) { - int size, len; - gz_statep state; - z_streamp strm; + int size, len; + gz_statep state; + z_streamp strm; - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; - /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) - return 0; + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return 0; - } + /* check for seek request */ + if (state->seek) + { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; - /* do the printf() into the input buffer, put length in len */ - size = (int)(state->size); - state->in[size - 1] = 0; + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; #ifdef NO_vsnprintf -# ifdef HAS_vsprintf_void - (void)vsprintf((char *)(state->in), format, va); - for (len = 0; len < size; len++) - if (state->in[len] == 0) break; -# else - len = vsprintf((char *)(state->in), format, va); -# endif +#ifdef HAS_vsprintf_void + (void)vsprintf((char *)(state->in), format, va); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; #else -# ifdef HAS_vsnprintf_void - (void)vsnprintf((char *)(state->in), size, format, va); - len = strlen((char *)(state->in)); -# else - len = vsnprintf((char *)(state->in), size, format, va); -# endif + len = vsprintf((char *)(state->in), format, va); +#endif +#else +#ifdef HAS_vsnprintf_void + (void)vsnprintf((char *)(state->in), size, format, va); + len = strlen((char *)(state->in)); +#else + len = vsnprintf((char *)(state->in), size, format, va); +#endif #endif - /* check that printf() results fit in buffer */ - if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) - return 0; + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; - /* update buffer and position, defer compression until needed */ - strm->avail_in = (unsigned)len; - strm->next_in = state->in; - state->x.pos += len; - return len; + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->x.pos += len; + return len; } int ZEXPORTVA gzprintf(gzFile file, const char *format, ...) { - va_list va; - int ret; + va_list va; + int ret; - va_start(va, format); - ret = gzvprintf(file, format, va); - va_end(va); - return ret; + va_start(va, format); + ret = gzvprintf(file, format, va); + va_end(va); + return ret; } #else /* !STDC && !Z_HAVE_STDARG_H */ /* -- see zlib.h -- */ -int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) - gzFile file; - const char *format; - int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; +int ZEXPORTVA gzprintf(file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20) + gzFile file; +const char *format; +int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, + a11, a12, a13, a14, a15, a16, a17, a18, a19, a20; { - int size, len; - gz_statep state; - z_streamp strm; + int size, len; + gz_statep state; + z_streamp strm; - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; - strm = &(state->strm); + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; + strm = &(state->strm); - /* check that can really pass pointer in ints */ - if (sizeof(int) != sizeof(void *)) - return 0; + /* check that can really pass pointer in ints */ + if (sizeof(int) != sizeof(void *)) + return 0; - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return 0; + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return 0; - /* make sure we have some buffer space */ - if (state->size == 0 && gz_init(state) == -1) - return 0; + /* make sure we have some buffer space */ + if (state->size == 0 && gz_init(state) == -1) + return 0; - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return 0; - } + /* check for seek request */ + if (state->seek) + { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return 0; + } - /* consume whatever's left in the input buffer */ - if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) - return 0; + /* consume whatever's left in the input buffer */ + if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1) + return 0; - /* do the printf() into the input buffer, put length in len */ - size = (int)(state->size); - state->in[size - 1] = 0; + /* do the printf() into the input buffer, put length in len */ + size = (int)(state->size); + state->in[size - 1] = 0; #ifdef NO_snprintf -# ifdef HAS_sprintf_void - sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - for (len = 0; len < size; len++) - if (state->in[len] == 0) break; -# else - len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); -# endif +#ifdef HAS_sprintf_void + sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + for (len = 0; len < size; len++) + if (state->in[len] == 0) break; #else -# ifdef HAS_snprintf_void - snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); - len = strlen((char *)(state->in)); -# else - len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, - a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, - a19, a20); -# endif + len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); +#endif +#else +#ifdef HAS_snprintf_void + snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8, + a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20); + len = strlen((char *)(state->in)); +#else + len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, + a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, + a19, a20); +#endif #endif - /* check that printf() results fit in buffer */ - if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) - return 0; + /* check that printf() results fit in buffer */ + if (len <= 0 || len >= (int)size || state->in[size - 1] != 0) + return 0; - /* update buffer and position, defer compression until needed */ - strm->avail_in = (unsigned)len; - strm->next_in = state->in; - state->x.pos += len; - return len; + /* update buffer and position, defer compression until needed */ + strm->avail_in = (unsigned)len; + strm->next_in = state->in; + state->x.pos += len; + return len; } #endif /* -- see zlib.h -- */ int ZEXPORT gzflush(file, flush) - gzFile file; - int flush; + gzFile file; +int flush; { - gz_statep state; + gz_statep state; - /* get internal structure */ - if (file == NULL) - return -1; - state = (gz_statep)file; + /* get internal structure */ + if (file == NULL) + return -1; + state = (gz_statep)file; - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; - /* check flush parameter */ - if (flush < 0 || flush > Z_FINISH) - return Z_STREAM_ERROR; + /* check flush parameter */ + if (flush < 0 || flush > Z_FINISH) + return Z_STREAM_ERROR; - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return -1; - } + /* check for seek request */ + if (state->seek) + { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } - /* compress remaining data with requested flush */ - gz_comp(state, flush); - return state->err; + /* compress remaining data with requested flush */ + gz_comp(state, flush); + return state->err; } /* -- see zlib.h -- */ int ZEXPORT gzsetparams(file, level, strategy) - gzFile file; - int level; - int strategy; + gzFile file; +int level; +int strategy; { - gz_statep state; - z_streamp strm; + gz_statep state; + z_streamp strm; - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; - strm = &(state->strm); + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; + strm = &(state->strm); - /* check that we're writing and that there's no error */ - if (state->mode != GZ_WRITE || state->err != Z_OK) - return Z_STREAM_ERROR; + /* check that we're writing and that there's no error */ + if (state->mode != GZ_WRITE || state->err != Z_OK) + return Z_STREAM_ERROR; - /* if no change is requested, then do nothing */ - if (level == state->level && strategy == state->strategy) - return Z_OK; + /* if no change is requested, then do nothing */ + if (level == state->level && strategy == state->strategy) + return Z_OK; - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - return -1; - } + /* check for seek request */ + if (state->seek) + { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + return -1; + } - /* change compression parameters for subsequent input */ - if (state->size) { - /* flush previous input with previous parameters before changing */ - if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) - return state->err; - deflateParams(strm, level, strategy); - } - state->level = level; - state->strategy = strategy; - return Z_OK; + /* change compression parameters for subsequent input */ + if (state->size) + { + /* flush previous input with previous parameters before changing */ + if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1) + return state->err; + deflateParams(strm, level, strategy); + } + state->level = level; + state->strategy = strategy; + return Z_OK; } /* -- see zlib.h -- */ int ZEXPORT gzclose_w(file) - gzFile file; + gzFile file; { - int ret = Z_OK; - gz_statep state; + int ret = Z_OK; + gz_statep state; - /* get internal structure */ - if (file == NULL) - return Z_STREAM_ERROR; - state = (gz_statep)file; + /* get internal structure */ + if (file == NULL) + return Z_STREAM_ERROR; + state = (gz_statep)file; - /* check that we're writing */ - if (state->mode != GZ_WRITE) - return Z_STREAM_ERROR; + /* check that we're writing */ + if (state->mode != GZ_WRITE) + return Z_STREAM_ERROR; - /* check for seek request */ - if (state->seek) { - state->seek = 0; - if (gz_zero(state, state->skip) == -1) - ret = state->err; - } + /* check for seek request */ + if (state->seek) + { + state->seek = 0; + if (gz_zero(state, state->skip) == -1) + ret = state->err; + } - /* flush, free memory, and close file */ - if (gz_comp(state, Z_FINISH) == -1) - ret = state->err; - if (state->size) { - if (!state->direct) { - (void)deflateEnd(&(state->strm)); - free(state->out); - } - free(state->in); - } - gz_error(state, Z_OK, NULL); - free(state->path); - if (close(state->fd) == -1) - ret = Z_ERRNO; - free(state); - return ret; + /* flush, free memory, and close file */ + if (gz_comp(state, Z_FINISH) == -1) + ret = state->err; + if (state->size) + { + if (!state->direct) + { + (void)deflateEnd(&(state->strm)); + free(state->out); + } + free(state->in); + } + gz_error(state, Z_OK, NULL); + free(state->path); + if (close(state->fd) == -1) + ret = Z_ERRNO; + free(state); + return ret; } diff --git a/examples/ThirdPartyLibs/zlib/infback.c b/examples/ThirdPartyLibs/zlib/infback.c index f3833c2e4..d4bbf9626 100644 --- a/examples/ThirdPartyLibs/zlib/infback.c +++ b/examples/ThirdPartyLibs/zlib/infback.c @@ -16,7 +16,7 @@ #include "inffast.h" /* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); +local void fixedtables OF((struct inflate_state FAR * state)); /* strm provides memory allocation functions in zalloc and zfree, or @@ -26,47 +26,48 @@ local void fixedtables OF((struct inflate_state FAR *state)); window and output buffer that is 2**windowBits bytes. */ int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size) -z_streamp strm; + z_streamp strm; int windowBits; unsigned char FAR *window; const char *version; int stream_size; { - struct inflate_state FAR *state; + struct inflate_state FAR *state; - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL || window == Z_NULL || - windowBits < 8 || windowBits > 15) - return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL || window == Z_NULL || + windowBits < 8 || windowBits > 15) + return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) + { #ifdef Z_SOLO - return Z_STREAM_ERROR; + return Z_STREAM_ERROR; #else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; #endif - } - if (strm->zfree == (free_func)0) + } + if (strm->zfree == (free_func)0) #ifdef Z_SOLO - return Z_STREAM_ERROR; + return Z_STREAM_ERROR; #else - strm->zfree = zcfree; + strm->zfree = zcfree; #endif - state = (struct inflate_state FAR *)ZALLOC(strm, 1, - sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->dmax = 32768U; - state->wbits = windowBits; - state->wsize = 1U << windowBits; - state->window = window; - state->wnext = 0; - state->whave = 0; - return Z_OK; + state = (struct inflate_state FAR *)ZALLOC(strm, 1, + sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->dmax = 32768U; + state->wbits = windowBits; + state->wsize = 1U << windowBits; + state->window = window; + state->wnext = 0; + state->whave = 0; + return Z_OK; } /* @@ -79,146 +80,159 @@ int stream_size; used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */ -local void fixedtables(state) -struct inflate_state FAR *state; +local void fixedtables(state) struct inflate_state FAR *state; { #ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) + { + unsigned sym, bits; + static code *next; - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - /* do this just once */ - virgin = 0; - } + /* do this just once */ + virgin = 0; + } #else /* !BUILDFIXED */ -# include "inffixed.h" +#include "inffixed.h" #endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; } /* Macros for inflateBack(): */ /* Load returned state from inflate_fast() */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) +#define LOAD() \ + do \ + { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) /* Set state from registers for inflate_fast() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) +#define RESTORE() \ + do \ + { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) /* Clear the input bit accumulator */ #define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) + do \ + { \ + hold = 0; \ + bits = 0; \ + } while (0) /* Assure that some input is available. If input is requested, but denied, then return a Z_BUF_ERROR from inflateBack(). */ -#define PULL() \ - do { \ - if (have == 0) { \ - have = in(in_desc, &next); \ - if (have == 0) { \ - next = Z_NULL; \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) +#define PULL() \ + do \ + { \ + if (have == 0) \ + { \ + have = in(in_desc, &next); \ + if (have == 0) \ + { \ + next = Z_NULL; \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) /* Get a byte of input into the bit accumulator, or return from inflateBack() with an error if there is no input available. */ -#define PULLBYTE() \ - do { \ - PULL(); \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) +#define PULLBYTE() \ + do \ + { \ + PULL(); \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) /* Assure that there are at least n bits in the bit accumulator. If there is not enough available input to do that, then return from inflateBack() with an error. */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) +#define NEEDBITS(n) \ + do \ + { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) /* Return the low n bits of the bit accumulator (n < 16) */ #define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) + ((unsigned)hold & ((1U << (n)) - 1)) /* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) +#define DROPBITS(n) \ + do \ + { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) /* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) +#define BYTEBITS() \ + do \ + { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) /* Assure that some output space is available, by writing out the window if it's full. If the write fails, return from inflateBack() with a Z_BUF_ERROR. */ -#define ROOM() \ - do { \ - if (left == 0) { \ - put = state->window; \ - left = state->wsize; \ - state->whave = left; \ - if (out(out_desc, put, left)) { \ - ret = Z_BUF_ERROR; \ - goto inf_leave; \ - } \ - } \ - } while (0) +#define ROOM() \ + do \ + { \ + if (left == 0) \ + { \ + put = state->window; \ + left = state->wsize; \ + state->whave = left; \ + if (out(out_desc, put, left)) \ + { \ + ret = Z_BUF_ERROR; \ + goto inf_leave; \ + } \ + } \ + } while (0) /* strm provides the memory allocation functions and window buffer on input, @@ -248,393 +262,429 @@ struct inflate_state FAR *state; are not correct, i.e. strm is Z_NULL or the state was not initialized. */ int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc) -z_streamp strm; + z_streamp strm; in_func in; void FAR *in_desc; out_func out; void FAR *out_desc; { - struct inflate_state FAR *state; - z_const unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + struct inflate_state FAR *state; + z_const unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - /* Check that the strm exists and that the state was initialized */ - if (strm == Z_NULL || strm->state == Z_NULL) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; + /* Check that the strm exists and that the state was initialized */ + if (strm == Z_NULL || strm->state == Z_NULL) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; - /* Reset the state */ - strm->msg = Z_NULL; - state->mode = TYPE; - state->last = 0; - state->whave = 0; - next = strm->next_in; - have = next != Z_NULL ? strm->avail_in : 0; - hold = 0; - bits = 0; - put = state->window; - left = state->wsize; + /* Reset the state */ + strm->msg = Z_NULL; + state->mode = TYPE; + state->last = 0; + state->whave = 0; + next = strm->next_in; + have = next != Z_NULL ? strm->avail_in : 0; + hold = 0; + bits = 0; + put = state->window; + left = state->wsize; - /* Inflate until end of block marked as last */ - for (;;) - switch (state->mode) { - case TYPE: - /* determine and dispatch block type */ - if (state->last) { - BYTEBITS(); - state->mode = DONE; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN; /* decode codes */ - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; + /* Inflate until end of block marked as last */ + for (;;) + switch (state->mode) + { + case TYPE: + /* determine and dispatch block type */ + if (state->last) + { + BYTEBITS(); + state->mode = DONE; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) + { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN; /* decode codes */ + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; - case STORED: - /* get and verify stored block length */ - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); + case STORED: + /* get and verify stored block length */ + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) + { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); - /* copy stored block from input to output */ - while (state->length != 0) { - copy = state->length; - PULL(); - ROOM(); - if (copy > have) copy = have; - if (copy > left) copy = left; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; + /* copy stored block from input to output */ + while (state->length != 0) + { + copy = state->length; + PULL(); + ROOM(); + if (copy > have) copy = have; + if (copy > left) copy = left; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; - case TABLE: - /* get dynamic table entries descriptor */ - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); + case TABLE: + /* get dynamic table entries descriptor */ + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); #ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } + if (state->nlen > 286 || state->ndist > 30) + { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } #endif - Tracev((stderr, "inflate: table sizes ok\n")); + Tracev((stderr, "inflate: table sizes ok\n")); - /* get code length code lengths (not a typo) */ - state->have = 0; - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); + /* get code length code lengths (not a typo) */ + state->have = 0; + while (state->have < state->ncode) + { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) + { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); - /* get length and distance code code lengths */ - state->have = 0; - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = (unsigned)(state->lens[state->have - 1]); - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } + /* get length and distance code code lengths */ + state->have = 0; + while (state->have < state->nlen + state->ndist) + { + for (;;) + { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) + { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else + { + if (here.val == 16) + { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) + { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = (unsigned)(state->lens[state->have - 1]); + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) + { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else + { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) + { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } - /* handle error breaks in while */ - if (state->mode == BAD) break; + /* handle error breaks in while */ + if (state->mode == BAD) break; - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) + { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } - /* build code tables -- note: do not change the lenbits or distbits + /* build code tables -- note: do not change the lenbits or distbits values here (9 and 6) without reading the comments in inftrees.h concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN; + state->next = state->codes; + state->lencode = (code const FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) + { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (code const FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) + { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN; - case LEN: - /* use inflate_fast() if we have enough input and output */ - if (have >= 6 && left >= 258) { - RESTORE(); - if (state->whave < state->wsize) - state->whave = state->wsize - left; - inflate_fast(strm, state->wsize); - LOAD(); - break; - } + case LEN: + /* use inflate_fast() if we have enough input and output */ + if (have >= 6 && left >= 258) + { + RESTORE(); + if (state->whave < state->wsize) + state->whave = state->wsize - left; + inflate_fast(strm, state->wsize); + LOAD(); + break; + } - /* get a literal, length, or end-of-block code */ - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - state->length = (unsigned)here.val; + /* get a literal, length, or end-of-block code */ + for (;;) + { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) + { + last = here; + for (;;) + { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + state->length = (unsigned)here.val; - /* process literal */ - if (here.op == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - ROOM(); - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - } + /* process literal */ + if (here.op == 0) + { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", here.val)); + ROOM(); + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + } - /* process end of block */ - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } + /* process end of block */ + if (here.op & 32) + { + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } - /* invalid code */ - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } + /* invalid code */ + if (here.op & 64) + { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } - /* length code -- get extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - } - Tracevv((stderr, "inflate: length %u\n", state->length)); + /* length code -- get extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) + { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + } + Tracevv((stderr, "inflate: length %u\n", state->length)); - /* get distance code */ - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - } - DROPBITS(here.bits); - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; + /* get distance code */ + for (;;) + { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) + { + last = here; + for (;;) + { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + } + DROPBITS(here.bits); + if (here.op & 64) + { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; - /* get distance extra bits, if any */ - state->extra = (unsigned)(here.op) & 15; - if (state->extra != 0) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - } - if (state->offset > state->wsize - (state->whave < state->wsize ? - left : 0)) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } - Tracevv((stderr, "inflate: distance %u\n", state->offset)); + /* get distance extra bits, if any */ + state->extra = (unsigned)(here.op) & 15; + if (state->extra != 0) + { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + } + if (state->offset > state->wsize - (state->whave < state->wsize ? left : 0)) + { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); - /* copy match from window to output */ - do { - ROOM(); - copy = state->wsize - state->offset; - if (copy < left) { - from = put + copy; - copy = left - copy; - } - else { - from = put - state->offset; - copy = left; - } - if (copy > state->length) copy = state->length; - state->length -= copy; - left -= copy; - do { - *put++ = *from++; - } while (--copy); - } while (state->length != 0); - break; + /* copy match from window to output */ + do + { + ROOM(); + copy = state->wsize - state->offset; + if (copy < left) + { + from = put + copy; + copy = left - copy; + } + else + { + from = put - state->offset; + copy = left; + } + if (copy > state->length) copy = state->length; + state->length -= copy; + left -= copy; + do + { + *put++ = *from++; + } while (--copy); + } while (state->length != 0); + break; - case DONE: - /* inflate stream terminated properly -- write leftover output */ - ret = Z_STREAM_END; - if (left < state->wsize) { - if (out(out_desc, state->window, state->wsize - left)) - ret = Z_BUF_ERROR; - } - goto inf_leave; + case DONE: + /* inflate stream terminated properly -- write leftover output */ + ret = Z_STREAM_END; + if (left < state->wsize) + { + if (out(out_desc, state->window, state->wsize - left)) + ret = Z_BUF_ERROR; + } + goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; - default: /* can't happen, but makes compilers happy */ - ret = Z_STREAM_ERROR; - goto inf_leave; - } + default: /* can't happen, but makes compilers happy */ + ret = Z_STREAM_ERROR; + goto inf_leave; + } - /* Return unused input */ - inf_leave: - strm->next_in = next; - strm->avail_in = have; - return ret; + /* Return unused input */ +inf_leave: + strm->next_in = next; + strm->avail_in = have; + return ret; } int ZEXPORT inflateBackEnd(strm) -z_streamp strm; + z_streamp strm; { - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; } diff --git a/examples/ThirdPartyLibs/zlib/inffast.c b/examples/ThirdPartyLibs/zlib/inffast.c index bda59ceb6..3d0a8826f 100644 --- a/examples/ThirdPartyLibs/zlib/inffast.c +++ b/examples/ThirdPartyLibs/zlib/inffast.c @@ -22,11 +22,11 @@ - M68060 (Nikl) */ #ifdef POSTINC -# define OFF 0 -# define PUP(a) *(a)++ +#define OFF 0 +#define PUP(a) *(a)++ #else -# define OFF 1 -# define PUP(a) *++(a) +#define OFF 1 +#define PUP(a) *++(a) #endif /* @@ -65,262 +65,299 @@ output space. */ void ZLIB_INTERNAL inflate_fast(strm, start) -z_streamp strm; -unsigned start; /* inflate()'s starting value for strm->avail_out */ + z_streamp strm; +unsigned start; /* inflate()'s starting value for strm->avail_out */ { - struct inflate_state FAR *state; - z_const unsigned char FAR *in; /* local strm->next_in */ - z_const unsigned char FAR *last; /* have enough input while in < last */ - unsigned char FAR *out; /* local strm->next_out */ - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ - unsigned char FAR *end; /* while out < end, enough space available */ + struct inflate_state FAR *state; + z_const unsigned char FAR *in; /* local strm->next_in */ + z_const unsigned char FAR *last; /* have enough input while in < last */ + unsigned char FAR *out; /* local strm->next_out */ + unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ + unsigned char FAR *end; /* while out < end, enough space available */ #ifdef INFLATE_STRICT - unsigned dmax; /* maximum distance from zlib header */ + unsigned dmax; /* maximum distance from zlib header */ #endif - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ - unsigned long hold; /* local strm->hold */ - unsigned bits; /* local strm->bits */ - code const FAR *lcode; /* local strm->lencode */ - code const FAR *dcode; /* local strm->distcode */ - unsigned lmask; /* mask for first level of length codes */ - unsigned dmask; /* mask for first level of distance codes */ - code here; /* retrieved table entry */ - unsigned op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - unsigned len; /* match length, unused bytes */ - unsigned dist; /* match distance */ - unsigned char FAR *from; /* where to copy match from */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ + unsigned long hold; /* local strm->hold */ + unsigned bits; /* local strm->bits */ + code const FAR *lcode; /* local strm->lencode */ + code const FAR *dcode; /* local strm->distcode */ + unsigned lmask; /* mask for first level of length codes */ + unsigned dmask; /* mask for first level of distance codes */ + code here; /* retrieved table entry */ + unsigned op; /* code bits, operation, extra bits, or */ + /* window position, window bytes to copy */ + unsigned len; /* match length, unused bytes */ + unsigned dist; /* match distance */ + unsigned char FAR *from; /* where to copy match from */ - /* copy state to local variables */ - state = (struct inflate_state FAR *)strm->state; - in = strm->next_in - OFF; - last = in + (strm->avail_in - 5); - out = strm->next_out - OFF; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); + /* copy state to local variables */ + state = (struct inflate_state FAR *)strm->state; + in = strm->next_in - OFF; + last = in + (strm->avail_in - 5); + out = strm->next_out - OFF; + beg = out - (start - strm->avail_out); + end = out + (strm->avail_out - 257); #ifdef INFLATE_STRICT - dmax = state->dmax; + dmax = state->dmax; #endif - wsize = state->wsize; - whave = state->whave; - wnext = state->wnext; - window = state->window; - hold = state->hold; - bits = state->bits; - lcode = state->lencode; - dcode = state->distcode; - lmask = (1U << state->lenbits) - 1; - dmask = (1U << state->distbits) - 1; + wsize = state->wsize; + whave = state->whave; + wnext = state->wnext; + window = state->window; + hold = state->hold; + bits = state->bits; + lcode = state->lencode; + dcode = state->distcode; + lmask = (1U << state->lenbits) - 1; + dmask = (1U << state->distbits) - 1; - /* decode literals and length/distances until end-of-block or not enough + /* decode literals and length/distances until end-of-block or not enough input data or output space */ - do { - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - here = lcode[hold & lmask]; - dolen: - op = (unsigned)(here.bits); - hold >>= op; - bits -= op; - op = (unsigned)(here.op); - if (op == 0) { /* literal */ - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - PUP(out) = (unsigned char)(here.val); - } - else if (op & 16) { /* length base */ - len = (unsigned)(here.val); - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - len += (unsigned)hold & ((1U << op) - 1); - hold >>= op; - bits -= op; - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - here = dcode[hold & dmask]; - dodist: - op = (unsigned)(here.bits); - hold >>= op; - bits -= op; - op = (unsigned)(here.op); - if (op & 16) { /* distance base */ - dist = (unsigned)(here.val); - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - } - dist += (unsigned)hold & ((1U << op) - 1); + do + { + if (bits < 15) + { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + here = lcode[hold & lmask]; + dolen: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op == 0) + { /* literal */ + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", here.val)); + PUP(out) = (unsigned char)(here.val); + } + else if (op & 16) + { /* length base */ + len = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (op) + { + if (bits < op) + { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + len += (unsigned)hold & ((1U << op) - 1); + hold >>= op; + bits -= op; + } + Tracevv((stderr, "inflate: length %u\n", len)); + if (bits < 15) + { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + here = dcode[hold & dmask]; + dodist: + op = (unsigned)(here.bits); + hold >>= op; + bits -= op; + op = (unsigned)(here.op); + if (op & 16) + { /* distance base */ + dist = (unsigned)(here.val); + op &= 15; /* number of extra bits */ + if (bits < op) + { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + if (bits < op) + { + hold += (unsigned long)(PUP(in)) << bits; + bits += 8; + } + } + dist += (unsigned)hold & ((1U << op) - 1); #ifdef INFLATE_STRICT - if (dist > dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } + if (dist > dmax) + { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } #endif - hold >>= op; - bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); - op = (unsigned)(out - beg); /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state->sane) { - strm->msg = - (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } + hold >>= op; + bits -= op; + Tracevv((stderr, "inflate: distance %u\n", dist)); + op = (unsigned)(out - beg); /* max distance in output */ + if (dist > op) + { /* see if copy from window */ + op = dist - op; /* distance back in window */ + if (op > whave) + { + if (state->sane) + { + strm->msg = + (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - if (len <= op - whave) { - do { - PUP(out) = 0; - } while (--len); - continue; - } - len -= op - whave; - do { - PUP(out) = 0; - } while (--op > whave); - if (op == 0) { - from = out - dist; - do { - PUP(out) = PUP(from); - } while (--len); - continue; - } + if (len <= op - whave) + { + do + { + PUP(out) = 0; + } while (--len); + continue; + } + len -= op - whave; + do + { + PUP(out) = 0; + } while (--op > whave); + if (op == 0) + { + from = out - dist; + do + { + PUP(out) = PUP(from); + } while (--len); + continue; + } #endif - } - from = window - OFF; - if (wnext == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = window - OFF; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - else { - from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } while (len > 2); - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - } - else if ((op & 64) == 0) { /* 2nd level distance code */ - here = dcode[here.val + (hold & ((1U << op) - 1))]; - goto dodist; - } - else { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - } - else if ((op & 64) == 0) { /* 2nd level length code */ - here = lcode[here.val + (hold & ((1U << op) - 1))]; - goto dolen; - } - else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - else { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - } while (in < last && out < end); + } + from = window - OFF; + if (wnext == 0) + { /* very common case */ + from += wsize - op; + if (op < len) + { /* some from window */ + len -= op; + do + { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + else if (wnext < op) + { /* wrap around window */ + from += wsize + wnext - op; + op -= wnext; + if (op < len) + { /* some from end of window */ + len -= op; + do + { + PUP(out) = PUP(from); + } while (--op); + from = window - OFF; + if (wnext < len) + { /* some from start of window */ + op = wnext; + len -= op; + do + { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + } + else + { /* contiguous in window */ + from += wnext - op; + if (op < len) + { /* some from window */ + len -= op; + do + { + PUP(out) = PUP(from); + } while (--op); + from = out - dist; /* rest from output */ + } + } + while (len > 2) + { + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } + if (len) + { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + else + { + from = out - dist; /* copy direct from output */ + do + { /* minimum length is three */ + PUP(out) = PUP(from); + PUP(out) = PUP(from); + PUP(out) = PUP(from); + len -= 3; + } while (len > 2); + if (len) + { + PUP(out) = PUP(from); + if (len > 1) + PUP(out) = PUP(from); + } + } + } + else if ((op & 64) == 0) + { /* 2nd level distance code */ + here = dcode[here.val + (hold & ((1U << op) - 1))]; + goto dodist; + } + else + { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + } + else if ((op & 64) == 0) + { /* 2nd level length code */ + here = lcode[here.val + (hold & ((1U << op) - 1))]; + goto dolen; + } + else if (op & 32) + { /* end-of-block */ + Tracevv((stderr, "inflate: end of block\n")); + state->mode = TYPE; + break; + } + else + { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + } while (in < last && out < end); - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - in -= len; - bits -= len << 3; - hold &= (1U << bits) - 1; + /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ + len = bits >> 3; + in -= len; + bits -= len << 3; + hold &= (1U << bits) - 1; - /* update state and return */ - strm->next_in = in + OFF; - strm->next_out = out + OFF; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? - 257 + (end - out) : 257 - (out - end)); - state->hold = hold; - state->bits = bits; - return; + /* update state and return */ + strm->next_in = in + OFF; + strm->next_out = out + OFF; + strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); + strm->avail_out = (unsigned)(out < end ? 257 + (end - out) : 257 - (out - end)); + state->hold = hold; + state->bits = bits; + return; } /* diff --git a/examples/ThirdPartyLibs/zlib/inffixed.h b/examples/ThirdPartyLibs/zlib/inffixed.h index d62832776..1684e54eb 100644 --- a/examples/ThirdPartyLibs/zlib/inffixed.h +++ b/examples/ThirdPartyLibs/zlib/inffixed.h @@ -1,94 +1,14 @@ - /* inffixed.h -- table for decoding fixed codes +/* inffixed.h -- table for decoding fixed codes * Generated automatically by makefixed(). */ - /* WARNING: this file should *not* be used by applications. +/* WARNING: this file should *not* be used by applications. It is part of the implementation of this library and is subject to change. Applications should only use zlib.h. */ - static const code lenfix[512] = { - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, - {0,9,255} - }; +static const code lenfix[512] = { + {96, 7, 0}, {0, 8, 80}, {0, 8, 16}, {20, 8, 115}, {18, 7, 31}, {0, 8, 112}, {0, 8, 48}, {0, 9, 192}, {16, 7, 10}, {0, 8, 96}, {0, 8, 32}, {0, 9, 160}, {0, 8, 0}, {0, 8, 128}, {0, 8, 64}, {0, 9, 224}, {16, 7, 6}, {0, 8, 88}, {0, 8, 24}, {0, 9, 144}, {19, 7, 59}, {0, 8, 120}, {0, 8, 56}, {0, 9, 208}, {17, 7, 17}, {0, 8, 104}, {0, 8, 40}, {0, 9, 176}, {0, 8, 8}, {0, 8, 136}, {0, 8, 72}, {0, 9, 240}, {16, 7, 4}, {0, 8, 84}, {0, 8, 20}, {21, 8, 227}, {19, 7, 43}, {0, 8, 116}, {0, 8, 52}, {0, 9, 200}, {17, 7, 13}, {0, 8, 100}, {0, 8, 36}, {0, 9, 168}, {0, 8, 4}, {0, 8, 132}, {0, 8, 68}, {0, 9, 232}, {16, 7, 8}, {0, 8, 92}, {0, 8, 28}, {0, 9, 152}, {20, 7, 83}, {0, 8, 124}, {0, 8, 60}, {0, 9, 216}, {18, 7, 23}, {0, 8, 108}, {0, 8, 44}, {0, 9, 184}, {0, 8, 12}, {0, 8, 140}, {0, 8, 76}, {0, 9, 248}, {16, 7, 3}, {0, 8, 82}, {0, 8, 18}, {21, 8, 163}, {19, 7, 35}, {0, 8, 114}, {0, 8, 50}, {0, 9, 196}, {17, 7, 11}, {0, 8, 98}, {0, 8, 34}, {0, 9, 164}, {0, 8, 2}, {0, 8, 130}, {0, 8, 66}, {0, 9, 228}, {16, 7, 7}, {0, 8, 90}, {0, 8, 26}, {0, 9, 148}, {20, 7, 67}, {0, 8, 122}, {0, 8, 58}, {0, 9, 212}, {18, 7, 19}, {0, 8, 106}, {0, 8, 42}, {0, 9, 180}, {0, 8, 10}, {0, 8, 138}, {0, 8, 74}, {0, 9, 244}, {16, 7, 5}, {0, 8, 86}, {0, 8, 22}, {64, 8, 0}, {19, 7, 51}, {0, 8, 118}, {0, 8, 54}, {0, 9, 204}, {17, 7, 15}, {0, 8, 102}, {0, 8, 38}, {0, 9, 172}, {0, 8, 6}, {0, 8, 134}, {0, 8, 70}, {0, 9, 236}, {16, 7, 9}, {0, 8, 94}, {0, 8, 30}, {0, 9, 156}, {20, 7, 99}, {0, 8, 126}, {0, 8, 62}, {0, 9, 220}, {18, 7, 27}, {0, 8, 110}, {0, 8, 46}, {0, 9, 188}, {0, 8, 14}, {0, 8, 142}, {0, 8, 78}, {0, 9, 252}, {96, 7, 0}, {0, 8, 81}, {0, 8, 17}, {21, 8, 131}, {18, 7, 31}, {0, 8, 113}, {0, 8, 49}, {0, 9, 194}, {16, 7, 10}, {0, 8, 97}, {0, 8, 33}, {0, 9, 162}, {0, 8, 1}, {0, 8, 129}, {0, 8, 65}, {0, 9, 226}, {16, 7, 6}, {0, 8, 89}, {0, 8, 25}, {0, 9, 146}, {19, 7, 59}, {0, 8, 121}, {0, 8, 57}, {0, 9, 210}, {17, 7, 17}, {0, 8, 105}, {0, 8, 41}, {0, 9, 178}, {0, 8, 9}, {0, 8, 137}, {0, 8, 73}, {0, 9, 242}, {16, 7, 4}, {0, 8, 85}, {0, 8, 21}, {16, 8, 258}, {19, 7, 43}, {0, 8, 117}, {0, 8, 53}, {0, 9, 202}, {17, 7, 13}, {0, 8, 101}, {0, 8, 37}, {0, 9, 170}, {0, 8, 5}, {0, 8, 133}, {0, 8, 69}, {0, 9, 234}, {16, 7, 8}, {0, 8, 93}, {0, 8, 29}, {0, 9, 154}, {20, 7, 83}, {0, 8, 125}, {0, 8, 61}, {0, 9, 218}, {18, 7, 23}, {0, 8, 109}, {0, 8, 45}, {0, 9, 186}, {0, 8, 13}, {0, 8, 141}, {0, 8, 77}, {0, 9, 250}, {16, 7, 3}, {0, 8, 83}, {0, 8, 19}, {21, 8, 195}, {19, 7, 35}, {0, 8, 115}, {0, 8, 51}, {0, 9, 198}, {17, 7, 11}, {0, 8, 99}, {0, 8, 35}, {0, 9, 166}, {0, 8, 3}, {0, 8, 131}, {0, 8, 67}, {0, 9, 230}, {16, 7, 7}, {0, 8, 91}, {0, 8, 27}, {0, 9, 150}, {20, 7, 67}, {0, 8, 123}, {0, 8, 59}, {0, 9, 214}, {18, 7, 19}, {0, 8, 107}, {0, 8, 43}, {0, 9, 182}, {0, 8, 11}, {0, 8, 139}, {0, 8, 75}, {0, 9, 246}, {16, 7, 5}, {0, 8, 87}, {0, 8, 23}, {64, 8, 0}, {19, 7, 51}, {0, 8, 119}, {0, 8, 55}, {0, 9, 206}, {17, 7, 15}, {0, 8, 103}, {0, 8, 39}, {0, 9, 174}, {0, 8, 7}, {0, 8, 135}, {0, 8, 71}, {0, 9, 238}, {16, 7, 9}, {0, 8, 95}, {0, 8, 31}, {0, 9, 158}, {20, 7, 99}, {0, 8, 127}, {0, 8, 63}, {0, 9, 222}, {18, 7, 27}, {0, 8, 111}, {0, 8, 47}, {0, 9, 190}, {0, 8, 15}, {0, 8, 143}, {0, 8, 79}, {0, 9, 254}, {96, 7, 0}, {0, 8, 80}, {0, 8, 16}, {20, 8, 115}, {18, 7, 31}, {0, 8, 112}, {0, 8, 48}, {0, 9, 193}, {16, 7, 10}, {0, 8, 96}, {0, 8, 32}, {0, 9, 161}, {0, 8, 0}, {0, 8, 128}, {0, 8, 64}, {0, 9, 225}, {16, 7, 6}, {0, 8, 88}, {0, 8, 24}, {0, 9, 145}, {19, 7, 59}, {0, 8, 120}, {0, 8, 56}, {0, 9, 209}, {17, 7, 17}, {0, 8, 104}, {0, 8, 40}, {0, 9, 177}, {0, 8, 8}, {0, 8, 136}, {0, 8, 72}, {0, 9, 241}, {16, 7, 4}, {0, 8, 84}, {0, 8, 20}, {21, 8, 227}, {19, 7, 43}, {0, 8, 116}, {0, 8, 52}, {0, 9, 201}, {17, 7, 13}, {0, 8, 100}, {0, 8, 36}, {0, 9, 169}, {0, 8, 4}, {0, 8, 132}, {0, 8, 68}, {0, 9, 233}, {16, 7, 8}, {0, 8, 92}, {0, 8, 28}, {0, 9, 153}, {20, 7, 83}, {0, 8, 124}, {0, 8, 60}, {0, 9, 217}, {18, 7, 23}, {0, 8, 108}, {0, 8, 44}, {0, 9, 185}, {0, 8, 12}, {0, 8, 140}, {0, 8, 76}, {0, 9, 249}, {16, 7, 3}, {0, 8, 82}, {0, 8, 18}, {21, 8, 163}, {19, 7, 35}, {0, 8, 114}, {0, 8, 50}, {0, 9, 197}, {17, 7, 11}, {0, 8, 98}, {0, 8, 34}, {0, 9, 165}, {0, 8, 2}, {0, 8, 130}, {0, 8, 66}, {0, 9, 229}, {16, 7, 7}, {0, 8, 90}, {0, 8, 26}, {0, 9, 149}, {20, 7, 67}, {0, 8, 122}, {0, 8, 58}, {0, 9, 213}, {18, 7, 19}, {0, 8, 106}, {0, 8, 42}, {0, 9, 181}, {0, 8, 10}, {0, 8, 138}, {0, 8, 74}, {0, 9, 245}, {16, 7, 5}, {0, 8, 86}, {0, 8, 22}, {64, 8, 0}, {19, 7, 51}, {0, 8, 118}, {0, 8, 54}, {0, 9, 205}, {17, 7, 15}, {0, 8, 102}, {0, 8, 38}, {0, 9, 173}, {0, 8, 6}, {0, 8, 134}, {0, 8, 70}, {0, 9, 237}, {16, 7, 9}, {0, 8, 94}, {0, 8, 30}, {0, 9, 157}, {20, 7, 99}, {0, 8, 126}, {0, 8, 62}, {0, 9, 221}, {18, 7, 27}, {0, 8, 110}, {0, 8, 46}, {0, 9, 189}, {0, 8, 14}, {0, 8, 142}, {0, 8, 78}, {0, 9, 253}, {96, 7, 0}, {0, 8, 81}, {0, 8, 17}, {21, 8, 131}, {18, 7, 31}, {0, 8, 113}, {0, 8, 49}, {0, 9, 195}, {16, 7, 10}, {0, 8, 97}, {0, 8, 33}, {0, 9, 163}, {0, 8, 1}, {0, 8, 129}, {0, 8, 65}, {0, 9, 227}, {16, 7, 6}, {0, 8, 89}, {0, 8, 25}, {0, 9, 147}, {19, 7, 59}, {0, 8, 121}, {0, 8, 57}, {0, 9, 211}, {17, 7, 17}, {0, 8, 105}, {0, 8, 41}, {0, 9, 179}, {0, 8, 9}, {0, 8, 137}, {0, 8, 73}, {0, 9, 243}, {16, 7, 4}, {0, 8, 85}, {0, 8, 21}, {16, 8, 258}, {19, 7, 43}, {0, 8, 117}, {0, 8, 53}, {0, 9, 203}, {17, 7, 13}, {0, 8, 101}, {0, 8, 37}, {0, 9, 171}, {0, 8, 5}, {0, 8, 133}, {0, 8, 69}, {0, 9, 235}, {16, 7, 8}, {0, 8, 93}, {0, 8, 29}, {0, 9, 155}, {20, 7, 83}, {0, 8, 125}, {0, 8, 61}, {0, 9, 219}, {18, 7, 23}, {0, 8, 109}, {0, 8, 45}, {0, 9, 187}, {0, 8, 13}, {0, 8, 141}, {0, 8, 77}, {0, 9, 251}, {16, 7, 3}, {0, 8, 83}, {0, 8, 19}, {21, 8, 195}, {19, 7, 35}, {0, 8, 115}, {0, 8, 51}, {0, 9, 199}, {17, 7, 11}, {0, 8, 99}, {0, 8, 35}, {0, 9, 167}, {0, 8, 3}, {0, 8, 131}, {0, 8, 67}, {0, 9, 231}, {16, 7, 7}, {0, 8, 91}, {0, 8, 27}, {0, 9, 151}, {20, 7, 67}, {0, 8, 123}, {0, 8, 59}, {0, 9, 215}, {18, 7, 19}, {0, 8, 107}, {0, 8, 43}, {0, 9, 183}, {0, 8, 11}, {0, 8, 139}, {0, 8, 75}, {0, 9, 247}, {16, 7, 5}, {0, 8, 87}, {0, 8, 23}, {64, 8, 0}, {19, 7, 51}, {0, 8, 119}, {0, 8, 55}, {0, 9, 207}, {17, 7, 15}, {0, 8, 103}, {0, 8, 39}, {0, 9, 175}, {0, 8, 7}, {0, 8, 135}, {0, 8, 71}, {0, 9, 239}, {16, 7, 9}, {0, 8, 95}, {0, 8, 31}, {0, 9, 159}, {20, 7, 99}, {0, 8, 127}, {0, 8, 63}, {0, 9, 223}, {18, 7, 27}, {0, 8, 111}, {0, 8, 47}, {0, 9, 191}, {0, 8, 15}, {0, 8, 143}, {0, 8, 79}, {0, 9, 255}}; - static const code distfix[32] = { - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, - {22,5,193},{64,5,0} - }; +static const code distfix[32] = { + {16, 5, 1}, {23, 5, 257}, {19, 5, 17}, {27, 5, 4097}, {17, 5, 5}, {25, 5, 1025}, {21, 5, 65}, {29, 5, 16385}, {16, 5, 3}, {24, 5, 513}, {20, 5, 33}, {28, 5, 8193}, {18, 5, 9}, {26, 5, 2049}, {22, 5, 129}, {64, 5, 0}, {16, 5, 2}, {23, 5, 385}, {19, 5, 25}, {27, 5, 6145}, {17, 5, 7}, {25, 5, 1537}, {21, 5, 97}, {29, 5, 24577}, {16, 5, 4}, {24, 5, 769}, {20, 5, 49}, {28, 5, 12289}, {18, 5, 13}, {26, 5, 3073}, {22, 5, 193}, {64, 5, 0}}; diff --git a/examples/ThirdPartyLibs/zlib/inflate.c b/examples/ThirdPartyLibs/zlib/inflate.c index 870f89bb4..8f714cbd9 100644 --- a/examples/ThirdPartyLibs/zlib/inflate.c +++ b/examples/ThirdPartyLibs/zlib/inflate.c @@ -86,166 +86,172 @@ #include "inffast.h" #ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif +#ifndef BUILDFIXED +#define BUILDFIXED +#endif #endif /* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); +local void fixedtables OF((struct inflate_state FAR * state)); local int updatewindow OF((z_streamp strm, const unsigned char FAR *end, - unsigned copy)); + unsigned copy)); #ifdef BUILDFIXED - void makefixed OF((void)); +void makefixed OF((void)); #endif local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf, - unsigned len)); + unsigned len)); int ZEXPORT inflateResetKeep(strm) -z_streamp strm; + z_streamp strm; { - struct inflate_state FAR *state; + struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - strm->total_in = strm->total_out = state->total = 0; - strm->msg = Z_NULL; - if (state->wrap) /* to support ill-conceived Java test suite */ - strm->adler = state->wrap & 1; - state->mode = HEAD; - state->last = 0; - state->havedict = 0; - state->dmax = 32768U; - state->head = Z_NULL; - state->hold = 0; - state->bits = 0; - state->lencode = state->distcode = state->next = state->codes; - state->sane = 1; - state->back = -1; - Tracev((stderr, "inflate: reset\n")); - return Z_OK; + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + strm->total_in = strm->total_out = state->total = 0; + strm->msg = Z_NULL; + if (state->wrap) /* to support ill-conceived Java test suite */ + strm->adler = state->wrap & 1; + state->mode = HEAD; + state->last = 0; + state->havedict = 0; + state->dmax = 32768U; + state->head = Z_NULL; + state->hold = 0; + state->bits = 0; + state->lencode = state->distcode = state->next = state->codes; + state->sane = 1; + state->back = -1; + Tracev((stderr, "inflate: reset\n")); + return Z_OK; } int ZEXPORT inflateReset(strm) -z_streamp strm; + z_streamp strm; { - struct inflate_state FAR *state; + struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - state->wsize = 0; - state->whave = 0; - state->wnext = 0; - return inflateResetKeep(strm); + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->wsize = 0; + state->whave = 0; + state->wnext = 0; + return inflateResetKeep(strm); } int ZEXPORT inflateReset2(strm, windowBits) -z_streamp strm; + z_streamp strm; int windowBits; { - int wrap; - struct inflate_state FAR *state; + int wrap; + struct inflate_state FAR *state; - /* get the state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; + /* get the state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 1; + /* extract wrap request from windowBits parameter */ + if (windowBits < 0) + { + wrap = 0; + windowBits = -windowBits; + } + else + { + wrap = (windowBits >> 4) + 1; #ifdef GUNZIP - if (windowBits < 48) - windowBits &= 15; + if (windowBits < 48) + windowBits &= 15; #endif - } + } - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) - return Z_STREAM_ERROR; - if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { - ZFREE(strm, state->window); - state->window = Z_NULL; - } + /* set number of window bits, free window if different */ + if (windowBits && (windowBits < 8 || windowBits > 15)) + return Z_STREAM_ERROR; + if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) + { + ZFREE(strm, state->window); + state->window = Z_NULL; + } - /* update state and reset the rest of it */ - state->wrap = wrap; - state->wbits = (unsigned)windowBits; - return inflateReset(strm); + /* update state and reset the rest of it */ + state->wrap = wrap; + state->wbits = (unsigned)windowBits; + return inflateReset(strm); } int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) -z_streamp strm; + z_streamp strm; int windowBits; const char *version; int stream_size; { - int ret; - struct inflate_state FAR *state; + int ret; + struct inflate_state FAR *state; - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL) return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { + if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || + stream_size != (int)(sizeof(z_stream))) + return Z_VERSION_ERROR; + if (strm == Z_NULL) return Z_STREAM_ERROR; + strm->msg = Z_NULL; /* in case we return an error */ + if (strm->zalloc == (alloc_func)0) + { #ifdef Z_SOLO - return Z_STREAM_ERROR; + return Z_STREAM_ERROR; #else - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; + strm->zalloc = zcalloc; + strm->opaque = (voidpf)0; #endif - } - if (strm->zfree == (free_func)0) + } + if (strm->zfree == (free_func)0) #ifdef Z_SOLO - return Z_STREAM_ERROR; + return Z_STREAM_ERROR; #else - strm->zfree = zcfree; + strm->zfree = zcfree; #endif - state = (struct inflate_state FAR *) - ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->window = Z_NULL; - ret = inflateReset2(strm, windowBits); - if (ret != Z_OK) { - ZFREE(strm, state); - strm->state = Z_NULL; - } - return ret; + state = (struct inflate_state FAR *) + ZALLOC(strm, 1, sizeof(struct inflate_state)); + if (state == Z_NULL) return Z_MEM_ERROR; + Tracev((stderr, "inflate: allocated\n")); + strm->state = (struct internal_state FAR *)state; + state->window = Z_NULL; + ret = inflateReset2(strm, windowBits); + if (ret != Z_OK) + { + ZFREE(strm, state); + strm->state = Z_NULL; + } + return ret; } int ZEXPORT inflateInit_(strm, version, stream_size) -z_streamp strm; + z_streamp strm; const char *version; int stream_size; { - return inflateInit2_(strm, DEF_WBITS, version, stream_size); + return inflateInit2_(strm, DEF_WBITS, version, stream_size); } int ZEXPORT inflatePrime(strm, bits, value) -z_streamp strm; + z_streamp strm; int bits; int value; { - struct inflate_state FAR *state; + struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (bits < 0) { - state->hold = 0; - state->bits = 0; - return Z_OK; - } - if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += value << state->bits; - state->bits += bits; - return Z_OK; + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (bits < 0) + { + state->hold = 0; + state->bits = 0; + return Z_OK; + } + if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; + value &= (1L << bits) - 1; + state->hold += value << state->bits; + state->bits += bits; + return Z_OK; } /* @@ -258,47 +264,47 @@ int value; used for threaded applications, since the rewriting of the tables and virgin may not be thread-safe. */ -local void fixedtables(state) -struct inflate_state FAR *state; +local void fixedtables(state) struct inflate_state FAR *state; { #ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; + static int virgin = 1; + static code *lenfix, *distfix; + static code fixed[544]; - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; + /* build fixed huffman tables if first call (may not be thread safe) */ + if (virgin) + { + unsigned sym, bits; + static code *next; - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); + /* literal/length table */ + sym = 0; + while (sym < 144) state->lens[sym++] = 8; + while (sym < 256) state->lens[sym++] = 9; + while (sym < 280) state->lens[sym++] = 7; + while (sym < 288) state->lens[sym++] = 8; + next = fixed; + lenfix = next; + bits = 9; + inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); + /* distance table */ + sym = 0; + while (sym < 32) state->lens[sym++] = 5; + distfix = next; + bits = 5; + inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - /* do this just once */ - virgin = 0; - } + /* do this just once */ + virgin = 0; + } #else /* !BUILDFIXED */ -# include "inffixed.h" +#include "inffixed.h" #endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; + state->lencode = lenfix; + state->lenbits = 9; + state->distcode = distfix; + state->distbits = 5; } #ifdef MAKEFIXED @@ -324,41 +330,43 @@ struct inflate_state FAR *state; */ void makefixed() { - unsigned low, size; - struct inflate_state state; + unsigned low, size; + struct inflate_state state; - fixedtables(&state); - puts(" /* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts(" /* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf(" static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, - state.lencode[low].bits, state.lencode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); - size = 1U << 5; - printf("\n static const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, - state.distcode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); + fixedtables(&state); + puts(" /* inffixed.h -- table for decoding fixed codes"); + puts(" * Generated automatically by makefixed()."); + puts(" */"); + puts(""); + puts(" /* WARNING: this file should *not* be used by applications."); + puts(" It is part of the implementation of this library and is"); + puts(" subject to change. Applications should only use zlib.h."); + puts(" */"); + puts(""); + size = 1U << 9; + printf(" static const code lenfix[%u] = {", size); + low = 0; + for (;;) + { + if ((low % 7) == 0) printf("\n "); + printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op, + state.lencode[low].bits, state.lencode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); + size = 1U << 5; + printf("\n static const code distfix[%u] = {", size); + low = 0; + for (;;) + { + if ((low % 6) == 0) printf("\n "); + printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, + state.distcode[low].val); + if (++low == size) break; + putchar(','); + } + puts("\n };"); } #endif /* MAKEFIXED */ @@ -377,148 +385,163 @@ void makefixed() The advantage may be dependent on the size of the processor's data caches. */ local int updatewindow(strm, end, copy) -z_streamp strm; + z_streamp strm; const Bytef *end; unsigned copy; { - struct inflate_state FAR *state; - unsigned dist; + struct inflate_state FAR *state; + unsigned dist; - state = (struct inflate_state FAR *)strm->state; + state = (struct inflate_state FAR *)strm->state; - /* if it hasn't been done already, allocate space for the window */ - if (state->window == Z_NULL) { - state->window = (unsigned char FAR *) - ZALLOC(strm, 1U << state->wbits, - sizeof(unsigned char)); - if (state->window == Z_NULL) return 1; - } + /* if it hasn't been done already, allocate space for the window */ + if (state->window == Z_NULL) + { + state->window = (unsigned char FAR *) + ZALLOC(strm, 1U << state->wbits, + sizeof(unsigned char)); + if (state->window == Z_NULL) return 1; + } - /* if window not in use yet, initialize */ - if (state->wsize == 0) { - state->wsize = 1U << state->wbits; - state->wnext = 0; - state->whave = 0; - } + /* if window not in use yet, initialize */ + if (state->wsize == 0) + { + state->wsize = 1U << state->wbits; + state->wnext = 0; + state->whave = 0; + } - /* copy state->wsize or less output bytes into the circular window */ - if (copy >= state->wsize) { - zmemcpy(state->window, end - state->wsize, state->wsize); - state->wnext = 0; - state->whave = state->wsize; - } - else { - dist = state->wsize - state->wnext; - if (dist > copy) dist = copy; - zmemcpy(state->window + state->wnext, end - copy, dist); - copy -= dist; - if (copy) { - zmemcpy(state->window, end - copy, copy); - state->wnext = copy; - state->whave = state->wsize; - } - else { - state->wnext += dist; - if (state->wnext == state->wsize) state->wnext = 0; - if (state->whave < state->wsize) state->whave += dist; - } - } - return 0; + /* copy state->wsize or less output bytes into the circular window */ + if (copy >= state->wsize) + { + zmemcpy(state->window, end - state->wsize, state->wsize); + state->wnext = 0; + state->whave = state->wsize; + } + else + { + dist = state->wsize - state->wnext; + if (dist > copy) dist = copy; + zmemcpy(state->window + state->wnext, end - copy, dist); + copy -= dist; + if (copy) + { + zmemcpy(state->window, end - copy, copy); + state->wnext = copy; + state->whave = state->wsize; + } + else + { + state->wnext += dist; + if (state->wnext == state->wsize) state->wnext = 0; + if (state->whave < state->wsize) state->whave += dist; + } + } + return 0; } /* Macros for inflate(): */ /* check function to use adler32() for zlib or crc32() for gzip */ #ifdef GUNZIP -# define UPDATE(check, buf, len) \ - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) +#define UPDATE(check, buf, len) \ + (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) #else -# define UPDATE(check, buf, len) adler32(check, buf, len) +#define UPDATE(check, buf, len) adler32(check, buf, len) #endif /* check macros for header crc */ #ifdef GUNZIP -# define CRC2(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - check = crc32(check, hbuf, 2); \ - } while (0) +#define CRC2(check, word) \ + do \ + { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + check = crc32(check, hbuf, 2); \ + } while (0) -# define CRC4(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - hbuf[2] = (unsigned char)((word) >> 16); \ - hbuf[3] = (unsigned char)((word) >> 24); \ - check = crc32(check, hbuf, 4); \ - } while (0) +#define CRC4(check, word) \ + do \ + { \ + hbuf[0] = (unsigned char)(word); \ + hbuf[1] = (unsigned char)((word) >> 8); \ + hbuf[2] = (unsigned char)((word) >> 16); \ + hbuf[3] = (unsigned char)((word) >> 24); \ + check = crc32(check, hbuf, 4); \ + } while (0) #endif /* Load registers with state in inflate() for speed */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) +#define LOAD() \ + do \ + { \ + put = strm->next_out; \ + left = strm->avail_out; \ + next = strm->next_in; \ + have = strm->avail_in; \ + hold = state->hold; \ + bits = state->bits; \ + } while (0) /* Restore state from registers in inflate() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) +#define RESTORE() \ + do \ + { \ + strm->next_out = put; \ + strm->avail_out = left; \ + strm->next_in = next; \ + strm->avail_in = have; \ + state->hold = hold; \ + state->bits = bits; \ + } while (0) /* Clear the input bit accumulator */ #define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) + do \ + { \ + hold = 0; \ + bits = 0; \ + } while (0) /* Get a byte of input into the bit accumulator, or return from inflate() if there is no input available. */ -#define PULLBYTE() \ - do { \ - if (have == 0) goto inf_leave; \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) +#define PULLBYTE() \ + do \ + { \ + if (have == 0) goto inf_leave; \ + have--; \ + hold += (unsigned long)(*next++) << bits; \ + bits += 8; \ + } while (0) /* Assure that there are at least n bits in the bit accumulator. If there is not enough available input to do that, then return from inflate(). */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) +#define NEEDBITS(n) \ + do \ + { \ + while (bits < (unsigned)(n)) \ + PULLBYTE(); \ + } while (0) /* Return the low n bits of the bit accumulator (n < 16) */ #define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) + ((unsigned)hold & ((1U << (n)) - 1)) /* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) +#define DROPBITS(n) \ + do \ + { \ + hold >>= (n); \ + bits -= (unsigned)(n); \ + } while (0) /* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) +#define BYTEBITS() \ + do \ + { \ + hold >>= bits & 7; \ + bits -= bits & 7; \ + } while (0) /* inflate() uses a state machine to process as much input data and generate as @@ -603,741 +626,808 @@ unsigned copy; */ int ZEXPORT inflate(strm, flush) -z_streamp strm; + z_streamp strm; int flush; { - struct inflate_state FAR *state; - z_const unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned in, out; /* save starting available input and output */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ + struct inflate_state FAR *state; + z_const unsigned char FAR *next; /* next input */ + unsigned char FAR *put; /* next output */ + unsigned have, left; /* available input and output */ + unsigned long hold; /* bit buffer */ + unsigned bits; /* bits in bit buffer */ + unsigned in, out; /* save starting available input and output */ + unsigned copy; /* number of stored or match bytes to copy */ + unsigned char FAR *from; /* where to copy match bytes from */ + code here; /* current decoding table entry */ + code last; /* parent table entry */ + unsigned len; /* length to copy for repeats, bits to drop */ + int ret; /* return code */ #ifdef GUNZIP - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ + unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ #endif - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; + static const unsigned short order[19] = /* permutation of code lengths */ + {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0)) - return Z_STREAM_ERROR; + if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || + (strm->next_in == Z_NULL && strm->avail_in != 0)) + return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ - LOAD(); - in = have; - out = left; - ret = Z_OK; - for (;;) - switch (state->mode) { - case HEAD: - if (state->wrap == 0) { - state->mode = TYPEDO; - break; - } - NEEDBITS(16); + state = (struct inflate_state FAR *)strm->state; + if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ + LOAD(); + in = have; + out = left; + ret = Z_OK; + for (;;) + switch (state->mode) + { + case HEAD: + if (state->wrap == 0) + { + state->mode = TYPEDO; + break; + } + NEEDBITS(16); #ifdef GUNZIP - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - state->check = crc32(0L, Z_NULL, 0); - CRC2(state->check, hold); - INITBITS(); - state->mode = FLAGS; - break; - } - state->flags = 0; /* expect zlib header */ - if (state->head != Z_NULL) - state->head->done = -1; - if (!(state->wrap & 1) || /* check if zlib header allowed */ + if ((state->wrap & 2) && hold == 0x8b1f) + { /* gzip header */ + state->check = crc32(0L, Z_NULL, 0); + CRC2(state->check, hold); + INITBITS(); + state->mode = FLAGS; + break; + } + state->flags = 0; /* expect zlib header */ + if (state->head != Z_NULL) + state->head->done = -1; + if (!(state->wrap & 1) || /* check if zlib header allowed */ #else - if ( + if ( #endif - ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (char *)"incorrect header check"; - state->mode = BAD; - break; - } - if (BITS(4) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - DROPBITS(4); - len = BITS(4) + 8; - if (state->wbits == 0) - state->wbits = len; - else if (len > state->wbits) { - strm->msg = (char *)"invalid window size"; - state->mode = BAD; - break; - } - state->dmax = 1U << len; - Tracev((stderr, "inflate: zlib header ok\n")); - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = hold & 0x200 ? DICTID : TYPE; - INITBITS(); - break; + ((BITS(8) << 8) + (hold >> 8)) % 31) + { + strm->msg = (char *)"incorrect header check"; + state->mode = BAD; + break; + } + if (BITS(4) != Z_DEFLATED) + { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + DROPBITS(4); + len = BITS(4) + 8; + if (state->wbits == 0) + state->wbits = len; + else if (len > state->wbits) + { + strm->msg = (char *)"invalid window size"; + state->mode = BAD; + break; + } + state->dmax = 1U << len; + Tracev((stderr, "inflate: zlib header ok\n")); + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = hold & 0x200 ? DICTID : TYPE; + INITBITS(); + break; #ifdef GUNZIP - case FLAGS: - NEEDBITS(16); - state->flags = (int)(hold); - if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - if (state->flags & 0xe000) { - strm->msg = (char *)"unknown header flags set"; - state->mode = BAD; - break; - } - if (state->head != Z_NULL) - state->head->text = (int)((hold >> 8) & 1); - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = TIME; - case TIME: - NEEDBITS(32); - if (state->head != Z_NULL) - state->head->time = hold; - if (state->flags & 0x0200) CRC4(state->check, hold); - INITBITS(); - state->mode = OS; - case OS: - NEEDBITS(16); - if (state->head != Z_NULL) { - state->head->xflags = (int)(hold & 0xff); - state->head->os = (int)(hold >> 8); - } - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = EXLEN; - case EXLEN: - if (state->flags & 0x0400) { - NEEDBITS(16); - state->length = (unsigned)(hold); - if (state->head != Z_NULL) - state->head->extra_len = (unsigned)hold; - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - } - else if (state->head != Z_NULL) - state->head->extra = Z_NULL; - state->mode = EXTRA; - case EXTRA: - if (state->flags & 0x0400) { - copy = state->length; - if (copy > have) copy = have; - if (copy) { - if (state->head != Z_NULL && - state->head->extra != Z_NULL) { - len = state->head->extra_len - state->length; - zmemcpy(state->head->extra + len, next, - len + copy > state->head->extra_max ? - state->head->extra_max - len : copy); - } - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - state->length -= copy; - } - if (state->length) goto inf_leave; - } - state->length = 0; - state->mode = NAME; - case NAME: - if (state->flags & 0x0800) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->name != Z_NULL && - state->length < state->head->name_max) - state->head->name[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->name = Z_NULL; - state->length = 0; - state->mode = COMMENT; - case COMMENT: - if (state->flags & 0x1000) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->comment != Z_NULL && - state->length < state->head->comm_max) - state->head->comment[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->comment = Z_NULL; - state->mode = HCRC; - case HCRC: - if (state->flags & 0x0200) { - NEEDBITS(16); - if (hold != (state->check & 0xffff)) { - strm->msg = (char *)"header crc mismatch"; - state->mode = BAD; - break; - } - INITBITS(); - } - if (state->head != Z_NULL) { - state->head->hcrc = (int)((state->flags >> 9) & 1); - state->head->done = 1; - } - strm->adler = state->check = crc32(0L, Z_NULL, 0); - state->mode = TYPE; - break; + case FLAGS: + NEEDBITS(16); + state->flags = (int)(hold); + if ((state->flags & 0xff) != Z_DEFLATED) + { + strm->msg = (char *)"unknown compression method"; + state->mode = BAD; + break; + } + if (state->flags & 0xe000) + { + strm->msg = (char *)"unknown header flags set"; + state->mode = BAD; + break; + } + if (state->head != Z_NULL) + state->head->text = (int)((hold >> 8) & 1); + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = TIME; + case TIME: + NEEDBITS(32); + if (state->head != Z_NULL) + state->head->time = hold; + if (state->flags & 0x0200) CRC4(state->check, hold); + INITBITS(); + state->mode = OS; + case OS: + NEEDBITS(16); + if (state->head != Z_NULL) + { + state->head->xflags = (int)(hold & 0xff); + state->head->os = (int)(hold >> 8); + } + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + state->mode = EXLEN; + case EXLEN: + if (state->flags & 0x0400) + { + NEEDBITS(16); + state->length = (unsigned)(hold); + if (state->head != Z_NULL) + state->head->extra_len = (unsigned)hold; + if (state->flags & 0x0200) CRC2(state->check, hold); + INITBITS(); + } + else if (state->head != Z_NULL) + state->head->extra = Z_NULL; + state->mode = EXTRA; + case EXTRA: + if (state->flags & 0x0400) + { + copy = state->length; + if (copy > have) copy = have; + if (copy) + { + if (state->head != Z_NULL && + state->head->extra != Z_NULL) + { + len = state->head->extra_len - state->length; + zmemcpy(state->head->extra + len, next, + len + copy > state->head->extra_max ? state->head->extra_max - len : copy); + } + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + state->length -= copy; + } + if (state->length) goto inf_leave; + } + state->length = 0; + state->mode = NAME; + case NAME: + if (state->flags & 0x0800) + { + if (have == 0) goto inf_leave; + copy = 0; + do + { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->name != Z_NULL && + state->length < state->head->name_max) + state->head->name[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->name = Z_NULL; + state->length = 0; + state->mode = COMMENT; + case COMMENT: + if (state->flags & 0x1000) + { + if (have == 0) goto inf_leave; + copy = 0; + do + { + len = (unsigned)(next[copy++]); + if (state->head != Z_NULL && + state->head->comment != Z_NULL && + state->length < state->head->comm_max) + state->head->comment[state->length++] = len; + } while (len && copy < have); + if (state->flags & 0x0200) + state->check = crc32(state->check, next, copy); + have -= copy; + next += copy; + if (len) goto inf_leave; + } + else if (state->head != Z_NULL) + state->head->comment = Z_NULL; + state->mode = HCRC; + case HCRC: + if (state->flags & 0x0200) + { + NEEDBITS(16); + if (hold != (state->check & 0xffff)) + { + strm->msg = (char *)"header crc mismatch"; + state->mode = BAD; + break; + } + INITBITS(); + } + if (state->head != Z_NULL) + { + state->head->hcrc = (int)((state->flags >> 9) & 1); + state->head->done = 1; + } + strm->adler = state->check = crc32(0L, Z_NULL, 0); + state->mode = TYPE; + break; #endif - case DICTID: - NEEDBITS(32); - strm->adler = state->check = ZSWAP32(hold); - INITBITS(); - state->mode = DICT; - case DICT: - if (state->havedict == 0) { - RESTORE(); - return Z_NEED_DICT; - } - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = TYPE; - case TYPE: - if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; - case TYPEDO: - if (state->last) { - BYTEBITS(); - state->mode = CHECK; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN_; /* decode codes */ - if (flush == Z_TREES) { - DROPBITS(2); - goto inf_leave; - } - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - case STORED: - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - state->mode = COPY_; - if (flush == Z_TREES) goto inf_leave; - case COPY_: - state->mode = COPY; - case COPY: - copy = state->length; - if (copy) { - if (copy > have) copy = have; - if (copy > left) copy = left; - if (copy == 0) goto inf_leave; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - break; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - case TABLE: - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); + case DICTID: + NEEDBITS(32); + strm->adler = state->check = ZSWAP32(hold); + INITBITS(); + state->mode = DICT; + case DICT: + if (state->havedict == 0) + { + RESTORE(); + return Z_NEED_DICT; + } + strm->adler = state->check = adler32(0L, Z_NULL, 0); + state->mode = TYPE; + case TYPE: + if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; + case TYPEDO: + if (state->last) + { + BYTEBITS(); + state->mode = CHECK; + break; + } + NEEDBITS(3); + state->last = BITS(1); + DROPBITS(1); + switch (BITS(2)) + { + case 0: /* stored block */ + Tracev((stderr, "inflate: stored block%s\n", + state->last ? " (last)" : "")); + state->mode = STORED; + break; + case 1: /* fixed block */ + fixedtables(state); + Tracev((stderr, "inflate: fixed codes block%s\n", + state->last ? " (last)" : "")); + state->mode = LEN_; /* decode codes */ + if (flush == Z_TREES) + { + DROPBITS(2); + goto inf_leave; + } + break; + case 2: /* dynamic block */ + Tracev((stderr, "inflate: dynamic codes block%s\n", + state->last ? " (last)" : "")); + state->mode = TABLE; + break; + case 3: + strm->msg = (char *)"invalid block type"; + state->mode = BAD; + } + DROPBITS(2); + break; + case STORED: + BYTEBITS(); /* go to byte boundary */ + NEEDBITS(32); + if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) + { + strm->msg = (char *)"invalid stored block lengths"; + state->mode = BAD; + break; + } + state->length = (unsigned)hold & 0xffff; + Tracev((stderr, "inflate: stored length %u\n", + state->length)); + INITBITS(); + state->mode = COPY_; + if (flush == Z_TREES) goto inf_leave; + case COPY_: + state->mode = COPY; + case COPY: + copy = state->length; + if (copy) + { + if (copy > have) copy = have; + if (copy > left) copy = left; + if (copy == 0) goto inf_leave; + zmemcpy(put, next, copy); + have -= copy; + next += copy; + left -= copy; + put += copy; + state->length -= copy; + break; + } + Tracev((stderr, "inflate: stored end\n")); + state->mode = TYPE; + break; + case TABLE: + NEEDBITS(14); + state->nlen = BITS(5) + 257; + DROPBITS(5); + state->ndist = BITS(5) + 1; + DROPBITS(5); + state->ncode = BITS(4) + 4; + DROPBITS(4); #ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } + if (state->nlen > 286 || state->ndist > 30) + { + strm->msg = (char *)"too many length or distance symbols"; + state->mode = BAD; + break; + } #endif - Tracev((stderr, "inflate: table sizes ok\n")); - state->have = 0; - state->mode = LENLENS; - case LENLENS: - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (const code FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - state->have = 0; - state->mode = CODELENS; - case CODELENS: - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = state->lens[state->have - 1]; - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } + Tracev((stderr, "inflate: table sizes ok\n")); + state->have = 0; + state->mode = LENLENS; + case LENLENS: + while (state->have < state->ncode) + { + NEEDBITS(3); + state->lens[order[state->have++]] = (unsigned short)BITS(3); + DROPBITS(3); + } + while (state->have < 19) + state->lens[order[state->have++]] = 0; + state->next = state->codes; + state->lencode = (const code FAR *)(state->next); + state->lenbits = 7; + ret = inflate_table(CODES, state->lens, 19, &(state->next), + &(state->lenbits), state->work); + if (ret) + { + strm->msg = (char *)"invalid code lengths set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: code lengths ok\n")); + state->have = 0; + state->mode = CODELENS; + case CODELENS: + while (state->have < state->nlen + state->ndist) + { + for (;;) + { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.val < 16) + { + DROPBITS(here.bits); + state->lens[state->have++] = here.val; + } + else + { + if (here.val == 16) + { + NEEDBITS(here.bits + 2); + DROPBITS(here.bits); + if (state->have == 0) + { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + len = state->lens[state->have - 1]; + copy = 3 + BITS(2); + DROPBITS(2); + } + else if (here.val == 17) + { + NEEDBITS(here.bits + 3); + DROPBITS(here.bits); + len = 0; + copy = 3 + BITS(3); + DROPBITS(3); + } + else + { + NEEDBITS(here.bits + 7); + DROPBITS(here.bits); + len = 0; + copy = 11 + BITS(7); + DROPBITS(7); + } + if (state->have + copy > state->nlen + state->ndist) + { + strm->msg = (char *)"invalid bit length repeat"; + state->mode = BAD; + break; + } + while (copy--) + state->lens[state->have++] = (unsigned short)len; + } + } - /* handle error breaks in while */ - if (state->mode == BAD) break; + /* handle error breaks in while */ + if (state->mode == BAD) break; - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } + /* check for end-of-block code (better have one) */ + if (state->lens[256] == 0) + { + strm->msg = (char *)"invalid code -- missing end-of-block"; + state->mode = BAD; + break; + } - /* build code tables -- note: do not change the lenbits or distbits + /* build code tables -- note: do not change the lenbits or distbits values here (9 and 6) without reading the comments in inftrees.h concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (const code FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (const code FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN_; - if (flush == Z_TREES) goto inf_leave; - case LEN_: - state->mode = LEN; - case LEN: - if (have >= 6 && left >= 258) { - RESTORE(); - inflate_fast(strm, out); - LOAD(); - if (state->mode == TYPE) - state->back = -1; - break; - } - state->back = 0; - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - state->length = (unsigned)here.val; - if ((int)(here.op) == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - state->mode = LIT; - break; - } - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->back = -1; - state->mode = TYPE; - break; - } - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - state->extra = (unsigned)(here.op) & 15; - state->mode = LENEXT; - case LENEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - state->was = state->length; - state->mode = DIST; - case DIST: - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - state->extra = (unsigned)(here.op) & 15; - state->mode = DISTEXT; - case DISTEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } + state->next = state->codes; + state->lencode = (const code FAR *)(state->next); + state->lenbits = 9; + ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), + &(state->lenbits), state->work); + if (ret) + { + strm->msg = (char *)"invalid literal/lengths set"; + state->mode = BAD; + break; + } + state->distcode = (const code FAR *)(state->next); + state->distbits = 6; + ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, + &(state->next), &(state->distbits), state->work); + if (ret) + { + strm->msg = (char *)"invalid distances set"; + state->mode = BAD; + break; + } + Tracev((stderr, "inflate: codes ok\n")); + state->mode = LEN_; + if (flush == Z_TREES) goto inf_leave; + case LEN_: + state->mode = LEN; + case LEN: + if (have >= 6 && left >= 258) + { + RESTORE(); + inflate_fast(strm, out); + LOAD(); + if (state->mode == TYPE) + state->back = -1; + break; + } + state->back = 0; + for (;;) + { + here = state->lencode[BITS(state->lenbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if (here.op && (here.op & 0xf0) == 0) + { + last = here; + for (;;) + { + here = state->lencode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + state->length = (unsigned)here.val; + if ((int)(here.op) == 0) + { + Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? "inflate: literal '%c'\n" : "inflate: literal 0x%02x\n", here.val)); + state->mode = LIT; + break; + } + if (here.op & 32) + { + Tracevv((stderr, "inflate: end of block\n")); + state->back = -1; + state->mode = TYPE; + break; + } + if (here.op & 64) + { + strm->msg = (char *)"invalid literal/length code"; + state->mode = BAD; + break; + } + state->extra = (unsigned)(here.op) & 15; + state->mode = LENEXT; + case LENEXT: + if (state->extra) + { + NEEDBITS(state->extra); + state->length += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } + Tracevv((stderr, "inflate: length %u\n", state->length)); + state->was = state->length; + state->mode = DIST; + case DIST: + for (;;) + { + here = state->distcode[BITS(state->distbits)]; + if ((unsigned)(here.bits) <= bits) break; + PULLBYTE(); + } + if ((here.op & 0xf0) == 0) + { + last = here; + for (;;) + { + here = state->distcode[last.val + + (BITS(last.bits + last.op) >> last.bits)]; + if ((unsigned)(last.bits + here.bits) <= bits) break; + PULLBYTE(); + } + DROPBITS(last.bits); + state->back += last.bits; + } + DROPBITS(here.bits); + state->back += here.bits; + if (here.op & 64) + { + strm->msg = (char *)"invalid distance code"; + state->mode = BAD; + break; + } + state->offset = (unsigned)here.val; + state->extra = (unsigned)(here.op) & 15; + state->mode = DISTEXT; + case DISTEXT: + if (state->extra) + { + NEEDBITS(state->extra); + state->offset += BITS(state->extra); + DROPBITS(state->extra); + state->back += state->extra; + } #ifdef INFLATE_STRICT - if (state->offset > state->dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } + if (state->offset > state->dmax) + { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } #endif - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - state->mode = MATCH; - case MATCH: - if (left == 0) goto inf_leave; - copy = out - left; - if (state->offset > copy) { /* copy from window */ - copy = state->offset - copy; - if (copy > state->whave) { - if (state->sane) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } + Tracevv((stderr, "inflate: distance %u\n", state->offset)); + state->mode = MATCH; + case MATCH: + if (left == 0) goto inf_leave; + copy = out - left; + if (state->offset > copy) + { /* copy from window */ + copy = state->offset - copy; + if (copy > state->whave) + { + if (state->sane) + { + strm->msg = (char *)"invalid distance too far back"; + state->mode = BAD; + break; + } #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - Trace((stderr, "inflate.c too far\n")); - copy -= state->whave; - if (copy > state->length) copy = state->length; - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = 0; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; + Trace((stderr, "inflate.c too far\n")); + copy -= state->whave; + if (copy > state->length) copy = state->length; + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do + { + *put++ = 0; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; #endif - } - if (copy > state->wnext) { - copy -= state->wnext; - from = state->window + (state->wsize - copy); - } - else - from = state->window + (state->wnext - copy); - if (copy > state->length) copy = state->length; - } - else { /* copy from output */ - from = put - state->offset; - copy = state->length; - } - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = *from++; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; - case LIT: - if (left == 0) goto inf_leave; - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - case CHECK: - if (state->wrap) { - NEEDBITS(32); - out -= left; - strm->total_out += out; - state->total += out; - if (out) - strm->adler = state->check = - UPDATE(state->check, put - out, out); - out = left; - if (( + } + if (copy > state->wnext) + { + copy -= state->wnext; + from = state->window + (state->wsize - copy); + } + else + from = state->window + (state->wnext - copy); + if (copy > state->length) copy = state->length; + } + else + { /* copy from output */ + from = put - state->offset; + copy = state->length; + } + if (copy > left) copy = left; + left -= copy; + state->length -= copy; + do + { + *put++ = *from++; + } while (--copy); + if (state->length == 0) state->mode = LEN; + break; + case LIT: + if (left == 0) goto inf_leave; + *put++ = (unsigned char)(state->length); + left--; + state->mode = LEN; + break; + case CHECK: + if (state->wrap) + { + NEEDBITS(32); + out -= left; + strm->total_out += out; + state->total += out; + if (out) + strm->adler = state->check = + UPDATE(state->check, put - out, out); + out = left; + if (( #ifdef GUNZIP - state->flags ? hold : + state->flags ? hold : #endif - ZSWAP32(hold)) != state->check) { - strm->msg = (char *)"incorrect data check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); - } + ZSWAP32(hold)) != state->check) + { + strm->msg = (char *)"incorrect data check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: check matches trailer\n")); + } #ifdef GUNZIP - state->mode = LENGTH; - case LENGTH: - if (state->wrap && state->flags) { - NEEDBITS(32); - if (hold != (state->total & 0xffffffffUL)) { - strm->msg = (char *)"incorrect length check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); - } + state->mode = LENGTH; + case LENGTH: + if (state->wrap && state->flags) + { + NEEDBITS(32); + if (hold != (state->total & 0xffffffffUL)) + { + strm->msg = (char *)"incorrect length check"; + state->mode = BAD; + break; + } + INITBITS(); + Tracev((stderr, "inflate: length matches trailer\n")); + } #endif - state->mode = DONE; - case DONE: - ret = Z_STREAM_END; - goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - default: - return Z_STREAM_ERROR; - } + state->mode = DONE; + case DONE: + ret = Z_STREAM_END; + goto inf_leave; + case BAD: + ret = Z_DATA_ERROR; + goto inf_leave; + case MEM: + return Z_MEM_ERROR; + case SYNC: + default: + return Z_STREAM_ERROR; + } - /* + /* Return from inflate(), updating the total counts and the check value. If there was no progress during the inflate() call, return a buffer error. Call updatewindow() to create and/or update the window state. Note: a memory error from inflate() is non-recoverable. */ - inf_leave: - RESTORE(); - if (state->wsize || (out != strm->avail_out && state->mode < BAD && - (state->mode < CHECK || flush != Z_FINISH))) - if (updatewindow(strm, strm->next_out, out - strm->avail_out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - in -= strm->avail_in; - out -= strm->avail_out; - strm->total_in += in; - strm->total_out += out; - state->total += out; - if (state->wrap && out) - strm->adler = state->check = - UPDATE(state->check, strm->next_out - out, out); - strm->data_type = state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0) + - (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) - ret = Z_BUF_ERROR; - return ret; +inf_leave: + RESTORE(); + if (state->wsize || (out != strm->avail_out && state->mode < BAD && + (state->mode < CHECK || flush != Z_FINISH))) + if (updatewindow(strm, strm->next_out, out - strm->avail_out)) + { + state->mode = MEM; + return Z_MEM_ERROR; + } + in -= strm->avail_in; + out -= strm->avail_out; + strm->total_in += in; + strm->total_out += out; + state->total += out; + if (state->wrap && out) + strm->adler = state->check = + UPDATE(state->check, strm->next_out - out, out); + strm->data_type = state->bits + (state->last ? 64 : 0) + + (state->mode == TYPE ? 128 : 0) + + (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); + if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) + ret = Z_BUF_ERROR; + return ret; } int ZEXPORT inflateEnd(strm) -z_streamp strm; + z_streamp strm; { - struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->window != Z_NULL) ZFREE(strm, state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; + struct inflate_state FAR *state; + if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->window != Z_NULL) ZFREE(strm, state->window); + ZFREE(strm, strm->state); + strm->state = Z_NULL; + Tracev((stderr, "inflate: end\n")); + return Z_OK; } int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength) -z_streamp strm; + z_streamp strm; Bytef *dictionary; uInt *dictLength; { - struct inflate_state FAR *state; + struct inflate_state FAR *state; - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; - /* copy dictionary */ - if (state->whave && dictionary != Z_NULL) { - zmemcpy(dictionary, state->window + state->wnext, - state->whave - state->wnext); - zmemcpy(dictionary + state->whave - state->wnext, - state->window, state->wnext); - } - if (dictLength != Z_NULL) - *dictLength = state->whave; - return Z_OK; + /* copy dictionary */ + if (state->whave && dictionary != Z_NULL) + { + zmemcpy(dictionary, state->window + state->wnext, + state->whave - state->wnext); + zmemcpy(dictionary + state->whave - state->wnext, + state->window, state->wnext); + } + if (dictLength != Z_NULL) + *dictLength = state->whave; + return Z_OK; } int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) -z_streamp strm; + z_streamp strm; const Bytef *dictionary; uInt dictLength; { - struct inflate_state FAR *state; - unsigned long dictid; - int ret; + struct inflate_state FAR *state; + unsigned long dictid; + int ret; - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->wrap != 0 && state->mode != DICT) - return Z_STREAM_ERROR; + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (state->wrap != 0 && state->mode != DICT) + return Z_STREAM_ERROR; - /* check for correct dictionary identifier */ - if (state->mode == DICT) { - dictid = adler32(0L, Z_NULL, 0); - dictid = adler32(dictid, dictionary, dictLength); - if (dictid != state->check) - return Z_DATA_ERROR; - } + /* check for correct dictionary identifier */ + if (state->mode == DICT) + { + dictid = adler32(0L, Z_NULL, 0); + dictid = adler32(dictid, dictionary, dictLength); + if (dictid != state->check) + return Z_DATA_ERROR; + } - /* copy dictionary to window using updatewindow(), which will amend the + /* copy dictionary to window using updatewindow(), which will amend the existing dictionary if appropriate */ - ret = updatewindow(strm, dictionary + dictLength, dictLength); - if (ret) { - state->mode = MEM; - return Z_MEM_ERROR; - } - state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; + ret = updatewindow(strm, dictionary + dictLength, dictLength); + if (ret) + { + state->mode = MEM; + return Z_MEM_ERROR; + } + state->havedict = 1; + Tracev((stderr, "inflate: dictionary set\n")); + return Z_OK; } int ZEXPORT inflateGetHeader(strm, head) -z_streamp strm; + z_streamp strm; gz_headerp head; { - struct inflate_state FAR *state; + struct inflate_state FAR *state; - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; + /* check state */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; - /* save header structure */ - state->head = head; - head->done = 0; - return Z_OK; + /* save header structure */ + state->head = head; + head->done = 0; + return Z_OK; } /* @@ -1351,70 +1441,74 @@ gz_headerp head; called again with more data and the *have state. *have is initialized to zero for the first call. */ -local unsigned syncsearch(have, buf, len) -unsigned FAR *have; +local unsigned syncsearch(have, buf, len) unsigned FAR *have; const unsigned char FAR *buf; unsigned len; { - unsigned got; - unsigned next; + unsigned got; + unsigned next; - got = *have; - next = 0; - while (next < len && got < 4) { - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) - got++; - else if (buf[next]) - got = 0; - else - got = 4 - got; - next++; - } - *have = got; - return next; + got = *have; + next = 0; + while (next < len && got < 4) + { + if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) + got++; + else if (buf[next]) + got = 0; + else + got = 4 - got; + next++; + } + *have = got; + return next; } int ZEXPORT inflateSync(strm) -z_streamp strm; + z_streamp strm; { - unsigned len; /* number of bytes to look at or looked at */ - unsigned long in, out; /* temporary to save total_in and total_out */ - unsigned char buf[4]; /* to restore bit buffer to byte string */ - struct inflate_state FAR *state; + unsigned len; /* number of bytes to look at or looked at */ + unsigned long in, out; /* temporary to save total_in and total_out */ + unsigned char buf[4]; /* to restore bit buffer to byte string */ + struct inflate_state FAR *state; - /* check parameters */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; + /* check parameters */ + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; - /* if first time, start search in bit buffer */ - if (state->mode != SYNC) { - state->mode = SYNC; - state->hold <<= state->bits & 7; - state->bits -= state->bits & 7; - len = 0; - while (state->bits >= 8) { - buf[len++] = (unsigned char)(state->hold); - state->hold >>= 8; - state->bits -= 8; - } - state->have = 0; - syncsearch(&(state->have), buf, len); - } + /* if first time, start search in bit buffer */ + if (state->mode != SYNC) + { + state->mode = SYNC; + state->hold <<= state->bits & 7; + state->bits -= state->bits & 7; + len = 0; + while (state->bits >= 8) + { + buf[len++] = (unsigned char)(state->hold); + state->hold >>= 8; + state->bits -= 8; + } + state->have = 0; + syncsearch(&(state->have), buf, len); + } - /* search available input */ - len = syncsearch(&(state->have), strm->next_in, strm->avail_in); - strm->avail_in -= len; - strm->next_in += len; - strm->total_in += len; + /* search available input */ + len = syncsearch(&(state->have), strm->next_in, strm->avail_in); + strm->avail_in -= len; + strm->next_in += len; + strm->total_in += len; - /* return no joy or set up to restart inflate() on a new block */ - if (state->have != 4) return Z_DATA_ERROR; - in = strm->total_in; out = strm->total_out; - inflateReset(strm); - strm->total_in = in; strm->total_out = out; - state->mode = TYPE; - return Z_OK; + /* return no joy or set up to restart inflate() on a new block */ + if (state->have != 4) return Z_DATA_ERROR; + in = strm->total_in; + out = strm->total_out; + inflateReset(strm); + strm->total_in = in; + strm->total_out = out; + state->mode = TYPE; + return Z_OK; } /* @@ -1426,87 +1520,90 @@ z_streamp strm; inflate is waiting for these length bytes. */ int ZEXPORT inflateSyncPoint(strm) -z_streamp strm; + z_streamp strm; { - struct inflate_state FAR *state; + struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - return state->mode == STORED && state->bits == 0; + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + return state->mode == STORED && state->bits == 0; } int ZEXPORT inflateCopy(dest, source) -z_streamp dest; + z_streamp dest; z_streamp source; { - struct inflate_state FAR *state; - struct inflate_state FAR *copy; - unsigned char FAR *window; - unsigned wsize; + struct inflate_state FAR *state; + struct inflate_state FAR *copy; + unsigned char FAR *window; + unsigned wsize; - /* check input */ - if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || - source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)source->state; + /* check input */ + if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || + source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) + return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)source->state; - /* allocate space */ - copy = (struct inflate_state FAR *) - ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; - window = Z_NULL; - if (state->window != Z_NULL) { - window = (unsigned char FAR *) - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); - if (window == Z_NULL) { - ZFREE(source, copy); - return Z_MEM_ERROR; - } - } + /* allocate space */ + copy = (struct inflate_state FAR *) + ZALLOC(source, 1, sizeof(struct inflate_state)); + if (copy == Z_NULL) return Z_MEM_ERROR; + window = Z_NULL; + if (state->window != Z_NULL) + { + window = (unsigned char FAR *) + ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); + if (window == Z_NULL) + { + ZFREE(source, copy); + return Z_MEM_ERROR; + } + } - /* copy state */ - zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); - zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); - if (state->lencode >= state->codes && - state->lencode <= state->codes + ENOUGH - 1) { - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); - } - copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) { - wsize = 1U << state->wbits; - zmemcpy(window, state->window, wsize); - } - copy->window = window; - dest->state = (struct internal_state FAR *)copy; - return Z_OK; + /* copy state */ + zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream)); + zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state)); + if (state->lencode >= state->codes && + state->lencode <= state->codes + ENOUGH - 1) + { + copy->lencode = copy->codes + (state->lencode - state->codes); + copy->distcode = copy->codes + (state->distcode - state->codes); + } + copy->next = copy->codes + (state->next - state->codes); + if (window != Z_NULL) + { + wsize = 1U << state->wbits; + zmemcpy(window, state->window, wsize); + } + copy->window = window; + dest->state = (struct internal_state FAR *)copy; + return Z_OK; } int ZEXPORT inflateUndermine(strm, subvert) -z_streamp strm; + z_streamp strm; int subvert; { - struct inflate_state FAR *state; + struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - state->sane = !subvert; + if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; + state = (struct inflate_state FAR *)strm->state; + state->sane = !subvert; #ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - return Z_OK; + return Z_OK; #else - state->sane = 1; - return Z_DATA_ERROR; + state->sane = 1; + return Z_DATA_ERROR; #endif } long ZEXPORT inflateMark(strm) -z_streamp strm; + z_streamp strm; { - struct inflate_state FAR *state; + struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; - state = (struct inflate_state FAR *)strm->state; - return ((long)(state->back) << 16) + - (state->mode == COPY ? state->length : - (state->mode == MATCH ? state->was - state->length : 0)); + if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; + state = (struct inflate_state FAR *)strm->state; + return ((long)(state->back) << 16) + + (state->mode == COPY ? state->length : (state->mode == MATCH ? state->was - state->length : 0)); } diff --git a/examples/ThirdPartyLibs/zlib/inflate.h b/examples/ThirdPartyLibs/zlib/inflate.h index 95f4986d4..230e0b797 100644 --- a/examples/ThirdPartyLibs/zlib/inflate.h +++ b/examples/ThirdPartyLibs/zlib/inflate.h @@ -13,43 +13,44 @@ the crc code when it is not needed. For shared libraries, gzip decoding should be left enabled. */ #ifndef NO_GZIP -# define GUNZIP +#define GUNZIP #endif /* Possible inflate modes between inflate() calls */ -typedef enum { - HEAD, /* i: waiting for magic header */ - FLAGS, /* i: waiting for method and flags (gzip) */ - TIME, /* i: waiting for modification time (gzip) */ - OS, /* i: waiting for extra flags and operating system (gzip) */ - EXLEN, /* i: waiting for extra length (gzip) */ - EXTRA, /* i: waiting for extra bytes (gzip) */ - NAME, /* i: waiting for end of file name (gzip) */ - COMMENT, /* i: waiting for end of comment (gzip) */ - HCRC, /* i: waiting for header crc (gzip) */ - DICTID, /* i: waiting for dictionary check value */ - DICT, /* waiting for inflateSetDictionary() call */ - TYPE, /* i: waiting for type bits, including last-flag bit */ - TYPEDO, /* i: same, but skip check to exit inflate on new block */ - STORED, /* i: waiting for stored size (length and complement) */ - COPY_, /* i/o: same as COPY below, but only first time in */ - COPY, /* i/o: waiting for input or output to copy stored block */ - TABLE, /* i: waiting for dynamic block table lengths */ - LENLENS, /* i: waiting for code length code lengths */ - CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN_, /* i: same as LEN below, but only first time in */ - LEN, /* i: waiting for length/lit/eob code */ - LENEXT, /* i: waiting for length extra bits */ - DIST, /* i: waiting for distance code */ - DISTEXT, /* i: waiting for distance extra bits */ - MATCH, /* o: waiting for output space to copy string */ - LIT, /* o: waiting for output space to write literal */ - CHECK, /* i: waiting for 32-bit check value */ - LENGTH, /* i: waiting for 32-bit length (gzip) */ - DONE, /* finished check, done -- remain here until reset */ - BAD, /* got a data error -- remain here until reset */ - MEM, /* got an inflate() memory error -- remain here until reset */ - SYNC /* looking for synchronization bytes to restart inflate() */ +typedef enum +{ + HEAD, /* i: waiting for magic header */ + FLAGS, /* i: waiting for method and flags (gzip) */ + TIME, /* i: waiting for modification time (gzip) */ + OS, /* i: waiting for extra flags and operating system (gzip) */ + EXLEN, /* i: waiting for extra length (gzip) */ + EXTRA, /* i: waiting for extra bytes (gzip) */ + NAME, /* i: waiting for end of file name (gzip) */ + COMMENT, /* i: waiting for end of comment (gzip) */ + HCRC, /* i: waiting for header crc (gzip) */ + DICTID, /* i: waiting for dictionary check value */ + DICT, /* waiting for inflateSetDictionary() call */ + TYPE, /* i: waiting for type bits, including last-flag bit */ + TYPEDO, /* i: same, but skip check to exit inflate on new block */ + STORED, /* i: waiting for stored size (length and complement) */ + COPY_, /* i/o: same as COPY below, but only first time in */ + COPY, /* i/o: waiting for input or output to copy stored block */ + TABLE, /* i: waiting for dynamic block table lengths */ + LENLENS, /* i: waiting for code length code lengths */ + CODELENS, /* i: waiting for length/lit and distance code lengths */ + LEN_, /* i: same as LEN below, but only first time in */ + LEN, /* i: waiting for length/lit/eob code */ + LENEXT, /* i: waiting for length extra bits */ + DIST, /* i: waiting for distance code */ + DISTEXT, /* i: waiting for distance extra bits */ + MATCH, /* o: waiting for output space to copy string */ + LIT, /* o: waiting for output space to write literal */ + CHECK, /* i: waiting for 32-bit check value */ + LENGTH, /* i: waiting for 32-bit length (gzip) */ + DONE, /* finished check, done -- remain here until reset */ + BAD, /* got a data error -- remain here until reset */ + MEM, /* got an inflate() memory error -- remain here until reset */ + SYNC /* looking for synchronization bytes to restart inflate() */ } inflate_mode; /* @@ -78,45 +79,46 @@ typedef enum { */ /* state maintained between inflate() calls. Approximately 10K bytes. */ -struct inflate_state { - inflate_mode mode; /* current inflate mode */ - int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags (0 if zlib) */ - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ - unsigned long check; /* protected copy of check value */ - unsigned long total; /* protected copy of output count */ - gz_headerp head; /* where to save gzip header information */ - /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if needed */ - /* bit accumulator */ - unsigned long hold; /* input bit accumulator */ - unsigned bits; /* number of bits in "in" */ - /* for string and stored block copying */ - unsigned length; /* literal or length of data to copy */ - unsigned offset; /* distance back to copy string from */ - /* for table and code decoding */ - unsigned extra; /* extra bits needed */ - /* fixed and dynamic code tables */ - code const FAR *lencode; /* starting table for length/literal codes */ - code const FAR *distcode; /* starting table for distance codes */ - unsigned lenbits; /* index bits for lencode */ - unsigned distbits; /* index bits for distcode */ - /* dynamic table building */ - unsigned ncode; /* number of code length code lengths */ - unsigned nlen; /* number of length code lengths */ - unsigned ndist; /* number of distance code lengths */ - unsigned have; /* number of code lengths in lens[] */ - code FAR *next; /* next available space in codes[] */ - unsigned short lens[320]; /* temporary storage for code lengths */ - unsigned short work[288]; /* work area for code table building */ - code codes[ENOUGH]; /* space for code tables */ - int sane; /* if false, allow invalid distance too far */ - int back; /* bits back of last unprocessed length/lit */ - unsigned was; /* initial length of match */ +struct inflate_state +{ + inflate_mode mode; /* current inflate mode */ + int last; /* true if processing last block */ + int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ + int havedict; /* true if dictionary provided */ + int flags; /* gzip header method and flags (0 if zlib) */ + unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ + unsigned long check; /* protected copy of check value */ + unsigned long total; /* protected copy of output count */ + gz_headerp head; /* where to save gzip header information */ + /* sliding window */ + unsigned wbits; /* log base 2 of requested window size */ + unsigned wsize; /* window size or zero if not using window */ + unsigned whave; /* valid bytes in the window */ + unsigned wnext; /* window write index */ + unsigned char FAR *window; /* allocated sliding window, if needed */ + /* bit accumulator */ + unsigned long hold; /* input bit accumulator */ + unsigned bits; /* number of bits in "in" */ + /* for string and stored block copying */ + unsigned length; /* literal or length of data to copy */ + unsigned offset; /* distance back to copy string from */ + /* for table and code decoding */ + unsigned extra; /* extra bits needed */ + /* fixed and dynamic code tables */ + code const FAR *lencode; /* starting table for length/literal codes */ + code const FAR *distcode; /* starting table for distance codes */ + unsigned lenbits; /* index bits for lencode */ + unsigned distbits; /* index bits for distcode */ + /* dynamic table building */ + unsigned ncode; /* number of code length code lengths */ + unsigned nlen; /* number of length code lengths */ + unsigned ndist; /* number of distance code lengths */ + unsigned have; /* number of code lengths in lens[] */ + code FAR *next; /* next available space in codes[] */ + unsigned short lens[320]; /* temporary storage for code lengths */ + unsigned short work[288]; /* work area for code table building */ + code codes[ENOUGH]; /* space for code tables */ + int sane; /* if false, allow invalid distance too far */ + int back; /* bits back of last unprocessed length/lit */ + unsigned was; /* initial length of match */ }; diff --git a/examples/ThirdPartyLibs/zlib/inftrees.c b/examples/ThirdPartyLibs/zlib/inftrees.c index 44d89cf24..a7a8f01a7 100644 --- a/examples/ThirdPartyLibs/zlib/inftrees.c +++ b/examples/ThirdPartyLibs/zlib/inftrees.c @@ -9,7 +9,7 @@ #define MAXBITS 15 const char inflate_copyright[] = - " inflate 1.2.8 Copyright 1995-2013 Mark Adler "; + " inflate 1.2.8 Copyright 1995-2013 Mark Adler "; /* If you use the zlib library in a product, an acknowledgment is welcome in the documentation of your product. If for some reason you cannot @@ -30,49 +30,49 @@ const char inflate_copyright[] = longest code or if it is less than the shortest code. */ int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) -codetype type; + codetype type; unsigned short FAR *lens; unsigned codes; -code FAR * FAR *table; +code FAR *FAR *table; unsigned FAR *bits; unsigned short FAR *work; { - unsigned len; /* a code's length in bits */ - unsigned sym; /* index of code symbols */ - unsigned min, max; /* minimum and maximum code lengths */ - unsigned root; /* number of index bits for root table */ - unsigned curr; /* number of index bits for current table */ - unsigned drop; /* code bits to drop for sub-table */ - int left; /* number of prefix codes available */ - unsigned used; /* code entries in table used */ - unsigned huff; /* Huffman code */ - unsigned incr; /* for incrementing code, index */ - unsigned fill; /* index for replicating entries */ - unsigned low; /* low bits for current root entry */ - unsigned mask; /* mask for low root bits */ - code here; /* table entry for duplication */ - code FAR *next; /* next available space in table */ - const unsigned short FAR *base; /* base value table to use */ - const unsigned short FAR *extra; /* extra bits table to use */ - int end; /* use base and extra for symbol > end */ - unsigned short count[MAXBITS+1]; /* number of codes of each length */ - unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ - static const unsigned short lbase[31] = { /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - static const unsigned short lext[31] = { /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78}; - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0}; - static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64}; + unsigned len; /* a code's length in bits */ + unsigned sym; /* index of code symbols */ + unsigned min, max; /* minimum and maximum code lengths */ + unsigned root; /* number of index bits for root table */ + unsigned curr; /* number of index bits for current table */ + unsigned drop; /* code bits to drop for sub-table */ + int left; /* number of prefix codes available */ + unsigned used; /* code entries in table used */ + unsigned huff; /* Huffman code */ + unsigned incr; /* for incrementing code, index */ + unsigned fill; /* index for replicating entries */ + unsigned low; /* low bits for current root entry */ + unsigned mask; /* mask for low root bits */ + code here; /* table entry for duplication */ + code FAR *next; /* next available space in table */ + const unsigned short FAR *base; /* base value table to use */ + const unsigned short FAR *extra; /* extra bits table to use */ + int end; /* use base and extra for symbol > end */ + unsigned short count[MAXBITS + 1]; /* number of codes of each length */ + unsigned short offs[MAXBITS + 1]; /* offsets in table for each length */ + static const unsigned short lbase[31] = {/* Length codes 257..285 base */ + 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, + 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; + static const unsigned short lext[31] = {/* Length codes 257..285 extra */ + 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, + 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78}; + static const unsigned short dbase[32] = {/* Distance codes 0..29 base */ + 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, + 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, + 8193, 12289, 16385, 24577, 0, 0}; + static const unsigned short dext[32] = {/* Distance codes 0..29 extra */ + 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, + 28, 28, 29, 29, 64, 64}; - /* + /* Process a set of code lengths to create a canonical Huffman code. The code lengths are lens[0..codes-1]. Each length corresponds to the symbols 0..codes-1. The Huffman code is generated by first sorting the @@ -103,50 +103,52 @@ unsigned short FAR *work; decoding tables. */ - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) - count[len] = 0; - for (sym = 0; sym < codes; sym++) - count[lens[sym]]++; + /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ + for (len = 0; len <= MAXBITS; len++) + count[len] = 0; + for (sym = 0; sym < codes; sym++) + count[lens[sym]]++; - /* bound code lengths, force root to be within code lengths */ - root = *bits; - for (max = MAXBITS; max >= 1; max--) - if (count[max] != 0) break; - if (root > max) root = max; - if (max == 0) { /* no symbols to code at all */ - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)1; - here.val = (unsigned short)0; - *(*table)++ = here; /* make a table to force an error */ - *(*table)++ = here; - *bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) - if (count[min] != 0) break; - if (root < min) root = min; + /* bound code lengths, force root to be within code lengths */ + root = *bits; + for (max = MAXBITS; max >= 1; max--) + if (count[max] != 0) break; + if (root > max) root = max; + if (max == 0) + { /* no symbols to code at all */ + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)1; + here.val = (unsigned short)0; + *(*table)++ = here; /* make a table to force an error */ + *(*table)++ = here; + *bits = 1; + return 0; /* no symbols, but wait for decoding to report error */ + } + for (min = 1; min < max; min++) + if (count[min] != 0) break; + if (root < min) root = min; - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) return -1; /* over-subscribed */ - } - if (left > 0 && (type == CODES || max != 1)) - return -1; /* incomplete set */ + /* check for an over-subscribed or incomplete set of lengths */ + left = 1; + for (len = 1; len <= MAXBITS; len++) + { + left <<= 1; + left -= count[len]; + if (left < 0) return -1; /* over-subscribed */ + } + if (left > 0 && (type == CODES || max != 1)) + return -1; /* incomplete set */ - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + count[len]; + /* generate offsets into symbol table for each length for sorting */ + offs[1] = 0; + for (len = 1; len < MAXBITS; len++) + offs[len + 1] = offs[len] + count[len]; - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; + /* sort symbols by length, by symbol order within each length */ + for (sym = 0; sym < codes; sym++) + if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; - /* + /* Create and fill in decoding tables. In this loop, the table being filled is at next and has curr index bits. The code being used is huff with length len. That code is converted to an index by dropping drop @@ -177,130 +179,141 @@ unsigned short FAR *work; in the rest of the decoding tables with invalid code markers. */ - /* set up for code type */ - switch (type) { - case CODES: - base = extra = work; /* dummy value--not used */ - end = 19; - break; - case LENS: - base = lbase; - base -= 257; - extra = lext; - extra -= 257; - end = 256; - break; - default: /* DISTS */ - base = dbase; - extra = dext; - end = -1; - } + /* set up for code type */ + switch (type) + { + case CODES: + base = extra = work; /* dummy value--not used */ + end = 19; + break; + case LENS: + base = lbase; + base -= 257; + extra = lext; + extra -= 257; + end = 256; + break; + default: /* DISTS */ + base = dbase; + extra = dext; + end = -1; + } - /* initialize state for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = *table; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = (unsigned)(-1); /* trigger new sub-table when len > root */ - used = 1U << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ + /* initialize state for loop */ + huff = 0; /* starting code */ + sym = 0; /* starting code symbol */ + len = min; /* starting code length */ + next = *table; /* current table to fill in */ + curr = root; /* current table index bits */ + drop = 0; /* current bits to drop from code for index */ + low = (unsigned)(-1); /* trigger new sub-table when len > root */ + used = 1U << root; /* use root table entries */ + mask = used - 1; /* mask for comparing low */ - /* check available table space */ - if ((type == LENS && used > ENOUGH_LENS) || - (type == DISTS && used > ENOUGH_DISTS)) - return 1; + /* check available table space */ + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) + return 1; - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here.bits = (unsigned char)(len - drop); - if ((int)(work[sym]) < end) { - here.op = (unsigned char)0; - here.val = work[sym]; - } - else if ((int)(work[sym]) > end) { - here.op = (unsigned char)(extra[work[sym]]); - here.val = base[work[sym]]; - } - else { - here.op = (unsigned char)(32 + 64); /* end of block */ - here.val = 0; - } + /* process all codes and make table entries */ + for (;;) + { + /* create table entry */ + here.bits = (unsigned char)(len - drop); + if ((int)(work[sym]) < end) + { + here.op = (unsigned char)0; + here.val = work[sym]; + } + else if ((int)(work[sym]) > end) + { + here.op = (unsigned char)(extra[work[sym]]); + here.val = base[work[sym]]; + } + else + { + here.op = (unsigned char)(32 + 64); /* end of block */ + here.val = 0; + } - /* replicate for those indices with low len bits equal to huff */ - incr = 1U << (len - drop); - fill = 1U << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - next[(huff >> drop) + fill] = here; - } while (fill != 0); + /* replicate for those indices with low len bits equal to huff */ + incr = 1U << (len - drop); + fill = 1U << curr; + min = fill; /* save offset to next table */ + do + { + fill -= incr; + next[(huff >> drop) + fill] = here; + } while (fill != 0); - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; + /* backwards increment the len-bit code huff */ + incr = 1U << (len - 1); + while (huff & incr) + incr >>= 1; + if (incr != 0) + { + huff &= incr - 1; + huff += incr; + } + else + huff = 0; - /* go to next symbol, update count, len */ - sym++; - if (--(count[len]) == 0) { - if (len == max) break; - len = lens[work[sym]]; - } + /* go to next symbol, update count, len */ + sym++; + if (--(count[len]) == 0) + { + if (len == max) break; + len = lens[work[sym]]; + } - /* create new sub-table if needed */ - if (len > root && (huff & mask) != low) { - /* if first time, transition to sub-tables */ - if (drop == 0) - drop = root; + /* create new sub-table if needed */ + if (len > root && (huff & mask) != low) + { + /* if first time, transition to sub-tables */ + if (drop == 0) + drop = root; - /* increment past last table */ - next += min; /* here min is 1 << curr */ + /* increment past last table */ + next += min; /* here min is 1 << curr */ - /* determine length of next table */ - curr = len - drop; - left = (int)(1 << curr); - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) break; - curr++; - left <<= 1; - } + /* determine length of next table */ + curr = len - drop; + left = (int)(1 << curr); + while (curr + drop < max) + { + left -= count[curr + drop]; + if (left <= 0) break; + curr++; + left <<= 1; + } - /* check for enough space */ - used += 1U << curr; - if ((type == LENS && used > ENOUGH_LENS) || - (type == DISTS && used > ENOUGH_DISTS)) - return 1; + /* check for enough space */ + used += 1U << curr; + if ((type == LENS && used > ENOUGH_LENS) || + (type == DISTS && used > ENOUGH_DISTS)) + return 1; - /* point entry in root table to sub-table */ - low = huff & mask; - (*table)[low].op = (unsigned char)curr; - (*table)[low].bits = (unsigned char)root; - (*table)[low].val = (unsigned short)(next - *table); - } - } + /* point entry in root table to sub-table */ + low = huff & mask; + (*table)[low].op = (unsigned char)curr; + (*table)[low].bits = (unsigned char)root; + (*table)[low].val = (unsigned short)(next - *table); + } + } - /* fill in remaining table entry if code is incomplete (guaranteed to have + /* fill in remaining table entry if code is incomplete (guaranteed to have at most one remaining entry, since if the code is incomplete, the maximum code length that was allowed to get this far is one bit) */ - if (huff != 0) { - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)(len - drop); - here.val = (unsigned short)0; - next[huff] = here; - } + if (huff != 0) + { + here.op = (unsigned char)64; /* invalid code marker */ + here.bits = (unsigned char)(len - drop); + here.val = (unsigned short)0; + next[huff] = here; + } - /* set return parameters */ - *table += used; - *bits = root; - return 0; + /* set return parameters */ + *table += used; + *bits = root; + return 0; } diff --git a/examples/ThirdPartyLibs/zlib/inftrees.h b/examples/ThirdPartyLibs/zlib/inftrees.h index baa53a0b1..827596032 100644 --- a/examples/ThirdPartyLibs/zlib/inftrees.h +++ b/examples/ThirdPartyLibs/zlib/inftrees.h @@ -21,10 +21,11 @@ of the bit buffer. val is the actual byte to output in the case of a literal, the base length or distance, or the offset from the current table to the next table. Each entry is four bytes. */ -typedef struct { - unsigned char op; /* operation, extra bits, table bits */ - unsigned char bits; /* bits in this part of the code */ - unsigned short val; /* offset in table or code value */ +typedef struct +{ + unsigned char op; /* operation, extra bits, table bits */ + unsigned char bits; /* bits in this part of the code */ + unsigned short val; /* offset in table or code value */ } code; /* op values as set by inflate_table(): @@ -48,15 +49,16 @@ typedef struct { updated. */ #define ENOUGH_LENS 852 #define ENOUGH_DISTS 592 -#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) +#define ENOUGH (ENOUGH_LENS + ENOUGH_DISTS) /* Type of code to build for inflate_table() */ -typedef enum { - CODES, - LENS, - DISTS +typedef enum +{ + CODES, + LENS, + DISTS } codetype; int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work)); + unsigned codes, code FAR *FAR *table, + unsigned FAR *bits, unsigned short FAR *work)); diff --git a/examples/ThirdPartyLibs/zlib/trees.c b/examples/ThirdPartyLibs/zlib/trees.c index 1fd7759ef..792c92ef5 100644 --- a/examples/ThirdPartyLibs/zlib/trees.c +++ b/examples/ThirdPartyLibs/zlib/trees.c @@ -37,7 +37,7 @@ #include "deflate.h" #ifdef DEBUG -# include +#include #endif /* =========================================================================== @@ -50,26 +50,25 @@ #define END_BLOCK 256 /* end of block literal code */ -#define REP_3_6 16 +#define REP_3_6 16 /* repeat previous bit length 3-6 times (2 bits of repeat count) */ -#define REPZ_3_10 17 +#define REPZ_3_10 17 /* repeat a zero length 3-10 times (3 bits of repeat count) */ -#define REPZ_11_138 18 +#define REPZ_11_138 18 /* repeat a zero length 11-138 times (7 bits of repeat count) */ local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; + = {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0}; local const int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; + = {0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; -local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; +local const int extra_blbits[BL_CODES] /* extra bits for each bit length code */ + = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; -local const uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; +local const uch bl_order[BL_CODES] = {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; /* The lengths of the bit length codes are sent in order of decreasing * probability, to avoid transmitting the lengths for unused bit length codes. */ @@ -78,12 +77,12 @@ local const uch bl_order[BL_CODES] * Local data. These are initialized only once. */ -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ +#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ #if defined(GEN_TREES_H) || !defined(STDC) /* non ANSI compilers may not accept trees.h */ -local ct_data static_ltree[L_CODES+2]; +local ct_data static_ltree[L_CODES + 2]; /* The static literal tree. Since the bit lengths are imposed, there is no * need for the L_CODES extra codes used during heap construction. However * The codes 286 and 287 are needed to build a canonical tree (see _tr_init @@ -101,7 +100,7 @@ uch _dist_code[DIST_CODE_LEN]; * the 15 bit distances. */ -uch _length_code[MAX_MATCH-MIN_MATCH+1]; +uch _length_code[MAX_MATCH - MIN_MATCH + 1]; /* length code for each normalized match length (0 == MIN_MATCH) */ local int base_length[LENGTH_CODES]; @@ -111,121 +110,131 @@ local int base_dist[D_CODES]; /* First normalized distance for each code (0 = distance of 1) */ #else -# include "trees.h" +#include "trees.h" #endif /* GEN_TREES_H */ -struct static_tree_desc_s { - const ct_data *static_tree; /* static tree or NULL */ - const intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ +struct static_tree_desc_s +{ + const ct_data *static_tree; /* static tree or NULL */ + const intf *extra_bits; /* extra bits for each code or NULL */ + int extra_base; /* base index for extra_bits */ + int elems; /* max number of elements in the tree */ + int max_length; /* max bit length for the codes */ }; -local static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; +local static_tree_desc static_l_desc = + {static_ltree, extra_lbits, LITERALS + 1, L_CODES, MAX_BITS}; -local static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; +local static_tree_desc static_d_desc = + {static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; -local static_tree_desc static_bl_desc = -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; +local static_tree_desc static_bl_desc = + {(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; /* =========================================================================== * Local (static) routines in this file. */ local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, const ct_data *ltree, - const ct_data *dtree)); -local int detect_data_type OF((deflate_state *s)); +local void init_block OF((deflate_state * s)); +local void pqdownheap OF((deflate_state * s, ct_data *tree, int k)); +local void gen_bitlen OF((deflate_state * s, tree_desc *desc)); +local void gen_codes OF((ct_data * tree, int max_code, ushf *bl_count)); +local void build_tree OF((deflate_state * s, tree_desc *desc)); +local void scan_tree OF((deflate_state * s, ct_data *tree, int max_code)); +local void send_tree OF((deflate_state * s, ct_data *tree, int max_code)); +local int build_bl_tree OF((deflate_state * s)); +local void send_all_trees OF((deflate_state * s, int lcodes, int dcodes, + int blcodes)); +local void compress_block OF((deflate_state * s, const ct_data *ltree, + const ct_data *dtree)); +local int detect_data_type OF((deflate_state * s)); local unsigned bi_reverse OF((unsigned value, int length)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); -local void copy_block OF((deflate_state *s, charf *buf, unsigned len, - int header)); +local void bi_windup OF((deflate_state * s)); +local void bi_flush OF((deflate_state * s)); +local void copy_block OF((deflate_state * s, charf *buf, unsigned len, + int header)); #ifdef GEN_TREES_H local void gen_trees_header OF((void)); #endif #ifndef DEBUG -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ +#define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) +/* Send a code of the given tree. c and tree must not have side effects */ #else /* DEBUG */ -# define send_code(s, c, tree) \ - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } +#define send_code(s, c, tree) \ + { \ + if (z_verbose > 2) fprintf(stderr, "\ncd %3d ", (c)); \ + send_bits(s, tree[c].Code, tree[c].Len); \ + } #endif /* =========================================================================== * Output a short LSB first on the stream. * IN assertion: there is enough room in pendingBuf. */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} +#define put_short(s, w) \ + { \ + put_byte(s, (uch)((w)&0xff)); \ + put_byte(s, (uch)((ush)(w) >> 8)); \ + } /* =========================================================================== * Send a value on a given number of bits. * IN assertion: length <= 16 and value fits in length bits. */ #ifdef DEBUG -local void send_bits OF((deflate_state *s, int value, int length)); +local void send_bits OF((deflate_state * s, int value, int length)); local void send_bits(s, value, length) - deflate_state *s; - int value; /* value to send */ - int length; /* number of bits */ + deflate_state *s; +int value; /* value to send */ +int length; /* number of bits */ { - Tracevv((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; + Tracevv((stderr, " l %2d v %4x ", length, value)); + Assert(length > 0 && length <= 15, "invalid length"); + s->bits_sent += (ulg)length; - /* If not enough room in bi_buf, use (valid) bits from bi_buf and + /* If not enough room in bi_buf, use (valid) bits from bi_buf and * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) * unused bits in value. */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (ush)value << s->bi_valid; - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= (ush)value << s->bi_valid; - s->bi_valid += length; - } + if (s->bi_valid > (int)Buf_size - length) + { + s->bi_buf |= (ush)value << s->bi_valid; + put_short(s, s->bi_buf); + s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); + s->bi_valid += length - Buf_size; + } + else + { + s->bi_buf |= (ush)value << s->bi_valid; + s->bi_valid += length; + } } #else /* !DEBUG */ -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = value;\ - s->bi_buf |= (ush)val << s->bi_valid;\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (ush)(value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} +#define send_bits(s, value, length) \ + { \ + int len = length; \ + if (s->bi_valid > (int)Buf_size - len) \ + { \ + int val = value; \ + s->bi_buf |= (ush)val << s->bi_valid; \ + put_short(s, s->bi_buf); \ + s->bi_buf = (ush)val >> (Buf_size - s->bi_valid); \ + s->bi_valid += len - Buf_size; \ + } \ + else \ + { \ + s->bi_buf |= (ush)(value) << s->bi_valid; \ + s->bi_valid += len; \ + } \ + } #endif /* DEBUG */ - /* the arguments must not have side effects */ /* =========================================================================== @@ -234,82 +243,89 @@ local void send_bits(s, value, length) local void tr_static_init() { #if defined(GEN_TREES_H) || !defined(STDC) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ + static int static_init_done = 0; + int n; /* iterates over tree elements */ + int bits; /* bit counter */ + int length; /* length value */ + int code; /* code value */ + int dist; /* distance index */ + ush bl_count[MAX_BITS + 1]; + /* number of codes at each bit length for an optimal tree */ - if (static_init_done) return; + if (static_init_done) return; - /* For some embedded targets, global variables are not initialized: */ + /* For some embedded targets, global variables are not initialized: */ #ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; + static_l_desc.static_tree = static_ltree; + static_l_desc.extra_bits = extra_lbits; + static_d_desc.static_tree = static_dtree; + static_d_desc.extra_bits = extra_dbits; + static_bl_desc.extra_bits = extra_blbits; #endif - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1< length code (0..28) */ + length = 0; + for (code = 0; code < LENGTH_CODES - 1; code++) + { + base_length[code] = length; + for (n = 0; n < (1 << extra_lbits[code]); n++) + { + _length_code[length++] = (uch)code; + } + } + Assert(length == 256, "tr_static_init: length != 256"); + /* Note that the length 255 (match length 258) can be represented * in two different ways: code 284 + 5 bits or code 285, so we * overwrite length_code[255] to use the best encoding: */ - _length_code[length-1] = (uch)code; + _length_code[length - 1] = (uch)code; - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { - _dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256+dist != 512"); + /* Initialize the mapping dist (0..32K) -> dist code (0..29) */ + dist = 0; + for (code = 0; code < 16; code++) + { + base_dist[code] = dist; + for (n = 0; n < (1 << extra_dbits[code]); n++) + { + _dist_code[dist++] = (uch)code; + } + } + Assert(dist == 256, "tr_static_init: dist != 256"); + dist >>= 7; /* from now on, all distances are divided by 128 */ + for (; code < D_CODES; code++) + { + base_dist[code] = dist << 7; + for (n = 0; n < (1 << (extra_dbits[code] - 7)); n++) + { + _dist_code[256 + dist++] = (uch)code; + } + } + Assert(dist == 256, "tr_static_init: 256+dist != 512"); - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the + /* Construct the codes of the static literal tree */ + for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; + n = 0; + while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; + while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; + while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; + while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; + /* Codes 286 and 287 do not exist, but we must include them in the * tree construction to get a canonical Huffman tree (longest code * all ones) */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); + gen_codes((ct_data *)static_ltree, L_CODES + 1, bl_count); - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; + /* The static distance tree is trivial: */ + for (n = 0; n < D_CODES; n++) + { + static_dtree[n].Len = 5; + static_dtree[n].Code = bi_reverse((unsigned)n, 5); + } + static_init_done = 1; -# ifdef GEN_TREES_H - gen_trees_header(); -# endif +#ifdef GEN_TREES_H + gen_trees_header(); +#endif #endif /* defined(GEN_TREES_H) || !defined(STDC) */ } @@ -317,61 +333,66 @@ local void tr_static_init() * Genererate the file trees.h describing the static trees. */ #ifdef GEN_TREES_H -# ifndef DEBUG -# include -# endif +#ifndef DEBUG +#include +#endif -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width)-1 ? ",\n" : ", ")) +#define SEPARATOR(i, last, width) \ + ((i) == (last) ? "\n};\n\n" : ((i) % (width) == (width)-1 ? ",\n" : ", ")) void gen_trees_header() { - FILE *header = fopen("trees.h", "w"); - int i; + FILE *header = fopen("trees.h", "w"); + int i; - Assert (header != NULL, "Can't open trees.h"); - fprintf(header, - "/* header created automatically with -DGEN_TREES_H */\n\n"); + Assert(header != NULL, "Can't open trees.h"); + fprintf(header, + "/* header created automatically with -DGEN_TREES_H */\n\n"); - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES+2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, - static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); - } + fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); + for (i = 0; i < L_CODES + 2; i++) + { + fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, + static_ltree[i].Len, SEPARATOR(i, L_CODES + 1, 5)); + } - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, - static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); - } + fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) + { + fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, + static_dtree[i].Len, SEPARATOR(i, D_CODES - 1, 5)); + } - fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", _dist_code[i], - SEPARATOR(i, DIST_CODE_LEN-1, 20)); - } + fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); + for (i = 0; i < DIST_CODE_LEN; i++) + { + fprintf(header, "%2u%s", _dist_code[i], + SEPARATOR(i, DIST_CODE_LEN - 1, 20)); + } - fprintf(header, - "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { - fprintf(header, "%2u%s", _length_code[i], - SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); - } + fprintf(header, + "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); + for (i = 0; i < MAX_MATCH - MIN_MATCH + 1; i++) + { + fprintf(header, "%2u%s", _length_code[i], + SEPARATOR(i, MAX_MATCH - MIN_MATCH, 20)); + } - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%1u%s", base_length[i], - SEPARATOR(i, LENGTH_CODES-1, 20)); - } + fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); + for (i = 0; i < LENGTH_CODES; i++) + { + fprintf(header, "%1u%s", base_length[i], + SEPARATOR(i, LENGTH_CODES - 1, 20)); + } - fprintf(header, "local const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5u%s", base_dist[i], - SEPARATOR(i, D_CODES-1, 10)); - } + fprintf(header, "local const int base_dist[D_CODES] = {\n"); + for (i = 0; i < D_CODES; i++) + { + fprintf(header, "%5u%s", base_dist[i], + SEPARATOR(i, D_CODES - 1, 10)); + } - fclose(header); + fclose(header); } #endif /* GEN_TREES_H */ @@ -379,70 +400,69 @@ void gen_trees_header() * Initialize the tree data structures for a new zlib stream. */ void ZLIB_INTERNAL _tr_init(s) - deflate_state *s; + deflate_state *s; { - tr_static_init(); + tr_static_init(); - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; + s->l_desc.dyn_tree = s->dyn_ltree; + s->l_desc.stat_desc = &static_l_desc; - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; + s->d_desc.dyn_tree = s->dyn_dtree; + s->d_desc.stat_desc = &static_d_desc; - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; + s->bl_desc.dyn_tree = s->bl_tree; + s->bl_desc.stat_desc = &static_bl_desc; - s->bi_buf = 0; - s->bi_valid = 0; + s->bi_buf = 0; + s->bi_valid = 0; #ifdef DEBUG - s->compressed_len = 0L; - s->bits_sent = 0L; + s->compressed_len = 0L; + s->bits_sent = 0L; #endif - /* Initialize the first block of the first file: */ - init_block(s); + /* Initialize the first block of the first file: */ + init_block(s); } /* =========================================================================== * Initialize a new block. */ local void init_block(s) - deflate_state *s; + deflate_state *s; { - int n; /* iterates over tree elements */ + int n; /* iterates over tree elements */ - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; + /* Initialize the trees. */ + for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; + for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; + for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->last_lit = s->matches = 0; + s->dyn_ltree[END_BLOCK].Freq = 1; + s->opt_len = s->static_len = 0L; + s->last_lit = s->matches = 0; } #define SMALLEST 1 /* Index within the heap array of least frequent node in the Huffman tree */ - /* =========================================================================== * Remove the smallest element from the heap and recreate the heap with * one less element. Updates heap and heap_len. */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} +#define pqremove(s, tree, top) \ + { \ + top = s->heap[SMALLEST]; \ + s->heap[SMALLEST] = s->heap[s->heap_len--]; \ + pqdownheap(s, tree, SMALLEST); \ + } /* =========================================================================== * Compares to subtrees, using the tree depth as tie breaker when * the subtrees have equal frequency. This minimizes the worst case length. */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) +#define smaller(tree, n, m, depth) \ + (tree[n].Freq < tree[m].Freq || \ + (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) /* =========================================================================== * Restore the heap property by moving down the tree starting at node k, @@ -451,28 +471,31 @@ local void init_block(s) * two sons). */ local void pqdownheap(s, tree, k) - deflate_state *s; - ct_data *tree; /* the tree to restore */ - int k; /* node to move down */ + deflate_state *s; +ct_data *tree; /* the tree to restore */ +int k; /* node to move down */ { - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; + int v = s->heap[k]; + int j = k << 1; /* left son of k */ + while (j <= s->heap_len) + { + /* Set j to the smallest of the two sons: */ + if (j < s->heap_len && + smaller(tree, s->heap[j + 1], s->heap[j], s->depth)) + { + j++; + } + /* Exit if v is smaller than both sons */ + if (smaller(tree, v, s->heap[j], s->depth)) break; - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; + /* Exchange v with the smallest son */ + s->heap[k] = s->heap[j]; + k = j; - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; + /* And continue down the tree, setting j to the left son of k */ + j <<= 1; + } + s->heap[k] = v; } /* =========================================================================== @@ -486,82 +509,86 @@ local void pqdownheap(s, tree, k) * not null. */ local void gen_bitlen(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ + deflate_state *s; +tree_desc *desc; /* the tree descriptor */ { - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - const ct_data *stree = desc->stat_desc->static_tree; - const intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ + ct_data *tree = desc->dyn_tree; + int max_code = desc->max_code; + const ct_data *stree = desc->stat_desc->static_tree; + const intf *extra = desc->stat_desc->extra_bits; + int base = desc->stat_desc->extra_base; + int max_length = desc->stat_desc->max_length; + int h; /* heap index */ + int n, m; /* iterate over the tree elements */ + int bits; /* bit length */ + int xbits; /* extra bits */ + ush f; /* frequency */ + int overflow = 0; /* number of elements with bit length too large */ - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; + for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - /* In a first pass, compute the optimal bit lengths (which may + /* In a first pass, compute the optimal bit lengths (which may * overflow in the case of the bit length tree). */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ + tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - for (h = s->heap_max+1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ + for (h = s->heap_max + 1; h < HEAP_SIZE; h++) + { + n = s->heap[h]; + bits = tree[tree[n].Dad].Len + 1; + if (bits > max_length) bits = max_length, overflow++; + tree[n].Len = (ush)bits; + /* We overwrite tree[n].Dad which is no longer needed */ - if (n > max_code) continue; /* not a leaf node */ + if (n > max_code) continue; /* not a leaf node */ - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (bits + xbits); - if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); - } - if (overflow == 0) return; + s->bl_count[bits]++; + xbits = 0; + if (n >= base) xbits = extra[n - base]; + f = tree[n].Freq; + s->opt_len += (ulg)f * (bits + xbits); + if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); + } + if (overflow == 0) return; - Trace((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ + Trace((stderr, "\nbit length overflow\n")); + /* This happens for example on obj2 and pic of the Calgary corpus */ - /* Find the first bit length which could increase: */ - do { - bits = max_length-1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, + /* Find the first bit length which could increase: */ + do + { + bits = max_length - 1; + while (s->bl_count[bits] == 0) bits--; + s->bl_count[bits]--; /* move one leaf down the tree */ + s->bl_count[bits + 1] += 2; /* move one overflow item as its brother */ + s->bl_count[max_length]--; + /* The brother of the overflow item also moves one step up, * but this does not affect bl_count[max_length] */ - overflow -= 2; - } while (overflow > 0); + overflow -= 2; + } while (overflow > 0); - /* Now recompute all bit lengths, scanning in increasing frequency. + /* Now recompute all bit lengths, scanning in increasing frequency. * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all * lengths instead of fixing only the wrong ones. This idea is taken * from 'ar' written by Haruhiko Okumura.) */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if ((unsigned) tree[m].Len != (unsigned) bits) { - Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((long)bits - (long)tree[m].Len) - *(long)tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } + for (bits = max_length; bits != 0; bits--) + { + n = s->bl_count[bits]; + while (n != 0) + { + m = s->heap[--h]; + if (m > max_code) continue; + if ((unsigned)tree[m].Len != (unsigned)bits) + { + Trace((stderr, "code %d bits %d->%d\n", m, tree[m].Len, bits)); + s->opt_len += ((long)bits - (long)tree[m].Len) * (long)tree[m].Freq; + tree[m].Len = (ush)bits; + } + n--; + } + } } /* =========================================================================== @@ -572,38 +599,40 @@ local void gen_bitlen(s, desc) * OUT assertion: the field code is set for all tree elements of non * zero code length. */ -local void gen_codes (tree, max_code, bl_count) - ct_data *tree; /* the tree to decorate */ - int max_code; /* largest code with non zero frequency */ - ushf *bl_count; /* number of codes at each bit length */ +local void gen_codes(tree, max_code, bl_count) + ct_data *tree; /* the tree to decorate */ +int max_code; /* largest code with non zero frequency */ +ushf *bl_count; /* number of codes at each bit length */ { - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - ush code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ + ush next_code[MAX_BITS + 1]; /* next code value for each bit length */ + ush code = 0; /* running code value */ + int bits; /* bit index */ + int n; /* code index */ - /* The distribution counts are first used to generate the code values + /* The distribution counts are first used to generate the code values * without bit reversal. */ - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (code + bl_count[bits-1]) << 1; - } - /* Check that the bit counts in bl_count are consistent. The last code + for (bits = 1; bits <= MAX_BITS; bits++) + { + next_code[bits] = code = (code + bl_count[bits - 1]) << 1; + } + /* Check that the bit counts in bl_count are consistent. The last code * must be all ones. */ - Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; - const ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ + ct_data *tree = desc->dyn_tree; + const ct_data *stree = desc->stat_desc->static_tree; + int elems = desc->stat_desc->elems; + int n, m; /* iterate over heap elements */ + int max_code = -1; /* largest code with non zero frequency */ + int node; /* new node being created */ - /* Construct the initial heap, with least frequent element in + /* Construct the initial heap, with least frequent element in * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. * heap[0] is not used. */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; + s->heap_len = 0, s->heap_max = HEAP_SIZE; - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } + for (n = 0; n < elems; n++) + { + if (tree[n].Freq != 0) + { + s->heap[++(s->heap_len)] = max_code = n; + s->depth[n] = 0; + } + else + { + tree[n].Len = 0; + } + } - /* The pkzip format requires that at least one distance code exists, + /* The pkzip format requires that at least one distance code exists, * and that at least one bit should be sent even if there is only one * possible code. So to avoid special checks later on we force at least * two codes of non zero frequency. */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; + while (s->heap_len < 2) + { + node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); + tree[node].Freq = 1; + s->depth[node] = 0; + s->opt_len--; + if (stree) s->static_len -= stree[node].Len; + /* node is 0 or 1 so it does not have extra bits */ + } + desc->max_code = max_code; - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, + /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, * establish sub-heaps of increasing lengths: */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); + for (n = s->heap_len / 2; n >= 1; n--) pqdownheap(s, tree, n); - /* Construct the Huffman tree by repeatedly combining the least two + /* Construct the Huffman tree by repeatedly combining the least two * frequent nodes. */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ + node = elems; /* next internal node of the tree */ + do + { + pqremove(s, tree, n); /* n = node of least frequency */ + m = s->heap[SMALLEST]; /* m = node of next least frequency */ - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; + s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ + s->heap[--(s->heap_max)] = m; - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? - s->depth[n] : s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; + /* Create a new node father of n and m */ + tree[node].Freq = tree[n].Freq + tree[m].Freq; + s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? s->depth[n] : s->depth[m]) + 1); + tree[n].Dad = tree[m].Dad = (ush)node; #ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } + if (tree == s->bl_tree) + { + fprintf(stderr, "\nnode %d(%d), sons %d(%d) %d(%d)", + node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); + } #endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); + /* and insert the new node in the heap */ + s->heap[SMALLEST] = node++; + pqdownheap(s, tree, SMALLEST); - } while (s->heap_len >= 2); + } while (s->heap_len >= 2); - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; + s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - /* At this point, the fields freq and dad are set. We can now + /* At this point, the fields freq and dad are set. We can now * generate the bit lengths. */ - gen_bitlen(s, (tree_desc *)desc); + gen_bitlen(s, (tree_desc *)desc); - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); + /* The field len is now set, we can generate the bit codes */ + gen_codes((ct_data *)tree, max_code, s->bl_count); } /* =========================================================================== * Scan a literal or distance tree to determine the frequencies of the codes * in the bit length tree. */ -local void scan_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ +local void scan_tree(s, tree, max_code) + deflate_state *s; +ct_data *tree; /* the tree to be scanned */ +int max_code; /* and its largest code of non zero frequency */ { - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code+1].Len = (ush)0xffff; /* guard */ + if (nextlen == 0) max_count = 138, min_count = 3; + tree[max_code + 1].Len = (ush)0xffff; /* guard */ - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } + for (n = 0; n <= max_code; n++) + { + curlen = nextlen; + nextlen = tree[n + 1].Len; + if (++count < max_count && curlen == nextlen) + { + continue; + } + else if (count < min_count) + { + s->bl_tree[curlen].Freq += count; + } + else if (curlen != 0) + { + if (curlen != prevlen) s->bl_tree[curlen].Freq++; + s->bl_tree[REP_3_6].Freq++; + } + else if (count <= 10) + { + s->bl_tree[REPZ_3_10].Freq++; + } + else + { + s->bl_tree[REPZ_11_138].Freq++; + } + count = 0; + prevlen = curlen; + if (nextlen == 0) + { + max_count = 138, min_count = 3; + } + else if (curlen == nextlen) + { + max_count = 6, min_count = 3; + } + else + { + max_count = 7, min_count = 4; + } + } } /* =========================================================================== * Send a literal or distance tree in compressed form, using the codes in * bl_tree. */ -local void send_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ +local void send_tree(s, tree, max_code) + deflate_state *s; +ct_data *tree; /* the tree to be scanned */ +int max_code; /* and its largest code of non zero frequency */ { - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ + int n; /* iterates over all tree elements */ + int prevlen = -1; /* last emitted length */ + int curlen; /* length of current code */ + int nextlen = tree[0].Len; /* length of next code */ + int count = 0; /* repeat count of the current code */ + int max_count = 7; /* max repeat count */ + int min_count = 4; /* min repeat count */ - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; + /* tree[max_code+1].Len = -1; */ /* guard already set */ + if (nextlen == 0) max_count = 138, min_count = 3; - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } + for (n = 0; n <= max_code; n++) + { + curlen = nextlen; + nextlen = tree[n + 1].Len; + if (++count < max_count && curlen == nextlen) + { + continue; + } + else if (count < min_count) + { + do + { + send_code(s, curlen, s->bl_tree); + } while (--count != 0); + } + else if (curlen != 0) + { + if (curlen != prevlen) + { + send_code(s, curlen, s->bl_tree); + count--; + } + Assert(count >= 3 && count <= 6, " 3_6?"); + send_code(s, REP_3_6, s->bl_tree); + send_bits(s, count - 3, 2); + } + else if (count <= 10) + { + send_code(s, REPZ_3_10, s->bl_tree); + send_bits(s, count - 3, 3); + } + else + { + send_code(s, REPZ_11_138, s->bl_tree); + send_bits(s, count - 11, 7); + } + count = 0; + prevlen = curlen; + if (nextlen == 0) + { + max_count = 138, min_count = 3; + } + else if (curlen == nextlen) + { + max_count = 6, min_count = 3; + } + else + { + max_count = 7, min_count = 4; + } + } } /* =========================================================================== @@ -799,33 +874,34 @@ local void send_tree (s, tree, max_code) * bl_order of the last bit length code to send. */ local int build_bl_tree(s) - deflate_state *s; + deflate_state *s; { - int max_blindex; /* index of last bit length code of non zero freq */ + int max_blindex; /* index of last bit length code of non zero freq */ - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); + /* Determine the bit length frequencies for literal and distance trees */ + scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); + scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except + /* Build the bit length tree: */ + build_tree(s, (tree_desc *)(&(s->bl_desc))); + /* opt_len now includes the length of the tree representations, except * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. */ - /* Determine the number of bit length codes to send. The pkzip format + /* Determine the number of bit length codes to send. The pkzip format * requires that at least 4 bit length codes be sent. (appnote.txt says * 3 but the actual value used is 4.) */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*(max_blindex+1) + 5+5+4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); + for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) + { + if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; + } + /* Update opt_len to include the bit length tree and counts */ + s->opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4; + Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", + s->opt_len, s->static_len)); - return max_blindex; + return max_blindex; } /* =========================================================================== @@ -834,55 +910,56 @@ local int build_bl_tree(s) * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. */ local void send_all_trees(s, lcodes, dcodes, blcodes) - deflate_state *s; - int lcodes, dcodes, blcodes; /* number of codes for each tree */ + deflate_state *s; +int lcodes, dcodes, blcodes; /* number of codes for each tree */ { - int rank; /* index in bl_order */ + int rank; /* index in bl_order */ - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes-1, 5); - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); + Assert(lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); + Assert(lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, + "too many codes"); + Tracev((stderr, "\nbl counts: ")); + send_bits(s, lcodes - 257, 5); /* not +255 as stated in appnote.txt */ + send_bits(s, dcodes - 1, 5); + send_bits(s, blcodes - 4, 4); /* not -3 as stated in appnote.txt */ + for (rank = 0; rank < blcodes; rank++) + { + Tracev((stderr, "\nbl code %2d ", bl_order[rank])); + send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); + } + Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); + send_tree(s, (ct_data *)s->dyn_ltree, lcodes - 1); /* literal tree */ + Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); + send_tree(s, (ct_data *)s->dyn_dtree, dcodes - 1); /* distance tree */ + Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); } /* =========================================================================== * Send a stored block */ void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ + deflate_state *s; +charf *buf; /* input block */ +ulg stored_len; /* length of input block */ +int last; /* one if this is the last block for a file */ { - send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ + send_bits(s, (STORED_BLOCK << 1) + last, 3); /* send block type */ #ifdef DEBUG - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; + s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; + s->compressed_len += (stored_len + 4) << 3; #endif - copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ + copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ } /* =========================================================================== * Flush the bits in the bit buffer to pending output (leaves at most 7 bits) */ void ZLIB_INTERNAL _tr_flush_bits(s) - deflate_state *s; + deflate_state *s; { - bi_flush(s); + bi_flush(s); } /* =========================================================================== @@ -890,14 +967,14 @@ void ZLIB_INTERNAL _tr_flush_bits(s) * This takes 10 bits, of which 7 may remain in the bit buffer. */ void ZLIB_INTERNAL _tr_align(s) - deflate_state *s; + deflate_state *s; { - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); + send_bits(s, STATIC_TREES << 1, 3); + send_code(s, END_BLOCK, static_ltree); #ifdef DEBUG - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ + s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ #endif - bi_flush(s); + bi_flush(s); } /* =========================================================================== @@ -905,150 +982,166 @@ void ZLIB_INTERNAL _tr_align(s) * trees or store, and output the encoded block to the zip file. */ void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block, or NULL if too old */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ + deflate_state *s; +charf *buf; /* input block, or NULL if too old */ +ulg stored_len; /* length of input block */ +int last; /* one if this is the last block for a file */ { - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ + ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ + int max_blindex = 0; /* index of last bit length code of non zero freq */ - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { + /* Build the Huffman trees unless a stored block is forced */ + if (s->level > 0) + { + /* Check if the file is binary or text */ + if (s->strm->data_type == Z_UNKNOWN) + s->strm->data_type = detect_data_type(s); - /* Check if the file is binary or text */ - if (s->strm->data_type == Z_UNKNOWN) - s->strm->data_type = detect_data_type(s); + /* Construct the literal and distance trees */ + build_tree(s, (tree_desc *)(&(s->l_desc))); + Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of + build_tree(s, (tree_desc *)(&(s->d_desc))); + Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, + s->static_len)); + /* At this point, opt_len and static_len are the total bit lengths of * the compressed block data, excluding the tree representations. */ - /* Build the bit length tree for the above two trees, and get the index + /* Build the bit length tree for the above two trees, and get the index * in bl_order of the last bit length code to send. */ - max_blindex = build_bl_tree(s); + max_blindex = build_bl_tree(s); - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s->opt_len+3+7)>>3; - static_lenb = (s->static_len+3+7)>>3; + /* Determine the best encoding. Compute the block lengths in bytes. */ + opt_lenb = (s->opt_len + 3 + 7) >> 3; + static_lenb = (s->static_len + 3 + 7) >> 3; - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->last_lit)); + Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", + opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, + s->last_lit)); - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - - } else { - Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } + if (static_lenb <= opt_lenb) opt_lenb = static_lenb; + } + else + { + Assert(buf != (char *)0, "lost buf"); + opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ + } #ifdef FORCE_STORED - if (buf != (char*)0) { /* force stored block */ + if (buf != (char *)0) + { /* force stored block */ #else - if (stored_len+4 <= opt_lenb && buf != (char*)0) { - /* 4: two words for the lengths */ + if (stored_len + 4 <= opt_lenb && buf != (char *)0) + { + /* 4: two words for the lengths */ #endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. + /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. * Otherwise we can't have processed more than WSIZE input bytes since * the last block flush, because compression would have been * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to * transform a block into a stored block. */ - _tr_stored_block(s, buf, stored_len, last); + _tr_stored_block(s, buf, stored_len, last); #ifdef FORCE_STATIC - } else if (static_lenb >= 0) { /* force static trees */ + } + else if (static_lenb >= 0) + { /* force static trees */ #else - } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { + } + else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) + { #endif - send_bits(s, (STATIC_TREES<<1)+last, 3); - compress_block(s, (const ct_data *)static_ltree, - (const ct_data *)static_dtree); + send_bits(s, (STATIC_TREES << 1) + last, 3); + compress_block(s, (const ct_data *)static_ltree, + (const ct_data *)static_dtree); #ifdef DEBUG - s->compressed_len += 3 + s->static_len; + s->compressed_len += 3 + s->static_len; #endif - } else { - send_bits(s, (DYN_TREES<<1)+last, 3); - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, - max_blindex+1); - compress_block(s, (const ct_data *)s->dyn_ltree, - (const ct_data *)s->dyn_dtree); + } + else + { + send_bits(s, (DYN_TREES << 1) + last, 3); + send_all_trees(s, s->l_desc.max_code + 1, s->d_desc.max_code + 1, + max_blindex + 1); + compress_block(s, (const ct_data *)s->dyn_ltree, + (const ct_data *)s->dyn_dtree); #ifdef DEBUG - s->compressed_len += 3 + s->opt_len; + s->compressed_len += 3 + s->opt_len; #endif - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB + } + Assert(s->compressed_len == s->bits_sent, "bad compressed size"); + /* The above check is made mod 2^32, for files larger than 512 MB * and uLong implemented on 32 bits. */ - init_block(s); + init_block(s); - if (last) { - bi_windup(s); + if (last) + { + bi_windup(s); #ifdef DEBUG - s->compressed_len += 7; /* align on byte boundary */ + s->compressed_len += 7; /* align on byte boundary */ #endif - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*last)); + } + Tracev((stderr, "\ncomprlen %lu(%lu) ", s->compressed_len >> 3, + s->compressed_len - 7 * last)); } /* =========================================================================== * Save the match info and tally the frequency counts. Return true if * the current block must be flushed. */ -int ZLIB_INTERNAL _tr_tally (s, dist, lc) - deflate_state *s; - unsigned dist; /* distance of matched string */ - unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ +int ZLIB_INTERNAL _tr_tally(s, dist, lc) + deflate_state *s; +unsigned dist; /* distance of matched string */ +unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ { - s->d_buf[s->last_lit] = (ush)dist; - s->l_buf[s->last_lit++] = (uch)lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); + s->d_buf[s->last_lit] = (ush)dist; + s->l_buf[s->last_lit++] = (uch)lc; + if (dist == 0) + { + /* lc is the unmatched char */ + s->dyn_ltree[lc].Freq++; + } + else + { + s->matches++; + /* Here, lc is the match length - MIN_MATCH */ + dist--; /* dist = match distance - 1 */ + Assert((ush)dist < (ush)MAX_DIST(s) && + (ush)lc <= (ush)(MAX_MATCH - MIN_MATCH) && + (ush)d_code(dist) < (ush)D_CODES, + "_tr_tally: bad match"); - s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } + s->dyn_ltree[_length_code[lc] + LITERALS + 1].Freq++; + s->dyn_dtree[d_code(dist)].Freq++; + } #ifdef TRUNCATE_BLOCK - /* Try to guess if it is profitable to stop the current block here */ - if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { - /* Compute an upper bound for the compressed length */ - ulg out_length = (ulg)s->last_lit*8L; - ulg in_length = (ulg)((long)s->strstart - s->block_start); - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (ulg)s->dyn_dtree[dcode].Freq * - (5L+extra_dbits[dcode]); - } - out_length >>= 3; - Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - s->last_lit, in_length, out_length, - 100L - out_length*100L/in_length)); - if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; - } + /* Try to guess if it is profitable to stop the current block here */ + if ((s->last_lit & 0x1fff) == 0 && s->level > 2) + { + /* Compute an upper bound for the compressed length */ + ulg out_length = (ulg)s->last_lit * 8L; + ulg in_length = (ulg)((long)s->strstart - s->block_start); + int dcode; + for (dcode = 0; dcode < D_CODES; dcode++) + { + out_length += (ulg)s->dyn_dtree[dcode].Freq * + (5L + extra_dbits[dcode]); + } + out_length >>= 3; + Tracev((stderr, "\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", + s->last_lit, in_length, out_length, + 100L - out_length * 100L / in_length)); + if (s->matches < s->last_lit / 2 && out_length < in_length / 2) return 1; + } #endif - return (s->last_lit == s->lit_bufsize-1); - /* We avoid equality with lit_bufsize because of wraparound at 64K + return (s->last_lit == s->lit_bufsize - 1); + /* We avoid equality with lit_bufsize because of wraparound at 64K * on 16 bit machines and because stored blocks are restricted to * 64K-1 bytes. */ @@ -1058,50 +1151,56 @@ int ZLIB_INTERNAL _tr_tally (s, dist, lc) * Send the block data compressed using the given Huffman trees */ local void compress_block(s, ltree, dtree) - deflate_state *s; - const ct_data *ltree; /* literal tree */ - const ct_data *dtree; /* distance tree */ + deflate_state *s; +const ct_data *ltree; /* literal tree */ +const ct_data *dtree; /* distance tree */ { - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned lx = 0; /* running index in l_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ + unsigned dist; /* distance of matched string */ + int lc; /* match length or unmatched char (if dist == 0) */ + unsigned lx = 0; /* running index in l_buf */ + unsigned code; /* the code to send */ + int extra; /* number of extra bits to send */ - if (s->last_lit != 0) do { - dist = s->d_buf[lx]; - lc = s->l_buf[lx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code+LITERALS+1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); + if (s->last_lit != 0) do + { + dist = s->d_buf[lx]; + lc = s->l_buf[lx++]; + if (dist == 0) + { + send_code(s, lc, ltree); /* send a literal byte */ + Tracecv(isgraph(lc), (stderr, " '%c' ", lc)); + } + else + { + /* Here, lc is the match length - MIN_MATCH */ + code = _length_code[lc]; + send_code(s, code + LITERALS + 1, ltree); /* send the length code */ + extra = extra_lbits[code]; + if (extra != 0) + { + lc -= base_length[code]; + send_bits(s, lc, extra); /* send the extra length bits */ + } + dist--; /* dist is now the match distance - 1 */ + code = d_code(dist); + Assert(code < D_CODES, "bad d_code"); - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ + send_code(s, code, dtree); /* send the distance code */ + extra = extra_dbits[code]; + if (extra != 0) + { + dist -= base_dist[code]; + send_bits(s, dist, extra); /* send the extra distance bits */ + } + } /* literal or match pair ? */ - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, - "pendingBuf overflow"); + /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ + Assert((uInt)(s->pending) < s->lit_bufsize + 2 * lx, + "pendingBuf overflow"); - } while (lx < s->last_lit); + } while (lx < s->last_lit); - send_code(s, END_BLOCK, ltree); + send_code(s, END_BLOCK, ltree); } /* =========================================================================== @@ -1118,32 +1217,31 @@ local void compress_block(s, ltree, dtree) * IN assertion: the fields Freq of dyn_ltree are set. */ local int detect_data_type(s) - deflate_state *s; + deflate_state *s; { - /* black_mask is the bit mask of black-listed bytes + /* black_mask is the bit mask of black-listed bytes * set bits 0..6, 14..25, and 28..31 * 0xf3ffc07f = binary 11110011111111111100000001111111 */ - unsigned long black_mask = 0xf3ffc07fUL; - int n; + unsigned long black_mask = 0xf3ffc07fUL; + int n; - /* Check for non-textual ("black-listed") bytes. */ - for (n = 0; n <= 31; n++, black_mask >>= 1) - if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) - return Z_BINARY; + /* Check for non-textual ("black-listed") bytes. */ + for (n = 0; n <= 31; n++, black_mask >>= 1) + if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) + return Z_BINARY; - /* Check for textual ("white-listed") bytes. */ - if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 - || s->dyn_ltree[13].Freq != 0) - return Z_TEXT; - for (n = 32; n < LITERALS; n++) - if (s->dyn_ltree[n].Freq != 0) - return Z_TEXT; + /* Check for textual ("white-listed") bytes. */ + if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 || s->dyn_ltree[13].Freq != 0) + return Z_TEXT; + for (n = 32; n < LITERALS; n++) + if (s->dyn_ltree[n].Freq != 0) + return Z_TEXT; - /* There are no "black-listed" or "white-listed" bytes: + /* There are no "black-listed" or "white-listed" bytes: * this stream either is empty or has tolerated ("gray-listed") bytes only. */ - return Z_BINARY; + return Z_BINARY; } /* =========================================================================== @@ -1151,50 +1249,56 @@ local int detect_data_type(s) * method would use a table) * IN assertion: 1 <= len <= 15 */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ +local unsigned bi_reverse(code, len) unsigned code; /* the value to invert */ +int len; /* its bit length */ { - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; + register unsigned res = 0; + do + { + res |= code & 1; + code >>= 1, res <<= 1; + } while (--len > 0); + return res >> 1; } /* =========================================================================== * Flush the bit buffer, keeping at most 7 bits in it. */ local void bi_flush(s) - deflate_state *s; + deflate_state *s; { - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } + if (s->bi_valid == 16) + { + put_short(s, s->bi_buf); + s->bi_buf = 0; + s->bi_valid = 0; + } + else if (s->bi_valid >= 8) + { + put_byte(s, (Byte)s->bi_buf); + s->bi_buf >>= 8; + s->bi_valid -= 8; + } } /* =========================================================================== * Flush the bit buffer and align the output on a byte boundary */ local void bi_windup(s) - deflate_state *s; + deflate_state *s; { - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; + if (s->bi_valid > 8) + { + put_short(s, s->bi_buf); + } + else if (s->bi_valid > 0) + { + put_byte(s, (Byte)s->bi_buf); + } + s->bi_buf = 0; + s->bi_valid = 0; #ifdef DEBUG - s->bits_sent = (s->bits_sent+7) & ~7; + s->bits_sent = (s->bits_sent + 7) & ~7; #endif } @@ -1203,24 +1307,26 @@ local void bi_windup(s) * one's complement if requested. */ local void copy_block(s, buf, len, header) - deflate_state *s; - charf *buf; /* the input data */ - unsigned len; /* its length */ - int header; /* true if block header must be written */ + deflate_state *s; +charf *buf; /* the input data */ +unsigned len; /* its length */ +int header; /* true if block header must be written */ { - bi_windup(s); /* align on byte boundary */ + bi_windup(s); /* align on byte boundary */ - if (header) { - put_short(s, (ush)len); - put_short(s, (ush)~len); + if (header) + { + put_short(s, (ush)len); + put_short(s, (ush)~len); #ifdef DEBUG - s->bits_sent += 2*16; + s->bits_sent += 2 * 16; #endif - } + } #ifdef DEBUG - s->bits_sent += (ulg)len<<3; + s->bits_sent += (ulg)len << 3; #endif - while (len--) { - put_byte(s, *buf++); - } + while (len--) + { + put_byte(s, *buf++); + } } diff --git a/examples/ThirdPartyLibs/zlib/trees.h b/examples/ThirdPartyLibs/zlib/trees.h index d35639d82..77067ff72 100644 --- a/examples/ThirdPartyLibs/zlib/trees.h +++ b/examples/ThirdPartyLibs/zlib/trees.h @@ -1,128 +1,59 @@ /* header created automatically with -DGEN_TREES_H */ -local const ct_data static_ltree[L_CODES+2] = { -{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, -{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, -{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, -{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, -{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, -{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, -{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, -{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, -{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, -{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, -{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, -{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, -{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, -{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, -{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, -{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, -{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, -{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, -{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, -{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, -{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, -{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, -{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, -{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, -{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, -{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, -{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, -{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, -{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, -{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, -{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, -{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, -{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, -{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, -{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, -{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, -{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, -{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, -{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, -{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, -{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, -{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, -{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, -{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, -{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, -{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, -{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, -{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, -{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, -{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, -{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, -{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, -{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, -{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, -{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, -{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, -{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, -{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} -}; +local const ct_data static_ltree[L_CODES + 2] = { + {{12}, {8}}, {{140}, {8}}, {{76}, {8}}, {{204}, {8}}, {{44}, {8}}, {{172}, {8}}, {{108}, {8}}, {{236}, {8}}, {{28}, {8}}, {{156}, {8}}, {{92}, {8}}, {{220}, {8}}, {{60}, {8}}, {{188}, {8}}, {{124}, {8}}, {{252}, {8}}, {{2}, {8}}, {{130}, {8}}, {{66}, {8}}, {{194}, {8}}, {{34}, {8}}, {{162}, {8}}, {{98}, {8}}, {{226}, {8}}, {{18}, {8}}, {{146}, {8}}, {{82}, {8}}, {{210}, {8}}, {{50}, {8}}, {{178}, {8}}, {{114}, {8}}, {{242}, {8}}, {{10}, {8}}, {{138}, {8}}, {{74}, {8}}, {{202}, {8}}, {{42}, {8}}, {{170}, {8}}, {{106}, {8}}, {{234}, {8}}, {{26}, {8}}, {{154}, {8}}, {{90}, {8}}, {{218}, {8}}, {{58}, {8}}, {{186}, {8}}, {{122}, {8}}, {{250}, {8}}, {{6}, {8}}, {{134}, {8}}, {{70}, {8}}, {{198}, {8}}, {{38}, {8}}, {{166}, {8}}, {{102}, {8}}, {{230}, {8}}, {{22}, {8}}, {{150}, {8}}, {{86}, {8}}, {{214}, {8}}, {{54}, {8}}, {{182}, {8}}, {{118}, {8}}, {{246}, {8}}, {{14}, {8}}, {{142}, {8}}, {{78}, {8}}, {{206}, {8}}, {{46}, {8}}, {{174}, {8}}, {{110}, {8}}, {{238}, {8}}, {{30}, {8}}, {{158}, {8}}, {{94}, {8}}, {{222}, {8}}, {{62}, {8}}, {{190}, {8}}, {{126}, {8}}, {{254}, {8}}, {{1}, {8}}, {{129}, {8}}, {{65}, {8}}, {{193}, {8}}, {{33}, {8}}, {{161}, {8}}, {{97}, {8}}, {{225}, {8}}, {{17}, {8}}, {{145}, {8}}, {{81}, {8}}, {{209}, {8}}, {{49}, {8}}, {{177}, {8}}, {{113}, {8}}, {{241}, {8}}, {{9}, {8}}, {{137}, {8}}, {{73}, {8}}, {{201}, {8}}, {{41}, {8}}, {{169}, {8}}, {{105}, {8}}, {{233}, {8}}, {{25}, {8}}, {{153}, {8}}, {{89}, {8}}, {{217}, {8}}, {{57}, {8}}, {{185}, {8}}, {{121}, {8}}, {{249}, {8}}, {{5}, {8}}, {{133}, {8}}, {{69}, {8}}, {{197}, {8}}, {{37}, {8}}, {{165}, {8}}, {{101}, {8}}, {{229}, {8}}, {{21}, {8}}, {{149}, {8}}, {{85}, {8}}, {{213}, {8}}, {{53}, {8}}, {{181}, {8}}, {{117}, {8}}, {{245}, {8}}, {{13}, {8}}, {{141}, {8}}, {{77}, {8}}, {{205}, {8}}, {{45}, {8}}, {{173}, {8}}, {{109}, {8}}, {{237}, {8}}, {{29}, {8}}, {{157}, {8}}, {{93}, {8}}, {{221}, {8}}, {{61}, {8}}, {{189}, {8}}, {{125}, {8}}, {{253}, {8}}, {{19}, {9}}, {{275}, {9}}, {{147}, {9}}, {{403}, {9}}, {{83}, {9}}, {{339}, {9}}, {{211}, {9}}, {{467}, {9}}, {{51}, {9}}, {{307}, {9}}, {{179}, {9}}, {{435}, {9}}, {{115}, {9}}, {{371}, {9}}, {{243}, {9}}, {{499}, {9}}, {{11}, {9}}, {{267}, {9}}, {{139}, {9}}, {{395}, {9}}, {{75}, {9}}, {{331}, {9}}, {{203}, {9}}, {{459}, {9}}, {{43}, {9}}, {{299}, {9}}, {{171}, {9}}, {{427}, {9}}, {{107}, {9}}, {{363}, {9}}, {{235}, {9}}, {{491}, {9}}, {{27}, {9}}, {{283}, {9}}, {{155}, {9}}, {{411}, {9}}, {{91}, {9}}, {{347}, {9}}, {{219}, {9}}, {{475}, {9}}, {{59}, {9}}, {{315}, {9}}, {{187}, {9}}, {{443}, {9}}, {{123}, {9}}, {{379}, {9}}, {{251}, {9}}, {{507}, {9}}, {{7}, {9}}, {{263}, {9}}, {{135}, {9}}, {{391}, {9}}, {{71}, {9}}, {{327}, {9}}, {{199}, {9}}, {{455}, {9}}, {{39}, {9}}, {{295}, {9}}, {{167}, {9}}, {{423}, {9}}, {{103}, {9}}, {{359}, {9}}, {{231}, {9}}, {{487}, {9}}, {{23}, {9}}, {{279}, {9}}, {{151}, {9}}, {{407}, {9}}, {{87}, {9}}, {{343}, {9}}, {{215}, {9}}, {{471}, {9}}, {{55}, {9}}, {{311}, {9}}, {{183}, {9}}, {{439}, {9}}, {{119}, {9}}, {{375}, {9}}, {{247}, {9}}, {{503}, {9}}, {{15}, {9}}, {{271}, {9}}, {{143}, {9}}, {{399}, {9}}, {{79}, {9}}, {{335}, {9}}, {{207}, {9}}, {{463}, {9}}, {{47}, {9}}, {{303}, {9}}, {{175}, {9}}, {{431}, {9}}, {{111}, {9}}, {{367}, {9}}, {{239}, {9}}, {{495}, {9}}, {{31}, {9}}, {{287}, {9}}, {{159}, {9}}, {{415}, {9}}, {{95}, {9}}, {{351}, {9}}, {{223}, {9}}, {{479}, {9}}, {{63}, {9}}, {{319}, {9}}, {{191}, {9}}, {{447}, {9}}, {{127}, {9}}, {{383}, {9}}, {{255}, {9}}, {{511}, {9}}, {{0}, {7}}, {{64}, {7}}, {{32}, {7}}, {{96}, {7}}, {{16}, {7}}, {{80}, {7}}, {{48}, {7}}, {{112}, {7}}, {{8}, {7}}, {{72}, {7}}, {{40}, {7}}, {{104}, {7}}, {{24}, {7}}, {{88}, {7}}, {{56}, {7}}, {{120}, {7}}, {{4}, {7}}, {{68}, {7}}, {{36}, {7}}, {{100}, {7}}, {{20}, {7}}, {{84}, {7}}, {{52}, {7}}, {{116}, {7}}, {{3}, {8}}, {{131}, {8}}, {{67}, {8}}, {{195}, {8}}, {{35}, {8}}, {{163}, {8}}, {{99}, {8}}, {{227}, {8}}}; local const ct_data static_dtree[D_CODES] = { -{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, -{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, -{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, -{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, -{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, -{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} -}; + {{0}, {5}}, {{16}, {5}}, {{8}, {5}}, {{24}, {5}}, {{4}, {5}}, {{20}, {5}}, {{12}, {5}}, {{28}, {5}}, {{2}, {5}}, {{18}, {5}}, {{10}, {5}}, {{26}, {5}}, {{6}, {5}}, {{22}, {5}}, {{14}, {5}}, {{30}, {5}}, {{1}, {5}}, {{17}, {5}}, {{9}, {5}}, {{25}, {5}}, {{5}, {5}}, {{21}, {5}}, {{13}, {5}}, {{29}, {5}}, {{3}, {5}}, {{19}, {5}}, {{11}, {5}}, {{27}, {5}}, {{7}, {5}}, {{23}, {5}}}; const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, -18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 -}; + 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, + 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, + 13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, + 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, + 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, + 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, + 28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, + 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29}; -const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, -13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, -17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, -19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 -}; +const uch ZLIB_INTERNAL _length_code[MAX_MATCH - MIN_MATCH + 1] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, + 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, + 17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, + 19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, + 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, + 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, + 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, + 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, + 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28}; local const int base_length[LENGTH_CODES] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, -64, 80, 96, 112, 128, 160, 192, 224, 0 -}; + 0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, + 64, 80, 96, 112, 128, 160, 192, 224, 0}; local const int base_dist[D_CODES] = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 -}; - + 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, + 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, + 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576}; diff --git a/examples/ThirdPartyLibs/zlib/uncompr.c b/examples/ThirdPartyLibs/zlib/uncompr.c index 242e9493d..b5fd1f155 100644 --- a/examples/ThirdPartyLibs/zlib/uncompr.c +++ b/examples/ThirdPartyLibs/zlib/uncompr.c @@ -21,39 +21,40 @@ enough memory, Z_BUF_ERROR if there was not enough room in the output buffer, or Z_DATA_ERROR if the input data was corrupted. */ -int ZEXPORT uncompress (dest, destLen, source, sourceLen) - Bytef *dest; - uLongf *destLen; - const Bytef *source; - uLong sourceLen; +int ZEXPORT uncompress(dest, destLen, source, sourceLen) + Bytef *dest; +uLongf *destLen; +const Bytef *source; +uLong sourceLen; { - z_stream stream; - int err; + z_stream stream; + int err; - stream.next_in = (z_const Bytef *)source; - stream.avail_in = (uInt)sourceLen; - /* Check for source > 64K on 16-bit machine: */ - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; + stream.next_in = (z_const Bytef *)source; + stream.avail_in = (uInt)sourceLen; + /* Check for source > 64K on 16-bit machine: */ + if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR; - stream.next_out = dest; - stream.avail_out = (uInt)*destLen; - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; + stream.next_out = dest; + stream.avail_out = (uInt)*destLen; + if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR; - stream.zalloc = (alloc_func)0; - stream.zfree = (free_func)0; + stream.zalloc = (alloc_func)0; + stream.zfree = (free_func)0; - err = inflateInit(&stream); - if (err != Z_OK) return err; + err = inflateInit(&stream); + if (err != Z_OK) return err; - err = inflate(&stream, Z_FINISH); - if (err != Z_STREAM_END) { - inflateEnd(&stream); - if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) - return Z_DATA_ERROR; - return err; - } - *destLen = stream.total_out; + err = inflate(&stream, Z_FINISH); + if (err != Z_STREAM_END) + { + inflateEnd(&stream); + if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0)) + return Z_DATA_ERROR; + return err; + } + *destLen = stream.total_out; - err = inflateEnd(&stream); - return err; + err = inflateEnd(&stream); + return err; } diff --git a/examples/ThirdPartyLibs/zlib/zconf.h b/examples/ThirdPartyLibs/zlib/zconf.h index 9987a7755..603c24121 100644 --- a/examples/ThirdPartyLibs/zlib/zconf.h +++ b/examples/ThirdPartyLibs/zlib/zconf.h @@ -14,164 +14,164 @@ * Even better than compiling with -DZ_PREFIX would be to use configure to set * this permanently in zconf.h using "./configure --zprefix". */ -#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ -# define Z_PREFIX_SET +#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ +#define Z_PREFIX_SET /* all linked symbols */ -# define _dist_code z__dist_code -# define _length_code z__length_code -# define _tr_align z__tr_align -# define _tr_flush_bits z__tr_flush_bits -# define _tr_flush_block z__tr_flush_block -# define _tr_init z__tr_init -# define _tr_stored_block z__tr_stored_block -# define _tr_tally z__tr_tally -# define adler32 z_adler32 -# define adler32_combine z_adler32_combine -# define adler32_combine64 z_adler32_combine64 -# ifndef Z_SOLO -# define compress z_compress -# define compress2 z_compress2 -# define compressBound z_compressBound -# endif -# define crc32 z_crc32 -# define crc32_combine z_crc32_combine -# define crc32_combine64 z_crc32_combine64 -# define deflate z_deflate -# define deflateBound z_deflateBound -# define deflateCopy z_deflateCopy -# define deflateEnd z_deflateEnd -# define deflateInit2_ z_deflateInit2_ -# define deflateInit_ z_deflateInit_ -# define deflateParams z_deflateParams -# define deflatePending z_deflatePending -# define deflatePrime z_deflatePrime -# define deflateReset z_deflateReset -# define deflateResetKeep z_deflateResetKeep -# define deflateSetDictionary z_deflateSetDictionary -# define deflateSetHeader z_deflateSetHeader -# define deflateTune z_deflateTune -# define deflate_copyright z_deflate_copyright -# define get_crc_table z_get_crc_table -# ifndef Z_SOLO -# define gz_error z_gz_error -# define gz_intmax z_gz_intmax -# define gz_strwinerror z_gz_strwinerror -# define gzbuffer z_gzbuffer -# define gzclearerr z_gzclearerr -# define gzclose z_gzclose -# define gzclose_r z_gzclose_r -# define gzclose_w z_gzclose_w -# define gzdirect z_gzdirect -# define gzdopen z_gzdopen -# define gzeof z_gzeof -# define gzerror z_gzerror -# define gzflush z_gzflush -# define gzgetc z_gzgetc -# define gzgetc_ z_gzgetc_ -# define gzgets z_gzgets -# define gzoffset z_gzoffset -# define gzoffset64 z_gzoffset64 -# define gzopen z_gzopen -# define gzopen64 z_gzopen64 -# ifdef _WIN32 -# define gzopen_w z_gzopen_w -# endif -# define gzprintf z_gzprintf -# define gzvprintf z_gzvprintf -# define gzputc z_gzputc -# define gzputs z_gzputs -# define gzread z_gzread -# define gzrewind z_gzrewind -# define gzseek z_gzseek -# define gzseek64 z_gzseek64 -# define gzsetparams z_gzsetparams -# define gztell z_gztell -# define gztell64 z_gztell64 -# define gzungetc z_gzungetc -# define gzwrite z_gzwrite -# endif -# define inflate z_inflate -# define inflateBack z_inflateBack -# define inflateBackEnd z_inflateBackEnd -# define inflateBackInit_ z_inflateBackInit_ -# define inflateCopy z_inflateCopy -# define inflateEnd z_inflateEnd -# define inflateGetHeader z_inflateGetHeader -# define inflateInit2_ z_inflateInit2_ -# define inflateInit_ z_inflateInit_ -# define inflateMark z_inflateMark -# define inflatePrime z_inflatePrime -# define inflateReset z_inflateReset -# define inflateReset2 z_inflateReset2 -# define inflateSetDictionary z_inflateSetDictionary -# define inflateGetDictionary z_inflateGetDictionary -# define inflateSync z_inflateSync -# define inflateSyncPoint z_inflateSyncPoint -# define inflateUndermine z_inflateUndermine -# define inflateResetKeep z_inflateResetKeep -# define inflate_copyright z_inflate_copyright -# define inflate_fast z_inflate_fast -# define inflate_table z_inflate_table -# ifndef Z_SOLO -# define uncompress z_uncompress -# endif -# define zError z_zError -# ifndef Z_SOLO -# define zcalloc z_zcalloc -# define zcfree z_zcfree -# endif -# define zlibCompileFlags z_zlibCompileFlags -# define zlibVersion z_zlibVersion +#define _dist_code z__dist_code +#define _length_code z__length_code +#define _tr_align z__tr_align +#define _tr_flush_bits z__tr_flush_bits +#define _tr_flush_block z__tr_flush_block +#define _tr_init z__tr_init +#define _tr_stored_block z__tr_stored_block +#define _tr_tally z__tr_tally +#define adler32 z_adler32 +#define adler32_combine z_adler32_combine +#define adler32_combine64 z_adler32_combine64 +#ifndef Z_SOLO +#define compress z_compress +#define compress2 z_compress2 +#define compressBound z_compressBound +#endif +#define crc32 z_crc32 +#define crc32_combine z_crc32_combine +#define crc32_combine64 z_crc32_combine64 +#define deflate z_deflate +#define deflateBound z_deflateBound +#define deflateCopy z_deflateCopy +#define deflateEnd z_deflateEnd +#define deflateInit2_ z_deflateInit2_ +#define deflateInit_ z_deflateInit_ +#define deflateParams z_deflateParams +#define deflatePending z_deflatePending +#define deflatePrime z_deflatePrime +#define deflateReset z_deflateReset +#define deflateResetKeep z_deflateResetKeep +#define deflateSetDictionary z_deflateSetDictionary +#define deflateSetHeader z_deflateSetHeader +#define deflateTune z_deflateTune +#define deflate_copyright z_deflate_copyright +#define get_crc_table z_get_crc_table +#ifndef Z_SOLO +#define gz_error z_gz_error +#define gz_intmax z_gz_intmax +#define gz_strwinerror z_gz_strwinerror +#define gzbuffer z_gzbuffer +#define gzclearerr z_gzclearerr +#define gzclose z_gzclose +#define gzclose_r z_gzclose_r +#define gzclose_w z_gzclose_w +#define gzdirect z_gzdirect +#define gzdopen z_gzdopen +#define gzeof z_gzeof +#define gzerror z_gzerror +#define gzflush z_gzflush +#define gzgetc z_gzgetc +#define gzgetc_ z_gzgetc_ +#define gzgets z_gzgets +#define gzoffset z_gzoffset +#define gzoffset64 z_gzoffset64 +#define gzopen z_gzopen +#define gzopen64 z_gzopen64 +#ifdef _WIN32 +#define gzopen_w z_gzopen_w +#endif +#define gzprintf z_gzprintf +#define gzvprintf z_gzvprintf +#define gzputc z_gzputc +#define gzputs z_gzputs +#define gzread z_gzread +#define gzrewind z_gzrewind +#define gzseek z_gzseek +#define gzseek64 z_gzseek64 +#define gzsetparams z_gzsetparams +#define gztell z_gztell +#define gztell64 z_gztell64 +#define gzungetc z_gzungetc +#define gzwrite z_gzwrite +#endif +#define inflate z_inflate +#define inflateBack z_inflateBack +#define inflateBackEnd z_inflateBackEnd +#define inflateBackInit_ z_inflateBackInit_ +#define inflateCopy z_inflateCopy +#define inflateEnd z_inflateEnd +#define inflateGetHeader z_inflateGetHeader +#define inflateInit2_ z_inflateInit2_ +#define inflateInit_ z_inflateInit_ +#define inflateMark z_inflateMark +#define inflatePrime z_inflatePrime +#define inflateReset z_inflateReset +#define inflateReset2 z_inflateReset2 +#define inflateSetDictionary z_inflateSetDictionary +#define inflateGetDictionary z_inflateGetDictionary +#define inflateSync z_inflateSync +#define inflateSyncPoint z_inflateSyncPoint +#define inflateUndermine z_inflateUndermine +#define inflateResetKeep z_inflateResetKeep +#define inflate_copyright z_inflate_copyright +#define inflate_fast z_inflate_fast +#define inflate_table z_inflate_table +#ifndef Z_SOLO +#define uncompress z_uncompress +#endif +#define zError z_zError +#ifndef Z_SOLO +#define zcalloc z_zcalloc +#define zcfree z_zcfree +#endif +#define zlibCompileFlags z_zlibCompileFlags +#define zlibVersion z_zlibVersion /* all zlib typedefs in zlib.h and zconf.h */ -# define Byte z_Byte -# define Bytef z_Bytef -# define alloc_func z_alloc_func -# define charf z_charf -# define free_func z_free_func -# ifndef Z_SOLO -# define gzFile z_gzFile -# endif -# define gz_header z_gz_header -# define gz_headerp z_gz_headerp -# define in_func z_in_func -# define intf z_intf -# define out_func z_out_func -# define uInt z_uInt -# define uIntf z_uIntf -# define uLong z_uLong -# define uLongf z_uLongf -# define voidp z_voidp -# define voidpc z_voidpc -# define voidpf z_voidpf +#define Byte z_Byte +#define Bytef z_Bytef +#define alloc_func z_alloc_func +#define charf z_charf +#define free_func z_free_func +#ifndef Z_SOLO +#define gzFile z_gzFile +#endif +#define gz_header z_gz_header +#define gz_headerp z_gz_headerp +#define in_func z_in_func +#define intf z_intf +#define out_func z_out_func +#define uInt z_uInt +#define uIntf z_uIntf +#define uLong z_uLong +#define uLongf z_uLongf +#define voidp z_voidp +#define voidpc z_voidpc +#define voidpf z_voidpf /* all zlib structs in zlib.h and zconf.h */ -# define gz_header_s z_gz_header_s -# define internal_state z_internal_state +#define gz_header_s z_gz_header_s +#define internal_state z_internal_state #endif #if defined(__MSDOS__) && !defined(MSDOS) -# define MSDOS +#define MSDOS #endif #if (defined(OS_2) || defined(__OS2__)) && !defined(OS2) -# define OS2 +#define OS2 #endif #if defined(_WINDOWS) && !defined(WINDOWS) -# define WINDOWS +#define WINDOWS #endif #if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__) -# ifndef WIN32 -# define WIN32 -# endif +#ifndef WIN32 +#define WIN32 +#endif #endif #if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32) -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) -# ifndef SYS16BIT -# define SYS16BIT -# endif -# endif +#if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__) +#ifndef SYS16BIT +#define SYS16BIT +#endif +#endif #endif /* @@ -179,63 +179,63 @@ * than 64k bytes at a time (needed on systems with 16-bit int). */ #ifdef SYS16BIT -# define MAXSEG_64K +#define MAXSEG_64K #endif #ifdef MSDOS -# define UNALIGNED_OK +#define UNALIGNED_OK #endif #ifdef __STDC_VERSION__ -# ifndef STDC -# define STDC -# endif -# if __STDC_VERSION__ >= 199901L -# ifndef STDC99 -# define STDC99 -# endif -# endif +#ifndef STDC +#define STDC +#endif +#if __STDC_VERSION__ >= 199901L +#ifndef STDC99 +#define STDC99 +#endif +#endif #endif #if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus)) -# define STDC +#define STDC #endif #if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__)) -# define STDC +#define STDC #endif #if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32)) -# define STDC +#define STDC #endif #if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__)) -# define STDC +#define STDC #endif -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ -# define STDC +#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */ +#define STDC #endif #ifndef STDC -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ -# define const /* note: need a more gentle solution here */ -# endif +#ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */ +#define const /* note: need a more gentle solution here */ +#endif #endif #if defined(ZLIB_CONST) && !defined(z_const) -# define z_const const +#define z_const const #else -# define z_const +#define z_const #endif /* Some Mac compilers merge all .h files incorrectly: */ -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) -# define NO_DUMMY_DECL +#if defined(__MWERKS__) || defined(applec) || defined(THINK_C) || defined(__SC__) +#define NO_DUMMY_DECL #endif /* Maximum value for memLevel in deflateInit2 */ #ifndef MAX_MEM_LEVEL -# ifdef MAXSEG_64K -# define MAX_MEM_LEVEL 8 -# else -# define MAX_MEM_LEVEL 9 -# endif +#ifdef MAXSEG_64K +#define MAX_MEM_LEVEL 8 +#else +#define MAX_MEM_LEVEL 9 +#endif #endif /* Maximum value for windowBits in deflateInit2 and inflateInit2. @@ -244,7 +244,7 @@ * gzip.) */ #ifndef MAX_WBITS -# define MAX_WBITS 15 /* 32K LZ77 window */ +#define MAX_WBITS 15 /* 32K LZ77 window */ #endif /* The memory requirements for deflate are (in bytes): @@ -260,22 +260,22 @@ for small objects. */ - /* Type declarations */ +/* Type declarations */ #ifndef OF /* function prototypes */ -# ifdef STDC -# define OF(args) args -# else -# define OF(args) () -# endif +#ifdef STDC +#define OF(args) args +#else +#define OF(args) () +#endif #endif #ifndef Z_ARG /* function prototypes for stdarg */ -# if defined(STDC) || defined(Z_HAVE_STDARG_H) -# define Z_ARG(args) args -# else -# define Z_ARG(args) () -# endif +#if defined(STDC) || defined(Z_HAVE_STDARG_H) +#define Z_ARG(args) args +#else +#define Z_ARG(args) () +#endif #endif /* The following definitions for FAR are needed only for MSDOS mixed @@ -285,153 +285,153 @@ * just define FAR to be empty. */ #ifdef SYS16BIT -# if defined(M_I86SM) || defined(M_I86MM) - /* MSC small or medium model */ -# define SMALL_MEDIUM -# ifdef _MSC_VER -# define FAR _far -# else -# define FAR far -# endif -# endif -# if (defined(__SMALL__) || defined(__MEDIUM__)) - /* Turbo C small or medium model */ -# define SMALL_MEDIUM -# ifdef __BORLANDC__ -# define FAR _far -# else -# define FAR far -# endif -# endif +#if defined(M_I86SM) || defined(M_I86MM) +/* MSC small or medium model */ +#define SMALL_MEDIUM +#ifdef _MSC_VER +#define FAR _far +#else +#define FAR far +#endif +#endif +#if (defined(__SMALL__) || defined(__MEDIUM__)) +/* Turbo C small or medium model */ +#define SMALL_MEDIUM +#ifdef __BORLANDC__ +#define FAR _far +#else +#define FAR far +#endif +#endif #endif #if defined(WINDOWS) || defined(WIN32) - /* If building or using zlib as a DLL, define ZLIB_DLL. +/* If building or using zlib as a DLL, define ZLIB_DLL. * This is not mandatory, but it offers a little performance increase. */ -# ifdef ZLIB_DLL -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) -# ifdef ZLIB_INTERNAL -# define ZEXTERN extern __declspec(dllexport) -# else -# define ZEXTERN extern __declspec(dllimport) -# endif -# endif -# endif /* ZLIB_DLL */ - /* If building or using zlib with the WINAPI/WINAPIV calling convention, +#ifdef ZLIB_DLL +#if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500)) +#ifdef ZLIB_INTERNAL +#define ZEXTERN extern __declspec(dllexport) +#else +#define ZEXTERN extern __declspec(dllimport) +#endif +#endif +#endif /* ZLIB_DLL */ +/* If building or using zlib with the WINAPI/WINAPIV calling convention, * define ZLIB_WINAPI. * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI. */ -# ifdef ZLIB_WINAPI -# ifdef FAR -# undef FAR -# endif -# include - /* No need for _export, use ZLIB.DEF instead. */ - /* For complete Windows compatibility, use WINAPI, not __stdcall. */ -# define ZEXPORT WINAPI -# ifdef WIN32 -# define ZEXPORTVA WINAPIV -# else -# define ZEXPORTVA FAR CDECL -# endif -# endif +#ifdef ZLIB_WINAPI +#ifdef FAR +#undef FAR +#endif +#include +/* No need for _export, use ZLIB.DEF instead. */ +/* For complete Windows compatibility, use WINAPI, not __stdcall. */ +#define ZEXPORT WINAPI +#ifdef WIN32 +#define ZEXPORTVA WINAPIV +#else +#define ZEXPORTVA FAR CDECL +#endif +#endif #endif -#if defined (__BEOS__) -# ifdef ZLIB_DLL -# ifdef ZLIB_INTERNAL -# define ZEXPORT __declspec(dllexport) -# define ZEXPORTVA __declspec(dllexport) -# else -# define ZEXPORT __declspec(dllimport) -# define ZEXPORTVA __declspec(dllimport) -# endif -# endif +#if defined(__BEOS__) +#ifdef ZLIB_DLL +#ifdef ZLIB_INTERNAL +#define ZEXPORT __declspec(dllexport) +#define ZEXPORTVA __declspec(dllexport) +#else +#define ZEXPORT __declspec(dllimport) +#define ZEXPORTVA __declspec(dllimport) +#endif +#endif #endif #ifndef ZEXTERN -# define ZEXTERN extern +#define ZEXTERN extern #endif #ifndef ZEXPORT -# define ZEXPORT +#define ZEXPORT #endif #ifndef ZEXPORTVA -# define ZEXPORTVA +#define ZEXPORTVA #endif #ifndef FAR -# define FAR +#define FAR #endif #if !defined(__MACTYPES__) -typedef unsigned char Byte; /* 8 bits */ +typedef unsigned char Byte; /* 8 bits */ #endif -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ +typedef unsigned int uInt; /* 16 bits or more */ +typedef unsigned long uLong; /* 32 bits or more */ #ifdef SMALL_MEDIUM - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ -# define Bytef Byte FAR +/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */ +#define Bytef Byte FAR #else - typedef Byte FAR Bytef; +typedef Byte FAR Bytef; #endif -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; +typedef char FAR charf; +typedef int FAR intf; +typedef uInt FAR uIntf; typedef uLong FAR uLongf; #ifdef STDC - typedef void const *voidpc; - typedef void FAR *voidpf; - typedef void *voidp; +typedef void const *voidpc; +typedef void FAR *voidpf; +typedef void *voidp; #else - typedef Byte const *voidpc; - typedef Byte FAR *voidpf; - typedef Byte *voidp; +typedef Byte const *voidpc; +typedef Byte FAR *voidpf; +typedef Byte *voidp; #endif #if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC) -# include -# if (UINT_MAX == 0xffffffffUL) -# define Z_U4 unsigned -# elif (ULONG_MAX == 0xffffffffUL) -# define Z_U4 unsigned long -# elif (USHRT_MAX == 0xffffffffUL) -# define Z_U4 unsigned short -# endif +#include +#if (UINT_MAX == 0xffffffffUL) +#define Z_U4 unsigned +#elif (ULONG_MAX == 0xffffffffUL) +#define Z_U4 unsigned long +#elif (USHRT_MAX == 0xffffffffUL) +#define Z_U4 unsigned short +#endif #endif #ifdef Z_U4 - typedef Z_U4 z_crc_t; +typedef Z_U4 z_crc_t; #else - typedef unsigned long z_crc_t; +typedef unsigned long z_crc_t; #endif -#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_UNISTD_H +#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */ +#define Z_HAVE_UNISTD_H #endif -#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ -# define Z_HAVE_STDARG_H +#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */ +#define Z_HAVE_STDARG_H #endif #ifdef STDC -# ifndef Z_SOLO -# include /* for off_t */ -# endif +#ifndef Z_SOLO +#include /* for off_t */ +#endif #endif #if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -# include /* for va_list */ -# endif +#ifndef Z_SOLO +#include /* for va_list */ +#endif #endif #ifdef _WIN32 -# ifndef Z_SOLO -# include /* for wchar_t */ -# endif +#ifndef Z_SOLO +#include /* for wchar_t */ +#endif #endif /* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and @@ -441,71 +441,71 @@ typedef uLong FAR uLongf; * equivalently requesting no 64-bit operations */ #if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1 -# undef _LARGEFILE64_SOURCE +#undef _LARGEFILE64_SOURCE #endif #if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H) -# define Z_HAVE_UNISTD_H +#define Z_HAVE_UNISTD_H #endif #ifndef Z_SOLO -# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) -# include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ -# ifdef VMS -# include /* for off_t */ -# endif -# ifndef z_off_t -# define z_off_t off_t -# endif -# endif +#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) +#include /* for SEEK_*, off_t, and _LFS64_LARGEFILE */ +#ifdef VMS +#include /* for off_t */ +#endif +#ifndef z_off_t +#define z_off_t off_t +#endif +#endif #endif -#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0 -# define Z_LFS64 +#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE - 0 +#define Z_LFS64 #endif #if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64) -# define Z_LARGE64 +#define Z_LARGE64 #endif -#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64) -# define Z_WANT64 +#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS - 0 == 64 && defined(Z_LFS64) +#define Z_WANT64 #endif #if !defined(SEEK_SET) && !defined(Z_SOLO) -# define SEEK_SET 0 /* Seek from beginning of file. */ -# define SEEK_CUR 1 /* Seek from current position. */ -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ +#define SEEK_SET 0 /* Seek from beginning of file. */ +#define SEEK_CUR 1 /* Seek from current position. */ +#define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ #endif #ifndef z_off_t -# define z_off_t long +#define z_off_t long #endif #if !defined(_WIN32) && defined(Z_LARGE64) -# define z_off64_t off64_t +#define z_off64_t off64_t #else -# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) -# define z_off64_t __int64 -# else -# define z_off64_t z_off_t -# endif +#if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO) +#define z_off64_t __int64 +#else +#define z_off64_t z_off_t +#endif #endif /* MVS linker does not support external names larger than 8 bytes */ #if defined(__MVS__) - #pragma map(deflateInit_,"DEIN") - #pragma map(deflateInit2_,"DEIN2") - #pragma map(deflateEnd,"DEEND") - #pragma map(deflateBound,"DEBND") - #pragma map(inflateInit_,"ININ") - #pragma map(inflateInit2_,"ININ2") - #pragma map(inflateEnd,"INEND") - #pragma map(inflateSync,"INSY") - #pragma map(inflateSetDictionary,"INSEDI") - #pragma map(compressBound,"CMBND") - #pragma map(inflate_table,"INTABL") - #pragma map(inflate_fast,"INFA") - #pragma map(inflate_copyright,"INCOPY") +#pragma map(deflateInit_, "DEIN") +#pragma map(deflateInit2_, "DEIN2") +#pragma map(deflateEnd, "DEEND") +#pragma map(deflateBound, "DEBND") +#pragma map(inflateInit_, "ININ") +#pragma map(inflateInit2_, "ININ2") +#pragma map(inflateEnd, "INEND") +#pragma map(inflateSync, "INSY") +#pragma map(inflateSetDictionary, "INSEDI") +#pragma map(compressBound, "CMBND") +#pragma map(inflate_table, "INTABL") +#pragma map(inflate_fast, "INFA") +#pragma map(inflate_copyright, "INCOPY") #endif #endif /* ZCONF_H */ diff --git a/examples/ThirdPartyLibs/zlib/zlib.h b/examples/ThirdPartyLibs/zlib/zlib.h index 3e0c7672a..097b05407 100644 --- a/examples/ThirdPartyLibs/zlib/zlib.h +++ b/examples/ThirdPartyLibs/zlib/zlib.h @@ -34,7 +34,8 @@ #include "zconf.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #define ZLIB_VERSION "1.2.8" @@ -44,7 +45,7 @@ extern "C" { #define ZLIB_VER_REVISION 8 #define ZLIB_VER_SUBREVISION 0 -/* + /* The 'zlib' compression library provides in-memory compression and decompression functions, including integrity checks of the uncompressed data. This version of the library supports only one compression method (deflation) @@ -77,58 +78,60 @@ extern "C" { even in case of corrupted input. */ -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); + typedef voidpf(*alloc_func) OF((voidpf opaque, uInt items, uInt size)); + typedef void(*free_func) OF((voidpf opaque, voidpf address)); -struct internal_state; + struct internal_state; -typedef struct z_stream_s { - z_const Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total number of input bytes read so far */ + typedef struct z_stream_s + { + z_const Bytef *next_in; /* next input byte */ + uInt avail_in; /* number of bytes available at next_in */ + uLong total_in; /* total number of input bytes read so far */ - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total number of bytes output so far */ + Bytef *next_out; /* next output byte should be put there */ + uInt avail_out; /* remaining free space at next_out */ + uLong total_out; /* total number of bytes output so far */ - z_const char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ + z_const char *msg; /* last error message, NULL if no error */ + struct internal_state FAR *state; /* not visible by applications */ - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ + alloc_func zalloc; /* used to allocate the internal state */ + free_func zfree; /* used to free the internal state */ + voidpf opaque; /* private data object passed to zalloc and zfree */ - int data_type; /* best guess about the data type: binary or text */ - uLong adler; /* adler32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; + int data_type; /* best guess about the data type: binary or text */ + uLong adler; /* adler32 value of the uncompressed data */ + uLong reserved; /* reserved for future use */ + } z_stream; -typedef z_stream FAR *z_streamp; + typedef z_stream FAR *z_streamp; -/* + /* gzip header information passed to and from zlib routines. See RFC 1952 for more details on the meanings of these fields. */ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used + typedef struct gz_header_s + { + int text; /* true if compressed data believed to be text */ + uLong time; /* modification time */ + int xflags; /* extra flags (not used when writing a gzip file) */ + int os; /* operating system */ + Bytef *extra; /* pointer to extra field or Z_NULL if none */ + uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ + uInt extra_max; /* space at extra (only when reading header) */ + Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ + uInt name_max; /* space at name (only when reading header) */ + Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ + uInt comm_max; /* space at comment (only when reading header) */ + int hcrc; /* true if there was or will be a header crc */ + int done; /* true when done reading gzip header (not used when writing a gzip file) */ -} gz_header; + } gz_header; -typedef gz_header FAR *gz_headerp; + typedef gz_header FAR *gz_headerp; -/* + /* The application must update next_in and avail_in when avail_in has dropped to zero. It must update next_out and avail_out when avail_out has dropped to zero. The application must initialize zalloc, zfree and opaque before @@ -159,68 +162,67 @@ typedef gz_header FAR *gz_headerp; if the decompressor wants to decompress everything in a single step). */ - /* constants */ + /* constants */ -#define Z_NO_FLUSH 0 +#define Z_NO_FLUSH 0 #define Z_PARTIAL_FLUSH 1 -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -#define Z_TREES 6 -/* Allowed flush values; see deflate() and inflate() below for details */ +#define Z_SYNC_FLUSH 2 +#define Z_FULL_FLUSH 3 +#define Z_FINISH 4 +#define Z_BLOCK 5 +#define Z_TREES 6 + /* Allowed flush values; see deflate() and inflate() below for details */ -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) +#define Z_OK 0 +#define Z_STREAM_END 1 +#define Z_NEED_DICT 2 +#define Z_ERRNO (-1) #define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) +#define Z_DATA_ERROR (-3) +#define Z_MEM_ERROR (-4) +#define Z_BUF_ERROR (-5) #define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative values + /* Return codes for the compression/decompression functions. Negative values * are errors, positive values are used for special but normal events. */ -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ +#define Z_NO_COMPRESSION 0 +#define Z_BEST_SPEED 1 +#define Z_BEST_COMPRESSION 9 +#define Z_DEFAULT_COMPRESSION (-1) + /* compression levels */ -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ +#define Z_FILTERED 1 +#define Z_HUFFMAN_ONLY 2 +#define Z_RLE 3 +#define Z_FIXED 4 +#define Z_DEFAULT_STRATEGY 0 + /* compression strategy; see deflateInit2() below for details */ -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field (though see inflate()) */ +#define Z_BINARY 0 +#define Z_TEXT 1 +#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ +#define Z_UNKNOWN 2 + /* Possible values of the data_type field (though see inflate()) */ -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ +#define Z_DEFLATED 8 + /* The deflate compression method (the only one supported in this version) */ -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ +#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ #define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ + /* for compatibility with versions < 1.0.2 */ + /* basic functions */ - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. + ZEXTERN const char *ZEXPORT zlibVersion OF((void)); + /* The application can compare zlibVersion and ZLIB_VERSION for consistency. If the first character differs, the library code actually used is not compatible with the zlib.h header file used by the application. This check is automatically made by deflateInit and inflateInit. */ -/* + /* ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); Initializes the internal stream state for compression. The fields @@ -242,9 +244,8 @@ ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); this will be done by deflate(). */ - -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -/* + ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); + /* deflate compresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when @@ -349,9 +350,8 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); space to continue compressing. */ - -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -/* + ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); + /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. @@ -363,8 +363,7 @@ ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); deallocated). */ - -/* + /* ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); Initializes the internal stream state for decompression. The fields @@ -388,9 +387,8 @@ ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); until inflate() is called. */ - -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -/* + ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); + /* inflate decompresses as much data as possible, and stops when the input buffer becomes empty or the output buffer becomes full. It may introduce some output latency (reading input without producing any output) except when @@ -504,9 +502,8 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); recovery of the data is desired. */ - -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -/* + ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); + /* All dynamically allocated data structures for this stream are freed. This function discards any unprocessed input and does not flush any pending output. @@ -516,14 +513,13 @@ ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); static string (which must not be deallocated). */ + /* Advanced functions */ - /* Advanced functions */ - -/* + /* The following functions are needed only in some special applications. */ -/* + /* ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, int level, int method, @@ -584,10 +580,10 @@ ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, compression: this will be done by deflate(). */ -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* + ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); + /* Initializes the compression dictionary from the given byte sequence without producing any compressed output. When using the zlib format, this function must be called immediately after deflateInit, deflateInit2 or @@ -628,9 +624,9 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, not perform any compression: this will be done by deflate(). */ -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* + ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, + z_streamp source)); + /* Sets the destination stream as a complete copy of the source stream. This function can be useful when several compression strategies will be @@ -646,8 +642,8 @@ ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, destination. */ -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -/* + ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); + /* This function is equivalent to deflateEnd followed by deflateInit, but does not free and reallocate all the internal compression state. The stream will keep the same compression level and any other attributes that @@ -657,10 +653,10 @@ ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); stream state was inconsistent (such as zalloc or state being Z_NULL). */ -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* + ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, + int level, + int strategy)); + /* Dynamically update the compression level and compression strategy. The interpretation of level and strategy is as in deflateInit2. This can be used to switch between compression and straight copy of the input data, or @@ -678,12 +674,12 @@ ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, strm->avail_out was zero. */ -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); -/* + ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, + int good_length, + int max_lazy, + int nice_length, + int max_chain)); + /* Fine tune deflate's internal compression parameters. This should only be used by someone who understands the algorithm used by zlib's deflate for searching for the best matching string, and even then only by the most @@ -695,9 +691,9 @@ ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. */ -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* + ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, + uLong sourceLen)); + /* deflateBound() returns an upper bound on the compressed size after deflation of sourceLen bytes. It must be called after deflateInit() or deflateInit2(), and after deflateSetHeader(), if used. This would be used @@ -710,10 +706,10 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, than Z_FINISH or Z_NO_FLUSH are used. */ -ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, - unsigned *pending, - int *bits)); -/* + ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, + unsigned *pending, + int *bits)); + /* deflatePending() returns the number of bytes and bits of output that have been generated, but not yet provided in the available output. The bytes not provided would be due to the available output space having being consumed. @@ -725,10 +721,10 @@ ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm, stream state was inconsistent. */ -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* + ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, + int bits, + int value)); + /* deflatePrime() inserts bits in the deflate output stream. The intent is that this function is used to start off the deflate output with the bits leftover from a previous deflate stream when appending to it. As such, this @@ -742,9 +738,9 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, source stream state was inconsistent. */ -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); -/* + ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, + gz_headerp head)); + /* deflateSetHeader() provides gzip header information for when a gzip stream is requested by deflateInit2(). deflateSetHeader() may be called after deflateInit2() or deflateReset() and before the first call of @@ -766,7 +762,7 @@ ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, stream state was inconsistent. */ -/* + /* ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, int windowBits)); @@ -816,10 +812,10 @@ ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, deferred until inflate() is called. */ -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* + ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, + const Bytef *dictionary, + uInt dictLength)); + /* Initializes the decompression dictionary from the given uncompressed byte sequence. This function must be called immediately after a call of inflate, if that call returned Z_NEED_DICT. The dictionary chosen by the compressor @@ -839,10 +835,10 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, inflate(). */ -ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, - Bytef *dictionary, - uInt *dictLength)); -/* + ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, + Bytef *dictionary, + uInt *dictLength)); + /* Returns the sliding dictionary being maintained by inflate. dictLength is set to the number of bytes in the dictionary, and that many bytes are copied to dictionary. dictionary must have enough space, where 32768 bytes is @@ -854,8 +850,8 @@ ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm, stream state is inconsistent. */ -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -/* + ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); + /* Skips invalid compressed data until a possible full flush point (see above for the description of deflate with Z_FULL_FLUSH) can be found, or until all available input is skipped. No output is provided. @@ -873,9 +869,9 @@ ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); input each time, until success or end of the input data. */ -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* + ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, + z_streamp source)); + /* Sets the destination stream as a complete copy of the source stream. This function can be useful when randomly accessing a large stream. The @@ -889,8 +885,8 @@ ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, destination. */ -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -/* + ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); + /* This function is equivalent to inflateEnd followed by inflateInit, but does not free and reallocate all the internal decompression state. The stream will keep attributes that may have been set by inflateInit2. @@ -899,9 +895,9 @@ ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); stream state was inconsistent (such as zalloc or state being Z_NULL). */ -ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, - int windowBits)); -/* + ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, + int windowBits)); + /* This function is the same as inflateReset, but it also permits changing the wrap and window size requests. The windowBits parameter is interpreted the same as it is for inflateInit2. @@ -911,10 +907,10 @@ ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, the windowBits parameter is invalid. */ -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); -/* + ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, + int bits, + int value)); + /* This function inserts bits in the inflate input stream. The intent is that this function is used to start inflating at a bit position in the middle of a byte. The provided bits will be used before any bytes are used @@ -932,8 +928,8 @@ ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, stream state was inconsistent. */ -ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); -/* + ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); + /* This function returns two values, one in the lower 16 bits of the return value, and the other in the remaining upper bits, obtained by shifting the return value down 16 bits. If the upper value is -1 and the lower value is @@ -960,9 +956,9 @@ ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); source stream state was inconsistent. */ -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); -/* + ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, + gz_headerp head)); + /* inflateGetHeader() requests that gzip header information be stored in the provided gz_header structure. inflateGetHeader() may be called after inflateInit2() or inflateReset(), and before the first call of inflate(). @@ -1000,7 +996,7 @@ ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, stream state was inconsistent. */ -/* + /* ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, unsigned char FAR *window)); @@ -1022,14 +1018,14 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, the version of the header file. */ -typedef unsigned (*in_func) OF((void FAR *, - z_const unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); + typedef unsigned(*in_func) OF((void FAR *, + z_const unsigned char FAR *FAR *)); + typedef int(*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* + ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, + in_func in, void FAR *in_desc, + out_func out, void FAR *out_desc)); + /* inflateBack() does a raw inflate with a single call using a call-back interface for input and output. This is potentially more efficient than inflate() for file i/o applications, in that it avoids copying between the @@ -1096,16 +1092,16 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, cannot return Z_OK. */ -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); -/* + ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); + /* All memory allocated by inflateBackInit() is freed. inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream state was inconsistent. */ -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. + ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); + /* Return flags indicating compile-time options. Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: 1.0: size of uInt @@ -1147,9 +1143,9 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); #ifndef Z_SOLO - /* utility functions */ + /* utility functions */ -/* + /* The following utility functions are implemented on top of the basic stream-oriented functions. To simplify the interface, some default options are assumed (compression level and memory usage, standard memory allocation @@ -1157,9 +1153,9 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); you need special options. */ -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* + ZEXTERN int ZEXPORT compress OF((Bytef * dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); + /* Compresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be at least the value returned by @@ -1171,10 +1167,10 @@ ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, buffer. */ -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* + ZEXTERN int ZEXPORT compress2 OF((Bytef * dest, uLongf *destLen, + const Bytef *source, uLong sourceLen, + int level)); + /* Compresses the source buffer into the destination buffer. The level parameter has the same meaning as in deflateInit. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the @@ -1187,16 +1183,16 @@ ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, Z_STREAM_ERROR if the level parameter is invalid. */ -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* + ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); + /* compressBound() returns an upper bound on the compressed size after compress() or compress2() on sourceLen bytes. It would be used before a compress() or compress2() call to allocate the destination buffer. */ -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* + ZEXTERN int ZEXPORT uncompress OF((Bytef * dest, uLongf *destLen, + const Bytef *source, uLong sourceLen)); + /* Decompresses the source buffer into the destination buffer. sourceLen is the byte length of the source buffer. Upon entry, destLen is the total size of the destination buffer, which must be large enough to hold the entire @@ -1212,18 +1208,18 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, buffer with the uncompressed data up to that point. */ - /* gzip file access functions */ + /* gzip file access functions */ -/* + /* This library supports reading and writing files in gzip (.gz) format with an interface similar to that of stdio, using the functions that start with "gz". The gzip format is different from the zlib format. gzip is a gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. */ -typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ + typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */ -/* + /* ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); Opens a gzip (.gz) file for reading or writing. The mode parameter is as @@ -1261,8 +1257,8 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); file could not be opened. */ -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -/* + ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); + /* gzdopen associates a gzFile with the file descriptor fd. File descriptors are obtained from calls like open, dup, creat, pipe or fileno (if the file has been previously opened with fopen). The mode parameter is as in gzopen. @@ -1284,8 +1280,8 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); will not detect if fd is invalid (unless fd is -1). */ -ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); -/* + ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); + /* Set the internal buffer size used by this library's functions. The default buffer size is 8192 bytes. This function must be called after gzopen() or gzdopen(), and before any other calls that read or write the @@ -1301,8 +1297,8 @@ ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); too late. */ -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* + ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); + /* Dynamically update the compression level or strategy. See the description of deflateInit2 for the meaning of these parameters. @@ -1310,8 +1306,8 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); opened for writing. */ -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* + ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); + /* Reads the given number of uncompressed bytes from the compressed file. If the input file is not in gzip format, gzread copies the given number of bytes into the buffer directly from the file. @@ -1338,16 +1334,16 @@ ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); len for end of file, or -1 for error. */ -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* + ZEXTERN int ZEXPORT gzwrite OF((gzFile file, + voidpc buf, unsigned len)); + /* Writes the given number of uncompressed bytes into the compressed file. gzwrite returns the number of uncompressed bytes written or 0 in case of error. */ -ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); -/* + ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); + /* Converts, formats, and writes the arguments to the compressed file under control of the format string, as in fprintf. gzprintf returns the number of uncompressed bytes actually written, or 0 in case of error. The number of @@ -1361,16 +1357,16 @@ ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...)); zlibCompileFlags(). */ -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -/* + ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); + /* Writes the given null-terminated string to the compressed file, excluding the terminating null character. gzputs returns the number of characters written, or -1 in case of error. */ -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -/* + ZEXTERN char *ZEXPORT gzgets OF((gzFile file, char *buf, int len)); + /* Reads bytes from the compressed file until len-1 characters are read, or a newline character is read and transferred to buf, or an end-of-file condition is encountered. If any characters are read or if len == 1, the @@ -1382,14 +1378,14 @@ ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); buf are indeterminate. */ -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -/* + ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); + /* Writes c, converted to an unsigned char, into the compressed file. gzputc returns the value that was written, or -1 in case of error. */ -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -/* + ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); + /* Reads one byte from the compressed file. gzgetc returns this byte or -1 in case of end of file or error. This is implemented as a macro for speed. As such, it does not do all of the checking the other functions do. I.e. @@ -1397,8 +1393,8 @@ ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); points to has been clobbered or not. */ -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* + ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); + /* Push one character back onto the stream to be read as the first character on the next read. At least one character of push-back is allowed. gzungetc() returns the character pushed, or -1 on failure. gzungetc() will @@ -1409,8 +1405,8 @@ ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); gzseek() or gzrewind(). */ -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -/* + ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); + /* Flushes all pending output into the compressed file. The parameter flush is as in the deflate() function. The return value is the zlib error number (see function gzerror below). gzflush is only permitted when writing. @@ -1424,7 +1420,7 @@ ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); degrade compression if called too often. */ -/* + /* ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, z_off_t offset, int whence)); @@ -1444,14 +1440,14 @@ ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, would be before the current position. */ -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -/* + ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); + /* Rewinds the given file. This function is supported only for reading. gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) */ -/* + /* ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); Returns the starting position for the next gzread or gzwrite on the given @@ -1462,7 +1458,7 @@ ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) */ -/* + /* ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); Returns the current offset in the file being read or written. This offset @@ -1472,8 +1468,8 @@ ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); for a progress indicator. On error, gzoffset() returns -1. */ -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -/* + ZEXTERN int ZEXPORT gzeof OF((gzFile file)); + /* Returns true (1) if the end-of-file indicator has been set while reading, false (0) otherwise. Note that the end-of-file indicator is set only if the read tried to go past the end of the input, but came up short. Therefore, @@ -1487,8 +1483,8 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file)); has grown since the previous end of file was detected. */ -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); -/* + ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); + /* Returns true (1) if file is being copied directly while reading, or false (0) if file is a gzip stream being decompressed. @@ -1508,8 +1504,8 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); gzip file reading and decompression, which may not be desired.) */ -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -/* + ZEXTERN int ZEXPORT gzclose OF((gzFile file)); + /* Flushes all pending output if necessary, closes the compressed file and deallocates the (de)compression state. Note that once file is closed, you cannot call gzerror with file, since its structures have been deallocated. @@ -1521,9 +1517,9 @@ ZEXTERN int ZEXPORT gzclose OF((gzFile file)); last read ended in the middle of a gzip stream, or Z_OK on success. */ -ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); -ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); -/* + ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); + ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); + /* Same as gzclose(), but gzclose_r() is only for use when reading, and gzclose_w() is only for use when writing or appending. The advantage to using these instead of gzclose() is that they avoid linking in zlib @@ -1533,8 +1529,8 @@ ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); zlib library. */ -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); -/* + ZEXTERN const char *ZEXPORT gzerror OF((gzFile file, int *errnum)); + /* Returns the error message for the last error which occurred on the given compressed file. errnum is set to zlib error number. If an error occurred in the file system and not in the compression library, errnum is set to @@ -1549,8 +1545,8 @@ ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); functions above that do not distinguish those cases in their return values. */ -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* + ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); + /* Clears the error and end-of-file flags for file. This is analogous to the clearerr() function in stdio. This is useful for continuing to read a gzip file that is being written concurrently. @@ -1558,16 +1554,16 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); #endif /* !Z_SOLO */ - /* checksum functions */ + /* checksum functions */ -/* + /* These functions are not related to compression but are exported anyway because they might be useful in applications using the compression library. */ -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -/* + ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); + /* Update a running Adler-32 checksum with the bytes buf[0..len-1] and return the updated checksum. If buf is Z_NULL, this function returns the required initial value for the checksum. @@ -1585,7 +1581,7 @@ ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); if (adler != original_adler) error(); */ -/* + /* ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, z_off_t len2)); @@ -1597,8 +1593,8 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, negative, the result has no meaning or utility. */ -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* + ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); + /* Update a running CRC-32 with the bytes buf[0..len-1] and return the updated CRC-32. If buf is Z_NULL, this function returns the required initial value for the crc. Pre- and post-conditioning (one's complement) is @@ -1614,7 +1610,7 @@ ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); if (crc != original_crc) error(); */ -/* + /* ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); Combine two CRC-32 check values into one. For two sequences of bytes, @@ -1624,62 +1620,62 @@ ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); len2. */ + /* various hacks, don't look :) */ - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version + /* deflateInit and inflateInit are macros to allow checking the zlib version * and the compiler's view of z_stream: */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); + ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, + const char *version, int stream_size)); + ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, + const char *version, int stream_size)); + ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, + int windowBits, int memLevel, + int strategy, const char *version, + int stream_size)); + ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, + const char *version, int stream_size)); + ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, + unsigned char FAR *window, + const char *version, + int stream_size)); #define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) + deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream)) #define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) + inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream)) #define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) -#define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ - (int)sizeof(z_stream)) -#define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, (int)sizeof(z_stream)) + deflateInit2_((strm), (level), (method), (windowBits), (memLevel), \ + (strategy), ZLIB_VERSION, (int)sizeof(z_stream)) +#define inflateInit2(strm, windowBits) \ + inflateInit2_((strm), (windowBits), ZLIB_VERSION, \ + (int)sizeof(z_stream)) +#define inflateBackInit(strm, windowBits, window) \ + inflateBackInit_((strm), (windowBits), (window), \ + ZLIB_VERSION, (int)sizeof(z_stream)) #ifndef Z_SOLO -/* gzgetc() macro and its supporting function and exposed data structure. Note + /* gzgetc() macro and its supporting function and exposed data structure. Note * that the real internal state is much larger than the exposed structure. * This abbreviated structure exposes just enough for the gzgetc() macro. The * user should not mess with these exposed elements, since their names or * behavior could change in the future, perhaps even capriciously. They can * only be used by the gzgetc() macro. You have been warned. */ -struct gzFile_s { - unsigned have; - unsigned char *next; - z_off64_t pos; -}; -ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ + struct gzFile_s + { + unsigned have; + unsigned char *next; + z_off64_t pos; + }; + ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ #ifdef Z_PREFIX_SET -# undef z_gzgetc -# define z_gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) +#undef z_gzgetc +#define z_gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) #else -# define gzgetc(g) \ - ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) +#define gzgetc(g) \ + ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g)) #endif /* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or @@ -1689,76 +1685,79 @@ ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */ * without large file support, _LFS64_LARGEFILE must also be true */ #ifdef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); + ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); #endif #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64) -# ifdef Z_PREFIX_SET -# define z_gzopen z_gzopen64 -# define z_gzseek z_gzseek64 -# define z_gztell z_gztell64 -# define z_gzoffset z_gzoffset64 -# define z_adler32_combine z_adler32_combine64 -# define z_crc32_combine z_crc32_combine64 -# else -# define gzopen gzopen64 -# define gzseek gzseek64 -# define gztell gztell64 -# define gzoffset gzoffset64 -# define adler32_combine adler32_combine64 -# define crc32_combine crc32_combine64 -# endif -# ifndef Z_LARGE64 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); -# endif +#ifdef Z_PREFIX_SET +#define z_gzopen z_gzopen64 +#define z_gzseek z_gzseek64 +#define z_gztell z_gztell64 +#define z_gzoffset z_gzoffset64 +#define z_adler32_combine z_adler32_combine64 +#define z_crc32_combine z_crc32_combine64 #else - ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +#define gzopen gzopen64 +#define gzseek gzseek64 +#define gztell gztell64 +#define gzoffset gzoffset64 +#define adler32_combine adler32_combine64 +#define crc32_combine crc32_combine64 +#endif +#ifndef Z_LARGE64 + ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); +#endif +#else + ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); + ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); + ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); + ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); + ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); + ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); #endif #else /* Z_SOLO */ - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); +ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); +ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); #endif /* !Z_SOLO */ /* hack for buggy compilers */ #if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; + struct internal_state + { + int dummy; + }; #endif -/* undocumented functions */ -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); -ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void)); -ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); -ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); -ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); + /* undocumented functions */ + ZEXTERN const char *ZEXPORT zError OF((int)); + ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); + ZEXTERN const z_crc_t FAR *ZEXPORT get_crc_table OF((void)); + ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); + ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp)); + ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp)); #if defined(_WIN32) && !defined(Z_SOLO) -ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, - const char *mode)); + ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path, + const char *mode)); #endif #if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifndef Z_SOLO -ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, - const char *format, - va_list va)); -# endif +#ifndef Z_SOLO + ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file, + const char *format, + va_list va)); +#endif #endif #ifdef __cplusplus diff --git a/examples/ThirdPartyLibs/zlib/zutil.c b/examples/ThirdPartyLibs/zlib/zutil.c index 23d2ebef0..8da4f0cc3 100644 --- a/examples/ThirdPartyLibs/zlib/zutil.c +++ b/examples/ThirdPartyLibs/zlib/zutil.c @@ -7,180 +7,211 @@ #include "zutil.h" #ifndef Z_SOLO -# include "gzguts.h" +#include "gzguts.h" #endif #ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ +struct internal_state +{ + int dummy; +}; /* for buggy compilers */ #endif -z_const char * const z_errmsg[10] = { -"need dictionary", /* Z_NEED_DICT 2 */ -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -"incompatible version",/* Z_VERSION_ERROR (-6) */ -""}; +z_const char* const z_errmsg[10] = { + "need dictionary", /* Z_NEED_DICT 2 */ + "stream end", /* Z_STREAM_END 1 */ + "", /* Z_OK 0 */ + "file error", /* Z_ERRNO (-1) */ + "stream error", /* Z_STREAM_ERROR (-2) */ + "data error", /* Z_DATA_ERROR (-3) */ + "insufficient memory", /* Z_MEM_ERROR (-4) */ + "buffer error", /* Z_BUF_ERROR (-5) */ + "incompatible version", /* Z_VERSION_ERROR (-6) */ + ""}; - -const char * ZEXPORT zlibVersion() +const char* ZEXPORT zlibVersion() { - return ZLIB_VERSION; + return ZLIB_VERSION; } uLong ZEXPORT zlibCompileFlags() { - uLong flags; + uLong flags; - flags = 0; - switch ((int)(sizeof(uInt))) { - case 2: break; - case 4: flags += 1; break; - case 8: flags += 2; break; - default: flags += 3; - } - switch ((int)(sizeof(uLong))) { - case 2: break; - case 4: flags += 1 << 2; break; - case 8: flags += 2 << 2; break; - default: flags += 3 << 2; - } - switch ((int)(sizeof(voidpf))) { - case 2: break; - case 4: flags += 1 << 4; break; - case 8: flags += 2 << 4; break; - default: flags += 3 << 4; - } - switch ((int)(sizeof(z_off_t))) { - case 2: break; - case 4: flags += 1 << 6; break; - case 8: flags += 2 << 6; break; - default: flags += 3 << 6; - } + flags = 0; + switch ((int)(sizeof(uInt))) + { + case 2: + break; + case 4: + flags += 1; + break; + case 8: + flags += 2; + break; + default: + flags += 3; + } + switch ((int)(sizeof(uLong))) + { + case 2: + break; + case 4: + flags += 1 << 2; + break; + case 8: + flags += 2 << 2; + break; + default: + flags += 3 << 2; + } + switch ((int)(sizeof(voidpf))) + { + case 2: + break; + case 4: + flags += 1 << 4; + break; + case 8: + flags += 2 << 4; + break; + default: + flags += 3 << 4; + } + switch ((int)(sizeof(z_off_t))) + { + case 2: + break; + case 4: + flags += 1 << 6; + break; + case 8: + flags += 2 << 6; + break; + default: + flags += 3 << 6; + } #ifdef DEBUG - flags += 1 << 8; + flags += 1 << 8; #endif #if defined(ASMV) || defined(ASMINF) - flags += 1 << 9; + flags += 1 << 9; #endif #ifdef ZLIB_WINAPI - flags += 1 << 10; + flags += 1 << 10; #endif #ifdef BUILDFIXED - flags += 1 << 12; + flags += 1 << 12; #endif #ifdef DYNAMIC_CRC_TABLE - flags += 1 << 13; + flags += 1 << 13; #endif #ifdef NO_GZCOMPRESS - flags += 1L << 16; + flags += 1L << 16; #endif #ifdef NO_GZIP - flags += 1L << 17; + flags += 1L << 17; #endif #ifdef PKZIP_BUG_WORKAROUND - flags += 1L << 20; + flags += 1L << 20; #endif #ifdef FASTEST - flags += 1L << 21; + flags += 1L << 21; #endif #if defined(STDC) || defined(Z_HAVE_STDARG_H) -# ifdef NO_vsnprintf - flags += 1L << 25; -# ifdef HAS_vsprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_vsnprintf_void - flags += 1L << 26; -# endif -# endif -#else - flags += 1L << 24; -# ifdef NO_snprintf - flags += 1L << 25; -# ifdef HAS_sprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_snprintf_void - flags += 1L << 26; -# endif -# endif +#ifdef NO_vsnprintf + flags += 1L << 25; +#ifdef HAS_vsprintf_void + flags += 1L << 26; #endif - return flags; +#else +#ifdef HAS_vsnprintf_void + flags += 1L << 26; +#endif +#endif +#else + flags += 1L << 24; +#ifdef NO_snprintf + flags += 1L << 25; +#ifdef HAS_sprintf_void + flags += 1L << 26; +#endif +#else +#ifdef HAS_snprintf_void + flags += 1L << 26; +#endif +#endif +#endif + return flags; } #ifdef DEBUG -# ifndef verbose -# define verbose 0 -# endif +#ifndef verbose +#define verbose 0 +#endif int ZLIB_INTERNAL z_verbose = verbose; -void ZLIB_INTERNAL z_error (m) - char *m; +void ZLIB_INTERNAL z_error(m) char* m; { - fprintf(stderr, "%s\n", m); - exit(1); + fprintf(stderr, "%s\n", m); + exit(1); } #endif /* exported to allow conversion of error code to string for compress() and * uncompress() */ -const char * ZEXPORT zError(err) - int err; +const char* ZEXPORT zError(err) int err; { - return ERR_MSG(err); + return ERR_MSG(err); } #if defined(_WIN32_WCE) - /* The Microsoft C Run-Time Library for Windows CE doesn't have +/* The Microsoft C Run-Time Library for Windows CE doesn't have * errno. We define it as a global variable to simplify porting. * Its value is always 0 and should not be used. */ - int errno = 0; +int errno = 0; #endif #ifndef HAVE_MEMCPY void ZLIB_INTERNAL zmemcpy(dest, source, len) - Bytef* dest; - const Bytef* source; - uInt len; + Bytef* dest; +const Bytef* source; +uInt len; { - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); + if (len == 0) return; + do + { + *dest++ = *source++; /* ??? to be unrolled */ + } while (--len != 0); } int ZLIB_INTERNAL zmemcmp(s1, s2, len) - const Bytef* s1; - const Bytef* s2; - uInt len; + const Bytef* s1; +const Bytef* s2; +uInt len; { - uInt j; + uInt j; - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; - } - return 0; + for (j = 0; j < len; j++) + { + if (s1[j] != s2[j]) return 2 * (s1[j] > s2[j]) - 1; + } + return 0; } void ZLIB_INTERNAL zmemzero(dest, len) - Bytef* dest; - uInt len; + Bytef* dest; +uInt len; { - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); + if (len == 0) return; + do + { + *dest++ = 0; /* ??? to be unrolled */ + } while (--len != 0); } #endif @@ -191,7 +222,7 @@ void ZLIB_INTERNAL zmemzero(dest, len) #ifdef __TURBOC__ /* Turbo C in 16-bit mode */ -# define MY_ZCALLOC +#define MY_ZCALLOC /* Turbo C malloc() does not allow dynamic allocation of 64K bytes * and farmalloc(64K) returns a pointer with an offset of 8, so we @@ -204,9 +235,10 @@ void ZLIB_INTERNAL zmemzero(dest, len) local int next_ptr = 0; -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; +typedef struct ptr_table_s +{ + voidpf org_ptr; + voidpf new_ptr; } ptr_table; local ptr_table table[MAX_PTR]; @@ -217,106 +249,109 @@ local ptr_table table[MAX_PTR]; * a protected system like OS/2. Use Microsoft C instead. */ -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, unsigned items, unsigned size) { - voidpf buf = opaque; /* just to make some compilers happy */ - ulg bsize = (ulg)items*size; + voidpf buf = opaque; /* just to make some compilers happy */ + ulg bsize = (ulg)items * size; - /* If we allocate less than 65520 bytes, we assume that farmalloc + /* If we allocate less than 65520 bytes, we assume that farmalloc * will return a usable pointer which doesn't have to be normalized. */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush*)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; + if (bsize < 65520L) + { + buf = farmalloc(bsize); + if (*(ush*)&buf != 0) return buf; + } + else + { + buf = farmalloc(bsize + 16L); + } + if (buf == NULL || next_ptr >= MAX_PTR) return NULL; + table[next_ptr].org_ptr = buf; - /* Normalize the pointer to seg:0 */ - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; - *(ush*)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; + /* Normalize the pointer to seg:0 */ + *((ush*)&buf + 1) += ((ush)((uch*)buf - 0) + 15) >> 4; + *(ush*)&buf = 0; + table[next_ptr++].new_ptr = buf; + return buf; } -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { - int n; - if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; + int n; + if (*(ush*)&ptr != 0) + { /* object < 64K */ + farfree(ptr); + return; + } + /* Find the original pointer */ + for (n = 0; n < next_ptr; n++) + { + if (ptr != table[n].new_ptr) continue; - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n-1] = table[n]; - } - next_ptr--; - return; - } - ptr = opaque; /* just to make some compilers happy */ - Assert(0, "zcfree: ptr not found"); + farfree(table[n].org_ptr); + while (++n < next_ptr) + { + table[n - 1] = table[n]; + } + next_ptr--; + return; + } + ptr = opaque; /* just to make some compilers happy */ + Assert(0, "zcfree: ptr not found"); } #endif /* __TURBOC__ */ - #ifdef M_I86 /* Microsoft C in 16-bit mode */ -# define MY_ZCALLOC +#define MY_ZCALLOC #if (!defined(_MSC_VER) || (_MSC_VER <= 600)) -# define _halloc halloc -# define _hfree hfree +#define _halloc halloc +#define _hfree hfree #endif -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) +voidpf ZLIB_INTERNAL zcalloc(voidpf opaque, uInt items, uInt size) { - if (opaque) opaque = 0; /* to make compiler happy */ - return _halloc((long)items, size); + if (opaque) opaque = 0; /* to make compiler happy */ + return _halloc((long)items, size); } -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) +void ZLIB_INTERNAL zcfree(voidpf opaque, voidpf ptr) { - if (opaque) opaque = 0; /* to make compiler happy */ - _hfree(ptr); + if (opaque) opaque = 0; /* to make compiler happy */ + _hfree(ptr); } #endif /* M_I86 */ #endif /* SYS16BIT */ - #ifndef MY_ZCALLOC /* Any system without a special alloc function */ #ifndef STDC -extern voidp malloc OF((uInt size)); -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); +extern voidp malloc OF((uInt size)); +extern voidp calloc OF((uInt items, uInt size)); +extern void free OF((voidpf ptr)); #endif -voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) - voidpf opaque; - unsigned items; - unsigned size; +voidpf ZLIB_INTERNAL zcalloc(opaque, items, size) + voidpf opaque; +unsigned items; +unsigned size; { - if (opaque) items += size - size; /* make compiler happy */ - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : - (voidpf)calloc(items, size); + if (opaque) items += size - size; /* make compiler happy */ + return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : (voidpf)calloc(items, size); } -void ZLIB_INTERNAL zcfree (opaque, ptr) - voidpf opaque; - voidpf ptr; +void ZLIB_INTERNAL zcfree(opaque, ptr) + voidpf opaque; +voidpf ptr; { - free(ptr); - if (opaque) return; /* make compiler happy */ + free(ptr); + if (opaque) return; /* make compiler happy */ } #endif /* MY_ZCALLOC */ diff --git a/examples/ThirdPartyLibs/zlib/zutil.h b/examples/ThirdPartyLibs/zlib/zutil.h index 24ab06b1c..fea108324 100644 --- a/examples/ThirdPartyLibs/zlib/zutil.h +++ b/examples/ThirdPartyLibs/zlib/zutil.h @@ -14,240 +14,261 @@ #define ZUTIL_H #ifdef HAVE_HIDDEN -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) +#define ZLIB_INTERNAL __attribute__((visibility("hidden"))) #else -# define ZLIB_INTERNAL +#define ZLIB_INTERNAL #endif #include "zlib.h" #if defined(STDC) && !defined(Z_SOLO) -# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) -# include -# endif -# include -# include +#if !(defined(_WIN32_WCE) && defined(_MSC_VER)) +#include +#endif +#include +#include #endif #ifdef Z_SOLO - typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ +typedef long ptrdiff_t; /* guess -- will be caught if guess is wrong */ #endif #ifndef local -# define local static +#define local static #endif /* compile with -Dlocal if your debugger can't find static symbols */ -typedef unsigned char uch; +typedef unsigned char uch; typedef uch FAR uchf; typedef unsigned short ush; typedef ush FAR ushf; -typedef unsigned long ulg; +typedef unsigned long ulg; -extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ +extern z_const char *const z_errmsg[10]; /* indexed by 2-zlib_error */ /* (size given to avoid silly warnings with Visual C++) */ -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] +#define ERR_MSG(err) z_errmsg[Z_NEED_DICT - (err)] -#define ERR_RETURN(strm,err) \ - return (strm->msg = ERR_MSG(err), (err)) +#define ERR_RETURN(strm, err) \ + return (strm->msg = ERR_MSG(err), (err)) /* To be used only when the state is known to be valid */ - /* common constants */ +/* common constants */ #ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS +#define DEF_WBITS MAX_WBITS #endif /* default windowBits for decompression. MAX_WBITS is for compression only */ #if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 +#define DEF_MEM_LEVEL 8 #else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL +#define DEF_MEM_LEVEL MAX_MEM_LEVEL #endif /* default memLevel */ #define STORED_BLOCK 0 #define STATIC_TREES 1 -#define DYN_TREES 2 +#define DYN_TREES 2 /* The three kinds of block type */ -#define MIN_MATCH 3 -#define MAX_MATCH 258 +#define MIN_MATCH 3 +#define MAX_MATCH 258 /* The minimum and maximum match lengths */ #define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - /* target dependencies */ +/* target dependencies */ #if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) -# define OS_CODE 0x00 -# ifndef Z_SOLO -# if defined(__TURBOC__) || defined(__BORLANDC__) -# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) - /* Allow compilation with ANSI keywords only enabled */ - void _Cdecl farfree( void *block ); - void *_Cdecl farmalloc( unsigned long nbytes ); -# else -# include -# endif -# else /* MSC or DJGPP */ -# include -# endif -# endif +#define OS_CODE 0x00 +#ifndef Z_SOLO +#if defined(__TURBOC__) || defined(__BORLANDC__) +#if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) +/* Allow compilation with ANSI keywords only enabled */ +void _Cdecl farfree(void *block); +void *_Cdecl farmalloc(unsigned long nbytes); +#else +#include +#endif +#else /* MSC or DJGPP */ +#include +#endif +#endif #endif #ifdef AMIGA -# define OS_CODE 0x01 +#define OS_CODE 0x01 #endif #if defined(VAXC) || defined(VMS) -# define OS_CODE 0x02 -# define F_OPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") +#define OS_CODE 0x02 +#define F_OPEN(name, mode) \ + fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") #endif #if defined(ATARI) || defined(atarist) -# define OS_CODE 0x05 +#define OS_CODE 0x05 #endif #ifdef OS2 -# define OS_CODE 0x06 -# if defined(M_I86) && !defined(Z_SOLO) -# include -# endif +#define OS_CODE 0x06 +#if defined(M_I86) && !defined(Z_SOLO) +#include +#endif #endif #if defined(MACOS) || defined(TARGET_OS_MAC) -# define OS_CODE 0x07 -# ifndef Z_SOLO -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -# endif +#define OS_CODE 0x07 +#ifndef Z_SOLO +#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os +#include /* for fdopen */ +#else +#ifndef fdopen +#define fdopen(fd, mode) NULL /* No fdopen() */ +#endif +#endif +#endif #endif #ifdef TOPS20 -# define OS_CODE 0x0a +#define OS_CODE 0x0a #endif #ifdef WIN32 -# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ -# define OS_CODE 0x0b -# endif +#ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ +#define OS_CODE 0x0b +#endif #endif #ifdef __50SERIES /* Prime/PRIMOS */ -# define OS_CODE 0x0f +#define OS_CODE 0x0f #endif #if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ +#define fdopen(fd, mode) NULL /* No fdopen() */ #endif #if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# ifndef _PTRDIFF_T_DEFINED - typedef int ptrdiff_t; -# define _PTRDIFF_T_DEFINED -# endif -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif +#if defined(_WIN32_WCE) +#define fdopen(fd, mode) NULL /* No fdopen() */ +#ifndef _PTRDIFF_T_DEFINED +typedef int ptrdiff_t; +#define _PTRDIFF_T_DEFINED +#endif +#else +#define fdopen(fd, type) _fdopen(fd, type) +#endif #endif #if defined(__BORLANDC__) && !defined(MSDOS) - #pragma warn -8004 - #pragma warn -8008 - #pragma warn -8066 +#pragma warn - 8004 +#pragma warn - 8008 +#pragma warn - 8066 #endif /* provide prototypes for these when building zlib without LFS */ #if !defined(_WIN32) && \ - (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0) - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); + (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE - 0 == 0) +ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); +ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); #endif - /* common defaults */ +/* common defaults */ #ifndef OS_CODE -# define OS_CODE 0x03 /* assume Unix */ +#define OS_CODE 0x03 /* assume Unix */ #endif #ifndef F_OPEN -# define F_OPEN(name, mode) fopen((name), (mode)) +#define F_OPEN(name, mode) fopen((name), (mode)) #endif - /* functions */ +/* functions */ #if defined(pyr) || defined(Z_SOLO) -# define NO_MEMCPY +#define NO_MEMCPY #endif #if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) - /* Use our own functions for small and medium model with MSC <= 5.0. +/* Use our own functions for small and medium model with MSC <= 5.0. * You may have to use the same strategy for Borland C (untested). * The __SC__ check is for Symantec. */ -# define NO_MEMCPY +#define NO_MEMCPY #endif #if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -# define HAVE_MEMCPY +#define HAVE_MEMCPY #endif #ifdef HAVE_MEMCPY -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ -# define zmemcpy _fmemcpy -# define zmemcmp _fmemcmp -# define zmemzero(dest, len) _fmemset(dest, 0, len) -# else -# define zmemcpy memcpy -# define zmemcmp memcmp -# define zmemzero(dest, len) memset(dest, 0, len) -# endif +#ifdef SMALL_MEDIUM /* MSDOS small or medium model */ +#define zmemcpy _fmemcpy +#define zmemcmp _fmemcmp +#define zmemzero(dest, len) _fmemset(dest, 0, len) #else - void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); - int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); - void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); +#define zmemcpy memcpy +#define zmemcmp memcmp +#define zmemzero(dest, len) memset(dest, 0, len) +#endif +#else +void ZLIB_INTERNAL zmemcpy OF((Bytef * dest, const Bytef* source, uInt len)); +int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); +void ZLIB_INTERNAL zmemzero OF((Bytef * dest, uInt len)); #endif /* Diagnostic functions */ #ifdef DEBUG -# include - extern int ZLIB_INTERNAL z_verbose; - extern void ZLIB_INTERNAL z_error OF((char *m)); -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) {if (z_verbose>=0) fprintf x ;} -# define Tracev(x) {if (z_verbose>0) fprintf x ;} -# define Tracevv(x) {if (z_verbose>1) fprintf x ;} -# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} -# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} +#include +extern int ZLIB_INTERNAL z_verbose; +extern void ZLIB_INTERNAL z_error OF((char *m)); +#define Assert(cond, msg) \ + { \ + if (!(cond)) z_error(msg); \ + } +#define Trace(x) \ + { \ + if (z_verbose >= 0) fprintf x; \ + } +#define Tracev(x) \ + { \ + if (z_verbose > 0) fprintf x; \ + } +#define Tracevv(x) \ + { \ + if (z_verbose > 1) fprintf x; \ + } +#define Tracec(c, x) \ + { \ + if (z_verbose > 0 && (c)) fprintf x; \ + } +#define Tracecv(c, x) \ + { \ + if (z_verbose > 1 && (c)) fprintf x; \ + } #else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) +#define Assert(cond, msg) +#define Trace(x) +#define Tracev(x) +#define Tracevv(x) +#define Tracec(c, x) +#define Tracecv(c, x) #endif #ifndef Z_SOLO - voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, - unsigned size)); - void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); +voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, + unsigned size)); +void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); #endif #define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} + (*((strm)->zalloc))((strm)->opaque, (items), (size)) +#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) +#define TRY_FREE(s, p) \ + { \ + if (p) ZFREE(s, p); \ + } /* Reverse the bytes in a 32-bit value */ #define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) + (((q)&0xff00) << 8) + (((q)&0xff) << 24)) #endif /* ZUTIL_H */ diff --git a/examples/TinyAudio/RtAudio.cpp b/examples/TinyAudio/RtAudio.cpp index bd2a520f4..882a478b1 100644 --- a/examples/TinyAudio/RtAudio.cpp +++ b/examples/TinyAudio/RtAudio.cpp @@ -50,40 +50,39 @@ // Static variable definitions. const unsigned int RtApi::MAX_SAMPLE_RATES = 14; const unsigned int RtApi::SAMPLE_RATES[] = { - 4000, 5512, 8000, 9600, 11025, 16000, 22050, - 32000, 44100, 48000, 88200, 96000, 176400, 192000 -}; + 4000, 5512, 8000, 9600, 11025, 16000, 22050, + 32000, 44100, 48000, 88200, 96000, 176400, 192000}; #if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__) || defined(__WINDOWS_WASAPI__) - #define MUTEX_INITIALIZE(A) InitializeCriticalSection(A) - #define MUTEX_DESTROY(A) DeleteCriticalSection(A) - #define MUTEX_LOCK(A) EnterCriticalSection(A) - #define MUTEX_UNLOCK(A) LeaveCriticalSection(A) +#define MUTEX_INITIALIZE(A) InitializeCriticalSection(A) +#define MUTEX_DESTROY(A) DeleteCriticalSection(A) +#define MUTEX_LOCK(A) EnterCriticalSection(A) +#define MUTEX_UNLOCK(A) LeaveCriticalSection(A) - #include "tchar.h" +#include "tchar.h" - static std::string convertCharPointerToStdString(const char *text) - { - return std::string(text); - } +static std::string convertCharPointerToStdString(const char *text) +{ + return std::string(text); +} - static std::string convertCharPointerToStdString(const wchar_t *text) - { - int length = WideCharToMultiByte(CP_UTF8, 0, text, -1, NULL, 0, NULL, NULL); - std::string s( length-1, '\0' ); - WideCharToMultiByte(CP_UTF8, 0, text, -1, &s[0], length, NULL, NULL); - return s; - } +static std::string convertCharPointerToStdString(const wchar_t *text) +{ + int length = WideCharToMultiByte(CP_UTF8, 0, text, -1, NULL, 0, NULL, NULL); + std::string s(length - 1, '\0'); + WideCharToMultiByte(CP_UTF8, 0, text, -1, &s[0], length, NULL, NULL); + return s; +} #elif defined(__LINUX_ALSA__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__) - // pthread API - #define MUTEX_INITIALIZE(A) pthread_mutex_init(A, NULL) - #define MUTEX_DESTROY(A) pthread_mutex_destroy(A) - #define MUTEX_LOCK(A) pthread_mutex_lock(A) - #define MUTEX_UNLOCK(A) pthread_mutex_unlock(A) +// pthread API +#define MUTEX_INITIALIZE(A) pthread_mutex_init(A, NULL) +#define MUTEX_DESTROY(A) pthread_mutex_destroy(A) +#define MUTEX_LOCK(A) pthread_mutex_lock(A) +#define MUTEX_UNLOCK(A) pthread_mutex_unlock(A) #else - #define MUTEX_INITIALIZE(A) abs(*A) // dummy definitions - #define MUTEX_DESTROY(A) abs(*A) // dummy definitions +#define MUTEX_INITIALIZE(A) abs(*A) // dummy definitions +#define MUTEX_DESTROY(A) abs(*A) // dummy definitions #endif // *************************************************** // @@ -92,140 +91,143 @@ const unsigned int RtApi::SAMPLE_RATES[] = { // // *************************************************** // -std::string RtAudio :: getVersion( void ) throw() +std::string RtAudio ::getVersion(void) throw() { - return RTAUDIO_VERSION; + return RTAUDIO_VERSION; } -void RtAudio :: getCompiledApi( std::vector &apis ) throw() +void RtAudio ::getCompiledApi(std::vector &apis) throw() { - apis.clear(); + apis.clear(); - // The order here will control the order of RtAudio's API search in - // the constructor. + // The order here will control the order of RtAudio's API search in + // the constructor. #if defined(__UNIX_JACK__) - apis.push_back( UNIX_JACK ); + apis.push_back(UNIX_JACK); #endif #if defined(__LINUX_ALSA__) - apis.push_back( LINUX_ALSA ); + apis.push_back(LINUX_ALSA); #endif #if defined(__LINUX_PULSE__) - apis.push_back( LINUX_PULSE ); + apis.push_back(LINUX_PULSE); #endif #if defined(__LINUX_OSS__) - apis.push_back( LINUX_OSS ); + apis.push_back(LINUX_OSS); #endif #if defined(__WINDOWS_ASIO__) - apis.push_back( WINDOWS_ASIO ); + apis.push_back(WINDOWS_ASIO); #endif #if defined(__WINDOWS_WASAPI__) - apis.push_back( WINDOWS_WASAPI ); + apis.push_back(WINDOWS_WASAPI); #endif #if defined(__WINDOWS_DS__) - apis.push_back( WINDOWS_DS ); + apis.push_back(WINDOWS_DS); #endif #if defined(__MACOSX_CORE__) - apis.push_back( MACOSX_CORE ); + apis.push_back(MACOSX_CORE); #endif #if defined(__RTAUDIO_DUMMY__) - apis.push_back( RTAUDIO_DUMMY ); + apis.push_back(RTAUDIO_DUMMY); #endif } -void RtAudio :: openRtApi( RtAudio::Api api ) +void RtAudio ::openRtApi(RtAudio::Api api) { - if ( rtapi_ ) - delete rtapi_; - rtapi_ = 0; + if (rtapi_) + delete rtapi_; + rtapi_ = 0; #if defined(__UNIX_JACK__) - if ( api == UNIX_JACK ) - rtapi_ = new RtApiJack(); + if (api == UNIX_JACK) + rtapi_ = new RtApiJack(); #endif #if defined(__LINUX_ALSA__) - if ( api == LINUX_ALSA ) - rtapi_ = new RtApiAlsa(); + if (api == LINUX_ALSA) + rtapi_ = new RtApiAlsa(); #endif #if defined(__LINUX_PULSE__) - if ( api == LINUX_PULSE ) - rtapi_ = new RtApiPulse(); + if (api == LINUX_PULSE) + rtapi_ = new RtApiPulse(); #endif #if defined(__LINUX_OSS__) - if ( api == LINUX_OSS ) - rtapi_ = new RtApiOss(); + if (api == LINUX_OSS) + rtapi_ = new RtApiOss(); #endif #if defined(__WINDOWS_ASIO__) - if ( api == WINDOWS_ASIO ) - rtapi_ = new RtApiAsio(); + if (api == WINDOWS_ASIO) + rtapi_ = new RtApiAsio(); #endif #if defined(__WINDOWS_WASAPI__) - if ( api == WINDOWS_WASAPI ) - rtapi_ = new RtApiWasapi(); + if (api == WINDOWS_WASAPI) + rtapi_ = new RtApiWasapi(); #endif #if defined(__WINDOWS_DS__) - if ( api == WINDOWS_DS ) - rtapi_ = new RtApiDs(); + if (api == WINDOWS_DS) + rtapi_ = new RtApiDs(); #endif #if defined(__MACOSX_CORE__) - if ( api == MACOSX_CORE ) - rtapi_ = new RtApiCore(); + if (api == MACOSX_CORE) + rtapi_ = new RtApiCore(); #endif #if defined(__RTAUDIO_DUMMY__) - if ( api == RTAUDIO_DUMMY ) - rtapi_ = new RtApiDummy(); + if (api == RTAUDIO_DUMMY) + rtapi_ = new RtApiDummy(); #endif } -RtAudio :: RtAudio( RtAudio::Api api ) +RtAudio ::RtAudio(RtAudio::Api api) { - rtapi_ = 0; + rtapi_ = 0; - if ( api != UNSPECIFIED ) { - // Attempt to open the specified API. - openRtApi( api ); - if ( rtapi_ ) return; + if (api != UNSPECIFIED) + { + // Attempt to open the specified API. + openRtApi(api); + if (rtapi_) return; - // No compiled support for specified API value. Issue a debug - // warning and continue as if no API was specified. - std::cerr << "\nRtAudio: no compiled support for specified API argument!\n" << std::endl; - } + // No compiled support for specified API value. Issue a debug + // warning and continue as if no API was specified. + std::cerr << "\nRtAudio: no compiled support for specified API argument!\n" + << std::endl; + } - // Iterate through the compiled APIs and return as soon as we find - // one with at least one device or we reach the end of the list. - std::vector< RtAudio::Api > apis; - getCompiledApi( apis ); - for ( unsigned int i=0; igetDeviceCount() ) break; - } + // Iterate through the compiled APIs and return as soon as we find + // one with at least one device or we reach the end of the list. + std::vector apis; + getCompiledApi(apis); + for (unsigned int i = 0; i < apis.size(); i++) + { + openRtApi(apis[i]); + if (rtapi_ && rtapi_->getDeviceCount()) break; + } - if ( rtapi_ ) return; + if (rtapi_) return; - // It should not be possible to get here because the preprocessor - // definition __RTAUDIO_DUMMY__ is automatically defined if no - // API-specific definitions are passed to the compiler. But just in - // case something weird happens, we'll thow an error. - std::string errorText = "\nRtAudio: no compiled API support found ... critical error!!\n\n"; - throw( RtAudioError( errorText, RtAudioError::UNSPECIFIED ) ); + // It should not be possible to get here because the preprocessor + // definition __RTAUDIO_DUMMY__ is automatically defined if no + // API-specific definitions are passed to the compiler. But just in + // case something weird happens, we'll thow an error. + std::string errorText = "\nRtAudio: no compiled API support found ... critical error!!\n\n"; + throw(RtAudioError(errorText, RtAudioError::UNSPECIFIED)); } -RtAudio :: ~RtAudio() throw() +RtAudio ::~RtAudio() throw() { - if ( rtapi_ ) - delete rtapi_; + if (rtapi_) + delete rtapi_; } -void RtAudio :: openStream( RtAudio::StreamParameters *outputParameters, - RtAudio::StreamParameters *inputParameters, - RtAudioFormat format, unsigned int sampleRate, - unsigned int *bufferFrames, - RtAudioCallback callback, void *userData, - RtAudio::StreamOptions *options, - RtAudioErrorCallback errorCallback ) +void RtAudio ::openStream(RtAudio::StreamParameters *outputParameters, + RtAudio::StreamParameters *inputParameters, + RtAudioFormat format, unsigned int sampleRate, + unsigned int *bufferFrames, + RtAudioCallback callback, void *userData, + RtAudio::StreamOptions *options, + RtAudioErrorCallback errorCallback) { - return rtapi_->openStream( outputParameters, inputParameters, format, - sampleRate, bufferFrames, callback, - userData, options, errorCallback ); + return rtapi_->openStream(outputParameters, inputParameters, format, + sampleRate, bufferFrames, callback, + userData, options, errorCallback); } // *************************************************** // @@ -235,208 +237,218 @@ void RtAudio :: openStream( RtAudio::StreamParameters *outputParameters, // // *************************************************** // -RtApi :: RtApi() +RtApi ::RtApi() { - stream_.state = STREAM_CLOSED; - stream_.mode = UNINITIALIZED; - stream_.apiHandle = 0; - stream_.userBuffer[0] = 0; - stream_.userBuffer[1] = 0; - MUTEX_INITIALIZE( &stream_.mutex ); - showWarnings_ = true; - firstErrorOccurred_ = false; + stream_.state = STREAM_CLOSED; + stream_.mode = UNINITIALIZED; + stream_.apiHandle = 0; + stream_.userBuffer[0] = 0; + stream_.userBuffer[1] = 0; + MUTEX_INITIALIZE(&stream_.mutex); + showWarnings_ = true; + firstErrorOccurred_ = false; } -RtApi :: ~RtApi() +RtApi ::~RtApi() { - MUTEX_DESTROY( &stream_.mutex ); + MUTEX_DESTROY(&stream_.mutex); } -void RtApi :: openStream( RtAudio::StreamParameters *oParams, - RtAudio::StreamParameters *iParams, - RtAudioFormat format, unsigned int sampleRate, - unsigned int *bufferFrames, - RtAudioCallback callback, void *userData, - RtAudio::StreamOptions *options, - RtAudioErrorCallback errorCallback ) +void RtApi ::openStream(RtAudio::StreamParameters *oParams, + RtAudio::StreamParameters *iParams, + RtAudioFormat format, unsigned int sampleRate, + unsigned int *bufferFrames, + RtAudioCallback callback, void *userData, + RtAudio::StreamOptions *options, + RtAudioErrorCallback errorCallback) { - if ( stream_.state != STREAM_CLOSED ) { - errorText_ = "RtApi::openStream: a stream is already open!"; - error( RtAudioError::INVALID_USE ); - return; - } + if (stream_.state != STREAM_CLOSED) + { + errorText_ = "RtApi::openStream: a stream is already open!"; + error(RtAudioError::INVALID_USE); + return; + } - // Clear stream information potentially left from a previously open stream. - clearStreamInfo(); + // Clear stream information potentially left from a previously open stream. + clearStreamInfo(); - if ( oParams && oParams->nChannels < 1 ) { - errorText_ = "RtApi::openStream: a non-NULL output StreamParameters structure cannot have an nChannels value less than one."; - error( RtAudioError::INVALID_USE ); - return; - } + if (oParams && oParams->nChannels < 1) + { + errorText_ = "RtApi::openStream: a non-NULL output StreamParameters structure cannot have an nChannels value less than one."; + error(RtAudioError::INVALID_USE); + return; + } - if ( iParams && iParams->nChannels < 1 ) { - errorText_ = "RtApi::openStream: a non-NULL input StreamParameters structure cannot have an nChannels value less than one."; - error( RtAudioError::INVALID_USE ); - return; - } + if (iParams && iParams->nChannels < 1) + { + errorText_ = "RtApi::openStream: a non-NULL input StreamParameters structure cannot have an nChannels value less than one."; + error(RtAudioError::INVALID_USE); + return; + } - if ( oParams == NULL && iParams == NULL ) { - errorText_ = "RtApi::openStream: input and output StreamParameters structures are both NULL!"; - error( RtAudioError::INVALID_USE ); - return; - } + if (oParams == NULL && iParams == NULL) + { + errorText_ = "RtApi::openStream: input and output StreamParameters structures are both NULL!"; + error(RtAudioError::INVALID_USE); + return; + } - if ( formatBytes(format) == 0 ) { - errorText_ = "RtApi::openStream: 'format' parameter value is undefined."; - error( RtAudioError::INVALID_USE ); - return; - } + if (formatBytes(format) == 0) + { + errorText_ = "RtApi::openStream: 'format' parameter value is undefined."; + error(RtAudioError::INVALID_USE); + return; + } - unsigned int nDevices = getDeviceCount(); - unsigned int oChannels = 0; - if ( oParams ) { - oChannels = oParams->nChannels; - if ( oParams->deviceId >= nDevices ) { - errorText_ = "RtApi::openStream: output device parameter value is invalid."; - error( RtAudioError::INVALID_USE ); - return; - } - } + unsigned int nDevices = getDeviceCount(); + unsigned int oChannels = 0; + if (oParams) + { + oChannels = oParams->nChannels; + if (oParams->deviceId >= nDevices) + { + errorText_ = "RtApi::openStream: output device parameter value is invalid."; + error(RtAudioError::INVALID_USE); + return; + } + } - unsigned int iChannels = 0; - if ( iParams ) { - iChannels = iParams->nChannels; - if ( iParams->deviceId >= nDevices ) { - errorText_ = "RtApi::openStream: input device parameter value is invalid."; - error( RtAudioError::INVALID_USE ); - return; - } - } + unsigned int iChannels = 0; + if (iParams) + { + iChannels = iParams->nChannels; + if (iParams->deviceId >= nDevices) + { + errorText_ = "RtApi::openStream: input device parameter value is invalid."; + error(RtAudioError::INVALID_USE); + return; + } + } - bool result; + bool result; - if ( oChannels > 0 ) { + if (oChannels > 0) + { + result = probeDeviceOpen(oParams->deviceId, OUTPUT, oChannels, oParams->firstChannel, + sampleRate, format, bufferFrames, options); + if (result == false) + { + error(RtAudioError::SYSTEM_ERROR); + return; + } + } - result = probeDeviceOpen( oParams->deviceId, OUTPUT, oChannels, oParams->firstChannel, - sampleRate, format, bufferFrames, options ); - if ( result == false ) { - error( RtAudioError::SYSTEM_ERROR ); - return; - } - } + if (iChannels > 0) + { + result = probeDeviceOpen(iParams->deviceId, INPUT, iChannels, iParams->firstChannel, + sampleRate, format, bufferFrames, options); + if (result == false) + { + if (oChannels > 0) closeStream(); + error(RtAudioError::SYSTEM_ERROR); + return; + } + } - if ( iChannels > 0 ) { + stream_.callbackInfo.callback = (void *)callback; + stream_.callbackInfo.userData = userData; + stream_.callbackInfo.errorCallback = (void *)errorCallback; - result = probeDeviceOpen( iParams->deviceId, INPUT, iChannels, iParams->firstChannel, - sampleRate, format, bufferFrames, options ); - if ( result == false ) { - if ( oChannels > 0 ) closeStream(); - error( RtAudioError::SYSTEM_ERROR ); - return; - } - } - - stream_.callbackInfo.callback = (void *) callback; - stream_.callbackInfo.userData = userData; - stream_.callbackInfo.errorCallback = (void *) errorCallback; - - if ( options ) options->numberOfBuffers = stream_.nBuffers; - stream_.state = STREAM_STOPPED; + if (options) options->numberOfBuffers = stream_.nBuffers; + stream_.state = STREAM_STOPPED; } -unsigned int RtApi :: getDefaultInputDevice( void ) +unsigned int RtApi ::getDefaultInputDevice(void) { - // Should be implemented in subclasses if possible. - return 0; + // Should be implemented in subclasses if possible. + return 0; } -unsigned int RtApi :: getDefaultOutputDevice( void ) +unsigned int RtApi ::getDefaultOutputDevice(void) { - // Should be implemented in subclasses if possible. - return 0; + // Should be implemented in subclasses if possible. + return 0; } -void RtApi :: closeStream( void ) +void RtApi ::closeStream(void) { - // MUST be implemented in subclasses! - return; + // MUST be implemented in subclasses! + return; } -bool RtApi :: probeDeviceOpen( unsigned int /*device*/, StreamMode /*mode*/, unsigned int /*channels*/, - unsigned int /*firstChannel*/, unsigned int /*sampleRate*/, - RtAudioFormat /*format*/, unsigned int * /*bufferSize*/, - RtAudio::StreamOptions * /*options*/ ) +bool RtApi ::probeDeviceOpen(unsigned int /*device*/, StreamMode /*mode*/, unsigned int /*channels*/, + unsigned int /*firstChannel*/, unsigned int /*sampleRate*/, + RtAudioFormat /*format*/, unsigned int * /*bufferSize*/, + RtAudio::StreamOptions * /*options*/) { - // MUST be implemented in subclasses! - return FAILURE; + // MUST be implemented in subclasses! + return FAILURE; } -void RtApi :: tickStreamTime( void ) +void RtApi ::tickStreamTime(void) { - // Subclasses that do not provide their own implementation of - // getStreamTime should call this function once per buffer I/O to - // provide basic stream time support. + // Subclasses that do not provide their own implementation of + // getStreamTime should call this function once per buffer I/O to + // provide basic stream time support. - stream_.streamTime += ( stream_.bufferSize * 1.0 / stream_.sampleRate ); + stream_.streamTime += (stream_.bufferSize * 1.0 / stream_.sampleRate); -#if defined( HAVE_GETTIMEOFDAY ) - gettimeofday( &stream_.lastTickTimestamp, NULL ); +#if defined(HAVE_GETTIMEOFDAY) + gettimeofday(&stream_.lastTickTimestamp, NULL); #endif } -long RtApi :: getStreamLatency( void ) +long RtApi ::getStreamLatency(void) { - verifyStream(); + verifyStream(); - long totalLatency = 0; - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) - totalLatency = stream_.latency[0]; - if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) - totalLatency += stream_.latency[1]; + long totalLatency = 0; + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + totalLatency = stream_.latency[0]; + if (stream_.mode == INPUT || stream_.mode == DUPLEX) + totalLatency += stream_.latency[1]; - return totalLatency; + return totalLatency; } -double RtApi :: getStreamTime( void ) +double RtApi ::getStreamTime(void) { - verifyStream(); + verifyStream(); -#if defined( HAVE_GETTIMEOFDAY ) - // Return a very accurate estimate of the stream time by - // adding in the elapsed time since the last tick. - struct timeval then; - struct timeval now; +#if defined(HAVE_GETTIMEOFDAY) + // Return a very accurate estimate of the stream time by + // adding in the elapsed time since the last tick. + struct timeval then; + struct timeval now; - if ( stream_.state != STREAM_RUNNING || stream_.streamTime == 0.0 ) - return stream_.streamTime; + if (stream_.state != STREAM_RUNNING || stream_.streamTime == 0.0) + return stream_.streamTime; - gettimeofday( &now, NULL ); - then = stream_.lastTickTimestamp; - return stream_.streamTime + - ((now.tv_sec + 0.000001 * now.tv_usec) - - (then.tv_sec + 0.000001 * then.tv_usec)); + gettimeofday(&now, NULL); + then = stream_.lastTickTimestamp; + return stream_.streamTime + + ((now.tv_sec + 0.000001 * now.tv_usec) - + (then.tv_sec + 0.000001 * then.tv_usec)); #else - return stream_.streamTime; + return stream_.streamTime; #endif } -void RtApi :: setStreamTime( double time ) +void RtApi ::setStreamTime(double time) { - verifyStream(); + verifyStream(); - if ( time >= 0.0 ) - stream_.streamTime = time; + if (time >= 0.0) + stream_.streamTime = time; } -unsigned int RtApi :: getStreamSampleRate( void ) +unsigned int RtApi ::getStreamSampleRate(void) { - verifyStream(); + verifyStream(); - return stream_.sampleRate; + return stream_.sampleRate; } - // *************************************************** // // // OS/API-specific methods. @@ -462,1113 +474,1229 @@ unsigned int RtApi :: getStreamSampleRate( void ) // A structure to hold various information related to the CoreAudio API // implementation. -struct CoreHandle { - AudioDeviceID id[2]; // device ids -#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) - AudioDeviceIOProcID procId[2]; +struct CoreHandle +{ + AudioDeviceID id[2]; // device ids +#if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) + AudioDeviceIOProcID procId[2]; #endif - UInt32 iStream[2]; // device stream index (or first if using multiple) - UInt32 nStreams[2]; // number of streams to use - bool xrun[2]; - char *deviceBuffer; - pthread_cond_t condition; - int drainCounter; // Tracks callback counts when draining - bool internalDrain; // Indicates if stop is initiated from callback or not. + UInt32 iStream[2]; // device stream index (or first if using multiple) + UInt32 nStreams[2]; // number of streams to use + bool xrun[2]; + char *deviceBuffer; + pthread_cond_t condition; + int drainCounter; // Tracks callback counts when draining + bool internalDrain; // Indicates if stop is initiated from callback or not. - CoreHandle() - :deviceBuffer(0), drainCounter(0), internalDrain(false) { nStreams[0] = 1; nStreams[1] = 1; id[0] = 0; id[1] = 0; xrun[0] = false; xrun[1] = false; } + CoreHandle() + : deviceBuffer(0), drainCounter(0), internalDrain(false) + { + nStreams[0] = 1; + nStreams[1] = 1; + id[0] = 0; + id[1] = 0; + xrun[0] = false; + xrun[1] = false; + } }; -RtApiCore:: RtApiCore() +RtApiCore::RtApiCore() { -#if defined( AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER ) - // This is a largely undocumented but absolutely necessary - // requirement starting with OS-X 10.6. If not called, queries and - // updates to various audio device properties are not handled - // correctly. - CFRunLoopRef theRunLoop = NULL; - AudioObjectPropertyAddress property = { kAudioHardwarePropertyRunLoop, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster }; - OSStatus result = AudioObjectSetPropertyData( kAudioObjectSystemObject, &property, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop); - if ( result != noErr ) { - errorText_ = "RtApiCore::RtApiCore: error setting run loop property!"; - error( RtAudioError::WARNING ); - } +#if defined(AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER) + // This is a largely undocumented but absolutely necessary + // requirement starting with OS-X 10.6. If not called, queries and + // updates to various audio device properties are not handled + // correctly. + CFRunLoopRef theRunLoop = NULL; + AudioObjectPropertyAddress property = {kAudioHardwarePropertyRunLoop, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster}; + OSStatus result = AudioObjectSetPropertyData(kAudioObjectSystemObject, &property, 0, NULL, sizeof(CFRunLoopRef), &theRunLoop); + if (result != noErr) + { + errorText_ = "RtApiCore::RtApiCore: error setting run loop property!"; + error(RtAudioError::WARNING); + } #endif } -RtApiCore :: ~RtApiCore() +RtApiCore ::~RtApiCore() { - // The subclass destructor gets called before the base class - // destructor, so close an existing stream before deallocating - // apiDeviceId memory. - if ( stream_.state != STREAM_CLOSED ) closeStream(); + // The subclass destructor gets called before the base class + // destructor, so close an existing stream before deallocating + // apiDeviceId memory. + if (stream_.state != STREAM_CLOSED) closeStream(); } -unsigned int RtApiCore :: getDeviceCount( void ) +unsigned int RtApiCore ::getDeviceCount(void) { - // Find out how many audio devices there are, if any. - UInt32 dataSize; - AudioObjectPropertyAddress propertyAddress = { kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; - OSStatus result = AudioObjectGetPropertyDataSize( kAudioObjectSystemObject, &propertyAddress, 0, NULL, &dataSize ); - if ( result != noErr ) { - errorText_ = "RtApiCore::getDeviceCount: OS-X error getting device info!"; - error( RtAudioError::WARNING ); - return 0; - } + // Find out how many audio devices there are, if any. + UInt32 dataSize; + AudioObjectPropertyAddress propertyAddress = {kAudioHardwarePropertyDevices, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster}; + OSStatus result = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &propertyAddress, 0, NULL, &dataSize); + if (result != noErr) + { + errorText_ = "RtApiCore::getDeviceCount: OS-X error getting device info!"; + error(RtAudioError::WARNING); + return 0; + } - return dataSize / sizeof( AudioDeviceID ); + return dataSize / sizeof(AudioDeviceID); } -unsigned int RtApiCore :: getDefaultInputDevice( void ) +unsigned int RtApiCore ::getDefaultInputDevice(void) { - unsigned int nDevices = getDeviceCount(); - if ( nDevices <= 1 ) return 0; + unsigned int nDevices = getDeviceCount(); + if (nDevices <= 1) return 0; - AudioDeviceID id; - UInt32 dataSize = sizeof( AudioDeviceID ); - AudioObjectPropertyAddress property = { kAudioHardwarePropertyDefaultInputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; - OSStatus result = AudioObjectGetPropertyData( kAudioObjectSystemObject, &property, 0, NULL, &dataSize, &id ); - if ( result != noErr ) { - errorText_ = "RtApiCore::getDefaultInputDevice: OS-X system error getting device."; - error( RtAudioError::WARNING ); - return 0; - } + AudioDeviceID id; + UInt32 dataSize = sizeof(AudioDeviceID); + AudioObjectPropertyAddress property = {kAudioHardwarePropertyDefaultInputDevice, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster}; + OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property, 0, NULL, &dataSize, &id); + if (result != noErr) + { + errorText_ = "RtApiCore::getDefaultInputDevice: OS-X system error getting device."; + error(RtAudioError::WARNING); + return 0; + } - dataSize *= nDevices; - AudioDeviceID deviceList[ nDevices ]; - property.mSelector = kAudioHardwarePropertyDevices; - result = AudioObjectGetPropertyData( kAudioObjectSystemObject, &property, 0, NULL, &dataSize, (void *) &deviceList ); - if ( result != noErr ) { - errorText_ = "RtApiCore::getDefaultInputDevice: OS-X system error getting device IDs."; - error( RtAudioError::WARNING ); - return 0; - } + dataSize *= nDevices; + AudioDeviceID deviceList[nDevices]; + property.mSelector = kAudioHardwarePropertyDevices; + result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property, 0, NULL, &dataSize, (void *)&deviceList); + if (result != noErr) + { + errorText_ = "RtApiCore::getDefaultInputDevice: OS-X system error getting device IDs."; + error(RtAudioError::WARNING); + return 0; + } - for ( unsigned int i=0; i= nDevices ) { - errorText_ = "RtApiCore::getDeviceInfo: device ID is invalid!"; - error( RtAudioError::INVALID_USE ); - return info; - } + if (device >= nDevices) + { + errorText_ = "RtApiCore::getDeviceInfo: device ID is invalid!"; + error(RtAudioError::INVALID_USE); + return info; + } - AudioDeviceID deviceList[ nDevices ]; - UInt32 dataSize = sizeof( AudioDeviceID ) * nDevices; - AudioObjectPropertyAddress property = { kAudioHardwarePropertyDevices, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster }; - OSStatus result = AudioObjectGetPropertyData( kAudioObjectSystemObject, &property, - 0, NULL, &dataSize, (void *) &deviceList ); - if ( result != noErr ) { - errorText_ = "RtApiCore::getDeviceInfo: OS-X system error getting device IDs."; - error( RtAudioError::WARNING ); - return info; - } + AudioDeviceID deviceList[nDevices]; + UInt32 dataSize = sizeof(AudioDeviceID) * nDevices; + AudioObjectPropertyAddress property = {kAudioHardwarePropertyDevices, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster}; + OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property, + 0, NULL, &dataSize, (void *)&deviceList); + if (result != noErr) + { + errorText_ = "RtApiCore::getDeviceInfo: OS-X system error getting device IDs."; + error(RtAudioError::WARNING); + return info; + } - AudioDeviceID id = deviceList[ device ]; + AudioDeviceID id = deviceList[device]; - // Get the device name. - info.name.erase(); - CFStringRef cfname; - dataSize = sizeof( CFStringRef ); - property.mSelector = kAudioObjectPropertyManufacturer; - result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &cfname ); - if ( result != noErr ) { - errorStream_ << "RtApiCore::probeDeviceInfo: system error (" << getErrorCode( result ) << ") getting device manufacturer."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + // Get the device name. + info.name.erase(); + CFStringRef cfname; + dataSize = sizeof(CFStringRef); + property.mSelector = kAudioObjectPropertyManufacturer; + result = AudioObjectGetPropertyData(id, &property, 0, NULL, &dataSize, &cfname); + if (result != noErr) + { + errorStream_ << "RtApiCore::probeDeviceInfo: system error (" << getErrorCode(result) << ") getting device manufacturer."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - //const char *mname = CFStringGetCStringPtr( cfname, CFStringGetSystemEncoding() ); - int length = CFStringGetLength(cfname); - char *mname = (char *)malloc(length * 3 + 1); -#if defined( UNICODE ) || defined( _UNICODE ) - CFStringGetCString(cfname, mname, length * 3 + 1, kCFStringEncodingUTF8); + //const char *mname = CFStringGetCStringPtr( cfname, CFStringGetSystemEncoding() ); + int length = CFStringGetLength(cfname); + char *mname = (char *)malloc(length * 3 + 1); +#if defined(UNICODE) || defined(_UNICODE) + CFStringGetCString(cfname, mname, length * 3 + 1, kCFStringEncodingUTF8); #else - CFStringGetCString(cfname, mname, length * 3 + 1, CFStringGetSystemEncoding()); + CFStringGetCString(cfname, mname, length * 3 + 1, CFStringGetSystemEncoding()); #endif - info.name.append( (const char *)mname, strlen(mname) ); - info.name.append( ": " ); - CFRelease( cfname ); - free(mname); + info.name.append((const char *)mname, strlen(mname)); + info.name.append(": "); + CFRelease(cfname); + free(mname); - property.mSelector = kAudioObjectPropertyName; - result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &cfname ); - if ( result != noErr ) { - errorStream_ << "RtApiCore::probeDeviceInfo: system error (" << getErrorCode( result ) << ") getting device name."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + property.mSelector = kAudioObjectPropertyName; + result = AudioObjectGetPropertyData(id, &property, 0, NULL, &dataSize, &cfname); + if (result != noErr) + { + errorStream_ << "RtApiCore::probeDeviceInfo: system error (" << getErrorCode(result) << ") getting device name."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - //const char *name = CFStringGetCStringPtr( cfname, CFStringGetSystemEncoding() ); - length = CFStringGetLength(cfname); - char *name = (char *)malloc(length * 3 + 1); -#if defined( UNICODE ) || defined( _UNICODE ) - CFStringGetCString(cfname, name, length * 3 + 1, kCFStringEncodingUTF8); + //const char *name = CFStringGetCStringPtr( cfname, CFStringGetSystemEncoding() ); + length = CFStringGetLength(cfname); + char *name = (char *)malloc(length * 3 + 1); +#if defined(UNICODE) || defined(_UNICODE) + CFStringGetCString(cfname, name, length * 3 + 1, kCFStringEncodingUTF8); #else - CFStringGetCString(cfname, name, length * 3 + 1, CFStringGetSystemEncoding()); + CFStringGetCString(cfname, name, length * 3 + 1, CFStringGetSystemEncoding()); #endif - info.name.append( (const char *)name, strlen(name) ); - CFRelease( cfname ); - free(name); + info.name.append((const char *)name, strlen(name)); + CFRelease(cfname); + free(name); - // Get the output stream "configuration". - AudioBufferList *bufferList = nil; - property.mSelector = kAudioDevicePropertyStreamConfiguration; - property.mScope = kAudioDevicePropertyScopeOutput; - // property.mElement = kAudioObjectPropertyElementWildcard; - dataSize = 0; - result = AudioObjectGetPropertyDataSize( id, &property, 0, NULL, &dataSize ); - if ( result != noErr || dataSize == 0 ) { - errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting output stream configuration info for device (" << device << ")."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + // Get the output stream "configuration". + AudioBufferList *bufferList = nil; + property.mSelector = kAudioDevicePropertyStreamConfiguration; + property.mScope = kAudioDevicePropertyScopeOutput; + // property.mElement = kAudioObjectPropertyElementWildcard; + dataSize = 0; + result = AudioObjectGetPropertyDataSize(id, &property, 0, NULL, &dataSize); + if (result != noErr || dataSize == 0) + { + errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode(result) << ") getting output stream configuration info for device (" << device << ")."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - // Allocate the AudioBufferList. - bufferList = (AudioBufferList *) malloc( dataSize ); - if ( bufferList == NULL ) { - errorText_ = "RtApiCore::getDeviceInfo: memory error allocating output AudioBufferList."; - error( RtAudioError::WARNING ); - return info; - } + // Allocate the AudioBufferList. + bufferList = (AudioBufferList *)malloc(dataSize); + if (bufferList == NULL) + { + errorText_ = "RtApiCore::getDeviceInfo: memory error allocating output AudioBufferList."; + error(RtAudioError::WARNING); + return info; + } - result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, bufferList ); - if ( result != noErr || dataSize == 0 ) { - free( bufferList ); - errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting output stream configuration for device (" << device << ")."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + result = AudioObjectGetPropertyData(id, &property, 0, NULL, &dataSize, bufferList); + if (result != noErr || dataSize == 0) + { + free(bufferList); + errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode(result) << ") getting output stream configuration for device (" << device << ")."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - // Get output channel information. - unsigned int i, nStreams = bufferList->mNumberBuffers; - for ( i=0; imBuffers[i].mNumberChannels; - free( bufferList ); + // Get output channel information. + unsigned int i, nStreams = bufferList->mNumberBuffers; + for (i = 0; i < nStreams; i++) + info.outputChannels += bufferList->mBuffers[i].mNumberChannels; + free(bufferList); - // Get the input stream "configuration". - property.mScope = kAudioDevicePropertyScopeInput; - result = AudioObjectGetPropertyDataSize( id, &property, 0, NULL, &dataSize ); - if ( result != noErr || dataSize == 0 ) { - errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting input stream configuration info for device (" << device << ")."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + // Get the input stream "configuration". + property.mScope = kAudioDevicePropertyScopeInput; + result = AudioObjectGetPropertyDataSize(id, &property, 0, NULL, &dataSize); + if (result != noErr || dataSize == 0) + { + errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode(result) << ") getting input stream configuration info for device (" << device << ")."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - // Allocate the AudioBufferList. - bufferList = (AudioBufferList *) malloc( dataSize ); - if ( bufferList == NULL ) { - errorText_ = "RtApiCore::getDeviceInfo: memory error allocating input AudioBufferList."; - error( RtAudioError::WARNING ); - return info; - } + // Allocate the AudioBufferList. + bufferList = (AudioBufferList *)malloc(dataSize); + if (bufferList == NULL) + { + errorText_ = "RtApiCore::getDeviceInfo: memory error allocating input AudioBufferList."; + error(RtAudioError::WARNING); + return info; + } - result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, bufferList ); - if (result != noErr || dataSize == 0) { - free( bufferList ); - errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting input stream configuration for device (" << device << ")."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + result = AudioObjectGetPropertyData(id, &property, 0, NULL, &dataSize, bufferList); + if (result != noErr || dataSize == 0) + { + free(bufferList); + errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode(result) << ") getting input stream configuration for device (" << device << ")."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - // Get input channel information. - nStreams = bufferList->mNumberBuffers; - for ( i=0; imBuffers[i].mNumberChannels; - free( bufferList ); + // Get input channel information. + nStreams = bufferList->mNumberBuffers; + for (i = 0; i < nStreams; i++) + info.inputChannels += bufferList->mBuffers[i].mNumberChannels; + free(bufferList); - // If device opens for both playback and capture, we determine the channels. - if ( info.outputChannels > 0 && info.inputChannels > 0 ) - info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels; + // If device opens for both playback and capture, we determine the channels. + if (info.outputChannels > 0 && info.inputChannels > 0) + info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels; - // Probe the device sample rates. - bool isInput = false; - if ( info.outputChannels == 0 ) isInput = true; + // Probe the device sample rates. + bool isInput = false; + if (info.outputChannels == 0) isInput = true; - // Determine the supported sample rates. - property.mSelector = kAudioDevicePropertyAvailableNominalSampleRates; - if ( isInput == false ) property.mScope = kAudioDevicePropertyScopeOutput; - result = AudioObjectGetPropertyDataSize( id, &property, 0, NULL, &dataSize ); - if ( result != kAudioHardwareNoError || dataSize == 0 ) { - errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting sample rate info."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + // Determine the supported sample rates. + property.mSelector = kAudioDevicePropertyAvailableNominalSampleRates; + if (isInput == false) property.mScope = kAudioDevicePropertyScopeOutput; + result = AudioObjectGetPropertyDataSize(id, &property, 0, NULL, &dataSize); + if (result != kAudioHardwareNoError || dataSize == 0) + { + errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode(result) << ") getting sample rate info."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - UInt32 nRanges = dataSize / sizeof( AudioValueRange ); - AudioValueRange rangeList[ nRanges ]; - result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &rangeList ); - if ( result != kAudioHardwareNoError ) { - errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode( result ) << ") getting sample rates."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + UInt32 nRanges = dataSize / sizeof(AudioValueRange); + AudioValueRange rangeList[nRanges]; + result = AudioObjectGetPropertyData(id, &property, 0, NULL, &dataSize, &rangeList); + if (result != kAudioHardwareNoError) + { + errorStream_ << "RtApiCore::getDeviceInfo: system error (" << getErrorCode(result) << ") getting sample rates."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - // The sample rate reporting mechanism is a bit of a mystery. It - // seems that it can either return individual rates or a range of - // rates. I assume that if the min / max range values are the same, - // then that represents a single supported rate and if the min / max - // range values are different, the device supports an arbitrary - // range of values (though there might be multiple ranges, so we'll - // use the most conservative range). - Float64 minimumRate = 1.0, maximumRate = 10000000000.0; - bool haveValueRange = false; - info.sampleRates.clear(); - for ( UInt32 i=0; i info.preferredSampleRate ) ) - info.preferredSampleRate = tmpSr; + if (!info.preferredSampleRate || (tmpSr <= 48000 && tmpSr > info.preferredSampleRate)) + info.preferredSampleRate = tmpSr; + } + else + { + haveValueRange = true; + if (rangeList[i].mMinimum > minimumRate) minimumRate = rangeList[i].mMinimum; + if (rangeList[i].mMaximum < maximumRate) maximumRate = rangeList[i].mMaximum; + } + } - } else { - haveValueRange = true; - if ( rangeList[i].mMinimum > minimumRate ) minimumRate = rangeList[i].mMinimum; - if ( rangeList[i].mMaximum < maximumRate ) maximumRate = rangeList[i].mMaximum; - } - } + if (haveValueRange) + { + for (unsigned int k = 0; k < MAX_SAMPLE_RATES; k++) + { + if (SAMPLE_RATES[k] >= (unsigned int)minimumRate && SAMPLE_RATES[k] <= (unsigned int)maximumRate) + { + info.sampleRates.push_back(SAMPLE_RATES[k]); - if ( haveValueRange ) { - for ( unsigned int k=0; k= (unsigned int) minimumRate && SAMPLE_RATES[k] <= (unsigned int) maximumRate ) { - info.sampleRates.push_back( SAMPLE_RATES[k] ); + if (!info.preferredSampleRate || (SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate)) + info.preferredSampleRate = SAMPLE_RATES[k]; + } + } + } - if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) ) - info.preferredSampleRate = SAMPLE_RATES[k]; - } - } - } + // Sort and remove any redundant values + std::sort(info.sampleRates.begin(), info.sampleRates.end()); + info.sampleRates.erase(unique(info.sampleRates.begin(), info.sampleRates.end()), info.sampleRates.end()); - // Sort and remove any redundant values - std::sort( info.sampleRates.begin(), info.sampleRates.end() ); - info.sampleRates.erase( unique( info.sampleRates.begin(), info.sampleRates.end() ), info.sampleRates.end() ); + if (info.sampleRates.size() == 0) + { + errorStream_ << "RtApiCore::probeDeviceInfo: No supported sample rates found for device (" << device << ")."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - if ( info.sampleRates.size() == 0 ) { - errorStream_ << "RtApiCore::probeDeviceInfo: No supported sample rates found for device (" << device << ")."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + // CoreAudio always uses 32-bit floating point data for PCM streams. + // Thus, any other "physical" formats supported by the device are of + // no interest to the client. + info.nativeFormats = RTAUDIO_FLOAT32; - // CoreAudio always uses 32-bit floating point data for PCM streams. - // Thus, any other "physical" formats supported by the device are of - // no interest to the client. - info.nativeFormats = RTAUDIO_FLOAT32; + if (info.outputChannels > 0) + if (getDefaultOutputDevice() == device) info.isDefaultOutput = true; + if (info.inputChannels > 0) + if (getDefaultInputDevice() == device) info.isDefaultInput = true; - if ( info.outputChannels > 0 ) - if ( getDefaultOutputDevice() == device ) info.isDefaultOutput = true; - if ( info.inputChannels > 0 ) - if ( getDefaultInputDevice() == device ) info.isDefaultInput = true; - - info.probed = true; - return info; + info.probed = true; + return info; } -static OSStatus callbackHandler( AudioDeviceID inDevice, - const AudioTimeStamp* /*inNow*/, - const AudioBufferList* inInputData, - const AudioTimeStamp* /*inInputTime*/, - AudioBufferList* outOutputData, - const AudioTimeStamp* /*inOutputTime*/, - void* infoPointer ) +static OSStatus callbackHandler(AudioDeviceID inDevice, + const AudioTimeStamp * /*inNow*/, + const AudioBufferList *inInputData, + const AudioTimeStamp * /*inInputTime*/, + AudioBufferList *outOutputData, + const AudioTimeStamp * /*inOutputTime*/, + void *infoPointer) { - CallbackInfo *info = (CallbackInfo *) infoPointer; + CallbackInfo *info = (CallbackInfo *)infoPointer; - RtApiCore *object = (RtApiCore *) info->object; - if ( object->callbackEvent( inDevice, inInputData, outOutputData ) == false ) - return kAudioHardwareUnspecifiedError; - else - return kAudioHardwareNoError; + RtApiCore *object = (RtApiCore *)info->object; + if (object->callbackEvent(inDevice, inInputData, outOutputData) == false) + return kAudioHardwareUnspecifiedError; + else + return kAudioHardwareNoError; } -static OSStatus xrunListener( AudioObjectID /*inDevice*/, - UInt32 nAddresses, - const AudioObjectPropertyAddress properties[], - void* handlePointer ) +static OSStatus xrunListener(AudioObjectID /*inDevice*/, + UInt32 nAddresses, + const AudioObjectPropertyAddress properties[], + void *handlePointer) { - CoreHandle *handle = (CoreHandle *) handlePointer; - for ( UInt32 i=0; ixrun[1] = true; - else - handle->xrun[0] = true; - } - } + CoreHandle *handle = (CoreHandle *)handlePointer; + for (UInt32 i = 0; i < nAddresses; i++) + { + if (properties[i].mSelector == kAudioDeviceProcessorOverload) + { + if (properties[i].mScope == kAudioDevicePropertyScopeInput) + handle->xrun[1] = true; + else + handle->xrun[0] = true; + } + } - return kAudioHardwareNoError; + return kAudioHardwareNoError; } -static OSStatus rateListener( AudioObjectID inDevice, - UInt32 /*nAddresses*/, - const AudioObjectPropertyAddress /*properties*/[], - void* ratePointer ) +static OSStatus rateListener(AudioObjectID inDevice, + UInt32 /*nAddresses*/, + const AudioObjectPropertyAddress /*properties*/[], + void *ratePointer) { - Float64 *rate = (Float64 *) ratePointer; - UInt32 dataSize = sizeof( Float64 ); - AudioObjectPropertyAddress property = { kAudioDevicePropertyNominalSampleRate, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster }; - AudioObjectGetPropertyData( inDevice, &property, 0, NULL, &dataSize, rate ); - return kAudioHardwareNoError; + Float64 *rate = (Float64 *)ratePointer; + UInt32 dataSize = sizeof(Float64); + AudioObjectPropertyAddress property = {kAudioDevicePropertyNominalSampleRate, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster}; + AudioObjectGetPropertyData(inDevice, &property, 0, NULL, &dataSize, rate); + return kAudioHardwareNoError; } -bool RtApiCore :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, - unsigned int firstChannel, unsigned int sampleRate, - RtAudioFormat format, unsigned int *bufferSize, - RtAudio::StreamOptions *options ) +bool RtApiCore ::probeDeviceOpen(unsigned int device, StreamMode mode, unsigned int channels, + unsigned int firstChannel, unsigned int sampleRate, + RtAudioFormat format, unsigned int *bufferSize, + RtAudio::StreamOptions *options) { - // Get device ID - unsigned int nDevices = getDeviceCount(); - if ( nDevices == 0 ) { - // This should not happen because a check is made before this function is called. - errorText_ = "RtApiCore::probeDeviceOpen: no devices found!"; - return FAILURE; - } + // Get device ID + unsigned int nDevices = getDeviceCount(); + if (nDevices == 0) + { + // This should not happen because a check is made before this function is called. + errorText_ = "RtApiCore::probeDeviceOpen: no devices found!"; + return FAILURE; + } - if ( device >= nDevices ) { - // This should not happen because a check is made before this function is called. - errorText_ = "RtApiCore::probeDeviceOpen: device ID is invalid!"; - return FAILURE; - } + if (device >= nDevices) + { + // This should not happen because a check is made before this function is called. + errorText_ = "RtApiCore::probeDeviceOpen: device ID is invalid!"; + return FAILURE; + } - AudioDeviceID deviceList[ nDevices ]; - UInt32 dataSize = sizeof( AudioDeviceID ) * nDevices; - AudioObjectPropertyAddress property = { kAudioHardwarePropertyDevices, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster }; - OSStatus result = AudioObjectGetPropertyData( kAudioObjectSystemObject, &property, - 0, NULL, &dataSize, (void *) &deviceList ); - if ( result != noErr ) { - errorText_ = "RtApiCore::probeDeviceOpen: OS-X system error getting device IDs."; - return FAILURE; - } + AudioDeviceID deviceList[nDevices]; + UInt32 dataSize = sizeof(AudioDeviceID) * nDevices; + AudioObjectPropertyAddress property = {kAudioHardwarePropertyDevices, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster}; + OSStatus result = AudioObjectGetPropertyData(kAudioObjectSystemObject, &property, + 0, NULL, &dataSize, (void *)&deviceList); + if (result != noErr) + { + errorText_ = "RtApiCore::probeDeviceOpen: OS-X system error getting device IDs."; + return FAILURE; + } - AudioDeviceID id = deviceList[ device ]; + AudioDeviceID id = deviceList[device]; - // Setup for stream mode. - bool isInput = false; - if ( mode == INPUT ) { - isInput = true; - property.mScope = kAudioDevicePropertyScopeInput; - } - else - property.mScope = kAudioDevicePropertyScopeOutput; + // Setup for stream mode. + bool isInput = false; + if (mode == INPUT) + { + isInput = true; + property.mScope = kAudioDevicePropertyScopeInput; + } + else + property.mScope = kAudioDevicePropertyScopeOutput; - // Get the stream "configuration". - AudioBufferList *bufferList = nil; - dataSize = 0; - property.mSelector = kAudioDevicePropertyStreamConfiguration; - result = AudioObjectGetPropertyDataSize( id, &property, 0, NULL, &dataSize ); - if ( result != noErr || dataSize == 0 ) { - errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting stream configuration info for device (" << device << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Get the stream "configuration". + AudioBufferList *bufferList = nil; + dataSize = 0; + property.mSelector = kAudioDevicePropertyStreamConfiguration; + result = AudioObjectGetPropertyDataSize(id, &property, 0, NULL, &dataSize); + if (result != noErr || dataSize == 0) + { + errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode(result) << ") getting stream configuration info for device (" << device << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Allocate the AudioBufferList. - bufferList = (AudioBufferList *) malloc( dataSize ); - if ( bufferList == NULL ) { - errorText_ = "RtApiCore::probeDeviceOpen: memory error allocating AudioBufferList."; - return FAILURE; - } + // Allocate the AudioBufferList. + bufferList = (AudioBufferList *)malloc(dataSize); + if (bufferList == NULL) + { + errorText_ = "RtApiCore::probeDeviceOpen: memory error allocating AudioBufferList."; + return FAILURE; + } - result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, bufferList ); - if (result != noErr || dataSize == 0) { - free( bufferList ); - errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting stream configuration for device (" << device << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } + result = AudioObjectGetPropertyData(id, &property, 0, NULL, &dataSize, bufferList); + if (result != noErr || dataSize == 0) + { + free(bufferList); + errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode(result) << ") getting stream configuration for device (" << device << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Search for one or more streams that contain the desired number of - // channels. CoreAudio devices can have an arbitrary number of - // streams and each stream can have an arbitrary number of channels. - // For each stream, a single buffer of interleaved samples is - // provided. RtAudio prefers the use of one stream of interleaved - // data or multiple consecutive single-channel streams. However, we - // now support multiple consecutive multi-channel streams of - // interleaved data as well. - UInt32 iStream, offsetCounter = firstChannel; - UInt32 nStreams = bufferList->mNumberBuffers; - bool monoMode = false; - bool foundStream = false; + // Search for one or more streams that contain the desired number of + // channels. CoreAudio devices can have an arbitrary number of + // streams and each stream can have an arbitrary number of channels. + // For each stream, a single buffer of interleaved samples is + // provided. RtAudio prefers the use of one stream of interleaved + // data or multiple consecutive single-channel streams. However, we + // now support multiple consecutive multi-channel streams of + // interleaved data as well. + UInt32 iStream, offsetCounter = firstChannel; + UInt32 nStreams = bufferList->mNumberBuffers; + bool monoMode = false; + bool foundStream = false; - // First check that the device supports the requested number of - // channels. - UInt32 deviceChannels = 0; - for ( iStream=0; iStreammBuffers[iStream].mNumberChannels; + // First check that the device supports the requested number of + // channels. + UInt32 deviceChannels = 0; + for (iStream = 0; iStream < nStreams; iStream++) + deviceChannels += bufferList->mBuffers[iStream].mNumberChannels; - if ( deviceChannels < ( channels + firstChannel ) ) { - free( bufferList ); - errorStream_ << "RtApiCore::probeDeviceOpen: the device (" << device << ") does not support the requested channel count."; - errorText_ = errorStream_.str(); - return FAILURE; - } + if (deviceChannels < (channels + firstChannel)) + { + free(bufferList); + errorStream_ << "RtApiCore::probeDeviceOpen: the device (" << device << ") does not support the requested channel count."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Look for a single stream meeting our needs. - UInt32 firstStream, streamCount = 1, streamChannels = 0, channelOffset = 0; - for ( iStream=0; iStreammBuffers[iStream].mNumberChannels; - if ( streamChannels >= channels + offsetCounter ) { - firstStream = iStream; - channelOffset = offsetCounter; - foundStream = true; - break; - } - if ( streamChannels > offsetCounter ) break; - offsetCounter -= streamChannels; - } + // Look for a single stream meeting our needs. + UInt32 firstStream, streamCount = 1, streamChannels = 0, channelOffset = 0; + for (iStream = 0; iStream < nStreams; iStream++) + { + streamChannels = bufferList->mBuffers[iStream].mNumberChannels; + if (streamChannels >= channels + offsetCounter) + { + firstStream = iStream; + channelOffset = offsetCounter; + foundStream = true; + break; + } + if (streamChannels > offsetCounter) break; + offsetCounter -= streamChannels; + } - // If we didn't find a single stream above, then we should be able - // to meet the channel specification with multiple streams. - if ( foundStream == false ) { - monoMode = true; - offsetCounter = firstChannel; - for ( iStream=0; iStreammBuffers[iStream].mNumberChannels; - if ( streamChannels > offsetCounter ) break; - offsetCounter -= streamChannels; - } + // If we didn't find a single stream above, then we should be able + // to meet the channel specification with multiple streams. + if (foundStream == false) + { + monoMode = true; + offsetCounter = firstChannel; + for (iStream = 0; iStream < nStreams; iStream++) + { + streamChannels = bufferList->mBuffers[iStream].mNumberChannels; + if (streamChannels > offsetCounter) break; + offsetCounter -= streamChannels; + } - firstStream = iStream; - channelOffset = offsetCounter; - Int32 channelCounter = channels + offsetCounter - streamChannels; + firstStream = iStream; + channelOffset = offsetCounter; + Int32 channelCounter = channels + offsetCounter - streamChannels; - if ( streamChannels > 1 ) monoMode = false; - while ( channelCounter > 0 ) { - streamChannels = bufferList->mBuffers[++iStream].mNumberChannels; - if ( streamChannels > 1 ) monoMode = false; - channelCounter -= streamChannels; - streamCount++; - } - } + if (streamChannels > 1) monoMode = false; + while (channelCounter > 0) + { + streamChannels = bufferList->mBuffers[++iStream].mNumberChannels; + if (streamChannels > 1) monoMode = false; + channelCounter -= streamChannels; + streamCount++; + } + } - free( bufferList ); + free(bufferList); - // Determine the buffer size. - AudioValueRange bufferRange; - dataSize = sizeof( AudioValueRange ); - property.mSelector = kAudioDevicePropertyBufferFrameSizeRange; - result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &bufferRange ); + // Determine the buffer size. + AudioValueRange bufferRange; + dataSize = sizeof(AudioValueRange); + property.mSelector = kAudioDevicePropertyBufferFrameSizeRange; + result = AudioObjectGetPropertyData(id, &property, 0, NULL, &dataSize, &bufferRange); - if ( result != noErr ) { - errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting buffer size range for device (" << device << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } + if (result != noErr) + { + errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode(result) << ") getting buffer size range for device (" << device << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } - if ( bufferRange.mMinimum > *bufferSize ) *bufferSize = (unsigned long) bufferRange.mMinimum; - else if ( bufferRange.mMaximum < *bufferSize ) *bufferSize = (unsigned long) bufferRange.mMaximum; - if ( options && options->flags & RTAUDIO_MINIMIZE_LATENCY ) *bufferSize = (unsigned long) bufferRange.mMinimum; + if (bufferRange.mMinimum > *bufferSize) + *bufferSize = (unsigned long)bufferRange.mMinimum; + else if (bufferRange.mMaximum < *bufferSize) + *bufferSize = (unsigned long)bufferRange.mMaximum; + if (options && options->flags & RTAUDIO_MINIMIZE_LATENCY) *bufferSize = (unsigned long)bufferRange.mMinimum; - // Set the buffer size. For multiple streams, I'm assuming we only - // need to make this setting for the master channel. - UInt32 theSize = (UInt32) *bufferSize; - dataSize = sizeof( UInt32 ); - property.mSelector = kAudioDevicePropertyBufferFrameSize; - result = AudioObjectSetPropertyData( id, &property, 0, NULL, dataSize, &theSize ); + // Set the buffer size. For multiple streams, I'm assuming we only + // need to make this setting for the master channel. + UInt32 theSize = (UInt32)*bufferSize; + dataSize = sizeof(UInt32); + property.mSelector = kAudioDevicePropertyBufferFrameSize; + result = AudioObjectSetPropertyData(id, &property, 0, NULL, dataSize, &theSize); - if ( result != noErr ) { - errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting the buffer size for device (" << device << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } + if (result != noErr) + { + errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode(result) << ") setting the buffer size for device (" << device << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // If attempting to setup a duplex stream, the bufferSize parameter - // MUST be the same in both directions! - *bufferSize = theSize; - if ( stream_.mode == OUTPUT && mode == INPUT && *bufferSize != stream_.bufferSize ) { - errorStream_ << "RtApiCore::probeDeviceOpen: system error setting buffer size for duplex stream on device (" << device << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } + // If attempting to setup a duplex stream, the bufferSize parameter + // MUST be the same in both directions! + *bufferSize = theSize; + if (stream_.mode == OUTPUT && mode == INPUT && *bufferSize != stream_.bufferSize) + { + errorStream_ << "RtApiCore::probeDeviceOpen: system error setting buffer size for duplex stream on device (" << device << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } - stream_.bufferSize = *bufferSize; - stream_.nBuffers = 1; + stream_.bufferSize = *bufferSize; + stream_.nBuffers = 1; - // Try to set "hog" mode ... it's not clear to me this is working. - if ( options && options->flags & RTAUDIO_HOG_DEVICE ) { - pid_t hog_pid; - dataSize = sizeof( hog_pid ); - property.mSelector = kAudioDevicePropertyHogMode; - result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &hog_pid ); - if ( result != noErr ) { - errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting 'hog' state!"; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Try to set "hog" mode ... it's not clear to me this is working. + if (options && options->flags & RTAUDIO_HOG_DEVICE) + { + pid_t hog_pid; + dataSize = sizeof(hog_pid); + property.mSelector = kAudioDevicePropertyHogMode; + result = AudioObjectGetPropertyData(id, &property, 0, NULL, &dataSize, &hog_pid); + if (result != noErr) + { + errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode(result) << ") getting 'hog' state!"; + errorText_ = errorStream_.str(); + return FAILURE; + } - if ( hog_pid != getpid() ) { - hog_pid = getpid(); - result = AudioObjectSetPropertyData( id, &property, 0, NULL, dataSize, &hog_pid ); - if ( result != noErr ) { - errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting 'hog' state!"; - errorText_ = errorStream_.str(); - return FAILURE; - } - } - } + if (hog_pid != getpid()) + { + hog_pid = getpid(); + result = AudioObjectSetPropertyData(id, &property, 0, NULL, dataSize, &hog_pid); + if (result != noErr) + { + errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode(result) << ") setting 'hog' state!"; + errorText_ = errorStream_.str(); + return FAILURE; + } + } + } - // Check and if necessary, change the sample rate for the device. - Float64 nominalRate; - dataSize = sizeof( Float64 ); - property.mSelector = kAudioDevicePropertyNominalSampleRate; - result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &nominalRate ); - if ( result != noErr ) { - errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting current sample rate."; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Check and if necessary, change the sample rate for the device. + Float64 nominalRate; + dataSize = sizeof(Float64); + property.mSelector = kAudioDevicePropertyNominalSampleRate; + result = AudioObjectGetPropertyData(id, &property, 0, NULL, &dataSize, &nominalRate); + if (result != noErr) + { + errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode(result) << ") getting current sample rate."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Only change the sample rate if off by more than 1 Hz. - if ( fabs( nominalRate - (double)sampleRate ) > 1.0 ) { + // Only change the sample rate if off by more than 1 Hz. + if (fabs(nominalRate - (double)sampleRate) > 1.0) + { + // Set a property listener for the sample rate change + Float64 reportedRate = 0.0; + AudioObjectPropertyAddress tmp = {kAudioDevicePropertyNominalSampleRate, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster}; + result = AudioObjectAddPropertyListener(id, &tmp, rateListener, (void *)&reportedRate); + if (result != noErr) + { + errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode(result) << ") setting sample rate property listener for device (" << device << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Set a property listener for the sample rate change - Float64 reportedRate = 0.0; - AudioObjectPropertyAddress tmp = { kAudioDevicePropertyNominalSampleRate, kAudioObjectPropertyScopeGlobal, kAudioObjectPropertyElementMaster }; - result = AudioObjectAddPropertyListener( id, &tmp, rateListener, (void *) &reportedRate ); - if ( result != noErr ) { - errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting sample rate property listener for device (" << device << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } + nominalRate = (Float64)sampleRate; + result = AudioObjectSetPropertyData(id, &property, 0, NULL, dataSize, &nominalRate); + if (result != noErr) + { + AudioObjectRemovePropertyListener(id, &tmp, rateListener, (void *)&reportedRate); + errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode(result) << ") setting sample rate for device (" << device << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } - nominalRate = (Float64) sampleRate; - result = AudioObjectSetPropertyData( id, &property, 0, NULL, dataSize, &nominalRate ); - if ( result != noErr ) { - AudioObjectRemovePropertyListener( id, &tmp, rateListener, (void *) &reportedRate ); - errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting sample rate for device (" << device << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Now wait until the reported nominal rate is what we just set. + UInt32 microCounter = 0; + while (reportedRate != nominalRate) + { + microCounter += 5000; + if (microCounter > 5000000) break; + usleep(5000); + } - // Now wait until the reported nominal rate is what we just set. - UInt32 microCounter = 0; - while ( reportedRate != nominalRate ) { - microCounter += 5000; - if ( microCounter > 5000000 ) break; - usleep( 5000 ); - } + // Remove the property listener. + AudioObjectRemovePropertyListener(id, &tmp, rateListener, (void *)&reportedRate); - // Remove the property listener. - AudioObjectRemovePropertyListener( id, &tmp, rateListener, (void *) &reportedRate ); + if (microCounter > 5000000) + { + errorStream_ << "RtApiCore::probeDeviceOpen: timeout waiting for sample rate update for device (" << device << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } + } - if ( microCounter > 5000000 ) { - errorStream_ << "RtApiCore::probeDeviceOpen: timeout waiting for sample rate update for device (" << device << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } - } + // Now set the stream format for all streams. Also, check the + // physical format of the device and change that if necessary. + AudioStreamBasicDescription description; + dataSize = sizeof(AudioStreamBasicDescription); + property.mSelector = kAudioStreamPropertyVirtualFormat; + result = AudioObjectGetPropertyData(id, &property, 0, NULL, &dataSize, &description); + if (result != noErr) + { + errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode(result) << ") getting stream format for device (" << device << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Now set the stream format for all streams. Also, check the - // physical format of the device and change that if necessary. - AudioStreamBasicDescription description; - dataSize = sizeof( AudioStreamBasicDescription ); - property.mSelector = kAudioStreamPropertyVirtualFormat; - result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &description ); - if ( result != noErr ) { - errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting stream format for device (" << device << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Set the sample rate and data format id. However, only make the + // change if the sample rate is not within 1.0 of the desired + // rate and the format is not linear pcm. + bool updateFormat = false; + if (fabs(description.mSampleRate - (Float64)sampleRate) > 1.0) + { + description.mSampleRate = (Float64)sampleRate; + updateFormat = true; + } - // Set the sample rate and data format id. However, only make the - // change if the sample rate is not within 1.0 of the desired - // rate and the format is not linear pcm. - bool updateFormat = false; - if ( fabs( description.mSampleRate - (Float64)sampleRate ) > 1.0 ) { - description.mSampleRate = (Float64) sampleRate; - updateFormat = true; - } + if (description.mFormatID != kAudioFormatLinearPCM) + { + description.mFormatID = kAudioFormatLinearPCM; + updateFormat = true; + } - if ( description.mFormatID != kAudioFormatLinearPCM ) { - description.mFormatID = kAudioFormatLinearPCM; - updateFormat = true; - } + if (updateFormat) + { + result = AudioObjectSetPropertyData(id, &property, 0, NULL, dataSize, &description); + if (result != noErr) + { + errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode(result) << ") setting sample rate or data format for device (" << device << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } + } - if ( updateFormat ) { - result = AudioObjectSetPropertyData( id, &property, 0, NULL, dataSize, &description ); - if ( result != noErr ) { - errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") setting sample rate or data format for device (" << device << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } - } + // Now check the physical format. + property.mSelector = kAudioStreamPropertyPhysicalFormat; + result = AudioObjectGetPropertyData(id, &property, 0, NULL, &dataSize, &description); + if (result != noErr) + { + errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode(result) << ") getting stream physical format for device (" << device << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Now check the physical format. - property.mSelector = kAudioStreamPropertyPhysicalFormat; - result = AudioObjectGetPropertyData( id, &property, 0, NULL, &dataSize, &description ); - if ( result != noErr ) { - errorStream_ << "RtApiCore::probeDeviceOpen: system error (" << getErrorCode( result ) << ") getting stream physical format for device (" << device << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } + //std::cout << "Current physical stream format:" << std::endl; + //std::cout << " mBitsPerChan = " << description.mBitsPerChannel << std::endl; + //std::cout << " aligned high = " << (description.mFormatFlags & kAudioFormatFlagIsAlignedHigh) << ", isPacked = " << (description.mFormatFlags & kAudioFormatFlagIsPacked) << std::endl; + //std::cout << " bytesPerFrame = " << description.mBytesPerFrame << std::endl; + //std::cout << " sample rate = " << description.mSampleRate << std::endl; - //std::cout << "Current physical stream format:" << std::endl; - //std::cout << " mBitsPerChan = " << description.mBitsPerChannel << std::endl; - //std::cout << " aligned high = " << (description.mFormatFlags & kAudioFormatFlagIsAlignedHigh) << ", isPacked = " << (description.mFormatFlags & kAudioFormatFlagIsPacked) << std::endl; - //std::cout << " bytesPerFrame = " << description.mBytesPerFrame << std::endl; - //std::cout << " sample rate = " << description.mSampleRate << std::endl; + if (description.mFormatID != kAudioFormatLinearPCM || description.mBitsPerChannel < 16) + { + description.mFormatID = kAudioFormatLinearPCM; + //description.mSampleRate = (Float64) sampleRate; + AudioStreamBasicDescription testDescription = description; + UInt32 formatFlags; - if ( description.mFormatID != kAudioFormatLinearPCM || description.mBitsPerChannel < 16 ) { - description.mFormatID = kAudioFormatLinearPCM; - //description.mSampleRate = (Float64) sampleRate; - AudioStreamBasicDescription testDescription = description; - UInt32 formatFlags; + // We'll try higher bit rates first and then work our way down. + std::vector > physicalFormats; + formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsFloat) & ~kLinearPCMFormatFlagIsSignedInteger; + physicalFormats.push_back(std::pair(32, formatFlags)); + formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked) & ~kLinearPCMFormatFlagIsFloat; + physicalFormats.push_back(std::pair(32, formatFlags)); + physicalFormats.push_back(std::pair(24, formatFlags)); // 24-bit packed + formatFlags &= ~(kAudioFormatFlagIsPacked | kAudioFormatFlagIsAlignedHigh); + physicalFormats.push_back(std::pair(24.2, formatFlags)); // 24-bit in 4 bytes, aligned low + formatFlags |= kAudioFormatFlagIsAlignedHigh; + physicalFormats.push_back(std::pair(24.4, formatFlags)); // 24-bit in 4 bytes, aligned high + formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked) & ~kLinearPCMFormatFlagIsFloat; + physicalFormats.push_back(std::pair(16, formatFlags)); + physicalFormats.push_back(std::pair(8, formatFlags)); - // We'll try higher bit rates first and then work our way down. - std::vector< std::pair > physicalFormats; - formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsFloat) & ~kLinearPCMFormatFlagIsSignedInteger; - physicalFormats.push_back( std::pair( 32, formatFlags ) ); - formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked) & ~kLinearPCMFormatFlagIsFloat; - physicalFormats.push_back( std::pair( 32, formatFlags ) ); - physicalFormats.push_back( std::pair( 24, formatFlags ) ); // 24-bit packed - formatFlags &= ~( kAudioFormatFlagIsPacked | kAudioFormatFlagIsAlignedHigh ); - physicalFormats.push_back( std::pair( 24.2, formatFlags ) ); // 24-bit in 4 bytes, aligned low - formatFlags |= kAudioFormatFlagIsAlignedHigh; - physicalFormats.push_back( std::pair( 24.4, formatFlags ) ); // 24-bit in 4 bytes, aligned high - formatFlags = (description.mFormatFlags | kLinearPCMFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked) & ~kLinearPCMFormatFlagIsFloat; - physicalFormats.push_back( std::pair( 16, formatFlags ) ); - physicalFormats.push_back( std::pair( 8, formatFlags ) ); + bool setPhysicalFormat = false; + for (unsigned int i = 0; i < physicalFormats.size(); i++) + { + testDescription = description; + testDescription.mBitsPerChannel = (UInt32)physicalFormats[i].first; + testDescription.mFormatFlags = physicalFormats[i].second; + if ((24 == (UInt32)physicalFormats[i].first) && ~(physicalFormats[i].second & kAudioFormatFlagIsPacked)) + testDescription.mBytesPerFrame = 4 * testDescription.mChannelsPerFrame; + else + testDescription.mBytesPerFrame = testDescription.mBitsPerChannel / 8 * testDescription.mChannelsPerFrame; + testDescription.mBytesPerPacket = testDescription.mBytesPerFrame * testDescription.mFramesPerPacket; + result = AudioObjectSetPropertyData(id, &property, 0, NULL, dataSize, &testDescription); + if (result == noErr) + { + setPhysicalFormat = true; + //std::cout << "Updated physical stream format:" << std::endl; + //std::cout << " mBitsPerChan = " << testDescription.mBitsPerChannel << std::endl; + //std::cout << " aligned high = " << (testDescription.mFormatFlags & kAudioFormatFlagIsAlignedHigh) << ", isPacked = " << (testDescription.mFormatFlags & kAudioFormatFlagIsPacked) << std::endl; + //std::cout << " bytesPerFrame = " << testDescription.mBytesPerFrame << std::endl; + //std::cout << " sample rate = " << testDescription.mSampleRate << std::endl; + break; + } + } - bool setPhysicalFormat = false; - for( unsigned int i=0; iflags & RTAUDIO_NONINTERLEAVED) + stream_.userInterleaved = false; + else + stream_.userInterleaved = true; + stream_.deviceInterleaved[mode] = true; + if (monoMode == true) stream_.deviceInterleaved[mode] = false; - if ( streamCount == 1 ) - stream_.nDeviceChannels[mode] = description.mChannelsPerFrame; - else // multiple streams - stream_.nDeviceChannels[mode] = channels; - stream_.nUserChannels[mode] = channels; - stream_.channelOffset[mode] = channelOffset; // offset within a CoreAudio stream - if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) stream_.userInterleaved = false; - else stream_.userInterleaved = true; - stream_.deviceInterleaved[mode] = true; - if ( monoMode == true ) stream_.deviceInterleaved[mode] = false; + // Set flags for buffer conversion. + stream_.doConvertBuffer[mode] = false; + if (stream_.userFormat != stream_.deviceFormat[mode]) + stream_.doConvertBuffer[mode] = true; + if (stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode]) + stream_.doConvertBuffer[mode] = true; + if (streamCount == 1) + { + if (stream_.nUserChannels[mode] > 1 && + stream_.userInterleaved != stream_.deviceInterleaved[mode]) + stream_.doConvertBuffer[mode] = true; + } + else if (monoMode && stream_.userInterleaved) + stream_.doConvertBuffer[mode] = true; - // Set flags for buffer conversion. - stream_.doConvertBuffer[mode] = false; - if ( stream_.userFormat != stream_.deviceFormat[mode] ) - stream_.doConvertBuffer[mode] = true; - if ( stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode] ) - stream_.doConvertBuffer[mode] = true; - if ( streamCount == 1 ) { - if ( stream_.nUserChannels[mode] > 1 && - stream_.userInterleaved != stream_.deviceInterleaved[mode] ) - stream_.doConvertBuffer[mode] = true; - } - else if ( monoMode && stream_.userInterleaved ) - stream_.doConvertBuffer[mode] = true; + // Allocate our CoreHandle structure for the stream. + CoreHandle *handle = 0; + if (stream_.apiHandle == 0) + { + try + { + handle = new CoreHandle; + } + catch (std::bad_alloc &) + { + errorText_ = "RtApiCore::probeDeviceOpen: error allocating CoreHandle memory."; + goto error; + } - // Allocate our CoreHandle structure for the stream. - CoreHandle *handle = 0; - if ( stream_.apiHandle == 0 ) { - try { - handle = new CoreHandle; - } - catch ( std::bad_alloc& ) { - errorText_ = "RtApiCore::probeDeviceOpen: error allocating CoreHandle memory."; - goto error; - } + if (pthread_cond_init(&handle->condition, NULL)) + { + errorText_ = "RtApiCore::probeDeviceOpen: error initializing pthread condition variable."; + goto error; + } + stream_.apiHandle = (void *)handle; + } + else + handle = (CoreHandle *)stream_.apiHandle; + handle->iStream[mode] = firstStream; + handle->nStreams[mode] = streamCount; + handle->id[mode] = id; - if ( pthread_cond_init( &handle->condition, NULL ) ) { - errorText_ = "RtApiCore::probeDeviceOpen: error initializing pthread condition variable."; - goto error; - } - stream_.apiHandle = (void *) handle; - } - else - handle = (CoreHandle *) stream_.apiHandle; - handle->iStream[mode] = firstStream; - handle->nStreams[mode] = streamCount; - handle->id[mode] = id; + // Allocate necessary internal buffers. + unsigned long bufferBytes; + bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes(stream_.userFormat); + // stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 ); + stream_.userBuffer[mode] = (char *)malloc(bufferBytes * sizeof(char)); + memset(stream_.userBuffer[mode], 0, bufferBytes * sizeof(char)); + if (stream_.userBuffer[mode] == NULL) + { + errorText_ = "RtApiCore::probeDeviceOpen: error allocating user buffer memory."; + goto error; + } - // Allocate necessary internal buffers. - unsigned long bufferBytes; - bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat ); - // stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 ); - stream_.userBuffer[mode] = (char *) malloc( bufferBytes * sizeof(char) ); - memset( stream_.userBuffer[mode], 0, bufferBytes * sizeof(char) ); - if ( stream_.userBuffer[mode] == NULL ) { - errorText_ = "RtApiCore::probeDeviceOpen: error allocating user buffer memory."; - goto error; - } + // If possible, we will make use of the CoreAudio stream buffers as + // "device buffers". However, we can't do this if using multiple + // streams. + if (stream_.doConvertBuffer[mode] && handle->nStreams[mode] > 1) + { + bool makeBuffer = true; + bufferBytes = stream_.nDeviceChannels[mode] * formatBytes(stream_.deviceFormat[mode]); + if (mode == INPUT) + { + if (stream_.mode == OUTPUT && stream_.deviceBuffer) + { + unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes(stream_.deviceFormat[0]); + if (bufferBytes <= bytesOut) makeBuffer = false; + } + } - // If possible, we will make use of the CoreAudio stream buffers as - // "device buffers". However, we can't do this if using multiple - // streams. - if ( stream_.doConvertBuffer[mode] && handle->nStreams[mode] > 1 ) { + if (makeBuffer) + { + bufferBytes *= *bufferSize; + if (stream_.deviceBuffer) free(stream_.deviceBuffer); + stream_.deviceBuffer = (char *)calloc(bufferBytes, 1); + if (stream_.deviceBuffer == NULL) + { + errorText_ = "RtApiCore::probeDeviceOpen: error allocating device buffer memory."; + goto error; + } + } + } - bool makeBuffer = true; - bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] ); - if ( mode == INPUT ) { - if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) { - unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] ); - if ( bufferBytes <= bytesOut ) makeBuffer = false; - } - } + stream_.sampleRate = sampleRate; + stream_.device[mode] = device; + stream_.state = STREAM_STOPPED; + stream_.callbackInfo.object = (void *)this; - if ( makeBuffer ) { - bufferBytes *= *bufferSize; - if ( stream_.deviceBuffer ) free( stream_.deviceBuffer ); - stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 ); - if ( stream_.deviceBuffer == NULL ) { - errorText_ = "RtApiCore::probeDeviceOpen: error allocating device buffer memory."; - goto error; - } - } - } + // Setup the buffer conversion information structure. + if (stream_.doConvertBuffer[mode]) + { + if (streamCount > 1) + setConvertInfo(mode, 0); + else + setConvertInfo(mode, channelOffset); + } - stream_.sampleRate = sampleRate; - stream_.device[mode] = device; - stream_.state = STREAM_STOPPED; - stream_.callbackInfo.object = (void *) this; - - // Setup the buffer conversion information structure. - if ( stream_.doConvertBuffer[mode] ) { - if ( streamCount > 1 ) setConvertInfo( mode, 0 ); - else setConvertInfo( mode, channelOffset ); - } - - if ( mode == INPUT && stream_.mode == OUTPUT && stream_.device[0] == device ) - // Only one callback procedure per device. - stream_.mode = DUPLEX; - else { -#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) - result = AudioDeviceCreateIOProcID( id, callbackHandler, (void *) &stream_.callbackInfo, &handle->procId[mode] ); + if (mode == INPUT && stream_.mode == OUTPUT && stream_.device[0] == device) + // Only one callback procedure per device. + stream_.mode = DUPLEX; + else + { +#if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) + result = AudioDeviceCreateIOProcID(id, callbackHandler, (void *)&stream_.callbackInfo, &handle->procId[mode]); #else - // deprecated in favor of AudioDeviceCreateIOProcID() - result = AudioDeviceAddIOProc( id, callbackHandler, (void *) &stream_.callbackInfo ); + // deprecated in favor of AudioDeviceCreateIOProcID() + result = AudioDeviceAddIOProc(id, callbackHandler, (void *)&stream_.callbackInfo); #endif - if ( result != noErr ) { - errorStream_ << "RtApiCore::probeDeviceOpen: system error setting callback for device (" << device << ")."; - errorText_ = errorStream_.str(); - goto error; - } - if ( stream_.mode == OUTPUT && mode == INPUT ) - stream_.mode = DUPLEX; - else - stream_.mode = mode; - } + if (result != noErr) + { + errorStream_ << "RtApiCore::probeDeviceOpen: system error setting callback for device (" << device << ")."; + errorText_ = errorStream_.str(); + goto error; + } + if (stream_.mode == OUTPUT && mode == INPUT) + stream_.mode = DUPLEX; + else + stream_.mode = mode; + } - // Setup the device property listener for over/underload. - property.mSelector = kAudioDeviceProcessorOverload; - property.mScope = kAudioObjectPropertyScopeGlobal; - result = AudioObjectAddPropertyListener( id, &property, xrunListener, (void *) handle ); + // Setup the device property listener for over/underload. + property.mSelector = kAudioDeviceProcessorOverload; + property.mScope = kAudioObjectPropertyScopeGlobal; + result = AudioObjectAddPropertyListener(id, &property, xrunListener, (void *)handle); - return SUCCESS; + return SUCCESS; - error: - if ( handle ) { - pthread_cond_destroy( &handle->condition ); - delete handle; - stream_.apiHandle = 0; - } +error: + if (handle) + { + pthread_cond_destroy(&handle->condition); + delete handle; + stream_.apiHandle = 0; + } - for ( int i=0; i<2; i++ ) { - if ( stream_.userBuffer[i] ) { - free( stream_.userBuffer[i] ); - stream_.userBuffer[i] = 0; - } - } + for (int i = 0; i < 2; i++) + { + if (stream_.userBuffer[i]) + { + free(stream_.userBuffer[i]); + stream_.userBuffer[i] = 0; + } + } - if ( stream_.deviceBuffer ) { - free( stream_.deviceBuffer ); - stream_.deviceBuffer = 0; - } + if (stream_.deviceBuffer) + { + free(stream_.deviceBuffer); + stream_.deviceBuffer = 0; + } - stream_.state = STREAM_CLOSED; - return FAILURE; + stream_.state = STREAM_CLOSED; + return FAILURE; } -void RtApiCore :: closeStream( void ) +void RtApiCore ::closeStream(void) { - if ( stream_.state == STREAM_CLOSED ) { - errorText_ = "RtApiCore::closeStream(): no open stream to close!"; - error( RtAudioError::WARNING ); - return; - } + if (stream_.state == STREAM_CLOSED) + { + errorText_ = "RtApiCore::closeStream(): no open stream to close!"; + error(RtAudioError::WARNING); + return; + } - CoreHandle *handle = (CoreHandle *) stream_.apiHandle; - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { - if (handle) { - AudioObjectPropertyAddress property = { kAudioHardwarePropertyDevices, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster }; + CoreHandle *handle = (CoreHandle *)stream_.apiHandle; + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + { + if (handle) + { + AudioObjectPropertyAddress property = {kAudioHardwarePropertyDevices, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster}; - property.mSelector = kAudioDeviceProcessorOverload; - property.mScope = kAudioObjectPropertyScopeGlobal; - if (AudioObjectRemovePropertyListener( handle->id[0], &property, xrunListener, (void *) handle ) != noErr) { - errorText_ = "RtApiCore::closeStream(): error removing property listener!"; - error( RtAudioError::WARNING ); - } - } - if ( stream_.state == STREAM_RUNNING ) - AudioDeviceStop( handle->id[0], callbackHandler ); -#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) - AudioDeviceDestroyIOProcID( handle->id[0], handle->procId[0] ); + property.mSelector = kAudioDeviceProcessorOverload; + property.mScope = kAudioObjectPropertyScopeGlobal; + if (AudioObjectRemovePropertyListener(handle->id[0], &property, xrunListener, (void *)handle) != noErr) + { + errorText_ = "RtApiCore::closeStream(): error removing property listener!"; + error(RtAudioError::WARNING); + } + } + if (stream_.state == STREAM_RUNNING) + AudioDeviceStop(handle->id[0], callbackHandler); +#if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) + AudioDeviceDestroyIOProcID(handle->id[0], handle->procId[0]); #else - // deprecated in favor of AudioDeviceDestroyIOProcID() - AudioDeviceRemoveIOProc( handle->id[0], callbackHandler ); + // deprecated in favor of AudioDeviceDestroyIOProcID() + AudioDeviceRemoveIOProc(handle->id[0], callbackHandler); #endif - } + } - if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1] ) ) { - if (handle) { - AudioObjectPropertyAddress property = { kAudioHardwarePropertyDevices, - kAudioObjectPropertyScopeGlobal, - kAudioObjectPropertyElementMaster }; + if (stream_.mode == INPUT || (stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1])) + { + if (handle) + { + AudioObjectPropertyAddress property = {kAudioHardwarePropertyDevices, + kAudioObjectPropertyScopeGlobal, + kAudioObjectPropertyElementMaster}; - property.mSelector = kAudioDeviceProcessorOverload; - property.mScope = kAudioObjectPropertyScopeGlobal; - if (AudioObjectRemovePropertyListener( handle->id[1], &property, xrunListener, (void *) handle ) != noErr) { - errorText_ = "RtApiCore::closeStream(): error removing property listener!"; - error( RtAudioError::WARNING ); - } - } - if ( stream_.state == STREAM_RUNNING ) - AudioDeviceStop( handle->id[1], callbackHandler ); -#if defined( MAC_OS_X_VERSION_10_5 ) && ( MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 ) - AudioDeviceDestroyIOProcID( handle->id[1], handle->procId[1] ); + property.mSelector = kAudioDeviceProcessorOverload; + property.mScope = kAudioObjectPropertyScopeGlobal; + if (AudioObjectRemovePropertyListener(handle->id[1], &property, xrunListener, (void *)handle) != noErr) + { + errorText_ = "RtApiCore::closeStream(): error removing property listener!"; + error(RtAudioError::WARNING); + } + } + if (stream_.state == STREAM_RUNNING) + AudioDeviceStop(handle->id[1], callbackHandler); +#if defined(MAC_OS_X_VERSION_10_5) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5) + AudioDeviceDestroyIOProcID(handle->id[1], handle->procId[1]); #else - // deprecated in favor of AudioDeviceDestroyIOProcID() - AudioDeviceRemoveIOProc( handle->id[1], callbackHandler ); + // deprecated in favor of AudioDeviceDestroyIOProcID() + AudioDeviceRemoveIOProc(handle->id[1], callbackHandler); #endif - } + } - for ( int i=0; i<2; i++ ) { - if ( stream_.userBuffer[i] ) { - free( stream_.userBuffer[i] ); - stream_.userBuffer[i] = 0; - } - } + for (int i = 0; i < 2; i++) + { + if (stream_.userBuffer[i]) + { + free(stream_.userBuffer[i]); + stream_.userBuffer[i] = 0; + } + } - if ( stream_.deviceBuffer ) { - free( stream_.deviceBuffer ); - stream_.deviceBuffer = 0; - } + if (stream_.deviceBuffer) + { + free(stream_.deviceBuffer); + stream_.deviceBuffer = 0; + } - // Destroy pthread condition variable. - pthread_cond_destroy( &handle->condition ); - delete handle; - stream_.apiHandle = 0; + // Destroy pthread condition variable. + pthread_cond_destroy(&handle->condition); + delete handle; + stream_.apiHandle = 0; - stream_.mode = UNINITIALIZED; - stream_.state = STREAM_CLOSED; + stream_.mode = UNINITIALIZED; + stream_.state = STREAM_CLOSED; } -void RtApiCore :: startStream( void ) +void RtApiCore ::startStream(void) { - verifyStream(); - if ( stream_.state == STREAM_RUNNING ) { - errorText_ = "RtApiCore::startStream(): the stream is already running!"; - error( RtAudioError::WARNING ); - return; - } + verifyStream(); + if (stream_.state == STREAM_RUNNING) + { + errorText_ = "RtApiCore::startStream(): the stream is already running!"; + error(RtAudioError::WARNING); + return; + } - OSStatus result = noErr; - CoreHandle *handle = (CoreHandle *) stream_.apiHandle; - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { + OSStatus result = noErr; + CoreHandle *handle = (CoreHandle *)stream_.apiHandle; + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + { + result = AudioDeviceStart(handle->id[0], callbackHandler); + if (result != noErr) + { + errorStream_ << "RtApiCore::startStream: system error (" << getErrorCode(result) << ") starting callback procedure on device (" << stream_.device[0] << ")."; + errorText_ = errorStream_.str(); + goto unlock; + } + } - result = AudioDeviceStart( handle->id[0], callbackHandler ); - if ( result != noErr ) { - errorStream_ << "RtApiCore::startStream: system error (" << getErrorCode( result ) << ") starting callback procedure on device (" << stream_.device[0] << ")."; - errorText_ = errorStream_.str(); - goto unlock; - } - } + if (stream_.mode == INPUT || + (stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1])) + { + result = AudioDeviceStart(handle->id[1], callbackHandler); + if (result != noErr) + { + errorStream_ << "RtApiCore::startStream: system error starting input callback procedure on device (" << stream_.device[1] << ")."; + errorText_ = errorStream_.str(); + goto unlock; + } + } - if ( stream_.mode == INPUT || - ( stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1] ) ) { + handle->drainCounter = 0; + handle->internalDrain = false; + stream_.state = STREAM_RUNNING; - result = AudioDeviceStart( handle->id[1], callbackHandler ); - if ( result != noErr ) { - errorStream_ << "RtApiCore::startStream: system error starting input callback procedure on device (" << stream_.device[1] << ")."; - errorText_ = errorStream_.str(); - goto unlock; - } - } - - handle->drainCounter = 0; - handle->internalDrain = false; - stream_.state = STREAM_RUNNING; - - unlock: - if ( result == noErr ) return; - error( RtAudioError::SYSTEM_ERROR ); +unlock: + if (result == noErr) return; + error(RtAudioError::SYSTEM_ERROR); } -void RtApiCore :: stopStream( void ) +void RtApiCore ::stopStream(void) { - verifyStream(); - if ( stream_.state == STREAM_STOPPED ) { - errorText_ = "RtApiCore::stopStream(): the stream is already stopped!"; - error( RtAudioError::WARNING ); - return; - } + verifyStream(); + if (stream_.state == STREAM_STOPPED) + { + errorText_ = "RtApiCore::stopStream(): the stream is already stopped!"; + error(RtAudioError::WARNING); + return; + } - OSStatus result = noErr; - CoreHandle *handle = (CoreHandle *) stream_.apiHandle; - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { + OSStatus result = noErr; + CoreHandle *handle = (CoreHandle *)stream_.apiHandle; + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + { + if (handle->drainCounter == 0) + { + handle->drainCounter = 2; + pthread_cond_wait(&handle->condition, &stream_.mutex); // block until signaled + } - if ( handle->drainCounter == 0 ) { - handle->drainCounter = 2; - pthread_cond_wait( &handle->condition, &stream_.mutex ); // block until signaled - } + result = AudioDeviceStop(handle->id[0], callbackHandler); + if (result != noErr) + { + errorStream_ << "RtApiCore::stopStream: system error (" << getErrorCode(result) << ") stopping callback procedure on device (" << stream_.device[0] << ")."; + errorText_ = errorStream_.str(); + goto unlock; + } + } - result = AudioDeviceStop( handle->id[0], callbackHandler ); - if ( result != noErr ) { - errorStream_ << "RtApiCore::stopStream: system error (" << getErrorCode( result ) << ") stopping callback procedure on device (" << stream_.device[0] << ")."; - errorText_ = errorStream_.str(); - goto unlock; - } - } + if (stream_.mode == INPUT || (stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1])) + { + result = AudioDeviceStop(handle->id[1], callbackHandler); + if (result != noErr) + { + errorStream_ << "RtApiCore::stopStream: system error (" << getErrorCode(result) << ") stopping input callback procedure on device (" << stream_.device[1] << ")."; + errorText_ = errorStream_.str(); + goto unlock; + } + } - if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && stream_.device[0] != stream_.device[1] ) ) { + stream_.state = STREAM_STOPPED; - result = AudioDeviceStop( handle->id[1], callbackHandler ); - if ( result != noErr ) { - errorStream_ << "RtApiCore::stopStream: system error (" << getErrorCode( result ) << ") stopping input callback procedure on device (" << stream_.device[1] << ")."; - errorText_ = errorStream_.str(); - goto unlock; - } - } - - stream_.state = STREAM_STOPPED; - - unlock: - if ( result == noErr ) return; - error( RtAudioError::SYSTEM_ERROR ); +unlock: + if (result == noErr) return; + error(RtAudioError::SYSTEM_ERROR); } -void RtApiCore :: abortStream( void ) +void RtApiCore ::abortStream(void) { - verifyStream(); - if ( stream_.state == STREAM_STOPPED ) { - errorText_ = "RtApiCore::abortStream(): the stream is already stopped!"; - error( RtAudioError::WARNING ); - return; - } + verifyStream(); + if (stream_.state == STREAM_STOPPED) + { + errorText_ = "RtApiCore::abortStream(): the stream is already stopped!"; + error(RtAudioError::WARNING); + return; + } - CoreHandle *handle = (CoreHandle *) stream_.apiHandle; - handle->drainCounter = 2; + CoreHandle *handle = (CoreHandle *)stream_.apiHandle; + handle->drainCounter = 2; - stopStream(); + stopStream(); } // This function will be called by a spawned thread when the user @@ -1576,318 +1704,366 @@ void RtApiCore :: abortStream( void ) // aborted. It is better to handle it this way because the // callbackEvent() function probably should return before the AudioDeviceStop() // function is called. -static void *coreStopStream( void *ptr ) +static void *coreStopStream(void *ptr) { - CallbackInfo *info = (CallbackInfo *) ptr; - RtApiCore *object = (RtApiCore *) info->object; + CallbackInfo *info = (CallbackInfo *)ptr; + RtApiCore *object = (RtApiCore *)info->object; - object->stopStream(); - pthread_exit( NULL ); + object->stopStream(); + pthread_exit(NULL); } -bool RtApiCore :: callbackEvent( AudioDeviceID deviceId, - const AudioBufferList *inBufferList, - const AudioBufferList *outBufferList ) +bool RtApiCore ::callbackEvent(AudioDeviceID deviceId, + const AudioBufferList *inBufferList, + const AudioBufferList *outBufferList) { - if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) return SUCCESS; - if ( stream_.state == STREAM_CLOSED ) { - errorText_ = "RtApiCore::callbackEvent(): the stream is closed ... this shouldn't happen!"; - error( RtAudioError::WARNING ); - return FAILURE; - } + if (stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING) return SUCCESS; + if (stream_.state == STREAM_CLOSED) + { + errorText_ = "RtApiCore::callbackEvent(): the stream is closed ... this shouldn't happen!"; + error(RtAudioError::WARNING); + return FAILURE; + } - CallbackInfo *info = (CallbackInfo *) &stream_.callbackInfo; - CoreHandle *handle = (CoreHandle *) stream_.apiHandle; + CallbackInfo *info = (CallbackInfo *)&stream_.callbackInfo; + CoreHandle *handle = (CoreHandle *)stream_.apiHandle; - // Check if we were draining the stream and signal is finished. - if ( handle->drainCounter > 3 ) { - ThreadHandle threadId; + // Check if we were draining the stream and signal is finished. + if (handle->drainCounter > 3) + { + ThreadHandle threadId; - stream_.state = STREAM_STOPPING; - if ( handle->internalDrain == true ) - pthread_create( &threadId, NULL, coreStopStream, info ); - else // external call to stopStream() - pthread_cond_signal( &handle->condition ); - return SUCCESS; - } + stream_.state = STREAM_STOPPING; + if (handle->internalDrain == true) + pthread_create(&threadId, NULL, coreStopStream, info); + else // external call to stopStream() + pthread_cond_signal(&handle->condition); + return SUCCESS; + } - AudioDeviceID outputDevice = handle->id[0]; + AudioDeviceID outputDevice = handle->id[0]; - // Invoke user callback to get fresh output data UNLESS we are - // draining stream or duplex mode AND the input/output devices are - // different AND this function is called for the input device. - if ( handle->drainCounter == 0 && ( stream_.mode != DUPLEX || deviceId == outputDevice ) ) { - RtAudioCallback callback = (RtAudioCallback) info->callback; - double streamTime = getStreamTime(); - RtAudioStreamStatus status = 0; - if ( stream_.mode != INPUT && handle->xrun[0] == true ) { - status |= RTAUDIO_OUTPUT_UNDERFLOW; - handle->xrun[0] = false; - } - if ( stream_.mode != OUTPUT && handle->xrun[1] == true ) { - status |= RTAUDIO_INPUT_OVERFLOW; - handle->xrun[1] = false; - } + // Invoke user callback to get fresh output data UNLESS we are + // draining stream or duplex mode AND the input/output devices are + // different AND this function is called for the input device. + if (handle->drainCounter == 0 && (stream_.mode != DUPLEX || deviceId == outputDevice)) + { + RtAudioCallback callback = (RtAudioCallback)info->callback; + double streamTime = getStreamTime(); + RtAudioStreamStatus status = 0; + if (stream_.mode != INPUT && handle->xrun[0] == true) + { + status |= RTAUDIO_OUTPUT_UNDERFLOW; + handle->xrun[0] = false; + } + if (stream_.mode != OUTPUT && handle->xrun[1] == true) + { + status |= RTAUDIO_INPUT_OVERFLOW; + handle->xrun[1] = false; + } - int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1], - stream_.bufferSize, streamTime, status, info->userData ); - if ( cbReturnValue == 2 ) { - stream_.state = STREAM_STOPPING; - handle->drainCounter = 2; - abortStream(); - return SUCCESS; - } - else if ( cbReturnValue == 1 ) { - handle->drainCounter = 1; - handle->internalDrain = true; - } - } + int cbReturnValue = callback(stream_.userBuffer[0], stream_.userBuffer[1], + stream_.bufferSize, streamTime, status, info->userData); + if (cbReturnValue == 2) + { + stream_.state = STREAM_STOPPING; + handle->drainCounter = 2; + abortStream(); + return SUCCESS; + } + else if (cbReturnValue == 1) + { + handle->drainCounter = 1; + handle->internalDrain = true; + } + } - if ( stream_.mode == OUTPUT || ( stream_.mode == DUPLEX && deviceId == outputDevice ) ) { + if (stream_.mode == OUTPUT || (stream_.mode == DUPLEX && deviceId == outputDevice)) + { + if (handle->drainCounter > 1) + { // write zeros to the output stream - if ( handle->drainCounter > 1 ) { // write zeros to the output stream + if (handle->nStreams[0] == 1) + { + memset(outBufferList->mBuffers[handle->iStream[0]].mData, + 0, + outBufferList->mBuffers[handle->iStream[0]].mDataByteSize); + } + else + { // fill multiple streams with zeros + for (unsigned int i = 0; i < handle->nStreams[0]; i++) + { + memset(outBufferList->mBuffers[handle->iStream[0] + i].mData, + 0, + outBufferList->mBuffers[handle->iStream[0] + i].mDataByteSize); + } + } + } + else if (handle->nStreams[0] == 1) + { + if (stream_.doConvertBuffer[0]) + { // convert directly to CoreAudio stream buffer + convertBuffer((char *)outBufferList->mBuffers[handle->iStream[0]].mData, + stream_.userBuffer[0], stream_.convertInfo[0]); + } + else + { // copy from user buffer + memcpy(outBufferList->mBuffers[handle->iStream[0]].mData, + stream_.userBuffer[0], + outBufferList->mBuffers[handle->iStream[0]].mDataByteSize); + } + } + else + { // fill multiple streams + Float32 *inBuffer = (Float32 *)stream_.userBuffer[0]; + if (stream_.doConvertBuffer[0]) + { + convertBuffer(stream_.deviceBuffer, stream_.userBuffer[0], stream_.convertInfo[0]); + inBuffer = (Float32 *)stream_.deviceBuffer; + } - if ( handle->nStreams[0] == 1 ) { - memset( outBufferList->mBuffers[handle->iStream[0]].mData, - 0, - outBufferList->mBuffers[handle->iStream[0]].mDataByteSize ); - } - else { // fill multiple streams with zeros - for ( unsigned int i=0; inStreams[0]; i++ ) { - memset( outBufferList->mBuffers[handle->iStream[0]+i].mData, - 0, - outBufferList->mBuffers[handle->iStream[0]+i].mDataByteSize ); - } - } - } - else if ( handle->nStreams[0] == 1 ) { - if ( stream_.doConvertBuffer[0] ) { // convert directly to CoreAudio stream buffer - convertBuffer( (char *) outBufferList->mBuffers[handle->iStream[0]].mData, - stream_.userBuffer[0], stream_.convertInfo[0] ); - } - else { // copy from user buffer - memcpy( outBufferList->mBuffers[handle->iStream[0]].mData, - stream_.userBuffer[0], - outBufferList->mBuffers[handle->iStream[0]].mDataByteSize ); - } - } - else { // fill multiple streams - Float32 *inBuffer = (Float32 *) stream_.userBuffer[0]; - if ( stream_.doConvertBuffer[0] ) { - convertBuffer( stream_.deviceBuffer, stream_.userBuffer[0], stream_.convertInfo[0] ); - inBuffer = (Float32 *) stream_.deviceBuffer; - } + if (stream_.deviceInterleaved[0] == false) + { // mono mode + UInt32 bufferBytes = outBufferList->mBuffers[handle->iStream[0]].mDataByteSize; + for (unsigned int i = 0; i < stream_.nUserChannels[0]; i++) + { + memcpy(outBufferList->mBuffers[handle->iStream[0] + i].mData, + (void *)&inBuffer[i * stream_.bufferSize], bufferBytes); + } + } + else + { // fill multiple multi-channel streams with interleaved data + UInt32 streamChannels, channelsLeft, inJump, outJump, inOffset; + Float32 *out, *in; - if ( stream_.deviceInterleaved[0] == false ) { // mono mode - UInt32 bufferBytes = outBufferList->mBuffers[handle->iStream[0]].mDataByteSize; - for ( unsigned int i=0; imBuffers[handle->iStream[0]+i].mData, - (void *)&inBuffer[i*stream_.bufferSize], bufferBytes ); - } - } - else { // fill multiple multi-channel streams with interleaved data - UInt32 streamChannels, channelsLeft, inJump, outJump, inOffset; - Float32 *out, *in; + bool inInterleaved = (stream_.userInterleaved) ? true : false; + UInt32 inChannels = stream_.nUserChannels[0]; + if (stream_.doConvertBuffer[0]) + { + inInterleaved = true; // device buffer will always be interleaved for nStreams > 1 and not mono mode + inChannels = stream_.nDeviceChannels[0]; + } - bool inInterleaved = ( stream_.userInterleaved ) ? true : false; - UInt32 inChannels = stream_.nUserChannels[0]; - if ( stream_.doConvertBuffer[0] ) { - inInterleaved = true; // device buffer will always be interleaved for nStreams > 1 and not mono mode - inChannels = stream_.nDeviceChannels[0]; - } + if (inInterleaved) + inOffset = 1; + else + inOffset = stream_.bufferSize; - if ( inInterleaved ) inOffset = 1; - else inOffset = stream_.bufferSize; + channelsLeft = inChannels; + for (unsigned int i = 0; i < handle->nStreams[0]; i++) + { + in = inBuffer; + out = (Float32 *)outBufferList->mBuffers[handle->iStream[0] + i].mData; + streamChannels = outBufferList->mBuffers[handle->iStream[0] + i].mNumberChannels; - channelsLeft = inChannels; - for ( unsigned int i=0; inStreams[0]; i++ ) { - in = inBuffer; - out = (Float32 *) outBufferList->mBuffers[handle->iStream[0]+i].mData; - streamChannels = outBufferList->mBuffers[handle->iStream[0]+i].mNumberChannels; + outJump = 0; + // Account for possible channel offset in first stream + if (i == 0 && stream_.channelOffset[0] > 0) + { + streamChannels -= stream_.channelOffset[0]; + outJump = stream_.channelOffset[0]; + out += outJump; + } - outJump = 0; - // Account for possible channel offset in first stream - if ( i == 0 && stream_.channelOffset[0] > 0 ) { - streamChannels -= stream_.channelOffset[0]; - outJump = stream_.channelOffset[0]; - out += outJump; - } + // Account for possible unfilled channels at end of the last stream + if (streamChannels > channelsLeft) + { + outJump = streamChannels - channelsLeft; + streamChannels = channelsLeft; + } - // Account for possible unfilled channels at end of the last stream - if ( streamChannels > channelsLeft ) { - outJump = streamChannels - channelsLeft; - streamChannels = channelsLeft; - } + // Determine input buffer offsets and skips + if (inInterleaved) + { + inJump = inChannels; + in += inChannels - channelsLeft; + } + else + { + inJump = 1; + in += (inChannels - channelsLeft) * inOffset; + } - // Determine input buffer offsets and skips - if ( inInterleaved ) { - inJump = inChannels; - in += inChannels - channelsLeft; - } - else { - inJump = 1; - in += (inChannels - channelsLeft) * inOffset; - } + for (unsigned int i = 0; i < stream_.bufferSize; i++) + { + for (unsigned int j = 0; j < streamChannels; j++) + { + *out++ = in[j * inOffset]; + } + out += outJump; + in += inJump; + } + channelsLeft -= streamChannels; + } + } + } + } - for ( unsigned int i=0; idrainCounter) + { + handle->drainCounter++; + goto unlock; + } - // Don't bother draining input - if ( handle->drainCounter ) { - handle->drainCounter++; - goto unlock; - } + AudioDeviceID inputDevice; + inputDevice = handle->id[1]; + if (stream_.mode == INPUT || (stream_.mode == DUPLEX && deviceId == inputDevice)) + { + if (handle->nStreams[1] == 1) + { + if (stream_.doConvertBuffer[1]) + { // convert directly from CoreAudio stream buffer + convertBuffer(stream_.userBuffer[1], + (char *)inBufferList->mBuffers[handle->iStream[1]].mData, + stream_.convertInfo[1]); + } + else + { // copy to user buffer + memcpy(stream_.userBuffer[1], + inBufferList->mBuffers[handle->iStream[1]].mData, + inBufferList->mBuffers[handle->iStream[1]].mDataByteSize); + } + } + else + { // read from multiple streams + Float32 *outBuffer = (Float32 *)stream_.userBuffer[1]; + if (stream_.doConvertBuffer[1]) outBuffer = (Float32 *)stream_.deviceBuffer; - AudioDeviceID inputDevice; - inputDevice = handle->id[1]; - if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && deviceId == inputDevice ) ) { + if (stream_.deviceInterleaved[1] == false) + { // mono mode + UInt32 bufferBytes = inBufferList->mBuffers[handle->iStream[1]].mDataByteSize; + for (unsigned int i = 0; i < stream_.nUserChannels[1]; i++) + { + memcpy((void *)&outBuffer[i * stream_.bufferSize], + inBufferList->mBuffers[handle->iStream[1] + i].mData, bufferBytes); + } + } + else + { // read from multiple multi-channel streams + UInt32 streamChannels, channelsLeft, inJump, outJump, outOffset; + Float32 *out, *in; - if ( handle->nStreams[1] == 1 ) { - if ( stream_.doConvertBuffer[1] ) { // convert directly from CoreAudio stream buffer - convertBuffer( stream_.userBuffer[1], - (char *) inBufferList->mBuffers[handle->iStream[1]].mData, - stream_.convertInfo[1] ); - } - else { // copy to user buffer - memcpy( stream_.userBuffer[1], - inBufferList->mBuffers[handle->iStream[1]].mData, - inBufferList->mBuffers[handle->iStream[1]].mDataByteSize ); - } - } - else { // read from multiple streams - Float32 *outBuffer = (Float32 *) stream_.userBuffer[1]; - if ( stream_.doConvertBuffer[1] ) outBuffer = (Float32 *) stream_.deviceBuffer; + bool outInterleaved = (stream_.userInterleaved) ? true : false; + UInt32 outChannels = stream_.nUserChannels[1]; + if (stream_.doConvertBuffer[1]) + { + outInterleaved = true; // device buffer will always be interleaved for nStreams > 1 and not mono mode + outChannels = stream_.nDeviceChannels[1]; + } - if ( stream_.deviceInterleaved[1] == false ) { // mono mode - UInt32 bufferBytes = inBufferList->mBuffers[handle->iStream[1]].mDataByteSize; - for ( unsigned int i=0; imBuffers[handle->iStream[1]+i].mData, bufferBytes ); - } - } - else { // read from multiple multi-channel streams - UInt32 streamChannels, channelsLeft, inJump, outJump, outOffset; - Float32 *out, *in; + if (outInterleaved) + outOffset = 1; + else + outOffset = stream_.bufferSize; - bool outInterleaved = ( stream_.userInterleaved ) ? true : false; - UInt32 outChannels = stream_.nUserChannels[1]; - if ( stream_.doConvertBuffer[1] ) { - outInterleaved = true; // device buffer will always be interleaved for nStreams > 1 and not mono mode - outChannels = stream_.nDeviceChannels[1]; - } + channelsLeft = outChannels; + for (unsigned int i = 0; i < handle->nStreams[1]; i++) + { + out = outBuffer; + in = (Float32 *)inBufferList->mBuffers[handle->iStream[1] + i].mData; + streamChannels = inBufferList->mBuffers[handle->iStream[1] + i].mNumberChannels; - if ( outInterleaved ) outOffset = 1; - else outOffset = stream_.bufferSize; + inJump = 0; + // Account for possible channel offset in first stream + if (i == 0 && stream_.channelOffset[1] > 0) + { + streamChannels -= stream_.channelOffset[1]; + inJump = stream_.channelOffset[1]; + in += inJump; + } - channelsLeft = outChannels; - for ( unsigned int i=0; inStreams[1]; i++ ) { - out = outBuffer; - in = (Float32 *) inBufferList->mBuffers[handle->iStream[1]+i].mData; - streamChannels = inBufferList->mBuffers[handle->iStream[1]+i].mNumberChannels; + // Account for possible unread channels at end of the last stream + if (streamChannels > channelsLeft) + { + inJump = streamChannels - channelsLeft; + streamChannels = channelsLeft; + } - inJump = 0; - // Account for possible channel offset in first stream - if ( i == 0 && stream_.channelOffset[1] > 0 ) { - streamChannels -= stream_.channelOffset[1]; - inJump = stream_.channelOffset[1]; - in += inJump; - } + // Determine output buffer offsets and skips + if (outInterleaved) + { + outJump = outChannels; + out += outChannels - channelsLeft; + } + else + { + outJump = 1; + out += (outChannels - channelsLeft) * outOffset; + } - // Account for possible unread channels at end of the last stream - if ( streamChannels > channelsLeft ) { - inJump = streamChannels - channelsLeft; - streamChannels = channelsLeft; - } + for (unsigned int i = 0; i < stream_.bufferSize; i++) + { + for (unsigned int j = 0; j < streamChannels; j++) + { + out[j * outOffset] = *in++; + } + out += outJump; + in += inJump; + } + channelsLeft -= streamChannels; + } + } - // Determine output buffer offsets and skips - if ( outInterleaved ) { - outJump = outChannels; - out += outChannels - channelsLeft; - } - else { - outJump = 1; - out += (outChannels - channelsLeft) * outOffset; - } + if (stream_.doConvertBuffer[1]) + { // convert from our internal "device" buffer + convertBuffer(stream_.userBuffer[1], + stream_.deviceBuffer, + stream_.convertInfo[1]); + } + } + } - for ( unsigned int i=0; i= nDevices ) { - jack_client_close( client ); - errorText_ = "RtApiJack::getDeviceInfo: device ID is invalid!"; - error( RtAudioError::INVALID_USE ); - return info; - } + if (device >= nDevices) + { + jack_client_close(client); + errorText_ = "RtApiJack::getDeviceInfo: device ID is invalid!"; + error(RtAudioError::INVALID_USE); + return info; + } - // Get the current jack server sample rate. - info.sampleRates.clear(); + // Get the current jack server sample rate. + info.sampleRates.clear(); - info.preferredSampleRate = jack_get_sample_rate( client ); - info.sampleRates.push_back( info.preferredSampleRate ); + info.preferredSampleRate = jack_get_sample_rate(client); + info.sampleRates.push_back(info.preferredSampleRate); - // Count the available ports containing the client name as device - // channels. Jack "input ports" equal RtAudio output channels. - unsigned int nChannels = 0; - ports = jack_get_ports( client, info.name.c_str(), NULL, JackPortIsInput ); - if ( ports ) { - while ( ports[ nChannels ] ) nChannels++; - free( ports ); - info.outputChannels = nChannels; - } + // Count the available ports containing the client name as device + // channels. Jack "input ports" equal RtAudio output channels. + unsigned int nChannels = 0; + ports = jack_get_ports(client, info.name.c_str(), NULL, JackPortIsInput); + if (ports) + { + while (ports[nChannels]) nChannels++; + free(ports); + info.outputChannels = nChannels; + } - // Jack "output ports" equal RtAudio input channels. - nChannels = 0; - ports = jack_get_ports( client, info.name.c_str(), NULL, JackPortIsOutput ); - if ( ports ) { - while ( ports[ nChannels ] ) nChannels++; - free( ports ); - info.inputChannels = nChannels; - } + // Jack "output ports" equal RtAudio input channels. + nChannels = 0; + ports = jack_get_ports(client, info.name.c_str(), NULL, JackPortIsOutput); + if (ports) + { + while (ports[nChannels]) nChannels++; + free(ports); + info.inputChannels = nChannels; + } - if ( info.outputChannels == 0 && info.inputChannels == 0 ) { - jack_client_close(client); - errorText_ = "RtApiJack::getDeviceInfo: error determining Jack input/output channels!"; - error( RtAudioError::WARNING ); - return info; - } + if (info.outputChannels == 0 && info.inputChannels == 0) + { + jack_client_close(client); + errorText_ = "RtApiJack::getDeviceInfo: error determining Jack input/output channels!"; + error(RtAudioError::WARNING); + return info; + } - // If device opens for both playback and capture, we determine the channels. - if ( info.outputChannels > 0 && info.inputChannels > 0 ) - info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels; + // If device opens for both playback and capture, we determine the channels. + if (info.outputChannels > 0 && info.inputChannels > 0) + info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels; - // Jack always uses 32-bit floats. - info.nativeFormats = RTAUDIO_FLOAT32; + // Jack always uses 32-bit floats. + info.nativeFormats = RTAUDIO_FLOAT32; - // Jack doesn't provide default devices so we'll use the first available one. - if ( device == 0 && info.outputChannels > 0 ) - info.isDefaultOutput = true; - if ( device == 0 && info.inputChannels > 0 ) - info.isDefaultInput = true; + // Jack doesn't provide default devices so we'll use the first available one. + if (device == 0 && info.outputChannels > 0) + info.isDefaultOutput = true; + if (device == 0 && info.inputChannels > 0) + info.isDefaultInput = true; - jack_client_close(client); - info.probed = true; - return info; + jack_client_close(client); + info.probed = true; + return info; } -static int jackCallbackHandler( jack_nframes_t nframes, void *infoPointer ) +static int jackCallbackHandler(jack_nframes_t nframes, void *infoPointer) { - CallbackInfo *info = (CallbackInfo *) infoPointer; + CallbackInfo *info = (CallbackInfo *)infoPointer; - RtApiJack *object = (RtApiJack *) info->object; - if ( object->callbackEvent( (unsigned long) nframes ) == false ) return 1; + RtApiJack *object = (RtApiJack *)info->object; + if (object->callbackEvent((unsigned long)nframes) == false) return 1; - return 0; + return 0; } // This function will be called by a spawned thread when the Jack // server signals that it is shutting down. It is necessary to handle // it this way because the jackShutdown() function must return before // the jack_deactivate() function (in closeStream()) will return. -static void *jackCloseStream( void *ptr ) +static void *jackCloseStream(void *ptr) { - CallbackInfo *info = (CallbackInfo *) ptr; - RtApiJack *object = (RtApiJack *) info->object; + CallbackInfo *info = (CallbackInfo *)ptr; + RtApiJack *object = (RtApiJack *)info->object; - object->closeStream(); + object->closeStream(); - pthread_exit( NULL ); + pthread_exit(NULL); } -static void jackShutdown( void *infoPointer ) +static void jackShutdown(void *infoPointer) { - CallbackInfo *info = (CallbackInfo *) infoPointer; - RtApiJack *object = (RtApiJack *) info->object; + CallbackInfo *info = (CallbackInfo *)infoPointer; + RtApiJack *object = (RtApiJack *)info->object; - // Check current stream state. If stopped, then we'll assume this - // was called as a result of a call to RtApiJack::stopStream (the - // deactivation of a client handle causes this function to be called). - // If not, we'll assume the Jack server is shutting down or some - // other problem occurred and we should close the stream. - if ( object->isStreamRunning() == false ) return; + // Check current stream state. If stopped, then we'll assume this + // was called as a result of a call to RtApiJack::stopStream (the + // deactivation of a client handle causes this function to be called). + // If not, we'll assume the Jack server is shutting down or some + // other problem occurred and we should close the stream. + if (object->isStreamRunning() == false) return; - ThreadHandle threadId; - pthread_create( &threadId, NULL, jackCloseStream, info ); - std::cerr << "\nRtApiJack: the Jack server is shutting down this client ... stream stopped and closed!!\n" << std::endl; + ThreadHandle threadId; + pthread_create(&threadId, NULL, jackCloseStream, info); + std::cerr << "\nRtApiJack: the Jack server is shutting down this client ... stream stopped and closed!!\n" + << std::endl; } -static int jackXrun( void *infoPointer ) +static int jackXrun(void *infoPointer) { - JackHandle *handle = (JackHandle *) infoPointer; + JackHandle *handle = (JackHandle *)infoPointer; - if ( handle->ports[0] ) handle->xrun[0] = true; - if ( handle->ports[1] ) handle->xrun[1] = true; + if (handle->ports[0]) handle->xrun[0] = true; + if (handle->ports[1]) handle->xrun[1] = true; - return 0; + return 0; } -bool RtApiJack :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, - unsigned int firstChannel, unsigned int sampleRate, - RtAudioFormat format, unsigned int *bufferSize, - RtAudio::StreamOptions *options ) +bool RtApiJack ::probeDeviceOpen(unsigned int device, StreamMode mode, unsigned int channels, + unsigned int firstChannel, unsigned int sampleRate, + RtAudioFormat format, unsigned int *bufferSize, + RtAudio::StreamOptions *options) { - JackHandle *handle = (JackHandle *) stream_.apiHandle; + JackHandle *handle = (JackHandle *)stream_.apiHandle; - // Look for jack server and try to become a client (only do once per stream). - jack_client_t *client = 0; - if ( mode == OUTPUT || ( mode == INPUT && stream_.mode != OUTPUT ) ) { - jack_options_t jackoptions = (jack_options_t) ( JackNoStartServer ); //JackNullOption; - jack_status_t *status = NULL; - if ( options && !options->streamName.empty() ) - client = jack_client_open( options->streamName.c_str(), jackoptions, status ); - else - client = jack_client_open( "RtApiJack", jackoptions, status ); - if ( client == 0 ) { - errorText_ = "RtApiJack::probeDeviceOpen: Jack server not found or connection error!"; - error( RtAudioError::WARNING ); - return FAILURE; - } - } - else { - // The handle must have been created on an earlier pass. - client = handle->client; - } + // Look for jack server and try to become a client (only do once per stream). + jack_client_t *client = 0; + if (mode == OUTPUT || (mode == INPUT && stream_.mode != OUTPUT)) + { + jack_options_t jackoptions = (jack_options_t)(JackNoStartServer); //JackNullOption; + jack_status_t *status = NULL; + if (options && !options->streamName.empty()) + client = jack_client_open(options->streamName.c_str(), jackoptions, status); + else + client = jack_client_open("RtApiJack", jackoptions, status); + if (client == 0) + { + errorText_ = "RtApiJack::probeDeviceOpen: Jack server not found or connection error!"; + error(RtAudioError::WARNING); + return FAILURE; + } + } + else + { + // The handle must have been created on an earlier pass. + client = handle->client; + } - const char **ports; - std::string port, previousPort, deviceName; - unsigned int nPorts = 0, nDevices = 0; - ports = jack_get_ports( client, NULL, NULL, 0 ); - if ( ports ) { - // Parse the port names up to the first colon (:). - size_t iColon = 0; - do { - port = (char *) ports[ nPorts ]; - iColon = port.find(":"); - if ( iColon != std::string::npos ) { - port = port.substr( 0, iColon ); - if ( port != previousPort ) { - if ( nDevices == device ) deviceName = port; - nDevices++; - previousPort = port; - } - } - } while ( ports[++nPorts] ); - free( ports ); - } + const char **ports; + std::string port, previousPort, deviceName; + unsigned int nPorts = 0, nDevices = 0; + ports = jack_get_ports(client, NULL, NULL, 0); + if (ports) + { + // Parse the port names up to the first colon (:). + size_t iColon = 0; + do + { + port = (char *)ports[nPorts]; + iColon = port.find(":"); + if (iColon != std::string::npos) + { + port = port.substr(0, iColon); + if (port != previousPort) + { + if (nDevices == device) deviceName = port; + nDevices++; + previousPort = port; + } + } + } while (ports[++nPorts]); + free(ports); + } - if ( device >= nDevices ) { - errorText_ = "RtApiJack::probeDeviceOpen: device ID is invalid!"; - return FAILURE; - } + if (device >= nDevices) + { + errorText_ = "RtApiJack::probeDeviceOpen: device ID is invalid!"; + return FAILURE; + } - // Count the available ports containing the client name as device - // channels. Jack "input ports" equal RtAudio output channels. - unsigned int nChannels = 0; - unsigned long flag = JackPortIsInput; - if ( mode == INPUT ) flag = JackPortIsOutput; - ports = jack_get_ports( client, deviceName.c_str(), NULL, flag ); - if ( ports ) { - while ( ports[ nChannels ] ) nChannels++; - free( ports ); - } + // Count the available ports containing the client name as device + // channels. Jack "input ports" equal RtAudio output channels. + unsigned int nChannels = 0; + unsigned long flag = JackPortIsInput; + if (mode == INPUT) flag = JackPortIsOutput; + ports = jack_get_ports(client, deviceName.c_str(), NULL, flag); + if (ports) + { + while (ports[nChannels]) nChannels++; + free(ports); + } - // Compare the jack ports for specified client to the requested number of channels. - if ( nChannels < (channels + firstChannel) ) { - errorStream_ << "RtApiJack::probeDeviceOpen: requested number of channels (" << channels << ") + offset (" << firstChannel << ") not found for specified device (" << device << ":" << deviceName << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Compare the jack ports for specified client to the requested number of channels. + if (nChannels < (channels + firstChannel)) + { + errorStream_ << "RtApiJack::probeDeviceOpen: requested number of channels (" << channels << ") + offset (" << firstChannel << ") not found for specified device (" << device << ":" << deviceName << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Check the jack server sample rate. - unsigned int jackRate = jack_get_sample_rate( client ); - if ( sampleRate != jackRate ) { - jack_client_close( client ); - errorStream_ << "RtApiJack::probeDeviceOpen: the requested sample rate (" << sampleRate << ") is different than the JACK server rate (" << jackRate << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } - stream_.sampleRate = jackRate; + // Check the jack server sample rate. + unsigned int jackRate = jack_get_sample_rate(client); + if (sampleRate != jackRate) + { + jack_client_close(client); + errorStream_ << "RtApiJack::probeDeviceOpen: the requested sample rate (" << sampleRate << ") is different than the JACK server rate (" << jackRate << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } + stream_.sampleRate = jackRate; - // Get the latency of the JACK port. - ports = jack_get_ports( client, deviceName.c_str(), NULL, flag ); - if ( ports[ firstChannel ] ) { - // Added by Ge Wang - jack_latency_callback_mode_t cbmode = (mode == INPUT ? JackCaptureLatency : JackPlaybackLatency); - // the range (usually the min and max are equal) - jack_latency_range_t latrange; latrange.min = latrange.max = 0; - // get the latency range - jack_port_get_latency_range( jack_port_by_name( client, ports[firstChannel] ), cbmode, &latrange ); - // be optimistic, use the min! - stream_.latency[mode] = latrange.min; - //stream_.latency[mode] = jack_port_get_latency( jack_port_by_name( client, ports[ firstChannel ] ) ); - } - free( ports ); + // Get the latency of the JACK port. + ports = jack_get_ports(client, deviceName.c_str(), NULL, flag); + if (ports[firstChannel]) + { + // Added by Ge Wang + jack_latency_callback_mode_t cbmode = (mode == INPUT ? JackCaptureLatency : JackPlaybackLatency); + // the range (usually the min and max are equal) + jack_latency_range_t latrange; + latrange.min = latrange.max = 0; + // get the latency range + jack_port_get_latency_range(jack_port_by_name(client, ports[firstChannel]), cbmode, &latrange); + // be optimistic, use the min! + stream_.latency[mode] = latrange.min; + //stream_.latency[mode] = jack_port_get_latency( jack_port_by_name( client, ports[ firstChannel ] ) ); + } + free(ports); - // The jack server always uses 32-bit floating-point data. - stream_.deviceFormat[mode] = RTAUDIO_FLOAT32; - stream_.userFormat = format; + // The jack server always uses 32-bit floating-point data. + stream_.deviceFormat[mode] = RTAUDIO_FLOAT32; + stream_.userFormat = format; - if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) stream_.userInterleaved = false; - else stream_.userInterleaved = true; + if (options && options->flags & RTAUDIO_NONINTERLEAVED) + stream_.userInterleaved = false; + else + stream_.userInterleaved = true; - // Jack always uses non-interleaved buffers. - stream_.deviceInterleaved[mode] = false; + // Jack always uses non-interleaved buffers. + stream_.deviceInterleaved[mode] = false; - // Jack always provides host byte-ordered data. - stream_.doByteSwap[mode] = false; + // Jack always provides host byte-ordered data. + stream_.doByteSwap[mode] = false; - // Get the buffer size. The buffer size and number of buffers - // (periods) is set when the jack server is started. - stream_.bufferSize = (int) jack_get_buffer_size( client ); - *bufferSize = stream_.bufferSize; + // Get the buffer size. The buffer size and number of buffers + // (periods) is set when the jack server is started. + stream_.bufferSize = (int)jack_get_buffer_size(client); + *bufferSize = stream_.bufferSize; - stream_.nDeviceChannels[mode] = channels; - stream_.nUserChannels[mode] = channels; + stream_.nDeviceChannels[mode] = channels; + stream_.nUserChannels[mode] = channels; - // Set flags for buffer conversion. - stream_.doConvertBuffer[mode] = false; - if ( stream_.userFormat != stream_.deviceFormat[mode] ) - stream_.doConvertBuffer[mode] = true; - if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] && - stream_.nUserChannels[mode] > 1 ) - stream_.doConvertBuffer[mode] = true; + // Set flags for buffer conversion. + stream_.doConvertBuffer[mode] = false; + if (stream_.userFormat != stream_.deviceFormat[mode]) + stream_.doConvertBuffer[mode] = true; + if (stream_.userInterleaved != stream_.deviceInterleaved[mode] && + stream_.nUserChannels[mode] > 1) + stream_.doConvertBuffer[mode] = true; - // Allocate our JackHandle structure for the stream. - if ( handle == 0 ) { - try { - handle = new JackHandle; - } - catch ( std::bad_alloc& ) { - errorText_ = "RtApiJack::probeDeviceOpen: error allocating JackHandle memory."; - goto error; - } + // Allocate our JackHandle structure for the stream. + if (handle == 0) + { + try + { + handle = new JackHandle; + } + catch (std::bad_alloc &) + { + errorText_ = "RtApiJack::probeDeviceOpen: error allocating JackHandle memory."; + goto error; + } - if ( pthread_cond_init(&handle->condition, NULL) ) { - errorText_ = "RtApiJack::probeDeviceOpen: error initializing pthread condition variable."; - goto error; - } - stream_.apiHandle = (void *) handle; - handle->client = client; - } - handle->deviceName[mode] = deviceName; + if (pthread_cond_init(&handle->condition, NULL)) + { + errorText_ = "RtApiJack::probeDeviceOpen: error initializing pthread condition variable."; + goto error; + } + stream_.apiHandle = (void *)handle; + handle->client = client; + } + handle->deviceName[mode] = deviceName; - // Allocate necessary internal buffers. - unsigned long bufferBytes; - bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat ); - stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 ); - if ( stream_.userBuffer[mode] == NULL ) { - errorText_ = "RtApiJack::probeDeviceOpen: error allocating user buffer memory."; - goto error; - } + // Allocate necessary internal buffers. + unsigned long bufferBytes; + bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes(stream_.userFormat); + stream_.userBuffer[mode] = (char *)calloc(bufferBytes, 1); + if (stream_.userBuffer[mode] == NULL) + { + errorText_ = "RtApiJack::probeDeviceOpen: error allocating user buffer memory."; + goto error; + } - if ( stream_.doConvertBuffer[mode] ) { + if (stream_.doConvertBuffer[mode]) + { + bool makeBuffer = true; + if (mode == OUTPUT) + bufferBytes = stream_.nDeviceChannels[0] * formatBytes(stream_.deviceFormat[0]); + else + { // mode == INPUT + bufferBytes = stream_.nDeviceChannels[1] * formatBytes(stream_.deviceFormat[1]); + if (stream_.mode == OUTPUT && stream_.deviceBuffer) + { + unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes(stream_.deviceFormat[0]); + if (bufferBytes < bytesOut) makeBuffer = false; + } + } - bool makeBuffer = true; - if ( mode == OUTPUT ) - bufferBytes = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] ); - else { // mode == INPUT - bufferBytes = stream_.nDeviceChannels[1] * formatBytes( stream_.deviceFormat[1] ); - if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) { - unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes(stream_.deviceFormat[0]); - if ( bufferBytes < bytesOut ) makeBuffer = false; - } - } + if (makeBuffer) + { + bufferBytes *= *bufferSize; + if (stream_.deviceBuffer) free(stream_.deviceBuffer); + stream_.deviceBuffer = (char *)calloc(bufferBytes, 1); + if (stream_.deviceBuffer == NULL) + { + errorText_ = "RtApiJack::probeDeviceOpen: error allocating device buffer memory."; + goto error; + } + } + } - if ( makeBuffer ) { - bufferBytes *= *bufferSize; - if ( stream_.deviceBuffer ) free( stream_.deviceBuffer ); - stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 ); - if ( stream_.deviceBuffer == NULL ) { - errorText_ = "RtApiJack::probeDeviceOpen: error allocating device buffer memory."; - goto error; - } - } - } + // Allocate memory for the Jack ports (channels) identifiers. + handle->ports[mode] = (jack_port_t **)malloc(sizeof(jack_port_t *) * channels); + if (handle->ports[mode] == NULL) + { + errorText_ = "RtApiJack::probeDeviceOpen: error allocating port memory."; + goto error; + } - // Allocate memory for the Jack ports (channels) identifiers. - handle->ports[mode] = (jack_port_t **) malloc ( sizeof (jack_port_t *) * channels ); - if ( handle->ports[mode] == NULL ) { - errorText_ = "RtApiJack::probeDeviceOpen: error allocating port memory."; - goto error; - } + stream_.device[mode] = device; + stream_.channelOffset[mode] = firstChannel; + stream_.state = STREAM_STOPPED; + stream_.callbackInfo.object = (void *)this; - stream_.device[mode] = device; - stream_.channelOffset[mode] = firstChannel; - stream_.state = STREAM_STOPPED; - stream_.callbackInfo.object = (void *) this; + if (stream_.mode == OUTPUT && mode == INPUT) + // We had already set up the stream for output. + stream_.mode = DUPLEX; + else + { + stream_.mode = mode; + jack_set_process_callback(handle->client, jackCallbackHandler, (void *)&stream_.callbackInfo); + jack_set_xrun_callback(handle->client, jackXrun, (void *)&handle); + jack_on_shutdown(handle->client, jackShutdown, (void *)&stream_.callbackInfo); + } - if ( stream_.mode == OUTPUT && mode == INPUT ) - // We had already set up the stream for output. - stream_.mode = DUPLEX; - else { - stream_.mode = mode; - jack_set_process_callback( handle->client, jackCallbackHandler, (void *) &stream_.callbackInfo ); - jack_set_xrun_callback( handle->client, jackXrun, (void *) &handle ); - jack_on_shutdown( handle->client, jackShutdown, (void *) &stream_.callbackInfo ); - } + // Register our ports. + char label[64]; + if (mode == OUTPUT) + { + for (unsigned int i = 0; i < stream_.nUserChannels[0]; i++) + { + snprintf(label, 64, "outport %d", i); + handle->ports[0][i] = jack_port_register(handle->client, (const char *)label, + JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); + } + } + else + { + for (unsigned int i = 0; i < stream_.nUserChannels[1]; i++) + { + snprintf(label, 64, "inport %d", i); + handle->ports[1][i] = jack_port_register(handle->client, (const char *)label, + JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); + } + } - // Register our ports. - char label[64]; - if ( mode == OUTPUT ) { - for ( unsigned int i=0; iports[0][i] = jack_port_register( handle->client, (const char *)label, - JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 ); - } - } - else { - for ( unsigned int i=0; iports[1][i] = jack_port_register( handle->client, (const char *)label, - JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 ); - } - } + // Setup the buffer conversion information structure. We don't use + // buffers to do channel offsets, so we override that parameter + // here. + if (stream_.doConvertBuffer[mode]) setConvertInfo(mode, 0); - // Setup the buffer conversion information structure. We don't use - // buffers to do channel offsets, so we override that parameter - // here. - if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, 0 ); + return SUCCESS; - return SUCCESS; +error: + if (handle) + { + pthread_cond_destroy(&handle->condition); + jack_client_close(handle->client); - error: - if ( handle ) { - pthread_cond_destroy( &handle->condition ); - jack_client_close( handle->client ); + if (handle->ports[0]) free(handle->ports[0]); + if (handle->ports[1]) free(handle->ports[1]); - if ( handle->ports[0] ) free( handle->ports[0] ); - if ( handle->ports[1] ) free( handle->ports[1] ); + delete handle; + stream_.apiHandle = 0; + } - delete handle; - stream_.apiHandle = 0; - } + for (int i = 0; i < 2; i++) + { + if (stream_.userBuffer[i]) + { + free(stream_.userBuffer[i]); + stream_.userBuffer[i] = 0; + } + } - for ( int i=0; i<2; i++ ) { - if ( stream_.userBuffer[i] ) { - free( stream_.userBuffer[i] ); - stream_.userBuffer[i] = 0; - } - } + if (stream_.deviceBuffer) + { + free(stream_.deviceBuffer); + stream_.deviceBuffer = 0; + } - if ( stream_.deviceBuffer ) { - free( stream_.deviceBuffer ); - stream_.deviceBuffer = 0; - } - - return FAILURE; + return FAILURE; } -void RtApiJack :: closeStream( void ) +void RtApiJack ::closeStream(void) { - if ( stream_.state == STREAM_CLOSED ) { - errorText_ = "RtApiJack::closeStream(): no open stream to close!"; - error( RtAudioError::WARNING ); - return; - } + if (stream_.state == STREAM_CLOSED) + { + errorText_ = "RtApiJack::closeStream(): no open stream to close!"; + error(RtAudioError::WARNING); + return; + } - JackHandle *handle = (JackHandle *) stream_.apiHandle; - if ( handle ) { + JackHandle *handle = (JackHandle *)stream_.apiHandle; + if (handle) + { + if (stream_.state == STREAM_RUNNING) + jack_deactivate(handle->client); - if ( stream_.state == STREAM_RUNNING ) - jack_deactivate( handle->client ); + jack_client_close(handle->client); + } - jack_client_close( handle->client ); - } + if (handle) + { + if (handle->ports[0]) free(handle->ports[0]); + if (handle->ports[1]) free(handle->ports[1]); + pthread_cond_destroy(&handle->condition); + delete handle; + stream_.apiHandle = 0; + } - if ( handle ) { - if ( handle->ports[0] ) free( handle->ports[0] ); - if ( handle->ports[1] ) free( handle->ports[1] ); - pthread_cond_destroy( &handle->condition ); - delete handle; - stream_.apiHandle = 0; - } + for (int i = 0; i < 2; i++) + { + if (stream_.userBuffer[i]) + { + free(stream_.userBuffer[i]); + stream_.userBuffer[i] = 0; + } + } - for ( int i=0; i<2; i++ ) { - if ( stream_.userBuffer[i] ) { - free( stream_.userBuffer[i] ); - stream_.userBuffer[i] = 0; - } - } + if (stream_.deviceBuffer) + { + free(stream_.deviceBuffer); + stream_.deviceBuffer = 0; + } - if ( stream_.deviceBuffer ) { - free( stream_.deviceBuffer ); - stream_.deviceBuffer = 0; - } - - stream_.mode = UNINITIALIZED; - stream_.state = STREAM_CLOSED; + stream_.mode = UNINITIALIZED; + stream_.state = STREAM_CLOSED; } -void RtApiJack :: startStream( void ) +void RtApiJack ::startStream(void) { - verifyStream(); - if ( stream_.state == STREAM_RUNNING ) { - errorText_ = "RtApiJack::startStream(): the stream is already running!"; - error( RtAudioError::WARNING ); - return; - } + verifyStream(); + if (stream_.state == STREAM_RUNNING) + { + errorText_ = "RtApiJack::startStream(): the stream is already running!"; + error(RtAudioError::WARNING); + return; + } - JackHandle *handle = (JackHandle *) stream_.apiHandle; - int result = jack_activate( handle->client ); - if ( result ) { - errorText_ = "RtApiJack::startStream(): unable to activate JACK client!"; - goto unlock; - } + JackHandle *handle = (JackHandle *)stream_.apiHandle; + int result = jack_activate(handle->client); + if (result) + { + errorText_ = "RtApiJack::startStream(): unable to activate JACK client!"; + goto unlock; + } - const char **ports; + const char **ports; - // Get the list of available ports. - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { - result = 1; - ports = jack_get_ports( handle->client, handle->deviceName[0].c_str(), NULL, JackPortIsInput); - if ( ports == NULL) { - errorText_ = "RtApiJack::startStream(): error determining available JACK input ports!"; - goto unlock; - } + // Get the list of available ports. + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + { + result = 1; + ports = jack_get_ports(handle->client, handle->deviceName[0].c_str(), NULL, JackPortIsInput); + if (ports == NULL) + { + errorText_ = "RtApiJack::startStream(): error determining available JACK input ports!"; + goto unlock; + } - // Now make the port connections. Since RtAudio wasn't designed to - // allow the user to select particular channels of a device, we'll - // just open the first "nChannels" ports with offset. - for ( unsigned int i=0; iclient, jack_port_name( handle->ports[0][i] ), ports[ stream_.channelOffset[0] + i ] ); - if ( result ) { - free( ports ); - errorText_ = "RtApiJack::startStream(): error connecting output ports!"; - goto unlock; - } - } - free(ports); - } + // Now make the port connections. Since RtAudio wasn't designed to + // allow the user to select particular channels of a device, we'll + // just open the first "nChannels" ports with offset. + for (unsigned int i = 0; i < stream_.nUserChannels[0]; i++) + { + result = 1; + if (ports[stream_.channelOffset[0] + i]) + result = jack_connect(handle->client, jack_port_name(handle->ports[0][i]), ports[stream_.channelOffset[0] + i]); + if (result) + { + free(ports); + errorText_ = "RtApiJack::startStream(): error connecting output ports!"; + goto unlock; + } + } + free(ports); + } - if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) { - result = 1; - ports = jack_get_ports( handle->client, handle->deviceName[1].c_str(), NULL, JackPortIsOutput ); - if ( ports == NULL) { - errorText_ = "RtApiJack::startStream(): error determining available JACK output ports!"; - goto unlock; - } + if (stream_.mode == INPUT || stream_.mode == DUPLEX) + { + result = 1; + ports = jack_get_ports(handle->client, handle->deviceName[1].c_str(), NULL, JackPortIsOutput); + if (ports == NULL) + { + errorText_ = "RtApiJack::startStream(): error determining available JACK output ports!"; + goto unlock; + } - // Now make the port connections. See note above. - for ( unsigned int i=0; iclient, ports[ stream_.channelOffset[1] + i ], jack_port_name( handle->ports[1][i] ) ); - if ( result ) { - free( ports ); - errorText_ = "RtApiJack::startStream(): error connecting input ports!"; - goto unlock; - } - } - free(ports); - } + // Now make the port connections. See note above. + for (unsigned int i = 0; i < stream_.nUserChannels[1]; i++) + { + result = 1; + if (ports[stream_.channelOffset[1] + i]) + result = jack_connect(handle->client, ports[stream_.channelOffset[1] + i], jack_port_name(handle->ports[1][i])); + if (result) + { + free(ports); + errorText_ = "RtApiJack::startStream(): error connecting input ports!"; + goto unlock; + } + } + free(ports); + } - handle->drainCounter = 0; - handle->internalDrain = false; - stream_.state = STREAM_RUNNING; + handle->drainCounter = 0; + handle->internalDrain = false; + stream_.state = STREAM_RUNNING; - unlock: - if ( result == 0 ) return; - error( RtAudioError::SYSTEM_ERROR ); +unlock: + if (result == 0) return; + error(RtAudioError::SYSTEM_ERROR); } -void RtApiJack :: stopStream( void ) +void RtApiJack ::stopStream(void) { - verifyStream(); - if ( stream_.state == STREAM_STOPPED ) { - errorText_ = "RtApiJack::stopStream(): the stream is already stopped!"; - error( RtAudioError::WARNING ); - return; - } + verifyStream(); + if (stream_.state == STREAM_STOPPED) + { + errorText_ = "RtApiJack::stopStream(): the stream is already stopped!"; + error(RtAudioError::WARNING); + return; + } - JackHandle *handle = (JackHandle *) stream_.apiHandle; - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { + JackHandle *handle = (JackHandle *)stream_.apiHandle; + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + { + if (handle->drainCounter == 0) + { + handle->drainCounter = 2; + pthread_cond_wait(&handle->condition, &stream_.mutex); // block until signaled + } + } - if ( handle->drainCounter == 0 ) { - handle->drainCounter = 2; - pthread_cond_wait( &handle->condition, &stream_.mutex ); // block until signaled - } - } - - jack_deactivate( handle->client ); - stream_.state = STREAM_STOPPED; + jack_deactivate(handle->client); + stream_.state = STREAM_STOPPED; } -void RtApiJack :: abortStream( void ) +void RtApiJack ::abortStream(void) { - verifyStream(); - if ( stream_.state == STREAM_STOPPED ) { - errorText_ = "RtApiJack::abortStream(): the stream is already stopped!"; - error( RtAudioError::WARNING ); - return; - } + verifyStream(); + if (stream_.state == STREAM_STOPPED) + { + errorText_ = "RtApiJack::abortStream(): the stream is already stopped!"; + error(RtAudioError::WARNING); + return; + } - JackHandle *handle = (JackHandle *) stream_.apiHandle; - handle->drainCounter = 2; + JackHandle *handle = (JackHandle *)stream_.apiHandle; + handle->drainCounter = 2; - stopStream(); + stopStream(); } // This function will be called by a spawned thread when the user @@ -2540,132 +2789,149 @@ void RtApiJack :: abortStream( void ) // aborted. It is necessary to handle it this way because the // callbackEvent() function must return before the jack_deactivate() // function will return. -static void *jackStopStream( void *ptr ) +static void *jackStopStream(void *ptr) { - CallbackInfo *info = (CallbackInfo *) ptr; - RtApiJack *object = (RtApiJack *) info->object; + CallbackInfo *info = (CallbackInfo *)ptr; + RtApiJack *object = (RtApiJack *)info->object; - object->stopStream(); - pthread_exit( NULL ); + object->stopStream(); + pthread_exit(NULL); } -bool RtApiJack :: callbackEvent( unsigned long nframes ) +bool RtApiJack ::callbackEvent(unsigned long nframes) { - if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) return SUCCESS; - if ( stream_.state == STREAM_CLOSED ) { - errorText_ = "RtApiCore::callbackEvent(): the stream is closed ... this shouldn't happen!"; - error( RtAudioError::WARNING ); - return FAILURE; - } - if ( stream_.bufferSize != nframes ) { - errorText_ = "RtApiCore::callbackEvent(): the JACK buffer size has changed ... cannot process!"; - error( RtAudioError::WARNING ); - return FAILURE; - } + if (stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING) return SUCCESS; + if (stream_.state == STREAM_CLOSED) + { + errorText_ = "RtApiCore::callbackEvent(): the stream is closed ... this shouldn't happen!"; + error(RtAudioError::WARNING); + return FAILURE; + } + if (stream_.bufferSize != nframes) + { + errorText_ = "RtApiCore::callbackEvent(): the JACK buffer size has changed ... cannot process!"; + error(RtAudioError::WARNING); + return FAILURE; + } - CallbackInfo *info = (CallbackInfo *) &stream_.callbackInfo; - JackHandle *handle = (JackHandle *) stream_.apiHandle; + CallbackInfo *info = (CallbackInfo *)&stream_.callbackInfo; + JackHandle *handle = (JackHandle *)stream_.apiHandle; - // Check if we were draining the stream and signal is finished. - if ( handle->drainCounter > 3 ) { - ThreadHandle threadId; + // Check if we were draining the stream and signal is finished. + if (handle->drainCounter > 3) + { + ThreadHandle threadId; - stream_.state = STREAM_STOPPING; - if ( handle->internalDrain == true ) - pthread_create( &threadId, NULL, jackStopStream, info ); - else - pthread_cond_signal( &handle->condition ); - return SUCCESS; - } + stream_.state = STREAM_STOPPING; + if (handle->internalDrain == true) + pthread_create(&threadId, NULL, jackStopStream, info); + else + pthread_cond_signal(&handle->condition); + return SUCCESS; + } - // Invoke user callback first, to get fresh output data. - if ( handle->drainCounter == 0 ) { - RtAudioCallback callback = (RtAudioCallback) info->callback; - double streamTime = getStreamTime(); - RtAudioStreamStatus status = 0; - if ( stream_.mode != INPUT && handle->xrun[0] == true ) { - status |= RTAUDIO_OUTPUT_UNDERFLOW; - handle->xrun[0] = false; - } - if ( stream_.mode != OUTPUT && handle->xrun[1] == true ) { - status |= RTAUDIO_INPUT_OVERFLOW; - handle->xrun[1] = false; - } - int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1], - stream_.bufferSize, streamTime, status, info->userData ); - if ( cbReturnValue == 2 ) { - stream_.state = STREAM_STOPPING; - handle->drainCounter = 2; - ThreadHandle id; - pthread_create( &id, NULL, jackStopStream, info ); - return SUCCESS; - } - else if ( cbReturnValue == 1 ) { - handle->drainCounter = 1; - handle->internalDrain = true; - } - } + // Invoke user callback first, to get fresh output data. + if (handle->drainCounter == 0) + { + RtAudioCallback callback = (RtAudioCallback)info->callback; + double streamTime = getStreamTime(); + RtAudioStreamStatus status = 0; + if (stream_.mode != INPUT && handle->xrun[0] == true) + { + status |= RTAUDIO_OUTPUT_UNDERFLOW; + handle->xrun[0] = false; + } + if (stream_.mode != OUTPUT && handle->xrun[1] == true) + { + status |= RTAUDIO_INPUT_OVERFLOW; + handle->xrun[1] = false; + } + int cbReturnValue = callback(stream_.userBuffer[0], stream_.userBuffer[1], + stream_.bufferSize, streamTime, status, info->userData); + if (cbReturnValue == 2) + { + stream_.state = STREAM_STOPPING; + handle->drainCounter = 2; + ThreadHandle id; + pthread_create(&id, NULL, jackStopStream, info); + return SUCCESS; + } + else if (cbReturnValue == 1) + { + handle->drainCounter = 1; + handle->internalDrain = true; + } + } - jack_default_audio_sample_t *jackbuffer; - unsigned long bufferBytes = nframes * sizeof( jack_default_audio_sample_t ); - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { + jack_default_audio_sample_t *jackbuffer; + unsigned long bufferBytes = nframes * sizeof(jack_default_audio_sample_t); + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + { + if (handle->drainCounter > 1) + { // write zeros to the output stream - if ( handle->drainCounter > 1 ) { // write zeros to the output stream + for (unsigned int i = 0; i < stream_.nDeviceChannels[0]; i++) + { + jackbuffer = (jack_default_audio_sample_t *)jack_port_get_buffer(handle->ports[0][i], (jack_nframes_t)nframes); + memset(jackbuffer, 0, bufferBytes); + } + } + else if (stream_.doConvertBuffer[0]) + { + convertBuffer(stream_.deviceBuffer, stream_.userBuffer[0], stream_.convertInfo[0]); - for ( unsigned int i=0; iports[0][i], (jack_nframes_t) nframes ); - memset( jackbuffer, 0, bufferBytes ); - } + for (unsigned int i = 0; i < stream_.nDeviceChannels[0]; i++) + { + jackbuffer = (jack_default_audio_sample_t *)jack_port_get_buffer(handle->ports[0][i], (jack_nframes_t)nframes); + memcpy(jackbuffer, &stream_.deviceBuffer[i * bufferBytes], bufferBytes); + } + } + else + { // no buffer conversion + for (unsigned int i = 0; i < stream_.nUserChannels[0]; i++) + { + jackbuffer = (jack_default_audio_sample_t *)jack_port_get_buffer(handle->ports[0][i], (jack_nframes_t)nframes); + memcpy(jackbuffer, &stream_.userBuffer[0][i * bufferBytes], bufferBytes); + } + } + } - } - else if ( stream_.doConvertBuffer[0] ) { + // Don't bother draining input + if (handle->drainCounter) + { + handle->drainCounter++; + goto unlock; + } - convertBuffer( stream_.deviceBuffer, stream_.userBuffer[0], stream_.convertInfo[0] ); + if (stream_.mode == INPUT || stream_.mode == DUPLEX) + { + if (stream_.doConvertBuffer[1]) + { + for (unsigned int i = 0; i < stream_.nDeviceChannels[1]; i++) + { + jackbuffer = (jack_default_audio_sample_t *)jack_port_get_buffer(handle->ports[1][i], (jack_nframes_t)nframes); + memcpy(&stream_.deviceBuffer[i * bufferBytes], jackbuffer, bufferBytes); + } + convertBuffer(stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1]); + } + else + { // no buffer conversion + for (unsigned int i = 0; i < stream_.nUserChannels[1]; i++) + { + jackbuffer = (jack_default_audio_sample_t *)jack_port_get_buffer(handle->ports[1][i], (jack_nframes_t)nframes); + memcpy(&stream_.userBuffer[1][i * bufferBytes], jackbuffer, bufferBytes); + } + } + } - for ( unsigned int i=0; iports[0][i], (jack_nframes_t) nframes ); - memcpy( jackbuffer, &stream_.deviceBuffer[i*bufferBytes], bufferBytes ); - } - } - else { // no buffer conversion - for ( unsigned int i=0; iports[0][i], (jack_nframes_t) nframes ); - memcpy( jackbuffer, &stream_.userBuffer[0][i*bufferBytes], bufferBytes ); - } - } - } - - // Don't bother draining input - if ( handle->drainCounter ) { - handle->drainCounter++; - goto unlock; - } - - if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) { - - if ( stream_.doConvertBuffer[1] ) { - for ( unsigned int i=0; iports[1][i], (jack_nframes_t) nframes ); - memcpy( &stream_.deviceBuffer[i*bufferBytes], jackbuffer, bufferBytes ); - } - convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] ); - } - else { // no buffer conversion - for ( unsigned int i=0; iports[1][i], (jack_nframes_t) nframes ); - memcpy( &stream_.userBuffer[1][i*bufferBytes], jackbuffer, bufferBytes ); - } - } - } - - unlock: - RtApi::tickStreamTime(); - return SUCCESS; +unlock: + RtApi::tickStreamTime(); + return SUCCESS; } - //******************** End of __UNIX_JACK__ *********************// +//******************** End of __UNIX_JACK__ *********************// #endif -#if defined(__WINDOWS_ASIO__) // ASIO API on Windows +#if defined(__WINDOWS_ASIO__) // ASIO API on Windows // The ASIO API is designed around a callback scheme, so this // implementation is similar to that used for OS-X CoreAudio and Linux @@ -2695,382 +2961,427 @@ static ASIODriverInfo driverInfo; static CallbackInfo *asioCallbackInfo; static bool asioXRun; -struct AsioHandle { - int drainCounter; // Tracks callback counts when draining - bool internalDrain; // Indicates if stop is initiated from callback or not. - ASIOBufferInfo *bufferInfos; - HANDLE condition; +struct AsioHandle +{ + int drainCounter; // Tracks callback counts when draining + bool internalDrain; // Indicates if stop is initiated from callback or not. + ASIOBufferInfo *bufferInfos; + HANDLE condition; - AsioHandle() - :drainCounter(0), internalDrain(false), bufferInfos(0) {} + AsioHandle() + : drainCounter(0), internalDrain(false), bufferInfos(0) {} }; // Function declarations (definitions at end of section) -static const char* getAsioErrorString( ASIOError result ); -static void sampleRateChanged( ASIOSampleRate sRate ); -static long asioMessages( long selector, long value, void* message, double* opt ); +static const char *getAsioErrorString(ASIOError result); +static void sampleRateChanged(ASIOSampleRate sRate); +static long asioMessages(long selector, long value, void *message, double *opt); -RtApiAsio :: RtApiAsio() +RtApiAsio ::RtApiAsio() { - // ASIO cannot run on a multi-threaded appartment. You can call - // CoInitialize beforehand, but it must be for appartment threading - // (in which case, CoInitilialize will return S_FALSE here). - coInitialized_ = false; - HRESULT hr = CoInitialize( NULL ); - if ( FAILED(hr) ) { - errorText_ = "RtApiAsio::ASIO requires a single-threaded appartment. Call CoInitializeEx(0,COINIT_APARTMENTTHREADED)"; - error( RtAudioError::WARNING ); - } - coInitialized_ = true; + // ASIO cannot run on a multi-threaded appartment. You can call + // CoInitialize beforehand, but it must be for appartment threading + // (in which case, CoInitilialize will return S_FALSE here). + coInitialized_ = false; + HRESULT hr = CoInitialize(NULL); + if (FAILED(hr)) + { + errorText_ = "RtApiAsio::ASIO requires a single-threaded appartment. Call CoInitializeEx(0,COINIT_APARTMENTTHREADED)"; + error(RtAudioError::WARNING); + } + coInitialized_ = true; - drivers.removeCurrentDriver(); - driverInfo.asioVersion = 2; + drivers.removeCurrentDriver(); + driverInfo.asioVersion = 2; - // See note in DirectSound implementation about GetDesktopWindow(). - driverInfo.sysRef = GetForegroundWindow(); + // See note in DirectSound implementation about GetDesktopWindow(). + driverInfo.sysRef = GetForegroundWindow(); } -RtApiAsio :: ~RtApiAsio() +RtApiAsio ::~RtApiAsio() { - if ( stream_.state != STREAM_CLOSED ) closeStream(); - if ( coInitialized_ ) CoUninitialize(); + if (stream_.state != STREAM_CLOSED) closeStream(); + if (coInitialized_) CoUninitialize(); } -unsigned int RtApiAsio :: getDeviceCount( void ) +unsigned int RtApiAsio ::getDeviceCount(void) { - return (unsigned int) drivers.asioGetNumDev(); + return (unsigned int)drivers.asioGetNumDev(); } -RtAudio::DeviceInfo RtApiAsio :: getDeviceInfo( unsigned int device ) +RtAudio::DeviceInfo RtApiAsio ::getDeviceInfo(unsigned int device) { - RtAudio::DeviceInfo info; - info.probed = false; + RtAudio::DeviceInfo info; + info.probed = false; - // Get device ID - unsigned int nDevices = getDeviceCount(); - if ( nDevices == 0 ) { - errorText_ = "RtApiAsio::getDeviceInfo: no devices found!"; - error( RtAudioError::INVALID_USE ); - return info; - } + // Get device ID + unsigned int nDevices = getDeviceCount(); + if (nDevices == 0) + { + errorText_ = "RtApiAsio::getDeviceInfo: no devices found!"; + error(RtAudioError::INVALID_USE); + return info; + } - if ( device >= nDevices ) { - errorText_ = "RtApiAsio::getDeviceInfo: device ID is invalid!"; - error( RtAudioError::INVALID_USE ); - return info; - } + if (device >= nDevices) + { + errorText_ = "RtApiAsio::getDeviceInfo: device ID is invalid!"; + error(RtAudioError::INVALID_USE); + return info; + } - // If a stream is already open, we cannot probe other devices. Thus, use the saved results. - if ( stream_.state != STREAM_CLOSED ) { - if ( device >= devices_.size() ) { - errorText_ = "RtApiAsio::getDeviceInfo: device ID was not present before stream was opened."; - error( RtAudioError::WARNING ); - return info; - } - return devices_[ device ]; - } + // If a stream is already open, we cannot probe other devices. Thus, use the saved results. + if (stream_.state != STREAM_CLOSED) + { + if (device >= devices_.size()) + { + errorText_ = "RtApiAsio::getDeviceInfo: device ID was not present before stream was opened."; + error(RtAudioError::WARNING); + return info; + } + return devices_[device]; + } - char driverName[32]; - ASIOError result = drivers.asioGetDriverName( (int) device, driverName, 32 ); - if ( result != ASE_OK ) { - errorStream_ << "RtApiAsio::getDeviceInfo: unable to get driver name (" << getAsioErrorString( result ) << ")."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + char driverName[32]; + ASIOError result = drivers.asioGetDriverName((int)device, driverName, 32); + if (result != ASE_OK) + { + errorStream_ << "RtApiAsio::getDeviceInfo: unable to get driver name (" << getAsioErrorString(result) << ")."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - info.name = driverName; + info.name = driverName; - if ( !drivers.loadDriver( driverName ) ) { - errorStream_ << "RtApiAsio::getDeviceInfo: unable to load driver (" << driverName << ")."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + if (!drivers.loadDriver(driverName)) + { + errorStream_ << "RtApiAsio::getDeviceInfo: unable to load driver (" << driverName << ")."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - result = ASIOInit( &driverInfo ); - if ( result != ASE_OK ) { - errorStream_ << "RtApiAsio::getDeviceInfo: error (" << getAsioErrorString( result ) << ") initializing driver (" << driverName << ")."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + result = ASIOInit(&driverInfo); + if (result != ASE_OK) + { + errorStream_ << "RtApiAsio::getDeviceInfo: error (" << getAsioErrorString(result) << ") initializing driver (" << driverName << ")."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - // Determine the device channel information. - long inputChannels, outputChannels; - result = ASIOGetChannels( &inputChannels, &outputChannels ); - if ( result != ASE_OK ) { - drivers.removeCurrentDriver(); - errorStream_ << "RtApiAsio::getDeviceInfo: error (" << getAsioErrorString( result ) << ") getting channel count (" << driverName << ")."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + // Determine the device channel information. + long inputChannels, outputChannels; + result = ASIOGetChannels(&inputChannels, &outputChannels); + if (result != ASE_OK) + { + drivers.removeCurrentDriver(); + errorStream_ << "RtApiAsio::getDeviceInfo: error (" << getAsioErrorString(result) << ") getting channel count (" << driverName << ")."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - info.outputChannels = outputChannels; - info.inputChannels = inputChannels; - if ( info.outputChannels > 0 && info.inputChannels > 0 ) - info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels; + info.outputChannels = outputChannels; + info.inputChannels = inputChannels; + if (info.outputChannels > 0 && info.inputChannels > 0) + info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels; - // Determine the supported sample rates. - info.sampleRates.clear(); - for ( unsigned int i=0; i info.preferredSampleRate ) ) - info.preferredSampleRate = SAMPLE_RATES[i]; - } - } + if (!info.preferredSampleRate || (SAMPLE_RATES[i] <= 48000 && SAMPLE_RATES[i] > info.preferredSampleRate)) + info.preferredSampleRate = SAMPLE_RATES[i]; + } + } - // Determine supported data types ... just check first channel and assume rest are the same. - ASIOChannelInfo channelInfo; - channelInfo.channel = 0; - channelInfo.isInput = true; - if ( info.inputChannels <= 0 ) channelInfo.isInput = false; - result = ASIOGetChannelInfo( &channelInfo ); - if ( result != ASE_OK ) { - drivers.removeCurrentDriver(); - errorStream_ << "RtApiAsio::getDeviceInfo: error (" << getAsioErrorString( result ) << ") getting driver channel info (" << driverName << ")."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + // Determine supported data types ... just check first channel and assume rest are the same. + ASIOChannelInfo channelInfo; + channelInfo.channel = 0; + channelInfo.isInput = true; + if (info.inputChannels <= 0) channelInfo.isInput = false; + result = ASIOGetChannelInfo(&channelInfo); + if (result != ASE_OK) + { + drivers.removeCurrentDriver(); + errorStream_ << "RtApiAsio::getDeviceInfo: error (" << getAsioErrorString(result) << ") getting driver channel info (" << driverName << ")."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - info.nativeFormats = 0; - if ( channelInfo.type == ASIOSTInt16MSB || channelInfo.type == ASIOSTInt16LSB ) - info.nativeFormats |= RTAUDIO_SINT16; - else if ( channelInfo.type == ASIOSTInt32MSB || channelInfo.type == ASIOSTInt32LSB ) - info.nativeFormats |= RTAUDIO_SINT32; - else if ( channelInfo.type == ASIOSTFloat32MSB || channelInfo.type == ASIOSTFloat32LSB ) - info.nativeFormats |= RTAUDIO_FLOAT32; - else if ( channelInfo.type == ASIOSTFloat64MSB || channelInfo.type == ASIOSTFloat64LSB ) - info.nativeFormats |= RTAUDIO_FLOAT64; - else if ( channelInfo.type == ASIOSTInt24MSB || channelInfo.type == ASIOSTInt24LSB ) - info.nativeFormats |= RTAUDIO_SINT24; + info.nativeFormats = 0; + if (channelInfo.type == ASIOSTInt16MSB || channelInfo.type == ASIOSTInt16LSB) + info.nativeFormats |= RTAUDIO_SINT16; + else if (channelInfo.type == ASIOSTInt32MSB || channelInfo.type == ASIOSTInt32LSB) + info.nativeFormats |= RTAUDIO_SINT32; + else if (channelInfo.type == ASIOSTFloat32MSB || channelInfo.type == ASIOSTFloat32LSB) + info.nativeFormats |= RTAUDIO_FLOAT32; + else if (channelInfo.type == ASIOSTFloat64MSB || channelInfo.type == ASIOSTFloat64LSB) + info.nativeFormats |= RTAUDIO_FLOAT64; + else if (channelInfo.type == ASIOSTInt24MSB || channelInfo.type == ASIOSTInt24LSB) + info.nativeFormats |= RTAUDIO_SINT24; - if ( info.outputChannels > 0 ) - if ( getDefaultOutputDevice() == device ) info.isDefaultOutput = true; - if ( info.inputChannels > 0 ) - if ( getDefaultInputDevice() == device ) info.isDefaultInput = true; + if (info.outputChannels > 0) + if (getDefaultOutputDevice() == device) info.isDefaultOutput = true; + if (info.inputChannels > 0) + if (getDefaultInputDevice() == device) info.isDefaultInput = true; - info.probed = true; - drivers.removeCurrentDriver(); - return info; + info.probed = true; + drivers.removeCurrentDriver(); + return info; } -static void bufferSwitch( long index, ASIOBool /*processNow*/ ) +static void bufferSwitch(long index, ASIOBool /*processNow*/) { - RtApiAsio *object = (RtApiAsio *) asioCallbackInfo->object; - object->callbackEvent( index ); + RtApiAsio *object = (RtApiAsio *)asioCallbackInfo->object; + object->callbackEvent(index); } -void RtApiAsio :: saveDeviceInfo( void ) +void RtApiAsio ::saveDeviceInfo(void) { - devices_.clear(); + devices_.clear(); - unsigned int nDevices = getDeviceCount(); - devices_.resize( nDevices ); - for ( unsigned int i=0; isaveDeviceInfo(); + // Only load the driver once for duplex stream. + if (!isDuplexInput) + { + // The getDeviceInfo() function will not work when a stream is open + // because ASIO does not allow multiple devices to run at the same + // time. Thus, we'll probe the system before opening a stream and + // save the results for use by getDeviceInfo(). + this->saveDeviceInfo(); - if ( !drivers.loadDriver( driverName ) ) { - errorStream_ << "RtApiAsio::probeDeviceOpen: unable to load driver (" << driverName << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } + if (!drivers.loadDriver(driverName)) + { + errorStream_ << "RtApiAsio::probeDeviceOpen: unable to load driver (" << driverName << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } - result = ASIOInit( &driverInfo ); - if ( result != ASE_OK ) { - errorStream_ << "RtApiAsio::probeDeviceOpen: error (" << getAsioErrorString( result ) << ") initializing driver (" << driverName << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } - } + result = ASIOInit(&driverInfo); + if (result != ASE_OK) + { + errorStream_ << "RtApiAsio::probeDeviceOpen: error (" << getAsioErrorString(result) << ") initializing driver (" << driverName << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } + } - // keep them before any "goto error", they are used for error cleanup + goto device boundary checks - bool buffersAllocated = false; - AsioHandle *handle = (AsioHandle *) stream_.apiHandle; - unsigned int nChannels; + // keep them before any "goto error", they are used for error cleanup + goto device boundary checks + bool buffersAllocated = false; + AsioHandle *handle = (AsioHandle *)stream_.apiHandle; + unsigned int nChannels; + // Check the device channel count. + long inputChannels, outputChannels; + result = ASIOGetChannels(&inputChannels, &outputChannels); + if (result != ASE_OK) + { + errorStream_ << "RtApiAsio::probeDeviceOpen: error (" << getAsioErrorString(result) << ") getting channel count (" << driverName << ")."; + errorText_ = errorStream_.str(); + goto error; + } - // Check the device channel count. - long inputChannels, outputChannels; - result = ASIOGetChannels( &inputChannels, &outputChannels ); - if ( result != ASE_OK ) { - errorStream_ << "RtApiAsio::probeDeviceOpen: error (" << getAsioErrorString( result ) << ") getting channel count (" << driverName << ")."; - errorText_ = errorStream_.str(); - goto error; - } + if ((mode == OUTPUT && (channels + firstChannel) > (unsigned int)outputChannels) || + (mode == INPUT && (channels + firstChannel) > (unsigned int)inputChannels)) + { + errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested channel count (" << channels << ") + offset (" << firstChannel << ")."; + errorText_ = errorStream_.str(); + goto error; + } + stream_.nDeviceChannels[mode] = channels; + stream_.nUserChannels[mode] = channels; + stream_.channelOffset[mode] = firstChannel; - if ( ( mode == OUTPUT && (channels+firstChannel) > (unsigned int) outputChannels) || - ( mode == INPUT && (channels+firstChannel) > (unsigned int) inputChannels) ) { - errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested channel count (" << channels << ") + offset (" << firstChannel << ")."; - errorText_ = errorStream_.str(); - goto error; - } - stream_.nDeviceChannels[mode] = channels; - stream_.nUserChannels[mode] = channels; - stream_.channelOffset[mode] = firstChannel; + // Verify the sample rate is supported. + result = ASIOCanSampleRate((ASIOSampleRate)sampleRate); + if (result != ASE_OK) + { + errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested sample rate (" << sampleRate << ")."; + errorText_ = errorStream_.str(); + goto error; + } - // Verify the sample rate is supported. - result = ASIOCanSampleRate( (ASIOSampleRate) sampleRate ); - if ( result != ASE_OK ) { - errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") does not support requested sample rate (" << sampleRate << ")."; - errorText_ = errorStream_.str(); - goto error; - } + // Get the current sample rate + ASIOSampleRate currentRate; + result = ASIOGetSampleRate(¤tRate); + if (result != ASE_OK) + { + errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error getting sample rate."; + errorText_ = errorStream_.str(); + goto error; + } - // Get the current sample rate - ASIOSampleRate currentRate; - result = ASIOGetSampleRate( ¤tRate ); - if ( result != ASE_OK ) { - errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error getting sample rate."; - errorText_ = errorStream_.str(); - goto error; - } + // Set the sample rate only if necessary + if (currentRate != sampleRate) + { + result = ASIOSetSampleRate((ASIOSampleRate)sampleRate); + if (result != ASE_OK) + { + errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error setting sample rate (" << sampleRate << ")."; + errorText_ = errorStream_.str(); + goto error; + } + } - // Set the sample rate only if necessary - if ( currentRate != sampleRate ) { - result = ASIOSetSampleRate( (ASIOSampleRate) sampleRate ); - if ( result != ASE_OK ) { - errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error setting sample rate (" << sampleRate << ")."; - errorText_ = errorStream_.str(); - goto error; - } - } + // Determine the driver data type. + ASIOChannelInfo channelInfo; + channelInfo.channel = 0; + if (mode == OUTPUT) + channelInfo.isInput = false; + else + channelInfo.isInput = true; + result = ASIOGetChannelInfo(&channelInfo); + if (result != ASE_OK) + { + errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString(result) << ") getting data format."; + errorText_ = errorStream_.str(); + goto error; + } - // Determine the driver data type. - ASIOChannelInfo channelInfo; - channelInfo.channel = 0; - if ( mode == OUTPUT ) channelInfo.isInput = false; - else channelInfo.isInput = true; - result = ASIOGetChannelInfo( &channelInfo ); - if ( result != ASE_OK ) { - errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting data format."; - errorText_ = errorStream_.str(); - goto error; - } + // Assuming WINDOWS host is always little-endian. + stream_.doByteSwap[mode] = false; + stream_.userFormat = format; + stream_.deviceFormat[mode] = 0; + if (channelInfo.type == ASIOSTInt16MSB || channelInfo.type == ASIOSTInt16LSB) + { + stream_.deviceFormat[mode] = RTAUDIO_SINT16; + if (channelInfo.type == ASIOSTInt16MSB) stream_.doByteSwap[mode] = true; + } + else if (channelInfo.type == ASIOSTInt32MSB || channelInfo.type == ASIOSTInt32LSB) + { + stream_.deviceFormat[mode] = RTAUDIO_SINT32; + if (channelInfo.type == ASIOSTInt32MSB) stream_.doByteSwap[mode] = true; + } + else if (channelInfo.type == ASIOSTFloat32MSB || channelInfo.type == ASIOSTFloat32LSB) + { + stream_.deviceFormat[mode] = RTAUDIO_FLOAT32; + if (channelInfo.type == ASIOSTFloat32MSB) stream_.doByteSwap[mode] = true; + } + else if (channelInfo.type == ASIOSTFloat64MSB || channelInfo.type == ASIOSTFloat64LSB) + { + stream_.deviceFormat[mode] = RTAUDIO_FLOAT64; + if (channelInfo.type == ASIOSTFloat64MSB) stream_.doByteSwap[mode] = true; + } + else if (channelInfo.type == ASIOSTInt24MSB || channelInfo.type == ASIOSTInt24LSB) + { + stream_.deviceFormat[mode] = RTAUDIO_SINT24; + if (channelInfo.type == ASIOSTInt24MSB) stream_.doByteSwap[mode] = true; + } - // Assuming WINDOWS host is always little-endian. - stream_.doByteSwap[mode] = false; - stream_.userFormat = format; - stream_.deviceFormat[mode] = 0; - if ( channelInfo.type == ASIOSTInt16MSB || channelInfo.type == ASIOSTInt16LSB ) { - stream_.deviceFormat[mode] = RTAUDIO_SINT16; - if ( channelInfo.type == ASIOSTInt16MSB ) stream_.doByteSwap[mode] = true; - } - else if ( channelInfo.type == ASIOSTInt32MSB || channelInfo.type == ASIOSTInt32LSB ) { - stream_.deviceFormat[mode] = RTAUDIO_SINT32; - if ( channelInfo.type == ASIOSTInt32MSB ) stream_.doByteSwap[mode] = true; - } - else if ( channelInfo.type == ASIOSTFloat32MSB || channelInfo.type == ASIOSTFloat32LSB ) { - stream_.deviceFormat[mode] = RTAUDIO_FLOAT32; - if ( channelInfo.type == ASIOSTFloat32MSB ) stream_.doByteSwap[mode] = true; - } - else if ( channelInfo.type == ASIOSTFloat64MSB || channelInfo.type == ASIOSTFloat64LSB ) { - stream_.deviceFormat[mode] = RTAUDIO_FLOAT64; - if ( channelInfo.type == ASIOSTFloat64MSB ) stream_.doByteSwap[mode] = true; - } - else if ( channelInfo.type == ASIOSTInt24MSB || channelInfo.type == ASIOSTInt24LSB ) { - stream_.deviceFormat[mode] = RTAUDIO_SINT24; - if ( channelInfo.type == ASIOSTInt24MSB ) stream_.doByteSwap[mode] = true; - } + if (stream_.deviceFormat[mode] == 0) + { + errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") data format not supported by RtAudio."; + errorText_ = errorStream_.str(); + goto error; + } - if ( stream_.deviceFormat[mode] == 0 ) { - errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") data format not supported by RtAudio."; - errorText_ = errorStream_.str(); - goto error; - } + // Set the buffer size. For a duplex stream, this will end up + // setting the buffer size based on the input constraints, which + // should be ok. + long minSize, maxSize, preferSize, granularity; + result = ASIOGetBufferSize(&minSize, &maxSize, &preferSize, &granularity); + if (result != ASE_OK) + { + errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString(result) << ") getting buffer size."; + errorText_ = errorStream_.str(); + goto error; + } - // Set the buffer size. For a duplex stream, this will end up - // setting the buffer size based on the input constraints, which - // should be ok. - long minSize, maxSize, preferSize, granularity; - result = ASIOGetBufferSize( &minSize, &maxSize, &preferSize, &granularity ); - if ( result != ASE_OK ) { - errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting buffer size."; - errorText_ = errorStream_.str(); - goto error; - } + if (isDuplexInput) + { + // When this is the duplex input (output was opened before), then we have to use the same + // buffersize as the output, because it might use the preferred buffer size, which most + // likely wasn't passed as input to this. The buffer sizes have to be identically anyway, + // So instead of throwing an error, make them equal. The caller uses the reference + // to the "bufferSize" param as usual to set up processing buffers. - if ( isDuplexInput ) { - // When this is the duplex input (output was opened before), then we have to use the same - // buffersize as the output, because it might use the preferred buffer size, which most - // likely wasn't passed as input to this. The buffer sizes have to be identically anyway, - // So instead of throwing an error, make them equal. The caller uses the reference - // to the "bufferSize" param as usual to set up processing buffers. + *bufferSize = stream_.bufferSize; + } + else + { + if (*bufferSize == 0) + *bufferSize = preferSize; + else if (*bufferSize < (unsigned int)minSize) + *bufferSize = (unsigned int)minSize; + else if (*bufferSize > (unsigned int)maxSize) + *bufferSize = (unsigned int)maxSize; + else if (granularity == -1) + { + // Make sure bufferSize is a power of two. + int log2_of_min_size = 0; + int log2_of_max_size = 0; - *bufferSize = stream_.bufferSize; + for (unsigned int i = 0; i < sizeof(long) * 8; i++) + { + if (minSize & ((long)1 << i)) log2_of_min_size = i; + if (maxSize & ((long)1 << i)) log2_of_max_size = i; + } - } else { - if ( *bufferSize == 0 ) *bufferSize = preferSize; - else if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize; - else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize; - else if ( granularity == -1 ) { - // Make sure bufferSize is a power of two. - int log2_of_min_size = 0; - int log2_of_max_size = 0; + long min_delta = std::abs((long)*bufferSize - ((long)1 << log2_of_min_size)); + int min_delta_num = log2_of_min_size; - for ( unsigned int i = 0; i < sizeof(long) * 8; i++ ) { - if ( minSize & ((long)1 << i) ) log2_of_min_size = i; - if ( maxSize & ((long)1 << i) ) log2_of_max_size = i; - } + for (int i = log2_of_min_size + 1; i <= log2_of_max_size; i++) + { + long current_delta = std::abs((long)*bufferSize - ((long)1 << i)); + if (current_delta < min_delta) + { + min_delta = current_delta; + min_delta_num = i; + } + } - long min_delta = std::abs( (long)*bufferSize - ((long)1 << log2_of_min_size) ); - int min_delta_num = log2_of_min_size; + *bufferSize = ((unsigned int)1 << min_delta_num); + if (*bufferSize < (unsigned int)minSize) + *bufferSize = (unsigned int)minSize; + else if (*bufferSize > (unsigned int)maxSize) + *bufferSize = (unsigned int)maxSize; + } + else if (granularity != 0) + { + // Set to an even multiple of granularity, rounding up. + *bufferSize = (*bufferSize + granularity - 1) / granularity * granularity; + } + } - for (int i = log2_of_min_size + 1; i <= log2_of_max_size; i++) { - long current_delta = std::abs( (long)*bufferSize - ((long)1 << i) ); - if (current_delta < min_delta) { - min_delta = current_delta; - min_delta_num = i; - } - } - - *bufferSize = ( (unsigned int)1 << min_delta_num ); - if ( *bufferSize < (unsigned int) minSize ) *bufferSize = (unsigned int) minSize; - else if ( *bufferSize > (unsigned int) maxSize ) *bufferSize = (unsigned int) maxSize; - } - else if ( granularity != 0 ) { - // Set to an even multiple of granularity, rounding up. - *bufferSize = (*bufferSize + granularity-1) / granularity * granularity; - } - } - - /* + /* // we don't use it anymore, see above! // Just left it here for the case... if ( isDuplexInput && stream_.bufferSize != *bufferSize ) { @@ -3079,305 +3390,338 @@ bool RtApiAsio :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigne } */ - stream_.bufferSize = *bufferSize; - stream_.nBuffers = 2; + stream_.bufferSize = *bufferSize; + stream_.nBuffers = 2; - if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) stream_.userInterleaved = false; - else stream_.userInterleaved = true; + if (options && options->flags & RTAUDIO_NONINTERLEAVED) + stream_.userInterleaved = false; + else + stream_.userInterleaved = true; - // ASIO always uses non-interleaved buffers. - stream_.deviceInterleaved[mode] = false; + // ASIO always uses non-interleaved buffers. + stream_.deviceInterleaved[mode] = false; - // Allocate, if necessary, our AsioHandle structure for the stream. - if ( handle == 0 ) { - try { - handle = new AsioHandle; - } - catch ( std::bad_alloc& ) { - errorText_ = "RtApiAsio::probeDeviceOpen: error allocating AsioHandle memory."; - goto error; - } - handle->bufferInfos = 0; + // Allocate, if necessary, our AsioHandle structure for the stream. + if (handle == 0) + { + try + { + handle = new AsioHandle; + } + catch (std::bad_alloc &) + { + errorText_ = "RtApiAsio::probeDeviceOpen: error allocating AsioHandle memory."; + goto error; + } + handle->bufferInfos = 0; - // Create a manual-reset event. - handle->condition = CreateEvent( NULL, // no security - TRUE, // manual-reset - FALSE, // non-signaled initially - NULL ); // unnamed - stream_.apiHandle = (void *) handle; - } + // Create a manual-reset event. + handle->condition = CreateEvent(NULL, // no security + TRUE, // manual-reset + FALSE, // non-signaled initially + NULL); // unnamed + stream_.apiHandle = (void *)handle; + } - // Create the ASIO internal buffers. Since RtAudio sets up input - // and output separately, we'll have to dispose of previously - // created output buffers for a duplex stream. - if ( mode == INPUT && stream_.mode == OUTPUT ) { - ASIODisposeBuffers(); - if ( handle->bufferInfos ) free( handle->bufferInfos ); - } + // Create the ASIO internal buffers. Since RtAudio sets up input + // and output separately, we'll have to dispose of previously + // created output buffers for a duplex stream. + if (mode == INPUT && stream_.mode == OUTPUT) + { + ASIODisposeBuffers(); + if (handle->bufferInfos) free(handle->bufferInfos); + } - // Allocate, initialize, and save the bufferInfos in our stream callbackInfo structure. - unsigned int i; - nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1]; - handle->bufferInfos = (ASIOBufferInfo *) malloc( nChannels * sizeof(ASIOBufferInfo) ); - if ( handle->bufferInfos == NULL ) { - errorStream_ << "RtApiAsio::probeDeviceOpen: error allocating bufferInfo memory for driver (" << driverName << ")."; - errorText_ = errorStream_.str(); - goto error; - } + // Allocate, initialize, and save the bufferInfos in our stream callbackInfo structure. + unsigned int i; + nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1]; + handle->bufferInfos = (ASIOBufferInfo *)malloc(nChannels * sizeof(ASIOBufferInfo)); + if (handle->bufferInfos == NULL) + { + errorStream_ << "RtApiAsio::probeDeviceOpen: error allocating bufferInfo memory for driver (" << driverName << ")."; + errorText_ = errorStream_.str(); + goto error; + } - ASIOBufferInfo *infos; - infos = handle->bufferInfos; - for ( i=0; iisInput = ASIOFalse; - infos->channelNum = i + stream_.channelOffset[0]; - infos->buffers[0] = infos->buffers[1] = 0; - } - for ( i=0; iisInput = ASIOTrue; - infos->channelNum = i + stream_.channelOffset[1]; - infos->buffers[0] = infos->buffers[1] = 0; - } + ASIOBufferInfo *infos; + infos = handle->bufferInfos; + for (i = 0; i < stream_.nDeviceChannels[0]; i++, infos++) + { + infos->isInput = ASIOFalse; + infos->channelNum = i + stream_.channelOffset[0]; + infos->buffers[0] = infos->buffers[1] = 0; + } + for (i = 0; i < stream_.nDeviceChannels[1]; i++, infos++) + { + infos->isInput = ASIOTrue; + infos->channelNum = i + stream_.channelOffset[1]; + infos->buffers[0] = infos->buffers[1] = 0; + } - // prepare for callbacks - stream_.sampleRate = sampleRate; - stream_.device[mode] = device; - stream_.mode = isDuplexInput ? DUPLEX : mode; + // prepare for callbacks + stream_.sampleRate = sampleRate; + stream_.device[mode] = device; + stream_.mode = isDuplexInput ? DUPLEX : mode; - // store this class instance before registering callbacks, that are going to use it - asioCallbackInfo = &stream_.callbackInfo; - stream_.callbackInfo.object = (void *) this; + // store this class instance before registering callbacks, that are going to use it + asioCallbackInfo = &stream_.callbackInfo; + stream_.callbackInfo.object = (void *)this; - // Set up the ASIO callback structure and create the ASIO data buffers. - asioCallbacks.bufferSwitch = &bufferSwitch; - asioCallbacks.sampleRateDidChange = &sampleRateChanged; - asioCallbacks.asioMessage = &asioMessages; - asioCallbacks.bufferSwitchTimeInfo = NULL; - result = ASIOCreateBuffers( handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks ); - if ( result != ASE_OK ) { - // Standard method failed. This can happen with strict/misbehaving drivers that return valid buffer size ranges - // but only accept the preferred buffer size as parameter for ASIOCreateBuffers. eg. Creatives ASIO driver - // in that case, let's be naïve and try that instead - *bufferSize = preferSize; - stream_.bufferSize = *bufferSize; - result = ASIOCreateBuffers( handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks ); - } + // Set up the ASIO callback structure and create the ASIO data buffers. + asioCallbacks.bufferSwitch = &bufferSwitch; + asioCallbacks.sampleRateDidChange = &sampleRateChanged; + asioCallbacks.asioMessage = &asioMessages; + asioCallbacks.bufferSwitchTimeInfo = NULL; + result = ASIOCreateBuffers(handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks); + if (result != ASE_OK) + { + // Standard method failed. This can happen with strict/misbehaving drivers that return valid buffer size ranges + // but only accept the preferred buffer size as parameter for ASIOCreateBuffers. eg. Creatives ASIO driver + // in that case, let's be naïve and try that instead + *bufferSize = preferSize; + stream_.bufferSize = *bufferSize; + result = ASIOCreateBuffers(handle->bufferInfos, nChannels, stream_.bufferSize, &asioCallbacks); + } - if ( result != ASE_OK ) { - errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") creating buffers."; - errorText_ = errorStream_.str(); - goto error; - } - buffersAllocated = true; - stream_.state = STREAM_STOPPED; + if (result != ASE_OK) + { + errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString(result) << ") creating buffers."; + errorText_ = errorStream_.str(); + goto error; + } + buffersAllocated = true; + stream_.state = STREAM_STOPPED; - // Set flags for buffer conversion. - stream_.doConvertBuffer[mode] = false; - if ( stream_.userFormat != stream_.deviceFormat[mode] ) - stream_.doConvertBuffer[mode] = true; - if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] && - stream_.nUserChannels[mode] > 1 ) - stream_.doConvertBuffer[mode] = true; + // Set flags for buffer conversion. + stream_.doConvertBuffer[mode] = false; + if (stream_.userFormat != stream_.deviceFormat[mode]) + stream_.doConvertBuffer[mode] = true; + if (stream_.userInterleaved != stream_.deviceInterleaved[mode] && + stream_.nUserChannels[mode] > 1) + stream_.doConvertBuffer[mode] = true; - // Allocate necessary internal buffers - unsigned long bufferBytes; - bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat ); - stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 ); - if ( stream_.userBuffer[mode] == NULL ) { - errorText_ = "RtApiAsio::probeDeviceOpen: error allocating user buffer memory."; - goto error; - } + // Allocate necessary internal buffers + unsigned long bufferBytes; + bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes(stream_.userFormat); + stream_.userBuffer[mode] = (char *)calloc(bufferBytes, 1); + if (stream_.userBuffer[mode] == NULL) + { + errorText_ = "RtApiAsio::probeDeviceOpen: error allocating user buffer memory."; + goto error; + } - if ( stream_.doConvertBuffer[mode] ) { + if (stream_.doConvertBuffer[mode]) + { + bool makeBuffer = true; + bufferBytes = stream_.nDeviceChannels[mode] * formatBytes(stream_.deviceFormat[mode]); + if (isDuplexInput && stream_.deviceBuffer) + { + unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes(stream_.deviceFormat[0]); + if (bufferBytes <= bytesOut) makeBuffer = false; + } - bool makeBuffer = true; - bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] ); - if ( isDuplexInput && stream_.deviceBuffer ) { - unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] ); - if ( bufferBytes <= bytesOut ) makeBuffer = false; - } + if (makeBuffer) + { + bufferBytes *= *bufferSize; + if (stream_.deviceBuffer) free(stream_.deviceBuffer); + stream_.deviceBuffer = (char *)calloc(bufferBytes, 1); + if (stream_.deviceBuffer == NULL) + { + errorText_ = "RtApiAsio::probeDeviceOpen: error allocating device buffer memory."; + goto error; + } + } + } - if ( makeBuffer ) { - bufferBytes *= *bufferSize; - if ( stream_.deviceBuffer ) free( stream_.deviceBuffer ); - stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 ); - if ( stream_.deviceBuffer == NULL ) { - errorText_ = "RtApiAsio::probeDeviceOpen: error allocating device buffer memory."; - goto error; - } - } - } + // Determine device latencies + long inputLatency, outputLatency; + result = ASIOGetLatencies(&inputLatency, &outputLatency); + if (result != ASE_OK) + { + errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString(result) << ") getting latency."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); // warn but don't fail + } + else + { + stream_.latency[0] = outputLatency; + stream_.latency[1] = inputLatency; + } - // Determine device latencies - long inputLatency, outputLatency; - result = ASIOGetLatencies( &inputLatency, &outputLatency ); - if ( result != ASE_OK ) { - errorStream_ << "RtApiAsio::probeDeviceOpen: driver (" << driverName << ") error (" << getAsioErrorString( result ) << ") getting latency."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING); // warn but don't fail - } - else { - stream_.latency[0] = outputLatency; - stream_.latency[1] = inputLatency; - } + // Setup the buffer conversion information structure. We don't use + // buffers to do channel offsets, so we override that parameter + // here. + if (stream_.doConvertBuffer[mode]) setConvertInfo(mode, 0); - // Setup the buffer conversion information structure. We don't use - // buffers to do channel offsets, so we override that parameter - // here. - if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, 0 ); + return SUCCESS; - return SUCCESS; +error: + if (!isDuplexInput) + { + // the cleanup for error in the duplex input, is done by RtApi::openStream + // So we clean up for single channel only - error: - if ( !isDuplexInput ) { - // the cleanup for error in the duplex input, is done by RtApi::openStream - // So we clean up for single channel only + if (buffersAllocated) + ASIODisposeBuffers(); - if ( buffersAllocated ) - ASIODisposeBuffers(); + drivers.removeCurrentDriver(); - drivers.removeCurrentDriver(); + if (handle) + { + CloseHandle(handle->condition); + if (handle->bufferInfos) + free(handle->bufferInfos); - if ( handle ) { - CloseHandle( handle->condition ); - if ( handle->bufferInfos ) - free( handle->bufferInfos ); + delete handle; + stream_.apiHandle = 0; + } - delete handle; - stream_.apiHandle = 0; - } + if (stream_.userBuffer[mode]) + { + free(stream_.userBuffer[mode]); + stream_.userBuffer[mode] = 0; + } + if (stream_.deviceBuffer) + { + free(stream_.deviceBuffer); + stream_.deviceBuffer = 0; + } + } - if ( stream_.userBuffer[mode] ) { - free( stream_.userBuffer[mode] ); - stream_.userBuffer[mode] = 0; - } + return FAILURE; +} //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - if ( stream_.deviceBuffer ) { - free( stream_.deviceBuffer ); - stream_.deviceBuffer = 0; - } - } - - return FAILURE; -}//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void RtApiAsio :: closeStream() +void RtApiAsio ::closeStream() { - if ( stream_.state == STREAM_CLOSED ) { - errorText_ = "RtApiAsio::closeStream(): no open stream to close!"; - error( RtAudioError::WARNING ); - return; - } + if (stream_.state == STREAM_CLOSED) + { + errorText_ = "RtApiAsio::closeStream(): no open stream to close!"; + error(RtAudioError::WARNING); + return; + } - if ( stream_.state == STREAM_RUNNING ) { - stream_.state = STREAM_STOPPED; - ASIOStop(); - } - ASIODisposeBuffers(); - drivers.removeCurrentDriver(); + if (stream_.state == STREAM_RUNNING) + { + stream_.state = STREAM_STOPPED; + ASIOStop(); + } + ASIODisposeBuffers(); + drivers.removeCurrentDriver(); - AsioHandle *handle = (AsioHandle *) stream_.apiHandle; - if ( handle ) { - CloseHandle( handle->condition ); - if ( handle->bufferInfos ) - free( handle->bufferInfos ); - delete handle; - stream_.apiHandle = 0; - } + AsioHandle *handle = (AsioHandle *)stream_.apiHandle; + if (handle) + { + CloseHandle(handle->condition); + if (handle->bufferInfos) + free(handle->bufferInfos); + delete handle; + stream_.apiHandle = 0; + } - for ( int i=0; i<2; i++ ) { - if ( stream_.userBuffer[i] ) { - free( stream_.userBuffer[i] ); - stream_.userBuffer[i] = 0; - } - } + for (int i = 0; i < 2; i++) + { + if (stream_.userBuffer[i]) + { + free(stream_.userBuffer[i]); + stream_.userBuffer[i] = 0; + } + } - if ( stream_.deviceBuffer ) { - free( stream_.deviceBuffer ); - stream_.deviceBuffer = 0; - } + if (stream_.deviceBuffer) + { + free(stream_.deviceBuffer); + stream_.deviceBuffer = 0; + } - stream_.mode = UNINITIALIZED; - stream_.state = STREAM_CLOSED; + stream_.mode = UNINITIALIZED; + stream_.state = STREAM_CLOSED; } bool stopThreadCalled = false; -void RtApiAsio :: startStream() +void RtApiAsio ::startStream() { - verifyStream(); - if ( stream_.state == STREAM_RUNNING ) { - errorText_ = "RtApiAsio::startStream(): the stream is already running!"; - error( RtAudioError::WARNING ); - return; - } + verifyStream(); + if (stream_.state == STREAM_RUNNING) + { + errorText_ = "RtApiAsio::startStream(): the stream is already running!"; + error(RtAudioError::WARNING); + return; + } - AsioHandle *handle = (AsioHandle *) stream_.apiHandle; - ASIOError result = ASIOStart(); - if ( result != ASE_OK ) { - errorStream_ << "RtApiAsio::startStream: error (" << getAsioErrorString( result ) << ") starting device."; - errorText_ = errorStream_.str(); - goto unlock; - } + AsioHandle *handle = (AsioHandle *)stream_.apiHandle; + ASIOError result = ASIOStart(); + if (result != ASE_OK) + { + errorStream_ << "RtApiAsio::startStream: error (" << getAsioErrorString(result) << ") starting device."; + errorText_ = errorStream_.str(); + goto unlock; + } - handle->drainCounter = 0; - handle->internalDrain = false; - ResetEvent( handle->condition ); - stream_.state = STREAM_RUNNING; - asioXRun = false; + handle->drainCounter = 0; + handle->internalDrain = false; + ResetEvent(handle->condition); + stream_.state = STREAM_RUNNING; + asioXRun = false; - unlock: - stopThreadCalled = false; +unlock: + stopThreadCalled = false; - if ( result == ASE_OK ) return; - error( RtAudioError::SYSTEM_ERROR ); + if (result == ASE_OK) return; + error(RtAudioError::SYSTEM_ERROR); } -void RtApiAsio :: stopStream() +void RtApiAsio ::stopStream() { - verifyStream(); - if ( stream_.state == STREAM_STOPPED ) { - errorText_ = "RtApiAsio::stopStream(): the stream is already stopped!"; - error( RtAudioError::WARNING ); - return; - } + verifyStream(); + if (stream_.state == STREAM_STOPPED) + { + errorText_ = "RtApiAsio::stopStream(): the stream is already stopped!"; + error(RtAudioError::WARNING); + return; + } - AsioHandle *handle = (AsioHandle *) stream_.apiHandle; - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { - if ( handle->drainCounter == 0 ) { - handle->drainCounter = 2; - WaitForSingleObject( handle->condition, INFINITE ); // block until signaled - } - } + AsioHandle *handle = (AsioHandle *)stream_.apiHandle; + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + { + if (handle->drainCounter == 0) + { + handle->drainCounter = 2; + WaitForSingleObject(handle->condition, INFINITE); // block until signaled + } + } - stream_.state = STREAM_STOPPED; + stream_.state = STREAM_STOPPED; - ASIOError result = ASIOStop(); - if ( result != ASE_OK ) { - errorStream_ << "RtApiAsio::stopStream: error (" << getAsioErrorString( result ) << ") stopping device."; - errorText_ = errorStream_.str(); - } + ASIOError result = ASIOStop(); + if (result != ASE_OK) + { + errorStream_ << "RtApiAsio::stopStream: error (" << getAsioErrorString(result) << ") stopping device."; + errorText_ = errorStream_.str(); + } - if ( result == ASE_OK ) return; - error( RtAudioError::SYSTEM_ERROR ); + if (result == ASE_OK) return; + error(RtAudioError::SYSTEM_ERROR); } -void RtApiAsio :: abortStream() +void RtApiAsio ::abortStream() { - verifyStream(); - if ( stream_.state == STREAM_STOPPED ) { - errorText_ = "RtApiAsio::abortStream(): the stream is already stopped!"; - error( RtAudioError::WARNING ); - return; - } + verifyStream(); + if (stream_.state == STREAM_STOPPED) + { + errorText_ = "RtApiAsio::abortStream(): the stream is already stopped!"; + error(RtAudioError::WARNING); + return; + } - // The following lines were commented-out because some behavior was - // noted where the device buffers need to be zeroed to avoid - // continuing sound, even when the device buffers are completely - // disposed. So now, calling abort is the same as calling stop. - // AsioHandle *handle = (AsioHandle *) stream_.apiHandle; - // handle->drainCounter = 2; - stopStream(); + // The following lines were commented-out because some behavior was + // noted where the device buffers need to be zeroed to avoid + // continuing sound, even when the device buffers are completely + // disposed. So now, calling abort is the same as calling stop. + // AsioHandle *handle = (AsioHandle *) stream_.apiHandle; + // handle->drainCounter = 2; + stopStream(); } // This function will be called by a spawned thread when the user @@ -3385,290 +3729,300 @@ void RtApiAsio :: abortStream() // aborted. It is necessary to handle it this way because the // callbackEvent() function must return before the ASIOStop() // function will return. -static unsigned __stdcall asioStopStream( void *ptr ) +static unsigned __stdcall asioStopStream(void *ptr) { - CallbackInfo *info = (CallbackInfo *) ptr; - RtApiAsio *object = (RtApiAsio *) info->object; + CallbackInfo *info = (CallbackInfo *)ptr; + RtApiAsio *object = (RtApiAsio *)info->object; - object->stopStream(); - _endthreadex( 0 ); - return 0; + object->stopStream(); + _endthreadex(0); + return 0; } -bool RtApiAsio :: callbackEvent( long bufferIndex ) +bool RtApiAsio ::callbackEvent(long bufferIndex) { - if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) return SUCCESS; - if ( stream_.state == STREAM_CLOSED ) { - errorText_ = "RtApiAsio::callbackEvent(): the stream is closed ... this shouldn't happen!"; - error( RtAudioError::WARNING ); - return FAILURE; - } + if (stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING) return SUCCESS; + if (stream_.state == STREAM_CLOSED) + { + errorText_ = "RtApiAsio::callbackEvent(): the stream is closed ... this shouldn't happen!"; + error(RtAudioError::WARNING); + return FAILURE; + } - CallbackInfo *info = (CallbackInfo *) &stream_.callbackInfo; - AsioHandle *handle = (AsioHandle *) stream_.apiHandle; + CallbackInfo *info = (CallbackInfo *)&stream_.callbackInfo; + AsioHandle *handle = (AsioHandle *)stream_.apiHandle; - // Check if we were draining the stream and signal if finished. - if ( handle->drainCounter > 3 ) { + // Check if we were draining the stream and signal if finished. + if (handle->drainCounter > 3) + { + stream_.state = STREAM_STOPPING; + if (handle->internalDrain == false) + SetEvent(handle->condition); + else + { // spawn a thread to stop the stream + unsigned threadId; + stream_.callbackInfo.thread = _beginthreadex(NULL, 0, &asioStopStream, + &stream_.callbackInfo, 0, &threadId); + } + return SUCCESS; + } - stream_.state = STREAM_STOPPING; - if ( handle->internalDrain == false ) - SetEvent( handle->condition ); - else { // spawn a thread to stop the stream - unsigned threadId; - stream_.callbackInfo.thread = _beginthreadex( NULL, 0, &asioStopStream, - &stream_.callbackInfo, 0, &threadId ); - } - return SUCCESS; - } + // Invoke user callback to get fresh output data UNLESS we are + // draining stream. + if (handle->drainCounter == 0) + { + RtAudioCallback callback = (RtAudioCallback)info->callback; + double streamTime = getStreamTime(); + RtAudioStreamStatus status = 0; + if (stream_.mode != INPUT && asioXRun == true) + { + status |= RTAUDIO_OUTPUT_UNDERFLOW; + asioXRun = false; + } + if (stream_.mode != OUTPUT && asioXRun == true) + { + status |= RTAUDIO_INPUT_OVERFLOW; + asioXRun = false; + } + int cbReturnValue = callback(stream_.userBuffer[0], stream_.userBuffer[1], + stream_.bufferSize, streamTime, status, info->userData); + if (cbReturnValue == 2) + { + stream_.state = STREAM_STOPPING; + handle->drainCounter = 2; + unsigned threadId; + stream_.callbackInfo.thread = _beginthreadex(NULL, 0, &asioStopStream, + &stream_.callbackInfo, 0, &threadId); + return SUCCESS; + } + else if (cbReturnValue == 1) + { + handle->drainCounter = 1; + handle->internalDrain = true; + } + } - // Invoke user callback to get fresh output data UNLESS we are - // draining stream. - if ( handle->drainCounter == 0 ) { - RtAudioCallback callback = (RtAudioCallback) info->callback; - double streamTime = getStreamTime(); - RtAudioStreamStatus status = 0; - if ( stream_.mode != INPUT && asioXRun == true ) { - status |= RTAUDIO_OUTPUT_UNDERFLOW; - asioXRun = false; - } - if ( stream_.mode != OUTPUT && asioXRun == true ) { - status |= RTAUDIO_INPUT_OVERFLOW; - asioXRun = false; - } - int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1], - stream_.bufferSize, streamTime, status, info->userData ); - if ( cbReturnValue == 2 ) { - stream_.state = STREAM_STOPPING; - handle->drainCounter = 2; - unsigned threadId; - stream_.callbackInfo.thread = _beginthreadex( NULL, 0, &asioStopStream, - &stream_.callbackInfo, 0, &threadId ); - return SUCCESS; - } - else if ( cbReturnValue == 1 ) { - handle->drainCounter = 1; - handle->internalDrain = true; - } - } + unsigned int nChannels, bufferBytes, i, j; + nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1]; + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + { + bufferBytes = stream_.bufferSize * formatBytes(stream_.deviceFormat[0]); - unsigned int nChannels, bufferBytes, i, j; - nChannels = stream_.nDeviceChannels[0] + stream_.nDeviceChannels[1]; - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { + if (handle->drainCounter > 1) + { // write zeros to the output stream - bufferBytes = stream_.bufferSize * formatBytes( stream_.deviceFormat[0] ); + for (i = 0, j = 0; i < nChannels; i++) + { + if (handle->bufferInfos[i].isInput != ASIOTrue) + memset(handle->bufferInfos[i].buffers[bufferIndex], 0, bufferBytes); + } + } + else if (stream_.doConvertBuffer[0]) + { + convertBuffer(stream_.deviceBuffer, stream_.userBuffer[0], stream_.convertInfo[0]); + if (stream_.doByteSwap[0]) + byteSwapBuffer(stream_.deviceBuffer, + stream_.bufferSize * stream_.nDeviceChannels[0], + stream_.deviceFormat[0]); - if ( handle->drainCounter > 1 ) { // write zeros to the output stream + for (i = 0, j = 0; i < nChannels; i++) + { + if (handle->bufferInfos[i].isInput != ASIOTrue) + memcpy(handle->bufferInfos[i].buffers[bufferIndex], + &stream_.deviceBuffer[j++ * bufferBytes], bufferBytes); + } + } + else + { + if (stream_.doByteSwap[0]) + byteSwapBuffer(stream_.userBuffer[0], + stream_.bufferSize * stream_.nUserChannels[0], + stream_.userFormat); - for ( i=0, j=0; ibufferInfos[i].isInput != ASIOTrue ) - memset( handle->bufferInfos[i].buffers[bufferIndex], 0, bufferBytes ); - } + for (i = 0, j = 0; i < nChannels; i++) + { + if (handle->bufferInfos[i].isInput != ASIOTrue) + memcpy(handle->bufferInfos[i].buffers[bufferIndex], + &stream_.userBuffer[0][bufferBytes * j++], bufferBytes); + } + } + } - } - else if ( stream_.doConvertBuffer[0] ) { + // Don't bother draining input + if (handle->drainCounter) + { + handle->drainCounter++; + goto unlock; + } - convertBuffer( stream_.deviceBuffer, stream_.userBuffer[0], stream_.convertInfo[0] ); - if ( stream_.doByteSwap[0] ) - byteSwapBuffer( stream_.deviceBuffer, - stream_.bufferSize * stream_.nDeviceChannels[0], - stream_.deviceFormat[0] ); + if (stream_.mode == INPUT || stream_.mode == DUPLEX) + { + bufferBytes = stream_.bufferSize * formatBytes(stream_.deviceFormat[1]); - for ( i=0, j=0; ibufferInfos[i].isInput != ASIOTrue ) - memcpy( handle->bufferInfos[i].buffers[bufferIndex], - &stream_.deviceBuffer[j++*bufferBytes], bufferBytes ); - } + if (stream_.doConvertBuffer[1]) + { + // Always interleave ASIO input data. + for (i = 0, j = 0; i < nChannels; i++) + { + if (handle->bufferInfos[i].isInput == ASIOTrue) + memcpy(&stream_.deviceBuffer[j++ * bufferBytes], + handle->bufferInfos[i].buffers[bufferIndex], + bufferBytes); + } - } - else { + if (stream_.doByteSwap[1]) + byteSwapBuffer(stream_.deviceBuffer, + stream_.bufferSize * stream_.nDeviceChannels[1], + stream_.deviceFormat[1]); + convertBuffer(stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1]); + } + else + { + for (i = 0, j = 0; i < nChannels; i++) + { + if (handle->bufferInfos[i].isInput == ASIOTrue) + { + memcpy(&stream_.userBuffer[1][bufferBytes * j++], + handle->bufferInfos[i].buffers[bufferIndex], + bufferBytes); + } + } - if ( stream_.doByteSwap[0] ) - byteSwapBuffer( stream_.userBuffer[0], - stream_.bufferSize * stream_.nUserChannels[0], - stream_.userFormat ); + if (stream_.doByteSwap[1]) + byteSwapBuffer(stream_.userBuffer[1], + stream_.bufferSize * stream_.nUserChannels[1], + stream_.userFormat); + } + } - for ( i=0, j=0; ibufferInfos[i].isInput != ASIOTrue ) - memcpy( handle->bufferInfos[i].buffers[bufferIndex], - &stream_.userBuffer[0][bufferBytes*j++], bufferBytes ); - } +unlock: + // The following call was suggested by Malte Clasen. While the API + // documentation indicates it should not be required, some device + // drivers apparently do not function correctly without it. + ASIOOutputReady(); - } - } - - // Don't bother draining input - if ( handle->drainCounter ) { - handle->drainCounter++; - goto unlock; - } - - if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) { - - bufferBytes = stream_.bufferSize * formatBytes(stream_.deviceFormat[1]); - - if (stream_.doConvertBuffer[1]) { - - // Always interleave ASIO input data. - for ( i=0, j=0; ibufferInfos[i].isInput == ASIOTrue ) - memcpy( &stream_.deviceBuffer[j++*bufferBytes], - handle->bufferInfos[i].buffers[bufferIndex], - bufferBytes ); - } - - if ( stream_.doByteSwap[1] ) - byteSwapBuffer( stream_.deviceBuffer, - stream_.bufferSize * stream_.nDeviceChannels[1], - stream_.deviceFormat[1] ); - convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] ); - - } - else { - for ( i=0, j=0; ibufferInfos[i].isInput == ASIOTrue ) { - memcpy( &stream_.userBuffer[1][bufferBytes*j++], - handle->bufferInfos[i].buffers[bufferIndex], - bufferBytes ); - } - } - - if ( stream_.doByteSwap[1] ) - byteSwapBuffer( stream_.userBuffer[1], - stream_.bufferSize * stream_.nUserChannels[1], - stream_.userFormat ); - } - } - - unlock: - // The following call was suggested by Malte Clasen. While the API - // documentation indicates it should not be required, some device - // drivers apparently do not function correctly without it. - ASIOOutputReady(); - - RtApi::tickStreamTime(); - return SUCCESS; + RtApi::tickStreamTime(); + return SUCCESS; } -static void sampleRateChanged( ASIOSampleRate sRate ) +static void sampleRateChanged(ASIOSampleRate sRate) { - // The ASIO documentation says that this usually only happens during - // external sync. Audio processing is not stopped by the driver, - // actual sample rate might not have even changed, maybe only the - // sample rate status of an AES/EBU or S/PDIF digital input at the - // audio device. + // The ASIO documentation says that this usually only happens during + // external sync. Audio processing is not stopped by the driver, + // actual sample rate might not have even changed, maybe only the + // sample rate status of an AES/EBU or S/PDIF digital input at the + // audio device. - RtApi *object = (RtApi *) asioCallbackInfo->object; - try { - object->stopStream(); - } - catch ( RtAudioError &exception ) { - std::cerr << "\nRtApiAsio: sampleRateChanged() error (" << exception.getMessage() << ")!\n" << std::endl; - return; - } + RtApi *object = (RtApi *)asioCallbackInfo->object; + try + { + object->stopStream(); + } + catch (RtAudioError &exception) + { + std::cerr << "\nRtApiAsio: sampleRateChanged() error (" << exception.getMessage() << ")!\n" + << std::endl; + return; + } - std::cerr << "\nRtApiAsio: driver reports sample rate changed to " << sRate << " ... stream stopped!!!\n" << std::endl; + std::cerr << "\nRtApiAsio: driver reports sample rate changed to " << sRate << " ... stream stopped!!!\n" + << std::endl; } -static long asioMessages( long selector, long value, void* /*message*/, double* /*opt*/ ) +static long asioMessages(long selector, long value, void * /*message*/, double * /*opt*/) { - long ret = 0; + long ret = 0; - switch( selector ) { - case kAsioSelectorSupported: - if ( value == kAsioResetRequest - || value == kAsioEngineVersion - || value == kAsioResyncRequest - || value == kAsioLatenciesChanged - // The following three were added for ASIO 2.0, you don't - // necessarily have to support them. - || value == kAsioSupportsTimeInfo - || value == kAsioSupportsTimeCode - || value == kAsioSupportsInputMonitor) - ret = 1L; - break; - case kAsioResetRequest: - // Defer the task and perform the reset of the driver during the - // next "safe" situation. You cannot reset the driver right now, - // as this code is called from the driver. Reset the driver is - // done by completely destruct is. I.e. ASIOStop(), - // ASIODisposeBuffers(), Destruction Afterwards you initialize the - // driver again. - std::cerr << "\nRtApiAsio: driver reset requested!!!" << std::endl; - ret = 1L; - break; - case kAsioResyncRequest: - // This informs the application that the driver encountered some - // non-fatal data loss. It is used for synchronization purposes - // of different media. Added mainly to work around the Win16Mutex - // problems in Windows 95/98 with the Windows Multimedia system, - // which could lose data because the Mutex was held too long by - // another thread. However a driver can issue it in other - // situations, too. - // std::cerr << "\nRtApiAsio: driver resync requested!!!" << std::endl; - asioXRun = true; - ret = 1L; - break; - case kAsioLatenciesChanged: - // This will inform the host application that the drivers were - // latencies changed. Beware, it this does not mean that the - // buffer sizes have changed! You might need to update internal - // delay data. - std::cerr << "\nRtApiAsio: driver latency may have changed!!!" << std::endl; - ret = 1L; - break; - case kAsioEngineVersion: - // Return the supported ASIO version of the host application. If - // a host application does not implement this selector, ASIO 1.0 - // is assumed by the driver. - ret = 2L; - break; - case kAsioSupportsTimeInfo: - // Informs the driver whether the - // asioCallbacks.bufferSwitchTimeInfo() callback is supported. - // For compatibility with ASIO 1.0 drivers the host application - // should always support the "old" bufferSwitch method, too. - ret = 0; - break; - case kAsioSupportsTimeCode: - // Informs the driver whether application is interested in time - // code info. If an application does not need to know about time - // code, the driver has less work to do. - ret = 0; - break; - } - return ret; + switch (selector) + { + case kAsioSelectorSupported: + if (value == kAsioResetRequest || value == kAsioEngineVersion || value == kAsioResyncRequest || value == kAsioLatenciesChanged + // The following three were added for ASIO 2.0, you don't + // necessarily have to support them. + || value == kAsioSupportsTimeInfo || value == kAsioSupportsTimeCode || value == kAsioSupportsInputMonitor) + ret = 1L; + break; + case kAsioResetRequest: + // Defer the task and perform the reset of the driver during the + // next "safe" situation. You cannot reset the driver right now, + // as this code is called from the driver. Reset the driver is + // done by completely destruct is. I.e. ASIOStop(), + // ASIODisposeBuffers(), Destruction Afterwards you initialize the + // driver again. + std::cerr << "\nRtApiAsio: driver reset requested!!!" << std::endl; + ret = 1L; + break; + case kAsioResyncRequest: + // This informs the application that the driver encountered some + // non-fatal data loss. It is used for synchronization purposes + // of different media. Added mainly to work around the Win16Mutex + // problems in Windows 95/98 with the Windows Multimedia system, + // which could lose data because the Mutex was held too long by + // another thread. However a driver can issue it in other + // situations, too. + // std::cerr << "\nRtApiAsio: driver resync requested!!!" << std::endl; + asioXRun = true; + ret = 1L; + break; + case kAsioLatenciesChanged: + // This will inform the host application that the drivers were + // latencies changed. Beware, it this does not mean that the + // buffer sizes have changed! You might need to update internal + // delay data. + std::cerr << "\nRtApiAsio: driver latency may have changed!!!" << std::endl; + ret = 1L; + break; + case kAsioEngineVersion: + // Return the supported ASIO version of the host application. If + // a host application does not implement this selector, ASIO 1.0 + // is assumed by the driver. + ret = 2L; + break; + case kAsioSupportsTimeInfo: + // Informs the driver whether the + // asioCallbacks.bufferSwitchTimeInfo() callback is supported. + // For compatibility with ASIO 1.0 drivers the host application + // should always support the "old" bufferSwitch method, too. + ret = 0; + break; + case kAsioSupportsTimeCode: + // Informs the driver whether application is interested in time + // code info. If an application does not need to know about time + // code, the driver has less work to do. + ret = 0; + break; + } + return ret; } -static const char* getAsioErrorString( ASIOError result ) +static const char *getAsioErrorString(ASIOError result) { - struct Messages - { - ASIOError value; - const char*message; - }; + struct Messages + { + ASIOError value; + const char *message; + }; - static const Messages m[] = - { - { ASE_NotPresent, "Hardware input or output is not present or available." }, - { ASE_HWMalfunction, "Hardware is malfunctioning." }, - { ASE_InvalidParameter, "Invalid input parameter." }, - { ASE_InvalidMode, "Invalid mode." }, - { ASE_SPNotAdvancing, "Sample position not advancing." }, - { ASE_NoClock, "Sample clock or rate cannot be determined or is not present." }, - { ASE_NoMemory, "Not enough memory to complete the request." } - }; + static const Messages m[] = + { + {ASE_NotPresent, "Hardware input or output is not present or available."}, + {ASE_HWMalfunction, "Hardware is malfunctioning."}, + {ASE_InvalidParameter, "Invalid input parameter."}, + {ASE_InvalidMode, "Invalid mode."}, + {ASE_SPNotAdvancing, "Sample position not advancing."}, + {ASE_NoClock, "Sample clock or rate cannot be determined or is not present."}, + {ASE_NoMemory, "Not enough memory to complete the request."}}; - for ( unsigned int i = 0; i < sizeof(m)/sizeof(m[0]); ++i ) - if ( m[i].value == result ) return m[i].message; + for (unsigned int i = 0; i < sizeof(m) / sizeof(m[0]); ++i) + if (m[i].value == result) return m[i].message; - return "Unknown error."; + return "Unknown error."; } //******************** End of __WINDOWS_ASIO__ *********************// #endif - -#if defined(__WINDOWS_WASAPI__) // Windows WASAPI API +#if defined(__WINDOWS_WASAPI__) // Windows WASAPI API // Authored by Marcus Tomlinson , April 2014 // - Introduces support for the Windows WASAPI API @@ -3677,7 +4031,7 @@ static const char* getAsioErrorString( ASIOError result ) // - Includes automatic internal conversion of sample rate and buffer size between hardware and the user #ifndef INITGUID - #define INITGUID +#define INITGUID #endif #include #include @@ -3686,14 +4040,14 @@ static const char* getAsioErrorString( ASIOError result ) //============================================================================= -#define SAFE_RELEASE( objectPtr )\ -if ( objectPtr )\ -{\ - objectPtr->Release();\ - objectPtr = NULL;\ -} +#define SAFE_RELEASE(objectPtr) \ + if (objectPtr) \ + { \ + objectPtr->Release(); \ + objectPtr = NULL; \ + } -typedef HANDLE ( __stdcall *TAvSetMmThreadCharacteristicsPtr )( LPCWSTR TaskName, LPDWORD TaskIndex ); +typedef HANDLE(__stdcall *TAvSetMmThreadCharacteristicsPtr)(LPCWSTR TaskName, LPDWORD TaskIndex); //----------------------------------------------------------------------------- @@ -3704,154 +4058,160 @@ typedef HANDLE ( __stdcall *TAvSetMmThreadCharacteristicsPtr )( LPCWSTR TaskName class WasapiBuffer { public: - WasapiBuffer() - : buffer_( NULL ), - bufferSize_( 0 ), - inIndex_( 0 ), - outIndex_( 0 ) {} + WasapiBuffer() + : buffer_(NULL), + bufferSize_(0), + inIndex_(0), + outIndex_(0) {} - ~WasapiBuffer() { - free( buffer_ ); - } + ~WasapiBuffer() + { + free(buffer_); + } - // sets the length of the internal ring buffer - void setBufferSize( unsigned int bufferSize, unsigned int formatBytes ) { - free( buffer_ ); + // sets the length of the internal ring buffer + void setBufferSize(unsigned int bufferSize, unsigned int formatBytes) + { + free(buffer_); - buffer_ = ( char* ) calloc( bufferSize, formatBytes ); + buffer_ = (char *)calloc(bufferSize, formatBytes); - bufferSize_ = bufferSize; - inIndex_ = 0; - outIndex_ = 0; - } + bufferSize_ = bufferSize; + inIndex_ = 0; + outIndex_ = 0; + } - // attempt to push a buffer into the ring buffer at the current "in" index - bool pushBuffer( char* buffer, unsigned int bufferSize, RtAudioFormat format ) - { - if ( !buffer || // incoming buffer is NULL - bufferSize == 0 || // incoming buffer has no data - bufferSize > bufferSize_ ) // incoming buffer too large - { - return false; - } + // attempt to push a buffer into the ring buffer at the current "in" index + bool pushBuffer(char *buffer, unsigned int bufferSize, RtAudioFormat format) + { + if (!buffer || // incoming buffer is NULL + bufferSize == 0 || // incoming buffer has no data + bufferSize > bufferSize_) // incoming buffer too large + { + return false; + } - unsigned int relOutIndex = outIndex_; - unsigned int inIndexEnd = inIndex_ + bufferSize; - if ( relOutIndex < inIndex_ && inIndexEnd >= bufferSize_ ) { - relOutIndex += bufferSize_; - } + unsigned int relOutIndex = outIndex_; + unsigned int inIndexEnd = inIndex_ + bufferSize; + if (relOutIndex < inIndex_ && inIndexEnd >= bufferSize_) + { + relOutIndex += bufferSize_; + } - // "in" index can end on the "out" index but cannot begin at it - if ( inIndex_ <= relOutIndex && inIndexEnd > relOutIndex ) { - return false; // not enough space between "in" index and "out" index - } + // "in" index can end on the "out" index but cannot begin at it + if (inIndex_ <= relOutIndex && inIndexEnd > relOutIndex) + { + return false; // not enough space between "in" index and "out" index + } - // copy buffer from external to internal - int fromZeroSize = inIndex_ + bufferSize - bufferSize_; - fromZeroSize = fromZeroSize < 0 ? 0 : fromZeroSize; - int fromInSize = bufferSize - fromZeroSize; + // copy buffer from external to internal + int fromZeroSize = inIndex_ + bufferSize - bufferSize_; + fromZeroSize = fromZeroSize < 0 ? 0 : fromZeroSize; + int fromInSize = bufferSize - fromZeroSize; - switch( format ) - { - case RTAUDIO_SINT8: - memcpy( &( ( char* ) buffer_ )[inIndex_], buffer, fromInSize * sizeof( char ) ); - memcpy( buffer_, &( ( char* ) buffer )[fromInSize], fromZeroSize * sizeof( char ) ); - break; - case RTAUDIO_SINT16: - memcpy( &( ( short* ) buffer_ )[inIndex_], buffer, fromInSize * sizeof( short ) ); - memcpy( buffer_, &( ( short* ) buffer )[fromInSize], fromZeroSize * sizeof( short ) ); - break; - case RTAUDIO_SINT24: - memcpy( &( ( S24* ) buffer_ )[inIndex_], buffer, fromInSize * sizeof( S24 ) ); - memcpy( buffer_, &( ( S24* ) buffer )[fromInSize], fromZeroSize * sizeof( S24 ) ); - break; - case RTAUDIO_SINT32: - memcpy( &( ( int* ) buffer_ )[inIndex_], buffer, fromInSize * sizeof( int ) ); - memcpy( buffer_, &( ( int* ) buffer )[fromInSize], fromZeroSize * sizeof( int ) ); - break; - case RTAUDIO_FLOAT32: - memcpy( &( ( float* ) buffer_ )[inIndex_], buffer, fromInSize * sizeof( float ) ); - memcpy( buffer_, &( ( float* ) buffer )[fromInSize], fromZeroSize * sizeof( float ) ); - break; - case RTAUDIO_FLOAT64: - memcpy( &( ( double* ) buffer_ )[inIndex_], buffer, fromInSize * sizeof( double ) ); - memcpy( buffer_, &( ( double* ) buffer )[fromInSize], fromZeroSize * sizeof( double ) ); - break; - } + switch (format) + { + case RTAUDIO_SINT8: + memcpy(&((char *)buffer_)[inIndex_], buffer, fromInSize * sizeof(char)); + memcpy(buffer_, &((char *)buffer)[fromInSize], fromZeroSize * sizeof(char)); + break; + case RTAUDIO_SINT16: + memcpy(&((short *)buffer_)[inIndex_], buffer, fromInSize * sizeof(short)); + memcpy(buffer_, &((short *)buffer)[fromInSize], fromZeroSize * sizeof(short)); + break; + case RTAUDIO_SINT24: + memcpy(&((S24 *)buffer_)[inIndex_], buffer, fromInSize * sizeof(S24)); + memcpy(buffer_, &((S24 *)buffer)[fromInSize], fromZeroSize * sizeof(S24)); + break; + case RTAUDIO_SINT32: + memcpy(&((int *)buffer_)[inIndex_], buffer, fromInSize * sizeof(int)); + memcpy(buffer_, &((int *)buffer)[fromInSize], fromZeroSize * sizeof(int)); + break; + case RTAUDIO_FLOAT32: + memcpy(&((float *)buffer_)[inIndex_], buffer, fromInSize * sizeof(float)); + memcpy(buffer_, &((float *)buffer)[fromInSize], fromZeroSize * sizeof(float)); + break; + case RTAUDIO_FLOAT64: + memcpy(&((double *)buffer_)[inIndex_], buffer, fromInSize * sizeof(double)); + memcpy(buffer_, &((double *)buffer)[fromInSize], fromZeroSize * sizeof(double)); + break; + } - // update "in" index - inIndex_ += bufferSize; - inIndex_ %= bufferSize_; + // update "in" index + inIndex_ += bufferSize; + inIndex_ %= bufferSize_; - return true; - } + return true; + } - // attempt to pull a buffer from the ring buffer from the current "out" index - bool pullBuffer( char* buffer, unsigned int bufferSize, RtAudioFormat format ) - { - if ( !buffer || // incoming buffer is NULL - bufferSize == 0 || // incoming buffer has no data - bufferSize > bufferSize_ ) // incoming buffer too large - { - return false; - } + // attempt to pull a buffer from the ring buffer from the current "out" index + bool pullBuffer(char *buffer, unsigned int bufferSize, RtAudioFormat format) + { + if (!buffer || // incoming buffer is NULL + bufferSize == 0 || // incoming buffer has no data + bufferSize > bufferSize_) // incoming buffer too large + { + return false; + } - unsigned int relInIndex = inIndex_; - unsigned int outIndexEnd = outIndex_ + bufferSize; - if ( relInIndex < outIndex_ && outIndexEnd >= bufferSize_ ) { - relInIndex += bufferSize_; - } + unsigned int relInIndex = inIndex_; + unsigned int outIndexEnd = outIndex_ + bufferSize; + if (relInIndex < outIndex_ && outIndexEnd >= bufferSize_) + { + relInIndex += bufferSize_; + } - // "out" index can begin at and end on the "in" index - if ( outIndex_ < relInIndex && outIndexEnd > relInIndex ) { - return false; // not enough space between "out" index and "in" index - } + // "out" index can begin at and end on the "in" index + if (outIndex_ < relInIndex && outIndexEnd > relInIndex) + { + return false; // not enough space between "out" index and "in" index + } - // copy buffer from internal to external - int fromZeroSize = outIndex_ + bufferSize - bufferSize_; - fromZeroSize = fromZeroSize < 0 ? 0 : fromZeroSize; - int fromOutSize = bufferSize - fromZeroSize; + // copy buffer from internal to external + int fromZeroSize = outIndex_ + bufferSize - bufferSize_; + fromZeroSize = fromZeroSize < 0 ? 0 : fromZeroSize; + int fromOutSize = bufferSize - fromZeroSize; - switch( format ) - { - case RTAUDIO_SINT8: - memcpy( buffer, &( ( char* ) buffer_ )[outIndex_], fromOutSize * sizeof( char ) ); - memcpy( &( ( char* ) buffer )[fromOutSize], buffer_, fromZeroSize * sizeof( char ) ); - break; - case RTAUDIO_SINT16: - memcpy( buffer, &( ( short* ) buffer_ )[outIndex_], fromOutSize * sizeof( short ) ); - memcpy( &( ( short* ) buffer )[fromOutSize], buffer_, fromZeroSize * sizeof( short ) ); - break; - case RTAUDIO_SINT24: - memcpy( buffer, &( ( S24* ) buffer_ )[outIndex_], fromOutSize * sizeof( S24 ) ); - memcpy( &( ( S24* ) buffer )[fromOutSize], buffer_, fromZeroSize * sizeof( S24 ) ); - break; - case RTAUDIO_SINT32: - memcpy( buffer, &( ( int* ) buffer_ )[outIndex_], fromOutSize * sizeof( int ) ); - memcpy( &( ( int* ) buffer )[fromOutSize], buffer_, fromZeroSize * sizeof( int ) ); - break; - case RTAUDIO_FLOAT32: - memcpy( buffer, &( ( float* ) buffer_ )[outIndex_], fromOutSize * sizeof( float ) ); - memcpy( &( ( float* ) buffer )[fromOutSize], buffer_, fromZeroSize * sizeof( float ) ); - break; - case RTAUDIO_FLOAT64: - memcpy( buffer, &( ( double* ) buffer_ )[outIndex_], fromOutSize * sizeof( double ) ); - memcpy( &( ( double* ) buffer )[fromOutSize], buffer_, fromZeroSize * sizeof( double ) ); - break; - } + switch (format) + { + case RTAUDIO_SINT8: + memcpy(buffer, &((char *)buffer_)[outIndex_], fromOutSize * sizeof(char)); + memcpy(&((char *)buffer)[fromOutSize], buffer_, fromZeroSize * sizeof(char)); + break; + case RTAUDIO_SINT16: + memcpy(buffer, &((short *)buffer_)[outIndex_], fromOutSize * sizeof(short)); + memcpy(&((short *)buffer)[fromOutSize], buffer_, fromZeroSize * sizeof(short)); + break; + case RTAUDIO_SINT24: + memcpy(buffer, &((S24 *)buffer_)[outIndex_], fromOutSize * sizeof(S24)); + memcpy(&((S24 *)buffer)[fromOutSize], buffer_, fromZeroSize * sizeof(S24)); + break; + case RTAUDIO_SINT32: + memcpy(buffer, &((int *)buffer_)[outIndex_], fromOutSize * sizeof(int)); + memcpy(&((int *)buffer)[fromOutSize], buffer_, fromZeroSize * sizeof(int)); + break; + case RTAUDIO_FLOAT32: + memcpy(buffer, &((float *)buffer_)[outIndex_], fromOutSize * sizeof(float)); + memcpy(&((float *)buffer)[fromOutSize], buffer_, fromZeroSize * sizeof(float)); + break; + case RTAUDIO_FLOAT64: + memcpy(buffer, &((double *)buffer_)[outIndex_], fromOutSize * sizeof(double)); + memcpy(&((double *)buffer)[fromOutSize], buffer_, fromZeroSize * sizeof(double)); + break; + } - // update "out" index - outIndex_ += bufferSize; - outIndex_ %= bufferSize_; + // update "out" index + outIndex_ += bufferSize; + outIndex_ %= bufferSize_; - return true; - } + return true; + } private: - char* buffer_; - unsigned int bufferSize_; - unsigned int inIndex_; - unsigned int outIndex_; + char *buffer_; + unsigned int bufferSize_; + unsigned int inIndex_; + unsigned int outIndex_; }; //----------------------------------------------------------------------------- @@ -3861,52 +4221,52 @@ private: // between HwIn->UserIn and UserOut->HwOut during the stream callback loop. // This sample rate converter favors speed over quality, and works best with conversions between // one rate and its multiple. -void convertBufferWasapi( char* outBuffer, - const char* inBuffer, - const unsigned int& channelCount, - const unsigned int& inSampleRate, - const unsigned int& outSampleRate, - const unsigned int& inSampleCount, - unsigned int& outSampleCount, - const RtAudioFormat& format ) +void convertBufferWasapi(char *outBuffer, + const char *inBuffer, + const unsigned int &channelCount, + const unsigned int &inSampleRate, + const unsigned int &outSampleRate, + const unsigned int &inSampleCount, + unsigned int &outSampleCount, + const RtAudioFormat &format) { - // calculate the new outSampleCount and relative sampleStep - float sampleRatio = ( float ) outSampleRate / inSampleRate; - float sampleStep = 1.0f / sampleRatio; - float inSampleFraction = 0.0f; + // calculate the new outSampleCount and relative sampleStep + float sampleRatio = (float)outSampleRate / inSampleRate; + float sampleStep = 1.0f / sampleRatio; + float inSampleFraction = 0.0f; - outSampleCount = ( unsigned int ) roundf( inSampleCount * sampleRatio ); + outSampleCount = (unsigned int)roundf(inSampleCount * sampleRatio); - // frame-by-frame, copy each relative input sample into it's corresponding output sample - for ( unsigned int outSample = 0; outSample < outSampleCount; outSample++ ) - { - unsigned int inSample = ( unsigned int ) inSampleFraction; + // frame-by-frame, copy each relative input sample into it's corresponding output sample + for (unsigned int outSample = 0; outSample < outSampleCount; outSample++) + { + unsigned int inSample = (unsigned int)inSampleFraction; - switch ( format ) - { - case RTAUDIO_SINT8: - memcpy( &( ( char* ) outBuffer )[ outSample * channelCount ], &( ( char* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( char ) ); - break; - case RTAUDIO_SINT16: - memcpy( &( ( short* ) outBuffer )[ outSample * channelCount ], &( ( short* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( short ) ); - break; - case RTAUDIO_SINT24: - memcpy( &( ( S24* ) outBuffer )[ outSample * channelCount ], &( ( S24* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( S24 ) ); - break; - case RTAUDIO_SINT32: - memcpy( &( ( int* ) outBuffer )[ outSample * channelCount ], &( ( int* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( int ) ); - break; - case RTAUDIO_FLOAT32: - memcpy( &( ( float* ) outBuffer )[ outSample * channelCount ], &( ( float* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( float ) ); - break; - case RTAUDIO_FLOAT64: - memcpy( &( ( double* ) outBuffer )[ outSample * channelCount ], &( ( double* ) inBuffer )[ inSample * channelCount ], channelCount * sizeof( double ) ); - break; - } + switch (format) + { + case RTAUDIO_SINT8: + memcpy(&((char *)outBuffer)[outSample * channelCount], &((char *)inBuffer)[inSample * channelCount], channelCount * sizeof(char)); + break; + case RTAUDIO_SINT16: + memcpy(&((short *)outBuffer)[outSample * channelCount], &((short *)inBuffer)[inSample * channelCount], channelCount * sizeof(short)); + break; + case RTAUDIO_SINT24: + memcpy(&((S24 *)outBuffer)[outSample * channelCount], &((S24 *)inBuffer)[inSample * channelCount], channelCount * sizeof(S24)); + break; + case RTAUDIO_SINT32: + memcpy(&((int *)outBuffer)[outSample * channelCount], &((int *)inBuffer)[inSample * channelCount], channelCount * sizeof(int)); + break; + case RTAUDIO_FLOAT32: + memcpy(&((float *)outBuffer)[outSample * channelCount], &((float *)inBuffer)[inSample * channelCount], channelCount * sizeof(float)); + break; + case RTAUDIO_FLOAT64: + memcpy(&((double *)outBuffer)[outSample * channelCount], &((double *)inBuffer)[inSample * channelCount], channelCount * sizeof(double)); + break; + } - // jump to next in sample - inSampleFraction += sampleStep; - } + // jump to next in sample + inSampleFraction += sampleStep; + } } //----------------------------------------------------------------------------- @@ -3914,1282 +4274,1416 @@ void convertBufferWasapi( char* outBuffer, // A structure to hold various information related to the WASAPI implementation. struct WasapiHandle { - IAudioClient* captureAudioClient; - IAudioClient* renderAudioClient; - IAudioCaptureClient* captureClient; - IAudioRenderClient* renderClient; - HANDLE captureEvent; - HANDLE renderEvent; + IAudioClient *captureAudioClient; + IAudioClient *renderAudioClient; + IAudioCaptureClient *captureClient; + IAudioRenderClient *renderClient; + HANDLE captureEvent; + HANDLE renderEvent; - WasapiHandle() - : captureAudioClient( NULL ), - renderAudioClient( NULL ), - captureClient( NULL ), - renderClient( NULL ), - captureEvent( NULL ), - renderEvent( NULL ) {} + WasapiHandle() + : captureAudioClient(NULL), + renderAudioClient(NULL), + captureClient(NULL), + renderClient(NULL), + captureEvent(NULL), + renderEvent(NULL) {} }; //============================================================================= RtApiWasapi::RtApiWasapi() - : coInitialized_( false ), deviceEnumerator_( NULL ) + : coInitialized_(false), deviceEnumerator_(NULL) { - // WASAPI can run either apartment or multi-threaded - HRESULT hr = CoInitialize( NULL ); - if ( !FAILED( hr ) ) - coInitialized_ = true; + // WASAPI can run either apartment or multi-threaded + HRESULT hr = CoInitialize(NULL); + if (!FAILED(hr)) + coInitialized_ = true; - // Instantiate device enumerator - hr = CoCreateInstance( __uuidof( MMDeviceEnumerator ), NULL, - CLSCTX_ALL, __uuidof( IMMDeviceEnumerator ), - ( void** ) &deviceEnumerator_ ); + // Instantiate device enumerator + hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), NULL, + CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), + (void **)&deviceEnumerator_); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::RtApiWasapi: Unable to instantiate device enumerator"; - error( RtAudioError::DRIVER_ERROR ); - } + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::RtApiWasapi: Unable to instantiate device enumerator"; + error(RtAudioError::DRIVER_ERROR); + } } //----------------------------------------------------------------------------- RtApiWasapi::~RtApiWasapi() { - if ( stream_.state != STREAM_CLOSED ) - closeStream(); + if (stream_.state != STREAM_CLOSED) + closeStream(); - SAFE_RELEASE( deviceEnumerator_ ); + SAFE_RELEASE(deviceEnumerator_); - // If this object previously called CoInitialize() - if ( coInitialized_ ) - CoUninitialize(); + // If this object previously called CoInitialize() + if (coInitialized_) + CoUninitialize(); } //============================================================================= -unsigned int RtApiWasapi::getDeviceCount( void ) +unsigned int RtApiWasapi::getDeviceCount(void) { - unsigned int captureDeviceCount = 0; - unsigned int renderDeviceCount = 0; + unsigned int captureDeviceCount = 0; + unsigned int renderDeviceCount = 0; - IMMDeviceCollection* captureDevices = NULL; - IMMDeviceCollection* renderDevices = NULL; + IMMDeviceCollection *captureDevices = NULL; + IMMDeviceCollection *renderDevices = NULL; - // Count capture devices - errorText_.clear(); - HRESULT hr = deviceEnumerator_->EnumAudioEndpoints( eCapture, DEVICE_STATE_ACTIVE, &captureDevices ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::getDeviceCount: Unable to retrieve capture device collection."; - goto Exit; - } + // Count capture devices + errorText_.clear(); + HRESULT hr = deviceEnumerator_->EnumAudioEndpoints(eCapture, DEVICE_STATE_ACTIVE, &captureDevices); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::getDeviceCount: Unable to retrieve capture device collection."; + goto Exit; + } - hr = captureDevices->GetCount( &captureDeviceCount ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::getDeviceCount: Unable to retrieve capture device count."; - goto Exit; - } + hr = captureDevices->GetCount(&captureDeviceCount); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::getDeviceCount: Unable to retrieve capture device count."; + goto Exit; + } - // Count render devices - hr = deviceEnumerator_->EnumAudioEndpoints( eRender, DEVICE_STATE_ACTIVE, &renderDevices ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::getDeviceCount: Unable to retrieve render device collection."; - goto Exit; - } + // Count render devices + hr = deviceEnumerator_->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &renderDevices); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::getDeviceCount: Unable to retrieve render device collection."; + goto Exit; + } - hr = renderDevices->GetCount( &renderDeviceCount ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::getDeviceCount: Unable to retrieve render device count."; - goto Exit; - } + hr = renderDevices->GetCount(&renderDeviceCount); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::getDeviceCount: Unable to retrieve render device count."; + goto Exit; + } Exit: - // release all references - SAFE_RELEASE( captureDevices ); - SAFE_RELEASE( renderDevices ); + // release all references + SAFE_RELEASE(captureDevices); + SAFE_RELEASE(renderDevices); - if ( errorText_.empty() ) - return captureDeviceCount + renderDeviceCount; + if (errorText_.empty()) + return captureDeviceCount + renderDeviceCount; - error( RtAudioError::DRIVER_ERROR ); - return 0; + error(RtAudioError::DRIVER_ERROR); + return 0; } //----------------------------------------------------------------------------- -RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo( unsigned int device ) +RtAudio::DeviceInfo RtApiWasapi::getDeviceInfo(unsigned int device) { - RtAudio::DeviceInfo info; - unsigned int captureDeviceCount = 0; - unsigned int renderDeviceCount = 0; - std::string defaultDeviceName; - bool isCaptureDevice = false; + RtAudio::DeviceInfo info; + unsigned int captureDeviceCount = 0; + unsigned int renderDeviceCount = 0; + std::string defaultDeviceName; + bool isCaptureDevice = false; - PROPVARIANT deviceNameProp; - PROPVARIANT defaultDeviceNameProp; + PROPVARIANT deviceNameProp; + PROPVARIANT defaultDeviceNameProp; - IMMDeviceCollection* captureDevices = NULL; - IMMDeviceCollection* renderDevices = NULL; - IMMDevice* devicePtr = NULL; - IMMDevice* defaultDevicePtr = NULL; - IAudioClient* audioClient = NULL; - IPropertyStore* devicePropStore = NULL; - IPropertyStore* defaultDevicePropStore = NULL; + IMMDeviceCollection *captureDevices = NULL; + IMMDeviceCollection *renderDevices = NULL; + IMMDevice *devicePtr = NULL; + IMMDevice *defaultDevicePtr = NULL; + IAudioClient *audioClient = NULL; + IPropertyStore *devicePropStore = NULL; + IPropertyStore *defaultDevicePropStore = NULL; - WAVEFORMATEX* deviceFormat = NULL; - WAVEFORMATEX* closestMatchFormat = NULL; + WAVEFORMATEX *deviceFormat = NULL; + WAVEFORMATEX *closestMatchFormat = NULL; - // probed - info.probed = false; + // probed + info.probed = false; - // Count capture devices - errorText_.clear(); - RtAudioError::Type errorType = RtAudioError::DRIVER_ERROR; - HRESULT hr = deviceEnumerator_->EnumAudioEndpoints( eCapture, DEVICE_STATE_ACTIVE, &captureDevices ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve capture device collection."; - goto Exit; - } + // Count capture devices + errorText_.clear(); + RtAudioError::Type errorType = RtAudioError::DRIVER_ERROR; + HRESULT hr = deviceEnumerator_->EnumAudioEndpoints(eCapture, DEVICE_STATE_ACTIVE, &captureDevices); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve capture device collection."; + goto Exit; + } - hr = captureDevices->GetCount( &captureDeviceCount ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve capture device count."; - goto Exit; - } + hr = captureDevices->GetCount(&captureDeviceCount); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve capture device count."; + goto Exit; + } - // Count render devices - hr = deviceEnumerator_->EnumAudioEndpoints( eRender, DEVICE_STATE_ACTIVE, &renderDevices ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve render device collection."; - goto Exit; - } + // Count render devices + hr = deviceEnumerator_->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &renderDevices); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve render device collection."; + goto Exit; + } - hr = renderDevices->GetCount( &renderDeviceCount ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve render device count."; - goto Exit; - } + hr = renderDevices->GetCount(&renderDeviceCount); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve render device count."; + goto Exit; + } - // validate device index - if ( device >= captureDeviceCount + renderDeviceCount ) { - errorText_ = "RtApiWasapi::getDeviceInfo: Invalid device index."; - errorType = RtAudioError::INVALID_USE; - goto Exit; - } + // validate device index + if (device >= captureDeviceCount + renderDeviceCount) + { + errorText_ = "RtApiWasapi::getDeviceInfo: Invalid device index."; + errorType = RtAudioError::INVALID_USE; + goto Exit; + } - // determine whether index falls within capture or render devices - if ( device >= renderDeviceCount ) { - hr = captureDevices->Item( device - renderDeviceCount, &devicePtr ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve capture device handle."; - goto Exit; - } - isCaptureDevice = true; - } - else { - hr = renderDevices->Item( device, &devicePtr ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve render device handle."; - goto Exit; - } - isCaptureDevice = false; - } + // determine whether index falls within capture or render devices + if (device >= renderDeviceCount) + { + hr = captureDevices->Item(device - renderDeviceCount, &devicePtr); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve capture device handle."; + goto Exit; + } + isCaptureDevice = true; + } + else + { + hr = renderDevices->Item(device, &devicePtr); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve render device handle."; + goto Exit; + } + isCaptureDevice = false; + } - // get default device name - if ( isCaptureDevice ) { - hr = deviceEnumerator_->GetDefaultAudioEndpoint( eCapture, eConsole, &defaultDevicePtr ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve default capture device handle."; - goto Exit; - } - } - else { - hr = deviceEnumerator_->GetDefaultAudioEndpoint( eRender, eConsole, &defaultDevicePtr ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve default render device handle."; - goto Exit; - } - } + // get default device name + if (isCaptureDevice) + { + hr = deviceEnumerator_->GetDefaultAudioEndpoint(eCapture, eConsole, &defaultDevicePtr); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve default capture device handle."; + goto Exit; + } + } + else + { + hr = deviceEnumerator_->GetDefaultAudioEndpoint(eRender, eConsole, &defaultDevicePtr); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve default render device handle."; + goto Exit; + } + } - hr = defaultDevicePtr->OpenPropertyStore( STGM_READ, &defaultDevicePropStore ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::getDeviceInfo: Unable to open default device property store."; - goto Exit; - } - PropVariantInit( &defaultDeviceNameProp ); + hr = defaultDevicePtr->OpenPropertyStore(STGM_READ, &defaultDevicePropStore); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::getDeviceInfo: Unable to open default device property store."; + goto Exit; + } + PropVariantInit(&defaultDeviceNameProp); - hr = defaultDevicePropStore->GetValue( PKEY_Device_FriendlyName, &defaultDeviceNameProp ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve default device property: PKEY_Device_FriendlyName."; - goto Exit; - } + hr = defaultDevicePropStore->GetValue(PKEY_Device_FriendlyName, &defaultDeviceNameProp); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve default device property: PKEY_Device_FriendlyName."; + goto Exit; + } - defaultDeviceName = convertCharPointerToStdString(defaultDeviceNameProp.pwszVal); + defaultDeviceName = convertCharPointerToStdString(defaultDeviceNameProp.pwszVal); - // name - hr = devicePtr->OpenPropertyStore( STGM_READ, &devicePropStore ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::getDeviceInfo: Unable to open device property store."; - goto Exit; - } + // name + hr = devicePtr->OpenPropertyStore(STGM_READ, &devicePropStore); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::getDeviceInfo: Unable to open device property store."; + goto Exit; + } - PropVariantInit( &deviceNameProp ); + PropVariantInit(&deviceNameProp); - hr = devicePropStore->GetValue( PKEY_Device_FriendlyName, &deviceNameProp ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve device property: PKEY_Device_FriendlyName."; - goto Exit; - } + hr = devicePropStore->GetValue(PKEY_Device_FriendlyName, &deviceNameProp); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve device property: PKEY_Device_FriendlyName."; + goto Exit; + } - info.name =convertCharPointerToStdString(deviceNameProp.pwszVal); + info.name = convertCharPointerToStdString(deviceNameProp.pwszVal); - // is default - if ( isCaptureDevice ) { - info.isDefaultInput = info.name == defaultDeviceName; - info.isDefaultOutput = false; - } - else { - info.isDefaultInput = false; - info.isDefaultOutput = info.name == defaultDeviceName; - } + // is default + if (isCaptureDevice) + { + info.isDefaultInput = info.name == defaultDeviceName; + info.isDefaultOutput = false; + } + else + { + info.isDefaultInput = false; + info.isDefaultOutput = info.name == defaultDeviceName; + } - // channel count - hr = devicePtr->Activate( __uuidof( IAudioClient ), CLSCTX_ALL, NULL, ( void** ) &audioClient ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve device audio client."; - goto Exit; - } + // channel count + hr = devicePtr->Activate(__uuidof(IAudioClient), CLSCTX_ALL, NULL, (void **)&audioClient); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve device audio client."; + goto Exit; + } - hr = audioClient->GetMixFormat( &deviceFormat ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve device mix format."; - goto Exit; - } + hr = audioClient->GetMixFormat(&deviceFormat); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::getDeviceInfo: Unable to retrieve device mix format."; + goto Exit; + } - if ( isCaptureDevice ) { - info.inputChannels = deviceFormat->nChannels; - info.outputChannels = 0; - info.duplexChannels = 0; - } - else { - info.inputChannels = 0; - info.outputChannels = deviceFormat->nChannels; - info.duplexChannels = 0; - } + if (isCaptureDevice) + { + info.inputChannels = deviceFormat->nChannels; + info.outputChannels = 0; + info.duplexChannels = 0; + } + else + { + info.inputChannels = 0; + info.outputChannels = deviceFormat->nChannels; + info.duplexChannels = 0; + } - // sample rates - info.sampleRates.clear(); + // sample rates + info.sampleRates.clear(); - // allow support for all sample rates as we have a built-in sample rate converter - for ( unsigned int i = 0; i < MAX_SAMPLE_RATES; i++ ) { - info.sampleRates.push_back( SAMPLE_RATES[i] ); - } - info.preferredSampleRate = deviceFormat->nSamplesPerSec; + // allow support for all sample rates as we have a built-in sample rate converter + for (unsigned int i = 0; i < MAX_SAMPLE_RATES; i++) + { + info.sampleRates.push_back(SAMPLE_RATES[i]); + } + info.preferredSampleRate = deviceFormat->nSamplesPerSec; - // native format - info.nativeFormats = 0; + // native format + info.nativeFormats = 0; - if ( deviceFormat->wFormatTag == WAVE_FORMAT_IEEE_FLOAT || - ( deviceFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE && - ( ( WAVEFORMATEXTENSIBLE* ) deviceFormat )->SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT ) ) - { - if ( deviceFormat->wBitsPerSample == 32 ) { - info.nativeFormats |= RTAUDIO_FLOAT32; - } - else if ( deviceFormat->wBitsPerSample == 64 ) { - info.nativeFormats |= RTAUDIO_FLOAT64; - } - } - else if ( deviceFormat->wFormatTag == WAVE_FORMAT_PCM || - ( deviceFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE && - ( ( WAVEFORMATEXTENSIBLE* ) deviceFormat )->SubFormat == KSDATAFORMAT_SUBTYPE_PCM ) ) - { - if ( deviceFormat->wBitsPerSample == 8 ) { - info.nativeFormats |= RTAUDIO_SINT8; - } - else if ( deviceFormat->wBitsPerSample == 16 ) { - info.nativeFormats |= RTAUDIO_SINT16; - } - else if ( deviceFormat->wBitsPerSample == 24 ) { - info.nativeFormats |= RTAUDIO_SINT24; - } - else if ( deviceFormat->wBitsPerSample == 32 ) { - info.nativeFormats |= RTAUDIO_SINT32; - } - } + if (deviceFormat->wFormatTag == WAVE_FORMAT_IEEE_FLOAT || + (deviceFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE && + ((WAVEFORMATEXTENSIBLE *)deviceFormat)->SubFormat == KSDATAFORMAT_SUBTYPE_IEEE_FLOAT)) + { + if (deviceFormat->wBitsPerSample == 32) + { + info.nativeFormats |= RTAUDIO_FLOAT32; + } + else if (deviceFormat->wBitsPerSample == 64) + { + info.nativeFormats |= RTAUDIO_FLOAT64; + } + } + else if (deviceFormat->wFormatTag == WAVE_FORMAT_PCM || + (deviceFormat->wFormatTag == WAVE_FORMAT_EXTENSIBLE && + ((WAVEFORMATEXTENSIBLE *)deviceFormat)->SubFormat == KSDATAFORMAT_SUBTYPE_PCM)) + { + if (deviceFormat->wBitsPerSample == 8) + { + info.nativeFormats |= RTAUDIO_SINT8; + } + else if (deviceFormat->wBitsPerSample == 16) + { + info.nativeFormats |= RTAUDIO_SINT16; + } + else if (deviceFormat->wBitsPerSample == 24) + { + info.nativeFormats |= RTAUDIO_SINT24; + } + else if (deviceFormat->wBitsPerSample == 32) + { + info.nativeFormats |= RTAUDIO_SINT32; + } + } - // probed - info.probed = true; + // probed + info.probed = true; Exit: - // release all references - PropVariantClear( &deviceNameProp ); - PropVariantClear( &defaultDeviceNameProp ); + // release all references + PropVariantClear(&deviceNameProp); + PropVariantClear(&defaultDeviceNameProp); - SAFE_RELEASE( captureDevices ); - SAFE_RELEASE( renderDevices ); - SAFE_RELEASE( devicePtr ); - SAFE_RELEASE( defaultDevicePtr ); - SAFE_RELEASE( audioClient ); - SAFE_RELEASE( devicePropStore ); - SAFE_RELEASE( defaultDevicePropStore ); + SAFE_RELEASE(captureDevices); + SAFE_RELEASE(renderDevices); + SAFE_RELEASE(devicePtr); + SAFE_RELEASE(defaultDevicePtr); + SAFE_RELEASE(audioClient); + SAFE_RELEASE(devicePropStore); + SAFE_RELEASE(defaultDevicePropStore); - CoTaskMemFree( deviceFormat ); - CoTaskMemFree( closestMatchFormat ); + CoTaskMemFree(deviceFormat); + CoTaskMemFree(closestMatchFormat); - if ( !errorText_.empty() ) - error( errorType ); - return info; + if (!errorText_.empty()) + error(errorType); + return info; } //----------------------------------------------------------------------------- -unsigned int RtApiWasapi::getDefaultOutputDevice( void ) +unsigned int RtApiWasapi::getDefaultOutputDevice(void) { - for ( unsigned int i = 0; i < getDeviceCount(); i++ ) { - if ( getDeviceInfo( i ).isDefaultOutput ) { - return i; - } - } + for (unsigned int i = 0; i < getDeviceCount(); i++) + { + if (getDeviceInfo(i).isDefaultOutput) + { + return i; + } + } - return 0; + return 0; } //----------------------------------------------------------------------------- -unsigned int RtApiWasapi::getDefaultInputDevice( void ) +unsigned int RtApiWasapi::getDefaultInputDevice(void) { - for ( unsigned int i = 0; i < getDeviceCount(); i++ ) { - if ( getDeviceInfo( i ).isDefaultInput ) { - return i; - } - } + for (unsigned int i = 0; i < getDeviceCount(); i++) + { + if (getDeviceInfo(i).isDefaultInput) + { + return i; + } + } - return 0; + return 0; } //----------------------------------------------------------------------------- -void RtApiWasapi::closeStream( void ) +void RtApiWasapi::closeStream(void) { - if ( stream_.state == STREAM_CLOSED ) { - errorText_ = "RtApiWasapi::closeStream: No open stream to close."; - error( RtAudioError::WARNING ); - return; - } + if (stream_.state == STREAM_CLOSED) + { + errorText_ = "RtApiWasapi::closeStream: No open stream to close."; + error(RtAudioError::WARNING); + return; + } - if ( stream_.state != STREAM_STOPPED ) - stopStream(); + if (stream_.state != STREAM_STOPPED) + stopStream(); - // clean up stream memory - SAFE_RELEASE( ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient ) - SAFE_RELEASE( ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient ) + // clean up stream memory + SAFE_RELEASE(((WasapiHandle *)stream_.apiHandle)->captureAudioClient) + SAFE_RELEASE(((WasapiHandle *)stream_.apiHandle)->renderAudioClient) - SAFE_RELEASE( ( ( WasapiHandle* ) stream_.apiHandle )->captureClient ) - SAFE_RELEASE( ( ( WasapiHandle* ) stream_.apiHandle )->renderClient ) + SAFE_RELEASE(((WasapiHandle *)stream_.apiHandle)->captureClient) + SAFE_RELEASE(((WasapiHandle *)stream_.apiHandle)->renderClient) - if ( ( ( WasapiHandle* ) stream_.apiHandle )->captureEvent ) - CloseHandle( ( ( WasapiHandle* ) stream_.apiHandle )->captureEvent ); + if (((WasapiHandle *)stream_.apiHandle)->captureEvent) + CloseHandle(((WasapiHandle *)stream_.apiHandle)->captureEvent); - if ( ( ( WasapiHandle* ) stream_.apiHandle )->renderEvent ) - CloseHandle( ( ( WasapiHandle* ) stream_.apiHandle )->renderEvent ); + if (((WasapiHandle *)stream_.apiHandle)->renderEvent) + CloseHandle(((WasapiHandle *)stream_.apiHandle)->renderEvent); - delete ( WasapiHandle* ) stream_.apiHandle; - stream_.apiHandle = NULL; + delete (WasapiHandle *)stream_.apiHandle; + stream_.apiHandle = NULL; - for ( int i = 0; i < 2; i++ ) { - if ( stream_.userBuffer[i] ) { - free( stream_.userBuffer[i] ); - stream_.userBuffer[i] = 0; - } - } + for (int i = 0; i < 2; i++) + { + if (stream_.userBuffer[i]) + { + free(stream_.userBuffer[i]); + stream_.userBuffer[i] = 0; + } + } - if ( stream_.deviceBuffer ) { - free( stream_.deviceBuffer ); - stream_.deviceBuffer = 0; - } + if (stream_.deviceBuffer) + { + free(stream_.deviceBuffer); + stream_.deviceBuffer = 0; + } - // update stream state - stream_.state = STREAM_CLOSED; + // update stream state + stream_.state = STREAM_CLOSED; } //----------------------------------------------------------------------------- -void RtApiWasapi::startStream( void ) +void RtApiWasapi::startStream(void) { - verifyStream(); + verifyStream(); - if ( stream_.state == STREAM_RUNNING ) { - errorText_ = "RtApiWasapi::startStream: The stream is already running."; - error( RtAudioError::WARNING ); - return; - } + if (stream_.state == STREAM_RUNNING) + { + errorText_ = "RtApiWasapi::startStream: The stream is already running."; + error(RtAudioError::WARNING); + return; + } - // update stream state - stream_.state = STREAM_RUNNING; + // update stream state + stream_.state = STREAM_RUNNING; - // create WASAPI stream thread - stream_.callbackInfo.thread = ( ThreadHandle ) CreateThread( NULL, 0, runWasapiThread, this, CREATE_SUSPENDED, NULL ); + // create WASAPI stream thread + stream_.callbackInfo.thread = (ThreadHandle)CreateThread(NULL, 0, runWasapiThread, this, CREATE_SUSPENDED, NULL); - if ( !stream_.callbackInfo.thread ) { - errorText_ = "RtApiWasapi::startStream: Unable to instantiate callback thread."; - error( RtAudioError::THREAD_ERROR ); - } - else { - SetThreadPriority( ( void* ) stream_.callbackInfo.thread, stream_.callbackInfo.priority ); - ResumeThread( ( void* ) stream_.callbackInfo.thread ); - } + if (!stream_.callbackInfo.thread) + { + errorText_ = "RtApiWasapi::startStream: Unable to instantiate callback thread."; + error(RtAudioError::THREAD_ERROR); + } + else + { + SetThreadPriority((void *)stream_.callbackInfo.thread, stream_.callbackInfo.priority); + ResumeThread((void *)stream_.callbackInfo.thread); + } } //----------------------------------------------------------------------------- -void RtApiWasapi::stopStream( void ) +void RtApiWasapi::stopStream(void) { - verifyStream(); + verifyStream(); - if ( stream_.state == STREAM_STOPPED ) { - errorText_ = "RtApiWasapi::stopStream: The stream is already stopped."; - error( RtAudioError::WARNING ); - return; - } + if (stream_.state == STREAM_STOPPED) + { + errorText_ = "RtApiWasapi::stopStream: The stream is already stopped."; + error(RtAudioError::WARNING); + return; + } - // inform stream thread by setting stream state to STREAM_STOPPING - stream_.state = STREAM_STOPPING; + // inform stream thread by setting stream state to STREAM_STOPPING + stream_.state = STREAM_STOPPING; - // wait until stream thread is stopped - while( stream_.state != STREAM_STOPPED ) { - Sleep( 1 ); - } + // wait until stream thread is stopped + while (stream_.state != STREAM_STOPPED) + { + Sleep(1); + } - // Wait for the last buffer to play before stopping. - Sleep( 1000 * stream_.bufferSize / stream_.sampleRate ); + // Wait for the last buffer to play before stopping. + Sleep(1000 * stream_.bufferSize / stream_.sampleRate); - // stop capture client if applicable - if ( ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient ) { - HRESULT hr = ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient->Stop(); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::stopStream: Unable to stop capture stream."; - error( RtAudioError::DRIVER_ERROR ); - return; - } - } + // stop capture client if applicable + if (((WasapiHandle *)stream_.apiHandle)->captureAudioClient) + { + HRESULT hr = ((WasapiHandle *)stream_.apiHandle)->captureAudioClient->Stop(); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::stopStream: Unable to stop capture stream."; + error(RtAudioError::DRIVER_ERROR); + return; + } + } - // stop render client if applicable - if ( ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient ) { - HRESULT hr = ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient->Stop(); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::stopStream: Unable to stop render stream."; - error( RtAudioError::DRIVER_ERROR ); - return; - } - } + // stop render client if applicable + if (((WasapiHandle *)stream_.apiHandle)->renderAudioClient) + { + HRESULT hr = ((WasapiHandle *)stream_.apiHandle)->renderAudioClient->Stop(); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::stopStream: Unable to stop render stream."; + error(RtAudioError::DRIVER_ERROR); + return; + } + } - // close thread handle - if ( stream_.callbackInfo.thread && !CloseHandle( ( void* ) stream_.callbackInfo.thread ) ) { - errorText_ = "RtApiWasapi::stopStream: Unable to close callback thread."; - error( RtAudioError::THREAD_ERROR ); - return; - } + // close thread handle + if (stream_.callbackInfo.thread && !CloseHandle((void *)stream_.callbackInfo.thread)) + { + errorText_ = "RtApiWasapi::stopStream: Unable to close callback thread."; + error(RtAudioError::THREAD_ERROR); + return; + } - stream_.callbackInfo.thread = (ThreadHandle) NULL; + stream_.callbackInfo.thread = (ThreadHandle)NULL; } //----------------------------------------------------------------------------- -void RtApiWasapi::abortStream( void ) +void RtApiWasapi::abortStream(void) { - verifyStream(); + verifyStream(); - if ( stream_.state == STREAM_STOPPED ) { - errorText_ = "RtApiWasapi::abortStream: The stream is already stopped."; - error( RtAudioError::WARNING ); - return; - } + if (stream_.state == STREAM_STOPPED) + { + errorText_ = "RtApiWasapi::abortStream: The stream is already stopped."; + error(RtAudioError::WARNING); + return; + } - // inform stream thread by setting stream state to STREAM_STOPPING - stream_.state = STREAM_STOPPING; + // inform stream thread by setting stream state to STREAM_STOPPING + stream_.state = STREAM_STOPPING; - // wait until stream thread is stopped - while ( stream_.state != STREAM_STOPPED ) { - Sleep( 1 ); - } + // wait until stream thread is stopped + while (stream_.state != STREAM_STOPPED) + { + Sleep(1); + } - // stop capture client if applicable - if ( ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient ) { - HRESULT hr = ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient->Stop(); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::abortStream: Unable to stop capture stream."; - error( RtAudioError::DRIVER_ERROR ); - return; - } - } + // stop capture client if applicable + if (((WasapiHandle *)stream_.apiHandle)->captureAudioClient) + { + HRESULT hr = ((WasapiHandle *)stream_.apiHandle)->captureAudioClient->Stop(); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::abortStream: Unable to stop capture stream."; + error(RtAudioError::DRIVER_ERROR); + return; + } + } - // stop render client if applicable - if ( ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient ) { - HRESULT hr = ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient->Stop(); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::abortStream: Unable to stop render stream."; - error( RtAudioError::DRIVER_ERROR ); - return; - } - } + // stop render client if applicable + if (((WasapiHandle *)stream_.apiHandle)->renderAudioClient) + { + HRESULT hr = ((WasapiHandle *)stream_.apiHandle)->renderAudioClient->Stop(); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::abortStream: Unable to stop render stream."; + error(RtAudioError::DRIVER_ERROR); + return; + } + } - // close thread handle - if ( stream_.callbackInfo.thread && !CloseHandle( ( void* ) stream_.callbackInfo.thread ) ) { - errorText_ = "RtApiWasapi::abortStream: Unable to close callback thread."; - error( RtAudioError::THREAD_ERROR ); - return; - } + // close thread handle + if (stream_.callbackInfo.thread && !CloseHandle((void *)stream_.callbackInfo.thread)) + { + errorText_ = "RtApiWasapi::abortStream: Unable to close callback thread."; + error(RtAudioError::THREAD_ERROR); + return; + } - stream_.callbackInfo.thread = (ThreadHandle) NULL; + stream_.callbackInfo.thread = (ThreadHandle)NULL; } //----------------------------------------------------------------------------- -bool RtApiWasapi::probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, - unsigned int firstChannel, unsigned int sampleRate, - RtAudioFormat format, unsigned int* bufferSize, - RtAudio::StreamOptions* options ) +bool RtApiWasapi::probeDeviceOpen(unsigned int device, StreamMode mode, unsigned int channels, + unsigned int firstChannel, unsigned int sampleRate, + RtAudioFormat format, unsigned int *bufferSize, + RtAudio::StreamOptions *options) { - bool methodResult = FAILURE; - unsigned int captureDeviceCount = 0; - unsigned int renderDeviceCount = 0; + bool methodResult = FAILURE; + unsigned int captureDeviceCount = 0; + unsigned int renderDeviceCount = 0; - IMMDeviceCollection* captureDevices = NULL; - IMMDeviceCollection* renderDevices = NULL; - IMMDevice* devicePtr = NULL; - WAVEFORMATEX* deviceFormat = NULL; - unsigned int bufferBytes; - stream_.state = STREAM_STOPPED; + IMMDeviceCollection *captureDevices = NULL; + IMMDeviceCollection *renderDevices = NULL; + IMMDevice *devicePtr = NULL; + WAVEFORMATEX *deviceFormat = NULL; + unsigned int bufferBytes; + stream_.state = STREAM_STOPPED; - // create API Handle if not already created - if ( !stream_.apiHandle ) - stream_.apiHandle = ( void* ) new WasapiHandle(); + // create API Handle if not already created + if (!stream_.apiHandle) + stream_.apiHandle = (void *)new WasapiHandle(); - // Count capture devices - errorText_.clear(); - RtAudioError::Type errorType = RtAudioError::DRIVER_ERROR; - HRESULT hr = deviceEnumerator_->EnumAudioEndpoints( eCapture, DEVICE_STATE_ACTIVE, &captureDevices ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve capture device collection."; - goto Exit; - } + // Count capture devices + errorText_.clear(); + RtAudioError::Type errorType = RtAudioError::DRIVER_ERROR; + HRESULT hr = deviceEnumerator_->EnumAudioEndpoints(eCapture, DEVICE_STATE_ACTIVE, &captureDevices); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve capture device collection."; + goto Exit; + } - hr = captureDevices->GetCount( &captureDeviceCount ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve capture device count."; - goto Exit; - } + hr = captureDevices->GetCount(&captureDeviceCount); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve capture device count."; + goto Exit; + } - // Count render devices - hr = deviceEnumerator_->EnumAudioEndpoints( eRender, DEVICE_STATE_ACTIVE, &renderDevices ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve render device collection."; - goto Exit; - } + // Count render devices + hr = deviceEnumerator_->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &renderDevices); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve render device collection."; + goto Exit; + } - hr = renderDevices->GetCount( &renderDeviceCount ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve render device count."; - goto Exit; - } + hr = renderDevices->GetCount(&renderDeviceCount); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve render device count."; + goto Exit; + } - // validate device index - if ( device >= captureDeviceCount + renderDeviceCount ) { - errorType = RtAudioError::INVALID_USE; - errorText_ = "RtApiWasapi::probeDeviceOpen: Invalid device index."; - goto Exit; - } + // validate device index + if (device >= captureDeviceCount + renderDeviceCount) + { + errorType = RtAudioError::INVALID_USE; + errorText_ = "RtApiWasapi::probeDeviceOpen: Invalid device index."; + goto Exit; + } - // determine whether index falls within capture or render devices - if ( device >= renderDeviceCount ) { - if ( mode != INPUT ) { - errorType = RtAudioError::INVALID_USE; - errorText_ = "RtApiWasapi::probeDeviceOpen: Capture device selected as output device."; - goto Exit; - } + // determine whether index falls within capture or render devices + if (device >= renderDeviceCount) + { + if (mode != INPUT) + { + errorType = RtAudioError::INVALID_USE; + errorText_ = "RtApiWasapi::probeDeviceOpen: Capture device selected as output device."; + goto Exit; + } - // retrieve captureAudioClient from devicePtr - IAudioClient*& captureAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient; + // retrieve captureAudioClient from devicePtr + IAudioClient *&captureAudioClient = ((WasapiHandle *)stream_.apiHandle)->captureAudioClient; - hr = captureDevices->Item( device - renderDeviceCount, &devicePtr ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve capture device handle."; - goto Exit; - } + hr = captureDevices->Item(device - renderDeviceCount, &devicePtr); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve capture device handle."; + goto Exit; + } - hr = devicePtr->Activate( __uuidof( IAudioClient ), CLSCTX_ALL, - NULL, ( void** ) &captureAudioClient ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve device audio client."; - goto Exit; - } + hr = devicePtr->Activate(__uuidof(IAudioClient), CLSCTX_ALL, + NULL, (void **)&captureAudioClient); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve device audio client."; + goto Exit; + } - hr = captureAudioClient->GetMixFormat( &deviceFormat ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve device mix format."; - goto Exit; - } + hr = captureAudioClient->GetMixFormat(&deviceFormat); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve device mix format."; + goto Exit; + } - stream_.nDeviceChannels[mode] = deviceFormat->nChannels; - captureAudioClient->GetStreamLatency( ( long long* ) &stream_.latency[mode] ); - } - else { - if ( mode != OUTPUT ) { - errorType = RtAudioError::INVALID_USE; - errorText_ = "RtApiWasapi::probeDeviceOpen: Render device selected as input device."; - goto Exit; - } + stream_.nDeviceChannels[mode] = deviceFormat->nChannels; + captureAudioClient->GetStreamLatency((long long *)&stream_.latency[mode]); + } + else + { + if (mode != OUTPUT) + { + errorType = RtAudioError::INVALID_USE; + errorText_ = "RtApiWasapi::probeDeviceOpen: Render device selected as input device."; + goto Exit; + } - // retrieve renderAudioClient from devicePtr - IAudioClient*& renderAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient; + // retrieve renderAudioClient from devicePtr + IAudioClient *&renderAudioClient = ((WasapiHandle *)stream_.apiHandle)->renderAudioClient; - hr = renderDevices->Item( device, &devicePtr ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve render device handle."; - goto Exit; - } + hr = renderDevices->Item(device, &devicePtr); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve render device handle."; + goto Exit; + } - hr = devicePtr->Activate( __uuidof( IAudioClient ), CLSCTX_ALL, - NULL, ( void** ) &renderAudioClient ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve device audio client."; - goto Exit; - } + hr = devicePtr->Activate(__uuidof(IAudioClient), CLSCTX_ALL, + NULL, (void **)&renderAudioClient); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve device audio client."; + goto Exit; + } - hr = renderAudioClient->GetMixFormat( &deviceFormat ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve device mix format."; - goto Exit; - } + hr = renderAudioClient->GetMixFormat(&deviceFormat); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::probeDeviceOpen: Unable to retrieve device mix format."; + goto Exit; + } - stream_.nDeviceChannels[mode] = deviceFormat->nChannels; - renderAudioClient->GetStreamLatency( ( long long* ) &stream_.latency[mode] ); - } + stream_.nDeviceChannels[mode] = deviceFormat->nChannels; + renderAudioClient->GetStreamLatency((long long *)&stream_.latency[mode]); + } - // fill stream data - if ( ( stream_.mode == OUTPUT && mode == INPUT ) || - ( stream_.mode == INPUT && mode == OUTPUT ) ) { - stream_.mode = DUPLEX; - } - else { - stream_.mode = mode; - } + // fill stream data + if ((stream_.mode == OUTPUT && mode == INPUT) || + (stream_.mode == INPUT && mode == OUTPUT)) + { + stream_.mode = DUPLEX; + } + else + { + stream_.mode = mode; + } - stream_.device[mode] = device; - stream_.doByteSwap[mode] = false; - stream_.sampleRate = sampleRate; - stream_.bufferSize = *bufferSize; - stream_.nBuffers = 1; - stream_.nUserChannels[mode] = channels; - stream_.channelOffset[mode] = firstChannel; - stream_.userFormat = format; - stream_.deviceFormat[mode] = getDeviceInfo( device ).nativeFormats; + stream_.device[mode] = device; + stream_.doByteSwap[mode] = false; + stream_.sampleRate = sampleRate; + stream_.bufferSize = *bufferSize; + stream_.nBuffers = 1; + stream_.nUserChannels[mode] = channels; + stream_.channelOffset[mode] = firstChannel; + stream_.userFormat = format; + stream_.deviceFormat[mode] = getDeviceInfo(device).nativeFormats; - if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) - stream_.userInterleaved = false; - else - stream_.userInterleaved = true; - stream_.deviceInterleaved[mode] = true; + if (options && options->flags & RTAUDIO_NONINTERLEAVED) + stream_.userInterleaved = false; + else + stream_.userInterleaved = true; + stream_.deviceInterleaved[mode] = true; - // Set flags for buffer conversion. - stream_.doConvertBuffer[mode] = false; - if ( stream_.userFormat != stream_.deviceFormat[mode] || - stream_.nUserChannels != stream_.nDeviceChannels ) - stream_.doConvertBuffer[mode] = true; - else if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] && - stream_.nUserChannels[mode] > 1 ) - stream_.doConvertBuffer[mode] = true; + // Set flags for buffer conversion. + stream_.doConvertBuffer[mode] = false; + if (stream_.userFormat != stream_.deviceFormat[mode] || + stream_.nUserChannels != stream_.nDeviceChannels) + stream_.doConvertBuffer[mode] = true; + else if (stream_.userInterleaved != stream_.deviceInterleaved[mode] && + stream_.nUserChannels[mode] > 1) + stream_.doConvertBuffer[mode] = true; - if ( stream_.doConvertBuffer[mode] ) - setConvertInfo( mode, 0 ); + if (stream_.doConvertBuffer[mode]) + setConvertInfo(mode, 0); - // Allocate necessary internal buffers - bufferBytes = stream_.nUserChannels[mode] * stream_.bufferSize * formatBytes( stream_.userFormat ); + // Allocate necessary internal buffers + bufferBytes = stream_.nUserChannels[mode] * stream_.bufferSize * formatBytes(stream_.userFormat); - stream_.userBuffer[mode] = ( char* ) calloc( bufferBytes, 1 ); - if ( !stream_.userBuffer[mode] ) { - errorType = RtAudioError::MEMORY_ERROR; - errorText_ = "RtApiWasapi::probeDeviceOpen: Error allocating user buffer memory."; - goto Exit; - } + stream_.userBuffer[mode] = (char *)calloc(bufferBytes, 1); + if (!stream_.userBuffer[mode]) + { + errorType = RtAudioError::MEMORY_ERROR; + errorText_ = "RtApiWasapi::probeDeviceOpen: Error allocating user buffer memory."; + goto Exit; + } - if ( options && options->flags & RTAUDIO_SCHEDULE_REALTIME ) - stream_.callbackInfo.priority = 15; - else - stream_.callbackInfo.priority = 0; + if (options && options->flags & RTAUDIO_SCHEDULE_REALTIME) + stream_.callbackInfo.priority = 15; + else + stream_.callbackInfo.priority = 0; - ///! TODO: RTAUDIO_MINIMIZE_LATENCY // Provide stream buffers directly to callback - ///! TODO: RTAUDIO_HOG_DEVICE // Exclusive mode + ///! TODO: RTAUDIO_MINIMIZE_LATENCY // Provide stream buffers directly to callback + ///! TODO: RTAUDIO_HOG_DEVICE // Exclusive mode - methodResult = SUCCESS; + methodResult = SUCCESS; Exit: - //clean up - SAFE_RELEASE( captureDevices ); - SAFE_RELEASE( renderDevices ); - SAFE_RELEASE( devicePtr ); - CoTaskMemFree( deviceFormat ); + //clean up + SAFE_RELEASE(captureDevices); + SAFE_RELEASE(renderDevices); + SAFE_RELEASE(devicePtr); + CoTaskMemFree(deviceFormat); - // if method failed, close the stream - if ( methodResult == FAILURE ) - closeStream(); + // if method failed, close the stream + if (methodResult == FAILURE) + closeStream(); - if ( !errorText_.empty() ) - error( errorType ); - return methodResult; + if (!errorText_.empty()) + error(errorType); + return methodResult; } //============================================================================= -DWORD WINAPI RtApiWasapi::runWasapiThread( void* wasapiPtr ) +DWORD WINAPI RtApiWasapi::runWasapiThread(void *wasapiPtr) { - if ( wasapiPtr ) - ( ( RtApiWasapi* ) wasapiPtr )->wasapiThread(); + if (wasapiPtr) + ((RtApiWasapi *)wasapiPtr)->wasapiThread(); - return 0; + return 0; } -DWORD WINAPI RtApiWasapi::stopWasapiThread( void* wasapiPtr ) +DWORD WINAPI RtApiWasapi::stopWasapiThread(void *wasapiPtr) { - if ( wasapiPtr ) - ( ( RtApiWasapi* ) wasapiPtr )->stopStream(); + if (wasapiPtr) + ((RtApiWasapi *)wasapiPtr)->stopStream(); - return 0; + return 0; } -DWORD WINAPI RtApiWasapi::abortWasapiThread( void* wasapiPtr ) +DWORD WINAPI RtApiWasapi::abortWasapiThread(void *wasapiPtr) { - if ( wasapiPtr ) - ( ( RtApiWasapi* ) wasapiPtr )->abortStream(); + if (wasapiPtr) + ((RtApiWasapi *)wasapiPtr)->abortStream(); - return 0; + return 0; } //----------------------------------------------------------------------------- void RtApiWasapi::wasapiThread() { - // as this is a new thread, we must CoInitialize it - CoInitialize( NULL ); + // as this is a new thread, we must CoInitialize it + CoInitialize(NULL); - HRESULT hr; + HRESULT hr; - IAudioClient* captureAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->captureAudioClient; - IAudioClient* renderAudioClient = ( ( WasapiHandle* ) stream_.apiHandle )->renderAudioClient; - IAudioCaptureClient* captureClient = ( ( WasapiHandle* ) stream_.apiHandle )->captureClient; - IAudioRenderClient* renderClient = ( ( WasapiHandle* ) stream_.apiHandle )->renderClient; - HANDLE captureEvent = ( ( WasapiHandle* ) stream_.apiHandle )->captureEvent; - HANDLE renderEvent = ( ( WasapiHandle* ) stream_.apiHandle )->renderEvent; + IAudioClient *captureAudioClient = ((WasapiHandle *)stream_.apiHandle)->captureAudioClient; + IAudioClient *renderAudioClient = ((WasapiHandle *)stream_.apiHandle)->renderAudioClient; + IAudioCaptureClient *captureClient = ((WasapiHandle *)stream_.apiHandle)->captureClient; + IAudioRenderClient *renderClient = ((WasapiHandle *)stream_.apiHandle)->renderClient; + HANDLE captureEvent = ((WasapiHandle *)stream_.apiHandle)->captureEvent; + HANDLE renderEvent = ((WasapiHandle *)stream_.apiHandle)->renderEvent; - WAVEFORMATEX* captureFormat = NULL; - WAVEFORMATEX* renderFormat = NULL; - float captureSrRatio = 0.0f; - float renderSrRatio = 0.0f; - WasapiBuffer captureBuffer; - WasapiBuffer renderBuffer; + WAVEFORMATEX *captureFormat = NULL; + WAVEFORMATEX *renderFormat = NULL; + float captureSrRatio = 0.0f; + float renderSrRatio = 0.0f; + WasapiBuffer captureBuffer; + WasapiBuffer renderBuffer; - // declare local stream variables - RtAudioCallback callback = ( RtAudioCallback ) stream_.callbackInfo.callback; - BYTE* streamBuffer = NULL; - unsigned long captureFlags = 0; - unsigned int bufferFrameCount = 0; - unsigned int numFramesPadding = 0; - unsigned int convBufferSize = 0; - bool callbackPushed = false; - bool callbackPulled = false; - bool callbackStopped = false; - int callbackResult = 0; + // declare local stream variables + RtAudioCallback callback = (RtAudioCallback)stream_.callbackInfo.callback; + BYTE *streamBuffer = NULL; + unsigned long captureFlags = 0; + unsigned int bufferFrameCount = 0; + unsigned int numFramesPadding = 0; + unsigned int convBufferSize = 0; + bool callbackPushed = false; + bool callbackPulled = false; + bool callbackStopped = false; + int callbackResult = 0; - // convBuffer is used to store converted buffers between WASAPI and the user - char* convBuffer = NULL; - unsigned int convBuffSize = 0; - unsigned int deviceBuffSize = 0; + // convBuffer is used to store converted buffers between WASAPI and the user + char *convBuffer = NULL; + unsigned int convBuffSize = 0; + unsigned int deviceBuffSize = 0; - errorText_.clear(); - RtAudioError::Type errorType = RtAudioError::DRIVER_ERROR; + errorText_.clear(); + RtAudioError::Type errorType = RtAudioError::DRIVER_ERROR; - // Attempt to assign "Pro Audio" characteristic to thread - HMODULE AvrtDll = LoadLibrary( (LPCTSTR) "AVRT.dll" ); - if ( AvrtDll ) { - DWORD taskIndex = 0; - TAvSetMmThreadCharacteristicsPtr AvSetMmThreadCharacteristicsPtr = ( TAvSetMmThreadCharacteristicsPtr ) GetProcAddress( AvrtDll, "AvSetMmThreadCharacteristicsW" ); - AvSetMmThreadCharacteristicsPtr( L"Pro Audio", &taskIndex ); - FreeLibrary( AvrtDll ); - } + // Attempt to assign "Pro Audio" characteristic to thread + HMODULE AvrtDll = LoadLibrary((LPCTSTR) "AVRT.dll"); + if (AvrtDll) + { + DWORD taskIndex = 0; + TAvSetMmThreadCharacteristicsPtr AvSetMmThreadCharacteristicsPtr = (TAvSetMmThreadCharacteristicsPtr)GetProcAddress(AvrtDll, "AvSetMmThreadCharacteristicsW"); + AvSetMmThreadCharacteristicsPtr(L"Pro Audio", &taskIndex); + FreeLibrary(AvrtDll); + } - // start capture stream if applicable - if ( captureAudioClient ) { - hr = captureAudioClient->GetMixFormat( &captureFormat ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve device mix format."; - goto Exit; - } + // start capture stream if applicable + if (captureAudioClient) + { + hr = captureAudioClient->GetMixFormat(&captureFormat); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve device mix format."; + goto Exit; + } - captureSrRatio = ( ( float ) captureFormat->nSamplesPerSec / stream_.sampleRate ); + captureSrRatio = ((float)captureFormat->nSamplesPerSec / stream_.sampleRate); - // initialize capture stream according to desire buffer size - float desiredBufferSize = stream_.bufferSize * captureSrRatio; - REFERENCE_TIME desiredBufferPeriod = ( REFERENCE_TIME ) ( ( float ) desiredBufferSize * 10000000 / captureFormat->nSamplesPerSec ); + // initialize capture stream according to desire buffer size + float desiredBufferSize = stream_.bufferSize * captureSrRatio; + REFERENCE_TIME desiredBufferPeriod = (REFERENCE_TIME)((float)desiredBufferSize * 10000000 / captureFormat->nSamplesPerSec); - if ( !captureClient ) { - hr = captureAudioClient->Initialize( AUDCLNT_SHAREMODE_SHARED, - AUDCLNT_STREAMFLAGS_EVENTCALLBACK, - desiredBufferPeriod, - desiredBufferPeriod, - captureFormat, - NULL ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to initialize capture audio client."; - goto Exit; - } + if (!captureClient) + { + hr = captureAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, + AUDCLNT_STREAMFLAGS_EVENTCALLBACK, + desiredBufferPeriod, + desiredBufferPeriod, + captureFormat, + NULL); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to initialize capture audio client."; + goto Exit; + } - hr = captureAudioClient->GetService( __uuidof( IAudioCaptureClient ), - ( void** ) &captureClient ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve capture client handle."; - goto Exit; - } + hr = captureAudioClient->GetService(__uuidof(IAudioCaptureClient), + (void **)&captureClient); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve capture client handle."; + goto Exit; + } - // configure captureEvent to trigger on every available capture buffer - captureEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); - if ( !captureEvent ) { - errorType = RtAudioError::SYSTEM_ERROR; - errorText_ = "RtApiWasapi::wasapiThread: Unable to create capture event."; - goto Exit; - } + // configure captureEvent to trigger on every available capture buffer + captureEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + if (!captureEvent) + { + errorType = RtAudioError::SYSTEM_ERROR; + errorText_ = "RtApiWasapi::wasapiThread: Unable to create capture event."; + goto Exit; + } - hr = captureAudioClient->SetEventHandle( captureEvent ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to set capture event handle."; - goto Exit; - } + hr = captureAudioClient->SetEventHandle(captureEvent); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to set capture event handle."; + goto Exit; + } - ( ( WasapiHandle* ) stream_.apiHandle )->captureClient = captureClient; - ( ( WasapiHandle* ) stream_.apiHandle )->captureEvent = captureEvent; - } + ((WasapiHandle *)stream_.apiHandle)->captureClient = captureClient; + ((WasapiHandle *)stream_.apiHandle)->captureEvent = captureEvent; + } - unsigned int inBufferSize = 0; - hr = captureAudioClient->GetBufferSize( &inBufferSize ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to get capture buffer size."; - goto Exit; - } + unsigned int inBufferSize = 0; + hr = captureAudioClient->GetBufferSize(&inBufferSize); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to get capture buffer size."; + goto Exit; + } - // scale outBufferSize according to stream->user sample rate ratio - unsigned int outBufferSize = ( unsigned int ) ( stream_.bufferSize * captureSrRatio ) * stream_.nDeviceChannels[INPUT]; - inBufferSize *= stream_.nDeviceChannels[INPUT]; + // scale outBufferSize according to stream->user sample rate ratio + unsigned int outBufferSize = (unsigned int)(stream_.bufferSize * captureSrRatio) * stream_.nDeviceChannels[INPUT]; + inBufferSize *= stream_.nDeviceChannels[INPUT]; - // set captureBuffer size - captureBuffer.setBufferSize( inBufferSize + outBufferSize, formatBytes( stream_.deviceFormat[INPUT] ) ); + // set captureBuffer size + captureBuffer.setBufferSize(inBufferSize + outBufferSize, formatBytes(stream_.deviceFormat[INPUT])); - // reset the capture stream - hr = captureAudioClient->Reset(); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to reset capture stream."; - goto Exit; - } + // reset the capture stream + hr = captureAudioClient->Reset(); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to reset capture stream."; + goto Exit; + } - // start the capture stream - hr = captureAudioClient->Start(); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to start capture stream."; - goto Exit; - } - } + // start the capture stream + hr = captureAudioClient->Start(); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to start capture stream."; + goto Exit; + } + } - // start render stream if applicable - if ( renderAudioClient ) { - hr = renderAudioClient->GetMixFormat( &renderFormat ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve device mix format."; - goto Exit; - } + // start render stream if applicable + if (renderAudioClient) + { + hr = renderAudioClient->GetMixFormat(&renderFormat); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve device mix format."; + goto Exit; + } - renderSrRatio = ( ( float ) renderFormat->nSamplesPerSec / stream_.sampleRate ); + renderSrRatio = ((float)renderFormat->nSamplesPerSec / stream_.sampleRate); - // initialize render stream according to desire buffer size - float desiredBufferSize = stream_.bufferSize * renderSrRatio; - REFERENCE_TIME desiredBufferPeriod = ( REFERENCE_TIME ) ( ( float ) desiredBufferSize * 10000000 / renderFormat->nSamplesPerSec ); + // initialize render stream according to desire buffer size + float desiredBufferSize = stream_.bufferSize * renderSrRatio; + REFERENCE_TIME desiredBufferPeriod = (REFERENCE_TIME)((float)desiredBufferSize * 10000000 / renderFormat->nSamplesPerSec); - if ( !renderClient ) { - hr = renderAudioClient->Initialize( AUDCLNT_SHAREMODE_SHARED, - AUDCLNT_STREAMFLAGS_EVENTCALLBACK, - desiredBufferPeriod, - desiredBufferPeriod, - renderFormat, - NULL ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to initialize render audio client."; - goto Exit; - } + if (!renderClient) + { + hr = renderAudioClient->Initialize(AUDCLNT_SHAREMODE_SHARED, + AUDCLNT_STREAMFLAGS_EVENTCALLBACK, + desiredBufferPeriod, + desiredBufferPeriod, + renderFormat, + NULL); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to initialize render audio client."; + goto Exit; + } - hr = renderAudioClient->GetService( __uuidof( IAudioRenderClient ), - ( void** ) &renderClient ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve render client handle."; - goto Exit; - } + hr = renderAudioClient->GetService(__uuidof(IAudioRenderClient), + (void **)&renderClient); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve render client handle."; + goto Exit; + } - // configure renderEvent to trigger on every available render buffer - renderEvent = CreateEvent( NULL, FALSE, FALSE, NULL ); - if ( !renderEvent ) { - errorType = RtAudioError::SYSTEM_ERROR; - errorText_ = "RtApiWasapi::wasapiThread: Unable to create render event."; - goto Exit; - } + // configure renderEvent to trigger on every available render buffer + renderEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + if (!renderEvent) + { + errorType = RtAudioError::SYSTEM_ERROR; + errorText_ = "RtApiWasapi::wasapiThread: Unable to create render event."; + goto Exit; + } - hr = renderAudioClient->SetEventHandle( renderEvent ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to set render event handle."; - goto Exit; - } + hr = renderAudioClient->SetEventHandle(renderEvent); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to set render event handle."; + goto Exit; + } - ( ( WasapiHandle* ) stream_.apiHandle )->renderClient = renderClient; - ( ( WasapiHandle* ) stream_.apiHandle )->renderEvent = renderEvent; - } + ((WasapiHandle *)stream_.apiHandle)->renderClient = renderClient; + ((WasapiHandle *)stream_.apiHandle)->renderEvent = renderEvent; + } - unsigned int outBufferSize = 0; - hr = renderAudioClient->GetBufferSize( &outBufferSize ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to get render buffer size."; - goto Exit; - } + unsigned int outBufferSize = 0; + hr = renderAudioClient->GetBufferSize(&outBufferSize); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to get render buffer size."; + goto Exit; + } - // scale inBufferSize according to user->stream sample rate ratio - unsigned int inBufferSize = ( unsigned int ) ( stream_.bufferSize * renderSrRatio ) * stream_.nDeviceChannels[OUTPUT]; - outBufferSize *= stream_.nDeviceChannels[OUTPUT]; + // scale inBufferSize according to user->stream sample rate ratio + unsigned int inBufferSize = (unsigned int)(stream_.bufferSize * renderSrRatio) * stream_.nDeviceChannels[OUTPUT]; + outBufferSize *= stream_.nDeviceChannels[OUTPUT]; - // set renderBuffer size - renderBuffer.setBufferSize( inBufferSize + outBufferSize, formatBytes( stream_.deviceFormat[OUTPUT] ) ); + // set renderBuffer size + renderBuffer.setBufferSize(inBufferSize + outBufferSize, formatBytes(stream_.deviceFormat[OUTPUT])); - // reset the render stream - hr = renderAudioClient->Reset(); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to reset render stream."; - goto Exit; - } + // reset the render stream + hr = renderAudioClient->Reset(); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to reset render stream."; + goto Exit; + } - // start the render stream - hr = renderAudioClient->Start(); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to start render stream."; - goto Exit; - } - } + // start the render stream + hr = renderAudioClient->Start(); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to start render stream."; + goto Exit; + } + } - if ( stream_.mode == INPUT ) { - convBuffSize = ( size_t ) ( stream_.bufferSize * captureSrRatio ) * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] ); - deviceBuffSize = stream_.bufferSize * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] ); - } - else if ( stream_.mode == OUTPUT ) { - convBuffSize = ( size_t ) ( stream_.bufferSize * renderSrRatio ) * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] ); - deviceBuffSize = stream_.bufferSize * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] ); - } - else if ( stream_.mode == DUPLEX ) { - convBuffSize = std::max( ( size_t ) ( stream_.bufferSize * captureSrRatio ) * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] ), - ( size_t ) ( stream_.bufferSize * renderSrRatio ) * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] ) ); - deviceBuffSize = std::max( stream_.bufferSize * stream_.nDeviceChannels[INPUT] * formatBytes( stream_.deviceFormat[INPUT] ), - stream_.bufferSize * stream_.nDeviceChannels[OUTPUT] * formatBytes( stream_.deviceFormat[OUTPUT] ) ); - } + if (stream_.mode == INPUT) + { + convBuffSize = (size_t)(stream_.bufferSize * captureSrRatio) * stream_.nDeviceChannels[INPUT] * formatBytes(stream_.deviceFormat[INPUT]); + deviceBuffSize = stream_.bufferSize * stream_.nDeviceChannels[INPUT] * formatBytes(stream_.deviceFormat[INPUT]); + } + else if (stream_.mode == OUTPUT) + { + convBuffSize = (size_t)(stream_.bufferSize * renderSrRatio) * stream_.nDeviceChannels[OUTPUT] * formatBytes(stream_.deviceFormat[OUTPUT]); + deviceBuffSize = stream_.bufferSize * stream_.nDeviceChannels[OUTPUT] * formatBytes(stream_.deviceFormat[OUTPUT]); + } + else if (stream_.mode == DUPLEX) + { + convBuffSize = std::max((size_t)(stream_.bufferSize * captureSrRatio) * stream_.nDeviceChannels[INPUT] * formatBytes(stream_.deviceFormat[INPUT]), + (size_t)(stream_.bufferSize * renderSrRatio) * stream_.nDeviceChannels[OUTPUT] * formatBytes(stream_.deviceFormat[OUTPUT])); + deviceBuffSize = std::max(stream_.bufferSize * stream_.nDeviceChannels[INPUT] * formatBytes(stream_.deviceFormat[INPUT]), + stream_.bufferSize * stream_.nDeviceChannels[OUTPUT] * formatBytes(stream_.deviceFormat[OUTPUT])); + } - convBuffer = ( char* ) malloc( convBuffSize ); - stream_.deviceBuffer = ( char* ) malloc( deviceBuffSize ); - if ( !convBuffer || !stream_.deviceBuffer ) { - errorType = RtAudioError::MEMORY_ERROR; - errorText_ = "RtApiWasapi::wasapiThread: Error allocating device buffer memory."; - goto Exit; - } + convBuffer = (char *)malloc(convBuffSize); + stream_.deviceBuffer = (char *)malloc(deviceBuffSize); + if (!convBuffer || !stream_.deviceBuffer) + { + errorType = RtAudioError::MEMORY_ERROR; + errorText_ = "RtApiWasapi::wasapiThread: Error allocating device buffer memory."; + goto Exit; + } - // stream process loop - while ( stream_.state != STREAM_STOPPING ) { - if ( !callbackPulled ) { - // Callback Input - // ============== - // 1. Pull callback buffer from inputBuffer - // 2. If 1. was successful: Convert callback buffer to user sample rate and channel count - // Convert callback buffer to user format + // stream process loop + while (stream_.state != STREAM_STOPPING) + { + if (!callbackPulled) + { + // Callback Input + // ============== + // 1. Pull callback buffer from inputBuffer + // 2. If 1. was successful: Convert callback buffer to user sample rate and channel count + // Convert callback buffer to user format - if ( captureAudioClient ) { - // Pull callback buffer from inputBuffer - callbackPulled = captureBuffer.pullBuffer( convBuffer, - ( unsigned int ) ( stream_.bufferSize * captureSrRatio ) * stream_.nDeviceChannels[INPUT], - stream_.deviceFormat[INPUT] ); + if (captureAudioClient) + { + // Pull callback buffer from inputBuffer + callbackPulled = captureBuffer.pullBuffer(convBuffer, + (unsigned int)(stream_.bufferSize * captureSrRatio) * stream_.nDeviceChannels[INPUT], + stream_.deviceFormat[INPUT]); - if ( callbackPulled ) { - // Convert callback buffer to user sample rate - convertBufferWasapi( stream_.deviceBuffer, - convBuffer, - stream_.nDeviceChannels[INPUT], - captureFormat->nSamplesPerSec, - stream_.sampleRate, - ( unsigned int ) ( stream_.bufferSize * captureSrRatio ), - convBufferSize, - stream_.deviceFormat[INPUT] ); + if (callbackPulled) + { + // Convert callback buffer to user sample rate + convertBufferWasapi(stream_.deviceBuffer, + convBuffer, + stream_.nDeviceChannels[INPUT], + captureFormat->nSamplesPerSec, + stream_.sampleRate, + (unsigned int)(stream_.bufferSize * captureSrRatio), + convBufferSize, + stream_.deviceFormat[INPUT]); - if ( stream_.doConvertBuffer[INPUT] ) { - // Convert callback buffer to user format - convertBuffer( stream_.userBuffer[INPUT], - stream_.deviceBuffer, - stream_.convertInfo[INPUT] ); - } - else { - // no further conversion, simple copy deviceBuffer to userBuffer - memcpy( stream_.userBuffer[INPUT], - stream_.deviceBuffer, - stream_.bufferSize * stream_.nUserChannels[INPUT] * formatBytes( stream_.userFormat ) ); - } - } - } - else { - // if there is no capture stream, set callbackPulled flag - callbackPulled = true; - } + if (stream_.doConvertBuffer[INPUT]) + { + // Convert callback buffer to user format + convertBuffer(stream_.userBuffer[INPUT], + stream_.deviceBuffer, + stream_.convertInfo[INPUT]); + } + else + { + // no further conversion, simple copy deviceBuffer to userBuffer + memcpy(stream_.userBuffer[INPUT], + stream_.deviceBuffer, + stream_.bufferSize * stream_.nUserChannels[INPUT] * formatBytes(stream_.userFormat)); + } + } + } + else + { + // if there is no capture stream, set callbackPulled flag + callbackPulled = true; + } - // Execute Callback - // ================ - // 1. Execute user callback method - // 2. Handle return value from callback + // Execute Callback + // ================ + // 1. Execute user callback method + // 2. Handle return value from callback - // if callback has not requested the stream to stop - if ( callbackPulled && !callbackStopped ) { - // Execute user callback method - callbackResult = callback( stream_.userBuffer[OUTPUT], - stream_.userBuffer[INPUT], - stream_.bufferSize, - getStreamTime(), - captureFlags & AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY ? RTAUDIO_INPUT_OVERFLOW : 0, - stream_.callbackInfo.userData ); + // if callback has not requested the stream to stop + if (callbackPulled && !callbackStopped) + { + // Execute user callback method + callbackResult = callback(stream_.userBuffer[OUTPUT], + stream_.userBuffer[INPUT], + stream_.bufferSize, + getStreamTime(), + captureFlags & AUDCLNT_BUFFERFLAGS_DATA_DISCONTINUITY ? RTAUDIO_INPUT_OVERFLOW : 0, + stream_.callbackInfo.userData); - // Handle return value from callback - if ( callbackResult == 1 ) { - // instantiate a thread to stop this thread - HANDLE threadHandle = CreateThread( NULL, 0, stopWasapiThread, this, 0, NULL ); - if ( !threadHandle ) { - errorType = RtAudioError::THREAD_ERROR; - errorText_ = "RtApiWasapi::wasapiThread: Unable to instantiate stream stop thread."; - goto Exit; - } - else if ( !CloseHandle( threadHandle ) ) { - errorType = RtAudioError::THREAD_ERROR; - errorText_ = "RtApiWasapi::wasapiThread: Unable to close stream stop thread handle."; - goto Exit; - } + // Handle return value from callback + if (callbackResult == 1) + { + // instantiate a thread to stop this thread + HANDLE threadHandle = CreateThread(NULL, 0, stopWasapiThread, this, 0, NULL); + if (!threadHandle) + { + errorType = RtAudioError::THREAD_ERROR; + errorText_ = "RtApiWasapi::wasapiThread: Unable to instantiate stream stop thread."; + goto Exit; + } + else if (!CloseHandle(threadHandle)) + { + errorType = RtAudioError::THREAD_ERROR; + errorText_ = "RtApiWasapi::wasapiThread: Unable to close stream stop thread handle."; + goto Exit; + } - callbackStopped = true; - } - else if ( callbackResult == 2 ) { - // instantiate a thread to stop this thread - HANDLE threadHandle = CreateThread( NULL, 0, abortWasapiThread, this, 0, NULL ); - if ( !threadHandle ) { - errorType = RtAudioError::THREAD_ERROR; - errorText_ = "RtApiWasapi::wasapiThread: Unable to instantiate stream abort thread."; - goto Exit; - } - else if ( !CloseHandle( threadHandle ) ) { - errorType = RtAudioError::THREAD_ERROR; - errorText_ = "RtApiWasapi::wasapiThread: Unable to close stream abort thread handle."; - goto Exit; - } + callbackStopped = true; + } + else if (callbackResult == 2) + { + // instantiate a thread to stop this thread + HANDLE threadHandle = CreateThread(NULL, 0, abortWasapiThread, this, 0, NULL); + if (!threadHandle) + { + errorType = RtAudioError::THREAD_ERROR; + errorText_ = "RtApiWasapi::wasapiThread: Unable to instantiate stream abort thread."; + goto Exit; + } + else if (!CloseHandle(threadHandle)) + { + errorType = RtAudioError::THREAD_ERROR; + errorText_ = "RtApiWasapi::wasapiThread: Unable to close stream abort thread handle."; + goto Exit; + } - callbackStopped = true; - } - } - } + callbackStopped = true; + } + } + } - // Callback Output - // =============== - // 1. Convert callback buffer to stream format - // 2. Convert callback buffer to stream sample rate and channel count - // 3. Push callback buffer into outputBuffer + // Callback Output + // =============== + // 1. Convert callback buffer to stream format + // 2. Convert callback buffer to stream sample rate and channel count + // 3. Push callback buffer into outputBuffer - if ( renderAudioClient && callbackPulled ) { - if ( stream_.doConvertBuffer[OUTPUT] ) { - // Convert callback buffer to stream format - convertBuffer( stream_.deviceBuffer, - stream_.userBuffer[OUTPUT], - stream_.convertInfo[OUTPUT] ); + if (renderAudioClient && callbackPulled) + { + if (stream_.doConvertBuffer[OUTPUT]) + { + // Convert callback buffer to stream format + convertBuffer(stream_.deviceBuffer, + stream_.userBuffer[OUTPUT], + stream_.convertInfo[OUTPUT]); + } - } + // Convert callback buffer to stream sample rate + convertBufferWasapi(convBuffer, + stream_.deviceBuffer, + stream_.nDeviceChannels[OUTPUT], + stream_.sampleRate, + renderFormat->nSamplesPerSec, + stream_.bufferSize, + convBufferSize, + stream_.deviceFormat[OUTPUT]); - // Convert callback buffer to stream sample rate - convertBufferWasapi( convBuffer, - stream_.deviceBuffer, - stream_.nDeviceChannels[OUTPUT], - stream_.sampleRate, - renderFormat->nSamplesPerSec, - stream_.bufferSize, - convBufferSize, - stream_.deviceFormat[OUTPUT] ); + // Push callback buffer into outputBuffer + callbackPushed = renderBuffer.pushBuffer(convBuffer, + convBufferSize * stream_.nDeviceChannels[OUTPUT], + stream_.deviceFormat[OUTPUT]); + } + else + { + // if there is no render stream, set callbackPushed flag + callbackPushed = true; + } - // Push callback buffer into outputBuffer - callbackPushed = renderBuffer.pushBuffer( convBuffer, - convBufferSize * stream_.nDeviceChannels[OUTPUT], - stream_.deviceFormat[OUTPUT] ); - } - else { - // if there is no render stream, set callbackPushed flag - callbackPushed = true; - } + // Stream Capture + // ============== + // 1. Get capture buffer from stream + // 2. Push capture buffer into inputBuffer + // 3. If 2. was successful: Release capture buffer - // Stream Capture - // ============== - // 1. Get capture buffer from stream - // 2. Push capture buffer into inputBuffer - // 3. If 2. was successful: Release capture buffer + if (captureAudioClient) + { + // if the callback input buffer was not pulled from captureBuffer, wait for next capture event + if (!callbackPulled) + { + WaitForSingleObject(captureEvent, INFINITE); + } - if ( captureAudioClient ) { - // if the callback input buffer was not pulled from captureBuffer, wait for next capture event - if ( !callbackPulled ) { - WaitForSingleObject( captureEvent, INFINITE ); - } + // Get capture buffer from stream + hr = captureClient->GetBuffer(&streamBuffer, + &bufferFrameCount, + &captureFlags, NULL, NULL); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve capture buffer."; + goto Exit; + } - // Get capture buffer from stream - hr = captureClient->GetBuffer( &streamBuffer, - &bufferFrameCount, - &captureFlags, NULL, NULL ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve capture buffer."; - goto Exit; - } + if (bufferFrameCount != 0) + { + // Push capture buffer into inputBuffer + if (captureBuffer.pushBuffer((char *)streamBuffer, + bufferFrameCount * stream_.nDeviceChannels[INPUT], + stream_.deviceFormat[INPUT])) + { + // Release capture buffer + hr = captureClient->ReleaseBuffer(bufferFrameCount); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to release capture buffer."; + goto Exit; + } + } + else + { + // Inform WASAPI that capture was unsuccessful + hr = captureClient->ReleaseBuffer(0); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to release capture buffer."; + goto Exit; + } + } + } + else + { + // Inform WASAPI that capture was unsuccessful + hr = captureClient->ReleaseBuffer(0); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to release capture buffer."; + goto Exit; + } + } + } - if ( bufferFrameCount != 0 ) { - // Push capture buffer into inputBuffer - if ( captureBuffer.pushBuffer( ( char* ) streamBuffer, - bufferFrameCount * stream_.nDeviceChannels[INPUT], - stream_.deviceFormat[INPUT] ) ) - { - // Release capture buffer - hr = captureClient->ReleaseBuffer( bufferFrameCount ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to release capture buffer."; - goto Exit; - } - } - else - { - // Inform WASAPI that capture was unsuccessful - hr = captureClient->ReleaseBuffer( 0 ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to release capture buffer."; - goto Exit; - } - } - } - else - { - // Inform WASAPI that capture was unsuccessful - hr = captureClient->ReleaseBuffer( 0 ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to release capture buffer."; - goto Exit; - } - } - } + // Stream Render + // ============= + // 1. Get render buffer from stream + // 2. Pull next buffer from outputBuffer + // 3. If 2. was successful: Fill render buffer with next buffer + // Release render buffer - // Stream Render - // ============= - // 1. Get render buffer from stream - // 2. Pull next buffer from outputBuffer - // 3. If 2. was successful: Fill render buffer with next buffer - // Release render buffer + if (renderAudioClient) + { + // if the callback output buffer was not pushed to renderBuffer, wait for next render event + if (callbackPulled && !callbackPushed) + { + WaitForSingleObject(renderEvent, INFINITE); + } - if ( renderAudioClient ) { - // if the callback output buffer was not pushed to renderBuffer, wait for next render event - if ( callbackPulled && !callbackPushed ) { - WaitForSingleObject( renderEvent, INFINITE ); - } + // Get render buffer from stream + hr = renderAudioClient->GetBufferSize(&bufferFrameCount); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve render buffer size."; + goto Exit; + } - // Get render buffer from stream - hr = renderAudioClient->GetBufferSize( &bufferFrameCount ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve render buffer size."; - goto Exit; - } + hr = renderAudioClient->GetCurrentPadding(&numFramesPadding); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve render buffer padding."; + goto Exit; + } - hr = renderAudioClient->GetCurrentPadding( &numFramesPadding ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve render buffer padding."; - goto Exit; - } + bufferFrameCount -= numFramesPadding; - bufferFrameCount -= numFramesPadding; + if (bufferFrameCount != 0) + { + hr = renderClient->GetBuffer(bufferFrameCount, &streamBuffer); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve render buffer."; + goto Exit; + } - if ( bufferFrameCount != 0 ) { - hr = renderClient->GetBuffer( bufferFrameCount, &streamBuffer ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to retrieve render buffer."; - goto Exit; - } + // Pull next buffer from outputBuffer + // Fill render buffer with next buffer + if (renderBuffer.pullBuffer((char *)streamBuffer, + bufferFrameCount * stream_.nDeviceChannels[OUTPUT], + stream_.deviceFormat[OUTPUT])) + { + // Release render buffer + hr = renderClient->ReleaseBuffer(bufferFrameCount, 0); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to release render buffer."; + goto Exit; + } + } + else + { + // Inform WASAPI that render was unsuccessful + hr = renderClient->ReleaseBuffer(0, 0); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to release render buffer."; + goto Exit; + } + } + } + else + { + // Inform WASAPI that render was unsuccessful + hr = renderClient->ReleaseBuffer(0, 0); + if (FAILED(hr)) + { + errorText_ = "RtApiWasapi::wasapiThread: Unable to release render buffer."; + goto Exit; + } + } + } - // Pull next buffer from outputBuffer - // Fill render buffer with next buffer - if ( renderBuffer.pullBuffer( ( char* ) streamBuffer, - bufferFrameCount * stream_.nDeviceChannels[OUTPUT], - stream_.deviceFormat[OUTPUT] ) ) - { - // Release render buffer - hr = renderClient->ReleaseBuffer( bufferFrameCount, 0 ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to release render buffer."; - goto Exit; - } - } - else - { - // Inform WASAPI that render was unsuccessful - hr = renderClient->ReleaseBuffer( 0, 0 ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to release render buffer."; - goto Exit; - } - } - } - else - { - // Inform WASAPI that render was unsuccessful - hr = renderClient->ReleaseBuffer( 0, 0 ); - if ( FAILED( hr ) ) { - errorText_ = "RtApiWasapi::wasapiThread: Unable to release render buffer."; - goto Exit; - } - } - } - - // if the callback buffer was pushed renderBuffer reset callbackPulled flag - if ( callbackPushed ) { - callbackPulled = false; - // tick stream time - RtApi::tickStreamTime(); - } - - } + // if the callback buffer was pushed renderBuffer reset callbackPulled flag + if (callbackPushed) + { + callbackPulled = false; + // tick stream time + RtApi::tickStreamTime(); + } + } Exit: - // clean up - CoTaskMemFree( captureFormat ); - CoTaskMemFree( renderFormat ); + // clean up + CoTaskMemFree(captureFormat); + CoTaskMemFree(renderFormat); - free ( convBuffer ); + free(convBuffer); - CoUninitialize(); + CoUninitialize(); - // update stream state - stream_.state = STREAM_STOPPED; + // update stream state + stream_.state = STREAM_STOPPED; - if ( errorText_.empty() ) - return; - else - error( errorType ); + if (errorText_.empty()) + return; + else + error(errorType); } //******************** End of __WINDOWS_WASAPI__ *********************// #endif - -#if defined(__WINDOWS_DS__) // Windows DirectSound API +#if defined(__WINDOWS_DS__) // Windows DirectSound API // Modified by Robin Davies, October 2005 -// - Improvements to DirectX pointer chasing. +// - Improvements to DirectX pointer chasing. // - Bug fix for non-power-of-two Asio granularity used by Edirol PCR-A30. // - Auto-call CoInitialize for DSOUND and ASIO platforms. // Various revisions for RtAudio 4.0 by Gary Scavone, April 2007 @@ -5200,7 +5694,7 @@ Exit: #include #if defined(__MINGW32__) - // missing from latest mingw winapi +// missing from latest mingw winapi #define WAVE_FORMAT_96M08 0x00010000 /* 96 kHz, Mono, 8-bit */ #define WAVE_FORMAT_96S08 0x00020000 /* 96 kHz, Stereo, 8-bit */ #define WAVE_FORMAT_96M16 0x00040000 /* 96 kHz, Mono, 16-bit */ @@ -5209,2881 +5703,3190 @@ Exit: #define MINIMUM_DEVICE_BUFFER_SIZE 32768 -#ifdef _MSC_VER // if Microsoft Visual C++ -#pragma comment( lib, "winmm.lib" ) // then, auto-link winmm.lib. Otherwise, it has to be added manually. +#ifdef _MSC_VER // if Microsoft Visual C++ +#pragma comment(lib, "winmm.lib") // then, auto-link winmm.lib. Otherwise, it has to be added manually. #endif -static inline DWORD dsPointerBetween( DWORD pointer, DWORD laterPointer, DWORD earlierPointer, DWORD bufferSize ) +static inline DWORD dsPointerBetween(DWORD pointer, DWORD laterPointer, DWORD earlierPointer, DWORD bufferSize) { - if ( pointer > bufferSize ) pointer -= bufferSize; - if ( laterPointer < earlierPointer ) laterPointer += bufferSize; - if ( pointer < earlierPointer ) pointer += bufferSize; - return pointer >= earlierPointer && pointer < laterPointer; + if (pointer > bufferSize) pointer -= bufferSize; + if (laterPointer < earlierPointer) laterPointer += bufferSize; + if (pointer < earlierPointer) pointer += bufferSize; + return pointer >= earlierPointer && pointer < laterPointer; } // A structure to hold various information related to the DirectSound // API implementation. -struct DsHandle { - unsigned int drainCounter; // Tracks callback counts when draining - bool internalDrain; // Indicates if stop is initiated from callback or not. - void *id[2]; - void *buffer[2]; - bool xrun[2]; - UINT bufferPointer[2]; - DWORD dsBufferSize[2]; - DWORD dsPointerLeadTime[2]; // the number of bytes ahead of the safe pointer to lead by. - HANDLE condition; +struct DsHandle +{ + unsigned int drainCounter; // Tracks callback counts when draining + bool internalDrain; // Indicates if stop is initiated from callback or not. + void *id[2]; + void *buffer[2]; + bool xrun[2]; + UINT bufferPointer[2]; + DWORD dsBufferSize[2]; + DWORD dsPointerLeadTime[2]; // the number of bytes ahead of the safe pointer to lead by. + HANDLE condition; - DsHandle() - :drainCounter(0), internalDrain(false) { id[0] = 0; id[1] = 0; buffer[0] = 0; buffer[1] = 0; xrun[0] = false; xrun[1] = false; bufferPointer[0] = 0; bufferPointer[1] = 0; } + DsHandle() + : drainCounter(0), internalDrain(false) + { + id[0] = 0; + id[1] = 0; + buffer[0] = 0; + buffer[1] = 0; + xrun[0] = false; + xrun[1] = false; + bufferPointer[0] = 0; + bufferPointer[1] = 0; + } }; // Declarations for utility functions, callbacks, and structures // specific to the DirectSound implementation. -static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid, - LPCTSTR description, - LPCTSTR module, - LPVOID lpContext ); +static BOOL CALLBACK deviceQueryCallback(LPGUID lpguid, + LPCTSTR description, + LPCTSTR module, + LPVOID lpContext); -static const char* getErrorString( int code ); +static const char *getErrorString(int code); -static unsigned __stdcall callbackHandler( void *ptr ); +static unsigned __stdcall callbackHandler(void *ptr); -struct DsDevice { - LPGUID id[2]; - bool validId[2]; - bool found; - std::string name; - - DsDevice() - : found(false) { validId[0] = false; validId[1] = false; } -}; - -struct DsProbeData { - bool isInput; - std::vector* dsDevices; -}; - -RtApiDs :: RtApiDs() +struct DsDevice { - // Dsound will run both-threaded. If CoInitialize fails, then just - // accept whatever the mainline chose for a threading model. - coInitialized_ = false; - HRESULT hr = CoInitialize( NULL ); - if ( !FAILED( hr ) ) coInitialized_ = true; + LPGUID id[2]; + bool validId[2]; + bool found; + std::string name; + + DsDevice() + : found(false) + { + validId[0] = false; + validId[1] = false; + } +}; + +struct DsProbeData +{ + bool isInput; + std::vector *dsDevices; +}; + +RtApiDs ::RtApiDs() +{ + // Dsound will run both-threaded. If CoInitialize fails, then just + // accept whatever the mainline chose for a threading model. + coInitialized_ = false; + HRESULT hr = CoInitialize(NULL); + if (!FAILED(hr)) coInitialized_ = true; } -RtApiDs :: ~RtApiDs() +RtApiDs ::~RtApiDs() { - if ( coInitialized_ ) CoUninitialize(); // balanced call. - if ( stream_.state != STREAM_CLOSED ) closeStream(); + if (coInitialized_) CoUninitialize(); // balanced call. + if (stream_.state != STREAM_CLOSED) closeStream(); } // The DirectSound default output is always the first device. -unsigned int RtApiDs :: getDefaultOutputDevice( void ) +unsigned int RtApiDs ::getDefaultOutputDevice(void) { - return 0; + return 0; } // The DirectSound default input is always the first input device, // which is the first capture device enumerated. -unsigned int RtApiDs :: getDefaultInputDevice( void ) +unsigned int RtApiDs ::getDefaultInputDevice(void) { - return 0; + return 0; } -unsigned int RtApiDs :: getDeviceCount( void ) +unsigned int RtApiDs ::getDeviceCount(void) { - // Set query flag for previously found devices to false, so that we - // can check for any devices that have disappeared. - for ( unsigned int i=0; i(dsDevices.size()); + return static_cast(dsDevices.size()); } -RtAudio::DeviceInfo RtApiDs :: getDeviceInfo( unsigned int device ) +RtAudio::DeviceInfo RtApiDs ::getDeviceInfo(unsigned int device) { - RtAudio::DeviceInfo info; - info.probed = false; + RtAudio::DeviceInfo info; + info.probed = false; - if ( dsDevices.size() == 0 ) { - // Force a query of all devices - getDeviceCount(); - if ( dsDevices.size() == 0 ) { - errorText_ = "RtApiDs::getDeviceInfo: no devices found!"; - error( RtAudioError::INVALID_USE ); - return info; - } - } + if (dsDevices.size() == 0) + { + // Force a query of all devices + getDeviceCount(); + if (dsDevices.size() == 0) + { + errorText_ = "RtApiDs::getDeviceInfo: no devices found!"; + error(RtAudioError::INVALID_USE); + return info; + } + } - if ( device >= dsDevices.size() ) { - errorText_ = "RtApiDs::getDeviceInfo: device ID is invalid!"; - error( RtAudioError::INVALID_USE ); - return info; - } + if (device >= dsDevices.size()) + { + errorText_ = "RtApiDs::getDeviceInfo: device ID is invalid!"; + error(RtAudioError::INVALID_USE); + return info; + } - HRESULT result; - if ( dsDevices[ device ].validId[0] == false ) goto probeInput; + HRESULT result; + if (dsDevices[device].validId[0] == false) goto probeInput; - LPDIRECTSOUND output; - DSCAPS outCaps; - result = DirectSoundCreate( dsDevices[ device ].id[0], &output, NULL ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString( result ) << ") opening output device (" << dsDevices[ device ].name << ")!"; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - goto probeInput; - } + LPDIRECTSOUND output; + DSCAPS outCaps; + result = DirectSoundCreate(dsDevices[device].id[0], &output, NULL); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString(result) << ") opening output device (" << dsDevices[device].name << ")!"; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + goto probeInput; + } - outCaps.dwSize = sizeof( outCaps ); - result = output->GetCaps( &outCaps ); - if ( FAILED( result ) ) { - output->Release(); - errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString( result ) << ") getting capabilities!"; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - goto probeInput; - } + outCaps.dwSize = sizeof(outCaps); + result = output->GetCaps(&outCaps); + if (FAILED(result)) + { + output->Release(); + errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString(result) << ") getting capabilities!"; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + goto probeInput; + } - // Get output channel information. - info.outputChannels = ( outCaps.dwFlags & DSCAPS_PRIMARYSTEREO ) ? 2 : 1; + // Get output channel information. + info.outputChannels = (outCaps.dwFlags & DSCAPS_PRIMARYSTEREO) ? 2 : 1; - // Get sample rate information. - info.sampleRates.clear(); - for ( unsigned int k=0; k= (unsigned int) outCaps.dwMinSecondarySampleRate && - SAMPLE_RATES[k] <= (unsigned int) outCaps.dwMaxSecondarySampleRate ) { - info.sampleRates.push_back( SAMPLE_RATES[k] ); + // Get sample rate information. + info.sampleRates.clear(); + for (unsigned int k = 0; k < MAX_SAMPLE_RATES; k++) + { + if (SAMPLE_RATES[k] >= (unsigned int)outCaps.dwMinSecondarySampleRate && + SAMPLE_RATES[k] <= (unsigned int)outCaps.dwMaxSecondarySampleRate) + { + info.sampleRates.push_back(SAMPLE_RATES[k]); - if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) ) - info.preferredSampleRate = SAMPLE_RATES[k]; - } - } + if (!info.preferredSampleRate || (SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate)) + info.preferredSampleRate = SAMPLE_RATES[k]; + } + } - // Get format information. - if ( outCaps.dwFlags & DSCAPS_PRIMARY16BIT ) info.nativeFormats |= RTAUDIO_SINT16; - if ( outCaps.dwFlags & DSCAPS_PRIMARY8BIT ) info.nativeFormats |= RTAUDIO_SINT8; + // Get format information. + if (outCaps.dwFlags & DSCAPS_PRIMARY16BIT) info.nativeFormats |= RTAUDIO_SINT16; + if (outCaps.dwFlags & DSCAPS_PRIMARY8BIT) info.nativeFormats |= RTAUDIO_SINT8; - output->Release(); + output->Release(); - if ( getDefaultOutputDevice() == device ) - info.isDefaultOutput = true; + if (getDefaultOutputDevice() == device) + info.isDefaultOutput = true; - if ( dsDevices[ device ].validId[1] == false ) { - info.name = dsDevices[ device ].name; - info.probed = true; - return info; - } + if (dsDevices[device].validId[1] == false) + { + info.name = dsDevices[device].name; + info.probed = true; + return info; + } - probeInput: +probeInput: - LPDIRECTSOUNDCAPTURE input; - result = DirectSoundCaptureCreate( dsDevices[ device ].id[1], &input, NULL ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString( result ) << ") opening input device (" << dsDevices[ device ].name << ")!"; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + LPDIRECTSOUNDCAPTURE input; + result = DirectSoundCaptureCreate(dsDevices[device].id[1], &input, NULL); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString(result) << ") opening input device (" << dsDevices[device].name << ")!"; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - DSCCAPS inCaps; - inCaps.dwSize = sizeof( inCaps ); - result = input->GetCaps( &inCaps ); - if ( FAILED( result ) ) { - input->Release(); - errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString( result ) << ") getting object capabilities (" << dsDevices[ device ].name << ")!"; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + DSCCAPS inCaps; + inCaps.dwSize = sizeof(inCaps); + result = input->GetCaps(&inCaps); + if (FAILED(result)) + { + input->Release(); + errorStream_ << "RtApiDs::getDeviceInfo: error (" << getErrorString(result) << ") getting object capabilities (" << dsDevices[device].name << ")!"; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - // Get input channel information. - info.inputChannels = inCaps.dwChannels; + // Get input channel information. + info.inputChannels = inCaps.dwChannels; - // Get sample rate and format information. - std::vector rates; - if ( inCaps.dwChannels >= 2 ) { - if ( inCaps.dwFormats & WAVE_FORMAT_1S16 ) info.nativeFormats |= RTAUDIO_SINT16; - if ( inCaps.dwFormats & WAVE_FORMAT_2S16 ) info.nativeFormats |= RTAUDIO_SINT16; - if ( inCaps.dwFormats & WAVE_FORMAT_4S16 ) info.nativeFormats |= RTAUDIO_SINT16; - if ( inCaps.dwFormats & WAVE_FORMAT_96S16 ) info.nativeFormats |= RTAUDIO_SINT16; - if ( inCaps.dwFormats & WAVE_FORMAT_1S08 ) info.nativeFormats |= RTAUDIO_SINT8; - if ( inCaps.dwFormats & WAVE_FORMAT_2S08 ) info.nativeFormats |= RTAUDIO_SINT8; - if ( inCaps.dwFormats & WAVE_FORMAT_4S08 ) info.nativeFormats |= RTAUDIO_SINT8; - if ( inCaps.dwFormats & WAVE_FORMAT_96S08 ) info.nativeFormats |= RTAUDIO_SINT8; + // Get sample rate and format information. + std::vector rates; + if (inCaps.dwChannels >= 2) + { + if (inCaps.dwFormats & WAVE_FORMAT_1S16) info.nativeFormats |= RTAUDIO_SINT16; + if (inCaps.dwFormats & WAVE_FORMAT_2S16) info.nativeFormats |= RTAUDIO_SINT16; + if (inCaps.dwFormats & WAVE_FORMAT_4S16) info.nativeFormats |= RTAUDIO_SINT16; + if (inCaps.dwFormats & WAVE_FORMAT_96S16) info.nativeFormats |= RTAUDIO_SINT16; + if (inCaps.dwFormats & WAVE_FORMAT_1S08) info.nativeFormats |= RTAUDIO_SINT8; + if (inCaps.dwFormats & WAVE_FORMAT_2S08) info.nativeFormats |= RTAUDIO_SINT8; + if (inCaps.dwFormats & WAVE_FORMAT_4S08) info.nativeFormats |= RTAUDIO_SINT8; + if (inCaps.dwFormats & WAVE_FORMAT_96S08) info.nativeFormats |= RTAUDIO_SINT8; - if ( info.nativeFormats & RTAUDIO_SINT16 ) { - if ( inCaps.dwFormats & WAVE_FORMAT_1S16 ) rates.push_back( 11025 ); - if ( inCaps.dwFormats & WAVE_FORMAT_2S16 ) rates.push_back( 22050 ); - if ( inCaps.dwFormats & WAVE_FORMAT_4S16 ) rates.push_back( 44100 ); - if ( inCaps.dwFormats & WAVE_FORMAT_96S16 ) rates.push_back( 96000 ); - } - else if ( info.nativeFormats & RTAUDIO_SINT8 ) { - if ( inCaps.dwFormats & WAVE_FORMAT_1S08 ) rates.push_back( 11025 ); - if ( inCaps.dwFormats & WAVE_FORMAT_2S08 ) rates.push_back( 22050 ); - if ( inCaps.dwFormats & WAVE_FORMAT_4S08 ) rates.push_back( 44100 ); - if ( inCaps.dwFormats & WAVE_FORMAT_96S08 ) rates.push_back( 96000 ); - } - } - else if ( inCaps.dwChannels == 1 ) { - if ( inCaps.dwFormats & WAVE_FORMAT_1M16 ) info.nativeFormats |= RTAUDIO_SINT16; - if ( inCaps.dwFormats & WAVE_FORMAT_2M16 ) info.nativeFormats |= RTAUDIO_SINT16; - if ( inCaps.dwFormats & WAVE_FORMAT_4M16 ) info.nativeFormats |= RTAUDIO_SINT16; - if ( inCaps.dwFormats & WAVE_FORMAT_96M16 ) info.nativeFormats |= RTAUDIO_SINT16; - if ( inCaps.dwFormats & WAVE_FORMAT_1M08 ) info.nativeFormats |= RTAUDIO_SINT8; - if ( inCaps.dwFormats & WAVE_FORMAT_2M08 ) info.nativeFormats |= RTAUDIO_SINT8; - if ( inCaps.dwFormats & WAVE_FORMAT_4M08 ) info.nativeFormats |= RTAUDIO_SINT8; - if ( inCaps.dwFormats & WAVE_FORMAT_96M08 ) info.nativeFormats |= RTAUDIO_SINT8; + if (info.nativeFormats & RTAUDIO_SINT16) + { + if (inCaps.dwFormats & WAVE_FORMAT_1S16) rates.push_back(11025); + if (inCaps.dwFormats & WAVE_FORMAT_2S16) rates.push_back(22050); + if (inCaps.dwFormats & WAVE_FORMAT_4S16) rates.push_back(44100); + if (inCaps.dwFormats & WAVE_FORMAT_96S16) rates.push_back(96000); + } + else if (info.nativeFormats & RTAUDIO_SINT8) + { + if (inCaps.dwFormats & WAVE_FORMAT_1S08) rates.push_back(11025); + if (inCaps.dwFormats & WAVE_FORMAT_2S08) rates.push_back(22050); + if (inCaps.dwFormats & WAVE_FORMAT_4S08) rates.push_back(44100); + if (inCaps.dwFormats & WAVE_FORMAT_96S08) rates.push_back(96000); + } + } + else if (inCaps.dwChannels == 1) + { + if (inCaps.dwFormats & WAVE_FORMAT_1M16) info.nativeFormats |= RTAUDIO_SINT16; + if (inCaps.dwFormats & WAVE_FORMAT_2M16) info.nativeFormats |= RTAUDIO_SINT16; + if (inCaps.dwFormats & WAVE_FORMAT_4M16) info.nativeFormats |= RTAUDIO_SINT16; + if (inCaps.dwFormats & WAVE_FORMAT_96M16) info.nativeFormats |= RTAUDIO_SINT16; + if (inCaps.dwFormats & WAVE_FORMAT_1M08) info.nativeFormats |= RTAUDIO_SINT8; + if (inCaps.dwFormats & WAVE_FORMAT_2M08) info.nativeFormats |= RTAUDIO_SINT8; + if (inCaps.dwFormats & WAVE_FORMAT_4M08) info.nativeFormats |= RTAUDIO_SINT8; + if (inCaps.dwFormats & WAVE_FORMAT_96M08) info.nativeFormats |= RTAUDIO_SINT8; - if ( info.nativeFormats & RTAUDIO_SINT16 ) { - if ( inCaps.dwFormats & WAVE_FORMAT_1M16 ) rates.push_back( 11025 ); - if ( inCaps.dwFormats & WAVE_FORMAT_2M16 ) rates.push_back( 22050 ); - if ( inCaps.dwFormats & WAVE_FORMAT_4M16 ) rates.push_back( 44100 ); - if ( inCaps.dwFormats & WAVE_FORMAT_96M16 ) rates.push_back( 96000 ); - } - else if ( info.nativeFormats & RTAUDIO_SINT8 ) { - if ( inCaps.dwFormats & WAVE_FORMAT_1M08 ) rates.push_back( 11025 ); - if ( inCaps.dwFormats & WAVE_FORMAT_2M08 ) rates.push_back( 22050 ); - if ( inCaps.dwFormats & WAVE_FORMAT_4M08 ) rates.push_back( 44100 ); - if ( inCaps.dwFormats & WAVE_FORMAT_96M08 ) rates.push_back( 96000 ); - } - } - else info.inputChannels = 0; // technically, this would be an error + if (info.nativeFormats & RTAUDIO_SINT16) + { + if (inCaps.dwFormats & WAVE_FORMAT_1M16) rates.push_back(11025); + if (inCaps.dwFormats & WAVE_FORMAT_2M16) rates.push_back(22050); + if (inCaps.dwFormats & WAVE_FORMAT_4M16) rates.push_back(44100); + if (inCaps.dwFormats & WAVE_FORMAT_96M16) rates.push_back(96000); + } + else if (info.nativeFormats & RTAUDIO_SINT8) + { + if (inCaps.dwFormats & WAVE_FORMAT_1M08) rates.push_back(11025); + if (inCaps.dwFormats & WAVE_FORMAT_2M08) rates.push_back(22050); + if (inCaps.dwFormats & WAVE_FORMAT_4M08) rates.push_back(44100); + if (inCaps.dwFormats & WAVE_FORMAT_96M08) rates.push_back(96000); + } + } + else + info.inputChannels = 0; // technically, this would be an error - input->Release(); + input->Release(); - if ( info.inputChannels == 0 ) return info; + if (info.inputChannels == 0) return info; - // Copy the supported rates to the info structure but avoid duplication. - bool found; - for ( unsigned int i=0; i 0 && info.inputChannels > 0 ) - info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels; + // If device opens for both playback and capture, we determine the channels. + if (info.outputChannels > 0 && info.inputChannels > 0) + info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels; - if ( device == 0 ) info.isDefaultInput = true; + if (device == 0) info.isDefaultInput = true; - // Copy name and return. - info.name = dsDevices[ device ].name; - info.probed = true; - return info; + // Copy name and return. + info.name = dsDevices[device].name; + info.probed = true; + return info; } -bool RtApiDs :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, - unsigned int firstChannel, unsigned int sampleRate, - RtAudioFormat format, unsigned int *bufferSize, - RtAudio::StreamOptions *options ) +bool RtApiDs ::probeDeviceOpen(unsigned int device, StreamMode mode, unsigned int channels, + unsigned int firstChannel, unsigned int sampleRate, + RtAudioFormat format, unsigned int *bufferSize, + RtAudio::StreamOptions *options) { - if ( channels + firstChannel > 2 ) { - errorText_ = "RtApiDs::probeDeviceOpen: DirectSound does not support more than 2 channels per device."; - return FAILURE; - } + if (channels + firstChannel > 2) + { + errorText_ = "RtApiDs::probeDeviceOpen: DirectSound does not support more than 2 channels per device."; + return FAILURE; + } - size_t nDevices = dsDevices.size(); - if ( nDevices == 0 ) { - // This should not happen because a check is made before this function is called. - errorText_ = "RtApiDs::probeDeviceOpen: no devices found!"; - return FAILURE; - } + size_t nDevices = dsDevices.size(); + if (nDevices == 0) + { + // This should not happen because a check is made before this function is called. + errorText_ = "RtApiDs::probeDeviceOpen: no devices found!"; + return FAILURE; + } - if ( device >= nDevices ) { - // This should not happen because a check is made before this function is called. - errorText_ = "RtApiDs::probeDeviceOpen: device ID is invalid!"; - return FAILURE; - } + if (device >= nDevices) + { + // This should not happen because a check is made before this function is called. + errorText_ = "RtApiDs::probeDeviceOpen: device ID is invalid!"; + return FAILURE; + } - if ( mode == OUTPUT ) { - if ( dsDevices[ device ].validId[0] == false ) { - errorStream_ << "RtApiDs::probeDeviceOpen: device (" << device << ") does not support output!"; - errorText_ = errorStream_.str(); - return FAILURE; - } - } - else { // mode == INPUT - if ( dsDevices[ device ].validId[1] == false ) { - errorStream_ << "RtApiDs::probeDeviceOpen: device (" << device << ") does not support input!"; - errorText_ = errorStream_.str(); - return FAILURE; - } - } + if (mode == OUTPUT) + { + if (dsDevices[device].validId[0] == false) + { + errorStream_ << "RtApiDs::probeDeviceOpen: device (" << device << ") does not support output!"; + errorText_ = errorStream_.str(); + return FAILURE; + } + } + else + { // mode == INPUT + if (dsDevices[device].validId[1] == false) + { + errorStream_ << "RtApiDs::probeDeviceOpen: device (" << device << ") does not support input!"; + errorText_ = errorStream_.str(); + return FAILURE; + } + } - // According to a note in PortAudio, using GetDesktopWindow() - // instead of GetForegroundWindow() is supposed to avoid problems - // that occur when the application's window is not the foreground - // window. Also, if the application window closes before the - // DirectSound buffer, DirectSound can crash. In the past, I had - // problems when using GetDesktopWindow() but it seems fine now - // (January 2010). I'll leave it commented here. - // HWND hWnd = GetForegroundWindow(); - HWND hWnd = GetDesktopWindow(); + // According to a note in PortAudio, using GetDesktopWindow() + // instead of GetForegroundWindow() is supposed to avoid problems + // that occur when the application's window is not the foreground + // window. Also, if the application window closes before the + // DirectSound buffer, DirectSound can crash. In the past, I had + // problems when using GetDesktopWindow() but it seems fine now + // (January 2010). I'll leave it commented here. + // HWND hWnd = GetForegroundWindow(); + HWND hWnd = GetDesktopWindow(); - // Check the numberOfBuffers parameter and limit the lowest value to - // two. This is a judgement call and a value of two is probably too - // low for capture, but it should work for playback. - int nBuffers = 0; - if ( options ) nBuffers = options->numberOfBuffers; - if ( options && options->flags & RTAUDIO_MINIMIZE_LATENCY ) nBuffers = 2; - if ( nBuffers < 2 ) nBuffers = 3; + // Check the numberOfBuffers parameter and limit the lowest value to + // two. This is a judgement call and a value of two is probably too + // low for capture, but it should work for playback. + int nBuffers = 0; + if (options) nBuffers = options->numberOfBuffers; + if (options && options->flags & RTAUDIO_MINIMIZE_LATENCY) nBuffers = 2; + if (nBuffers < 2) nBuffers = 3; - // Check the lower range of the user-specified buffer size and set - // (arbitrarily) to a lower bound of 32. - if ( *bufferSize < 32 ) *bufferSize = 32; + // Check the lower range of the user-specified buffer size and set + // (arbitrarily) to a lower bound of 32. + if (*bufferSize < 32) *bufferSize = 32; - // Create the wave format structure. The data format setting will - // be determined later. - WAVEFORMATEX waveFormat; - ZeroMemory( &waveFormat, sizeof(WAVEFORMATEX) ); - waveFormat.wFormatTag = WAVE_FORMAT_PCM; - waveFormat.nChannels = channels + firstChannel; - waveFormat.nSamplesPerSec = (unsigned long) sampleRate; + // Create the wave format structure. The data format setting will + // be determined later. + WAVEFORMATEX waveFormat; + ZeroMemory(&waveFormat, sizeof(WAVEFORMATEX)); + waveFormat.wFormatTag = WAVE_FORMAT_PCM; + waveFormat.nChannels = channels + firstChannel; + waveFormat.nSamplesPerSec = (unsigned long)sampleRate; - // Determine the device buffer size. By default, we'll use the value - // defined above (32K), but we will grow it to make allowances for - // very large software buffer sizes. - DWORD dsBufferSize = MINIMUM_DEVICE_BUFFER_SIZE; - DWORD dsPointerLeadTime = 0; + // Determine the device buffer size. By default, we'll use the value + // defined above (32K), but we will grow it to make allowances for + // very large software buffer sizes. + DWORD dsBufferSize = MINIMUM_DEVICE_BUFFER_SIZE; + DWORD dsPointerLeadTime = 0; - void *ohandle = 0, *bhandle = 0; - HRESULT result; - if ( mode == OUTPUT ) { + void *ohandle = 0, *bhandle = 0; + HRESULT result; + if (mode == OUTPUT) + { + LPDIRECTSOUND output; + result = DirectSoundCreate(dsDevices[device].id[0], &output, NULL); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString(result) << ") opening output device (" << dsDevices[device].name << ")!"; + errorText_ = errorStream_.str(); + return FAILURE; + } - LPDIRECTSOUND output; - result = DirectSoundCreate( dsDevices[ device ].id[0], &output, NULL ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") opening output device (" << dsDevices[ device ].name << ")!"; - errorText_ = errorStream_.str(); - return FAILURE; - } + DSCAPS outCaps; + outCaps.dwSize = sizeof(outCaps); + result = output->GetCaps(&outCaps); + if (FAILED(result)) + { + output->Release(); + errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString(result) << ") getting capabilities (" << dsDevices[device].name << ")!"; + errorText_ = errorStream_.str(); + return FAILURE; + } - DSCAPS outCaps; - outCaps.dwSize = sizeof( outCaps ); - result = output->GetCaps( &outCaps ); - if ( FAILED( result ) ) { - output->Release(); - errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") getting capabilities (" << dsDevices[ device ].name << ")!"; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Check channel information. + if (channels + firstChannel == 2 && !(outCaps.dwFlags & DSCAPS_PRIMARYSTEREO)) + { + errorStream_ << "RtApiDs::getDeviceInfo: the output device (" << dsDevices[device].name << ") does not support stereo playback."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Check channel information. - if ( channels + firstChannel == 2 && !( outCaps.dwFlags & DSCAPS_PRIMARYSTEREO ) ) { - errorStream_ << "RtApiDs::getDeviceInfo: the output device (" << dsDevices[ device ].name << ") does not support stereo playback."; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Check format information. Use 16-bit format unless not + // supported or user requests 8-bit. + if (outCaps.dwFlags & DSCAPS_PRIMARY16BIT && + !(format == RTAUDIO_SINT8 && outCaps.dwFlags & DSCAPS_PRIMARY8BIT)) + { + waveFormat.wBitsPerSample = 16; + stream_.deviceFormat[mode] = RTAUDIO_SINT16; + } + else + { + waveFormat.wBitsPerSample = 8; + stream_.deviceFormat[mode] = RTAUDIO_SINT8; + } + stream_.userFormat = format; - // Check format information. Use 16-bit format unless not - // supported or user requests 8-bit. - if ( outCaps.dwFlags & DSCAPS_PRIMARY16BIT && - !( format == RTAUDIO_SINT8 && outCaps.dwFlags & DSCAPS_PRIMARY8BIT ) ) { - waveFormat.wBitsPerSample = 16; - stream_.deviceFormat[mode] = RTAUDIO_SINT16; - } - else { - waveFormat.wBitsPerSample = 8; - stream_.deviceFormat[mode] = RTAUDIO_SINT8; - } - stream_.userFormat = format; + // Update wave format structure and buffer information. + waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8; + waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; + dsPointerLeadTime = nBuffers * (*bufferSize) * (waveFormat.wBitsPerSample / 8) * channels; - // Update wave format structure and buffer information. - waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8; - waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; - dsPointerLeadTime = nBuffers * (*bufferSize) * (waveFormat.wBitsPerSample / 8) * channels; + // If the user wants an even bigger buffer, increase the device buffer size accordingly. + while (dsPointerLeadTime * 2U > dsBufferSize) + dsBufferSize *= 2; - // If the user wants an even bigger buffer, increase the device buffer size accordingly. - while ( dsPointerLeadTime * 2U > dsBufferSize ) - dsBufferSize *= 2; + // Set cooperative level to DSSCL_EXCLUSIVE ... sound stops when window focus changes. + // result = output->SetCooperativeLevel( hWnd, DSSCL_EXCLUSIVE ); + // Set cooperative level to DSSCL_PRIORITY ... sound remains when window focus changes. + result = output->SetCooperativeLevel(hWnd, DSSCL_PRIORITY); + if (FAILED(result)) + { + output->Release(); + errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString(result) << ") setting cooperative level (" << dsDevices[device].name << ")!"; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Set cooperative level to DSSCL_EXCLUSIVE ... sound stops when window focus changes. - // result = output->SetCooperativeLevel( hWnd, DSSCL_EXCLUSIVE ); - // Set cooperative level to DSSCL_PRIORITY ... sound remains when window focus changes. - result = output->SetCooperativeLevel( hWnd, DSSCL_PRIORITY ); - if ( FAILED( result ) ) { - output->Release(); - errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") setting cooperative level (" << dsDevices[ device ].name << ")!"; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Even though we will write to the secondary buffer, we need to + // access the primary buffer to set the correct output format + // (since the default is 8-bit, 22 kHz!). Setup the DS primary + // buffer description. + DSBUFFERDESC bufferDescription; + ZeroMemory(&bufferDescription, sizeof(DSBUFFERDESC)); + bufferDescription.dwSize = sizeof(DSBUFFERDESC); + bufferDescription.dwFlags = DSBCAPS_PRIMARYBUFFER; - // Even though we will write to the secondary buffer, we need to - // access the primary buffer to set the correct output format - // (since the default is 8-bit, 22 kHz!). Setup the DS primary - // buffer description. - DSBUFFERDESC bufferDescription; - ZeroMemory( &bufferDescription, sizeof( DSBUFFERDESC ) ); - bufferDescription.dwSize = sizeof( DSBUFFERDESC ); - bufferDescription.dwFlags = DSBCAPS_PRIMARYBUFFER; + // Obtain the primary buffer + LPDIRECTSOUNDBUFFER buffer; + result = output->CreateSoundBuffer(&bufferDescription, &buffer, NULL); + if (FAILED(result)) + { + output->Release(); + errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString(result) << ") accessing primary buffer (" << dsDevices[device].name << ")!"; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Obtain the primary buffer - LPDIRECTSOUNDBUFFER buffer; - result = output->CreateSoundBuffer( &bufferDescription, &buffer, NULL ); - if ( FAILED( result ) ) { - output->Release(); - errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") accessing primary buffer (" << dsDevices[ device ].name << ")!"; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Set the primary DS buffer sound format. + result = buffer->SetFormat(&waveFormat); + if (FAILED(result)) + { + output->Release(); + errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString(result) << ") setting primary buffer format (" << dsDevices[device].name << ")!"; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Set the primary DS buffer sound format. - result = buffer->SetFormat( &waveFormat ); - if ( FAILED( result ) ) { - output->Release(); - errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") setting primary buffer format (" << dsDevices[ device ].name << ")!"; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Setup the secondary DS buffer description. + ZeroMemory(&bufferDescription, sizeof(DSBUFFERDESC)); + bufferDescription.dwSize = sizeof(DSBUFFERDESC); + bufferDescription.dwFlags = (DSBCAPS_STICKYFOCUS | + DSBCAPS_GLOBALFOCUS | + DSBCAPS_GETCURRENTPOSITION2 | + DSBCAPS_LOCHARDWARE); // Force hardware mixing + bufferDescription.dwBufferBytes = dsBufferSize; + bufferDescription.lpwfxFormat = &waveFormat; - // Setup the secondary DS buffer description. - ZeroMemory( &bufferDescription, sizeof( DSBUFFERDESC ) ); - bufferDescription.dwSize = sizeof( DSBUFFERDESC ); - bufferDescription.dwFlags = ( DSBCAPS_STICKYFOCUS | - DSBCAPS_GLOBALFOCUS | - DSBCAPS_GETCURRENTPOSITION2 | - DSBCAPS_LOCHARDWARE ); // Force hardware mixing - bufferDescription.dwBufferBytes = dsBufferSize; - bufferDescription.lpwfxFormat = &waveFormat; + // Try to create the secondary DS buffer. If that doesn't work, + // try to use software mixing. Otherwise, there's a problem. + result = output->CreateSoundBuffer(&bufferDescription, &buffer, NULL); + if (FAILED(result)) + { + bufferDescription.dwFlags = (DSBCAPS_STICKYFOCUS | + DSBCAPS_GLOBALFOCUS | + DSBCAPS_GETCURRENTPOSITION2 | + DSBCAPS_LOCSOFTWARE); // Force software mixing + result = output->CreateSoundBuffer(&bufferDescription, &buffer, NULL); + if (FAILED(result)) + { + output->Release(); + errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString(result) << ") creating secondary buffer (" << dsDevices[device].name << ")!"; + errorText_ = errorStream_.str(); + return FAILURE; + } + } - // Try to create the secondary DS buffer. If that doesn't work, - // try to use software mixing. Otherwise, there's a problem. - result = output->CreateSoundBuffer( &bufferDescription, &buffer, NULL ); - if ( FAILED( result ) ) { - bufferDescription.dwFlags = ( DSBCAPS_STICKYFOCUS | - DSBCAPS_GLOBALFOCUS | - DSBCAPS_GETCURRENTPOSITION2 | - DSBCAPS_LOCSOFTWARE ); // Force software mixing - result = output->CreateSoundBuffer( &bufferDescription, &buffer, NULL ); - if ( FAILED( result ) ) { - output->Release(); - errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") creating secondary buffer (" << dsDevices[ device ].name << ")!"; - errorText_ = errorStream_.str(); - return FAILURE; - } - } + // Get the buffer size ... might be different from what we specified. + DSBCAPS dsbcaps; + dsbcaps.dwSize = sizeof(DSBCAPS); + result = buffer->GetCaps(&dsbcaps); + if (FAILED(result)) + { + output->Release(); + buffer->Release(); + errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString(result) << ") getting buffer settings (" << dsDevices[device].name << ")!"; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Get the buffer size ... might be different from what we specified. - DSBCAPS dsbcaps; - dsbcaps.dwSize = sizeof( DSBCAPS ); - result = buffer->GetCaps( &dsbcaps ); - if ( FAILED( result ) ) { - output->Release(); - buffer->Release(); - errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") getting buffer settings (" << dsDevices[ device ].name << ")!"; - errorText_ = errorStream_.str(); - return FAILURE; - } + dsBufferSize = dsbcaps.dwBufferBytes; - dsBufferSize = dsbcaps.dwBufferBytes; + // Lock the DS buffer + LPVOID audioPtr; + DWORD dataLen; + result = buffer->Lock(0, dsBufferSize, &audioPtr, &dataLen, NULL, NULL, 0); + if (FAILED(result)) + { + output->Release(); + buffer->Release(); + errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString(result) << ") locking buffer (" << dsDevices[device].name << ")!"; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Lock the DS buffer - LPVOID audioPtr; - DWORD dataLen; - result = buffer->Lock( 0, dsBufferSize, &audioPtr, &dataLen, NULL, NULL, 0 ); - if ( FAILED( result ) ) { - output->Release(); - buffer->Release(); - errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") locking buffer (" << dsDevices[ device ].name << ")!"; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Zero the DS buffer + ZeroMemory(audioPtr, dataLen); - // Zero the DS buffer - ZeroMemory( audioPtr, dataLen ); + // Unlock the DS buffer + result = buffer->Unlock(audioPtr, dataLen, NULL, 0); + if (FAILED(result)) + { + output->Release(); + buffer->Release(); + errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString(result) << ") unlocking buffer (" << dsDevices[device].name << ")!"; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Unlock the DS buffer - result = buffer->Unlock( audioPtr, dataLen, NULL, 0 ); - if ( FAILED( result ) ) { - output->Release(); - buffer->Release(); - errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") unlocking buffer (" << dsDevices[ device ].name << ")!"; - errorText_ = errorStream_.str(); - return FAILURE; - } + ohandle = (void *)output; + bhandle = (void *)buffer; + } - ohandle = (void *) output; - bhandle = (void *) buffer; - } + if (mode == INPUT) + { + LPDIRECTSOUNDCAPTURE input; + result = DirectSoundCaptureCreate(dsDevices[device].id[1], &input, NULL); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString(result) << ") opening input device (" << dsDevices[device].name << ")!"; + errorText_ = errorStream_.str(); + return FAILURE; + } - if ( mode == INPUT ) { + DSCCAPS inCaps; + inCaps.dwSize = sizeof(inCaps); + result = input->GetCaps(&inCaps); + if (FAILED(result)) + { + input->Release(); + errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString(result) << ") getting input capabilities (" << dsDevices[device].name << ")!"; + errorText_ = errorStream_.str(); + return FAILURE; + } - LPDIRECTSOUNDCAPTURE input; - result = DirectSoundCaptureCreate( dsDevices[ device ].id[1], &input, NULL ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") opening input device (" << dsDevices[ device ].name << ")!"; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Check channel information. + if (inCaps.dwChannels < channels + firstChannel) + { + errorText_ = "RtApiDs::getDeviceInfo: the input device does not support requested input channels."; + return FAILURE; + } - DSCCAPS inCaps; - inCaps.dwSize = sizeof( inCaps ); - result = input->GetCaps( &inCaps ); - if ( FAILED( result ) ) { - input->Release(); - errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") getting input capabilities (" << dsDevices[ device ].name << ")!"; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Check format information. Use 16-bit format unless user + // requests 8-bit. + DWORD deviceFormats; + if (channels + firstChannel == 2) + { + deviceFormats = WAVE_FORMAT_1S08 | WAVE_FORMAT_2S08 | WAVE_FORMAT_4S08 | WAVE_FORMAT_96S08; + if (format == RTAUDIO_SINT8 && inCaps.dwFormats & deviceFormats) + { + waveFormat.wBitsPerSample = 8; + stream_.deviceFormat[mode] = RTAUDIO_SINT8; + } + else + { // assume 16-bit is supported + waveFormat.wBitsPerSample = 16; + stream_.deviceFormat[mode] = RTAUDIO_SINT16; + } + } + else + { // channel == 1 + deviceFormats = WAVE_FORMAT_1M08 | WAVE_FORMAT_2M08 | WAVE_FORMAT_4M08 | WAVE_FORMAT_96M08; + if (format == RTAUDIO_SINT8 && inCaps.dwFormats & deviceFormats) + { + waveFormat.wBitsPerSample = 8; + stream_.deviceFormat[mode] = RTAUDIO_SINT8; + } + else + { // assume 16-bit is supported + waveFormat.wBitsPerSample = 16; + stream_.deviceFormat[mode] = RTAUDIO_SINT16; + } + } + stream_.userFormat = format; - // Check channel information. - if ( inCaps.dwChannels < channels + firstChannel ) { - errorText_ = "RtApiDs::getDeviceInfo: the input device does not support requested input channels."; - return FAILURE; - } + // Update wave format structure and buffer information. + waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8; + waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; + dsPointerLeadTime = nBuffers * (*bufferSize) * (waveFormat.wBitsPerSample / 8) * channels; - // Check format information. Use 16-bit format unless user - // requests 8-bit. - DWORD deviceFormats; - if ( channels + firstChannel == 2 ) { - deviceFormats = WAVE_FORMAT_1S08 | WAVE_FORMAT_2S08 | WAVE_FORMAT_4S08 | WAVE_FORMAT_96S08; - if ( format == RTAUDIO_SINT8 && inCaps.dwFormats & deviceFormats ) { - waveFormat.wBitsPerSample = 8; - stream_.deviceFormat[mode] = RTAUDIO_SINT8; - } - else { // assume 16-bit is supported - waveFormat.wBitsPerSample = 16; - stream_.deviceFormat[mode] = RTAUDIO_SINT16; - } - } - else { // channel == 1 - deviceFormats = WAVE_FORMAT_1M08 | WAVE_FORMAT_2M08 | WAVE_FORMAT_4M08 | WAVE_FORMAT_96M08; - if ( format == RTAUDIO_SINT8 && inCaps.dwFormats & deviceFormats ) { - waveFormat.wBitsPerSample = 8; - stream_.deviceFormat[mode] = RTAUDIO_SINT8; - } - else { // assume 16-bit is supported - waveFormat.wBitsPerSample = 16; - stream_.deviceFormat[mode] = RTAUDIO_SINT16; - } - } - stream_.userFormat = format; + // If the user wants an even bigger buffer, increase the device buffer size accordingly. + while (dsPointerLeadTime * 2U > dsBufferSize) + dsBufferSize *= 2; - // Update wave format structure and buffer information. - waveFormat.nBlockAlign = waveFormat.nChannels * waveFormat.wBitsPerSample / 8; - waveFormat.nAvgBytesPerSec = waveFormat.nSamplesPerSec * waveFormat.nBlockAlign; - dsPointerLeadTime = nBuffers * (*bufferSize) * (waveFormat.wBitsPerSample / 8) * channels; + // Setup the secondary DS buffer description. + DSCBUFFERDESC bufferDescription; + ZeroMemory(&bufferDescription, sizeof(DSCBUFFERDESC)); + bufferDescription.dwSize = sizeof(DSCBUFFERDESC); + bufferDescription.dwFlags = 0; + bufferDescription.dwReserved = 0; + bufferDescription.dwBufferBytes = dsBufferSize; + bufferDescription.lpwfxFormat = &waveFormat; - // If the user wants an even bigger buffer, increase the device buffer size accordingly. - while ( dsPointerLeadTime * 2U > dsBufferSize ) - dsBufferSize *= 2; + // Create the capture buffer. + LPDIRECTSOUNDCAPTUREBUFFER buffer; + result = input->CreateCaptureBuffer(&bufferDescription, &buffer, NULL); + if (FAILED(result)) + { + input->Release(); + errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString(result) << ") creating input buffer (" << dsDevices[device].name << ")!"; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Setup the secondary DS buffer description. - DSCBUFFERDESC bufferDescription; - ZeroMemory( &bufferDescription, sizeof( DSCBUFFERDESC ) ); - bufferDescription.dwSize = sizeof( DSCBUFFERDESC ); - bufferDescription.dwFlags = 0; - bufferDescription.dwReserved = 0; - bufferDescription.dwBufferBytes = dsBufferSize; - bufferDescription.lpwfxFormat = &waveFormat; + // Get the buffer size ... might be different from what we specified. + DSCBCAPS dscbcaps; + dscbcaps.dwSize = sizeof(DSCBCAPS); + result = buffer->GetCaps(&dscbcaps); + if (FAILED(result)) + { + input->Release(); + buffer->Release(); + errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString(result) << ") getting buffer settings (" << dsDevices[device].name << ")!"; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Create the capture buffer. - LPDIRECTSOUNDCAPTUREBUFFER buffer; - result = input->CreateCaptureBuffer( &bufferDescription, &buffer, NULL ); - if ( FAILED( result ) ) { - input->Release(); - errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") creating input buffer (" << dsDevices[ device ].name << ")!"; - errorText_ = errorStream_.str(); - return FAILURE; - } + dsBufferSize = dscbcaps.dwBufferBytes; - // Get the buffer size ... might be different from what we specified. - DSCBCAPS dscbcaps; - dscbcaps.dwSize = sizeof( DSCBCAPS ); - result = buffer->GetCaps( &dscbcaps ); - if ( FAILED( result ) ) { - input->Release(); - buffer->Release(); - errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") getting buffer settings (" << dsDevices[ device ].name << ")!"; - errorText_ = errorStream_.str(); - return FAILURE; - } + // NOTE: We could have a problem here if this is a duplex stream + // and the play and capture hardware buffer sizes are different + // (I'm actually not sure if that is a problem or not). + // Currently, we are not verifying that. - dsBufferSize = dscbcaps.dwBufferBytes; + // Lock the capture buffer + LPVOID audioPtr; + DWORD dataLen; + result = buffer->Lock(0, dsBufferSize, &audioPtr, &dataLen, NULL, NULL, 0); + if (FAILED(result)) + { + input->Release(); + buffer->Release(); + errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString(result) << ") locking input buffer (" << dsDevices[device].name << ")!"; + errorText_ = errorStream_.str(); + return FAILURE; + } - // NOTE: We could have a problem here if this is a duplex stream - // and the play and capture hardware buffer sizes are different - // (I'm actually not sure if that is a problem or not). - // Currently, we are not verifying that. + // Zero the buffer + ZeroMemory(audioPtr, dataLen); - // Lock the capture buffer - LPVOID audioPtr; - DWORD dataLen; - result = buffer->Lock( 0, dsBufferSize, &audioPtr, &dataLen, NULL, NULL, 0 ); - if ( FAILED( result ) ) { - input->Release(); - buffer->Release(); - errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") locking input buffer (" << dsDevices[ device ].name << ")!"; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Unlock the buffer + result = buffer->Unlock(audioPtr, dataLen, NULL, 0); + if (FAILED(result)) + { + input->Release(); + buffer->Release(); + errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString(result) << ") unlocking input buffer (" << dsDevices[device].name << ")!"; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Zero the buffer - ZeroMemory( audioPtr, dataLen ); + ohandle = (void *)input; + bhandle = (void *)buffer; + } - // Unlock the buffer - result = buffer->Unlock( audioPtr, dataLen, NULL, 0 ); - if ( FAILED( result ) ) { - input->Release(); - buffer->Release(); - errorStream_ << "RtApiDs::probeDeviceOpen: error (" << getErrorString( result ) << ") unlocking input buffer (" << dsDevices[ device ].name << ")!"; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Set various stream parameters + DsHandle *handle = 0; + stream_.nDeviceChannels[mode] = channels + firstChannel; + stream_.nUserChannels[mode] = channels; + stream_.bufferSize = *bufferSize; + stream_.channelOffset[mode] = firstChannel; + stream_.deviceInterleaved[mode] = true; + if (options && options->flags & RTAUDIO_NONINTERLEAVED) + stream_.userInterleaved = false; + else + stream_.userInterleaved = true; - ohandle = (void *) input; - bhandle = (void *) buffer; - } + // Set flag for buffer conversion + stream_.doConvertBuffer[mode] = false; + if (stream_.nUserChannels[mode] != stream_.nDeviceChannels[mode]) + stream_.doConvertBuffer[mode] = true; + if (stream_.userFormat != stream_.deviceFormat[mode]) + stream_.doConvertBuffer[mode] = true; + if (stream_.userInterleaved != stream_.deviceInterleaved[mode] && + stream_.nUserChannels[mode] > 1) + stream_.doConvertBuffer[mode] = true; - // Set various stream parameters - DsHandle *handle = 0; - stream_.nDeviceChannels[mode] = channels + firstChannel; - stream_.nUserChannels[mode] = channels; - stream_.bufferSize = *bufferSize; - stream_.channelOffset[mode] = firstChannel; - stream_.deviceInterleaved[mode] = true; - if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) stream_.userInterleaved = false; - else stream_.userInterleaved = true; + // Allocate necessary internal buffers + long bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes(stream_.userFormat); + stream_.userBuffer[mode] = (char *)calloc(bufferBytes, 1); + if (stream_.userBuffer[mode] == NULL) + { + errorText_ = "RtApiDs::probeDeviceOpen: error allocating user buffer memory."; + goto error; + } - // Set flag for buffer conversion - stream_.doConvertBuffer[mode] = false; - if (stream_.nUserChannels[mode] != stream_.nDeviceChannels[mode]) - stream_.doConvertBuffer[mode] = true; - if (stream_.userFormat != stream_.deviceFormat[mode]) - stream_.doConvertBuffer[mode] = true; - if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] && - stream_.nUserChannels[mode] > 1 ) - stream_.doConvertBuffer[mode] = true; + if (stream_.doConvertBuffer[mode]) + { + bool makeBuffer = true; + bufferBytes = stream_.nDeviceChannels[mode] * formatBytes(stream_.deviceFormat[mode]); + if (mode == INPUT) + { + if (stream_.mode == OUTPUT && stream_.deviceBuffer) + { + unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes(stream_.deviceFormat[0]); + if (bufferBytes <= (long)bytesOut) makeBuffer = false; + } + } - // Allocate necessary internal buffers - long bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat ); - stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 ); - if ( stream_.userBuffer[mode] == NULL ) { - errorText_ = "RtApiDs::probeDeviceOpen: error allocating user buffer memory."; - goto error; - } + if (makeBuffer) + { + bufferBytes *= *bufferSize; + if (stream_.deviceBuffer) free(stream_.deviceBuffer); + stream_.deviceBuffer = (char *)calloc(bufferBytes, 1); + if (stream_.deviceBuffer == NULL) + { + errorText_ = "RtApiDs::probeDeviceOpen: error allocating device buffer memory."; + goto error; + } + } + } - if ( stream_.doConvertBuffer[mode] ) { + // Allocate our DsHandle structures for the stream. + if (stream_.apiHandle == 0) + { + try + { + handle = new DsHandle; + } + catch (std::bad_alloc &) + { + errorText_ = "RtApiDs::probeDeviceOpen: error allocating AsioHandle memory."; + goto error; + } - bool makeBuffer = true; - bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] ); - if ( mode == INPUT ) { - if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) { - unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] ); - if ( bufferBytes <= (long) bytesOut ) makeBuffer = false; - } - } + // Create a manual-reset event. + handle->condition = CreateEvent(NULL, // no security + TRUE, // manual-reset + FALSE, // non-signaled initially + NULL); // unnamed + stream_.apiHandle = (void *)handle; + } + else + handle = (DsHandle *)stream_.apiHandle; + handle->id[mode] = ohandle; + handle->buffer[mode] = bhandle; + handle->dsBufferSize[mode] = dsBufferSize; + handle->dsPointerLeadTime[mode] = dsPointerLeadTime; - if ( makeBuffer ) { - bufferBytes *= *bufferSize; - if ( stream_.deviceBuffer ) free( stream_.deviceBuffer ); - stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 ); - if ( stream_.deviceBuffer == NULL ) { - errorText_ = "RtApiDs::probeDeviceOpen: error allocating device buffer memory."; - goto error; - } - } - } + stream_.device[mode] = device; + stream_.state = STREAM_STOPPED; + if (stream_.mode == OUTPUT && mode == INPUT) + // We had already set up an output stream. + stream_.mode = DUPLEX; + else + stream_.mode = mode; + stream_.nBuffers = nBuffers; + stream_.sampleRate = sampleRate; - // Allocate our DsHandle structures for the stream. - if ( stream_.apiHandle == 0 ) { - try { - handle = new DsHandle; - } - catch ( std::bad_alloc& ) { - errorText_ = "RtApiDs::probeDeviceOpen: error allocating AsioHandle memory."; - goto error; - } + // Setup the buffer conversion information structure. + if (stream_.doConvertBuffer[mode]) setConvertInfo(mode, firstChannel); - // Create a manual-reset event. - handle->condition = CreateEvent( NULL, // no security - TRUE, // manual-reset - FALSE, // non-signaled initially - NULL ); // unnamed - stream_.apiHandle = (void *) handle; - } - else - handle = (DsHandle *) stream_.apiHandle; - handle->id[mode] = ohandle; - handle->buffer[mode] = bhandle; - handle->dsBufferSize[mode] = dsBufferSize; - handle->dsPointerLeadTime[mode] = dsPointerLeadTime; + // Setup the callback thread. + if (stream_.callbackInfo.isRunning == false) + { + unsigned threadId; + stream_.callbackInfo.isRunning = true; + stream_.callbackInfo.object = (void *)this; + stream_.callbackInfo.thread = _beginthreadex(NULL, 0, &callbackHandler, + &stream_.callbackInfo, 0, &threadId); + if (stream_.callbackInfo.thread == 0) + { + errorText_ = "RtApiDs::probeDeviceOpen: error creating callback thread!"; + goto error; + } - stream_.device[mode] = device; - stream_.state = STREAM_STOPPED; - if ( stream_.mode == OUTPUT && mode == INPUT ) - // We had already set up an output stream. - stream_.mode = DUPLEX; - else - stream_.mode = mode; - stream_.nBuffers = nBuffers; - stream_.sampleRate = sampleRate; + // Boost DS thread priority + SetThreadPriority((HANDLE)stream_.callbackInfo.thread, THREAD_PRIORITY_HIGHEST); + } + return SUCCESS; - // Setup the buffer conversion information structure. - if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, firstChannel ); +error: + if (handle) + { + if (handle->buffer[0]) + { // the object pointer can be NULL and valid + LPDIRECTSOUND object = (LPDIRECTSOUND)handle->id[0]; + LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER)handle->buffer[0]; + if (buffer) buffer->Release(); + object->Release(); + } + if (handle->buffer[1]) + { + LPDIRECTSOUNDCAPTURE object = (LPDIRECTSOUNDCAPTURE)handle->id[1]; + LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER)handle->buffer[1]; + if (buffer) buffer->Release(); + object->Release(); + } + CloseHandle(handle->condition); + delete handle; + stream_.apiHandle = 0; + } - // Setup the callback thread. - if ( stream_.callbackInfo.isRunning == false ) { - unsigned threadId; - stream_.callbackInfo.isRunning = true; - stream_.callbackInfo.object = (void *) this; - stream_.callbackInfo.thread = _beginthreadex( NULL, 0, &callbackHandler, - &stream_.callbackInfo, 0, &threadId ); - if ( stream_.callbackInfo.thread == 0 ) { - errorText_ = "RtApiDs::probeDeviceOpen: error creating callback thread!"; - goto error; - } + for (int i = 0; i < 2; i++) + { + if (stream_.userBuffer[i]) + { + free(stream_.userBuffer[i]); + stream_.userBuffer[i] = 0; + } + } - // Boost DS thread priority - SetThreadPriority( (HANDLE) stream_.callbackInfo.thread, THREAD_PRIORITY_HIGHEST ); - } - return SUCCESS; + if (stream_.deviceBuffer) + { + free(stream_.deviceBuffer); + stream_.deviceBuffer = 0; + } - error: - if ( handle ) { - if ( handle->buffer[0] ) { // the object pointer can be NULL and valid - LPDIRECTSOUND object = (LPDIRECTSOUND) handle->id[0]; - LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0]; - if ( buffer ) buffer->Release(); - object->Release(); - } - if ( handle->buffer[1] ) { - LPDIRECTSOUNDCAPTURE object = (LPDIRECTSOUNDCAPTURE) handle->id[1]; - LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1]; - if ( buffer ) buffer->Release(); - object->Release(); - } - CloseHandle( handle->condition ); - delete handle; - stream_.apiHandle = 0; - } - - for ( int i=0; i<2; i++ ) { - if ( stream_.userBuffer[i] ) { - free( stream_.userBuffer[i] ); - stream_.userBuffer[i] = 0; - } - } - - if ( stream_.deviceBuffer ) { - free( stream_.deviceBuffer ); - stream_.deviceBuffer = 0; - } - - stream_.state = STREAM_CLOSED; - return FAILURE; + stream_.state = STREAM_CLOSED; + return FAILURE; } -void RtApiDs :: closeStream() +void RtApiDs ::closeStream() { - if ( stream_.state == STREAM_CLOSED ) { - errorText_ = "RtApiDs::closeStream(): no open stream to close!"; - error( RtAudioError::WARNING ); - return; - } + if (stream_.state == STREAM_CLOSED) + { + errorText_ = "RtApiDs::closeStream(): no open stream to close!"; + error(RtAudioError::WARNING); + return; + } - // Stop the callback thread. - stream_.callbackInfo.isRunning = false; - WaitForSingleObject( (HANDLE) stream_.callbackInfo.thread, INFINITE ); - CloseHandle( (HANDLE) stream_.callbackInfo.thread ); + // Stop the callback thread. + stream_.callbackInfo.isRunning = false; + WaitForSingleObject((HANDLE)stream_.callbackInfo.thread, INFINITE); + CloseHandle((HANDLE)stream_.callbackInfo.thread); - DsHandle *handle = (DsHandle *) stream_.apiHandle; - if ( handle ) { - if ( handle->buffer[0] ) { // the object pointer can be NULL and valid - LPDIRECTSOUND object = (LPDIRECTSOUND) handle->id[0]; - LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0]; - if ( buffer ) { - buffer->Stop(); - buffer->Release(); - } - object->Release(); - } - if ( handle->buffer[1] ) { - LPDIRECTSOUNDCAPTURE object = (LPDIRECTSOUNDCAPTURE) handle->id[1]; - LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1]; - if ( buffer ) { - buffer->Stop(); - buffer->Release(); - } - object->Release(); - } - CloseHandle( handle->condition ); - delete handle; - stream_.apiHandle = 0; - } + DsHandle *handle = (DsHandle *)stream_.apiHandle; + if (handle) + { + if (handle->buffer[0]) + { // the object pointer can be NULL and valid + LPDIRECTSOUND object = (LPDIRECTSOUND)handle->id[0]; + LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER)handle->buffer[0]; + if (buffer) + { + buffer->Stop(); + buffer->Release(); + } + object->Release(); + } + if (handle->buffer[1]) + { + LPDIRECTSOUNDCAPTURE object = (LPDIRECTSOUNDCAPTURE)handle->id[1]; + LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER)handle->buffer[1]; + if (buffer) + { + buffer->Stop(); + buffer->Release(); + } + object->Release(); + } + CloseHandle(handle->condition); + delete handle; + stream_.apiHandle = 0; + } - for ( int i=0; i<2; i++ ) { - if ( stream_.userBuffer[i] ) { - free( stream_.userBuffer[i] ); - stream_.userBuffer[i] = 0; - } - } + for (int i = 0; i < 2; i++) + { + if (stream_.userBuffer[i]) + { + free(stream_.userBuffer[i]); + stream_.userBuffer[i] = 0; + } + } - if ( stream_.deviceBuffer ) { - free( stream_.deviceBuffer ); - stream_.deviceBuffer = 0; - } + if (stream_.deviceBuffer) + { + free(stream_.deviceBuffer); + stream_.deviceBuffer = 0; + } - stream_.mode = UNINITIALIZED; - stream_.state = STREAM_CLOSED; + stream_.mode = UNINITIALIZED; + stream_.state = STREAM_CLOSED; } -void RtApiDs :: startStream() +void RtApiDs ::startStream() { - verifyStream(); - if ( stream_.state == STREAM_RUNNING ) { - errorText_ = "RtApiDs::startStream(): the stream is already running!"; - error( RtAudioError::WARNING ); - return; - } + verifyStream(); + if (stream_.state == STREAM_RUNNING) + { + errorText_ = "RtApiDs::startStream(): the stream is already running!"; + error(RtAudioError::WARNING); + return; + } - DsHandle *handle = (DsHandle *) stream_.apiHandle; + DsHandle *handle = (DsHandle *)stream_.apiHandle; - // Increase scheduler frequency on lesser windows (a side-effect of - // increasing timer accuracy). On greater windows (Win2K or later), - // this is already in effect. - timeBeginPeriod( 1 ); + // Increase scheduler frequency on lesser windows (a side-effect of + // increasing timer accuracy). On greater windows (Win2K or later), + // this is already in effect. + timeBeginPeriod(1); - buffersRolling = false; - duplexPrerollBytes = 0; + buffersRolling = false; + duplexPrerollBytes = 0; - if ( stream_.mode == DUPLEX ) { - // 0.5 seconds of silence in DUPLEX mode while the devices spin up and synchronize. - duplexPrerollBytes = (int) ( 0.5 * stream_.sampleRate * formatBytes( stream_.deviceFormat[1] ) * stream_.nDeviceChannels[1] ); - } + if (stream_.mode == DUPLEX) + { + // 0.5 seconds of silence in DUPLEX mode while the devices spin up and synchronize. + duplexPrerollBytes = (int)(0.5 * stream_.sampleRate * formatBytes(stream_.deviceFormat[1]) * stream_.nDeviceChannels[1]); + } - HRESULT result = 0; - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { + HRESULT result = 0; + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + { + LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER)handle->buffer[0]; + result = buffer->Play(0, 0, DSBPLAY_LOOPING); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::startStream: error (" << getErrorString(result) << ") starting output buffer!"; + errorText_ = errorStream_.str(); + goto unlock; + } + } - LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0]; - result = buffer->Play( 0, 0, DSBPLAY_LOOPING ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::startStream: error (" << getErrorString( result ) << ") starting output buffer!"; - errorText_ = errorStream_.str(); - goto unlock; - } - } + if (stream_.mode == INPUT || stream_.mode == DUPLEX) + { + LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER)handle->buffer[1]; + result = buffer->Start(DSCBSTART_LOOPING); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::startStream: error (" << getErrorString(result) << ") starting input buffer!"; + errorText_ = errorStream_.str(); + goto unlock; + } + } - if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) { + handle->drainCounter = 0; + handle->internalDrain = false; + ResetEvent(handle->condition); + stream_.state = STREAM_RUNNING; - LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1]; - result = buffer->Start( DSCBSTART_LOOPING ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::startStream: error (" << getErrorString( result ) << ") starting input buffer!"; - errorText_ = errorStream_.str(); - goto unlock; - } - } - - handle->drainCounter = 0; - handle->internalDrain = false; - ResetEvent( handle->condition ); - stream_.state = STREAM_RUNNING; - - unlock: - if ( FAILED( result ) ) error( RtAudioError::SYSTEM_ERROR ); +unlock: + if (FAILED(result)) error(RtAudioError::SYSTEM_ERROR); } -void RtApiDs :: stopStream() +void RtApiDs ::stopStream() { - verifyStream(); - if ( stream_.state == STREAM_STOPPED ) { - errorText_ = "RtApiDs::stopStream(): the stream is already stopped!"; - error( RtAudioError::WARNING ); - return; - } + verifyStream(); + if (stream_.state == STREAM_STOPPED) + { + errorText_ = "RtApiDs::stopStream(): the stream is already stopped!"; + error(RtAudioError::WARNING); + return; + } - HRESULT result = 0; - LPVOID audioPtr; - DWORD dataLen; - DsHandle *handle = (DsHandle *) stream_.apiHandle; - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { - if ( handle->drainCounter == 0 ) { - handle->drainCounter = 2; - WaitForSingleObject( handle->condition, INFINITE ); // block until signaled - } + HRESULT result = 0; + LPVOID audioPtr; + DWORD dataLen; + DsHandle *handle = (DsHandle *)stream_.apiHandle; + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + { + if (handle->drainCounter == 0) + { + handle->drainCounter = 2; + WaitForSingleObject(handle->condition, INFINITE); // block until signaled + } - stream_.state = STREAM_STOPPED; + stream_.state = STREAM_STOPPED; - MUTEX_LOCK( &stream_.mutex ); + MUTEX_LOCK(&stream_.mutex); - // Stop the buffer and clear memory - LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0]; - result = buffer->Stop(); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") stopping output buffer!"; - errorText_ = errorStream_.str(); - goto unlock; - } + // Stop the buffer and clear memory + LPDIRECTSOUNDBUFFER buffer = (LPDIRECTSOUNDBUFFER)handle->buffer[0]; + result = buffer->Stop(); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::stopStream: error (" << getErrorString(result) << ") stopping output buffer!"; + errorText_ = errorStream_.str(); + goto unlock; + } - // Lock the buffer and clear it so that if we start to play again, - // we won't have old data playing. - result = buffer->Lock( 0, handle->dsBufferSize[0], &audioPtr, &dataLen, NULL, NULL, 0 ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") locking output buffer!"; - errorText_ = errorStream_.str(); - goto unlock; - } + // Lock the buffer and clear it so that if we start to play again, + // we won't have old data playing. + result = buffer->Lock(0, handle->dsBufferSize[0], &audioPtr, &dataLen, NULL, NULL, 0); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::stopStream: error (" << getErrorString(result) << ") locking output buffer!"; + errorText_ = errorStream_.str(); + goto unlock; + } - // Zero the DS buffer - ZeroMemory( audioPtr, dataLen ); + // Zero the DS buffer + ZeroMemory(audioPtr, dataLen); - // Unlock the DS buffer - result = buffer->Unlock( audioPtr, dataLen, NULL, 0 ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") unlocking output buffer!"; - errorText_ = errorStream_.str(); - goto unlock; - } + // Unlock the DS buffer + result = buffer->Unlock(audioPtr, dataLen, NULL, 0); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::stopStream: error (" << getErrorString(result) << ") unlocking output buffer!"; + errorText_ = errorStream_.str(); + goto unlock; + } - // If we start playing again, we must begin at beginning of buffer. - handle->bufferPointer[0] = 0; - } + // If we start playing again, we must begin at beginning of buffer. + handle->bufferPointer[0] = 0; + } - if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) { - LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1]; - audioPtr = NULL; - dataLen = 0; + if (stream_.mode == INPUT || stream_.mode == DUPLEX) + { + LPDIRECTSOUNDCAPTUREBUFFER buffer = (LPDIRECTSOUNDCAPTUREBUFFER)handle->buffer[1]; + audioPtr = NULL; + dataLen = 0; - stream_.state = STREAM_STOPPED; + stream_.state = STREAM_STOPPED; - if ( stream_.mode != DUPLEX ) - MUTEX_LOCK( &stream_.mutex ); + if (stream_.mode != DUPLEX) + MUTEX_LOCK(&stream_.mutex); - result = buffer->Stop(); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") stopping input buffer!"; - errorText_ = errorStream_.str(); - goto unlock; - } + result = buffer->Stop(); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::stopStream: error (" << getErrorString(result) << ") stopping input buffer!"; + errorText_ = errorStream_.str(); + goto unlock; + } - // Lock the buffer and clear it so that if we start to play again, - // we won't have old data playing. - result = buffer->Lock( 0, handle->dsBufferSize[1], &audioPtr, &dataLen, NULL, NULL, 0 ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") locking input buffer!"; - errorText_ = errorStream_.str(); - goto unlock; - } + // Lock the buffer and clear it so that if we start to play again, + // we won't have old data playing. + result = buffer->Lock(0, handle->dsBufferSize[1], &audioPtr, &dataLen, NULL, NULL, 0); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::stopStream: error (" << getErrorString(result) << ") locking input buffer!"; + errorText_ = errorStream_.str(); + goto unlock; + } - // Zero the DS buffer - ZeroMemory( audioPtr, dataLen ); + // Zero the DS buffer + ZeroMemory(audioPtr, dataLen); - // Unlock the DS buffer - result = buffer->Unlock( audioPtr, dataLen, NULL, 0 ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::stopStream: error (" << getErrorString( result ) << ") unlocking input buffer!"; - errorText_ = errorStream_.str(); - goto unlock; - } + // Unlock the DS buffer + result = buffer->Unlock(audioPtr, dataLen, NULL, 0); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::stopStream: error (" << getErrorString(result) << ") unlocking input buffer!"; + errorText_ = errorStream_.str(); + goto unlock; + } - // If we start recording again, we must begin at beginning of buffer. - handle->bufferPointer[1] = 0; - } + // If we start recording again, we must begin at beginning of buffer. + handle->bufferPointer[1] = 0; + } - unlock: - timeEndPeriod( 1 ); // revert to normal scheduler frequency on lesser windows. - MUTEX_UNLOCK( &stream_.mutex ); +unlock: + timeEndPeriod(1); // revert to normal scheduler frequency on lesser windows. + MUTEX_UNLOCK(&stream_.mutex); - if ( FAILED( result ) ) error( RtAudioError::SYSTEM_ERROR ); + if (FAILED(result)) error(RtAudioError::SYSTEM_ERROR); } -void RtApiDs :: abortStream() +void RtApiDs ::abortStream() { - verifyStream(); - if ( stream_.state == STREAM_STOPPED ) { - errorText_ = "RtApiDs::abortStream(): the stream is already stopped!"; - error( RtAudioError::WARNING ); - return; - } + verifyStream(); + if (stream_.state == STREAM_STOPPED) + { + errorText_ = "RtApiDs::abortStream(): the stream is already stopped!"; + error(RtAudioError::WARNING); + return; + } - DsHandle *handle = (DsHandle *) stream_.apiHandle; - handle->drainCounter = 2; + DsHandle *handle = (DsHandle *)stream_.apiHandle; + handle->drainCounter = 2; - stopStream(); + stopStream(); } -void RtApiDs :: callbackEvent() +void RtApiDs ::callbackEvent() { - if ( stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING ) { - Sleep( 50 ); // sleep 50 milliseconds - return; - } + if (stream_.state == STREAM_STOPPED || stream_.state == STREAM_STOPPING) + { + Sleep(50); // sleep 50 milliseconds + return; + } - if ( stream_.state == STREAM_CLOSED ) { - errorText_ = "RtApiDs::callbackEvent(): the stream is closed ... this shouldn't happen!"; - error( RtAudioError::WARNING ); - return; - } + if (stream_.state == STREAM_CLOSED) + { + errorText_ = "RtApiDs::callbackEvent(): the stream is closed ... this shouldn't happen!"; + error(RtAudioError::WARNING); + return; + } - CallbackInfo *info = (CallbackInfo *) &stream_.callbackInfo; - DsHandle *handle = (DsHandle *) stream_.apiHandle; + CallbackInfo *info = (CallbackInfo *)&stream_.callbackInfo; + DsHandle *handle = (DsHandle *)stream_.apiHandle; - // Check if we were draining the stream and signal is finished. - if ( handle->drainCounter > stream_.nBuffers + 2 ) { + // Check if we were draining the stream and signal is finished. + if (handle->drainCounter > stream_.nBuffers + 2) + { + stream_.state = STREAM_STOPPING; + if (handle->internalDrain == false) + SetEvent(handle->condition); + else + stopStream(); + return; + } - stream_.state = STREAM_STOPPING; - if ( handle->internalDrain == false ) - SetEvent( handle->condition ); - else - stopStream(); - return; - } + // Invoke user callback to get fresh output data UNLESS we are + // draining stream. + if (handle->drainCounter == 0) + { + RtAudioCallback callback = (RtAudioCallback)info->callback; + double streamTime = getStreamTime(); + RtAudioStreamStatus status = 0; + if (stream_.mode != INPUT && handle->xrun[0] == true) + { + status |= RTAUDIO_OUTPUT_UNDERFLOW; + handle->xrun[0] = false; + } + if (stream_.mode != OUTPUT && handle->xrun[1] == true) + { + status |= RTAUDIO_INPUT_OVERFLOW; + handle->xrun[1] = false; + } + int cbReturnValue = callback(stream_.userBuffer[0], stream_.userBuffer[1], + stream_.bufferSize, streamTime, status, info->userData); + if (cbReturnValue == 2) + { + stream_.state = STREAM_STOPPING; + handle->drainCounter = 2; + abortStream(); + return; + } + else if (cbReturnValue == 1) + { + handle->drainCounter = 1; + handle->internalDrain = true; + } + } - // Invoke user callback to get fresh output data UNLESS we are - // draining stream. - if ( handle->drainCounter == 0 ) { - RtAudioCallback callback = (RtAudioCallback) info->callback; - double streamTime = getStreamTime(); - RtAudioStreamStatus status = 0; - if ( stream_.mode != INPUT && handle->xrun[0] == true ) { - status |= RTAUDIO_OUTPUT_UNDERFLOW; - handle->xrun[0] = false; - } - if ( stream_.mode != OUTPUT && handle->xrun[1] == true ) { - status |= RTAUDIO_INPUT_OVERFLOW; - handle->xrun[1] = false; - } - int cbReturnValue = callback( stream_.userBuffer[0], stream_.userBuffer[1], - stream_.bufferSize, streamTime, status, info->userData ); - if ( cbReturnValue == 2 ) { - stream_.state = STREAM_STOPPING; - handle->drainCounter = 2; - abortStream(); - return; - } - else if ( cbReturnValue == 1 ) { - handle->drainCounter = 1; - handle->internalDrain = true; - } - } + HRESULT result; + DWORD currentWritePointer, safeWritePointer; + DWORD currentReadPointer, safeReadPointer; + UINT nextWritePointer; - HRESULT result; - DWORD currentWritePointer, safeWritePointer; - DWORD currentReadPointer, safeReadPointer; - UINT nextWritePointer; + LPVOID buffer1 = NULL; + LPVOID buffer2 = NULL; + DWORD bufferSize1 = 0; + DWORD bufferSize2 = 0; - LPVOID buffer1 = NULL; - LPVOID buffer2 = NULL; - DWORD bufferSize1 = 0; - DWORD bufferSize2 = 0; + char *buffer; + long bufferBytes; - char *buffer; - long bufferBytes; + MUTEX_LOCK(&stream_.mutex); + if (stream_.state == STREAM_STOPPED) + { + MUTEX_UNLOCK(&stream_.mutex); + return; + } - MUTEX_LOCK( &stream_.mutex ); - if ( stream_.state == STREAM_STOPPED ) { - MUTEX_UNLOCK( &stream_.mutex ); - return; - } + if (buffersRolling == false) + { + if (stream_.mode == DUPLEX) + { + //assert( handle->dsBufferSize[0] == handle->dsBufferSize[1] ); - if ( buffersRolling == false ) { - if ( stream_.mode == DUPLEX ) { - //assert( handle->dsBufferSize[0] == handle->dsBufferSize[1] ); + // It takes a while for the devices to get rolling. As a result, + // there's no guarantee that the capture and write device pointers + // will move in lockstep. Wait here for both devices to start + // rolling, and then set our buffer pointers accordingly. + // e.g. Crystal Drivers: the capture buffer starts up 5700 to 9600 + // bytes later than the write buffer. - // It takes a while for the devices to get rolling. As a result, - // there's no guarantee that the capture and write device pointers - // will move in lockstep. Wait here for both devices to start - // rolling, and then set our buffer pointers accordingly. - // e.g. Crystal Drivers: the capture buffer starts up 5700 to 9600 - // bytes later than the write buffer. + // Stub: a serious risk of having a pre-emptive scheduling round + // take place between the two GetCurrentPosition calls... but I'm + // really not sure how to solve the problem. Temporarily boost to + // Realtime priority, maybe; but I'm not sure what priority the + // DirectSound service threads run at. We *should* be roughly + // within a ms or so of correct. - // Stub: a serious risk of having a pre-emptive scheduling round - // take place between the two GetCurrentPosition calls... but I'm - // really not sure how to solve the problem. Temporarily boost to - // Realtime priority, maybe; but I'm not sure what priority the - // DirectSound service threads run at. We *should* be roughly - // within a ms or so of correct. + LPDIRECTSOUNDBUFFER dsWriteBuffer = (LPDIRECTSOUNDBUFFER)handle->buffer[0]; + LPDIRECTSOUNDCAPTUREBUFFER dsCaptureBuffer = (LPDIRECTSOUNDCAPTUREBUFFER)handle->buffer[1]; - LPDIRECTSOUNDBUFFER dsWriteBuffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0]; - LPDIRECTSOUNDCAPTUREBUFFER dsCaptureBuffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1]; + DWORD startSafeWritePointer, startSafeReadPointer; - DWORD startSafeWritePointer, startSafeReadPointer; + result = dsWriteBuffer->GetCurrentPosition(NULL, &startSafeWritePointer); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString(result) << ") getting current write position!"; + errorText_ = errorStream_.str(); + MUTEX_UNLOCK(&stream_.mutex); + error(RtAudioError::SYSTEM_ERROR); + return; + } + result = dsCaptureBuffer->GetCurrentPosition(NULL, &startSafeReadPointer); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString(result) << ") getting current read position!"; + errorText_ = errorStream_.str(); + MUTEX_UNLOCK(&stream_.mutex); + error(RtAudioError::SYSTEM_ERROR); + return; + } + while (true) + { + result = dsWriteBuffer->GetCurrentPosition(NULL, &safeWritePointer); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString(result) << ") getting current write position!"; + errorText_ = errorStream_.str(); + MUTEX_UNLOCK(&stream_.mutex); + error(RtAudioError::SYSTEM_ERROR); + return; + } + result = dsCaptureBuffer->GetCurrentPosition(NULL, &safeReadPointer); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString(result) << ") getting current read position!"; + errorText_ = errorStream_.str(); + MUTEX_UNLOCK(&stream_.mutex); + error(RtAudioError::SYSTEM_ERROR); + return; + } + if (safeWritePointer != startSafeWritePointer && safeReadPointer != startSafeReadPointer) break; + Sleep(1); + } - result = dsWriteBuffer->GetCurrentPosition( NULL, &startSafeWritePointer ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!"; - errorText_ = errorStream_.str(); - MUTEX_UNLOCK( &stream_.mutex ); - error( RtAudioError::SYSTEM_ERROR ); - return; - } - result = dsCaptureBuffer->GetCurrentPosition( NULL, &startSafeReadPointer ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!"; - errorText_ = errorStream_.str(); - MUTEX_UNLOCK( &stream_.mutex ); - error( RtAudioError::SYSTEM_ERROR ); - return; - } - while ( true ) { - result = dsWriteBuffer->GetCurrentPosition( NULL, &safeWritePointer ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!"; - errorText_ = errorStream_.str(); - MUTEX_UNLOCK( &stream_.mutex ); - error( RtAudioError::SYSTEM_ERROR ); - return; - } - result = dsCaptureBuffer->GetCurrentPosition( NULL, &safeReadPointer ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!"; - errorText_ = errorStream_.str(); - MUTEX_UNLOCK( &stream_.mutex ); - error( RtAudioError::SYSTEM_ERROR ); - return; - } - if ( safeWritePointer != startSafeWritePointer && safeReadPointer != startSafeReadPointer ) break; - Sleep( 1 ); - } + //assert( handle->dsBufferSize[0] == handle->dsBufferSize[1] ); - //assert( handle->dsBufferSize[0] == handle->dsBufferSize[1] ); + handle->bufferPointer[0] = safeWritePointer + handle->dsPointerLeadTime[0]; + if (handle->bufferPointer[0] >= handle->dsBufferSize[0]) handle->bufferPointer[0] -= handle->dsBufferSize[0]; + handle->bufferPointer[1] = safeReadPointer; + } + else if (stream_.mode == OUTPUT) + { + // Set the proper nextWritePosition after initial startup. + LPDIRECTSOUNDBUFFER dsWriteBuffer = (LPDIRECTSOUNDBUFFER)handle->buffer[0]; + result = dsWriteBuffer->GetCurrentPosition(¤tWritePointer, &safeWritePointer); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString(result) << ") getting current write position!"; + errorText_ = errorStream_.str(); + MUTEX_UNLOCK(&stream_.mutex); + error(RtAudioError::SYSTEM_ERROR); + return; + } + handle->bufferPointer[0] = safeWritePointer + handle->dsPointerLeadTime[0]; + if (handle->bufferPointer[0] >= handle->dsBufferSize[0]) handle->bufferPointer[0] -= handle->dsBufferSize[0]; + } - handle->bufferPointer[0] = safeWritePointer + handle->dsPointerLeadTime[0]; - if ( handle->bufferPointer[0] >= handle->dsBufferSize[0] ) handle->bufferPointer[0] -= handle->dsBufferSize[0]; - handle->bufferPointer[1] = safeReadPointer; - } - else if ( stream_.mode == OUTPUT ) { + buffersRolling = true; + } - // Set the proper nextWritePosition after initial startup. - LPDIRECTSOUNDBUFFER dsWriteBuffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0]; - result = dsWriteBuffer->GetCurrentPosition( ¤tWritePointer, &safeWritePointer ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!"; - errorText_ = errorStream_.str(); - MUTEX_UNLOCK( &stream_.mutex ); - error( RtAudioError::SYSTEM_ERROR ); - return; - } - handle->bufferPointer[0] = safeWritePointer + handle->dsPointerLeadTime[0]; - if ( handle->bufferPointer[0] >= handle->dsBufferSize[0] ) handle->bufferPointer[0] -= handle->dsBufferSize[0]; - } + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + { + LPDIRECTSOUNDBUFFER dsBuffer = (LPDIRECTSOUNDBUFFER)handle->buffer[0]; - buffersRolling = true; - } + if (handle->drainCounter > 1) + { // write zeros to the output stream + bufferBytes = stream_.bufferSize * stream_.nUserChannels[0]; + bufferBytes *= formatBytes(stream_.userFormat); + memset(stream_.userBuffer[0], 0, bufferBytes); + } - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { - - LPDIRECTSOUNDBUFFER dsBuffer = (LPDIRECTSOUNDBUFFER) handle->buffer[0]; + // Setup parameters and do buffer conversion if necessary. + if (stream_.doConvertBuffer[0]) + { + buffer = stream_.deviceBuffer; + convertBuffer(buffer, stream_.userBuffer[0], stream_.convertInfo[0]); + bufferBytes = stream_.bufferSize * stream_.nDeviceChannels[0]; + bufferBytes *= formatBytes(stream_.deviceFormat[0]); + } + else + { + buffer = stream_.userBuffer[0]; + bufferBytes = stream_.bufferSize * stream_.nUserChannels[0]; + bufferBytes *= formatBytes(stream_.userFormat); + } - if ( handle->drainCounter > 1 ) { // write zeros to the output stream - bufferBytes = stream_.bufferSize * stream_.nUserChannels[0]; - bufferBytes *= formatBytes( stream_.userFormat ); - memset( stream_.userBuffer[0], 0, bufferBytes ); - } + // No byte swapping necessary in DirectSound implementation. - // Setup parameters and do buffer conversion if necessary. - if ( stream_.doConvertBuffer[0] ) { - buffer = stream_.deviceBuffer; - convertBuffer( buffer, stream_.userBuffer[0], stream_.convertInfo[0] ); - bufferBytes = stream_.bufferSize * stream_.nDeviceChannels[0]; - bufferBytes *= formatBytes( stream_.deviceFormat[0] ); - } - else { - buffer = stream_.userBuffer[0]; - bufferBytes = stream_.bufferSize * stream_.nUserChannels[0]; - bufferBytes *= formatBytes( stream_.userFormat ); - } + // Ahhh ... windoze. 16-bit data is signed but 8-bit data is + // unsigned. So, we need to convert our signed 8-bit data here to + // unsigned. + if (stream_.deviceFormat[0] == RTAUDIO_SINT8) + for (int i = 0; i < bufferBytes; i++) buffer[i] = (unsigned char)(buffer[i] + 128); - // No byte swapping necessary in DirectSound implementation. + DWORD dsBufferSize = handle->dsBufferSize[0]; + nextWritePointer = handle->bufferPointer[0]; - // Ahhh ... windoze. 16-bit data is signed but 8-bit data is - // unsigned. So, we need to convert our signed 8-bit data here to - // unsigned. - if ( stream_.deviceFormat[0] == RTAUDIO_SINT8 ) - for ( int i=0; iGetCurrentPosition(¤tWritePointer, &safeWritePointer); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString(result) << ") getting current write position!"; + errorText_ = errorStream_.str(); + MUTEX_UNLOCK(&stream_.mutex); + error(RtAudioError::SYSTEM_ERROR); + return; + } - DWORD dsBufferSize = handle->dsBufferSize[0]; - nextWritePointer = handle->bufferPointer[0]; + // We will copy our output buffer into the region between + // safeWritePointer and leadPointer. If leadPointer is not + // beyond the next endWrite position, wait until it is. + leadPointer = safeWritePointer + handle->dsPointerLeadTime[0]; + //std::cout << "safeWritePointer = " << safeWritePointer << ", leadPointer = " << leadPointer << ", nextWritePointer = " << nextWritePointer << std::endl; + if (leadPointer > dsBufferSize) leadPointer -= dsBufferSize; + if (leadPointer < nextWritePointer) leadPointer += dsBufferSize; // unwrap offset + endWrite = nextWritePointer + bufferBytes; - DWORD endWrite, leadPointer; - while ( true ) { - // Find out where the read and "safe write" pointers are. - result = dsBuffer->GetCurrentPosition( ¤tWritePointer, &safeWritePointer ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current write position!"; - errorText_ = errorStream_.str(); - MUTEX_UNLOCK( &stream_.mutex ); - error( RtAudioError::SYSTEM_ERROR ); - return; - } + // Check whether the entire write region is behind the play pointer. + if (leadPointer >= endWrite) break; - // We will copy our output buffer into the region between - // safeWritePointer and leadPointer. If leadPointer is not - // beyond the next endWrite position, wait until it is. - leadPointer = safeWritePointer + handle->dsPointerLeadTime[0]; - //std::cout << "safeWritePointer = " << safeWritePointer << ", leadPointer = " << leadPointer << ", nextWritePointer = " << nextWritePointer << std::endl; - if ( leadPointer > dsBufferSize ) leadPointer -= dsBufferSize; - if ( leadPointer < nextWritePointer ) leadPointer += dsBufferSize; // unwrap offset - endWrite = nextWritePointer + bufferBytes; + // If we are here, then we must wait until the leadPointer advances + // beyond the end of our next write region. We use the + // Sleep() function to suspend operation until that happens. + double millis = (endWrite - leadPointer) * 1000.0; + millis /= (formatBytes(stream_.deviceFormat[0]) * stream_.nDeviceChannels[0] * stream_.sampleRate); + if (millis < 1.0) millis = 1.0; + Sleep((DWORD)millis); + } - // Check whether the entire write region is behind the play pointer. - if ( leadPointer >= endWrite ) break; + if (dsPointerBetween(nextWritePointer, safeWritePointer, currentWritePointer, dsBufferSize) || dsPointerBetween(endWrite, safeWritePointer, currentWritePointer, dsBufferSize)) + { + // We've strayed into the forbidden zone ... resync the read pointer. + handle->xrun[0] = true; + nextWritePointer = safeWritePointer + handle->dsPointerLeadTime[0] - bufferBytes; + if (nextWritePointer >= dsBufferSize) nextWritePointer -= dsBufferSize; + handle->bufferPointer[0] = nextWritePointer; + endWrite = nextWritePointer + bufferBytes; + } - // If we are here, then we must wait until the leadPointer advances - // beyond the end of our next write region. We use the - // Sleep() function to suspend operation until that happens. - double millis = ( endWrite - leadPointer ) * 1000.0; - millis /= ( formatBytes( stream_.deviceFormat[0]) * stream_.nDeviceChannels[0] * stream_.sampleRate); - if ( millis < 1.0 ) millis = 1.0; - Sleep( (DWORD) millis ); - } + // Lock free space in the buffer + result = dsBuffer->Lock(nextWritePointer, bufferBytes, &buffer1, + &bufferSize1, &buffer2, &bufferSize2, 0); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString(result) << ") locking buffer during playback!"; + errorText_ = errorStream_.str(); + MUTEX_UNLOCK(&stream_.mutex); + error(RtAudioError::SYSTEM_ERROR); + return; + } - if ( dsPointerBetween( nextWritePointer, safeWritePointer, currentWritePointer, dsBufferSize ) - || dsPointerBetween( endWrite, safeWritePointer, currentWritePointer, dsBufferSize ) ) { - // We've strayed into the forbidden zone ... resync the read pointer. - handle->xrun[0] = true; - nextWritePointer = safeWritePointer + handle->dsPointerLeadTime[0] - bufferBytes; - if ( nextWritePointer >= dsBufferSize ) nextWritePointer -= dsBufferSize; - handle->bufferPointer[0] = nextWritePointer; - endWrite = nextWritePointer + bufferBytes; - } + // Copy our buffer into the DS buffer + CopyMemory(buffer1, buffer, bufferSize1); + if (buffer2 != NULL) CopyMemory(buffer2, buffer + bufferSize1, bufferSize2); - // Lock free space in the buffer - result = dsBuffer->Lock( nextWritePointer, bufferBytes, &buffer1, - &bufferSize1, &buffer2, &bufferSize2, 0 ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking buffer during playback!"; - errorText_ = errorStream_.str(); - MUTEX_UNLOCK( &stream_.mutex ); - error( RtAudioError::SYSTEM_ERROR ); - return; - } + // Update our buffer offset and unlock sound buffer + dsBuffer->Unlock(buffer1, bufferSize1, buffer2, bufferSize2); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString(result) << ") unlocking buffer during playback!"; + errorText_ = errorStream_.str(); + MUTEX_UNLOCK(&stream_.mutex); + error(RtAudioError::SYSTEM_ERROR); + return; + } + nextWritePointer = (nextWritePointer + bufferSize1 + bufferSize2) % dsBufferSize; + handle->bufferPointer[0] = nextWritePointer; + } - // Copy our buffer into the DS buffer - CopyMemory( buffer1, buffer, bufferSize1 ); - if ( buffer2 != NULL ) CopyMemory( buffer2, buffer+bufferSize1, bufferSize2 ); + // Don't bother draining input + if (handle->drainCounter) + { + handle->drainCounter++; + goto unlock; + } - // Update our buffer offset and unlock sound buffer - dsBuffer->Unlock( buffer1, bufferSize1, buffer2, bufferSize2 ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking buffer during playback!"; - errorText_ = errorStream_.str(); - MUTEX_UNLOCK( &stream_.mutex ); - error( RtAudioError::SYSTEM_ERROR ); - return; - } - nextWritePointer = ( nextWritePointer + bufferSize1 + bufferSize2 ) % dsBufferSize; - handle->bufferPointer[0] = nextWritePointer; - } + if (stream_.mode == INPUT || stream_.mode == DUPLEX) + { + // Setup parameters. + if (stream_.doConvertBuffer[1]) + { + buffer = stream_.deviceBuffer; + bufferBytes = stream_.bufferSize * stream_.nDeviceChannels[1]; + bufferBytes *= formatBytes(stream_.deviceFormat[1]); + } + else + { + buffer = stream_.userBuffer[1]; + bufferBytes = stream_.bufferSize * stream_.nUserChannels[1]; + bufferBytes *= formatBytes(stream_.userFormat); + } - // Don't bother draining input - if ( handle->drainCounter ) { - handle->drainCounter++; - goto unlock; - } + LPDIRECTSOUNDCAPTUREBUFFER dsBuffer = (LPDIRECTSOUNDCAPTUREBUFFER)handle->buffer[1]; + long nextReadPointer = handle->bufferPointer[1]; + DWORD dsBufferSize = handle->dsBufferSize[1]; - if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) { + // Find out where the write and "safe read" pointers are. + result = dsBuffer->GetCurrentPosition(¤tReadPointer, &safeReadPointer); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString(result) << ") getting current read position!"; + errorText_ = errorStream_.str(); + MUTEX_UNLOCK(&stream_.mutex); + error(RtAudioError::SYSTEM_ERROR); + return; + } - // Setup parameters. - if ( stream_.doConvertBuffer[1] ) { - buffer = stream_.deviceBuffer; - bufferBytes = stream_.bufferSize * stream_.nDeviceChannels[1]; - bufferBytes *= formatBytes( stream_.deviceFormat[1] ); - } - else { - buffer = stream_.userBuffer[1]; - bufferBytes = stream_.bufferSize * stream_.nUserChannels[1]; - bufferBytes *= formatBytes( stream_.userFormat ); - } + if (safeReadPointer < (DWORD)nextReadPointer) safeReadPointer += dsBufferSize; // unwrap offset + DWORD endRead = nextReadPointer + bufferBytes; - LPDIRECTSOUNDCAPTUREBUFFER dsBuffer = (LPDIRECTSOUNDCAPTUREBUFFER) handle->buffer[1]; - long nextReadPointer = handle->bufferPointer[1]; - DWORD dsBufferSize = handle->dsBufferSize[1]; + // Handling depends on whether we are INPUT or DUPLEX. + // If we're in INPUT mode then waiting is a good thing. If we're in DUPLEX mode, + // then a wait here will drag the write pointers into the forbidden zone. + // + // In DUPLEX mode, rather than wait, we will back off the read pointer until + // it's in a safe position. This causes dropouts, but it seems to be the only + // practical way to sync up the read and write pointers reliably, given the + // the very complex relationship between phase and increment of the read and write + // pointers. + // + // In order to minimize audible dropouts in DUPLEX mode, we will + // provide a pre-roll period of 0.5 seconds in which we return + // zeros from the read buffer while the pointers sync up. - // Find out where the write and "safe read" pointers are. - result = dsBuffer->GetCurrentPosition( ¤tReadPointer, &safeReadPointer ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!"; - errorText_ = errorStream_.str(); - MUTEX_UNLOCK( &stream_.mutex ); - error( RtAudioError::SYSTEM_ERROR ); - return; - } + if (stream_.mode == DUPLEX) + { + if (safeReadPointer < endRead) + { + if (duplexPrerollBytes <= 0) + { + // Pre-roll time over. Be more agressive. + int adjustment = endRead - safeReadPointer; - if ( safeReadPointer < (DWORD)nextReadPointer ) safeReadPointer += dsBufferSize; // unwrap offset - DWORD endRead = nextReadPointer + bufferBytes; + handle->xrun[1] = true; + // Two cases: + // - large adjustments: we've probably run out of CPU cycles, so just resync exactly, + // and perform fine adjustments later. + // - small adjustments: back off by twice as much. + if (adjustment >= 2 * bufferBytes) + nextReadPointer = safeReadPointer - 2 * bufferBytes; + else + nextReadPointer = safeReadPointer - bufferBytes - adjustment; - // Handling depends on whether we are INPUT or DUPLEX. - // If we're in INPUT mode then waiting is a good thing. If we're in DUPLEX mode, - // then a wait here will drag the write pointers into the forbidden zone. - // - // In DUPLEX mode, rather than wait, we will back off the read pointer until - // it's in a safe position. This causes dropouts, but it seems to be the only - // practical way to sync up the read and write pointers reliably, given the - // the very complex relationship between phase and increment of the read and write - // pointers. - // - // In order to minimize audible dropouts in DUPLEX mode, we will - // provide a pre-roll period of 0.5 seconds in which we return - // zeros from the read buffer while the pointers sync up. + if (nextReadPointer < 0) nextReadPointer += dsBufferSize; + } + else + { + // In pre=roll time. Just do it. + nextReadPointer = safeReadPointer - bufferBytes; + while (nextReadPointer < 0) nextReadPointer += dsBufferSize; + } + endRead = nextReadPointer + bufferBytes; + } + } + else + { // mode == INPUT + while (safeReadPointer < endRead && stream_.callbackInfo.isRunning) + { + // See comments for playback. + double millis = (endRead - safeReadPointer) * 1000.0; + millis /= (formatBytes(stream_.deviceFormat[1]) * stream_.nDeviceChannels[1] * stream_.sampleRate); + if (millis < 1.0) millis = 1.0; + Sleep((DWORD)millis); - if ( stream_.mode == DUPLEX ) { - if ( safeReadPointer < endRead ) { - if ( duplexPrerollBytes <= 0 ) { - // Pre-roll time over. Be more agressive. - int adjustment = endRead-safeReadPointer; + // Wake up and find out where we are now. + result = dsBuffer->GetCurrentPosition(¤tReadPointer, &safeReadPointer); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString(result) << ") getting current read position!"; + errorText_ = errorStream_.str(); + MUTEX_UNLOCK(&stream_.mutex); + error(RtAudioError::SYSTEM_ERROR); + return; + } - handle->xrun[1] = true; - // Two cases: - // - large adjustments: we've probably run out of CPU cycles, so just resync exactly, - // and perform fine adjustments later. - // - small adjustments: back off by twice as much. - if ( adjustment >= 2*bufferBytes ) - nextReadPointer = safeReadPointer-2*bufferBytes; - else - nextReadPointer = safeReadPointer-bufferBytes-adjustment; + if (safeReadPointer < (DWORD)nextReadPointer) safeReadPointer += dsBufferSize; // unwrap offset + } + } - if ( nextReadPointer < 0 ) nextReadPointer += dsBufferSize; + // Lock free space in the buffer + result = dsBuffer->Lock(nextReadPointer, bufferBytes, &buffer1, + &bufferSize1, &buffer2, &bufferSize2, 0); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString(result) << ") locking capture buffer!"; + errorText_ = errorStream_.str(); + MUTEX_UNLOCK(&stream_.mutex); + error(RtAudioError::SYSTEM_ERROR); + return; + } - } - else { - // In pre=roll time. Just do it. - nextReadPointer = safeReadPointer - bufferBytes; - while ( nextReadPointer < 0 ) nextReadPointer += dsBufferSize; - } - endRead = nextReadPointer + bufferBytes; - } - } - else { // mode == INPUT - while ( safeReadPointer < endRead && stream_.callbackInfo.isRunning ) { - // See comments for playback. - double millis = (endRead - safeReadPointer) * 1000.0; - millis /= ( formatBytes(stream_.deviceFormat[1]) * stream_.nDeviceChannels[1] * stream_.sampleRate); - if ( millis < 1.0 ) millis = 1.0; - Sleep( (DWORD) millis ); + if (duplexPrerollBytes <= 0) + { + // Copy our buffer into the DS buffer + CopyMemory(buffer, buffer1, bufferSize1); + if (buffer2 != NULL) CopyMemory(buffer + bufferSize1, buffer2, bufferSize2); + } + else + { + memset(buffer, 0, bufferSize1); + if (buffer2 != NULL) memset(buffer + bufferSize1, 0, bufferSize2); + duplexPrerollBytes -= bufferSize1 + bufferSize2; + } - // Wake up and find out where we are now. - result = dsBuffer->GetCurrentPosition( ¤tReadPointer, &safeReadPointer ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") getting current read position!"; - errorText_ = errorStream_.str(); - MUTEX_UNLOCK( &stream_.mutex ); - error( RtAudioError::SYSTEM_ERROR ); - return; - } - - if ( safeReadPointer < (DWORD)nextReadPointer ) safeReadPointer += dsBufferSize; // unwrap offset - } - } + // Update our buffer offset and unlock sound buffer + nextReadPointer = (nextReadPointer + bufferSize1 + bufferSize2) % dsBufferSize; + dsBuffer->Unlock(buffer1, bufferSize1, buffer2, bufferSize2); + if (FAILED(result)) + { + errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString(result) << ") unlocking capture buffer!"; + errorText_ = errorStream_.str(); + MUTEX_UNLOCK(&stream_.mutex); + error(RtAudioError::SYSTEM_ERROR); + return; + } + handle->bufferPointer[1] = nextReadPointer; - // Lock free space in the buffer - result = dsBuffer->Lock( nextReadPointer, bufferBytes, &buffer1, - &bufferSize1, &buffer2, &bufferSize2, 0 ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") locking capture buffer!"; - errorText_ = errorStream_.str(); - MUTEX_UNLOCK( &stream_.mutex ); - error( RtAudioError::SYSTEM_ERROR ); - return; - } + // No byte swapping necessary in DirectSound implementation. - if ( duplexPrerollBytes <= 0 ) { - // Copy our buffer into the DS buffer - CopyMemory( buffer, buffer1, bufferSize1 ); - if ( buffer2 != NULL ) CopyMemory( buffer+bufferSize1, buffer2, bufferSize2 ); - } - else { - memset( buffer, 0, bufferSize1 ); - if ( buffer2 != NULL ) memset( buffer + bufferSize1, 0, bufferSize2 ); - duplexPrerollBytes -= bufferSize1 + bufferSize2; - } + // If necessary, convert 8-bit data from unsigned to signed. + if (stream_.deviceFormat[1] == RTAUDIO_SINT8) + for (int j = 0; j < bufferBytes; j++) buffer[j] = (signed char)(buffer[j] - 128); - // Update our buffer offset and unlock sound buffer - nextReadPointer = ( nextReadPointer + bufferSize1 + bufferSize2 ) % dsBufferSize; - dsBuffer->Unlock( buffer1, bufferSize1, buffer2, bufferSize2 ); - if ( FAILED( result ) ) { - errorStream_ << "RtApiDs::callbackEvent: error (" << getErrorString( result ) << ") unlocking capture buffer!"; - errorText_ = errorStream_.str(); - MUTEX_UNLOCK( &stream_.mutex ); - error( RtAudioError::SYSTEM_ERROR ); - return; - } - handle->bufferPointer[1] = nextReadPointer; + // Do buffer conversion if necessary. + if (stream_.doConvertBuffer[1]) + convertBuffer(stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1]); + } - // No byte swapping necessary in DirectSound implementation. - - // If necessary, convert 8-bit data from unsigned to signed. - if ( stream_.deviceFormat[1] == RTAUDIO_SINT8 ) - for ( int j=0; jobject; - bool* isRunning = &info->isRunning; + CallbackInfo *info = (CallbackInfo *)ptr; + RtApiDs *object = (RtApiDs *)info->object; + bool *isRunning = &info->isRunning; - while ( *isRunning == true ) { - object->callbackEvent(); - } + while (*isRunning == true) + { + object->callbackEvent(); + } - _endthreadex( 0 ); - return 0; + _endthreadex(0); + return 0; } -static BOOL CALLBACK deviceQueryCallback( LPGUID lpguid, - LPCTSTR description, - LPCTSTR /*module*/, - LPVOID lpContext ) +static BOOL CALLBACK deviceQueryCallback(LPGUID lpguid, + LPCTSTR description, + LPCTSTR /*module*/, + LPVOID lpContext) { - struct DsProbeData& probeInfo = *(struct DsProbeData*) lpContext; - std::vector& dsDevices = *probeInfo.dsDevices; + struct DsProbeData &probeInfo = *(struct DsProbeData *)lpContext; + std::vector &dsDevices = *probeInfo.dsDevices; - HRESULT hr; - bool validDevice = false; - if ( probeInfo.isInput == true ) { - DSCCAPS caps; - LPDIRECTSOUNDCAPTURE object; + HRESULT hr; + bool validDevice = false; + if (probeInfo.isInput == true) + { + DSCCAPS caps; + LPDIRECTSOUNDCAPTURE object; - hr = DirectSoundCaptureCreate( lpguid, &object, NULL ); - if ( hr != DS_OK ) return TRUE; + hr = DirectSoundCaptureCreate(lpguid, &object, NULL); + if (hr != DS_OK) return TRUE; - caps.dwSize = sizeof(caps); - hr = object->GetCaps( &caps ); - if ( hr == DS_OK ) { - if ( caps.dwChannels > 0 && caps.dwFormats > 0 ) - validDevice = true; - } - object->Release(); - } - else { - DSCAPS caps; - LPDIRECTSOUND object; - hr = DirectSoundCreate( lpguid, &object, NULL ); - if ( hr != DS_OK ) return TRUE; + caps.dwSize = sizeof(caps); + hr = object->GetCaps(&caps); + if (hr == DS_OK) + { + if (caps.dwChannels > 0 && caps.dwFormats > 0) + validDevice = true; + } + object->Release(); + } + else + { + DSCAPS caps; + LPDIRECTSOUND object; + hr = DirectSoundCreate(lpguid, &object, NULL); + if (hr != DS_OK) return TRUE; - caps.dwSize = sizeof(caps); - hr = object->GetCaps( &caps ); - if ( hr == DS_OK ) { - if ( caps.dwFlags & DSCAPS_PRIMARYMONO || caps.dwFlags & DSCAPS_PRIMARYSTEREO ) - validDevice = true; - } - object->Release(); - } + caps.dwSize = sizeof(caps); + hr = object->GetCaps(&caps); + if (hr == DS_OK) + { + if (caps.dwFlags & DSCAPS_PRIMARYMONO || caps.dwFlags & DSCAPS_PRIMARYSTEREO) + validDevice = true; + } + object->Release(); + } - // If good device, then save its name and guid. - std::string name = convertCharPointerToStdString( description ); - //if ( name == "Primary Sound Driver" || name == "Primary Sound Capture Driver" ) - if ( lpguid == NULL ) - name = "Default Device"; - if ( validDevice ) { - for ( unsigned int i=0; i #include - // A structure to hold various information related to the ALSA API - // implementation. -struct AlsaHandle { - snd_pcm_t *handles[2]; - bool synchronized; - bool xrun[2]; - pthread_cond_t runnable_cv; - bool runnable; +// A structure to hold various information related to the ALSA API +// implementation. +struct AlsaHandle +{ + snd_pcm_t *handles[2]; + bool synchronized; + bool xrun[2]; + pthread_cond_t runnable_cv; + bool runnable; - AlsaHandle() - :synchronized(false), runnable(false) { xrun[0] = false; xrun[1] = false; } + AlsaHandle() + : synchronized(false), runnable(false) + { + xrun[0] = false; + xrun[1] = false; + } }; -static void *alsaCallbackHandler( void * ptr ); +static void *alsaCallbackHandler(void *ptr); -RtApiAlsa :: RtApiAlsa() +RtApiAlsa ::RtApiAlsa() { - // Nothing to do here. + // Nothing to do here. } -RtApiAlsa :: ~RtApiAlsa() +RtApiAlsa ::~RtApiAlsa() { - if ( stream_.state != STREAM_CLOSED ) closeStream(); + if (stream_.state != STREAM_CLOSED) closeStream(); } -unsigned int RtApiAlsa :: getDeviceCount( void ) +unsigned int RtApiAlsa ::getDeviceCount(void) { - unsigned nDevices = 0; - int result, subdevice, card; - char name[64]; - snd_ctl_t *handle; + unsigned nDevices = 0; + int result, subdevice, card; + char name[64]; + snd_ctl_t *handle; - // Count cards and devices - card = -1; - snd_card_next( &card ); - while ( card >= 0 ) { - sprintf( name, "hw:%d", card ); - result = snd_ctl_open( &handle, name, 0 ); - if ( result < 0 ) { - errorStream_ << "RtApiAlsa::getDeviceCount: control open, card = " << card << ", " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - goto nextcard; - } - subdevice = -1; - while( 1 ) { - result = snd_ctl_pcm_next_device( handle, &subdevice ); - if ( result < 0 ) { - errorStream_ << "RtApiAlsa::getDeviceCount: control next device, card = " << card << ", " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - break; - } - if ( subdevice < 0 ) - break; - nDevices++; - } - nextcard: - snd_ctl_close( handle ); - snd_card_next( &card ); - } + // Count cards and devices + card = -1; + snd_card_next(&card); + while (card >= 0) + { + sprintf(name, "hw:%d", card); + result = snd_ctl_open(&handle, name, 0); + if (result < 0) + { + errorStream_ << "RtApiAlsa::getDeviceCount: control open, card = " << card << ", " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + goto nextcard; + } + subdevice = -1; + while (1) + { + result = snd_ctl_pcm_next_device(handle, &subdevice); + if (result < 0) + { + errorStream_ << "RtApiAlsa::getDeviceCount: control next device, card = " << card << ", " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + break; + } + if (subdevice < 0) + break; + nDevices++; + } + nextcard: + snd_ctl_close(handle); + snd_card_next(&card); + } - result = snd_ctl_open( &handle, "default", 0 ); - if (result == 0) { - nDevices++; - snd_ctl_close( handle ); - } + result = snd_ctl_open(&handle, "default", 0); + if (result == 0) + { + nDevices++; + snd_ctl_close(handle); + } - return nDevices; + return nDevices; } -RtAudio::DeviceInfo RtApiAlsa :: getDeviceInfo( unsigned int device ) +RtAudio::DeviceInfo RtApiAlsa ::getDeviceInfo(unsigned int device) { - RtAudio::DeviceInfo info; - info.probed = false; + RtAudio::DeviceInfo info; + info.probed = false; - unsigned nDevices = 0; - int result, subdevice, card; - char name[64]; - snd_ctl_t *chandle; + unsigned nDevices = 0; + int result, subdevice, card; + char name[64]; + snd_ctl_t *chandle; - // Count cards and devices - card = -1; - subdevice = -1; - snd_card_next( &card ); - while ( card >= 0 ) { - sprintf( name, "hw:%d", card ); - result = snd_ctl_open( &chandle, name, SND_CTL_NONBLOCK ); - if ( result < 0 ) { - errorStream_ << "RtApiAlsa::getDeviceInfo: control open, card = " << card << ", " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - goto nextcard; - } - subdevice = -1; - while( 1 ) { - result = snd_ctl_pcm_next_device( chandle, &subdevice ); - if ( result < 0 ) { - errorStream_ << "RtApiAlsa::getDeviceInfo: control next device, card = " << card << ", " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - break; - } - if ( subdevice < 0 ) break; - if ( nDevices == device ) { - sprintf( name, "hw:%d,%d", card, subdevice ); - goto foundDevice; - } - nDevices++; - } - nextcard: - snd_ctl_close( chandle ); - snd_card_next( &card ); - } + // Count cards and devices + card = -1; + subdevice = -1; + snd_card_next(&card); + while (card >= 0) + { + sprintf(name, "hw:%d", card); + result = snd_ctl_open(&chandle, name, SND_CTL_NONBLOCK); + if (result < 0) + { + errorStream_ << "RtApiAlsa::getDeviceInfo: control open, card = " << card << ", " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + goto nextcard; + } + subdevice = -1; + while (1) + { + result = snd_ctl_pcm_next_device(chandle, &subdevice); + if (result < 0) + { + errorStream_ << "RtApiAlsa::getDeviceInfo: control next device, card = " << card << ", " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + break; + } + if (subdevice < 0) break; + if (nDevices == device) + { + sprintf(name, "hw:%d,%d", card, subdevice); + goto foundDevice; + } + nDevices++; + } + nextcard: + snd_ctl_close(chandle); + snd_card_next(&card); + } - result = snd_ctl_open( &chandle, "default", SND_CTL_NONBLOCK ); - if ( result == 0 ) { - if ( nDevices == device ) { - strcpy( name, "default" ); - goto foundDevice; - } - nDevices++; - } + result = snd_ctl_open(&chandle, "default", SND_CTL_NONBLOCK); + if (result == 0) + { + if (nDevices == device) + { + strcpy(name, "default"); + goto foundDevice; + } + nDevices++; + } - if ( nDevices == 0 ) { - errorText_ = "RtApiAlsa::getDeviceInfo: no devices found!"; - error( RtAudioError::INVALID_USE ); - return info; - } + if (nDevices == 0) + { + errorText_ = "RtApiAlsa::getDeviceInfo: no devices found!"; + error(RtAudioError::INVALID_USE); + return info; + } - if ( device >= nDevices ) { - errorText_ = "RtApiAlsa::getDeviceInfo: device ID is invalid!"; - error( RtAudioError::INVALID_USE ); - return info; - } + if (device >= nDevices) + { + errorText_ = "RtApiAlsa::getDeviceInfo: device ID is invalid!"; + error(RtAudioError::INVALID_USE); + return info; + } - foundDevice: +foundDevice: - // If a stream is already open, we cannot probe the stream devices. - // Thus, use the saved results. - if ( stream_.state != STREAM_CLOSED && - ( stream_.device[0] == device || stream_.device[1] == device ) ) { - snd_ctl_close( chandle ); - if ( device >= devices_.size() ) { - errorText_ = "RtApiAlsa::getDeviceInfo: device ID was not present before stream was opened."; - error( RtAudioError::WARNING ); - return info; - } - return devices_[ device ]; - } + // If a stream is already open, we cannot probe the stream devices. + // Thus, use the saved results. + if (stream_.state != STREAM_CLOSED && + (stream_.device[0] == device || stream_.device[1] == device)) + { + snd_ctl_close(chandle); + if (device >= devices_.size()) + { + errorText_ = "RtApiAlsa::getDeviceInfo: device ID was not present before stream was opened."; + error(RtAudioError::WARNING); + return info; + } + return devices_[device]; + } - int openMode = SND_PCM_ASYNC; - snd_pcm_stream_t stream; - snd_pcm_info_t *pcminfo; - snd_pcm_info_alloca( &pcminfo ); - snd_pcm_t *phandle; - snd_pcm_hw_params_t *params; - snd_pcm_hw_params_alloca( ¶ms ); + int openMode = SND_PCM_ASYNC; + snd_pcm_stream_t stream; + snd_pcm_info_t *pcminfo; + snd_pcm_info_alloca(&pcminfo); + snd_pcm_t *phandle; + snd_pcm_hw_params_t *params; + snd_pcm_hw_params_alloca(¶ms); - // First try for playback unless default device (which has subdev -1) - stream = SND_PCM_STREAM_PLAYBACK; - snd_pcm_info_set_stream( pcminfo, stream ); - if ( subdevice != -1 ) { - snd_pcm_info_set_device( pcminfo, subdevice ); - snd_pcm_info_set_subdevice( pcminfo, 0 ); + // First try for playback unless default device (which has subdev -1) + stream = SND_PCM_STREAM_PLAYBACK; + snd_pcm_info_set_stream(pcminfo, stream); + if (subdevice != -1) + { + snd_pcm_info_set_device(pcminfo, subdevice); + snd_pcm_info_set_subdevice(pcminfo, 0); - result = snd_ctl_pcm_info( chandle, pcminfo ); - if ( result < 0 ) { - // Device probably doesn't support playback. - goto captureProbe; - } - } + result = snd_ctl_pcm_info(chandle, pcminfo); + if (result < 0) + { + // Device probably doesn't support playback. + goto captureProbe; + } + } - result = snd_pcm_open( &phandle, name, stream, openMode | SND_PCM_NONBLOCK ); - if ( result < 0 ) { - errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_open error for device (" << name << "), " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - goto captureProbe; - } + result = snd_pcm_open(&phandle, name, stream, openMode | SND_PCM_NONBLOCK); + if (result < 0) + { + errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_open error for device (" << name << "), " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + goto captureProbe; + } - // The device is open ... fill the parameter structure. - result = snd_pcm_hw_params_any( phandle, params ); - if ( result < 0 ) { - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - goto captureProbe; - } + // The device is open ... fill the parameter structure. + result = snd_pcm_hw_params_any(phandle, params); + if (result < 0) + { + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + goto captureProbe; + } - // Get output channel information. - unsigned int value; - result = snd_pcm_hw_params_get_channels_max( params, &value ); - if ( result < 0 ) { - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::getDeviceInfo: error getting device (" << name << ") output channels, " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - goto captureProbe; - } - info.outputChannels = value; - snd_pcm_close( phandle ); + // Get output channel information. + unsigned int value; + result = snd_pcm_hw_params_get_channels_max(params, &value); + if (result < 0) + { + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::getDeviceInfo: error getting device (" << name << ") output channels, " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + goto captureProbe; + } + info.outputChannels = value; + snd_pcm_close(phandle); - captureProbe: - stream = SND_PCM_STREAM_CAPTURE; - snd_pcm_info_set_stream( pcminfo, stream ); +captureProbe: + stream = SND_PCM_STREAM_CAPTURE; + snd_pcm_info_set_stream(pcminfo, stream); - // Now try for capture unless default device (with subdev = -1) - if ( subdevice != -1 ) { - result = snd_ctl_pcm_info( chandle, pcminfo ); - snd_ctl_close( chandle ); - if ( result < 0 ) { - // Device probably doesn't support capture. - if ( info.outputChannels == 0 ) return info; - goto probeParameters; - } - } - else - snd_ctl_close( chandle ); + // Now try for capture unless default device (with subdev = -1) + if (subdevice != -1) + { + result = snd_ctl_pcm_info(chandle, pcminfo); + snd_ctl_close(chandle); + if (result < 0) + { + // Device probably doesn't support capture. + if (info.outputChannels == 0) return info; + goto probeParameters; + } + } + else + snd_ctl_close(chandle); - result = snd_pcm_open( &phandle, name, stream, openMode | SND_PCM_NONBLOCK); - if ( result < 0 ) { - errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_open error for device (" << name << "), " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - if ( info.outputChannels == 0 ) return info; - goto probeParameters; - } + result = snd_pcm_open(&phandle, name, stream, openMode | SND_PCM_NONBLOCK); + if (result < 0) + { + errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_open error for device (" << name << "), " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + if (info.outputChannels == 0) return info; + goto probeParameters; + } - // The device is open ... fill the parameter structure. - result = snd_pcm_hw_params_any( phandle, params ); - if ( result < 0 ) { - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - if ( info.outputChannels == 0 ) return info; - goto probeParameters; - } + // The device is open ... fill the parameter structure. + result = snd_pcm_hw_params_any(phandle, params); + if (result < 0) + { + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + if (info.outputChannels == 0) return info; + goto probeParameters; + } - result = snd_pcm_hw_params_get_channels_max( params, &value ); - if ( result < 0 ) { - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::getDeviceInfo: error getting device (" << name << ") input channels, " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - if ( info.outputChannels == 0 ) return info; - goto probeParameters; - } - info.inputChannels = value; - snd_pcm_close( phandle ); + result = snd_pcm_hw_params_get_channels_max(params, &value); + if (result < 0) + { + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::getDeviceInfo: error getting device (" << name << ") input channels, " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + if (info.outputChannels == 0) return info; + goto probeParameters; + } + info.inputChannels = value; + snd_pcm_close(phandle); - // If device opens for both playback and capture, we determine the channels. - if ( info.outputChannels > 0 && info.inputChannels > 0 ) - info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels; + // If device opens for both playback and capture, we determine the channels. + if (info.outputChannels > 0 && info.inputChannels > 0) + info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels; - // ALSA doesn't provide default devices so we'll use the first available one. - if ( device == 0 && info.outputChannels > 0 ) - info.isDefaultOutput = true; - if ( device == 0 && info.inputChannels > 0 ) - info.isDefaultInput = true; + // ALSA doesn't provide default devices so we'll use the first available one. + if (device == 0 && info.outputChannels > 0) + info.isDefaultOutput = true; + if (device == 0 && info.inputChannels > 0) + info.isDefaultInput = true; - probeParameters: - // At this point, we just need to figure out the supported data - // formats and sample rates. We'll proceed by opening the device in - // the direction with the maximum number of channels, or playback if - // they are equal. This might limit our sample rate options, but so - // be it. +probeParameters: + // At this point, we just need to figure out the supported data + // formats and sample rates. We'll proceed by opening the device in + // the direction with the maximum number of channels, or playback if + // they are equal. This might limit our sample rate options, but so + // be it. - if ( info.outputChannels >= info.inputChannels ) - stream = SND_PCM_STREAM_PLAYBACK; - else - stream = SND_PCM_STREAM_CAPTURE; - snd_pcm_info_set_stream( pcminfo, stream ); + if (info.outputChannels >= info.inputChannels) + stream = SND_PCM_STREAM_PLAYBACK; + else + stream = SND_PCM_STREAM_CAPTURE; + snd_pcm_info_set_stream(pcminfo, stream); - result = snd_pcm_open( &phandle, name, stream, openMode | SND_PCM_NONBLOCK); - if ( result < 0 ) { - errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_open error for device (" << name << "), " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + result = snd_pcm_open(&phandle, name, stream, openMode | SND_PCM_NONBLOCK); + if (result < 0) + { + errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_open error for device (" << name << "), " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - // The device is open ... fill the parameter structure. - result = snd_pcm_hw_params_any( phandle, params ); - if ( result < 0 ) { - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + // The device is open ... fill the parameter structure. + result = snd_pcm_hw_params_any(phandle, params); + if (result < 0) + { + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::getDeviceInfo: snd_pcm_hw_params error for device (" << name << "), " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - // Test our discrete set of sample rate values. - info.sampleRates.clear(); - for ( unsigned int i=0; i info.preferredSampleRate ) ) - info.preferredSampleRate = SAMPLE_RATES[i]; - } - } - if ( info.sampleRates.size() == 0 ) { - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::getDeviceInfo: no supported sample rates found for device (" << name << ")."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + if (!info.preferredSampleRate || (SAMPLE_RATES[i] <= 48000 && SAMPLE_RATES[i] > info.preferredSampleRate)) + info.preferredSampleRate = SAMPLE_RATES[i]; + } + } + if (info.sampleRates.size() == 0) + { + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::getDeviceInfo: no supported sample rates found for device (" << name << ")."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - // Probe the supported data formats ... we don't care about endian-ness just yet - snd_pcm_format_t format; - info.nativeFormats = 0; - format = SND_PCM_FORMAT_S8; - if ( snd_pcm_hw_params_test_format( phandle, params, format ) == 0 ) - info.nativeFormats |= RTAUDIO_SINT8; - format = SND_PCM_FORMAT_S16; - if ( snd_pcm_hw_params_test_format( phandle, params, format ) == 0 ) - info.nativeFormats |= RTAUDIO_SINT16; - format = SND_PCM_FORMAT_S24; - if ( snd_pcm_hw_params_test_format( phandle, params, format ) == 0 ) - info.nativeFormats |= RTAUDIO_SINT24; - format = SND_PCM_FORMAT_S32; - if ( snd_pcm_hw_params_test_format( phandle, params, format ) == 0 ) - info.nativeFormats |= RTAUDIO_SINT32; - format = SND_PCM_FORMAT_FLOAT; - if ( snd_pcm_hw_params_test_format( phandle, params, format ) == 0 ) - info.nativeFormats |= RTAUDIO_FLOAT32; - format = SND_PCM_FORMAT_FLOAT64; - if ( snd_pcm_hw_params_test_format( phandle, params, format ) == 0 ) - info.nativeFormats |= RTAUDIO_FLOAT64; + // Probe the supported data formats ... we don't care about endian-ness just yet + snd_pcm_format_t format; + info.nativeFormats = 0; + format = SND_PCM_FORMAT_S8; + if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) + info.nativeFormats |= RTAUDIO_SINT8; + format = SND_PCM_FORMAT_S16; + if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) + info.nativeFormats |= RTAUDIO_SINT16; + format = SND_PCM_FORMAT_S24; + if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) + info.nativeFormats |= RTAUDIO_SINT24; + format = SND_PCM_FORMAT_S32; + if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) + info.nativeFormats |= RTAUDIO_SINT32; + format = SND_PCM_FORMAT_FLOAT; + if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) + info.nativeFormats |= RTAUDIO_FLOAT32; + format = SND_PCM_FORMAT_FLOAT64; + if (snd_pcm_hw_params_test_format(phandle, params, format) == 0) + info.nativeFormats |= RTAUDIO_FLOAT64; - // Check that we have at least one supported format - if ( info.nativeFormats == 0 ) { - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::getDeviceInfo: pcm device (" << name << ") data format not supported by RtAudio."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + // Check that we have at least one supported format + if (info.nativeFormats == 0) + { + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::getDeviceInfo: pcm device (" << name << ") data format not supported by RtAudio."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - // Get the device name - char *cardname; - result = snd_card_get_name( card, &cardname ); - if ( result >= 0 ) { - sprintf( name, "hw:%s,%d", cardname, subdevice ); - free( cardname ); - } - info.name = name; + // Get the device name + char *cardname; + result = snd_card_get_name(card, &cardname); + if (result >= 0) + { + sprintf(name, "hw:%s,%d", cardname, subdevice); + free(cardname); + } + info.name = name; - // That's all ... close the device and return - snd_pcm_close( phandle ); - info.probed = true; - return info; + // That's all ... close the device and return + snd_pcm_close(phandle); + info.probed = true; + return info; } -void RtApiAlsa :: saveDeviceInfo( void ) +void RtApiAlsa ::saveDeviceInfo(void) { - devices_.clear(); + devices_.clear(); - unsigned int nDevices = getDeviceCount(); - devices_.resize( nDevices ); - for ( unsigned int i=0; iflags & RTAUDIO_ALSA_USE_DEFAULT ) - snprintf(name, sizeof(name), "%s", "default"); - else { - // Count cards and devices - card = -1; - snd_card_next( &card ); - while ( card >= 0 ) { - sprintf( name, "hw:%d", card ); - result = snd_ctl_open( &chandle, name, SND_CTL_NONBLOCK ); - if ( result < 0 ) { - errorStream_ << "RtApiAlsa::probeDeviceOpen: control open, card = " << card << ", " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - return FAILURE; - } - subdevice = -1; - while( 1 ) { - result = snd_ctl_pcm_next_device( chandle, &subdevice ); - if ( result < 0 ) break; - if ( subdevice < 0 ) break; - if ( nDevices == device ) { - sprintf( name, "hw:%d,%d", card, subdevice ); - snd_ctl_close( chandle ); - goto foundDevice; - } - nDevices++; - } - snd_ctl_close( chandle ); - snd_card_next( &card ); - } + if (options && options->flags & RTAUDIO_ALSA_USE_DEFAULT) + snprintf(name, sizeof(name), "%s", "default"); + else + { + // Count cards and devices + card = -1; + snd_card_next(&card); + while (card >= 0) + { + sprintf(name, "hw:%d", card); + result = snd_ctl_open(&chandle, name, SND_CTL_NONBLOCK); + if (result < 0) + { + errorStream_ << "RtApiAlsa::probeDeviceOpen: control open, card = " << card << ", " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + return FAILURE; + } + subdevice = -1; + while (1) + { + result = snd_ctl_pcm_next_device(chandle, &subdevice); + if (result < 0) break; + if (subdevice < 0) break; + if (nDevices == device) + { + sprintf(name, "hw:%d,%d", card, subdevice); + snd_ctl_close(chandle); + goto foundDevice; + } + nDevices++; + } + snd_ctl_close(chandle); + snd_card_next(&card); + } - result = snd_ctl_open( &chandle, "default", SND_CTL_NONBLOCK ); - if ( result == 0 ) { - if ( nDevices == device ) { - strcpy( name, "default" ); - goto foundDevice; - } - nDevices++; - } + result = snd_ctl_open(&chandle, "default", SND_CTL_NONBLOCK); + if (result == 0) + { + if (nDevices == device) + { + strcpy(name, "default"); + goto foundDevice; + } + nDevices++; + } - if ( nDevices == 0 ) { - // This should not happen because a check is made before this function is called. - errorText_ = "RtApiAlsa::probeDeviceOpen: no devices found!"; - return FAILURE; - } + if (nDevices == 0) + { + // This should not happen because a check is made before this function is called. + errorText_ = "RtApiAlsa::probeDeviceOpen: no devices found!"; + return FAILURE; + } - if ( device >= nDevices ) { - // This should not happen because a check is made before this function is called. - errorText_ = "RtApiAlsa::probeDeviceOpen: device ID is invalid!"; - return FAILURE; - } - } + if (device >= nDevices) + { + // This should not happen because a check is made before this function is called. + errorText_ = "RtApiAlsa::probeDeviceOpen: device ID is invalid!"; + return FAILURE; + } + } - foundDevice: +foundDevice: - // The getDeviceInfo() function will not work for a device that is - // already open. Thus, we'll probe the system before opening a - // stream and save the results for use by getDeviceInfo(). - if ( mode == OUTPUT || ( mode == INPUT && stream_.mode != OUTPUT ) ) // only do once - this->saveDeviceInfo(); + // The getDeviceInfo() function will not work for a device that is + // already open. Thus, we'll probe the system before opening a + // stream and save the results for use by getDeviceInfo(). + if (mode == OUTPUT || (mode == INPUT && stream_.mode != OUTPUT)) // only do once + this->saveDeviceInfo(); - snd_pcm_stream_t stream; - if ( mode == OUTPUT ) - stream = SND_PCM_STREAM_PLAYBACK; - else - stream = SND_PCM_STREAM_CAPTURE; + snd_pcm_stream_t stream; + if (mode == OUTPUT) + stream = SND_PCM_STREAM_PLAYBACK; + else + stream = SND_PCM_STREAM_CAPTURE; - snd_pcm_t *phandle; - int openMode = SND_PCM_ASYNC; - result = snd_pcm_open( &phandle, name, stream, openMode ); - if ( result < 0 ) { - if ( mode == OUTPUT ) - errorStream_ << "RtApiAlsa::probeDeviceOpen: pcm device (" << name << ") won't open for output."; - else - errorStream_ << "RtApiAlsa::probeDeviceOpen: pcm device (" << name << ") won't open for input."; - errorText_ = errorStream_.str(); - return FAILURE; - } + snd_pcm_t *phandle; + int openMode = SND_PCM_ASYNC; + result = snd_pcm_open(&phandle, name, stream, openMode); + if (result < 0) + { + if (mode == OUTPUT) + errorStream_ << "RtApiAlsa::probeDeviceOpen: pcm device (" << name << ") won't open for output."; + else + errorStream_ << "RtApiAlsa::probeDeviceOpen: pcm device (" << name << ") won't open for input."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Fill the parameter structure. - snd_pcm_hw_params_t *hw_params; - snd_pcm_hw_params_alloca( &hw_params ); - result = snd_pcm_hw_params_any( phandle, hw_params ); - if ( result < 0 ) { - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting pcm device (" << name << ") parameters, " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Fill the parameter structure. + snd_pcm_hw_params_t *hw_params; + snd_pcm_hw_params_alloca(&hw_params); + result = snd_pcm_hw_params_any(phandle, hw_params); + if (result < 0) + { + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting pcm device (" << name << ") parameters, " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + return FAILURE; + } #if defined(__RTAUDIO_DEBUG__) - fprintf( stderr, "\nRtApiAlsa: dump hardware params just after device open:\n\n" ); - snd_pcm_hw_params_dump( hw_params, out ); + fprintf(stderr, "\nRtApiAlsa: dump hardware params just after device open:\n\n"); + snd_pcm_hw_params_dump(hw_params, out); #endif - // Set access ... check user preference. - if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) { - stream_.userInterleaved = false; - result = snd_pcm_hw_params_set_access( phandle, hw_params, SND_PCM_ACCESS_RW_NONINTERLEAVED ); - if ( result < 0 ) { - result = snd_pcm_hw_params_set_access( phandle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED ); - stream_.deviceInterleaved[mode] = true; - } - else - stream_.deviceInterleaved[mode] = false; - } - else { - stream_.userInterleaved = true; - result = snd_pcm_hw_params_set_access( phandle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED ); - if ( result < 0 ) { - result = snd_pcm_hw_params_set_access( phandle, hw_params, SND_PCM_ACCESS_RW_NONINTERLEAVED ); - stream_.deviceInterleaved[mode] = false; - } - else - stream_.deviceInterleaved[mode] = true; - } + // Set access ... check user preference. + if (options && options->flags & RTAUDIO_NONINTERLEAVED) + { + stream_.userInterleaved = false; + result = snd_pcm_hw_params_set_access(phandle, hw_params, SND_PCM_ACCESS_RW_NONINTERLEAVED); + if (result < 0) + { + result = snd_pcm_hw_params_set_access(phandle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); + stream_.deviceInterleaved[mode] = true; + } + else + stream_.deviceInterleaved[mode] = false; + } + else + { + stream_.userInterleaved = true; + result = snd_pcm_hw_params_set_access(phandle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); + if (result < 0) + { + result = snd_pcm_hw_params_set_access(phandle, hw_params, SND_PCM_ACCESS_RW_NONINTERLEAVED); + stream_.deviceInterleaved[mode] = false; + } + else + stream_.deviceInterleaved[mode] = true; + } - if ( result < 0 ) { - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting pcm device (" << name << ") access, " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - return FAILURE; - } + if (result < 0) + { + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting pcm device (" << name << ") access, " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Determine how to set the device format. - stream_.userFormat = format; - snd_pcm_format_t deviceFormat = SND_PCM_FORMAT_UNKNOWN; + // Determine how to set the device format. + stream_.userFormat = format; + snd_pcm_format_t deviceFormat = SND_PCM_FORMAT_UNKNOWN; - if ( format == RTAUDIO_SINT8 ) - deviceFormat = SND_PCM_FORMAT_S8; - else if ( format == RTAUDIO_SINT16 ) - deviceFormat = SND_PCM_FORMAT_S16; - else if ( format == RTAUDIO_SINT24 ) - deviceFormat = SND_PCM_FORMAT_S24; - else if ( format == RTAUDIO_SINT32 ) - deviceFormat = SND_PCM_FORMAT_S32; - else if ( format == RTAUDIO_FLOAT32 ) - deviceFormat = SND_PCM_FORMAT_FLOAT; - else if ( format == RTAUDIO_FLOAT64 ) - deviceFormat = SND_PCM_FORMAT_FLOAT64; + if (format == RTAUDIO_SINT8) + deviceFormat = SND_PCM_FORMAT_S8; + else if (format == RTAUDIO_SINT16) + deviceFormat = SND_PCM_FORMAT_S16; + else if (format == RTAUDIO_SINT24) + deviceFormat = SND_PCM_FORMAT_S24; + else if (format == RTAUDIO_SINT32) + deviceFormat = SND_PCM_FORMAT_S32; + else if (format == RTAUDIO_FLOAT32) + deviceFormat = SND_PCM_FORMAT_FLOAT; + else if (format == RTAUDIO_FLOAT64) + deviceFormat = SND_PCM_FORMAT_FLOAT64; - if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat) == 0) { - stream_.deviceFormat[mode] = format; - goto setFormat; - } + if (snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat) == 0) + { + stream_.deviceFormat[mode] = format; + goto setFormat; + } - // The user requested format is not natively supported by the device. - deviceFormat = SND_PCM_FORMAT_FLOAT64; - if ( snd_pcm_hw_params_test_format( phandle, hw_params, deviceFormat ) == 0 ) { - stream_.deviceFormat[mode] = RTAUDIO_FLOAT64; - goto setFormat; - } + // The user requested format is not natively supported by the device. + deviceFormat = SND_PCM_FORMAT_FLOAT64; + if (snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat) == 0) + { + stream_.deviceFormat[mode] = RTAUDIO_FLOAT64; + goto setFormat; + } - deviceFormat = SND_PCM_FORMAT_FLOAT; - if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat ) == 0 ) { - stream_.deviceFormat[mode] = RTAUDIO_FLOAT32; - goto setFormat; - } + deviceFormat = SND_PCM_FORMAT_FLOAT; + if (snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat) == 0) + { + stream_.deviceFormat[mode] = RTAUDIO_FLOAT32; + goto setFormat; + } - deviceFormat = SND_PCM_FORMAT_S32; - if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat ) == 0 ) { - stream_.deviceFormat[mode] = RTAUDIO_SINT32; - goto setFormat; - } + deviceFormat = SND_PCM_FORMAT_S32; + if (snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat) == 0) + { + stream_.deviceFormat[mode] = RTAUDIO_SINT32; + goto setFormat; + } - deviceFormat = SND_PCM_FORMAT_S24; - if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat ) == 0 ) { - stream_.deviceFormat[mode] = RTAUDIO_SINT24; - goto setFormat; - } + deviceFormat = SND_PCM_FORMAT_S24; + if (snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat) == 0) + { + stream_.deviceFormat[mode] = RTAUDIO_SINT24; + goto setFormat; + } - deviceFormat = SND_PCM_FORMAT_S16; - if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat ) == 0 ) { - stream_.deviceFormat[mode] = RTAUDIO_SINT16; - goto setFormat; - } + deviceFormat = SND_PCM_FORMAT_S16; + if (snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat) == 0) + { + stream_.deviceFormat[mode] = RTAUDIO_SINT16; + goto setFormat; + } - deviceFormat = SND_PCM_FORMAT_S8; - if ( snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat ) == 0 ) { - stream_.deviceFormat[mode] = RTAUDIO_SINT8; - goto setFormat; - } + deviceFormat = SND_PCM_FORMAT_S8; + if (snd_pcm_hw_params_test_format(phandle, hw_params, deviceFormat) == 0) + { + stream_.deviceFormat[mode] = RTAUDIO_SINT8; + goto setFormat; + } - // If we get here, no supported format was found. - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::probeDeviceOpen: pcm device " << device << " data format not supported by RtAudio."; - errorText_ = errorStream_.str(); - return FAILURE; + // If we get here, no supported format was found. + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::probeDeviceOpen: pcm device " << device << " data format not supported by RtAudio."; + errorText_ = errorStream_.str(); + return FAILURE; - setFormat: - result = snd_pcm_hw_params_set_format( phandle, hw_params, deviceFormat ); - if ( result < 0 ) { - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting pcm device (" << name << ") data format, " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - return FAILURE; - } +setFormat: + result = snd_pcm_hw_params_set_format(phandle, hw_params, deviceFormat); + if (result < 0) + { + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting pcm device (" << name << ") data format, " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Determine whether byte-swaping is necessary. - stream_.doByteSwap[mode] = false; - if ( deviceFormat != SND_PCM_FORMAT_S8 ) { - result = snd_pcm_format_cpu_endian( deviceFormat ); - if ( result == 0 ) - stream_.doByteSwap[mode] = true; - else if (result < 0) { - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting pcm device (" << name << ") endian-ness, " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - return FAILURE; - } - } + // Determine whether byte-swaping is necessary. + stream_.doByteSwap[mode] = false; + if (deviceFormat != SND_PCM_FORMAT_S8) + { + result = snd_pcm_format_cpu_endian(deviceFormat); + if (result == 0) + stream_.doByteSwap[mode] = true; + else if (result < 0) + { + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting pcm device (" << name << ") endian-ness, " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + return FAILURE; + } + } - // Set the sample rate. - result = snd_pcm_hw_params_set_rate_near( phandle, hw_params, (unsigned int*) &sampleRate, 0 ); - if ( result < 0 ) { - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting sample rate on device (" << name << "), " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Set the sample rate. + result = snd_pcm_hw_params_set_rate_near(phandle, hw_params, (unsigned int *)&sampleRate, 0); + if (result < 0) + { + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting sample rate on device (" << name << "), " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Determine the number of channels for this device. We support a possible - // minimum device channel number > than the value requested by the user. - stream_.nUserChannels[mode] = channels; - unsigned int value; - result = snd_pcm_hw_params_get_channels_max( hw_params, &value ); - unsigned int deviceChannels = value; - if ( result < 0 || deviceChannels < channels + firstChannel ) { - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::probeDeviceOpen: requested channel parameters not supported by device (" << name << "), " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Determine the number of channels for this device. We support a possible + // minimum device channel number > than the value requested by the user. + stream_.nUserChannels[mode] = channels; + unsigned int value; + result = snd_pcm_hw_params_get_channels_max(hw_params, &value); + unsigned int deviceChannels = value; + if (result < 0 || deviceChannels < channels + firstChannel) + { + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::probeDeviceOpen: requested channel parameters not supported by device (" << name << "), " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + return FAILURE; + } - result = snd_pcm_hw_params_get_channels_min( hw_params, &value ); - if ( result < 0 ) { - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting minimum channels for device (" << name << "), " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - return FAILURE; - } - deviceChannels = value; - if ( deviceChannels < channels + firstChannel ) deviceChannels = channels + firstChannel; - stream_.nDeviceChannels[mode] = deviceChannels; + result = snd_pcm_hw_params_get_channels_min(hw_params, &value); + if (result < 0) + { + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::probeDeviceOpen: error getting minimum channels for device (" << name << "), " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + return FAILURE; + } + deviceChannels = value; + if (deviceChannels < channels + firstChannel) deviceChannels = channels + firstChannel; + stream_.nDeviceChannels[mode] = deviceChannels; - // Set the device channels. - result = snd_pcm_hw_params_set_channels( phandle, hw_params, deviceChannels ); - if ( result < 0 ) { - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting channels for device (" << name << "), " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Set the device channels. + result = snd_pcm_hw_params_set_channels(phandle, hw_params, deviceChannels); + if (result < 0) + { + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting channels for device (" << name << "), " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Set the buffer (or period) size. - int dir = 0; - snd_pcm_uframes_t periodSize = *bufferSize; - result = snd_pcm_hw_params_set_period_size_near( phandle, hw_params, &periodSize, &dir ); - if ( result < 0 ) { - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting period size for device (" << name << "), " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - return FAILURE; - } - *bufferSize = periodSize; + // Set the buffer (or period) size. + int dir = 0; + snd_pcm_uframes_t periodSize = *bufferSize; + result = snd_pcm_hw_params_set_period_size_near(phandle, hw_params, &periodSize, &dir); + if (result < 0) + { + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting period size for device (" << name << "), " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + return FAILURE; + } + *bufferSize = periodSize; - // Set the buffer number, which in ALSA is referred to as the "period". - unsigned int periods = 0; - if ( options && options->flags & RTAUDIO_MINIMIZE_LATENCY ) periods = 2; - if ( options && options->numberOfBuffers > 0 ) periods = options->numberOfBuffers; - if ( periods < 2 ) periods = 4; // a fairly safe default value - result = snd_pcm_hw_params_set_periods_near( phandle, hw_params, &periods, &dir ); - if ( result < 0 ) { - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting periods for device (" << name << "), " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Set the buffer number, which in ALSA is referred to as the "period". + unsigned int periods = 0; + if (options && options->flags & RTAUDIO_MINIMIZE_LATENCY) periods = 2; + if (options && options->numberOfBuffers > 0) periods = options->numberOfBuffers; + if (periods < 2) periods = 4; // a fairly safe default value + result = snd_pcm_hw_params_set_periods_near(phandle, hw_params, &periods, &dir); + if (result < 0) + { + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::probeDeviceOpen: error setting periods for device (" << name << "), " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // If attempting to setup a duplex stream, the bufferSize parameter - // MUST be the same in both directions! - if ( stream_.mode == OUTPUT && mode == INPUT && *bufferSize != stream_.bufferSize ) { - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::probeDeviceOpen: system error setting buffer size for duplex stream on device (" << name << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } + // If attempting to setup a duplex stream, the bufferSize parameter + // MUST be the same in both directions! + if (stream_.mode == OUTPUT && mode == INPUT && *bufferSize != stream_.bufferSize) + { + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::probeDeviceOpen: system error setting buffer size for duplex stream on device (" << name << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } - stream_.bufferSize = *bufferSize; + stream_.bufferSize = *bufferSize; - // Install the hardware configuration - result = snd_pcm_hw_params( phandle, hw_params ); - if ( result < 0 ) { - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::probeDeviceOpen: error installing hardware configuration on device (" << name << "), " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Install the hardware configuration + result = snd_pcm_hw_params(phandle, hw_params); + if (result < 0) + { + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::probeDeviceOpen: error installing hardware configuration on device (" << name << "), " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + return FAILURE; + } #if defined(__RTAUDIO_DEBUG__) - fprintf(stderr, "\nRtApiAlsa: dump hardware params after installation:\n\n"); - snd_pcm_hw_params_dump( hw_params, out ); + fprintf(stderr, "\nRtApiAlsa: dump hardware params after installation:\n\n"); + snd_pcm_hw_params_dump(hw_params, out); #endif - // Set the software configuration to fill buffers with zeros and prevent device stopping on xruns. - snd_pcm_sw_params_t *sw_params = NULL; - snd_pcm_sw_params_alloca( &sw_params ); - snd_pcm_sw_params_current( phandle, sw_params ); - snd_pcm_sw_params_set_start_threshold( phandle, sw_params, *bufferSize ); - snd_pcm_sw_params_set_stop_threshold( phandle, sw_params, ULONG_MAX ); - snd_pcm_sw_params_set_silence_threshold( phandle, sw_params, 0 ); + // Set the software configuration to fill buffers with zeros and prevent device stopping on xruns. + snd_pcm_sw_params_t *sw_params = NULL; + snd_pcm_sw_params_alloca(&sw_params); + snd_pcm_sw_params_current(phandle, sw_params); + snd_pcm_sw_params_set_start_threshold(phandle, sw_params, *bufferSize); + snd_pcm_sw_params_set_stop_threshold(phandle, sw_params, ULONG_MAX); + snd_pcm_sw_params_set_silence_threshold(phandle, sw_params, 0); - // The following two settings were suggested by Theo Veenker - //snd_pcm_sw_params_set_avail_min( phandle, sw_params, *bufferSize ); - //snd_pcm_sw_params_set_xfer_align( phandle, sw_params, 1 ); + // The following two settings were suggested by Theo Veenker + //snd_pcm_sw_params_set_avail_min( phandle, sw_params, *bufferSize ); + //snd_pcm_sw_params_set_xfer_align( phandle, sw_params, 1 ); - // here are two options for a fix - //snd_pcm_sw_params_set_silence_size( phandle, sw_params, ULONG_MAX ); - snd_pcm_uframes_t val; - snd_pcm_sw_params_get_boundary( sw_params, &val ); - snd_pcm_sw_params_set_silence_size( phandle, sw_params, val ); + // here are two options for a fix + //snd_pcm_sw_params_set_silence_size( phandle, sw_params, ULONG_MAX ); + snd_pcm_uframes_t val; + snd_pcm_sw_params_get_boundary(sw_params, &val); + snd_pcm_sw_params_set_silence_size(phandle, sw_params, val); - result = snd_pcm_sw_params( phandle, sw_params ); - if ( result < 0 ) { - snd_pcm_close( phandle ); - errorStream_ << "RtApiAlsa::probeDeviceOpen: error installing software configuration on device (" << name << "), " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - return FAILURE; - } + result = snd_pcm_sw_params(phandle, sw_params); + if (result < 0) + { + snd_pcm_close(phandle); + errorStream_ << "RtApiAlsa::probeDeviceOpen: error installing software configuration on device (" << name << "), " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + return FAILURE; + } #if defined(__RTAUDIO_DEBUG__) - fprintf(stderr, "\nRtApiAlsa: dump software params after installation:\n\n"); - snd_pcm_sw_params_dump( sw_params, out ); + fprintf(stderr, "\nRtApiAlsa: dump software params after installation:\n\n"); + snd_pcm_sw_params_dump(sw_params, out); #endif - // Set flags for buffer conversion - stream_.doConvertBuffer[mode] = false; - if ( stream_.userFormat != stream_.deviceFormat[mode] ) - stream_.doConvertBuffer[mode] = true; - if ( stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode] ) - stream_.doConvertBuffer[mode] = true; - if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] && - stream_.nUserChannels[mode] > 1 ) - stream_.doConvertBuffer[mode] = true; + // Set flags for buffer conversion + stream_.doConvertBuffer[mode] = false; + if (stream_.userFormat != stream_.deviceFormat[mode]) + stream_.doConvertBuffer[mode] = true; + if (stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode]) + stream_.doConvertBuffer[mode] = true; + if (stream_.userInterleaved != stream_.deviceInterleaved[mode] && + stream_.nUserChannels[mode] > 1) + stream_.doConvertBuffer[mode] = true; - // Allocate the ApiHandle if necessary and then save. - AlsaHandle *apiInfo = 0; - if ( stream_.apiHandle == 0 ) { - try { - apiInfo = (AlsaHandle *) new AlsaHandle; - } - catch ( std::bad_alloc& ) { - errorText_ = "RtApiAlsa::probeDeviceOpen: error allocating AlsaHandle memory."; - goto error; - } + // Allocate the ApiHandle if necessary and then save. + AlsaHandle *apiInfo = 0; + if (stream_.apiHandle == 0) + { + try + { + apiInfo = (AlsaHandle *)new AlsaHandle; + } + catch (std::bad_alloc &) + { + errorText_ = "RtApiAlsa::probeDeviceOpen: error allocating AlsaHandle memory."; + goto error; + } - if ( pthread_cond_init( &apiInfo->runnable_cv, NULL ) ) { - errorText_ = "RtApiAlsa::probeDeviceOpen: error initializing pthread condition variable."; - goto error; - } + if (pthread_cond_init(&apiInfo->runnable_cv, NULL)) + { + errorText_ = "RtApiAlsa::probeDeviceOpen: error initializing pthread condition variable."; + goto error; + } - stream_.apiHandle = (void *) apiInfo; - apiInfo->handles[0] = 0; - apiInfo->handles[1] = 0; - } - else { - apiInfo = (AlsaHandle *) stream_.apiHandle; - } - apiInfo->handles[mode] = phandle; - phandle = 0; + stream_.apiHandle = (void *)apiInfo; + apiInfo->handles[0] = 0; + apiInfo->handles[1] = 0; + } + else + { + apiInfo = (AlsaHandle *)stream_.apiHandle; + } + apiInfo->handles[mode] = phandle; + phandle = 0; - // Allocate necessary internal buffers. - unsigned long bufferBytes; - bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat ); - stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 ); - if ( stream_.userBuffer[mode] == NULL ) { - errorText_ = "RtApiAlsa::probeDeviceOpen: error allocating user buffer memory."; - goto error; - } + // Allocate necessary internal buffers. + unsigned long bufferBytes; + bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes(stream_.userFormat); + stream_.userBuffer[mode] = (char *)calloc(bufferBytes, 1); + if (stream_.userBuffer[mode] == NULL) + { + errorText_ = "RtApiAlsa::probeDeviceOpen: error allocating user buffer memory."; + goto error; + } - if ( stream_.doConvertBuffer[mode] ) { + if (stream_.doConvertBuffer[mode]) + { + bool makeBuffer = true; + bufferBytes = stream_.nDeviceChannels[mode] * formatBytes(stream_.deviceFormat[mode]); + if (mode == INPUT) + { + if (stream_.mode == OUTPUT && stream_.deviceBuffer) + { + unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes(stream_.deviceFormat[0]); + if (bufferBytes <= bytesOut) makeBuffer = false; + } + } - bool makeBuffer = true; - bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] ); - if ( mode == INPUT ) { - if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) { - unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] ); - if ( bufferBytes <= bytesOut ) makeBuffer = false; - } - } + if (makeBuffer) + { + bufferBytes *= *bufferSize; + if (stream_.deviceBuffer) free(stream_.deviceBuffer); + stream_.deviceBuffer = (char *)calloc(bufferBytes, 1); + if (stream_.deviceBuffer == NULL) + { + errorText_ = "RtApiAlsa::probeDeviceOpen: error allocating device buffer memory."; + goto error; + } + } + } - if ( makeBuffer ) { - bufferBytes *= *bufferSize; - if ( stream_.deviceBuffer ) free( stream_.deviceBuffer ); - stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 ); - if ( stream_.deviceBuffer == NULL ) { - errorText_ = "RtApiAlsa::probeDeviceOpen: error allocating device buffer memory."; - goto error; - } - } - } + stream_.sampleRate = sampleRate; + stream_.nBuffers = periods; + stream_.device[mode] = device; + stream_.state = STREAM_STOPPED; - stream_.sampleRate = sampleRate; - stream_.nBuffers = periods; - stream_.device[mode] = device; - stream_.state = STREAM_STOPPED; + // Setup the buffer conversion information structure. + if (stream_.doConvertBuffer[mode]) setConvertInfo(mode, firstChannel); - // Setup the buffer conversion information structure. - if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, firstChannel ); + // Setup thread if necessary. + if (stream_.mode == OUTPUT && mode == INPUT) + { + // We had already set up an output stream. + stream_.mode = DUPLEX; + // Link the streams if possible. + apiInfo->synchronized = false; + if (snd_pcm_link(apiInfo->handles[0], apiInfo->handles[1]) == 0) + apiInfo->synchronized = true; + else + { + errorText_ = "RtApiAlsa::probeDeviceOpen: unable to synchronize input and output devices."; + error(RtAudioError::WARNING); + } + } + else + { + stream_.mode = mode; - // Setup thread if necessary. - if ( stream_.mode == OUTPUT && mode == INPUT ) { - // We had already set up an output stream. - stream_.mode = DUPLEX; - // Link the streams if possible. - apiInfo->synchronized = false; - if ( snd_pcm_link( apiInfo->handles[0], apiInfo->handles[1] ) == 0 ) - apiInfo->synchronized = true; - else { - errorText_ = "RtApiAlsa::probeDeviceOpen: unable to synchronize input and output devices."; - error( RtAudioError::WARNING ); - } - } - else { - stream_.mode = mode; + // Setup callback thread. + stream_.callbackInfo.object = (void *)this; - // Setup callback thread. - stream_.callbackInfo.object = (void *) this; + // Set the thread attributes for joinable and realtime scheduling + // priority (optional). The higher priority will only take affect + // if the program is run as root or suid. Note, under Linux + // processes with CAP_SYS_NICE privilege, a user can change + // scheduling policy and priority (thus need not be root). See + // POSIX "capabilities". + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - // Set the thread attributes for joinable and realtime scheduling - // priority (optional). The higher priority will only take affect - // if the program is run as root or suid. Note, under Linux - // processes with CAP_SYS_NICE privilege, a user can change - // scheduling policy and priority (thus need not be root). See - // POSIX "capabilities". - pthread_attr_t attr; - pthread_attr_init( &attr ); - pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ); - -#ifdef SCHED_RR // Undefined with some OSes (eg: NetBSD 1.6.x with GNU Pthread) - if ( options && options->flags & RTAUDIO_SCHEDULE_REALTIME ) { - // We previously attempted to increase the audio callback priority - // to SCHED_RR here via the attributes. However, while no errors - // were reported in doing so, it did not work. So, now this is - // done in the alsaCallbackHandler function. - stream_.callbackInfo.doRealtime = true; - int priority = options->priority; - int min = sched_get_priority_min( SCHED_RR ); - int max = sched_get_priority_max( SCHED_RR ); - if ( priority < min ) priority = min; - else if ( priority > max ) priority = max; - stream_.callbackInfo.priority = priority; - } +#ifdef SCHED_RR // Undefined with some OSes (eg: NetBSD 1.6.x with GNU Pthread) + if (options && options->flags & RTAUDIO_SCHEDULE_REALTIME) + { + // We previously attempted to increase the audio callback priority + // to SCHED_RR here via the attributes. However, while no errors + // were reported in doing so, it did not work. So, now this is + // done in the alsaCallbackHandler function. + stream_.callbackInfo.doRealtime = true; + int priority = options->priority; + int min = sched_get_priority_min(SCHED_RR); + int max = sched_get_priority_max(SCHED_RR); + if (priority < min) + priority = min; + else if (priority > max) + priority = max; + stream_.callbackInfo.priority = priority; + } #endif - stream_.callbackInfo.isRunning = true; - result = pthread_create( &stream_.callbackInfo.thread, &attr, alsaCallbackHandler, &stream_.callbackInfo ); - pthread_attr_destroy( &attr ); - if ( result ) { - stream_.callbackInfo.isRunning = false; - errorText_ = "RtApiAlsa::error creating callback thread!"; - goto error; - } - } + stream_.callbackInfo.isRunning = true; + result = pthread_create(&stream_.callbackInfo.thread, &attr, alsaCallbackHandler, &stream_.callbackInfo); + pthread_attr_destroy(&attr); + if (result) + { + stream_.callbackInfo.isRunning = false; + errorText_ = "RtApiAlsa::error creating callback thread!"; + goto error; + } + } - return SUCCESS; + return SUCCESS; - error: - if ( apiInfo ) { - pthread_cond_destroy( &apiInfo->runnable_cv ); - if ( apiInfo->handles[0] ) snd_pcm_close( apiInfo->handles[0] ); - if ( apiInfo->handles[1] ) snd_pcm_close( apiInfo->handles[1] ); - delete apiInfo; - stream_.apiHandle = 0; - } +error: + if (apiInfo) + { + pthread_cond_destroy(&apiInfo->runnable_cv); + if (apiInfo->handles[0]) snd_pcm_close(apiInfo->handles[0]); + if (apiInfo->handles[1]) snd_pcm_close(apiInfo->handles[1]); + delete apiInfo; + stream_.apiHandle = 0; + } - if ( phandle) snd_pcm_close( phandle ); + if (phandle) snd_pcm_close(phandle); - for ( int i=0; i<2; i++ ) { - if ( stream_.userBuffer[i] ) { - free( stream_.userBuffer[i] ); - stream_.userBuffer[i] = 0; - } - } + for (int i = 0; i < 2; i++) + { + if (stream_.userBuffer[i]) + { + free(stream_.userBuffer[i]); + stream_.userBuffer[i] = 0; + } + } - if ( stream_.deviceBuffer ) { - free( stream_.deviceBuffer ); - stream_.deviceBuffer = 0; - } + if (stream_.deviceBuffer) + { + free(stream_.deviceBuffer); + stream_.deviceBuffer = 0; + } - stream_.state = STREAM_CLOSED; - return FAILURE; + stream_.state = STREAM_CLOSED; + return FAILURE; } -void RtApiAlsa :: closeStream() +void RtApiAlsa ::closeStream() { - if ( stream_.state == STREAM_CLOSED ) { - errorText_ = "RtApiAlsa::closeStream(): no open stream to close!"; - error( RtAudioError::WARNING ); - return; - } + if (stream_.state == STREAM_CLOSED) + { + errorText_ = "RtApiAlsa::closeStream(): no open stream to close!"; + error(RtAudioError::WARNING); + return; + } - AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle; - stream_.callbackInfo.isRunning = false; - MUTEX_LOCK( &stream_.mutex ); - if ( stream_.state == STREAM_STOPPED ) { - apiInfo->runnable = true; - pthread_cond_signal( &apiInfo->runnable_cv ); - } - MUTEX_UNLOCK( &stream_.mutex ); - pthread_join( stream_.callbackInfo.thread, NULL ); + AlsaHandle *apiInfo = (AlsaHandle *)stream_.apiHandle; + stream_.callbackInfo.isRunning = false; + MUTEX_LOCK(&stream_.mutex); + if (stream_.state == STREAM_STOPPED) + { + apiInfo->runnable = true; + pthread_cond_signal(&apiInfo->runnable_cv); + } + MUTEX_UNLOCK(&stream_.mutex); + pthread_join(stream_.callbackInfo.thread, NULL); - if ( stream_.state == STREAM_RUNNING ) { - stream_.state = STREAM_STOPPED; - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) - snd_pcm_drop( apiInfo->handles[0] ); - if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) - snd_pcm_drop( apiInfo->handles[1] ); - } + if (stream_.state == STREAM_RUNNING) + { + stream_.state = STREAM_STOPPED; + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + snd_pcm_drop(apiInfo->handles[0]); + if (stream_.mode == INPUT || stream_.mode == DUPLEX) + snd_pcm_drop(apiInfo->handles[1]); + } - if ( apiInfo ) { - pthread_cond_destroy( &apiInfo->runnable_cv ); - if ( apiInfo->handles[0] ) snd_pcm_close( apiInfo->handles[0] ); - if ( apiInfo->handles[1] ) snd_pcm_close( apiInfo->handles[1] ); - delete apiInfo; - stream_.apiHandle = 0; - } + if (apiInfo) + { + pthread_cond_destroy(&apiInfo->runnable_cv); + if (apiInfo->handles[0]) snd_pcm_close(apiInfo->handles[0]); + if (apiInfo->handles[1]) snd_pcm_close(apiInfo->handles[1]); + delete apiInfo; + stream_.apiHandle = 0; + } - for ( int i=0; i<2; i++ ) { - if ( stream_.userBuffer[i] ) { - free( stream_.userBuffer[i] ); - stream_.userBuffer[i] = 0; - } - } + for (int i = 0; i < 2; i++) + { + if (stream_.userBuffer[i]) + { + free(stream_.userBuffer[i]); + stream_.userBuffer[i] = 0; + } + } - if ( stream_.deviceBuffer ) { - free( stream_.deviceBuffer ); - stream_.deviceBuffer = 0; - } + if (stream_.deviceBuffer) + { + free(stream_.deviceBuffer); + stream_.deviceBuffer = 0; + } - stream_.mode = UNINITIALIZED; - stream_.state = STREAM_CLOSED; + stream_.mode = UNINITIALIZED; + stream_.state = STREAM_CLOSED; } -void RtApiAlsa :: startStream() +void RtApiAlsa ::startStream() { - // This method calls snd_pcm_prepare if the device isn't already in that state. + // This method calls snd_pcm_prepare if the device isn't already in that state. - verifyStream(); - if ( stream_.state == STREAM_RUNNING ) { - errorText_ = "RtApiAlsa::startStream(): the stream is already running!"; - error( RtAudioError::WARNING ); - return; - } + verifyStream(); + if (stream_.state == STREAM_RUNNING) + { + errorText_ = "RtApiAlsa::startStream(): the stream is already running!"; + error(RtAudioError::WARNING); + return; + } - MUTEX_LOCK( &stream_.mutex ); + MUTEX_LOCK(&stream_.mutex); - int result = 0; - snd_pcm_state_t state; - AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle; - snd_pcm_t **handle = (snd_pcm_t **) apiInfo->handles; - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { - state = snd_pcm_state( handle[0] ); - if ( state != SND_PCM_STATE_PREPARED ) { - result = snd_pcm_prepare( handle[0] ); - if ( result < 0 ) { - errorStream_ << "RtApiAlsa::startStream: error preparing output pcm device, " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - goto unlock; - } - } - } + int result = 0; + snd_pcm_state_t state; + AlsaHandle *apiInfo = (AlsaHandle *)stream_.apiHandle; + snd_pcm_t **handle = (snd_pcm_t **)apiInfo->handles; + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + { + state = snd_pcm_state(handle[0]); + if (state != SND_PCM_STATE_PREPARED) + { + result = snd_pcm_prepare(handle[0]); + if (result < 0) + { + errorStream_ << "RtApiAlsa::startStream: error preparing output pcm device, " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + goto unlock; + } + } + } - if ( ( stream_.mode == INPUT || stream_.mode == DUPLEX ) && !apiInfo->synchronized ) { - result = snd_pcm_drop(handle[1]); // fix to remove stale data received since device has been open - state = snd_pcm_state( handle[1] ); - if ( state != SND_PCM_STATE_PREPARED ) { - result = snd_pcm_prepare( handle[1] ); - if ( result < 0 ) { - errorStream_ << "RtApiAlsa::startStream: error preparing input pcm device, " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - goto unlock; - } - } - } + if ((stream_.mode == INPUT || stream_.mode == DUPLEX) && !apiInfo->synchronized) + { + result = snd_pcm_drop(handle[1]); // fix to remove stale data received since device has been open + state = snd_pcm_state(handle[1]); + if (state != SND_PCM_STATE_PREPARED) + { + result = snd_pcm_prepare(handle[1]); + if (result < 0) + { + errorStream_ << "RtApiAlsa::startStream: error preparing input pcm device, " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + goto unlock; + } + } + } - stream_.state = STREAM_RUNNING; + stream_.state = STREAM_RUNNING; - unlock: - apiInfo->runnable = true; - pthread_cond_signal( &apiInfo->runnable_cv ); - MUTEX_UNLOCK( &stream_.mutex ); +unlock: + apiInfo->runnable = true; + pthread_cond_signal(&apiInfo->runnable_cv); + MUTEX_UNLOCK(&stream_.mutex); - if ( result >= 0 ) return; - error( RtAudioError::SYSTEM_ERROR ); + if (result >= 0) return; + error(RtAudioError::SYSTEM_ERROR); } -void RtApiAlsa :: stopStream() +void RtApiAlsa ::stopStream() { - verifyStream(); - if ( stream_.state == STREAM_STOPPED ) { - errorText_ = "RtApiAlsa::stopStream(): the stream is already stopped!"; - error( RtAudioError::WARNING ); - return; - } + verifyStream(); + if (stream_.state == STREAM_STOPPED) + { + errorText_ = "RtApiAlsa::stopStream(): the stream is already stopped!"; + error(RtAudioError::WARNING); + return; + } - stream_.state = STREAM_STOPPED; - MUTEX_LOCK( &stream_.mutex ); + stream_.state = STREAM_STOPPED; + MUTEX_LOCK(&stream_.mutex); - int result = 0; - AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle; - snd_pcm_t **handle = (snd_pcm_t **) apiInfo->handles; - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { - if ( apiInfo->synchronized ) - result = snd_pcm_drop( handle[0] ); - else - result = snd_pcm_drain( handle[0] ); - if ( result < 0 ) { - errorStream_ << "RtApiAlsa::stopStream: error draining output pcm device, " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - goto unlock; - } - } + int result = 0; + AlsaHandle *apiInfo = (AlsaHandle *)stream_.apiHandle; + snd_pcm_t **handle = (snd_pcm_t **)apiInfo->handles; + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + { + if (apiInfo->synchronized) + result = snd_pcm_drop(handle[0]); + else + result = snd_pcm_drain(handle[0]); + if (result < 0) + { + errorStream_ << "RtApiAlsa::stopStream: error draining output pcm device, " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + goto unlock; + } + } - if ( ( stream_.mode == INPUT || stream_.mode == DUPLEX ) && !apiInfo->synchronized ) { - result = snd_pcm_drop( handle[1] ); - if ( result < 0 ) { - errorStream_ << "RtApiAlsa::stopStream: error stopping input pcm device, " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - goto unlock; - } - } + if ((stream_.mode == INPUT || stream_.mode == DUPLEX) && !apiInfo->synchronized) + { + result = snd_pcm_drop(handle[1]); + if (result < 0) + { + errorStream_ << "RtApiAlsa::stopStream: error stopping input pcm device, " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + goto unlock; + } + } - unlock: - apiInfo->runnable = false; // fixes high CPU usage when stopped - MUTEX_UNLOCK( &stream_.mutex ); +unlock: + apiInfo->runnable = false; // fixes high CPU usage when stopped + MUTEX_UNLOCK(&stream_.mutex); - if ( result >= 0 ) return; - error( RtAudioError::SYSTEM_ERROR ); + if (result >= 0) return; + error(RtAudioError::SYSTEM_ERROR); } -void RtApiAlsa :: abortStream() +void RtApiAlsa ::abortStream() { - verifyStream(); - if ( stream_.state == STREAM_STOPPED ) { - errorText_ = "RtApiAlsa::abortStream(): the stream is already stopped!"; - error( RtAudioError::WARNING ); - return; - } + verifyStream(); + if (stream_.state == STREAM_STOPPED) + { + errorText_ = "RtApiAlsa::abortStream(): the stream is already stopped!"; + error(RtAudioError::WARNING); + return; + } - stream_.state = STREAM_STOPPED; - MUTEX_LOCK( &stream_.mutex ); + stream_.state = STREAM_STOPPED; + MUTEX_LOCK(&stream_.mutex); - int result = 0; - AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle; - snd_pcm_t **handle = (snd_pcm_t **) apiInfo->handles; - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { - result = snd_pcm_drop( handle[0] ); - if ( result < 0 ) { - errorStream_ << "RtApiAlsa::abortStream: error aborting output pcm device, " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - goto unlock; - } - } + int result = 0; + AlsaHandle *apiInfo = (AlsaHandle *)stream_.apiHandle; + snd_pcm_t **handle = (snd_pcm_t **)apiInfo->handles; + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + { + result = snd_pcm_drop(handle[0]); + if (result < 0) + { + errorStream_ << "RtApiAlsa::abortStream: error aborting output pcm device, " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + goto unlock; + } + } - if ( ( stream_.mode == INPUT || stream_.mode == DUPLEX ) && !apiInfo->synchronized ) { - result = snd_pcm_drop( handle[1] ); - if ( result < 0 ) { - errorStream_ << "RtApiAlsa::abortStream: error aborting input pcm device, " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - goto unlock; - } - } + if ((stream_.mode == INPUT || stream_.mode == DUPLEX) && !apiInfo->synchronized) + { + result = snd_pcm_drop(handle[1]); + if (result < 0) + { + errorStream_ << "RtApiAlsa::abortStream: error aborting input pcm device, " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + goto unlock; + } + } - unlock: - apiInfo->runnable = false; // fixes high CPU usage when stopped - MUTEX_UNLOCK( &stream_.mutex ); +unlock: + apiInfo->runnable = false; // fixes high CPU usage when stopped + MUTEX_UNLOCK(&stream_.mutex); - if ( result >= 0 ) return; - error( RtAudioError::SYSTEM_ERROR ); + if (result >= 0) return; + error(RtAudioError::SYSTEM_ERROR); } -void RtApiAlsa :: callbackEvent() +void RtApiAlsa ::callbackEvent() { - AlsaHandle *apiInfo = (AlsaHandle *) stream_.apiHandle; - if ( stream_.state == STREAM_STOPPED ) { - MUTEX_LOCK( &stream_.mutex ); - while ( !apiInfo->runnable ) - pthread_cond_wait( &apiInfo->runnable_cv, &stream_.mutex ); + AlsaHandle *apiInfo = (AlsaHandle *)stream_.apiHandle; + if (stream_.state == STREAM_STOPPED) + { + MUTEX_LOCK(&stream_.mutex); + while (!apiInfo->runnable) + pthread_cond_wait(&apiInfo->runnable_cv, &stream_.mutex); - if ( stream_.state != STREAM_RUNNING ) { - MUTEX_UNLOCK( &stream_.mutex ); - return; - } - MUTEX_UNLOCK( &stream_.mutex ); - } + if (stream_.state != STREAM_RUNNING) + { + MUTEX_UNLOCK(&stream_.mutex); + return; + } + MUTEX_UNLOCK(&stream_.mutex); + } - if ( stream_.state == STREAM_CLOSED ) { - errorText_ = "RtApiAlsa::callbackEvent(): the stream is closed ... this shouldn't happen!"; - error( RtAudioError::WARNING ); - return; - } + if (stream_.state == STREAM_CLOSED) + { + errorText_ = "RtApiAlsa::callbackEvent(): the stream is closed ... this shouldn't happen!"; + error(RtAudioError::WARNING); + return; + } - int doStopStream = 0; - RtAudioCallback callback = (RtAudioCallback) stream_.callbackInfo.callback; - double streamTime = getStreamTime(); - RtAudioStreamStatus status = 0; - if ( stream_.mode != INPUT && apiInfo->xrun[0] == true ) { - status |= RTAUDIO_OUTPUT_UNDERFLOW; - apiInfo->xrun[0] = false; - } - if ( stream_.mode != OUTPUT && apiInfo->xrun[1] == true ) { - status |= RTAUDIO_INPUT_OVERFLOW; - apiInfo->xrun[1] = false; - } - doStopStream = callback( stream_.userBuffer[0], stream_.userBuffer[1], - stream_.bufferSize, streamTime, status, stream_.callbackInfo.userData ); + int doStopStream = 0; + RtAudioCallback callback = (RtAudioCallback)stream_.callbackInfo.callback; + double streamTime = getStreamTime(); + RtAudioStreamStatus status = 0; + if (stream_.mode != INPUT && apiInfo->xrun[0] == true) + { + status |= RTAUDIO_OUTPUT_UNDERFLOW; + apiInfo->xrun[0] = false; + } + if (stream_.mode != OUTPUT && apiInfo->xrun[1] == true) + { + status |= RTAUDIO_INPUT_OVERFLOW; + apiInfo->xrun[1] = false; + } + doStopStream = callback(stream_.userBuffer[0], stream_.userBuffer[1], + stream_.bufferSize, streamTime, status, stream_.callbackInfo.userData); - if ( doStopStream == 2 ) { - abortStream(); - return; - } + if (doStopStream == 2) + { + abortStream(); + return; + } - MUTEX_LOCK( &stream_.mutex ); + MUTEX_LOCK(&stream_.mutex); - // The state might change while waiting on a mutex. - if ( stream_.state == STREAM_STOPPED ) goto unlock; + // The state might change while waiting on a mutex. + if (stream_.state == STREAM_STOPPED) goto unlock; - int result; - char *buffer; - int channels; - snd_pcm_t **handle; - snd_pcm_sframes_t frames; - RtAudioFormat format; - handle = (snd_pcm_t **) apiInfo->handles; + int result; + char *buffer; + int channels; + snd_pcm_t **handle; + snd_pcm_sframes_t frames; + RtAudioFormat format; + handle = (snd_pcm_t **)apiInfo->handles; - if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) { + if (stream_.mode == INPUT || stream_.mode == DUPLEX) + { + // Setup parameters. + if (stream_.doConvertBuffer[1]) + { + buffer = stream_.deviceBuffer; + channels = stream_.nDeviceChannels[1]; + format = stream_.deviceFormat[1]; + } + else + { + buffer = stream_.userBuffer[1]; + channels = stream_.nUserChannels[1]; + format = stream_.userFormat; + } - // Setup parameters. - if ( stream_.doConvertBuffer[1] ) { - buffer = stream_.deviceBuffer; - channels = stream_.nDeviceChannels[1]; - format = stream_.deviceFormat[1]; - } - else { - buffer = stream_.userBuffer[1]; - channels = stream_.nUserChannels[1]; - format = stream_.userFormat; - } + // Read samples from device in interleaved/non-interleaved format. + if (stream_.deviceInterleaved[1]) + result = snd_pcm_readi(handle[1], buffer, stream_.bufferSize); + else + { + void *bufs[channels]; + size_t offset = stream_.bufferSize * formatBytes(format); + for (int i = 0; i < channels; i++) + bufs[i] = (void *)(buffer + (i * offset)); + result = snd_pcm_readn(handle[1], bufs, stream_.bufferSize); + } - // Read samples from device in interleaved/non-interleaved format. - if ( stream_.deviceInterleaved[1] ) - result = snd_pcm_readi( handle[1], buffer, stream_.bufferSize ); - else { - void *bufs[channels]; - size_t offset = stream_.bufferSize * formatBytes( format ); - for ( int i=0; ixrun[1] = true; + result = snd_pcm_prepare(handle[1]); + if (result < 0) + { + errorStream_ << "RtApiAlsa::callbackEvent: error preparing device after overrun, " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + } + } + else + { + errorStream_ << "RtApiAlsa::callbackEvent: error, current state is " << snd_pcm_state_name(state) << ", " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + } + } + else + { + errorStream_ << "RtApiAlsa::callbackEvent: audio read error, " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + } + error(RtAudioError::WARNING); + goto tryOutput; + } - if ( result < (int) stream_.bufferSize ) { - // Either an error or overrun occured. - if ( result == -EPIPE ) { - snd_pcm_state_t state = snd_pcm_state( handle[1] ); - if ( state == SND_PCM_STATE_XRUN ) { - apiInfo->xrun[1] = true; - result = snd_pcm_prepare( handle[1] ); - if ( result < 0 ) { - errorStream_ << "RtApiAlsa::callbackEvent: error preparing device after overrun, " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - } - } - else { - errorStream_ << "RtApiAlsa::callbackEvent: error, current state is " << snd_pcm_state_name( state ) << ", " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - } - } - else { - errorStream_ << "RtApiAlsa::callbackEvent: audio read error, " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - } - error( RtAudioError::WARNING ); - goto tryOutput; - } + // Do byte swapping if necessary. + if (stream_.doByteSwap[1]) + byteSwapBuffer(buffer, stream_.bufferSize * channels, format); - // Do byte swapping if necessary. - if ( stream_.doByteSwap[1] ) - byteSwapBuffer( buffer, stream_.bufferSize * channels, format ); + // Do buffer conversion if necessary. + if (stream_.doConvertBuffer[1]) + convertBuffer(stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1]); - // Do buffer conversion if necessary. - if ( stream_.doConvertBuffer[1] ) - convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] ); + // Check stream latency + result = snd_pcm_delay(handle[1], &frames); + if (result == 0 && frames > 0) stream_.latency[1] = frames; + } - // Check stream latency - result = snd_pcm_delay( handle[1], &frames ); - if ( result == 0 && frames > 0 ) stream_.latency[1] = frames; - } +tryOutput: - tryOutput: + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + { + // Setup parameters and do buffer conversion if necessary. + if (stream_.doConvertBuffer[0]) + { + buffer = stream_.deviceBuffer; + convertBuffer(buffer, stream_.userBuffer[0], stream_.convertInfo[0]); + channels = stream_.nDeviceChannels[0]; + format = stream_.deviceFormat[0]; + } + else + { + buffer = stream_.userBuffer[0]; + channels = stream_.nUserChannels[0]; + format = stream_.userFormat; + } - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { + // Do byte swapping if necessary. + if (stream_.doByteSwap[0]) + byteSwapBuffer(buffer, stream_.bufferSize * channels, format); - // Setup parameters and do buffer conversion if necessary. - if ( stream_.doConvertBuffer[0] ) { - buffer = stream_.deviceBuffer; - convertBuffer( buffer, stream_.userBuffer[0], stream_.convertInfo[0] ); - channels = stream_.nDeviceChannels[0]; - format = stream_.deviceFormat[0]; - } - else { - buffer = stream_.userBuffer[0]; - channels = stream_.nUserChannels[0]; - format = stream_.userFormat; - } + // Write samples to device in interleaved/non-interleaved format. + if (stream_.deviceInterleaved[0]) + result = snd_pcm_writei(handle[0], buffer, stream_.bufferSize); + else + { + void *bufs[channels]; + size_t offset = stream_.bufferSize * formatBytes(format); + for (int i = 0; i < channels; i++) + bufs[i] = (void *)(buffer + (i * offset)); + result = snd_pcm_writen(handle[0], bufs, stream_.bufferSize); + } - // Do byte swapping if necessary. - if ( stream_.doByteSwap[0] ) - byteSwapBuffer(buffer, stream_.bufferSize * channels, format); + if (result < (int)stream_.bufferSize) + { + // Either an error or underrun occured. + if (result == -EPIPE) + { + snd_pcm_state_t state = snd_pcm_state(handle[0]); + if (state == SND_PCM_STATE_XRUN) + { + apiInfo->xrun[0] = true; + result = snd_pcm_prepare(handle[0]); + if (result < 0) + { + errorStream_ << "RtApiAlsa::callbackEvent: error preparing device after underrun, " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + } + else + errorText_ = "RtApiAlsa::callbackEvent: audio write error, underrun."; + } + else + { + errorStream_ << "RtApiAlsa::callbackEvent: error, current state is " << snd_pcm_state_name(state) << ", " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + } + } + else + { + errorStream_ << "RtApiAlsa::callbackEvent: audio write error, " << snd_strerror(result) << "."; + errorText_ = errorStream_.str(); + } + error(RtAudioError::WARNING); + goto unlock; + } - // Write samples to device in interleaved/non-interleaved format. - if ( stream_.deviceInterleaved[0] ) - result = snd_pcm_writei( handle[0], buffer, stream_.bufferSize ); - else { - void *bufs[channels]; - size_t offset = stream_.bufferSize * formatBytes( format ); - for ( int i=0; i 0) stream_.latency[0] = frames; + } - if ( result < (int) stream_.bufferSize ) { - // Either an error or underrun occured. - if ( result == -EPIPE ) { - snd_pcm_state_t state = snd_pcm_state( handle[0] ); - if ( state == SND_PCM_STATE_XRUN ) { - apiInfo->xrun[0] = true; - result = snd_pcm_prepare( handle[0] ); - if ( result < 0 ) { - errorStream_ << "RtApiAlsa::callbackEvent: error preparing device after underrun, " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - } - else - errorText_ = "RtApiAlsa::callbackEvent: audio write error, underrun."; - } - else { - errorStream_ << "RtApiAlsa::callbackEvent: error, current state is " << snd_pcm_state_name( state ) << ", " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - } - } - else { - errorStream_ << "RtApiAlsa::callbackEvent: audio write error, " << snd_strerror( result ) << "."; - errorText_ = errorStream_.str(); - } - error( RtAudioError::WARNING ); - goto unlock; - } +unlock: + MUTEX_UNLOCK(&stream_.mutex); - // Check stream latency - result = snd_pcm_delay( handle[0], &frames ); - if ( result == 0 && frames > 0 ) stream_.latency[0] = frames; - } - - unlock: - MUTEX_UNLOCK( &stream_.mutex ); - - RtApi::tickStreamTime(); - if ( doStopStream == 1 ) this->stopStream(); + RtApi::tickStreamTime(); + if (doStopStream == 1) this->stopStream(); } -static void *alsaCallbackHandler( void *ptr ) +static void *alsaCallbackHandler(void *ptr) { - CallbackInfo *info = (CallbackInfo *) ptr; - RtApiAlsa *object = (RtApiAlsa *) info->object; - bool *isRunning = &info->isRunning; + CallbackInfo *info = (CallbackInfo *)ptr; + RtApiAlsa *object = (RtApiAlsa *)info->object; + bool *isRunning = &info->isRunning; -#ifdef SCHED_RR // Undefined with some OSes (eg: NetBSD 1.6.x with GNU Pthread) - if ( info->doRealtime ) { - pthread_t tID = pthread_self(); // ID of this thread - sched_param prio = { info->priority }; // scheduling priority of thread - pthread_setschedparam( tID, SCHED_RR, &prio ); - } +#ifdef SCHED_RR // Undefined with some OSes (eg: NetBSD 1.6.x with GNU Pthread) + if (info->doRealtime) + { + pthread_t tID = pthread_self(); // ID of this thread + sched_param prio = {info->priority}; // scheduling priority of thread + pthread_setschedparam(tID, SCHED_RR, &prio); + } #endif - while ( *isRunning == true ) { - pthread_testcancel(); - object->callbackEvent(); - } + while (*isRunning == true) + { + pthread_testcancel(); + object->callbackEvent(); + } - pthread_exit( NULL ); + pthread_exit(NULL); } //******************** End of __LINUX_ALSA__ *********************// @@ -8098,480 +8901,532 @@ static void *alsaCallbackHandler( void *ptr ) #include #include -static const unsigned int SUPPORTED_SAMPLERATES[] = { 8000, 16000, 22050, 32000, - 44100, 48000, 96000, 0}; +static const unsigned int SUPPORTED_SAMPLERATES[] = {8000, 16000, 22050, 32000, + 44100, 48000, 96000, 0}; -struct rtaudio_pa_format_mapping_t { - RtAudioFormat rtaudio_format; - pa_sample_format_t pa_format; +struct rtaudio_pa_format_mapping_t +{ + RtAudioFormat rtaudio_format; + pa_sample_format_t pa_format; }; static const rtaudio_pa_format_mapping_t supported_sampleformats[] = { - {RTAUDIO_SINT16, PA_SAMPLE_S16LE}, - {RTAUDIO_SINT32, PA_SAMPLE_S32LE}, - {RTAUDIO_FLOAT32, PA_SAMPLE_FLOAT32LE}, - {0, PA_SAMPLE_INVALID}}; + {RTAUDIO_SINT16, PA_SAMPLE_S16LE}, + {RTAUDIO_SINT32, PA_SAMPLE_S32LE}, + {RTAUDIO_FLOAT32, PA_SAMPLE_FLOAT32LE}, + {0, PA_SAMPLE_INVALID}}; -struct PulseAudioHandle { - pa_simple *s_play; - pa_simple *s_rec; - pthread_t thread; - pthread_cond_t runnable_cv; - bool runnable; - PulseAudioHandle() : s_play(0), s_rec(0), runnable(false) { } +struct PulseAudioHandle +{ + pa_simple *s_play; + pa_simple *s_rec; + pthread_t thread; + pthread_cond_t runnable_cv; + bool runnable; + PulseAudioHandle() : s_play(0), s_rec(0), runnable(false) {} }; RtApiPulse::~RtApiPulse() { - if ( stream_.state != STREAM_CLOSED ) - closeStream(); + if (stream_.state != STREAM_CLOSED) + closeStream(); } -unsigned int RtApiPulse::getDeviceCount( void ) +unsigned int RtApiPulse::getDeviceCount(void) { - return 1; + return 1; } -RtAudio::DeviceInfo RtApiPulse::getDeviceInfo( unsigned int /*device*/ ) +RtAudio::DeviceInfo RtApiPulse::getDeviceInfo(unsigned int /*device*/) { - RtAudio::DeviceInfo info; - info.probed = true; - info.name = "PulseAudio"; - info.outputChannels = 2; - info.inputChannels = 2; - info.duplexChannels = 2; - info.isDefaultOutput = true; - info.isDefaultInput = true; + RtAudio::DeviceInfo info; + info.probed = true; + info.name = "PulseAudio"; + info.outputChannels = 2; + info.inputChannels = 2; + info.duplexChannels = 2; + info.isDefaultOutput = true; + info.isDefaultInput = true; - for ( const unsigned int *sr = SUPPORTED_SAMPLERATES; *sr; ++sr ) - info.sampleRates.push_back( *sr ); + for (const unsigned int *sr = SUPPORTED_SAMPLERATES; *sr; ++sr) + info.sampleRates.push_back(*sr); - info.preferredSampleRate = 48000; - info.nativeFormats = RTAUDIO_SINT16 | RTAUDIO_SINT32 | RTAUDIO_FLOAT32; + info.preferredSampleRate = 48000; + info.nativeFormats = RTAUDIO_SINT16 | RTAUDIO_SINT32 | RTAUDIO_FLOAT32; - return info; + return info; } -static void *pulseaudio_callback( void * user ) +static void *pulseaudio_callback(void *user) { - CallbackInfo *cbi = static_cast( user ); - RtApiPulse *context = static_cast( cbi->object ); - volatile bool *isRunning = &cbi->isRunning; + CallbackInfo *cbi = static_cast(user); + RtApiPulse *context = static_cast(cbi->object); + volatile bool *isRunning = &cbi->isRunning; - while ( *isRunning ) { - pthread_testcancel(); - context->callbackEvent(); - } + while (*isRunning) + { + pthread_testcancel(); + context->callbackEvent(); + } - pthread_exit( NULL ); + pthread_exit(NULL); } -void RtApiPulse::closeStream( void ) +void RtApiPulse::closeStream(void) { - PulseAudioHandle *pah = static_cast( stream_.apiHandle ); + PulseAudioHandle *pah = static_cast(stream_.apiHandle); - stream_.callbackInfo.isRunning = false; - if ( pah ) { - MUTEX_LOCK( &stream_.mutex ); - if ( stream_.state == STREAM_STOPPED ) { - pah->runnable = true; - pthread_cond_signal( &pah->runnable_cv ); - } - MUTEX_UNLOCK( &stream_.mutex ); + stream_.callbackInfo.isRunning = false; + if (pah) + { + MUTEX_LOCK(&stream_.mutex); + if (stream_.state == STREAM_STOPPED) + { + pah->runnable = true; + pthread_cond_signal(&pah->runnable_cv); + } + MUTEX_UNLOCK(&stream_.mutex); - pthread_join( pah->thread, 0 ); - if ( pah->s_play ) { - pa_simple_flush( pah->s_play, NULL ); - pa_simple_free( pah->s_play ); - } - if ( pah->s_rec ) - pa_simple_free( pah->s_rec ); + pthread_join(pah->thread, 0); + if (pah->s_play) + { + pa_simple_flush(pah->s_play, NULL); + pa_simple_free(pah->s_play); + } + if (pah->s_rec) + pa_simple_free(pah->s_rec); - pthread_cond_destroy( &pah->runnable_cv ); - delete pah; - stream_.apiHandle = 0; - } + pthread_cond_destroy(&pah->runnable_cv); + delete pah; + stream_.apiHandle = 0; + } - if ( stream_.userBuffer[0] ) { - free( stream_.userBuffer[0] ); - stream_.userBuffer[0] = 0; - } - if ( stream_.userBuffer[1] ) { - free( stream_.userBuffer[1] ); - stream_.userBuffer[1] = 0; - } + if (stream_.userBuffer[0]) + { + free(stream_.userBuffer[0]); + stream_.userBuffer[0] = 0; + } + if (stream_.userBuffer[1]) + { + free(stream_.userBuffer[1]); + stream_.userBuffer[1] = 0; + } - stream_.state = STREAM_CLOSED; - stream_.mode = UNINITIALIZED; + stream_.state = STREAM_CLOSED; + stream_.mode = UNINITIALIZED; } -void RtApiPulse::callbackEvent( void ) +void RtApiPulse::callbackEvent(void) { - PulseAudioHandle *pah = static_cast( stream_.apiHandle ); + PulseAudioHandle *pah = static_cast(stream_.apiHandle); - if ( stream_.state == STREAM_STOPPED ) { - MUTEX_LOCK( &stream_.mutex ); - while ( !pah->runnable ) - pthread_cond_wait( &pah->runnable_cv, &stream_.mutex ); + if (stream_.state == STREAM_STOPPED) + { + MUTEX_LOCK(&stream_.mutex); + while (!pah->runnable) + pthread_cond_wait(&pah->runnable_cv, &stream_.mutex); - if ( stream_.state != STREAM_RUNNING ) { - MUTEX_UNLOCK( &stream_.mutex ); - return; - } - MUTEX_UNLOCK( &stream_.mutex ); - } + if (stream_.state != STREAM_RUNNING) + { + MUTEX_UNLOCK(&stream_.mutex); + return; + } + MUTEX_UNLOCK(&stream_.mutex); + } - if ( stream_.state == STREAM_CLOSED ) { - errorText_ = "RtApiPulse::callbackEvent(): the stream is closed ... " - "this shouldn't happen!"; - error( RtAudioError::WARNING ); - return; - } + if (stream_.state == STREAM_CLOSED) + { + errorText_ = + "RtApiPulse::callbackEvent(): the stream is closed ... " + "this shouldn't happen!"; + error(RtAudioError::WARNING); + return; + } - RtAudioCallback callback = (RtAudioCallback) stream_.callbackInfo.callback; - double streamTime = getStreamTime(); - RtAudioStreamStatus status = 0; - int doStopStream = callback( stream_.userBuffer[OUTPUT], stream_.userBuffer[INPUT], - stream_.bufferSize, streamTime, status, - stream_.callbackInfo.userData ); + RtAudioCallback callback = (RtAudioCallback)stream_.callbackInfo.callback; + double streamTime = getStreamTime(); + RtAudioStreamStatus status = 0; + int doStopStream = callback(stream_.userBuffer[OUTPUT], stream_.userBuffer[INPUT], + stream_.bufferSize, streamTime, status, + stream_.callbackInfo.userData); - if ( doStopStream == 2 ) { - abortStream(); - return; - } + if (doStopStream == 2) + { + abortStream(); + return; + } - MUTEX_LOCK( &stream_.mutex ); - void *pulse_in = stream_.doConvertBuffer[INPUT] ? stream_.deviceBuffer : stream_.userBuffer[INPUT]; - void *pulse_out = stream_.doConvertBuffer[OUTPUT] ? stream_.deviceBuffer : stream_.userBuffer[OUTPUT]; + MUTEX_LOCK(&stream_.mutex); + void *pulse_in = stream_.doConvertBuffer[INPUT] ? stream_.deviceBuffer : stream_.userBuffer[INPUT]; + void *pulse_out = stream_.doConvertBuffer[OUTPUT] ? stream_.deviceBuffer : stream_.userBuffer[OUTPUT]; - if ( stream_.state != STREAM_RUNNING ) - goto unlock; + if (stream_.state != STREAM_RUNNING) + goto unlock; - int pa_error; - size_t bytes; - if (stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { - if ( stream_.doConvertBuffer[OUTPUT] ) { - convertBuffer( stream_.deviceBuffer, - stream_.userBuffer[OUTPUT], - stream_.convertInfo[OUTPUT] ); - bytes = stream_.nDeviceChannels[OUTPUT] * stream_.bufferSize * - formatBytes( stream_.deviceFormat[OUTPUT] ); - } else - bytes = stream_.nUserChannels[OUTPUT] * stream_.bufferSize * - formatBytes( stream_.userFormat ); + int pa_error; + size_t bytes; + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + { + if (stream_.doConvertBuffer[OUTPUT]) + { + convertBuffer(stream_.deviceBuffer, + stream_.userBuffer[OUTPUT], + stream_.convertInfo[OUTPUT]); + bytes = stream_.nDeviceChannels[OUTPUT] * stream_.bufferSize * + formatBytes(stream_.deviceFormat[OUTPUT]); + } + else + bytes = stream_.nUserChannels[OUTPUT] * stream_.bufferSize * + formatBytes(stream_.userFormat); - if ( pa_simple_write( pah->s_play, pulse_out, bytes, &pa_error ) < 0 ) { - errorStream_ << "RtApiPulse::callbackEvent: audio write error, " << - pa_strerror( pa_error ) << "."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - } - } + if (pa_simple_write(pah->s_play, pulse_out, bytes, &pa_error) < 0) + { + errorStream_ << "RtApiPulse::callbackEvent: audio write error, " << pa_strerror(pa_error) << "."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + } + } - if ( stream_.mode == INPUT || stream_.mode == DUPLEX) { - if ( stream_.doConvertBuffer[INPUT] ) - bytes = stream_.nDeviceChannels[INPUT] * stream_.bufferSize * - formatBytes( stream_.deviceFormat[INPUT] ); - else - bytes = stream_.nUserChannels[INPUT] * stream_.bufferSize * - formatBytes( stream_.userFormat ); - - if ( pa_simple_read( pah->s_rec, pulse_in, bytes, &pa_error ) < 0 ) { - errorStream_ << "RtApiPulse::callbackEvent: audio read error, " << - pa_strerror( pa_error ) << "."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - } - if ( stream_.doConvertBuffer[INPUT] ) { - convertBuffer( stream_.userBuffer[INPUT], - stream_.deviceBuffer, - stream_.convertInfo[INPUT] ); - } - } + if (stream_.mode == INPUT || stream_.mode == DUPLEX) + { + if (stream_.doConvertBuffer[INPUT]) + bytes = stream_.nDeviceChannels[INPUT] * stream_.bufferSize * + formatBytes(stream_.deviceFormat[INPUT]); + else + bytes = stream_.nUserChannels[INPUT] * stream_.bufferSize * + formatBytes(stream_.userFormat); - unlock: - MUTEX_UNLOCK( &stream_.mutex ); - RtApi::tickStreamTime(); + if (pa_simple_read(pah->s_rec, pulse_in, bytes, &pa_error) < 0) + { + errorStream_ << "RtApiPulse::callbackEvent: audio read error, " << pa_strerror(pa_error) << "."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + } + if (stream_.doConvertBuffer[INPUT]) + { + convertBuffer(stream_.userBuffer[INPUT], + stream_.deviceBuffer, + stream_.convertInfo[INPUT]); + } + } - if ( doStopStream == 1 ) - stopStream(); +unlock: + MUTEX_UNLOCK(&stream_.mutex); + RtApi::tickStreamTime(); + + if (doStopStream == 1) + stopStream(); } -void RtApiPulse::startStream( void ) +void RtApiPulse::startStream(void) { - PulseAudioHandle *pah = static_cast( stream_.apiHandle ); + PulseAudioHandle *pah = static_cast(stream_.apiHandle); - if ( stream_.state == STREAM_CLOSED ) { - errorText_ = "RtApiPulse::startStream(): the stream is not open!"; - error( RtAudioError::INVALID_USE ); - return; - } - if ( stream_.state == STREAM_RUNNING ) { - errorText_ = "RtApiPulse::startStream(): the stream is already running!"; - error( RtAudioError::WARNING ); - return; - } + if (stream_.state == STREAM_CLOSED) + { + errorText_ = "RtApiPulse::startStream(): the stream is not open!"; + error(RtAudioError::INVALID_USE); + return; + } + if (stream_.state == STREAM_RUNNING) + { + errorText_ = "RtApiPulse::startStream(): the stream is already running!"; + error(RtAudioError::WARNING); + return; + } - MUTEX_LOCK( &stream_.mutex ); + MUTEX_LOCK(&stream_.mutex); - stream_.state = STREAM_RUNNING; + stream_.state = STREAM_RUNNING; - pah->runnable = true; - pthread_cond_signal( &pah->runnable_cv ); - MUTEX_UNLOCK( &stream_.mutex ); + pah->runnable = true; + pthread_cond_signal(&pah->runnable_cv); + MUTEX_UNLOCK(&stream_.mutex); } -void RtApiPulse::stopStream( void ) +void RtApiPulse::stopStream(void) { - PulseAudioHandle *pah = static_cast( stream_.apiHandle ); + PulseAudioHandle *pah = static_cast(stream_.apiHandle); - if ( stream_.state == STREAM_CLOSED ) { - errorText_ = "RtApiPulse::stopStream(): the stream is not open!"; - error( RtAudioError::INVALID_USE ); - return; - } - if ( stream_.state == STREAM_STOPPED ) { - errorText_ = "RtApiPulse::stopStream(): the stream is already stopped!"; - error( RtAudioError::WARNING ); - return; - } + if (stream_.state == STREAM_CLOSED) + { + errorText_ = "RtApiPulse::stopStream(): the stream is not open!"; + error(RtAudioError::INVALID_USE); + return; + } + if (stream_.state == STREAM_STOPPED) + { + errorText_ = "RtApiPulse::stopStream(): the stream is already stopped!"; + error(RtAudioError::WARNING); + return; + } - stream_.state = STREAM_STOPPED; - MUTEX_LOCK( &stream_.mutex ); + stream_.state = STREAM_STOPPED; + MUTEX_LOCK(&stream_.mutex); - if ( pah && pah->s_play ) { - int pa_error; - if ( pa_simple_drain( pah->s_play, &pa_error ) < 0 ) { - errorStream_ << "RtApiPulse::stopStream: error draining output device, " << - pa_strerror( pa_error ) << "."; - errorText_ = errorStream_.str(); - MUTEX_UNLOCK( &stream_.mutex ); - error( RtAudioError::SYSTEM_ERROR ); - return; - } - } + if (pah && pah->s_play) + { + int pa_error; + if (pa_simple_drain(pah->s_play, &pa_error) < 0) + { + errorStream_ << "RtApiPulse::stopStream: error draining output device, " << pa_strerror(pa_error) << "."; + errorText_ = errorStream_.str(); + MUTEX_UNLOCK(&stream_.mutex); + error(RtAudioError::SYSTEM_ERROR); + return; + } + } - stream_.state = STREAM_STOPPED; - MUTEX_UNLOCK( &stream_.mutex ); + stream_.state = STREAM_STOPPED; + MUTEX_UNLOCK(&stream_.mutex); } -void RtApiPulse::abortStream( void ) +void RtApiPulse::abortStream(void) { - PulseAudioHandle *pah = static_cast( stream_.apiHandle ); + PulseAudioHandle *pah = static_cast(stream_.apiHandle); - if ( stream_.state == STREAM_CLOSED ) { - errorText_ = "RtApiPulse::abortStream(): the stream is not open!"; - error( RtAudioError::INVALID_USE ); - return; - } - if ( stream_.state == STREAM_STOPPED ) { - errorText_ = "RtApiPulse::abortStream(): the stream is already stopped!"; - error( RtAudioError::WARNING ); - return; - } + if (stream_.state == STREAM_CLOSED) + { + errorText_ = "RtApiPulse::abortStream(): the stream is not open!"; + error(RtAudioError::INVALID_USE); + return; + } + if (stream_.state == STREAM_STOPPED) + { + errorText_ = "RtApiPulse::abortStream(): the stream is already stopped!"; + error(RtAudioError::WARNING); + return; + } - stream_.state = STREAM_STOPPED; - MUTEX_LOCK( &stream_.mutex ); + stream_.state = STREAM_STOPPED; + MUTEX_LOCK(&stream_.mutex); - if ( pah && pah->s_play ) { - int pa_error; - if ( pa_simple_flush( pah->s_play, &pa_error ) < 0 ) { - errorStream_ << "RtApiPulse::abortStream: error flushing output device, " << - pa_strerror( pa_error ) << "."; - errorText_ = errorStream_.str(); - MUTEX_UNLOCK( &stream_.mutex ); - error( RtAudioError::SYSTEM_ERROR ); - return; - } - } + if (pah && pah->s_play) + { + int pa_error; + if (pa_simple_flush(pah->s_play, &pa_error) < 0) + { + errorStream_ << "RtApiPulse::abortStream: error flushing output device, " << pa_strerror(pa_error) << "."; + errorText_ = errorStream_.str(); + MUTEX_UNLOCK(&stream_.mutex); + error(RtAudioError::SYSTEM_ERROR); + return; + } + } - stream_.state = STREAM_STOPPED; - MUTEX_UNLOCK( &stream_.mutex ); + stream_.state = STREAM_STOPPED; + MUTEX_UNLOCK(&stream_.mutex); } -bool RtApiPulse::probeDeviceOpen( unsigned int device, StreamMode mode, - unsigned int channels, unsigned int firstChannel, - unsigned int sampleRate, RtAudioFormat format, - unsigned int *bufferSize, RtAudio::StreamOptions *options ) +bool RtApiPulse::probeDeviceOpen(unsigned int device, StreamMode mode, + unsigned int channels, unsigned int firstChannel, + unsigned int sampleRate, RtAudioFormat format, + unsigned int *bufferSize, RtAudio::StreamOptions *options) { - PulseAudioHandle *pah = 0; - unsigned long bufferBytes = 0; - pa_sample_spec ss; + PulseAudioHandle *pah = 0; + unsigned long bufferBytes = 0; + pa_sample_spec ss; - if ( device != 0 ) return false; - if ( mode != INPUT && mode != OUTPUT ) return false; - if ( channels != 1 && channels != 2 ) { - errorText_ = "RtApiPulse::probeDeviceOpen: unsupported number of channels."; - return false; - } - ss.channels = channels; + if (device != 0) return false; + if (mode != INPUT && mode != OUTPUT) return false; + if (channels != 1 && channels != 2) + { + errorText_ = "RtApiPulse::probeDeviceOpen: unsupported number of channels."; + return false; + } + ss.channels = channels; - if ( firstChannel != 0 ) return false; + if (firstChannel != 0) return false; - bool sr_found = false; - for ( const unsigned int *sr = SUPPORTED_SAMPLERATES; *sr; ++sr ) { - if ( sampleRate == *sr ) { - sr_found = true; - stream_.sampleRate = sampleRate; - ss.rate = sampleRate; - break; - } - } - if ( !sr_found ) { - errorText_ = "RtApiPulse::probeDeviceOpen: unsupported sample rate."; - return false; - } + bool sr_found = false; + for (const unsigned int *sr = SUPPORTED_SAMPLERATES; *sr; ++sr) + { + if (sampleRate == *sr) + { + sr_found = true; + stream_.sampleRate = sampleRate; + ss.rate = sampleRate; + break; + } + } + if (!sr_found) + { + errorText_ = "RtApiPulse::probeDeviceOpen: unsupported sample rate."; + return false; + } - bool sf_found = 0; - for ( const rtaudio_pa_format_mapping_t *sf = supported_sampleformats; - sf->rtaudio_format && sf->pa_format != PA_SAMPLE_INVALID; ++sf ) { - if ( format == sf->rtaudio_format ) { - sf_found = true; - stream_.userFormat = sf->rtaudio_format; - stream_.deviceFormat[mode] = stream_.userFormat; - ss.format = sf->pa_format; - break; - } - } - if ( !sf_found ) { // Use internal data format conversion. - stream_.userFormat = format; - stream_.deviceFormat[mode] = RTAUDIO_FLOAT32; - ss.format = PA_SAMPLE_FLOAT32LE; - } + bool sf_found = 0; + for (const rtaudio_pa_format_mapping_t *sf = supported_sampleformats; + sf->rtaudio_format && sf->pa_format != PA_SAMPLE_INVALID; ++sf) + { + if (format == sf->rtaudio_format) + { + sf_found = true; + stream_.userFormat = sf->rtaudio_format; + stream_.deviceFormat[mode] = stream_.userFormat; + ss.format = sf->pa_format; + break; + } + } + if (!sf_found) + { // Use internal data format conversion. + stream_.userFormat = format; + stream_.deviceFormat[mode] = RTAUDIO_FLOAT32; + ss.format = PA_SAMPLE_FLOAT32LE; + } - // Set other stream parameters. - if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) stream_.userInterleaved = false; - else stream_.userInterleaved = true; - stream_.deviceInterleaved[mode] = true; - stream_.nBuffers = 1; - stream_.doByteSwap[mode] = false; - stream_.nUserChannels[mode] = channels; - stream_.nDeviceChannels[mode] = channels + firstChannel; - stream_.channelOffset[mode] = 0; - std::string streamName = "RtAudio"; + // Set other stream parameters. + if (options && options->flags & RTAUDIO_NONINTERLEAVED) + stream_.userInterleaved = false; + else + stream_.userInterleaved = true; + stream_.deviceInterleaved[mode] = true; + stream_.nBuffers = 1; + stream_.doByteSwap[mode] = false; + stream_.nUserChannels[mode] = channels; + stream_.nDeviceChannels[mode] = channels + firstChannel; + stream_.channelOffset[mode] = 0; + std::string streamName = "RtAudio"; - // Set flags for buffer conversion. - stream_.doConvertBuffer[mode] = false; - if ( stream_.userFormat != stream_.deviceFormat[mode] ) - stream_.doConvertBuffer[mode] = true; - if ( stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode] ) - stream_.doConvertBuffer[mode] = true; + // Set flags for buffer conversion. + stream_.doConvertBuffer[mode] = false; + if (stream_.userFormat != stream_.deviceFormat[mode]) + stream_.doConvertBuffer[mode] = true; + if (stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode]) + stream_.doConvertBuffer[mode] = true; - // Allocate necessary internal buffers. - bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat ); - stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 ); - if ( stream_.userBuffer[mode] == NULL ) { - errorText_ = "RtApiPulse::probeDeviceOpen: error allocating user buffer memory."; - goto error; - } - stream_.bufferSize = *bufferSize; + // Allocate necessary internal buffers. + bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes(stream_.userFormat); + stream_.userBuffer[mode] = (char *)calloc(bufferBytes, 1); + if (stream_.userBuffer[mode] == NULL) + { + errorText_ = "RtApiPulse::probeDeviceOpen: error allocating user buffer memory."; + goto error; + } + stream_.bufferSize = *bufferSize; - if ( stream_.doConvertBuffer[mode] ) { + if (stream_.doConvertBuffer[mode]) + { + bool makeBuffer = true; + bufferBytes = stream_.nDeviceChannels[mode] * formatBytes(stream_.deviceFormat[mode]); + if (mode == INPUT) + { + if (stream_.mode == OUTPUT && stream_.deviceBuffer) + { + unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes(stream_.deviceFormat[0]); + if (bufferBytes <= bytesOut) makeBuffer = false; + } + } - bool makeBuffer = true; - bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] ); - if ( mode == INPUT ) { - if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) { - unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] ); - if ( bufferBytes <= bytesOut ) makeBuffer = false; - } - } + if (makeBuffer) + { + bufferBytes *= *bufferSize; + if (stream_.deviceBuffer) free(stream_.deviceBuffer); + stream_.deviceBuffer = (char *)calloc(bufferBytes, 1); + if (stream_.deviceBuffer == NULL) + { + errorText_ = "RtApiPulse::probeDeviceOpen: error allocating device buffer memory."; + goto error; + } + } + } - if ( makeBuffer ) { - bufferBytes *= *bufferSize; - if ( stream_.deviceBuffer ) free( stream_.deviceBuffer ); - stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 ); - if ( stream_.deviceBuffer == NULL ) { - errorText_ = "RtApiPulse::probeDeviceOpen: error allocating device buffer memory."; - goto error; - } - } - } + stream_.device[mode] = device; - stream_.device[mode] = device; + // Setup the buffer conversion information structure. + if (stream_.doConvertBuffer[mode]) setConvertInfo(mode, firstChannel); - // Setup the buffer conversion information structure. - if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, firstChannel ); + if (!stream_.apiHandle) + { + PulseAudioHandle *pah = new PulseAudioHandle; + if (!pah) + { + errorText_ = "RtApiPulse::probeDeviceOpen: error allocating memory for handle."; + goto error; + } - if ( !stream_.apiHandle ) { - PulseAudioHandle *pah = new PulseAudioHandle; - if ( !pah ) { - errorText_ = "RtApiPulse::probeDeviceOpen: error allocating memory for handle."; - goto error; - } + stream_.apiHandle = pah; + if (pthread_cond_init(&pah->runnable_cv, NULL) != 0) + { + errorText_ = "RtApiPulse::probeDeviceOpen: error creating condition variable."; + goto error; + } + } + pah = static_cast(stream_.apiHandle); - stream_.apiHandle = pah; - if ( pthread_cond_init( &pah->runnable_cv, NULL ) != 0 ) { - errorText_ = "RtApiPulse::probeDeviceOpen: error creating condition variable."; - goto error; - } - } - pah = static_cast( stream_.apiHandle ); + int error; + if (options && !options->streamName.empty()) streamName = options->streamName; + switch (mode) + { + case INPUT: + pa_buffer_attr buffer_attr; + buffer_attr.fragsize = bufferBytes; + buffer_attr.maxlength = -1; - int error; - if ( options && !options->streamName.empty() ) streamName = options->streamName; - switch ( mode ) { - case INPUT: - pa_buffer_attr buffer_attr; - buffer_attr.fragsize = bufferBytes; - buffer_attr.maxlength = -1; + pah->s_rec = pa_simple_new(NULL, streamName.c_str(), PA_STREAM_RECORD, NULL, "Record", &ss, NULL, &buffer_attr, &error); + if (!pah->s_rec) + { + errorText_ = "RtApiPulse::probeDeviceOpen: error connecting input to PulseAudio server."; + goto error; + } + break; + case OUTPUT: + pah->s_play = pa_simple_new(NULL, streamName.c_str(), PA_STREAM_PLAYBACK, NULL, "Playback", &ss, NULL, NULL, &error); + if (!pah->s_play) + { + errorText_ = "RtApiPulse::probeDeviceOpen: error connecting output to PulseAudio server."; + goto error; + } + break; + default: + goto error; + } - pah->s_rec = pa_simple_new( NULL, streamName.c_str(), PA_STREAM_RECORD, NULL, "Record", &ss, NULL, &buffer_attr, &error ); - if ( !pah->s_rec ) { - errorText_ = "RtApiPulse::probeDeviceOpen: error connecting input to PulseAudio server."; - goto error; - } - break; - case OUTPUT: - pah->s_play = pa_simple_new( NULL, streamName.c_str(), PA_STREAM_PLAYBACK, NULL, "Playback", &ss, NULL, NULL, &error ); - if ( !pah->s_play ) { - errorText_ = "RtApiPulse::probeDeviceOpen: error connecting output to PulseAudio server."; - goto error; - } - break; - default: - goto error; - } + if (stream_.mode == UNINITIALIZED) + stream_.mode = mode; + else if (stream_.mode == mode) + goto error; + else + stream_.mode = DUPLEX; - if ( stream_.mode == UNINITIALIZED ) - stream_.mode = mode; - else if ( stream_.mode == mode ) - goto error; - else - stream_.mode = DUPLEX; + if (!stream_.callbackInfo.isRunning) + { + stream_.callbackInfo.object = this; + stream_.callbackInfo.isRunning = true; + if (pthread_create(&pah->thread, NULL, pulseaudio_callback, (void *)&stream_.callbackInfo) != 0) + { + errorText_ = "RtApiPulse::probeDeviceOpen: error creating thread."; + goto error; + } + } - if ( !stream_.callbackInfo.isRunning ) { - stream_.callbackInfo.object = this; - stream_.callbackInfo.isRunning = true; - if ( pthread_create( &pah->thread, NULL, pulseaudio_callback, (void *)&stream_.callbackInfo) != 0 ) { - errorText_ = "RtApiPulse::probeDeviceOpen: error creating thread."; - goto error; - } - } + stream_.state = STREAM_STOPPED; + return true; - stream_.state = STREAM_STOPPED; - return true; - - error: - if ( pah && stream_.callbackInfo.isRunning ) { - pthread_cond_destroy( &pah->runnable_cv ); - delete pah; - stream_.apiHandle = 0; - } +error: + if (pah && stream_.callbackInfo.isRunning) + { + pthread_cond_destroy(&pah->runnable_cv); + delete pah; + stream_.apiHandle = 0; + } - for ( int i=0; i<2; i++ ) { - if ( stream_.userBuffer[i] ) { - free( stream_.userBuffer[i] ); - stream_.userBuffer[i] = 0; - } - } + for (int i = 0; i < 2; i++) + { + if (stream_.userBuffer[i]) + { + free(stream_.userBuffer[i]); + stream_.userBuffer[i] = 0; + } + } - if ( stream_.deviceBuffer ) { - free( stream_.deviceBuffer ); - stream_.deviceBuffer = 0; - } + if (stream_.deviceBuffer) + { + free(stream_.deviceBuffer); + stream_.deviceBuffer = 0; + } - return FAILURE; + return FAILURE; } //******************** End of __LINUX_PULSE__ *********************// @@ -8587,267 +9442,302 @@ bool RtApiPulse::probeDeviceOpen( unsigned int device, StreamMode mode, #include #include -static void *ossCallbackHandler(void * ptr); +static void *ossCallbackHandler(void *ptr); // A structure to hold various information related to the OSS API // implementation. -struct OssHandle { - int id[2]; // device ids - bool xrun[2]; - bool triggered; - pthread_cond_t runnable; +struct OssHandle +{ + int id[2]; // device ids + bool xrun[2]; + bool triggered; + pthread_cond_t runnable; - OssHandle() - :triggered(false) { id[0] = 0; id[1] = 0; xrun[0] = false; xrun[1] = false; } + OssHandle() + : triggered(false) + { + id[0] = 0; + id[1] = 0; + xrun[0] = false; + xrun[1] = false; + } }; -RtApiOss :: RtApiOss() +RtApiOss ::RtApiOss() { - // Nothing to do here. + // Nothing to do here. } -RtApiOss :: ~RtApiOss() +RtApiOss ::~RtApiOss() { - if ( stream_.state != STREAM_CLOSED ) closeStream(); + if (stream_.state != STREAM_CLOSED) closeStream(); } -unsigned int RtApiOss :: getDeviceCount( void ) +unsigned int RtApiOss ::getDeviceCount(void) { - int mixerfd = open( "/dev/mixer", O_RDWR, 0 ); - if ( mixerfd == -1 ) { - errorText_ = "RtApiOss::getDeviceCount: error opening '/dev/mixer'."; - error( RtAudioError::WARNING ); - return 0; - } + int mixerfd = open("/dev/mixer", O_RDWR, 0); + if (mixerfd == -1) + { + errorText_ = "RtApiOss::getDeviceCount: error opening '/dev/mixer'."; + error(RtAudioError::WARNING); + return 0; + } - oss_sysinfo sysinfo; - if ( ioctl( mixerfd, SNDCTL_SYSINFO, &sysinfo ) == -1 ) { - close( mixerfd ); - errorText_ = "RtApiOss::getDeviceCount: error getting sysinfo, OSS version >= 4.0 is required."; - error( RtAudioError::WARNING ); - return 0; - } + oss_sysinfo sysinfo; + if (ioctl(mixerfd, SNDCTL_SYSINFO, &sysinfo) == -1) + { + close(mixerfd); + errorText_ = "RtApiOss::getDeviceCount: error getting sysinfo, OSS version >= 4.0 is required."; + error(RtAudioError::WARNING); + return 0; + } - close( mixerfd ); - return sysinfo.numaudios; + close(mixerfd); + return sysinfo.numaudios; } -RtAudio::DeviceInfo RtApiOss :: getDeviceInfo( unsigned int device ) +RtAudio::DeviceInfo RtApiOss ::getDeviceInfo(unsigned int device) { - RtAudio::DeviceInfo info; - info.probed = false; + RtAudio::DeviceInfo info; + info.probed = false; - int mixerfd = open( "/dev/mixer", O_RDWR, 0 ); - if ( mixerfd == -1 ) { - errorText_ = "RtApiOss::getDeviceInfo: error opening '/dev/mixer'."; - error( RtAudioError::WARNING ); - return info; - } + int mixerfd = open("/dev/mixer", O_RDWR, 0); + if (mixerfd == -1) + { + errorText_ = "RtApiOss::getDeviceInfo: error opening '/dev/mixer'."; + error(RtAudioError::WARNING); + return info; + } - oss_sysinfo sysinfo; - int result = ioctl( mixerfd, SNDCTL_SYSINFO, &sysinfo ); - if ( result == -1 ) { - close( mixerfd ); - errorText_ = "RtApiOss::getDeviceInfo: error getting sysinfo, OSS version >= 4.0 is required."; - error( RtAudioError::WARNING ); - return info; - } + oss_sysinfo sysinfo; + int result = ioctl(mixerfd, SNDCTL_SYSINFO, &sysinfo); + if (result == -1) + { + close(mixerfd); + errorText_ = "RtApiOss::getDeviceInfo: error getting sysinfo, OSS version >= 4.0 is required."; + error(RtAudioError::WARNING); + return info; + } - unsigned nDevices = sysinfo.numaudios; - if ( nDevices == 0 ) { - close( mixerfd ); - errorText_ = "RtApiOss::getDeviceInfo: no devices found!"; - error( RtAudioError::INVALID_USE ); - return info; - } + unsigned nDevices = sysinfo.numaudios; + if (nDevices == 0) + { + close(mixerfd); + errorText_ = "RtApiOss::getDeviceInfo: no devices found!"; + error(RtAudioError::INVALID_USE); + return info; + } - if ( device >= nDevices ) { - close( mixerfd ); - errorText_ = "RtApiOss::getDeviceInfo: device ID is invalid!"; - error( RtAudioError::INVALID_USE ); - return info; - } + if (device >= nDevices) + { + close(mixerfd); + errorText_ = "RtApiOss::getDeviceInfo: device ID is invalid!"; + error(RtAudioError::INVALID_USE); + return info; + } - oss_audioinfo ainfo; - ainfo.dev = device; - result = ioctl( mixerfd, SNDCTL_AUDIOINFO, &ainfo ); - close( mixerfd ); - if ( result == -1 ) { - errorStream_ << "RtApiOss::getDeviceInfo: error getting device (" << ainfo.name << ") info."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + oss_audioinfo ainfo; + ainfo.dev = device; + result = ioctl(mixerfd, SNDCTL_AUDIOINFO, &ainfo); + close(mixerfd); + if (result == -1) + { + errorStream_ << "RtApiOss::getDeviceInfo: error getting device (" << ainfo.name << ") info."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - // Probe channels - if ( ainfo.caps & PCM_CAP_OUTPUT ) info.outputChannels = ainfo.max_channels; - if ( ainfo.caps & PCM_CAP_INPUT ) info.inputChannels = ainfo.max_channels; - if ( ainfo.caps & PCM_CAP_DUPLEX ) { - if ( info.outputChannels > 0 && info.inputChannels > 0 && ainfo.caps & PCM_CAP_DUPLEX ) - info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels; - } + // Probe channels + if (ainfo.caps & PCM_CAP_OUTPUT) info.outputChannels = ainfo.max_channels; + if (ainfo.caps & PCM_CAP_INPUT) info.inputChannels = ainfo.max_channels; + if (ainfo.caps & PCM_CAP_DUPLEX) + { + if (info.outputChannels > 0 && info.inputChannels > 0 && ainfo.caps & PCM_CAP_DUPLEX) + info.duplexChannels = (info.outputChannels > info.inputChannels) ? info.inputChannels : info.outputChannels; + } - // Probe data formats ... do for input - unsigned long mask = ainfo.iformats; - if ( mask & AFMT_S16_LE || mask & AFMT_S16_BE ) - info.nativeFormats |= RTAUDIO_SINT16; - if ( mask & AFMT_S8 ) - info.nativeFormats |= RTAUDIO_SINT8; - if ( mask & AFMT_S32_LE || mask & AFMT_S32_BE ) - info.nativeFormats |= RTAUDIO_SINT32; - if ( mask & AFMT_FLOAT ) - info.nativeFormats |= RTAUDIO_FLOAT32; - if ( mask & AFMT_S24_LE || mask & AFMT_S24_BE ) - info.nativeFormats |= RTAUDIO_SINT24; + // Probe data formats ... do for input + unsigned long mask = ainfo.iformats; + if (mask & AFMT_S16_LE || mask & AFMT_S16_BE) + info.nativeFormats |= RTAUDIO_SINT16; + if (mask & AFMT_S8) + info.nativeFormats |= RTAUDIO_SINT8; + if (mask & AFMT_S32_LE || mask & AFMT_S32_BE) + info.nativeFormats |= RTAUDIO_SINT32; + if (mask & AFMT_FLOAT) + info.nativeFormats |= RTAUDIO_FLOAT32; + if (mask & AFMT_S24_LE || mask & AFMT_S24_BE) + info.nativeFormats |= RTAUDIO_SINT24; - // Check that we have at least one supported format - if ( info.nativeFormats == 0 ) { - errorStream_ << "RtApiOss::getDeviceInfo: device (" << ainfo.name << ") data format not supported by RtAudio."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - return info; - } + // Check that we have at least one supported format + if (info.nativeFormats == 0) + { + errorStream_ << "RtApiOss::getDeviceInfo: device (" << ainfo.name << ") data format not supported by RtAudio."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + return info; + } - // Probe the supported sample rates. - info.sampleRates.clear(); - if ( ainfo.nrates ) { - for ( unsigned int i=0; i info.preferredSampleRate ) ) - info.preferredSampleRate = SAMPLE_RATES[k]; + if (!info.preferredSampleRate || (SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate)) + info.preferredSampleRate = SAMPLE_RATES[k]; - break; - } - } - } - } - else { - // Check min and max rate values; - for ( unsigned int k=0; k= (int) SAMPLE_RATES[k] ) { - info.sampleRates.push_back( SAMPLE_RATES[k] ); + break; + } + } + } + } + else + { + // Check min and max rate values; + for (unsigned int k = 0; k < MAX_SAMPLE_RATES; k++) + { + if (ainfo.min_rate <= (int)SAMPLE_RATES[k] && ainfo.max_rate >= (int)SAMPLE_RATES[k]) + { + info.sampleRates.push_back(SAMPLE_RATES[k]); - if ( !info.preferredSampleRate || ( SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate ) ) - info.preferredSampleRate = SAMPLE_RATES[k]; - } - } - } + if (!info.preferredSampleRate || (SAMPLE_RATES[k] <= 48000 && SAMPLE_RATES[k] > info.preferredSampleRate)) + info.preferredSampleRate = SAMPLE_RATES[k]; + } + } + } - if ( info.sampleRates.size() == 0 ) { - errorStream_ << "RtApiOss::getDeviceInfo: no supported sample rates found for device (" << ainfo.name << ")."; - errorText_ = errorStream_.str(); - error( RtAudioError::WARNING ); - } - else { - info.probed = true; - info.name = ainfo.name; - } + if (info.sampleRates.size() == 0) + { + errorStream_ << "RtApiOss::getDeviceInfo: no supported sample rates found for device (" << ainfo.name << ")."; + errorText_ = errorStream_.str(); + error(RtAudioError::WARNING); + } + else + { + info.probed = true; + info.name = ainfo.name; + } - return info; + return info; } - -bool RtApiOss :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, - unsigned int firstChannel, unsigned int sampleRate, - RtAudioFormat format, unsigned int *bufferSize, - RtAudio::StreamOptions *options ) +bool RtApiOss ::probeDeviceOpen(unsigned int device, StreamMode mode, unsigned int channels, + unsigned int firstChannel, unsigned int sampleRate, + RtAudioFormat format, unsigned int *bufferSize, + RtAudio::StreamOptions *options) { - int mixerfd = open( "/dev/mixer", O_RDWR, 0 ); - if ( mixerfd == -1 ) { - errorText_ = "RtApiOss::probeDeviceOpen: error opening '/dev/mixer'."; - return FAILURE; - } + int mixerfd = open("/dev/mixer", O_RDWR, 0); + if (mixerfd == -1) + { + errorText_ = "RtApiOss::probeDeviceOpen: error opening '/dev/mixer'."; + return FAILURE; + } - oss_sysinfo sysinfo; - int result = ioctl( mixerfd, SNDCTL_SYSINFO, &sysinfo ); - if ( result == -1 ) { - close( mixerfd ); - errorText_ = "RtApiOss::probeDeviceOpen: error getting sysinfo, OSS version >= 4.0 is required."; - return FAILURE; - } + oss_sysinfo sysinfo; + int result = ioctl(mixerfd, SNDCTL_SYSINFO, &sysinfo); + if (result == -1) + { + close(mixerfd); + errorText_ = "RtApiOss::probeDeviceOpen: error getting sysinfo, OSS version >= 4.0 is required."; + return FAILURE; + } - unsigned nDevices = sysinfo.numaudios; - if ( nDevices == 0 ) { - // This should not happen because a check is made before this function is called. - close( mixerfd ); - errorText_ = "RtApiOss::probeDeviceOpen: no devices found!"; - return FAILURE; - } + unsigned nDevices = sysinfo.numaudios; + if (nDevices == 0) + { + // This should not happen because a check is made before this function is called. + close(mixerfd); + errorText_ = "RtApiOss::probeDeviceOpen: no devices found!"; + return FAILURE; + } - if ( device >= nDevices ) { - // This should not happen because a check is made before this function is called. - close( mixerfd ); - errorText_ = "RtApiOss::probeDeviceOpen: device ID is invalid!"; - return FAILURE; - } + if (device >= nDevices) + { + // This should not happen because a check is made before this function is called. + close(mixerfd); + errorText_ = "RtApiOss::probeDeviceOpen: device ID is invalid!"; + return FAILURE; + } - oss_audioinfo ainfo; - ainfo.dev = device; - result = ioctl( mixerfd, SNDCTL_AUDIOINFO, &ainfo ); - close( mixerfd ); - if ( result == -1 ) { - errorStream_ << "RtApiOss::getDeviceInfo: error getting device (" << ainfo.name << ") info."; - errorText_ = errorStream_.str(); - return FAILURE; - } + oss_audioinfo ainfo; + ainfo.dev = device; + result = ioctl(mixerfd, SNDCTL_AUDIOINFO, &ainfo); + close(mixerfd); + if (result == -1) + { + errorStream_ << "RtApiOss::getDeviceInfo: error getting device (" << ainfo.name << ") info."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Check if device supports input or output - if ( ( mode == OUTPUT && !( ainfo.caps & PCM_CAP_OUTPUT ) ) || - ( mode == INPUT && !( ainfo.caps & PCM_CAP_INPUT ) ) ) { - if ( mode == OUTPUT ) - errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support output."; - else - errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support input."; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Check if device supports input or output + if ((mode == OUTPUT && !(ainfo.caps & PCM_CAP_OUTPUT)) || + (mode == INPUT && !(ainfo.caps & PCM_CAP_INPUT))) + { + if (mode == OUTPUT) + errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support output."; + else + errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support input."; + errorText_ = errorStream_.str(); + return FAILURE; + } - int flags = 0; - OssHandle *handle = (OssHandle *) stream_.apiHandle; - if ( mode == OUTPUT ) - flags |= O_WRONLY; - else { // mode == INPUT - if (stream_.mode == OUTPUT && stream_.device[0] == device) { - // We just set the same device for playback ... close and reopen for duplex (OSS only). - close( handle->id[0] ); - handle->id[0] = 0; - if ( !( ainfo.caps & PCM_CAP_DUPLEX ) ) { - errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support duplex mode."; - errorText_ = errorStream_.str(); - return FAILURE; - } - // Check that the number previously set channels is the same. - if ( stream_.nUserChannels[0] != channels ) { - errorStream_ << "RtApiOss::probeDeviceOpen: input/output channels must be equal for OSS duplex device (" << ainfo.name << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } - flags |= O_RDWR; - } - else - flags |= O_RDONLY; - } + int flags = 0; + OssHandle *handle = (OssHandle *)stream_.apiHandle; + if (mode == OUTPUT) + flags |= O_WRONLY; + else + { // mode == INPUT + if (stream_.mode == OUTPUT && stream_.device[0] == device) + { + // We just set the same device for playback ... close and reopen for duplex (OSS only). + close(handle->id[0]); + handle->id[0] = 0; + if (!(ainfo.caps & PCM_CAP_DUPLEX)) + { + errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support duplex mode."; + errorText_ = errorStream_.str(); + return FAILURE; + } + // Check that the number previously set channels is the same. + if (stream_.nUserChannels[0] != channels) + { + errorStream_ << "RtApiOss::probeDeviceOpen: input/output channels must be equal for OSS duplex device (" << ainfo.name << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } + flags |= O_RDWR; + } + else + flags |= O_RDONLY; + } - // Set exclusive access if specified. - if ( options && options->flags & RTAUDIO_HOG_DEVICE ) flags |= O_EXCL; + // Set exclusive access if specified. + if (options && options->flags & RTAUDIO_HOG_DEVICE) flags |= O_EXCL; - // Try to open the device. - int fd; - fd = open( ainfo.devnode, flags, 0 ); - if ( fd == -1 ) { - if ( errno == EBUSY ) - errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") is busy."; - else - errorStream_ << "RtApiOss::probeDeviceOpen: error opening device (" << ainfo.name << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Try to open the device. + int fd; + fd = open(ainfo.devnode, flags, 0); + if (fd == -1) + { + if (errno == EBUSY) + errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") is busy."; + else + errorStream_ << "RtApiOss::probeDeviceOpen: error opening device (" << ainfo.name << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // For duplex operation, specifically set this mode (this doesn't seem to work). - /* + // For duplex operation, specifically set this mode (this doesn't seem to work). + /* if ( flags | O_RDWR ) { result = ioctl( fd, SNDCTL_DSP_SETDUPLEX, NULL ); if ( result == -1) { @@ -8858,670 +9748,753 @@ bool RtApiOss :: probeDeviceOpen( unsigned int device, StreamMode mode, unsigned } */ - // Check the device channel support. - stream_.nUserChannels[mode] = channels; - if ( ainfo.max_channels < (int)(channels + firstChannel) ) { - close( fd ); - errorStream_ << "RtApiOss::probeDeviceOpen: the device (" << ainfo.name << ") does not support requested channel parameters."; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Check the device channel support. + stream_.nUserChannels[mode] = channels; + if (ainfo.max_channels < (int)(channels + firstChannel)) + { + close(fd); + errorStream_ << "RtApiOss::probeDeviceOpen: the device (" << ainfo.name << ") does not support requested channel parameters."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Set the number of channels. - int deviceChannels = channels + firstChannel; - result = ioctl( fd, SNDCTL_DSP_CHANNELS, &deviceChannels ); - if ( result == -1 || deviceChannels < (int)(channels + firstChannel) ) { - close( fd ); - errorStream_ << "RtApiOss::probeDeviceOpen: error setting channel parameters on device (" << ainfo.name << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } - stream_.nDeviceChannels[mode] = deviceChannels; + // Set the number of channels. + int deviceChannels = channels + firstChannel; + result = ioctl(fd, SNDCTL_DSP_CHANNELS, &deviceChannels); + if (result == -1 || deviceChannels < (int)(channels + firstChannel)) + { + close(fd); + errorStream_ << "RtApiOss::probeDeviceOpen: error setting channel parameters on device (" << ainfo.name << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } + stream_.nDeviceChannels[mode] = deviceChannels; - // Get the data format mask - int mask; - result = ioctl( fd, SNDCTL_DSP_GETFMTS, &mask ); - if ( result == -1 ) { - close( fd ); - errorStream_ << "RtApiOss::probeDeviceOpen: error getting device (" << ainfo.name << ") data formats."; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Get the data format mask + int mask; + result = ioctl(fd, SNDCTL_DSP_GETFMTS, &mask); + if (result == -1) + { + close(fd); + errorStream_ << "RtApiOss::probeDeviceOpen: error getting device (" << ainfo.name << ") data formats."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Determine how to set the device format. - stream_.userFormat = format; - int deviceFormat = -1; - stream_.doByteSwap[mode] = false; - if ( format == RTAUDIO_SINT8 ) { - if ( mask & AFMT_S8 ) { - deviceFormat = AFMT_S8; - stream_.deviceFormat[mode] = RTAUDIO_SINT8; - } - } - else if ( format == RTAUDIO_SINT16 ) { - if ( mask & AFMT_S16_NE ) { - deviceFormat = AFMT_S16_NE; - stream_.deviceFormat[mode] = RTAUDIO_SINT16; - } - else if ( mask & AFMT_S16_OE ) { - deviceFormat = AFMT_S16_OE; - stream_.deviceFormat[mode] = RTAUDIO_SINT16; - stream_.doByteSwap[mode] = true; - } - } - else if ( format == RTAUDIO_SINT24 ) { - if ( mask & AFMT_S24_NE ) { - deviceFormat = AFMT_S24_NE; - stream_.deviceFormat[mode] = RTAUDIO_SINT24; - } - else if ( mask & AFMT_S24_OE ) { - deviceFormat = AFMT_S24_OE; - stream_.deviceFormat[mode] = RTAUDIO_SINT24; - stream_.doByteSwap[mode] = true; - } - } - else if ( format == RTAUDIO_SINT32 ) { - if ( mask & AFMT_S32_NE ) { - deviceFormat = AFMT_S32_NE; - stream_.deviceFormat[mode] = RTAUDIO_SINT32; - } - else if ( mask & AFMT_S32_OE ) { - deviceFormat = AFMT_S32_OE; - stream_.deviceFormat[mode] = RTAUDIO_SINT32; - stream_.doByteSwap[mode] = true; - } - } + // Determine how to set the device format. + stream_.userFormat = format; + int deviceFormat = -1; + stream_.doByteSwap[mode] = false; + if (format == RTAUDIO_SINT8) + { + if (mask & AFMT_S8) + { + deviceFormat = AFMT_S8; + stream_.deviceFormat[mode] = RTAUDIO_SINT8; + } + } + else if (format == RTAUDIO_SINT16) + { + if (mask & AFMT_S16_NE) + { + deviceFormat = AFMT_S16_NE; + stream_.deviceFormat[mode] = RTAUDIO_SINT16; + } + else if (mask & AFMT_S16_OE) + { + deviceFormat = AFMT_S16_OE; + stream_.deviceFormat[mode] = RTAUDIO_SINT16; + stream_.doByteSwap[mode] = true; + } + } + else if (format == RTAUDIO_SINT24) + { + if (mask & AFMT_S24_NE) + { + deviceFormat = AFMT_S24_NE; + stream_.deviceFormat[mode] = RTAUDIO_SINT24; + } + else if (mask & AFMT_S24_OE) + { + deviceFormat = AFMT_S24_OE; + stream_.deviceFormat[mode] = RTAUDIO_SINT24; + stream_.doByteSwap[mode] = true; + } + } + else if (format == RTAUDIO_SINT32) + { + if (mask & AFMT_S32_NE) + { + deviceFormat = AFMT_S32_NE; + stream_.deviceFormat[mode] = RTAUDIO_SINT32; + } + else if (mask & AFMT_S32_OE) + { + deviceFormat = AFMT_S32_OE; + stream_.deviceFormat[mode] = RTAUDIO_SINT32; + stream_.doByteSwap[mode] = true; + } + } - if ( deviceFormat == -1 ) { - // The user requested format is not natively supported by the device. - if ( mask & AFMT_S16_NE ) { - deviceFormat = AFMT_S16_NE; - stream_.deviceFormat[mode] = RTAUDIO_SINT16; - } - else if ( mask & AFMT_S32_NE ) { - deviceFormat = AFMT_S32_NE; - stream_.deviceFormat[mode] = RTAUDIO_SINT32; - } - else if ( mask & AFMT_S24_NE ) { - deviceFormat = AFMT_S24_NE; - stream_.deviceFormat[mode] = RTAUDIO_SINT24; - } - else if ( mask & AFMT_S16_OE ) { - deviceFormat = AFMT_S16_OE; - stream_.deviceFormat[mode] = RTAUDIO_SINT16; - stream_.doByteSwap[mode] = true; - } - else if ( mask & AFMT_S32_OE ) { - deviceFormat = AFMT_S32_OE; - stream_.deviceFormat[mode] = RTAUDIO_SINT32; - stream_.doByteSwap[mode] = true; - } - else if ( mask & AFMT_S24_OE ) { - deviceFormat = AFMT_S24_OE; - stream_.deviceFormat[mode] = RTAUDIO_SINT24; - stream_.doByteSwap[mode] = true; - } - else if ( mask & AFMT_S8) { - deviceFormat = AFMT_S8; - stream_.deviceFormat[mode] = RTAUDIO_SINT8; - } - } + if (deviceFormat == -1) + { + // The user requested format is not natively supported by the device. + if (mask & AFMT_S16_NE) + { + deviceFormat = AFMT_S16_NE; + stream_.deviceFormat[mode] = RTAUDIO_SINT16; + } + else if (mask & AFMT_S32_NE) + { + deviceFormat = AFMT_S32_NE; + stream_.deviceFormat[mode] = RTAUDIO_SINT32; + } + else if (mask & AFMT_S24_NE) + { + deviceFormat = AFMT_S24_NE; + stream_.deviceFormat[mode] = RTAUDIO_SINT24; + } + else if (mask & AFMT_S16_OE) + { + deviceFormat = AFMT_S16_OE; + stream_.deviceFormat[mode] = RTAUDIO_SINT16; + stream_.doByteSwap[mode] = true; + } + else if (mask & AFMT_S32_OE) + { + deviceFormat = AFMT_S32_OE; + stream_.deviceFormat[mode] = RTAUDIO_SINT32; + stream_.doByteSwap[mode] = true; + } + else if (mask & AFMT_S24_OE) + { + deviceFormat = AFMT_S24_OE; + stream_.deviceFormat[mode] = RTAUDIO_SINT24; + stream_.doByteSwap[mode] = true; + } + else if (mask & AFMT_S8) + { + deviceFormat = AFMT_S8; + stream_.deviceFormat[mode] = RTAUDIO_SINT8; + } + } - if ( stream_.deviceFormat[mode] == 0 ) { - // This really shouldn't happen ... - close( fd ); - errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") data format not supported by RtAudio."; - errorText_ = errorStream_.str(); - return FAILURE; - } + if (stream_.deviceFormat[mode] == 0) + { + // This really shouldn't happen ... + close(fd); + errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") data format not supported by RtAudio."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Set the data format. - int temp = deviceFormat; - result = ioctl( fd, SNDCTL_DSP_SETFMT, &deviceFormat ); - if ( result == -1 || deviceFormat != temp ) { - close( fd ); - errorStream_ << "RtApiOss::probeDeviceOpen: error setting data format on device (" << ainfo.name << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Set the data format. + int temp = deviceFormat; + result = ioctl(fd, SNDCTL_DSP_SETFMT, &deviceFormat); + if (result == -1 || deviceFormat != temp) + { + close(fd); + errorStream_ << "RtApiOss::probeDeviceOpen: error setting data format on device (" << ainfo.name << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Attempt to set the buffer size. According to OSS, the minimum - // number of buffers is two. The supposed minimum buffer size is 16 - // bytes, so that will be our lower bound. The argument to this - // call is in the form 0xMMMMSSSS (hex), where the buffer size (in - // bytes) is given as 2^SSSS and the number of buffers as 2^MMMM. - // We'll check the actual value used near the end of the setup - // procedure. - int ossBufferBytes = *bufferSize * formatBytes( stream_.deviceFormat[mode] ) * deviceChannels; - if ( ossBufferBytes < 16 ) ossBufferBytes = 16; - int buffers = 0; - if ( options ) buffers = options->numberOfBuffers; - if ( options && options->flags & RTAUDIO_MINIMIZE_LATENCY ) buffers = 2; - if ( buffers < 2 ) buffers = 3; - temp = ((int) buffers << 16) + (int)( log10( (double)ossBufferBytes ) / log10( 2.0 ) ); - result = ioctl( fd, SNDCTL_DSP_SETFRAGMENT, &temp ); - if ( result == -1 ) { - close( fd ); - errorStream_ << "RtApiOss::probeDeviceOpen: error setting buffer size on device (" << ainfo.name << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } - stream_.nBuffers = buffers; + // Attempt to set the buffer size. According to OSS, the minimum + // number of buffers is two. The supposed minimum buffer size is 16 + // bytes, so that will be our lower bound. The argument to this + // call is in the form 0xMMMMSSSS (hex), where the buffer size (in + // bytes) is given as 2^SSSS and the number of buffers as 2^MMMM. + // We'll check the actual value used near the end of the setup + // procedure. + int ossBufferBytes = *bufferSize * formatBytes(stream_.deviceFormat[mode]) * deviceChannels; + if (ossBufferBytes < 16) ossBufferBytes = 16; + int buffers = 0; + if (options) buffers = options->numberOfBuffers; + if (options && options->flags & RTAUDIO_MINIMIZE_LATENCY) buffers = 2; + if (buffers < 2) buffers = 3; + temp = ((int)buffers << 16) + (int)(log10((double)ossBufferBytes) / log10(2.0)); + result = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &temp); + if (result == -1) + { + close(fd); + errorStream_ << "RtApiOss::probeDeviceOpen: error setting buffer size on device (" << ainfo.name << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } + stream_.nBuffers = buffers; - // Save buffer size (in sample frames). - *bufferSize = ossBufferBytes / ( formatBytes(stream_.deviceFormat[mode]) * deviceChannels ); - stream_.bufferSize = *bufferSize; + // Save buffer size (in sample frames). + *bufferSize = ossBufferBytes / (formatBytes(stream_.deviceFormat[mode]) * deviceChannels); + stream_.bufferSize = *bufferSize; - // Set the sample rate. - int srate = sampleRate; - result = ioctl( fd, SNDCTL_DSP_SPEED, &srate ); - if ( result == -1 ) { - close( fd ); - errorStream_ << "RtApiOss::probeDeviceOpen: error setting sample rate (" << sampleRate << ") on device (" << ainfo.name << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } + // Set the sample rate. + int srate = sampleRate; + result = ioctl(fd, SNDCTL_DSP_SPEED, &srate); + if (result == -1) + { + close(fd); + errorStream_ << "RtApiOss::probeDeviceOpen: error setting sample rate (" << sampleRate << ") on device (" << ainfo.name << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } - // Verify the sample rate setup worked. - if ( abs( srate - sampleRate ) > 100 ) { - close( fd ); - errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support sample rate (" << sampleRate << ")."; - errorText_ = errorStream_.str(); - return FAILURE; - } - stream_.sampleRate = sampleRate; + // Verify the sample rate setup worked. + if (abs(srate - sampleRate) > 100) + { + close(fd); + errorStream_ << "RtApiOss::probeDeviceOpen: device (" << ainfo.name << ") does not support sample rate (" << sampleRate << ")."; + errorText_ = errorStream_.str(); + return FAILURE; + } + stream_.sampleRate = sampleRate; - if ( mode == INPUT && stream_.mode == OUTPUT && stream_.device[0] == device) { - // We're doing duplex setup here. - stream_.deviceFormat[0] = stream_.deviceFormat[1]; - stream_.nDeviceChannels[0] = deviceChannels; - } + if (mode == INPUT && stream_.mode == OUTPUT && stream_.device[0] == device) + { + // We're doing duplex setup here. + stream_.deviceFormat[0] = stream_.deviceFormat[1]; + stream_.nDeviceChannels[0] = deviceChannels; + } - // Set interleaving parameters. - stream_.userInterleaved = true; - stream_.deviceInterleaved[mode] = true; - if ( options && options->flags & RTAUDIO_NONINTERLEAVED ) - stream_.userInterleaved = false; + // Set interleaving parameters. + stream_.userInterleaved = true; + stream_.deviceInterleaved[mode] = true; + if (options && options->flags & RTAUDIO_NONINTERLEAVED) + stream_.userInterleaved = false; - // Set flags for buffer conversion - stream_.doConvertBuffer[mode] = false; - if ( stream_.userFormat != stream_.deviceFormat[mode] ) - stream_.doConvertBuffer[mode] = true; - if ( stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode] ) - stream_.doConvertBuffer[mode] = true; - if ( stream_.userInterleaved != stream_.deviceInterleaved[mode] && - stream_.nUserChannels[mode] > 1 ) - stream_.doConvertBuffer[mode] = true; + // Set flags for buffer conversion + stream_.doConvertBuffer[mode] = false; + if (stream_.userFormat != stream_.deviceFormat[mode]) + stream_.doConvertBuffer[mode] = true; + if (stream_.nUserChannels[mode] < stream_.nDeviceChannels[mode]) + stream_.doConvertBuffer[mode] = true; + if (stream_.userInterleaved != stream_.deviceInterleaved[mode] && + stream_.nUserChannels[mode] > 1) + stream_.doConvertBuffer[mode] = true; - // Allocate the stream handles if necessary and then save. - if ( stream_.apiHandle == 0 ) { - try { - handle = new OssHandle; - } - catch ( std::bad_alloc& ) { - errorText_ = "RtApiOss::probeDeviceOpen: error allocating OssHandle memory."; - goto error; - } + // Allocate the stream handles if necessary and then save. + if (stream_.apiHandle == 0) + { + try + { + handle = new OssHandle; + } + catch (std::bad_alloc &) + { + errorText_ = "RtApiOss::probeDeviceOpen: error allocating OssHandle memory."; + goto error; + } - if ( pthread_cond_init( &handle->runnable, NULL ) ) { - errorText_ = "RtApiOss::probeDeviceOpen: error initializing pthread condition variable."; - goto error; - } + if (pthread_cond_init(&handle->runnable, NULL)) + { + errorText_ = "RtApiOss::probeDeviceOpen: error initializing pthread condition variable."; + goto error; + } - stream_.apiHandle = (void *) handle; - } - else { - handle = (OssHandle *) stream_.apiHandle; - } - handle->id[mode] = fd; + stream_.apiHandle = (void *)handle; + } + else + { + handle = (OssHandle *)stream_.apiHandle; + } + handle->id[mode] = fd; - // Allocate necessary internal buffers. - unsigned long bufferBytes; - bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes( stream_.userFormat ); - stream_.userBuffer[mode] = (char *) calloc( bufferBytes, 1 ); - if ( stream_.userBuffer[mode] == NULL ) { - errorText_ = "RtApiOss::probeDeviceOpen: error allocating user buffer memory."; - goto error; - } + // Allocate necessary internal buffers. + unsigned long bufferBytes; + bufferBytes = stream_.nUserChannels[mode] * *bufferSize * formatBytes(stream_.userFormat); + stream_.userBuffer[mode] = (char *)calloc(bufferBytes, 1); + if (stream_.userBuffer[mode] == NULL) + { + errorText_ = "RtApiOss::probeDeviceOpen: error allocating user buffer memory."; + goto error; + } - if ( stream_.doConvertBuffer[mode] ) { + if (stream_.doConvertBuffer[mode]) + { + bool makeBuffer = true; + bufferBytes = stream_.nDeviceChannels[mode] * formatBytes(stream_.deviceFormat[mode]); + if (mode == INPUT) + { + if (stream_.mode == OUTPUT && stream_.deviceBuffer) + { + unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes(stream_.deviceFormat[0]); + if (bufferBytes <= bytesOut) makeBuffer = false; + } + } - bool makeBuffer = true; - bufferBytes = stream_.nDeviceChannels[mode] * formatBytes( stream_.deviceFormat[mode] ); - if ( mode == INPUT ) { - if ( stream_.mode == OUTPUT && stream_.deviceBuffer ) { - unsigned long bytesOut = stream_.nDeviceChannels[0] * formatBytes( stream_.deviceFormat[0] ); - if ( bufferBytes <= bytesOut ) makeBuffer = false; - } - } + if (makeBuffer) + { + bufferBytes *= *bufferSize; + if (stream_.deviceBuffer) free(stream_.deviceBuffer); + stream_.deviceBuffer = (char *)calloc(bufferBytes, 1); + if (stream_.deviceBuffer == NULL) + { + errorText_ = "RtApiOss::probeDeviceOpen: error allocating device buffer memory."; + goto error; + } + } + } - if ( makeBuffer ) { - bufferBytes *= *bufferSize; - if ( stream_.deviceBuffer ) free( stream_.deviceBuffer ); - stream_.deviceBuffer = (char *) calloc( bufferBytes, 1 ); - if ( stream_.deviceBuffer == NULL ) { - errorText_ = "RtApiOss::probeDeviceOpen: error allocating device buffer memory."; - goto error; - } - } - } + stream_.device[mode] = device; + stream_.state = STREAM_STOPPED; - stream_.device[mode] = device; - stream_.state = STREAM_STOPPED; + // Setup the buffer conversion information structure. + if (stream_.doConvertBuffer[mode]) setConvertInfo(mode, firstChannel); - // Setup the buffer conversion information structure. - if ( stream_.doConvertBuffer[mode] ) setConvertInfo( mode, firstChannel ); + // Setup thread if necessary. + if (stream_.mode == OUTPUT && mode == INPUT) + { + // We had already set up an output stream. + stream_.mode = DUPLEX; + if (stream_.device[0] == device) handle->id[0] = fd; + } + else + { + stream_.mode = mode; - // Setup thread if necessary. - if ( stream_.mode == OUTPUT && mode == INPUT ) { - // We had already set up an output stream. - stream_.mode = DUPLEX; - if ( stream_.device[0] == device ) handle->id[0] = fd; - } - else { - stream_.mode = mode; + // Setup callback thread. + stream_.callbackInfo.object = (void *)this; - // Setup callback thread. - stream_.callbackInfo.object = (void *) this; - - // Set the thread attributes for joinable and realtime scheduling - // priority. The higher priority will only take affect if the - // program is run as root or suid. - pthread_attr_t attr; - pthread_attr_init( &attr ); - pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE ); -#ifdef SCHED_RR // Undefined with some OSes (eg: NetBSD 1.6.x with GNU Pthread) - if ( options && options->flags & RTAUDIO_SCHEDULE_REALTIME ) { - struct sched_param param; - int priority = options->priority; - int min = sched_get_priority_min( SCHED_RR ); - int max = sched_get_priority_max( SCHED_RR ); - if ( priority < min ) priority = min; - else if ( priority > max ) priority = max; - param.sched_priority = priority; - pthread_attr_setschedparam( &attr, ¶m ); - pthread_attr_setschedpolicy( &attr, SCHED_RR ); - } - else - pthread_attr_setschedpolicy( &attr, SCHED_OTHER ); + // Set the thread attributes for joinable and realtime scheduling + // priority. The higher priority will only take affect if the + // program is run as root or suid. + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); +#ifdef SCHED_RR // Undefined with some OSes (eg: NetBSD 1.6.x with GNU Pthread) + if (options && options->flags & RTAUDIO_SCHEDULE_REALTIME) + { + struct sched_param param; + int priority = options->priority; + int min = sched_get_priority_min(SCHED_RR); + int max = sched_get_priority_max(SCHED_RR); + if (priority < min) + priority = min; + else if (priority > max) + priority = max; + param.sched_priority = priority; + pthread_attr_setschedparam(&attr, ¶m); + pthread_attr_setschedpolicy(&attr, SCHED_RR); + } + else + pthread_attr_setschedpolicy(&attr, SCHED_OTHER); #else - pthread_attr_setschedpolicy( &attr, SCHED_OTHER ); + pthread_attr_setschedpolicy(&attr, SCHED_OTHER); #endif - stream_.callbackInfo.isRunning = true; - result = pthread_create( &stream_.callbackInfo.thread, &attr, ossCallbackHandler, &stream_.callbackInfo ); - pthread_attr_destroy( &attr ); - if ( result ) { - stream_.callbackInfo.isRunning = false; - errorText_ = "RtApiOss::error creating callback thread!"; - goto error; - } - } + stream_.callbackInfo.isRunning = true; + result = pthread_create(&stream_.callbackInfo.thread, &attr, ossCallbackHandler, &stream_.callbackInfo); + pthread_attr_destroy(&attr); + if (result) + { + stream_.callbackInfo.isRunning = false; + errorText_ = "RtApiOss::error creating callback thread!"; + goto error; + } + } - return SUCCESS; + return SUCCESS; - error: - if ( handle ) { - pthread_cond_destroy( &handle->runnable ); - if ( handle->id[0] ) close( handle->id[0] ); - if ( handle->id[1] ) close( handle->id[1] ); - delete handle; - stream_.apiHandle = 0; - } +error: + if (handle) + { + pthread_cond_destroy(&handle->runnable); + if (handle->id[0]) close(handle->id[0]); + if (handle->id[1]) close(handle->id[1]); + delete handle; + stream_.apiHandle = 0; + } - for ( int i=0; i<2; i++ ) { - if ( stream_.userBuffer[i] ) { - free( stream_.userBuffer[i] ); - stream_.userBuffer[i] = 0; - } - } + for (int i = 0; i < 2; i++) + { + if (stream_.userBuffer[i]) + { + free(stream_.userBuffer[i]); + stream_.userBuffer[i] = 0; + } + } - if ( stream_.deviceBuffer ) { - free( stream_.deviceBuffer ); - stream_.deviceBuffer = 0; - } + if (stream_.deviceBuffer) + { + free(stream_.deviceBuffer); + stream_.deviceBuffer = 0; + } - return FAILURE; + return FAILURE; } -void RtApiOss :: closeStream() +void RtApiOss ::closeStream() { - if ( stream_.state == STREAM_CLOSED ) { - errorText_ = "RtApiOss::closeStream(): no open stream to close!"; - error( RtAudioError::WARNING ); - return; - } + if (stream_.state == STREAM_CLOSED) + { + errorText_ = "RtApiOss::closeStream(): no open stream to close!"; + error(RtAudioError::WARNING); + return; + } - OssHandle *handle = (OssHandle *) stream_.apiHandle; - stream_.callbackInfo.isRunning = false; - MUTEX_LOCK( &stream_.mutex ); - if ( stream_.state == STREAM_STOPPED ) - pthread_cond_signal( &handle->runnable ); - MUTEX_UNLOCK( &stream_.mutex ); - pthread_join( stream_.callbackInfo.thread, NULL ); + OssHandle *handle = (OssHandle *)stream_.apiHandle; + stream_.callbackInfo.isRunning = false; + MUTEX_LOCK(&stream_.mutex); + if (stream_.state == STREAM_STOPPED) + pthread_cond_signal(&handle->runnable); + MUTEX_UNLOCK(&stream_.mutex); + pthread_join(stream_.callbackInfo.thread, NULL); - if ( stream_.state == STREAM_RUNNING ) { - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) - ioctl( handle->id[0], SNDCTL_DSP_HALT, 0 ); - else - ioctl( handle->id[1], SNDCTL_DSP_HALT, 0 ); - stream_.state = STREAM_STOPPED; - } + if (stream_.state == STREAM_RUNNING) + { + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + ioctl(handle->id[0], SNDCTL_DSP_HALT, 0); + else + ioctl(handle->id[1], SNDCTL_DSP_HALT, 0); + stream_.state = STREAM_STOPPED; + } - if ( handle ) { - pthread_cond_destroy( &handle->runnable ); - if ( handle->id[0] ) close( handle->id[0] ); - if ( handle->id[1] ) close( handle->id[1] ); - delete handle; - stream_.apiHandle = 0; - } + if (handle) + { + pthread_cond_destroy(&handle->runnable); + if (handle->id[0]) close(handle->id[0]); + if (handle->id[1]) close(handle->id[1]); + delete handle; + stream_.apiHandle = 0; + } - for ( int i=0; i<2; i++ ) { - if ( stream_.userBuffer[i] ) { - free( stream_.userBuffer[i] ); - stream_.userBuffer[i] = 0; - } - } + for (int i = 0; i < 2; i++) + { + if (stream_.userBuffer[i]) + { + free(stream_.userBuffer[i]); + stream_.userBuffer[i] = 0; + } + } - if ( stream_.deviceBuffer ) { - free( stream_.deviceBuffer ); - stream_.deviceBuffer = 0; - } + if (stream_.deviceBuffer) + { + free(stream_.deviceBuffer); + stream_.deviceBuffer = 0; + } - stream_.mode = UNINITIALIZED; - stream_.state = STREAM_CLOSED; + stream_.mode = UNINITIALIZED; + stream_.state = STREAM_CLOSED; } -void RtApiOss :: startStream() +void RtApiOss ::startStream() { - verifyStream(); - if ( stream_.state == STREAM_RUNNING ) { - errorText_ = "RtApiOss::startStream(): the stream is already running!"; - error( RtAudioError::WARNING ); - return; - } + verifyStream(); + if (stream_.state == STREAM_RUNNING) + { + errorText_ = "RtApiOss::startStream(): the stream is already running!"; + error(RtAudioError::WARNING); + return; + } - MUTEX_LOCK( &stream_.mutex ); + MUTEX_LOCK(&stream_.mutex); - stream_.state = STREAM_RUNNING; + stream_.state = STREAM_RUNNING; - // No need to do anything else here ... OSS automatically starts - // when fed samples. + // No need to do anything else here ... OSS automatically starts + // when fed samples. - MUTEX_UNLOCK( &stream_.mutex ); + MUTEX_UNLOCK(&stream_.mutex); - OssHandle *handle = (OssHandle *) stream_.apiHandle; - pthread_cond_signal( &handle->runnable ); + OssHandle *handle = (OssHandle *)stream_.apiHandle; + pthread_cond_signal(&handle->runnable); } -void RtApiOss :: stopStream() +void RtApiOss ::stopStream() { - verifyStream(); - if ( stream_.state == STREAM_STOPPED ) { - errorText_ = "RtApiOss::stopStream(): the stream is already stopped!"; - error( RtAudioError::WARNING ); - return; - } + verifyStream(); + if (stream_.state == STREAM_STOPPED) + { + errorText_ = "RtApiOss::stopStream(): the stream is already stopped!"; + error(RtAudioError::WARNING); + return; + } - MUTEX_LOCK( &stream_.mutex ); + MUTEX_LOCK(&stream_.mutex); - // The state might change while waiting on a mutex. - if ( stream_.state == STREAM_STOPPED ) { - MUTEX_UNLOCK( &stream_.mutex ); - return; - } + // The state might change while waiting on a mutex. + if (stream_.state == STREAM_STOPPED) + { + MUTEX_UNLOCK(&stream_.mutex); + return; + } - int result = 0; - OssHandle *handle = (OssHandle *) stream_.apiHandle; - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { + int result = 0; + OssHandle *handle = (OssHandle *)stream_.apiHandle; + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + { + // Flush the output with zeros a few times. + char *buffer; + int samples; + RtAudioFormat format; - // Flush the output with zeros a few times. - char *buffer; - int samples; - RtAudioFormat format; + if (stream_.doConvertBuffer[0]) + { + buffer = stream_.deviceBuffer; + samples = stream_.bufferSize * stream_.nDeviceChannels[0]; + format = stream_.deviceFormat[0]; + } + else + { + buffer = stream_.userBuffer[0]; + samples = stream_.bufferSize * stream_.nUserChannels[0]; + format = stream_.userFormat; + } - if ( stream_.doConvertBuffer[0] ) { - buffer = stream_.deviceBuffer; - samples = stream_.bufferSize * stream_.nDeviceChannels[0]; - format = stream_.deviceFormat[0]; - } - else { - buffer = stream_.userBuffer[0]; - samples = stream_.bufferSize * stream_.nUserChannels[0]; - format = stream_.userFormat; - } + memset(buffer, 0, samples * formatBytes(format)); + for (unsigned int i = 0; i < stream_.nBuffers + 1; i++) + { + result = write(handle->id[0], buffer, samples * formatBytes(format)); + if (result == -1) + { + errorText_ = "RtApiOss::stopStream: audio write error."; + error(RtAudioError::WARNING); + } + } - memset( buffer, 0, samples * formatBytes(format) ); - for ( unsigned int i=0; iid[0], buffer, samples * formatBytes(format) ); - if ( result == -1 ) { - errorText_ = "RtApiOss::stopStream: audio write error."; - error( RtAudioError::WARNING ); - } - } + result = ioctl(handle->id[0], SNDCTL_DSP_HALT, 0); + if (result == -1) + { + errorStream_ << "RtApiOss::stopStream: system error stopping callback procedure on device (" << stream_.device[0] << ")."; + errorText_ = errorStream_.str(); + goto unlock; + } + handle->triggered = false; + } - result = ioctl( handle->id[0], SNDCTL_DSP_HALT, 0 ); - if ( result == -1 ) { - errorStream_ << "RtApiOss::stopStream: system error stopping callback procedure on device (" << stream_.device[0] << ")."; - errorText_ = errorStream_.str(); - goto unlock; - } - handle->triggered = false; - } + if (stream_.mode == INPUT || (stream_.mode == DUPLEX && handle->id[0] != handle->id[1])) + { + result = ioctl(handle->id[1], SNDCTL_DSP_HALT, 0); + if (result == -1) + { + errorStream_ << "RtApiOss::stopStream: system error stopping input callback procedure on device (" << stream_.device[0] << ")."; + errorText_ = errorStream_.str(); + goto unlock; + } + } - if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && handle->id[0] != handle->id[1] ) ) { - result = ioctl( handle->id[1], SNDCTL_DSP_HALT, 0 ); - if ( result == -1 ) { - errorStream_ << "RtApiOss::stopStream: system error stopping input callback procedure on device (" << stream_.device[0] << ")."; - errorText_ = errorStream_.str(); - goto unlock; - } - } +unlock: + stream_.state = STREAM_STOPPED; + MUTEX_UNLOCK(&stream_.mutex); - unlock: - stream_.state = STREAM_STOPPED; - MUTEX_UNLOCK( &stream_.mutex ); - - if ( result != -1 ) return; - error( RtAudioError::SYSTEM_ERROR ); + if (result != -1) return; + error(RtAudioError::SYSTEM_ERROR); } -void RtApiOss :: abortStream() +void RtApiOss ::abortStream() { - verifyStream(); - if ( stream_.state == STREAM_STOPPED ) { - errorText_ = "RtApiOss::abortStream(): the stream is already stopped!"; - error( RtAudioError::WARNING ); - return; - } + verifyStream(); + if (stream_.state == STREAM_STOPPED) + { + errorText_ = "RtApiOss::abortStream(): the stream is already stopped!"; + error(RtAudioError::WARNING); + return; + } - MUTEX_LOCK( &stream_.mutex ); + MUTEX_LOCK(&stream_.mutex); - // The state might change while waiting on a mutex. - if ( stream_.state == STREAM_STOPPED ) { - MUTEX_UNLOCK( &stream_.mutex ); - return; - } + // The state might change while waiting on a mutex. + if (stream_.state == STREAM_STOPPED) + { + MUTEX_UNLOCK(&stream_.mutex); + return; + } - int result = 0; - OssHandle *handle = (OssHandle *) stream_.apiHandle; - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { - result = ioctl( handle->id[0], SNDCTL_DSP_HALT, 0 ); - if ( result == -1 ) { - errorStream_ << "RtApiOss::abortStream: system error stopping callback procedure on device (" << stream_.device[0] << ")."; - errorText_ = errorStream_.str(); - goto unlock; - } - handle->triggered = false; - } + int result = 0; + OssHandle *handle = (OssHandle *)stream_.apiHandle; + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + { + result = ioctl(handle->id[0], SNDCTL_DSP_HALT, 0); + if (result == -1) + { + errorStream_ << "RtApiOss::abortStream: system error stopping callback procedure on device (" << stream_.device[0] << ")."; + errorText_ = errorStream_.str(); + goto unlock; + } + handle->triggered = false; + } - if ( stream_.mode == INPUT || ( stream_.mode == DUPLEX && handle->id[0] != handle->id[1] ) ) { - result = ioctl( handle->id[1], SNDCTL_DSP_HALT, 0 ); - if ( result == -1 ) { - errorStream_ << "RtApiOss::abortStream: system error stopping input callback procedure on device (" << stream_.device[0] << ")."; - errorText_ = errorStream_.str(); - goto unlock; - } - } + if (stream_.mode == INPUT || (stream_.mode == DUPLEX && handle->id[0] != handle->id[1])) + { + result = ioctl(handle->id[1], SNDCTL_DSP_HALT, 0); + if (result == -1) + { + errorStream_ << "RtApiOss::abortStream: system error stopping input callback procedure on device (" << stream_.device[0] << ")."; + errorText_ = errorStream_.str(); + goto unlock; + } + } - unlock: - stream_.state = STREAM_STOPPED; - MUTEX_UNLOCK( &stream_.mutex ); +unlock: + stream_.state = STREAM_STOPPED; + MUTEX_UNLOCK(&stream_.mutex); - if ( result != -1 ) return; - error( RtAudioError::SYSTEM_ERROR ); + if (result != -1) return; + error(RtAudioError::SYSTEM_ERROR); } -void RtApiOss :: callbackEvent() +void RtApiOss ::callbackEvent() { - OssHandle *handle = (OssHandle *) stream_.apiHandle; - if ( stream_.state == STREAM_STOPPED ) { - MUTEX_LOCK( &stream_.mutex ); - pthread_cond_wait( &handle->runnable, &stream_.mutex ); - if ( stream_.state != STREAM_RUNNING ) { - MUTEX_UNLOCK( &stream_.mutex ); - return; - } - MUTEX_UNLOCK( &stream_.mutex ); - } + OssHandle *handle = (OssHandle *)stream_.apiHandle; + if (stream_.state == STREAM_STOPPED) + { + MUTEX_LOCK(&stream_.mutex); + pthread_cond_wait(&handle->runnable, &stream_.mutex); + if (stream_.state != STREAM_RUNNING) + { + MUTEX_UNLOCK(&stream_.mutex); + return; + } + MUTEX_UNLOCK(&stream_.mutex); + } - if ( stream_.state == STREAM_CLOSED ) { - errorText_ = "RtApiOss::callbackEvent(): the stream is closed ... this shouldn't happen!"; - error( RtAudioError::WARNING ); - return; - } + if (stream_.state == STREAM_CLOSED) + { + errorText_ = "RtApiOss::callbackEvent(): the stream is closed ... this shouldn't happen!"; + error(RtAudioError::WARNING); + return; + } - // Invoke user callback to get fresh output data. - int doStopStream = 0; - RtAudioCallback callback = (RtAudioCallback) stream_.callbackInfo.callback; - double streamTime = getStreamTime(); - RtAudioStreamStatus status = 0; - if ( stream_.mode != INPUT && handle->xrun[0] == true ) { - status |= RTAUDIO_OUTPUT_UNDERFLOW; - handle->xrun[0] = false; - } - if ( stream_.mode != OUTPUT && handle->xrun[1] == true ) { - status |= RTAUDIO_INPUT_OVERFLOW; - handle->xrun[1] = false; - } - doStopStream = callback( stream_.userBuffer[0], stream_.userBuffer[1], - stream_.bufferSize, streamTime, status, stream_.callbackInfo.userData ); - if ( doStopStream == 2 ) { - this->abortStream(); - return; - } + // Invoke user callback to get fresh output data. + int doStopStream = 0; + RtAudioCallback callback = (RtAudioCallback)stream_.callbackInfo.callback; + double streamTime = getStreamTime(); + RtAudioStreamStatus status = 0; + if (stream_.mode != INPUT && handle->xrun[0] == true) + { + status |= RTAUDIO_OUTPUT_UNDERFLOW; + handle->xrun[0] = false; + } + if (stream_.mode != OUTPUT && handle->xrun[1] == true) + { + status |= RTAUDIO_INPUT_OVERFLOW; + handle->xrun[1] = false; + } + doStopStream = callback(stream_.userBuffer[0], stream_.userBuffer[1], + stream_.bufferSize, streamTime, status, stream_.callbackInfo.userData); + if (doStopStream == 2) + { + this->abortStream(); + return; + } - MUTEX_LOCK( &stream_.mutex ); + MUTEX_LOCK(&stream_.mutex); - // The state might change while waiting on a mutex. - if ( stream_.state == STREAM_STOPPED ) goto unlock; + // The state might change while waiting on a mutex. + if (stream_.state == STREAM_STOPPED) goto unlock; - int result; - char *buffer; - int samples; - RtAudioFormat format; + int result; + char *buffer; + int samples; + RtAudioFormat format; - if ( stream_.mode == OUTPUT || stream_.mode == DUPLEX ) { + if (stream_.mode == OUTPUT || stream_.mode == DUPLEX) + { + // Setup parameters and do buffer conversion if necessary. + if (stream_.doConvertBuffer[0]) + { + buffer = stream_.deviceBuffer; + convertBuffer(buffer, stream_.userBuffer[0], stream_.convertInfo[0]); + samples = stream_.bufferSize * stream_.nDeviceChannels[0]; + format = stream_.deviceFormat[0]; + } + else + { + buffer = stream_.userBuffer[0]; + samples = stream_.bufferSize * stream_.nUserChannels[0]; + format = stream_.userFormat; + } - // Setup parameters and do buffer conversion if necessary. - if ( stream_.doConvertBuffer[0] ) { - buffer = stream_.deviceBuffer; - convertBuffer( buffer, stream_.userBuffer[0], stream_.convertInfo[0] ); - samples = stream_.bufferSize * stream_.nDeviceChannels[0]; - format = stream_.deviceFormat[0]; - } - else { - buffer = stream_.userBuffer[0]; - samples = stream_.bufferSize * stream_.nUserChannels[0]; - format = stream_.userFormat; - } + // Do byte swapping if necessary. + if (stream_.doByteSwap[0]) + byteSwapBuffer(buffer, samples, format); - // Do byte swapping if necessary. - if ( stream_.doByteSwap[0] ) - byteSwapBuffer( buffer, samples, format ); + if (stream_.mode == DUPLEX && handle->triggered == false) + { + int trig = 0; + ioctl(handle->id[0], SNDCTL_DSP_SETTRIGGER, &trig); + result = write(handle->id[0], buffer, samples * formatBytes(format)); + trig = PCM_ENABLE_INPUT | PCM_ENABLE_OUTPUT; + ioctl(handle->id[0], SNDCTL_DSP_SETTRIGGER, &trig); + handle->triggered = true; + } + else + // Write samples to device. + result = write(handle->id[0], buffer, samples * formatBytes(format)); - if ( stream_.mode == DUPLEX && handle->triggered == false ) { - int trig = 0; - ioctl( handle->id[0], SNDCTL_DSP_SETTRIGGER, &trig ); - result = write( handle->id[0], buffer, samples * formatBytes(format) ); - trig = PCM_ENABLE_INPUT|PCM_ENABLE_OUTPUT; - ioctl( handle->id[0], SNDCTL_DSP_SETTRIGGER, &trig ); - handle->triggered = true; - } - else - // Write samples to device. - result = write( handle->id[0], buffer, samples * formatBytes(format) ); + if (result == -1) + { + // We'll assume this is an underrun, though there isn't a + // specific means for determining that. + handle->xrun[0] = true; + errorText_ = "RtApiOss::callbackEvent: audio write error."; + error(RtAudioError::WARNING); + // Continue on to input section. + } + } - if ( result == -1 ) { - // We'll assume this is an underrun, though there isn't a - // specific means for determining that. - handle->xrun[0] = true; - errorText_ = "RtApiOss::callbackEvent: audio write error."; - error( RtAudioError::WARNING ); - // Continue on to input section. - } - } + if (stream_.mode == INPUT || stream_.mode == DUPLEX) + { + // Setup parameters. + if (stream_.doConvertBuffer[1]) + { + buffer = stream_.deviceBuffer; + samples = stream_.bufferSize * stream_.nDeviceChannels[1]; + format = stream_.deviceFormat[1]; + } + else + { + buffer = stream_.userBuffer[1]; + samples = stream_.bufferSize * stream_.nUserChannels[1]; + format = stream_.userFormat; + } - if ( stream_.mode == INPUT || stream_.mode == DUPLEX ) { + // Read samples from device. + result = read(handle->id[1], buffer, samples * formatBytes(format)); - // Setup parameters. - if ( stream_.doConvertBuffer[1] ) { - buffer = stream_.deviceBuffer; - samples = stream_.bufferSize * stream_.nDeviceChannels[1]; - format = stream_.deviceFormat[1]; - } - else { - buffer = stream_.userBuffer[1]; - samples = stream_.bufferSize * stream_.nUserChannels[1]; - format = stream_.userFormat; - } + if (result == -1) + { + // We'll assume this is an overrun, though there isn't a + // specific means for determining that. + handle->xrun[1] = true; + errorText_ = "RtApiOss::callbackEvent: audio read error."; + error(RtAudioError::WARNING); + goto unlock; + } - // Read samples from device. - result = read( handle->id[1], buffer, samples * formatBytes(format) ); + // Do byte swapping if necessary. + if (stream_.doByteSwap[1]) + byteSwapBuffer(buffer, samples, format); - if ( result == -1 ) { - // We'll assume this is an overrun, though there isn't a - // specific means for determining that. - handle->xrun[1] = true; - errorText_ = "RtApiOss::callbackEvent: audio read error."; - error( RtAudioError::WARNING ); - goto unlock; - } + // Do buffer conversion if necessary. + if (stream_.doConvertBuffer[1]) + convertBuffer(stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1]); + } - // Do byte swapping if necessary. - if ( stream_.doByteSwap[1] ) - byteSwapBuffer( buffer, samples, format ); +unlock: + MUTEX_UNLOCK(&stream_.mutex); - // Do buffer conversion if necessary. - if ( stream_.doConvertBuffer[1] ) - convertBuffer( stream_.userBuffer[1], stream_.deviceBuffer, stream_.convertInfo[1] ); - } - - unlock: - MUTEX_UNLOCK( &stream_.mutex ); - - RtApi::tickStreamTime(); - if ( doStopStream == 1 ) this->stopStream(); + RtApi::tickStreamTime(); + if (doStopStream == 1) this->stopStream(); } -static void *ossCallbackHandler( void *ptr ) +static void *ossCallbackHandler(void *ptr) { - CallbackInfo *info = (CallbackInfo *) ptr; - RtApiOss *object = (RtApiOss *) info->object; - bool *isRunning = &info->isRunning; + CallbackInfo *info = (CallbackInfo *)ptr; + RtApiOss *object = (RtApiOss *)info->object; + bool *isRunning = &info->isRunning; - while ( *isRunning == true ) { - pthread_testcancel(); - object->callbackEvent(); - } + while (*isRunning == true) + { + pthread_testcancel(); + object->callbackEvent(); + } - pthread_exit( NULL ); + pthread_exit(NULL); } //******************** End of __LINUX_OSS__ *********************// #endif - // *************************************************** // // // Protected common (OS-independent) RtAudio methods. @@ -9530,699 +10503,845 @@ static void *ossCallbackHandler( void *ptr ) // This method can be modified to control the behavior of error // message printing. -void RtApi :: error( RtAudioError::Type type ) +void RtApi ::error(RtAudioError::Type type) { - errorStream_.str(""); // clear the ostringstream + errorStream_.str(""); // clear the ostringstream - RtAudioErrorCallback errorCallback = (RtAudioErrorCallback) stream_.callbackInfo.errorCallback; - if ( errorCallback ) { - // abortStream() can generate new error messages. Ignore them. Just keep original one. + RtAudioErrorCallback errorCallback = (RtAudioErrorCallback)stream_.callbackInfo.errorCallback; + if (errorCallback) + { + // abortStream() can generate new error messages. Ignore them. Just keep original one. - if ( firstErrorOccurred_ ) - return; + if (firstErrorOccurred_) + return; - firstErrorOccurred_ = true; - const std::string errorMessage = errorText_; + firstErrorOccurred_ = true; + const std::string errorMessage = errorText_; - if ( type != RtAudioError::WARNING && stream_.state != STREAM_STOPPED) { - stream_.callbackInfo.isRunning = false; // exit from the thread - abortStream(); - } + if (type != RtAudioError::WARNING && stream_.state != STREAM_STOPPED) + { + stream_.callbackInfo.isRunning = false; // exit from the thread + abortStream(); + } - errorCallback( type, errorMessage ); - firstErrorOccurred_ = false; - return; - } + errorCallback(type, errorMessage); + firstErrorOccurred_ = false; + return; + } - if ( type == RtAudioError::WARNING && showWarnings_ == true ) - std::cerr << '\n' << errorText_ << "\n\n"; - else if ( type != RtAudioError::WARNING ) - throw( RtAudioError( errorText_, type ) ); + if (type == RtAudioError::WARNING && showWarnings_ == true) + std::cerr << '\n' + << errorText_ << "\n\n"; + else if (type != RtAudioError::WARNING) + throw(RtAudioError(errorText_, type)); } -void RtApi :: verifyStream() +void RtApi ::verifyStream() { - if ( stream_.state == STREAM_CLOSED ) { - errorText_ = "RtApi:: a stream is not open!"; - error( RtAudioError::INVALID_USE ); - } + if (stream_.state == STREAM_CLOSED) + { + errorText_ = "RtApi:: a stream is not open!"; + error(RtAudioError::INVALID_USE); + } } -void RtApi :: clearStreamInfo() +void RtApi ::clearStreamInfo() { - stream_.mode = UNINITIALIZED; - stream_.state = STREAM_CLOSED; - stream_.sampleRate = 0; - stream_.bufferSize = 0; - stream_.nBuffers = 0; - stream_.userFormat = 0; - stream_.userInterleaved = true; - stream_.streamTime = 0.0; - stream_.apiHandle = 0; - stream_.deviceBuffer = 0; - stream_.callbackInfo.callback = 0; - stream_.callbackInfo.userData = 0; - stream_.callbackInfo.isRunning = false; - stream_.callbackInfo.errorCallback = 0; - for ( int i=0; i<2; i++ ) { - stream_.device[i] = 11111; - stream_.doConvertBuffer[i] = false; - stream_.deviceInterleaved[i] = true; - stream_.doByteSwap[i] = false; - stream_.nUserChannels[i] = 0; - stream_.nDeviceChannels[i] = 0; - stream_.channelOffset[i] = 0; - stream_.deviceFormat[i] = 0; - stream_.latency[i] = 0; - stream_.userBuffer[i] = 0; - stream_.convertInfo[i].channels = 0; - stream_.convertInfo[i].inJump = 0; - stream_.convertInfo[i].outJump = 0; - stream_.convertInfo[i].inFormat = 0; - stream_.convertInfo[i].outFormat = 0; - stream_.convertInfo[i].inOffset.clear(); - stream_.convertInfo[i].outOffset.clear(); - } + stream_.mode = UNINITIALIZED; + stream_.state = STREAM_CLOSED; + stream_.sampleRate = 0; + stream_.bufferSize = 0; + stream_.nBuffers = 0; + stream_.userFormat = 0; + stream_.userInterleaved = true; + stream_.streamTime = 0.0; + stream_.apiHandle = 0; + stream_.deviceBuffer = 0; + stream_.callbackInfo.callback = 0; + stream_.callbackInfo.userData = 0; + stream_.callbackInfo.isRunning = false; + stream_.callbackInfo.errorCallback = 0; + for (int i = 0; i < 2; i++) + { + stream_.device[i] = 11111; + stream_.doConvertBuffer[i] = false; + stream_.deviceInterleaved[i] = true; + stream_.doByteSwap[i] = false; + stream_.nUserChannels[i] = 0; + stream_.nDeviceChannels[i] = 0; + stream_.channelOffset[i] = 0; + stream_.deviceFormat[i] = 0; + stream_.latency[i] = 0; + stream_.userBuffer[i] = 0; + stream_.convertInfo[i].channels = 0; + stream_.convertInfo[i].inJump = 0; + stream_.convertInfo[i].outJump = 0; + stream_.convertInfo[i].inFormat = 0; + stream_.convertInfo[i].outFormat = 0; + stream_.convertInfo[i].inOffset.clear(); + stream_.convertInfo[i].outOffset.clear(); + } } -unsigned int RtApi :: formatBytes( RtAudioFormat format ) +unsigned int RtApi ::formatBytes(RtAudioFormat format) { - if ( format == RTAUDIO_SINT16 ) - return 2; - else if ( format == RTAUDIO_SINT32 || format == RTAUDIO_FLOAT32 ) - return 4; - else if ( format == RTAUDIO_FLOAT64 ) - return 8; - else if ( format == RTAUDIO_SINT24 ) - return 3; - else if ( format == RTAUDIO_SINT8 ) - return 1; + if (format == RTAUDIO_SINT16) + return 2; + else if (format == RTAUDIO_SINT32 || format == RTAUDIO_FLOAT32) + return 4; + else if (format == RTAUDIO_FLOAT64) + return 8; + else if (format == RTAUDIO_SINT24) + return 3; + else if (format == RTAUDIO_SINT8) + return 1; - errorText_ = "RtApi::formatBytes: undefined format."; - error( RtAudioError::WARNING ); + errorText_ = "RtApi::formatBytes: undefined format."; + error(RtAudioError::WARNING); - return 0; + return 0; } -void RtApi :: setConvertInfo( StreamMode mode, unsigned int firstChannel ) +void RtApi ::setConvertInfo(StreamMode mode, unsigned int firstChannel) { - if ( mode == INPUT ) { // convert device to user buffer - stream_.convertInfo[mode].inJump = stream_.nDeviceChannels[1]; - stream_.convertInfo[mode].outJump = stream_.nUserChannels[1]; - stream_.convertInfo[mode].inFormat = stream_.deviceFormat[1]; - stream_.convertInfo[mode].outFormat = stream_.userFormat; - } - else { // convert user to device buffer - stream_.convertInfo[mode].inJump = stream_.nUserChannels[0]; - stream_.convertInfo[mode].outJump = stream_.nDeviceChannels[0]; - stream_.convertInfo[mode].inFormat = stream_.userFormat; - stream_.convertInfo[mode].outFormat = stream_.deviceFormat[0]; - } + if (mode == INPUT) + { // convert device to user buffer + stream_.convertInfo[mode].inJump = stream_.nDeviceChannels[1]; + stream_.convertInfo[mode].outJump = stream_.nUserChannels[1]; + stream_.convertInfo[mode].inFormat = stream_.deviceFormat[1]; + stream_.convertInfo[mode].outFormat = stream_.userFormat; + } + else + { // convert user to device buffer + stream_.convertInfo[mode].inJump = stream_.nUserChannels[0]; + stream_.convertInfo[mode].outJump = stream_.nDeviceChannels[0]; + stream_.convertInfo[mode].inFormat = stream_.userFormat; + stream_.convertInfo[mode].outFormat = stream_.deviceFormat[0]; + } - if ( stream_.convertInfo[mode].inJump < stream_.convertInfo[mode].outJump ) - stream_.convertInfo[mode].channels = stream_.convertInfo[mode].inJump; - else - stream_.convertInfo[mode].channels = stream_.convertInfo[mode].outJump; + if (stream_.convertInfo[mode].inJump < stream_.convertInfo[mode].outJump) + stream_.convertInfo[mode].channels = stream_.convertInfo[mode].inJump; + else + stream_.convertInfo[mode].channels = stream_.convertInfo[mode].outJump; - // Set up the interleave/deinterleave offsets. - if ( stream_.deviceInterleaved[mode] != stream_.userInterleaved ) { - if ( ( mode == OUTPUT && stream_.deviceInterleaved[mode] ) || - ( mode == INPUT && stream_.userInterleaved ) ) { - for ( int k=0; k 0 ) { - if ( stream_.deviceInterleaved[mode] ) { - if ( mode == OUTPUT ) { - for ( int k=0; k 0) + { + if (stream_.deviceInterleaved[mode]) + { + if (mode == OUTPUT) + { + for (int k = 0; k < stream_.convertInfo[mode].channels; k++) + stream_.convertInfo[mode].outOffset[k] += firstChannel; + } + else + { + for (int k = 0; k < stream_.convertInfo[mode].channels; k++) + stream_.convertInfo[mode].inOffset[k] += firstChannel; + } + } + else + { + if (mode == OUTPUT) + { + for (int k = 0; k < stream_.convertInfo[mode].channels; k++) + stream_.convertInfo[mode].outOffset[k] += (firstChannel * stream_.bufferSize); + } + else + { + for (int k = 0; k < stream_.convertInfo[mode].channels; k++) + stream_.convertInfo[mode].inOffset[k] += (firstChannel * stream_.bufferSize); + } + } + } } -void RtApi :: convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info ) +void RtApi ::convertBuffer(char *outBuffer, char *inBuffer, ConvertInfo &info) { - // This function does format conversion, input/output channel compensation, and - // data interleaving/deinterleaving. 24-bit integers are assumed to occupy - // the lower three bytes of a 32-bit integer. + // This function does format conversion, input/output channel compensation, and + // data interleaving/deinterleaving. 24-bit integers are assumed to occupy + // the lower three bytes of a 32-bit integer. - // Clear our device buffer when in/out duplex device channels are different - if ( outBuffer == stream_.deviceBuffer && stream_.mode == DUPLEX && - ( stream_.nDeviceChannels[0] < stream_.nDeviceChannels[1] ) ) - memset( outBuffer, 0, stream_.bufferSize * info.outJump * formatBytes( info.outFormat ) ); + // Clear our device buffer when in/out duplex device channels are different + if (outBuffer == stream_.deviceBuffer && stream_.mode == DUPLEX && + (stream_.nDeviceChannels[0] < stream_.nDeviceChannels[1])) + memset(outBuffer, 0, stream_.bufferSize * info.outJump * formatBytes(info.outFormat)); - int j; - if (info.outFormat == RTAUDIO_FLOAT64) { - Float64 scale; - Float64 *out = (Float64 *)outBuffer; + int j; + if (info.outFormat == RTAUDIO_FLOAT64) + { + Float64 scale; + Float64 *out = (Float64 *)outBuffer; - if (info.inFormat == RTAUDIO_SINT8) { - signed char *in = (signed char *)inBuffer; - scale = 1.0 / 127.5; - for (unsigned int i=0; i> 8); - //out[info.outOffset[j]] >>= 8; - } - in += info.inJump; - out += info.outJump; - } - } - else if (info.inFormat == RTAUDIO_FLOAT32) { - Float32 *in = (Float32 *)inBuffer; - for (unsigned int i=0; i> 8); - } - in += info.inJump; - out += info.outJump; - } - } - else if (info.inFormat == RTAUDIO_SINT32) { - Int32 *in = (Int32 *)inBuffer; - for (unsigned int i=0; i> 16) & 0x0000ffff); - } - in += info.inJump; - out += info.outJump; - } - } - else if (info.inFormat == RTAUDIO_FLOAT32) { - Float32 *in = (Float32 *)inBuffer; - for (unsigned int i=0; i> 8) & 0x00ff); - } - in += info.inJump; - out += info.outJump; - } - } - else if (info.inFormat == RTAUDIO_SINT24) { - Int24 *in = (Int24 *)inBuffer; - for (unsigned int i=0; i> 16); - } - in += info.inJump; - out += info.outJump; - } - } - else if (info.inFormat == RTAUDIO_SINT32) { - Int32 *in = (Int32 *)inBuffer; - for (unsigned int i=0; i> 24) & 0x000000ff); - } - in += info.inJump; - out += info.outJump; - } - } - else if (info.inFormat == RTAUDIO_FLOAT32) { - Float32 *in = (Float32 *)inBuffer; - for (unsigned int i=0; i> 8); + //out[info.outOffset[j]] >>= 8; + } + in += info.inJump; + out += info.outJump; + } + } + else if (info.inFormat == RTAUDIO_FLOAT32) + { + Float32 *in = (Float32 *)inBuffer; + for (unsigned int i = 0; i < stream_.bufferSize; i++) + { + for (j = 0; j < info.channels; j++) + { + out[info.outOffset[j]] = (Int32)(in[info.inOffset[j]] * 8388607.5 - 0.5); + } + in += info.inJump; + out += info.outJump; + } + } + else if (info.inFormat == RTAUDIO_FLOAT64) + { + Float64 *in = (Float64 *)inBuffer; + for (unsigned int i = 0; i < stream_.bufferSize; i++) + { + for (j = 0; j < info.channels; j++) + { + out[info.outOffset[j]] = (Int32)(in[info.inOffset[j]] * 8388607.5 - 0.5); + } + in += info.inJump; + out += info.outJump; + } + } + } + else if (info.outFormat == RTAUDIO_SINT16) + { + Int16 *out = (Int16 *)outBuffer; + if (info.inFormat == RTAUDIO_SINT8) + { + signed char *in = (signed char *)inBuffer; + for (unsigned int i = 0; i < stream_.bufferSize; i++) + { + for (j = 0; j < info.channels; j++) + { + out[info.outOffset[j]] = (Int16)in[info.inOffset[j]]; + out[info.outOffset[j]] <<= 8; + } + in += info.inJump; + out += info.outJump; + } + } + else if (info.inFormat == RTAUDIO_SINT16) + { + // Channel compensation and/or (de)interleaving only. + Int16 *in = (Int16 *)inBuffer; + for (unsigned int i = 0; i < stream_.bufferSize; i++) + { + for (j = 0; j < info.channels; j++) + { + out[info.outOffset[j]] = in[info.inOffset[j]]; + } + in += info.inJump; + out += info.outJump; + } + } + else if (info.inFormat == RTAUDIO_SINT24) + { + Int24 *in = (Int24 *)inBuffer; + for (unsigned int i = 0; i < stream_.bufferSize; i++) + { + for (j = 0; j < info.channels; j++) + { + out[info.outOffset[j]] = (Int16)(in[info.inOffset[j]].asInt() >> 8); + } + in += info.inJump; + out += info.outJump; + } + } + else if (info.inFormat == RTAUDIO_SINT32) + { + Int32 *in = (Int32 *)inBuffer; + for (unsigned int i = 0; i < stream_.bufferSize; i++) + { + for (j = 0; j < info.channels; j++) + { + out[info.outOffset[j]] = (Int16)((in[info.inOffset[j]] >> 16) & 0x0000ffff); + } + in += info.inJump; + out += info.outJump; + } + } + else if (info.inFormat == RTAUDIO_FLOAT32) + { + Float32 *in = (Float32 *)inBuffer; + for (unsigned int i = 0; i < stream_.bufferSize; i++) + { + for (j = 0; j < info.channels; j++) + { + out[info.outOffset[j]] = (Int16)(in[info.inOffset[j]] * 32767.5 - 0.5); + } + in += info.inJump; + out += info.outJump; + } + } + else if (info.inFormat == RTAUDIO_FLOAT64) + { + Float64 *in = (Float64 *)inBuffer; + for (unsigned int i = 0; i < stream_.bufferSize; i++) + { + for (j = 0; j < info.channels; j++) + { + out[info.outOffset[j]] = (Int16)(in[info.inOffset[j]] * 32767.5 - 0.5); + } + in += info.inJump; + out += info.outJump; + } + } + } + else if (info.outFormat == RTAUDIO_SINT8) + { + signed char *out = (signed char *)outBuffer; + if (info.inFormat == RTAUDIO_SINT8) + { + // Channel compensation and/or (de)interleaving only. + signed char *in = (signed char *)inBuffer; + for (unsigned int i = 0; i < stream_.bufferSize; i++) + { + for (j = 0; j < info.channels; j++) + { + out[info.outOffset[j]] = in[info.inOffset[j]]; + } + in += info.inJump; + out += info.outJump; + } + } + if (info.inFormat == RTAUDIO_SINT16) + { + Int16 *in = (Int16 *)inBuffer; + for (unsigned int i = 0; i < stream_.bufferSize; i++) + { + for (j = 0; j < info.channels; j++) + { + out[info.outOffset[j]] = (signed char)((in[info.inOffset[j]] >> 8) & 0x00ff); + } + in += info.inJump; + out += info.outJump; + } + } + else if (info.inFormat == RTAUDIO_SINT24) + { + Int24 *in = (Int24 *)inBuffer; + for (unsigned int i = 0; i < stream_.bufferSize; i++) + { + for (j = 0; j < info.channels; j++) + { + out[info.outOffset[j]] = (signed char)(in[info.inOffset[j]].asInt() >> 16); + } + in += info.inJump; + out += info.outJump; + } + } + else if (info.inFormat == RTAUDIO_SINT32) + { + Int32 *in = (Int32 *)inBuffer; + for (unsigned int i = 0; i < stream_.bufferSize; i++) + { + for (j = 0; j < info.channels; j++) + { + out[info.outOffset[j]] = (signed char)((in[info.inOffset[j]] >> 24) & 0x000000ff); + } + in += info.inJump; + out += info.outJump; + } + } + else if (info.inFormat == RTAUDIO_FLOAT32) + { + Float32 *in = (Float32 *)inBuffer; + for (unsigned int i = 0; i < stream_.bufferSize; i++) + { + for (j = 0; j < info.channels; j++) + { + out[info.outOffset[j]] = (signed char)(in[info.inOffset[j]] * 127.5 - 0.5); + } + in += info.inJump; + out += info.outJump; + } + } + else if (info.inFormat == RTAUDIO_FLOAT64) + { + Float64 *in = (Float64 *)inBuffer; + for (unsigned int i = 0; i < stream_.bufferSize; i++) + { + for (j = 0; j < info.channels; j++) + { + out[info.outOffset[j]] = (signed char)(in[info.inOffset[j]] * 127.5 - 0.5); + } + in += info.inJump; + out += info.outJump; + } + } + } } //static inline uint16_t bswap_16(uint16_t x) { return (x>>8) | (x<<8); } //static inline uint32_t bswap_32(uint32_t x) { return (bswap_16(x&0xffff)<<16) | (bswap_16(x>>16)); } //static inline uint64_t bswap_64(uint64_t x) { return (((unsigned long long)bswap_32(x&0xffffffffull))<<32) | (bswap_32(x>>32)); } -void RtApi :: byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format ) +void RtApi ::byteSwapBuffer(char *buffer, unsigned int samples, RtAudioFormat format) { - char val; - char *ptr; + char val; + char *ptr; - ptr = buffer; - if ( format == RTAUDIO_SINT16 ) { - for ( unsigned int i=0; i sampleRates; /*!< Supported sample rates (queried from list of standard rates). */ + unsigned int preferredSampleRate; /*!< Preferred sample rate, eg. for WASAPI the system sample rate. */ + RtAudioFormat nativeFormats; /*!< Bit mask of supported data formats. */ - //! The public device information structure for returning queried values. - struct DeviceInfo { - bool probed; /*!< true if the device capabilities were successfully probed. */ - std::string name; /*!< Character string device identifier. */ - unsigned int outputChannels; /*!< Maximum output channels supported by device. */ - unsigned int inputChannels; /*!< Maximum input channels supported by device. */ - unsigned int duplexChannels; /*!< Maximum simultaneous input/output channels supported by device. */ - bool isDefaultOutput; /*!< true if this is the default output device. */ - bool isDefaultInput; /*!< true if this is the default input device. */ - std::vector sampleRates; /*!< Supported sample rates (queried from list of standard rates). */ - unsigned int preferredSampleRate; /*!< Preferred sample rate, eg. for WASAPI the system sample rate. */ - RtAudioFormat nativeFormats; /*!< Bit mask of supported data formats. */ + // Default constructor. + DeviceInfo() + : probed(false), outputChannels(0), inputChannels(0), duplexChannels(0), isDefaultOutput(false), isDefaultInput(false), preferredSampleRate(0), nativeFormats(0) {} + }; - // Default constructor. - DeviceInfo() - :probed(false), outputChannels(0), inputChannels(0), duplexChannels(0), - isDefaultOutput(false), isDefaultInput(false), preferredSampleRate(0), nativeFormats(0) {} - }; + //! The structure for specifying input or ouput stream parameters. + struct StreamParameters + { + unsigned int deviceId; /*!< Device index (0 to getDeviceCount() - 1). */ + unsigned int nChannels; /*!< Number of channels. */ + unsigned int firstChannel; /*!< First channel index on device (default = 0). */ - //! The structure for specifying input or ouput stream parameters. - struct StreamParameters { - unsigned int deviceId; /*!< Device index (0 to getDeviceCount() - 1). */ - unsigned int nChannels; /*!< Number of channels. */ - unsigned int firstChannel; /*!< First channel index on device (default = 0). */ + // Default constructor. + StreamParameters() + : deviceId(0), nChannels(0), firstChannel(0) {} + }; - // Default constructor. - StreamParameters() - : deviceId(0), nChannels(0), firstChannel(0) {} - }; - - //! The structure for specifying stream options. - /*! + //! The structure for specifying stream options. + /*! The following flags can be OR'ed together to allow a client to make changes to the default stream behavior: @@ -363,30 +366,31 @@ class RtAudio RtApiJack. However, if you wish to create multiple instances of RtAudio with Jack, each instance must have a unique client name. */ - struct StreamOptions { - RtAudioStreamFlags flags; /*!< A bit-mask of stream flags (RTAUDIO_NONINTERLEAVED, RTAUDIO_MINIMIZE_LATENCY, RTAUDIO_HOG_DEVICE, RTAUDIO_ALSA_USE_DEFAULT). */ - unsigned int numberOfBuffers; /*!< Number of stream buffers. */ - std::string streamName; /*!< A stream name (currently used only in Jack). */ - int priority; /*!< Scheduling priority of callback thread (only used with flag RTAUDIO_SCHEDULE_REALTIME). */ + struct StreamOptions + { + RtAudioStreamFlags flags; /*!< A bit-mask of stream flags (RTAUDIO_NONINTERLEAVED, RTAUDIO_MINIMIZE_LATENCY, RTAUDIO_HOG_DEVICE, RTAUDIO_ALSA_USE_DEFAULT). */ + unsigned int numberOfBuffers; /*!< Number of stream buffers. */ + std::string streamName; /*!< A stream name (currently used only in Jack). */ + int priority; /*!< Scheduling priority of callback thread (only used with flag RTAUDIO_SCHEDULE_REALTIME). */ - // Default constructor. - StreamOptions() - : flags(0), numberOfBuffers(0), priority(0) {} - }; + // Default constructor. + StreamOptions() + : flags(0), numberOfBuffers(0), priority(0) {} + }; - //! A static function to determine the current RtAudio version. - static std::string getVersion( void ) throw(); + //! A static function to determine the current RtAudio version. + static std::string getVersion(void) throw(); - //! A static function to determine the available compiled audio APIs. - /*! + //! A static function to determine the available compiled audio APIs. + /*! The values returned in the std::vector can be compared against the enumerated list values. Note that there can be more than one API compiled for certain operating systems. */ - static void getCompiledApi( std::vector &apis ) throw(); + static void getCompiledApi(std::vector &apis) throw(); - //! The class constructor. - /*! + //! The class constructor. + /*! The constructor performs minor initialization tasks. An exception can be thrown if no API support is compiled. @@ -394,28 +398,28 @@ class RtAudio compiled, the default order of use is JACK, ALSA, OSS (Linux systems) and ASIO, DS (Windows systems). */ - RtAudio( RtAudio::Api api=UNSPECIFIED ); + RtAudio(RtAudio::Api api = UNSPECIFIED); - //! The destructor. - /*! + //! The destructor. + /*! If a stream is running or open, it will be stopped and closed automatically. */ - ~RtAudio() throw(); + ~RtAudio() throw(); - //! Returns the audio API specifier for the current instance of RtAudio. - RtAudio::Api getCurrentApi( void ) throw(); + //! Returns the audio API specifier for the current instance of RtAudio. + RtAudio::Api getCurrentApi(void) throw(); - //! A public function that queries for the number of audio devices available. - /*! + //! A public function that queries for the number of audio devices available. + /*! This function performs a system query of available devices each time it is called, thus supporting devices connected \e after instantiation. If a system error occurs during processing, a warning will be issued. */ - unsigned int getDeviceCount( void ) throw(); + unsigned int getDeviceCount(void) throw(); - //! Return an RtAudio::DeviceInfo structure for a specified device number. - /*! + //! Return an RtAudio::DeviceInfo structure for a specified device number. + /*! Any device integer between 0 and getDeviceCount() - 1 is valid. If an invalid argument is provided, an RtAudioError (type = INVALID_USE) @@ -425,30 +429,30 @@ class RtAudio current default input or output device, the corresponding "isDefault" member will have a value of "true". */ - RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); + RtAudio::DeviceInfo getDeviceInfo(unsigned int device); - //! A function that returns the index of the default output device. - /*! + //! A function that returns the index of the default output device. + /*! If the underlying audio API does not provide a "default device", or if no devices are available, the return value will be 0. Note that this is a valid device identifier and it is the client's responsibility to verify that a device is available before attempting to open a stream. */ - unsigned int getDefaultOutputDevice( void ) throw(); + unsigned int getDefaultOutputDevice(void) throw(); - //! A function that returns the index of the default input device. - /*! + //! A function that returns the index of the default input device. + /*! If the underlying audio API does not provide a "default device", or if no devices are available, the return value will be 0. Note that this is a valid device identifier and it is the client's responsibility to verify that a device is available before attempting to open a stream. */ - unsigned int getDefaultInputDevice( void ) throw(); + unsigned int getDefaultInputDevice(void) throw(); - //! A public function for opening a stream with the specified parameters. - /*! + //! A public function for opening a stream with the specified parameters. + /*! An RtAudioError (type = SYSTEM_ERROR) is thrown if a stream cannot be opened with the specified parameters or an error occurs during processing. An RtAudioError (type = INVALID_USE) is thrown if any @@ -487,66 +491,66 @@ class RtAudio \param errorCallback A client-defined function that will be invoked when an error has occured. */ - void openStream( RtAudio::StreamParameters *outputParameters, - RtAudio::StreamParameters *inputParameters, - RtAudioFormat format, unsigned int sampleRate, - unsigned int *bufferFrames, RtAudioCallback callback, - void *userData = NULL, RtAudio::StreamOptions *options = NULL, RtAudioErrorCallback errorCallback = NULL ); + void openStream(RtAudio::StreamParameters *outputParameters, + RtAudio::StreamParameters *inputParameters, + RtAudioFormat format, unsigned int sampleRate, + unsigned int *bufferFrames, RtAudioCallback callback, + void *userData = NULL, RtAudio::StreamOptions *options = NULL, RtAudioErrorCallback errorCallback = NULL); - //! A function that closes a stream and frees any associated stream memory. - /*! + //! A function that closes a stream and frees any associated stream memory. + /*! If a stream is not open, this function issues a warning and returns (no exception is thrown). */ - void closeStream( void ) throw(); + void closeStream(void) throw(); - //! A function that starts a stream. - /*! + //! A function that starts a stream. + /*! An RtAudioError (type = SYSTEM_ERROR) is thrown if an error occurs during processing. An RtAudioError (type = INVALID_USE) is thrown if a stream is not open. A warning is issued if the stream is already running. */ - void startStream( void ); + void startStream(void); - //! Stop a stream, allowing any samples remaining in the output queue to be played. - /*! + //! Stop a stream, allowing any samples remaining in the output queue to be played. + /*! An RtAudioError (type = SYSTEM_ERROR) is thrown if an error occurs during processing. An RtAudioError (type = INVALID_USE) is thrown if a stream is not open. A warning is issued if the stream is already stopped. */ - void stopStream( void ); + void stopStream(void); - //! Stop a stream, discarding any samples remaining in the input/output queue. - /*! + //! Stop a stream, discarding any samples remaining in the input/output queue. + /*! An RtAudioError (type = SYSTEM_ERROR) is thrown if an error occurs during processing. An RtAudioError (type = INVALID_USE) is thrown if a stream is not open. A warning is issued if the stream is already stopped. */ - void abortStream( void ); + void abortStream(void); - //! Returns true if a stream is open and false if not. - bool isStreamOpen( void ) const throw(); + //! Returns true if a stream is open and false if not. + bool isStreamOpen(void) const throw(); - //! Returns true if the stream is running and false if it is stopped or not open. - bool isStreamRunning( void ) const throw(); + //! Returns true if the stream is running and false if it is stopped or not open. + bool isStreamRunning(void) const throw(); - //! Returns the number of elapsed seconds since the stream was started. - /*! + //! Returns the number of elapsed seconds since the stream was started. + /*! If a stream is not open, an RtAudioError (type = INVALID_USE) will be thrown. */ - double getStreamTime( void ); + double getStreamTime(void); - //! Set the stream time to a time in seconds greater than or equal to 0.0. - /*! + //! Set the stream time to a time in seconds greater than or equal to 0.0. + /*! If a stream is not open, an RtAudioError (type = INVALID_USE) will be thrown. */ - void setStreamTime( double time ); + void setStreamTime(double time); - //! Returns the internal stream latency in sample frames. - /*! + //! Returns the internal stream latency in sample frames. + /*! The stream latency refers to delay in audio input and/or output caused by internal buffering by the audio system and/or hardware. For duplex streams, the returned value will represent the sum of @@ -554,69 +558,69 @@ class RtAudio RtAudioError (type = INVALID_USE) will be thrown. If the API does not report latency, the return value will be zero. */ - long getStreamLatency( void ); + long getStreamLatency(void); - //! Returns actual sample rate in use by the stream. - /*! + //! Returns actual sample rate in use by the stream. + /*! On some systems, the sample rate used may be slightly different than that specified in the stream parameters. If a stream is not open, an RtAudioError (type = INVALID_USE) will be thrown. */ - unsigned int getStreamSampleRate( void ); + unsigned int getStreamSampleRate(void); - //! Specify whether warning messages should be printed to stderr. - void showWarnings( bool value = true ) throw(); + //! Specify whether warning messages should be printed to stderr. + void showWarnings(bool value = true) throw(); - protected: - - void openRtApi( RtAudio::Api api ); - RtApi *rtapi_; +protected: + void openRtApi(RtAudio::Api api); + RtApi *rtapi_; }; // Operating system dependent thread functionality. #if defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__) || defined(__WINDOWS_WASAPI__) - #ifndef NOMINMAX - #define NOMINMAX - #endif - #include - #include +#ifndef NOMINMAX +#define NOMINMAX +#endif +#include +#include - typedef uintptr_t ThreadHandle; - typedef CRITICAL_SECTION StreamMutex; +typedef uintptr_t ThreadHandle; +typedef CRITICAL_SECTION StreamMutex; #elif defined(__LINUX_ALSA__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__) || defined(__LINUX_OSS__) || defined(__MACOSX_CORE__) - // Using pthread library for various flavors of unix. - #include +// Using pthread library for various flavors of unix. +#include - typedef pthread_t ThreadHandle; - typedef pthread_mutex_t StreamMutex; +typedef pthread_t ThreadHandle; +typedef pthread_mutex_t StreamMutex; -#else // Setup for "dummy" behavior +#else // Setup for "dummy" behavior - #define __RTAUDIO_DUMMY__ - typedef int ThreadHandle; - typedef int StreamMutex; +#define __RTAUDIO_DUMMY__ +typedef int ThreadHandle; +typedef int StreamMutex; #endif // This global structure type is used to pass callback information // between the private RtAudio stream structure and global callback // handling functions. -struct CallbackInfo { - void *object; // Used as a "this" pointer. - ThreadHandle thread; - void *callback; - void *userData; - void *errorCallback; - void *apiInfo; // void pointer for API specific callback information - bool isRunning; - bool doRealtime; - int priority; +struct CallbackInfo +{ + void *object; // Used as a "this" pointer. + ThreadHandle thread; + void *callback; + void *userData; + void *errorCallback; + void *apiInfo; // void pointer for API specific callback information + bool isRunning; + bool doRealtime; + int priority; - // Default constructor. - CallbackInfo() - :object(0), callback(0), userData(0), errorCallback(0), apiInfo(0), isRunning(false), doRealtime(false) {} + // Default constructor. + CallbackInfo() + : object(0), callback(0), userData(0), errorCallback(0), apiInfo(0), isRunning(false), doRealtime(false) {} }; // **************************************************************** // @@ -634,37 +638,39 @@ struct CallbackInfo { // **************************************************************** // #pragma pack(push, 1) -class S24 { +class S24 +{ +protected: + unsigned char c3[3]; - protected: - unsigned char c3[3]; +public: + S24() {} - public: - S24() {} + S24 &operator=(const int &i) + { + c3[0] = (i & 0x000000ff); + c3[1] = (i & 0x0000ff00) >> 8; + c3[2] = (i & 0x00ff0000) >> 16; + return *this; + } - S24& operator = ( const int& i ) { - c3[0] = (i & 0x000000ff); - c3[1] = (i & 0x0000ff00) >> 8; - c3[2] = (i & 0x00ff0000) >> 16; - return *this; - } + S24(const S24 &v) { *this = v; } + S24(const double &d) { *this = (int)d; } + S24(const float &f) { *this = (int)f; } + S24(const signed short &s) { *this = (int)s; } + S24(const char &c) { *this = (int)c; } - S24( const S24& v ) { *this = v; } - S24( const double& d ) { *this = (int) d; } - S24( const float& f ) { *this = (int) f; } - S24( const signed short& s ) { *this = (int) s; } - S24( const char& c ) { *this = (int) c; } - - int asInt() { - int i = c3[0] | (c3[1] << 8) | (c3[2] << 16); - if (i & 0x800000) i |= ~0xffffff; - return i; - } + int asInt() + { + int i = c3[0] | (c3[1] << 8) | (c3[2] << 16); + if (i & 0x800000) i |= ~0xffffff; + return i; + } }; #pragma pack(pop) -#if defined( HAVE_GETTIMEOFDAY ) - #include +#if defined(HAVE_GETTIMEOFDAY) +#include #endif #include @@ -672,150 +678,159 @@ class S24 { class RtApi { public: - - RtApi(); - virtual ~RtApi(); - virtual RtAudio::Api getCurrentApi( void ) = 0; - virtual unsigned int getDeviceCount( void ) = 0; - virtual RtAudio::DeviceInfo getDeviceInfo( unsigned int device ) = 0; - virtual unsigned int getDefaultInputDevice( void ); - virtual unsigned int getDefaultOutputDevice( void ); - void openStream( RtAudio::StreamParameters *outputParameters, - RtAudio::StreamParameters *inputParameters, - RtAudioFormat format, unsigned int sampleRate, - unsigned int *bufferFrames, RtAudioCallback callback, - void *userData, RtAudio::StreamOptions *options, - RtAudioErrorCallback errorCallback ); - virtual void closeStream( void ); - virtual void startStream( void ) = 0; - virtual void stopStream( void ) = 0; - virtual void abortStream( void ) = 0; - long getStreamLatency( void ); - unsigned int getStreamSampleRate( void ); - virtual double getStreamTime( void ); - virtual void setStreamTime( double time ); - bool isStreamOpen( void ) const { return stream_.state != STREAM_CLOSED; } - bool isStreamRunning( void ) const { return stream_.state == STREAM_RUNNING; } - void showWarnings( bool value ) { showWarnings_ = value; } - + RtApi(); + virtual ~RtApi(); + virtual RtAudio::Api getCurrentApi(void) = 0; + virtual unsigned int getDeviceCount(void) = 0; + virtual RtAudio::DeviceInfo getDeviceInfo(unsigned int device) = 0; + virtual unsigned int getDefaultInputDevice(void); + virtual unsigned int getDefaultOutputDevice(void); + void openStream(RtAudio::StreamParameters *outputParameters, + RtAudio::StreamParameters *inputParameters, + RtAudioFormat format, unsigned int sampleRate, + unsigned int *bufferFrames, RtAudioCallback callback, + void *userData, RtAudio::StreamOptions *options, + RtAudioErrorCallback errorCallback); + virtual void closeStream(void); + virtual void startStream(void) = 0; + virtual void stopStream(void) = 0; + virtual void abortStream(void) = 0; + long getStreamLatency(void); + unsigned int getStreamSampleRate(void); + virtual double getStreamTime(void); + virtual void setStreamTime(double time); + bool isStreamOpen(void) const { return stream_.state != STREAM_CLOSED; } + bool isStreamRunning(void) const { return stream_.state == STREAM_RUNNING; } + void showWarnings(bool value) { showWarnings_ = value; } protected: + static const unsigned int MAX_SAMPLE_RATES; + static const unsigned int SAMPLE_RATES[]; - static const unsigned int MAX_SAMPLE_RATES; - static const unsigned int SAMPLE_RATES[]; + enum + { + FAILURE, + SUCCESS + }; - enum { FAILURE, SUCCESS }; + enum StreamState + { + STREAM_STOPPED, + STREAM_STOPPING, + STREAM_RUNNING, + STREAM_CLOSED = -50 + }; - enum StreamState { - STREAM_STOPPED, - STREAM_STOPPING, - STREAM_RUNNING, - STREAM_CLOSED = -50 - }; + enum StreamMode + { + OUTPUT, + INPUT, + DUPLEX, + UNINITIALIZED = -75 + }; - enum StreamMode { - OUTPUT, - INPUT, - DUPLEX, - UNINITIALIZED = -75 - }; + // A protected structure used for buffer conversion. + struct ConvertInfo + { + int channels; + int inJump, outJump; + RtAudioFormat inFormat, outFormat; + std::vector inOffset; + std::vector outOffset; + }; - // A protected structure used for buffer conversion. - struct ConvertInfo { - int channels; - int inJump, outJump; - RtAudioFormat inFormat, outFormat; - std::vector inOffset; - std::vector outOffset; - }; - - // A protected structure for audio streams. - struct RtApiStream { - unsigned int device[2]; // Playback and record, respectively. - void *apiHandle; // void pointer for API specific stream handle information - StreamMode mode; // OUTPUT, INPUT, or DUPLEX. - StreamState state; // STOPPED, RUNNING, or CLOSED - char *userBuffer[2]; // Playback and record, respectively. - char *deviceBuffer; - bool doConvertBuffer[2]; // Playback and record, respectively. - bool userInterleaved; - bool deviceInterleaved[2]; // Playback and record, respectively. - bool doByteSwap[2]; // Playback and record, respectively. - unsigned int sampleRate; - unsigned int bufferSize; - unsigned int nBuffers; - unsigned int nUserChannels[2]; // Playback and record, respectively. - unsigned int nDeviceChannels[2]; // Playback and record channels, respectively. - unsigned int channelOffset[2]; // Playback and record, respectively. - unsigned long latency[2]; // Playback and record, respectively. - RtAudioFormat userFormat; - RtAudioFormat deviceFormat[2]; // Playback and record, respectively. - StreamMutex mutex; - CallbackInfo callbackInfo; - ConvertInfo convertInfo[2]; - double streamTime; // Number of elapsed seconds since the stream started. + // A protected structure for audio streams. + struct RtApiStream + { + unsigned int device[2]; // Playback and record, respectively. + void *apiHandle; // void pointer for API specific stream handle information + StreamMode mode; // OUTPUT, INPUT, or DUPLEX. + StreamState state; // STOPPED, RUNNING, or CLOSED + char *userBuffer[2]; // Playback and record, respectively. + char *deviceBuffer; + bool doConvertBuffer[2]; // Playback and record, respectively. + bool userInterleaved; + bool deviceInterleaved[2]; // Playback and record, respectively. + bool doByteSwap[2]; // Playback and record, respectively. + unsigned int sampleRate; + unsigned int bufferSize; + unsigned int nBuffers; + unsigned int nUserChannels[2]; // Playback and record, respectively. + unsigned int nDeviceChannels[2]; // Playback and record channels, respectively. + unsigned int channelOffset[2]; // Playback and record, respectively. + unsigned long latency[2]; // Playback and record, respectively. + RtAudioFormat userFormat; + RtAudioFormat deviceFormat[2]; // Playback and record, respectively. + StreamMutex mutex; + CallbackInfo callbackInfo; + ConvertInfo convertInfo[2]; + double streamTime; // Number of elapsed seconds since the stream started. #if defined(HAVE_GETTIMEOFDAY) - struct timeval lastTickTimestamp; + struct timeval lastTickTimestamp; #endif - RtApiStream() - :apiHandle(0), deviceBuffer(0) { device[0] = 11111; device[1] = 11111; } - }; + RtApiStream() + : apiHandle(0), deviceBuffer(0) + { + device[0] = 11111; + device[1] = 11111; + } + }; - typedef S24 Int24; - typedef signed short Int16; - typedef signed int Int32; - typedef float Float32; - typedef double Float64; + typedef S24 Int24; + typedef signed short Int16; + typedef signed int Int32; + typedef float Float32; + typedef double Float64; - std::ostringstream errorStream_; - std::string errorText_; - bool showWarnings_; - RtApiStream stream_; - bool firstErrorOccurred_; + std::ostringstream errorStream_; + std::string errorText_; + bool showWarnings_; + RtApiStream stream_; + bool firstErrorOccurred_; - /*! + /*! Protected, api-specific method that attempts to open a device with the given parameters. This function MUST be implemented by all subclasses. If an error is encountered during the probe, a "warning" message is reported and FAILURE is returned. A successful probe is indicated by a return value of SUCCESS. */ - virtual bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, - unsigned int firstChannel, unsigned int sampleRate, - RtAudioFormat format, unsigned int *bufferSize, - RtAudio::StreamOptions *options ); + virtual bool probeDeviceOpen(unsigned int device, StreamMode mode, unsigned int channels, + unsigned int firstChannel, unsigned int sampleRate, + RtAudioFormat format, unsigned int *bufferSize, + RtAudio::StreamOptions *options); - //! A protected function used to increment the stream time. - void tickStreamTime( void ); + //! A protected function used to increment the stream time. + void tickStreamTime(void); - //! Protected common method to clear an RtApiStream structure. - void clearStreamInfo(); + //! Protected common method to clear an RtApiStream structure. + void clearStreamInfo(); - /*! + /*! Protected common method that throws an RtAudioError (type = INVALID_USE) if a stream is not open. */ - void verifyStream( void ); + void verifyStream(void); - //! Protected common error method to allow global control over error handling. - void error( RtAudioError::Type type ); + //! Protected common error method to allow global control over error handling. + void error(RtAudioError::Type type); - /*! + /*! Protected method used to perform format, channel number, and/or interleaving conversions between the user and device buffers. */ - void convertBuffer( char *outBuffer, char *inBuffer, ConvertInfo &info ); + void convertBuffer(char *outBuffer, char *inBuffer, ConvertInfo &info); - //! Protected common method used to perform byte-swapping on buffers. - void byteSwapBuffer( char *buffer, unsigned int samples, RtAudioFormat format ); + //! Protected common method used to perform byte-swapping on buffers. + void byteSwapBuffer(char *buffer, unsigned int samples, RtAudioFormat format); - //! Protected common method that returns the number of bytes for a given format. - unsigned int formatBytes( RtAudioFormat format ); + //! Protected common method that returns the number of bytes for a given format. + unsigned int formatBytes(RtAudioFormat format); - //! Protected common method that sets up the parameters for buffer conversion. - void setConvertInfo( StreamMode mode, unsigned int firstChannel ); + //! Protected common method that sets up the parameters for buffer conversion. + void setConvertInfo(StreamMode mode, unsigned int firstChannel); }; // **************************************************************** // @@ -824,22 +839,22 @@ protected: // // **************************************************************** // -inline RtAudio::Api RtAudio :: getCurrentApi( void ) throw() { return rtapi_->getCurrentApi(); } -inline unsigned int RtAudio :: getDeviceCount( void ) throw() { return rtapi_->getDeviceCount(); } -inline RtAudio::DeviceInfo RtAudio :: getDeviceInfo( unsigned int device ) { return rtapi_->getDeviceInfo( device ); } -inline unsigned int RtAudio :: getDefaultInputDevice( void ) throw() { return rtapi_->getDefaultInputDevice(); } -inline unsigned int RtAudio :: getDefaultOutputDevice( void ) throw() { return rtapi_->getDefaultOutputDevice(); } -inline void RtAudio :: closeStream( void ) throw() { return rtapi_->closeStream(); } -inline void RtAudio :: startStream( void ) { return rtapi_->startStream(); } -inline void RtAudio :: stopStream( void ) { return rtapi_->stopStream(); } -inline void RtAudio :: abortStream( void ) { return rtapi_->abortStream(); } -inline bool RtAudio :: isStreamOpen( void ) const throw() { return rtapi_->isStreamOpen(); } -inline bool RtAudio :: isStreamRunning( void ) const throw() { return rtapi_->isStreamRunning(); } -inline long RtAudio :: getStreamLatency( void ) { return rtapi_->getStreamLatency(); } -inline unsigned int RtAudio :: getStreamSampleRate( void ) { return rtapi_->getStreamSampleRate(); } -inline double RtAudio :: getStreamTime( void ) { return rtapi_->getStreamTime(); } -inline void RtAudio :: setStreamTime( double time ) { return rtapi_->setStreamTime( time ); } -inline void RtAudio :: showWarnings( bool value ) throw() { rtapi_->showWarnings( value ); } +inline RtAudio::Api RtAudio ::getCurrentApi(void) throw() { return rtapi_->getCurrentApi(); } +inline unsigned int RtAudio ::getDeviceCount(void) throw() { return rtapi_->getDeviceCount(); } +inline RtAudio::DeviceInfo RtAudio ::getDeviceInfo(unsigned int device) { return rtapi_->getDeviceInfo(device); } +inline unsigned int RtAudio ::getDefaultInputDevice(void) throw() { return rtapi_->getDefaultInputDevice(); } +inline unsigned int RtAudio ::getDefaultOutputDevice(void) throw() { return rtapi_->getDefaultOutputDevice(); } +inline void RtAudio ::closeStream(void) throw() { return rtapi_->closeStream(); } +inline void RtAudio ::startStream(void) { return rtapi_->startStream(); } +inline void RtAudio ::stopStream(void) { return rtapi_->stopStream(); } +inline void RtAudio ::abortStream(void) { return rtapi_->abortStream(); } +inline bool RtAudio ::isStreamOpen(void) const throw() { return rtapi_->isStreamOpen(); } +inline bool RtAudio ::isStreamRunning(void) const throw() { return rtapi_->isStreamRunning(); } +inline long RtAudio ::getStreamLatency(void) { return rtapi_->getStreamLatency(); } +inline unsigned int RtAudio ::getStreamSampleRate(void) { return rtapi_->getStreamSampleRate(); } +inline double RtAudio ::getStreamTime(void) { return rtapi_->getStreamTime(); } +inline void RtAudio ::setStreamTime(double time) { return rtapi_->setStreamTime(time); } +inline void RtAudio ::showWarnings(bool value) throw() { rtapi_->showWarnings(value); } // RtApi Subclass prototypes. @@ -847,146 +862,138 @@ inline void RtAudio :: showWarnings( bool value ) throw() { rtapi_->showWarnings #include -class RtApiCore: public RtApi +class RtApiCore : public RtApi { public: + RtApiCore(); + ~RtApiCore(); + RtAudio::Api getCurrentApi(void) { return RtAudio::MACOSX_CORE; } + unsigned int getDeviceCount(void); + RtAudio::DeviceInfo getDeviceInfo(unsigned int device); + unsigned int getDefaultOutputDevice(void); + unsigned int getDefaultInputDevice(void); + void closeStream(void); + void startStream(void); + void stopStream(void); + void abortStream(void); + long getStreamLatency(void); - RtApiCore(); - ~RtApiCore(); - RtAudio::Api getCurrentApi( void ) { return RtAudio::MACOSX_CORE; } - unsigned int getDeviceCount( void ); - RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); - unsigned int getDefaultOutputDevice( void ); - unsigned int getDefaultInputDevice( void ); - void closeStream( void ); - void startStream( void ); - void stopStream( void ); - void abortStream( void ); - long getStreamLatency( void ); + // This function is intended for internal use only. It must be + // public because it is called by the internal callback handler, + // which is not a member of RtAudio. External use of this function + // will most likely produce highly undesireable results! + bool callbackEvent(AudioDeviceID deviceId, + const AudioBufferList *inBufferList, + const AudioBufferList *outBufferList); - // This function is intended for internal use only. It must be - // public because it is called by the internal callback handler, - // which is not a member of RtAudio. External use of this function - // will most likely produce highly undesireable results! - bool callbackEvent( AudioDeviceID deviceId, - const AudioBufferList *inBufferList, - const AudioBufferList *outBufferList ); - - private: - - bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, - unsigned int firstChannel, unsigned int sampleRate, - RtAudioFormat format, unsigned int *bufferSize, - RtAudio::StreamOptions *options ); - static const char* getErrorCode( OSStatus code ); +private: + bool probeDeviceOpen(unsigned int device, StreamMode mode, unsigned int channels, + unsigned int firstChannel, unsigned int sampleRate, + RtAudioFormat format, unsigned int *bufferSize, + RtAudio::StreamOptions *options); + static const char *getErrorCode(OSStatus code); }; #endif #if defined(__UNIX_JACK__) -class RtApiJack: public RtApi +class RtApiJack : public RtApi { public: + RtApiJack(); + ~RtApiJack(); + RtAudio::Api getCurrentApi(void) { return RtAudio::UNIX_JACK; } + unsigned int getDeviceCount(void); + RtAudio::DeviceInfo getDeviceInfo(unsigned int device); + void closeStream(void); + void startStream(void); + void stopStream(void); + void abortStream(void); + long getStreamLatency(void); - RtApiJack(); - ~RtApiJack(); - RtAudio::Api getCurrentApi( void ) { return RtAudio::UNIX_JACK; } - unsigned int getDeviceCount( void ); - RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); - void closeStream( void ); - void startStream( void ); - void stopStream( void ); - void abortStream( void ); - long getStreamLatency( void ); + // This function is intended for internal use only. It must be + // public because it is called by the internal callback handler, + // which is not a member of RtAudio. External use of this function + // will most likely produce highly undesireable results! + bool callbackEvent(unsigned long nframes); - // This function is intended for internal use only. It must be - // public because it is called by the internal callback handler, - // which is not a member of RtAudio. External use of this function - // will most likely produce highly undesireable results! - bool callbackEvent( unsigned long nframes ); - - private: - - bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, - unsigned int firstChannel, unsigned int sampleRate, - RtAudioFormat format, unsigned int *bufferSize, - RtAudio::StreamOptions *options ); +private: + bool probeDeviceOpen(unsigned int device, StreamMode mode, unsigned int channels, + unsigned int firstChannel, unsigned int sampleRate, + RtAudioFormat format, unsigned int *bufferSize, + RtAudio::StreamOptions *options); }; #endif #if defined(__WINDOWS_ASIO__) -class RtApiAsio: public RtApi +class RtApiAsio : public RtApi { public: + RtApiAsio(); + ~RtApiAsio(); + RtAudio::Api getCurrentApi(void) { return RtAudio::WINDOWS_ASIO; } + unsigned int getDeviceCount(void); + RtAudio::DeviceInfo getDeviceInfo(unsigned int device); + void closeStream(void); + void startStream(void); + void stopStream(void); + void abortStream(void); + long getStreamLatency(void); - RtApiAsio(); - ~RtApiAsio(); - RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_ASIO; } - unsigned int getDeviceCount( void ); - RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); - void closeStream( void ); - void startStream( void ); - void stopStream( void ); - void abortStream( void ); - long getStreamLatency( void ); + // This function is intended for internal use only. It must be + // public because it is called by the internal callback handler, + // which is not a member of RtAudio. External use of this function + // will most likely produce highly undesireable results! + bool callbackEvent(long bufferIndex); - // This function is intended for internal use only. It must be - // public because it is called by the internal callback handler, - // which is not a member of RtAudio. External use of this function - // will most likely produce highly undesireable results! - bool callbackEvent( long bufferIndex ); - - private: - - std::vector devices_; - void saveDeviceInfo( void ); - bool coInitialized_; - bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, - unsigned int firstChannel, unsigned int sampleRate, - RtAudioFormat format, unsigned int *bufferSize, - RtAudio::StreamOptions *options ); +private: + std::vector devices_; + void saveDeviceInfo(void); + bool coInitialized_; + bool probeDeviceOpen(unsigned int device, StreamMode mode, unsigned int channels, + unsigned int firstChannel, unsigned int sampleRate, + RtAudioFormat format, unsigned int *bufferSize, + RtAudio::StreamOptions *options); }; #endif #if defined(__WINDOWS_DS__) -class RtApiDs: public RtApi +class RtApiDs : public RtApi { public: + RtApiDs(); + ~RtApiDs(); + RtAudio::Api getCurrentApi(void) { return RtAudio::WINDOWS_DS; } + unsigned int getDeviceCount(void); + unsigned int getDefaultOutputDevice(void); + unsigned int getDefaultInputDevice(void); + RtAudio::DeviceInfo getDeviceInfo(unsigned int device); + void closeStream(void); + void startStream(void); + void stopStream(void); + void abortStream(void); + long getStreamLatency(void); - RtApiDs(); - ~RtApiDs(); - RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_DS; } - unsigned int getDeviceCount( void ); - unsigned int getDefaultOutputDevice( void ); - unsigned int getDefaultInputDevice( void ); - RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); - void closeStream( void ); - void startStream( void ); - void stopStream( void ); - void abortStream( void ); - long getStreamLatency( void ); + // This function is intended for internal use only. It must be + // public because it is called by the internal callback handler, + // which is not a member of RtAudio. External use of this function + // will most likely produce highly undesireable results! + void callbackEvent(void); - // This function is intended for internal use only. It must be - // public because it is called by the internal callback handler, - // which is not a member of RtAudio. External use of this function - // will most likely produce highly undesireable results! - void callbackEvent( void ); - - private: - - bool coInitialized_; - bool buffersRolling; - long duplexPrerollBytes; - std::vector dsDevices; - bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, - unsigned int firstChannel, unsigned int sampleRate, - RtAudioFormat format, unsigned int *bufferSize, - RtAudio::StreamOptions *options ); +private: + bool coInitialized_; + bool buffersRolling; + long duplexPrerollBytes; + std::vector dsDevices; + bool probeDeviceOpen(unsigned int device, StreamMode mode, unsigned int channels, + unsigned int firstChannel, unsigned int sampleRate, + RtAudioFormat format, unsigned int *bufferSize, + RtAudio::StreamOptions *options); }; #endif @@ -998,155 +1005,156 @@ struct IMMDeviceEnumerator; class RtApiWasapi : public RtApi { public: - RtApiWasapi(); - ~RtApiWasapi(); + RtApiWasapi(); + ~RtApiWasapi(); - RtAudio::Api getCurrentApi( void ) { return RtAudio::WINDOWS_WASAPI; } - unsigned int getDeviceCount( void ); - RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); - unsigned int getDefaultOutputDevice( void ); - unsigned int getDefaultInputDevice( void ); - void closeStream( void ); - void startStream( void ); - void stopStream( void ); - void abortStream( void ); + RtAudio::Api getCurrentApi(void) { return RtAudio::WINDOWS_WASAPI; } + unsigned int getDeviceCount(void); + RtAudio::DeviceInfo getDeviceInfo(unsigned int device); + unsigned int getDefaultOutputDevice(void); + unsigned int getDefaultInputDevice(void); + void closeStream(void); + void startStream(void); + void stopStream(void); + void abortStream(void); private: - bool coInitialized_; - IMMDeviceEnumerator* deviceEnumerator_; + bool coInitialized_; + IMMDeviceEnumerator *deviceEnumerator_; - bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, - unsigned int firstChannel, unsigned int sampleRate, - RtAudioFormat format, unsigned int* bufferSize, - RtAudio::StreamOptions* options ); + bool probeDeviceOpen(unsigned int device, StreamMode mode, unsigned int channels, + unsigned int firstChannel, unsigned int sampleRate, + RtAudioFormat format, unsigned int *bufferSize, + RtAudio::StreamOptions *options); - static DWORD WINAPI runWasapiThread( void* wasapiPtr ); - static DWORD WINAPI stopWasapiThread( void* wasapiPtr ); - static DWORD WINAPI abortWasapiThread( void* wasapiPtr ); - void wasapiThread(); + static DWORD WINAPI runWasapiThread(void *wasapiPtr); + static DWORD WINAPI stopWasapiThread(void *wasapiPtr); + static DWORD WINAPI abortWasapiThread(void *wasapiPtr); + void wasapiThread(); }; #endif #if defined(__LINUX_ALSA__) -class RtApiAlsa: public RtApi +class RtApiAlsa : public RtApi { public: + RtApiAlsa(); + ~RtApiAlsa(); + RtAudio::Api getCurrentApi() { return RtAudio::LINUX_ALSA; } + unsigned int getDeviceCount(void); + RtAudio::DeviceInfo getDeviceInfo(unsigned int device); + void closeStream(void); + void startStream(void); + void stopStream(void); + void abortStream(void); - RtApiAlsa(); - ~RtApiAlsa(); - RtAudio::Api getCurrentApi() { return RtAudio::LINUX_ALSA; } - unsigned int getDeviceCount( void ); - RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); - void closeStream( void ); - void startStream( void ); - void stopStream( void ); - void abortStream( void ); + // This function is intended for internal use only. It must be + // public because it is called by the internal callback handler, + // which is not a member of RtAudio. External use of this function + // will most likely produce highly undesireable results! + void callbackEvent(void); - // This function is intended for internal use only. It must be - // public because it is called by the internal callback handler, - // which is not a member of RtAudio. External use of this function - // will most likely produce highly undesireable results! - void callbackEvent( void ); - - private: - - std::vector devices_; - void saveDeviceInfo( void ); - bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, - unsigned int firstChannel, unsigned int sampleRate, - RtAudioFormat format, unsigned int *bufferSize, - RtAudio::StreamOptions *options ); +private: + std::vector devices_; + void saveDeviceInfo(void); + bool probeDeviceOpen(unsigned int device, StreamMode mode, unsigned int channels, + unsigned int firstChannel, unsigned int sampleRate, + RtAudioFormat format, unsigned int *bufferSize, + RtAudio::StreamOptions *options); }; #endif #if defined(__LINUX_PULSE__) -class RtApiPulse: public RtApi +class RtApiPulse : public RtApi { public: - ~RtApiPulse(); - RtAudio::Api getCurrentApi() { return RtAudio::LINUX_PULSE; } - unsigned int getDeviceCount( void ); - RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); - void closeStream( void ); - void startStream( void ); - void stopStream( void ); - void abortStream( void ); + ~RtApiPulse(); + RtAudio::Api getCurrentApi() { return RtAudio::LINUX_PULSE; } + unsigned int getDeviceCount(void); + RtAudio::DeviceInfo getDeviceInfo(unsigned int device); + void closeStream(void); + void startStream(void); + void stopStream(void); + void abortStream(void); - // This function is intended for internal use only. It must be - // public because it is called by the internal callback handler, - // which is not a member of RtAudio. External use of this function - // will most likely produce highly undesireable results! - void callbackEvent( void ); + // This function is intended for internal use only. It must be + // public because it is called by the internal callback handler, + // which is not a member of RtAudio. External use of this function + // will most likely produce highly undesireable results! + void callbackEvent(void); - private: - - std::vector devices_; - void saveDeviceInfo( void ); - bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, - unsigned int firstChannel, unsigned int sampleRate, - RtAudioFormat format, unsigned int *bufferSize, - RtAudio::StreamOptions *options ); +private: + std::vector devices_; + void saveDeviceInfo(void); + bool probeDeviceOpen(unsigned int device, StreamMode mode, unsigned int channels, + unsigned int firstChannel, unsigned int sampleRate, + RtAudioFormat format, unsigned int *bufferSize, + RtAudio::StreamOptions *options); }; #endif #if defined(__LINUX_OSS__) -class RtApiOss: public RtApi +class RtApiOss : public RtApi { public: + RtApiOss(); + ~RtApiOss(); + RtAudio::Api getCurrentApi() { return RtAudio::LINUX_OSS; } + unsigned int getDeviceCount(void); + RtAudio::DeviceInfo getDeviceInfo(unsigned int device); + void closeStream(void); + void startStream(void); + void stopStream(void); + void abortStream(void); - RtApiOss(); - ~RtApiOss(); - RtAudio::Api getCurrentApi() { return RtAudio::LINUX_OSS; } - unsigned int getDeviceCount( void ); - RtAudio::DeviceInfo getDeviceInfo( unsigned int device ); - void closeStream( void ); - void startStream( void ); - void stopStream( void ); - void abortStream( void ); + // This function is intended for internal use only. It must be + // public because it is called by the internal callback handler, + // which is not a member of RtAudio. External use of this function + // will most likely produce highly undesireable results! + void callbackEvent(void); - // This function is intended for internal use only. It must be - // public because it is called by the internal callback handler, - // which is not a member of RtAudio. External use of this function - // will most likely produce highly undesireable results! - void callbackEvent( void ); - - private: - - bool probeDeviceOpen( unsigned int device, StreamMode mode, unsigned int channels, - unsigned int firstChannel, unsigned int sampleRate, - RtAudioFormat format, unsigned int *bufferSize, - RtAudio::StreamOptions *options ); +private: + bool probeDeviceOpen(unsigned int device, StreamMode mode, unsigned int channels, + unsigned int firstChannel, unsigned int sampleRate, + RtAudioFormat format, unsigned int *bufferSize, + RtAudio::StreamOptions *options); }; #endif #if defined(__RTAUDIO_DUMMY__) -class RtApiDummy: public RtApi +class RtApiDummy : public RtApi { public: + RtApiDummy() + { + errorText_ = "RtApiDummy: This class provides no functionality."; + error(RtAudioError::WARNING); + } + RtAudio::Api getCurrentApi(void) { return RtAudio::RTAUDIO_DUMMY; } + unsigned int getDeviceCount(void) { return 0; } + RtAudio::DeviceInfo getDeviceInfo(unsigned int /*device*/) + { + RtAudio::DeviceInfo info; + return info; + } + void closeStream(void) {} + void startStream(void) {} + void stopStream(void) {} + void abortStream(void) {} - RtApiDummy() { errorText_ = "RtApiDummy: This class provides no functionality."; error( RtAudioError::WARNING ); } - RtAudio::Api getCurrentApi( void ) { return RtAudio::RTAUDIO_DUMMY; } - unsigned int getDeviceCount( void ) { return 0; } - RtAudio::DeviceInfo getDeviceInfo( unsigned int /*device*/ ) { RtAudio::DeviceInfo info; return info; } - void closeStream( void ) {} - void startStream( void ) {} - void stopStream( void ) {} - void abortStream( void ) {} - - private: - - bool probeDeviceOpen( unsigned int /*device*/, StreamMode /*mode*/, unsigned int /*channels*/, - unsigned int /*firstChannel*/, unsigned int /*sampleRate*/, - RtAudioFormat /*format*/, unsigned int * /*bufferSize*/, - RtAudio::StreamOptions * /*options*/ ) { return false; } +private: + bool probeDeviceOpen(unsigned int /*device*/, StreamMode /*mode*/, unsigned int /*channels*/, + unsigned int /*firstChannel*/, unsigned int /*sampleRate*/, + RtAudioFormat /*format*/, unsigned int * /*bufferSize*/, + RtAudio::StreamOptions * /*options*/) { return false; } }; #endif diff --git a/examples/TinyAudio/TinyAudioExample.cpp b/examples/TinyAudio/TinyAudioExample.cpp index 43796de37..5cc93f900 100644 --- a/examples/TinyAudio/TinyAudioExample.cpp +++ b/examples/TinyAudio/TinyAudioExample.cpp @@ -4,7 +4,6 @@ #include "Bullet3Common/b3AlignedObjectArray.h" #include "Bullet3Common/b3HashMap.h" - #include "b3SoundEngine.h" #include "b3SoundSource.h" #include @@ -13,27 +12,27 @@ struct MyHashString { std::string m_string; - unsigned int m_hash; + unsigned int m_hash; - B3_FORCE_INLINE unsigned int getHash()const + B3_FORCE_INLINE unsigned int getHash() const { return m_hash; } MyHashString(const char* name) - :m_string(name) + : m_string(name) { /* magic numbers from http://www.isthe.com/chongo/tech/comp/fnv/ */ - static const unsigned int InitialFNV = 2166136261u; + static const unsigned int InitialFNV = 2166136261u; static const unsigned int FNVMultiple = 16777619u; /* Fowler / Noll / Vo (FNV) Hash */ unsigned int hash = InitialFNV; - - for(int i = 0; m_string[i]; i++) + + for (int i = 0; m_string[i]; i++) { - hash = hash ^ (m_string[i]); /* xor the low 8 bits */ - hash = hash * FNVMultiple; /* multiply by the magic number */ + hash = hash ^ (m_string[i]); /* xor the low 8 bits */ + hash = hash * FNVMultiple; /* multiply by the magic number */ } m_hash = hash; } @@ -42,38 +41,36 @@ struct MyHashString { return (m_string == other.m_string); } - }; - double base_frequency = 440.0; double base_pitch = 69.0; -double MidiPitch2Frequency(double incoming_note) { - return base_frequency * pow (2.0, (incoming_note - base_pitch) / 12.0); +double MidiPitch2Frequency(double incoming_note) +{ + return base_frequency * pow(2.0, (incoming_note - base_pitch) / 12.0); } -double FrequencytoMidiPitch(double incoming_frequency) { - return base_pitch + (12.0 * log(incoming_frequency / base_frequency) / log(2)); +double FrequencytoMidiPitch(double incoming_frequency) +{ + return base_pitch + (12.0 * log(incoming_frequency / base_frequency) / log(2)); } - class TinyAudioExample : public CommonExampleInterface { - GUIHelperInterface* m_guiHelper; - + b3SoundEngine m_soundEngine; int m_wavId; - b3HashMap m_keyToSoundSource; - + b3HashMap m_keyToSoundSource; + public: TinyAudioExample(struct GUIHelperInterface* helper) - :m_guiHelper(helper) + : m_guiHelper(helper) { } - + virtual ~TinyAudioExample() { } @@ -87,54 +84,50 @@ public: m_wavId = m_soundEngine.loadWavFile("wav/xylophone.rosewood.ff.C5B5_1.wav"); int sampleRate = m_soundEngine.getSampleRate(); - } - + } + virtual void exitPhysics() { - m_soundEngine.exit(); } virtual void renderScene() { } - - virtual void stepSimulation(float deltaTime) + + virtual void stepSimulation(float deltaTime) { } - virtual void physicsDebugDraw(int debugFlags) + virtual void physicsDebugDraw(int debugFlags) { } - virtual bool mouseMoveCallback(float x,float y) + virtual bool mouseMoveCallback(float x, float y) { return false; } - virtual bool mouseButtonCallback(int button, int state, float x, float y) + virtual bool mouseButtonCallback(int button, int state, float x, float y) { return false; } - - - virtual bool keyboardCallback(int key, int state) + virtual bool keyboardCallback(int key, int state) { - if (key>='a' && key<='z') + if (key >= 'a' && key <= 'z') { char keyStr[2]; keyStr[0] = (char)key; keyStr[1] = 0; - MyHashString hs (keyStr); + MyHashString hs(keyStr); if (state) { int soundSourceIndex = m_soundEngine.getAvailableSoundSource(); - if (soundSourceIndex>=0) + if (soundSourceIndex >= 0) { - - int note = key-(97-58); + int note = key - (97 - 58); double freq = MidiPitch2Frequency(note); - + b3SoundMessage msg; msg.m_type = B3_SOUND_SOURCE_SINE_OSCILLATOR; msg.m_frequency = freq; @@ -147,10 +140,10 @@ public: msg.m_releaseRate = 0.001; m_soundEngine.startSound(soundSourceIndex, msg); - m_keyToSoundSource.insert(hs,soundSourceIndex); + m_keyToSoundSource.insert(hs, soundSourceIndex); //printf("soundSourceIndex:%d\n", soundSourceIndex); - - #if 0 + +#if 0 b3SoundSource* soundSource = this->m_soundSourcesPool[soundSourceIndex]; soundSource->setOscillatorFrequency(0, freq ); @@ -165,9 +158,10 @@ public: printf("just inserted: %d\n", newIndex); } } - #endif +#endif } - } else + } + else { int* soundSourceIndexPtr = m_keyToSoundSource[hs]; if (soundSourceIndexPtr) @@ -176,7 +170,7 @@ public: //printf("releaseSound: %d\n", soundSourceIndex); m_soundEngine.releaseSound(soundSourceIndex); } - #if 0 +#if 0 if (soundSourceIndex>=0) { printf("releasing %d\n", soundSourceIndex); @@ -184,11 +178,10 @@ public: soundSource->stopSound(); } } - #endif +#endif } } - return false; } @@ -197,17 +190,14 @@ public: float dist = 4; float pitch = 52; float yaw = 35; - float targetPos[3]={0,0,0}; - m_guiHelper->resetCamera(dist,pitch,yaw,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {0, 0, 0}; + m_guiHelper->resetCamera(dist, pitch, yaw, targetPos[0], targetPos[1], targetPos[2]); } - }; -CommonExampleInterface* TinyAudioExampleCreateFunc(CommonExampleOptions& options) +CommonExampleInterface* TinyAudioExampleCreateFunc(CommonExampleOptions& options) { return new TinyAudioExample(options.m_guiHelper); - } - B3_STANDALONE_EXAMPLE(TinyAudioExampleCreateFunc) diff --git a/examples/TinyAudio/TinyAudioExample.h b/examples/TinyAudio/TinyAudioExample.h index d20ef8608..14276cd3e 100644 --- a/examples/TinyAudio/TinyAudioExample.h +++ b/examples/TinyAudio/TinyAudioExample.h @@ -2,6 +2,6 @@ #ifndef TINY_AUDIO_EXAMPLE_H #define TINY_AUDIO_EXAMPLE_H -class CommonExampleInterface* TinyAudioExampleCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* TinyAudioExampleCreateFunc(struct CommonExampleOptions& options); -#endif //TINY_AUDIO_EXAMPLE_H \ No newline at end of file +#endif //TINY_AUDIO_EXAMPLE_H \ No newline at end of file diff --git a/examples/TinyAudio/b3ADSR.cpp b/examples/TinyAudio/b3ADSR.cpp index a96354245..f3a287a35 100644 --- a/examples/TinyAudio/b3ADSR.cpp +++ b/examples/TinyAudio/b3ADSR.cpp @@ -4,7 +4,6 @@ //! ADSR envelope states. - enum { ADSR_ATTACK, /*!< Attack */ @@ -69,7 +68,6 @@ double b3ADSR::tick() { keyOff(); } - } } break; @@ -96,7 +94,7 @@ void b3ADSR::keyOn(bool autoKeyOff) m_autoKeyOff = autoKeyOff; if (m_target <= 0.0) m_target = 1.0; - if (m_attackRate==1) + if (m_attackRate == 1) { m_value = 1.0; } @@ -108,5 +106,4 @@ void b3ADSR::keyOff() m_autoKeyOff = false; m_target = 0.0; m_state = ADSR_RELEASE; - } diff --git a/examples/TinyAudio/b3ADSR.h b/examples/TinyAudio/b3ADSR.h index db3b088be..62d62479e 100644 --- a/examples/TinyAudio/b3ADSR.h +++ b/examples/TinyAudio/b3ADSR.h @@ -12,8 +12,8 @@ class b3ADSR double m_releaseTime; double m_sustainLevel; bool m_autoKeyOff; -public: +public: b3ADSR(); virtual ~b3ADSR(); @@ -22,14 +22,13 @@ public: void keyOn(bool autoKeyOff); void keyOff(); - void setValues(double attack,double decay,double sustain,double release) + void setValues(double attack, double decay, double sustain, double release) { m_attackRate = attack; m_decayRate = decay; m_sustainLevel = sustain; m_releaseRate = release; } - }; -#endif //B3_ADSR_H \ No newline at end of file +#endif //B3_ADSR_H \ No newline at end of file diff --git a/examples/TinyAudio/b3AudioListener.cpp b/examples/TinyAudio/b3AudioListener.cpp index 7c4238595..184b169ec 100644 --- a/examples/TinyAudio/b3AudioListener.cpp +++ b/examples/TinyAudio/b3AudioListener.cpp @@ -4,9 +4,9 @@ #include "b3WriteWavFile.h" template -inline const T& MyMin(const T& a, const T& b) +inline const T& MyMin(const T& a, const T& b) { - return a < b ? a : b ; + return a < b ? a : b; } #define MAX_SOUND_SOURCES 128 #define B3_SAMPLE_RATE 48000 @@ -18,17 +18,15 @@ struct b3AudioListenerInternalData b3SoundSource* m_soundSources[MAX_SOUND_SOURCES]; - b3WriteWavFile m_wavOut2; bool m_writeWavOut; b3AudioListenerInternalData() - :m_numControlTicks(64), - m_sampleRate(B3_SAMPLE_RATE), - m_writeWavOut(false) + : m_numControlTicks(64), + m_sampleRate(B3_SAMPLE_RATE), + m_writeWavOut(false) { - - for (int i=0;im_writeWavOut) { - m_data->m_wavOut2.setWavFile("bulletAudio2.wav",B3_SAMPLE_RATE,2,false); + m_data->m_wavOut2.setWavFile("bulletAudio2.wav", B3_SAMPLE_RATE, 2, false); } } @@ -58,9 +56,9 @@ int b3AudioListener::addSoundSource(b3SoundSource* source) { int soundIndex = -1; - for (int i=0;im_soundSources[i]==0) + if (m_data->m_soundSources[i] == 0) { m_data->m_soundSources[i] = source; soundIndex = i; @@ -72,9 +70,9 @@ int b3AudioListener::addSoundSource(b3SoundSource* source) void b3AudioListener::removeSoundSource(b3SoundSource* source) { - for (int i=0;im_soundSources[i]==source) + if (m_data->m_soundSources[i] == source) { m_data->m_soundSources[i] = 0; } @@ -101,69 +99,67 @@ void b3AudioListener::setSampleRate(double sampleRate) m_data->m_sampleRate = sampleRate; } - -int b3AudioListener::tick(void *outputBuffer,void *inputBuffer1,unsigned int nBufferFrames, - double streamTime,unsigned int status,void *dataPointer) +int b3AudioListener::tick(void* outputBuffer, void* inputBuffer1, unsigned int nBufferFrames, + double streamTime, unsigned int status, void* dataPointer) { B3_PROFILE("b3AudioListener::tick"); - b3AudioListenerInternalData *data = (b3AudioListenerInternalData *)dataPointer; - register double outs[2],*samples = (double *)outputBuffer; + b3AudioListenerInternalData* data = (b3AudioListenerInternalData*)dataPointer; + register double outs[2], *samples = (double*)outputBuffer; register double tempOuts[2]; - int counter,nTicks = (int)nBufferFrames; + int counter, nTicks = (int)nBufferFrames; bool done = false; - + int numSamples = 0; - while(nTicks > 0 && !done) + while (nTicks > 0 && !done) { - counter = MyMin(nTicks,data->m_numControlTicks); + counter = MyMin(nTicks, data->m_numControlTicks); bool newsynth = true; - if(newsynth) + if (newsynth) { - for(int i = 0; i < counter; i++) + for (int i = 0; i < counter; i++) { outs[0] = 0.; outs[1] = 0.; //make_sound_double(outs,1); - float numActiveSources = 0; + float numActiveSources = 0; - for (int i=0;im_soundSources[i]) { - if (data->m_soundSources[i]) - { - tempOuts[0] = 0; - tempOuts[1] = 0; + tempOuts[0] = 0; + tempOuts[1] = 0; - if (data->m_soundSources[i]->computeSamples(tempOuts,1, data->m_sampleRate)) - { - numActiveSources++; - //simple mixer - outs[0] += tempOuts[0]; - outs[1] += tempOuts[1]; - } + if (data->m_soundSources[i]->computeSamples(tempOuts, 1, data->m_sampleRate)) + { + numActiveSources++; + //simple mixer + outs[0] += tempOuts[0]; + outs[1] += tempOuts[1]; } } + } - //soft-clipping of sounds - outs[0] = tanh(outs[0]); - outs[1] = tanh(outs[1]); + //soft-clipping of sounds + outs[0] = tanh(outs[0]); + outs[1] = tanh(outs[1]); *samples++ = outs[0]; *samples++ = outs[1]; numSamples++; - } nTicks -= counter; } - if(nTicks == 0) + if (nTicks == 0) break; } //logging to wav file if (data->m_writeWavOut && numSamples) { - data->m_wavOut2.tick( (double *)outputBuffer,numSamples); + data->m_wavOut2.tick((double*)outputBuffer, numSamples); } return 0; } diff --git a/examples/TinyAudio/b3AudioListener.h b/examples/TinyAudio/b3AudioListener.h index d3378f4c4..46b33d43c 100644 --- a/examples/TinyAudio/b3AudioListener.h +++ b/examples/TinyAudio/b3AudioListener.h @@ -3,7 +3,6 @@ class b3SoundSource; - class b3AudioListener { struct b3AudioListenerInternalData* m_data; @@ -11,9 +10,9 @@ class b3AudioListener public: b3AudioListener(); virtual ~b3AudioListener(); - - static int tick(void *outputBuffer, void *inputBuffer1, unsigned int nBufferFrames, - double streamTime, unsigned int status, void *dataPointer); + + static int tick(void* outputBuffer, void* inputBuffer1, unsigned int nBufferFrames, + double streamTime, unsigned int status, void* dataPointer); int addSoundSource(b3SoundSource* source); void removeSoundSource(b3SoundSource* source); @@ -23,7 +22,6 @@ public: double getSampleRate() const; void setSampleRate(double sampleRate); +}; -}; - -#endif //B3_AUDIO_LISTENER_H \ No newline at end of file +#endif //B3_AUDIO_LISTENER_H \ No newline at end of file diff --git a/examples/TinyAudio/b3ReadWavFile.cpp b/examples/TinyAudio/b3ReadWavFile.cpp index c5e9ff14a..4e2b2f0dd 100644 --- a/examples/TinyAudio/b3ReadWavFile.cpp +++ b/examples/TinyAudio/b3ReadWavFile.cpp @@ -101,7 +101,7 @@ b3WavTicker b3ReadWavFile::createWavTicker(double sampleRate) bool b3ReadWavFile::getWavInfo(const char *fileName) { - fd_ = fopen(fileName,"rb"); + fd_ = fopen(fileName, "rb"); if (fd_ == 0) return false; diff --git a/examples/TinyAudio/b3ReadWavFile.h b/examples/TinyAudio/b3ReadWavFile.h index fb77dafb9..55c4f6a55 100644 --- a/examples/TinyAudio/b3ReadWavFile.h +++ b/examples/TinyAudio/b3ReadWavFile.h @@ -1,7 +1,6 @@ #ifndef B3_READ_WAV_FILE_H #define B3_READ_WAV_FILE_H - #include "Bullet3Common/b3AlignedObjectArray.h" #include #include @@ -14,8 +13,6 @@ struct b3WavTicker double rate_; }; - - class b3ReadWavFile { bool byteswap_; @@ -27,8 +24,8 @@ class b3ReadWavFile unsigned long dataOffset_; unsigned int channels_; bool m_machineIsLittleEndian; -public: +public: b3ReadWavFile(); virtual ~b3ReadWavFile(); @@ -47,11 +44,10 @@ public: bool read(unsigned long startFrame, bool doNormalize); - int getNumFrames() const + int getNumFrames() const { return m_numFrames; } }; - #endif //B3_READ_WAV_FILE_H diff --git a/examples/TinyAudio/b3SoundEngine.cpp b/examples/TinyAudio/b3SoundEngine.cpp index 34f92b876..e683bf19a 100644 --- a/examples/TinyAudio/b3SoundEngine.cpp +++ b/examples/TinyAudio/b3SoundEngine.cpp @@ -88,7 +88,7 @@ void b3SoundEngine::exit() } m_data->m_soundSources.clear(); - for (int i=0;im_wavFiles.size();i++) + for (int i = 0; i < m_data->m_wavFiles.size(); i++) { b3ReadWavFile** wavPtr = m_data->m_wavFiles.getAtIndex(i); if (wavPtr && *wavPtr) @@ -99,7 +99,6 @@ void b3SoundEngine::exit() } m_data->m_wavFiles.clear(); m_data->m_name2wav.clear(); - } int b3SoundEngine::getAvailableSoundSource() @@ -117,10 +116,10 @@ int b3SoundEngine::getAvailableSoundSource() void b3SoundEngine::startSound(int soundSourceIndex, b3SoundMessage msg) { b3SoundSource* soundSource = m_data->m_soundSources[soundSourceIndex]; - soundSource->setOscillatorAmplitude(0,msg.m_amplitude); - soundSource->setOscillatorAmplitude(1,msg.m_amplitude); + soundSource->setOscillatorAmplitude(0, msg.m_amplitude); + soundSource->setOscillatorAmplitude(1, msg.m_amplitude); - soundSource->setADSR(msg.m_attackRate,msg.m_decayRate,msg.m_sustainLevel,msg.m_releaseRate); + soundSource->setADSR(msg.m_attackRate, msg.m_decayRate, msg.m_sustainLevel, msg.m_releaseRate); switch (msg.m_type) { @@ -128,7 +127,7 @@ void b3SoundEngine::startSound(int soundSourceIndex, b3SoundMessage msg) { soundSource->setOscillatorFrequency(0, msg.m_frequency); soundSource->setOscillatorFrequency(1, msg.m_frequency); - + soundSource->startSound(msg.m_autoKeyOff); break; } @@ -138,8 +137,8 @@ void b3SoundEngine::startSound(int soundSourceIndex, b3SoundMessage msg) if (wavFilePtr) { b3ReadWavFile* wavFile = *wavFilePtr; - soundSource->setWavFile(0,wavFile,getSampleRate()); - soundSource->setWavFile(1,wavFile,getSampleRate()); + soundSource->setWavFile(0, wavFile, getSampleRate()); + soundSource->setWavFile(1, wavFile, getSampleRate()); soundSource->startSound(msg.m_autoKeyOff); } break; @@ -174,7 +173,7 @@ int b3SoundEngine::loadWavFile(const char* fileName) wavFile->normalize(1); int wavUID = m_data->m_wavFileUidGenerator++; m_data->m_wavFiles.insert(wavUID, wavFile); - m_data->m_name2wav.insert(fileName,wavUID); + m_data->m_name2wav.insert(fileName, wavUID); return wavUID; } return 0; diff --git a/examples/TinyAudio/b3SoundEngine.h b/examples/TinyAudio/b3SoundEngine.h index daf2df6b3..db2326cfc 100644 --- a/examples/TinyAudio/b3SoundEngine.h +++ b/examples/TinyAudio/b3SoundEngine.h @@ -6,7 +6,7 @@ struct b3SoundMessage { - int m_type;//B3_SOUND_SOURCE_TYPE + int m_type; //B3_SOUND_SOURCE_TYPE double m_amplitude; double m_frequency; @@ -19,15 +19,15 @@ struct b3SoundMessage bool m_autoKeyOff; b3SoundMessage() - :m_type(B3_SOUND_SOURCE_SINE_OSCILLATOR), - m_amplitude(0.5), - m_frequency(440), - m_wavId(-1), - m_attackRate(0.001), - m_decayRate(0.00001), - m_sustainLevel(0.5), - m_releaseRate(0.0005), - m_autoKeyOff(false) + : m_type(B3_SOUND_SOURCE_SINE_OSCILLATOR), + m_amplitude(0.5), + m_frequency(440), + m_wavId(-1), + m_attackRate(0.001), + m_decayRate(0.00001), + m_sustainLevel(0.5), + m_releaseRate(0.0005), + m_autoKeyOff(false) { } }; @@ -35,9 +35,8 @@ struct b3SoundMessage class b3SoundEngine { struct b3SoundEngineInternalData* m_data; - - public: - + +public: b3SoundEngine(); virtual ~b3SoundEngine(); @@ -51,7 +50,6 @@ class b3SoundEngine int loadWavFile(const char* fileName); double getSampleRate() const; - }; -#endif //B3_SOUND_ENGINE_H +#endif //B3_SOUND_ENGINE_H diff --git a/examples/TinyAudio/b3SoundSource.cpp b/examples/TinyAudio/b3SoundSource.cpp index 860692894..b8045bb97 100644 --- a/examples/TinyAudio/b3SoundSource.cpp +++ b/examples/TinyAudio/b3SoundSource.cpp @@ -1,9 +1,8 @@ #include "b3SoundSource.h" -#define MY2PI (2.*3.14159265) +#define MY2PI (2. * 3.14159265) #include - #include "Bullet3Common/b3FileUtils.h" #include "b3ReadWavFile.h" #include "b3ADSR.h" @@ -15,19 +14,18 @@ struct b3SoundOscillator double m_frequency; double m_amplitude; double m_phase; - - b3WavTicker m_wavTicker; + b3WavTicker m_wavTicker; double sampleSineWaveForm(double sampleRate) { while (m_phase >= MY2PI) m_phase -= MY2PI; - double z = sinf(m_phase); - double sample = m_amplitude*z; + double z = sinf(m_phase); + double sample = m_amplitude * z; - m_phase += MY2PI * (1./sampleRate) * m_frequency; + m_phase += MY2PI * (1. / sampleRate) * m_frequency; return sample; } @@ -36,10 +34,10 @@ struct b3SoundOscillator while (m_phase >= MY2PI) m_phase -= MY2PI; - double z = 2.*(m_phase)/MY2PI-1.; - double sample = m_amplitude*z; + double z = 2. * (m_phase) / MY2PI - 1.; + double sample = m_amplitude * z; - m_phase += MY2PI * (1./sampleRate) * m_frequency; + m_phase += MY2PI * (1. / sampleRate) * m_frequency; return sample; } @@ -49,12 +47,11 @@ struct b3SoundOscillator } b3SoundOscillator() - :m_type(0), - m_frequency(442.), - m_amplitude(1), - m_phase(0) + : m_type(0), + m_frequency(442.), + m_amplitude(1), + m_phase(0) { - } }; #define MAX_OSCILLATORS 2 @@ -65,7 +62,7 @@ struct b3SoundSourceInternalData b3ADSR m_envelope; b3ReadWavFile* m_wavFilePtr; b3SoundSourceInternalData() - :m_wavFilePtr(0) + : m_wavFilePtr(0) { } }; @@ -80,30 +77,28 @@ b3SoundSource::~b3SoundSource() delete m_data; } -void b3SoundSource::setADSR( double attack, double decay, double sustain, double release) +void b3SoundSource::setADSR(double attack, double decay, double sustain, double release) { - m_data->m_envelope.setValues(attack,decay,sustain,release); + m_data->m_envelope.setValues(attack, decay, sustain, release); } - bool b3SoundSource::computeSamples(double* sampleBuffer, int numSamples, double sampleRate) { - double* outputSamples = sampleBuffer; int numActive = 0; - for (int i=0;im_envelope.tick(); if (env) { - for (int osc=0;oscm_oscillators[osc].m_type == 0) { - samples[osc] += env * m_data->m_oscillators[osc].sampleSineWaveForm(sampleRate); + samples[osc] += env * m_data->m_oscillators[osc].sampleSineWaveForm(sampleRate); numActive++; } @@ -116,14 +111,15 @@ bool b3SoundSource::computeSamples(double* sampleBuffer, int numSamples, double if (m_data->m_oscillators[osc].m_type == 128) { int frame = 0; - double data = env * m_data->m_oscillators[osc].m_amplitude * m_data->m_wavFilePtr->tick(frame,&m_data->m_oscillators[osc].m_wavTicker); + double data = env * m_data->m_oscillators[osc].m_amplitude * m_data->m_wavFilePtr->tick(frame, &m_data->m_oscillators[osc].m_wavTicker); samples[osc] += data; numActive++; } - } - } else + } + } + else { - for (int osc=0;oscm_oscillators[osc].m_type == 128) { @@ -140,10 +136,10 @@ bool b3SoundSource::computeSamples(double* sampleBuffer, int numSamples, double } *outputSamples++ = sampleRight; - *outputSamples++ = sampleLeft ; + *outputSamples++ = sampleLeft; } -/* if (m_data->m_flags & looping) + /* if (m_data->m_flags & looping) { for (int osc=0;osc0; -// return false; + return numActive > 0; + // return false; } int b3SoundSource::getNumOscillators() const @@ -187,25 +183,24 @@ void b3SoundSource::startSound(bool autoKeyOff) { if (m_data->m_envelope.isIdle()) { - for (int osc=0;oscm_oscillators[osc].reset(); - if (m_data->m_oscillators[osc].m_type == B3_SOUND_SOURCE_WAV_FILE)// .m_wavTicker.finished_) + if (m_data->m_oscillators[osc].m_type == B3_SOUND_SOURCE_WAV_FILE) // .m_wavTicker.finished_) { - //test reverse playback of wav //m_data->m_oscillators[osc].m_wavTicker.rate_ *= -1; - if (m_data->m_oscillators[osc].m_wavTicker.rate_<0) + if (m_data->m_oscillators[osc].m_wavTicker.rate_ < 0) { - m_data->m_oscillators[osc].m_wavTicker.time_ = m_data->m_wavFilePtr->getNumFrames()-1.; - } else + m_data->m_oscillators[osc].m_wavTicker.time_ = m_data->m_wavFilePtr->getNumFrames() - 1.; + } + else { m_data->m_oscillators[osc].m_wavTicker.time_ = 0.f; } m_data->m_oscillators[osc].m_wavTicker.finished_ = false; - } } } @@ -217,21 +212,20 @@ void b3SoundSource::stopSound() m_data->m_envelope.keyOff(); } - bool b3SoundSource::setWavFile(int oscillatorIndex, b3ReadWavFile* wavFilePtr, int sampleRate) { { m_data->m_wavFilePtr = wavFilePtr; m_data->m_oscillators[oscillatorIndex].m_wavTicker = m_data->m_wavFilePtr->createWavTicker(sampleRate); -// waveIn.openFile(resourcePath); + // waveIn.openFile(resourcePath); double rate = 1.0; - // rate = waveIn.getFileRate() / stkSampleRate; - // waveIn.setRate( rate ); - // waveIn.ignoreSampleRateChange(); + // rate = waveIn.getFileRate() / stkSampleRate; + // waveIn.setRate( rate ); + // waveIn.ignoreSampleRateChange(); // Find out how many channels we have. - // int channels = waveIn.channelsOut(); - // m_data->m_oscillators[oscillatorIndex].m_frames.resize( 1, channels ); + // int channels = waveIn.channelsOut(); + // m_data->m_oscillators[oscillatorIndex].m_frames.resize( 1, channels ); m_data->m_oscillators[oscillatorIndex].m_type = 128; return true; } diff --git a/examples/TinyAudio/b3SoundSource.h b/examples/TinyAudio/b3SoundSource.h index af38a2183..227281261 100644 --- a/examples/TinyAudio/b3SoundSource.h +++ b/examples/TinyAudio/b3SoundSource.h @@ -3,24 +3,22 @@ #include "b3Sound_C_Api.h" - class b3SoundSource { struct b3SoundSourceInternalData* m_data; public: - b3SoundSource(); virtual ~b3SoundSource(); - - virtual bool computeSamples(double *sampleBuffer, int numSamples, double sampleRate); + + virtual bool computeSamples(double* sampleBuffer, int numSamples, double sampleRate); int getNumOscillators() const; void setOscillatorType(int oscillatorIndex, int type); void setOscillatorFrequency(int oscillatorIndex, double frequency); void setOscillatorAmplitude(int oscillatorIndex, double amplitude); void setOscillatorPhase(int oscillatorIndex, double phase); - void setADSR( double attackRate, double decayRate, double sustainLevel, double releaseRate); + void setADSR(double attackRate, double decayRate, double sustainLevel, double releaseRate); bool setWavFile(int oscillatorIndex, class b3ReadWavFile* wavFilePtr, int sampleRate); @@ -30,4 +28,4 @@ public: bool isAvailable() const; }; -#endif //B3_SOUND_SOURCE_H +#endif //B3_SOUND_SOURCE_H diff --git a/examples/TinyAudio/b3Sound_C_Api.h b/examples/TinyAudio/b3Sound_C_Api.h index 15b1bfc0b..95305410f 100644 --- a/examples/TinyAudio/b3Sound_C_Api.h +++ b/examples/TinyAudio/b3Sound_C_Api.h @@ -12,20 +12,18 @@ enum B3_SOUND_SOURCE_TYPE { - B3_SOUND_SOURCE_SINE_OSCILLATOR=1, + B3_SOUND_SOURCE_SINE_OSCILLATOR = 1, B3_SOUND_SOURCE_SAW_OSCILLATOR, B3_SOUND_SOURCE_WAV_FILE, }; - #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif - - #ifdef __cplusplus } #endif -#endif///B3_SOUND_C_API_H +#endif ///B3_SOUND_C_API_H diff --git a/examples/TinyAudio/b3SwapUtils.h b/examples/TinyAudio/b3SwapUtils.h index 32fc1a28f..8bef80b05 100644 --- a/examples/TinyAudio/b3SwapUtils.h +++ b/examples/TinyAudio/b3SwapUtils.h @@ -3,31 +3,30 @@ inline void b3Swap16(unsigned char *ptr) { - unsigned char val; + unsigned char val; - // Swap 1st and 2nd bytes - val = *(ptr); - *(ptr) = *(ptr+1); - *(ptr+1) = val; + // Swap 1st and 2nd bytes + val = *(ptr); + *(ptr) = *(ptr + 1); + *(ptr + 1) = val; } inline void b3Swap32(unsigned char *ptr) { - unsigned char val; + unsigned char val; - // Swap 1st and 4th bytes - val = *(ptr); - *(ptr) = *(ptr+3); - *(ptr+3) = val; + // Swap 1st and 4th bytes + val = *(ptr); + *(ptr) = *(ptr + 3); + *(ptr + 3) = val; - //Swap 2nd and 3rd bytes - ptr += 1; - val = *(ptr); - *(ptr) = *(ptr+1); - *(ptr+1) = val; + //Swap 2nd and 3rd bytes + ptr += 1; + val = *(ptr); + *(ptr) = *(ptr + 1); + *(ptr + 1) = val; } - inline void b3Swap64(unsigned char *ptr) { unsigned char val; @@ -56,4 +55,4 @@ inline void b3Swap64(unsigned char *ptr) *(ptr + 1) = val; } -#endif //B3_SWAP_UTILS_H +#endif //B3_SWAP_UTILS_H diff --git a/examples/TinyAudio/b3WriteWavFile.cpp b/examples/TinyAudio/b3WriteWavFile.cpp index e95a27d3b..30a9d1339 100644 --- a/examples/TinyAudio/b3WriteWavFile.cpp +++ b/examples/TinyAudio/b3WriteWavFile.cpp @@ -153,15 +153,14 @@ bool b3WriteWavFile::setWavFile(std::string fileName, int sampleRate, int numCha char data[4] = {'d', 'a', 't', 'a'}; int dataSize = 0; - if (fwrite(&hdr, 1, bytesToWrite, m_data->m_file) != bytesToWrite) + if (fwrite(&hdr, 1, bytesToWrite, m_data->m_file) != bytesToWrite) return false; - if (fwrite(&data, 4, 1, m_data->m_file) != 1) + if (fwrite(&data, 4, 1, m_data->m_file) != 1) return false; - if (fwrite(&dataSize, 4, 1, m_data->m_file) != 1) + if (fwrite(&dataSize, 4, 1, m_data->m_file) != 1) return false; - - return true; + return true; } void b3WriteWavFile::closeWavFile() diff --git a/examples/TinyAudio/b3WriteWavFile.h b/examples/TinyAudio/b3WriteWavFile.h index 143bcba26..3dc2bd954 100644 --- a/examples/TinyAudio/b3WriteWavFile.h +++ b/examples/TinyAudio/b3WriteWavFile.h @@ -8,7 +8,7 @@ class b3WriteWavFile { - void incrementFrame( void ); + void incrementFrame(void); void flush(); struct b3WriteWavFileInternalData* m_data; @@ -16,17 +16,14 @@ class b3WriteWavFile void flushData(int bufferSize); public: - b3WriteWavFile(); virtual ~b3WriteWavFile(); - bool setWavFile(std::string fileName, int sampleRate, int numChannels, bool useDoublePrecision=true); + bool setWavFile(std::string fileName, int sampleRate, int numChannels, bool useDoublePrecision = true); void closeWavFile(); - void tick( double* values, int numValues ); - - + void tick(double* values, int numValues); }; #endif //B3_WRITE_WAV_FILE_H diff --git a/examples/TinyRenderer/TinyRenderer.cpp b/examples/TinyRenderer/TinyRenderer.cpp index 824791d55..647c5eb1d 100644 --- a/examples/TinyRenderer/TinyRenderer.cpp +++ b/examples/TinyRenderer/TinyRenderer.cpp @@ -14,278 +14,275 @@ #include "LinearMath/btVector3.h" #include "Bullet3Common/b3Logging.h" -struct DepthShader : public IShader { - - Model* m_model; - Matrix& m_modelMat; - Matrix m_invModelMat; - - Matrix& m_projectionMat; - Vec3f m_localScaling; - Matrix& m_lightModelView; - float m_lightDistance; - - mat<2,3,float> varying_uv; // triangle uv coordinates, written by the vertex shader, read by the fragment shader - mat<4,3,float> varying_tri; // triangle coordinates (clip coordinates), written by VS, read by FS - - mat<3,3,float> varying_nrm; // normal per vertex to be interpolated by FS - - DepthShader(Model* model, Matrix& lightModelView, Matrix& projectionMat, Matrix& modelMat, Vec3f localScaling, float lightDistance) - :m_model(model), - m_modelMat(modelMat), - m_projectionMat(projectionMat), - m_localScaling(localScaling), - m_lightModelView(lightModelView), - m_lightDistance(lightDistance) - { - m_nearPlane = m_projectionMat.col(3)[2]/(m_projectionMat.col(2)[2]-1); - m_farPlane = m_projectionMat.col(3)[2]/(m_projectionMat.col(2)[2]+1); +struct DepthShader : public IShader +{ + Model* m_model; + Matrix& m_modelMat; + Matrix m_invModelMat; - m_invModelMat = m_modelMat.invert_transpose(); - } - virtual Vec4f vertex(int iface, int nthvert) { - Vec2f uv = m_model->uv(iface, nthvert); - varying_uv.set_col(nthvert, uv); - varying_nrm.set_col(nthvert, proj<3>(m_invModelMat*embed<4>(m_model->normal(iface, nthvert), 0.f))); - Vec3f unScaledVert = m_model->vert(iface, nthvert); - Vec3f scaledVert=Vec3f(unScaledVert[0]*m_localScaling[0], - unScaledVert[1]*m_localScaling[1], - unScaledVert[2]*m_localScaling[2]); - Vec4f gl_Vertex = m_projectionMat*m_lightModelView*embed<4>(scaledVert); - varying_tri.set_col(nthvert, gl_Vertex); - return gl_Vertex; - } - - virtual bool fragment(Vec3f bar, TGAColor &color) { - Vec4f p = varying_tri*bar; - color = TGAColor(255, 255, 255)*(p[2]/m_lightDistance); - return false; - } + Matrix& m_projectionMat; + Vec3f m_localScaling; + Matrix& m_lightModelView; + float m_lightDistance; + + mat<2, 3, float> varying_uv; // triangle uv coordinates, written by the vertex shader, read by the fragment shader + mat<4, 3, float> varying_tri; // triangle coordinates (clip coordinates), written by VS, read by FS + + mat<3, 3, float> varying_nrm; // normal per vertex to be interpolated by FS + + DepthShader(Model* model, Matrix& lightModelView, Matrix& projectionMat, Matrix& modelMat, Vec3f localScaling, float lightDistance) + : m_model(model), + m_modelMat(modelMat), + m_projectionMat(projectionMat), + m_localScaling(localScaling), + m_lightModelView(lightModelView), + m_lightDistance(lightDistance) + { + m_nearPlane = m_projectionMat.col(3)[2] / (m_projectionMat.col(2)[2] - 1); + m_farPlane = m_projectionMat.col(3)[2] / (m_projectionMat.col(2)[2] + 1); + + m_invModelMat = m_modelMat.invert_transpose(); + } + virtual Vec4f vertex(int iface, int nthvert) + { + Vec2f uv = m_model->uv(iface, nthvert); + varying_uv.set_col(nthvert, uv); + varying_nrm.set_col(nthvert, proj<3>(m_invModelMat * embed<4>(m_model->normal(iface, nthvert), 0.f))); + Vec3f unScaledVert = m_model->vert(iface, nthvert); + Vec3f scaledVert = Vec3f(unScaledVert[0] * m_localScaling[0], + unScaledVert[1] * m_localScaling[1], + unScaledVert[2] * m_localScaling[2]); + Vec4f gl_Vertex = m_projectionMat * m_lightModelView * embed<4>(scaledVert); + varying_tri.set_col(nthvert, gl_Vertex); + return gl_Vertex; + } + + virtual bool fragment(Vec3f bar, TGAColor& color) + { + Vec4f p = varying_tri * bar; + color = TGAColor(255, 255, 255) * (p[2] / m_lightDistance); + return false; + } }; -struct Shader : public IShader { - - Model* m_model; - Vec3f m_light_dir_local; - Vec3f m_light_color; - Matrix& m_modelMat; - Matrix m_invModelMat; - Matrix& m_modelView1; - Matrix& m_projectionMat; - Vec3f m_localScaling; - Matrix& m_lightModelView; - Vec4f m_colorRGBA; - Matrix& m_viewportMat; +struct Shader : public IShader +{ + Model* m_model; + Vec3f m_light_dir_local; + Vec3f m_light_color; + Matrix& m_modelMat; + Matrix m_invModelMat; + Matrix& m_modelView1; + Matrix& m_projectionMat; + Vec3f m_localScaling; + Matrix& m_lightModelView; + Vec4f m_colorRGBA; + Matrix& m_viewportMat; Matrix m_projectionModelViewMat; Matrix m_projectionLightViewMat; - float m_ambient_coefficient; - float m_diffuse_coefficient; - float m_specular_coefficient; - - b3AlignedObjectArray* m_shadowBuffer; - - int m_width; - int m_height; - - int m_index; - - mat<2,3,float> varying_uv; // triangle uv coordinates, written by the vertex shader, read by the fragment shader - mat<4,3,float> varying_tri; // triangle coordinates (clip coordinates), written by VS, read by FS - mat<4,3,float> varying_tri_light_view; - mat<3,3,float> varying_nrm; // normal per vertex to be interpolated by FS - mat<4,3,float> world_tri; // model triangle coordinates in the world space used for backface culling, written by VS - + float m_ambient_coefficient; + float m_diffuse_coefficient; + float m_specular_coefficient; - Shader(Model* model, Vec3f light_dir_local, Vec3f light_color, Matrix& modelView, Matrix& lightModelView, Matrix& projectionMat, Matrix& modelMat, Matrix& viewportMat, Vec3f localScaling, const Vec4f& colorRGBA, int width, int height, b3AlignedObjectArray* shadowBuffer, float ambient_coefficient=0.6, float diffuse_coefficient=0.35, float specular_coefficient=0.05) - :m_model(model), - m_light_dir_local(light_dir_local), - m_light_color(light_color), - m_modelMat(modelMat), - m_modelView1(modelView), - m_projectionMat(projectionMat), - m_localScaling(localScaling), - m_lightModelView(lightModelView), - m_colorRGBA(colorRGBA), - m_viewportMat(viewportMat), - m_ambient_coefficient(ambient_coefficient), - m_diffuse_coefficient(diffuse_coefficient), - m_specular_coefficient(specular_coefficient), + b3AlignedObjectArray* m_shadowBuffer; - m_shadowBuffer(shadowBuffer), - m_width(width), - m_height(height) - - { - m_nearPlane = m_projectionMat.col(3)[2]/(m_projectionMat.col(2)[2]-1); - m_farPlane = m_projectionMat.col(3)[2]/(m_projectionMat.col(2)[2]+1); + int m_width; + int m_height; + + int m_index; + + mat<2, 3, float> varying_uv; // triangle uv coordinates, written by the vertex shader, read by the fragment shader + mat<4, 3, float> varying_tri; // triangle coordinates (clip coordinates), written by VS, read by FS + mat<4, 3, float> varying_tri_light_view; + mat<3, 3, float> varying_nrm; // normal per vertex to be interpolated by FS + mat<4, 3, float> world_tri; // model triangle coordinates in the world space used for backface culling, written by VS + + Shader(Model* model, Vec3f light_dir_local, Vec3f light_color, Matrix& modelView, Matrix& lightModelView, Matrix& projectionMat, Matrix& modelMat, Matrix& viewportMat, Vec3f localScaling, const Vec4f& colorRGBA, int width, int height, b3AlignedObjectArray* shadowBuffer, float ambient_coefficient = 0.6, float diffuse_coefficient = 0.35, float specular_coefficient = 0.05) + : m_model(model), + m_light_dir_local(light_dir_local), + m_light_color(light_color), + m_modelMat(modelMat), + m_modelView1(modelView), + m_projectionMat(projectionMat), + m_localScaling(localScaling), + m_lightModelView(lightModelView), + m_colorRGBA(colorRGBA), + m_viewportMat(viewportMat), + m_ambient_coefficient(ambient_coefficient), + m_diffuse_coefficient(diffuse_coefficient), + m_specular_coefficient(specular_coefficient), + + m_shadowBuffer(shadowBuffer), + m_width(width), + m_height(height) + + { + m_nearPlane = m_projectionMat.col(3)[2] / (m_projectionMat.col(2)[2] - 1); + m_farPlane = m_projectionMat.col(3)[2] / (m_projectionMat.col(2)[2] + 1); //printf("near=%f, far=%f\n", m_nearPlane, m_farPlane); - m_invModelMat = m_modelMat.invert_transpose(); - m_projectionModelViewMat = m_projectionMat*m_modelView1; - m_projectionLightViewMat = m_projectionMat*m_lightModelView; - } - virtual Vec4f vertex(int iface, int nthvert) { + m_invModelMat = m_modelMat.invert_transpose(); + m_projectionModelViewMat = m_projectionMat * m_modelView1; + m_projectionLightViewMat = m_projectionMat * m_lightModelView; + } + virtual Vec4f vertex(int iface, int nthvert) + { //B3_PROFILE("vertex"); - Vec2f uv = m_model->uv(iface, nthvert); - varying_uv.set_col(nthvert, uv); - varying_nrm.set_col(nthvert, proj<3>(m_invModelMat*embed<4>(m_model->normal(iface, nthvert), 0.f))); - Vec3f unScaledVert = m_model->vert(iface, nthvert); - Vec3f scaledVert=Vec3f(unScaledVert[0]*m_localScaling[0], - unScaledVert[1]*m_localScaling[1], - unScaledVert[2]*m_localScaling[2]); - Vec4f gl_Vertex = m_projectionModelViewMat*embed<4>(scaledVert); - varying_tri.set_col(nthvert, gl_Vertex); - Vec4f world_Vertex = m_modelMat*embed<4>(scaledVert); + Vec2f uv = m_model->uv(iface, nthvert); + varying_uv.set_col(nthvert, uv); + varying_nrm.set_col(nthvert, proj<3>(m_invModelMat * embed<4>(m_model->normal(iface, nthvert), 0.f))); + Vec3f unScaledVert = m_model->vert(iface, nthvert); + Vec3f scaledVert = Vec3f(unScaledVert[0] * m_localScaling[0], + unScaledVert[1] * m_localScaling[1], + unScaledVert[2] * m_localScaling[2]); + Vec4f gl_Vertex = m_projectionModelViewMat * embed<4>(scaledVert); + varying_tri.set_col(nthvert, gl_Vertex); + Vec4f world_Vertex = m_modelMat * embed<4>(scaledVert); world_tri.set_col(nthvert, world_Vertex); - Vec4f gl_VertexLightView = m_projectionLightViewMat*embed<4>(scaledVert); - varying_tri_light_view.set_col(nthvert, gl_VertexLightView); - return gl_Vertex; - } - - virtual bool fragment(Vec3f bar, TGAColor &color) { - //B3_PROFILE("fragment"); - Vec4f p = m_viewportMat*(varying_tri_light_view*bar); - float depth = p[2]; - p = p/p[3]; - - float index_x = b3Max(float(0.0), b3Min(float(m_width-1), p[0])); - float index_y = b3Max(float(0.0), b3Min(float(m_height-1), p[1])); - int idx = int(index_x) + int(index_y)*m_width; // index in the shadowbuffer array - float shadow = 0.8+0.2*(m_shadowBuffer->at(idx)<-depth+0.05); // magic coeff to avoid z-fighting - - Vec3f bn = (varying_nrm*bar).normalize(); - Vec2f uv = varying_uv*bar; - - Vec3f reflection_direction = (bn * (bn * m_light_dir_local * 2.f) - m_light_dir_local).normalize(); - float specular = pow(b3Max(reflection_direction.z, 0.f), m_model->specular(uv)); - float diffuse = b3Max(0.f, bn * m_light_dir_local); - - color = m_model->diffuse(uv); - color[0] *= m_colorRGBA[0]; - color[1] *= m_colorRGBA[1]; - color[2] *= m_colorRGBA[2]; - color[3] *= m_colorRGBA[3]; - - for (int i = 0; i < 3; ++i) - { - color[i] = b3Min(int(m_ambient_coefficient*color[i] + shadow*(m_diffuse_coefficient*diffuse+m_specular_coefficient*specular)*color[i]*m_light_color[i]), 255); - } - - return false; + Vec4f gl_VertexLightView = m_projectionLightViewMat * embed<4>(scaledVert); + varying_tri_light_view.set_col(nthvert, gl_VertexLightView); + return gl_Vertex; + } - } + virtual bool fragment(Vec3f bar, TGAColor& color) + { + //B3_PROFILE("fragment"); + Vec4f p = m_viewportMat * (varying_tri_light_view * bar); + float depth = p[2]; + p = p / p[3]; + + float index_x = b3Max(float(0.0), b3Min(float(m_width - 1), p[0])); + float index_y = b3Max(float(0.0), b3Min(float(m_height - 1), p[1])); + int idx = int(index_x) + int(index_y) * m_width; // index in the shadowbuffer array + float shadow = 0.8 + 0.2 * (m_shadowBuffer->at(idx) < -depth + 0.05); // magic coeff to avoid z-fighting + + Vec3f bn = (varying_nrm * bar).normalize(); + Vec2f uv = varying_uv * bar; + + Vec3f reflection_direction = (bn * (bn * m_light_dir_local * 2.f) - m_light_dir_local).normalize(); + float specular = pow(b3Max(reflection_direction.z, 0.f), m_model->specular(uv)); + float diffuse = b3Max(0.f, bn * m_light_dir_local); + + color = m_model->diffuse(uv); + color[0] *= m_colorRGBA[0]; + color[1] *= m_colorRGBA[1]; + color[2] *= m_colorRGBA[2]; + color[3] *= m_colorRGBA[3]; + + for (int i = 0; i < 3; ++i) + { + color[i] = b3Min(int(m_ambient_coefficient * color[i] + shadow * (m_diffuse_coefficient * diffuse + m_specular_coefficient * specular) * color[i] * m_light_color[i]), 255); + } + + return false; + } }; -TinyRenderObjectData::TinyRenderObjectData(TGAImage& rgbColorBuffer,b3AlignedObjectArray&depthBuffer,b3AlignedObjectArray* shadowBuffer) -: -m_model(0), -m_rgbColorBuffer(rgbColorBuffer), -m_depthBuffer(depthBuffer), -m_shadowBuffer(shadowBuffer), -m_segmentationMaskBufferPtr(0), -m_userData(0), -m_userIndex(-1), -m_objectIndex(-1) +TinyRenderObjectData::TinyRenderObjectData(TGAImage& rgbColorBuffer, b3AlignedObjectArray& depthBuffer, b3AlignedObjectArray* shadowBuffer) + : m_model(0), + m_rgbColorBuffer(rgbColorBuffer), + m_depthBuffer(depthBuffer), + m_shadowBuffer(shadowBuffer), + m_segmentationMaskBufferPtr(0), + m_userData(0), + m_userIndex(-1), + m_objectIndex(-1) { - Vec3f eye(1,1,3); - Vec3f center(0,0,0); - Vec3f up(0,0,1); - m_lightDirWorld.setValue(0,0,0); - m_lightColor.setValue(1, 1, 1); - m_localScaling.setValue(1,1,1); - m_modelMatrix = Matrix::identity(); - m_lightAmbientCoeff = 0.6; - m_lightDiffuseCoeff = 0.35; - m_lightSpecularCoeff = 0.05; - -} - -TinyRenderObjectData::TinyRenderObjectData(TGAImage& rgbColorBuffer,b3AlignedObjectArray&depthBuffer, b3AlignedObjectArray* shadowBuffer, b3AlignedObjectArray* segmentationMaskBuffer, int objectIndex, int linkIndex) -:m_model(0), -m_rgbColorBuffer(rgbColorBuffer), -m_depthBuffer(depthBuffer), -m_shadowBuffer(shadowBuffer), -m_segmentationMaskBufferPtr(segmentationMaskBuffer), -m_userData(0), -m_userIndex(-1), -m_objectIndex(objectIndex), -m_linkIndex(linkIndex) -{ - Vec3f eye(1,1,3); - Vec3f center(0,0,0); - Vec3f up(0,0,1); - m_lightDirWorld.setValue(0,0,0); - m_lightColor.setValue(1, 1, 1); - m_localScaling.setValue(1,1,1); - m_modelMatrix = Matrix::identity(); - m_lightAmbientCoeff = 0.6; - m_lightDiffuseCoeff = 0.35; - m_lightSpecularCoeff = 0.05; - -} - -TinyRenderObjectData::TinyRenderObjectData(TGAImage& rgbColorBuffer,b3AlignedObjectArray&depthBuffer) -:m_model(0), -m_rgbColorBuffer(rgbColorBuffer), -m_depthBuffer(depthBuffer), -m_segmentationMaskBufferPtr(0), -m_userData(0), -m_userIndex(-1), -m_objectIndex(-1) -{ - Vec3f eye(1,1,3); - Vec3f center(0,0,0); - Vec3f up(0,0,1); - m_lightDirWorld.setValue(0,0,0); + Vec3f eye(1, 1, 3); + Vec3f center(0, 0, 0); + Vec3f up(0, 0, 1); + m_lightDirWorld.setValue(0, 0, 0); m_lightColor.setValue(1, 1, 1); - m_localScaling.setValue(1,1,1); - m_modelMatrix = Matrix::identity(); - m_lightAmbientCoeff = 0.6; - m_lightDiffuseCoeff = 0.35; - m_lightSpecularCoeff = 0.05; - + m_localScaling.setValue(1, 1, 1); + m_modelMatrix = Matrix::identity(); + m_lightAmbientCoeff = 0.6; + m_lightDiffuseCoeff = 0.35; + m_lightSpecularCoeff = 0.05; } -TinyRenderObjectData::TinyRenderObjectData(TGAImage& rgbColorBuffer,b3AlignedObjectArray&depthBuffer, b3AlignedObjectArray* segmentationMaskBuffer, int objectIndex) -:m_model(0), -m_rgbColorBuffer(rgbColorBuffer), -m_depthBuffer(depthBuffer), -m_segmentationMaskBufferPtr(segmentationMaskBuffer), -m_userData(0), -m_userIndex(-1), -m_objectIndex(objectIndex) +TinyRenderObjectData::TinyRenderObjectData(TGAImage& rgbColorBuffer, b3AlignedObjectArray& depthBuffer, b3AlignedObjectArray* shadowBuffer, b3AlignedObjectArray* segmentationMaskBuffer, int objectIndex, int linkIndex) + : m_model(0), + m_rgbColorBuffer(rgbColorBuffer), + m_depthBuffer(depthBuffer), + m_shadowBuffer(shadowBuffer), + m_segmentationMaskBufferPtr(segmentationMaskBuffer), + m_userData(0), + m_userIndex(-1), + m_objectIndex(objectIndex), + m_linkIndex(linkIndex) { - Vec3f eye(1,1,3); - Vec3f center(0,0,0); - Vec3f up(0,0,1); - m_lightDirWorld.setValue(0,0,0); + Vec3f eye(1, 1, 3); + Vec3f center(0, 0, 0); + Vec3f up(0, 0, 1); + m_lightDirWorld.setValue(0, 0, 0); m_lightColor.setValue(1, 1, 1); - m_localScaling.setValue(1,1,1); - m_modelMatrix = Matrix::identity(); - m_lightAmbientCoeff = 0.6; - m_lightDiffuseCoeff = 0.35; - m_lightSpecularCoeff = 0.05; - + m_localScaling.setValue(1, 1, 1); + m_modelMatrix = Matrix::identity(); + m_lightAmbientCoeff = 0.6; + m_lightDiffuseCoeff = 0.35; + m_lightSpecularCoeff = 0.05; +} + +TinyRenderObjectData::TinyRenderObjectData(TGAImage& rgbColorBuffer, b3AlignedObjectArray& depthBuffer) + : m_model(0), + m_rgbColorBuffer(rgbColorBuffer), + m_depthBuffer(depthBuffer), + m_segmentationMaskBufferPtr(0), + m_userData(0), + m_userIndex(-1), + m_objectIndex(-1) +{ + Vec3f eye(1, 1, 3); + Vec3f center(0, 0, 0); + Vec3f up(0, 0, 1); + m_lightDirWorld.setValue(0, 0, 0); + m_lightColor.setValue(1, 1, 1); + m_localScaling.setValue(1, 1, 1); + m_modelMatrix = Matrix::identity(); + m_lightAmbientCoeff = 0.6; + m_lightDiffuseCoeff = 0.35; + m_lightSpecularCoeff = 0.05; +} + +TinyRenderObjectData::TinyRenderObjectData(TGAImage& rgbColorBuffer, b3AlignedObjectArray& depthBuffer, b3AlignedObjectArray* segmentationMaskBuffer, int objectIndex) + : m_model(0), + m_rgbColorBuffer(rgbColorBuffer), + m_depthBuffer(depthBuffer), + m_segmentationMaskBufferPtr(segmentationMaskBuffer), + m_userData(0), + m_userIndex(-1), + m_objectIndex(objectIndex) +{ + Vec3f eye(1, 1, 3); + Vec3f center(0, 0, 0); + Vec3f up(0, 0, 1); + m_lightDirWorld.setValue(0, 0, 0); + m_lightColor.setValue(1, 1, 1); + m_localScaling.setValue(1, 1, 1); + m_modelMatrix = Matrix::identity(); + m_lightAmbientCoeff = 0.6; + m_lightDiffuseCoeff = 0.35; + m_lightSpecularCoeff = 0.05; } void TinyRenderObjectData::loadModel(const char* fileName) { - //todo(erwincoumans) move the file loading out of here - char relativeFileName[1024]; - if (!b3ResourcePath::findResourcePath(fileName, relativeFileName, 1024)) - { - printf("Cannot find file %s\n", fileName); - } else - { - m_model = new Model(relativeFileName); - } + //todo(erwincoumans) move the file loading out of here + char relativeFileName[1024]; + if (!b3ResourcePath::findResourcePath(fileName, relativeFileName, 1024)) + { + printf("Cannot find file %s\n", fileName); + } + else + { + m_model = new Model(relativeFileName); + } } - -void TinyRenderObjectData::registerMeshShape(const float* vertices, int numVertices,const int* indices, int numIndices, const float rgbaColor[4], - unsigned char* textureImage, int textureWidth, int textureHeight) +void TinyRenderObjectData::registerMeshShape(const float* vertices, int numVertices, const int* indices, int numIndices, const float rgbaColor[4], + unsigned char* textureImage, int textureWidth, int textureHeight) { - if (0==m_model) - { + if (0 == m_model) + { { B3_PROFILE("setColorRGBA"); @@ -298,7 +295,8 @@ void TinyRenderObjectData::registerMeshShape(const float* vertices, int numVerti B3_PROFILE("setDiffuseTextureFromData"); m_model->setDiffuseTextureFromData(textureImage, textureWidth, textureHeight); } - } else + } + else { /*char relativeFileName[1024]; if (b3ResourcePath::findResourcePath("floor_diffuse.tga", relativeFileName, 1024)) @@ -316,13 +314,13 @@ void TinyRenderObjectData::registerMeshShape(const float* vertices, int numVerti for (int i = 0; i < numVertices; i++) { m_model->addVertex(vertices[i * 9], - vertices[i * 9 + 1], - vertices[i * 9 + 2], - vertices[i * 9 + 4], - vertices[i * 9 + 5], - vertices[i * 9 + 6], - vertices[i * 9 + 7], - vertices[i * 9 + 8]); + vertices[i * 9 + 1], + vertices[i * 9 + 2], + vertices[i * 9 + 4], + vertices[i * 9 + 5], + vertices[i * 9 + 6], + vertices[i * 9 + 7], + vertices[i * 9 + 8]); } } { @@ -330,84 +328,82 @@ void TinyRenderObjectData::registerMeshShape(const float* vertices, int numVerti for (int i = 0; i < numIndices; i += 3) { m_model->addTriangle(indices[i], indices[i], indices[i], - indices[i + 1], indices[i + 1], indices[i + 1], - indices[i + 2], indices[i + 2], indices[i + 2]); + indices[i + 1], indices[i + 1], indices[i + 1], + indices[i + 2], indices[i + 2], indices[i + 2]); } } - } + } } -void TinyRenderObjectData::registerMesh2(btAlignedObjectArray& vertices, btAlignedObjectArray& normals,btAlignedObjectArray& indices) +void TinyRenderObjectData::registerMesh2(btAlignedObjectArray& vertices, btAlignedObjectArray& normals, btAlignedObjectArray& indices) { - if (0==m_model) - { + if (0 == m_model) + { int numVertices = vertices.size(); int numIndices = indices.size(); - m_model = new Model(); + m_model = new Model(); char relativeFileName[1024]; if (b3ResourcePath::findResourcePath("floor_diffuse.tga", relativeFileName, 1024)) { m_model->loadDiffuseTexture(relativeFileName); } - - for (int i=0;iaddVertex(vertices[i].x(), - vertices[i].y(), - vertices[i].z(), - normals[i].x(), - normals[i].y(), - normals[i].z(), - 0.5,0.5); - } - for (int i=0;iaddTriangle(indices[i],indices[i],indices[i], - indices[i+1],indices[i+1],indices[i+1], - indices[i+2],indices[i+2],indices[i+2]); - } - } + + for (int i = 0; i < numVertices; i++) + { + m_model->addVertex(vertices[i].x(), + vertices[i].y(), + vertices[i].z(), + normals[i].x(), + normals[i].y(), + normals[i].z(), + 0.5, 0.5); + } + for (int i = 0; i < numIndices; i += 3) + { + m_model->addTriangle(indices[i], indices[i], indices[i], + indices[i + 1], indices[i + 1], indices[i + 1], + indices[i + 2], indices[i + 2], indices[i + 2]); + } + } } -void TinyRenderObjectData::createCube(float halfExtentsX,float halfExtentsY,float halfExtentsZ) +void TinyRenderObjectData::createCube(float halfExtentsX, float halfExtentsY, float halfExtentsZ) { - m_model = new Model(); - - char relativeFileName[1024]; - if (b3ResourcePath::findResourcePath("floor_diffuse.tga", relativeFileName, 1024)) - { - m_model->loadDiffuseTexture(relativeFileName); - } - + m_model = new Model(); - int strideInBytes = 9*sizeof(float); - int numVertices = sizeof(cube_vertices_textured)/strideInBytes; - int numIndices = sizeof(cube_indices)/sizeof(int); - - for (int i=0;iaddVertex(halfExtentsX*cube_vertices_textured[i*9], - halfExtentsY*cube_vertices_textured[i*9+1], - halfExtentsY*cube_vertices_textured[i*9+2], - cube_vertices_textured[i*9+4], - cube_vertices_textured[i*9+5], - cube_vertices_textured[i*9+6], - cube_vertices_textured[i*9+7], - cube_vertices_textured[i*9+8]); + m_model->loadDiffuseTexture(relativeFileName); + } + + int strideInBytes = 9 * sizeof(float); + int numVertices = sizeof(cube_vertices_textured) / strideInBytes; + int numIndices = sizeof(cube_indices) / sizeof(int); + + for (int i = 0; i < numVertices; i++) + { + m_model->addVertex(halfExtentsX * cube_vertices_textured[i * 9], + halfExtentsY * cube_vertices_textured[i * 9 + 1], + halfExtentsY * cube_vertices_textured[i * 9 + 2], + cube_vertices_textured[i * 9 + 4], + cube_vertices_textured[i * 9 + 5], + cube_vertices_textured[i * 9 + 6], + cube_vertices_textured[i * 9 + 7], + cube_vertices_textured[i * 9 + 8]); + } + for (int i = 0; i < numIndices; i += 3) + { + m_model->addTriangle(cube_indices[i], cube_indices[i], cube_indices[i], + cube_indices[i + 1], cube_indices[i + 1], cube_indices[i + 1], + cube_indices[i + 2], cube_indices[i + 2], cube_indices[i + 2]); } - for (int i=0;iaddTriangle(cube_indices[i],cube_indices[i],cube_indices[i], - cube_indices[i+1],cube_indices[i+1],cube_indices[i+1], - cube_indices[i+2],cube_indices[i+2],cube_indices[i+2]); - } - } TinyRenderObjectData::~TinyRenderObjectData() { - delete m_model; + delete m_model; } static bool equals(const Vec4f& vA, const Vec4f& vB) @@ -415,36 +411,38 @@ static bool equals(const Vec4f& vA, const Vec4f& vB) return false; } -static void clipEdge(const mat<4,3,float>& triangleIn, int vertexIndexA, int vertexIndexB, b3AlignedObjectArray& vertices) +static void clipEdge(const mat<4, 3, float>& triangleIn, int vertexIndexA, int vertexIndexB, b3AlignedObjectArray& vertices) { Vec4f v0New = triangleIn.col(vertexIndexA); Vec4f v1New = triangleIn.col(vertexIndexB); bool v0Inside = v0New[3] > 0.f && v0New[2] > -v0New[3]; - bool v1Inside= v1New[3] > 0.f && v1New[2] > -v1New[3]; + bool v1Inside = v1New[3] > 0.f && v1New[2] > -v1New[3]; if (v0Inside && v1Inside) { - - } else if (v0Inside || v1Inside) + } + else if (v0Inside || v1Inside) { - float d0 = v0New[2]+v0New[3]; - float d1 = v1New[2]+v1New[3]; - float factor = 1.0 / (d1-d0); - Vec4f newVertex =(v0New*d1-v1New*d0)*factor; + float d0 = v0New[2] + v0New[3]; + float d1 = v1New[2] + v1New[3]; + float factor = 1.0 / (d1 - d0); + Vec4f newVertex = (v0New * d1 - v1New * d0) * factor; if (v0Inside) { v1New = newVertex; - } else + } + else { v0New = newVertex; } - } else + } + else { return; } - if (vertices.size()==0 || !(equals(vertices[vertices.size()-1],v0New))) + if (vertices.size() == 0 || !(equals(vertices[vertices.size() - 1], v0New))) { vertices.push_back(v0New); } @@ -452,21 +450,16 @@ static void clipEdge(const mat<4,3,float>& triangleIn, int vertexIndexA, int ver vertices.push_back(v1New); } - - - -static bool clipTriangleAgainstNearplane(const mat<4,3,float>& triangleIn, b3AlignedObjectArray >& clippedTrianglesOut) +static bool clipTriangleAgainstNearplane(const mat<4, 3, float>& triangleIn, b3AlignedObjectArray >& clippedTrianglesOut) { - - //discard triangle if all vertices are behind near-plane - if (triangleIn[3][0]<0 && triangleIn[3][1] <0 && triangleIn[3][2] <0) + if (triangleIn[3][0] < 0 && triangleIn[3][1] < 0 && triangleIn[3][2] < 0) { return true; } //accept triangle if all vertices are in front of the near-plane - if (triangleIn[3][0]>=0 && triangleIn[3][1] >=0 && triangleIn[3][2] >=0) + if (triangleIn[3][0] >= 0 && triangleIn[3][1] >= 0 && triangleIn[3][2] >= 0) { clippedTrianglesOut.push_back(triangleIn); return false; @@ -475,26 +468,26 @@ static bool clipTriangleAgainstNearplane(const mat<4,3,float>& triangleIn, b3Ali Vec4f vtxCache[5]; b3AlignedObjectArray vertices; - vertices.initializeFromBuffer(vtxCache,0,5); - clipEdge(triangleIn,0,1,vertices); - clipEdge(triangleIn,1,2,vertices); - clipEdge(triangleIn,2,0,vertices); + vertices.initializeFromBuffer(vtxCache, 0, 5); + clipEdge(triangleIn, 0, 1, vertices); + clipEdge(triangleIn, 1, 2, vertices); + clipEdge(triangleIn, 2, 0, vertices); - if (vertices.size()<3) + if (vertices.size() < 3) return true; - - if (equals(vertices[0],vertices[vertices.size()-1])) + + if (equals(vertices[0], vertices[vertices.size() - 1])) { vertices.pop_back(); } //create a fan of triangles - for (int i=1;i& vtx = clippedTrianglesOut.expand(); - vtx.set_col(0,vertices[0]); - vtx.set_col(1,vertices[i]); - vtx.set_col(2,vertices[i+1]); + mat<4, 3, float>& vtx = clippedTrianglesOut.expand(); + vtx.set_col(0, vertices[0]); + vtx.set_col(1, vertices[i]); + vtx.set_col(2, vertices[i + 1]); } return true; } @@ -502,131 +495,130 @@ static bool clipTriangleAgainstNearplane(const mat<4,3,float>& triangleIn, b3Ali void TinyRenderer::renderObject(TinyRenderObjectData& renderData) { B3_PROFILE("renderObject"); - int width = renderData.m_rgbColorBuffer.get_width(); - int height = renderData.m_rgbColorBuffer.get_height(); - - Vec3f light_dir_local = Vec3f(renderData.m_lightDirWorld[0],renderData.m_lightDirWorld[1],renderData.m_lightDirWorld[2]); - Vec3f light_color = Vec3f(renderData.m_lightColor[0],renderData.m_lightColor[1],renderData.m_lightColor[2]); - float light_distance = renderData.m_lightDistance; - Model* model = renderData.m_model; - if (0==model) - return; + int width = renderData.m_rgbColorBuffer.get_width(); + int height = renderData.m_rgbColorBuffer.get_height(); + + Vec3f light_dir_local = Vec3f(renderData.m_lightDirWorld[0], renderData.m_lightDirWorld[1], renderData.m_lightDirWorld[2]); + Vec3f light_color = Vec3f(renderData.m_lightColor[0], renderData.m_lightColor[1], renderData.m_lightColor[2]); + float light_distance = renderData.m_lightDistance; + Model* model = renderData.m_model; + if (0 == model) + return; //discard invisible objects (zero alpha) - if (model->getColorRGBA()[3]==0) + if (model->getColorRGBA()[3] == 0) return; - renderData.m_viewportMatrix = viewport(0,0,width, height); - - b3AlignedObjectArray& zbuffer = renderData.m_depthBuffer; - b3AlignedObjectArray* shadowBufferPtr = renderData.m_shadowBuffer; - int* segmentationMaskBufferPtr = (renderData.m_segmentationMaskBufferPtr && renderData.m_segmentationMaskBufferPtr->size())?&renderData.m_segmentationMaskBufferPtr->at(0):0; - - TGAImage& frame = renderData.m_rgbColorBuffer; - - { - // light target is set to be the origin, and the up direction is set to be vertical up. - Matrix lightViewMatrix = lookat(light_dir_local*light_distance, Vec3f(0.0,0.0,0.0), Vec3f(0.0,0.0,1.0)); - Matrix lightModelViewMatrix = lightViewMatrix*renderData.m_modelMatrix; - Matrix modelViewMatrix = renderData.m_viewMatrix*renderData.m_modelMatrix; - Vec3f localScaling(renderData.m_localScaling[0],renderData.m_localScaling[1],renderData.m_localScaling[2]); + renderData.m_viewportMatrix = viewport(0, 0, width, height); + + b3AlignedObjectArray& zbuffer = renderData.m_depthBuffer; + b3AlignedObjectArray* shadowBufferPtr = renderData.m_shadowBuffer; + int* segmentationMaskBufferPtr = (renderData.m_segmentationMaskBufferPtr && renderData.m_segmentationMaskBufferPtr->size()) ? &renderData.m_segmentationMaskBufferPtr->at(0) : 0; + + TGAImage& frame = renderData.m_rgbColorBuffer; + + { + // light target is set to be the origin, and the up direction is set to be vertical up. + Matrix lightViewMatrix = lookat(light_dir_local * light_distance, Vec3f(0.0, 0.0, 0.0), Vec3f(0.0, 0.0, 1.0)); + Matrix lightModelViewMatrix = lightViewMatrix * renderData.m_modelMatrix; + Matrix modelViewMatrix = renderData.m_viewMatrix * renderData.m_modelMatrix; + Vec3f localScaling(renderData.m_localScaling[0], renderData.m_localScaling[1], renderData.m_localScaling[2]); Matrix viewMatrixInv = renderData.m_viewMatrix.invert(); btVector3 P(viewMatrixInv[0][3], viewMatrixInv[1][3], viewMatrixInv[2][3]); - - Shader shader(model, light_dir_local, light_color, modelViewMatrix, lightModelViewMatrix, renderData.m_projectionMatrix,renderData.m_modelMatrix, renderData.m_viewportMatrix, localScaling, model->getColorRGBA(), width, height, shadowBufferPtr, renderData.m_lightAmbientCoeff, renderData.m_lightDiffuseCoeff, renderData.m_lightSpecularCoeff); - + + Shader shader(model, light_dir_local, light_color, modelViewMatrix, lightModelViewMatrix, renderData.m_projectionMatrix, renderData.m_modelMatrix, renderData.m_viewportMatrix, localScaling, model->getColorRGBA(), width, height, shadowBufferPtr, renderData.m_lightAmbientCoeff, renderData.m_lightDiffuseCoeff, renderData.m_lightSpecularCoeff); + { - B3_PROFILE("face"); + B3_PROFILE("face"); - for (int i=0; infaces(); i++) - { - for (int j=0; j<3; j++) { - shader.vertex(i, j); - } - - // backface culling - btVector3 v0(shader.world_tri.col(0)[0], shader.world_tri.col(0)[1], shader.world_tri.col(0)[2]); - btVector3 v1(shader.world_tri.col(1)[0], shader.world_tri.col(1)[1], shader.world_tri.col(1)[2]); - btVector3 v2(shader.world_tri.col(2)[0], shader.world_tri.col(2)[1], shader.world_tri.col(2)[2]); - btVector3 N = (v1-v0).cross(v2-v0); - if ((v0-P).dot(N) >= 0) - continue; + for (int i = 0; i < model->nfaces(); i++) + { + for (int j = 0; j < 3; j++) + { + shader.vertex(i, j); + } - mat<4,3,float> stackTris[3]; + // backface culling + btVector3 v0(shader.world_tri.col(0)[0], shader.world_tri.col(0)[1], shader.world_tri.col(0)[2]); + btVector3 v1(shader.world_tri.col(1)[0], shader.world_tri.col(1)[1], shader.world_tri.col(1)[2]); + btVector3 v2(shader.world_tri.col(2)[0], shader.world_tri.col(2)[1], shader.world_tri.col(2)[2]); + btVector3 N = (v1 - v0).cross(v2 - v0); + if ((v0 - P).dot(N) >= 0) + continue; - b3AlignedObjectArray< mat<4,3,float> > clippedTriangles; - clippedTriangles.initializeFromBuffer(stackTris,0,3); + mat<4, 3, float> stackTris[3]; - bool hasClipped = clipTriangleAgainstNearplane(shader.varying_tri,clippedTriangles); + b3AlignedObjectArray > clippedTriangles; + clippedTriangles.initializeFromBuffer(stackTris, 0, 3); + + bool hasClipped = clipTriangleAgainstNearplane(shader.varying_tri, clippedTriangles); + + if (hasClipped) + { + for (int t = 0; t < clippedTriangles.size(); t++) + { + triangleClipped(clippedTriangles[t], shader.varying_tri, shader, frame, &zbuffer[0], segmentationMaskBufferPtr, renderData.m_viewportMatrix, renderData.m_objectIndex + ((renderData.m_linkIndex + 1) << 24)); + } + } + else + { + triangle(shader.varying_tri, shader, frame, &zbuffer[0], segmentationMaskBufferPtr, renderData.m_viewportMatrix, renderData.m_objectIndex + ((renderData.m_linkIndex + 1) << 24)); + } + } + } + } +} + +void TinyRenderer::renderObjectDepth(TinyRenderObjectData& renderData) +{ + int width = renderData.m_rgbColorBuffer.get_width(); + int height = renderData.m_rgbColorBuffer.get_height(); + + Vec3f light_dir_local = Vec3f(renderData.m_lightDirWorld[0], renderData.m_lightDirWorld[1], renderData.m_lightDirWorld[2]); + float light_distance = renderData.m_lightDistance; + Model* model = renderData.m_model; + if (0 == model) + return; + + renderData.m_viewportMatrix = viewport(0, 0, width, height); + + float* shadowBufferPtr = (renderData.m_shadowBuffer && renderData.m_shadowBuffer->size()) ? &renderData.m_shadowBuffer->at(0) : 0; + int* segmentationMaskBufferPtr = 0; + + TGAImage depthFrame(width, height, TGAImage::RGB); + + { + // light target is set to be the origin, and the up direction is set to be vertical up. + Matrix lightViewMatrix = lookat(light_dir_local * light_distance, Vec3f(0.0, 0.0, 0.0), Vec3f(0.0, 0.0, 1.0)); + Matrix lightModelViewMatrix = lightViewMatrix * renderData.m_modelMatrix; + Matrix lightViewProjectionMatrix = renderData.m_projectionMatrix; + Vec3f localScaling(renderData.m_localScaling[0], renderData.m_localScaling[1], renderData.m_localScaling[2]); + + DepthShader shader(model, lightModelViewMatrix, lightViewProjectionMatrix, renderData.m_modelMatrix, localScaling, light_distance); + for (int i = 0; i < model->nfaces(); i++) + { + for (int j = 0; j < 3; j++) + { + shader.vertex(i, j); + } + + mat<4, 3, float> stackTris[3]; + + b3AlignedObjectArray > clippedTriangles; + clippedTriangles.initializeFromBuffer(stackTris, 0, 3); + + bool hasClipped = clipTriangleAgainstNearplane(shader.varying_tri, clippedTriangles); if (hasClipped) { - for (int t=0;tsize())?&renderData.m_shadowBuffer->at(0):0; - int* segmentationMaskBufferPtr = 0; - - TGAImage depthFrame(width, height, TGAImage::RGB); - - { - // light target is set to be the origin, and the up direction is set to be vertical up. - Matrix lightViewMatrix = lookat(light_dir_local*light_distance, Vec3f(0.0,0.0,0.0), Vec3f(0.0,0.0,1.0)); - Matrix lightModelViewMatrix = lightViewMatrix*renderData.m_modelMatrix; - Matrix lightViewProjectionMatrix = renderData.m_projectionMatrix; - Vec3f localScaling(renderData.m_localScaling[0],renderData.m_localScaling[1],renderData.m_localScaling[2]); - - DepthShader shader(model, lightModelViewMatrix, lightViewProjectionMatrix,renderData.m_modelMatrix, localScaling, light_distance); - for (int i=0; infaces(); i++) - { - for (int j=0; j<3; j++) { - shader.vertex(i, j); - } - - - mat<4,3,float> stackTris[3]; - - b3AlignedObjectArray< mat<4,3,float> > clippedTriangles; - clippedTriangles.initializeFromBuffer(stackTris,0,3); - - bool hasClipped = clipTriangleAgainstNearplane(shader.varying_tri,clippedTriangles); - - if (hasClipped) - { - for (int t=0;t& m_depthBuffer;//required, hence a reference - b3AlignedObjectArray* m_shadowBuffer;//optional, hence a pointer - b3AlignedObjectArray* m_segmentationMaskBufferPtr;//optional, hence a pointer - - TinyRenderObjectData(TGAImage& rgbColorBuffer,b3AlignedObjectArray&depthBuffer); - TinyRenderObjectData(TGAImage& rgbColorBuffer,b3AlignedObjectArray&depthBuffer,b3AlignedObjectArray* segmentationMaskBuffer,int objectIndex); - TinyRenderObjectData(TGAImage& rgbColorBuffer,b3AlignedObjectArray&depthBuffer,b3AlignedObjectArray* shadowBuffer); - TinyRenderObjectData(TGAImage& rgbColorBuffer,b3AlignedObjectArray&depthBuffer,b3AlignedObjectArray* shadowBuffer, b3AlignedObjectArray* segmentationMaskBuffer,int objectIndex, int linkIndex); - virtual ~TinyRenderObjectData(); - - void loadModel(const char* fileName); - void createCube(float HalfExtentsX,float HalfExtentsY,float HalfExtentsZ); - void registerMeshShape(const float* vertices, int numVertices,const int* indices, int numIndices, const float rgbaColor[4], - unsigned char* textureImage=0, int textureWidth=0, int textureHeight=0); - - void registerMesh2(btAlignedObjectArray& vertices, btAlignedObjectArray& normals,btAlignedObjectArray& indices); - - void* m_userData; - int m_userIndex; - int m_objectIndex; - int m_linkIndex; -}; + btVector3 m_lightColor; + float m_lightDistance; + float m_lightAmbientCoeff; + float m_lightDiffuseCoeff; + float m_lightSpecularCoeff; + //Model (vertices, indices, textures, shader) + Matrix m_modelMatrix; + class Model* m_model; + //class IShader* m_shader; todo(erwincoumans) expose the shader, for now we use a default shader + + //Output + + TGAImage& m_rgbColorBuffer; + b3AlignedObjectArray& m_depthBuffer; //required, hence a reference + b3AlignedObjectArray* m_shadowBuffer; //optional, hence a pointer + b3AlignedObjectArray* m_segmentationMaskBufferPtr; //optional, hence a pointer + + TinyRenderObjectData(TGAImage& rgbColorBuffer, b3AlignedObjectArray& depthBuffer); + TinyRenderObjectData(TGAImage& rgbColorBuffer, b3AlignedObjectArray& depthBuffer, b3AlignedObjectArray* segmentationMaskBuffer, int objectIndex); + TinyRenderObjectData(TGAImage& rgbColorBuffer, b3AlignedObjectArray& depthBuffer, b3AlignedObjectArray* shadowBuffer); + TinyRenderObjectData(TGAImage& rgbColorBuffer, b3AlignedObjectArray& depthBuffer, b3AlignedObjectArray* shadowBuffer, b3AlignedObjectArray* segmentationMaskBuffer, int objectIndex, int linkIndex); + virtual ~TinyRenderObjectData(); + + void loadModel(const char* fileName); + void createCube(float HalfExtentsX, float HalfExtentsY, float HalfExtentsZ); + void registerMeshShape(const float* vertices, int numVertices, const int* indices, int numIndices, const float rgbaColor[4], + unsigned char* textureImage = 0, int textureWidth = 0, int textureHeight = 0); + + void registerMesh2(btAlignedObjectArray& vertices, btAlignedObjectArray& normals, btAlignedObjectArray& indices); + + void* m_userData; + int m_userIndex; + int m_objectIndex; + int m_linkIndex; +}; class TinyRenderer { - public: - static void renderObjectDepth(TinyRenderObjectData& renderData); - static void renderObject(TinyRenderObjectData& renderData); +public: + static void renderObjectDepth(TinyRenderObjectData& renderData); + static void renderObject(TinyRenderObjectData& renderData); }; -#endif // TINY_RENDERER_Hbla +#endif // TINY_RENDERER_Hbla diff --git a/examples/TinyRenderer/geometry.cpp b/examples/TinyRenderer/geometry.cpp index 3b6b2f251..f6e35d184 100644 --- a/examples/TinyRenderer/geometry.cpp +++ b/examples/TinyRenderer/geometry.cpp @@ -1,7 +1,22 @@ #include "geometry.h" -template <> template <> vec<3,int> ::vec(const vec<3,float> &v) : x(int(v.x+.5f)),y(int(v.y+.5f)),z(int(v.z+.5f)) {} -template <> template <> vec<3,float>::vec(const vec<3,int> &v) : x(v.x),y(v.y),z(v.z) {} -template <> template <> vec<2,int> ::vec(const vec<2,float> &v) : x(int(v.x+.5f)),y(int(v.y+.5f)) {} -template <> template <> vec<2,float>::vec(const vec<2,int> &v) : x(v.x),y(v.y) {} - +template <> +template <> +vec<3, int>::vec(const vec<3, float> &v) : x(int(v.x + .5f)), y(int(v.y + .5f)), z(int(v.z + .5f)) +{ +} +template <> +template <> +vec<3, float>::vec(const vec<3, int> &v) : x(v.x), y(v.y), z(v.z) +{ +} +template <> +template <> +vec<2, int>::vec(const vec<2, float> &v) : x(int(v.x + .5f)), y(int(v.y + .5f)) +{ +} +template <> +template <> +vec<2, float>::vec(const vec<2, int> &v) : x(v.x), y(v.y) +{ +} diff --git a/examples/TinyRenderer/geometry.h b/examples/TinyRenderer/geometry.h index 38bb4d935..e72d21ac9 100644 --- a/examples/TinyRenderer/geometry.h +++ b/examples/TinyRenderer/geometry.h @@ -4,86 +4,149 @@ #include #include +template +class mat; -template class mat; +template +struct vec +{ + vec() + { + for (size_t i = DIM; i--; data_[i] = T()) + ; + } + T& operator[](const size_t i) + { + assert(i < DIM); + return data_[i]; + } + const T& operator[](const size_t i) const + { + assert(i < DIM); + return data_[i]; + } -template struct vec { - vec() { for (size_t i=DIM; i--; data_[i] = T()); } - T& operator[](const size_t i) { assert(i struct vec<2,T> { - vec() : x(T()), y(T()) {} - vec(T X, T Y) : x(X), y(Y) {} - template vec<2,T>(const vec<2,U> &v); - T& operator[](const size_t i) { assert(i<2); return i<=0 ? x : y; } - const T& operator[](const size_t i) const { assert(i<2); return i<=0 ? x : y; } +template +struct vec<2, T> +{ + vec() : x(T()), y(T()) {} + vec(T X, T Y) : x(X), y(Y) {} + template + vec<2, T>(const vec<2, U>& v); + T& operator[](const size_t i) + { + assert(i < 2); + return i <= 0 ? x : y; + } + const T& operator[](const size_t i) const + { + assert(i < 2); + return i <= 0 ? x : y; + } - T x,y; + T x, y; }; ///////////////////////////////////////////////////////////////////////////////// -template struct vec<3,T> { - vec() : x(T()), y(T()), z(T()) {} - vec(T X, T Y, T Z) : x(X), y(Y), z(Z) {} - template vec<3,T>(const vec<3,U> &v); - T& operator[](const size_t i) { assert(i<3); return i<=0 ? x : (1==i ? y : z); } - const T& operator[](const size_t i) const { assert(i<3); return i<=0 ? x : (1==i ? y : z); } - float norm() { return std::sqrt(x*x+y*y+z*z); } - vec<3,T> & normalize(T l=1) { *this = (*this)*(l/norm()); return *this; } +template +struct vec<3, T> +{ + vec() : x(T()), y(T()), z(T()) {} + vec(T X, T Y, T Z) : x(X), y(Y), z(Z) {} + template + vec<3, T>(const vec<3, U>& v); + T& operator[](const size_t i) + { + assert(i < 3); + return i <= 0 ? x : (1 == i ? y : z); + } + const T& operator[](const size_t i) const + { + assert(i < 3); + return i <= 0 ? x : (1 == i ? y : z); + } + float norm() { return std::sqrt(x * x + y * y + z * z); } + vec<3, T>& normalize(T l = 1) + { + *this = (*this) * (l / norm()); + return *this; + } - T x,y,z; + T x, y, z; }; ///////////////////////////////////////////////////////////////////////////////// -template T operator*(const vec& lhs, const vec& rhs) { - T ret = T(); - for (size_t i=DIM; i--; ret+=lhs[i]*rhs[i]); - return ret; +template +T operator*(const vec& lhs, const vec& rhs) +{ + T ret = T(); + for (size_t i = DIM; i--; ret += lhs[i] * rhs[i]) + ; + return ret; } - -templatevec operator+(vec lhs, const vec& rhs) { - for (size_t i=DIM; i--; lhs[i]+=rhs[i]); - return lhs; +template +vec operator+(vec lhs, const vec& rhs) +{ + for (size_t i = DIM; i--; lhs[i] += rhs[i]) + ; + return lhs; } -templatevec operator-(vec lhs, const vec& rhs) { - for (size_t i=DIM; i--; lhs[i]-=rhs[i]); - return lhs; +template +vec operator-(vec lhs, const vec& rhs) +{ + for (size_t i = DIM; i--; lhs[i] -= rhs[i]) + ; + return lhs; } -template vec operator*(vec lhs, const U& rhs) { - for (size_t i=DIM; i--; lhs[i]*=rhs); - return lhs; +template +vec operator*(vec lhs, const U& rhs) +{ + for (size_t i = DIM; i--; lhs[i] *= rhs) + ; + return lhs; } -template vec operator/(vec lhs, const U& rhs) { - for (size_t i=DIM; i--; lhs[i]/=rhs); - return lhs; +template +vec operator/(vec lhs, const U& rhs) +{ + for (size_t i = DIM; i--; lhs[i] /= rhs) + ; + return lhs; } -template vec embed(const vec &v, T fill=1) { - vec ret; - for (size_t i=LEN; i--; ret[i]=(i +vec embed(const vec& v, T fill = 1) +{ + vec ret; + for (size_t i = LEN; i--; ret[i] = (i < DIM ? v[i] : fill)) + ; + return ret; } -template vec proj(const vec &v) { - vec ret; - for (size_t i=LEN; i--; ret[i]=v[i]); - return ret; +template +vec proj(const vec& v) +{ + vec ret; + for (size_t i = LEN; i--; ret[i] = v[i]) + ; + return ret; } -template vec<3,T> cross(vec<3,T> v1, vec<3,T> v2) { - return vec<3,T>(v1.y*v2.z - v1.z*v2.y, v1.z*v2.x - v1.x*v2.z, v1.x*v2.y - v1.y*v2.x); +template +vec<3, T> cross(vec<3, T> v1, vec<3, T> v2) +{ + return vec<3, T>(v1.y * v2.z - v1.z * v2.y, v1.z * v2.x - v1.x * v2.z, v1.x * v2.y - v1.y * v2.x); } #if 0 template std::ostream& operator<<(std::ostream& out, vec& v) { @@ -95,113 +158,150 @@ template std::ostream& operator<<(std::ostream& out, ve #endif ///////////////////////////////////////////////////////////////////////////////// -template struct dt { - static T det(const mat& src) { - T ret=0; - for (size_t i=DIM; i--; ret += src[0][i]*src.cofactor(0,i)); - return ret; - } +template +struct dt +{ + static T det(const mat& src) + { + T ret = 0; + for (size_t i = DIM; i--; ret += src[0][i] * src.cofactor(0, i)) + ; + return ret; + } }; -template struct dt<1,T> { - static T det(const mat<1,1,T>& src) { - return src[0][0]; - } +template +struct dt<1, T> +{ + static T det(const mat<1, 1, T>& src) + { + return src[0][0]; + } }; ///////////////////////////////////////////////////////////////////////////////// -template class mat { - vec rows[DimRows]; +template +class mat +{ + vec rows[DimRows]; + public: - mat() {} + mat() {} - vec& operator[] (const size_t idx) { - assert(idx& operator[](const size_t idx) + { + assert(idx < DimRows); + return rows[idx]; + } - const vec& operator[] (const size_t idx) const { - assert(idx& operator[](const size_t idx) const + { + assert(idx < DimRows); + return rows[idx]; + } - vec col(const size_t idx) const { - assert(idx ret; - for (size_t i=DimRows; i--; ret[i]=rows[i][idx]); - return ret; - } + vec col(const size_t idx) const + { + assert(idx < DimCols); + vec ret; + for (size_t i = DimRows; i--; ret[i] = rows[i][idx]) + ; + return ret; + } - void set_col(size_t idx, vec v) { - assert(idx v) + { + assert(idx < DimCols); + for (size_t i = DimRows; i--; rows[i][idx] = v[i]) + ; + } - static mat identity() { - mat ret; - for (size_t i=DimRows; i--; ) - for (size_t j=DimCols;j--; ret[i][j]=(i==j)); - return ret; - } + static mat identity() + { + mat ret; + for (size_t i = DimRows; i--;) + for (size_t j = DimCols; j--; ret[i][j] = (i == j)) + ; + return ret; + } - T det() const { - return dt::det(*this); - } + T det() const + { + return dt::det(*this); + } - mat get_minor(size_t row, size_t col) const { - mat ret; - for (size_t i=DimRows-1; i--; ) - for (size_t j=DimCols-1;j--; ret[i][j]=rows[i get_minor(size_t row, size_t col) const + { + mat ret; + for (size_t i = DimRows - 1; i--;) + for (size_t j = DimCols - 1; j--; ret[i][j] = rows[i < row ? i : i + 1][j < col ? j : j + 1]) + ; + return ret; + } - T cofactor(size_t row, size_t col) const { - return get_minor(row,col).det()*((row+col)%2 ? -1 : 1); - } + T cofactor(size_t row, size_t col) const + { + return get_minor(row, col).det() * ((row + col) % 2 ? -1 : 1); + } - mat adjugate() const { - mat ret; - for (size_t i=DimRows; i--; ) - for (size_t j=DimCols; j--; ret[i][j]=cofactor(i,j)); - return ret; - } + mat adjugate() const + { + mat ret; + for (size_t i = DimRows; i--;) + for (size_t j = DimCols; j--; ret[i][j] = cofactor(i, j)) + ; + return ret; + } - mat invert_transpose() { - mat ret = adjugate(); - T tmp = ret[0]*rows[0]; - return ret/tmp; - } + mat invert_transpose() + { + mat ret = adjugate(); + T tmp = ret[0] * rows[0]; + return ret / tmp; + } - mat invert() { - return invert_transpose().transpose(); - } + mat invert() + { + return invert_transpose().transpose(); + } - mat transpose() { - mat ret; - for (size_t i=DimCols; i--; ret[i]=this->col(i)); - return ret; - } + mat transpose() + { + mat ret; + for (size_t i = DimCols; i--; ret[i] = this->col(i)) + ; + return ret; + } }; ///////////////////////////////////////////////////////////////////////////////// -template vec operator*(const mat& lhs, const vec& rhs) { - vec ret; - for (size_t i=DimRows; i--; ret[i]=lhs[i]*rhs); - return ret; +template +vec operator*(const mat& lhs, const vec& rhs) +{ + vec ret; + for (size_t i = DimRows; i--; ret[i] = lhs[i] * rhs) + ; + return ret; } -templatemat operator*(const mat& lhs, const mat& rhs) { - mat result; - for (size_t i=R1; i--; ) - for (size_t j=C2; j--; result[i][j]=lhs[i]*rhs.col(j)); - return result; +template +mat operator*(const mat& lhs, const mat& rhs) +{ + mat result; + for (size_t i = R1; i--;) + for (size_t j = C2; j--; result[i][j] = lhs[i] * rhs.col(j)) + ; + return result; } -templatemat operator/(mat lhs, const T& rhs) { - for (size_t i=DimRows; i--; lhs[i]=lhs[i]/rhs); - return lhs; +template +mat operator/(mat lhs, const T& rhs) +{ + for (size_t i = DimRows; i--; lhs[i] = lhs[i] / rhs) + ; + return lhs; } #if 0 @@ -212,11 +312,10 @@ template std::ostream& operator<<(std::o #endif ///////////////////////////////////////////////////////////////////////////////// -typedef vec<2, float> Vec2f; -typedef vec<2, int> Vec2i; -typedef vec<3, float> Vec3f; -typedef vec<3, int> Vec3i; -typedef vec<4, float> Vec4f; -typedef mat<4,4,float> Matrix; -#endif //__GEOMETRY_H__ - +typedef vec<2, float> Vec2f; +typedef vec<2, int> Vec2i; +typedef vec<3, float> Vec3f; +typedef vec<3, int> Vec3i; +typedef vec<4, float> Vec4f; +typedef mat<4, 4, float> Matrix; +#endif //__GEOMETRY_H__ diff --git a/examples/TinyRenderer/main.cpp b/examples/TinyRenderer/main.cpp index 32f5e7edd..c94c94114 100644 --- a/examples/TinyRenderer/main.cpp +++ b/examples/TinyRenderer/main.cpp @@ -16,60 +16,57 @@ static b3MouseButtonCallback sOldMouseButtonCB = 0; static b3KeyboardCallback sOldKeyboardCB = 0; //static b3RenderCallback sOldRenderCB = 0; -float gWidth = 0 ; +float gWidth = 0; float gHeight = 0; void MyWheelCallback(float deltax, float deltay) { if (sOldWheelCB) - sOldWheelCB(deltax,deltay); + sOldWheelCB(deltax, deltay); } -void MyResizeCallback( float width, float height) +void MyResizeCallback(float width, float height) { - gWidth = width; - gHeight = height; - + gWidth = width; + gHeight = height; + if (sOldResizeCB) - sOldResizeCB(width,height); + sOldResizeCB(width, height); } -void MyMouseMoveCallback( float x, float y) +void MyMouseMoveCallback(float x, float y) { - printf("Mouse Move: %f, %f\n", x,y); + printf("Mouse Move: %f, %f\n", x, y); if (sOldMouseMoveCB) - sOldMouseMoveCB(x,y); + sOldMouseMoveCB(x, y); } void MyMouseButtonCallback(int button, int state, float x, float y) { if (sOldMouseButtonCB) - sOldMouseButtonCB(button,state,x,y); + sOldMouseButtonCB(button, state, x, y); } - void MyKeyboardCallback(int keycode, int state) { //keycodes are in examples/CommonInterfaces/CommonWindowInterface.h //for example B3G_ESCAPE for escape key //state == 1 for pressed, state == 0 for released. // use app->m_window->isModifiedPressed(...) to check for shift, escape and alt keys - printf("MyKeyboardCallback received key:%c in state %d\n",keycode,state); + printf("MyKeyboardCallback received key:%c in state %d\n", keycode, state); if (sOldKeyboardCB) - sOldKeyboardCB(keycode,state); + sOldKeyboardCB(keycode, state); } #include "TinyRenderer.h" int main(int argc, char* argv[]) { - b3CommandLineArgs myArgs(argc,argv); + b3CommandLineArgs myArgs(argc, argv); + + SimpleOpenGL3App* app = new SimpleOpenGL3App("SimpleOpenGL3App", 640, 480, true); - - - SimpleOpenGL3App* app = new SimpleOpenGL3App("SimpleOpenGL3App",640,480,true); - app->m_instancingRenderer->getActiveCamera()->setCameraDistance(13); app->m_instancingRenderer->getActiveCamera()->setCameraPitch(0); - app->m_instancingRenderer->getActiveCamera()->setCameraTargetPosition(0,0,0); - sOldKeyboardCB = app->m_window->getKeyboardCallback(); + app->m_instancingRenderer->getActiveCamera()->setCameraTargetPosition(0, 0, 0); + sOldKeyboardCB = app->m_window->getKeyboardCallback(); app->m_window->setKeyboardCallback(MyKeyboardCallback); sOldMouseMoveCB = app->m_window->getMouseMoveCallback(); app->m_window->setMouseMoveCallback(MyMouseMoveCallback); @@ -79,159 +76,149 @@ int main(int argc, char* argv[]) app->m_window->setWheelCallback(MyWheelCallback); sOldResizeCB = app->m_window->getResizeCallback(); app->m_window->setResizeCallback(MyResizeCallback); - - int textureWidth = gWidth; - int textureHeight = gHeight; - TGAImage rgbColorBuffer(gWidth,gHeight,TGAImage::RGB); - b3AlignedObjectArray depthBuffer; - depthBuffer.resize(gWidth*gHeight); - - TinyRenderObjectData renderData(rgbColorBuffer,depthBuffer);//, "african_head/african_head.obj");//floor.obj"); - + + int textureWidth = gWidth; + int textureHeight = gHeight; + TGAImage rgbColorBuffer(gWidth, gHeight, TGAImage::RGB); + b3AlignedObjectArray depthBuffer; + depthBuffer.resize(gWidth * gHeight); + + TinyRenderObjectData renderData(rgbColorBuffer, depthBuffer); //, "african_head/african_head.obj");//floor.obj"); + //renderData.loadModel("african_head/african_head.obj"); renderData.loadModel("floor.obj"); - + //renderData.createCube(1,1,1); - - - myArgs.GetCmdLineArgument("mp4_file",gVideoFileName); - if (gVideoFileName) - app->dumpFramesToVideo(gVideoFileName); - myArgs.GetCmdLineArgument("png_file",gPngFileName); - char fileName[1024]; - - - - unsigned char* image=new unsigned char[textureWidth*textureHeight*4]; - - - int textureHandle = app->m_renderer->registerTexture(image,textureWidth,textureHeight); + myArgs.GetCmdLineArgument("mp4_file", gVideoFileName); + if (gVideoFileName) + app->dumpFramesToVideo(gVideoFileName); + + myArgs.GetCmdLineArgument("png_file", gPngFileName); + char fileName[1024]; + + unsigned char* image = new unsigned char[textureWidth * textureHeight * 4]; + + int textureHandle = app->m_renderer->registerTexture(image, textureWidth, textureHeight); + + int cubeIndex = app->registerCubeShape(1, 1, 1); + + b3Vector3 pos = b3MakeVector3(0, 0, 0); + b3Quaternion orn(0, 0, 0, 1); + b3Vector3 color = b3MakeVector3(1, 0, 0); + b3Vector3 scaling = b3MakeVector3(1, 1, 1); + app->m_renderer->registerGraphicsInstance(cubeIndex, pos, orn, color, scaling); + app->m_renderer->writeTransforms(); - int cubeIndex = app->registerCubeShape(1,1,1); - - b3Vector3 pos = b3MakeVector3(0,0,0); - b3Quaternion orn(0,0,0,1); - b3Vector3 color=b3MakeVector3(1,0,0); - b3Vector3 scaling=b3MakeVector3 (1,1,1); - app->m_renderer->registerGraphicsInstance(cubeIndex,pos,orn,color,scaling); - app->m_renderer->writeTransforms(); - do { - static int frameCount = 0; + static int frameCount = 0; frameCount++; if (gPngFileName) - { - printf("gPngFileName=%s\n",gPngFileName); + { + printf("gPngFileName=%s\n", gPngFileName); - sprintf(fileName,"%s%d.png",gPngFileName,frameCount++); - app->dumpNextFrameToPng(fileName); - } - - app->m_instancingRenderer->init(); + sprintf(fileName, "%s%d.png", gPngFileName, frameCount++); + app->dumpNextFrameToPng(fileName); + } + + app->m_instancingRenderer->init(); app->m_instancingRenderer->updateCamera(); - ///clear the color and z (depth) buffer - for(int y=0;ym_instancingRenderer->getActiveCamera()->getCameraProjectionMatrix(projMat); - float viewMat[16]; - app->m_instancingRenderer->getActiveCamera()->getCameraViewMatrix(viewMat); - B3_ATTRIBUTE_ALIGNED16(float modelMat[16]); - - //sync the object transform - b3Transform tr; - tr.setIdentity(); - static float posUp = 0.f; - // posUp += 0.001; - b3Vector3 org = b3MakeVector3(0,posUp,0); - tr.setOrigin(org); - tr.getOpenGLMatrix(modelMat); - - for (int i=0;i<4;i++) - { - for (int j=0;j<4;j++) - { - renderData.m_viewMatrix[i][j] = viewMat[i+4*j]; - renderData.m_modelMatrix[i][j] = modelMat[i+4*j]; - } - } - - //render the object - TinyRenderer::renderObject(renderData); - - #if 1 - //update the texels of the texture using a simple pattern, animated using frame index - for(int y=0;ym_instancingRenderer->getActiveCamera()->getCameraProjectionMatrix(projMat); + float viewMat[16]; + app->m_instancingRenderer->getActiveCamera()->getCameraViewMatrix(viewMat); + B3_ATTRIBUTE_ALIGNED16(float modelMat[16]); + + //sync the object transform + b3Transform tr; + tr.setIdentity(); + static float posUp = 0.f; + // posUp += 0.001; + b3Vector3 org = b3MakeVector3(0, posUp, 0); + tr.setOrigin(org); + tr.getOpenGLMatrix(modelMat); + + for (int i = 0; i < 4; i++) + { + for (int j = 0; j < 4; j++) + { + renderData.m_viewMatrix[i][j] = viewMat[i + 4 * j]; + renderData.m_modelMatrix[i][j] = modelMat[i + 4 * j]; + } + } + + //render the object + TinyRenderer::renderObject(renderData); + +#if 1 + //update the texels of the texture using a simple pattern, animated using frame index + for (int y = 0; y < textureHeight; ++y) + { + unsigned char* pi = image + (y)*textureWidth * 3; + for (int x = 0; x < textureWidth; ++x) + { + TGAColor color = renderData.m_rgbColorBuffer.get(x, y); pi[0] = color.bgra[2]; pi[1] = color.bgra[1]; pi[2] = color.bgra[0]; pi[3] = 255; - pi+=3; - } - } - #else - - //update the texels of the texture using a simple pattern, animated using frame index - for(int y=0;y>4; - unsigned char* pi=image+y*textureWidth*3; - for(int x=0;x>4; - const unsigned char b=180; - unsigned char c=b+((s+(t&1))&1)*(255-b); - pi[0]=pi[1]=pi[2]=pi[3]=c; - pi+=3; - } - } - #endif - - - app->m_renderer->activateTexture(textureHandle); - app->m_renderer->updateTexture(textureHandle,image); - - float color[4] = {1,1,1,1}; - app->m_primRenderer->drawTexturedRect(0,0,gWidth/3,gHeight/3,color,0,0,1,1,true); - - - - app->m_renderer->renderScene(); + //update the texels of the texture using a simple pattern, animated using frame index + for (int y = 0; y < textureHeight; ++y) + { + const int t = (y + frameCount) >> 4; + unsigned char* pi = image + y * textureWidth * 3; + for (int x = 0; x < textureWidth; ++x) + { + TGAColor color = renderData.m_rgbColorBuffer.get(x, y); + + const int s = x >> 4; + const unsigned char b = 180; + unsigned char c = b + ((s + (t & 1)) & 1) * (255 - b); + pi[0] = pi[1] = pi[2] = pi[3] = c; + pi += 3; + } + } +#endif + + app->m_renderer->activateTexture(textureHandle); + app->m_renderer->updateTexture(textureHandle, image); + + float color[4] = {1, 1, 1, 1}; + app->m_primRenderer->drawTexturedRect(0, 0, gWidth / 3, gHeight / 3, color, 0, 0, 1, 1, true); + + app->m_renderer->renderScene(); app->drawGrid(); char bla[1024]; - sprintf(bla,"Simple test frame %d", frameCount); + sprintf(bla, "Simple test frame %d", frameCount); - app->drawText(bla,10,10); + app->drawText(bla, 10, 10); app->swapBuffer(); } while (!app->m_window->requestedExit()); - delete app; return 0; } diff --git a/examples/TinyRenderer/model.cpp b/examples/TinyRenderer/model.cpp index e4cef0fce..16188526d 100644 --- a/examples/TinyRenderer/model.cpp +++ b/examples/TinyRenderer/model.cpp @@ -4,53 +4,63 @@ #include #include "model.h" #include "Bullet3Common/b3Logging.h" -#include // memcpy -Model::Model(const char *filename) : verts_(), faces_(), norms_(), uv_(), diffusemap_(), normalmap_(), specularmap_() { - std::ifstream in; - in.open (filename, std::ifstream::in); - if (in.fail()) return; - std::string line; - while (!in.eof()) { - std::getline(in, line); - std::istringstream iss(line.c_str()); - char trash; - if (!line.compare(0, 2, "v ")) { - iss >> trash; - Vec3f v; - for (int i=0;i<3;i++) iss >> v[i]; - verts_.push_back(v); - } else if (!line.compare(0, 3, "vn ")) { - iss >> trash >> trash; - Vec3f n; - for (int i=0;i<3;i++) iss >> n[i]; - norms_.push_back(n); - } else if (!line.compare(0, 3, "vt ")) { - iss >> trash >> trash; - Vec2f uv; - for (int i=0;i<2;i++) iss >> uv[i]; - uv_.push_back(uv); - } else if (!line.compare(0, 2, "f ")) { - std::vector f; - Vec3i tmp; - iss >> trash; - while (iss >> tmp[0] >> trash >> tmp[1] >> trash >> tmp[2]) { - for (int i=0; i<3; i++) tmp[i]--; // in wavefront obj all indices start at 1, not zero - f.push_back(tmp); - } - faces_.push_back(f); - } - } - std::cerr << "# v# " << verts_.size() << " f# " << faces_.size() << " vt# " << uv_.size() << " vn# " << norms_.size() << std::endl; - load_texture(filename, "_diffuse.tga", diffusemap_); - load_texture(filename, "_nm_tangent.tga", normalmap_); - load_texture(filename, "_spec.tga", specularmap_); +#include // memcpy +Model::Model(const char *filename) : verts_(), faces_(), norms_(), uv_(), diffusemap_(), normalmap_(), specularmap_() +{ + std::ifstream in; + in.open(filename, std::ifstream::in); + if (in.fail()) return; + std::string line; + while (!in.eof()) + { + std::getline(in, line); + std::istringstream iss(line.c_str()); + char trash; + if (!line.compare(0, 2, "v ")) + { + iss >> trash; + Vec3f v; + for (int i = 0; i < 3; i++) iss >> v[i]; + verts_.push_back(v); + } + else if (!line.compare(0, 3, "vn ")) + { + iss >> trash >> trash; + Vec3f n; + for (int i = 0; i < 3; i++) iss >> n[i]; + norms_.push_back(n); + } + else if (!line.compare(0, 3, "vt ")) + { + iss >> trash >> trash; + Vec2f uv; + for (int i = 0; i < 2; i++) iss >> uv[i]; + uv_.push_back(uv); + } + else if (!line.compare(0, 2, "f ")) + { + std::vector f; + Vec3i tmp; + iss >> trash; + while (iss >> tmp[0] >> trash >> tmp[1] >> trash >> tmp[2]) + { + for (int i = 0; i < 3; i++) tmp[i]--; // in wavefront obj all indices start at 1, not zero + f.push_back(tmp); + } + faces_.push_back(f); + } + } + std::cerr << "# v# " << verts_.size() << " f# " << faces_.size() << " vt# " << uv_.size() << " vn# " << norms_.size() << std::endl; + load_texture(filename, "_diffuse.tga", diffusemap_); + load_texture(filename, "_nm_tangent.tga", normalmap_); + load_texture(filename, "_spec.tga", specularmap_); } -Model::Model():verts_(), faces_(), norms_(), uv_(), diffusemap_(), normalmap_(), specularmap_() +Model::Model() : verts_(), faces_(), norms_(), uv_(), diffusemap_(), normalmap_(), specularmap_() { } -void Model::setDiffuseTextureFromData(unsigned char* textureImage,int textureWidth,int textureHeight) +void Model::setDiffuseTextureFromData(unsigned char *textureImage, int textureWidth, int textureHeight) { { B3_PROFILE("new TGAImage"); @@ -62,7 +72,7 @@ void Model::setDiffuseTextureFromData(unsigned char* textureImage,int textureWid color.bytespp = 3; { B3_PROFILE("copy texels"); - memcpy(diffusemap_.buffer(), textureImage, textureHeight*textureWidth * 3); + memcpy(diffusemap_.buffer(), textureImage, textureHeight * textureWidth * 3); } { B3_PROFILE("flip_vertically"); @@ -70,9 +80,9 @@ void Model::setDiffuseTextureFromData(unsigned char* textureImage,int textureWid } } -void Model::loadDiffuseTexture(const char* relativeFileName) +void Model::loadDiffuseTexture(const char *relativeFileName) { - diffusemap_.read_tga_file(relativeFileName); + diffusemap_.read_tga_file(relativeFileName); } void Model::reserveMemory(int numVertices, int numIndices) @@ -83,99 +93,108 @@ void Model::reserveMemory(int numVertices, int numIndices) faces_.reserve(numIndices); } -void Model::addVertex(float x,float y,float z, float normalX, float normalY, float normalZ, float u, float v) +void Model::addVertex(float x, float y, float z, float normalX, float normalY, float normalZ, float u, float v) { - verts_.push_back(Vec3f(x,y,z)); - norms_.push_back(Vec3f(normalX,normalY,normalZ)); - uv_.push_back(Vec2f(u,v)); - + verts_.push_back(Vec3f(x, y, z)); + norms_.push_back(Vec3f(normalX, normalY, normalZ)); + uv_.push_back(Vec2f(u, v)); } void Model::addTriangle(int vertexposIndex0, int normalIndex0, int uvIndex0, - int vertexposIndex1, int normalIndex1, int uvIndex1, - int vertexposIndex2, int normalIndex2, int uvIndex2) + int vertexposIndex1, int normalIndex1, int uvIndex1, + int vertexposIndex2, int normalIndex2, int uvIndex2) { - std::vector f; - f.push_back(Vec3i(vertexposIndex0, normalIndex0, uvIndex0)); - f.push_back(Vec3i(vertexposIndex1, normalIndex1, uvIndex1)); - f.push_back(Vec3i(vertexposIndex2, normalIndex2, uvIndex2)); - faces_.push_back(f); + std::vector f; + f.push_back(Vec3i(vertexposIndex0, normalIndex0, uvIndex0)); + f.push_back(Vec3i(vertexposIndex1, normalIndex1, uvIndex1)); + f.push_back(Vec3i(vertexposIndex2, normalIndex2, uvIndex2)); + faces_.push_back(f); } - Model::~Model() {} -int Model::nverts() { - return (int)verts_.size(); +int Model::nverts() +{ + return (int)verts_.size(); } -int Model::nfaces() { - return (int)faces_.size(); +int Model::nfaces() +{ + return (int)faces_.size(); } -std::vector Model::face(int idx) { - std::vector face; - for (int i=0; i<(int)faces_[idx].size(); i++) face.push_back(faces_[idx][i][0]); - return face; +std::vector Model::face(int idx) +{ + std::vector face; + for (int i = 0; i < (int)faces_[idx].size(); i++) face.push_back(faces_[idx][i][0]); + return face; } -Vec3f Model::vert(int i) { - return verts_[i]; +Vec3f Model::vert(int i) +{ + return verts_[i]; } -Vec3f Model::vert(int iface, int nthvert) { - return verts_[faces_[iface][nthvert][0]]; +Vec3f Model::vert(int iface, int nthvert) +{ + return verts_[faces_[iface][nthvert][0]]; } -void Model::load_texture(std::string filename, const char *suffix, TGAImage &img) { - std::string texfile(filename); - size_t dot = texfile.find_last_of("."); - if (dot!=std::string::npos) { - texfile = texfile.substr(0,dot) + std::string(suffix); - std::cerr << "texture file " << texfile << " loading " << (img.read_tga_file(texfile.c_str()) ? "ok" : "failed") << std::endl; - img.flip_vertically(); - } +void Model::load_texture(std::string filename, const char *suffix, TGAImage &img) +{ + std::string texfile(filename); + size_t dot = texfile.find_last_of("."); + if (dot != std::string::npos) + { + texfile = texfile.substr(0, dot) + std::string(suffix); + std::cerr << "texture file " << texfile << " loading " << (img.read_tga_file(texfile.c_str()) ? "ok" : "failed") << std::endl; + img.flip_vertically(); + } } -TGAColor Model::diffuse(Vec2f uvf) { - if (diffusemap_.get_width() && diffusemap_.get_height()) - { +TGAColor Model::diffuse(Vec2f uvf) +{ + if (diffusemap_.get_width() && diffusemap_.get_height()) + { double val; -// bool repeat = true; -// if (repeat) + // bool repeat = true; + // if (repeat) { - uvf[0] = modf(uvf[0],&val); - uvf[1] = modf(uvf[1],&val); + uvf[0] = modf(uvf[0], &val); + uvf[1] = modf(uvf[1], &val); } - Vec2i uv(uvf[0]*diffusemap_.get_width(), uvf[1]*diffusemap_.get_height()); - return diffusemap_.get(uv[0], uv[1]); - } - return TGAColor(255,255,255,255); + Vec2i uv(uvf[0] * diffusemap_.get_width(), uvf[1] * diffusemap_.get_height()); + return diffusemap_.get(uv[0], uv[1]); + } + return TGAColor(255, 255, 255, 255); } -Vec3f Model::normal(Vec2f uvf) { - Vec2i uv(uvf[0]*normalmap_.get_width(), uvf[1]*normalmap_.get_height()); - TGAColor c = normalmap_.get(uv[0], uv[1]); - Vec3f res; - for (int i=0; i<3; i++) - res[2-i] = (float)c[i]/255.f*2.f - 1.f; - return res; +Vec3f Model::normal(Vec2f uvf) +{ + Vec2i uv(uvf[0] * normalmap_.get_width(), uvf[1] * normalmap_.get_height()); + TGAColor c = normalmap_.get(uv[0], uv[1]); + Vec3f res; + for (int i = 0; i < 3; i++) + res[2 - i] = (float)c[i] / 255.f * 2.f - 1.f; + return res; } -Vec2f Model::uv(int iface, int nthvert) { - return uv_[faces_[iface][nthvert][1]]; +Vec2f Model::uv(int iface, int nthvert) +{ + return uv_[faces_[iface][nthvert][1]]; } -float Model::specular(Vec2f uvf) { +float Model::specular(Vec2f uvf) +{ if (specularmap_.get_width() && specularmap_.get_height()) { - Vec2i uv(uvf[0]*specularmap_.get_width(), uvf[1]*specularmap_.get_height()); - return specularmap_.get(uv[0], uv[1])[0]/1.f; + Vec2i uv(uvf[0] * specularmap_.get_width(), uvf[1] * specularmap_.get_height()); + return specularmap_.get(uv[0], uv[1])[0] / 1.f; } return 2.0; } -Vec3f Model::normal(int iface, int nthvert) { - int idx = faces_[iface][nthvert][2]; - return norms_[idx].normalize(); +Vec3f Model::normal(int iface, int nthvert) +{ + int idx = faces_[iface][nthvert][2]; + return norms_[idx].normalize(); } - diff --git a/examples/TinyRenderer/model.h b/examples/TinyRenderer/model.h index 6cd9e383b..0594063ea 100644 --- a/examples/TinyRenderer/model.h +++ b/examples/TinyRenderer/model.h @@ -5,50 +5,51 @@ #include "geometry.h" #include "tgaimage.h" -class Model { +class Model +{ private: - std::vector verts_; - std::vector > faces_; // attention, this Vec3i means vertex/uv/normal - std::vector norms_; - std::vector uv_; - TGAImage diffusemap_; - TGAImage normalmap_; - TGAImage specularmap_; - Vec4f m_colorRGBA; - - void load_texture(std::string filename, const char *suffix, TGAImage &img); -public: - Model(const char *filename); - Model(); - void setColorRGBA(const float rgba[4]) - { - for (int i=0;i<4;i++) - m_colorRGBA[i] = rgba[i]; - } - - const Vec4f& getColorRGBA() const - { - return m_colorRGBA; - } - void loadDiffuseTexture(const char* relativeFileName); - void setDiffuseTextureFromData(unsigned char* textureImage,int textureWidth,int textureHeight); - void reserveMemory(int numVertices, int numIndices); - void addVertex(float x,float y,float z, float normalX, float normalY, float normalZ, float u, float v); - void addTriangle(int vertexposIndex0, int normalIndex0, int uvIndex0, - int vertexposIndex1, int normalIndex1, int uvIndex1, - int vertexposIndex2, int normalIndex2, int uvIndex2); - - ~Model(); - int nverts(); - int nfaces(); - Vec3f normal(int iface, int nthvert); - Vec3f normal(Vec2f uv); - Vec3f vert(int i); - Vec3f vert(int iface, int nthvert); - Vec2f uv(int iface, int nthvert); - TGAColor diffuse(Vec2f uv); - float specular(Vec2f uv); - std::vector face(int idx); -}; -#endif //__MODEL_H__ + std::vector verts_; + std::vector > faces_; // attention, this Vec3i means vertex/uv/normal + std::vector norms_; + std::vector uv_; + TGAImage diffusemap_; + TGAImage normalmap_; + TGAImage specularmap_; + Vec4f m_colorRGBA; + void load_texture(std::string filename, const char* suffix, TGAImage& img); + +public: + Model(const char* filename); + Model(); + void setColorRGBA(const float rgba[4]) + { + for (int i = 0; i < 4; i++) + m_colorRGBA[i] = rgba[i]; + } + + const Vec4f& getColorRGBA() const + { + return m_colorRGBA; + } + void loadDiffuseTexture(const char* relativeFileName); + void setDiffuseTextureFromData(unsigned char* textureImage, int textureWidth, int textureHeight); + void reserveMemory(int numVertices, int numIndices); + void addVertex(float x, float y, float z, float normalX, float normalY, float normalZ, float u, float v); + void addTriangle(int vertexposIndex0, int normalIndex0, int uvIndex0, + int vertexposIndex1, int normalIndex1, int uvIndex1, + int vertexposIndex2, int normalIndex2, int uvIndex2); + + ~Model(); + int nverts(); + int nfaces(); + Vec3f normal(int iface, int nthvert); + Vec3f normal(Vec2f uv); + Vec3f vert(int i); + Vec3f vert(int iface, int nthvert); + Vec2f uv(int iface, int nthvert); + TGAColor diffuse(Vec2f uv); + float specular(Vec2f uv); + std::vector face(int idx); +}; +#endif //__MODEL_H__ diff --git a/examples/TinyRenderer/our_gl.cpp b/examples/TinyRenderer/our_gl.cpp index 9f6e46e45..ade4694f0 100644 --- a/examples/TinyRenderer/our_gl.cpp +++ b/examples/TinyRenderer/our_gl.cpp @@ -6,193 +6,202 @@ IShader::~IShader() {} -Matrix viewport(int x, int y, int w, int h) +Matrix viewport(int x, int y, int w, int h) { - Matrix Viewport; - Viewport = Matrix::identity(); - Viewport[0][3] = x+w/2.f; - Viewport[1][3] = y+h/2.f; - Viewport[2][3] = .5f; - Viewport[0][0] = w/2.f; - Viewport[1][1] = h/2.f; - Viewport[2][2] = .5f; - return Viewport; + Matrix Viewport; + Viewport = Matrix::identity(); + Viewport[0][3] = x + w / 2.f; + Viewport[1][3] = y + h / 2.f; + Viewport[2][3] = .5f; + Viewport[0][0] = w / 2.f; + Viewport[1][1] = h / 2.f; + Viewport[2][2] = .5f; + return Viewport; } -Matrix projection(float coeff) { - Matrix Projection; - Projection = Matrix::identity(); - Projection[3][2] = coeff; - return Projection; -} - -Matrix lookat(Vec3f eye, Vec3f center, Vec3f up) { - Vec3f f = (center - eye).normalize(); - Vec3f u = up.normalize(); - Vec3f s = cross(f,u).normalize(); - u = cross(s,f); - - Matrix ModelView; - ModelView[0][0] = s.x; - ModelView[0][1] = s.y; - ModelView[0][2] = s.z; - - ModelView[1][0] = u.x; - ModelView[1][1] = u.y; - ModelView[1][2] = u.z; - - ModelView[2][0] =-f.x; - ModelView[2][1] =-f.y; - ModelView[2][2] =-f.z; - - ModelView[3][0] = 0.f; - ModelView[3][1] = 0.f; - ModelView[3][2] = 0.f; - - ModelView[0][3] = -(s[0]*eye[0]+s[1]*eye[1]+s[2]*eye[2]); - ModelView[1][3] = -(u[0]*eye[0]+u[1]*eye[1]+u[2]*eye[2]); - ModelView[2][3] = f[0]*eye[0]+f[1]*eye[1]+f[2]*eye[2]; - ModelView[3][3] = 1.f; - - return ModelView; -} - -Vec3f barycentric(Vec2f A, Vec2f B, Vec2f C, Vec2f P) { - Vec3f s[2]; - for (int i=2; i--; ) { - s[i][0] = C[i]-A[i]; - s[i][1] = B[i]-A[i]; - s[i][2] = A[i]-P[i]; - } - Vec3f u = cross(s[0], s[1]); - if (std::abs(u[2])>1e-2) // dont forget that u[2] is integer. If it is zero then triangle ABC is degenerate - return Vec3f(1.f-(u.x+u.y)/u.z, u.y/u.z, u.x/u.z); - return Vec3f(-1,1,1); // in this case generate negative coordinates, it will be thrown away by the rasterizator -} - -void triangleClipped(mat<4,3,float> &clipc, mat<4,3,float> &orgClipc, IShader &shader, TGAImage &image, float *zbuffer, const Matrix& viewPortMatrix) +Matrix projection(float coeff) { - triangleClipped(clipc, orgClipc,shader,image,zbuffer,0,viewPortMatrix,0); + Matrix Projection; + Projection = Matrix::identity(); + Projection[3][2] = coeff; + return Projection; } -void triangleClipped(mat<4,3,float> &clipc, mat<4,3,float> &orgClipc, IShader &shader, TGAImage &image, float *zbuffer, int* segmentationMaskBuffer, const Matrix& viewPortMatrix, int objectAndLinkIndex) +Matrix lookat(Vec3f eye, Vec3f center, Vec3f up) { + Vec3f f = (center - eye).normalize(); + Vec3f u = up.normalize(); + Vec3f s = cross(f, u).normalize(); + u = cross(s, f); - mat<3,4,float> screenSpacePts = (viewPortMatrix*clipc).transpose(); // transposed to ease access to each of the points - - mat<3,2,float> pts2; - for (int i=0; i<3; i++) + Matrix ModelView; + ModelView[0][0] = s.x; + ModelView[0][1] = s.y; + ModelView[0][2] = s.z; + + ModelView[1][0] = u.x; + ModelView[1][1] = u.y; + ModelView[1][2] = u.z; + + ModelView[2][0] = -f.x; + ModelView[2][1] = -f.y; + ModelView[2][2] = -f.z; + + ModelView[3][0] = 0.f; + ModelView[3][1] = 0.f; + ModelView[3][2] = 0.f; + + ModelView[0][3] = -(s[0] * eye[0] + s[1] * eye[1] + s[2] * eye[2]); + ModelView[1][3] = -(u[0] * eye[0] + u[1] * eye[1] + u[2] * eye[2]); + ModelView[2][3] = f[0] * eye[0] + f[1] * eye[1] + f[2] * eye[2]; + ModelView[3][3] = 1.f; + + return ModelView; +} + +Vec3f barycentric(Vec2f A, Vec2f B, Vec2f C, Vec2f P) +{ + Vec3f s[2]; + for (int i = 2; i--;) { - pts2[i] = proj<2>(screenSpacePts[i]/screenSpacePts[i][3]); + s[i][0] = C[i] - A[i]; + s[i][1] = B[i] - A[i]; + s[i][2] = A[i] - P[i]; + } + Vec3f u = cross(s[0], s[1]); + if (std::abs(u[2]) > 1e-2) // dont forget that u[2] is integer. If it is zero then triangle ABC is degenerate + return Vec3f(1.f - (u.x + u.y) / u.z, u.y / u.z, u.x / u.z); + return Vec3f(-1, 1, 1); // in this case generate negative coordinates, it will be thrown away by the rasterizator +} + +void triangleClipped(mat<4, 3, float> &clipc, mat<4, 3, float> &orgClipc, IShader &shader, TGAImage &image, float *zbuffer, const Matrix &viewPortMatrix) +{ + triangleClipped(clipc, orgClipc, shader, image, zbuffer, 0, viewPortMatrix, 0); +} + +void triangleClipped(mat<4, 3, float> &clipc, mat<4, 3, float> &orgClipc, IShader &shader, TGAImage &image, float *zbuffer, int *segmentationMaskBuffer, const Matrix &viewPortMatrix, int objectAndLinkIndex) +{ + mat<3, 4, float> screenSpacePts = (viewPortMatrix * clipc).transpose(); // transposed to ease access to each of the points + + mat<3, 2, float> pts2; + for (int i = 0; i < 3; i++) + { + pts2[i] = proj<2>(screenSpacePts[i] / screenSpacePts[i][3]); } - Vec2f bboxmin( std::numeric_limits::max(), std::numeric_limits::max()); - Vec2f bboxmax(-std::numeric_limits::max(), -std::numeric_limits::max()); - Vec2f clamp(image.get_width()-1, image.get_height()-1); - - for (int i=0; i<3; i++) { - for (int j=0; j<2; j++) { - bboxmin[j] = b3Max(0.f, b3Min(bboxmin[j], pts2[i][j])); - bboxmax[j] = b3Min(clamp[j], b3Max(bboxmax[j], pts2[i][j])); - } - } + Vec2f bboxmin(std::numeric_limits::max(), std::numeric_limits::max()); + Vec2f bboxmax(-std::numeric_limits::max(), -std::numeric_limits::max()); + Vec2f clamp(image.get_width() - 1, image.get_height() - 1); + + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 2; j++) + { + bboxmin[j] = b3Max(0.f, b3Min(bboxmin[j], pts2[i][j])); + bboxmax[j] = b3Min(clamp[j], b3Max(bboxmax[j], pts2[i][j])); + } + } Vec2i P; - TGAColor color; + TGAColor color; - mat<3,4,float> orgScreenSpacePts = (viewPortMatrix*orgClipc).transpose(); // transposed to ease access to each of the points - - mat<3,2,float> orgPts2; - for (int i=0; i<3; i++) + mat<3, 4, float> orgScreenSpacePts = (viewPortMatrix * orgClipc).transpose(); // transposed to ease access to each of the points + + mat<3, 2, float> orgPts2; + for (int i = 0; i < 3; i++) { - orgPts2[i] = proj<2>(orgScreenSpacePts[i]/orgScreenSpacePts[i][3]); + orgPts2[i] = proj<2>(orgScreenSpacePts[i] / orgScreenSpacePts[i][3]); } - - for (P.x=bboxmin.x; P.x<=bboxmax.x; P.x++) { - for (P.y=bboxmin.y; P.y<=bboxmax.y; P.y++) + for (P.x = bboxmin.x; P.x <= bboxmax.x; P.x++) + { + for (P.y = bboxmin.y; P.y <= bboxmax.y; P.y++) { float frag_depth = 0; { - Vec3f bc_screen = barycentric(pts2[0], pts2[1], pts2[2], P); - Vec3f bc_clip = Vec3f(bc_screen.x/screenSpacePts[0][3], bc_screen.y/screenSpacePts[1][3], bc_screen.z/screenSpacePts[2][3]); - bc_clip = bc_clip/(bc_clip.x+bc_clip.y+bc_clip.z); - frag_depth = -1*(clipc[2]*bc_clip); - - if (bc_screen.x<0 || bc_screen.y<0 || bc_screen.z<0 || - zbuffer[P.x+P.y*image.get_width()]>frag_depth) + Vec3f bc_screen = barycentric(pts2[0], pts2[1], pts2[2], P); + Vec3f bc_clip = Vec3f(bc_screen.x / screenSpacePts[0][3], bc_screen.y / screenSpacePts[1][3], bc_screen.z / screenSpacePts[2][3]); + bc_clip = bc_clip / (bc_clip.x + bc_clip.y + bc_clip.z); + frag_depth = -1 * (clipc[2] * bc_clip); + + if (bc_screen.x < 0 || bc_screen.y < 0 || bc_screen.z < 0 || + zbuffer[P.x + P.y * image.get_width()] > frag_depth) continue; } - Vec3f bc_screen2 = barycentric(orgPts2[0], orgPts2[1], orgPts2[2], P); - Vec3f bc_clip2 = Vec3f(bc_screen2.x/orgScreenSpacePts[0][3], bc_screen2.y/orgScreenSpacePts[1][3], bc_screen2.z/orgScreenSpacePts[2][3]); - bc_clip2 = bc_clip2/(bc_clip2.x+bc_clip2.y+bc_clip2.z); - float frag_depth2 = -1*(orgClipc[2]*bc_clip2); - - bool discard = shader.fragment(bc_clip2, color); + Vec3f bc_screen2 = barycentric(orgPts2[0], orgPts2[1], orgPts2[2], P); + Vec3f bc_clip2 = Vec3f(bc_screen2.x / orgScreenSpacePts[0][3], bc_screen2.y / orgScreenSpacePts[1][3], bc_screen2.z / orgScreenSpacePts[2][3]); + bc_clip2 = bc_clip2 / (bc_clip2.x + bc_clip2.y + bc_clip2.z); + float frag_depth2 = -1 * (orgClipc[2] * bc_clip2); - if (!discard) { - zbuffer[P.x+P.y*image.get_width()] = frag_depth; - if (segmentationMaskBuffer) - { - segmentationMaskBuffer[P.x+P.y*image.get_width()] = objectAndLinkIndex; - } - image.set(P.x, P.y, color); - } - } - } + bool discard = shader.fragment(bc_clip2, color); + + if (!discard) + { + zbuffer[P.x + P.y * image.get_width()] = frag_depth; + if (segmentationMaskBuffer) + { + segmentationMaskBuffer[P.x + P.y * image.get_width()] = objectAndLinkIndex; + } + image.set(P.x, P.y, color); + } + } + } } - -void triangle(mat<4,3,float> &clipc, IShader &shader, TGAImage &image, float *zbuffer, const Matrix& viewPortMatrix) +void triangle(mat<4, 3, float> &clipc, IShader &shader, TGAImage &image, float *zbuffer, const Matrix &viewPortMatrix) { - triangle(clipc,shader,image,zbuffer,0,viewPortMatrix,0); + triangle(clipc, shader, image, zbuffer, 0, viewPortMatrix, 0); } -void triangle(mat<4,3,float> &clipc, IShader &shader, TGAImage &image, float *zbuffer, int* segmentationMaskBuffer, const Matrix& viewPortMatrix, int objectAndLinkIndex) { - mat<3,4,float> pts = (viewPortMatrix*clipc).transpose(); // transposed to ease access to each of the points - - +void triangle(mat<4, 3, float> &clipc, IShader &shader, TGAImage &image, float *zbuffer, int *segmentationMaskBuffer, const Matrix &viewPortMatrix, int objectAndLinkIndex) +{ + mat<3, 4, float> pts = (viewPortMatrix * clipc).transpose(); // transposed to ease access to each of the points - mat<3,2,float> pts2; - for (int i=0; i<3; i++) pts2[i] = proj<2>(pts[i]/pts[i][3]); + mat<3, 2, float> pts2; + for (int i = 0; i < 3; i++) pts2[i] = proj<2>(pts[i] / pts[i][3]); - Vec2f bboxmin( std::numeric_limits::max(), std::numeric_limits::max()); - Vec2f bboxmax(-std::numeric_limits::max(), -std::numeric_limits::max()); - Vec2f clamp(image.get_width()-1, image.get_height()-1); - - for (int i=0; i<3; i++) { - for (int j=0; j<2; j++) { - bboxmin[j] = b3Max(0.f, b3Min(bboxmin[j], pts2[i][j])); - bboxmax[j] = b3Min(clamp[j], b3Max(bboxmax[j], pts2[i][j])); - } - } + Vec2f bboxmin(std::numeric_limits::max(), std::numeric_limits::max()); + Vec2f bboxmax(-std::numeric_limits::max(), -std::numeric_limits::max()); + Vec2f clamp(image.get_width() - 1, image.get_height() - 1); + + for (int i = 0; i < 3; i++) + { + for (int j = 0; j < 2; j++) + { + bboxmin[j] = b3Max(0.f, b3Min(bboxmin[j], pts2[i][j])); + bboxmax[j] = b3Min(clamp[j], b3Max(bboxmax[j], pts2[i][j])); + } + } Vec2i P; - TGAColor color; - for (P.x=bboxmin.x; P.x<=bboxmax.x; P.x++) { - for (P.y=bboxmin.y; P.y<=bboxmax.y; P.y++) { - Vec3f bc_screen = barycentric(pts2[0], pts2[1], pts2[2], P); - Vec3f bc_clip = Vec3f(bc_screen.x/pts[0][3], bc_screen.y/pts[1][3], bc_screen.z/pts[2][3]); - bc_clip = bc_clip/(bc_clip.x+bc_clip.y+bc_clip.z); - float frag_depth = -1*(clipc[2]*bc_clip); - if (bc_screen.x<0 || bc_screen.y<0 || bc_screen.z<0 || - zbuffer[P.x+P.y*image.get_width()]>frag_depth) + TGAColor color; + for (P.x = bboxmin.x; P.x <= bboxmax.x; P.x++) + { + for (P.y = bboxmin.y; P.y <= bboxmax.y; P.y++) + { + Vec3f bc_screen = barycentric(pts2[0], pts2[1], pts2[2], P); + Vec3f bc_clip = Vec3f(bc_screen.x / pts[0][3], bc_screen.y / pts[1][3], bc_screen.z / pts[2][3]); + bc_clip = bc_clip / (bc_clip.x + bc_clip.y + bc_clip.z); + float frag_depth = -1 * (clipc[2] * bc_clip); + if (bc_screen.x < 0 || bc_screen.y < 0 || bc_screen.z < 0 || + zbuffer[P.x + P.y * image.get_width()] > frag_depth) continue; - bool discard = shader.fragment(bc_clip, color); - if (frag_depth<-shader.m_farPlane) - discard=true; - if (frag_depth>shader.m_nearPlane) - discard=true; + bool discard = shader.fragment(bc_clip, color); + if (frag_depth < -shader.m_farPlane) + discard = true; + if (frag_depth > shader.m_nearPlane) + discard = true; - if (!discard) { - zbuffer[P.x+P.y*image.get_width()] = frag_depth; - if (segmentationMaskBuffer) - { - segmentationMaskBuffer[P.x+P.y*image.get_width()] = objectAndLinkIndex; - } - image.set(P.x, P.y, color); - } - } - } + if (!discard) + { + zbuffer[P.x + P.y * image.get_width()] = frag_depth; + if (segmentationMaskBuffer) + { + segmentationMaskBuffer[P.x + P.y * image.get_width()] = objectAndLinkIndex; + } + image.set(P.x, P.y, color); + } + } + } } diff --git a/examples/TinyRenderer/our_gl.h b/examples/TinyRenderer/our_gl.h index 6a18cf1ae..54d09250a 100644 --- a/examples/TinyRenderer/our_gl.h +++ b/examples/TinyRenderer/our_gl.h @@ -3,25 +3,22 @@ #include "tgaimage.h" #include "geometry.h" - - - Matrix viewport(int x, int y, int w, int h); -Matrix projection(float coeff=0.f); // coeff = -1/c +Matrix projection(float coeff = 0.f); // coeff = -1/c Matrix lookat(Vec3f eye, Vec3f center, Vec3f up); -struct IShader { - float m_nearPlane; +struct IShader +{ + float m_nearPlane; float m_farPlane; - virtual ~IShader(); - virtual Vec4f vertex(int iface, int nthvert) = 0; - virtual bool fragment(Vec3f bar, TGAColor &color) = 0; + virtual ~IShader(); + virtual Vec4f vertex(int iface, int nthvert) = 0; + virtual bool fragment(Vec3f bar, TGAColor &color) = 0; }; -void triangle(mat<4,3,float> &pts, IShader &shader, TGAImage &image, float *zbuffer, const Matrix& viewPortMatrix); -void triangle(mat<4,3,float> &pts, IShader &shader, TGAImage &image, float *zbuffer, int* segmentationMaskBuffer, const Matrix& viewPortMatrix, int objectIndex); -void triangleClipped(mat<4,3,float> &clippedPts, mat<4,3,float> &pts, IShader &shader, TGAImage &image, float *zbuffer, const Matrix& viewPortMatrix); -void triangleClipped(mat<4,3,float> &clippedPts, mat<4,3,float> &pts, IShader &shader, TGAImage &image, float *zbuffer, int* segmentationMaskBuffer, const Matrix& viewPortMatrix, int objectIndex); - -#endif //__OUR_GL_H__ +void triangle(mat<4, 3, float> &pts, IShader &shader, TGAImage &image, float *zbuffer, const Matrix &viewPortMatrix); +void triangle(mat<4, 3, float> &pts, IShader &shader, TGAImage &image, float *zbuffer, int *segmentationMaskBuffer, const Matrix &viewPortMatrix, int objectIndex); +void triangleClipped(mat<4, 3, float> &clippedPts, mat<4, 3, float> &pts, IShader &shader, TGAImage &image, float *zbuffer, const Matrix &viewPortMatrix); +void triangleClipped(mat<4, 3, float> &clippedPts, mat<4, 3, float> &pts, IShader &shader, TGAImage &image, float *zbuffer, int *segmentationMaskBuffer, const Matrix &viewPortMatrix, int objectIndex); +#endif //__OUR_GL_H__ diff --git a/examples/TinyRenderer/tgaimage.cpp b/examples/TinyRenderer/tgaimage.cpp index cb6921067..706baefe3 100644 --- a/examples/TinyRenderer/tgaimage.cpp +++ b/examples/TinyRenderer/tgaimage.cpp @@ -7,350 +7,420 @@ TGAImage::TGAImage() : data(NULL), width(0), height(0), bytespp(0) {} -TGAImage::TGAImage(int w, int h, int bpp) : data(NULL), width(w), height(h), bytespp(bpp) { - unsigned long nbytes = width*height*bytespp; - data = new unsigned char[nbytes]; - //memset(data, 0, nbytes); +TGAImage::TGAImage(int w, int h, int bpp) : data(NULL), width(w), height(h), bytespp(bpp) +{ + unsigned long nbytes = width * height * bytespp; + data = new unsigned char[nbytes]; + //memset(data, 0, nbytes); } -TGAImage::TGAImage(const TGAImage &img) : data(NULL), width(img.width), height(img.height), bytespp(img.bytespp) { - unsigned long nbytes = width*height*bytespp; - data = new unsigned char[nbytes]; - //memcpy(data, img.data, nbytes); +TGAImage::TGAImage(const TGAImage &img) : data(NULL), width(img.width), height(img.height), bytespp(img.bytespp) +{ + unsigned long nbytes = width * height * bytespp; + data = new unsigned char[nbytes]; + //memcpy(data, img.data, nbytes); } -TGAImage::~TGAImage() { - if (data) delete [] data; +TGAImage::~TGAImage() +{ + if (data) delete[] data; } -TGAImage & TGAImage::operator =(const TGAImage &img) { - if (this != &img) { - if (data) delete [] data; - width = img.width; - height = img.height; - bytespp = img.bytespp; - unsigned long nbytes = width*height*bytespp; - data = new unsigned char[nbytes]; - memcpy(data, img.data, nbytes); - } - return *this; +TGAImage &TGAImage::operator=(const TGAImage &img) +{ + if (this != &img) + { + if (data) delete[] data; + width = img.width; + height = img.height; + bytespp = img.bytespp; + unsigned long nbytes = width * height * bytespp; + data = new unsigned char[nbytes]; + memcpy(data, img.data, nbytes); + } + return *this; } -bool TGAImage::read_tga_file(const char *filename) { - if (data) delete [] data; - data = NULL; - std::ifstream in; - in.open (filename, std::ios::binary); - if (!in.is_open()) { - std::cerr << "can't open file " << filename << "\n"; - in.close(); - return false; - } - TGA_Header header; - in.read((char *)&header, sizeof(header)); - if (!in.good()) { - in.close(); - std::cerr << "an error occured while reading the header\n"; - return false; - } - width = header.width; - height = header.height; - bytespp = header.bitsperpixel>>3; - if (width<=0 || height<=0 || (bytespp!=GRAYSCALE && bytespp!=RGB && bytespp!=RGBA)) { - in.close(); - std::cerr << "bad bpp (or width/height) value\n"; - return false; - } - unsigned long nbytes = bytespp*width*height; - data = new unsigned char[nbytes]; - if (3==header.datatypecode || 2==header.datatypecode) { - in.read((char *)data, nbytes); - if (!in.good()) { - in.close(); - std::cerr << "an error occured while reading the data\n"; - return false; - } - } else if (10==header.datatypecode||11==header.datatypecode) { - if (!load_rle_data(in)) { - in.close(); - std::cerr << "an error occured while reading the data\n"; - return false; - } - } else { - in.close(); - std::cerr << "unknown file format " << (int)header.datatypecode << "\n"; - return false; - } - if (!(header.imagedescriptor & 0x20)) { - flip_vertically(); - } - if (header.imagedescriptor & 0x10) { - flip_horizontally(); - } - std::cerr << width << "x" << height << "/" << bytespp*8 << "\n"; - in.close(); - return true; +bool TGAImage::read_tga_file(const char *filename) +{ + if (data) delete[] data; + data = NULL; + std::ifstream in; + in.open(filename, std::ios::binary); + if (!in.is_open()) + { + std::cerr << "can't open file " << filename << "\n"; + in.close(); + return false; + } + TGA_Header header; + in.read((char *)&header, sizeof(header)); + if (!in.good()) + { + in.close(); + std::cerr << "an error occured while reading the header\n"; + return false; + } + width = header.width; + height = header.height; + bytespp = header.bitsperpixel >> 3; + if (width <= 0 || height <= 0 || (bytespp != GRAYSCALE && bytespp != RGB && bytespp != RGBA)) + { + in.close(); + std::cerr << "bad bpp (or width/height) value\n"; + return false; + } + unsigned long nbytes = bytespp * width * height; + data = new unsigned char[nbytes]; + if (3 == header.datatypecode || 2 == header.datatypecode) + { + in.read((char *)data, nbytes); + if (!in.good()) + { + in.close(); + std::cerr << "an error occured while reading the data\n"; + return false; + } + } + else if (10 == header.datatypecode || 11 == header.datatypecode) + { + if (!load_rle_data(in)) + { + in.close(); + std::cerr << "an error occured while reading the data\n"; + return false; + } + } + else + { + in.close(); + std::cerr << "unknown file format " << (int)header.datatypecode << "\n"; + return false; + } + if (!(header.imagedescriptor & 0x20)) + { + flip_vertically(); + } + if (header.imagedescriptor & 0x10) + { + flip_horizontally(); + } + std::cerr << width << "x" << height << "/" << bytespp * 8 << "\n"; + in.close(); + return true; } -bool TGAImage::load_rle_data(std::ifstream &in) { - unsigned long pixelcount = width*height; - unsigned long currentpixel = 0; - unsigned long currentbyte = 0; - TGAColor colorbuffer; - do { - unsigned char chunkheader = 0; - chunkheader = in.get(); - if (!in.good()) { - std::cerr << "an error occured while reading the data\n"; - return false; - } - if (chunkheader<128) { - chunkheader++; - for (int i=0; ipixelcount) { - std::cerr << "Too many pixels read\n"; - return false; - } - } - } else { - chunkheader -= 127; - in.read((char *)colorbuffer.bgra, bytespp); - if (!in.good()) { - std::cerr << "an error occured while reading the header\n"; - return false; - } - for (int i=0; ipixelcount) { - std::cerr << "Too many pixels read\n"; - return false; - } - } - } - } while (currentpixel < pixelcount); - return true; +bool TGAImage::load_rle_data(std::ifstream &in) +{ + unsigned long pixelcount = width * height; + unsigned long currentpixel = 0; + unsigned long currentbyte = 0; + TGAColor colorbuffer; + do + { + unsigned char chunkheader = 0; + chunkheader = in.get(); + if (!in.good()) + { + std::cerr << "an error occured while reading the data\n"; + return false; + } + if (chunkheader < 128) + { + chunkheader++; + for (int i = 0; i < chunkheader; i++) + { + in.read((char *)colorbuffer.bgra, bytespp); + if (!in.good()) + { + std::cerr << "an error occured while reading the header\n"; + return false; + } + for (int t = 0; t < bytespp; t++) + data[currentbyte++] = colorbuffer.bgra[t]; + currentpixel++; + if (currentpixel > pixelcount) + { + std::cerr << "Too many pixels read\n"; + return false; + } + } + } + else + { + chunkheader -= 127; + in.read((char *)colorbuffer.bgra, bytespp); + if (!in.good()) + { + std::cerr << "an error occured while reading the header\n"; + return false; + } + for (int i = 0; i < chunkheader; i++) + { + for (int t = 0; t < bytespp; t++) + data[currentbyte++] = colorbuffer.bgra[t]; + currentpixel++; + if (currentpixel > pixelcount) + { + std::cerr << "Too many pixels read\n"; + return false; + } + } + } + } while (currentpixel < pixelcount); + return true; } -bool TGAImage::write_tga_file(const char *filename, bool rle) const { - unsigned char developer_area_ref[4] = {0, 0, 0, 0}; - unsigned char extension_area_ref[4] = {0, 0, 0, 0}; - unsigned char footer[18] = {'T','R','U','E','V','I','S','I','O','N','-','X','F','I','L','E','.','\0'}; - std::ofstream out; - out.open (filename, std::ios::binary); - if (!out.is_open()) { - std::cerr << "can't open file " << filename << "\n"; - out.close(); - return false; - } - TGA_Header header; - memset((void *)&header, 0, sizeof(header)); - header.bitsperpixel = bytespp<<3; - header.width = width; - header.height = height; - header.datatypecode = (bytespp==GRAYSCALE?(rle?11:3):(rle?10:2)); - header.imagedescriptor = 0x20; // top-left origin - out.write((char *)&header, sizeof(header)); - if (!out.good()) { - out.close(); - std::cerr << "can't dump the tga file\n"; - return false; - } - if (!rle) { - out.write((char *)data, width*height*bytespp); - if (!out.good()) { - std::cerr << "can't unload raw data\n"; - out.close(); - return false; - } - } else { - if (!unload_rle_data(out)) { - out.close(); - std::cerr << "can't unload rle data\n"; - return false; - } - } - out.write((char *)developer_area_ref, sizeof(developer_area_ref)); - if (!out.good()) { - std::cerr << "can't dump the tga file\n"; - out.close(); - return false; - } - out.write((char *)extension_area_ref, sizeof(extension_area_ref)); - if (!out.good()) { - std::cerr << "can't dump the tga file\n"; - out.close(); - return false; - } - out.write((char *)footer, sizeof(footer)); - if (!out.good()) { - std::cerr << "can't dump the tga file\n"; - out.close(); - return false; - } - out.close(); - return true; +bool TGAImage::write_tga_file(const char *filename, bool rle) const +{ + unsigned char developer_area_ref[4] = {0, 0, 0, 0}; + unsigned char extension_area_ref[4] = {0, 0, 0, 0}; + unsigned char footer[18] = {'T', 'R', 'U', 'E', 'V', 'I', 'S', 'I', 'O', 'N', '-', 'X', 'F', 'I', 'L', 'E', '.', '\0'}; + std::ofstream out; + out.open(filename, std::ios::binary); + if (!out.is_open()) + { + std::cerr << "can't open file " << filename << "\n"; + out.close(); + return false; + } + TGA_Header header; + memset((void *)&header, 0, sizeof(header)); + header.bitsperpixel = bytespp << 3; + header.width = width; + header.height = height; + header.datatypecode = (bytespp == GRAYSCALE ? (rle ? 11 : 3) : (rle ? 10 : 2)); + header.imagedescriptor = 0x20; // top-left origin + out.write((char *)&header, sizeof(header)); + if (!out.good()) + { + out.close(); + std::cerr << "can't dump the tga file\n"; + return false; + } + if (!rle) + { + out.write((char *)data, width * height * bytespp); + if (!out.good()) + { + std::cerr << "can't unload raw data\n"; + out.close(); + return false; + } + } + else + { + if (!unload_rle_data(out)) + { + out.close(); + std::cerr << "can't unload rle data\n"; + return false; + } + } + out.write((char *)developer_area_ref, sizeof(developer_area_ref)); + if (!out.good()) + { + std::cerr << "can't dump the tga file\n"; + out.close(); + return false; + } + out.write((char *)extension_area_ref, sizeof(extension_area_ref)); + if (!out.good()) + { + std::cerr << "can't dump the tga file\n"; + out.close(); + return false; + } + out.write((char *)footer, sizeof(footer)); + if (!out.good()) + { + std::cerr << "can't dump the tga file\n"; + out.close(); + return false; + } + out.close(); + return true; } // TODO: it is not necessary to break a raw chunk for two equal pixels (for the matter of the resulting size) -bool TGAImage::unload_rle_data(std::ofstream &out) const { - const unsigned char max_chunk_length = 128; - unsigned long npixels = width*height; - unsigned long curpix = 0; - while (curpix=width || y>=height) { - return TGAColor(128.f,128.f,128.f,255.f); - } - return TGAColor(data+(x+y*width)*bytespp, bytespp); +TGAColor TGAImage::get(int x, int y) const +{ + if (!data || x < 0 || y < 0 || x >= width || y >= height) + { + return TGAColor(128.f, 128.f, 128.f, 255.f); + } + return TGAColor(data + (x + y * width) * bytespp, bytespp); } -bool TGAImage::set(int x, int y, TGAColor &c) { - if (!data || x<0 || y<0 || x>=width || y>=height) { - return false; - } - memcpy(data+(x+y*width)*bytespp, c.bgra, bytespp); - return true; +bool TGAImage::set(int x, int y, TGAColor &c) +{ + if (!data || x < 0 || y < 0 || x >= width || y >= height) + { + return false; + } + memcpy(data + (x + y * width) * bytespp, c.bgra, bytespp); + return true; } -bool TGAImage::set(int x, int y, const TGAColor &c) { - if (!data || x<0 || y<0 || x>=width || y>=height) { - return false; - } - memcpy(data+(x+y*width)*bytespp, c.bgra, bytespp); - return true; +bool TGAImage::set(int x, int y, const TGAColor &c) +{ + if (!data || x < 0 || y < 0 || x >= width || y >= height) + { + return false; + } + memcpy(data + (x + y * width) * bytespp, c.bgra, bytespp); + return true; } -int TGAImage::get_bytespp() { - return bytespp; +int TGAImage::get_bytespp() +{ + return bytespp; } -int TGAImage::get_width() { - return width; +int TGAImage::get_width() +{ + return width; } -int TGAImage::get_height() { - return height; +int TGAImage::get_height() +{ + return height; } -bool TGAImage::flip_horizontally() { - if (!data) return false; - int half = width>>1; - for (int i=0; i> 1; + for (int i = 0; i < half; i++) + { + for (int j = 0; j < height; j++) + { + TGAColor c1 = get(i, j); + TGAColor c2 = get(width - 1 - i, j); + set(i, j, c2); + set(width - 1 - i, j, c1); + } + } + return true; } -bool TGAImage::flip_vertically() { - if (!data) return false; - unsigned long bytes_per_line = width*bytespp; - unsigned char *line = new unsigned char[bytes_per_line]; - int half = height>>1; - for (int j=0; j> 1; + for (int j = 0; j < half; j++) + { + unsigned long l1 = j * bytes_per_line; + unsigned long l2 = (height - 1 - j) * bytes_per_line; + memmove((void *)line, (void *)(data + l1), bytes_per_line); + memmove((void *)(data + l1), (void *)(data + l2), bytes_per_line); + memmove((void *)(data + l2), (void *)line, bytes_per_line); + } + delete[] line; + return true; } -unsigned char *TGAImage::buffer() { - return data; +unsigned char *TGAImage::buffer() +{ + return data; } -void TGAImage::clear() { - memset((void *)data, 0, width*height*bytespp); +void TGAImage::clear() +{ + memset((void *)data, 0, width * height * bytespp); } -bool TGAImage::scale(int w, int h) { - if (w<=0 || h<=0 || !data) return false; - unsigned char *tdata = new unsigned char[w*h*bytespp]; - int nscanline = 0; - int oscanline = 0; - int erry = 0; - unsigned long nlinebytes = w*bytespp; - unsigned long olinebytes = width*bytespp; - for (int j=0; j=(int)width) { - errx -= width; - nx += bytespp; - memcpy(tdata+nscanline+nx, data+oscanline+ox, bytespp); - } - } - erry += h; - oscanline += olinebytes; - while (erry>=(int)height) { - if (erry>=(int)height<<1) // it means we jump over a scanline - memcpy(tdata+nscanline+nlinebytes, tdata+nscanline, nlinebytes); - erry -= height; - nscanline += nlinebytes; - } - } - delete [] data; - data = tdata; - width = w; - height = h; - return true; +bool TGAImage::scale(int w, int h) +{ + if (w <= 0 || h <= 0 || !data) return false; + unsigned char *tdata = new unsigned char[w * h * bytespp]; + int nscanline = 0; + int oscanline = 0; + int erry = 0; + unsigned long nlinebytes = w * bytespp; + unsigned long olinebytes = width * bytespp; + for (int j = 0; j < height; j++) + { + int errx = width - w; + int nx = -bytespp; + int ox = -bytespp; + for (int i = 0; i < width; i++) + { + ox += bytespp; + errx += w; + while (errx >= (int)width) + { + errx -= width; + nx += bytespp; + memcpy(tdata + nscanline + nx, data + oscanline + ox, bytespp); + } + } + erry += h; + oscanline += olinebytes; + while (erry >= (int)height) + { + if (erry >= (int)height << 1) // it means we jump over a scanline + memcpy(tdata + nscanline + nlinebytes, tdata + nscanline, nlinebytes); + erry -= height; + nscanline += nlinebytes; + } + } + delete[] data; + data = tdata; + width = w; + height = h; + return true; } - diff --git a/examples/TinyRenderer/tgaimage.h b/examples/TinyRenderer/tgaimage.h index 80818dda7..7df593a08 100644 --- a/examples/TinyRenderer/tgaimage.h +++ b/examples/TinyRenderer/tgaimage.h @@ -3,99 +3,110 @@ #include -#pragma pack(push,1) -struct TGA_Header { - char idlength; - char colormaptype; - char datatypecode; - short colormaporigin; - short colormaplength; - char colormapdepth; - short x_origin; - short y_origin; - short width; - short height; - char bitsperpixel; - char imagedescriptor; +#pragma pack(push, 1) +struct TGA_Header +{ + char idlength; + char colormaptype; + char datatypecode; + short colormaporigin; + short colormaplength; + char colormapdepth; + short x_origin; + short y_origin; + short width; + short height; + char bitsperpixel; + char imagedescriptor; }; #pragma pack(pop) -struct TGAColor { - unsigned char bgra[4]; - unsigned char bytespp; +struct TGAColor +{ + unsigned char bgra[4]; + unsigned char bytespp; - TGAColor() : bytespp(1) + TGAColor() : bytespp(1) { - for (int i=0; i<4; i++) + for (int i = 0; i < 4; i++) bgra[i] = 0; - } + } - TGAColor(unsigned char R, unsigned char G, unsigned char B, unsigned char A=255) : bytespp(4) { - bgra[0] = B; - bgra[1] = G; - bgra[2] = R; - bgra[3] = A; - } + TGAColor(unsigned char R, unsigned char G, unsigned char B, unsigned char A = 255) : bytespp(4) + { + bgra[0] = B; + bgra[1] = G; + bgra[2] = R; + bgra[3] = A; + } - TGAColor(unsigned char v) : bytespp(1) { - for (int i=0; i<4; i++) bgra[i] = 0; - bgra[0] = v; - } + TGAColor(unsigned char v) : bytespp(1) + { + for (int i = 0; i < 4; i++) bgra[i] = 0; + bgra[0] = v; + } + TGAColor(const unsigned char *p, unsigned char bpp) : bytespp(bpp) + { + for (int i = 0; i < (int)bpp; i++) + { + bgra[i] = p[i]; + } + for (int i = bpp; i < 4; i++) + { + bgra[i] = 0; + } + } - TGAColor(const unsigned char *p, unsigned char bpp) : bytespp(bpp) { - for (int i=0; i<(int)bpp; i++) { - bgra[i] = p[i]; - } - for (int i=bpp; i<4; i++) { - bgra[i] = 0; - } - } + unsigned char &operator[](const int i) { return bgra[i]; } - unsigned char& operator[](const int i) { return bgra[i]; } - - TGAColor operator *(float intensity) const { - TGAColor res = *this; - intensity = (intensity>1.f?1.f:(intensity<0.f?0.f:intensity)); - for (int i=0; i<4; i++) res.bgra[i] = bgra[i]*intensity; - return res; - } + TGAColor operator*(float intensity) const + { + TGAColor res = *this; + intensity = (intensity > 1.f ? 1.f : (intensity < 0.f ? 0.f : intensity)); + for (int i = 0; i < 4; i++) res.bgra[i] = bgra[i] * intensity; + return res; + } }; -class TGAImage { +class TGAImage +{ protected: - unsigned char* data; - int width; - int height; - int bytespp; + unsigned char *data; + int width; + int height; + int bytespp; + + bool load_rle_data(std::ifstream &in); + bool unload_rle_data(std::ofstream &out) const; - bool load_rle_data(std::ifstream &in); - bool unload_rle_data(std::ofstream &out) const; public: - enum Format { - GRAYSCALE=1, RGB=3, RGBA=4 - }; + enum Format + { + GRAYSCALE = 1, + RGB = 3, + RGBA = 4 + }; - TGAImage(); - TGAImage(int w, int h, int bpp); - TGAImage(const TGAImage &img); - bool read_tga_file(const char *filename); - bool write_tga_file(const char *filename, bool rle=true) const; - bool flip_horizontally(); - bool flip_vertically(); - bool scale(int w, int h); - TGAColor get(int x, int y) const; - - bool set(int x, int y, TGAColor &c); - bool set(int x, int y, const TGAColor &c); - ~TGAImage(); - TGAImage & operator =(const TGAImage &img); - int get_width(); - int get_height(); - int get_bytespp(); - unsigned char *buffer(); - void clear(); + TGAImage(); + TGAImage(int w, int h, int bpp); + TGAImage(const TGAImage &img); + bool read_tga_file(const char *filename); + bool write_tga_file(const char *filename, bool rle = true) const; + bool flip_horizontally(); + bool flip_vertically(); + bool scale(int w, int h); + TGAColor get(int x, int y) const; + + bool set(int x, int y, TGAColor &c); + bool set(int x, int y, const TGAColor &c); + ~TGAImage(); + TGAImage &operator=(const TGAImage &img); + int get_width(); + int get_height(); + int get_bytespp(); + unsigned char *buffer(); + void clear(); }; -#endif //__IMAGE_H__ - +#endif //__IMAGE_H__ diff --git a/examples/Tutorial/Dof6ConstraintTutorial.cpp b/examples/Tutorial/Dof6ConstraintTutorial.cpp index 889182e11..333c474e2 100644 --- a/examples/Tutorial/Dof6ConstraintTutorial.cpp +++ b/examples/Tutorial/Dof6ConstraintTutorial.cpp @@ -10,37 +10,32 @@ #include "BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h" - #ifndef M_PI -#define M_PI 3.14159265358979323846 +#define M_PI 3.14159265358979323846 #endif #ifndef M_PI_2 -#define M_PI_2 1.57079632679489661923 +#define M_PI_2 1.57079632679489661923 #endif #ifndef M_PI_4 -#define M_PI_4 0.785398163397448309616 +#define M_PI_4 0.785398163397448309616 #endif - extern float g_additionalBodyMass; //comment this out to compare with original spring constraint #define USE_6DOF2 #ifdef USE_6DOF2 - #define CONSTRAINT_TYPE btGeneric6DofSpring2Constraint - #define EXTRAPARAMS +#define CONSTRAINT_TYPE btGeneric6DofSpring2Constraint +#define EXTRAPARAMS #else - #define CONSTRAINT_TYPE btGeneric6DofSpringConstraint - #define EXTRAPARAMS ,true +#define CONSTRAINT_TYPE btGeneric6DofSpringConstraint +#define EXTRAPARAMS , true #endif #include "../CommonInterfaces/CommonRigidBodyBase.h" - - - struct Dof6ConstraintTutorial : public CommonRigidBodyBase { struct Dof6ConstraintTutorialInternalData* m_data; @@ -58,49 +53,46 @@ struct Dof6ConstraintTutorial : public CommonRigidBodyBase float dist = 5; float pitch = -35; float yaw = 722; - float targetPos[3]={4,2,-11}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {4, 2, -11}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } }; - - struct Dof6ConstraintTutorialInternalData { - btRigidBody* m_TranslateSpringBody; - btRigidBody* m_TranslateSpringBody2; - btRigidBody* m_RotateSpringBody; - btRigidBody* m_RotateSpringBody2; - btRigidBody* m_BouncingTranslateBody; - btRigidBody* m_MotorBody; - btRigidBody* m_ServoMotorBody; - btRigidBody* m_ChainLeftBody; - btRigidBody* m_ChainRightBody; - CONSTRAINT_TYPE* m_ServoMotorConstraint; - CONSTRAINT_TYPE* m_ChainLeftConstraint; - CONSTRAINT_TYPE* m_ChainRightConstraint; - - TimeSeriesCanvas* m_timeSeriesCanvas; - + btRigidBody* m_TranslateSpringBody; + btRigidBody* m_TranslateSpringBody2; + btRigidBody* m_RotateSpringBody; + btRigidBody* m_RotateSpringBody2; + btRigidBody* m_BouncingTranslateBody; + btRigidBody* m_MotorBody; + btRigidBody* m_ServoMotorBody; + btRigidBody* m_ChainLeftBody; + btRigidBody* m_ChainRightBody; + CONSTRAINT_TYPE* m_ServoMotorConstraint; + CONSTRAINT_TYPE* m_ChainLeftConstraint; + CONSTRAINT_TYPE* m_ChainRightConstraint; + + TimeSeriesCanvas* m_timeSeriesCanvas; + float mDt; unsigned int frameID; Dof6ConstraintTutorialInternalData() - : mDt(1./60.),frameID(0) + : mDt(1. / 60.), frameID(0) { } }; Dof6ConstraintTutorial::Dof6ConstraintTutorial(struct GUIHelperInterface* helper) - :CommonRigidBodyBase(helper) + : CommonRigidBodyBase(helper) { m_data = new Dof6ConstraintTutorialInternalData; - m_data->m_timeSeriesCanvas = new TimeSeriesCanvas(helper->get2dCanvasInterface(),256,256,"Position and Velocity"); - m_data->m_timeSeriesCanvas ->setupTimeSeries(20,100, 0); - m_data->m_timeSeriesCanvas->addDataSource("X position (m)", 255,0,0); - m_data->m_timeSeriesCanvas->addDataSource("X velocity (m/s)", 0,0,255); - m_data->m_timeSeriesCanvas->addDataSource("dX/dt (m/s)", 0,0,0); - + m_data->m_timeSeriesCanvas = new TimeSeriesCanvas(helper->get2dCanvasInterface(), 256, 256, "Position and Velocity"); + m_data->m_timeSeriesCanvas->setupTimeSeries(20, 100, 0); + m_data->m_timeSeriesCanvas->addDataSource("X position (m)", 255, 0, 0); + m_data->m_timeSeriesCanvas->addDataSource("X velocity (m/s)", 0, 0, 255); + m_data->m_timeSeriesCanvas->addDataSource("dX/dt (m/s)", 0, 0, 0); } Dof6ConstraintTutorial::~Dof6ConstraintTutorial() { @@ -112,99 +104,99 @@ Dof6ConstraintTutorial::~Dof6ConstraintTutorial() void Dof6ConstraintTutorial::initPhysics() { // Setup the basic world - + m_guiHelper->setUpAxis(1); - m_collisionConfiguration = new btDefaultCollisionConfiguration(); - m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); - btVector3 worldAabbMin(-10000,-10000,-10000); - btVector3 worldAabbMax(10000,10000,10000); - m_broadphase = new btAxisSweep3 (worldAabbMin, worldAabbMax); + m_collisionConfiguration = new btDefaultCollisionConfiguration(); + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + btVector3 worldAabbMin(-10000, -10000, -10000); + btVector3 worldAabbMax(10000, 10000, 10000); + m_broadphase = new btAxisSweep3(worldAabbMin, worldAabbMax); -/////// uncomment the corresponding line to test a solver. - //m_solver = new btSequentialImpulseConstraintSolver; - m_solver = new btNNCGConstraintSolver; - //m_solver = new btMLCPSolver(new btSolveProjectedGaussSeidel()); - //m_solver = new btMLCPSolver(new btDantzigSolver()); - //m_solver = new btMLCPSolver(new btLemkeSolver()); + /////// uncomment the corresponding line to test a solver. + //m_solver = new btSequentialImpulseConstraintSolver; + m_solver = new btNNCGConstraintSolver; + //m_solver = new btMLCPSolver(new btSolveProjectedGaussSeidel()); + //m_solver = new btMLCPSolver(new btDantzigSolver()); + //m_solver = new btMLCPSolver(new btLemkeSolver()); - m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); - m_dynamicsWorld->getDispatchInfo().m_useContinuous = true; - m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); - - m_dynamicsWorld->setGravity(btVector3(0,0,0)); + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration); + m_dynamicsWorld->getDispatchInfo().m_useContinuous = true; + m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); - // Setup a big ground box + m_dynamicsWorld->setGravity(btVector3(0, 0, 0)); + + // Setup a big ground box if (0) - { - btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.),btScalar(5.),btScalar(200.))); - btTransform groundTransform; - groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0,-10,0)); + { + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(200.), btScalar(5.), btScalar(200.))); + btTransform groundTransform; + groundTransform.setIdentity(); + groundTransform.setOrigin(btVector3(0, -10, 0)); #define CREATE_GROUND_COLLISION_OBJECT 1 #ifdef CREATE_GROUND_COLLISION_OBJECT - btCollisionObject* fixedGround = new btCollisionObject(); - fixedGround->setCollisionShape(groundShape); - fixedGround->setWorldTransform(groundTransform); - m_dynamicsWorld->addCollisionObject(fixedGround); + btCollisionObject* fixedGround = new btCollisionObject(); + fixedGround->setCollisionShape(groundShape); + fixedGround->setWorldTransform(groundTransform); + m_dynamicsWorld->addCollisionObject(fixedGround); #else - localCreateRigidBody(btScalar(0.),groundTransform,groundShape); -#endif //CREATE_GROUND_COLLISION_OBJECT - } + localCreateRigidBody(btScalar(0.), groundTransform, groundShape); +#endif //CREATE_GROUND_COLLISION_OBJECT + } - m_dynamicsWorld->getSolverInfo().m_numIterations = 100; + m_dynamicsWorld->getSolverInfo().m_numIterations = 100; - btCollisionShape* shape; - btVector3 localInertia(0,0,0); - btDefaultMotionState* motionState; - btTransform bodyTransform; - btScalar mass; - btTransform localA; - btTransform localB; - CONSTRAINT_TYPE* constraint; + btCollisionShape* shape; + btVector3 localInertia(0, 0, 0); + btDefaultMotionState* motionState; + btTransform bodyTransform; + btScalar mass; + btTransform localA; + btTransform localB; + CONSTRAINT_TYPE* constraint; + //static body centered in the origo + mass = 0.0; + shape = new btBoxShape(btVector3(0.5, 0.5, 0.5)); + localInertia = btVector3(0, 0, 0); + bodyTransform.setIdentity(); + motionState = new btDefaultMotionState(bodyTransform); + btRigidBody* staticBody = new btRigidBody(mass, motionState, shape, localInertia); + m_dynamicsWorld->addRigidBody(staticBody); - //static body centered in the origo - mass = 0.0; - shape= new btBoxShape(btVector3(0.5,0.5,0.5)); - localInertia = btVector3(0,0,0); + /////////// box with undamped translate spring attached to static body + /////////// the box should oscillate left-to-right forever + { + mass = 1.0; + shape = new btBoxShape(btVector3(0.5, 0.5, 0.5)); + shape->calculateLocalInertia(mass, localInertia); bodyTransform.setIdentity(); + bodyTransform.setOrigin(btVector3(-2, 0, -5)); motionState = new btDefaultMotionState(bodyTransform); - btRigidBody* staticBody = new btRigidBody(mass,motionState,shape,localInertia); - m_dynamicsWorld->addRigidBody(staticBody); - -/////////// box with undamped translate spring attached to static body -/////////// the box should oscillate left-to-right forever - { - mass = 1.0; - shape= new btBoxShape(btVector3(0.5,0.5,0.5)); - shape->calculateLocalInertia(mass,localInertia); - bodyTransform.setIdentity(); - bodyTransform.setOrigin(btVector3(-2,0,-5)); - motionState = new btDefaultMotionState(bodyTransform); - m_data->m_TranslateSpringBody = new btRigidBody(mass,motionState,shape,localInertia); - m_data->m_TranslateSpringBody->setActivationState(DISABLE_DEACTIVATION); - m_dynamicsWorld->addRigidBody(m_data->m_TranslateSpringBody); - localA.setIdentity();localA.getOrigin() = btVector3(0,0,-5); - localB.setIdentity(); - constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_TranslateSpringBody, localA, localB EXTRAPARAMS); - constraint->setLimit(0, 1,-1); - constraint->setLimit(1, 0, 0); - constraint->setLimit(2, 0, 0); - constraint->setLimit(3, 0, 0); - constraint->setLimit(4, 0, 0); - constraint->setLimit(5, 0, 0); - constraint->enableSpring(0, true); - constraint->setStiffness(0, 100); - #ifdef USE_6DOF2 - constraint->setDamping(0, 0); - #else - constraint->setDamping(0, 1); - #endif - constraint->setEquilibriumPoint(0, 0); - constraint->setDbgDrawSize(btScalar(2.f)); - m_dynamicsWorld->addConstraint(constraint, true); - } + m_data->m_TranslateSpringBody = new btRigidBody(mass, motionState, shape, localInertia); + m_data->m_TranslateSpringBody->setActivationState(DISABLE_DEACTIVATION); + m_dynamicsWorld->addRigidBody(m_data->m_TranslateSpringBody); + localA.setIdentity(); + localA.getOrigin() = btVector3(0, 0, -5); + localB.setIdentity(); + constraint = new CONSTRAINT_TYPE(*staticBody, *m_data->m_TranslateSpringBody, localA, localB EXTRAPARAMS); + constraint->setLimit(0, 1, -1); + constraint->setLimit(1, 0, 0); + constraint->setLimit(2, 0, 0); + constraint->setLimit(3, 0, 0); + constraint->setLimit(4, 0, 0); + constraint->setLimit(5, 0, 0); + constraint->enableSpring(0, true); + constraint->setStiffness(0, 100); +#ifdef USE_6DOF2 + constraint->setDamping(0, 0); +#else + constraint->setDamping(0, 1); +#endif + constraint->setEquilibriumPoint(0, 0); + constraint->setDbgDrawSize(btScalar(2.f)); + m_dynamicsWorld->addConstraint(constraint, true); + } #if 0 /////////// box with rotate spring, attached to static body /////////// box should swing (rotate) left-to-right forever @@ -229,11 +221,11 @@ void Dof6ConstraintTutorial::initPhysics() constraint->setLimit(5, 1, -1); constraint->enableSpring(5, true); constraint->setStiffness(5, 100); - #ifdef USE_6DOF2 +#ifdef USE_6DOF2 constraint->setDamping(5, 0); - #else +#else constraint->setDamping(5, 1); - #endif +#endif constraint->setEquilibriumPoint(0, 0); constraint->setDbgDrawSize(btScalar(2.f)); m_dynamicsWorld->addConstraint(constraint, true); @@ -262,11 +254,11 @@ void Dof6ConstraintTutorial::initPhysics() constraint->setLimit(3, 0, 0); constraint->setLimit(4, 0, 0); constraint->setLimit(5, 0, 0); - #ifdef USE_6DOF2 +#ifdef USE_6DOF2 constraint->setBounce(0,0); - #else //bounce is named restitution in 6dofspring, but not implemented for translational limit motor, so the following line has no effect +#else //bounce is named restitution in 6dofspring, but not implemented for translational limit motor, so the following line has no effect constraint->getTranslationalLimitMotor()->m_restitution = 0.0; - #endif +#endif constraint->setParam(BT_CONSTRAINT_STOP_ERP,0.995,0); constraint->setParam(BT_CONSTRAINT_STOP_CFM,0.0,0); constraint->setDbgDrawSize(btScalar(2.f)); @@ -278,11 +270,11 @@ void Dof6ConstraintTutorial::initPhysics() constraint->setLimit(3, 0, 0); constraint->setLimit(4, 0, 0); constraint->setLimit(5, 0, 0); - #ifdef USE_6DOF2 +#ifdef USE_6DOF2 constraint->setBounce(0,1); - #else //bounce is named restitution in 6dofspring, but not implemented for translational limit motor, so the following line has no effect +#else //bounce is named restitution in 6dofspring, but not implemented for translational limit motor, so the following line has no effect constraint->getTranslationalLimitMotor()->m_restitution = 1.0; - #endif +#endif constraint->setParam(BT_CONSTRAINT_STOP_ERP,0.995,0); constraint->setParam(BT_CONSTRAINT_STOP_CFM,0.0,0); constraint->setDbgDrawSize(btScalar(2.f)); @@ -310,15 +302,15 @@ void Dof6ConstraintTutorial::initPhysics() constraint->setLimit(3, 0, 0); constraint->setLimit(4, 0, 0); constraint->setLimit(5, 1,-1); - #ifdef USE_6DOF2 +#ifdef USE_6DOF2 constraint->enableMotor(5,true); constraint->setTargetVelocity(5,3.f); constraint->setMaxMotorForce(5,600.f); - #else +#else constraint->getRotationalLimitMotor(2)->m_enableMotor = true; constraint->getRotationalLimitMotor(2)->m_targetVelocity = 3.f; constraint->getRotationalLimitMotor(2)->m_maxMotorForce = 600.f; - #endif +#endif constraint->setDbgDrawSize(btScalar(2.f)); m_dynamicsWorld->addConstraint(constraint, true); } @@ -345,18 +337,18 @@ void Dof6ConstraintTutorial::initPhysics() constraint->setLimit(3, 0, 0); constraint->setLimit(4, 0, 0); constraint->setLimit(5, 1,-1); - #ifdef USE_6DOF2 +#ifdef USE_6DOF2 constraint->enableMotor(5,true); constraint->setTargetVelocity(5,3.f); constraint->setMaxMotorForce(5,600.f); constraint->setServo(5,true); constraint->setServoTarget(5, M_PI_2); - #else +#else constraint->getRotationalLimitMotor(2)->m_enableMotor = true; constraint->getRotationalLimitMotor(2)->m_targetVelocity = 3.f; constraint->getRotationalLimitMotor(2)->m_maxMotorForce = 600.f; //servo motor is not implemented in 6dofspring constraint - #endif +#endif constraint->setDbgDrawSize(btScalar(2.f)); m_dynamicsWorld->addConstraint(constraint, true); m_data->m_ServoMotorConstraint = constraint; @@ -447,88 +439,83 @@ void Dof6ConstraintTutorial::initPhysics() } } #endif - m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); + m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } - void Dof6ConstraintTutorial::animate() { - /////// servo motor: flip its target periodically #ifdef USE_6DOF2 - static float servoNextFrame = -1; - //btScalar pos = m_data->m_ServoMotorConstraint->getRotationalLimitMotor(2)->m_currentPosition; - //btScalar target = m_data->m_ServoMotorConstraint->getRotationalLimitMotor(2)->m_servoTarget; - if(servoNextFrame < 0) - { - m_data->m_ServoMotorConstraint->getRotationalLimitMotor(2)->m_servoTarget *= -1; - servoNextFrame = 3.0; - } - servoNextFrame -= m_data->mDt; + static float servoNextFrame = -1; + //btScalar pos = m_data->m_ServoMotorConstraint->getRotationalLimitMotor(2)->m_currentPosition; + //btScalar target = m_data->m_ServoMotorConstraint->getRotationalLimitMotor(2)->m_servoTarget; + if (servoNextFrame < 0) + { + m_data->m_ServoMotorConstraint->getRotationalLimitMotor(2)->m_servoTarget *= -1; + servoNextFrame = 3.0; + } + servoNextFrame -= m_data->mDt; #endif -/////// constraint chain: pull the chain left and right periodically - static float chainNextFrame = -1; - static bool left = true; - if(chainNextFrame < 0) + /////// constraint chain: pull the chain left and right periodically + static float chainNextFrame = -1; + static bool left = true; + if (chainNextFrame < 0) + { + if (!left) { - if(!left) - { - m_data->m_ChainRightBody->setActivationState(ACTIVE_TAG); - m_dynamicsWorld->removeConstraint(m_data->m_ChainRightConstraint); - m_data->m_ChainLeftConstraint->setDbgDrawSize(btScalar(2.f)); - m_dynamicsWorld->addConstraint(m_data->m_ChainLeftConstraint, true); - } - else - { - m_data->m_ChainLeftBody->setActivationState(ACTIVE_TAG); - m_dynamicsWorld->removeConstraint(m_data->m_ChainLeftConstraint); - m_data->m_ChainRightConstraint->setDbgDrawSize(btScalar(2.f)); - m_dynamicsWorld->addConstraint(m_data->m_ChainRightConstraint, true); - } - chainNextFrame = 3.0; - left = !left; + m_data->m_ChainRightBody->setActivationState(ACTIVE_TAG); + m_dynamicsWorld->removeConstraint(m_data->m_ChainRightConstraint); + m_data->m_ChainLeftConstraint->setDbgDrawSize(btScalar(2.f)); + m_dynamicsWorld->addConstraint(m_data->m_ChainLeftConstraint, true); } - chainNextFrame -= m_data->mDt; - -/////// bouncing constraint: push the box periodically - m_data->m_BouncingTranslateBody->setActivationState(ACTIVE_TAG); - static float bounceNextFrame = -1; - if(bounceNextFrame < 0) + else { - m_data->m_BouncingTranslateBody->applyCentralImpulse(btVector3(10,0,0)); - bounceNextFrame = 3.0; + m_data->m_ChainLeftBody->setActivationState(ACTIVE_TAG); + m_dynamicsWorld->removeConstraint(m_data->m_ChainLeftConstraint); + m_data->m_ChainRightConstraint->setDbgDrawSize(btScalar(2.f)); + m_dynamicsWorld->addConstraint(m_data->m_ChainRightConstraint, true); } - bounceNextFrame -= m_data->mDt; + chainNextFrame = 3.0; + left = !left; + } + chainNextFrame -= m_data->mDt; - m_data->frameID++; + /////// bouncing constraint: push the box periodically + m_data->m_BouncingTranslateBody->setActivationState(ACTIVE_TAG); + static float bounceNextFrame = -1; + if (bounceNextFrame < 0) + { + m_data->m_BouncingTranslateBody->applyCentralImpulse(btVector3(10, 0, 0)); + bounceNextFrame = 3.0; + } + bounceNextFrame -= m_data->mDt; + + m_data->frameID++; } - void Dof6ConstraintTutorial::stepSimulation(float deltaTime) { //animate(); - //float time = m_data->m_timeSeriesCanvas->getCurrentTime(); - + float prevPos = m_data->m_TranslateSpringBody->getWorldTransform().getOrigin().x(); m_dynamicsWorld->stepSimulation(deltaTime); float xPos = m_data->m_TranslateSpringBody->getWorldTransform().getOrigin().x(); - m_data->m_timeSeriesCanvas->insertDataAtCurrentTime(xPos,0,true); - m_data->m_timeSeriesCanvas->insertDataAtCurrentTime(m_data->m_TranslateSpringBody->getLinearVelocity().x(),1,true); + m_data->m_timeSeriesCanvas->insertDataAtCurrentTime(xPos, 0, true); + m_data->m_timeSeriesCanvas->insertDataAtCurrentTime(m_data->m_TranslateSpringBody->getLinearVelocity().x(), 1, true); - if (deltaTime>0) + if (deltaTime > 0) { - m_data->m_timeSeriesCanvas->insertDataAtCurrentTime((xPos-prevPos)/deltaTime,2,true); + m_data->m_timeSeriesCanvas->insertDataAtCurrentTime((xPos - prevPos) / deltaTime, 2, true); } prevPos = xPos; m_data->m_timeSeriesCanvas->nextTick(); - } -class CommonExampleInterface* Dof6ConstraintTutorialCreateFunc( CommonExampleOptions& options) +class CommonExampleInterface* Dof6ConstraintTutorialCreateFunc(CommonExampleOptions& options) { return new Dof6ConstraintTutorial(options.m_guiHelper); } diff --git a/examples/Tutorial/Dof6ConstraintTutorial.h b/examples/Tutorial/Dof6ConstraintTutorial.h index 90e45351c..c00f2759d 100644 --- a/examples/Tutorial/Dof6ConstraintTutorial.h +++ b/examples/Tutorial/Dof6ConstraintTutorial.h @@ -1,6 +1,6 @@ #ifndef GENERIC_6DOF_SPRING2_CONSTRAINT_TUTORIAL_H #define GENERIC_6DOF_SPRING2_CONSTRAINT_TUTORIAL_H -class CommonExampleInterface* Dof6ConstraintTutorialCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* Dof6ConstraintTutorialCreateFunc(struct CommonExampleOptions& options); -#endif //GENERIC_6DOF_SPRING2_CONSTRAINT_TUTORIAL_H +#endif //GENERIC_6DOF_SPRING2_CONSTRAINT_TUTORIAL_H diff --git a/examples/Tutorial/Tutorial.cpp b/examples/Tutorial/Tutorial.cpp index 8d43daac2..439eda6ed 100644 --- a/examples/Tutorial/Tutorial.cpp +++ b/examples/Tutorial/Tutorial.cpp @@ -14,7 +14,7 @@ #include "../CommonInterfaces/CommonParameterInterface.h" #include "LinearMath/btAlignedObjectArray.h" -#define stdvector btAlignedObjectArray +#define stdvector btAlignedObjectArray #define SPHERE_RADIUS 1 static btScalar gRestitution = 0.f; @@ -32,18 +32,18 @@ struct LWPlane { BT_DECLARE_ALIGNED_ALLOCATOR(); - b3Vector3 m_normal; - btScalar m_planeConstant; + b3Vector3 m_normal; + btScalar m_planeConstant; }; struct LWSphere { - btScalar m_radius; - + btScalar m_radius; + void computeLocalInertia(b3Scalar mass, b3Vector3& localInertia) { - btScalar elem = b3Scalar(0.4) * mass * m_radius*m_radius; - localInertia.setValue(elem,elem,elem); + btScalar elem = b3Scalar(0.4) * mass * m_radius * m_radius; + localInertia.setValue(elem, elem, elem); } }; @@ -56,77 +56,76 @@ struct LWBox struct LWCollisionShape { LWEnumCollisionTypes m_type; - union - { - LWPlane m_plane; - LWSphere m_sphere; - LWBox m_box; + union { + LWPlane m_plane; + LWSphere m_sphere; + LWBox m_box; }; - }; struct LWPose { BT_DECLARE_ALIGNED_ALLOCATOR(); - b3Vector3 m_position; - b3Quaternion m_orientation; + b3Vector3 m_position; + b3Quaternion m_orientation; LWPose() - :m_position(b3MakeVector3(0,0,0)), - m_orientation(0,0,0,1) + : m_position(b3MakeVector3(0, 0, 0)), + m_orientation(0, 0, 0, 1) { } - + b3Vector3 transformPoint(const b3Vector3& pointIn) { - b3Vector3 rotPoint = b3QuatRotate(m_orientation,pointIn); - return rotPoint+m_position; + b3Vector3 rotPoint = b3QuatRotate(m_orientation, pointIn); + return rotPoint + m_position; } - }; struct LWContactPoint { b3Vector3 m_ptOnAWorld; b3Vector3 m_ptOnBWorld; b3Vector3 m_normalOnB; - btScalar m_distance; + btScalar m_distance; }; ///returns true if we found a pair of closest points -void ComputeClosestPointsPlaneSphere(const LWPlane& planeWorld, const LWSphere& sphere, const LWPose& spherePose, LWContactPoint& pointOut) { +void ComputeClosestPointsPlaneSphere(const LWPlane& planeWorld, const LWSphere& sphere, const LWPose& spherePose, LWContactPoint& pointOut) +{ b3Vector3 spherePosWorld = spherePose.m_position; - btScalar t = -(spherePosWorld.dot(-planeWorld.m_normal)+planeWorld.m_planeConstant); - b3Vector3 intersectionPoint = spherePosWorld+t*-planeWorld.m_normal; - b3Scalar distance = t-sphere.m_radius; + btScalar t = -(spherePosWorld.dot(-planeWorld.m_normal) + planeWorld.m_planeConstant); + b3Vector3 intersectionPoint = spherePosWorld + t * -planeWorld.m_normal; + b3Scalar distance = t - sphere.m_radius; pointOut.m_distance = distance; pointOut.m_ptOnBWorld = intersectionPoint; - pointOut.m_ptOnAWorld = spherePosWorld+sphere.m_radius*-planeWorld.m_normal; + pointOut.m_ptOnAWorld = spherePosWorld + sphere.m_radius * -planeWorld.m_normal; pointOut.m_normalOnB = planeWorld.m_normal; } -void ComputeClosestPointsSphereSphere(const LWSphere& sphereA, const LWPose& sphereAPose, const LWSphere& sphereB, const LWPose& sphereBPose, LWContactPoint& pointOut) { - b3Vector3 diff = sphereAPose.m_position-sphereBPose.m_position; +void ComputeClosestPointsSphereSphere(const LWSphere& sphereA, const LWPose& sphereAPose, const LWSphere& sphereB, const LWPose& sphereBPose, LWContactPoint& pointOut) +{ + b3Vector3 diff = sphereAPose.m_position - sphereBPose.m_position; btScalar len = diff.length(); - pointOut.m_distance = len - (sphereA.m_radius+sphereB.m_radius); - pointOut.m_normalOnB = b3MakeVector3(1,0,0); - if (len > B3_EPSILON) { + pointOut.m_distance = len - (sphereA.m_radius + sphereB.m_radius); + pointOut.m_normalOnB = b3MakeVector3(1, 0, 0); + if (len > B3_EPSILON) + { pointOut.m_normalOnB = diff / len; } - pointOut.m_ptOnAWorld = sphereAPose.m_position - sphereA.m_radius*pointOut.m_normalOnB; - pointOut.m_ptOnBWorld = pointOut.m_ptOnAWorld-pointOut.m_normalOnB*pointOut.m_distance; + pointOut.m_ptOnAWorld = sphereAPose.m_position - sphereA.m_radius * pointOut.m_normalOnB; + pointOut.m_ptOnBWorld = pointOut.m_ptOnAWorld - pointOut.m_normalOnB * pointOut.m_distance; } - enum LWRIGIDBODY_FLAGS { LWFLAG_USE_QUATERNION_DERIVATIVE = 1, - + }; struct LWRigidBody { BT_DECLARE_ALIGNED_ALLOCATOR(); - LWPose m_worldPose; + LWPose m_worldPose; b3Vector3 m_linearVelocity; b3Vector3 m_angularVelocity; b3Vector3 m_gravityAcceleration; @@ -138,128 +137,124 @@ struct LWRigidBody void computeInvInertiaTensorWorld() { b3Vector3 invInertiaLocal; - invInertiaLocal.setValue(m_localInertia.x != btScalar(0.0) ? btScalar(1.0) / m_localInertia.x: btScalar(0.0), - m_localInertia.y != btScalar(0.0) ? btScalar(1.0) / m_localInertia.y: btScalar(0.0), - m_localInertia.z != btScalar(0.0) ? btScalar(1.0) / m_localInertia.z: btScalar(0.0)); - b3Matrix3x3 m (m_worldPose.m_orientation); + invInertiaLocal.setValue(m_localInertia.x != btScalar(0.0) ? btScalar(1.0) / m_localInertia.x : btScalar(0.0), + m_localInertia.y != btScalar(0.0) ? btScalar(1.0) / m_localInertia.y : btScalar(0.0), + m_localInertia.z != btScalar(0.0) ? btScalar(1.0) / m_localInertia.z : btScalar(0.0)); + b3Matrix3x3 m(m_worldPose.m_orientation); m_invInertiaTensorWorld = m.scaled(invInertiaLocal) * m.transpose(); } - - int m_graphicsIndex; + + int m_graphicsIndex; LWCollisionShape m_collisionShape; - - - LWRIGIDBODY_FLAGS m_flags; - + + LWRIGIDBODY_FLAGS m_flags; + LWRigidBody() - :m_linearVelocity(b3MakeVector3(0,0,0)), - m_angularVelocity(b3MakeVector3(0,0,0)), - m_gravityAcceleration(b3MakeVector3(0,0,0)),//-10,0)), - m_flags(LWFLAG_USE_QUATERNION_DERIVATIVE) + : m_linearVelocity(b3MakeVector3(0, 0, 0)), + m_angularVelocity(b3MakeVector3(0, 0, 0)), + m_gravityAcceleration(b3MakeVector3(0, 0, 0)), //-10,0)), + m_flags(LWFLAG_USE_QUATERNION_DERIVATIVE) { - } - + const b3Vector3& getPosition() const { return m_worldPose.m_position; } - + b3Vector3 getVelocity(const b3Vector3& relPos) const { return m_linearVelocity + m_angularVelocity.cross(relPos); } - - void integrateAcceleration(double deltaTime) { - m_linearVelocity += m_gravityAcceleration*deltaTime; + + void integrateAcceleration(double deltaTime) + { + m_linearVelocity += m_gravityAcceleration * deltaTime; } - + void applyImpulse(const b3Vector3& impulse, const b3Vector3& rel_pos) { m_linearVelocity += impulse * m_invMass; b3Vector3 torqueImpulse = rel_pos.cross(impulse); m_angularVelocity += m_invInertiaTensorWorld * torqueImpulse; } - - void integrateVelocity(double deltaTime) + + void integrateVelocity(double deltaTime) { LWPose newPose; - - newPose.m_position = m_worldPose.m_position + m_linearVelocity*deltaTime; - + + newPose.m_position = m_worldPose.m_position + m_linearVelocity * deltaTime; + if (m_flags & LWFLAG_USE_QUATERNION_DERIVATIVE) { newPose.m_orientation = m_worldPose.m_orientation; newPose.m_orientation += (m_angularVelocity * newPose.m_orientation) * (deltaTime * btScalar(0.5)); newPose.m_orientation.normalize(); m_worldPose = newPose; - } else + } + else { //Exponential map //google for "Practical Parameterization of Rotations Using the Exponential Map", F. Sebastian Grassia - + //btQuaternion q_w = [ sin(|w|*dt/2) * w/|w| , cos(|w|*dt/2)] //btQuaternion q_new = q_w * q_old; - + b3Vector3 axis; - b3Scalar fAngle = m_angularVelocity.length(); + b3Scalar fAngle = m_angularVelocity.length(); //limit the angular motion - const btScalar angularMotionThreshold = btScalar(0.5)*SIMD_HALF_PI; - - if (fAngle*deltaTime > angularMotionThreshold) + const btScalar angularMotionThreshold = btScalar(0.5) * SIMD_HALF_PI; + + if (fAngle * deltaTime > angularMotionThreshold) { fAngle = angularMotionThreshold / deltaTime; } - - if ( fAngle < btScalar(0.001) ) + + if (fAngle < btScalar(0.001)) { // use Taylor's expansions of sync function - axis = m_angularVelocity*( btScalar(0.5)*deltaTime-(deltaTime*deltaTime*deltaTime)*(btScalar(0.020833333333))*fAngle*fAngle ); + axis = m_angularVelocity * (btScalar(0.5) * deltaTime - (deltaTime * deltaTime * deltaTime) * (btScalar(0.020833333333)) * fAngle * fAngle); } else { // sync(fAngle) = sin(c*fAngle)/t - axis = m_angularVelocity*( btSin(btScalar(0.5)*fAngle*deltaTime)/fAngle ); + axis = m_angularVelocity * (btSin(btScalar(0.5) * fAngle * deltaTime) / fAngle); } - b3Quaternion dorn (axis.x,axis.y,axis.z,btCos( fAngle*deltaTime*b3Scalar(0.5) )); + b3Quaternion dorn(axis.x, axis.y, axis.z, btCos(fAngle * deltaTime * b3Scalar(0.5))); b3Quaternion orn0 = m_worldPose.m_orientation; - + b3Quaternion predictedOrn = dorn * orn0; predictedOrn.normalize(); m_worldPose.m_orientation = predictedOrn; } - } - - - void stepSimulation(double deltaTime) + + void stepSimulation(double deltaTime) { integrateVelocity(deltaTime); } }; - b3Scalar resolveCollision(LWRigidBody& bodyA, - LWRigidBody& bodyB, - LWContactPoint& contactPoint) + LWRigidBody& bodyB, + LWContactPoint& contactPoint) { - b3Assert(contactPoint.m_distance<=0); - - + b3Assert(contactPoint.m_distance <= 0); + btScalar appliedImpulse = 0.f; - + b3Vector3 rel_pos1 = contactPoint.m_ptOnAWorld - bodyA.m_worldPose.m_position; b3Vector3 rel_pos2 = contactPoint.m_ptOnBWorld - bodyB.getPosition(); - + btScalar rel_vel = contactPoint.m_normalOnB.dot(bodyA.getVelocity(rel_pos1) - bodyB.getVelocity(rel_pos2)); - if (rel_vel < -B3_EPSILON) + if (rel_vel < -B3_EPSILON) { - b3Vector3 temp1 = bodyA.m_invInertiaTensorWorld * rel_pos1.cross(contactPoint.m_normalOnB); - b3Vector3 temp2 = bodyB.m_invInertiaTensorWorld * rel_pos2.cross(contactPoint.m_normalOnB); - - btScalar impulse = -(1.0f + gRestitution) * rel_vel / - (bodyA.m_invMass + bodyB.m_invMass + contactPoint.m_normalOnB.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2))); - + b3Vector3 temp1 = bodyA.m_invInertiaTensorWorld * rel_pos1.cross(contactPoint.m_normalOnB); + b3Vector3 temp2 = bodyB.m_invInertiaTensorWorld * rel_pos2.cross(contactPoint.m_normalOnB); + + btScalar impulse = -(1.0f + gRestitution) * rel_vel / + (bodyA.m_invMass + bodyB.m_invMass + contactPoint.m_normalOnB.dot(temp1.cross(rel_pos1) + temp2.cross(rel_pos2))); + b3Vector3 impulse_vector = contactPoint.m_normalOnB * impulse; b3Printf("impulse = %f\n", impulse); appliedImpulse = impulse; @@ -269,229 +264,213 @@ b3Scalar resolveCollision(LWRigidBody& bodyA, return appliedImpulse; } - - class Tutorial : public CommonExampleInterface { - CommonGraphicsApp* m_app; + CommonGraphicsApp* m_app; GUIHelperInterface* m_guiHelper; - int m_tutorialIndex; + int m_tutorialIndex; stdvector m_bodies; - - TimeSeriesCanvas* m_timeSeriesCanvas0; - TimeSeriesCanvas* m_timeSeriesCanvas1; + + TimeSeriesCanvas* m_timeSeriesCanvas0; + TimeSeriesCanvas* m_timeSeriesCanvas1; stdvector m_contactPoints; - + int m_stage; int m_counter; + public: - - Tutorial(GUIHelperInterface* guiHelper, int tutorialIndex) - :m_app(guiHelper->getAppInterface()), - m_guiHelper(guiHelper), - m_tutorialIndex(tutorialIndex), - m_timeSeriesCanvas0(0), - m_timeSeriesCanvas1(0), - m_stage(0), - m_counter(0) + Tutorial(GUIHelperInterface* guiHelper, int tutorialIndex) + : m_app(guiHelper->getAppInterface()), + m_guiHelper(guiHelper), + m_tutorialIndex(tutorialIndex), + m_timeSeriesCanvas0(0), + m_timeSeriesCanvas1(0), + m_stage(0), + m_counter(0) { int numBodies = 1; - + m_app->setUpAxis(1); - + switch (m_tutorialIndex) { case TUT_VELOCITY: { - numBodies=10; - m_timeSeriesCanvas0 = new TimeSeriesCanvas(m_app->m_2dCanvasInterface,512,256,"Constant Velocity"); - - m_timeSeriesCanvas0 ->setupTimeSeries(2,60, 0); - m_timeSeriesCanvas0->addDataSource("X position (m)", 255,0,0); - m_timeSeriesCanvas0->addDataSource("X velocity (m/s)", 0,0,255); - m_timeSeriesCanvas0->addDataSource("dX/dt (m/s)", 0,0,0); + numBodies = 10; + m_timeSeriesCanvas0 = new TimeSeriesCanvas(m_app->m_2dCanvasInterface, 512, 256, "Constant Velocity"); + + m_timeSeriesCanvas0->setupTimeSeries(2, 60, 0); + m_timeSeriesCanvas0->addDataSource("X position (m)", 255, 0, 0); + m_timeSeriesCanvas0->addDataSource("X velocity (m/s)", 0, 0, 255); + m_timeSeriesCanvas0->addDataSource("dX/dt (m/s)", 0, 0, 0); break; } case TUT_ACCELERATION: { - numBodies=10; - m_timeSeriesCanvas1 = new TimeSeriesCanvas(m_app->m_2dCanvasInterface,256,512,"Constant Acceleration"); - - m_timeSeriesCanvas1 ->setupTimeSeries(50,60, 0); - m_timeSeriesCanvas1->addDataSource("Y position (m)", 255,0,0); - m_timeSeriesCanvas1->addDataSource("Y velocity (m/s)", 0,0,255); - m_timeSeriesCanvas1->addDataSource("dY/dt (m/s)", 0,0,0); + numBodies = 10; + m_timeSeriesCanvas1 = new TimeSeriesCanvas(m_app->m_2dCanvasInterface, 256, 512, "Constant Acceleration"); + + m_timeSeriesCanvas1->setupTimeSeries(50, 60, 0); + m_timeSeriesCanvas1->addDataSource("Y position (m)", 255, 0, 0); + m_timeSeriesCanvas1->addDataSource("Y velocity (m/s)", 0, 0, 255); + m_timeSeriesCanvas1->addDataSource("dY/dt (m/s)", 0, 0, 0); break; } case TUT_COLLISION: { - numBodies=2; - m_timeSeriesCanvas1 = new TimeSeriesCanvas(m_app->m_2dCanvasInterface,512,200,"Distance"); - m_timeSeriesCanvas1 ->setupTimeSeries(1.5,60, 0); - m_timeSeriesCanvas1->addDataSource("distance", 255,0,0); + numBodies = 2; + m_timeSeriesCanvas1 = new TimeSeriesCanvas(m_app->m_2dCanvasInterface, 512, 200, "Distance"); + m_timeSeriesCanvas1->setupTimeSeries(1.5, 60, 0); + m_timeSeriesCanvas1->addDataSource("distance", 255, 0, 0); break; } - + case TUT_SOLVE_CONTACT_CONSTRAINT: { - numBodies=2; - m_timeSeriesCanvas1 = new TimeSeriesCanvas(m_app->m_2dCanvasInterface,512,200,"Collision Impulse"); - m_timeSeriesCanvas1 ->setupTimeSeries(1.5,60, 0); - m_timeSeriesCanvas1->addDataSource("Distance", 0,0,255); - m_timeSeriesCanvas1->addDataSource("Impulse magnutide", 255,0,0); - + numBodies = 2; + m_timeSeriesCanvas1 = new TimeSeriesCanvas(m_app->m_2dCanvasInterface, 512, 200, "Collision Impulse"); + m_timeSeriesCanvas1->setupTimeSeries(1.5, 60, 0); + m_timeSeriesCanvas1->addDataSource("Distance", 0, 0, 255); + m_timeSeriesCanvas1->addDataSource("Impulse magnutide", 255, 0, 0); + { - SliderParams slider("Restitution",&gRestitution); - slider.m_minVal=0; - slider.m_maxVal=1; + SliderParams slider("Restitution", &gRestitution); + slider.m_minVal = 0; + slider.m_maxVal = 1; m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); } { - SliderParams slider("Mass A",&gMassA); - slider.m_minVal=0; - slider.m_maxVal=100; + SliderParams slider("Mass A", &gMassA); + slider.m_minVal = 0; + slider.m_maxVal = 100; m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); } - + { - SliderParams slider("Mass B",&gMassB); - slider.m_minVal=0; - slider.m_maxVal=100; + SliderParams slider("Mass B", &gMassB); + slider.m_minVal = 0; + slider.m_maxVal = 100; m_guiHelper->getParameterInterface()->registerSliderFloatParameter(slider); } - - - + break; } - + default: { - - m_timeSeriesCanvas0 = new TimeSeriesCanvas(m_app->m_2dCanvasInterface,512,256,"Unknown"); - m_timeSeriesCanvas0 ->setupTimeSeries(1,60, 0); - + m_timeSeriesCanvas0 = new TimeSeriesCanvas(m_app->m_2dCanvasInterface, 512, 256, "Unknown"); + m_timeSeriesCanvas0->setupTimeSeries(1, 60, 0); } }; - - - if (m_tutorialIndex==TUT_VELOCITY) + if (m_tutorialIndex == TUT_VELOCITY) { - - int boxId = m_app->registerCubeShape(100,1,100); - b3Vector3 pos = b3MakeVector3(0,-3.5,0); - b3Quaternion orn(0,0,0,1); - b3Vector4 color = b3MakeVector4(1,1,1,1); - b3Vector3 scaling = b3MakeVector3(1,1,1); - m_app->m_renderer->registerGraphicsInstance(boxId,pos,orn,color,scaling); + int boxId = m_app->registerCubeShape(100, 1, 100); + b3Vector3 pos = b3MakeVector3(0, -3.5, 0); + b3Quaternion orn(0, 0, 0, 1); + b3Vector4 color = b3MakeVector4(1, 1, 1, 1); + b3Vector3 scaling = b3MakeVector3(1, 1, 1); + m_app->m_renderer->registerGraphicsInstance(boxId, pos, orn, color, scaling); } - for (int i=0;im_worldPose.m_position.setValue((i/4)*5,3,(i&3)*5); + m_bodies[i]->m_worldPose.m_position.setValue((i / 4) * 5, 3, (i & 3) * 5); } { int textureIndex = -1; - + if (1) { - int width,height,n; - + int width, height, n; + const char* filename = "data/checker_huge.gif"; - const unsigned char* image=0; - - const char* prefix[]={"./","../","../../","../../../","../../../../"}; - int numprefix = sizeof(prefix)/sizeof(const char*); - - for (int i=0;!image && im_renderer->registerTexture(image,width,height); + textureIndex = m_app->m_renderer->registerTexture(image, width, height); } } - + // int boxId = m_app->registerCubeShape(1,1,1,textureIndex); int sphereTransparent = m_app->registerGraphicsUnitSphereShape(SPHERE_LOD_HIGH, textureIndex); - int sphereOpaque= m_app->registerGraphicsUnitSphereShape(SPHERE_LOD_HIGH, textureIndex); - - b3Vector3 scaling = b3MakeVector3(SPHERE_RADIUS,SPHERE_RADIUS,SPHERE_RADIUS); - for (int i=0;iregisterGraphicsUnitSphereShape(SPHERE_LOD_HIGH, textureIndex); + + b3Vector3 scaling = b3MakeVector3(SPHERE_RADIUS, SPHERE_RADIUS, SPHERE_RADIUS); + for (int i = 0; i < m_bodies.size(); i++) { int gfxShape = sphereOpaque; - b3Vector4 color = b3MakeVector4(.1,.1,1,1); - if (i%2) + b3Vector4 color = b3MakeVector4(.1, .1, 1, 1); + if (i % 2) { - color.setValue(1,.1,.1,0.1); + color.setValue(1, .1, .1, 0.1); gfxShape = sphereTransparent; } m_bodies[i]->m_collisionShape.m_sphere.m_radius = SPHERE_RADIUS; m_bodies[i]->m_collisionShape.m_type = LW_SPHERE_TYPE; - - m_bodies[i]->m_graphicsIndex = m_app->m_renderer->registerGraphicsInstance(gfxShape,m_bodies[i]->m_worldPose.m_position, m_bodies[i]->m_worldPose.m_orientation,color,scaling); + + m_bodies[i]->m_graphicsIndex = m_app->m_renderer->registerGraphicsInstance(gfxShape, m_bodies[i]->m_worldPose.m_position, m_bodies[i]->m_worldPose.m_orientation, color, scaling); m_app->m_renderer->writeSingleInstanceTransformToCPU(m_bodies[i]->m_worldPose.m_position, m_bodies[i]->m_worldPose.m_orientation, m_bodies[i]->m_graphicsIndex); } } - if (m_tutorialIndex == TUT_SOLVE_CONTACT_CONSTRAINT) { - m_bodies[0]->m_invMass = gMassA? 1./gMassA : 0; - m_bodies[0]->m_collisionShape.m_sphere.computeLocalInertia(gMassA,m_bodies[0]->m_localInertia); - - m_bodies[1]->m_invMass =gMassB? 1./gMassB : 0; - m_bodies[1]->m_collisionShape.m_sphere.computeLocalInertia(gMassB,m_bodies[1]->m_localInertia); + m_bodies[0]->m_invMass = gMassA ? 1. / gMassA : 0; + m_bodies[0]->m_collisionShape.m_sphere.computeLocalInertia(gMassA, m_bodies[0]->m_localInertia); + + m_bodies[1]->m_invMass = gMassB ? 1. / gMassB : 0; + m_bodies[1]->m_collisionShape.m_sphere.computeLocalInertia(gMassB, m_bodies[1]->m_localInertia); if (gMassA) - m_bodies[0]->m_linearVelocity.setValue(0,0,1); + m_bodies[0]->m_linearVelocity.setValue(0, 0, 1); if (gMassB) - m_bodies[1]->m_linearVelocity.setValue(0,0,-1); - + m_bodies[1]->m_linearVelocity.setValue(0, 0, -1); } - - - m_app->m_renderer->writeTransforms(); - } - virtual ~Tutorial() - { + m_app->m_renderer->writeTransforms(); + } + virtual ~Tutorial() + { delete m_timeSeriesCanvas0; delete m_timeSeriesCanvas1; m_timeSeriesCanvas0 = 0; m_timeSeriesCanvas1 = 0; + } + + virtual void initPhysics() + { + } + virtual void exitPhysics() + { + } - } - - - virtual void initPhysics() - { - } - virtual void exitPhysics() - { - - } - void tutorial1Update(float deltaTime); void tutorial2Update(float deltaTime); - void tutorialCollisionUpdate(float deltaTime,LWContactPoint& contact); - void tutorialSolveContactConstraintUpdate(float deltaTime,LWContactPoint& contact); - - virtual void stepSimulation(float deltaTime) - { + void tutorialCollisionUpdate(float deltaTime, LWContactPoint& contact); + void tutorialSolveContactConstraintUpdate(float deltaTime, LWContactPoint& contact); + + virtual void stepSimulation(float deltaTime) + { switch (m_tutorialIndex) { case TUT_VELOCITY: @@ -499,8 +478,8 @@ public: tutorial1Update(deltaTime); float xPos = m_bodies[0]->m_worldPose.m_position.x; float xVel = m_bodies[0]->m_linearVelocity.x; - m_timeSeriesCanvas0->insertDataAtCurrentTime(xPos,0,true); - m_timeSeriesCanvas0->insertDataAtCurrentTime(xVel,1,true); + m_timeSeriesCanvas0->insertDataAtCurrentTime(xPos, 0, true); + m_timeSeriesCanvas0->insertDataAtCurrentTime(xVel, 1, true); break; } case TUT_ACCELERATION: @@ -508,9 +487,9 @@ public: tutorial2Update(deltaTime); float yPos = m_bodies[0]->m_worldPose.m_position.y; float yVel = m_bodies[0]->m_linearVelocity.y; - m_timeSeriesCanvas1->insertDataAtCurrentTime(yPos,0,true); - m_timeSeriesCanvas1->insertDataAtCurrentTime(yVel,1,true); - + m_timeSeriesCanvas1->insertDataAtCurrentTime(yPos, 0, true); + m_timeSeriesCanvas1->insertDataAtCurrentTime(yVel, 1, true); + break; } case TUT_COLLISION: @@ -519,8 +498,8 @@ public: LWContactPoint contactPoint; tutorialCollisionUpdate(deltaTime, contactPoint); m_contactPoints.push_back(contactPoint); - m_timeSeriesCanvas1->insertDataAtCurrentTime(contactPoint.m_distance,0,true); - + m_timeSeriesCanvas1->insertDataAtCurrentTime(contactPoint.m_distance, 0, true); + break; } case TUT_SOLVE_CONTACT_CONSTRAINT: @@ -529,278 +508,261 @@ public: LWContactPoint contactPoint; tutorialSolveContactConstraintUpdate(deltaTime, contactPoint); m_contactPoints.push_back(contactPoint); - if (contactPoint.m_distance<0) + if (contactPoint.m_distance < 0) { m_bodies[0]->computeInvInertiaTensorWorld(); m_bodies[1]->computeInvInertiaTensorWorld(); - + b3Scalar appliedImpulse = resolveCollision(*m_bodies[0], - *m_bodies[1], - contactPoint - ); - - m_timeSeriesCanvas1->insertDataAtCurrentTime(appliedImpulse,1,true); - - } else - { - m_timeSeriesCanvas1->insertDataAtCurrentTime(0.,1,true); + *m_bodies[1], + contactPoint); + + m_timeSeriesCanvas1->insertDataAtCurrentTime(appliedImpulse, 1, true); } - m_timeSeriesCanvas1->insertDataAtCurrentTime(contactPoint.m_distance,0,true); - + else + { + m_timeSeriesCanvas1->insertDataAtCurrentTime(0., 1, true); + } + m_timeSeriesCanvas1->insertDataAtCurrentTime(contactPoint.m_distance, 0, true); + break; } default: { } - }; - - + if (m_timeSeriesCanvas0) m_timeSeriesCanvas0->nextTick(); - + if (m_timeSeriesCanvas1) m_timeSeriesCanvas1->nextTick(); - - for (int i=0;iintegrateAcceleration(deltaTime); m_bodies[i]->integrateVelocity(deltaTime); - + m_app->m_renderer->writeSingleInstanceTransformToCPU(m_bodies[i]->m_worldPose.m_position, m_bodies[i]->m_worldPose.m_orientation, m_bodies[i]->m_graphicsIndex); } - - m_app->m_renderer->writeTransforms(); - } - virtual void renderScene() - { + m_app->m_renderer->writeTransforms(); + } + virtual void renderScene() + { m_app->m_renderer->renderScene(); - m_app->drawText3D("X",1,0,0,1); - m_app->drawText3D("Y",0,1,0,1); - m_app->drawText3D("Z",0,0,1,1); + m_app->drawText3D("X", 1, 0, 0, 1); + m_app->drawText3D("Y", 0, 1, 0, 1); + m_app->drawText3D("Z", 0, 0, 1, 1); - for (int i=0;im_renderer->drawLine(contact.m_ptOnAWorld,contact.m_ptOnBWorld,color,lineWidth); + m_app->m_renderer->drawLine(contact.m_ptOnAWorld, contact.m_ptOnBWorld, color, lineWidth); } - } + } - - - virtual void physicsDebugDraw(int debugDrawFlags) - { - - - } - virtual bool mouseMoveCallback(float x,float y) - { - return false; - } - virtual bool mouseButtonCallback(int button, int state, float x, float y) - { - return false; - } - virtual bool keyboardCallback(int key, int state) - { - return false; - } - + virtual void physicsDebugDraw(int debugDrawFlags) + { + } + virtual bool mouseMoveCallback(float x, float y) + { + return false; + } + virtual bool mouseButtonCallback(int button, int state, float x, float y) + { + return false; + } + virtual bool keyboardCallback(int key, int state) + { + return false; + } virtual void resetCamera() { float dist = 10.5; float pitch = -32; float yaw = 136; - float targetPos[3]={0,0,0}; - if (m_app->m_renderer && m_app->m_renderer->getActiveCamera()) + float targetPos[3] = {0, 0, 0}; + if (m_app->m_renderer && m_app->m_renderer->getActiveCamera()) { m_app->m_renderer->getActiveCamera()->setCameraDistance(dist); m_app->m_renderer->getActiveCamera()->setCameraPitch(pitch); m_app->m_renderer->getActiveCamera()->setCameraYaw(yaw); - m_app->m_renderer->getActiveCamera()->setCameraTargetPosition(targetPos[0],targetPos[1],targetPos[2]); + m_app->m_renderer->getActiveCamera()->setCameraTargetPosition(targetPos[0], targetPos[1], targetPos[2]); } } }; void Tutorial::tutorial2Update(float deltaTime) { - for (int i=0;im_gravityAcceleration.setValue(0,-10,0); + m_bodies[i]->m_gravityAcceleration.setValue(0, -10, 0); } } void Tutorial::tutorial1Update(float deltaTime) { - for (int i=0;im_angularVelocity = b3MakeVector3(0, 0, 0); + m_bodies[i]->m_linearVelocity = b3MakeVector3(1, 0, 0); + break; + } + case 1: + { + m_bodies[i]->m_linearVelocity = b3MakeVector3(-1, 0, 0); + break; + } + case 2: + { + m_bodies[i]->m_linearVelocity = b3MakeVector3(0, 1, 0); + break; + } + case 3: + { + m_bodies[i]->m_linearVelocity = b3MakeVector3(0, -1, 0); + break; + } + case 4: + { + m_bodies[i]->m_linearVelocity = b3MakeVector3(0, 0, 1); + break; + } + case 5: + { + m_bodies[i]->m_linearVelocity = b3MakeVector3(0, 0, -1); + break; + } + case 6: + { + m_bodies[i]->m_linearVelocity = b3MakeVector3(0, 0, 0); + m_bodies[i]->m_angularVelocity = b3MakeVector3(1, 0, 0); + break; + } + case 7: + { + m_bodies[i]->m_angularVelocity = b3MakeVector3(-1, 0, 0); + break; + } + case 8: + { + m_bodies[i]->m_angularVelocity = b3MakeVector3(0, 1, 0); + break; + } + case 9: + { + m_bodies[i]->m_angularVelocity = b3MakeVector3(0, -1, 0); + break; + } + case 10: + { + m_bodies[i]->m_angularVelocity = b3MakeVector3(0, 0, 1); + break; + } + case 11: + { + m_bodies[i]->m_angularVelocity = b3MakeVector3(0, 0, -1); + break; + } + default: + { + m_bodies[i]->m_angularVelocity = b3MakeVector3(0, 0, 0); + } + }; + } + + m_counter++; + if (m_counter > 60) + { + m_counter = 0; + m_stage++; + if (m_stage > 11) + m_stage = 0; + b3Printf("Stage = %d\n", m_stage); + b3Printf("linVel = %f,%f,%f\n", m_bodies[0]->m_linearVelocity.x, m_bodies[0]->m_linearVelocity.y, m_bodies[0]->m_linearVelocity.z); + b3Printf("angVel = %f,%f,%f\n", m_bodies[0]->m_angularVelocity.x, m_bodies[0]->m_angularVelocity.y, m_bodies[0]->m_angularVelocity.z); + } +} + +void Tutorial::tutorialSolveContactConstraintUpdate(float deltaTime, LWContactPoint& contact) +{ + ComputeClosestPointsSphereSphere(m_bodies[0]->m_collisionShape.m_sphere, + m_bodies[0]->m_worldPose, + m_bodies[1]->m_collisionShape.m_sphere, + m_bodies[1]->m_worldPose, + contact); +} + +void Tutorial::tutorialCollisionUpdate(float deltaTime, LWContactPoint& contact) +{ + m_bodies[1]->m_worldPose.m_position.z = 3; + + ComputeClosestPointsSphereSphere(m_bodies[0]->m_collisionShape.m_sphere, + m_bodies[0]->m_worldPose, + m_bodies[1]->m_collisionShape.m_sphere, + m_bodies[1]->m_worldPose, + contact); + switch (m_stage) { case 0: { - m_bodies[i]->m_angularVelocity=b3MakeVector3(0,0,0); - m_bodies[i]->m_linearVelocity=b3MakeVector3(1,0,0); + m_bodies[0]->m_angularVelocity = b3MakeVector3(0, 0, 0); + m_bodies[0]->m_linearVelocity = b3MakeVector3(1, 0, 0); break; } case 1: { - m_bodies[i]->m_linearVelocity=b3MakeVector3(-1,0,0); + m_bodies[0]->m_linearVelocity = b3MakeVector3(-1, 0, 0); break; } case 2: { - m_bodies[i]->m_linearVelocity=b3MakeVector3(0,1,0); + m_bodies[0]->m_linearVelocity = b3MakeVector3(0, 1, 0); break; } case 3: { - m_bodies[i]->m_linearVelocity=b3MakeVector3(0,-1,0); + m_bodies[0]->m_linearVelocity = b3MakeVector3(0, -1, 0); break; } case 4: { - m_bodies[i]->m_linearVelocity=b3MakeVector3(0,0,1); + m_bodies[0]->m_linearVelocity = b3MakeVector3(0, 0, 1); break; } case 5: { - m_bodies[i]->m_linearVelocity=b3MakeVector3(0,0,-1); - break; - } - case 6: - { - m_bodies[i]->m_linearVelocity=b3MakeVector3(0,0,0); - m_bodies[i]->m_angularVelocity=b3MakeVector3(1,0,0); - break; - } - case 7: - { - m_bodies[i]->m_angularVelocity=b3MakeVector3(-1,0,0); - break; - } - case 8: - { - m_bodies[i]->m_angularVelocity=b3MakeVector3(0,1,0); - break; - } - case 9: - { - m_bodies[i]->m_angularVelocity=b3MakeVector3(0,-1,0); - break; - } - case 10: - { - m_bodies[i]->m_angularVelocity=b3MakeVector3(0,0,1); - break; - } - case 11: - { - m_bodies[i]->m_angularVelocity=b3MakeVector3(0,0,-1); + m_bodies[0]->m_linearVelocity = b3MakeVector3(0, 0, -1); break; } default: { - m_bodies[i]->m_angularVelocity=b3MakeVector3(0,0,0); } }; - } - m_counter++; - if (m_counter>60) + if (m_counter > 120) { - m_counter=0; + m_counter = 0; m_stage++; - if (m_stage>11) - m_stage=0; - b3Printf("Stage = %d\n",m_stage); - b3Printf("linVel = %f,%f,%f\n",m_bodies[0]->m_linearVelocity.x,m_bodies[0]->m_linearVelocity.y,m_bodies[0]->m_linearVelocity.z); - b3Printf("angVel = %f,%f,%f\n",m_bodies[0]->m_angularVelocity.x,m_bodies[0]->m_angularVelocity.y,m_bodies[0]->m_angularVelocity.z); - + if (m_stage > 5) + m_stage = 0; } } - -void Tutorial::tutorialSolveContactConstraintUpdate(float deltaTime,LWContactPoint& contact) -{ - ComputeClosestPointsSphereSphere(m_bodies[0]->m_collisionShape.m_sphere, - m_bodies[0]->m_worldPose, - m_bodies[1]->m_collisionShape.m_sphere, - m_bodies[1]->m_worldPose, - contact); - -} - -void Tutorial::tutorialCollisionUpdate(float deltaTime,LWContactPoint& contact) -{ - m_bodies[1]->m_worldPose.m_position.z = 3; - - - ComputeClosestPointsSphereSphere(m_bodies[0]->m_collisionShape.m_sphere, - m_bodies[0]->m_worldPose, - m_bodies[1]->m_collisionShape.m_sphere, - m_bodies[1]->m_worldPose, - contact); - - switch (m_stage) - { - case 0: - { - m_bodies[0]->m_angularVelocity=b3MakeVector3(0,0,0); - m_bodies[0]->m_linearVelocity=b3MakeVector3(1,0,0); - break; - } - case 1: - { - m_bodies[0]->m_linearVelocity=b3MakeVector3(-1,0,0); - break; - } - case 2: - { - m_bodies[0]->m_linearVelocity=b3MakeVector3(0,1,0); - break; - } - case 3: - { - m_bodies[0]->m_linearVelocity=b3MakeVector3(0,-1,0); - break; - } - case 4: - { - m_bodies[0]->m_linearVelocity=b3MakeVector3(0,0,1); - break; - } - case 5: - { - m_bodies[0]->m_linearVelocity=b3MakeVector3(0,0,-1); - break; - } - default:{} - }; - m_counter++; - if (m_counter>120) - { - m_counter=0; - m_stage++; - if (m_stage>5) - m_stage=0; - - } -} - - - -class CommonExampleInterface* TutorialCreateFunc(struct CommonExampleOptions& options) +class CommonExampleInterface* TutorialCreateFunc(struct CommonExampleOptions& options) { return new Tutorial(options.m_guiHelper, options.m_option); } - diff --git a/examples/Tutorial/Tutorial.h b/examples/Tutorial/Tutorial.h index fd78f4dcd..33aee0a2b 100644 --- a/examples/Tutorial/Tutorial.h +++ b/examples/Tutorial/Tutorial.h @@ -3,12 +3,12 @@ enum EnumTutorialTypes { - TUT_VELOCITY=0, + TUT_VELOCITY = 0, TUT_ACCELERATION, TUT_COLLISION, TUT_SOLVE_CONTACT_CONSTRAINT, }; -class CommonExampleInterface* TutorialCreateFunc(struct CommonExampleOptions& options); +class CommonExampleInterface* TutorialCreateFunc(struct CommonExampleOptions& options); -#endif //TUTORIAL_H +#endif //TUTORIAL_H diff --git a/examples/TwoJoint/TwoJointMain.cpp b/examples/TwoJoint/TwoJointMain.cpp index 64e325bf5..8625bd483 100644 --- a/examples/TwoJoint/TwoJointMain.cpp +++ b/examples/TwoJoint/TwoJointMain.cpp @@ -16,7 +16,7 @@ const int CONTROL_RATE = 500; // Bullet globals b3PhysicsClientHandle kPhysClient = 0; -const b3Scalar FIXED_TIMESTEP = 1.0/((b3Scalar)CONTROL_RATE); +const b3Scalar FIXED_TIMESTEP = 1.0 / ((b3Scalar)CONTROL_RATE); // temp vars used a lot b3SharedMemoryCommandHandle command; b3SharedMemoryStatusHandle statusHandle; @@ -25,9 +25,10 @@ b3JointInfo jointInfo; b3JointSensorState state; // test int twojoint; -std::map< std::string, int > jointNameToId; +std::map jointNameToId; -int main(int argc, char* argv[]) { +int main(int argc, char* argv[]) +{ kPhysClient = b3CreateInProcessPhysicsServerAndConnect(argc, argv); if (!kPhysClient) return -1; @@ -54,7 +55,6 @@ int main(int argc, char* argv[]) { b3Assert(b3GetStatusType(statusHandle) == CMD_CLIENT_COMMAND_COMPLETED); - // load test command = b3LoadUrdfCommandInit(kPhysClient, "TwoJointRobot_wo_fixedJoints.urdf"); int flags = URDF_USE_INERTIA_FROM_FILE; @@ -66,26 +66,31 @@ int main(int argc, char* argv[]) { statusHandle = b3SubmitClientCommandAndWaitStatus(kPhysClient, command); statusType = b3GetStatusType(statusHandle); b3Assert(statusType == CMD_URDF_LOADING_COMPLETED); - if (statusType == CMD_URDF_LOADING_COMPLETED) { + if (statusType == CMD_URDF_LOADING_COMPLETED) + { twojoint = b3GetStatusBodyIndex(statusHandle); } - //disable default linear/angular damping - b3SharedMemoryCommandHandle command = b3InitChangeDynamicsInfo(kPhysClient); - double linearDamping = 0; - double angularDamping = 0; - b3ChangeDynamicsInfoSetLinearDamping(command, twojoint, linearDamping); - b3ChangeDynamicsInfoSetAngularDamping(command, twojoint, angularDamping); - statusHandle = b3SubmitClientCommandAndWaitStatus(kPhysClient, command); + //disable default linear/angular damping + b3SharedMemoryCommandHandle command = b3InitChangeDynamicsInfo(kPhysClient); + double linearDamping = 0; + double angularDamping = 0; + b3ChangeDynamicsInfoSetLinearDamping(command, twojoint, linearDamping); + b3ChangeDynamicsInfoSetAngularDamping(command, twojoint, angularDamping); + statusHandle = b3SubmitClientCommandAndWaitStatus(kPhysClient, command); int numJoints = b3GetNumJoints(kPhysClient, twojoint); printf("twojoint numjoints = %d\n", numJoints); // Loop through all joints - for (int i=0; i #endif -#define BT_TIMING_CAPACITY 16*65536 +#define BT_TIMING_CAPACITY 16 * 65536 static bool m_firstTiming = true; - struct btTimings { btTimings() - :m_numTimings(0), - m_activeBuffer(0) + : m_numTimings(0), + m_activeBuffer(0) { - } void flush() { - for (int i = 0; iendTime) + if (startTime > endTime) { endTime = startTime; } @@ -75,13 +72,13 @@ struct btTimings char startTimeRem1000Str[16]; char endTimeRem1000Str[16]; - if (startTimeRem1000<10) + if (startTimeRem1000 < 10) { sprintf(startTimeRem1000Str, "00%d", startTimeRem1000); } else { - if (startTimeRem1000<100) + if (startTimeRem1000 < 100) { sprintf(startTimeRem1000Str, "0%d", startTimeRem1000); } @@ -91,13 +88,13 @@ struct btTimings } } - if (endTimeRem1000<10) + if (endTimeRem1000 < 10) { sprintf(endTimeRem1000Str, "00%d", endTimeRem1000); } else { - if (endTimeRem1000<100) + if (endTimeRem1000 < 100) { sprintf(endTimeRem1000Str, "0%d", endTimeRem1000); } @@ -114,21 +111,19 @@ struct btTimings #ifdef _WIN32 fprintf(gTimingFile, "{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%I64d.%s ,\"ph\":\"B\",\"name\":\"%s\",\"args\":{}},\n", - threadId, startTimeDiv1000, startTimeRem1000Str, newname); + threadId, startTimeDiv1000, startTimeRem1000Str, newname); fprintf(gTimingFile, "{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%I64d.%s ,\"ph\":\"E\",\"name\":\"%s\",\"args\":{}}", - threadId, endTimeDiv1000, endTimeRem1000Str, newname); + threadId, endTimeDiv1000, endTimeRem1000Str, newname); #else fprintf(gTimingFile, "{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%" PRIu64 ".%s ,\"ph\":\"B\",\"name\":\"%s\",\"args\":{}},\n", - threadId, startTimeDiv1000, startTimeRem1000Str, newname); + threadId, startTimeDiv1000, startTimeRem1000Str, newname); fprintf(gTimingFile, "{\"cat\":\"timing\",\"pid\":1,\"tid\":%d,\"ts\":%" PRIu64 ".%s ,\"ph\":\"E\",\"name\":\"%s\",\"args\":{}}", - threadId, endTimeDiv1000, endTimeRem1000Str, newname); + threadId, endTimeDiv1000, endTimeRem1000Str, newname); #endif #endif - } m_numTimings = 0; - } void addTiming(const char* name, int threadId, unsigned long long int startTime, unsigned long long int endTime) @@ -151,7 +146,6 @@ struct btTimings m_timings[m_activeBuffer][slot].m_usEndTime = endTime; } - int m_numTimings; int m_activeBuffer; btAlignedObjectArray m_timings[1]; @@ -159,18 +153,15 @@ struct btTimings //#ifndef BT_NO_PROFILE btTimings gTimings[BT_QUICKPROF_MAX_THREAD_COUNT]; #define MAX_NESTING 1024 -int gStackDepths[BT_QUICKPROF_MAX_THREAD_COUNT] = { 0 }; +int gStackDepths[BT_QUICKPROF_MAX_THREAD_COUNT] = {0}; const char* gFuncNames[BT_QUICKPROF_MAX_THREAD_COUNT][MAX_NESTING]; unsigned long long int gStartTimes[BT_QUICKPROF_MAX_THREAD_COUNT][MAX_NESTING]; //#endif btClock clk; - - bool gProfileDisabled = true; - void MyDummyEnterProfileZoneFunc(const char* msg) { } @@ -185,7 +176,7 @@ void MyEnterProfileZoneFunc(const char* msg) return; #ifndef BT_NO_PROFILE int threadId = btQuickprofGetCurrentThreadIndex2(); - if (threadId<0 || threadId >= BT_QUICKPROF_MAX_THREAD_COUNT) + if (threadId < 0 || threadId >= BT_QUICKPROF_MAX_THREAD_COUNT) return; if (gStackDepths[threadId] >= MAX_NESTING) @@ -201,7 +192,6 @@ void MyEnterProfileZoneFunc(const char* msg) } gStackDepths[threadId]++; #endif - } void MyLeaveProfileZoneFunc() { @@ -209,8 +199,8 @@ void MyLeaveProfileZoneFunc() return; #ifndef BT_NO_PROFILE int threadId = btQuickprofGetCurrentThreadIndex2(); - if (threadId<0 || threadId >= BT_QUICKPROF_MAX_THREAD_COUNT) - return; + if (threadId < 0 || threadId >= BT_QUICKPROF_MAX_THREAD_COUNT) + return; if (gStackDepths[threadId] <= 0) { @@ -224,56 +214,55 @@ void MyLeaveProfileZoneFunc() unsigned long long int endTime = clk.getTimeNanoseconds(); gTimings[threadId].addTiming(name, threadId, startTime, endTime); -#endif //BT_NO_PROFILE +#endif //BT_NO_PROFILE } - void b3ChromeUtilsStartTimings() { - m_firstTiming = true; - gProfileDisabled = false;//true; - b3SetCustomEnterProfileZoneFunc(MyEnterProfileZoneFunc); - b3SetCustomLeaveProfileZoneFunc(MyLeaveProfileZoneFunc); + m_firstTiming = true; + gProfileDisabled = false; //true; + b3SetCustomEnterProfileZoneFunc(MyEnterProfileZoneFunc); + b3SetCustomLeaveProfileZoneFunc(MyLeaveProfileZoneFunc); - //also for Bullet 2.x API - btSetCustomEnterProfileZoneFunc(MyEnterProfileZoneFunc); - btSetCustomLeaveProfileZoneFunc(MyLeaveProfileZoneFunc); + //also for Bullet 2.x API + btSetCustomEnterProfileZoneFunc(MyEnterProfileZoneFunc); + btSetCustomLeaveProfileZoneFunc(MyLeaveProfileZoneFunc); } void b3ChromeUtilsStopTimingsAndWriteJsonFile(const char* fileNamePrefix) { - b3SetCustomEnterProfileZoneFunc(MyDummyEnterProfileZoneFunc); - b3SetCustomLeaveProfileZoneFunc(MyDummyLeaveProfileZoneFunc); - //also for Bullet 2.x API - btSetCustomEnterProfileZoneFunc(MyDummyEnterProfileZoneFunc); - btSetCustomLeaveProfileZoneFunc(MyDummyLeaveProfileZoneFunc); - char fileName[1024]; - static int fileCounter = 0; - sprintf(fileName,"%s_%d.json",fileNamePrefix, fileCounter++); - gTimingFile = fopen(fileName,"w"); - if (gTimingFile) + b3SetCustomEnterProfileZoneFunc(MyDummyEnterProfileZoneFunc); + b3SetCustomLeaveProfileZoneFunc(MyDummyLeaveProfileZoneFunc); + //also for Bullet 2.x API + btSetCustomEnterProfileZoneFunc(MyDummyEnterProfileZoneFunc); + btSetCustomLeaveProfileZoneFunc(MyDummyLeaveProfileZoneFunc); + char fileName[1024]; + static int fileCounter = 0; + sprintf(fileName, "%s_%d.json", fileNamePrefix, fileCounter++); + gTimingFile = fopen(fileName, "w"); + if (gTimingFile) + { + fprintf(gTimingFile, "{\"traceEvents\":[\n"); + //dump the content to file + for (int i = 0; i < BT_QUICKPROF_MAX_THREAD_COUNT; i++) + { + if (gTimings[i].m_numTimings) { - fprintf(gTimingFile,"{\"traceEvents\":[\n"); - //dump the content to file - for (int i=0;i& line) { int c = 0; - for (c=fgetc(file);(c != EOF && c != '\n');c=fgetc(file)) + for (c = fgetc(file); (c != EOF && c != '\n'); c = fgetc(file)) { line.push_back(c); } @@ -16,13 +15,11 @@ static bool readLine(FILE* file, btAlignedObjectArray& line) return (c == EOF); } - int readMinitaurLogFile(const char* fileName, btAlignedObjectArray& structNames, std::string& structTypes, btAlignedObjectArray& logRecords, bool verbose) { - int retVal = 0; - FILE* f = fopen(fileName,"rb"); + FILE* f = fopen(fileName, "rb"); if (f) { if (verbose) @@ -30,36 +27,36 @@ int readMinitaurLogFile(const char* fileName, btAlignedObjectArray& printf("Opened file %s\n", fileName); } btAlignedObjectArray line0Buf; - bool eof = readLine(f,line0Buf); + bool eof = readLine(f, line0Buf); btAlignedObjectArray line1Buf; - eof |= readLine(f,line1Buf); + eof |= readLine(f, line1Buf); std::string line0 = &line0Buf[0]; structTypes = &line1Buf[0]; - + btAlignedObjectArray separators; separators.push_back(","); - - urdfStringSplit(structNames,line0,separators); + + urdfStringSplit(structNames, line0, separators); if (verbose) { - printf("Num Fields = %d\n",structNames.size()); + printf("Num Fields = %d\n", structNames.size()); } btAssert(structTypes.size() == structNames.size()); if (structTypes.size() != structNames.size()) { retVal = eCorruptHeader; } - int numStructsRead = 0; + int numStructsRead = 0; if (structTypes.size() == structNames.size()) { while (!eof) { unsigned char blaat[1024]; - size_t s = fread(blaat,2,1,f); - if (s!=1) + size_t s = fread(blaat, 2, 1, f); + if (s != 1) { - eof=true; + eof = true; retVal = eInvalidAABBAlignCheck; break; } @@ -73,125 +70,120 @@ int readMinitaurLogFile(const char* fileName, btAlignedObjectArray& if (verbose) { - printf("Reading structure %d\n",numStructsRead); + printf("Reading structure %d\n", numStructsRead); } MinitaurLogRecord record; - for (int i=0;i& return retVal; } - FILE* createMinitaurLogFile(const char* fileName, btAlignedObjectArray& structNames, std::string& structTypes) { - FILE* f = fopen(fileName,"wb"); + FILE* f = fopen(fileName, "wb"); if (f) { - for (int i=0;i -const T& b3ClockMin(const T& a, const T& b) +const T& b3ClockMin(const T& a, const T& b) { - return a < b ? a : b ; + return a < b ? a : b; } - #ifdef __CELLOS_LV2__ #include #include #include #endif -#if defined (SUNOS) || defined (__SUNOS__) -#include +#if defined(SUNOS) || defined(__SUNOS__) +#include #endif #if defined(WIN32) || defined(_WIN32) @@ -23,38 +22,33 @@ const T& b3ClockMin(const T& a, const T& b) #define WIN32_LEAN_AND_MEAN #define NOWINRES #define NOMCX -#define NOIME +#define NOIME #ifdef _XBOX - #include -#else //_XBOX - #include -#endif //_XBOX +#include +#else //_XBOX +#include +#endif //_XBOX #include - -#else //_WIN32 +#else //_WIN32 #include #include -#endif //_WIN32 - - +#endif //_WIN32 struct b3ClockData { - #ifdef B3_USE_WINDOWS_TIMERS LARGE_INTEGER mClockFrequency; LARGE_INTEGER mStartTime; #else #ifdef __CELLOS_LV2__ - uint64_t mStartTime; + uint64_t mStartTime; #else struct timeval mStartTime; #endif -#endif //__CELLOS_LV2__ - +#endif //__CELLOS_LV2__ }; ///The b3Clock is a portable basic clock that measures accurate time in seconds, use for profiling. @@ -67,7 +61,6 @@ b3Clock::b3Clock() reset(); } - b3Clock::~b3Clock() { delete m_data; @@ -85,8 +78,7 @@ b3Clock& b3Clock::operator=(const b3Clock& other) return *this; } - - /// Resets the initial reference time. +/// Resets the initial reference time. void b3Clock::reset(bool zeroReference) { if (zeroReference) @@ -94,126 +86,126 @@ void b3Clock::reset(bool zeroReference) #ifdef B3_USE_WINDOWS_TIMERS m_data->mStartTime.QuadPart = 0; #else - #ifdef __CELLOS_LV2__ - m_data->mStartTime = 0; - #else - m_data->mStartTime = (struct timeval){0}; - #endif +#ifdef __CELLOS_LV2__ + m_data->mStartTime = 0; +#else + m_data->mStartTime = (struct timeval){0}; #endif - - } else +#endif + } + else { #ifdef B3_USE_WINDOWS_TIMERS - QueryPerformanceCounter(&m_data->mStartTime); + QueryPerformanceCounter(&m_data->mStartTime); #else #ifdef __CELLOS_LV2__ - typedef uint64_t ClockSize; - ClockSize newTime; - //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); - SYS_TIMEBASE_GET( newTime ); - m_data->mStartTime = newTime; + typedef uint64_t ClockSize; + ClockSize newTime; + //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); + SYS_TIMEBASE_GET(newTime); + m_data->mStartTime = newTime; #else - gettimeofday(&m_data->mStartTime, 0); + gettimeofday(&m_data->mStartTime, 0); #endif #endif } } -/// Returns the time in ms since the last call to reset or since +/// Returns the time in ms since the last call to reset or since /// the b3Clock was created. unsigned long int b3Clock::getTimeMilliseconds() { #ifdef B3_USE_WINDOWS_TIMERS LARGE_INTEGER currentTime; QueryPerformanceCounter(¤tTime); - LONGLONG elapsedTime = currentTime.QuadPart - - m_data->mStartTime.QuadPart; - // Compute the number of millisecond ticks elapsed. - unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / - m_data->mClockFrequency.QuadPart); - + LONGLONG elapsedTime = currentTime.QuadPart - + m_data->mStartTime.QuadPart; + // Compute the number of millisecond ticks elapsed. + unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / + m_data->mClockFrequency.QuadPart); - return msecTicks; + return msecTicks; #else #ifdef __CELLOS_LV2__ - uint64_t freq=sys_time_get_timebase_frequency(); - double dFreq=((double) freq) / 1000.0; - typedef uint64_t ClockSize; - ClockSize newTime; - SYS_TIMEBASE_GET( newTime ); - //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); + uint64_t freq = sys_time_get_timebase_frequency(); + double dFreq = ((double)freq) / 1000.0; + typedef uint64_t ClockSize; + ClockSize newTime; + SYS_TIMEBASE_GET(newTime); + //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); - return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq); + return (unsigned long int)((double(newTime - m_data->mStartTime)) / dFreq); #else - struct timeval currentTime; - gettimeofday(¤tTime, 0); - return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000 + - (currentTime.tv_usec - m_data->mStartTime.tv_usec) / 1000; -#endif //__CELLOS_LV2__ + struct timeval currentTime; + gettimeofday(¤tTime, 0); + return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000 + + (currentTime.tv_usec - m_data->mStartTime.tv_usec) / 1000; +#endif //__CELLOS_LV2__ #endif } - /// Returns the time in us since the last call to reset or since - /// the Clock was created. +/// Returns the time in us since the last call to reset or since +/// the Clock was created. unsigned long long int b3Clock::getTimeMicroseconds() { #ifdef B3_USE_WINDOWS_TIMERS //see https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx - LARGE_INTEGER currentTime, elapsedTime; - - QueryPerformanceCounter(¤tTime); - elapsedTime.QuadPart = currentTime.QuadPart - - m_data->mStartTime.QuadPart; - elapsedTime.QuadPart *= 1000000; - elapsedTime.QuadPart /= m_data->mClockFrequency.QuadPart; + LARGE_INTEGER currentTime, elapsedTime; - return (unsigned long long) elapsedTime.QuadPart; + QueryPerformanceCounter(¤tTime); + elapsedTime.QuadPart = currentTime.QuadPart - + m_data->mStartTime.QuadPart; + elapsedTime.QuadPart *= 1000000; + elapsedTime.QuadPart /= m_data->mClockFrequency.QuadPart; + + return (unsigned long long)elapsedTime.QuadPart; #else #ifdef __CELLOS_LV2__ - uint64_t freq=sys_time_get_timebase_frequency(); - double dFreq=((double) freq)/ 1000000.0; - typedef uint64_t ClockSize; - ClockSize newTime; - //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); - SYS_TIMEBASE_GET( newTime ); + uint64_t freq = sys_time_get_timebase_frequency(); + double dFreq = ((double)freq) / 1000000.0; + typedef uint64_t ClockSize; + ClockSize newTime; + //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); + SYS_TIMEBASE_GET(newTime); - return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq); + return (unsigned long int)((double(newTime - m_data->mStartTime)) / dFreq); #else - struct timeval currentTime; - gettimeofday(¤tTime, 0); - return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000000 + - (currentTime.tv_usec - m_data->mStartTime.tv_usec); -#endif//__CELLOS_LV2__ -#endif + struct timeval currentTime; + gettimeofday(¤tTime, 0); + return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000000 + + (currentTime.tv_usec - m_data->mStartTime.tv_usec); +#endif //__CELLOS_LV2__ +#endif } double b3Clock::getTimeInSeconds() { - return double(getTimeMicroseconds()/1.e6); + return double(getTimeMicroseconds() / 1.e6); } void b3Clock::usleep(int microSeconds) { #ifdef _WIN32 - if (microSeconds==0) + if (microSeconds == 0) { Sleep(0); - } else + } + else { - int millis = microSeconds/1000; - if (millis<1) - millis=1; + int millis = microSeconds / 1000; + if (millis < 1) + millis = 1; Sleep(millis); } #else - if (microSeconds>0) + if (microSeconds > 0) { - ::usleep(microSeconds); + ::usleep(microSeconds); //struct timeval tv; //tv.tv_sec = microSeconds/1000000L; //tv.tv_usec = microSeconds%1000000L; diff --git a/examples/Utils/b3Clock.h b/examples/Utils/b3Clock.h index 1cdd28847..bb3fcffca 100644 --- a/examples/Utils/b3Clock.h +++ b/examples/Utils/b3Clock.h @@ -1,7 +1,6 @@ #ifndef B3_CLOCK_H #define B3_CLOCK_H - ///The b3Clock is a portable basic clock that measures accurate time in seconds, use for profiling. class b3Clock { @@ -14,17 +13,17 @@ public: ~b3Clock(); /// Resets the initial reference time. If zeroReference is true, will set reference to absolute 0. - void reset(bool zeroReference=false); + void reset(bool zeroReference = false); - /// Returns the time in ms since the last call to reset or since + /// Returns the time in ms since the last call to reset or since /// the b3Clock was created. unsigned long int getTimeMilliseconds(); - /// Returns the time in us since the last call to reset or since + /// Returns the time in us since the last call to reset or since /// the Clock was created. unsigned long long int getTimeMicroseconds(); - /// Returns the time in seconds since the last call to reset or since + /// Returns the time in seconds since the last call to reset or since /// the Clock was created. double getTimeInSeconds(); @@ -36,5 +35,4 @@ private: struct b3ClockData* m_data; }; - -#endif //B3_CLOCK_H +#endif //B3_CLOCK_H diff --git a/examples/Utils/b3ERPCFMHelper.hpp b/examples/Utils/b3ERPCFMHelper.hpp index 272616782..89be537a6 100755 --- a/examples/Utils/b3ERPCFMHelper.hpp +++ b/examples/Utils/b3ERPCFMHelper.hpp @@ -9,9 +9,9 @@ * @date 2015-09-20 * @author Benjamin Ellenberger */ -class b3ERPCFMHelper { +class b3ERPCFMHelper +{ public: - /** * == How To Use ERP and CFM == * ERP and CFM can be independently set in many joints. They can be set in contact joints, in joint limits and various other places, to control the spongyness and springyness of the joint (or joint limit). @@ -45,7 +45,8 @@ public: * @return */ static btScalar getERP(btScalar timeStep, btScalar kSpring, - btScalar kDamper) { + btScalar kDamper) + { return timeStep * kSpring / (timeStep * kSpring + kDamper); } @@ -71,7 +72,8 @@ public: * @return */ static btScalar getCFM(btScalar avoidSingularity, btScalar timeStep, btScalar kSpring, - btScalar kDamper) { + btScalar kDamper) + { return btScalar(avoidSingularity) / (timeStep * kSpring + kDamper); } }; diff --git a/examples/Utils/b3Quickprof.cpp b/examples/Utils/b3Quickprof.cpp index 4ba9158dd..96c57264c 100644 --- a/examples/Utils/b3Quickprof.cpp +++ b/examples/Utils/b3Quickprof.cpp @@ -24,37 +24,27 @@ subject to the following restrictions: ** ***************************************************************************************************/ -// Credits: The Clock class was inspired by the Timer classes in +// Credits: The Clock class was inspired by the Timer classes in // Ogre (www.ogre3d.org). #include "Bullet3Common/b3MinMax.h" #include "b3Quickprof.h" - #ifndef B3_NO_PROFILE - static b3Clock b3s_profileClock; - - - - - -inline void b3Profile_Get_Ticks(unsigned long int * ticks) +inline void b3Profile_Get_Ticks(unsigned long int* ticks) { *ticks = b3s_profileClock.getTimeMicroseconds(); } inline float b3Profile_Get_Tick_Rate(void) { -// return 1000000.f; + // return 1000000.f; return 1000.f; - } - - /*************************************************************************************************** ** ** b3ProfileNode @@ -70,36 +60,33 @@ inline float b3Profile_Get_Tick_Rate(void) * The name is assumed to be a static pointer, only the pointer is stored and compared for * * efficiency reasons. * *=============================================================================================*/ -b3ProfileNode::b3ProfileNode( const char * name, b3ProfileNode * parent ) : - Name( name ), - TotalCalls( 0 ), - TotalTime( 0 ), - StartTime( 0 ), - RecursionCounter( 0 ), - Parent( parent ), - Child( NULL ), - Sibling( NULL ), - m_userPtr(0) +b3ProfileNode::b3ProfileNode(const char* name, b3ProfileNode* parent) : Name(name), + TotalCalls(0), + TotalTime(0), + StartTime(0), + RecursionCounter(0), + Parent(parent), + Child(NULL), + Sibling(NULL), + m_userPtr(0) { Reset(); } - -void b3ProfileNode::CleanupMemory() +void b3ProfileNode::CleanupMemory() { - delete ( Child); + delete (Child); Child = NULL; - delete ( Sibling); + delete (Sibling); Sibling = NULL; } -b3ProfileNode::~b3ProfileNode( void ) +b3ProfileNode::~b3ProfileNode(void) { - delete ( Child); - delete ( Sibling); + delete (Child); + delete (Sibling); } - /*********************************************************************************************** * INPUT: * * name - static string pointer to the name of the node we are searching for * @@ -108,127 +95,124 @@ b3ProfileNode::~b3ProfileNode( void ) * All profile names are assumed to be static strings so this function uses pointer compares * * to find the named node. * *=============================================================================================*/ -b3ProfileNode * b3ProfileNode::Get_Sub_Node( const char * name ) +b3ProfileNode* b3ProfileNode::Get_Sub_Node(const char* name) { // Try to find this sub node - b3ProfileNode * child = Child; - while ( child ) { - if ( child->Name == name ) { + b3ProfileNode* child = Child; + while (child) + { + if (child->Name == name) + { return child; } child = child->Sibling; } // We didn't find it, so add it - - b3ProfileNode * node = new b3ProfileNode( name, this ); + + b3ProfileNode* node = new b3ProfileNode(name, this); node->Sibling = Child; Child = node; return node; } - -void b3ProfileNode::Reset( void ) +void b3ProfileNode::Reset(void) { TotalCalls = 0; TotalTime = 0.0f; - - if ( Child ) { + if (Child) + { Child->Reset(); } - if ( Sibling ) { + if (Sibling) + { Sibling->Reset(); } } - -void b3ProfileNode::Call( void ) +void b3ProfileNode::Call(void) { TotalCalls++; - if (RecursionCounter++ == 0) { + if (RecursionCounter++ == 0) + { b3Profile_Get_Ticks(&StartTime); } } - -bool b3ProfileNode::Return( void ) +bool b3ProfileNode::Return(void) { - if ( --RecursionCounter == 0 && TotalCalls != 0 ) { + if (--RecursionCounter == 0 && TotalCalls != 0) + { unsigned long int time; b3Profile_Get_Ticks(&time); - time-=StartTime; + time -= StartTime; TotalTime += (float)time / b3Profile_Get_Tick_Rate(); } - return ( RecursionCounter == 0 ); + return (RecursionCounter == 0); } - /*************************************************************************************************** ** ** b3ProfileIterator ** ***************************************************************************************************/ -b3ProfileIterator::b3ProfileIterator( b3ProfileNode * start ) +b3ProfileIterator::b3ProfileIterator(b3ProfileNode* start) { CurrentParent = start; CurrentChild = CurrentParent->Get_Child(); } - -void b3ProfileIterator::First(void) +void b3ProfileIterator::First(void) { CurrentChild = CurrentParent->Get_Child(); } - -void b3ProfileIterator::Next(void) +void b3ProfileIterator::Next(void) { CurrentChild = CurrentChild->Get_Sibling(); } - -bool b3ProfileIterator::Is_Done(void) +bool b3ProfileIterator::Is_Done(void) { return CurrentChild == NULL; } - -void b3ProfileIterator::Enter_Child( int index ) +void b3ProfileIterator::Enter_Child(int index) { CurrentChild = CurrentParent->Get_Child(); - while ( (CurrentChild != NULL) && (index != 0) ) { + while ((CurrentChild != NULL) && (index != 0)) + { index--; CurrentChild = CurrentChild->Get_Sibling(); } - if ( CurrentChild != NULL ) { + if (CurrentChild != NULL) + { CurrentParent = CurrentChild; CurrentChild = CurrentParent->Get_Child(); } } - -void b3ProfileIterator::Enter_Parent( void ) +void b3ProfileIterator::Enter_Parent(void) { - if ( CurrentParent->Get_Parent() != NULL ) { + if (CurrentParent->Get_Parent() != NULL) + { CurrentParent = CurrentParent->Get_Parent(); } CurrentChild = CurrentParent->Get_Child(); } - /*************************************************************************************************** ** ** b3ProfileManager ** ***************************************************************************************************/ -b3ProfileNode b3ProfileManager::Root( "Root", NULL ); -b3ProfileNode * b3ProfileManager::CurrentNode = &b3ProfileManager::Root; -int b3ProfileManager::FrameCounter = 0; -unsigned long int b3ProfileManager::ResetTime = 0; - +b3ProfileNode b3ProfileManager::Root("Root", NULL); +b3ProfileNode* b3ProfileManager::CurrentNode = &b3ProfileManager::Root; +int b3ProfileManager::FrameCounter = 0; +unsigned long int b3ProfileManager::ResetTime = 0; /*********************************************************************************************** * b3ProfileManager::Start_Profile -- Begin a named profile * @@ -243,57 +227,55 @@ unsigned long int b3ProfileManager::ResetTime = 0; * The string used is assumed to be a static string; pointer compares are used throughout * * the profiling code for efficiency. * *=============================================================================================*/ -void b3ProfileManager::Start_Profile( const char * name ) +void b3ProfileManager::Start_Profile(const char* name) { - if (name != CurrentNode->Get_Name()) { - CurrentNode = CurrentNode->Get_Sub_Node( name ); - } - + if (name != CurrentNode->Get_Name()) + { + CurrentNode = CurrentNode->Get_Sub_Node(name); + } + CurrentNode->Call(); } - /*********************************************************************************************** * b3ProfileManager::Stop_Profile -- Stop timing and record the results. * *=============================================================================================*/ -void b3ProfileManager::Stop_Profile( void ) +void b3ProfileManager::Stop_Profile(void) { // Return will indicate whether we should back up to our parent (we may // be profiling a recursive function) - if (CurrentNode->Return()) { + if (CurrentNode->Return()) + { CurrentNode = CurrentNode->Get_Parent(); } } - /*********************************************************************************************** * b3ProfileManager::Reset -- Reset the contents of the profiling system * * * * This resets everything except for the tree structure. All of the timing data is reset. * *=============================================================================================*/ -void b3ProfileManager::Reset( void ) -{ +void b3ProfileManager::Reset(void) +{ b3s_profileClock.reset(); Root.Reset(); - Root.Call(); + Root.Call(); FrameCounter = 0; b3Profile_Get_Ticks(&ResetTime); } - /*********************************************************************************************** * b3ProfileManager::Increment_Frame_Counter -- Increment the frame counter * *=============================================================================================*/ -void b3ProfileManager::Increment_Frame_Counter( void ) +void b3ProfileManager::Increment_Frame_Counter(void) { FrameCounter++; } - /*********************************************************************************************** * b3ProfileManager::Get_Time_Since_Reset -- returns the elapsed time since last reset * *=============================================================================================*/ -float b3ProfileManager::Get_Time_Since_Reset( void ) +float b3ProfileManager::Get_Time_Since_Reset(void) { unsigned long int time; b3Profile_Get_Ticks(&time); @@ -303,34 +285,34 @@ float b3ProfileManager::Get_Time_Since_Reset( void ) #include -void b3ProfileManager::dumpRecursive(b3ProfileIterator* profileIterator, int spacing) +void b3ProfileManager::dumpRecursive(b3ProfileIterator* profileIterator, int spacing) { profileIterator->First(); if (profileIterator->Is_Done()) return; - float accumulated_time=0,parent_time = profileIterator->Is_Root() ? b3ProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time(); + float accumulated_time = 0, parent_time = profileIterator->Is_Root() ? b3ProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time(); int i; int frames_since_reset = b3ProfileManager::Get_Frame_Count_Since_Reset(); - for (i=0;iGet_Current_Parent_Name(), parent_time ); + for (i = 0; i < spacing; i++) b3Printf("."); + b3Printf("Profiling: %s (total running time: %.3f ms) ---\n", profileIterator->Get_Current_Parent_Name(), parent_time); float totalTime = 0.f; - int numChildren = 0; - - for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next()) + + for (i = 0; !profileIterator->Is_Done(); i++, profileIterator->Next()) { numChildren++; float current_total_time = profileIterator->Get_Current_Total_Time(); accumulated_time += current_total_time; float fraction = parent_time > B3_EPSILON ? (current_total_time / parent_time) * 100 : 0.f; { - int i; for (i=0;iGet_Current_Name(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls()); + b3Printf("%d -- %s (%.2f %%) :: %.3f ms / frame (%d calls)\n", i, profileIterator->Get_Current_Name(), fraction, (current_total_time / (double)frames_since_reset), profileIterator->Get_Current_Total_Calls()); totalTime += current_total_time; //recurse into children } @@ -339,92 +321,83 @@ void b3ProfileManager::dumpRecursive(b3ProfileIterator* profileIterator, int spa { b3Printf("what's wrong\n"); } - for (i=0;i B3_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time); - - for (i=0;i B3_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time); + + for (i = 0; i < numChildren; i++) { profileIterator->Enter_Child(i); - dumpRecursive(profileIterator,spacing+3); + dumpRecursive(profileIterator, spacing + 3); profileIterator->Enter_Parent(); } } - - - -void b3ProfileManager::dumpAll() +void b3ProfileManager::dumpAll() { b3ProfileIterator* profileIterator = 0; profileIterator = b3ProfileManager::Get_Iterator(); - dumpRecursive(profileIterator,0); + dumpRecursive(profileIterator, 0); b3ProfileManager::Release_Iterator(profileIterator); } - -void b3ProfileManager::dumpRecursive(FILE* f, b3ProfileIterator* profileIterator, int spacing) +void b3ProfileManager::dumpRecursive(FILE* f, b3ProfileIterator* profileIterator, int spacing) { profileIterator->First(); if (profileIterator->Is_Done()) return; - float accumulated_time=0,parent_time = profileIterator->Is_Root() ? b3ProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time(); + float accumulated_time = 0, parent_time = profileIterator->Is_Root() ? b3ProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time(); int i; int frames_since_reset = b3ProfileManager::Get_Frame_Count_Since_Reset(); - for (i=0;iGet_Current_Parent_Name(), parent_time ); + for (i = 0; i < spacing; i++) fprintf(f, "."); + fprintf(f, "----------------------------------\n"); + for (i = 0; i < spacing; i++) fprintf(f, "."); + fprintf(f, "Profiling: %s (total running time: %.3f ms) ---\n", profileIterator->Get_Current_Parent_Name(), parent_time); float totalTime = 0.f; - int numChildren = 0; - - for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next()) + + for (i = 0; !profileIterator->Is_Done(); i++, profileIterator->Next()) { numChildren++; float current_total_time = profileIterator->Get_Current_Total_Time(); accumulated_time += current_total_time; float fraction = parent_time > B3_EPSILON ? (current_total_time / parent_time) * 100 : 0.f; { - int i; for (i=0;iGet_Current_Name(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls()); + fprintf(f, "%d -- %s (%.2f %%) :: %.3f ms / frame (%d calls)\n", i, profileIterator->Get_Current_Name(), fraction, (current_total_time / (double)frames_since_reset), profileIterator->Get_Current_Total_Calls()); totalTime += current_total_time; //recurse into children } if (parent_time < accumulated_time) { - fprintf(f,"what's wrong\n"); + fprintf(f, "what's wrong\n"); } - for (i=0;i B3_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time); - - for (i=0;i B3_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time); + + for (i = 0; i < numChildren; i++) { profileIterator->Enter_Child(i); - dumpRecursive(f,profileIterator,spacing+3); + dumpRecursive(f, profileIterator, spacing + 3); profileIterator->Enter_Parent(); } } - - - -void b3ProfileManager::dumpAll(FILE* f) +void b3ProfileManager::dumpAll(FILE* f) { b3ProfileIterator* profileIterator = 0; profileIterator = b3ProfileManager::Get_Iterator(); - dumpRecursive(f, profileIterator,0); + dumpRecursive(f, profileIterator, 0); b3ProfileManager::Release_Iterator(profileIterator); } - - -#endif //B3_NO_PROFILE +#endif //B3_NO_PROFILE diff --git a/examples/Utils/b3Quickprof.h b/examples/Utils/b3Quickprof.h index 44824baae..43394ad66 100644 --- a/examples/Utils/b3Quickprof.h +++ b/examples/Utils/b3Quickprof.h @@ -20,65 +20,57 @@ subject to the following restrictions: ** ***************************************************************************************************/ -// Credits: The Clock class was inspired by the Timer classes in +// Credits: The Clock class was inspired by the Timer classes in // Ogre (www.ogre3d.org). - - #ifndef B3_QUICK_PROF_H #define B3_QUICK_PROF_H //To disable built-in profiling, please comment out next line //#define B3_NO_PROFILE 1 #ifndef B3_NO_PROFILE -#include //@todo remove this, backwards compatibility +#include //@todo remove this, backwards compatibility #include "Bullet3Common/b3Scalar.h" #include "Bullet3Common/b3AlignedAllocator.h" #include - - - #include "b3Clock.h" - - - ///A node in the Profile Hierarchy Tree -class b3ProfileNode { - +class b3ProfileNode +{ public: - b3ProfileNode( const char * name, b3ProfileNode * parent ); - ~b3ProfileNode( void ); + b3ProfileNode(const char* name, b3ProfileNode* parent); + ~b3ProfileNode(void); - b3ProfileNode * Get_Sub_Node( const char * name ); + b3ProfileNode* Get_Sub_Node(const char* name); - b3ProfileNode * Get_Parent( void ) { return Parent; } - b3ProfileNode * Get_Sibling( void ) { return Sibling; } - b3ProfileNode * Get_Child( void ) { return Child; } + b3ProfileNode* Get_Parent(void) { return Parent; } + b3ProfileNode* Get_Sibling(void) { return Sibling; } + b3ProfileNode* Get_Child(void) { return Child; } - void CleanupMemory(); - void Reset( void ); - void Call( void ); - bool Return( void ); + void CleanupMemory(); + void Reset(void); + void Call(void); + bool Return(void); + + const char* Get_Name(void) { return Name; } + int Get_Total_Calls(void) { return TotalCalls; } + float Get_Total_Time(void) { return TotalTime; } + void* GetUserPointer() const { return m_userPtr; } + void SetUserPointer(void* ptr) { m_userPtr = ptr; } - const char * Get_Name( void ) { return Name; } - int Get_Total_Calls( void ) { return TotalCalls; } - float Get_Total_Time( void ) { return TotalTime; } - void* GetUserPointer() const {return m_userPtr;} - void SetUserPointer(void* ptr) { m_userPtr = ptr;} protected: + const char* Name; + int TotalCalls; + float TotalTime; + unsigned long int StartTime; + int RecursionCounter; - const char * Name; - int TotalCalls; - float TotalTime; - unsigned long int StartTime; - int RecursionCounter; - - b3ProfileNode * Parent; - b3ProfileNode * Child; - b3ProfileNode * Sibling; - void* m_userPtr; + b3ProfileNode* Parent; + b3ProfileNode* Child; + b3ProfileNode* Sibling; + void* m_userPtr; }; ///An iterator to navigate through the tree @@ -86,88 +78,73 @@ class b3ProfileIterator { public: // Access all the children of the current parent - void First(void); - void Next(void); - bool Is_Done(void); - bool Is_Root(void) { return (CurrentParent->Get_Parent() == 0); } + void First(void); + void Next(void); + bool Is_Done(void); + bool Is_Root(void) { return (CurrentParent->Get_Parent() == 0); } - void Enter_Child( int index ); // Make the given child the new parent - void Enter_Largest_Child( void ); // Make the largest child the new parent - void Enter_Parent( void ); // Make the current parent's parent the new parent + void Enter_Child(int index); // Make the given child the new parent + void Enter_Largest_Child(void); // Make the largest child the new parent + void Enter_Parent(void); // Make the current parent's parent the new parent // Access the current child - const char * Get_Current_Name( void ) { return CurrentChild->Get_Name(); } - int Get_Current_Total_Calls( void ) { return CurrentChild->Get_Total_Calls(); } - float Get_Current_Total_Time( void ) { return CurrentChild->Get_Total_Time(); } + const char* Get_Current_Name(void) { return CurrentChild->Get_Name(); } + int Get_Current_Total_Calls(void) { return CurrentChild->Get_Total_Calls(); } + float Get_Current_Total_Time(void) { return CurrentChild->Get_Total_Time(); } - void* Get_Current_UserPointer( void ) { return CurrentChild->GetUserPointer(); } - void Set_Current_UserPointer(void* ptr) {CurrentChild->SetUserPointer(ptr);} + void* Get_Current_UserPointer(void) { return CurrentChild->GetUserPointer(); } + void Set_Current_UserPointer(void* ptr) { CurrentChild->SetUserPointer(ptr); } // Access the current parent - const char * Get_Current_Parent_Name( void ) { return CurrentParent->Get_Name(); } - int Get_Current_Parent_Total_Calls( void ) { return CurrentParent->Get_Total_Calls(); } - float Get_Current_Parent_Total_Time( void ) { return CurrentParent->Get_Total_Time(); } - - + const char* Get_Current_Parent_Name(void) { return CurrentParent->Get_Name(); } + int Get_Current_Parent_Total_Calls(void) { return CurrentParent->Get_Total_Calls(); } + float Get_Current_Parent_Total_Time(void) { return CurrentParent->Get_Total_Time(); } protected: + b3ProfileNode* CurrentParent; + b3ProfileNode* CurrentChild; - b3ProfileNode * CurrentParent; - b3ProfileNode * CurrentChild; - - - b3ProfileIterator( b3ProfileNode * start ); - friend class b3ProfileManager; + b3ProfileIterator(b3ProfileNode* start); + friend class b3ProfileManager; }; - ///The Manager for the Profile system -class b3ProfileManager { +class b3ProfileManager +{ public: - static void Start_Profile( const char * name ); - static void Stop_Profile( void ); + static void Start_Profile(const char* name); + static void Stop_Profile(void); - static void CleanupMemory(void) + static void CleanupMemory(void) { Root.CleanupMemory(); } - static void Reset( void ); - static void Increment_Frame_Counter( void ); - static int Get_Frame_Count_Since_Reset( void ) { return FrameCounter; } - static float Get_Time_Since_Reset( void ); + static void Reset(void); + static void Increment_Frame_Counter(void); + static int Get_Frame_Count_Since_Reset(void) { return FrameCounter; } + static float Get_Time_Since_Reset(void); - static b3ProfileIterator * Get_Iterator( void ) - { - - return new b3ProfileIterator( &Root ); + static b3ProfileIterator* Get_Iterator(void) + { + return new b3ProfileIterator(&Root); } - static void Release_Iterator( b3ProfileIterator * iterator ) { delete ( iterator); } + static void Release_Iterator(b3ProfileIterator* iterator) { delete (iterator); } - static void dumpRecursive(b3ProfileIterator* profileIterator, int spacing); - static void dumpAll(); + static void dumpRecursive(b3ProfileIterator* profileIterator, int spacing); + static void dumpAll(); - static void dumpRecursive(FILE* f, b3ProfileIterator* profileIterator, int spacing); - static void dumpAll(FILE* f); + static void dumpRecursive(FILE* f, b3ProfileIterator* profileIterator, int spacing); + static void dumpAll(FILE* f); private: - static b3ProfileNode Root; - static b3ProfileNode * CurrentNode; - static int FrameCounter; - static unsigned long int ResetTime; + static b3ProfileNode Root; + static b3ProfileNode* CurrentNode; + static int FrameCounter; + static unsigned long int ResetTime; }; - - - - #else +#endif //#ifndef B3_NO_PROFILE - -#endif //#ifndef B3_NO_PROFILE - - - -#endif //B3_QUICK_PROF_H - - +#endif //B3_QUICK_PROF_H diff --git a/examples/Utils/b3ReferenceFrameHelper.hpp b/examples/Utils/b3ReferenceFrameHelper.hpp index 05e839d53..8616a6d41 100755 --- a/examples/Utils/b3ReferenceFrameHelper.hpp +++ b/examples/Utils/b3ReferenceFrameHelper.hpp @@ -19,38 +19,44 @@ subject to the following restrictions: #include "LinearMath/btTransform.h" #include "LinearMath/btVector3.h" -class b3ReferenceFrameHelper { +class b3ReferenceFrameHelper +{ public: - static btVector3 getPointWorldToLocal(const btTransform& localObjectCenterOfMassTransform, const btVector3& point) { - return localObjectCenterOfMassTransform.inverse() * point; // transforms the point from the world frame into the local frame + static btVector3 getPointWorldToLocal(const btTransform& localObjectCenterOfMassTransform, const btVector3& point) + { + return localObjectCenterOfMassTransform.inverse() * point; // transforms the point from the world frame into the local frame } - static btVector3 getPointLocalToWorld(const btTransform& localObjectCenterOfMassTransform,const btVector3& point) { - return localObjectCenterOfMassTransform * point; // transforms the point from the world frame into the local frame + static btVector3 getPointLocalToWorld(const btTransform& localObjectCenterOfMassTransform, const btVector3& point) + { + return localObjectCenterOfMassTransform * point; // transforms the point from the world frame into the local frame } - static btVector3 getAxisWorldToLocal(const btTransform& localObjectCenterOfMassTransform, const btVector3& axis) { - btTransform local1 = localObjectCenterOfMassTransform.inverse(); // transforms the axis from the local frame into the world frame - btVector3 zero(0,0,0); - local1.setOrigin(zero); - return local1 * axis; + static btVector3 getAxisWorldToLocal(const btTransform& localObjectCenterOfMassTransform, const btVector3& axis) + { + btTransform local1 = localObjectCenterOfMassTransform.inverse(); // transforms the axis from the local frame into the world frame + btVector3 zero(0, 0, 0); + local1.setOrigin(zero); + return local1 * axis; } - static btVector3 getAxisLocalToWorld(const btTransform& localObjectCenterOfMassTransform, const btVector3& axis) { - btTransform local1 = localObjectCenterOfMassTransform; // transforms the axis from the local frame into the world frame - btVector3 zero(0,0,0); - local1.setOrigin(zero); - return local1 * axis; + static btVector3 getAxisLocalToWorld(const btTransform& localObjectCenterOfMassTransform, const btVector3& axis) + { + btTransform local1 = localObjectCenterOfMassTransform; // transforms the axis from the local frame into the world frame + btVector3 zero(0, 0, 0); + local1.setOrigin(zero); + return local1 * axis; } - static btTransform getTransformWorldToLocal(const btTransform& localObjectCenterOfMassTransform, const btTransform& transform) { - return localObjectCenterOfMassTransform.inverse() * transform; // transforms the axis from the local frame into the world frame + static btTransform getTransformWorldToLocal(const btTransform& localObjectCenterOfMassTransform, const btTransform& transform) + { + return localObjectCenterOfMassTransform.inverse() * transform; // transforms the axis from the local frame into the world frame } - static btTransform getTransformLocalToWorld(const btTransform& localObjectCenterOfMassTransform, const btTransform& transform) { - return localObjectCenterOfMassTransform * transform; // transforms the axis from the local frame into the world frame + static btTransform getTransformLocalToWorld(const btTransform& localObjectCenterOfMassTransform, const btTransform& transform) + { + return localObjectCenterOfMassTransform * transform; // transforms the axis from the local frame into the world frame } - }; #endif /* B3_REFERENCEFRAMEHELPER_H */ diff --git a/examples/Utils/b3ResourcePath.cpp b/examples/Utils/b3ResourcePath.cpp index 913b2d319..4ff3c2ac7 100644 --- a/examples/Utils/b3ResourcePath.cpp +++ b/examples/Utils/b3ResourcePath.cpp @@ -1,7 +1,7 @@ #include "b3ResourcePath.h" #include "Bullet3Common/b3Logging.h" #ifdef __APPLE__ -#include /* _NSGetExecutablePath */ +#include /* _NSGetExecutablePath */ #else #ifdef _WIN32 #include @@ -11,7 +11,6 @@ #endif #endif - #include "Bullet3Common/b3FileUtils.h" #define B3_MAX_EXE_PATH_LEN 4096 @@ -20,13 +19,14 @@ int b3ResourcePath::getExePath(char* path, int maxPathLenInBytes) int numBytes = 0; #if __APPLE__ - uint32_t bufsize = uint32_t(maxPathLenInBytes); + uint32_t bufsize = uint32_t(maxPathLenInBytes); - if (_NSGetExecutablePath(path, &bufsize)!=0) + if (_NSGetExecutablePath(path, &bufsize) != 0) { b3Warning("Cannot find executable path\n"); return false; - } else + } + else { numBytes = strlen(path); } @@ -39,16 +39,17 @@ int b3ResourcePath::getExePath(char* path, int maxPathLenInBytes) #else ///http://stackoverflow.com/questions/933850/how-to-find-the-location-of-the-executable-in-c - numBytes = (int)readlink("/proc/self/exe", path, maxPathLenInBytes-1); - if (numBytes > 0) + numBytes = (int)readlink("/proc/self/exe", path, maxPathLenInBytes - 1); + if (numBytes > 0) { path[numBytes] = 0; - } else + } + else { b3Warning("Cannot find executable path\n"); } -#endif //_WIN32 -#endif //__APPLE__ +#endif //_WIN32 +#endif //__APPLE__ return numBytes; } @@ -59,7 +60,7 @@ struct TempResourcePath TempResourcePath(int len) { m_path = (char*)malloc(len); - memset(m_path,0,len); + memset(m_path, 0, len); } virtual ~TempResourcePath() { @@ -74,12 +75,13 @@ void b3ResourcePath::setAdditionalSearchPath(const char* path) if (path) { int len = strlen(path); - if (len<(B3_MAX_EXE_PATH_LEN-1)) + if (len < (B3_MAX_EXE_PATH_LEN - 1)) { - strcpy(sAdditionalSearchPath,path); + strcpy(sAdditionalSearchPath, path); sAdditionalSearchPath[len] = 0; } - } else + } + else { sAdditionalSearchPath[0] = 0; } @@ -92,16 +94,16 @@ int b3ResourcePath::findResourcePath(const char* resourceName, char* resourcePat bool res = b3FileUtils::findFile(resourceName, resourcePathOut, resourcePathMaxNumBytes); if (res) - { - return strlen(resourcePathOut); - } + { + return strlen(resourcePathOut); + } if (sAdditionalSearchPath[0]) { - TempResourcePath tmpPath(resourcePathMaxNumBytes+1024); + TempResourcePath tmpPath(resourcePathMaxNumBytes + 1024); char* resourcePathIn = tmpPath.m_path; - sprintf(resourcePathIn,"%s/%s",sAdditionalSearchPath,resourceName); - //printf("try resource at %s\n", resourcePath); + sprintf(resourcePathIn, "%s/%s", sAdditionalSearchPath, resourceName); + //printf("try resource at %s\n", resourcePath); if (b3FileUtils::findFile(resourcePathIn, resourcePathOut, resourcePathMaxNumBytes)) { return strlen(resourcePathOut); @@ -111,37 +113,34 @@ int b3ResourcePath::findResourcePath(const char* resourceName, char* resourcePat int l = b3ResourcePath::getExePath(exePath, B3_MAX_EXE_PATH_LEN); if (l) { - char pathToExe[B3_MAX_EXE_PATH_LEN]; + char pathToExe[B3_MAX_EXE_PATH_LEN]; - int exeNamePos = b3FileUtils::extractPath(exePath,pathToExe,B3_MAX_EXE_PATH_LEN); - if (exeNamePos) - { - TempResourcePath tmpPath(resourcePathMaxNumBytes+1024); - char* resourcePathIn = tmpPath.m_path; - sprintf(resourcePathIn,"%s../data/%s",pathToExe,resourceName); - //printf("try resource at %s\n", resourcePath); - if (b3FileUtils::findFile(resourcePathIn, resourcePathOut, resourcePathMaxNumBytes)) - { - return strlen(resourcePathOut); - } + int exeNamePos = b3FileUtils::extractPath(exePath, pathToExe, B3_MAX_EXE_PATH_LEN); + if (exeNamePos) + { + TempResourcePath tmpPath(resourcePathMaxNumBytes + 1024); + char* resourcePathIn = tmpPath.m_path; + sprintf(resourcePathIn, "%s../data/%s", pathToExe, resourceName); + //printf("try resource at %s\n", resourcePath); + if (b3FileUtils::findFile(resourcePathIn, resourcePathOut, resourcePathMaxNumBytes)) + { + return strlen(resourcePathOut); + } - sprintf(resourcePathIn,"%s../resources/%s/%s",pathToExe,&exePath[exeNamePos],resourceName); - //printf("try resource at %s\n", resourcePath); - if (b3FileUtils::findFile(resourcePathIn, resourcePathOut, resourcePathMaxNumBytes)) - { - return strlen(resourcePathOut); - } - sprintf(resourcePathIn,"%s.runfiles/google3/third_party/bullet/data/%s",exePath,resourceName); - //printf("try resource at %s\n", resourcePath); - if (b3FileUtils::findFile(resourcePathIn, resourcePathOut, resourcePathMaxNumBytes)) - { - return strlen(resourcePathOut); - } - } + sprintf(resourcePathIn, "%s../resources/%s/%s", pathToExe, &exePath[exeNamePos], resourceName); + //printf("try resource at %s\n", resourcePath); + if (b3FileUtils::findFile(resourcePathIn, resourcePathOut, resourcePathMaxNumBytes)) + { + return strlen(resourcePathOut); + } + sprintf(resourcePathIn, "%s.runfiles/google3/third_party/bullet/data/%s", exePath, resourceName); + //printf("try resource at %s\n", resourcePath); + if (b3FileUtils::findFile(resourcePathIn, resourcePathOut, resourcePathMaxNumBytes)) + { + return strlen(resourcePathOut); + } + } } - - return 0; } - diff --git a/examples/Utils/b3ResourcePath.h b/examples/Utils/b3ResourcePath.h index 2b3264b68..b7b0f129b 100644 --- a/examples/Utils/b3ResourcePath.h +++ b/examples/Utils/b3ResourcePath.h @@ -1,5 +1,5 @@ #ifndef _B3_RESOURCE_PATH_H -#define _B3_RESOURCE_PATH_H +#define _B3_RESOURCE_PATH_H #include @@ -11,4 +11,3 @@ public: static void setAdditionalSearchPath(const char* path); }; #endif - diff --git a/examples/Vehicles/Hinge2Vehicle.cpp b/examples/Vehicles/Hinge2Vehicle.cpp index a7ecb07af..3564a23ae 100644 --- a/examples/Vehicles/Hinge2Vehicle.cpp +++ b/examples/Vehicles/Hinge2Vehicle.cpp @@ -21,7 +21,6 @@ subject to the following restrictions: #include "btBulletDynamicsCommon.h" #include "BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h" - #include "BulletDynamics/MLCPSolvers/btDantzigSolver.h" #include "BulletDynamics/MLCPSolvers/btSolveProjectedGaussSeidel.h" #include "BulletDynamics/MLCPSolvers/btMLCPSolver.h" @@ -30,7 +29,6 @@ class btVehicleTuning; class btCollisionShape; - #include "BulletDynamics/ConstraintSolver/btHingeConstraint.h" #include "BulletDynamics/ConstraintSolver/btSliderConstraint.h" @@ -44,76 +42,68 @@ class btCollisionShape; #include "../CommonInterfaces/CommonRigidBodyBase.h" -class Hinge2Vehicle : public CommonRigidBodyBase +class Hinge2Vehicle : public CommonRigidBodyBase { - public: - - /* extra stuff*/ +public: + /* extra stuff*/ btVector3 m_cameraPosition; - + btRigidBody* m_carChassis; btRigidBody* localCreateRigidBody(btScalar mass, const btTransform& worldTransform, btCollisionShape* colSape); GUIHelperInterface* m_guiHelper; int m_wheelInstances[4]; -//---------------------------- + //---------------------------- btRigidBody* m_liftBody; - btVector3 m_liftStartPos; + btVector3 m_liftStartPos; btHingeConstraint* m_liftHinge; btRigidBody* m_forkBody; - btVector3 m_forkStartPos; + btVector3 m_forkStartPos; btSliderConstraint* m_forkSlider; btRigidBody* m_loadBody; - btVector3 m_loadStartPos; + btVector3 m_loadStartPos; void lockLiftHinge(void); void lockForkSlider(void); bool m_useDefaultCamera; -//---------------------------- + //---------------------------- + class btTriangleIndexVertexArray* m_indexVertexArrays; - class btTriangleIndexVertexArray* m_indexVertexArrays; + btVector3* m_vertices; - btVector3* m_vertices; + btCollisionShape* m_wheelShape; - - - btCollisionShape* m_wheelShape; - - float m_cameraHeight; - - float m_minCameraDistance; - float m_maxCameraDistance; + float m_cameraHeight; + float m_minCameraDistance; + float m_maxCameraDistance; Hinge2Vehicle(struct GUIHelperInterface* helper); virtual ~Hinge2Vehicle(); virtual void stepSimulation(float deltaTime); - - virtual void resetForklift(); - + + virtual void resetForklift(); + virtual void clientResetScene(); virtual void displayCallback(); - - + virtual void specialKeyboard(int key, int x, int y); virtual void specialKeyboardUp(int key, int x, int y); - - virtual bool keyboardCallback(int key, int state); + virtual bool keyboardCallback(int key, int state); virtual void renderScene(); virtual void physicsDebugDraw(int debugFlags); - void initPhysics(); void exitPhysics(); @@ -123,8 +113,8 @@ class Hinge2Vehicle : public CommonRigidBodyBase float dist = 8; float pitch = -32; float yaw = -45; - float targetPos[3]={-0.33,-0.72,4.5}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {-0.33, -0.72, 4.5}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } /*static DemoApplication* Create() @@ -137,113 +127,98 @@ class Hinge2Vehicle : public CommonRigidBodyBase */ }; - static btScalar maxMotorImpulse = 4000.f; //the sequential impulse solver has difficulties dealing with large mass ratios (differences), between loadMass and the fork parts -static btScalar loadMass = 350.f;// +static btScalar loadMass = 350.f; // //btScalar loadMass = 10.f;//this should work fine for the SI solver - #ifndef M_PI -#define M_PI 3.14159265358979323846 +#define M_PI 3.14159265358979323846 #endif #ifndef M_PI_2 -#define M_PI_2 1.57079632679489661923 +#define M_PI_2 1.57079632679489661923 #endif #ifndef M_PI_4 -#define M_PI_4 0.785398163397448309616 +#define M_PI_4 0.785398163397448309616 #endif - //static int rightIndex = 0; //static int upIndex = 1; //static int forwardIndex = 2; -static btVector3 wheelDirectionCS0(0,-1,0); -static btVector3 wheelAxleCS(-1,0,0); +static btVector3 wheelDirectionCS0(0, -1, 0); +static btVector3 wheelAxleCS(-1, 0, 0); -static bool useMCLPSolver = false;//true; - - -#include //printf debugging +static bool useMCLPSolver = false; //true; +#include //printf debugging #include "Hinge2Vehicle.h" - //static const int maxProxies = 32766; //static const int maxOverlap = 65535; -static float gEngineForce = 0.f; +static float gEngineForce = 0.f; -static float defaultBreakingForce = 10.f; -static float gBreakingForce = 100.f; +static float defaultBreakingForce = 10.f; +static float gBreakingForce = 100.f; -static float maxEngineForce = 1000.f;//this should be engine/velocity dependent +static float maxEngineForce = 1000.f; //this should be engine/velocity dependent //static float maxBreakingForce = 100.f; -static float gVehicleSteering = 0.f; -static float steeringIncrement = 0.04f; -static float steeringClamp = 0.3f; -static float wheelRadius = 0.5f; -static float wheelWidth = 0.4f; +static float gVehicleSteering = 0.f; +static float steeringIncrement = 0.04f; +static float steeringClamp = 0.3f; +static float wheelRadius = 0.5f; +static float wheelWidth = 0.4f; //static float wheelFriction = 1000;//BT_LARGE_FLOAT; //static float suspensionStiffness = 20.f; //static float suspensionDamping = 2.3f; //static float suspensionCompression = 4.4f; //static float rollInfluence = 0.1f;//1.0f; - //static btScalar suspensionRestLength(0.6); #define CUBE_HALF_EXTENTS 1 - - //////////////////////////////////// - - - Hinge2Vehicle::Hinge2Vehicle(struct GUIHelperInterface* helper) -:CommonRigidBodyBase(helper), -m_carChassis(0), -m_guiHelper(helper), -m_liftBody(0), -m_forkBody(0), -m_loadBody(0), -m_indexVertexArrays(0), -m_vertices(0), -m_cameraHeight(4.f), -m_minCameraDistance(3.f), -m_maxCameraDistance(10.f) + : CommonRigidBodyBase(helper), + m_carChassis(0), + m_guiHelper(helper), + m_liftBody(0), + m_forkBody(0), + m_loadBody(0), + m_indexVertexArrays(0), + m_vertices(0), + m_cameraHeight(4.f), + m_minCameraDistance(3.f), + m_maxCameraDistance(10.f) { helper->setUpAxis(1); m_wheelShape = 0; - m_cameraPosition = btVector3(30,30,30); + m_cameraPosition = btVector3(30, 30, 30); m_useDefaultCamera = false; -// setTexturing(true); -// setShadows(true); - + // setTexturing(true); + // setShadows(true); } - void Hinge2Vehicle::exitPhysics() { - //cleanup in the reverse order of creation/initialization + //cleanup in the reverse order of creation/initialization //remove the rigidbodies from the dynamics world and delete them int i; - for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--) { btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; btRigidBody* body = btRigidBody::upcast(obj); if (body && body->getMotionState()) { - while (body->getNumConstraintRefs()) { btTypedConstraint* constraint = body->getConstraintRef(0); @@ -252,15 +227,16 @@ void Hinge2Vehicle::exitPhysics() } delete body->getMotionState(); m_dynamicsWorld->removeRigidBody(body); - } else + } + else { - m_dynamicsWorld->removeCollisionObject( obj ); + m_dynamicsWorld->removeCollisionObject(obj); } delete obj; } //delete collision shapes - for (int j=0;jsetUpAxis(1); - - btCollisionShape* groundShape = new btBoxShape(btVector3(50,3,50)); + btCollisionShape* groundShape = new btBoxShape(btVector3(50, 3, 50)); m_collisionShapes.push_back(groundShape); m_collisionConfiguration = new btDefaultCollisionConfiguration(); m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); - btVector3 worldMin(-1000,-1000,-1000); - btVector3 worldMax(1000,1000,1000); - m_broadphase = new btAxisSweep3(worldMin,worldMax); + btVector3 worldMin(-1000, -1000, -1000); + btVector3 worldMax(1000, 1000, 1000); + m_broadphase = new btAxisSweep3(worldMin, worldMax); if (useMCLPSolver) { btDantzigSolver* mlcp = new btDantzigSolver(); //btSolveProjectedGaussSeidel* mlcp = new btSolveProjectedGaussSeidel; btMLCPSolver* sol = new btMLCPSolver(mlcp); m_solver = sol; - } else + } + else { m_solver = new btSequentialImpulseConstraintSolver(); } - m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration); if (useMCLPSolver) { - m_dynamicsWorld ->getSolverInfo().m_minimumSolverBatchSize = 1;//for direct solver it is better to have a small A matrix - } else + m_dynamicsWorld->getSolverInfo().m_minimumSolverBatchSize = 1; //for direct solver it is better to have a small A matrix + } + else { - m_dynamicsWorld ->getSolverInfo().m_minimumSolverBatchSize = 128;//for direct solver, it is better to solve multiple objects together, small batches have high overhead + m_dynamicsWorld->getSolverInfo().m_minimumSolverBatchSize = 128; //for direct solver, it is better to solve multiple objects together, small batches have high overhead } m_dynamicsWorld->getSolverInfo().m_numIterations = 100; m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); - //m_dynamicsWorld->setGravity(btVector3(0,0,0)); -btTransform tr; -tr.setIdentity(); -tr.setOrigin(btVector3(0,-3,0)); - -//either use heightfield or triangle mesh + btTransform tr; + tr.setIdentity(); + tr.setOrigin(btVector3(0, -3, 0)); + //either use heightfield or triangle mesh //create ground object - localCreateRigidBody(0,tr,groundShape); + localCreateRigidBody(0, tr, groundShape); - btCollisionShape* chassisShape = new btBoxShape(btVector3(1.f,0.5f,2.f)); + btCollisionShape* chassisShape = new btBoxShape(btVector3(1.f, 0.5f, 2.f)); m_collisionShapes.push_back(chassisShape); btCompoundShape* compound = new btCompoundShape(); @@ -355,28 +326,27 @@ tr.setOrigin(btVector3(0,-3,0)); btTransform localTrans; localTrans.setIdentity(); //localTrans effectively shifts the center of mass with respect to the chassis - localTrans.setOrigin(btVector3(0,1,0)); + localTrans.setOrigin(btVector3(0, 1, 0)); - compound->addChildShape(localTrans,chassisShape); + compound->addChildShape(localTrans, chassisShape); { - btCollisionShape* suppShape = new btBoxShape(btVector3(0.5f,0.1f,0.5f)); + btCollisionShape* suppShape = new btBoxShape(btVector3(0.5f, 0.1f, 0.5f)); btTransform suppLocalTrans; suppLocalTrans.setIdentity(); //localTrans effectively shifts the center of mass with respect to the chassis - suppLocalTrans.setOrigin(btVector3(0,1.0,2.5)); + suppLocalTrans.setOrigin(btVector3(0, 1.0, 2.5)); compound->addChildShape(suppLocalTrans, suppShape); } - tr.setOrigin(btVector3(0,0.f,0)); + tr.setOrigin(btVector3(0, 0.f, 0)); btScalar chassisMass = 800; - m_carChassis = localCreateRigidBody(chassisMass,tr,compound);//chassisShape); + m_carChassis = localCreateRigidBody(chassisMass, tr, compound); //chassisShape); //m_carChassis->setDamping(0.2,0.2); - + //m_wheelShape = new btCylinderShapeX(btVector3(wheelWidth,wheelRadius,wheelRadius)); - m_wheelShape = new btCylinderShapeX(btVector3(wheelWidth,wheelRadius,wheelRadius)); - + m_wheelShape = new btCylinderShapeX(btVector3(wheelWidth, wheelRadius, wheelRadius)); //const float position[4]={0,10,10,0}; //const float quaternion[4]={0,0,0,1}; @@ -387,67 +357,62 @@ tr.setOrigin(btVector3(0,-3,0)); btVector3(btScalar(-1.), btScalar(-0.25), btScalar(1.25)), btVector3(btScalar(1.), btScalar(-0.25), btScalar(1.25)), btVector3(btScalar(1.), btScalar(-0.25), btScalar(-1.25)), - btVector3(btScalar(-1.), btScalar(-0.25), btScalar(-1.25)) - }; + btVector3(btScalar(-1.), btScalar(-0.25), btScalar(-1.25))}; - - for (int i=0;i<4;i++) - { + for (int i = 0; i < 4; i++) + { // create a Hinge2 joint // create two rigid bodies // static bodyA (parent) on top: - - - btRigidBody* pBodyA = this->m_carChassis;//m_chassis;//createRigidBody( 0.0, tr, m_wheelShape); + + btRigidBody* pBodyA = this->m_carChassis; //m_chassis;//createRigidBody( 0.0, tr, m_wheelShape); pBodyA->setActivationState(DISABLE_DEACTIVATION); // dynamic bodyB (child) below it : btTransform tr; tr.setIdentity(); tr.setOrigin(wheelPos[i]); - + btRigidBody* pBodyB = createRigidBody(10.0, tr, m_wheelShape); pBodyB->setFriction(1110); pBodyB->setActivationState(DISABLE_DEACTIVATION); // add some data to build constraint frames - btVector3 parentAxis(0.f, 1.f, 0.f); - btVector3 childAxis(1.f, 0.f, 0.f); - btVector3 anchor = tr.getOrigin();//(0.f, 0.f, 0.f); + btVector3 parentAxis(0.f, 1.f, 0.f); + btVector3 childAxis(1.f, 0.f, 0.f); + btVector3 anchor = tr.getOrigin(); //(0.f, 0.f, 0.f); btHinge2Constraint* pHinge2 = new btHinge2Constraint(*pBodyA, *pBodyB, anchor, parentAxis, childAxis); - + //m_guiHelper->get2dCanvasInterface(); - pHinge2->setLowerLimit(-SIMD_HALF_PI * 0.5f); - pHinge2->setUpperLimit( SIMD_HALF_PI * 0.5f); + pHinge2->setUpperLimit(SIMD_HALF_PI * 0.5f); // add constraint to world m_dynamicsWorld->addConstraint(pHinge2, true); // draw constraint frames and limits for debugging { int motorAxis = 3; - pHinge2->enableMotor(motorAxis,true); - pHinge2->setMaxMotorForce(motorAxis,1000); - pHinge2->setTargetVelocity(motorAxis,-1); + pHinge2->enableMotor(motorAxis, true); + pHinge2->setMaxMotorForce(motorAxis, 1000); + pHinge2->setTargetVelocity(motorAxis, -1); } { int motorAxis = 5; - pHinge2->enableMotor(motorAxis,true); - pHinge2->setMaxMotorForce(motorAxis,1000); - pHinge2->setTargetVelocity(motorAxis,0); + pHinge2->enableMotor(motorAxis, true); + pHinge2->setMaxMotorForce(motorAxis, 1000); + pHinge2->setTargetVelocity(motorAxis, 0); } pHinge2->setDbgDrawSize(btScalar(5.f)); } - { - btCollisionShape* liftShape = new btBoxShape(btVector3(0.5f,2.0f,0.05f)); + btCollisionShape* liftShape = new btBoxShape(btVector3(0.5f, 2.0f, 0.05f)); m_collisionShapes.push_back(liftShape); btTransform liftTrans; m_liftStartPos = btVector3(0.0f, 2.5f, 3.05f); liftTrans.setIdentity(); liftTrans.setOrigin(m_liftStartPos); - m_liftBody = localCreateRigidBody(10,liftTrans, liftShape); + m_liftBody = localCreateRigidBody(10, liftTrans, liftShape); btTransform localA, localB; localA.setIdentity(); @@ -456,12 +421,12 @@ tr.setOrigin(btVector3(0,-3,0)); localA.setOrigin(btVector3(0.0, 1.0, 3.05)); localB.getBasis().setEulerZYX(0, M_PI_2, 0); localB.setOrigin(btVector3(0.0, -1.5, -0.05)); - m_liftHinge = new btHingeConstraint(*m_carChassis,*m_liftBody, localA, localB); -// m_liftHinge->setLimit(-LIFT_EPS, LIFT_EPS); + m_liftHinge = new btHingeConstraint(*m_carChassis, *m_liftBody, localA, localB); + // m_liftHinge->setLimit(-LIFT_EPS, LIFT_EPS); m_liftHinge->setLimit(0.0f, 0.0f); m_dynamicsWorld->addConstraint(m_liftHinge, true); - btCollisionShape* forkShapeA = new btBoxShape(btVector3(1.0f,0.1f,0.1f)); + btCollisionShape* forkShapeA = new btBoxShape(btVector3(1.0f, 0.1f, 0.1f)); m_collisionShapes.push_back(forkShapeA); btCompoundShape* forkCompound = new btCompoundShape(); m_collisionShapes.push_back(forkCompound); @@ -469,13 +434,13 @@ tr.setOrigin(btVector3(0,-3,0)); forkLocalTrans.setIdentity(); forkCompound->addChildShape(forkLocalTrans, forkShapeA); - btCollisionShape* forkShapeB = new btBoxShape(btVector3(0.1f,0.02f,0.6f)); + btCollisionShape* forkShapeB = new btBoxShape(btVector3(0.1f, 0.02f, 0.6f)); m_collisionShapes.push_back(forkShapeB); forkLocalTrans.setIdentity(); forkLocalTrans.setOrigin(btVector3(-0.9f, -0.08f, 0.7f)); forkCompound->addChildShape(forkLocalTrans, forkShapeB); - btCollisionShape* forkShapeC = new btBoxShape(btVector3(0.1f,0.02f,0.6f)); + btCollisionShape* forkShapeC = new btBoxShape(btVector3(0.1f, 0.02f, 0.6f)); m_collisionShapes.push_back(forkShapeC); forkLocalTrans.setIdentity(); forkLocalTrans.setOrigin(btVector3(0.9f, -0.08f, 0.7f)); @@ -496,26 +461,25 @@ tr.setOrigin(btVector3(0,-3,0)); m_forkSlider = new btSliderConstraint(*m_liftBody, *m_forkBody, localA, localB, true); m_forkSlider->setLowerLinLimit(0.1f); m_forkSlider->setUpperLinLimit(0.1f); -// m_forkSlider->setLowerAngLimit(-LIFT_EPS); -// m_forkSlider->setUpperAngLimit(LIFT_EPS); + // m_forkSlider->setLowerAngLimit(-LIFT_EPS); + // m_forkSlider->setUpperAngLimit(LIFT_EPS); m_forkSlider->setLowerAngLimit(0.0f); m_forkSlider->setUpperAngLimit(0.0f); m_dynamicsWorld->addConstraint(m_forkSlider, true); - btCompoundShape* loadCompound = new btCompoundShape(); m_collisionShapes.push_back(loadCompound); - btCollisionShape* loadShapeA = new btBoxShape(btVector3(2.0f,0.5f,0.5f)); + btCollisionShape* loadShapeA = new btBoxShape(btVector3(2.0f, 0.5f, 0.5f)); m_collisionShapes.push_back(loadShapeA); btTransform loadTrans; loadTrans.setIdentity(); loadCompound->addChildShape(loadTrans, loadShapeA); - btCollisionShape* loadShapeB = new btBoxShape(btVector3(0.1f,1.0f,1.0f)); + btCollisionShape* loadShapeB = new btBoxShape(btVector3(0.1f, 1.0f, 1.0f)); m_collisionShapes.push_back(loadShapeB); loadTrans.setIdentity(); loadTrans.setOrigin(btVector3(2.1f, 0.0f, 0.0f)); loadCompound->addChildShape(loadTrans, loadShapeB); - btCollisionShape* loadShapeC = new btBoxShape(btVector3(0.1f,1.0f,1.0f)); + btCollisionShape* loadShapeC = new btBoxShape(btVector3(0.1f, 1.0f, 1.0f)); m_collisionShapes.push_back(loadShapeC); loadTrans.setIdentity(); loadTrans.setOrigin(btVector3(-2.1f, 0.0f, 0.0f)); @@ -523,15 +487,12 @@ tr.setOrigin(btVector3(0,-3,0)); loadTrans.setIdentity(); m_loadStartPos = btVector3(0.0f, 3.5f, 7.0f); loadTrans.setOrigin(m_loadStartPos); - m_loadBody = localCreateRigidBody(loadMass, loadTrans, loadCompound); + m_loadBody = localCreateRigidBody(loadMass, loadTrans, loadCompound); } - - - resetForklift(); - -// setCameraDistance(26.f); + + // setCameraDistance(26.f); m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } @@ -565,16 +526,13 @@ void Hinge2Vehicle::renderScene() } } #endif - + m_guiHelper->render(m_dynamicsWorld); - btVector3 wheelColor(1,0,0); - - btVector3 worldBoundsMin,worldBoundsMax; - getDynamicsWorld()->getBroadphase()->getBroadphaseAabb(worldBoundsMin,worldBoundsMax); - - + btVector3 wheelColor(1, 0, 0); + btVector3 worldBoundsMin, worldBoundsMax; + getDynamicsWorld()->getBroadphase()->getBroadphaseAabb(worldBoundsMin, worldBoundsMax); #if 0 int lineWidth=400; @@ -638,8 +596,7 @@ void Hinge2Vehicle::renderScene() void Hinge2Vehicle::stepSimulation(float deltaTime) { - - //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); #if 0 { @@ -660,70 +617,62 @@ void Hinge2Vehicle::stepSimulation(float deltaTime) #endif float dt = deltaTime; - + if (m_dynamicsWorld) { //during idle mode, just run 1 simulation step maximum - int maxSimSubSteps = 2; - - int numSimSteps; - numSimSteps = m_dynamicsWorld->stepSimulation(dt,maxSimSubSteps); + int maxSimSubSteps = 2; - if (m_dynamicsWorld->getConstraintSolver()->getSolverType()==BT_MLCP_SOLVER) + int numSimSteps; + numSimSteps = m_dynamicsWorld->stepSimulation(dt, maxSimSubSteps); + + if (m_dynamicsWorld->getConstraintSolver()->getSolverType() == BT_MLCP_SOLVER) { - btMLCPSolver* sol = (btMLCPSolver*) m_dynamicsWorld->getConstraintSolver(); + btMLCPSolver* sol = (btMLCPSolver*)m_dynamicsWorld->getConstraintSolver(); int numFallbacks = sol->getNumFallbacks(); if (numFallbacks) { static int totalFailures = 0; - totalFailures+=numFallbacks; - printf("MLCP solver failed %d times, falling back to btSequentialImpulseSolver (SI)\n",totalFailures); + totalFailures += numFallbacks; + printf("MLCP solver failed %d times, falling back to btSequentialImpulseSolver (SI)\n", totalFailures); } sol->setNumFallbacks(0); } - //#define VERBOSE_FEEDBACK #ifdef VERBOSE_FEEDBACK - if (!numSimSteps) + if (!numSimSteps) printf("Interpolated transforms\n"); else { if (numSimSteps > maxSimSubSteps) { //detect dropping frames - printf("Dropped (%i) simulation steps out of %i\n",numSimSteps - maxSimSubSteps,numSimSteps); - } else + printf("Dropped (%i) simulation steps out of %i\n", numSimSteps - maxSimSubSteps, numSimSteps); + } + else { - printf("Simulated (%i) steps\n",numSimSteps); + printf("Simulated (%i) steps\n", numSimSteps); } } -#endif //VERBOSE_FEEDBACK - +#endif //VERBOSE_FEEDBACK } - - - - } - - -void Hinge2Vehicle::displayCallback(void) +void Hinge2Vehicle::displayCallback(void) { -// glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //renderme(); -//optional but useful: debug drawing + //optional but useful: debug drawing if (m_dynamicsWorld) m_dynamicsWorld->debugDrawWorld(); -// glFlush(); -// glutSwapBuffers(); + // glFlush(); + // glutSwapBuffers(); } - void Hinge2Vehicle::clientResetScene() { exitPhysics(); @@ -737,9 +686,9 @@ void Hinge2Vehicle::resetForklift() gEngineForce = 0.f; m_carChassis->setCenterOfMassTransform(btTransform::getIdentity()); - m_carChassis->setLinearVelocity(btVector3(0,0,0)); - m_carChassis->setAngularVelocity(btVector3(0,0,0)); - m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(m_carChassis->getBroadphaseHandle(),getDynamicsWorld()->getDispatcher()); + m_carChassis->setLinearVelocity(btVector3(0, 0, 0)); + m_carChassis->setAngularVelocity(btVector3(0, 0, 0)); + m_dynamicsWorld->getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(m_carChassis->getBroadphaseHandle(), getDynamicsWorld()->getDispatcher()); #if 0 if (m_vehicle) { @@ -756,22 +705,21 @@ void Hinge2Vehicle::resetForklift() liftTrans.setOrigin(m_liftStartPos); m_liftBody->activate(); m_liftBody->setCenterOfMassTransform(liftTrans); - m_liftBody->setLinearVelocity(btVector3(0,0,0)); - m_liftBody->setAngularVelocity(btVector3(0,0,0)); + m_liftBody->setLinearVelocity(btVector3(0, 0, 0)); + m_liftBody->setAngularVelocity(btVector3(0, 0, 0)); btTransform forkTrans; forkTrans.setIdentity(); forkTrans.setOrigin(m_forkStartPos); m_forkBody->activate(); m_forkBody->setCenterOfMassTransform(forkTrans); - m_forkBody->setLinearVelocity(btVector3(0,0,0)); - m_forkBody->setAngularVelocity(btVector3(0,0,0)); + m_forkBody->setLinearVelocity(btVector3(0, 0, 0)); + m_forkBody->setAngularVelocity(btVector3(0, 0, 0)); -// m_liftHinge->setLimit(-LIFT_EPS, LIFT_EPS); + // m_liftHinge->setLimit(-LIFT_EPS, LIFT_EPS); m_liftHinge->setLimit(0.0f, 0.0f); m_liftHinge->enableAngularMotor(false, 0, 0); - m_forkSlider->setLowerLinLimit(0.1f); m_forkSlider->setUpperLinLimit(0.1f); m_forkSlider->setPoweredLinMotor(false); @@ -781,40 +729,36 @@ void Hinge2Vehicle::resetForklift() loadTrans.setOrigin(m_loadStartPos); m_loadBody->activate(); m_loadBody->setCenterOfMassTransform(loadTrans); - m_loadBody->setLinearVelocity(btVector3(0,0,0)); - m_loadBody->setAngularVelocity(btVector3(0,0,0)); - + m_loadBody->setLinearVelocity(btVector3(0, 0, 0)); + m_loadBody->setAngularVelocity(btVector3(0, 0, 0)); } - -bool Hinge2Vehicle::keyboardCallback(int key, int state) +bool Hinge2Vehicle::keyboardCallback(int key, int state) { bool handled = false; bool isShiftPressed = m_guiHelper->getAppInterface()->m_window->isModifierKeyPressed(B3G_SHIFT); if (state) { - if (isShiftPressed) - { - switch (key) + if (isShiftPressed) + { + switch (key) { - case B3G_LEFT_ARROW : + case B3G_LEFT_ARROW: { - - m_liftHinge->setLimit(-M_PI/16.0f, M_PI/8.0f); + m_liftHinge->setLimit(-M_PI / 16.0f, M_PI / 8.0f); m_liftHinge->enableAngularMotor(true, -0.1, maxMotorImpulse); handled = true; break; } - case B3G_RIGHT_ARROW : + case B3G_RIGHT_ARROW: { - - m_liftHinge->setLimit(-M_PI/16.0f, M_PI/8.0f); + m_liftHinge->setLimit(-M_PI / 16.0f, M_PI / 8.0f); m_liftHinge->enableAngularMotor(true, 0.1, maxMotorImpulse); handled = true; break; } - case B3G_UP_ARROW : + case B3G_UP_ARROW: { m_forkSlider->setLowerLinLimit(0.1f); m_forkSlider->setUpperLinLimit(3.9f); @@ -824,7 +768,7 @@ bool Hinge2Vehicle::keyboardCallback(int key, int state) handled = true; break; } - case B3G_DOWN_ARROW : + case B3G_DOWN_ARROW: { m_forkSlider->setLowerLinLimit(0.1f); m_forkSlider->setUpperLinLimit(3.9f); @@ -835,37 +779,37 @@ bool Hinge2Vehicle::keyboardCallback(int key, int state) break; } } - - } else - { - switch (key) + } + else + { + switch (key) { - case B3G_LEFT_ARROW : + case B3G_LEFT_ARROW: { handled = true; gVehicleSteering += steeringIncrement; - if ( gVehicleSteering > steeringClamp) + if (gVehicleSteering > steeringClamp) gVehicleSteering = steeringClamp; break; } - case B3G_RIGHT_ARROW : + case B3G_RIGHT_ARROW: { handled = true; gVehicleSteering -= steeringIncrement; - if ( gVehicleSteering < -steeringClamp) + if (gVehicleSteering < -steeringClamp) gVehicleSteering = -steeringClamp; break; } - case B3G_UP_ARROW : + case B3G_UP_ARROW: { handled = true; gEngineForce = maxEngineForce; gBreakingForce = 0.f; break; } - case B3G_DOWN_ARROW : + case B3G_DOWN_ARROW: { handled = true; gEngineForce = -maxEngineForce; @@ -873,7 +817,7 @@ bool Hinge2Vehicle::keyboardCallback(int key, int state) break; } - case B3G_F7: + case B3G_F7: { handled = true; btDiscreteDynamicsWorld* world = (btDiscreteDynamicsWorld*)m_dynamicsWorld; @@ -881,7 +825,7 @@ bool Hinge2Vehicle::keyboardCallback(int key, int state) printf("world latencyMotionStateInterpolation = %d\n", world->getLatencyMotionStateInterpolation()); break; } - case B3G_F6: + case B3G_F6: { handled = true; //switch solver (needs demo restart) @@ -895,58 +839,58 @@ bool Hinge2Vehicle::keyboardCallback(int key, int state) //btSolveProjectedGaussSeidel* mlcp = new btSolveProjectedGaussSeidel; btMLCPSolver* sol = new btMLCPSolver(mlcp); m_solver = sol; - } else + } + else { m_solver = new btSequentialImpulseConstraintSolver(); } m_dynamicsWorld->setConstraintSolver(m_solver); - //exitPhysics(); //initPhysics(); break; } - case B3G_F5: - handled = true; - m_useDefaultCamera = !m_useDefaultCamera; - break; - default: - break; + case B3G_F5: + handled = true; + m_useDefaultCamera = !m_useDefaultCamera; + break; + default: + break; } + } } - - } else + else { - switch (key) + switch (key) { - case B3G_UP_ARROW: - { - lockForkSlider(); - gEngineForce = 0.f; - gBreakingForce = defaultBreakingForce; - handled=true; - break; - } - case B3G_DOWN_ARROW: + case B3G_UP_ARROW: { lockForkSlider(); gEngineForce = 0.f; gBreakingForce = defaultBreakingForce; - handled=true; - break; - } - case B3G_LEFT_ARROW: - case B3G_RIGHT_ARROW: - { - lockLiftHinge(); - handled=true; + handled = true; break; } - default: - - break; + case B3G_DOWN_ARROW: + { + lockForkSlider(); + gEngineForce = 0.f; + gBreakingForce = defaultBreakingForce; + handled = true; + break; + } + case B3G_LEFT_ARROW: + case B3G_RIGHT_ARROW: + { + lockLiftHinge(); + handled = true; + break; + } + default: + + break; } } return handled; @@ -955,11 +899,10 @@ bool Hinge2Vehicle::keyboardCallback(int key, int state) void Hinge2Vehicle::specialKeyboardUp(int key, int x, int y) { #if 0 - + #endif } - void Hinge2Vehicle::specialKeyboard(int key, int x, int y) { #if 0 @@ -1092,30 +1035,29 @@ void Hinge2Vehicle::specialKeyboard(int key, int x, int y) #endif } - void Hinge2Vehicle::lockLiftHinge(void) { btScalar hingeAngle = m_liftHinge->getHingeAngle(); btScalar lowLim = m_liftHinge->getLowerLimit(); btScalar hiLim = m_liftHinge->getUpperLimit(); m_liftHinge->enableAngularMotor(false, 0, 0); - if(hingeAngle < lowLim) + if (hingeAngle < lowLim) { -// m_liftHinge->setLimit(lowLim, lowLim + LIFT_EPS); + // m_liftHinge->setLimit(lowLim, lowLim + LIFT_EPS); m_liftHinge->setLimit(lowLim, lowLim); } - else if(hingeAngle > hiLim) + else if (hingeAngle > hiLim) { -// m_liftHinge->setLimit(hiLim - LIFT_EPS, hiLim); + // m_liftHinge->setLimit(hiLim - LIFT_EPS, hiLim); m_liftHinge->setLimit(hiLim, hiLim); } else { -// m_liftHinge->setLimit(hingeAngle - LIFT_EPS, hingeAngle + LIFT_EPS); + // m_liftHinge->setLimit(hingeAngle - LIFT_EPS, hingeAngle + LIFT_EPS); m_liftHinge->setLimit(hingeAngle, hingeAngle); } return; -} // Hinge2Vehicle::lockLiftHinge() +} // Hinge2Vehicle::lockLiftHinge() void Hinge2Vehicle::lockForkSlider(void) { @@ -1123,12 +1065,12 @@ void Hinge2Vehicle::lockForkSlider(void) btScalar lowLim = m_forkSlider->getLowerLinLimit(); btScalar hiLim = m_forkSlider->getUpperLinLimit(); m_forkSlider->setPoweredLinMotor(false); - if(linDepth <= lowLim) + if (linDepth <= lowLim) { m_forkSlider->setLowerLinLimit(lowLim); m_forkSlider->setUpperLinLimit(lowLim); } - else if(linDepth > hiLim) + else if (linDepth > hiLim) { m_forkSlider->setLowerLinLimit(hiLim); m_forkSlider->setUpperLinLimit(hiLim); @@ -1139,7 +1081,7 @@ void Hinge2Vehicle::lockForkSlider(void) m_forkSlider->setUpperLinLimit(linDepth); } return; -} // Hinge2Vehicle::lockForkSlider() +} // Hinge2Vehicle::lockForkSlider() btRigidBody* Hinge2Vehicle::localCreateRigidBody(btScalar mass, const btTransform& startTransform, btCollisionShape* shape) { @@ -1148,31 +1090,31 @@ btRigidBody* Hinge2Vehicle::localCreateRigidBody(btScalar mass, const btTransfor //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); - btVector3 localInertia(0,0,0); + btVector3 localInertia(0, 0, 0); if (isDynamic) - shape->calculateLocalInertia(mass,localInertia); + shape->calculateLocalInertia(mass, localInertia); - //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects + //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects #define USE_MOTIONSTATE 1 #ifdef USE_MOTIONSTATE btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); - btRigidBody::btRigidBodyConstructionInfo cInfo(mass,myMotionState,shape,localInertia); + btRigidBody::btRigidBodyConstructionInfo cInfo(mass, myMotionState, shape, localInertia); btRigidBody* body = new btRigidBody(cInfo); //body->setContactProcessingThreshold(m_defaultContactProcessingThreshold); #else - btRigidBody* body = new btRigidBody(mass,0,shape,localInertia); + btRigidBody* body = new btRigidBody(mass, 0, shape, localInertia); body->setWorldTransform(startTransform); -#endif// +#endif // m_dynamicsWorld->addRigidBody(body); return body; } -CommonExampleInterface* Hinge2VehicleCreateFunc(struct CommonExampleOptions& options) +CommonExampleInterface* Hinge2VehicleCreateFunc(struct CommonExampleOptions& options) { return new Hinge2Vehicle(options.m_guiHelper); } diff --git a/examples/Vehicles/Hinge2Vehicle.h b/examples/Vehicles/Hinge2Vehicle.h index 02af743bd..d4ac4bc33 100644 --- a/examples/Vehicles/Hinge2Vehicle.h +++ b/examples/Vehicles/Hinge2Vehicle.h @@ -16,8 +16,6 @@ subject to the following restrictions: #ifndef HINGE2_VEHICLE_H #define HINGE2_VEHICLE_H -class CommonExampleInterface* Hinge2VehicleCreateFunc(struct CommonExampleOptions& options); - -#endif // HINGE2_VEHICLE_H - +class CommonExampleInterface* Hinge2VehicleCreateFunc(struct CommonExampleOptions& options); +#endif // HINGE2_VEHICLE_H diff --git a/examples/VoronoiFracture/VoronoiFractureDemo.cpp b/examples/VoronoiFracture/VoronoiFractureDemo.cpp index 5e7212919..bbc79b248 100644 --- a/examples/VoronoiFracture/VoronoiFractureDemo.cpp +++ b/examples/VoronoiFracture/VoronoiFractureDemo.cpp @@ -33,14 +33,12 @@ static int useMpr = 0; ///btBulletDynamicsCommon.h is the main Bullet include file, contains most common include files. #include "btBulletDynamicsCommon.h" -#include //printf debugging - +#include //printf debugging static bool useGenericConstraint = false; #include "btConvexConvexMprAlgorithm.h" - #include "LinearMath/btAlignedObjectArray.h" #include "LinearMath/btConvexHullComputer.h" #include "LinearMath/btQuaternion.h" @@ -57,38 +55,35 @@ class btDefaultCollisionConfiguration; #include "../CommonInterfaces/CommonRigidBodyBase.h" - class VoronoiFractureDemo : public CommonRigidBodyBase { //keep the collision shapes, for deletion/cleanup - btAlignedObjectArray m_collisionShapes; + btAlignedObjectArray m_collisionShapes; - btBroadphaseInterface* m_broadphase; + btBroadphaseInterface* m_broadphase; - btCollisionDispatcher* m_dispatcher; + btCollisionDispatcher* m_dispatcher; - btConstraintSolver* m_solver; + btConstraintSolver* m_solver; btDefaultCollisionConfiguration* m_collisionConfiguration; btClock m_perfmTimer; - public: - +public: VoronoiFractureDemo(struct GUIHelperInterface* helper) - :CommonRigidBodyBase(helper) + : CommonRigidBodyBase(helper) { - srand((unsigned)time(NULL)); // Seed it... + srand((unsigned)time(NULL)); // Seed it... } virtual ~VoronoiFractureDemo() { - btAssert(m_dynamicsWorld==0); + btAssert(m_dynamicsWorld == 0); } + void initPhysics(); - void initPhysics(); - - void exitPhysics(); + void exitPhysics(); //virtual void renderme(); @@ -100,7 +95,7 @@ class VoronoiFractureDemo : public CommonRigidBodyBase //virtual void displayCallback(); //virtual void clientResetScene(); - + //virtual void keyboardCallback(unsigned char key, int x, int y); void attachFixedConstraints(); @@ -110,11 +105,9 @@ class VoronoiFractureDemo : public CommonRigidBodyBase float dist = 18; float pitch = -30; float yaw = 129; - float targetPos[3]={-1.5,4.7,-2}; - m_guiHelper->resetCamera(dist,yaw,pitch,targetPos[0],targetPos[1],targetPos[2]); + float targetPos[3] = {-1.5, 4.7, -2}; + m_guiHelper->resetCamera(dist, yaw, pitch, targetPos[0], targetPos[1], targetPos[2]); } - - }; void VoronoiFractureDemo::attachFixedConstraints() @@ -123,7 +116,7 @@ void VoronoiFractureDemo::attachFixedConstraints() int numManifolds = m_dynamicsWorld->getDispatcher()->getNumManifolds(); - for (int i=0;igetDispatcher()->getManifoldByIndexInternal(i); if (!manifold->getNumContacts()) @@ -131,26 +124,26 @@ void VoronoiFractureDemo::attachFixedConstraints() btScalar minDist = 1e30f; int minIndex = -1; - for (int v=0;vgetNumContacts();v++) + for (int v = 0; v < manifold->getNumContacts(); v++) { - if (minDist >manifold->getContactPoint(v).getDistance()) + if (minDist > manifold->getContactPoint(v).getDistance()) { minDist = manifold->getContactPoint(v).getDistance(); minIndex = v; } } - if (minDist>0.) + if (minDist > 0.) continue; - + btCollisionObject* colObj0 = (btCollisionObject*)manifold->getBody0(); btCollisionObject* colObj1 = (btCollisionObject*)manifold->getBody1(); - // int tag0 = (colObj0)->getIslandTag(); -// int tag1 = (colObj1)->getIslandTag(); + // int tag0 = (colObj0)->getIslandTag(); + // int tag1 = (colObj1)->getIslandTag(); btRigidBody* body0 = btRigidBody::upcast(colObj0); btRigidBody* body1 = btRigidBody::upcast(colObj1); - if (bodies.findLinearSearch(body0)==bodies.size()) + if (bodies.findLinearSearch(body0) == bodies.size()) bodies.push_back(body0); - if (bodies.findLinearSearch(body1)==bodies.size()) + if (bodies.findLinearSearch(body1) == bodies.size()) bodies.push_back(body1); if (body0 && body1) @@ -160,7 +153,7 @@ void VoronoiFractureDemo::attachFixedConstraints() if (body0->checkCollideWithOverride(body1)) { { - btTransform trA,trB; + btTransform trA, trB; trA.setIdentity(); trB.setIdentity(); btVector3 contactPosWorld = manifold->getContactPoint(minIndex).m_positionWorldOnA; @@ -168,40 +161,35 @@ void VoronoiFractureDemo::attachFixedConstraints() globalFrame.setIdentity(); globalFrame.setOrigin(contactPosWorld); - trA = body0->getWorldTransform().inverse()*globalFrame; - trB = body1->getWorldTransform().inverse()*globalFrame; - float totalMass = 1.f/body0->getInvMass() + 1.f/body1->getInvMass(); + trA = body0->getWorldTransform().inverse() * globalFrame; + trB = body1->getWorldTransform().inverse() * globalFrame; + float totalMass = 1.f / body0->getInvMass() + 1.f / body1->getInvMass(); - if (useGenericConstraint) { - btGeneric6DofConstraint* dof6 = new btGeneric6DofConstraint(*body0,*body1,trA,trB,true); + btGeneric6DofConstraint* dof6 = new btGeneric6DofConstraint(*body0, *body1, trA, trB, true); dof6->setOverrideNumSolverIterations(30); + dof6->setBreakingImpulseThreshold(BREAKING_THRESHOLD * totalMass); - dof6->setBreakingImpulseThreshold(BREAKING_THRESHOLD*totalMass); - - for (int i=0;i<6;i++) - dof6->setLimit(i,0,0); - m_dynamicsWorld->addConstraint(dof6,true); - - } else - { - btFixedConstraint* fixed = new btFixedConstraint(*body0,*body1,trA,trB); - fixed->setBreakingImpulseThreshold(BREAKING_THRESHOLD*totalMass); - fixed ->setOverrideNumSolverIterations(30); - m_dynamicsWorld->addConstraint(fixed,true); - + for (int i = 0; i < 6; i++) + dof6->setLimit(i, 0, 0); + m_dynamicsWorld->addConstraint(dof6, true); + } + else + { + btFixedConstraint* fixed = new btFixedConstraint(*body0, *body1, trA, trB); + fixed->setBreakingImpulseThreshold(BREAKING_THRESHOLD * totalMass); + fixed->setOverrideNumSolverIterations(30); + m_dynamicsWorld->addConstraint(fixed, true); } - } } } } - - } + } - for (int i=0;iremoveRigidBody(bodies[i]); m_dynamicsWorld->addRigidBody(bodies[i]); @@ -227,30 +215,30 @@ void VoronoiFractureDemo::getVerticesInsidePlanes(const btAlignedObjectArray btScalar(0.0001)) { - for (k=j+1;k btScalar(0.0001)) && (n3n1.length2() > btScalar(0.0001) )) + if ((n2n3.length2() > btScalar(0.0001)) && (n3n1.length2() > btScalar(0.0001))) { btScalar quotient = (N1.dot(n2n3)); if (btFabs(quotient) > btScalar(0.0001)) { btVector3 potentialVertex = (n2n3 * N1[3] + n3n1 * N2[3] + n1n2 * N3[3]) * (btScalar(-1.) / quotient); - for (l=0; l btScalar(0.000001)) + if (btScalar(NP.dot(potentialVertex)) + btScalar(NP[3]) > btScalar(0.000001)) break; } if (l == numPlanes) @@ -269,14 +257,14 @@ void VoronoiFractureDemo::getVerticesInsidePlanes(const btAlignedObjectArray& points, const btVector3& bbmin, const btVector3& bbmax, const btQuaternion& bbq, const btVector3& bbt, btScalar matDensity) { +void VoronoiFractureDemo::voronoiBBShatter(const btAlignedObjectArray& points, const btVector3& bbmin, const btVector3& bbmax, const btQuaternion& bbq, const btVector3& bbt, btScalar matDensity) +{ // points define voronoi cells in world space (avoid duplicates) // bbmin & bbmax = bounding box min and max in local space // bbq & bbt = bounding box quaternion rotation and translation @@ -308,21 +297,29 @@ void VoronoiFractureDemo::voronoiBBShatter(const btAlignedObjectArray int i, j, k; int numpoints = points.size(); - for (i=0; i < numpoints ;i++) { + for (i = 0; i < numpoints; i++) + { curVoronoiPoint = points[i]; btVector3 icp = quatRotate(bbiq, curVoronoiPoint - bbt); rbb = icp - bbmax; nrbb = bbmin - icp; planes.resize(6); - planes[0] = bbvx; planes[0][3] = rbb.x(); - planes[1] = bbvy; planes[1][3] = rbb.y(); - planes[2] = bbvz; planes[2][3] = rbb.z(); - planes[3] = -bbvx; planes[3][3] = nrbb.x(); - planes[4] = -bbvy; planes[4][3] = nrbb.y(); - planes[5] = -bbvz; planes[5][3] = nrbb.z(); + planes[0] = bbvx; + planes[0][3] = rbb.x(); + planes[1] = bbvy; + planes[1][3] = rbb.y(); + planes[2] = bbvz; + planes[2][3] = rbb.z(); + planes[3] = -bbvx; + planes[3][3] = nrbb.x(); + planes[4] = -bbvy; + planes[4][3] = nrbb.y(); + planes[5] = -bbvz; + planes[5][3] = nrbb.z(); maxDistance = SIMD_INFINITY; sortedVoronoiPoints.heapSort(pointCmp()); - for (j=1; j < numpoints; j++) { + for (j = 1; j < numpoints; j++) + { normal = sortedVoronoiPoints[j] - curVoronoiPoint; nlength = normal.length(); if (nlength > maxDistance) @@ -334,9 +331,11 @@ void VoronoiFractureDemo::voronoiBBShatter(const btAlignedObjectArray if (vertices.size() == 0) break; numplaneIndices = planeIndices.size(); - if (numplaneIndices != planes.size()) { + if (numplaneIndices != planes.size()) + { planeIndicesIter = planeIndices.begin(); - for (k=0; k < numplaneIndices; k++) { + for (k = 0; k < numplaneIndices; k++) + { if (k != *planeIndicesIter) planes[k] = planes[*planeIndicesIter]; planeIndicesIter++; @@ -344,7 +343,8 @@ void VoronoiFractureDemo::voronoiBBShatter(const btAlignedObjectArray planes.resize(numplaneIndices); } maxDistance = vertices[0].length(); - for (k=1; k < vertices.size(); k++) { + for (k = 1; k < vertices.size(); k++) + { distance = vertices[k].length(); if (maxDistance < distance) maxDistance = distance; @@ -355,22 +355,24 @@ void VoronoiFractureDemo::voronoiBBShatter(const btAlignedObjectArray continue; // Clean-up voronoi convex shard vertices and generate edges & faces - convexHC->compute(&vertices[0].getX(), sizeof(btVector3), vertices.size(),CONVEX_MARGIN,0.0); + convexHC->compute(&vertices[0].getX(), sizeof(btVector3), vertices.size(), CONVEX_MARGIN, 0.0); // At this point we have a complete 3D voronoi shard mesh contained in convexHC // Calculate volume and center of mass (Stan Melax volume integration) int numFaces = convexHC->faces.size(); - int v0, v1, v2; // Triangle vertices + int v0, v1, v2; // Triangle vertices btScalar volume = btScalar(0.); btVector3 com(0., 0., 0.); - for (j=0; j < numFaces; j++) { + for (j = 0; j < numFaces; j++) + { const btConvexHullComputer::Edge* edge = &convexHC->edges[convexHC->faces[j]]; v0 = edge->getSourceVertex(); v1 = edge->getTargetVertex(); edge = edge->getNextEdgeOfFace(); v2 = edge->getTargetVertex(); - while (v2 != v0) { + while (v2 != v0) + { // Counter-clockwise triangulated voronoi shard mesh faces (v0-v1-v2) and edges here... btScalar vol = convexHC->vertices[v0].triple(convexHC->vertices[v1], convexHC->vertices[v2]); volume += vol; @@ -385,7 +387,7 @@ void VoronoiFractureDemo::voronoiBBShatter(const btAlignedObjectArray // Shift all vertices relative to center of mass int numVerts = convexHC->vertices.size(); - for (j=0; j < numVerts; j++) + for (j = 0; j < numVerts; j++) { convexHC->vertices[j] -= com; } @@ -397,26 +399,26 @@ void VoronoiFractureDemo::voronoiBBShatter(const btAlignedObjectArray // Create Bullet Physics rigid body shards btCollisionShape* shardShape = new btConvexHullShape(&(convexHC->vertices[0].getX()), convexHC->vertices.size()); - shardShape->setMargin(CONVEX_MARGIN); // for this demo; note convexHC has optional margin parameter for this + shardShape->setMargin(CONVEX_MARGIN); // for this demo; note convexHC has optional margin parameter for this m_collisionShapes.push_back(shardShape); btTransform shardTransform; shardTransform.setIdentity(); - shardTransform.setOrigin(curVoronoiPoint + com); // Shard's adjusted location + shardTransform.setOrigin(curVoronoiPoint + com); // Shard's adjusted location btDefaultMotionState* shardMotionState = new btDefaultMotionState(shardTransform); btScalar shardMass(volume * matDensity); - btVector3 shardInertia(0.,0.,0.); + btVector3 shardInertia(0., 0., 0.); shardShape->calculateLocalInertia(shardMass, shardInertia); btRigidBody::btRigidBodyConstructionInfo shardRBInfo(shardMass, shardMotionState, shardShape, shardInertia); btRigidBody* shardBody = new btRigidBody(shardRBInfo); m_dynamicsWorld->addRigidBody(shardBody); - cellnum ++; - + cellnum++; } printf("Generated %d voronoi btRigidBody shards\n", cellnum); } -void VoronoiFractureDemo::voronoiConvexHullShatter(const btAlignedObjectArray& points, const btAlignedObjectArray& verts, const btQuaternion& bbq, const btVector3& bbt, btScalar matDensity) { +void VoronoiFractureDemo::voronoiConvexHullShatter(const btAlignedObjectArray& points, const btAlignedObjectArray& verts, const btQuaternion& bbq, const btVector3& bbt, btScalar matDensity) +{ // points define voronoi cells in world space (avoid duplicates) // verts = source (convex hull) mesh vertices in local space // bbq & bbt = source (convex hull) mesh quaternion rotation and translation @@ -438,36 +440,41 @@ void VoronoiFractureDemo::voronoiConvexHullShatter(const btAlignedObjectArraycompute(&chverts[0].getX(), sizeof(btVector3), numverts, 0.0, 0.0); int numFaces = convexHC->faces.size(); - int v0, v1, v2; // vertices - for (i=0; i < numFaces; i++) { + int v0, v1, v2; // vertices + for (i = 0; i < numFaces; i++) + { const btConvexHullComputer::Edge* edge = &convexHC->edges[convexHC->faces[i]]; v0 = edge->getSourceVertex(); v1 = edge->getTargetVertex(); edge = edge->getNextEdgeOfFace(); v2 = edge->getTargetVertex(); - plane = (convexHC->vertices[v1]-convexHC->vertices[v0]).cross(convexHC->vertices[v2]-convexHC->vertices[v0]).normalize(); + plane = (convexHC->vertices[v1] - convexHC->vertices[v0]).cross(convexHC->vertices[v2] - convexHC->vertices[v0]).normalize(); plane[3] = -plane.dot(convexHC->vertices[v0]); convexPlanes.push_back(plane); } const int numconvexPlanes = convexPlanes.size(); int numpoints = points.size(); - for (i=0; i < numpoints ;i++) { + for (i = 0; i < numpoints; i++) + { curVoronoiPoint = points[i]; planes.copyFromArray(convexPlanes); - for (j=0; j < numconvexPlanes ;j++) { + for (j = 0; j < numconvexPlanes; j++) + { planes[j][3] += planes[j].dot(curVoronoiPoint); } maxDistance = SIMD_INFINITY; sortedVoronoiPoints.heapSort(pointCmp()); - for (j=1; j < numpoints; j++) { + for (j = 1; j < numpoints; j++) + { normal = sortedVoronoiPoints[j] - curVoronoiPoint; nlength = normal.length(); if (nlength > maxDistance) @@ -479,9 +486,11 @@ void VoronoiFractureDemo::voronoiConvexHullShatter(const btAlignedObjectArraycompute(&vertices[0].getX(), sizeof(btVector3), vertices.size(),0.0,0.0); + convexHC->compute(&vertices[0].getX(), sizeof(btVector3), vertices.size(), 0.0, 0.0); // At this point we have a complete 3D voronoi shard mesh contained in convexHC @@ -508,13 +518,15 @@ void VoronoiFractureDemo::voronoiConvexHullShatter(const btAlignedObjectArrayfaces.size(); btScalar volume = btScalar(0.); btVector3 com(0., 0., 0.); - for (j=0; j < numFaces; j++) { + for (j = 0; j < numFaces; j++) + { const btConvexHullComputer::Edge* edge = &convexHC->edges[convexHC->faces[j]]; v0 = edge->getSourceVertex(); v1 = edge->getTargetVertex(); edge = edge->getNextEdgeOfFace(); v2 = edge->getTargetVertex(); - while (v2 != v0) { + while (v2 != v0) + { // Counter-clockwise triangulated voronoi shard mesh faces (v0-v1-v2) and edges here... btScalar vol = convexHC->vertices[v0].triple(convexHC->vertices[v1], convexHC->vertices[v2]); volume += vol; @@ -529,7 +541,7 @@ void VoronoiFractureDemo::voronoiConvexHullShatter(const btAlignedObjectArrayvertices.size(); - for (j=0; j < numVerts; j++) + for (j = 0; j < numVerts; j++) { convexHC->vertices[j] -= com; } @@ -541,21 +553,20 @@ void VoronoiFractureDemo::voronoiConvexHullShatter(const btAlignedObjectArrayvertices[0].getX()), convexHC->vertices.size()); - shardShape->setMargin(CONVEX_MARGIN); // for this demo; note convexHC has optional margin parameter for this + shardShape->setMargin(CONVEX_MARGIN); // for this demo; note convexHC has optional margin parameter for this m_collisionShapes.push_back(shardShape); btTransform shardTransform; shardTransform.setIdentity(); - shardTransform.setOrigin(curVoronoiPoint + com); // Shard's adjusted location + shardTransform.setOrigin(curVoronoiPoint + com); // Shard's adjusted location btDefaultMotionState* shardMotionState = new btDefaultMotionState(shardTransform); btScalar shardMass(volume * matDensity); - btVector3 shardInertia(0.,0.,0.); + btVector3 shardInertia(0., 0., 0.); shardShape->calculateLocalInertia(shardMass, shardInertia); btRigidBody::btRigidBodyConstructionInfo shardRBInfo(shardMass, shardMotionState, shardShape, shardInertia); btRigidBody* shardBody = new btRigidBody(shardRBInfo); m_dynamicsWorld->addRigidBody(shardBody); - cellnum ++; - + cellnum++; } printf("Generated %d voronoi btRigidBody shards\n", cellnum); } @@ -620,7 +631,7 @@ void VoronoiFractureDemo::renderme() } */ -void VoronoiFractureDemo::initPhysics() +void VoronoiFractureDemo::initPhysics() { m_guiHelper->setUpAxis(1); @@ -628,15 +639,13 @@ void VoronoiFractureDemo::initPhysics() useGenericConstraint = !useGenericConstraint; printf("useGenericConstraint = %d\n", useGenericConstraint); - - ///collision configuration contains default setup for memory, collision setup m_collisionConfiguration = new btDefaultCollisionConfiguration(); //m_collisionConfiguration->setConvexConvexMultipointIterations(); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) - m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); - + m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); + useMpr = 1 - useMpr; if (useMpr) @@ -651,30 +660,29 @@ void VoronoiFractureDemo::initPhysics() { printf("using default (GJK+EPA) convex-convex collision detection\n"); } - + m_broadphase = new btDbvtBroadphase(); ///the default constraint solver. For parallel processing you can use a different solver (see Extras/BulletMultiThreaded) btSequentialImpulseConstraintSolver* sol = new btSequentialImpulseConstraintSolver; m_solver = sol; - m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher,m_broadphase,m_solver,m_collisionConfiguration); + m_dynamicsWorld = new btDiscreteDynamicsWorld(m_dispatcher, m_broadphase, m_solver, m_collisionConfiguration); m_dynamicsWorld->getSolverInfo().m_splitImpulse = true; - + m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); - - m_dynamicsWorld->setGravity(btVector3(0,-10,0)); + m_dynamicsWorld->setGravity(btVector3(0, -10, 0)); ///create a few basic rigid bodies - btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.),btScalar(50.),btScalar(50.))); -// btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); - + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(50.), btScalar(50.), btScalar(50.))); + // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); + m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); - groundTransform.setOrigin(btVector3(0,-50,0)); + groundTransform.setOrigin(btVector3(0, -50, 0)); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: { @@ -683,13 +691,13 @@ void VoronoiFractureDemo::initPhysics() //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); - btVector3 localInertia(0,0,0); + btVector3 localInertia(0, 0, 0); if (isDynamic) - groundShape->calculateLocalInertia(mass,localInertia); + groundShape->calculateLocalInertia(mass, localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); - btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia); btRigidBody* body = new btRigidBody(rbInfo); //add the body to the dynamics world @@ -697,19 +705,19 @@ void VoronoiFractureDemo::initPhysics() } { - btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(10.),btScalar(8.),btScalar(1.))); + btCollisionShape* groundShape = new btBoxShape(btVector3(btScalar(10.), btScalar(8.), btScalar(1.))); btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); - btVector3 localInertia(0,0,0); + btVector3 localInertia(0, 0, 0); if (isDynamic) - groundShape->calculateLocalInertia(mass,localInertia); - groundTransform.setOrigin(btVector3(0,0,0)); + groundShape->calculateLocalInertia(mass, localInertia); + groundTransform.setOrigin(btVector3(0, 0, 0)); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); - btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); + btRigidBody::btRigidBodyConstructionInfo rbInfo(mass, myMotionState, groundShape, localInertia); btRigidBody* body = new btRigidBody(rbInfo); //add the body to the dynamics world @@ -719,36 +727,37 @@ void VoronoiFractureDemo::initPhysics() // ==> Voronoi Shatter Basic Demo: Random Cuboid // Random size cuboid (defined by bounding box max and min) - btVector3 bbmax(btScalar(rand() / btScalar(RAND_MAX)) * 12. +0.5, btScalar(rand() / btScalar(RAND_MAX)) * 1. +0.5, btScalar(rand() / btScalar(RAND_MAX)) * 1. +0.5); + btVector3 bbmax(btScalar(rand() / btScalar(RAND_MAX)) * 12. + 0.5, btScalar(rand() / btScalar(RAND_MAX)) * 1. + 0.5, btScalar(rand() / btScalar(RAND_MAX)) * 1. + 0.5); btVector3 bbmin = -bbmax; // Place it 10 units above ground - btVector3 bbt(0,15,0); + btVector3 bbt(0, 15, 0); // Use an arbitrary material density for shards (should be consitent/relative with/to rest of RBs in world) btScalar matDensity = 1; // Using random rotation - btQuaternion bbq(btScalar(rand() / btScalar(RAND_MAX)) * 2. -1.,btScalar(rand() / btScalar(RAND_MAX)) * 2. -1.,btScalar(rand() / btScalar(RAND_MAX)) * 2. -1.,btScalar(rand() / btScalar(RAND_MAX)) * 2. -1.); + btQuaternion bbq(btScalar(rand() / btScalar(RAND_MAX)) * 2. - 1., btScalar(rand() / btScalar(RAND_MAX)) * 2. - 1., btScalar(rand() / btScalar(RAND_MAX)) * 2. - 1., btScalar(rand() / btScalar(RAND_MAX)) * 2. - 1.); bbq.normalize(); // Generate random points for voronoi cells btAlignedObjectArray points; btVector3 point; btVector3 diff = bbmax - bbmin; - for (int i=0; i < VORONOIPOINTS; i++) { + for (int i = 0; i < VORONOIPOINTS; i++) + { // Place points within box area (points are in world coordinates) - point = quatRotate(bbq, btVector3(btScalar(rand() / btScalar(RAND_MAX)) * diff.x() -diff.x()/2., btScalar(rand() / btScalar(RAND_MAX)) * diff.y() -diff.y()/2., btScalar(rand() / btScalar(RAND_MAX)) * diff.z() -diff.z()/2.)) + bbt; + point = quatRotate(bbq, btVector3(btScalar(rand() / btScalar(RAND_MAX)) * diff.x() - diff.x() / 2., btScalar(rand() / btScalar(RAND_MAX)) * diff.y() - diff.y() / 2., btScalar(rand() / btScalar(RAND_MAX)) * diff.z() - diff.z() / 2.)) + bbt; points.push_back(point); } m_perfmTimer.reset(); voronoiBBShatter(points, bbmin, bbmax, bbq, bbt, matDensity); - printf("Total Time: %f seconds\n", m_perfmTimer.getTimeMilliseconds()/1000.); - - for (int i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + printf("Total Time: %f seconds\n", m_perfmTimer.getTimeMilliseconds() / 1000.); + + for (int i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--) { btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; - obj->getCollisionShape()->setMargin(CONVEX_MARGIN+0.01); + obj->getCollisionShape()->setMargin(CONVEX_MARGIN + 0.01); } m_dynamicsWorld->performDiscreteCollisionDetection(); - for (int i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + for (int i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--) { btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; obj->getCollisionShape()->setMargin(CONVEX_MARGIN); @@ -759,24 +768,22 @@ void VoronoiFractureDemo::initPhysics() m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); } - -void VoronoiFractureDemo::exitPhysics() +void VoronoiFractureDemo::exitPhysics() { - //cleanup in the reverse order of creation/initialization int i; //remove all constraints - for (i=m_dynamicsWorld->getNumConstraints()-1;i>=0;i--) + for (i = m_dynamicsWorld->getNumConstraints() - 1; i >= 0; i--) { btTypedConstraint* constraint = m_dynamicsWorld->getConstraint(i); m_dynamicsWorld->removeConstraint(constraint); delete constraint; } - + //remove the rigidbodies from the dynamics world and delete them - - for (i=m_dynamicsWorld->getNumCollisionObjects()-1; i>=0 ;i--) + + for (i = m_dynamicsWorld->getNumCollisionObjects() - 1; i >= 0; i--) { btCollisionObject* obj = m_dynamicsWorld->getCollisionObjectArray()[i]; btRigidBody* body = btRigidBody::upcast(obj); @@ -784,12 +791,12 @@ void VoronoiFractureDemo::exitPhysics() { delete body->getMotionState(); } - m_dynamicsWorld->removeCollisionObject( obj ); + m_dynamicsWorld->removeCollisionObject(obj); delete obj; } //delete collision shapes - for (int j=0;j @@ -24,8 +23,6 @@ subject to the following restrictions: #include "BulletCollision/CollisionShapes/btTriangleShape.h" - - #include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" @@ -37,8 +34,6 @@ subject to the following restrictions: #include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" #include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h" - - #include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" #include "BulletCollision/CollisionShapes/btSphereShape.h" @@ -58,25 +53,21 @@ bool gUseMprCollisionFunction = true; btConvexConvexMprAlgorithm::CreateFunc::CreateFunc() { - } -btConvexConvexMprAlgorithm::CreateFunc::~CreateFunc() -{ +btConvexConvexMprAlgorithm::CreateFunc::~CreateFunc() +{ } -btConvexConvexMprAlgorithm::btConvexConvexMprAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) -: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap), -m_ownManifold (false), -m_manifoldPtr(mf) +btConvexConvexMprAlgorithm::btConvexConvexMprAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) + : btActivatingCollisionAlgorithm(ci, body0Wrap, body1Wrap), + m_ownManifold(false), + m_manifoldPtr(mf) { (void)body0Wrap; (void)body1Wrap; } - - - btConvexConvexMprAlgorithm::~btConvexConvexMprAlgorithm() { if (m_ownManifold) @@ -86,24 +77,22 @@ btConvexConvexMprAlgorithm::~btConvexConvexMprAlgorithm() } } - btVector3 btBulletShapeSupportFunc(const void* shapeAptr, const btVector3& dir, bool includeMargin) { - btConvexShape* shape = (btConvexShape*) shapeAptr; + btConvexShape* shape = (btConvexShape*)shapeAptr; if (includeMargin) { return shape->localGetSupportingVertex(dir); } - + return shape->localGetSupportingVertexWithoutMargin(dir); } btVector3 btBulletShapeCenterFunc(const void* shapeAptr) { - return btVector3(0,0,0); + return btVector3(0, 0, 0); } - struct btMprConvexWrap { const btConvexShape* m_convex; @@ -132,46 +121,42 @@ struct btMprConvexWrap struct btMyDistanceInfo { - btVector3 m_pointOnA; - btVector3 m_pointOnB; - btVector3 m_normalBtoA; - btScalar m_distance; + btVector3 m_pointOnA; + btVector3 m_pointOnB; + btVector3 m_normalBtoA; + btScalar m_distance; }; // // Convex-Convex collision algorithm // -void btConvexConvexMprAlgorithm ::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +void btConvexConvexMprAlgorithm ::processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { - if (!m_manifoldPtr) { //swapped? - m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject()); + m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(), body1Wrap->getCollisionObject()); m_ownManifold = true; } resultOut->setPersistentManifold(m_manifoldPtr); //comment-out next line to test multi-contact generation //resultOut->getPersistentManifold()->clearManifold(); - const btConvexShape* min0 = static_cast(body0Wrap->getCollisionShape()); const btConvexShape* min1 = static_cast(body1Wrap->getCollisionShape()); - btVector3 normalOnB; - btVector3 pointOnBWorld; + btVector3 normalOnB; + btVector3 pointOnBWorld; btGjkPairDetector::ClosestPointInput input; btVoronoiSimplexSolver vs; btGjkEpaPenetrationDepthSolver epa; - - + if (gUseMprCollisionFunction) { - - btMprConvexWrap a,b; + btMprConvexWrap a, b; a.m_worldTrans = body0Wrap->getWorldTransform(); b.m_worldTrans = body1Wrap->getWorldTransform(); a.m_convex = (const btConvexShape*)body0Wrap->getCollisionShape(); @@ -180,17 +165,17 @@ void btConvexConvexMprAlgorithm ::processCollision (const btCollisionObjectWrapp simplexSolver.reset(); btGjkCollisionDescription colDesc; btMyDistanceInfo distInfo; - int res = btComputeGjkDistance(a,b,colDesc,&distInfo); - if (res==0) + int res = btComputeGjkDistance(a, b, colDesc, &distInfo); + if (res == 0) { - //printf("use GJK results in distance %f\n",distInfo.m_distance); - } else + //printf("use GJK results in distance %f\n",distInfo.m_distance); + } + else { btMprCollisionDescription mprDesc; - res = btComputeMprPenetration(a,b,mprDesc, &distInfo); + res = btComputeMprPenetration(a, b, mprDesc, &distInfo); //printf("use MPR results in distance %f\n",distInfo.m_distance); - } if (res == 0) { @@ -201,7 +186,7 @@ void btConvexConvexMprAlgorithm ::processCollision (const btCollisionObjectWrapp distInfo.m_pointOnB[0], distInfo.m_pointOnB[1], distInfo.m_pointOnB[2]); #endif - if (distInfo.m_distance<=0) + if (distInfo.m_distance <= 0) { resultOut->addContactPoint(distInfo.m_normalBtoA, distInfo.m_pointOnB, distInfo.m_distance); } @@ -213,7 +198,6 @@ void btConvexConvexMprAlgorithm ::processCollision (const btCollisionObjectWrapp //ASSERT_NEAR(computedA.z(),distInfo.m_pointOnA.z(),abs_error); } - #if 0 btCollisionDescription colDesc; colDesc.m_objA = min0; @@ -244,10 +228,10 @@ void btConvexConvexMprAlgorithm ::processCollision (const btCollisionObjectWrapp int btComputeGjkEpaPenetration(min0, min1, &colDesc, &distInfo); */ #endif - } else + } + else { - - btGjkPairDetector gjkPairDetector(min0,min1,&vs,&epa);//m_simplexSolver,m_pdSolver); + btGjkPairDetector gjkPairDetector(min0, min1, &vs, &epa); //m_simplexSolver,m_pdSolver); //TODO: if (dispatchInfo.m_useContinuous) gjkPairDetector.setMinkowskiA(min0); gjkPairDetector.setMinkowskiB(min1); @@ -259,30 +243,26 @@ void btConvexConvexMprAlgorithm ::processCollision (const btCollisionObjectWrapp //} else //{ input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold(); - // } + // } - input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared; + input.m_maximumDistanceSquared *= input.m_maximumDistanceSquared; } input.m_transformA = body0Wrap->getWorldTransform(); input.m_transformB = body1Wrap->getWorldTransform(); - - gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); + gjkPairDetector.getClosestPoints(input, *resultOut, dispatchInfo.m_debugDraw); } if (m_ownManifold) { resultOut->refreshContactPoints(); } - } - -btScalar btConvexConvexMprAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +btScalar btConvexConvexMprAlgorithm::calculateTimeOfImpact(btCollisionObject* col0, btCollisionObject* col1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { (void)resultOut; (void)dispatchInfo; btAssert(0); return 0; } - diff --git a/examples/VoronoiFracture/btConvexConvexMprAlgorithm.h b/examples/VoronoiFracture/btConvexConvexMprAlgorithm.h index 6edbdccae..40f273531 100644 --- a/examples/VoronoiFracture/btConvexConvexMprAlgorithm.h +++ b/examples/VoronoiFracture/btConvexConvexMprAlgorithm.h @@ -23,7 +23,7 @@ subject to the following restrictions: #include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" #include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" -#include "LinearMath/btTransformUtil.h" //for btConvexSeparatingDistanceUtil +#include "LinearMath/btTransformUtil.h" //for btConvexSeparatingDistanceUtil class btConvexPenetrationDepthSolver; @@ -37,51 +37,43 @@ class btConvexPenetrationDepthSolver; ///This idea was described by Gino van den Bergen in this forum topic http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=4&t=288&p=888#p888 class btConvexConvexMprAlgorithm : public btActivatingCollisionAlgorithm { - - - bool m_ownManifold; - btPersistentManifold* m_manifoldPtr; + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; ///cache separating vector to speedup collision detection - -public: - btConvexConvexMprAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap); +public: + btConvexConvexMprAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap); virtual ~btConvexConvexMprAlgorithm(); - virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) { ///should we use m_ownManifold to avoid adding duplicates? if (m_manifoldPtr && m_ownManifold) manifoldArray.push_back(m_manifoldPtr); } -const btPersistentManifold* getManifold() + const btPersistentManifold* getManifold() { return m_manifoldPtr; } - struct CreateFunc :public btCollisionAlgorithmCreateFunc + struct CreateFunc : public btCollisionAlgorithmCreateFunc { - - - CreateFunc(); - + virtual ~CreateFunc(); - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConvexMprAlgorithm)); - return new(mem) btConvexConvexMprAlgorithm(ci.m_manifold,ci,body0Wrap,body1Wrap); + return new (mem) btConvexConvexMprAlgorithm(ci.m_manifold, ci, body0Wrap, body1Wrap); } }; - - }; -#endif //BT_CONVEX_CONVEX_MPR_ALGORITHM_H +#endif //BT_CONVEX_CONVEX_MPR_ALGORITHM_H diff --git a/examples/pybullet/pybullet.c b/examples/pybullet/pybullet.c index ba5e479c7..88e4de5f2 100644 --- a/examples/pybullet/pybullet.c +++ b/examples/pybullet/pybullet.c @@ -32,7 +32,7 @@ #ifdef B3_DUMP_PYTHON_VERSION #define B3_VALUE_TO_STRING(x) #x #define B3_VALUE(x) B3_VALUE_TO_STRING(x) -#define B3_VAR_NAME_VALUE(var) #var "=" B3_VALUE(var) +#define B3_VAR_NAME_VALUE(var) #var "=" B3_VALUE(var) #pragma message(B3_VAR_NAME_VALUE(PY_MAJOR_VERSION)) #pragma message(B3_VAR_NAME_VALUE(PY_MINOR_VERSION)) #endif @@ -41,7 +41,6 @@ #include #endif - #if PY_MAJOR_VERSION >= 3 #define PyInt_FromLong PyLong_FromLong #define PyString_FromString PyBytes_FromString @@ -78,7 +77,6 @@ b3PhysicsClientHandle getPhysicsClient(int physicsClientId) return 0; } - static double pybullet_internalGetFloatFromSequence(PyObject* seq, int index) { double v = 0.0; @@ -126,7 +124,7 @@ static int pybullet_internalSetMatrix(PyObject* objMat, float matrix[16]) int i, len; PyObject* seq; - if (objMat==NULL) + if (objMat == NULL) return 0; seq = PySequence_Fast(objMat, "expected a sequence"); @@ -237,7 +235,6 @@ static int pybullet_internalSetVector4d(PyObject* obVec, double vector[4]) return 0; } - static int pybullet_internalGetVector3FromSequence(PyObject* seq, int index, double vec[3]) { int v = 0; @@ -246,12 +243,12 @@ static int pybullet_internalGetVector3FromSequence(PyObject* seq, int index, dou if (PyList_Check(seq)) { item = PyList_GET_ITEM(seq, index); - pybullet_internalSetVectord(item,vec); + pybullet_internalSetVectord(item, vec); } else { item = PyTuple_GET_ITEM(seq, index); - pybullet_internalSetVectord(item,vec); + pybullet_internalSetVectord(item, vec); } return v; } @@ -264,18 +261,16 @@ static int pybullet_internalGetVector4FromSequence(PyObject* seq, int index, dou if (PyList_Check(seq)) { item = PyList_GET_ITEM(seq, index); - pybullet_internalSetVector4d(item,vec); + pybullet_internalSetVector4d(item, vec); } else { item = PyTuple_GET_ITEM(seq, index); - pybullet_internalSetVector4d(item,vec); + pybullet_internalSetVector4d(item, vec); } return v; } - - // Step through one timestep of the simulation static PyObject* pybullet_stepSimulation(PyObject* self, PyObject* args, PyObject* keywds) { @@ -315,7 +310,7 @@ static PyObject* pybullet_connectPhysicsServer(PyObject* self, PyObject* args, P int freeIndex = -1; int method = eCONNECT_GUI; int i; - char* options=0; + char* options = 0; b3PhysicsClientHandle sm = 0; @@ -332,24 +327,24 @@ static PyObject* pybullet_connectPhysicsServer(PyObject* self, PyObject* args, P int tcpPort = 6667; int grpcPort = -1; int argc = 0; - char** argv=0; + char** argv = 0; const char* hostName = "localhost"; + static char* kwlist1[] = {"method", "key", "options", NULL}; + static char* kwlist2[] = {"method", "hostName", "port", "options", NULL}; - static char* kwlist1[] = {"method","key", "options", NULL}; - static char* kwlist2[] = {"method","hostName", "port", "options", NULL}; - - if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|is", kwlist1, &method,&key,&options)) + if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|is", kwlist1, &method, &key, &options)) { int port = -1; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|sis", kwlist2, &method,&hostName, &port,&options)) + if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|sis", kwlist2, &method, &hostName, &port, &options)) { return NULL; - } else + } + else { PyErr_Clear(); - if (port>=0) + if (port >= 0) { udpPort = port; tcpPort = port; @@ -387,8 +382,6 @@ static PyObject* pybullet_connectPhysicsServer(PyObject* self, PyObject* args, P { case eCONNECT_GUI: { - - #ifdef __APPLE__ sm = b3CreateInProcessPhysicsServerAndConnectMainThread(argc, argv); #else @@ -397,13 +390,12 @@ static PyObject* pybullet_connectPhysicsServer(PyObject* self, PyObject* args, P break; } case eCONNECT_GUI_MAIN_THREAD: - { - sm = b3CreateInProcessPhysicsServerAndConnectMainThread(argc, argv); - break; - } + { + sm = b3CreateInProcessPhysicsServerAndConnectMainThread(argc, argv); + break; + } case eCONNECT_GUI_SERVER: { - #ifdef __APPLE__ sm = b3CreateInProcessPhysicsServerAndConnectMainThreadSharedMemory(argc, argv); #else @@ -411,11 +403,11 @@ static PyObject* pybullet_connectPhysicsServer(PyObject* self, PyObject* args, P #endif break; } - case eCONNECT_SHARED_MEMORY_SERVER: - { - sm = b3CreateInProcessPhysicsServerFromExistingExampleBrowserAndConnect3(0, key); - break; - } + case eCONNECT_SHARED_MEMORY_SERVER: + { + sm = b3CreateInProcessPhysicsServerFromExistingExampleBrowserAndConnect3(0, key); + break; + } case eCONNECT_DIRECT: { sm = b3ConnectPhysicsDirect(); @@ -444,7 +436,7 @@ static PyObject* pybullet_connectPhysicsServer(PyObject* self, PyObject* args, P PyErr_SetString(SpamError, "GRPC is not enabled in this pybullet build"); #endif break; - } + } case eCONNECT_SHARED_MEMORY: { sm = b3ConnectSharedMemory(key); @@ -519,11 +511,11 @@ static PyObject* pybullet_connectPhysicsServer(PyObject* self, PyObject* args, P { printf("Connection terminated, couldn't get body info\n"); b3DisconnectSharedMemory(sm); - sm = 0; + sm = 0; sPhysicsClients1[freeIndex] = 0; - sPhysicsClientsGUI[freeIndex] = 0; - sNumPhysicsClients++; - return PyInt_FromLong(-1); + sPhysicsClientsGUI[freeIndex] = 0; + sNumPhysicsClients++; + return PyInt_FromLong(-1); } command = b3InitSyncUserDataCommand(sm); @@ -534,14 +526,15 @@ static PyObject* pybullet_connectPhysicsServer(PyObject* self, PyObject* args, P { printf("Connection terminated, couldn't get user data\n"); b3DisconnectSharedMemory(sm); - sm = 0; + sm = 0; sPhysicsClients1[freeIndex] = 0; - sPhysicsClientsGUI[freeIndex] = 0; - sNumPhysicsClients++; - return PyInt_FromLong(-1); + sPhysicsClientsGUI[freeIndex] = 0; + sNumPhysicsClients++; + return PyInt_FromLong(-1); } } - } else + } + else { b3DisconnectSharedMemory(sm); } @@ -584,7 +577,7 @@ static PyObject* pybullet_disconnectPhysicsServer(PyObject* self, void b3pybulletExitFunc(void) { int i; - for (i=0;i=0) + if (flags >= 0) { - b3LoadMJCFCommandSetFlags(command,flags); + b3LoadMJCFCommandSetFlags(command, flags); } statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command); statusType = b3GetStatusType(statusHandle); @@ -1189,7 +1165,7 @@ static PyObject* pybullet_loadMJCF(PyObject* self, PyObject* args, PyObject* key if (numBodies > MAX_SDF_BODIES) { char str[1024]; - sprintf(str,"SDF exceeds body capacity: %d > %d", numBodies, MAX_SDF_BODIES); + sprintf(str, "SDF exceeds body capacity: %d > %d", numBodies, MAX_SDF_BODIES); PyErr_SetString(SpamError, str); return NULL; } @@ -1212,25 +1188,25 @@ static PyObject* pybullet_changeDynamicsInfo(PyObject* self, PyObject* args, PyO int linkIndex = -2; double mass = -1; double lateralFriction = -1; - double spinningFriction= -1; + double spinningFriction = -1; double rollingFriction = -1; double restitution = -1; double linearDamping = -1; double angularDamping = -1; double contactStiffness = -1; double contactDamping = -1; - double ccdSweptSphereRadius=-1; + double ccdSweptSphereRadius = -1; int frictionAnchor = -1; double contactProcessingThreshold = -1; int activationState = -1; - PyObject* localInertiaDiagonalObj=0; + PyObject* localInertiaDiagonalObj = 0; b3PhysicsClientHandle sm = 0; int physicsClientId = 0; - static char* kwlist[] = {"bodyUniqueId", "linkIndex", "mass", "lateralFriction", "spinningFriction", "rollingFriction","restitution", "linearDamping", "angularDamping", "contactStiffness", "contactDamping", "frictionAnchor", "localInertiaDiagonal", "ccdSweptSphereRadius", "contactProcessingThreshold", "activationState", "physicsClientId", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "ii|dddddddddiOddii", kwlist, &bodyUniqueId, &linkIndex,&mass, &lateralFriction, &spinningFriction, &rollingFriction, &restitution,&linearDamping, &angularDamping, &contactStiffness, &contactDamping, &frictionAnchor, &localInertiaDiagonalObj, &ccdSweptSphereRadius, &contactProcessingThreshold,&activationState, &physicsClientId)) + static char* kwlist[] = {"bodyUniqueId", "linkIndex", "mass", "lateralFriction", "spinningFriction", "rollingFriction", "restitution", "linearDamping", "angularDamping", "contactStiffness", "contactDamping", "frictionAnchor", "localInertiaDiagonal", "ccdSweptSphereRadius", "contactProcessingThreshold", "activationState", "physicsClientId", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, keywds, "ii|dddddddddiOddii", kwlist, &bodyUniqueId, &linkIndex, &mass, &lateralFriction, &spinningFriction, &rollingFriction, &restitution, &linearDamping, &angularDamping, &contactStiffness, &contactDamping, &frictionAnchor, &localInertiaDiagonalObj, &ccdSweptSphereRadius, &contactProcessingThreshold, &activationState, &physicsClientId)) { return NULL; } @@ -1242,7 +1218,7 @@ static PyObject* pybullet_changeDynamicsInfo(PyObject* self, PyObject* args, PyO return NULL; } - if ((contactStiffness>=0 && contactDamping <0)||(contactStiffness<0 && contactDamping >=0)) + if ((contactStiffness >= 0 && contactDamping < 0) || (contactStiffness < 0 && contactDamping >= 0)) { PyErr_SetString(SpamError, "Both contactStiffness and contactDamping needs to be set together."); return NULL; @@ -1266,39 +1242,39 @@ static PyObject* pybullet_changeDynamicsInfo(PyObject* self, PyObject* args, PyO { b3ChangeDynamicsInfoSetLateralFriction(command, bodyUniqueId, linkIndex, lateralFriction); } - if (spinningFriction>=0) + if (spinningFriction >= 0) { - b3ChangeDynamicsInfoSetSpinningFriction(command, bodyUniqueId, linkIndex,spinningFriction); + b3ChangeDynamicsInfoSetSpinningFriction(command, bodyUniqueId, linkIndex, spinningFriction); } - if (rollingFriction>=0) + if (rollingFriction >= 0) { - b3ChangeDynamicsInfoSetRollingFriction(command, bodyUniqueId, linkIndex,rollingFriction); + b3ChangeDynamicsInfoSetRollingFriction(command, bodyUniqueId, linkIndex, rollingFriction); } - if (linearDamping>=0) + if (linearDamping >= 0) { - b3ChangeDynamicsInfoSetLinearDamping(command,bodyUniqueId, linearDamping); + b3ChangeDynamicsInfoSetLinearDamping(command, bodyUniqueId, linearDamping); } - if (angularDamping>=0) + if (angularDamping >= 0) { - b3ChangeDynamicsInfoSetAngularDamping(command,bodyUniqueId,angularDamping); + b3ChangeDynamicsInfoSetAngularDamping(command, bodyUniqueId, angularDamping); } - if (restitution>=0) + if (restitution >= 0) { b3ChangeDynamicsInfoSetRestitution(command, bodyUniqueId, linkIndex, restitution); } - if (contactStiffness>=0 && contactDamping >=0) + if (contactStiffness >= 0 && contactDamping >= 0) { - b3ChangeDynamicsInfoSetContactStiffnessAndDamping(command,bodyUniqueId,linkIndex,contactStiffness, contactDamping); + b3ChangeDynamicsInfoSetContactStiffnessAndDamping(command, bodyUniqueId, linkIndex, contactStiffness, contactDamping); } - if (frictionAnchor>=0) + if (frictionAnchor >= 0) { - b3ChangeDynamicsInfoSetFrictionAnchor(command,bodyUniqueId,linkIndex, frictionAnchor); + b3ChangeDynamicsInfoSetFrictionAnchor(command, bodyUniqueId, linkIndex, frictionAnchor); } - if (ccdSweptSphereRadius>=0) + if (ccdSweptSphereRadius >= 0) { - b3ChangeDynamicsInfoSetCcdSweptSphereRadius(command,bodyUniqueId,linkIndex, ccdSweptSphereRadius); + b3ChangeDynamicsInfoSetCcdSweptSphereRadius(command, bodyUniqueId, linkIndex, ccdSweptSphereRadius); } if (activationState >= 0) { @@ -1325,7 +1301,7 @@ static PyObject* pybullet_getDynamicsInfo(PyObject* self, PyObject* args, PyObje int physicsClientId = 0; static char* kwlist[] = {"bodyUniqueId", "linkIndex", "physicsClientId", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "ii|i", kwlist, &bodyUniqueId, &linkIndex, &physicsClientId)) + if (!PyArg_ParseTupleAndKeywords(args, keywds, "ii|i", kwlist, &bodyUniqueId, &linkIndex, &physicsClientId)) { return NULL; } @@ -1341,7 +1317,6 @@ static PyObject* pybullet_getDynamicsInfo(PyObject* self, PyObject* args, PyObje b3SharedMemoryStatusHandle status_handle; struct b3DynamicsInfo info; - if (bodyUniqueId < 0) { PyErr_SetString(SpamError, "getDynamicsInfo failed; invalid bodyUniqueId"); @@ -1363,7 +1338,6 @@ static PyObject* pybullet_getDynamicsInfo(PyObject* self, PyObject* args, PyObje if (b3GetDynamicsInfo(status_handle, &info)) { - int numFields = 10; PyObject* pyDynamicsInfo = PyTuple_New(numFields); PyTuple_SetItem(pyDynamicsInfo, 0, PyFloat_FromDouble(info.m_mass)); @@ -1377,14 +1351,14 @@ static PyObject* pybullet_getDynamicsInfo(PyObject* self, PyObject* args, PyObje PyTuple_SetItem(pyDynamicsInfo, 2, pyInertiaDiag); } { - PyObject* pyInertiaPos= PyTuple_New(3); + PyObject* pyInertiaPos = PyTuple_New(3); PyTuple_SetItem(pyInertiaPos, 0, PyFloat_FromDouble(info.m_localInertialFrame[0])); PyTuple_SetItem(pyInertiaPos, 1, PyFloat_FromDouble(info.m_localInertialFrame[1])); PyTuple_SetItem(pyInertiaPos, 2, PyFloat_FromDouble(info.m_localInertialFrame[2])); PyTuple_SetItem(pyDynamicsInfo, 3, pyInertiaPos); } { - PyObject* pyInertiaOrn= PyTuple_New(4); + PyObject* pyInertiaOrn = PyTuple_New(4); PyTuple_SetItem(pyInertiaOrn, 0, PyFloat_FromDouble(info.m_localInertialFrame[3])); PyTuple_SetItem(pyInertiaOrn, 1, PyFloat_FromDouble(info.m_localInertialFrame[4])); PyTuple_SetItem(pyInertiaOrn, 2, PyFloat_FromDouble(info.m_localInertialFrame[5])); @@ -1407,7 +1381,7 @@ static PyObject* pybullet_getDynamicsInfo(PyObject* self, PyObject* args, PyObje static PyObject* pybullet_getPhysicsEngineParameters(PyObject* self, PyObject* args, PyObject* keywds) { b3PhysicsClientHandle sm = 0; - PyObject* val=0; + PyObject* val = 0; int physicsClientId = 0; static char* kwlist[] = {"physicsClientId", NULL}; @@ -1430,29 +1404,26 @@ static PyObject* pybullet_getPhysicsEngineParameters(PyObject* self, PyObject* a statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command); statusType = b3GetStatusType(statusHandle); - if (statusType!=CMD_REQUEST_PHYSICS_SIMULATION_PARAMETERS_COMPLETED) + if (statusType != CMD_REQUEST_PHYSICS_SIMULATION_PARAMETERS_COMPLETED) { PyErr_SetString(SpamError, "Couldn't get physics simulation parameters."); return NULL; } - b3GetStatusPhysicsSimulationParameters(statusHandle,¶ms); + b3GetStatusPhysicsSimulationParameters(statusHandle, ¶ms); //for now, return a subset, expose more/all on request val = Py_BuildValue("{s:d,s:i,s:i,s:i,s:d,s:d,s:d}", - "fixedTimeStep", params.m_deltaTime, - "numSubSteps", params.m_numSimulationSubSteps, - "numSolverIterations", params.m_numSolverIterations, - "useRealTimeSimulation", params.m_useRealTimeSimulation, - "gravityAccelerationX", params.m_gravityAcceleration[0], - "gravityAccelerationY", params.m_gravityAcceleration[1], - "gravityAccelerationZ", params.m_gravityAcceleration[2] - ); + "fixedTimeStep", params.m_deltaTime, + "numSubSteps", params.m_numSimulationSubSteps, + "numSolverIterations", params.m_numSolverIterations, + "useRealTimeSimulation", params.m_useRealTimeSimulation, + "gravityAccelerationX", params.m_gravityAcceleration[0], + "gravityAccelerationY", params.m_gravityAcceleration[1], + "gravityAccelerationZ", params.m_gravityAcceleration[2]); return val; } //"fixedTimeStep", "numSolverIterations", "useSplitImpulse", "splitImpulsePenetrationThreshold", "numSubSteps", "collisionFilterMode", "contactBreakingThreshold", "maxNumCmdPer1ms", "enableFileCaching","restitutionVelocityThreshold", "erp", "contactERP", "frictionERP", //val = Py_BuildValue("{s:i,s:i}","isConnected", isConnected, "connectionMethod", method); - - } static PyObject* pybullet_setPhysicsEngineParameter(PyObject* self, PyObject* args, PyObject* keywds) @@ -1466,7 +1437,7 @@ static PyObject* pybullet_setPhysicsEngineParameter(PyObject* self, PyObject* ar double contactBreakingThreshold = -1; int maxNumCmdPer1ms = -2; int enableFileCaching = -1; - double restitutionVelocityThreshold=-1; + double restitutionVelocityThreshold = -1; double erp = -1; double contactERP = -1; double frictionERP = -1; @@ -1475,18 +1446,17 @@ static PyObject* pybullet_setPhysicsEngineParameter(PyObject* self, PyObject* ar int enableConeFriction = -1; b3PhysicsClientHandle sm = 0; int deterministicOverlappingPairs = -1; - int jointFeedbackMode =-1; + int jointFeedbackMode = -1; double solverResidualThreshold = -1; double contactSlop = -1; int enableSAT = -1; - int constraintSolverType=-1; - double globalCFM = -1; + int constraintSolverType = -1; + double globalCFM = -1; int minimumSolverIslandSize = -1; - int physicsClientId = 0; - static char* kwlist[] = {"fixedTimeStep", "numSolverIterations", "useSplitImpulse", "splitImpulsePenetrationThreshold", "numSubSteps", "collisionFilterMode", "contactBreakingThreshold", "maxNumCmdPer1ms", "enableFileCaching","restitutionVelocityThreshold", "erp", "contactERP", "frictionERP", "enableConeFriction", "deterministicOverlappingPairs", "allowedCcdPenetration", "jointFeedbackMode", "solverResidualThreshold", "contactSlop", "enableSAT", "constraintSolverType", "globalCFM", "minimumSolverIslandSize", "physicsClientId", NULL}; + static char* kwlist[] = {"fixedTimeStep", "numSolverIterations", "useSplitImpulse", "splitImpulsePenetrationThreshold", "numSubSteps", "collisionFilterMode", "contactBreakingThreshold", "maxNumCmdPer1ms", "enableFileCaching", "restitutionVelocityThreshold", "erp", "contactERP", "frictionERP", "enableConeFriction", "deterministicOverlappingPairs", "allowedCcdPenetration", "jointFeedbackMode", "solverResidualThreshold", "contactSlop", "enableSAT", "constraintSolverType", "globalCFM", "minimumSolverIslandSize", "physicsClientId", NULL}; if (!PyArg_ParseTupleAndKeywords(args, keywds, "|diidiidiiddddiididdiiddi", kwlist, &fixedTimeStep, &numSolverIterations, &useSplitImpulse, &splitImpulsePenetrationThreshold, &numSubSteps, &collisionFilterMode, &contactBreakingThreshold, &maxNumCmdPer1ms, &enableFileCaching, &restitutionVelocityThreshold, &erp, &contactERP, &frictionERP, &enableConeFriction, &deterministicOverlappingPairs, &allowedCcdPenetration, &jointFeedbackMode, &solverResidualThreshold, &contactSlop, &enableSAT, &constraintSolverType, &globalCFM, &minimumSolverIslandSize, &physicsClientId)) @@ -1515,8 +1485,7 @@ static PyObject* pybullet_setPhysicsEngineParameter(PyObject* self, PyObject* ar b3PhysicsParameterSetMinimumSolverIslandSize(command, minimumSolverIslandSize); } - - if (solverResidualThreshold>=0) + if (solverResidualThreshold >= 0) { b3PhysicsParamSetSolverResidualThreshold(command, solverResidualThreshold); } @@ -1550,68 +1519,66 @@ static PyObject* pybullet_setPhysicsEngineParameter(PyObject* self, PyObject* ar b3PhysicsParamSetContactSlop(command, contactSlop); } - //-1 is disables the maxNumCmdPer1ms feature, allow it if (maxNumCmdPer1ms >= -1) { b3PhysicsParamSetMaxNumCommandsPer1ms(command, maxNumCmdPer1ms); } - if (restitutionVelocityThreshold>=0) + if (restitutionVelocityThreshold >= 0) { b3PhysicsParamSetRestitutionVelocityThreshold(command, restitutionVelocityThreshold); } - if (enableFileCaching>=0) + if (enableFileCaching >= 0) { b3PhysicsParamSetEnableFileCaching(command, enableFileCaching); } - if (erp>=0) + if (erp >= 0) { - b3PhysicsParamSetDefaultNonContactERP(command,erp); + b3PhysicsParamSetDefaultNonContactERP(command, erp); } - if (contactERP>=0) + if (contactERP >= 0) { - b3PhysicsParamSetDefaultContactERP(command,contactERP); + b3PhysicsParamSetDefaultContactERP(command, contactERP); } - if (frictionERP >=0) + if (frictionERP >= 0) { - b3PhysicsParamSetDefaultFrictionERP(command,frictionERP); + b3PhysicsParamSetDefaultFrictionERP(command, frictionERP); } if (enableConeFriction >= 0) { b3PhysicsParamSetEnableConeFriction(command, enableConeFriction); } - if (deterministicOverlappingPairs>=0) + if (deterministicOverlappingPairs >= 0) { - b3PhysicsParameterSetDeterministicOverlappingPairs(command,deterministicOverlappingPairs); + b3PhysicsParameterSetDeterministicOverlappingPairs(command, deterministicOverlappingPairs); } - if (allowedCcdPenetration>=0) + if (allowedCcdPenetration >= 0) { - b3PhysicsParameterSetAllowedCcdPenetration(command,allowedCcdPenetration); + b3PhysicsParameterSetAllowedCcdPenetration(command, allowedCcdPenetration); } - if (jointFeedbackMode>=0) + if (jointFeedbackMode >= 0) { - b3PhysicsParameterSetJointFeedbackMode(command,jointFeedbackMode); + b3PhysicsParameterSetJointFeedbackMode(command, jointFeedbackMode); } - if (enableSAT>=0) + if (enableSAT >= 0) { b3PhysicsParameterSetEnableSAT(command, enableSAT); } - if (constraintSolverType>=0) - { - b3PhysicsParameterSetConstraintSolverType(command, constraintSolverType); - } - if (globalCFM>=0) - { - b3PhysicsParamSetDefaultGlobalCFM(command, globalCFM); - } + if (constraintSolverType >= 0) + { + b3PhysicsParameterSetConstraintSolverType(command, constraintSolverType); + } + if (globalCFM >= 0) + { + b3PhysicsParamSetDefaultGlobalCFM(command, globalCFM); + } statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command); } - Py_INCREF(Py_None); return Py_None; } @@ -1626,12 +1593,12 @@ static PyObject* pybullet_loadURDF(PyObject* self, PyObject* args, PyObject* key int physicsClientId = 0; int flags = 0; - static char* kwlist[] = {"fileName", "basePosition", "baseOrientation", "useMaximalCoordinates", "useFixedBase", "flags","globalScaling", "physicsClientId", NULL}; + static char* kwlist[] = {"fileName", "basePosition", "baseOrientation", "useMaximalCoordinates", "useFixedBase", "flags", "globalScaling", "physicsClientId", NULL}; static char* kwlistBackwardCompatible4[] = {"fileName", "startPosX", "startPosY", "startPosZ", NULL}; static char* kwlistBackwardCompatible8[] = {"fileName", "startPosX", "startPosY", "startPosZ", "startOrnX", "startOrnY", "startOrnZ", "startOrnW", NULL}; - int bodyUniqueId= -1; + int bodyUniqueId = -1; const char* urdfFileName = ""; double globalScaling = -1; double startPosX = 0.0; @@ -1722,24 +1689,24 @@ static PyObject* pybullet_loadURDF(PyObject* self, PyObject* args, PyObject* key b3SharedMemoryCommandHandle command = b3LoadUrdfCommandInit(sm, urdfFileName); - b3LoadUrdfCommandSetFlags(command,flags); + b3LoadUrdfCommandSetFlags(command, flags); // setting the initial position, orientation and other arguments are // optional b3LoadUrdfCommandSetStartPosition(command, startPosX, startPosY, startPosZ); b3LoadUrdfCommandSetStartOrientation(command, startOrnX, startOrnY, startOrnZ, startOrnW); - if (useMaximalCoordinates>=0) + if (useMaximalCoordinates >= 0) { - b3LoadUrdfCommandSetUseMultiBody(command, useMaximalCoordinates==0); + b3LoadUrdfCommandSetUseMultiBody(command, useMaximalCoordinates == 0); } if (useFixedBase) { b3LoadUrdfCommandSetUseFixedBase(command, 1); } - if (globalScaling>0) + if (globalScaling > 0) { - b3LoadUrdfCommandSetGlobalScaling(command,globalScaling); + b3LoadUrdfCommandSetGlobalScaling(command, globalScaling); } statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command); statusType = b3GetStatusType(statusHandle); @@ -1787,13 +1754,13 @@ static PyObject* pybullet_loadSDF(PyObject* self, PyObject* args, PyObject* keyw } commandHandle = b3LoadSdfCommandInit(sm, sdfFileName); - if (useMaximalCoordinates>0) + if (useMaximalCoordinates > 0) { - b3LoadSdfCommandSetUseMultiBody(commandHandle,0); + b3LoadSdfCommandSetUseMultiBody(commandHandle, 0); } if (globalScaling > 0) { - b3LoadSdfCommandSetUseGlobalScaling(commandHandle,globalScaling); + b3LoadSdfCommandSetUseGlobalScaling(commandHandle, globalScaling); } statusHandle = b3SubmitClientCommandAndWaitStatus(sm, commandHandle); statusType = b3GetStatusType(statusHandle); @@ -1808,7 +1775,7 @@ static PyObject* pybullet_loadSDF(PyObject* self, PyObject* args, PyObject* keyw if (numBodies > MAX_SDF_BODIES) { char str[1024]; - sprintf(str,"SDF exceeds body capacity: %d > %d", numBodies, MAX_SDF_BODIES); + sprintf(str, "SDF exceeds body capacity: %d > %d", numBodies, MAX_SDF_BODIES); PyErr_SetString(SpamError, str); return NULL; } @@ -1834,7 +1801,7 @@ static PyObject* pybullet_loadSoftBody(PyObject* self, PyObject* args, PyObject* static char* kwlist[] = {"fileName", "scale", "mass", "collisionMargin", "physicsClientId", NULL}; - int bodyUniqueId= -1; + int bodyUniqueId = -1; const char* fileName = ""; double scale = -1; double mass = -1; @@ -1859,19 +1826,19 @@ static PyObject* pybullet_loadSoftBody(PyObject* self, PyObject* args, PyObject* b3SharedMemoryStatusHandle statusHandle; int statusType; b3SharedMemoryCommandHandle command = - b3LoadSoftBodyCommandInit(sm, fileName); + b3LoadSoftBodyCommandInit(sm, fileName); - if (scale>0) + if (scale > 0) { - b3LoadSoftBodySetScale(command,scale); + b3LoadSoftBodySetScale(command, scale); } - if (mass>0) + if (mass > 0) { - b3LoadSoftBodySetMass(command,mass); + b3LoadSoftBodySetMass(command, mass); } - if (collisionMargin>0) + if (collisionMargin > 0) { - b3LoadSoftBodySetCollisionMargin(command,collisionMargin); + b3LoadSoftBodySetCollisionMargin(command, collisionMargin); } statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command); statusType = b3GetStatusType(statusHandle); @@ -2125,7 +2092,7 @@ static PyObject* pybullet_setJointMotorControl(PyObject* self, PyObject* args) static PyObject* pybullet_setJointMotorControlArray(PyObject* self, PyObject* args, PyObject* keywds) { - int bodyUniqueId, controlMode; + int bodyUniqueId, controlMode; PyObject* jointIndicesObj = 0; PyObject* targetPositionsObj = 0; PyObject* targetVelocitiesObj = 0; @@ -2143,7 +2110,7 @@ static PyObject* pybullet_setJointMotorControlArray(PyObject* self, PyObject* ar static char* kwlist2[] = {"bodyIndex", "jointIndices", "controlMode", "targetPositions", "targetVelocities", "forces", "positionGains", "velocityGains", "physicsClientId", NULL}; PyErr_Clear(); if (!PyArg_ParseTupleAndKeywords(args, keywds, "iOi|OOOOOi", kwlist2, &bodyUniqueId, &jointIndicesObj, &controlMode, - &targetPositionsObj, &targetVelocitiesObj, &forcesObj, &kpsObj, &kdsObj, &physicsClientId)) + &targetPositionsObj, &targetVelocitiesObj, &forcesObj, &kpsObj, &kdsObj, &physicsClientId)) { return NULL; } @@ -2156,7 +2123,6 @@ static PyObject* pybullet_setJointMotorControlArray(PyObject* self, PyObject* ar } { - int numJoints; int i; b3SharedMemoryCommandHandle commandHandle; @@ -2180,16 +2146,16 @@ static PyObject* pybullet_setJointMotorControlArray(PyObject* self, PyObject* ar return NULL; } - jointIndicesSeq = PySequence_Fast(jointIndicesObj, "expected a sequence of joint indices"); + jointIndicesSeq = PySequence_Fast(jointIndicesObj, "expected a sequence of joint indices"); - if (jointIndicesSeq==0) + if (jointIndicesSeq == 0) { PyErr_SetString(SpamError, "expected a sequence of joint indices"); return NULL; } numControlledDofs = PySequence_Size(jointIndicesObj); - if (numControlledDofs==0) + if (numControlledDofs == 0) { Py_DECREF(jointIndicesSeq); Py_INCREF(Py_None); @@ -2219,7 +2185,7 @@ static PyObject* pybullet_setJointMotorControlArray(PyObject* self, PyObject* ar PyErr_SetString(SpamError, "number of target velocies should match the number of joint indices"); return NULL; } - targetVelocitiesSeq = PySequence_Fast(targetVelocitiesObj, "expected a sequence of target velocities"); + targetVelocitiesSeq = PySequence_Fast(targetVelocitiesObj, "expected a sequence of target velocities"); } if (targetPositionsObj) @@ -2236,7 +2202,7 @@ static PyObject* pybullet_setJointMotorControlArray(PyObject* self, PyObject* ar return NULL; } - targetPositionsSeq = PySequence_Fast(targetPositionsObj, "expected a sequence of target positions"); + targetPositionsSeq = PySequence_Fast(targetPositionsObj, "expected a sequence of target positions"); } if (forcesObj) @@ -2258,10 +2224,9 @@ static PyObject* pybullet_setJointMotorControlArray(PyObject* self, PyObject* ar return NULL; } - forcesSeq = PySequence_Fast(forcesObj, "expected a sequence of forces"); + forcesSeq = PySequence_Fast(forcesObj, "expected a sequence of forces"); } - if (kpsObj) { int num = PySequence_Size(kpsObj); @@ -2285,10 +2250,9 @@ static PyObject* pybullet_setJointMotorControlArray(PyObject* self, PyObject* ar return NULL; } - kpsSeq = PySequence_Fast(kpsObj, "expected a sequence of kps"); + kpsSeq = PySequence_Fast(kpsObj, "expected a sequence of kps"); } - if (kdsObj) { int num = PySequence_Size(kdsObj); @@ -2316,12 +2280,12 @@ static PyObject* pybullet_setJointMotorControlArray(PyObject* self, PyObject* ar return NULL; } - kdsSeq = PySequence_Fast(kdsObj, "expected a sequence of kds"); + kdsSeq = PySequence_Fast(kdsObj, "expected a sequence of kds"); } commandHandle = b3JointControlCommandInit2(sm, bodyUniqueId, controlMode); - for (i=0;i bodyUniqueId, don't need to update this function: people have to migrate to bodyUniqueId - static char* kwlist2[] = {"bodyIndex", "jointIndex", "controlMode", "targetPosition", "targetVelocity", "force", "positionGain", "velocityGain", "maxVelocity","physicsClientId", NULL}; + static char* kwlist2[] = {"bodyIndex", "jointIndex", "controlMode", "targetPosition", "targetVelocity", "force", "positionGain", "velocityGain", "maxVelocity", "physicsClientId", NULL}; PyErr_Clear(); if (!PyArg_ParseTupleAndKeywords(args, keywds, "iii|ddddddi", kwlist2, &bodyUniqueId, &jointIndex, &controlMode, - &targetPosition, &targetVelocity, &force, &kp, &kd, &maxVelocity, &physicsClientId)) + &targetPosition, &targetVelocity, &force, &kp, &kd, &maxVelocity, &physicsClientId)) { return NULL; } @@ -2476,7 +2438,7 @@ static PyObject* pybullet_setJointMotorControl2(PyObject* self, PyObject* args, if ((controlMode != CONTROL_MODE_VELOCITY) && (controlMode != CONTROL_MODE_TORQUE) && (controlMode != CONTROL_MODE_POSITION_VELOCITY_PD) && - (controlMode != CONTROL_MODE_PD)) + (controlMode != CONTROL_MODE_PD)) { PyErr_SetString(SpamError, "Illegral control mode."); return NULL; @@ -2505,9 +2467,9 @@ static PyObject* pybullet_setJointMotorControl2(PyObject* self, PyObject* args, } case CONTROL_MODE_POSITION_VELOCITY_PD: - case CONTROL_MODE_PD: + case CONTROL_MODE_PD: { - if (maxVelocity>0) + if (maxVelocity > 0) { b3JointControlSetMaximumVelocity(commandHandle, info.m_uIndex, maxVelocity); } @@ -2829,7 +2791,6 @@ static int pybullet_internalGetBasePositionAndOrientation( static PyObject* pybullet_getAABB(PyObject* self, PyObject* args, PyObject* keywds) { - int bodyUniqueId = -1; int linkIndex = -1; @@ -2877,19 +2838,19 @@ static PyObject* pybullet_getAABB(PyObject* self, PyObject* args, PyObject* keyw } { - PyObject* pyListAabb=0; - PyObject* pyListAabbMin=0; - PyObject* pyListAabbMax=0; + PyObject* pyListAabb = 0; + PyObject* pyListAabbMin = 0; + PyObject* pyListAabbMax = 0; double aabbMin[3]; double aabbMax[3]; - int i=0; + int i = 0; if (b3GetStatusAABB(status_handle, linkIndex, aabbMin, aabbMax)) { pyListAabb = PyTuple_New(2); pyListAabbMin = PyTuple_New(3); pyListAabbMax = PyTuple_New(3); - for (i=0;i<3;i++) + for (i = 0; i < 3; i++) { PyTuple_SetItem(pyListAabbMin, i, PyFloat_FromDouble(aabbMin[i])); PyTuple_SetItem(pyListAabbMax, i, PyFloat_FromDouble(aabbMax[i])); @@ -2903,7 +2864,6 @@ static PyObject* pybullet_getAABB(PyObject* self, PyObject* args, PyObject* keyw return pyListAabb; } } - } PyErr_SetString(SpamError, "getAABB failed."); @@ -3102,7 +3062,7 @@ static PyObject* pybullet_getBodyUniqueId(PyObject* self, PyObject* args, PyObje static PyObject* pybullet_removeCollisionShape(PyObject* self, PyObject* args, PyObject* keywds) { { - int collisionShapeId= -1; + int collisionShapeId = -1; b3PhysicsClientHandle sm = 0; int physicsClientId = 0; @@ -3117,13 +3077,13 @@ static PyObject* pybullet_removeCollisionShape(PyObject* self, PyObject* args, P PyErr_SetString(SpamError, "Not connected to physics server."); return NULL; } - if (collisionShapeId>=0) + if (collisionShapeId >= 0) { b3SharedMemoryStatusHandle statusHandle; int statusType; if (b3CanSubmitCommand(sm)) { - statusHandle = b3SubmitClientCommandAndWaitStatus( sm, b3InitRemoveCollisionShapeCommand(sm,collisionShapeId)); + statusHandle = b3SubmitClientCommandAndWaitStatus(sm, b3InitRemoveCollisionShapeCommand(sm, collisionShapeId)); statusType = b3GetStatusType(statusHandle); } } @@ -3151,13 +3111,13 @@ static PyObject* pybullet_removeBody(PyObject* self, PyObject* args, PyObject* k PyErr_SetString(SpamError, "Not connected to physics server."); return NULL; } - if (bodyUniqueId>=0) + if (bodyUniqueId >= 0) { b3SharedMemoryStatusHandle statusHandle; int statusType; if (b3CanSubmitCommand(sm)) { - statusHandle = b3SubmitClientCommandAndWaitStatus( sm, b3InitRemoveBodyCommand(sm,bodyUniqueId)); + statusHandle = b3SubmitClientCommandAndWaitStatus(sm, b3InitRemoveBodyCommand(sm, bodyUniqueId)); statusType = b3GetStatusType(statusHandle); } } @@ -3208,7 +3168,7 @@ static PyObject* pybullet_getConstraintInfo(PyObject* self, PyObject* args, PyOb b3PhysicsClientHandle sm = 0; int physicsClientId = 0; - static char* kwlist[] = { "constraintUniqueId", "physicsClientId", NULL }; + static char* kwlist[] = {"constraintUniqueId", "physicsClientId", NULL}; if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|i", kwlist, &constraintUniqueId, &physicsClientId)) { return NULL; @@ -3281,7 +3241,6 @@ static PyObject* pybullet_getConstraintInfo(PyObject* self, PyObject* args, PyOb } } - PyErr_SetString(SpamError, "Couldn't get user constraint info"); return NULL; } @@ -3293,7 +3252,7 @@ static PyObject* pybullet_getConstraintState(PyObject* self, PyObject* args, PyO b3PhysicsClientHandle sm = 0; int physicsClientId = 0; - static char* kwlist[] = { "constraintUniqueId", "physicsClientId", NULL }; + static char* kwlist[] = {"constraintUniqueId", "physicsClientId", NULL}; if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|i", kwlist, &constraintUniqueId, &physicsClientId)) { return NULL; @@ -3698,11 +3657,12 @@ static PyObject* pybullet_getJointInfo(PyObject* self, PyObject* args, PyObject* if (info.m_jointName[0]) { PyTuple_SetItem(pyListJointInfo, 1, - PyString_FromString(info.m_jointName)); - } else + PyString_FromString(info.m_jointName)); + } + else { PyTuple_SetItem(pyListJointInfo, 1, - PyString_FromString("not available")); + PyString_FromString("not available")); } PyTuple_SetItem(pyListJointInfo, 2, PyInt_FromLong(info.m_jointType)); @@ -3723,10 +3683,10 @@ static PyObject* pybullet_getJointInfo(PyObject* self, PyObject* args, PyObject* PyFloat_FromDouble(info.m_jointMaxVelocity)); if (info.m_linkName[0]) { - PyTuple_SetItem(pyListJointInfo, 12, PyString_FromString(info.m_linkName)); - } else + } + else { PyTuple_SetItem(pyListJointInfo, 12, PyString_FromString("not available")); @@ -3755,7 +3715,6 @@ static PyObject* pybullet_getJointInfo(PyObject* self, PyObject* args, PyObject* } PyTuple_SetItem(pyListJointInfo, 16, PyInt_FromLong(info.m_parentIndex)); - return pyListJointInfo; } else @@ -3878,7 +3837,7 @@ static PyObject* pybullet_getJointStates(PyObject* self, PyObject* args, PyObjec { PyObject* pyListJointForceTorque; PyObject* pyListJointState; - PyObject* jointIndicesObj=0; + PyObject* jointIndicesObj = 0; struct b3JointSensorState sensorState; @@ -3908,7 +3867,7 @@ static PyObject* pybullet_getJointStates(PyObject* self, PyObject* args, PyObjec int numRequestedJoints = 0; PyObject* jointIndicesSeq = 0; int numJoints = 0; - PyObject* resultListJointState=0; + PyObject* resultListJointState = 0; b3SharedMemoryCommandHandle cmd_handle; b3SharedMemoryStatusHandle status_handle; @@ -3918,24 +3877,22 @@ static PyObject* pybullet_getJointStates(PyObject* self, PyObject* args, PyObjec return NULL; } numJoints = b3GetNumJoints(sm, bodyUniqueId); - jointIndicesSeq = PySequence_Fast(jointIndicesObj, "expected a sequence of joint indices"); + jointIndicesSeq = PySequence_Fast(jointIndicesObj, "expected a sequence of joint indices"); - if (jointIndicesSeq==0) + if (jointIndicesSeq == 0) { PyErr_SetString(SpamError, "expected a sequence of joint indices"); return NULL; } numRequestedJoints = PySequence_Size(jointIndicesObj); - if (numRequestedJoints==0) + if (numRequestedJoints == 0) { Py_DECREF(jointIndicesSeq); Py_INCREF(Py_None); return Py_None; } - - cmd_handle = b3RequestActualStateCommandInit(sm, bodyUniqueId); status_handle = @@ -4021,7 +3978,7 @@ static PyObject* pybullet_getLinkState(PyObject* self, PyObject* args, PyObject* int physicsClientId = 0; static char* kwlist[] = {"bodyUniqueId", "linkIndex", "computeLinkVelocity", "computeForwardKinematics", "physicsClientId", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "ii|iii", kwlist, &bodyUniqueId, &linkIndex,&computeLinkVelocity,&computeForwardKinematics,&physicsClientId)) + if (!PyArg_ParseTupleAndKeywords(args, keywds, "ii|iii", kwlist, &bodyUniqueId, &linkIndex, &computeLinkVelocity, &computeForwardKinematics, &physicsClientId)) { return NULL; } @@ -4054,12 +4011,12 @@ static PyObject* pybullet_getLinkState(PyObject* self, PyObject* args, PyObject* if (computeLinkVelocity) { - b3RequestActualStateCommandComputeLinkVelocity(cmd_handle,computeLinkVelocity); + b3RequestActualStateCommandComputeLinkVelocity(cmd_handle, computeLinkVelocity); } if (computeForwardKinematics) { - b3RequestActualStateCommandComputeForwardKinematics(cmd_handle,computeForwardKinematics); + b3RequestActualStateCommandComputeForwardKinematics(cmd_handle, computeForwardKinematics); } status_handle = @@ -4116,12 +4073,11 @@ static PyObject* pybullet_getLinkState(PyObject* self, PyObject* args, PyObject* PyFloat_FromDouble(linkState.m_worldLinkFrameOrientation[i])); } - - if (computeLinkVelocity) { pyLinkState = PyTuple_New(8); - } else + } + else { pyLinkState = PyTuple_New(6); } @@ -4255,8 +4211,8 @@ static PyObject* pybullet_addUserDebugText(PyObject* self, PyObject* args, PyObj PyObject* textColorRGBObj = 0; PyObject* textOrientationObj = 0; double textOrientation[4]; - int parentObjectUniqueId=-1; - int parentLinkIndex=-1; + int parentObjectUniqueId = -1; + int parentLinkIndex = -1; double textSize = 1.f; double lifeTime = 0.f; @@ -4297,9 +4253,9 @@ static PyObject* pybullet_addUserDebugText(PyObject* self, PyObject* args, PyObj commandHandle = b3InitUserDebugDrawAddText3D(sm, text, posXYZ, colorRGB, textSize, lifeTime); - if (parentObjectUniqueId>=0) + if (parentObjectUniqueId >= 0) { - b3UserDebugItemSetParentObject(commandHandle, parentObjectUniqueId,parentLinkIndex); + b3UserDebugItemSetParentObject(commandHandle, parentObjectUniqueId, parentLinkIndex); } if (textOrientationObj) { @@ -4308,15 +4264,16 @@ static PyObject* pybullet_addUserDebugText(PyObject* self, PyObject* args, PyObj { PyErr_SetString(SpamError, "Error converting textOrientation[4]"); return NULL; - } else + } + else { - b3UserDebugTextSetOrientation(commandHandle,textOrientation); + b3UserDebugTextSetOrientation(commandHandle, textOrientation); } } - if (replaceItemUniqueId>=0) + if (replaceItemUniqueId >= 0) { - b3UserDebugItemSetReplaceItemUniqueId(commandHandle,replaceItemUniqueId); + b3UserDebugItemSetReplaceItemUniqueId(commandHandle, replaceItemUniqueId); } statusHandle = b3SubmitClientCommandAndWaitStatus(sm, commandHandle); @@ -4328,8 +4285,8 @@ static PyObject* pybullet_addUserDebugText(PyObject* self, PyObject* args, PyObj } { - PyObject* item = PyInt_FromLong(debugItemUniqueId); - return item; + PyObject* item = PyInt_FromLong(debugItemUniqueId); + return item; } } @@ -4343,8 +4300,8 @@ static PyObject* pybullet_addUserDebugLine(PyObject* self, PyObject* args, PyObj double fromXYZ[3]; double toXYZ[3]; double colorRGB[3] = {1, 1, 1}; - int parentObjectUniqueId=-1; - int parentLinkIndex=-1; + int parentObjectUniqueId = -1; + int parentLinkIndex = -1; PyObject* lineFromObj = 0; PyObject* lineToObj = 0; @@ -4386,17 +4343,16 @@ static PyObject* pybullet_addUserDebugLine(PyObject* self, PyObject* args, PyObj res = pybullet_internalSetVectord(lineColorRGBObj, colorRGB); } - commandHandle = b3InitUserDebugDrawAddLine3D(sm, fromXYZ, toXYZ, colorRGB, lineWidth, lifeTime); - if (parentObjectUniqueId>=0) + if (parentObjectUniqueId >= 0) { - b3UserDebugItemSetParentObject(commandHandle, parentObjectUniqueId,parentLinkIndex); + b3UserDebugItemSetParentObject(commandHandle, parentObjectUniqueId, parentLinkIndex); } - if (replaceItemUniqueId>=0) + if (replaceItemUniqueId >= 0) { - b3UserDebugItemSetReplaceItemUniqueId(commandHandle,replaceItemUniqueId); + b3UserDebugItemSetReplaceItemUniqueId(commandHandle, replaceItemUniqueId); } statusHandle = b3SubmitClientCommandAndWaitStatus(sm, commandHandle); @@ -4406,8 +4362,8 @@ static PyObject* pybullet_addUserDebugLine(PyObject* self, PyObject* args, PyObj debugItemUniqueId = b3GetDebugItemUniqueId(statusHandle); } { - PyObject* item = PyInt_FromLong(debugItemUniqueId); - return item; + PyObject* item = PyInt_FromLong(debugItemUniqueId); + return item; } } @@ -4546,12 +4502,12 @@ static PyObject* pybullet_startStateLogging(PyObject* self, PyObject* args, PyOb b3StateLoggingSetLinkIndexB(commandHandle, linkIndexB); } - if (deviceTypeFilter>=0) + if (deviceTypeFilter >= 0) { - b3StateLoggingSetDeviceTypeFilter(commandHandle,deviceTypeFilter); + b3StateLoggingSetDeviceTypeFilter(commandHandle, deviceTypeFilter); } - if (logFlags >0) + if (logFlags > 0) { b3StateLoggingSetLogFlags(commandHandle, logFlags); } @@ -4572,10 +4528,10 @@ static PyObject* pybullet_startStateLogging(PyObject* self, PyObject* args, PyOb static PyObject* pybullet_submitProfileTiming(PyObject* self, PyObject* args, PyObject* keywds) { -// b3SharedMemoryStatusHandle statusHandle; -// int statusType; + // b3SharedMemoryStatusHandle statusHandle; + // int statusType; char* eventName = 0; - int duractionInMicroSeconds=-1; + int duractionInMicroSeconds = -1; b3PhysicsClientHandle sm = 0; static char* kwlist[] = {"eventName ", "duraction", "physicsClientId", NULL}; @@ -4595,7 +4551,7 @@ static PyObject* pybullet_submitProfileTiming(PyObject* self, PyObject* args, Py { b3SharedMemoryCommandHandle commandHandle; commandHandle = b3ProfileTimingCommandInit(sm, eventName); - if (duractionInMicroSeconds>=0) + if (duractionInMicroSeconds >= 0) { b3SetProfileTimingDuractionInMicroSeconds(commandHandle, duractionInMicroSeconds); } @@ -4605,7 +4561,6 @@ static PyObject* pybullet_submitProfileTiming(PyObject* self, PyObject* args, Py return Py_None; } - static PyObject* pybullet_stopStateLogging(PyObject* self, PyObject* args, PyObject* keywds) { b3SharedMemoryStatusHandle statusHandle; @@ -4638,7 +4593,6 @@ static PyObject* pybullet_stopStateLogging(PyObject* self, PyObject* args, PyObj return Py_None; } - static PyObject* pybullet_setAdditionalSearchPath(PyObject* self, PyObject* args, PyObject* keywds) { static char* kwlist[] = {"path", "physicsClientId", NULL}; @@ -4789,7 +4743,6 @@ static PyObject* pybullet_rayTestBatch(PyObject* self, PyObject* args, PyObject* int sizeFrom = 0; int sizeTo = 0; - static char* kwlist[] = {"rayFromPositions", "rayToPositions", "numThreads", "physicsClientId", NULL}; int physicsClientId = 0; @@ -4804,12 +4757,9 @@ static PyObject* pybullet_rayTestBatch(PyObject* self, PyObject* args, PyObject* return NULL; } - - commandHandle = b3CreateRaycastBatchCommandInit(sm); b3RaycastBatchSetNumThreads(commandHandle, numThreads); - if (rayFromObjList) { PyObject* seqRayFromObj = PySequence_Fast(rayFromObjList, "expected a sequence of rayFrom positions"); @@ -4818,14 +4768,15 @@ static PyObject* pybullet_rayTestBatch(PyObject* self, PyObject* args, PyObject* if (seqRayFromObj && seqRayToObj) { int lenFrom = PySequence_Size(rayFromObjList); - int lenTo= PySequence_Size(seqRayToObj); - if (lenFrom!=lenTo) + int lenTo = PySequence_Size(seqRayToObj); + if (lenFrom != lenTo) { - PyErr_SetString(SpamError, "Size of from_positions need to be equal to size of to_positions."); - Py_DECREF(seqRayFromObj); - Py_DECREF(seqRayToObj); - return NULL; - } else + PyErr_SetString(SpamError, "Size of from_positions need to be equal to size of to_positions."); + Py_DECREF(seqRayFromObj); + Py_DECREF(seqRayToObj); + return NULL; + } + else { int i; @@ -4839,8 +4790,8 @@ static PyObject* pybullet_rayTestBatch(PyObject* self, PyObject* args, PyObject* b3PushProfileTiming(sm, "extractPythonFromToSequenceToC"); for (i = 0; i < lenFrom; i++) { - PyObject* rayFromObj = PySequence_GetItem(rayFromObjList,i); - PyObject* rayToObj = PySequence_GetItem(seqRayToObj,i); + PyObject* rayFromObj = PySequence_GetItem(rayFromObjList, i); + PyObject* rayToObj = PySequence_GetItem(seqRayToObj, i); double rayFromWorld[3]; double rayToWorld[3]; @@ -4849,8 +4800,9 @@ static PyObject* pybullet_rayTestBatch(PyObject* self, PyObject* args, PyObject* { //todo: better to upload all rays at once //b3RaycastBatchAddRay(commandHandle, rayFromWorld, rayToWorld); - b3RaycastBatchAddRays(sm, commandHandle, rayFromWorld, rayToWorld,1); - } else + b3RaycastBatchAddRays(sm, commandHandle, rayFromWorld, rayToWorld, 1); + } + else { PyErr_SetString(SpamError, "Items in the from/to positions need to be an [x,y,z] list of 3 floats/doubles"); Py_DECREF(seqRayFromObj); @@ -4865,9 +4817,9 @@ static PyObject* pybullet_rayTestBatch(PyObject* self, PyObject* args, PyObject* } b3PopProfileTiming(sm); } - } else + } + else { - } if (seqRayFromObj) { @@ -4939,15 +4891,14 @@ static PyObject* pybullet_getMatrixFromQuaternion(PyObject* self, PyObject* args { PyObject* quatObj; double quat[4]; - int physicsClientId=0; - static char* kwlist[] = {"quaternion","physicsClientId", NULL}; + int physicsClientId = 0; + static char* kwlist[] = {"quaternion", "physicsClientId", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|i", kwlist, &quatObj,&physicsClientId)) + if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|i", kwlist, &quatObj, &physicsClientId)) { return NULL; } - if (quatObj) { if (pybullet_internalSetVector4d(quatObj, quat)) @@ -4990,8 +4941,8 @@ static PyObject* pybullet_setVRCameraState(PyObject* self, PyObject* args, PyObj double rootPos[3]; double rootOrn[4]; - static char* kwlist[] = {"rootPosition", "rootOrientation", "trackObject", "trackObjectFlag","physicsClientId", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "|OOiii", kwlist, &rootPosObj, &rootOrnObj, &trackObjectUid,&trackObjectFlag, &physicsClientId)) + static char* kwlist[] = {"rootPosition", "rootOrientation", "trackObject", "trackObjectFlag", "physicsClientId", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, keywds, "|OOiii", kwlist, &rootPosObj, &rootOrnObj, &trackObjectUid, &trackObjectFlag, &physicsClientId)) { return NULL; } @@ -5018,7 +4969,7 @@ static PyObject* pybullet_setVRCameraState(PyObject* self, PyObject* args, PyObj b3SetVRCameraTrackingObject(commandHandle, trackObjectUid); } - if (trackObjectFlag>=-1) + if (trackObjectFlag >= -1) { b3SetVRCameraTrackingObjectFlag(commandHandle, trackObjectFlag); } @@ -5098,19 +5049,16 @@ static PyObject* pybullet_getMouseEvents(PyObject* self, PyObject* args, PyObjec for (i = 0; i < mouseEventsData.m_numMouseEvents; i++) { PyObject* mouseEventObj = PyTuple_New(5); - PyTuple_SetItem(mouseEventObj,0, PyInt_FromLong(mouseEventsData.m_mouseEvents[i].m_eventType)); - PyTuple_SetItem(mouseEventObj,1, PyFloat_FromDouble(mouseEventsData.m_mouseEvents[i].m_mousePosX)); - PyTuple_SetItem(mouseEventObj,2, PyFloat_FromDouble(mouseEventsData.m_mouseEvents[i].m_mousePosY)); - PyTuple_SetItem(mouseEventObj,3, PyInt_FromLong(mouseEventsData.m_mouseEvents[i].m_buttonIndex)); - PyTuple_SetItem(mouseEventObj,4, PyInt_FromLong(mouseEventsData.m_mouseEvents[i].m_buttonState)); - PyTuple_SetItem(mouseEventsObj,i,mouseEventObj); - + PyTuple_SetItem(mouseEventObj, 0, PyInt_FromLong(mouseEventsData.m_mouseEvents[i].m_eventType)); + PyTuple_SetItem(mouseEventObj, 1, PyFloat_FromDouble(mouseEventsData.m_mouseEvents[i].m_mousePosX)); + PyTuple_SetItem(mouseEventObj, 2, PyFloat_FromDouble(mouseEventsData.m_mouseEvents[i].m_mousePosY)); + PyTuple_SetItem(mouseEventObj, 3, PyInt_FromLong(mouseEventsData.m_mouseEvents[i].m_buttonIndex)); + PyTuple_SetItem(mouseEventObj, 4, PyInt_FromLong(mouseEventsData.m_mouseEvents[i].m_buttonState)); + PyTuple_SetItem(mouseEventsObj, i, mouseEventObj); } return mouseEventsObj; } - - static PyObject* pybullet_getVREvents(PyObject* self, PyObject* args, PyObject* keywds) { b3SharedMemoryCommandHandle commandHandle; @@ -5149,7 +5097,7 @@ static PyObject* pybullet_getVREvents(PyObject* self, PyObject* args, PyObject* vrEventsObj = PyTuple_New(vrEvents.m_numControllerEvents); for (i = 0; i < vrEvents.m_numControllerEvents; i++) { - int numFields = allAnalogAxes? 9 : 8; + int numFields = allAnalogAxes ? 9 : 8; PyObject* vrEventObj = PyTuple_New(numFields); PyTuple_SetItem(vrEventObj, 0, PyInt_FromLong(vrEvents.m_controllerEvents[i].m_controllerId)); @@ -5186,9 +5134,9 @@ static PyObject* pybullet_getVREvents(PyObject* self, PyObject* args, PyObject* if (allAnalogAxes) { - PyObject* buttonsObj = PyTuple_New(MAX_VR_ANALOG_AXIS*2); + PyObject* buttonsObj = PyTuple_New(MAX_VR_ANALOG_AXIS * 2); int b; - for (b = 0; b < MAX_VR_ANALOG_AXIS*2; b++) + for (b = 0; b < MAX_VR_ANALOG_AXIS * 2; b++) { PyObject* axisVal = PyFloat_FromDouble(vrEvents.m_controllerEvents[i].m_auxAnalogAxis[b]); PyTuple_SetItem(buttonsObj, b, axisVal); @@ -5207,7 +5155,6 @@ static PyObject* pybullet_getVREvents(PyObject* self, PyObject* args, PyObject* static PyObject* pybullet_getDebugVisualizerCamera(PyObject* self, PyObject* args, PyObject* keywds) { - int physicsClientId = 0; b3PhysicsClientHandle sm = 0; static char* kwlist[] = {"physicsClientId", NULL}; @@ -5215,7 +5162,7 @@ static PyObject* pybullet_getDebugVisualizerCamera(PyObject* self, PyObject* arg int hasCamInfo; b3SharedMemoryStatusHandle statusHandle; struct b3OpenGLVisualizerCameraInfo camera; - PyObject* pyCameraList =0; + PyObject* pyCameraList = 0; sm = getPhysicsClient(physicsClientId); if (sm == 0) @@ -5227,77 +5174,76 @@ static PyObject* pybullet_getDebugVisualizerCamera(PyObject* self, PyObject* arg commandHandle = b3InitRequestOpenGLVisualizerCameraCommand(sm); statusHandle = b3SubmitClientCommandAndWaitStatus(sm, commandHandle); - hasCamInfo = b3GetStatusOpenGLVisualizerCamera(statusHandle, &camera); + hasCamInfo = b3GetStatusOpenGLVisualizerCamera(statusHandle, &camera); if (hasCamInfo) { - PyObject* item=0; + PyObject* item = 0; pyCameraList = PyTuple_New(12); item = PyInt_FromLong(camera.m_width); - PyTuple_SetItem(pyCameraList,0,item); + PyTuple_SetItem(pyCameraList, 0, item); item = PyInt_FromLong(camera.m_height); - PyTuple_SetItem(pyCameraList,1,item); + PyTuple_SetItem(pyCameraList, 1, item); { PyObject* viewMat16 = PyTuple_New(16); PyObject* projMat16 = PyTuple_New(16); int i; - for (i=0;i<16;i++) + for (i = 0; i < 16; i++) { item = PyFloat_FromDouble(camera.m_viewMatrix[i]); - PyTuple_SetItem(viewMat16,i,item); + PyTuple_SetItem(viewMat16, i, item); item = PyFloat_FromDouble(camera.m_projectionMatrix[i]); - PyTuple_SetItem(projMat16,i,item); + PyTuple_SetItem(projMat16, i, item); } - PyTuple_SetItem(pyCameraList,2,viewMat16); - PyTuple_SetItem(pyCameraList,3,projMat16); + PyTuple_SetItem(pyCameraList, 2, viewMat16); + PyTuple_SetItem(pyCameraList, 3, projMat16); } { - PyObject* item=0; + PyObject* item = 0; int i; PyObject* camUp = PyTuple_New(3); PyObject* camFwd = PyTuple_New(3); PyObject* hor = PyTuple_New(3); - PyObject* vert= PyTuple_New(3); - for (i=0;i<3;i++) + PyObject* vert = PyTuple_New(3); + for (i = 0; i < 3; i++) { item = PyFloat_FromDouble(camera.m_camUp[i]); - PyTuple_SetItem(camUp,i,item); + PyTuple_SetItem(camUp, i, item); item = PyFloat_FromDouble(camera.m_camForward[i]); - PyTuple_SetItem(camFwd,i,item); + PyTuple_SetItem(camFwd, i, item); item = PyFloat_FromDouble(camera.m_horizontal[i]); - PyTuple_SetItem(hor,i,item); + PyTuple_SetItem(hor, i, item); item = PyFloat_FromDouble(camera.m_vertical[i]); - PyTuple_SetItem(vert,i,item); + PyTuple_SetItem(vert, i, item); } - PyTuple_SetItem(pyCameraList,4,camUp); - PyTuple_SetItem(pyCameraList,5,camFwd); - PyTuple_SetItem(pyCameraList,6,hor); - PyTuple_SetItem(pyCameraList,7,vert); + PyTuple_SetItem(pyCameraList, 4, camUp); + PyTuple_SetItem(pyCameraList, 5, camFwd); + PyTuple_SetItem(pyCameraList, 6, hor); + PyTuple_SetItem(pyCameraList, 7, vert); } item = PyFloat_FromDouble(camera.m_yaw); - PyTuple_SetItem(pyCameraList,8,item); + PyTuple_SetItem(pyCameraList, 8, item); item = PyFloat_FromDouble(camera.m_pitch); - PyTuple_SetItem(pyCameraList,9,item); + PyTuple_SetItem(pyCameraList, 9, item); item = PyFloat_FromDouble(camera.m_dist); - PyTuple_SetItem(pyCameraList,10,item); + PyTuple_SetItem(pyCameraList, 10, item); { - PyObject* item=0; + PyObject* item = 0; int i; PyObject* camTarget = PyTuple_New(3); - for (i=0;i<3;i++) + for (i = 0; i < 3; i++) { item = PyFloat_FromDouble(camera.m_target[i]); - PyTuple_SetItem(camTarget,i,item); + PyTuple_SetItem(camTarget, i, item); } - PyTuple_SetItem(pyCameraList,11,camTarget); + PyTuple_SetItem(pyCameraList, 11, camTarget); } return pyCameraList; } PyErr_SetString(SpamError, "Cannot get OpenGL visualizer camera info."); return NULL; - } static PyObject* pybullet_configureDebugVisualizer(PyObject* self, PyObject* args, PyObject* keywds) @@ -5420,7 +5366,7 @@ static PyObject* pybullet_getCollisionShapeData(PyObject* self, PyObject* args, PyObject* pyResultList = 0; int physicsClientId = 0; b3PhysicsClientHandle sm = 0; - static char* kwlist[] = { "objectUniqueId", "linkIndex", "physicsClientId", NULL }; + static char* kwlist[] = {"objectUniqueId", "linkIndex", "physicsClientId", NULL}; if (!PyArg_ParseTupleAndKeywords(args, keywds, "ii|i", kwlist, &objectUniqueId, &linkIndex, &physicsClientId)) { return NULL; @@ -5492,7 +5438,6 @@ static PyObject* pybullet_getCollisionShapeData(PyObject* self, PyObject* args, PyTuple_SetItem(collisionShapeObList, 6, vec); } - PyTuple_SetItem(pyResultList, i, collisionShapeObList); } return pyResultList; @@ -5508,7 +5453,6 @@ static PyObject* pybullet_getCollisionShapeData(PyObject* self, PyObject* args, return Py_None; } - static PyObject* pybullet_getVisualShapeData(PyObject* self, PyObject* args, PyObject* keywds) { int objectUniqueId = -1; @@ -5520,7 +5464,7 @@ static PyObject* pybullet_getVisualShapeData(PyObject* self, PyObject* args, PyO PyObject* pyResultList = 0; int physicsClientId = 0; b3PhysicsClientHandle sm = 0; - int flags=0; + int flags = 0; static char* kwlist[] = {"objectUniqueId", "flags", "physicsClientId", NULL}; if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|ii", kwlist, &objectUniqueId, &flags, &physicsClientId)) @@ -5544,7 +5488,7 @@ static PyObject* pybullet_getVisualShapeData(PyObject* self, PyObject* args, PyO pyResultList = PyTuple_New(visualShapeInfo.m_numVisualShapes); for (i = 0; i < visualShapeInfo.m_numVisualShapes; i++) { - int numFields = flags&eVISUAL_SHAPE_DATA_TEXTURE_UNIQUE_IDS ? 9 : 8; + int numFields = flags & eVISUAL_SHAPE_DATA_TEXTURE_UNIQUE_IDS ? 9 : 8; PyObject* visualShapeObList = PyTuple_New(numFields); PyObject* item; @@ -5607,10 +5551,10 @@ static PyObject* pybullet_getVisualShapeData(PyObject* self, PyObject* args, PyO PyTuple_SetItem(rgba, 3, item); PyTuple_SetItem(visualShapeObList, 7, rgba); } - if (flags&eVISUAL_SHAPE_DATA_TEXTURE_UNIQUE_IDS) + if (flags & eVISUAL_SHAPE_DATA_TEXTURE_UNIQUE_IDS) { item = PyInt_FromLong(visualShapeInfo.m_visualShapeData[i].m_textureUniqueId); - PyTuple_SetItem(visualShapeObList, 8, item); + PyTuple_SetItem(visualShapeObList, 8, item); } PyTuple_SetItem(pyResultList, i, visualShapeObList); @@ -5641,8 +5585,6 @@ static PyObject* pybullet_changeVisualShape(PyObject* self, PyObject* args, PyOb PyObject* rgbaColorObj = 0; PyObject* specularColorObj = 0; - - b3PhysicsClientHandle sm = 0; static char* kwlist[] = {"objectUniqueId", "linkIndex", "shapeIndex", "textureUniqueId", "rgbaColor", "specularColor", "physicsClientId", NULL}; if (!PyArg_ParseTupleAndKeywords(args, keywds, "ii|iiOOi", kwlist, &objectUniqueId, &jointIndex, &shapeIndex, &textureUniqueId, &rgbaColorObj, &specularColorObj, &physicsClientId)) @@ -5661,17 +5603,16 @@ static PyObject* pybullet_changeVisualShape(PyObject* self, PyObject* args, PyOb if (specularColorObj) { - double specularColor[3] = {1,1,1}; + double specularColor[3] = {1, 1, 1}; pybullet_internalSetVectord(specularColorObj, specularColor); - b3UpdateVisualShapeSpecularColor(commandHandle,specularColor); - + b3UpdateVisualShapeSpecularColor(commandHandle, specularColor); } if (rgbaColorObj) { - double rgbaColor[4] = {1,1,1,1}; + double rgbaColor[4] = {1, 1, 1, 1}; pybullet_internalSetVector4d(rgbaColorObj, rgbaColor); - b3UpdateVisualShapeRGBAColor(commandHandle,rgbaColor); + b3UpdateVisualShapeRGBAColor(commandHandle, rgbaColor); } statusHandle = b3SubmitClientCommandAndWaitStatus(sm, commandHandle); @@ -5690,16 +5631,15 @@ static PyObject* pybullet_changeVisualShape(PyObject* self, PyObject* args, PyOb return Py_None; } - static PyObject* pybullet_changeTexture(PyObject* self, PyObject* args, PyObject* keywds) { b3SharedMemoryCommandHandle commandHandle = 0; - b3SharedMemoryStatusHandle statusHandle=0; + b3SharedMemoryStatusHandle statusHandle = 0; int statusType = -1; int textureUniqueId = -1; int physicsClientId = 0; - int width=-1; - int height=-1; + int width = -1; + int height = -1; PyObject* pixelsObj = 0; @@ -5716,30 +5656,31 @@ static PyObject* pybullet_changeTexture(PyObject* self, PyObject* args, PyObject return NULL; } - if (textureUniqueId>=0 && width>=0 && height>=0 && pixelsObj) + if (textureUniqueId >= 0 && width >= 0 && height >= 0 && pixelsObj) { PyObject* seqPixels = PySequence_Fast(pixelsObj, "expected a sequence"); PyObject* item; int i; - int numPixels = width*height; - unsigned char* pixelBuffer = (unsigned char*) malloc (numPixels*3); + int numPixels = width * height; + unsigned char* pixelBuffer = (unsigned char*)malloc(numPixels * 3); if (PyList_Check(seqPixels)) { - for (i=0;i=0) + if (bodyUniqueIdA >= 0) { b3SetClosestDistanceFilterBodyA(commandHandle, bodyUniqueIdA); } - if (bodyUniqueIdB>=0) + if (bodyUniqueIdB >= 0) { b3SetClosestDistanceFilterBodyB(commandHandle, bodyUniqueIdB); } @@ -6091,32 +6029,32 @@ static PyObject* pybullet_getClosestPointData(PyObject* self, PyObject* args, Py { b3SetClosestDistanceFilterLinkB(commandHandle, linkIndexB); } - if (collisionShapeA>=0) + if (collisionShapeA >= 0) { b3SetClosestDistanceFilterCollisionShapeA(commandHandle, collisionShapeA); } - if (collisionShapeB>=0) + if (collisionShapeB >= 0) { b3SetClosestDistanceFilterCollisionShapeB(commandHandle, collisionShapeB); } if (collisionShapePositionAObj) { - pybullet_internalSetVectord(collisionShapePositionAObj,collisionShapePositionA); + pybullet_internalSetVectord(collisionShapePositionAObj, collisionShapePositionA); b3SetClosestDistanceFilterCollisionShapePositionA(commandHandle, collisionShapePositionA); } if (collisionShapePositionBObj) { - pybullet_internalSetVectord(collisionShapePositionBObj,collisionShapePositionB); + pybullet_internalSetVectord(collisionShapePositionBObj, collisionShapePositionB); b3SetClosestDistanceFilterCollisionShapePositionB(commandHandle, collisionShapePositionB); } if (collisionShapeOrientationAObj) { - pybullet_internalSetVector4d(collisionShapeOrientationAObj,collisionShapeOrientationA); + pybullet_internalSetVector4d(collisionShapeOrientationAObj, collisionShapeOrientationA); b3SetClosestDistanceFilterCollisionShapeOrientationA(commandHandle, collisionShapeOrientationA); } if (collisionShapeOrientationBObj) { - pybullet_internalSetVector4d(collisionShapeOrientationBObj,collisionShapeOrientationB); + pybullet_internalSetVector4d(collisionShapeOrientationBObj, collisionShapeOrientationB); b3SetClosestDistanceFilterCollisionShapeOrientationB(commandHandle, collisionShapeOrientationB); } @@ -6149,8 +6087,8 @@ static PyObject* pybullet_changeUserConstraint(PyObject* self, PyObject* args, P double jointChildFrameOrn[4]; double maxForce = -1; double gearRatio = 0; - double relativePositionTarget=1e32; - double erp=-1; + double relativePositionTarget = 1e32; + double erp = -1; if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|OOddiddi", kwlist, &userConstraintUniqueId, &jointChildPivotObj, &jointChildFrameOrnObj, &maxForce, &gearRatio, &gearAuxLink, &relativePositionTarget, &erp, &physicsClientId)) { return NULL; @@ -6175,11 +6113,11 @@ static PyObject* pybullet_changeUserConstraint(PyObject* self, PyObject* args, P b3InitChangeUserConstraintSetFrameInB(commandHandle, jointChildFrameOrn); } - if (relativePositionTarget<1e10) + if (relativePositionTarget < 1e10) { b3InitChangeUserConstraintSetRelativePositionTarget(commandHandle, relativePositionTarget); } - if (erp>=0) + if (erp >= 0) { b3InitChangeUserConstraintSetERP(commandHandle, erp); } @@ -6188,13 +6126,13 @@ static PyObject* pybullet_changeUserConstraint(PyObject* self, PyObject* args, P { b3InitChangeUserConstraintSetMaxForce(commandHandle, maxForce); } - if (gearRatio!=0) + if (gearRatio != 0) { - b3InitChangeUserConstraintSetGearRatio(commandHandle,gearRatio); + b3InitChangeUserConstraintSetGearRatio(commandHandle, gearRatio); } - if (gearAuxLink>=0) + if (gearAuxLink >= 0) { - b3InitChangeUserConstraintSetGearAuxLink(commandHandle,gearAuxLink); + b3InitChangeUserConstraintSetGearAuxLink(commandHandle, gearAuxLink); } statusHandle = b3SubmitClientCommandAndWaitStatus(sm, commandHandle); statusType = b3GetStatusType(statusHandle); @@ -6246,7 +6184,7 @@ static PyObject* pybullet_enableJointForceTorqueSensor(PyObject* self, PyObject* b3PhysicsClientHandle sm = 0; int numJoints = -1; - static char* kwlist[] = {"bodyUniqueId", "jointIndex", "enableSensor", "physicsClientId",NULL}; + static char* kwlist[] = {"bodyUniqueId", "jointIndex", "enableSensor", "physicsClientId", NULL}; if (!PyArg_ParseTupleAndKeywords(args, keywds, "ii|ii", kwlist, &bodyUniqueId, &jointIndex, &enableSensor, &physicsClientId)) { @@ -6296,25 +6234,25 @@ static PyObject* pybullet_createCollisionShape(PyObject* self, PyObject* args, P { int physicsClientId = 0; b3PhysicsClientHandle sm = 0; - int shapeType=-1; - double radius=0.5; + int shapeType = -1; + double radius = 0.5; double height = 1; - PyObject* meshScaleObj=0; - double meshScale[3] = {1,1,1}; - PyObject* planeNormalObj=0; - double planeNormal[3] = {0,0,1}; - PyObject* collisionFramePositionObj=0; - double collisionFramePosition[3]={0,0,0}; - PyObject* collisionFrameOrientationObj=0; - double collisionFrameOrientation[4]={0,0,0,1}; - char* fileName=0; + PyObject* meshScaleObj = 0; + double meshScale[3] = {1, 1, 1}; + PyObject* planeNormalObj = 0; + double planeNormal[3] = {0, 0, 1}; + PyObject* collisionFramePositionObj = 0; + double collisionFramePosition[3] = {0, 0, 0}; + PyObject* collisionFrameOrientationObj = 0; + double collisionFrameOrientation[4] = {0, 0, 0, 1}; + char* fileName = 0; int flags = 0; - PyObject* halfExtentsObj=0; + PyObject* halfExtentsObj = 0; - static char* kwlist[] = {"shapeType","radius","halfExtents", "height", "fileName", "meshScale", "planeNormal", "flags", "collisionFramePosition", "collisionFrameOrientation", "physicsClientId", NULL}; + static char* kwlist[] = {"shapeType", "radius", "halfExtents", "height", "fileName", "meshScale", "planeNormal", "flags", "collisionFramePosition", "collisionFrameOrientation", "physicsClientId", NULL}; if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|dOdsOOiOOi", kwlist, - &shapeType, &radius,&halfExtentsObj, &height, &fileName, &meshScaleObj, &planeNormalObj, &flags,&collisionFramePositionObj, &collisionFrameOrientationObj, &physicsClientId)) + &shapeType, &radius, &halfExtentsObj, &height, &fileName, &meshScaleObj, &planeNormalObj, &flags, &collisionFramePositionObj, &collisionFrameOrientationObj, &physicsClientId)) { return NULL; } @@ -6324,59 +6262,58 @@ static PyObject* pybullet_createCollisionShape(PyObject* self, PyObject* args, P PyErr_SetString(SpamError, "Not connected to physics server."); return NULL; } - if (shapeType>=GEOM_SPHERE) + if (shapeType >= GEOM_SPHERE) { b3SharedMemoryStatusHandle statusHandle; int statusType; int shapeIndex = -1; b3SharedMemoryCommandHandle commandHandle = b3CreateCollisionShapeCommandInit(sm); - if (shapeType==GEOM_SPHERE && radius>0) + if (shapeType == GEOM_SPHERE && radius > 0) { - shapeIndex = b3CreateCollisionShapeAddSphere(commandHandle,radius); + shapeIndex = b3CreateCollisionShapeAddSphere(commandHandle, radius); } - if (shapeType==GEOM_BOX && halfExtentsObj) + if (shapeType == GEOM_BOX && halfExtentsObj) { - double halfExtents[3] = {1,1,1}; - pybullet_internalSetVectord(halfExtentsObj,halfExtents); - shapeIndex = b3CreateCollisionShapeAddBox(commandHandle,halfExtents); + double halfExtents[3] = {1, 1, 1}; + pybullet_internalSetVectord(halfExtentsObj, halfExtents); + shapeIndex = b3CreateCollisionShapeAddBox(commandHandle, halfExtents); } - if (shapeType==GEOM_CAPSULE && radius>0 && height>=0) + if (shapeType == GEOM_CAPSULE && radius > 0 && height >= 0) { - shapeIndex = b3CreateCollisionShapeAddCapsule(commandHandle,radius,height); + shapeIndex = b3CreateCollisionShapeAddCapsule(commandHandle, radius, height); } - if (shapeType==GEOM_CYLINDER && radius>0 && height>=0) + if (shapeType == GEOM_CYLINDER && radius > 0 && height >= 0) { - shapeIndex = b3CreateCollisionShapeAddCylinder(commandHandle,radius,height); + shapeIndex = b3CreateCollisionShapeAddCylinder(commandHandle, radius, height); } - if (shapeType==GEOM_MESH && fileName) + if (shapeType == GEOM_MESH && fileName) { - pybullet_internalSetVectord(meshScaleObj,meshScale); - shapeIndex = b3CreateCollisionShapeAddMesh(commandHandle, fileName,meshScale); + pybullet_internalSetVectord(meshScaleObj, meshScale); + shapeIndex = b3CreateCollisionShapeAddMesh(commandHandle, fileName, meshScale); } - if (shapeType==GEOM_PLANE) + if (shapeType == GEOM_PLANE) { - double planeConstant=0; - pybullet_internalSetVectord(planeNormalObj,planeNormal); + double planeConstant = 0; + pybullet_internalSetVectord(planeNormalObj, planeNormal); shapeIndex = b3CreateCollisionShapeAddPlane(commandHandle, planeNormal, planeConstant); } - if (shapeIndex>=0 && flags) + if (shapeIndex >= 0 && flags) { - b3CreateCollisionSetFlag(commandHandle,shapeIndex,flags); + b3CreateCollisionSetFlag(commandHandle, shapeIndex, flags); } - if (shapeIndex>=0) + if (shapeIndex >= 0) { if (collisionFramePositionObj) { - pybullet_internalSetVectord(collisionFramePositionObj,collisionFramePosition); + pybullet_internalSetVectord(collisionFramePositionObj, collisionFramePosition); } if (collisionFrameOrientationObj) { - pybullet_internalSetVector4d(collisionFrameOrientationObj,collisionFrameOrientation); + pybullet_internalSetVector4d(collisionFrameOrientationObj, collisionFrameOrientation); } - b3CreateVisualShapeSetChildTransform(commandHandle, shapeIndex, collisionFramePosition,collisionFrameOrientation); - + b3CreateVisualShapeSetChildTransform(commandHandle, shapeIndex, collisionFramePosition, collisionFrameOrientation); } statusHandle = b3SubmitClientCommandAndWaitStatus(sm, commandHandle); statusType = b3GetStatusType(statusHandle); @@ -6409,10 +6346,10 @@ static PyObject* pybullet_createCollisionShapeArray(PyObject* self, PyObject* ar PyObject* collisionFramePositionObjArray = 0; PyObject* collisionFrameOrientationObjArray = 0; - static char* kwlist[] = { "shapeTypes", "radii", "halfExtents", "lengths", "fileNames", "meshScales", "planeNormals", - "flags", "collisionFramePositions", "collisionFrameOrientations", "physicsClientId", NULL }; + static char* kwlist[] = {"shapeTypes", "radii", "halfExtents", "lengths", "fileNames", "meshScales", "planeNormals", + "flags", "collisionFramePositions", "collisionFrameOrientations", "physicsClientId", NULL}; if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|OOOOOOOOOi", kwlist, - &shapeTypeArray, &radiusArray, &halfExtentsObjArray, &lengthArray, &fileNameArray, &meshScaleObjArray, &planeNormalObjArray, &flagsArray, &collisionFramePositionObjArray, &collisionFrameOrientationObjArray, &physicsClientId)) + &shapeTypeArray, &radiusArray, &halfExtentsObjArray, &lengthArray, &fileNameArray, &meshScaleObjArray, &planeNormalObjArray, &flagsArray, &collisionFramePositionObjArray, &collisionFrameOrientationObjArray, &physicsClientId)) { return NULL; } @@ -6423,9 +6360,6 @@ static PyObject* pybullet_createCollisionShapeArray(PyObject* self, PyObject* ar return NULL; } - - - { b3SharedMemoryCommandHandle commandHandle = b3CreateCollisionShapeCommandInit(sm); int numShapeTypes = 0; @@ -6440,16 +6374,16 @@ static PyObject* pybullet_createCollisionShapeArray(PyObject* self, PyObject* ar int numOrientations = 0; int s; - PyObject* shapeTypeArraySeq = shapeTypeArray?PySequence_Fast(shapeTypeArray, "expected a sequence of shape types"):0; - PyObject* radiusArraySeq = radiusArray?PySequence_Fast(radiusArray, "expected a sequence of radii"):0; - PyObject* halfExtentsArraySeq = halfExtentsObjArray?PySequence_Fast(halfExtentsObjArray, "expected a sequence of half extents"):0; - PyObject* lengthArraySeq = lengthArray ?PySequence_Fast(lengthArray, "expected a sequence of lengths"):0; - PyObject* fileNameArraySeq = fileNameArray?PySequence_Fast(fileNameArray, "expected a sequence of filename"):0; - PyObject* meshScaleArraySeq = meshScaleObjArray?PySequence_Fast(meshScaleObjArray, "expected a sequence of mesh scale"):0; - PyObject* planeNormalArraySeq = planeNormalObjArray?PySequence_Fast(planeNormalObjArray, "expected a sequence of plane normal"):0; - PyObject* flagsArraySeq = flagsArray?PySequence_Fast(flagsArray, "expected a sequence of flags"):0; - PyObject* positionArraySeq = collisionFramePositionObjArray?PySequence_Fast(collisionFramePositionObjArray, "expected a sequence of collision frame positions"):0; - PyObject* orientationArraySeq = collisionFrameOrientationObjArray?PySequence_Fast(collisionFrameOrientationObjArray, "expected a sequence of collision frame orientations"):0; + PyObject* shapeTypeArraySeq = shapeTypeArray ? PySequence_Fast(shapeTypeArray, "expected a sequence of shape types") : 0; + PyObject* radiusArraySeq = radiusArray ? PySequence_Fast(radiusArray, "expected a sequence of radii") : 0; + PyObject* halfExtentsArraySeq = halfExtentsObjArray ? PySequence_Fast(halfExtentsObjArray, "expected a sequence of half extents") : 0; + PyObject* lengthArraySeq = lengthArray ? PySequence_Fast(lengthArray, "expected a sequence of lengths") : 0; + PyObject* fileNameArraySeq = fileNameArray ? PySequence_Fast(fileNameArray, "expected a sequence of filename") : 0; + PyObject* meshScaleArraySeq = meshScaleObjArray ? PySequence_Fast(meshScaleObjArray, "expected a sequence of mesh scale") : 0; + PyObject* planeNormalArraySeq = planeNormalObjArray ? PySequence_Fast(planeNormalObjArray, "expected a sequence of plane normal") : 0; + PyObject* flagsArraySeq = flagsArray ? PySequence_Fast(flagsArray, "expected a sequence of flags") : 0; + PyObject* positionArraySeq = collisionFramePositionObjArray ? PySequence_Fast(collisionFramePositionObjArray, "expected a sequence of collision frame positions") : 0; + PyObject* orientationArraySeq = collisionFrameOrientationObjArray ? PySequence_Fast(collisionFrameOrientationObjArray, "expected a sequence of collision frame orientations") : 0; if (shapeTypeArraySeq == 0) { @@ -6457,20 +6391,19 @@ static PyObject* pybullet_createCollisionShapeArray(PyObject* self, PyObject* ar return NULL; } - numShapeTypes = shapeTypeArray?PySequence_Size(shapeTypeArray):0; - numRadius = radiusArraySeq?PySequence_Size(radiusArraySeq):0; - numHalfExtents = halfExtentsArraySeq?PySequence_Size(halfExtentsArraySeq):0; - numLengths = lengthArraySeq?PySequence_Size(lengthArraySeq):0; - numFileNames = fileNameArraySeq?PySequence_Size(fileNameArraySeq):0; - numMeshScales = meshScaleArraySeq?PySequence_Size(meshScaleArraySeq):0; - numPlaneNormals = planeNormalArraySeq?PySequence_Size(planeNormalArraySeq):0; + numShapeTypes = shapeTypeArray ? PySequence_Size(shapeTypeArray) : 0; + numRadius = radiusArraySeq ? PySequence_Size(radiusArraySeq) : 0; + numHalfExtents = halfExtentsArraySeq ? PySequence_Size(halfExtentsArraySeq) : 0; + numLengths = lengthArraySeq ? PySequence_Size(lengthArraySeq) : 0; + numFileNames = fileNameArraySeq ? PySequence_Size(fileNameArraySeq) : 0; + numMeshScales = meshScaleArraySeq ? PySequence_Size(meshScaleArraySeq) : 0; + numPlaneNormals = planeNormalArraySeq ? PySequence_Size(planeNormalArraySeq) : 0; - for (s=0;s= GEOM_SPHERE) { - int shapeIndex = -1; if (shapeType == GEOM_SPHERE && s <= numRadius) @@ -6484,9 +6417,9 @@ static PyObject* pybullet_createCollisionShapeArray(PyObject* self, PyObject* ar if (shapeType == GEOM_BOX) { PyObject* halfExtentsObj = 0; - double halfExtents[3] = { 1, 1, 1 }; + double halfExtents[3] = {1, 1, 1}; - if (halfExtentsArraySeq && s<= numHalfExtents) + if (halfExtentsArraySeq && s <= numHalfExtents) { if (PyList_Check(halfExtentsArraySeq)) { @@ -6500,7 +6433,7 @@ static PyObject* pybullet_createCollisionShapeArray(PyObject* self, PyObject* ar pybullet_internalSetVectord(halfExtentsObj, halfExtents); shapeIndex = b3CreateCollisionShapeAddBox(commandHandle, halfExtents); } - if (shapeType == GEOM_CAPSULE && s<=numRadius) + if (shapeType == GEOM_CAPSULE && s <= numRadius) { double radius = pybullet_internalGetFloatFromSequence(radiusArraySeq, s); double height = pybullet_internalGetFloatFromSequence(lengthArraySeq, s); @@ -6509,7 +6442,7 @@ static PyObject* pybullet_createCollisionShapeArray(PyObject* self, PyObject* ar shapeIndex = b3CreateCollisionShapeAddCapsule(commandHandle, radius, height); } } - if (shapeType == GEOM_CYLINDER && s <= numRadius && s=GEOM_SPHERE) + if (shapeType >= GEOM_SPHERE) { b3SharedMemoryStatusHandle statusHandle; int statusType; b3SharedMemoryCommandHandle commandHandle = b3CreateVisualShapeCommandInit(sm); int shapeIndex = -1; - if (shapeType==GEOM_SPHERE && radius>0) + if (shapeType == GEOM_SPHERE && radius > 0) { - shapeIndex = b3CreateVisualShapeAddSphere(commandHandle,radius); + shapeIndex = b3CreateVisualShapeAddSphere(commandHandle, radius); } - if (shapeType==GEOM_BOX && halfExtentsObj) + if (shapeType == GEOM_BOX && halfExtentsObj) { - double halfExtents[3] = {1,1,1}; - pybullet_internalSetVectord(halfExtentsObj,halfExtents); - shapeIndex = b3CreateVisualShapeAddBox(commandHandle,halfExtents); + double halfExtents[3] = {1, 1, 1}; + pybullet_internalSetVectord(halfExtentsObj, halfExtents); + shapeIndex = b3CreateVisualShapeAddBox(commandHandle, halfExtents); } - if (shapeType==GEOM_CAPSULE && radius>0 && length>=0) + if (shapeType == GEOM_CAPSULE && radius > 0 && length >= 0) { - shapeIndex = b3CreateVisualShapeAddCapsule(commandHandle,radius,length); + shapeIndex = b3CreateVisualShapeAddCapsule(commandHandle, radius, length); } - if (shapeType==GEOM_CYLINDER && radius>0 && length>=0) + if (shapeType == GEOM_CYLINDER && radius > 0 && length >= 0) { - shapeIndex = b3CreateVisualShapeAddCylinder(commandHandle,radius,length); + shapeIndex = b3CreateVisualShapeAddCylinder(commandHandle, radius, length); } - if (shapeType==GEOM_MESH && fileName) + if (shapeType == GEOM_MESH && fileName) { - pybullet_internalSetVectord(meshScaleObj,meshScale); - shapeIndex = b3CreateVisualShapeAddMesh(commandHandle, fileName,meshScale); + pybullet_internalSetVectord(meshScaleObj, meshScale); + shapeIndex = b3CreateVisualShapeAddMesh(commandHandle, fileName, meshScale); } - if (shapeType==GEOM_PLANE) + if (shapeType == GEOM_PLANE) { - double planeConstant=0; - pybullet_internalSetVectord(planeNormalObj,planeNormal); + double planeConstant = 0; + pybullet_internalSetVectord(planeNormalObj, planeNormal); shapeIndex = b3CreateVisualShapeAddPlane(commandHandle, planeNormal, planeConstant); } - if (shapeIndex>=0 && flags) + if (shapeIndex >= 0 && flags) { - b3CreateVisualSetFlag(commandHandle,shapeIndex,flags); + b3CreateVisualSetFlag(commandHandle, shapeIndex, flags); } - if (shapeIndex>=0) + if (shapeIndex >= 0) { - double rgbaColor[4] = {1,1,1,1}; - double specularColor[3] = {1,1,1}; + double rgbaColor[4] = {1, 1, 1, 1}; + double specularColor[3] = {1, 1, 1}; if (rgbaColorObj) { - pybullet_internalSetVector4d(rgbaColorObj,rgbaColor); + pybullet_internalSetVector4d(rgbaColorObj, rgbaColor); } - b3CreateVisualShapeSetRGBAColor(commandHandle,shapeIndex, rgbaColor); + b3CreateVisualShapeSetRGBAColor(commandHandle, shapeIndex, rgbaColor); if (specularColorObj) { - pybullet_internalSetVectord(specularColorObj,specularColor); + pybullet_internalSetVectord(specularColorObj, specularColor); } - b3CreateVisualShapeSetSpecularColor(commandHandle,shapeIndex,specularColor); + b3CreateVisualShapeSetSpecularColor(commandHandle, shapeIndex, specularColor); if (visualFramePositionObj) { - pybullet_internalSetVectord(visualFramePositionObj,visualFramePosition); + pybullet_internalSetVectord(visualFramePositionObj, visualFramePosition); } if (visualFrameOrientationObj) { - pybullet_internalSetVector4d(visualFrameOrientationObj,visualFrameOrientation); + pybullet_internalSetVector4d(visualFrameOrientationObj, visualFrameOrientation); } - b3CreateVisualShapeSetChildTransform(commandHandle, shapeIndex, visualFramePosition,visualFrameOrientation); - + b3CreateVisualShapeSetChildTransform(commandHandle, shapeIndex, visualFramePosition, visualFrameOrientation); } - statusHandle = b3SubmitClientCommandAndWaitStatus(sm, commandHandle); statusType = b3GetStatusType(statusHandle); if (statusType == CMD_CREATE_VISUAL_SHAPE_COMPLETED) @@ -6749,7 +6674,6 @@ static PyObject* pybullet_createVisualShape(PyObject* self, PyObject* args, PyOb return NULL; } - static PyObject* pybullet_createVisualShapeArray(PyObject* self, PyObject* args, PyObject* keywds) { int physicsClientId = 0; @@ -6764,16 +6688,16 @@ static PyObject* pybullet_createVisualShapeArray(PyObject* self, PyObject* args, PyObject* fileNameArray = 0; PyObject* meshScaleObjArray = 0; PyObject* planeNormalObjArray = 0; - PyObject* rgbaColorArray = 0; + PyObject* rgbaColorArray = 0; PyObject* flagsArray = 0; PyObject* visualFramePositionObjArray = 0; PyObject* visualFrameOrientationObjArray = 0; - static char* kwlist[] = { "shapeTypes", "radii", "halfExtents", "lengths", "fileNames", "meshScales", "planeNormals", - "flags", "rgbaColors", "visualFramePositions", "visualFrameOrientations", "physicsClientId", NULL }; + static char* kwlist[] = {"shapeTypes", "radii", "halfExtents", "lengths", "fileNames", "meshScales", "planeNormals", + "flags", "rgbaColors", "visualFramePositions", "visualFrameOrientations", "physicsClientId", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|OOOOOOOOOOi", kwlist, - &shapeTypeArray, &radiusArray, &halfExtentsObjArray, &lengthArray, &fileNameArray, &meshScaleObjArray, &planeNormalObjArray, &flagsArray, &rgbaColorArray, &visualFramePositionObjArray, &visualFrameOrientationObjArray, &physicsClientId)) + if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|OOOOOOOOOOi", kwlist, + &shapeTypeArray, &radiusArray, &halfExtentsObjArray, &lengthArray, &fileNameArray, &meshScaleObjArray, &planeNormalObjArray, &flagsArray, &rgbaColorArray, &visualFramePositionObjArray, &visualFrameOrientationObjArray, &physicsClientId)) { return NULL; } @@ -6784,9 +6708,6 @@ static PyObject* pybullet_createVisualShapeArray(PyObject* self, PyObject* args, return NULL; } - - - { b3SharedMemoryCommandHandle commandHandle = b3CreateVisualShapeCommandInit(sm); int numShapeTypes = 0; @@ -6796,7 +6717,7 @@ static PyObject* pybullet_createVisualShapeArray(PyObject* self, PyObject* args, int numFileNames = 0; int numMeshScales = 0; int numPlaneNormals = 0; - int numRGBAColors = 0; + int numRGBAColors = 0; int numFlags = 0; int numPositions = 0; int numOrientations = 0; @@ -6809,7 +6730,7 @@ static PyObject* pybullet_createVisualShapeArray(PyObject* self, PyObject* args, PyObject* fileNameArraySeq = fileNameArray ? PySequence_Fast(fileNameArray, "expected a sequence of filename") : 0; PyObject* meshScaleArraySeq = meshScaleObjArray ? PySequence_Fast(meshScaleObjArray, "expected a sequence of mesh scale") : 0; PyObject* planeNormalArraySeq = planeNormalObjArray ? PySequence_Fast(planeNormalObjArray, "expected a sequence of plane normal") : 0; - PyObject* rgbaColorArraySeq = rgbaColorArray ? PySequence_Fast(rgbaColorArray, "expected a sequence of rgba color") : 0; + PyObject* rgbaColorArraySeq = rgbaColorArray ? PySequence_Fast(rgbaColorArray, "expected a sequence of rgba color") : 0; PyObject* flagsArraySeq = flagsArray ? PySequence_Fast(flagsArray, "expected a sequence of flags") : 0; PyObject* positionArraySeq = visualFramePositionObjArray ? PySequence_Fast(visualFramePositionObjArray, "expected a sequence of visual frame positions") : 0; PyObject* orientationArraySeq = visualFrameOrientationObjArray ? PySequence_Fast(visualFrameOrientationObjArray, "expected a sequence of visual frame orientations") : 0; @@ -6827,14 +6748,13 @@ static PyObject* pybullet_createVisualShapeArray(PyObject* self, PyObject* args, numFileNames = fileNameArraySeq ? PySequence_Size(fileNameArraySeq) : 0; numMeshScales = meshScaleArraySeq ? PySequence_Size(meshScaleArraySeq) : 0; numPlaneNormals = planeNormalArraySeq ? PySequence_Size(planeNormalArraySeq) : 0; - numRGBAColors = rgbaColorArraySeq ? PySequence_Size(rgbaColorArraySeq) : 0; + numRGBAColors = rgbaColorArraySeq ? PySequence_Size(rgbaColorArraySeq) : 0; - for (s = 0; s= GEOM_SPHERE) { - int shapeIndex = -1; if (shapeType == GEOM_SPHERE && s <= numRadius) @@ -6848,7 +6768,7 @@ static PyObject* pybullet_createVisualShapeArray(PyObject* self, PyObject* args, if (shapeType == GEOM_BOX) { PyObject* halfExtentsObj = 0; - double halfExtents[3] = { 1, 1, 1 }; + double halfExtents[3] = {1, 1, 1}; if (halfExtentsArraySeq && s <= numHalfExtents) { @@ -6873,7 +6793,7 @@ static PyObject* pybullet_createVisualShapeArray(PyObject* self, PyObject* args, shapeIndex = b3CreateVisualShapeAddCapsule(commandHandle, radius, height); } } - if (shapeType == GEOM_CYLINDER && s <= numRadius && s0) + if (useMaximalCoordinates > 0) { b3CreateMultiBodyUseMaximalCoordinates(commandHandle); } - if (flags >0) + if (flags > 0) { b3CreateMultiBodySetFlags(commandHandle, flags); } @@ -7166,8 +7077,8 @@ static PyObject* pybullet_createMultiBody(PyObject* self, PyObject* args, PyObje PyObject* ob = PyLong_FromLong(uid); return ob; } - - } else + } + else { if (seqLinkMasses) Py_DECREF(seqLinkMasses); @@ -7194,8 +7105,7 @@ static PyObject* pybullet_createMultiBody(PyObject* self, PyObject* args, PyObje return NULL; } - - #if 0 +#if 0 PyObject* seq; seq = PySequence_Fast(objMat, "expected a sequence"); if (seq) @@ -7212,15 +7122,12 @@ static PyObject* pybullet_createMultiBody(PyObject* self, PyObject* args, PyObje } Py_DECREF(seq); } - #endif - - +#endif } PyErr_SetString(SpamError, "createMultiBody failed."); return NULL; } - static PyObject* pybullet_createUserConstraint(PyObject* self, PyObject* args, PyObject* keywds) { b3SharedMemoryCommandHandle commandHandle; @@ -7344,22 +7251,22 @@ static PyObject* pybullet_getContactPointData(PyObject* self, PyObject* args, Py } commandHandle = b3InitRequestContactPointInformation(sm); - if (bodyUniqueIdA>=0) + if (bodyUniqueIdA >= 0) { b3SetContactFilterBodyA(commandHandle, bodyUniqueIdA); } - if (bodyUniqueIdB>=0) + if (bodyUniqueIdB >= 0) { b3SetContactFilterBodyB(commandHandle, bodyUniqueIdB); } - if (linkIndexA>=-1) + if (linkIndexA >= -1) { - b3SetContactFilterLinkA( commandHandle, linkIndexA); + b3SetContactFilterLinkA(commandHandle, linkIndexA); } - if (linkIndexB >=-1) + if (linkIndexB >= -1) { - b3SetContactFilterLinkB( commandHandle, linkIndexB); + b3SetContactFilterLinkB(commandHandle, linkIndexB); } statusHandle = b3SubmitClientCommandAndWaitStatus(sm, commandHandle); @@ -7375,7 +7282,6 @@ static PyObject* pybullet_getContactPointData(PyObject* self, PyObject* args, Py return Py_None; } - static PyObject* pybullet_isNumpyEnabled(PyObject* self, PyObject* args, PyObject* keywds) { int physicsClientId = 0; @@ -7384,7 +7290,7 @@ static PyObject* pybullet_isNumpyEnabled(PyObject* self, PyObject* args, PyObjec PyObject* pylist = 0; PyObject* val = 0; b3PhysicsClientHandle sm = 0; - static char* kwlist[] = { "physicsClientId", NULL }; + static char* kwlist[] = {"physicsClientId", NULL}; if (!PyArg_ParseTupleAndKeywords(args, keywds, "|i", kwlist, &physicsClientId)) { return NULL; @@ -7396,8 +7302,6 @@ static PyObject* pybullet_isNumpyEnabled(PyObject* self, PyObject* args, PyObjec return PyLong_FromLong(isNumpyEnabled); } - - /// Render an image from the current timestep of the simulation, width, height are required, other args are optional // getCameraImage(w, h, view[16], projection[16], lightDir[3], lightColor[3], lightDist, hasShadow, lightAmbientCoeff, lightDiffuseCoeff, lightSpecularCoeff, renderer) static PyObject* pybullet_getCameraImage(PyObject* self, PyObject* args, PyObject* keywds) @@ -7455,25 +7359,25 @@ static PyObject* pybullet_getCameraImage(PyObject* self, PyObject* args, PyObjec { b3RequestCameraImageSetLightColor(command, lightColor); } - if (lightDist>=0) + if (lightDist >= 0) { b3RequestCameraImageSetLightDistance(command, lightDist); } - if (hasShadow>=0) + if (hasShadow >= 0) { b3RequestCameraImageSetShadow(command, hasShadow); } - if (lightAmbientCoeff>=0) + if (lightAmbientCoeff >= 0) { b3RequestCameraImageSetLightAmbientCoeff(command, lightAmbientCoeff); } - if (lightDiffuseCoeff>=0) + if (lightDiffuseCoeff >= 0) { b3RequestCameraImageSetLightDiffuseCoeff(command, lightDiffuseCoeff); } - if (lightSpecularCoeff>=0) + if (lightSpecularCoeff >= 0) { b3RequestCameraImageSetLightSpecularCoeff(command, lightSpecularCoeff); } @@ -7486,11 +7390,11 @@ static PyObject* pybullet_getCameraImage(PyObject* self, PyObject* args, PyObjec { b3RequestCameraImageSetProjectiveTextureMatrices(command, projectiveTextureView, projectiveTextureProj); } - if (renderer>=0) + if (renderer >= 0) { - b3RequestCameraImageSelectRenderer(command, renderer);//renderer could be ER_BULLET_HARDWARE_OPENGL + b3RequestCameraImageSelectRenderer(command, renderer); //renderer could be ER_BULLET_HARDWARE_OPENGL } - //PyErr_Clear(); + //PyErr_Clear(); if (b3CanSubmitCommand(sm)) { @@ -7501,7 +7405,6 @@ static PyObject* pybullet_getCameraImage(PyObject* self, PyObject* args, PyObjec statusType = b3GetStatusType(statusHandle); if (statusType == CMD_CAMERA_IMAGE_COMPLETED) { - PyObject* pyResultList; // store 4 elements in this result: width, // height, rgbData, depth @@ -7512,34 +7415,33 @@ static PyObject* pybullet_getCameraImage(PyObject* self, PyObject* args, PyObjec int bytesPerPixel = 4; // Red, Green, Blue, and Alpha each 8 bit values - b3GetCameraImageData(sm, &imageData); // TODO(hellojas): error handling if image size is 0 { - npy_intp rgb_dims[3] = {imageData.m_pixelHeight, imageData.m_pixelWidth, - bytesPerPixel}; - npy_intp dep_dims[2] = {imageData.m_pixelHeight, imageData.m_pixelWidth}; - npy_intp seg_dims[2] = {imageData.m_pixelHeight, imageData.m_pixelWidth}; + npy_intp rgb_dims[3] = {imageData.m_pixelHeight, imageData.m_pixelWidth, + bytesPerPixel}; + npy_intp dep_dims[2] = {imageData.m_pixelHeight, imageData.m_pixelWidth}; + npy_intp seg_dims[2] = {imageData.m_pixelHeight, imageData.m_pixelWidth}; - pyResultList = PyTuple_New(5); + pyResultList = PyTuple_New(5); - PyTuple_SetItem(pyResultList, 0, PyInt_FromLong(imageData.m_pixelWidth)); - PyTuple_SetItem(pyResultList, 1, PyInt_FromLong(imageData.m_pixelHeight)); + PyTuple_SetItem(pyResultList, 0, PyInt_FromLong(imageData.m_pixelWidth)); + PyTuple_SetItem(pyResultList, 1, PyInt_FromLong(imageData.m_pixelHeight)); - pyRGB = PyArray_SimpleNew(3, rgb_dims, NPY_UINT8); - pyDep = PyArray_SimpleNew(2, dep_dims, NPY_FLOAT32); - pySeg = PyArray_SimpleNew(2, seg_dims, NPY_INT32); + pyRGB = PyArray_SimpleNew(3, rgb_dims, NPY_UINT8); + pyDep = PyArray_SimpleNew(2, dep_dims, NPY_FLOAT32); + pySeg = PyArray_SimpleNew(2, seg_dims, NPY_INT32); - memcpy(PyArray_DATA(pyRGB), imageData.m_rgbColorData, - imageData.m_pixelHeight * imageData.m_pixelWidth * bytesPerPixel); - memcpy(PyArray_DATA(pyDep), imageData.m_depthValues, - imageData.m_pixelHeight * imageData.m_pixelWidth * sizeof(float)); - memcpy(PyArray_DATA(pySeg), imageData.m_segmentationMaskValues, - imageData.m_pixelHeight * imageData.m_pixelWidth * sizeof(int)); + memcpy(PyArray_DATA(pyRGB), imageData.m_rgbColorData, + imageData.m_pixelHeight * imageData.m_pixelWidth * bytesPerPixel); + memcpy(PyArray_DATA(pyDep), imageData.m_depthValues, + imageData.m_pixelHeight * imageData.m_pixelWidth * sizeof(float)); + memcpy(PyArray_DATA(pySeg), imageData.m_segmentationMaskValues, + imageData.m_pixelHeight * imageData.m_pixelWidth * sizeof(int)); - PyTuple_SetItem(pyResultList, 2, pyRGB); - PyTuple_SetItem(pyResultList, 3, pyDep); - PyTuple_SetItem(pyResultList, 4, pySeg); + PyTuple_SetItem(pyResultList, 2, pyRGB); + PyTuple_SetItem(pyResultList, 3, pyDep); + PyTuple_SetItem(pyResultList, 4, pySeg); } #else //PYBULLET_USE_NUMPY PyObject* item2; @@ -7614,11 +7516,11 @@ static PyObject* pybullet_computeViewMatrix(PyObject* self, PyObject* args, PyOb float camEye[3]; float camTargetPosition[3]; float camUpVector[3]; - int physicsClientId=0; + int physicsClientId = 0; // set camera resolution, optionally view, projection matrix, light position static char* kwlist[] = {"cameraEyePosition", "cameraTargetPosition", "cameraUpVector", "physicsClientId", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "OOO|i", kwlist, &camEyeObj, &camTargetPositionObj, &camUpVectorObj,&physicsClientId)) + if (!PyArg_ParseTupleAndKeywords(args, keywds, "OOO|i", kwlist, &camEyeObj, &camTargetPositionObj, &camUpVectorObj, &physicsClientId)) { return NULL; } @@ -7660,7 +7562,7 @@ static PyObject* pybullet_computeViewMatrixFromYawPitchRoll(PyObject* self, PyOb // set camera resolution, optionally view, projection matrix, light position static char* kwlist[] = {"cameraTargetPosition", "distance", "yaw", "pitch", "roll", "upAxisIndex", "physicsClientId", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "Offffi|i", kwlist, &cameraTargetPositionObj, &distance, &yaw, &pitch, &roll, &upAxisIndex,&physicsClientId)) + if (!PyArg_ParseTupleAndKeywords(args, keywds, "Offffi|i", kwlist, &cameraTargetPositionObj, &distance, &yaw, &pitch, &roll, &upAxisIndex, &physicsClientId)) { return NULL; } @@ -7697,9 +7599,9 @@ static PyObject* pybullet_computeProjectionMatrix(PyObject* self, PyObject* args int physicsClientId; // set camera resolution, optionally view, projection matrix, light position - static char* kwlist[] = {"left", "right", "bottom", "top", "nearVal", "farVal", "physicsClientId",NULL}; + static char* kwlist[] = {"left", "right", "bottom", "top", "nearVal", "farVal", "physicsClientId", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "ffffff|i", kwlist, &left, &right, &bottom, &top, &nearVal, &farVal,&physicsClientId)) + if (!PyArg_ParseTupleAndKeywords(args, keywds, "ffffff|i", kwlist, &left, &right, &bottom, &top, &nearVal, &farVal, &physicsClientId)) { return NULL; } @@ -7721,11 +7623,11 @@ static PyObject* pybullet_computeProjectionMatrixFOV(PyObject* self, PyObject* a PyObject* pyResultList = 0; float projectionMatrix[16]; int i; - int physicsClientId=0; + int physicsClientId = 0; static char* kwlist[] = {"fov", "aspect", "nearVal", "farVal", "physicsClientId", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "ffff|i", kwlist, &fov, &aspect, &nearVal, &farVal,&physicsClientId)) + if (!PyArg_ParseTupleAndKeywords(args, keywds, "ffff|i", kwlist, &fov, &aspect, &nearVal, &farVal, &physicsClientId)) { return NULL; } @@ -7927,12 +7829,10 @@ static PyObject* pybullet_renderImageObsolete(PyObject* self, PyObject* args) b3SharedMemoryStatusHandle statusHandle; int statusType; - statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command); statusType = b3GetStatusType(statusHandle); if (statusType == CMD_CAMERA_IMAGE_COMPLETED) { - PyObject* pyResultList; // store 4 elements in this result: width, // height, rgbData, depth @@ -7941,7 +7841,6 @@ static PyObject* pybullet_renderImageObsolete(PyObject* self, PyObject* args) PyObject* pyDep; PyObject* pySeg; - int bytesPerPixel = 4; // Red, Green, Blue, and Alpha each 8 bit values b3GetCameraImageData(sm, &imageData); @@ -7950,25 +7849,25 @@ static PyObject* pybullet_renderImageObsolete(PyObject* self, PyObject* args) PyTuple_SetItem(pyResultList, 0, PyInt_FromLong(imageData.m_pixelWidth)); PyTuple_SetItem(pyResultList, 1, PyInt_FromLong(imageData.m_pixelHeight)); { - npy_intp rgb_dims[3] = {imageData.m_pixelHeight, imageData.m_pixelWidth, - bytesPerPixel}; - npy_intp dep_dims[2] = {imageData.m_pixelHeight, imageData.m_pixelWidth}; - npy_intp seg_dims[2] = {imageData.m_pixelHeight, imageData.m_pixelWidth}; + npy_intp rgb_dims[3] = {imageData.m_pixelHeight, imageData.m_pixelWidth, + bytesPerPixel}; + npy_intp dep_dims[2] = {imageData.m_pixelHeight, imageData.m_pixelWidth}; + npy_intp seg_dims[2] = {imageData.m_pixelHeight, imageData.m_pixelWidth}; - pyRGB = PyArray_SimpleNew(3, rgb_dims, NPY_UINT8); - pyDep = PyArray_SimpleNew(2, dep_dims, NPY_FLOAT32); - pySeg = PyArray_SimpleNew(2, seg_dims, NPY_INT32); + pyRGB = PyArray_SimpleNew(3, rgb_dims, NPY_UINT8); + pyDep = PyArray_SimpleNew(2, dep_dims, NPY_FLOAT32); + pySeg = PyArray_SimpleNew(2, seg_dims, NPY_INT32); - memcpy(PyArray_DATA(pyRGB), imageData.m_rgbColorData, - imageData.m_pixelHeight * imageData.m_pixelWidth * bytesPerPixel); - memcpy(PyArray_DATA(pyDep), imageData.m_depthValues, - imageData.m_pixelHeight * imageData.m_pixelWidth); - memcpy(PyArray_DATA(pySeg), imageData.m_segmentationMaskValues, - imageData.m_pixelHeight * imageData.m_pixelWidth); + memcpy(PyArray_DATA(pyRGB), imageData.m_rgbColorData, + imageData.m_pixelHeight * imageData.m_pixelWidth * bytesPerPixel); + memcpy(PyArray_DATA(pyDep), imageData.m_depthValues, + imageData.m_pixelHeight * imageData.m_pixelWidth); + memcpy(PyArray_DATA(pySeg), imageData.m_segmentationMaskValues, + imageData.m_pixelHeight * imageData.m_pixelWidth); - PyTuple_SetItem(pyResultList, 2, pyRGB); - PyTuple_SetItem(pyResultList, 3, pyDep); - PyTuple_SetItem(pyResultList, 4, pySeg); + PyTuple_SetItem(pyResultList, 2, pyRGB); + PyTuple_SetItem(pyResultList, 3, pyDep); + PyTuple_SetItem(pyResultList, 4, pySeg); } #else //PYBULLET_USE_NUMPY PyObject* item2; @@ -8191,11 +8090,11 @@ static PyObject* pybullet_getQuaternionFromEuler(PyObject* self, double rpy[3]; PyObject* eulerObj; - int physicsClientId=0; + int physicsClientId = 0; - static char* kwlist[] = {"eulerAngles","physicsClientId", NULL}; + static char* kwlist[] = {"eulerAngles", "physicsClientId", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|i", kwlist, &eulerObj,&physicsClientId)) + if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|i", kwlist, &eulerObj, &physicsClientId)) { return NULL; } @@ -8266,26 +8165,26 @@ static PyObject* pybullet_getQuaternionFromEuler(PyObject* self, } static PyObject* pybullet_multiplyTransforms(PyObject* self, - PyObject* args, PyObject* keywds) + PyObject* args, PyObject* keywds) { PyObject* posAObj = 0; PyObject* ornAObj = 0; PyObject* posBObj = 0; PyObject* ornBObj = 0; - int hasPosA=0; - int hasOrnA=0; - int hasPosB=0; - int hasOrnB=0; + int hasPosA = 0; + int hasOrnA = 0; + int hasPosB = 0; + int hasOrnB = 0; double posA[3]; double ornA[4] = {0, 0, 0, 1}; double posB[3]; double ornB[4] = {0, 0, 0, 1}; - int physicsClientId=0; + int physicsClientId = 0; static char* kwlist[] = {"positionA", "orientationA", "positionB", "orientationB", "physicsClientId", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "OOOO|i", kwlist, &posAObj, &ornAObj,&posBObj, &ornBObj,&physicsClientId)) + if (!PyArg_ParseTupleAndKeywords(args, keywds, "OOOO|i", kwlist, &posAObj, &ornAObj, &posBObj, &ornBObj, &physicsClientId)) { return NULL; } @@ -8293,18 +8192,18 @@ static PyObject* pybullet_multiplyTransforms(PyObject* self, hasPosA = pybullet_internalSetVectord(posAObj, posA); hasOrnA = pybullet_internalSetVector4d(ornAObj, ornA); hasPosB = pybullet_internalSetVectord(posBObj, posB); - hasOrnB= pybullet_internalSetVector4d(ornBObj, ornB); + hasOrnB = pybullet_internalSetVector4d(ornBObj, ornB); - if (hasPosA&&hasOrnA&&hasPosB&&hasOrnB) + if (hasPosA && hasOrnA && hasPosB && hasOrnB) { double outPos[3]; double outOrn[4]; int i; - PyObject* pyListOutObj=0; - PyObject* pyPosOutObj=0; - PyObject* pyOrnOutObj=0; + PyObject* pyListOutObj = 0; + PyObject* pyPosOutObj = 0; + PyObject* pyOrnOutObj = 0; - b3MultiplyTransforms(posA,ornA,posB,ornB, outPos, outOrn); + b3MultiplyTransforms(posA, ornA, posB, ornB, outPos, outOrn); pyListOutObj = PyTuple_New(2); pyPosOutObj = PyTuple_New(3); @@ -8324,18 +8223,18 @@ static PyObject* pybullet_multiplyTransforms(PyObject* self, } static PyObject* pybullet_invertTransform(PyObject* self, - PyObject* args, PyObject* keywds) + PyObject* args, PyObject* keywds) { PyObject* posObj = 0; PyObject* ornObj = 0; double pos[3]; double orn[4] = {0, 0, 0, 1}; - int hasPos =0; - int hasOrn =0; + int hasPos = 0; + int hasOrn = 0; int physicsClientId = 0; static char* kwlist[] = {"position", "orientation", "physicsClientId", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "OO|i", kwlist, &posObj, &ornObj,&physicsClientId)) + if (!PyArg_ParseTupleAndKeywords(args, keywds, "OO|i", kwlist, &posObj, &ornObj, &physicsClientId)) { return NULL; } @@ -8348,9 +8247,9 @@ static PyObject* pybullet_invertTransform(PyObject* self, double outPos[3]; double outOrn[4]; int i; - PyObject* pyListOutObj=0; - PyObject* pyPosOutObj=0; - PyObject* pyOrnOutObj=0; + PyObject* pyListOutObj = 0; + PyObject* pyPosOutObj = 0; + PyObject* pyOrnOutObj = 0; b3InvertTransform(pos, orn, outPos, outOrn); @@ -8368,12 +8267,10 @@ static PyObject* pybullet_invertTransform(PyObject* self, return pyListOutObj; } - PyErr_SetString(SpamError, "Invalid input: expected position [x,y,z] and orientation [x,y,z,w]."); return NULL; } - /// quaternion <-> euler yaw/pitch/roll convention from URDF/SDF, see Gazebo /// https://github.com/arpg/Gazebo/blob/master/gazebo/math/Quaternion.cc static PyObject* pybullet_getEulerFromQuaternion(PyObject* self, @@ -8388,11 +8285,11 @@ static PyObject* pybullet_getEulerFromQuaternion(PyObject* self, PyObject* quatObj; - int physicsClientId=0; + int physicsClientId = 0; - static char* kwlist[] = {"quaternion","physicsClientId", NULL}; + static char* kwlist[] = {"quaternion", "physicsClientId", NULL}; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|i", kwlist, &quatObj,&physicsClientId)) + if (!PyArg_ParseTupleAndKeywords(args, keywds, "O|i", kwlist, &quatObj, &physicsClientId)) { return NULL; } @@ -8439,15 +8336,17 @@ static PyObject* pybullet_getEulerFromQuaternion(PyObject* self, // set rollX = 0 and compute yawZ. if (sarg <= -0.99999) { - rpy[0] = 0; - rpy[1] = -0.5*PYBULLET_PI; - rpy[2] = 2 * atan2(quat[0],-quat[1]); - } else if (sarg >= 0.99999) + rpy[0] = 0; + rpy[1] = -0.5 * PYBULLET_PI; + rpy[2] = 2 * atan2(quat[0], -quat[1]); + } + else if (sarg >= 0.99999) { - rpy[0] = 0; - rpy[1] = 0.5*PYBULLET_PI; - rpy[2] = 2 * atan2(-quat[0], quat[1]); - } else + rpy[0] = 0; + rpy[1] = 0.5 * PYBULLET_PI; + rpy[2] = 2 * atan2(-quat[0], quat[1]); + } + else { rpy[0] = atan2(2 * (quat[1] * quat[2] + quat[3] * quat[0]), squ - sqx - sqy + sqz); rpy[1] = asin(sarg); @@ -8466,9 +8365,8 @@ static PyObject* pybullet_getEulerFromQuaternion(PyObject* self, return Py_None; } - static PyObject* pybullet_loadPlugin(PyObject* self, - PyObject* args, PyObject* keywds) + PyObject* args, PyObject* keywds) { int physicsClientId = 0; @@ -8476,11 +8374,11 @@ static PyObject* pybullet_loadPlugin(PyObject* self, char* postFix = 0; b3SharedMemoryCommandHandle command = 0; - b3SharedMemoryStatusHandle statusHandle = 0; + b3SharedMemoryStatusHandle statusHandle = 0; int statusType = -1; b3PhysicsClientHandle sm = 0; - static char* kwlist[] = { "pluginPath", "postFix", "physicsClientId", NULL }; + static char* kwlist[] = {"pluginPath", "postFix", "physicsClientId", NULL}; if (!PyArg_ParseTupleAndKeywords(args, keywds, "s|si", kwlist, &pluginPath, &postFix, &physicsClientId)) { return NULL; @@ -8504,20 +8402,19 @@ static PyObject* pybullet_loadPlugin(PyObject* self, return PyInt_FromLong(statusType); } - static PyObject* pybullet_unloadPlugin(PyObject* self, - PyObject* args, PyObject* keywds) + PyObject* args, PyObject* keywds) { int physicsClientId = 0; int pluginUniqueId = -1; b3SharedMemoryCommandHandle command = 0; - b3SharedMemoryStatusHandle statusHandle = 0; + b3SharedMemoryStatusHandle statusHandle = 0; int statusType = -1; b3PhysicsClientHandle sm = 0; - static char* kwlist[] = { "pluginUniqueId", "physicsClientId", NULL }; - if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|i", kwlist, &pluginUniqueId,&physicsClientId)) + static char* kwlist[] = {"pluginUniqueId", "physicsClientId", NULL}; + if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|i", kwlist, &pluginUniqueId, &physicsClientId)) { return NULL; } @@ -8534,24 +8431,25 @@ static PyObject* pybullet_unloadPlugin(PyObject* self, statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command); Py_INCREF(Py_None); - return Py_None;; + return Py_None; + ; } //createCustomCommand for executing commands implemented in a plugin system static PyObject* pybullet_executePluginCommand(PyObject* self, - PyObject* args, PyObject* keywds) + PyObject* args, PyObject* keywds) { int physicsClientId = 0; int pluginUniqueId = -1; char* textArgument = 0; - b3SharedMemoryCommandHandle command=0; - b3SharedMemoryStatusHandle statusHandle=0; + b3SharedMemoryCommandHandle command = 0; + b3SharedMemoryStatusHandle statusHandle = 0; int statusType = -1; - PyObject* intArgs=0; - PyObject* floatArgs=0; + PyObject* intArgs = 0; + PyObject* floatArgs = 0; b3PhysicsClientHandle sm = 0; - static char* kwlist[] = { "pluginUniqueId", "textArgument", "intArgs", "floatArgs", "physicsClientId", NULL }; + static char* kwlist[] = {"pluginUniqueId", "textArgument", "intArgs", "floatArgs", "physicsClientId", NULL}; if (!PyArg_ParseTupleAndKeywords(args, keywds, "i|sOOi", kwlist, &pluginUniqueId, &textArgument, &intArgs, &floatArgs, &physicsClientId)) { return NULL; @@ -8564,26 +8462,24 @@ static PyObject* pybullet_executePluginCommand(PyObject* self, return NULL; } - command = b3CreateCustomCommand(sm); b3CustomCommandExecutePluginCommand(command, pluginUniqueId, textArgument); { - PyObject* seqIntArgs = intArgs?PySequence_Fast(intArgs, "expected a sequence"):0; - PyObject* seqFloatArgs = floatArgs?PySequence_Fast(floatArgs, "expected a sequence"):0; - int numIntArgs = seqIntArgs?PySequence_Size(intArgs):0; - int numFloatArgs = seqFloatArgs?PySequence_Size(floatArgs):0; + PyObject* seqIntArgs = intArgs ? PySequence_Fast(intArgs, "expected a sequence") : 0; + PyObject* seqFloatArgs = floatArgs ? PySequence_Fast(floatArgs, "expected a sequence") : 0; + int numIntArgs = seqIntArgs ? PySequence_Size(intArgs) : 0; + int numFloatArgs = seqFloatArgs ? PySequence_Size(floatArgs) : 0; int i; - for (i=0;i bodyUniqueId. don't update keywords, people need to migrate to bodyUniqueId version - static char* kwlist2[] = {"bodyIndex", "endEffectorLinkIndex", "targetPosition", "targetOrientation", "lowerLimits", "upperLimits", "jointRanges", "restPoses", "jointDamping", "physicsClientId", NULL}; + static char* kwlist2[] = {"bodyIndex", "endEffectorLinkIndex", "targetPosition", "targetOrientation", "lowerLimits", "upperLimits", "jointRanges", "restPoses", "jointDamping", "physicsClientId", NULL}; PyErr_Clear(); if (!PyArg_ParseTupleAndKeywords(args, keywds, "iiO|OOOOOOi", kwlist2, &bodyUniqueId, &endEffectorLinkIndex, &targetPosObj, &targetOrnObj, &lowerLimitsObj, &upperLimitsObj, &jointRangesObj, &restPosesObj, &jointDampingObj, &physicsClientId)) { @@ -8655,7 +8551,6 @@ static PyObject* pybullet_calculateInverseKinematics(PyObject* self, int szCurrentPositions = currentPositionsObj ? PySequence_Size(currentPositionsObj) : 0; - int numJoints = b3GetNumJoints(sm, bodyUniqueId); int dofCount = b3ComputeDofCount(sm, bodyUniqueId); @@ -8684,7 +8579,7 @@ static PyObject* pybullet_calculateInverseKinematics(PyObject* self, lowerLimits[i] = pybullet_internalGetFloatFromSequence(lowerLimitsObj, i); upperLimits[i] = pybullet_internalGetFloatFromSequence(upperLimitsObj, i); jointRanges[i] = pybullet_internalGetFloatFromSequence(jointRangesObj, i); - restPoses[i] = pybullet_internalGetFloatFromSequence(restPosesObj, i); + restPoses[i] = pybullet_internalGetFloatFromSequence(restPosesObj, i); } hasNullSpace = 1; } @@ -8747,13 +8642,13 @@ static PyObject* pybullet_calculateInverseKinematics(PyObject* self, { b3CalculateInverseKinematicsSetCurrentPositions(command, dofCount, currentPositions); } - if (maxNumIterations>0) + if (maxNumIterations > 0) { - b3CalculateInverseKinematicsSetMaxNumIterations(command,maxNumIterations); + b3CalculateInverseKinematicsSetMaxNumIterations(command, maxNumIterations); } - if (residualThreshold>=0) + if (residualThreshold >= 0) { - b3CalculateInverseKinematicsSetResidualThreshold(command,residualThreshold); + b3CalculateInverseKinematicsSetResidualThreshold(command, residualThreshold); } if (hasNullSpace) @@ -8855,10 +8750,10 @@ static PyObject* pybullet_calculateInverseDynamics(PyObject* self, PyObject* arg "physicsClientId", NULL}; PyErr_Clear(); if (!PyArg_ParseTupleAndKeywords(args, keywds, "iOOO|i", kwlist2, - &bodyUniqueId, &objPositionsQ, &objVelocitiesQdot, - &objAccelerations, &physicsClientId)) + &bodyUniqueId, &objPositionsQ, &objVelocitiesQdot, + &objAccelerations, &physicsClientId)) { - return NULL; + return NULL; } } sm = getPhysicsClient(physicsClientId); @@ -8915,7 +8810,6 @@ static PyObject* pybullet_calculateInverseDynamics(PyObject* self, PyObject* arg b3GetStatusInverseDynamicsJointForces(statusHandle, &bodyUniqueId, &dofCount, 0); - if (dofCount) { b3GetStatusInverseDynamicsJointForces(statusHandle, 0, 0, @@ -8975,8 +8869,8 @@ static PyObject* pybullet_calculateJacobian(PyObject* self, PyObject* args, PyOb "objPositions", "objVelocities", "objAccelerations", "physicsClientId", NULL}; if (!PyArg_ParseTupleAndKeywords(args, keywds, "iiOOOO|i", kwlist, - &bodyUniqueId, &linkIndex, &localPosition, &objPositions, - &objVelocities, &objAccelerations, &physicsClientId)) + &bodyUniqueId, &linkIndex, &localPosition, &objPositions, + &objVelocities, &objAccelerations, &physicsClientId)) { return NULL; } @@ -8994,34 +8888,34 @@ static PyObject* pybullet_calculateJacobian(PyObject* self, PyObject* args, PyOb int szObAcc = PySequence_Size(objAccelerations); int numJoints = b3GetNumJoints(sm, bodyUniqueId); - int j=0; + int j = 0; int dofCountOrg = 0; - for (j=0;j= 3 @@ -9801,28 +9695,27 @@ initpybullet(void) #endif PyModule_AddIntConstant(m, "SHARED_MEMORY", - eCONNECT_SHARED_MEMORY); // user read - PyModule_AddIntConstant(m, "DIRECT", eCONNECT_DIRECT); // user read - PyModule_AddIntConstant(m, "GUI", eCONNECT_GUI); // user read - PyModule_AddIntConstant(m, "UDP", eCONNECT_UDP); // user read - PyModule_AddIntConstant(m, "TCP", eCONNECT_TCP); // user read - PyModule_AddIntConstant(m, "GUI_SERVER", eCONNECT_GUI_SERVER); // user read - PyModule_AddIntConstant(m, "GUI_MAIN_THREAD", eCONNECT_GUI_MAIN_THREAD); // user read - PyModule_AddIntConstant(m, "SHARED_MEMORY_SERVER", eCONNECT_SHARED_MEMORY_SERVER); // user read + eCONNECT_SHARED_MEMORY); // user read + PyModule_AddIntConstant(m, "DIRECT", eCONNECT_DIRECT); // user read + PyModule_AddIntConstant(m, "GUI", eCONNECT_GUI); // user read + PyModule_AddIntConstant(m, "UDP", eCONNECT_UDP); // user read + PyModule_AddIntConstant(m, "TCP", eCONNECT_TCP); // user read + PyModule_AddIntConstant(m, "GUI_SERVER", eCONNECT_GUI_SERVER); // user read + PyModule_AddIntConstant(m, "GUI_MAIN_THREAD", eCONNECT_GUI_MAIN_THREAD); // user read + PyModule_AddIntConstant(m, "SHARED_MEMORY_SERVER", eCONNECT_SHARED_MEMORY_SERVER); // user read #ifdef BT_ENABLE_DART - PyModule_AddIntConstant(m, "DART", eCONNECT_DART); // user read + PyModule_AddIntConstant(m, "DART", eCONNECT_DART); // user read #endif #ifdef BT_ENABLE_MUJOCO - PyModule_AddIntConstant(m, "MuJoCo", eCONNECT_MUJOCO); // user read + PyModule_AddIntConstant(m, "MuJoCo", eCONNECT_MUJOCO); // user read #endif #ifdef BT_ENABLE_GRPC - PyModule_AddIntConstant(m, "GRPC", eCONNECT_GRPC); // user read + PyModule_AddIntConstant(m, "GRPC", eCONNECT_GRPC); // user read #endif - - PyModule_AddIntConstant(m, "SHARED_MEMORY_KEY", SHARED_MEMORY_KEY); - PyModule_AddIntConstant(m, "SHARED_MEMORY_KEY2", SHARED_MEMORY_KEY+1); + PyModule_AddIntConstant(m, "SHARED_MEMORY_KEY", SHARED_MEMORY_KEY); + PyModule_AddIntConstant(m, "SHARED_MEMORY_KEY2", SHARED_MEMORY_KEY + 1); PyModule_AddIntConstant(m, "JOINT_REVOLUTE", eRevoluteType); // user read PyModule_AddIntConstant(m, "JOINT_PRISMATIC", ePrismaticType); // user read @@ -9830,8 +9723,7 @@ initpybullet(void) PyModule_AddIntConstant(m, "JOINT_PLANAR", ePlanarType); // user read PyModule_AddIntConstant(m, "JOINT_FIXED", eFixedType); // user read PyModule_AddIntConstant(m, "JOINT_POINT2POINT", ePoint2PointType); // user read - PyModule_AddIntConstant(m, "JOINT_GEAR", eGearType); // user read - + PyModule_AddIntConstant(m, "JOINT_GEAR", eGearType); // user read PyModule_AddIntConstant(m, "SENSOR_FORCE_TORQUE", eSensorForceTorqueType); // user read @@ -9843,8 +9735,8 @@ initpybullet(void) CONTROL_MODE_VELOCITY); // user read PyModule_AddIntConstant(m, "POSITION_CONTROL", CONTROL_MODE_POSITION_VELOCITY_PD); // user read - PyModule_AddIntConstant(m, "PD_CONTROL", - CONTROL_MODE_PD); // user read + PyModule_AddIntConstant(m, "PD_CONTROL", + CONTROL_MODE_PD); // user read PyModule_AddIntConstant(m, "LINK_FRAME", EF_LINK_FRAME); PyModule_AddIntConstant(m, "WORLD_FRAME", EF_WORLD_FRAME); @@ -9852,12 +9744,12 @@ initpybullet(void) PyModule_AddIntConstant(m, "CONTACT_REPORT_EXISTING", CONTACT_QUERY_MODE_REPORT_EXISTING_CONTACT_POINTS); PyModule_AddIntConstant(m, "CONTACT_RECOMPUTE_CLOSEST", CONTACT_QUERY_MODE_COMPUTE_CLOSEST_POINTS); - PyModule_AddIntConstant(m, "CONSTRAINT_SOLVER_LCP_SI",eConstraintSolverLCP_SI); - PyModule_AddIntConstant(m, "CONSTRAINT_SOLVER_LCP_PGS",eConstraintSolverLCP_PGS); - PyModule_AddIntConstant(m, "CONSTRAINT_SOLVER_LCP_DANTZIG",eConstraintSolverLCP_DANTZIG); - //PyModule_AddIntConstant(m, "CONSTRAINT_SOLVER_LCP_LEMKE",eConstraintSolverLCP_LEMKE); - //PyModule_AddIntConstant(m, "CONSTRAINT_SOLVER_LCP_NNCF",eConstraintSolverLCP_NNCG); - //PyModule_AddIntConstant(m, "CONSTRAINT_SOLVER_LCP_BLOCK",eConstraintSolverLCP_BLOCK_PGS); + PyModule_AddIntConstant(m, "CONSTRAINT_SOLVER_LCP_SI", eConstraintSolverLCP_SI); + PyModule_AddIntConstant(m, "CONSTRAINT_SOLVER_LCP_PGS", eConstraintSolverLCP_PGS); + PyModule_AddIntConstant(m, "CONSTRAINT_SOLVER_LCP_DANTZIG", eConstraintSolverLCP_DANTZIG); + //PyModule_AddIntConstant(m, "CONSTRAINT_SOLVER_LCP_LEMKE",eConstraintSolverLCP_LEMKE); + //PyModule_AddIntConstant(m, "CONSTRAINT_SOLVER_LCP_NNCF",eConstraintSolverLCP_NNCG); + //PyModule_AddIntConstant(m, "CONSTRAINT_SOLVER_LCP_BLOCK",eConstraintSolverLCP_BLOCK_PGS); PyModule_AddIntConstant(m, "VR_BUTTON_IS_DOWN", eButtonIsDown); PyModule_AddIntConstant(m, "VR_BUTTON_WAS_TRIGGERED", eButtonTriggered); @@ -9905,7 +9797,6 @@ initpybullet(void) PyModule_AddIntConstant(m, "COV_ENABLE_PLANAR_REFLECTION", COV_ENABLE_PLANAR_REFLECTION); PyModule_AddIntConstant(m, "COV_ENABLE_SINGLE_STEP_RENDERING", COV_ENABLE_SINGLE_STEP_RENDERING); - PyModule_AddIntConstant(m, "ER_TINY_RENDERER", ER_TINY_RENDERER); PyModule_AddIntConstant(m, "ER_BULLET_HARDWARE_OPENGL", ER_BULLET_HARDWARE_OPENGL); PyModule_AddIntConstant(m, "ER_SEGMENTATION_MASK_OBJECT_AND_LINKINDEX", ER_SEGMENTATION_MASK_OBJECT_AND_LINKINDEX); @@ -9982,19 +9873,16 @@ initpybullet(void) PyModule_AddIntConstant(m, "GEOM_FORCE_CONCAVE_TRIMESH", GEOM_FORCE_CONCAVE_TRIMESH); PyModule_AddIntConstant(m, "GEOM_CONCAVE_INTERNAL_EDGE", GEOM_CONCAVE_INTERNAL_EDGE); - PyModule_AddIntConstant(m, "STATE_LOG_JOINT_MOTOR_TORQUES", STATE_LOG_JOINT_MOTOR_TORQUES); PyModule_AddIntConstant(m, "STATE_LOG_JOINT_USER_TORQUES", STATE_LOG_JOINT_USER_TORQUES); - PyModule_AddIntConstant(m, "STATE_LOG_JOINT_TORQUES", STATE_LOG_JOINT_USER_TORQUES+STATE_LOG_JOINT_MOTOR_TORQUES); - + PyModule_AddIntConstant(m, "STATE_LOG_JOINT_TORQUES", STATE_LOG_JOINT_USER_TORQUES + STATE_LOG_JOINT_MOTOR_TORQUES); SpamError = PyErr_NewException("pybullet.error", NULL, NULL); Py_INCREF(SpamError); PyModule_AddObject(m, "error", SpamError); - printf("pybullet build time: %s %s\n", __DATE__,__TIME__); - - Py_AtExit( b3pybulletExitFunc ); + printf("pybullet build time: %s %s\n", __DATE__, __TIME__); + Py_AtExit(b3pybulletExitFunc); #ifdef PYBULLET_USE_NUMPY // Initialize numpy array. diff --git a/src/Bullet3Collision/BroadPhaseCollision/b3BroadphaseCallback.h b/src/Bullet3Collision/BroadPhaseCollision/b3BroadphaseCallback.h index 1bc56cf80..bec0800a6 100644 --- a/src/Bullet3Collision/BroadPhaseCollision/b3BroadphaseCallback.h +++ b/src/Bullet3Collision/BroadPhaseCollision/b3BroadphaseCallback.h @@ -19,22 +19,20 @@ subject to the following restrictions: #include "Bullet3Common/b3Vector3.h" struct b3BroadphaseProxy; - -struct b3BroadphaseAabbCallback +struct b3BroadphaseAabbCallback { virtual ~b3BroadphaseAabbCallback() {} - virtual bool process(const b3BroadphaseProxy* proxy) = 0; + virtual bool process(const b3BroadphaseProxy* proxy) = 0; }; - -struct b3BroadphaseRayCallback : public b3BroadphaseAabbCallback +struct b3BroadphaseRayCallback : public b3BroadphaseAabbCallback { ///added some cached data to accelerate ray-AABB tests - b3Vector3 m_rayDirectionInverse; - unsigned int m_signs[3]; - b3Scalar m_lambda_max; + b3Vector3 m_rayDirectionInverse; + unsigned int m_signs[3]; + b3Scalar m_lambda_max; virtual ~b3BroadphaseRayCallback() {} }; -#endif //B3_BROADPHASE_CALLBACK_H +#endif //B3_BROADPHASE_CALLBACK_H diff --git a/src/Bullet3Collision/BroadPhaseCollision/b3DynamicBvh.cpp b/src/Bullet3Collision/BroadPhaseCollision/b3DynamicBvh.cpp index 0f04efe33..a0dc1da95 100644 --- a/src/Bullet3Collision/BroadPhaseCollision/b3DynamicBvh.cpp +++ b/src/Bullet3Collision/BroadPhaseCollision/b3DynamicBvh.cpp @@ -17,209 +17,224 @@ subject to the following restrictions: #include "b3DynamicBvh.h" // -typedef b3AlignedObjectArray b3NodeArray; -typedef b3AlignedObjectArray b3ConstNodeArray; +typedef b3AlignedObjectArray b3NodeArray; +typedef b3AlignedObjectArray b3ConstNodeArray; // struct b3DbvtNodeEnumerator : b3DynamicBvh::ICollide { - b3ConstNodeArray nodes; + b3ConstNodeArray nodes; void Process(const b3DbvtNode* n) { nodes.push_back(n); } }; // -static B3_DBVT_INLINE int b3IndexOf(const b3DbvtNode* node) +static B3_DBVT_INLINE int b3IndexOf(const b3DbvtNode* node) { - return(node->parent->childs[1]==node); + return (node->parent->childs[1] == node); } // -static B3_DBVT_INLINE b3DbvtVolume b3Merge( const b3DbvtVolume& a, - const b3DbvtVolume& b) +static B3_DBVT_INLINE b3DbvtVolume b3Merge(const b3DbvtVolume& a, + const b3DbvtVolume& b) { -#if (B3_DBVT_MERGE_IMPL==B3_DBVT_IMPL_SSE) +#if (B3_DBVT_MERGE_IMPL == B3_DBVT_IMPL_SSE) B3_ATTRIBUTE_ALIGNED16(char locals[sizeof(b3DbvtAabbMm)]); - b3DbvtVolume& res=*(b3DbvtVolume*)locals; + b3DbvtVolume& res = *(b3DbvtVolume*)locals; #else - b3DbvtVolume res; + b3DbvtVolume res; #endif - b3Merge(a,b,res); - return(res); + b3Merge(a, b, res); + return (res); } // volume+edge lengths -static B3_DBVT_INLINE b3Scalar b3Size(const b3DbvtVolume& a) +static B3_DBVT_INLINE b3Scalar b3Size(const b3DbvtVolume& a) { - const b3Vector3 edges=a.Lengths(); - return( edges.x*edges.y*edges.z+ - edges.x+edges.y+edges.z); + const b3Vector3 edges = a.Lengths(); + return (edges.x * edges.y * edges.z + + edges.x + edges.y + edges.z); } // -static void b3GetMaxDepth(const b3DbvtNode* node,int depth,int& maxdepth) +static void b3GetMaxDepth(const b3DbvtNode* node, int depth, int& maxdepth) { - if(node->isinternal()) + if (node->isinternal()) { - b3GetMaxDepth(node->childs[0],depth+1,maxdepth); - b3GetMaxDepth(node->childs[1],depth+1,maxdepth); - } else maxdepth=b3Max(maxdepth,depth); + b3GetMaxDepth(node->childs[0], depth + 1, maxdepth); + b3GetMaxDepth(node->childs[1], depth + 1, maxdepth); + } + else + maxdepth = b3Max(maxdepth, depth); } // -static B3_DBVT_INLINE void b3DeleteNode( b3DynamicBvh* pdbvt, - b3DbvtNode* node) +static B3_DBVT_INLINE void b3DeleteNode(b3DynamicBvh* pdbvt, + b3DbvtNode* node) { b3AlignedFree(pdbvt->m_free); - pdbvt->m_free=node; + pdbvt->m_free = node; } // -static void b3RecurseDeleteNode( b3DynamicBvh* pdbvt, - b3DbvtNode* node) +static void b3RecurseDeleteNode(b3DynamicBvh* pdbvt, + b3DbvtNode* node) { - if(!node->isleaf()) + if (!node->isleaf()) { - b3RecurseDeleteNode(pdbvt,node->childs[0]); - b3RecurseDeleteNode(pdbvt,node->childs[1]); + b3RecurseDeleteNode(pdbvt, node->childs[0]); + b3RecurseDeleteNode(pdbvt, node->childs[1]); } - if(node==pdbvt->m_root) pdbvt->m_root=0; - b3DeleteNode(pdbvt,node); + if (node == pdbvt->m_root) pdbvt->m_root = 0; + b3DeleteNode(pdbvt, node); } // -static B3_DBVT_INLINE b3DbvtNode* b3CreateNode( b3DynamicBvh* pdbvt, - b3DbvtNode* parent, - void* data) +static B3_DBVT_INLINE b3DbvtNode* b3CreateNode(b3DynamicBvh* pdbvt, + b3DbvtNode* parent, + void* data) { - b3DbvtNode* node; - if(pdbvt->m_free) - { node=pdbvt->m_free;pdbvt->m_free=0; } - else - { node=new(b3AlignedAlloc(sizeof(b3DbvtNode),16)) b3DbvtNode(); } - node->parent = parent; - node->data = data; - node->childs[1] = 0; - return(node); -} - -// -static B3_DBVT_INLINE b3DbvtNode* b3CreateNode( b3DynamicBvh* pdbvt, - b3DbvtNode* parent, - const b3DbvtVolume& volume, - void* data) -{ - b3DbvtNode* node=b3CreateNode(pdbvt,parent,data); - node->volume=volume; - return(node); -} - -// -static B3_DBVT_INLINE b3DbvtNode* b3CreateNode( b3DynamicBvh* pdbvt, - b3DbvtNode* parent, - const b3DbvtVolume& volume0, - const b3DbvtVolume& volume1, - void* data) -{ - b3DbvtNode* node=b3CreateNode(pdbvt,parent,data); - b3Merge(volume0,volume1,node->volume); - return(node); -} - -// -static void b3InsertLeaf( b3DynamicBvh* pdbvt, - b3DbvtNode* root, - b3DbvtNode* leaf) -{ - if(!pdbvt->m_root) + b3DbvtNode* node; + if (pdbvt->m_free) { - pdbvt->m_root = leaf; - leaf->parent = 0; + node = pdbvt->m_free; + pdbvt->m_free = 0; } else { - if(!root->isleaf()) + node = new (b3AlignedAlloc(sizeof(b3DbvtNode), 16)) b3DbvtNode(); + } + node->parent = parent; + node->data = data; + node->childs[1] = 0; + return (node); +} + +// +static B3_DBVT_INLINE b3DbvtNode* b3CreateNode(b3DynamicBvh* pdbvt, + b3DbvtNode* parent, + const b3DbvtVolume& volume, + void* data) +{ + b3DbvtNode* node = b3CreateNode(pdbvt, parent, data); + node->volume = volume; + return (node); +} + +// +static B3_DBVT_INLINE b3DbvtNode* b3CreateNode(b3DynamicBvh* pdbvt, + b3DbvtNode* parent, + const b3DbvtVolume& volume0, + const b3DbvtVolume& volume1, + void* data) +{ + b3DbvtNode* node = b3CreateNode(pdbvt, parent, data); + b3Merge(volume0, volume1, node->volume); + return (node); +} + +// +static void b3InsertLeaf(b3DynamicBvh* pdbvt, + b3DbvtNode* root, + b3DbvtNode* leaf) +{ + if (!pdbvt->m_root) + { + pdbvt->m_root = leaf; + leaf->parent = 0; + } + else + { + if (!root->isleaf()) { - do { - root=root->childs[b3Select( leaf->volume, - root->childs[0]->volume, - root->childs[1]->volume)]; - } while(!root->isleaf()); + do + { + root = root->childs[b3Select(leaf->volume, + root->childs[0]->volume, + root->childs[1]->volume)]; + } while (!root->isleaf()); } - b3DbvtNode* prev=root->parent; - b3DbvtNode* node=b3CreateNode(pdbvt,prev,leaf->volume,root->volume,0); - if(prev) + b3DbvtNode* prev = root->parent; + b3DbvtNode* node = b3CreateNode(pdbvt, prev, leaf->volume, root->volume, 0); + if (prev) { - prev->childs[b3IndexOf(root)] = node; - node->childs[0] = root;root->parent=node; - node->childs[1] = leaf;leaf->parent=node; - do { - if(!prev->volume.Contain(node->volume)) - b3Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume); + prev->childs[b3IndexOf(root)] = node; + node->childs[0] = root; + root->parent = node; + node->childs[1] = leaf; + leaf->parent = node; + do + { + if (!prev->volume.Contain(node->volume)) + b3Merge(prev->childs[0]->volume, prev->childs[1]->volume, prev->volume); else break; - node=prev; - } while(0!=(prev=node->parent)); + node = prev; + } while (0 != (prev = node->parent)); } else { - node->childs[0] = root;root->parent=node; - node->childs[1] = leaf;leaf->parent=node; - pdbvt->m_root = node; + node->childs[0] = root; + root->parent = node; + node->childs[1] = leaf; + leaf->parent = node; + pdbvt->m_root = node; } } } // -static b3DbvtNode* b3RemoveLeaf( b3DynamicBvh* pdbvt, - b3DbvtNode* leaf) +static b3DbvtNode* b3RemoveLeaf(b3DynamicBvh* pdbvt, + b3DbvtNode* leaf) { - if(leaf==pdbvt->m_root) + if (leaf == pdbvt->m_root) { - pdbvt->m_root=0; - return(0); + pdbvt->m_root = 0; + return (0); } else { - b3DbvtNode* parent=leaf->parent; - b3DbvtNode* prev=parent->parent; - b3DbvtNode* sibling=parent->childs[1-b3IndexOf(leaf)]; - if(prev) + b3DbvtNode* parent = leaf->parent; + b3DbvtNode* prev = parent->parent; + b3DbvtNode* sibling = parent->childs[1 - b3IndexOf(leaf)]; + if (prev) { - prev->childs[b3IndexOf(parent)]=sibling; - sibling->parent=prev; - b3DeleteNode(pdbvt,parent); - while(prev) + prev->childs[b3IndexOf(parent)] = sibling; + sibling->parent = prev; + b3DeleteNode(pdbvt, parent); + while (prev) { - const b3DbvtVolume pb=prev->volume; - b3Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume); - if(b3NotEqual(pb,prev->volume)) + const b3DbvtVolume pb = prev->volume; + b3Merge(prev->childs[0]->volume, prev->childs[1]->volume, prev->volume); + if (b3NotEqual(pb, prev->volume)) { - prev=prev->parent; - } else break; + prev = prev->parent; + } + else + break; } - return(prev?prev:pdbvt->m_root); + return (prev ? prev : pdbvt->m_root); } else - { - pdbvt->m_root=sibling; - sibling->parent=0; - b3DeleteNode(pdbvt,parent); - return(pdbvt->m_root); - } + { + pdbvt->m_root = sibling; + sibling->parent = 0; + b3DeleteNode(pdbvt, parent); + return (pdbvt->m_root); + } } } // -static void b3FetchLeaves(b3DynamicBvh* pdbvt, - b3DbvtNode* root, - b3NodeArray& leaves, - int depth=-1) +static void b3FetchLeaves(b3DynamicBvh* pdbvt, + b3DbvtNode* root, + b3NodeArray& leaves, + int depth = -1) { - if(root->isinternal()&&depth) + if (root->isinternal() && depth) { - b3FetchLeaves(pdbvt,root->childs[0],leaves,depth-1); - b3FetchLeaves(pdbvt,root->childs[1],leaves,depth-1); - b3DeleteNode(pdbvt,root); + b3FetchLeaves(pdbvt, root->childs[0], leaves, depth - 1); + b3FetchLeaves(pdbvt, root->childs[1], leaves, depth - 1); + b3DeleteNode(pdbvt, root); } else { @@ -227,50 +242,50 @@ static void b3FetchLeaves(b3DynamicBvh* pdbvt, } } -static bool b3LeftOfAxis( const b3DbvtNode* node, - const b3Vector3& org, - const b3Vector3& axis) +static bool b3LeftOfAxis(const b3DbvtNode* node, + const b3Vector3& org, + const b3Vector3& axis) { - return b3Dot(axis,node->volume.Center()-org) <= 0; + return b3Dot(axis, node->volume.Center() - org) <= 0; } // Partitions leaves such that leaves[0, n) are on the // left of axis, and leaves[n, count) are on the right // of axis. returns N. -static int b3Split( b3DbvtNode** leaves, - int count, - const b3Vector3& org, - const b3Vector3& axis) +static int b3Split(b3DbvtNode** leaves, + int count, + const b3Vector3& org, + const b3Vector3& axis) { - int begin=0; - int end=count; - for(;;) + int begin = 0; + int end = count; + for (;;) { - while(begin!=end && b3LeftOfAxis(leaves[begin],org,axis)) + while (begin != end && b3LeftOfAxis(leaves[begin], org, axis)) { ++begin; } - if(begin==end) + if (begin == end) { break; } - while(begin!=end && !b3LeftOfAxis(leaves[end-1],org,axis)) + while (begin != end && !b3LeftOfAxis(leaves[end - 1], org, axis)) { --end; } - if(begin==end) + if (begin == end) { break; } // swap out of place nodes --end; - b3DbvtNode* temp=leaves[begin]; - leaves[begin]=leaves[end]; - leaves[end]=temp; + b3DbvtNode* temp = leaves[begin]; + leaves[begin] = leaves[end]; + leaves[end] = temp; ++begin; } @@ -278,149 +293,152 @@ static int b3Split( b3DbvtNode** leaves, } // -static b3DbvtVolume b3Bounds( b3DbvtNode** leaves, - int count) +static b3DbvtVolume b3Bounds(b3DbvtNode** leaves, + int count) { -#if B3_DBVT_MERGE_IMPL==B3_DBVT_IMPL_SSE - B3_ATTRIBUTE_ALIGNED16(char locals[sizeof(b3DbvtVolume)]); - b3DbvtVolume& volume=*(b3DbvtVolume*)locals; - volume=leaves[0]->volume; +#if B3_DBVT_MERGE_IMPL == B3_DBVT_IMPL_SSE + B3_ATTRIBUTE_ALIGNED16(char locals[sizeof(b3DbvtVolume)]); + b3DbvtVolume& volume = *(b3DbvtVolume*)locals; + volume = leaves[0]->volume; #else - b3DbvtVolume volume=leaves[0]->volume; + b3DbvtVolume volume = leaves[0]->volume; #endif - for(int i=1,ni=count;ivolume,volume); + b3Merge(volume, leaves[i]->volume, volume); } - return(volume); + return (volume); } // -static void b3BottomUp( b3DynamicBvh* pdbvt, - b3DbvtNode** leaves, - int count) +static void b3BottomUp(b3DynamicBvh* pdbvt, + b3DbvtNode** leaves, + int count) { - while(count>1) + while (count > 1) { - b3Scalar minsize=B3_INFINITY; - int minidx[2]={-1,-1}; - for(int i=0;ivolume,leaves[j]->volume)); - if(szvolume, leaves[j]->volume)); + if (sz < minsize) { - minsize = sz; - minidx[0] = i; - minidx[1] = j; + minsize = sz; + minidx[0] = i; + minidx[1] = j; } } } - b3DbvtNode* n[] = {leaves[minidx[0]],leaves[minidx[1]]}; - b3DbvtNode* p = b3CreateNode(pdbvt,0,n[0]->volume,n[1]->volume,0); - p->childs[0] = n[0]; - p->childs[1] = n[1]; - n[0]->parent = p; - n[1]->parent = p; - leaves[minidx[0]] = p; - leaves[minidx[1]] = leaves[count-1]; + b3DbvtNode* n[] = {leaves[minidx[0]], leaves[minidx[1]]}; + b3DbvtNode* p = b3CreateNode(pdbvt, 0, n[0]->volume, n[1]->volume, 0); + p->childs[0] = n[0]; + p->childs[1] = n[1]; + n[0]->parent = p; + n[1]->parent = p; + leaves[minidx[0]] = p; + leaves[minidx[1]] = leaves[count - 1]; --count; } } // -static b3DbvtNode* b3TopDown(b3DynamicBvh* pdbvt, - b3DbvtNode** leaves, - int count, - int bu_treshold) +static b3DbvtNode* b3TopDown(b3DynamicBvh* pdbvt, + b3DbvtNode** leaves, + int count, + int bu_treshold) { - static const b3Vector3 axis[]={b3MakeVector3(1,0,0), - b3MakeVector3(0,1,0), - b3MakeVector3(0,0,1)}; - b3Assert(bu_treshold>1); - if(count>1) + static const b3Vector3 axis[] = {b3MakeVector3(1, 0, 0), + b3MakeVector3(0, 1, 0), + b3MakeVector3(0, 0, 1)}; + b3Assert(bu_treshold > 1); + if (count > 1) { - if(count>bu_treshold) + if (count > bu_treshold) { - const b3DbvtVolume vol=b3Bounds(leaves,count); - const b3Vector3 org=vol.Center(); - int partition; - int bestaxis=-1; - int bestmidp=count; - int splitcount[3][2]={{0,0},{0,0},{0,0}}; + const b3DbvtVolume vol = b3Bounds(leaves, count); + const b3Vector3 org = vol.Center(); + int partition; + int bestaxis = -1; + int bestmidp = count; + int splitcount[3][2] = {{0, 0}, {0, 0}, {0, 0}}; int i; - for( i=0;ivolume.Center()-org; - for(int j=0;j<3;++j) + const b3Vector3 x = leaves[i]->volume.Center() - org; + for (int j = 0; j < 3; ++j) { - ++splitcount[j][b3Dot(x,axis[j])>0?1:0]; + ++splitcount[j][b3Dot(x, axis[j]) > 0 ? 1 : 0]; } } - for( i=0;i<3;++i) + for (i = 0; i < 3; ++i) { - if((splitcount[i][0]>0)&&(splitcount[i][1]>0)) + if ((splitcount[i][0] > 0) && (splitcount[i][1] > 0)) { - const int midp=(int)b3Fabs(b3Scalar(splitcount[i][0]-splitcount[i][1])); - if(midp=0) + if (bestaxis >= 0) { - partition=b3Split(leaves,count,org,axis[bestaxis]); - b3Assert(partition!=0 && partition!=count); + partition = b3Split(leaves, count, org, axis[bestaxis]); + b3Assert(partition != 0 && partition != count); } else { - partition=count/2+1; + partition = count / 2 + 1; } - b3DbvtNode* node=b3CreateNode(pdbvt,0,vol,0); - node->childs[0]=b3TopDown(pdbvt,&leaves[0],partition,bu_treshold); - node->childs[1]=b3TopDown(pdbvt,&leaves[partition],count-partition,bu_treshold); - node->childs[0]->parent=node; - node->childs[1]->parent=node; - return(node); + b3DbvtNode* node = b3CreateNode(pdbvt, 0, vol, 0); + node->childs[0] = b3TopDown(pdbvt, &leaves[0], partition, bu_treshold); + node->childs[1] = b3TopDown(pdbvt, &leaves[partition], count - partition, bu_treshold); + node->childs[0]->parent = node; + node->childs[1]->parent = node; + return (node); } else { - b3BottomUp(pdbvt,leaves,count); - return(leaves[0]); + b3BottomUp(pdbvt, leaves, count); + return (leaves[0]); } } - return(leaves[0]); + return (leaves[0]); } // -static B3_DBVT_INLINE b3DbvtNode* b3Sort(b3DbvtNode* n,b3DbvtNode*& r) +static B3_DBVT_INLINE b3DbvtNode* b3Sort(b3DbvtNode* n, b3DbvtNode*& r) { - b3DbvtNode* p=n->parent; + b3DbvtNode* p = n->parent; b3Assert(n->isinternal()); - if(p>n) + if (p > n) { - const int i=b3IndexOf(n); - const int j=1-i; - b3DbvtNode* s=p->childs[j]; - b3DbvtNode* q=p->parent; - b3Assert(n==p->childs[i]); - if(q) q->childs[b3IndexOf(p)]=n; else r=n; - s->parent=n; - p->parent=n; - n->parent=q; - p->childs[0]=n->childs[0]; - p->childs[1]=n->childs[1]; - n->childs[0]->parent=p; - n->childs[1]->parent=p; - n->childs[i]=p; - n->childs[j]=s; - b3Swap(p->volume,n->volume); - return(p); + const int i = b3IndexOf(n); + const int j = 1 - i; + b3DbvtNode* s = p->childs[j]; + b3DbvtNode* q = p->parent; + b3Assert(n == p->childs[i]); + if (q) + q->childs[b3IndexOf(p)] = n; + else + r = n; + s->parent = n; + p->parent = n; + n->parent = q; + p->childs[0] = n->childs[0]; + p->childs[1] = n->childs[1]; + n->childs[0]->parent = p; + n->childs[1]->parent = p; + n->childs[i] = p; + n->childs[j] = s; + b3Swap(p->volume, n->volume); + return (p); } - return(n); + return (n); } #if 0 @@ -438,11 +456,11 @@ static B3_DBVT_INLINE b3DbvtNode* walkup(b3DbvtNode* n,int count) // b3DynamicBvh::b3DynamicBvh() { - m_root = 0; - m_free = 0; - m_lkhd = -1; - m_leaves = 0; - m_opath = 0; + m_root = 0; + m_free = 0; + m_lkhd = -1; + m_leaves = 0; + m_opath = 0; } // @@ -452,228 +470,233 @@ b3DynamicBvh::~b3DynamicBvh() } // -void b3DynamicBvh::clear() +void b3DynamicBvh::clear() { - if(m_root) - b3RecurseDeleteNode(this,m_root); + if (m_root) + b3RecurseDeleteNode(this, m_root); b3AlignedFree(m_free); - m_free=0; - m_lkhd = -1; + m_free = 0; + m_lkhd = -1; m_stkStack.clear(); - m_opath = 0; - + m_opath = 0; } // -void b3DynamicBvh::optimizeBottomUp() +void b3DynamicBvh::optimizeBottomUp() { - if(m_root) + if (m_root) { b3NodeArray leaves; leaves.reserve(m_leaves); - b3FetchLeaves(this,m_root,leaves); - b3BottomUp(this,&leaves[0],leaves.size()); - m_root=leaves[0]; + b3FetchLeaves(this, m_root, leaves); + b3BottomUp(this, &leaves[0], leaves.size()); + m_root = leaves[0]; } } // -void b3DynamicBvh::optimizeTopDown(int bu_treshold) +void b3DynamicBvh::optimizeTopDown(int bu_treshold) { - if(m_root) + if (m_root) { - b3NodeArray leaves; + b3NodeArray leaves; leaves.reserve(m_leaves); - b3FetchLeaves(this,m_root,leaves); - m_root=b3TopDown(this,&leaves[0],leaves.size(),bu_treshold); + b3FetchLeaves(this, m_root, leaves); + m_root = b3TopDown(this, &leaves[0], leaves.size(), bu_treshold); } } // -void b3DynamicBvh::optimizeIncremental(int passes) +void b3DynamicBvh::optimizeIncremental(int passes) { - if(passes<0) passes=m_leaves; - if(m_root&&(passes>0)) + if (passes < 0) passes = m_leaves; + if (m_root && (passes > 0)) { - do { - b3DbvtNode* node=m_root; - unsigned bit=0; - while(node->isinternal()) + do + { + b3DbvtNode* node = m_root; + unsigned bit = 0; + while (node->isinternal()) { - node=b3Sort(node,m_root)->childs[(m_opath>>bit)&1]; - bit=(bit+1)&(sizeof(unsigned)*8-1); + node = b3Sort(node, m_root)->childs[(m_opath >> bit) & 1]; + bit = (bit + 1) & (sizeof(unsigned) * 8 - 1); } update(node); ++m_opath; - } while(--passes); + } while (--passes); } } // -b3DbvtNode* b3DynamicBvh::insert(const b3DbvtVolume& volume,void* data) +b3DbvtNode* b3DynamicBvh::insert(const b3DbvtVolume& volume, void* data) { - b3DbvtNode* leaf=b3CreateNode(this,0,volume,data); - b3InsertLeaf(this,m_root,leaf); + b3DbvtNode* leaf = b3CreateNode(this, 0, volume, data); + b3InsertLeaf(this, m_root, leaf); ++m_leaves; - return(leaf); + return (leaf); } // -void b3DynamicBvh::update(b3DbvtNode* leaf,int lookahead) +void b3DynamicBvh::update(b3DbvtNode* leaf, int lookahead) { - b3DbvtNode* root=b3RemoveLeaf(this,leaf); - if(root) + b3DbvtNode* root = b3RemoveLeaf(this, leaf); + if (root) { - if(lookahead>=0) + if (lookahead >= 0) { - for(int i=0;(iparent;++i) + for (int i = 0; (i < lookahead) && root->parent; ++i) { - root=root->parent; + root = root->parent; } - } else root=m_root; + } + else + root = m_root; } - b3InsertLeaf(this,root,leaf); + b3InsertLeaf(this, root, leaf); } // -void b3DynamicBvh::update(b3DbvtNode* leaf,b3DbvtVolume& volume) +void b3DynamicBvh::update(b3DbvtNode* leaf, b3DbvtVolume& volume) { - b3DbvtNode* root=b3RemoveLeaf(this,leaf); - if(root) + b3DbvtNode* root = b3RemoveLeaf(this, leaf); + if (root) { - if(m_lkhd>=0) + if (m_lkhd >= 0) { - for(int i=0;(iparent;++i) + for (int i = 0; (i < m_lkhd) && root->parent; ++i) { - root=root->parent; + root = root->parent; } - } else root=m_root; + } + else + root = m_root; } - leaf->volume=volume; - b3InsertLeaf(this,root,leaf); + leaf->volume = volume; + b3InsertLeaf(this, root, leaf); } // -bool b3DynamicBvh::update(b3DbvtNode* leaf,b3DbvtVolume& volume,const b3Vector3& velocity,b3Scalar margin) +bool b3DynamicBvh::update(b3DbvtNode* leaf, b3DbvtVolume& volume, const b3Vector3& velocity, b3Scalar margin) { - if(leaf->volume.Contain(volume)) return(false); - volume.Expand(b3MakeVector3(margin,margin,margin)); + if (leaf->volume.Contain(volume)) return (false); + volume.Expand(b3MakeVector3(margin, margin, margin)); volume.SignedExpand(velocity); - update(leaf,volume); - return(true); + update(leaf, volume); + return (true); } // -bool b3DynamicBvh::update(b3DbvtNode* leaf,b3DbvtVolume& volume,const b3Vector3& velocity) +bool b3DynamicBvh::update(b3DbvtNode* leaf, b3DbvtVolume& volume, const b3Vector3& velocity) { - if(leaf->volume.Contain(volume)) return(false); + if (leaf->volume.Contain(volume)) return (false); volume.SignedExpand(velocity); - update(leaf,volume); - return(true); + update(leaf, volume); + return (true); } // -bool b3DynamicBvh::update(b3DbvtNode* leaf,b3DbvtVolume& volume,b3Scalar margin) +bool b3DynamicBvh::update(b3DbvtNode* leaf, b3DbvtVolume& volume, b3Scalar margin) { - if(leaf->volume.Contain(volume)) return(false); - volume.Expand(b3MakeVector3(margin,margin,margin)); - update(leaf,volume); - return(true); + if (leaf->volume.Contain(volume)) return (false); + volume.Expand(b3MakeVector3(margin, margin, margin)); + update(leaf, volume); + return (true); } // -void b3DynamicBvh::remove(b3DbvtNode* leaf) +void b3DynamicBvh::remove(b3DbvtNode* leaf) { - b3RemoveLeaf(this,leaf); - b3DeleteNode(this,leaf); + b3RemoveLeaf(this, leaf); + b3DeleteNode(this, leaf); --m_leaves; } // -void b3DynamicBvh::write(IWriter* iwriter) const +void b3DynamicBvh::write(IWriter* iwriter) const { - b3DbvtNodeEnumerator nodes; - nodes.nodes.reserve(m_leaves*2); - enumNodes(m_root,nodes); - iwriter->Prepare(m_root,nodes.nodes.size()); - for(int i=0;iPrepare(m_root, nodes.nodes.size()); + for (int i = 0; i < nodes.nodes.size(); ++i) { - const b3DbvtNode* n=nodes.nodes[i]; - int p=-1; - if(n->parent) p=nodes.nodes.findLinearSearch(n->parent); - if(n->isinternal()) + const b3DbvtNode* n = nodes.nodes[i]; + int p = -1; + if (n->parent) p = nodes.nodes.findLinearSearch(n->parent); + if (n->isinternal()) { - const int c0=nodes.nodes.findLinearSearch(n->childs[0]); - const int c1=nodes.nodes.findLinearSearch(n->childs[1]); - iwriter->WriteNode(n,i,p,c0,c1); + const int c0 = nodes.nodes.findLinearSearch(n->childs[0]); + const int c1 = nodes.nodes.findLinearSearch(n->childs[1]); + iwriter->WriteNode(n, i, p, c0, c1); } else { - iwriter->WriteLeaf(n,i,p); - } + iwriter->WriteLeaf(n, i, p); + } } } // -void b3DynamicBvh::clone(b3DynamicBvh& dest,IClone* iclone) const +void b3DynamicBvh::clone(b3DynamicBvh& dest, IClone* iclone) const { dest.clear(); - if(m_root!=0) - { - b3AlignedObjectArray stack; + if (m_root != 0) + { + b3AlignedObjectArray stack; stack.reserve(m_leaves); - stack.push_back(sStkCLN(m_root,0)); - do { - const int i=stack.size()-1; - const sStkCLN e=stack[i]; - b3DbvtNode* n=b3CreateNode(&dest,e.parent,e.node->volume,e.node->data); + stack.push_back(sStkCLN(m_root, 0)); + do + { + const int i = stack.size() - 1; + const sStkCLN e = stack[i]; + b3DbvtNode* n = b3CreateNode(&dest, e.parent, e.node->volume, e.node->data); stack.pop_back(); - if(e.parent!=0) - e.parent->childs[i&1]=n; + if (e.parent != 0) + e.parent->childs[i & 1] = n; else - dest.m_root=n; - if(e.node->isinternal()) + dest.m_root = n; + if (e.node->isinternal()) { - stack.push_back(sStkCLN(e.node->childs[0],n)); - stack.push_back(sStkCLN(e.node->childs[1],n)); + stack.push_back(sStkCLN(e.node->childs[0], n)); + stack.push_back(sStkCLN(e.node->childs[1], n)); } else { iclone->CloneLeaf(n); } - } while(stack.size()>0); + } while (stack.size() > 0); } } // -int b3DynamicBvh::maxdepth(const b3DbvtNode* node) +int b3DynamicBvh::maxdepth(const b3DbvtNode* node) { - int depth=0; - if(node) b3GetMaxDepth(node,1,depth); - return(depth); + int depth = 0; + if (node) b3GetMaxDepth(node, 1, depth); + return (depth); } // -int b3DynamicBvh::countLeaves(const b3DbvtNode* node) +int b3DynamicBvh::countLeaves(const b3DbvtNode* node) { - if(node->isinternal()) - return(countLeaves(node->childs[0])+countLeaves(node->childs[1])); + if (node->isinternal()) + return (countLeaves(node->childs[0]) + countLeaves(node->childs[1])); else - return(1); + return (1); } // -void b3DynamicBvh::extractLeaves(const b3DbvtNode* node,b3AlignedObjectArray& leaves) +void b3DynamicBvh::extractLeaves(const b3DbvtNode* node, b3AlignedObjectArray& leaves) { - if(node->isinternal()) + if (node->isinternal()) { - extractLeaves(node->childs[0],leaves); - extractLeaves(node->childs[1],leaves); + extractLeaves(node->childs[0], leaves); + extractLeaves(node->childs[1], leaves); } else { leaves.push_back(node); - } + } } // @@ -682,7 +705,6 @@ void b3DynamicBvh::extractLeaves(const b3DbvtNode* node,b3AlignedObjectArray #include - /* q6600,2.4ghz @@ -722,603 +744,608 @@ struct b3DbvtBenchmark { struct NilPolicy : b3DynamicBvh::ICollide { - NilPolicy() : m_pcount(0),m_depth(-B3_INFINITY),m_checksort(true) {} - void Process(const b3DbvtNode*,const b3DbvtNode*) { ++m_pcount; } - void Process(const b3DbvtNode*) { ++m_pcount; } - void Process(const b3DbvtNode*,b3Scalar depth) + NilPolicy() : m_pcount(0), m_depth(-B3_INFINITY), m_checksort(true) {} + void Process(const b3DbvtNode*, const b3DbvtNode*) { ++m_pcount; } + void Process(const b3DbvtNode*) { ++m_pcount; } + void Process(const b3DbvtNode*, b3Scalar depth) { ++m_pcount; - if(m_checksort) - { if(depth>=m_depth) m_depth=depth; else printf("wrong depth: %f (should be >= %f)\r\n",depth,m_depth); } + if (m_checksort) + { + if (depth >= m_depth) + m_depth = depth; + else + printf("wrong depth: %f (should be >= %f)\r\n", depth, m_depth); + } } - int m_pcount; - b3Scalar m_depth; - bool m_checksort; + int m_pcount; + b3Scalar m_depth; + bool m_checksort; }; struct P14 : b3DynamicBvh::ICollide { struct Node { - const b3DbvtNode* leaf; - b3Scalar depth; + const b3DbvtNode* leaf; + b3Scalar depth; }; - void Process(const b3DbvtNode* leaf,b3Scalar depth) + void Process(const b3DbvtNode* leaf, b3Scalar depth) { - Node n; - n.leaf = leaf; - n.depth = depth; + Node n; + n.leaf = leaf; + n.depth = depth; } - static int sortfnc(const Node& a,const Node& b) + static int sortfnc(const Node& a, const Node& b) { - if(a.depthb.depth) return(-1); - return(0); + if (a.depth < b.depth) return (+1); + if (a.depth > b.depth) return (-1); + return (0); } - b3AlignedObjectArray m_nodes; + b3AlignedObjectArray m_nodes; }; struct P15 : b3DynamicBvh::ICollide { struct Node { - const b3DbvtNode* leaf; - b3Scalar depth; + const b3DbvtNode* leaf; + b3Scalar depth; }; void Process(const b3DbvtNode* leaf) { - Node n; - n.leaf = leaf; - n.depth = dot(leaf->volume.Center(),m_axis); + Node n; + n.leaf = leaf; + n.depth = dot(leaf->volume.Center(), m_axis); } - static int sortfnc(const Node& a,const Node& b) + static int sortfnc(const Node& a, const Node& b) { - if(a.depthb.depth) return(-1); - return(0); + if (a.depth < b.depth) return (+1); + if (a.depth > b.depth) return (-1); + return (0); } - b3AlignedObjectArray m_nodes; - b3Vector3 m_axis; + b3AlignedObjectArray m_nodes; + b3Vector3 m_axis; }; - static b3Scalar RandUnit() + static b3Scalar RandUnit() { - return(rand()/(b3Scalar)RAND_MAX); + return (rand() / (b3Scalar)RAND_MAX); } - static b3Vector3 RandVector3() + static b3Vector3 RandVector3() { - return(b3Vector3(RandUnit(),RandUnit(),RandUnit())); + return (b3Vector3(RandUnit(), RandUnit(), RandUnit())); } - static b3Vector3 RandVector3(b3Scalar cs) + static b3Vector3 RandVector3(b3Scalar cs) { - return(RandVector3()*cs-b3Vector3(cs,cs,cs)/2); + return (RandVector3() * cs - b3Vector3(cs, cs, cs) / 2); } - static b3DbvtVolume RandVolume(b3Scalar cs,b3Scalar eb,b3Scalar es) + static b3DbvtVolume RandVolume(b3Scalar cs, b3Scalar eb, b3Scalar es) { - return(b3DbvtVolume::FromCE(RandVector3(cs),b3Vector3(eb,eb,eb)+RandVector3()*es)); + return (b3DbvtVolume::FromCE(RandVector3(cs), b3Vector3(eb, eb, eb) + RandVector3() * es)); } - static b3Transform RandTransform(b3Scalar cs) + static b3Transform RandTransform(b3Scalar cs) { - b3Transform t; + b3Transform t; t.setOrigin(RandVector3(cs)); - t.setRotation(b3Quaternion(RandUnit()*B3_PI*2,RandUnit()*B3_PI*2,RandUnit()*B3_PI*2).normalized()); - return(t); + t.setRotation(b3Quaternion(RandUnit() * B3_PI * 2, RandUnit() * B3_PI * 2, RandUnit() * B3_PI * 2).normalized()); + return (t); } - static void RandTree(b3Scalar cs,b3Scalar eb,b3Scalar es,int leaves,b3DynamicBvh& dbvt) + static void RandTree(b3Scalar cs, b3Scalar eb, b3Scalar es, int leaves, b3DynamicBvh& dbvt) { dbvt.clear(); - for(int i=0;i volumes; - b3AlignedObjectArray results; + b3AlignedObjectArray volumes; + b3AlignedObjectArray results; volumes.resize(cfgLeaves); results.resize(cfgLeaves); - for(int i=0;i volumes; - b3AlignedObjectArray results; + b3AlignedObjectArray volumes; + b3AlignedObjectArray results; volumes.resize(cfgLeaves); results.resize(cfgLeaves); - for(int i=0;i transforms; - b3DbvtBenchmark::NilPolicy policy; + b3DynamicBvh dbvt[2]; + b3AlignedObjectArray transforms; + b3DbvtBenchmark::NilPolicy policy; transforms.resize(cfgBenchmark5_Iterations); - for(int i=0;i transforms; - b3DbvtBenchmark::NilPolicy policy; + b3DynamicBvh dbvt; + b3AlignedObjectArray transforms; + b3DbvtBenchmark::NilPolicy policy; transforms.resize(cfgBenchmark6_Iterations); - for(int i=0;i rayorg; - b3AlignedObjectArray raydir; - b3DbvtBenchmark::NilPolicy policy; + b3DynamicBvh dbvt; + b3AlignedObjectArray rayorg; + b3AlignedObjectArray raydir; + b3DbvtBenchmark::NilPolicy policy; rayorg.resize(cfgBenchmark7_Iterations); raydir.resize(cfgBenchmark7_Iterations); - for(int i=0;i leaves; - b3DbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); + b3DynamicBvh dbvt; + b3AlignedObjectArray leaves; + b3DbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt); dbvt.optimizeTopDown(); - dbvt.extractLeaves(dbvt.m_root,leaves); + dbvt.extractLeaves(dbvt.m_root, leaves); printf("[9] updates (teleport): "); wallclock.reset(); - for(int i=0;i(leaves[rand()%cfgLeaves]), - b3DbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale)); + dbvt.update(const_cast(leaves[rand() % cfgLeaves]), + b3DbvtBenchmark::RandVolume(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale)); } } - const int time=(int)wallclock.getTimeMilliseconds(); - const int up=cfgBenchmark9_Passes*cfgBenchmark9_Iterations; - printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark9_Reference)*100/time,up*1000/time); + const int time = (int)wallclock.getTimeMilliseconds(); + const int up = cfgBenchmark9_Passes * cfgBenchmark9_Iterations; + printf("%u ms (%i%%),(%u u/s)\r\n", time, (time - cfgBenchmark9_Reference) * 100 / time, up * 1000 / time); } - if(cfgBenchmark10_Enable) - {// Benchmark 10 + if (cfgBenchmark10_Enable) + { // Benchmark 10 srand(380843); - b3DynamicBvh dbvt; - b3AlignedObjectArray leaves; - b3AlignedObjectArray vectors; + b3DynamicBvh dbvt; + b3AlignedObjectArray leaves; + b3AlignedObjectArray vectors; vectors.resize(cfgBenchmark10_Iterations); - for(int i=0;i(leaves[rand()%cfgLeaves]); - b3DbvtVolume v=b3DbvtVolume::FromMM(l->volume.Mins()+d,l->volume.Maxs()+d); - dbvt.update(l,v); + for (int j = 0; j < cfgBenchmark10_Iterations; ++j) + { + const b3Vector3& d = vectors[j]; + b3DbvtNode* l = const_cast(leaves[rand() % cfgLeaves]); + b3DbvtVolume v = b3DbvtVolume::FromMM(l->volume.Mins() + d, l->volume.Maxs() + d); + dbvt.update(l, v); } } - const int time=(int)wallclock.getTimeMilliseconds(); - const int up=cfgBenchmark10_Passes*cfgBenchmark10_Iterations; - printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark10_Reference)*100/time,up*1000/time); + const int time = (int)wallclock.getTimeMilliseconds(); + const int up = cfgBenchmark10_Passes * cfgBenchmark10_Iterations; + printf("%u ms (%i%%),(%u u/s)\r\n", time, (time - cfgBenchmark10_Reference) * 100 / time, up * 1000 / time); } - if(cfgBenchmark11_Enable) - {// Benchmark 11 + if (cfgBenchmark11_Enable) + { // Benchmark 11 srand(380843); - b3DynamicBvh dbvt; - b3DbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); + b3DynamicBvh dbvt; + b3DbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt); dbvt.optimizeTopDown(); printf("[11] optimize (incremental): "); - wallclock.reset(); - for(int i=0;i volumes; - b3AlignedObjectArray results; + b3AlignedObjectArray volumes; + b3AlignedObjectArray results; volumes.resize(cfgLeaves); results.resize(cfgLeaves); - for(int i=0;i vectors; - b3DbvtBenchmark::NilPolicy policy; + b3DynamicBvh dbvt; + b3AlignedObjectArray vectors; + b3DbvtBenchmark::NilPolicy policy; vectors.resize(cfgBenchmark13_Iterations); - for(int i=0;i vectors; - b3DbvtBenchmark::P14 policy; + b3DynamicBvh dbvt; + b3AlignedObjectArray vectors; + b3DbvtBenchmark::P14 policy; vectors.resize(cfgBenchmark14_Iterations); - for(int i=0;i vectors; - b3DbvtBenchmark::P15 policy; + b3DynamicBvh dbvt; + b3AlignedObjectArray vectors; + b3DbvtBenchmark::P15 policy; vectors.resize(cfgBenchmark15_Iterations); - for(int i=0;i batch; - b3DbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); + b3DynamicBvh dbvt; + b3AlignedObjectArray batch; + b3DbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt); dbvt.optimizeTopDown(); batch.reserve(cfgBenchmark16_BatchCount); - printf("[16] insert/remove batch(%u): ",cfgBenchmark16_BatchCount); + printf("[16] insert/remove batch(%u): ", cfgBenchmark16_BatchCount); wallclock.reset(); - for(int i=0;i volumes; - b3AlignedObjectArray results; - b3AlignedObjectArray indices; + b3AlignedObjectArray volumes; + b3AlignedObjectArray results; + b3AlignedObjectArray indices; volumes.resize(cfgLeaves); results.resize(cfgLeaves); indices.resize(cfgLeaves); - for(int i=0;i= 1400) -#define B3_DBVT_USE_TEMPLATE 1 +#if (defined(_MSC_VER) && _MSC_VER >= 1400) +#define B3_DBVT_USE_TEMPLATE 1 #else -#define B3_DBVT_USE_TEMPLATE 0 +#define B3_DBVT_USE_TEMPLATE 0 #endif #else -#define B3_DBVT_USE_TEMPLATE 0 +#define B3_DBVT_USE_TEMPLATE 0 #endif // Use only intrinsics instead of inline asm -#define B3_DBVT_USE_INTRINSIC_SSE 1 +#define B3_DBVT_USE_INTRINSIC_SSE 1 // Using memmov for collideOCL -#define B3_DBVT_USE_MEMMOVE 1 +#define B3_DBVT_USE_MEMMOVE 1 // Enable benchmarking code -#define B3_DBVT_ENABLE_BENCHMARK 0 +#define B3_DBVT_ENABLE_BENCHMARK 0 // Inlining -#define B3_DBVT_INLINE B3_FORCE_INLINE +#define B3_DBVT_INLINE B3_FORCE_INLINE // Specific methods implementation //SSE gives errors on a MSVC 7.1 -#if defined (B3_USE_SSE) //&& defined (_WIN32) -#define B3_DBVT_SELECT_IMPL B3_DBVT_IMPL_SSE -#define B3_DBVT_MERGE_IMPL B3_DBVT_IMPL_SSE -#define B3_DBVT_INT0_IMPL B3_DBVT_IMPL_SSE +#if defined(B3_USE_SSE) //&& defined (_WIN32) +#define B3_DBVT_SELECT_IMPL B3_DBVT_IMPL_SSE +#define B3_DBVT_MERGE_IMPL B3_DBVT_IMPL_SSE +#define B3_DBVT_INT0_IMPL B3_DBVT_IMPL_SSE #else -#define B3_DBVT_SELECT_IMPL B3_DBVT_IMPL_GENERIC -#define B3_DBVT_MERGE_IMPL B3_DBVT_IMPL_GENERIC -#define B3_DBVT_INT0_IMPL B3_DBVT_IMPL_GENERIC +#define B3_DBVT_SELECT_IMPL B3_DBVT_IMPL_GENERIC +#define B3_DBVT_MERGE_IMPL B3_DBVT_IMPL_GENERIC +#define B3_DBVT_INT0_IMPL B3_DBVT_IMPL_GENERIC #endif -#if (B3_DBVT_SELECT_IMPL==B3_DBVT_IMPL_SSE)|| \ - (B3_DBVT_MERGE_IMPL==B3_DBVT_IMPL_SSE)|| \ - (B3_DBVT_INT0_IMPL==B3_DBVT_IMPL_SSE) +#if (B3_DBVT_SELECT_IMPL == B3_DBVT_IMPL_SSE) || \ + (B3_DBVT_MERGE_IMPL == B3_DBVT_IMPL_SSE) || \ + (B3_DBVT_INT0_IMPL == B3_DBVT_IMPL_SSE) #include #endif @@ -78,21 +77,24 @@ subject to the following restrictions: // #if B3_DBVT_USE_TEMPLATE -#define B3_DBVT_VIRTUAL +#define B3_DBVT_VIRTUAL #define B3_DBVT_VIRTUAL_DTOR(a) -#define B3_DBVT_PREFIX template -#define B3_DBVT_IPOLICY T& policy -#define B3_DBVT_CHECKTYPE static const ICollide& typechecker=*(T*)1;(void)typechecker; +#define B3_DBVT_PREFIX template +#define B3_DBVT_IPOLICY T& policy +#define B3_DBVT_CHECKTYPE \ + static const ICollide& typechecker = *(T*)1; \ + (void)typechecker; #else -#define B3_DBVT_VIRTUAL_DTOR(a) virtual ~a() {} -#define B3_DBVT_VIRTUAL virtual +#define B3_DBVT_VIRTUAL_DTOR(a) \ + virtual ~a() {} +#define B3_DBVT_VIRTUAL virtual #define B3_DBVT_PREFIX -#define B3_DBVT_IPOLICY ICollide& policy +#define B3_DBVT_IPOLICY ICollide& policy #define B3_DBVT_CHECKTYPE #endif #if B3_DBVT_USE_MEMMOVE -#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__) +#if !defined(__CELLOS_LV2__) && !defined(__MWERKS__) #include #endif #include @@ -126,187 +128,188 @@ subject to the following restrictions: // Defaults volumes // -/* b3DbvtAabbMm */ -struct b3DbvtAabbMm +/* b3DbvtAabbMm */ +struct b3DbvtAabbMm { - B3_DBVT_INLINE b3Vector3 Center() const { return((mi+mx)/2); } - B3_DBVT_INLINE b3Vector3 Lengths() const { return(mx-mi); } - B3_DBVT_INLINE b3Vector3 Extents() const { return((mx-mi)/2); } - B3_DBVT_INLINE const b3Vector3& Mins() const { return(mi); } - B3_DBVT_INLINE const b3Vector3& Maxs() const { return(mx); } - static inline b3DbvtAabbMm FromCE(const b3Vector3& c,const b3Vector3& e); - static inline b3DbvtAabbMm FromCR(const b3Vector3& c,b3Scalar r); - static inline b3DbvtAabbMm FromMM(const b3Vector3& mi,const b3Vector3& mx); - static inline b3DbvtAabbMm FromPoints(const b3Vector3* pts,int n); - static inline b3DbvtAabbMm FromPoints(const b3Vector3** ppts,int n); - B3_DBVT_INLINE void Expand(const b3Vector3& e); - B3_DBVT_INLINE void SignedExpand(const b3Vector3& e); - B3_DBVT_INLINE bool Contain(const b3DbvtAabbMm& a) const; - B3_DBVT_INLINE int Classify(const b3Vector3& n,b3Scalar o,int s) const; - B3_DBVT_INLINE b3Scalar ProjectMinimum(const b3Vector3& v,unsigned signs) const; - B3_DBVT_INLINE friend bool b3Intersect( const b3DbvtAabbMm& a, - const b3DbvtAabbMm& b); - - B3_DBVT_INLINE friend bool b3Intersect( const b3DbvtAabbMm& a, - const b3Vector3& b); + B3_DBVT_INLINE b3Vector3 Center() const { return ((mi + mx) / 2); } + B3_DBVT_INLINE b3Vector3 Lengths() const { return (mx - mi); } + B3_DBVT_INLINE b3Vector3 Extents() const { return ((mx - mi) / 2); } + B3_DBVT_INLINE const b3Vector3& Mins() const { return (mi); } + B3_DBVT_INLINE const b3Vector3& Maxs() const { return (mx); } + static inline b3DbvtAabbMm FromCE(const b3Vector3& c, const b3Vector3& e); + static inline b3DbvtAabbMm FromCR(const b3Vector3& c, b3Scalar r); + static inline b3DbvtAabbMm FromMM(const b3Vector3& mi, const b3Vector3& mx); + static inline b3DbvtAabbMm FromPoints(const b3Vector3* pts, int n); + static inline b3DbvtAabbMm FromPoints(const b3Vector3** ppts, int n); + B3_DBVT_INLINE void Expand(const b3Vector3& e); + B3_DBVT_INLINE void SignedExpand(const b3Vector3& e); + B3_DBVT_INLINE bool Contain(const b3DbvtAabbMm& a) const; + B3_DBVT_INLINE int Classify(const b3Vector3& n, b3Scalar o, int s) const; + B3_DBVT_INLINE b3Scalar ProjectMinimum(const b3Vector3& v, unsigned signs) const; + B3_DBVT_INLINE friend bool b3Intersect(const b3DbvtAabbMm& a, + const b3DbvtAabbMm& b); + + B3_DBVT_INLINE friend bool b3Intersect(const b3DbvtAabbMm& a, + const b3Vector3& b); + + B3_DBVT_INLINE friend b3Scalar b3Proximity(const b3DbvtAabbMm& a, + const b3DbvtAabbMm& b); + B3_DBVT_INLINE friend int b3Select(const b3DbvtAabbMm& o, + const b3DbvtAabbMm& a, + const b3DbvtAabbMm& b); + B3_DBVT_INLINE friend void b3Merge(const b3DbvtAabbMm& a, + const b3DbvtAabbMm& b, + b3DbvtAabbMm& r); + B3_DBVT_INLINE friend bool b3NotEqual(const b3DbvtAabbMm& a, + const b3DbvtAabbMm& b); + + B3_DBVT_INLINE b3Vector3& tMins() { return (mi); } + B3_DBVT_INLINE b3Vector3& tMaxs() { return (mx); } - B3_DBVT_INLINE friend b3Scalar b3Proximity( const b3DbvtAabbMm& a, - const b3DbvtAabbMm& b); - B3_DBVT_INLINE friend int b3Select( const b3DbvtAabbMm& o, - const b3DbvtAabbMm& a, - const b3DbvtAabbMm& b); - B3_DBVT_INLINE friend void b3Merge( const b3DbvtAabbMm& a, - const b3DbvtAabbMm& b, - b3DbvtAabbMm& r); - B3_DBVT_INLINE friend bool b3NotEqual( const b3DbvtAabbMm& a, - const b3DbvtAabbMm& b); - - B3_DBVT_INLINE b3Vector3& tMins() { return(mi); } - B3_DBVT_INLINE b3Vector3& tMaxs() { return(mx); } - private: - B3_DBVT_INLINE void AddSpan(const b3Vector3& d,b3Scalar& smi,b3Scalar& smx) const; + B3_DBVT_INLINE void AddSpan(const b3Vector3& d, b3Scalar& smi, b3Scalar& smx) const; + private: - b3Vector3 mi,mx; + b3Vector3 mi, mx; }; -// Types -typedef b3DbvtAabbMm b3DbvtVolume; +// Types +typedef b3DbvtAabbMm b3DbvtVolume; -/* b3DbvtNode */ -struct b3DbvtNode +/* b3DbvtNode */ +struct b3DbvtNode { - b3DbvtVolume volume; - b3DbvtNode* parent; - B3_DBVT_INLINE bool isleaf() const { return(childs[1]==0); } - B3_DBVT_INLINE bool isinternal() const { return(!isleaf()); } - union - { - b3DbvtNode* childs[2]; - void* data; - int dataAsInt; + b3DbvtVolume volume; + b3DbvtNode* parent; + B3_DBVT_INLINE bool isleaf() const { return (childs[1] == 0); } + B3_DBVT_INLINE bool isinternal() const { return (!isleaf()); } + union { + b3DbvtNode* childs[2]; + void* data; + int dataAsInt; }; }; ///The b3DynamicBvh class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes (aabb tree). ///This b3DynamicBvh is used for soft body collision detection and for the b3DynamicBvhBroadphase. It has a fast insert, remove and update of nodes. ///Unlike the b3QuantizedBvh, nodes can be dynamically moved around, which allows for change in topology of the underlying data structure. -struct b3DynamicBvh +struct b3DynamicBvh { - /* Stack element */ - struct sStkNN + /* Stack element */ + struct sStkNN { - const b3DbvtNode* a; - const b3DbvtNode* b; + const b3DbvtNode* a; + const b3DbvtNode* b; sStkNN() {} - sStkNN(const b3DbvtNode* na,const b3DbvtNode* nb) : a(na),b(nb) {} + sStkNN(const b3DbvtNode* na, const b3DbvtNode* nb) : a(na), b(nb) {} }; - struct sStkNP + struct sStkNP { - const b3DbvtNode* node; - int mask; - sStkNP(const b3DbvtNode* n,unsigned m) : node(n),mask(m) {} + const b3DbvtNode* node; + int mask; + sStkNP(const b3DbvtNode* n, unsigned m) : node(n), mask(m) {} }; - struct sStkNPS + struct sStkNPS { - const b3DbvtNode* node; - int mask; - b3Scalar value; + const b3DbvtNode* node; + int mask; + b3Scalar value; sStkNPS() {} - sStkNPS(const b3DbvtNode* n,unsigned m,b3Scalar v) : node(n),mask(m),value(v) {} + sStkNPS(const b3DbvtNode* n, unsigned m, b3Scalar v) : node(n), mask(m), value(v) {} }; - struct sStkCLN + struct sStkCLN { - const b3DbvtNode* node; - b3DbvtNode* parent; - sStkCLN(const b3DbvtNode* n,b3DbvtNode* p) : node(n),parent(p) {} + const b3DbvtNode* node; + b3DbvtNode* parent; + sStkCLN(const b3DbvtNode* n, b3DbvtNode* p) : node(n), parent(p) {} }; // Policies/Interfaces - /* ICollide */ - struct ICollide - { + /* ICollide */ + struct ICollide + { B3_DBVT_VIRTUAL_DTOR(ICollide) - B3_DBVT_VIRTUAL void Process(const b3DbvtNode*,const b3DbvtNode*) {} - B3_DBVT_VIRTUAL void Process(const b3DbvtNode*) {} - B3_DBVT_VIRTUAL void Process(const b3DbvtNode* n,b3Scalar) { Process(n); } - B3_DBVT_VIRTUAL bool Descent(const b3DbvtNode*) { return(true); } - B3_DBVT_VIRTUAL bool AllLeaves(const b3DbvtNode*) { return(true); } + B3_DBVT_VIRTUAL void Process(const b3DbvtNode*, const b3DbvtNode*) {} + B3_DBVT_VIRTUAL void Process(const b3DbvtNode*) {} + B3_DBVT_VIRTUAL void Process(const b3DbvtNode* n, b3Scalar) { Process(n); } + B3_DBVT_VIRTUAL bool Descent(const b3DbvtNode*) { return (true); } + B3_DBVT_VIRTUAL bool AllLeaves(const b3DbvtNode*) { return (true); } }; - /* IWriter */ - struct IWriter + /* IWriter */ + struct IWriter { virtual ~IWriter() {} - virtual void Prepare(const b3DbvtNode* root,int numnodes)=0; - virtual void WriteNode(const b3DbvtNode*,int index,int parent,int child0,int child1)=0; - virtual void WriteLeaf(const b3DbvtNode*,int index,int parent)=0; + virtual void Prepare(const b3DbvtNode* root, int numnodes) = 0; + virtual void WriteNode(const b3DbvtNode*, int index, int parent, int child0, int child1) = 0; + virtual void WriteLeaf(const b3DbvtNode*, int index, int parent) = 0; }; - /* IClone */ - struct IClone + /* IClone */ + struct IClone { - virtual ~IClone() {} - virtual void CloneLeaf(b3DbvtNode*) {} + virtual ~IClone() {} + virtual void CloneLeaf(b3DbvtNode*) {} }; // Constants - enum { - B3_SIMPLE_STACKSIZE = 64, - B3_DOUBLE_STACKSIZE = B3_SIMPLE_STACKSIZE*2 + enum + { + B3_SIMPLE_STACKSIZE = 64, + B3_DOUBLE_STACKSIZE = B3_SIMPLE_STACKSIZE * 2 }; // Fields - b3DbvtNode* m_root; - b3DbvtNode* m_free; - int m_lkhd; - int m_leaves; - unsigned m_opath; - - - b3AlignedObjectArray m_stkStack; - mutable b3AlignedObjectArray m_rayTestStack; + b3DbvtNode* m_root; + b3DbvtNode* m_free; + int m_lkhd; + int m_leaves; + unsigned m_opath; + b3AlignedObjectArray m_stkStack; + mutable b3AlignedObjectArray m_rayTestStack; // Methods b3DynamicBvh(); ~b3DynamicBvh(); - void clear(); - bool empty() const { return(0==m_root); } - void optimizeBottomUp(); - void optimizeTopDown(int bu_treshold=128); - void optimizeIncremental(int passes); - b3DbvtNode* insert(const b3DbvtVolume& box,void* data); - void update(b3DbvtNode* leaf,int lookahead=-1); - void update(b3DbvtNode* leaf,b3DbvtVolume& volume); - bool update(b3DbvtNode* leaf,b3DbvtVolume& volume,const b3Vector3& velocity,b3Scalar margin); - bool update(b3DbvtNode* leaf,b3DbvtVolume& volume,const b3Vector3& velocity); - bool update(b3DbvtNode* leaf,b3DbvtVolume& volume,b3Scalar margin); - void remove(b3DbvtNode* leaf); - void write(IWriter* iwriter) const; - void clone(b3DynamicBvh& dest,IClone* iclone=0) const; - static int maxdepth(const b3DbvtNode* node); - static int countLeaves(const b3DbvtNode* node); - static void extractLeaves(const b3DbvtNode* node,b3AlignedObjectArray& leaves); + void clear(); + bool empty() const { return (0 == m_root); } + void optimizeBottomUp(); + void optimizeTopDown(int bu_treshold = 128); + void optimizeIncremental(int passes); + b3DbvtNode* insert(const b3DbvtVolume& box, void* data); + void update(b3DbvtNode* leaf, int lookahead = -1); + void update(b3DbvtNode* leaf, b3DbvtVolume& volume); + bool update(b3DbvtNode* leaf, b3DbvtVolume& volume, const b3Vector3& velocity, b3Scalar margin); + bool update(b3DbvtNode* leaf, b3DbvtVolume& volume, const b3Vector3& velocity); + bool update(b3DbvtNode* leaf, b3DbvtVolume& volume, b3Scalar margin); + void remove(b3DbvtNode* leaf); + void write(IWriter* iwriter) const; + void clone(b3DynamicBvh& dest, IClone* iclone = 0) const; + static int maxdepth(const b3DbvtNode* node); + static int countLeaves(const b3DbvtNode* node); + static void extractLeaves(const b3DbvtNode* node, b3AlignedObjectArray& leaves); #if B3_DBVT_ENABLE_BENCHMARK - static void benchmark(); + static void benchmark(); #else - static void benchmark(){} + static void benchmark() + { + } #endif // B3_DBVT_IPOLICY must support ICollide policy/interface B3_DBVT_PREFIX - static void enumNodes( const b3DbvtNode* root, - B3_DBVT_IPOLICY); + static void enumNodes(const b3DbvtNode* root, + B3_DBVT_IPOLICY); B3_DBVT_PREFIX - static void enumLeaves( const b3DbvtNode* root, - B3_DBVT_IPOLICY); + static void enumLeaves(const b3DbvtNode* root, + B3_DBVT_IPOLICY); B3_DBVT_PREFIX - void collideTT( const b3DbvtNode* root0, - const b3DbvtNode* root1, - B3_DBVT_IPOLICY); + void collideTT(const b3DbvtNode* root0, + const b3DbvtNode* root1, + B3_DBVT_IPOLICY); B3_DBVT_PREFIX - void collideTTpersistentStack( const b3DbvtNode* root0, - const b3DbvtNode* root1, - B3_DBVT_IPOLICY); + void collideTTpersistentStack(const b3DbvtNode* root0, + const b3DbvtNode* root1, + B3_DBVT_IPOLICY); #if 0 B3_DBVT_PREFIX void collideTT( const b3DbvtNode* root0, @@ -322,71 +325,81 @@ struct b3DynamicBvh #endif B3_DBVT_PREFIX - void collideTV( const b3DbvtNode* root, - const b3DbvtVolume& volume, - B3_DBVT_IPOLICY) const; + void collideTV(const b3DbvtNode* root, + const b3DbvtVolume& volume, + B3_DBVT_IPOLICY) const; ///rayTest is a re-entrant ray test, and can be called in parallel as long as the b3AlignedAlloc is thread-safe (uses locking etc) ///rayTest is slower than rayTestInternal, because it builds a local stack, using memory allocations, and it recomputes signs/rayDirectionInverses each time B3_DBVT_PREFIX - static void rayTest( const b3DbvtNode* root, - const b3Vector3& rayFrom, - const b3Vector3& rayTo, - B3_DBVT_IPOLICY); + static void rayTest(const b3DbvtNode* root, + const b3Vector3& rayFrom, + const b3Vector3& rayTo, + B3_DBVT_IPOLICY); ///rayTestInternal is faster than rayTest, because it uses a persistent stack (to reduce dynamic memory allocations to a minimum) and it uses precomputed signs/rayInverseDirections ///rayTestInternal is used by b3DynamicBvhBroadphase to accelerate world ray casts B3_DBVT_PREFIX - void rayTestInternal( const b3DbvtNode* root, - const b3Vector3& rayFrom, - const b3Vector3& rayTo, - const b3Vector3& rayDirectionInverse, - unsigned int signs[3], - b3Scalar lambda_max, - const b3Vector3& aabbMin, - const b3Vector3& aabbMax, - B3_DBVT_IPOLICY) const; + void rayTestInternal(const b3DbvtNode* root, + const b3Vector3& rayFrom, + const b3Vector3& rayTo, + const b3Vector3& rayDirectionInverse, + unsigned int signs[3], + b3Scalar lambda_max, + const b3Vector3& aabbMin, + const b3Vector3& aabbMax, + B3_DBVT_IPOLICY) const; B3_DBVT_PREFIX - static void collideKDOP(const b3DbvtNode* root, - const b3Vector3* normals, - const b3Scalar* offsets, - int count, - B3_DBVT_IPOLICY); + static void collideKDOP(const b3DbvtNode* root, + const b3Vector3* normals, + const b3Scalar* offsets, + int count, + B3_DBVT_IPOLICY); B3_DBVT_PREFIX - static void collideOCL( const b3DbvtNode* root, - const b3Vector3* normals, - const b3Scalar* offsets, - const b3Vector3& sortaxis, - int count, - B3_DBVT_IPOLICY, - bool fullsort=true); + static void collideOCL(const b3DbvtNode* root, + const b3Vector3* normals, + const b3Scalar* offsets, + const b3Vector3& sortaxis, + int count, + B3_DBVT_IPOLICY, + bool fullsort = true); B3_DBVT_PREFIX - static void collideTU( const b3DbvtNode* root, - B3_DBVT_IPOLICY); - // Helpers - static B3_DBVT_INLINE int nearest(const int* i,const b3DynamicBvh::sStkNPS* a,b3Scalar v,int l,int h) + static void collideTU(const b3DbvtNode* root, + B3_DBVT_IPOLICY); + // Helpers + static B3_DBVT_INLINE int nearest(const int* i, const b3DynamicBvh::sStkNPS* a, b3Scalar v, int l, int h) { - int m=0; - while(l>1; - if(a[i[m]].value>=v) l=m+1; else h=m; + m = (l + h) >> 1; + if (a[i[m]].value >= v) + l = m + 1; + else + h = m; } - return(h); + return (h); } - static B3_DBVT_INLINE int allocate( b3AlignedObjectArray& ifree, - b3AlignedObjectArray& stock, - const sStkNPS& value) + static B3_DBVT_INLINE int allocate(b3AlignedObjectArray& ifree, + b3AlignedObjectArray& stock, + const sStkNPS& value) { - int i; - if(ifree.size()>0) - { i=ifree[ifree.size()-1];ifree.pop_back();stock[i]=value; } + int i; + if (ifree.size() > 0) + { + i = ifree[ifree.size() - 1]; + ifree.pop_back(); + stock[i] = value; + } else - { i=stock.size();stock.push_back(value); } - return(i); + { + i = stock.size(); + stock.push_back(value); + } + return (i); } // private: - b3DynamicBvh(const b3DynamicBvh&) {} + b3DynamicBvh(const b3DynamicBvh&) {} }; // @@ -394,227 +407,252 @@ private: // // -inline b3DbvtAabbMm b3DbvtAabbMm::FromCE(const b3Vector3& c,const b3Vector3& e) +inline b3DbvtAabbMm b3DbvtAabbMm::FromCE(const b3Vector3& c, const b3Vector3& e) { b3DbvtAabbMm box; - box.mi=c-e;box.mx=c+e; - return(box); + box.mi = c - e; + box.mx = c + e; + return (box); } // -inline b3DbvtAabbMm b3DbvtAabbMm::FromCR(const b3Vector3& c,b3Scalar r) +inline b3DbvtAabbMm b3DbvtAabbMm::FromCR(const b3Vector3& c, b3Scalar r) { - return(FromCE(c,b3MakeVector3(r,r,r))); + return (FromCE(c, b3MakeVector3(r, r, r))); } // -inline b3DbvtAabbMm b3DbvtAabbMm::FromMM(const b3Vector3& mi,const b3Vector3& mx) +inline b3DbvtAabbMm b3DbvtAabbMm::FromMM(const b3Vector3& mi, const b3Vector3& mx) { b3DbvtAabbMm box; - box.mi=mi;box.mx=mx; - return(box); + box.mi = mi; + box.mx = mx; + return (box); } // -inline b3DbvtAabbMm b3DbvtAabbMm::FromPoints(const b3Vector3* pts,int n) +inline b3DbvtAabbMm b3DbvtAabbMm::FromPoints(const b3Vector3* pts, int n) { b3DbvtAabbMm box; - box.mi=box.mx=pts[0]; - for(int i=1;i0) mx.setX(mx.x+e[0]); else mi.setX(mi.x+e[0]); - if(e.y>0) mx.setY(mx.y+e[1]); else mi.setY(mi.y+e[1]); - if(e.z>0) mx.setZ(mx.z+e[2]); else mi.setZ(mi.z+e[2]); + if (e.x > 0) + mx.setX(mx.x + e[0]); + else + mi.setX(mi.x + e[0]); + if (e.y > 0) + mx.setY(mx.y + e[1]); + else + mi.setY(mi.y + e[1]); + if (e.z > 0) + mx.setZ(mx.z + e[2]); + else + mi.setZ(mi.z + e[2]); } // -B3_DBVT_INLINE bool b3DbvtAabbMm::Contain(const b3DbvtAabbMm& a) const +B3_DBVT_INLINE bool b3DbvtAabbMm::Contain(const b3DbvtAabbMm& a) const { - return( (mi.x<=a.mi.x)&& - (mi.y<=a.mi.y)&& - (mi.z<=a.mi.z)&& - (mx.x>=a.mx.x)&& - (mx.y>=a.mx.y)&& - (mx.z>=a.mx.z)); + return ((mi.x <= a.mi.x) && + (mi.y <= a.mi.y) && + (mi.z <= a.mi.z) && + (mx.x >= a.mx.x) && + (mx.y >= a.mx.y) && + (mx.z >= a.mx.z)); } // -B3_DBVT_INLINE int b3DbvtAabbMm::Classify(const b3Vector3& n,b3Scalar o,int s) const +B3_DBVT_INLINE int b3DbvtAabbMm::Classify(const b3Vector3& n, b3Scalar o, int s) const { - b3Vector3 pi,px; - switch(s) + b3Vector3 pi, px; + switch (s) { - case (0+0+0): px=b3MakeVector3(mi.x,mi.y,mi.z); - pi=b3MakeVector3(mx.x,mx.y,mx.z);break; - case (1+0+0): px=b3MakeVector3(mx.x,mi.y,mi.z); - pi=b3MakeVector3(mi.x,mx.y,mx.z);break; - case (0+2+0): px=b3MakeVector3(mi.x,mx.y,mi.z); - pi=b3MakeVector3(mx.x,mi.y,mx.z);break; - case (1+2+0): px=b3MakeVector3(mx.x,mx.y,mi.z); - pi=b3MakeVector3(mi.x,mi.y,mx.z);break; - case (0+0+4): px=b3MakeVector3(mi.x,mi.y,mx.z); - pi=b3MakeVector3(mx.x,mx.y,mi.z);break; - case (1+0+4): px=b3MakeVector3(mx.x,mi.y,mx.z); - pi=b3MakeVector3(mi.x,mx.y,mi.z);break; - case (0+2+4): px=b3MakeVector3(mi.x,mx.y,mx.z); - pi=b3MakeVector3(mx.x,mi.y,mi.z);break; - case (1+2+4): px=b3MakeVector3(mx.x,mx.y,mx.z); - pi=b3MakeVector3(mi.x,mi.y,mi.z);break; + case (0 + 0 + 0): + px = b3MakeVector3(mi.x, mi.y, mi.z); + pi = b3MakeVector3(mx.x, mx.y, mx.z); + break; + case (1 + 0 + 0): + px = b3MakeVector3(mx.x, mi.y, mi.z); + pi = b3MakeVector3(mi.x, mx.y, mx.z); + break; + case (0 + 2 + 0): + px = b3MakeVector3(mi.x, mx.y, mi.z); + pi = b3MakeVector3(mx.x, mi.y, mx.z); + break; + case (1 + 2 + 0): + px = b3MakeVector3(mx.x, mx.y, mi.z); + pi = b3MakeVector3(mi.x, mi.y, mx.z); + break; + case (0 + 0 + 4): + px = b3MakeVector3(mi.x, mi.y, mx.z); + pi = b3MakeVector3(mx.x, mx.y, mi.z); + break; + case (1 + 0 + 4): + px = b3MakeVector3(mx.x, mi.y, mx.z); + pi = b3MakeVector3(mi.x, mx.y, mi.z); + break; + case (0 + 2 + 4): + px = b3MakeVector3(mi.x, mx.y, mx.z); + pi = b3MakeVector3(mx.x, mi.y, mi.z); + break; + case (1 + 2 + 4): + px = b3MakeVector3(mx.x, mx.y, mx.z); + pi = b3MakeVector3(mi.x, mi.y, mi.z); + break; } - if((b3Dot(n,px)+o)<0) return(-1); - if((b3Dot(n,pi)+o)>=0) return(+1); - return(0); + if ((b3Dot(n, px) + o) < 0) return (-1); + if ((b3Dot(n, pi) + o) >= 0) return (+1); + return (0); } // -B3_DBVT_INLINE b3Scalar b3DbvtAabbMm::ProjectMinimum(const b3Vector3& v,unsigned signs) const +B3_DBVT_INLINE b3Scalar b3DbvtAabbMm::ProjectMinimum(const b3Vector3& v, unsigned signs) const { - const b3Vector3* b[]={&mx,&mi}; - const b3Vector3 p = b3MakeVector3( b[(signs>>0)&1]->x, - b[(signs>>1)&1]->y, - b[(signs>>2)&1]->z); - return(b3Dot(p,v)); + const b3Vector3* b[] = {&mx, &mi}; + const b3Vector3 p = b3MakeVector3(b[(signs >> 0) & 1]->x, + b[(signs >> 1) & 1]->y, + b[(signs >> 2) & 1]->z); + return (b3Dot(p, v)); } // -B3_DBVT_INLINE void b3DbvtAabbMm::AddSpan(const b3Vector3& d,b3Scalar& smi,b3Scalar& smx) const +B3_DBVT_INLINE void b3DbvtAabbMm::AddSpan(const b3Vector3& d, b3Scalar& smi, b3Scalar& smx) const { - for(int i=0;i<3;++i) + for (int i = 0; i < 3; ++i) { - if(d[i]<0) - { smi+=mx[i]*d[i];smx+=mi[i]*d[i]; } + if (d[i] < 0) + { + smi += mx[i] * d[i]; + smx += mi[i] * d[i]; + } else - { smi+=mi[i]*d[i];smx+=mx[i]*d[i]; } + { + smi += mi[i] * d[i]; + smx += mx[i] * d[i]; + } } } // -B3_DBVT_INLINE bool b3Intersect( const b3DbvtAabbMm& a, - const b3DbvtAabbMm& b) +B3_DBVT_INLINE bool b3Intersect(const b3DbvtAabbMm& a, + const b3DbvtAabbMm& b) { -#if B3_DBVT_INT0_IMPL == B3_DBVT_IMPL_SSE - const __m128 rt(_mm_or_ps( _mm_cmplt_ps(_mm_load_ps(b.mx),_mm_load_ps(a.mi)), - _mm_cmplt_ps(_mm_load_ps(a.mx),_mm_load_ps(b.mi)))); -#if defined (_WIN32) - const __int32* pu((const __int32*)&rt); +#if B3_DBVT_INT0_IMPL == B3_DBVT_IMPL_SSE + const __m128 rt(_mm_or_ps(_mm_cmplt_ps(_mm_load_ps(b.mx), _mm_load_ps(a.mi)), + _mm_cmplt_ps(_mm_load_ps(a.mx), _mm_load_ps(b.mi)))); +#if defined(_WIN32) + const __int32* pu((const __int32*)&rt); #else - const int* pu((const int*)&rt); + const int* pu((const int*)&rt); #endif - return((pu[0]|pu[1]|pu[2])==0); + return ((pu[0] | pu[1] | pu[2]) == 0); #else - return( (a.mi.x<=b.mx.x)&& - (a.mx.x>=b.mi.x)&& - (a.mi.y<=b.mx.y)&& - (a.mx.y>=b.mi.y)&& - (a.mi.z<=b.mx.z)&& - (a.mx.z>=b.mi.z)); + return ((a.mi.x <= b.mx.x) && + (a.mx.x >= b.mi.x) && + (a.mi.y <= b.mx.y) && + (a.mx.y >= b.mi.y) && + (a.mi.z <= b.mx.z) && + (a.mx.z >= b.mi.z)); #endif } - - // -B3_DBVT_INLINE bool b3Intersect( const b3DbvtAabbMm& a, - const b3Vector3& b) +B3_DBVT_INLINE bool b3Intersect(const b3DbvtAabbMm& a, + const b3Vector3& b) { - return( (b.x>=a.mi.x)&& - (b.y>=a.mi.y)&& - (b.z>=a.mi.z)&& - (b.x<=a.mx.x)&& - (b.y<=a.mx.y)&& - (b.z<=a.mx.z)); + return ((b.x >= a.mi.x) && + (b.y >= a.mi.y) && + (b.z >= a.mi.z) && + (b.x <= a.mx.x) && + (b.y <= a.mx.y) && + (b.z <= a.mx.z)); } - - - - ////////////////////////////////////// - // -B3_DBVT_INLINE b3Scalar b3Proximity( const b3DbvtAabbMm& a, - const b3DbvtAabbMm& b) +B3_DBVT_INLINE b3Scalar b3Proximity(const b3DbvtAabbMm& a, + const b3DbvtAabbMm& b) { - const b3Vector3 d=(a.mi+a.mx)-(b.mi+b.mx); - return(b3Fabs(d.x)+b3Fabs(d.y)+b3Fabs(d.z)); + const b3Vector3 d = (a.mi + a.mx) - (b.mi + b.mx); + return (b3Fabs(d.x) + b3Fabs(d.y) + b3Fabs(d.z)); } - - // -B3_DBVT_INLINE int b3Select( const b3DbvtAabbMm& o, - const b3DbvtAabbMm& a, - const b3DbvtAabbMm& b) +B3_DBVT_INLINE int b3Select(const b3DbvtAabbMm& o, + const b3DbvtAabbMm& a, + const b3DbvtAabbMm& b) { -#if B3_DBVT_SELECT_IMPL == B3_DBVT_IMPL_SSE - -#if defined (_WIN32) - static B3_ATTRIBUTE_ALIGNED16(const unsigned __int32) mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff}; +#if B3_DBVT_SELECT_IMPL == B3_DBVT_IMPL_SSE + +#if defined(_WIN32) + static B3_ATTRIBUTE_ALIGNED16(const unsigned __int32) mask[] = {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}; #else - static B3_ATTRIBUTE_ALIGNED16(const unsigned int) mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x00000000 /*0x7fffffff*/}; + static B3_ATTRIBUTE_ALIGNED16(const unsigned int) mask[] = {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x00000000 /*0x7fffffff*/}; #endif ///@todo: the intrinsic version is 11% slower #if B3_DBVT_USE_INTRINSIC_SSE - union b3SSEUnion ///NOTE: if we use more intrinsics, move b3SSEUnion into the LinearMath directory + union b3SSEUnion ///NOTE: if we use more intrinsics, move b3SSEUnion into the LinearMath directory { - __m128 ssereg; - float floats[4]; - int ints[4]; + __m128 ssereg; + float floats[4]; + int ints[4]; }; - __m128 omi(_mm_load_ps(o.mi)); - omi=_mm_add_ps(omi,_mm_load_ps(o.mx)); - __m128 ami(_mm_load_ps(a.mi)); - ami=_mm_add_ps(ami,_mm_load_ps(a.mx)); - ami=_mm_sub_ps(ami,omi); - ami=_mm_and_ps(ami,_mm_load_ps((const float*)mask)); - __m128 bmi(_mm_load_ps(b.mi)); - bmi=_mm_add_ps(bmi,_mm_load_ps(b.mx)); - bmi=_mm_sub_ps(bmi,omi); - bmi=_mm_and_ps(bmi,_mm_load_ps((const float*)mask)); - __m128 t0(_mm_movehl_ps(ami,ami)); - ami=_mm_add_ps(ami,t0); - ami=_mm_add_ss(ami,_mm_shuffle_ps(ami,ami,1)); - __m128 t1(_mm_movehl_ps(bmi,bmi)); - bmi=_mm_add_ps(bmi,t1); - bmi=_mm_add_ss(bmi,_mm_shuffle_ps(bmi,bmi,1)); - + __m128 omi(_mm_load_ps(o.mi)); + omi = _mm_add_ps(omi, _mm_load_ps(o.mx)); + __m128 ami(_mm_load_ps(a.mi)); + ami = _mm_add_ps(ami, _mm_load_ps(a.mx)); + ami = _mm_sub_ps(ami, omi); + ami = _mm_and_ps(ami, _mm_load_ps((const float*)mask)); + __m128 bmi(_mm_load_ps(b.mi)); + bmi = _mm_add_ps(bmi, _mm_load_ps(b.mx)); + bmi = _mm_sub_ps(bmi, omi); + bmi = _mm_and_ps(bmi, _mm_load_ps((const float*)mask)); + __m128 t0(_mm_movehl_ps(ami, ami)); + ami = _mm_add_ps(ami, t0); + ami = _mm_add_ss(ami, _mm_shuffle_ps(ami, ami, 1)); + __m128 t1(_mm_movehl_ps(bmi, bmi)); + bmi = _mm_add_ps(bmi, t1); + bmi = _mm_add_ss(bmi, _mm_shuffle_ps(bmi, bmi, 1)); + b3SSEUnion tmp; - tmp.ssereg = _mm_cmple_ss(bmi,ami); - return tmp.ints[0]&1; + tmp.ssereg = _mm_cmple_ss(bmi, ami); + return tmp.ints[0] & 1; #else - B3_ATTRIBUTE_ALIGNED16(__int32 r[1]); + B3_ATTRIBUTE_ALIGNED16(__int32 r[1]); __asm { mov eax,o @@ -642,46 +680,52 @@ B3_DBVT_INLINE int b3Select( const b3DbvtAabbMm& o, cmpless xmm2,xmm1 movss r,xmm2 } - return(r[0]&1); + return (r[0] & 1); #endif #else - return(b3Proximity(o,a)b.mx[i]) r.mx[i]=a.mx[i]; else r.mx[i]=b.mx[i]; + if (a.mi[i] < b.mi[i]) + r.mi[i] = a.mi[i]; + else + r.mi[i] = b.mi[i]; + if (a.mx[i] > b.mx[i]) + r.mx[i] = a.mx[i]; + else + r.mx[i] = b.mx[i]; } #endif } // -B3_DBVT_INLINE bool b3NotEqual( const b3DbvtAabbMm& a, - const b3DbvtAabbMm& b) +B3_DBVT_INLINE bool b3NotEqual(const b3DbvtAabbMm& a, + const b3DbvtAabbMm& b) { - return( (a.mi.x!=b.mi.x)|| - (a.mi.y!=b.mi.y)|| - (a.mi.z!=b.mi.z)|| - (a.mx.x!=b.mx.x)|| - (a.mx.y!=b.mx.y)|| - (a.mx.z!=b.mx.z)); + return ((a.mi.x != b.mi.x) || + (a.mi.y != b.mi.y) || + (a.mi.z != b.mi.z) || + (a.mx.x != b.mx.x) || + (a.mx.y != b.mx.y) || + (a.mx.z != b.mx.z)); } // @@ -690,162 +734,162 @@ B3_DBVT_INLINE bool b3NotEqual( const b3DbvtAabbMm& a, // B3_DBVT_PREFIX -inline void b3DynamicBvh::enumNodes( const b3DbvtNode* root, - B3_DBVT_IPOLICY) +inline void b3DynamicBvh::enumNodes(const b3DbvtNode* root, + B3_DBVT_IPOLICY) { B3_DBVT_CHECKTYPE - policy.Process(root); - if(root->isinternal()) + policy.Process(root); + if (root->isinternal()) { - enumNodes(root->childs[0],policy); - enumNodes(root->childs[1],policy); + enumNodes(root->childs[0], policy); + enumNodes(root->childs[1], policy); } } // B3_DBVT_PREFIX -inline void b3DynamicBvh::enumLeaves( const b3DbvtNode* root, - B3_DBVT_IPOLICY) +inline void b3DynamicBvh::enumLeaves(const b3DbvtNode* root, + B3_DBVT_IPOLICY) { B3_DBVT_CHECKTYPE - if(root->isinternal()) - { - enumLeaves(root->childs[0],policy); - enumLeaves(root->childs[1],policy); - } - else - { - policy.Process(root); - } + if (root->isinternal()) + { + enumLeaves(root->childs[0], policy); + enumLeaves(root->childs[1], policy); + } + else + { + policy.Process(root); + } } // B3_DBVT_PREFIX -inline void b3DynamicBvh::collideTT( const b3DbvtNode* root0, - const b3DbvtNode* root1, - B3_DBVT_IPOLICY) +inline void b3DynamicBvh::collideTT(const b3DbvtNode* root0, + const b3DbvtNode* root1, + B3_DBVT_IPOLICY) { B3_DBVT_CHECKTYPE - if(root0&&root1) + if (root0 && root1) + { + int depth = 1; + int treshold = B3_DOUBLE_STACKSIZE - 4; + b3AlignedObjectArray stkStack; + stkStack.resize(B3_DOUBLE_STACKSIZE); + stkStack[0] = sStkNN(root0, root1); + do { - int depth=1; - int treshold=B3_DOUBLE_STACKSIZE-4; - b3AlignedObjectArray stkStack; - stkStack.resize(B3_DOUBLE_STACKSIZE); - stkStack[0]=sStkNN(root0,root1); - do { - sStkNN p=stkStack[--depth]; - if(depth>treshold) + sStkNN p = stkStack[--depth]; + if (depth > treshold) + { + stkStack.resize(stkStack.size() * 2); + treshold = stkStack.size() - 4; + } + if (p.a == p.b) + { + if (p.a->isinternal()) { - stkStack.resize(stkStack.size()*2); - treshold=stkStack.size()-4; + stkStack[depth++] = sStkNN(p.a->childs[0], p.a->childs[0]); + stkStack[depth++] = sStkNN(p.a->childs[1], p.a->childs[1]); + stkStack[depth++] = sStkNN(p.a->childs[0], p.a->childs[1]); } - if(p.a==p.b) + } + else if (b3Intersect(p.a->volume, p.b->volume)) + { + if (p.a->isinternal()) { - if(p.a->isinternal()) + if (p.b->isinternal()) { - stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]); - stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]); - stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]); - } - } - else if(b3Intersect(p.a->volume,p.b->volume)) - { - if(p.a->isinternal()) - { - if(p.b->isinternal()) - { - stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]); - stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]); - stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]); - stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]); - } - else - { - stkStack[depth++]=sStkNN(p.a->childs[0],p.b); - stkStack[depth++]=sStkNN(p.a->childs[1],p.b); - } + stkStack[depth++] = sStkNN(p.a->childs[0], p.b->childs[0]); + stkStack[depth++] = sStkNN(p.a->childs[1], p.b->childs[0]); + stkStack[depth++] = sStkNN(p.a->childs[0], p.b->childs[1]); + stkStack[depth++] = sStkNN(p.a->childs[1], p.b->childs[1]); } else { - if(p.b->isinternal()) - { - stkStack[depth++]=sStkNN(p.a,p.b->childs[0]); - stkStack[depth++]=sStkNN(p.a,p.b->childs[1]); - } - else - { - policy.Process(p.a,p.b); - } + stkStack[depth++] = sStkNN(p.a->childs[0], p.b); + stkStack[depth++] = sStkNN(p.a->childs[1], p.b); } } - } while(depth); - } + else + { + if (p.b->isinternal()) + { + stkStack[depth++] = sStkNN(p.a, p.b->childs[0]); + stkStack[depth++] = sStkNN(p.a, p.b->childs[1]); + } + else + { + policy.Process(p.a, p.b); + } + } + } + } while (depth); + } } - - B3_DBVT_PREFIX -inline void b3DynamicBvh::collideTTpersistentStack( const b3DbvtNode* root0, - const b3DbvtNode* root1, - B3_DBVT_IPOLICY) +inline void b3DynamicBvh::collideTTpersistentStack(const b3DbvtNode* root0, + const b3DbvtNode* root1, + B3_DBVT_IPOLICY) { B3_DBVT_CHECKTYPE - if(root0&&root1) + if (root0 && root1) + { + int depth = 1; + int treshold = B3_DOUBLE_STACKSIZE - 4; + + m_stkStack.resize(B3_DOUBLE_STACKSIZE); + m_stkStack[0] = sStkNN(root0, root1); + do { - int depth=1; - int treshold=B3_DOUBLE_STACKSIZE-4; - - m_stkStack.resize(B3_DOUBLE_STACKSIZE); - m_stkStack[0]=sStkNN(root0,root1); - do { - sStkNN p=m_stkStack[--depth]; - if(depth>treshold) + sStkNN p = m_stkStack[--depth]; + if (depth > treshold) + { + m_stkStack.resize(m_stkStack.size() * 2); + treshold = m_stkStack.size() - 4; + } + if (p.a == p.b) + { + if (p.a->isinternal()) { - m_stkStack.resize(m_stkStack.size()*2); - treshold=m_stkStack.size()-4; + m_stkStack[depth++] = sStkNN(p.a->childs[0], p.a->childs[0]); + m_stkStack[depth++] = sStkNN(p.a->childs[1], p.a->childs[1]); + m_stkStack[depth++] = sStkNN(p.a->childs[0], p.a->childs[1]); } - if(p.a==p.b) + } + else if (b3Intersect(p.a->volume, p.b->volume)) + { + if (p.a->isinternal()) { - if(p.a->isinternal()) + if (p.b->isinternal()) { - m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]); - m_stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]); - m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]); - } - } - else if(b3Intersect(p.a->volume,p.b->volume)) - { - if(p.a->isinternal()) - { - if(p.b->isinternal()) - { - m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]); - m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]); - m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]); - m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]); - } - else - { - m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b); - m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b); - } + m_stkStack[depth++] = sStkNN(p.a->childs[0], p.b->childs[0]); + m_stkStack[depth++] = sStkNN(p.a->childs[1], p.b->childs[0]); + m_stkStack[depth++] = sStkNN(p.a->childs[0], p.b->childs[1]); + m_stkStack[depth++] = sStkNN(p.a->childs[1], p.b->childs[1]); } else { - if(p.b->isinternal()) - { - m_stkStack[depth++]=sStkNN(p.a,p.b->childs[0]); - m_stkStack[depth++]=sStkNN(p.a,p.b->childs[1]); - } - else - { - policy.Process(p.a,p.b); - } + m_stkStack[depth++] = sStkNN(p.a->childs[0], p.b); + m_stkStack[depth++] = sStkNN(p.a->childs[1], p.b); } } - } while(depth); - } + else + { + if (p.b->isinternal()) + { + m_stkStack[depth++] = sStkNN(p.a, p.b->childs[0]); + m_stkStack[depth++] = sStkNN(p.a, p.b->childs[1]); + } + else + { + policy.Process(p.a, p.b); + } + } + } + } while (depth); + } } #if 0 @@ -915,337 +959,356 @@ inline void b3DynamicBvh::collideTT( const b3DbvtNode* root0, const b3Transform xform=xform0.inverse()*xform1; collideTT(root0,root1,xform,policy); } -#endif +#endif // B3_DBVT_PREFIX -inline void b3DynamicBvh::collideTV( const b3DbvtNode* root, - const b3DbvtVolume& vol, - B3_DBVT_IPOLICY) const +inline void b3DynamicBvh::collideTV(const b3DbvtNode* root, + const b3DbvtVolume& vol, + B3_DBVT_IPOLICY) const { B3_DBVT_CHECKTYPE - if(root) + if (root) + { + B3_ATTRIBUTE_ALIGNED16(b3DbvtVolume) + volume(vol); + b3AlignedObjectArray stack; + stack.resize(0); + stack.reserve(B3_SIMPLE_STACKSIZE); + stack.push_back(root); + do { - B3_ATTRIBUTE_ALIGNED16(b3DbvtVolume) volume(vol); - b3AlignedObjectArray stack; - stack.resize(0); - stack.reserve(B3_SIMPLE_STACKSIZE); - stack.push_back(root); - do { - const b3DbvtNode* n=stack[stack.size()-1]; - stack.pop_back(); - if(b3Intersect(n->volume,volume)) + const b3DbvtNode* n = stack[stack.size() - 1]; + stack.pop_back(); + if (b3Intersect(n->volume, volume)) + { + if (n->isinternal()) { - if(n->isinternal()) - { - stack.push_back(n->childs[0]); - stack.push_back(n->childs[1]); - } - else - { - policy.Process(n); - } + stack.push_back(n->childs[0]); + stack.push_back(n->childs[1]); } - } while(stack.size()>0); - } + else + { + policy.Process(n); + } + } + } while (stack.size() > 0); + } } B3_DBVT_PREFIX -inline void b3DynamicBvh::rayTestInternal( const b3DbvtNode* root, - const b3Vector3& rayFrom, - const b3Vector3& rayTo, - const b3Vector3& rayDirectionInverse, - unsigned int signs[3], - b3Scalar lambda_max, - const b3Vector3& aabbMin, - const b3Vector3& aabbMax, - B3_DBVT_IPOLICY) const +inline void b3DynamicBvh::rayTestInternal(const b3DbvtNode* root, + const b3Vector3& rayFrom, + const b3Vector3& rayTo, + const b3Vector3& rayDirectionInverse, + unsigned int signs[3], + b3Scalar lambda_max, + const b3Vector3& aabbMin, + const b3Vector3& aabbMax, + B3_DBVT_IPOLICY) const { - (void) rayTo; + (void)rayTo; B3_DBVT_CHECKTYPE - if(root) + if (root) { - int depth=1; - int treshold=B3_DOUBLE_STACKSIZE-2; - b3AlignedObjectArray& stack = m_rayTestStack; + int depth = 1; + int treshold = B3_DOUBLE_STACKSIZE - 2; + b3AlignedObjectArray& stack = m_rayTestStack; stack.resize(B3_DOUBLE_STACKSIZE); - stack[0]=root; + stack[0] = root; b3Vector3 bounds[2]; - do + do { - const b3DbvtNode* node=stack[--depth]; - bounds[0] = node->volume.Mins()-aabbMax; - bounds[1] = node->volume.Maxs()-aabbMin; - b3Scalar tmin=1.f,lambda_min=0.f; - unsigned int result1=false; - result1 = b3RayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max); - if(result1) + const b3DbvtNode* node = stack[--depth]; + bounds[0] = node->volume.Mins() - aabbMax; + bounds[1] = node->volume.Maxs() - aabbMin; + b3Scalar tmin = 1.f, lambda_min = 0.f; + unsigned int result1 = false; + result1 = b3RayAabb2(rayFrom, rayDirectionInverse, signs, bounds, tmin, lambda_min, lambda_max); + if (result1) { - if(node->isinternal()) + if (node->isinternal()) { - if(depth>treshold) + if (depth > treshold) { - stack.resize(stack.size()*2); - treshold=stack.size()-2; + stack.resize(stack.size() * 2); + treshold = stack.size() - 2; } - stack[depth++]=node->childs[0]; - stack[depth++]=node->childs[1]; + stack[depth++] = node->childs[0]; + stack[depth++] = node->childs[1]; } else { policy.Process(node); } } - } while(depth); + } while (depth); } } // B3_DBVT_PREFIX -inline void b3DynamicBvh::rayTest( const b3DbvtNode* root, - const b3Vector3& rayFrom, - const b3Vector3& rayTo, - B3_DBVT_IPOLICY) -{ - B3_DBVT_CHECKTYPE - if(root) - { - b3Vector3 rayDir = (rayTo-rayFrom); - rayDir.normalize (); - - ///what about division by zero? --> just set rayDirection[i] to INF/B3_LARGE_FLOAT - b3Vector3 rayDirectionInverse; - rayDirectionInverse[0] = rayDir[0] == b3Scalar(0.0) ? b3Scalar(B3_LARGE_FLOAT) : b3Scalar(1.0) / rayDir[0]; - rayDirectionInverse[1] = rayDir[1] == b3Scalar(0.0) ? b3Scalar(B3_LARGE_FLOAT) : b3Scalar(1.0) / rayDir[1]; - rayDirectionInverse[2] = rayDir[2] == b3Scalar(0.0) ? b3Scalar(B3_LARGE_FLOAT) : b3Scalar(1.0) / rayDir[2]; - unsigned int signs[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0}; - - b3Scalar lambda_max = rayDir.dot(rayTo-rayFrom); -#ifdef COMPARE_BTRAY_AABB2 - b3Vector3 resultNormal; -#endif//COMPARE_BTRAY_AABB2 - - b3AlignedObjectArray stack; - - int depth=1; - int treshold=B3_DOUBLE_STACKSIZE-2; - - stack.resize(B3_DOUBLE_STACKSIZE); - stack[0]=root; - b3Vector3 bounds[2]; - do { - const b3DbvtNode* node=stack[--depth]; - - bounds[0] = node->volume.Mins(); - bounds[1] = node->volume.Maxs(); - - b3Scalar tmin=1.f,lambda_min=0.f; - unsigned int result1 = b3RayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max); - -#ifdef COMPARE_BTRAY_AABB2 - b3Scalar param=1.f; - bool result2 = b3RayAabb(rayFrom,rayTo,node->volume.Mins(),node->volume.Maxs(),param,resultNormal); - b3Assert(result1 == result2); -#endif //TEST_BTRAY_AABB2 - - if(result1) - { - if(node->isinternal()) - { - if(depth>treshold) - { - stack.resize(stack.size()*2); - treshold=stack.size()-2; - } - stack[depth++]=node->childs[0]; - stack[depth++]=node->childs[1]; - } - else - { - policy.Process(node); - } - } - } while(depth); - - } -} - -// -B3_DBVT_PREFIX -inline void b3DynamicBvh::collideKDOP(const b3DbvtNode* root, - const b3Vector3* normals, - const b3Scalar* offsets, - int count, - B3_DBVT_IPOLICY) -{ - B3_DBVT_CHECKTYPE - if(root) - { - const int inside=(1< stack; - int signs[sizeof(unsigned)*8]; - b3Assert(count=0)?1:0)+ - ((normals[i].y>=0)?2:0)+ - ((normals[i].z>=0)?4:0); - } - stack.reserve(B3_SIMPLE_STACKSIZE); - stack.push_back(sStkNP(root,0)); - do { - sStkNP se=stack[stack.size()-1]; - bool out=false; - stack.pop_back(); - for(int i=0,j=1;(!out)&&(ivolume.Classify(normals[i],offsets[i],signs[i]); - switch(side) - { - case -1: out=true;break; - case +1: se.mask|=j;break; - } - } - } - if(!out) - { - if((se.mask!=inside)&&(se.node->isinternal())) - { - stack.push_back(sStkNP(se.node->childs[0],se.mask)); - stack.push_back(sStkNP(se.node->childs[1],se.mask)); - } - else - { - if(policy.AllLeaves(se.node)) enumLeaves(se.node,policy); - } - } - } while(stack.size()); - } -} - -// -B3_DBVT_PREFIX -inline void b3DynamicBvh::collideOCL( const b3DbvtNode* root, - const b3Vector3* normals, - const b3Scalar* offsets, - const b3Vector3& sortaxis, - int count, - B3_DBVT_IPOLICY, - bool fsort) -{ - B3_DBVT_CHECKTYPE - if(root) - { - const unsigned srtsgns=(sortaxis[0]>=0?1:0)+ - (sortaxis[1]>=0?2:0)+ - (sortaxis[2]>=0?4:0); - const int inside=(1< stock; - b3AlignedObjectArray ifree; - b3AlignedObjectArray stack; - int signs[sizeof(unsigned)*8]; - b3Assert(count=0)?1:0)+ - ((normals[i].y>=0)?2:0)+ - ((normals[i].z>=0)?4:0); - } - stock.reserve(B3_SIMPLE_STACKSIZE); - stack.reserve(B3_SIMPLE_STACKSIZE); - ifree.reserve(B3_SIMPLE_STACKSIZE); - stack.push_back(allocate(ifree,stock,sStkNPS(root,0,root->volume.ProjectMinimum(sortaxis,srtsgns)))); - do { - const int id=stack[stack.size()-1]; - sStkNPS se=stock[id]; - stack.pop_back();ifree.push_back(id); - if(se.mask!=inside) - { - bool out=false; - for(int i=0,j=1;(!out)&&(ivolume.Classify(normals[i],offsets[i],signs[i]); - switch(side) - { - case -1: out=true;break; - case +1: se.mask|=j;break; - } - } - } - if(out) continue; - } - if(policy.Descent(se.node)) - { - if(se.node->isinternal()) - { - const b3DbvtNode* pns[]={ se.node->childs[0],se.node->childs[1]}; - sStkNPS nes[]={ sStkNPS(pns[0],se.mask,pns[0]->volume.ProjectMinimum(sortaxis,srtsgns)), - sStkNPS(pns[1],se.mask,pns[1]->volume.ProjectMinimum(sortaxis,srtsgns))}; - const int q=nes[0].value0)) - { - /* Insert 0 */ - j=nearest(&stack[0],&stock[0],nes[q].value,0,stack.size()); - stack.push_back(0); -#if B3_DBVT_USE_MEMMOVE - memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1)); -#else - for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1]; -#endif - stack[j]=allocate(ifree,stock,nes[q]); - /* Insert 1 */ - j=nearest(&stack[0],&stock[0],nes[1-q].value,j,stack.size()); - stack.push_back(0); -#if B3_DBVT_USE_MEMMOVE - memmove(&stack[j+1],&stack[j],sizeof(int)*(stack.size()-j-1)); -#else - for(int k=stack.size()-1;k>j;--k) stack[k]=stack[k-1]; -#endif - stack[j]=allocate(ifree,stock,nes[1-q]); - } - else - { - stack.push_back(allocate(ifree,stock,nes[q])); - stack.push_back(allocate(ifree,stock,nes[1-q])); - } - } - else - { - policy.Process(se.node,se.value); - } - } - } while(stack.size()); - } -} - -// -B3_DBVT_PREFIX -inline void b3DynamicBvh::collideTU( const b3DbvtNode* root, +inline void b3DynamicBvh::rayTest(const b3DbvtNode* root, + const b3Vector3& rayFrom, + const b3Vector3& rayTo, B3_DBVT_IPOLICY) { B3_DBVT_CHECKTYPE - if(root) + if (root) + { + b3Vector3 rayDir = (rayTo - rayFrom); + rayDir.normalize(); + + ///what about division by zero? --> just set rayDirection[i] to INF/B3_LARGE_FLOAT + b3Vector3 rayDirectionInverse; + rayDirectionInverse[0] = rayDir[0] == b3Scalar(0.0) ? b3Scalar(B3_LARGE_FLOAT) : b3Scalar(1.0) / rayDir[0]; + rayDirectionInverse[1] = rayDir[1] == b3Scalar(0.0) ? b3Scalar(B3_LARGE_FLOAT) : b3Scalar(1.0) / rayDir[1]; + rayDirectionInverse[2] = rayDir[2] == b3Scalar(0.0) ? b3Scalar(B3_LARGE_FLOAT) : b3Scalar(1.0) / rayDir[2]; + unsigned int signs[3] = {rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0}; + + b3Scalar lambda_max = rayDir.dot(rayTo - rayFrom); +#ifdef COMPARE_BTRAY_AABB2 + b3Vector3 resultNormal; +#endif //COMPARE_BTRAY_AABB2 + + b3AlignedObjectArray stack; + + int depth = 1; + int treshold = B3_DOUBLE_STACKSIZE - 2; + + stack.resize(B3_DOUBLE_STACKSIZE); + stack[0] = root; + b3Vector3 bounds[2]; + do { - b3AlignedObjectArray stack; - stack.reserve(B3_SIMPLE_STACKSIZE); - stack.push_back(root); - do { - const b3DbvtNode* n=stack[stack.size()-1]; - stack.pop_back(); - if(policy.Descent(n)) + const b3DbvtNode* node = stack[--depth]; + + bounds[0] = node->volume.Mins(); + bounds[1] = node->volume.Maxs(); + + b3Scalar tmin = 1.f, lambda_min = 0.f; + unsigned int result1 = b3RayAabb2(rayFrom, rayDirectionInverse, signs, bounds, tmin, lambda_min, lambda_max); + +#ifdef COMPARE_BTRAY_AABB2 + b3Scalar param = 1.f; + bool result2 = b3RayAabb(rayFrom, rayTo, node->volume.Mins(), node->volume.Maxs(), param, resultNormal); + b3Assert(result1 == result2); +#endif //TEST_BTRAY_AABB2 + + if (result1) + { + if (node->isinternal()) { - if(n->isinternal()) - { stack.push_back(n->childs[0]);stack.push_back(n->childs[1]); } - else - { policy.Process(n); } + if (depth > treshold) + { + stack.resize(stack.size() * 2); + treshold = stack.size() - 2; + } + stack[depth++] = node->childs[0]; + stack[depth++] = node->childs[1]; } - } while(stack.size()>0); + else + { + policy.Process(node); + } + } + } while (depth); + } +} + +// +B3_DBVT_PREFIX +inline void b3DynamicBvh::collideKDOP(const b3DbvtNode* root, + const b3Vector3* normals, + const b3Scalar* offsets, + int count, + B3_DBVT_IPOLICY) +{ + B3_DBVT_CHECKTYPE + if (root) + { + const int inside = (1 << count) - 1; + b3AlignedObjectArray stack; + int signs[sizeof(unsigned) * 8]; + b3Assert(count < int(sizeof(signs) / sizeof(signs[0]))); + for (int i = 0; i < count; ++i) + { + signs[i] = ((normals[i].x >= 0) ? 1 : 0) + + ((normals[i].y >= 0) ? 2 : 0) + + ((normals[i].z >= 0) ? 4 : 0); } + stack.reserve(B3_SIMPLE_STACKSIZE); + stack.push_back(sStkNP(root, 0)); + do + { + sStkNP se = stack[stack.size() - 1]; + bool out = false; + stack.pop_back(); + for (int i = 0, j = 1; (!out) && (i < count); ++i, j <<= 1) + { + if (0 == (se.mask & j)) + { + const int side = se.node->volume.Classify(normals[i], offsets[i], signs[i]); + switch (side) + { + case -1: + out = true; + break; + case +1: + se.mask |= j; + break; + } + } + } + if (!out) + { + if ((se.mask != inside) && (se.node->isinternal())) + { + stack.push_back(sStkNP(se.node->childs[0], se.mask)); + stack.push_back(sStkNP(se.node->childs[1], se.mask)); + } + else + { + if (policy.AllLeaves(se.node)) enumLeaves(se.node, policy); + } + } + } while (stack.size()); + } +} + +// +B3_DBVT_PREFIX +inline void b3DynamicBvh::collideOCL(const b3DbvtNode* root, + const b3Vector3* normals, + const b3Scalar* offsets, + const b3Vector3& sortaxis, + int count, + B3_DBVT_IPOLICY, + bool fsort) +{ + B3_DBVT_CHECKTYPE + if (root) + { + const unsigned srtsgns = (sortaxis[0] >= 0 ? 1 : 0) + + (sortaxis[1] >= 0 ? 2 : 0) + + (sortaxis[2] >= 0 ? 4 : 0); + const int inside = (1 << count) - 1; + b3AlignedObjectArray stock; + b3AlignedObjectArray ifree; + b3AlignedObjectArray stack; + int signs[sizeof(unsigned) * 8]; + b3Assert(count < int(sizeof(signs) / sizeof(signs[0]))); + for (int i = 0; i < count; ++i) + { + signs[i] = ((normals[i].x >= 0) ? 1 : 0) + + ((normals[i].y >= 0) ? 2 : 0) + + ((normals[i].z >= 0) ? 4 : 0); + } + stock.reserve(B3_SIMPLE_STACKSIZE); + stack.reserve(B3_SIMPLE_STACKSIZE); + ifree.reserve(B3_SIMPLE_STACKSIZE); + stack.push_back(allocate(ifree, stock, sStkNPS(root, 0, root->volume.ProjectMinimum(sortaxis, srtsgns)))); + do + { + const int id = stack[stack.size() - 1]; + sStkNPS se = stock[id]; + stack.pop_back(); + ifree.push_back(id); + if (se.mask != inside) + { + bool out = false; + for (int i = 0, j = 1; (!out) && (i < count); ++i, j <<= 1) + { + if (0 == (se.mask & j)) + { + const int side = se.node->volume.Classify(normals[i], offsets[i], signs[i]); + switch (side) + { + case -1: + out = true; + break; + case +1: + se.mask |= j; + break; + } + } + } + if (out) continue; + } + if (policy.Descent(se.node)) + { + if (se.node->isinternal()) + { + const b3DbvtNode* pns[] = {se.node->childs[0], se.node->childs[1]}; + sStkNPS nes[] = {sStkNPS(pns[0], se.mask, pns[0]->volume.ProjectMinimum(sortaxis, srtsgns)), + sStkNPS(pns[1], se.mask, pns[1]->volume.ProjectMinimum(sortaxis, srtsgns))}; + const int q = nes[0].value < nes[1].value ? 1 : 0; + int j = stack.size(); + if (fsort && (j > 0)) + { + /* Insert 0 */ + j = nearest(&stack[0], &stock[0], nes[q].value, 0, stack.size()); + stack.push_back(0); +#if B3_DBVT_USE_MEMMOVE + memmove(&stack[j + 1], &stack[j], sizeof(int) * (stack.size() - j - 1)); +#else + for (int k = stack.size() - 1; k > j; --k) stack[k] = stack[k - 1]; +#endif + stack[j] = allocate(ifree, stock, nes[q]); + /* Insert 1 */ + j = nearest(&stack[0], &stock[0], nes[1 - q].value, j, stack.size()); + stack.push_back(0); +#if B3_DBVT_USE_MEMMOVE + memmove(&stack[j + 1], &stack[j], sizeof(int) * (stack.size() - j - 1)); +#else + for (int k = stack.size() - 1; k > j; --k) stack[k] = stack[k - 1]; +#endif + stack[j] = allocate(ifree, stock, nes[1 - q]); + } + else + { + stack.push_back(allocate(ifree, stock, nes[q])); + stack.push_back(allocate(ifree, stock, nes[1 - q])); + } + } + else + { + policy.Process(se.node, se.value); + } + } + } while (stack.size()); + } +} + +// +B3_DBVT_PREFIX +inline void b3DynamicBvh::collideTU(const b3DbvtNode* root, + B3_DBVT_IPOLICY) +{ + B3_DBVT_CHECKTYPE + if (root) + { + b3AlignedObjectArray stack; + stack.reserve(B3_SIMPLE_STACKSIZE); + stack.push_back(root); + do + { + const b3DbvtNode* n = stack[stack.size() - 1]; + stack.pop_back(); + if (policy.Descent(n)) + { + if (n->isinternal()) + { + stack.push_back(n->childs[0]); + stack.push_back(n->childs[1]); + } + else + { + policy.Process(n); + } + } + } while (stack.size() > 0); + } } // diff --git a/src/Bullet3Collision/BroadPhaseCollision/b3DynamicBvhBroadphase.cpp b/src/Bullet3Collision/BroadPhaseCollision/b3DynamicBvhBroadphase.cpp index bc150955b..dea2ddb0f 100644 --- a/src/Bullet3Collision/BroadPhaseCollision/b3DynamicBvhBroadphase.cpp +++ b/src/Bullet3Collision/BroadPhaseCollision/b3DynamicBvhBroadphase.cpp @@ -22,28 +22,27 @@ subject to the following restrictions: // Profiling // -#if B3_DBVT_BP_PROFILE||B3_DBVT_BP_ENABLE_BENCHMARK +#if B3_DBVT_BP_PROFILE || B3_DBVT_BP_ENABLE_BENCHMARK #include #endif #if B3_DBVT_BP_PROFILE -struct b3ProfileScope +struct b3ProfileScope { - __forceinline b3ProfileScope(b3Clock& clock,unsigned long& value) : - m_clock(&clock),m_value(&value),m_base(clock.getTimeMicroseconds()) + __forceinline b3ProfileScope(b3Clock& clock, unsigned long& value) : m_clock(&clock), m_value(&value), m_base(clock.getTimeMicroseconds()) { } __forceinline ~b3ProfileScope() { - (*m_value)+=m_clock->getTimeMicroseconds()-m_base; + (*m_value) += m_clock->getTimeMicroseconds() - m_base; } - b3Clock* m_clock; - unsigned long* m_value; - unsigned long m_base; + b3Clock* m_clock; + unsigned long* m_value; + unsigned long m_base; }; -#define b3SPC(_value_) b3ProfileScope spc_scope(m_clock,_value_) +#define b3SPC(_value_) b3ProfileScope spc_scope(m_clock, _value_) #else -#define b3SPC(_value_) +#define b3SPC(_value_) #endif // @@ -52,66 +51,75 @@ struct b3ProfileScope // template -static inline void b3ListAppend(T* item,T*& list) +static inline void b3ListAppend(T* item, T*& list) { - item->links[0]=0; - item->links[1]=list; - if(list) list->links[0]=item; - list=item; + item->links[0] = 0; + item->links[1] = list; + if (list) list->links[0] = item; + list = item; } // template -static inline void b3ListRemove(T* item,T*& list) +static inline void b3ListRemove(T* item, T*& list) { - if(item->links[0]) item->links[0]->links[1]=item->links[1]; else list=item->links[1]; - if(item->links[1]) item->links[1]->links[0]=item->links[0]; + if (item->links[0]) + item->links[0]->links[1] = item->links[1]; + else + list = item->links[1]; + if (item->links[1]) item->links[1]->links[0] = item->links[0]; } // template -static inline int b3ListCount(T* root) +static inline int b3ListCount(T* root) { - int n=0; - while(root) { ++n;root=root->links[1]; } - return(n); + int n = 0; + while (root) + { + ++n; + root = root->links[1]; + } + return (n); } // template -static inline void b3Clear(T& value) +static inline void b3Clear(T& value) { - static const struct ZeroDummy : T {} zerodummy; - value=zerodummy; + static const struct ZeroDummy : T + { + } zerodummy; + value = zerodummy; } // // Colliders // -/* Tree collider */ -struct b3DbvtTreeCollider : b3DynamicBvh::ICollide +/* Tree collider */ +struct b3DbvtTreeCollider : b3DynamicBvh::ICollide { - b3DynamicBvhBroadphase* pbp; - b3DbvtProxy* proxy; + b3DynamicBvhBroadphase* pbp; + b3DbvtProxy* proxy; b3DbvtTreeCollider(b3DynamicBvhBroadphase* p) : pbp(p) {} - void Process(const b3DbvtNode* na,const b3DbvtNode* nb) + void Process(const b3DbvtNode* na, const b3DbvtNode* nb) { - if(na!=nb) + if (na != nb) { - b3DbvtProxy* pa=(b3DbvtProxy*)na->data; - b3DbvtProxy* pb=(b3DbvtProxy*)nb->data; + b3DbvtProxy* pa = (b3DbvtProxy*)na->data; + b3DbvtProxy* pb = (b3DbvtProxy*)nb->data; #if B3_DBVT_BP_SORTPAIRS - if(pa->m_uniqueId>pb->m_uniqueId) - b3Swap(pa,pb); + if (pa->m_uniqueId > pb->m_uniqueId) + b3Swap(pa, pb); #endif - pbp->m_paircache->addOverlappingPair(pa->getUid(),pb->getUid()); + pbp->m_paircache->addOverlappingPair(pa->getUid(), pb->getUid()); ++pbp->m_newpairs; } } - void Process(const b3DbvtNode* n) + void Process(const b3DbvtNode* n) { - Process(n,proxy->leaf); + Process(n, proxy->leaf); } }; @@ -122,26 +130,26 @@ struct b3DbvtTreeCollider : b3DynamicBvh::ICollide // b3DynamicBvhBroadphase::b3DynamicBvhBroadphase(int proxyCapacity, b3OverlappingPairCache* paircache) { - m_deferedcollide = false; - m_needcleanup = true; - m_releasepaircache = (paircache!=0)?false:true; - m_prediction = 0; - m_stageCurrent = 0; - m_fixedleft = 0; - m_fupdates = 1; - m_dupdates = 0; - m_cupdates = 10; - m_newpairs = 1; - m_updates_call = 0; - m_updates_done = 0; - m_updates_ratio = 0; - m_paircache = paircache? paircache : new(b3AlignedAlloc(sizeof(b3HashedOverlappingPairCache),16)) b3HashedOverlappingPairCache(); - - m_pid = 0; - m_cid = 0; - for(int i=0;i<=STAGECOUNT;++i) + m_deferedcollide = false; + m_needcleanup = true; + m_releasepaircache = (paircache != 0) ? false : true; + m_prediction = 0; + m_stageCurrent = 0; + m_fixedleft = 0; + m_fupdates = 1; + m_dupdates = 0; + m_cupdates = 10; + m_newpairs = 1; + m_updates_call = 0; + m_updates_done = 0; + m_updates_ratio = 0; + m_paircache = paircache ? paircache : new (b3AlignedAlloc(sizeof(b3HashedOverlappingPairCache), 16)) b3HashedOverlappingPairCache(); + + m_pid = 0; + m_cid = 0; + for (int i = 0; i <= STAGECOUNT; ++i) { - m_stageRoots[i]=0; + m_stageRoots[i] = 0; } #if B3_DBVT_BP_PROFILE b3Clear(m_profiling); @@ -152,7 +160,7 @@ b3DynamicBvhBroadphase::b3DynamicBvhBroadphase(int proxyCapacity, b3OverlappingP // b3DynamicBvhBroadphase::~b3DynamicBvhBroadphase() { - if(m_releasepaircache) + if (m_releasepaircache) { m_paircache->~b3OverlappingPairCache(); b3AlignedFree(m_paircache); @@ -160,53 +168,53 @@ b3DynamicBvhBroadphase::~b3DynamicBvhBroadphase() } // -b3BroadphaseProxy* b3DynamicBvhBroadphase::createProxy( const b3Vector3& aabbMin, - const b3Vector3& aabbMax, - int objectId, - void* userPtr, - int collisionFilterGroup, - int collisionFilterMask) +b3BroadphaseProxy* b3DynamicBvhBroadphase::createProxy(const b3Vector3& aabbMin, + const b3Vector3& aabbMax, + int objectId, + void* userPtr, + int collisionFilterGroup, + int collisionFilterMask) { b3DbvtProxy* mem = &m_proxies[objectId]; - b3DbvtProxy* proxy=new(mem) b3DbvtProxy( aabbMin,aabbMax,userPtr, - collisionFilterGroup, - collisionFilterMask); + b3DbvtProxy* proxy = new (mem) b3DbvtProxy(aabbMin, aabbMax, userPtr, + collisionFilterGroup, + collisionFilterMask); - b3DbvtAabbMm aabb = b3DbvtVolume::FromMM(aabbMin,aabbMax); + b3DbvtAabbMm aabb = b3DbvtVolume::FromMM(aabbMin, aabbMax); //bproxy->aabb = b3DbvtVolume::FromMM(aabbMin,aabbMax); - proxy->stage = m_stageCurrent; - proxy->m_uniqueId = objectId; - proxy->leaf = m_sets[0].insert(aabb,proxy); - b3ListAppend(proxy,m_stageRoots[m_stageCurrent]); - if(!m_deferedcollide) + proxy->stage = m_stageCurrent; + proxy->m_uniqueId = objectId; + proxy->leaf = m_sets[0].insert(aabb, proxy); + b3ListAppend(proxy, m_stageRoots[m_stageCurrent]); + if (!m_deferedcollide) { - b3DbvtTreeCollider collider(this); - collider.proxy=proxy; - m_sets[0].collideTV(m_sets[0].m_root,aabb,collider); - m_sets[1].collideTV(m_sets[1].m_root,aabb,collider); + b3DbvtTreeCollider collider(this); + collider.proxy = proxy; + m_sets[0].collideTV(m_sets[0].m_root, aabb, collider); + m_sets[1].collideTV(m_sets[1].m_root, aabb, collider); } - return(proxy); + return (proxy); } // -void b3DynamicBvhBroadphase::destroyProxy( b3BroadphaseProxy* absproxy, - b3Dispatcher* dispatcher) +void b3DynamicBvhBroadphase::destroyProxy(b3BroadphaseProxy* absproxy, + b3Dispatcher* dispatcher) { - b3DbvtProxy* proxy=(b3DbvtProxy*)absproxy; - if(proxy->stage==STAGECOUNT) + b3DbvtProxy* proxy = (b3DbvtProxy*)absproxy; + if (proxy->stage == STAGECOUNT) m_sets[1].remove(proxy->leaf); else m_sets[0].remove(proxy->leaf); - b3ListRemove(proxy,m_stageRoots[proxy->stage]); - m_paircache->removeOverlappingPairsContainingProxy(proxy->getUid(),dispatcher); - - m_needcleanup=true; + b3ListRemove(proxy, m_stageRoots[proxy->stage]); + m_paircache->removeOverlappingPairsContainingProxy(proxy->getUid(), dispatcher); + + m_needcleanup = true; } -void b3DynamicBvhBroadphase::getAabb(int objectId,b3Vector3& aabbMin, b3Vector3& aabbMax ) const +void b3DynamicBvhBroadphase::getAabb(int objectId, b3Vector3& aabbMin, b3Vector3& aabbMax) const { - const b3DbvtProxy* proxy=&m_proxies[objectId]; + const b3DbvtProxy* proxy = &m_proxies[objectId]; aabbMin = proxy->m_aabbMin; aabbMax = proxy->m_aabbMax; } @@ -219,235 +227,223 @@ void b3DynamicBvhBroadphase::getAabb(b3BroadphaseProxy* absproxy,b3Vector3& aabb } */ - -struct BroadphaseRayTester : b3DynamicBvh::ICollide +struct BroadphaseRayTester : b3DynamicBvh::ICollide { b3BroadphaseRayCallback& m_rayCallback; BroadphaseRayTester(b3BroadphaseRayCallback& orgCallback) - :m_rayCallback(orgCallback) + : m_rayCallback(orgCallback) { } - void Process(const b3DbvtNode* leaf) + void Process(const b3DbvtNode* leaf) { - b3DbvtProxy* proxy=(b3DbvtProxy*)leaf->data; + b3DbvtProxy* proxy = (b3DbvtProxy*)leaf->data; m_rayCallback.process(proxy); } -}; +}; -void b3DynamicBvhBroadphase::rayTest(const b3Vector3& rayFrom,const b3Vector3& rayTo, b3BroadphaseRayCallback& rayCallback,const b3Vector3& aabbMin,const b3Vector3& aabbMax) +void b3DynamicBvhBroadphase::rayTest(const b3Vector3& rayFrom, const b3Vector3& rayTo, b3BroadphaseRayCallback& rayCallback, const b3Vector3& aabbMin, const b3Vector3& aabbMax) { BroadphaseRayTester callback(rayCallback); - m_sets[0].rayTestInternal( m_sets[0].m_root, - rayFrom, - rayTo, - rayCallback.m_rayDirectionInverse, - rayCallback.m_signs, - rayCallback.m_lambda_max, - aabbMin, - aabbMax, - callback); - - m_sets[1].rayTestInternal( m_sets[1].m_root, - rayFrom, - rayTo, - rayCallback.m_rayDirectionInverse, - rayCallback.m_signs, - rayCallback.m_lambda_max, - aabbMin, - aabbMax, - callback); + m_sets[0].rayTestInternal(m_sets[0].m_root, + rayFrom, + rayTo, + rayCallback.m_rayDirectionInverse, + rayCallback.m_signs, + rayCallback.m_lambda_max, + aabbMin, + aabbMax, + callback); + m_sets[1].rayTestInternal(m_sets[1].m_root, + rayFrom, + rayTo, + rayCallback.m_rayDirectionInverse, + rayCallback.m_signs, + rayCallback.m_lambda_max, + aabbMin, + aabbMax, + callback); } - -struct BroadphaseAabbTester : b3DynamicBvh::ICollide +struct BroadphaseAabbTester : b3DynamicBvh::ICollide { b3BroadphaseAabbCallback& m_aabbCallback; BroadphaseAabbTester(b3BroadphaseAabbCallback& orgCallback) - :m_aabbCallback(orgCallback) + : m_aabbCallback(orgCallback) { } - void Process(const b3DbvtNode* leaf) + void Process(const b3DbvtNode* leaf) { - b3DbvtProxy* proxy=(b3DbvtProxy*)leaf->data; + b3DbvtProxy* proxy = (b3DbvtProxy*)leaf->data; m_aabbCallback.process(proxy); } -}; +}; -void b3DynamicBvhBroadphase::aabbTest(const b3Vector3& aabbMin,const b3Vector3& aabbMax,b3BroadphaseAabbCallback& aabbCallback) +void b3DynamicBvhBroadphase::aabbTest(const b3Vector3& aabbMin, const b3Vector3& aabbMax, b3BroadphaseAabbCallback& aabbCallback) { BroadphaseAabbTester callback(aabbCallback); - const B3_ATTRIBUTE_ALIGNED16(b3DbvtVolume) bounds=b3DbvtVolume::FromMM(aabbMin,aabbMax); - //process all children, that overlap with the given AABB bounds - m_sets[0].collideTV(m_sets[0].m_root,bounds,callback); - m_sets[1].collideTV(m_sets[1].m_root,bounds,callback); - + const B3_ATTRIBUTE_ALIGNED16(b3DbvtVolume) bounds = b3DbvtVolume::FromMM(aabbMin, aabbMax); + //process all children, that overlap with the given AABB bounds + m_sets[0].collideTV(m_sets[0].m_root, bounds, callback); + m_sets[1].collideTV(m_sets[1].m_root, bounds, callback); } - - // -void b3DynamicBvhBroadphase::setAabb(int objectId, - const b3Vector3& aabbMin, - const b3Vector3& aabbMax, - b3Dispatcher* /*dispatcher*/) +void b3DynamicBvhBroadphase::setAabb(int objectId, + const b3Vector3& aabbMin, + const b3Vector3& aabbMax, + b3Dispatcher* /*dispatcher*/) { - b3DbvtProxy* proxy=&m_proxies[objectId]; -// b3DbvtProxy* proxy=(b3DbvtProxy*)absproxy; - B3_ATTRIBUTE_ALIGNED16(b3DbvtVolume) aabb=b3DbvtVolume::FromMM(aabbMin,aabbMax); + b3DbvtProxy* proxy = &m_proxies[objectId]; + // b3DbvtProxy* proxy=(b3DbvtProxy*)absproxy; + B3_ATTRIBUTE_ALIGNED16(b3DbvtVolume) + aabb = b3DbvtVolume::FromMM(aabbMin, aabbMax); #if B3_DBVT_BP_PREVENTFALSEUPDATE - if(b3NotEqual(aabb,proxy->leaf->volume)) + if (b3NotEqual(aabb, proxy->leaf->volume)) #endif { - bool docollide=false; - if(proxy->stage==STAGECOUNT) - {/* fixed -> dynamic set */ + bool docollide = false; + if (proxy->stage == STAGECOUNT) + { /* fixed -> dynamic set */ m_sets[1].remove(proxy->leaf); - proxy->leaf=m_sets[0].insert(aabb,proxy); - docollide=true; + proxy->leaf = m_sets[0].insert(aabb, proxy); + docollide = true; } else - {/* dynamic set */ + { /* dynamic set */ ++m_updates_call; - if(b3Intersect(proxy->leaf->volume,aabb)) - {/* Moving */ + if (b3Intersect(proxy->leaf->volume, aabb)) + { /* Moving */ - const b3Vector3 delta=aabbMin-proxy->m_aabbMin; - b3Vector3 velocity(((proxy->m_aabbMax-proxy->m_aabbMin)/2)*m_prediction); - if(delta[0]<0) velocity[0]=-velocity[0]; - if(delta[1]<0) velocity[1]=-velocity[1]; - if(delta[2]<0) velocity[2]=-velocity[2]; - if ( -#ifdef B3_DBVT_BP_MARGIN - m_sets[0].update(proxy->leaf,aabb,velocity,B3_DBVT_BP_MARGIN) + const b3Vector3 delta = aabbMin - proxy->m_aabbMin; + b3Vector3 velocity(((proxy->m_aabbMax - proxy->m_aabbMin) / 2) * m_prediction); + if (delta[0] < 0) velocity[0] = -velocity[0]; + if (delta[1] < 0) velocity[1] = -velocity[1]; + if (delta[2] < 0) velocity[2] = -velocity[2]; + if ( +#ifdef B3_DBVT_BP_MARGIN + m_sets[0].update(proxy->leaf, aabb, velocity, B3_DBVT_BP_MARGIN) #else - m_sets[0].update(proxy->leaf,aabb,velocity) + m_sets[0].update(proxy->leaf, aabb, velocity) #endif - ) + ) { ++m_updates_done; - docollide=true; + docollide = true; } } else - {/* Teleporting */ - m_sets[0].update(proxy->leaf,aabb); + { /* Teleporting */ + m_sets[0].update(proxy->leaf, aabb); ++m_updates_done; - docollide=true; - } + docollide = true; + } } - b3ListRemove(proxy,m_stageRoots[proxy->stage]); + b3ListRemove(proxy, m_stageRoots[proxy->stage]); proxy->m_aabbMin = aabbMin; proxy->m_aabbMax = aabbMax; - proxy->stage = m_stageCurrent; - b3ListAppend(proxy,m_stageRoots[m_stageCurrent]); - if(docollide) + proxy->stage = m_stageCurrent; + b3ListAppend(proxy, m_stageRoots[m_stageCurrent]); + if (docollide) { - m_needcleanup=true; - if(!m_deferedcollide) + m_needcleanup = true; + if (!m_deferedcollide) { - b3DbvtTreeCollider collider(this); - m_sets[1].collideTTpersistentStack(m_sets[1].m_root,proxy->leaf,collider); - m_sets[0].collideTTpersistentStack(m_sets[0].m_root,proxy->leaf,collider); + b3DbvtTreeCollider collider(this); + m_sets[1].collideTTpersistentStack(m_sets[1].m_root, proxy->leaf, collider); + m_sets[0].collideTTpersistentStack(m_sets[0].m_root, proxy->leaf, collider); } - } + } } } - // -void b3DynamicBvhBroadphase::setAabbForceUpdate( b3BroadphaseProxy* absproxy, - const b3Vector3& aabbMin, - const b3Vector3& aabbMax, - b3Dispatcher* /*dispatcher*/) +void b3DynamicBvhBroadphase::setAabbForceUpdate(b3BroadphaseProxy* absproxy, + const b3Vector3& aabbMin, + const b3Vector3& aabbMax, + b3Dispatcher* /*dispatcher*/) { - b3DbvtProxy* proxy=(b3DbvtProxy*)absproxy; - B3_ATTRIBUTE_ALIGNED16(b3DbvtVolume) aabb=b3DbvtVolume::FromMM(aabbMin,aabbMax); - bool docollide=false; - if(proxy->stage==STAGECOUNT) - {/* fixed -> dynamic set */ + b3DbvtProxy* proxy = (b3DbvtProxy*)absproxy; + B3_ATTRIBUTE_ALIGNED16(b3DbvtVolume) + aabb = b3DbvtVolume::FromMM(aabbMin, aabbMax); + bool docollide = false; + if (proxy->stage == STAGECOUNT) + { /* fixed -> dynamic set */ m_sets[1].remove(proxy->leaf); - proxy->leaf=m_sets[0].insert(aabb,proxy); - docollide=true; + proxy->leaf = m_sets[0].insert(aabb, proxy); + docollide = true; } else - {/* dynamic set */ + { /* dynamic set */ ++m_updates_call; - /* Teleporting */ - m_sets[0].update(proxy->leaf,aabb); + /* Teleporting */ + m_sets[0].update(proxy->leaf, aabb); ++m_updates_done; - docollide=true; + docollide = true; } - b3ListRemove(proxy,m_stageRoots[proxy->stage]); + b3ListRemove(proxy, m_stageRoots[proxy->stage]); proxy->m_aabbMin = aabbMin; proxy->m_aabbMax = aabbMax; - proxy->stage = m_stageCurrent; - b3ListAppend(proxy,m_stageRoots[m_stageCurrent]); - if(docollide) + proxy->stage = m_stageCurrent; + b3ListAppend(proxy, m_stageRoots[m_stageCurrent]); + if (docollide) { - m_needcleanup=true; - if(!m_deferedcollide) + m_needcleanup = true; + if (!m_deferedcollide) { - b3DbvtTreeCollider collider(this); - m_sets[1].collideTTpersistentStack(m_sets[1].m_root,proxy->leaf,collider); - m_sets[0].collideTTpersistentStack(m_sets[0].m_root,proxy->leaf,collider); + b3DbvtTreeCollider collider(this); + m_sets[1].collideTTpersistentStack(m_sets[1].m_root, proxy->leaf, collider); + m_sets[0].collideTTpersistentStack(m_sets[0].m_root, proxy->leaf, collider); } - } + } } // -void b3DynamicBvhBroadphase::calculateOverlappingPairs(b3Dispatcher* dispatcher) +void b3DynamicBvhBroadphase::calculateOverlappingPairs(b3Dispatcher* dispatcher) { collide(dispatcher); #if B3_DBVT_BP_PROFILE - if(0==(m_pid%B3_DBVT_BP_PROFILING_RATE)) - { - printf("fixed(%u) dynamics(%u) pairs(%u)\r\n",m_sets[1].m_leaves,m_sets[0].m_leaves,m_paircache->getNumOverlappingPairs()); - unsigned int total=m_profiling.m_total; - if(total<=0) total=1; - printf("ddcollide: %u%% (%uus)\r\n",(50+m_profiling.m_ddcollide*100)/total,m_profiling.m_ddcollide/B3_DBVT_BP_PROFILING_RATE); - printf("fdcollide: %u%% (%uus)\r\n",(50+m_profiling.m_fdcollide*100)/total,m_profiling.m_fdcollide/B3_DBVT_BP_PROFILING_RATE); - printf("cleanup: %u%% (%uus)\r\n",(50+m_profiling.m_cleanup*100)/total,m_profiling.m_cleanup/B3_DBVT_BP_PROFILING_RATE); - printf("total: %uus\r\n",total/B3_DBVT_BP_PROFILING_RATE); - const unsigned long sum=m_profiling.m_ddcollide+ - m_profiling.m_fdcollide+ - m_profiling.m_cleanup; - printf("leaked: %u%% (%uus)\r\n",100-((50+sum*100)/total),(total-sum)/B3_DBVT_BP_PROFILING_RATE); - printf("job counts: %u%%\r\n",(m_profiling.m_jobcount*100)/((m_sets[0].m_leaves+m_sets[1].m_leaves)*B3_DBVT_BP_PROFILING_RATE)); + if (0 == (m_pid % B3_DBVT_BP_PROFILING_RATE)) + { + printf("fixed(%u) dynamics(%u) pairs(%u)\r\n", m_sets[1].m_leaves, m_sets[0].m_leaves, m_paircache->getNumOverlappingPairs()); + unsigned int total = m_profiling.m_total; + if (total <= 0) total = 1; + printf("ddcollide: %u%% (%uus)\r\n", (50 + m_profiling.m_ddcollide * 100) / total, m_profiling.m_ddcollide / B3_DBVT_BP_PROFILING_RATE); + printf("fdcollide: %u%% (%uus)\r\n", (50 + m_profiling.m_fdcollide * 100) / total, m_profiling.m_fdcollide / B3_DBVT_BP_PROFILING_RATE); + printf("cleanup: %u%% (%uus)\r\n", (50 + m_profiling.m_cleanup * 100) / total, m_profiling.m_cleanup / B3_DBVT_BP_PROFILING_RATE); + printf("total: %uus\r\n", total / B3_DBVT_BP_PROFILING_RATE); + const unsigned long sum = m_profiling.m_ddcollide + + m_profiling.m_fdcollide + + m_profiling.m_cleanup; + printf("leaked: %u%% (%uus)\r\n", 100 - ((50 + sum * 100) / total), (total - sum) / B3_DBVT_BP_PROFILING_RATE); + printf("job counts: %u%%\r\n", (m_profiling.m_jobcount * 100) / ((m_sets[0].m_leaves + m_sets[1].m_leaves) * B3_DBVT_BP_PROFILING_RATE)); b3Clear(m_profiling); m_clock.reset(); } #endif performDeferredRemoval(dispatcher); - } void b3DynamicBvhBroadphase::performDeferredRemoval(b3Dispatcher* dispatcher) { - if (m_paircache->hasDeferredRemoval()) { - - b3BroadphasePairArray& overlappingPairArray = m_paircache->getOverlappingPairArray(); + b3BroadphasePairArray& overlappingPairArray = m_paircache->getOverlappingPairArray(); //perform a sort, to find duplicates and to sort 'invalid' pairs to the end overlappingPairArray.quickSort(b3BroadphasePairSortPredicate()); int invalidPair = 0; - int i; - b3BroadphasePair previousPair = b3MakeBroadphasePair(-1,-1); - - - - for (i=0;ileaf->volume,pb->leaf->volume); + b3DbvtProxy* pa = &m_proxies[pair.x]; + b3DbvtProxy* pb = &m_proxies[pair.y]; + bool hasOverlap = b3Intersect(pa->leaf->volume, pb->leaf->volume); if (hasOverlap) { needsRemoval = false; - } else + } + else { needsRemoval = true; } - } else + } + else { //remove duplicate needsRemoval = true; //should have no algorithm } - + if (needsRemoval) { - m_paircache->cleanOverlappingPair(pair,dispatcher); + m_paircache->cleanOverlappingPair(pair, dispatcher); pair.x = -1; pair.y = -1; invalidPair++; - } - + } } //perform a sort, to sort 'invalid' pairs to the end @@ -495,7 +492,7 @@ void b3DynamicBvhBroadphase::performDeferredRemoval(b3Dispatcher* dispatcher) } // -void b3DynamicBvhBroadphase::collide(b3Dispatcher* dispatcher) +void b3DynamicBvhBroadphase::collide(b3Dispatcher* dispatcher) { /*printf("---------------------------------------------------------\n"); printf("m_sets[0].m_leaves=%d\n",m_sets[0].m_leaves); @@ -512,285 +509,293 @@ void b3DynamicBvhBroadphase::collide(b3Dispatcher* dispatcher) } */ - - b3SPC(m_profiling.m_total); - /* optimize */ - m_sets[0].optimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/100); - if(m_fixedleft) + /* optimize */ + m_sets[0].optimizeIncremental(1 + (m_sets[0].m_leaves * m_dupdates) / 100); + if (m_fixedleft) { - const int count=1+(m_sets[1].m_leaves*m_fupdates)/100; - m_sets[1].optimizeIncremental(1+(m_sets[1].m_leaves*m_fupdates)/100); - m_fixedleft=b3Max(0,m_fixedleft-count); + const int count = 1 + (m_sets[1].m_leaves * m_fupdates) / 100; + m_sets[1].optimizeIncremental(1 + (m_sets[1].m_leaves * m_fupdates) / 100); + m_fixedleft = b3Max(0, m_fixedleft - count); } - /* dynamic -> fixed set */ - m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT; - b3DbvtProxy* current=m_stageRoots[m_stageCurrent]; - if(current) + /* dynamic -> fixed set */ + m_stageCurrent = (m_stageCurrent + 1) % STAGECOUNT; + b3DbvtProxy* current = m_stageRoots[m_stageCurrent]; + if (current) { - b3DbvtTreeCollider collider(this); - do { - b3DbvtProxy* next=current->links[1]; - b3ListRemove(current,m_stageRoots[current->stage]); - b3ListAppend(current,m_stageRoots[STAGECOUNT]); + b3DbvtTreeCollider collider(this); + do + { + b3DbvtProxy* next = current->links[1]; + b3ListRemove(current, m_stageRoots[current->stage]); + b3ListAppend(current, m_stageRoots[STAGECOUNT]); #if B3_DBVT_BP_ACCURATESLEEPING - m_paircache->removeOverlappingPairsContainingProxy(current,dispatcher); - collider.proxy=current; - b3DynamicBvh::collideTV(m_sets[0].m_root,current->aabb,collider); - b3DynamicBvh::collideTV(m_sets[1].m_root,current->aabb,collider); + m_paircache->removeOverlappingPairsContainingProxy(current, dispatcher); + collider.proxy = current; + b3DynamicBvh::collideTV(m_sets[0].m_root, current->aabb, collider); + b3DynamicBvh::collideTV(m_sets[1].m_root, current->aabb, collider); #endif m_sets[0].remove(current->leaf); - B3_ATTRIBUTE_ALIGNED16(b3DbvtVolume) curAabb=b3DbvtVolume::FromMM(current->m_aabbMin,current->m_aabbMax); - current->leaf = m_sets[1].insert(curAabb,current); - current->stage = STAGECOUNT; - current = next; - } while(current); - m_fixedleft=m_sets[1].m_leaves; - m_needcleanup=true; + B3_ATTRIBUTE_ALIGNED16(b3DbvtVolume) + curAabb = b3DbvtVolume::FromMM(current->m_aabbMin, current->m_aabbMax); + current->leaf = m_sets[1].insert(curAabb, current); + current->stage = STAGECOUNT; + current = next; + } while (current); + m_fixedleft = m_sets[1].m_leaves; + m_needcleanup = true; } - /* collide dynamics */ + /* collide dynamics */ { - b3DbvtTreeCollider collider(this); - if(m_deferedcollide) + b3DbvtTreeCollider collider(this); + if (m_deferedcollide) { b3SPC(m_profiling.m_fdcollide); - m_sets[0].collideTTpersistentStack(m_sets[0].m_root,m_sets[1].m_root,collider); + m_sets[0].collideTTpersistentStack(m_sets[0].m_root, m_sets[1].m_root, collider); } - if(m_deferedcollide) + if (m_deferedcollide) { b3SPC(m_profiling.m_ddcollide); - m_sets[0].collideTTpersistentStack(m_sets[0].m_root,m_sets[0].m_root,collider); + m_sets[0].collideTTpersistentStack(m_sets[0].m_root, m_sets[0].m_root, collider); } } - /* clean up */ - if(m_needcleanup) + /* clean up */ + if (m_needcleanup) { b3SPC(m_profiling.m_cleanup); - b3BroadphasePairArray& pairs=m_paircache->getOverlappingPairArray(); - if(pairs.size()>0) + b3BroadphasePairArray& pairs = m_paircache->getOverlappingPairArray(); + if (pairs.size() > 0) { - - int ni=b3Min(pairs.size(),b3Max(m_newpairs,(pairs.size()*m_cupdates)/100)); - for(int i=0;i(m_newpairs, (pairs.size() * m_cupdates) / 100)); + for (int i = 0; i < ni; ++i) { - b3BroadphasePair& p=pairs[(m_cid+i)%pairs.size()]; - b3DbvtProxy* pa=&m_proxies[p.x]; - b3DbvtProxy* pb=&m_proxies[p.y]; - if(!b3Intersect(pa->leaf->volume,pb->leaf->volume)) + b3BroadphasePair& p = pairs[(m_cid + i) % pairs.size()]; + b3DbvtProxy* pa = &m_proxies[p.x]; + b3DbvtProxy* pb = &m_proxies[p.y]; + if (!b3Intersect(pa->leaf->volume, pb->leaf->volume)) { #if B3_DBVT_BP_SORTPAIRS - if(pa->m_uniqueId>pb->m_uniqueId) - b3Swap(pa,pb); + if (pa->m_uniqueId > pb->m_uniqueId) + b3Swap(pa, pb); #endif - m_paircache->removeOverlappingPair(pa->getUid(),pb->getUid(),dispatcher); - --ni;--i; + m_paircache->removeOverlappingPair(pa->getUid(), pb->getUid(), dispatcher); + --ni; + --i; } } - if(pairs.size()>0) m_cid=(m_cid+ni)%pairs.size(); else m_cid=0; + if (pairs.size() > 0) + m_cid = (m_cid + ni) % pairs.size(); + else + m_cid = 0; } } ++m_pid; - m_newpairs=1; - m_needcleanup=false; - if(m_updates_call>0) - { m_updates_ratio=m_updates_done/(b3Scalar)m_updates_call; } + m_newpairs = 1; + m_needcleanup = false; + if (m_updates_call > 0) + { + m_updates_ratio = m_updates_done / (b3Scalar)m_updates_call; + } else - { m_updates_ratio=0; } - m_updates_done/=2; - m_updates_call/=2; + { + m_updates_ratio = 0; + } + m_updates_done /= 2; + m_updates_call /= 2; } // -void b3DynamicBvhBroadphase::optimize() +void b3DynamicBvhBroadphase::optimize() { m_sets[0].optimizeTopDown(); m_sets[1].optimizeTopDown(); } // -b3OverlappingPairCache* b3DynamicBvhBroadphase::getOverlappingPairCache() +b3OverlappingPairCache* b3DynamicBvhBroadphase::getOverlappingPairCache() { - return(m_paircache); + return (m_paircache); } // -const b3OverlappingPairCache* b3DynamicBvhBroadphase::getOverlappingPairCache() const +const b3OverlappingPairCache* b3DynamicBvhBroadphase::getOverlappingPairCache() const { - return(m_paircache); + return (m_paircache); } // -void b3DynamicBvhBroadphase::getBroadphaseAabb(b3Vector3& aabbMin,b3Vector3& aabbMax) const +void b3DynamicBvhBroadphase::getBroadphaseAabb(b3Vector3& aabbMin, b3Vector3& aabbMax) const { + B3_ATTRIBUTE_ALIGNED16(b3DbvtVolume) + bounds; - B3_ATTRIBUTE_ALIGNED16(b3DbvtVolume) bounds; - - if(!m_sets[0].empty()) - if(!m_sets[1].empty()) b3Merge( m_sets[0].m_root->volume, - m_sets[1].m_root->volume,bounds); + if (!m_sets[0].empty()) + if (!m_sets[1].empty()) + b3Merge(m_sets[0].m_root->volume, + m_sets[1].m_root->volume, bounds); else - bounds=m_sets[0].m_root->volume; - else if(!m_sets[1].empty()) bounds=m_sets[1].m_root->volume; + bounds = m_sets[0].m_root->volume; + else if (!m_sets[1].empty()) + bounds = m_sets[1].m_root->volume; else - bounds=b3DbvtVolume::FromCR(b3MakeVector3(0,0,0),0); - aabbMin=bounds.Mins(); - aabbMax=bounds.Maxs(); + bounds = b3DbvtVolume::FromCR(b3MakeVector3(0, 0, 0), 0); + aabbMin = bounds.Mins(); + aabbMax = bounds.Maxs(); } void b3DynamicBvhBroadphase::resetPool(b3Dispatcher* dispatcher) { - int totalObjects = m_sets[0].m_leaves + m_sets[1].m_leaves; if (!totalObjects) { //reset internal dynamic tree data structures m_sets[0].clear(); m_sets[1].clear(); - - m_deferedcollide = false; - m_needcleanup = true; - m_stageCurrent = 0; - m_fixedleft = 0; - m_fupdates = 1; - m_dupdates = 0; - m_cupdates = 10; - m_newpairs = 1; - m_updates_call = 0; - m_updates_done = 0; - m_updates_ratio = 0; - - m_pid = 0; - m_cid = 0; - for(int i=0;i<=STAGECOUNT;++i) + + m_deferedcollide = false; + m_needcleanup = true; + m_stageCurrent = 0; + m_fixedleft = 0; + m_fupdates = 1; + m_dupdates = 0; + m_cupdates = 10; + m_newpairs = 1; + m_updates_call = 0; + m_updates_done = 0; + m_updates_ratio = 0; + + m_pid = 0; + m_cid = 0; + for (int i = 0; i <= STAGECOUNT; ++i) { - m_stageRoots[i]=0; + m_stageRoots[i] = 0; } } } // -void b3DynamicBvhBroadphase::printStats() -{} +void b3DynamicBvhBroadphase::printStats() +{ +} // #if B3_DBVT_BP_ENABLE_BENCHMARK -struct b3BroadphaseBenchmark +struct b3BroadphaseBenchmark { - struct Experiment + struct Experiment { - const char* name; - int object_count; - int update_count; - int spawn_count; - int iterations; - b3Scalar speed; - b3Scalar amplitude; + const char* name; + int object_count; + int update_count; + int spawn_count; + int iterations; + b3Scalar speed; + b3Scalar amplitude; }; - struct Object + struct Object { - b3Vector3 center; - b3Vector3 extents; - b3BroadphaseProxy* proxy; - b3Scalar time; - void update(b3Scalar speed,b3Scalar amplitude,b3BroadphaseInterface* pbi) + b3Vector3 center; + b3Vector3 extents; + b3BroadphaseProxy* proxy; + b3Scalar time; + void update(b3Scalar speed, b3Scalar amplitude, b3BroadphaseInterface* pbi) { - time += speed; - center[0] = b3Cos(time*(b3Scalar)2.17)*amplitude+ - b3Sin(time)*amplitude/2; - center[1] = b3Cos(time*(b3Scalar)1.38)*amplitude+ - b3Sin(time)*amplitude; - center[2] = b3Sin(time*(b3Scalar)0.777)*amplitude; - pbi->setAabb(proxy,center-extents,center+extents,0); + time += speed; + center[0] = b3Cos(time * (b3Scalar)2.17) * amplitude + + b3Sin(time) * amplitude / 2; + center[1] = b3Cos(time * (b3Scalar)1.38) * amplitude + + b3Sin(time) * amplitude; + center[2] = b3Sin(time * (b3Scalar)0.777) * amplitude; + pbi->setAabb(proxy, center - extents, center + extents, 0); } }; - static int UnsignedRand(int range=RAND_MAX-1) { return(rand()%(range+1)); } - static b3Scalar UnitRand() { return(UnsignedRand(16384)/(b3Scalar)16384); } - static void OutputTime(const char* name,b3Clock& c,unsigned count=0) + static int UnsignedRand(int range = RAND_MAX - 1) { return (rand() % (range + 1)); } + static b3Scalar UnitRand() { return (UnsignedRand(16384) / (b3Scalar)16384); } + static void OutputTime(const char* name, b3Clock& c, unsigned count = 0) { - const unsigned long us=c.getTimeMicroseconds(); - const unsigned long ms=(us+500)/1000; - const b3Scalar sec=us/(b3Scalar)(1000*1000); - if(count>0) - printf("%s : %u us (%u ms), %.2f/s\r\n",name,us,ms,count/sec); + const unsigned long us = c.getTimeMicroseconds(); + const unsigned long ms = (us + 500) / 1000; + const b3Scalar sec = us / (b3Scalar)(1000 * 1000); + if (count > 0) + printf("%s : %u us (%u ms), %.2f/s\r\n", name, us, ms, count / sec); else - printf("%s : %u us (%u ms)\r\n",name,us,ms); + printf("%s : %u us (%u ms)\r\n", name, us, ms); } }; -void b3DynamicBvhBroadphase::benchmark(b3BroadphaseInterface* pbi) +void b3DynamicBvhBroadphase::benchmark(b3BroadphaseInterface* pbi) { - static const b3BroadphaseBenchmark::Experiment experiments[]= - { - {"1024o.10%",1024,10,0,8192,(b3Scalar)0.005,(b3Scalar)100}, - /*{"4096o.10%",4096,10,0,8192,(b3Scalar)0.005,(b3Scalar)100}, + static const b3BroadphaseBenchmark::Experiment experiments[] = + { + {"1024o.10%", 1024, 10, 0, 8192, (b3Scalar)0.005, (b3Scalar)100}, + /*{"4096o.10%",4096,10,0,8192,(b3Scalar)0.005,(b3Scalar)100}, {"8192o.10%",8192,10,0,8192,(b3Scalar)0.005,(b3Scalar)100},*/ - }; - static const int nexperiments=sizeof(experiments)/sizeof(experiments[0]); - b3AlignedObjectArray objects; - b3Clock wallclock; - /* Begin */ - for(int iexp=0;iexp objects; + b3Clock wallclock; + /* Begin */ + for (int iexp = 0; iexp < nexperiments; ++iexp) { - const b3BroadphaseBenchmark::Experiment& experiment=experiments[iexp]; - const int object_count=experiment.object_count; - const int update_count=(object_count*experiment.update_count)/100; - const int spawn_count=(object_count*experiment.spawn_count)/100; - const b3Scalar speed=experiment.speed; - const b3Scalar amplitude=experiment.amplitude; - printf("Experiment #%u '%s':\r\n",iexp,experiment.name); - printf("\tObjects: %u\r\n",object_count); - printf("\tUpdate: %u\r\n",update_count); - printf("\tSpawn: %u\r\n",spawn_count); - printf("\tSpeed: %f\r\n",speed); - printf("\tAmplitude: %f\r\n",amplitude); + const b3BroadphaseBenchmark::Experiment& experiment = experiments[iexp]; + const int object_count = experiment.object_count; + const int update_count = (object_count * experiment.update_count) / 100; + const int spawn_count = (object_count * experiment.spawn_count) / 100; + const b3Scalar speed = experiment.speed; + const b3Scalar amplitude = experiment.amplitude; + printf("Experiment #%u '%s':\r\n", iexp, experiment.name); + printf("\tObjects: %u\r\n", object_count); + printf("\tUpdate: %u\r\n", update_count); + printf("\tSpawn: %u\r\n", spawn_count); + printf("\tSpeed: %f\r\n", speed); + printf("\tAmplitude: %f\r\n", amplitude); srand(180673); - /* Create objects */ + /* Create objects */ wallclock.reset(); objects.reserve(object_count); - for(int i=0;icenter[0]=b3BroadphaseBenchmark::UnitRand()*50; - po->center[1]=b3BroadphaseBenchmark::UnitRand()*50; - po->center[2]=b3BroadphaseBenchmark::UnitRand()*50; - po->extents[0]=b3BroadphaseBenchmark::UnitRand()*2+2; - po->extents[1]=b3BroadphaseBenchmark::UnitRand()*2+2; - po->extents[2]=b3BroadphaseBenchmark::UnitRand()*2+2; - po->time=b3BroadphaseBenchmark::UnitRand()*2000; - po->proxy=pbi->createProxy(po->center-po->extents,po->center+po->extents,0,po,1,1,0,0); + b3BroadphaseBenchmark::Object* po = new b3BroadphaseBenchmark::Object(); + po->center[0] = b3BroadphaseBenchmark::UnitRand() * 50; + po->center[1] = b3BroadphaseBenchmark::UnitRand() * 50; + po->center[2] = b3BroadphaseBenchmark::UnitRand() * 50; + po->extents[0] = b3BroadphaseBenchmark::UnitRand() * 2 + 2; + po->extents[1] = b3BroadphaseBenchmark::UnitRand() * 2 + 2; + po->extents[2] = b3BroadphaseBenchmark::UnitRand() * 2 + 2; + po->time = b3BroadphaseBenchmark::UnitRand() * 2000; + po->proxy = pbi->createProxy(po->center - po->extents, po->center + po->extents, 0, po, 1, 1, 0, 0); objects.push_back(po); } - b3BroadphaseBenchmark::OutputTime("\tInitialization",wallclock); - /* First update */ + b3BroadphaseBenchmark::OutputTime("\tInitialization", wallclock); + /* First update */ wallclock.reset(); - for(int i=0;iupdate(speed,amplitude,pbi); + objects[i]->update(speed, amplitude, pbi); } - b3BroadphaseBenchmark::OutputTime("\tFirst update",wallclock); - /* Updates */ + b3BroadphaseBenchmark::OutputTime("\tFirst update", wallclock); + /* Updates */ wallclock.reset(); - for(int i=0;iupdate(speed,amplitude,pbi); + for (int j = 0; j < update_count; ++j) + { + objects[j]->update(speed, amplitude, pbi); } pbi->calculateOverlappingPairs(0); } - b3BroadphaseBenchmark::OutputTime("\tUpdate",wallclock,experiment.iterations); - /* Clean up */ + b3BroadphaseBenchmark::OutputTime("\tUpdate", wallclock, experiment.iterations); + /* Clean up */ wallclock.reset(); - for(int i=0;idestroyProxy(objects[i]->proxy,0); + pbi->destroyProxy(objects[i]->proxy, 0); delete objects[i]; } objects.resize(0); - b3BroadphaseBenchmark::OutputTime("\tRelease",wallclock); + b3BroadphaseBenchmark::OutputTime("\tRelease", wallclock); } - } #else /*void b3DynamicBvhBroadphase::benchmark(b3BroadphaseInterface*) @@ -799,6 +804,5 @@ void b3DynamicBvhBroadphase::benchmark(b3BroadphaseInterface* pbi) #endif #if B3_DBVT_BP_PROFILE -#undef b3SPC +#undef b3SPC #endif - diff --git a/src/Bullet3Collision/BroadPhaseCollision/b3DynamicBvhBroadphase.h b/src/Bullet3Collision/BroadPhaseCollision/b3DynamicBvhBroadphase.h index 7ac085d90..c235e4014 100644 --- a/src/Bullet3Collision/BroadPhaseCollision/b3DynamicBvhBroadphase.h +++ b/src/Bullet3Collision/BroadPhaseCollision/b3DynamicBvhBroadphase.h @@ -27,46 +27,43 @@ subject to the following restrictions: // Compile time config // -#define B3_DBVT_BP_PROFILE 0 +#define B3_DBVT_BP_PROFILE 0 //#define B3_DBVT_BP_SORTPAIRS 1 -#define B3_DBVT_BP_PREVENTFALSEUPDATE 0 -#define B3_DBVT_BP_ACCURATESLEEPING 0 -#define B3_DBVT_BP_ENABLE_BENCHMARK 0 -#define B3_DBVT_BP_MARGIN (b3Scalar)0.05 +#define B3_DBVT_BP_PREVENTFALSEUPDATE 0 +#define B3_DBVT_BP_ACCURATESLEEPING 0 +#define B3_DBVT_BP_ENABLE_BENCHMARK 0 +#define B3_DBVT_BP_MARGIN (b3Scalar)0.05 #if B3_DBVT_BP_PROFILE -#define B3_DBVT_BP_PROFILING_RATE 256 +#define B3_DBVT_BP_PROFILING_RATE 256 #endif - - - -B3_ATTRIBUTE_ALIGNED16(struct) b3BroadphaseProxy +B3_ATTRIBUTE_ALIGNED16(struct) +b3BroadphaseProxy { + B3_DECLARE_ALIGNED_ALLOCATOR(); -B3_DECLARE_ALIGNED_ALLOCATOR(); - ///optional filtering to cull potential collisions enum CollisionFilterGroups { - DefaultFilter = 1, - StaticFilter = 2, - KinematicFilter = 4, - DebrisFilter = 8, - SensorTrigger = 16, - CharacterFilter = 32, - AllFilter = -1 //all bits sets: DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger + DefaultFilter = 1, + StaticFilter = 2, + KinematicFilter = 4, + DebrisFilter = 8, + SensorTrigger = 16, + CharacterFilter = 32, + AllFilter = -1 //all bits sets: DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger }; //Usually the client b3CollisionObject or Rigidbody class - void* m_clientObject; + void* m_clientObject; int m_collisionFilterGroup; int m_collisionFilterMask; - int m_uniqueId;//m_uniqueId is introduced for paircache. could get rid of this, by calculating the address offset etc. + int m_uniqueId; //m_uniqueId is introduced for paircache. could get rid of this, by calculating the address offset etc. - b3Vector3 m_aabbMin; - b3Vector3 m_aabbMax; + b3Vector3 m_aabbMin; + b3Vector3 m_aabbMax; B3_FORCE_INLINE int getUid() const { @@ -74,116 +71,112 @@ B3_DECLARE_ALIGNED_ALLOCATOR(); } //used for memory pools - b3BroadphaseProxy() :m_clientObject(0) + b3BroadphaseProxy() : m_clientObject(0) { } - b3BroadphaseProxy(const b3Vector3& aabbMin,const b3Vector3& aabbMax,void* userPtr, int collisionFilterGroup, int collisionFilterMask) - :m_clientObject(userPtr), - m_collisionFilterGroup(collisionFilterGroup), - m_collisionFilterMask(collisionFilterMask), - m_aabbMin(aabbMin), - m_aabbMax(aabbMax) + b3BroadphaseProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, void* userPtr, int collisionFilterGroup, int collisionFilterMask) + : m_clientObject(userPtr), + m_collisionFilterGroup(collisionFilterGroup), + m_collisionFilterMask(collisionFilterMask), + m_aabbMin(aabbMin), + m_aabbMax(aabbMax) { } }; - - - - // // b3DbvtProxy // struct b3DbvtProxy : b3BroadphaseProxy { - /* Fields */ + /* Fields */ //b3DbvtAabbMm aabb; - b3DbvtNode* leaf; - b3DbvtProxy* links[2]; - int stage; - /* ctor */ + b3DbvtNode* leaf; + b3DbvtProxy* links[2]; + int stage; + /* ctor */ explicit b3DbvtProxy() {} - b3DbvtProxy(const b3Vector3& aabbMin,const b3Vector3& aabbMax,void* userPtr, int collisionFilterGroup, int collisionFilterMask) : - b3BroadphaseProxy(aabbMin,aabbMax,userPtr,collisionFilterGroup,collisionFilterMask) + b3DbvtProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, void* userPtr, int collisionFilterGroup, int collisionFilterMask) : b3BroadphaseProxy(aabbMin, aabbMax, userPtr, collisionFilterGroup, collisionFilterMask) { - links[0]=links[1]=0; + links[0] = links[1] = 0; } }; -typedef b3AlignedObjectArray b3DbvtProxyArray; +typedef b3AlignedObjectArray b3DbvtProxyArray; ///The b3DynamicBvhBroadphase implements a broadphase using two dynamic AABB bounding volume hierarchies/trees (see b3DynamicBvh). ///One tree is used for static/non-moving objects, and another tree is used for dynamic objects. Objects can move from one tree to the other. ///This is a very fast broadphase, especially for very dynamic worlds where many objects are moving. Its insert/add and remove of objects is generally faster than the sweep and prune broadphases b3AxisSweep3 and b332BitAxisSweep3. -struct b3DynamicBvhBroadphase +struct b3DynamicBvhBroadphase { - /* Config */ - enum { - DYNAMIC_SET = 0, /* Dynamic set index */ - FIXED_SET = 1, /* Fixed set index */ - STAGECOUNT = 2 /* Number of stages */ + /* Config */ + enum + { + DYNAMIC_SET = 0, /* Dynamic set index */ + FIXED_SET = 1, /* Fixed set index */ + STAGECOUNT = 2 /* Number of stages */ }; - /* Fields */ - b3DynamicBvh m_sets[2]; // Dbvt sets - b3DbvtProxy* m_stageRoots[STAGECOUNT+1]; // Stages list + /* Fields */ + b3DynamicBvh m_sets[2]; // Dbvt sets + b3DbvtProxy* m_stageRoots[STAGECOUNT + 1]; // Stages list - b3AlignedObjectArray m_proxies; - b3OverlappingPairCache* m_paircache; // Pair cache - b3Scalar m_prediction; // Velocity prediction - int m_stageCurrent; // Current stage - int m_fupdates; // % of fixed updates per frame - int m_dupdates; // % of dynamic updates per frame - int m_cupdates; // % of cleanup updates per frame - int m_newpairs; // Number of pairs created - int m_fixedleft; // Fixed optimization left - unsigned m_updates_call; // Number of updates call - unsigned m_updates_done; // Number of updates done - b3Scalar m_updates_ratio; // m_updates_done/m_updates_call - int m_pid; // Parse id - int m_cid; // Cleanup index - bool m_releasepaircache; // Release pair cache on delete - bool m_deferedcollide; // Defere dynamic/static collision to collide call - bool m_needcleanup; // Need to run cleanup? + b3AlignedObjectArray m_proxies; + b3OverlappingPairCache* m_paircache; // Pair cache + b3Scalar m_prediction; // Velocity prediction + int m_stageCurrent; // Current stage + int m_fupdates; // % of fixed updates per frame + int m_dupdates; // % of dynamic updates per frame + int m_cupdates; // % of cleanup updates per frame + int m_newpairs; // Number of pairs created + int m_fixedleft; // Fixed optimization left + unsigned m_updates_call; // Number of updates call + unsigned m_updates_done; // Number of updates done + b3Scalar m_updates_ratio; // m_updates_done/m_updates_call + int m_pid; // Parse id + int m_cid; // Cleanup index + bool m_releasepaircache; // Release pair cache on delete + bool m_deferedcollide; // Defere dynamic/static collision to collide call + bool m_needcleanup; // Need to run cleanup? #if B3_DBVT_BP_PROFILE - b3Clock m_clock; - struct { - unsigned long m_total; - unsigned long m_ddcollide; - unsigned long m_fdcollide; - unsigned long m_cleanup; - unsigned long m_jobcount; - } m_profiling; + b3Clock m_clock; + struct + { + unsigned long m_total; + unsigned long m_ddcollide; + unsigned long m_fdcollide; + unsigned long m_cleanup; + unsigned long m_jobcount; + } m_profiling; #endif - /* Methods */ - b3DynamicBvhBroadphase(int proxyCapacity, b3OverlappingPairCache* paircache=0); + /* Methods */ + b3DynamicBvhBroadphase(int proxyCapacity, b3OverlappingPairCache* paircache = 0); virtual ~b3DynamicBvhBroadphase(); - void collide(b3Dispatcher* dispatcher); - void optimize(); - + void collide(b3Dispatcher* dispatcher); + void optimize(); + /* b3BroadphaseInterface Implementation */ - b3BroadphaseProxy* createProxy(const b3Vector3& aabbMin,const b3Vector3& aabbMax,int objectIndex,void* userPtr, int collisionFilterGroup, int collisionFilterMask); - virtual void destroyProxy(b3BroadphaseProxy* proxy,b3Dispatcher* dispatcher); - virtual void setAabb(int objectId,const b3Vector3& aabbMin,const b3Vector3& aabbMax,b3Dispatcher* dispatcher); - virtual void rayTest(const b3Vector3& rayFrom,const b3Vector3& rayTo, b3BroadphaseRayCallback& rayCallback, const b3Vector3& aabbMin=b3MakeVector3(0,0,0), const b3Vector3& aabbMax = b3MakeVector3(0,0,0)); - virtual void aabbTest(const b3Vector3& aabbMin, const b3Vector3& aabbMax, b3BroadphaseAabbCallback& callback); + b3BroadphaseProxy* createProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int objectIndex, void* userPtr, int collisionFilterGroup, int collisionFilterMask); + virtual void destroyProxy(b3BroadphaseProxy* proxy, b3Dispatcher* dispatcher); + virtual void setAabb(int objectId, const b3Vector3& aabbMin, const b3Vector3& aabbMax, b3Dispatcher* dispatcher); + virtual void rayTest(const b3Vector3& rayFrom, const b3Vector3& rayTo, b3BroadphaseRayCallback& rayCallback, const b3Vector3& aabbMin = b3MakeVector3(0, 0, 0), const b3Vector3& aabbMax = b3MakeVector3(0, 0, 0)); + virtual void aabbTest(const b3Vector3& aabbMin, const b3Vector3& aabbMax, b3BroadphaseAabbCallback& callback); //virtual void getAabb(b3BroadphaseProxy* proxy,b3Vector3& aabbMin, b3Vector3& aabbMax ) const; - virtual void getAabb(int objectId,b3Vector3& aabbMin, b3Vector3& aabbMax ) const; - virtual void calculateOverlappingPairs(b3Dispatcher* dispatcher=0); - virtual b3OverlappingPairCache* getOverlappingPairCache(); - virtual const b3OverlappingPairCache* getOverlappingPairCache() const; - virtual void getBroadphaseAabb(b3Vector3& aabbMin,b3Vector3& aabbMax) const; - virtual void printStats(); - + virtual void getAabb(int objectId, b3Vector3& aabbMin, b3Vector3& aabbMax) const; + virtual void calculateOverlappingPairs(b3Dispatcher* dispatcher = 0); + virtual b3OverlappingPairCache* getOverlappingPairCache(); + virtual const b3OverlappingPairCache* getOverlappingPairCache() const; + virtual void getBroadphaseAabb(b3Vector3& aabbMin, b3Vector3& aabbMax) const; + virtual void printStats(); ///reset broadphase internal structures, to ensure determinism/reproducability virtual void resetPool(b3Dispatcher* dispatcher); - void performDeferredRemoval(b3Dispatcher* dispatcher); - - void setVelocityPrediction(b3Scalar prediction) + void performDeferredRemoval(b3Dispatcher* dispatcher); + + void setVelocityPrediction(b3Scalar prediction) { m_prediction = prediction; } @@ -192,15 +185,13 @@ struct b3DynamicBvhBroadphase return m_prediction; } - ///this setAabbForceUpdate is similar to setAabb but always forces the aabb update. + ///this setAabbForceUpdate is similar to setAabb but always forces the aabb update. ///it is not part of the b3BroadphaseInterface but specific to b3DynamicBvhBroadphase. ///it bypasses certain optimizations that prevent aabb updates (when the aabb shrinks), see ///http://code.google.com/p/bullet/issues/detail?id=223 - void setAabbForceUpdate( b3BroadphaseProxy* absproxy,const b3Vector3& aabbMin,const b3Vector3& aabbMax,b3Dispatcher* /*dispatcher*/); + void setAabbForceUpdate(b3BroadphaseProxy* absproxy, const b3Vector3& aabbMin, const b3Vector3& aabbMax, b3Dispatcher* /*dispatcher*/); //static void benchmark(b3BroadphaseInterface*); - - }; #endif diff --git a/src/Bullet3Collision/BroadPhaseCollision/b3OverlappingPair.h b/src/Bullet3Collision/BroadPhaseCollision/b3OverlappingPair.h index 39bf27de3..4ff9ebae8 100644 --- a/src/Bullet3Collision/BroadPhaseCollision/b3OverlappingPair.h +++ b/src/Bullet3Collision/BroadPhaseCollision/b3OverlappingPair.h @@ -23,20 +23,20 @@ subject to the following restrictions: typedef b3Int4 b3BroadphasePair; -inline b3Int4 b3MakeBroadphasePair(int xx,int yy) +inline b3Int4 b3MakeBroadphasePair(int xx, int yy) { b3Int4 pair; if (xx < yy) - { - pair.x = xx; - pair.y = yy; - } - else - { + { + pair.x = xx; + pair.y = yy; + } + else + { pair.x = yy; - pair.y = xx; - } + pair.y = xx; + } pair.z = B3_NEW_PAIR_MARKER; pair.w = B3_NEW_PAIR_MARKER; return pair; @@ -51,22 +51,20 @@ inline b3Int4 b3MakeBroadphasePair(int xx,int yy) class b3BroadphasePairSortPredicate { - public: - - bool operator() ( const b3BroadphasePair& a, const b3BroadphasePair& b ) const - { - const int uidA0 = a.x; - const int uidB0 = b.x; - const int uidA1 = a.y; - const int uidB1 = b.y; - return uidA0 > uidB0 || (uidA0 == uidB0 && uidA1 > uidB1); - } +public: + bool operator()(const b3BroadphasePair& a, const b3BroadphasePair& b) const + { + const int uidA0 = a.x; + const int uidB0 = b.x; + const int uidA1 = a.y; + const int uidB1 = b.y; + return uidA0 > uidB0 || (uidA0 == uidB0 && uidA1 > uidB1); + } }; -B3_FORCE_INLINE bool operator==(const b3BroadphasePair& a, const b3BroadphasePair& b) +B3_FORCE_INLINE bool operator==(const b3BroadphasePair& a, const b3BroadphasePair& b) { - return (a.x == b.x ) && (a.y == b.y ); + return (a.x == b.x) && (a.y == b.y); } -#endif //B3_OVERLAPPING_PAIR_H - +#endif //B3_OVERLAPPING_PAIR_H diff --git a/src/Bullet3Collision/BroadPhaseCollision/b3OverlappingPairCache.cpp b/src/Bullet3Collision/BroadPhaseCollision/b3OverlappingPairCache.cpp index e4bda6162..19773244b 100644 --- a/src/Bullet3Collision/BroadPhaseCollision/b3OverlappingPairCache.cpp +++ b/src/Bullet3Collision/BroadPhaseCollision/b3OverlappingPairCache.cpp @@ -13,8 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "b3OverlappingPairCache.h" //#include "b3Dispatcher.h" @@ -23,35 +21,26 @@ subject to the following restrictions: #include -int b3g_overlappingPairs = 0; -int b3g_removePairs =0; -int b3g_addedPairs =0; -int b3g_findPairs =0; +int b3g_overlappingPairs = 0; +int b3g_removePairs = 0; +int b3g_addedPairs = 0; +int b3g_findPairs = 0; - - - -b3HashedOverlappingPairCache::b3HashedOverlappingPairCache(): - m_overlapFilterCallback(0) +b3HashedOverlappingPairCache::b3HashedOverlappingPairCache() : m_overlapFilterCallback(0) //, m_blockedForChanges(false) { - int initialAllocatedSize= 2; + int initialAllocatedSize = 2; m_overlappingPairArray.reserve(initialAllocatedSize); growTables(); } - - - b3HashedOverlappingPairCache::~b3HashedOverlappingPairCache() { } - - -void b3HashedOverlappingPairCache::cleanOverlappingPair(b3BroadphasePair& pair,b3Dispatcher* dispatcher) +void b3HashedOverlappingPairCache::cleanOverlappingPair(b3BroadphasePair& pair, b3Dispatcher* dispatcher) { -/* if (pair.m_algorithm) + /* if (pair.m_algorithm) { { pair.m_algorithm->~b3CollisionAlgorithm(); @@ -60,91 +49,74 @@ void b3HashedOverlappingPairCache::cleanOverlappingPair(b3BroadphasePair& pair,b } } */ - } - - - -void b3HashedOverlappingPairCache::cleanProxyFromPairs(int proxy,b3Dispatcher* dispatcher) +void b3HashedOverlappingPairCache::cleanProxyFromPairs(int proxy, b3Dispatcher* dispatcher) { - - class CleanPairCallback : public b3OverlapCallback + class CleanPairCallback : public b3OverlapCallback { int m_cleanProxy; - b3OverlappingPairCache* m_pairCache; + b3OverlappingPairCache* m_pairCache; b3Dispatcher* m_dispatcher; public: - CleanPairCallback(int cleanProxy,b3OverlappingPairCache* pairCache,b3Dispatcher* dispatcher) - :m_cleanProxy(cleanProxy), - m_pairCache(pairCache), - m_dispatcher(dispatcher) + CleanPairCallback(int cleanProxy, b3OverlappingPairCache* pairCache, b3Dispatcher* dispatcher) + : m_cleanProxy(cleanProxy), + m_pairCache(pairCache), + m_dispatcher(dispatcher) { } - virtual bool processOverlap(b3BroadphasePair& pair) + virtual bool processOverlap(b3BroadphasePair& pair) { if ((pair.x == m_cleanProxy) || (pair.y == m_cleanProxy)) { - m_pairCache->cleanOverlappingPair(pair,m_dispatcher); + m_pairCache->cleanOverlappingPair(pair, m_dispatcher); } return false; } - }; - CleanPairCallback cleanPairs(proxy,this,dispatcher); - - processAllOverlappingPairs(&cleanPairs,dispatcher); + CleanPairCallback cleanPairs(proxy, this, dispatcher); + processAllOverlappingPairs(&cleanPairs, dispatcher); } - - - -void b3HashedOverlappingPairCache::removeOverlappingPairsContainingProxy(int proxy,b3Dispatcher* dispatcher) +void b3HashedOverlappingPairCache::removeOverlappingPairsContainingProxy(int proxy, b3Dispatcher* dispatcher) { - - class RemovePairCallback : public b3OverlapCallback + class RemovePairCallback : public b3OverlapCallback { int m_obsoleteProxy; public: RemovePairCallback(int obsoleteProxy) - :m_obsoleteProxy(obsoleteProxy) + : m_obsoleteProxy(obsoleteProxy) { } - virtual bool processOverlap(b3BroadphasePair& pair) + virtual bool processOverlap(b3BroadphasePair& pair) { return ((pair.x == m_obsoleteProxy) || - (pair.y == m_obsoleteProxy)); + (pair.y == m_obsoleteProxy)); } - }; - RemovePairCallback removeCallback(proxy); - processAllOverlappingPairs(&removeCallback,dispatcher); + processAllOverlappingPairs(&removeCallback, dispatcher); } - - - - b3BroadphasePair* b3HashedOverlappingPairCache::findPair(int proxy0, int proxy1) { b3g_findPairs++; - if(proxy0 >proxy1) - b3Swap(proxy0,proxy1); + if (proxy0 > proxy1) + b3Swap(proxy0, proxy1); int proxyId1 = proxy0; int proxyId2 = proxy1; /*if (proxyId1 > proxyId2) b3Swap(proxyId1, proxyId2);*/ - int hash = static_cast(getHash(static_cast(proxyId1), static_cast(proxyId2)) & (m_overlappingPairArray.capacity()-1)); + int hash = static_cast(getHash(static_cast(proxyId1), static_cast(proxyId2)) & (m_overlappingPairArray.capacity() - 1)); if (hash >= m_hashTable.size()) { @@ -169,9 +141,8 @@ b3BroadphasePair* b3HashedOverlappingPairCache::findPair(int proxy0, int proxy1) //#include -void b3HashedOverlappingPairCache::growTables() +void b3HashedOverlappingPairCache::growTables() { - int newCapacity = m_overlappingPairArray.capacity(); if (m_hashTable.size() < newCapacity) @@ -182,10 +153,9 @@ void b3HashedOverlappingPairCache::growTables() m_hashTable.resize(newCapacity); m_next.resize(newCapacity); - int i; - for (i= 0; i < newCapacity; ++i) + for (i = 0; i < newCapacity; ++i) { m_hashTable[i] = B3_NULL_PAIR; } @@ -194,35 +164,31 @@ void b3HashedOverlappingPairCache::growTables() m_next[i] = B3_NULL_PAIR; } - for(i=0;i proxyId2) b3Swap(proxyId1, proxyId2);*/ - int hashValue = static_cast(getHash(static_cast(proxyId1),static_cast(proxyId2)) & (m_overlappingPairArray.capacity()-1)); // New hash value with new mask + int hashValue = static_cast(getHash(static_cast(proxyId1), static_cast(proxyId2)) & (m_overlappingPairArray.capacity() - 1)); // New hash value with new mask m_next[i] = m_hashTable[hashValue]; m_hashTable[hashValue] = i; } - - } } b3BroadphasePair* b3HashedOverlappingPairCache::internalAddPair(int proxy0, int proxy1) { - if(proxy0>proxy1) - b3Swap(proxy0,proxy1); + if (proxy0 > proxy1) + b3Swap(proxy0, proxy1); int proxyId1 = proxy0; int proxyId2 = proxy1; /*if (proxyId1 > proxyId2) b3Swap(proxyId1, proxyId2);*/ - int hash = static_cast(getHash(static_cast(proxyId1),static_cast(proxyId2)) & (m_overlappingPairArray.capacity()-1)); // New hash value with new mask - + int hash = static_cast(getHash(static_cast(proxyId1), static_cast(proxyId2)) & (m_overlappingPairArray.capacity() - 1)); // New hash value with new mask b3BroadphasePair* pair = internalFindPair(proxy0, proxy1, hash); if (pair != NULL) @@ -243,8 +209,8 @@ b3BroadphasePair* b3HashedOverlappingPairCache::internalAddPair(int proxy0, int pair = &m_overlappingPairArray.expandNonInitializing(); //this is where we add an actual pair, so also call the 'ghost' -// if (m_ghostPairCallback) -// m_ghostPairCallback->addOverlappingPair(proxy0,proxy1); + // if (m_ghostPairCallback) + // m_ghostPairCallback->addOverlappingPair(proxy0,proxy1); int newCapacity = m_overlappingPairArray.capacity(); @@ -252,16 +218,15 @@ b3BroadphasePair* b3HashedOverlappingPairCache::internalAddPair(int proxy0, int { growTables(); //hash with new capacity - hash = static_cast(getHash(static_cast(proxyId1),static_cast(proxyId2)) & (m_overlappingPairArray.capacity()-1)); + hash = static_cast(getHash(static_cast(proxyId1), static_cast(proxyId2)) & (m_overlappingPairArray.capacity() - 1)); } - - *pair = b3MakeBroadphasePair(proxy0,proxy1); - -// pair->m_pProxy0 = proxy0; -// pair->m_pProxy1 = proxy1; + + *pair = b3MakeBroadphasePair(proxy0, proxy1); + + // pair->m_pProxy0 = proxy0; + // pair->m_pProxy1 = proxy1; //pair->m_algorithm = 0; //pair->m_internalTmpValue = 0; - m_next[count] = m_hashTable[hash]; m_hashTable[hash] = count; @@ -269,20 +234,18 @@ b3BroadphasePair* b3HashedOverlappingPairCache::internalAddPair(int proxy0, int return pair; } - - -void* b3HashedOverlappingPairCache::removeOverlappingPair(int proxy0, int proxy1,b3Dispatcher* dispatcher) +void* b3HashedOverlappingPairCache::removeOverlappingPair(int proxy0, int proxy1, b3Dispatcher* dispatcher) { b3g_removePairs++; - if(proxy0>proxy1) - b3Swap(proxy0,proxy1); + if (proxy0 > proxy1) + b3Swap(proxy0, proxy1); int proxyId1 = proxy0; int proxyId2 = proxy1; /*if (proxyId1 > proxyId2) b3Swap(proxyId1, proxyId2);*/ - int hash = static_cast(getHash(static_cast(proxyId1),static_cast(proxyId2)) & (m_overlappingPairArray.capacity()-1)); + int hash = static_cast(getHash(static_cast(proxyId1), static_cast(proxyId2)) & (m_overlappingPairArray.capacity() - 1)); b3BroadphasePair* pair = internalFindPair(proxy0, proxy1, hash); if (pair == NULL) @@ -290,9 +253,7 @@ void* b3HashedOverlappingPairCache::removeOverlappingPair(int proxy0, int proxy1 return 0; } - cleanOverlappingPair(*pair,dispatcher); - - + cleanOverlappingPair(*pair, dispatcher); int pairIndex = int(pair - &m_overlappingPairArray[0]); b3Assert(pairIndex < m_overlappingPairArray.size()); @@ -336,8 +297,8 @@ void* b3HashedOverlappingPairCache::removeOverlappingPair(int proxy0, int proxy1 // Remove the last pair from the hash table. const b3BroadphasePair* last = &m_overlappingPairArray[lastPairIndex]; - /* missing swap here too, Nat. */ - int lastHash = static_cast(getHash(static_cast(last->x), static_cast(last->y)) & (m_overlappingPairArray.capacity()-1)); + /* missing swap here too, Nat. */ + int lastHash = static_cast(getHash(static_cast(last->x), static_cast(last->y)) & (m_overlappingPairArray.capacity() - 1)); index = m_hashTable[lastHash]; b3Assert(index != B3_NULL_PAIR); @@ -372,47 +333,42 @@ void* b3HashedOverlappingPairCache::removeOverlappingPair(int proxy0, int proxy1 } //#include -void b3HashedOverlappingPairCache::processAllOverlappingPairs(b3OverlapCallback* callback,b3Dispatcher* dispatcher) +void b3HashedOverlappingPairCache::processAllOverlappingPairs(b3OverlapCallback* callback, b3Dispatcher* dispatcher) { - int i; -// printf("m_overlappingPairArray.size()=%d\n",m_overlappingPairArray.size()); - for (i=0;iprocessOverlap(*pair)) { - removeOverlappingPair(pair->x,pair->y,dispatcher); + removeOverlappingPair(pair->x, pair->y, dispatcher); b3g_overlappingPairs--; - } else + } + else { i++; } } } - - - - -void b3HashedOverlappingPairCache::sortOverlappingPairs(b3Dispatcher* dispatcher) +void b3HashedOverlappingPairCache::sortOverlappingPairs(b3Dispatcher* dispatcher) { ///need to keep hashmap in sync with pair address, so rebuild all b3BroadphasePairArray tmpPairs; int i; - for (i=0;iremoveOverlappingPair(proxy0, proxy1,dispatcher); - - m_overlappingPairArray.swap(findIndex,m_overlappingPairArray.capacity()-1); + + m_overlappingPairArray.swap(findIndex, m_overlappingPairArray.capacity() - 1); m_overlappingPairArray.pop_back(); return 0; } @@ -455,100 +407,77 @@ void* b3SortedOverlappingPairCache::removeOverlappingPair(int proxy0,int proxy1, return 0; } - - - - - - - -b3BroadphasePair* b3SortedOverlappingPairCache::addOverlappingPair(int proxy0,int proxy1) +b3BroadphasePair* b3SortedOverlappingPairCache::addOverlappingPair(int proxy0, int proxy1) { //don't add overlap with own b3Assert(proxy0 != proxy1); - if (!needsBroadphaseCollision(proxy0,proxy1)) + if (!needsBroadphaseCollision(proxy0, proxy1)) return 0; - + b3BroadphasePair* pair = &m_overlappingPairArray.expandNonInitializing(); - *pair = b3MakeBroadphasePair(proxy0,proxy1); - - + *pair = b3MakeBroadphasePair(proxy0, proxy1); + b3g_overlappingPairs++; b3g_addedPairs++; - -// if (m_ghostPairCallback) -// m_ghostPairCallback->addOverlappingPair(proxy0, proxy1); + + // if (m_ghostPairCallback) + // m_ghostPairCallback->addOverlappingPair(proxy0, proxy1); return pair; - } ///this findPair becomes really slow. Either sort the list to speedup the query, or ///use a different solution. It is mainly used for Removing overlapping pairs. Removal could be delayed. ///we could keep a linked list in each proxy, and store pair in one of the proxies (with lowest memory address) ///Also we can use a 2D bitmap, which can be useful for a future GPU implementation - b3BroadphasePair* b3SortedOverlappingPairCache::findPair(int proxy0,int proxy1) +b3BroadphasePair* b3SortedOverlappingPairCache::findPair(int proxy0, int proxy1) { - if (!needsBroadphaseCollision(proxy0,proxy1)) + if (!needsBroadphaseCollision(proxy0, proxy1)) return 0; - b3BroadphasePair tmpPair = b3MakeBroadphasePair(proxy0,proxy1); + b3BroadphasePair tmpPair = b3MakeBroadphasePair(proxy0, proxy1); int findIndex = m_overlappingPairArray.findLinearSearch(tmpPair); if (findIndex < m_overlappingPairArray.size()) { //b3Assert(it != m_overlappingPairSet.end()); - b3BroadphasePair* pair = &m_overlappingPairArray[findIndex]; + b3BroadphasePair* pair = &m_overlappingPairArray[findIndex]; return pair; } return 0; } - - - - - - - - - //#include -void b3SortedOverlappingPairCache::processAllOverlappingPairs(b3OverlapCallback* callback,b3Dispatcher* dispatcher) +void b3SortedOverlappingPairCache::processAllOverlappingPairs(b3OverlapCallback* callback, b3Dispatcher* dispatcher) { - int i; - for (i=0;iprocessOverlap(*pair)) { - cleanOverlappingPair(*pair,dispatcher); + cleanOverlappingPair(*pair, dispatcher); pair->x = -1; pair->y = -1; - m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); + m_overlappingPairArray.swap(i, m_overlappingPairArray.size() - 1); m_overlappingPairArray.pop_back(); b3g_overlappingPairs--; - } else + } + else { i++; } } } - - - -b3SortedOverlappingPairCache::b3SortedOverlappingPairCache(): - m_blockedForChanges(false), - m_hasDeferredRemoval(true), - m_overlapFilterCallback(0) +b3SortedOverlappingPairCache::b3SortedOverlappingPairCache() : m_blockedForChanges(false), + m_hasDeferredRemoval(true), + m_overlapFilterCallback(0) { - int initialAllocatedSize= 2; + int initialAllocatedSize = 2; m_overlappingPairArray.reserve(initialAllocatedSize); } @@ -556,9 +485,9 @@ b3SortedOverlappingPairCache::~b3SortedOverlappingPairCache() { } -void b3SortedOverlappingPairCache::cleanOverlappingPair(b3BroadphasePair& pair,b3Dispatcher* dispatcher) +void b3SortedOverlappingPairCache::cleanOverlappingPair(b3BroadphasePair& pair, b3Dispatcher* dispatcher) { -/* if (pair.m_algorithm) + /* if (pair.m_algorithm) { { pair.m_algorithm->~b3CollisionAlgorithm(); @@ -570,69 +499,61 @@ void b3SortedOverlappingPairCache::cleanOverlappingPair(b3BroadphasePair& pair,b */ } - -void b3SortedOverlappingPairCache::cleanProxyFromPairs(int proxy,b3Dispatcher* dispatcher) +void b3SortedOverlappingPairCache::cleanProxyFromPairs(int proxy, b3Dispatcher* dispatcher) { - - class CleanPairCallback : public b3OverlapCallback + class CleanPairCallback : public b3OverlapCallback { int m_cleanProxy; - b3OverlappingPairCache* m_pairCache; + b3OverlappingPairCache* m_pairCache; b3Dispatcher* m_dispatcher; public: - CleanPairCallback(int cleanProxy,b3OverlappingPairCache* pairCache,b3Dispatcher* dispatcher) - :m_cleanProxy(cleanProxy), - m_pairCache(pairCache), - m_dispatcher(dispatcher) + CleanPairCallback(int cleanProxy, b3OverlappingPairCache* pairCache, b3Dispatcher* dispatcher) + : m_cleanProxy(cleanProxy), + m_pairCache(pairCache), + m_dispatcher(dispatcher) { } - virtual bool processOverlap(b3BroadphasePair& pair) + virtual bool processOverlap(b3BroadphasePair& pair) { if ((pair.x == m_cleanProxy) || (pair.y == m_cleanProxy)) { - m_pairCache->cleanOverlappingPair(pair,m_dispatcher); + m_pairCache->cleanOverlappingPair(pair, m_dispatcher); } return false; } - }; - CleanPairCallback cleanPairs(proxy,this,dispatcher); - - processAllOverlappingPairs(&cleanPairs,dispatcher); + CleanPairCallback cleanPairs(proxy, this, dispatcher); + processAllOverlappingPairs(&cleanPairs, dispatcher); } - -void b3SortedOverlappingPairCache::removeOverlappingPairsContainingProxy(int proxy,b3Dispatcher* dispatcher) +void b3SortedOverlappingPairCache::removeOverlappingPairsContainingProxy(int proxy, b3Dispatcher* dispatcher) { - - class RemovePairCallback : public b3OverlapCallback + class RemovePairCallback : public b3OverlapCallback { int m_obsoleteProxy; public: RemovePairCallback(int obsoleteProxy) - :m_obsoleteProxy(obsoleteProxy) + : m_obsoleteProxy(obsoleteProxy) { } - virtual bool processOverlap(b3BroadphasePair& pair) + virtual bool processOverlap(b3BroadphasePair& pair) { return ((pair.x == m_obsoleteProxy) || - (pair.y == m_obsoleteProxy)); + (pair.y == m_obsoleteProxy)); } - }; RemovePairCallback removeCallback(proxy); - processAllOverlappingPairs(&removeCallback,dispatcher); + processAllOverlappingPairs(&removeCallback, dispatcher); } -void b3SortedOverlappingPairCache::sortOverlappingPairs(b3Dispatcher* dispatcher) +void b3SortedOverlappingPairCache::sortOverlappingPairs(b3Dispatcher* dispatcher) { //should already be sorted } - diff --git a/src/Bullet3Collision/BroadPhaseCollision/b3OverlappingPairCache.h b/src/Bullet3Collision/BroadPhaseCollision/b3OverlappingPairCache.h index f67eb676f..f1de1d94e 100644 --- a/src/Bullet3Collision/BroadPhaseCollision/b3OverlappingPairCache.h +++ b/src/Bullet3Collision/BroadPhaseCollision/b3OverlappingPairCache.h @@ -22,152 +22,136 @@ subject to the following restrictions: class b3Dispatcher; #include "b3OverlappingPair.h" +typedef b3AlignedObjectArray b3BroadphasePairArray; - -typedef b3AlignedObjectArray b3BroadphasePairArray; - -struct b3OverlapCallback +struct b3OverlapCallback { virtual ~b3OverlapCallback() - {} + { + } //return true for deletion of the pair - virtual bool processOverlap(b3BroadphasePair& pair) = 0; - + virtual bool processOverlap(b3BroadphasePair& pair) = 0; }; struct b3OverlapFilterCallback { virtual ~b3OverlapFilterCallback() - {} + { + } // return true when pairs need collision - virtual bool needBroadphaseCollision(int proxy0,int proxy1) const = 0; + virtual bool needBroadphaseCollision(int proxy0, int proxy1) const = 0; }; - - - - - - extern int b3g_removePairs; extern int b3g_addedPairs; extern int b3g_findPairs; -const int B3_NULL_PAIR=0xffffffff; +const int B3_NULL_PAIR = 0xffffffff; ///The b3OverlappingPairCache provides an interface for overlapping pair management (add, remove, storage), used by the b3BroadphaseInterface broadphases. ///The b3HashedOverlappingPairCache and b3SortedOverlappingPairCache classes are two implementations. -class b3OverlappingPairCache +class b3OverlappingPairCache { public: - virtual ~b3OverlappingPairCache() {} // this is needed so we can get to the derived class destructor + virtual ~b3OverlappingPairCache() {} // this is needed so we can get to the derived class destructor - virtual b3BroadphasePair* getOverlappingPairArrayPtr() = 0; - - virtual const b3BroadphasePair* getOverlappingPairArrayPtr() const = 0; + virtual b3BroadphasePair* getOverlappingPairArrayPtr() = 0; - virtual b3BroadphasePairArray& getOverlappingPairArray() = 0; + virtual const b3BroadphasePair* getOverlappingPairArrayPtr() const = 0; - virtual void cleanOverlappingPair(b3BroadphasePair& pair,b3Dispatcher* dispatcher) = 0; + virtual b3BroadphasePairArray& getOverlappingPairArray() = 0; + + virtual void cleanOverlappingPair(b3BroadphasePair& pair, b3Dispatcher* dispatcher) = 0; virtual int getNumOverlappingPairs() const = 0; - virtual void cleanProxyFromPairs(int proxy,b3Dispatcher* dispatcher) = 0; + virtual void cleanProxyFromPairs(int proxy, b3Dispatcher* dispatcher) = 0; - virtual void setOverlapFilterCallback(b3OverlapFilterCallback* callback) = 0; + virtual void setOverlapFilterCallback(b3OverlapFilterCallback* callback) = 0; - virtual void processAllOverlappingPairs(b3OverlapCallback*,b3Dispatcher* dispatcher) = 0; + virtual void processAllOverlappingPairs(b3OverlapCallback*, b3Dispatcher* dispatcher) = 0; virtual b3BroadphasePair* findPair(int proxy0, int proxy1) = 0; - virtual bool hasDeferredRemoval() = 0; + virtual bool hasDeferredRemoval() = 0; //virtual void setInternalGhostPairCallback(b3OverlappingPairCallback* ghostPairCallback)=0; - virtual b3BroadphasePair* addOverlappingPair(int proxy0,int proxy1)=0; - virtual void* removeOverlappingPair(int proxy0,int proxy1,b3Dispatcher* dispatcher)=0; - virtual void removeOverlappingPairsContainingProxy(int /*proxy0*/,b3Dispatcher* /*dispatcher*/)=0; - - virtual void sortOverlappingPairs(b3Dispatcher* dispatcher) = 0; - + virtual b3BroadphasePair* addOverlappingPair(int proxy0, int proxy1) = 0; + virtual void* removeOverlappingPair(int proxy0, int proxy1, b3Dispatcher* dispatcher) = 0; + virtual void removeOverlappingPairsContainingProxy(int /*proxy0*/, b3Dispatcher* /*dispatcher*/) = 0; + virtual void sortOverlappingPairs(b3Dispatcher* dispatcher) = 0; }; /// Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman, Codercorner, http://codercorner.com class b3HashedOverlappingPairCache : public b3OverlappingPairCache { - b3BroadphasePairArray m_overlappingPairArray; + b3BroadphasePairArray m_overlappingPairArray; b3OverlapFilterCallback* m_overlapFilterCallback; -// bool m_blockedForChanges; - + // bool m_blockedForChanges; public: b3HashedOverlappingPairCache(); virtual ~b3HashedOverlappingPairCache(); - - virtual void removeOverlappingPairsContainingProxy(int proxy,b3Dispatcher* dispatcher); + virtual void removeOverlappingPairsContainingProxy(int proxy, b3Dispatcher* dispatcher); - virtual void* removeOverlappingPair(int proxy0,int proxy1,b3Dispatcher* dispatcher); - - B3_FORCE_INLINE bool needsBroadphaseCollision(int proxy0,int proxy1) const + virtual void* removeOverlappingPair(int proxy0, int proxy1, b3Dispatcher* dispatcher); + + B3_FORCE_INLINE bool needsBroadphaseCollision(int proxy0, int proxy1) const { if (m_overlapFilterCallback) - return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1); + return m_overlapFilterCallback->needBroadphaseCollision(proxy0, proxy1); - bool collides = true;//(proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; + bool collides = true; //(proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; //collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); - + return collides; } // Add a pair and return the new pair. If the pair already exists, // no new pair is created and the old one is returned. - virtual b3BroadphasePair* addOverlappingPair(int proxy0,int proxy1) + virtual b3BroadphasePair* addOverlappingPair(int proxy0, int proxy1) { b3g_addedPairs++; - if (!needsBroadphaseCollision(proxy0,proxy1)) + if (!needsBroadphaseCollision(proxy0, proxy1)) return 0; - return internalAddPair(proxy0,proxy1); + return internalAddPair(proxy0, proxy1); } - + void cleanProxyFromPairs(int proxy, b3Dispatcher* dispatcher); - void cleanProxyFromPairs(int proxy,b3Dispatcher* dispatcher); + virtual void processAllOverlappingPairs(b3OverlapCallback*, b3Dispatcher* dispatcher); - - virtual void processAllOverlappingPairs(b3OverlapCallback*,b3Dispatcher* dispatcher); - - virtual b3BroadphasePair* getOverlappingPairArrayPtr() + virtual b3BroadphasePair* getOverlappingPairArrayPtr() { return &m_overlappingPairArray[0]; } - const b3BroadphasePair* getOverlappingPairArrayPtr() const + const b3BroadphasePair* getOverlappingPairArrayPtr() const { return &m_overlappingPairArray[0]; } - b3BroadphasePairArray& getOverlappingPairArray() + b3BroadphasePairArray& getOverlappingPairArray() { return m_overlappingPairArray; } - const b3BroadphasePairArray& getOverlappingPairArray() const + const b3BroadphasePairArray& getOverlappingPairArray() const { return m_overlappingPairArray; } - void cleanOverlappingPair(b3BroadphasePair& pair,b3Dispatcher* dispatcher); - - + void cleanOverlappingPair(b3BroadphasePair& pair, b3Dispatcher* dispatcher); b3BroadphasePair* findPair(int proxy0, int proxy1); int GetCount() const { return m_overlappingPairArray.size(); } -// b3BroadphasePair* GetPairs() { return m_pairs; } + // b3BroadphasePair* GetPairs() { return m_pairs; } b3OverlapFilterCallback* getOverlapFilterCallback() { @@ -179,19 +163,19 @@ public: m_overlapFilterCallback = callback; } - int getNumOverlappingPairs() const + int getNumOverlappingPairs() const { return m_overlappingPairArray.size(); } -private: - - b3BroadphasePair* internalAddPair(int proxy0,int proxy1); - void growTables(); +private: + b3BroadphasePair* internalAddPair(int proxy0, int proxy1); + + void growTables(); B3_FORCE_INLINE bool equalsPair(const b3BroadphasePair& pair, int proxyId1, int proxyId2) - { - return pair.x == proxyId1 && pair.y == proxyId2; + { + return pair.x == proxyId1 && pair.y == proxyId2; } /* @@ -210,43 +194,37 @@ private: } */ - - - B3_FORCE_INLINE unsigned int getHash(unsigned int proxyId1, unsigned int proxyId2) + B3_FORCE_INLINE unsigned int getHash(unsigned int proxyId1, unsigned int proxyId2) { - int key = static_cast(((unsigned int)proxyId1) | (((unsigned int)proxyId2) <<16)); + int key = static_cast(((unsigned int)proxyId1) | (((unsigned int)proxyId2) << 16)); // Thomas Wang's hash key += ~(key << 15); - key ^= (key >> 10); - key += (key << 3); - key ^= (key >> 6); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); key += ~(key << 11); - key ^= (key >> 16); + key ^= (key >> 16); return static_cast(key); } - - - - B3_FORCE_INLINE b3BroadphasePair* internalFindPair(int proxy0, int proxy1, int hash) { int proxyId1 = proxy0; int proxyId2 = proxy1; - #if 0 // wrong, 'equalsPair' use unsorted uids, copy-past devil striked again. Nat. +#if 0 // wrong, 'equalsPair' use unsorted uids, copy-past devil striked again. Nat. if (proxyId1 > proxyId2) b3Swap(proxyId1, proxyId2); - #endif +#endif int index = m_hashTable[hash]; - - while( index != B3_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false) + + while (index != B3_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false) { index = m_next[index]; } - if ( index == B3_NULL_PAIR ) + if (index == B3_NULL_PAIR) { return NULL; } @@ -256,161 +234,142 @@ private: return &m_overlappingPairArray[index]; } - virtual bool hasDeferredRemoval() + virtual bool hasDeferredRemoval() { return false; } -/* virtual void setInternalGhostPairCallback(b3OverlappingPairCallback* ghostPairCallback) + /* virtual void setInternalGhostPairCallback(b3OverlappingPairCallback* ghostPairCallback) { m_ghostPairCallback = ghostPairCallback; } */ - virtual void sortOverlappingPairs(b3Dispatcher* dispatcher); - + virtual void sortOverlappingPairs(b3Dispatcher* dispatcher); protected: - - b3AlignedObjectArray m_hashTable; - b3AlignedObjectArray m_next; -// b3OverlappingPairCallback* m_ghostPairCallback; - + b3AlignedObjectArray m_hashTable; + b3AlignedObjectArray m_next; + // b3OverlappingPairCallback* m_ghostPairCallback; }; - - - ///b3SortedOverlappingPairCache maintains the objects with overlapping AABB ///Typically managed by the Broadphase, Axis3Sweep or b3SimpleBroadphase -class b3SortedOverlappingPairCache : public b3OverlappingPairCache +class b3SortedOverlappingPairCache : public b3OverlappingPairCache { - protected: - //avoid brute-force finding all the time - b3BroadphasePairArray m_overlappingPairArray; +protected: + //avoid brute-force finding all the time + b3BroadphasePairArray m_overlappingPairArray; - //during the dispatch, check that user doesn't destroy/create proxy - bool m_blockedForChanges; + //during the dispatch, check that user doesn't destroy/create proxy + bool m_blockedForChanges; - ///by default, do the removal during the pair traversal - bool m_hasDeferredRemoval; - - //if set, use the callback instead of the built in filter in needBroadphaseCollision - b3OverlapFilterCallback* m_overlapFilterCallback; + ///by default, do the removal during the pair traversal + bool m_hasDeferredRemoval; -// b3OverlappingPairCallback* m_ghostPairCallback; + //if set, use the callback instead of the built in filter in needBroadphaseCollision + b3OverlapFilterCallback* m_overlapFilterCallback; - public: - - b3SortedOverlappingPairCache(); - virtual ~b3SortedOverlappingPairCache(); + // b3OverlappingPairCallback* m_ghostPairCallback; - virtual void processAllOverlappingPairs(b3OverlapCallback*,b3Dispatcher* dispatcher); +public: + b3SortedOverlappingPairCache(); + virtual ~b3SortedOverlappingPairCache(); - void* removeOverlappingPair(int proxy0,int proxy1,b3Dispatcher* dispatcher); + virtual void processAllOverlappingPairs(b3OverlapCallback*, b3Dispatcher* dispatcher); - void cleanOverlappingPair(b3BroadphasePair& pair,b3Dispatcher* dispatcher); - - b3BroadphasePair* addOverlappingPair(int proxy0,int proxy1); + void* removeOverlappingPair(int proxy0, int proxy1, b3Dispatcher* dispatcher); - b3BroadphasePair* findPair(int proxy0,int proxy1); - - - void cleanProxyFromPairs(int proxy,b3Dispatcher* dispatcher); + void cleanOverlappingPair(b3BroadphasePair& pair, b3Dispatcher* dispatcher); - virtual void removeOverlappingPairsContainingProxy(int proxy,b3Dispatcher* dispatcher); + b3BroadphasePair* addOverlappingPair(int proxy0, int proxy1); + b3BroadphasePair* findPair(int proxy0, int proxy1); - inline bool needsBroadphaseCollision(int proxy0,int proxy1) const - { - if (m_overlapFilterCallback) - return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1); + void cleanProxyFromPairs(int proxy, b3Dispatcher* dispatcher); - bool collides = true;//(proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; - //collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); - - return collides; - } - - b3BroadphasePairArray& getOverlappingPairArray() - { - return m_overlappingPairArray; - } + virtual void removeOverlappingPairsContainingProxy(int proxy, b3Dispatcher* dispatcher); - const b3BroadphasePairArray& getOverlappingPairArray() const - { - return m_overlappingPairArray; - } + inline bool needsBroadphaseCollision(int proxy0, int proxy1) const + { + if (m_overlapFilterCallback) + return m_overlapFilterCallback->needBroadphaseCollision(proxy0, proxy1); - + bool collides = true; //(proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; + //collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); + return collides; + } - b3BroadphasePair* getOverlappingPairArrayPtr() - { - return &m_overlappingPairArray[0]; - } + b3BroadphasePairArray& getOverlappingPairArray() + { + return m_overlappingPairArray; + } - const b3BroadphasePair* getOverlappingPairArrayPtr() const - { - return &m_overlappingPairArray[0]; - } + const b3BroadphasePairArray& getOverlappingPairArray() const + { + return m_overlappingPairArray; + } - int getNumOverlappingPairs() const - { - return m_overlappingPairArray.size(); - } - - b3OverlapFilterCallback* getOverlapFilterCallback() - { - return m_overlapFilterCallback; - } + b3BroadphasePair* getOverlappingPairArrayPtr() + { + return &m_overlappingPairArray[0]; + } - void setOverlapFilterCallback(b3OverlapFilterCallback* callback) - { - m_overlapFilterCallback = callback; - } + const b3BroadphasePair* getOverlappingPairArrayPtr() const + { + return &m_overlappingPairArray[0]; + } - virtual bool hasDeferredRemoval() - { - return m_hasDeferredRemoval; - } + int getNumOverlappingPairs() const + { + return m_overlappingPairArray.size(); + } -/* virtual void setInternalGhostPairCallback(b3OverlappingPairCallback* ghostPairCallback) + b3OverlapFilterCallback* getOverlapFilterCallback() + { + return m_overlapFilterCallback; + } + + void setOverlapFilterCallback(b3OverlapFilterCallback* callback) + { + m_overlapFilterCallback = callback; + } + + virtual bool hasDeferredRemoval() + { + return m_hasDeferredRemoval; + } + + /* virtual void setInternalGhostPairCallback(b3OverlappingPairCallback* ghostPairCallback) { m_ghostPairCallback = ghostPairCallback; } */ - virtual void sortOverlappingPairs(b3Dispatcher* dispatcher); - - + virtual void sortOverlappingPairs(b3Dispatcher* dispatcher); }; - - ///b3NullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and unit testing. class b3NullPairCache : public b3OverlappingPairCache { - - b3BroadphasePairArray m_overlappingPairArray; + b3BroadphasePairArray m_overlappingPairArray; public: - - virtual b3BroadphasePair* getOverlappingPairArrayPtr() + virtual b3BroadphasePair* getOverlappingPairArrayPtr() { return &m_overlappingPairArray[0]; } - const b3BroadphasePair* getOverlappingPairArrayPtr() const + const b3BroadphasePair* getOverlappingPairArrayPtr() const { return &m_overlappingPairArray[0]; } - b3BroadphasePairArray& getOverlappingPairArray() + b3BroadphasePairArray& getOverlappingPairArray() { return m_overlappingPairArray; } - - virtual void cleanOverlappingPair(b3BroadphasePair& /*pair*/,b3Dispatcher* /*dispatcher*/) - { + virtual void cleanOverlappingPair(b3BroadphasePair& /*pair*/, b3Dispatcher* /*dispatcher*/) + { } virtual int getNumOverlappingPairs() const @@ -418,16 +377,15 @@ public: return 0; } - virtual void cleanProxyFromPairs(int /*proxy*/,b3Dispatcher* /*dispatcher*/) - { - - } - - virtual void setOverlapFilterCallback(b3OverlapFilterCallback* /*callback*/) + virtual void cleanProxyFromPairs(int /*proxy*/, b3Dispatcher* /*dispatcher*/) { } - virtual void processAllOverlappingPairs(b3OverlapCallback*,b3Dispatcher* /*dispatcher*/) + virtual void setOverlapFilterCallback(b3OverlapFilterCallback* /*callback*/) + { + } + + virtual void processAllOverlappingPairs(b3OverlapCallback*, b3Dispatcher* /*dispatcher*/) { } @@ -436,39 +394,34 @@ public: return 0; } - virtual bool hasDeferredRemoval() + virtual bool hasDeferredRemoval() { return true; } -// virtual void setInternalGhostPairCallback(b3OverlappingPairCallback* /* ghostPairCallback */) -// { -// -// } + // virtual void setInternalGhostPairCallback(b3OverlappingPairCallback* /* ghostPairCallback */) + // { + // + // } - virtual b3BroadphasePair* addOverlappingPair(int /*proxy0*/,int /*proxy1*/) + virtual b3BroadphasePair* addOverlappingPair(int /*proxy0*/, int /*proxy1*/) { return 0; } - virtual void* removeOverlappingPair(int /*proxy0*/,int /*proxy1*/,b3Dispatcher* /*dispatcher*/) + virtual void* removeOverlappingPair(int /*proxy0*/, int /*proxy1*/, b3Dispatcher* /*dispatcher*/) { return 0; } - virtual void removeOverlappingPairsContainingProxy(int /*proxy0*/,b3Dispatcher* /*dispatcher*/) + virtual void removeOverlappingPairsContainingProxy(int /*proxy0*/, b3Dispatcher* /*dispatcher*/) { } - - virtual void sortOverlappingPairs(b3Dispatcher* dispatcher) + + virtual void sortOverlappingPairs(b3Dispatcher* dispatcher) { - (void) dispatcher; + (void)dispatcher; } - - }; - -#endif //B3_OVERLAPPING_PAIR_CACHE_H - - +#endif //B3_OVERLAPPING_PAIR_CACHE_H diff --git a/src/Bullet3Collision/BroadPhaseCollision/shared/b3Aabb.h b/src/Bullet3Collision/BroadPhaseCollision/shared/b3Aabb.h index 7f9bf990b..343a2c0e2 100644 --- a/src/Bullet3Collision/BroadPhaseCollision/shared/b3Aabb.h +++ b/src/Bullet3Collision/BroadPhaseCollision/shared/b3Aabb.h @@ -2,7 +2,6 @@ #ifndef B3_AABB_H #define B3_AABB_H - #include "Bullet3Common/shared/b3Float4.h" #include "Bullet3Common/shared/b3Mat3x3.h" @@ -10,44 +9,42 @@ typedef struct b3Aabb b3Aabb_t; struct b3Aabb { - union - { + union { float m_min[4]; b3Float4 m_minVec; int m_minIndices[4]; }; - union - { - float m_max[4]; + union { + float m_max[4]; b3Float4 m_maxVec; int m_signedMaxIndices[4]; }; }; -inline void b3TransformAabb2(b3Float4ConstArg localAabbMin,b3Float4ConstArg localAabbMax, float margin, - b3Float4ConstArg pos, - b3QuatConstArg orn, - b3Float4* aabbMinOut,b3Float4* aabbMaxOut) +inline void b3TransformAabb2(b3Float4ConstArg localAabbMin, b3Float4ConstArg localAabbMax, float margin, + b3Float4ConstArg pos, + b3QuatConstArg orn, + b3Float4* aabbMinOut, b3Float4* aabbMaxOut) { - b3Float4 localHalfExtents = 0.5f*(localAabbMax-localAabbMin); - localHalfExtents+=b3MakeFloat4(margin,margin,margin,0.f); - b3Float4 localCenter = 0.5f*(localAabbMax+localAabbMin); - b3Mat3x3 m; - m = b3QuatGetRotationMatrix(orn); - b3Mat3x3 abs_b = b3AbsoluteMat3x3(m); - b3Float4 center = b3TransformPoint(localCenter,pos,orn); - - b3Float4 extent = b3MakeFloat4(b3Dot3F4(localHalfExtents,b3GetRow(abs_b,0)), - b3Dot3F4(localHalfExtents,b3GetRow(abs_b,1)), - b3Dot3F4(localHalfExtents,b3GetRow(abs_b,2)), - 0.f); - *aabbMinOut = center-extent; - *aabbMaxOut = center+extent; + b3Float4 localHalfExtents = 0.5f * (localAabbMax - localAabbMin); + localHalfExtents += b3MakeFloat4(margin, margin, margin, 0.f); + b3Float4 localCenter = 0.5f * (localAabbMax + localAabbMin); + b3Mat3x3 m; + m = b3QuatGetRotationMatrix(orn); + b3Mat3x3 abs_b = b3AbsoluteMat3x3(m); + b3Float4 center = b3TransformPoint(localCenter, pos, orn); + + b3Float4 extent = b3MakeFloat4(b3Dot3F4(localHalfExtents, b3GetRow(abs_b, 0)), + b3Dot3F4(localHalfExtents, b3GetRow(abs_b, 1)), + b3Dot3F4(localHalfExtents, b3GetRow(abs_b, 2)), + 0.f); + *aabbMinOut = center - extent; + *aabbMaxOut = center + extent; } /// conservative test for overlap between two aabbs -inline bool b3TestAabbAgainstAabb(b3Float4ConstArg aabbMin1,b3Float4ConstArg aabbMax1, - b3Float4ConstArg aabbMin2, b3Float4ConstArg aabbMax2) +inline bool b3TestAabbAgainstAabb(b3Float4ConstArg aabbMin1, b3Float4ConstArg aabbMax1, + b3Float4ConstArg aabbMin2, b3Float4ConstArg aabbMax2) { bool overlap = true; overlap = (aabbMin1.x > aabbMax2.x || aabbMax1.x < aabbMin2.x) ? false : overlap; @@ -56,4 +53,4 @@ inline bool b3TestAabbAgainstAabb(b3Float4ConstArg aabbMin1,b3Float4ConstArg aab return overlap; } -#endif //B3_AABB_H +#endif //B3_AABB_H diff --git a/src/Bullet3Collision/NarrowPhaseCollision/b3Config.h b/src/Bullet3Collision/NarrowPhaseCollision/b3Config.h index 65d4a2161..518da89c5 100644 --- a/src/Bullet3Collision/NarrowPhaseCollision/b3Config.h +++ b/src/Bullet3Collision/NarrowPhaseCollision/b3Config.h @@ -1,41 +1,39 @@ #ifndef B3_CONFIG_H #define B3_CONFIG_H -struct b3Config +struct b3Config { - int m_maxConvexBodies; - int m_maxConvexShapes; - int m_maxBroadphasePairs; + int m_maxConvexBodies; + int m_maxConvexShapes; + int m_maxBroadphasePairs; int m_maxContactCapacity; int m_compoundPairCapacity; int m_maxVerticesPerFace; int m_maxFacesPerShape; - int m_maxConvexVertices; + int m_maxConvexVertices; int m_maxConvexIndices; int m_maxConvexUniqueEdges; - - int m_maxCompoundChildShapes; - + + int m_maxCompoundChildShapes; + int m_maxTriConvexPairCapacity; b3Config() - :m_maxConvexBodies(128*1024), - m_maxVerticesPerFace(64), - m_maxFacesPerShape(12), - m_maxConvexVertices(8192), - m_maxConvexIndices(81920), - m_maxConvexUniqueEdges(8192), - m_maxCompoundChildShapes(8192), - m_maxTriConvexPairCapacity(256*1024) + : m_maxConvexBodies(128 * 1024), + m_maxVerticesPerFace(64), + m_maxFacesPerShape(12), + m_maxConvexVertices(8192), + m_maxConvexIndices(81920), + m_maxConvexUniqueEdges(8192), + m_maxCompoundChildShapes(8192), + m_maxTriConvexPairCapacity(256 * 1024) { m_maxConvexShapes = m_maxConvexBodies; - m_maxBroadphasePairs = 16*m_maxConvexBodies; + m_maxBroadphasePairs = 16 * m_maxConvexBodies; m_maxContactCapacity = m_maxBroadphasePairs; - m_compoundPairCapacity = 1024*1024; + m_compoundPairCapacity = 1024 * 1024; } }; - -#endif//B3_CONFIG_H - +#endif //B3_CONFIG_H diff --git a/src/Bullet3Collision/NarrowPhaseCollision/b3Contact4.h b/src/Bullet3Collision/NarrowPhaseCollision/b3Contact4.h index fb2516567..c2cd3c729 100644 --- a/src/Bullet3Collision/NarrowPhaseCollision/b3Contact4.h +++ b/src/Bullet3Collision/NarrowPhaseCollision/b3Contact4.h @@ -19,28 +19,37 @@ subject to the following restrictions: #include "Bullet3Common/b3Vector3.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3Contact4Data.h" -B3_ATTRIBUTE_ALIGNED16(struct) b3Contact4 : public b3Contact4Data +B3_ATTRIBUTE_ALIGNED16(struct) +b3Contact4 : public b3Contact4Data { B3_DECLARE_ALIGNED_ALLOCATOR(); - int getBodyA()const {return abs(m_bodyAPtrAndSignBit);} - int getBodyB()const {return abs(m_bodyBPtrAndSignBit);} - bool isBodyAFixed()const { return m_bodyAPtrAndSignBit<0;} - bool isBodyBFixed()const { return m_bodyBPtrAndSignBit<0;} + int getBodyA() const { return abs(m_bodyAPtrAndSignBit); } + int getBodyB() const { return abs(m_bodyBPtrAndSignBit); } + bool isBodyAFixed() const { return m_bodyAPtrAndSignBit < 0; } + bool isBodyBFixed() const { return m_bodyBPtrAndSignBit < 0; } // todo. make it safer int& getBatchIdx() { return m_batchIdx; } const int& getBatchIdx() const { return m_batchIdx; } - float getRestituitionCoeff() const { return ((float)m_restituitionCoeffCmp/(float)0xffff); } - void setRestituitionCoeff( float c ) { b3Assert( c >= 0.f && c <= 1.f ); m_restituitionCoeffCmp = (unsigned short)(c*0xffff); } - float getFrictionCoeff() const { return ((float)m_frictionCoeffCmp/(float)0xffff); } - void setFrictionCoeff( float c ) { b3Assert( c >= 0.f && c <= 1.f ); m_frictionCoeffCmp = (unsigned short)(c*0xffff); } + float getRestituitionCoeff() const { return ((float)m_restituitionCoeffCmp / (float)0xffff); } + void setRestituitionCoeff(float c) + { + b3Assert(c >= 0.f && c <= 1.f); + m_restituitionCoeffCmp = (unsigned short)(c * 0xffff); + } + float getFrictionCoeff() const { return ((float)m_frictionCoeffCmp / (float)0xffff); } + void setFrictionCoeff(float c) + { + b3Assert(c >= 0.f && c <= 1.f); + m_frictionCoeffCmp = (unsigned short)(c * 0xffff); + } //float& getNPoints() { return m_worldNormal[3]; } - int getNPoints() const { return (int) m_worldNormalOnB.w; } + int getNPoints() const { return (int)m_worldNormalOnB.w; } float getPenetration(int idx) const { return m_worldPosB[idx].w; } - bool isInvalid() const { return (getBodyA()==0 || getBodyB()==0); } + bool isInvalid() const { return (getBodyA() == 0 || getBodyB() == 0); } }; -#endif //B3_CONTACT4_H +#endif //B3_CONTACT4_H diff --git a/src/Bullet3Collision/NarrowPhaseCollision/b3ConvexUtility.cpp b/src/Bullet3Collision/NarrowPhaseCollision/b3ConvexUtility.cpp index 55706fa63..a5dab74a3 100644 --- a/src/Bullet3Collision/NarrowPhaseCollision/b3ConvexUtility.cpp +++ b/src/Bullet3Collision/NarrowPhaseCollision/b3ConvexUtility.cpp @@ -13,52 +13,42 @@ subject to the following restrictions: */ //Originally written by Erwin Coumans - #include "b3ConvexUtility.h" #include "Bullet3Geometry/b3ConvexHullComputer.h" #include "Bullet3Geometry/b3GrahamScan2dConvexHull.h" #include "Bullet3Common/b3Quaternion.h" #include "Bullet3Common/b3HashMap.h" - - - - b3ConvexUtility::~b3ConvexUtility() { } -bool b3ConvexUtility::initializePolyhedralFeatures(const b3Vector3* orgVertices, int numPoints, bool mergeCoplanarTriangles) +bool b3ConvexUtility::initializePolyhedralFeatures(const b3Vector3* orgVertices, int numPoints, bool mergeCoplanarTriangles) { - - - b3ConvexHullComputer conv; - conv.compute(&orgVertices[0].getX(), sizeof(b3Vector3),numPoints,0.f,0.f); + conv.compute(&orgVertices[0].getX(), sizeof(b3Vector3), numPoints, 0.f, 0.f); b3AlignedObjectArray faceNormals; int numFaces = conv.faces.size(); faceNormals.resize(numFaces); b3ConvexHullComputer* convexUtil = &conv; - - b3AlignedObjectArray tmpFaces; + b3AlignedObjectArray tmpFaces; tmpFaces.resize(numFaces); int numVertices = convexUtil->vertices.size(); m_vertices.resize(numVertices); - for (int p=0;pvertices[p]; } - - for (int i=0;ifaces[i]; //printf("face=%d\n",face); - const b3ConvexHullComputer::Edge* firstEdge = &convexUtil->edges[face]; - const b3ConvexHullComputer::Edge* edge = firstEdge; + const b3ConvexHullComputer::Edge* firstEdge = &convexUtil->edges[face]; + const b3ConvexHullComputer::Edge* edge = firstEdge; b3Vector3 edges[3]; int numEdges = 0; @@ -66,25 +56,23 @@ bool b3ConvexUtility::initializePolyhedralFeatures(const b3Vector3* orgVertices, do { - int src = edge->getSourceVertex(); tmpFaces[i].m_indices.push_back(src); int targ = edge->getTargetVertex(); b3Vector3 wa = convexUtil->vertices[src]; b3Vector3 wb = convexUtil->vertices[targ]; - b3Vector3 newEdge = wb-wa; + b3Vector3 newEdge = wb - wa; newEdge.normalize(); - if (numEdges<2) + if (numEdges < 2) edges[numEdges++] = newEdge; edge = edge->getNextEdgeOfFace(); - } while (edge!=firstEdge); + } while (edge != firstEdge); b3Scalar planeEq = 1e30f; - - if (numEdges==2) + if (numEdges == 2) { faceNormals[i] = edges[0].cross(edges[1]); faceNormals[i].normalize(); @@ -92,20 +80,19 @@ bool b3ConvexUtility::initializePolyhedralFeatures(const b3Vector3* orgVertices, tmpFaces[i].m_plane[1] = faceNormals[i].getY(); tmpFaces[i].m_plane[2] = faceNormals[i].getZ(); tmpFaces[i].m_plane[3] = planeEq; - } else { - b3Assert(0);//degenerate? + b3Assert(0); //degenerate? faceNormals[i].setZero(); } - for (int v=0;veq) + if (planeEq > eq) { - planeEq=eq; + planeEq = eq; } } tmpFaces[i].m_plane[3] = -planeEq; @@ -113,89 +100,86 @@ bool b3ConvexUtility::initializePolyhedralFeatures(const b3Vector3* orgVertices, //merge coplanar faces and copy them to m_polyhedron - b3Scalar faceWeldThreshold= 0.999f; + b3Scalar faceWeldThreshold = 0.999f; b3AlignedObjectArray todoFaces; - for (int i=0;i coplanarFaceGroup; - int refFace = todoFaces[todoFaces.size()-1]; + int refFace = todoFaces[todoFaces.size() - 1]; coplanarFaceGroup.push_back(refFace); b3MyFace& faceA = tmpFaces[refFace]; todoFaces.pop_back(); - b3Vector3 faceNormalA = b3MakeVector3(faceA.m_plane[0],faceA.m_plane[1],faceA.m_plane[2]); - for (int j=todoFaces.size()-1;j>=0;j--) + b3Vector3 faceNormalA = b3MakeVector3(faceA.m_plane[0], faceA.m_plane[1], faceA.m_plane[2]); + for (int j = todoFaces.size() - 1; j >= 0; j--) { int i = todoFaces[j]; b3MyFace& faceB = tmpFaces[i]; - b3Vector3 faceNormalB = b3MakeVector3(faceB.m_plane[0],faceB.m_plane[1],faceB.m_plane[2]); - if (faceNormalA.dot(faceNormalB)>faceWeldThreshold) + b3Vector3 faceNormalB = b3MakeVector3(faceB.m_plane[0], faceB.m_plane[1], faceB.m_plane[2]); + if (faceNormalA.dot(faceNormalB) > faceWeldThreshold) { coplanarFaceGroup.push_back(i); todoFaces.remove(i); } } - bool did_merge = false; - if (coplanarFaceGroup.size()>1) + if (coplanarFaceGroup.size() > 1) { //do the merge: use Graham Scan 2d convex hull b3AlignedObjectArray orgpoints; - b3Vector3 averageFaceNormal = b3MakeVector3(0,0,0); + b3Vector3 averageFaceNormal = b3MakeVector3(0, 0, 0); - for (int i=0;im_faces.push_back(tmpFaces[coplanarFaceGroup[i]]); + // m_polyhedron->m_faces.push_back(tmpFaces[coplanarFaceGroup[i]]); b3MyFace& face = tmpFaces[coplanarFaceGroup[i]]; - b3Vector3 faceNormal = b3MakeVector3(face.m_plane[0],face.m_plane[1],face.m_plane[2]); - averageFaceNormal+=faceNormal; - for (int f=0;f hull; averageFaceNormal.normalize(); - b3GrahamScanConvexHull2D(orgpoints,hull,averageFaceNormal); + b3GrahamScanConvexHull2D(orgpoints, hull, averageFaceNormal); - for (int i=0;i1e-6 || fabsf(v.getY())>1e-6 || fabsf(v.getZ())>1e-6) return false; + if (fabsf(v.getX()) > 1e-6 || fabsf(v.getY()) > 1e-6 || fabsf(v.getZ()) > 1e-6) return false; return true; } struct b3InternalVertexPair { - b3InternalVertexPair(short int v0,short int v1) - :m_v0(v0), - m_v1(v1) + b3InternalVertexPair(short int v0, short int v1) + : m_v0(v0), + m_v1(v1) { - if (m_v1>m_v0) - b3Swap(m_v0,m_v1); + if (m_v1 > m_v0) + b3Swap(m_v0, m_v1); } short int m_v0; short int m_v1; int getHash() const { - return m_v0+(m_v1<<16); + return m_v0 + (m_v1 << 16); } bool equals(const b3InternalVertexPair& other) const { - return m_v0==other.m_v0 && m_v1==other.m_v1; + return m_v0 == other.m_v0 && m_v1 == other.m_v1; } }; struct b3InternalEdge { b3InternalEdge() - :m_face0(-1), - m_face1(-1) + : m_face0(-1), + m_face1(-1) { } short int m_face0; @@ -312,23 +290,31 @@ struct b3InternalEdge #ifdef TEST_INTERNAL_OBJECTS bool b3ConvexUtility::testContainment() const { - for(int p=0;p<8;p++) + for (int p = 0; p < 8; p++) { b3Vector3 LocalPt; - if(p==0) LocalPt = m_localCenter + b3Vector3(m_extents[0], m_extents[1], m_extents[2]); - else if(p==1) LocalPt = m_localCenter + b3Vector3(m_extents[0], m_extents[1], -m_extents[2]); - else if(p==2) LocalPt = m_localCenter + b3Vector3(m_extents[0], -m_extents[1], m_extents[2]); - else if(p==3) LocalPt = m_localCenter + b3Vector3(m_extents[0], -m_extents[1], -m_extents[2]); - else if(p==4) LocalPt = m_localCenter + b3Vector3(-m_extents[0], m_extents[1], m_extents[2]); - else if(p==5) LocalPt = m_localCenter + b3Vector3(-m_extents[0], m_extents[1], -m_extents[2]); - else if(p==6) LocalPt = m_localCenter + b3Vector3(-m_extents[0], -m_extents[1], m_extents[2]); - else if(p==7) LocalPt = m_localCenter + b3Vector3(-m_extents[0], -m_extents[1], -m_extents[2]); + if (p == 0) + LocalPt = m_localCenter + b3Vector3(m_extents[0], m_extents[1], m_extents[2]); + else if (p == 1) + LocalPt = m_localCenter + b3Vector3(m_extents[0], m_extents[1], -m_extents[2]); + else if (p == 2) + LocalPt = m_localCenter + b3Vector3(m_extents[0], -m_extents[1], m_extents[2]); + else if (p == 3) + LocalPt = m_localCenter + b3Vector3(m_extents[0], -m_extents[1], -m_extents[2]); + else if (p == 4) + LocalPt = m_localCenter + b3Vector3(-m_extents[0], m_extents[1], m_extents[2]); + else if (p == 5) + LocalPt = m_localCenter + b3Vector3(-m_extents[0], m_extents[1], -m_extents[2]); + else if (p == 6) + LocalPt = m_localCenter + b3Vector3(-m_extents[0], -m_extents[1], m_extents[2]); + else if (p == 7) + LocalPt = m_localCenter + b3Vector3(-m_extents[0], -m_extents[1], -m_extents[2]); - for(int i=0;i0.0f) + if (d > 0.0f) return false; } } @@ -336,39 +322,38 @@ bool b3ConvexUtility::testContainment() const } #endif -void b3ConvexUtility::initialize() +void b3ConvexUtility::initialize() { - - b3HashMap edges; + b3HashMap edges; b3Scalar TotalArea = 0.0f; - + m_localCenter.setValue(0, 0, 0); - for(int i=0;im_face0>=0); - // b3Assert(edptr->m_face1<0); + //TBD: figure out why I added this assert + // b3Assert(edptr->m_face0>=0); + // b3Assert(edptr->m_face1<0); edptr->m_face1 = i; - } else + } + else { b3InternalEdge ed; ed.m_face0 = i; - edges.insert(vp,ed); + edges.insert(vp, ed); } } } #ifdef USE_CONNECTED_FACES - for(int i=0;im_face0>=0); - b3Assert(edptr->m_face1>=0); + b3Assert(edptr->m_face0 >= 0); + b3Assert(edptr->m_face1 >= 0); - int connectedFace = (edptr->m_face0==i)?edptr->m_face1:edptr->m_face0; + int connectedFace = (edptr->m_face0 == i) ? edptr->m_face1 : edptr->m_face0; m_faces[i].m_connectedFaces[j] = connectedFace; } } -#endif//USE_CONNECTED_FACES +#endif //USE_CONNECTED_FACES - for(int i=0;iMaxX) MaxX = pt.getX(); - if(pt.getY()MaxY) MaxY = pt.getY(); - if(pt.getZ()MaxZ) MaxZ = pt.getZ(); + if (pt.getX() < MinX) MinX = pt.getX(); + if (pt.getX() > MaxX) MaxX = pt.getX(); + if (pt.getY() < MinY) MinY = pt.getY(); + if (pt.getY() > MaxY) MaxY = pt.getY(); + if (pt.getZ() < MinZ) MinZ = pt.getZ(); + if (pt.getZ() > MaxZ) MaxZ = pt.getZ(); } - mC.setValue(MaxX+MinX, MaxY+MinY, MaxZ+MinZ); - mE.setValue(MaxX-MinX, MaxY-MinY, MaxZ-MinZ); + mC.setValue(MaxX + MinX, MaxY + MinY, MaxZ + MinZ); + mE.setValue(MaxX - MinX, MaxY - MinY, MaxZ - MinZ); - - -// const b3Scalar r = m_radius / sqrtf(2.0f); + // const b3Scalar r = m_radius / sqrtf(2.0f); const b3Scalar r = m_radius / sqrtf(3.0f); const int LargestExtent = mE.maxAxis(); - const b3Scalar Step = (mE[LargestExtent]*0.5f - r)/1024.0f; + const b3Scalar Step = (mE[LargestExtent] * 0.5f - r) / 1024.0f; m_extents[0] = m_extents[1] = m_extents[2] = r; - m_extents[LargestExtent] = mE[LargestExtent]*0.5f; + m_extents[LargestExtent] = mE[LargestExtent] * 0.5f; bool FoundBox = false; - for(int j=0;j<1024;j++) + for (int j = 0; j < 1024; j++) { - if(testContainment()) + if (testContainment()) { FoundBox = true; break; @@ -489,25 +469,25 @@ void b3ConvexUtility::initialize() m_extents[LargestExtent] -= Step; } - if(!FoundBox) + if (!FoundBox) { m_extents[0] = m_extents[1] = m_extents[2] = r; } else { // Refine the box - const b3Scalar Step = (m_radius - r)/1024.0f; - const int e0 = (1< m_indices; - b3Scalar m_plane[4]; + b3AlignedObjectArray m_indices; + b3Scalar m_plane[4]; }; -B3_ATTRIBUTE_ALIGNED16(class) b3ConvexUtility +B3_ATTRIBUTE_ALIGNED16(class) +b3ConvexUtility { - public: +public: B3_DECLARE_ALIGNED_ALLOCATOR(); - b3Vector3 m_localCenter; - b3Vector3 m_extents; - b3Vector3 mC; - b3Vector3 mE; - b3Scalar m_radius; - - b3AlignedObjectArray m_vertices; - b3AlignedObjectArray m_faces; + b3Vector3 m_localCenter; + b3Vector3 m_extents; + b3Vector3 mC; + b3Vector3 mE; + b3Scalar m_radius; + + b3AlignedObjectArray m_vertices; + b3AlignedObjectArray m_faces; b3AlignedObjectArray m_uniqueEdges; - b3ConvexUtility() { } virtual ~b3ConvexUtility(); - bool initializePolyhedralFeatures(const b3Vector3* orgVertices, int numVertices, bool mergeCoplanarTriangles=true); - - void initialize(); + bool initializePolyhedralFeatures(const b3Vector3* orgVertices, int numVertices, bool mergeCoplanarTriangles = true); + + void initialize(); bool testContainment() const; - - - }; #endif - \ No newline at end of file diff --git a/src/Bullet3Collision/NarrowPhaseCollision/b3CpuNarrowPhase.cpp b/src/Bullet3Collision/NarrowPhaseCollision/b3CpuNarrowPhase.cpp index c3134b2c6..e0b216110 100644 --- a/src/Bullet3Collision/NarrowPhaseCollision/b3CpuNarrowPhase.cpp +++ b/src/Bullet3Collision/NarrowPhaseCollision/b3CpuNarrowPhase.cpp @@ -5,15 +5,13 @@ #include "Bullet3Collision/NarrowPhaseCollision/shared/b3ConvexPolyhedronData.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3ContactConvexConvexSAT.h" - struct b3CpuNarrowPhaseInternalData { b3AlignedObjectArray m_localShapeAABBCPU; - b3AlignedObjectArray m_collidablesCPU; + b3AlignedObjectArray m_collidablesCPU; b3AlignedObjectArray m_convexData; b3Config m_config; - b3AlignedObjectArray m_convexPolyhedra; b3AlignedObjectArray m_uniqueEdges; b3AlignedObjectArray m_convexVertices; @@ -22,10 +20,9 @@ struct b3CpuNarrowPhaseInternalData b3AlignedObjectArray m_contacts; - int m_numAcceleratedShapes; + int m_numAcceleratedShapes; }; - const b3AlignedObjectArray& b3CpuNarrowPhase::getContacts() const { return m_data->m_contacts; @@ -41,7 +38,6 @@ const b3Collidable& b3CpuNarrowPhase::getCollidableCpu(int collidableIndex) cons return m_data->m_collidablesCPU[collidableIndex]; } - b3CpuNarrowPhase::b3CpuNarrowPhase(const struct b3Config& config) { m_data = new b3CpuNarrowPhaseInternalData; @@ -61,7 +57,7 @@ void b3CpuNarrowPhase::computeContacts(b3AlignedObjectArray& pairs, b3Al int maxContactCapacity = m_data->m_config.m_maxContactCapacity; m_data->m_contacts.resize(maxContactCapacity); - for (int i=0;i& pairs, b3Al if (m_data->m_collidablesCPU[collidableIndexA].m_shapeType == SHAPE_SPHERE && m_data->m_collidablesCPU[collidableIndexB].m_shapeType == SHAPE_CONVEX_HULL) { -// computeContactSphereConvex(i,bodyIndexA,bodyIndexB,collidableIndexA,collidableIndexB,&bodies[0], -// &m_data->m_collidablesCPU[0],&hostConvexData[0],&hostVertices[0],&hostIndices[0],&hostFaces[0],&hostContacts[0],nContacts,maxContactCapacity); + // computeContactSphereConvex(i,bodyIndexA,bodyIndexB,collidableIndexA,collidableIndexB,&bodies[0], + // &m_data->m_collidablesCPU[0],&hostConvexData[0],&hostVertices[0],&hostIndices[0],&hostFaces[0],&hostContacts[0],nContacts,maxContactCapacity); } if (m_data->m_collidablesCPU[collidableIndexA].m_shapeType == SHAPE_CONVEX_HULL && m_data->m_collidablesCPU[collidableIndexB].m_shapeType == SHAPE_SPHERE) { -// computeContactSphereConvex(i,bodyIndexB,bodyIndexA,collidableIndexB,collidableIndexA,&bodies[0], -// &m_data->m_collidablesCPU[0],&hostConvexData[0],&hostVertices[0],&hostIndices[0],&hostFaces[0],&hostContacts[0],nContacts,maxContactCapacity); + // computeContactSphereConvex(i,bodyIndexB,bodyIndexA,collidableIndexB,collidableIndexA,&bodies[0], + // &m_data->m_collidablesCPU[0],&hostConvexData[0],&hostVertices[0],&hostIndices[0],&hostFaces[0],&hostContacts[0],nContacts,maxContactCapacity); //printf("convex-sphere\n"); - } if (m_data->m_collidablesCPU[collidableIndexA].m_shapeType == SHAPE_CONVEX_HULL && m_data->m_collidablesCPU[collidableIndexB].m_shapeType == SHAPE_PLANE) { -// computeContactPlaneConvex(i,bodyIndexB,bodyIndexA,collidableIndexB,collidableIndexA,&bodies[0], -// &m_data->m_collidablesCPU[0],&hostConvexData[0],&hostVertices[0],&hostIndices[0],&hostFaces[0],&hostContacts[0],nContacts,maxContactCapacity); -// printf("convex-plane\n"); - + // computeContactPlaneConvex(i,bodyIndexB,bodyIndexA,collidableIndexB,collidableIndexA,&bodies[0], + // &m_data->m_collidablesCPU[0],&hostConvexData[0],&hostVertices[0],&hostIndices[0],&hostFaces[0],&hostContacts[0],nContacts,maxContactCapacity); + // printf("convex-plane\n"); } if (m_data->m_collidablesCPU[collidableIndexA].m_shapeType == SHAPE_PLANE && m_data->m_collidablesCPU[collidableIndexB].m_shapeType == SHAPE_CONVEX_HULL) { -// computeContactPlaneConvex(i,bodyIndexA,bodyIndexB,collidableIndexA,collidableIndexB,&bodies[0], -// &m_data->m_collidablesCPU[0],&hostConvexData[0],&hostVertices[0],&hostIndices[0],&hostFaces[0],&hostContacts[0],nContacts,maxContactCapacity); -// printf("plane-convex\n"); - + // computeContactPlaneConvex(i,bodyIndexA,bodyIndexB,collidableIndexA,collidableIndexB,&bodies[0], + // &m_data->m_collidablesCPU[0],&hostConvexData[0],&hostVertices[0],&hostIndices[0],&hostFaces[0],&hostContacts[0],nContacts,maxContactCapacity); + // printf("plane-convex\n"); } - if (m_data->m_collidablesCPU[collidableIndexA].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS && + if (m_data->m_collidablesCPU[collidableIndexA].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS && m_data->m_collidablesCPU[collidableIndexB].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS) { -// computeContactCompoundCompound(i,bodyIndexB,bodyIndexA,collidableIndexB,collidableIndexA,&bodies[0], -// &m_data->m_collidablesCPU[0],&hostConvexData[0],&cpuChildShapes[0], hostAabbsWorldSpace,hostAabbsLocalSpace,hostVertices,hostUniqueEdges,hostIndices,hostFaces,&hostContacts[0], -// nContacts,maxContactCapacity,treeNodesCPU,subTreesCPU,bvhInfoCPU); -// printf("convex-plane\n"); - + // computeContactCompoundCompound(i,bodyIndexB,bodyIndexA,collidableIndexB,collidableIndexA,&bodies[0], + // &m_data->m_collidablesCPU[0],&hostConvexData[0],&cpuChildShapes[0], hostAabbsWorldSpace,hostAabbsLocalSpace,hostVertices,hostUniqueEdges,hostIndices,hostFaces,&hostContacts[0], + // nContacts,maxContactCapacity,treeNodesCPU,subTreesCPU,bvhInfoCPU); + // printf("convex-plane\n"); } - - if (m_data->m_collidablesCPU[collidableIndexA].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS && + if (m_data->m_collidablesCPU[collidableIndexA].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS && m_data->m_collidablesCPU[collidableIndexB].m_shapeType == SHAPE_PLANE) { -// computeContactPlaneCompound(i,bodyIndexB,bodyIndexA,collidableIndexB,collidableIndexA,&bodies[0], -// &m_data->m_collidablesCPU[0],&hostConvexData[0],&cpuChildShapes[0], &hostVertices[0],&hostIndices[0],&hostFaces[0],&hostContacts[0],nContacts,maxContactCapacity); -// printf("convex-plane\n"); - + // computeContactPlaneCompound(i,bodyIndexB,bodyIndexA,collidableIndexB,collidableIndexA,&bodies[0], + // &m_data->m_collidablesCPU[0],&hostConvexData[0],&cpuChildShapes[0], &hostVertices[0],&hostIndices[0],&hostFaces[0],&hostContacts[0],nContacts,maxContactCapacity); + // printf("convex-plane\n"); } if (m_data->m_collidablesCPU[collidableIndexA].m_shapeType == SHAPE_PLANE && m_data->m_collidablesCPU[collidableIndexB].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS) { -// computeContactPlaneCompound(i,bodyIndexA,bodyIndexB,collidableIndexA,collidableIndexB,&bodies[0], -// &m_data->m_collidablesCPU[0],&hostConvexData[0],&cpuChildShapes[0],&hostVertices[0],&hostIndices[0],&hostFaces[0],&hostContacts[0],nContacts,maxContactCapacity); -// printf("plane-convex\n"); - + // computeContactPlaneCompound(i,bodyIndexA,bodyIndexB,collidableIndexA,collidableIndexB,&bodies[0], + // &m_data->m_collidablesCPU[0],&hostConvexData[0],&cpuChildShapes[0],&hostVertices[0],&hostIndices[0],&hostFaces[0],&hostContacts[0],nContacts,maxContactCapacity); + // printf("plane-convex\n"); } if (m_data->m_collidablesCPU[collidableIndexA].m_shapeType == SHAPE_CONVEX_HULL && @@ -137,54 +126,48 @@ void b3CpuNarrowPhase::computeContacts(b3AlignedObjectArray& pairs, b3Al //printf("pairs[i].z=%d\n",pairs[i].z); //int contactIndex = computeContactConvexConvex2(i,bodyIndexA,bodyIndexB,collidableIndexA,collidableIndexB,bodies, // m_data->m_collidablesCPU,hostConvexData,hostVertices,hostUniqueEdges,hostIndices,hostFaces,hostContacts,nContacts,maxContactCapacity,oldHostContacts); - int contactIndex = b3ContactConvexConvexSAT(i,bodyIndexA,bodyIndexB,collidableIndexA,collidableIndexB,bodies, - m_data->m_collidablesCPU,m_data->m_convexPolyhedra,m_data->m_convexVertices,m_data->m_uniqueEdges,m_data->m_convexIndices,m_data->m_convexFaces,m_data->m_contacts,numContacts,maxContactCapacity); + int contactIndex = b3ContactConvexConvexSAT(i, bodyIndexA, bodyIndexB, collidableIndexA, collidableIndexB, bodies, + m_data->m_collidablesCPU, m_data->m_convexPolyhedra, m_data->m_convexVertices, m_data->m_uniqueEdges, m_data->m_convexIndices, m_data->m_convexFaces, m_data->m_contacts, numContacts, maxContactCapacity); - - if (contactIndex>=0) + if (contactIndex >= 0) { pairs[i].z = contactIndex; } -// printf("plane-convex\n"); - + // printf("plane-convex\n"); } - - } m_data->m_contacts.resize(numContacts); } -int b3CpuNarrowPhase::registerConvexHullShape(b3ConvexUtility* utilPtr) +int b3CpuNarrowPhase::registerConvexHullShape(b3ConvexUtility* utilPtr) { int collidableIndex = allocateCollidable(); - if (collidableIndex<0) + if (collidableIndex < 0) return collidableIndex; - b3Collidable& col = m_data->m_collidablesCPU[collidableIndex]; col.m_shapeType = SHAPE_CONVEX_HULL; col.m_shapeIndex = -1; - - + { - b3Vector3 localCenter=b3MakeVector3(0,0,0); - for (int i=0;im_vertices.size();i++) - localCenter+=utilPtr->m_vertices[i]; - localCenter*= (1.f/utilPtr->m_vertices.size()); + b3Vector3 localCenter = b3MakeVector3(0, 0, 0); + for (int i = 0; i < utilPtr->m_vertices.size(); i++) + localCenter += utilPtr->m_vertices[i]; + localCenter *= (1.f / utilPtr->m_vertices.size()); utilPtr->m_localCenter = localCenter; - col.m_shapeIndex = registerConvexHullShapeInternal(utilPtr,col); + col.m_shapeIndex = registerConvexHullShapeInternal(utilPtr, col); } - if (col.m_shapeIndex>=0) + if (col.m_shapeIndex >= 0) { b3Aabb aabb; - - b3Vector3 myAabbMin=b3MakeVector3(1e30f,1e30f,1e30f); - b3Vector3 myAabbMax=b3MakeVector3(-1e30f,-1e30f,-1e30f); - for (int i=0;im_vertices.size();i++) + b3Vector3 myAabbMin = b3MakeVector3(1e30f, 1e30f, 1e30f); + b3Vector3 myAabbMax = b3MakeVector3(-1e30f, -1e30f, -1e30f); + + for (int i = 0; i < utilPtr->m_vertices.size(); i++) { myAabbMin.setMin(utilPtr->m_vertices[i]); myAabbMax.setMax(utilPtr->m_vertices[i]); @@ -200,44 +183,42 @@ int b3CpuNarrowPhase::registerConvexHullShape(b3ConvexUtility* utilPtr) aabb.m_signedMaxIndices[3] = 0; m_data->m_localShapeAABBCPU.push_back(aabb); - } - + return collidableIndex; } -int b3CpuNarrowPhase::allocateCollidable() +int b3CpuNarrowPhase::allocateCollidable() { int curSize = m_data->m_collidablesCPU.size(); - if (curSizem_config.m_maxConvexShapes) + if (curSize < m_data->m_config.m_maxConvexShapes) { m_data->m_collidablesCPU.expand(); return curSize; } else { - b3Error("allocateCollidable out-of-range %d\n",m_data->m_config.m_maxConvexShapes); + b3Error("allocateCollidable out-of-range %d\n", m_data->m_config.m_maxConvexShapes); } return -1; - } -int b3CpuNarrowPhase::registerConvexHullShape(const float* vertices, int strideInBytes, int numVertices, const float* scaling) +int b3CpuNarrowPhase::registerConvexHullShape(const float* vertices, int strideInBytes, int numVertices, const float* scaling) { b3AlignedObjectArray verts; - unsigned char* vts = (unsigned char*) vertices; - for (int i=0;iinitializePolyhedralFeatures(&verts[0],verts.size(),merge); + utilPtr->initializePolyhedralFeatures(&verts[0], verts.size(), merge); } int collidableIndex = registerConvexHullShape(utilPtr); @@ -246,74 +227,67 @@ int b3CpuNarrowPhase::registerConvexHullShape(const float* vertices, int strideI return collidableIndex; } - -int b3CpuNarrowPhase::registerConvexHullShapeInternal(b3ConvexUtility* convexPtr,b3Collidable& col) +int b3CpuNarrowPhase::registerConvexHullShapeInternal(b3ConvexUtility* convexPtr, b3Collidable& col) { + m_data->m_convexData.resize(m_data->m_numAcceleratedShapes + 1); + m_data->m_convexPolyhedra.resize(m_data->m_numAcceleratedShapes + 1); - m_data->m_convexData.resize(m_data->m_numAcceleratedShapes+1); - m_data->m_convexPolyhedra.resize(m_data->m_numAcceleratedShapes+1); - - - b3ConvexPolyhedronData& convex = m_data->m_convexPolyhedra.at(m_data->m_convexPolyhedra.size()-1); + b3ConvexPolyhedronData& convex = m_data->m_convexPolyhedra.at(m_data->m_convexPolyhedra.size() - 1); convex.mC = convexPtr->mC; convex.mE = convexPtr->mE; - convex.m_extents= convexPtr->m_extents; + convex.m_extents = convexPtr->m_extents; convex.m_localCenter = convexPtr->m_localCenter; convex.m_radius = convexPtr->m_radius; - + convex.m_numUniqueEdges = convexPtr->m_uniqueEdges.size(); int edgeOffset = m_data->m_uniqueEdges.size(); convex.m_uniqueEdgesOffset = edgeOffset; - - m_data->m_uniqueEdges.resize(edgeOffset+convex.m_numUniqueEdges); - + + m_data->m_uniqueEdges.resize(edgeOffset + convex.m_numUniqueEdges); + //convex data here int i; - for ( i=0;im_uniqueEdges.size();i++) + for (i = 0; i < convexPtr->m_uniqueEdges.size(); i++) { - m_data->m_uniqueEdges[edgeOffset+i] = convexPtr->m_uniqueEdges[i]; + m_data->m_uniqueEdges[edgeOffset + i] = convexPtr->m_uniqueEdges[i]; } - + int faceOffset = m_data->m_convexFaces.size(); convex.m_faceOffset = faceOffset; convex.m_numFaces = convexPtr->m_faces.size(); - m_data->m_convexFaces.resize(faceOffset+convex.m_numFaces); - + m_data->m_convexFaces.resize(faceOffset + convex.m_numFaces); - for (i=0;im_faces.size();i++) + for (i = 0; i < convexPtr->m_faces.size(); i++) { - m_data->m_convexFaces[convex.m_faceOffset+i].m_plane = b3MakeVector3(convexPtr->m_faces[i].m_plane[0], - convexPtr->m_faces[i].m_plane[1], - convexPtr->m_faces[i].m_plane[2], - convexPtr->m_faces[i].m_plane[3]); + m_data->m_convexFaces[convex.m_faceOffset + i].m_plane = b3MakeVector3(convexPtr->m_faces[i].m_plane[0], + convexPtr->m_faces[i].m_plane[1], + convexPtr->m_faces[i].m_plane[2], + convexPtr->m_faces[i].m_plane[3]); - int indexOffset = m_data->m_convexIndices.size(); int numIndices = convexPtr->m_faces[i].m_indices.size(); - m_data->m_convexFaces[convex.m_faceOffset+i].m_numIndices = numIndices; - m_data->m_convexFaces[convex.m_faceOffset+i].m_indexOffset = indexOffset; - m_data->m_convexIndices.resize(indexOffset+numIndices); - for (int p=0;pm_convexFaces[convex.m_faceOffset + i].m_numIndices = numIndices; + m_data->m_convexFaces[convex.m_faceOffset + i].m_indexOffset = indexOffset; + m_data->m_convexIndices.resize(indexOffset + numIndices); + for (int p = 0; p < numIndices; p++) { - m_data->m_convexIndices[indexOffset+p] = convexPtr->m_faces[i].m_indices[p]; + m_data->m_convexIndices[indexOffset + p] = convexPtr->m_faces[i].m_indices[p]; } } - + convex.m_numVertices = convexPtr->m_vertices.size(); int vertexOffset = m_data->m_convexVertices.size(); - convex.m_vertexOffset =vertexOffset; - - m_data->m_convexVertices.resize(vertexOffset+convex.m_numVertices); - for (int i=0;im_vertices.size();i++) + convex.m_vertexOffset = vertexOffset; + + m_data->m_convexVertices.resize(vertexOffset + convex.m_numVertices); + for (int i = 0; i < convexPtr->m_vertices.size(); i++) { - m_data->m_convexVertices[vertexOffset+i] = convexPtr->m_vertices[i]; + m_data->m_convexVertices[vertexOffset + i] = convexPtr->m_vertices[i]; } (m_data->m_convexData)[m_data->m_numAcceleratedShapes] = convexPtr; - - - + return m_data->m_numAcceleratedShapes++; } diff --git a/src/Bullet3Collision/NarrowPhaseCollision/b3CpuNarrowPhase.h b/src/Bullet3Collision/NarrowPhaseCollision/b3CpuNarrowPhase.h index 528be3346..f02353c26 100644 --- a/src/Bullet3Collision/NarrowPhaseCollision/b3CpuNarrowPhase.h +++ b/src/Bullet3Collision/NarrowPhaseCollision/b3CpuNarrowPhase.h @@ -12,66 +12,55 @@ class b3CpuNarrowPhase { protected: - - struct b3CpuNarrowPhaseInternalData* m_data; + struct b3CpuNarrowPhaseInternalData* m_data; int m_acceleratedCompanionShapeIndex; int m_planeBodyIndex; - int m_static0Index; + int m_static0Index; - int registerConvexHullShapeInternal(class b3ConvexUtility* convexPtr,b3Collidable& col); + int registerConvexHullShapeInternal(class b3ConvexUtility* convexPtr, b3Collidable& col); int registerConcaveMeshShape(b3AlignedObjectArray* vertices, b3AlignedObjectArray* indices, b3Collidable& col, const float* scaling); public: - - - - b3CpuNarrowPhase(const struct b3Config& config); virtual ~b3CpuNarrowPhase(void); - int registerSphereShape(float radius); - int registerPlaneShape(const b3Vector3& planeNormal, float planeConstant); + int registerSphereShape(float radius); + int registerPlaneShape(const b3Vector3& planeNormal, float planeConstant); int registerCompoundShape(b3AlignedObjectArray* childShapes); int registerFace(const b3Vector3& faceNormal, float faceConstant); - - int registerConcaveMesh(b3AlignedObjectArray* vertices, b3AlignedObjectArray* indices,const float* scaling); - + + int registerConcaveMesh(b3AlignedObjectArray* vertices, b3AlignedObjectArray* indices, const float* scaling); + //do they need to be merged? - - int registerConvexHullShape(b3ConvexUtility* utilPtr); - int registerConvexHullShape(const float* vertices, int strideInBytes, int numVertices, const float* scaling); + + int registerConvexHullShape(b3ConvexUtility* utilPtr); + int registerConvexHullShape(const float* vertices, int strideInBytes, int numVertices, const float* scaling); //int registerRigidBody(int collidableIndex, float mass, const float* position, const float* orientation, const float* aabbMin, const float* aabbMax,bool writeToGpu); - void setObjectTransform(const float* position, const float* orientation , int bodyIndex); + void setObjectTransform(const float* position, const float* orientation, int bodyIndex); - void writeAllBodiesToGpu(); - void reset(); - void readbackAllBodiesToCpu(); - bool getObjectTransformFromCpu(float* position, float* orientation , int bodyIndex) const; + void writeAllBodiesToGpu(); + void reset(); + void readbackAllBodiesToCpu(); + bool getObjectTransformFromCpu(float* position, float* orientation, int bodyIndex) const; - void setObjectTransformCpu(float* position, float* orientation , int bodyIndex); + void setObjectTransformCpu(float* position, float* orientation, int bodyIndex); void setObjectVelocityCpu(float* linVel, float* angVel, int bodyIndex); - //virtual void computeContacts(cl_mem broadphasePairs, int numBroadphasePairs, cl_mem aabbsWorldSpace, int numObjects); virtual void computeContacts(b3AlignedObjectArray& pairs, b3AlignedObjectArray& aabbsWorldSpace, b3AlignedObjectArray& bodies); - - const struct b3RigidBodyData* getBodiesCpu() const; //struct b3RigidBodyData* getBodiesCpu(); - int getNumBodiesGpu() const; + int getNumBodiesGpu() const; - - int getNumBodyInertiasGpu() const; + int getNumBodyInertiasGpu() const; - const struct b3Collidable* getCollidablesCpu() const; - int getNumCollidablesGpu() const; - + int getNumCollidablesGpu() const; /*const struct b3Contact4* getContactsCPU() const; @@ -80,8 +69,7 @@ public: */ const b3AlignedObjectArray& getContacts() const; - - + int getNumRigidBodies() const; int allocateCollidable(); @@ -93,13 +81,12 @@ public: b3Collidable& getCollidableCpu(int collidableIndex); const b3Collidable& getCollidableCpu(int collidableIndex) const; - const b3CpuNarrowPhaseInternalData* getInternalData() const + const b3CpuNarrowPhaseInternalData* getInternalData() const { - return m_data; + return m_data; } const struct b3Aabb& getLocalSpaceAabb(int collidableIndex) const; }; -#endif //B3_CPU_NARROWPHASE_H - +#endif //B3_CPU_NARROWPHASE_H diff --git a/src/Bullet3Collision/NarrowPhaseCollision/b3RaycastInfo.h b/src/Bullet3Collision/NarrowPhaseCollision/b3RaycastInfo.h index fba8bd07a..b50c0eca4 100644 --- a/src/Bullet3Collision/NarrowPhaseCollision/b3RaycastInfo.h +++ b/src/Bullet3Collision/NarrowPhaseCollision/b3RaycastInfo.h @@ -4,21 +4,22 @@ #include "Bullet3Common/b3Vector3.h" -B3_ATTRIBUTE_ALIGNED16(struct) b3RayInfo +B3_ATTRIBUTE_ALIGNED16(struct) +b3RayInfo { b3Vector3 m_from; b3Vector3 m_to; }; -B3_ATTRIBUTE_ALIGNED16(struct) b3RayHit +B3_ATTRIBUTE_ALIGNED16(struct) +b3RayHit { - b3Scalar m_hitFraction; - int m_hitBody; - int m_hitResult1; - int m_hitResult2; - b3Vector3 m_hitPoint; - b3Vector3 m_hitNormal; + b3Scalar m_hitFraction; + int m_hitBody; + int m_hitResult1; + int m_hitResult2; + b3Vector3 m_hitPoint; + b3Vector3 m_hitNormal; }; -#endif //B3_RAYCAST_INFO_H - +#endif //B3_RAYCAST_INFO_H diff --git a/src/Bullet3Collision/NarrowPhaseCollision/b3RigidBodyCL.h b/src/Bullet3Collision/NarrowPhaseCollision/b3RigidBodyCL.h index d58f71802..be1be57f0 100644 --- a/src/Bullet3Collision/NarrowPhaseCollision/b3RigidBodyCL.h +++ b/src/Bullet3Collision/NarrowPhaseCollision/b3RigidBodyCL.h @@ -20,11 +20,9 @@ subject to the following restrictions: #include "Bullet3Common/b3Matrix3x3.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3RigidBodyData.h" - -inline float b3GetInvMass(const b3RigidBodyData& body) +inline float b3GetInvMass(const b3RigidBodyData& body) { - return body.m_invMass; + return body.m_invMass; } - -#endif//B3_RIGID_BODY_CL +#endif //B3_RIGID_BODY_CL diff --git a/src/Bullet3Collision/NarrowPhaseCollision/shared/b3BvhSubtreeInfoData.h b/src/Bullet3Collision/NarrowPhaseCollision/shared/b3BvhSubtreeInfoData.h index 8788ccbb4..d6beb662b 100644 --- a/src/Bullet3Collision/NarrowPhaseCollision/shared/b3BvhSubtreeInfoData.h +++ b/src/Bullet3Collision/NarrowPhaseCollision/shared/b3BvhSubtreeInfoData.h @@ -7,14 +7,13 @@ typedef struct b3BvhSubtreeInfoData b3BvhSubtreeInfoData_t; struct b3BvhSubtreeInfoData { //12 bytes - unsigned short int m_quantizedAabbMin[3]; - unsigned short int m_quantizedAabbMax[3]; + unsigned short int m_quantizedAabbMin[3]; + unsigned short int m_quantizedAabbMax[3]; //4 bytes, points to the root of the subtree - int m_rootNodeIndex; + int m_rootNodeIndex; //4 bytes - int m_subtreeSize; - int m_padding[3]; + int m_subtreeSize; + int m_padding[3]; }; -#endif //B3_BVH_SUBTREE_INFO_DATA_H - +#endif //B3_BVH_SUBTREE_INFO_DATA_H diff --git a/src/Bullet3Collision/NarrowPhaseCollision/shared/b3BvhTraversal.h b/src/Bullet3Collision/NarrowPhaseCollision/shared/b3BvhTraversal.h index 2618da24b..7c2507cc9 100644 --- a/src/Bullet3Collision/NarrowPhaseCollision/shared/b3BvhTraversal.h +++ b/src/Bullet3Collision/NarrowPhaseCollision/shared/b3BvhTraversal.h @@ -7,69 +7,64 @@ #include "Bullet3Collision/NarrowPhaseCollision/shared/b3BvhSubtreeInfoData.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3QuantizedBvhNodeData.h" - - // work-in-progress -void b3BvhTraversal( __global const b3Int4* pairs, - __global const b3RigidBodyData* rigidBodies, - __global const b3Collidable* collidables, - __global b3Aabb* aabbs, - __global b3Int4* concavePairsOut, - __global volatile int* numConcavePairsOut, - __global const b3BvhSubtreeInfo* subtreeHeadersRoot, - __global const b3QuantizedBvhNode* quantizedNodesRoot, - __global const b3BvhInfo* bvhInfos, - int numPairs, - int maxNumConcavePairsCapacity, - int id) +void b3BvhTraversal(__global const b3Int4* pairs, + __global const b3RigidBodyData* rigidBodies, + __global const b3Collidable* collidables, + __global b3Aabb* aabbs, + __global b3Int4* concavePairsOut, + __global volatile int* numConcavePairsOut, + __global const b3BvhSubtreeInfo* subtreeHeadersRoot, + __global const b3QuantizedBvhNode* quantizedNodesRoot, + __global const b3BvhInfo* bvhInfos, + int numPairs, + int maxNumConcavePairsCapacity, + int id) { - int bodyIndexA = pairs[id].x; int bodyIndexB = pairs[id].y; int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx; int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx; - + //once the broadphase avoids static-static pairs, we can remove this test - if ((rigidBodies[bodyIndexA].m_invMass==0) &&(rigidBodies[bodyIndexB].m_invMass==0)) + if ((rigidBodies[bodyIndexA].m_invMass == 0) && (rigidBodies[bodyIndexB].m_invMass == 0)) { return; } - - if (collidables[collidableIndexA].m_shapeType!=SHAPE_CONCAVE_TRIMESH) + + if (collidables[collidableIndexA].m_shapeType != SHAPE_CONCAVE_TRIMESH) return; int shapeTypeB = collidables[collidableIndexB].m_shapeType; - - if (shapeTypeB!=SHAPE_CONVEX_HULL && - shapeTypeB!=SHAPE_SPHERE && - shapeTypeB!=SHAPE_COMPOUND_OF_CONVEX_HULLS - ) + + if (shapeTypeB != SHAPE_CONVEX_HULL && + shapeTypeB != SHAPE_SPHERE && + shapeTypeB != SHAPE_COMPOUND_OF_CONVEX_HULLS) return; b3BvhInfo bvhInfo = bvhInfos[collidables[collidableIndexA].m_numChildShapes]; - b3Float4 bvhAabbMin = bvhInfo.m_aabbMin; - b3Float4 bvhAabbMax = bvhInfo.m_aabbMax; - b3Float4 bvhQuantization = bvhInfo.m_quantization; + b3Float4 bvhAabbMin = bvhInfo.m_aabbMin; + b3Float4 bvhAabbMax = bvhInfo.m_aabbMax; + b3Float4 bvhQuantization = bvhInfo.m_quantization; int numSubtreeHeaders = bvhInfo.m_numSubTrees; __global const b3BvhSubtreeInfoData* subtreeHeaders = &subtreeHeadersRoot[bvhInfo.m_subTreeOffset]; __global const b3QuantizedBvhNodeData* quantizedNodes = &quantizedNodesRoot[bvhInfo.m_nodeOffset]; - unsigned short int quantizedQueryAabbMin[3]; unsigned short int quantizedQueryAabbMax[3]; - b3QuantizeWithClamp(quantizedQueryAabbMin,aabbs[bodyIndexB].m_minVec,false,bvhAabbMin, bvhAabbMax,bvhQuantization); - b3QuantizeWithClamp(quantizedQueryAabbMax,aabbs[bodyIndexB].m_maxVec,true ,bvhAabbMin, bvhAabbMax,bvhQuantization); - - for (int i=0;i= 0, so output intersection - ppVtxOut[numVertsOut++] = b3Lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) ); + ppVtxOut[numVertsOut++] = b3Lerp3(firstVertex, endVertex, (ds * 1.f / (ds - de))); } } else { - if (de<0) + if (de < 0) { // Start >= 0, end < 0 so output intersection and end - ppVtxOut[numVertsOut++] = b3Lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) ); + ppVtxOut[numVertsOut++] = b3Lerp3(firstVertex, endVertex, (ds * 1.f / (ds - de))); ppVtxOut[numVertsOut++] = endVertex; } } @@ -67,90 +64,81 @@ int clipFaceGlobal(__global const b3Float4* pVtxIn, int numVertsIn, b3Float4Cons return numVertsOut; } - -__kernel void clipFacesAndFindContactsKernel( __global const b3Float4* separatingNormals, - __global const int* hasSeparatingAxis, - __global b3Int4* clippingFacesOut, - __global b3Float4* worldVertsA1, - __global b3Float4* worldNormalsA1, - __global b3Float4* worldVertsB1, - __global b3Float4* worldVertsB2, - int vertexFaceCapacity, - int pairIndex - ) +__kernel void clipFacesAndFindContactsKernel(__global const b3Float4* separatingNormals, + __global const int* hasSeparatingAxis, + __global b3Int4* clippingFacesOut, + __global b3Float4* worldVertsA1, + __global b3Float4* worldNormalsA1, + __global b3Float4* worldVertsB1, + __global b3Float4* worldVertsB2, + int vertexFaceCapacity, + int pairIndex) { -// int i = get_global_id(0); + // int i = get_global_id(0); //int pairIndex = i; int i = pairIndex; - + float minDist = -1e30f; float maxDist = 0.02f; - -// if (i=0) - { - - - - // clip polygon to back of planes of all faces of hull A that are adjacent to witness face - - for(int e0=0;e0= 0) + { + // clip polygon to back of planes of all faces of hull A that are adjacent to witness face + + for (int e0 = 0; e0 < numVertsInA; e0++) + { + const b3Float4 aw = worldVertsA1[pairIndex * capacityWorldVertsB2 + e0]; + const b3Float4 bw = worldVertsA1[pairIndex * capacityWorldVertsB2 + ((e0 + 1) % numVertsInA)]; + const b3Float4 WorldEdge0 = aw - bw; + b3Float4 worldPlaneAnormal1 = worldNormalsA1[pairIndex]; + b3Float4 planeNormalWS1 = -b3Cross(WorldEdge0, worldPlaneAnormal1); + b3Float4 worldA1 = aw; + float planeEqWS1 = -b3Dot(worldA1, planeNormalWS1); + b3Float4 planeNormalWS = planeNormalWS1; + float planeEqWS = planeEqWS1; + numVertsOut = clipFaceGlobal(pVtxIn, numVertsInB, planeNormalWS, planeEqWS, pVtxOut); + __global b3Float4* tmp = pVtxOut; + pVtxOut = pVtxIn; + pVtxIn = tmp; + numVertsInB = numVertsOut; + numVertsOut = 0; + } + + b3Float4 planeNormalWS = worldNormalsA1[pairIndex]; + float planeEqWS = -b3Dot(planeNormalWS, worldVertsA1[pairIndex * capacityWorldVertsB2]); + + for (int i = 0; i < numVertsInB; i++) + { + float depth = b3Dot(planeNormalWS, pVtxIn[i]) + planeEqWS; + if (depth <= minDist) + { + depth = minDist; + } + /* static float maxDepth = 0.f; if (depth < maxDepth) { @@ -163,26 +151,21 @@ __kernel void clipFacesAndFindContactsKernel( __global const b3Float4* sepa } */ - if (depth <=maxDist) - { - b3Float4 pointInWorld = pVtxIn[i]; - pVtxOut[numLocalContactsOut++] = b3MakeFloat4(pointInWorld.x,pointInWorld.y,pointInWorld.z,depth); - } - } - - } - clippingFaces[pairIndex].w =numLocalContactsOut; - + if (depth <= maxDist) + { + b3Float4 pointInWorld = pVtxIn[i]; + pVtxOut[numLocalContactsOut++] = b3MakeFloat4(pointInWorld.x, pointInWorld.y, pointInWorld.z, depth); + } + } + } + clippingFaces[pairIndex].w = numLocalContactsOut; + } - } - - for (int i=0;im_worldNormalOnB.w = (float)numPoints; }; - - -#endif //B3_CONTACT4DATA_H \ No newline at end of file +#endif //B3_CONTACT4DATA_H \ No newline at end of file diff --git a/src/Bullet3Collision/NarrowPhaseCollision/shared/b3ContactConvexConvexSAT.h b/src/Bullet3Collision/NarrowPhaseCollision/shared/b3ContactConvexConvexSAT.h index f295f01a6..ca68f4bc4 100644 --- a/src/Bullet3Collision/NarrowPhaseCollision/shared/b3ContactConvexConvexSAT.h +++ b/src/Bullet3Collision/NarrowPhaseCollision/shared/b3ContactConvexConvexSAT.h @@ -2,48 +2,43 @@ #ifndef B3_CONTACT_CONVEX_CONVEX_SAT_H #define B3_CONTACT_CONVEX_CONVEX_SAT_H - #include "Bullet3Collision/NarrowPhaseCollision/shared/b3Contact4Data.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3FindSeparatingAxis.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3ReduceContacts.h" #define B3_MAX_VERTS 1024 - - -inline b3Float4 b3Lerp3(const b3Float4& a,const b3Float4& b, float t) +inline b3Float4 b3Lerp3(const b3Float4& a, const b3Float4& b, float t) { - return b3MakeVector3( a.x + (b.x - a.x) * t, - a.y + (b.y - a.y) * t, - a.z + (b.z - a.z) * t, - 0.f); + return b3MakeVector3(a.x + (b.x - a.x) * t, + a.y + (b.y - a.y) * t, + a.z + (b.z - a.z) * t, + 0.f); } - // Clips a face to the back of a plane, return the number of vertices out, stored in ppVtxOut -inline int b3ClipFace(const b3Float4* pVtxIn, int numVertsIn, b3Float4& planeNormalWS,float planeEqWS, b3Float4* ppVtxOut) +inline int b3ClipFace(const b3Float4* pVtxIn, int numVertsIn, b3Float4& planeNormalWS, float planeEqWS, b3Float4* ppVtxOut) { - int ve; float ds, de; int numVertsOut = 0; if (numVertsIn < 2) return 0; - b3Float4 firstVertex=pVtxIn[numVertsIn-1]; + b3Float4 firstVertex = pVtxIn[numVertsIn - 1]; b3Float4 endVertex = pVtxIn[0]; - - ds = b3Dot3F4(planeNormalWS,firstVertex)+planeEqWS; + + ds = b3Dot3F4(planeNormalWS, firstVertex) + planeEqWS; for (ve = 0; ve < numVertsIn; ve++) { - endVertex=pVtxIn[ve]; + endVertex = pVtxIn[ve]; - de = b3Dot3F4(planeNormalWS,endVertex)+planeEqWS; + de = b3Dot3F4(planeNormalWS, endVertex) + planeEqWS; - if (ds<0) + if (ds < 0) { - if (de<0) + if (de < 0) { // Start < 0, end < 0, so output endVertex ppVtxOut[numVertsOut++] = endVertex; @@ -51,15 +46,15 @@ inline int b3ClipFace(const b3Float4* pVtxIn, int numVertsIn, b3Float4& planeNor else { // Start < 0, end >= 0, so output intersection - ppVtxOut[numVertsOut++] = b3Lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) ); + ppVtxOut[numVertsOut++] = b3Lerp3(firstVertex, endVertex, (ds * 1.f / (ds - de))); } } else { - if (de<0) + if (de < 0) { // Start >= 0, end < 0 so output intersection and end - ppVtxOut[numVertsOut++] = b3Lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) ); + ppVtxOut[numVertsOut++] = b3Lerp3(firstVertex, endVertex, (ds * 1.f / (ds - de))); ppVtxOut[numVertsOut++] = endVertex; } } @@ -69,36 +64,35 @@ inline int b3ClipFace(const b3Float4* pVtxIn, int numVertsIn, b3Float4& planeNor return numVertsOut; } - -inline int b3ClipFaceAgainstHull(const b3Float4& separatingNormal, const b3ConvexPolyhedronData* hullA, - const b3Float4& posA, const b3Quaternion& ornA, b3Float4* worldVertsB1, int numWorldVertsB1, - b3Float4* worldVertsB2, int capacityWorldVertsB2, - const float minDist, float maxDist, - const b3AlignedObjectArray& verticesA, const b3AlignedObjectArray& facesA, const b3AlignedObjectArray& indicesA, - //const b3Float4* verticesB, const b3GpuFace* facesB, const int* indicesB, - b3Float4* contactsOut, - int contactCapacity) +inline int b3ClipFaceAgainstHull(const b3Float4& separatingNormal, const b3ConvexPolyhedronData* hullA, + const b3Float4& posA, const b3Quaternion& ornA, b3Float4* worldVertsB1, int numWorldVertsB1, + b3Float4* worldVertsB2, int capacityWorldVertsB2, + const float minDist, float maxDist, + const b3AlignedObjectArray& verticesA, const b3AlignedObjectArray& facesA, const b3AlignedObjectArray& indicesA, + //const b3Float4* verticesB, const b3GpuFace* facesB, const int* indicesB, + b3Float4* contactsOut, + int contactCapacity) { int numContactsOut = 0; b3Float4* pVtxIn = worldVertsB1; b3Float4* pVtxOut = worldVertsB2; - + int numVertsIn = numWorldVertsB1; int numVertsOut = 0; - int closestFaceA=-1; + int closestFaceA = -1; { float dmin = FLT_MAX; - for(int face=0;facem_numFaces;face++) + for (int face = 0; face < hullA->m_numFaces; face++) { const b3Float4 Normal = b3MakeVector3( - facesA[hullA->m_faceOffset+face].m_plane.x, - facesA[hullA->m_faceOffset+face].m_plane.y, - facesA[hullA->m_faceOffset+face].m_plane.z,0.f); - const b3Float4 faceANormalWS = b3QuatRotate(ornA,Normal); - - float d = b3Dot3F4(faceANormalWS,separatingNormal); + facesA[hullA->m_faceOffset + face].m_plane.x, + facesA[hullA->m_faceOffset + face].m_plane.y, + facesA[hullA->m_faceOffset + face].m_plane.z, 0.f); + const b3Float4 faceANormalWS = b3QuatRotate(ornA, Normal); + + float d = b3Dot3F4(faceANormalWS, separatingNormal); if (d < dmin) { dmin = d; @@ -106,33 +100,33 @@ inline int b3ClipFaceAgainstHull(const b3Float4& separatingNormal, const b3Conve } } } - if (closestFaceA<0) + if (closestFaceA < 0) return numContactsOut; - b3GpuFace polyA = facesA[hullA->m_faceOffset+closestFaceA]; + b3GpuFace polyA = facesA[hullA->m_faceOffset + closestFaceA]; // clip polygon to back of planes of all faces of hull A that are adjacent to witness face //int numContacts = numWorldVertsB1; int numVerticesA = polyA.m_numIndices; - for(int e0=0;e0m_vertexOffset+indicesA[polyA.m_indexOffset+e0]]; - const b3Float4 b = verticesA[hullA->m_vertexOffset+indicesA[polyA.m_indexOffset+((e0+1)%numVerticesA)]]; + const b3Float4 a = verticesA[hullA->m_vertexOffset + indicesA[polyA.m_indexOffset + e0]]; + const b3Float4 b = verticesA[hullA->m_vertexOffset + indicesA[polyA.m_indexOffset + ((e0 + 1) % numVerticesA)]]; const b3Float4 edge0 = a - b; - const b3Float4 WorldEdge0 = b3QuatRotate(ornA,edge0); - b3Float4 planeNormalA = b3MakeFloat4(polyA.m_plane.x,polyA.m_plane.y,polyA.m_plane.z,0.f); - b3Float4 worldPlaneAnormal1 = b3QuatRotate(ornA,planeNormalA); + const b3Float4 WorldEdge0 = b3QuatRotate(ornA, edge0); + b3Float4 planeNormalA = b3MakeFloat4(polyA.m_plane.x, polyA.m_plane.y, polyA.m_plane.z, 0.f); + b3Float4 worldPlaneAnormal1 = b3QuatRotate(ornA, planeNormalA); + + b3Float4 planeNormalWS1 = -b3Cross3(WorldEdge0, worldPlaneAnormal1); + b3Float4 worldA1 = b3TransformPoint(a, posA, ornA); + float planeEqWS1 = -b3Dot3F4(worldA1, planeNormalWS1); - b3Float4 planeNormalWS1 = -b3Cross3(WorldEdge0,worldPlaneAnormal1); - b3Float4 worldA1 = b3TransformPoint(a,posA,ornA); - float planeEqWS1 = -b3Dot3F4(worldA1,planeNormalWS1); - b3Float4 planeNormalWS = planeNormalWS1; - float planeEqWS=planeEqWS1; - + float planeEqWS = planeEqWS1; + //clip face //clipFace(*pVtxIn, *pVtxOut,planeNormalWS,planeEqWS); - numVertsOut = b3ClipFace(pVtxIn, numVertsIn, planeNormalWS,planeEqWS, pVtxOut); + numVertsOut = b3ClipFace(pVtxIn, numVertsIn, planeNormalWS, planeEqWS, pVtxOut); //btSwap(pVtxIn,pVtxOut); b3Float4* tmp = pVtxOut; @@ -142,32 +136,32 @@ inline int b3ClipFaceAgainstHull(const b3Float4& separatingNormal, const b3Conve numVertsOut = 0; } - // only keep points that are behind the witness face { - b3Float4 localPlaneNormal = b3MakeFloat4(polyA.m_plane.x,polyA.m_plane.y,polyA.m_plane.z,0.f); + b3Float4 localPlaneNormal = b3MakeFloat4(polyA.m_plane.x, polyA.m_plane.y, polyA.m_plane.z, 0.f); float localPlaneEq = polyA.m_plane.w; - b3Float4 planeNormalWS = b3QuatRotate(ornA,localPlaneNormal); - float planeEqWS=localPlaneEq-b3Dot3F4(planeNormalWS,posA); - for (int i=0;i& verticesA, const b3AlignedObjectArray& facesA, const b3AlignedObjectArray& indicesA, + const b3AlignedObjectArray& verticesB, const b3AlignedObjectArray& facesB, const b3AlignedObjectArray& indicesB, - -inline int b3ClipHullAgainstHull(const b3Float4& separatingNormal, - const b3ConvexPolyhedronData& hullA, const b3ConvexPolyhedronData& hullB, - const b3Float4& posA, const b3Quaternion& ornA,const b3Float4& posB, const b3Quaternion& ornB, - b3Float4* worldVertsB1, b3Float4* worldVertsB2, int capacityWorldVerts, - const float minDist, float maxDist, - const b3AlignedObjectArray& verticesA, const b3AlignedObjectArray& facesA, const b3AlignedObjectArray& indicesA, - const b3AlignedObjectArray& verticesB, const b3AlignedObjectArray& facesB, const b3AlignedObjectArray& indicesB, - - b3Float4* contactsOut, - int contactCapacity) + b3Float4* contactsOut, + int contactCapacity) { int numContactsOut = 0; - int numWorldVertsB1= 0; - + int numWorldVertsB1 = 0; + B3_PROFILE("clipHullAgainstHull"); //float curMaxDist=maxDist; - int closestFaceB=-1; + int closestFaceB = -1; float dmax = -FLT_MAX; { //B3_PROFILE("closestFaceB"); - if (hullB.m_numFaces!=1) + if (hullB.m_numFaces != 1) { //printf("wtf\n"); } static bool once = true; //printf("separatingNormal=%f,%f,%f\n",separatingNormal.x,separatingNormal.y,separatingNormal.z); - - for(int face=0;facem_numIndices;i++) + for (int i = 0; i < faceB->m_numIndices; i++) { - b3Float4 vert = verticesB[hullB.m_vertexOffset+indicesB[faceB->m_indexOffset+i]]; - printf("vert[%d] = %f,%f,%f\n",i,vert.x,vert.y,vert.z); + b3Float4 vert = verticesB[hullB.m_vertexOffset + indicesB[faceB->m_indexOffset + i]]; + printf("vert[%d] = %f,%f,%f\n", i, vert.x, vert.y, vert.z); } } -#endif //BT_DEBUG_SAT_FACE - //if (facesB[hullB.m_faceOffset+face].m_numIndices>2) +#endif //BT_DEBUG_SAT_FACE \ + //if (facesB[hullB.m_faceOffset+face].m_numIndices>2) { - const b3Float4 Normal = b3MakeVector3(facesB[hullB.m_faceOffset+face].m_plane.x, - facesB[hullB.m_faceOffset+face].m_plane.y, facesB[hullB.m_faceOffset+face].m_plane.z,0.f); + const b3Float4 Normal = b3MakeVector3(facesB[hullB.m_faceOffset + face].m_plane.x, + facesB[hullB.m_faceOffset + face].m_plane.y, facesB[hullB.m_faceOffset + face].m_plane.z, 0.f); const b3Float4 WorldNormal = b3QuatRotate(ornB, Normal); #ifdef BT_DEBUG_SAT_FACE if (once) - printf("faceNormal = %f,%f,%f\n",Normal.x,Normal.y,Normal.z); + printf("faceNormal = %f,%f,%f\n", Normal.x, Normal.y, Normal.z); #endif - float d = b3Dot3F4(WorldNormal,separatingNormal); + float d = b3Dot3F4(WorldNormal, separatingNormal); if (d > dmax) { dmax = d; @@ -241,79 +233,73 @@ inline int b3ClipHullAgainstHull(const b3Float4& separatingNormal, once = false; } - - b3Assert(closestFaceB>=0); + b3Assert(closestFaceB >= 0); { //B3_PROFILE("worldVertsB1"); - const b3GpuFace& polyB = facesB[hullB.m_faceOffset+closestFaceB]; + const b3GpuFace& polyB = facesB[hullB.m_faceOffset + closestFaceB]; const int numVertices = polyB.m_numIndices; - for(int e0=0;e0=0) + if (closestFaceB >= 0) { //B3_PROFILE("clipFaceAgainstHull"); - numContactsOut = b3ClipFaceAgainstHull((b3Float4&)separatingNormal, &hullA, - posA,ornA, - worldVertsB1,numWorldVertsB1,worldVertsB2,capacityWorldVerts, minDist, maxDist, - verticesA, facesA, indicesA, - contactsOut,contactCapacity); + numContactsOut = b3ClipFaceAgainstHull((b3Float4&)separatingNormal, &hullA, + posA, ornA, + worldVertsB1, numWorldVertsB1, worldVertsB2, capacityWorldVerts, minDist, maxDist, + verticesA, facesA, indicesA, + contactsOut, contactCapacity); } return numContactsOut; } - - - inline int b3ClipHullHullSingle( - int bodyIndexA, int bodyIndexB, - const b3Float4& posA, - const b3Quaternion& ornA, - const b3Float4& posB, - const b3Quaternion& ornB, + int bodyIndexA, int bodyIndexB, + const b3Float4& posA, + const b3Quaternion& ornA, + const b3Float4& posB, + const b3Quaternion& ornB, - int collidableIndexA, int collidableIndexB, + int collidableIndexA, int collidableIndexB, - const b3AlignedObjectArray* bodyBuf, - b3AlignedObjectArray* globalContactOut, - int& nContacts, - - const b3AlignedObjectArray& hostConvexDataA, - const b3AlignedObjectArray& hostConvexDataB, - - const b3AlignedObjectArray& verticesA, - const b3AlignedObjectArray& uniqueEdgesA, - const b3AlignedObjectArray& facesA, - const b3AlignedObjectArray& indicesA, - - const b3AlignedObjectArray& verticesB, - const b3AlignedObjectArray& uniqueEdgesB, - const b3AlignedObjectArray& facesB, - const b3AlignedObjectArray& indicesB, + const b3AlignedObjectArray* bodyBuf, + b3AlignedObjectArray* globalContactOut, + int& nContacts, - const b3AlignedObjectArray& hostCollidablesA, - const b3AlignedObjectArray& hostCollidablesB, - const b3Vector3& sepNormalWorldSpace, - int maxContactCapacity ) + const b3AlignedObjectArray& hostConvexDataA, + const b3AlignedObjectArray& hostConvexDataB, + + const b3AlignedObjectArray& verticesA, + const b3AlignedObjectArray& uniqueEdgesA, + const b3AlignedObjectArray& facesA, + const b3AlignedObjectArray& indicesA, + + const b3AlignedObjectArray& verticesB, + const b3AlignedObjectArray& uniqueEdgesB, + const b3AlignedObjectArray& facesB, + const b3AlignedObjectArray& indicesB, + + const b3AlignedObjectArray& hostCollidablesA, + const b3AlignedObjectArray& hostCollidablesB, + const b3Vector3& sepNormalWorldSpace, + int maxContactCapacity) { int contactIndex = -1; b3ConvexPolyhedronData hullA, hullB; - - b3Collidable colA = hostCollidablesA[collidableIndexA]; - hullA = hostConvexDataA[colA.m_shapeIndex]; - //printf("numvertsA = %d\n",hullA.m_numVertices); - - - b3Collidable colB = hostCollidablesB[collidableIndexB]; - hullB = hostConvexDataB[colB.m_shapeIndex]; - //printf("numvertsB = %d\n",hullB.m_numVertices); - - + + b3Collidable colA = hostCollidablesA[collidableIndexA]; + hullA = hostConvexDataA[colA.m_shapeIndex]; + //printf("numvertsA = %d\n",hullA.m_numVertices); + + b3Collidable colB = hostCollidablesB[collidableIndexB]; + hullB = hostConvexDataB[colB.m_shapeIndex]; + //printf("numvertsB = %d\n",hullB.m_numVertices); + b3Float4 contactsOut[B3_MAX_VERTS]; int localContactCapacity = B3_MAX_VERTS; @@ -321,187 +307,168 @@ inline int b3ClipHullHullSingle( b3Assert(_finite(bodyBuf->at(bodyIndexA).m_pos.x)); b3Assert(_finite(bodyBuf->at(bodyIndexB).m_pos.x)); #endif - - + { - b3Float4 worldVertsB1[B3_MAX_VERTS]; b3Float4 worldVertsB2[B3_MAX_VERTS]; int capacityWorldVerts = B3_MAX_VERTS; - b3Float4 hostNormal = b3MakeFloat4(sepNormalWorldSpace.x,sepNormalWorldSpace.y,sepNormalWorldSpace.z,0.f); + b3Float4 hostNormal = b3MakeFloat4(sepNormalWorldSpace.x, sepNormalWorldSpace.y, sepNormalWorldSpace.z, 0.f); int shapeA = hostCollidablesA[collidableIndexA].m_shapeIndex; int shapeB = hostCollidablesB[collidableIndexB].m_shapeIndex; b3Scalar minDist = -1; b3Scalar maxDist = 0.; - - - b3Transform trA,trB; + b3Transform trA, trB; { - //B3_PROFILE("b3TransformPoint computation"); - //trA.setIdentity(); - trA.setOrigin(b3MakeVector3(posA.x,posA.y,posA.z)); - trA.setRotation(b3Quaternion(ornA.x,ornA.y,ornA.z,ornA.w)); - - //trB.setIdentity(); - trB.setOrigin(b3MakeVector3(posB.x,posB.y,posB.z)); - trB.setRotation(b3Quaternion(ornB.x,ornB.y,ornB.z,ornB.w)); + //B3_PROFILE("b3TransformPoint computation"); + //trA.setIdentity(); + trA.setOrigin(b3MakeVector3(posA.x, posA.y, posA.z)); + trA.setRotation(b3Quaternion(ornA.x, ornA.y, ornA.z, ornA.w)); + + //trB.setIdentity(); + trB.setOrigin(b3MakeVector3(posB.x, posB.y, posB.z)); + trB.setRotation(b3Quaternion(ornB.x, ornB.y, ornB.z, ornB.w)); } b3Quaternion trAorn = trA.getRotation(); - b3Quaternion trBorn = trB.getRotation(); - - int numContactsOut = b3ClipHullAgainstHull(hostNormal, - hostConvexDataA.at(shapeA), - hostConvexDataB.at(shapeB), - (b3Float4&)trA.getOrigin(), (b3Quaternion&)trAorn, - (b3Float4&)trB.getOrigin(), (b3Quaternion&)trBorn, - worldVertsB1,worldVertsB2,capacityWorldVerts, - minDist, maxDist, - verticesA, facesA,indicesA, - verticesB, facesB,indicesB, - - contactsOut,localContactCapacity); + b3Quaternion trBorn = trB.getRotation(); - if (numContactsOut>0) + int numContactsOut = b3ClipHullAgainstHull(hostNormal, + hostConvexDataA.at(shapeA), + hostConvexDataB.at(shapeB), + (b3Float4&)trA.getOrigin(), (b3Quaternion&)trAorn, + (b3Float4&)trB.getOrigin(), (b3Quaternion&)trBorn, + worldVertsB1, worldVertsB2, capacityWorldVerts, + minDist, maxDist, + verticesA, facesA, indicesA, + verticesB, facesB, indicesB, + + contactsOut, localContactCapacity); + + if (numContactsOut > 0) { B3_PROFILE("overlap"); b3Float4 normalOnSurfaceB = (b3Float4&)hostNormal; -// b3Float4 centerOut; - + // b3Float4 centerOut; + b3Int4 contactIdx; contactIdx.x = 0; contactIdx.y = 1; contactIdx.z = 2; contactIdx.w = 3; - + int numPoints = 0; - + { B3_PROFILE("extractManifold"); - numPoints = b3ReduceContacts(contactsOut, numContactsOut, normalOnSurfaceB, &contactIdx); + numPoints = b3ReduceContacts(contactsOut, numContactsOut, normalOnSurfaceB, &contactIdx); } - + b3Assert(numPoints); - - if (nContactsexpand(); b3Contact4Data& contact = globalContactOut->at(nContacts); - contact.m_batchIdx = 0;//i; - contact.m_bodyAPtrAndSignBit = (bodyBuf->at(bodyIndexA).m_invMass==0)? -bodyIndexA:bodyIndexA; - contact.m_bodyBPtrAndSignBit = (bodyBuf->at(bodyIndexB).m_invMass==0)? -bodyIndexB:bodyIndexB; + contact.m_batchIdx = 0; //i; + contact.m_bodyAPtrAndSignBit = (bodyBuf->at(bodyIndexA).m_invMass == 0) ? -bodyIndexA : bodyIndexA; + contact.m_bodyBPtrAndSignBit = (bodyBuf->at(bodyIndexB).m_invMass == 0) ? -bodyIndexB : bodyIndexB; contact.m_frictionCoeffCmp = 45874; contact.m_restituitionCoeffCmp = 0; - - // float distance = 0.f; - for (int p=0;p& rigidBodies, - const b3AlignedObjectArray& collidables, - const b3AlignedObjectArray& convexShapes, - const b3AlignedObjectArray& convexVertices, - const b3AlignedObjectArray& uniqueEdges, - const b3AlignedObjectArray& convexIndices, - const b3AlignedObjectArray& faces, - b3AlignedObjectArray& globalContactsOut, - int& nGlobalContactsOut, - int maxContactCapacity) + int pairIndex, + int bodyIndexA, int bodyIndexB, + int collidableIndexA, int collidableIndexB, + const b3AlignedObjectArray& rigidBodies, + const b3AlignedObjectArray& collidables, + const b3AlignedObjectArray& convexShapes, + const b3AlignedObjectArray& convexVertices, + const b3AlignedObjectArray& uniqueEdges, + const b3AlignedObjectArray& convexIndices, + const b3AlignedObjectArray& faces, + b3AlignedObjectArray& globalContactsOut, + int& nGlobalContactsOut, + int maxContactCapacity) { int contactIndex = -1; - b3Float4 posA = rigidBodies[bodyIndexA].m_pos; b3Quaternion ornA = rigidBodies[bodyIndexA].m_quat; b3Float4 posB = rigidBodies[bodyIndexB].m_pos; b3Quaternion ornB = rigidBodies[bodyIndexB].m_quat; - b3ConvexPolyhedronData hullA, hullB; - + b3Float4 sepNormalWorldSpace; - - - b3Collidable colA = collidables[collidableIndexA]; - hullA = convexShapes[colA.m_shapeIndex]; - //printf("numvertsA = %d\n",hullA.m_numVertices); - - - b3Collidable colB = collidables[collidableIndexB]; - hullB = convexShapes[colB.m_shapeIndex]; - //printf("numvertsB = %d\n",hullB.m_numVertices); - - + b3Collidable colA = collidables[collidableIndexA]; + hullA = convexShapes[colA.m_shapeIndex]; + //printf("numvertsA = %d\n",hullA.m_numVertices); + b3Collidable colB = collidables[collidableIndexB]; + hullB = convexShapes[colB.m_shapeIndex]; + //printf("numvertsB = %d\n",hullB.m_numVertices); #ifdef _WIN32 b3Assert(_finite(rigidBodies[bodyIndexA].m_pos.x)); b3Assert(_finite(rigidBodies[bodyIndexB].m_pos.x)); #endif - - bool foundSepAxis = b3FindSeparatingAxis(hullA,hullB, - posA, - ornA, - posB, - ornB, - convexVertices,uniqueEdges,faces,convexIndices, - convexVertices,uniqueEdges,faces,convexIndices, - - sepNormalWorldSpace - ); + bool foundSepAxis = b3FindSeparatingAxis(hullA, hullB, + posA, + ornA, + posB, + ornB, + + convexVertices, uniqueEdges, faces, convexIndices, + convexVertices, uniqueEdges, faces, convexIndices, + + sepNormalWorldSpace); - if (foundSepAxis) { - - contactIndex = b3ClipHullHullSingle( bodyIndexA, bodyIndexB, - posA,ornA, - posB,ornB, + posA, ornA, + posB, ornB, collidableIndexA, collidableIndexB, - &rigidBodies, + &rigidBodies, &globalContactsOut, nGlobalContactsOut, - + convexShapes, convexShapes, - - convexVertices, - uniqueEdges, + + convexVertices, + uniqueEdges, faces, convexIndices, - + convexVertices, uniqueEdges, faces, @@ -511,10 +478,9 @@ inline int b3ContactConvexConvexSAT( collidables, sepNormalWorldSpace, maxContactCapacity); - } return contactIndex; } -#endif //B3_CONTACT_CONVEX_CONVEX_SAT_H +#endif //B3_CONTACT_CONVEX_CONVEX_SAT_H diff --git a/src/Bullet3Collision/NarrowPhaseCollision/shared/b3ContactSphereSphere.h b/src/Bullet3Collision/NarrowPhaseCollision/shared/b3ContactSphereSphere.h index a3fa82287..acf7c1b18 100644 --- a/src/Bullet3Collision/NarrowPhaseCollision/shared/b3ContactSphereSphere.h +++ b/src/Bullet3Collision/NarrowPhaseCollision/shared/b3ContactSphereSphere.h @@ -2,32 +2,24 @@ #ifndef B3_CONTACT_SPHERE_SPHERE_H #define B3_CONTACT_SPHERE_SPHERE_H - - - - -void computeContactSphereConvex(int pairIndex, - int bodyIndexA, int bodyIndexB, - int collidableIndexA, int collidableIndexB, - const b3RigidBodyData* rigidBodies, - const b3Collidable* collidables, - const b3ConvexPolyhedronData* convexShapes, - const b3Vector3* convexVertices, - const int* convexIndices, - const b3GpuFace* faces, - b3Contact4* globalContactsOut, - int& nGlobalContactsOut, - int maxContactCapacity) +void computeContactSphereConvex(int pairIndex, + int bodyIndexA, int bodyIndexB, + int collidableIndexA, int collidableIndexB, + const b3RigidBodyData* rigidBodies, + const b3Collidable* collidables, + const b3ConvexPolyhedronData* convexShapes, + const b3Vector3* convexVertices, + const int* convexIndices, + const b3GpuFace* faces, + b3Contact4* globalContactsOut, + int& nGlobalContactsOut, + int maxContactCapacity) { - float radius = collidables[collidableIndexA].m_radius; float4 spherePos1 = rigidBodies[bodyIndexA].m_pos; b3Quaternion sphereOrn = rigidBodies[bodyIndexA].m_quat; - - float4 pos = rigidBodies[bodyIndexB].m_pos; - b3Quaternion quat = rigidBodies[bodyIndexB].m_quat; @@ -44,63 +36,64 @@ void computeContactSphereConvex(int pairIndex, int numFaces = convexShapes[shapeIndex].m_numFaces; float4 closestPnt = b3MakeVector3(0, 0, 0, 0); float4 hitNormalWorld = b3MakeVector3(0, 0, 0, 0); - float minDist = -1000000.f; // TODO: What is the largest/smallest float? + float minDist = -1000000.f; // TODO: What is the largest/smallest float? bool bCollide = true; int region = -1; float4 localHitNormal; - for ( int f = 0; f < numFaces; f++ ) + for (int f = 0; f < numFaces; f++) { - b3GpuFace face = faces[convexShapes[shapeIndex].m_faceOffset+f]; + b3GpuFace face = faces[convexShapes[shapeIndex].m_faceOffset + f]; float4 planeEqn; - float4 localPlaneNormal = b3MakeVector3(face.m_plane.x,face.m_plane.y,face.m_plane.z,0.f); - float4 n1 = localPlaneNormal;//quatRotate(quat,localPlaneNormal); + float4 localPlaneNormal = b3MakeVector3(face.m_plane.x, face.m_plane.y, face.m_plane.z, 0.f); + float4 n1 = localPlaneNormal; //quatRotate(quat,localPlaneNormal); planeEqn = n1; planeEqn[3] = face.m_plane.w; float4 pntReturn; float dist = signedDistanceFromPointToPlane(spherePos, planeEqn, &pntReturn); - if ( dist > radius) + if (dist > radius) { bCollide = false; break; } - if ( dist > 0 ) + if (dist > 0) { //might hit an edge or vertex b3Vector3 out; bool isInPoly = IsPointInPolygon(spherePos, - &face, - &convexVertices[convexShapes[shapeIndex].m_vertexOffset], - convexIndices, - &out); + &face, + &convexVertices[convexShapes[shapeIndex].m_vertexOffset], + convexIndices, + &out); if (isInPoly) { - if (dist>minDist) + if (dist > minDist) { minDist = dist; closestPnt = pntReturn; localHitNormal = planeEqn; - region=1; + region = 1; } - } else + } + else { - b3Vector3 tmp = spherePos-out; + b3Vector3 tmp = spherePos - out; b3Scalar l2 = tmp.length2(); - if (l2minDist) + dist = b3Sqrt(l2); + if (dist > minDist) { minDist = dist; closestPnt = out; - localHitNormal = tmp/dist; - region=2; + localHitNormal = tmp / dist; + region = 2; } - - } else + } + else { bCollide = false; break; @@ -109,12 +102,12 @@ void computeContactSphereConvex(int pairIndex, } else { - if ( dist > minDist ) + if (dist > minDist) { minDist = dist; closestPnt = pntReturn; localHitNormal = planeEqn; - region=3; + region = 3; } } } @@ -123,40 +116,38 @@ void computeContactSphereConvex(int pairIndex, if (bCollide && minDist > -10000) { - - float4 normalOnSurfaceB1 = tr.getBasis()*localHitNormal;//-hitNormalWorld; + float4 normalOnSurfaceB1 = tr.getBasis() * localHitNormal; //-hitNormalWorld; float4 pOnB1 = tr(closestPnt); //printf("dist ,%f,",minDist); - float actualDepth = minDist-radius; - if (actualDepth<0) + float actualDepth = minDist - radius; + if (actualDepth < 0) { - //printf("actualDepth = ,%f,", actualDepth); - //printf("normalOnSurfaceB1 = ,%f,%f,%f,", normalOnSurfaceB1.x,normalOnSurfaceB1.y,normalOnSurfaceB1.z); - //printf("region=,%d,\n", region); - pOnB1[3] = actualDepth; + //printf("actualDepth = ,%f,", actualDepth); + //printf("normalOnSurfaceB1 = ,%f,%f,%f,", normalOnSurfaceB1.x,normalOnSurfaceB1.y,normalOnSurfaceB1.z); + //printf("region=,%d,\n", region); + pOnB1[3] = actualDepth; - int dstIdx; -// dstIdx = nGlobalContactsOut++;//AppendInc( nGlobalContactsOut, dstIdx ); - - if (nGlobalContactsOut < maxContactCapacity) - { - dstIdx=nGlobalContactsOut; - nGlobalContactsOut++; + int dstIdx; + // dstIdx = nGlobalContactsOut++;//AppendInc( nGlobalContactsOut, dstIdx ); - b3Contact4* c = &globalContactsOut[dstIdx]; - c->m_worldNormalOnB = normalOnSurfaceB1; - c->setFrictionCoeff(0.7); - c->setRestituitionCoeff(0.f); + if (nGlobalContactsOut < maxContactCapacity) + { + dstIdx = nGlobalContactsOut; + nGlobalContactsOut++; - c->m_batchIdx = pairIndex; - c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass==0?-bodyIndexA:bodyIndexA; - c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass==0?-bodyIndexB:bodyIndexB; - c->m_worldPosB[0] = pOnB1; - int numPoints = 1; - c->m_worldNormalOnB.w = (b3Scalar)numPoints; - }//if (dstIdx < numPairs) + b3Contact4* c = &globalContactsOut[dstIdx]; + c->m_worldNormalOnB = normalOnSurfaceB1; + c->setFrictionCoeff(0.7); + c->setRestituitionCoeff(0.f); + + c->m_batchIdx = pairIndex; + c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass == 0 ? -bodyIndexA : bodyIndexA; + c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass == 0 ? -bodyIndexB : bodyIndexB; + c->m_worldPosB[0] = pOnB1; + int numPoints = 1; + c->m_worldNormalOnB.w = (b3Scalar)numPoints; + } //if (dstIdx < numPairs) } - }//if (hasCollision) - + } //if (hasCollision) } -#endif //B3_CONTACT_SPHERE_SPHERE_H +#endif //B3_CONTACT_SPHERE_SPHERE_H diff --git a/src/Bullet3Collision/NarrowPhaseCollision/shared/b3ConvexPolyhedronData.h b/src/Bullet3Collision/NarrowPhaseCollision/shared/b3ConvexPolyhedronData.h index 5c5f4e297..d5a73bd4f 100644 --- a/src/Bullet3Collision/NarrowPhaseCollision/shared/b3ConvexPolyhedronData.h +++ b/src/Bullet3Collision/NarrowPhaseCollision/shared/b3ConvexPolyhedronData.h @@ -2,8 +2,6 @@ #ifndef B3_CONVEX_POLYHEDRON_DATA_H #define B3_CONVEX_POLYHEDRON_DATA_H - - #include "Bullet3Common/shared/b3Float4.h" #include "Bullet3Common/shared/b3Quat.h" @@ -21,20 +19,20 @@ typedef struct b3ConvexPolyhedronData b3ConvexPolyhedronData_t; struct b3ConvexPolyhedronData { - b3Float4 m_localCenter; - b3Float4 m_extents; - b3Float4 mC; - b3Float4 mE; + b3Float4 m_localCenter; + b3Float4 m_extents; + b3Float4 mC; + b3Float4 mE; - float m_radius; - int m_faceOffset; + float m_radius; + int m_faceOffset; int m_numFaces; - int m_numVertices; + int m_numVertices; int m_vertexOffset; - int m_uniqueEdgesOffset; - int m_numUniqueEdges; + int m_uniqueEdgesOffset; + int m_numUniqueEdges; int m_unused; }; -#endif //B3_CONVEX_POLYHEDRON_DATA_H +#endif //B3_CONVEX_POLYHEDRON_DATA_H diff --git a/src/Bullet3Collision/NarrowPhaseCollision/shared/b3FindConcaveSatAxis.h b/src/Bullet3Collision/NarrowPhaseCollision/shared/b3FindConcaveSatAxis.h index 89993f356..983554eb2 100644 --- a/src/Bullet3Collision/NarrowPhaseCollision/shared/b3FindConcaveSatAxis.h +++ b/src/Bullet3Collision/NarrowPhaseCollision/shared/b3FindConcaveSatAxis.h @@ -3,7 +3,6 @@ #define B3_TRIANGLE_NUM_CONVEX_FACES 5 - #include "Bullet3Common/shared/b3Int4.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3RigidBodyData.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3Collidable.h" @@ -12,25 +11,24 @@ #include "Bullet3Collision/NarrowPhaseCollision/shared/b3QuantizedBvhNodeData.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3ConvexPolyhedronData.h" - -inline void b3Project(__global const b3ConvexPolyhedronData* hull, b3Float4ConstArg pos, b3QuatConstArg orn, -const b3Float4* dir, __global const b3Float4* vertices, float* min, float* max) +inline void b3Project(__global const b3ConvexPolyhedronData* hull, b3Float4ConstArg pos, b3QuatConstArg orn, + const b3Float4* dir, __global const b3Float4* vertices, float* min, float* max) { min[0] = FLT_MAX; max[0] = -FLT_MAX; int numVerts = hull->m_numVertices; - const b3Float4 localDir = b3QuatRotate(b3QuatInverse(orn),*dir); - float offset = b3Dot(pos,*dir); - for(int i=0;im_vertexOffset+i],localDir); - if(dp < min[0]) + float dp = b3Dot(vertices[hull->m_vertexOffset + i], localDir); + if (dp < min[0]) min[0] = dp; - if(dp > max[0]) + if (dp > max[0]) max[0] = dp; } - if(min[0]>max[0]) + if (min[0] > max[0]) { float tmp = min[0]; min[0] = max[0]; @@ -40,53 +38,49 @@ const b3Float4* dir, __global const b3Float4* vertices, float* min, float* max) max[0] += offset; } - -inline bool b3TestSepAxis(const b3ConvexPolyhedronData* hullA, __global const b3ConvexPolyhedronData* hullB, - b3Float4ConstArg posA,b3QuatConstArg ornA, - b3Float4ConstArg posB,b3QuatConstArg ornB, - b3Float4* sep_axis, const b3Float4* verticesA, __global const b3Float4* verticesB,float* depth) +inline bool b3TestSepAxis(const b3ConvexPolyhedronData* hullA, __global const b3ConvexPolyhedronData* hullB, + b3Float4ConstArg posA, b3QuatConstArg ornA, + b3Float4ConstArg posB, b3QuatConstArg ornB, + b3Float4* sep_axis, const b3Float4* verticesA, __global const b3Float4* verticesB, float* depth) { - float Min0,Max0; - float Min1,Max1; - b3Project(hullA,posA,ornA,sep_axis,verticesA, &Min0, &Max0); - b3Project(hullB,posB,ornB, sep_axis,verticesB, &Min1, &Max1); + float Min0, Max0; + float Min1, Max1; + b3Project(hullA, posA, ornA, sep_axis, verticesA, &Min0, &Max0); + b3Project(hullB, posB, ornB, sep_axis, verticesB, &Min1, &Max1); - if(Max0m_numFaces*hullB->m_numVertices; @@ -102,300 +96,289 @@ bool b3FindSeparatingAxis( const b3ConvexPolyhedronData* hullA, __global const b } */ - int curPlaneTests=0; + int curPlaneTests = 0; { int numFacesA = hullA->m_numFaces; // Test normals from hullA - for(int i=0;im_faceOffset+i].m_plane; - b3Float4 faceANormalWS = b3QuatRotate(ornA,normal); - if (b3Dot(DeltaC2,faceANormalWS)<0) - faceANormalWS*=-1.f; + const b3Float4 normal = facesA[hullA->m_faceOffset + i].m_plane; + b3Float4 faceANormalWS = b3QuatRotate(ornA, normal); + if (b3Dot(DeltaC2, faceANormalWS) < 0) + faceANormalWS *= -1.f; curPlaneTests++; float d; - if(!b3TestSepAxis( hullA, hullB, posA,ornA,posB,ornB,&faceANormalWS, verticesA, verticesB,&d)) + if (!b3TestSepAxis(hullA, hullB, posA, ornA, posB, ornB, &faceANormalWS, verticesA, verticesB, &d)) return false; - if(d<*dmin) + if (d < *dmin) { *dmin = d; *sep = faceANormalWS; } } } - if((b3Dot(-DeltaC2,*sep))>0.0f) + if ((b3Dot(-DeltaC2, *sep)) > 0.0f) { *sep = -(*sep); } return true; } +b3Vector3 unitSphere162[] = + { + b3MakeVector3(0.000000, -1.000000, 0.000000), + b3MakeVector3(0.203181, -0.967950, 0.147618), + b3MakeVector3(-0.077607, -0.967950, 0.238853), + b3MakeVector3(0.723607, -0.447220, 0.525725), + b3MakeVector3(0.609547, -0.657519, 0.442856), + b3MakeVector3(0.812729, -0.502301, 0.295238), + b3MakeVector3(-0.251147, -0.967949, 0.000000), + b3MakeVector3(-0.077607, -0.967950, -0.238853), + b3MakeVector3(0.203181, -0.967950, -0.147618), + b3MakeVector3(0.860698, -0.251151, 0.442858), + b3MakeVector3(-0.276388, -0.447220, 0.850649), + b3MakeVector3(-0.029639, -0.502302, 0.864184), + b3MakeVector3(-0.155215, -0.251152, 0.955422), + b3MakeVector3(-0.894426, -0.447216, 0.000000), + b3MakeVector3(-0.831051, -0.502299, 0.238853), + b3MakeVector3(-0.956626, -0.251149, 0.147618), + b3MakeVector3(-0.276388, -0.447220, -0.850649), + b3MakeVector3(-0.483971, -0.502302, -0.716565), + b3MakeVector3(-0.436007, -0.251152, -0.864188), + b3MakeVector3(0.723607, -0.447220, -0.525725), + b3MakeVector3(0.531941, -0.502302, -0.681712), + b3MakeVector3(0.687159, -0.251152, -0.681715), + b3MakeVector3(0.687159, -0.251152, 0.681715), + b3MakeVector3(-0.436007, -0.251152, 0.864188), + b3MakeVector3(-0.956626, -0.251149, -0.147618), + b3MakeVector3(-0.155215, -0.251152, -0.955422), + b3MakeVector3(0.860698, -0.251151, -0.442858), + b3MakeVector3(0.276388, 0.447220, 0.850649), + b3MakeVector3(0.483971, 0.502302, 0.716565), + b3MakeVector3(0.232822, 0.657519, 0.716563), + b3MakeVector3(-0.723607, 0.447220, 0.525725), + b3MakeVector3(-0.531941, 0.502302, 0.681712), + b3MakeVector3(-0.609547, 0.657519, 0.442856), + b3MakeVector3(-0.723607, 0.447220, -0.525725), + b3MakeVector3(-0.812729, 0.502301, -0.295238), + b3MakeVector3(-0.609547, 0.657519, -0.442856), + b3MakeVector3(0.276388, 0.447220, -0.850649), + b3MakeVector3(0.029639, 0.502302, -0.864184), + b3MakeVector3(0.232822, 0.657519, -0.716563), + b3MakeVector3(0.894426, 0.447216, 0.000000), + b3MakeVector3(0.831051, 0.502299, -0.238853), + b3MakeVector3(0.753442, 0.657515, 0.000000), + b3MakeVector3(-0.232822, -0.657519, 0.716563), + b3MakeVector3(-0.162456, -0.850654, 0.499995), + b3MakeVector3(0.052790, -0.723612, 0.688185), + b3MakeVector3(0.138199, -0.894429, 0.425321), + b3MakeVector3(0.262869, -0.525738, 0.809012), + b3MakeVector3(0.361805, -0.723611, 0.587779), + b3MakeVector3(0.531941, -0.502302, 0.681712), + b3MakeVector3(0.425323, -0.850654, 0.309011), + b3MakeVector3(0.812729, -0.502301, -0.295238), + b3MakeVector3(0.609547, -0.657519, -0.442856), + b3MakeVector3(0.850648, -0.525736, 0.000000), + b3MakeVector3(0.670817, -0.723611, -0.162457), + b3MakeVector3(0.670817, -0.723610, 0.162458), + b3MakeVector3(0.425323, -0.850654, -0.309011), + b3MakeVector3(0.447211, -0.894428, 0.000001), + b3MakeVector3(-0.753442, -0.657515, 0.000000), + b3MakeVector3(-0.525730, -0.850652, 0.000000), + b3MakeVector3(-0.638195, -0.723609, 0.262864), + b3MakeVector3(-0.361801, -0.894428, 0.262864), + b3MakeVector3(-0.688189, -0.525736, 0.499997), + b3MakeVector3(-0.447211, -0.723610, 0.525729), + b3MakeVector3(-0.483971, -0.502302, 0.716565), + b3MakeVector3(-0.232822, -0.657519, -0.716563), + b3MakeVector3(-0.162456, -0.850654, -0.499995), + b3MakeVector3(-0.447211, -0.723611, -0.525727), + b3MakeVector3(-0.361801, -0.894429, -0.262863), + b3MakeVector3(-0.688189, -0.525736, -0.499997), + b3MakeVector3(-0.638195, -0.723609, -0.262863), + b3MakeVector3(-0.831051, -0.502299, -0.238853), + b3MakeVector3(0.361804, -0.723612, -0.587779), + b3MakeVector3(0.138197, -0.894429, -0.425321), + b3MakeVector3(0.262869, -0.525738, -0.809012), + b3MakeVector3(0.052789, -0.723611, -0.688186), + b3MakeVector3(-0.029639, -0.502302, -0.864184), + b3MakeVector3(0.956626, 0.251149, 0.147618), + b3MakeVector3(0.956626, 0.251149, -0.147618), + b3MakeVector3(0.951058, -0.000000, 0.309013), + b3MakeVector3(1.000000, 0.000000, 0.000000), + b3MakeVector3(0.947213, -0.276396, 0.162458), + b3MakeVector3(0.951058, 0.000000, -0.309013), + b3MakeVector3(0.947213, -0.276396, -0.162458), + b3MakeVector3(0.155215, 0.251152, 0.955422), + b3MakeVector3(0.436007, 0.251152, 0.864188), + b3MakeVector3(-0.000000, -0.000000, 1.000000), + b3MakeVector3(0.309017, 0.000000, 0.951056), + b3MakeVector3(0.138199, -0.276398, 0.951055), + b3MakeVector3(0.587786, 0.000000, 0.809017), + b3MakeVector3(0.447216, -0.276398, 0.850648), + b3MakeVector3(-0.860698, 0.251151, 0.442858), + b3MakeVector3(-0.687159, 0.251152, 0.681715), + b3MakeVector3(-0.951058, -0.000000, 0.309013), + b3MakeVector3(-0.809018, 0.000000, 0.587783), + b3MakeVector3(-0.861803, -0.276396, 0.425324), + b3MakeVector3(-0.587786, 0.000000, 0.809017), + b3MakeVector3(-0.670819, -0.276397, 0.688191), + b3MakeVector3(-0.687159, 0.251152, -0.681715), + b3MakeVector3(-0.860698, 0.251151, -0.442858), + b3MakeVector3(-0.587786, -0.000000, -0.809017), + b3MakeVector3(-0.809018, -0.000000, -0.587783), + b3MakeVector3(-0.670819, -0.276397, -0.688191), + b3MakeVector3(-0.951058, 0.000000, -0.309013), + b3MakeVector3(-0.861803, -0.276396, -0.425324), + b3MakeVector3(0.436007, 0.251152, -0.864188), + b3MakeVector3(0.155215, 0.251152, -0.955422), + b3MakeVector3(0.587786, -0.000000, -0.809017), + b3MakeVector3(0.309017, -0.000000, -0.951056), + b3MakeVector3(0.447216, -0.276398, -0.850648), + b3MakeVector3(0.000000, 0.000000, -1.000000), + b3MakeVector3(0.138199, -0.276398, -0.951055), + b3MakeVector3(0.670820, 0.276396, 0.688190), + b3MakeVector3(0.809019, -0.000002, 0.587783), + b3MakeVector3(0.688189, 0.525736, 0.499997), + b3MakeVector3(0.861804, 0.276394, 0.425323), + b3MakeVector3(0.831051, 0.502299, 0.238853), + b3MakeVector3(-0.447216, 0.276397, 0.850649), + b3MakeVector3(-0.309017, -0.000001, 0.951056), + b3MakeVector3(-0.262869, 0.525738, 0.809012), + b3MakeVector3(-0.138199, 0.276397, 0.951055), + b3MakeVector3(0.029639, 0.502302, 0.864184), + b3MakeVector3(-0.947213, 0.276396, -0.162458), + b3MakeVector3(-1.000000, 0.000001, 0.000000), + b3MakeVector3(-0.850648, 0.525736, -0.000000), + b3MakeVector3(-0.947213, 0.276397, 0.162458), + b3MakeVector3(-0.812729, 0.502301, 0.295238), + b3MakeVector3(-0.138199, 0.276397, -0.951055), + b3MakeVector3(-0.309016, -0.000000, -0.951057), + b3MakeVector3(-0.262869, 0.525738, -0.809012), + b3MakeVector3(-0.447215, 0.276397, -0.850649), + b3MakeVector3(-0.531941, 0.502302, -0.681712), + b3MakeVector3(0.861804, 0.276396, -0.425322), + b3MakeVector3(0.809019, 0.000000, -0.587782), + b3MakeVector3(0.688189, 0.525736, -0.499997), + b3MakeVector3(0.670821, 0.276397, -0.688189), + b3MakeVector3(0.483971, 0.502302, -0.716565), + b3MakeVector3(0.077607, 0.967950, 0.238853), + b3MakeVector3(0.251147, 0.967949, 0.000000), + b3MakeVector3(0.000000, 1.000000, 0.000000), + b3MakeVector3(0.162456, 0.850654, 0.499995), + b3MakeVector3(0.361800, 0.894429, 0.262863), + b3MakeVector3(0.447209, 0.723612, 0.525728), + b3MakeVector3(0.525730, 0.850652, 0.000000), + b3MakeVector3(0.638194, 0.723610, 0.262864), + b3MakeVector3(-0.203181, 0.967950, 0.147618), + b3MakeVector3(-0.425323, 0.850654, 0.309011), + b3MakeVector3(-0.138197, 0.894430, 0.425320), + b3MakeVector3(-0.361804, 0.723612, 0.587778), + b3MakeVector3(-0.052790, 0.723612, 0.688185), + b3MakeVector3(-0.203181, 0.967950, -0.147618), + b3MakeVector3(-0.425323, 0.850654, -0.309011), + b3MakeVector3(-0.447210, 0.894429, 0.000000), + b3MakeVector3(-0.670817, 0.723611, -0.162457), + b3MakeVector3(-0.670817, 0.723611, 0.162457), + b3MakeVector3(0.077607, 0.967950, -0.238853), + b3MakeVector3(0.162456, 0.850654, -0.499995), + b3MakeVector3(-0.138197, 0.894430, -0.425320), + b3MakeVector3(-0.052790, 0.723612, -0.688185), + b3MakeVector3(-0.361804, 0.723612, -0.587778), + b3MakeVector3(0.361800, 0.894429, -0.262863), + b3MakeVector3(0.638194, 0.723610, -0.262864), + b3MakeVector3(0.447209, 0.723612, -0.525728)}; -b3Vector3 unitSphere162[]= +bool b3FindSeparatingAxisEdgeEdge(const b3ConvexPolyhedronData* hullA, __global const b3ConvexPolyhedronData* hullB, + b3Float4ConstArg posA1, + b3QuatConstArg ornA, + b3Float4ConstArg posB1, + b3QuatConstArg ornB, + b3Float4ConstArg DeltaC2, + const b3Float4* verticesA, + const b3Float4* uniqueEdgesA, + const b3GpuFace* facesA, + const int* indicesA, + __global const b3Float4* verticesB, + __global const b3Float4* uniqueEdgesB, + __global const b3GpuFace* facesB, + __global const int* indicesB, + b3Float4* sep, + float* dmin, + bool searchAllEdgeEdge) { - b3MakeVector3(0.000000,-1.000000,0.000000), -b3MakeVector3(0.203181,-0.967950,0.147618), -b3MakeVector3(-0.077607,-0.967950,0.238853), -b3MakeVector3(0.723607,-0.447220,0.525725), -b3MakeVector3(0.609547,-0.657519,0.442856), -b3MakeVector3(0.812729,-0.502301,0.295238), -b3MakeVector3(-0.251147,-0.967949,0.000000), -b3MakeVector3(-0.077607,-0.967950,-0.238853), -b3MakeVector3(0.203181,-0.967950,-0.147618), -b3MakeVector3(0.860698,-0.251151,0.442858), -b3MakeVector3(-0.276388,-0.447220,0.850649), -b3MakeVector3(-0.029639,-0.502302,0.864184), -b3MakeVector3(-0.155215,-0.251152,0.955422), -b3MakeVector3(-0.894426,-0.447216,0.000000), -b3MakeVector3(-0.831051,-0.502299,0.238853), -b3MakeVector3(-0.956626,-0.251149,0.147618), -b3MakeVector3(-0.276388,-0.447220,-0.850649), -b3MakeVector3(-0.483971,-0.502302,-0.716565), -b3MakeVector3(-0.436007,-0.251152,-0.864188), -b3MakeVector3(0.723607,-0.447220,-0.525725), -b3MakeVector3(0.531941,-0.502302,-0.681712), -b3MakeVector3(0.687159,-0.251152,-0.681715), -b3MakeVector3(0.687159,-0.251152,0.681715), -b3MakeVector3(-0.436007,-0.251152,0.864188), -b3MakeVector3(-0.956626,-0.251149,-0.147618), -b3MakeVector3(-0.155215,-0.251152,-0.955422), -b3MakeVector3(0.860698,-0.251151,-0.442858), -b3MakeVector3(0.276388,0.447220,0.850649), -b3MakeVector3(0.483971,0.502302,0.716565), -b3MakeVector3(0.232822,0.657519,0.716563), -b3MakeVector3(-0.723607,0.447220,0.525725), -b3MakeVector3(-0.531941,0.502302,0.681712), -b3MakeVector3(-0.609547,0.657519,0.442856), -b3MakeVector3(-0.723607,0.447220,-0.525725), -b3MakeVector3(-0.812729,0.502301,-0.295238), -b3MakeVector3(-0.609547,0.657519,-0.442856), -b3MakeVector3(0.276388,0.447220,-0.850649), -b3MakeVector3(0.029639,0.502302,-0.864184), -b3MakeVector3(0.232822,0.657519,-0.716563), -b3MakeVector3(0.894426,0.447216,0.000000), -b3MakeVector3(0.831051,0.502299,-0.238853), -b3MakeVector3(0.753442,0.657515,0.000000), -b3MakeVector3(-0.232822,-0.657519,0.716563), -b3MakeVector3(-0.162456,-0.850654,0.499995), -b3MakeVector3(0.052790,-0.723612,0.688185), -b3MakeVector3(0.138199,-0.894429,0.425321), -b3MakeVector3(0.262869,-0.525738,0.809012), -b3MakeVector3(0.361805,-0.723611,0.587779), -b3MakeVector3(0.531941,-0.502302,0.681712), -b3MakeVector3(0.425323,-0.850654,0.309011), -b3MakeVector3(0.812729,-0.502301,-0.295238), -b3MakeVector3(0.609547,-0.657519,-0.442856), -b3MakeVector3(0.850648,-0.525736,0.000000), -b3MakeVector3(0.670817,-0.723611,-0.162457), -b3MakeVector3(0.670817,-0.723610,0.162458), -b3MakeVector3(0.425323,-0.850654,-0.309011), -b3MakeVector3(0.447211,-0.894428,0.000001), -b3MakeVector3(-0.753442,-0.657515,0.000000), -b3MakeVector3(-0.525730,-0.850652,0.000000), -b3MakeVector3(-0.638195,-0.723609,0.262864), -b3MakeVector3(-0.361801,-0.894428,0.262864), -b3MakeVector3(-0.688189,-0.525736,0.499997), -b3MakeVector3(-0.447211,-0.723610,0.525729), -b3MakeVector3(-0.483971,-0.502302,0.716565), -b3MakeVector3(-0.232822,-0.657519,-0.716563), -b3MakeVector3(-0.162456,-0.850654,-0.499995), -b3MakeVector3(-0.447211,-0.723611,-0.525727), -b3MakeVector3(-0.361801,-0.894429,-0.262863), -b3MakeVector3(-0.688189,-0.525736,-0.499997), -b3MakeVector3(-0.638195,-0.723609,-0.262863), -b3MakeVector3(-0.831051,-0.502299,-0.238853), -b3MakeVector3(0.361804,-0.723612,-0.587779), -b3MakeVector3(0.138197,-0.894429,-0.425321), -b3MakeVector3(0.262869,-0.525738,-0.809012), -b3MakeVector3(0.052789,-0.723611,-0.688186), -b3MakeVector3(-0.029639,-0.502302,-0.864184), -b3MakeVector3(0.956626,0.251149,0.147618), -b3MakeVector3(0.956626,0.251149,-0.147618), -b3MakeVector3(0.951058,-0.000000,0.309013), -b3MakeVector3(1.000000,0.000000,0.000000), -b3MakeVector3(0.947213,-0.276396,0.162458), -b3MakeVector3(0.951058,0.000000,-0.309013), -b3MakeVector3(0.947213,-0.276396,-0.162458), -b3MakeVector3(0.155215,0.251152,0.955422), -b3MakeVector3(0.436007,0.251152,0.864188), -b3MakeVector3(-0.000000,-0.000000,1.000000), -b3MakeVector3(0.309017,0.000000,0.951056), -b3MakeVector3(0.138199,-0.276398,0.951055), -b3MakeVector3(0.587786,0.000000,0.809017), -b3MakeVector3(0.447216,-0.276398,0.850648), -b3MakeVector3(-0.860698,0.251151,0.442858), -b3MakeVector3(-0.687159,0.251152,0.681715), -b3MakeVector3(-0.951058,-0.000000,0.309013), -b3MakeVector3(-0.809018,0.000000,0.587783), -b3MakeVector3(-0.861803,-0.276396,0.425324), -b3MakeVector3(-0.587786,0.000000,0.809017), -b3MakeVector3(-0.670819,-0.276397,0.688191), -b3MakeVector3(-0.687159,0.251152,-0.681715), -b3MakeVector3(-0.860698,0.251151,-0.442858), -b3MakeVector3(-0.587786,-0.000000,-0.809017), -b3MakeVector3(-0.809018,-0.000000,-0.587783), -b3MakeVector3(-0.670819,-0.276397,-0.688191), -b3MakeVector3(-0.951058,0.000000,-0.309013), -b3MakeVector3(-0.861803,-0.276396,-0.425324), -b3MakeVector3(0.436007,0.251152,-0.864188), -b3MakeVector3(0.155215,0.251152,-0.955422), -b3MakeVector3(0.587786,-0.000000,-0.809017), -b3MakeVector3(0.309017,-0.000000,-0.951056), -b3MakeVector3(0.447216,-0.276398,-0.850648), -b3MakeVector3(0.000000,0.000000,-1.000000), -b3MakeVector3(0.138199,-0.276398,-0.951055), -b3MakeVector3(0.670820,0.276396,0.688190), -b3MakeVector3(0.809019,-0.000002,0.587783), -b3MakeVector3(0.688189,0.525736,0.499997), -b3MakeVector3(0.861804,0.276394,0.425323), -b3MakeVector3(0.831051,0.502299,0.238853), -b3MakeVector3(-0.447216,0.276397,0.850649), -b3MakeVector3(-0.309017,-0.000001,0.951056), -b3MakeVector3(-0.262869,0.525738,0.809012), -b3MakeVector3(-0.138199,0.276397,0.951055), -b3MakeVector3(0.029639,0.502302,0.864184), -b3MakeVector3(-0.947213,0.276396,-0.162458), -b3MakeVector3(-1.000000,0.000001,0.000000), -b3MakeVector3(-0.850648,0.525736,-0.000000), -b3MakeVector3(-0.947213,0.276397,0.162458), -b3MakeVector3(-0.812729,0.502301,0.295238), -b3MakeVector3(-0.138199,0.276397,-0.951055), -b3MakeVector3(-0.309016,-0.000000,-0.951057), -b3MakeVector3(-0.262869,0.525738,-0.809012), -b3MakeVector3(-0.447215,0.276397,-0.850649), -b3MakeVector3(-0.531941,0.502302,-0.681712), -b3MakeVector3(0.861804,0.276396,-0.425322), -b3MakeVector3(0.809019,0.000000,-0.587782), -b3MakeVector3(0.688189,0.525736,-0.499997), -b3MakeVector3(0.670821,0.276397,-0.688189), -b3MakeVector3(0.483971,0.502302,-0.716565), -b3MakeVector3(0.077607,0.967950,0.238853), -b3MakeVector3(0.251147,0.967949,0.000000), -b3MakeVector3(0.000000,1.000000,0.000000), -b3MakeVector3(0.162456,0.850654,0.499995), -b3MakeVector3(0.361800,0.894429,0.262863), -b3MakeVector3(0.447209,0.723612,0.525728), -b3MakeVector3(0.525730,0.850652,0.000000), -b3MakeVector3(0.638194,0.723610,0.262864), -b3MakeVector3(-0.203181,0.967950,0.147618), -b3MakeVector3(-0.425323,0.850654,0.309011), -b3MakeVector3(-0.138197,0.894430,0.425320), -b3MakeVector3(-0.361804,0.723612,0.587778), -b3MakeVector3(-0.052790,0.723612,0.688185), -b3MakeVector3(-0.203181,0.967950,-0.147618), -b3MakeVector3(-0.425323,0.850654,-0.309011), -b3MakeVector3(-0.447210,0.894429,0.000000), -b3MakeVector3(-0.670817,0.723611,-0.162457), -b3MakeVector3(-0.670817,0.723611,0.162457), -b3MakeVector3(0.077607,0.967950,-0.238853), -b3MakeVector3(0.162456,0.850654,-0.499995), -b3MakeVector3(-0.138197,0.894430,-0.425320), -b3MakeVector3(-0.052790,0.723612,-0.688185), -b3MakeVector3(-0.361804,0.723612,-0.587778), -b3MakeVector3(0.361800,0.894429,-0.262863), -b3MakeVector3(0.638194,0.723610,-0.262864), -b3MakeVector3(0.447209,0.723612,-0.525728) -}; - - -bool b3FindSeparatingAxisEdgeEdge( const b3ConvexPolyhedronData* hullA, __global const b3ConvexPolyhedronData* hullB, - b3Float4ConstArg posA1, - b3QuatConstArg ornA, - b3Float4ConstArg posB1, - b3QuatConstArg ornB, - b3Float4ConstArg DeltaC2, - const b3Float4* verticesA, - const b3Float4* uniqueEdgesA, - const b3GpuFace* facesA, - const int* indicesA, - __global const b3Float4* verticesB, - __global const b3Float4* uniqueEdgesB, - __global const b3GpuFace* facesB, - __global const int* indicesB, - b3Float4* sep, - float* dmin, - bool searchAllEdgeEdge) -{ - - b3Float4 posA = posA1; posA.w = 0.f; b3Float4 posB = posB1; posB.w = 0.f; -// int curPlaneTests=0; + // int curPlaneTests=0; int curEdgeEdge = 0; // Test edges static int maxEdgeTests = 0; int curEdgeTests = hullA->m_numUniqueEdges * hullB->m_numUniqueEdges; - if (curEdgeTests >maxEdgeTests ) + if (curEdgeTests > maxEdgeTests) { - maxEdgeTests = curEdgeTests ; - printf("maxEdgeTests = %d\n",maxEdgeTests ); - printf("hullA->m_numUniqueEdges = %d\n",hullA->m_numUniqueEdges); - printf("hullB->m_numUniqueEdges = %d\n",hullB->m_numUniqueEdges); - + maxEdgeTests = curEdgeTests; + printf("maxEdgeTests = %d\n", maxEdgeTests); + printf("hullA->m_numUniqueEdges = %d\n", hullA->m_numUniqueEdges); + printf("hullB->m_numUniqueEdges = %d\n", hullB->m_numUniqueEdges); } - if (searchAllEdgeEdge) { - for(int e0=0;e0m_numUniqueEdges;e0++) + for (int e0 = 0; e0 < hullA->m_numUniqueEdges; e0++) { - const b3Float4 edge0 = uniqueEdgesA[hullA->m_uniqueEdgesOffset+e0]; - b3Float4 edge0World = b3QuatRotate(ornA,edge0); + const b3Float4 edge0 = uniqueEdgesA[hullA->m_uniqueEdgesOffset + e0]; + b3Float4 edge0World = b3QuatRotate(ornA, edge0); - for(int e1=0;e1m_numUniqueEdges;e1++) + for (int e1 = 0; e1 < hullB->m_numUniqueEdges; e1++) { - const b3Float4 edge1 = uniqueEdgesB[hullB->m_uniqueEdgesOffset+e1]; - b3Float4 edge1World = b3QuatRotate(ornB,edge1); + const b3Float4 edge1 = uniqueEdgesB[hullB->m_uniqueEdgesOffset + e1]; + b3Float4 edge1World = b3QuatRotate(ornB, edge1); - - b3Float4 crossje = b3Cross(edge0World,edge1World); + b3Float4 crossje = b3Cross(edge0World, edge1World); curEdgeEdge++; - if(!b3IsAlmostZero(crossje)) + if (!b3IsAlmostZero(crossje)) { crossje = b3Normalized(crossje); - if (b3Dot(DeltaC2,crossje)<0) + if (b3Dot(DeltaC2, crossje) < 0) crossje *= -1.f; float dist; bool result = true; { - float Min0,Max0; - float Min1,Max1; - b3Project(hullA,posA,ornA,&crossje,verticesA, &Min0, &Max0); - b3Project(hullB,posB,ornB,&crossje,verticesB, &Min1, &Max1); - - if(Max00.0f) + if ((b3Dot(-DeltaC2, *sep)) > 0.0f) { *sep = -(*sep); } return true; } +inline int b3FindClippingFaces(b3Float4ConstArg separatingNormal, + __global const b3ConvexPolyhedronData_t* hullA, __global const b3ConvexPolyhedronData_t* hullB, + b3Float4ConstArg posA, b3QuatConstArg ornA, b3Float4ConstArg posB, b3QuatConstArg ornB, + __global b3Float4* worldVertsA1, + __global b3Float4* worldNormalsA1, + __global b3Float4* worldVertsB1, + int capacityWorldVerts, + const float minDist, float maxDist, + __global const b3Float4* verticesA, + __global const b3GpuFace_t* facesA, + __global const int* indicesA, + __global const b3Float4* verticesB, + __global const b3GpuFace_t* facesB, + __global const int* indicesB, - -inline int b3FindClippingFaces(b3Float4ConstArg separatingNormal, - __global const b3ConvexPolyhedronData_t* hullA, __global const b3ConvexPolyhedronData_t* hullB, - b3Float4ConstArg posA, b3QuatConstArg ornA,b3Float4ConstArg posB, b3QuatConstArg ornB, - __global b3Float4* worldVertsA1, - __global b3Float4* worldNormalsA1, - __global b3Float4* worldVertsB1, - int capacityWorldVerts, - const float minDist, float maxDist, - __global const b3Float4* verticesA, - __global const b3GpuFace_t* facesA, - __global const int* indicesA, - __global const b3Float4* verticesB, - __global const b3GpuFace_t* facesB, - __global const int* indicesB, - - __global b3Int4* clippingFaces, int pairIndex) + __global b3Int4* clippingFaces, int pairIndex) { int numContactsOut = 0; - int numWorldVertsB1= 0; - - - int closestFaceB=-1; + int numWorldVertsB1 = 0; + + int closestFaceB = -1; float dmax = -FLT_MAX; - + { - for(int face=0;facem_numFaces;face++) + for (int face = 0; face < hullB->m_numFaces; face++) { - const b3Float4 Normal = b3MakeFloat4(facesB[hullB->m_faceOffset+face].m_plane.x, - facesB[hullB->m_faceOffset+face].m_plane.y, facesB[hullB->m_faceOffset+face].m_plane.z,0.f); + const b3Float4 Normal = b3MakeFloat4(facesB[hullB->m_faceOffset + face].m_plane.x, + facesB[hullB->m_faceOffset + face].m_plane.y, facesB[hullB->m_faceOffset + face].m_plane.z, 0.f); const b3Float4 WorldNormal = b3QuatRotate(ornB, Normal); - float d = b3Dot(WorldNormal,separatingNormal); + float d = b3Dot(WorldNormal, separatingNormal); if (d > dmax) { dmax = d; @@ -479,81 +455,76 @@ inline int b3FindClippingFaces(b3Float4ConstArg separatingNormal, } } } - + { - const b3GpuFace_t polyB = facesB[hullB->m_faceOffset+closestFaceB]; + const b3GpuFace_t polyB = facesB[hullB->m_faceOffset + closestFaceB]; const int numVertices = polyB.m_numIndices; - for(int e0=0;e0m_vertexOffset+indicesB[polyB.m_indexOffset+e0]]; - worldVertsB1[pairIndex*capacityWorldVerts+numWorldVertsB1++] = b3TransformPoint(b,posB,ornB); + const b3Float4 b = verticesB[hullB->m_vertexOffset + indicesB[polyB.m_indexOffset + e0]]; + worldVertsB1[pairIndex * capacityWorldVerts + numWorldVertsB1++] = b3TransformPoint(b, posB, ornB); } } - - int closestFaceA=-1; + + int closestFaceA = -1; { float dmin = FLT_MAX; - for(int face=0;facem_numFaces;face++) + for (int face = 0; face < hullA->m_numFaces; face++) { const b3Float4 Normal = b3MakeFloat4( - facesA[hullA->m_faceOffset+face].m_plane.x, - facesA[hullA->m_faceOffset+face].m_plane.y, - facesA[hullA->m_faceOffset+face].m_plane.z, - 0.f); - const b3Float4 faceANormalWS = b3QuatRotate(ornA,Normal); - - float d = b3Dot(faceANormalWS,separatingNormal); + facesA[hullA->m_faceOffset + face].m_plane.x, + facesA[hullA->m_faceOffset + face].m_plane.y, + facesA[hullA->m_faceOffset + face].m_plane.z, + 0.f); + const b3Float4 faceANormalWS = b3QuatRotate(ornA, Normal); + + float d = b3Dot(faceANormalWS, separatingNormal); if (d < dmin) { dmin = d; closestFaceA = face; - worldNormalsA1[pairIndex] = faceANormalWS; + worldNormalsA1[pairIndex] = faceANormalWS; } } } - - int numVerticesA = facesA[hullA->m_faceOffset+closestFaceA].m_numIndices; - for(int e0=0;e0m_faceOffset + closestFaceA].m_numIndices; + for (int e0 = 0; e0 < numVerticesA; e0++) { - const b3Float4 a = verticesA[hullA->m_vertexOffset+indicesA[facesA[hullA->m_faceOffset+closestFaceA].m_indexOffset+e0]]; - worldVertsA1[pairIndex*capacityWorldVerts+e0] = b3TransformPoint(a, posA,ornA); - } - - clippingFaces[pairIndex].x = closestFaceA; - clippingFaces[pairIndex].y = closestFaceB; - clippingFaces[pairIndex].z = numVerticesA; - clippingFaces[pairIndex].w = numWorldVertsB1; - - + const b3Float4 a = verticesA[hullA->m_vertexOffset + indicesA[facesA[hullA->m_faceOffset + closestFaceA].m_indexOffset + e0]]; + worldVertsA1[pairIndex * capacityWorldVerts + e0] = b3TransformPoint(a, posA, ornA); + } + + clippingFaces[pairIndex].x = closestFaceA; + clippingFaces[pairIndex].y = closestFaceB; + clippingFaces[pairIndex].z = numVerticesA; + clippingFaces[pairIndex].w = numWorldVertsB1; + return numContactsOut; } - - - -__kernel void b3FindConcaveSeparatingAxisKernel( __global b3Int4* concavePairs, - __global const b3RigidBodyData* rigidBodies, - __global const b3Collidable* collidables, - __global const b3ConvexPolyhedronData* convexShapes, - __global const b3Float4* vertices, - __global const b3Float4* uniqueEdges, - __global const b3GpuFace* faces, - __global const int* indices, - __global const b3GpuChildShape* gpuChildShapes, - __global b3Aabb* aabbs, - __global b3Float4* concaveSeparatingNormalsOut, - __global b3Int4* clippingFacesOut, - __global b3Vector3* worldVertsA1Out, - __global b3Vector3* worldNormalsA1Out, - __global b3Vector3* worldVertsB1Out, - __global int* hasSeparatingNormals, - int vertexFaceCapacity, - int numConcavePairs, - int pairIdx - ) +__kernel void b3FindConcaveSeparatingAxisKernel(__global b3Int4* concavePairs, + __global const b3RigidBodyData* rigidBodies, + __global const b3Collidable* collidables, + __global const b3ConvexPolyhedronData* convexShapes, + __global const b3Float4* vertices, + __global const b3Float4* uniqueEdges, + __global const b3GpuFace* faces, + __global const int* indices, + __global const b3GpuChildShape* gpuChildShapes, + __global b3Aabb* aabbs, + __global b3Float4* concaveSeparatingNormalsOut, + __global b3Int4* clippingFacesOut, + __global b3Vector3* worldVertsA1Out, + __global b3Vector3* worldNormalsA1Out, + __global b3Vector3* worldVertsB1Out, + __global int* hasSeparatingNormals, + int vertexFaceCapacity, + int numConcavePairs, + int pairIdx) { int i = pairIdx; -/* int i = get_global_id(0); + /* int i = get_global_id(0); if (i>=numConcavePairs) return; int pairIdx = i; @@ -568,8 +539,8 @@ __kernel void b3FindConcaveSeparatingAxisKernel( __global b3Int4* concavePairs int shapeIndexA = collidables[collidableIndexA].m_shapeIndex; int shapeIndexB = collidables[collidableIndexB].m_shapeIndex; - if (collidables[collidableIndexB].m_shapeType!=SHAPE_CONVEX_HULL&& - collidables[collidableIndexB].m_shapeType!=SHAPE_COMPOUND_OF_CONVEX_HULLS) + if (collidables[collidableIndexB].m_shapeType != SHAPE_CONVEX_HULL && + collidables[collidableIndexB].m_shapeType != SHAPE_COMPOUND_OF_CONVEX_HULLS) { concavePairs[pairIdx].w = -1; return; @@ -577,121 +548,119 @@ __kernel void b3FindConcaveSeparatingAxisKernel( __global b3Int4* concavePairs hasSeparatingNormals[i] = 0; -// int numFacesA = convexShapes[shapeIndexA].m_numFaces; + // int numFacesA = convexShapes[shapeIndexA].m_numFaces; int numActualConcaveConvexTests = 0; - + int f = concavePairs[i].z; - + bool overlap = false; - + b3ConvexPolyhedronData convexPolyhedronA; //add 3 vertices of the triangle convexPolyhedronA.m_numVertices = 3; convexPolyhedronA.m_vertexOffset = 0; - b3Float4 localCenter = b3MakeFloat4(0.f,0.f,0.f,0.f); + b3Float4 localCenter = b3MakeFloat4(0.f, 0.f, 0.f, 0.f); - b3GpuFace face = faces[convexShapes[shapeIndexA].m_faceOffset+f]; + b3GpuFace face = faces[convexShapes[shapeIndexA].m_faceOffset + f]; b3Aabb triAabb; - triAabb.m_minVec = b3MakeFloat4(1e30f,1e30f,1e30f,0.f); - triAabb.m_maxVec = b3MakeFloat4(-1e30f,-1e30f,-1e30f,0.f); - + triAabb.m_minVec = b3MakeFloat4(1e30f, 1e30f, 1e30f, 0.f); + triAabb.m_maxVec = b3MakeFloat4(-1e30f, -1e30f, -1e30f, 0.f); + b3Float4 verticesA[3]; - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) { - int index = indices[face.m_indexOffset+i]; - b3Float4 vert = vertices[convexShapes[shapeIndexA].m_vertexOffset+index]; + int index = indices[face.m_indexOffset + i]; + b3Float4 vert = vertices[convexShapes[shapeIndexA].m_vertexOffset + index]; verticesA[i] = vert; localCenter += vert; - - triAabb.m_minVec = b3MinFloat4(triAabb.m_minVec,vert); - triAabb.m_maxVec = b3MaxFloat4(triAabb.m_maxVec,vert); + triAabb.m_minVec = b3MinFloat4(triAabb.m_minVec, vert); + triAabb.m_maxVec = b3MaxFloat4(triAabb.m_maxVec, vert); } overlap = true; overlap = (triAabb.m_minVec.x > aabbs[bodyIndexB].m_maxVec.x || triAabb.m_maxVec.x < aabbs[bodyIndexB].m_minVec.x) ? false : overlap; overlap = (triAabb.m_minVec.z > aabbs[bodyIndexB].m_maxVec.z || triAabb.m_maxVec.z < aabbs[bodyIndexB].m_minVec.z) ? false : overlap; overlap = (triAabb.m_minVec.y > aabbs[bodyIndexB].m_maxVec.y || triAabb.m_maxVec.y < aabbs[bodyIndexB].m_minVec.y) ? false : overlap; - + if (overlap) { float dmin = FLT_MAX; - int hasSeparatingAxis=5; - b3Float4 sepAxis=b3MakeFloat4(1,2,3,4); + int hasSeparatingAxis = 5; + b3Float4 sepAxis = b3MakeFloat4(1, 2, 3, 4); - // int localCC=0; + // int localCC=0; numActualConcaveConvexTests++; //a triangle has 3 unique edges convexPolyhedronA.m_numUniqueEdges = 3; convexPolyhedronA.m_uniqueEdgesOffset = 0; b3Float4 uniqueEdgesA[3]; - - uniqueEdgesA[0] = (verticesA[1]-verticesA[0]); - uniqueEdgesA[1] = (verticesA[2]-verticesA[1]); - uniqueEdgesA[2] = (verticesA[0]-verticesA[2]); + uniqueEdgesA[0] = (verticesA[1] - verticesA[0]); + uniqueEdgesA[1] = (verticesA[2] - verticesA[1]); + uniqueEdgesA[2] = (verticesA[0] - verticesA[2]); convexPolyhedronA.m_faceOffset = 0; - - b3Float4 normal = b3MakeFloat4(face.m_plane.x,face.m_plane.y,face.m_plane.z,0.f); - + + b3Float4 normal = b3MakeFloat4(face.m_plane.x, face.m_plane.y, face.m_plane.z, 0.f); + b3GpuFace facesA[B3_TRIANGLE_NUM_CONVEX_FACES]; - int indicesA[3+3+2+2+2]; - int curUsedIndices=0; - int fidx=0; + int indicesA[3 + 3 + 2 + 2 + 2]; + int curUsedIndices = 0; + int fidx = 0; //front size of triangle { - facesA[fidx].m_indexOffset=curUsedIndices; + facesA[fidx].m_indexOffset = curUsedIndices; indicesA[0] = 0; indicesA[1] = 1; indicesA[2] = 2; - curUsedIndices+=3; + curUsedIndices += 3; float c = face.m_plane.w; facesA[fidx].m_plane.x = normal.x; facesA[fidx].m_plane.y = normal.y; facesA[fidx].m_plane.z = normal.z; facesA[fidx].m_plane.w = c; - facesA[fidx].m_numIndices=3; + facesA[fidx].m_numIndices = 3; } fidx++; //back size of triangle { - facesA[fidx].m_indexOffset=curUsedIndices; - indicesA[3]=2; - indicesA[4]=1; - indicesA[5]=0; - curUsedIndices+=3; - float c = b3Dot(normal,verticesA[0]); - // float c1 = -face.m_plane.w; + facesA[fidx].m_indexOffset = curUsedIndices; + indicesA[3] = 2; + indicesA[4] = 1; + indicesA[5] = 0; + curUsedIndices += 3; + float c = b3Dot(normal, verticesA[0]); + // float c1 = -face.m_plane.w; facesA[fidx].m_plane.x = -normal.x; facesA[fidx].m_plane.y = -normal.y; facesA[fidx].m_plane.z = -normal.z; facesA[fidx].m_plane.w = c; - facesA[fidx].m_numIndices=3; + facesA[fidx].m_numIndices = 3; } fidx++; bool addEdgePlanes = true; if (addEdgePlanes) { - int numVertices=3; - int prevVertex = numVertices-1; - for (int i=0;i& vertices, b3Scalar& min, b3Scalar& max) +inline void b3ProjectAxis(const b3ConvexPolyhedronData& hull, const b3Float4& pos, const b3Quaternion& orn, const b3Float4& dir, const b3AlignedObjectArray& vertices, b3Scalar& min, b3Scalar& max) { min = FLT_MAX; max = -FLT_MAX; int numVerts = hull.m_numVertices; - const b3Float4 localDir = b3QuatRotate(orn.inverse(),dir); + const b3Float4 localDir = b3QuatRotate(orn.inverse(), dir); - b3Scalar offset = b3Dot3F4(pos,dir); + b3Scalar offset = b3Dot3F4(pos, dir); - for(int i=0;i max) max = dp; + if (dp < min) min = dp; + if (dp > max) max = dp; } - if(min>max) + if (min > max) { b3Scalar tmp = min; min = max; @@ -32,44 +31,42 @@ inline void b3ProjectAxis(const b3ConvexPolyhedronData& hull, const b3Float4& p max += offset; } - -inline bool b3TestSepAxis(const b3ConvexPolyhedronData& hullA, const b3ConvexPolyhedronData& hullB, - const b3Float4& posA,const b3Quaternion& ornA, - const b3Float4& posB,const b3Quaternion& ornB, - const b3Float4& sep_axis, const b3AlignedObjectArray& verticesA,const b3AlignedObjectArray& verticesB,b3Scalar& depth) +inline bool b3TestSepAxis(const b3ConvexPolyhedronData& hullA, const b3ConvexPolyhedronData& hullB, + const b3Float4& posA, const b3Quaternion& ornA, + const b3Float4& posB, const b3Quaternion& ornB, + const b3Float4& sep_axis, const b3AlignedObjectArray& verticesA, const b3AlignedObjectArray& verticesB, b3Scalar& depth) { - b3Scalar Min0,Max0; - b3Scalar Min1,Max1; - b3ProjectAxis(hullA,posA,ornA,sep_axis,verticesA, Min0, Max0); - b3ProjectAxis(hullB,posB,ornB, sep_axis,verticesB, Min1, Max1); + b3Scalar Min0, Max0; + b3Scalar Min1, Max1; + b3ProjectAxis(hullA, posA, ornA, sep_axis, verticesA, Min0, Max0); + b3ProjectAxis(hullB, posB, ornB, sep_axis, verticesB, Min1, Max1); - if(Max0=0.0f); + b3Assert(d0 >= 0.0f); b3Scalar d1 = Max1 - Min0; - b3Assert(d1>=0.0f); - depth = d0= 0.0f); + depth = d0 < d1 ? d0 : d1; return true; } +inline bool b3FindSeparatingAxis(const b3ConvexPolyhedronData& hullA, const b3ConvexPolyhedronData& hullB, + const b3Float4& posA1, + const b3Quaternion& ornA, + const b3Float4& posB1, + const b3Quaternion& ornB, + const b3AlignedObjectArray& verticesA, + const b3AlignedObjectArray& uniqueEdgesA, + const b3AlignedObjectArray& facesA, + const b3AlignedObjectArray& indicesA, + const b3AlignedObjectArray& verticesB, + const b3AlignedObjectArray& uniqueEdgesB, + const b3AlignedObjectArray& facesB, + const b3AlignedObjectArray& indicesB, -inline bool b3FindSeparatingAxis( const b3ConvexPolyhedronData& hullA, const b3ConvexPolyhedronData& hullB, - const b3Float4& posA1, - const b3Quaternion& ornA, - const b3Float4& posB1, - const b3Quaternion& ornB, - const b3AlignedObjectArray& verticesA, - const b3AlignedObjectArray& uniqueEdgesA, - const b3AlignedObjectArray& facesA, - const b3AlignedObjectArray& indicesA, - const b3AlignedObjectArray& verticesB, - const b3AlignedObjectArray& uniqueEdgesB, - const b3AlignedObjectArray& facesB, - const b3AlignedObjectArray& indicesB, - - b3Vector3& sep) + b3Vector3& sep) { B3_PROFILE("findSeparatingAxis"); @@ -77,42 +74,41 @@ inline bool b3FindSeparatingAxis( const b3ConvexPolyhedronData& hullA, const b3C posA.w = 0.f; b3Float4 posB = posB1; posB.w = 0.f; -//#ifdef TEST_INTERNAL_OBJECTS + //#ifdef TEST_INTERNAL_OBJECTS b3Float4 c0local = (b3Float4&)hullA.m_localCenter; b3Float4 c0 = b3TransformPoint(c0local, posA, ornA); b3Float4 c1local = (b3Float4&)hullB.m_localCenter; - b3Float4 c1 = b3TransformPoint(c1local,posB,ornB); + b3Float4 c1 = b3TransformPoint(c1local, posB, ornB); const b3Float4 deltaC2 = c0 - c1; -//#endif + //#endif b3Scalar dmin = FLT_MAX; - int curPlaneTests=0; + int curPlaneTests = 0; int numFacesA = hullA.m_numFaces; // Test normals from hullA - for(int i=0;i0.0f) + if ((b3Dot3F4(-deltaC2, (b3Float4&)sep)) > 0.0f) sep = -sep; return true; } -#endif //B3_FIND_SEPARATING_AXIS_H - +#endif //B3_FIND_SEPARATING_AXIS_H diff --git a/src/Bullet3Collision/NarrowPhaseCollision/shared/b3MprPenetration.h b/src/Bullet3Collision/NarrowPhaseCollision/shared/b3MprPenetration.h index 6c3ad7c9d..a3bfbf299 100644 --- a/src/Bullet3Collision/NarrowPhaseCollision/shared/b3MprPenetration.h +++ b/src/Bullet3Collision/NarrowPhaseCollision/shared/b3MprPenetration.h @@ -15,9 +15,6 @@ * See the License for more information. */ - - - #ifndef B3_MPR_PENETRATION_H #define B3_MPR_PENETRATION_H @@ -27,9 +24,6 @@ #include "Bullet3Collision/NarrowPhaseCollision/shared/b3ConvexPolyhedronData.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3Collidable.h" - - - #ifdef __cplusplus #define B3_MPR_SQRT sqrtf #else @@ -41,196 +35,171 @@ #define B3_MPR_TOLERANCE 1E-6f #define B3_MPR_MAX_ITERATIONS 1000 -struct _b3MprSupport_t +struct _b3MprSupport_t { - b3Float4 v; //!< Support point in minkowski sum - b3Float4 v1; //!< Support point in obj1 - b3Float4 v2; //!< Support point in obj2 + b3Float4 v; //!< Support point in minkowski sum + b3Float4 v1; //!< Support point in obj1 + b3Float4 v2; //!< Support point in obj2 }; typedef struct _b3MprSupport_t b3MprSupport_t; -struct _b3MprSimplex_t +struct _b3MprSimplex_t { - b3MprSupport_t ps[4]; - int last; //!< index of last added point + b3MprSupport_t ps[4]; + int last; //!< index of last added point }; typedef struct _b3MprSimplex_t b3MprSimplex_t; -inline b3MprSupport_t* b3MprSimplexPointW(b3MprSimplex_t *s, int idx) +inline b3MprSupport_t *b3MprSimplexPointW(b3MprSimplex_t *s, int idx) { - return &s->ps[idx]; + return &s->ps[idx]; } inline void b3MprSimplexSetSize(b3MprSimplex_t *s, int size) { - s->last = size - 1; + s->last = size - 1; } - inline int b3MprSimplexSize(const b3MprSimplex_t *s) { - return s->last + 1; + return s->last + 1; } - -inline const b3MprSupport_t* b3MprSimplexPoint(const b3MprSimplex_t* s, int idx) +inline const b3MprSupport_t *b3MprSimplexPoint(const b3MprSimplex_t *s, int idx) { - // here is no check on boundaries - return &s->ps[idx]; + // here is no check on boundaries + return &s->ps[idx]; } inline void b3MprSupportCopy(b3MprSupport_t *d, const b3MprSupport_t *s) { - *d = *s; + *d = *s; } inline void b3MprSimplexSet(b3MprSimplex_t *s, size_t pos, const b3MprSupport_t *a) { - b3MprSupportCopy(s->ps + pos, a); + b3MprSupportCopy(s->ps + pos, a); } - inline void b3MprSimplexSwap(b3MprSimplex_t *s, size_t pos1, size_t pos2) { - b3MprSupport_t supp; + b3MprSupport_t supp; - b3MprSupportCopy(&supp, &s->ps[pos1]); - b3MprSupportCopy(&s->ps[pos1], &s->ps[pos2]); - b3MprSupportCopy(&s->ps[pos2], &supp); + b3MprSupportCopy(&supp, &s->ps[pos1]); + b3MprSupportCopy(&s->ps[pos1], &s->ps[pos2]); + b3MprSupportCopy(&s->ps[pos2], &supp); } - inline int b3MprIsZero(float val) { - return B3_MPR_FABS(val) < FLT_EPSILON; + return B3_MPR_FABS(val) < FLT_EPSILON; } - - inline int b3MprEq(float _a, float _b) { - float ab; - float a, b; + float ab; + float a, b; - ab = B3_MPR_FABS(_a - _b); - if (B3_MPR_FABS(ab) < FLT_EPSILON) - return 1; + ab = B3_MPR_FABS(_a - _b); + if (B3_MPR_FABS(ab) < FLT_EPSILON) + return 1; - a = B3_MPR_FABS(_a); - b = B3_MPR_FABS(_b); - if (b > a){ - return ab < FLT_EPSILON * b; - }else{ - return ab < FLT_EPSILON * a; - } + a = B3_MPR_FABS(_a); + b = B3_MPR_FABS(_b); + if (b > a) + { + return ab < FLT_EPSILON * b; + } + else + { + return ab < FLT_EPSILON * a; + } } - -inline int b3MprVec3Eq(const b3Float4* a, const b3Float4 *b) +inline int b3MprVec3Eq(const b3Float4 *a, const b3Float4 *b) { - return b3MprEq((*a).x, (*b).x) - && b3MprEq((*a).y, (*b).y) - && b3MprEq((*a).z, (*b).z); + return b3MprEq((*a).x, (*b).x) && b3MprEq((*a).y, (*b).y) && b3MprEq((*a).z, (*b).z); } - - -inline b3Float4 b3LocalGetSupportVertex(b3Float4ConstArg supportVec,__global const b3ConvexPolyhedronData_t* hull, b3ConstArray(b3Float4) verticesA) +inline b3Float4 b3LocalGetSupportVertex(b3Float4ConstArg supportVec, __global const b3ConvexPolyhedronData_t *hull, b3ConstArray(b3Float4) verticesA) { - b3Float4 supVec = b3MakeFloat4(0,0,0,0); + b3Float4 supVec = b3MakeFloat4(0, 0, 0, 0); float maxDot = -B3_LARGE_FLOAT; - if( 0 < hull->m_numVertices ) - { - const b3Float4 scaled = supportVec; + if (0 < hull->m_numVertices) + { + const b3Float4 scaled = supportVec; int index = b3MaxDot(scaled, &verticesA[hull->m_vertexOffset], hull->m_numVertices, &maxDot); - return verticesA[hull->m_vertexOffset+index]; - } - - return supVec; + return verticesA[hull->m_vertexOffset + index]; + } + return supVec; } - -B3_STATIC void b3MprConvexSupport(int pairIndex,int bodyIndex, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, - b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, - b3ConstArray(b3Collidable_t) cpuCollidables, - b3ConstArray(b3Float4) cpuVertices, - __global b3Float4* sepAxis, - const b3Float4* _dir, b3Float4* outp, int logme) +B3_STATIC void b3MprConvexSupport(int pairIndex, int bodyIndex, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, + b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, + b3ConstArray(b3Collidable_t) cpuCollidables, + b3ConstArray(b3Float4) cpuVertices, + __global b3Float4 *sepAxis, + const b3Float4 *_dir, b3Float4 *outp, int logme) { //dir is in worldspace, move to local space - + b3Float4 pos = cpuBodyBuf[bodyIndex].m_pos; b3Quat orn = cpuBodyBuf[bodyIndex].m_quat; - - b3Float4 dir = b3MakeFloat4((*_dir).x,(*_dir).y,(*_dir).z,0.f); - - const b3Float4 localDir = b3QuatRotate(b3QuatInverse(orn),dir); - + + b3Float4 dir = b3MakeFloat4((*_dir).x, (*_dir).y, (*_dir).z, 0.f); + + const b3Float4 localDir = b3QuatRotate(b3QuatInverse(orn), dir); //find local support vertex int colIndex = cpuBodyBuf[bodyIndex].m_collidableIdx; - - b3Assert(cpuCollidables[colIndex].m_shapeType==SHAPE_CONVEX_HULL); - __global const b3ConvexPolyhedronData_t* hull = &cpuConvexData[cpuCollidables[colIndex].m_shapeIndex]; - + + b3Assert(cpuCollidables[colIndex].m_shapeType == SHAPE_CONVEX_HULL); + __global const b3ConvexPolyhedronData_t *hull = &cpuConvexData[cpuCollidables[colIndex].m_shapeIndex]; + b3Float4 pInA; if (logme) { - - - // b3Float4 supVec = b3MakeFloat4(0,0,0,0); + // b3Float4 supVec = b3MakeFloat4(0,0,0,0); float maxDot = -B3_LARGE_FLOAT; - if( 0 < hull->m_numVertices ) + if (0 < hull->m_numVertices) { const b3Float4 scaled = localDir; int index = b3MaxDot(scaled, &cpuVertices[hull->m_vertexOffset], hull->m_numVertices, &maxDot); - pInA = cpuVertices[hull->m_vertexOffset+index]; - + pInA = cpuVertices[hull->m_vertexOffset + index]; } - - - } else + } + else { - pInA = b3LocalGetSupportVertex(localDir,hull,cpuVertices); + pInA = b3LocalGetSupportVertex(localDir, hull, cpuVertices); } //move vertex to world space - *outp = b3TransformPoint(pInA,pos,orn); - + *outp = b3TransformPoint(pInA, pos, orn); } -inline void b3MprSupport(int pairIndex,int bodyIndexA, int bodyIndexB, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, - b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, - b3ConstArray(b3Collidable_t) cpuCollidables, - b3ConstArray(b3Float4) cpuVertices, - __global b3Float4* sepAxis, - const b3Float4* _dir, b3MprSupport_t *supp) +inline void b3MprSupport(int pairIndex, int bodyIndexA, int bodyIndexB, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, + b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, + b3ConstArray(b3Collidable_t) cpuCollidables, + b3ConstArray(b3Float4) cpuVertices, + __global b3Float4 *sepAxis, + const b3Float4 *_dir, b3MprSupport_t *supp) { - b3Float4 dir; + b3Float4 dir; dir = *_dir; - b3MprConvexSupport(pairIndex,bodyIndexA,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices,sepAxis,&dir, &supp->v1,0); - dir = *_dir*-1.f; - b3MprConvexSupport(pairIndex,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices,sepAxis,&dir, &supp->v2,0); - supp->v = supp->v1 - supp->v2; + b3MprConvexSupport(pairIndex, bodyIndexA, cpuBodyBuf, cpuConvexData, cpuCollidables, cpuVertices, sepAxis, &dir, &supp->v1, 0); + dir = *_dir * -1.f; + b3MprConvexSupport(pairIndex, bodyIndexB, cpuBodyBuf, cpuConvexData, cpuCollidables, cpuVertices, sepAxis, &dir, &supp->v2, 0); + supp->v = supp->v1 - supp->v2; } - - - - - - - - inline void b3FindOrigin(int bodyIndexA, int bodyIndexB, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, b3MprSupport_t *center) { - - center->v1 = cpuBodyBuf[bodyIndexA].m_pos; + center->v1 = cpuBodyBuf[bodyIndexA].m_pos; center->v2 = cpuBodyBuf[bodyIndexB].m_pos; - center->v = center->v1 - center->v2; + center->v = center->v1 - center->v2; } inline void b3MprVec3Set(b3Float4 *v, float x, float y, float z) @@ -243,48 +212,45 @@ inline void b3MprVec3Set(b3Float4 *v, float x, float y, float z) inline void b3MprVec3Add(b3Float4 *v, const b3Float4 *w) { - (*v).x += (*w).x; - (*v).y += (*w).y; - (*v).z += (*w).z; + (*v).x += (*w).x; + (*v).y += (*w).y; + (*v).z += (*w).z; } inline void b3MprVec3Copy(b3Float4 *v, const b3Float4 *w) { - *v = *w; + *v = *w; } inline void b3MprVec3Scale(b3Float4 *d, float k) { - *d *= k; + *d *= k; } inline float b3MprVec3Dot(const b3Float4 *a, const b3Float4 *b) { - float dot; + float dot; - dot = b3Dot3F4(*a,*b); - return dot; + dot = b3Dot3F4(*a, *b); + return dot; } - inline float b3MprVec3Len2(const b3Float4 *v) { - return b3MprVec3Dot(v, v); + return b3MprVec3Dot(v, v); } inline void b3MprVec3Normalize(b3Float4 *d) { - float k = 1.f / B3_MPR_SQRT(b3MprVec3Len2(d)); - b3MprVec3Scale(d, k); + float k = 1.f / B3_MPR_SQRT(b3MprVec3Len2(d)); + b3MprVec3Scale(d, k); } inline void b3MprVec3Cross(b3Float4 *d, const b3Float4 *a, const b3Float4 *b) { - *d = b3Cross3(*a,*b); - + *d = b3Cross3(*a, *b); } - inline void b3MprVec3Sub2(b3Float4 *d, const b3Float4 *v, const b3Float4 *w) { *d = *v - *w; @@ -292,629 +258,631 @@ inline void b3MprVec3Sub2(b3Float4 *d, const b3Float4 *v, const b3Float4 *w) inline void b3PortalDir(const b3MprSimplex_t *portal, b3Float4 *dir) { - b3Float4 v2v1, v3v1; + b3Float4 v2v1, v3v1; - b3MprVec3Sub2(&v2v1, &b3MprSimplexPoint(portal, 2)->v, - &b3MprSimplexPoint(portal, 1)->v); - b3MprVec3Sub2(&v3v1, &b3MprSimplexPoint(portal, 3)->v, - &b3MprSimplexPoint(portal, 1)->v); - b3MprVec3Cross(dir, &v2v1, &v3v1); - b3MprVec3Normalize(dir); + b3MprVec3Sub2(&v2v1, &b3MprSimplexPoint(portal, 2)->v, + &b3MprSimplexPoint(portal, 1)->v); + b3MprVec3Sub2(&v3v1, &b3MprSimplexPoint(portal, 3)->v, + &b3MprSimplexPoint(portal, 1)->v); + b3MprVec3Cross(dir, &v2v1, &v3v1); + b3MprVec3Normalize(dir); } - inline int portalEncapsulesOrigin(const b3MprSimplex_t *portal, - const b3Float4 *dir) + const b3Float4 *dir) { - float dot; - dot = b3MprVec3Dot(dir, &b3MprSimplexPoint(portal, 1)->v); - return b3MprIsZero(dot) || dot > 0.f; + float dot; + dot = b3MprVec3Dot(dir, &b3MprSimplexPoint(portal, 1)->v); + return b3MprIsZero(dot) || dot > 0.f; } inline int portalReachTolerance(const b3MprSimplex_t *portal, - const b3MprSupport_t *v4, - const b3Float4 *dir) + const b3MprSupport_t *v4, + const b3Float4 *dir) { - float dv1, dv2, dv3, dv4; - float dot1, dot2, dot3; + float dv1, dv2, dv3, dv4; + float dot1, dot2, dot3; - // find the smallest dot product of dir and {v1-v4, v2-v4, v3-v4} + // find the smallest dot product of dir and {v1-v4, v2-v4, v3-v4} - dv1 = b3MprVec3Dot(&b3MprSimplexPoint(portal, 1)->v, dir); - dv2 = b3MprVec3Dot(&b3MprSimplexPoint(portal, 2)->v, dir); - dv3 = b3MprVec3Dot(&b3MprSimplexPoint(portal, 3)->v, dir); - dv4 = b3MprVec3Dot(&v4->v, dir); + dv1 = b3MprVec3Dot(&b3MprSimplexPoint(portal, 1)->v, dir); + dv2 = b3MprVec3Dot(&b3MprSimplexPoint(portal, 2)->v, dir); + dv3 = b3MprVec3Dot(&b3MprSimplexPoint(portal, 3)->v, dir); + dv4 = b3MprVec3Dot(&v4->v, dir); - dot1 = dv4 - dv1; - dot2 = dv4 - dv2; - dot3 = dv4 - dv3; + dot1 = dv4 - dv1; + dot2 = dv4 - dv2; + dot3 = dv4 - dv3; - dot1 = B3_MPR_FMIN(dot1, dot2); - dot1 = B3_MPR_FMIN(dot1, dot3); + dot1 = B3_MPR_FMIN(dot1, dot2); + dot1 = B3_MPR_FMIN(dot1, dot3); - return b3MprEq(dot1, B3_MPR_TOLERANCE) || dot1 < B3_MPR_TOLERANCE; + return b3MprEq(dot1, B3_MPR_TOLERANCE) || dot1 < B3_MPR_TOLERANCE; } -inline int portalCanEncapsuleOrigin(const b3MprSimplex_t *portal, - const b3MprSupport_t *v4, - const b3Float4 *dir) +inline int portalCanEncapsuleOrigin(const b3MprSimplex_t *portal, + const b3MprSupport_t *v4, + const b3Float4 *dir) { - float dot; - dot = b3MprVec3Dot(&v4->v, dir); - return b3MprIsZero(dot) || dot > 0.f; + float dot; + dot = b3MprVec3Dot(&v4->v, dir); + return b3MprIsZero(dot) || dot > 0.f; } inline void b3ExpandPortal(b3MprSimplex_t *portal, - const b3MprSupport_t *v4) + const b3MprSupport_t *v4) { - float dot; - b3Float4 v4v0; + float dot; + b3Float4 v4v0; - b3MprVec3Cross(&v4v0, &v4->v, &b3MprSimplexPoint(portal, 0)->v); - dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 1)->v, &v4v0); - if (dot > 0.f){ - dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 2)->v, &v4v0); - if (dot > 0.f){ - b3MprSimplexSet(portal, 1, v4); - }else{ - b3MprSimplexSet(portal, 3, v4); - } - }else{ - dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 3)->v, &v4v0); - if (dot > 0.f){ - b3MprSimplexSet(portal, 2, v4); - }else{ - b3MprSimplexSet(portal, 1, v4); - } - } -} - - - -B3_STATIC int b3DiscoverPortal(int pairIndex, int bodyIndexA, int bodyIndexB, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, - b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, - b3ConstArray(b3Collidable_t) cpuCollidables, - b3ConstArray(b3Float4) cpuVertices, - __global b3Float4* sepAxis, - __global int* hasSepAxis, - b3MprSimplex_t *portal) -{ - b3Float4 dir, va, vb; - float dot; - int cont; - - - - // vertex 0 is center of portal - b3FindOrigin(bodyIndexA,bodyIndexB,cpuBodyBuf, b3MprSimplexPointW(portal, 0)); - // vertex 0 is center of portal - b3MprSimplexSetSize(portal, 1); - - - - b3Float4 zero = b3MakeFloat4(0,0,0,0); - b3Float4* b3mpr_vec3_origin = &zero; - - if (b3MprVec3Eq(&b3MprSimplexPoint(portal, 0)->v, b3mpr_vec3_origin)){ - // Portal's center lies on origin (0,0,0) => we know that objects - // intersect but we would need to know penetration info. - // So move center little bit... - b3MprVec3Set(&va, FLT_EPSILON * 10.f, 0.f, 0.f); - b3MprVec3Add(&b3MprSimplexPointW(portal, 0)->v, &va); - } - - - // vertex 1 = support in direction of origin - b3MprVec3Copy(&dir, &b3MprSimplexPoint(portal, 0)->v); - b3MprVec3Scale(&dir, -1.f); - b3MprVec3Normalize(&dir); - - - b3MprSupport(pairIndex,bodyIndexA,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices, sepAxis,&dir, b3MprSimplexPointW(portal, 1)); - - b3MprSimplexSetSize(portal, 2); - - // test if origin isn't outside of v1 - dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 1)->v, &dir); - - - if (b3MprIsZero(dot) || dot < 0.f) - return -1; - - - // vertex 2 - b3MprVec3Cross(&dir, &b3MprSimplexPoint(portal, 0)->v, - &b3MprSimplexPoint(portal, 1)->v); - if (b3MprIsZero(b3MprVec3Len2(&dir))){ - if (b3MprVec3Eq(&b3MprSimplexPoint(portal, 1)->v, b3mpr_vec3_origin)){ - // origin lies on v1 - return 1; - }else{ - // origin lies on v0-v1 segment - return 2; - } - } - - b3MprVec3Normalize(&dir); - b3MprSupport(pairIndex,bodyIndexA,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices, sepAxis,&dir, b3MprSimplexPointW(portal, 2)); - - dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 2)->v, &dir); - if (b3MprIsZero(dot) || dot < 0.f) - return -1; - - b3MprSimplexSetSize(portal, 3); - - // vertex 3 direction - b3MprVec3Sub2(&va, &b3MprSimplexPoint(portal, 1)->v, - &b3MprSimplexPoint(portal, 0)->v); - b3MprVec3Sub2(&vb, &b3MprSimplexPoint(portal, 2)->v, - &b3MprSimplexPoint(portal, 0)->v); - b3MprVec3Cross(&dir, &va, &vb); - b3MprVec3Normalize(&dir); - - // it is better to form portal faces to be oriented "outside" origin - dot = b3MprVec3Dot(&dir, &b3MprSimplexPoint(portal, 0)->v); - if (dot > 0.f){ - b3MprSimplexSwap(portal, 1, 2); - b3MprVec3Scale(&dir, -1.f); - } - - while (b3MprSimplexSize(portal) < 4){ - b3MprSupport(pairIndex,bodyIndexA,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices, sepAxis,&dir, b3MprSimplexPointW(portal, 3)); - - dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 3)->v, &dir); - if (b3MprIsZero(dot) || dot < 0.f) - return -1; - - cont = 0; - - // test if origin is outside (v1, v0, v3) - set v2 as v3 and - // continue - b3MprVec3Cross(&va, &b3MprSimplexPoint(portal, 1)->v, - &b3MprSimplexPoint(portal, 3)->v); - dot = b3MprVec3Dot(&va, &b3MprSimplexPoint(portal, 0)->v); - if (dot < 0.f && !b3MprIsZero(dot)){ - b3MprSimplexSet(portal, 2, b3MprSimplexPoint(portal, 3)); - cont = 1; - } - - if (!cont){ - // test if origin is outside (v3, v0, v2) - set v1 as v3 and - // continue - b3MprVec3Cross(&va, &b3MprSimplexPoint(portal, 3)->v, - &b3MprSimplexPoint(portal, 2)->v); - dot = b3MprVec3Dot(&va, &b3MprSimplexPoint(portal, 0)->v); - if (dot < 0.f && !b3MprIsZero(dot)){ - b3MprSimplexSet(portal, 1, b3MprSimplexPoint(portal, 3)); - cont = 1; - } - } - - if (cont){ - b3MprVec3Sub2(&va, &b3MprSimplexPoint(portal, 1)->v, - &b3MprSimplexPoint(portal, 0)->v); - b3MprVec3Sub2(&vb, &b3MprSimplexPoint(portal, 2)->v, - &b3MprSimplexPoint(portal, 0)->v); - b3MprVec3Cross(&dir, &va, &vb); - b3MprVec3Normalize(&dir); - }else{ - b3MprSimplexSetSize(portal, 4); - } - } - - return 0; -} - - -B3_STATIC int b3RefinePortal(int pairIndex,int bodyIndexA, int bodyIndexB, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, - b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, - b3ConstArray(b3Collidable_t) cpuCollidables, - b3ConstArray(b3Float4) cpuVertices, - __global b3Float4* sepAxis, - b3MprSimplex_t *portal) -{ - b3Float4 dir; - b3MprSupport_t v4; - - for (int i=0;iv, &b3MprSimplexPoint(portal, 0)->v); + dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 1)->v, &v4v0); + if (dot > 0.f) { - // compute direction outside the portal (from v0 throught v1,v2,v3 - // face) - b3PortalDir(portal, &dir); - - // test if origin is inside the portal - if (portalEncapsulesOrigin(portal, &dir)) - return 0; - - // get next support point - - b3MprSupport(pairIndex,bodyIndexA,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices, sepAxis,&dir, &v4); - - - // test if v4 can expand portal to contain origin and if portal - // expanding doesn't reach given tolerance - if (!portalCanEncapsuleOrigin(portal, &v4, &dir) - || portalReachTolerance(portal, &v4, &dir)) + dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 2)->v, &v4v0); + if (dot > 0.f) { - return -1; - } + b3MprSimplexSet(portal, 1, v4); + } + else + { + b3MprSimplexSet(portal, 3, v4); + } + } + else + { + dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 3)->v, &v4v0); + if (dot > 0.f) + { + b3MprSimplexSet(portal, 2, v4); + } + else + { + b3MprSimplexSet(portal, 1, v4); + } + } +} - // v1-v2-v3 triangle must be rearranged to face outside Minkowski - // difference (direction from v0). - b3ExpandPortal(portal, &v4); - } +B3_STATIC int b3DiscoverPortal(int pairIndex, int bodyIndexA, int bodyIndexB, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, + b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, + b3ConstArray(b3Collidable_t) cpuCollidables, + b3ConstArray(b3Float4) cpuVertices, + __global b3Float4 *sepAxis, + __global int *hasSepAxis, + b3MprSimplex_t *portal) +{ + b3Float4 dir, va, vb; + float dot; + int cont; - return -1; + // vertex 0 is center of portal + b3FindOrigin(bodyIndexA, bodyIndexB, cpuBodyBuf, b3MprSimplexPointW(portal, 0)); + // vertex 0 is center of portal + b3MprSimplexSetSize(portal, 1); + + b3Float4 zero = b3MakeFloat4(0, 0, 0, 0); + b3Float4 *b3mpr_vec3_origin = &zero; + + if (b3MprVec3Eq(&b3MprSimplexPoint(portal, 0)->v, b3mpr_vec3_origin)) + { + // Portal's center lies on origin (0,0,0) => we know that objects + // intersect but we would need to know penetration info. + // So move center little bit... + b3MprVec3Set(&va, FLT_EPSILON * 10.f, 0.f, 0.f); + b3MprVec3Add(&b3MprSimplexPointW(portal, 0)->v, &va); + } + + // vertex 1 = support in direction of origin + b3MprVec3Copy(&dir, &b3MprSimplexPoint(portal, 0)->v); + b3MprVec3Scale(&dir, -1.f); + b3MprVec3Normalize(&dir); + + b3MprSupport(pairIndex, bodyIndexA, bodyIndexB, cpuBodyBuf, cpuConvexData, cpuCollidables, cpuVertices, sepAxis, &dir, b3MprSimplexPointW(portal, 1)); + + b3MprSimplexSetSize(portal, 2); + + // test if origin isn't outside of v1 + dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 1)->v, &dir); + + if (b3MprIsZero(dot) || dot < 0.f) + return -1; + + // vertex 2 + b3MprVec3Cross(&dir, &b3MprSimplexPoint(portal, 0)->v, + &b3MprSimplexPoint(portal, 1)->v); + if (b3MprIsZero(b3MprVec3Len2(&dir))) + { + if (b3MprVec3Eq(&b3MprSimplexPoint(portal, 1)->v, b3mpr_vec3_origin)) + { + // origin lies on v1 + return 1; + } + else + { + // origin lies on v0-v1 segment + return 2; + } + } + + b3MprVec3Normalize(&dir); + b3MprSupport(pairIndex, bodyIndexA, bodyIndexB, cpuBodyBuf, cpuConvexData, cpuCollidables, cpuVertices, sepAxis, &dir, b3MprSimplexPointW(portal, 2)); + + dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 2)->v, &dir); + if (b3MprIsZero(dot) || dot < 0.f) + return -1; + + b3MprSimplexSetSize(portal, 3); + + // vertex 3 direction + b3MprVec3Sub2(&va, &b3MprSimplexPoint(portal, 1)->v, + &b3MprSimplexPoint(portal, 0)->v); + b3MprVec3Sub2(&vb, &b3MprSimplexPoint(portal, 2)->v, + &b3MprSimplexPoint(portal, 0)->v); + b3MprVec3Cross(&dir, &va, &vb); + b3MprVec3Normalize(&dir); + + // it is better to form portal faces to be oriented "outside" origin + dot = b3MprVec3Dot(&dir, &b3MprSimplexPoint(portal, 0)->v); + if (dot > 0.f) + { + b3MprSimplexSwap(portal, 1, 2); + b3MprVec3Scale(&dir, -1.f); + } + + while (b3MprSimplexSize(portal) < 4) + { + b3MprSupport(pairIndex, bodyIndexA, bodyIndexB, cpuBodyBuf, cpuConvexData, cpuCollidables, cpuVertices, sepAxis, &dir, b3MprSimplexPointW(portal, 3)); + + dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 3)->v, &dir); + if (b3MprIsZero(dot) || dot < 0.f) + return -1; + + cont = 0; + + // test if origin is outside (v1, v0, v3) - set v2 as v3 and + // continue + b3MprVec3Cross(&va, &b3MprSimplexPoint(portal, 1)->v, + &b3MprSimplexPoint(portal, 3)->v); + dot = b3MprVec3Dot(&va, &b3MprSimplexPoint(portal, 0)->v); + if (dot < 0.f && !b3MprIsZero(dot)) + { + b3MprSimplexSet(portal, 2, b3MprSimplexPoint(portal, 3)); + cont = 1; + } + + if (!cont) + { + // test if origin is outside (v3, v0, v2) - set v1 as v3 and + // continue + b3MprVec3Cross(&va, &b3MprSimplexPoint(portal, 3)->v, + &b3MprSimplexPoint(portal, 2)->v); + dot = b3MprVec3Dot(&va, &b3MprSimplexPoint(portal, 0)->v); + if (dot < 0.f && !b3MprIsZero(dot)) + { + b3MprSimplexSet(portal, 1, b3MprSimplexPoint(portal, 3)); + cont = 1; + } + } + + if (cont) + { + b3MprVec3Sub2(&va, &b3MprSimplexPoint(portal, 1)->v, + &b3MprSimplexPoint(portal, 0)->v); + b3MprVec3Sub2(&vb, &b3MprSimplexPoint(portal, 2)->v, + &b3MprSimplexPoint(portal, 0)->v); + b3MprVec3Cross(&dir, &va, &vb); + b3MprVec3Normalize(&dir); + } + else + { + b3MprSimplexSetSize(portal, 4); + } + } + + return 0; +} + +B3_STATIC int b3RefinePortal(int pairIndex, int bodyIndexA, int bodyIndexB, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, + b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, + b3ConstArray(b3Collidable_t) cpuCollidables, + b3ConstArray(b3Float4) cpuVertices, + __global b3Float4 *sepAxis, + b3MprSimplex_t *portal) +{ + b3Float4 dir; + b3MprSupport_t v4; + + for (int i = 0; i < B3_MPR_MAX_ITERATIONS; i++) + //while (1) + { + // compute direction outside the portal (from v0 throught v1,v2,v3 + // face) + b3PortalDir(portal, &dir); + + // test if origin is inside the portal + if (portalEncapsulesOrigin(portal, &dir)) + return 0; + + // get next support point + + b3MprSupport(pairIndex, bodyIndexA, bodyIndexB, cpuBodyBuf, cpuConvexData, cpuCollidables, cpuVertices, sepAxis, &dir, &v4); + + // test if v4 can expand portal to contain origin and if portal + // expanding doesn't reach given tolerance + if (!portalCanEncapsuleOrigin(portal, &v4, &dir) || portalReachTolerance(portal, &v4, &dir)) + { + return -1; + } + + // v1-v2-v3 triangle must be rearranged to face outside Minkowski + // difference (direction from v0). + b3ExpandPortal(portal, &v4); + } + + return -1; } B3_STATIC void b3FindPos(const b3MprSimplex_t *portal, b3Float4 *pos) { + b3Float4 zero = b3MakeFloat4(0, 0, 0, 0); + b3Float4 *b3mpr_vec3_origin = &zero; - b3Float4 zero = b3MakeFloat4(0,0,0,0); - b3Float4* b3mpr_vec3_origin = &zero; + b3Float4 dir; + size_t i; + float b[4], sum, inv; + b3Float4 vec, p1, p2; - b3Float4 dir; - size_t i; - float b[4], sum, inv; - b3Float4 vec, p1, p2; + b3PortalDir(portal, &dir); - b3PortalDir(portal, &dir); + // use barycentric coordinates of tetrahedron to find origin + b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 1)->v, + &b3MprSimplexPoint(portal, 2)->v); + b[0] = b3MprVec3Dot(&vec, &b3MprSimplexPoint(portal, 3)->v); - // use barycentric coordinates of tetrahedron to find origin - b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 1)->v, - &b3MprSimplexPoint(portal, 2)->v); - b[0] = b3MprVec3Dot(&vec, &b3MprSimplexPoint(portal, 3)->v); + b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 3)->v, + &b3MprSimplexPoint(portal, 2)->v); + b[1] = b3MprVec3Dot(&vec, &b3MprSimplexPoint(portal, 0)->v); - b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 3)->v, - &b3MprSimplexPoint(portal, 2)->v); - b[1] = b3MprVec3Dot(&vec, &b3MprSimplexPoint(portal, 0)->v); + b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 0)->v, + &b3MprSimplexPoint(portal, 1)->v); + b[2] = b3MprVec3Dot(&vec, &b3MprSimplexPoint(portal, 3)->v); - b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 0)->v, - &b3MprSimplexPoint(portal, 1)->v); - b[2] = b3MprVec3Dot(&vec, &b3MprSimplexPoint(portal, 3)->v); - - b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 2)->v, - &b3MprSimplexPoint(portal, 1)->v); - b[3] = b3MprVec3Dot(&vec, &b3MprSimplexPoint(portal, 0)->v); + b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 2)->v, + &b3MprSimplexPoint(portal, 1)->v); + b[3] = b3MprVec3Dot(&vec, &b3MprSimplexPoint(portal, 0)->v); sum = b[0] + b[1] + b[2] + b[3]; - if (b3MprIsZero(sum) || sum < 0.f){ + if (b3MprIsZero(sum) || sum < 0.f) + { b[0] = 0.f; - b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 2)->v, - &b3MprSimplexPoint(portal, 3)->v); - b[1] = b3MprVec3Dot(&vec, &dir); - b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 3)->v, - &b3MprSimplexPoint(portal, 1)->v); - b[2] = b3MprVec3Dot(&vec, &dir); - b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 1)->v, - &b3MprSimplexPoint(portal, 2)->v); - b[3] = b3MprVec3Dot(&vec, &dir); + b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 2)->v, + &b3MprSimplexPoint(portal, 3)->v); + b[1] = b3MprVec3Dot(&vec, &dir); + b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 3)->v, + &b3MprSimplexPoint(portal, 1)->v); + b[2] = b3MprVec3Dot(&vec, &dir); + b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 1)->v, + &b3MprSimplexPoint(portal, 2)->v); + b[3] = b3MprVec3Dot(&vec, &dir); sum = b[1] + b[2] + b[3]; } inv = 1.f / sum; - b3MprVec3Copy(&p1, b3mpr_vec3_origin); - b3MprVec3Copy(&p2, b3mpr_vec3_origin); - for (i = 0; i < 4; i++){ - b3MprVec3Copy(&vec, &b3MprSimplexPoint(portal, i)->v1); - b3MprVec3Scale(&vec, b[i]); - b3MprVec3Add(&p1, &vec); + b3MprVec3Copy(&p1, b3mpr_vec3_origin); + b3MprVec3Copy(&p2, b3mpr_vec3_origin); + for (i = 0; i < 4; i++) + { + b3MprVec3Copy(&vec, &b3MprSimplexPoint(portal, i)->v1); + b3MprVec3Scale(&vec, b[i]); + b3MprVec3Add(&p1, &vec); - b3MprVec3Copy(&vec, &b3MprSimplexPoint(portal, i)->v2); - b3MprVec3Scale(&vec, b[i]); - b3MprVec3Add(&p2, &vec); - } - b3MprVec3Scale(&p1, inv); - b3MprVec3Scale(&p2, inv); + b3MprVec3Copy(&vec, &b3MprSimplexPoint(portal, i)->v2); + b3MprVec3Scale(&vec, b[i]); + b3MprVec3Add(&p2, &vec); + } + b3MprVec3Scale(&p1, inv); + b3MprVec3Scale(&p2, inv); - b3MprVec3Copy(pos, &p1); - b3MprVec3Add(pos, &p2); - b3MprVec3Scale(pos, 0.5); + b3MprVec3Copy(pos, &p1); + b3MprVec3Add(pos, &p2); + b3MprVec3Scale(pos, 0.5); } inline float b3MprVec3Dist2(const b3Float4 *a, const b3Float4 *b) { - b3Float4 ab; - b3MprVec3Sub2(&ab, a, b); - return b3MprVec3Len2(&ab); + b3Float4 ab; + b3MprVec3Sub2(&ab, a, b); + return b3MprVec3Len2(&ab); } inline float _b3MprVec3PointSegmentDist2(const b3Float4 *P, - const b3Float4 *x0, - const b3Float4 *b, - b3Float4 *witness) + const b3Float4 *x0, + const b3Float4 *b, + b3Float4 *witness) { - // The computation comes from solving equation of segment: - // S(t) = x0 + t.d - // where - x0 is initial point of segment - // - d is direction of segment from x0 (|d| > 0) - // - t belongs to <0, 1> interval - // - // Than, distance from a segment to some point P can be expressed: - // D(t) = |x0 + t.d - P|^2 - // which is distance from any point on segment. Minimization - // of this function brings distance from P to segment. - // Minimization of D(t) leads to simple quadratic equation that's - // solving is straightforward. - // - // Bonus of this method is witness point for free. + // The computation comes from solving equation of segment: + // S(t) = x0 + t.d + // where - x0 is initial point of segment + // - d is direction of segment from x0 (|d| > 0) + // - t belongs to <0, 1> interval + // + // Than, distance from a segment to some point P can be expressed: + // D(t) = |x0 + t.d - P|^2 + // which is distance from any point on segment. Minimization + // of this function brings distance from P to segment. + // Minimization of D(t) leads to simple quadratic equation that's + // solving is straightforward. + // + // Bonus of this method is witness point for free. - float dist, t; - b3Float4 d, a; + float dist, t; + b3Float4 d, a; - // direction of segment - b3MprVec3Sub2(&d, b, x0); + // direction of segment + b3MprVec3Sub2(&d, b, x0); - // precompute vector from P to x0 - b3MprVec3Sub2(&a, x0, P); + // precompute vector from P to x0 + b3MprVec3Sub2(&a, x0, P); - t = -1.f * b3MprVec3Dot(&a, &d); - t /= b3MprVec3Len2(&d); + t = -1.f * b3MprVec3Dot(&a, &d); + t /= b3MprVec3Len2(&d); - if (t < 0.f || b3MprIsZero(t)){ - dist = b3MprVec3Dist2(x0, P); - if (witness) - b3MprVec3Copy(witness, x0); - }else if (t > 1.f || b3MprEq(t, 1.f)){ - dist = b3MprVec3Dist2(b, P); - if (witness) - b3MprVec3Copy(witness, b); - }else{ - if (witness){ - b3MprVec3Copy(witness, &d); - b3MprVec3Scale(witness, t); - b3MprVec3Add(witness, x0); - dist = b3MprVec3Dist2(witness, P); - }else{ - // recycling variables - b3MprVec3Scale(&d, t); - b3MprVec3Add(&d, &a); - dist = b3MprVec3Len2(&d); - } - } + if (t < 0.f || b3MprIsZero(t)) + { + dist = b3MprVec3Dist2(x0, P); + if (witness) + b3MprVec3Copy(witness, x0); + } + else if (t > 1.f || b3MprEq(t, 1.f)) + { + dist = b3MprVec3Dist2(b, P); + if (witness) + b3MprVec3Copy(witness, b); + } + else + { + if (witness) + { + b3MprVec3Copy(witness, &d); + b3MprVec3Scale(witness, t); + b3MprVec3Add(witness, x0); + dist = b3MprVec3Dist2(witness, P); + } + else + { + // recycling variables + b3MprVec3Scale(&d, t); + b3MprVec3Add(&d, &a); + dist = b3MprVec3Len2(&d); + } + } - return dist; + return dist; } - inline float b3MprVec3PointTriDist2(const b3Float4 *P, - const b3Float4 *x0, const b3Float4 *B, - const b3Float4 *C, - b3Float4 *witness) + const b3Float4 *x0, const b3Float4 *B, + const b3Float4 *C, + b3Float4 *witness) { - // Computation comes from analytic expression for triangle (x0, B, C) - // T(s, t) = x0 + s.d1 + t.d2, where d1 = B - x0 and d2 = C - x0 and - // Then equation for distance is: - // D(s, t) = | T(s, t) - P |^2 - // This leads to minimization of quadratic function of two variables. - // The solution from is taken only if s is between 0 and 1, t is - // between 0 and 1 and t + s < 1, otherwise distance from segment is - // computed. + // Computation comes from analytic expression for triangle (x0, B, C) + // T(s, t) = x0 + s.d1 + t.d2, where d1 = B - x0 and d2 = C - x0 and + // Then equation for distance is: + // D(s, t) = | T(s, t) - P |^2 + // This leads to minimization of quadratic function of two variables. + // The solution from is taken only if s is between 0 and 1, t is + // between 0 and 1 and t + s < 1, otherwise distance from segment is + // computed. - b3Float4 d1, d2, a; - float u, v, w, p, q, r; - float s, t, dist, dist2; - b3Float4 witness2; + b3Float4 d1, d2, a; + float u, v, w, p, q, r; + float s, t, dist, dist2; + b3Float4 witness2; - b3MprVec3Sub2(&d1, B, x0); - b3MprVec3Sub2(&d2, C, x0); - b3MprVec3Sub2(&a, x0, P); + b3MprVec3Sub2(&d1, B, x0); + b3MprVec3Sub2(&d2, C, x0); + b3MprVec3Sub2(&a, x0, P); - u = b3MprVec3Dot(&a, &a); - v = b3MprVec3Dot(&d1, &d1); - w = b3MprVec3Dot(&d2, &d2); - p = b3MprVec3Dot(&a, &d1); - q = b3MprVec3Dot(&a, &d2); - r = b3MprVec3Dot(&d1, &d2); + u = b3MprVec3Dot(&a, &a); + v = b3MprVec3Dot(&d1, &d1); + w = b3MprVec3Dot(&d2, &d2); + p = b3MprVec3Dot(&a, &d1); + q = b3MprVec3Dot(&a, &d2); + r = b3MprVec3Dot(&d1, &d2); - s = (q * r - w * p) / (w * v - r * r); - t = (-s * r - q) / w; + s = (q * r - w * p) / (w * v - r * r); + t = (-s * r - q) / w; - if ((b3MprIsZero(s) || s > 0.f) - && (b3MprEq(s, 1.f) || s < 1.f) - && (b3MprIsZero(t) || t > 0.f) - && (b3MprEq(t, 1.f) || t < 1.f) - && (b3MprEq(t + s, 1.f) || t + s < 1.f)){ + if ((b3MprIsZero(s) || s > 0.f) && (b3MprEq(s, 1.f) || s < 1.f) && (b3MprIsZero(t) || t > 0.f) && (b3MprEq(t, 1.f) || t < 1.f) && (b3MprEq(t + s, 1.f) || t + s < 1.f)) + { + if (witness) + { + b3MprVec3Scale(&d1, s); + b3MprVec3Scale(&d2, t); + b3MprVec3Copy(witness, x0); + b3MprVec3Add(witness, &d1); + b3MprVec3Add(witness, &d2); - if (witness){ - b3MprVec3Scale(&d1, s); - b3MprVec3Scale(&d2, t); - b3MprVec3Copy(witness, x0); - b3MprVec3Add(witness, &d1); - b3MprVec3Add(witness, &d2); + dist = b3MprVec3Dist2(witness, P); + } + else + { + dist = s * s * v; + dist += t * t * w; + dist += 2.f * s * t * r; + dist += 2.f * s * p; + dist += 2.f * t * q; + dist += u; + } + } + else + { + dist = _b3MprVec3PointSegmentDist2(P, x0, B, witness); - dist = b3MprVec3Dist2(witness, P); - }else{ - dist = s * s * v; - dist += t * t * w; - dist += 2.f * s * t * r; - dist += 2.f * s * p; - dist += 2.f * t * q; - dist += u; - } - }else{ - dist = _b3MprVec3PointSegmentDist2(P, x0, B, witness); + dist2 = _b3MprVec3PointSegmentDist2(P, x0, C, &witness2); + if (dist2 < dist) + { + dist = dist2; + if (witness) + b3MprVec3Copy(witness, &witness2); + } - dist2 = _b3MprVec3PointSegmentDist2(P, x0, C, &witness2); - if (dist2 < dist){ - dist = dist2; - if (witness) - b3MprVec3Copy(witness, &witness2); - } + dist2 = _b3MprVec3PointSegmentDist2(P, B, C, &witness2); + if (dist2 < dist) + { + dist = dist2; + if (witness) + b3MprVec3Copy(witness, &witness2); + } + } - dist2 = _b3MprVec3PointSegmentDist2(P, B, C, &witness2); - if (dist2 < dist){ - dist = dist2; - if (witness) - b3MprVec3Copy(witness, &witness2); - } - } - - return dist; + return dist; } - -B3_STATIC void b3FindPenetr(int pairIndex,int bodyIndexA, int bodyIndexB, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, - b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, - b3ConstArray(b3Collidable_t) cpuCollidables, - b3ConstArray(b3Float4) cpuVertices, - __global b3Float4* sepAxis, - b3MprSimplex_t *portal, - float *depth, b3Float4 *pdir, b3Float4 *pos) +B3_STATIC void b3FindPenetr(int pairIndex, int bodyIndexA, int bodyIndexB, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, + b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, + b3ConstArray(b3Collidable_t) cpuCollidables, + b3ConstArray(b3Float4) cpuVertices, + __global b3Float4 *sepAxis, + b3MprSimplex_t *portal, + float *depth, b3Float4 *pdir, b3Float4 *pos) { - b3Float4 dir; - b3MprSupport_t v4; - unsigned long iterations; + b3Float4 dir; + b3MprSupport_t v4; + unsigned long iterations; - b3Float4 zero = b3MakeFloat4(0,0,0,0); - b3Float4* b3mpr_vec3_origin = &zero; + b3Float4 zero = b3MakeFloat4(0, 0, 0, 0); + b3Float4 *b3mpr_vec3_origin = &zero; - - iterations = 1UL; - for (int i=0;i find penetration info - if (portalReachTolerance(portal, &v4, &dir) - || iterations ==B3_MPR_MAX_ITERATIONS) + // reached tolerance -> find penetration info + if (portalReachTolerance(portal, &v4, &dir) || iterations == B3_MPR_MAX_ITERATIONS) { - *depth = b3MprVec3PointTriDist2(b3mpr_vec3_origin,&b3MprSimplexPoint(portal, 1)->v,&b3MprSimplexPoint(portal, 2)->v,&b3MprSimplexPoint(portal, 3)->v,pdir); - *depth = B3_MPR_SQRT(*depth); - + *depth = b3MprVec3PointTriDist2(b3mpr_vec3_origin, &b3MprSimplexPoint(portal, 1)->v, &b3MprSimplexPoint(portal, 2)->v, &b3MprSimplexPoint(portal, 3)->v, pdir); + *depth = B3_MPR_SQRT(*depth); + if (b3MprIsZero((*pdir).x) && b3MprIsZero((*pdir).y) && b3MprIsZero((*pdir).z)) { - *pdir = dir; - } + } b3MprVec3Normalize(pdir); - - // barycentric coordinates: - b3FindPos(portal, pos); + // barycentric coordinates: + b3FindPos(portal, pos); - return; - } + return; + } - b3ExpandPortal(portal, &v4); + b3ExpandPortal(portal, &v4); - iterations++; - } + iterations++; + } } -B3_STATIC void b3FindPenetrTouch(b3MprSimplex_t *portal,float *depth, b3Float4 *dir, b3Float4 *pos) +B3_STATIC void b3FindPenetrTouch(b3MprSimplex_t *portal, float *depth, b3Float4 *dir, b3Float4 *pos) { - // Touching contact on portal's v1 - so depth is zero and direction - // is unimportant and pos can be guessed - *depth = 0.f; - b3Float4 zero = b3MakeFloat4(0,0,0,0); - b3Float4* b3mpr_vec3_origin = &zero; - + // Touching contact on portal's v1 - so depth is zero and direction + // is unimportant and pos can be guessed + *depth = 0.f; + b3Float4 zero = b3MakeFloat4(0, 0, 0, 0); + b3Float4 *b3mpr_vec3_origin = &zero; b3MprVec3Copy(dir, b3mpr_vec3_origin); - b3MprVec3Copy(pos, &b3MprSimplexPoint(portal, 1)->v1); - b3MprVec3Add(pos, &b3MprSimplexPoint(portal, 1)->v2); - b3MprVec3Scale(pos, 0.5); + b3MprVec3Copy(pos, &b3MprSimplexPoint(portal, 1)->v1); + b3MprVec3Add(pos, &b3MprSimplexPoint(portal, 1)->v2); + b3MprVec3Scale(pos, 0.5); } B3_STATIC void b3FindPenetrSegment(b3MprSimplex_t *portal, - float *depth, b3Float4 *dir, b3Float4 *pos) + float *depth, b3Float4 *dir, b3Float4 *pos) { - - // Origin lies on v0-v1 segment. - // Depth is distance to v1, direction also and position must be - // computed + // Origin lies on v0-v1 segment. + // Depth is distance to v1, direction also and position must be + // computed - b3MprVec3Copy(pos, &b3MprSimplexPoint(portal, 1)->v1); - b3MprVec3Add(pos, &b3MprSimplexPoint(portal, 1)->v2); - b3MprVec3Scale(pos, 0.5f); + b3MprVec3Copy(pos, &b3MprSimplexPoint(portal, 1)->v1); + b3MprVec3Add(pos, &b3MprSimplexPoint(portal, 1)->v2); + b3MprVec3Scale(pos, 0.5f); - - b3MprVec3Copy(dir, &b3MprSimplexPoint(portal, 1)->v); - *depth = B3_MPR_SQRT(b3MprVec3Len2(dir)); - b3MprVec3Normalize(dir); + b3MprVec3Copy(dir, &b3MprSimplexPoint(portal, 1)->v); + *depth = B3_MPR_SQRT(b3MprVec3Len2(dir)); + b3MprVec3Normalize(dir); } - - inline int b3MprPenetration(int pairIndex, int bodyIndexA, int bodyIndexB, - b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, - b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, - b3ConstArray(b3Collidable_t) cpuCollidables, - b3ConstArray(b3Float4) cpuVertices, - __global b3Float4* sepAxis, - __global int* hasSepAxis, - float *depthOut, b3Float4* dirOut, b3Float4* posOut) + b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, + b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, + b3ConstArray(b3Collidable_t) cpuCollidables, + b3ConstArray(b3Float4) cpuVertices, + __global b3Float4 *sepAxis, + __global int *hasSepAxis, + float *depthOut, b3Float4 *dirOut, b3Float4 *posOut) { - - b3MprSimplex_t portal; + b3MprSimplex_t portal; - -// if (!hasSepAxis[pairIndex]) + // if (!hasSepAxis[pairIndex]) // return -1; - - hasSepAxis[pairIndex] = 0; - int res; - // Phase 1: Portal discovery - res = b3DiscoverPortal(pairIndex,bodyIndexA,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices,sepAxis,hasSepAxis, &portal); - - + hasSepAxis[pairIndex] = 0; + int res; + + // Phase 1: Portal discovery + res = b3DiscoverPortal(pairIndex, bodyIndexA, bodyIndexB, cpuBodyBuf, cpuConvexData, cpuCollidables, cpuVertices, sepAxis, hasSepAxis, &portal); + //sepAxis[pairIndex] = *pdir;//or -dir? switch (res) { - case 0: + case 0: { // Phase 2: Portal refinement - - res = b3RefinePortal(pairIndex,bodyIndexA,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices, sepAxis,&portal); + + res = b3RefinePortal(pairIndex, bodyIndexA, bodyIndexB, cpuBodyBuf, cpuConvexData, cpuCollidables, cpuVertices, sepAxis, &portal); if (res < 0) return -1; // Phase 3. Penetration info - b3FindPenetr(pairIndex,bodyIndexA,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices, sepAxis,&portal, depthOut, dirOut, posOut); + b3FindPenetr(pairIndex, bodyIndexA, bodyIndexB, cpuBodyBuf, cpuConvexData, cpuCollidables, cpuVertices, sepAxis, &portal, depthOut, dirOut, posOut); hasSepAxis[pairIndex] = 1; sepAxis[pairIndex] = -*dirOut; break; } - case 1: + case 1: { - // Touching contact on portal's v1. + // Touching contact on portal's v1. b3FindPenetrTouch(&portal, depthOut, dirOut, posOut); break; } - case 2: + case 2: { - - b3FindPenetrSegment( &portal, depthOut, dirOut, posOut); + b3FindPenetrSegment(&portal, depthOut, dirOut, posOut); break; } - default: + default: { - hasSepAxis[pairIndex]=0; + hasSepAxis[pairIndex] = 0; //if (res < 0) //{ - // Origin isn't inside portal - no collision. - return -1; + // Origin isn't inside portal - no collision. + return -1; //} } }; - + return 0; }; - - -#endif //B3_MPR_PENETRATION_H +#endif //B3_MPR_PENETRATION_H diff --git a/src/Bullet3Collision/NarrowPhaseCollision/shared/b3NewContactReduction.h b/src/Bullet3Collision/NarrowPhaseCollision/shared/b3NewContactReduction.h index 718222ebc..6e991e14b 100644 --- a/src/Bullet3Collision/NarrowPhaseCollision/shared/b3NewContactReduction.h +++ b/src/Bullet3Collision/NarrowPhaseCollision/shared/b3NewContactReduction.h @@ -8,189 +8,168 @@ #define GET_NPOINTS(x) (x).m_worldNormalOnB.w - int b3ExtractManifoldSequentialGlobal(__global const b3Float4* p, int nPoints, b3Float4ConstArg nearNormal, b3Int4* contactIdx) { - if( nPoints == 0 ) - return 0; - - if (nPoints <=4) - return nPoints; - - - if (nPoints >64) - nPoints = 64; - - b3Float4 center = b3MakeFloat4(0,0,0,0); + if (nPoints == 0) + return 0; + + if (nPoints <= 4) + return nPoints; + + if (nPoints > 64) + nPoints = 64; + + b3Float4 center = b3MakeFloat4(0, 0, 0, 0); { - - for (int i=0;i0) - { - __global b3Float4* pointsIn = &worldVertsB2[pairIndex*vertexFaceCapacity]; - b3Float4 normal = -separatingNormals[i]; - - int nReducedContacts = b3ExtractManifoldSequentialGlobal(pointsIn, nPoints, normal, &contactIdx); - - int dstIdx; - dstIdx = b3AtomicInc( nGlobalContactsOut); - -//#if 0 - b3Assert(dstIdx < contactCapacity); + if (nPoints > 0) + { + __global b3Float4* pointsIn = &worldVertsB2[pairIndex * vertexFaceCapacity]; + b3Float4 normal = -separatingNormals[i]; + + int nReducedContacts = b3ExtractManifoldSequentialGlobal(pointsIn, nPoints, normal, &contactIdx); + + int dstIdx; + dstIdx = b3AtomicInc(nGlobalContactsOut); + + //#if 0 + b3Assert(dstIdx < contactCapacity); if (dstIdx < contactCapacity) { - __global struct b3Contact4Data* c = &globalContactsOut[dstIdx]; c->m_worldNormalOnB = -normal; - c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff); + c->m_restituitionCoeffCmp = (0.f * 0xffff); + c->m_frictionCoeffCmp = (0.7f * 0xffff); c->m_batchIdx = pairIndex; int bodyA = pairs[pairIndex].x; int bodyB = pairs[pairIndex].y; pairs[pairIndex].w = dstIdx; - c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA; - c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB; - c->m_childIndexA =-1; - c->m_childIndexB =-1; + c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass == 0 ? -bodyA : bodyA; + c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass == 0 ? -bodyB : bodyB; + c->m_childIndexA = -1; + c->m_childIndexB = -1; + + switch (nReducedContacts) + { + case 4: + c->m_worldPosB[3] = pointsIn[contactIdx.w]; + case 3: + c->m_worldPosB[2] = pointsIn[contactIdx.z]; + case 2: + c->m_worldPosB[1] = pointsIn[contactIdx.y]; + case 1: + c->m_worldPosB[0] = pointsIn[contactIdx.x]; + default: + { + } + }; - switch (nReducedContacts) - { - case 4: - c->m_worldPosB[3] = pointsIn[contactIdx.w]; - case 3: - c->m_worldPosB[2] = pointsIn[contactIdx.z]; - case 2: - c->m_worldPosB[1] = pointsIn[contactIdx.y]; - case 1: - c->m_worldPosB[0] = pointsIn[contactIdx.x]; - default: - { - } - }; - GET_NPOINTS(*c) = nReducedContacts; - - } - - -//#endif - - }// if (numContactsOut>0) - }// if (hasSeparatingAxis[i]) - }// if (i0) + } // if (hasSeparatingAxis[i]) + } // if (im_escapeIndexOrTriangleIndex&~(y)); + return (rootNode->m_escapeIndexOrTriangleIndex & ~(y)); } inline int b3IsLeaf(const b3QuantizedBvhNodeData* rootNode) { //skipindex is negative (internal node), triangleindex >=0 (leafnode) - return (rootNode->m_escapeIndexOrTriangleIndex >= 0)? 1 : 0; + return (rootNode->m_escapeIndexOrTriangleIndex >= 0) ? 1 : 0; } - + inline int b3GetEscapeIndex(const b3QuantizedBvhNodeData* rootNode) { return -rootNode->m_escapeIndexOrTriangleIndex; } -inline void b3QuantizeWithClamp(unsigned short* out, b3Float4ConstArg point2,int isMax, b3Float4ConstArg bvhAabbMin, b3Float4ConstArg bvhAabbMax, b3Float4ConstArg bvhQuantization) +inline void b3QuantizeWithClamp(unsigned short* out, b3Float4ConstArg point2, int isMax, b3Float4ConstArg bvhAabbMin, b3Float4ConstArg bvhAabbMax, b3Float4ConstArg bvhQuantization) { - b3Float4 clampedPoint = b3MaxFloat4(point2,bvhAabbMin); - clampedPoint = b3MinFloat4 (clampedPoint, bvhAabbMax); + b3Float4 clampedPoint = b3MaxFloat4(point2, bvhAabbMin); + clampedPoint = b3MinFloat4(clampedPoint, bvhAabbMax); b3Float4 v = (clampedPoint - bvhAabbMin) * bvhQuantization; if (isMax) { - out[0] = (unsigned short) (((unsigned short)(v.x+1.f) | 1)); - out[1] = (unsigned short) (((unsigned short)(v.y+1.f) | 1)); - out[2] = (unsigned short) (((unsigned short)(v.z+1.f) | 1)); - } else - { - out[0] = (unsigned short) (((unsigned short)(v.x) & 0xfffe)); - out[1] = (unsigned short) (((unsigned short)(v.y) & 0xfffe)); - out[2] = (unsigned short) (((unsigned short)(v.z) & 0xfffe)); + out[0] = (unsigned short)(((unsigned short)(v.x + 1.f) | 1)); + out[1] = (unsigned short)(((unsigned short)(v.y + 1.f) | 1)); + out[2] = (unsigned short)(((unsigned short)(v.z + 1.f) | 1)); + } + else + { + out[0] = (unsigned short)(((unsigned short)(v.x) & 0xfffe)); + out[1] = (unsigned short)(((unsigned short)(v.y) & 0xfffe)); + out[2] = (unsigned short)(((unsigned short)(v.z) & 0xfffe)); } - } - inline int b3TestQuantizedAabbAgainstQuantizedAabbSlow( - const unsigned short int* aabbMin1, - const unsigned short int* aabbMax1, - const unsigned short int* aabbMin2, - const unsigned short int* aabbMax2) + const unsigned short int* aabbMin1, + const unsigned short int* aabbMax1, + const unsigned short int* aabbMin2, + const unsigned short int* aabbMax2) { //int overlap = 1; if (aabbMin1[0] > aabbMax2[0]) @@ -86,5 +85,4 @@ inline int b3TestQuantizedAabbAgainstQuantizedAabbSlow( //return overlap; } - -#endif //B3_QUANTIZED_BVH_NODE_H +#endif //B3_QUANTIZED_BVH_NODE_H diff --git a/src/Bullet3Collision/NarrowPhaseCollision/shared/b3ReduceContacts.h b/src/Bullet3Collision/NarrowPhaseCollision/shared/b3ReduceContacts.h index 35b519700..c108255b9 100644 --- a/src/Bullet3Collision/NarrowPhaseCollision/shared/b3ReduceContacts.h +++ b/src/Bullet3Collision/NarrowPhaseCollision/shared/b3ReduceContacts.h @@ -3,95 +3,87 @@ inline int b3ReduceContacts(const b3Float4* p, int nPoints, const b3Float4& nearNormal, b3Int4* contactIdx) { - if( nPoints == 0 ) - return 0; - - if (nPoints <=4) - return nPoints; - - - if (nPoints >64) - nPoints = 64; - - b3Float4 center = b3MakeFloat4(0,0,0,0); + if (nPoints == 0) + return 0; + + if (nPoints <= 4) + return nPoints; + + if (nPoints > 64) + nPoints = 64; + + b3Float4 center = b3MakeFloat4(0, 0, 0, 0); { - - for (int i=0;im_pos; - b3Quat orientation = body->m_quat; - + b3Quat orientation = body->m_quat; + int collidableIndex = body->m_collidableIdx; int shapeIndex = collidables[collidableIndex].m_shapeIndex; - - if (shapeIndex>=0) + + if (shapeIndex >= 0) { - b3Aabb_t localAabb = localShapeAABB[collidableIndex]; b3Aabb_t worldAabb; - - b3Float4 aabbAMinOut,aabbAMaxOut; + + b3Float4 aabbAMinOut, aabbAMaxOut; float margin = 0.f; - b3TransformAabb2(localAabb.m_minVec,localAabb.m_maxVec,margin,position,orientation,&aabbAMinOut,&aabbAMaxOut); - - worldAabb.m_minVec =aabbAMinOut; + b3TransformAabb2(localAabb.m_minVec, localAabb.m_maxVec, margin, position, orientation, &aabbAMinOut, &aabbAMaxOut); + + worldAabb.m_minVec = aabbAMinOut; worldAabb.m_minIndices[3] = bodyId; worldAabb.m_maxVec = aabbAMaxOut; - worldAabb.m_signedMaxIndices[3] = body[bodyId].m_invMass==0.f? 0 : 1; + worldAabb.m_signedMaxIndices[3] = body[bodyId].m_invMass == 0.f ? 0 : 1; worldAabbs[bodyId] = worldAabb; } } -#endif //B3_UPDATE_AABBS_H +#endif //B3_UPDATE_AABBS_H diff --git a/src/Bullet3Common/b3AlignedAllocator.cpp b/src/Bullet3Common/b3AlignedAllocator.cpp index b98e2b4d3..6e54c5fb7 100644 --- a/src/Bullet3Common/b3AlignedAllocator.cpp +++ b/src/Bullet3Common/b3AlignedAllocator.cpp @@ -17,7 +17,7 @@ subject to the following restrictions: int b3g_numAlignedAllocs = 0; int b3g_numAlignedFree = 0; -int b3g_totalBytesAlignedAllocs = 0;//detect memory leaks +int b3g_totalBytesAlignedAllocs = 0; //detect memory leaks static void *b3AllocDefault(size_t size) { @@ -29,12 +29,10 @@ static void b3FreeDefault(void *ptr) free(ptr); } -static b3AllocFunc* b3s_allocFunc = b3AllocDefault; -static b3FreeFunc* b3s_freeFunc = b3FreeDefault; +static b3AllocFunc *b3s_allocFunc = b3AllocDefault; +static b3FreeFunc *b3s_freeFunc = b3FreeDefault; - - -#if defined (B3_HAS_ALIGNED_ALLOCATOR) +#if defined(B3_HAS_ALIGNED_ALLOCATOR) #include static void *b3AlignedAllocDefault(size_t size, int alignment) { @@ -59,113 +57,114 @@ static inline void b3AlignedFreeDefault(void *ptr) } #else - - - - static inline void *b3AlignedAllocDefault(size_t size, int alignment) { - void *ret; - char *real; - real = (char *)b3s_allocFunc(size + sizeof(void *) + (alignment-1)); - if (real) { - ret = b3AlignPointer(real + sizeof(void *),alignment); - *((void **)(ret)-1) = (void *)(real); - } else { - ret = (void *)(real); - } - return (ret); + void *ret; + char *real; + real = (char *)b3s_allocFunc(size + sizeof(void *) + (alignment - 1)); + if (real) + { + ret = b3AlignPointer(real + sizeof(void *), alignment); + *((void **)(ret)-1) = (void *)(real); + } + else + { + ret = (void *)(real); + } + return (ret); } static inline void b3AlignedFreeDefault(void *ptr) { - void* real; + void *real; - if (ptr) { - real = *((void **)(ptr)-1); - b3s_freeFunc(real); - } + if (ptr) + { + real = *((void **)(ptr)-1); + b3s_freeFunc(real); + } } #endif - -static b3AlignedAllocFunc* b3s_alignedAllocFunc = b3AlignedAllocDefault; -static b3AlignedFreeFunc* b3s_alignedFreeFunc = b3AlignedFreeDefault; +static b3AlignedAllocFunc *b3s_alignedAllocFunc = b3AlignedAllocDefault; +static b3AlignedFreeFunc *b3s_alignedFreeFunc = b3AlignedFreeDefault; void b3AlignedAllocSetCustomAligned(b3AlignedAllocFunc *allocFunc, b3AlignedFreeFunc *freeFunc) { - b3s_alignedAllocFunc = allocFunc ? allocFunc : b3AlignedAllocDefault; - b3s_alignedFreeFunc = freeFunc ? freeFunc : b3AlignedFreeDefault; + b3s_alignedAllocFunc = allocFunc ? allocFunc : b3AlignedAllocDefault; + b3s_alignedFreeFunc = freeFunc ? freeFunc : b3AlignedFreeDefault; } void b3AlignedAllocSetCustom(b3AllocFunc *allocFunc, b3FreeFunc *freeFunc) { - b3s_allocFunc = allocFunc ? allocFunc : b3AllocDefault; - b3s_freeFunc = freeFunc ? freeFunc : b3FreeDefault; + b3s_allocFunc = allocFunc ? allocFunc : b3AllocDefault; + b3s_freeFunc = freeFunc ? freeFunc : b3FreeDefault; } #ifdef B3_DEBUG_MEMORY_ALLOCATIONS //this generic allocator provides the total allocated number of bytes #include -void* b3AlignedAllocInternal (size_t size, int alignment,int line,char* filename) +void *b3AlignedAllocInternal(size_t size, int alignment, int line, char *filename) { - void *ret; - char *real; + void *ret; + char *real; - b3g_totalBytesAlignedAllocs += size; - b3g_numAlignedAllocs++; + b3g_totalBytesAlignedAllocs += size; + b3g_numAlignedAllocs++; - - real = (char *)b3s_allocFunc(size + 2*sizeof(void *) + (alignment-1)); - if (real) { - ret = (void*) b3AlignPointer(real + 2*sizeof(void *), alignment); - *((void **)(ret)-1) = (void *)(real); - *((int*)(ret)-2) = size; + real = (char *)b3s_allocFunc(size + 2 * sizeof(void *) + (alignment - 1)); + if (real) + { + ret = (void *)b3AlignPointer(real + 2 * sizeof(void *), alignment); + *((void **)(ret)-1) = (void *)(real); + *((int *)(ret)-2) = size; + } + else + { + ret = (void *)(real); //?? + } - } else { - ret = (void *)(real);//?? - } + b3Printf("allocation#%d at address %x, from %s,line %d, size %d\n", b3g_numAlignedAllocs, real, filename, line, size); - b3Printf("allocation#%d at address %x, from %s,line %d, size %d\n",b3g_numAlignedAllocs,real, filename,line,size); - - int* ptr = (int*)ret; - *ptr = 12; - return (ret); + int *ptr = (int *)ret; + *ptr = 12; + return (ret); } -void b3AlignedFreeInternal (void* ptr,int line,char* filename) +void b3AlignedFreeInternal(void *ptr, int line, char *filename) { + void *real; + b3g_numAlignedFree++; - void* real; - b3g_numAlignedFree++; + if (ptr) + { + real = *((void **)(ptr)-1); + int size = *((int *)(ptr)-2); + b3g_totalBytesAlignedAllocs -= size; - if (ptr) { - real = *((void **)(ptr)-1); - int size = *((int*)(ptr)-2); - b3g_totalBytesAlignedAllocs -= size; + b3Printf("free #%d at address %x, from %s,line %d, size %d\n", b3g_numAlignedFree, real, filename, line, size); - b3Printf("free #%d at address %x, from %s,line %d, size %d\n",b3g_numAlignedFree,real, filename,line,size); - - b3s_freeFunc(real); - } else - { - b3Printf("NULL ptr\n"); - } + b3s_freeFunc(real); + } + else + { + b3Printf("NULL ptr\n"); + } } -#else //B3_DEBUG_MEMORY_ALLOCATIONS +#else //B3_DEBUG_MEMORY_ALLOCATIONS -void* b3AlignedAllocInternal (size_t size, int alignment) +void *b3AlignedAllocInternal(size_t size, int alignment) { b3g_numAlignedAllocs++; - void* ptr; + void *ptr; ptr = b3s_alignedAllocFunc(size, alignment); -// b3Printf("b3AlignedAllocInternal %d, %x\n",size,ptr); + // b3Printf("b3AlignedAllocInternal %d, %x\n",size,ptr); return ptr; } -void b3AlignedFreeInternal (void* ptr) +void b3AlignedFreeInternal(void *ptr) { if (!ptr) { @@ -173,9 +172,8 @@ void b3AlignedFreeInternal (void* ptr) } b3g_numAlignedFree++; -// b3Printf("b3AlignedFreeInternal %x\n",ptr); + // b3Printf("b3AlignedFreeInternal %x\n",ptr); b3s_alignedFreeFunc(ptr); } -#endif //B3_DEBUG_MEMORY_ALLOCATIONS - +#endif //B3_DEBUG_MEMORY_ALLOCATIONS diff --git a/src/Bullet3Common/b3AlignedAllocator.h b/src/Bullet3Common/b3AlignedAllocator.h index be418bd55..bcff9f128 100644 --- a/src/Bullet3Common/b3AlignedAllocator.h +++ b/src/Bullet3Common/b3AlignedAllocator.h @@ -24,84 +24,87 @@ subject to the following restrictions: //#define B3_DEBUG_MEMORY_ALLOCATIONS 1 #ifdef B3_DEBUG_MEMORY_ALLOCATIONS -#define b3AlignedAlloc(a,b) \ - b3AlignedAllocInternal(a,b,__LINE__,__FILE__) +#define b3AlignedAlloc(a, b) \ + b3AlignedAllocInternal(a, b, __LINE__, __FILE__) #define b3AlignedFree(ptr) \ - b3AlignedFreeInternal(ptr,__LINE__,__FILE__) + b3AlignedFreeInternal(ptr, __LINE__, __FILE__) -void* b3AlignedAllocInternal (size_t size, int alignment,int line,char* filename); +void* b3AlignedAllocInternal(size_t size, int alignment, int line, char* filename); -void b3AlignedFreeInternal (void* ptr,int line,char* filename); +void b3AlignedFreeInternal(void* ptr, int line, char* filename); #else - void* b3AlignedAllocInternal (size_t size, int alignment); - void b3AlignedFreeInternal (void* ptr); +void* b3AlignedAllocInternal(size_t size, int alignment); +void b3AlignedFreeInternal(void* ptr); - #define b3AlignedAlloc(size,alignment) b3AlignedAllocInternal(size,alignment) - #define b3AlignedFree(ptr) b3AlignedFreeInternal(ptr) +#define b3AlignedAlloc(size, alignment) b3AlignedAllocInternal(size, alignment) +#define b3AlignedFree(ptr) b3AlignedFreeInternal(ptr) #endif -typedef int btSizeType; +typedef int btSizeType; -typedef void *(b3AlignedAllocFunc)(size_t size, int alignment); -typedef void (b3AlignedFreeFunc)(void *memblock); -typedef void *(b3AllocFunc)(size_t size); -typedef void (b3FreeFunc)(void *memblock); +typedef void*(b3AlignedAllocFunc)(size_t size, int alignment); +typedef void(b3AlignedFreeFunc)(void* memblock); +typedef void*(b3AllocFunc)(size_t size); +typedef void(b3FreeFunc)(void* memblock); ///The developer can let all Bullet memory allocations go through a custom memory allocator, using b3AlignedAllocSetCustom -void b3AlignedAllocSetCustom(b3AllocFunc *allocFunc, b3FreeFunc *freeFunc); +void b3AlignedAllocSetCustom(b3AllocFunc* allocFunc, b3FreeFunc* freeFunc); ///If the developer has already an custom aligned allocator, then b3AlignedAllocSetCustomAligned can be used. The default aligned allocator pre-allocates extra memory using the non-aligned allocator, and instruments it. -void b3AlignedAllocSetCustomAligned(b3AlignedAllocFunc *allocFunc, b3AlignedFreeFunc *freeFunc); - +void b3AlignedAllocSetCustomAligned(b3AlignedAllocFunc* allocFunc, b3AlignedFreeFunc* freeFunc); ///The b3AlignedAllocator is a portable class for aligned memory allocations. ///Default implementations for unaligned and aligned allocations can be overridden by a custom allocator using b3AlignedAllocSetCustom and b3AlignedAllocSetCustomAligned. -template < typename T , unsigned Alignment > -class b3AlignedAllocator { - - typedef b3AlignedAllocator< T , Alignment > self_type; - -public: +template +class b3AlignedAllocator +{ + typedef b3AlignedAllocator self_type; +public: //just going down a list: b3AlignedAllocator() {} /* b3AlignedAllocator( const self_type & ) {} */ - template < typename Other > - b3AlignedAllocator( const b3AlignedAllocator< Other , Alignment > & ) {} + template + b3AlignedAllocator(const b3AlignedAllocator&) + { + } - typedef const T* const_pointer; - typedef const T& const_reference; - typedef T* pointer; - typedef T& reference; - typedef T value_type; + typedef const T* const_pointer; + typedef const T& const_reference; + typedef T* pointer; + typedef T& reference; + typedef T value_type; - pointer address ( reference ref ) const { return &ref; } - const_pointer address ( const_reference ref ) const { return &ref; } - pointer allocate ( btSizeType n , const_pointer * hint = 0 ) { + pointer address(reference ref) const { return &ref; } + const_pointer address(const_reference ref) const { return &ref; } + pointer allocate(btSizeType n, const_pointer* hint = 0) + { (void)hint; - return reinterpret_cast< pointer >(b3AlignedAlloc( sizeof(value_type) * n , Alignment )); + return reinterpret_cast(b3AlignedAlloc(sizeof(value_type) * n, Alignment)); } - void construct ( pointer ptr , const value_type & value ) { new (ptr) value_type( value ); } - void deallocate( pointer ptr ) { - b3AlignedFree( reinterpret_cast< void * >( ptr ) ); + void construct(pointer ptr, const value_type& value) { new (ptr) value_type(value); } + void deallocate(pointer ptr) + { + b3AlignedFree(reinterpret_cast(ptr)); } - void destroy ( pointer ptr ) { ptr->~value_type(); } - + void destroy(pointer ptr) { ptr->~value_type(); } - template < typename O > struct rebind { - typedef b3AlignedAllocator< O , Alignment > other; + template + struct rebind + { + typedef b3AlignedAllocator other; }; - template < typename O > - self_type & operator=( const b3AlignedAllocator< O , Alignment > & ) { return *this; } + template + self_type& operator=(const b3AlignedAllocator&) + { + return *this; + } - friend bool operator==( const self_type & , const self_type & ) { return true; } + friend bool operator==(const self_type&, const self_type&) { return true; } }; - - -#endif //B3_ALIGNED_ALLOCATOR - +#endif //B3_ALIGNED_ALLOCATOR diff --git a/src/Bullet3Common/b3AlignedObjectArray.h b/src/Bullet3Common/b3AlignedObjectArray.h index ef7101656..249e381bf 100644 --- a/src/Bullet3Common/b3AlignedObjectArray.h +++ b/src/Bullet3Common/b3AlignedObjectArray.h @@ -13,11 +13,10 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef B3_OBJECT_ARRAY__ #define B3_OBJECT_ARRAY__ -#include "b3Scalar.h" // has definitions like B3_FORCE_INLINE +#include "b3Scalar.h" // has definitions like B3_FORCE_INLINE #include "b3AlignedAllocator.h" ///If the platform doesn't support placement new, you can disable B3_USE_PLACEMENT_NEW @@ -28,402 +27,386 @@ subject to the following restrictions: #define B3_USE_PLACEMENT_NEW 1 //#define B3_USE_MEMCPY 1 //disable, because it is cumbersome to find out for each platform where memcpy is defined. It can be in or or otherwise... -#define B3_ALLOW_ARRAY_COPY_OPERATOR // enabling this can accidently perform deep copies of data if you are not careful +#define B3_ALLOW_ARRAY_COPY_OPERATOR // enabling this can accidently perform deep copies of data if you are not careful #ifdef B3_USE_MEMCPY #include #include -#endif //B3_USE_MEMCPY +#endif //B3_USE_MEMCPY #ifdef B3_USE_PLACEMENT_NEW -#include //for placement new -#endif //B3_USE_PLACEMENT_NEW - +#include //for placement new +#endif //B3_USE_PLACEMENT_NEW ///The b3AlignedObjectArray template class uses a subset of the stl::vector interface for its methods ///It is developed to replace stl::vector to avoid portability issues, including STL alignment issues to add SIMD/SSE data -template -//template +template +//template class b3AlignedObjectArray { - b3AlignedAllocator m_allocator; + b3AlignedAllocator m_allocator; - int m_size; - int m_capacity; - T* m_data; + int m_size; + int m_capacity; + T* m_data; //PCK: added this line - bool m_ownsMemory; + bool m_ownsMemory; #ifdef B3_ALLOW_ARRAY_COPY_OPERATOR public: - B3_FORCE_INLINE b3AlignedObjectArray& operator=(const b3AlignedObjectArray &other) + B3_FORCE_INLINE b3AlignedObjectArray& operator=(const b3AlignedObjectArray& other) { copyFromArray(other); return *this; } -#else//B3_ALLOW_ARRAY_COPY_OPERATOR +#else //B3_ALLOW_ARRAY_COPY_OPERATOR private: - B3_FORCE_INLINE b3AlignedObjectArray& operator=(const b3AlignedObjectArray &other); -#endif//B3_ALLOW_ARRAY_COPY_OPERATOR + B3_FORCE_INLINE b3AlignedObjectArray& operator=(const b3AlignedObjectArray& other); +#endif //B3_ALLOW_ARRAY_COPY_OPERATOR protected: - B3_FORCE_INLINE int allocSize(int size) - { - return (size ? size*2 : 1); - } - B3_FORCE_INLINE void copy(int start,int end, T* dest) const - { - int i; - for (i=start;i= 0); + b3Assert(n < size()); + return m_data[n]; + } + + B3_FORCE_INLINE T& at(int n) + { + b3Assert(n >= 0); + b3Assert(n < size()); + return m_data[n]; + } + + B3_FORCE_INLINE const T& operator[](int n) const + { + b3Assert(n >= 0); + b3Assert(n < size()); + return m_data[n]; + } + + B3_FORCE_INLINE T& operator[](int n) + { + b3Assert(n >= 0); + b3Assert(n < size()); + return m_data[n]; + } + + ///clear the array, deallocated memory. Generally it is better to use array.resize(0), to reduce performance overhead of run-time memory (de)allocations. + B3_FORCE_INLINE void clear() + { + destroy(0, size()); + + deallocate(); + + init(); + } + + B3_FORCE_INLINE void pop_back() + { + b3Assert(m_size > 0); + m_size--; + m_data[m_size].~T(); + } + + ///resize changes the number of elements in the array. If the new size is larger, the new elements will be constructed using the optional second argument. + ///when the new number of elements is smaller, the destructor will be called, but memory will not be freed, to reduce performance overhead of run-time memory (de)allocations. + B3_FORCE_INLINE void resizeNoInitialize(int newsize) + { + int curSize = size(); + + if (newsize < curSize) + { + } + else + { + if (newsize > size()) + { + reserve(newsize); + } + //leave this uninitialized + } + m_size = newsize; + } + + B3_FORCE_INLINE void resize(int newsize, const T& fillData = T()) + { + int curSize = size(); + + if (newsize < curSize) + { + for (int i = newsize; i < curSize; i++) { m_data[i].~T(); } } - - B3_FORCE_INLINE void* allocate(int size) + else { - if (size) - return m_allocator.allocate(size); - return 0; - } - - B3_FORCE_INLINE void deallocate() - { - if(m_data) { - //PCK: enclosed the deallocation in this block - if (m_ownsMemory) - { - m_allocator.deallocate(m_data); - } - m_data = 0; + if (newsize > size()) + { + reserve(newsize); } - } - - - - - public: - - b3AlignedObjectArray() - { - init(); - } - - ~b3AlignedObjectArray() - { - clear(); - } - - ///Generally it is best to avoid using the copy constructor of an b3AlignedObjectArray, and use a (const) reference to the array instead. - b3AlignedObjectArray(const b3AlignedObjectArray& otherArray) - { - init(); - - int otherSize = otherArray.size(); - resize (otherSize); - otherArray.copy(0, otherSize, m_data); - } - - - - /// return the number of elements in the array - B3_FORCE_INLINE int size() const - { - return m_size; - } - - B3_FORCE_INLINE const T& at(int n) const - { - b3Assert(n>=0); - b3Assert(n=0); - b3Assert(n=0); - b3Assert(n=0); - b3Assert(n0); - m_size--; - m_data[m_size].~T(); - } - - - ///resize changes the number of elements in the array. If the new size is larger, the new elements will be constructed using the optional second argument. - ///when the new number of elements is smaller, the destructor will be called, but memory will not be freed, to reduce performance overhead of run-time memory (de)allocations. - B3_FORCE_INLINE void resizeNoInitialize(int newsize) - { - int curSize = size(); - - if (newsize < curSize) - { - } else - { - if (newsize > size()) - { - reserve(newsize); - } - //leave this uninitialized - } - m_size = newsize; - } - - B3_FORCE_INLINE void resize(int newsize, const T& fillData=T()) - { - int curSize = size(); - - if (newsize < curSize) - { - for(int i = newsize; i < curSize; i++) - { - m_data[i].~T(); - } - } else - { - if (newsize > size()) - { - reserve(newsize); - } #ifdef B3_USE_PLACEMENT_NEW - for (int i=curSize;i - void quickSortInternal(const L& CompareFunc,int lo, int hi) - { + template + void quickSortInternal(const L& CompareFunc, int lo, int hi) + { // lo is the lower index, hi is the upper index // of the region of array a that is to be sorted - int i=lo, j=hi; - T x=m_data[(lo+hi)/2]; + int i = lo, j = hi; + T x = m_data[(lo + hi) / 2]; - // partition - do - { - while (CompareFunc(m_data[i],x)) - i++; - while (CompareFunc(x,m_data[j])) - j--; - if (i<=j) - { - swap(i,j); - i++; j--; - } - } while (i<=j); - - // recursion - if (lo - void quickSort(const L& CompareFunc) + // partition + do { - //don't sort 0 or 1 elements - if (size()>1) + while (CompareFunc(m_data[i], x)) + i++; + while (CompareFunc(x, m_data[j])) + j--; + if (i <= j) { - quickSortInternal(CompareFunc,0,size()-1); + swap(i, j); + i++; + j--; + } + } while (i <= j); + + // recursion + if (lo < j) + quickSortInternal(CompareFunc, lo, j); + if (i < hi) + quickSortInternal(CompareFunc, i, hi); + } + + template + void quickSort(const L& CompareFunc) + { + //don't sort 0 or 1 elements + if (size() > 1) + { + quickSortInternal(CompareFunc, 0, size() - 1); + } + } + + ///heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/ + template + void downHeap(T* pArr, int k, int n, const L& CompareFunc) + { + /* PRE: a[k+1..N] is a heap */ + /* POST: a[k..N] is a heap */ + + T temp = pArr[k - 1]; + /* k has child(s) */ + while (k <= n / 2) + { + int child = 2 * k; + + if ((child < n) && CompareFunc(pArr[child - 1], pArr[child])) + { + child++; + } + /* pick larger child */ + if (CompareFunc(temp, pArr[child - 1])) + { + /* move child up */ + pArr[k - 1] = pArr[child - 1]; + k = child; + } + else + { + break; } } + pArr[k - 1] = temp; + } /*downHeap*/ - - ///heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/ - template - void downHeap(T *pArr, int k, int n, const L& CompareFunc) - { - /* PRE: a[k+1..N] is a heap */ - /* POST: a[k..N] is a heap */ - - T temp = pArr[k - 1]; - /* k has child(s) */ - while (k <= n/2) - { - int child = 2*k; - - if ((child < n) && CompareFunc(pArr[child - 1] , pArr[child])) - { - child++; - } - /* pick larger child */ - if (CompareFunc(temp , pArr[child - 1])) - { - /* move child up */ - pArr[k - 1] = pArr[child - 1]; - k = child; - } - else - { - break; - } - } - pArr[k - 1] = temp; - } /*downHeap*/ - - void swap(int index0,int index1) - { + void swap(int index0, int index1) + { #ifdef B3_USE_MEMCPY - char temp[sizeof(T)]; - memcpy(temp,&m_data[index0],sizeof(T)); - memcpy(&m_data[index0],&m_data[index1],sizeof(T)); - memcpy(&m_data[index1],temp,sizeof(T)); + char temp[sizeof(T)]; + memcpy(temp, &m_data[index0], sizeof(T)); + memcpy(&m_data[index0], &m_data[index1], sizeof(T)); + memcpy(&m_data[index1], temp, sizeof(T)); #else - T temp = m_data[index0]; - m_data[index0] = m_data[index1]; - m_data[index1] = temp; -#endif //B3_USE_PLACEMENT_NEW - - } + T temp = m_data[index0]; + m_data[index0] = m_data[index1]; + m_data[index1] = temp; +#endif //B3_USE_PLACEMENT_NEW + } template void heapSort(const L& CompareFunc) @@ -431,49 +414,48 @@ protected: /* sort a[0..N-1], N.B. 0 to N-1 */ int k; int n = m_size; - for (k = n/2; k > 0; k--) + for (k = n / 2; k > 0; k--) { downHeap(m_data, k, n, CompareFunc); } /* a[1..N] is now a heap */ - while ( n>=1 ) + while (n >= 1) { - swap(0,n-1); /* largest of a[0..n-1] */ - + swap(0, n - 1); /* largest of a[0..n-1] */ n = n - 1; /* restore a[1..i-1] heap */ downHeap(m_data, 1, n, CompareFunc); - } + } } ///non-recursive binary search, assumes sorted array - int findBinarySearch(const T& key) const + int findBinarySearch(const T& key) const { int first = 0; - int last = size()-1; + int last = size() - 1; //assume sorted array - while (first <= last) { + while (first <= last) + { int mid = (first + last) / 2; // compute mid point. - if (key > m_data[mid]) + if (key > m_data[mid]) first = mid + 1; // repeat search in top half. - else if (key < m_data[mid]) - last = mid - 1; // repeat search in bottom half. + else if (key < m_data[mid]) + last = mid - 1; // repeat search in bottom half. else - return mid; // found it. return position ///// + return mid; // found it. return position ///// } - return size(); // failed to find key + return size(); // failed to find key } - - int findLinearSearch(const T& key) const + int findLinearSearch(const T& key) const { - int index=size(); + int index = size(); int i; - for (i=0;i pairs; public: - // Constructor b3CommandLineArgs(int argc, char **argv) { - addArgs(argc,argv); + addArgs(argc, argv); } - void addArgs(int argc, char**argv) + void addArgs(int argc, char **argv) { - for (int i = 1; i < argc; i++) - { - std::string arg = argv[i]; + for (int i = 1; i < argc; i++) + { + std::string arg = argv[i]; - if ((arg.length() < 2) || (arg[0] != '-') || (arg[1] != '-')) { - continue; - } - - std::string::size_type pos; - std::string key, val; - if ((pos = arg.find( '=')) == std::string::npos) { - key = std::string(arg, 2, arg.length() - 2); - val = ""; - } else { - key = std::string(arg, 2, pos - 2); - val = std::string(arg, pos + 1, arg.length() - 1); - } - - //only add new keys, don't replace existing - if(pairs.find(key) == pairs.end()) + if ((arg.length() < 2) || (arg[0] != '-') || (arg[1] != '-')) { - pairs[key] = val; + continue; } - } + + std::string::size_type pos; + std::string key, val; + if ((pos = arg.find('=')) == std::string::npos) + { + key = std::string(arg, 2, arg.length() - 2); + val = ""; + } + else + { + key = std::string(arg, 2, pos - 2); + val = std::string(arg, pos + 1, arg.length() - 1); + } + + //only add new keys, don't replace existing + if (pairs.find(key) == pairs.end()) + { + pairs[key] = val; + } + } } - bool CheckCmdLineFlag(const char* arg_name) + bool CheckCmdLineFlag(const char *arg_name) { std::map::iterator itr; - if ((itr = pairs.find(arg_name)) != pairs.end()) { + if ((itr = pairs.find(arg_name)) != pairs.end()) + { return true; - } + } return false; } @@ -73,29 +76,31 @@ template inline bool b3CommandLineArgs::GetCmdLineArgument(const char *arg_name, T &val) { std::map::iterator itr; - if ((itr = pairs.find(arg_name)) != pairs.end()) { + if ((itr = pairs.find(arg_name)) != pairs.end()) + { std::istringstream strstream(itr->second); strstream >> val; return true; - } - return false; -} - -template <> -inline bool b3CommandLineArgs::GetCmdLineArgument(const char* arg_name, char* &val) -{ - std::map::iterator itr; - if ((itr = pairs.find(arg_name)) != pairs.end()) { - - std::string s = itr->second; - val = (char*) malloc(sizeof(char) * (s.length() + 1)); - std::strcpy(val, s.c_str()); - return true; - } else { - val = NULL; } return false; } +template <> +inline bool b3CommandLineArgs::GetCmdLineArgument(const char *arg_name, char *&val) +{ + std::map::iterator itr; + if ((itr = pairs.find(arg_name)) != pairs.end()) + { + std::string s = itr->second; + val = (char *)malloc(sizeof(char) * (s.length() + 1)); + std::strcpy(val, s.c_str()); + return true; + } + else + { + val = NULL; + } + return false; +} -#endif //COMMAND_LINE_ARGS_H +#endif //COMMAND_LINE_ARGS_H diff --git a/src/Bullet3Common/b3FileUtils.h b/src/Bullet3Common/b3FileUtils.h index b5e8225cf..9ded17eaa 100644 --- a/src/Bullet3Common/b3FileUtils.h +++ b/src/Bullet3Common/b3FileUtils.h @@ -3,7 +3,7 @@ #include #include "b3Scalar.h" -#include //ptrdiff_h +#include //ptrdiff_h #include struct b3FileUtils @@ -17,42 +17,42 @@ struct b3FileUtils static bool findFile(const char* orgFileName, char* relativeFileName, int maxRelativeFileNameMaxLen) { - FILE* f=0; - f = fopen(orgFileName,"rb"); - if (f) - { + FILE* f = 0; + f = fopen(orgFileName, "rb"); + if (f) + { //printf("original file found: [%s]\n", orgFileName); - sprintf(relativeFileName,"%s", orgFileName); + sprintf(relativeFileName, "%s", orgFileName); fclose(f); return true; } - //printf("Trying various directories, relative to current working directory\n"); - const char* prefix[]={"./","./data/","../data/","../../data/","../../../data/","../../../../data/"}; - int numPrefixes = sizeof(prefix)/sizeof(const char*); - - f=0; - bool fileFound = false; + //printf("Trying various directories, relative to current working directory\n"); + const char* prefix[] = {"./", "./data/", "../data/", "../../data/", "../../../data/", "../../../../data/"}; + int numPrefixes = sizeof(prefix) / sizeof(const char*); - for (int i=0;!f && i0); - if (maxPathLength>0) + b3Assert(maxPathLength > 0); + if (maxPathLength > 0) { path[len] = 0; } @@ -102,23 +100,21 @@ struct b3FileUtils static char toLowerChar(const char t) { - if (t>=(char)'A' && t<=(char)'Z') + if (t >= (char)'A' && t <= (char)'Z') return t + ((char)'a' - (char)'A'); else return t; } - static void toLower(char* str) { - int len=strlen(str); - for (int i=0;i ///very basic hashable string implementation, compatible with b3HashMap struct b3HashString { std::string m_string; - unsigned int m_hash; + unsigned int m_hash; - B3_FORCE_INLINE unsigned int getHash()const + B3_FORCE_INLINE unsigned int getHash() const { return m_hash; } - b3HashString(const char* name) - :m_string(name) + : m_string(name) { - /* magic numbers from http://www.isthe.com/chongo/tech/comp/fnv/ */ - static const unsigned int InitialFNV = 2166136261u; + static const unsigned int InitialFNV = 2166136261u; static const unsigned int FNVMultiple = 16777619u; /* Fowler / Noll / Vo (FNV) Hash */ unsigned int hash = InitialFNV; int len = m_string.length(); - for(int i = 0; i 0 ) - ret = 1 ; + if (ret < 0) + ret = -1; + else if (ret > 0) + ret = 1; - return( ret ); + return (ret); } bool equals(const b3HashString& other) const { return (m_string == other.m_string); } - }; - -const int B3_HASH_NULL=0xffffffff; - +const int B3_HASH_NULL = 0xffffffff; class b3HashInt { - int m_uid; + int m_uid; + public: - b3HashInt(int uid) :m_uid(uid) + b3HashInt(int uid) : m_uid(uid) { } - int getUid1() const + int getUid1() const { return m_uid; } - void setUid1(int uid) + void setUid1(int uid) { m_uid = uid; } @@ -102,34 +96,34 @@ public: return getUid1() == other.getUid1(); } //to our success - B3_FORCE_INLINE unsigned int getHash()const + B3_FORCE_INLINE unsigned int getHash() const { int key = m_uid; // Thomas Wang's hash - key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16); + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); return key; } }; - - class b3HashPtr { - - union - { - const void* m_pointer; - int m_hashValues[2]; + union { + const void* m_pointer; + int m_hashValues[2]; }; public: - b3HashPtr(const void* ptr) - :m_pointer(ptr) + : m_pointer(ptr) { } - const void* getPointer() const + const void* getPointer() const { return m_pointer; } @@ -140,65 +134,69 @@ public: } //to our success - B3_FORCE_INLINE unsigned int getHash()const + B3_FORCE_INLINE unsigned int getHash() const { - const bool VOID_IS_8 = ((sizeof(void*)==8)); - - int key = VOID_IS_8? m_hashValues[0]+m_hashValues[1] : m_hashValues[0]; - + const bool VOID_IS_8 = ((sizeof(void*) == 8)); + + int key = VOID_IS_8 ? m_hashValues[0] + m_hashValues[1] : m_hashValues[0]; + // Thomas Wang's hash - key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16); + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); return key; } - - }; - template class b3HashKeyPtr { - int m_uid; + int m_uid; + public: + b3HashKeyPtr(int uid) : m_uid(uid) + { + } - b3HashKeyPtr(int uid) :m_uid(uid) - { - } + int getUid1() const + { + return m_uid; + } - int getUid1() const - { - return m_uid; - } + bool equals(const b3HashKeyPtr& other) const + { + return getUid1() == other.getUid1(); + } - bool equals(const b3HashKeyPtr& other) const - { - return getUid1() == other.getUid1(); - } - - //to our success - B3_FORCE_INLINE unsigned int getHash()const - { - int key = m_uid; - // Thomas Wang's hash - key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16); - return key; - } - - + //to our success + B3_FORCE_INLINE unsigned int getHash() const + { + int key = m_uid; + // Thomas Wang's hash + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); + return key; + } }; - template class b3HashKey { - int m_uid; -public: + int m_uid; - b3HashKey(int uid) :m_uid(uid) +public: + b3HashKey(int uid) : m_uid(uid) { } - int getUid1() const + int getUid1() const { return m_uid; } @@ -208,30 +206,33 @@ public: return getUid1() == other.getUid1(); } //to our success - B3_FORCE_INLINE unsigned int getHash()const + B3_FORCE_INLINE unsigned int getHash() const { int key = m_uid; // Thomas Wang's hash - key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16); + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); return key; } }; - ///The b3HashMap template class implements a generic and lightweight hashmap. ///A basic sample of how to use b3HashMap is located in Demos\BasicDemo\main.cpp template class b3HashMap { - protected: - b3AlignedObjectArray m_hashTable; - b3AlignedObjectArray m_next; - - b3AlignedObjectArray m_valueArray; - b3AlignedObjectArray m_keyArray; + b3AlignedObjectArray m_hashTable; + b3AlignedObjectArray m_next; - void growTables(const Key& /*key*/) + b3AlignedObjectArray m_valueArray; + b3AlignedObjectArray m_keyArray; + + void growTables(const Key& /*key*/) { int newCapacity = m_valueArray.capacity(); @@ -245,7 +246,7 @@ protected: int i; - for (i= 0; i < newCapacity; ++i) + for (i = 0; i < newCapacity; ++i) { m_hashTable[i] = B3_HASH_NULL; } @@ -254,30 +255,28 @@ protected: m_next[i] = B3_HASH_NULL; } - for(i=0;i= (unsigned int)m_hashTable.size()) { @@ -453,14 +450,13 @@ protected: return index; } - void clear() + void clear() { m_hashTable.clear(); m_next.clear(); m_valueArray.clear(); m_keyArray.clear(); } - }; -#endif //B3_HASH_MAP_H +#endif //B3_HASH_MAP_H diff --git a/src/Bullet3Common/b3Logging.cpp b/src/Bullet3Common/b3Logging.cpp index a8e950715..9c9f7c09e 100644 --- a/src/Bullet3Common/b3Logging.cpp +++ b/src/Bullet3Common/b3Logging.cpp @@ -20,17 +20,16 @@ subject to the following restrictions: #ifdef _WIN32 #include -#endif //_WIN32 - +#endif //_WIN32 void b3PrintfFuncDefault(const char* msg) { #ifdef _WIN32 OutputDebugStringA(msg); #endif - printf("%s",msg); - //is this portable? - fflush(stdout); + printf("%s", msg); + //is this portable? + fflush(stdout); } void b3WarningMessageFuncDefault(const char* msg) @@ -38,32 +37,26 @@ void b3WarningMessageFuncDefault(const char* msg) #ifdef _WIN32 OutputDebugStringA(msg); #endif - printf("%s",msg); - //is this portable? - fflush(stdout); - + printf("%s", msg); + //is this portable? + fflush(stdout); } - void b3ErrorMessageFuncDefault(const char* msg) { #ifdef _WIN32 OutputDebugStringA(msg); #endif - printf("%s",msg); + printf("%s", msg); - //is this portable? - fflush(stdout); - + //is this portable? + fflush(stdout); } - - static b3PrintfFunc* b3s_printfFunc = b3PrintfFuncDefault; static b3WarningMessageFunc* b3s_warningMessageFunc = b3WarningMessageFuncDefault; static b3ErrorMessageFunc* b3s_errorMessageFunc = b3ErrorMessageFuncDefault; - ///The developer can route b3Printf output using their own implementation void b3SetCustomPrintfFunc(b3PrintfFunc* printfFunc) { @@ -81,54 +74,50 @@ void b3SetCustomErrorMessageFunc(b3PrintfFunc* errorMessageFunc) //#define B3_MAX_DEBUG_STRING_LENGTH 2048 #define B3_MAX_DEBUG_STRING_LENGTH 32768 - -void b3OutputPrintfVarArgsInternal(const char *str, ...) +void b3OutputPrintfVarArgsInternal(const char* str, ...) { - char strDebug[B3_MAX_DEBUG_STRING_LENGTH]={0}; - va_list argList; - va_start(argList, str); + char strDebug[B3_MAX_DEBUG_STRING_LENGTH] = {0}; + va_list argList; + va_start(argList, str); #ifdef _MSC_VER - vsprintf_s(strDebug,B3_MAX_DEBUG_STRING_LENGTH,str,argList); + vsprintf_s(strDebug, B3_MAX_DEBUG_STRING_LENGTH, str, argList); #else - vsnprintf(strDebug,B3_MAX_DEBUG_STRING_LENGTH,str,argList); + vsnprintf(strDebug, B3_MAX_DEBUG_STRING_LENGTH, str, argList); #endif - (b3s_printfFunc)(strDebug); - va_end(argList); + (b3s_printfFunc)(strDebug); + va_end(argList); } -void b3OutputWarningMessageVarArgsInternal(const char *str, ...) +void b3OutputWarningMessageVarArgsInternal(const char* str, ...) { - char strDebug[B3_MAX_DEBUG_STRING_LENGTH]={0}; - va_list argList; - va_start(argList, str); + char strDebug[B3_MAX_DEBUG_STRING_LENGTH] = {0}; + va_list argList; + va_start(argList, str); #ifdef _MSC_VER - vsprintf_s(strDebug,B3_MAX_DEBUG_STRING_LENGTH,str,argList); + vsprintf_s(strDebug, B3_MAX_DEBUG_STRING_LENGTH, str, argList); #else - vsnprintf(strDebug,B3_MAX_DEBUG_STRING_LENGTH,str,argList); + vsnprintf(strDebug, B3_MAX_DEBUG_STRING_LENGTH, str, argList); #endif - (b3s_warningMessageFunc)(strDebug); - va_end(argList); + (b3s_warningMessageFunc)(strDebug); + va_end(argList); } -void b3OutputErrorMessageVarArgsInternal(const char *str, ...) +void b3OutputErrorMessageVarArgsInternal(const char* str, ...) { - - char strDebug[B3_MAX_DEBUG_STRING_LENGTH]={0}; - va_list argList; - va_start(argList, str); + char strDebug[B3_MAX_DEBUG_STRING_LENGTH] = {0}; + va_list argList; + va_start(argList, str); #ifdef _MSC_VER - vsprintf_s(strDebug,B3_MAX_DEBUG_STRING_LENGTH,str,argList); + vsprintf_s(strDebug, B3_MAX_DEBUG_STRING_LENGTH, str, argList); #else - vsnprintf(strDebug,B3_MAX_DEBUG_STRING_LENGTH,str,argList); + vsnprintf(strDebug, B3_MAX_DEBUG_STRING_LENGTH, str, argList); #endif - (b3s_errorMessageFunc)(strDebug); - va_end(argList); - + (b3s_errorMessageFunc)(strDebug); + va_end(argList); } - -void b3EnterProfileZoneDefault(const char* name) +void b3EnterProfileZoneDefault(const char* name) { } -void b3LeaveProfileZoneDefault() +void b3LeaveProfileZoneDefault() { } static b3EnterProfileZoneFunc* b3s_enterFunc = b3EnterProfileZoneDefault; @@ -151,10 +140,6 @@ void b3SetCustomLeaveProfileZoneFunc(b3LeaveProfileZoneFunc* leaveFunc) b3s_leaveFunc = leaveFunc; } - - - #ifndef _MSC_VER #undef vsprintf_s #endif - diff --git a/src/Bullet3Common/b3Logging.h b/src/Bullet3Common/b3Logging.h index b302effe4..9c92b12eb 100644 --- a/src/Bullet3Common/b3Logging.h +++ b/src/Bullet3Common/b3Logging.h @@ -3,75 +3,84 @@ #define B3_LOGGING_H #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif - + ///We add the do/while so that the statement "if (condition) b3Printf("test"); else {...}" would fail ///You can also customize the message by uncommenting out a different line below #define b3Printf(...) b3OutputPrintfVarArgsInternal(__VA_ARGS__) -//#define b3Printf(...) do {b3OutputPrintfVarArgsInternal("b3Printf[%s,%d]:",__FILE__,__LINE__);b3OutputPrintfVarArgsInternal(__VA_ARGS__); } while(0) -//#define b3Printf b3OutputPrintfVarArgsInternal -//#define b3Printf(...) printf(__VA_ARGS__) -//#define b3Printf(...) - -#define b3Warning(...) do {b3OutputWarningMessageVarArgsInternal("b3Warning[%s,%d]:\n",__FILE__,__LINE__);b3OutputWarningMessageVarArgsInternal(__VA_ARGS__); }while(0) -#define b3Error(...) do {b3OutputErrorMessageVarArgsInternal("b3Error[%s,%d]:\n",__FILE__,__LINE__);b3OutputErrorMessageVarArgsInternal(__VA_ARGS__); } while(0) + //#define b3Printf(...) do {b3OutputPrintfVarArgsInternal("b3Printf[%s,%d]:",__FILE__,__LINE__);b3OutputPrintfVarArgsInternal(__VA_ARGS__); } while(0) + //#define b3Printf b3OutputPrintfVarArgsInternal + //#define b3Printf(...) printf(__VA_ARGS__) + //#define b3Printf(...) +#define b3Warning(...) \ + do \ + { \ + b3OutputWarningMessageVarArgsInternal("b3Warning[%s,%d]:\n", __FILE__, __LINE__); \ + b3OutputWarningMessageVarArgsInternal(__VA_ARGS__); \ + } while (0) +#define b3Error(...) \ + do \ + { \ + b3OutputErrorMessageVarArgsInternal("b3Error[%s,%d]:\n", __FILE__, __LINE__); \ + b3OutputErrorMessageVarArgsInternal(__VA_ARGS__); \ + } while (0) #ifndef B3_NO_PROFILE -void b3EnterProfileZone(const char* name); -void b3LeaveProfileZone(); + void b3EnterProfileZone(const char* name); + void b3LeaveProfileZone(); #ifdef __cplusplus -class b3ProfileZone -{ -public: - b3ProfileZone(const char* name) - { - b3EnterProfileZone( name ); - } + class b3ProfileZone + { + public: + b3ProfileZone(const char* name) + { + b3EnterProfileZone(name); + } - ~b3ProfileZone() - { - b3LeaveProfileZone(); - } -}; + ~b3ProfileZone() + { + b3LeaveProfileZone(); + } + }; -#define B3_PROFILE( name ) b3ProfileZone __profile( name ) +#define B3_PROFILE(name) b3ProfileZone __profile(name) #endif -#else //B3_NO_PROFILE +#else //B3_NO_PROFILE -#define B3_PROFILE( name ) +#define B3_PROFILE(name) #define b3StartProfile(a) #define b3StopProfile -#endif //#ifndef B3_NO_PROFILE +#endif //#ifndef B3_NO_PROFILE + typedef void(b3PrintfFunc)(const char* msg); + typedef void(b3WarningMessageFunc)(const char* msg); + typedef void(b3ErrorMessageFunc)(const char* msg); + typedef void(b3EnterProfileZoneFunc)(const char* msg); + typedef void(b3LeaveProfileZoneFunc)(); -typedef void (b3PrintfFunc)(const char* msg); -typedef void (b3WarningMessageFunc)(const char* msg); -typedef void (b3ErrorMessageFunc)(const char* msg); -typedef void (b3EnterProfileZoneFunc)(const char* msg); -typedef void (b3LeaveProfileZoneFunc)(); + ///The developer can route b3Printf output using their own implementation + void b3SetCustomPrintfFunc(b3PrintfFunc* printfFunc); + void b3SetCustomWarningMessageFunc(b3WarningMessageFunc* warningMsgFunc); + void b3SetCustomErrorMessageFunc(b3ErrorMessageFunc* errorMsgFunc); -///The developer can route b3Printf output using their own implementation -void b3SetCustomPrintfFunc(b3PrintfFunc* printfFunc); -void b3SetCustomWarningMessageFunc(b3WarningMessageFunc* warningMsgFunc); -void b3SetCustomErrorMessageFunc(b3ErrorMessageFunc* errorMsgFunc); + ///Set custom profile zone functions (zones can be nested) + void b3SetCustomEnterProfileZoneFunc(b3EnterProfileZoneFunc* enterFunc); + void b3SetCustomLeaveProfileZoneFunc(b3LeaveProfileZoneFunc* leaveFunc); -///Set custom profile zone functions (zones can be nested) -void b3SetCustomEnterProfileZoneFunc(b3EnterProfileZoneFunc* enterFunc); -void b3SetCustomLeaveProfileZoneFunc(b3LeaveProfileZoneFunc* leaveFunc); - -///Don't use those internal functions directly, use the b3Printf or b3SetCustomPrintfFunc instead (or warning/error version) -void b3OutputPrintfVarArgsInternal(const char *str, ...); -void b3OutputWarningMessageVarArgsInternal(const char *str, ...); -void b3OutputErrorMessageVarArgsInternal(const char *str, ...); + ///Don't use those internal functions directly, use the b3Printf or b3SetCustomPrintfFunc instead (or warning/error version) + void b3OutputPrintfVarArgsInternal(const char* str, ...); + void b3OutputWarningMessageVarArgsInternal(const char* str, ...); + void b3OutputErrorMessageVarArgsInternal(const char* str, ...); #ifdef __cplusplus - } +} #endif -#endif//B3_LOGGING_H \ No newline at end of file +#endif //B3_LOGGING_H \ No newline at end of file diff --git a/src/Bullet3Common/b3Matrix3x3.h b/src/Bullet3Common/b3Matrix3x3.h index 89b57cf59..6c46536a8 100644 --- a/src/Bullet3Common/b3Matrix3x3.h +++ b/src/Bullet3Common/b3Matrix3x3.h @@ -12,8 +12,7 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - -#ifndef B3_MATRIX3x3_H +#ifndef B3_MATRIX3x3_H #define B3_MATRIX3x3_H #include "b3Vector3.h" @@ -32,22 +31,22 @@ const b3SimdFloat4 B3_ATTRIBUTE_ALIGNED16(b3v0010) = {0.0f, 0.0f, 1.0f, 0.0f}; #endif #ifdef B3_USE_DOUBLE_PRECISION -#define b3Matrix3x3Data b3Matrix3x3DoubleData +#define b3Matrix3x3Data b3Matrix3x3DoubleData #else -#define b3Matrix3x3Data b3Matrix3x3FloatData -#endif //B3_USE_DOUBLE_PRECISION - +#define b3Matrix3x3Data b3Matrix3x3FloatData +#endif //B3_USE_DOUBLE_PRECISION /**@brief The b3Matrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with b3Quaternion, b3Transform and b3Vector3. * Make sure to only include a pure orthogonal matrix without scaling. */ -B3_ATTRIBUTE_ALIGNED16(class) b3Matrix3x3 { - +B3_ATTRIBUTE_ALIGNED16(class) +b3Matrix3x3 +{ ///Data storage for the matrix, each vector is a row of the matrix b3Vector3 m_el[3]; public: /** @brief No initializaion constructor */ - b3Matrix3x3 () {} + b3Matrix3x3() {} // explicit b3Matrix3x3(const b3Scalar *m) { setFromOpenGLSubMatrix(m); } @@ -62,27 +61,27 @@ public: */ /** @brief Constructor with row major formatting */ b3Matrix3x3(const b3Scalar& xx, const b3Scalar& xy, const b3Scalar& xz, - const b3Scalar& yx, const b3Scalar& yy, const b3Scalar& yz, - const b3Scalar& zx, const b3Scalar& zy, const b3Scalar& zz) - { - setValue(xx, xy, xz, - yx, yy, yz, - zx, zy, zz); + const b3Scalar& yx, const b3Scalar& yy, const b3Scalar& yz, + const b3Scalar& zx, const b3Scalar& zy, const b3Scalar& zz) + { + setValue(xx, xy, xz, + yx, yy, yz, + zx, zy, zz); } -#if (defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE))|| defined (B3_USE_NEON) - B3_FORCE_INLINE b3Matrix3x3 (const b3SimdFloat4 v0, const b3SimdFloat4 v1, const b3SimdFloat4 v2 ) +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) || defined(B3_USE_NEON) + B3_FORCE_INLINE b3Matrix3x3(const b3SimdFloat4 v0, const b3SimdFloat4 v1, const b3SimdFloat4 v2) { - m_el[0].mVec128 = v0; - m_el[1].mVec128 = v1; - m_el[2].mVec128 = v2; + m_el[0].mVec128 = v0; + m_el[1].mVec128 = v1; + m_el[2].mVec128 = v2; } - B3_FORCE_INLINE b3Matrix3x3 (const b3Vector3& v0, const b3Vector3& v1, const b3Vector3& v2 ) + B3_FORCE_INLINE b3Matrix3x3(const b3Vector3& v0, const b3Vector3& v1, const b3Vector3& v2) { - m_el[0] = v0; - m_el[1] = v1; - m_el[2] = v2; + m_el[0] = v0; + m_el[1] = v1; + m_el[2] = v2; } // Copy constructor @@ -94,25 +93,25 @@ public: } // Assignment Operator - B3_FORCE_INLINE b3Matrix3x3& operator=(const b3Matrix3x3& m) + B3_FORCE_INLINE b3Matrix3x3& operator=(const b3Matrix3x3& m) { m_el[0].mVec128 = m.m_el[0].mVec128; m_el[1].mVec128 = m.m_el[1].mVec128; m_el[2].mVec128 = m.m_el[2].mVec128; - + return *this; } #else /** @brief Copy constructor */ - B3_FORCE_INLINE b3Matrix3x3 (const b3Matrix3x3& other) + B3_FORCE_INLINE b3Matrix3x3(const b3Matrix3x3& other) { m_el[0] = other.m_el[0]; m_el[1] = other.m_el[1]; m_el[2] = other.m_el[2]; } - + /** @brief Assignment Operator */ B3_FORCE_INLINE b3Matrix3x3& operator=(const b3Matrix3x3& other) { @@ -128,10 +127,9 @@ public: * @param i Column number 0 indexed */ B3_FORCE_INLINE b3Vector3 getColumn(int i) const { - return b3MakeVector3(m_el[0][i],m_el[1][i],m_el[2][i]); + return b3MakeVector3(m_el[0][i], m_el[1][i], m_el[2][i]); } - /** @brief Get a row of the matrix as a vector * @param i Row number 0 indexed */ B3_FORCE_INLINE const b3Vector3& getRow(int i) const @@ -142,10 +140,10 @@ public: /** @brief Get a mutable reference to a row of the matrix as a vector * @param i Row number 0 indexed */ - B3_FORCE_INLINE b3Vector3& operator[](int i) - { + B3_FORCE_INLINE b3Vector3& operator[](int i) + { b3FullAssert(0 <= i && i < 3); - return m_el[i]; + return m_el[i]; } /** @brief Get a const reference to a row of the matrix as a vector @@ -153,32 +151,31 @@ public: B3_FORCE_INLINE const b3Vector3& operator[](int i) const { b3FullAssert(0 <= i && i < 3); - return m_el[i]; + return m_el[i]; } /** @brief Multiply by the target matrix on the right * @param m Rotation matrix to be applied * Equivilant to this = this * m */ - b3Matrix3x3& operator*=(const b3Matrix3x3& m); + b3Matrix3x3& operator*=(const b3Matrix3x3& m); /** @brief Adds by the target matrix on the right * @param m matrix to be applied * Equivilant to this = this + m */ - b3Matrix3x3& operator+=(const b3Matrix3x3& m); + b3Matrix3x3& operator+=(const b3Matrix3x3& m); /** @brief Substractss by the target matrix on the right * @param m matrix to be applied * Equivilant to this = this - m */ - b3Matrix3x3& operator-=(const b3Matrix3x3& m); + b3Matrix3x3& operator-=(const b3Matrix3x3& m); /** @brief Set from the rotational part of a 4x4 OpenGL matrix * @param m A pointer to the beginning of the array of scalars*/ - void setFromOpenGLSubMatrix(const b3Scalar *m) + void setFromOpenGLSubMatrix(const b3Scalar* m) { - m_el[0].setValue(m[0],m[4],m[8]); - m_el[1].setValue(m[1],m[5],m[9]); - m_el[2].setValue(m[2],m[6],m[10]); - + m_el[0].setValue(m[0], m[4], m[8]); + m_el[1].setValue(m[1], m[5], m[9]); + m_el[2].setValue(m[2], m[6], m[10]); } /** @brief Set the values of the matrix explicitly (row major) * @param xx Top left @@ -190,93 +187,92 @@ public: * @param zx Bottom Left * @param zy Bottom Middle * @param zz Bottom Right*/ - void setValue(const b3Scalar& xx, const b3Scalar& xy, const b3Scalar& xz, - const b3Scalar& yx, const b3Scalar& yy, const b3Scalar& yz, - const b3Scalar& zx, const b3Scalar& zy, const b3Scalar& zz) + void setValue(const b3Scalar& xx, const b3Scalar& xy, const b3Scalar& xz, + const b3Scalar& yx, const b3Scalar& yy, const b3Scalar& yz, + const b3Scalar& zx, const b3Scalar& zy, const b3Scalar& zz) { - m_el[0].setValue(xx,xy,xz); - m_el[1].setValue(yx,yy,yz); - m_el[2].setValue(zx,zy,zz); + m_el[0].setValue(xx, xy, xz); + m_el[1].setValue(yx, yy, yz); + m_el[2].setValue(zx, zy, zz); } /** @brief Set the matrix from a quaternion - * @param q The Quaternion to match */ - void setRotation(const b3Quaternion& q) + * @param q The Quaternion to match */ + void setRotation(const b3Quaternion& q) { b3Scalar d = q.length2(); b3FullAssert(d != b3Scalar(0.0)); b3Scalar s = b3Scalar(2.0) / d; - - #if defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE) - __m128 vs, Q = q.get128(); + +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) + __m128 vs, Q = q.get128(); __m128i Qi = b3CastfTo128i(Q); - __m128 Y, Z; - __m128 V1, V2, V3; - __m128 V11, V21, V31; - __m128 NQ = _mm_xor_ps(Q, b3vMzeroMask); + __m128 Y, Z; + __m128 V1, V2, V3; + __m128 V11, V21, V31; + __m128 NQ = _mm_xor_ps(Q, b3vMzeroMask); __m128i NQi = b3CastfTo128i(NQ); - - V1 = b3CastiTo128f(_mm_shuffle_epi32 (Qi, B3_SHUFFLE(1,0,2,3))); // Y X Z W - V2 = _mm_shuffle_ps(NQ, Q, B3_SHUFFLE(0,0,1,3)); // -X -X Y W - V3 = b3CastiTo128f(_mm_shuffle_epi32 (Qi, B3_SHUFFLE(2,1,0,3))); // Z Y X W - V1 = _mm_xor_ps(V1, b3vMPPP); // change the sign of the first element - - V11 = b3CastiTo128f(_mm_shuffle_epi32 (Qi, B3_SHUFFLE(1,1,0,3))); // Y Y X W - V21 = _mm_unpackhi_ps(Q, Q); // Z Z W W - V31 = _mm_shuffle_ps(Q, NQ, B3_SHUFFLE(0,2,0,3)); // X Z -X -W - V2 = V2 * V1; // - V1 = V1 * V11; // - V3 = V3 * V31; // + V1 = b3CastiTo128f(_mm_shuffle_epi32(Qi, B3_SHUFFLE(1, 0, 2, 3))); // Y X Z W + V2 = _mm_shuffle_ps(NQ, Q, B3_SHUFFLE(0, 0, 1, 3)); // -X -X Y W + V3 = b3CastiTo128f(_mm_shuffle_epi32(Qi, B3_SHUFFLE(2, 1, 0, 3))); // Z Y X W + V1 = _mm_xor_ps(V1, b3vMPPP); // change the sign of the first element - V11 = _mm_shuffle_ps(NQ, Q, B3_SHUFFLE(2,3,1,3)); // -Z -W Y W - V11 = V11 * V21; // - V21 = _mm_xor_ps(V21, b3vMPPP); // change the sign of the first element - V31 = _mm_shuffle_ps(Q, NQ, B3_SHUFFLE(3,3,1,3)); // W W -Y -W - V31 = _mm_xor_ps(V31, b3vMPPP); // change the sign of the first element - Y = b3CastiTo128f(_mm_shuffle_epi32 (NQi, B3_SHUFFLE(3,2,0,3))); // -W -Z -X -W - Z = b3CastiTo128f(_mm_shuffle_epi32 (Qi, B3_SHUFFLE(1,0,1,3))); // Y X Y W + V11 = b3CastiTo128f(_mm_shuffle_epi32(Qi, B3_SHUFFLE(1, 1, 0, 3))); // Y Y X W + V21 = _mm_unpackhi_ps(Q, Q); // Z Z W W + V31 = _mm_shuffle_ps(Q, NQ, B3_SHUFFLE(0, 2, 0, 3)); // X Z -X -W + + V2 = V2 * V1; // + V1 = V1 * V11; // + V3 = V3 * V31; // + + V11 = _mm_shuffle_ps(NQ, Q, B3_SHUFFLE(2, 3, 1, 3)); // -Z -W Y W + V11 = V11 * V21; // + V21 = _mm_xor_ps(V21, b3vMPPP); // change the sign of the first element + V31 = _mm_shuffle_ps(Q, NQ, B3_SHUFFLE(3, 3, 1, 3)); // W W -Y -W + V31 = _mm_xor_ps(V31, b3vMPPP); // change the sign of the first element + Y = b3CastiTo128f(_mm_shuffle_epi32(NQi, B3_SHUFFLE(3, 2, 0, 3))); // -W -Z -X -W + Z = b3CastiTo128f(_mm_shuffle_epi32(Qi, B3_SHUFFLE(1, 0, 1, 3))); // Y X Y W vs = _mm_load_ss(&s); V21 = V21 * Y; V31 = V31 * Z; V1 = V1 + V11; - V2 = V2 + V21; - V3 = V3 + V31; + V2 = V2 + V21; + V3 = V3 + V31; - vs = b3_splat3_ps(vs, 0); - // s ready - V1 = V1 * vs; - V2 = V2 * vs; - V3 = V3 * vs; - - V1 = V1 + b3v1000; - V2 = V2 + b3v0100; - V3 = V3 + b3v0010; - - m_el[0] = b3MakeVector3(V1); - m_el[1] = b3MakeVector3(V2); - m_el[2] = b3MakeVector3(V3); - #else - b3Scalar xs = q.getX() * s, ys = q.getY() * s, zs = q.getZ() * s; - b3Scalar wx = q.getW() * xs, wy = q.getW() * ys, wz = q.getW() * zs; - b3Scalar xx = q.getX() * xs, xy = q.getX() * ys, xz = q.getX() * zs; - b3Scalar yy = q.getY() * ys, yz = q.getY() * zs, zz = q.getZ() * zs; + vs = b3_splat3_ps(vs, 0); + // s ready + V1 = V1 * vs; + V2 = V2 * vs; + V3 = V3 * vs; + + V1 = V1 + b3v1000; + V2 = V2 + b3v0100; + V3 = V3 + b3v0010; + + m_el[0] = b3MakeVector3(V1); + m_el[1] = b3MakeVector3(V2); + m_el[2] = b3MakeVector3(V3); +#else + b3Scalar xs = q.getX() * s, ys = q.getY() * s, zs = q.getZ() * s; + b3Scalar wx = q.getW() * xs, wy = q.getW() * ys, wz = q.getW() * zs; + b3Scalar xx = q.getX() * xs, xy = q.getX() * ys, xz = q.getX() * zs; + b3Scalar yy = q.getY() * ys, yz = q.getY() * zs, zz = q.getZ() * zs; setValue( - b3Scalar(1.0) - (yy + zz), xy - wz, xz + wy, + b3Scalar(1.0) - (yy + zz), xy - wz, xz + wy, xy + wz, b3Scalar(1.0) - (xx + zz), yz - wx, xz - wy, yz + wx, b3Scalar(1.0) - (xx + yy)); - #endif - } - +#endif + } /** @brief Set the matrix from euler angles using YPR around YXZ respectively * @param yaw Yaw about Y axis * @param pitch Pitch about X axis * @param roll Roll about Z axis */ - void setEulerYPR(const b3Scalar& yaw, const b3Scalar& pitch, const b3Scalar& roll) + void setEulerYPR(const b3Scalar& yaw, const b3Scalar& pitch, const b3Scalar& roll) { setEulerZYX(roll, pitch, yaw); } @@ -290,182 +286,197 @@ public: * angles are applied in ZYX order. I.e a vector is first rotated * about X then Y and then Z **/ - void setEulerZYX(b3Scalar eulerX,b3Scalar eulerY,b3Scalar eulerZ) { + void setEulerZYX(b3Scalar eulerX, b3Scalar eulerY, b3Scalar eulerZ) + { ///@todo proposed to reverse this since it's labeled zyx but takes arguments xyz and it will match all other parts of the code - b3Scalar ci ( b3Cos(eulerX)); - b3Scalar cj ( b3Cos(eulerY)); - b3Scalar ch ( b3Cos(eulerZ)); - b3Scalar si ( b3Sin(eulerX)); - b3Scalar sj ( b3Sin(eulerY)); - b3Scalar sh ( b3Sin(eulerZ)); - b3Scalar cc = ci * ch; - b3Scalar cs = ci * sh; - b3Scalar sc = si * ch; + b3Scalar ci(b3Cos(eulerX)); + b3Scalar cj(b3Cos(eulerY)); + b3Scalar ch(b3Cos(eulerZ)); + b3Scalar si(b3Sin(eulerX)); + b3Scalar sj(b3Sin(eulerY)); + b3Scalar sh(b3Sin(eulerZ)); + b3Scalar cc = ci * ch; + b3Scalar cs = ci * sh; + b3Scalar sc = si * ch; b3Scalar ss = si * sh; setValue(cj * ch, sj * sc - cs, sj * cc + ss, - cj * sh, sj * ss + cc, sj * cs - sc, - -sj, cj * si, cj * ci); + cj * sh, sj * ss + cc, sj * cs - sc, + -sj, cj * si, cj * ci); } /**@brief Set the matrix to the identity */ void setIdentity() - { -#if (defined(B3_USE_SSE_IN_API)&& defined (B3_USE_SSE)) || defined(B3_USE_NEON) - m_el[0] = b3MakeVector3(b3v1000); - m_el[1] = b3MakeVector3(b3v0100); - m_el[2] = b3MakeVector3(b3v0010); + { +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) || defined(B3_USE_NEON) + m_el[0] = b3MakeVector3(b3v1000); + m_el[1] = b3MakeVector3(b3v0100); + m_el[2] = b3MakeVector3(b3v0010); #else - setValue(b3Scalar(1.0), b3Scalar(0.0), b3Scalar(0.0), - b3Scalar(0.0), b3Scalar(1.0), b3Scalar(0.0), - b3Scalar(0.0), b3Scalar(0.0), b3Scalar(1.0)); + setValue(b3Scalar(1.0), b3Scalar(0.0), b3Scalar(0.0), + b3Scalar(0.0), b3Scalar(1.0), b3Scalar(0.0), + b3Scalar(0.0), b3Scalar(0.0), b3Scalar(1.0)); #endif } - static const b3Matrix3x3& getIdentity() + static const b3Matrix3x3& getIdentity() { -#if (defined(B3_USE_SSE_IN_API)&& defined (B3_USE_SSE)) || defined(B3_USE_NEON) - static const b3Matrix3x3 - identityMatrix(b3v1000, b3v0100, b3v0010); +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) || defined(B3_USE_NEON) + static const b3Matrix3x3 + identityMatrix(b3v1000, b3v0100, b3v0010); #else - static const b3Matrix3x3 - identityMatrix( - b3Scalar(1.0), b3Scalar(0.0), b3Scalar(0.0), - b3Scalar(0.0), b3Scalar(1.0), b3Scalar(0.0), - b3Scalar(0.0), b3Scalar(0.0), b3Scalar(1.0)); + static const b3Matrix3x3 + identityMatrix( + b3Scalar(1.0), b3Scalar(0.0), b3Scalar(0.0), + b3Scalar(0.0), b3Scalar(1.0), b3Scalar(0.0), + b3Scalar(0.0), b3Scalar(0.0), b3Scalar(1.0)); #endif return identityMatrix; } /**@brief Fill the rotational part of an OpenGL matrix and clear the shear/perspective * @param m The array to be filled */ - void getOpenGLSubMatrix(b3Scalar *m) const + void getOpenGLSubMatrix(b3Scalar * m) const { -#if defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE) - __m128 v0 = m_el[0].mVec128; - __m128 v1 = m_el[1].mVec128; - __m128 v2 = m_el[2].mVec128; // x2 y2 z2 w2 - __m128 *vm = (__m128 *)m; - __m128 vT; - - v2 = _mm_and_ps(v2, b3vFFF0fMask); // x2 y2 z2 0 - - vT = _mm_unpackhi_ps(v0, v1); // z0 z1 * * - v0 = _mm_unpacklo_ps(v0, v1); // x0 x1 y0 y1 +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) + __m128 v0 = m_el[0].mVec128; + __m128 v1 = m_el[1].mVec128; + __m128 v2 = m_el[2].mVec128; // x2 y2 z2 w2 + __m128* vm = (__m128*)m; + __m128 vT; - v1 = _mm_shuffle_ps(v0, v2, B3_SHUFFLE(2, 3, 1, 3) ); // y0 y1 y2 0 - v0 = _mm_shuffle_ps(v0, v2, B3_SHUFFLE(0, 1, 0, 3) ); // x0 x1 x2 0 - v2 = b3CastdTo128f(_mm_move_sd(b3CastfTo128d(v2), b3CastfTo128d(vT))); // z0 z1 z2 0 + v2 = _mm_and_ps(v2, b3vFFF0fMask); // x2 y2 z2 0 - vm[0] = v0; - vm[1] = v1; - vm[2] = v2; + vT = _mm_unpackhi_ps(v0, v1); // z0 z1 * * + v0 = _mm_unpacklo_ps(v0, v1); // x0 x1 y0 y1 + + v1 = _mm_shuffle_ps(v0, v2, B3_SHUFFLE(2, 3, 1, 3)); // y0 y1 y2 0 + v0 = _mm_shuffle_ps(v0, v2, B3_SHUFFLE(0, 1, 0, 3)); // x0 x1 x2 0 + v2 = b3CastdTo128f(_mm_move_sd(b3CastfTo128d(v2), b3CastfTo128d(vT))); // z0 z1 z2 0 + + vm[0] = v0; + vm[1] = v1; + vm[2] = v2; #elif defined(B3_USE_NEON) - // note: zeros the w channel. We can preserve it at the cost of two more vtrn instructions. - static const uint32x2_t zMask = (const uint32x2_t) {-1, 0 }; - float32x4_t *vm = (float32x4_t *)m; - float32x4x2_t top = vtrnq_f32( m_el[0].mVec128, m_el[1].mVec128 ); // {x0 x1 z0 z1}, {y0 y1 w0 w1} - float32x2x2_t bl = vtrn_f32( vget_low_f32(m_el[2].mVec128), vdup_n_f32(0.0f) ); // {x2 0 }, {y2 0} - float32x4_t v0 = vcombine_f32( vget_low_f32(top.val[0]), bl.val[0] ); - float32x4_t v1 = vcombine_f32( vget_low_f32(top.val[1]), bl.val[1] ); - float32x2_t q = (float32x2_t) vand_u32( (uint32x2_t) vget_high_f32( m_el[2].mVec128), zMask ); - float32x4_t v2 = vcombine_f32( vget_high_f32(top.val[0]), q ); // z0 z1 z2 0 + // note: zeros the w channel. We can preserve it at the cost of two more vtrn instructions. + static const uint32x2_t zMask = (const uint32x2_t){-1, 0}; + float32x4_t* vm = (float32x4_t*)m; + float32x4x2_t top = vtrnq_f32(m_el[0].mVec128, m_el[1].mVec128); // {x0 x1 z0 z1}, {y0 y1 w0 w1} + float32x2x2_t bl = vtrn_f32(vget_low_f32(m_el[2].mVec128), vdup_n_f32(0.0f)); // {x2 0 }, {y2 0} + float32x4_t v0 = vcombine_f32(vget_low_f32(top.val[0]), bl.val[0]); + float32x4_t v1 = vcombine_f32(vget_low_f32(top.val[1]), bl.val[1]); + float32x2_t q = (float32x2_t)vand_u32((uint32x2_t)vget_high_f32(m_el[2].mVec128), zMask); + float32x4_t v2 = vcombine_f32(vget_high_f32(top.val[0]), q); // z0 z1 z2 0 - vm[0] = v0; - vm[1] = v1; - vm[2] = v2; + vm[0] = v0; + vm[1] = v1; + vm[2] = v2; #else - m[0] = b3Scalar(m_el[0].getX()); - m[1] = b3Scalar(m_el[1].getX()); - m[2] = b3Scalar(m_el[2].getX()); - m[3] = b3Scalar(0.0); - m[4] = b3Scalar(m_el[0].getY()); - m[5] = b3Scalar(m_el[1].getY()); - m[6] = b3Scalar(m_el[2].getY()); - m[7] = b3Scalar(0.0); - m[8] = b3Scalar(m_el[0].getZ()); - m[9] = b3Scalar(m_el[1].getZ()); + m[0] = b3Scalar(m_el[0].getX()); + m[1] = b3Scalar(m_el[1].getX()); + m[2] = b3Scalar(m_el[2].getX()); + m[3] = b3Scalar(0.0); + m[4] = b3Scalar(m_el[0].getY()); + m[5] = b3Scalar(m_el[1].getY()); + m[6] = b3Scalar(m_el[2].getY()); + m[7] = b3Scalar(0.0); + m[8] = b3Scalar(m_el[0].getZ()); + m[9] = b3Scalar(m_el[1].getZ()); m[10] = b3Scalar(m_el[2].getZ()); - m[11] = b3Scalar(0.0); + m[11] = b3Scalar(0.0); #endif } /**@brief Get the matrix represented as a quaternion * @param q The quaternion which will be set */ - void getRotation(b3Quaternion& q) const + void getRotation(b3Quaternion & q) const { -#if (defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE))|| defined (B3_USE_NEON) - b3Scalar trace = m_el[0].getX() + m_el[1].getY() + m_el[2].getZ(); - b3Scalar s, x; - - union { - b3SimdFloat4 vec; - b3Scalar f[4]; - } temp; - - if (trace > b3Scalar(0.0)) - { - x = trace + b3Scalar(1.0); +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) || defined(B3_USE_NEON) + b3Scalar trace = m_el[0].getX() + m_el[1].getY() + m_el[2].getZ(); + b3Scalar s, x; - temp.f[0]=m_el[2].getY() - m_el[1].getZ(); - temp.f[1]=m_el[0].getZ() - m_el[2].getX(); - temp.f[2]=m_el[1].getX() - m_el[0].getY(); - temp.f[3]=x; - //temp.f[3]= s * b3Scalar(0.5); - } - else - { - int i, j, k; - if(m_el[0].getX() < m_el[1].getY()) - { - if( m_el[1].getY() < m_el[2].getZ() ) - { i = 2; j = 0; k = 1; } - else - { i = 1; j = 2; k = 0; } - } - else - { - if( m_el[0].getX() < m_el[2].getZ()) - { i = 2; j = 0; k = 1; } - else - { i = 0; j = 1; k = 2; } - } + union { + b3SimdFloat4 vec; + b3Scalar f[4]; + } temp; - x = m_el[i][i] - m_el[j][j] - m_el[k][k] + b3Scalar(1.0); + if (trace > b3Scalar(0.0)) + { + x = trace + b3Scalar(1.0); - temp.f[3] = (m_el[k][j] - m_el[j][k]); - temp.f[j] = (m_el[j][i] + m_el[i][j]); - temp.f[k] = (m_el[k][i] + m_el[i][k]); - temp.f[i] = x; - //temp.f[i] = s * b3Scalar(0.5); - } + temp.f[0] = m_el[2].getY() - m_el[1].getZ(); + temp.f[1] = m_el[0].getZ() - m_el[2].getX(); + temp.f[2] = m_el[1].getX() - m_el[0].getY(); + temp.f[3] = x; + //temp.f[3]= s * b3Scalar(0.5); + } + else + { + int i, j, k; + if (m_el[0].getX() < m_el[1].getY()) + { + if (m_el[1].getY() < m_el[2].getZ()) + { + i = 2; + j = 0; + k = 1; + } + else + { + i = 1; + j = 2; + k = 0; + } + } + else + { + if (m_el[0].getX() < m_el[2].getZ()) + { + i = 2; + j = 0; + k = 1; + } + else + { + i = 0; + j = 1; + k = 2; + } + } - s = b3Sqrt(x); - q.set128(temp.vec); - s = b3Scalar(0.5) / s; + x = m_el[i][i] - m_el[j][j] - m_el[k][k] + b3Scalar(1.0); - q *= s; -#else + temp.f[3] = (m_el[k][j] - m_el[j][k]); + temp.f[j] = (m_el[j][i] + m_el[i][j]); + temp.f[k] = (m_el[k][i] + m_el[i][k]); + temp.f[i] = x; + //temp.f[i] = s * b3Scalar(0.5); + } + + s = b3Sqrt(x); + q.set128(temp.vec); + s = b3Scalar(0.5) / s; + + q *= s; +#else b3Scalar trace = m_el[0].getX() + m_el[1].getY() + m_el[2].getZ(); b3Scalar temp[4]; - if (trace > b3Scalar(0.0)) + if (trace > b3Scalar(0.0)) { b3Scalar s = b3Sqrt(trace + b3Scalar(1.0)); - temp[3]=(s * b3Scalar(0.5)); + temp[3] = (s * b3Scalar(0.5)); s = b3Scalar(0.5) / s; - temp[0]=((m_el[2].getY() - m_el[1].getZ()) * s); - temp[1]=((m_el[0].getZ() - m_el[2].getX()) * s); - temp[2]=((m_el[1].getX() - m_el[0].getY()) * s); - } - else + temp[0] = ((m_el[2].getY() - m_el[1].getZ()) * s); + temp[1] = ((m_el[0].getZ() - m_el[2].getX()) * s); + temp[2] = ((m_el[1].getX() - m_el[0].getY()) * s); + } + else { - int i = m_el[0].getX() < m_el[1].getY() ? - (m_el[1].getY() < m_el[2].getZ() ? 2 : 1) : - (m_el[0].getX() < m_el[2].getZ() ? 2 : 0); - int j = (i + 1) % 3; + int i = m_el[0].getX() < m_el[1].getY() ? (m_el[1].getY() < m_el[2].getZ() ? 2 : 1) : (m_el[0].getX() < m_el[2].getZ() ? 2 : 0); + int j = (i + 1) % 3; int k = (i + 2) % 3; b3Scalar s = b3Sqrt(m_el[i][i] - m_el[j][j] - m_el[k][k] + b3Scalar(1.0)); @@ -476,44 +487,42 @@ public: temp[j] = (m_el[j][i] + m_el[i][j]) * s; temp[k] = (m_el[k][i] + m_el[i][k]) * s; } - q.setValue(temp[0],temp[1],temp[2],temp[3]); + q.setValue(temp[0], temp[1], temp[2], temp[3]); #endif } /**@brief Get the matrix represented as euler angles around YXZ, roundtrip with setEulerYPR * @param yaw Yaw around Y axis * @param pitch Pitch around X axis - * @param roll around Z axis */ - void getEulerYPR(b3Scalar& yaw, b3Scalar& pitch, b3Scalar& roll) const + * @param roll around Z axis */ + void getEulerYPR(b3Scalar & yaw, b3Scalar & pitch, b3Scalar & roll) const { - // first use the normal calculus yaw = b3Scalar(b3Atan2(m_el[1].getX(), m_el[0].getX())); pitch = b3Scalar(b3Asin(-m_el[2].getX())); roll = b3Scalar(b3Atan2(m_el[2].getY(), m_el[2].getZ())); // on pitch = +/-HalfPI - if (b3Fabs(pitch)==B3_HALF_PI) + if (b3Fabs(pitch) == B3_HALF_PI) { - if (yaw>0) - yaw-=B3_PI; + if (yaw > 0) + yaw -= B3_PI; else - yaw+=B3_PI; + yaw += B3_PI; - if (roll>0) - roll-=B3_PI; + if (roll > 0) + roll -= B3_PI; else - roll+=B3_PI; + roll += B3_PI; } }; - /**@brief Get the matrix represented as euler angles around ZYX * @param yaw Yaw around X axis * @param pitch Pitch around Y axis * @param roll around X axis - * @param solution_number Which solution of two possible solutions ( 1 or 2) are possible values*/ - void getEulerZYX(b3Scalar& yaw, b3Scalar& pitch, b3Scalar& roll, unsigned int solution_number = 1) const + * @param solution_number Which solution of two possible solutions ( 1 or 2) are possible values*/ + void getEulerZYX(b3Scalar & yaw, b3Scalar & pitch, b3Scalar & roll, unsigned int solution_number = 1) const { struct Euler { @@ -523,7 +532,7 @@ public: }; Euler euler_out; - Euler euler_out2; //second solution + Euler euler_out2; //second solution //get the pointer to the raw data // Check that pitch is not at a singularity @@ -533,7 +542,7 @@ public: euler_out2.yaw = 0; // From difference of angles formula - b3Scalar delta = b3Atan2(m_el[0].getX(),m_el[0].getZ()); + b3Scalar delta = b3Atan2(m_el[0].getX(), m_el[0].getZ()); if (m_el[2].getX() > 0) //gimbal locked up { euler_out.pitch = B3_PI / b3Scalar(2.0); @@ -541,7 +550,7 @@ public: euler_out.roll = euler_out.pitch + delta; euler_out2.roll = euler_out.pitch + delta; } - else // gimbal locked down + else // gimbal locked down { euler_out.pitch = -B3_PI / b3Scalar(2.0); euler_out2.pitch = -B3_PI / b3Scalar(2.0); @@ -551,29 +560,29 @@ public: } else { - euler_out.pitch = - b3Asin(m_el[2].getX()); + euler_out.pitch = -b3Asin(m_el[2].getX()); euler_out2.pitch = B3_PI - euler_out.pitch; - euler_out.roll = b3Atan2(m_el[2].getY()/b3Cos(euler_out.pitch), - m_el[2].getZ()/b3Cos(euler_out.pitch)); - euler_out2.roll = b3Atan2(m_el[2].getY()/b3Cos(euler_out2.pitch), - m_el[2].getZ()/b3Cos(euler_out2.pitch)); + euler_out.roll = b3Atan2(m_el[2].getY() / b3Cos(euler_out.pitch), + m_el[2].getZ() / b3Cos(euler_out.pitch)); + euler_out2.roll = b3Atan2(m_el[2].getY() / b3Cos(euler_out2.pitch), + m_el[2].getZ() / b3Cos(euler_out2.pitch)); - euler_out.yaw = b3Atan2(m_el[1].getX()/b3Cos(euler_out.pitch), - m_el[0].getX()/b3Cos(euler_out.pitch)); - euler_out2.yaw = b3Atan2(m_el[1].getX()/b3Cos(euler_out2.pitch), - m_el[0].getX()/b3Cos(euler_out2.pitch)); + euler_out.yaw = b3Atan2(m_el[1].getX() / b3Cos(euler_out.pitch), + m_el[0].getX() / b3Cos(euler_out.pitch)); + euler_out2.yaw = b3Atan2(m_el[1].getX() / b3Cos(euler_out2.pitch), + m_el[0].getX() / b3Cos(euler_out2.pitch)); } if (solution_number == 1) - { - yaw = euler_out.yaw; + { + yaw = euler_out.yaw; pitch = euler_out.pitch; roll = euler_out.roll; } else - { - yaw = euler_out2.yaw; + { + yaw = euler_out2.yaw; pitch = euler_out2.pitch; roll = euler_out2.roll; } @@ -584,18 +593,18 @@ public: b3Matrix3x3 scaled(const b3Vector3& s) const { -#if (defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE))|| defined (B3_USE_NEON) +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) || defined(B3_USE_NEON) return b3Matrix3x3(m_el[0] * s, m_el[1] * s, m_el[2] * s); -#else +#else return b3Matrix3x3( - m_el[0].getX() * s.getX(), m_el[0].getY() * s.getY(), m_el[0].getZ() * s.getZ(), + m_el[0].getX() * s.getX(), m_el[0].getY() * s.getY(), m_el[0].getZ() * s.getZ(), m_el[1].getX() * s.getX(), m_el[1].getY() * s.getY(), m_el[1].getZ() * s.getZ(), m_el[2].getX() * s.getX(), m_el[2].getY() * s.getY(), m_el[2].getZ() * s.getZ()); #endif } /**@brief Return the determinant of the matrix */ - b3Scalar determinant() const; + b3Scalar determinant() const; /**@brief Return the adjoint of the matrix */ b3Matrix3x3 adjoint() const; /**@brief Return the matrix with all values non negative */ @@ -603,25 +612,24 @@ public: /**@brief Return the transpose of the matrix */ b3Matrix3x3 transpose() const; /**@brief Return the inverse of the matrix */ - b3Matrix3x3 inverse() const; + b3Matrix3x3 inverse() const; b3Matrix3x3 transposeTimes(const b3Matrix3x3& m) const; b3Matrix3x3 timesTranspose(const b3Matrix3x3& m) const; - B3_FORCE_INLINE b3Scalar tdotx(const b3Vector3& v) const + B3_FORCE_INLINE b3Scalar tdotx(const b3Vector3& v) const { return m_el[0].getX() * v.getX() + m_el[1].getX() * v.getY() + m_el[2].getX() * v.getZ(); } - B3_FORCE_INLINE b3Scalar tdoty(const b3Vector3& v) const + B3_FORCE_INLINE b3Scalar tdoty(const b3Vector3& v) const { return m_el[0].getY() * v.getX() + m_el[1].getY() * v.getY() + m_el[2].getY() * v.getZ(); } - B3_FORCE_INLINE b3Scalar tdotz(const b3Vector3& v) const + B3_FORCE_INLINE b3Scalar tdotz(const b3Vector3& v) const { return m_el[0].getZ() * v.getX() + m_el[1].getZ() * v.getY() + m_el[2].getZ() * v.getZ(); } - /**@brief diagonalizes this matrix by the Jacobi method. * @param rot stores the rotation from the coordinate system in which the matrix is diagonal to the original * coordinate system, i.e., old_this = rot * new_this * rot^T. @@ -631,7 +639,7 @@ public: * * Note that this matrix is assumed to be symmetric. */ - void diagonalize(b3Matrix3x3& rot, b3Scalar threshold, int maxSteps) + void diagonalize(b3Matrix3x3 & rot, b3Scalar threshold, int maxSteps) { rot.setIdentity(); for (int step = maxSteps; step > 0; step--) @@ -667,7 +675,7 @@ public: step = 1; } - // compute Jacobi rotation J which leads to a zero for element [p][q] + // compute Jacobi rotation J which leads to a zero for element [p][q] b3Scalar mpq = m_el[p][q]; b3Scalar theta = (m_el[q][q] - m_el[p][p]) / (2 * mpq); b3Scalar theta2 = theta * theta; @@ -676,7 +684,7 @@ public: if (theta2 * theta2 < b3Scalar(10 / B3_EPSILON)) { t = (theta >= 0) ? 1 / (theta + b3Sqrt(1 + theta2)) - : 1 / (theta - b3Sqrt(1 + theta2)); + : 1 / (theta - b3Sqrt(1 + theta2)); cos = 1 / b3Sqrt(1 + t * t); sin = cos * t; } @@ -709,9 +717,6 @@ public: } } - - - /**@brief Calculate the matrix cofactor * @param r1 The first row to use for calculating the cofactor * @param c1 The first column to use for calculating the cofactor @@ -719,304 +724,298 @@ public: * @param c1 The second column to use for calculating the cofactor * See http://en.wikipedia.org/wiki/Cofactor_(linear_algebra) for more details */ - b3Scalar cofac(int r1, int c1, int r2, int c2) const + b3Scalar cofac(int r1, int c1, int r2, int c2) const { return m_el[r1][c1] * m_el[r2][c2] - m_el[r1][c2] * m_el[r2][c1]; } - void serialize(struct b3Matrix3x3Data& dataOut) const; + void serialize(struct b3Matrix3x3Data & dataOut) const; - void serializeFloat(struct b3Matrix3x3FloatData& dataOut) const; + void serializeFloat(struct b3Matrix3x3FloatData & dataOut) const; - void deSerialize(const struct b3Matrix3x3Data& dataIn); + void deSerialize(const struct b3Matrix3x3Data& dataIn); - void deSerializeFloat(const struct b3Matrix3x3FloatData& dataIn); - - void deSerializeDouble(const struct b3Matrix3x3DoubleData& dataIn); + void deSerializeFloat(const struct b3Matrix3x3FloatData& dataIn); + void deSerializeDouble(const struct b3Matrix3x3DoubleData& dataIn); }; - -B3_FORCE_INLINE b3Matrix3x3& +B3_FORCE_INLINE b3Matrix3x3& b3Matrix3x3::operator*=(const b3Matrix3x3& m) { -#if defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE) - __m128 rv00, rv01, rv02; - __m128 rv10, rv11, rv12; - __m128 rv20, rv21, rv22; - __m128 mv0, mv1, mv2; +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) + __m128 rv00, rv01, rv02; + __m128 rv10, rv11, rv12; + __m128 rv20, rv21, rv22; + __m128 mv0, mv1, mv2; - rv02 = m_el[0].mVec128; - rv12 = m_el[1].mVec128; - rv22 = m_el[2].mVec128; + rv02 = m_el[0].mVec128; + rv12 = m_el[1].mVec128; + rv22 = m_el[2].mVec128; - mv0 = _mm_and_ps(m[0].mVec128, b3vFFF0fMask); - mv1 = _mm_and_ps(m[1].mVec128, b3vFFF0fMask); - mv2 = _mm_and_ps(m[2].mVec128, b3vFFF0fMask); - - // rv0 - rv00 = b3_splat_ps(rv02, 0); - rv01 = b3_splat_ps(rv02, 1); - rv02 = b3_splat_ps(rv02, 2); - - rv00 = _mm_mul_ps(rv00, mv0); - rv01 = _mm_mul_ps(rv01, mv1); - rv02 = _mm_mul_ps(rv02, mv2); - - // rv1 - rv10 = b3_splat_ps(rv12, 0); - rv11 = b3_splat_ps(rv12, 1); - rv12 = b3_splat_ps(rv12, 2); - - rv10 = _mm_mul_ps(rv10, mv0); - rv11 = _mm_mul_ps(rv11, mv1); - rv12 = _mm_mul_ps(rv12, mv2); - - // rv2 - rv20 = b3_splat_ps(rv22, 0); - rv21 = b3_splat_ps(rv22, 1); - rv22 = b3_splat_ps(rv22, 2); - - rv20 = _mm_mul_ps(rv20, mv0); - rv21 = _mm_mul_ps(rv21, mv1); - rv22 = _mm_mul_ps(rv22, mv2); + mv0 = _mm_and_ps(m[0].mVec128, b3vFFF0fMask); + mv1 = _mm_and_ps(m[1].mVec128, b3vFFF0fMask); + mv2 = _mm_and_ps(m[2].mVec128, b3vFFF0fMask); - rv00 = _mm_add_ps(rv00, rv01); - rv10 = _mm_add_ps(rv10, rv11); - rv20 = _mm_add_ps(rv20, rv21); + // rv0 + rv00 = b3_splat_ps(rv02, 0); + rv01 = b3_splat_ps(rv02, 1); + rv02 = b3_splat_ps(rv02, 2); - m_el[0].mVec128 = _mm_add_ps(rv00, rv02); - m_el[1].mVec128 = _mm_add_ps(rv10, rv12); - m_el[2].mVec128 = _mm_add_ps(rv20, rv22); + rv00 = _mm_mul_ps(rv00, mv0); + rv01 = _mm_mul_ps(rv01, mv1); + rv02 = _mm_mul_ps(rv02, mv2); + + // rv1 + rv10 = b3_splat_ps(rv12, 0); + rv11 = b3_splat_ps(rv12, 1); + rv12 = b3_splat_ps(rv12, 2); + + rv10 = _mm_mul_ps(rv10, mv0); + rv11 = _mm_mul_ps(rv11, mv1); + rv12 = _mm_mul_ps(rv12, mv2); + + // rv2 + rv20 = b3_splat_ps(rv22, 0); + rv21 = b3_splat_ps(rv22, 1); + rv22 = b3_splat_ps(rv22, 2); + + rv20 = _mm_mul_ps(rv20, mv0); + rv21 = _mm_mul_ps(rv21, mv1); + rv22 = _mm_mul_ps(rv22, mv2); + + rv00 = _mm_add_ps(rv00, rv01); + rv10 = _mm_add_ps(rv10, rv11); + rv20 = _mm_add_ps(rv20, rv21); + + m_el[0].mVec128 = _mm_add_ps(rv00, rv02); + m_el[1].mVec128 = _mm_add_ps(rv10, rv12); + m_el[2].mVec128 = _mm_add_ps(rv20, rv22); #elif defined(B3_USE_NEON) - float32x4_t rv0, rv1, rv2; - float32x4_t v0, v1, v2; - float32x4_t mv0, mv1, mv2; + float32x4_t rv0, rv1, rv2; + float32x4_t v0, v1, v2; + float32x4_t mv0, mv1, mv2; - v0 = m_el[0].mVec128; - v1 = m_el[1].mVec128; - v2 = m_el[2].mVec128; + v0 = m_el[0].mVec128; + v1 = m_el[1].mVec128; + v2 = m_el[2].mVec128; - mv0 = (float32x4_t) vandq_s32((int32x4_t)m[0].mVec128, b3vFFF0Mask); - mv1 = (float32x4_t) vandq_s32((int32x4_t)m[1].mVec128, b3vFFF0Mask); - mv2 = (float32x4_t) vandq_s32((int32x4_t)m[2].mVec128, b3vFFF0Mask); - - rv0 = vmulq_lane_f32(mv0, vget_low_f32(v0), 0); - rv1 = vmulq_lane_f32(mv0, vget_low_f32(v1), 0); - rv2 = vmulq_lane_f32(mv0, vget_low_f32(v2), 0); - - rv0 = vmlaq_lane_f32(rv0, mv1, vget_low_f32(v0), 1); - rv1 = vmlaq_lane_f32(rv1, mv1, vget_low_f32(v1), 1); - rv2 = vmlaq_lane_f32(rv2, mv1, vget_low_f32(v2), 1); - - rv0 = vmlaq_lane_f32(rv0, mv2, vget_high_f32(v0), 0); - rv1 = vmlaq_lane_f32(rv1, mv2, vget_high_f32(v1), 0); - rv2 = vmlaq_lane_f32(rv2, mv2, vget_high_f32(v2), 0); + mv0 = (float32x4_t)vandq_s32((int32x4_t)m[0].mVec128, b3vFFF0Mask); + mv1 = (float32x4_t)vandq_s32((int32x4_t)m[1].mVec128, b3vFFF0Mask); + mv2 = (float32x4_t)vandq_s32((int32x4_t)m[2].mVec128, b3vFFF0Mask); - m_el[0].mVec128 = rv0; - m_el[1].mVec128 = rv1; - m_el[2].mVec128 = rv2; -#else + rv0 = vmulq_lane_f32(mv0, vget_low_f32(v0), 0); + rv1 = vmulq_lane_f32(mv0, vget_low_f32(v1), 0); + rv2 = vmulq_lane_f32(mv0, vget_low_f32(v2), 0); + + rv0 = vmlaq_lane_f32(rv0, mv1, vget_low_f32(v0), 1); + rv1 = vmlaq_lane_f32(rv1, mv1, vget_low_f32(v1), 1); + rv2 = vmlaq_lane_f32(rv2, mv1, vget_low_f32(v2), 1); + + rv0 = vmlaq_lane_f32(rv0, mv2, vget_high_f32(v0), 0); + rv1 = vmlaq_lane_f32(rv1, mv2, vget_high_f32(v1), 0); + rv2 = vmlaq_lane_f32(rv2, mv2, vget_high_f32(v2), 0); + + m_el[0].mVec128 = rv0; + m_el[1].mVec128 = rv1; + m_el[2].mVec128 = rv2; +#else setValue( - m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]), + m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]), m.tdotx(m_el[1]), m.tdoty(m_el[1]), m.tdotz(m_el[1]), m.tdotx(m_el[2]), m.tdoty(m_el[2]), m.tdotz(m_el[2])); #endif return *this; } -B3_FORCE_INLINE b3Matrix3x3& +B3_FORCE_INLINE b3Matrix3x3& b3Matrix3x3::operator+=(const b3Matrix3x3& m) { -#if (defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE))|| defined (B3_USE_NEON) - m_el[0].mVec128 = m_el[0].mVec128 + m.m_el[0].mVec128; - m_el[1].mVec128 = m_el[1].mVec128 + m.m_el[1].mVec128; - m_el[2].mVec128 = m_el[2].mVec128 + m.m_el[2].mVec128; +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) || defined(B3_USE_NEON) + m_el[0].mVec128 = m_el[0].mVec128 + m.m_el[0].mVec128; + m_el[1].mVec128 = m_el[1].mVec128 + m.m_el[1].mVec128; + m_el[2].mVec128 = m_el[2].mVec128 + m.m_el[2].mVec128; #else setValue( - m_el[0][0]+m.m_el[0][0], - m_el[0][1]+m.m_el[0][1], - m_el[0][2]+m.m_el[0][2], - m_el[1][0]+m.m_el[1][0], - m_el[1][1]+m.m_el[1][1], - m_el[1][2]+m.m_el[1][2], - m_el[2][0]+m.m_el[2][0], - m_el[2][1]+m.m_el[2][1], - m_el[2][2]+m.m_el[2][2]); + m_el[0][0] + m.m_el[0][0], + m_el[0][1] + m.m_el[0][1], + m_el[0][2] + m.m_el[0][2], + m_el[1][0] + m.m_el[1][0], + m_el[1][1] + m.m_el[1][1], + m_el[1][2] + m.m_el[1][2], + m_el[2][0] + m.m_el[2][0], + m_el[2][1] + m.m_el[2][1], + m_el[2][2] + m.m_el[2][2]); #endif return *this; } B3_FORCE_INLINE b3Matrix3x3 -operator*(const b3Matrix3x3& m, const b3Scalar & k) +operator*(const b3Matrix3x3& m, const b3Scalar& k) { -#if (defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE)) - __m128 vk = b3_splat_ps(_mm_load_ss((float *)&k), 0x80); - return b3Matrix3x3( - _mm_mul_ps(m[0].mVec128, vk), - _mm_mul_ps(m[1].mVec128, vk), - _mm_mul_ps(m[2].mVec128, vk)); +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) + __m128 vk = b3_splat_ps(_mm_load_ss((float*)&k), 0x80); + return b3Matrix3x3( + _mm_mul_ps(m[0].mVec128, vk), + _mm_mul_ps(m[1].mVec128, vk), + _mm_mul_ps(m[2].mVec128, vk)); #elif defined(B3_USE_NEON) - return b3Matrix3x3( - vmulq_n_f32(m[0].mVec128, k), - vmulq_n_f32(m[1].mVec128, k), - vmulq_n_f32(m[2].mVec128, k)); + return b3Matrix3x3( + vmulq_n_f32(m[0].mVec128, k), + vmulq_n_f32(m[1].mVec128, k), + vmulq_n_f32(m[2].mVec128, k)); #else return b3Matrix3x3( - m[0].getX()*k,m[0].getY()*k,m[0].getZ()*k, - m[1].getX()*k,m[1].getY()*k,m[1].getZ()*k, - m[2].getX()*k,m[2].getY()*k,m[2].getZ()*k); + m[0].getX() * k, m[0].getY() * k, m[0].getZ() * k, + m[1].getX() * k, m[1].getY() * k, m[1].getZ() * k, + m[2].getX() * k, m[2].getY() * k, m[2].getZ() * k); #endif } -B3_FORCE_INLINE b3Matrix3x3 +B3_FORCE_INLINE b3Matrix3x3 operator+(const b3Matrix3x3& m1, const b3Matrix3x3& m2) { -#if (defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE))|| defined (B3_USE_NEON) +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) || defined(B3_USE_NEON) return b3Matrix3x3( - m1[0].mVec128 + m2[0].mVec128, - m1[1].mVec128 + m2[1].mVec128, - m1[2].mVec128 + m2[2].mVec128); + m1[0].mVec128 + m2[0].mVec128, + m1[1].mVec128 + m2[1].mVec128, + m1[2].mVec128 + m2[2].mVec128); #else return b3Matrix3x3( - m1[0][0]+m2[0][0], - m1[0][1]+m2[0][1], - m1[0][2]+m2[0][2], - - m1[1][0]+m2[1][0], - m1[1][1]+m2[1][1], - m1[1][2]+m2[1][2], - - m1[2][0]+m2[2][0], - m1[2][1]+m2[2][1], - m1[2][2]+m2[2][2]); -#endif -} + m1[0][0] + m2[0][0], + m1[0][1] + m2[0][1], + m1[0][2] + m2[0][2], -B3_FORCE_INLINE b3Matrix3x3 -operator-(const b3Matrix3x3& m1, const b3Matrix3x3& m2) -{ -#if (defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE))|| defined (B3_USE_NEON) - return b3Matrix3x3( - m1[0].mVec128 - m2[0].mVec128, - m1[1].mVec128 - m2[1].mVec128, - m1[2].mVec128 - m2[2].mVec128); -#else - return b3Matrix3x3( - m1[0][0]-m2[0][0], - m1[0][1]-m2[0][1], - m1[0][2]-m2[0][2], - - m1[1][0]-m2[1][0], - m1[1][1]-m2[1][1], - m1[1][2]-m2[1][2], - - m1[2][0]-m2[2][0], - m1[2][1]-m2[2][1], - m1[2][2]-m2[2][2]); + m1[1][0] + m2[1][0], + m1[1][1] + m2[1][1], + m1[1][2] + m2[1][2], + + m1[2][0] + m2[2][0], + m1[2][1] + m2[2][1], + m1[2][2] + m2[2][2]); #endif } +B3_FORCE_INLINE b3Matrix3x3 +operator-(const b3Matrix3x3& m1, const b3Matrix3x3& m2) +{ +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) || defined(B3_USE_NEON) + return b3Matrix3x3( + m1[0].mVec128 - m2[0].mVec128, + m1[1].mVec128 - m2[1].mVec128, + m1[2].mVec128 - m2[2].mVec128); +#else + return b3Matrix3x3( + m1[0][0] - m2[0][0], + m1[0][1] - m2[0][1], + m1[0][2] - m2[0][2], -B3_FORCE_INLINE b3Matrix3x3& + m1[1][0] - m2[1][0], + m1[1][1] - m2[1][1], + m1[1][2] - m2[1][2], + + m1[2][0] - m2[2][0], + m1[2][1] - m2[2][1], + m1[2][2] - m2[2][2]); +#endif +} + +B3_FORCE_INLINE b3Matrix3x3& b3Matrix3x3::operator-=(const b3Matrix3x3& m) { -#if (defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE))|| defined (B3_USE_NEON) - m_el[0].mVec128 = m_el[0].mVec128 - m.m_el[0].mVec128; - m_el[1].mVec128 = m_el[1].mVec128 - m.m_el[1].mVec128; - m_el[2].mVec128 = m_el[2].mVec128 - m.m_el[2].mVec128; +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) || defined(B3_USE_NEON) + m_el[0].mVec128 = m_el[0].mVec128 - m.m_el[0].mVec128; + m_el[1].mVec128 = m_el[1].mVec128 - m.m_el[1].mVec128; + m_el[2].mVec128 = m_el[2].mVec128 - m.m_el[2].mVec128; #else setValue( - m_el[0][0]-m.m_el[0][0], - m_el[0][1]-m.m_el[0][1], - m_el[0][2]-m.m_el[0][2], - m_el[1][0]-m.m_el[1][0], - m_el[1][1]-m.m_el[1][1], - m_el[1][2]-m.m_el[1][2], - m_el[2][0]-m.m_el[2][0], - m_el[2][1]-m.m_el[2][1], - m_el[2][2]-m.m_el[2][2]); + m_el[0][0] - m.m_el[0][0], + m_el[0][1] - m.m_el[0][1], + m_el[0][2] - m.m_el[0][2], + m_el[1][0] - m.m_el[1][0], + m_el[1][1] - m.m_el[1][1], + m_el[1][2] - m.m_el[1][2], + m_el[2][0] - m.m_el[2][0], + m_el[2][1] - m.m_el[2][1], + m_el[2][2] - m.m_el[2][2]); #endif return *this; } - -B3_FORCE_INLINE b3Scalar +B3_FORCE_INLINE b3Scalar b3Matrix3x3::determinant() const -{ +{ return b3Triple((*this)[0], (*this)[1], (*this)[2]); } - -B3_FORCE_INLINE b3Matrix3x3 +B3_FORCE_INLINE b3Matrix3x3 b3Matrix3x3::absolute() const { -#if (defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE)) - return b3Matrix3x3( - _mm_and_ps(m_el[0].mVec128, b3vAbsfMask), - _mm_and_ps(m_el[1].mVec128, b3vAbsfMask), - _mm_and_ps(m_el[2].mVec128, b3vAbsfMask)); -#elif defined(B3_USE_NEON) - return b3Matrix3x3( - (float32x4_t)vandq_s32((int32x4_t)m_el[0].mVec128, b3v3AbsMask), - (float32x4_t)vandq_s32((int32x4_t)m_el[1].mVec128, b3v3AbsMask), - (float32x4_t)vandq_s32((int32x4_t)m_el[2].mVec128, b3v3AbsMask)); -#else +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) return b3Matrix3x3( - b3Fabs(m_el[0].getX()), b3Fabs(m_el[0].getY()), b3Fabs(m_el[0].getZ()), - b3Fabs(m_el[1].getX()), b3Fabs(m_el[1].getY()), b3Fabs(m_el[1].getZ()), - b3Fabs(m_el[2].getX()), b3Fabs(m_el[2].getY()), b3Fabs(m_el[2].getZ())); -#endif -} - -B3_FORCE_INLINE b3Matrix3x3 -b3Matrix3x3::transpose() const -{ -#if (defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE)) - __m128 v0 = m_el[0].mVec128; - __m128 v1 = m_el[1].mVec128; - __m128 v2 = m_el[2].mVec128; // x2 y2 z2 w2 - __m128 vT; - - v2 = _mm_and_ps(v2, b3vFFF0fMask); // x2 y2 z2 0 - - vT = _mm_unpackhi_ps(v0, v1); // z0 z1 * * - v0 = _mm_unpacklo_ps(v0, v1); // x0 x1 y0 y1 - - v1 = _mm_shuffle_ps(v0, v2, B3_SHUFFLE(2, 3, 1, 3) ); // y0 y1 y2 0 - v0 = _mm_shuffle_ps(v0, v2, B3_SHUFFLE(0, 1, 0, 3) ); // x0 x1 x2 0 - v2 = b3CastdTo128f(_mm_move_sd(b3CastfTo128d(v2), b3CastfTo128d(vT))); // z0 z1 z2 0 - - - return b3Matrix3x3( v0, v1, v2 ); + _mm_and_ps(m_el[0].mVec128, b3vAbsfMask), + _mm_and_ps(m_el[1].mVec128, b3vAbsfMask), + _mm_and_ps(m_el[2].mVec128, b3vAbsfMask)); #elif defined(B3_USE_NEON) - // note: zeros the w channel. We can preserve it at the cost of two more vtrn instructions. - static const uint32x2_t zMask = (const uint32x2_t) {-1, 0 }; - float32x4x2_t top = vtrnq_f32( m_el[0].mVec128, m_el[1].mVec128 ); // {x0 x1 z0 z1}, {y0 y1 w0 w1} - float32x2x2_t bl = vtrn_f32( vget_low_f32(m_el[2].mVec128), vdup_n_f32(0.0f) ); // {x2 0 }, {y2 0} - float32x4_t v0 = vcombine_f32( vget_low_f32(top.val[0]), bl.val[0] ); - float32x4_t v1 = vcombine_f32( vget_low_f32(top.val[1]), bl.val[1] ); - float32x2_t q = (float32x2_t) vand_u32( (uint32x2_t) vget_high_f32( m_el[2].mVec128), zMask ); - float32x4_t v2 = vcombine_f32( vget_high_f32(top.val[0]), q ); // z0 z1 z2 0 - return b3Matrix3x3( v0, v1, v2 ); + return b3Matrix3x3( + (float32x4_t)vandq_s32((int32x4_t)m_el[0].mVec128, b3v3AbsMask), + (float32x4_t)vandq_s32((int32x4_t)m_el[1].mVec128, b3v3AbsMask), + (float32x4_t)vandq_s32((int32x4_t)m_el[2].mVec128, b3v3AbsMask)); #else - return b3Matrix3x3( m_el[0].getX(), m_el[1].getX(), m_el[2].getX(), - m_el[0].getY(), m_el[1].getY(), m_el[2].getY(), - m_el[0].getZ(), m_el[1].getZ(), m_el[2].getZ()); + return b3Matrix3x3( + b3Fabs(m_el[0].getX()), b3Fabs(m_el[0].getY()), b3Fabs(m_el[0].getZ()), + b3Fabs(m_el[1].getX()), b3Fabs(m_el[1].getY()), b3Fabs(m_el[1].getZ()), + b3Fabs(m_el[2].getX()), b3Fabs(m_el[2].getY()), b3Fabs(m_el[2].getZ())); #endif } -B3_FORCE_INLINE b3Matrix3x3 -b3Matrix3x3::adjoint() const +B3_FORCE_INLINE b3Matrix3x3 +b3Matrix3x3::transpose() const +{ +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) + __m128 v0 = m_el[0].mVec128; + __m128 v1 = m_el[1].mVec128; + __m128 v2 = m_el[2].mVec128; // x2 y2 z2 w2 + __m128 vT; + + v2 = _mm_and_ps(v2, b3vFFF0fMask); // x2 y2 z2 0 + + vT = _mm_unpackhi_ps(v0, v1); // z0 z1 * * + v0 = _mm_unpacklo_ps(v0, v1); // x0 x1 y0 y1 + + v1 = _mm_shuffle_ps(v0, v2, B3_SHUFFLE(2, 3, 1, 3)); // y0 y1 y2 0 + v0 = _mm_shuffle_ps(v0, v2, B3_SHUFFLE(0, 1, 0, 3)); // x0 x1 x2 0 + v2 = b3CastdTo128f(_mm_move_sd(b3CastfTo128d(v2), b3CastfTo128d(vT))); // z0 z1 z2 0 + + return b3Matrix3x3(v0, v1, v2); +#elif defined(B3_USE_NEON) + // note: zeros the w channel. We can preserve it at the cost of two more vtrn instructions. + static const uint32x2_t zMask = (const uint32x2_t){-1, 0}; + float32x4x2_t top = vtrnq_f32(m_el[0].mVec128, m_el[1].mVec128); // {x0 x1 z0 z1}, {y0 y1 w0 w1} + float32x2x2_t bl = vtrn_f32(vget_low_f32(m_el[2].mVec128), vdup_n_f32(0.0f)); // {x2 0 }, {y2 0} + float32x4_t v0 = vcombine_f32(vget_low_f32(top.val[0]), bl.val[0]); + float32x4_t v1 = vcombine_f32(vget_low_f32(top.val[1]), bl.val[1]); + float32x2_t q = (float32x2_t)vand_u32((uint32x2_t)vget_high_f32(m_el[2].mVec128), zMask); + float32x4_t v2 = vcombine_f32(vget_high_f32(top.val[0]), q); // z0 z1 z2 0 + return b3Matrix3x3(v0, v1, v2); +#else + return b3Matrix3x3(m_el[0].getX(), m_el[1].getX(), m_el[2].getX(), + m_el[0].getY(), m_el[1].getY(), m_el[2].getY(), + m_el[0].getZ(), m_el[1].getZ(), m_el[2].getZ()); +#endif +} + +B3_FORCE_INLINE b3Matrix3x3 +b3Matrix3x3::adjoint() const { return b3Matrix3x3(cofac(1, 1, 2, 2), cofac(0, 2, 2, 1), cofac(0, 1, 1, 2), - cofac(1, 2, 2, 0), cofac(0, 0, 2, 2), cofac(0, 2, 1, 0), - cofac(1, 0, 2, 1), cofac(0, 1, 2, 0), cofac(0, 0, 1, 1)); + cofac(1, 2, 2, 0), cofac(0, 0, 2, 2), cofac(0, 2, 1, 0), + cofac(1, 0, 2, 1), cofac(0, 1, 2, 0), cofac(0, 0, 1, 1)); } -B3_FORCE_INLINE b3Matrix3x3 +B3_FORCE_INLINE b3Matrix3x3 b3Matrix3x3::inverse() const { b3Vector3 co = b3MakeVector3(cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1)); @@ -1024,54 +1023,54 @@ b3Matrix3x3::inverse() const b3FullAssert(det != b3Scalar(0.0)); b3Scalar s = b3Scalar(1.0) / det; return b3Matrix3x3(co.getX() * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s, - co.getY() * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s, - co.getZ() * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s); + co.getY() * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s, + co.getZ() * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s); } -B3_FORCE_INLINE b3Matrix3x3 +B3_FORCE_INLINE b3Matrix3x3 b3Matrix3x3::transposeTimes(const b3Matrix3x3& m) const { -#if (defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE)) - // zeros w -// static const __m128i xyzMask = (const __m128i){ -1ULL, 0xffffffffULL }; - __m128 row = m_el[0].mVec128; - __m128 m0 = _mm_and_ps( m.getRow(0).mVec128, b3vFFF0fMask ); - __m128 m1 = _mm_and_ps( m.getRow(1).mVec128, b3vFFF0fMask); - __m128 m2 = _mm_and_ps( m.getRow(2).mVec128, b3vFFF0fMask ); - __m128 r0 = _mm_mul_ps(m0, _mm_shuffle_ps(row, row, 0)); - __m128 r1 = _mm_mul_ps(m0, _mm_shuffle_ps(row, row, 0x55)); - __m128 r2 = _mm_mul_ps(m0, _mm_shuffle_ps(row, row, 0xaa)); - row = m_el[1].mVec128; - r0 = _mm_add_ps( r0, _mm_mul_ps(m1, _mm_shuffle_ps(row, row, 0))); - r1 = _mm_add_ps( r1, _mm_mul_ps(m1, _mm_shuffle_ps(row, row, 0x55))); - r2 = _mm_add_ps( r2, _mm_mul_ps(m1, _mm_shuffle_ps(row, row, 0xaa))); - row = m_el[2].mVec128; - r0 = _mm_add_ps( r0, _mm_mul_ps(m2, _mm_shuffle_ps(row, row, 0))); - r1 = _mm_add_ps( r1, _mm_mul_ps(m2, _mm_shuffle_ps(row, row, 0x55))); - r2 = _mm_add_ps( r2, _mm_mul_ps(m2, _mm_shuffle_ps(row, row, 0xaa))); - return b3Matrix3x3( r0, r1, r2 ); +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) + // zeros w + // static const __m128i xyzMask = (const __m128i){ -1ULL, 0xffffffffULL }; + __m128 row = m_el[0].mVec128; + __m128 m0 = _mm_and_ps(m.getRow(0).mVec128, b3vFFF0fMask); + __m128 m1 = _mm_and_ps(m.getRow(1).mVec128, b3vFFF0fMask); + __m128 m2 = _mm_and_ps(m.getRow(2).mVec128, b3vFFF0fMask); + __m128 r0 = _mm_mul_ps(m0, _mm_shuffle_ps(row, row, 0)); + __m128 r1 = _mm_mul_ps(m0, _mm_shuffle_ps(row, row, 0x55)); + __m128 r2 = _mm_mul_ps(m0, _mm_shuffle_ps(row, row, 0xaa)); + row = m_el[1].mVec128; + r0 = _mm_add_ps(r0, _mm_mul_ps(m1, _mm_shuffle_ps(row, row, 0))); + r1 = _mm_add_ps(r1, _mm_mul_ps(m1, _mm_shuffle_ps(row, row, 0x55))); + r2 = _mm_add_ps(r2, _mm_mul_ps(m1, _mm_shuffle_ps(row, row, 0xaa))); + row = m_el[2].mVec128; + r0 = _mm_add_ps(r0, _mm_mul_ps(m2, _mm_shuffle_ps(row, row, 0))); + r1 = _mm_add_ps(r1, _mm_mul_ps(m2, _mm_shuffle_ps(row, row, 0x55))); + r2 = _mm_add_ps(r2, _mm_mul_ps(m2, _mm_shuffle_ps(row, row, 0xaa))); + return b3Matrix3x3(r0, r1, r2); #elif defined B3_USE_NEON - // zeros w - static const uint32x4_t xyzMask = (const uint32x4_t){ -1, -1, -1, 0 }; - float32x4_t m0 = (float32x4_t) vandq_u32( (uint32x4_t) m.getRow(0).mVec128, xyzMask ); - float32x4_t m1 = (float32x4_t) vandq_u32( (uint32x4_t) m.getRow(1).mVec128, xyzMask ); - float32x4_t m2 = (float32x4_t) vandq_u32( (uint32x4_t) m.getRow(2).mVec128, xyzMask ); - float32x4_t row = m_el[0].mVec128; - float32x4_t r0 = vmulq_lane_f32( m0, vget_low_f32(row), 0); - float32x4_t r1 = vmulq_lane_f32( m0, vget_low_f32(row), 1); - float32x4_t r2 = vmulq_lane_f32( m0, vget_high_f32(row), 0); - row = m_el[1].mVec128; - r0 = vmlaq_lane_f32( r0, m1, vget_low_f32(row), 0); - r1 = vmlaq_lane_f32( r1, m1, vget_low_f32(row), 1); - r2 = vmlaq_lane_f32( r2, m1, vget_high_f32(row), 0); - row = m_el[2].mVec128; - r0 = vmlaq_lane_f32( r0, m2, vget_low_f32(row), 0); - r1 = vmlaq_lane_f32( r1, m2, vget_low_f32(row), 1); - r2 = vmlaq_lane_f32( r2, m2, vget_high_f32(row), 0); - return b3Matrix3x3( r0, r1, r2 ); + // zeros w + static const uint32x4_t xyzMask = (const uint32x4_t){-1, -1, -1, 0}; + float32x4_t m0 = (float32x4_t)vandq_u32((uint32x4_t)m.getRow(0).mVec128, xyzMask); + float32x4_t m1 = (float32x4_t)vandq_u32((uint32x4_t)m.getRow(1).mVec128, xyzMask); + float32x4_t m2 = (float32x4_t)vandq_u32((uint32x4_t)m.getRow(2).mVec128, xyzMask); + float32x4_t row = m_el[0].mVec128; + float32x4_t r0 = vmulq_lane_f32(m0, vget_low_f32(row), 0); + float32x4_t r1 = vmulq_lane_f32(m0, vget_low_f32(row), 1); + float32x4_t r2 = vmulq_lane_f32(m0, vget_high_f32(row), 0); + row = m_el[1].mVec128; + r0 = vmlaq_lane_f32(r0, m1, vget_low_f32(row), 0); + r1 = vmlaq_lane_f32(r1, m1, vget_low_f32(row), 1); + r2 = vmlaq_lane_f32(r2, m1, vget_high_f32(row), 0); + row = m_el[2].mVec128; + r0 = vmlaq_lane_f32(r0, m2, vget_low_f32(row), 0); + r1 = vmlaq_lane_f32(r1, m2, vget_low_f32(row), 1); + r2 = vmlaq_lane_f32(r2, m2, vget_high_f32(row), 0); + return b3Matrix3x3(r0, r1, r2); #else - return b3Matrix3x3( + return b3Matrix3x3( m_el[0].getX() * m[0].getX() + m_el[1].getX() * m[1].getX() + m_el[2].getX() * m[2].getX(), m_el[0].getX() * m[0].getY() + m_el[1].getX() * m[1].getY() + m_el[2].getX() * m[2].getY(), m_el[0].getX() * m[0].getZ() + m_el[1].getX() * m[1].getZ() + m_el[2].getX() * m[2].getZ(), @@ -1084,51 +1083,51 @@ b3Matrix3x3::transposeTimes(const b3Matrix3x3& m) const #endif } -B3_FORCE_INLINE b3Matrix3x3 +B3_FORCE_INLINE b3Matrix3x3 b3Matrix3x3::timesTranspose(const b3Matrix3x3& m) const { -#if (defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE)) - __m128 a0 = m_el[0].mVec128; - __m128 a1 = m_el[1].mVec128; - __m128 a2 = m_el[2].mVec128; - - b3Matrix3x3 mT = m.transpose(); // we rely on transpose() zeroing w channel so that we don't have to do it here - __m128 mx = mT[0].mVec128; - __m128 my = mT[1].mVec128; - __m128 mz = mT[2].mVec128; - - __m128 r0 = _mm_mul_ps(mx, _mm_shuffle_ps(a0, a0, 0x00)); - __m128 r1 = _mm_mul_ps(mx, _mm_shuffle_ps(a1, a1, 0x00)); - __m128 r2 = _mm_mul_ps(mx, _mm_shuffle_ps(a2, a2, 0x00)); - r0 = _mm_add_ps(r0, _mm_mul_ps(my, _mm_shuffle_ps(a0, a0, 0x55))); - r1 = _mm_add_ps(r1, _mm_mul_ps(my, _mm_shuffle_ps(a1, a1, 0x55))); - r2 = _mm_add_ps(r2, _mm_mul_ps(my, _mm_shuffle_ps(a2, a2, 0x55))); - r0 = _mm_add_ps(r0, _mm_mul_ps(mz, _mm_shuffle_ps(a0, a0, 0xaa))); - r1 = _mm_add_ps(r1, _mm_mul_ps(mz, _mm_shuffle_ps(a1, a1, 0xaa))); - r2 = _mm_add_ps(r2, _mm_mul_ps(mz, _mm_shuffle_ps(a2, a2, 0xaa))); - return b3Matrix3x3( r0, r1, r2); - +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) + __m128 a0 = m_el[0].mVec128; + __m128 a1 = m_el[1].mVec128; + __m128 a2 = m_el[2].mVec128; + + b3Matrix3x3 mT = m.transpose(); // we rely on transpose() zeroing w channel so that we don't have to do it here + __m128 mx = mT[0].mVec128; + __m128 my = mT[1].mVec128; + __m128 mz = mT[2].mVec128; + + __m128 r0 = _mm_mul_ps(mx, _mm_shuffle_ps(a0, a0, 0x00)); + __m128 r1 = _mm_mul_ps(mx, _mm_shuffle_ps(a1, a1, 0x00)); + __m128 r2 = _mm_mul_ps(mx, _mm_shuffle_ps(a2, a2, 0x00)); + r0 = _mm_add_ps(r0, _mm_mul_ps(my, _mm_shuffle_ps(a0, a0, 0x55))); + r1 = _mm_add_ps(r1, _mm_mul_ps(my, _mm_shuffle_ps(a1, a1, 0x55))); + r2 = _mm_add_ps(r2, _mm_mul_ps(my, _mm_shuffle_ps(a2, a2, 0x55))); + r0 = _mm_add_ps(r0, _mm_mul_ps(mz, _mm_shuffle_ps(a0, a0, 0xaa))); + r1 = _mm_add_ps(r1, _mm_mul_ps(mz, _mm_shuffle_ps(a1, a1, 0xaa))); + r2 = _mm_add_ps(r2, _mm_mul_ps(mz, _mm_shuffle_ps(a2, a2, 0xaa))); + return b3Matrix3x3(r0, r1, r2); + #elif defined B3_USE_NEON - float32x4_t a0 = m_el[0].mVec128; - float32x4_t a1 = m_el[1].mVec128; - float32x4_t a2 = m_el[2].mVec128; - - b3Matrix3x3 mT = m.transpose(); // we rely on transpose() zeroing w channel so that we don't have to do it here - float32x4_t mx = mT[0].mVec128; - float32x4_t my = mT[1].mVec128; - float32x4_t mz = mT[2].mVec128; - - float32x4_t r0 = vmulq_lane_f32( mx, vget_low_f32(a0), 0); - float32x4_t r1 = vmulq_lane_f32( mx, vget_low_f32(a1), 0); - float32x4_t r2 = vmulq_lane_f32( mx, vget_low_f32(a2), 0); - r0 = vmlaq_lane_f32( r0, my, vget_low_f32(a0), 1); - r1 = vmlaq_lane_f32( r1, my, vget_low_f32(a1), 1); - r2 = vmlaq_lane_f32( r2, my, vget_low_f32(a2), 1); - r0 = vmlaq_lane_f32( r0, mz, vget_high_f32(a0), 0); - r1 = vmlaq_lane_f32( r1, mz, vget_high_f32(a1), 0); - r2 = vmlaq_lane_f32( r2, mz, vget_high_f32(a2), 0); - return b3Matrix3x3( r0, r1, r2 ); - + float32x4_t a0 = m_el[0].mVec128; + float32x4_t a1 = m_el[1].mVec128; + float32x4_t a2 = m_el[2].mVec128; + + b3Matrix3x3 mT = m.transpose(); // we rely on transpose() zeroing w channel so that we don't have to do it here + float32x4_t mx = mT[0].mVec128; + float32x4_t my = mT[1].mVec128; + float32x4_t mz = mT[2].mVec128; + + float32x4_t r0 = vmulq_lane_f32(mx, vget_low_f32(a0), 0); + float32x4_t r1 = vmulq_lane_f32(mx, vget_low_f32(a1), 0); + float32x4_t r2 = vmulq_lane_f32(mx, vget_low_f32(a2), 0); + r0 = vmlaq_lane_f32(r0, my, vget_low_f32(a0), 1); + r1 = vmlaq_lane_f32(r1, my, vget_low_f32(a1), 1); + r2 = vmlaq_lane_f32(r2, my, vget_low_f32(a2), 1); + r0 = vmlaq_lane_f32(r0, mz, vget_high_f32(a0), 0); + r1 = vmlaq_lane_f32(r1, mz, vget_high_f32(a1), 0); + r2 = vmlaq_lane_f32(r2, mz, vget_high_f32(a2), 0); + return b3Matrix3x3(r0, r1, r2); + #else return b3Matrix3x3( m_el[0].dot(m[0]), m_el[0].dot(m[1]), m_el[0].dot(m[2]), @@ -1137,139 +1136,138 @@ b3Matrix3x3::timesTranspose(const b3Matrix3x3& m) const #endif } -B3_FORCE_INLINE b3Vector3 -operator*(const b3Matrix3x3& m, const b3Vector3& v) +B3_FORCE_INLINE b3Vector3 +operator*(const b3Matrix3x3& m, const b3Vector3& v) { -#if (defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE))|| defined (B3_USE_NEON) - return v.dot3(m[0], m[1], m[2]); +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) || defined(B3_USE_NEON) + return v.dot3(m[0], m[1], m[2]); #else return b3MakeVector3(m[0].dot(v), m[1].dot(v), m[2].dot(v)); #endif } - B3_FORCE_INLINE b3Vector3 operator*(const b3Vector3& v, const b3Matrix3x3& m) { -#if (defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE)) +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) - const __m128 vv = v.mVec128; + const __m128 vv = v.mVec128; - __m128 c0 = b3_splat_ps( vv, 0); - __m128 c1 = b3_splat_ps( vv, 1); - __m128 c2 = b3_splat_ps( vv, 2); + __m128 c0 = b3_splat_ps(vv, 0); + __m128 c1 = b3_splat_ps(vv, 1); + __m128 c2 = b3_splat_ps(vv, 2); - c0 = _mm_mul_ps(c0, _mm_and_ps(m[0].mVec128, b3vFFF0fMask) ); - c1 = _mm_mul_ps(c1, _mm_and_ps(m[1].mVec128, b3vFFF0fMask) ); - c0 = _mm_add_ps(c0, c1); - c2 = _mm_mul_ps(c2, _mm_and_ps(m[2].mVec128, b3vFFF0fMask) ); - - return b3MakeVector3(_mm_add_ps(c0, c2)); + c0 = _mm_mul_ps(c0, _mm_and_ps(m[0].mVec128, b3vFFF0fMask)); + c1 = _mm_mul_ps(c1, _mm_and_ps(m[1].mVec128, b3vFFF0fMask)); + c0 = _mm_add_ps(c0, c1); + c2 = _mm_mul_ps(c2, _mm_and_ps(m[2].mVec128, b3vFFF0fMask)); + + return b3MakeVector3(_mm_add_ps(c0, c2)); #elif defined(B3_USE_NEON) - const float32x4_t vv = v.mVec128; - const float32x2_t vlo = vget_low_f32(vv); - const float32x2_t vhi = vget_high_f32(vv); + const float32x4_t vv = v.mVec128; + const float32x2_t vlo = vget_low_f32(vv); + const float32x2_t vhi = vget_high_f32(vv); - float32x4_t c0, c1, c2; + float32x4_t c0, c1, c2; - c0 = (float32x4_t) vandq_s32((int32x4_t)m[0].mVec128, b3vFFF0Mask); - c1 = (float32x4_t) vandq_s32((int32x4_t)m[1].mVec128, b3vFFF0Mask); - c2 = (float32x4_t) vandq_s32((int32x4_t)m[2].mVec128, b3vFFF0Mask); + c0 = (float32x4_t)vandq_s32((int32x4_t)m[0].mVec128, b3vFFF0Mask); + c1 = (float32x4_t)vandq_s32((int32x4_t)m[1].mVec128, b3vFFF0Mask); + c2 = (float32x4_t)vandq_s32((int32x4_t)m[2].mVec128, b3vFFF0Mask); - c0 = vmulq_lane_f32(c0, vlo, 0); - c1 = vmulq_lane_f32(c1, vlo, 1); - c2 = vmulq_lane_f32(c2, vhi, 0); - c0 = vaddq_f32(c0, c1); - c0 = vaddq_f32(c0, c2); - - return b3MakeVector3(c0); + c0 = vmulq_lane_f32(c0, vlo, 0); + c1 = vmulq_lane_f32(c1, vlo, 1); + c2 = vmulq_lane_f32(c2, vhi, 0); + c0 = vaddq_f32(c0, c1); + c0 = vaddq_f32(c0, c2); + + return b3MakeVector3(c0); #else return b3MakeVector3(m.tdotx(v), m.tdoty(v), m.tdotz(v)); #endif } -B3_FORCE_INLINE b3Matrix3x3 +B3_FORCE_INLINE b3Matrix3x3 operator*(const b3Matrix3x3& m1, const b3Matrix3x3& m2) { -#if (defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE)) +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) - __m128 m10 = m1[0].mVec128; - __m128 m11 = m1[1].mVec128; - __m128 m12 = m1[2].mVec128; - - __m128 m2v = _mm_and_ps(m2[0].mVec128, b3vFFF0fMask); - - __m128 c0 = b3_splat_ps( m10, 0); - __m128 c1 = b3_splat_ps( m11, 0); - __m128 c2 = b3_splat_ps( m12, 0); - - c0 = _mm_mul_ps(c0, m2v); - c1 = _mm_mul_ps(c1, m2v); - c2 = _mm_mul_ps(c2, m2v); - - m2v = _mm_and_ps(m2[1].mVec128, b3vFFF0fMask); - - __m128 c0_1 = b3_splat_ps( m10, 1); - __m128 c1_1 = b3_splat_ps( m11, 1); - __m128 c2_1 = b3_splat_ps( m12, 1); - - c0_1 = _mm_mul_ps(c0_1, m2v); - c1_1 = _mm_mul_ps(c1_1, m2v); - c2_1 = _mm_mul_ps(c2_1, m2v); - - m2v = _mm_and_ps(m2[2].mVec128, b3vFFF0fMask); - - c0 = _mm_add_ps(c0, c0_1); - c1 = _mm_add_ps(c1, c1_1); - c2 = _mm_add_ps(c2, c2_1); - - m10 = b3_splat_ps( m10, 2); - m11 = b3_splat_ps( m11, 2); - m12 = b3_splat_ps( m12, 2); - - m10 = _mm_mul_ps(m10, m2v); - m11 = _mm_mul_ps(m11, m2v); - m12 = _mm_mul_ps(m12, m2v); - - c0 = _mm_add_ps(c0, m10); - c1 = _mm_add_ps(c1, m11); - c2 = _mm_add_ps(c2, m12); - - return b3Matrix3x3(c0, c1, c2); + __m128 m10 = m1[0].mVec128; + __m128 m11 = m1[1].mVec128; + __m128 m12 = m1[2].mVec128; + + __m128 m2v = _mm_and_ps(m2[0].mVec128, b3vFFF0fMask); + + __m128 c0 = b3_splat_ps(m10, 0); + __m128 c1 = b3_splat_ps(m11, 0); + __m128 c2 = b3_splat_ps(m12, 0); + + c0 = _mm_mul_ps(c0, m2v); + c1 = _mm_mul_ps(c1, m2v); + c2 = _mm_mul_ps(c2, m2v); + + m2v = _mm_and_ps(m2[1].mVec128, b3vFFF0fMask); + + __m128 c0_1 = b3_splat_ps(m10, 1); + __m128 c1_1 = b3_splat_ps(m11, 1); + __m128 c2_1 = b3_splat_ps(m12, 1); + + c0_1 = _mm_mul_ps(c0_1, m2v); + c1_1 = _mm_mul_ps(c1_1, m2v); + c2_1 = _mm_mul_ps(c2_1, m2v); + + m2v = _mm_and_ps(m2[2].mVec128, b3vFFF0fMask); + + c0 = _mm_add_ps(c0, c0_1); + c1 = _mm_add_ps(c1, c1_1); + c2 = _mm_add_ps(c2, c2_1); + + m10 = b3_splat_ps(m10, 2); + m11 = b3_splat_ps(m11, 2); + m12 = b3_splat_ps(m12, 2); + + m10 = _mm_mul_ps(m10, m2v); + m11 = _mm_mul_ps(m11, m2v); + m12 = _mm_mul_ps(m12, m2v); + + c0 = _mm_add_ps(c0, m10); + c1 = _mm_add_ps(c1, m11); + c2 = _mm_add_ps(c2, m12); + + return b3Matrix3x3(c0, c1, c2); #elif defined(B3_USE_NEON) - float32x4_t rv0, rv1, rv2; - float32x4_t v0, v1, v2; - float32x4_t mv0, mv1, mv2; + float32x4_t rv0, rv1, rv2; + float32x4_t v0, v1, v2; + float32x4_t mv0, mv1, mv2; - v0 = m1[0].mVec128; - v1 = m1[1].mVec128; - v2 = m1[2].mVec128; + v0 = m1[0].mVec128; + v1 = m1[1].mVec128; + v2 = m1[2].mVec128; - mv0 = (float32x4_t) vandq_s32((int32x4_t)m2[0].mVec128, b3vFFF0Mask); - mv1 = (float32x4_t) vandq_s32((int32x4_t)m2[1].mVec128, b3vFFF0Mask); - mv2 = (float32x4_t) vandq_s32((int32x4_t)m2[2].mVec128, b3vFFF0Mask); - - rv0 = vmulq_lane_f32(mv0, vget_low_f32(v0), 0); - rv1 = vmulq_lane_f32(mv0, vget_low_f32(v1), 0); - rv2 = vmulq_lane_f32(mv0, vget_low_f32(v2), 0); - - rv0 = vmlaq_lane_f32(rv0, mv1, vget_low_f32(v0), 1); - rv1 = vmlaq_lane_f32(rv1, mv1, vget_low_f32(v1), 1); - rv2 = vmlaq_lane_f32(rv2, mv1, vget_low_f32(v2), 1); - - rv0 = vmlaq_lane_f32(rv0, mv2, vget_high_f32(v0), 0); - rv1 = vmlaq_lane_f32(rv1, mv2, vget_high_f32(v1), 0); - rv2 = vmlaq_lane_f32(rv2, mv2, vget_high_f32(v2), 0); + mv0 = (float32x4_t)vandq_s32((int32x4_t)m2[0].mVec128, b3vFFF0Mask); + mv1 = (float32x4_t)vandq_s32((int32x4_t)m2[1].mVec128, b3vFFF0Mask); + mv2 = (float32x4_t)vandq_s32((int32x4_t)m2[2].mVec128, b3vFFF0Mask); + + rv0 = vmulq_lane_f32(mv0, vget_low_f32(v0), 0); + rv1 = vmulq_lane_f32(mv0, vget_low_f32(v1), 0); + rv2 = vmulq_lane_f32(mv0, vget_low_f32(v2), 0); + + rv0 = vmlaq_lane_f32(rv0, mv1, vget_low_f32(v0), 1); + rv1 = vmlaq_lane_f32(rv1, mv1, vget_low_f32(v1), 1); + rv2 = vmlaq_lane_f32(rv2, mv1, vget_low_f32(v2), 1); + + rv0 = vmlaq_lane_f32(rv0, mv2, vget_high_f32(v0), 0); + rv1 = vmlaq_lane_f32(rv1, mv2, vget_high_f32(v1), 0); + rv2 = vmlaq_lane_f32(rv2, mv2, vget_high_f32(v2), 0); return b3Matrix3x3(rv0, rv1, rv2); - -#else + +#else return b3Matrix3x3( - m2.tdotx( m1[0]), m2.tdoty( m1[0]), m2.tdotz( m1[0]), - m2.tdotx( m1[1]), m2.tdoty( m1[1]), m2.tdotz( m1[1]), - m2.tdotx( m1[2]), m2.tdoty( m1[2]), m2.tdotz( m1[2])); + m2.tdotx(m1[0]), m2.tdoty(m1[0]), m2.tdotz(m1[0]), + m2.tdotx(m1[1]), m2.tdoty(m1[1]), m2.tdotz(m1[1]), + m2.tdotx(m1[2]), m2.tdoty(m1[2]), m2.tdotz(m1[2])); #endif } @@ -1292,71 +1290,65 @@ m1[0][2] * m2[0][2] + m1[1][2] * m2[1][2] + m1[2][2] * m2[2][2]); * It will test all elements are equal. */ B3_FORCE_INLINE bool operator==(const b3Matrix3x3& m1, const b3Matrix3x3& m2) { -#if (defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE)) +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) - __m128 c0, c1, c2; + __m128 c0, c1, c2; - c0 = _mm_cmpeq_ps(m1[0].mVec128, m2[0].mVec128); - c1 = _mm_cmpeq_ps(m1[1].mVec128, m2[1].mVec128); - c2 = _mm_cmpeq_ps(m1[2].mVec128, m2[2].mVec128); - - c0 = _mm_and_ps(c0, c1); - c0 = _mm_and_ps(c0, c2); + c0 = _mm_cmpeq_ps(m1[0].mVec128, m2[0].mVec128); + c1 = _mm_cmpeq_ps(m1[1].mVec128, m2[1].mVec128); + c2 = _mm_cmpeq_ps(m1[2].mVec128, m2[2].mVec128); - return (0x7 == _mm_movemask_ps((__m128)c0)); -#else - return - ( m1[0][0] == m2[0][0] && m1[1][0] == m2[1][0] && m1[2][0] == m2[2][0] && - m1[0][1] == m2[0][1] && m1[1][1] == m2[1][1] && m1[2][1] == m2[2][1] && - m1[0][2] == m2[0][2] && m1[1][2] == m2[1][2] && m1[2][2] == m2[2][2] ); + c0 = _mm_and_ps(c0, c1); + c0 = _mm_and_ps(c0, c2); + + return (0x7 == _mm_movemask_ps((__m128)c0)); +#else + return (m1[0][0] == m2[0][0] && m1[1][0] == m2[1][0] && m1[2][0] == m2[2][0] && + m1[0][1] == m2[0][1] && m1[1][1] == m2[1][1] && m1[2][1] == m2[2][1] && + m1[0][2] == m2[0][2] && m1[1][2] == m2[1][2] && m1[2][2] == m2[2][2]); #endif } ///for serialization -struct b3Matrix3x3FloatData +struct b3Matrix3x3FloatData { b3Vector3FloatData m_el[3]; }; ///for serialization -struct b3Matrix3x3DoubleData +struct b3Matrix3x3DoubleData { b3Vector3DoubleData m_el[3]; }; - - - -B3_FORCE_INLINE void b3Matrix3x3::serialize(struct b3Matrix3x3Data& dataOut) const +B3_FORCE_INLINE void b3Matrix3x3::serialize(struct b3Matrix3x3Data& dataOut) const { - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) m_el[i].serialize(dataOut.m_el[i]); } -B3_FORCE_INLINE void b3Matrix3x3::serializeFloat(struct b3Matrix3x3FloatData& dataOut) const +B3_FORCE_INLINE void b3Matrix3x3::serializeFloat(struct b3Matrix3x3FloatData& dataOut) const { - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) m_el[i].serializeFloat(dataOut.m_el[i]); } - -B3_FORCE_INLINE void b3Matrix3x3::deSerialize(const struct b3Matrix3x3Data& dataIn) +B3_FORCE_INLINE void b3Matrix3x3::deSerialize(const struct b3Matrix3x3Data& dataIn) { - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) m_el[i].deSerialize(dataIn.m_el[i]); } -B3_FORCE_INLINE void b3Matrix3x3::deSerializeFloat(const struct b3Matrix3x3FloatData& dataIn) +B3_FORCE_INLINE void b3Matrix3x3::deSerializeFloat(const struct b3Matrix3x3FloatData& dataIn) { - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) m_el[i].deSerializeFloat(dataIn.m_el[i]); } -B3_FORCE_INLINE void b3Matrix3x3::deSerializeDouble(const struct b3Matrix3x3DoubleData& dataIn) +B3_FORCE_INLINE void b3Matrix3x3::deSerializeDouble(const struct b3Matrix3x3DoubleData& dataIn) { - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) m_el[i].deSerializeDouble(dataIn.m_el[i]); } -#endif //B3_MATRIX3x3_H - +#endif //B3_MATRIX3x3_H diff --git a/src/Bullet3Common/b3MinMax.h b/src/Bullet3Common/b3MinMax.h index 73af23a4f..c09c3db3f 100644 --- a/src/Bullet3Common/b3MinMax.h +++ b/src/Bullet3Common/b3MinMax.h @@ -12,60 +12,58 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #ifndef B3_GEN_MINMAX_H #define B3_GEN_MINMAX_H #include "b3Scalar.h" template -B3_FORCE_INLINE const T& b3Min(const T& a, const T& b) +B3_FORCE_INLINE const T& b3Min(const T& a, const T& b) { - return a < b ? a : b ; + return a < b ? a : b; } template -B3_FORCE_INLINE const T& b3Max(const T& a, const T& b) +B3_FORCE_INLINE const T& b3Max(const T& a, const T& b) { - return a > b ? a : b; + return a > b ? a : b; } template -B3_FORCE_INLINE const T& b3Clamped(const T& a, const T& lb, const T& ub) +B3_FORCE_INLINE const T& b3Clamped(const T& a, const T& lb, const T& ub) { - return a < lb ? lb : (ub < a ? ub : a); + return a < lb ? lb : (ub < a ? ub : a); } template -B3_FORCE_INLINE void b3SetMin(T& a, const T& b) +B3_FORCE_INLINE void b3SetMin(T& a, const T& b) { - if (b < a) + if (b < a) { a = b; } } template -B3_FORCE_INLINE void b3SetMax(T& a, const T& b) +B3_FORCE_INLINE void b3SetMax(T& a, const T& b) { - if (a < b) + if (a < b) { a = b; } } template -B3_FORCE_INLINE void b3Clamp(T& a, const T& lb, const T& ub) +B3_FORCE_INLINE void b3Clamp(T& a, const T& lb, const T& ub) { - if (a < lb) + if (a < lb) { - a = lb; + a = lb; } - else if (ub < a) + else if (ub < a) { a = ub; } } -#endif //B3_GEN_MINMAX_H +#endif //B3_GEN_MINMAX_H diff --git a/src/Bullet3Common/b3PoolAllocator.h b/src/Bullet3Common/b3PoolAllocator.h index 2fcdcf5b2..ed56bc627 100644 --- a/src/Bullet3Common/b3PoolAllocator.h +++ b/src/Bullet3Common/b3PoolAllocator.h @@ -12,7 +12,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef _BT_POOL_ALLOCATOR_H #define _BT_POOL_ALLOCATOR_H @@ -22,37 +21,37 @@ subject to the following restrictions: ///The b3PoolAllocator class allows to efficiently allocate a large pool of objects, instead of dynamically allocating them separately. class b3PoolAllocator { - int m_elemSize; - int m_maxElements; - int m_freeCount; - void* m_firstFree; - unsigned char* m_pool; + int m_elemSize; + int m_maxElements; + int m_freeCount; + void* m_firstFree; + unsigned char* m_pool; public: - b3PoolAllocator(int elemSize, int maxElements) - :m_elemSize(elemSize), - m_maxElements(maxElements) + : m_elemSize(elemSize), + m_maxElements(maxElements) { - m_pool = (unsigned char*) b3AlignedAlloc( static_cast(m_elemSize*m_maxElements),16); + m_pool = (unsigned char*)b3AlignedAlloc(static_cast(m_elemSize * m_maxElements), 16); unsigned char* p = m_pool; - m_firstFree = p; - m_freeCount = m_maxElements; - int count = m_maxElements; - while (--count) { - *(void**)p = (p + m_elemSize); - p += m_elemSize; - } - *(void**)p = 0; - } + m_firstFree = p; + m_freeCount = m_maxElements; + int count = m_maxElements; + while (--count) + { + *(void**)p = (p + m_elemSize); + p += m_elemSize; + } + *(void**)p = 0; + } ~b3PoolAllocator() { - b3AlignedFree( m_pool); + b3AlignedFree(m_pool); } - int getFreeCount() const + int getFreeCount() const { return m_freeCount; } @@ -67,21 +66,22 @@ public: return m_maxElements; } - void* allocate(int size) + void* allocate(int size) { // release mode fix (void)size; - b3Assert(!size || size<=m_elemSize); - b3Assert(m_freeCount>0); - void* result = m_firstFree; - m_firstFree = *(void**)m_firstFree; - --m_freeCount; - return result; + b3Assert(!size || size <= m_elemSize); + b3Assert(m_freeCount > 0); + void* result = m_firstFree; + m_firstFree = *(void**)m_firstFree; + --m_freeCount; + return result; } bool validPtr(void* ptr) { - if (ptr) { + if (ptr) + { if (((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize)) { return true; @@ -90,32 +90,32 @@ public: return false; } - void freeMemory(void* ptr) + void freeMemory(void* ptr) { - if (ptr) { - b3Assert((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize); + if (ptr) + { + b3Assert((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize); - *(void**)ptr = m_firstFree; - m_firstFree = ptr; - ++m_freeCount; - } + *(void**)ptr = m_firstFree; + m_firstFree = ptr; + ++m_freeCount; + } } - int getElementSize() const + int getElementSize() const { return m_elemSize; } - unsigned char* getPoolAddress() + unsigned char* getPoolAddress() { return m_pool; } - const unsigned char* getPoolAddress() const + const unsigned char* getPoolAddress() const { return m_pool; } - }; -#endif //_BT_POOL_ALLOCATOR_H +#endif //_BT_POOL_ALLOCATOR_H diff --git a/src/Bullet3Common/b3QuadWord.h b/src/Bullet3Common/b3QuadWord.h index 65c958197..0def305fa 100644 --- a/src/Bullet3Common/b3QuadWord.h +++ b/src/Bullet3Common/b3QuadWord.h @@ -12,18 +12,13 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef B3_SIMD_QUADWORD_H #define B3_SIMD_QUADWORD_H #include "b3Scalar.h" #include "b3MinMax.h" - - - - -#if defined (__CELLOS_LV2) && defined (__SPU__) +#if defined(__CELLOS_LV2) && defined(__SPU__) #include #endif @@ -31,58 +26,64 @@ subject to the following restrictions: * Some issues under PS3 Linux with IBM 2.1 SDK, gcc compiler prevent from using aligned quadword. */ #ifndef USE_LIBSPE2 -B3_ATTRIBUTE_ALIGNED16(class) b3QuadWord +B3_ATTRIBUTE_ALIGNED16(class) +b3QuadWord #else class b3QuadWord #endif { protected: - -#if defined (__SPU__) && defined (__CELLOS_LV2__) +#if defined(__SPU__) && defined(__CELLOS_LV2__) union { vec_float4 mVec128; - b3Scalar m_floats[4]; + b3Scalar m_floats[4]; }; + public: - vec_float4 get128() const + vec_float4 get128() const { return mVec128; } -#else //__CELLOS_LV2__ __SPU__ +#else //__CELLOS_LV2__ __SPU__ -#if defined(B3_USE_SSE) || defined(B3_USE_NEON) +#if defined(B3_USE_SSE) || defined(B3_USE_NEON) public: union { b3SimdFloat4 mVec128; - b3Scalar m_floats[4]; - struct {b3Scalar x,y,z,w;}; + b3Scalar m_floats[4]; + struct + { + b3Scalar x, y, z, w; + }; }; + public: - B3_FORCE_INLINE b3SimdFloat4 get128() const + B3_FORCE_INLINE b3SimdFloat4 get128() const { return mVec128; } - B3_FORCE_INLINE void set128(b3SimdFloat4 v128) + B3_FORCE_INLINE void set128(b3SimdFloat4 v128) { mVec128 = v128; } #else public: - union - { - b3Scalar m_floats[4]; - struct {b3Scalar x,y,z,w;}; + union { + b3Scalar m_floats[4]; + struct + { + b3Scalar x, y, z, w; + }; }; -#endif // B3_USE_SSE +#endif // B3_USE_SSE -#endif //__CELLOS_LV2__ __SPU__ +#endif //__CELLOS_LV2__ __SPU__ - public: - +public: #if defined(B3_USE_SSE) || defined(B3_USE_NEON) - // Set Vector + // Set Vector B3_FORCE_INLINE b3QuadWord(const b3SimdFloat4 vec) { mVec128 = vec; @@ -95,151 +96,147 @@ public: } // Assignment Operator - B3_FORCE_INLINE b3QuadWord& - operator=(const b3QuadWord& v) + B3_FORCE_INLINE b3QuadWord& + operator=(const b3QuadWord& v) { mVec128 = v.mVec128; - + return *this; } - + #endif - /**@brief Return the x value */ - B3_FORCE_INLINE const b3Scalar& getX() const { return m_floats[0]; } - /**@brief Return the y value */ - B3_FORCE_INLINE const b3Scalar& getY() const { return m_floats[1]; } - /**@brief Return the z value */ - B3_FORCE_INLINE const b3Scalar& getZ() const { return m_floats[2]; } - /**@brief Set the x value */ - B3_FORCE_INLINE void setX(b3Scalar _x) { m_floats[0] = _x;}; - /**@brief Set the y value */ - B3_FORCE_INLINE void setY(b3Scalar _y) { m_floats[1] = _y;}; - /**@brief Set the z value */ - B3_FORCE_INLINE void setZ(b3Scalar _z) { m_floats[2] = _z;}; - /**@brief Set the w value */ - B3_FORCE_INLINE void setW(b3Scalar _w) { m_floats[3] = _w;}; - /**@brief Return the x value */ + /**@brief Return the x value */ + B3_FORCE_INLINE const b3Scalar& getX() const { return m_floats[0]; } + /**@brief Return the y value */ + B3_FORCE_INLINE const b3Scalar& getY() const { return m_floats[1]; } + /**@brief Return the z value */ + B3_FORCE_INLINE const b3Scalar& getZ() const { return m_floats[2]; } + /**@brief Set the x value */ + B3_FORCE_INLINE void setX(b3Scalar _x) { m_floats[0] = _x; }; + /**@brief Set the y value */ + B3_FORCE_INLINE void setY(b3Scalar _y) { m_floats[1] = _y; }; + /**@brief Set the z value */ + B3_FORCE_INLINE void setZ(b3Scalar _z) { m_floats[2] = _z; }; + /**@brief Set the w value */ + B3_FORCE_INLINE void setW(b3Scalar _w) { m_floats[3] = _w; }; + /**@brief Return the x value */ - - //B3_FORCE_INLINE b3Scalar& operator[](int i) { return (&m_floats[0])[i]; } + //B3_FORCE_INLINE b3Scalar& operator[](int i) { return (&m_floats[0])[i]; } //B3_FORCE_INLINE const b3Scalar& operator[](int i) const { return (&m_floats[0])[i]; } ///operator b3Scalar*() replaces operator[], using implicit conversion. We added operator != and operator == to avoid pointer comparisons. - B3_FORCE_INLINE operator b3Scalar *() { return &m_floats[0]; } - B3_FORCE_INLINE operator const b3Scalar *() const { return &m_floats[0]; } + B3_FORCE_INLINE operator b3Scalar*() { return &m_floats[0]; } + B3_FORCE_INLINE operator const b3Scalar*() const { return &m_floats[0]; } - B3_FORCE_INLINE bool operator==(const b3QuadWord& other) const + B3_FORCE_INLINE bool operator==(const b3QuadWord& other) const { #ifdef B3_USE_SSE - return (0xf == _mm_movemask_ps((__m128)_mm_cmpeq_ps(mVec128, other.mVec128))); -#else - return ((m_floats[3]==other.m_floats[3]) && - (m_floats[2]==other.m_floats[2]) && - (m_floats[1]==other.m_floats[1]) && - (m_floats[0]==other.m_floats[0])); + return (0xf == _mm_movemask_ps((__m128)_mm_cmpeq_ps(mVec128, other.mVec128))); +#else + return ((m_floats[3] == other.m_floats[3]) && + (m_floats[2] == other.m_floats[2]) && + (m_floats[1] == other.m_floats[1]) && + (m_floats[0] == other.m_floats[0])); #endif } - B3_FORCE_INLINE bool operator!=(const b3QuadWord& other) const + B3_FORCE_INLINE bool operator!=(const b3QuadWord& other) const { return !(*this == other); } - /**@brief Set x,y,z and zero w + /**@brief Set x,y,z and zero w * @param x Value of x * @param y Value of y * @param z Value of z */ - B3_FORCE_INLINE void setValue(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z) - { - m_floats[0]=_x; - m_floats[1]=_y; - m_floats[2]=_z; - m_floats[3] = 0.f; - } + B3_FORCE_INLINE void setValue(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z) + { + m_floats[0] = _x; + m_floats[1] = _y; + m_floats[2] = _z; + m_floats[3] = 0.f; + } -/* void getValue(b3Scalar *m) const + /* void getValue(b3Scalar *m) const { m[0] = m_floats[0]; m[1] = m_floats[1]; m[2] = m_floats[2]; } */ -/**@brief Set the values + /**@brief Set the values * @param x Value of x * @param y Value of y * @param z Value of z * @param w Value of w */ - B3_FORCE_INLINE void setValue(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z,const b3Scalar& _w) - { - m_floats[0]=_x; - m_floats[1]=_y; - m_floats[2]=_z; - m_floats[3]=_w; - } - /**@brief No initialization constructor */ - B3_FORCE_INLINE b3QuadWord() - // :m_floats[0](b3Scalar(0.)),m_floats[1](b3Scalar(0.)),m_floats[2](b3Scalar(0.)),m_floats[3](b3Scalar(0.)) - { - } - - /**@brief Three argument constructor (zeros w) + B3_FORCE_INLINE void setValue(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z, const b3Scalar& _w) + { + m_floats[0] = _x; + m_floats[1] = _y; + m_floats[2] = _z; + m_floats[3] = _w; + } + /**@brief No initialization constructor */ + B3_FORCE_INLINE b3QuadWord() + // :m_floats[0](b3Scalar(0.)),m_floats[1](b3Scalar(0.)),m_floats[2](b3Scalar(0.)),m_floats[3](b3Scalar(0.)) + { + } + + /**@brief Three argument constructor (zeros w) * @param x Value of x * @param y Value of y * @param z Value of z */ - B3_FORCE_INLINE b3QuadWord(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z) - { - m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = 0.0f; - } + B3_FORCE_INLINE b3QuadWord(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z) + { + m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = 0.0f; + } -/**@brief Initializing constructor + /**@brief Initializing constructor * @param x Value of x * @param y Value of y * @param z Value of z * @param w Value of w */ - B3_FORCE_INLINE b3QuadWord(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z,const b3Scalar& _w) - { - m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = _w; - } + B3_FORCE_INLINE b3QuadWord(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z, const b3Scalar& _w) + { + m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = _w; + } - /**@brief Set each element to the max of the current values and the values of another b3QuadWord + /**@brief Set each element to the max of the current values and the values of another b3QuadWord * @param other The other b3QuadWord to compare with */ - B3_FORCE_INLINE void setMax(const b3QuadWord& other) - { - #ifdef B3_USE_SSE - mVec128 = _mm_max_ps(mVec128, other.mVec128); - #elif defined(B3_USE_NEON) - mVec128 = vmaxq_f32(mVec128, other.mVec128); - #else - b3SetMax(m_floats[0], other.m_floats[0]); - b3SetMax(m_floats[1], other.m_floats[1]); - b3SetMax(m_floats[2], other.m_floats[2]); - b3SetMax(m_floats[3], other.m_floats[3]); - #endif - } - /**@brief Set each element to the min of the current values and the values of another b3QuadWord + B3_FORCE_INLINE void setMax(const b3QuadWord& other) + { +#ifdef B3_USE_SSE + mVec128 = _mm_max_ps(mVec128, other.mVec128); +#elif defined(B3_USE_NEON) + mVec128 = vmaxq_f32(mVec128, other.mVec128); +#else + b3SetMax(m_floats[0], other.m_floats[0]); + b3SetMax(m_floats[1], other.m_floats[1]); + b3SetMax(m_floats[2], other.m_floats[2]); + b3SetMax(m_floats[3], other.m_floats[3]); +#endif + } + /**@brief Set each element to the min of the current values and the values of another b3QuadWord * @param other The other b3QuadWord to compare with */ - B3_FORCE_INLINE void setMin(const b3QuadWord& other) - { - #ifdef B3_USE_SSE - mVec128 = _mm_min_ps(mVec128, other.mVec128); - #elif defined(B3_USE_NEON) - mVec128 = vminq_f32(mVec128, other.mVec128); - #else - b3SetMin(m_floats[0], other.m_floats[0]); - b3SetMin(m_floats[1], other.m_floats[1]); - b3SetMin(m_floats[2], other.m_floats[2]); - b3SetMin(m_floats[3], other.m_floats[3]); - #endif - } - - - + B3_FORCE_INLINE void setMin(const b3QuadWord& other) + { +#ifdef B3_USE_SSE + mVec128 = _mm_min_ps(mVec128, other.mVec128); +#elif defined(B3_USE_NEON) + mVec128 = vminq_f32(mVec128, other.mVec128); +#else + b3SetMin(m_floats[0], other.m_floats[0]); + b3SetMin(m_floats[1], other.m_floats[1]); + b3SetMin(m_floats[2], other.m_floats[2]); + b3SetMin(m_floats[3], other.m_floats[3]); +#endif + } }; -#endif //B3_SIMD_QUADWORD_H +#endif //B3_SIMD_QUADWORD_H diff --git a/src/Bullet3Common/b3Quaternion.h b/src/Bullet3Common/b3Quaternion.h index ad2054334..98e07c98d 100644 --- a/src/Bullet3Common/b3Quaternion.h +++ b/src/Bullet3Common/b3Quaternion.h @@ -12,19 +12,12 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #ifndef B3_SIMD__QUATERNION_H_ #define B3_SIMD__QUATERNION_H_ - #include "b3Vector3.h" #include "b3QuadWord.h" - - - - #ifdef B3_USE_SSE const __m128 B3_ATTRIBUTE_ALIGNED16(b3vOnes) = {1.0f, 1.0f, 1.0f, 1.0f}; @@ -39,13 +32,14 @@ const b3SimdFloat4 B3_ATTRIBUTE_ALIGNED16(b3vPPPM) = {+0.0f, +0.0f, +0.0f, -0.0f #endif /**@brief The b3Quaternion implements quaternion to perform linear algebra rotations in combination with b3Matrix3x3, b3Vector3 and b3Transform. */ -class b3Quaternion : public b3QuadWord { +class b3Quaternion : public b3QuadWord +{ public: - /**@brief No initialization constructor */ + /**@brief No initialization constructor */ b3Quaternion() {} -#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE))|| defined(B3_USE_NEON) - // Set Vector +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) || defined(B3_USE_NEON) + // Set Vector B3_FORCE_INLINE b3Quaternion(const b3SimdFloat4 vec) { mVec128 = vec; @@ -58,44 +52,44 @@ public: } // Assignment Operator - B3_FORCE_INLINE b3Quaternion& - operator=(const b3Quaternion& v) + B3_FORCE_INLINE b3Quaternion& + operator=(const b3Quaternion& v) { mVec128 = v.mVec128; - + return *this; } - + #endif // template // explicit Quaternion(const b3Scalar *v) : Tuple4(v) {} - /**@brief Constructor from scalars */ - b3Quaternion(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z, const b3Scalar& _w) - : b3QuadWord(_x, _y, _z, _w) + /**@brief Constructor from scalars */ + b3Quaternion(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z, const b3Scalar& _w) + : b3QuadWord(_x, _y, _z, _w) { //b3Assert(!((_x==1.f) && (_y==0.f) && (_z==0.f) && (_w==0.f))); } - /**@brief Axis angle Constructor + /**@brief Axis angle Constructor * @param axis The axis which the rotation is around * @param angle The magnitude of the rotation around the angle (Radians) */ - b3Quaternion(const b3Vector3& _axis, const b3Scalar& _angle) - { - setRotation(_axis, _angle); + b3Quaternion(const b3Vector3& _axis, const b3Scalar& _angle) + { + setRotation(_axis, _angle); } - /**@brief Constructor from Euler angles + /**@brief Constructor from Euler angles * @param yaw Angle around Y unless B3_EULER_DEFAULT_ZYX defined then Z * @param pitch Angle around X unless B3_EULER_DEFAULT_ZYX defined then Y * @param roll Angle around Z unless B3_EULER_DEFAULT_ZYX defined then X */ b3Quaternion(const b3Scalar& yaw, const b3Scalar& pitch, const b3Scalar& roll) - { + { #ifndef B3_EULER_DEFAULT_ZYX - setEuler(yaw, pitch, roll); + setEuler(yaw, pitch, roll); #else - setEulerZYX(yaw, pitch, roll); -#endif + setEulerZYX(yaw, pitch, roll); +#endif } - /**@brief Set the rotation using axis angle notation + /**@brief Set the rotation using axis angle notation * @param axis The axis around which to rotate * @param angle The magnitude of the rotation in Radians */ void setRotation(const b3Vector3& axis, const b3Scalar& _angle) @@ -103,18 +97,18 @@ public: b3Scalar d = axis.length(); b3Assert(d != b3Scalar(0.0)); b3Scalar s = b3Sin(_angle * b3Scalar(0.5)) / d; - setValue(axis.getX() * s, axis.getY() * s, axis.getZ() * s, - b3Cos(_angle * b3Scalar(0.5))); + setValue(axis.getX() * s, axis.getY() * s, axis.getZ() * s, + b3Cos(_angle * b3Scalar(0.5))); } - /**@brief Set the quaternion using Euler angles + /**@brief Set the quaternion using Euler angles * @param yaw Angle around Y * @param pitch Angle around X * @param roll Angle around Z */ void setEuler(const b3Scalar& yaw, const b3Scalar& pitch, const b3Scalar& roll) { - b3Scalar halfYaw = b3Scalar(yaw) * b3Scalar(0.5); - b3Scalar halfPitch = b3Scalar(pitch) * b3Scalar(0.5); - b3Scalar halfRoll = b3Scalar(roll) * b3Scalar(0.5); + b3Scalar halfYaw = b3Scalar(yaw) * b3Scalar(0.5); + b3Scalar halfPitch = b3Scalar(pitch) * b3Scalar(0.5); + b3Scalar halfRoll = b3Scalar(roll) * b3Scalar(0.5); b3Scalar cosYaw = b3Cos(halfYaw); b3Scalar sinYaw = b3Sin(halfYaw); b3Scalar cosPitch = b3Cos(halfPitch); @@ -122,34 +116,34 @@ public: b3Scalar cosRoll = b3Cos(halfRoll); b3Scalar sinRoll = b3Sin(halfRoll); setValue(cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, - cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, - sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, - cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); + cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, + sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, + cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); } - + /**@brief Set the quaternion using euler angles * @param yaw Angle around Z * @param pitch Angle around Y * @param roll Angle around X */ void setEulerZYX(const b3Scalar& yawZ, const b3Scalar& pitchY, const b3Scalar& rollX) { - b3Scalar halfYaw = b3Scalar(yawZ) * b3Scalar(0.5); - b3Scalar halfPitch = b3Scalar(pitchY) * b3Scalar(0.5); - b3Scalar halfRoll = b3Scalar(rollX) * b3Scalar(0.5); + b3Scalar halfYaw = b3Scalar(yawZ) * b3Scalar(0.5); + b3Scalar halfPitch = b3Scalar(pitchY) * b3Scalar(0.5); + b3Scalar halfRoll = b3Scalar(rollX) * b3Scalar(0.5); b3Scalar cosYaw = b3Cos(halfYaw); b3Scalar sinYaw = b3Sin(halfYaw); b3Scalar cosPitch = b3Cos(halfPitch); b3Scalar sinPitch = b3Sin(halfPitch); b3Scalar cosRoll = b3Cos(halfRoll); b3Scalar sinRoll = b3Sin(halfRoll); - setValue(sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, //x - cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, //y - cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, //z - cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); //formerly yzx + setValue(sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, //x + cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, //y + cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, //z + cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); //formerly yzx normalize(); } - /**@brief Get the euler angles from this quaternion + /**@brief Get the euler angles from this quaternion * @param yaw Angle around Z * @param pitch Angle around Y * @param roll Angle around X */ @@ -166,221 +160,221 @@ public: squ = m_floats[3] * m_floats[3]; rollX = b3Atan2(2 * (m_floats[1] * m_floats[2] + m_floats[3] * m_floats[0]), squ - sqx - sqy + sqz); sarg = b3Scalar(-2.) * (m_floats[0] * m_floats[2] - m_floats[3] * m_floats[1]); - pitchY = sarg <= b3Scalar(-1.0) ? b3Scalar(-0.5) * B3_PI: (sarg >= b3Scalar(1.0) ? b3Scalar(0.5) * B3_PI : b3Asin(sarg)); + pitchY = sarg <= b3Scalar(-1.0) ? b3Scalar(-0.5) * B3_PI : (sarg >= b3Scalar(1.0) ? b3Scalar(0.5) * B3_PI : b3Asin(sarg)); yawZ = b3Atan2(2 * (m_floats[0] * m_floats[1] + m_floats[3] * m_floats[2]), squ + sqx - sqy - sqz); } - /**@brief Add two quaternions + /**@brief Add two quaternions * @param q The quaternion to add to this one */ - B3_FORCE_INLINE b3Quaternion& operator+=(const b3Quaternion& q) + B3_FORCE_INLINE b3Quaternion& operator+=(const b3Quaternion& q) { -#if defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) mVec128 = _mm_add_ps(mVec128, q.mVec128); #elif defined(B3_USE_NEON) mVec128 = vaddq_f32(mVec128, q.mVec128); -#else - m_floats[0] += q.getX(); - m_floats[1] += q.getY(); - m_floats[2] += q.getZ(); - m_floats[3] += q.m_floats[3]; +#else + m_floats[0] += q.getX(); + m_floats[1] += q.getY(); + m_floats[2] += q.getZ(); + m_floats[3] += q.m_floats[3]; #endif return *this; } - /**@brief Subtract out a quaternion + /**@brief Subtract out a quaternion * @param q The quaternion to subtract from this one */ - b3Quaternion& operator-=(const b3Quaternion& q) + b3Quaternion& operator-=(const b3Quaternion& q) { -#if defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) mVec128 = _mm_sub_ps(mVec128, q.mVec128); #elif defined(B3_USE_NEON) mVec128 = vsubq_f32(mVec128, q.mVec128); -#else - m_floats[0] -= q.getX(); - m_floats[1] -= q.getY(); - m_floats[2] -= q.getZ(); - m_floats[3] -= q.m_floats[3]; +#else + m_floats[0] -= q.getX(); + m_floats[1] -= q.getY(); + m_floats[2] -= q.getZ(); + m_floats[3] -= q.m_floats[3]; #endif - return *this; + return *this; } - /**@brief Scale this quaternion + /**@brief Scale this quaternion * @param s The scalar to scale by */ b3Quaternion& operator*=(const b3Scalar& s) { -#if defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE) - __m128 vs = _mm_load_ss(&s); // (S 0 0 0) - vs = b3_pshufd_ps(vs, 0); // (S S S S) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) + __m128 vs = _mm_load_ss(&s); // (S 0 0 0) + vs = b3_pshufd_ps(vs, 0); // (S S S S) mVec128 = _mm_mul_ps(mVec128, vs); #elif defined(B3_USE_NEON) mVec128 = vmulq_n_f32(mVec128, s); #else - m_floats[0] *= s; - m_floats[1] *= s; - m_floats[2] *= s; - m_floats[3] *= s; + m_floats[0] *= s; + m_floats[1] *= s; + m_floats[2] *= s; + m_floats[3] *= s; #endif return *this; } - /**@brief Multiply this quaternion by q on the right + /**@brief Multiply this quaternion by q on the right * @param q The other quaternion * Equivilant to this = this * q */ b3Quaternion& operator*=(const b3Quaternion& q) { -#if defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) __m128 vQ2 = q.get128(); - - __m128 A1 = b3_pshufd_ps(mVec128, B3_SHUFFLE(0,1,2,0)); - __m128 B1 = b3_pshufd_ps(vQ2, B3_SHUFFLE(3,3,3,0)); - + + __m128 A1 = b3_pshufd_ps(mVec128, B3_SHUFFLE(0, 1, 2, 0)); + __m128 B1 = b3_pshufd_ps(vQ2, B3_SHUFFLE(3, 3, 3, 0)); + A1 = A1 * B1; - - __m128 A2 = b3_pshufd_ps(mVec128, B3_SHUFFLE(1,2,0,1)); - __m128 B2 = b3_pshufd_ps(vQ2, B3_SHUFFLE(2,0,1,1)); - + + __m128 A2 = b3_pshufd_ps(mVec128, B3_SHUFFLE(1, 2, 0, 1)); + __m128 B2 = b3_pshufd_ps(vQ2, B3_SHUFFLE(2, 0, 1, 1)); + A2 = A2 * B2; - - B1 = b3_pshufd_ps(mVec128, B3_SHUFFLE(2,0,1,2)); - B2 = b3_pshufd_ps(vQ2, B3_SHUFFLE(1,2,0,2)); - - B1 = B1 * B2; // A3 *= B3 - - mVec128 = b3_splat_ps(mVec128, 3); // A0 - mVec128 = mVec128 * vQ2; // A0 * B0 - - A1 = A1 + A2; // AB12 - mVec128 = mVec128 - B1; // AB03 = AB0 - AB3 - A1 = _mm_xor_ps(A1, b3vPPPM); // change sign of the last element - mVec128 = mVec128+ A1; // AB03 + AB12 -#elif defined(B3_USE_NEON) + B1 = b3_pshufd_ps(mVec128, B3_SHUFFLE(2, 0, 1, 2)); + B2 = b3_pshufd_ps(vQ2, B3_SHUFFLE(1, 2, 0, 2)); - float32x4_t vQ1 = mVec128; - float32x4_t vQ2 = q.get128(); - float32x4_t A0, A1, B1, A2, B2, A3, B3; - float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz; - - { - float32x2x2_t tmp; - tmp = vtrn_f32( vget_high_f32(vQ1), vget_low_f32(vQ1) ); // {z x}, {w y} - vQ1zx = tmp.val[0]; + B1 = B1 * B2; // A3 *= B3 - tmp = vtrn_f32( vget_high_f32(vQ2), vget_low_f32(vQ2) ); // {z x}, {w y} - vQ2zx = tmp.val[0]; - } - vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1); + mVec128 = b3_splat_ps(mVec128, 3); // A0 + mVec128 = mVec128 * vQ2; // A0 * B0 - vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1); + A1 = A1 + A2; // AB12 + mVec128 = mVec128 - B1; // AB03 = AB0 - AB3 + A1 = _mm_xor_ps(A1, b3vPPPM); // change sign of the last element + mVec128 = mVec128 + A1; // AB03 + AB12 - vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1); - vQ2xz = vext_f32(vQ2zx, vQ2zx, 1); +#elif defined(B3_USE_NEON) - A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx); // X Y z x - B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx); // W W W X + float32x4_t vQ1 = mVec128; + float32x4_t vQ2 = q.get128(); + float32x4_t A0, A1, B1, A2, B2, A3, B3; + float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz; - A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1)); - B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1)); + { + float32x2x2_t tmp; + tmp = vtrn_f32(vget_high_f32(vQ1), vget_low_f32(vQ1)); // {z x}, {w y} + vQ1zx = tmp.val[0]; - A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z - B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z + tmp = vtrn_f32(vget_high_f32(vQ2), vget_low_f32(vQ2)); // {z x}, {w y} + vQ2zx = tmp.val[0]; + } + vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1); - A1 = vmulq_f32(A1, B1); - A2 = vmulq_f32(A2, B2); - A3 = vmulq_f32(A3, B3); // A3 *= B3 - A0 = vmulq_lane_f32(vQ2, vget_high_f32(vQ1), 1); // A0 * B0 + vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1); - A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2 - A0 = vsubq_f32(A0, A3); // AB03 = AB0 - AB3 - - // change the sign of the last element - A1 = (b3SimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)b3vPPPM); - A0 = vaddq_f32(A0, A1); // AB03 + AB12 - - mVec128 = A0; + vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1); + vQ2xz = vext_f32(vQ2zx, vQ2zx, 1); + + A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx); // X Y z x + B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx); // W W W X + + A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1)); + B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1)); + + A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z + B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z + + A1 = vmulq_f32(A1, B1); + A2 = vmulq_f32(A2, B2); + A3 = vmulq_f32(A3, B3); // A3 *= B3 + A0 = vmulq_lane_f32(vQ2, vget_high_f32(vQ1), 1); // A0 * B0 + + A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2 + A0 = vsubq_f32(A0, A3); // AB03 = AB0 - AB3 + + // change the sign of the last element + A1 = (b3SimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)b3vPPPM); + A0 = vaddq_f32(A0, A1); // AB03 + AB12 + + mVec128 = A0; #else setValue( - m_floats[3] * q.getX() + m_floats[0] * q.m_floats[3] + m_floats[1] * q.getZ() - m_floats[2] * q.getY(), + m_floats[3] * q.getX() + m_floats[0] * q.m_floats[3] + m_floats[1] * q.getZ() - m_floats[2] * q.getY(), m_floats[3] * q.getY() + m_floats[1] * q.m_floats[3] + m_floats[2] * q.getX() - m_floats[0] * q.getZ(), m_floats[3] * q.getZ() + m_floats[2] * q.m_floats[3] + m_floats[0] * q.getY() - m_floats[1] * q.getX(), m_floats[3] * q.m_floats[3] - m_floats[0] * q.getX() - m_floats[1] * q.getY() - m_floats[2] * q.getZ()); #endif return *this; } - /**@brief Return the dot product between this quaternion and another + /**@brief Return the dot product between this quaternion and another * @param q The other quaternion */ b3Scalar dot(const b3Quaternion& q) const { -#if defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE) - __m128 vd; - +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) + __m128 vd; + vd = _mm_mul_ps(mVec128, q.mVec128); - - __m128 t = _mm_movehl_ps(vd, vd); + + __m128 t = _mm_movehl_ps(vd, vd); vd = _mm_add_ps(vd, t); t = _mm_shuffle_ps(vd, vd, 0x55); vd = _mm_add_ss(vd, t); - - return _mm_cvtss_f32(vd); + + return _mm_cvtss_f32(vd); #elif defined(B3_USE_NEON) float32x4_t vd = vmulq_f32(mVec128, q.mVec128); - float32x2_t x = vpadd_f32(vget_low_f32(vd), vget_high_f32(vd)); + float32x2_t x = vpadd_f32(vget_low_f32(vd), vget_high_f32(vd)); x = vpadd_f32(x, x); return vget_lane_f32(x, 0); -#else - return m_floats[0] * q.getX() + - m_floats[1] * q.getY() + - m_floats[2] * q.getZ() + - m_floats[3] * q.m_floats[3]; +#else + return m_floats[0] * q.getX() + + m_floats[1] * q.getY() + + m_floats[2] * q.getZ() + + m_floats[3] * q.m_floats[3]; #endif } - /**@brief Return the length squared of the quaternion */ + /**@brief Return the length squared of the quaternion */ b3Scalar length2() const { return dot(*this); } - /**@brief Return the length of the quaternion */ + /**@brief Return the length of the quaternion */ b3Scalar length() const { return b3Sqrt(length2()); } - /**@brief Normalize the quaternion + /**@brief Normalize the quaternion * Such that x^2 + y^2 + z^2 +w^2 = 1 */ - b3Quaternion& normalize() + b3Quaternion& normalize() { -#if defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE) - __m128 vd; - +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) + __m128 vd; + vd = _mm_mul_ps(mVec128, mVec128); - - __m128 t = _mm_movehl_ps(vd, vd); + + __m128 t = _mm_movehl_ps(vd, vd); vd = _mm_add_ps(vd, t); t = _mm_shuffle_ps(vd, vd, 0x55); vd = _mm_add_ss(vd, t); vd = _mm_sqrt_ss(vd); vd = _mm_div_ss(b3vOnes, vd); - vd = b3_pshufd_ps(vd, 0); // splat + vd = b3_pshufd_ps(vd, 0); // splat mVec128 = _mm_mul_ps(mVec128, vd); - + return *this; -#else +#else return *this /= length(); #endif } - /**@brief Return a scaled version of this quaternion + /**@brief Return a scaled version of this quaternion * @param s The scale factor */ B3_FORCE_INLINE b3Quaternion operator*(const b3Scalar& s) const { -#if defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE) - __m128 vs = _mm_load_ss(&s); // (S 0 0 0) - vs = b3_pshufd_ps(vs, 0x00); // (S S S S) - +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) + __m128 vs = _mm_load_ss(&s); // (S 0 0 0) + vs = b3_pshufd_ps(vs, 0x00); // (S S S S) + return b3Quaternion(_mm_mul_ps(mVec128, vs)); #elif defined(B3_USE_NEON) return b3Quaternion(vmulq_n_f32(mVec128, s)); @@ -389,7 +383,7 @@ public: #endif } - /**@brief Return an inversely scaled versionof this quaternion + /**@brief Return an inversely scaled versionof this quaternion * @param s The inverse scale factor */ b3Quaternion operator/(const b3Scalar& s) const { @@ -397,29 +391,29 @@ public: return *this * (b3Scalar(1.0) / s); } - /**@brief Inversely scale this quaternion + /**@brief Inversely scale this quaternion * @param s The scale factor */ - b3Quaternion& operator/=(const b3Scalar& s) + b3Quaternion& operator/=(const b3Scalar& s) { b3Assert(s != b3Scalar(0.0)); return *this *= b3Scalar(1.0) / s; } - /**@brief Return a normalized version of this quaternion */ - b3Quaternion normalized() const + /**@brief Return a normalized version of this quaternion */ + b3Quaternion normalized() const { return *this / length(); - } - /**@brief Return the angle between this quaternion and the other + } + /**@brief Return the angle between this quaternion and the other * @param q The other quaternion */ - b3Scalar angle(const b3Quaternion& q) const + b3Scalar angle(const b3Quaternion& q) const { b3Scalar s = b3Sqrt(length2() * q.length2()); b3Assert(s != b3Scalar(0.0)); return b3Acos(dot(q) / s); } - /**@brief Return the angle of rotation represented by this quaternion */ - b3Scalar getAngle() const + /**@brief Return the angle of rotation represented by this quaternion */ + b3Scalar getAngle() const { b3Scalar s = b3Scalar(2.) * b3Acos(m_floats[3]); return s; @@ -428,117 +422,116 @@ public: /**@brief Return the axis of the rotation represented by this quaternion */ b3Vector3 getAxis() const { - b3Scalar s_squared = 1.f-m_floats[3]*m_floats[3]; - - if (s_squared < b3Scalar(10.) * B3_EPSILON) //Check for divide by zero - return b3MakeVector3(1.0, 0.0, 0.0); // Arbitrary - b3Scalar s = 1.f/b3Sqrt(s_squared); + b3Scalar s_squared = 1.f - m_floats[3] * m_floats[3]; + + if (s_squared < b3Scalar(10.) * B3_EPSILON) //Check for divide by zero + return b3MakeVector3(1.0, 0.0, 0.0); // Arbitrary + b3Scalar s = 1.f / b3Sqrt(s_squared); return b3MakeVector3(m_floats[0] * s, m_floats[1] * s, m_floats[2] * s); } /**@brief Return the inverse of this quaternion */ b3Quaternion inverse() const { -#if defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) return b3Quaternion(_mm_xor_ps(mVec128, b3vQInv)); #elif defined(B3_USE_NEON) - return b3Quaternion((b3SimdFloat4)veorq_s32((int32x4_t)mVec128, (int32x4_t)b3vQInv)); -#else + return b3Quaternion((b3SimdFloat4)veorq_s32((int32x4_t)mVec128, (int32x4_t)b3vQInv)); +#else return b3Quaternion(-m_floats[0], -m_floats[1], -m_floats[2], m_floats[3]); #endif } - /**@brief Return the sum of this quaternion and the other + /**@brief Return the sum of this quaternion and the other * @param q2 The other quaternion */ B3_FORCE_INLINE b3Quaternion operator+(const b3Quaternion& q2) const { -#if defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) return b3Quaternion(_mm_add_ps(mVec128, q2.mVec128)); #elif defined(B3_USE_NEON) - return b3Quaternion(vaddq_f32(mVec128, q2.mVec128)); -#else + return b3Quaternion(vaddq_f32(mVec128, q2.mVec128)); +#else const b3Quaternion& q1 = *this; return b3Quaternion(q1.getX() + q2.getX(), q1.getY() + q2.getY(), q1.getZ() + q2.getZ(), q1.m_floats[3] + q2.m_floats[3]); #endif } - /**@brief Return the difference between this quaternion and the other + /**@brief Return the difference between this quaternion and the other * @param q2 The other quaternion */ B3_FORCE_INLINE b3Quaternion operator-(const b3Quaternion& q2) const { -#if defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) return b3Quaternion(_mm_sub_ps(mVec128, q2.mVec128)); #elif defined(B3_USE_NEON) - return b3Quaternion(vsubq_f32(mVec128, q2.mVec128)); -#else + return b3Quaternion(vsubq_f32(mVec128, q2.mVec128)); +#else const b3Quaternion& q1 = *this; return b3Quaternion(q1.getX() - q2.getX(), q1.getY() - q2.getY(), q1.getZ() - q2.getZ(), q1.m_floats[3] - q2.m_floats[3]); #endif } - /**@brief Return the negative of this quaternion + /**@brief Return the negative of this quaternion * This simply negates each element */ B3_FORCE_INLINE b3Quaternion operator-() const { -#if defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) return b3Quaternion(_mm_xor_ps(mVec128, b3vMzeroMask)); #elif defined(B3_USE_NEON) - return b3Quaternion((b3SimdFloat4)veorq_s32((int32x4_t)mVec128, (int32x4_t)b3vMzeroMask) ); -#else + return b3Quaternion((b3SimdFloat4)veorq_s32((int32x4_t)mVec128, (int32x4_t)b3vMzeroMask)); +#else const b3Quaternion& q2 = *this; - return b3Quaternion( - q2.getX(), - q2.getY(), - q2.getZ(), - q2.m_floats[3]); + return b3Quaternion(-q2.getX(), -q2.getY(), -q2.getZ(), -q2.m_floats[3]); #endif } - /**@todo document this and it's use */ - B3_FORCE_INLINE b3Quaternion farthest( const b3Quaternion& qd) const + /**@todo document this and it's use */ + B3_FORCE_INLINE b3Quaternion farthest(const b3Quaternion& qd) const { - b3Quaternion diff,sum; + b3Quaternion diff, sum; diff = *this - qd; sum = *this + qd; - if( diff.dot(diff) > sum.dot(sum) ) + if (diff.dot(diff) > sum.dot(sum)) return qd; return (-qd); } /**@todo document this and it's use */ - B3_FORCE_INLINE b3Quaternion nearest( const b3Quaternion& qd) const + B3_FORCE_INLINE b3Quaternion nearest(const b3Quaternion& qd) const { - b3Quaternion diff,sum; + b3Quaternion diff, sum; diff = *this - qd; sum = *this + qd; - if( diff.dot(diff) < sum.dot(sum) ) + if (diff.dot(diff) < sum.dot(sum)) return qd; return (-qd); } - - /**@brief Return the quaternion which is the result of Spherical Linear Interpolation between this and the other quaternion + /**@brief Return the quaternion which is the result of Spherical Linear Interpolation between this and the other quaternion * @param q The other quaternion to interpolate with * @param t The ratio between this and q to interpolate. If t = 0 the result is this, if t=1 the result is q. * Slerp interpolates assuming constant velocity. */ b3Quaternion slerp(const b3Quaternion& q, const b3Scalar& t) const { - b3Scalar magnitude = b3Sqrt(length2() * q.length2()); - b3Assert(magnitude > b3Scalar(0)); + b3Scalar magnitude = b3Sqrt(length2() * q.length2()); + b3Assert(magnitude > b3Scalar(0)); - b3Scalar product = dot(q) / magnitude; - if (b3Fabs(product) < b3Scalar(1)) + b3Scalar product = dot(q) / magnitude; + if (b3Fabs(product) < b3Scalar(1)) { - // Take care of long angle case see http://en.wikipedia.org/wiki/Slerp - const b3Scalar sign = (product < 0) ? b3Scalar(-1) : b3Scalar(1); + // Take care of long angle case see http://en.wikipedia.org/wiki/Slerp + const b3Scalar sign = (product < 0) ? b3Scalar(-1) : b3Scalar(1); - const b3Scalar theta = b3Acos(sign * product); - const b3Scalar s1 = b3Sin(sign * t * theta); - const b3Scalar d = b3Scalar(1.0) / b3Sin(theta); - const b3Scalar s0 = b3Sin((b3Scalar(1.0) - t) * theta); + const b3Scalar theta = b3Acos(sign * product); + const b3Scalar s1 = b3Sin(sign * t * theta); + const b3Scalar d = b3Scalar(1.0) / b3Sin(theta); + const b3Scalar s0 = b3Sin((b3Scalar(1.0) - t) * theta); - return b3Quaternion( - (m_floats[0] * s0 + q.getX() * s1) * d, - (m_floats[1] * s0 + q.getY() * s1) * d, - (m_floats[2] * s0 + q.getZ() * s1) * d, - (m_floats[3] * s0 + q.m_floats[3] * s1) * d); + return b3Quaternion( + (m_floats[0] * s0 + q.getX() * s1) * d, + (m_floats[1] * s0 + q.getY() * s1) * d, + (m_floats[2] * s0 + q.getZ() * s1) * d, + (m_floats[3] * s0 + q.m_floats[3] * s1) * d); } else { @@ -546,301 +539,294 @@ public: } } - static const b3Quaternion& getIdentity() + static const b3Quaternion& getIdentity() { - static const b3Quaternion identityQuat(b3Scalar(0.),b3Scalar(0.),b3Scalar(0.),b3Scalar(1.)); + static const b3Quaternion identityQuat(b3Scalar(0.), b3Scalar(0.), b3Scalar(0.), b3Scalar(1.)); return identityQuat; } B3_FORCE_INLINE const b3Scalar& getW() const { return m_floats[3]; } - - }; - - - - /**@brief Return the product of two quaternions */ B3_FORCE_INLINE b3Quaternion -operator*(const b3Quaternion& q1, const b3Quaternion& q2) +operator*(const b3Quaternion& q1, const b3Quaternion& q2) { -#if defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) __m128 vQ1 = q1.get128(); __m128 vQ2 = q2.get128(); __m128 A0, A1, B1, A2, B2; - - A1 = b3_pshufd_ps(vQ1, B3_SHUFFLE(0,1,2,0)); // X Y z x // vtrn - B1 = b3_pshufd_ps(vQ2, B3_SHUFFLE(3,3,3,0)); // W W W X // vdup vext + + A1 = b3_pshufd_ps(vQ1, B3_SHUFFLE(0, 1, 2, 0)); // X Y z x // vtrn + B1 = b3_pshufd_ps(vQ2, B3_SHUFFLE(3, 3, 3, 0)); // W W W X // vdup vext A1 = A1 * B1; - - A2 = b3_pshufd_ps(vQ1, B3_SHUFFLE(1,2,0,1)); // Y Z X Y // vext - B2 = b3_pshufd_ps(vQ2, B3_SHUFFLE(2,0,1,1)); // z x Y Y // vtrn vdup + + A2 = b3_pshufd_ps(vQ1, B3_SHUFFLE(1, 2, 0, 1)); // Y Z X Y // vext + B2 = b3_pshufd_ps(vQ2, B3_SHUFFLE(2, 0, 1, 1)); // z x Y Y // vtrn vdup A2 = A2 * B2; - B1 = b3_pshufd_ps(vQ1, B3_SHUFFLE(2,0,1,2)); // z x Y Z // vtrn vext - B2 = b3_pshufd_ps(vQ2, B3_SHUFFLE(1,2,0,2)); // Y Z x z // vext vtrn - - B1 = B1 * B2; // A3 *= B3 + B1 = b3_pshufd_ps(vQ1, B3_SHUFFLE(2, 0, 1, 2)); // z x Y Z // vtrn vext + B2 = b3_pshufd_ps(vQ2, B3_SHUFFLE(1, 2, 0, 2)); // Y Z x z // vext vtrn - A0 = b3_splat_ps(vQ1, 3); // A0 - A0 = A0 * vQ2; // A0 * B0 + B1 = B1 * B2; // A3 *= B3 + + A0 = b3_splat_ps(vQ1, 3); // A0 + A0 = A0 * vQ2; // A0 * B0 + + A1 = A1 + A2; // AB12 + A0 = A0 - B1; // AB03 = AB0 - AB3 + + A1 = _mm_xor_ps(A1, b3vPPPM); // change sign of the last element + A0 = A0 + A1; // AB03 + AB12 - A1 = A1 + A2; // AB12 - A0 = A0 - B1; // AB03 = AB0 - AB3 - - A1 = _mm_xor_ps(A1, b3vPPPM); // change sign of the last element - A0 = A0 + A1; // AB03 + AB12 - return b3Quaternion(A0); -#elif defined(B3_USE_NEON) +#elif defined(B3_USE_NEON) float32x4_t vQ1 = q1.get128(); float32x4_t vQ2 = q2.get128(); float32x4_t A0, A1, B1, A2, B2, A3, B3; - float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz; - - { - float32x2x2_t tmp; - tmp = vtrn_f32( vget_high_f32(vQ1), vget_low_f32(vQ1) ); // {z x}, {w y} - vQ1zx = tmp.val[0]; + float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz; - tmp = vtrn_f32( vget_high_f32(vQ2), vget_low_f32(vQ2) ); // {z x}, {w y} - vQ2zx = tmp.val[0]; - } - vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1); + { + float32x2x2_t tmp; + tmp = vtrn_f32(vget_high_f32(vQ1), vget_low_f32(vQ1)); // {z x}, {w y} + vQ1zx = tmp.val[0]; - vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1); + tmp = vtrn_f32(vget_high_f32(vQ2), vget_low_f32(vQ2)); // {z x}, {w y} + vQ2zx = tmp.val[0]; + } + vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1); - vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1); - vQ2xz = vext_f32(vQ2zx, vQ2zx, 1); + vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1); - A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx); // X Y z x - B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx); // W W W X + vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1); + vQ2xz = vext_f32(vQ2zx, vQ2zx, 1); + + A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx); // X Y z x + B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx); // W W W X A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1)); - B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1)); + B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1)); - A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z - B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z + A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z + B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z A1 = vmulq_f32(A1, B1); A2 = vmulq_f32(A2, B2); - A3 = vmulq_f32(A3, B3); // A3 *= B3 - A0 = vmulq_lane_f32(vQ2, vget_high_f32(vQ1), 1); // A0 * B0 + A3 = vmulq_f32(A3, B3); // A3 *= B3 + A0 = vmulq_lane_f32(vQ2, vget_high_f32(vQ1), 1); // A0 * B0 + + A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2 + A0 = vsubq_f32(A0, A3); // AB03 = AB0 - AB3 + + // change the sign of the last element + A1 = (b3SimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)b3vPPPM); + A0 = vaddq_f32(A0, A1); // AB03 + AB12 - A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2 - A0 = vsubq_f32(A0, A3); // AB03 = AB0 - AB3 - - // change the sign of the last element - A1 = (b3SimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)b3vPPPM); - A0 = vaddq_f32(A0, A1); // AB03 + AB12 - return b3Quaternion(A0); #else return b3Quaternion( - q1.getW() * q2.getX() + q1.getX() * q2.getW() + q1.getY() * q2.getZ() - q1.getZ() * q2.getY(), + q1.getW() * q2.getX() + q1.getX() * q2.getW() + q1.getY() * q2.getZ() - q1.getZ() * q2.getY(), q1.getW() * q2.getY() + q1.getY() * q2.getW() + q1.getZ() * q2.getX() - q1.getX() * q2.getZ(), q1.getW() * q2.getZ() + q1.getZ() * q2.getW() + q1.getX() * q2.getY() - q1.getY() * q2.getX(), - q1.getW() * q2.getW() - q1.getX() * q2.getX() - q1.getY() * q2.getY() - q1.getZ() * q2.getZ()); + q1.getW() * q2.getW() - q1.getX() * q2.getX() - q1.getY() * q2.getY() - q1.getZ() * q2.getZ()); #endif } B3_FORCE_INLINE b3Quaternion operator*(const b3Quaternion& q, const b3Vector3& w) { -#if defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) __m128 vQ1 = q.get128(); __m128 vQ2 = w.get128(); __m128 A1, B1, A2, B2, A3, B3; - - A1 = b3_pshufd_ps(vQ1, B3_SHUFFLE(3,3,3,0)); - B1 = b3_pshufd_ps(vQ2, B3_SHUFFLE(0,1,2,0)); + + A1 = b3_pshufd_ps(vQ1, B3_SHUFFLE(3, 3, 3, 0)); + B1 = b3_pshufd_ps(vQ2, B3_SHUFFLE(0, 1, 2, 0)); A1 = A1 * B1; - - A2 = b3_pshufd_ps(vQ1, B3_SHUFFLE(1,2,0,1)); - B2 = b3_pshufd_ps(vQ2, B3_SHUFFLE(2,0,1,1)); + + A2 = b3_pshufd_ps(vQ1, B3_SHUFFLE(1, 2, 0, 1)); + B2 = b3_pshufd_ps(vQ2, B3_SHUFFLE(2, 0, 1, 1)); A2 = A2 * B2; - A3 = b3_pshufd_ps(vQ1, B3_SHUFFLE(2,0,1,2)); - B3 = b3_pshufd_ps(vQ2, B3_SHUFFLE(1,2,0,2)); - - A3 = A3 * B3; // A3 *= B3 + A3 = b3_pshufd_ps(vQ1, B3_SHUFFLE(2, 0, 1, 2)); + B3 = b3_pshufd_ps(vQ2, B3_SHUFFLE(1, 2, 0, 2)); + + A3 = A3 * B3; // A3 *= B3 + + A1 = A1 + A2; // AB12 + A1 = _mm_xor_ps(A1, b3vPPPM); // change sign of the last element + A1 = A1 - A3; // AB123 = AB12 - AB3 - A1 = A1 + A2; // AB12 - A1 = _mm_xor_ps(A1, b3vPPPM); // change sign of the last element - A1 = A1 - A3; // AB123 = AB12 - AB3 - return b3Quaternion(A1); - -#elif defined(B3_USE_NEON) + +#elif defined(B3_USE_NEON) float32x4_t vQ1 = q.get128(); float32x4_t vQ2 = w.get128(); float32x4_t A1, B1, A2, B2, A3, B3; - float32x2_t vQ1wx, vQ2zx, vQ1yz, vQ2yz, vQ1zx, vQ2xz; - - vQ1wx = vext_f32(vget_high_f32(vQ1), vget_low_f32(vQ1), 1); - { - float32x2x2_t tmp; + float32x2_t vQ1wx, vQ2zx, vQ1yz, vQ2yz, vQ1zx, vQ2xz; - tmp = vtrn_f32( vget_high_f32(vQ2), vget_low_f32(vQ2) ); // {z x}, {w y} - vQ2zx = tmp.val[0]; + vQ1wx = vext_f32(vget_high_f32(vQ1), vget_low_f32(vQ1), 1); + { + float32x2x2_t tmp; - tmp = vtrn_f32( vget_high_f32(vQ1), vget_low_f32(vQ1) ); // {z x}, {w y} - vQ1zx = tmp.val[0]; - } + tmp = vtrn_f32(vget_high_f32(vQ2), vget_low_f32(vQ2)); // {z x}, {w y} + vQ2zx = tmp.val[0]; - vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1); + tmp = vtrn_f32(vget_high_f32(vQ1), vget_low_f32(vQ1)); // {z x}, {w y} + vQ1zx = tmp.val[0]; + } - vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1); - vQ2xz = vext_f32(vQ2zx, vQ2zx, 1); + vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1); - A1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ1), 1), vQ1wx); // W W W X - B1 = vcombine_f32(vget_low_f32(vQ2), vQ2zx); // X Y z x + vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1); + vQ2xz = vext_f32(vQ2zx, vQ2zx, 1); + + A1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ1), 1), vQ1wx); // W W W X + B1 = vcombine_f32(vget_low_f32(vQ2), vQ2zx); // X Y z x A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1)); - B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1)); + B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1)); - A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z - B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z + A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z + B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z A1 = vmulq_f32(A1, B1); A2 = vmulq_f32(A2, B2); - A3 = vmulq_f32(A3, B3); // A3 *= B3 + A3 = vmulq_f32(A3, B3); // A3 *= B3 + + A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2 + + // change the sign of the last element + A1 = (b3SimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)b3vPPPM); + + A1 = vsubq_f32(A1, A3); // AB123 = AB12 - AB3 - A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2 - - // change the sign of the last element - A1 = (b3SimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)b3vPPPM); - - A1 = vsubq_f32(A1, A3); // AB123 = AB12 - AB3 - return b3Quaternion(A1); - + #else - return b3Quaternion( - q.getW() * w.getX() + q.getY() * w.getZ() - q.getZ() * w.getY(), - q.getW() * w.getY() + q.getZ() * w.getX() - q.getX() * w.getZ(), - q.getW() * w.getZ() + q.getX() * w.getY() - q.getY() * w.getX(), - -q.getX() * w.getX() - q.getY() * w.getY() - q.getZ() * w.getZ()); + return b3Quaternion( + q.getW() * w.getX() + q.getY() * w.getZ() - q.getZ() * w.getY(), + q.getW() * w.getY() + q.getZ() * w.getX() - q.getX() * w.getZ(), + q.getW() * w.getZ() + q.getX() * w.getY() - q.getY() * w.getX(), + -q.getX() * w.getX() - q.getY() * w.getY() - q.getZ() * w.getZ()); #endif } B3_FORCE_INLINE b3Quaternion operator*(const b3Vector3& w, const b3Quaternion& q) { -#if defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) __m128 vQ1 = w.get128(); __m128 vQ2 = q.get128(); __m128 A1, B1, A2, B2, A3, B3; - - A1 = b3_pshufd_ps(vQ1, B3_SHUFFLE(0,1,2,0)); // X Y z x - B1 = b3_pshufd_ps(vQ2, B3_SHUFFLE(3,3,3,0)); // W W W X + + A1 = b3_pshufd_ps(vQ1, B3_SHUFFLE(0, 1, 2, 0)); // X Y z x + B1 = b3_pshufd_ps(vQ2, B3_SHUFFLE(3, 3, 3, 0)); // W W W X A1 = A1 * B1; - - A2 = b3_pshufd_ps(vQ1, B3_SHUFFLE(1,2,0,1)); - B2 = b3_pshufd_ps(vQ2, B3_SHUFFLE(2,0,1,1)); - A2 = A2 *B2; + A2 = b3_pshufd_ps(vQ1, B3_SHUFFLE(1, 2, 0, 1)); + B2 = b3_pshufd_ps(vQ2, B3_SHUFFLE(2, 0, 1, 1)); - A3 = b3_pshufd_ps(vQ1, B3_SHUFFLE(2,0,1,2)); - B3 = b3_pshufd_ps(vQ2, B3_SHUFFLE(1,2,0,2)); - - A3 = A3 * B3; // A3 *= B3 + A2 = A2 * B2; + + A3 = b3_pshufd_ps(vQ1, B3_SHUFFLE(2, 0, 1, 2)); + B3 = b3_pshufd_ps(vQ2, B3_SHUFFLE(1, 2, 0, 2)); + + A3 = A3 * B3; // A3 *= B3 + + A1 = A1 + A2; // AB12 + A1 = _mm_xor_ps(A1, b3vPPPM); // change sign of the last element + A1 = A1 - A3; // AB123 = AB12 - AB3 - A1 = A1 + A2; // AB12 - A1 = _mm_xor_ps(A1, b3vPPPM); // change sign of the last element - A1 = A1 - A3; // AB123 = AB12 - AB3 - return b3Quaternion(A1); -#elif defined(B3_USE_NEON) +#elif defined(B3_USE_NEON) float32x4_t vQ1 = w.get128(); float32x4_t vQ2 = q.get128(); - float32x4_t A1, B1, A2, B2, A3, B3; - float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz; - - { - float32x2x2_t tmp; - - tmp = vtrn_f32( vget_high_f32(vQ1), vget_low_f32(vQ1) ); // {z x}, {w y} - vQ1zx = tmp.val[0]; + float32x4_t A1, B1, A2, B2, A3, B3; + float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz; - tmp = vtrn_f32( vget_high_f32(vQ2), vget_low_f32(vQ2) ); // {z x}, {w y} - vQ2zx = tmp.val[0]; - } - vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1); + { + float32x2x2_t tmp; - vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1); + tmp = vtrn_f32(vget_high_f32(vQ1), vget_low_f32(vQ1)); // {z x}, {w y} + vQ1zx = tmp.val[0]; - vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1); - vQ2xz = vext_f32(vQ2zx, vQ2zx, 1); + tmp = vtrn_f32(vget_high_f32(vQ2), vget_low_f32(vQ2)); // {z x}, {w y} + vQ2zx = tmp.val[0]; + } + vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1); - A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx); // X Y z x - B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx); // W W W X + vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1); + + vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1); + vQ2xz = vext_f32(vQ2zx, vQ2zx, 1); + + A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx); // X Y z x + B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx); // W W W X A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1)); - B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1)); + B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1)); - A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z - B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z + A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z + B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z A1 = vmulq_f32(A1, B1); A2 = vmulq_f32(A2, B2); - A3 = vmulq_f32(A3, B3); // A3 *= B3 + A3 = vmulq_f32(A3, B3); // A3 *= B3 + + A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2 + + // change the sign of the last element + A1 = (b3SimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)b3vPPPM); + + A1 = vsubq_f32(A1, A3); // AB123 = AB12 - AB3 - A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2 - - // change the sign of the last element - A1 = (b3SimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)b3vPPPM); - - A1 = vsubq_f32(A1, A3); // AB123 = AB12 - AB3 - return b3Quaternion(A1); - + #else - return b3Quaternion( - +w.getX() * q.getW() + w.getY() * q.getZ() - w.getZ() * q.getY(), + return b3Quaternion( + +w.getX() * q.getW() + w.getY() * q.getZ() - w.getZ() * q.getY(), +w.getY() * q.getW() + w.getZ() * q.getX() - w.getX() * q.getZ(), +w.getZ() * q.getW() + w.getX() * q.getY() - w.getY() * q.getX(), - -w.getX() * q.getX() - w.getY() * q.getY() - w.getZ() * q.getZ()); + -w.getX() * q.getX() - w.getY() * q.getY() - w.getZ() * q.getZ()); #endif } /**@brief Calculate the dot product between two quaternions */ -B3_FORCE_INLINE b3Scalar -b3Dot(const b3Quaternion& q1, const b3Quaternion& q2) -{ - return q1.dot(q2); +B3_FORCE_INLINE b3Scalar +b3Dot(const b3Quaternion& q1, const b3Quaternion& q2) +{ + return q1.dot(q2); } - /**@brief Return the length of a quaternion */ B3_FORCE_INLINE b3Scalar -b3Length(const b3Quaternion& q) -{ - return q.length(); +b3Length(const b3Quaternion& q) +{ + return q.length(); } /**@brief Return the angle between two quaternions*/ B3_FORCE_INLINE b3Scalar -b3Angle(const b3Quaternion& q1, const b3Quaternion& q2) -{ - return q1.angle(q2); +b3Angle(const b3Quaternion& q1, const b3Quaternion& q2) +{ + return q1.angle(q2); } /**@brief Return the inverse of a quaternion*/ B3_FORCE_INLINE b3Quaternion -b3Inverse(const b3Quaternion& q) +b3Inverse(const b3Quaternion& q) { return q.inverse(); } @@ -851,7 +837,7 @@ b3Inverse(const b3Quaternion& q) * @param t The ration between q1 and q2. t = 0 return q1, t=1 returns q2 * Slerp assumes constant velocity between positions. */ B3_FORCE_INLINE b3Quaternion -b3Slerp(const b3Quaternion& q1, const b3Quaternion& q2, const b3Scalar& t) +b3Slerp(const b3Quaternion& q1, const b3Quaternion& q2, const b3Scalar& t) { return q1.slerp(q2, t); } @@ -859,7 +845,7 @@ b3Slerp(const b3Quaternion& q1, const b3Quaternion& q2, const b3Scalar& t) B3_FORCE_INLINE b3Quaternion b3QuatMul(const b3Quaternion& rot0, const b3Quaternion& rot1) { - return rot0*rot1; + return rot0 * rot1; } B3_FORCE_INLINE b3Quaternion @@ -868,51 +854,45 @@ b3QuatNormalized(const b3Quaternion& orn) return orn.normalized(); } - - -B3_FORCE_INLINE b3Vector3 -b3QuatRotate(const b3Quaternion& rotation, const b3Vector3& v) +B3_FORCE_INLINE b3Vector3 +b3QuatRotate(const b3Quaternion& rotation, const b3Vector3& v) { b3Quaternion q = rotation * v; q *= rotation.inverse(); -#if defined (B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) return b3MakeVector3(_mm_and_ps(q.get128(), b3vFFF0fMask)); #elif defined(B3_USE_NEON) - return b3MakeVector3((float32x4_t)vandq_s32((int32x4_t)q.get128(), b3vFFF0Mask)); -#else - return b3MakeVector3(q.getX(),q.getY(),q.getZ()); + return b3MakeVector3((float32x4_t)vandq_s32((int32x4_t)q.get128(), b3vFFF0Mask)); +#else + return b3MakeVector3(q.getX(), q.getY(), q.getZ()); #endif } -B3_FORCE_INLINE b3Quaternion -b3ShortestArcQuat(const b3Vector3& v0, const b3Vector3& v1) // Game Programming Gems 2.10. make sure v0,v1 are normalized +B3_FORCE_INLINE b3Quaternion +b3ShortestArcQuat(const b3Vector3& v0, const b3Vector3& v1) // Game Programming Gems 2.10. make sure v0,v1 are normalized { b3Vector3 c = v0.cross(v1); - b3Scalar d = v0.dot(v1); + b3Scalar d = v0.dot(v1); if (d < -1.0 + B3_EPSILON) { - b3Vector3 n,unused; - b3PlaneSpace1(v0,n,unused); - return b3Quaternion(n.getX(),n.getY(),n.getZ(),0.0f); // just pick any vector that is orthogonal to v0 + b3Vector3 n, unused; + b3PlaneSpace1(v0, n, unused); + return b3Quaternion(n.getX(), n.getY(), n.getZ(), 0.0f); // just pick any vector that is orthogonal to v0 } - b3Scalar s = b3Sqrt((1.0f + d) * 2.0f); + b3Scalar s = b3Sqrt((1.0f + d) * 2.0f); b3Scalar rs = 1.0f / s; - return b3Quaternion(c.getX()*rs,c.getY()*rs,c.getZ()*rs,s * 0.5f); - + return b3Quaternion(c.getX() * rs, c.getY() * rs, c.getZ() * rs, s * 0.5f); } -B3_FORCE_INLINE b3Quaternion -b3ShortestArcQuatNormalize2(b3Vector3& v0,b3Vector3& v1) +B3_FORCE_INLINE b3Quaternion +b3ShortestArcQuatNormalize2(b3Vector3& v0, b3Vector3& v1) { v0.normalize(); v1.normalize(); - return b3ShortestArcQuat(v0,v1); + return b3ShortestArcQuat(v0, v1); } -#endif //B3_SIMD__QUATERNION_H_ - - - +#endif //B3_SIMD__QUATERNION_H_ diff --git a/src/Bullet3Common/b3Random.h b/src/Bullet3Common/b3Random.h index dc040f156..c2e21496c 100644 --- a/src/Bullet3Common/b3Random.h +++ b/src/Bullet3Common/b3Random.h @@ -12,8 +12,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #ifndef B3_GEN_RANDOM_H #define B3_GEN_RANDOM_H @@ -26,8 +24,8 @@ subject to the following restrictions: #define B3_RAND_MAX UINT_MAX -B3_FORCE_INLINE void b3Srand(unsigned int seed) { init_genrand(seed); } -B3_FORCE_INLINE unsigned int b3rand() { return genrand_int32(); } +B3_FORCE_INLINE void b3Srand(unsigned int seed) { init_genrand(seed); } +B3_FORCE_INLINE unsigned int b3rand() { return genrand_int32(); } #else @@ -35,8 +33,8 @@ B3_FORCE_INLINE unsigned int b3rand() { return genrand_int32() #define B3_RAND_MAX RAND_MAX -B3_FORCE_INLINE void b3Srand(unsigned int seed) { srand(seed); } -B3_FORCE_INLINE unsigned int b3rand() { return rand(); } +B3_FORCE_INLINE void b3Srand(unsigned int seed) { srand(seed); } +B3_FORCE_INLINE unsigned int b3rand() { return rand(); } #endif @@ -45,6 +43,4 @@ inline b3Scalar b3RandRange(b3Scalar minRange, b3Scalar maxRange) return (b3rand() / (b3Scalar(B3_RAND_MAX) + b3Scalar(1.0))) * (maxRange - minRange) + minRange; } - -#endif //B3_GEN_RANDOM_H - +#endif //B3_GEN_RANDOM_H diff --git a/src/Bullet3Common/b3ResizablePool.h b/src/Bullet3Common/b3ResizablePool.h index 06ad8a778..cafe3ff39 100644 --- a/src/Bullet3Common/b3ResizablePool.h +++ b/src/Bullet3Common/b3ResizablePool.h @@ -4,10 +4,10 @@ #include "Bullet3Common/b3AlignedObjectArray.h" -enum +enum { - B3_POOL_HANDLE_TERMINAL_FREE=-1, - B3_POOL_HANDLE_TERMINAL_USED =-2 + B3_POOL_HANDLE_TERMINAL_FREE = -1, + B3_POOL_HANDLE_TERMINAL_USED = -2 }; template @@ -20,25 +20,23 @@ struct b3PoolBodyHandle : public U { m_nextFreeHandle = next; } - int getNextFree() const + int getNextFree() const { return m_nextFreeHandle; } }; -template +template class b3ResizablePool { - protected: - b3AlignedObjectArray m_bodyHandles; - int m_numUsedHandles; // number of active handles - int m_firstFreeHandle; // free handles list + b3AlignedObjectArray m_bodyHandles; + int m_numUsedHandles; // number of active handles + int m_firstFreeHandle; // free handles list T* getHandleInternal(int handle) { return &m_bodyHandles[handle]; - } const T* getHandleInternal(int handle) const { @@ -46,17 +44,16 @@ protected: } public: - b3ResizablePool() { initHandles(); } - + virtual ~b3ResizablePool() { exitHandles(); } -///handle management + ///handle management int getNumHandles() const { @@ -65,44 +62,40 @@ public: void getUsedHandles(b3AlignedObjectArray& usedHandles) const { - - for (int i=0;i=0); - b3Assert(handle=m_bodyHandles.size())) + b3Assert(handle >= 0); + b3Assert(handle < m_bodyHandles.size()); + if ((handle < 0) || (handle >= m_bodyHandles.size())) { return 0; } - if (m_bodyHandles[handle].getNextFree()==B3_POOL_HANDLE_TERMINAL_USED) + if (m_bodyHandles[handle].getNextFree() == B3_POOL_HANDLE_TERMINAL_USED) { return &m_bodyHandles[handle]; } return 0; - } const T* getHandle(int handle) const { - b3Assert(handle>=0); - b3Assert(handle=m_bodyHandles.size())) + b3Assert(handle >= 0); + b3Assert(handle < m_bodyHandles.size()); + if ((handle < 0) || (handle >= m_bodyHandles.size())) { return 0; } - if (m_bodyHandles[handle].getNextFree()==B3_POOL_HANDLE_TERMINAL_USED) + if (m_bodyHandles[handle].getNextFree() == B3_POOL_HANDLE_TERMINAL_USED) { return &m_bodyHandles[handle]; } @@ -120,7 +113,6 @@ public: for (int i = curCapacity; i < newCapacity; i++) m_bodyHandles[i].setNextFree(i + 1); - m_bodyHandles[newCapacity - 1].setNextFree(-1); } m_firstFreeHandle = curCapacity; @@ -142,19 +134,18 @@ public: int allocHandle() { - b3Assert(m_firstFreeHandle>=0); + b3Assert(m_firstFreeHandle >= 0); int handle = m_firstFreeHandle; m_firstFreeHandle = getHandleInternal(handle)->getNextFree(); m_numUsedHandles++; - if (m_firstFreeHandle<0) + if (m_firstFreeHandle < 0) { //int curCapacity = m_bodyHandles.size(); - int additionalCapacity= m_bodyHandles.size(); + int additionalCapacity = m_bodyHandles.size(); increaseHandleCapacity(additionalCapacity); - getHandleInternal(handle)->setNextFree(m_firstFreeHandle); } getHandleInternal(handle)->setNextFree(B3_POOL_HANDLE_TERMINAL_USED); @@ -162,12 +153,11 @@ public: return handle; } - void freeHandle(int handle) { b3Assert(handle >= 0); - if (m_bodyHandles[handle].getNextFree()==B3_POOL_HANDLE_TERMINAL_USED) + if (m_bodyHandles[handle].getNextFree() == B3_POOL_HANDLE_TERMINAL_USED) { getHandleInternal(handle)->clear(); getHandleInternal(handle)->setNextFree(m_firstFreeHandle); @@ -176,7 +166,6 @@ public: } } }; - ///end handle management - - #endif //B3_RESIZABLE_POOL_H - \ No newline at end of file +///end handle management + +#endif //B3_RESIZABLE_POOL_H diff --git a/src/Bullet3Common/b3Scalar.h b/src/Bullet3Common/b3Scalar.h index dbc7fea39..0db5eb6f4 100644 --- a/src/Bullet3Common/b3Scalar.h +++ b/src/Bullet3Common/b3Scalar.h @@ -12,8 +12,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #ifndef B3_SCALAR_H #define B3_SCALAR_H @@ -22,238 +20,252 @@ subject to the following restrictions: #pragma unmanaged #endif - - #include -#include //size_t for MSVC 6.0 +#include //size_t for MSVC 6.0 #include //Original repository is at http://github.com/erwincoumans/bullet3 #define B3_BULLET_VERSION 300 -inline int b3GetVersion() +inline int b3GetVersion() { return B3_BULLET_VERSION; } -#if defined(DEBUG) || defined (_DEBUG) +#if defined(DEBUG) || defined(_DEBUG) #define B3_DEBUG #endif -#include "b3Logging.h"//for b3Error - +#include "b3Logging.h" //for b3Error #ifdef _WIN32 - #if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300) +#if defined(__MINGW32__) || defined(__CYGWIN__) || (defined(_MSC_VER) && _MSC_VER < 1300) - #define B3_FORCE_INLINE inline - #define B3_ATTRIBUTE_ALIGNED16(a) a - #define B3_ATTRIBUTE_ALIGNED64(a) a - #define B3_ATTRIBUTE_ALIGNED128(a) a - #else - //#define B3_HAS_ALIGNED_ALLOCATOR - #pragma warning(disable : 4324) // disable padding warning +#define B3_FORCE_INLINE inline +#define B3_ATTRIBUTE_ALIGNED16(a) a +#define B3_ATTRIBUTE_ALIGNED64(a) a +#define B3_ATTRIBUTE_ALIGNED128(a) a +#else +//#define B3_HAS_ALIGNED_ALLOCATOR +#pragma warning(disable : 4324) // disable padding warning // #pragma warning(disable:4530) // Disable the exception disable but used in MSCV Stl warning. - #pragma warning(disable:4996) //Turn off warnings about deprecated C routines +#pragma warning(disable : 4996) //Turn off warnings about deprecated C routines // #pragma warning(disable:4786) // Disable the "debug name too long" warning - #define B3_FORCE_INLINE __forceinline - #define B3_ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a - #define B3_ATTRIBUTE_ALIGNED64(a) __declspec(align(64)) a - #define B3_ATTRIBUTE_ALIGNED128(a) __declspec (align(128)) a - #ifdef _XBOX - #define B3_USE_VMX128 +#define B3_FORCE_INLINE __forceinline +#define B3_ATTRIBUTE_ALIGNED16(a) __declspec(align(16)) a +#define B3_ATTRIBUTE_ALIGNED64(a) __declspec(align(64)) a +#define B3_ATTRIBUTE_ALIGNED128(a) __declspec(align(128)) a +#ifdef _XBOX +#define B3_USE_VMX128 - #include - #define B3_HAVE_NATIVE_FSEL - #define b3Fsel(a,b,c) __fsel((a),(b),(c)) - #else +#include +#define B3_HAVE_NATIVE_FSEL +#define b3Fsel(a, b, c) __fsel((a), (b), (c)) +#else -#if (defined (_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined (B3_USE_DOUBLE_PRECISION)) - #if (defined (_M_IX86) || defined (_M_X64)) - #define B3_USE_SSE - #ifdef B3_USE_SSE - //B3_USE_SSE_IN_API is disabled under Windows by default, because - //it makes it harder to integrate Bullet into your application under Windows - //(structured embedding Bullet structs/classes need to be 16-byte aligned) - //with relatively little performance gain - //If you are not embedded Bullet data in your classes, or make sure that you align those classes on 16-byte boundaries - //you can manually enable this line or set it in the build system for a bit of performance gain (a few percent, dependent on usage) - //#define B3_USE_SSE_IN_API - #endif //B3_USE_SSE - #include - #endif +#if (defined(_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) && (!defined(B3_USE_DOUBLE_PRECISION)) +#if (defined(_M_IX86) || defined(_M_X64)) +#define B3_USE_SSE +#ifdef B3_USE_SSE +//B3_USE_SSE_IN_API is disabled under Windows by default, because +//it makes it harder to integrate Bullet into your application under Windows +//(structured embedding Bullet structs/classes need to be 16-byte aligned) +//with relatively little performance gain +//If you are not embedded Bullet data in your classes, or make sure that you align those classes on 16-byte boundaries +//you can manually enable this line or set it in the build system for a bit of performance gain (a few percent, dependent on usage) +//#define B3_USE_SSE_IN_API +#endif //B3_USE_SSE +#include +#endif #endif - #endif//_XBOX +#endif //_XBOX - #endif //__MINGW32__ +#endif //__MINGW32__ #ifdef B3_DEBUG - #ifdef _MSC_VER - #include - #define b3Assert(x) { if(!(x)){b3Error("Assert "__FILE__ ":%u ("#x")\n", __LINE__);__debugbreak(); }} - #else//_MSC_VER - #include - #define b3Assert assert - #endif//_MSC_VER +#ifdef _MSC_VER +#include +#define b3Assert(x) \ + { \ + if (!(x)) \ + { \ + b3Error( \ + "Assert "__FILE__ \ + ":%u (" #x ")\n", \ + __LINE__); \ + __debugbreak(); \ + } \ + } +#else //_MSC_VER +#include +#define b3Assert assert +#endif //_MSC_VER #else - #define b3Assert(x) +#define b3Assert(x) #endif - //b3FullAssert is optional, slows down a lot - #define b3FullAssert(x) +//b3FullAssert is optional, slows down a lot +#define b3FullAssert(x) - #define b3Likely(_c) _c - #define b3Unlikely(_c) _c +#define b3Likely(_c) _c +#define b3Unlikely(_c) _c #else - -#if defined (__CELLOS_LV2__) - #define B3_FORCE_INLINE inline __attribute__((always_inline)) - #define B3_ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16))) - #define B3_ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64))) - #define B3_ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128))) - #ifndef assert - #include - #endif + +#if defined(__CELLOS_LV2__) +#define B3_FORCE_INLINE inline __attribute__((always_inline)) +#define B3_ATTRIBUTE_ALIGNED16(a) a __attribute__((aligned(16))) +#define B3_ATTRIBUTE_ALIGNED64(a) a __attribute__((aligned(64))) +#define B3_ATTRIBUTE_ALIGNED128(a) a __attribute__((aligned(128))) +#ifndef assert +#include +#endif #ifdef B3_DEBUG #ifdef __SPU__ #include #define printf spu_printf - #define b3Assert(x) {if(!(x)){b3Error("Assert "__FILE__ ":%u ("#x")\n", __LINE__);spu_hcmpeq(0,0);}} +#define b3Assert(x) \ + { \ + if (!(x)) \ + { \ + b3Error( \ + "Assert "__FILE__ \ + ":%u (" #x ")\n", \ + __LINE__); \ + spu_hcmpeq(0, 0); \ + } \ + } #else - #define b3Assert assert +#define b3Assert assert #endif - -#else - #define b3Assert(x) -#endif - //b3FullAssert is optional, slows down a lot - #define b3FullAssert(x) - #define b3Likely(_c) _c - #define b3Unlikely(_c) _c +#else +#define b3Assert(x) +#endif +//b3FullAssert is optional, slows down a lot +#define b3FullAssert(x) + +#define b3Likely(_c) _c +#define b3Unlikely(_c) _c #else #ifdef USE_LIBSPE2 - #define B3_FORCE_INLINE __inline - #define B3_ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16))) - #define B3_ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64))) - #define B3_ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128))) - #ifndef assert - #include - #endif +#define B3_FORCE_INLINE __inline +#define B3_ATTRIBUTE_ALIGNED16(a) a __attribute__((aligned(16))) +#define B3_ATTRIBUTE_ALIGNED64(a) a __attribute__((aligned(64))) +#define B3_ATTRIBUTE_ALIGNED128(a) a __attribute__((aligned(128))) +#ifndef assert +#include +#endif #ifdef B3_DEBUG - #define b3Assert assert +#define b3Assert assert #else - #define b3Assert(x) +#define b3Assert(x) #endif - //b3FullAssert is optional, slows down a lot - #define b3FullAssert(x) +//b3FullAssert is optional, slows down a lot +#define b3FullAssert(x) - - #define b3Likely(_c) __builtin_expect((_c), 1) - #define b3Unlikely(_c) __builtin_expect((_c), 0) - +#define b3Likely(_c) __builtin_expect((_c), 1) +#define b3Unlikely(_c) __builtin_expect((_c), 0) #else - //non-windows systems +//non-windows systems -#if (defined (__APPLE__) && (!defined (B3_USE_DOUBLE_PRECISION))) - #if defined (__i386__) || defined (__x86_64__) - #define B3_USE_SSE - //B3_USE_SSE_IN_API is enabled on Mac OSX by default, because memory is automatically aligned on 16-byte boundaries - //if apps run into issues, we will disable the next line - #define B3_USE_SSE_IN_API - #ifdef B3_USE_SSE - // include appropriate SSE level - #if defined (__SSE4_1__) - #include - #elif defined (__SSSE3__) - #include - #elif defined (__SSE3__) - #include - #else - #include - #endif - #endif //B3_USE_SSE - #elif defined( __armv7__ ) - #ifdef __clang__ - #define B3_USE_NEON 1 +#if (defined(__APPLE__) && (!defined(B3_USE_DOUBLE_PRECISION))) +#if defined(__i386__) || defined(__x86_64__) +#define B3_USE_SSE +//B3_USE_SSE_IN_API is enabled on Mac OSX by default, because memory is automatically aligned on 16-byte boundaries +//if apps run into issues, we will disable the next line +#define B3_USE_SSE_IN_API +#ifdef B3_USE_SSE +// include appropriate SSE level +#if defined(__SSE4_1__) +#include +#elif defined(__SSSE3__) +#include +#elif defined(__SSE3__) +#include +#else +#include +#endif +#endif //B3_USE_SSE +#elif defined(__armv7__) +#ifdef __clang__ +#define B3_USE_NEON 1 - #if defined B3_USE_NEON && defined (__clang__) - #include - #endif//B3_USE_NEON - #endif //__clang__ - #endif//__arm__ +#if defined B3_USE_NEON && defined(__clang__) +#include +#endif //B3_USE_NEON +#endif //__clang__ +#endif //__arm__ - #define B3_FORCE_INLINE inline __attribute__ ((always_inline)) +#define B3_FORCE_INLINE inline __attribute__((always_inline)) ///@todo: check out alignment methods for other platforms/compilers - #define B3_ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16))) - #define B3_ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64))) - #define B3_ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128))) - #ifndef assert - #include - #endif +#define B3_ATTRIBUTE_ALIGNED16(a) a __attribute__((aligned(16))) +#define B3_ATTRIBUTE_ALIGNED64(a) a __attribute__((aligned(64))) +#define B3_ATTRIBUTE_ALIGNED128(a) a __attribute__((aligned(128))) +#ifndef assert +#include +#endif - #if defined(DEBUG) || defined (_DEBUG) - #if defined (__i386__) || defined (__x86_64__) - #include - #define b3Assert(x)\ - {\ - if(!(x))\ - {\ - b3Error("Assert %s in line %d, file %s\n",#x, __LINE__, __FILE__);\ - asm volatile ("int3");\ - }\ +#if defined(DEBUG) || defined(_DEBUG) +#if defined(__i386__) || defined(__x86_64__) +#include +#define b3Assert(x) \ + { \ + if (!(x)) \ + { \ + b3Error("Assert %s in line %d, file %s\n", #x, __LINE__, __FILE__); \ + asm volatile("int3"); \ + } \ } - #else//defined (__i386__) || defined (__x86_64__) - #define b3Assert assert - #endif//defined (__i386__) || defined (__x86_64__) - #else//defined(DEBUG) || defined (_DEBUG) - #define b3Assert(x) - #endif//defined(DEBUG) || defined (_DEBUG) +#else //defined (__i386__) || defined (__x86_64__) +#define b3Assert assert +#endif //defined (__i386__) || defined (__x86_64__) +#else //defined(DEBUG) || defined (_DEBUG) +#define b3Assert(x) +#endif //defined(DEBUG) || defined (_DEBUG) - //b3FullAssert is optional, slows down a lot - #define b3FullAssert(x) - #define b3Likely(_c) _c - #define b3Unlikely(_c) _c +//b3FullAssert is optional, slows down a lot +#define b3FullAssert(x) +#define b3Likely(_c) _c +#define b3Unlikely(_c) _c #else - #define B3_FORCE_INLINE inline - ///@todo: check out alignment methods for other platforms/compilers - #define B3_ATTRIBUTE_ALIGNED16(a) a __attribute__ ((aligned (16))) - #define B3_ATTRIBUTE_ALIGNED64(a) a __attribute__ ((aligned (64))) - #define B3_ATTRIBUTE_ALIGNED128(a) a __attribute__ ((aligned (128))) - ///#define B3_ATTRIBUTE_ALIGNED16(a) a - ///#define B3_ATTRIBUTE_ALIGNED64(a) a - ///#define B3_ATTRIBUTE_ALIGNED128(a) a - #ifndef assert - #include - #endif +#define B3_FORCE_INLINE inline +///@todo: check out alignment methods for other platforms/compilers +#define B3_ATTRIBUTE_ALIGNED16(a) a __attribute__((aligned(16))) +#define B3_ATTRIBUTE_ALIGNED64(a) a __attribute__((aligned(64))) +#define B3_ATTRIBUTE_ALIGNED128(a) a __attribute__((aligned(128))) +///#define B3_ATTRIBUTE_ALIGNED16(a) a +///#define B3_ATTRIBUTE_ALIGNED64(a) a +///#define B3_ATTRIBUTE_ALIGNED128(a) a +#ifndef assert +#include +#endif -#if defined(DEBUG) || defined (_DEBUG) - #define b3Assert assert +#if defined(DEBUG) || defined(_DEBUG) +#define b3Assert assert #else - #define b3Assert(x) +#define b3Assert(x) #endif - //b3FullAssert is optional, slows down a lot - #define b3FullAssert(x) - #define b3Likely(_c) _c - #define b3Unlikely(_c) _c -#endif //__APPLE__ +//b3FullAssert is optional, slows down a lot +#define b3FullAssert(x) +#define b3Likely(_c) _c +#define b3Unlikely(_c) _c +#endif //__APPLE__ -#endif // LIBSPE2 +#endif // LIBSPE2 -#endif //__CELLOS_LV2__ +#endif //__CELLOS_LV2__ #endif - ///The b3Scalar type abstracts floating point numbers, to easily switch between double and single floating point precision. #if defined(B3_USE_DOUBLE_PRECISION) typedef double b3Scalar; @@ -267,34 +279,34 @@ typedef float b3Scalar; #ifdef B3_USE_SSE typedef __m128 b3SimdFloat4; -#endif//B3_USE_SSE +#endif //B3_USE_SSE -#if defined B3_USE_SSE_IN_API && defined (B3_USE_SSE) +#if defined B3_USE_SSE_IN_API && defined(B3_USE_SSE) #ifdef _WIN32 #ifndef B3_NAN static int b3NanMask = 0x7F800001; -#define B3_NAN (*(float*)&b3NanMask) +#define B3_NAN (*(float *)&b3NanMask) #endif #ifndef B3_INFINITY_MASK -static int b3InfinityMask = 0x7F800000; -#define B3_INFINITY_MASK (*(float*)&b3InfinityMask) +static int b3InfinityMask = 0x7F800000; +#define B3_INFINITY_MASK (*(float *)&b3InfinityMask) #endif -inline __m128 operator + (const __m128 A, const __m128 B) +inline __m128 operator+(const __m128 A, const __m128 B) { - return _mm_add_ps(A, B); + return _mm_add_ps(A, B); } -inline __m128 operator - (const __m128 A, const __m128 B) +inline __m128 operator-(const __m128 A, const __m128 B) { - return _mm_sub_ps(A, B); + return _mm_sub_ps(A, B); } -inline __m128 operator * (const __m128 A, const __m128 B) +inline __m128 operator*(const __m128 A, const __m128 B) { - return _mm_mul_ps(A, B); + return _mm_mul_ps(A, B); } #define b3CastfTo128i(a) (_mm_castps_si128(a)) @@ -302,18 +314,19 @@ inline __m128 operator * (const __m128 A, const __m128 B) #define b3CastiTo128f(a) (_mm_castsi128_ps(a)) #define b3CastdTo128f(a) (_mm_castpd_ps(a)) #define b3CastdTo128i(a) (_mm_castpd_si128(a)) -#define b3Assign128(r0,r1,r2,r3) _mm_setr_ps(r0,r1,r2,r3) +#define b3Assign128(r0, r1, r2, r3) _mm_setr_ps(r0, r1, r2, r3) -#else//_WIN32 +#else //_WIN32 #define b3CastfTo128i(a) ((__m128i)(a)) #define b3CastfTo128d(a) ((__m128d)(a)) -#define b3CastiTo128f(a) ((__m128) (a)) -#define b3CastdTo128f(a) ((__m128) (a)) +#define b3CastiTo128f(a) ((__m128)(a)) +#define b3CastdTo128f(a) ((__m128)(a)) #define b3CastdTo128i(a) ((__m128i)(a)) -#define b3Assign128(r0,r1,r2,r3) (__m128){r0,r1,r2,r3} -#endif//_WIN32 -#endif //B3_USE_SSE_IN_API +#define b3Assign128(r0, r1, r2, r3) \ + (__m128) { r0, r1, r2, r3 } +#endif //_WIN32 +#endif //B3_USE_SSE_IN_API #ifdef B3_USE_NEON #include @@ -321,142 +334,160 @@ inline __m128 operator * (const __m128 A, const __m128 B) typedef float32x4_t b3SimdFloat4; #define B3_INFINITY INFINITY #define B3_NAN NAN -#define b3Assign128(r0,r1,r2,r3) (float32x4_t){r0,r1,r2,r3} +#define b3Assign128(r0, r1, r2, r3) \ + (float32x4_t) { r0, r1, r2, r3 } #endif - - - - -#define B3_DECLARE_ALIGNED_ALLOCATOR() \ - B3_FORCE_INLINE void* operator new(size_t sizeInBytes) { return b3AlignedAlloc(sizeInBytes,16); } \ - B3_FORCE_INLINE void operator delete(void* ptr) { b3AlignedFree(ptr); } \ - B3_FORCE_INLINE void* operator new(size_t, void* ptr) { return ptr; } \ - B3_FORCE_INLINE void operator delete(void*, void*) { } \ - B3_FORCE_INLINE void* operator new[](size_t sizeInBytes) { return b3AlignedAlloc(sizeInBytes,16); } \ - B3_FORCE_INLINE void operator delete[](void* ptr) { b3AlignedFree(ptr); } \ - B3_FORCE_INLINE void* operator new[](size_t, void* ptr) { return ptr; } \ - B3_FORCE_INLINE void operator delete[](void*, void*) { } \ - - +#define B3_DECLARE_ALIGNED_ALLOCATOR() \ + B3_FORCE_INLINE void *operator new(size_t sizeInBytes) { return b3AlignedAlloc(sizeInBytes, 16); } \ + B3_FORCE_INLINE void operator delete(void *ptr) { b3AlignedFree(ptr); } \ + B3_FORCE_INLINE void *operator new(size_t, void *ptr) { return ptr; } \ + B3_FORCE_INLINE void operator delete(void *, void *) {} \ + B3_FORCE_INLINE void *operator new[](size_t sizeInBytes) { return b3AlignedAlloc(sizeInBytes, 16); } \ + B3_FORCE_INLINE void operator delete[](void *ptr) { b3AlignedFree(ptr); } \ + B3_FORCE_INLINE void *operator new[](size_t, void *ptr) { return ptr; } \ + B3_FORCE_INLINE void operator delete[](void *, void *) {} #if defined(B3_USE_DOUBLE_PRECISION) || defined(B3_FORCE_DOUBLE_FUNCTIONS) - -B3_FORCE_INLINE b3Scalar b3Sqrt(b3Scalar x) { return sqrt(x); } + +B3_FORCE_INLINE b3Scalar b3Sqrt(b3Scalar x) +{ + return sqrt(x); +} B3_FORCE_INLINE b3Scalar b3Fabs(b3Scalar x) { return fabs(x); } B3_FORCE_INLINE b3Scalar b3Cos(b3Scalar x) { return cos(x); } B3_FORCE_INLINE b3Scalar b3Sin(b3Scalar x) { return sin(x); } B3_FORCE_INLINE b3Scalar b3Tan(b3Scalar x) { return tan(x); } -B3_FORCE_INLINE b3Scalar b3Acos(b3Scalar x) { if (xb3Scalar(1)) x=b3Scalar(1); return acos(x); } -B3_FORCE_INLINE b3Scalar b3Asin(b3Scalar x) { if (xb3Scalar(1)) x=b3Scalar(1); return asin(x); } +B3_FORCE_INLINE b3Scalar b3Acos(b3Scalar x) +{ + if (x < b3Scalar(-1)) x = b3Scalar(-1); + if (x > b3Scalar(1)) x = b3Scalar(1); + return acos(x); +} +B3_FORCE_INLINE b3Scalar b3Asin(b3Scalar x) +{ + if (x < b3Scalar(-1)) x = b3Scalar(-1); + if (x > b3Scalar(1)) x = b3Scalar(1); + return asin(x); +} B3_FORCE_INLINE b3Scalar b3Atan(b3Scalar x) { return atan(x); } B3_FORCE_INLINE b3Scalar b3Atan2(b3Scalar x, b3Scalar y) { return atan2(x, y); } B3_FORCE_INLINE b3Scalar b3Exp(b3Scalar x) { return exp(x); } B3_FORCE_INLINE b3Scalar b3Log(b3Scalar x) { return log(x); } -B3_FORCE_INLINE b3Scalar b3Pow(b3Scalar x,b3Scalar y) { return pow(x,y); } -B3_FORCE_INLINE b3Scalar b3Fmod(b3Scalar x,b3Scalar y) { return fmod(x,y); } +B3_FORCE_INLINE b3Scalar b3Pow(b3Scalar x, b3Scalar y) { return pow(x, y); } +B3_FORCE_INLINE b3Scalar b3Fmod(b3Scalar x, b3Scalar y) { return fmod(x, y); } #else - -B3_FORCE_INLINE b3Scalar b3Sqrt(b3Scalar y) -{ + +B3_FORCE_INLINE b3Scalar b3Sqrt(b3Scalar y) +{ #ifdef USE_APPROXIMATION - double x, z, tempf; - unsigned long *tfptr = ((unsigned long *)&tempf) + 1; + double x, z, tempf; + unsigned long *tfptr = ((unsigned long *)&tempf) + 1; tempf = y; - *tfptr = (0xbfcdd90a - *tfptr)>>1; /* estimate of 1/sqrt(y) */ - x = tempf; - z = y*b3Scalar(0.5); - x = (b3Scalar(1.5)*x)-(x*x)*(x*z); /* iteration formula */ - x = (b3Scalar(1.5)*x)-(x*x)*(x*z); - x = (b3Scalar(1.5)*x)-(x*x)*(x*z); - x = (b3Scalar(1.5)*x)-(x*x)*(x*z); - x = (b3Scalar(1.5)*x)-(x*x)*(x*z); - return x*y; + *tfptr = (0xbfcdd90a - *tfptr) >> 1; /* estimate of 1/sqrt(y) */ + x = tempf; + z = y * b3Scalar(0.5); + x = (b3Scalar(1.5) * x) - (x * x) * (x * z); /* iteration formula */ + x = (b3Scalar(1.5) * x) - (x * x) * (x * z); + x = (b3Scalar(1.5) * x) - (x * x) * (x * z); + x = (b3Scalar(1.5) * x) - (x * x) * (x * z); + x = (b3Scalar(1.5) * x) - (x * x) * (x * z); + return x * y; #else - return sqrtf(y); + return sqrtf(y); #endif } B3_FORCE_INLINE b3Scalar b3Fabs(b3Scalar x) { return fabsf(x); } B3_FORCE_INLINE b3Scalar b3Cos(b3Scalar x) { return cosf(x); } B3_FORCE_INLINE b3Scalar b3Sin(b3Scalar x) { return sinf(x); } B3_FORCE_INLINE b3Scalar b3Tan(b3Scalar x) { return tanf(x); } -B3_FORCE_INLINE b3Scalar b3Acos(b3Scalar x) { - if (xb3Scalar(1)) - x=b3Scalar(1); - return acosf(x); +B3_FORCE_INLINE b3Scalar b3Acos(b3Scalar x) +{ + if (x < b3Scalar(-1)) + x = b3Scalar(-1); + if (x > b3Scalar(1)) + x = b3Scalar(1); + return acosf(x); } -B3_FORCE_INLINE b3Scalar b3Asin(b3Scalar x) { - if (xb3Scalar(1)) - x=b3Scalar(1); - return asinf(x); +B3_FORCE_INLINE b3Scalar b3Asin(b3Scalar x) +{ + if (x < b3Scalar(-1)) + x = b3Scalar(-1); + if (x > b3Scalar(1)) + x = b3Scalar(1); + return asinf(x); } B3_FORCE_INLINE b3Scalar b3Atan(b3Scalar x) { return atanf(x); } B3_FORCE_INLINE b3Scalar b3Atan2(b3Scalar x, b3Scalar y) { return atan2f(x, y); } B3_FORCE_INLINE b3Scalar b3Exp(b3Scalar x) { return expf(x); } B3_FORCE_INLINE b3Scalar b3Log(b3Scalar x) { return logf(x); } -B3_FORCE_INLINE b3Scalar b3Pow(b3Scalar x,b3Scalar y) { return powf(x,y); } -B3_FORCE_INLINE b3Scalar b3Fmod(b3Scalar x,b3Scalar y) { return fmodf(x,y); } - +B3_FORCE_INLINE b3Scalar b3Pow(b3Scalar x, b3Scalar y) { return powf(x, y); } +B3_FORCE_INLINE b3Scalar b3Fmod(b3Scalar x, b3Scalar y) { return fmodf(x, y); } + #endif -#define B3_2_PI b3Scalar(6.283185307179586232) -#define B3_PI (B3_2_PI * b3Scalar(0.5)) -#define B3_HALF_PI (B3_2_PI * b3Scalar(0.25)) +#define B3_2_PI b3Scalar(6.283185307179586232) +#define B3_PI (B3_2_PI * b3Scalar(0.5)) +#define B3_HALF_PI (B3_2_PI * b3Scalar(0.25)) #define B3_RADS_PER_DEG (B3_2_PI / b3Scalar(360.0)) -#define B3_DEGS_PER_RAD (b3Scalar(360.0) / B3_2_PI) +#define B3_DEGS_PER_RAD (b3Scalar(360.0) / B3_2_PI) #define B3_SQRT12 b3Scalar(0.7071067811865475244008443621048490) -#define b3RecipSqrt(x) ((b3Scalar)(b3Scalar(1.0)/b3Sqrt(b3Scalar(x)))) /* reciprocal square root */ - +#define b3RecipSqrt(x) ((b3Scalar)(b3Scalar(1.0) / b3Sqrt(b3Scalar(x)))) /* reciprocal square root */ #ifdef B3_USE_DOUBLE_PRECISION -#define B3_EPSILON DBL_EPSILON -#define B3_INFINITY DBL_MAX +#define B3_EPSILON DBL_EPSILON +#define B3_INFINITY DBL_MAX #else -#define B3_EPSILON FLT_EPSILON -#define B3_INFINITY FLT_MAX +#define B3_EPSILON FLT_EPSILON +#define B3_INFINITY FLT_MAX #endif -B3_FORCE_INLINE b3Scalar b3Atan2Fast(b3Scalar y, b3Scalar x) +B3_FORCE_INLINE b3Scalar b3Atan2Fast(b3Scalar y, b3Scalar x) { b3Scalar coeff_1 = B3_PI / 4.0f; b3Scalar coeff_2 = 3.0f * coeff_1; b3Scalar abs_y = b3Fabs(y); b3Scalar angle; - if (x >= 0.0f) { + if (x >= 0.0f) + { b3Scalar r = (x - abs_y) / (x + abs_y); angle = coeff_1 - coeff_1 * r; - } else { + } + else + { b3Scalar r = (x + abs_y) / (abs_y - x); angle = coeff_2 - coeff_1 * r; } return (y < 0.0f) ? -angle : angle; } -B3_FORCE_INLINE bool b3FuzzyZero(b3Scalar x) { return b3Fabs(x) < B3_EPSILON; } +B3_FORCE_INLINE bool b3FuzzyZero(b3Scalar x) { return b3Fabs(x) < B3_EPSILON; } -B3_FORCE_INLINE bool b3Equal(b3Scalar a, b3Scalar eps) { +B3_FORCE_INLINE bool b3Equal(b3Scalar a, b3Scalar eps) +{ return (((a) <= eps) && !((a) < -eps)); } -B3_FORCE_INLINE bool b3GreaterEqual (b3Scalar a, b3Scalar eps) { +B3_FORCE_INLINE bool b3GreaterEqual(b3Scalar a, b3Scalar eps) +{ return (!((a) <= eps)); } - -B3_FORCE_INLINE int b3IsNegative(b3Scalar x) { - return x < b3Scalar(0.0) ? 1 : 0; +B3_FORCE_INLINE int b3IsNegative(b3Scalar x) +{ + return x < b3Scalar(0.0) ? 1 : 0; } B3_FORCE_INLINE b3Scalar b3Radians(b3Scalar x) { return x * B3_RADS_PER_DEG; } B3_FORCE_INLINE b3Scalar b3Degrees(b3Scalar x) { return x * B3_DEGS_PER_RAD; } -#define B3_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name +#define B3_DECLARE_HANDLE(name) \ + typedef struct name##__ \ + { \ + int unused; \ + } * name #ifndef b3Fsel B3_FORCE_INLINE b3Scalar b3Fsel(b3Scalar a, b3Scalar b, b3Scalar c) @@ -464,60 +495,57 @@ B3_FORCE_INLINE b3Scalar b3Fsel(b3Scalar a, b3Scalar b, b3Scalar c) return a >= 0 ? b : c; } #endif -#define b3Fsels(a,b,c) (b3Scalar)b3Fsel(a,b,c) - +#define b3Fsels(a, b, c) (b3Scalar) b3Fsel(a, b, c) B3_FORCE_INLINE bool b3MachineIsLittleEndian() { - long int i = 1; - const char *p = (const char *) &i; - if (p[0] == 1) // Lowest address contains the least significant byte - return true; - else - return false; + long int i = 1; + const char *p = (const char *)&i; + if (p[0] == 1) // Lowest address contains the least significant byte + return true; + else + return false; } - - ///b3Select avoids branches, which makes performance much better for consoles like Playstation 3 and XBox 360 ///Thanks Phil Knight. See also http://www.cellperformance.com/articles/2006/04/more_techniques_for_eliminatin_1.html -B3_FORCE_INLINE unsigned b3Select(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero) +B3_FORCE_INLINE unsigned b3Select(unsigned condition, unsigned valueIfConditionNonZero, unsigned valueIfConditionZero) { - // Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero - // Rely on positive value or'ed with its negative having sign bit on - // and zero value or'ed with its negative (which is still zero) having sign bit off - // Use arithmetic shift right, shifting the sign bit through all 32 bits - unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31); - unsigned testEqz = ~testNz; - return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); + // Set testNz to 0xFFFFFFFF if condition is nonzero, 0x00000000 if condition is zero + // Rely on positive value or'ed with its negative having sign bit on + // and zero value or'ed with its negative (which is still zero) having sign bit off + // Use arithmetic shift right, shifting the sign bit through all 32 bits + unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31); + unsigned testEqz = ~testNz; + return ((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); } B3_FORCE_INLINE int b3Select(unsigned condition, int valueIfConditionNonZero, int valueIfConditionZero) { - unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31); - unsigned testEqz = ~testNz; - return static_cast((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); + unsigned testNz = (unsigned)(((int)condition | -(int)condition) >> 31); + unsigned testEqz = ~testNz; + return static_cast((valueIfConditionNonZero & testNz) | (valueIfConditionZero & testEqz)); } B3_FORCE_INLINE float b3Select(unsigned condition, float valueIfConditionNonZero, float valueIfConditionZero) { #ifdef B3_HAVE_NATIVE_FSEL - return (float)b3Fsel((b3Scalar)condition - b3Scalar(1.0f), valueIfConditionNonZero, valueIfConditionZero); + return (float)b3Fsel((b3Scalar)condition - b3Scalar(1.0f), valueIfConditionNonZero, valueIfConditionZero); #else - return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero; + return (condition != 0) ? valueIfConditionNonZero : valueIfConditionZero; #endif } -template B3_FORCE_INLINE void b3Swap(T& a, T& b) +template +B3_FORCE_INLINE void b3Swap(T &a, T &b) { T tmp = a; a = b; b = tmp; } - //PCK: endian swapping functions B3_FORCE_INLINE unsigned b3SwapEndian(unsigned val) { - return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); + return (((val & 0xff000000) >> 24) | ((val & 0x00ff0000) >> 8) | ((val & 0x0000ff00) << 8) | ((val & 0x000000ff) << 24)); } B3_FORCE_INLINE unsigned short b3SwapEndian(unsigned short val) @@ -532,87 +560,85 @@ B3_FORCE_INLINE unsigned b3SwapEndian(int val) B3_FORCE_INLINE unsigned short b3SwapEndian(short val) { - return b3SwapEndian((unsigned short) val); + return b3SwapEndian((unsigned short)val); } ///b3SwapFloat uses using char pointers to swap the endianness ////b3SwapFloat/b3SwapDouble will NOT return a float, because the machine might 'correct' invalid floating point values -///Not all values of sign/exponent/mantissa are valid floating point numbers according to IEEE 754. -///When a floating point unit is faced with an invalid value, it may actually change the value, or worse, throw an exception. -///In most systems, running user mode code, you wouldn't get an exception, but instead the hardware/os/runtime will 'fix' the number for you. +///Not all values of sign/exponent/mantissa are valid floating point numbers according to IEEE 754. +///When a floating point unit is faced with an invalid value, it may actually change the value, or worse, throw an exception. +///In most systems, running user mode code, you wouldn't get an exception, but instead the hardware/os/runtime will 'fix' the number for you. ///so instead of returning a float/double, we return integer/long long integer -B3_FORCE_INLINE unsigned int b3SwapEndianFloat(float d) +B3_FORCE_INLINE unsigned int b3SwapEndianFloat(float d) { - unsigned int a = 0; - unsigned char *dst = (unsigned char *)&a; - unsigned char *src = (unsigned char *)&d; + unsigned int a = 0; + unsigned char *dst = (unsigned char *)&a; + unsigned char *src = (unsigned char *)&d; - dst[0] = src[3]; - dst[1] = src[2]; - dst[2] = src[1]; - dst[3] = src[0]; - return a; + dst[0] = src[3]; + dst[1] = src[2]; + dst[2] = src[1]; + dst[3] = src[0]; + return a; } // unswap using char pointers -B3_FORCE_INLINE float b3UnswapEndianFloat(unsigned int a) +B3_FORCE_INLINE float b3UnswapEndianFloat(unsigned int a) { - float d = 0.0f; - unsigned char *src = (unsigned char *)&a; - unsigned char *dst = (unsigned char *)&d; + float d = 0.0f; + unsigned char *src = (unsigned char *)&a; + unsigned char *dst = (unsigned char *)&d; - dst[0] = src[3]; - dst[1] = src[2]; - dst[2] = src[1]; - dst[3] = src[0]; + dst[0] = src[3]; + dst[1] = src[2]; + dst[2] = src[1]; + dst[3] = src[0]; - return d; + return d; } - // swap using char pointers -B3_FORCE_INLINE void b3SwapEndianDouble(double d, unsigned char* dst) +B3_FORCE_INLINE void b3SwapEndianDouble(double d, unsigned char *dst) { - unsigned char *src = (unsigned char *)&d; - - dst[0] = src[7]; - dst[1] = src[6]; - dst[2] = src[5]; - dst[3] = src[4]; - dst[4] = src[3]; - dst[5] = src[2]; - dst[6] = src[1]; - dst[7] = src[0]; + unsigned char *src = (unsigned char *)&d; + dst[0] = src[7]; + dst[1] = src[6]; + dst[2] = src[5]; + dst[3] = src[4]; + dst[4] = src[3]; + dst[5] = src[2]; + dst[6] = src[1]; + dst[7] = src[0]; } // unswap using char pointers -B3_FORCE_INLINE double b3UnswapEndianDouble(const unsigned char *src) +B3_FORCE_INLINE double b3UnswapEndianDouble(const unsigned char *src) { - double d = 0.0; - unsigned char *dst = (unsigned char *)&d; + double d = 0.0; + unsigned char *dst = (unsigned char *)&d; - dst[0] = src[7]; - dst[1] = src[6]; - dst[2] = src[5]; - dst[3] = src[4]; - dst[4] = src[3]; - dst[5] = src[2]; - dst[6] = src[1]; - dst[7] = src[0]; + dst[0] = src[7]; + dst[1] = src[6]; + dst[2] = src[5]; + dst[3] = src[4]; + dst[4] = src[3]; + dst[5] = src[2]; + dst[6] = src[1]; + dst[7] = src[0]; return d; } // returns normalized value in range [-B3_PI, B3_PI] -B3_FORCE_INLINE b3Scalar b3NormalizeAngle(b3Scalar angleInRadians) +B3_FORCE_INLINE b3Scalar b3NormalizeAngle(b3Scalar angleInRadians) { angleInRadians = b3Fmod(angleInRadians, B3_2_PI); - if(angleInRadians < -B3_PI) + if (angleInRadians < -B3_PI) { return angleInRadians + B3_2_PI; } - else if(angleInRadians > B3_PI) + else if (angleInRadians > B3_PI) { return angleInRadians - B3_2_PI; } @@ -626,38 +652,34 @@ B3_FORCE_INLINE b3Scalar b3NormalizeAngle(b3Scalar angleInRadians) struct b3TypedObject { b3TypedObject(int objectType) - :m_objectType(objectType) + : m_objectType(objectType) { } - int m_objectType; + int m_objectType; inline int getObjectType() const { return m_objectType; } }; - - ///align a pointer to the provided alignment, upwards -template T* b3AlignPointer(T* unalignedPtr, size_t alignment) +template +T *b3AlignPointer(T *unalignedPtr, size_t alignment) { - struct b3ConvertPointerSizeT { - union - { - T* ptr; - size_t integer; + union { + T *ptr; + size_t integer; }; }; - b3ConvertPointerSizeT converter; - - + b3ConvertPointerSizeT converter; + const size_t bit_mask = ~(alignment - 1); - converter.ptr = unalignedPtr; - converter.integer += alignment-1; + converter.ptr = unalignedPtr; + converter.integer += alignment - 1; converter.integer &= bit_mask; return converter.ptr; } -#endif //B3_SCALAR_H +#endif //B3_SCALAR_H diff --git a/src/Bullet3Common/b3StackAlloc.h b/src/Bullet3Common/b3StackAlloc.h index de7de056b..4972236ac 100644 --- a/src/Bullet3Common/b3StackAlloc.h +++ b/src/Bullet3Common/b3StackAlloc.h @@ -20,97 +20,99 @@ Nov.2006 #ifndef B3_STACK_ALLOC #define B3_STACK_ALLOC -#include "b3Scalar.h" //for b3Assert +#include "b3Scalar.h" //for b3Assert #include "b3AlignedAllocator.h" ///The b3Block class is an internal structure for the b3StackAlloc memory allocator. struct b3Block { - b3Block* previous; - unsigned char* address; + b3Block* previous; + unsigned char* address; }; ///The StackAlloc class provides some fast stack-based memory allocator (LIFO last-in first-out) class b3StackAlloc { public: + b3StackAlloc(unsigned int size) + { + ctor(); + create(size); + } + ~b3StackAlloc() { destroy(); } - b3StackAlloc(unsigned int size) { ctor();create(size); } - ~b3StackAlloc() { destroy(); } - - inline void create(unsigned int size) + inline void create(unsigned int size) { destroy(); - data = (unsigned char*) b3AlignedAlloc(size,16); - totalsize = size; + data = (unsigned char*)b3AlignedAlloc(size, 16); + totalsize = size; } - inline void destroy() + inline void destroy() { - b3Assert(usedsize==0); + b3Assert(usedsize == 0); //Raise(L"StackAlloc is still in use"); - if(usedsize==0) + if (usedsize == 0) { - if(!ischild && data) + if (!ischild && data) b3AlignedFree(data); - data = 0; - usedsize = 0; + data = 0; + usedsize = 0; } - } - int getAvailableMemory() const + int getAvailableMemory() const { return static_cast(totalsize - usedsize); } - unsigned char* allocate(unsigned int size) + unsigned char* allocate(unsigned int size) { - const unsigned int nus(usedsize+size); - if(nusprevious = current; - pb->address = data+usedsize; - current = pb; - return(pb); + b3Block* pb = (b3Block*)allocate(sizeof(b3Block)); + pb->previous = current; + pb->address = data + usedsize; + current = pb; + return (pb); } - B3_FORCE_INLINE void endBlock(b3Block* block) + B3_FORCE_INLINE void endBlock(b3Block* block) { - b3Assert(block==current); + b3Assert(block == current); //Raise(L"Unmatched blocks"); - if(block==current) + if (block == current) { - current = block->previous; - usedsize = (unsigned int)((block->address-data)-sizeof(b3Block)); + current = block->previous; + usedsize = (unsigned int)((block->address - data) - sizeof(b3Block)); } } private: - void ctor() + void ctor() { - data = 0; - totalsize = 0; - usedsize = 0; - current = 0; - ischild = false; + data = 0; + totalsize = 0; + usedsize = 0; + current = 0; + ischild = false; } - unsigned char* data; - unsigned int totalsize; - unsigned int usedsize; - b3Block* current; - bool ischild; + unsigned char* data; + unsigned int totalsize; + unsigned int usedsize; + b3Block* current; + bool ischild; }; -#endif //B3_STACK_ALLOC +#endif //B3_STACK_ALLOC diff --git a/src/Bullet3Common/b3Transform.h b/src/Bullet3Common/b3Transform.h index fa480759b..149da9d14 100644 --- a/src/Bullet3Common/b3Transform.h +++ b/src/Bullet3Common/b3Transform.h @@ -12,11 +12,9 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef B3_TRANSFORM_H #define B3_TRANSFORM_H - #include "b3Matrix3x3.h" #ifdef B3_USE_DOUBLE_PRECISION @@ -25,46 +23,45 @@ subject to the following restrictions: #define b3TransformData b3TransformFloatData #endif - - - /**@brief The b3Transform class supports rigid transforms with only translation and rotation and no scaling/shear. *It can be used in combination with b3Vector3, b3Quaternion and b3Matrix3x3 linear algebra classes. */ -B3_ATTRIBUTE_ALIGNED16(class) b3Transform { - - ///Storage for the rotation +B3_ATTRIBUTE_ALIGNED16(class) +b3Transform +{ + ///Storage for the rotation b3Matrix3x3 m_basis; - ///Storage for the translation - b3Vector3 m_origin; + ///Storage for the translation + b3Vector3 m_origin; public: - - /**@brief No initialization constructor */ + /**@brief No initialization constructor */ b3Transform() {} - /**@brief Constructor from b3Quaternion (optional b3Vector3 ) + /**@brief Constructor from b3Quaternion (optional b3Vector3 ) * @param q Rotation from quaternion * @param c Translation from Vector (default 0,0,0) */ - explicit B3_FORCE_INLINE b3Transform(const b3Quaternion& q, - const b3Vector3& c = b3MakeVector3(b3Scalar(0), b3Scalar(0), b3Scalar(0))) + explicit B3_FORCE_INLINE b3Transform(const b3Quaternion& q, + const b3Vector3& c = b3MakeVector3(b3Scalar(0), b3Scalar(0), b3Scalar(0))) : m_basis(q), - m_origin(c) - {} - - /**@brief Constructor from b3Matrix3x3 (optional b3Vector3) - * @param b Rotation from Matrix - * @param c Translation from Vector default (0,0,0)*/ - explicit B3_FORCE_INLINE b3Transform(const b3Matrix3x3& b, - const b3Vector3& c = b3MakeVector3(b3Scalar(0), b3Scalar(0), b3Scalar(0))) - : m_basis(b), - m_origin(c) - {} - /**@brief Copy constructor */ - B3_FORCE_INLINE b3Transform (const b3Transform& other) - : m_basis(other.m_basis), - m_origin(other.m_origin) + m_origin(c) { } - /**@brief Assignment Operator */ + + /**@brief Constructor from b3Matrix3x3 (optional b3Vector3) + * @param b Rotation from Matrix + * @param c Translation from Vector default (0,0,0)*/ + explicit B3_FORCE_INLINE b3Transform(const b3Matrix3x3& b, + const b3Vector3& c = b3MakeVector3(b3Scalar(0), b3Scalar(0), b3Scalar(0))) + : m_basis(b), + m_origin(c) + { + } + /**@brief Copy constructor */ + B3_FORCE_INLINE b3Transform(const b3Transform& other) + : m_basis(other.m_basis), + m_origin(other.m_origin) + { + } + /**@brief Assignment Operator */ B3_FORCE_INLINE b3Transform& operator=(const b3Transform& other) { m_basis = other.m_basis; @@ -72,70 +69,70 @@ public: return *this; } - - /**@brief Set the current transform as the value of the product of two transforms + /**@brief Set the current transform as the value of the product of two transforms * @param t1 Transform 1 * @param t2 Transform 2 * This = Transform1 * Transform2 */ - B3_FORCE_INLINE void mult(const b3Transform& t1, const b3Transform& t2) { - m_basis = t1.m_basis * t2.m_basis; - m_origin = t1(t2.m_origin); - } + B3_FORCE_INLINE void mult(const b3Transform& t1, const b3Transform& t2) + { + m_basis = t1.m_basis * t2.m_basis; + m_origin = t1(t2.m_origin); + } -/* void multInverseLeft(const b3Transform& t1, const b3Transform& t2) { + /* void multInverseLeft(const b3Transform& t1, const b3Transform& t2) { b3Vector3 v = t2.m_origin - t1.m_origin; m_basis = b3MultTransposeLeft(t1.m_basis, t2.m_basis); m_origin = v * t1.m_basis; } */ -/**@brief Return the transform of the vector */ + /**@brief Return the transform of the vector */ B3_FORCE_INLINE b3Vector3 operator()(const b3Vector3& x) const { - return x.dot3(m_basis[0], m_basis[1], m_basis[2]) + m_origin; + return x.dot3(m_basis[0], m_basis[1], m_basis[2]) + m_origin; } - /**@brief Return the transform of the vector */ + /**@brief Return the transform of the vector */ B3_FORCE_INLINE b3Vector3 operator*(const b3Vector3& x) const { return (*this)(x); } - /**@brief Return the transform of the b3Quaternion */ + /**@brief Return the transform of the b3Quaternion */ B3_FORCE_INLINE b3Quaternion operator*(const b3Quaternion& q) const { return getRotation() * q; } - /**@brief Return the basis matrix for the rotation */ - B3_FORCE_INLINE b3Matrix3x3& getBasis() { return m_basis; } - /**@brief Return the basis matrix for the rotation */ - B3_FORCE_INLINE const b3Matrix3x3& getBasis() const { return m_basis; } + /**@brief Return the basis matrix for the rotation */ + B3_FORCE_INLINE b3Matrix3x3& getBasis() { return m_basis; } + /**@brief Return the basis matrix for the rotation */ + B3_FORCE_INLINE const b3Matrix3x3& getBasis() const { return m_basis; } - /**@brief Return the origin vector translation */ - B3_FORCE_INLINE b3Vector3& getOrigin() { return m_origin; } - /**@brief Return the origin vector translation */ - B3_FORCE_INLINE const b3Vector3& getOrigin() const { return m_origin; } + /**@brief Return the origin vector translation */ + B3_FORCE_INLINE b3Vector3& getOrigin() { return m_origin; } + /**@brief Return the origin vector translation */ + B3_FORCE_INLINE const b3Vector3& getOrigin() const { return m_origin; } - /**@brief Return a quaternion representing the rotation */ - b3Quaternion getRotation() const { + /**@brief Return a quaternion representing the rotation */ + b3Quaternion getRotation() const + { b3Quaternion q; m_basis.getRotation(q); return q; } - - - /**@brief Set from an array + + /**@brief Set from an array * @param m A pointer to a 15 element array (12 rotation(row major padded on the right by 1), and 3 translation */ - void setFromOpenGLMatrix(const b3Scalar *m) + void setFromOpenGLMatrix(const b3Scalar* m) { m_basis.setFromOpenGLSubMatrix(m); - m_origin.setValue(m[12],m[13],m[14]); + m_origin.setValue(m[12], m[13], m[14]); } - /**@brief Fill an array representation + /**@brief Fill an array representation * @param m A pointer to a 15 element array (12 rotation(row major padded on the right by 1), and 3 translation */ - void getOpenGLMatrix(b3Scalar *m) const + void getOpenGLMatrix(b3Scalar * m) const { m_basis.getOpenGLSubMatrix(m); m[12] = m_origin.getX(); @@ -144,80 +141,76 @@ public: m[15] = b3Scalar(1.0); } - /**@brief Set the translational element + /**@brief Set the translational element * @param origin The vector to set the translation to */ - B3_FORCE_INLINE void setOrigin(const b3Vector3& origin) - { + B3_FORCE_INLINE void setOrigin(const b3Vector3& origin) + { m_origin = origin; } B3_FORCE_INLINE b3Vector3 invXform(const b3Vector3& inVec) const; - - /**@brief Set the rotational element by b3Matrix3x3 */ + /**@brief Set the rotational element by b3Matrix3x3 */ B3_FORCE_INLINE void setBasis(const b3Matrix3x3& basis) - { + { m_basis = basis; } - /**@brief Set the rotational element by b3Quaternion */ + /**@brief Set the rotational element by b3Quaternion */ B3_FORCE_INLINE void setRotation(const b3Quaternion& q) { m_basis.setRotation(q); } - - /**@brief Set this transformation to the identity */ + /**@brief Set this transformation to the identity */ void setIdentity() { m_basis.setIdentity(); m_origin.setValue(b3Scalar(0.0), b3Scalar(0.0), b3Scalar(0.0)); } - /**@brief Multiply this Transform by another(this = this * another) + /**@brief Multiply this Transform by another(this = this * another) * @param t The other transform */ - b3Transform& operator*=(const b3Transform& t) + b3Transform& operator*=(const b3Transform& t) { m_origin += m_basis * t.m_origin; m_basis *= t.m_basis; return *this; } - /**@brief Return the inverse of this transform */ + /**@brief Return the inverse of this transform */ b3Transform inverse() const - { + { b3Matrix3x3 inv = m_basis.transpose(); return b3Transform(inv, inv * -m_origin); } - /**@brief Return the inverse of this transform times the other transform + /**@brief Return the inverse of this transform times the other transform * @param t The other transform * return this.inverse() * the other */ - b3Transform inverseTimes(const b3Transform& t) const; + b3Transform inverseTimes(const b3Transform& t) const; - /**@brief Return the product of this transform and the other */ + /**@brief Return the product of this transform and the other */ b3Transform operator*(const b3Transform& t) const; - /**@brief Return an identity transform */ - static const b3Transform& getIdentity() + /**@brief Return an identity transform */ + static const b3Transform& getIdentity() { static const b3Transform identityTransform(b3Matrix3x3::getIdentity()); return identityTransform; } - void serialize(struct b3TransformData& dataOut) const; + void serialize(struct b3TransformData & dataOut) const; - void serializeFloat(struct b3TransformFloatData& dataOut) const; + void serializeFloat(struct b3TransformFloatData & dataOut) const; - void deSerialize(const struct b3TransformData& dataIn); + void deSerialize(const struct b3TransformData& dataIn); - void deSerializeDouble(const struct b3TransformDoubleData& dataIn); - - void deSerializeFloat(const struct b3TransformFloatData& dataIn); + void deSerializeDouble(const struct b3TransformDoubleData& dataIn); + void deSerializeFloat(const struct b3TransformFloatData& dataIn); }; - B3_FORCE_INLINE b3Vector3 b3Transform::invXform(const b3Vector3& inVec) const { @@ -225,80 +218,69 @@ b3Transform::invXform(const b3Vector3& inVec) const return (m_basis.transpose() * v); } -B3_FORCE_INLINE b3Transform -b3Transform::inverseTimes(const b3Transform& t) const +B3_FORCE_INLINE b3Transform +b3Transform::inverseTimes(const b3Transform& t) const { b3Vector3 v = t.getOrigin() - m_origin; - return b3Transform(m_basis.transposeTimes(t.m_basis), - v * m_basis); + return b3Transform(m_basis.transposeTimes(t.m_basis), + v * m_basis); } -B3_FORCE_INLINE b3Transform -b3Transform::operator*(const b3Transform& t) const +B3_FORCE_INLINE b3Transform + b3Transform::operator*(const b3Transform& t) const { - return b3Transform(m_basis * t.m_basis, - (*this)(t.m_origin)); + return b3Transform(m_basis * t.m_basis, + (*this)(t.m_origin)); } /**@brief Test if two transforms have all elements equal */ B3_FORCE_INLINE bool operator==(const b3Transform& t1, const b3Transform& t2) { - return ( t1.getBasis() == t2.getBasis() && - t1.getOrigin() == t2.getOrigin() ); + return (t1.getBasis() == t2.getBasis() && + t1.getOrigin() == t2.getOrigin()); } - ///for serialization -struct b3TransformFloatData +struct b3TransformFloatData { - b3Matrix3x3FloatData m_basis; - b3Vector3FloatData m_origin; + b3Matrix3x3FloatData m_basis; + b3Vector3FloatData m_origin; }; -struct b3TransformDoubleData +struct b3TransformDoubleData { - b3Matrix3x3DoubleData m_basis; - b3Vector3DoubleData m_origin; + b3Matrix3x3DoubleData m_basis; + b3Vector3DoubleData m_origin; }; - - -B3_FORCE_INLINE void b3Transform::serialize(b3TransformData& dataOut) const +B3_FORCE_INLINE void b3Transform::serialize(b3TransformData& dataOut) const { m_basis.serialize(dataOut.m_basis); m_origin.serialize(dataOut.m_origin); } -B3_FORCE_INLINE void b3Transform::serializeFloat(b3TransformFloatData& dataOut) const +B3_FORCE_INLINE void b3Transform::serializeFloat(b3TransformFloatData& dataOut) const { m_basis.serializeFloat(dataOut.m_basis); m_origin.serializeFloat(dataOut.m_origin); } - -B3_FORCE_INLINE void b3Transform::deSerialize(const b3TransformData& dataIn) +B3_FORCE_INLINE void b3Transform::deSerialize(const b3TransformData& dataIn) { m_basis.deSerialize(dataIn.m_basis); m_origin.deSerialize(dataIn.m_origin); } -B3_FORCE_INLINE void b3Transform::deSerializeFloat(const b3TransformFloatData& dataIn) +B3_FORCE_INLINE void b3Transform::deSerializeFloat(const b3TransformFloatData& dataIn) { m_basis.deSerializeFloat(dataIn.m_basis); m_origin.deSerializeFloat(dataIn.m_origin); } -B3_FORCE_INLINE void b3Transform::deSerializeDouble(const b3TransformDoubleData& dataIn) +B3_FORCE_INLINE void b3Transform::deSerializeDouble(const b3TransformDoubleData& dataIn) { m_basis.deSerializeDouble(dataIn.m_basis); m_origin.deSerializeDouble(dataIn.m_origin); } - -#endif //B3_TRANSFORM_H - - - - - - +#endif //B3_TRANSFORM_H diff --git a/src/Bullet3Common/b3TransformUtil.h b/src/Bullet3Common/b3TransformUtil.h index 6ce580c13..1850a9be5 100644 --- a/src/Bullet3Common/b3TransformUtil.h +++ b/src/Bullet3Common/b3TransformUtil.h @@ -12,204 +12,189 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef B3_TRANSFORM_UTIL_H #define B3_TRANSFORM_UTIL_H #include "b3Transform.h" -#define B3_ANGULAR_MOTION_THRESHOLD b3Scalar(0.5)*B3_HALF_PI +#define B3_ANGULAR_MOTION_THRESHOLD b3Scalar(0.5) * B3_HALF_PI - - - -B3_FORCE_INLINE b3Vector3 b3AabbSupport(const b3Vector3& halfExtents,const b3Vector3& supportDir) +B3_FORCE_INLINE b3Vector3 b3AabbSupport(const b3Vector3& halfExtents, const b3Vector3& supportDir) { return b3MakeVector3(supportDir.getX() < b3Scalar(0.0) ? -halfExtents.getX() : halfExtents.getX(), - supportDir.getY() < b3Scalar(0.0) ? -halfExtents.getY() : halfExtents.getY(), - supportDir.getZ() < b3Scalar(0.0) ? -halfExtents.getZ() : halfExtents.getZ()); + supportDir.getY() < b3Scalar(0.0) ? -halfExtents.getY() : halfExtents.getY(), + supportDir.getZ() < b3Scalar(0.0) ? -halfExtents.getZ() : halfExtents.getZ()); } - - - - - /// Utils related to temporal transforms class b3TransformUtil { - public: - - static void integrateTransform(const b3Transform& curTrans,const b3Vector3& linvel,const b3Vector3& angvel,b3Scalar timeStep,b3Transform& predictedTransform) + static void integrateTransform(const b3Transform& curTrans, const b3Vector3& linvel, const b3Vector3& angvel, b3Scalar timeStep, b3Transform& predictedTransform) { predictedTransform.setOrigin(curTrans.getOrigin() + linvel * timeStep); -// #define QUATERNION_DERIVATIVE - #ifdef QUATERNION_DERIVATIVE + // #define QUATERNION_DERIVATIVE +#ifdef QUATERNION_DERIVATIVE b3Quaternion predictedOrn = curTrans.getRotation(); predictedOrn += (angvel * predictedOrn) * (timeStep * b3Scalar(0.5)); predictedOrn.normalize(); - #else +#else //Exponential map //google for "Practical Parameterization of Rotations Using the Exponential Map", F. Sebastian Grassia b3Vector3 axis; - b3Scalar fAngle = angvel.length(); + b3Scalar fAngle = angvel.length(); //limit the angular motion - if (fAngle*timeStep > B3_ANGULAR_MOTION_THRESHOLD) + if (fAngle * timeStep > B3_ANGULAR_MOTION_THRESHOLD) { fAngle = B3_ANGULAR_MOTION_THRESHOLD / timeStep; } - if ( fAngle < b3Scalar(0.001) ) + if (fAngle < b3Scalar(0.001)) { // use Taylor's expansions of sync function - axis = angvel*( b3Scalar(0.5)*timeStep-(timeStep*timeStep*timeStep)*(b3Scalar(0.020833333333))*fAngle*fAngle ); + axis = angvel * (b3Scalar(0.5) * timeStep - (timeStep * timeStep * timeStep) * (b3Scalar(0.020833333333)) * fAngle * fAngle); } else { // sync(fAngle) = sin(c*fAngle)/t - axis = angvel*( b3Sin(b3Scalar(0.5)*fAngle*timeStep)/fAngle ); + axis = angvel * (b3Sin(b3Scalar(0.5) * fAngle * timeStep) / fAngle); } - b3Quaternion dorn (axis.getX(),axis.getY(),axis.getZ(),b3Cos( fAngle*timeStep*b3Scalar(0.5) )); + b3Quaternion dorn(axis.getX(), axis.getY(), axis.getZ(), b3Cos(fAngle * timeStep * b3Scalar(0.5))); b3Quaternion orn0 = curTrans.getRotation(); b3Quaternion predictedOrn = dorn * orn0; predictedOrn.normalize(); - #endif +#endif predictedTransform.setRotation(predictedOrn); } - static void calculateVelocityQuaternion(const b3Vector3& pos0,const b3Vector3& pos1,const b3Quaternion& orn0,const b3Quaternion& orn1,b3Scalar timeStep,b3Vector3& linVel,b3Vector3& angVel) + static void calculateVelocityQuaternion(const b3Vector3& pos0, const b3Vector3& pos1, const b3Quaternion& orn0, const b3Quaternion& orn1, b3Scalar timeStep, b3Vector3& linVel, b3Vector3& angVel) { linVel = (pos1 - pos0) / timeStep; b3Vector3 axis; - b3Scalar angle; + b3Scalar angle; if (orn0 != orn1) { - calculateDiffAxisAngleQuaternion(orn0,orn1,axis,angle); + calculateDiffAxisAngleQuaternion(orn0, orn1, axis, angle); angVel = axis * angle / timeStep; - } else + } + else { - angVel.setValue(0,0,0); + angVel.setValue(0, 0, 0); } } - static void calculateDiffAxisAngleQuaternion(const b3Quaternion& orn0,const b3Quaternion& orn1a,b3Vector3& axis,b3Scalar& angle) + static void calculateDiffAxisAngleQuaternion(const b3Quaternion& orn0, const b3Quaternion& orn1a, b3Vector3& axis, b3Scalar& angle) { b3Quaternion orn1 = orn0.nearest(orn1a); b3Quaternion dorn = orn1 * orn0.inverse(); angle = dorn.getAngle(); - axis = b3MakeVector3(dorn.getX(),dorn.getY(),dorn.getZ()); + axis = b3MakeVector3(dorn.getX(), dorn.getY(), dorn.getZ()); axis[3] = b3Scalar(0.); //check for axis length b3Scalar len = axis.length2(); - if (len < B3_EPSILON*B3_EPSILON) - axis = b3MakeVector3(b3Scalar(1.),b3Scalar(0.),b3Scalar(0.)); + if (len < B3_EPSILON * B3_EPSILON) + axis = b3MakeVector3(b3Scalar(1.), b3Scalar(0.), b3Scalar(0.)); else axis /= b3Sqrt(len); } - static void calculateVelocity(const b3Transform& transform0,const b3Transform& transform1,b3Scalar timeStep,b3Vector3& linVel,b3Vector3& angVel) + static void calculateVelocity(const b3Transform& transform0, const b3Transform& transform1, b3Scalar timeStep, b3Vector3& linVel, b3Vector3& angVel) { linVel = (transform1.getOrigin() - transform0.getOrigin()) / timeStep; b3Vector3 axis; - b3Scalar angle; - calculateDiffAxisAngle(transform0,transform1,axis,angle); + b3Scalar angle; + calculateDiffAxisAngle(transform0, transform1, axis, angle); angVel = axis * angle / timeStep; } - static void calculateDiffAxisAngle(const b3Transform& transform0,const b3Transform& transform1,b3Vector3& axis,b3Scalar& angle) + static void calculateDiffAxisAngle(const b3Transform& transform0, const b3Transform& transform1, b3Vector3& axis, b3Scalar& angle) { b3Matrix3x3 dmat = transform1.getBasis() * transform0.getBasis().inverse(); b3Quaternion dorn; dmat.getRotation(dorn); - ///floating point inaccuracy can lead to w component > 1..., which breaks + ///floating point inaccuracy can lead to w component > 1..., which breaks dorn.normalize(); - + angle = dorn.getAngle(); - axis = b3MakeVector3(dorn.getX(),dorn.getY(),dorn.getZ()); + axis = b3MakeVector3(dorn.getX(), dorn.getY(), dorn.getZ()); axis[3] = b3Scalar(0.); //check for axis length b3Scalar len = axis.length2(); - if (len < B3_EPSILON*B3_EPSILON) - axis = b3MakeVector3(b3Scalar(1.),b3Scalar(0.),b3Scalar(0.)); + if (len < B3_EPSILON * B3_EPSILON) + axis = b3MakeVector3(b3Scalar(1.), b3Scalar(0.), b3Scalar(0.)); else axis /= b3Sqrt(len); } - }; - -///The b3ConvexSeparatingDistanceUtil can help speed up convex collision detection +///The b3ConvexSeparatingDistanceUtil can help speed up convex collision detection ///by conservatively updating a cached separating distance/vector instead of re-calculating the closest distance -class b3ConvexSeparatingDistanceUtil +class b3ConvexSeparatingDistanceUtil { - b3Quaternion m_ornA; - b3Quaternion m_ornB; - b3Vector3 m_posA; - b3Vector3 m_posB; - - b3Vector3 m_separatingNormal; + b3Quaternion m_ornA; + b3Quaternion m_ornB; + b3Vector3 m_posA; + b3Vector3 m_posB; - b3Scalar m_boundingRadiusA; - b3Scalar m_boundingRadiusB; - b3Scalar m_separatingDistance; + b3Vector3 m_separatingNormal; + + b3Scalar m_boundingRadiusA; + b3Scalar m_boundingRadiusB; + b3Scalar m_separatingDistance; public: - - b3ConvexSeparatingDistanceUtil(b3Scalar boundingRadiusA,b3Scalar boundingRadiusB) - :m_boundingRadiusA(boundingRadiusA), - m_boundingRadiusB(boundingRadiusB), - m_separatingDistance(0.f) + b3ConvexSeparatingDistanceUtil(b3Scalar boundingRadiusA, b3Scalar boundingRadiusB) + : m_boundingRadiusA(boundingRadiusA), + m_boundingRadiusB(boundingRadiusB), + m_separatingDistance(0.f) { } - b3Scalar getConservativeSeparatingDistance() + b3Scalar getConservativeSeparatingDistance() { return m_separatingDistance; } - void updateSeparatingDistance(const b3Transform& transA,const b3Transform& transB) + void updateSeparatingDistance(const b3Transform& transA, const b3Transform& transB) { const b3Vector3& toPosA = transA.getOrigin(); const b3Vector3& toPosB = transB.getOrigin(); b3Quaternion toOrnA = transA.getRotation(); b3Quaternion toOrnB = transB.getRotation(); - if (m_separatingDistance>0.f) + if (m_separatingDistance > 0.f) { - - - b3Vector3 linVelA,angVelA,linVelB,angVelB; - b3TransformUtil::calculateVelocityQuaternion(m_posA,toPosA,m_ornA,toOrnA,b3Scalar(1.),linVelA,angVelA); - b3TransformUtil::calculateVelocityQuaternion(m_posB,toPosB,m_ornB,toOrnB,b3Scalar(1.),linVelB,angVelB); + b3Vector3 linVelA, angVelA, linVelB, angVelB; + b3TransformUtil::calculateVelocityQuaternion(m_posA, toPosA, m_ornA, toOrnA, b3Scalar(1.), linVelA, angVelA); + b3TransformUtil::calculateVelocityQuaternion(m_posB, toPosB, m_ornB, toOrnB, b3Scalar(1.), linVelB, angVelB); b3Scalar maxAngularProjectedVelocity = angVelA.length() * m_boundingRadiusA + angVelB.length() * m_boundingRadiusB; - b3Vector3 relLinVel = (linVelB-linVelA); + b3Vector3 relLinVel = (linVelB - linVelA); b3Scalar relLinVelocLength = relLinVel.dot(m_separatingNormal); - if (relLinVelocLength<0.f) + if (relLinVelocLength < 0.f) { relLinVelocLength = 0.f; } - - b3Scalar projectedMotion = maxAngularProjectedVelocity +relLinVelocLength; + + b3Scalar projectedMotion = maxAngularProjectedVelocity + relLinVelocLength; m_separatingDistance -= projectedMotion; } - + m_posA = toPosA; m_posB = toPosB; m_ornA = toOrnA; m_ornB = toOrnB; } - void initSeparatingDistance(const b3Vector3& separatingVector,b3Scalar separatingDistance,const b3Transform& transA,const b3Transform& transB) + void initSeparatingDistance(const b3Vector3& separatingVector, b3Scalar separatingDistance, const b3Transform& transA, const b3Transform& transB) { m_separatingDistance = separatingDistance; - if (m_separatingDistance>0.f) + if (m_separatingDistance > 0.f) { m_separatingNormal = separatingVector; - + const b3Vector3& toPosA = transA.getOrigin(); const b3Vector3& toPosB = transB.getOrigin(); b3Quaternion toOrnA = transA.getRotation(); @@ -220,9 +205,6 @@ public: m_ornB = toOrnB; } } - }; - -#endif //B3_TRANSFORM_UTIL_H - +#endif //B3_TRANSFORM_UTIL_H diff --git a/src/Bullet3Common/b3Vector3.cpp b/src/Bullet3Common/b3Vector3.cpp index 5f5ac4ac0..100fb774c 100644 --- a/src/Bullet3Common/b3Vector3.cpp +++ b/src/Bullet3Common/b3Vector3.cpp @@ -14,274 +14,281 @@ This source version has been altered. */ -#if defined (_WIN32) || defined (__i386__) +#if defined(_WIN32) || defined(__i386__) #define B3_USE_SSE_IN_API #endif #include "b3Vector3.h" -#if defined (B3_USE_SSE) || defined (B3_USE_NEON) +#if defined(B3_USE_SSE) || defined(B3_USE_NEON) #ifdef __APPLE__ #include -typedef float float4 __attribute__ ((vector_size(16))); +typedef float float4 __attribute__((vector_size(16))); #else #define float4 __m128 #endif //typedef uint32_t uint4 __attribute__ ((vector_size(16))); - #if defined B3_USE_SSE || defined _WIN32 -#define LOG2_ARRAY_SIZE 6 -#define STACK_ARRAY_COUNT (1UL << LOG2_ARRAY_SIZE) +#define LOG2_ARRAY_SIZE 6 +#define STACK_ARRAY_COUNT (1UL << LOG2_ARRAY_SIZE) #include -long b3_maxdot_large( const float *vv, const float *vec, unsigned long count, float *dotResult ); -long b3_maxdot_large( const float *vv, const float *vec, unsigned long count, float *dotResult ) +long b3_maxdot_large(const float *vv, const float *vec, unsigned long count, float *dotResult); +long b3_maxdot_large(const float *vv, const float *vec, unsigned long count, float *dotResult) { - const float4 *vertices = (const float4*) vv; - static const unsigned char indexTable[16] = {(unsigned char)-1, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 }; - float4 dotMax = b3Assign128( -B3_INFINITY, -B3_INFINITY, -B3_INFINITY, -B3_INFINITY ); - float4 vvec = _mm_loadu_ps( vec ); - float4 vHi = b3CastiTo128f(_mm_shuffle_epi32( b3CastfTo128i( vvec), 0xaa )); /// zzzz - float4 vLo = _mm_movelh_ps( vvec, vvec ); /// xyxy + const float4 *vertices = (const float4 *)vv; + static const unsigned char indexTable[16] = {(unsigned char)-1, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0}; + float4 dotMax = b3Assign128(-B3_INFINITY, -B3_INFINITY, -B3_INFINITY, -B3_INFINITY); + float4 vvec = _mm_loadu_ps(vec); + float4 vHi = b3CastiTo128f(_mm_shuffle_epi32(b3CastfTo128i(vvec), 0xaa)); /// zzzz + float4 vLo = _mm_movelh_ps(vvec, vvec); /// xyxy - long maxIndex = -1L; + long maxIndex = -1L; - size_t segment = 0; - float4 stack_array[ STACK_ARRAY_COUNT ]; + size_t segment = 0; + float4 stack_array[STACK_ARRAY_COUNT]; #if DEBUG - // memset( stack_array, -1, STACK_ARRAY_COUNT * sizeof(stack_array[0]) ); + // memset( stack_array, -1, STACK_ARRAY_COUNT * sizeof(stack_array[0]) ); #endif - size_t index; - float4 max; - // Faster loop without cleanup code for full tiles - for ( segment = 0; segment + STACK_ARRAY_COUNT*4 <= count; segment += STACK_ARRAY_COUNT*4 ) - { - max = dotMax; + size_t index; + float4 max; + // Faster loop without cleanup code for full tiles + for (segment = 0; segment + STACK_ARRAY_COUNT * 4 <= count; segment += STACK_ARRAY_COUNT * 4) + { + max = dotMax; - for( index = 0; index < STACK_ARRAY_COUNT; index+= 4 ) - { // do four dot products at a time. Carefully avoid touching the w element. - float4 v0 = vertices[0]; - float4 v1 = vertices[1]; - float4 v2 = vertices[2]; - float4 v3 = vertices[3]; vertices += 4; + for (index = 0; index < STACK_ARRAY_COUNT; index += 4) + { // do four dot products at a time. Carefully avoid touching the w element. + float4 v0 = vertices[0]; + float4 v1 = vertices[1]; + float4 v2 = vertices[2]; + float4 v3 = vertices[3]; + vertices += 4; - float4 lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - float4 hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - float4 lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - float4 hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + float4 lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + float4 hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + float4 lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + float4 hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 - lo0 = lo0*vLo; - lo1 = lo1*vLo; - float4 z = _mm_shuffle_ps(hi0, hi1, 0x88); - float4 x = _mm_shuffle_ps(lo0, lo1, 0x88); - float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index] = x; - max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + float4 z = _mm_shuffle_ps(hi0, hi1, 0x88); + float4 x = _mm_shuffle_ps(lo0, lo1, 0x88); + float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index] = x; + max = _mm_max_ps(x, max); // control the order here so that max is never NaN even if x is nan - v0 = vertices[0]; - v1 = vertices[1]; - v2 = vertices[2]; - v3 = vertices[3]; vertices += 4; + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; - lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 - lo0 = lo0*vLo; - lo1 = lo1*vLo; - z = _mm_shuffle_ps(hi0, hi1, 0x88); - x = _mm_shuffle_ps(lo0, lo1, 0x88); - y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index+1] = x; - max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 1] = x; + max = _mm_max_ps(x, max); // control the order here so that max is never NaN even if x is nan - v0 = vertices[0]; - v1 = vertices[1]; - v2 = vertices[2]; - v3 = vertices[3]; vertices += 4; + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; - lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 - lo0 = lo0*vLo; - lo1 = lo1*vLo; - z = _mm_shuffle_ps(hi0, hi1, 0x88); - x = _mm_shuffle_ps(lo0, lo1, 0x88); - y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index+2] = x; - max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 2] = x; + max = _mm_max_ps(x, max); // control the order here so that max is never NaN even if x is nan - v0 = vertices[0]; - v1 = vertices[1]; - v2 = vertices[2]; - v3 = vertices[3]; vertices += 4; + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; - lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 - lo0 = lo0*vLo; - lo1 = lo1*vLo; - z = _mm_shuffle_ps(hi0, hi1, 0x88); - x = _mm_shuffle_ps(lo0, lo1, 0x88); - y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index+3] = x; - max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 3] = x; + max = _mm_max_ps(x, max); // control the order here so that max is never NaN even if x is nan - // It is too costly to keep the index of the max here. We will look for it again later. We save a lot of work this way. - } + // It is too costly to keep the index of the max here. We will look for it again later. We save a lot of work this way. + } - // If we found a new max - if( 0xf != _mm_movemask_ps( (float4) _mm_cmpeq_ps(max, dotMax))) - { - // copy the new max across all lanes of our max accumulator - max = _mm_max_ps(max, (float4) _mm_shuffle_ps( max, max, 0x4e)); - max = _mm_max_ps(max, (float4) _mm_shuffle_ps( max, max, 0xb1)); + // If we found a new max + if (0xf != _mm_movemask_ps((float4)_mm_cmpeq_ps(max, dotMax))) + { + // copy the new max across all lanes of our max accumulator + max = _mm_max_ps(max, (float4)_mm_shuffle_ps(max, max, 0x4e)); + max = _mm_max_ps(max, (float4)_mm_shuffle_ps(max, max, 0xb1)); - dotMax = max; + dotMax = max; - // find first occurrence of that max - size_t test; - for( index = 0; 0 == (test=_mm_movemask_ps( _mm_cmpeq_ps( stack_array[index], max))); index++ ) // local_count must be a multiple of 4 - {} - // record where it is. - maxIndex = 4*index + segment + indexTable[test]; - } - } + // find first occurrence of that max + size_t test; + for (index = 0; 0 == (test = _mm_movemask_ps(_mm_cmpeq_ps(stack_array[index], max))); index++) // local_count must be a multiple of 4 + { + } + // record where it is. + maxIndex = 4 * index + segment + indexTable[test]; + } + } - // account for work we've already done - count -= segment; + // account for work we've already done + count -= segment; - // Deal with the last < STACK_ARRAY_COUNT vectors - max = dotMax; - index = 0; + // Deal with the last < STACK_ARRAY_COUNT vectors + max = dotMax; + index = 0; + if (b3Unlikely(count > 16)) + { + for (; index + 4 <= count / 4; index += 4) + { // do four dot products at a time. Carefully avoid touching the w element. + float4 v0 = vertices[0]; + float4 v1 = vertices[1]; + float4 v2 = vertices[2]; + float4 v3 = vertices[3]; + vertices += 4; - if( b3Unlikely( count > 16) ) - { - for( ; index + 4 <= count / 4; index+=4 ) - { // do four dot products at a time. Carefully avoid touching the w element. - float4 v0 = vertices[0]; - float4 v1 = vertices[1]; - float4 v2 = vertices[2]; - float4 v3 = vertices[3]; vertices += 4; + float4 lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + float4 hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + float4 lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + float4 hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 - float4 lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - float4 hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - float4 lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - float4 hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + float4 z = _mm_shuffle_ps(hi0, hi1, 0x88); + float4 x = _mm_shuffle_ps(lo0, lo1, 0x88); + float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index] = x; + max = _mm_max_ps(x, max); // control the order here so that max is never NaN even if x is nan - lo0 = lo0*vLo; - lo1 = lo1*vLo; - float4 z = _mm_shuffle_ps(hi0, hi1, 0x88); - float4 x = _mm_shuffle_ps(lo0, lo1, 0x88); - float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index] = x; - max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; - v0 = vertices[0]; - v1 = vertices[1]; - v2 = vertices[2]; - v3 = vertices[3]; vertices += 4; + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 - lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 1] = x; + max = _mm_max_ps(x, max); // control the order here so that max is never NaN even if x is nan - lo0 = lo0*vLo; - lo1 = lo1*vLo; - z = _mm_shuffle_ps(hi0, hi1, 0x88); - x = _mm_shuffle_ps(lo0, lo1, 0x88); - y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index+1] = x; - max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; - v0 = vertices[0]; - v1 = vertices[1]; - v2 = vertices[2]; - v3 = vertices[3]; vertices += 4; + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 - lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 2] = x; + max = _mm_max_ps(x, max); // control the order here so that max is never NaN even if x is nan - lo0 = lo0*vLo; - lo1 = lo1*vLo; - z = _mm_shuffle_ps(hi0, hi1, 0x88); - x = _mm_shuffle_ps(lo0, lo1, 0x88); - y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index+2] = x; - max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; - v0 = vertices[0]; - v1 = vertices[1]; - v2 = vertices[2]; - v3 = vertices[3]; vertices += 4; + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 - lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 3] = x; + max = _mm_max_ps(x, max); // control the order here so that max is never NaN even if x is nan - lo0 = lo0*vLo; - lo1 = lo1*vLo; - z = _mm_shuffle_ps(hi0, hi1, 0x88); - x = _mm_shuffle_ps(lo0, lo1, 0x88); - y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index+3] = x; - max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan + // It is too costly to keep the index of the max here. We will look for it again later. We save a lot of work this way. + } + } - // It is too costly to keep the index of the max here. We will look for it again later. We save a lot of work this way. - } - } - - size_t localCount = (count & -4L) - 4*index; - if( localCount ) - { + size_t localCount = (count & -4L) - 4 * index; + if (localCount) + { #ifdef __APPLE__ - float4 t0, t1, t2, t3, t4; - float4 * sap = &stack_array[index + localCount / 4]; - vertices += localCount; // counter the offset - size_t byteIndex = -(localCount) * sizeof(float); - //AT&T Code style assembly - asm volatile - ( ".align 4 \n\ + float4 t0, t1, t2, t3, t4; + float4 *sap = &stack_array[index + localCount / 4]; + vertices += localCount; // counter the offset + size_t byteIndex = -(localCount) * sizeof(float); + //AT&T Code style assembly + asm volatile( + ".align 4 \n\ 0: movaps %[max], %[t2] // move max out of the way to avoid propagating NaNs in max \n\ movaps (%[vertices], %[byteIndex], 4), %[t0] // vertices[0] \n\ movaps 16(%[vertices], %[byteIndex], 4), %[t1] // vertices[1] \n\ @@ -307,369 +314,375 @@ long b3_maxdot_large( const float *vv, const float *vec, unsigned long count, fl add $16, %[byteIndex] // advance loop counter\n\ jnz 0b \n\ " - : [max] "+x" (max), [t0] "=&x" (t0), [t1] "=&x" (t1), [t2] "=&x" (t2), [t3] "=&x" (t3), [t4] "=&x" (t4), [byteIndex] "+r" (byteIndex) - : [vLo] "x" (vLo), [vHi] "x" (vHi), [vertices] "r" (vertices), [sap] "r" (sap) - : "memory", "cc" - ); - index += localCount/4; + : [max] "+x"(max), [t0] "=&x"(t0), [t1] "=&x"(t1), [t2] "=&x"(t2), [t3] "=&x"(t3), [t4] "=&x"(t4), [byteIndex] "+r"(byteIndex) + : [vLo] "x"(vLo), [vHi] "x"(vHi), [vertices] "r"(vertices), [sap] "r"(sap) + : "memory", "cc"); + index += localCount / 4; #else - { - for( unsigned int i=0; i 16)) + { + for (; index + 4 <= count / 4; index += 4) + { // do four dot products at a time. Carefully avoid touching the w element. + float4 v0 = vertices[0]; + float4 v1 = vertices[1]; + float4 v2 = vertices[2]; + float4 v3 = vertices[3]; + vertices += 4; - if(b3Unlikely( count > 16) ) - { - for( ; index + 4 <= count / 4; index+=4 ) - { // do four dot products at a time. Carefully avoid touching the w element. - float4 v0 = vertices[0]; - float4 v1 = vertices[1]; - float4 v2 = vertices[2]; - float4 v3 = vertices[3]; vertices += 4; + float4 lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + float4 hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + float4 lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + float4 hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 - float4 lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - float4 hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - float4 lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - float4 hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + float4 z = _mm_shuffle_ps(hi0, hi1, 0x88); + float4 x = _mm_shuffle_ps(lo0, lo1, 0x88); + float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index] = x; + min = _mm_min_ps(x, min); // control the order here so that min is never NaN even if x is nan - lo0 = lo0*vLo; - lo1 = lo1*vLo; - float4 z = _mm_shuffle_ps(hi0, hi1, 0x88); - float4 x = _mm_shuffle_ps(lo0, lo1, 0x88); - float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index] = x; - min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; - v0 = vertices[0]; - v1 = vertices[1]; - v2 = vertices[2]; - v3 = vertices[3]; vertices += 4; + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 - lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 1] = x; + min = _mm_min_ps(x, min); // control the order here so that min is never NaN even if x is nan - lo0 = lo0*vLo; - lo1 = lo1*vLo; - z = _mm_shuffle_ps(hi0, hi1, 0x88); - x = _mm_shuffle_ps(lo0, lo1, 0x88); - y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index+1] = x; - min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; - v0 = vertices[0]; - v1 = vertices[1]; - v2 = vertices[2]; - v3 = vertices[3]; vertices += 4; + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 - lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 2] = x; + min = _mm_min_ps(x, min); // control the order here so that min is never NaN even if x is nan - lo0 = lo0*vLo; - lo1 = lo1*vLo; - z = _mm_shuffle_ps(hi0, hi1, 0x88); - x = _mm_shuffle_ps(lo0, lo1, 0x88); - y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index+2] = x; - min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; - v0 = vertices[0]; - v1 = vertices[1]; - v2 = vertices[2]; - v3 = vertices[3]; vertices += 4; + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 - lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 - - lo0 = lo0*vLo; - lo1 = lo1*vLo; - z = _mm_shuffle_ps(hi0, hi1, 0x88); - x = _mm_shuffle_ps(lo0, lo1, 0x88); - y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index+3] = x; - min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan - - // It is too costly to keep the index of the min here. We will look for it again later. We save a lot of work this way. - } - } - - size_t localCount = (count & -4L) - 4*index; - if( localCount ) - { + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 3] = x; + min = _mm_min_ps(x, min); // control the order here so that min is never NaN even if x is nan + // It is too costly to keep the index of the min here. We will look for it again later. We save a lot of work this way. + } + } + size_t localCount = (count & -4L) - 4 * index; + if (localCount) + { #ifdef __APPLE__ - vertices += localCount; // counter the offset - float4 t0, t1, t2, t3, t4; - size_t byteIndex = -(localCount) * sizeof(float); - float4 * sap = &stack_array[index + localCount / 4]; + vertices += localCount; // counter the offset + float4 t0, t1, t2, t3, t4; + size_t byteIndex = -(localCount) * sizeof(float); + float4 *sap = &stack_array[index + localCount / 4]; - asm volatile - ( ".align 4 \n\ + asm volatile( + ".align 4 \n\ 0: movaps %[min], %[t2] // move min out of the way to avoid propagating NaNs in min \n\ movaps (%[vertices], %[byteIndex], 4), %[t0] // vertices[0] \n\ movaps 16(%[vertices], %[byteIndex], 4), %[t1] // vertices[1] \n\ @@ -695,937 +708,930 @@ long b3_mindot_large( const float *vv, const float *vec, unsigned long count, fl add $16, %[byteIndex] // advance loop counter\n\ jnz 0b \n\ " - : [min] "+x" (min), [t0] "=&x" (t0), [t1] "=&x" (t1), [t2] "=&x" (t2), [t3] "=&x" (t3), [t4] "=&x" (t4), [byteIndex] "+r" (byteIndex) - : [vLo] "x" (vLo), [vHi] "x" (vHi), [vertices] "r" (vertices), [sap] "r" (sap) - : "memory", "cc" - ); - index += localCount/4; + : [min] "+x"(min), [t0] "=&x"(t0), [t1] "=&x"(t1), [t2] "=&x"(t2), [t3] "=&x"(t3), [t4] "=&x"(t4), [byteIndex] "+r"(byteIndex) + : [vLo] "x"(vLo), [vHi] "x"(vHi), [vertices] "r"(vertices), [sap] "r"(sap) + : "memory", "cc"); + index += localCount / 4; #else - { - for( unsigned int i=0; i +static long b3_maxdot_large_v0(const float *vv, const float *vec, unsigned long count, float *dotResult); +static long b3_maxdot_large_v1(const float *vv, const float *vec, unsigned long count, float *dotResult); +static long b3_maxdot_large_sel(const float *vv, const float *vec, unsigned long count, float *dotResult); +static long b3_mindot_large_v0(const float *vv, const float *vec, unsigned long count, float *dotResult); +static long b3_mindot_large_v1(const float *vv, const float *vec, unsigned long count, float *dotResult); +static long b3_mindot_large_sel(const float *vv, const float *vec, unsigned long count, float *dotResult); -static long b3_maxdot_large_v0( const float *vv, const float *vec, unsigned long count, float *dotResult ); -static long b3_maxdot_large_v1( const float *vv, const float *vec, unsigned long count, float *dotResult ); -static long b3_maxdot_large_sel( const float *vv, const float *vec, unsigned long count, float *dotResult ); -static long b3_mindot_large_v0( const float *vv, const float *vec, unsigned long count, float *dotResult ); -static long b3_mindot_large_v1( const float *vv, const float *vec, unsigned long count, float *dotResult ); -static long b3_mindot_large_sel( const float *vv, const float *vec, unsigned long count, float *dotResult ); +long (*b3_maxdot_large)(const float *vv, const float *vec, unsigned long count, float *dotResult) = b3_maxdot_large_sel; +long (*b3_mindot_large)(const float *vv, const float *vec, unsigned long count, float *dotResult) = b3_mindot_large_sel; -long (*b3_maxdot_large)( const float *vv, const float *vec, unsigned long count, float *dotResult ) = b3_maxdot_large_sel; -long (*b3_mindot_large)( const float *vv, const float *vec, unsigned long count, float *dotResult ) = b3_mindot_large_sel; - -extern "C" {int _get_cpu_capabilities( void );} - -static long b3_maxdot_large_sel( const float *vv, const float *vec, unsigned long count, float *dotResult ) +extern "C" { - if( _get_cpu_capabilities() & 0x2000 ) - b3_maxdot_large = _maxdot_large_v1; - else - b3_maxdot_large = _maxdot_large_v0; - - return b3_maxdot_large(vv, vec, count, dotResult); + int _get_cpu_capabilities(void); } -static long b3_mindot_large_sel( const float *vv, const float *vec, unsigned long count, float *dotResult ) +static long b3_maxdot_large_sel(const float *vv, const float *vec, unsigned long count, float *dotResult) { - if( _get_cpu_capabilities() & 0x2000 ) - b3_mindot_large = _mindot_large_v1; - else - b3_mindot_large = _mindot_large_v0; + if (_get_cpu_capabilities() & 0x2000) + b3_maxdot_large = _maxdot_large_v1; + else + b3_maxdot_large = _maxdot_large_v0; - return b3_mindot_large(vv, vec, count, dotResult); + return b3_maxdot_large(vv, vec, count, dotResult); } - - -#define vld1q_f32_aligned_postincrement( _ptr ) ({ float32x4_t _r; asm( "vld1.f32 {%0}, [%1, :128]!\n" : "=w" (_r), "+r" (_ptr) ); /*return*/ _r; }) - - -long b3_maxdot_large_v0( const float *vv, const float *vec, unsigned long count, float *dotResult ) +static long b3_mindot_large_sel(const float *vv, const float *vec, unsigned long count, float *dotResult) { - unsigned long i = 0; - float32x4_t vvec = vld1q_f32_aligned_postincrement( vec ); - float32x2_t vLo = vget_low_f32(vvec); - float32x2_t vHi = vdup_lane_f32(vget_high_f32(vvec), 0); - float32x2_t dotMaxLo = (float32x2_t) { -B3_INFINITY, -B3_INFINITY }; - float32x2_t dotMaxHi = (float32x2_t) { -B3_INFINITY, -B3_INFINITY }; - uint32x2_t indexLo = (uint32x2_t) {0, 1}; - uint32x2_t indexHi = (uint32x2_t) {2, 3}; - uint32x2_t iLo = (uint32x2_t) {-1, -1}; - uint32x2_t iHi = (uint32x2_t) {-1, -1}; - const uint32x2_t four = (uint32x2_t) {4,4}; + if (_get_cpu_capabilities() & 0x2000) + b3_mindot_large = _mindot_large_v1; + else + b3_mindot_large = _mindot_large_v0; - for( ; i+8 <= count; i+= 8 ) - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); - - float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); - float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); - float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo); - float32x2_t xy3 = vmul_f32( vget_low_f32(v3), vLo); - - float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x2x2_t z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3)); - float32x2_t zLo = vmul_f32( z0.val[0], vHi); - float32x2_t zHi = vmul_f32( z1.val[0], vHi); - - float32x2_t rLo = vpadd_f32( xy0, xy1); - float32x2_t rHi = vpadd_f32( xy2, xy3); - rLo = vadd_f32(rLo, zLo); - rHi = vadd_f32(rHi, zHi); - - uint32x2_t maskLo = vcgt_f32( rLo, dotMaxLo ); - uint32x2_t maskHi = vcgt_f32( rHi, dotMaxHi ); - dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo); - dotMaxHi = vbsl_f32( maskHi, rHi, dotMaxHi); - iLo = vbsl_u32(maskLo, indexLo, iLo); - iHi = vbsl_u32(maskHi, indexHi, iHi); - indexLo = vadd_u32(indexLo, four); - indexHi = vadd_u32(indexHi, four); - - v0 = vld1q_f32_aligned_postincrement( vv ); - v1 = vld1q_f32_aligned_postincrement( vv ); - v2 = vld1q_f32_aligned_postincrement( vv ); - v3 = vld1q_f32_aligned_postincrement( vv ); - - xy0 = vmul_f32( vget_low_f32(v0), vLo); - xy1 = vmul_f32( vget_low_f32(v1), vLo); - xy2 = vmul_f32( vget_low_f32(v2), vLo); - xy3 = vmul_f32( vget_low_f32(v3), vLo); - - z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); - z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3)); - zLo = vmul_f32( z0.val[0], vHi); - zHi = vmul_f32( z1.val[0], vHi); - - rLo = vpadd_f32( xy0, xy1); - rHi = vpadd_f32( xy2, xy3); - rLo = vadd_f32(rLo, zLo); - rHi = vadd_f32(rHi, zHi); - - maskLo = vcgt_f32( rLo, dotMaxLo ); - maskHi = vcgt_f32( rHi, dotMaxHi ); - dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo); - dotMaxHi = vbsl_f32( maskHi, rHi, dotMaxHi); - iLo = vbsl_u32(maskLo, indexLo, iLo); - iHi = vbsl_u32(maskHi, indexHi, iHi); - indexLo = vadd_u32(indexLo, four); - indexHi = vadd_u32(indexHi, four); - } - - for( ; i+4 <= count; i+= 4 ) - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); - - float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); - float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); - float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo); - float32x2_t xy3 = vmul_f32( vget_low_f32(v3), vLo); - - float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x2x2_t z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3)); - float32x2_t zLo = vmul_f32( z0.val[0], vHi); - float32x2_t zHi = vmul_f32( z1.val[0], vHi); - - float32x2_t rLo = vpadd_f32( xy0, xy1); - float32x2_t rHi = vpadd_f32( xy2, xy3); - rLo = vadd_f32(rLo, zLo); - rHi = vadd_f32(rHi, zHi); - - uint32x2_t maskLo = vcgt_f32( rLo, dotMaxLo ); - uint32x2_t maskHi = vcgt_f32( rHi, dotMaxHi ); - dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo); - dotMaxHi = vbsl_f32( maskHi, rHi, dotMaxHi); - iLo = vbsl_u32(maskLo, indexLo, iLo); - iHi = vbsl_u32(maskHi, indexHi, iHi); - indexLo = vadd_u32(indexLo, four); - indexHi = vadd_u32(indexHi, four); - } - - switch( count & 3 ) - { - case 3: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - - float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); - float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); - float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo); - - float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x2_t zLo = vmul_f32( z0.val[0], vHi); - float32x2_t zHi = vmul_f32( vdup_lane_f32(vget_high_f32(v2), 0), vHi); - - float32x2_t rLo = vpadd_f32( xy0, xy1); - float32x2_t rHi = vpadd_f32( xy2, xy2); - rLo = vadd_f32(rLo, zLo); - rHi = vadd_f32(rHi, zHi); - - uint32x2_t maskLo = vcgt_f32( rLo, dotMaxLo ); - uint32x2_t maskHi = vcgt_f32( rHi, dotMaxHi ); - dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo); - dotMaxHi = vbsl_f32( maskHi, rHi, dotMaxHi); - iLo = vbsl_u32(maskLo, indexLo, iLo); - iHi = vbsl_u32(maskHi, indexHi, iHi); - } - break; - case 2: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - - float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); - float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); - - float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x2_t zLo = vmul_f32( z0.val[0], vHi); - - float32x2_t rLo = vpadd_f32( xy0, xy1); - rLo = vadd_f32(rLo, zLo); - - uint32x2_t maskLo = vcgt_f32( rLo, dotMaxLo ); - dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo); - iLo = vbsl_u32(maskLo, indexLo, iLo); - } - break; - case 1: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); - float32x2_t z0 = vdup_lane_f32(vget_high_f32(v0), 0); - float32x2_t zLo = vmul_f32( z0, vHi); - float32x2_t rLo = vpadd_f32( xy0, xy0); - rLo = vadd_f32(rLo, zLo); - uint32x2_t maskLo = vcgt_f32( rLo, dotMaxLo ); - dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo); - iLo = vbsl_u32(maskLo, indexLo, iLo); - } - break; - - default: - break; - } - - // select best answer between hi and lo results - uint32x2_t mask = vcgt_f32( dotMaxHi, dotMaxLo ); - dotMaxLo = vbsl_f32(mask, dotMaxHi, dotMaxLo); - iLo = vbsl_u32(mask, iHi, iLo); - - // select best answer between even and odd results - dotMaxHi = vdup_lane_f32(dotMaxLo, 1); - iHi = vdup_lane_u32(iLo, 1); - mask = vcgt_f32( dotMaxHi, dotMaxLo ); - dotMaxLo = vbsl_f32(mask, dotMaxHi, dotMaxLo); - iLo = vbsl_u32(mask, iHi, iLo); - - *dotResult = vget_lane_f32( dotMaxLo, 0); - return vget_lane_u32(iLo, 0); + return b3_mindot_large(vv, vec, count, dotResult); } +#define vld1q_f32_aligned_postincrement(_ptr) ({ float32x4_t _r; asm( "vld1.f32 {%0}, [%1, :128]!\n" : "=w" (_r), "+r" (_ptr) ); /*return*/ _r; }) -long b3_maxdot_large_v1( const float *vv, const float *vec, unsigned long count, float *dotResult ) +long b3_maxdot_large_v0(const float *vv, const float *vec, unsigned long count, float *dotResult) { - float32x4_t vvec = vld1q_f32_aligned_postincrement( vec ); - float32x4_t vLo = vcombine_f32(vget_low_f32(vvec), vget_low_f32(vvec)); - float32x4_t vHi = vdupq_lane_f32(vget_high_f32(vvec), 0); - const uint32x4_t four = (uint32x4_t){ 4, 4, 4, 4 }; - uint32x4_t local_index = (uint32x4_t) {0, 1, 2, 3}; - uint32x4_t index = (uint32x4_t) { -1, -1, -1, -1 }; - float32x4_t maxDot = (float32x4_t) { -B3_INFINITY, -B3_INFINITY, -B3_INFINITY, -B3_INFINITY }; + unsigned long i = 0; + float32x4_t vvec = vld1q_f32_aligned_postincrement(vec); + float32x2_t vLo = vget_low_f32(vvec); + float32x2_t vHi = vdup_lane_f32(vget_high_f32(vvec), 0); + float32x2_t dotMaxLo = (float32x2_t){-B3_INFINITY, -B3_INFINITY}; + float32x2_t dotMaxHi = (float32x2_t){-B3_INFINITY, -B3_INFINITY}; + uint32x2_t indexLo = (uint32x2_t){0, 1}; + uint32x2_t indexHi = (uint32x2_t){2, 3}; + uint32x2_t iLo = (uint32x2_t){-1, -1}; + uint32x2_t iHi = (uint32x2_t){-1, -1}; + const uint32x2_t four = (uint32x2_t){4, 4}; - unsigned long i = 0; - for( ; i + 8 <= count; i += 8 ) - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); + for (; i + 8 <= count; i += 8) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v3 = vld1q_f32_aligned_postincrement(vv); - // the next two lines should resolve to a single vswp d, d - float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); - float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3)); - // the next two lines should resolve to a single vswp d, d - float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3)); + float32x2_t xy0 = vmul_f32(vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32(vget_low_f32(v1), vLo); + float32x2_t xy2 = vmul_f32(vget_low_f32(v2), vLo); + float32x2_t xy3 = vmul_f32(vget_low_f32(v3), vLo); - xy0 = vmulq_f32(xy0, vLo); - xy1 = vmulq_f32(xy1, vLo); + float32x2x2_t z0 = vtrn_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x2x2_t z1 = vtrn_f32(vget_high_f32(v2), vget_high_f32(v3)); + float32x2_t zLo = vmul_f32(z0.val[0], vHi); + float32x2_t zHi = vmul_f32(z1.val[0], vHi); - float32x4x2_t zb = vuzpq_f32( z0, z1); - float32x4_t z = vmulq_f32( zb.val[0], vHi); - float32x4x2_t xy = vuzpq_f32( xy0, xy1); - float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); + float32x2_t rLo = vpadd_f32(xy0, xy1); + float32x2_t rHi = vpadd_f32(xy2, xy3); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); - uint32x4_t mask = vcgtq_f32(x, maxDot); - maxDot = vbslq_f32( mask, x, maxDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); + uint32x2_t maskLo = vcgt_f32(rLo, dotMaxLo); + uint32x2_t maskHi = vcgt_f32(rHi, dotMaxHi); + dotMaxLo = vbsl_f32(maskLo, rLo, dotMaxLo); + dotMaxHi = vbsl_f32(maskHi, rHi, dotMaxHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + indexLo = vadd_u32(indexLo, four); + indexHi = vadd_u32(indexHi, four); - v0 = vld1q_f32_aligned_postincrement( vv ); - v1 = vld1q_f32_aligned_postincrement( vv ); - v2 = vld1q_f32_aligned_postincrement( vv ); - v3 = vld1q_f32_aligned_postincrement( vv ); + v0 = vld1q_f32_aligned_postincrement(vv); + v1 = vld1q_f32_aligned_postincrement(vv); + v2 = vld1q_f32_aligned_postincrement(vv); + v3 = vld1q_f32_aligned_postincrement(vv); - // the next two lines should resolve to a single vswp d, d - xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); - xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3)); - // the next two lines should resolve to a single vswp d, d - z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); - z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3)); + xy0 = vmul_f32(vget_low_f32(v0), vLo); + xy1 = vmul_f32(vget_low_f32(v1), vLo); + xy2 = vmul_f32(vget_low_f32(v2), vLo); + xy3 = vmul_f32(vget_low_f32(v3), vLo); - xy0 = vmulq_f32(xy0, vLo); - xy1 = vmulq_f32(xy1, vLo); + z0 = vtrn_f32(vget_high_f32(v0), vget_high_f32(v1)); + z1 = vtrn_f32(vget_high_f32(v2), vget_high_f32(v3)); + zLo = vmul_f32(z0.val[0], vHi); + zHi = vmul_f32(z1.val[0], vHi); - zb = vuzpq_f32( z0, z1); - z = vmulq_f32( zb.val[0], vHi); - xy = vuzpq_f32( xy0, xy1); - x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); + rLo = vpadd_f32(xy0, xy1); + rHi = vpadd_f32(xy2, xy3); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); - mask = vcgtq_f32(x, maxDot); - maxDot = vbslq_f32( mask, x, maxDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - } + maskLo = vcgt_f32(rLo, dotMaxLo); + maskHi = vcgt_f32(rHi, dotMaxHi); + dotMaxLo = vbsl_f32(maskLo, rLo, dotMaxLo); + dotMaxHi = vbsl_f32(maskHi, rHi, dotMaxHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + indexLo = vadd_u32(indexLo, four); + indexHi = vadd_u32(indexHi, four); + } - for( ; i + 4 <= count; i += 4 ) - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); + for (; i + 4 <= count; i += 4) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v3 = vld1q_f32_aligned_postincrement(vv); - // the next two lines should resolve to a single vswp d, d - float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); - float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3)); - // the next two lines should resolve to a single vswp d, d - float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3)); + float32x2_t xy0 = vmul_f32(vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32(vget_low_f32(v1), vLo); + float32x2_t xy2 = vmul_f32(vget_low_f32(v2), vLo); + float32x2_t xy3 = vmul_f32(vget_low_f32(v3), vLo); - xy0 = vmulq_f32(xy0, vLo); - xy1 = vmulq_f32(xy1, vLo); + float32x2x2_t z0 = vtrn_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x2x2_t z1 = vtrn_f32(vget_high_f32(v2), vget_high_f32(v3)); + float32x2_t zLo = vmul_f32(z0.val[0], vHi); + float32x2_t zHi = vmul_f32(z1.val[0], vHi); - float32x4x2_t zb = vuzpq_f32( z0, z1); - float32x4_t z = vmulq_f32( zb.val[0], vHi); - float32x4x2_t xy = vuzpq_f32( xy0, xy1); - float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); + float32x2_t rLo = vpadd_f32(xy0, xy1); + float32x2_t rHi = vpadd_f32(xy2, xy3); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); - uint32x4_t mask = vcgtq_f32(x, maxDot); - maxDot = vbslq_f32( mask, x, maxDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - } + uint32x2_t maskLo = vcgt_f32(rLo, dotMaxLo); + uint32x2_t maskHi = vcgt_f32(rHi, dotMaxHi); + dotMaxLo = vbsl_f32(maskLo, rLo, dotMaxLo); + dotMaxHi = vbsl_f32(maskHi, rHi, dotMaxHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + indexLo = vadd_u32(indexLo, four); + indexHi = vadd_u32(indexHi, four); + } - switch (count & 3) { - case 3: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); + switch (count & 3) + { + case 3: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); - // the next two lines should resolve to a single vswp d, d - float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); - float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v2)); - // the next two lines should resolve to a single vswp d, d - float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v2)); + float32x2_t xy0 = vmul_f32(vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32(vget_low_f32(v1), vLo); + float32x2_t xy2 = vmul_f32(vget_low_f32(v2), vLo); - xy0 = vmulq_f32(xy0, vLo); - xy1 = vmulq_f32(xy1, vLo); + float32x2x2_t z0 = vtrn_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x2_t zLo = vmul_f32(z0.val[0], vHi); + float32x2_t zHi = vmul_f32(vdup_lane_f32(vget_high_f32(v2), 0), vHi); - float32x4x2_t zb = vuzpq_f32( z0, z1); - float32x4_t z = vmulq_f32( zb.val[0], vHi); - float32x4x2_t xy = vuzpq_f32( xy0, xy1); - float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); + float32x2_t rLo = vpadd_f32(xy0, xy1); + float32x2_t rHi = vpadd_f32(xy2, xy2); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); - uint32x4_t mask = vcgtq_f32(x, maxDot); - maxDot = vbslq_f32( mask, x, maxDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - } - break; + uint32x2_t maskLo = vcgt_f32(rLo, dotMaxLo); + uint32x2_t maskHi = vcgt_f32(rHi, dotMaxHi); + dotMaxLo = vbsl_f32(maskLo, rLo, dotMaxLo); + dotMaxHi = vbsl_f32(maskHi, rHi, dotMaxHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + } + break; + case 2: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); - case 2: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); + float32x2_t xy0 = vmul_f32(vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32(vget_low_f32(v1), vLo); - // the next two lines should resolve to a single vswp d, d - float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); - // the next two lines should resolve to a single vswp d, d - float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); + float32x2x2_t z0 = vtrn_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x2_t zLo = vmul_f32(z0.val[0], vHi); - xy0 = vmulq_f32(xy0, vLo); + float32x2_t rLo = vpadd_f32(xy0, xy1); + rLo = vadd_f32(rLo, zLo); - float32x4x2_t zb = vuzpq_f32( z0, z0); - float32x4_t z = vmulq_f32( zb.val[0], vHi); - float32x4x2_t xy = vuzpq_f32( xy0, xy0); - float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); + uint32x2_t maskLo = vcgt_f32(rLo, dotMaxLo); + dotMaxLo = vbsl_f32(maskLo, rLo, dotMaxLo); + iLo = vbsl_u32(maskLo, indexLo, iLo); + } + break; + case 1: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x2_t xy0 = vmul_f32(vget_low_f32(v0), vLo); + float32x2_t z0 = vdup_lane_f32(vget_high_f32(v0), 0); + float32x2_t zLo = vmul_f32(z0, vHi); + float32x2_t rLo = vpadd_f32(xy0, xy0); + rLo = vadd_f32(rLo, zLo); + uint32x2_t maskLo = vcgt_f32(rLo, dotMaxLo); + dotMaxLo = vbsl_f32(maskLo, rLo, dotMaxLo); + iLo = vbsl_u32(maskLo, indexLo, iLo); + } + break; - uint32x4_t mask = vcgtq_f32(x, maxDot); - maxDot = vbslq_f32( mask, x, maxDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - } - break; + default: + break; + } - case 1: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + // select best answer between hi and lo results + uint32x2_t mask = vcgt_f32(dotMaxHi, dotMaxLo); + dotMaxLo = vbsl_f32(mask, dotMaxHi, dotMaxLo); + iLo = vbsl_u32(mask, iHi, iLo); - // the next two lines should resolve to a single vswp d, d - float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v0)); - // the next two lines should resolve to a single vswp d, d - float32x4_t z = vdupq_lane_f32(vget_high_f32(v0), 0); - - xy0 = vmulq_f32(xy0, vLo); - - z = vmulq_f32( z, vHi); - float32x4x2_t xy = vuzpq_f32( xy0, xy0); - float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); - - uint32x4_t mask = vcgtq_f32(x, maxDot); - maxDot = vbslq_f32( mask, x, maxDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - } - break; - - default: - break; - } - - - // select best answer between hi and lo results - uint32x2_t mask = vcgt_f32( vget_high_f32(maxDot), vget_low_f32(maxDot)); - float32x2_t maxDot2 = vbsl_f32(mask, vget_high_f32(maxDot), vget_low_f32(maxDot)); - uint32x2_t index2 = vbsl_u32(mask, vget_high_u32(index), vget_low_u32(index)); - - // select best answer between even and odd results - float32x2_t maxDotO = vdup_lane_f32(maxDot2, 1); - uint32x2_t indexHi = vdup_lane_u32(index2, 1); - mask = vcgt_f32( maxDotO, maxDot2 ); - maxDot2 = vbsl_f32(mask, maxDotO, maxDot2); - index2 = vbsl_u32(mask, indexHi, index2); - - *dotResult = vget_lane_f32( maxDot2, 0); - return vget_lane_u32(index2, 0); + // select best answer between even and odd results + dotMaxHi = vdup_lane_f32(dotMaxLo, 1); + iHi = vdup_lane_u32(iLo, 1); + mask = vcgt_f32(dotMaxHi, dotMaxLo); + dotMaxLo = vbsl_f32(mask, dotMaxHi, dotMaxLo); + iLo = vbsl_u32(mask, iHi, iLo); + *dotResult = vget_lane_f32(dotMaxLo, 0); + return vget_lane_u32(iLo, 0); } -long b3_mindot_large_v0( const float *vv, const float *vec, unsigned long count, float *dotResult ) +long b3_maxdot_large_v1(const float *vv, const float *vec, unsigned long count, float *dotResult) { - unsigned long i = 0; - float32x4_t vvec = vld1q_f32_aligned_postincrement( vec ); - float32x2_t vLo = vget_low_f32(vvec); - float32x2_t vHi = vdup_lane_f32(vget_high_f32(vvec), 0); - float32x2_t dotMinLo = (float32x2_t) { B3_INFINITY, B3_INFINITY }; - float32x2_t dotMinHi = (float32x2_t) { B3_INFINITY, B3_INFINITY }; - uint32x2_t indexLo = (uint32x2_t) {0, 1}; - uint32x2_t indexHi = (uint32x2_t) {2, 3}; - uint32x2_t iLo = (uint32x2_t) {-1, -1}; - uint32x2_t iHi = (uint32x2_t) {-1, -1}; - const uint32x2_t four = (uint32x2_t) {4,4}; + float32x4_t vvec = vld1q_f32_aligned_postincrement(vec); + float32x4_t vLo = vcombine_f32(vget_low_f32(vvec), vget_low_f32(vvec)); + float32x4_t vHi = vdupq_lane_f32(vget_high_f32(vvec), 0); + const uint32x4_t four = (uint32x4_t){4, 4, 4, 4}; + uint32x4_t local_index = (uint32x4_t){0, 1, 2, 3}; + uint32x4_t index = (uint32x4_t){-1, -1, -1, -1}; + float32x4_t maxDot = (float32x4_t){-B3_INFINITY, -B3_INFINITY, -B3_INFINITY, -B3_INFINITY}; - for( ; i+8 <= count; i+= 8 ) - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); + unsigned long i = 0; + for (; i + 8 <= count; i += 8) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v3 = vld1q_f32_aligned_postincrement(vv); - float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); - float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); - float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo); - float32x2_t xy3 = vmul_f32( vget_low_f32(v3), vLo); + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v1)); + float32x4_t xy1 = vcombine_f32(vget_low_f32(v2), vget_low_f32(v3)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x4_t z1 = vcombine_f32(vget_high_f32(v2), vget_high_f32(v3)); - float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x2x2_t z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3)); - float32x2_t zLo = vmul_f32( z0.val[0], vHi); - float32x2_t zHi = vmul_f32( z1.val[0], vHi); + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); - float32x2_t rLo = vpadd_f32( xy0, xy1); - float32x2_t rHi = vpadd_f32( xy2, xy3); - rLo = vadd_f32(rLo, zLo); - rHi = vadd_f32(rHi, zHi); + float32x4x2_t zb = vuzpq_f32(z0, z1); + float32x4_t z = vmulq_f32(zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32(xy0, xy1); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); - uint32x2_t maskLo = vclt_f32( rLo, dotMinLo ); - uint32x2_t maskHi = vclt_f32( rHi, dotMinHi ); - dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo); - dotMinHi = vbsl_f32( maskHi, rHi, dotMinHi); - iLo = vbsl_u32(maskLo, indexLo, iLo); - iHi = vbsl_u32(maskHi, indexHi, iHi); - indexLo = vadd_u32(indexLo, four); - indexHi = vadd_u32(indexHi, four); + uint32x4_t mask = vcgtq_f32(x, maxDot); + maxDot = vbslq_f32(mask, x, maxDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); - v0 = vld1q_f32_aligned_postincrement( vv ); - v1 = vld1q_f32_aligned_postincrement( vv ); - v2 = vld1q_f32_aligned_postincrement( vv ); - v3 = vld1q_f32_aligned_postincrement( vv ); + v0 = vld1q_f32_aligned_postincrement(vv); + v1 = vld1q_f32_aligned_postincrement(vv); + v2 = vld1q_f32_aligned_postincrement(vv); + v3 = vld1q_f32_aligned_postincrement(vv); - xy0 = vmul_f32( vget_low_f32(v0), vLo); - xy1 = vmul_f32( vget_low_f32(v1), vLo); - xy2 = vmul_f32( vget_low_f32(v2), vLo); - xy3 = vmul_f32( vget_low_f32(v3), vLo); + // the next two lines should resolve to a single vswp d, d + xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v1)); + xy1 = vcombine_f32(vget_low_f32(v2), vget_low_f32(v3)); + // the next two lines should resolve to a single vswp d, d + z0 = vcombine_f32(vget_high_f32(v0), vget_high_f32(v1)); + z1 = vcombine_f32(vget_high_f32(v2), vget_high_f32(v3)); - z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); - z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3)); - zLo = vmul_f32( z0.val[0], vHi); - zHi = vmul_f32( z1.val[0], vHi); + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); - rLo = vpadd_f32( xy0, xy1); - rHi = vpadd_f32( xy2, xy3); - rLo = vadd_f32(rLo, zLo); - rHi = vadd_f32(rHi, zHi); + zb = vuzpq_f32(z0, z1); + z = vmulq_f32(zb.val[0], vHi); + xy = vuzpq_f32(xy0, xy1); + x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); - maskLo = vclt_f32( rLo, dotMinLo ); - maskHi = vclt_f32( rHi, dotMinHi ); - dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo); - dotMinHi = vbsl_f32( maskHi, rHi, dotMinHi); - iLo = vbsl_u32(maskLo, indexLo, iLo); - iHi = vbsl_u32(maskHi, indexHi, iHi); - indexLo = vadd_u32(indexLo, four); - indexHi = vadd_u32(indexHi, four); - } + mask = vcgtq_f32(x, maxDot); + maxDot = vbslq_f32(mask, x, maxDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } - for( ; i+4 <= count; i+= 4 ) - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); + for (; i + 4 <= count; i += 4) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v3 = vld1q_f32_aligned_postincrement(vv); - float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); - float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); - float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo); - float32x2_t xy3 = vmul_f32( vget_low_f32(v3), vLo); + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v1)); + float32x4_t xy1 = vcombine_f32(vget_low_f32(v2), vget_low_f32(v3)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x4_t z1 = vcombine_f32(vget_high_f32(v2), vget_high_f32(v3)); - float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x2x2_t z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3)); - float32x2_t zLo = vmul_f32( z0.val[0], vHi); - float32x2_t zHi = vmul_f32( z1.val[0], vHi); + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); - float32x2_t rLo = vpadd_f32( xy0, xy1); - float32x2_t rHi = vpadd_f32( xy2, xy3); - rLo = vadd_f32(rLo, zLo); - rHi = vadd_f32(rHi, zHi); + float32x4x2_t zb = vuzpq_f32(z0, z1); + float32x4_t z = vmulq_f32(zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32(xy0, xy1); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); - uint32x2_t maskLo = vclt_f32( rLo, dotMinLo ); - uint32x2_t maskHi = vclt_f32( rHi, dotMinHi ); - dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo); - dotMinHi = vbsl_f32( maskHi, rHi, dotMinHi); - iLo = vbsl_u32(maskLo, indexLo, iLo); - iHi = vbsl_u32(maskHi, indexHi, iHi); - indexLo = vadd_u32(indexLo, four); - indexHi = vadd_u32(indexHi, four); - } - switch( count & 3 ) - { - case 3: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); + uint32x4_t mask = vcgtq_f32(x, maxDot); + maxDot = vbslq_f32(mask, x, maxDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } - float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); - float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); - float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo); + switch (count & 3) + { + case 3: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); - float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x2_t zLo = vmul_f32( z0.val[0], vHi); - float32x2_t zHi = vmul_f32( vdup_lane_f32(vget_high_f32(v2), 0), vHi); + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v1)); + float32x4_t xy1 = vcombine_f32(vget_low_f32(v2), vget_low_f32(v2)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x4_t z1 = vcombine_f32(vget_high_f32(v2), vget_high_f32(v2)); - float32x2_t rLo = vpadd_f32( xy0, xy1); - float32x2_t rHi = vpadd_f32( xy2, xy2); - rLo = vadd_f32(rLo, zLo); - rHi = vadd_f32(rHi, zHi); + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); - uint32x2_t maskLo = vclt_f32( rLo, dotMinLo ); - uint32x2_t maskHi = vclt_f32( rHi, dotMinHi ); - dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo); - dotMinHi = vbsl_f32( maskHi, rHi, dotMinHi); - iLo = vbsl_u32(maskLo, indexLo, iLo); - iHi = vbsl_u32(maskHi, indexHi, iHi); - } - break; - case 2: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); + float32x4x2_t zb = vuzpq_f32(z0, z1); + float32x4_t z = vmulq_f32(zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32(xy0, xy1); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); - float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); - float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); + uint32x4_t mask = vcgtq_f32(x, maxDot); + maxDot = vbslq_f32(mask, x, maxDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + break; - float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x2_t zLo = vmul_f32( z0.val[0], vHi); + case 2: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); - float32x2_t rLo = vpadd_f32( xy0, xy1); - rLo = vadd_f32(rLo, zLo); + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v1)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32(vget_high_f32(v0), vget_high_f32(v1)); - uint32x2_t maskLo = vclt_f32( rLo, dotMinLo ); - dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo); - iLo = vbsl_u32(maskLo, indexLo, iLo); - } - break; - case 1: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); - float32x2_t z0 = vdup_lane_f32(vget_high_f32(v0), 0); - float32x2_t zLo = vmul_f32( z0, vHi); - float32x2_t rLo = vpadd_f32( xy0, xy0); - rLo = vadd_f32(rLo, zLo); - uint32x2_t maskLo = vclt_f32( rLo, dotMinLo ); - dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo); - iLo = vbsl_u32(maskLo, indexLo, iLo); - } - break; + xy0 = vmulq_f32(xy0, vLo); - default: - break; - } + float32x4x2_t zb = vuzpq_f32(z0, z0); + float32x4_t z = vmulq_f32(zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32(xy0, xy0); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); - // select best answer between hi and lo results - uint32x2_t mask = vclt_f32( dotMinHi, dotMinLo ); - dotMinLo = vbsl_f32(mask, dotMinHi, dotMinLo); - iLo = vbsl_u32(mask, iHi, iLo); + uint32x4_t mask = vcgtq_f32(x, maxDot); + maxDot = vbslq_f32(mask, x, maxDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + break; - // select best answer between even and odd results - dotMinHi = vdup_lane_f32(dotMinLo, 1); - iHi = vdup_lane_u32(iLo, 1); - mask = vclt_f32( dotMinHi, dotMinLo ); - dotMinLo = vbsl_f32(mask, dotMinHi, dotMinLo); - iLo = vbsl_u32(mask, iHi, iLo); + case 1: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); - *dotResult = vget_lane_f32( dotMinLo, 0); - return vget_lane_u32(iLo, 0); + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v0)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z = vdupq_lane_f32(vget_high_f32(v0), 0); + + xy0 = vmulq_f32(xy0, vLo); + + z = vmulq_f32(z, vHi); + float32x4x2_t xy = vuzpq_f32(xy0, xy0); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcgtq_f32(x, maxDot); + maxDot = vbslq_f32(mask, x, maxDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + break; + + default: + break; + } + + // select best answer between hi and lo results + uint32x2_t mask = vcgt_f32(vget_high_f32(maxDot), vget_low_f32(maxDot)); + float32x2_t maxDot2 = vbsl_f32(mask, vget_high_f32(maxDot), vget_low_f32(maxDot)); + uint32x2_t index2 = vbsl_u32(mask, vget_high_u32(index), vget_low_u32(index)); + + // select best answer between even and odd results + float32x2_t maxDotO = vdup_lane_f32(maxDot2, 1); + uint32x2_t indexHi = vdup_lane_u32(index2, 1); + mask = vcgt_f32(maxDotO, maxDot2); + maxDot2 = vbsl_f32(mask, maxDotO, maxDot2); + index2 = vbsl_u32(mask, indexHi, index2); + + *dotResult = vget_lane_f32(maxDot2, 0); + return vget_lane_u32(index2, 0); } -long b3_mindot_large_v1( const float *vv, const float *vec, unsigned long count, float *dotResult ) +long b3_mindot_large_v0(const float *vv, const float *vec, unsigned long count, float *dotResult) { - float32x4_t vvec = vld1q_f32_aligned_postincrement( vec ); - float32x4_t vLo = vcombine_f32(vget_low_f32(vvec), vget_low_f32(vvec)); - float32x4_t vHi = vdupq_lane_f32(vget_high_f32(vvec), 0); - const uint32x4_t four = (uint32x4_t){ 4, 4, 4, 4 }; - uint32x4_t local_index = (uint32x4_t) {0, 1, 2, 3}; - uint32x4_t index = (uint32x4_t) { -1, -1, -1, -1 }; - float32x4_t minDot = (float32x4_t) { B3_INFINITY, B3_INFINITY, B3_INFINITY, B3_INFINITY }; + unsigned long i = 0; + float32x4_t vvec = vld1q_f32_aligned_postincrement(vec); + float32x2_t vLo = vget_low_f32(vvec); + float32x2_t vHi = vdup_lane_f32(vget_high_f32(vvec), 0); + float32x2_t dotMinLo = (float32x2_t){B3_INFINITY, B3_INFINITY}; + float32x2_t dotMinHi = (float32x2_t){B3_INFINITY, B3_INFINITY}; + uint32x2_t indexLo = (uint32x2_t){0, 1}; + uint32x2_t indexHi = (uint32x2_t){2, 3}; + uint32x2_t iLo = (uint32x2_t){-1, -1}; + uint32x2_t iHi = (uint32x2_t){-1, -1}; + const uint32x2_t four = (uint32x2_t){4, 4}; - unsigned long i = 0; - for( ; i + 8 <= count; i += 8 ) - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); + for (; i + 8 <= count; i += 8) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v3 = vld1q_f32_aligned_postincrement(vv); - // the next two lines should resolve to a single vswp d, d - float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); - float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3)); - // the next two lines should resolve to a single vswp d, d - float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3)); + float32x2_t xy0 = vmul_f32(vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32(vget_low_f32(v1), vLo); + float32x2_t xy2 = vmul_f32(vget_low_f32(v2), vLo); + float32x2_t xy3 = vmul_f32(vget_low_f32(v3), vLo); - xy0 = vmulq_f32(xy0, vLo); - xy1 = vmulq_f32(xy1, vLo); + float32x2x2_t z0 = vtrn_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x2x2_t z1 = vtrn_f32(vget_high_f32(v2), vget_high_f32(v3)); + float32x2_t zLo = vmul_f32(z0.val[0], vHi); + float32x2_t zHi = vmul_f32(z1.val[0], vHi); - float32x4x2_t zb = vuzpq_f32( z0, z1); - float32x4_t z = vmulq_f32( zb.val[0], vHi); - float32x4x2_t xy = vuzpq_f32( xy0, xy1); - float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); + float32x2_t rLo = vpadd_f32(xy0, xy1); + float32x2_t rHi = vpadd_f32(xy2, xy3); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); - uint32x4_t mask = vcltq_f32(x, minDot); - minDot = vbslq_f32( mask, x, minDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); + uint32x2_t maskLo = vclt_f32(rLo, dotMinLo); + uint32x2_t maskHi = vclt_f32(rHi, dotMinHi); + dotMinLo = vbsl_f32(maskLo, rLo, dotMinLo); + dotMinHi = vbsl_f32(maskHi, rHi, dotMinHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + indexLo = vadd_u32(indexLo, four); + indexHi = vadd_u32(indexHi, four); - v0 = vld1q_f32_aligned_postincrement( vv ); - v1 = vld1q_f32_aligned_postincrement( vv ); - v2 = vld1q_f32_aligned_postincrement( vv ); - v3 = vld1q_f32_aligned_postincrement( vv ); + v0 = vld1q_f32_aligned_postincrement(vv); + v1 = vld1q_f32_aligned_postincrement(vv); + v2 = vld1q_f32_aligned_postincrement(vv); + v3 = vld1q_f32_aligned_postincrement(vv); - // the next two lines should resolve to a single vswp d, d - xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); - xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3)); - // the next two lines should resolve to a single vswp d, d - z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); - z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3)); + xy0 = vmul_f32(vget_low_f32(v0), vLo); + xy1 = vmul_f32(vget_low_f32(v1), vLo); + xy2 = vmul_f32(vget_low_f32(v2), vLo); + xy3 = vmul_f32(vget_low_f32(v3), vLo); - xy0 = vmulq_f32(xy0, vLo); - xy1 = vmulq_f32(xy1, vLo); + z0 = vtrn_f32(vget_high_f32(v0), vget_high_f32(v1)); + z1 = vtrn_f32(vget_high_f32(v2), vget_high_f32(v3)); + zLo = vmul_f32(z0.val[0], vHi); + zHi = vmul_f32(z1.val[0], vHi); - zb = vuzpq_f32( z0, z1); - z = vmulq_f32( zb.val[0], vHi); - xy = vuzpq_f32( xy0, xy1); - x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); + rLo = vpadd_f32(xy0, xy1); + rHi = vpadd_f32(xy2, xy3); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); - mask = vcltq_f32(x, minDot); - minDot = vbslq_f32( mask, x, minDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - } + maskLo = vclt_f32(rLo, dotMinLo); + maskHi = vclt_f32(rHi, dotMinHi); + dotMinLo = vbsl_f32(maskLo, rLo, dotMinLo); + dotMinHi = vbsl_f32(maskHi, rHi, dotMinHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + indexLo = vadd_u32(indexLo, four); + indexHi = vadd_u32(indexHi, four); + } - for( ; i + 4 <= count; i += 4 ) - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); + for (; i + 4 <= count; i += 4) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v3 = vld1q_f32_aligned_postincrement(vv); - // the next two lines should resolve to a single vswp d, d - float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); - float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3)); - // the next two lines should resolve to a single vswp d, d - float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3)); + float32x2_t xy0 = vmul_f32(vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32(vget_low_f32(v1), vLo); + float32x2_t xy2 = vmul_f32(vget_low_f32(v2), vLo); + float32x2_t xy3 = vmul_f32(vget_low_f32(v3), vLo); - xy0 = vmulq_f32(xy0, vLo); - xy1 = vmulq_f32(xy1, vLo); + float32x2x2_t z0 = vtrn_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x2x2_t z1 = vtrn_f32(vget_high_f32(v2), vget_high_f32(v3)); + float32x2_t zLo = vmul_f32(z0.val[0], vHi); + float32x2_t zHi = vmul_f32(z1.val[0], vHi); - float32x4x2_t zb = vuzpq_f32( z0, z1); - float32x4_t z = vmulq_f32( zb.val[0], vHi); - float32x4x2_t xy = vuzpq_f32( xy0, xy1); - float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); + float32x2_t rLo = vpadd_f32(xy0, xy1); + float32x2_t rHi = vpadd_f32(xy2, xy3); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); - uint32x4_t mask = vcltq_f32(x, minDot); - minDot = vbslq_f32( mask, x, minDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - } + uint32x2_t maskLo = vclt_f32(rLo, dotMinLo); + uint32x2_t maskHi = vclt_f32(rHi, dotMinHi); + dotMinLo = vbsl_f32(maskLo, rLo, dotMinLo); + dotMinHi = vbsl_f32(maskHi, rHi, dotMinHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + indexLo = vadd_u32(indexLo, four); + indexHi = vadd_u32(indexHi, four); + } + switch (count & 3) + { + case 3: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); - switch (count & 3) { - case 3: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); + float32x2_t xy0 = vmul_f32(vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32(vget_low_f32(v1), vLo); + float32x2_t xy2 = vmul_f32(vget_low_f32(v2), vLo); - // the next two lines should resolve to a single vswp d, d - float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); - float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v2)); - // the next two lines should resolve to a single vswp d, d - float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v2)); + float32x2x2_t z0 = vtrn_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x2_t zLo = vmul_f32(z0.val[0], vHi); + float32x2_t zHi = vmul_f32(vdup_lane_f32(vget_high_f32(v2), 0), vHi); - xy0 = vmulq_f32(xy0, vLo); - xy1 = vmulq_f32(xy1, vLo); + float32x2_t rLo = vpadd_f32(xy0, xy1); + float32x2_t rHi = vpadd_f32(xy2, xy2); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); - float32x4x2_t zb = vuzpq_f32( z0, z1); - float32x4_t z = vmulq_f32( zb.val[0], vHi); - float32x4x2_t xy = vuzpq_f32( xy0, xy1); - float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); + uint32x2_t maskLo = vclt_f32(rLo, dotMinLo); + uint32x2_t maskHi = vclt_f32(rHi, dotMinHi); + dotMinLo = vbsl_f32(maskLo, rLo, dotMinLo); + dotMinHi = vbsl_f32(maskHi, rHi, dotMinHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + } + break; + case 2: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); - uint32x4_t mask = vcltq_f32(x, minDot); - minDot = vbslq_f32( mask, x, minDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - } - break; + float32x2_t xy0 = vmul_f32(vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32(vget_low_f32(v1), vLo); - case 2: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); + float32x2x2_t z0 = vtrn_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x2_t zLo = vmul_f32(z0.val[0], vHi); - // the next two lines should resolve to a single vswp d, d - float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); - // the next two lines should resolve to a single vswp d, d - float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); + float32x2_t rLo = vpadd_f32(xy0, xy1); + rLo = vadd_f32(rLo, zLo); - xy0 = vmulq_f32(xy0, vLo); + uint32x2_t maskLo = vclt_f32(rLo, dotMinLo); + dotMinLo = vbsl_f32(maskLo, rLo, dotMinLo); + iLo = vbsl_u32(maskLo, indexLo, iLo); + } + break; + case 1: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x2_t xy0 = vmul_f32(vget_low_f32(v0), vLo); + float32x2_t z0 = vdup_lane_f32(vget_high_f32(v0), 0); + float32x2_t zLo = vmul_f32(z0, vHi); + float32x2_t rLo = vpadd_f32(xy0, xy0); + rLo = vadd_f32(rLo, zLo); + uint32x2_t maskLo = vclt_f32(rLo, dotMinLo); + dotMinLo = vbsl_f32(maskLo, rLo, dotMinLo); + iLo = vbsl_u32(maskLo, indexLo, iLo); + } + break; - float32x4x2_t zb = vuzpq_f32( z0, z0); - float32x4_t z = vmulq_f32( zb.val[0], vHi); - float32x4x2_t xy = vuzpq_f32( xy0, xy0); - float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); + default: + break; + } - uint32x4_t mask = vcltq_f32(x, minDot); - minDot = vbslq_f32( mask, x, minDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - } - break; + // select best answer between hi and lo results + uint32x2_t mask = vclt_f32(dotMinHi, dotMinLo); + dotMinLo = vbsl_f32(mask, dotMinHi, dotMinLo); + iLo = vbsl_u32(mask, iHi, iLo); - case 1: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); + // select best answer between even and odd results + dotMinHi = vdup_lane_f32(dotMinLo, 1); + iHi = vdup_lane_u32(iLo, 1); + mask = vclt_f32(dotMinHi, dotMinLo); + dotMinLo = vbsl_f32(mask, dotMinHi, dotMinLo); + iLo = vbsl_u32(mask, iHi, iLo); - // the next two lines should resolve to a single vswp d, d - float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v0)); - // the next two lines should resolve to a single vswp d, d - float32x4_t z = vdupq_lane_f32(vget_high_f32(v0), 0); + *dotResult = vget_lane_f32(dotMinLo, 0); + return vget_lane_u32(iLo, 0); +} - xy0 = vmulq_f32(xy0, vLo); +long b3_mindot_large_v1(const float *vv, const float *vec, unsigned long count, float *dotResult) +{ + float32x4_t vvec = vld1q_f32_aligned_postincrement(vec); + float32x4_t vLo = vcombine_f32(vget_low_f32(vvec), vget_low_f32(vvec)); + float32x4_t vHi = vdupq_lane_f32(vget_high_f32(vvec), 0); + const uint32x4_t four = (uint32x4_t){4, 4, 4, 4}; + uint32x4_t local_index = (uint32x4_t){0, 1, 2, 3}; + uint32x4_t index = (uint32x4_t){-1, -1, -1, -1}; + float32x4_t minDot = (float32x4_t){B3_INFINITY, B3_INFINITY, B3_INFINITY, B3_INFINITY}; - z = vmulq_f32( z, vHi); - float32x4x2_t xy = vuzpq_f32( xy0, xy0); - float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); + unsigned long i = 0; + for (; i + 8 <= count; i += 8) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v3 = vld1q_f32_aligned_postincrement(vv); - uint32x4_t mask = vcltq_f32(x, minDot); - minDot = vbslq_f32( mask, x, minDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - } - break; + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v1)); + float32x4_t xy1 = vcombine_f32(vget_low_f32(v2), vget_low_f32(v3)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x4_t z1 = vcombine_f32(vget_high_f32(v2), vget_high_f32(v3)); - default: - break; - } + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); + float32x4x2_t zb = vuzpq_f32(z0, z1); + float32x4_t z = vmulq_f32(zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32(xy0, xy1); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); - // select best answer between hi and lo results - uint32x2_t mask = vclt_f32( vget_high_f32(minDot), vget_low_f32(minDot)); - float32x2_t minDot2 = vbsl_f32(mask, vget_high_f32(minDot), vget_low_f32(minDot)); - uint32x2_t index2 = vbsl_u32(mask, vget_high_u32(index), vget_low_u32(index)); + uint32x4_t mask = vcltq_f32(x, minDot); + minDot = vbslq_f32(mask, x, minDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); - // select best answer between even and odd results - float32x2_t minDotO = vdup_lane_f32(minDot2, 1); - uint32x2_t indexHi = vdup_lane_u32(index2, 1); - mask = vclt_f32( minDotO, minDot2 ); - minDot2 = vbsl_f32(mask, minDotO, minDot2); - index2 = vbsl_u32(mask, indexHi, index2); + v0 = vld1q_f32_aligned_postincrement(vv); + v1 = vld1q_f32_aligned_postincrement(vv); + v2 = vld1q_f32_aligned_postincrement(vv); + v3 = vld1q_f32_aligned_postincrement(vv); - *dotResult = vget_lane_f32( minDot2, 0); - return vget_lane_u32(index2, 0); + // the next two lines should resolve to a single vswp d, d + xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v1)); + xy1 = vcombine_f32(vget_low_f32(v2), vget_low_f32(v3)); + // the next two lines should resolve to a single vswp d, d + z0 = vcombine_f32(vget_high_f32(v0), vget_high_f32(v1)); + z1 = vcombine_f32(vget_high_f32(v2), vget_high_f32(v3)); + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); + + zb = vuzpq_f32(z0, z1); + z = vmulq_f32(zb.val[0], vHi); + xy = vuzpq_f32(xy0, xy1); + x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + mask = vcltq_f32(x, minDot); + minDot = vbslq_f32(mask, x, minDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + + for (; i + 4 <= count; i += 4) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v3 = vld1q_f32_aligned_postincrement(vv); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v1)); + float32x4_t xy1 = vcombine_f32(vget_low_f32(v2), vget_low_f32(v3)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x4_t z1 = vcombine_f32(vget_high_f32(v2), vget_high_f32(v3)); + + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); + + float32x4x2_t zb = vuzpq_f32(z0, z1); + float32x4_t z = vmulq_f32(zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32(xy0, xy1); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcltq_f32(x, minDot); + minDot = vbslq_f32(mask, x, minDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + + switch (count & 3) + { + case 3: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v1)); + float32x4_t xy1 = vcombine_f32(vget_low_f32(v2), vget_low_f32(v2)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x4_t z1 = vcombine_f32(vget_high_f32(v2), vget_high_f32(v2)); + + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); + + float32x4x2_t zb = vuzpq_f32(z0, z1); + float32x4_t z = vmulq_f32(zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32(xy0, xy1); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcltq_f32(x, minDot); + minDot = vbslq_f32(mask, x, minDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + break; + + case 2: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v1)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32(vget_high_f32(v0), vget_high_f32(v1)); + + xy0 = vmulq_f32(xy0, vLo); + + float32x4x2_t zb = vuzpq_f32(z0, z0); + float32x4_t z = vmulq_f32(zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32(xy0, xy0); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcltq_f32(x, minDot); + minDot = vbslq_f32(mask, x, minDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + break; + + case 1: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v0)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z = vdupq_lane_f32(vget_high_f32(v0), 0); + + xy0 = vmulq_f32(xy0, vLo); + + z = vmulq_f32(z, vHi); + float32x4x2_t xy = vuzpq_f32(xy0, xy0); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcltq_f32(x, minDot); + minDot = vbslq_f32(mask, x, minDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + break; + + default: + break; + } + + // select best answer between hi and lo results + uint32x2_t mask = vclt_f32(vget_high_f32(minDot), vget_low_f32(minDot)); + float32x2_t minDot2 = vbsl_f32(mask, vget_high_f32(minDot), vget_low_f32(minDot)); + uint32x2_t index2 = vbsl_u32(mask, vget_high_u32(index), vget_low_u32(index)); + + // select best answer between even and odd results + float32x2_t minDotO = vdup_lane_f32(minDot2, 1); + uint32x2_t indexHi = vdup_lane_u32(index2, 1); + mask = vclt_f32(minDotO, minDot2); + minDot2 = vbsl_f32(mask, minDotO, minDot2); + index2 = vbsl_u32(mask, indexHi, index2); + + *dotResult = vget_lane_f32(minDot2, 0); + return vget_lane_u32(index2, 0); } #else - #error Unhandled __APPLE__ arch +#error Unhandled __APPLE__ arch #endif -#endif /* __APPLE__ */ - - +#endif /* __APPLE__ */ diff --git a/src/Bullet3Common/b3Vector3.h b/src/Bullet3Common/b3Vector3.h index 16ec02b0e..56e6c1331 100644 --- a/src/Bullet3Common/b3Vector3.h +++ b/src/Bullet3Common/b3Vector3.h @@ -12,8 +12,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #ifndef B3_VECTOR3_H #define B3_VECTOR3_H @@ -28,37 +26,34 @@ subject to the following restrictions: #else #define b3Vector3Data b3Vector3FloatData #define b3Vector3DataName "b3Vector3FloatData" -#endif //B3_USE_DOUBLE_PRECISION +#endif //B3_USE_DOUBLE_PRECISION #if defined B3_USE_SSE //typedef uint32_t __m128i __attribute__ ((vector_size(16))); #ifdef _MSC_VER -#pragma warning(disable: 4556) // value of intrinsic immediate argument '4294967239' is out of range '0 - 255' +#pragma warning(disable : 4556) // value of intrinsic immediate argument '4294967239' is out of range '0 - 255' #endif - -#define B3_SHUFFLE(x,y,z,w) ((w)<<6 | (z)<<4 | (y)<<2 | (x)) +#define B3_SHUFFLE(x, y, z, w) ((w) << 6 | (z) << 4 | (y) << 2 | (x)) //#define b3_pshufd_ps( _a, _mask ) (__m128) _mm_shuffle_epi32((__m128i)(_a), (_mask) ) -#define b3_pshufd_ps( _a, _mask ) _mm_shuffle_ps((_a), (_a), (_mask) ) -#define b3_splat3_ps( _a, _i ) b3_pshufd_ps((_a), B3_SHUFFLE(_i,_i,_i, 3) ) -#define b3_splat_ps( _a, _i ) b3_pshufd_ps((_a), B3_SHUFFLE(_i,_i,_i,_i) ) +#define b3_pshufd_ps(_a, _mask) _mm_shuffle_ps((_a), (_a), (_mask)) +#define b3_splat3_ps(_a, _i) b3_pshufd_ps((_a), B3_SHUFFLE(_i, _i, _i, 3)) +#define b3_splat_ps(_a, _i) b3_pshufd_ps((_a), B3_SHUFFLE(_i, _i, _i, _i)) #define b3v3AbsiMask (_mm_set_epi32(0x00000000, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF)) -#define b3vAbsMask (_mm_set_epi32( 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF)) +#define b3vAbsMask (_mm_set_epi32(0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF)) #define b3vFFF0Mask (_mm_set_epi32(0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF)) #define b3v3AbsfMask b3CastiTo128f(b3v3AbsiMask) #define b3vFFF0fMask b3CastiTo128f(b3vFFF0Mask) #define b3vxyzMaskf b3vFFF0fMask #define b3vAbsfMask b3CastiTo128f(b3vAbsMask) - - const __m128 B3_ATTRIBUTE_ALIGNED16(b3vMzeroMask) = {-0.0f, -0.0f, -0.0f, -0.0f}; const __m128 B3_ATTRIBUTE_ALIGNED16(b3v1110) = {1.0f, 1.0f, 1.0f, 0.0f}; const __m128 B3_ATTRIBUTE_ALIGNED16(b3vHalf) = {0.5f, 0.5f, 0.5f, 0.5f}; -const __m128 B3_ATTRIBUTE_ALIGNED16(b3v1_5) = {1.5f, 1.5f, 1.5f, 1.5f}; +const __m128 B3_ATTRIBUTE_ALIGNED16(b3v1_5) = {1.5f, 1.5f, 1.5f, 1.5f}; #endif @@ -74,70 +69,69 @@ const int32x4_t B3_ATTRIBUTE_ALIGNED16(b3v3AbsMask) = (int32x4_t){0x7FFFFFFF, 0x class b3Vector3; class b3Vector4; -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) //#if defined (B3_USE_SSE) || defined (B3_USE_NEON) -inline b3Vector3 b3MakeVector3( b3SimdFloat4 v); -inline b3Vector4 b3MakeVector4( b3SimdFloat4 vec); +inline b3Vector3 b3MakeVector3(b3SimdFloat4 v); +inline b3Vector4 b3MakeVector4(b3SimdFloat4 vec); #endif -inline b3Vector3 b3MakeVector3(b3Scalar x,b3Scalar y,b3Scalar z); -inline b3Vector3 b3MakeVector3(b3Scalar x,b3Scalar y,b3Scalar z, b3Scalar w); -inline b3Vector4 b3MakeVector4(b3Scalar x,b3Scalar y,b3Scalar z,b3Scalar w); - +inline b3Vector3 b3MakeVector3(b3Scalar x, b3Scalar y, b3Scalar z); +inline b3Vector3 b3MakeVector3(b3Scalar x, b3Scalar y, b3Scalar z, b3Scalar w); +inline b3Vector4 b3MakeVector4(b3Scalar x, b3Scalar y, b3Scalar z, b3Scalar w); /**@brief b3Vector3 can be used to represent 3D points and vectors. * It has an un-used w component to suit 16-byte alignment when b3Vector3 is stored in containers. This extra component can be used by derived classes (Quaternion?) or by user * Ideally, this class should be replaced by a platform optimized SIMD version that keeps the data in registers */ -B3_ATTRIBUTE_ALIGNED16(class) b3Vector3 +B3_ATTRIBUTE_ALIGNED16(class) +b3Vector3 { public: -#if defined (B3_USE_SSE) || defined(B3_USE_NEON) // _WIN32 || ARM - union { - b3SimdFloat4 mVec128; - float m_floats[4]; - struct {float x,y,z,w;}; - - }; +#if defined(B3_USE_SSE) || defined(B3_USE_NEON) // _WIN32 || ARM + union { + b3SimdFloat4 mVec128; + float m_floats[4]; + struct + { + float x, y, z, w; + }; + }; #else - union - { - float m_floats[4]; - struct {float x,y,z,w;}; + union { + float m_floats[4]; + struct + { + float x, y, z, w; + }; }; #endif - public: - B3_DECLARE_ALIGNED_ALLOCATOR(); -#if defined (B3_USE_SSE) || defined(B3_USE_NEON) // _WIN32 || ARM +#if defined(B3_USE_SSE) || defined(B3_USE_NEON) // _WIN32 || ARM /*B3_FORCE_INLINE b3Vector3() { } */ - B3_FORCE_INLINE b3SimdFloat4 get128() const - { - return mVec128; - } - B3_FORCE_INLINE void set128(b3SimdFloat4 v128) - { - mVec128 = v128; - } + B3_FORCE_INLINE b3SimdFloat4 get128() const + { + return mVec128; + } + B3_FORCE_INLINE void set128(b3SimdFloat4 v128) + { + mVec128 = v128; + } #endif - public: - - - -/**@brief Add a vector to this one +public: + /**@brief Add a vector to this one * @param The vector to add to this one */ B3_FORCE_INLINE b3Vector3& operator+=(const b3Vector3& v) { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) mVec128 = _mm_add_ps(mVec128, v.mVec128); #elif defined(B3_USE_NEON) mVec128 = vaddq_f32(mVec128, v.mVec128); @@ -149,12 +143,11 @@ public: return *this; } - - /**@brief Subtract a vector from this one + /**@brief Subtract a vector from this one * @param The vector to subtract */ B3_FORCE_INLINE b3Vector3& operator-=(const b3Vector3& v) { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) mVec128 = _mm_sub_ps(mVec128, v.mVec128); #elif defined(B3_USE_NEON) mVec128 = vsubq_f32(mVec128, v.mVec128); @@ -166,13 +159,13 @@ public: return *this; } - /**@brief Scale the vector + /**@brief Scale the vector * @param s Scale factor */ B3_FORCE_INLINE b3Vector3& operator*=(const b3Scalar& s) { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) - __m128 vs = _mm_load_ss(&s); // (S 0 0 0) - vs = b3_pshufd_ps(vs, 0x80); // (S S S 0.0) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) + __m128 vs = _mm_load_ss(&s); // (S 0 0 0) + vs = b3_pshufd_ps(vs, 0x80); // (S S S 0.0) mVec128 = _mm_mul_ps(mVec128, vs); #elif defined(B3_USE_NEON) mVec128 = vmulq_n_f32(mVec128, s); @@ -184,13 +177,13 @@ public: return *this; } - /**@brief Inversely scale the vector + /**@brief Inversely scale the vector * @param s Scale factor to divide by */ B3_FORCE_INLINE b3Vector3& operator/=(const b3Scalar& s) { b3FullAssert(s != b3Scalar(0.0)); -#if 0 //defined(B3_USE_SSE_IN_API) +#if 0 //defined(B3_USE_SSE_IN_API) // this code is not faster ! __m128 vs = _mm_load_ss(&s); vs = _mm_div_ss(b3v1110, vs); @@ -204,11 +197,11 @@ public: #endif } - /**@brief Return the dot product + /**@brief Return the dot product * @param v The other vector in the dot product */ B3_FORCE_INLINE b3Scalar dot(const b3Vector3& v) const { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) __m128 vd = _mm_mul_ps(mVec128, v.mVec128); __m128 z = _mm_movehl_ps(vd, vd); __m128 y = _mm_shuffle_ps(vd, vd, 0x55); @@ -221,29 +214,29 @@ public: x = vadd_f32(x, vget_high_f32(vd)); return vget_lane_f32(x, 0); #else - return m_floats[0] * v.m_floats[0] + - m_floats[1] * v.m_floats[1] + - m_floats[2] * v.m_floats[2]; + return m_floats[0] * v.m_floats[0] + + m_floats[1] * v.m_floats[1] + + m_floats[2] * v.m_floats[2]; #endif } - /**@brief Return the length of the vector squared */ + /**@brief Return the length of the vector squared */ B3_FORCE_INLINE b3Scalar length2() const { return dot(*this); } - /**@brief Return the length of the vector */ + /**@brief Return the length of the vector */ B3_FORCE_INLINE b3Scalar length() const { return b3Sqrt(length2()); } - /**@brief Return the distance squared between the ends of this and another vector + /**@brief Return the distance squared between the ends of this and another vector * This is symantically treating the vector like a point */ B3_FORCE_INLINE b3Scalar distance2(const b3Vector3& v) const; - /**@brief Return the distance between the ends of this and another vector + /**@brief Return the distance between the ends of this and another vector * This is symantically treating the vector like a point */ B3_FORCE_INLINE b3Scalar distance(const b3Vector3& v) const; @@ -251,7 +244,7 @@ public: { b3Scalar l2 = length2(); //triNormal.normalize(); - if (l2 >= B3_EPSILON*B3_EPSILON) + if (l2 >= B3_EPSILON * B3_EPSILON) { (*this) /= b3Sqrt(l2); } @@ -262,43 +255,42 @@ public: return *this; } - /**@brief Normalize this vector + /**@brief Normalize this vector * x^2 + y^2 + z^2 = 1 */ B3_FORCE_INLINE b3Vector3& normalize() { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) - // dot product first +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) + // dot product first __m128 vd = _mm_mul_ps(mVec128, mVec128); __m128 z = _mm_movehl_ps(vd, vd); __m128 y = _mm_shuffle_ps(vd, vd, 0x55); vd = _mm_add_ss(vd, y); vd = _mm_add_ss(vd, z); - #if 0 +#if 0 vd = _mm_sqrt_ss(vd); vd = _mm_div_ss(b3v1110, vd); vd = b3_splat_ps(vd, 0x80); mVec128 = _mm_mul_ps(mVec128, vd); - #else +#else - // NR step 1/sqrt(x) - vd is x, y is output - y = _mm_rsqrt_ss(vd); // estimate + // NR step 1/sqrt(x) - vd is x, y is output + y = _mm_rsqrt_ss(vd); // estimate - // one step NR - z = b3v1_5; - vd = _mm_mul_ss(vd, b3vHalf); // vd * 0.5 - //x2 = vd; - vd = _mm_mul_ss(vd, y); // vd * 0.5 * y0 - vd = _mm_mul_ss(vd, y); // vd * 0.5 * y0 * y0 - z = _mm_sub_ss(z, vd); // 1.5 - vd * 0.5 * y0 * y0 + // one step NR + z = b3v1_5; + vd = _mm_mul_ss(vd, b3vHalf); // vd * 0.5 + //x2 = vd; + vd = _mm_mul_ss(vd, y); // vd * 0.5 * y0 + vd = _mm_mul_ss(vd, y); // vd * 0.5 * y0 * y0 + z = _mm_sub_ss(z, vd); // 1.5 - vd * 0.5 * y0 * y0 - y = _mm_mul_ss(y, z); // y0 * (1.5 - vd * 0.5 * y0 * y0) + y = _mm_mul_ss(y, z); // y0 * (1.5 - vd * 0.5 * y0 * y0) y = b3_splat_ps(y, 0x80); mVec128 = _mm_mul_ps(mVec128, y); - #endif - +#endif return *this; #else @@ -306,15 +298,15 @@ public: #endif } - /**@brief Return a normalized version of this vector */ + /**@brief Return a normalized version of this vector */ B3_FORCE_INLINE b3Vector3 normalized() const; - /**@brief Return a rotated version of this vector + /**@brief Return a rotated version of this vector * @param wAxis The axis to rotate about * @param angle The angle to rotate by */ - B3_FORCE_INLINE b3Vector3 rotate( const b3Vector3& wAxis, const b3Scalar angle ) const; + B3_FORCE_INLINE b3Vector3 rotate(const b3Vector3& wAxis, const b3Scalar angle) const; - /**@brief Return the angle between this and another vector + /**@brief Return the angle between this and another vector * @param v The other vector */ B3_FORCE_INLINE b3Scalar angle(const b3Vector3& v) const { @@ -323,10 +315,10 @@ public: return b3Acos(dot(v) / s); } - /**@brief Return a vector will the absolute values of each element */ + /**@brief Return a vector will the absolute values of each element */ B3_FORCE_INLINE b3Vector3 absolute() const { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) return b3MakeVector3(_mm_and_ps(mVec128, b3v3AbsfMask)); #elif defined(B3_USE_NEON) return b3Vector3(vabsq_f32(mVec128)); @@ -338,15 +330,15 @@ public: #endif } - /**@brief Return the cross product between this and another vector + /**@brief Return the cross product between this and another vector * @param v The other vector */ B3_FORCE_INLINE b3Vector3 cross(const b3Vector3& v) const { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) - __m128 T, V; +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) + __m128 T, V; - T = b3_pshufd_ps(mVec128, B3_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0) - V = b3_pshufd_ps(v.mVec128, B3_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0) + T = b3_pshufd_ps(mVec128, B3_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0) + V = b3_pshufd_ps(v.mVec128, B3_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0) V = _mm_mul_ps(V, mVec128); T = _mm_mul_ps(T, v.mVec128); @@ -381,10 +373,10 @@ public: B3_FORCE_INLINE b3Scalar triple(const b3Vector3& v1, const b3Vector3& v2) const { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) // cross: - __m128 T = _mm_shuffle_ps(v1.mVec128, v1.mVec128, B3_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0) - __m128 V = _mm_shuffle_ps(v2.mVec128, v2.mVec128, B3_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0) + __m128 T = _mm_shuffle_ps(v1.mVec128, v1.mVec128, B3_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0) + __m128 V = _mm_shuffle_ps(v2.mVec128, v2.mVec128, B3_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0) V = _mm_mul_ps(V, v1.mVec128); T = _mm_mul_ps(T, v2.mVec128); @@ -422,25 +414,24 @@ public: x = vadd_f32(x, vget_high_f32(V)); return vget_lane_f32(x, 0); #else - return - m_floats[0] * (v1.m_floats[1] * v2.m_floats[2] - v1.m_floats[2] * v2.m_floats[1]) + - m_floats[1] * (v1.m_floats[2] * v2.m_floats[0] - v1.m_floats[0] * v2.m_floats[2]) + - m_floats[2] * (v1.m_floats[0] * v2.m_floats[1] - v1.m_floats[1] * v2.m_floats[0]); + return m_floats[0] * (v1.m_floats[1] * v2.m_floats[2] - v1.m_floats[2] * v2.m_floats[1]) + + m_floats[1] * (v1.m_floats[2] * v2.m_floats[0] - v1.m_floats[0] * v2.m_floats[2]) + + m_floats[2] * (v1.m_floats[0] * v2.m_floats[1] - v1.m_floats[1] * v2.m_floats[0]); #endif } - /**@brief Return the axis with the smallest value + /**@brief Return the axis with the smallest value * Note return values are 0,1,2 for x, y, or z */ B3_FORCE_INLINE int minAxis() const { - return m_floats[0] < m_floats[1] ? (m_floats[0] return this, t=1 => return other) */ B3_FORCE_INLINE b3Vector3 lerp(const b3Vector3& v, const b3Scalar& t) const { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) - __m128 vt = _mm_load_ss(&t); // (t 0 0 0) - vt = b3_pshufd_ps(vt, 0x80); // (rt rt rt 0.0) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) + __m128 vt = _mm_load_ss(&t); // (t 0 0 0) + vt = b3_pshufd_ps(vt, 0x80); // (rt rt rt 0.0) __m128 vl = _mm_sub_ps(v.mVec128, mVec128); vl = _mm_mul_ps(vl, vt); vl = _mm_add_ps(vl, mVec128); @@ -500,18 +490,17 @@ public: return b3Vector3(vl); #else - return - b3MakeVector3( m_floats[0] + (v.m_floats[0] - m_floats[0]) * t, - m_floats[1] + (v.m_floats[1] - m_floats[1]) * t, - m_floats[2] + (v.m_floats[2] - m_floats[2]) * t); + return b3MakeVector3(m_floats[0] + (v.m_floats[0] - m_floats[0]) * t, + m_floats[1] + (v.m_floats[1] - m_floats[1]) * t, + m_floats[2] + (v.m_floats[2] - m_floats[2]) * t); #endif } - /**@brief Elementwise multiply this vector by the other + /**@brief Elementwise multiply this vector by the other * @param v The other vector */ B3_FORCE_INLINE b3Vector3& operator*=(const b3Vector3& v) { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) mVec128 = _mm_mul_ps(mVec128, v.mVec128); #elif defined(B3_USE_NEON) mVec128 = vmulq_f32(mVec128, v.mVec128); @@ -523,53 +512,53 @@ public: return *this; } - /**@brief Return the x value */ - B3_FORCE_INLINE const b3Scalar& getX() const { return m_floats[0]; } - /**@brief Return the y value */ - B3_FORCE_INLINE const b3Scalar& getY() const { return m_floats[1]; } - /**@brief Return the z value */ - B3_FORCE_INLINE const b3Scalar& getZ() const { return m_floats[2]; } -/**@brief Return the w value */ - B3_FORCE_INLINE const b3Scalar& getW() const { return m_floats[3]; } + /**@brief Return the x value */ + B3_FORCE_INLINE const b3Scalar& getX() const { return m_floats[0]; } + /**@brief Return the y value */ + B3_FORCE_INLINE const b3Scalar& getY() const { return m_floats[1]; } + /**@brief Return the z value */ + B3_FORCE_INLINE const b3Scalar& getZ() const { return m_floats[2]; } + /**@brief Return the w value */ + B3_FORCE_INLINE const b3Scalar& getW() const { return m_floats[3]; } - /**@brief Set the x value */ - B3_FORCE_INLINE void setX(b3Scalar _x) { m_floats[0] = _x;}; - /**@brief Set the y value */ - B3_FORCE_INLINE void setY(b3Scalar _y) { m_floats[1] = _y;}; - /**@brief Set the z value */ - B3_FORCE_INLINE void setZ(b3Scalar _z) { m_floats[2] = _z;}; - /**@brief Set the w value */ - B3_FORCE_INLINE void setW(b3Scalar _w) { m_floats[3] = _w;}; + /**@brief Set the x value */ + B3_FORCE_INLINE void setX(b3Scalar _x) { m_floats[0] = _x; }; + /**@brief Set the y value */ + B3_FORCE_INLINE void setY(b3Scalar _y) { m_floats[1] = _y; }; + /**@brief Set the z value */ + B3_FORCE_INLINE void setZ(b3Scalar _z) { m_floats[2] = _z; }; + /**@brief Set the w value */ + B3_FORCE_INLINE void setW(b3Scalar _w) { m_floats[3] = _w; }; //B3_FORCE_INLINE b3Scalar& operator[](int i) { return (&m_floats[0])[i]; } //B3_FORCE_INLINE const b3Scalar& operator[](int i) const { return (&m_floats[0])[i]; } ///operator b3Scalar*() replaces operator[], using implicit conversion. We added operator != and operator == to avoid pointer comparisons. - B3_FORCE_INLINE operator b3Scalar *() { return &m_floats[0]; } - B3_FORCE_INLINE operator const b3Scalar *() const { return &m_floats[0]; } + B3_FORCE_INLINE operator b3Scalar*() { return &m_floats[0]; } + B3_FORCE_INLINE operator const b3Scalar*() const { return &m_floats[0]; } - B3_FORCE_INLINE bool operator==(const b3Vector3& other) const + B3_FORCE_INLINE bool operator==(const b3Vector3& other) const { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) - return (0xf == _mm_movemask_ps((__m128)_mm_cmpeq_ps(mVec128, other.mVec128))); +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) + return (0xf == _mm_movemask_ps((__m128)_mm_cmpeq_ps(mVec128, other.mVec128))); #else - return ((m_floats[3]==other.m_floats[3]) && - (m_floats[2]==other.m_floats[2]) && - (m_floats[1]==other.m_floats[1]) && - (m_floats[0]==other.m_floats[0])); + return ((m_floats[3] == other.m_floats[3]) && + (m_floats[2] == other.m_floats[2]) && + (m_floats[1] == other.m_floats[1]) && + (m_floats[0] == other.m_floats[0])); #endif } - B3_FORCE_INLINE bool operator!=(const b3Vector3& other) const + B3_FORCE_INLINE bool operator!=(const b3Vector3& other) const { return !(*this == other); } - /**@brief Set each element to the max of the current values and the values of another b3Vector3 + /**@brief Set each element to the max of the current values and the values of another b3Vector3 * @param other The other b3Vector3 to compare with */ - B3_FORCE_INLINE void setMax(const b3Vector3& other) + B3_FORCE_INLINE void setMax(const b3Vector3& other) { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) mVec128 = _mm_max_ps(mVec128, other.mVec128); #elif defined(B3_USE_NEON) mVec128 = vmaxq_f32(mVec128, other.mVec128); @@ -581,12 +570,12 @@ public: #endif } - /**@brief Set each element to the min of the current values and the values of another b3Vector3 + /**@brief Set each element to the min of the current values and the values of another b3Vector3 * @param other The other b3Vector3 to compare with */ - B3_FORCE_INLINE void setMin(const b3Vector3& other) + B3_FORCE_INLINE void setMin(const b3Vector3& other) { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) mVec128 = _mm_min_ps(mVec128, other.mVec128); #elif defined(B3_USE_NEON) mVec128 = vminq_f32(mVec128, other.mVec128); @@ -598,46 +587,46 @@ public: #endif } - B3_FORCE_INLINE void setValue(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z) + B3_FORCE_INLINE void setValue(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z) { - m_floats[0]=_x; - m_floats[1]=_y; - m_floats[2]=_z; + m_floats[0] = _x; + m_floats[1] = _y; + m_floats[2] = _z; m_floats[3] = b3Scalar(0.f); } - void getSkewSymmetricMatrix(b3Vector3* v0,b3Vector3* v1,b3Vector3* v2) const + void getSkewSymmetricMatrix(b3Vector3 * v0, b3Vector3 * v1, b3Vector3 * v2) const { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) - __m128 V = _mm_and_ps(mVec128, b3vFFF0fMask); + __m128 V = _mm_and_ps(mVec128, b3vFFF0fMask); __m128 V0 = _mm_xor_ps(b3vMzeroMask, V); __m128 V2 = _mm_movelh_ps(V0, V); __m128 V1 = _mm_shuffle_ps(V, V0, 0xCE); - V0 = _mm_shuffle_ps(V0, V, 0xDB); + V0 = _mm_shuffle_ps(V0, V, 0xDB); V2 = _mm_shuffle_ps(V2, V, 0xF9); v0->mVec128 = V0; v1->mVec128 = V1; v2->mVec128 = V2; #else - v0->setValue(0. ,-getZ() ,getY()); - v1->setValue(getZ() ,0. ,-getX()); - v2->setValue(-getY() ,getX() ,0.); + v0->setValue(0., -getZ(), getY()); + v1->setValue(getZ(), 0., -getX()); + v2->setValue(-getY(), getX(), 0.); #endif } void setZero() { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) mVec128 = (__m128)_mm_xor_ps(mVec128, mVec128); #elif defined(B3_USE_NEON) int32x4_t vi = vdupq_n_s32(0); mVec128 = vreinterpretq_f32_s32(vi); #else - setValue(b3Scalar(0.),b3Scalar(0.),b3Scalar(0.)); + setValue(b3Scalar(0.), b3Scalar(0.), b3Scalar(0.)); #endif } @@ -651,76 +640,76 @@ public: return length2() < B3_EPSILON; } - B3_FORCE_INLINE void serialize(struct b3Vector3Data& dataOut) const; + B3_FORCE_INLINE void serialize(struct b3Vector3Data & dataOut) const; - B3_FORCE_INLINE void deSerialize(const struct b3Vector3Data& dataIn); + B3_FORCE_INLINE void deSerialize(const struct b3Vector3Data& dataIn); - B3_FORCE_INLINE void serializeFloat(struct b3Vector3FloatData& dataOut) const; + B3_FORCE_INLINE void serializeFloat(struct b3Vector3FloatData & dataOut) const; - B3_FORCE_INLINE void deSerializeFloat(const struct b3Vector3FloatData& dataIn); + B3_FORCE_INLINE void deSerializeFloat(const struct b3Vector3FloatData& dataIn); - B3_FORCE_INLINE void serializeDouble(struct b3Vector3DoubleData& dataOut) const; + B3_FORCE_INLINE void serializeDouble(struct b3Vector3DoubleData & dataOut) const; - B3_FORCE_INLINE void deSerializeDouble(const struct b3Vector3DoubleData& dataIn); + B3_FORCE_INLINE void deSerializeDouble(const struct b3Vector3DoubleData& dataIn); - /**@brief returns index of maximum dot product between this and vectors in array[] + /**@brief returns index of maximum dot product between this and vectors in array[] * @param array The other vectors * @param array_count The number of other vectors * @param dotOut The maximum dot product */ - B3_FORCE_INLINE long maxDot( const b3Vector3 *array, long array_count, b3Scalar &dotOut ) const; + B3_FORCE_INLINE long maxDot(const b3Vector3* array, long array_count, b3Scalar& dotOut) const; - /**@brief returns index of minimum dot product between this and vectors in array[] + /**@brief returns index of minimum dot product between this and vectors in array[] * @param array The other vectors * @param array_count The number of other vectors * @param dotOut The minimum dot product */ - B3_FORCE_INLINE long minDot( const b3Vector3 *array, long array_count, b3Scalar &dotOut ) const; + B3_FORCE_INLINE long minDot(const b3Vector3* array, long array_count, b3Scalar& dotOut) const; - /* create a vector as b3Vector3( this->dot( b3Vector3 v0 ), this->dot( b3Vector3 v1), this->dot( b3Vector3 v2 )) */ - B3_FORCE_INLINE b3Vector3 dot3( const b3Vector3 &v0, const b3Vector3 &v1, const b3Vector3 &v2 ) const - { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) + /* create a vector as b3Vector3( this->dot( b3Vector3 v0 ), this->dot( b3Vector3 v1), this->dot( b3Vector3 v2 )) */ + B3_FORCE_INLINE b3Vector3 dot3(const b3Vector3& v0, const b3Vector3& v1, const b3Vector3& v2) const + { +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) - __m128 a0 = _mm_mul_ps( v0.mVec128, this->mVec128 ); - __m128 a1 = _mm_mul_ps( v1.mVec128, this->mVec128 ); - __m128 a2 = _mm_mul_ps( v2.mVec128, this->mVec128 ); - __m128 b0 = _mm_unpacklo_ps( a0, a1 ); - __m128 b1 = _mm_unpackhi_ps( a0, a1 ); - __m128 b2 = _mm_unpacklo_ps( a2, _mm_setzero_ps() ); - __m128 r = _mm_movelh_ps( b0, b2 ); - r = _mm_add_ps( r, _mm_movehl_ps( b2, b0 )); - a2 = _mm_and_ps( a2, b3vxyzMaskf); - r = _mm_add_ps( r, b3CastdTo128f (_mm_move_sd( b3CastfTo128d(a2), b3CastfTo128d(b1) ))); - return b3MakeVector3(r); + __m128 a0 = _mm_mul_ps(v0.mVec128, this->mVec128); + __m128 a1 = _mm_mul_ps(v1.mVec128, this->mVec128); + __m128 a2 = _mm_mul_ps(v2.mVec128, this->mVec128); + __m128 b0 = _mm_unpacklo_ps(a0, a1); + __m128 b1 = _mm_unpackhi_ps(a0, a1); + __m128 b2 = _mm_unpacklo_ps(a2, _mm_setzero_ps()); + __m128 r = _mm_movelh_ps(b0, b2); + r = _mm_add_ps(r, _mm_movehl_ps(b2, b0)); + a2 = _mm_and_ps(a2, b3vxyzMaskf); + r = _mm_add_ps(r, b3CastdTo128f(_mm_move_sd(b3CastfTo128d(a2), b3CastfTo128d(b1)))); + return b3MakeVector3(r); #elif defined(B3_USE_NEON) - static const uint32x4_t xyzMask = (const uint32x4_t){ -1, -1, -1, 0 }; - float32x4_t a0 = vmulq_f32( v0.mVec128, this->mVec128); - float32x4_t a1 = vmulq_f32( v1.mVec128, this->mVec128); - float32x4_t a2 = vmulq_f32( v2.mVec128, this->mVec128); - float32x2x2_t zLo = vtrn_f32( vget_high_f32(a0), vget_high_f32(a1)); - a2 = (float32x4_t) vandq_u32((uint32x4_t) a2, xyzMask ); - float32x2_t b0 = vadd_f32( vpadd_f32( vget_low_f32(a0), vget_low_f32(a1)), zLo.val[0] ); - float32x2_t b1 = vpadd_f32( vpadd_f32( vget_low_f32(a2), vget_high_f32(a2)), vdup_n_f32(0.0f)); - return b3Vector3( vcombine_f32(b0, b1) ); + static const uint32x4_t xyzMask = (const uint32x4_t){-1, -1, -1, 0}; + float32x4_t a0 = vmulq_f32(v0.mVec128, this->mVec128); + float32x4_t a1 = vmulq_f32(v1.mVec128, this->mVec128); + float32x4_t a2 = vmulq_f32(v2.mVec128, this->mVec128); + float32x2x2_t zLo = vtrn_f32(vget_high_f32(a0), vget_high_f32(a1)); + a2 = (float32x4_t)vandq_u32((uint32x4_t)a2, xyzMask); + float32x2_t b0 = vadd_f32(vpadd_f32(vget_low_f32(a0), vget_low_f32(a1)), zLo.val[0]); + float32x2_t b1 = vpadd_f32(vpadd_f32(vget_low_f32(a2), vget_high_f32(a2)), vdup_n_f32(0.0f)); + return b3Vector3(vcombine_f32(b0, b1)); #else - return b3MakeVector3( dot(v0), dot(v1), dot(v2)); + return b3MakeVector3(dot(v0), dot(v1), dot(v2)); #endif - } + } }; /**@brief Return the sum of two vectors (Point symantics)*/ B3_FORCE_INLINE b3Vector3 operator+(const b3Vector3& v1, const b3Vector3& v2) { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) return b3MakeVector3(_mm_add_ps(v1.mVec128, v2.mVec128)); #elif defined(B3_USE_NEON) return b3MakeVector3(vaddq_f32(v1.mVec128, v2.mVec128)); #else return b3MakeVector3( - v1.m_floats[0] + v2.m_floats[0], - v1.m_floats[1] + v2.m_floats[1], - v1.m_floats[2] + v2.m_floats[2]); + v1.m_floats[0] + v2.m_floats[0], + v1.m_floats[1] + v2.m_floats[1], + v1.m_floats[2] + v2.m_floats[2]); #endif } @@ -728,15 +717,15 @@ operator+(const b3Vector3& v1, const b3Vector3& v2) B3_FORCE_INLINE b3Vector3 operator*(const b3Vector3& v1, const b3Vector3& v2) { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) return b3MakeVector3(_mm_mul_ps(v1.mVec128, v2.mVec128)); #elif defined(B3_USE_NEON) return b3MakeVector3(vmulq_f32(v1.mVec128, v2.mVec128)); #else return b3MakeVector3( - v1.m_floats[0] * v2.m_floats[0], - v1.m_floats[1] * v2.m_floats[1], - v1.m_floats[2] * v2.m_floats[2]); + v1.m_floats[0] * v2.m_floats[0], + v1.m_floats[1] * v2.m_floats[1], + v1.m_floats[2] * v2.m_floats[2]); #endif } @@ -744,7 +733,7 @@ operator*(const b3Vector3& v1, const b3Vector3& v2) B3_FORCE_INLINE b3Vector3 operator-(const b3Vector3& v1, const b3Vector3& v2) { -#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) // without _mm_and_ps this code causes slowdown in Concave moving __m128 r = _mm_sub_ps(v1.mVec128, v2.mVec128); @@ -754,9 +743,9 @@ operator-(const b3Vector3& v1, const b3Vector3& v2) return b3MakeVector3((float32x4_t)vandq_s32((int32x4_t)r, b3vFFF0Mask)); #else return b3MakeVector3( - v1.m_floats[0] - v2.m_floats[0], - v1.m_floats[1] - v2.m_floats[1], - v1.m_floats[2] - v2.m_floats[2]); + v1.m_floats[0] - v2.m_floats[0], + v1.m_floats[1] - v2.m_floats[1], + v1.m_floats[2] - v2.m_floats[2]); #endif } @@ -764,7 +753,7 @@ operator-(const b3Vector3& v1, const b3Vector3& v2) B3_FORCE_INLINE b3Vector3 operator-(const b3Vector3& v) { -#if (defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE)) +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) __m128 r = _mm_xor_ps(v.mVec128, b3vMzeroMask); return b3MakeVector3(_mm_and_ps(r, b3vFFF0fMask)); #elif defined(B3_USE_NEON) @@ -778,9 +767,9 @@ operator-(const b3Vector3& v) B3_FORCE_INLINE b3Vector3 operator*(const b3Vector3& v, const b3Scalar& s) { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) - __m128 vs = _mm_load_ss(&s); // (S 0 0 0) - vs = b3_pshufd_ps(vs, 0x80); // (S S S 0.0) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) + __m128 vs = _mm_load_ss(&s); // (S 0 0 0) + vs = b3_pshufd_ps(vs, 0x80); // (S S S 0.0) return b3MakeVector3(_mm_mul_ps(v.mVec128, vs)); #elif defined(B3_USE_NEON) float32x4_t r = vmulq_n_f32(v.mVec128, s); @@ -802,7 +791,7 @@ B3_FORCE_INLINE b3Vector3 operator/(const b3Vector3& v, const b3Scalar& s) { b3FullAssert(s != b3Scalar(0.0)); -#if 0 //defined(B3_USE_SSE_IN_API) +#if 0 //defined(B3_USE_SSE_IN_API) // this code is not faster ! __m128 vs = _mm_load_ss(&s); vs = _mm_div_ss(b3v1110, vs); @@ -818,7 +807,7 @@ operator/(const b3Vector3& v, const b3Scalar& s) B3_FORCE_INLINE b3Vector3 operator/(const b3Vector3& v1, const b3Vector3& v2) { -#if (defined(B3_USE_SSE_IN_API)&& defined (B3_USE_SSE)) +#if (defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE)) __m128 vec = _mm_div_ps(v1.mVec128, v2.mVec128); vec = _mm_and_ps(vec, b3vFFF0fMask); return b3MakeVector3(vec); @@ -828,19 +817,19 @@ operator/(const b3Vector3& v1, const b3Vector3& v2) x = v1.mVec128; y = v2.mVec128; - v = vrecpeq_f32(y); // v ~ 1/y - m = vrecpsq_f32(y, v); // m = (2-v*y) - v = vmulq_f32(v, m); // vv = v*m ~~ 1/y - m = vrecpsq_f32(y, v); // mm = (2-vv*y) - v = vmulq_f32(v, x); // x*vv - v = vmulq_f32(v, m); // (x*vv)*(2-vv*y) = x*(vv(2-vv*y)) ~~~ x/y + v = vrecpeq_f32(y); // v ~ 1/y + m = vrecpsq_f32(y, v); // m = (2-v*y) + v = vmulq_f32(v, m); // vv = v*m ~~ 1/y + m = vrecpsq_f32(y, v); // mm = (2-vv*y) + v = vmulq_f32(v, x); // x*vv + v = vmulq_f32(v, m); // (x*vv)*(2-vv*y) = x*(vv(2-vv*y)) ~~~ x/y return b3Vector3(v); #else return b3MakeVector3( - v1.m_floats[0] / v2.m_floats[0], - v1.m_floats[1] / v2.m_floats[1], - v1.m_floats[2] / v2.m_floats[2]); + v1.m_floats[0] / v2.m_floats[0], + v1.m_floats[1] / v2.m_floats[1], + v1.m_floats[2] / v2.m_floats[2]); #endif } @@ -851,7 +840,6 @@ b3Dot(const b3Vector3& v1, const b3Vector3& v2) return v1.dot(v2); } - /**@brief Return the distance squared between two vectors */ B3_FORCE_INLINE b3Scalar b3Distance2(const b3Vector3& v1, const b3Vector3& v2) @@ -859,7 +847,6 @@ b3Distance2(const b3Vector3& v1, const b3Vector3& v2) return v1.distance2(v2); } - /**@brief Return the distance between two vectors */ B3_FORCE_INLINE b3Scalar b3Distance(const b3Vector3& v1, const b3Vector3& v2) @@ -897,8 +884,6 @@ b3Lerp(const b3Vector3& v1, const b3Vector3& v2, const b3Scalar& t) return v1.lerp(v2, t); } - - B3_FORCE_INLINE b3Scalar b3Vector3::distance2(const b3Vector3& v) const { return (v - *this).length2(); @@ -911,7 +896,7 @@ B3_FORCE_INLINE b3Scalar b3Vector3::distance(const b3Vector3& v) const B3_FORCE_INLINE b3Vector3 b3Vector3::normalized() const { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) b3Vector3 norm = *this; return norm.normalize(); @@ -920,143 +905,136 @@ B3_FORCE_INLINE b3Vector3 b3Vector3::normalized() const #endif } -B3_FORCE_INLINE b3Vector3 b3Vector3::rotate( const b3Vector3& wAxis, const b3Scalar _angle ) const +B3_FORCE_INLINE b3Vector3 b3Vector3::rotate(const b3Vector3& wAxis, const b3Scalar _angle) const { // wAxis must be a unit lenght vector -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) - __m128 O = _mm_mul_ps(wAxis.mVec128, mVec128); - b3Scalar ssin = b3Sin( _angle ); - __m128 C = wAxis.cross( b3MakeVector3(mVec128) ).mVec128; + __m128 O = _mm_mul_ps(wAxis.mVec128, mVec128); + b3Scalar ssin = b3Sin(_angle); + __m128 C = wAxis.cross(b3MakeVector3(mVec128)).mVec128; O = _mm_and_ps(O, b3vFFF0fMask); - b3Scalar scos = b3Cos( _angle ); + b3Scalar scos = b3Cos(_angle); - __m128 vsin = _mm_load_ss(&ssin); // (S 0 0 0) - __m128 vcos = _mm_load_ss(&scos); // (S 0 0 0) + __m128 vsin = _mm_load_ss(&ssin); // (S 0 0 0) + __m128 vcos = _mm_load_ss(&scos); // (S 0 0 0) - __m128 Y = b3_pshufd_ps(O, 0xC9); // (Y Z X 0) - __m128 Z = b3_pshufd_ps(O, 0xD2); // (Z X Y 0) + __m128 Y = b3_pshufd_ps(O, 0xC9); // (Y Z X 0) + __m128 Z = b3_pshufd_ps(O, 0xD2); // (Z X Y 0) O = _mm_add_ps(O, Y); - vsin = b3_pshufd_ps(vsin, 0x80); // (S S S 0) + vsin = b3_pshufd_ps(vsin, 0x80); // (S S S 0) O = _mm_add_ps(O, Z); - vcos = b3_pshufd_ps(vcos, 0x80); // (S S S 0) + vcos = b3_pshufd_ps(vcos, 0x80); // (S S S 0) - vsin = vsin * C; + vsin = vsin * C; O = O * wAxis.mVec128; __m128 X = mVec128 - O; - O = O + vsin; + O = O + vsin; vcos = vcos * X; O = O + vcos; return b3MakeVector3(O); #else - b3Vector3 o = wAxis * wAxis.dot( *this ); + b3Vector3 o = wAxis * wAxis.dot(*this); b3Vector3 _x = *this - o; b3Vector3 _y; - _y = wAxis.cross( *this ); + _y = wAxis.cross(*this); - return ( o + _x * b3Cos( _angle ) + _y * b3Sin( _angle ) ); + return (o + _x * b3Cos(_angle) + _y * b3Sin(_angle)); #endif } -B3_FORCE_INLINE long b3Vector3::maxDot( const b3Vector3 *array, long array_count, b3Scalar &dotOut ) const +B3_FORCE_INLINE long b3Vector3::maxDot(const b3Vector3* array, long array_count, b3Scalar& dotOut) const { -#if defined (B3_USE_SSE) || defined (B3_USE_NEON) - #if defined _WIN32 || defined (B3_USE_SSE) - const long scalar_cutoff = 10; - long b3_maxdot_large( const float *array, const float *vec, unsigned long array_count, float *dotOut ); - #elif defined B3_USE_NEON - const long scalar_cutoff = 4; - extern long (*_maxdot_large)( const float *array, const float *vec, unsigned long array_count, float *dotOut ); - #endif - if( array_count < scalar_cutoff ) +#if defined(B3_USE_SSE) || defined(B3_USE_NEON) +#if defined _WIN32 || defined(B3_USE_SSE) + const long scalar_cutoff = 10; + long b3_maxdot_large(const float* array, const float* vec, unsigned long array_count, float* dotOut); +#elif defined B3_USE_NEON + const long scalar_cutoff = 4; + extern long (*_maxdot_large)(const float* array, const float* vec, unsigned long array_count, float* dotOut); +#endif + if (array_count < scalar_cutoff) #else -#endif//B3_USE_SSE || B3_USE_NEON - { - b3Scalar maxDot = -B3_INFINITY; - int i = 0; - int ptIndex = -1; - for( i = 0; i < array_count; i++ ) - { - b3Scalar dot = array[i].dot(*this); +#endif //B3_USE_SSE || B3_USE_NEON + { + b3Scalar maxDot = -B3_INFINITY; + int i = 0; + int ptIndex = -1; + for (i = 0; i < array_count; i++) + { + b3Scalar dot = array[i].dot(*this); - if( dot > maxDot ) - { - maxDot = dot; - ptIndex = i; - } - } + if (dot > maxDot) + { + maxDot = dot; + ptIndex = i; + } + } - b3Assert(ptIndex>=0); - if (ptIndex<0) + b3Assert(ptIndex >= 0); + if (ptIndex < 0) { ptIndex = 0; } - dotOut = maxDot; - return ptIndex; - } -#if defined (B3_USE_SSE) || defined (B3_USE_NEON) - return b3_maxdot_large( (float*) array, (float*) &m_floats[0], array_count, &dotOut ); + dotOut = maxDot; + return ptIndex; + } +#if defined(B3_USE_SSE) || defined(B3_USE_NEON) + return b3_maxdot_large((float*)array, (float*)&m_floats[0], array_count, &dotOut); #endif } -B3_FORCE_INLINE long b3Vector3::minDot( const b3Vector3 *array, long array_count, b3Scalar &dotOut ) const +B3_FORCE_INLINE long b3Vector3::minDot(const b3Vector3* array, long array_count, b3Scalar& dotOut) const { -#if defined (B3_USE_SSE) || defined (B3_USE_NEON) - #if defined B3_USE_SSE - const long scalar_cutoff = 10; - long b3_mindot_large( const float *array, const float *vec, unsigned long array_count, float *dotOut ); - #elif defined B3_USE_NEON - const long scalar_cutoff = 4; - extern long (*b3_mindot_large)( const float *array, const float *vec, unsigned long array_count, float *dotOut ); - #else - #error unhandled arch! - #endif +#if defined(B3_USE_SSE) || defined(B3_USE_NEON) +#if defined B3_USE_SSE + const long scalar_cutoff = 10; + long b3_mindot_large(const float* array, const float* vec, unsigned long array_count, float* dotOut); +#elif defined B3_USE_NEON + const long scalar_cutoff = 4; + extern long (*b3_mindot_large)(const float* array, const float* vec, unsigned long array_count, float* dotOut); +#else +#error unhandled arch! +#endif - if( array_count < scalar_cutoff ) -#endif//B3_USE_SSE || B3_USE_NEON - { - b3Scalar minDot = B3_INFINITY; - int i = 0; - int ptIndex = -1; + if (array_count < scalar_cutoff) +#endif //B3_USE_SSE || B3_USE_NEON + { + b3Scalar minDot = B3_INFINITY; + int i = 0; + int ptIndex = -1; - for( i = 0; i < array_count; i++ ) - { - b3Scalar dot = array[i].dot(*this); + for (i = 0; i < array_count; i++) + { + b3Scalar dot = array[i].dot(*this); - if( dot < minDot ) - { - minDot = dot; - ptIndex = i; - } - } + if (dot < minDot) + { + minDot = dot; + ptIndex = i; + } + } - dotOut = minDot; + dotOut = minDot; - return ptIndex; - } -#if defined (B3_USE_SSE) || defined (B3_USE_NEON) - return b3_mindot_large( (float*) array, (float*) &m_floats[0], array_count, &dotOut ); + return ptIndex; + } +#if defined(B3_USE_SSE) || defined(B3_USE_NEON) + return b3_mindot_large((float*)array, (float*)&m_floats[0], array_count, &dotOut); #endif } - class b3Vector4 : public b3Vector3 { public: - - - - - - B3_FORCE_INLINE b3Vector4 absolute4() const { -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) return b3MakeVector4(_mm_and_ps(mVec128, b3vAbsfMask)); #elif defined(B3_USE_NEON) return b3Vector4(vabsq_f32(mVec128)); @@ -1069,11 +1047,9 @@ public: #endif } + b3Scalar getW() const { return m_floats[3]; } - b3Scalar getW() const { return m_floats[3];} - - - B3_FORCE_INLINE int maxAxis4() const + B3_FORCE_INLINE int maxAxis4() const { int maxIndex = -1; b3Scalar maxVal = b3Scalar(-B3_LARGE_FLOAT); @@ -1090,7 +1066,7 @@ public: if (m_floats[2] > maxVal) { maxIndex = 2; - maxVal =m_floats[2]; + maxVal = m_floats[2]; } if (m_floats[3] > maxVal) { @@ -1100,7 +1076,6 @@ public: return maxIndex; } - B3_FORCE_INLINE int minAxis4() const { int minIndex = -1; @@ -1118,7 +1093,7 @@ public: if (m_floats[2] < minVal) { minIndex = 2; - minVal =m_floats[2]; + minVal = m_floats[2]; } if (m_floats[3] < minVal) { @@ -1129,216 +1104,200 @@ public: return minIndex; } - B3_FORCE_INLINE int closestAxis4() const { return absolute4().maxAxis4(); } - - - - /**@brief Set x,y,z and zero w + /**@brief Set x,y,z and zero w * @param x Value of x * @param y Value of y * @param z Value of z */ - -/* void getValue(b3Scalar *m) const + /* void getValue(b3Scalar *m) const { m[0] = m_floats[0]; m[1] = m_floats[1]; m[2] =m_floats[2]; } */ -/**@brief Set the values + /**@brief Set the values * @param x Value of x * @param y Value of y * @param z Value of z * @param w Value of w */ - B3_FORCE_INLINE void setValue(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z,const b3Scalar& _w) - { - m_floats[0]=_x; - m_floats[1]=_y; - m_floats[2]=_z; - m_floats[3]=_w; - } - - + B3_FORCE_INLINE void setValue(const b3Scalar& _x, const b3Scalar& _y, const b3Scalar& _z, const b3Scalar& _w) + { + m_floats[0] = _x; + m_floats[1] = _y; + m_floats[2] = _z; + m_floats[3] = _w; + } }; - ///b3SwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization -B3_FORCE_INLINE void b3SwapScalarEndian(const b3Scalar& sourceVal, b3Scalar& destVal) +B3_FORCE_INLINE void b3SwapScalarEndian(const b3Scalar& sourceVal, b3Scalar& destVal) { - #ifdef B3_USE_DOUBLE_PRECISION - unsigned char* dest = (unsigned char*) &destVal; - unsigned char* src = (unsigned char*) &sourceVal; +#ifdef B3_USE_DOUBLE_PRECISION + unsigned char* dest = (unsigned char*)&destVal; + unsigned char* src = (unsigned char*)&sourceVal; dest[0] = src[7]; - dest[1] = src[6]; - dest[2] = src[5]; - dest[3] = src[4]; - dest[4] = src[3]; - dest[5] = src[2]; - dest[6] = src[1]; - dest[7] = src[0]; + dest[1] = src[6]; + dest[2] = src[5]; + dest[3] = src[4]; + dest[4] = src[3]; + dest[5] = src[2]; + dest[6] = src[1]; + dest[7] = src[0]; #else - unsigned char* dest = (unsigned char*) &destVal; - unsigned char* src = (unsigned char*) &sourceVal; + unsigned char* dest = (unsigned char*)&destVal; + unsigned char* src = (unsigned char*)&sourceVal; dest[0] = src[3]; - dest[1] = src[2]; - dest[2] = src[1]; - dest[3] = src[0]; -#endif //B3_USE_DOUBLE_PRECISION + dest[1] = src[2]; + dest[2] = src[1]; + dest[3] = src[0]; +#endif //B3_USE_DOUBLE_PRECISION } ///b3SwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization -B3_FORCE_INLINE void b3SwapVector3Endian(const b3Vector3& sourceVec, b3Vector3& destVec) +B3_FORCE_INLINE void b3SwapVector3Endian(const b3Vector3& sourceVec, b3Vector3& destVec) { - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) { - b3SwapScalarEndian(sourceVec[i],destVec[i]); + b3SwapScalarEndian(sourceVec[i], destVec[i]); } - } ///b3UnSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization -B3_FORCE_INLINE void b3UnSwapVector3Endian(b3Vector3& vector) +B3_FORCE_INLINE void b3UnSwapVector3Endian(b3Vector3& vector) { - - b3Vector3 swappedVec; - for (int i=0;i<4;i++) + b3Vector3 swappedVec; + for (int i = 0; i < 4; i++) { - b3SwapScalarEndian(vector[i],swappedVec[i]); + b3SwapScalarEndian(vector[i], swappedVec[i]); } vector = swappedVec; } template -B3_FORCE_INLINE void b3PlaneSpace1 (const T& n, T& p, T& q) +B3_FORCE_INLINE void b3PlaneSpace1(const T& n, T& p, T& q) { - if (b3Fabs(n[2]) > B3_SQRT12) { - // choose p in y-z plane - b3Scalar a = n[1]*n[1] + n[2]*n[2]; - b3Scalar k = b3RecipSqrt (a); - p[0] = 0; - p[1] = -n[2]*k; - p[2] = n[1]*k; - // set q = n x p - q[0] = a*k; - q[1] = -n[0]*p[2]; - q[2] = n[0]*p[1]; - } - else { - // choose p in x-y plane - b3Scalar a = n[0]*n[0] + n[1]*n[1]; - b3Scalar k = b3RecipSqrt (a); - p[0] = -n[1]*k; - p[1] = n[0]*k; - p[2] = 0; - // set q = n x p - q[0] = -n[2]*p[1]; - q[1] = n[2]*p[0]; - q[2] = a*k; - } + if (b3Fabs(n[2]) > B3_SQRT12) + { + // choose p in y-z plane + b3Scalar a = n[1] * n[1] + n[2] * n[2]; + b3Scalar k = b3RecipSqrt(a); + p[0] = 0; + p[1] = -n[2] * k; + p[2] = n[1] * k; + // set q = n x p + q[0] = a * k; + q[1] = -n[0] * p[2]; + q[2] = n[0] * p[1]; + } + else + { + // choose p in x-y plane + b3Scalar a = n[0] * n[0] + n[1] * n[1]; + b3Scalar k = b3RecipSqrt(a); + p[0] = -n[1] * k; + p[1] = n[0] * k; + p[2] = 0; + // set q = n x p + q[0] = -n[2] * p[1]; + q[1] = n[2] * p[0]; + q[2] = a * k; + } } - -struct b3Vector3FloatData +struct b3Vector3FloatData { - float m_floats[4]; + float m_floats[4]; }; -struct b3Vector3DoubleData +struct b3Vector3DoubleData { - double m_floats[4]; - + double m_floats[4]; }; -B3_FORCE_INLINE void b3Vector3::serializeFloat(struct b3Vector3FloatData& dataOut) const +B3_FORCE_INLINE void b3Vector3::serializeFloat(struct b3Vector3FloatData& dataOut) const { ///could also do a memcpy, check if it is worth it - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) dataOut.m_floats[i] = float(m_floats[i]); } -B3_FORCE_INLINE void b3Vector3::deSerializeFloat(const struct b3Vector3FloatData& dataIn) +B3_FORCE_INLINE void b3Vector3::deSerializeFloat(const struct b3Vector3FloatData& dataIn) { - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) m_floats[i] = b3Scalar(dataIn.m_floats[i]); } - -B3_FORCE_INLINE void b3Vector3::serializeDouble(struct b3Vector3DoubleData& dataOut) const +B3_FORCE_INLINE void b3Vector3::serializeDouble(struct b3Vector3DoubleData& dataOut) const { ///could also do a memcpy, check if it is worth it - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) dataOut.m_floats[i] = double(m_floats[i]); } -B3_FORCE_INLINE void b3Vector3::deSerializeDouble(const struct b3Vector3DoubleData& dataIn) +B3_FORCE_INLINE void b3Vector3::deSerializeDouble(const struct b3Vector3DoubleData& dataIn) { - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) m_floats[i] = b3Scalar(dataIn.m_floats[i]); } - -B3_FORCE_INLINE void b3Vector3::serialize(struct b3Vector3Data& dataOut) const +B3_FORCE_INLINE void b3Vector3::serialize(struct b3Vector3Data& dataOut) const { ///could also do a memcpy, check if it is worth it - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) dataOut.m_floats[i] = m_floats[i]; } -B3_FORCE_INLINE void b3Vector3::deSerialize(const struct b3Vector3Data& dataIn) +B3_FORCE_INLINE void b3Vector3::deSerialize(const struct b3Vector3Data& dataIn) { - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) m_floats[i] = dataIn.m_floats[i]; } - - - -inline b3Vector3 b3MakeVector3(b3Scalar x,b3Scalar y,b3Scalar z) +inline b3Vector3 b3MakeVector3(b3Scalar x, b3Scalar y, b3Scalar z) { - b3Vector3 tmp; - tmp.setValue(x,y,z); + b3Vector3 tmp; + tmp.setValue(x, y, z); return tmp; } -inline b3Vector3 b3MakeVector3(b3Scalar x,b3Scalar y,b3Scalar z, b3Scalar w) +inline b3Vector3 b3MakeVector3(b3Scalar x, b3Scalar y, b3Scalar z, b3Scalar w) { - b3Vector3 tmp; - tmp.setValue(x,y,z); + b3Vector3 tmp; + tmp.setValue(x, y, z); tmp.w = w; return tmp; } -inline b3Vector4 b3MakeVector4(b3Scalar x,b3Scalar y,b3Scalar z,b3Scalar w) +inline b3Vector4 b3MakeVector4(b3Scalar x, b3Scalar y, b3Scalar z, b3Scalar w) { - b3Vector4 tmp; - tmp.setValue(x,y,z,w); + b3Vector4 tmp; + tmp.setValue(x, y, z, w); return tmp; } -#if defined(B3_USE_SSE_IN_API) && defined (B3_USE_SSE) +#if defined(B3_USE_SSE_IN_API) && defined(B3_USE_SSE) -inline b3Vector3 b3MakeVector3( b3SimdFloat4 v) +inline b3Vector3 b3MakeVector3(b3SimdFloat4 v) { - b3Vector3 tmp; - tmp.set128(v); - return tmp; + b3Vector3 tmp; + tmp.set128(v); + return tmp; } inline b3Vector4 b3MakeVector4(b3SimdFloat4 vec) { - b3Vector4 tmp; + b3Vector4 tmp; tmp.set128(vec); return tmp; } #endif - -#endif //B3_VECTOR3_H +#endif //B3_VECTOR3_H diff --git a/src/Bullet3Common/shared/b3Float4.h b/src/Bullet3Common/shared/b3Float4.h index 5e4b95bce..d8a9f4741 100644 --- a/src/Bullet3Common/shared/b3Float4.h +++ b/src/Bullet3Common/shared/b3Float4.h @@ -4,94 +4,87 @@ #include "Bullet3Common/shared/b3PlatformDefinitions.h" #ifdef __cplusplus - #include "Bullet3Common/b3Vector3.h" - #define b3Float4 b3Vector3 - #define b3Float4ConstArg const b3Vector3& - #define b3Dot3F4 b3Dot - #define b3Cross3 b3Cross - #define b3MakeFloat4 b3MakeVector3 - inline b3Vector3 b3Normalized(const b3Vector3& vec) - { - return vec.normalized(); - } - - inline b3Float4 b3FastNormalized3(b3Float4ConstArg v) - { - return v.normalized(); - } - - inline b3Float4 b3MaxFloat4 (const b3Float4& a, const b3Float4& b) - { - b3Float4 tmp = a; - tmp.setMax(b); - return tmp; - } - inline b3Float4 b3MinFloat4 (const b3Float4& a, const b3Float4& b) - { - b3Float4 tmp = a; - tmp.setMin(b); - return tmp; - } +#include "Bullet3Common/b3Vector3.h" +#define b3Float4 b3Vector3 +#define b3Float4ConstArg const b3Vector3& +#define b3Dot3F4 b3Dot +#define b3Cross3 b3Cross +#define b3MakeFloat4 b3MakeVector3 +inline b3Vector3 b3Normalized(const b3Vector3& vec) +{ + return vec.normalized(); +} +inline b3Float4 b3FastNormalized3(b3Float4ConstArg v) +{ + return v.normalized(); +} +inline b3Float4 b3MaxFloat4(const b3Float4& a, const b3Float4& b) +{ + b3Float4 tmp = a; + tmp.setMax(b); + return tmp; +} +inline b3Float4 b3MinFloat4(const b3Float4& a, const b3Float4& b) +{ + b3Float4 tmp = a; + tmp.setMin(b); + return tmp; +} #else - typedef float4 b3Float4; - #define b3Float4ConstArg const b3Float4 - #define b3MakeFloat4 (float4) - float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1) - { - float4 a1 = b3MakeFloat4(v0.xyz,0.f); - float4 b1 = b3MakeFloat4(v1.xyz,0.f); - return dot(a1, b1); - } - b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1) - { - float4 a1 = b3MakeFloat4(v0.xyz,0.f); - float4 b1 = b3MakeFloat4(v1.xyz,0.f); - return cross(a1, b1); - } - #define b3MinFloat4 min - #define b3MaxFloat4 max +typedef float4 b3Float4; +#define b3Float4ConstArg const b3Float4 +#define b3MakeFloat4 (float4) +float b3Dot3F4(b3Float4ConstArg v0, b3Float4ConstArg v1) +{ + float4 a1 = b3MakeFloat4(v0.xyz, 0.f); + float4 b1 = b3MakeFloat4(v1.xyz, 0.f); + return dot(a1, b1); +} +b3Float4 b3Cross3(b3Float4ConstArg v0, b3Float4ConstArg v1) +{ + float4 a1 = b3MakeFloat4(v0.xyz, 0.f); + float4 b1 = b3MakeFloat4(v1.xyz, 0.f); + return cross(a1, b1); +} +#define b3MinFloat4 min +#define b3MaxFloat4 max - #define b3Normalized(a) normalize(a) +#define b3Normalized(a) normalize(a) -#endif +#endif - - inline bool b3IsAlmostZero(b3Float4ConstArg v) { - if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) + if (b3Fabs(v.x) > 1e-6 || b3Fabs(v.y) > 1e-6 || b3Fabs(v.z) > 1e-6) return false; return true; } - -inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut ) +inline int b3MaxDot(b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut) { - float maxDot = -B3_INFINITY; - int i = 0; - int ptIndex = -1; - for( i = 0; i < vecLen; i++ ) - { - float dot = b3Dot3F4(vecArray[i],vec); - - if( dot > maxDot ) - { - maxDot = dot; - ptIndex = i; - } - } - b3Assert(ptIndex>=0); - if (ptIndex<0) + float maxDot = -B3_INFINITY; + int i = 0; + int ptIndex = -1; + for (i = 0; i < vecLen; i++) + { + float dot = b3Dot3F4(vecArray[i], vec); + + if (dot > maxDot) + { + maxDot = dot; + ptIndex = i; + } + } + b3Assert(ptIndex >= 0); + if (ptIndex < 0) { ptIndex = 0; } - *dotOut = maxDot; - return ptIndex; + *dotOut = maxDot; + return ptIndex; } - - -#endif //B3_FLOAT4_H +#endif //B3_FLOAT4_H diff --git a/src/Bullet3Common/shared/b3Int2.h b/src/Bullet3Common/shared/b3Int2.h index f1d01f81a..7b84de443 100644 --- a/src/Bullet3Common/shared/b3Int2.h +++ b/src/Bullet3Common/shared/b3Int2.h @@ -20,11 +20,10 @@ subject to the following restrictions: struct b3UnsignedInt2 { - union - { + union { struct { - unsigned int x,y; + unsigned int x, y; }; struct { @@ -35,11 +34,10 @@ struct b3UnsignedInt2 struct b3Int2 { - union - { + union { struct { - int x,y; + int x, y; }; struct { @@ -51,7 +49,8 @@ struct b3Int2 inline b3Int2 b3MakeInt2(int x, int y) { b3Int2 v; - v.s[0] = x; v.s[1] = y; + v.s[0] = x; + v.s[1] = y; return v; } #else @@ -60,5 +59,5 @@ inline b3Int2 b3MakeInt2(int x, int y) #define b3Int2 int2 #define b3MakeInt2 (int2) -#endif //__cplusplus +#endif //__cplusplus #endif \ No newline at end of file diff --git a/src/Bullet3Common/shared/b3Int4.h b/src/Bullet3Common/shared/b3Int4.h index aa02d6bee..f6a175424 100644 --- a/src/Bullet3Common/shared/b3Int4.h +++ b/src/Bullet3Common/shared/b3Int4.h @@ -5,16 +5,15 @@ #include "Bullet3Common/b3Scalar.h" - -B3_ATTRIBUTE_ALIGNED16(struct) b3UnsignedInt4 +B3_ATTRIBUTE_ALIGNED16(struct) +b3UnsignedInt4 { B3_DECLARE_ALIGNED_ALLOCATOR(); - union - { + union { struct { - unsigned int x,y,z,w; + unsigned int x, y, z, w; }; struct { @@ -23,15 +22,15 @@ B3_ATTRIBUTE_ALIGNED16(struct) b3UnsignedInt4 }; }; -B3_ATTRIBUTE_ALIGNED16(struct) b3Int4 +B3_ATTRIBUTE_ALIGNED16(struct) +b3Int4 { B3_DECLARE_ALIGNED_ALLOCATOR(); - union - { + union { struct { - int x,y,z,w; + int x, y, z, w; }; struct { @@ -43,26 +42,30 @@ B3_ATTRIBUTE_ALIGNED16(struct) b3Int4 B3_FORCE_INLINE b3Int4 b3MakeInt4(int x, int y, int z, int w = 0) { b3Int4 v; - v.s[0] = x; v.s[1] = y; v.s[2] = z; v.s[3] = w; + v.s[0] = x; + v.s[1] = y; + v.s[2] = z; + v.s[3] = w; return v; } B3_FORCE_INLINE b3UnsignedInt4 b3MakeUnsignedInt4(unsigned int x, unsigned int y, unsigned int z, unsigned int w = 0) { b3UnsignedInt4 v; - v.s[0] = x; v.s[1] = y; v.s[2] = z; v.s[3] = w; + v.s[0] = x; + v.s[1] = y; + v.s[2] = z; + v.s[3] = w; return v; } #else - #define b3UnsignedInt4 uint4 #define b3Int4 int4 #define b3MakeInt4 (int4) #define b3MakeUnsignedInt4 (uint4) +#endif //__cplusplus -#endif //__cplusplus - -#endif //B3_INT4_H +#endif //B3_INT4_H diff --git a/src/Bullet3Common/shared/b3Mat3x3.h b/src/Bullet3Common/shared/b3Mat3x3.h index 7b1fef32f..ce6482b5a 100644 --- a/src/Bullet3Common/shared/b3Mat3x3.h +++ b/src/Bullet3Common/shared/b3Mat3x3.h @@ -4,7 +4,6 @@ #include "Bullet3Common/shared/b3Quat.h" - #ifdef __cplusplus #include "Bullet3Common/b3Matrix3x3.h" @@ -22,43 +21,41 @@ inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg mat) return mat.absolute(); } -#define b3GetRow(m,row) m.getRow(row) +#define b3GetRow(m, row) m.getRow(row) -__inline -b3Float4 mtMul3(b3Float4ConstArg a, b3Mat3x3ConstArg b) +__inline b3Float4 mtMul3(b3Float4ConstArg a, b3Mat3x3ConstArg b) { - return b*a; + return b * a; } - #else typedef struct { b3Float4 m_row[3]; -}b3Mat3x3; +} b3Mat3x3; #define b3Mat3x3ConstArg const b3Mat3x3 -#define b3GetRow(m,row) (m.m_row[row]) +#define b3GetRow(m, row) (m.m_row[row]) inline b3Mat3x3 b3QuatGetRotationMatrix(b3Quat quat) { - b3Float4 quat2 = (b3Float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f); + b3Float4 quat2 = (b3Float4)(quat.x * quat.x, quat.y * quat.y, quat.z * quat.z, 0.f); b3Mat3x3 out; - out.m_row[0].x=1-2*quat2.y-2*quat2.z; - out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z; - out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y; + out.m_row[0].x = 1 - 2 * quat2.y - 2 * quat2.z; + out.m_row[0].y = 2 * quat.x * quat.y - 2 * quat.w * quat.z; + out.m_row[0].z = 2 * quat.x * quat.z + 2 * quat.w * quat.y; out.m_row[0].w = 0.f; - out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z; - out.m_row[1].y=1-2*quat2.x-2*quat2.z; - out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x; + out.m_row[1].x = 2 * quat.x * quat.y + 2 * quat.w * quat.z; + out.m_row[1].y = 1 - 2 * quat2.x - 2 * quat2.z; + out.m_row[1].z = 2 * quat.y * quat.z - 2 * quat.w * quat.x; out.m_row[1].w = 0.f; - out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y; - out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x; - out.m_row[2].z=1-2*quat2.x-2*quat2.y; + out.m_row[2].x = 2 * quat.x * quat.z - 2 * quat.w * quat.y; + out.m_row[2].y = 2 * quat.y * quat.z + 2 * quat.w * quat.x; + out.m_row[2].z = 1 - 2 * quat2.x - 2 * quat2.y; out.m_row[2].w = 0.f; return out; @@ -73,27 +70,19 @@ inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg matIn) return out; } +__inline b3Mat3x3 mtZero(); -__inline -b3Mat3x3 mtZero(); +__inline b3Mat3x3 mtIdentity(); -__inline -b3Mat3x3 mtIdentity(); +__inline b3Mat3x3 mtTranspose(b3Mat3x3 m); -__inline -b3Mat3x3 mtTranspose(b3Mat3x3 m); +__inline b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b); -__inline -b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b); +__inline b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b); -__inline -b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b); +__inline b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b); -__inline -b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b); - -__inline -b3Mat3x3 mtZero() +__inline b3Mat3x3 mtZero() { b3Mat3x3 m; m.m_row[0] = (b3Float4)(0.f); @@ -102,18 +91,16 @@ b3Mat3x3 mtZero() return m; } -__inline -b3Mat3x3 mtIdentity() +__inline b3Mat3x3 mtIdentity() { b3Mat3x3 m; - m.m_row[0] = (b3Float4)(1,0,0,0); - m.m_row[1] = (b3Float4)(0,1,0,0); - m.m_row[2] = (b3Float4)(0,0,1,0); + m.m_row[0] = (b3Float4)(1, 0, 0, 0); + m.m_row[1] = (b3Float4)(0, 1, 0, 0); + m.m_row[2] = (b3Float4)(0, 0, 1, 0); return m; } -__inline -b3Mat3x3 mtTranspose(b3Mat3x3 m) +__inline b3Mat3x3 mtTranspose(b3Mat3x3 m) { b3Mat3x3 out; out.m_row[0] = (b3Float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f); @@ -122,58 +109,49 @@ b3Mat3x3 mtTranspose(b3Mat3x3 m) return out; } -__inline -b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b) +__inline b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b) { b3Mat3x3 transB; - transB = mtTranspose( b ); + transB = mtTranspose(b); b3Mat3x3 ans; // why this doesn't run when 0ing in the for{} a.m_row[0].w = 0.f; a.m_row[1].w = 0.f; a.m_row[2].w = 0.f; - for(int i=0; i<3; i++) + for (int i = 0; i < 3; i++) { -// a.m_row[i].w = 0.f; - ans.m_row[i].x = b3Dot3F4(a.m_row[i],transB.m_row[0]); - ans.m_row[i].y = b3Dot3F4(a.m_row[i],transB.m_row[1]); - ans.m_row[i].z = b3Dot3F4(a.m_row[i],transB.m_row[2]); + // a.m_row[i].w = 0.f; + ans.m_row[i].x = b3Dot3F4(a.m_row[i], transB.m_row[0]); + ans.m_row[i].y = b3Dot3F4(a.m_row[i], transB.m_row[1]); + ans.m_row[i].z = b3Dot3F4(a.m_row[i], transB.m_row[2]); ans.m_row[i].w = 0.f; } return ans; } -__inline -b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b) +__inline b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b) { b3Float4 ans; - ans.x = b3Dot3F4( a.m_row[0], b ); - ans.y = b3Dot3F4( a.m_row[1], b ); - ans.z = b3Dot3F4( a.m_row[2], b ); + ans.x = b3Dot3F4(a.m_row[0], b); + ans.y = b3Dot3F4(a.m_row[1], b); + ans.z = b3Dot3F4(a.m_row[2], b); ans.w = 0.f; return ans; } -__inline -b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b) +__inline b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b) { b3Float4 colx = b3MakeFloat4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0); b3Float4 coly = b3MakeFloat4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0); b3Float4 colz = b3MakeFloat4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0); b3Float4 ans; - ans.x = b3Dot3F4( a, colx ); - ans.y = b3Dot3F4( a, coly ); - ans.z = b3Dot3F4( a, colz ); + ans.x = b3Dot3F4(a, colx); + ans.y = b3Dot3F4(a, coly); + ans.z = b3Dot3F4(a, colz); return ans; } - #endif - - - - - -#endif //B3_MAT3x3_H +#endif //B3_MAT3x3_H diff --git a/src/Bullet3Common/shared/b3PlatformDefinitions.h b/src/Bullet3Common/shared/b3PlatformDefinitions.h index 1c133fb08..b72bee931 100644 --- a/src/Bullet3Common/shared/b3PlatformDefinitions.h +++ b/src/Bullet3Common/shared/b3PlatformDefinitions.h @@ -8,18 +8,18 @@ struct MyTest #ifdef __cplusplus //#define b3ConstArray(a) const b3AlignedObjectArray& -#define b3ConstArray(a) const a* +#define b3ConstArray(a) const a * #define b3AtomicInc(a) ((*a)++) -inline int b3AtomicAdd (volatile int *p, int val) +inline int b3AtomicAdd(volatile int *p, int val) { int oldValue = *p; - int newValue = oldValue+val; + int newValue = oldValue + val; *p = newValue; return oldValue; } -#define __global +#define __global #define B3_STATIC static #else @@ -27,7 +27,7 @@ inline int b3AtomicAdd (volatile int *p, int val) #define B3_LARGE_FLOAT 1e18f #define B3_INFINITY 1e18f #define b3Assert(a) -#define b3ConstArray(a) __global const a* +#define b3ConstArray(a) __global const a * #define b3AtomicInc atomic_inc #define b3AtomicAdd atomic_add #define b3Fabs fabs diff --git a/src/Bullet3Common/shared/b3Quat.h b/src/Bullet3Common/shared/b3Quat.h index f262d5e08..940610c77 100644 --- a/src/Bullet3Common/shared/b3Quat.h +++ b/src/Bullet3Common/shared/b3Quat.h @@ -5,35 +5,34 @@ #include "Bullet3Common/shared/b3Float4.h" #ifdef __cplusplus - #include "Bullet3Common/b3Quaternion.h" - #include "Bullet3Common/b3Transform.h" +#include "Bullet3Common/b3Quaternion.h" +#include "Bullet3Common/b3Transform.h" - #define b3Quat b3Quaternion - #define b3QuatConstArg const b3Quaternion& - inline b3Quat b3QuatInverse(b3QuatConstArg orn) - { - return orn.inverse(); - } +#define b3Quat b3Quaternion +#define b3QuatConstArg const b3Quaternion& +inline b3Quat b3QuatInverse(b3QuatConstArg orn) +{ + return orn.inverse(); +} - inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation) - { - b3Transform tr; - tr.setOrigin(translation); - tr.setRotation(orientation); - return tr(point); - } +inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation) +{ + b3Transform tr; + tr.setOrigin(translation); + tr.setRotation(orientation); + return tr(point); +} #else - typedef float4 b3Quat; - #define b3QuatConstArg const b3Quat - - +typedef float4 b3Quat; +#define b3QuatConstArg const b3Quat + inline float4 b3FastNormalize4(float4 v) { - v = (float4)(v.xyz,0.f); + v = (float4)(v.xyz, 0.f); return fast_normalize(v); } - + inline b3Quat b3QuatMul(b3Quat a, b3Quat b); inline b3Quat b3QuatNormalized(b3QuatConstArg in); inline b3Quat b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec); @@ -43,20 +42,20 @@ inline b3Quat b3QuatInverse(b3QuatConstArg q); inline b3Quat b3QuatMul(b3QuatConstArg a, b3QuatConstArg b) { b3Quat ans; - ans = b3Cross3( a, b ); - ans += a.w*b+b.w*a; -// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z); - ans.w = a.w*b.w - b3Dot3F4(a, b); + ans = b3Cross3(a, b); + ans += a.w * b + b.w * a; + // ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z); + ans.w = a.w * b.w - b3Dot3F4(a, b); return ans; } inline b3Quat b3QuatNormalized(b3QuatConstArg in) { b3Quat q; - q=in; + q = in; //return b3FastNormalize4(in); float len = native_sqrt(dot(q, q)); - if(len > 0.f) + if (len > 0.f) { q *= 1.f / len; } @@ -69,15 +68,13 @@ inline b3Quat b3QuatNormalized(b3QuatConstArg in) } inline float4 b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec) { - b3Quat qInv = b3QuatInvert( q ); + b3Quat qInv = b3QuatInvert(q); float4 vcpy = vec; vcpy.w = 0.f; - float4 out = b3QuatMul(b3QuatMul(q,vcpy),qInv); + float4 out = b3QuatMul(b3QuatMul(q, vcpy), qInv); return out; } - - inline b3Quat b3QuatInverse(b3QuatConstArg q) { return (b3Quat)(-q.xyz, q.w); @@ -90,14 +87,14 @@ inline b3Quat b3QuatInvert(b3QuatConstArg q) inline float4 b3QuatInvRotate(b3QuatConstArg q, b3QuatConstArg vec) { - return b3QuatRotate( b3QuatInvert( q ), vec ); + return b3QuatRotate(b3QuatInvert(q), vec); } -inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation) +inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation) { - return b3QuatRotate( orientation, point ) + (translation); + return b3QuatRotate(orientation, point) + (translation); } - -#endif -#endif //B3_QUAT_H +#endif + +#endif //B3_QUAT_H diff --git a/src/Bullet3Dynamics/ConstraintSolver/b3ContactSolverInfo.h b/src/Bullet3Dynamics/ConstraintSolver/b3ContactSolverInfo.h index 7a12257b3..049c9116f 100644 --- a/src/Bullet3Dynamics/ConstraintSolver/b3ContactSolverInfo.h +++ b/src/Bullet3Dynamics/ConstraintSolver/b3ContactSolverInfo.h @@ -18,7 +18,7 @@ subject to the following restrictions: #include "Bullet3Common/b3Scalar.h" -enum b3SolverMode +enum b3SolverMode { B3_SOLVER_RANDMIZE_ORDER = 1, B3_SOLVER_FRICTION_SEPARATE = 2, @@ -34,45 +34,38 @@ enum b3SolverMode struct b3ContactSolverInfoData { - - - b3Scalar m_tau; - b3Scalar m_damping;//global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'. - b3Scalar m_friction; - b3Scalar m_timeStep; - b3Scalar m_restitution; - int m_numIterations; - b3Scalar m_maxErrorReduction; - b3Scalar m_sor; - b3Scalar m_erp;//used as Baumgarte factor - b3Scalar m_erp2;//used in Split Impulse - b3Scalar m_globalCfm;//constraint force mixing - int m_splitImpulse; - b3Scalar m_splitImpulsePenetrationThreshold; - b3Scalar m_splitImpulseTurnErp; - b3Scalar m_linearSlop; - b3Scalar m_warmstartingFactor; - - int m_solverMode; - int m_restingContactRestitutionThreshold; - int m_minimumSolverBatchSize; - b3Scalar m_maxGyroscopicForce; - b3Scalar m_singleAxisRollingFrictionThreshold; - + b3Scalar m_tau; + b3Scalar m_damping; //global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'. + b3Scalar m_friction; + b3Scalar m_timeStep; + b3Scalar m_restitution; + int m_numIterations; + b3Scalar m_maxErrorReduction; + b3Scalar m_sor; + b3Scalar m_erp; //used as Baumgarte factor + b3Scalar m_erp2; //used in Split Impulse + b3Scalar m_globalCfm; //constraint force mixing + int m_splitImpulse; + b3Scalar m_splitImpulsePenetrationThreshold; + b3Scalar m_splitImpulseTurnErp; + b3Scalar m_linearSlop; + b3Scalar m_warmstartingFactor; + int m_solverMode; + int m_restingContactRestitutionThreshold; + int m_minimumSolverBatchSize; + b3Scalar m_maxGyroscopicForce; + b3Scalar m_singleAxisRollingFrictionThreshold; }; struct b3ContactSolverInfo : public b3ContactSolverInfoData { - - - inline b3ContactSolverInfo() { m_tau = b3Scalar(0.6); m_damping = b3Scalar(1.0); m_friction = b3Scalar(0.3); - m_timeStep = b3Scalar(1.f/60.f); + m_timeStep = b3Scalar(1.f / 60.f); m_restitution = b3Scalar(0.); m_maxErrorReduction = b3Scalar(20.); m_numIterations = 10; @@ -84,76 +77,73 @@ struct b3ContactSolverInfo : public b3ContactSolverInfoData m_splitImpulsePenetrationThreshold = -.04f; m_splitImpulseTurnErp = 0.1f; m_linearSlop = b3Scalar(0.0); - m_warmstartingFactor=b3Scalar(0.85); + m_warmstartingFactor = b3Scalar(0.85); //m_solverMode = B3_SOLVER_USE_WARMSTARTING | B3_SOLVER_SIMD | B3_SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION|B3_SOLVER_USE_2_FRICTION_DIRECTIONS|B3_SOLVER_ENABLE_FRICTION_DIRECTION_CACHING;// | B3_SOLVER_RANDMIZE_ORDER; - m_solverMode = B3_SOLVER_USE_WARMSTARTING | B3_SOLVER_SIMD;// | B3_SOLVER_RANDMIZE_ORDER; - m_restingContactRestitutionThreshold = 2;//unused as of 2.81 - m_minimumSolverBatchSize = 128; //try to combine islands until the amount of constraints reaches this limit - m_maxGyroscopicForce = 100.f; ///only used to clamp forces for bodies that have their B3_ENABLE_GYROPSCOPIC_FORCE flag set (using b3RigidBody::setFlag) - m_singleAxisRollingFrictionThreshold = 1e30f;///if the velocity is above this threshold, it will use a single constraint row (axis), otherwise 3 rows. + m_solverMode = B3_SOLVER_USE_WARMSTARTING | B3_SOLVER_SIMD; // | B3_SOLVER_RANDMIZE_ORDER; + m_restingContactRestitutionThreshold = 2; //unused as of 2.81 + m_minimumSolverBatchSize = 128; //try to combine islands until the amount of constraints reaches this limit + m_maxGyroscopicForce = 100.f; ///only used to clamp forces for bodies that have their B3_ENABLE_GYROPSCOPIC_FORCE flag set (using b3RigidBody::setFlag) + m_singleAxisRollingFrictionThreshold = 1e30f; ///if the velocity is above this threshold, it will use a single constraint row (axis), otherwise 3 rows. } }; ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 struct b3ContactSolverInfoDoubleData { - double m_tau; - double m_damping;//global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'. - double m_friction; - double m_timeStep; - double m_restitution; - double m_maxErrorReduction; - double m_sor; - double m_erp;//used as Baumgarte factor - double m_erp2;//used in Split Impulse - double m_globalCfm;//constraint force mixing - double m_splitImpulsePenetrationThreshold; - double m_splitImpulseTurnErp; - double m_linearSlop; - double m_warmstartingFactor; - double m_maxGyroscopicForce; - double m_singleAxisRollingFrictionThreshold; - - int m_numIterations; - int m_solverMode; - int m_restingContactRestitutionThreshold; - int m_minimumSolverBatchSize; - int m_splitImpulse; - char m_padding[4]; + double m_tau; + double m_damping; //global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'. + double m_friction; + double m_timeStep; + double m_restitution; + double m_maxErrorReduction; + double m_sor; + double m_erp; //used as Baumgarte factor + double m_erp2; //used in Split Impulse + double m_globalCfm; //constraint force mixing + double m_splitImpulsePenetrationThreshold; + double m_splitImpulseTurnErp; + double m_linearSlop; + double m_warmstartingFactor; + double m_maxGyroscopicForce; + double m_singleAxisRollingFrictionThreshold; + int m_numIterations; + int m_solverMode; + int m_restingContactRestitutionThreshold; + int m_minimumSolverBatchSize; + int m_splitImpulse; + char m_padding[4]; }; ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 struct b3ContactSolverInfoFloatData { - float m_tau; - float m_damping;//global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'. - float m_friction; - float m_timeStep; + float m_tau; + float m_damping; //global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'. + float m_friction; + float m_timeStep; - float m_restitution; - float m_maxErrorReduction; - float m_sor; - float m_erp;//used as Baumgarte factor + float m_restitution; + float m_maxErrorReduction; + float m_sor; + float m_erp; //used as Baumgarte factor - float m_erp2;//used in Split Impulse - float m_globalCfm;//constraint force mixing - float m_splitImpulsePenetrationThreshold; - float m_splitImpulseTurnErp; + float m_erp2; //used in Split Impulse + float m_globalCfm; //constraint force mixing + float m_splitImpulsePenetrationThreshold; + float m_splitImpulseTurnErp; - float m_linearSlop; - float m_warmstartingFactor; - float m_maxGyroscopicForce; - float m_singleAxisRollingFrictionThreshold; + float m_linearSlop; + float m_warmstartingFactor; + float m_maxGyroscopicForce; + float m_singleAxisRollingFrictionThreshold; - int m_numIterations; - int m_solverMode; - int m_restingContactRestitutionThreshold; - int m_minimumSolverBatchSize; + int m_numIterations; + int m_solverMode; + int m_restingContactRestitutionThreshold; + int m_minimumSolverBatchSize; - int m_splitImpulse; - char m_padding[4]; + int m_splitImpulse; + char m_padding[4]; }; - - -#endif //B3_CONTACT_SOLVER_INFO +#endif //B3_CONTACT_SOLVER_INFO diff --git a/src/Bullet3Dynamics/ConstraintSolver/b3FixedConstraint.cpp b/src/Bullet3Dynamics/ConstraintSolver/b3FixedConstraint.cpp index 5e11e7493..ace4b1838 100644 --- a/src/Bullet3Dynamics/ConstraintSolver/b3FixedConstraint.cpp +++ b/src/Bullet3Dynamics/ConstraintSolver/b3FixedConstraint.cpp @@ -4,105 +4,100 @@ #include "Bullet3Common/b3TransformUtil.h" #include - -b3FixedConstraint::b3FixedConstraint(int rbA,int rbB, const b3Transform& frameInA,const b3Transform& frameInB) -:b3TypedConstraint(B3_FIXED_CONSTRAINT_TYPE,rbA,rbB) +b3FixedConstraint::b3FixedConstraint(int rbA, int rbB, const b3Transform& frameInA, const b3Transform& frameInB) + : b3TypedConstraint(B3_FIXED_CONSTRAINT_TYPE, rbA, rbB) { m_pivotInA = frameInA.getOrigin(); m_pivotInB = frameInB.getOrigin(); - m_relTargetAB = frameInA.getRotation()*frameInB.getRotation().inverse(); - + m_relTargetAB = frameInA.getRotation() * frameInB.getRotation().inverse(); } -b3FixedConstraint::~b3FixedConstraint () +b3FixedConstraint::~b3FixedConstraint() { } - -void b3FixedConstraint::getInfo1 (b3ConstraintInfo1* info,const b3RigidBodyData* bodies) +void b3FixedConstraint::getInfo1(b3ConstraintInfo1* info, const b3RigidBodyData* bodies) { info->m_numConstraintRows = 6; info->nub = 6; } -void b3FixedConstraint::getInfo2 (b3ConstraintInfo2* info, const b3RigidBodyData* bodies) +void b3FixedConstraint::getInfo2(b3ConstraintInfo2* info, const b3RigidBodyData* bodies) { //fix the 3 linear degrees of freedom const b3Vector3& worldPosA = bodies[m_rbA].m_pos; const b3Quaternion& worldOrnA = bodies[m_rbA].m_quat; - const b3Vector3& worldPosB= bodies[m_rbB].m_pos; + const b3Vector3& worldPosB = bodies[m_rbB].m_pos; const b3Quaternion& worldOrnB = bodies[m_rbB].m_quat; info->m_J1linearAxis[0] = 1; - info->m_J1linearAxis[info->rowskip+1] = 1; - info->m_J1linearAxis[2*info->rowskip+2] = 1; + info->m_J1linearAxis[info->rowskip + 1] = 1; + info->m_J1linearAxis[2 * info->rowskip + 2] = 1; - b3Vector3 a1 = b3QuatRotate(worldOrnA,m_pivotInA); + b3Vector3 a1 = b3QuatRotate(worldOrnA, m_pivotInA); { b3Vector3* angular0 = (b3Vector3*)(info->m_J1angularAxis); - b3Vector3* angular1 = (b3Vector3*)(info->m_J1angularAxis+info->rowskip); - b3Vector3* angular2 = (b3Vector3*)(info->m_J1angularAxis+2*info->rowskip); + b3Vector3* angular1 = (b3Vector3*)(info->m_J1angularAxis + info->rowskip); + b3Vector3* angular2 = (b3Vector3*)(info->m_J1angularAxis + 2 * info->rowskip); b3Vector3 a1neg = -a1; - a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2); + a1neg.getSkewSymmetricMatrix(angular0, angular1, angular2); } - + if (info->m_J2linearAxis) { info->m_J2linearAxis[0] = -1; - info->m_J2linearAxis[info->rowskip+1] = -1; - info->m_J2linearAxis[2*info->rowskip+2] = -1; + info->m_J2linearAxis[info->rowskip + 1] = -1; + info->m_J2linearAxis[2 * info->rowskip + 2] = -1; } - - b3Vector3 a2 = b3QuatRotate(worldOrnB,m_pivotInB); - + + b3Vector3 a2 = b3QuatRotate(worldOrnB, m_pivotInB); + { - // b3Vector3 a2n = -a2; + // b3Vector3 a2n = -a2; b3Vector3* angular0 = (b3Vector3*)(info->m_J2angularAxis); - b3Vector3* angular1 = (b3Vector3*)(info->m_J2angularAxis+info->rowskip); - b3Vector3* angular2 = (b3Vector3*)(info->m_J2angularAxis+2*info->rowskip); - a2.getSkewSymmetricMatrix(angular0,angular1,angular2); + b3Vector3* angular1 = (b3Vector3*)(info->m_J2angularAxis + info->rowskip); + b3Vector3* angular2 = (b3Vector3*)(info->m_J2angularAxis + 2 * info->rowskip); + a2.getSkewSymmetricMatrix(angular0, angular1, angular2); } - // set right hand side for the linear dofs + // set right hand side for the linear dofs b3Scalar k = info->fps * info->erp; - b3Vector3 linearError = k*(a2+worldPosB-a1-worldPosA); - int j; - for (j=0; j<3; j++) - { - info->m_constraintError[j*info->rowskip] = linearError[j]; + b3Vector3 linearError = k * (a2 + worldPosB - a1 - worldPosA); + int j; + for (j = 0; j < 3; j++) + { + info->m_constraintError[j * info->rowskip] = linearError[j]; //printf("info->m_constraintError[%d]=%f\n",j,info->m_constraintError[j]); - } + } - //fix the 3 angular degrees of freedom + //fix the 3 angular degrees of freedom int start_row = 3; int s = info->rowskip; - int start_index = start_row * s; + int start_index = start_row * s; - // 3 rows to make body rotations equal + // 3 rows to make body rotations equal info->m_J1angularAxis[start_index] = 1; - info->m_J1angularAxis[start_index + s + 1] = 1; - info->m_J1angularAxis[start_index + s*2+2] = 1; - if ( info->m_J2angularAxis) - { - info->m_J2angularAxis[start_index] = -1; - info->m_J2angularAxis[start_index + s+1] = -1; - info->m_J2angularAxis[start_index + s*2+2] = -1; - } + info->m_J1angularAxis[start_index + s + 1] = 1; + info->m_J1angularAxis[start_index + s * 2 + 2] = 1; + if (info->m_J2angularAxis) + { + info->m_J2angularAxis[start_index] = -1; + info->m_J2angularAxis[start_index + s + 1] = -1; + info->m_J2angularAxis[start_index + s * 2 + 2] = -1; + } - - // set right hand side for the angular dofs + // set right hand side for the angular dofs b3Vector3 diff; b3Scalar angle; - b3Quaternion qrelCur = worldOrnA *worldOrnB.inverse(); - - b3TransformUtil::calculateDiffAxisAngleQuaternion(m_relTargetAB,qrelCur,diff,angle); - diff*=-angle; - for (j=0; j<3; j++) - { - info->m_constraintError[(3+j)*info->rowskip] = k * diff[j]; - } + b3Quaternion qrelCur = worldOrnA * worldOrnB.inverse(); + b3TransformUtil::calculateDiffAxisAngleQuaternion(m_relTargetAB, qrelCur, diff, angle); + diff *= -angle; + for (j = 0; j < 3; j++) + { + info->m_constraintError[(3 + j) * info->rowskip] = k * diff[j]; + } } \ No newline at end of file diff --git a/src/Bullet3Dynamics/ConstraintSolver/b3FixedConstraint.h b/src/Bullet3Dynamics/ConstraintSolver/b3FixedConstraint.h index e884a8291..64809666e 100644 --- a/src/Bullet3Dynamics/ConstraintSolver/b3FixedConstraint.h +++ b/src/Bullet3Dynamics/ConstraintSolver/b3FixedConstraint.h @@ -4,32 +4,31 @@ #include "b3TypedConstraint.h" -B3_ATTRIBUTE_ALIGNED16(class) b3FixedConstraint : public b3TypedConstraint +B3_ATTRIBUTE_ALIGNED16(class) +b3FixedConstraint : public b3TypedConstraint { b3Vector3 m_pivotInA; b3Vector3 m_pivotInB; b3Quaternion m_relTargetAB; public: - b3FixedConstraint(int rbA,int rbB, const b3Transform& frameInA,const b3Transform& frameInB); - + b3FixedConstraint(int rbA, int rbB, const b3Transform& frameInA, const b3Transform& frameInB); + virtual ~b3FixedConstraint(); - - virtual void getInfo1 (b3ConstraintInfo1* info,const b3RigidBodyData* bodies); + virtual void getInfo1(b3ConstraintInfo1 * info, const b3RigidBodyData* bodies); - virtual void getInfo2 (b3ConstraintInfo2* info, const b3RigidBodyData* bodies); + virtual void getInfo2(b3ConstraintInfo2 * info, const b3RigidBodyData* bodies); - virtual void setParam(int num, b3Scalar value, int axis = -1) + virtual void setParam(int num, b3Scalar value, int axis = -1) { b3Assert(0); } - virtual b3Scalar getParam(int num, int axis = -1) const + virtual b3Scalar getParam(int num, int axis = -1) const { b3Assert(0); return 0.f; } - }; -#endif //B3_FIXED_CONSTRAINT_H +#endif //B3_FIXED_CONSTRAINT_H diff --git a/src/Bullet3Dynamics/ConstraintSolver/b3Generic6DofConstraint.cpp b/src/Bullet3Dynamics/ConstraintSolver/b3Generic6DofConstraint.cpp index 3ae2922e5..0d5bb2014 100644 --- a/src/Bullet3Dynamics/ConstraintSolver/b3Generic6DofConstraint.cpp +++ b/src/Bullet3Dynamics/ConstraintSolver/b3Generic6DofConstraint.cpp @@ -26,69 +26,48 @@ http://gimpact.sf.net #include "Bullet3Common/b3TransformUtil.h" #include - - #define D6_USE_OBSOLETE_METHOD false #define D6_USE_FRAME_OFFSET true - - - - - -b3Generic6DofConstraint::b3Generic6DofConstraint(int rbA,int rbB, const b3Transform& frameInA, const b3Transform& frameInB, bool useLinearReferenceFrameA, const b3RigidBodyData* bodies) -: b3TypedConstraint(B3_D6_CONSTRAINT_TYPE, rbA, rbB) -, m_frameInA(frameInA) -, m_frameInB(frameInB), -m_useLinearReferenceFrameA(useLinearReferenceFrameA), -m_useOffsetForConstraintFrame(D6_USE_FRAME_OFFSET), -m_flags(0) +b3Generic6DofConstraint::b3Generic6DofConstraint(int rbA, int rbB, const b3Transform& frameInA, const b3Transform& frameInB, bool useLinearReferenceFrameA, const b3RigidBodyData* bodies) + : b3TypedConstraint(B3_D6_CONSTRAINT_TYPE, rbA, rbB), m_frameInA(frameInA), m_frameInB(frameInB), m_useLinearReferenceFrameA(useLinearReferenceFrameA), m_useOffsetForConstraintFrame(D6_USE_FRAME_OFFSET), m_flags(0) { calculateTransforms(bodies); } - - - - - #define GENERIC_D6_DISABLE_WARMSTARTING 1 - - b3Scalar btGetMatrixElem(const b3Matrix3x3& mat, int index); b3Scalar btGetMatrixElem(const b3Matrix3x3& mat, int index) { - int i = index%3; - int j = index/3; + int i = index % 3; + int j = index / 3; return mat[i][j]; } - - ///MatrixToEulerXYZ from http://www.geometrictools.com/LibFoundation/Mathematics/Wm4Matrix3.inl.html -bool matrixToEulerXYZ(const b3Matrix3x3& mat,b3Vector3& xyz); -bool matrixToEulerXYZ(const b3Matrix3x3& mat,b3Vector3& xyz) +bool matrixToEulerXYZ(const b3Matrix3x3& mat, b3Vector3& xyz); +bool matrixToEulerXYZ(const b3Matrix3x3& mat, b3Vector3& xyz) { // // rot = cy*cz -cy*sz sy // // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx // // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy // - b3Scalar fi = btGetMatrixElem(mat,2); + b3Scalar fi = btGetMatrixElem(mat, 2); if (fi < b3Scalar(1.0f)) { if (fi > b3Scalar(-1.0f)) { - xyz[0] = b3Atan2(-btGetMatrixElem(mat,5),btGetMatrixElem(mat,8)); - xyz[1] = b3Asin(btGetMatrixElem(mat,2)); - xyz[2] = b3Atan2(-btGetMatrixElem(mat,1),btGetMatrixElem(mat,0)); + xyz[0] = b3Atan2(-btGetMatrixElem(mat, 5), btGetMatrixElem(mat, 8)); + xyz[1] = b3Asin(btGetMatrixElem(mat, 2)); + xyz[2] = b3Atan2(-btGetMatrixElem(mat, 1), btGetMatrixElem(mat, 0)); return true; } else { // WARNING. Not unique. XA - ZA = -atan2(r10,r11) - xyz[0] = -b3Atan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4)); + xyz[0] = -b3Atan2(btGetMatrixElem(mat, 3), btGetMatrixElem(mat, 4)); xyz[1] = -B3_HALF_PI; xyz[2] = b3Scalar(0.0); return false; @@ -97,7 +76,7 @@ bool matrixToEulerXYZ(const b3Matrix3x3& mat,b3Vector3& xyz) else { // WARNING. Not unique. XAngle + ZAngle = atan2(r10,r11) - xyz[0] = b3Atan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4)); + xyz[0] = b3Atan2(btGetMatrixElem(mat, 3), btGetMatrixElem(mat, 4)); xyz[1] = B3_HALF_PI; xyz[2] = 0.0; } @@ -108,85 +87,75 @@ bool matrixToEulerXYZ(const b3Matrix3x3& mat,b3Vector3& xyz) int b3RotationalLimitMotor::testLimitValue(b3Scalar test_value) { - if(m_loLimit>m_hiLimit) + if (m_loLimit > m_hiLimit) { - m_currentLimit = 0;//Free from violation + m_currentLimit = 0; //Free from violation return 0; } if (test_value < m_loLimit) { - m_currentLimit = 1;//low limit violation - m_currentLimitError = test_value - m_loLimit; - if(m_currentLimitError>B3_PI) - m_currentLimitError-=B3_2_PI; - else if(m_currentLimitError<-B3_PI) - m_currentLimitError+=B3_2_PI; + m_currentLimit = 1; //low limit violation + m_currentLimitError = test_value - m_loLimit; + if (m_currentLimitError > B3_PI) + m_currentLimitError -= B3_2_PI; + else if (m_currentLimitError < -B3_PI) + m_currentLimitError += B3_2_PI; return 1; } - else if (test_value> m_hiLimit) + else if (test_value > m_hiLimit) { - m_currentLimit = 2;//High limit violation + m_currentLimit = 2; //High limit violation m_currentLimitError = test_value - m_hiLimit; - if(m_currentLimitError>B3_PI) - m_currentLimitError-=B3_2_PI; - else if(m_currentLimitError<-B3_PI) - m_currentLimitError+=B3_2_PI; + if (m_currentLimitError > B3_PI) + m_currentLimitError -= B3_2_PI; + else if (m_currentLimitError < -B3_PI) + m_currentLimitError += B3_2_PI; return 2; }; - m_currentLimit = 0;//Free from violation + m_currentLimit = 0; //Free from violation return 0; - } - - - //////////////////////////// End b3RotationalLimitMotor //////////////////////////////////// - - - //////////////////////////// b3TranslationalLimitMotor //////////////////////////////////// - int b3TranslationalLimitMotor::testLimitValue(int limitIndex, b3Scalar test_value) { b3Scalar loLimit = m_lowerLimit[limitIndex]; b3Scalar hiLimit = m_upperLimit[limitIndex]; - if(loLimit > hiLimit) + if (loLimit > hiLimit) { - m_currentLimit[limitIndex] = 0;//Free from violation + m_currentLimit[limitIndex] = 0; //Free from violation m_currentLimitError[limitIndex] = b3Scalar(0.f); return 0; } if (test_value < loLimit) { - m_currentLimit[limitIndex] = 2;//low limit violation - m_currentLimitError[limitIndex] = test_value - loLimit; + m_currentLimit[limitIndex] = 2; //low limit violation + m_currentLimitError[limitIndex] = test_value - loLimit; return 2; } - else if (test_value> hiLimit) + else if (test_value > hiLimit) { - m_currentLimit[limitIndex] = 1;//High limit violation + m_currentLimit[limitIndex] = 1; //High limit violation m_currentLimitError[limitIndex] = test_value - hiLimit; return 1; }; - m_currentLimit[limitIndex] = 0;//Free from violation + m_currentLimit[limitIndex] = 0; //Free from violation m_currentLimitError[limitIndex] = b3Scalar(0.f); return 0; } - - //////////////////////////// b3TranslationalLimitMotor //////////////////////////////////// void b3Generic6DofConstraint::calculateAngleInfo() { - b3Matrix3x3 relative_frame = m_calculatedTransformA.getBasis().inverse()*m_calculatedTransformB.getBasis(); - matrixToEulerXYZ(relative_frame,m_calculatedAxisAngleDiff); + b3Matrix3x3 relative_frame = m_calculatedTransformA.getBasis().inverse() * m_calculatedTransformB.getBasis(); + matrixToEulerXYZ(relative_frame, m_calculatedAxisAngleDiff); // in euler angle mode we do not actually constrain the angular velocity // along the axes axis[0] and axis[2] (although we do use axis[1]) : // @@ -211,12 +180,11 @@ void b3Generic6DofConstraint::calculateAngleInfo() m_calculatedAxis[0].normalize(); m_calculatedAxis[1].normalize(); m_calculatedAxis[2].normalize(); - } static b3Transform getCenterOfMassTransform(const b3RigidBodyData& body) { - b3Transform tr(body.m_quat,body.m_pos); + b3Transform tr(body.m_quat, body.m_pos); return tr; } @@ -226,26 +194,26 @@ void b3Generic6DofConstraint::calculateTransforms(const b3RigidBodyData* bodies) b3Transform transB; transA = getCenterOfMassTransform(bodies[m_rbA]); transB = getCenterOfMassTransform(bodies[m_rbB]); - calculateTransforms(transA,transB,bodies); + calculateTransforms(transA, transB, bodies); } -void b3Generic6DofConstraint::calculateTransforms(const b3Transform& transA,const b3Transform& transB,const b3RigidBodyData* bodies) +void b3Generic6DofConstraint::calculateTransforms(const b3Transform& transA, const b3Transform& transB, const b3RigidBodyData* bodies) { m_calculatedTransformA = transA * m_frameInA; m_calculatedTransformB = transB * m_frameInB; calculateLinearInfo(); calculateAngleInfo(); - if(m_useOffsetForConstraintFrame) - { // get weight factors depending on masses + if (m_useOffsetForConstraintFrame) + { // get weight factors depending on masses b3Scalar miA = bodies[m_rbA].m_invMass; b3Scalar miB = bodies[m_rbB].m_invMass; m_hasStaticBody = (miA < B3_EPSILON) || (miB < B3_EPSILON); b3Scalar miS = miA + miB; - if(miS > b3Scalar(0.f)) + if (miS > b3Scalar(0.f)) { m_factA = miB / miS; } - else + else { m_factA = b3Scalar(0.5f); } @@ -253,12 +221,6 @@ void b3Generic6DofConstraint::calculateTransforms(const b3Transform& transA,cons } } - - - - - - bool b3Generic6DofConstraint::testAngularLimitMotor(int axis_index) { b3Scalar angle = m_calculatedAxisAngleDiff[axis_index]; @@ -269,48 +231,43 @@ bool b3Generic6DofConstraint::testAngularLimitMotor(int axis_index) return m_angularLimits[axis_index].needApplyTorques(); } - - - -void b3Generic6DofConstraint::getInfo1 (b3ConstraintInfo1* info,const b3RigidBodyData* bodies) +void b3Generic6DofConstraint::getInfo1(b3ConstraintInfo1* info, const b3RigidBodyData* bodies) { //prepare constraint - calculateTransforms(getCenterOfMassTransform(bodies[m_rbA]),getCenterOfMassTransform(bodies[m_rbB]),bodies); + calculateTransforms(getCenterOfMassTransform(bodies[m_rbA]), getCenterOfMassTransform(bodies[m_rbB]), bodies); info->m_numConstraintRows = 0; info->nub = 6; int i; //test linear limits - for(i = 0; i < 3; i++) + for (i = 0; i < 3; i++) { - if(m_linearLimits.needApplyForce(i)) + if (m_linearLimits.needApplyForce(i)) { info->m_numConstraintRows++; info->nub--; } } //test angular limits - for (i=0;i<3 ;i++ ) + for (i = 0; i < 3; i++) { - if(testAngularLimitMotor(i)) + if (testAngularLimitMotor(i)) { info->m_numConstraintRows++; info->nub--; } } -// printf("info->m_numConstraintRows=%d\n",info->m_numConstraintRows); + // printf("info->m_numConstraintRows=%d\n",info->m_numConstraintRows); } -void b3Generic6DofConstraint::getInfo1NonVirtual (b3ConstraintInfo1* info,const b3RigidBodyData* bodies) +void b3Generic6DofConstraint::getInfo1NonVirtual(b3ConstraintInfo1* info, const b3RigidBodyData* bodies) { //pre-allocate all 6 info->m_numConstraintRows = 6; info->nub = 0; } - -void b3Generic6DofConstraint::getInfo2 (b3ConstraintInfo2* info,const b3RigidBodyData* bodies) +void b3Generic6DofConstraint::getInfo2(b3ConstraintInfo2* info, const b3RigidBodyData* bodies) { - b3Transform transA = getCenterOfMassTransform(bodies[m_rbA]); b3Transform transB = getCenterOfMassTransform(bodies[m_rbB]); const b3Vector3& linVelA = bodies[m_rbA].m_linVel; @@ -318,136 +275,124 @@ void b3Generic6DofConstraint::getInfo2 (b3ConstraintInfo2* info,const b3RigidBod const b3Vector3& angVelA = bodies[m_rbA].m_angVel; const b3Vector3& angVelB = bodies[m_rbB].m_angVel; - if(m_useOffsetForConstraintFrame) - { // for stability better to solve angular limits first - int row = setAngularLimits(info, 0,transA,transB,linVelA,linVelB,angVelA,angVelB); - setLinearLimits(info, row, transA,transB,linVelA,linVelB,angVelA,angVelB); + if (m_useOffsetForConstraintFrame) + { // for stability better to solve angular limits first + int row = setAngularLimits(info, 0, transA, transB, linVelA, linVelB, angVelA, angVelB); + setLinearLimits(info, row, transA, transB, linVelA, linVelB, angVelA, angVelB); } else - { // leave old version for compatibility - int row = setLinearLimits(info, 0, transA,transB,linVelA,linVelB,angVelA,angVelB); - setAngularLimits(info, row,transA,transB,linVelA,linVelB,angVelA,angVelB); + { // leave old version for compatibility + int row = setLinearLimits(info, 0, transA, transB, linVelA, linVelB, angVelA, angVelB); + setAngularLimits(info, row, transA, transB, linVelA, linVelB, angVelA, angVelB); } - } - -void b3Generic6DofConstraint::getInfo2NonVirtual (b3ConstraintInfo2* info, const b3Transform& transA,const b3Transform& transB,const b3Vector3& linVelA,const b3Vector3& linVelB,const b3Vector3& angVelA,const b3Vector3& angVelB,const b3RigidBodyData* bodies) +void b3Generic6DofConstraint::getInfo2NonVirtual(b3ConstraintInfo2* info, const b3Transform& transA, const b3Transform& transB, const b3Vector3& linVelA, const b3Vector3& linVelB, const b3Vector3& angVelA, const b3Vector3& angVelB, const b3RigidBodyData* bodies) { - //prepare constraint - calculateTransforms(transA,transB,bodies); + calculateTransforms(transA, transB, bodies); int i; - for (i=0;i<3 ;i++ ) + for (i = 0; i < 3; i++) { testAngularLimitMotor(i); } - if(m_useOffsetForConstraintFrame) - { // for stability better to solve angular limits first - int row = setAngularLimits(info, 0,transA,transB,linVelA,linVelB,angVelA,angVelB); - setLinearLimits(info, row, transA,transB,linVelA,linVelB,angVelA,angVelB); + if (m_useOffsetForConstraintFrame) + { // for stability better to solve angular limits first + int row = setAngularLimits(info, 0, transA, transB, linVelA, linVelB, angVelA, angVelB); + setLinearLimits(info, row, transA, transB, linVelA, linVelB, angVelA, angVelB); } else - { // leave old version for compatibility - int row = setLinearLimits(info, 0, transA,transB,linVelA,linVelB,angVelA,angVelB); - setAngularLimits(info, row,transA,transB,linVelA,linVelB,angVelA,angVelB); + { // leave old version for compatibility + int row = setLinearLimits(info, 0, transA, transB, linVelA, linVelB, angVelA, angVelB); + setAngularLimits(info, row, transA, transB, linVelA, linVelB, angVelA, angVelB); } } - - -int b3Generic6DofConstraint::setLinearLimits(b3ConstraintInfo2* info, int row, const b3Transform& transA,const b3Transform& transB,const b3Vector3& linVelA,const b3Vector3& linVelB,const b3Vector3& angVelA,const b3Vector3& angVelB) +int b3Generic6DofConstraint::setLinearLimits(b3ConstraintInfo2* info, int row, const b3Transform& transA, const b3Transform& transB, const b3Vector3& linVelA, const b3Vector3& linVelB, const b3Vector3& angVelA, const b3Vector3& angVelB) { -// int row = 0; + // int row = 0; //solve linear limits b3RotationalLimitMotor limot; - for (int i=0;i<3 ;i++ ) + for (int i = 0; i < 3; i++) { - if(m_linearLimits.needApplyForce(i)) - { // re-use rotational motor code + if (m_linearLimits.needApplyForce(i)) + { // re-use rotational motor code limot.m_bounce = b3Scalar(0.f); limot.m_currentLimit = m_linearLimits.m_currentLimit[i]; limot.m_currentPosition = m_linearLimits.m_currentLinearDiff[i]; - limot.m_currentLimitError = m_linearLimits.m_currentLimitError[i]; - limot.m_damping = m_linearLimits.m_damping; - limot.m_enableMotor = m_linearLimits.m_enableMotor[i]; - limot.m_hiLimit = m_linearLimits.m_upperLimit[i]; - limot.m_limitSoftness = m_linearLimits.m_limitSoftness; - limot.m_loLimit = m_linearLimits.m_lowerLimit[i]; - limot.m_maxLimitForce = b3Scalar(0.f); - limot.m_maxMotorForce = m_linearLimits.m_maxMotorForce[i]; - limot.m_targetVelocity = m_linearLimits.m_targetVelocity[i]; + limot.m_currentLimitError = m_linearLimits.m_currentLimitError[i]; + limot.m_damping = m_linearLimits.m_damping; + limot.m_enableMotor = m_linearLimits.m_enableMotor[i]; + limot.m_hiLimit = m_linearLimits.m_upperLimit[i]; + limot.m_limitSoftness = m_linearLimits.m_limitSoftness; + limot.m_loLimit = m_linearLimits.m_lowerLimit[i]; + limot.m_maxLimitForce = b3Scalar(0.f); + limot.m_maxMotorForce = m_linearLimits.m_maxMotorForce[i]; + limot.m_targetVelocity = m_linearLimits.m_targetVelocity[i]; b3Vector3 axis = m_calculatedTransformA.getBasis().getColumn(i); int flags = m_flags >> (i * B3_6DOF_FLAGS_AXIS_SHIFT); - limot.m_normalCFM = (flags & B3_6DOF_FLAGS_CFM_NORM) ? m_linearLimits.m_normalCFM[i] : info->cfm[0]; - limot.m_stopCFM = (flags & B3_6DOF_FLAGS_CFM_STOP) ? m_linearLimits.m_stopCFM[i] : info->cfm[0]; - limot.m_stopERP = (flags & B3_6DOF_FLAGS_ERP_STOP) ? m_linearLimits.m_stopERP[i] : info->erp; - if(m_useOffsetForConstraintFrame) + limot.m_normalCFM = (flags & B3_6DOF_FLAGS_CFM_NORM) ? m_linearLimits.m_normalCFM[i] : info->cfm[0]; + limot.m_stopCFM = (flags & B3_6DOF_FLAGS_CFM_STOP) ? m_linearLimits.m_stopCFM[i] : info->cfm[0]; + limot.m_stopERP = (flags & B3_6DOF_FLAGS_ERP_STOP) ? m_linearLimits.m_stopERP[i] : info->erp; + if (m_useOffsetForConstraintFrame) { int indx1 = (i + 1) % 3; int indx2 = (i + 2) % 3; - int rotAllowed = 1; // rotations around orthos to current axis - if(m_angularLimits[indx1].m_currentLimit && m_angularLimits[indx2].m_currentLimit) + int rotAllowed = 1; // rotations around orthos to current axis + if (m_angularLimits[indx1].m_currentLimit && m_angularLimits[indx2].m_currentLimit) { rotAllowed = 0; } - row += get_limit_motor_info2(&limot, transA,transB,linVelA,linVelB,angVelA,angVelB, info, row, axis, 0, rotAllowed); + row += get_limit_motor_info2(&limot, transA, transB, linVelA, linVelB, angVelA, angVelB, info, row, axis, 0, rotAllowed); } else { - row += get_limit_motor_info2(&limot, transA,transB,linVelA,linVelB,angVelA,angVelB, info, row, axis, 0); + row += get_limit_motor_info2(&limot, transA, transB, linVelA, linVelB, angVelA, angVelB, info, row, axis, 0); } } } return row; } - - -int b3Generic6DofConstraint::setAngularLimits(b3ConstraintInfo2 *info, int row_offset, const b3Transform& transA,const b3Transform& transB,const b3Vector3& linVelA,const b3Vector3& linVelB,const b3Vector3& angVelA,const b3Vector3& angVelB) +int b3Generic6DofConstraint::setAngularLimits(b3ConstraintInfo2* info, int row_offset, const b3Transform& transA, const b3Transform& transB, const b3Vector3& linVelA, const b3Vector3& linVelB, const b3Vector3& angVelA, const b3Vector3& angVelB) { - b3Generic6DofConstraint * d6constraint = this; + b3Generic6DofConstraint* d6constraint = this; int row = row_offset; //solve angular limits - for (int i=0;i<3 ;i++ ) + for (int i = 0; i < 3; i++) { - if(d6constraint->getRotationalLimitMotor(i)->needApplyTorques()) + if (d6constraint->getRotationalLimitMotor(i)->needApplyTorques()) { b3Vector3 axis = d6constraint->getAxis(i); int flags = m_flags >> ((i + 3) * B3_6DOF_FLAGS_AXIS_SHIFT); - if(!(flags & B3_6DOF_FLAGS_CFM_NORM)) + if (!(flags & B3_6DOF_FLAGS_CFM_NORM)) { m_angularLimits[i].m_normalCFM = info->cfm[0]; } - if(!(flags & B3_6DOF_FLAGS_CFM_STOP)) + if (!(flags & B3_6DOF_FLAGS_CFM_STOP)) { m_angularLimits[i].m_stopCFM = info->cfm[0]; } - if(!(flags & B3_6DOF_FLAGS_ERP_STOP)) + if (!(flags & B3_6DOF_FLAGS_ERP_STOP)) { m_angularLimits[i].m_stopERP = info->erp; } row += get_limit_motor_info2(d6constraint->getRotationalLimitMotor(i), - transA,transB,linVelA,linVelB,angVelA,angVelB, info,row,axis,1); + transA, transB, linVelA, linVelB, angVelA, angVelB, info, row, axis, 1); } } return row; } - - - -void b3Generic6DofConstraint::updateRHS(b3Scalar timeStep) +void b3Generic6DofConstraint::updateRHS(b3Scalar timeStep) { (void)timeStep; - } - -void b3Generic6DofConstraint::setFrames(const b3Transform& frameA, const b3Transform& frameB,const b3RigidBodyData* bodies) +void b3Generic6DofConstraint::setFrames(const b3Transform& frameA, const b3Transform& frameB, const b3RigidBodyData* bodies) { m_frameInA = frameA; m_frameInB = frameB; @@ -455,33 +400,27 @@ void b3Generic6DofConstraint::setFrames(const b3Transform& frameA, const b3Trans calculateTransforms(bodies); } - - b3Vector3 b3Generic6DofConstraint::getAxis(int axis_index) const { return m_calculatedAxis[axis_index]; } - -b3Scalar b3Generic6DofConstraint::getRelativePivotPosition(int axisIndex) const +b3Scalar b3Generic6DofConstraint::getRelativePivotPosition(int axisIndex) const { return m_calculatedLinearDiff[axisIndex]; } - b3Scalar b3Generic6DofConstraint::getAngle(int axisIndex) const { return m_calculatedAxisAngleDiff[axisIndex]; } - - void b3Generic6DofConstraint::calcAnchorPos(const b3RigidBodyData* bodies) { b3Scalar imA = bodies[m_rbA].m_invMass; b3Scalar imB = bodies[m_rbB].m_invMass; b3Scalar weight; - if(imB == b3Scalar(0.0)) + if (imB == b3Scalar(0.0)) { weight = b3Scalar(1.0); } @@ -495,47 +434,43 @@ void b3Generic6DofConstraint::calcAnchorPos(const b3RigidBodyData* bodies) return; } - - void b3Generic6DofConstraint::calculateLinearInfo() { m_calculatedLinearDiff = m_calculatedTransformB.getOrigin() - m_calculatedTransformA.getOrigin(); m_calculatedLinearDiff = m_calculatedTransformA.getBasis().inverse() * m_calculatedLinearDiff; - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { m_linearLimits.m_currentLinearDiff[i] = m_calculatedLinearDiff[i]; m_linearLimits.testLimitValue(i, m_calculatedLinearDiff[i]); } } - - int b3Generic6DofConstraint::get_limit_motor_info2( - b3RotationalLimitMotor * limot, - const b3Transform& transA,const b3Transform& transB,const b3Vector3& linVelA,const b3Vector3& linVelB,const b3Vector3& angVelA,const b3Vector3& angVelB, - b3ConstraintInfo2 *info, int row, b3Vector3& ax1, int rotational,int rotAllowed) + b3RotationalLimitMotor* limot, + const b3Transform& transA, const b3Transform& transB, const b3Vector3& linVelA, const b3Vector3& linVelB, const b3Vector3& angVelA, const b3Vector3& angVelB, + b3ConstraintInfo2* info, int row, b3Vector3& ax1, int rotational, int rotAllowed) { - int srow = row * info->rowskip; - bool powered = limot->m_enableMotor; - int limit = limot->m_currentLimit; - if (powered || limit) - { // if the joint is powered, or has joint limits, add in the extra row - b3Scalar *J1 = rotational ? info->m_J1angularAxis : info->m_J1linearAxis; - b3Scalar *J2 = rotational ? info->m_J2angularAxis : info->m_J2linearAxis; + int srow = row * info->rowskip; + bool powered = limot->m_enableMotor; + int limit = limot->m_currentLimit; + if (powered || limit) + { // if the joint is powered, or has joint limits, add in the extra row + b3Scalar* J1 = rotational ? info->m_J1angularAxis : info->m_J1linearAxis; + b3Scalar* J2 = rotational ? info->m_J2angularAxis : info->m_J2linearAxis; if (J1) { - J1[srow+0] = ax1[0]; - J1[srow+1] = ax1[1]; - J1[srow+2] = ax1[2]; + J1[srow + 0] = ax1[0]; + J1[srow + 1] = ax1[1]; + J1[srow + 2] = ax1[2]; } if (J2) { - J2[srow+0] = -ax1[0]; - J2[srow+1] = -ax1[1]; - J2[srow+2] = -ax1[2]; + J2[srow + 0] = -ax1[0]; + J2[srow + 1] = -ax1[1]; + J2[srow + 2] = -ax1[2]; } - if((!rotational)) - { + if ((!rotational)) + { if (m_useOffsetForConstraintFrame) { b3Vector3 tmpA, tmpB, relA, relB; @@ -558,55 +493,56 @@ int b3Generic6DofConstraint::get_limit_motor_info2( relB = orthoB - totalDist * m_factB; tmpA = relA.cross(ax1); tmpB = relB.cross(ax1); - if(m_hasStaticBody && (!rotAllowed)) + if (m_hasStaticBody && (!rotAllowed)) { tmpA *= m_factA; tmpB *= m_factB; } int i; - for (i=0; i<3; i++) info->m_J1angularAxis[srow+i] = tmpA[i]; - for (i=0; i<3; i++) info->m_J2angularAxis[srow+i] = -tmpB[i]; - } else + for (i = 0; i < 3; i++) info->m_J1angularAxis[srow + i] = tmpA[i]; + for (i = 0; i < 3; i++) info->m_J2angularAxis[srow + i] = -tmpB[i]; + } + else { - b3Vector3 ltd; // Linear Torque Decoupling vector + b3Vector3 ltd; // Linear Torque Decoupling vector b3Vector3 c = m_calculatedTransformB.getOrigin() - transA.getOrigin(); ltd = c.cross(ax1); - info->m_J1angularAxis[srow+0] = ltd[0]; - info->m_J1angularAxis[srow+1] = ltd[1]; - info->m_J1angularAxis[srow+2] = ltd[2]; + info->m_J1angularAxis[srow + 0] = ltd[0]; + info->m_J1angularAxis[srow + 1] = ltd[1]; + info->m_J1angularAxis[srow + 2] = ltd[2]; c = m_calculatedTransformB.getOrigin() - transB.getOrigin(); ltd = -c.cross(ax1); - info->m_J2angularAxis[srow+0] = ltd[0]; - info->m_J2angularAxis[srow+1] = ltd[1]; - info->m_J2angularAxis[srow+2] = ltd[2]; + info->m_J2angularAxis[srow + 0] = ltd[0]; + info->m_J2angularAxis[srow + 1] = ltd[1]; + info->m_J2angularAxis[srow + 2] = ltd[2]; } - } - // if we're limited low and high simultaneously, the joint motor is - // ineffective - if (limit && (limot->m_loLimit == limot->m_hiLimit)) powered = false; - info->m_constraintError[srow] = b3Scalar(0.f); - if (powered) - { + } + // if we're limited low and high simultaneously, the joint motor is + // ineffective + if (limit && (limot->m_loLimit == limot->m_hiLimit)) powered = false; + info->m_constraintError[srow] = b3Scalar(0.f); + if (powered) + { info->cfm[srow] = limot->m_normalCFM; - if(!limit) - { + if (!limit) + { b3Scalar tag_vel = rotational ? limot->m_targetVelocity : -limot->m_targetVelocity; - b3Scalar mot_fact = getMotorFactor( limot->m_currentPosition, - limot->m_loLimit, - limot->m_hiLimit, - tag_vel, - info->fps * limot->m_stopERP); + b3Scalar mot_fact = getMotorFactor(limot->m_currentPosition, + limot->m_loLimit, + limot->m_hiLimit, + tag_vel, + info->fps * limot->m_stopERP); info->m_constraintError[srow] += mot_fact * limot->m_targetVelocity; - info->m_lowerLimit[srow] = -limot->m_maxMotorForce / info->fps; - info->m_upperLimit[srow] = limot->m_maxMotorForce / info->fps; - } - } - if(limit) - { - b3Scalar k = info->fps * limot->m_stopERP; - if(!rotational) + info->m_lowerLimit[srow] = -limot->m_maxMotorForce / info->fps; + info->m_upperLimit[srow] = limot->m_maxMotorForce / info->fps; + } + } + if (limit) + { + b3Scalar k = info->fps * limot->m_stopERP; + if (!rotational) { info->m_constraintError[srow] += k * limot->m_currentLimitError; } @@ -615,116 +551,112 @@ int b3Generic6DofConstraint::get_limit_motor_info2( info->m_constraintError[srow] += -k * limot->m_currentLimitError; } info->cfm[srow] = limot->m_stopCFM; - if (limot->m_loLimit == limot->m_hiLimit) - { // limited low and high simultaneously - info->m_lowerLimit[srow] = -B3_INFINITY; - info->m_upperLimit[srow] = B3_INFINITY; - } - else - { - if (limit == 1) - { - info->m_lowerLimit[srow] = 0; - info->m_upperLimit[srow] = B3_INFINITY; - } - else - { - info->m_lowerLimit[srow] = -B3_INFINITY; - info->m_upperLimit[srow] = 0; - } - // deal with bounce - if (limot->m_bounce > 0) - { - // calculate joint velocity - b3Scalar vel; - if (rotational) - { - vel = angVelA.dot(ax1); -//make sure that if no body -> angVelB == zero vec -// if (body1) - vel -= angVelB.dot(ax1); - } - else - { - vel = linVelA.dot(ax1); -//make sure that if no body -> angVelB == zero vec -// if (body1) - vel -= linVelB.dot(ax1); - } - // only apply bounce if the velocity is incoming, and if the - // resulting c[] exceeds what we already have. - if (limit == 1) - { - if (vel < 0) - { - b3Scalar newc = -limot->m_bounce* vel; - if (newc > info->m_constraintError[srow]) + if (limot->m_loLimit == limot->m_hiLimit) + { // limited low and high simultaneously + info->m_lowerLimit[srow] = -B3_INFINITY; + info->m_upperLimit[srow] = B3_INFINITY; + } + else + { + if (limit == 1) + { + info->m_lowerLimit[srow] = 0; + info->m_upperLimit[srow] = B3_INFINITY; + } + else + { + info->m_lowerLimit[srow] = -B3_INFINITY; + info->m_upperLimit[srow] = 0; + } + // deal with bounce + if (limot->m_bounce > 0) + { + // calculate joint velocity + b3Scalar vel; + if (rotational) + { + vel = angVelA.dot(ax1); + //make sure that if no body -> angVelB == zero vec + // if (body1) + vel -= angVelB.dot(ax1); + } + else + { + vel = linVelA.dot(ax1); + //make sure that if no body -> angVelB == zero vec + // if (body1) + vel -= linVelB.dot(ax1); + } + // only apply bounce if the velocity is incoming, and if the + // resulting c[] exceeds what we already have. + if (limit == 1) + { + if (vel < 0) + { + b3Scalar newc = -limot->m_bounce * vel; + if (newc > info->m_constraintError[srow]) info->m_constraintError[srow] = newc; - } - } - else - { - if (vel > 0) - { - b3Scalar newc = -limot->m_bounce * vel; - if (newc < info->m_constraintError[srow]) + } + } + else + { + if (vel > 0) + { + b3Scalar newc = -limot->m_bounce * vel; + if (newc < info->m_constraintError[srow]) info->m_constraintError[srow] = newc; - } - } - } - } - } - return 1; - } - else return 0; + } + } + } + } + } + return 1; + } + else + return 0; } - - - - - - ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). - ///If no axis is provided, it uses the default axis for this constraint. +///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). +///If no axis is provided, it uses the default axis for this constraint. void b3Generic6DofConstraint::setParam(int num, b3Scalar value, int axis) { - if((axis >= 0) && (axis < 3)) + if ((axis >= 0) && (axis < 3)) { - switch(num) + switch (num) { - case B3_CONSTRAINT_STOP_ERP : + case B3_CONSTRAINT_STOP_ERP: m_linearLimits.m_stopERP[axis] = value; m_flags |= B3_6DOF_FLAGS_ERP_STOP << (axis * B3_6DOF_FLAGS_AXIS_SHIFT); break; - case B3_CONSTRAINT_STOP_CFM : + case B3_CONSTRAINT_STOP_CFM: m_linearLimits.m_stopCFM[axis] = value; m_flags |= B3_6DOF_FLAGS_CFM_STOP << (axis * B3_6DOF_FLAGS_AXIS_SHIFT); break; - case B3_CONSTRAINT_CFM : + case B3_CONSTRAINT_CFM: m_linearLimits.m_normalCFM[axis] = value; m_flags |= B3_6DOF_FLAGS_CFM_NORM << (axis * B3_6DOF_FLAGS_AXIS_SHIFT); break; - default : + default: b3AssertConstrParams(0); } } - else if((axis >=3) && (axis < 6)) + else if ((axis >= 3) && (axis < 6)) { - switch(num) + switch (num) { - case B3_CONSTRAINT_STOP_ERP : + case B3_CONSTRAINT_STOP_ERP: m_angularLimits[axis - 3].m_stopERP = value; m_flags |= B3_6DOF_FLAGS_ERP_STOP << (axis * B3_6DOF_FLAGS_AXIS_SHIFT); break; - case B3_CONSTRAINT_STOP_CFM : + case B3_CONSTRAINT_STOP_CFM: m_angularLimits[axis - 3].m_stopCFM = value; m_flags |= B3_6DOF_FLAGS_CFM_STOP << (axis * B3_6DOF_FLAGS_AXIS_SHIFT); break; - case B3_CONSTRAINT_CFM : + case B3_CONSTRAINT_CFM: m_angularLimits[axis - 3].m_normalCFM = value; m_flags |= B3_6DOF_FLAGS_CFM_NORM << (axis * B3_6DOF_FLAGS_AXIS_SHIFT); break; - default : + default: b3AssertConstrParams(0); } } @@ -734,47 +666,47 @@ void b3Generic6DofConstraint::setParam(int num, b3Scalar value, int axis) } } - ///return the local value of parameter -b3Scalar b3Generic6DofConstraint::getParam(int num, int axis) const +///return the local value of parameter +b3Scalar b3Generic6DofConstraint::getParam(int num, int axis) const { b3Scalar retVal = 0; - if((axis >= 0) && (axis < 3)) + if ((axis >= 0) && (axis < 3)) { - switch(num) + switch (num) { - case B3_CONSTRAINT_STOP_ERP : + case B3_CONSTRAINT_STOP_ERP: b3AssertConstrParams(m_flags & (B3_6DOF_FLAGS_ERP_STOP << (axis * B3_6DOF_FLAGS_AXIS_SHIFT))); retVal = m_linearLimits.m_stopERP[axis]; break; - case B3_CONSTRAINT_STOP_CFM : + case B3_CONSTRAINT_STOP_CFM: b3AssertConstrParams(m_flags & (B3_6DOF_FLAGS_CFM_STOP << (axis * B3_6DOF_FLAGS_AXIS_SHIFT))); retVal = m_linearLimits.m_stopCFM[axis]; break; - case B3_CONSTRAINT_CFM : + case B3_CONSTRAINT_CFM: b3AssertConstrParams(m_flags & (B3_6DOF_FLAGS_CFM_NORM << (axis * B3_6DOF_FLAGS_AXIS_SHIFT))); retVal = m_linearLimits.m_normalCFM[axis]; break; - default : + default: b3AssertConstrParams(0); } } - else if((axis >=3) && (axis < 6)) + else if ((axis >= 3) && (axis < 6)) { - switch(num) + switch (num) { - case B3_CONSTRAINT_STOP_ERP : + case B3_CONSTRAINT_STOP_ERP: b3AssertConstrParams(m_flags & (B3_6DOF_FLAGS_ERP_STOP << (axis * B3_6DOF_FLAGS_AXIS_SHIFT))); retVal = m_angularLimits[axis - 3].m_stopERP; break; - case B3_CONSTRAINT_STOP_CFM : + case B3_CONSTRAINT_STOP_CFM: b3AssertConstrParams(m_flags & (B3_6DOF_FLAGS_CFM_STOP << (axis * B3_6DOF_FLAGS_AXIS_SHIFT))); retVal = m_angularLimits[axis - 3].m_stopCFM; break; - case B3_CONSTRAINT_CFM : + case B3_CONSTRAINT_CFM: b3AssertConstrParams(m_flags & (B3_6DOF_FLAGS_CFM_NORM << (axis * B3_6DOF_FLAGS_AXIS_SHIFT))); retVal = m_angularLimits[axis - 3].m_normalCFM; break; - default : + default: b3AssertConstrParams(0); } } @@ -785,23 +717,21 @@ b3Scalar b3Generic6DofConstraint::getParam(int num, int axis) const return retVal; } - - -void b3Generic6DofConstraint::setAxis(const b3Vector3& axis1,const b3Vector3& axis2, const b3RigidBodyData* bodies) +void b3Generic6DofConstraint::setAxis(const b3Vector3& axis1, const b3Vector3& axis2, const b3RigidBodyData* bodies) { b3Vector3 zAxis = axis1.normalized(); b3Vector3 yAxis = axis2.normalized(); - b3Vector3 xAxis = yAxis.cross(zAxis); // we want right coordinate system - + b3Vector3 xAxis = yAxis.cross(zAxis); // we want right coordinate system + b3Transform frameInW; frameInW.setIdentity(); - frameInW.getBasis().setValue( xAxis[0], yAxis[0], zAxis[0], - xAxis[1], yAxis[1], zAxis[1], - xAxis[2], yAxis[2], zAxis[2]); - + frameInW.getBasis().setValue(xAxis[0], yAxis[0], zAxis[0], + xAxis[1], yAxis[1], zAxis[1], + xAxis[2], yAxis[2], zAxis[2]); + // now get constraint frame in local coordinate systems m_frameInA = getCenterOfMassTransform(bodies[m_rbA]).inverse() * frameInW; m_frameInB = getCenterOfMassTransform(bodies[m_rbB]).inverse() * frameInW; - + calculateTransforms(bodies); } diff --git a/src/Bullet3Dynamics/ConstraintSolver/b3Generic6DofConstraint.h b/src/Bullet3Dynamics/ConstraintSolver/b3Generic6DofConstraint.h index 169b1b94a..1597809db 100644 --- a/src/Bullet3Dynamics/ConstraintSolver/b3Generic6DofConstraint.h +++ b/src/Bullet3Dynamics/ConstraintSolver/b3Generic6DofConstraint.h @@ -23,7 +23,6 @@ email: projectileman@yahoo.com http://gimpact.sf.net */ - #ifndef B3_GENERIC_6DOF_CONSTRAINT_H #define B3_GENERIC_6DOF_CONSTRAINT_H @@ -33,88 +32,83 @@ http://gimpact.sf.net struct b3RigidBodyData; - - - //! Rotation Limit structure for generic joints class b3RotationalLimitMotor { public: - //! limit_parameters - //!@{ - b3Scalar m_loLimit;//!< joint limit - b3Scalar m_hiLimit;//!< joint limit - b3Scalar m_targetVelocity;//!< target motor velocity - b3Scalar m_maxMotorForce;//!< max force on motor - b3Scalar m_maxLimitForce;//!< max force on limit - b3Scalar m_damping;//!< Damping. - b3Scalar m_limitSoftness;//! Relaxation factor - b3Scalar m_normalCFM;//!< Constraint force mixing factor - b3Scalar m_stopERP;//!< Error tolerance factor when joint is at limit - b3Scalar m_stopCFM;//!< Constraint force mixing factor when joint is at limit - b3Scalar m_bounce;//!< restitution factor - bool m_enableMotor; + //! limit_parameters + //!@{ + b3Scalar m_loLimit; //!< joint limit + b3Scalar m_hiLimit; //!< joint limit + b3Scalar m_targetVelocity; //!< target motor velocity + b3Scalar m_maxMotorForce; //!< max force on motor + b3Scalar m_maxLimitForce; //!< max force on limit + b3Scalar m_damping; //!< Damping. + b3Scalar m_limitSoftness; //! Relaxation factor + b3Scalar m_normalCFM; //!< Constraint force mixing factor + b3Scalar m_stopERP; //!< Error tolerance factor when joint is at limit + b3Scalar m_stopCFM; //!< Constraint force mixing factor when joint is at limit + b3Scalar m_bounce; //!< restitution factor + bool m_enableMotor; - //!@} + //!@} - //! temp_variables - //!@{ - b3Scalar m_currentLimitError;//! How much is violated this limit - b3Scalar m_currentPosition; //! current value of angle - int m_currentLimit;//!< 0=free, 1=at lo limit, 2=at hi limit - b3Scalar m_accumulatedImpulse; - //!@} + //! temp_variables + //!@{ + b3Scalar m_currentLimitError; //! How much is violated this limit + b3Scalar m_currentPosition; //! current value of angle + int m_currentLimit; //!< 0=free, 1=at lo limit, 2=at hi limit + b3Scalar m_accumulatedImpulse; + //!@} - b3RotationalLimitMotor() - { - m_accumulatedImpulse = 0.f; - m_targetVelocity = 0; - m_maxMotorForce = 6.0f; - m_maxLimitForce = 300.0f; - m_loLimit = 1.0f; - m_hiLimit = -1.0f; + b3RotationalLimitMotor() + { + m_accumulatedImpulse = 0.f; + m_targetVelocity = 0; + m_maxMotorForce = 6.0f; + m_maxLimitForce = 300.0f; + m_loLimit = 1.0f; + m_hiLimit = -1.0f; m_normalCFM = 0.f; m_stopERP = 0.2f; m_stopCFM = 0.f; - m_bounce = 0.0f; - m_damping = 1.0f; - m_limitSoftness = 0.5f; - m_currentLimit = 0; - m_currentLimitError = 0; - m_enableMotor = false; - } + m_bounce = 0.0f; + m_damping = 1.0f; + m_limitSoftness = 0.5f; + m_currentLimit = 0; + m_currentLimitError = 0; + m_enableMotor = false; + } - b3RotationalLimitMotor(const b3RotationalLimitMotor & limot) - { - m_targetVelocity = limot.m_targetVelocity; - m_maxMotorForce = limot.m_maxMotorForce; - m_limitSoftness = limot.m_limitSoftness; - m_loLimit = limot.m_loLimit; - m_hiLimit = limot.m_hiLimit; + b3RotationalLimitMotor(const b3RotationalLimitMotor& limot) + { + m_targetVelocity = limot.m_targetVelocity; + m_maxMotorForce = limot.m_maxMotorForce; + m_limitSoftness = limot.m_limitSoftness; + m_loLimit = limot.m_loLimit; + m_hiLimit = limot.m_hiLimit; m_normalCFM = limot.m_normalCFM; m_stopERP = limot.m_stopERP; - m_stopCFM = limot.m_stopCFM; - m_bounce = limot.m_bounce; - m_currentLimit = limot.m_currentLimit; - m_currentLimitError = limot.m_currentLimitError; - m_enableMotor = limot.m_enableMotor; - } - - + m_stopCFM = limot.m_stopCFM; + m_bounce = limot.m_bounce; + m_currentLimit = limot.m_currentLimit; + m_currentLimitError = limot.m_currentLimitError; + m_enableMotor = limot.m_enableMotor; + } //! Is limited - bool isLimited() - { - if(m_loLimit > m_hiLimit) return false; - return true; - } + bool isLimited() + { + if (m_loLimit > m_hiLimit) return false; + return true; + } //! Need apply correction - bool needApplyTorques() - { - if(m_currentLimit == 0 && m_enableMotor == false) return false; - return true; - } + bool needApplyTorques() + { + if (m_currentLimit == 0 && m_enableMotor == false) return false; + return true; + } //! calculates error /*! @@ -123,104 +117,98 @@ public: int testLimitValue(b3Scalar test_value); //! apply the correction impulses for two bodies - b3Scalar solveAngularLimits(b3Scalar timeStep,b3Vector3& axis, b3Scalar jacDiagABInv,b3RigidBodyData * body0, b3RigidBodyData * body1); - + b3Scalar solveAngularLimits(b3Scalar timeStep, b3Vector3& axis, b3Scalar jacDiagABInv, b3RigidBodyData* body0, b3RigidBodyData* body1); }; - - class b3TranslationalLimitMotor { public: - b3Vector3 m_lowerLimit;//!< the constraint lower limits - b3Vector3 m_upperLimit;//!< the constraint upper limits - b3Vector3 m_accumulatedImpulse; - //! Linear_Limit_parameters - //!@{ - b3Vector3 m_normalCFM;//!< Constraint force mixing factor - b3Vector3 m_stopERP;//!< Error tolerance factor when joint is at limit - b3Vector3 m_stopCFM;//!< Constraint force mixing factor when joint is at limit - b3Vector3 m_targetVelocity;//!< target motor velocity - b3Vector3 m_maxMotorForce;//!< max force on motor - b3Vector3 m_currentLimitError;//! How much is violated this limit - b3Vector3 m_currentLinearDiff;//! Current relative offset of constraint frames - b3Scalar m_limitSoftness;//!< Softness for linear limit - b3Scalar m_damping;//!< Damping for linear limit - b3Scalar m_restitution;//! Bounce parameter for linear limit + b3Vector3 m_lowerLimit; //!< the constraint lower limits + b3Vector3 m_upperLimit; //!< the constraint upper limits + b3Vector3 m_accumulatedImpulse; + //! Linear_Limit_parameters + //!@{ + b3Vector3 m_normalCFM; //!< Constraint force mixing factor + b3Vector3 m_stopERP; //!< Error tolerance factor when joint is at limit + b3Vector3 m_stopCFM; //!< Constraint force mixing factor when joint is at limit + b3Vector3 m_targetVelocity; //!< target motor velocity + b3Vector3 m_maxMotorForce; //!< max force on motor + b3Vector3 m_currentLimitError; //! How much is violated this limit + b3Vector3 m_currentLinearDiff; //! Current relative offset of constraint frames + b3Scalar m_limitSoftness; //!< Softness for linear limit + b3Scalar m_damping; //!< Damping for linear limit + b3Scalar m_restitution; //! Bounce parameter for linear limit //!@} - bool m_enableMotor[3]; - int m_currentLimit[3];//!< 0=free, 1=at lower limit, 2=at upper limit + bool m_enableMotor[3]; + int m_currentLimit[3]; //!< 0=free, 1=at lower limit, 2=at upper limit - b3TranslationalLimitMotor() - { - m_lowerLimit.setValue(0.f,0.f,0.f); - m_upperLimit.setValue(0.f,0.f,0.f); - m_accumulatedImpulse.setValue(0.f,0.f,0.f); + b3TranslationalLimitMotor() + { + m_lowerLimit.setValue(0.f, 0.f, 0.f); + m_upperLimit.setValue(0.f, 0.f, 0.f); + m_accumulatedImpulse.setValue(0.f, 0.f, 0.f); m_normalCFM.setValue(0.f, 0.f, 0.f); m_stopERP.setValue(0.2f, 0.2f, 0.2f); m_stopCFM.setValue(0.f, 0.f, 0.f); - m_limitSoftness = 0.7f; - m_damping = b3Scalar(1.0f); - m_restitution = b3Scalar(0.5f); - for(int i=0; i < 3; i++) + m_limitSoftness = 0.7f; + m_damping = b3Scalar(1.0f); + m_restitution = b3Scalar(0.5f); + for (int i = 0; i < 3; i++) { m_enableMotor[i] = false; m_targetVelocity[i] = b3Scalar(0.f); m_maxMotorForce[i] = b3Scalar(0.f); } - } + } - b3TranslationalLimitMotor(const b3TranslationalLimitMotor & other ) - { - m_lowerLimit = other.m_lowerLimit; - m_upperLimit = other.m_upperLimit; - m_accumulatedImpulse = other.m_accumulatedImpulse; + b3TranslationalLimitMotor(const b3TranslationalLimitMotor& other) + { + m_lowerLimit = other.m_lowerLimit; + m_upperLimit = other.m_upperLimit; + m_accumulatedImpulse = other.m_accumulatedImpulse; - m_limitSoftness = other.m_limitSoftness ; - m_damping = other.m_damping; - m_restitution = other.m_restitution; + m_limitSoftness = other.m_limitSoftness; + m_damping = other.m_damping; + m_restitution = other.m_restitution; m_normalCFM = other.m_normalCFM; m_stopERP = other.m_stopERP; m_stopCFM = other.m_stopCFM; - for(int i=0; i < 3; i++) + for (int i = 0; i < 3; i++) { m_enableMotor[i] = other.m_enableMotor[i]; m_targetVelocity[i] = other.m_targetVelocity[i]; m_maxMotorForce[i] = other.m_maxMotorForce[i]; } - } + } - //! Test limit + //! Test limit /*! - free means upper < lower, - locked means upper == lower - limited means upper > lower - limitIndex: first 3 are linear, next 3 are angular */ - inline bool isLimited(int limitIndex) - { - return (m_upperLimit[limitIndex] >= m_lowerLimit[limitIndex]); - } - inline bool needApplyForce(int limitIndex) - { - if(m_currentLimit[limitIndex] == 0 && m_enableMotor[limitIndex] == false) return false; - return true; - } + inline bool isLimited(int limitIndex) + { + return (m_upperLimit[limitIndex] >= m_lowerLimit[limitIndex]); + } + inline bool needApplyForce(int limitIndex) + { + if (m_currentLimit[limitIndex] == 0 && m_enableMotor[limitIndex] == false) return false; + return true; + } int testLimitValue(int limitIndex, b3Scalar test_value); - - b3Scalar solveLinearAxis( - b3Scalar timeStep, - b3Scalar jacDiagABInv, - b3RigidBodyData& body1,const b3Vector3 &pointInA, - b3RigidBodyData& body2,const b3Vector3 &pointInB, - int limit_index, - const b3Vector3 & axis_normal_on_a, - const b3Vector3 & anchorPos); - - + b3Scalar solveLinearAxis( + b3Scalar timeStep, + b3Scalar jacDiagABInv, + b3RigidBodyData& body1, const b3Vector3& pointInA, + b3RigidBodyData& body2, const b3Vector3& pointInB, + int limit_index, + const b3Vector3& axis_normal_on_a, + const b3Vector3& anchorPos); }; enum b36DofFlags @@ -229,8 +217,7 @@ enum b36DofFlags B3_6DOF_FLAGS_CFM_STOP = 2, B3_6DOF_FLAGS_ERP_STOP = 4 }; -#define B3_6DOF_FLAGS_AXIS_SHIFT 3 // bits per axis - +#define B3_6DOF_FLAGS_AXIS_SHIFT 3 // bits per axis /// b3Generic6DofConstraint between two rigidbodies each with a pivotpoint that descibes the axis location in local space /*! @@ -268,240 +255,229 @@ This brings support for limit parameters and motors. */ -B3_ATTRIBUTE_ALIGNED16(class) b3Generic6DofConstraint : public b3TypedConstraint +B3_ATTRIBUTE_ALIGNED16(class) +b3Generic6DofConstraint : public b3TypedConstraint { protected: - //! relative_frames - //!@{ - b3Transform m_frameInA;//!< the constraint space w.r.t body A - b3Transform m_frameInB;//!< the constraint space w.r.t body B - //!@} - - //! Jacobians - //!@{ -// b3JacobianEntry m_jacLinear[3];//!< 3 orthogonal linear constraints -// b3JacobianEntry m_jacAng[3];//!< 3 orthogonal angular constraints - //!@} - - //! Linear_Limit_parameters - //!@{ - b3TranslationalLimitMotor m_linearLimits; - //!@} - - - //! hinge_parameters - //!@{ - b3RotationalLimitMotor m_angularLimits[3]; + //!@{ + b3Transform m_frameInA; //!< the constraint space w.r.t body A + b3Transform m_frameInB; //!< the constraint space w.r.t body B //!@} + //! Jacobians + //!@{ + // b3JacobianEntry m_jacLinear[3];//!< 3 orthogonal linear constraints + // b3JacobianEntry m_jacAng[3];//!< 3 orthogonal angular constraints + //!@} + + //! Linear_Limit_parameters + //!@{ + b3TranslationalLimitMotor m_linearLimits; + //!@} + + //! hinge_parameters + //!@{ + b3RotationalLimitMotor m_angularLimits[3]; + //!@} protected: - //! temporal variables - //!@{ - b3Transform m_calculatedTransformA; - b3Transform m_calculatedTransformB; - b3Vector3 m_calculatedAxisAngleDiff; - b3Vector3 m_calculatedAxis[3]; - b3Vector3 m_calculatedLinearDiff; - b3Scalar m_timeStep; - b3Scalar m_factA; - b3Scalar m_factB; - bool m_hasStaticBody; - - b3Vector3 m_AnchorPos; // point betwen pivots of bodies A and B to solve linear axes + //! temporal variables + //!@{ + b3Transform m_calculatedTransformA; + b3Transform m_calculatedTransformB; + b3Vector3 m_calculatedAxisAngleDiff; + b3Vector3 m_calculatedAxis[3]; + b3Vector3 m_calculatedLinearDiff; + b3Scalar m_timeStep; + b3Scalar m_factA; + b3Scalar m_factB; + bool m_hasStaticBody; - bool m_useLinearReferenceFrameA; - bool m_useOffsetForConstraintFrame; - - int m_flags; + b3Vector3 m_AnchorPos; // point betwen pivots of bodies A and B to solve linear axes - //!@} + bool m_useLinearReferenceFrameA; + bool m_useOffsetForConstraintFrame; - b3Generic6DofConstraint& operator=(b3Generic6DofConstraint& other) - { - b3Assert(0); - (void) other; - return *this; - } + int m_flags; + //!@} - int setAngularLimits(b3ConstraintInfo2 *info, int row_offset,const b3Transform& transA,const b3Transform& transB,const b3Vector3& linVelA,const b3Vector3& linVelB,const b3Vector3& angVelA,const b3Vector3& angVelB); + b3Generic6DofConstraint& operator=(b3Generic6DofConstraint& other) + { + b3Assert(0); + (void)other; + return *this; + } - int setLinearLimits(b3ConstraintInfo2 *info, int row, const b3Transform& transA,const b3Transform& transB,const b3Vector3& linVelA,const b3Vector3& linVelB,const b3Vector3& angVelA,const b3Vector3& angVelB); + int setAngularLimits(b3ConstraintInfo2 * info, int row_offset, const b3Transform& transA, const b3Transform& transB, const b3Vector3& linVelA, const b3Vector3& linVelB, const b3Vector3& angVelA, const b3Vector3& angVelB); + int setLinearLimits(b3ConstraintInfo2 * info, int row, const b3Transform& transA, const b3Transform& transB, const b3Vector3& linVelA, const b3Vector3& linVelB, const b3Vector3& angVelA, const b3Vector3& angVelB); // tests linear limits void calculateLinearInfo(); //! calcs the euler angles between the two bodies. - void calculateAngleInfo(); - - + void calculateAngleInfo(); public: - B3_DECLARE_ALIGNED_ALLOCATOR(); - - b3Generic6DofConstraint(int rbA, int rbB, const b3Transform& frameInA, const b3Transform& frameInB ,bool useLinearReferenceFrameA,const b3RigidBodyData* bodies); - + + b3Generic6DofConstraint(int rbA, int rbB, const b3Transform& frameInA, const b3Transform& frameInB, bool useLinearReferenceFrameA, const b3RigidBodyData* bodies); + //! Calcs global transform of the offsets /*! Calcs the global transform for the joint offset for body A an B, and also calcs the agle differences between the bodies. \sa b3Generic6DofConstraint.getCalculatedTransformA , b3Generic6DofConstraint.getCalculatedTransformB, b3Generic6DofConstraint.calculateAngleInfo */ - void calculateTransforms(const b3Transform& transA,const b3Transform& transB,const b3RigidBodyData* bodies); + void calculateTransforms(const b3Transform& transA, const b3Transform& transB, const b3RigidBodyData* bodies); void calculateTransforms(const b3RigidBodyData* bodies); //! Gets the global transform of the offset for body A - /*! + /*! \sa b3Generic6DofConstraint.getFrameOffsetA, b3Generic6DofConstraint.getFrameOffsetB, b3Generic6DofConstraint.calculateAngleInfo. */ - const b3Transform & getCalculatedTransformA() const - { - return m_calculatedTransformA; - } + const b3Transform& getCalculatedTransformA() const + { + return m_calculatedTransformA; + } - //! Gets the global transform of the offset for body B - /*! + //! Gets the global transform of the offset for body B + /*! \sa b3Generic6DofConstraint.getFrameOffsetA, b3Generic6DofConstraint.getFrameOffsetB, b3Generic6DofConstraint.calculateAngleInfo. */ - const b3Transform & getCalculatedTransformB() const - { - return m_calculatedTransformB; - } + const b3Transform& getCalculatedTransformB() const + { + return m_calculatedTransformB; + } - const b3Transform & getFrameOffsetA() const - { - return m_frameInA; - } + const b3Transform& getFrameOffsetA() const + { + return m_frameInA; + } - const b3Transform & getFrameOffsetB() const - { - return m_frameInB; - } + const b3Transform& getFrameOffsetB() const + { + return m_frameInB; + } + b3Transform& getFrameOffsetA() + { + return m_frameInA; + } - b3Transform & getFrameOffsetA() - { - return m_frameInA; - } + b3Transform& getFrameOffsetB() + { + return m_frameInB; + } - b3Transform & getFrameOffsetB() - { - return m_frameInB; - } + virtual void getInfo1(b3ConstraintInfo1 * info, const b3RigidBodyData* bodies); + void getInfo1NonVirtual(b3ConstraintInfo1 * info, const b3RigidBodyData* bodies); + virtual void getInfo2(b3ConstraintInfo2 * info, const b3RigidBodyData* bodies); - virtual void getInfo1 (b3ConstraintInfo1* info,const b3RigidBodyData* bodies); + void getInfo2NonVirtual(b3ConstraintInfo2 * info, const b3Transform& transA, const b3Transform& transB, const b3Vector3& linVelA, const b3Vector3& linVelB, const b3Vector3& angVelA, const b3Vector3& angVelB, const b3RigidBodyData* bodies); - void getInfo1NonVirtual (b3ConstraintInfo1* info,const b3RigidBodyData* bodies); - - virtual void getInfo2 (b3ConstraintInfo2* info,const b3RigidBodyData* bodies); - - void getInfo2NonVirtual (b3ConstraintInfo2* info,const b3Transform& transA,const b3Transform& transB,const b3Vector3& linVelA,const b3Vector3& linVelB,const b3Vector3& angVelA,const b3Vector3& angVelB,const b3RigidBodyData* bodies); - - - void updateRHS(b3Scalar timeStep); + void updateRHS(b3Scalar timeStep); //! Get the rotation axis in global coordinates - b3Vector3 getAxis(int axis_index) const; + b3Vector3 getAxis(int axis_index) const; - //! Get the relative Euler angle - /*! + //! Get the relative Euler angle + /*! \pre b3Generic6DofConstraint::calculateTransforms() must be called previously. */ - b3Scalar getAngle(int axis_index) const; + b3Scalar getAngle(int axis_index) const; //! Get the relative position of the constraint pivot - /*! + /*! \pre b3Generic6DofConstraint::calculateTransforms() must be called previously. */ b3Scalar getRelativePivotPosition(int axis_index) const; - void setFrames(const b3Transform & frameA, const b3Transform & frameB, const b3RigidBodyData* bodies); + void setFrames(const b3Transform& frameA, const b3Transform& frameB, const b3RigidBodyData* bodies); //! Test angular limit. /*! Calculates angular correction and returns true if limit needs to be corrected. \pre b3Generic6DofConstraint::calculateTransforms() must be called previously. */ - bool testAngularLimitMotor(int axis_index); + bool testAngularLimitMotor(int axis_index); - void setLinearLowerLimit(const b3Vector3& linearLower) - { - m_linearLimits.m_lowerLimit = linearLower; - } + void setLinearLowerLimit(const b3Vector3& linearLower) + { + m_linearLimits.m_lowerLimit = linearLower; + } - void getLinearLowerLimit(b3Vector3& linearLower) + void getLinearLowerLimit(b3Vector3 & linearLower) { linearLower = m_linearLimits.m_lowerLimit; } - void setLinearUpperLimit(const b3Vector3& linearUpper) + void setLinearUpperLimit(const b3Vector3& linearUpper) { m_linearLimits.m_upperLimit = linearUpper; } - void getLinearUpperLimit(b3Vector3& linearUpper) + void getLinearUpperLimit(b3Vector3 & linearUpper) { linearUpper = m_linearLimits.m_upperLimit; } - void setAngularLowerLimit(const b3Vector3& angularLower) - { - for(int i = 0; i < 3; i++) - m_angularLimits[i].m_loLimit = b3NormalizeAngle(angularLower[i]); - } - - void getAngularLowerLimit(b3Vector3& angularLower) + void setAngularLowerLimit(const b3Vector3& angularLower) { - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) + m_angularLimits[i].m_loLimit = b3NormalizeAngle(angularLower[i]); + } + + void getAngularLowerLimit(b3Vector3 & angularLower) + { + for (int i = 0; i < 3; i++) angularLower[i] = m_angularLimits[i].m_loLimit; } - void setAngularUpperLimit(const b3Vector3& angularUpper) - { - for(int i = 0; i < 3; i++) - m_angularLimits[i].m_hiLimit = b3NormalizeAngle(angularUpper[i]); - } - - void getAngularUpperLimit(b3Vector3& angularUpper) + void setAngularUpperLimit(const b3Vector3& angularUpper) { - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) + m_angularLimits[i].m_hiLimit = b3NormalizeAngle(angularUpper[i]); + } + + void getAngularUpperLimit(b3Vector3 & angularUpper) + { + for (int i = 0; i < 3; i++) angularUpper[i] = m_angularLimits[i].m_hiLimit; } //! Retrieves the angular limit informacion - b3RotationalLimitMotor * getRotationalLimitMotor(int index) - { - return &m_angularLimits[index]; - } + b3RotationalLimitMotor* getRotationalLimitMotor(int index) + { + return &m_angularLimits[index]; + } - //! Retrieves the limit informacion - b3TranslationalLimitMotor * getTranslationalLimitMotor() - { - return &m_linearLimits; - } + //! Retrieves the limit informacion + b3TranslationalLimitMotor* getTranslationalLimitMotor() + { + return &m_linearLimits; + } - //first 3 are linear, next 3 are angular - void setLimit(int axis, b3Scalar lo, b3Scalar hi) - { - if(axis<3) - { - m_linearLimits.m_lowerLimit[axis] = lo; - m_linearLimits.m_upperLimit[axis] = hi; - } - else - { + //first 3 are linear, next 3 are angular + void setLimit(int axis, b3Scalar lo, b3Scalar hi) + { + if (axis < 3) + { + m_linearLimits.m_lowerLimit[axis] = lo; + m_linearLimits.m_upperLimit[axis] = hi; + } + else + { lo = b3NormalizeAngle(lo); hi = b3NormalizeAngle(hi); - m_angularLimits[axis-3].m_loLimit = lo; - m_angularLimits[axis-3].m_hiLimit = hi; - } - } + m_angularLimits[axis - 3].m_loLimit = lo; + m_angularLimits[axis - 3].m_hiLimit = hi; + } + } //! Test limit /*! @@ -510,41 +486,32 @@ public: - limited means upper > lower - limitIndex: first 3 are linear, next 3 are angular */ - bool isLimited(int limitIndex) - { - if(limitIndex<3) - { + bool isLimited(int limitIndex) + { + if (limitIndex < 3) + { return m_linearLimits.isLimited(limitIndex); + } + return m_angularLimits[limitIndex - 3].isLimited(); + } - } - return m_angularLimits[limitIndex-3].isLimited(); - } + virtual void calcAnchorPos(const b3RigidBodyData* bodies); // overridable - virtual void calcAnchorPos(const b3RigidBodyData* bodies); // overridable - - int get_limit_motor_info2( b3RotationalLimitMotor * limot, - const b3Transform& transA,const b3Transform& transB,const b3Vector3& linVelA,const b3Vector3& linVelB,const b3Vector3& angVelA,const b3Vector3& angVelB, - b3ConstraintInfo2 *info, int row, b3Vector3& ax1, int rotational, int rotAllowed = false); + int get_limit_motor_info2(b3RotationalLimitMotor * limot, + const b3Transform& transA, const b3Transform& transB, const b3Vector3& linVelA, const b3Vector3& linVelB, const b3Vector3& angVelA, const b3Vector3& angVelB, + b3ConstraintInfo2* info, int row, b3Vector3& ax1, int rotational, int rotAllowed = false); // access for UseFrameOffset bool getUseFrameOffset() { return m_useOffsetForConstraintFrame; } void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; } - ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). + ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). ///If no axis is provided, it uses the default axis for this constraint. - virtual void setParam(int num, b3Scalar value, int axis = -1); + virtual void setParam(int num, b3Scalar value, int axis = -1); ///return the local value of parameter - virtual b3Scalar getParam(int num, int axis = -1) const; + virtual b3Scalar getParam(int num, int axis = -1) const; - void setAxis( const b3Vector3& axis1, const b3Vector3& axis2,const b3RigidBodyData* bodies); - - - - + void setAxis(const b3Vector3& axis1, const b3Vector3& axis2, const b3RigidBodyData* bodies); }; - - - - -#endif //B3_GENERIC_6DOF_CONSTRAINT_H +#endif //B3_GENERIC_6DOF_CONSTRAINT_H diff --git a/src/Bullet3Dynamics/ConstraintSolver/b3JacobianEntry.h b/src/Bullet3Dynamics/ConstraintSolver/b3JacobianEntry.h index a55168eb3..13269debf 100644 --- a/src/Bullet3Dynamics/ConstraintSolver/b3JacobianEntry.h +++ b/src/Bullet3Dynamics/ConstraintSolver/b3JacobianEntry.h @@ -18,7 +18,6 @@ subject to the following restrictions: #include "Bullet3Common/b3Matrix3x3.h" - //notes: // Another memory optimization would be to store m_1MinvJt in the remaining 3 w components // which makes the b3JacobianEntry memory layout 16 bytes @@ -27,25 +26,26 @@ subject to the following restrictions: /// Jacobian entry is an abstraction that allows to describe constraints /// it can be used in combination with a constraint solver /// Can be used to relate the effect of an impulse to the constraint error -B3_ATTRIBUTE_ALIGNED16(class) b3JacobianEntry +B3_ATTRIBUTE_ALIGNED16(class) +b3JacobianEntry { public: - b3JacobianEntry() {}; + b3JacobianEntry(){}; //constraint between two different rigidbodies b3JacobianEntry( const b3Matrix3x3& world2A, const b3Matrix3x3& world2B, - const b3Vector3& rel_pos1,const b3Vector3& rel_pos2, + const b3Vector3& rel_pos1, const b3Vector3& rel_pos2, const b3Vector3& jointAxis, - const b3Vector3& inertiaInvA, + const b3Vector3& inertiaInvA, const b3Scalar massInvA, const b3Vector3& inertiaInvB, const b3Scalar massInvB) - :m_linearJointAxis(jointAxis) + : m_linearJointAxis(jointAxis) { - m_aJ = world2A*(rel_pos1.cross(m_linearJointAxis)); - m_bJ = world2B*(rel_pos2.cross(-m_linearJointAxis)); - m_0MinvJt = inertiaInvA * m_aJ; + m_aJ = world2A * (rel_pos1.cross(m_linearJointAxis)); + m_bJ = world2B * (rel_pos2.cross(-m_linearJointAxis)); + m_0MinvJt = inertiaInvA * m_aJ; m_1MinvJt = inertiaInvB * m_bJ; m_Adiag = massInvA + m_0MinvJt.dot(m_aJ) + massInvB + m_1MinvJt.dot(m_bJ); @@ -54,33 +54,31 @@ public: //angular constraint between two different rigidbodies b3JacobianEntry(const b3Vector3& jointAxis, - const b3Matrix3x3& world2A, - const b3Matrix3x3& world2B, - const b3Vector3& inertiaInvA, - const b3Vector3& inertiaInvB) - :m_linearJointAxis(b3MakeVector3(b3Scalar(0.),b3Scalar(0.),b3Scalar(0.))) + const b3Matrix3x3& world2A, + const b3Matrix3x3& world2B, + const b3Vector3& inertiaInvA, + const b3Vector3& inertiaInvB) + : m_linearJointAxis(b3MakeVector3(b3Scalar(0.), b3Scalar(0.), b3Scalar(0.))) { - m_aJ= world2A*jointAxis; - m_bJ = world2B*-jointAxis; - m_0MinvJt = inertiaInvA * m_aJ; + m_aJ = world2A * jointAxis; + m_bJ = world2B * -jointAxis; + m_0MinvJt = inertiaInvA * m_aJ; m_1MinvJt = inertiaInvB * m_bJ; - m_Adiag = m_0MinvJt.dot(m_aJ) + m_1MinvJt.dot(m_bJ); + m_Adiag = m_0MinvJt.dot(m_aJ) + m_1MinvJt.dot(m_bJ); b3Assert(m_Adiag > b3Scalar(0.0)); } //angular constraint between two different rigidbodies b3JacobianEntry(const b3Vector3& axisInA, - const b3Vector3& axisInB, - const b3Vector3& inertiaInvA, - const b3Vector3& inertiaInvB) - : m_linearJointAxis(b3MakeVector3(b3Scalar(0.),b3Scalar(0.),b3Scalar(0.))) - , m_aJ(axisInA) - , m_bJ(-axisInB) + const b3Vector3& axisInB, + const b3Vector3& inertiaInvA, + const b3Vector3& inertiaInvB) + : m_linearJointAxis(b3MakeVector3(b3Scalar(0.), b3Scalar(0.), b3Scalar(0.))), m_aJ(axisInA), m_bJ(-axisInB) { - m_0MinvJt = inertiaInvA * m_aJ; + m_0MinvJt = inertiaInvA * m_aJ; m_1MinvJt = inertiaInvB * m_bJ; - m_Adiag = m_0MinvJt.dot(m_aJ) + m_1MinvJt.dot(m_bJ); + m_Adiag = m_0MinvJt.dot(m_aJ) + m_1MinvJt.dot(m_bJ); b3Assert(m_Adiag > b3Scalar(0.0)); } @@ -88,25 +86,25 @@ public: //constraint on one rigidbody b3JacobianEntry( const b3Matrix3x3& world2A, - const b3Vector3& rel_pos1,const b3Vector3& rel_pos2, + const b3Vector3& rel_pos1, const b3Vector3& rel_pos2, const b3Vector3& jointAxis, - const b3Vector3& inertiaInvA, + const b3Vector3& inertiaInvA, const b3Scalar massInvA) - :m_linearJointAxis(jointAxis) + : m_linearJointAxis(jointAxis) { - m_aJ= world2A*(rel_pos1.cross(jointAxis)); - m_bJ = world2A*(rel_pos2.cross(-jointAxis)); - m_0MinvJt = inertiaInvA * m_aJ; - m_1MinvJt = b3MakeVector3(b3Scalar(0.),b3Scalar(0.),b3Scalar(0.)); + m_aJ = world2A * (rel_pos1.cross(jointAxis)); + m_bJ = world2A * (rel_pos2.cross(-jointAxis)); + m_0MinvJt = inertiaInvA * m_aJ; + m_1MinvJt = b3MakeVector3(b3Scalar(0.), b3Scalar(0.), b3Scalar(0.)); m_Adiag = massInvA + m_0MinvJt.dot(m_aJ); b3Assert(m_Adiag > b3Scalar(0.0)); } - b3Scalar getDiagonal() const { return m_Adiag; } + b3Scalar getDiagonal() const { return m_Adiag; } // for two constraints on the same rigidbody (for example vehicle friction) - b3Scalar getNonDiagonal(const b3JacobianEntry& jacB, const b3Scalar massInvA) const + b3Scalar getNonDiagonal(const b3JacobianEntry& jacB, const b3Scalar massInvA) const { const b3JacobianEntry& jacA = *this; b3Scalar lin = massInvA * jacA.m_linearJointAxis.dot(jacB.m_linearJointAxis); @@ -114,42 +112,39 @@ public: return lin + ang; } - - // for two constraints on sharing two same rigidbodies (for example two contact points between two rigidbodies) - b3Scalar getNonDiagonal(const b3JacobianEntry& jacB,const b3Scalar massInvA,const b3Scalar massInvB) const + b3Scalar getNonDiagonal(const b3JacobianEntry& jacB, const b3Scalar massInvA, const b3Scalar massInvB) const { const b3JacobianEntry& jacA = *this; b3Vector3 lin = jacA.m_linearJointAxis * jacB.m_linearJointAxis; b3Vector3 ang0 = jacA.m_0MinvJt * jacB.m_aJ; b3Vector3 ang1 = jacA.m_1MinvJt * jacB.m_bJ; - b3Vector3 lin0 = massInvA * lin ; + b3Vector3 lin0 = massInvA * lin; b3Vector3 lin1 = massInvB * lin; - b3Vector3 sum = ang0+ang1+lin0+lin1; - return sum[0]+sum[1]+sum[2]; + b3Vector3 sum = ang0 + ang1 + lin0 + lin1; + return sum[0] + sum[1] + sum[2]; } - b3Scalar getRelativeVelocity(const b3Vector3& linvelA,const b3Vector3& angvelA,const b3Vector3& linvelB,const b3Vector3& angvelB) + b3Scalar getRelativeVelocity(const b3Vector3& linvelA, const b3Vector3& angvelA, const b3Vector3& linvelB, const b3Vector3& angvelB) { b3Vector3 linrel = linvelA - linvelB; - b3Vector3 angvela = angvelA * m_aJ; - b3Vector3 angvelb = angvelB * m_bJ; + b3Vector3 angvela = angvelA * m_aJ; + b3Vector3 angvelb = angvelB * m_bJ; linrel *= m_linearJointAxis; angvela += angvelb; angvela += linrel; - b3Scalar rel_vel2 = angvela[0]+angvela[1]+angvela[2]; + b3Scalar rel_vel2 = angvela[0] + angvela[1] + angvela[2]; return rel_vel2 + B3_EPSILON; } -//private: + //private: - b3Vector3 m_linearJointAxis; - b3Vector3 m_aJ; - b3Vector3 m_bJ; - b3Vector3 m_0MinvJt; - b3Vector3 m_1MinvJt; + b3Vector3 m_linearJointAxis; + b3Vector3 m_aJ; + b3Vector3 m_bJ; + b3Vector3 m_0MinvJt; + b3Vector3 m_1MinvJt; //Optimization: can be stored in the w/last component of one of the vectors - b3Scalar m_Adiag; - + b3Scalar m_Adiag; }; -#endif //B3_JACOBIAN_ENTRY_H +#endif //B3_JACOBIAN_ENTRY_H diff --git a/src/Bullet3Dynamics/ConstraintSolver/b3PgsJacobiSolver.cpp b/src/Bullet3Dynamics/ConstraintSolver/b3PgsJacobiSolver.cpp index de729d455..b7050b107 100644 --- a/src/Bullet3Dynamics/ConstraintSolver/b3PgsJacobiSolver.cpp +++ b/src/Bullet3Dynamics/ConstraintSolver/b3PgsJacobiSolver.cpp @@ -29,14 +29,13 @@ subject to the following restrictions: //#include "b3SolverBody.h" //#include "b3SolverConstraint.h" #include "Bullet3Common/b3AlignedObjectArray.h" -#include //for memset +#include //for memset //#include "../../dynamics/basic_demo/Stubs/AdlContact4.h" #include "Bullet3Collision/NarrowPhaseCollision/b3Contact4.h" - #include "Bullet3Collision/NarrowPhaseCollision/shared/b3RigidBodyData.h" -static b3Transform getWorldTransform(b3RigidBodyData* rb) +static b3Transform getWorldTransform(b3RigidBodyData* rb) { b3Transform newTrans; newTrans.setOrigin(rb->m_pos); @@ -44,19 +43,17 @@ static b3Transform getWorldTransform(b3RigidBodyData* rb) return newTrans; } -static const b3Matrix3x3& getInvInertiaTensorWorld(b3InertiaData* inertia) +static const b3Matrix3x3& getInvInertiaTensorWorld(b3InertiaData* inertia) { return inertia->m_invInertiaWorld; } - - -static const b3Vector3& getLinearVelocity(b3RigidBodyData* rb) +static const b3Vector3& getLinearVelocity(b3RigidBodyData* rb) { return rb->m_linVel; } -static const b3Vector3& getAngularVelocity(b3RigidBodyData* rb) +static const b3Vector3& getAngularVelocity(b3RigidBodyData* rb) { return rb->m_angVel; } @@ -65,47 +62,46 @@ static b3Vector3 getVelocityInLocalPoint(b3RigidBodyData* rb, const b3Vector3& r { //we also calculate lin/ang velocity for kinematic objects return getLinearVelocity(rb) + getAngularVelocity(rb).cross(rel_pos); - } -struct b3ContactPoint +struct b3ContactPoint { - b3Vector3 m_positionWorldOnA; - b3Vector3 m_positionWorldOnB; - b3Vector3 m_normalWorldOnB; - b3Scalar m_appliedImpulse; - b3Scalar m_distance; - b3Scalar m_combinedRestitution; + b3Vector3 m_positionWorldOnA; + b3Vector3 m_positionWorldOnB; + b3Vector3 m_normalWorldOnB; + b3Scalar m_appliedImpulse; + b3Scalar m_distance; + b3Scalar m_combinedRestitution; ///information related to friction - b3Scalar m_combinedFriction; - b3Vector3 m_lateralFrictionDir1; - b3Vector3 m_lateralFrictionDir2; - b3Scalar m_appliedImpulseLateral1; - b3Scalar m_appliedImpulseLateral2; - b3Scalar m_combinedRollingFriction; - b3Scalar m_contactMotion1; - b3Scalar m_contactMotion2; - b3Scalar m_contactCFM1; - b3Scalar m_contactCFM2; - - bool m_lateralFrictionInitialized; + b3Scalar m_combinedFriction; + b3Vector3 m_lateralFrictionDir1; + b3Vector3 m_lateralFrictionDir2; + b3Scalar m_appliedImpulseLateral1; + b3Scalar m_appliedImpulseLateral2; + b3Scalar m_combinedRollingFriction; + b3Scalar m_contactMotion1; + b3Scalar m_contactMotion2; + b3Scalar m_contactCFM1; + b3Scalar m_contactCFM2; - b3Vector3 getPositionWorldOnA() + bool m_lateralFrictionInitialized; + + b3Vector3 getPositionWorldOnA() { return m_positionWorldOnA; } - b3Vector3 getPositionWorldOnB() + b3Vector3 getPositionWorldOnB() { return m_positionWorldOnB; } - b3Scalar getDistance() + b3Scalar getDistance() { return m_distance; } }; -void getContactPoint(b3Contact4* contact, int contactIndex, b3ContactPoint& pointOut) +void getContactPoint(b3Contact4* contact, int contactIndex, b3ContactPoint& pointOut) { pointOut.m_appliedImpulse = 0.f; pointOut.m_appliedImpulseLateral1 = 0.f; @@ -117,160 +113,145 @@ void getContactPoint(b3Contact4* contact, int contactIndex, b3ContactPoint& poin pointOut.m_contactCFM2 = 0.f; pointOut.m_contactMotion1 = 0.f; pointOut.m_contactMotion2 = 0.f; - pointOut.m_distance = contact->getPenetration(contactIndex);//??0.01f + pointOut.m_distance = contact->getPenetration(contactIndex); //??0.01f b3Vector3 normalOnB = contact->m_worldNormalOnB; - normalOnB.normalize();//is this needed? + normalOnB.normalize(); //is this needed? - b3Vector3 l1,l2; - b3PlaneSpace1(normalOnB,l1,l2); + b3Vector3 l1, l2; + b3PlaneSpace1(normalOnB, l1, l2); pointOut.m_normalWorldOnB = normalOnB; //printf("normalOnB = %f,%f,%f\n",normalOnB.getX(),normalOnB.getY(),normalOnB.getZ()); pointOut.m_lateralFrictionDir1 = l1; pointOut.m_lateralFrictionDir2 = l2; pointOut.m_lateralFrictionInitialized = true; - - + b3Vector3 worldPosB = contact->m_worldPosB[contactIndex]; pointOut.m_positionWorldOnB = worldPosB; - pointOut.m_positionWorldOnA = worldPosB+normalOnB*pointOut.m_distance; + pointOut.m_positionWorldOnA = worldPosB + normalOnB * pointOut.m_distance; } -int getNumContacts(b3Contact4* contact) +int getNumContacts(b3Contact4* contact) { return contact->getNPoints(); } b3PgsJacobiSolver::b3PgsJacobiSolver(bool usePgs) -:m_usePgs(usePgs), -m_numSplitImpulseRecoveries(0), -m_btSeed2(0) + : m_usePgs(usePgs), + m_numSplitImpulseRecoveries(0), + m_btSeed2(0) { - } b3PgsJacobiSolver::~b3PgsJacobiSolver() { } -void b3PgsJacobiSolver::solveContacts(int numBodies, b3RigidBodyData* bodies, b3InertiaData* inertias, int numContacts, b3Contact4* contacts, int numConstraints, b3TypedConstraint** constraints) +void b3PgsJacobiSolver::solveContacts(int numBodies, b3RigidBodyData* bodies, b3InertiaData* inertias, int numContacts, b3Contact4* contacts, int numConstraints, b3TypedConstraint** constraints) { b3ContactSolverInfo infoGlobal; infoGlobal.m_splitImpulse = false; - infoGlobal.m_timeStep = 1.f/60.f; - infoGlobal.m_numIterations = 4;//4; -// infoGlobal.m_solverMode|=B3_SOLVER_USE_2_FRICTION_DIRECTIONS|B3_SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS|B3_SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION; + infoGlobal.m_timeStep = 1.f / 60.f; + infoGlobal.m_numIterations = 4; //4; + // infoGlobal.m_solverMode|=B3_SOLVER_USE_2_FRICTION_DIRECTIONS|B3_SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS|B3_SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION; //infoGlobal.m_solverMode|=B3_SOLVER_USE_2_FRICTION_DIRECTIONS|B3_SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS; - infoGlobal.m_solverMode|=B3_SOLVER_USE_2_FRICTION_DIRECTIONS; + infoGlobal.m_solverMode |= B3_SOLVER_USE_2_FRICTION_DIRECTIONS; //if (infoGlobal.m_solverMode & B3_SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS) //if ((infoGlobal.m_solverMode & B3_SOLVER_USE_2_FRICTION_DIRECTIONS) && (infoGlobal.m_solverMode & B3_SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION)) - - solveGroup(bodies,inertias,numBodies,contacts,numContacts,constraints,numConstraints,infoGlobal); + solveGroup(bodies, inertias, numBodies, contacts, numContacts, constraints, numConstraints, infoGlobal); if (!numContacts) return; } - - - /// b3PgsJacobiSolver Sequentially applies impulses b3Scalar b3PgsJacobiSolver::solveGroup(b3RigidBodyData* bodies, - b3InertiaData* inertias, - int numBodies, - b3Contact4* manifoldPtr, - int numManifolds, - b3TypedConstraint** constraints, - int numConstraints, - const b3ContactSolverInfo& infoGlobal) + b3InertiaData* inertias, + int numBodies, + b3Contact4* manifoldPtr, + int numManifolds, + b3TypedConstraint** constraints, + int numConstraints, + const b3ContactSolverInfo& infoGlobal) { - B3_PROFILE("solveGroup"); //you need to provide at least some bodies - - solveGroupCacheFriendlySetup( bodies, inertias,numBodies, manifoldPtr, numManifolds,constraints, numConstraints,infoGlobal); - solveGroupCacheFriendlyIterations(constraints, numConstraints,infoGlobal); + solveGroupCacheFriendlySetup(bodies, inertias, numBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal); + + solveGroupCacheFriendlyIterations(constraints, numConstraints, infoGlobal); + + solveGroupCacheFriendlyFinish(bodies, inertias, numBodies, infoGlobal); - solveGroupCacheFriendlyFinish(bodies, inertias,numBodies, infoGlobal); - return 0.f; } - - - - - - - - #ifdef USE_SIMD #include -#define b3VecSplat(x, e) _mm_shuffle_ps(x, x, _MM_SHUFFLE(e,e,e,e)) -static inline __m128 b3SimdDot3( __m128 vec0, __m128 vec1 ) +#define b3VecSplat(x, e) _mm_shuffle_ps(x, x, _MM_SHUFFLE(e, e, e, e)) +static inline __m128 b3SimdDot3(__m128 vec0, __m128 vec1) { - __m128 result = _mm_mul_ps( vec0, vec1); - return _mm_add_ps( b3VecSplat( result, 0 ), _mm_add_ps( b3VecSplat( result, 1 ), b3VecSplat( result, 2 ) ) ); + __m128 result = _mm_mul_ps(vec0, vec1); + return _mm_add_ps(b3VecSplat(result, 0), _mm_add_ps(b3VecSplat(result, 1), b3VecSplat(result, 2))); } -#endif//USE_SIMD +#endif //USE_SIMD // Project Gauss Seidel or the equivalent Sequential Impulse -void b3PgsJacobiSolver::resolveSingleConstraintRowGenericSIMD(b3SolverBody& body1,b3SolverBody& body2,const b3SolverConstraint& c) +void b3PgsJacobiSolver::resolveSingleConstraintRowGenericSIMD(b3SolverBody& body1, b3SolverBody& body2, const b3SolverConstraint& c) { #ifdef USE_SIMD __m128 cpAppliedImp = _mm_set1_ps(c.m_appliedImpulse); - __m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit); - __m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit); - __m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhs), _mm_mul_ps(_mm_set1_ps(c.m_appliedImpulse),_mm_set1_ps(c.m_cfm))); - __m128 deltaVel1Dotn = _mm_add_ps(b3SimdDot3(c.m_contactNormal.mVec128,body1.internalGetDeltaLinearVelocity().mVec128), b3SimdDot3(c.m_relpos1CrossNormal.mVec128,body1.internalGetDeltaAngularVelocity().mVec128)); - __m128 deltaVel2Dotn = _mm_sub_ps(b3SimdDot3(c.m_relpos2CrossNormal.mVec128,body2.internalGetDeltaAngularVelocity().mVec128),b3SimdDot3((c.m_contactNormal).mVec128,body2.internalGetDeltaLinearVelocity().mVec128)); - deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv))); - deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv))); - b3SimdScalar sum = _mm_add_ps(cpAppliedImp,deltaImpulse); - b3SimdScalar resultLowerLess,resultUpperLess; - resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1); - resultUpperLess = _mm_cmplt_ps(sum,upperLimit1); - __m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp); - deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) ); - c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) ); - __m128 upperMinApplied = _mm_sub_ps(upperLimit1,cpAppliedImp); - deltaImpulse = _mm_or_ps( _mm_and_ps(resultUpperLess, deltaImpulse), _mm_andnot_ps(resultUpperLess, upperMinApplied) ); - c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultUpperLess, c.m_appliedImpulse), _mm_andnot_ps(resultUpperLess, upperLimit1) ); - __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,body1.internalGetInvMass().mVec128); - __m128 linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,body2.internalGetInvMass().mVec128); + __m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit); + __m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit); + __m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhs), _mm_mul_ps(_mm_set1_ps(c.m_appliedImpulse), _mm_set1_ps(c.m_cfm))); + __m128 deltaVel1Dotn = _mm_add_ps(b3SimdDot3(c.m_contactNormal.mVec128, body1.internalGetDeltaLinearVelocity().mVec128), b3SimdDot3(c.m_relpos1CrossNormal.mVec128, body1.internalGetDeltaAngularVelocity().mVec128)); + __m128 deltaVel2Dotn = _mm_sub_ps(b3SimdDot3(c.m_relpos2CrossNormal.mVec128, body2.internalGetDeltaAngularVelocity().mVec128), b3SimdDot3((c.m_contactNormal).mVec128, body2.internalGetDeltaLinearVelocity().mVec128)); + deltaImpulse = _mm_sub_ps(deltaImpulse, _mm_mul_ps(deltaVel1Dotn, _mm_set1_ps(c.m_jacDiagABInv))); + deltaImpulse = _mm_sub_ps(deltaImpulse, _mm_mul_ps(deltaVel2Dotn, _mm_set1_ps(c.m_jacDiagABInv))); + b3SimdScalar sum = _mm_add_ps(cpAppliedImp, deltaImpulse); + b3SimdScalar resultLowerLess, resultUpperLess; + resultLowerLess = _mm_cmplt_ps(sum, lowerLimit1); + resultUpperLess = _mm_cmplt_ps(sum, upperLimit1); + __m128 lowMinApplied = _mm_sub_ps(lowerLimit1, cpAppliedImp); + deltaImpulse = _mm_or_ps(_mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse)); + c.m_appliedImpulse = _mm_or_ps(_mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum)); + __m128 upperMinApplied = _mm_sub_ps(upperLimit1, cpAppliedImp); + deltaImpulse = _mm_or_ps(_mm_and_ps(resultUpperLess, deltaImpulse), _mm_andnot_ps(resultUpperLess, upperMinApplied)); + c.m_appliedImpulse = _mm_or_ps(_mm_and_ps(resultUpperLess, c.m_appliedImpulse), _mm_andnot_ps(resultUpperLess, upperLimit1)); + __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128, body1.internalGetInvMass().mVec128); + __m128 linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128, body2.internalGetInvMass().mVec128); __m128 impulseMagnitude = deltaImpulse; - body1.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude)); - body1.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude)); - body2.internalGetDeltaLinearVelocity().mVec128 = _mm_sub_ps(body2.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude)); - body2.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body2.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude)); + body1.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaLinearVelocity().mVec128, _mm_mul_ps(linearComponentA, impulseMagnitude)); + body1.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaAngularVelocity().mVec128, _mm_mul_ps(c.m_angularComponentA.mVec128, impulseMagnitude)); + body2.internalGetDeltaLinearVelocity().mVec128 = _mm_sub_ps(body2.internalGetDeltaLinearVelocity().mVec128, _mm_mul_ps(linearComponentB, impulseMagnitude)); + body2.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body2.internalGetDeltaAngularVelocity().mVec128, _mm_mul_ps(c.m_angularComponentB.mVec128, impulseMagnitude)); #else - resolveSingleConstraintRowGeneric(body1,body2,c); + resolveSingleConstraintRowGeneric(body1, body2, c); #endif } // Project Gauss Seidel or the equivalent Sequential Impulse - void b3PgsJacobiSolver::resolveSingleConstraintRowGeneric(b3SolverBody& body1,b3SolverBody& body2,const b3SolverConstraint& c) +void b3PgsJacobiSolver::resolveSingleConstraintRowGeneric(b3SolverBody& body1, b3SolverBody& body2, const b3SolverConstraint& c) { - b3Scalar deltaImpulse = c.m_rhs-b3Scalar(c.m_appliedImpulse)*c.m_cfm; - const b3Scalar deltaVel1Dotn = c.m_contactNormal.dot(body1.internalGetDeltaLinearVelocity()) + c.m_relpos1CrossNormal.dot(body1.internalGetDeltaAngularVelocity()); - const b3Scalar deltaVel2Dotn = -c.m_contactNormal.dot(body2.internalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetDeltaAngularVelocity()); + b3Scalar deltaImpulse = c.m_rhs - b3Scalar(c.m_appliedImpulse) * c.m_cfm; + const b3Scalar deltaVel1Dotn = c.m_contactNormal.dot(body1.internalGetDeltaLinearVelocity()) + c.m_relpos1CrossNormal.dot(body1.internalGetDeltaAngularVelocity()); + const b3Scalar deltaVel2Dotn = -c.m_contactNormal.dot(body2.internalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetDeltaAngularVelocity()); -// const b3Scalar delta_rel_vel = deltaVel1Dotn-deltaVel2Dotn; - deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv; - deltaImpulse -= deltaVel2Dotn*c.m_jacDiagABInv; + // const b3Scalar delta_rel_vel = deltaVel1Dotn-deltaVel2Dotn; + deltaImpulse -= deltaVel1Dotn * c.m_jacDiagABInv; + deltaImpulse -= deltaVel2Dotn * c.m_jacDiagABInv; const b3Scalar sum = b3Scalar(c.m_appliedImpulse) + deltaImpulse; if (sum < c.m_lowerLimit) { - deltaImpulse = c.m_lowerLimit-c.m_appliedImpulse; + deltaImpulse = c.m_lowerLimit - c.m_appliedImpulse; c.m_appliedImpulse = c.m_lowerLimit; } - else if (sum > c.m_upperLimit) + else if (sum > c.m_upperLimit) { - deltaImpulse = c.m_upperLimit-c.m_appliedImpulse; + deltaImpulse = c.m_upperLimit - c.m_appliedImpulse; c.m_appliedImpulse = c.m_upperLimit; } else @@ -278,94 +259,93 @@ void b3PgsJacobiSolver::resolveSingleConstraintRowGenericSIMD(b3SolverBody& body c.m_appliedImpulse = sum; } - body1.internalApplyImpulse(c.m_contactNormal*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse); - body2.internalApplyImpulse(-c.m_contactNormal*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse); + body1.internalApplyImpulse(c.m_contactNormal * body1.internalGetInvMass(), c.m_angularComponentA, deltaImpulse); + body2.internalApplyImpulse(-c.m_contactNormal * body2.internalGetInvMass(), c.m_angularComponentB, deltaImpulse); } - void b3PgsJacobiSolver::resolveSingleConstraintRowLowerLimitSIMD(b3SolverBody& body1,b3SolverBody& body2,const b3SolverConstraint& c) +void b3PgsJacobiSolver::resolveSingleConstraintRowLowerLimitSIMD(b3SolverBody& body1, b3SolverBody& body2, const b3SolverConstraint& c) { #ifdef USE_SIMD __m128 cpAppliedImp = _mm_set1_ps(c.m_appliedImpulse); - __m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit); - __m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit); - __m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhs), _mm_mul_ps(_mm_set1_ps(c.m_appliedImpulse),_mm_set1_ps(c.m_cfm))); - __m128 deltaVel1Dotn = _mm_add_ps(b3SimdDot3(c.m_contactNormal.mVec128,body1.internalGetDeltaLinearVelocity().mVec128), b3SimdDot3(c.m_relpos1CrossNormal.mVec128,body1.internalGetDeltaAngularVelocity().mVec128)); - __m128 deltaVel2Dotn = _mm_sub_ps(b3SimdDot3(c.m_relpos2CrossNormal.mVec128,body2.internalGetDeltaAngularVelocity().mVec128),b3SimdDot3((c.m_contactNormal).mVec128,body2.internalGetDeltaLinearVelocity().mVec128)); - deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv))); - deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv))); - b3SimdScalar sum = _mm_add_ps(cpAppliedImp,deltaImpulse); - b3SimdScalar resultLowerLess,resultUpperLess; - resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1); - resultUpperLess = _mm_cmplt_ps(sum,upperLimit1); - __m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp); - deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) ); - c.m_appliedImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) ); - __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,body1.internalGetInvMass().mVec128); - __m128 linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,body2.internalGetInvMass().mVec128); + __m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit); + __m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit); + __m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhs), _mm_mul_ps(_mm_set1_ps(c.m_appliedImpulse), _mm_set1_ps(c.m_cfm))); + __m128 deltaVel1Dotn = _mm_add_ps(b3SimdDot3(c.m_contactNormal.mVec128, body1.internalGetDeltaLinearVelocity().mVec128), b3SimdDot3(c.m_relpos1CrossNormal.mVec128, body1.internalGetDeltaAngularVelocity().mVec128)); + __m128 deltaVel2Dotn = _mm_sub_ps(b3SimdDot3(c.m_relpos2CrossNormal.mVec128, body2.internalGetDeltaAngularVelocity().mVec128), b3SimdDot3((c.m_contactNormal).mVec128, body2.internalGetDeltaLinearVelocity().mVec128)); + deltaImpulse = _mm_sub_ps(deltaImpulse, _mm_mul_ps(deltaVel1Dotn, _mm_set1_ps(c.m_jacDiagABInv))); + deltaImpulse = _mm_sub_ps(deltaImpulse, _mm_mul_ps(deltaVel2Dotn, _mm_set1_ps(c.m_jacDiagABInv))); + b3SimdScalar sum = _mm_add_ps(cpAppliedImp, deltaImpulse); + b3SimdScalar resultLowerLess, resultUpperLess; + resultLowerLess = _mm_cmplt_ps(sum, lowerLimit1); + resultUpperLess = _mm_cmplt_ps(sum, upperLimit1); + __m128 lowMinApplied = _mm_sub_ps(lowerLimit1, cpAppliedImp); + deltaImpulse = _mm_or_ps(_mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse)); + c.m_appliedImpulse = _mm_or_ps(_mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum)); + __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128, body1.internalGetInvMass().mVec128); + __m128 linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128, body2.internalGetInvMass().mVec128); __m128 impulseMagnitude = deltaImpulse; - body1.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude)); - body1.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude)); - body2.internalGetDeltaLinearVelocity().mVec128 = _mm_sub_ps(body2.internalGetDeltaLinearVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude)); - body2.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body2.internalGetDeltaAngularVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude)); + body1.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaLinearVelocity().mVec128, _mm_mul_ps(linearComponentA, impulseMagnitude)); + body1.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body1.internalGetDeltaAngularVelocity().mVec128, _mm_mul_ps(c.m_angularComponentA.mVec128, impulseMagnitude)); + body2.internalGetDeltaLinearVelocity().mVec128 = _mm_sub_ps(body2.internalGetDeltaLinearVelocity().mVec128, _mm_mul_ps(linearComponentB, impulseMagnitude)); + body2.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(body2.internalGetDeltaAngularVelocity().mVec128, _mm_mul_ps(c.m_angularComponentB.mVec128, impulseMagnitude)); #else - resolveSingleConstraintRowLowerLimit(body1,body2,c); + resolveSingleConstraintRowLowerLimit(body1, body2, c); #endif } // Project Gauss Seidel or the equivalent Sequential Impulse - void b3PgsJacobiSolver::resolveSingleConstraintRowLowerLimit(b3SolverBody& body1,b3SolverBody& body2,const b3SolverConstraint& c) +void b3PgsJacobiSolver::resolveSingleConstraintRowLowerLimit(b3SolverBody& body1, b3SolverBody& body2, const b3SolverConstraint& c) { - b3Scalar deltaImpulse = c.m_rhs-b3Scalar(c.m_appliedImpulse)*c.m_cfm; - const b3Scalar deltaVel1Dotn = c.m_contactNormal.dot(body1.internalGetDeltaLinearVelocity()) + c.m_relpos1CrossNormal.dot(body1.internalGetDeltaAngularVelocity()); - const b3Scalar deltaVel2Dotn = -c.m_contactNormal.dot(body2.internalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetDeltaAngularVelocity()); + b3Scalar deltaImpulse = c.m_rhs - b3Scalar(c.m_appliedImpulse) * c.m_cfm; + const b3Scalar deltaVel1Dotn = c.m_contactNormal.dot(body1.internalGetDeltaLinearVelocity()) + c.m_relpos1CrossNormal.dot(body1.internalGetDeltaAngularVelocity()); + const b3Scalar deltaVel2Dotn = -c.m_contactNormal.dot(body2.internalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetDeltaAngularVelocity()); - deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv; - deltaImpulse -= deltaVel2Dotn*c.m_jacDiagABInv; + deltaImpulse -= deltaVel1Dotn * c.m_jacDiagABInv; + deltaImpulse -= deltaVel2Dotn * c.m_jacDiagABInv; const b3Scalar sum = b3Scalar(c.m_appliedImpulse) + deltaImpulse; if (sum < c.m_lowerLimit) { - deltaImpulse = c.m_lowerLimit-c.m_appliedImpulse; + deltaImpulse = c.m_lowerLimit - c.m_appliedImpulse; c.m_appliedImpulse = c.m_lowerLimit; } else { c.m_appliedImpulse = sum; } - body1.internalApplyImpulse(c.m_contactNormal*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse); - body2.internalApplyImpulse(-c.m_contactNormal*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse); + body1.internalApplyImpulse(c.m_contactNormal * body1.internalGetInvMass(), c.m_angularComponentA, deltaImpulse); + body2.internalApplyImpulse(-c.m_contactNormal * body2.internalGetInvMass(), c.m_angularComponentB, deltaImpulse); } - -void b3PgsJacobiSolver::resolveSplitPenetrationImpulseCacheFriendly( - b3SolverBody& body1, - b3SolverBody& body2, - const b3SolverConstraint& c) +void b3PgsJacobiSolver::resolveSplitPenetrationImpulseCacheFriendly( + b3SolverBody& body1, + b3SolverBody& body2, + const b3SolverConstraint& c) { - if (c.m_rhsPenetration) - { - m_numSplitImpulseRecoveries++; - b3Scalar deltaImpulse = c.m_rhsPenetration-b3Scalar(c.m_appliedPushImpulse)*c.m_cfm; - const b3Scalar deltaVel1Dotn = c.m_contactNormal.dot(body1.internalGetPushVelocity()) + c.m_relpos1CrossNormal.dot(body1.internalGetTurnVelocity()); - const b3Scalar deltaVel2Dotn = -c.m_contactNormal.dot(body2.internalGetPushVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetTurnVelocity()); + if (c.m_rhsPenetration) + { + m_numSplitImpulseRecoveries++; + b3Scalar deltaImpulse = c.m_rhsPenetration - b3Scalar(c.m_appliedPushImpulse) * c.m_cfm; + const b3Scalar deltaVel1Dotn = c.m_contactNormal.dot(body1.internalGetPushVelocity()) + c.m_relpos1CrossNormal.dot(body1.internalGetTurnVelocity()); + const b3Scalar deltaVel2Dotn = -c.m_contactNormal.dot(body2.internalGetPushVelocity()) + c.m_relpos2CrossNormal.dot(body2.internalGetTurnVelocity()); - deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv; - deltaImpulse -= deltaVel2Dotn*c.m_jacDiagABInv; - const b3Scalar sum = b3Scalar(c.m_appliedPushImpulse) + deltaImpulse; - if (sum < c.m_lowerLimit) - { - deltaImpulse = c.m_lowerLimit-c.m_appliedPushImpulse; - c.m_appliedPushImpulse = c.m_lowerLimit; - } - else - { - c.m_appliedPushImpulse = sum; - } - body1.internalApplyPushImpulse(c.m_contactNormal*body1.internalGetInvMass(),c.m_angularComponentA,deltaImpulse); - body2.internalApplyPushImpulse(-c.m_contactNormal*body2.internalGetInvMass(),c.m_angularComponentB,deltaImpulse); - } + deltaImpulse -= deltaVel1Dotn * c.m_jacDiagABInv; + deltaImpulse -= deltaVel2Dotn * c.m_jacDiagABInv; + const b3Scalar sum = b3Scalar(c.m_appliedPushImpulse) + deltaImpulse; + if (sum < c.m_lowerLimit) + { + deltaImpulse = c.m_lowerLimit - c.m_appliedPushImpulse; + c.m_appliedPushImpulse = c.m_lowerLimit; + } + else + { + c.m_appliedPushImpulse = sum; + } + body1.internalApplyPushImpulse(c.m_contactNormal * body1.internalGetInvMass(), c.m_angularComponentA, deltaImpulse); + body2.internalApplyPushImpulse(-c.m_contactNormal * body2.internalGetInvMass(), c.m_angularComponentB, deltaImpulse); + } } - void b3PgsJacobiSolver::resolveSplitPenetrationSIMD(b3SolverBody& body1,b3SolverBody& body2,const b3SolverConstraint& c) +void b3PgsJacobiSolver::resolveSplitPenetrationSIMD(b3SolverBody& body1, b3SolverBody& body2, const b3SolverConstraint& c) { #ifdef USE_SIMD if (!c.m_rhsPenetration) @@ -374,44 +354,40 @@ void b3PgsJacobiSolver::resolveSplitPenetrationImpulseCacheFriendly( m_numSplitImpulseRecoveries++; __m128 cpAppliedImp = _mm_set1_ps(c.m_appliedPushImpulse); - __m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit); - __m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit); - __m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhsPenetration), _mm_mul_ps(_mm_set1_ps(c.m_appliedPushImpulse),_mm_set1_ps(c.m_cfm))); - __m128 deltaVel1Dotn = _mm_add_ps(b3SimdDot3(c.m_contactNormal.mVec128,body1.internalGetPushVelocity().mVec128), b3SimdDot3(c.m_relpos1CrossNormal.mVec128,body1.internalGetTurnVelocity().mVec128)); - __m128 deltaVel2Dotn = _mm_sub_ps(b3SimdDot3(c.m_relpos2CrossNormal.mVec128,body2.internalGetTurnVelocity().mVec128),b3SimdDot3((c.m_contactNormal).mVec128,body2.internalGetPushVelocity().mVec128)); - deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv))); - deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv))); - b3SimdScalar sum = _mm_add_ps(cpAppliedImp,deltaImpulse); - b3SimdScalar resultLowerLess,resultUpperLess; - resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1); - resultUpperLess = _mm_cmplt_ps(sum,upperLimit1); - __m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp); - deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) ); - c.m_appliedPushImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) ); - __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128,body1.internalGetInvMass().mVec128); - __m128 linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128,body2.internalGetInvMass().mVec128); + __m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit); + __m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit); + __m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhsPenetration), _mm_mul_ps(_mm_set1_ps(c.m_appliedPushImpulse), _mm_set1_ps(c.m_cfm))); + __m128 deltaVel1Dotn = _mm_add_ps(b3SimdDot3(c.m_contactNormal.mVec128, body1.internalGetPushVelocity().mVec128), b3SimdDot3(c.m_relpos1CrossNormal.mVec128, body1.internalGetTurnVelocity().mVec128)); + __m128 deltaVel2Dotn = _mm_sub_ps(b3SimdDot3(c.m_relpos2CrossNormal.mVec128, body2.internalGetTurnVelocity().mVec128), b3SimdDot3((c.m_contactNormal).mVec128, body2.internalGetPushVelocity().mVec128)); + deltaImpulse = _mm_sub_ps(deltaImpulse, _mm_mul_ps(deltaVel1Dotn, _mm_set1_ps(c.m_jacDiagABInv))); + deltaImpulse = _mm_sub_ps(deltaImpulse, _mm_mul_ps(deltaVel2Dotn, _mm_set1_ps(c.m_jacDiagABInv))); + b3SimdScalar sum = _mm_add_ps(cpAppliedImp, deltaImpulse); + b3SimdScalar resultLowerLess, resultUpperLess; + resultLowerLess = _mm_cmplt_ps(sum, lowerLimit1); + resultUpperLess = _mm_cmplt_ps(sum, upperLimit1); + __m128 lowMinApplied = _mm_sub_ps(lowerLimit1, cpAppliedImp); + deltaImpulse = _mm_or_ps(_mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse)); + c.m_appliedPushImpulse = _mm_or_ps(_mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum)); + __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal.mVec128, body1.internalGetInvMass().mVec128); + __m128 linearComponentB = _mm_mul_ps((c.m_contactNormal).mVec128, body2.internalGetInvMass().mVec128); __m128 impulseMagnitude = deltaImpulse; - body1.internalGetPushVelocity().mVec128 = _mm_add_ps(body1.internalGetPushVelocity().mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude)); - body1.internalGetTurnVelocity().mVec128 = _mm_add_ps(body1.internalGetTurnVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude)); - body2.internalGetPushVelocity().mVec128 = _mm_sub_ps(body2.internalGetPushVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude)); - body2.internalGetTurnVelocity().mVec128 = _mm_add_ps(body2.internalGetTurnVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude)); + body1.internalGetPushVelocity().mVec128 = _mm_add_ps(body1.internalGetPushVelocity().mVec128, _mm_mul_ps(linearComponentA, impulseMagnitude)); + body1.internalGetTurnVelocity().mVec128 = _mm_add_ps(body1.internalGetTurnVelocity().mVec128, _mm_mul_ps(c.m_angularComponentA.mVec128, impulseMagnitude)); + body2.internalGetPushVelocity().mVec128 = _mm_sub_ps(body2.internalGetPushVelocity().mVec128, _mm_mul_ps(linearComponentB, impulseMagnitude)); + body2.internalGetTurnVelocity().mVec128 = _mm_add_ps(body2.internalGetTurnVelocity().mVec128, _mm_mul_ps(c.m_angularComponentB.mVec128, impulseMagnitude)); #else - resolveSplitPenetrationImpulseCacheFriendly(body1,body2,c); + resolveSplitPenetrationImpulseCacheFriendly(body1, body2, c); #endif } - - unsigned long b3PgsJacobiSolver::b3Rand2() { - m_btSeed2 = (1664525L*m_btSeed2 + 1013904223L) & 0xffffffff; + m_btSeed2 = (1664525L * m_btSeed2 + 1013904223L) & 0xffffffff; return m_btSeed2; } - - //See ODE: adam's all-int straightforward(?) dRandInt (0..n-1) -int b3PgsJacobiSolver::b3RandInt2 (int n) +int b3PgsJacobiSolver::b3RandInt2(int n) { // seems good; xor-fold and modulus const unsigned long un = static_cast(n); @@ -419,15 +395,20 @@ int b3PgsJacobiSolver::b3RandInt2 (int n) // note: probably more aggressive than it needs to be -- might be // able to get away without one or two of the innermost branches. - if (un <= 0x00010000UL) { + if (un <= 0x00010000UL) + { r ^= (r >> 16); - if (un <= 0x00000100UL) { + if (un <= 0x00000100UL) + { r ^= (r >> 8); - if (un <= 0x00000010UL) { + if (un <= 0x00000010UL) + { r ^= (r >> 4); - if (un <= 0x00000004UL) { + if (un <= 0x00000004UL) + { r ^= (r >> 2); - if (un <= 0x00000002UL) { + if (un <= 0x00000002UL) + { r ^= (r >> 1); } } @@ -435,62 +416,46 @@ int b3PgsJacobiSolver::b3RandInt2 (int n) } } - return (int) (r % un); + return (int)(r % un); } - - -void b3PgsJacobiSolver::initSolverBody(int bodyIndex, b3SolverBody* solverBody, b3RigidBodyData* rb) +void b3PgsJacobiSolver::initSolverBody(int bodyIndex, b3SolverBody* solverBody, b3RigidBodyData* rb) { - - solverBody->m_deltaLinearVelocity.setValue(0.f,0.f,0.f); - solverBody->m_deltaAngularVelocity.setValue(0.f,0.f,0.f); - solverBody->internalGetPushVelocity().setValue(0.f,0.f,0.f); - solverBody->internalGetTurnVelocity().setValue(0.f,0.f,0.f); + solverBody->m_deltaLinearVelocity.setValue(0.f, 0.f, 0.f); + solverBody->m_deltaAngularVelocity.setValue(0.f, 0.f, 0.f); + solverBody->internalGetPushVelocity().setValue(0.f, 0.f, 0.f); + solverBody->internalGetTurnVelocity().setValue(0.f, 0.f, 0.f); if (rb) { solverBody->m_worldTransform = getWorldTransform(rb); - solverBody->internalSetInvMass(b3MakeVector3(rb->m_invMass,rb->m_invMass,rb->m_invMass)); + solverBody->internalSetInvMass(b3MakeVector3(rb->m_invMass, rb->m_invMass, rb->m_invMass)); solverBody->m_originalBodyIndex = bodyIndex; - solverBody->m_angularFactor = b3MakeVector3(1,1,1); - solverBody->m_linearFactor = b3MakeVector3(1,1,1); + solverBody->m_angularFactor = b3MakeVector3(1, 1, 1); + solverBody->m_linearFactor = b3MakeVector3(1, 1, 1); solverBody->m_linearVelocity = getLinearVelocity(rb); solverBody->m_angularVelocity = getAngularVelocity(rb); - } else + } + else { solverBody->m_worldTransform.setIdentity(); - solverBody->internalSetInvMass(b3MakeVector3(0,0,0)); + solverBody->internalSetInvMass(b3MakeVector3(0, 0, 0)); solverBody->m_originalBodyIndex = bodyIndex; - solverBody->m_angularFactor.setValue(1,1,1); - solverBody->m_linearFactor.setValue(1,1,1); - solverBody->m_linearVelocity.setValue(0,0,0); - solverBody->m_angularVelocity.setValue(0,0,0); + solverBody->m_angularFactor.setValue(1, 1, 1); + solverBody->m_linearFactor.setValue(1, 1, 1); + solverBody->m_linearVelocity.setValue(0, 0, 0); + solverBody->m_angularVelocity.setValue(0, 0, 0); } - - } - - - - - b3Scalar b3PgsJacobiSolver::restitutionCurve(b3Scalar rel_vel, b3Scalar restitution) { b3Scalar rest = restitution * -rel_vel; return rest; } - - - - - -void b3PgsJacobiSolver::setupFrictionConstraint(b3RigidBodyData* bodies,b3InertiaData* inertias, b3SolverConstraint& solverConstraint, const b3Vector3& normalAxis,int solverBodyIdA,int solverBodyIdB,b3ContactPoint& cp,const b3Vector3& rel_pos1,const b3Vector3& rel_pos2,b3RigidBodyData* colObj0,b3RigidBodyData* colObj1, b3Scalar relaxation, b3Scalar desiredVelocity, b3Scalar cfmSlip) +void b3PgsJacobiSolver::setupFrictionConstraint(b3RigidBodyData* bodies, b3InertiaData* inertias, b3SolverConstraint& solverConstraint, const b3Vector3& normalAxis, int solverBodyIdA, int solverBodyIdB, b3ContactPoint& cp, const b3Vector3& rel_pos1, const b3Vector3& rel_pos2, b3RigidBodyData* colObj0, b3RigidBodyData* colObj1, b3Scalar relaxation, b3Scalar desiredVelocity, b3Scalar cfmSlip) { - - solverConstraint.m_contactNormal = normalAxis; b3SolverBody& solverBodyA = m_tmpSolverBodyPool[solverBodyIdA]; b3SolverBody& solverBodyB = m_tmpSolverBodyPool[solverBodyIdB]; @@ -498,7 +463,6 @@ void b3PgsJacobiSolver::setupFrictionConstraint(b3RigidBodyData* bodies,b3Inerti b3RigidBodyData* body0 = &bodies[solverBodyA.m_originalBodyIndex]; b3RigidBodyData* body1 = &bodies[solverBodyB.m_originalBodyIndex]; - solverConstraint.m_solverBodyIdA = solverBodyIdA; solverConstraint.m_solverBodyIdB = solverBodyIdB; @@ -511,12 +475,12 @@ void b3PgsJacobiSolver::setupFrictionConstraint(b3RigidBodyData* bodies,b3Inerti { b3Vector3 ftorqueAxis1 = rel_pos1.cross(solverConstraint.m_contactNormal); solverConstraint.m_relpos1CrossNormal = ftorqueAxis1; - solverConstraint.m_angularComponentA = body0 ? getInvInertiaTensorWorld(&inertias[solverBodyA.m_originalBodyIndex])*ftorqueAxis1 : b3MakeVector3(0,0,0); + solverConstraint.m_angularComponentA = body0 ? getInvInertiaTensorWorld(&inertias[solverBodyA.m_originalBodyIndex]) * ftorqueAxis1 : b3MakeVector3(0, 0, 0); } { b3Vector3 ftorqueAxis1 = rel_pos2.cross(-solverConstraint.m_contactNormal); solverConstraint.m_relpos2CrossNormal = ftorqueAxis1; - solverConstraint.m_angularComponentB = body1 ? getInvInertiaTensorWorld(&inertias[solverBodyB.m_originalBodyIndex])*ftorqueAxis1 : b3MakeVector3(0,0,0); + solverConstraint.m_angularComponentB = body1 ? getInvInertiaTensorWorld(&inertias[solverBodyB.m_originalBodyIndex]) * ftorqueAxis1 : b3MakeVector3(0, 0, 0); } b3Scalar scaledDenom; @@ -527,72 +491,66 @@ void b3PgsJacobiSolver::setupFrictionConstraint(b3RigidBodyData* bodies,b3Inerti b3Scalar denom1 = 0.f; if (body0) { - vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1); + vec = (solverConstraint.m_angularComponentA).cross(rel_pos1); denom0 = body0->m_invMass + normalAxis.dot(vec); } if (body1) { - vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2); + vec = (-solverConstraint.m_angularComponentB).cross(rel_pos2); denom1 = body1->m_invMass + normalAxis.dot(vec); } b3Scalar denom; if (m_usePgs) { - scaledDenom = denom = relaxation/(denom0+denom1); - } else + scaledDenom = denom = relaxation / (denom0 + denom1); + } + else { - denom = relaxation/(denom0+denom1); - b3Scalar countA = body0->m_invMass ? b3Scalar(m_bodyCount[solverBodyA.m_originalBodyIndex]): 1.f; - b3Scalar countB = body1->m_invMass ? b3Scalar(m_bodyCount[solverBodyB.m_originalBodyIndex]): 1.f; + denom = relaxation / (denom0 + denom1); + b3Scalar countA = body0->m_invMass ? b3Scalar(m_bodyCount[solverBodyA.m_originalBodyIndex]) : 1.f; + b3Scalar countB = body1->m_invMass ? b3Scalar(m_bodyCount[solverBodyB.m_originalBodyIndex]) : 1.f; - scaledDenom = relaxation/(denom0*countA+denom1*countB); + scaledDenom = relaxation / (denom0 * countA + denom1 * countB); } solverConstraint.m_jacDiagABInv = denom; } { - - b3Scalar rel_vel; - b3Scalar vel1Dotn = solverConstraint.m_contactNormal.dot(body0?solverBodyA.m_linearVelocity:b3MakeVector3(0,0,0)) - + solverConstraint.m_relpos1CrossNormal.dot(body0?solverBodyA.m_angularVelocity:b3MakeVector3(0,0,0)); - b3Scalar vel2Dotn = -solverConstraint.m_contactNormal.dot(body1?solverBodyB.m_linearVelocity:b3MakeVector3(0,0,0)) - + solverConstraint.m_relpos2CrossNormal.dot(body1?solverBodyB.m_angularVelocity:b3MakeVector3(0,0,0)); + b3Scalar vel1Dotn = solverConstraint.m_contactNormal.dot(body0 ? solverBodyA.m_linearVelocity : b3MakeVector3(0, 0, 0)) + solverConstraint.m_relpos1CrossNormal.dot(body0 ? solverBodyA.m_angularVelocity : b3MakeVector3(0, 0, 0)); + b3Scalar vel2Dotn = -solverConstraint.m_contactNormal.dot(body1 ? solverBodyB.m_linearVelocity : b3MakeVector3(0, 0, 0)) + solverConstraint.m_relpos2CrossNormal.dot(body1 ? solverBodyB.m_angularVelocity : b3MakeVector3(0, 0, 0)); - rel_vel = vel1Dotn+vel2Dotn; + rel_vel = vel1Dotn + vel2Dotn; -// b3Scalar positionalError = 0.f; + // b3Scalar positionalError = 0.f; - b3SimdScalar velocityError = desiredVelocity - rel_vel; - b3SimdScalar velocityImpulse = velocityError * b3SimdScalar(scaledDenom);//solverConstraint.m_jacDiagABInv); + b3SimdScalar velocityError = desiredVelocity - rel_vel; + b3SimdScalar velocityImpulse = velocityError * b3SimdScalar(scaledDenom); //solverConstraint.m_jacDiagABInv); solverConstraint.m_rhs = velocityImpulse; solverConstraint.m_cfm = cfmSlip; solverConstraint.m_lowerLimit = 0; solverConstraint.m_upperLimit = 1e10f; - } } -b3SolverConstraint& b3PgsJacobiSolver::addFrictionConstraint(b3RigidBodyData* bodies,b3InertiaData* inertias, const b3Vector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,b3ContactPoint& cp,const b3Vector3& rel_pos1,const b3Vector3& rel_pos2,b3RigidBodyData* colObj0,b3RigidBodyData* colObj1, b3Scalar relaxation, b3Scalar desiredVelocity, b3Scalar cfmSlip) +b3SolverConstraint& b3PgsJacobiSolver::addFrictionConstraint(b3RigidBodyData* bodies, b3InertiaData* inertias, const b3Vector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, b3ContactPoint& cp, const b3Vector3& rel_pos1, const b3Vector3& rel_pos2, b3RigidBodyData* colObj0, b3RigidBodyData* colObj1, b3Scalar relaxation, b3Scalar desiredVelocity, b3Scalar cfmSlip) { b3SolverConstraint& solverConstraint = m_tmpSolverContactFrictionConstraintPool.expandNonInitializing(); solverConstraint.m_frictionIndex = frictionIndex; - setupFrictionConstraint(bodies,inertias,solverConstraint, normalAxis, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, + setupFrictionConstraint(bodies, inertias, solverConstraint, normalAxis, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, desiredVelocity, cfmSlip); return solverConstraint; } - -void b3PgsJacobiSolver::setupRollingFrictionConstraint(b3RigidBodyData* bodies,b3InertiaData* inertias, b3SolverConstraint& solverConstraint, const b3Vector3& normalAxis1,int solverBodyIdA,int solverBodyIdB, - b3ContactPoint& cp,const b3Vector3& rel_pos1,const b3Vector3& rel_pos2, - b3RigidBodyData* colObj0,b3RigidBodyData* colObj1, b3Scalar relaxation, - b3Scalar desiredVelocity, b3Scalar cfmSlip) +void b3PgsJacobiSolver::setupRollingFrictionConstraint(b3RigidBodyData* bodies, b3InertiaData* inertias, b3SolverConstraint& solverConstraint, const b3Vector3& normalAxis1, int solverBodyIdA, int solverBodyIdB, + b3ContactPoint& cp, const b3Vector3& rel_pos1, const b3Vector3& rel_pos2, + b3RigidBodyData* colObj0, b3RigidBodyData* colObj1, b3Scalar relaxation, + b3Scalar desiredVelocity, b3Scalar cfmSlip) { - b3Vector3 normalAxis=b3MakeVector3(0,0,0); - + b3Vector3 normalAxis = b3MakeVector3(0, 0, 0); solverConstraint.m_contactNormal = normalAxis; b3SolverBody& solverBodyA = m_tmpSolverBodyPool[solverBodyIdA]; @@ -613,272 +571,244 @@ void b3PgsJacobiSolver::setupRollingFrictionConstraint(b3RigidBodyData* bodies,b { b3Vector3 ftorqueAxis1 = -normalAxis1; solverConstraint.m_relpos1CrossNormal = ftorqueAxis1; - solverConstraint.m_angularComponentA = body0 ? getInvInertiaTensorWorld(&inertias[solverBodyA.m_originalBodyIndex])*ftorqueAxis1 : b3MakeVector3(0,0,0); + solverConstraint.m_angularComponentA = body0 ? getInvInertiaTensorWorld(&inertias[solverBodyA.m_originalBodyIndex]) * ftorqueAxis1 : b3MakeVector3(0, 0, 0); } { b3Vector3 ftorqueAxis1 = normalAxis1; solverConstraint.m_relpos2CrossNormal = ftorqueAxis1; - solverConstraint.m_angularComponentB = body1 ? getInvInertiaTensorWorld(&inertias[solverBodyB.m_originalBodyIndex])*ftorqueAxis1 : b3MakeVector3(0,0,0); + solverConstraint.m_angularComponentB = body1 ? getInvInertiaTensorWorld(&inertias[solverBodyB.m_originalBodyIndex]) * ftorqueAxis1 : b3MakeVector3(0, 0, 0); } - { - b3Vector3 iMJaA = body0?getInvInertiaTensorWorld(&inertias[solverBodyA.m_originalBodyIndex])*solverConstraint.m_relpos1CrossNormal:b3MakeVector3(0,0,0); - b3Vector3 iMJaB = body1?getInvInertiaTensorWorld(&inertias[solverBodyB.m_originalBodyIndex])*solverConstraint.m_relpos2CrossNormal:b3MakeVector3(0,0,0); + b3Vector3 iMJaA = body0 ? getInvInertiaTensorWorld(&inertias[solverBodyA.m_originalBodyIndex]) * solverConstraint.m_relpos1CrossNormal : b3MakeVector3(0, 0, 0); + b3Vector3 iMJaB = body1 ? getInvInertiaTensorWorld(&inertias[solverBodyB.m_originalBodyIndex]) * solverConstraint.m_relpos2CrossNormal : b3MakeVector3(0, 0, 0); b3Scalar sum = 0; sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal); sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal); - solverConstraint.m_jacDiagABInv = b3Scalar(1.)/sum; + solverConstraint.m_jacDiagABInv = b3Scalar(1.) / sum; } { - - b3Scalar rel_vel; - b3Scalar vel1Dotn = solverConstraint.m_contactNormal.dot(body0?solverBodyA.m_linearVelocity:b3MakeVector3(0,0,0)) - + solverConstraint.m_relpos1CrossNormal.dot(body0?solverBodyA.m_angularVelocity:b3MakeVector3(0,0,0)); - b3Scalar vel2Dotn = -solverConstraint.m_contactNormal.dot(body1?solverBodyB.m_linearVelocity:b3MakeVector3(0,0,0)) - + solverConstraint.m_relpos2CrossNormal.dot(body1?solverBodyB.m_angularVelocity:b3MakeVector3(0,0,0)); + b3Scalar vel1Dotn = solverConstraint.m_contactNormal.dot(body0 ? solverBodyA.m_linearVelocity : b3MakeVector3(0, 0, 0)) + solverConstraint.m_relpos1CrossNormal.dot(body0 ? solverBodyA.m_angularVelocity : b3MakeVector3(0, 0, 0)); + b3Scalar vel2Dotn = -solverConstraint.m_contactNormal.dot(body1 ? solverBodyB.m_linearVelocity : b3MakeVector3(0, 0, 0)) + solverConstraint.m_relpos2CrossNormal.dot(body1 ? solverBodyB.m_angularVelocity : b3MakeVector3(0, 0, 0)); - rel_vel = vel1Dotn+vel2Dotn; + rel_vel = vel1Dotn + vel2Dotn; -// b3Scalar positionalError = 0.f; + // b3Scalar positionalError = 0.f; - b3SimdScalar velocityError = desiredVelocity - rel_vel; - b3SimdScalar velocityImpulse = velocityError * b3SimdScalar(solverConstraint.m_jacDiagABInv); + b3SimdScalar velocityError = desiredVelocity - rel_vel; + b3SimdScalar velocityImpulse = velocityError * b3SimdScalar(solverConstraint.m_jacDiagABInv); solverConstraint.m_rhs = velocityImpulse; solverConstraint.m_cfm = cfmSlip; solverConstraint.m_lowerLimit = 0; solverConstraint.m_upperLimit = 1e10f; - } } - - - - - - - -b3SolverConstraint& b3PgsJacobiSolver::addRollingFrictionConstraint(b3RigidBodyData* bodies,b3InertiaData* inertias,const b3Vector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,b3ContactPoint& cp,const b3Vector3& rel_pos1,const b3Vector3& rel_pos2,b3RigidBodyData* colObj0,b3RigidBodyData* colObj1, b3Scalar relaxation, b3Scalar desiredVelocity, b3Scalar cfmSlip) +b3SolverConstraint& b3PgsJacobiSolver::addRollingFrictionConstraint(b3RigidBodyData* bodies, b3InertiaData* inertias, const b3Vector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, b3ContactPoint& cp, const b3Vector3& rel_pos1, const b3Vector3& rel_pos2, b3RigidBodyData* colObj0, b3RigidBodyData* colObj1, b3Scalar relaxation, b3Scalar desiredVelocity, b3Scalar cfmSlip) { b3SolverConstraint& solverConstraint = m_tmpSolverContactRollingFrictionConstraintPool.expandNonInitializing(); solverConstraint.m_frictionIndex = frictionIndex; - setupRollingFrictionConstraint(bodies,inertias,solverConstraint, normalAxis, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, - colObj0, colObj1, relaxation, desiredVelocity, cfmSlip); + setupRollingFrictionConstraint(bodies, inertias, solverConstraint, normalAxis, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, + colObj0, colObj1, relaxation, desiredVelocity, cfmSlip); return solverConstraint; } - -int b3PgsJacobiSolver::getOrInitSolverBody(int bodyIndex, b3RigidBodyData* bodies,b3InertiaData* inertias) +int b3PgsJacobiSolver::getOrInitSolverBody(int bodyIndex, b3RigidBodyData* bodies, b3InertiaData* inertias) { //b3Assert(bodyIndex< m_tmpSolverBodyPool.size()); b3RigidBodyData& body = bodies[bodyIndex]; int curIndex = -1; - if (m_usePgs || body.m_invMass==0.f) + if (m_usePgs || body.m_invMass == 0.f) { - if (m_bodyCount[bodyIndex]<0) + if (m_bodyCount[bodyIndex] < 0) { curIndex = m_tmpSolverBodyPool.size(); b3SolverBody& solverBody = m_tmpSolverBodyPool.expand(); - initSolverBody(bodyIndex,&solverBody,&body); + initSolverBody(bodyIndex, &solverBody, &body); solverBody.m_originalBodyIndex = bodyIndex; m_bodyCount[bodyIndex] = curIndex; - } else + } + else { curIndex = m_bodyCount[bodyIndex]; } - } else + } + else { - b3Assert(m_bodyCount[bodyIndex]>0); + b3Assert(m_bodyCount[bodyIndex] > 0); m_bodyCountCheck[bodyIndex]++; curIndex = m_tmpSolverBodyPool.size(); b3SolverBody& solverBody = m_tmpSolverBodyPool.expand(); - initSolverBody(bodyIndex,&solverBody,&body); + initSolverBody(bodyIndex, &solverBody, &body); solverBody.m_originalBodyIndex = bodyIndex; } - b3Assert(curIndex>=0); + b3Assert(curIndex >= 0); return curIndex; - } #include - -void b3PgsJacobiSolver::setupContactConstraint(b3RigidBodyData* bodies, b3InertiaData* inertias,b3SolverConstraint& solverConstraint, - int solverBodyIdA, int solverBodyIdB, - b3ContactPoint& cp, const b3ContactSolverInfo& infoGlobal, - b3Vector3& vel, b3Scalar& rel_vel, b3Scalar& relaxation, - b3Vector3& rel_pos1, b3Vector3& rel_pos2) -{ - - const b3Vector3& pos1 = cp.getPositionWorldOnA(); - const b3Vector3& pos2 = cp.getPositionWorldOnB(); - - b3SolverBody* bodyA = &m_tmpSolverBodyPool[solverBodyIdA]; - b3SolverBody* bodyB = &m_tmpSolverBodyPool[solverBodyIdB]; - - b3RigidBodyData* rb0 = &bodies[bodyA->m_originalBodyIndex]; - b3RigidBodyData* rb1 = &bodies[bodyB->m_originalBodyIndex]; - -// b3Vector3 rel_pos1 = pos1 - colObj0->getWorldTransform().getOrigin(); -// b3Vector3 rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin(); - rel_pos1 = pos1 - bodyA->getWorldTransform().getOrigin(); - rel_pos2 = pos2 - bodyB->getWorldTransform().getOrigin(); - - relaxation = 1.f; - - b3Vector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB); - solverConstraint.m_angularComponentA = rb0 ? getInvInertiaTensorWorld(&inertias[bodyA->m_originalBodyIndex])*torqueAxis0 : b3MakeVector3(0,0,0); - b3Vector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB); - solverConstraint.m_angularComponentB = rb1 ? getInvInertiaTensorWorld(&inertias[bodyB->m_originalBodyIndex])*-torqueAxis1 : b3MakeVector3(0,0,0); - - b3Scalar scaledDenom; - { -#ifdef COMPUTE_IMPULSE_DENOM - b3Scalar denom0 = rb0->computeImpulseDenominator(pos1,cp.m_normalWorldOnB); - b3Scalar denom1 = rb1->computeImpulseDenominator(pos2,cp.m_normalWorldOnB); -#else - b3Vector3 vec; - b3Scalar denom0 = 0.f; - b3Scalar denom1 = 0.f; - if (rb0) - { - vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1); - denom0 = rb0->m_invMass + cp.m_normalWorldOnB.dot(vec); - } - if (rb1) - { - vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2); - denom1 = rb1->m_invMass + cp.m_normalWorldOnB.dot(vec); - } -#endif //COMPUTE_IMPULSE_DENOM - - - b3Scalar denom; - if (m_usePgs) - { - scaledDenom = denom = relaxation/(denom0+denom1); - } else - { - denom = relaxation/(denom0+denom1); - - b3Scalar countA = rb0->m_invMass? b3Scalar(m_bodyCount[bodyA->m_originalBodyIndex]) : 1.f; - b3Scalar countB = rb1->m_invMass? b3Scalar(m_bodyCount[bodyB->m_originalBodyIndex]) : 1.f; - scaledDenom = relaxation/(denom0*countA+denom1*countB); - } - solverConstraint.m_jacDiagABInv = denom; - } - - solverConstraint.m_contactNormal = cp.m_normalWorldOnB; - solverConstraint.m_relpos1CrossNormal = torqueAxis0; - solverConstraint.m_relpos2CrossNormal = -torqueAxis1; - - b3Scalar restitution = 0.f; - b3Scalar penetration = cp.getDistance()+infoGlobal.m_linearSlop; - - { - b3Vector3 vel1,vel2; - - vel1 = rb0? getVelocityInLocalPoint(rb0,rel_pos1) : b3MakeVector3(0,0,0); - vel2 = rb1? getVelocityInLocalPoint(rb1, rel_pos2) : b3MakeVector3(0,0,0); - - // b3Vector3 vel2 = rb1 ? rb1->getVelocityInLocalPoint(rel_pos2) : b3Vector3(0,0,0); - vel = vel1 - vel2; - rel_vel = cp.m_normalWorldOnB.dot(vel); - - - - solverConstraint.m_friction = cp.m_combinedFriction; - - - restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution); - if (restitution <= b3Scalar(0.)) - { - restitution = 0.f; - }; - } - - - ///warm starting (or zero if disabled) - if (infoGlobal.m_solverMode & B3_SOLVER_USE_WARMSTARTING) - { - solverConstraint.m_appliedImpulse = cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor; - if (rb0) - bodyA->internalApplyImpulse(solverConstraint.m_contactNormal*bodyA->internalGetInvMass(),solverConstraint.m_angularComponentA,solverConstraint.m_appliedImpulse); - if (rb1) - bodyB->internalApplyImpulse(solverConstraint.m_contactNormal*bodyB->internalGetInvMass(),-solverConstraint.m_angularComponentB,-(b3Scalar)solverConstraint.m_appliedImpulse); - } else - { - solverConstraint.m_appliedImpulse = 0.f; - } - - solverConstraint.m_appliedPushImpulse = 0.f; - - { - b3Scalar vel1Dotn = solverConstraint.m_contactNormal.dot(rb0?bodyA->m_linearVelocity:b3MakeVector3(0,0,0)) - + solverConstraint.m_relpos1CrossNormal.dot(rb0?bodyA->m_angularVelocity:b3MakeVector3(0,0,0)); - b3Scalar vel2Dotn = -solverConstraint.m_contactNormal.dot(rb1?bodyB->m_linearVelocity:b3MakeVector3(0,0,0)) - + solverConstraint.m_relpos2CrossNormal.dot(rb1?bodyB->m_angularVelocity:b3MakeVector3(0,0,0)); - b3Scalar rel_vel = vel1Dotn+vel2Dotn; - - b3Scalar positionalError = 0.f; - b3Scalar velocityError = restitution - rel_vel;// * damping; - - - b3Scalar erp = infoGlobal.m_erp2; - if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold)) - { - erp = infoGlobal.m_erp; - } - - if (penetration>0) - { - positionalError = 0; - - velocityError -= penetration / infoGlobal.m_timeStep; - } else - { - positionalError = -penetration * erp/infoGlobal.m_timeStep; - } - - b3Scalar penetrationImpulse = positionalError*scaledDenom;//solverConstraint.m_jacDiagABInv; - b3Scalar velocityImpulse = velocityError *scaledDenom;//solverConstraint.m_jacDiagABInv; - - if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold)) - { - //combine position and velocity into rhs - solverConstraint.m_rhs = penetrationImpulse+velocityImpulse; - solverConstraint.m_rhsPenetration = 0.f; - - } else - { - //split position and velocity into rhs and m_rhsPenetration - solverConstraint.m_rhs = velocityImpulse; - solverConstraint.m_rhsPenetration = penetrationImpulse; - } - solverConstraint.m_cfm = 0.f; - solverConstraint.m_lowerLimit = 0; - solverConstraint.m_upperLimit = 1e10f; - } - - - - -} - - - -void b3PgsJacobiSolver::setFrictionConstraintImpulse( b3RigidBodyData* bodies, b3InertiaData* inertias,b3SolverConstraint& solverConstraint, - int solverBodyIdA, int solverBodyIdB, - b3ContactPoint& cp, const b3ContactSolverInfo& infoGlobal) +void b3PgsJacobiSolver::setupContactConstraint(b3RigidBodyData* bodies, b3InertiaData* inertias, b3SolverConstraint& solverConstraint, + int solverBodyIdA, int solverBodyIdB, + b3ContactPoint& cp, const b3ContactSolverInfo& infoGlobal, + b3Vector3& vel, b3Scalar& rel_vel, b3Scalar& relaxation, + b3Vector3& rel_pos1, b3Vector3& rel_pos2) { + const b3Vector3& pos1 = cp.getPositionWorldOnA(); + const b3Vector3& pos2 = cp.getPositionWorldOnB(); b3SolverBody* bodyA = &m_tmpSolverBodyPool[solverBodyIdA]; b3SolverBody* bodyB = &m_tmpSolverBodyPool[solverBodyIdB]; + b3RigidBodyData* rb0 = &bodies[bodyA->m_originalBodyIndex]; + b3RigidBodyData* rb1 = &bodies[bodyB->m_originalBodyIndex]; + + // b3Vector3 rel_pos1 = pos1 - colObj0->getWorldTransform().getOrigin(); + // b3Vector3 rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin(); + rel_pos1 = pos1 - bodyA->getWorldTransform().getOrigin(); + rel_pos2 = pos2 - bodyB->getWorldTransform().getOrigin(); + + relaxation = 1.f; + + b3Vector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB); + solverConstraint.m_angularComponentA = rb0 ? getInvInertiaTensorWorld(&inertias[bodyA->m_originalBodyIndex]) * torqueAxis0 : b3MakeVector3(0, 0, 0); + b3Vector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB); + solverConstraint.m_angularComponentB = rb1 ? getInvInertiaTensorWorld(&inertias[bodyB->m_originalBodyIndex]) * -torqueAxis1 : b3MakeVector3(0, 0, 0); + + b3Scalar scaledDenom; + { +#ifdef COMPUTE_IMPULSE_DENOM + b3Scalar denom0 = rb0->computeImpulseDenominator(pos1, cp.m_normalWorldOnB); + b3Scalar denom1 = rb1->computeImpulseDenominator(pos2, cp.m_normalWorldOnB); +#else + b3Vector3 vec; + b3Scalar denom0 = 0.f; + b3Scalar denom1 = 0.f; + if (rb0) + { + vec = (solverConstraint.m_angularComponentA).cross(rel_pos1); + denom0 = rb0->m_invMass + cp.m_normalWorldOnB.dot(vec); + } + if (rb1) + { + vec = (-solverConstraint.m_angularComponentB).cross(rel_pos2); + denom1 = rb1->m_invMass + cp.m_normalWorldOnB.dot(vec); + } +#endif //COMPUTE_IMPULSE_DENOM + + b3Scalar denom; + if (m_usePgs) + { + scaledDenom = denom = relaxation / (denom0 + denom1); + } + else + { + denom = relaxation / (denom0 + denom1); + + b3Scalar countA = rb0->m_invMass ? b3Scalar(m_bodyCount[bodyA->m_originalBodyIndex]) : 1.f; + b3Scalar countB = rb1->m_invMass ? b3Scalar(m_bodyCount[bodyB->m_originalBodyIndex]) : 1.f; + scaledDenom = relaxation / (denom0 * countA + denom1 * countB); + } + solverConstraint.m_jacDiagABInv = denom; + } + + solverConstraint.m_contactNormal = cp.m_normalWorldOnB; + solverConstraint.m_relpos1CrossNormal = torqueAxis0; + solverConstraint.m_relpos2CrossNormal = -torqueAxis1; + + b3Scalar restitution = 0.f; + b3Scalar penetration = cp.getDistance() + infoGlobal.m_linearSlop; + + { + b3Vector3 vel1, vel2; + + vel1 = rb0 ? getVelocityInLocalPoint(rb0, rel_pos1) : b3MakeVector3(0, 0, 0); + vel2 = rb1 ? getVelocityInLocalPoint(rb1, rel_pos2) : b3MakeVector3(0, 0, 0); + + // b3Vector3 vel2 = rb1 ? rb1->getVelocityInLocalPoint(rel_pos2) : b3Vector3(0,0,0); + vel = vel1 - vel2; + rel_vel = cp.m_normalWorldOnB.dot(vel); + + solverConstraint.m_friction = cp.m_combinedFriction; + + restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution); + if (restitution <= b3Scalar(0.)) + { + restitution = 0.f; + }; + } + + ///warm starting (or zero if disabled) + if (infoGlobal.m_solverMode & B3_SOLVER_USE_WARMSTARTING) + { + solverConstraint.m_appliedImpulse = cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor; + if (rb0) + bodyA->internalApplyImpulse(solverConstraint.m_contactNormal * bodyA->internalGetInvMass(), solverConstraint.m_angularComponentA, solverConstraint.m_appliedImpulse); + if (rb1) + bodyB->internalApplyImpulse(solverConstraint.m_contactNormal * bodyB->internalGetInvMass(), -solverConstraint.m_angularComponentB, -(b3Scalar)solverConstraint.m_appliedImpulse); + } + else + { + solverConstraint.m_appliedImpulse = 0.f; + } + + solverConstraint.m_appliedPushImpulse = 0.f; + + { + b3Scalar vel1Dotn = solverConstraint.m_contactNormal.dot(rb0 ? bodyA->m_linearVelocity : b3MakeVector3(0, 0, 0)) + solverConstraint.m_relpos1CrossNormal.dot(rb0 ? bodyA->m_angularVelocity : b3MakeVector3(0, 0, 0)); + b3Scalar vel2Dotn = -solverConstraint.m_contactNormal.dot(rb1 ? bodyB->m_linearVelocity : b3MakeVector3(0, 0, 0)) + solverConstraint.m_relpos2CrossNormal.dot(rb1 ? bodyB->m_angularVelocity : b3MakeVector3(0, 0, 0)); + b3Scalar rel_vel = vel1Dotn + vel2Dotn; + + b3Scalar positionalError = 0.f; + b3Scalar velocityError = restitution - rel_vel; // * damping; + + b3Scalar erp = infoGlobal.m_erp2; + if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold)) + { + erp = infoGlobal.m_erp; + } + + if (penetration > 0) + { + positionalError = 0; + + velocityError -= penetration / infoGlobal.m_timeStep; + } + else + { + positionalError = -penetration * erp / infoGlobal.m_timeStep; + } + + b3Scalar penetrationImpulse = positionalError * scaledDenom; //solverConstraint.m_jacDiagABInv; + b3Scalar velocityImpulse = velocityError * scaledDenom; //solverConstraint.m_jacDiagABInv; + + if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold)) + { + //combine position and velocity into rhs + solverConstraint.m_rhs = penetrationImpulse + velocityImpulse; + solverConstraint.m_rhsPenetration = 0.f; + } + else + { + //split position and velocity into rhs and m_rhsPenetration + solverConstraint.m_rhs = velocityImpulse; + solverConstraint.m_rhsPenetration = penetrationImpulse; + } + solverConstraint.m_cfm = 0.f; + solverConstraint.m_lowerLimit = 0; + solverConstraint.m_upperLimit = 1e10f; + } +} + +void b3PgsJacobiSolver::setFrictionConstraintImpulse(b3RigidBodyData* bodies, b3InertiaData* inertias, b3SolverConstraint& solverConstraint, + int solverBodyIdA, int solverBodyIdB, + b3ContactPoint& cp, const b3ContactSolverInfo& infoGlobal) +{ + b3SolverBody* bodyA = &m_tmpSolverBodyPool[solverBodyIdA]; + b3SolverBody* bodyB = &m_tmpSolverBodyPool[solverBodyIdB]; { b3SolverConstraint& frictionConstraint1 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex]; @@ -886,10 +816,11 @@ void b3PgsJacobiSolver::setFrictionConstraintImpulse( b3RigidBodyData* bodies, b { frictionConstraint1.m_appliedImpulse = cp.m_appliedImpulseLateral1 * infoGlobal.m_warmstartingFactor; if (bodies[bodyA->m_originalBodyIndex].m_invMass) - bodyA->internalApplyImpulse(frictionConstraint1.m_contactNormal*bodies[bodyA->m_originalBodyIndex].m_invMass,frictionConstraint1.m_angularComponentA,frictionConstraint1.m_appliedImpulse); + bodyA->internalApplyImpulse(frictionConstraint1.m_contactNormal * bodies[bodyA->m_originalBodyIndex].m_invMass, frictionConstraint1.m_angularComponentA, frictionConstraint1.m_appliedImpulse); if (bodies[bodyB->m_originalBodyIndex].m_invMass) - bodyB->internalApplyImpulse(frictionConstraint1.m_contactNormal*bodies[bodyB->m_originalBodyIndex].m_invMass,-frictionConstraint1.m_angularComponentB,-(b3Scalar)frictionConstraint1.m_appliedImpulse); - } else + bodyB->internalApplyImpulse(frictionConstraint1.m_contactNormal * bodies[bodyB->m_originalBodyIndex].m_invMass, -frictionConstraint1.m_angularComponentB, -(b3Scalar)frictionConstraint1.m_appliedImpulse); + } + else { frictionConstraint1.m_appliedImpulse = 0.f; } @@ -897,51 +828,45 @@ void b3PgsJacobiSolver::setFrictionConstraintImpulse( b3RigidBodyData* bodies, b if ((infoGlobal.m_solverMode & B3_SOLVER_USE_2_FRICTION_DIRECTIONS)) { - b3SolverConstraint& frictionConstraint2 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex+1]; + b3SolverConstraint& frictionConstraint2 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex + 1]; if (infoGlobal.m_solverMode & B3_SOLVER_USE_WARMSTARTING) { - frictionConstraint2.m_appliedImpulse = cp.m_appliedImpulseLateral2 * infoGlobal.m_warmstartingFactor; + frictionConstraint2.m_appliedImpulse = cp.m_appliedImpulseLateral2 * infoGlobal.m_warmstartingFactor; if (bodies[bodyA->m_originalBodyIndex].m_invMass) - bodyA->internalApplyImpulse(frictionConstraint2.m_contactNormal*bodies[bodyA->m_originalBodyIndex].m_invMass,frictionConstraint2.m_angularComponentA,frictionConstraint2.m_appliedImpulse); + bodyA->internalApplyImpulse(frictionConstraint2.m_contactNormal * bodies[bodyA->m_originalBodyIndex].m_invMass, frictionConstraint2.m_angularComponentA, frictionConstraint2.m_appliedImpulse); if (bodies[bodyB->m_originalBodyIndex].m_invMass) - bodyB->internalApplyImpulse(frictionConstraint2.m_contactNormal*bodies[bodyB->m_originalBodyIndex].m_invMass,-frictionConstraint2.m_angularComponentB,-(b3Scalar)frictionConstraint2.m_appliedImpulse); - } else + bodyB->internalApplyImpulse(frictionConstraint2.m_contactNormal * bodies[bodyB->m_originalBodyIndex].m_invMass, -frictionConstraint2.m_angularComponentB, -(b3Scalar)frictionConstraint2.m_appliedImpulse); + } + else { frictionConstraint2.m_appliedImpulse = 0.f; } } } - - - -void b3PgsJacobiSolver::convertContact(b3RigidBodyData* bodies, b3InertiaData* inertias,b3Contact4* manifold,const b3ContactSolverInfo& infoGlobal) +void b3PgsJacobiSolver::convertContact(b3RigidBodyData* bodies, b3InertiaData* inertias, b3Contact4* manifold, const b3ContactSolverInfo& infoGlobal) { - b3RigidBodyData* colObj0=0,*colObj1=0; + b3RigidBodyData *colObj0 = 0, *colObj1 = 0; - - int solverBodyIdA = getOrInitSolverBody(manifold->getBodyA(),bodies,inertias); - int solverBodyIdB = getOrInitSolverBody(manifold->getBodyB(),bodies,inertias); + int solverBodyIdA = getOrInitSolverBody(manifold->getBodyA(), bodies, inertias); + int solverBodyIdB = getOrInitSolverBody(manifold->getBodyB(), bodies, inertias); -// b3RigidBody* bodyA = b3RigidBody::upcast(colObj0); -// b3RigidBody* bodyB = b3RigidBody::upcast(colObj1); + // b3RigidBody* bodyA = b3RigidBody::upcast(colObj0); + // b3RigidBody* bodyB = b3RigidBody::upcast(colObj1); b3SolverBody* solverBodyA = &m_tmpSolverBodyPool[solverBodyIdA]; b3SolverBody* solverBodyB = &m_tmpSolverBodyPool[solverBodyIdB]; - - ///avoid collision response between two static objects if (solverBodyA->m_invMass.isZero() && solverBodyB->m_invMass.isZero()) return; - int rollingFriction=1; + int rollingFriction = 1; int numContacts = getNumContacts(manifold); - for (int j=0;jgetAngularVelocity(angVelA); - solverBodyB->getAngularVelocity(angVelB); - b3Vector3 relAngVel = angVelB-angVelA; + solverBodyB->getAngularVelocity(angVelB); + b3Vector3 relAngVel = angVelB - angVelA; - if ((cp.m_combinedRollingFriction>0.f) && (rollingFriction>0)) + if ((cp.m_combinedRollingFriction > 0.f) && (rollingFriction > 0)) { //only a single rollingFriction per manifold rollingFriction--; - if (relAngVel.length()>infoGlobal.m_singleAxisRollingFrictionThreshold) + if (relAngVel.length() > infoGlobal.m_singleAxisRollingFrictionThreshold) { relAngVel.normalize(); - if (relAngVel.length()>0.001) - addRollingFrictionConstraint(bodies,inertias,relAngVel,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); - - } else + if (relAngVel.length() > 0.001) + addRollingFrictionConstraint(bodies, inertias, relAngVel, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation); + } + else { - addRollingFrictionConstraint(bodies,inertias,cp.m_normalWorldOnB,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); - b3Vector3 axis0,axis1; - b3PlaneSpace1(cp.m_normalWorldOnB,axis0,axis1); - if (axis0.length()>0.001) - addRollingFrictionConstraint(bodies,inertias,axis0,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); - if (axis1.length()>0.001) - addRollingFrictionConstraint(bodies,inertias,axis1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); - + addRollingFrictionConstraint(bodies, inertias, cp.m_normalWorldOnB, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation); + b3Vector3 axis0, axis1; + b3PlaneSpace1(cp.m_normalWorldOnB, axis0, axis1); + if (axis0.length() > 0.001) + addRollingFrictionConstraint(bodies, inertias, axis0, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation); + if (axis1.length() > 0.001) + addRollingFrictionConstraint(bodies, inertias, axis1, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation); } } ///Bullet has several options to set the friction directions - ///By default, each contact has only a single friction direction that is recomputed automatically very frame + ///By default, each contact has only a single friction direction that is recomputed automatically very frame ///based on the relative linear velocity. ///If the relative velocity it zero, it will automatically compute a friction direction. - + ///You can also enable two friction directions, using the B3_SOLVER_USE_2_FRICTION_DIRECTIONS. ///In that case, the second friction direction will be orthogonal to both contact normal and first friction direction. /// ///If you choose B3_SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION, then the friction will be independent from the relative projected velocity. /// - ///The user can manually override the friction directions for certain contacts using a contact callback, + ///The user can manually override the friction directions for certain contacts using a contact callback, ///and set the cp.m_lateralFrictionInitialized to true ///In that case, you can set the target relative motion in each friction direction (cp.m_contactMotion1 and cp.m_contactMotion2) ///this will give a conveyor belt effect @@ -1018,99 +942,91 @@ void b3PgsJacobiSolver::convertContact(b3RigidBodyData* bodies, b3InertiaData* i b3Scalar lat_rel_vel = cp.m_lateralFrictionDir1.length2(); if (!(infoGlobal.m_solverMode & B3_SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION) && lat_rel_vel > B3_EPSILON) { - cp.m_lateralFrictionDir1 *= 1.f/b3Sqrt(lat_rel_vel); - if((infoGlobal.m_solverMode & B3_SOLVER_USE_2_FRICTION_DIRECTIONS)) + cp.m_lateralFrictionDir1 *= 1.f / b3Sqrt(lat_rel_vel); + if ((infoGlobal.m_solverMode & B3_SOLVER_USE_2_FRICTION_DIRECTIONS)) { cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB); - cp.m_lateralFrictionDir2.normalize();//?? - addFrictionConstraint(bodies,inertias,cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); - + cp.m_lateralFrictionDir2.normalize(); //?? + addFrictionConstraint(bodies, inertias, cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation); } - addFrictionConstraint(bodies,inertias,cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); - - } else + addFrictionConstraint(bodies, inertias, cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation); + } + else { - b3PlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2); + b3PlaneSpace1(cp.m_normalWorldOnB, cp.m_lateralFrictionDir1, cp.m_lateralFrictionDir2); if ((infoGlobal.m_solverMode & B3_SOLVER_USE_2_FRICTION_DIRECTIONS)) { - addFrictionConstraint(bodies,inertias,cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); + addFrictionConstraint(bodies, inertias, cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation); } - addFrictionConstraint(bodies,inertias,cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation); + addFrictionConstraint(bodies, inertias, cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation); if ((infoGlobal.m_solverMode & B3_SOLVER_USE_2_FRICTION_DIRECTIONS) && (infoGlobal.m_solverMode & B3_SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION)) { cp.m_lateralFrictionInitialized = true; } } - - } else + } + else { - addFrictionConstraint(bodies,inertias,cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation,cp.m_contactMotion1, cp.m_contactCFM1); + addFrictionConstraint(bodies, inertias, cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, cp.m_contactMotion1, cp.m_contactCFM1); if ((infoGlobal.m_solverMode & B3_SOLVER_USE_2_FRICTION_DIRECTIONS)) - addFrictionConstraint(bodies,inertias,cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation, cp.m_contactMotion2, cp.m_contactCFM2); + addFrictionConstraint(bodies, inertias, cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, cp.m_contactMotion2, cp.m_contactCFM2); - setFrictionConstraintImpulse( bodies,inertias,solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal); + setFrictionConstraintImpulse(bodies, inertias, solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal); } - - - - } } } -b3Scalar b3PgsJacobiSolver::solveGroupCacheFriendlySetup(b3RigidBodyData* bodies, b3InertiaData* inertias, int numBodies, b3Contact4* manifoldPtr, int numManifolds,b3TypedConstraint** constraints,int numConstraints,const b3ContactSolverInfo& infoGlobal) +b3Scalar b3PgsJacobiSolver::solveGroupCacheFriendlySetup(b3RigidBodyData* bodies, b3InertiaData* inertias, int numBodies, b3Contact4* manifoldPtr, int numManifolds, b3TypedConstraint** constraints, int numConstraints, const b3ContactSolverInfo& infoGlobal) { B3_PROFILE("solveGroupCacheFriendlySetup"); - m_maxOverrideNumSolverIterations = 0; - - m_tmpSolverBodyPool.resize(0); - - + m_bodyCount.resize(0); - m_bodyCount.resize(numBodies,0); + m_bodyCount.resize(numBodies, 0); m_bodyCountCheck.resize(0); - m_bodyCountCheck.resize(numBodies,0); - + m_bodyCountCheck.resize(numBodies, 0); + m_deltaLinearVelocities.resize(0); - m_deltaLinearVelocities.resize(numBodies,b3MakeVector3(0,0,0)); + m_deltaLinearVelocities.resize(numBodies, b3MakeVector3(0, 0, 0)); m_deltaAngularVelocities.resize(0); - m_deltaAngularVelocities.resize(numBodies,b3MakeVector3(0,0,0)); - + m_deltaAngularVelocities.resize(numBodies, b3MakeVector3(0, 0, 0)); + //int totalBodies = 0; - for (int i=0;igetRigidBodyA(); int bodyIndexB = constraints[i]->getRigidBodyB(); if (m_usePgs) { - m_bodyCount[bodyIndexA]=-1; - m_bodyCount[bodyIndexB]=-1; - } else + m_bodyCount[bodyIndexA] = -1; + m_bodyCount[bodyIndexB] = -1; + } + else { //didn't implement joints with Jacobi version yet b3Assert(0); } - } - for (int i=0;iinternalSetAppliedImpulse(0.0f); } } @@ -1146,13 +1059,12 @@ b3Scalar b3PgsJacobiSolver::solveGroupCacheFriendlySetup(b3RigidBodyData* bodies //if (1) { { - int totalNumRows = 0; int i; - + m_tmpConstraintSizesPool.resizeNoInitialize(numConstraints); //calculate the total number of contraint rows - for (i=0;igetJointFeedback(); @@ -1169,8 +1081,9 @@ b3Scalar b3PgsJacobiSolver::solveGroupCacheFriendlySetup(b3RigidBodyData* bodies } if (constraints[i]->isEnabled()) { - constraints[i]->getInfo1(&info1,bodies); - } else + constraints[i]->getInfo1(&info1, bodies); + } + else { info1.m_numConstraintRows = 0; info1.nub = 0; @@ -1179,45 +1092,40 @@ b3Scalar b3PgsJacobiSolver::solveGroupCacheFriendlySetup(b3RigidBodyData* bodies } m_tmpSolverNonContactConstraintPool.resizeNoInitialize(totalNumRows); - #ifndef DISABLE_JOINTS ///setup the b3SolverConstraints int currentRow = 0; - for (i=0;igetRigidBodyA()]; + b3RigidBodyData& rbA = bodies[constraint->getRigidBodyA()]; //b3RigidBody& rbA = constraint->getRigidBodyA(); - // b3RigidBody& rbB = constraint->getRigidBodyB(); - b3RigidBodyData& rbB = bodies[ constraint->getRigidBodyB()]; - - int solverBodyIdA = getOrInitSolverBody(constraint->getRigidBodyA(),bodies,inertias); - int solverBodyIdB = getOrInitSolverBody(constraint->getRigidBodyB(),bodies,inertias); - - b3SolverBody* bodyAPtr = &m_tmpSolverBodyPool[solverBodyIdA]; - b3SolverBody* bodyBPtr = &m_tmpSolverBodyPool[solverBodyIdB]; - + // b3RigidBody& rbB = constraint->getRigidBodyB(); + b3RigidBodyData& rbB = bodies[constraint->getRigidBodyB()]; + int solverBodyIdA = getOrInitSolverBody(constraint->getRigidBodyA(), bodies, inertias); + int solverBodyIdB = getOrInitSolverBody(constraint->getRigidBodyB(), bodies, inertias); + b3SolverBody* bodyAPtr = &m_tmpSolverBodyPool[solverBodyIdA]; + b3SolverBody* bodyBPtr = &m_tmpSolverBodyPool[solverBodyIdB]; int overrideNumSolverIterations = constraint->getOverrideNumSolverIterations() > 0 ? constraint->getOverrideNumSolverIterations() : infoGlobal.m_numIterations; - if (overrideNumSolverIterations>m_maxOverrideNumSolverIterations) + if (overrideNumSolverIterations > m_maxOverrideNumSolverIterations) m_maxOverrideNumSolverIterations = overrideNumSolverIterations; - int j; - for ( j=0;jinternalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f); - bodyAPtr->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f); - bodyAPtr->internalGetPushVelocity().setValue(0.f,0.f,0.f); - bodyAPtr->internalGetTurnVelocity().setValue(0.f,0.f,0.f); - bodyBPtr->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f); - bodyBPtr->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f); - bodyBPtr->internalGetPushVelocity().setValue(0.f,0.f,0.f); - bodyBPtr->internalGetTurnVelocity().setValue(0.f,0.f,0.f); - + bodyAPtr->internalGetDeltaLinearVelocity().setValue(0.f, 0.f, 0.f); + bodyAPtr->internalGetDeltaAngularVelocity().setValue(0.f, 0.f, 0.f); + bodyAPtr->internalGetPushVelocity().setValue(0.f, 0.f, 0.f); + bodyAPtr->internalGetTurnVelocity().setValue(0.f, 0.f, 0.f); + bodyBPtr->internalGetDeltaLinearVelocity().setValue(0.f, 0.f, 0.f); + bodyBPtr->internalGetDeltaAngularVelocity().setValue(0.f, 0.f, 0.f); + bodyBPtr->internalGetPushVelocity().setValue(0.f, 0.f, 0.f); + bodyBPtr->internalGetTurnVelocity().setValue(0.f, 0.f, 0.f); b3TypedConstraint::b3ConstraintInfo2 info2; - info2.fps = 1.f/infoGlobal.m_timeStep; + info2.fps = 1.f / infoGlobal.m_timeStep; info2.erp = infoGlobal.m_erp; info2.m_J1linearAxis = currentConstraintRow->m_contactNormal; info2.m_J1angularAxis = currentConstraintRow->m_relpos1CrossNormal; info2.m_J2linearAxis = 0; info2.m_J2angularAxis = currentConstraintRow->m_relpos2CrossNormal; - info2.rowskip = sizeof(b3SolverConstraint)/sizeof(b3Scalar);//check this - ///the size of b3SolverConstraint needs be a multiple of b3Scalar - b3Assert(info2.rowskip*sizeof(b3Scalar)== sizeof(b3SolverConstraint)); + info2.rowskip = sizeof(b3SolverConstraint) / sizeof(b3Scalar); //check this + ///the size of b3SolverConstraint needs be a multiple of b3Scalar + b3Assert(info2.rowskip * sizeof(b3Scalar) == sizeof(b3SolverConstraint)); info2.m_constraintError = ¤tConstraintRow->m_rhs; currentConstraintRow->m_cfm = infoGlobal.m_globalCfm; info2.m_damping = infoGlobal.m_damping; @@ -1254,47 +1161,45 @@ b3Scalar b3PgsJacobiSolver::solveGroupCacheFriendlySetup(b3RigidBodyData* bodies info2.m_lowerLimit = ¤tConstraintRow->m_lowerLimit; info2.m_upperLimit = ¤tConstraintRow->m_upperLimit; info2.m_numIterations = infoGlobal.m_numIterations; - constraints[i]->getInfo2(&info2,bodies); + constraints[i]->getInfo2(&info2, bodies); ///finalize the constraint setup - for ( j=0;j=constraints[i]->getBreakingImpulseThreshold()) + if (solverConstraint.m_upperLimit >= constraints[i]->getBreakingImpulseThreshold()) { solverConstraint.m_upperLimit = constraints[i]->getBreakingImpulseThreshold(); } - if (solverConstraint.m_lowerLimit<=-constraints[i]->getBreakingImpulseThreshold()) + if (solverConstraint.m_lowerLimit <= -constraints[i]->getBreakingImpulseThreshold()) { solverConstraint.m_lowerLimit = -constraints[i]->getBreakingImpulseThreshold(); } solverConstraint.m_originalContactPoint = constraint; - - b3Matrix3x3& invInertiaWorldA= inertias[constraint->getRigidBodyA()].m_invInertiaWorld; - { + b3Matrix3x3& invInertiaWorldA = inertias[constraint->getRigidBodyA()].m_invInertiaWorld; + { //b3Vector3 angularFactorA(1,1,1); const b3Vector3& ftorqueAxis1 = solverConstraint.m_relpos1CrossNormal; - solverConstraint.m_angularComponentA = invInertiaWorldA*ftorqueAxis1;//*angularFactorA; + solverConstraint.m_angularComponentA = invInertiaWorldA * ftorqueAxis1; //*angularFactorA; } - - b3Matrix3x3& invInertiaWorldB= inertias[constraint->getRigidBodyB()].m_invInertiaWorld; - { + b3Matrix3x3& invInertiaWorldB = inertias[constraint->getRigidBodyB()].m_invInertiaWorld; + { const b3Vector3& ftorqueAxis2 = solverConstraint.m_relpos2CrossNormal; - solverConstraint.m_angularComponentB = invInertiaWorldB*ftorqueAxis2;//*constraint->getRigidBodyB().getAngularFactor(); + solverConstraint.m_angularComponentB = invInertiaWorldB * ftorqueAxis2; //*constraint->getRigidBodyB().getAngularFactor(); } { //it is ok to use solverConstraint.m_contactNormal instead of -solverConstraint.m_contactNormal //because it gets multiplied iMJlB - b3Vector3 iMJlA = solverConstraint.m_contactNormal*rbA.m_invMass; - b3Vector3 iMJaA = invInertiaWorldA*solverConstraint.m_relpos1CrossNormal; - b3Vector3 iMJlB = solverConstraint.m_contactNormal*rbB.m_invMass;//sign of normal? - b3Vector3 iMJaB = invInertiaWorldB*solverConstraint.m_relpos2CrossNormal; + b3Vector3 iMJlA = solverConstraint.m_contactNormal * rbA.m_invMass; + b3Vector3 iMJaA = invInertiaWorldA * solverConstraint.m_relpos1CrossNormal; + b3Vector3 iMJlB = solverConstraint.m_contactNormal * rbB.m_invMass; //sign of normal? + b3Vector3 iMJaB = invInertiaWorldB * solverConstraint.m_relpos2CrossNormal; b3Scalar sum = iMJlA.dot(solverConstraint.m_contactNormal); sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal); @@ -1302,10 +1207,9 @@ b3Scalar b3PgsJacobiSolver::solveGroupCacheFriendlySetup(b3RigidBodyData* bodies sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal); b3Scalar fsum = b3Fabs(sum); b3Assert(fsum > B3_EPSILON); - solverConstraint.m_jacDiagABInv = fsum>B3_EPSILON?b3Scalar(1.)/sum : 0.f; + solverConstraint.m_jacDiagABInv = fsum > B3_EPSILON ? b3Scalar(1.) / sum : 0.f; } - ///fix rhs ///todo: add force/torque accelerators { @@ -1313,38 +1217,35 @@ b3Scalar b3PgsJacobiSolver::solveGroupCacheFriendlySetup(b3RigidBodyData* bodies b3Scalar vel1Dotn = solverConstraint.m_contactNormal.dot(rbA.m_linVel) + solverConstraint.m_relpos1CrossNormal.dot(rbA.m_angVel); b3Scalar vel2Dotn = -solverConstraint.m_contactNormal.dot(rbB.m_linVel) + solverConstraint.m_relpos2CrossNormal.dot(rbB.m_angVel); - rel_vel = vel1Dotn+vel2Dotn; + rel_vel = vel1Dotn + vel2Dotn; b3Scalar restitution = 0.f; - b3Scalar positionalError = solverConstraint.m_rhs;//already filled in by getConstraintInfo2 - b3Scalar velocityError = restitution - rel_vel * info2.m_damping; - b3Scalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv; - b3Scalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv; - solverConstraint.m_rhs = penetrationImpulse+velocityImpulse; + b3Scalar positionalError = solverConstraint.m_rhs; //already filled in by getConstraintInfo2 + b3Scalar velocityError = restitution - rel_vel * info2.m_damping; + b3Scalar penetrationImpulse = positionalError * solverConstraint.m_jacDiagABInv; + b3Scalar velocityImpulse = velocityError * solverConstraint.m_jacDiagABInv; + solverConstraint.m_rhs = penetrationImpulse + velocityImpulse; solverConstraint.m_appliedImpulse = 0.f; - } } } - currentRow+=m_tmpConstraintSizesPool[i].m_numConstraintRows; + currentRow += m_tmpConstraintSizesPool[i].m_numConstraintRows; } -#endif //DISABLE_JOINTS +#endif //DISABLE_JOINTS } - { int i; - for (i=0;ib3Scalar(0)) + if (totalImpulse > b3Scalar(0)) { - solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse); - solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse; + solveManifold.m_lowerLimit = -(solveManifold.m_friction * totalImpulse); + solveManifold.m_upperLimit = solveManifold.m_friction * totalImpulse; - resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold); + resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold); } } if (infoGlobal.m_solverMode & B3_SOLVER_USE_2_FRICTION_DIRECTIONS) { + b3SolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[c * multiplier + 1]]; - b3SolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[c*multiplier+1]]; - - if (totalImpulse>b3Scalar(0)) + if (totalImpulse > b3Scalar(0)) { - solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse); - solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse; + solveManifold.m_lowerLimit = -(solveManifold.m_friction * totalImpulse); + solveManifold.m_upperLimit = solveManifold.m_friction * totalImpulse; - resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold); + resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold); } } } } - } - else//B3_SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS + else //B3_SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS { //solve the friction constraints after all contact constraints, don't interleave them int numPoolConstraints = m_tmpSolverContactConstraintPool.size(); int j; - for (j=0;jb3Scalar(0)) + if (totalImpulse > b3Scalar(0)) { - solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse); - solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse; + solveManifold.m_lowerLimit = -(solveManifold.m_friction * totalImpulse); + solveManifold.m_upperLimit = solveManifold.m_friction * totalImpulse; - resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold); + resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold); } } - int numRollingFrictionPoolConstraints = m_tmpSolverContactRollingFrictionConstraintPool.size(); - for (j=0;jb3Scalar(0)) + if (totalImpulse > b3Scalar(0)) { - b3Scalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction*totalImpulse; - if (rollingFrictionMagnitude>rollingFrictionConstraint.m_friction) + b3Scalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction * totalImpulse; + if (rollingFrictionMagnitude > rollingFrictionConstraint.m_friction) rollingFrictionMagnitude = rollingFrictionConstraint.m_friction; rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude; rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude; - resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA],m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB],rollingFrictionConstraint); + resolveSingleConstraintRowGenericSIMD(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA], m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB], rollingFrictionConstraint); } } - - - } + } } - } else + } + else { //non-SIMD version ///solve all joint constraints - for (int j=0;jb3Scalar(0)) + if (totalImpulse > b3Scalar(0)) { - solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse); - solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse; + solveManifold.m_lowerLimit = -(solveManifold.m_friction * totalImpulse); + solveManifold.m_upperLimit = solveManifold.m_friction * totalImpulse; - resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold); + resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold); } } int numRollingFrictionPoolConstraints = m_tmpSolverContactRollingFrictionConstraintPool.size(); - for (int j=0;jb3Scalar(0)) + if (totalImpulse > b3Scalar(0)) { - b3Scalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction*totalImpulse; - if (rollingFrictionMagnitude>rollingFrictionConstraint.m_friction) + b3Scalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction * totalImpulse; + if (rollingFrictionMagnitude > rollingFrictionConstraint.m_friction) rollingFrictionMagnitude = rollingFrictionConstraint.m_friction; rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude; rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude; - resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA],m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB],rollingFrictionConstraint); + resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA], m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB], rollingFrictionConstraint); } } } @@ -1595,40 +1485,39 @@ b3Scalar b3PgsJacobiSolver::solveSingleIteration(int iteration,b3TypedConstraint return 0.f; } - -void b3PgsJacobiSolver::solveGroupCacheFriendlySplitImpulseIterations(b3TypedConstraint** constraints,int numConstraints,const b3ContactSolverInfo& infoGlobal) +void b3PgsJacobiSolver::solveGroupCacheFriendlySplitImpulseIterations(b3TypedConstraint** constraints, int numConstraints, const b3ContactSolverInfo& infoGlobal) { int iteration; if (infoGlobal.m_splitImpulse) { if (infoGlobal.m_solverMode & B3_SOLVER_SIMD) { - for ( iteration = 0;iteration infoGlobal.m_numIterations? m_maxOverrideNumSolverIterations : infoGlobal.m_numIterations; + int maxIterations = m_maxOverrideNumSolverIterations > infoGlobal.m_numIterations ? m_maxOverrideNumSolverIterations : infoGlobal.m_numIterations; - for ( int iteration = 0 ; iteration< maxIterations ; iteration++) + for (int iteration = 0; iteration < maxIterations; iteration++) //for ( int iteration = maxIterations-1 ; iteration >= 0;iteration--) - { - - solveSingleIteration(iteration, constraints,numConstraints,infoGlobal); - + { + solveSingleIteration(iteration, constraints, numConstraints, infoGlobal); if (!m_usePgs) { averageVelocities(); } } - } return 0.f; } -void b3PgsJacobiSolver::averageVelocities() +void b3PgsJacobiSolver::averageVelocities() { B3_PROFILE("averaging"); //average the velocities int numBodies = m_bodyCount.size(); m_deltaLinearVelocities.resize(0); - m_deltaLinearVelocities.resize(numBodies,b3MakeVector3(0,0,0)); + m_deltaLinearVelocities.resize(numBodies, b3MakeVector3(0, 0, 0)); m_deltaAngularVelocities.resize(0); - m_deltaAngularVelocities.resize(numBodies,b3MakeVector3(0,0,0)); + m_deltaAngularVelocities.resize(numBodies, b3MakeVector3(0, 0, 0)); - for (int i=0;im_appliedImpulse = solveManifold.m_appliedImpulse; - // float f = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse; + // float f = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse; // printf("pt->m_appliedImpulseLateral1 = %f\n", f); pt->m_appliedImpulseLateral1 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse; //printf("pt->m_appliedImpulseLateral1 = %f\n", pt->m_appliedImpulseLateral1); if ((infoGlobal.m_solverMode & B3_SOLVER_USE_2_FRICTION_DIRECTIONS)) { - pt->m_appliedImpulseLateral2 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse; + pt->m_appliedImpulseLateral2 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex + 1].m_appliedImpulse; } //do a callback here? } } numPoolConstraints = m_tmpSolverNonContactConstraintPool.size(); - for (j=0;jm_appliedForceBodyA += solverConstr.m_contactNormal*solverConstr.m_appliedImpulse*bodyA->m_linearFactor/infoGlobal.m_timeStep; - fb->m_appliedForceBodyB += -solverConstr.m_contactNormal*solverConstr.m_appliedImpulse*bodyB->m_linearFactor/infoGlobal.m_timeStep; - fb->m_appliedTorqueBodyA += solverConstr.m_relpos1CrossNormal* bodyA->m_angularFactor*solverConstr.m_appliedImpulse/infoGlobal.m_timeStep; - fb->m_appliedTorqueBodyB += -solverConstr.m_relpos1CrossNormal* bodyB->m_angularFactor*solverConstr.m_appliedImpulse/infoGlobal.m_timeStep; - + fb->m_appliedForceBodyA += solverConstr.m_contactNormal * solverConstr.m_appliedImpulse * bodyA->m_linearFactor / infoGlobal.m_timeStep; + fb->m_appliedForceBodyB += -solverConstr.m_contactNormal * solverConstr.m_appliedImpulse * bodyB->m_linearFactor / infoGlobal.m_timeStep; + fb->m_appliedTorqueBodyA += solverConstr.m_relpos1CrossNormal * bodyA->m_angularFactor * solverConstr.m_appliedImpulse / infoGlobal.m_timeStep; + fb->m_appliedTorqueBodyB += -solverConstr.m_relpos1CrossNormal * bodyB->m_angularFactor * solverConstr.m_appliedImpulse / infoGlobal.m_timeStep; } constr->internalSetAppliedImpulse(solverConstr.m_appliedImpulse); - if (b3Fabs(solverConstr.m_appliedImpulse)>=constr->getBreakingImpulseThreshold()) + if (b3Fabs(solverConstr.m_appliedImpulse) >= constr->getBreakingImpulseThreshold()) { constr->setEnabled(false); } @@ -1755,7 +1638,7 @@ b3Scalar b3PgsJacobiSolver::solveGroupCacheFriendlyFinish(b3RigidBodyData* bodie { B3_PROFILE("write back velocities and transforms"); - for ( i=0;im_linVel = m_tmpSolverBodyPool[i].m_linearVelocity; body->m_angVel = m_tmpSolverBodyPool[i].m_angularVelocity; - } else + } + else { - b3Scalar factor = 1.f/b3Scalar(m_bodyCount[bodyIndex]); + b3Scalar factor = 1.f / b3Scalar(m_bodyCount[bodyIndex]); - b3Vector3 deltaLinVel = m_deltaLinearVelocities[bodyIndex]*factor; - b3Vector3 deltaAngVel = m_deltaAngularVelocities[bodyIndex]*factor; + b3Vector3 deltaLinVel = m_deltaLinearVelocities[bodyIndex] * factor; + b3Vector3 deltaAngVel = m_deltaAngularVelocities[bodyIndex] * factor; //printf("body %d\n",bodyIndex); //printf("deltaLinVel = %f,%f,%f\n",deltaLinVel.getX(),deltaLinVel.getY(),deltaLinVel.getZ()); //printf("deltaAngVel = %f,%f,%f\n",deltaAngVel.getX(),deltaAngVel.getY(),deltaAngVel.getZ()); @@ -1785,7 +1669,7 @@ b3Scalar b3PgsJacobiSolver::solveGroupCacheFriendlyFinish(b3RigidBodyData* bodie body->m_linVel += deltaLinVel; body->m_angVel += deltaAngVel; } - + if (infoGlobal.m_splitImpulse) { body->m_pos = m_tmpSolverBodyPool[i].m_worldTransform.getOrigin(); @@ -1797,7 +1681,6 @@ b3Scalar b3PgsJacobiSolver::solveGroupCacheFriendlyFinish(b3RigidBodyData* bodie } } - m_tmpSolverContactConstraintPool.resizeNoInitialize(0); m_tmpSolverNonContactConstraintPool.resizeNoInitialize(0); m_tmpSolverContactFrictionConstraintPool.resizeNoInitialize(0); @@ -1807,9 +1690,7 @@ b3Scalar b3PgsJacobiSolver::solveGroupCacheFriendlyFinish(b3RigidBodyData* bodie return 0.f; } - - -void b3PgsJacobiSolver::reset() +void b3PgsJacobiSolver::reset() { m_btSeed2 = 0; } \ No newline at end of file diff --git a/src/Bullet3Dynamics/ConstraintSolver/b3PgsJacobiSolver.h b/src/Bullet3Dynamics/ConstraintSolver/b3PgsJacobiSolver.h index d2ca307fa..5b616541d 100644 --- a/src/Bullet3Dynamics/ConstraintSolver/b3PgsJacobiSolver.h +++ b/src/Bullet3Dynamics/ConstraintSolver/b3PgsJacobiSolver.h @@ -1,11 +1,9 @@ #ifndef B3_PGS_JACOBI_SOLVER #define B3_PGS_JACOBI_SOLVER - struct b3Contact4; struct b3ContactPoint; - class b3Dispatcher; #include "b3TypedConstraint.h" @@ -18,132 +16,118 @@ struct b3InertiaData; class b3PgsJacobiSolver { - protected: - b3AlignedObjectArray m_tmpSolverBodyPool; - b3ConstraintArray m_tmpSolverContactConstraintPool; - b3ConstraintArray m_tmpSolverNonContactConstraintPool; - b3ConstraintArray m_tmpSolverContactFrictionConstraintPool; - b3ConstraintArray m_tmpSolverContactRollingFrictionConstraintPool; + b3AlignedObjectArray m_tmpSolverBodyPool; + b3ConstraintArray m_tmpSolverContactConstraintPool; + b3ConstraintArray m_tmpSolverNonContactConstraintPool; + b3ConstraintArray m_tmpSolverContactFrictionConstraintPool; + b3ConstraintArray m_tmpSolverContactRollingFrictionConstraintPool; - b3AlignedObjectArray m_orderTmpConstraintPool; - b3AlignedObjectArray m_orderNonContactConstraintPool; - b3AlignedObjectArray m_orderFrictionConstraintPool; + b3AlignedObjectArray m_orderTmpConstraintPool; + b3AlignedObjectArray m_orderNonContactConstraintPool; + b3AlignedObjectArray m_orderFrictionConstraintPool; b3AlignedObjectArray m_tmpConstraintSizesPool; - - b3AlignedObjectArray m_bodyCount; - b3AlignedObjectArray m_bodyCountCheck; - - b3AlignedObjectArray m_deltaLinearVelocities; - b3AlignedObjectArray m_deltaAngularVelocities; - bool m_usePgs; - void averageVelocities(); + b3AlignedObjectArray m_bodyCount; + b3AlignedObjectArray m_bodyCountCheck; - int m_maxOverrideNumSolverIterations; + b3AlignedObjectArray m_deltaLinearVelocities; + b3AlignedObjectArray m_deltaAngularVelocities; - int m_numSplitImpulseRecoveries; + bool m_usePgs; + void averageVelocities(); - b3Scalar getContactProcessingThreshold(b3Contact4* contact) + int m_maxOverrideNumSolverIterations; + + int m_numSplitImpulseRecoveries; + + b3Scalar getContactProcessingThreshold(b3Contact4* contact) { return 0.02f; } - void setupFrictionConstraint( b3RigidBodyData* bodies,b3InertiaData* inertias, b3SolverConstraint& solverConstraint, const b3Vector3& normalAxis,int solverBodyIdA,int solverBodyIdB, - b3ContactPoint& cp,const b3Vector3& rel_pos1,const b3Vector3& rel_pos2, - b3RigidBodyData* colObj0,b3RigidBodyData* colObj1, b3Scalar relaxation, - b3Scalar desiredVelocity=0., b3Scalar cfmSlip=0.); + void setupFrictionConstraint(b3RigidBodyData* bodies, b3InertiaData* inertias, b3SolverConstraint& solverConstraint, const b3Vector3& normalAxis, int solverBodyIdA, int solverBodyIdB, + b3ContactPoint& cp, const b3Vector3& rel_pos1, const b3Vector3& rel_pos2, + b3RigidBodyData* colObj0, b3RigidBodyData* colObj1, b3Scalar relaxation, + b3Scalar desiredVelocity = 0., b3Scalar cfmSlip = 0.); - void setupRollingFrictionConstraint(b3RigidBodyData* bodies,b3InertiaData* inertias, b3SolverConstraint& solverConstraint, const b3Vector3& normalAxis,int solverBodyIdA,int solverBodyIdB, - b3ContactPoint& cp,const b3Vector3& rel_pos1,const b3Vector3& rel_pos2, - b3RigidBodyData* colObj0,b3RigidBodyData* colObj1, b3Scalar relaxation, - b3Scalar desiredVelocity=0., b3Scalar cfmSlip=0.); - - b3SolverConstraint& addFrictionConstraint(b3RigidBodyData* bodies,b3InertiaData* inertias,const b3Vector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,b3ContactPoint& cp,const b3Vector3& rel_pos1,const b3Vector3& rel_pos2,b3RigidBodyData* colObj0,b3RigidBodyData* colObj1, b3Scalar relaxation, b3Scalar desiredVelocity=0., b3Scalar cfmSlip=0.); - b3SolverConstraint& addRollingFrictionConstraint(b3RigidBodyData* bodies,b3InertiaData* inertias,const b3Vector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,b3ContactPoint& cp,const b3Vector3& rel_pos1,const b3Vector3& rel_pos2,b3RigidBodyData* colObj0,b3RigidBodyData* colObj1, b3Scalar relaxation, b3Scalar desiredVelocity=0, b3Scalar cfmSlip=0.f); + void setupRollingFrictionConstraint(b3RigidBodyData* bodies, b3InertiaData* inertias, b3SolverConstraint& solverConstraint, const b3Vector3& normalAxis, int solverBodyIdA, int solverBodyIdB, + b3ContactPoint& cp, const b3Vector3& rel_pos1, const b3Vector3& rel_pos2, + b3RigidBodyData* colObj0, b3RigidBodyData* colObj1, b3Scalar relaxation, + b3Scalar desiredVelocity = 0., b3Scalar cfmSlip = 0.); + b3SolverConstraint& addFrictionConstraint(b3RigidBodyData* bodies, b3InertiaData* inertias, const b3Vector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, b3ContactPoint& cp, const b3Vector3& rel_pos1, const b3Vector3& rel_pos2, b3RigidBodyData* colObj0, b3RigidBodyData* colObj1, b3Scalar relaxation, b3Scalar desiredVelocity = 0., b3Scalar cfmSlip = 0.); + b3SolverConstraint& addRollingFrictionConstraint(b3RigidBodyData* bodies, b3InertiaData* inertias, const b3Vector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, b3ContactPoint& cp, const b3Vector3& rel_pos1, const b3Vector3& rel_pos2, b3RigidBodyData* colObj0, b3RigidBodyData* colObj1, b3Scalar relaxation, b3Scalar desiredVelocity = 0, b3Scalar cfmSlip = 0.f); void setupContactConstraint(b3RigidBodyData* bodies, b3InertiaData* inertias, - b3SolverConstraint& solverConstraint, int solverBodyIdA, int solverBodyIdB, b3ContactPoint& cp, - const b3ContactSolverInfo& infoGlobal, b3Vector3& vel, b3Scalar& rel_vel, b3Scalar& relaxation, + b3SolverConstraint& solverConstraint, int solverBodyIdA, int solverBodyIdB, b3ContactPoint& cp, + const b3ContactSolverInfo& infoGlobal, b3Vector3& vel, b3Scalar& rel_vel, b3Scalar& relaxation, b3Vector3& rel_pos1, b3Vector3& rel_pos2); - void setFrictionConstraintImpulse( b3RigidBodyData* bodies, b3InertiaData* inertias,b3SolverConstraint& solverConstraint, int solverBodyIdA,int solverBodyIdB, - b3ContactPoint& cp, const b3ContactSolverInfo& infoGlobal); + void setFrictionConstraintImpulse(b3RigidBodyData* bodies, b3InertiaData* inertias, b3SolverConstraint& solverConstraint, int solverBodyIdA, int solverBodyIdB, + b3ContactPoint& cp, const b3ContactSolverInfo& infoGlobal); ///m_btSeed2 is used for re-arranging the constraint rows. improves convergence/quality of friction - unsigned long m_btSeed2; + unsigned long m_btSeed2; - b3Scalar restitutionCurve(b3Scalar rel_vel, b3Scalar restitution); - void convertContact(b3RigidBodyData* bodies, b3InertiaData* inertias,b3Contact4* manifold,const b3ContactSolverInfo& infoGlobal); + void convertContact(b3RigidBodyData* bodies, b3InertiaData* inertias, b3Contact4* manifold, const b3ContactSolverInfo& infoGlobal); + void resolveSplitPenetrationSIMD( + b3SolverBody& bodyA, b3SolverBody& bodyB, + const b3SolverConstraint& contactConstraint); - void resolveSplitPenetrationSIMD( - b3SolverBody& bodyA,b3SolverBody& bodyB, - const b3SolverConstraint& contactConstraint); - - void resolveSplitPenetrationImpulseCacheFriendly( - b3SolverBody& bodyA,b3SolverBody& bodyB, - const b3SolverConstraint& contactConstraint); + void resolveSplitPenetrationImpulseCacheFriendly( + b3SolverBody& bodyA, b3SolverBody& bodyB, + const b3SolverConstraint& contactConstraint); //internal method - int getOrInitSolverBody(int bodyIndex, b3RigidBodyData* bodies,b3InertiaData* inertias); - void initSolverBody(int bodyIndex, b3SolverBody* solverBody, b3RigidBodyData* collisionObject); + int getOrInitSolverBody(int bodyIndex, b3RigidBodyData* bodies, b3InertiaData* inertias); + void initSolverBody(int bodyIndex, b3SolverBody* solverBody, b3RigidBodyData* collisionObject); - void resolveSingleConstraintRowGeneric(b3SolverBody& bodyA,b3SolverBody& bodyB,const b3SolverConstraint& contactConstraint); + void resolveSingleConstraintRowGeneric(b3SolverBody& bodyA, b3SolverBody& bodyB, const b3SolverConstraint& contactConstraint); + + void resolveSingleConstraintRowGenericSIMD(b3SolverBody& bodyA, b3SolverBody& bodyB, const b3SolverConstraint& contactConstraint); + + void resolveSingleConstraintRowLowerLimit(b3SolverBody& bodyA, b3SolverBody& bodyB, const b3SolverConstraint& contactConstraint); + + void resolveSingleConstraintRowLowerLimitSIMD(b3SolverBody& bodyA, b3SolverBody& bodyB, const b3SolverConstraint& contactConstraint); - void resolveSingleConstraintRowGenericSIMD(b3SolverBody& bodyA,b3SolverBody& bodyB,const b3SolverConstraint& contactConstraint); - - void resolveSingleConstraintRowLowerLimit(b3SolverBody& bodyA,b3SolverBody& bodyB,const b3SolverConstraint& contactConstraint); - - void resolveSingleConstraintRowLowerLimitSIMD(b3SolverBody& bodyA,b3SolverBody& bodyB,const b3SolverConstraint& contactConstraint); - protected: + virtual b3Scalar solveGroupCacheFriendlySetup(b3RigidBodyData* bodies, b3InertiaData* inertias, int numBodies, b3Contact4* manifoldPtr, int numManifolds, b3TypedConstraint** constraints, int numConstraints, const b3ContactSolverInfo& infoGlobal); - virtual b3Scalar solveGroupCacheFriendlySetup(b3RigidBodyData* bodies, b3InertiaData* inertias,int numBodies,b3Contact4* manifoldPtr, int numManifolds,b3TypedConstraint** constraints,int numConstraints,const b3ContactSolverInfo& infoGlobal); - - - virtual b3Scalar solveGroupCacheFriendlyIterations(b3TypedConstraint** constraints,int numConstraints,const b3ContactSolverInfo& infoGlobal); - virtual void solveGroupCacheFriendlySplitImpulseIterations(b3TypedConstraint** constraints,int numConstraints,const b3ContactSolverInfo& infoGlobal); - b3Scalar solveSingleIteration(int iteration, b3TypedConstraint** constraints,int numConstraints,const b3ContactSolverInfo& infoGlobal); - - - virtual b3Scalar solveGroupCacheFriendlyFinish(b3RigidBodyData* bodies, b3InertiaData* inertias,int numBodies,const b3ContactSolverInfo& infoGlobal); + virtual b3Scalar solveGroupCacheFriendlyIterations(b3TypedConstraint** constraints, int numConstraints, const b3ContactSolverInfo& infoGlobal); + virtual void solveGroupCacheFriendlySplitImpulseIterations(b3TypedConstraint** constraints, int numConstraints, const b3ContactSolverInfo& infoGlobal); + b3Scalar solveSingleIteration(int iteration, b3TypedConstraint** constraints, int numConstraints, const b3ContactSolverInfo& infoGlobal); + virtual b3Scalar solveGroupCacheFriendlyFinish(b3RigidBodyData* bodies, b3InertiaData* inertias, int numBodies, const b3ContactSolverInfo& infoGlobal); public: - B3_DECLARE_ALIGNED_ALLOCATOR(); - + b3PgsJacobiSolver(bool usePgs); virtual ~b3PgsJacobiSolver(); -// void solveContacts(int numBodies, b3RigidBodyData* bodies, b3InertiaData* inertias, int numContacts, b3Contact4* contacts); - void solveContacts(int numBodies, b3RigidBodyData* bodies, b3InertiaData* inertias, int numContacts, b3Contact4* contacts, int numConstraints, b3TypedConstraint** constraints); + // void solveContacts(int numBodies, b3RigidBodyData* bodies, b3InertiaData* inertias, int numContacts, b3Contact4* contacts); + void solveContacts(int numBodies, b3RigidBodyData* bodies, b3InertiaData* inertias, int numContacts, b3Contact4* contacts, int numConstraints, b3TypedConstraint** constraints); - b3Scalar solveGroup(b3RigidBodyData* bodies,b3InertiaData* inertias,int numBodies,b3Contact4* manifoldPtr, int numManifolds,b3TypedConstraint** constraints,int numConstraints,const b3ContactSolverInfo& infoGlobal); + b3Scalar solveGroup(b3RigidBodyData* bodies, b3InertiaData* inertias, int numBodies, b3Contact4* manifoldPtr, int numManifolds, b3TypedConstraint** constraints, int numConstraints, const b3ContactSolverInfo& infoGlobal); ///clear internal cached data and reset random seed - virtual void reset(); - + virtual void reset(); + unsigned long b3Rand2(); - int b3RandInt2 (int n); + int b3RandInt2(int n); - void setRandSeed(unsigned long seed) + void setRandSeed(unsigned long seed) { m_btSeed2 = seed; } - unsigned long getRandSeed() const + unsigned long getRandSeed() const { return m_btSeed2; } - - - - }; -#endif //B3_PGS_JACOBI_SOLVER - +#endif //B3_PGS_JACOBI_SOLVER diff --git a/src/Bullet3Dynamics/ConstraintSolver/b3Point2PointConstraint.cpp b/src/Bullet3Dynamics/ConstraintSolver/b3Point2PointConstraint.cpp index 02c11db32..cfa7c7dd1 100644 --- a/src/Bullet3Dynamics/ConstraintSolver/b3Point2PointConstraint.cpp +++ b/src/Bullet3Dynamics/ConstraintSolver/b3Point2PointConstraint.cpp @@ -13,21 +13,14 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "b3Point2PointConstraint.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3RigidBodyData.h" #include - - - - -b3Point2PointConstraint::b3Point2PointConstraint(int rbA,int rbB, const b3Vector3& pivotInA,const b3Vector3& pivotInB) -:b3TypedConstraint(B3_POINT2POINT_CONSTRAINT_TYPE,rbA,rbB),m_pivotInA(pivotInA),m_pivotInB(pivotInB), -m_flags(0) +b3Point2PointConstraint::b3Point2PointConstraint(int rbA, int rbB, const b3Vector3& pivotInA, const b3Vector3& pivotInB) + : b3TypedConstraint(B3_POINT2POINT_CONSTRAINT_TYPE, rbA, rbB), m_pivotInA(pivotInA), m_pivotInB(pivotInB), m_flags(0) { - } /* @@ -40,22 +33,18 @@ m_useSolveConstraintObsolete(false) } */ - -void b3Point2PointConstraint::getInfo1 (b3ConstraintInfo1* info,const b3RigidBodyData* bodies) +void b3Point2PointConstraint::getInfo1(b3ConstraintInfo1* info, const b3RigidBodyData* bodies) { - getInfo1NonVirtual(info,bodies); + getInfo1NonVirtual(info, bodies); } -void b3Point2PointConstraint::getInfo1NonVirtual (b3ConstraintInfo1* info,const b3RigidBodyData* bodies) +void b3Point2PointConstraint::getInfo1NonVirtual(b3ConstraintInfo1* info, const b3RigidBodyData* bodies) { - info->m_numConstraintRows = 3; - info->nub = 3; + info->m_numConstraintRows = 3; + info->nub = 3; } - - - -void b3Point2PointConstraint::getInfo2 (b3ConstraintInfo2* info, const b3RigidBodyData* bodies) +void b3Point2PointConstraint::getInfo2(b3ConstraintInfo2* info, const b3RigidBodyData* bodies) { b3Transform trA; trA.setIdentity(); @@ -67,143 +56,135 @@ void b3Point2PointConstraint::getInfo2 (b3ConstraintInfo2* info, const b3RigidBo trB.setOrigin(bodies[m_rbB].m_pos); trB.setRotation(bodies[m_rbB].m_quat); - getInfo2NonVirtual(info, trA,trB); + getInfo2NonVirtual(info, trA, trB); } -void b3Point2PointConstraint::getInfo2NonVirtual (b3ConstraintInfo2* info, const b3Transform& body0_trans, const b3Transform& body1_trans) +void b3Point2PointConstraint::getInfo2NonVirtual(b3ConstraintInfo2* info, const b3Transform& body0_trans, const b3Transform& body1_trans) { - - //retrieve matrices + //retrieve matrices // anchor points in global coordinates with respect to body PORs. - - // set jacobian - info->m_J1linearAxis[0] = 1; - info->m_J1linearAxis[info->rowskip+1] = 1; - info->m_J1linearAxis[2*info->rowskip+2] = 1; - b3Vector3 a1 = body0_trans.getBasis()*getPivotInA(); + // set jacobian + info->m_J1linearAxis[0] = 1; + info->m_J1linearAxis[info->rowskip + 1] = 1; + info->m_J1linearAxis[2 * info->rowskip + 2] = 1; + + b3Vector3 a1 = body0_trans.getBasis() * getPivotInA(); //b3Vector3 a1a = b3QuatRotate(body0_trans.getRotation(),getPivotInA()); { b3Vector3* angular0 = (b3Vector3*)(info->m_J1angularAxis); - b3Vector3* angular1 = (b3Vector3*)(info->m_J1angularAxis+info->rowskip); - b3Vector3* angular2 = (b3Vector3*)(info->m_J1angularAxis+2*info->rowskip); + b3Vector3* angular1 = (b3Vector3*)(info->m_J1angularAxis + info->rowskip); + b3Vector3* angular2 = (b3Vector3*)(info->m_J1angularAxis + 2 * info->rowskip); b3Vector3 a1neg = -a1; - a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2); + a1neg.getSkewSymmetricMatrix(angular0, angular1, angular2); } - + if (info->m_J2linearAxis) { info->m_J2linearAxis[0] = -1; - info->m_J2linearAxis[info->rowskip+1] = -1; - info->m_J2linearAxis[2*info->rowskip+2] = -1; + info->m_J2linearAxis[info->rowskip + 1] = -1; + info->m_J2linearAxis[2 * info->rowskip + 2] = -1; } - - b3Vector3 a2 = body1_trans.getBasis()*getPivotInB(); - + + b3Vector3 a2 = body1_trans.getBasis() * getPivotInB(); + { - // b3Vector3 a2n = -a2; + // b3Vector3 a2n = -a2; b3Vector3* angular0 = (b3Vector3*)(info->m_J2angularAxis); - b3Vector3* angular1 = (b3Vector3*)(info->m_J2angularAxis+info->rowskip); - b3Vector3* angular2 = (b3Vector3*)(info->m_J2angularAxis+2*info->rowskip); - a2.getSkewSymmetricMatrix(angular0,angular1,angular2); + b3Vector3* angular1 = (b3Vector3*)(info->m_J2angularAxis + info->rowskip); + b3Vector3* angular2 = (b3Vector3*)(info->m_J2angularAxis + 2 * info->rowskip); + a2.getSkewSymmetricMatrix(angular0, angular1, angular2); } - - - // set right hand side + // set right hand side b3Scalar currERP = (m_flags & B3_P2P_FLAGS_ERP) ? m_erp : info->erp; - b3Scalar k = info->fps * currERP; - int j; - for (j=0; j<3; j++) - { - info->m_constraintError[j*info->rowskip] = k * (a2[j] + body1_trans.getOrigin()[j] - a1[j] - body0_trans.getOrigin()[j]); - //printf("info->m_constraintError[%d]=%f\n",j,info->m_constraintError[j]); - } - if(m_flags & B3_P2P_FLAGS_CFM) + b3Scalar k = info->fps * currERP; + int j; + for (j = 0; j < 3; j++) { - for (j=0; j<3; j++) + info->m_constraintError[j * info->rowskip] = k * (a2[j] + body1_trans.getOrigin()[j] - a1[j] - body0_trans.getOrigin()[j]); + //printf("info->m_constraintError[%d]=%f\n",j,info->m_constraintError[j]); + } + if (m_flags & B3_P2P_FLAGS_CFM) + { + for (j = 0; j < 3; j++) { - info->cfm[j*info->rowskip] = m_cfm; + info->cfm[j * info->rowskip] = m_cfm; } } - b3Scalar impulseClamp = m_setting.m_impulseClamp;// - for (j=0; j<3; j++) - { + b3Scalar impulseClamp = m_setting.m_impulseClamp; // + for (j = 0; j < 3; j++) + { if (m_setting.m_impulseClamp > 0) { - info->m_lowerLimit[j*info->rowskip] = -impulseClamp; - info->m_upperLimit[j*info->rowskip] = impulseClamp; + info->m_lowerLimit[j * info->rowskip] = -impulseClamp; + info->m_upperLimit[j * info->rowskip] = impulseClamp; } } info->m_damping = m_setting.m_damping; - } - - -void b3Point2PointConstraint::updateRHS(b3Scalar timeStep) +void b3Point2PointConstraint::updateRHS(b3Scalar timeStep) { (void)timeStep; - } -///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). +///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). ///If no axis is provided, it uses the default axis for this constraint. void b3Point2PointConstraint::setParam(int num, b3Scalar value, int axis) { - if(axis != -1) + if (axis != -1) { b3AssertConstrParams(0); } else { - switch(num) + switch (num) { - case B3_CONSTRAINT_ERP : - case B3_CONSTRAINT_STOP_ERP : - m_erp = value; + case B3_CONSTRAINT_ERP: + case B3_CONSTRAINT_STOP_ERP: + m_erp = value; m_flags |= B3_P2P_FLAGS_ERP; break; - case B3_CONSTRAINT_CFM : - case B3_CONSTRAINT_STOP_CFM : - m_cfm = value; + case B3_CONSTRAINT_CFM: + case B3_CONSTRAINT_STOP_CFM: + m_cfm = value; m_flags |= B3_P2P_FLAGS_CFM; break; - default: + default: b3AssertConstrParams(0); } } } ///return the local value of parameter -b3Scalar b3Point2PointConstraint::getParam(int num, int axis) const +b3Scalar b3Point2PointConstraint::getParam(int num, int axis) const { b3Scalar retVal(B3_INFINITY); - if(axis != -1) + if (axis != -1) { b3AssertConstrParams(0); } else { - switch(num) + switch (num) { - case B3_CONSTRAINT_ERP : - case B3_CONSTRAINT_STOP_ERP : + case B3_CONSTRAINT_ERP: + case B3_CONSTRAINT_STOP_ERP: b3AssertConstrParams(m_flags & B3_P2P_FLAGS_ERP); - retVal = m_erp; + retVal = m_erp; break; - case B3_CONSTRAINT_CFM : - case B3_CONSTRAINT_STOP_CFM : + case B3_CONSTRAINT_CFM: + case B3_CONSTRAINT_STOP_CFM: b3AssertConstrParams(m_flags & B3_P2P_FLAGS_CFM); - retVal = m_cfm; + retVal = m_cfm; break; - default: + default: b3AssertConstrParams(0); } } return retVal; } - diff --git a/src/Bullet3Dynamics/ConstraintSolver/b3Point2PointConstraint.h b/src/Bullet3Dynamics/ConstraintSolver/b3Point2PointConstraint.h index 681b48733..14762a3e3 100644 --- a/src/Bullet3Dynamics/ConstraintSolver/b3Point2PointConstraint.h +++ b/src/Bullet3Dynamics/ConstraintSolver/b3Point2PointConstraint.h @@ -22,26 +22,24 @@ subject to the following restrictions: class b3RigidBody; - #ifdef B3_USE_DOUBLE_PRECISION -#define b3Point2PointConstraintData b3Point2PointConstraintDoubleData -#define b3Point2PointConstraintDataName "b3Point2PointConstraintDoubleData" +#define b3Point2PointConstraintData b3Point2PointConstraintDoubleData +#define b3Point2PointConstraintDataName "b3Point2PointConstraintDoubleData" #else -#define b3Point2PointConstraintData b3Point2PointConstraintFloatData -#define b3Point2PointConstraintDataName "b3Point2PointConstraintFloatData" -#endif //B3_USE_DOUBLE_PRECISION +#define b3Point2PointConstraintData b3Point2PointConstraintFloatData +#define b3Point2PointConstraintDataName "b3Point2PointConstraintFloatData" +#endif //B3_USE_DOUBLE_PRECISION -struct b3ConstraintSetting +struct b3ConstraintSetting { - b3ConstraintSetting() : - m_tau(b3Scalar(0.3)), - m_damping(b3Scalar(1.)), - m_impulseClamp(b3Scalar(0.)) + b3ConstraintSetting() : m_tau(b3Scalar(0.3)), + m_damping(b3Scalar(1.)), + m_impulseClamp(b3Scalar(0.)) { } - b3Scalar m_tau; - b3Scalar m_damping; - b3Scalar m_impulseClamp; + b3Scalar m_tau; + b3Scalar m_damping; + b3Scalar m_impulseClamp; }; enum b3Point2PointFlags @@ -51,47 +49,45 @@ enum b3Point2PointFlags }; /// point to point constraint between two rigidbodies each with a pivotpoint that descibes the 'ballsocket' location in local space -B3_ATTRIBUTE_ALIGNED16(class) b3Point2PointConstraint : public b3TypedConstraint +B3_ATTRIBUTE_ALIGNED16(class) +b3Point2PointConstraint : public b3TypedConstraint { #ifdef IN_PARALLELL_SOLVER public: #endif - - b3Vector3 m_pivotInA; - b3Vector3 m_pivotInB; - - int m_flags; - b3Scalar m_erp; - b3Scalar m_cfm; - -public: + b3Vector3 m_pivotInA; + b3Vector3 m_pivotInB; + + int m_flags; + b3Scalar m_erp; + b3Scalar m_cfm; + +public: B3_DECLARE_ALIGNED_ALLOCATOR(); - b3ConstraintSetting m_setting; + b3ConstraintSetting m_setting; - b3Point2PointConstraint(int rbA,int rbB, const b3Vector3& pivotInA,const b3Vector3& pivotInB); + b3Point2PointConstraint(int rbA, int rbB, const b3Vector3& pivotInA, const b3Vector3& pivotInB); //b3Point2PointConstraint(int rbA,const b3Vector3& pivotInA); + virtual void getInfo1(b3ConstraintInfo1 * info, const b3RigidBodyData* bodies); + void getInfo1NonVirtual(b3ConstraintInfo1 * info, const b3RigidBodyData* bodies); - virtual void getInfo1 (b3ConstraintInfo1* info,const b3RigidBodyData* bodies); + virtual void getInfo2(b3ConstraintInfo2 * info, const b3RigidBodyData* bodies); - void getInfo1NonVirtual (b3ConstraintInfo1* info,const b3RigidBodyData* bodies); + void getInfo2NonVirtual(b3ConstraintInfo2 * info, const b3Transform& body0_trans, const b3Transform& body1_trans); - virtual void getInfo2 (b3ConstraintInfo2* info, const b3RigidBodyData* bodies); + void updateRHS(b3Scalar timeStep); - void getInfo2NonVirtual (b3ConstraintInfo2* info, const b3Transform& body0_trans, const b3Transform& body1_trans); - - void updateRHS(b3Scalar timeStep); - - void setPivotA(const b3Vector3& pivotA) + void setPivotA(const b3Vector3& pivotA) { m_pivotInA = pivotA; } - void setPivotB(const b3Vector3& pivotB) + void setPivotB(const b3Vector3& pivotB) { m_pivotInB = pivotB; } @@ -106,34 +102,32 @@ public: return m_pivotInB; } - ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). + ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). ///If no axis is provided, it uses the default axis for this constraint. - virtual void setParam(int num, b3Scalar value, int axis = -1); + virtual void setParam(int num, b3Scalar value, int axis = -1); ///return the local value of parameter - virtual b3Scalar getParam(int num, int axis = -1) const; + virtual b3Scalar getParam(int num, int axis = -1) const; -// virtual int calculateSerializeBufferSize() const; + // virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) -// virtual const char* serialize(void* dataBuffer, b3Serializer* serializer) const; - - + // virtual const char* serialize(void* dataBuffer, b3Serializer* serializer) const; }; ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 -struct b3Point2PointConstraintFloatData +struct b3Point2PointConstraintFloatData { - b3TypedConstraintData m_typeConstraintData; - b3Vector3FloatData m_pivotInA; - b3Vector3FloatData m_pivotInB; + b3TypedConstraintData m_typeConstraintData; + b3Vector3FloatData m_pivotInA; + b3Vector3FloatData m_pivotInB; }; ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 -struct b3Point2PointConstraintDoubleData +struct b3Point2PointConstraintDoubleData { - b3TypedConstraintData m_typeConstraintData; - b3Vector3DoubleData m_pivotInA; - b3Vector3DoubleData m_pivotInB; + b3TypedConstraintData m_typeConstraintData; + b3Vector3DoubleData m_pivotInA; + b3Vector3DoubleData m_pivotInB; }; /* @@ -156,4 +150,4 @@ B3_FORCE_INLINE const char* b3Point2PointConstraint::serialize(void* dataBuffer, } */ -#endif //B3_POINT2POINTCONSTRAINT_H +#endif //B3_POINT2POINTCONSTRAINT_H diff --git a/src/Bullet3Dynamics/ConstraintSolver/b3SolverBody.h b/src/Bullet3Dynamics/ConstraintSolver/b3SolverBody.h index 0049317d9..196d0e579 100644 --- a/src/Bullet3Dynamics/ConstraintSolver/b3SolverBody.h +++ b/src/Bullet3Dynamics/ConstraintSolver/b3SolverBody.h @@ -16,7 +16,6 @@ subject to the following restrictions: #ifndef B3_SOLVER_BODY_H #define B3_SOLVER_BODY_H - #include "Bullet3Common/b3Vector3.h" #include "Bullet3Common/b3Matrix3x3.h" @@ -26,110 +25,104 @@ subject to the following restrictions: ///Until we get other contributions, only use SIMD on Windows, when using Visual Studio 2008 or later, and not double precision #ifdef B3_USE_SSE #define USE_SIMD 1 -#endif // - +#endif // #ifdef USE_SIMD -struct b3SimdScalar +struct b3SimdScalar { - B3_FORCE_INLINE b3SimdScalar() - { - - } - - B3_FORCE_INLINE b3SimdScalar(float fl) - :m_vec128 (_mm_set1_ps(fl)) + B3_FORCE_INLINE b3SimdScalar() { } - B3_FORCE_INLINE b3SimdScalar(__m128 v128) - :m_vec128(v128) + B3_FORCE_INLINE b3SimdScalar(float fl) + : m_vec128(_mm_set1_ps(fl)) { } - union + + B3_FORCE_INLINE b3SimdScalar(__m128 v128) + : m_vec128(v128) { - __m128 m_vec128; - float m_floats[4]; - float x,y,z,w; - int m_ints[4]; - b3Scalar m_unusedPadding; + } + union { + __m128 m_vec128; + float m_floats[4]; + float x, y, z, w; + int m_ints[4]; + b3Scalar m_unusedPadding; }; - B3_FORCE_INLINE __m128 get128() + B3_FORCE_INLINE __m128 get128() { return m_vec128; } - B3_FORCE_INLINE const __m128 get128() const + B3_FORCE_INLINE const __m128 get128() const { return m_vec128; } - B3_FORCE_INLINE void set128(__m128 v128) + B3_FORCE_INLINE void set128(__m128 v128) { m_vec128 = v128; } - B3_FORCE_INLINE operator __m128() - { - return m_vec128; + B3_FORCE_INLINE operator __m128() + { + return m_vec128; } - B3_FORCE_INLINE operator const __m128() const - { - return m_vec128; - } - - B3_FORCE_INLINE operator float() const - { - return m_floats[0]; + B3_FORCE_INLINE operator const __m128() const + { + return m_vec128; } + B3_FORCE_INLINE operator float() const + { + return m_floats[0]; + } }; ///@brief Return the elementwise product of two b3SimdScalar -B3_FORCE_INLINE b3SimdScalar -operator*(const b3SimdScalar& v1, const b3SimdScalar& v2) +B3_FORCE_INLINE b3SimdScalar +operator*(const b3SimdScalar& v1, const b3SimdScalar& v2) { - return b3SimdScalar(_mm_mul_ps(v1.get128(),v2.get128())); + return b3SimdScalar(_mm_mul_ps(v1.get128(), v2.get128())); } ///@brief Return the elementwise product of two b3SimdScalar -B3_FORCE_INLINE b3SimdScalar -operator+(const b3SimdScalar& v1, const b3SimdScalar& v2) +B3_FORCE_INLINE b3SimdScalar +operator+(const b3SimdScalar& v1, const b3SimdScalar& v2) { - return b3SimdScalar(_mm_add_ps(v1.get128(),v2.get128())); + return b3SimdScalar(_mm_add_ps(v1.get128(), v2.get128())); } - #else #define b3SimdScalar b3Scalar #endif ///The b3SolverBody is an internal datastructure for the constraint solver. Only necessary data is packed to increase cache coherence/performance. -B3_ATTRIBUTE_ALIGNED16 (struct) b3SolverBody +B3_ATTRIBUTE_ALIGNED16(struct) +b3SolverBody { B3_DECLARE_ALIGNED_ALLOCATOR(); - b3Transform m_worldTransform; - b3Vector3 m_deltaLinearVelocity; - b3Vector3 m_deltaAngularVelocity; - b3Vector3 m_angularFactor; - b3Vector3 m_linearFactor; - b3Vector3 m_invMass; - b3Vector3 m_pushVelocity; - b3Vector3 m_turnVelocity; - b3Vector3 m_linearVelocity; - b3Vector3 m_angularVelocity; + b3Transform m_worldTransform; + b3Vector3 m_deltaLinearVelocity; + b3Vector3 m_deltaAngularVelocity; + b3Vector3 m_angularFactor; + b3Vector3 m_linearFactor; + b3Vector3 m_invMass; + b3Vector3 m_pushVelocity; + b3Vector3 m_turnVelocity; + b3Vector3 m_linearVelocity; + b3Vector3 m_angularVelocity; - union - { - void* m_originalBody; - int m_originalBodyIndex; + union { + void* m_originalBody; + int m_originalBodyIndex; }; int padding[3]; - - void setWorldTransform(const b3Transform& worldTransform) + void setWorldTransform(const b3Transform& worldTransform) { m_worldTransform = worldTransform; } @@ -138,45 +131,42 @@ B3_ATTRIBUTE_ALIGNED16 (struct) b3SolverBody { return m_worldTransform; } - - B3_FORCE_INLINE void getVelocityInLocalPointObsolete(const b3Vector3& rel_pos, b3Vector3& velocity ) const + + B3_FORCE_INLINE void getVelocityInLocalPointObsolete(const b3Vector3& rel_pos, b3Vector3& velocity) const { if (m_originalBody) - velocity = m_linearVelocity+m_deltaLinearVelocity + (m_angularVelocity+m_deltaAngularVelocity).cross(rel_pos); + velocity = m_linearVelocity + m_deltaLinearVelocity + (m_angularVelocity + m_deltaAngularVelocity).cross(rel_pos); else - velocity.setValue(0,0,0); + velocity.setValue(0, 0, 0); } - B3_FORCE_INLINE void getAngularVelocity(b3Vector3& angVel) const + B3_FORCE_INLINE void getAngularVelocity(b3Vector3 & angVel) const { if (m_originalBody) - angVel =m_angularVelocity+m_deltaAngularVelocity; + angVel = m_angularVelocity + m_deltaAngularVelocity; else - angVel.setValue(0,0,0); + angVel.setValue(0, 0, 0); } - //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position - B3_FORCE_INLINE void applyImpulse(const b3Vector3& linearComponent, const b3Vector3& angularComponent,const b3Scalar impulseMagnitude) + B3_FORCE_INLINE void applyImpulse(const b3Vector3& linearComponent, const b3Vector3& angularComponent, const b3Scalar impulseMagnitude) { if (m_originalBody) { - m_deltaLinearVelocity += linearComponent*impulseMagnitude*m_linearFactor; - m_deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor); + m_deltaLinearVelocity += linearComponent * impulseMagnitude * m_linearFactor; + m_deltaAngularVelocity += angularComponent * (impulseMagnitude * m_angularFactor); } } - B3_FORCE_INLINE void internalApplyPushImpulse(const b3Vector3& linearComponent, const b3Vector3& angularComponent,b3Scalar impulseMagnitude) + B3_FORCE_INLINE void internalApplyPushImpulse(const b3Vector3& linearComponent, const b3Vector3& angularComponent, b3Scalar impulseMagnitude) { if (m_originalBody) { - m_pushVelocity += linearComponent*impulseMagnitude*m_linearFactor; - m_turnVelocity += angularComponent*(impulseMagnitude*m_angularFactor); + m_pushVelocity += linearComponent * impulseMagnitude * m_linearFactor; + m_turnVelocity += angularComponent * (impulseMagnitude * m_angularFactor); } } - - const b3Vector3& getDeltaLinearVelocity() const { return m_deltaLinearVelocity; @@ -187,20 +177,19 @@ B3_ATTRIBUTE_ALIGNED16 (struct) b3SolverBody return m_deltaAngularVelocity; } - const b3Vector3& getPushVelocity() const + const b3Vector3& getPushVelocity() const { return m_pushVelocity; } - const b3Vector3& getTurnVelocity() const + const b3Vector3& getTurnVelocity() const { return m_turnVelocity; } - //////////////////////////////////////////////// ///some internal methods, don't use them - + b3Vector3& internalGetDeltaLinearVelocity() { return m_deltaLinearVelocity; @@ -225,7 +214,7 @@ B3_ATTRIBUTE_ALIGNED16 (struct) b3SolverBody { m_invMass = invMass; } - + b3Vector3& internalGetPushVelocity() { return m_pushVelocity; @@ -236,67 +225,57 @@ B3_ATTRIBUTE_ALIGNED16 (struct) b3SolverBody return m_turnVelocity; } - B3_FORCE_INLINE void internalGetVelocityInLocalPointObsolete(const b3Vector3& rel_pos, b3Vector3& velocity ) const + B3_FORCE_INLINE void internalGetVelocityInLocalPointObsolete(const b3Vector3& rel_pos, b3Vector3& velocity) const { - velocity = m_linearVelocity+m_deltaLinearVelocity + (m_angularVelocity+m_deltaAngularVelocity).cross(rel_pos); + velocity = m_linearVelocity + m_deltaLinearVelocity + (m_angularVelocity + m_deltaAngularVelocity).cross(rel_pos); } - B3_FORCE_INLINE void internalGetAngularVelocity(b3Vector3& angVel) const + B3_FORCE_INLINE void internalGetAngularVelocity(b3Vector3 & angVel) const { - angVel = m_angularVelocity+m_deltaAngularVelocity; + angVel = m_angularVelocity + m_deltaAngularVelocity; } - //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position - B3_FORCE_INLINE void internalApplyImpulse(const b3Vector3& linearComponent, const b3Vector3& angularComponent,const b3Scalar impulseMagnitude) + B3_FORCE_INLINE void internalApplyImpulse(const b3Vector3& linearComponent, const b3Vector3& angularComponent, const b3Scalar impulseMagnitude) { //if (m_originalBody) { - m_deltaLinearVelocity += linearComponent*impulseMagnitude*m_linearFactor; - m_deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor); + m_deltaLinearVelocity += linearComponent * impulseMagnitude * m_linearFactor; + m_deltaAngularVelocity += angularComponent * (impulseMagnitude * m_angularFactor); } } - - - - void writebackVelocity() + void writebackVelocity() { //if (m_originalBody>=0) { - m_linearVelocity +=m_deltaLinearVelocity; + m_linearVelocity += m_deltaLinearVelocity; m_angularVelocity += m_deltaAngularVelocity; - + //m_originalBody->setCompanionId(-1); } } - - void writebackVelocityAndTransform(b3Scalar timeStep, b3Scalar splitImpulseTurnErp) + void writebackVelocityAndTransform(b3Scalar timeStep, b3Scalar splitImpulseTurnErp) { - (void) timeStep; + (void)timeStep; if (m_originalBody) { m_linearVelocity += m_deltaLinearVelocity; m_angularVelocity += m_deltaAngularVelocity; - + //correct the position/orientation based on push/turn recovery b3Transform newTransform; - if (m_pushVelocity[0]!=0.f || m_pushVelocity[1]!=0 || m_pushVelocity[2]!=0 || m_turnVelocity[0]!=0.f || m_turnVelocity[1]!=0 || m_turnVelocity[2]!=0) + if (m_pushVelocity[0] != 0.f || m_pushVelocity[1] != 0 || m_pushVelocity[2] != 0 || m_turnVelocity[0] != 0.f || m_turnVelocity[1] != 0 || m_turnVelocity[2] != 0) { - // b3Quaternion orn = m_worldTransform.getRotation(); - b3TransformUtil::integrateTransform(m_worldTransform,m_pushVelocity,m_turnVelocity*splitImpulseTurnErp,timeStep,newTransform); + // b3Quaternion orn = m_worldTransform.getRotation(); + b3TransformUtil::integrateTransform(m_worldTransform, m_pushVelocity, m_turnVelocity * splitImpulseTurnErp, timeStep, newTransform); m_worldTransform = newTransform; } //m_worldTransform.setRotation(orn); //m_originalBody->setCompanionId(-1); } } - - - }; -#endif //B3_SOLVER_BODY_H - - +#endif //B3_SOLVER_BODY_H diff --git a/src/Bullet3Dynamics/ConstraintSolver/b3SolverConstraint.h b/src/Bullet3Dynamics/ConstraintSolver/b3SolverConstraint.h index bce83d460..4927ae428 100644 --- a/src/Bullet3Dynamics/ConstraintSolver/b3SolverConstraint.h +++ b/src/Bullet3Dynamics/ConstraintSolver/b3SolverConstraint.h @@ -16,7 +16,6 @@ subject to the following restrictions: #ifndef B3_SOLVER_CONSTRAINT_H #define B3_SOLVER_CONSTRAINT_H - #include "Bullet3Common/b3Vector3.h" #include "Bullet3Common/b3Matrix3x3.h" //#include "b3JacobianEntry.h" @@ -25,56 +24,50 @@ subject to the following restrictions: //#define NO_FRICTION_TANGENTIALS 1 #include "b3SolverBody.h" - ///1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and friction constraints. -B3_ATTRIBUTE_ALIGNED16 (struct) b3SolverConstraint +B3_ATTRIBUTE_ALIGNED16(struct) +b3SolverConstraint { B3_DECLARE_ALIGNED_ALLOCATOR(); - b3Vector3 m_relpos1CrossNormal; - b3Vector3 m_contactNormal; + b3Vector3 m_relpos1CrossNormal; + b3Vector3 m_contactNormal; - b3Vector3 m_relpos2CrossNormal; + b3Vector3 m_relpos2CrossNormal; //b3Vector3 m_contactNormal2;//usually m_contactNormal2 == -m_contactNormal - b3Vector3 m_angularComponentA; - b3Vector3 m_angularComponentB; - - mutable b3SimdScalar m_appliedPushImpulse; - mutable b3SimdScalar m_appliedImpulse; + b3Vector3 m_angularComponentA; + b3Vector3 m_angularComponentB; + + mutable b3SimdScalar m_appliedPushImpulse; + mutable b3SimdScalar m_appliedImpulse; int m_padding1; int m_padding2; - b3Scalar m_friction; - b3Scalar m_jacDiagABInv; - b3Scalar m_rhs; - b3Scalar m_cfm; - - b3Scalar m_lowerLimit; - b3Scalar m_upperLimit; - b3Scalar m_rhsPenetration; - union - { - void* m_originalContactPoint; - b3Scalar m_unusedPadding4; + b3Scalar m_friction; + b3Scalar m_jacDiagABInv; + b3Scalar m_rhs; + b3Scalar m_cfm; + + b3Scalar m_lowerLimit; + b3Scalar m_upperLimit; + b3Scalar m_rhsPenetration; + union { + void* m_originalContactPoint; + b3Scalar m_unusedPadding4; }; - int m_overrideNumSolverIterations; - int m_frictionIndex; + int m_overrideNumSolverIterations; + int m_frictionIndex; int m_solverBodyIdA; int m_solverBodyIdB; - - enum b3SolverConstraintType + enum b3SolverConstraintType { B3_SOLVER_CONTACT_1D = 0, B3_SOLVER_FRICTION_1D }; }; -typedef b3AlignedObjectArray b3ConstraintArray; - - -#endif //B3_SOLVER_CONSTRAINT_H - - +typedef b3AlignedObjectArray b3ConstraintArray; +#endif //B3_SOLVER_CONSTRAINT_H diff --git a/src/Bullet3Dynamics/ConstraintSolver/b3TypedConstraint.cpp b/src/Bullet3Dynamics/ConstraintSolver/b3TypedConstraint.cpp index 699c481d6..885e277d8 100644 --- a/src/Bullet3Dynamics/ConstraintSolver/b3TypedConstraint.cpp +++ b/src/Bullet3Dynamics/ConstraintSolver/b3TypedConstraint.cpp @@ -13,53 +13,46 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "b3TypedConstraint.h" //#include "Bullet3Common/b3Serializer.h" - #define B3_DEFAULT_DEBUGDRAW_SIZE b3Scalar(0.3f) - - -b3TypedConstraint::b3TypedConstraint(b3TypedConstraintType type, int rbA,int rbB) -:b3TypedObject(type), -m_userConstraintType(-1), -m_userConstraintPtr((void*)-1), -m_breakingImpulseThreshold(B3_INFINITY), -m_isEnabled(true), -m_needsFeedback(false), -m_overrideNumSolverIterations(-1), -m_rbA(rbA), -m_rbB(rbB), -m_appliedImpulse(b3Scalar(0.)), -m_dbgDrawSize(B3_DEFAULT_DEBUGDRAW_SIZE), -m_jointFeedback(0) +b3TypedConstraint::b3TypedConstraint(b3TypedConstraintType type, int rbA, int rbB) + : b3TypedObject(type), + m_userConstraintType(-1), + m_userConstraintPtr((void*)-1), + m_breakingImpulseThreshold(B3_INFINITY), + m_isEnabled(true), + m_needsFeedback(false), + m_overrideNumSolverIterations(-1), + m_rbA(rbA), + m_rbB(rbB), + m_appliedImpulse(b3Scalar(0.)), + m_dbgDrawSize(B3_DEFAULT_DEBUGDRAW_SIZE), + m_jointFeedback(0) { } - - - b3Scalar b3TypedConstraint::getMotorFactor(b3Scalar pos, b3Scalar lowLim, b3Scalar uppLim, b3Scalar vel, b3Scalar timeFact) { - if(lowLim > uppLim) + if (lowLim > uppLim) { return b3Scalar(1.0f); } - else if(lowLim == uppLim) + else if (lowLim == uppLim) { return b3Scalar(0.0f); } b3Scalar lim_fact = b3Scalar(1.0f); b3Scalar delta_max = vel / timeFact; - if(delta_max < b3Scalar(0.0f)) + if (delta_max < b3Scalar(0.0f)) { - if((pos >= lowLim) && (pos < (lowLim - delta_max))) + if ((pos >= lowLim) && (pos < (lowLim - delta_max))) { lim_fact = (lowLim - pos) / delta_max; } - else if(pos < lowLim) + else if (pos < lowLim) { lim_fact = b3Scalar(0.0f); } @@ -68,13 +61,13 @@ b3Scalar b3TypedConstraint::getMotorFactor(b3Scalar pos, b3Scalar lowLim, b3Scal lim_fact = b3Scalar(1.0f); } } - else if(delta_max > b3Scalar(0.0f)) + else if (delta_max > b3Scalar(0.0f)) { - if((pos <= uppLim) && (pos > (uppLim - delta_max))) + if ((pos <= uppLim) && (pos > (uppLim - delta_max))) { lim_fact = (uppLim - pos) / delta_max; } - else if(pos > uppLim) + else if (pos > uppLim) { lim_fact = b3Scalar(0.0f); } @@ -85,18 +78,16 @@ b3Scalar b3TypedConstraint::getMotorFactor(b3Scalar pos, b3Scalar lowLim, b3Scal } else { - lim_fact = b3Scalar(0.0f); + lim_fact = b3Scalar(0.0f); } return lim_fact; } - - void b3AngularLimit::set(b3Scalar low, b3Scalar high, b3Scalar _softness, b3Scalar _biasFactor, b3Scalar _relaxationFactor) { m_halfRange = (high - low) / 2.0f; m_center = b3NormalizeAngle(low + m_halfRange); - m_softness = _softness; + m_softness = _softness; m_biasFactor = _biasFactor; m_relaxationFactor = _relaxationFactor; } @@ -113,7 +104,7 @@ void b3AngularLimit::test(const b3Scalar angle) if (deviation < -m_halfRange) { m_solveLimit = true; - m_correction = - (deviation + m_halfRange); + m_correction = -(deviation + m_halfRange); m_sign = +1.0f; } else if (deviation > m_halfRange) @@ -125,7 +116,6 @@ void b3AngularLimit::test(const b3Scalar angle) } } - b3Scalar b3AngularLimit::getError() const { return m_correction * m_sign; diff --git a/src/Bullet3Dynamics/ConstraintSolver/b3TypedConstraint.h b/src/Bullet3Dynamics/ConstraintSolver/b3TypedConstraint.h index cf9cec0d5..f74aec4d3 100644 --- a/src/Bullet3Dynamics/ConstraintSolver/b3TypedConstraint.h +++ b/src/Bullet3Dynamics/ConstraintSolver/b3TypedConstraint.h @@ -16,7 +16,6 @@ subject to the following restrictions: #ifndef B3_TYPED_CONSTRAINT_H #define B3_TYPED_CONSTRAINT_H - #include "Bullet3Common/b3Scalar.h" #include "b3SolverConstraint.h" @@ -25,7 +24,7 @@ class b3Serializer; //Don't change any of the existing enum values, so add enum types at the end for serialization compatibility enum b3TypedConstraintType { - B3_POINT2POINT_CONSTRAINT_TYPE=3, + B3_POINT2POINT_CONSTRAINT_TYPE = 3, B3_HINGE_CONSTRAINT_TYPE, B3_CONETWIST_CONSTRAINT_TYPE, B3_D6_CONSTRAINT_TYPE, @@ -37,92 +36,86 @@ enum b3TypedConstraintType B3_MAX_CONSTRAINT_TYPE }; - enum b3ConstraintParams { - B3_CONSTRAINT_ERP=1, + B3_CONSTRAINT_ERP = 1, B3_CONSTRAINT_STOP_ERP, B3_CONSTRAINT_CFM, B3_CONSTRAINT_STOP_CFM }; #if 1 - #define b3AssertConstrParams(_par) b3Assert(_par) +#define b3AssertConstrParams(_par) b3Assert(_par) #else - #define b3AssertConstrParams(_par) +#define b3AssertConstrParams(_par) #endif - -B3_ATTRIBUTE_ALIGNED16(struct) b3JointFeedback +B3_ATTRIBUTE_ALIGNED16(struct) +b3JointFeedback { - b3Vector3 m_appliedForceBodyA; - b3Vector3 m_appliedTorqueBodyA; - b3Vector3 m_appliedForceBodyB; - b3Vector3 m_appliedTorqueBodyB; + b3Vector3 m_appliedForceBodyA; + b3Vector3 m_appliedTorqueBodyA; + b3Vector3 m_appliedForceBodyB; + b3Vector3 m_appliedTorqueBodyB; }; - struct b3RigidBodyData; - ///TypedConstraint is the baseclass for Bullet constraints and vehicles -B3_ATTRIBUTE_ALIGNED16(class) b3TypedConstraint : public b3TypedObject +B3_ATTRIBUTE_ALIGNED16(class) +b3TypedConstraint : public b3TypedObject { - int m_userConstraintType; + int m_userConstraintType; - union - { - int m_userConstraintId; + union { + int m_userConstraintId; void* m_userConstraintPtr; }; - b3Scalar m_breakingImpulseThreshold; - bool m_isEnabled; - bool m_needsFeedback; - int m_overrideNumSolverIterations; + b3Scalar m_breakingImpulseThreshold; + bool m_isEnabled; + bool m_needsFeedback; + int m_overrideNumSolverIterations; - - b3TypedConstraint& operator=(b3TypedConstraint& other) + b3TypedConstraint& operator=(b3TypedConstraint& other) { b3Assert(0); - (void) other; + (void)other; return *this; } protected: - int m_rbA; - int m_rbB; - b3Scalar m_appliedImpulse; - b3Scalar m_dbgDrawSize; - b3JointFeedback* m_jointFeedback; + int m_rbA; + int m_rbB; + b3Scalar m_appliedImpulse; + b3Scalar m_dbgDrawSize; + b3JointFeedback* m_jointFeedback; ///internal method used by the constraint solver, don't use them directly b3Scalar getMotorFactor(b3Scalar pos, b3Scalar lowLim, b3Scalar uppLim, b3Scalar vel, b3Scalar timeFact); - public: - B3_DECLARE_ALIGNED_ALLOCATOR(); - virtual ~b3TypedConstraint() {}; - b3TypedConstraint(b3TypedConstraintType type, int bodyA,int bodyB); + virtual ~b3TypedConstraint(){}; + b3TypedConstraint(b3TypedConstraintType type, int bodyA, int bodyB); - struct b3ConstraintInfo1 { - int m_numConstraintRows,nub; + struct b3ConstraintInfo1 + { + int m_numConstraintRows, nub; }; - - - struct b3ConstraintInfo2 { + struct b3ConstraintInfo2 + { // integrator parameters: frames per second (1/stepsize), default error // reduction parameter (0..1). - b3Scalar fps,erp; + b3Scalar fps, erp; // for the first and second body, pointers to two (linear and angular) // n*3 jacobian sub matrices, stored by rows. these matrices will have // been initialized to 0 on entry. if the second body is zero then the // J2xx pointers may be 0. - b3Scalar *m_J1linearAxis,*m_J1angularAxis,*m_J2linearAxis,*m_J2angularAxis; + b3Scalar *m_J1linearAxis, *m_J1angularAxis, *m_J2linearAxis, *m_J2angularAxis; // elements to jump from one row to the next in J's int rowskip; @@ -130,24 +123,24 @@ public: // right hand sides of the equation J*v = c + cfm * lambda. cfm is the // "constraint force mixing" vector. c is set to zero on entry, cfm is // set to a constant value (typically very small or zero) value on entry. - b3Scalar *m_constraintError,*cfm; + b3Scalar *m_constraintError, *cfm; // lo and hi limits for variables (set to -/+ infinity on entry). - b3Scalar *m_lowerLimit,*m_upperLimit; + b3Scalar *m_lowerLimit, *m_upperLimit; // findex vector for variables. see the LCP solver interface for a // description of what this does. this is set to -1 on entry. // note that the returned indexes are relative to the first index of // the constraint. - int *findex; + int* findex; // number of solver iterations int m_numIterations; //damping of the velocity - b3Scalar m_damping; + b3Scalar m_damping; }; - int getOverrideNumSolverIterations() const + int getOverrideNumSolverIterations() const { return m_overrideNumSolverIterations; } @@ -159,59 +152,55 @@ public: m_overrideNumSolverIterations = overideNumIterations; } - ///internal method used by the constraint solver, don't use them directly - virtual void setupSolverConstraint(b3ConstraintArray& ca, int solverBodyA,int solverBodyB, b3Scalar timeStep) + virtual void setupSolverConstraint(b3ConstraintArray & ca, int solverBodyA, int solverBodyB, b3Scalar timeStep) { - (void)ca; - (void)solverBodyA; - (void)solverBodyB; - (void)timeStep; + (void)ca; + (void)solverBodyA; + (void)solverBodyB; + (void)timeStep; } - - ///internal method used by the constraint solver, don't use them directly - virtual void getInfo1 (b3ConstraintInfo1* info,const b3RigidBodyData* bodies)=0; ///internal method used by the constraint solver, don't use them directly - virtual void getInfo2 (b3ConstraintInfo2* info, const b3RigidBodyData* bodies)=0; + virtual void getInfo1(b3ConstraintInfo1 * info, const b3RigidBodyData* bodies) = 0; ///internal method used by the constraint solver, don't use them directly - void internalSetAppliedImpulse(b3Scalar appliedImpulse) + virtual void getInfo2(b3ConstraintInfo2 * info, const b3RigidBodyData* bodies) = 0; + + ///internal method used by the constraint solver, don't use them directly + void internalSetAppliedImpulse(b3Scalar appliedImpulse) { m_appliedImpulse = appliedImpulse; } ///internal method used by the constraint solver, don't use them directly - b3Scalar internalGetAppliedImpulse() + b3Scalar internalGetAppliedImpulse() { return m_appliedImpulse; } - - b3Scalar getBreakingImpulseThreshold() const + b3Scalar getBreakingImpulseThreshold() const { - return m_breakingImpulseThreshold; + return m_breakingImpulseThreshold; } - void setBreakingImpulseThreshold(b3Scalar threshold) + void setBreakingImpulseThreshold(b3Scalar threshold) { m_breakingImpulseThreshold = threshold; } - bool isEnabled() const + bool isEnabled() const { return m_isEnabled; } - void setEnabled(bool enabled) + void setEnabled(bool enabled) { - m_isEnabled=enabled; + m_isEnabled = enabled; } - ///internal method used by the constraint solver, don't use them directly - virtual void solveConstraintObsolete(b3SolverBody& /*bodyA*/,b3SolverBody& /*bodyB*/,b3Scalar /*timeStep*/) {}; + virtual void solveConstraintObsolete(b3SolverBody& /*bodyA*/, b3SolverBody& /*bodyB*/, b3Scalar /*timeStep*/){}; - int getRigidBodyA() const { return m_rbA; @@ -221,8 +210,7 @@ public: return m_rbB; } - - int getRigidBodyA() + int getRigidBodyA() { return m_rbA; } @@ -233,15 +221,15 @@ public: int getUserConstraintType() const { - return m_userConstraintType ; + return m_userConstraintType; } - void setUserConstraintType(int userConstraintType) + void setUserConstraintType(int userConstraintType) { m_userConstraintType = userConstraintType; }; - void setUserConstraintId(int uid) + void setUserConstraintId(int uid) { m_userConstraintId = uid; } @@ -251,17 +239,17 @@ public: return m_userConstraintId; } - void setUserConstraintPtr(void* ptr) + void setUserConstraintPtr(void* ptr) { m_userConstraintPtr = ptr; } - void* getUserConstraintPtr() + void* getUserConstraintPtr() { return m_userConstraintPtr; } - void setJointFeedback(b3JointFeedback* jointFeedback) + void setJointFeedback(b3JointFeedback * jointFeedback) { m_jointFeedback = jointFeedback; } @@ -276,37 +264,36 @@ public: return m_jointFeedback; } - int getUid() const { - return m_userConstraintId; - } + return m_userConstraintId; + } - bool needsFeedback() const + bool needsFeedback() const { return m_needsFeedback; } ///enableFeedback will allow to read the applied linear and angular impulse ///use getAppliedImpulse, getAppliedLinearImpulse and getAppliedAngularImpulse to read feedback information - void enableFeedback(bool needsFeedback) + void enableFeedback(bool needsFeedback) { m_needsFeedback = needsFeedback; } - ///getAppliedImpulse is an estimated total applied impulse. + ///getAppliedImpulse is an estimated total applied impulse. ///This feedback could be used to determine breaking constraints or playing sounds. - b3Scalar getAppliedImpulse() const + b3Scalar getAppliedImpulse() const { b3Assert(m_needsFeedback); return m_appliedImpulse; } - b3TypedConstraintType getConstraintType () const + b3TypedConstraintType getConstraintType() const { return b3TypedConstraintType(m_objectType); } - + void setDbgDrawSize(b3Scalar dbgDrawSize) { m_dbgDrawSize = dbgDrawSize; @@ -316,35 +303,34 @@ public: return m_dbgDrawSize; } - ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). + ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). ///If no axis is provided, it uses the default axis for this constraint. - virtual void setParam(int num, b3Scalar value, int axis = -1) = 0; + virtual void setParam(int num, b3Scalar value, int axis = -1) = 0; ///return the local value of parameter - virtual b3Scalar getParam(int num, int axis = -1) const = 0; - -// virtual int calculateSerializeBufferSize() const; + virtual b3Scalar getParam(int num, int axis = -1) const = 0; + + // virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) //virtual const char* serialize(void* dataBuffer, b3Serializer* serializer) const; - }; -// returns angle in range [-B3_2_PI, B3_2_PI], closest to one of the limits +// returns angle in range [-B3_2_PI, B3_2_PI], closest to one of the limits // all arguments should be normalized angles (i.e. in range [-B3_PI, B3_PI]) B3_FORCE_INLINE b3Scalar b3AdjustAngleToLimits(b3Scalar angleInRadians, b3Scalar angleLowerLimitInRadians, b3Scalar angleUpperLimitInRadians) { - if(angleLowerLimitInRadians >= angleUpperLimitInRadians) + if (angleLowerLimitInRadians >= angleUpperLimitInRadians) { return angleInRadians; } - else if(angleInRadians < angleLowerLimitInRadians) + else if (angleInRadians < angleLowerLimitInRadians) { b3Scalar diffLo = b3Fabs(b3NormalizeAngle(angleLowerLimitInRadians - angleInRadians)); b3Scalar diffHi = b3Fabs(b3NormalizeAngle(angleUpperLimitInRadians - angleInRadians)); return (diffLo < diffHi) ? angleInRadians : (angleInRadians + B3_2_PI); } - else if(angleInRadians > angleUpperLimitInRadians) + else if (angleInRadians > angleUpperLimitInRadians) { b3Scalar diffHi = b3Fabs(b3NormalizeAngle(angleInRadians - angleUpperLimitInRadians)); b3Scalar diffLo = b3Fabs(b3NormalizeAngle(angleInRadians - angleLowerLimitInRadians)); @@ -356,6 +342,7 @@ B3_FORCE_INLINE b3Scalar b3AdjustAngleToLimits(b3Scalar angleInRadians, b3Scalar } } +// clang-format off ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 struct b3TypedConstraintData { @@ -379,17 +366,18 @@ struct b3TypedConstraintData }; +// clang-format on + /*B3_FORCE_INLINE int b3TypedConstraint::calculateSerializeBufferSize() const { return sizeof(b3TypedConstraintData); } */ - class b3AngularLimit { private: - b3Scalar + b3Scalar m_center, m_halfRange, m_softness, @@ -404,15 +392,16 @@ private: public: /// Default constructor initializes limit as inactive, allowing free constraint movement b3AngularLimit() - :m_center(0.0f), - m_halfRange(-1.0f), - m_softness(0.9f), - m_biasFactor(0.3f), - m_relaxationFactor(1.0f), - m_correction(0.0f), - m_sign(0.0f), - m_solveLimit(false) - {} + : m_center(0.0f), + m_halfRange(-1.0f), + m_softness(0.9f), + m_biasFactor(0.3f), + m_relaxationFactor(1.0f), + m_correction(0.0f), + m_sign(0.0f), + m_solveLimit(false) + { + } /// Sets all limit's parameters. /// When low > high limit becomes inactive. @@ -441,13 +430,13 @@ public: return m_relaxationFactor; } - /// Returns correction value evaluated when test() was invoked + /// Returns correction value evaluated when test() was invoked inline b3Scalar getCorrection() const { return m_correction; } - /// Returns sign value evaluated when test() was invoked + /// Returns sign value evaluated when test() was invoked inline b3Scalar getSign() const { return m_sign; @@ -475,9 +464,6 @@ public: b3Scalar getLow() const; b3Scalar getHigh() const; - }; - - -#endif //B3_TYPED_CONSTRAINT_H +#endif //B3_TYPED_CONSTRAINT_H diff --git a/src/Bullet3Dynamics/b3CpuRigidBodyPipeline.cpp b/src/Bullet3Dynamics/b3CpuRigidBodyPipeline.cpp index fbc84cc28..f1080d9d5 100644 --- a/src/Bullet3Dynamics/b3CpuRigidBodyPipeline.cpp +++ b/src/Bullet3Dynamics/b3CpuRigidBodyPipeline.cpp @@ -11,7 +11,6 @@ #include "Bullet3Dynamics/shared/b3ContactConstraint4.h" #include "Bullet3Dynamics/shared/b3Inertia.h" - struct b3CpuRigidBodyPipelineInternalData { b3AlignedObjectArray m_rigidBodies; @@ -22,7 +21,6 @@ struct b3CpuRigidBodyPipelineInternalData b3CpuNarrowPhase* m_np; b3Config m_config; }; - b3CpuRigidBodyPipeline::b3CpuRigidBodyPipeline(class b3CpuNarrowPhase* narrowphase, struct b3DynamicBvhBroadphase* broadphaseDbvt, const b3Config& config) { @@ -39,49 +37,43 @@ b3CpuRigidBodyPipeline::~b3CpuRigidBodyPipeline() void b3CpuRigidBodyPipeline::updateAabbWorldSpace() { - - for (int i=0;igetNumBodies();i++) + for (int i = 0; i < this->getNumBodies(); i++) { b3RigidBodyData* body = &m_data->m_rigidBodies[i]; b3Float4 position = body->m_pos; - b3Quat orientation = body->m_quat; + b3Quat orientation = body->m_quat; int collidableIndex = body->m_collidableIdx; b3Collidable& collidable = m_data->m_np->getCollidableCpu(collidableIndex); int shapeIndex = collidable.m_shapeIndex; - - if (shapeIndex>=0) - { - + if (shapeIndex >= 0) + { b3Aabb localAabb = m_data->m_np->getLocalSpaceAabb(shapeIndex); b3Aabb& worldAabb = m_data->m_aabbWorldSpace[i]; - float margin=0.f; - b3TransformAabb2(localAabb.m_minVec,localAabb.m_maxVec,margin,position,orientation,&worldAabb.m_minVec,&worldAabb.m_maxVec); - m_data->m_bp->setAabb(i,worldAabb.m_minVec,worldAabb.m_maxVec,0); + float margin = 0.f; + b3TransformAabb2(localAabb.m_minVec, localAabb.m_maxVec, margin, position, orientation, &worldAabb.m_minVec, &worldAabb.m_maxVec); + m_data->m_bp->setAabb(i, worldAabb.m_minVec, worldAabb.m_maxVec, 0); } } } -void b3CpuRigidBodyPipeline::computeOverlappingPairs() +void b3CpuRigidBodyPipeline::computeOverlappingPairs() { int numPairs = m_data->m_bp->getOverlappingPairCache()->getNumOverlappingPairs(); m_data->m_bp->calculateOverlappingPairs(); numPairs = m_data->m_bp->getOverlappingPairCache()->getNumOverlappingPairs(); - printf("numPairs=%d\n",numPairs); + printf("numPairs=%d\n", numPairs); } void b3CpuRigidBodyPipeline::computeContactPoints() { - b3AlignedObjectArray& pairs = m_data->m_bp->getOverlappingPairCache()->getOverlappingPairArray(); - - m_data->m_np->computeContacts(pairs,m_data->m_aabbWorldSpace, m_data->m_rigidBodies); + m_data->m_np->computeContacts(pairs, m_data->m_aabbWorldSpace, m_data->m_rigidBodies); } -void b3CpuRigidBodyPipeline::stepSimulation(float deltaTime) +void b3CpuRigidBodyPipeline::stepSimulation(float deltaTime) { - //update world space aabb's updateAabbWorldSpace(); @@ -92,73 +84,71 @@ void b3CpuRigidBodyPipeline::stepSimulation(float deltaTime) computeContactPoints(); //solve contacts - + //update transforms integrate(deltaTime); - - } - -static inline float b3CalcRelVel(const b3Vector3& l0, const b3Vector3& l1, const b3Vector3& a0, const b3Vector3& a1, - const b3Vector3& linVel0, const b3Vector3& angVel0, const b3Vector3& linVel1, const b3Vector3& angVel1) +static inline float b3CalcRelVel(const b3Vector3& l0, const b3Vector3& l1, const b3Vector3& a0, const b3Vector3& a1, + const b3Vector3& linVel0, const b3Vector3& angVel0, const b3Vector3& linVel1, const b3Vector3& angVel1) { return b3Dot(l0, linVel0) + b3Dot(a0, angVel0) + b3Dot(l1, linVel1) + b3Dot(a1, angVel1); } - -static inline void b3SetLinearAndAngular(const b3Vector3& n, const b3Vector3& r0, const b3Vector3& r1, - b3Vector3& linear, b3Vector3& angular0, b3Vector3& angular1) +static inline void b3SetLinearAndAngular(const b3Vector3& n, const b3Vector3& r0, const b3Vector3& r1, + b3Vector3& linear, b3Vector3& angular0, b3Vector3& angular1) { linear = -n; angular0 = -b3Cross(r0, n); angular1 = b3Cross(r1, n); } - - -static inline void b3SolveContact(b3ContactConstraint4& cs, - const b3Vector3& posA, b3Vector3& linVelA, b3Vector3& angVelA, float invMassA, const b3Matrix3x3& invInertiaA, - const b3Vector3& posB, b3Vector3& linVelB, b3Vector3& angVelB, float invMassB, const b3Matrix3x3& invInertiaB, - float maxRambdaDt[4], float minRambdaDt[4]) +static inline void b3SolveContact(b3ContactConstraint4& cs, + const b3Vector3& posA, b3Vector3& linVelA, b3Vector3& angVelA, float invMassA, const b3Matrix3x3& invInertiaA, + const b3Vector3& posB, b3Vector3& linVelB, b3Vector3& angVelB, float invMassB, const b3Matrix3x3& invInertiaB, + float maxRambdaDt[4], float minRambdaDt[4]) { + b3Vector3 dLinVelA; + dLinVelA.setZero(); + b3Vector3 dAngVelA; + dAngVelA.setZero(); + b3Vector3 dLinVelB; + dLinVelB.setZero(); + b3Vector3 dAngVelB; + dAngVelB.setZero(); - b3Vector3 dLinVelA; dLinVelA.setZero(); - b3Vector3 dAngVelA; dAngVelA.setZero(); - b3Vector3 dLinVelB; dLinVelB.setZero(); - b3Vector3 dAngVelB; dAngVelB.setZero(); - - for(int ic=0; ic<4; ic++) + for (int ic = 0; ic < 4; ic++) { // dont necessary because this makes change to 0 - if( cs.m_jacCoeffInv[ic] == 0.f ) continue; + if (cs.m_jacCoeffInv[ic] == 0.f) continue; { b3Vector3 angular0, angular1, linear; b3Vector3 r0 = cs.m_worldPos[ic] - (b3Vector3&)posA; b3Vector3 r1 = cs.m_worldPos[ic] - (b3Vector3&)posB; - b3SetLinearAndAngular( (const b3Vector3 &)-cs.m_linear, (const b3Vector3 &)r0, (const b3Vector3 &)r1, linear, angular0, angular1 ); + b3SetLinearAndAngular((const b3Vector3&)-cs.m_linear, (const b3Vector3&)r0, (const b3Vector3&)r1, linear, angular0, angular1); - float rambdaDt = b3CalcRelVel((const b3Vector3 &)cs.m_linear,(const b3Vector3 &) -cs.m_linear, angular0, angular1, - linVelA, angVelA, linVelB, angVelB ) + cs.m_b[ic]; + float rambdaDt = b3CalcRelVel((const b3Vector3&)cs.m_linear, (const b3Vector3&)-cs.m_linear, angular0, angular1, + linVelA, angVelA, linVelB, angVelB) + + cs.m_b[ic]; rambdaDt *= cs.m_jacCoeffInv[ic]; { float prevSum = cs.m_appliedRambdaDt[ic]; float updated = prevSum; updated += rambdaDt; - updated = b3Max( updated, minRambdaDt[ic] ); - updated = b3Min( updated, maxRambdaDt[ic] ); + updated = b3Max(updated, minRambdaDt[ic]); + updated = b3Min(updated, maxRambdaDt[ic]); rambdaDt = updated - prevSum; cs.m_appliedRambdaDt[ic] = updated; } - b3Vector3 linImp0 = invMassA*linear*rambdaDt; - b3Vector3 linImp1 = invMassB*(-linear)*rambdaDt; - b3Vector3 angImp0 = (invInertiaA* angular0)*rambdaDt; - b3Vector3 angImp1 = (invInertiaB* angular1)*rambdaDt; + b3Vector3 linImp0 = invMassA * linear * rambdaDt; + b3Vector3 linImp1 = invMassB * (-linear) * rambdaDt; + b3Vector3 angImp0 = (invInertiaA * angular0) * rambdaDt; + b3Vector3 angImp1 = (invInertiaB * angular1) * rambdaDt; #ifdef _WIN32 - b3Assert(_finite(linImp0.getX())); + b3Assert(_finite(linImp0.getX())); b3Assert(_finite(linImp1.getX())); #endif { @@ -169,53 +159,46 @@ static inline void b3SolveContact(b3ContactConstraint4& cs, } } } - - } - - - - -static inline void b3SolveFriction(b3ContactConstraint4& cs, - const b3Vector3& posA, b3Vector3& linVelA, b3Vector3& angVelA, float invMassA, const b3Matrix3x3& invInertiaA, - const b3Vector3& posB, b3Vector3& linVelB, b3Vector3& angVelB, float invMassB, const b3Matrix3x3& invInertiaB, - float maxRambdaDt[4], float minRambdaDt[4]) +static inline void b3SolveFriction(b3ContactConstraint4& cs, + const b3Vector3& posA, b3Vector3& linVelA, b3Vector3& angVelA, float invMassA, const b3Matrix3x3& invInertiaA, + const b3Vector3& posB, b3Vector3& linVelB, b3Vector3& angVelB, float invMassB, const b3Matrix3x3& invInertiaB, + float maxRambdaDt[4], float minRambdaDt[4]) { - - if( cs.m_fJacCoeffInv[0] == 0 && cs.m_fJacCoeffInv[0] == 0 ) return; + if (cs.m_fJacCoeffInv[0] == 0 && cs.m_fJacCoeffInv[0] == 0) return; const b3Vector3& center = (const b3Vector3&)cs.m_center; b3Vector3 n = -(const b3Vector3&)cs.m_linear; b3Vector3 tangent[2]; - b3PlaneSpace1 (n, tangent[0],tangent[1]); + b3PlaneSpace1(n, tangent[0], tangent[1]); b3Vector3 angular0, angular1, linear; b3Vector3 r0 = center - posA; b3Vector3 r1 = center - posB; - for(int i=0; i<2; i++) + for (int i = 0; i < 2; i++) { - b3SetLinearAndAngular( tangent[i], r0, r1, linear, angular0, angular1 ); + b3SetLinearAndAngular(tangent[i], r0, r1, linear, angular0, angular1); float rambdaDt = b3CalcRelVel(linear, -linear, angular0, angular1, - linVelA, angVelA, linVelB, angVelB ); + linVelA, angVelA, linVelB, angVelB); rambdaDt *= cs.m_fJacCoeffInv[i]; - { - float prevSum = cs.m_fAppliedRambdaDt[i]; - float updated = prevSum; - updated += rambdaDt; - updated = b3Max( updated, minRambdaDt[i] ); - updated = b3Min( updated, maxRambdaDt[i] ); - rambdaDt = updated - prevSum; - cs.m_fAppliedRambdaDt[i] = updated; - } + { + float prevSum = cs.m_fAppliedRambdaDt[i]; + float updated = prevSum; + updated += rambdaDt; + updated = b3Max(updated, minRambdaDt[i]); + updated = b3Min(updated, maxRambdaDt[i]); + rambdaDt = updated - prevSum; + cs.m_fAppliedRambdaDt[i] = updated; + } - b3Vector3 linImp0 = invMassA*linear*rambdaDt; - b3Vector3 linImp1 = invMassB*(-linear)*rambdaDt; - b3Vector3 angImp0 = (invInertiaA* angular0)*rambdaDt; - b3Vector3 angImp1 = (invInertiaB* angular1)*rambdaDt; + b3Vector3 linImp0 = invMassA * linear * rambdaDt; + b3Vector3 linImp1 = invMassB * (-linear) * rambdaDt; + b3Vector3 angImp0 = (invInertiaA * angular0) * rambdaDt; + b3Vector3 angImp1 = (invInertiaB * angular1) * rambdaDt; #ifdef _WIN32 b3Assert(_finite(linImp0.getX())); b3Assert(_finite(linImp1.getX())); @@ -226,57 +209,45 @@ static inline void b3SolveFriction(b3ContactConstraint4& cs, angVelB += angImp1; } - { // angular damping for point constraint - b3Vector3 ab = ( posB - posA ).normalized(); - b3Vector3 ac = ( center - posA ).normalized(); - if( b3Dot( ab, ac ) > 0.95f || (invMassA == 0.f || invMassB == 0.f)) + { // angular damping for point constraint + b3Vector3 ab = (posB - posA).normalized(); + b3Vector3 ac = (center - posA).normalized(); + if (b3Dot(ab, ac) > 0.95f || (invMassA == 0.f || invMassB == 0.f)) { - float angNA = b3Dot( n, angVelA ); - float angNB = b3Dot( n, angVelB ); + float angNA = b3Dot(n, angVelA); + float angNB = b3Dot(n, angVelB); - angVelA -= (angNA*0.1f)*n; - angVelB -= (angNB*0.1f)*n; + angVelA -= (angNA * 0.1f) * n; + angVelB -= (angNB * 0.1f) * n; } } - } - - - - -struct b3SolveTask// : public ThreadPool::Task +struct b3SolveTask // : public ThreadPool::Task { - b3SolveTask(b3AlignedObjectArray& bodies, - b3AlignedObjectArray& shapes, + b3SolveTask(b3AlignedObjectArray& bodies, + b3AlignedObjectArray& shapes, b3AlignedObjectArray& constraints, int start, int nConstraints, int maxNumBatches, - b3AlignedObjectArray* wgUsedBodies, int curWgidx - ) - : m_bodies( bodies ), m_shapes( shapes ), m_constraints( constraints ), - m_wgUsedBodies(wgUsedBodies),m_curWgidx(curWgidx), -m_start( start ), - m_nConstraints( nConstraints ), - m_solveFriction( true ), - m_maxNumBatches(maxNumBatches) - {} + b3AlignedObjectArray* wgUsedBodies, int curWgidx) + : m_bodies(bodies), m_shapes(shapes), m_constraints(constraints), m_wgUsedBodies(wgUsedBodies), m_curWgidx(curWgidx), m_start(start), m_nConstraints(nConstraints), m_solveFriction(true), m_maxNumBatches(maxNumBatches) + { + } - unsigned short int getType(){ return 0; } + unsigned short int getType() { return 0; } void run(int tIdx) { b3AlignedObjectArray usedBodies; //printf("run..............\n"); - - for (int bb=0;bb=0; ic--) + for (int ic = m_nConstraints - 1; ic >= 0; ic--) //for(int ic=0; ic& m_bodies; @@ -397,24 +361,22 @@ void b3CpuRigidBodyPipeline::solveContactConstraints() int m_nIterations = 4; b3AlignedObjectArray contactConstraints; -// const b3AlignedObjectArray& contacts = m_data->m_np->getContacts(); + // const b3AlignedObjectArray& contacts = m_data->m_np->getContacts(); int n = contactConstraints.size(); //convert contacts... - - int maxNumBatches = 250; - for(int iter=0; iterm_rigidBodies, m_data->m_inertias, contactConstraints, 0, n ,maxNumBatches,0,0); + b3SolveTask task(m_data->m_rigidBodies, m_data->m_inertias, contactConstraints, 0, n, maxNumBatches, 0, 0); task.m_solveFriction = false; task.run(0); } - for(int iter=0; iterm_rigidBodies, m_data->m_inertias, contactConstraints, 0, n ,maxNumBatches,0,0); + b3SolveTask task(m_data->m_rigidBodies, m_data->m_inertias, contactConstraints, 0, n, maxNumBatches, 0, 0); task.m_solveFriction = true; task.run(0); } @@ -422,53 +384,51 @@ void b3CpuRigidBodyPipeline::solveContactConstraints() void b3CpuRigidBodyPipeline::integrate(float deltaTime) { - float angDamping=0.f; - b3Vector3 gravityAcceleration=b3MakeVector3(0,-9,0); + float angDamping = 0.f; + b3Vector3 gravityAcceleration = b3MakeVector3(0, -9, 0); //integrate transforms (external forces/gravity should be moved into constraint solver) - for (int i=0;im_rigidBodies.size();i++) + for (int i = 0; i < m_data->m_rigidBodies.size(); i++) { - b3IntegrateTransform(&m_data->m_rigidBodies[i],deltaTime,angDamping,gravityAcceleration); + b3IntegrateTransform(&m_data->m_rigidBodies[i], deltaTime, angDamping, gravityAcceleration); } - } -int b3CpuRigidBodyPipeline::registerPhysicsInstance(float mass, const float* position, const float* orientation, int collidableIndex, int userData) +int b3CpuRigidBodyPipeline::registerPhysicsInstance(float mass, const float* position, const float* orientation, int collidableIndex, int userData) { b3RigidBodyData body; int bodyIndex = m_data->m_rigidBodies.size(); - body.m_invMass = mass ? 1.f/mass : 0.f; - body.m_angVel.setValue(0,0,0); + body.m_invMass = mass ? 1.f / mass : 0.f; + body.m_angVel.setValue(0, 0, 0); body.m_collidableIdx = collidableIndex; body.m_frictionCoeff = 0.3f; - body.m_linVel.setValue(0,0,0); - body.m_pos.setValue(position[0],position[1],position[2]); - body.m_quat.setValue(orientation[0],orientation[1],orientation[2],orientation[3]); + body.m_linVel.setValue(0, 0, 0); + body.m_pos.setValue(position[0], position[1], position[2]); + body.m_quat.setValue(orientation[0], orientation[1], orientation[2], orientation[3]); body.m_restituitionCoeff = 0.f; m_data->m_rigidBodies.push_back(body); - - if (collidableIndex>=0) + if (collidableIndex >= 0) { b3Aabb& worldAabb = m_data->m_aabbWorldSpace.expand(); b3Aabb localAabb = m_data->m_np->getLocalSpaceAabb(collidableIndex); - b3Vector3 localAabbMin=b3MakeVector3(localAabb.m_min[0],localAabb.m_min[1],localAabb.m_min[2]); - b3Vector3 localAabbMax=b3MakeVector3(localAabb.m_max[0],localAabb.m_max[1],localAabb.m_max[2]); - + b3Vector3 localAabbMin = b3MakeVector3(localAabb.m_min[0], localAabb.m_min[1], localAabb.m_min[2]); + b3Vector3 localAabbMax = b3MakeVector3(localAabb.m_max[0], localAabb.m_max[1], localAabb.m_max[2]); + b3Scalar margin = 0.01f; b3Transform t; t.setIdentity(); - t.setOrigin(b3MakeVector3(position[0],position[1],position[2])); - t.setRotation(b3Quaternion(orientation[0],orientation[1],orientation[2],orientation[3])); - b3TransformAabb(localAabbMin,localAabbMax, margin,t,worldAabb.m_minVec,worldAabb.m_maxVec); + t.setOrigin(b3MakeVector3(position[0], position[1], position[2])); + t.setRotation(b3Quaternion(orientation[0], orientation[1], orientation[2], orientation[3])); + b3TransformAabb(localAabbMin, localAabbMax, margin, t, worldAabb.m_minVec, worldAabb.m_maxVec); - m_data->m_bp->createProxy(worldAabb.m_minVec,worldAabb.m_maxVec,bodyIndex,0,1,1); -// b3Vector3 aabbMin,aabbMax; - // m_data->m_bp->getAabb(bodyIndex,aabbMin,aabbMax); - - } else + m_data->m_bp->createProxy(worldAabb.m_minVec, worldAabb.m_maxVec, bodyIndex, 0, 1, 1); + // b3Vector3 aabbMin,aabbMax; + // m_data->m_bp->getAabb(bodyIndex,aabbMin,aabbMax); + } + else { b3Error("registerPhysicsInstance using invalid collidableIndex\n"); } @@ -476,13 +436,12 @@ int b3CpuRigidBodyPipeline::registerPhysicsInstance(float mass, const float* po return bodyIndex; } - const struct b3RigidBodyData* b3CpuRigidBodyPipeline::getBodyBuffer() const { return m_data->m_rigidBodies.size() ? &m_data->m_rigidBodies[0] : 0; } -int b3CpuRigidBodyPipeline::getNumBodies() const +int b3CpuRigidBodyPipeline::getNumBodies() const { return m_data->m_rigidBodies.size(); } diff --git a/src/Bullet3Dynamics/b3CpuRigidBodyPipeline.h b/src/Bullet3Dynamics/b3CpuRigidBodyPipeline.h index 2f3c2ae77..9c65419f2 100644 --- a/src/Bullet3Dynamics/b3CpuRigidBodyPipeline.h +++ b/src/Bullet3Dynamics/b3CpuRigidBodyPipeline.h @@ -16,52 +16,47 @@ subject to the following restrictions: #ifndef B3_CPU_RIGIDBODY_PIPELINE_H #define B3_CPU_RIGIDBODY_PIPELINE_H - - #include "Bullet3Common/b3AlignedObjectArray.h" #include "Bullet3Collision/NarrowPhaseCollision/b3RaycastInfo.h" class b3CpuRigidBodyPipeline { protected: - struct b3CpuRigidBodyPipelineInternalData* m_data; + struct b3CpuRigidBodyPipelineInternalData* m_data; int allocateCollidable(); public: - - b3CpuRigidBodyPipeline(class b3CpuNarrowPhase* narrowphase, struct b3DynamicBvhBroadphase* broadphaseDbvt, const struct b3Config& config); virtual ~b3CpuRigidBodyPipeline(); - virtual void stepSimulation(float deltaTime); - virtual void integrate(float timeStep); - virtual void updateAabbWorldSpace(); - virtual void computeOverlappingPairs(); - virtual void computeContactPoints(); - virtual void solveContactConstraints(); + virtual void stepSimulation(float deltaTime); + virtual void integrate(float timeStep); + virtual void updateAabbWorldSpace(); + virtual void computeOverlappingPairs(); + virtual void computeContactPoints(); + virtual void solveContactConstraints(); - int registerConvexPolyhedron(class b3ConvexUtility* convex); + int registerConvexPolyhedron(class b3ConvexUtility* convex); - int registerPhysicsInstance(float mass, const float* position, const float* orientation, int collisionShapeIndex, int userData); - void writeAllInstancesToGpu(); - void copyConstraintsToHost(); - void setGravity(const float* grav); - void reset(); - - int createPoint2PointConstraint(int bodyA, int bodyB, const float* pivotInA, const float* pivotInB,float breakingThreshold); + int registerPhysicsInstance(float mass, const float* position, const float* orientation, int collisionShapeIndex, int userData); + void writeAllInstancesToGpu(); + void copyConstraintsToHost(); + void setGravity(const float* grav); + void reset(); + + int createPoint2PointConstraint(int bodyA, int bodyB, const float* pivotInA, const float* pivotInB, float breakingThreshold); int createFixedConstraint(int bodyA, int bodyB, const float* pivotInA, const float* pivotInB, const float* relTargetAB, float breakingThreshold); void removeConstraintByUid(int uid); - void addConstraint(class b3TypedConstraint* constraint); - void removeConstraint(b3TypedConstraint* constraint); + void addConstraint(class b3TypedConstraint* constraint); + void removeConstraint(b3TypedConstraint* constraint); - void castRays(const b3AlignedObjectArray& rays, b3AlignedObjectArray& hitResults); + void castRays(const b3AlignedObjectArray& rays, b3AlignedObjectArray& hitResults); const struct b3RigidBodyData* getBodyBuffer() const; - int getNumBodies() const; - + int getNumBodies() const; }; -#endif //B3_CPU_RIGIDBODY_PIPELINE_H \ No newline at end of file +#endif //B3_CPU_RIGIDBODY_PIPELINE_H \ No newline at end of file diff --git a/src/Bullet3Dynamics/shared/b3ContactConstraint4.h b/src/Bullet3Dynamics/shared/b3ContactConstraint4.h index 68cf65e31..cf2eed0e7 100644 --- a/src/Bullet3Dynamics/shared/b3ContactConstraint4.h +++ b/src/Bullet3Dynamics/shared/b3ContactConstraint4.h @@ -5,30 +5,27 @@ typedef struct b3ContactConstraint4 b3ContactConstraint4_t; - struct b3ContactConstraint4 { - - b3Float4 m_linear;//normal? + b3Float4 m_linear; //normal? b3Float4 m_worldPos[4]; - b3Float4 m_center; // friction + b3Float4 m_center; // friction float m_jacCoeffInv[4]; float m_b[4]; float m_appliedRambdaDt[4]; - float m_fJacCoeffInv[2]; // friction - float m_fAppliedRambdaDt[2]; // friction + float m_fJacCoeffInv[2]; // friction + float m_fAppliedRambdaDt[2]; // friction unsigned int m_bodyA; unsigned int m_bodyB; - int m_batchIdx; + int m_batchIdx; unsigned int m_paddings; - }; //inline void setFrictionCoeff(float value) { m_linear[3] = value; } -inline float b3GetFrictionCoeff(b3ContactConstraint4_t* constraint) +inline float b3GetFrictionCoeff(b3ContactConstraint4_t* constraint) { - return constraint->m_linear.w; + return constraint->m_linear.w; } -#endif //B3_CONTACT_CONSTRAINT5_H +#endif //B3_CONTACT_CONSTRAINT5_H diff --git a/src/Bullet3Dynamics/shared/b3ConvertConstraint4.h b/src/Bullet3Dynamics/shared/b3ConvertConstraint4.h index 805a2bd3e..3e72f1c3f 100644 --- a/src/Bullet3Dynamics/shared/b3ConvertConstraint4.h +++ b/src/Bullet3Dynamics/shared/b3ConvertConstraint4.h @@ -4,89 +4,84 @@ #include "Bullet3Dynamics/shared/b3ContactConstraint4.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3RigidBodyData.h" - -void b3PlaneSpace1 (b3Float4ConstArg n, b3Float4* p, b3Float4* q); - void b3PlaneSpace1 (b3Float4ConstArg n, b3Float4* p, b3Float4* q) +void b3PlaneSpace1(b3Float4ConstArg n, b3Float4* p, b3Float4* q); +void b3PlaneSpace1(b3Float4ConstArg n, b3Float4* p, b3Float4* q) { - if (b3Fabs(n.z) > 0.70710678f) { - // choose p in y-z plane - float a = n.y*n.y + n.z*n.z; - float k = 1.f/sqrt(a); - p[0].x = 0; - p[0].y = -n.z*k; - p[0].z = n.y*k; - // set q = n x p - q[0].x = a*k; - q[0].y = -n.x*p[0].z; - q[0].z = n.x*p[0].y; - } - else { - // choose p in x-y plane - float a = n.x*n.x + n.y*n.y; - float k = 1.f/sqrt(a); - p[0].x = -n.y*k; - p[0].y = n.x*k; - p[0].z = 0; - // set q = n x p - q[0].x = -n.z*p[0].y; - q[0].y = n.z*p[0].x; - q[0].z = a*k; - } + if (b3Fabs(n.z) > 0.70710678f) + { + // choose p in y-z plane + float a = n.y * n.y + n.z * n.z; + float k = 1.f / sqrt(a); + p[0].x = 0; + p[0].y = -n.z * k; + p[0].z = n.y * k; + // set q = n x p + q[0].x = a * k; + q[0].y = -n.x * p[0].z; + q[0].z = n.x * p[0].y; + } + else + { + // choose p in x-y plane + float a = n.x * n.x + n.y * n.y; + float k = 1.f / sqrt(a); + p[0].x = -n.y * k; + p[0].y = n.x * k; + p[0].z = 0; + // set q = n x p + q[0].x = -n.z * p[0].y; + q[0].y = n.z * p[0].x; + q[0].z = a * k; + } } - - -void setLinearAndAngular( b3Float4ConstArg n, b3Float4ConstArg r0, b3Float4ConstArg r1, b3Float4* linear, b3Float4* angular0, b3Float4* angular1) +void setLinearAndAngular(b3Float4ConstArg n, b3Float4ConstArg r0, b3Float4ConstArg r1, b3Float4* linear, b3Float4* angular0, b3Float4* angular1) { - *linear = b3MakeFloat4(n.x,n.y,n.z,0.f); + *linear = b3MakeFloat4(n.x, n.y, n.z, 0.f); *angular0 = b3Cross3(r0, n); *angular1 = -b3Cross3(r1, n); } - -float calcRelVel( b3Float4ConstArg l0, b3Float4ConstArg l1, b3Float4ConstArg a0, b3Float4ConstArg a1, b3Float4ConstArg linVel0, - b3Float4ConstArg angVel0, b3Float4ConstArg linVel1, b3Float4ConstArg angVel1 ) +float calcRelVel(b3Float4ConstArg l0, b3Float4ConstArg l1, b3Float4ConstArg a0, b3Float4ConstArg a1, b3Float4ConstArg linVel0, + b3Float4ConstArg angVel0, b3Float4ConstArg linVel1, b3Float4ConstArg angVel1) { return b3Dot3F4(l0, linVel0) + b3Dot3F4(a0, angVel0) + b3Dot3F4(l1, linVel1) + b3Dot3F4(a1, angVel1); } - float calcJacCoeff(b3Float4ConstArg linear0, b3Float4ConstArg linear1, b3Float4ConstArg angular0, b3Float4ConstArg angular1, - float invMass0, const b3Mat3x3* invInertia0, float invMass1, const b3Mat3x3* invInertia1) + float invMass0, const b3Mat3x3* invInertia0, float invMass1, const b3Mat3x3* invInertia1) { // linear0,1 are normlized - float jmj0 = invMass0;//b3Dot3F4(linear0, linear0)*invMass0; - float jmj1 = b3Dot3F4(mtMul3(angular0,*invInertia0), angular0); - float jmj2 = invMass1;//b3Dot3F4(linear1, linear1)*invMass1; - float jmj3 = b3Dot3F4(mtMul3(angular1,*invInertia1), angular1); - return -1.f/(jmj0+jmj1+jmj2+jmj3); + float jmj0 = invMass0; //b3Dot3F4(linear0, linear0)*invMass0; + float jmj1 = b3Dot3F4(mtMul3(angular0, *invInertia0), angular0); + float jmj2 = invMass1; //b3Dot3F4(linear1, linear1)*invMass1; + float jmj3 = b3Dot3F4(mtMul3(angular1, *invInertia1), angular1); + return -1.f / (jmj0 + jmj1 + jmj2 + jmj3); } - -void setConstraint4( b3Float4ConstArg posA, b3Float4ConstArg linVelA, b3Float4ConstArg angVelA, float invMassA, b3Mat3x3ConstArg invInertiaA, - b3Float4ConstArg posB, b3Float4ConstArg linVelB, b3Float4ConstArg angVelB, float invMassB, b3Mat3x3ConstArg invInertiaB, - __global struct b3Contact4Data* src, float dt, float positionDrift, float positionConstraintCoeff, - b3ContactConstraint4_t* dstC ) +void setConstraint4(b3Float4ConstArg posA, b3Float4ConstArg linVelA, b3Float4ConstArg angVelA, float invMassA, b3Mat3x3ConstArg invInertiaA, + b3Float4ConstArg posB, b3Float4ConstArg linVelB, b3Float4ConstArg angVelB, float invMassB, b3Mat3x3ConstArg invInertiaB, + __global struct b3Contact4Data* src, float dt, float positionDrift, float positionConstraintCoeff, + b3ContactConstraint4_t* dstC) { dstC->m_bodyA = abs(src->m_bodyAPtrAndSignBit); dstC->m_bodyB = abs(src->m_bodyBPtrAndSignBit); - float dtInv = 1.f/dt; - for(int ic=0; ic<4; ic++) + float dtInv = 1.f / dt; + for (int ic = 0; ic < 4; ic++) { dstC->m_appliedRambdaDt[ic] = 0.f; } dstC->m_fJacCoeffInv[0] = dstC->m_fJacCoeffInv[1] = 0.f; - dstC->m_linear = src->m_worldNormalOnB; - dstC->m_linear.w = 0.7f ;//src->getFrictionCoeff() ); - for(int ic=0; ic<4; ic++) + dstC->m_linear.w = 0.7f; //src->getFrictionCoeff() ); + for (int ic = 0; ic < 4; ic++) { b3Float4 r0 = src->m_worldPosB[ic] - posA; b3Float4 r1 = src->m_worldPosB[ic] - posB; - if( ic >= src->m_worldNormalOnB.w )//npoints + if (ic >= src->m_worldNormalOnB.w) //npoints { dstC->m_jacCoeffInv[ic] = 0.f; continue; @@ -98,56 +93,56 @@ void setConstraint4( b3Float4ConstArg posA, b3Float4ConstArg linVelA, b3Float4Co setLinearAndAngular(src->m_worldNormalOnB, r0, r1, &linear, &angular0, &angular1); dstC->m_jacCoeffInv[ic] = calcJacCoeff(linear, -linear, angular0, angular1, - invMassA, &invInertiaA, invMassB, &invInertiaB ); + invMassA, &invInertiaA, invMassB, &invInertiaB); relVelN = calcRelVel(linear, -linear, angular0, angular1, - linVelA, angVelA, linVelB, angVelB); + linVelA, angVelA, linVelB, angVelB); - float e = 0.f;//src->getRestituitionCoeff(); - if( relVelN*relVelN < 0.004f ) e = 0.f; + float e = 0.f; //src->getRestituitionCoeff(); + if (relVelN * relVelN < 0.004f) e = 0.f; - dstC->m_b[ic] = e*relVelN; + dstC->m_b[ic] = e * relVelN; //float penetration = src->m_worldPosB[ic].w; - dstC->m_b[ic] += (src->m_worldPosB[ic].w + positionDrift)*positionConstraintCoeff*dtInv; + dstC->m_b[ic] += (src->m_worldPosB[ic].w + positionDrift) * positionConstraintCoeff * dtInv; dstC->m_appliedRambdaDt[ic] = 0.f; } } - if( src->m_worldNormalOnB.w > 0 )//npoints - { // prepare friction - b3Float4 center = b3MakeFloat4(0.f,0.f,0.f,0.f); - for(int i=0; im_worldNormalOnB.w; i++) + if (src->m_worldNormalOnB.w > 0) //npoints + { // prepare friction + b3Float4 center = b3MakeFloat4(0.f, 0.f, 0.f, 0.f); + for (int i = 0; i < src->m_worldNormalOnB.w; i++) center += src->m_worldPosB[i]; center /= (float)src->m_worldNormalOnB.w; b3Float4 tangent[2]; - b3PlaneSpace1(src->m_worldNormalOnB,&tangent[0],&tangent[1]); - + b3PlaneSpace1(src->m_worldNormalOnB, &tangent[0], &tangent[1]); + b3Float4 r[2]; r[0] = center - posA; r[1] = center - posB; - for(int i=0; i<2; i++) + for (int i = 0; i < 2; i++) { b3Float4 linear, angular0, angular1; setLinearAndAngular(tangent[i], r[0], r[1], &linear, &angular0, &angular1); dstC->m_fJacCoeffInv[i] = calcJacCoeff(linear, -linear, angular0, angular1, - invMassA, &invInertiaA, invMassB, &invInertiaB ); + invMassA, &invInertiaA, invMassB, &invInertiaB); dstC->m_fAppliedRambdaDt[i] = 0.f; } dstC->m_center = center; } - for(int i=0; i<4; i++) + for (int i = 0; i < 4; i++) { - if( im_worldNormalOnB.w ) + if (i < src->m_worldNormalOnB.w) { dstC->m_worldPos[i] = src->m_worldPosB[i]; } else { - dstC->m_worldPos[i] = b3MakeFloat4(0.f,0.f,0.f,0.f); + dstC->m_worldPos[i] = b3MakeFloat4(0.f, 0.f, 0.f, 0.f); } } } diff --git a/src/Bullet3Dynamics/shared/b3Inertia.h b/src/Bullet3Dynamics/shared/b3Inertia.h index 96fe9f8b3..602a1335a 100644 --- a/src/Bullet3Dynamics/shared/b3Inertia.h +++ b/src/Bullet3Dynamics/shared/b3Inertia.h @@ -11,5 +11,4 @@ struct b3Inertia b3Mat3x3 m_initInvInertia; }; - -#endif //B3_INERTIA_H \ No newline at end of file +#endif //B3_INERTIA_H \ No newline at end of file diff --git a/src/Bullet3Dynamics/shared/b3IntegrateTransforms.h b/src/Bullet3Dynamics/shared/b3IntegrateTransforms.h index e96f90d3f..56d9118f9 100644 --- a/src/Bullet3Dynamics/shared/b3IntegrateTransforms.h +++ b/src/Bullet3Dynamics/shared/b3IntegrateTransforms.h @@ -2,11 +2,8 @@ #include "Bullet3Collision/NarrowPhaseCollision/shared/b3RigidBodyData.h" - - -inline void integrateSingleTransform( __global b3RigidBodyData_t* bodies,int nodeID, float timeStep, float angularDamping, b3Float4ConstArg gravityAcceleration) +inline void integrateSingleTransform(__global b3RigidBodyData_t* bodies, int nodeID, float timeStep, float angularDamping, b3Float4ConstArg gravityAcceleration) { - if (bodies[nodeID].m_invMass != 0.f) { float BT_GPU_ANGULAR_MOTION_THRESHOLD = (0.25f * 3.14159254f); @@ -18,27 +15,27 @@ inline void integrateSingleTransform( __global b3RigidBodyData_t* bodies,int nod bodies[nodeID].m_angVel.x *= angularDamping; bodies[nodeID].m_angVel.y *= angularDamping; bodies[nodeID].m_angVel.z *= angularDamping; - + b3Float4 angvel = bodies[nodeID].m_angVel; float fAngle = b3Sqrt(b3Dot3F4(angvel, angvel)); - + //limit the angular motion - if(fAngle*timeStep > BT_GPU_ANGULAR_MOTION_THRESHOLD) + if (fAngle * timeStep > BT_GPU_ANGULAR_MOTION_THRESHOLD) { fAngle = BT_GPU_ANGULAR_MOTION_THRESHOLD / timeStep; } - if(fAngle < 0.001f) + if (fAngle < 0.001f) { // use Taylor's expansions of sync function - axis = angvel * (0.5f*timeStep-(timeStep*timeStep*timeStep)*0.020833333333f * fAngle * fAngle); + axis = angvel * (0.5f * timeStep - (timeStep * timeStep * timeStep) * 0.020833333333f * fAngle * fAngle); } else { // sync(fAngle) = sin(c*fAngle)/t - axis = angvel * ( b3Sin(0.5f * fAngle * timeStep) / fAngle); + axis = angvel * (b3Sin(0.5f * fAngle * timeStep) / fAngle); } - + b3Quat dorn; dorn.x = axis.x; dorn.y = axis.y; @@ -47,23 +44,21 @@ inline void integrateSingleTransform( __global b3RigidBodyData_t* bodies,int nod b3Quat orn0 = bodies[nodeID].m_quat; b3Quat predictedOrn = b3QuatMul(dorn, orn0); predictedOrn = b3QuatNormalized(predictedOrn); - bodies[nodeID].m_quat=predictedOrn; + bodies[nodeID].m_quat = predictedOrn; } - //linear velocity - bodies[nodeID].m_pos += bodies[nodeID].m_linVel * timeStep; - + //linear velocity + bodies[nodeID].m_pos += bodies[nodeID].m_linVel * timeStep; + //apply gravity bodies[nodeID].m_linVel += gravityAcceleration * timeStep; - } - } -inline void b3IntegrateTransform( __global b3RigidBodyData_t* body, float timeStep, float angularDamping, b3Float4ConstArg gravityAcceleration) +inline void b3IntegrateTransform(__global b3RigidBodyData_t* body, float timeStep, float angularDamping, b3Float4ConstArg gravityAcceleration) { float BT_GPU_ANGULAR_MOTION_THRESHOLD = (0.25f * 3.14159254f); - - if( (body->m_invMass != 0.f)) + + if ((body->m_invMass != 0.f)) { //angular velocity { @@ -72,23 +67,23 @@ inline void b3IntegrateTransform( __global b3RigidBodyData_t* body, float timeSt body->m_angVel.x *= angularDamping; body->m_angVel.y *= angularDamping; body->m_angVel.z *= angularDamping; - + b3Float4 angvel = body->m_angVel; float fAngle = b3Sqrt(b3Dot3F4(angvel, angvel)); //limit the angular motion - if(fAngle*timeStep > BT_GPU_ANGULAR_MOTION_THRESHOLD) + if (fAngle * timeStep > BT_GPU_ANGULAR_MOTION_THRESHOLD) { fAngle = BT_GPU_ANGULAR_MOTION_THRESHOLD / timeStep; } - if(fAngle < 0.001f) + if (fAngle < 0.001f) { // use Taylor's expansions of sync function - axis = angvel * (0.5f*timeStep-(timeStep*timeStep*timeStep)*0.020833333333f * fAngle * fAngle); + axis = angvel * (0.5f * timeStep - (timeStep * timeStep * timeStep) * 0.020833333333f * fAngle * fAngle); } else { // sync(fAngle) = sin(c*fAngle)/t - axis = angvel * ( b3Sin(0.5f * fAngle * timeStep) / fAngle); + axis = angvel * (b3Sin(0.5f * fAngle * timeStep) / fAngle); } b3Quat dorn; dorn.x = axis.x; @@ -99,15 +94,13 @@ inline void b3IntegrateTransform( __global b3RigidBodyData_t* body, float timeSt b3Quat predictedOrn = b3QuatMul(dorn, orn0); predictedOrn = b3QuatNormalized(predictedOrn); - body->m_quat=predictedOrn; + body->m_quat = predictedOrn; } //apply gravity body->m_linVel += gravityAcceleration * timeStep; - //linear velocity - body->m_pos += body->m_linVel * timeStep; - + //linear velocity + body->m_pos += body->m_linVel * timeStep; } - } diff --git a/src/Bullet3Geometry/b3AabbUtil.h b/src/Bullet3Geometry/b3AabbUtil.h index 4c72d5bbf..396a40145 100644 --- a/src/Bullet3Geometry/b3AabbUtil.h +++ b/src/Bullet3Geometry/b3AabbUtil.h @@ -12,8 +12,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #ifndef B3_AABB_UTIL2 #define B3_AABB_UTIL2 @@ -21,20 +19,18 @@ subject to the following restrictions: #include "Bullet3Common/b3Vector3.h" #include "Bullet3Common/b3MinMax.h" - - -B3_FORCE_INLINE void b3AabbExpand (b3Vector3& aabbMin, - b3Vector3& aabbMax, - const b3Vector3& expansionMin, - const b3Vector3& expansionMax) +B3_FORCE_INLINE void b3AabbExpand(b3Vector3& aabbMin, + b3Vector3& aabbMax, + const b3Vector3& expansionMin, + const b3Vector3& expansionMax) { aabbMin = aabbMin + expansionMin; aabbMax = aabbMax + expansionMax; } /// conservative test for overlap between two aabbs -B3_FORCE_INLINE bool b3TestPointAgainstAabb2(const b3Vector3 &aabbMin1, const b3Vector3 &aabbMax1, - const b3Vector3 &point) +B3_FORCE_INLINE bool b3TestPointAgainstAabb2(const b3Vector3& aabbMin1, const b3Vector3& aabbMax1, + const b3Vector3& point) { bool overlap = true; overlap = (aabbMin1.getX() > point.getX() || aabbMax1.getX() < point.getX()) ? false : overlap; @@ -43,10 +39,9 @@ B3_FORCE_INLINE bool b3TestPointAgainstAabb2(const b3Vector3 &aabbMin1, const b3 return overlap; } - /// conservative test for overlap between two aabbs -B3_FORCE_INLINE bool b3TestAabbAgainstAabb2(const b3Vector3 &aabbMin1, const b3Vector3 &aabbMax1, - const b3Vector3 &aabbMin2, const b3Vector3 &aabbMax2) +B3_FORCE_INLINE bool b3TestAabbAgainstAabb2(const b3Vector3& aabbMin1, const b3Vector3& aabbMax1, + const b3Vector3& aabbMin2, const b3Vector3& aabbMax2) { bool overlap = true; overlap = (aabbMin1.getX() > aabbMax2.getX() || aabbMax1.getX() < aabbMin2.getX()) ? false : overlap; @@ -56,52 +51,49 @@ B3_FORCE_INLINE bool b3TestAabbAgainstAabb2(const b3Vector3 &aabbMin1, const b3V } /// conservative test for overlap between triangle and aabb -B3_FORCE_INLINE bool b3TestTriangleAgainstAabb2(const b3Vector3 *vertices, - const b3Vector3 &aabbMin, const b3Vector3 &aabbMax) +B3_FORCE_INLINE bool b3TestTriangleAgainstAabb2(const b3Vector3* vertices, + const b3Vector3& aabbMin, const b3Vector3& aabbMax) { - const b3Vector3 &p1 = vertices[0]; - const b3Vector3 &p2 = vertices[1]; - const b3Vector3 &p3 = vertices[2]; + const b3Vector3& p1 = vertices[0]; + const b3Vector3& p2 = vertices[1]; + const b3Vector3& p3 = vertices[2]; if (b3Min(b3Min(p1[0], p2[0]), p3[0]) > aabbMax[0]) return false; if (b3Max(b3Max(p1[0], p2[0]), p3[0]) < aabbMin[0]) return false; if (b3Min(b3Min(p1[2], p2[2]), p3[2]) > aabbMax[2]) return false; if (b3Max(b3Max(p1[2], p2[2]), p3[2]) < aabbMin[2]) return false; - + if (b3Min(b3Min(p1[1], p2[1]), p3[1]) > aabbMax[1]) return false; if (b3Max(b3Max(p1[1], p2[1]), p3[1]) < aabbMin[1]) return false; return true; } - -B3_FORCE_INLINE int b3Outcode(const b3Vector3& p,const b3Vector3& halfExtent) +B3_FORCE_INLINE int b3Outcode(const b3Vector3& p, const b3Vector3& halfExtent) { - return (p.getX() < -halfExtent.getX() ? 0x01 : 0x0) | - (p.getX() > halfExtent.getX() ? 0x08 : 0x0) | - (p.getY() < -halfExtent.getY() ? 0x02 : 0x0) | - (p.getY() > halfExtent.getY() ? 0x10 : 0x0) | - (p.getZ() < -halfExtent.getZ() ? 0x4 : 0x0) | - (p.getZ() > halfExtent.getZ() ? 0x20 : 0x0); + return (p.getX() < -halfExtent.getX() ? 0x01 : 0x0) | + (p.getX() > halfExtent.getX() ? 0x08 : 0x0) | + (p.getY() < -halfExtent.getY() ? 0x02 : 0x0) | + (p.getY() > halfExtent.getY() ? 0x10 : 0x0) | + (p.getZ() < -halfExtent.getZ() ? 0x4 : 0x0) | + (p.getZ() > halfExtent.getZ() ? 0x20 : 0x0); } - - B3_FORCE_INLINE bool b3RayAabb2(const b3Vector3& rayFrom, - const b3Vector3& rayInvDirection, - const unsigned int raySign[3], - const b3Vector3 bounds[2], - b3Scalar& tmin, - b3Scalar lambda_min, - b3Scalar lambda_max) + const b3Vector3& rayInvDirection, + const unsigned int raySign[3], + const b3Vector3 bounds[2], + b3Scalar& tmin, + b3Scalar lambda_min, + b3Scalar lambda_max) { b3Scalar tmax, tymin, tymax, tzmin, tzmax; tmin = (bounds[raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX(); - tmax = (bounds[1-raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX(); + tmax = (bounds[1 - raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX(); tymin = (bounds[raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY(); - tymax = (bounds[1-raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY(); + tymax = (bounds[1 - raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY(); - if ( (tmin > tymax) || (tymin > tmax) ) + if ((tmin > tymax) || (tymin > tmax)) return false; if (tymin > tmin) @@ -111,59 +103,59 @@ B3_FORCE_INLINE bool b3RayAabb2(const b3Vector3& rayFrom, tmax = tymax; tzmin = (bounds[raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ(); - tzmax = (bounds[1-raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ(); + tzmax = (bounds[1 - raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ(); - if ( (tmin > tzmax) || (tzmin > tmax) ) + if ((tmin > tzmax) || (tzmin > tmax)) return false; if (tzmin > tmin) tmin = tzmin; if (tzmax < tmax) tmax = tzmax; - return ( (tmin < lambda_max) && (tmax > lambda_min) ); + return ((tmin < lambda_max) && (tmax > lambda_min)); } -B3_FORCE_INLINE bool b3RayAabb(const b3Vector3& rayFrom, - const b3Vector3& rayTo, - const b3Vector3& aabbMin, - const b3Vector3& aabbMax, - b3Scalar& param, b3Vector3& normal) +B3_FORCE_INLINE bool b3RayAabb(const b3Vector3& rayFrom, + const b3Vector3& rayTo, + const b3Vector3& aabbMin, + const b3Vector3& aabbMax, + b3Scalar& param, b3Vector3& normal) { - b3Vector3 aabbHalfExtent = (aabbMax-aabbMin)* b3Scalar(0.5); - b3Vector3 aabbCenter = (aabbMax+aabbMin)* b3Scalar(0.5); - b3Vector3 source = rayFrom - aabbCenter; - b3Vector3 target = rayTo - aabbCenter; - int sourceOutcode = b3Outcode(source,aabbHalfExtent); - int targetOutcode = b3Outcode(target,aabbHalfExtent); + b3Vector3 aabbHalfExtent = (aabbMax - aabbMin) * b3Scalar(0.5); + b3Vector3 aabbCenter = (aabbMax + aabbMin) * b3Scalar(0.5); + b3Vector3 source = rayFrom - aabbCenter; + b3Vector3 target = rayTo - aabbCenter; + int sourceOutcode = b3Outcode(source, aabbHalfExtent); + int targetOutcode = b3Outcode(target, aabbHalfExtent); if ((sourceOutcode & targetOutcode) == 0x0) { b3Scalar lambda_enter = b3Scalar(0.0); - b3Scalar lambda_exit = param; + b3Scalar lambda_exit = param; b3Vector3 r = target - source; int i; - b3Scalar normSign = 1; - b3Vector3 hitNormal = b3MakeVector3(0,0,0); - int bit=1; + b3Scalar normSign = 1; + b3Vector3 hitNormal = b3MakeVector3(0, 0, 0); + int bit = 1; - for (int j=0;j<2;j++) + for (int j = 0; j < 2; j++) { for (i = 0; i != 3; ++i) { if (sourceOutcode & bit) { - b3Scalar lambda = (-source[i] - aabbHalfExtent[i]*normSign) / r[i]; + b3Scalar lambda = (-source[i] - aabbHalfExtent[i] * normSign) / r[i]; if (lambda_enter <= lambda) { lambda_enter = lambda; - hitNormal.setValue(0,0,0); + hitNormal.setValue(0, 0, 0); hitNormal[i] = normSign; } } - else if (targetOutcode & bit) + else if (targetOutcode & bit) { - b3Scalar lambda = (-source[i] - aabbHalfExtent[i]*normSign) / r[i]; + b3Scalar lambda = (-source[i] - aabbHalfExtent[i] * normSign) / r[i]; b3SetMin(lambda_exit, lambda); } - bit<<=1; + bit <<= 1; } normSign = b3Scalar(-1.); } @@ -177,56 +169,49 @@ B3_FORCE_INLINE bool b3RayAabb(const b3Vector3& rayFrom, return false; } - - -B3_FORCE_INLINE void b3TransformAabb(const b3Vector3& halfExtents, b3Scalar margin,const b3Transform& t,b3Vector3& aabbMinOut,b3Vector3& aabbMaxOut) +B3_FORCE_INLINE void b3TransformAabb(const b3Vector3& halfExtents, b3Scalar margin, const b3Transform& t, b3Vector3& aabbMinOut, b3Vector3& aabbMaxOut) { - b3Vector3 halfExtentsWithMargin = halfExtents+b3MakeVector3(margin,margin,margin); - b3Matrix3x3 abs_b = t.getBasis().absolute(); + b3Vector3 halfExtentsWithMargin = halfExtents + b3MakeVector3(margin, margin, margin); + b3Matrix3x3 abs_b = t.getBasis().absolute(); b3Vector3 center = t.getOrigin(); - b3Vector3 extent = halfExtentsWithMargin.dot3( abs_b[0], abs_b[1], abs_b[2] ); + b3Vector3 extent = halfExtentsWithMargin.dot3(abs_b[0], abs_b[1], abs_b[2]); aabbMinOut = center - extent; aabbMaxOut = center + extent; } - -B3_FORCE_INLINE void b3TransformAabb(const b3Vector3& localAabbMin,const b3Vector3& localAabbMax, b3Scalar margin,const b3Transform& trans,b3Vector3& aabbMinOut,b3Vector3& aabbMaxOut) +B3_FORCE_INLINE void b3TransformAabb(const b3Vector3& localAabbMin, const b3Vector3& localAabbMax, b3Scalar margin, const b3Transform& trans, b3Vector3& aabbMinOut, b3Vector3& aabbMaxOut) { - //b3Assert(localAabbMin.getX() <= localAabbMax.getX()); - //b3Assert(localAabbMin.getY() <= localAabbMax.getY()); - //b3Assert(localAabbMin.getZ() <= localAabbMax.getZ()); - b3Vector3 localHalfExtents = b3Scalar(0.5)*(localAabbMax-localAabbMin); - localHalfExtents+=b3MakeVector3(margin,margin,margin); + //b3Assert(localAabbMin.getX() <= localAabbMax.getX()); + //b3Assert(localAabbMin.getY() <= localAabbMax.getY()); + //b3Assert(localAabbMin.getZ() <= localAabbMax.getZ()); + b3Vector3 localHalfExtents = b3Scalar(0.5) * (localAabbMax - localAabbMin); + localHalfExtents += b3MakeVector3(margin, margin, margin); - b3Vector3 localCenter = b3Scalar(0.5)*(localAabbMax+localAabbMin); - b3Matrix3x3 abs_b = trans.getBasis().absolute(); - b3Vector3 center = trans(localCenter); - b3Vector3 extent = localHalfExtents.dot3( abs_b[0], abs_b[1], abs_b[2] ); - aabbMinOut = center-extent; - aabbMaxOut = center+extent; + b3Vector3 localCenter = b3Scalar(0.5) * (localAabbMax + localAabbMin); + b3Matrix3x3 abs_b = trans.getBasis().absolute(); + b3Vector3 center = trans(localCenter); + b3Vector3 extent = localHalfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); + aabbMinOut = center - extent; + aabbMaxOut = center + extent; } #define B3_USE_BANCHLESS 1 #ifdef B3_USE_BANCHLESS - //This block replaces the block below and uses no branches, and replaces the 8 bit return with a 32 bit return for improved performance (~3x on XBox 360) - B3_FORCE_INLINE unsigned b3TestQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1,const unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) - { - return static_cast(b3Select((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0]) - & (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2]) - & (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])), - 1, 0)); - } +//This block replaces the block below and uses no branches, and replaces the 8 bit return with a 32 bit return for improved performance (~3x on XBox 360) +B3_FORCE_INLINE unsigned b3TestQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1, const unsigned short int* aabbMax1, const unsigned short int* aabbMin2, const unsigned short int* aabbMax2) +{ + return static_cast(b3Select((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0]) & (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2]) & (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])), + 1, 0)); +} #else - B3_FORCE_INLINE bool b3TestQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1,const unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) - { - bool overlap = true; - overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap; - overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap; - overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap; - return overlap; - } -#endif //B3_USE_BANCHLESS - -#endif //B3_AABB_UTIL2 - +B3_FORCE_INLINE bool b3TestQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1, const unsigned short int* aabbMax1, const unsigned short int* aabbMin2, const unsigned short int* aabbMax2) +{ + bool overlap = true; + overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap; + overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap; + overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap; + return overlap; +} +#endif //B3_USE_BANCHLESS +#endif //B3_AABB_UTIL2 diff --git a/src/Bullet3Geometry/b3ConvexHullComputer.cpp b/src/Bullet3Geometry/b3ConvexHullComputer.cpp index 18835c38d..b37652456 100644 --- a/src/Bullet3Geometry/b3ConvexHullComputer.cpp +++ b/src/Bullet3Geometry/b3ConvexHullComputer.cpp @@ -20,850 +20,851 @@ subject to the following restrictions: #include "Bullet3Common/b3Vector3.h" #ifdef __GNUC__ - #include - typedef int32_t btInt32_t; - typedef int64_t btInt64_t; - typedef uint32_t btUint32_t; - typedef uint64_t btUint64_t; +#include +typedef int32_t btInt32_t; +typedef int64_t btInt64_t; +typedef uint32_t btUint32_t; +typedef uint64_t btUint64_t; #elif defined(_MSC_VER) - typedef __int32 btInt32_t; - typedef __int64 btInt64_t; - typedef unsigned __int32 btUint32_t; - typedef unsigned __int64 btUint64_t; +typedef __int32 btInt32_t; +typedef __int64 btInt64_t; +typedef unsigned __int32 btUint32_t; +typedef unsigned __int64 btUint64_t; #else - typedef int btInt32_t; - typedef long long int btInt64_t; - typedef unsigned int btUint32_t; - typedef unsigned long long int btUint64_t; +typedef int btInt32_t; +typedef long long int btInt64_t; +typedef unsigned int btUint32_t; +typedef unsigned long long int btUint64_t; #endif - //The definition of USE_X86_64_ASM is moved into the build system. You can enable it manually by commenting out the following lines //#if (defined(__GNUC__) && defined(__x86_64__) && !defined(__ICL)) // || (defined(__ICL) && defined(_M_X64)) bug in Intel compiler, disable inline assembly // #define USE_X86_64_ASM //#endif - //#define DEBUG_CONVEX_HULL //#define SHOW_ITERATIONS #if defined(DEBUG_CONVEX_HULL) || defined(SHOW_ITERATIONS) - #include +#include #endif // Convex hull implementation based on Preparata and Hong // Ole Kniemeyer, MAXON Computer GmbH class b3ConvexHullInternal { +public: + class Point64 + { public: - - class Point64 + btInt64_t x; + btInt64_t y; + btInt64_t z; + + Point64(btInt64_t x, btInt64_t y, btInt64_t z) : x(x), y(y), z(z) { - public: - btInt64_t x; - btInt64_t y; - btInt64_t z; - - Point64(btInt64_t x, btInt64_t y, btInt64_t z): x(x), y(y), z(z) - { - } - - bool isZero() - { - return (x == 0) && (y == 0) && (z == 0); - } - - btInt64_t dot(const Point64& b) const - { - return x * b.x + y * b.y + z * b.z; - } - }; - - class Point32 - { - public: - btInt32_t x; - btInt32_t y; - btInt32_t z; - int index; - - Point32() - { - } - - Point32(btInt32_t x, btInt32_t y, btInt32_t z): x(x), y(y), z(z), index(-1) - { - } - - bool operator==(const Point32& b) const - { - return (x == b.x) && (y == b.y) && (z == b.z); - } - - bool operator!=(const Point32& b) const - { - return (x != b.x) || (y != b.y) || (z != b.z); - } - - bool isZero() - { - return (x == 0) && (y == 0) && (z == 0); - } - - Point64 cross(const Point32& b) const - { - return Point64(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); - } - - Point64 cross(const Point64& b) const - { - return Point64(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); - } - - btInt64_t dot(const Point32& b) const - { - return x * b.x + y * b.y + z * b.z; - } - - btInt64_t dot(const Point64& b) const - { - return x * b.x + y * b.y + z * b.z; - } - - Point32 operator+(const Point32& b) const - { - return Point32(x + b.x, y + b.y, z + b.z); - } - - Point32 operator-(const Point32& b) const - { - return Point32(x - b.x, y - b.y, z - b.z); - } - }; - - class Int128 - { - public: - btUint64_t low; - btUint64_t high; - - Int128() - { - } - - Int128(btUint64_t low, btUint64_t high): low(low), high(high) - { - } - - Int128(btUint64_t low): low(low), high(0) - { - } - - Int128(btInt64_t value): low(value), high((value >= 0) ? 0 : (btUint64_t) -1LL) - { - } - - static Int128 mul(btInt64_t a, btInt64_t b); - - static Int128 mul(btUint64_t a, btUint64_t b); - - Int128 operator-() const - { - return Int128((btUint64_t) -(btInt64_t)low, ~high + (low == 0)); - } - - Int128 operator+(const Int128& b) const - { -#ifdef USE_X86_64_ASM - Int128 result; - __asm__ ("addq %[bl], %[rl]\n\t" - "adcq %[bh], %[rh]\n\t" - : [rl] "=r" (result.low), [rh] "=r" (result.high) - : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) - : "cc" ); - return result; -#else - btUint64_t lo = low + b.low; - return Int128(lo, high + b.high + (lo < low)); -#endif - } - - Int128 operator-(const Int128& b) const - { -#ifdef USE_X86_64_ASM - Int128 result; - __asm__ ("subq %[bl], %[rl]\n\t" - "sbbq %[bh], %[rh]\n\t" - : [rl] "=r" (result.low), [rh] "=r" (result.high) - : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) - : "cc" ); - return result; -#else - return *this + -b; -#endif - } - - Int128& operator+=(const Int128& b) - { -#ifdef USE_X86_64_ASM - __asm__ ("addq %[bl], %[rl]\n\t" - "adcq %[bh], %[rh]\n\t" - : [rl] "=r" (low), [rh] "=r" (high) - : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) - : "cc" ); -#else - btUint64_t lo = low + b.low; - if (lo < low) - { - ++high; - } - low = lo; - high += b.high; -#endif - return *this; - } - - Int128& operator++() - { - if (++low == 0) - { - ++high; - } - return *this; - } - - Int128 operator*(btInt64_t b) const; - - b3Scalar toScalar() const - { - return ((btInt64_t) high >= 0) ? b3Scalar(high) * (b3Scalar(0x100000000LL) * b3Scalar(0x100000000LL)) + b3Scalar(low) - : -(-*this).toScalar(); - } - - int getSign() const - { - return ((btInt64_t) high < 0) ? -1 : (high || low) ? 1 : 0; - } - - bool operator<(const Int128& b) const - { - return (high < b.high) || ((high == b.high) && (low < b.low)); - } - - int ucmp(const Int128&b) const - { - if (high < b.high) - { - return -1; - } - if (high > b.high) - { - return 1; - } - if (low < b.low) - { - return -1; - } - if (low > b.low) - { - return 1; - } - return 0; - } - }; - - - class Rational64 - { - private: - btUint64_t m_numerator; - btUint64_t m_denominator; - int sign; - - public: - Rational64(btInt64_t numerator, btInt64_t denominator) - { - if (numerator > 0) - { - sign = 1; - m_numerator = (btUint64_t) numerator; - } - else if (numerator < 0) - { - sign = -1; - m_numerator = (btUint64_t) -numerator; - } - else - { - sign = 0; - m_numerator = 0; - } - if (denominator > 0) - { - m_denominator = (btUint64_t) denominator; - } - else if (denominator < 0) - { - sign = -sign; - m_denominator = (btUint64_t) -denominator; - } - else - { - m_denominator = 0; - } - } - - bool isNegativeInfinity() const - { - return (sign < 0) && (m_denominator == 0); - } - - bool isNaN() const - { - return (sign == 0) && (m_denominator == 0); - } - - int compare(const Rational64& b) const; - - b3Scalar toScalar() const - { - return sign * ((m_denominator == 0) ? B3_INFINITY : (b3Scalar) m_numerator / m_denominator); - } - }; - - - class Rational128 - { - private: - Int128 numerator; - Int128 denominator; - int sign; - bool isInt64; - - public: - Rational128(btInt64_t value) - { - if (value > 0) - { - sign = 1; - this->numerator = value; - } - else if (value < 0) - { - sign = -1; - this->numerator = -value; - } - else - { - sign = 0; - this->numerator = (btUint64_t) 0; - } - this->denominator = (btUint64_t) 1; - isInt64 = true; - } - - Rational128(const Int128& numerator, const Int128& denominator) - { - sign = numerator.getSign(); - if (sign >= 0) - { - this->numerator = numerator; - } - else - { - this->numerator = -numerator; - } - int dsign = denominator.getSign(); - if (dsign >= 0) - { - this->denominator = denominator; - } - else - { - sign = -sign; - this->denominator = -denominator; - } - isInt64 = false; - } - - int compare(const Rational128& b) const; - - int compare(btInt64_t b) const; - - b3Scalar toScalar() const - { - return sign * ((denominator.getSign() == 0) ? B3_INFINITY : numerator.toScalar() / denominator.toScalar()); - } - }; - - class PointR128 - { - public: - Int128 x; - Int128 y; - Int128 z; - Int128 denominator; - - PointR128() - { - } - - PointR128(Int128 x, Int128 y, Int128 z, Int128 denominator): x(x), y(y), z(z), denominator(denominator) - { - } - - b3Scalar xvalue() const - { - return x.toScalar() / denominator.toScalar(); - } - - b3Scalar yvalue() const - { - return y.toScalar() / denominator.toScalar(); - } - - b3Scalar zvalue() const - { - return z.toScalar() / denominator.toScalar(); - } - }; - - - class Edge; - class Face; - - class Vertex - { - public: - Vertex* next; - Vertex* prev; - Edge* edges; - Face* firstNearbyFace; - Face* lastNearbyFace; - PointR128 point128; - Point32 point; - int copy; - - Vertex(): next(NULL), prev(NULL), edges(NULL), firstNearbyFace(NULL), lastNearbyFace(NULL), copy(-1) - { - } - -#ifdef DEBUG_CONVEX_HULL - void print() - { - b3Printf("V%d (%d, %d, %d)", point.index, point.x, point.y, point.z); - } - - void printGraph(); -#endif - - Point32 operator-(const Vertex& b) const - { - return point - b.point; - } - - Rational128 dot(const Point64& b) const - { - return (point.index >= 0) ? Rational128(point.dot(b)) - : Rational128(point128.x * b.x + point128.y * b.y + point128.z * b.z, point128.denominator); - } - - b3Scalar xvalue() const - { - return (point.index >= 0) ? b3Scalar(point.x) : point128.xvalue(); - } - - b3Scalar yvalue() const - { - return (point.index >= 0) ? b3Scalar(point.y) : point128.yvalue(); - } - - b3Scalar zvalue() const - { - return (point.index >= 0) ? b3Scalar(point.z) : point128.zvalue(); - } - - void receiveNearbyFaces(Vertex* src) - { - if (lastNearbyFace) - { - lastNearbyFace->nextWithSameNearbyVertex = src->firstNearbyFace; - } - else - { - firstNearbyFace = src->firstNearbyFace; - } - if (src->lastNearbyFace) - { - lastNearbyFace = src->lastNearbyFace; - } - for (Face* f = src->firstNearbyFace; f; f = f->nextWithSameNearbyVertex) - { - b3Assert(f->nearbyVertex == src); - f->nearbyVertex = this; - } - src->firstNearbyFace = NULL; - src->lastNearbyFace = NULL; - } - }; - - - class Edge - { - public: - Edge* next; - Edge* prev; - Edge* reverse; - Vertex* target; - Face* face; - int copy; - - ~Edge() - { - next = NULL; - prev = NULL; - reverse = NULL; - target = NULL; - face = NULL; - } - - void link(Edge* n) - { - b3Assert(reverse->target == n->reverse->target); - next = n; - n->prev = this; - } - -#ifdef DEBUG_CONVEX_HULL - void print() - { - b3Printf("E%p : %d -> %d, n=%p p=%p (0 %d\t%d\t%d) -> (%d %d %d)", this, reverse->target->point.index, target->point.index, next, prev, - reverse->target->point.x, reverse->target->point.y, reverse->target->point.z, target->point.x, target->point.y, target->point.z); - } -#endif - }; - - class Face - { - public: - Face* next; - Vertex* nearbyVertex; - Face* nextWithSameNearbyVertex; - Point32 origin; - Point32 dir0; - Point32 dir1; - - Face(): next(NULL), nearbyVertex(NULL), nextWithSameNearbyVertex(NULL) - { - } - - void init(Vertex* a, Vertex* b, Vertex* c) - { - nearbyVertex = a; - origin = a->point; - dir0 = *b - *a; - dir1 = *c - *a; - if (a->lastNearbyFace) - { - a->lastNearbyFace->nextWithSameNearbyVertex = this; - } - else - { - a->firstNearbyFace = this; - } - a->lastNearbyFace = this; - } - - Point64 getNormal() - { - return dir0.cross(dir1); - } - }; - - template class DMul - { - private: - static btUint32_t high(btUint64_t value) - { - return (btUint32_t) (value >> 32); - } - - static btUint32_t low(btUint64_t value) - { - return (btUint32_t) value; - } - - static btUint64_t mul(btUint32_t a, btUint32_t b) - { - return (btUint64_t) a * (btUint64_t) b; - } - - static void shlHalf(btUint64_t& value) - { - value <<= 32; - } - - static btUint64_t high(Int128 value) - { - return value.high; - } - - static btUint64_t low(Int128 value) - { - return value.low; - } - - static Int128 mul(btUint64_t a, btUint64_t b) - { - return Int128::mul(a, b); - } - - static void shlHalf(Int128& value) - { - value.high = value.low; - value.low = 0; - } - - public: - - static void mul(UWord a, UWord b, UWord& resLow, UWord& resHigh) - { - UWord p00 = mul(low(a), low(b)); - UWord p01 = mul(low(a), high(b)); - UWord p10 = mul(high(a), low(b)); - UWord p11 = mul(high(a), high(b)); - UWord p0110 = UWord(low(p01)) + UWord(low(p10)); - p11 += high(p01); - p11 += high(p10); - p11 += high(p0110); - shlHalf(p0110); - p00 += p0110; - if (p00 < p0110) - { - ++p11; - } - resLow = p00; - resHigh = p11; - } - }; - - private: - - class IntermediateHull - { - public: - Vertex* minXy; - Vertex* maxXy; - Vertex* minYx; - Vertex* maxYx; - - IntermediateHull(): minXy(NULL), maxXy(NULL), minYx(NULL), maxYx(NULL) - { - } - - void print(); - }; - - enum Orientation {NONE, CLOCKWISE, COUNTER_CLOCKWISE}; - - template class PoolArray - { - private: - T* array; - int size; - - public: - PoolArray* next; - - PoolArray(int size): size(size), next(NULL) - { - array = (T*) b3AlignedAlloc(sizeof(T) * size, 16); - } - - ~PoolArray() - { - b3AlignedFree(array); - } - - T* init() - { - T* o = array; - for (int i = 0; i < size; i++, o++) - { - o->next = (i+1 < size) ? o + 1 : NULL; - } - return array; - } - }; - - template class Pool - { - private: - PoolArray* arrays; - PoolArray* nextArray; - T* freeObjects; - int arraySize; - - public: - Pool(): arrays(NULL), nextArray(NULL), freeObjects(NULL), arraySize(256) - { - } - - ~Pool() - { - while (arrays) - { - PoolArray* p = arrays; - arrays = p->next; - p->~PoolArray(); - b3AlignedFree(p); - } - } - - void reset() - { - nextArray = arrays; - freeObjects = NULL; - } - - void setArraySize(int arraySize) - { - this->arraySize = arraySize; - } - - T* newObject() - { - T* o = freeObjects; - if (!o) - { - PoolArray* p = nextArray; - if (p) - { - nextArray = p->next; - } - else - { - p = new(b3AlignedAlloc(sizeof(PoolArray), 16)) PoolArray(arraySize); - p->next = arrays; - arrays = p; - } - o = p->init(); - } - freeObjects = o->next; - return new(o) T(); - }; - - void freeObject(T* object) - { - object->~T(); - object->next = freeObjects; - freeObjects = object; - } - }; - - b3Vector3 scaling; - b3Vector3 center; - Pool vertexPool; - Pool edgePool; - Pool facePool; - b3AlignedObjectArray originalVertices; - int mergeStamp; - int minAxis; - int medAxis; - int maxAxis; - int usedEdgePairs; - int maxUsedEdgePairs; - - static Orientation getOrientation(const Edge* prev, const Edge* next, const Point32& s, const Point32& t); - Edge* findMaxAngle(bool ccw, const Vertex* start, const Point32& s, const Point64& rxs, const Point64& sxrxs, Rational64& minCot); - void findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge*& e0, Edge*& e1, Vertex* stop0, Vertex* stop1); - - Edge* newEdgePair(Vertex* from, Vertex* to); - - void removeEdgePair(Edge* edge) - { - Edge* n = edge->next; - Edge* r = edge->reverse; - - b3Assert(edge->target && r->target); - - if (n != edge) - { - n->prev = edge->prev; - edge->prev->next = n; - r->target->edges = n; - } - else - { - r->target->edges = NULL; - } - - n = r->next; - - if (n != r) - { - n->prev = r->prev; - r->prev->next = n; - edge->target->edges = n; - } - else - { - edge->target->edges = NULL; - } - - edgePool.freeObject(edge); - edgePool.freeObject(r); - usedEdgePairs--; } - - void computeInternal(int start, int end, IntermediateHull& result); - - bool mergeProjection(IntermediateHull& h0, IntermediateHull& h1, Vertex*& c0, Vertex*& c1); - - void merge(IntermediateHull& h0, IntermediateHull& h1); - b3Vector3 toBtVector(const Point32& v); + bool isZero() + { + return (x == 0) && (y == 0) && (z == 0); + } - b3Vector3 getBtNormal(Face* face); + btInt64_t dot(const Point64& b) const + { + return x * b.x + y * b.y + z * b.z; + } + }; - bool shiftFace(Face* face, b3Scalar amount, b3AlignedObjectArray stack); + class Point32 + { + public: + btInt32_t x; + btInt32_t y; + btInt32_t z; + int index; + + Point32() + { + } + + Point32(btInt32_t x, btInt32_t y, btInt32_t z) : x(x), y(y), z(z), index(-1) + { + } + + bool operator==(const Point32& b) const + { + return (x == b.x) && (y == b.y) && (z == b.z); + } + + bool operator!=(const Point32& b) const + { + return (x != b.x) || (y != b.y) || (z != b.z); + } + + bool isZero() + { + return (x == 0) && (y == 0) && (z == 0); + } + + Point64 cross(const Point32& b) const + { + return Point64(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); + } + + Point64 cross(const Point64& b) const + { + return Point64(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); + } + + btInt64_t dot(const Point32& b) const + { + return x * b.x + y * b.y + z * b.z; + } + + btInt64_t dot(const Point64& b) const + { + return x * b.x + y * b.y + z * b.z; + } + + Point32 operator+(const Point32& b) const + { + return Point32(x + b.x, y + b.y, z + b.z); + } + + Point32 operator-(const Point32& b) const + { + return Point32(x - b.x, y - b.y, z - b.z); + } + }; + + class Int128 + { + public: + btUint64_t low; + btUint64_t high; + + Int128() + { + } + + Int128(btUint64_t low, btUint64_t high) : low(low), high(high) + { + } + + Int128(btUint64_t low) : low(low), high(0) + { + } + + Int128(btInt64_t value) : low(value), high((value >= 0) ? 0 : (btUint64_t)-1LL) + { + } + + static Int128 mul(btInt64_t a, btInt64_t b); + + static Int128 mul(btUint64_t a, btUint64_t b); + + Int128 operator-() const + { + return Int128((btUint64_t) - (btInt64_t)low, ~high + (low == 0)); + } + + Int128 operator+(const Int128& b) const + { +#ifdef USE_X86_64_ASM + Int128 result; + __asm__( + "addq %[bl], %[rl]\n\t" + "adcq %[bh], %[rh]\n\t" + : [rl] "=r"(result.low), [rh] "=r"(result.high) + : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) + : "cc"); + return result; +#else + btUint64_t lo = low + b.low; + return Int128(lo, high + b.high + (lo < low)); +#endif + } + + Int128 operator-(const Int128& b) const + { +#ifdef USE_X86_64_ASM + Int128 result; + __asm__( + "subq %[bl], %[rl]\n\t" + "sbbq %[bh], %[rh]\n\t" + : [rl] "=r"(result.low), [rh] "=r"(result.high) + : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) + : "cc"); + return result; +#else + return *this + -b; +#endif + } + + Int128& operator+=(const Int128& b) + { +#ifdef USE_X86_64_ASM + __asm__( + "addq %[bl], %[rl]\n\t" + "adcq %[bh], %[rh]\n\t" + : [rl] "=r"(low), [rh] "=r"(high) + : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) + : "cc"); +#else + btUint64_t lo = low + b.low; + if (lo < low) + { + ++high; + } + low = lo; + high += b.high; +#endif + return *this; + } + + Int128& operator++() + { + if (++low == 0) + { + ++high; + } + return *this; + } + + Int128 operator*(btInt64_t b) const; + + b3Scalar toScalar() const + { + return ((btInt64_t)high >= 0) ? b3Scalar(high) * (b3Scalar(0x100000000LL) * b3Scalar(0x100000000LL)) + b3Scalar(low) + : -(-*this).toScalar(); + } + + int getSign() const + { + return ((btInt64_t)high < 0) ? -1 : (high || low) ? 1 : 0; + } + + bool operator<(const Int128& b) const + { + return (high < b.high) || ((high == b.high) && (low < b.low)); + } + + int ucmp(const Int128& b) const + { + if (high < b.high) + { + return -1; + } + if (high > b.high) + { + return 1; + } + if (low < b.low) + { + return -1; + } + if (low > b.low) + { + return 1; + } + return 0; + } + }; + + class Rational64 + { + private: + btUint64_t m_numerator; + btUint64_t m_denominator; + int sign; public: - Vertex* vertexList; + Rational64(btInt64_t numerator, btInt64_t denominator) + { + if (numerator > 0) + { + sign = 1; + m_numerator = (btUint64_t)numerator; + } + else if (numerator < 0) + { + sign = -1; + m_numerator = (btUint64_t)-numerator; + } + else + { + sign = 0; + m_numerator = 0; + } + if (denominator > 0) + { + m_denominator = (btUint64_t)denominator; + } + else if (denominator < 0) + { + sign = -sign; + m_denominator = (btUint64_t)-denominator; + } + else + { + m_denominator = 0; + } + } - void compute(const void* coords, bool doubleCoords, int stride, int count); + bool isNegativeInfinity() const + { + return (sign < 0) && (m_denominator == 0); + } - b3Vector3 getCoordinates(const Vertex* v); + bool isNaN() const + { + return (sign == 0) && (m_denominator == 0); + } - b3Scalar shrink(b3Scalar amount, b3Scalar clampAmount); + int compare(const Rational64& b) const; + + b3Scalar toScalar() const + { + return sign * ((m_denominator == 0) ? B3_INFINITY : (b3Scalar)m_numerator / m_denominator); + } + }; + + class Rational128 + { + private: + Int128 numerator; + Int128 denominator; + int sign; + bool isInt64; + + public: + Rational128(btInt64_t value) + { + if (value > 0) + { + sign = 1; + this->numerator = value; + } + else if (value < 0) + { + sign = -1; + this->numerator = -value; + } + else + { + sign = 0; + this->numerator = (btUint64_t)0; + } + this->denominator = (btUint64_t)1; + isInt64 = true; + } + + Rational128(const Int128& numerator, const Int128& denominator) + { + sign = numerator.getSign(); + if (sign >= 0) + { + this->numerator = numerator; + } + else + { + this->numerator = -numerator; + } + int dsign = denominator.getSign(); + if (dsign >= 0) + { + this->denominator = denominator; + } + else + { + sign = -sign; + this->denominator = -denominator; + } + isInt64 = false; + } + + int compare(const Rational128& b) const; + + int compare(btInt64_t b) const; + + b3Scalar toScalar() const + { + return sign * ((denominator.getSign() == 0) ? B3_INFINITY : numerator.toScalar() / denominator.toScalar()); + } + }; + + class PointR128 + { + public: + Int128 x; + Int128 y; + Int128 z; + Int128 denominator; + + PointR128() + { + } + + PointR128(Int128 x, Int128 y, Int128 z, Int128 denominator) : x(x), y(y), z(z), denominator(denominator) + { + } + + b3Scalar xvalue() const + { + return x.toScalar() / denominator.toScalar(); + } + + b3Scalar yvalue() const + { + return y.toScalar() / denominator.toScalar(); + } + + b3Scalar zvalue() const + { + return z.toScalar() / denominator.toScalar(); + } + }; + + class Edge; + class Face; + + class Vertex + { + public: + Vertex* next; + Vertex* prev; + Edge* edges; + Face* firstNearbyFace; + Face* lastNearbyFace; + PointR128 point128; + Point32 point; + int copy; + + Vertex() : next(NULL), prev(NULL), edges(NULL), firstNearbyFace(NULL), lastNearbyFace(NULL), copy(-1) + { + } + +#ifdef DEBUG_CONVEX_HULL + void print() + { + b3Printf("V%d (%d, %d, %d)", point.index, point.x, point.y, point.z); + } + + void printGraph(); +#endif + + Point32 operator-(const Vertex& b) const + { + return point - b.point; + } + + Rational128 dot(const Point64& b) const + { + return (point.index >= 0) ? Rational128(point.dot(b)) + : Rational128(point128.x * b.x + point128.y * b.y + point128.z * b.z, point128.denominator); + } + + b3Scalar xvalue() const + { + return (point.index >= 0) ? b3Scalar(point.x) : point128.xvalue(); + } + + b3Scalar yvalue() const + { + return (point.index >= 0) ? b3Scalar(point.y) : point128.yvalue(); + } + + b3Scalar zvalue() const + { + return (point.index >= 0) ? b3Scalar(point.z) : point128.zvalue(); + } + + void receiveNearbyFaces(Vertex* src) + { + if (lastNearbyFace) + { + lastNearbyFace->nextWithSameNearbyVertex = src->firstNearbyFace; + } + else + { + firstNearbyFace = src->firstNearbyFace; + } + if (src->lastNearbyFace) + { + lastNearbyFace = src->lastNearbyFace; + } + for (Face* f = src->firstNearbyFace; f; f = f->nextWithSameNearbyVertex) + { + b3Assert(f->nearbyVertex == src); + f->nearbyVertex = this; + } + src->firstNearbyFace = NULL; + src->lastNearbyFace = NULL; + } + }; + + class Edge + { + public: + Edge* next; + Edge* prev; + Edge* reverse; + Vertex* target; + Face* face; + int copy; + + ~Edge() + { + next = NULL; + prev = NULL; + reverse = NULL; + target = NULL; + face = NULL; + } + + void link(Edge* n) + { + b3Assert(reverse->target == n->reverse->target); + next = n; + n->prev = this; + } + +#ifdef DEBUG_CONVEX_HULL + void print() + { + b3Printf("E%p : %d -> %d, n=%p p=%p (0 %d\t%d\t%d) -> (%d %d %d)", this, reverse->target->point.index, target->point.index, next, prev, + reverse->target->point.x, reverse->target->point.y, reverse->target->point.z, target->point.x, target->point.y, target->point.z); + } +#endif + }; + + class Face + { + public: + Face* next; + Vertex* nearbyVertex; + Face* nextWithSameNearbyVertex; + Point32 origin; + Point32 dir0; + Point32 dir1; + + Face() : next(NULL), nearbyVertex(NULL), nextWithSameNearbyVertex(NULL) + { + } + + void init(Vertex* a, Vertex* b, Vertex* c) + { + nearbyVertex = a; + origin = a->point; + dir0 = *b - *a; + dir1 = *c - *a; + if (a->lastNearbyFace) + { + a->lastNearbyFace->nextWithSameNearbyVertex = this; + } + else + { + a->firstNearbyFace = this; + } + a->lastNearbyFace = this; + } + + Point64 getNormal() + { + return dir0.cross(dir1); + } + }; + + template + class DMul + { + private: + static btUint32_t high(btUint64_t value) + { + return (btUint32_t)(value >> 32); + } + + static btUint32_t low(btUint64_t value) + { + return (btUint32_t)value; + } + + static btUint64_t mul(btUint32_t a, btUint32_t b) + { + return (btUint64_t)a * (btUint64_t)b; + } + + static void shlHalf(btUint64_t& value) + { + value <<= 32; + } + + static btUint64_t high(Int128 value) + { + return value.high; + } + + static btUint64_t low(Int128 value) + { + return value.low; + } + + static Int128 mul(btUint64_t a, btUint64_t b) + { + return Int128::mul(a, b); + } + + static void shlHalf(Int128& value) + { + value.high = value.low; + value.low = 0; + } + + public: + static void mul(UWord a, UWord b, UWord& resLow, UWord& resHigh) + { + UWord p00 = mul(low(a), low(b)); + UWord p01 = mul(low(a), high(b)); + UWord p10 = mul(high(a), low(b)); + UWord p11 = mul(high(a), high(b)); + UWord p0110 = UWord(low(p01)) + UWord(low(p10)); + p11 += high(p01); + p11 += high(p10); + p11 += high(p0110); + shlHalf(p0110); + p00 += p0110; + if (p00 < p0110) + { + ++p11; + } + resLow = p00; + resHigh = p11; + } + }; + +private: + class IntermediateHull + { + public: + Vertex* minXy; + Vertex* maxXy; + Vertex* minYx; + Vertex* maxYx; + + IntermediateHull() : minXy(NULL), maxXy(NULL), minYx(NULL), maxYx(NULL) + { + } + + void print(); + }; + + enum Orientation + { + NONE, + CLOCKWISE, + COUNTER_CLOCKWISE + }; + + template + class PoolArray + { + private: + T* array; + int size; + + public: + PoolArray* next; + + PoolArray(int size) : size(size), next(NULL) + { + array = (T*)b3AlignedAlloc(sizeof(T) * size, 16); + } + + ~PoolArray() + { + b3AlignedFree(array); + } + + T* init() + { + T* o = array; + for (int i = 0; i < size; i++, o++) + { + o->next = (i + 1 < size) ? o + 1 : NULL; + } + return array; + } + }; + + template + class Pool + { + private: + PoolArray* arrays; + PoolArray* nextArray; + T* freeObjects; + int arraySize; + + public: + Pool() : arrays(NULL), nextArray(NULL), freeObjects(NULL), arraySize(256) + { + } + + ~Pool() + { + while (arrays) + { + PoolArray* p = arrays; + arrays = p->next; + p->~PoolArray(); + b3AlignedFree(p); + } + } + + void reset() + { + nextArray = arrays; + freeObjects = NULL; + } + + void setArraySize(int arraySize) + { + this->arraySize = arraySize; + } + + T* newObject() + { + T* o = freeObjects; + if (!o) + { + PoolArray* p = nextArray; + if (p) + { + nextArray = p->next; + } + else + { + p = new (b3AlignedAlloc(sizeof(PoolArray), 16)) PoolArray(arraySize); + p->next = arrays; + arrays = p; + } + o = p->init(); + } + freeObjects = o->next; + return new (o) T(); + }; + + void freeObject(T* object) + { + object->~T(); + object->next = freeObjects; + freeObjects = object; + } + }; + + b3Vector3 scaling; + b3Vector3 center; + Pool vertexPool; + Pool edgePool; + Pool facePool; + b3AlignedObjectArray originalVertices; + int mergeStamp; + int minAxis; + int medAxis; + int maxAxis; + int usedEdgePairs; + int maxUsedEdgePairs; + + static Orientation getOrientation(const Edge* prev, const Edge* next, const Point32& s, const Point32& t); + Edge* findMaxAngle(bool ccw, const Vertex* start, const Point32& s, const Point64& rxs, const Point64& sxrxs, Rational64& minCot); + void findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge*& e0, Edge*& e1, Vertex* stop0, Vertex* stop1); + + Edge* newEdgePair(Vertex* from, Vertex* to); + + void removeEdgePair(Edge* edge) + { + Edge* n = edge->next; + Edge* r = edge->reverse; + + b3Assert(edge->target && r->target); + + if (n != edge) + { + n->prev = edge->prev; + edge->prev->next = n; + r->target->edges = n; + } + else + { + r->target->edges = NULL; + } + + n = r->next; + + if (n != r) + { + n->prev = r->prev; + r->prev->next = n; + edge->target->edges = n; + } + else + { + edge->target->edges = NULL; + } + + edgePool.freeObject(edge); + edgePool.freeObject(r); + usedEdgePairs--; + } + + void computeInternal(int start, int end, IntermediateHull& result); + + bool mergeProjection(IntermediateHull& h0, IntermediateHull& h1, Vertex*& c0, Vertex*& c1); + + void merge(IntermediateHull& h0, IntermediateHull& h1); + + b3Vector3 toBtVector(const Point32& v); + + b3Vector3 getBtNormal(Face* face); + + bool shiftFace(Face* face, b3Scalar amount, b3AlignedObjectArray stack); + +public: + Vertex* vertexList; + + void compute(const void* coords, bool doubleCoords, int stride, int count); + + b3Vector3 getCoordinates(const Vertex* v); + + b3Scalar shrink(b3Scalar amount, b3Scalar clampAmount); }; - b3ConvexHullInternal::Int128 b3ConvexHullInternal::Int128::operator*(btInt64_t b) const { - bool negative = (btInt64_t) high < 0; + bool negative = (btInt64_t)high < 0; Int128 a = negative ? -*this : *this; if (b < 0) { negative = !negative; b = -b; } - Int128 result = mul(a.low, (btUint64_t) b); - result.high += a.high * (btUint64_t) b; + Int128 result = mul(a.low, (btUint64_t)b); + result.high += a.high * (btUint64_t)b; return negative ? -result : result; } b3ConvexHullInternal::Int128 b3ConvexHullInternal::Int128::mul(btInt64_t a, btInt64_t b) { Int128 result; - + #ifdef USE_X86_64_ASM - __asm__ ("imulq %[b]" - : "=a" (result.low), "=d" (result.high) - : "0"(a), [b] "r"(b) - : "cc" ); + __asm__("imulq %[b]" + : "=a"(result.low), "=d"(result.high) + : "0"(a), [b] "r"(b) + : "cc"); return result; - + #else bool negative = a < 0; if (negative) @@ -875,7 +876,7 @@ b3ConvexHullInternal::Int128 b3ConvexHullInternal::Int128::mul(btInt64_t a, btIn negative = !negative; b = -b; } - DMul::mul((btUint64_t) a, (btUint64_t) b, result.low, result.high); + DMul::mul((btUint64_t)a, (btUint64_t)b, result.low, result.high); return negative ? -result : result; #endif } @@ -885,10 +886,10 @@ b3ConvexHullInternal::Int128 b3ConvexHullInternal::Int128::mul(btUint64_t a, btU Int128 result; #ifdef USE_X86_64_ASM - __asm__ ("mulq %[b]" - : "=a" (result.low), "=d" (result.high) - : "0"(a), [b] "r"(b) - : "cc" ); + __asm__("mulq %[b]" + : "=a"(result.low), "=d"(result.high) + : "0"(a), [b] "r"(b) + : "cc"); #else DMul::mul(a, b, result.low, result.high); @@ -915,24 +916,25 @@ int b3ConvexHullInternal::Rational64::compare(const Rational64& b) const int result; btInt64_t tmp; btInt64_t dummy; - __asm__ ("mulq %[bn]\n\t" - "movq %%rax, %[tmp]\n\t" - "movq %%rdx, %%rbx\n\t" - "movq %[tn], %%rax\n\t" - "mulq %[bd]\n\t" - "subq %[tmp], %%rax\n\t" - "sbbq %%rbx, %%rdx\n\t" // rdx:rax contains 128-bit-difference "numerator*b.denominator - b.numerator*denominator" - "setnsb %%bh\n\t" // bh=1 if difference is non-negative, bh=0 otherwise - "orq %%rdx, %%rax\n\t" - "setnzb %%bl\n\t" // bl=1 if difference if non-zero, bl=0 if it is zero - "decb %%bh\n\t" // now bx=0x0000 if difference is zero, 0xff01 if it is negative, 0x0001 if it is positive (i.e., same sign as difference) - "shll $16, %%ebx\n\t" // ebx has same sign as difference - : "=&b"(result), [tmp] "=&r"(tmp), "=a"(dummy) - : "a"(denominator), [bn] "g"(b.numerator), [tn] "g"(numerator), [bd] "g"(b.denominator) - : "%rdx", "cc" ); - return result ? result ^ sign // if sign is +1, only bit 0 of result is inverted, which does not change the sign of result (and cannot result in zero) - // if sign is -1, all bits of result are inverted, which changes the sign of result (and again cannot result in zero) - : 0; + __asm__( + "mulq %[bn]\n\t" + "movq %%rax, %[tmp]\n\t" + "movq %%rdx, %%rbx\n\t" + "movq %[tn], %%rax\n\t" + "mulq %[bd]\n\t" + "subq %[tmp], %%rax\n\t" + "sbbq %%rbx, %%rdx\n\t" // rdx:rax contains 128-bit-difference "numerator*b.denominator - b.numerator*denominator" + "setnsb %%bh\n\t" // bh=1 if difference is non-negative, bh=0 otherwise + "orq %%rdx, %%rax\n\t" + "setnzb %%bl\n\t" // bl=1 if difference if non-zero, bl=0 if it is zero + "decb %%bh\n\t" // now bx=0x0000 if difference is zero, 0xff01 if it is negative, 0x0001 if it is positive (i.e., same sign as difference) + "shll $16, %%ebx\n\t" // ebx has same sign as difference + : "=&b"(result), [tmp] "=&r"(tmp), "=a"(dummy) + : "a"(denominator), [bn] "g"(b.numerator), [tn] "g"(numerator), [bd] "g"(b.denominator) + : "%rdx", "cc"); + return result ? result ^ sign // if sign is +1, only bit 0 of result is inverted, which does not change the sign of result (and cannot result in zero) + // if sign is -1, all bits of result are inverted, which changes the sign of result (and again cannot result in zero) + : 0; #else @@ -953,7 +955,7 @@ int b3ConvexHullInternal::Rational128::compare(const Rational128& b) const } if (isInt64) { - return -b.compare(sign * (btInt64_t) numerator.low); + return -b.compare(sign * (btInt64_t)numerator.low); } Int128 nbdLow, nbdHigh, dbnLow, dbnHigh; @@ -972,7 +974,7 @@ int b3ConvexHullInternal::Rational128::compare(btInt64_t b) const { if (isInt64) { - btInt64_t a = sign * (btInt64_t) numerator.low; + btInt64_t a = sign * (btInt64_t)numerator.low; return (a > b) ? 1 : (a < b) ? -1 : 0; } if (b > 0) @@ -998,7 +1000,6 @@ int b3ConvexHullInternal::Rational128::compare(btInt64_t b) const return numerator.ucmp(denominator * b) * sign; } - b3ConvexHullInternal::Edge* b3ConvexHullInternal::newEdgePair(Vertex* from, Vertex* to) { b3Assert(from && to); @@ -1066,7 +1067,7 @@ bool b3ConvexHullInternal::mergeProjection(IntermediateHull& h0, IntermediateHul } } } - + v0 = h0.maxXy; v1 = h1.maxXy; Vertex* v00 = NULL; @@ -1074,7 +1075,7 @@ bool b3ConvexHullInternal::mergeProjection(IntermediateHull& h0, IntermediateHul btInt32_t sign = 1; for (int side = 0; side <= 1; side++) - { + { btInt32_t dx = (v1->point.x - v0->point.x) * sign; if (dx > 0) { @@ -1117,7 +1118,7 @@ bool b3ConvexHullInternal::mergeProjection(IntermediateHull& h0, IntermediateHul while (true) { btInt32_t dy = v1->point.y - v0->point.y; - + Vertex* w1 = side ? v1->prev : v1->next; if (w1 != v1) { @@ -1130,7 +1131,7 @@ bool b3ConvexHullInternal::mergeProjection(IntermediateHull& h0, IntermediateHul continue; } } - + Vertex* w0 = side ? v0->prev : v0->next; if (w0 != v0) { @@ -1144,7 +1145,7 @@ bool b3ConvexHullInternal::mergeProjection(IntermediateHull& h0, IntermediateHul continue; } } - + break; } } @@ -1170,7 +1171,7 @@ bool b3ConvexHullInternal::mergeProjection(IntermediateHull& h0, IntermediateHul } v1 = w1; } - + if (side == 0) { v00 = v0; @@ -1196,7 +1197,7 @@ bool b3ConvexHullInternal::mergeProjection(IntermediateHull& h0, IntermediateHul { h0.maxXy = h1.maxXy; } - + h0.maxYx = h1.maxYx; c0 = v00; @@ -1300,7 +1301,7 @@ void b3ConvexHullInternal::computeInternal(int start, int end, IntermediateHull& } int split0 = start + n / 2; - Point32 p = originalVertices[split0-1]->point; + Point32 p = originalVertices[split0 - 1]->point; int split1 = split0; while ((split1 < end) && (originalVertices[split1]->point == p)) { @@ -1325,7 +1326,7 @@ void b3ConvexHullInternal::computeInternal(int start, int end, IntermediateHull& void b3ConvexHullInternal::IntermediateHull::print() { b3Printf(" Hull\n"); - for (Vertex* v = minXy; v; ) + for (Vertex* v = minXy; v;) { b3Printf(" "); v->print(); @@ -1353,7 +1354,7 @@ void b3ConvexHullInternal::IntermediateHull::print() } } if (minXy) - { + { minXy->copy = (minXy->copy == -1) ? -2 : -1; minXy->printGraph(); } @@ -1429,7 +1430,7 @@ b3ConvexHullInternal::Edge* b3ConvexHullInternal::findMaxAngle(bool ccw, const V Point32 t = *e->target - *start; Rational64 cot(t.dot(sxrxs), t.dot(rxs)); #ifdef DEBUG_CONVEX_HULL - b3Printf(" Angle is %f (%d) for ", (float) b3Atan(cot.toScalar()), (int) cot.isNaN()); + b3Printf(" Angle is %f (%d) for ", (float)b3Atan(cot.toScalar()), (int)cot.isNaN()); e->print(); #endif if (cot.isNaN()) @@ -1476,7 +1477,7 @@ void b3ConvexHullInternal::findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge b3Assert(!start1 || (start1->target->point.dot(normal) == dist)); Point64 perp = s.cross(normal); b3Assert(!perp.isZero()); - + #ifdef DEBUG_CONVEX_HULL b3Printf(" Advancing %d %d (%p %p, %d %d)\n", c0->point.index, c1->point.index, start0, start1, start0 ? start0->target->point.index : -1, start1 ? start1->target->point.index : -1); #endif @@ -1506,7 +1507,7 @@ void b3ConvexHullInternal::findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge et0 = e->target->point; } } - + btInt64_t maxDot1 = et1.dot(perp); if (e1) { @@ -1543,7 +1544,7 @@ void b3ConvexHullInternal::findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge while (true) { btInt64_t dy = (et1 - et0).dot(s); - + if (e0 && (e0->target != stop0)) { Edge* f0 = e0->next->reverse; @@ -1560,7 +1561,7 @@ void b3ConvexHullInternal::findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge } } } - + if (e1 && (e1->target != stop1)) { Edge* f1 = e1->reverse->next; @@ -1595,7 +1596,7 @@ void b3ConvexHullInternal::findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge while (true) { btInt64_t dy = (et1 - et0).dot(s); - + if (e1 && (e1->target != stop1)) { Edge* f1 = e1->prev->reverse; @@ -1612,7 +1613,7 @@ void b3ConvexHullInternal::findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge } } } - + if (e0 && (e0->target != stop0)) { Edge* f0 = e0->reverse->prev; @@ -1647,7 +1648,6 @@ void b3ConvexHullInternal::findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge #endif } - void b3ConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) { if (!h1.maxXy) @@ -1659,7 +1659,7 @@ void b3ConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) h0 = h1; return; } - + mergeStamp--; Vertex* c0 = NULL; @@ -1699,7 +1699,7 @@ void b3ConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) e = e->next; } while (e != c0->edges); } - + e = c1->edges; Edge* start1 = NULL; if (e) @@ -1751,7 +1751,7 @@ void b3ConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) Point32 r = prevPoint - c0->point; Point64 rxs = r.cross(s); Point64 sxrxs = s.cross(rxs); - + #ifdef DEBUG_CONVEX_HULL b3Printf("\n Checking %d %d\n", c0->point.index, c1->point.index); #endif @@ -1802,7 +1802,7 @@ void b3ConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) e->prev = pendingTail1; pendingTail1 = e; } - + Edge* e0 = min0; Edge* e1 = min1; @@ -1819,7 +1819,7 @@ void b3ConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) { if (toPrev1) { - for (Edge* e = toPrev1->next, *n = NULL; e != min1; e = n) + for (Edge *e = toPrev1->next, *n = NULL; e != min1; e = n) { n = e->next; removeEdgePair(e); @@ -1855,7 +1855,7 @@ void b3ConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) { if (toPrev0) { - for (Edge* e = toPrev0->prev, *n = NULL; e != min0; e = n) + for (Edge *e = toPrev0->prev, *n = NULL; e != min0; e = n) { n = e->prev; removeEdgePair(e); @@ -1897,7 +1897,7 @@ void b3ConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) } else { - for (Edge* e = toPrev0->prev, *n = NULL; e != firstNew0; e = n) + for (Edge *e = toPrev0->prev, *n = NULL; e != firstNew0; e = n) { n = e->prev; removeEdgePair(e); @@ -1916,7 +1916,7 @@ void b3ConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) } else { - for (Edge* e = toPrev1->next, *n = NULL; e != firstNew1; e = n) + for (Edge *e = toPrev1->next, *n = NULL; e != firstNew1; e = n) { n = e->next; removeEdgePair(e); @@ -1927,7 +1927,7 @@ void b3ConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) pendingTail1->link(firstNew1); } } - + return; } @@ -1935,7 +1935,6 @@ void b3ConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) } } - static bool b3PointCmp(const b3ConvexHullInternal::Point32& p, const b3ConvexHullInternal::Point32& q) { return (p.y < q.y) || ((p.y == q.y) && ((p.x < q.x) || ((p.x == q.x) && (p.z < q.z)))); @@ -1943,14 +1942,14 @@ static bool b3PointCmp(const b3ConvexHullInternal::Point32& p, const b3ConvexHul void b3ConvexHullInternal::compute(const void* coords, bool doubleCoords, int stride, int count) { - b3Vector3 min = b3MakeVector3(b3Scalar(1e30), b3Scalar(1e30), b3Scalar(1e30)), max = b3MakeVector3(b3Scalar(-1e30), b3Scalar(-1e30), b3Scalar(-1e30)); - const char* ptr = (const char*) coords; + b3Vector3 min = b3MakeVector3(b3Scalar(1e30), b3Scalar(1e30), b3Scalar(1e30)), max = b3MakeVector3(b3Scalar(-1e30), b3Scalar(-1e30), b3Scalar(-1e30)); + const char* ptr = (const char*)coords; if (doubleCoords) { for (int i = 0; i < count; i++) { - const double* v = (const double*) ptr; - b3Vector3 p = b3MakeVector3((b3Scalar) v[0], (b3Scalar) v[1], (b3Scalar) v[2]); + const double* v = (const double*)ptr; + b3Vector3 p = b3MakeVector3((b3Scalar)v[0], (b3Scalar)v[1], (b3Scalar)v[2]); ptr += stride; min.setMin(p); max.setMax(p); @@ -1960,7 +1959,7 @@ void b3ConvexHullInternal::compute(const void* coords, bool doubleCoords, int st { for (int i = 0; i < count; i++) { - const float* v = (const float*) ptr; + const float* v = (const float*)ptr; b3Vector3 p = b3MakeVector3(v[0], v[1], v[2]); ptr += stride; min.setMin(p); @@ -2001,18 +2000,18 @@ void b3ConvexHullInternal::compute(const void* coords, bool doubleCoords, int st b3AlignedObjectArray points; points.resize(count); - ptr = (const char*) coords; + ptr = (const char*)coords; if (doubleCoords) { for (int i = 0; i < count; i++) { - const double* v = (const double*) ptr; - b3Vector3 p = b3MakeVector3((b3Scalar) v[0], (b3Scalar) v[1], (b3Scalar) v[2]); + const double* v = (const double*)ptr; + b3Vector3 p = b3MakeVector3((b3Scalar)v[0], (b3Scalar)v[1], (b3Scalar)v[2]); ptr += stride; p = (p - center) * s; - points[i].x = (btInt32_t) p[medAxis]; - points[i].y = (btInt32_t) p[maxAxis]; - points[i].z = (btInt32_t) p[minAxis]; + points[i].x = (btInt32_t)p[medAxis]; + points[i].y = (btInt32_t)p[maxAxis]; + points[i].z = (btInt32_t)p[minAxis]; points[i].index = i; } } @@ -2020,13 +2019,13 @@ void b3ConvexHullInternal::compute(const void* coords, bool doubleCoords, int st { for (int i = 0; i < count; i++) { - const float* v = (const float*) ptr; + const float* v = (const float*)ptr; b3Vector3 p = b3MakeVector3(v[0], v[1], v[2]); ptr += stride; p = (p - center) * s; - points[i].x = (btInt32_t) p[medAxis]; - points[i].y = (btInt32_t) p[maxAxis]; - points[i].z = (btInt32_t) p[minAxis]; + points[i].x = (btInt32_t)p[medAxis]; + points[i].y = (btInt32_t)p[maxAxis]; + points[i].z = (btInt32_t)p[minAxis]; points[i].index = i; } } @@ -2180,7 +2179,7 @@ b3Scalar b3ConvexHullInternal::shrink(b3Scalar amount, b3Scalar clampAmount) minDist = dist; } } - + if (minDist <= 0) { return 0; @@ -2221,7 +2220,7 @@ bool b3ConvexHullInternal::shiftFace(Face* face, b3Scalar amount, b3AlignedObjec { origShift[2] /= scaling[2]; } - Point32 shift((btInt32_t) origShift[medAxis], (btInt32_t) origShift[maxAxis], (btInt32_t) origShift[minAxis]); + Point32 shift((btInt32_t)origShift[medAxis], (btInt32_t)origShift[maxAxis], (btInt32_t)origShift[minAxis]); if (shift.isZero()) { return true; @@ -2229,7 +2228,7 @@ bool b3ConvexHullInternal::shiftFace(Face* face, b3Scalar amount, b3AlignedObjec Point64 normal = face->getNormal(); #ifdef DEBUG_CONVEX_HULL b3Printf("\nShrinking face (%d %d %d) (%d %d %d) (%d %d %d) by (%d %d %d)\n", - face->origin.x, face->origin.y, face->origin.z, face->dir0.x, face->dir0.y, face->dir0.z, face->dir1.x, face->dir1.y, face->dir1.z, shift.x, shift.y, shift.z); + face->origin.x, face->origin.y, face->origin.z, face->dir0.x, face->dir0.y, face->dir0.z, face->dir1.x, face->dir1.y, face->dir1.z, shift.x, shift.y, shift.z); #endif btInt64_t origDot = face->origin.dot(normal); Point32 shiftedOrigin = face->origin + shift; @@ -2266,7 +2265,7 @@ bool b3ConvexHullInternal::shiftFace(Face* face, b3Scalar amount, b3AlignedObjec #ifdef DEBUG_CONVEX_HULL b3Printf("Moving downwards, edge is "); e->print(); - b3Printf(", dot is %f (%f %lld)\n", (float) dot.toScalar(), (float) optDot.toScalar(), shiftedDot); + b3Printf(", dot is %f (%f %lld)\n", (float)dot.toScalar(), (float)optDot.toScalar(), shiftedDot); #endif if (dot.compare(optDot) < 0) { @@ -2302,7 +2301,7 @@ bool b3ConvexHullInternal::shiftFace(Face* face, b3Scalar amount, b3AlignedObjec #ifdef DEBUG_CONVEX_HULL b3Printf("Moving upwards, edge is "); e->print(); - b3Printf(", dot is %f (%f %lld)\n", (float) dot.toScalar(), (float) optDot.toScalar(), shiftedDot); + b3Printf(", dot is %f (%f %lld)\n", (float)dot.toScalar(), (float)optDot.toScalar(), shiftedDot); #endif if (dot.compare(optDot) > 0) { @@ -2318,7 +2317,7 @@ bool b3ConvexHullInternal::shiftFace(Face* face, b3Scalar amount, b3AlignedObjec } e = e->prev; } while (e != startEdge); - + if (!intersection) { return true; @@ -2355,7 +2354,7 @@ bool b3ConvexHullInternal::shiftFace(Face* face, b3Scalar amount, b3AlignedObjec b3Printf("Needed %d iterations to check for complete containment\n", n); #endif } - + Edge* firstIntersection = NULL; Edge* faceEdge = NULL; Edge* firstFaceEdge = NULL; @@ -2464,7 +2463,7 @@ bool b3ConvexHullInternal::shiftFace(Face* face, b3Scalar amount, b3AlignedObjec #ifdef DEBUG_CONVEX_HULL b3Printf("1: Removed part contains (%d %d %d)\n", removed->point.x, removed->point.y, removed->point.z); #endif - + Point64 n0 = intersection->face->getNormal(); Point64 n1 = intersection->reverse->face->getNormal(); btInt64_t m00 = face->dir0.dot(n0); @@ -2478,16 +2477,13 @@ bool b3ConvexHullInternal::shiftFace(Face* face, b3Scalar amount, b3AlignedObjec Vertex* v = vertexPool.newObject(); v->point.index = -1; v->copy = -1; - v->point128 = PointR128(Int128::mul(face->dir0.x * r0, m11) - Int128::mul(face->dir0.x * r1, m01) - + Int128::mul(face->dir1.x * r1, m00) - Int128::mul(face->dir1.x * r0, m10) + det * shiftedOrigin.x, - Int128::mul(face->dir0.y * r0, m11) - Int128::mul(face->dir0.y * r1, m01) - + Int128::mul(face->dir1.y * r1, m00) - Int128::mul(face->dir1.y * r0, m10) + det * shiftedOrigin.y, - Int128::mul(face->dir0.z * r0, m11) - Int128::mul(face->dir0.z * r1, m01) - + Int128::mul(face->dir1.z * r1, m00) - Int128::mul(face->dir1.z * r0, m10) + det * shiftedOrigin.z, - det); - v->point.x = (btInt32_t) v->point128.xvalue(); - v->point.y = (btInt32_t) v->point128.yvalue(); - v->point.z = (btInt32_t) v->point128.zvalue(); + v->point128 = PointR128(Int128::mul(face->dir0.x * r0, m11) - Int128::mul(face->dir0.x * r1, m01) + Int128::mul(face->dir1.x * r1, m00) - Int128::mul(face->dir1.x * r0, m10) + det * shiftedOrigin.x, + Int128::mul(face->dir0.y * r0, m11) - Int128::mul(face->dir0.y * r1, m01) + Int128::mul(face->dir1.y * r1, m00) - Int128::mul(face->dir1.y * r0, m10) + det * shiftedOrigin.y, + Int128::mul(face->dir0.z * r0, m11) - Int128::mul(face->dir0.z * r1, m01) + Int128::mul(face->dir1.z * r1, m00) - Int128::mul(face->dir1.z * r0, m10) + det * shiftedOrigin.z, + det); + v->point.x = (btInt32_t)v->point128.xvalue(); + v->point.y = (btInt32_t)v->point128.yvalue(); + v->point.z = (btInt32_t)v->point128.zvalue(); intersection->target = v; v->edges = e; @@ -2626,7 +2622,6 @@ bool b3ConvexHullInternal::shiftFace(Face* face, b3Scalar amount, b3AlignedObjec return true; } - static int getVertexCopy(b3ConvexHullInternal::Vertex* vertex, b3AlignedObjectArray& vertices) { int index = vertex->copy; @@ -2748,8 +2743,3 @@ b3Scalar b3ConvexHullComputer::compute(const void* coords, bool doubleCoords, in return shift; } - - - - - diff --git a/src/Bullet3Geometry/b3ConvexHullComputer.h b/src/Bullet3Geometry/b3ConvexHullComputer.h index 6dcc931a7..8852c5a52 100644 --- a/src/Bullet3Geometry/b3ConvexHullComputer.h +++ b/src/Bullet3Geometry/b3ConvexHullComputer.h @@ -23,58 +23,56 @@ subject to the following restrictions: /// Ole Kniemeyer, MAXON Computer GmbH class b3ConvexHullComputer { +private: + b3Scalar compute(const void* coords, bool doubleCoords, int stride, int count, b3Scalar shrink, b3Scalar shrinkClamp); + +public: + class Edge + { private: - b3Scalar compute(const void* coords, bool doubleCoords, int stride, int count, b3Scalar shrink, b3Scalar shrinkClamp); + int next; + int reverse; + int targetVertex; + + friend class b3ConvexHullComputer; public: - - class Edge + int getSourceVertex() const { - private: - int next; - int reverse; - int targetVertex; + return (this + reverse)->targetVertex; + } - friend class b3ConvexHullComputer; + int getTargetVertex() const + { + return targetVertex; + } - public: - int getSourceVertex() const - { - return (this + reverse)->targetVertex; - } + const Edge* getNextEdgeOfVertex() const // clockwise list of all edges of a vertex + { + return this + next; + } - int getTargetVertex() const - { - return targetVertex; - } + const Edge* getNextEdgeOfFace() const // counter-clockwise list of all edges of a face + { + return (this + reverse)->getNextEdgeOfVertex(); + } - const Edge* getNextEdgeOfVertex() const // clockwise list of all edges of a vertex - { - return this + next; - } + const Edge* getReverseEdge() const + { + return this + reverse; + } + }; - const Edge* getNextEdgeOfFace() const // counter-clockwise list of all edges of a face - { - return (this + reverse)->getNextEdgeOfVertex(); - } + // Vertices of the output hull + b3AlignedObjectArray vertices; - const Edge* getReverseEdge() const - { - return this + reverse; - } - }; + // Edges of the output hull + b3AlignedObjectArray edges; + // Faces of the convex hull. Each entry is an index into the "edges" array pointing to an edge of the face. Faces are planar n-gons + b3AlignedObjectArray faces; - // Vertices of the output hull - b3AlignedObjectArray vertices; - - // Edges of the output hull - b3AlignedObjectArray edges; - - // Faces of the convex hull. Each entry is an index into the "edges" array pointing to an edge of the face. Faces are planar n-gons - b3AlignedObjectArray faces; - - /* + /* Compute convex hull of "count" vertices stored in "coords". "stride" is the difference in bytes between the addresses of consecutive vertices. If "shrink" is positive, the convex hull is shrunken by that amount (each face is moved by "shrink" length units towards the center along its normal). @@ -86,18 +84,16 @@ class b3ConvexHullComputer The output convex hull can be found in the member variables "vertices", "edges", "faces". */ - b3Scalar compute(const float* coords, int stride, int count, b3Scalar shrink, b3Scalar shrinkClamp) - { - return compute(coords, false, stride, count, shrink, shrinkClamp); - } + b3Scalar compute(const float* coords, int stride, int count, b3Scalar shrink, b3Scalar shrinkClamp) + { + return compute(coords, false, stride, count, shrink, shrinkClamp); + } - // same as above, but double precision - b3Scalar compute(const double* coords, int stride, int count, b3Scalar shrink, b3Scalar shrinkClamp) - { - return compute(coords, true, stride, count, shrink, shrinkClamp); - } + // same as above, but double precision + b3Scalar compute(const double* coords, int stride, int count, b3Scalar shrink, b3Scalar shrinkClamp) + { + return compute(coords, true, stride, count, shrink, shrinkClamp); + } }; - -#endif //B3_CONVEX_HULL_COMPUTER_H - +#endif //B3_CONVEX_HULL_COMPUTER_H diff --git a/src/Bullet3Geometry/b3GeometryUtil.cpp b/src/Bullet3Geometry/b3GeometryUtil.cpp index dd80fed6b..c4041003c 100644 --- a/src/Bullet3Geometry/b3GeometryUtil.cpp +++ b/src/Bullet3Geometry/b3GeometryUtil.cpp @@ -12,49 +12,43 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "b3GeometryUtil.h" - /* Make sure this dummy function never changes so that it can be used by probes that are checking whether the library is actually installed. */ extern "C" -{ - void b3BulletMathProbe (); +{ + void b3BulletMathProbe(); - void b3BulletMathProbe () {} + void b3BulletMathProbe() {} } - -bool b3GeometryUtil::isPointInsidePlanes(const b3AlignedObjectArray& planeEquations, const b3Vector3& point, b3Scalar margin) +bool b3GeometryUtil::isPointInsidePlanes(const b3AlignedObjectArray& planeEquations, const b3Vector3& point, b3Scalar margin) { int numbrushes = planeEquations.size(); - for (int i=0;ib3Scalar(0.)) + b3Scalar dist = b3Scalar(N1.dot(point)) + b3Scalar(N1[3]) - margin; + if (dist > b3Scalar(0.)) { return false; } } return true; - } - -bool b3GeometryUtil::areVerticesBehindPlane(const b3Vector3& planeNormal, const b3AlignedObjectArray& vertices, b3Scalar margin) +bool b3GeometryUtil::areVerticesBehindPlane(const b3Vector3& planeNormal, const b3AlignedObjectArray& vertices, b3Scalar margin) { int numvertices = vertices.size(); - for (int i=0;ib3Scalar(0.)) + b3Scalar dist = b3Scalar(planeNormal.dot(N1)) + b3Scalar(planeNormal[3]) - margin; + if (dist > b3Scalar(0.)) { return false; } @@ -62,102 +56,98 @@ bool b3GeometryUtil::areVerticesBehindPlane(const b3Vector3& planeNormal, const return true; } -bool notExist(const b3Vector3& planeEquation,const b3AlignedObjectArray& planeEquations); +bool notExist(const b3Vector3& planeEquation, const b3AlignedObjectArray& planeEquations); -bool notExist(const b3Vector3& planeEquation,const b3AlignedObjectArray& planeEquations) +bool notExist(const b3Vector3& planeEquation, const b3AlignedObjectArray& planeEquations) { int numbrushes = planeEquations.size(); - for (int i=0;i b3Scalar(0.999)) { return false; - } + } } return true; } -void b3GeometryUtil::getPlaneEquationsFromVertices(b3AlignedObjectArray& vertices, b3AlignedObjectArray& planeEquationsOut ) +void b3GeometryUtil::getPlaneEquationsFromVertices(b3AlignedObjectArray& vertices, b3AlignedObjectArray& planeEquationsOut) { - const int numvertices = vertices.size(); + const int numvertices = vertices.size(); // brute force: - for (int i=0;i b3Scalar(0.0001)) { planeEquation.normalize(); - if (notExist(planeEquation,planeEquationsOut)) + if (notExist(planeEquation, planeEquationsOut)) { planeEquation[3] = -planeEquation.dot(N1); - - //check if inside, and replace supportingVertexOut if needed - if (areVerticesBehindPlane(planeEquation,vertices,b3Scalar(0.01))) - { - planeEquationsOut.push_back(planeEquation); - } + + //check if inside, and replace supportingVertexOut if needed + if (areVerticesBehindPlane(planeEquation, vertices, b3Scalar(0.01))) + { + planeEquationsOut.push_back(planeEquation); + } } } normalSign = b3Scalar(-1.); } - } } } - } -void b3GeometryUtil::getVerticesFromPlaneEquations(const b3AlignedObjectArray& planeEquations , b3AlignedObjectArray& verticesOut ) +void b3GeometryUtil::getVerticesFromPlaneEquations(const b3AlignedObjectArray& planeEquations, b3AlignedObjectArray& verticesOut) { const int numbrushes = planeEquations.size(); // brute force: - for (int i=0;i b3Scalar(0.0001) ) && - ( n3n1.length2() > b3Scalar(0.0001) ) && - ( n1n2.length2() > b3Scalar(0.0001) ) ) + b3Vector3 n2n3; + n2n3 = N2.cross(N3); + b3Vector3 n3n1; + n3n1 = N3.cross(N1); + b3Vector3 n1n2; + n1n2 = N1.cross(N2); + + if ((n2n3.length2() > b3Scalar(0.0001)) && + (n3n1.length2() > b3Scalar(0.0001)) && + (n1n2.length2() > b3Scalar(0.0001))) { //point P out of 3 plane equations: - // d1 ( N2 * N3 ) + d2 ( N3 * N1 ) + d3 ( N1 * N2 ) - //P = ------------------------------------------------------------------------- - // N1 . ( N2 * N3 ) - + // d1 ( N2 * N3 ) + d2 ( N3 * N1 ) + d3 ( N1 * N2 ) + //P = ------------------------------------------------------------------------- + // N1 . ( N2 * N3 ) b3Scalar quotient = (N1.dot(n2n3)); if (b3Fabs(quotient) > b3Scalar(0.000001)) @@ -172,7 +162,7 @@ void b3GeometryUtil::getVerticesFromPlaneEquations(const b3AlignedObjectArray& vertices, b3AlignedObjectArray& planeEquationsOut ); +public: + static void getPlaneEquationsFromVertices(b3AlignedObjectArray& vertices, b3AlignedObjectArray& planeEquationsOut); - static void getVerticesFromPlaneEquations(const b3AlignedObjectArray& planeEquations , b3AlignedObjectArray& verticesOut ); - - static bool isInside(const b3AlignedObjectArray& vertices, const b3Vector3& planeNormal, b3Scalar margin); - - static bool isPointInsidePlanes(const b3AlignedObjectArray& planeEquations, const b3Vector3& point, b3Scalar margin); + static void getVerticesFromPlaneEquations(const b3AlignedObjectArray& planeEquations, b3AlignedObjectArray& verticesOut); - static bool areVerticesBehindPlane(const b3Vector3& planeNormal, const b3AlignedObjectArray& vertices, b3Scalar margin); + static bool isInside(const b3AlignedObjectArray& vertices, const b3Vector3& planeNormal, b3Scalar margin); + static bool isPointInsidePlanes(const b3AlignedObjectArray& planeEquations, const b3Vector3& point, b3Scalar margin); + + static bool areVerticesBehindPlane(const b3Vector3& planeNormal, const b3AlignedObjectArray& vertices, b3Scalar margin); }; - -#endif //B3_GEOMETRY_UTIL_H - +#endif //B3_GEOMETRY_UTIL_H diff --git a/src/Bullet3Geometry/b3GrahamScan2dConvexHull.h b/src/Bullet3Geometry/b3GrahamScan2dConvexHull.h index 1b933c526..8881c9a63 100644 --- a/src/Bullet3Geometry/b3GrahamScan2dConvexHull.h +++ b/src/Bullet3Geometry/b3GrahamScan2dConvexHull.h @@ -13,41 +13,40 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef B3_GRAHAM_SCAN_2D_CONVEX_HULL_H #define B3_GRAHAM_SCAN_2D_CONVEX_HULL_H - #include "Bullet3Common/b3Vector3.h" #include "Bullet3Common/b3AlignedObjectArray.h" struct b3GrahamVector3 : public b3Vector3 { b3GrahamVector3(const b3Vector3& org, int orgIndex) - :b3Vector3(org), - m_orgIndex(orgIndex) + : b3Vector3(org), + m_orgIndex(orgIndex) { } - b3Scalar m_angle; + b3Scalar m_angle; int m_orgIndex; }; - -struct b3AngleCompareFunc { +struct b3AngleCompareFunc +{ b3Vector3 m_anchor; b3AngleCompareFunc(const b3Vector3& anchor) - : m_anchor(anchor) + : m_anchor(anchor) { } - bool operator()(const b3GrahamVector3& a, const b3GrahamVector3& b) const { + bool operator()(const b3GrahamVector3& a, const b3GrahamVector3& b) const + { if (a.m_angle != b.m_angle) return a.m_angle < b.m_angle; else { - b3Scalar al = (a-m_anchor).length2(); - b3Scalar bl = (b-m_anchor).length2(); + b3Scalar al = (a - m_anchor).length2(); + b3Scalar bl = (b - m_anchor).length2(); if (al != bl) - return al < bl; + return al < bl; else { return a.m_orgIndex < b.m_orgIndex; @@ -58,60 +57,60 @@ struct b3AngleCompareFunc { inline void b3GrahamScanConvexHull2D(b3AlignedObjectArray& originalPoints, b3AlignedObjectArray& hull, const b3Vector3& normalAxis) { - b3Vector3 axis0,axis1; - b3PlaneSpace1(normalAxis,axis0,axis1); - + b3Vector3 axis0, axis1; + b3PlaneSpace1(normalAxis, axis0, axis1); - if (originalPoints.size()<=1) + if (originalPoints.size() <= 1) { - for (int i=0;i1) { - b3Vector3& a = hull[hull.size()-2]; - b3Vector3& b = hull[hull.size()-1]; - isConvex = b3Cross(a-b,a-originalPoints[i]).dot(normalAxis)> 0; + while (!isConvex && hull.size() > 1) + { + b3Vector3& a = hull[hull.size() - 2]; + b3Vector3& b = hull[hull.size() - 1]; + isConvex = b3Cross(a - b, a - originalPoints[i]).dot(normalAxis) > 0; if (!isConvex) hull.pop_back(); - else + else hull.push_back(originalPoints[i]); } } } -#endif //B3_GRAHAM_SCAN_2D_CONVEX_HULL_H +#endif //B3_GRAHAM_SCAN_2D_CONVEX_HULL_H diff --git a/src/Bullet3OpenCL/BroadphaseCollision/b3GpuBroadphaseInterface.h b/src/Bullet3OpenCL/BroadphaseCollision/b3GpuBroadphaseInterface.h index 0ed8aa823..b29699252 100644 --- a/src/Bullet3OpenCL/BroadphaseCollision/b3GpuBroadphaseInterface.h +++ b/src/Bullet3OpenCL/BroadphaseCollision/b3GpuBroadphaseInterface.h @@ -12,33 +12,31 @@ class b3GpuBroadphaseInterface { public: - - typedef class b3GpuBroadphaseInterface* (CreateFunc)(cl_context ctx,cl_device_id device, cl_command_queue q); + typedef class b3GpuBroadphaseInterface*(CreateFunc)(cl_context ctx, cl_device_id device, cl_command_queue q); virtual ~b3GpuBroadphaseInterface() { } - virtual void createProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr , int collisionFilterGroup, int collisionFilterMask)=0; - virtual void createLargeProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr , int collisionFilterGroup, int collisionFilterMask)=0; + virtual void createProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr, int collisionFilterGroup, int collisionFilterMask) = 0; + virtual void createLargeProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr, int collisionFilterGroup, int collisionFilterMask) = 0; - virtual void calculateOverlappingPairs(int maxPairs)=0; - virtual void calculateOverlappingPairsHost(int maxPairs)=0; + virtual void calculateOverlappingPairs(int maxPairs) = 0; + virtual void calculateOverlappingPairsHost(int maxPairs) = 0; //call writeAabbsToGpu after done making all changes (createProxy etc) - virtual void writeAabbsToGpu()=0; + virtual void writeAabbsToGpu() = 0; - virtual cl_mem getAabbBufferWS()=0; - virtual int getNumOverlap()=0; - virtual cl_mem getOverlappingPairBuffer()=0; + virtual cl_mem getAabbBufferWS() = 0; + virtual int getNumOverlap() = 0; + virtual cl_mem getOverlappingPairBuffer() = 0; + + virtual b3OpenCLArray& getAllAabbsGPU() = 0; + virtual b3AlignedObjectArray& getAllAabbsCPU() = 0; - virtual b3OpenCLArray& getAllAabbsGPU()=0; - virtual b3AlignedObjectArray& getAllAabbsCPU()=0; - virtual b3OpenCLArray& getOverlappingPairsGPU() = 0; virtual b3OpenCLArray& getSmallAabbIndicesGPU() = 0; virtual b3OpenCLArray& getLargeAabbIndicesGPU() = 0; - }; -#endif //B3_GPU_BROADPHASE_INTERFACE_H +#endif //B3_GPU_BROADPHASE_INTERFACE_H diff --git a/src/Bullet3OpenCL/BroadphaseCollision/b3GpuGridBroadphase.cpp b/src/Bullet3OpenCL/BroadphaseCollision/b3GpuGridBroadphase.cpp index 74d0c8056..e714fadac 100644 --- a/src/Bullet3OpenCL/BroadphaseCollision/b3GpuGridBroadphase.cpp +++ b/src/Bullet3OpenCL/BroadphaseCollision/b3GpuGridBroadphase.cpp @@ -5,12 +5,9 @@ #include "kernels/sapKernels.h" //#include "kernels/gridBroadphase.cl" - #include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h" #include "Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h" - - #define B3_BROADPHASE_SAP_PATH "src/Bullet3OpenCL/BroadphaseCollision/kernels/sap.cl" #define B3_GRID_BROADPHASE_PATH "src/Bullet3OpenCL/BroadphaseCollision/kernels/gridBroadphase.cl" @@ -21,31 +18,25 @@ cl_kernel kFindOverlappingPairs; cl_kernel m_copyAabbsKernel; cl_kernel m_sap2Kernel; - - - - //int maxPairsPerBody = 64; -int maxBodiesPerCell = 256;//?? +int maxBodiesPerCell = 256; //?? -b3GpuGridBroadphase::b3GpuGridBroadphase(cl_context ctx,cl_device_id device, cl_command_queue q ) -:m_context(ctx), -m_device(device), -m_queue(q), -m_allAabbsGPU1(ctx,q), -m_smallAabbsMappingGPU(ctx,q), -m_largeAabbsMappingGPU(ctx,q), -m_gpuPairs(ctx,q), +b3GpuGridBroadphase::b3GpuGridBroadphase(cl_context ctx, cl_device_id device, cl_command_queue q) + : m_context(ctx), + m_device(device), + m_queue(q), + m_allAabbsGPU1(ctx, q), + m_smallAabbsMappingGPU(ctx, q), + m_largeAabbsMappingGPU(ctx, q), + m_gpuPairs(ctx, q), -m_hashGpu(ctx,q), + m_hashGpu(ctx, q), -m_cellStartGpu(ctx,q), -m_paramsGPU(ctx,q) + m_cellStartGpu(ctx, q), + m_paramsGPU(ctx, q) { - - - b3Vector3 gridSize = b3MakeVector3(3,3,3); - b3Vector3 invGridSize = b3MakeVector3(1.f/gridSize[0],1.f/gridSize[1],1.f/gridSize[2]); + b3Vector3 gridSize = b3MakeVector3(3, 3, 3); + b3Vector3 invGridSize = b3MakeVector3(1.f / gridSize[0], 1.f / gridSize[1], 1.f / gridSize[2]); m_paramsCPU.m_gridSize[0] = 128; m_paramsCPU.m_gridSize[1] = 128; @@ -58,92 +49,79 @@ m_paramsGPU(ctx,q) m_paramsCPU.m_invCellSize[3] = 0.f; m_paramsGPU.push_back(m_paramsCPU); - cl_int errNum=0; + cl_int errNum = 0; { const char* sapSrc = sapCL; - cl_program sapProg = b3OpenCLUtils::compileCLProgramFromString(m_context,m_device,sapSrc,&errNum,"",B3_BROADPHASE_SAP_PATH); - b3Assert(errNum==CL_SUCCESS); - m_copyAabbsKernel= b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,sapSrc, "copyAabbsKernel",&errNum,sapProg ); - m_sap2Kernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,sapSrc, "computePairsKernelTwoArrays",&errNum,sapProg ); - b3Assert(errNum==CL_SUCCESS); + cl_program sapProg = b3OpenCLUtils::compileCLProgramFromString(m_context, m_device, sapSrc, &errNum, "", B3_BROADPHASE_SAP_PATH); + b3Assert(errNum == CL_SUCCESS); + m_copyAabbsKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, sapSrc, "copyAabbsKernel", &errNum, sapProg); + m_sap2Kernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, sapSrc, "computePairsKernelTwoArrays", &errNum, sapProg); + b3Assert(errNum == CL_SUCCESS); } { - - cl_program gridProg = b3OpenCLUtils::compileCLProgramFromString(m_context,m_device,gridBroadphaseCL,&errNum,"",B3_GRID_BROADPHASE_PATH); - b3Assert(errNum==CL_SUCCESS); + cl_program gridProg = b3OpenCLUtils::compileCLProgramFromString(m_context, m_device, gridBroadphaseCL, &errNum, "", B3_GRID_BROADPHASE_PATH); + b3Assert(errNum == CL_SUCCESS); - kCalcHashAABB = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,gridBroadphaseCL, "kCalcHashAABB",&errNum,gridProg); - b3Assert(errNum==CL_SUCCESS); - - kClearCellStart = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,gridBroadphaseCL, "kClearCellStart",&errNum,gridProg); - b3Assert(errNum==CL_SUCCESS); + kCalcHashAABB = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, gridBroadphaseCL, "kCalcHashAABB", &errNum, gridProg); + b3Assert(errNum == CL_SUCCESS); - kFindCellStart = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,gridBroadphaseCL, "kFindCellStart",&errNum,gridProg); - b3Assert(errNum==CL_SUCCESS); + kClearCellStart = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, gridBroadphaseCL, "kClearCellStart", &errNum, gridProg); + b3Assert(errNum == CL_SUCCESS); - - kFindOverlappingPairs = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,gridBroadphaseCL, "kFindOverlappingPairs",&errNum,gridProg); - b3Assert(errNum==CL_SUCCESS); + kFindCellStart = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, gridBroadphaseCL, "kFindCellStart", &errNum, gridProg); + b3Assert(errNum == CL_SUCCESS); - - - + kFindOverlappingPairs = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, gridBroadphaseCL, "kFindOverlappingPairs", &errNum, gridProg); + b3Assert(errNum == CL_SUCCESS); } - m_sorter = new b3RadixSort32CL(m_context,m_device,m_queue); - + m_sorter = new b3RadixSort32CL(m_context, m_device, m_queue); } b3GpuGridBroadphase::~b3GpuGridBroadphase() { - clReleaseKernel( kCalcHashAABB); - clReleaseKernel( kClearCellStart); - clReleaseKernel( kFindCellStart); - clReleaseKernel( kFindOverlappingPairs); - clReleaseKernel( m_sap2Kernel); - clReleaseKernel( m_copyAabbsKernel); - - - + clReleaseKernel(kCalcHashAABB); + clReleaseKernel(kClearCellStart); + clReleaseKernel(kFindCellStart); + clReleaseKernel(kFindOverlappingPairs); + clReleaseKernel(m_sap2Kernel); + clReleaseKernel(m_copyAabbsKernel); + delete m_sorter; } - - -void b3GpuGridBroadphase::createProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr , int collisionFilterGroup, int collisionFilterMask) +void b3GpuGridBroadphase::createProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr, int collisionFilterGroup, int collisionFilterMask) { b3SapAabb aabb; aabb.m_minVec = aabbMin; aabb.m_maxVec = aabbMax; aabb.m_minIndices[3] = userPtr; - aabb.m_signedMaxIndices[3] = m_allAabbsCPU1.size();//NOT userPtr; + aabb.m_signedMaxIndices[3] = m_allAabbsCPU1.size(); //NOT userPtr; m_smallAabbsMappingCPU.push_back(m_allAabbsCPU1.size()); m_allAabbsCPU1.push_back(aabb); - } -void b3GpuGridBroadphase::createLargeProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr , int collisionFilterGroup, int collisionFilterMask) +void b3GpuGridBroadphase::createLargeProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr, int collisionFilterGroup, int collisionFilterMask) { b3SapAabb aabb; aabb.m_minVec = aabbMin; aabb.m_maxVec = aabbMax; aabb.m_minIndices[3] = userPtr; - aabb.m_signedMaxIndices[3] = m_allAabbsCPU1.size();//NOT userPtr; + aabb.m_signedMaxIndices[3] = m_allAabbsCPU1.size(); //NOT userPtr; m_largeAabbsMappingCPU.push_back(m_allAabbsCPU1.size()); m_allAabbsCPU1.push_back(aabb); } -void b3GpuGridBroadphase::calculateOverlappingPairs(int maxPairs) +void b3GpuGridBroadphase::calculateOverlappingPairs(int maxPairs) { B3_PROFILE("b3GpuGridBroadphase::calculateOverlappingPairs"); - if (0) { calculateOverlappingPairsHost(maxPairs); - /* + /* b3AlignedObjectArray cpuPairs; m_gpuPairs.copyToHost(cpuPairs); printf("host m_gpuPairs.size()=%d\n",m_gpuPairs.size()); @@ -154,57 +132,50 @@ void b3GpuGridBroadphase::calculateOverlappingPairs(int maxPairs) */ return; } - - - - int numSmallAabbs = m_smallAabbsMappingGPU.size(); - b3OpenCLArray pairCount(m_context,m_queue); + b3OpenCLArray pairCount(m_context, m_queue); pairCount.push_back(0); - m_gpuPairs.resize(maxPairs);//numSmallAabbs*maxPairsPerBody); + m_gpuPairs.resize(maxPairs); //numSmallAabbs*maxPairsPerBody); { int numLargeAabbs = m_largeAabbsMappingGPU.size(); if (numLargeAabbs && numSmallAabbs) { B3_PROFILE("sap2Kernel"); - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( m_allAabbsGPU1.getBufferCL() ), - b3BufferInfoCL( m_largeAabbsMappingGPU.getBufferCL() ), - b3BufferInfoCL( m_smallAabbsMappingGPU.getBufferCL() ), - b3BufferInfoCL( m_gpuPairs.getBufferCL() ), + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(m_allAabbsGPU1.getBufferCL()), + b3BufferInfoCL(m_largeAabbsMappingGPU.getBufferCL()), + b3BufferInfoCL(m_smallAabbsMappingGPU.getBufferCL()), + b3BufferInfoCL(m_gpuPairs.getBufferCL()), b3BufferInfoCL(pairCount.getBufferCL())}; - b3LauncherCL launcher(m_queue, m_sap2Kernel,"m_sap2Kernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( numLargeAabbs ); - launcher.setConst( numSmallAabbs); - launcher.setConst( 0 );//axis is not used - launcher.setConst( maxPairs ); - //@todo: use actual maximum work item sizes of the device instead of hardcoded values - launcher.launch2D( numLargeAabbs, numSmallAabbs,4,64); - + b3LauncherCL launcher(m_queue, m_sap2Kernel, "m_sap2Kernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(numLargeAabbs); + launcher.setConst(numSmallAabbs); + launcher.setConst(0); //axis is not used + launcher.setConst(maxPairs); + //@todo: use actual maximum work item sizes of the device instead of hardcoded values + launcher.launch2D(numLargeAabbs, numSmallAabbs, 4, 64); + int numPairs = pairCount.at(0); - - if (numPairs >maxPairs) + + if (numPairs > maxPairs) { b3Error("Error running out of pairs: numPairs = %d, maxPairs = %d.\n", numPairs, maxPairs); - numPairs =maxPairs; + numPairs = maxPairs; } } } - - - if (numSmallAabbs) { B3_PROFILE("gridKernel"); m_hashGpu.resize(numSmallAabbs); { B3_PROFILE("kCalcHashAABB"); - b3LauncherCL launch(m_queue,kCalcHashAABB,"kCalcHashAABB"); + b3LauncherCL launch(m_queue, kCalcHashAABB, "kCalcHashAABB"); launch.setConst(numSmallAabbs); launch.setBuffer(m_allAabbsGPU1.getBufferCL()); launch.setBuffer(m_smallAabbsMappingGPU.getBufferCL()); @@ -214,117 +185,104 @@ void b3GpuGridBroadphase::calculateOverlappingPairs(int maxPairs) } m_sorter->execute(m_hashGpu); - - int numCells = this->m_paramsCPU.m_gridSize[0]*this->m_paramsCPU.m_gridSize[1]*this->m_paramsCPU.m_gridSize[2]; + + int numCells = this->m_paramsCPU.m_gridSize[0] * this->m_paramsCPU.m_gridSize[1] * this->m_paramsCPU.m_gridSize[2]; m_cellStartGpu.resize(numCells); //b3AlignedObjectArray cellStartCpu; - - + { B3_PROFILE("kClearCellStart"); - b3LauncherCL launch(m_queue,kClearCellStart,"kClearCellStart"); + b3LauncherCL launch(m_queue, kClearCellStart, "kClearCellStart"); launch.setConst(numCells); launch.setBuffer(m_cellStartGpu.getBufferCL()); launch.launch1D(numCells); //m_cellStartGpu.copyToHost(cellStartCpu); //printf("??\n"); - } - { B3_PROFILE("kFindCellStart"); - b3LauncherCL launch(m_queue,kFindCellStart,"kFindCellStart"); + b3LauncherCL launch(m_queue, kFindCellStart, "kFindCellStart"); launch.setConst(numSmallAabbs); launch.setBuffer(m_hashGpu.getBufferCL()); launch.setBuffer(m_cellStartGpu.getBufferCL()); launch.launch1D(numSmallAabbs); //m_cellStartGpu.copyToHost(cellStartCpu); //printf("??\n"); - } - + { B3_PROFILE("kFindOverlappingPairs"); - - - b3LauncherCL launch(m_queue,kFindOverlappingPairs,"kFindOverlappingPairs"); + + b3LauncherCL launch(m_queue, kFindOverlappingPairs, "kFindOverlappingPairs"); launch.setConst(numSmallAabbs); launch.setBuffer(m_allAabbsGPU1.getBufferCL()); launch.setBuffer(m_smallAabbsMappingGPU.getBufferCL()); launch.setBuffer(m_hashGpu.getBufferCL()); launch.setBuffer(m_cellStartGpu.getBufferCL()); - + launch.setBuffer(m_paramsGPU.getBufferCL()); //launch.setBuffer(0); launch.setBuffer(pairCount.getBufferCL()); launch.setBuffer(m_gpuPairs.getBufferCL()); - + launch.setConst(maxPairs); launch.launch1D(numSmallAabbs); - int numPairs = pairCount.at(0); - if (numPairs >maxPairs) + if (numPairs > maxPairs) { b3Error("Error running out of pairs: numPairs = %d, maxPairs = %d.\n", numPairs, maxPairs); - numPairs =maxPairs; + numPairs = maxPairs; } - + m_gpuPairs.resize(numPairs); - + if (0) { b3AlignedObjectArray pairsCpu; m_gpuPairs.copyToHost(pairsCpu); int sz = m_gpuPairs.size(); - printf("m_gpuPairs.size()=%d\n",sz); - for (int i=0;im_allAabbsGPU1.getBufferCL(); } -int b3GpuGridBroadphase::getNumOverlap() +int b3GpuGridBroadphase::getNumOverlap() { return m_gpuPairs.size(); } -cl_mem b3GpuGridBroadphase::getOverlappingPairBuffer() +cl_mem b3GpuGridBroadphase::getOverlappingPairBuffer() { return m_gpuPairs.getBufferCL(); } -b3OpenCLArray& b3GpuGridBroadphase::getAllAabbsGPU() +b3OpenCLArray& b3GpuGridBroadphase::getAllAabbsGPU() { return m_allAabbsGPU1; } -b3AlignedObjectArray& b3GpuGridBroadphase::getAllAabbsCPU() +b3AlignedObjectArray& b3GpuGridBroadphase::getAllAabbsCPU() { return m_allAabbsCPU1; } @@ -382,4 +336,3 @@ b3OpenCLArray& b3GpuGridBroadphase::getLargeAabbIndicesGPU() { return m_largeAabbsMappingGPU; } - diff --git a/src/Bullet3OpenCL/BroadphaseCollision/b3GpuGridBroadphase.h b/src/Bullet3OpenCL/BroadphaseCollision/b3GpuGridBroadphase.h index ec18c9f71..b76cb43b6 100644 --- a/src/Bullet3OpenCL/BroadphaseCollision/b3GpuGridBroadphase.h +++ b/src/Bullet3OpenCL/BroadphaseCollision/b3GpuGridBroadphase.h @@ -6,83 +6,75 @@ struct b3ParamsGridBroadphaseCL { - float m_invCellSize[4]; - int m_gridSize[4]; + int m_gridSize[4]; - int getMaxBodiesPerCell() const + int getMaxBodiesPerCell() const { return m_gridSize[3]; } - void setMaxBodiesPerCell(int maxOverlap) + void setMaxBodiesPerCell(int maxOverlap) { m_gridSize[3] = maxOverlap; } }; - class b3GpuGridBroadphase : public b3GpuBroadphaseInterface { protected: - cl_context m_context; - cl_device_id m_device; - cl_command_queue m_queue; + cl_context m_context; + cl_device_id m_device; + cl_command_queue m_queue; - b3OpenCLArray m_allAabbsGPU1; - b3AlignedObjectArray m_allAabbsCPU1; + b3OpenCLArray m_allAabbsGPU1; + b3AlignedObjectArray m_allAabbsCPU1; - b3OpenCLArray m_smallAabbsMappingGPU; + b3OpenCLArray m_smallAabbsMappingGPU; b3AlignedObjectArray m_smallAabbsMappingCPU; - b3OpenCLArray m_largeAabbsMappingGPU; + b3OpenCLArray m_largeAabbsMappingGPU; b3AlignedObjectArray m_largeAabbsMappingCPU; b3AlignedObjectArray m_hostPairs; - b3OpenCLArray m_gpuPairs; + b3OpenCLArray m_gpuPairs; - b3OpenCLArray m_hashGpu; - b3OpenCLArray m_cellStartGpu; - + b3OpenCLArray m_hashGpu; + b3OpenCLArray m_cellStartGpu; - b3ParamsGridBroadphaseCL m_paramsCPU; - b3OpenCLArray m_paramsGPU; + b3ParamsGridBroadphaseCL m_paramsCPU; + b3OpenCLArray m_paramsGPU; - class b3RadixSort32CL* m_sorter; + class b3RadixSort32CL* m_sorter; public: - - b3GpuGridBroadphase(cl_context ctx,cl_device_id device, cl_command_queue q ); + b3GpuGridBroadphase(cl_context ctx, cl_device_id device, cl_command_queue q); virtual ~b3GpuGridBroadphase(); - static b3GpuBroadphaseInterface* CreateFunc(cl_context ctx,cl_device_id device, cl_command_queue q) + static b3GpuBroadphaseInterface* CreateFunc(cl_context ctx, cl_device_id device, cl_command_queue q) { - return new b3GpuGridBroadphase(ctx,device,q); + return new b3GpuGridBroadphase(ctx, device, q); } - + virtual void createProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr, int collisionFilterGroup, int collisionFilterMask); + virtual void createLargeProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr, int collisionFilterGroup, int collisionFilterMask); - - virtual void createProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr , int collisionFilterGroup, int collisionFilterMask); - virtual void createLargeProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr , int collisionFilterGroup, int collisionFilterMask); - - virtual void calculateOverlappingPairs(int maxPairs); - virtual void calculateOverlappingPairsHost(int maxPairs); + virtual void calculateOverlappingPairs(int maxPairs); + virtual void calculateOverlappingPairsHost(int maxPairs); //call writeAabbsToGpu after done making all changes (createProxy etc) virtual void writeAabbsToGpu(); - virtual cl_mem getAabbBufferWS(); - virtual int getNumOverlap(); - virtual cl_mem getOverlappingPairBuffer(); + virtual cl_mem getAabbBufferWS(); + virtual int getNumOverlap(); + virtual cl_mem getOverlappingPairBuffer(); + + virtual b3OpenCLArray& getAllAabbsGPU(); + virtual b3AlignedObjectArray& getAllAabbsCPU(); - virtual b3OpenCLArray& getAllAabbsGPU(); - virtual b3AlignedObjectArray& getAllAabbsCPU(); - virtual b3OpenCLArray& getOverlappingPairsGPU(); virtual b3OpenCLArray& getSmallAabbIndicesGPU(); virtual b3OpenCLArray& getLargeAabbIndicesGPU(); - }; -#endif //B3_GPU_GRID_BROADPHASE_H \ No newline at end of file +#endif //B3_GPU_GRID_BROADPHASE_H \ No newline at end of file diff --git a/src/Bullet3OpenCL/BroadphaseCollision/b3GpuParallelLinearBvh.cpp b/src/Bullet3OpenCL/BroadphaseCollision/b3GpuParallelLinearBvh.cpp index 641df9eb1..072192868 100644 --- a/src/Bullet3OpenCL/BroadphaseCollision/b3GpuParallelLinearBvh.cpp +++ b/src/Bullet3OpenCL/BroadphaseCollision/b3GpuParallelLinearBvh.cpp @@ -16,177 +16,174 @@ subject to the following restrictions: #include "b3GpuParallelLinearBvh.h" -b3GpuParallelLinearBvh::b3GpuParallelLinearBvh(cl_context context, cl_device_id device, cl_command_queue queue) : - m_queue(queue), - m_radixSorter(context, device, queue), - - m_rootNodeIndex(context, queue), - m_maxDistanceFromRoot(context, queue), - m_temp(context, queue), - - m_internalNodeAabbs(context, queue), - m_internalNodeLeafIndexRanges(context, queue), - m_internalNodeChildNodes(context, queue), - m_internalNodeParentNodes(context, queue), - - m_commonPrefixes(context, queue), - m_commonPrefixLengths(context, queue), - m_distanceFromRoot(context, queue), - - m_leafNodeParentNodes(context, queue), - m_mortonCodesAndAabbIndicies(context, queue), - m_mergedAabb(context, queue), - m_leafNodeAabbs(context, queue), - - m_largeAabbs(context, queue) +b3GpuParallelLinearBvh::b3GpuParallelLinearBvh(cl_context context, cl_device_id device, cl_command_queue queue) : m_queue(queue), + m_radixSorter(context, device, queue), + + m_rootNodeIndex(context, queue), + m_maxDistanceFromRoot(context, queue), + m_temp(context, queue), + + m_internalNodeAabbs(context, queue), + m_internalNodeLeafIndexRanges(context, queue), + m_internalNodeChildNodes(context, queue), + m_internalNodeParentNodes(context, queue), + + m_commonPrefixes(context, queue), + m_commonPrefixLengths(context, queue), + m_distanceFromRoot(context, queue), + + m_leafNodeParentNodes(context, queue), + m_mortonCodesAndAabbIndicies(context, queue), + m_mergedAabb(context, queue), + m_leafNodeAabbs(context, queue), + + m_largeAabbs(context, queue) { m_rootNodeIndex.resize(1); m_maxDistanceFromRoot.resize(1); m_temp.resize(1); - + // const char CL_PROGRAM_PATH[] = "src/Bullet3OpenCL/BroadphaseCollision/kernels/parallelLinearBvh.cl"; - - const char* kernelSource = parallelLinearBvhCL; //parallelLinearBvhCL.h + + const char* kernelSource = parallelLinearBvhCL; //parallelLinearBvhCL.h cl_int error; char* additionalMacros = 0; m_parallelLinearBvhProgram = b3OpenCLUtils::compileCLProgramFromString(context, device, kernelSource, &error, additionalMacros, CL_PROGRAM_PATH); b3Assert(m_parallelLinearBvhProgram); - - m_separateAabbsKernel = b3OpenCLUtils::compileCLKernelFromString( context, device, kernelSource, "separateAabbs", &error, m_parallelLinearBvhProgram, additionalMacros ); + + m_separateAabbsKernel = b3OpenCLUtils::compileCLKernelFromString(context, device, kernelSource, "separateAabbs", &error, m_parallelLinearBvhProgram, additionalMacros); b3Assert(m_separateAabbsKernel); - m_findAllNodesMergedAabbKernel = b3OpenCLUtils::compileCLKernelFromString( context, device, kernelSource, "findAllNodesMergedAabb", &error, m_parallelLinearBvhProgram, additionalMacros ); + m_findAllNodesMergedAabbKernel = b3OpenCLUtils::compileCLKernelFromString(context, device, kernelSource, "findAllNodesMergedAabb", &error, m_parallelLinearBvhProgram, additionalMacros); b3Assert(m_findAllNodesMergedAabbKernel); - m_assignMortonCodesAndAabbIndiciesKernel = b3OpenCLUtils::compileCLKernelFromString( context, device, kernelSource, "assignMortonCodesAndAabbIndicies", &error, m_parallelLinearBvhProgram, additionalMacros ); + m_assignMortonCodesAndAabbIndiciesKernel = b3OpenCLUtils::compileCLKernelFromString(context, device, kernelSource, "assignMortonCodesAndAabbIndicies", &error, m_parallelLinearBvhProgram, additionalMacros); b3Assert(m_assignMortonCodesAndAabbIndiciesKernel); - - m_computeAdjacentPairCommonPrefixKernel = b3OpenCLUtils::compileCLKernelFromString( context, device, kernelSource, "computeAdjacentPairCommonPrefix", &error, m_parallelLinearBvhProgram, additionalMacros ); + + m_computeAdjacentPairCommonPrefixKernel = b3OpenCLUtils::compileCLKernelFromString(context, device, kernelSource, "computeAdjacentPairCommonPrefix", &error, m_parallelLinearBvhProgram, additionalMacros); b3Assert(m_computeAdjacentPairCommonPrefixKernel); - m_buildBinaryRadixTreeLeafNodesKernel = b3OpenCLUtils::compileCLKernelFromString( context, device, kernelSource, "buildBinaryRadixTreeLeafNodes", &error, m_parallelLinearBvhProgram, additionalMacros ); + m_buildBinaryRadixTreeLeafNodesKernel = b3OpenCLUtils::compileCLKernelFromString(context, device, kernelSource, "buildBinaryRadixTreeLeafNodes", &error, m_parallelLinearBvhProgram, additionalMacros); b3Assert(m_buildBinaryRadixTreeLeafNodesKernel); - m_buildBinaryRadixTreeInternalNodesKernel = b3OpenCLUtils::compileCLKernelFromString( context, device, kernelSource, "buildBinaryRadixTreeInternalNodes", &error, m_parallelLinearBvhProgram, additionalMacros ); + m_buildBinaryRadixTreeInternalNodesKernel = b3OpenCLUtils::compileCLKernelFromString(context, device, kernelSource, "buildBinaryRadixTreeInternalNodes", &error, m_parallelLinearBvhProgram, additionalMacros); b3Assert(m_buildBinaryRadixTreeInternalNodesKernel); - m_findDistanceFromRootKernel = b3OpenCLUtils::compileCLKernelFromString( context, device, kernelSource, "findDistanceFromRoot", &error, m_parallelLinearBvhProgram, additionalMacros ); + m_findDistanceFromRootKernel = b3OpenCLUtils::compileCLKernelFromString(context, device, kernelSource, "findDistanceFromRoot", &error, m_parallelLinearBvhProgram, additionalMacros); b3Assert(m_findDistanceFromRootKernel); - m_buildBinaryRadixTreeAabbsRecursiveKernel = b3OpenCLUtils::compileCLKernelFromString( context, device, kernelSource, "buildBinaryRadixTreeAabbsRecursive", &error, m_parallelLinearBvhProgram, additionalMacros ); + m_buildBinaryRadixTreeAabbsRecursiveKernel = b3OpenCLUtils::compileCLKernelFromString(context, device, kernelSource, "buildBinaryRadixTreeAabbsRecursive", &error, m_parallelLinearBvhProgram, additionalMacros); b3Assert(m_buildBinaryRadixTreeAabbsRecursiveKernel); - - m_findLeafIndexRangesKernel = b3OpenCLUtils::compileCLKernelFromString( context, device, kernelSource, "findLeafIndexRanges", &error, m_parallelLinearBvhProgram, additionalMacros ); + + m_findLeafIndexRangesKernel = b3OpenCLUtils::compileCLKernelFromString(context, device, kernelSource, "findLeafIndexRanges", &error, m_parallelLinearBvhProgram, additionalMacros); b3Assert(m_findLeafIndexRangesKernel); - - m_plbvhCalculateOverlappingPairsKernel = b3OpenCLUtils::compileCLKernelFromString( context, device, kernelSource, "plbvhCalculateOverlappingPairs", &error, m_parallelLinearBvhProgram, additionalMacros ); + + m_plbvhCalculateOverlappingPairsKernel = b3OpenCLUtils::compileCLKernelFromString(context, device, kernelSource, "plbvhCalculateOverlappingPairs", &error, m_parallelLinearBvhProgram, additionalMacros); b3Assert(m_plbvhCalculateOverlappingPairsKernel); - m_plbvhRayTraverseKernel = b3OpenCLUtils::compileCLKernelFromString( context, device, kernelSource, "plbvhRayTraverse", &error, m_parallelLinearBvhProgram, additionalMacros ); + m_plbvhRayTraverseKernel = b3OpenCLUtils::compileCLKernelFromString(context, device, kernelSource, "plbvhRayTraverse", &error, m_parallelLinearBvhProgram, additionalMacros); b3Assert(m_plbvhRayTraverseKernel); - m_plbvhLargeAabbAabbTestKernel = b3OpenCLUtils::compileCLKernelFromString( context, device, kernelSource, "plbvhLargeAabbAabbTest", &error, m_parallelLinearBvhProgram, additionalMacros ); + m_plbvhLargeAabbAabbTestKernel = b3OpenCLUtils::compileCLKernelFromString(context, device, kernelSource, "plbvhLargeAabbAabbTest", &error, m_parallelLinearBvhProgram, additionalMacros); b3Assert(m_plbvhLargeAabbAabbTestKernel); - m_plbvhLargeAabbRayTestKernel = b3OpenCLUtils::compileCLKernelFromString( context, device, kernelSource, "plbvhLargeAabbRayTest", &error, m_parallelLinearBvhProgram, additionalMacros ); + m_plbvhLargeAabbRayTestKernel = b3OpenCLUtils::compileCLKernelFromString(context, device, kernelSource, "plbvhLargeAabbRayTest", &error, m_parallelLinearBvhProgram, additionalMacros); b3Assert(m_plbvhLargeAabbRayTestKernel); } -b3GpuParallelLinearBvh::~b3GpuParallelLinearBvh() +b3GpuParallelLinearBvh::~b3GpuParallelLinearBvh() { clReleaseKernel(m_separateAabbsKernel); clReleaseKernel(m_findAllNodesMergedAabbKernel); clReleaseKernel(m_assignMortonCodesAndAabbIndiciesKernel); - + clReleaseKernel(m_computeAdjacentPairCommonPrefixKernel); clReleaseKernel(m_buildBinaryRadixTreeLeafNodesKernel); clReleaseKernel(m_buildBinaryRadixTreeInternalNodesKernel); clReleaseKernel(m_findDistanceFromRootKernel); clReleaseKernel(m_buildBinaryRadixTreeAabbsRecursiveKernel); - + clReleaseKernel(m_findLeafIndexRangesKernel); - + clReleaseKernel(m_plbvhCalculateOverlappingPairsKernel); clReleaseKernel(m_plbvhRayTraverseKernel); clReleaseKernel(m_plbvhLargeAabbAabbTestKernel); clReleaseKernel(m_plbvhLargeAabbRayTestKernel); - + clReleaseProgram(m_parallelLinearBvhProgram); } -void b3GpuParallelLinearBvh::build(const b3OpenCLArray& worldSpaceAabbs, const b3OpenCLArray& smallAabbIndices, - const b3OpenCLArray& largeAabbIndices) +void b3GpuParallelLinearBvh::build(const b3OpenCLArray& worldSpaceAabbs, const b3OpenCLArray& smallAabbIndices, + const b3OpenCLArray& largeAabbIndices) { B3_PROFILE("b3ParallelLinearBvh::build()"); - + int numLargeAabbs = largeAabbIndices.size(); int numSmallAabbs = smallAabbIndices.size(); - - //Since all AABBs(both large and small) are input as a contiguous array, + + //Since all AABBs(both large and small) are input as a contiguous array, //with 2 additional arrays used to indicate the indices of large and small AABBs, //it is necessary to separate the AABBs so that the large AABBs will not degrade the quality of the BVH. { B3_PROFILE("Separate large and small AABBs"); - + m_largeAabbs.resize(numLargeAabbs); m_leafNodeAabbs.resize(numSmallAabbs); - + //Write large AABBs into m_largeAabbs { - b3BufferInfoCL bufferInfo[] = - { - b3BufferInfoCL( worldSpaceAabbs.getBufferCL() ), - b3BufferInfoCL( largeAabbIndices.getBufferCL() ), - - b3BufferInfoCL( m_largeAabbs.getBufferCL() ) - }; - + b3BufferInfoCL bufferInfo[] = + { + b3BufferInfoCL(worldSpaceAabbs.getBufferCL()), + b3BufferInfoCL(largeAabbIndices.getBufferCL()), + + b3BufferInfoCL(m_largeAabbs.getBufferCL())}; + b3LauncherCL launcher(m_queue, m_separateAabbsKernel, "m_separateAabbsKernel"); - launcher.setBuffers( bufferInfo, sizeof(bufferInfo)/sizeof(b3BufferInfoCL) ); + launcher.setBuffers(bufferInfo, sizeof(bufferInfo) / sizeof(b3BufferInfoCL)); launcher.setConst(numLargeAabbs); - + launcher.launch1D(numLargeAabbs); } - + //Write small AABBs into m_leafNodeAabbs { - b3BufferInfoCL bufferInfo[] = - { - b3BufferInfoCL( worldSpaceAabbs.getBufferCL() ), - b3BufferInfoCL( smallAabbIndices.getBufferCL() ), - - b3BufferInfoCL( m_leafNodeAabbs.getBufferCL() ) - }; - + b3BufferInfoCL bufferInfo[] = + { + b3BufferInfoCL(worldSpaceAabbs.getBufferCL()), + b3BufferInfoCL(smallAabbIndices.getBufferCL()), + + b3BufferInfoCL(m_leafNodeAabbs.getBufferCL())}; + b3LauncherCL launcher(m_queue, m_separateAabbsKernel, "m_separateAabbsKernel"); - launcher.setBuffers( bufferInfo, sizeof(bufferInfo)/sizeof(b3BufferInfoCL) ); + launcher.setBuffers(bufferInfo, sizeof(bufferInfo) / sizeof(b3BufferInfoCL)); launcher.setConst(numSmallAabbs); - + launcher.launch1D(numSmallAabbs); } - + clFinish(m_queue); } - + // - int numLeaves = numSmallAabbs; //Number of leaves in the BVH == Number of rigid bodies with small AABBs + int numLeaves = numSmallAabbs; //Number of leaves in the BVH == Number of rigid bodies with small AABBs int numInternalNodes = numLeaves - 1; - - if(numLeaves < 2) + + if (numLeaves < 2) { //Number of leaf nodes is checked in calculateOverlappingPairs() and testRaysAgainstBvhAabbs(), //so it does not matter if numLeaves == 0 and rootNodeIndex == -1 int rootNodeIndex = numLeaves - 1; m_rootNodeIndex.copyFromHostPointer(&rootNodeIndex, 1); - + //Since the AABBs need to be rearranged(sorted) for the BVH construction algorithm, //m_mortonCodesAndAabbIndicies.m_value is used to map a sorted AABB index to the unsorted AABB index //instead of directly moving the AABBs. It needs to be set for the ray cast traversal kernel to work. //( m_mortonCodesAndAabbIndicies[].m_value == unsorted index == index of m_leafNodeAabbs ) - if(numLeaves == 1) + if (numLeaves == 1) { b3SortData leaf; - leaf.m_value = 0; //1 leaf so index is always 0; leaf.m_key does not need to be set - + leaf.m_value = 0; //1 leaf so index is always 0; leaf.m_key does not need to be set + m_mortonCodesAndAabbIndicies.resize(1); m_mortonCodesAndAabbIndicies.copyFromHostPointer(&leaf, 1); } - + return; } - + // { m_internalNodeAabbs.resize(numInternalNodes); @@ -197,37 +194,37 @@ void b3GpuParallelLinearBvh::build(const b3OpenCLArray& worldSpaceAab m_commonPrefixes.resize(numInternalNodes); m_commonPrefixLengths.resize(numInternalNodes); m_distanceFromRoot.resize(numInternalNodes); - + m_leafNodeParentNodes.resize(numLeaves); m_mortonCodesAndAabbIndicies.resize(numLeaves); m_mergedAabb.resize(numLeaves); } - - //Find the merged AABB of all small AABBs; this is used to define the size of + + //Find the merged AABB of all small AABBs; this is used to define the size of //each cell in the virtual grid for the next kernel(2^10 cells in each dimension). { B3_PROFILE("Find AABB of merged nodes"); - - m_mergedAabb.copyFromOpenCLArray(m_leafNodeAabbs); //Need to make a copy since the kernel modifies the array - - for(int numAabbsNeedingMerge = numLeaves; numAabbsNeedingMerge >= 2; - numAabbsNeedingMerge = numAabbsNeedingMerge / 2 + numAabbsNeedingMerge % 2) + + m_mergedAabb.copyFromOpenCLArray(m_leafNodeAabbs); //Need to make a copy since the kernel modifies the array + + for (int numAabbsNeedingMerge = numLeaves; numAabbsNeedingMerge >= 2; + numAabbsNeedingMerge = numAabbsNeedingMerge / 2 + numAabbsNeedingMerge % 2) { - b3BufferInfoCL bufferInfo[] = - { - b3BufferInfoCL( m_mergedAabb.getBufferCL() ) //Resulting AABB is stored in m_mergedAabb[0] - }; - + b3BufferInfoCL bufferInfo[] = + { + b3BufferInfoCL(m_mergedAabb.getBufferCL()) //Resulting AABB is stored in m_mergedAabb[0] + }; + b3LauncherCL launcher(m_queue, m_findAllNodesMergedAabbKernel, "m_findAllNodesMergedAabbKernel"); - launcher.setBuffers( bufferInfo, sizeof(bufferInfo)/sizeof(b3BufferInfoCL) ); + launcher.setBuffers(bufferInfo, sizeof(bufferInfo) / sizeof(b3BufferInfoCL)); launcher.setConst(numAabbsNeedingMerge); - + launcher.launch1D(numAabbsNeedingMerge); } - + clFinish(m_queue); } - + //Insert the center of the AABBs into a virtual grid, //then convert the discrete grid coordinates into a morton code //For each element in m_mortonCodesAndAabbIndicies, set @@ -235,34 +232,32 @@ void b3GpuParallelLinearBvh::build(const b3OpenCLArray& worldSpaceAab // m_value == small AABB index { B3_PROFILE("Assign morton codes"); - - b3BufferInfoCL bufferInfo[] = - { - b3BufferInfoCL( m_leafNodeAabbs.getBufferCL() ), - b3BufferInfoCL( m_mergedAabb.getBufferCL() ), - b3BufferInfoCL( m_mortonCodesAndAabbIndicies.getBufferCL() ) - }; - + + b3BufferInfoCL bufferInfo[] = + { + b3BufferInfoCL(m_leafNodeAabbs.getBufferCL()), + b3BufferInfoCL(m_mergedAabb.getBufferCL()), + b3BufferInfoCL(m_mortonCodesAndAabbIndicies.getBufferCL())}; + b3LauncherCL launcher(m_queue, m_assignMortonCodesAndAabbIndiciesKernel, "m_assignMortonCodesAndAabbIndiciesKernel"); - launcher.setBuffers( bufferInfo, sizeof(bufferInfo)/sizeof(b3BufferInfoCL) ); + launcher.setBuffers(bufferInfo, sizeof(bufferInfo) / sizeof(b3BufferInfoCL)); launcher.setConst(numLeaves); - + launcher.launch1D(numLeaves); clFinish(m_queue); } - + // { B3_PROFILE("Sort leaves by morton codes"); - + m_radixSorter.execute(m_mortonCodesAndAabbIndicies); clFinish(m_queue); } - + // constructBinaryRadixTree(); - - + //Since it is a sorted binary radix tree, each internal node contains a contiguous subset of leaf node indices. //The root node contains leaf node indices in the range [0, numLeafNodes - 1]. //The child nodes of each node split their parent's index range into 2 contiguous halves. @@ -273,17 +268,16 @@ void b3GpuParallelLinearBvh::build(const b3OpenCLArray& worldSpaceAab //This property can be used for optimizing calculateOverlappingPairs(), to avoid testing each AABB pair twice { B3_PROFILE("m_findLeafIndexRangesKernel"); - - b3BufferInfoCL bufferInfo[] = - { - b3BufferInfoCL( m_internalNodeChildNodes.getBufferCL() ), - b3BufferInfoCL( m_internalNodeLeafIndexRanges.getBufferCL() ) - }; - + + b3BufferInfoCL bufferInfo[] = + { + b3BufferInfoCL(m_internalNodeChildNodes.getBufferCL()), + b3BufferInfoCL(m_internalNodeLeafIndexRanges.getBufferCL())}; + b3LauncherCL launcher(m_queue, m_findLeafIndexRangesKernel, "m_findLeafIndexRangesKernel"); - launcher.setBuffers( bufferInfo, sizeof(bufferInfo)/sizeof(b3BufferInfoCL) ); + launcher.setBuffers(bufferInfo, sizeof(bufferInfo) / sizeof(b3BufferInfoCL)); launcher.setConst(numInternalNodes); - + launcher.launch1D(numInternalNodes); clFinish(m_queue); } @@ -293,285 +287,271 @@ void b3GpuParallelLinearBvh::calculateOverlappingPairs(b3OpenCLArray& ou { int maxPairs = out_overlappingPairs.size(); b3OpenCLArray& numPairsGpu = m_temp; - + int reset = 0; numPairsGpu.copyFromHostPointer(&reset, 1); - + // - if( m_leafNodeAabbs.size() > 1 ) + if (m_leafNodeAabbs.size() > 1) { B3_PROFILE("PLBVH small-small AABB test"); - + int numQueryAabbs = m_leafNodeAabbs.size(); - - b3BufferInfoCL bufferInfo[] = - { - b3BufferInfoCL( m_leafNodeAabbs.getBufferCL() ), - - b3BufferInfoCL( m_rootNodeIndex.getBufferCL() ), - b3BufferInfoCL( m_internalNodeChildNodes.getBufferCL() ), - b3BufferInfoCL( m_internalNodeAabbs.getBufferCL() ), - b3BufferInfoCL( m_internalNodeLeafIndexRanges.getBufferCL() ), - b3BufferInfoCL( m_mortonCodesAndAabbIndicies.getBufferCL() ), - - b3BufferInfoCL( numPairsGpu.getBufferCL() ), - b3BufferInfoCL( out_overlappingPairs.getBufferCL() ) - }; - + + b3BufferInfoCL bufferInfo[] = + { + b3BufferInfoCL(m_leafNodeAabbs.getBufferCL()), + + b3BufferInfoCL(m_rootNodeIndex.getBufferCL()), + b3BufferInfoCL(m_internalNodeChildNodes.getBufferCL()), + b3BufferInfoCL(m_internalNodeAabbs.getBufferCL()), + b3BufferInfoCL(m_internalNodeLeafIndexRanges.getBufferCL()), + b3BufferInfoCL(m_mortonCodesAndAabbIndicies.getBufferCL()), + + b3BufferInfoCL(numPairsGpu.getBufferCL()), + b3BufferInfoCL(out_overlappingPairs.getBufferCL())}; + b3LauncherCL launcher(m_queue, m_plbvhCalculateOverlappingPairsKernel, "m_plbvhCalculateOverlappingPairsKernel"); - launcher.setBuffers( bufferInfo, sizeof(bufferInfo)/sizeof(b3BufferInfoCL) ); + launcher.setBuffers(bufferInfo, sizeof(bufferInfo) / sizeof(b3BufferInfoCL)); launcher.setConst(maxPairs); launcher.setConst(numQueryAabbs); - + launcher.launch1D(numQueryAabbs); clFinish(m_queue); } - + int numLargeAabbRigids = m_largeAabbs.size(); - if( numLargeAabbRigids > 0 && m_leafNodeAabbs.size() > 0 ) + if (numLargeAabbRigids > 0 && m_leafNodeAabbs.size() > 0) { B3_PROFILE("PLBVH large-small AABB test"); - + int numQueryAabbs = m_leafNodeAabbs.size(); - - b3BufferInfoCL bufferInfo[] = - { - b3BufferInfoCL( m_leafNodeAabbs.getBufferCL() ), - b3BufferInfoCL( m_largeAabbs.getBufferCL() ), - - b3BufferInfoCL( numPairsGpu.getBufferCL() ), - b3BufferInfoCL( out_overlappingPairs.getBufferCL() ) - }; - + + b3BufferInfoCL bufferInfo[] = + { + b3BufferInfoCL(m_leafNodeAabbs.getBufferCL()), + b3BufferInfoCL(m_largeAabbs.getBufferCL()), + + b3BufferInfoCL(numPairsGpu.getBufferCL()), + b3BufferInfoCL(out_overlappingPairs.getBufferCL())}; + b3LauncherCL launcher(m_queue, m_plbvhLargeAabbAabbTestKernel, "m_plbvhLargeAabbAabbTestKernel"); - launcher.setBuffers( bufferInfo, sizeof(bufferInfo)/sizeof(b3BufferInfoCL) ); + launcher.setBuffers(bufferInfo, sizeof(bufferInfo) / sizeof(b3BufferInfoCL)); launcher.setConst(maxPairs); launcher.setConst(numLargeAabbRigids); launcher.setConst(numQueryAabbs); - + launcher.launch1D(numQueryAabbs); clFinish(m_queue); } - - + // int numPairs = -1; numPairsGpu.copyToHostPointer(&numPairs, 1); - if(numPairs > maxPairs) + if (numPairs > maxPairs) { b3Error("Error running out of pairs: numPairs = %d, maxPairs = %d.\n", numPairs, maxPairs); numPairs = maxPairs; numPairsGpu.copyFromHostPointer(&maxPairs, 1); } - + out_overlappingPairs.resize(numPairs); } - -void b3GpuParallelLinearBvh::testRaysAgainstBvhAabbs(const b3OpenCLArray& rays, - b3OpenCLArray& out_numRayRigidPairs, b3OpenCLArray& out_rayRigidPairs) +void b3GpuParallelLinearBvh::testRaysAgainstBvhAabbs(const b3OpenCLArray& rays, + b3OpenCLArray& out_numRayRigidPairs, b3OpenCLArray& out_rayRigidPairs) { B3_PROFILE("PLBVH testRaysAgainstBvhAabbs()"); - + int numRays = rays.size(); int maxRayRigidPairs = out_rayRigidPairs.size(); - + int reset = 0; out_numRayRigidPairs.copyFromHostPointer(&reset, 1); - + // - if( m_leafNodeAabbs.size() > 0 ) + if (m_leafNodeAabbs.size() > 0) { B3_PROFILE("PLBVH ray test small AABB"); - - b3BufferInfoCL bufferInfo[] = - { - b3BufferInfoCL( m_leafNodeAabbs.getBufferCL() ), - - b3BufferInfoCL( m_rootNodeIndex.getBufferCL() ), - b3BufferInfoCL( m_internalNodeChildNodes.getBufferCL() ), - b3BufferInfoCL( m_internalNodeAabbs.getBufferCL() ), - b3BufferInfoCL( m_internalNodeLeafIndexRanges.getBufferCL() ), - b3BufferInfoCL( m_mortonCodesAndAabbIndicies.getBufferCL() ), - - b3BufferInfoCL( rays.getBufferCL() ), - - b3BufferInfoCL( out_numRayRigidPairs.getBufferCL() ), - b3BufferInfoCL( out_rayRigidPairs.getBufferCL() ) - }; - + + b3BufferInfoCL bufferInfo[] = + { + b3BufferInfoCL(m_leafNodeAabbs.getBufferCL()), + + b3BufferInfoCL(m_rootNodeIndex.getBufferCL()), + b3BufferInfoCL(m_internalNodeChildNodes.getBufferCL()), + b3BufferInfoCL(m_internalNodeAabbs.getBufferCL()), + b3BufferInfoCL(m_internalNodeLeafIndexRanges.getBufferCL()), + b3BufferInfoCL(m_mortonCodesAndAabbIndicies.getBufferCL()), + + b3BufferInfoCL(rays.getBufferCL()), + + b3BufferInfoCL(out_numRayRigidPairs.getBufferCL()), + b3BufferInfoCL(out_rayRigidPairs.getBufferCL())}; + b3LauncherCL launcher(m_queue, m_plbvhRayTraverseKernel, "m_plbvhRayTraverseKernel"); - launcher.setBuffers( bufferInfo, sizeof(bufferInfo)/sizeof(b3BufferInfoCL) ); + launcher.setBuffers(bufferInfo, sizeof(bufferInfo) / sizeof(b3BufferInfoCL)); launcher.setConst(maxRayRigidPairs); launcher.setConst(numRays); - + launcher.launch1D(numRays); clFinish(m_queue); } - + int numLargeAabbRigids = m_largeAabbs.size(); - if(numLargeAabbRigids > 0) + if (numLargeAabbRigids > 0) { B3_PROFILE("PLBVH ray test large AABB"); - - b3BufferInfoCL bufferInfo[] = - { - b3BufferInfoCL( m_largeAabbs.getBufferCL() ), - b3BufferInfoCL( rays.getBufferCL() ), - - b3BufferInfoCL( out_numRayRigidPairs.getBufferCL() ), - b3BufferInfoCL( out_rayRigidPairs.getBufferCL() ) - }; - + + b3BufferInfoCL bufferInfo[] = + { + b3BufferInfoCL(m_largeAabbs.getBufferCL()), + b3BufferInfoCL(rays.getBufferCL()), + + b3BufferInfoCL(out_numRayRigidPairs.getBufferCL()), + b3BufferInfoCL(out_rayRigidPairs.getBufferCL())}; + b3LauncherCL launcher(m_queue, m_plbvhLargeAabbRayTestKernel, "m_plbvhLargeAabbRayTestKernel"); - launcher.setBuffers( bufferInfo, sizeof(bufferInfo)/sizeof(b3BufferInfoCL) ); + launcher.setBuffers(bufferInfo, sizeof(bufferInfo) / sizeof(b3BufferInfoCL)); launcher.setConst(numLargeAabbRigids); launcher.setConst(maxRayRigidPairs); launcher.setConst(numRays); - + launcher.launch1D(numRays); clFinish(m_queue); } - + // int numRayRigidPairs = -1; out_numRayRigidPairs.copyToHostPointer(&numRayRigidPairs, 1); - - if(numRayRigidPairs > maxRayRigidPairs) + + if (numRayRigidPairs > maxRayRigidPairs) b3Error("Error running out of rayRigid pairs: numRayRigidPairs = %d, maxRayRigidPairs = %d.\n", numRayRigidPairs, maxRayRigidPairs); - } void b3GpuParallelLinearBvh::constructBinaryRadixTree() { B3_PROFILE("b3GpuParallelLinearBvh::constructBinaryRadixTree()"); - + int numLeaves = m_leafNodeAabbs.size(); int numInternalNodes = numLeaves - 1; - + //Each internal node is placed in between 2 leaf nodes. //By using this arrangement and computing the common prefix between //these 2 adjacent leaf nodes, it is possible to quickly construct a binary radix tree. { B3_PROFILE("m_computeAdjacentPairCommonPrefixKernel"); - - b3BufferInfoCL bufferInfo[] = - { - b3BufferInfoCL( m_mortonCodesAndAabbIndicies.getBufferCL() ), - b3BufferInfoCL( m_commonPrefixes.getBufferCL() ), - b3BufferInfoCL( m_commonPrefixLengths.getBufferCL() ) - }; - + + b3BufferInfoCL bufferInfo[] = + { + b3BufferInfoCL(m_mortonCodesAndAabbIndicies.getBufferCL()), + b3BufferInfoCL(m_commonPrefixes.getBufferCL()), + b3BufferInfoCL(m_commonPrefixLengths.getBufferCL())}; + b3LauncherCL launcher(m_queue, m_computeAdjacentPairCommonPrefixKernel, "m_computeAdjacentPairCommonPrefixKernel"); - launcher.setBuffers( bufferInfo, sizeof(bufferInfo)/sizeof(b3BufferInfoCL) ); + launcher.setBuffers(bufferInfo, sizeof(bufferInfo) / sizeof(b3BufferInfoCL)); launcher.setConst(numInternalNodes); - + launcher.launch1D(numInternalNodes); clFinish(m_queue); } - - //For each leaf node, select its parent node by + + //For each leaf node, select its parent node by //comparing the 2 nearest internal nodes and assign child node indices { B3_PROFILE("m_buildBinaryRadixTreeLeafNodesKernel"); - - b3BufferInfoCL bufferInfo[] = - { - b3BufferInfoCL( m_commonPrefixLengths.getBufferCL() ), - b3BufferInfoCL( m_leafNodeParentNodes.getBufferCL() ), - b3BufferInfoCL( m_internalNodeChildNodes.getBufferCL() ) - }; - + + b3BufferInfoCL bufferInfo[] = + { + b3BufferInfoCL(m_commonPrefixLengths.getBufferCL()), + b3BufferInfoCL(m_leafNodeParentNodes.getBufferCL()), + b3BufferInfoCL(m_internalNodeChildNodes.getBufferCL())}; + b3LauncherCL launcher(m_queue, m_buildBinaryRadixTreeLeafNodesKernel, "m_buildBinaryRadixTreeLeafNodesKernel"); - launcher.setBuffers( bufferInfo, sizeof(bufferInfo)/sizeof(b3BufferInfoCL) ); + launcher.setBuffers(bufferInfo, sizeof(bufferInfo) / sizeof(b3BufferInfoCL)); launcher.setConst(numLeaves); - + launcher.launch1D(numLeaves); clFinish(m_queue); } - + //For each internal node, perform 2 binary searches among the other internal nodes //to its left and right to find its potential parent nodes and assign child node indices { B3_PROFILE("m_buildBinaryRadixTreeInternalNodesKernel"); - - b3BufferInfoCL bufferInfo[] = - { - b3BufferInfoCL( m_commonPrefixes.getBufferCL() ), - b3BufferInfoCL( m_commonPrefixLengths.getBufferCL() ), - b3BufferInfoCL( m_internalNodeChildNodes.getBufferCL() ), - b3BufferInfoCL( m_internalNodeParentNodes.getBufferCL() ), - b3BufferInfoCL( m_rootNodeIndex.getBufferCL() ) - }; - + + b3BufferInfoCL bufferInfo[] = + { + b3BufferInfoCL(m_commonPrefixes.getBufferCL()), + b3BufferInfoCL(m_commonPrefixLengths.getBufferCL()), + b3BufferInfoCL(m_internalNodeChildNodes.getBufferCL()), + b3BufferInfoCL(m_internalNodeParentNodes.getBufferCL()), + b3BufferInfoCL(m_rootNodeIndex.getBufferCL())}; + b3LauncherCL launcher(m_queue, m_buildBinaryRadixTreeInternalNodesKernel, "m_buildBinaryRadixTreeInternalNodesKernel"); - launcher.setBuffers( bufferInfo, sizeof(bufferInfo)/sizeof(b3BufferInfoCL) ); + launcher.setBuffers(bufferInfo, sizeof(bufferInfo) / sizeof(b3BufferInfoCL)); launcher.setConst(numInternalNodes); - + launcher.launch1D(numInternalNodes); clFinish(m_queue); } - + //Find the number of nodes seperating each internal node and the root node //so that the AABBs can be set using the next kernel. //Also determine the maximum number of nodes separating an internal node and the root node. { B3_PROFILE("m_findDistanceFromRootKernel"); - - b3BufferInfoCL bufferInfo[] = - { - b3BufferInfoCL( m_rootNodeIndex.getBufferCL() ), - b3BufferInfoCL( m_internalNodeParentNodes.getBufferCL() ), - b3BufferInfoCL( m_maxDistanceFromRoot.getBufferCL() ), - b3BufferInfoCL( m_distanceFromRoot.getBufferCL() ) - }; - + + b3BufferInfoCL bufferInfo[] = + { + b3BufferInfoCL(m_rootNodeIndex.getBufferCL()), + b3BufferInfoCL(m_internalNodeParentNodes.getBufferCL()), + b3BufferInfoCL(m_maxDistanceFromRoot.getBufferCL()), + b3BufferInfoCL(m_distanceFromRoot.getBufferCL())}; + b3LauncherCL launcher(m_queue, m_findDistanceFromRootKernel, "m_findDistanceFromRootKernel"); - launcher.setBuffers( bufferInfo, sizeof(bufferInfo)/sizeof(b3BufferInfoCL) ); + launcher.setBuffers(bufferInfo, sizeof(bufferInfo) / sizeof(b3BufferInfoCL)); launcher.setConst(numInternalNodes); - + launcher.launch1D(numInternalNodes); clFinish(m_queue); } - + //Starting from the internal nodes nearest to the leaf nodes, recursively move up //the tree towards the root to set the AABBs of each internal node; each internal node //checks its children and merges their AABBs { B3_PROFILE("m_buildBinaryRadixTreeAabbsRecursiveKernel"); - + int maxDistanceFromRoot = -1; { B3_PROFILE("copy maxDistanceFromRoot to CPU"); m_maxDistanceFromRoot.copyToHostPointer(&maxDistanceFromRoot, 1); clFinish(m_queue); } - - for(int distanceFromRoot = maxDistanceFromRoot; distanceFromRoot >= 0; --distanceFromRoot) + + for (int distanceFromRoot = maxDistanceFromRoot; distanceFromRoot >= 0; --distanceFromRoot) { - b3BufferInfoCL bufferInfo[] = - { - b3BufferInfoCL( m_distanceFromRoot.getBufferCL() ), - b3BufferInfoCL( m_mortonCodesAndAabbIndicies.getBufferCL() ), - b3BufferInfoCL( m_internalNodeChildNodes.getBufferCL() ), - b3BufferInfoCL( m_leafNodeAabbs.getBufferCL() ), - b3BufferInfoCL( m_internalNodeAabbs.getBufferCL() ) - }; - + b3BufferInfoCL bufferInfo[] = + { + b3BufferInfoCL(m_distanceFromRoot.getBufferCL()), + b3BufferInfoCL(m_mortonCodesAndAabbIndicies.getBufferCL()), + b3BufferInfoCL(m_internalNodeChildNodes.getBufferCL()), + b3BufferInfoCL(m_leafNodeAabbs.getBufferCL()), + b3BufferInfoCL(m_internalNodeAabbs.getBufferCL())}; + b3LauncherCL launcher(m_queue, m_buildBinaryRadixTreeAabbsRecursiveKernel, "m_buildBinaryRadixTreeAabbsRecursiveKernel"); - launcher.setBuffers( bufferInfo, sizeof(bufferInfo)/sizeof(b3BufferInfoCL) ); + launcher.setBuffers(bufferInfo, sizeof(bufferInfo) / sizeof(b3BufferInfoCL)); launcher.setConst(maxDistanceFromRoot); launcher.setConst(distanceFromRoot); launcher.setConst(numInternalNodes); - + //It may seem inefficent to launch a thread for each internal node when a //much smaller number of nodes is actually processed, but this is actually - //faster than determining the exact nodes that are ready to merge their child AABBs. + //faster than determining the exact nodes that are ready to merge their child AABBs. launcher.launch1D(numInternalNodes); } - + clFinish(m_queue); } } - - \ No newline at end of file diff --git a/src/Bullet3OpenCL/BroadphaseCollision/b3GpuParallelLinearBvh.h b/src/Bullet3OpenCL/BroadphaseCollision/b3GpuParallelLinearBvh.h index effe617b7..b39077512 100644 --- a/src/Bullet3OpenCL/BroadphaseCollision/b3GpuParallelLinearBvh.h +++ b/src/Bullet3OpenCL/BroadphaseCollision/b3GpuParallelLinearBvh.h @@ -37,10 +37,10 @@ subject to the following restrictions: ///"Maximizing Parallelism in the Construction of BVHs, Octrees, and k-d trees" [Karras 2012] \n ///@par ///The basic algorithm for building the BVH as presented in [Lauterbach et al. 2009] consists of 4 stages: -/// - [fully parallel] Assign morton codes for each AABB using its center (after quantizing the AABB centers into a virtual grid) +/// - [fully parallel] Assign morton codes for each AABB using its center (after quantizing the AABB centers into a virtual grid) /// - [fully parallel] Sort morton codes -/// - [somewhat parallel] Build binary radix tree (assign parent/child pointers for internal nodes of the BVH) -/// - [somewhat parallel] Set internal node AABBs +/// - [somewhat parallel] Build binary radix tree (assign parent/child pointers for internal nodes of the BVH) +/// - [somewhat parallel] Set internal node AABBs ///@par ///[Karras 2012] improves on the algorithm by introducing fully parallel methods for the last 2 stages. ///The BVH implementation here shares many concepts with [Karras 2012], but a different method is used for constructing the tree. @@ -49,75 +49,75 @@ subject to the following restrictions: class b3GpuParallelLinearBvh { cl_command_queue m_queue; - + cl_program m_parallelLinearBvhProgram; - + cl_kernel m_separateAabbsKernel; cl_kernel m_findAllNodesMergedAabbKernel; cl_kernel m_assignMortonCodesAndAabbIndiciesKernel; - + //Binary radix tree construction kernels cl_kernel m_computeAdjacentPairCommonPrefixKernel; cl_kernel m_buildBinaryRadixTreeLeafNodesKernel; cl_kernel m_buildBinaryRadixTreeInternalNodesKernel; cl_kernel m_findDistanceFromRootKernel; cl_kernel m_buildBinaryRadixTreeAabbsRecursiveKernel; - + cl_kernel m_findLeafIndexRangesKernel; - + //Traversal kernels cl_kernel m_plbvhCalculateOverlappingPairsKernel; cl_kernel m_plbvhRayTraverseKernel; cl_kernel m_plbvhLargeAabbAabbTestKernel; cl_kernel m_plbvhLargeAabbRayTestKernel; - + b3RadixSort32CL m_radixSorter; - + //1 element - b3OpenCLArray m_rootNodeIndex; //Most significant bit(0x80000000) is set to indicate internal node - b3OpenCLArray m_maxDistanceFromRoot; //Max number of internal nodes between an internal node and the root node - b3OpenCLArray m_temp; //Used to hold the number of pairs in calculateOverlappingPairs() - + b3OpenCLArray m_rootNodeIndex; //Most significant bit(0x80000000) is set to indicate internal node + b3OpenCLArray m_maxDistanceFromRoot; //Max number of internal nodes between an internal node and the root node + b3OpenCLArray m_temp; //Used to hold the number of pairs in calculateOverlappingPairs() + //1 element per internal node (number_of_internal_nodes == number_of_leaves - 1) b3OpenCLArray m_internalNodeAabbs; - b3OpenCLArray m_internalNodeLeafIndexRanges; //x == min leaf index, y == max leaf index - b3OpenCLArray m_internalNodeChildNodes; //x == left child, y == right child; msb(0x80000000) is set to indicate internal node - b3OpenCLArray m_internalNodeParentNodes; //For parent node index, msb(0x80000000) is not set since it is always internal - + b3OpenCLArray m_internalNodeLeafIndexRanges; //x == min leaf index, y == max leaf index + b3OpenCLArray m_internalNodeChildNodes; //x == left child, y == right child; msb(0x80000000) is set to indicate internal node + b3OpenCLArray m_internalNodeParentNodes; //For parent node index, msb(0x80000000) is not set since it is always internal + //1 element per internal node; for binary radix tree construction b3OpenCLArray m_commonPrefixes; b3OpenCLArray m_commonPrefixLengths; - b3OpenCLArray m_distanceFromRoot; //Number of internal nodes between this node and the root - + b3OpenCLArray m_distanceFromRoot; //Number of internal nodes between this node and the root + //1 element per leaf node (leaf nodes only include small AABBs) - b3OpenCLArray m_leafNodeParentNodes; //For parent node index, msb(0x80000000) is not set since it is always internal - b3OpenCLArray m_mortonCodesAndAabbIndicies; //m_key == morton code, m_value == aabb index in m_leafNodeAabbs - b3OpenCLArray m_mergedAabb; //m_mergedAabb[0] contains the merged AABB of all leaf nodes - b3OpenCLArray m_leafNodeAabbs; //Contains only small AABBs - + b3OpenCLArray m_leafNodeParentNodes; //For parent node index, msb(0x80000000) is not set since it is always internal + b3OpenCLArray m_mortonCodesAndAabbIndicies; //m_key == morton code, m_value == aabb index in m_leafNodeAabbs + b3OpenCLArray m_mergedAabb; //m_mergedAabb[0] contains the merged AABB of all leaf nodes + b3OpenCLArray m_leafNodeAabbs; //Contains only small AABBs + //1 element per large AABB, which is not stored in the BVH b3OpenCLArray m_largeAabbs; - + public: b3GpuParallelLinearBvh(cl_context context, cl_device_id device, cl_command_queue queue); virtual ~b3GpuParallelLinearBvh(); - + ///Must be called before any other function - void build(const b3OpenCLArray& worldSpaceAabbs, const b3OpenCLArray& smallAabbIndices, - const b3OpenCLArray& largeAabbIndices); - + void build(const b3OpenCLArray& worldSpaceAabbs, const b3OpenCLArray& smallAabbIndices, + const b3OpenCLArray& largeAabbIndices); + ///calculateOverlappingPairs() uses the worldSpaceAabbs parameter of b3GpuParallelLinearBvh::build() as the query AABBs. ///@param out_overlappingPairs The size() of this array is used to determine the max number of pairs. ///If the number of overlapping pairs is < out_overlappingPairs.size(), out_overlappingPairs is resized. void calculateOverlappingPairs(b3OpenCLArray& out_overlappingPairs); - + ///@param out_numRigidRayPairs Array of length 1; contains the number of detected ray-rigid AABB intersections; ///this value may be greater than out_rayRigidPairs.size() if out_rayRigidPairs is not large enough. ///@param out_rayRigidPairs Contains an array of rays intersecting rigid AABBs; x == ray index, y == rigid body index. ///If the size of this array is insufficient to hold all ray-rigid AABB intersections, additional intersections are discarded. - void testRaysAgainstBvhAabbs(const b3OpenCLArray& rays, - b3OpenCLArray& out_numRayRigidPairs, b3OpenCLArray& out_rayRigidPairs); - + void testRaysAgainstBvhAabbs(const b3OpenCLArray& rays, + b3OpenCLArray& out_numRayRigidPairs, b3OpenCLArray& out_rayRigidPairs); + private: void constructBinaryRadixTree(); }; diff --git a/src/Bullet3OpenCL/BroadphaseCollision/b3GpuParallelLinearBvhBroadphase.cpp b/src/Bullet3OpenCL/BroadphaseCollision/b3GpuParallelLinearBvhBroadphase.cpp index d2618024a..62ea7a32d 100644 --- a/src/Bullet3OpenCL/BroadphaseCollision/b3GpuParallelLinearBvhBroadphase.cpp +++ b/src/Bullet3OpenCL/BroadphaseCollision/b3GpuParallelLinearBvhBroadphase.cpp @@ -13,45 +13,44 @@ subject to the following restrictions: #include "b3GpuParallelLinearBvhBroadphase.h" -b3GpuParallelLinearBvhBroadphase::b3GpuParallelLinearBvhBroadphase(cl_context context, cl_device_id device, cl_command_queue queue) : - m_plbvh(context, device, queue), - - m_overlappingPairsGpu(context, queue), - - m_aabbsGpu(context, queue), - m_smallAabbsMappingGpu(context, queue), - m_largeAabbsMappingGpu(context, queue) +b3GpuParallelLinearBvhBroadphase::b3GpuParallelLinearBvhBroadphase(cl_context context, cl_device_id device, cl_command_queue queue) : m_plbvh(context, device, queue), + + m_overlappingPairsGpu(context, queue), + + m_aabbsGpu(context, queue), + m_smallAabbsMappingGpu(context, queue), + m_largeAabbsMappingGpu(context, queue) { } -void b3GpuParallelLinearBvhBroadphase::createProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr, int collisionFilterGroup, int collisionFilterMask) +void b3GpuParallelLinearBvhBroadphase::createProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr, int collisionFilterGroup, int collisionFilterMask) { int newAabbIndex = m_aabbsCpu.size(); b3SapAabb aabb; aabb.m_minVec = aabbMin; aabb.m_maxVec = aabbMax; - + aabb.m_minIndices[3] = userPtr; aabb.m_signedMaxIndices[3] = newAabbIndex; - + m_smallAabbsMappingCpu.push_back(newAabbIndex); - + m_aabbsCpu.push_back(aabb); } -void b3GpuParallelLinearBvhBroadphase::createLargeProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr, int collisionFilterGroup, int collisionFilterMask) +void b3GpuParallelLinearBvhBroadphase::createLargeProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr, int collisionFilterGroup, int collisionFilterMask) { int newAabbIndex = m_aabbsCpu.size(); b3SapAabb aabb; aabb.m_minVec = aabbMin; aabb.m_maxVec = aabbMax; - + aabb.m_minIndices[3] = userPtr; aabb.m_signedMaxIndices[3] = newAabbIndex; - + m_largeAabbsMappingCpu.push_back(newAabbIndex); - + m_aabbsCpu.push_back(aabb); } @@ -59,22 +58,19 @@ void b3GpuParallelLinearBvhBroadphase::calculateOverlappingPairs(int maxPairs) { //Reconstruct BVH m_plbvh.build(m_aabbsGpu, m_smallAabbsMappingGpu, m_largeAabbsMappingGpu); - + // m_overlappingPairsGpu.resize(maxPairs); m_plbvh.calculateOverlappingPairs(m_overlappingPairsGpu); } void b3GpuParallelLinearBvhBroadphase::calculateOverlappingPairsHost(int maxPairs) { - b3Assert(0); //CPU version not implemented + b3Assert(0); //CPU version not implemented } -void b3GpuParallelLinearBvhBroadphase::writeAabbsToGpu() -{ - m_aabbsGpu.copyFromHost(m_aabbsCpu); +void b3GpuParallelLinearBvhBroadphase::writeAabbsToGpu() +{ + m_aabbsGpu.copyFromHost(m_aabbsCpu); m_smallAabbsMappingGpu.copyFromHost(m_smallAabbsMappingCpu); m_largeAabbsMappingGpu.copyFromHost(m_largeAabbsMappingCpu); } - - - diff --git a/src/Bullet3OpenCL/BroadphaseCollision/b3GpuParallelLinearBvhBroadphase.h b/src/Bullet3OpenCL/BroadphaseCollision/b3GpuParallelLinearBvhBroadphase.h index e51850063..dda0eea7b 100644 --- a/src/Bullet3OpenCL/BroadphaseCollision/b3GpuParallelLinearBvhBroadphase.h +++ b/src/Bullet3OpenCL/BroadphaseCollision/b3GpuParallelLinearBvhBroadphase.h @@ -21,42 +21,42 @@ subject to the following restrictions: class b3GpuParallelLinearBvhBroadphase : public b3GpuBroadphaseInterface { b3GpuParallelLinearBvh m_plbvh; - + b3OpenCLArray m_overlappingPairsGpu; - + b3OpenCLArray m_aabbsGpu; b3OpenCLArray m_smallAabbsMappingGpu; b3OpenCLArray m_largeAabbsMappingGpu; - + b3AlignedObjectArray m_aabbsCpu; b3AlignedObjectArray m_smallAabbsMappingCpu; b3AlignedObjectArray m_largeAabbsMappingCpu; - + public: b3GpuParallelLinearBvhBroadphase(cl_context context, cl_device_id device, cl_command_queue queue); virtual ~b3GpuParallelLinearBvhBroadphase() {} - virtual void createProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr, int collisionFilterGroup, int collisionFilterMask); - virtual void createLargeProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr, int collisionFilterGroup, int collisionFilterMask); - + virtual void createProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr, int collisionFilterGroup, int collisionFilterMask); + virtual void createLargeProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr, int collisionFilterGroup, int collisionFilterMask); + virtual void calculateOverlappingPairs(int maxPairs); virtual void calculateOverlappingPairsHost(int maxPairs); //call writeAabbsToGpu after done making all changes (createProxy etc) virtual void writeAabbsToGpu(); - - virtual int getNumOverlap() { return m_overlappingPairsGpu.size(); } + + virtual int getNumOverlap() { return m_overlappingPairsGpu.size(); } virtual cl_mem getOverlappingPairBuffer() { return m_overlappingPairsGpu.getBufferCL(); } virtual cl_mem getAabbBufferWS() { return m_aabbsGpu.getBufferCL(); } virtual b3OpenCLArray& getAllAabbsGPU() { return m_aabbsGpu; } - + virtual b3OpenCLArray& getOverlappingPairsGPU() { return m_overlappingPairsGpu; } virtual b3OpenCLArray& getSmallAabbIndicesGPU() { return m_smallAabbsMappingGpu; } virtual b3OpenCLArray& getLargeAabbIndicesGPU() { return m_largeAabbsMappingGpu; } - + virtual b3AlignedObjectArray& getAllAabbsCPU() { return m_aabbsCpu; } - + static b3GpuBroadphaseInterface* CreateFunc(cl_context context, cl_device_id device, cl_command_queue queue) { return new b3GpuParallelLinearBvhBroadphase(context, device, queue); diff --git a/src/Bullet3OpenCL/BroadphaseCollision/b3GpuSapBroadphase.cpp b/src/Bullet3OpenCL/BroadphaseCollision/b3GpuSapBroadphase.cpp index c45fbbdca..db9030f66 100644 --- a/src/Bullet3OpenCL/BroadphaseCollision/b3GpuSapBroadphase.cpp +++ b/src/Bullet3OpenCL/BroadphaseCollision/b3GpuSapBroadphase.cpp @@ -6,7 +6,6 @@ bool searchIncremental3dSapOnGpu = true; #include "Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h" #include "Bullet3OpenCL/ParallelPrimitives/b3PrefixScanFloat4CL.h" - #include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h" #include "kernels/sapKernels.h" @@ -56,110 +55,105 @@ bool searchIncremental3dSapOnGpu = true; class b3PrefixScanFloat4CL* m_prefixScanFloat4; */ -b3GpuSapBroadphase::b3GpuSapBroadphase(cl_context ctx,cl_device_id device, cl_command_queue q , b3GpuSapKernelType kernelType) -:m_context(ctx), -m_device(device), -m_queue(q), +b3GpuSapBroadphase::b3GpuSapBroadphase(cl_context ctx, cl_device_id device, cl_command_queue q, b3GpuSapKernelType kernelType) + : m_context(ctx), + m_device(device), + m_queue(q), -m_objectMinMaxIndexGPUaxis0(ctx,q), -m_objectMinMaxIndexGPUaxis1(ctx,q), -m_objectMinMaxIndexGPUaxis2(ctx,q), -m_objectMinMaxIndexGPUaxis0prev(ctx,q), -m_objectMinMaxIndexGPUaxis1prev(ctx,q), -m_objectMinMaxIndexGPUaxis2prev(ctx,q), -m_sortedAxisGPU0(ctx,q), -m_sortedAxisGPU1(ctx,q), -m_sortedAxisGPU2(ctx,q), -m_sortedAxisGPU0prev(ctx,q), -m_sortedAxisGPU1prev(ctx,q), -m_sortedAxisGPU2prev(ctx,q), -m_addedHostPairsGPU(ctx,q), -m_removedHostPairsGPU(ctx,q), -m_addedCountGPU(ctx,q), -m_removedCountGPU(ctx,q), -m_currentBuffer(-1), -m_pairCount(ctx,q), -m_allAabbsGPU(ctx,q), -m_sum(ctx,q), -m_sum2(ctx,q), -m_dst(ctx,q), -m_smallAabbsMappingGPU(ctx,q), -m_largeAabbsMappingGPU(ctx,q), -m_overlappingPairs(ctx,q), -m_gpuSmallSortData(ctx,q), -m_gpuSmallSortedAabbs(ctx,q) + m_objectMinMaxIndexGPUaxis0(ctx, q), + m_objectMinMaxIndexGPUaxis1(ctx, q), + m_objectMinMaxIndexGPUaxis2(ctx, q), + m_objectMinMaxIndexGPUaxis0prev(ctx, q), + m_objectMinMaxIndexGPUaxis1prev(ctx, q), + m_objectMinMaxIndexGPUaxis2prev(ctx, q), + m_sortedAxisGPU0(ctx, q), + m_sortedAxisGPU1(ctx, q), + m_sortedAxisGPU2(ctx, q), + m_sortedAxisGPU0prev(ctx, q), + m_sortedAxisGPU1prev(ctx, q), + m_sortedAxisGPU2prev(ctx, q), + m_addedHostPairsGPU(ctx, q), + m_removedHostPairsGPU(ctx, q), + m_addedCountGPU(ctx, q), + m_removedCountGPU(ctx, q), + m_currentBuffer(-1), + m_pairCount(ctx, q), + m_allAabbsGPU(ctx, q), + m_sum(ctx, q), + m_sum2(ctx, q), + m_dst(ctx, q), + m_smallAabbsMappingGPU(ctx, q), + m_largeAabbsMappingGPU(ctx, q), + m_overlappingPairs(ctx, q), + m_gpuSmallSortData(ctx, q), + m_gpuSmallSortedAabbs(ctx, q) { const char* sapSrc = sapCL; - - - cl_int errNum=0; + + cl_int errNum = 0; b3Assert(m_context); b3Assert(m_device); - cl_program sapProg = b3OpenCLUtils::compileCLProgramFromString(m_context,m_device,sapSrc,&errNum,"",B3_BROADPHASE_SAP_PATH); - b3Assert(errNum==CL_SUCCESS); + cl_program sapProg = b3OpenCLUtils::compileCLProgramFromString(m_context, m_device, sapSrc, &errNum, "", B3_BROADPHASE_SAP_PATH); + b3Assert(errNum == CL_SUCCESS); - - b3Assert(errNum==CL_SUCCESS); + b3Assert(errNum == CL_SUCCESS); #ifndef __APPLE__ - m_prefixScanFloat4 = new b3PrefixScanFloat4CL(m_context,m_device,m_queue); + m_prefixScanFloat4 = new b3PrefixScanFloat4CL(m_context, m_device, m_queue); #else m_prefixScanFloat4 = 0; #endif m_sapKernel = 0; - + switch (kernelType) { case B3_GPU_SAP_KERNEL_BRUTE_FORCE_CPU: { - m_sapKernel=0; + m_sapKernel = 0; break; } - case B3_GPU_SAP_KERNEL_BRUTE_FORCE_GPU: + case B3_GPU_SAP_KERNEL_BRUTE_FORCE_GPU: { - m_sapKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,sapSrc, "computePairsKernelBruteForce",&errNum,sapProg ); + m_sapKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, sapSrc, "computePairsKernelBruteForce", &errNum, sapProg); break; } case B3_GPU_SAP_KERNEL_ORIGINAL: { - m_sapKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,sapSrc, "computePairsKernelOriginal",&errNum,sapProg ); + m_sapKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, sapSrc, "computePairsKernelOriginal", &errNum, sapProg); break; } case B3_GPU_SAP_KERNEL_BARRIER: { - m_sapKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,sapSrc, "computePairsKernelBarrier",&errNum,sapProg ); + m_sapKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, sapSrc, "computePairsKernelBarrier", &errNum, sapProg); break; } case B3_GPU_SAP_KERNEL_LOCAL_SHARED_MEMORY: { - m_sapKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,sapSrc, "computePairsKernelLocalSharedMemory",&errNum,sapProg ); + m_sapKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, sapSrc, "computePairsKernelLocalSharedMemory", &errNum, sapProg); break; } default: { - m_sapKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,sapSrc, "computePairsKernelLocalSharedMemory",&errNum,sapProg ); + m_sapKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, sapSrc, "computePairsKernelLocalSharedMemory", &errNum, sapProg); b3Error("Unknown 3D GPU SAP provided, fallback to computePairsKernelLocalSharedMemory"); } }; - - - - m_sap2Kernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,sapSrc, "computePairsKernelTwoArrays",&errNum,sapProg ); - b3Assert(errNum==CL_SUCCESS); - m_prepareSumVarianceKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,sapSrc, "prepareSumVarianceKernel",&errNum,sapProg ); - b3Assert(errNum==CL_SUCCESS); + m_sap2Kernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, sapSrc, "computePairsKernelTwoArrays", &errNum, sapProg); + b3Assert(errNum == CL_SUCCESS); - - m_flipFloatKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,sapSrc, "flipFloatKernel",&errNum,sapProg ); + m_prepareSumVarianceKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, sapSrc, "prepareSumVarianceKernel", &errNum, sapProg); + b3Assert(errNum == CL_SUCCESS); - m_copyAabbsKernel= b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,sapSrc, "copyAabbsKernel",&errNum,sapProg ); + m_flipFloatKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, sapSrc, "flipFloatKernel", &errNum, sapProg); - m_scatterKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,sapSrc, "scatterKernel",&errNum,sapProg ); + m_copyAabbsKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, sapSrc, "copyAabbsKernel", &errNum, sapProg); - m_sorter = new b3RadixSort32CL(m_context,m_device,m_queue); + m_scatterKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, sapSrc, "scatterKernel", &errNum, sapProg); + + m_sorter = new b3RadixSort32CL(m_context, m_device, m_queue); } b3GpuSapBroadphase::~b3GpuSapBroadphase() @@ -173,13 +167,11 @@ b3GpuSapBroadphase::~b3GpuSapBroadphase() clReleaseKernel(m_sapKernel); clReleaseKernel(m_sap2Kernel); clReleaseKernel(m_prepareSumVarianceKernel); - - } /// conservative test for overlap between two aabbs -static bool TestAabbAgainstAabb2(const b3Vector3 &aabbMin1, const b3Vector3 &aabbMax1, - const b3Vector3 &aabbMin2, const b3Vector3 &aabbMax2) +static bool TestAabbAgainstAabb2(const b3Vector3& aabbMin1, const b3Vector3& aabbMax1, + const b3Vector3& aabbMin2, const b3Vector3& aabbMax2) { bool overlap = true; overlap = (aabbMin1.getX() > aabbMax2.getX() || aabbMax1.getX() < aabbMin2.getX()) ? false : overlap; @@ -188,8 +180,6 @@ static bool TestAabbAgainstAabb2(const b3Vector3 &aabbMin1, const b3Vector3 &aab return overlap; } - - //http://stereopsis.com/radix.html static unsigned int FloatFlip(float fl) { @@ -198,79 +188,77 @@ static unsigned int FloatFlip(float fl) return f ^ mask; }; -void b3GpuSapBroadphase::init3dSap() +void b3GpuSapBroadphase::init3dSap() { - if (m_currentBuffer<0) + if (m_currentBuffer < 0) { m_allAabbsGPU.copyToHost(m_allAabbsCPU); m_currentBuffer = 0; - for (int axis=0;axis<3;axis++) + for (int axis = 0; axis < 3; axis++) { - for (int buf=0;buf<2;buf++) + for (int buf = 0; buf < 2; buf++) { int totalNumAabbs = m_allAabbsCPU.size(); - int numEndPoints = 2*totalNumAabbs; + int numEndPoints = 2 * totalNumAabbs; m_sortedAxisCPU[axis][buf].resize(numEndPoints); - if (buf==m_currentBuffer) + if (buf == m_currentBuffer) { - for (int i=0;iexecuteHost(m_sortedAxisCPU[axis][m_currentBuffer]); } - for (int axis=0;axis<3;axis++) + for (int axis = 0; axis < 3; axis++) { //int totalNumAabbs = m_allAabbsCPU.size(); int numEndPoints = m_sortedAxisCPU[axis][m_currentBuffer].size(); m_objectMinMaxIndexCPU[axis][m_currentBuffer].resize(numEndPoints); - for (int i=0;i(const b3Int4& a,const b3Int4& b) +static bool operator>(const b3Int4& a, const b3Int4& b) { return a.x > b.x || (a.x == b.x && a.y > b.y); }; @@ -278,31 +266,29 @@ static bool operator>(const b3Int4& a,const b3Int4& b) b3AlignedObjectArray addedHostPairs; b3AlignedObjectArray removedHostPairs; -b3AlignedObjectArray preAabbs; +b3AlignedObjectArray preAabbs; -void b3GpuSapBroadphase::calculateOverlappingPairsHostIncremental3Sap() +void b3GpuSapBroadphase::calculateOverlappingPairsHostIncremental3Sap() { //static int framepje = 0; //printf("framepje=%d\n",framepje++); - B3_PROFILE("calculateOverlappingPairsHostIncremental3Sap"); addedHostPairs.resize(0); removedHostPairs.resize(0); - b3Assert(m_currentBuffer>=0); - + b3Assert(m_currentBuffer >= 0); + { preAabbs.resize(m_allAabbsCPU.size()); - for (int i=0;iexecuteHost(m_sortedAxisCPU[axis][m_currentBuffer]); } @@ -432,21 +405,22 @@ void b3GpuSapBroadphase::calculateOverlappingPairsHostIncremental3Sap() { B3_PROFILE("assign m_objectMinMaxIndexCPU"); - for (int axis=0;axis<3;axis++) + for (int axis = 0; axis < 3; axis++) { int totalNumAabbs = m_allAabbsCPU.size(); int numEndPoints = m_sortedAxisCPU[axis][m_currentBuffer].size(); m_objectMinMaxIndexCPU[axis][m_currentBuffer].resize(totalNumAabbs); - for (int i=0;i m_objectMinMaxIndexCPU[ax][m_currentBuffer][otherIndex].y) || (m_objectMinMaxIndexCPU[ax][m_currentBuffer][i].y < m_objectMinMaxIndexCPU[ax][m_currentBuffer][otherIndex].x)) - overlap=false; + overlap = false; } - // b3Assert(overlap2==overlap); + // b3Assert(overlap2==overlap); bool prevOverlap = true; - for (int ax=0;ax<3;ax++) + for (int ax = 0; ax < 3; ax++) { - if ((m_objectMinMaxIndexCPU[ax][1-m_currentBuffer][i].x > m_objectMinMaxIndexCPU[ax][1-m_currentBuffer][otherIndex].y) || - (m_objectMinMaxIndexCPU[ax][1-m_currentBuffer][i].y < m_objectMinMaxIndexCPU[ax][1-m_currentBuffer][otherIndex].x)) - prevOverlap=false; + if ((m_objectMinMaxIndexCPU[ax][1 - m_currentBuffer][i].x > m_objectMinMaxIndexCPU[ax][1 - m_currentBuffer][otherIndex].y) || + (m_objectMinMaxIndexCPU[ax][1 - m_currentBuffer][i].y < m_objectMinMaxIndexCPU[ax][1 - m_currentBuffer][otherIndex].x)) + prevOverlap = false; } - //b3Assert(overlap==overlap2); - - - if (dmin<0) + if (dmin < 0) { if (overlap && !prevOverlap) { //add a pair b3Int4 newPair; - if (i<=otherIndex) + if (i <= otherIndex) { newPair.x = i; newPair.y = otherIndex; - } else + } + else { newPair.x = otherIndex; newPair.y = i; } addedHostPairs.push_back(newPair); } - } + } else { if (!overlap && prevOverlap) { - //remove a pair b3Int4 removedPair; - if (i<=otherIndex) + if (i <= otherIndex) { removedPair.x = i; removedPair.y = otherIndex; - } else + } + else { removedPair.x = otherIndex; removedPair.y = i; } removedHostPairs.push_back(removedPair); } - }//otherisMax - }//if (dmin<0) - }//if (otherIndex!=i) - }//for (int j= + } //otherisMax + } //if (dmin<0) + } //if (otherIndex!=i) + } //for (int j= } - - if (dmax!=0) + + if (dmax != 0) { - int stepMax = dmax<0 ? -1 : 1; - for (int j=prevMaxIndex;j!=curMaxIndex;j+=stepMax) + int stepMax = dmax < 0 ? -1 : 1; + for (int j = prevMaxIndex; j != curMaxIndex; j += stepMax) { int otherIndex2 = m_sortedAxisCPU[axis][otherbuffer][j].y; - int otherIndex = otherIndex2/2; - if (otherIndex!=i) + int otherIndex = otherIndex2 / 2; + if (otherIndex != i) { //bool otherIsMin = ((otherIndex2&1)==0); //if (otherIsMin) { //bool overlap = TestAabbAgainstAabb2((const b3Vector3&)m_allAabbsCPU[i].m_min, (const b3Vector3&)m_allAabbsCPU[i].m_max,(const b3Vector3&)m_allAabbsCPU[otherIndex].m_min,(const b3Vector3&)m_allAabbsCPU[otherIndex].m_max); //bool prevOverlap = TestAabbAgainstAabb2((const b3Vector3&)preAabbs[i].m_min, (const b3Vector3&)preAabbs[i].m_max,(const b3Vector3&)preAabbs[otherIndex].m_min,(const b3Vector3&)preAabbs[otherIndex].m_max); - + bool overlap = true; - for (int ax=0;ax<3;ax++) + for (int ax = 0; ax < 3; ax++) { if ((m_objectMinMaxIndexCPU[ax][m_currentBuffer][i].x > m_objectMinMaxIndexCPU[ax][m_currentBuffer][otherIndex].y) || (m_objectMinMaxIndexCPU[ax][m_currentBuffer][i].y < m_objectMinMaxIndexCPU[ax][m_currentBuffer][otherIndex].x)) - overlap=false; + overlap = false; } //b3Assert(overlap2==overlap); bool prevOverlap = true; - for (int ax=0;ax<3;ax++) + for (int ax = 0; ax < 3; ax++) { - if ((m_objectMinMaxIndexCPU[ax][1-m_currentBuffer][i].x > m_objectMinMaxIndexCPU[ax][1-m_currentBuffer][otherIndex].y) || - (m_objectMinMaxIndexCPU[ax][1-m_currentBuffer][i].y < m_objectMinMaxIndexCPU[ax][1-m_currentBuffer][otherIndex].x)) - prevOverlap=false; + if ((m_objectMinMaxIndexCPU[ax][1 - m_currentBuffer][i].x > m_objectMinMaxIndexCPU[ax][1 - m_currentBuffer][otherIndex].y) || + (m_objectMinMaxIndexCPU[ax][1 - m_currentBuffer][i].y < m_objectMinMaxIndexCPU[ax][1 - m_currentBuffer][otherIndex].x)) + prevOverlap = false; } - - if (dmax>0) + if (dmax > 0) { if (overlap && !prevOverlap) { //add a pair b3Int4 newPair; - if (i<=otherIndex) + if (i <= otherIndex) { newPair.x = i; newPair.y = otherIndex; - } else + } + else { newPair.x = otherIndex; newPair.y = i; } addedHostPairs.push_back(newPair); - } - } + } else { if (!overlap && prevOverlap) @@ -750,33 +718,31 @@ void b3GpuSapBroadphase::calculateOverlappingPairsHostIncremental3Sap() //if (otherIndex2&1==0) -> min? //remove a pair b3Int4 removedPair; - if (i<=otherIndex) + if (i <= otherIndex) { removedPair.x = i; removedPair.y = otherIndex; - } else + } + else { removedPair.x = otherIndex; removedPair.y = i; } removedHostPairs.push_back(removedPair); - } } - - }//if (dmin<0) - }//if (otherIndex!=i) - }//for (int j= + + } //if (dmin<0) + } //if (otherIndex!=i) + } //for (int j= } - }//for (int otherbuffer - }//for (int axis=0; - }//for (int i=0;i removedPositions; { B3_PROFILE("actual removing"); - for (int i=0;i actualAddedPairs; { B3_PROFILE("actual adding"); - for (int i=0;i=0) + // if (m_currentBuffer>=0) // return calculateOverlappingPairsHostIncremental3Sap(); b3Assert(m_allAabbsCPU.size() == m_allAabbsGPU.size()); m_allAabbsGPU.copyToHost(m_allAabbsCPU); - - - int axis=0; + int axis = 0; { B3_PROFILE("CPU compute best variance axis"); - b3Vector3 s=b3MakeVector3(0,0,0),s2=b3MakeVector3(0,0,0); + b3Vector3 s = b3MakeVector3(0, 0, 0), s2 = b3MakeVector3(0, 0, 0); int numRigidBodies = m_smallAabbsMappingCPU.size(); - for(int i=0;im_allAabbsCPU[m_smallAabbsMappingCPU[i]]; - b3Vector3 maxAabb=b3MakeVector3(aabb.m_max[0],aabb.m_max[1],aabb.m_max[2]); - b3Vector3 minAabb=b3MakeVector3(aabb.m_min[0],aabb.m_min[1],aabb.m_min[2]); - b3Vector3 centerAabb=(maxAabb+minAabb)*0.5f; - + b3Vector3 maxAabb = b3MakeVector3(aabb.m_max[0], aabb.m_max[1], aabb.m_max[2]); + b3Vector3 minAabb = b3MakeVector3(aabb.m_min[0], aabb.m_min[1], aabb.m_min[2]); + b3Vector3 centerAabb = (maxAabb + minAabb) * 0.5f; + s += centerAabb; - s2 += centerAabb*centerAabb; + s2 += centerAabb * centerAabb; } - b3Vector3 v = s2 - (s*s) / (float)numRigidBodies; - - if(v[1] > v[0]) + b3Vector3 v = s2 - (s * s) / (float)numRigidBodies; + + if (v[1] > v[0]) axis = 1; - if(v[2] > v[axis]) + if (v[2] > v[axis]) axis = 2; } - - - b3AlignedObjectArray hostPairs; { int numSmallAabbs = m_smallAabbsMappingCPU.size(); - for (int i=0;iexecute(m_sum, m_dst, numSmallAabbs + 1, &s); + m_prefixScanFloat4->execute(m_sum2, m_dst, numSmallAabbs + 1, &s2); + + b3Vector3 v = s2 - (s * s) / (float)numSmallAabbs; + + if (v[1] > v[0]) + axis = 1; + if (v[2] > v[axis]) + axis = 2; } - b3LauncherCL launcher(m_queue, m_prepareSumVarianceKernel ,"m_prepareSumVarianceKernel"); - launcher.setBuffer(m_allAabbsGPU.getBufferCL()); - - launcher.setBuffer(m_smallAabbsMappingGPU.getBufferCL()); - launcher.setBuffer(m_sum.getBufferCL()); - launcher.setBuffer(m_sum2.getBufferCL()); - launcher.setConst( numSmallAabbs ); - int num = numSmallAabbs; - launcher.launch1D( num); - - - b3Vector3 s; - b3Vector3 s2; - m_prefixScanFloat4->execute(m_sum,m_dst,numSmallAabbs+1,&s); - m_prefixScanFloat4->execute(m_sum2,m_dst,numSmallAabbs+1,&s2); - - b3Vector3 v = s2 - (s*s) / (float)numSmallAabbs; - - if(v[1] > v[0]) - axis = 1; - if(v[2] > v[axis]) - axis = 2; - } - - - m_gpuSmallSortData.resize(numSmallAabbs); - #if 1 if (m_smallAabbsMappingGPU.size()) { - B3_PROFILE("flipFloatKernel"); - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( m_allAabbsGPU.getBufferCL(), true ), - b3BufferInfoCL( m_smallAabbsMappingGPU.getBufferCL(), true), - b3BufferInfoCL( m_gpuSmallSortData.getBufferCL())}; - b3LauncherCL launcher(m_queue, m_flipFloatKernel ,"m_flipFloatKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( numSmallAabbs ); - launcher.setConst( axis ); - + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(m_allAabbsGPU.getBufferCL(), true), + b3BufferInfoCL(m_smallAabbsMappingGPU.getBufferCL(), true), + b3BufferInfoCL(m_gpuSmallSortData.getBufferCL())}; + b3LauncherCL launcher(m_queue, m_flipFloatKernel, "m_flipFloatKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(numSmallAabbs); + launcher.setConst(axis); + int num = numSmallAabbs; - launcher.launch1D( num); + launcher.launch1D(num); clFinish(m_queue); } @@ -1141,69 +1082,66 @@ void b3GpuSapBroadphase::calculateOverlappingPairs(int maxPairs) if (numSmallAabbs) { B3_PROFILE("scatterKernel"); - - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( m_allAabbsGPU.getBufferCL(), true ), - b3BufferInfoCL( m_smallAabbsMappingGPU.getBufferCL(), true), - b3BufferInfoCL( m_gpuSmallSortData.getBufferCL(),true), + + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(m_allAabbsGPU.getBufferCL(), true), + b3BufferInfoCL(m_smallAabbsMappingGPU.getBufferCL(), true), + b3BufferInfoCL(m_gpuSmallSortData.getBufferCL(), true), b3BufferInfoCL(m_gpuSmallSortedAabbs.getBufferCL())}; - b3LauncherCL launcher(m_queue, m_scatterKernel ,"m_scatterKernel "); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( numSmallAabbs); + b3LauncherCL launcher(m_queue, m_scatterKernel, "m_scatterKernel "); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(numSmallAabbs); int num = numSmallAabbs; - launcher.launch1D( num); + launcher.launch1D(num); clFinish(m_queue); - } - - m_overlappingPairs.resize(maxPairs); + m_overlappingPairs.resize(maxPairs); - m_pairCount.resize(0); - m_pairCount.push_back(0); - int numPairs=0; + m_pairCount.resize(0); + m_pairCount.push_back(0); + int numPairs = 0; + { + int numLargeAabbs = m_largeAabbsMappingGPU.size(); + if (numLargeAabbs && numSmallAabbs) { - int numLargeAabbs = m_largeAabbsMappingGPU.size(); - if (numLargeAabbs && numSmallAabbs) + //@todo + B3_PROFILE("sap2Kernel"); + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(m_allAabbsGPU.getBufferCL()), + b3BufferInfoCL(m_largeAabbsMappingGPU.getBufferCL()), + b3BufferInfoCL(m_smallAabbsMappingGPU.getBufferCL()), + b3BufferInfoCL(m_overlappingPairs.getBufferCL()), + b3BufferInfoCL(m_pairCount.getBufferCL())}; + b3LauncherCL launcher(m_queue, m_sap2Kernel, "m_sap2Kernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(numLargeAabbs); + launcher.setConst(numSmallAabbs); + launcher.setConst(axis); + launcher.setConst(maxPairs); + //@todo: use actual maximum work item sizes of the device instead of hardcoded values + launcher.launch2D(numLargeAabbs, numSmallAabbs, 4, 64); + + numPairs = m_pairCount.at(0); + if (numPairs > maxPairs) { - //@todo - B3_PROFILE("sap2Kernel"); - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( m_allAabbsGPU.getBufferCL() ), - b3BufferInfoCL( m_largeAabbsMappingGPU.getBufferCL() ), - b3BufferInfoCL( m_smallAabbsMappingGPU.getBufferCL() ), - b3BufferInfoCL( m_overlappingPairs.getBufferCL() ), - b3BufferInfoCL(m_pairCount.getBufferCL())}; - b3LauncherCL launcher(m_queue, m_sap2Kernel,"m_sap2Kernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( numLargeAabbs ); - launcher.setConst( numSmallAabbs); - launcher.setConst( axis ); - launcher.setConst( maxPairs ); -//@todo: use actual maximum work item sizes of the device instead of hardcoded values - launcher.launch2D( numLargeAabbs, numSmallAabbs,4,64); - - numPairs = m_pairCount.at(0); - if (numPairs >maxPairs) - { - b3Error("Error running out of pairs: numPairs = %d, maxPairs = %d.\n", numPairs, maxPairs); - numPairs =maxPairs; - } + b3Error("Error running out of pairs: numPairs = %d, maxPairs = %d.\n", numPairs, maxPairs); + numPairs = maxPairs; } } - if (m_gpuSmallSortedAabbs.size()) - { - B3_PROFILE("sapKernel"); - b3BufferInfoCL bInfo[] = { b3BufferInfoCL( m_gpuSmallSortedAabbs.getBufferCL() ), b3BufferInfoCL( m_overlappingPairs.getBufferCL() ), b3BufferInfoCL(m_pairCount.getBufferCL())}; - b3LauncherCL launcher(m_queue, m_sapKernel,"m_sapKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( numSmallAabbs ); - launcher.setConst( axis ); - launcher.setConst( maxPairs ); + } + if (m_gpuSmallSortedAabbs.size()) + { + B3_PROFILE("sapKernel"); + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(m_gpuSmallSortedAabbs.getBufferCL()), b3BufferInfoCL(m_overlappingPairs.getBufferCL()), b3BufferInfoCL(m_pairCount.getBufferCL())}; + b3LauncherCL launcher(m_queue, m_sapKernel, "m_sapKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(numSmallAabbs); + launcher.setConst(axis); + launcher.setConst(maxPairs); - - int num = numSmallAabbs; + int num = numSmallAabbs; #if 0 int buffSize = launcher.getSerializationBufferSize(); unsigned char* buf = new unsigned char[buffSize+sizeof(int)]; @@ -1225,72 +1163,70 @@ void b3GpuSapBroadphase::calculateOverlappingPairs(int maxPairs) FILE* f = fopen("m_sapKernelArgs.bin","wb"); fwrite(buf,buffSize+sizeof(int),1,f); fclose(f); -#endif// +#endif // - launcher.launch1D( num); - clFinish(m_queue); - - numPairs = m_pairCount.at(0); - if (numPairs>maxPairs) - { - b3Error("Error running out of pairs: numPairs = %d, maxPairs = %d.\n", numPairs, maxPairs); - numPairs = maxPairs; - m_pairCount.resize(0); - m_pairCount.push_back(maxPairs); - } + launcher.launch1D(num); + clFinish(m_queue); + + numPairs = m_pairCount.at(0); + if (numPairs > maxPairs) + { + b3Error("Error running out of pairs: numPairs = %d, maxPairs = %d.\n", numPairs, maxPairs); + numPairs = maxPairs; + m_pairCount.resize(0); + m_pairCount.push_back(maxPairs); } - + } + #else - int numPairs = 0; - - - b3LauncherCL launcher(m_queue, m_sapKernel); + int numPairs = 0; - const char* fileName = "m_sapKernelArgs.bin"; - FILE* f = fopen(fileName,"rb"); - if (f) - { - int sizeInBytes=0; - if (fseek(f, 0, SEEK_END) || (sizeInBytes = ftell(f)) == EOF || fseek(f, 0, SEEK_SET)) - { - printf("error, cannot get file size\n"); - exit(0); - } - - unsigned char* buf = (unsigned char*) malloc(sizeInBytes); - fread(buf,sizeInBytes,1,f); - int serializedBytes = launcher.deserializeArgs(buf, sizeInBytes,m_context); - int num = *(int*)&buf[serializedBytes]; - launcher.launch1D( num); - - b3OpenCLArray pairCount(m_context, m_queue); - int numElements = launcher.m_arrays[2]->size()/sizeof(int); - pairCount.setFromOpenCLBuffer(launcher.m_arrays[2]->getBufferCL(),numElements); - numPairs = pairCount.at(0); - //printf("overlapping pairs = %d\n",numPairs); - b3AlignedObjectArray hostOoverlappingPairs; - b3OpenCLArray tmpGpuPairs(m_context,m_queue); - tmpGpuPairs.setFromOpenCLBuffer(launcher.m_arrays[1]->getBufferCL(),numPairs ); - - tmpGpuPairs.copyToHost(hostOoverlappingPairs); - m_overlappingPairs.copyFromHost(hostOoverlappingPairs); - //printf("hello %d\n", m_overlappingPairs.size()); - free(buf); - fclose(f); - - } else { - printf("error: cannot find file %s\n",fileName); - } - - clFinish(m_queue); + b3LauncherCL launcher(m_queue, m_sapKernel); + + const char* fileName = "m_sapKernelArgs.bin"; + FILE* f = fopen(fileName, "rb"); + if (f) + { + int sizeInBytes = 0; + if (fseek(f, 0, SEEK_END) || (sizeInBytes = ftell(f)) == EOF || fseek(f, 0, SEEK_SET)) + { + printf("error, cannot get file size\n"); + exit(0); + } + + unsigned char* buf = (unsigned char*)malloc(sizeInBytes); + fread(buf, sizeInBytes, 1, f); + int serializedBytes = launcher.deserializeArgs(buf, sizeInBytes, m_context); + int num = *(int*)&buf[serializedBytes]; + launcher.launch1D(num); + + b3OpenCLArray pairCount(m_context, m_queue); + int numElements = launcher.m_arrays[2]->size() / sizeof(int); + pairCount.setFromOpenCLBuffer(launcher.m_arrays[2]->getBufferCL(), numElements); + numPairs = pairCount.at(0); + //printf("overlapping pairs = %d\n",numPairs); + b3AlignedObjectArray hostOoverlappingPairs; + b3OpenCLArray tmpGpuPairs(m_context, m_queue); + tmpGpuPairs.setFromOpenCLBuffer(launcher.m_arrays[1]->getBufferCL(), numPairs); + + tmpGpuPairs.copyToHost(hostOoverlappingPairs); + m_overlappingPairs.copyFromHost(hostOoverlappingPairs); + //printf("hello %d\n", m_overlappingPairs.size()); + free(buf); + fclose(f); + } + else + { + printf("error: cannot find file %s\n", fileName); + } + + clFinish(m_queue); - #endif - - m_overlappingPairs.resize(numPairs); - - }//B3_PROFILE("GPU_RADIX SORT"); + m_overlappingPairs.resize(numPairs); + + } //B3_PROFILE("GPU_RADIX SORT"); //init3dSap(); } @@ -1299,17 +1235,14 @@ void b3GpuSapBroadphase::writeAabbsToGpu() m_smallAabbsMappingGPU.copyFromHost(m_smallAabbsMappingCPU); m_largeAabbsMappingGPU.copyFromHost(m_largeAabbsMappingCPU); - m_allAabbsGPU.copyFromHost(m_allAabbsCPU);//might not be necessary, the 'setupGpuAabbsFull' already takes care of this - - - + m_allAabbsGPU.copyFromHost(m_allAabbsCPU); //might not be necessary, the 'setupGpuAabbsFull' already takes care of this } -void b3GpuSapBroadphase::createLargeProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr , int collisionFilterGroup, int collisionFilterMask) +void b3GpuSapBroadphase::createLargeProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr, int collisionFilterGroup, int collisionFilterMask) { int index = userPtr; b3SapAabb aabb; - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) { aabb.m_min[i] = aabbMin[i]; aabb.m_max[i] = aabbMax[i]; @@ -1317,15 +1250,15 @@ void b3GpuSapBroadphase::createLargeProxy(const b3Vector3& aabbMin, const b3Vec aabb.m_minIndices[3] = index; aabb.m_signedMaxIndices[3] = m_allAabbsCPU.size(); m_largeAabbsMappingCPU.push_back(m_allAabbsCPU.size()); - + m_allAabbsCPU.push_back(aabb); } -void b3GpuSapBroadphase::createProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr , int collisionFilterGroup, int collisionFilterMask) +void b3GpuSapBroadphase::createProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr, int collisionFilterGroup, int collisionFilterMask) { int index = userPtr; b3SapAabb aabb; - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) { aabb.m_min[i] = aabbMin[i]; aabb.m_max[i] = aabbMax[i]; @@ -1334,20 +1267,19 @@ void b3GpuSapBroadphase::createProxy(const b3Vector3& aabbMin, const b3Vector3& aabb.m_signedMaxIndices[3] = m_allAabbsCPU.size(); m_smallAabbsMappingCPU.push_back(m_allAabbsCPU.size()); - m_allAabbsCPU.push_back(aabb); } -cl_mem b3GpuSapBroadphase::getAabbBufferWS() +cl_mem b3GpuSapBroadphase::getAabbBufferWS() { return m_allAabbsGPU.getBufferCL(); } -int b3GpuSapBroadphase::getNumOverlap() +int b3GpuSapBroadphase::getNumOverlap() { return m_overlappingPairs.size(); } -cl_mem b3GpuSapBroadphase::getOverlappingPairBuffer() +cl_mem b3GpuSapBroadphase::getOverlappingPairBuffer() { return m_overlappingPairs.getBufferCL(); } diff --git a/src/Bullet3OpenCL/BroadphaseCollision/b3GpuSapBroadphase.h b/src/Bullet3OpenCL/BroadphaseCollision/b3GpuSapBroadphase.h index 8d36ac78f..d17590b14 100644 --- a/src/Bullet3OpenCL/BroadphaseCollision/b3GpuSapBroadphase.h +++ b/src/Bullet3OpenCL/BroadphaseCollision/b3GpuSapBroadphase.h @@ -2,7 +2,7 @@ #define B3_GPU_SAP_BROADPHASE_H #include "Bullet3OpenCL/ParallelPrimitives/b3OpenCLArray.h" -#include "Bullet3OpenCL/ParallelPrimitives/b3FillCL.h" //b3Int2 +#include "Bullet3OpenCL/ParallelPrimitives/b3FillCL.h" //b3Int2 class b3Vector3; #include "Bullet3OpenCL/ParallelPrimitives/b3RadixSort32CL.h" @@ -11,141 +11,133 @@ class b3Vector3; #include "b3GpuBroadphaseInterface.h" - class b3GpuSapBroadphase : public b3GpuBroadphaseInterface { - - cl_context m_context; - cl_device_id m_device; - cl_command_queue m_queue; - cl_kernel m_flipFloatKernel; - cl_kernel m_scatterKernel ; - cl_kernel m_copyAabbsKernel; - cl_kernel m_sapKernel; - cl_kernel m_sap2Kernel; - cl_kernel m_prepareSumVarianceKernel; - + cl_context m_context; + cl_device_id m_device; + cl_command_queue m_queue; + cl_kernel m_flipFloatKernel; + cl_kernel m_scatterKernel; + cl_kernel m_copyAabbsKernel; + cl_kernel m_sapKernel; + cl_kernel m_sap2Kernel; + cl_kernel m_prepareSumVarianceKernel; class b3RadixSort32CL* m_sorter; ///test for 3d SAP - b3AlignedObjectArray m_sortedAxisCPU[3][2]; - b3AlignedObjectArray m_objectMinMaxIndexCPU[3][2]; - b3OpenCLArray m_objectMinMaxIndexGPUaxis0; - b3OpenCLArray m_objectMinMaxIndexGPUaxis1; - b3OpenCLArray m_objectMinMaxIndexGPUaxis2; - b3OpenCLArray m_objectMinMaxIndexGPUaxis0prev; - b3OpenCLArray m_objectMinMaxIndexGPUaxis1prev; - b3OpenCLArray m_objectMinMaxIndexGPUaxis2prev; + b3AlignedObjectArray m_sortedAxisCPU[3][2]; + b3AlignedObjectArray m_objectMinMaxIndexCPU[3][2]; + b3OpenCLArray m_objectMinMaxIndexGPUaxis0; + b3OpenCLArray m_objectMinMaxIndexGPUaxis1; + b3OpenCLArray m_objectMinMaxIndexGPUaxis2; + b3OpenCLArray m_objectMinMaxIndexGPUaxis0prev; + b3OpenCLArray m_objectMinMaxIndexGPUaxis1prev; + b3OpenCLArray m_objectMinMaxIndexGPUaxis2prev; - b3OpenCLArray m_sortedAxisGPU0; - b3OpenCLArray m_sortedAxisGPU1; - b3OpenCLArray m_sortedAxisGPU2; - b3OpenCLArray m_sortedAxisGPU0prev; - b3OpenCLArray m_sortedAxisGPU1prev; - b3OpenCLArray m_sortedAxisGPU2prev; + b3OpenCLArray m_sortedAxisGPU0; + b3OpenCLArray m_sortedAxisGPU1; + b3OpenCLArray m_sortedAxisGPU2; + b3OpenCLArray m_sortedAxisGPU0prev; + b3OpenCLArray m_sortedAxisGPU1prev; + b3OpenCLArray m_sortedAxisGPU2prev; + b3OpenCLArray m_addedHostPairsGPU; + b3OpenCLArray m_removedHostPairsGPU; + b3OpenCLArray m_addedCountGPU; + b3OpenCLArray m_removedCountGPU; - b3OpenCLArray m_addedHostPairsGPU; - b3OpenCLArray m_removedHostPairsGPU; - b3OpenCLArray m_addedCountGPU; - b3OpenCLArray m_removedCountGPU; - - int m_currentBuffer; + int m_currentBuffer; public: - b3OpenCLArray m_pairCount; + b3OpenCLArray m_allAabbsGPU; + b3AlignedObjectArray m_allAabbsCPU; - b3OpenCLArray m_allAabbsGPU; - b3AlignedObjectArray m_allAabbsCPU; - - virtual b3OpenCLArray& getAllAabbsGPU() + virtual b3OpenCLArray& getAllAabbsGPU() { return m_allAabbsGPU; } - virtual b3AlignedObjectArray& getAllAabbsCPU() + virtual b3AlignedObjectArray& getAllAabbsCPU() { return m_allAabbsCPU; } - b3OpenCLArray m_sum; - b3OpenCLArray m_sum2; - b3OpenCLArray m_dst; + b3OpenCLArray m_sum; + b3OpenCLArray m_sum2; + b3OpenCLArray m_dst; - b3OpenCLArray m_smallAabbsMappingGPU; + b3OpenCLArray m_smallAabbsMappingGPU; b3AlignedObjectArray m_smallAabbsMappingCPU; - b3OpenCLArray m_largeAabbsMappingGPU; + b3OpenCLArray m_largeAabbsMappingGPU; b3AlignedObjectArray m_largeAabbsMappingCPU; - - b3OpenCLArray m_overlappingPairs; + b3OpenCLArray m_overlappingPairs; //temporary gpu work memory - b3OpenCLArray m_gpuSmallSortData; - b3OpenCLArray m_gpuSmallSortedAabbs; + b3OpenCLArray m_gpuSmallSortData; + b3OpenCLArray m_gpuSmallSortedAabbs; - class b3PrefixScanFloat4CL* m_prefixScanFloat4; + class b3PrefixScanFloat4CL* m_prefixScanFloat4; enum b3GpuSapKernelType { - B3_GPU_SAP_KERNEL_BRUTE_FORCE_CPU=1, + B3_GPU_SAP_KERNEL_BRUTE_FORCE_CPU = 1, B3_GPU_SAP_KERNEL_BRUTE_FORCE_GPU, B3_GPU_SAP_KERNEL_ORIGINAL, B3_GPU_SAP_KERNEL_BARRIER, B3_GPU_SAP_KERNEL_LOCAL_SHARED_MEMORY }; - b3GpuSapBroadphase(cl_context ctx,cl_device_id device, cl_command_queue q , b3GpuSapKernelType kernelType=B3_GPU_SAP_KERNEL_LOCAL_SHARED_MEMORY); + b3GpuSapBroadphase(cl_context ctx, cl_device_id device, cl_command_queue q, b3GpuSapKernelType kernelType = B3_GPU_SAP_KERNEL_LOCAL_SHARED_MEMORY); virtual ~b3GpuSapBroadphase(); - - static b3GpuBroadphaseInterface* CreateFuncBruteForceCpu(cl_context ctx,cl_device_id device, cl_command_queue q) + + static b3GpuBroadphaseInterface* CreateFuncBruteForceCpu(cl_context ctx, cl_device_id device, cl_command_queue q) { - return new b3GpuSapBroadphase(ctx,device,q,B3_GPU_SAP_KERNEL_BRUTE_FORCE_CPU); + return new b3GpuSapBroadphase(ctx, device, q, B3_GPU_SAP_KERNEL_BRUTE_FORCE_CPU); } - static b3GpuBroadphaseInterface* CreateFuncBruteForceGpu(cl_context ctx,cl_device_id device, cl_command_queue q) + static b3GpuBroadphaseInterface* CreateFuncBruteForceGpu(cl_context ctx, cl_device_id device, cl_command_queue q) { - return new b3GpuSapBroadphase(ctx,device,q,B3_GPU_SAP_KERNEL_BRUTE_FORCE_GPU); + return new b3GpuSapBroadphase(ctx, device, q, B3_GPU_SAP_KERNEL_BRUTE_FORCE_GPU); } - static b3GpuBroadphaseInterface* CreateFuncOriginal(cl_context ctx,cl_device_id device, cl_command_queue q) + static b3GpuBroadphaseInterface* CreateFuncOriginal(cl_context ctx, cl_device_id device, cl_command_queue q) { - return new b3GpuSapBroadphase(ctx,device,q,B3_GPU_SAP_KERNEL_ORIGINAL); + return new b3GpuSapBroadphase(ctx, device, q, B3_GPU_SAP_KERNEL_ORIGINAL); } - static b3GpuBroadphaseInterface* CreateFuncBarrier(cl_context ctx,cl_device_id device, cl_command_queue q) + static b3GpuBroadphaseInterface* CreateFuncBarrier(cl_context ctx, cl_device_id device, cl_command_queue q) { - return new b3GpuSapBroadphase(ctx,device,q,B3_GPU_SAP_KERNEL_BARRIER); + return new b3GpuSapBroadphase(ctx, device, q, B3_GPU_SAP_KERNEL_BARRIER); } - static b3GpuBroadphaseInterface* CreateFuncLocalMemory(cl_context ctx,cl_device_id device, cl_command_queue q) + static b3GpuBroadphaseInterface* CreateFuncLocalMemory(cl_context ctx, cl_device_id device, cl_command_queue q) { - return new b3GpuSapBroadphase(ctx,device,q,B3_GPU_SAP_KERNEL_LOCAL_SHARED_MEMORY); + return new b3GpuSapBroadphase(ctx, device, q, B3_GPU_SAP_KERNEL_LOCAL_SHARED_MEMORY); } - - virtual void calculateOverlappingPairs(int maxPairs); - virtual void calculateOverlappingPairsHost(int maxPairs); - - void reset(); + virtual void calculateOverlappingPairs(int maxPairs); + virtual void calculateOverlappingPairsHost(int maxPairs); + + void reset(); void init3dSap(); virtual void calculateOverlappingPairsHostIncremental3Sap(); - virtual void createProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr , int collisionFilterGroup, int collisionFilterMask); - virtual void createLargeProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr , int collisionFilterGroup, int collisionFilterMask); + virtual void createProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr, int collisionFilterGroup, int collisionFilterMask); + virtual void createLargeProxy(const b3Vector3& aabbMin, const b3Vector3& aabbMax, int userPtr, int collisionFilterGroup, int collisionFilterMask); //call writeAabbsToGpu after done making all changes (createProxy etc) virtual void writeAabbsToGpu(); - virtual cl_mem getAabbBufferWS(); - virtual int getNumOverlap(); - virtual cl_mem getOverlappingPairBuffer(); - + virtual cl_mem getAabbBufferWS(); + virtual int getNumOverlap(); + virtual cl_mem getOverlappingPairBuffer(); + virtual b3OpenCLArray& getOverlappingPairsGPU(); virtual b3OpenCLArray& getSmallAabbIndicesGPU(); virtual b3OpenCLArray& getLargeAabbIndicesGPU(); }; -#endif //B3_GPU_SAP_BROADPHASE_H \ No newline at end of file +#endif //B3_GPU_SAP_BROADPHASE_H \ No newline at end of file diff --git a/src/Bullet3OpenCL/BroadphaseCollision/b3SapAabb.h b/src/Bullet3OpenCL/BroadphaseCollision/b3SapAabb.h index ea6550fed..60570f260 100644 --- a/src/Bullet3OpenCL/BroadphaseCollision/b3SapAabb.h +++ b/src/Bullet3OpenCL/BroadphaseCollision/b3SapAabb.h @@ -5,10 +5,9 @@ #include "Bullet3Collision/BroadPhaseCollision/shared/b3Aabb.h" ///just make sure that the b3Aabb is 16-byte aligned -B3_ATTRIBUTE_ALIGNED16(struct) b3SapAabb : public b3Aabb -{ +B3_ATTRIBUTE_ALIGNED16(struct) +b3SapAabb : public b3Aabb{ -}; + }; - -#endif //B3_SAP_AABB_H +#endif //B3_SAP_AABB_H diff --git a/src/Bullet3OpenCL/BroadphaseCollision/kernels/gridBroadphaseKernels.h b/src/Bullet3OpenCL/BroadphaseCollision/kernels/gridBroadphaseKernels.h index dad42477c..018541778 100644 --- a/src/Bullet3OpenCL/BroadphaseCollision/kernels/gridBroadphaseKernels.h +++ b/src/Bullet3OpenCL/BroadphaseCollision/kernels/gridBroadphaseKernels.h @@ -1,199 +1,198 @@ //this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project -static const char* gridBroadphaseCL= \ -"int getPosHash(int4 gridPos, __global float4* pParams)\n" -"{\n" -" int4 gridDim = *((__global int4*)(pParams + 1));\n" -" gridPos.x &= gridDim.x - 1;\n" -" gridPos.y &= gridDim.y - 1;\n" -" gridPos.z &= gridDim.z - 1;\n" -" int hash = gridPos.z * gridDim.y * gridDim.x + gridPos.y * gridDim.x + gridPos.x;\n" -" return hash;\n" -"} \n" -"int4 getGridPos(float4 worldPos, __global float4* pParams)\n" -"{\n" -" int4 gridPos;\n" -" int4 gridDim = *((__global int4*)(pParams + 1));\n" -" gridPos.x = (int)floor(worldPos.x * pParams[0].x) & (gridDim.x - 1);\n" -" gridPos.y = (int)floor(worldPos.y * pParams[0].y) & (gridDim.y - 1);\n" -" gridPos.z = (int)floor(worldPos.z * pParams[0].z) & (gridDim.z - 1);\n" -" return gridPos;\n" -"}\n" -"// calculate grid hash value for each body using its AABB\n" -"__kernel void kCalcHashAABB(int numObjects, __global float4* allpAABB, __global const int* smallAabbMapping, __global int2* pHash, __global float4* pParams )\n" -"{\n" -" int index = get_global_id(0);\n" -" if(index >= numObjects)\n" -" {\n" -" return;\n" -" }\n" -" float4 bbMin = allpAABB[smallAabbMapping[index]*2];\n" -" float4 bbMax = allpAABB[smallAabbMapping[index]*2 + 1];\n" -" float4 pos;\n" -" pos.x = (bbMin.x + bbMax.x) * 0.5f;\n" -" pos.y = (bbMin.y + bbMax.y) * 0.5f;\n" -" pos.z = (bbMin.z + bbMax.z) * 0.5f;\n" -" pos.w = 0.f;\n" -" // get address in grid\n" -" int4 gridPos = getGridPos(pos, pParams);\n" -" int gridHash = getPosHash(gridPos, pParams);\n" -" // store grid hash and body index\n" -" int2 hashVal;\n" -" hashVal.x = gridHash;\n" -" hashVal.y = index;\n" -" pHash[index] = hashVal;\n" -"}\n" -"__kernel void kClearCellStart( int numCells, \n" -" __global int* pCellStart )\n" -"{\n" -" int index = get_global_id(0);\n" -" if(index >= numCells)\n" -" {\n" -" return;\n" -" }\n" -" pCellStart[index] = -1;\n" -"}\n" -"__kernel void kFindCellStart(int numObjects, __global int2* pHash, __global int* cellStart )\n" -"{\n" -" __local int sharedHash[513];\n" -" int index = get_global_id(0);\n" -" int2 sortedData;\n" -" if(index < numObjects)\n" -" {\n" -" sortedData = pHash[index];\n" -" // Load hash data into shared memory so that we can look \n" -" // at neighboring body's hash value without loading\n" -" // two hash values per thread\n" -" sharedHash[get_local_id(0) + 1] = sortedData.x;\n" -" if((index > 0) && (get_local_id(0) == 0))\n" -" {\n" -" // first thread in block must load neighbor body hash\n" -" sharedHash[0] = pHash[index-1].x;\n" -" }\n" -" }\n" -" barrier(CLK_LOCAL_MEM_FENCE);\n" -" if(index < numObjects)\n" -" {\n" -" if((index == 0) || (sortedData.x != sharedHash[get_local_id(0)]))\n" -" {\n" -" cellStart[sortedData.x] = index;\n" -" }\n" -" }\n" -"}\n" -"int testAABBOverlap(float4 min0, float4 max0, float4 min1, float4 max1)\n" -"{\n" -" return (min0.x <= max1.x)&& (min1.x <= max0.x) && \n" -" (min0.y <= max1.y)&& (min1.y <= max0.y) && \n" -" (min0.z <= max1.z)&& (min1.z <= max0.z); \n" -"}\n" -"//search for AABB 'index' against other AABBs' in this cell\n" -"void findPairsInCell( int numObjects,\n" -" int4 gridPos,\n" -" int index,\n" -" __global int2* pHash,\n" -" __global int* pCellStart,\n" -" __global float4* allpAABB, \n" -" __global const int* smallAabbMapping,\n" -" __global float4* pParams,\n" -" volatile __global int* pairCount,\n" -" __global int4* pPairBuff2,\n" -" int maxPairs\n" -" )\n" -"{\n" -" int4 pGridDim = *((__global int4*)(pParams + 1));\n" -" int maxBodiesPerCell = pGridDim.w;\n" -" int gridHash = getPosHash(gridPos, pParams);\n" -" // get start of bucket for this cell\n" -" int bucketStart = pCellStart[gridHash];\n" -" if (bucketStart == -1)\n" -" {\n" -" return; // cell empty\n" -" }\n" -" // iterate over bodies in this cell\n" -" int2 sortedData = pHash[index];\n" -" int unsorted_indx = sortedData.y;\n" -" float4 min0 = allpAABB[smallAabbMapping[unsorted_indx]*2 + 0]; \n" -" float4 max0 = allpAABB[smallAabbMapping[unsorted_indx]*2 + 1];\n" -" int handleIndex = as_int(min0.w);\n" -" \n" -" int bucketEnd = bucketStart + maxBodiesPerCell;\n" -" bucketEnd = (bucketEnd > numObjects) ? numObjects : bucketEnd;\n" -" for(int index2 = bucketStart; index2 < bucketEnd; index2++) \n" -" {\n" -" int2 cellData = pHash[index2];\n" -" if (cellData.x != gridHash)\n" -" {\n" -" break; // no longer in same bucket\n" -" }\n" -" int unsorted_indx2 = cellData.y;\n" -" //if (unsorted_indx2 < unsorted_indx) // check not colliding with self\n" -" if (unsorted_indx2 != unsorted_indx) // check not colliding with self\n" -" { \n" -" float4 min1 = allpAABB[smallAabbMapping[unsorted_indx2]*2 + 0];\n" -" float4 max1 = allpAABB[smallAabbMapping[unsorted_indx2]*2 + 1];\n" -" if(testAABBOverlap(min0, max0, min1, max1))\n" -" {\n" -" if (pairCount)\n" -" {\n" -" int handleIndex2 = as_int(min1.w);\n" -" if (handleIndex= numObjects)\n" -" {\n" -" return;\n" -" }\n" -" int2 sortedData = pHash[index];\n" -" int unsorted_indx = sortedData.y;\n" -" float4 bbMin = allpAABB[smallAabbMapping[unsorted_indx]*2 + 0];\n" -" float4 bbMax = allpAABB[smallAabbMapping[unsorted_indx]*2 + 1];\n" -" float4 pos;\n" -" pos.x = (bbMin.x + bbMax.x) * 0.5f;\n" -" pos.y = (bbMin.y + bbMax.y) * 0.5f;\n" -" pos.z = (bbMin.z + bbMax.z) * 0.5f;\n" -" // get address in grid\n" -" int4 gridPosA = getGridPos(pos, pParams);\n" -" int4 gridPosB; \n" -" // examine only neighbouring cells\n" -" for(int z=-1; z<=1; z++) \n" -" {\n" -" gridPosB.z = gridPosA.z + z;\n" -" for(int y=-1; y<=1; y++) \n" -" {\n" -" gridPosB.y = gridPosA.y + y;\n" -" for(int x=-1; x<=1; x++) \n" -" {\n" -" gridPosB.x = gridPosA.x + x;\n" -" findPairsInCell(numObjects, gridPosB, index, pHash, pCellStart, allpAABB,smallAabbMapping, pParams, pairCount,pPairBuff2, maxPairs);\n" -" }\n" -" }\n" -" }\n" -"}\n" -; +static const char* gridBroadphaseCL = + "int getPosHash(int4 gridPos, __global float4* pParams)\n" + "{\n" + " int4 gridDim = *((__global int4*)(pParams + 1));\n" + " gridPos.x &= gridDim.x - 1;\n" + " gridPos.y &= gridDim.y - 1;\n" + " gridPos.z &= gridDim.z - 1;\n" + " int hash = gridPos.z * gridDim.y * gridDim.x + gridPos.y * gridDim.x + gridPos.x;\n" + " return hash;\n" + "} \n" + "int4 getGridPos(float4 worldPos, __global float4* pParams)\n" + "{\n" + " int4 gridPos;\n" + " int4 gridDim = *((__global int4*)(pParams + 1));\n" + " gridPos.x = (int)floor(worldPos.x * pParams[0].x) & (gridDim.x - 1);\n" + " gridPos.y = (int)floor(worldPos.y * pParams[0].y) & (gridDim.y - 1);\n" + " gridPos.z = (int)floor(worldPos.z * pParams[0].z) & (gridDim.z - 1);\n" + " return gridPos;\n" + "}\n" + "// calculate grid hash value for each body using its AABB\n" + "__kernel void kCalcHashAABB(int numObjects, __global float4* allpAABB, __global const int* smallAabbMapping, __global int2* pHash, __global float4* pParams )\n" + "{\n" + " int index = get_global_id(0);\n" + " if(index >= numObjects)\n" + " {\n" + " return;\n" + " }\n" + " float4 bbMin = allpAABB[smallAabbMapping[index]*2];\n" + " float4 bbMax = allpAABB[smallAabbMapping[index]*2 + 1];\n" + " float4 pos;\n" + " pos.x = (bbMin.x + bbMax.x) * 0.5f;\n" + " pos.y = (bbMin.y + bbMax.y) * 0.5f;\n" + " pos.z = (bbMin.z + bbMax.z) * 0.5f;\n" + " pos.w = 0.f;\n" + " // get address in grid\n" + " int4 gridPos = getGridPos(pos, pParams);\n" + " int gridHash = getPosHash(gridPos, pParams);\n" + " // store grid hash and body index\n" + " int2 hashVal;\n" + " hashVal.x = gridHash;\n" + " hashVal.y = index;\n" + " pHash[index] = hashVal;\n" + "}\n" + "__kernel void kClearCellStart( int numCells, \n" + " __global int* pCellStart )\n" + "{\n" + " int index = get_global_id(0);\n" + " if(index >= numCells)\n" + " {\n" + " return;\n" + " }\n" + " pCellStart[index] = -1;\n" + "}\n" + "__kernel void kFindCellStart(int numObjects, __global int2* pHash, __global int* cellStart )\n" + "{\n" + " __local int sharedHash[513];\n" + " int index = get_global_id(0);\n" + " int2 sortedData;\n" + " if(index < numObjects)\n" + " {\n" + " sortedData = pHash[index];\n" + " // Load hash data into shared memory so that we can look \n" + " // at neighboring body's hash value without loading\n" + " // two hash values per thread\n" + " sharedHash[get_local_id(0) + 1] = sortedData.x;\n" + " if((index > 0) && (get_local_id(0) == 0))\n" + " {\n" + " // first thread in block must load neighbor body hash\n" + " sharedHash[0] = pHash[index-1].x;\n" + " }\n" + " }\n" + " barrier(CLK_LOCAL_MEM_FENCE);\n" + " if(index < numObjects)\n" + " {\n" + " if((index == 0) || (sortedData.x != sharedHash[get_local_id(0)]))\n" + " {\n" + " cellStart[sortedData.x] = index;\n" + " }\n" + " }\n" + "}\n" + "int testAABBOverlap(float4 min0, float4 max0, float4 min1, float4 max1)\n" + "{\n" + " return (min0.x <= max1.x)&& (min1.x <= max0.x) && \n" + " (min0.y <= max1.y)&& (min1.y <= max0.y) && \n" + " (min0.z <= max1.z)&& (min1.z <= max0.z); \n" + "}\n" + "//search for AABB 'index' against other AABBs' in this cell\n" + "void findPairsInCell( int numObjects,\n" + " int4 gridPos,\n" + " int index,\n" + " __global int2* pHash,\n" + " __global int* pCellStart,\n" + " __global float4* allpAABB, \n" + " __global const int* smallAabbMapping,\n" + " __global float4* pParams,\n" + " volatile __global int* pairCount,\n" + " __global int4* pPairBuff2,\n" + " int maxPairs\n" + " )\n" + "{\n" + " int4 pGridDim = *((__global int4*)(pParams + 1));\n" + " int maxBodiesPerCell = pGridDim.w;\n" + " int gridHash = getPosHash(gridPos, pParams);\n" + " // get start of bucket for this cell\n" + " int bucketStart = pCellStart[gridHash];\n" + " if (bucketStart == -1)\n" + " {\n" + " return; // cell empty\n" + " }\n" + " // iterate over bodies in this cell\n" + " int2 sortedData = pHash[index];\n" + " int unsorted_indx = sortedData.y;\n" + " float4 min0 = allpAABB[smallAabbMapping[unsorted_indx]*2 + 0]; \n" + " float4 max0 = allpAABB[smallAabbMapping[unsorted_indx]*2 + 1];\n" + " int handleIndex = as_int(min0.w);\n" + " \n" + " int bucketEnd = bucketStart + maxBodiesPerCell;\n" + " bucketEnd = (bucketEnd > numObjects) ? numObjects : bucketEnd;\n" + " for(int index2 = bucketStart; index2 < bucketEnd; index2++) \n" + " {\n" + " int2 cellData = pHash[index2];\n" + " if (cellData.x != gridHash)\n" + " {\n" + " break; // no longer in same bucket\n" + " }\n" + " int unsorted_indx2 = cellData.y;\n" + " //if (unsorted_indx2 < unsorted_indx) // check not colliding with self\n" + " if (unsorted_indx2 != unsorted_indx) // check not colliding with self\n" + " { \n" + " float4 min1 = allpAABB[smallAabbMapping[unsorted_indx2]*2 + 0];\n" + " float4 max1 = allpAABB[smallAabbMapping[unsorted_indx2]*2 + 1];\n" + " if(testAABBOverlap(min0, max0, min1, max1))\n" + " {\n" + " if (pairCount)\n" + " {\n" + " int handleIndex2 = as_int(min1.w);\n" + " if (handleIndex= numObjects)\n" + " {\n" + " return;\n" + " }\n" + " int2 sortedData = pHash[index];\n" + " int unsorted_indx = sortedData.y;\n" + " float4 bbMin = allpAABB[smallAabbMapping[unsorted_indx]*2 + 0];\n" + " float4 bbMax = allpAABB[smallAabbMapping[unsorted_indx]*2 + 1];\n" + " float4 pos;\n" + " pos.x = (bbMin.x + bbMax.x) * 0.5f;\n" + " pos.y = (bbMin.y + bbMax.y) * 0.5f;\n" + " pos.z = (bbMin.z + bbMax.z) * 0.5f;\n" + " // get address in grid\n" + " int4 gridPosA = getGridPos(pos, pParams);\n" + " int4 gridPosB; \n" + " // examine only neighbouring cells\n" + " for(int z=-1; z<=1; z++) \n" + " {\n" + " gridPosB.z = gridPosA.z + z;\n" + " for(int y=-1; y<=1; y++) \n" + " {\n" + " gridPosB.y = gridPosA.y + y;\n" + " for(int x=-1; x<=1; x++) \n" + " {\n" + " gridPosB.x = gridPosA.x + x;\n" + " findPairsInCell(numObjects, gridPosB, index, pHash, pCellStart, allpAABB,smallAabbMapping, pParams, pairCount,pPairBuff2, maxPairs);\n" + " }\n" + " }\n" + " }\n" + "}\n"; diff --git a/src/Bullet3OpenCL/BroadphaseCollision/kernels/parallelLinearBvhKernels.h b/src/Bullet3OpenCL/BroadphaseCollision/kernels/parallelLinearBvhKernels.h index 5eb8f45b1..c02877dde 100644 --- a/src/Bullet3OpenCL/BroadphaseCollision/kernels/parallelLinearBvhKernels.h +++ b/src/Bullet3OpenCL/BroadphaseCollision/kernels/parallelLinearBvhKernels.h @@ -1,729 +1,728 @@ //this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project -static const char* parallelLinearBvhCL= \ -"/*\n" -"This software is provided 'as-is', without any express or implied warranty.\n" -"In no event will the authors be held liable for any damages arising from the use of this software.\n" -"Permission is granted to anyone to use this software for any purpose,\n" -"including commercial applications, and to alter it and redistribute it freely,\n" -"subject to the following restrictions:\n" -"1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" -"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" -"3. This notice may not be removed or altered from any source distribution.\n" -"*/\n" -"//Initial Author Jackson Lee, 2014\n" -"typedef float b3Scalar;\n" -"typedef float4 b3Vector3;\n" -"#define b3Max max\n" -"#define b3Min min\n" -"#define b3Sqrt sqrt\n" -"typedef struct\n" -"{\n" -" unsigned int m_key;\n" -" unsigned int m_value;\n" -"} SortDataCL;\n" -"typedef struct \n" -"{\n" -" union\n" -" {\n" -" float4 m_min;\n" -" float m_minElems[4];\n" -" int m_minIndices[4];\n" -" };\n" -" union\n" -" {\n" -" float4 m_max;\n" -" float m_maxElems[4];\n" -" int m_maxIndices[4];\n" -" };\n" -"} b3AabbCL;\n" -"unsigned int interleaveBits(unsigned int x)\n" -"{\n" -" //........ ........ ......12 3456789A //x\n" -" //....1..2 ..3..4.. 5..6..7. .8..9..A //x after interleaving bits\n" -" \n" -" //......12 3456789A ......12 3456789A //x ^ (x << 16)\n" -" //11111111 ........ ........ 11111111 //0x FF 00 00 FF\n" -" //......12 ........ ........ 3456789A //x = (x ^ (x << 16)) & 0xFF0000FF;\n" -" \n" -" //......12 ........ 3456789A 3456789A //x ^ (x << 8)\n" -" //......11 ........ 1111.... ....1111 //0x 03 00 F0 0F\n" -" //......12 ........ 3456.... ....789A //x = (x ^ (x << 8)) & 0x0300F00F;\n" -" \n" -" //..12..12 ....3456 3456.... 789A789A //x ^ (x << 4)\n" -" //......11 ....11.. ..11.... 11....11 //0x 03 0C 30 C3\n" -" //......12 ....34.. ..56.... 78....9A //x = (x ^ (x << 4)) & 0x030C30C3;\n" -" \n" -" //....1212 ..3434.. 5656..78 78..9A9A //x ^ (x << 2)\n" -" //....1..1 ..1..1.. 1..1..1. .1..1..1 //0x 09 24 92 49\n" -" //....1..2 ..3..4.. 5..6..7. .8..9..A //x = (x ^ (x << 2)) & 0x09249249;\n" -" \n" -" //........ ........ ......11 11111111 //0x000003FF\n" -" x &= 0x000003FF; //Clear all bits above bit 10\n" -" \n" -" x = (x ^ (x << 16)) & 0xFF0000FF;\n" -" x = (x ^ (x << 8)) & 0x0300F00F;\n" -" x = (x ^ (x << 4)) & 0x030C30C3;\n" -" x = (x ^ (x << 2)) & 0x09249249;\n" -" \n" -" return x;\n" -"}\n" -"unsigned int getMortonCode(unsigned int x, unsigned int y, unsigned int z)\n" -"{\n" -" return interleaveBits(x) << 0 | interleaveBits(y) << 1 | interleaveBits(z) << 2;\n" -"}\n" -"__kernel void separateAabbs(__global b3AabbCL* unseparatedAabbs, __global int* aabbIndices, __global b3AabbCL* out_aabbs, int numAabbsToSeparate)\n" -"{\n" -" int separatedAabbIndex = get_global_id(0);\n" -" if(separatedAabbIndex >= numAabbsToSeparate) return;\n" -" int unseparatedAabbIndex = aabbIndices[separatedAabbIndex];\n" -" out_aabbs[separatedAabbIndex] = unseparatedAabbs[unseparatedAabbIndex];\n" -"}\n" -"//Should replace with an optimized parallel reduction\n" -"__kernel void findAllNodesMergedAabb(__global b3AabbCL* out_mergedAabb, int numAabbsNeedingMerge)\n" -"{\n" -" //Each time this kernel is added to the command queue, \n" -" //the number of AABBs needing to be merged is halved\n" -" //\n" -" //Example with 159 AABBs:\n" -" // numRemainingAabbs == 159 / 2 + 159 % 2 == 80\n" -" // numMergedAabbs == 159 - 80 == 79\n" -" //So, indices [0, 78] are merged with [0 + 80, 78 + 80]\n" -" \n" -" int numRemainingAabbs = numAabbsNeedingMerge / 2 + numAabbsNeedingMerge % 2;\n" -" int numMergedAabbs = numAabbsNeedingMerge - numRemainingAabbs;\n" -" \n" -" int aabbIndex = get_global_id(0);\n" -" if(aabbIndex >= numMergedAabbs) return;\n" -" \n" -" int otherAabbIndex = aabbIndex + numRemainingAabbs;\n" -" \n" -" b3AabbCL aabb = out_mergedAabb[aabbIndex];\n" -" b3AabbCL otherAabb = out_mergedAabb[otherAabbIndex];\n" -" \n" -" b3AabbCL mergedAabb;\n" -" mergedAabb.m_min = b3Min(aabb.m_min, otherAabb.m_min);\n" -" mergedAabb.m_max = b3Max(aabb.m_max, otherAabb.m_max);\n" -" out_mergedAabb[aabbIndex] = mergedAabb;\n" -"}\n" -"__kernel void assignMortonCodesAndAabbIndicies(__global b3AabbCL* worldSpaceAabbs, __global b3AabbCL* mergedAabbOfAllNodes, \n" -" __global SortDataCL* out_mortonCodesAndAabbIndices, int numAabbs)\n" -"{\n" -" int leafNodeIndex = get_global_id(0); //Leaf node index == AABB index\n" -" if(leafNodeIndex >= numAabbs) return;\n" -" \n" -" b3AabbCL mergedAabb = mergedAabbOfAllNodes[0];\n" -" b3Vector3 gridCenter = (mergedAabb.m_min + mergedAabb.m_max) * 0.5f;\n" -" b3Vector3 gridCellSize = (mergedAabb.m_max - mergedAabb.m_min) / (float)1024;\n" -" \n" -" b3AabbCL aabb = worldSpaceAabbs[leafNodeIndex];\n" -" b3Vector3 aabbCenter = (aabb.m_min + aabb.m_max) * 0.5f;\n" -" b3Vector3 aabbCenterRelativeToGrid = aabbCenter - gridCenter;\n" -" \n" -" //Quantize into integer coordinates\n" -" //floor() is needed to prevent the center cell, at (0,0,0) from being twice the size\n" -" b3Vector3 gridPosition = aabbCenterRelativeToGrid / gridCellSize;\n" -" \n" -" int4 discretePosition;\n" -" discretePosition.x = (int)( (gridPosition.x >= 0.0f) ? gridPosition.x : floor(gridPosition.x) );\n" -" discretePosition.y = (int)( (gridPosition.y >= 0.0f) ? gridPosition.y : floor(gridPosition.y) );\n" -" discretePosition.z = (int)( (gridPosition.z >= 0.0f) ? gridPosition.z : floor(gridPosition.z) );\n" -" \n" -" //Clamp coordinates into [-512, 511], then convert range from [-512, 511] to [0, 1023]\n" -" discretePosition = b3Max( -512, b3Min(discretePosition, 511) );\n" -" discretePosition += 512;\n" -" \n" -" //Interleave bits(assign a morton code, also known as a z-curve)\n" -" unsigned int mortonCode = getMortonCode(discretePosition.x, discretePosition.y, discretePosition.z);\n" -" \n" -" //\n" -" SortDataCL mortonCodeIndexPair;\n" -" mortonCodeIndexPair.m_key = mortonCode;\n" -" mortonCodeIndexPair.m_value = leafNodeIndex;\n" -" \n" -" out_mortonCodesAndAabbIndices[leafNodeIndex] = mortonCodeIndexPair;\n" -"}\n" -"#define B3_PLVBH_TRAVERSE_MAX_STACK_SIZE 128\n" -"//The most significant bit(0x80000000) of a int32 is used to distinguish between leaf and internal nodes.\n" -"//If it is set, then the index is for an internal node; otherwise, it is a leaf node. \n" -"//In both cases, the bit should be cleared to access the actual node index.\n" -"int isLeafNode(int index) { return (index >> 31 == 0); }\n" -"int getIndexWithInternalNodeMarkerRemoved(int index) { return index & (~0x80000000); }\n" -"int getIndexWithInternalNodeMarkerSet(int isLeaf, int index) { return (isLeaf) ? index : (index | 0x80000000); }\n" -"//From sap.cl\n" -"#define NEW_PAIR_MARKER -1\n" -"bool TestAabbAgainstAabb2(const b3AabbCL* aabb1, const b3AabbCL* aabb2)\n" -"{\n" -" bool overlap = true;\n" -" overlap = (aabb1->m_min.x > aabb2->m_max.x || aabb1->m_max.x < aabb2->m_min.x) ? false : overlap;\n" -" overlap = (aabb1->m_min.z > aabb2->m_max.z || aabb1->m_max.z < aabb2->m_min.z) ? false : overlap;\n" -" overlap = (aabb1->m_min.y > aabb2->m_max.y || aabb1->m_max.y < aabb2->m_min.y) ? false : overlap;\n" -" return overlap;\n" -"}\n" -"//From sap.cl\n" -"__kernel void plbvhCalculateOverlappingPairs(__global b3AabbCL* rigidAabbs, \n" -" __global int* rootNodeIndex, \n" -" __global int2* internalNodeChildIndices, \n" -" __global b3AabbCL* internalNodeAabbs,\n" -" __global int2* internalNodeLeafIndexRanges,\n" -" \n" -" __global SortDataCL* mortonCodesAndAabbIndices,\n" -" __global int* out_numPairs, __global int4* out_overlappingPairs, \n" -" int maxPairs, int numQueryAabbs)\n" -"{\n" -" //Using get_group_id()/get_local_id() is Faster than get_global_id(0) since\n" -" //mortonCodesAndAabbIndices[] contains rigid body indices sorted along the z-curve (more spatially coherent)\n" -" int queryBvhNodeIndex = get_group_id(0) * get_local_size(0) + get_local_id(0);\n" -" if(queryBvhNodeIndex >= numQueryAabbs) return;\n" -" \n" -" int queryRigidIndex = mortonCodesAndAabbIndices[queryBvhNodeIndex].m_value;\n" -" b3AabbCL queryAabb = rigidAabbs[queryRigidIndex];\n" -" \n" -" int stack[B3_PLVBH_TRAVERSE_MAX_STACK_SIZE];\n" -" \n" -" int stackSize = 1;\n" -" stack[0] = *rootNodeIndex;\n" -" \n" -" while(stackSize)\n" -" {\n" -" int internalOrLeafNodeIndex = stack[ stackSize - 1 ];\n" -" --stackSize;\n" -" \n" -" int isLeaf = isLeafNode(internalOrLeafNodeIndex); //Internal node if false\n" -" int bvhNodeIndex = getIndexWithInternalNodeMarkerRemoved(internalOrLeafNodeIndex);\n" -" \n" -" //Optimization - if the BVH is structured as a binary radix tree, then\n" -" //each internal node corresponds to a contiguous range of leaf nodes(internalNodeLeafIndexRanges[]).\n" -" //This can be used to avoid testing each AABB-AABB pair twice, including preventing each node from colliding with itself.\n" -" {\n" -" int highestLeafIndex = (isLeaf) ? bvhNodeIndex : internalNodeLeafIndexRanges[bvhNodeIndex].y;\n" -" if(highestLeafIndex <= queryBvhNodeIndex) continue;\n" -" }\n" -" \n" -" //bvhRigidIndex is not used if internal node\n" -" int bvhRigidIndex = (isLeaf) ? mortonCodesAndAabbIndices[bvhNodeIndex].m_value : -1;\n" -" \n" -" b3AabbCL bvhNodeAabb = (isLeaf) ? rigidAabbs[bvhRigidIndex] : internalNodeAabbs[bvhNodeIndex];\n" -" if( TestAabbAgainstAabb2(&queryAabb, &bvhNodeAabb) )\n" -" {\n" -" if(isLeaf)\n" -" {\n" -" int4 pair;\n" -" pair.x = rigidAabbs[queryRigidIndex].m_minIndices[3];\n" -" pair.y = rigidAabbs[bvhRigidIndex].m_minIndices[3];\n" -" pair.z = NEW_PAIR_MARKER;\n" -" pair.w = NEW_PAIR_MARKER;\n" -" \n" -" int pairIndex = atomic_inc(out_numPairs);\n" -" if(pairIndex < maxPairs) out_overlappingPairs[pairIndex] = pair;\n" -" }\n" -" \n" -" if(!isLeaf) //Internal node\n" -" {\n" -" if(stackSize + 2 > B3_PLVBH_TRAVERSE_MAX_STACK_SIZE)\n" -" {\n" -" //Error\n" -" }\n" -" else\n" -" {\n" -" stack[ stackSize++ ] = internalNodeChildIndices[bvhNodeIndex].x;\n" -" stack[ stackSize++ ] = internalNodeChildIndices[bvhNodeIndex].y;\n" -" }\n" -" }\n" -" }\n" -" \n" -" }\n" -"}\n" -"//From rayCastKernels.cl\n" -"typedef struct\n" -"{\n" -" float4 m_from;\n" -" float4 m_to;\n" -"} b3RayInfo;\n" -"//From rayCastKernels.cl\n" -"b3Vector3 b3Vector3_normalize(b3Vector3 v)\n" -"{\n" -" b3Vector3 normal = (b3Vector3){v.x, v.y, v.z, 0.f};\n" -" return normalize(normal); //OpenCL normalize == vector4 normalize\n" -"}\n" -"b3Scalar b3Vector3_length2(b3Vector3 v) { return v.x*v.x + v.y*v.y + v.z*v.z; }\n" -"b3Scalar b3Vector3_dot(b3Vector3 a, b3Vector3 b) { return a.x*b.x + a.y*b.y + a.z*b.z; }\n" -"int rayIntersectsAabb(b3Vector3 rayOrigin, b3Scalar rayLength, b3Vector3 rayNormalizedDirection, b3AabbCL aabb)\n" -"{\n" -" //AABB is considered as 3 pairs of 2 planes( {x_min, x_max}, {y_min, y_max}, {z_min, z_max} ).\n" -" //t_min is the point of intersection with the closer plane, t_max is the point of intersection with the farther plane.\n" -" //\n" -" //if (rayNormalizedDirection.x < 0.0f), then max.x will be the near plane \n" -" //and min.x will be the far plane; otherwise, it is reversed.\n" -" //\n" -" //In order for there to be a collision, the t_min and t_max of each pair must overlap.\n" -" //This can be tested for by selecting the highest t_min and lowest t_max and comparing them.\n" -" \n" -" int4 isNegative = isless( rayNormalizedDirection, ((b3Vector3){0.0f, 0.0f, 0.0f, 0.0f}) ); //isless(x,y) returns (x < y)\n" -" \n" -" //When using vector types, the select() function checks the most signficant bit, \n" -" //but isless() sets the least significant bit.\n" -" isNegative <<= 31;\n" -" //select(b, a, condition) == condition ? a : b\n" -" //When using select() with vector types, (condition[i]) is true if its most significant bit is 1\n" -" b3Vector3 t_min = ( select(aabb.m_min, aabb.m_max, isNegative) - rayOrigin ) / rayNormalizedDirection;\n" -" b3Vector3 t_max = ( select(aabb.m_max, aabb.m_min, isNegative) - rayOrigin ) / rayNormalizedDirection;\n" -" \n" -" b3Scalar t_min_final = 0.0f;\n" -" b3Scalar t_max_final = rayLength;\n" -" \n" -" //Must use fmin()/fmax(); if one of the parameters is NaN, then the parameter that is not NaN is returned. \n" -" //Behavior of min()/max() with NaNs is undefined. (See OpenCL Specification 1.2 [6.12.2] and [6.12.4])\n" -" //Since the innermost fmin()/fmax() is always not NaN, this should never return NaN.\n" -" t_min_final = fmax( t_min.z, fmax(t_min.y, fmax(t_min.x, t_min_final)) );\n" -" t_max_final = fmin( t_max.z, fmin(t_max.y, fmin(t_max.x, t_max_final)) );\n" -" \n" -" return (t_min_final <= t_max_final);\n" -"}\n" -"__kernel void plbvhRayTraverse(__global b3AabbCL* rigidAabbs,\n" -" __global int* rootNodeIndex, \n" -" __global int2* internalNodeChildIndices, \n" -" __global b3AabbCL* internalNodeAabbs,\n" -" __global int2* internalNodeLeafIndexRanges,\n" -" __global SortDataCL* mortonCodesAndAabbIndices,\n" -" \n" -" __global b3RayInfo* rays,\n" -" \n" -" __global int* out_numRayRigidPairs, \n" -" __global int2* out_rayRigidPairs,\n" -" int maxRayRigidPairs, int numRays)\n" -"{\n" -" int rayIndex = get_global_id(0);\n" -" if(rayIndex >= numRays) return;\n" -" \n" -" //\n" -" b3Vector3 rayFrom = rays[rayIndex].m_from;\n" -" b3Vector3 rayTo = rays[rayIndex].m_to;\n" -" b3Vector3 rayNormalizedDirection = b3Vector3_normalize(rayTo - rayFrom);\n" -" b3Scalar rayLength = b3Sqrt( b3Vector3_length2(rayTo - rayFrom) );\n" -" \n" -" //\n" -" int stack[B3_PLVBH_TRAVERSE_MAX_STACK_SIZE];\n" -" \n" -" int stackSize = 1;\n" -" stack[0] = *rootNodeIndex;\n" -" \n" -" while(stackSize)\n" -" {\n" -" int internalOrLeafNodeIndex = stack[ stackSize - 1 ];\n" -" --stackSize;\n" -" \n" -" int isLeaf = isLeafNode(internalOrLeafNodeIndex); //Internal node if false\n" -" int bvhNodeIndex = getIndexWithInternalNodeMarkerRemoved(internalOrLeafNodeIndex);\n" -" \n" -" //bvhRigidIndex is not used if internal node\n" -" int bvhRigidIndex = (isLeaf) ? mortonCodesAndAabbIndices[bvhNodeIndex].m_value : -1;\n" -" \n" -" b3AabbCL bvhNodeAabb = (isLeaf) ? rigidAabbs[bvhRigidIndex] : internalNodeAabbs[bvhNodeIndex];\n" -" if( rayIntersectsAabb(rayFrom, rayLength, rayNormalizedDirection, bvhNodeAabb) )\n" -" {\n" -" if(isLeaf)\n" -" {\n" -" int2 rayRigidPair;\n" -" rayRigidPair.x = rayIndex;\n" -" rayRigidPair.y = rigidAabbs[bvhRigidIndex].m_minIndices[3];\n" -" \n" -" int pairIndex = atomic_inc(out_numRayRigidPairs);\n" -" if(pairIndex < maxRayRigidPairs) out_rayRigidPairs[pairIndex] = rayRigidPair;\n" -" }\n" -" \n" -" if(!isLeaf) //Internal node\n" -" {\n" -" if(stackSize + 2 > B3_PLVBH_TRAVERSE_MAX_STACK_SIZE)\n" -" {\n" -" //Error\n" -" }\n" -" else\n" -" {\n" -" stack[ stackSize++ ] = internalNodeChildIndices[bvhNodeIndex].x;\n" -" stack[ stackSize++ ] = internalNodeChildIndices[bvhNodeIndex].y;\n" -" }\n" -" }\n" -" }\n" -" }\n" -"}\n" -"__kernel void plbvhLargeAabbAabbTest(__global b3AabbCL* smallAabbs, __global b3AabbCL* largeAabbs, \n" -" __global int* out_numPairs, __global int4* out_overlappingPairs, \n" -" int maxPairs, int numLargeAabbRigids, int numSmallAabbRigids)\n" -"{\n" -" int smallAabbIndex = get_global_id(0);\n" -" if(smallAabbIndex >= numSmallAabbRigids) return;\n" -" \n" -" b3AabbCL smallAabb = smallAabbs[smallAabbIndex];\n" -" for(int i = 0; i < numLargeAabbRigids; ++i)\n" -" {\n" -" b3AabbCL largeAabb = largeAabbs[i];\n" -" if( TestAabbAgainstAabb2(&smallAabb, &largeAabb) )\n" -" {\n" -" int4 pair;\n" -" pair.x = largeAabb.m_minIndices[3];\n" -" pair.y = smallAabb.m_minIndices[3];\n" -" pair.z = NEW_PAIR_MARKER;\n" -" pair.w = NEW_PAIR_MARKER;\n" -" \n" -" int pairIndex = atomic_inc(out_numPairs);\n" -" if(pairIndex < maxPairs) out_overlappingPairs[pairIndex] = pair;\n" -" }\n" -" }\n" -"}\n" -"__kernel void plbvhLargeAabbRayTest(__global b3AabbCL* largeRigidAabbs, __global b3RayInfo* rays,\n" -" __global int* out_numRayRigidPairs, __global int2* out_rayRigidPairs,\n" -" int numLargeAabbRigids, int maxRayRigidPairs, int numRays)\n" -"{\n" -" int rayIndex = get_global_id(0);\n" -" if(rayIndex >= numRays) return;\n" -" \n" -" b3Vector3 rayFrom = rays[rayIndex].m_from;\n" -" b3Vector3 rayTo = rays[rayIndex].m_to;\n" -" b3Vector3 rayNormalizedDirection = b3Vector3_normalize(rayTo - rayFrom);\n" -" b3Scalar rayLength = b3Sqrt( b3Vector3_length2(rayTo - rayFrom) );\n" -" \n" -" for(int i = 0; i < numLargeAabbRigids; ++i)\n" -" {\n" -" b3AabbCL rigidAabb = largeRigidAabbs[i];\n" -" if( rayIntersectsAabb(rayFrom, rayLength, rayNormalizedDirection, rigidAabb) )\n" -" {\n" -" int2 rayRigidPair;\n" -" rayRigidPair.x = rayIndex;\n" -" rayRigidPair.y = rigidAabb.m_minIndices[3];\n" -" \n" -" int pairIndex = atomic_inc(out_numRayRigidPairs);\n" -" if(pairIndex < maxRayRigidPairs) out_rayRigidPairs[pairIndex] = rayRigidPair;\n" -" }\n" -" }\n" -"}\n" -"//Set so that it is always greater than the actual common prefixes, and never selected as a parent node.\n" -"//If there are no duplicates, then the highest common prefix is 32 or 64, depending on the number of bits used for the z-curve.\n" -"//Duplicate common prefixes increase the highest common prefix at most by the number of bits used to index the leaf node.\n" -"//Since 32 bit ints are used to index leaf nodes, the max prefix is 64(32 + 32 bit z-curve) or 96(32 + 64 bit z-curve).\n" -"#define B3_PLBVH_INVALID_COMMON_PREFIX 128\n" -"#define B3_PLBVH_ROOT_NODE_MARKER -1\n" -"#define b3Int64 long\n" -"int computeCommonPrefixLength(b3Int64 i, b3Int64 j) { return (int)clz(i ^ j); }\n" -"b3Int64 computeCommonPrefix(b3Int64 i, b3Int64 j) \n" -"{\n" -" //This function only needs to return (i & j) in order for the algorithm to work,\n" -" //but it may help with debugging to mask out the lower bits.\n" -" b3Int64 commonPrefixLength = (b3Int64)computeCommonPrefixLength(i, j);\n" -" b3Int64 sharedBits = i & j;\n" -" b3Int64 bitmask = ((b3Int64)(~0)) << (64 - commonPrefixLength); //Set all bits after the common prefix to 0\n" -" \n" -" return sharedBits & bitmask;\n" -"}\n" -"//Same as computeCommonPrefixLength(), but allows for prefixes with different lengths\n" -"int getSharedPrefixLength(b3Int64 prefixA, int prefixLengthA, b3Int64 prefixB, int prefixLengthB)\n" -"{\n" -" return b3Min( computeCommonPrefixLength(prefixA, prefixB), b3Min(prefixLengthA, prefixLengthB) );\n" -"}\n" -"__kernel void computeAdjacentPairCommonPrefix(__global SortDataCL* mortonCodesAndAabbIndices,\n" -" __global b3Int64* out_commonPrefixes,\n" -" __global int* out_commonPrefixLengths,\n" -" int numInternalNodes)\n" -"{\n" -" int internalNodeIndex = get_global_id(0);\n" -" if (internalNodeIndex >= numInternalNodes) return;\n" -" \n" -" //Here, (internalNodeIndex + 1) is never out of bounds since it is a leaf node index,\n" -" //and the number of internal nodes is always numLeafNodes - 1\n" -" int leftLeafIndex = internalNodeIndex;\n" -" int rightLeafIndex = internalNodeIndex + 1;\n" -" \n" -" int leftLeafMortonCode = mortonCodesAndAabbIndices[leftLeafIndex].m_key;\n" -" int rightLeafMortonCode = mortonCodesAndAabbIndices[rightLeafIndex].m_key;\n" -" \n" -" //Binary radix tree construction algorithm does not work if there are duplicate morton codes.\n" -" //Append the index of each leaf node to each morton code so that there are no duplicates.\n" -" //The algorithm also requires that the morton codes are sorted in ascending order; this requirement\n" -" //is also satisfied with this method, as (leftLeafIndex < rightLeafIndex) is always true.\n" -" //\n" -" //upsample(a, b) == ( ((b3Int64)a) << 32) | b\n" -" b3Int64 nonduplicateLeftMortonCode = upsample(leftLeafMortonCode, leftLeafIndex);\n" -" b3Int64 nonduplicateRightMortonCode = upsample(rightLeafMortonCode, rightLeafIndex);\n" -" \n" -" out_commonPrefixes[internalNodeIndex] = computeCommonPrefix(nonduplicateLeftMortonCode, nonduplicateRightMortonCode);\n" -" out_commonPrefixLengths[internalNodeIndex] = computeCommonPrefixLength(nonduplicateLeftMortonCode, nonduplicateRightMortonCode);\n" -"}\n" -"__kernel void buildBinaryRadixTreeLeafNodes(__global int* commonPrefixLengths, __global int* out_leafNodeParentNodes,\n" -" __global int2* out_childNodes, int numLeafNodes)\n" -"{\n" -" int leafNodeIndex = get_global_id(0);\n" -" if (leafNodeIndex >= numLeafNodes) return;\n" -" \n" -" int numInternalNodes = numLeafNodes - 1;\n" -" \n" -" int leftSplitIndex = leafNodeIndex - 1;\n" -" int rightSplitIndex = leafNodeIndex;\n" -" \n" -" int leftCommonPrefix = (leftSplitIndex >= 0) ? commonPrefixLengths[leftSplitIndex] : B3_PLBVH_INVALID_COMMON_PREFIX;\n" -" int rightCommonPrefix = (rightSplitIndex < numInternalNodes) ? commonPrefixLengths[rightSplitIndex] : B3_PLBVH_INVALID_COMMON_PREFIX;\n" -" \n" -" //Parent node is the highest adjacent common prefix that is lower than the node's common prefix\n" -" //Leaf nodes are considered as having the highest common prefix\n" -" int isLeftHigherCommonPrefix = (leftCommonPrefix > rightCommonPrefix);\n" -" \n" -" //Handle cases for the edge nodes; the first and last node\n" -" //For leaf nodes, leftCommonPrefix and rightCommonPrefix should never both be B3_PLBVH_INVALID_COMMON_PREFIX\n" -" if(leftCommonPrefix == B3_PLBVH_INVALID_COMMON_PREFIX) isLeftHigherCommonPrefix = false;\n" -" if(rightCommonPrefix == B3_PLBVH_INVALID_COMMON_PREFIX) isLeftHigherCommonPrefix = true;\n" -" \n" -" int parentNodeIndex = (isLeftHigherCommonPrefix) ? leftSplitIndex : rightSplitIndex;\n" -" out_leafNodeParentNodes[leafNodeIndex] = parentNodeIndex;\n" -" \n" -" int isRightChild = (isLeftHigherCommonPrefix); //If the left node is the parent, then this node is its right child and vice versa\n" -" \n" -" //out_childNodesAsInt[0] == int2.x == left child\n" -" //out_childNodesAsInt[1] == int2.y == right child\n" -" int isLeaf = 1;\n" -" __global int* out_childNodesAsInt = (__global int*)(&out_childNodes[parentNodeIndex]);\n" -" out_childNodesAsInt[isRightChild] = getIndexWithInternalNodeMarkerSet(isLeaf, leafNodeIndex);\n" -"}\n" -"__kernel void buildBinaryRadixTreeInternalNodes(__global b3Int64* commonPrefixes, __global int* commonPrefixLengths,\n" -" __global int2* out_childNodes,\n" -" __global int* out_internalNodeParentNodes, __global int* out_rootNodeIndex,\n" -" int numInternalNodes)\n" -"{\n" -" int internalNodeIndex = get_group_id(0) * get_local_size(0) + get_local_id(0);\n" -" if(internalNodeIndex >= numInternalNodes) return;\n" -" \n" -" b3Int64 nodePrefix = commonPrefixes[internalNodeIndex];\n" -" int nodePrefixLength = commonPrefixLengths[internalNodeIndex];\n" -" \n" -"//#define USE_LINEAR_SEARCH\n" -"#ifdef USE_LINEAR_SEARCH\n" -" int leftIndex = -1;\n" -" int rightIndex = -1;\n" -" \n" -" //Find nearest element to left with a lower common prefix\n" -" for(int i = internalNodeIndex - 1; i >= 0; --i)\n" -" {\n" -" int nodeLeftSharedPrefixLength = getSharedPrefixLength(nodePrefix, nodePrefixLength, commonPrefixes[i], commonPrefixLengths[i]);\n" -" if(nodeLeftSharedPrefixLength < nodePrefixLength)\n" -" {\n" -" leftIndex = i;\n" -" break;\n" -" }\n" -" }\n" -" \n" -" //Find nearest element to right with a lower common prefix\n" -" for(int i = internalNodeIndex + 1; i < numInternalNodes; ++i)\n" -" {\n" -" int nodeRightSharedPrefixLength = getSharedPrefixLength(nodePrefix, nodePrefixLength, commonPrefixes[i], commonPrefixLengths[i]);\n" -" if(nodeRightSharedPrefixLength < nodePrefixLength)\n" -" {\n" -" rightIndex = i;\n" -" break;\n" -" }\n" -" }\n" -" \n" -"#else //Use binary search\n" -" //Find nearest element to left with a lower common prefix\n" -" int leftIndex = -1;\n" -" {\n" -" int lower = 0;\n" -" int upper = internalNodeIndex - 1;\n" -" \n" -" while(lower <= upper)\n" -" {\n" -" int mid = (lower + upper) / 2;\n" -" b3Int64 midPrefix = commonPrefixes[mid];\n" -" int midPrefixLength = commonPrefixLengths[mid];\n" -" \n" -" int nodeMidSharedPrefixLength = getSharedPrefixLength(nodePrefix, nodePrefixLength, midPrefix, midPrefixLength);\n" -" if(nodeMidSharedPrefixLength < nodePrefixLength) \n" -" {\n" -" int right = mid + 1;\n" -" if(right < internalNodeIndex)\n" -" {\n" -" b3Int64 rightPrefix = commonPrefixes[right];\n" -" int rightPrefixLength = commonPrefixLengths[right];\n" -" \n" -" int nodeRightSharedPrefixLength = getSharedPrefixLength(nodePrefix, nodePrefixLength, rightPrefix, rightPrefixLength);\n" -" if(nodeRightSharedPrefixLength < nodePrefixLength) \n" -" {\n" -" lower = right;\n" -" leftIndex = right;\n" -" }\n" -" else \n" -" {\n" -" leftIndex = mid;\n" -" break;\n" -" }\n" -" }\n" -" else \n" -" {\n" -" leftIndex = mid;\n" -" break;\n" -" }\n" -" }\n" -" else upper = mid - 1;\n" -" }\n" -" }\n" -" \n" -" //Find nearest element to right with a lower common prefix\n" -" int rightIndex = -1;\n" -" {\n" -" int lower = internalNodeIndex + 1;\n" -" int upper = numInternalNodes - 1;\n" -" \n" -" while(lower <= upper)\n" -" {\n" -" int mid = (lower + upper) / 2;\n" -" b3Int64 midPrefix = commonPrefixes[mid];\n" -" int midPrefixLength = commonPrefixLengths[mid];\n" -" \n" -" int nodeMidSharedPrefixLength = getSharedPrefixLength(nodePrefix, nodePrefixLength, midPrefix, midPrefixLength);\n" -" if(nodeMidSharedPrefixLength < nodePrefixLength) \n" -" {\n" -" int left = mid - 1;\n" -" if(left > internalNodeIndex)\n" -" {\n" -" b3Int64 leftPrefix = commonPrefixes[left];\n" -" int leftPrefixLength = commonPrefixLengths[left];\n" -" \n" -" int nodeLeftSharedPrefixLength = getSharedPrefixLength(nodePrefix, nodePrefixLength, leftPrefix, leftPrefixLength);\n" -" if(nodeLeftSharedPrefixLength < nodePrefixLength) \n" -" {\n" -" upper = left;\n" -" rightIndex = left;\n" -" }\n" -" else \n" -" {\n" -" rightIndex = mid;\n" -" break;\n" -" }\n" -" }\n" -" else \n" -" {\n" -" rightIndex = mid;\n" -" break;\n" -" }\n" -" }\n" -" else lower = mid + 1;\n" -" }\n" -" }\n" -"#endif\n" -" \n" -" //Select parent\n" -" {\n" -" int leftPrefixLength = (leftIndex != -1) ? commonPrefixLengths[leftIndex] : B3_PLBVH_INVALID_COMMON_PREFIX;\n" -" int rightPrefixLength = (rightIndex != -1) ? commonPrefixLengths[rightIndex] : B3_PLBVH_INVALID_COMMON_PREFIX;\n" -" \n" -" int isLeftHigherPrefixLength = (leftPrefixLength > rightPrefixLength);\n" -" \n" -" if(leftPrefixLength == B3_PLBVH_INVALID_COMMON_PREFIX) isLeftHigherPrefixLength = false;\n" -" else if(rightPrefixLength == B3_PLBVH_INVALID_COMMON_PREFIX) isLeftHigherPrefixLength = true;\n" -" \n" -" int parentNodeIndex = (isLeftHigherPrefixLength) ? leftIndex : rightIndex;\n" -" \n" -" int isRootNode = (leftIndex == -1 && rightIndex == -1);\n" -" out_internalNodeParentNodes[internalNodeIndex] = (!isRootNode) ? parentNodeIndex : B3_PLBVH_ROOT_NODE_MARKER;\n" -" \n" -" int isLeaf = 0;\n" -" if(!isRootNode)\n" -" {\n" -" int isRightChild = (isLeftHigherPrefixLength); //If the left node is the parent, then this node is its right child and vice versa\n" -" \n" -" //out_childNodesAsInt[0] == int2.x == left child\n" -" //out_childNodesAsInt[1] == int2.y == right child\n" -" __global int* out_childNodesAsInt = (__global int*)(&out_childNodes[parentNodeIndex]);\n" -" out_childNodesAsInt[isRightChild] = getIndexWithInternalNodeMarkerSet(isLeaf, internalNodeIndex);\n" -" }\n" -" else *out_rootNodeIndex = getIndexWithInternalNodeMarkerSet(isLeaf, internalNodeIndex);\n" -" }\n" -"}\n" -"__kernel void findDistanceFromRoot(__global int* rootNodeIndex, __global int* internalNodeParentNodes,\n" -" __global int* out_maxDistanceFromRoot, __global int* out_distanceFromRoot, int numInternalNodes)\n" -"{\n" -" if( get_global_id(0) == 0 ) atomic_xchg(out_maxDistanceFromRoot, 0);\n" -" int internalNodeIndex = get_global_id(0);\n" -" if(internalNodeIndex >= numInternalNodes) return;\n" -" \n" -" //\n" -" int distanceFromRoot = 0;\n" -" {\n" -" int parentIndex = internalNodeParentNodes[internalNodeIndex];\n" -" while(parentIndex != B3_PLBVH_ROOT_NODE_MARKER)\n" -" {\n" -" parentIndex = internalNodeParentNodes[parentIndex];\n" -" ++distanceFromRoot;\n" -" }\n" -" }\n" -" out_distanceFromRoot[internalNodeIndex] = distanceFromRoot;\n" -" \n" -" //\n" -" __local int localMaxDistanceFromRoot;\n" -" if( get_local_id(0) == 0 ) localMaxDistanceFromRoot = 0;\n" -" barrier(CLK_LOCAL_MEM_FENCE);\n" -" \n" -" atomic_max(&localMaxDistanceFromRoot, distanceFromRoot);\n" -" barrier(CLK_LOCAL_MEM_FENCE);\n" -" \n" -" if( get_local_id(0) == 0 ) atomic_max(out_maxDistanceFromRoot, localMaxDistanceFromRoot);\n" -"}\n" -"__kernel void buildBinaryRadixTreeAabbsRecursive(__global int* distanceFromRoot, __global SortDataCL* mortonCodesAndAabbIndices,\n" -" __global int2* childNodes,\n" -" __global b3AabbCL* leafNodeAabbs, __global b3AabbCL* internalNodeAabbs,\n" -" int maxDistanceFromRoot, int processedDistance, int numInternalNodes)\n" -"{\n" -" int internalNodeIndex = get_global_id(0);\n" -" if(internalNodeIndex >= numInternalNodes) return;\n" -" \n" -" int distance = distanceFromRoot[internalNodeIndex];\n" -" \n" -" if(distance == processedDistance)\n" -" {\n" -" int leftChildIndex = childNodes[internalNodeIndex].x;\n" -" int rightChildIndex = childNodes[internalNodeIndex].y;\n" -" \n" -" int isLeftChildLeaf = isLeafNode(leftChildIndex);\n" -" int isRightChildLeaf = isLeafNode(rightChildIndex);\n" -" \n" -" leftChildIndex = getIndexWithInternalNodeMarkerRemoved(leftChildIndex);\n" -" rightChildIndex = getIndexWithInternalNodeMarkerRemoved(rightChildIndex);\n" -" \n" -" //leftRigidIndex/rightRigidIndex is not used if internal node\n" -" int leftRigidIndex = (isLeftChildLeaf) ? mortonCodesAndAabbIndices[leftChildIndex].m_value : -1;\n" -" int rightRigidIndex = (isRightChildLeaf) ? mortonCodesAndAabbIndices[rightChildIndex].m_value : -1;\n" -" \n" -" b3AabbCL leftChildAabb = (isLeftChildLeaf) ? leafNodeAabbs[leftRigidIndex] : internalNodeAabbs[leftChildIndex];\n" -" b3AabbCL rightChildAabb = (isRightChildLeaf) ? leafNodeAabbs[rightRigidIndex] : internalNodeAabbs[rightChildIndex];\n" -" \n" -" b3AabbCL mergedAabb;\n" -" mergedAabb.m_min = b3Min(leftChildAabb.m_min, rightChildAabb.m_min);\n" -" mergedAabb.m_max = b3Max(leftChildAabb.m_max, rightChildAabb.m_max);\n" -" internalNodeAabbs[internalNodeIndex] = mergedAabb;\n" -" }\n" -"}\n" -"__kernel void findLeafIndexRanges(__global int2* internalNodeChildNodes, __global int2* out_leafIndexRanges, int numInternalNodes)\n" -"{\n" -" int internalNodeIndex = get_global_id(0);\n" -" if(internalNodeIndex >= numInternalNodes) return;\n" -" \n" -" int numLeafNodes = numInternalNodes + 1;\n" -" \n" -" int2 childNodes = internalNodeChildNodes[internalNodeIndex];\n" -" \n" -" int2 leafIndexRange; //x == min leaf index, y == max leaf index\n" -" \n" -" //Find lowest leaf index covered by this internal node\n" -" {\n" -" int lowestIndex = childNodes.x; //childNodes.x == Left child\n" -" while( !isLeafNode(lowestIndex) ) lowestIndex = internalNodeChildNodes[ getIndexWithInternalNodeMarkerRemoved(lowestIndex) ].x;\n" -" leafIndexRange.x = lowestIndex;\n" -" }\n" -" \n" -" //Find highest leaf index covered by this internal node\n" -" {\n" -" int highestIndex = childNodes.y; //childNodes.y == Right child\n" -" while( !isLeafNode(highestIndex) ) highestIndex = internalNodeChildNodes[ getIndexWithInternalNodeMarkerRemoved(highestIndex) ].y;\n" -" leafIndexRange.y = highestIndex;\n" -" }\n" -" \n" -" //\n" -" out_leafIndexRanges[internalNodeIndex] = leafIndexRange;\n" -"}\n" -; +static const char* parallelLinearBvhCL = + "/*\n" + "This software is provided 'as-is', without any express or implied warranty.\n" + "In no event will the authors be held liable for any damages arising from the use of this software.\n" + "Permission is granted to anyone to use this software for any purpose,\n" + "including commercial applications, and to alter it and redistribute it freely,\n" + "subject to the following restrictions:\n" + "1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" + "2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" + "3. This notice may not be removed or altered from any source distribution.\n" + "*/\n" + "//Initial Author Jackson Lee, 2014\n" + "typedef float b3Scalar;\n" + "typedef float4 b3Vector3;\n" + "#define b3Max max\n" + "#define b3Min min\n" + "#define b3Sqrt sqrt\n" + "typedef struct\n" + "{\n" + " unsigned int m_key;\n" + " unsigned int m_value;\n" + "} SortDataCL;\n" + "typedef struct \n" + "{\n" + " union\n" + " {\n" + " float4 m_min;\n" + " float m_minElems[4];\n" + " int m_minIndices[4];\n" + " };\n" + " union\n" + " {\n" + " float4 m_max;\n" + " float m_maxElems[4];\n" + " int m_maxIndices[4];\n" + " };\n" + "} b3AabbCL;\n" + "unsigned int interleaveBits(unsigned int x)\n" + "{\n" + " //........ ........ ......12 3456789A //x\n" + " //....1..2 ..3..4.. 5..6..7. .8..9..A //x after interleaving bits\n" + " \n" + " //......12 3456789A ......12 3456789A //x ^ (x << 16)\n" + " //11111111 ........ ........ 11111111 //0x FF 00 00 FF\n" + " //......12 ........ ........ 3456789A //x = (x ^ (x << 16)) & 0xFF0000FF;\n" + " \n" + " //......12 ........ 3456789A 3456789A //x ^ (x << 8)\n" + " //......11 ........ 1111.... ....1111 //0x 03 00 F0 0F\n" + " //......12 ........ 3456.... ....789A //x = (x ^ (x << 8)) & 0x0300F00F;\n" + " \n" + " //..12..12 ....3456 3456.... 789A789A //x ^ (x << 4)\n" + " //......11 ....11.. ..11.... 11....11 //0x 03 0C 30 C3\n" + " //......12 ....34.. ..56.... 78....9A //x = (x ^ (x << 4)) & 0x030C30C3;\n" + " \n" + " //....1212 ..3434.. 5656..78 78..9A9A //x ^ (x << 2)\n" + " //....1..1 ..1..1.. 1..1..1. .1..1..1 //0x 09 24 92 49\n" + " //....1..2 ..3..4.. 5..6..7. .8..9..A //x = (x ^ (x << 2)) & 0x09249249;\n" + " \n" + " //........ ........ ......11 11111111 //0x000003FF\n" + " x &= 0x000003FF; //Clear all bits above bit 10\n" + " \n" + " x = (x ^ (x << 16)) & 0xFF0000FF;\n" + " x = (x ^ (x << 8)) & 0x0300F00F;\n" + " x = (x ^ (x << 4)) & 0x030C30C3;\n" + " x = (x ^ (x << 2)) & 0x09249249;\n" + " \n" + " return x;\n" + "}\n" + "unsigned int getMortonCode(unsigned int x, unsigned int y, unsigned int z)\n" + "{\n" + " return interleaveBits(x) << 0 | interleaveBits(y) << 1 | interleaveBits(z) << 2;\n" + "}\n" + "__kernel void separateAabbs(__global b3AabbCL* unseparatedAabbs, __global int* aabbIndices, __global b3AabbCL* out_aabbs, int numAabbsToSeparate)\n" + "{\n" + " int separatedAabbIndex = get_global_id(0);\n" + " if(separatedAabbIndex >= numAabbsToSeparate) return;\n" + " int unseparatedAabbIndex = aabbIndices[separatedAabbIndex];\n" + " out_aabbs[separatedAabbIndex] = unseparatedAabbs[unseparatedAabbIndex];\n" + "}\n" + "//Should replace with an optimized parallel reduction\n" + "__kernel void findAllNodesMergedAabb(__global b3AabbCL* out_mergedAabb, int numAabbsNeedingMerge)\n" + "{\n" + " //Each time this kernel is added to the command queue, \n" + " //the number of AABBs needing to be merged is halved\n" + " //\n" + " //Example with 159 AABBs:\n" + " // numRemainingAabbs == 159 / 2 + 159 % 2 == 80\n" + " // numMergedAabbs == 159 - 80 == 79\n" + " //So, indices [0, 78] are merged with [0 + 80, 78 + 80]\n" + " \n" + " int numRemainingAabbs = numAabbsNeedingMerge / 2 + numAabbsNeedingMerge % 2;\n" + " int numMergedAabbs = numAabbsNeedingMerge - numRemainingAabbs;\n" + " \n" + " int aabbIndex = get_global_id(0);\n" + " if(aabbIndex >= numMergedAabbs) return;\n" + " \n" + " int otherAabbIndex = aabbIndex + numRemainingAabbs;\n" + " \n" + " b3AabbCL aabb = out_mergedAabb[aabbIndex];\n" + " b3AabbCL otherAabb = out_mergedAabb[otherAabbIndex];\n" + " \n" + " b3AabbCL mergedAabb;\n" + " mergedAabb.m_min = b3Min(aabb.m_min, otherAabb.m_min);\n" + " mergedAabb.m_max = b3Max(aabb.m_max, otherAabb.m_max);\n" + " out_mergedAabb[aabbIndex] = mergedAabb;\n" + "}\n" + "__kernel void assignMortonCodesAndAabbIndicies(__global b3AabbCL* worldSpaceAabbs, __global b3AabbCL* mergedAabbOfAllNodes, \n" + " __global SortDataCL* out_mortonCodesAndAabbIndices, int numAabbs)\n" + "{\n" + " int leafNodeIndex = get_global_id(0); //Leaf node index == AABB index\n" + " if(leafNodeIndex >= numAabbs) return;\n" + " \n" + " b3AabbCL mergedAabb = mergedAabbOfAllNodes[0];\n" + " b3Vector3 gridCenter = (mergedAabb.m_min + mergedAabb.m_max) * 0.5f;\n" + " b3Vector3 gridCellSize = (mergedAabb.m_max - mergedAabb.m_min) / (float)1024;\n" + " \n" + " b3AabbCL aabb = worldSpaceAabbs[leafNodeIndex];\n" + " b3Vector3 aabbCenter = (aabb.m_min + aabb.m_max) * 0.5f;\n" + " b3Vector3 aabbCenterRelativeToGrid = aabbCenter - gridCenter;\n" + " \n" + " //Quantize into integer coordinates\n" + " //floor() is needed to prevent the center cell, at (0,0,0) from being twice the size\n" + " b3Vector3 gridPosition = aabbCenterRelativeToGrid / gridCellSize;\n" + " \n" + " int4 discretePosition;\n" + " discretePosition.x = (int)( (gridPosition.x >= 0.0f) ? gridPosition.x : floor(gridPosition.x) );\n" + " discretePosition.y = (int)( (gridPosition.y >= 0.0f) ? gridPosition.y : floor(gridPosition.y) );\n" + " discretePosition.z = (int)( (gridPosition.z >= 0.0f) ? gridPosition.z : floor(gridPosition.z) );\n" + " \n" + " //Clamp coordinates into [-512, 511], then convert range from [-512, 511] to [0, 1023]\n" + " discretePosition = b3Max( -512, b3Min(discretePosition, 511) );\n" + " discretePosition += 512;\n" + " \n" + " //Interleave bits(assign a morton code, also known as a z-curve)\n" + " unsigned int mortonCode = getMortonCode(discretePosition.x, discretePosition.y, discretePosition.z);\n" + " \n" + " //\n" + " SortDataCL mortonCodeIndexPair;\n" + " mortonCodeIndexPair.m_key = mortonCode;\n" + " mortonCodeIndexPair.m_value = leafNodeIndex;\n" + " \n" + " out_mortonCodesAndAabbIndices[leafNodeIndex] = mortonCodeIndexPair;\n" + "}\n" + "#define B3_PLVBH_TRAVERSE_MAX_STACK_SIZE 128\n" + "//The most significant bit(0x80000000) of a int32 is used to distinguish between leaf and internal nodes.\n" + "//If it is set, then the index is for an internal node; otherwise, it is a leaf node. \n" + "//In both cases, the bit should be cleared to access the actual node index.\n" + "int isLeafNode(int index) { return (index >> 31 == 0); }\n" + "int getIndexWithInternalNodeMarkerRemoved(int index) { return index & (~0x80000000); }\n" + "int getIndexWithInternalNodeMarkerSet(int isLeaf, int index) { return (isLeaf) ? index : (index | 0x80000000); }\n" + "//From sap.cl\n" + "#define NEW_PAIR_MARKER -1\n" + "bool TestAabbAgainstAabb2(const b3AabbCL* aabb1, const b3AabbCL* aabb2)\n" + "{\n" + " bool overlap = true;\n" + " overlap = (aabb1->m_min.x > aabb2->m_max.x || aabb1->m_max.x < aabb2->m_min.x) ? false : overlap;\n" + " overlap = (aabb1->m_min.z > aabb2->m_max.z || aabb1->m_max.z < aabb2->m_min.z) ? false : overlap;\n" + " overlap = (aabb1->m_min.y > aabb2->m_max.y || aabb1->m_max.y < aabb2->m_min.y) ? false : overlap;\n" + " return overlap;\n" + "}\n" + "//From sap.cl\n" + "__kernel void plbvhCalculateOverlappingPairs(__global b3AabbCL* rigidAabbs, \n" + " __global int* rootNodeIndex, \n" + " __global int2* internalNodeChildIndices, \n" + " __global b3AabbCL* internalNodeAabbs,\n" + " __global int2* internalNodeLeafIndexRanges,\n" + " \n" + " __global SortDataCL* mortonCodesAndAabbIndices,\n" + " __global int* out_numPairs, __global int4* out_overlappingPairs, \n" + " int maxPairs, int numQueryAabbs)\n" + "{\n" + " //Using get_group_id()/get_local_id() is Faster than get_global_id(0) since\n" + " //mortonCodesAndAabbIndices[] contains rigid body indices sorted along the z-curve (more spatially coherent)\n" + " int queryBvhNodeIndex = get_group_id(0) * get_local_size(0) + get_local_id(0);\n" + " if(queryBvhNodeIndex >= numQueryAabbs) return;\n" + " \n" + " int queryRigidIndex = mortonCodesAndAabbIndices[queryBvhNodeIndex].m_value;\n" + " b3AabbCL queryAabb = rigidAabbs[queryRigidIndex];\n" + " \n" + " int stack[B3_PLVBH_TRAVERSE_MAX_STACK_SIZE];\n" + " \n" + " int stackSize = 1;\n" + " stack[0] = *rootNodeIndex;\n" + " \n" + " while(stackSize)\n" + " {\n" + " int internalOrLeafNodeIndex = stack[ stackSize - 1 ];\n" + " --stackSize;\n" + " \n" + " int isLeaf = isLeafNode(internalOrLeafNodeIndex); //Internal node if false\n" + " int bvhNodeIndex = getIndexWithInternalNodeMarkerRemoved(internalOrLeafNodeIndex);\n" + " \n" + " //Optimization - if the BVH is structured as a binary radix tree, then\n" + " //each internal node corresponds to a contiguous range of leaf nodes(internalNodeLeafIndexRanges[]).\n" + " //This can be used to avoid testing each AABB-AABB pair twice, including preventing each node from colliding with itself.\n" + " {\n" + " int highestLeafIndex = (isLeaf) ? bvhNodeIndex : internalNodeLeafIndexRanges[bvhNodeIndex].y;\n" + " if(highestLeafIndex <= queryBvhNodeIndex) continue;\n" + " }\n" + " \n" + " //bvhRigidIndex is not used if internal node\n" + " int bvhRigidIndex = (isLeaf) ? mortonCodesAndAabbIndices[bvhNodeIndex].m_value : -1;\n" + " \n" + " b3AabbCL bvhNodeAabb = (isLeaf) ? rigidAabbs[bvhRigidIndex] : internalNodeAabbs[bvhNodeIndex];\n" + " if( TestAabbAgainstAabb2(&queryAabb, &bvhNodeAabb) )\n" + " {\n" + " if(isLeaf)\n" + " {\n" + " int4 pair;\n" + " pair.x = rigidAabbs[queryRigidIndex].m_minIndices[3];\n" + " pair.y = rigidAabbs[bvhRigidIndex].m_minIndices[3];\n" + " pair.z = NEW_PAIR_MARKER;\n" + " pair.w = NEW_PAIR_MARKER;\n" + " \n" + " int pairIndex = atomic_inc(out_numPairs);\n" + " if(pairIndex < maxPairs) out_overlappingPairs[pairIndex] = pair;\n" + " }\n" + " \n" + " if(!isLeaf) //Internal node\n" + " {\n" + " if(stackSize + 2 > B3_PLVBH_TRAVERSE_MAX_STACK_SIZE)\n" + " {\n" + " //Error\n" + " }\n" + " else\n" + " {\n" + " stack[ stackSize++ ] = internalNodeChildIndices[bvhNodeIndex].x;\n" + " stack[ stackSize++ ] = internalNodeChildIndices[bvhNodeIndex].y;\n" + " }\n" + " }\n" + " }\n" + " \n" + " }\n" + "}\n" + "//From rayCastKernels.cl\n" + "typedef struct\n" + "{\n" + " float4 m_from;\n" + " float4 m_to;\n" + "} b3RayInfo;\n" + "//From rayCastKernels.cl\n" + "b3Vector3 b3Vector3_normalize(b3Vector3 v)\n" + "{\n" + " b3Vector3 normal = (b3Vector3){v.x, v.y, v.z, 0.f};\n" + " return normalize(normal); //OpenCL normalize == vector4 normalize\n" + "}\n" + "b3Scalar b3Vector3_length2(b3Vector3 v) { return v.x*v.x + v.y*v.y + v.z*v.z; }\n" + "b3Scalar b3Vector3_dot(b3Vector3 a, b3Vector3 b) { return a.x*b.x + a.y*b.y + a.z*b.z; }\n" + "int rayIntersectsAabb(b3Vector3 rayOrigin, b3Scalar rayLength, b3Vector3 rayNormalizedDirection, b3AabbCL aabb)\n" + "{\n" + " //AABB is considered as 3 pairs of 2 planes( {x_min, x_max}, {y_min, y_max}, {z_min, z_max} ).\n" + " //t_min is the point of intersection with the closer plane, t_max is the point of intersection with the farther plane.\n" + " //\n" + " //if (rayNormalizedDirection.x < 0.0f), then max.x will be the near plane \n" + " //and min.x will be the far plane; otherwise, it is reversed.\n" + " //\n" + " //In order for there to be a collision, the t_min and t_max of each pair must overlap.\n" + " //This can be tested for by selecting the highest t_min and lowest t_max and comparing them.\n" + " \n" + " int4 isNegative = isless( rayNormalizedDirection, ((b3Vector3){0.0f, 0.0f, 0.0f, 0.0f}) ); //isless(x,y) returns (x < y)\n" + " \n" + " //When using vector types, the select() function checks the most signficant bit, \n" + " //but isless() sets the least significant bit.\n" + " isNegative <<= 31;\n" + " //select(b, a, condition) == condition ? a : b\n" + " //When using select() with vector types, (condition[i]) is true if its most significant bit is 1\n" + " b3Vector3 t_min = ( select(aabb.m_min, aabb.m_max, isNegative) - rayOrigin ) / rayNormalizedDirection;\n" + " b3Vector3 t_max = ( select(aabb.m_max, aabb.m_min, isNegative) - rayOrigin ) / rayNormalizedDirection;\n" + " \n" + " b3Scalar t_min_final = 0.0f;\n" + " b3Scalar t_max_final = rayLength;\n" + " \n" + " //Must use fmin()/fmax(); if one of the parameters is NaN, then the parameter that is not NaN is returned. \n" + " //Behavior of min()/max() with NaNs is undefined. (See OpenCL Specification 1.2 [6.12.2] and [6.12.4])\n" + " //Since the innermost fmin()/fmax() is always not NaN, this should never return NaN.\n" + " t_min_final = fmax( t_min.z, fmax(t_min.y, fmax(t_min.x, t_min_final)) );\n" + " t_max_final = fmin( t_max.z, fmin(t_max.y, fmin(t_max.x, t_max_final)) );\n" + " \n" + " return (t_min_final <= t_max_final);\n" + "}\n" + "__kernel void plbvhRayTraverse(__global b3AabbCL* rigidAabbs,\n" + " __global int* rootNodeIndex, \n" + " __global int2* internalNodeChildIndices, \n" + " __global b3AabbCL* internalNodeAabbs,\n" + " __global int2* internalNodeLeafIndexRanges,\n" + " __global SortDataCL* mortonCodesAndAabbIndices,\n" + " \n" + " __global b3RayInfo* rays,\n" + " \n" + " __global int* out_numRayRigidPairs, \n" + " __global int2* out_rayRigidPairs,\n" + " int maxRayRigidPairs, int numRays)\n" + "{\n" + " int rayIndex = get_global_id(0);\n" + " if(rayIndex >= numRays) return;\n" + " \n" + " //\n" + " b3Vector3 rayFrom = rays[rayIndex].m_from;\n" + " b3Vector3 rayTo = rays[rayIndex].m_to;\n" + " b3Vector3 rayNormalizedDirection = b3Vector3_normalize(rayTo - rayFrom);\n" + " b3Scalar rayLength = b3Sqrt( b3Vector3_length2(rayTo - rayFrom) );\n" + " \n" + " //\n" + " int stack[B3_PLVBH_TRAVERSE_MAX_STACK_SIZE];\n" + " \n" + " int stackSize = 1;\n" + " stack[0] = *rootNodeIndex;\n" + " \n" + " while(stackSize)\n" + " {\n" + " int internalOrLeafNodeIndex = stack[ stackSize - 1 ];\n" + " --stackSize;\n" + " \n" + " int isLeaf = isLeafNode(internalOrLeafNodeIndex); //Internal node if false\n" + " int bvhNodeIndex = getIndexWithInternalNodeMarkerRemoved(internalOrLeafNodeIndex);\n" + " \n" + " //bvhRigidIndex is not used if internal node\n" + " int bvhRigidIndex = (isLeaf) ? mortonCodesAndAabbIndices[bvhNodeIndex].m_value : -1;\n" + " \n" + " b3AabbCL bvhNodeAabb = (isLeaf) ? rigidAabbs[bvhRigidIndex] : internalNodeAabbs[bvhNodeIndex];\n" + " if( rayIntersectsAabb(rayFrom, rayLength, rayNormalizedDirection, bvhNodeAabb) )\n" + " {\n" + " if(isLeaf)\n" + " {\n" + " int2 rayRigidPair;\n" + " rayRigidPair.x = rayIndex;\n" + " rayRigidPair.y = rigidAabbs[bvhRigidIndex].m_minIndices[3];\n" + " \n" + " int pairIndex = atomic_inc(out_numRayRigidPairs);\n" + " if(pairIndex < maxRayRigidPairs) out_rayRigidPairs[pairIndex] = rayRigidPair;\n" + " }\n" + " \n" + " if(!isLeaf) //Internal node\n" + " {\n" + " if(stackSize + 2 > B3_PLVBH_TRAVERSE_MAX_STACK_SIZE)\n" + " {\n" + " //Error\n" + " }\n" + " else\n" + " {\n" + " stack[ stackSize++ ] = internalNodeChildIndices[bvhNodeIndex].x;\n" + " stack[ stackSize++ ] = internalNodeChildIndices[bvhNodeIndex].y;\n" + " }\n" + " }\n" + " }\n" + " }\n" + "}\n" + "__kernel void plbvhLargeAabbAabbTest(__global b3AabbCL* smallAabbs, __global b3AabbCL* largeAabbs, \n" + " __global int* out_numPairs, __global int4* out_overlappingPairs, \n" + " int maxPairs, int numLargeAabbRigids, int numSmallAabbRigids)\n" + "{\n" + " int smallAabbIndex = get_global_id(0);\n" + " if(smallAabbIndex >= numSmallAabbRigids) return;\n" + " \n" + " b3AabbCL smallAabb = smallAabbs[smallAabbIndex];\n" + " for(int i = 0; i < numLargeAabbRigids; ++i)\n" + " {\n" + " b3AabbCL largeAabb = largeAabbs[i];\n" + " if( TestAabbAgainstAabb2(&smallAabb, &largeAabb) )\n" + " {\n" + " int4 pair;\n" + " pair.x = largeAabb.m_minIndices[3];\n" + " pair.y = smallAabb.m_minIndices[3];\n" + " pair.z = NEW_PAIR_MARKER;\n" + " pair.w = NEW_PAIR_MARKER;\n" + " \n" + " int pairIndex = atomic_inc(out_numPairs);\n" + " if(pairIndex < maxPairs) out_overlappingPairs[pairIndex] = pair;\n" + " }\n" + " }\n" + "}\n" + "__kernel void plbvhLargeAabbRayTest(__global b3AabbCL* largeRigidAabbs, __global b3RayInfo* rays,\n" + " __global int* out_numRayRigidPairs, __global int2* out_rayRigidPairs,\n" + " int numLargeAabbRigids, int maxRayRigidPairs, int numRays)\n" + "{\n" + " int rayIndex = get_global_id(0);\n" + " if(rayIndex >= numRays) return;\n" + " \n" + " b3Vector3 rayFrom = rays[rayIndex].m_from;\n" + " b3Vector3 rayTo = rays[rayIndex].m_to;\n" + " b3Vector3 rayNormalizedDirection = b3Vector3_normalize(rayTo - rayFrom);\n" + " b3Scalar rayLength = b3Sqrt( b3Vector3_length2(rayTo - rayFrom) );\n" + " \n" + " for(int i = 0; i < numLargeAabbRigids; ++i)\n" + " {\n" + " b3AabbCL rigidAabb = largeRigidAabbs[i];\n" + " if( rayIntersectsAabb(rayFrom, rayLength, rayNormalizedDirection, rigidAabb) )\n" + " {\n" + " int2 rayRigidPair;\n" + " rayRigidPair.x = rayIndex;\n" + " rayRigidPair.y = rigidAabb.m_minIndices[3];\n" + " \n" + " int pairIndex = atomic_inc(out_numRayRigidPairs);\n" + " if(pairIndex < maxRayRigidPairs) out_rayRigidPairs[pairIndex] = rayRigidPair;\n" + " }\n" + " }\n" + "}\n" + "//Set so that it is always greater than the actual common prefixes, and never selected as a parent node.\n" + "//If there are no duplicates, then the highest common prefix is 32 or 64, depending on the number of bits used for the z-curve.\n" + "//Duplicate common prefixes increase the highest common prefix at most by the number of bits used to index the leaf node.\n" + "//Since 32 bit ints are used to index leaf nodes, the max prefix is 64(32 + 32 bit z-curve) or 96(32 + 64 bit z-curve).\n" + "#define B3_PLBVH_INVALID_COMMON_PREFIX 128\n" + "#define B3_PLBVH_ROOT_NODE_MARKER -1\n" + "#define b3Int64 long\n" + "int computeCommonPrefixLength(b3Int64 i, b3Int64 j) { return (int)clz(i ^ j); }\n" + "b3Int64 computeCommonPrefix(b3Int64 i, b3Int64 j) \n" + "{\n" + " //This function only needs to return (i & j) in order for the algorithm to work,\n" + " //but it may help with debugging to mask out the lower bits.\n" + " b3Int64 commonPrefixLength = (b3Int64)computeCommonPrefixLength(i, j);\n" + " b3Int64 sharedBits = i & j;\n" + " b3Int64 bitmask = ((b3Int64)(~0)) << (64 - commonPrefixLength); //Set all bits after the common prefix to 0\n" + " \n" + " return sharedBits & bitmask;\n" + "}\n" + "//Same as computeCommonPrefixLength(), but allows for prefixes with different lengths\n" + "int getSharedPrefixLength(b3Int64 prefixA, int prefixLengthA, b3Int64 prefixB, int prefixLengthB)\n" + "{\n" + " return b3Min( computeCommonPrefixLength(prefixA, prefixB), b3Min(prefixLengthA, prefixLengthB) );\n" + "}\n" + "__kernel void computeAdjacentPairCommonPrefix(__global SortDataCL* mortonCodesAndAabbIndices,\n" + " __global b3Int64* out_commonPrefixes,\n" + " __global int* out_commonPrefixLengths,\n" + " int numInternalNodes)\n" + "{\n" + " int internalNodeIndex = get_global_id(0);\n" + " if (internalNodeIndex >= numInternalNodes) return;\n" + " \n" + " //Here, (internalNodeIndex + 1) is never out of bounds since it is a leaf node index,\n" + " //and the number of internal nodes is always numLeafNodes - 1\n" + " int leftLeafIndex = internalNodeIndex;\n" + " int rightLeafIndex = internalNodeIndex + 1;\n" + " \n" + " int leftLeafMortonCode = mortonCodesAndAabbIndices[leftLeafIndex].m_key;\n" + " int rightLeafMortonCode = mortonCodesAndAabbIndices[rightLeafIndex].m_key;\n" + " \n" + " //Binary radix tree construction algorithm does not work if there are duplicate morton codes.\n" + " //Append the index of each leaf node to each morton code so that there are no duplicates.\n" + " //The algorithm also requires that the morton codes are sorted in ascending order; this requirement\n" + " //is also satisfied with this method, as (leftLeafIndex < rightLeafIndex) is always true.\n" + " //\n" + " //upsample(a, b) == ( ((b3Int64)a) << 32) | b\n" + " b3Int64 nonduplicateLeftMortonCode = upsample(leftLeafMortonCode, leftLeafIndex);\n" + " b3Int64 nonduplicateRightMortonCode = upsample(rightLeafMortonCode, rightLeafIndex);\n" + " \n" + " out_commonPrefixes[internalNodeIndex] = computeCommonPrefix(nonduplicateLeftMortonCode, nonduplicateRightMortonCode);\n" + " out_commonPrefixLengths[internalNodeIndex] = computeCommonPrefixLength(nonduplicateLeftMortonCode, nonduplicateRightMortonCode);\n" + "}\n" + "__kernel void buildBinaryRadixTreeLeafNodes(__global int* commonPrefixLengths, __global int* out_leafNodeParentNodes,\n" + " __global int2* out_childNodes, int numLeafNodes)\n" + "{\n" + " int leafNodeIndex = get_global_id(0);\n" + " if (leafNodeIndex >= numLeafNodes) return;\n" + " \n" + " int numInternalNodes = numLeafNodes - 1;\n" + " \n" + " int leftSplitIndex = leafNodeIndex - 1;\n" + " int rightSplitIndex = leafNodeIndex;\n" + " \n" + " int leftCommonPrefix = (leftSplitIndex >= 0) ? commonPrefixLengths[leftSplitIndex] : B3_PLBVH_INVALID_COMMON_PREFIX;\n" + " int rightCommonPrefix = (rightSplitIndex < numInternalNodes) ? commonPrefixLengths[rightSplitIndex] : B3_PLBVH_INVALID_COMMON_PREFIX;\n" + " \n" + " //Parent node is the highest adjacent common prefix that is lower than the node's common prefix\n" + " //Leaf nodes are considered as having the highest common prefix\n" + " int isLeftHigherCommonPrefix = (leftCommonPrefix > rightCommonPrefix);\n" + " \n" + " //Handle cases for the edge nodes; the first and last node\n" + " //For leaf nodes, leftCommonPrefix and rightCommonPrefix should never both be B3_PLBVH_INVALID_COMMON_PREFIX\n" + " if(leftCommonPrefix == B3_PLBVH_INVALID_COMMON_PREFIX) isLeftHigherCommonPrefix = false;\n" + " if(rightCommonPrefix == B3_PLBVH_INVALID_COMMON_PREFIX) isLeftHigherCommonPrefix = true;\n" + " \n" + " int parentNodeIndex = (isLeftHigherCommonPrefix) ? leftSplitIndex : rightSplitIndex;\n" + " out_leafNodeParentNodes[leafNodeIndex] = parentNodeIndex;\n" + " \n" + " int isRightChild = (isLeftHigherCommonPrefix); //If the left node is the parent, then this node is its right child and vice versa\n" + " \n" + " //out_childNodesAsInt[0] == int2.x == left child\n" + " //out_childNodesAsInt[1] == int2.y == right child\n" + " int isLeaf = 1;\n" + " __global int* out_childNodesAsInt = (__global int*)(&out_childNodes[parentNodeIndex]);\n" + " out_childNodesAsInt[isRightChild] = getIndexWithInternalNodeMarkerSet(isLeaf, leafNodeIndex);\n" + "}\n" + "__kernel void buildBinaryRadixTreeInternalNodes(__global b3Int64* commonPrefixes, __global int* commonPrefixLengths,\n" + " __global int2* out_childNodes,\n" + " __global int* out_internalNodeParentNodes, __global int* out_rootNodeIndex,\n" + " int numInternalNodes)\n" + "{\n" + " int internalNodeIndex = get_group_id(0) * get_local_size(0) + get_local_id(0);\n" + " if(internalNodeIndex >= numInternalNodes) return;\n" + " \n" + " b3Int64 nodePrefix = commonPrefixes[internalNodeIndex];\n" + " int nodePrefixLength = commonPrefixLengths[internalNodeIndex];\n" + " \n" + "//#define USE_LINEAR_SEARCH\n" + "#ifdef USE_LINEAR_SEARCH\n" + " int leftIndex = -1;\n" + " int rightIndex = -1;\n" + " \n" + " //Find nearest element to left with a lower common prefix\n" + " for(int i = internalNodeIndex - 1; i >= 0; --i)\n" + " {\n" + " int nodeLeftSharedPrefixLength = getSharedPrefixLength(nodePrefix, nodePrefixLength, commonPrefixes[i], commonPrefixLengths[i]);\n" + " if(nodeLeftSharedPrefixLength < nodePrefixLength)\n" + " {\n" + " leftIndex = i;\n" + " break;\n" + " }\n" + " }\n" + " \n" + " //Find nearest element to right with a lower common prefix\n" + " for(int i = internalNodeIndex + 1; i < numInternalNodes; ++i)\n" + " {\n" + " int nodeRightSharedPrefixLength = getSharedPrefixLength(nodePrefix, nodePrefixLength, commonPrefixes[i], commonPrefixLengths[i]);\n" + " if(nodeRightSharedPrefixLength < nodePrefixLength)\n" + " {\n" + " rightIndex = i;\n" + " break;\n" + " }\n" + " }\n" + " \n" + "#else //Use binary search\n" + " //Find nearest element to left with a lower common prefix\n" + " int leftIndex = -1;\n" + " {\n" + " int lower = 0;\n" + " int upper = internalNodeIndex - 1;\n" + " \n" + " while(lower <= upper)\n" + " {\n" + " int mid = (lower + upper) / 2;\n" + " b3Int64 midPrefix = commonPrefixes[mid];\n" + " int midPrefixLength = commonPrefixLengths[mid];\n" + " \n" + " int nodeMidSharedPrefixLength = getSharedPrefixLength(nodePrefix, nodePrefixLength, midPrefix, midPrefixLength);\n" + " if(nodeMidSharedPrefixLength < nodePrefixLength) \n" + " {\n" + " int right = mid + 1;\n" + " if(right < internalNodeIndex)\n" + " {\n" + " b3Int64 rightPrefix = commonPrefixes[right];\n" + " int rightPrefixLength = commonPrefixLengths[right];\n" + " \n" + " int nodeRightSharedPrefixLength = getSharedPrefixLength(nodePrefix, nodePrefixLength, rightPrefix, rightPrefixLength);\n" + " if(nodeRightSharedPrefixLength < nodePrefixLength) \n" + " {\n" + " lower = right;\n" + " leftIndex = right;\n" + " }\n" + " else \n" + " {\n" + " leftIndex = mid;\n" + " break;\n" + " }\n" + " }\n" + " else \n" + " {\n" + " leftIndex = mid;\n" + " break;\n" + " }\n" + " }\n" + " else upper = mid - 1;\n" + " }\n" + " }\n" + " \n" + " //Find nearest element to right with a lower common prefix\n" + " int rightIndex = -1;\n" + " {\n" + " int lower = internalNodeIndex + 1;\n" + " int upper = numInternalNodes - 1;\n" + " \n" + " while(lower <= upper)\n" + " {\n" + " int mid = (lower + upper) / 2;\n" + " b3Int64 midPrefix = commonPrefixes[mid];\n" + " int midPrefixLength = commonPrefixLengths[mid];\n" + " \n" + " int nodeMidSharedPrefixLength = getSharedPrefixLength(nodePrefix, nodePrefixLength, midPrefix, midPrefixLength);\n" + " if(nodeMidSharedPrefixLength < nodePrefixLength) \n" + " {\n" + " int left = mid - 1;\n" + " if(left > internalNodeIndex)\n" + " {\n" + " b3Int64 leftPrefix = commonPrefixes[left];\n" + " int leftPrefixLength = commonPrefixLengths[left];\n" + " \n" + " int nodeLeftSharedPrefixLength = getSharedPrefixLength(nodePrefix, nodePrefixLength, leftPrefix, leftPrefixLength);\n" + " if(nodeLeftSharedPrefixLength < nodePrefixLength) \n" + " {\n" + " upper = left;\n" + " rightIndex = left;\n" + " }\n" + " else \n" + " {\n" + " rightIndex = mid;\n" + " break;\n" + " }\n" + " }\n" + " else \n" + " {\n" + " rightIndex = mid;\n" + " break;\n" + " }\n" + " }\n" + " else lower = mid + 1;\n" + " }\n" + " }\n" + "#endif\n" + " \n" + " //Select parent\n" + " {\n" + " int leftPrefixLength = (leftIndex != -1) ? commonPrefixLengths[leftIndex] : B3_PLBVH_INVALID_COMMON_PREFIX;\n" + " int rightPrefixLength = (rightIndex != -1) ? commonPrefixLengths[rightIndex] : B3_PLBVH_INVALID_COMMON_PREFIX;\n" + " \n" + " int isLeftHigherPrefixLength = (leftPrefixLength > rightPrefixLength);\n" + " \n" + " if(leftPrefixLength == B3_PLBVH_INVALID_COMMON_PREFIX) isLeftHigherPrefixLength = false;\n" + " else if(rightPrefixLength == B3_PLBVH_INVALID_COMMON_PREFIX) isLeftHigherPrefixLength = true;\n" + " \n" + " int parentNodeIndex = (isLeftHigherPrefixLength) ? leftIndex : rightIndex;\n" + " \n" + " int isRootNode = (leftIndex == -1 && rightIndex == -1);\n" + " out_internalNodeParentNodes[internalNodeIndex] = (!isRootNode) ? parentNodeIndex : B3_PLBVH_ROOT_NODE_MARKER;\n" + " \n" + " int isLeaf = 0;\n" + " if(!isRootNode)\n" + " {\n" + " int isRightChild = (isLeftHigherPrefixLength); //If the left node is the parent, then this node is its right child and vice versa\n" + " \n" + " //out_childNodesAsInt[0] == int2.x == left child\n" + " //out_childNodesAsInt[1] == int2.y == right child\n" + " __global int* out_childNodesAsInt = (__global int*)(&out_childNodes[parentNodeIndex]);\n" + " out_childNodesAsInt[isRightChild] = getIndexWithInternalNodeMarkerSet(isLeaf, internalNodeIndex);\n" + " }\n" + " else *out_rootNodeIndex = getIndexWithInternalNodeMarkerSet(isLeaf, internalNodeIndex);\n" + " }\n" + "}\n" + "__kernel void findDistanceFromRoot(__global int* rootNodeIndex, __global int* internalNodeParentNodes,\n" + " __global int* out_maxDistanceFromRoot, __global int* out_distanceFromRoot, int numInternalNodes)\n" + "{\n" + " if( get_global_id(0) == 0 ) atomic_xchg(out_maxDistanceFromRoot, 0);\n" + " int internalNodeIndex = get_global_id(0);\n" + " if(internalNodeIndex >= numInternalNodes) return;\n" + " \n" + " //\n" + " int distanceFromRoot = 0;\n" + " {\n" + " int parentIndex = internalNodeParentNodes[internalNodeIndex];\n" + " while(parentIndex != B3_PLBVH_ROOT_NODE_MARKER)\n" + " {\n" + " parentIndex = internalNodeParentNodes[parentIndex];\n" + " ++distanceFromRoot;\n" + " }\n" + " }\n" + " out_distanceFromRoot[internalNodeIndex] = distanceFromRoot;\n" + " \n" + " //\n" + " __local int localMaxDistanceFromRoot;\n" + " if( get_local_id(0) == 0 ) localMaxDistanceFromRoot = 0;\n" + " barrier(CLK_LOCAL_MEM_FENCE);\n" + " \n" + " atomic_max(&localMaxDistanceFromRoot, distanceFromRoot);\n" + " barrier(CLK_LOCAL_MEM_FENCE);\n" + " \n" + " if( get_local_id(0) == 0 ) atomic_max(out_maxDistanceFromRoot, localMaxDistanceFromRoot);\n" + "}\n" + "__kernel void buildBinaryRadixTreeAabbsRecursive(__global int* distanceFromRoot, __global SortDataCL* mortonCodesAndAabbIndices,\n" + " __global int2* childNodes,\n" + " __global b3AabbCL* leafNodeAabbs, __global b3AabbCL* internalNodeAabbs,\n" + " int maxDistanceFromRoot, int processedDistance, int numInternalNodes)\n" + "{\n" + " int internalNodeIndex = get_global_id(0);\n" + " if(internalNodeIndex >= numInternalNodes) return;\n" + " \n" + " int distance = distanceFromRoot[internalNodeIndex];\n" + " \n" + " if(distance == processedDistance)\n" + " {\n" + " int leftChildIndex = childNodes[internalNodeIndex].x;\n" + " int rightChildIndex = childNodes[internalNodeIndex].y;\n" + " \n" + " int isLeftChildLeaf = isLeafNode(leftChildIndex);\n" + " int isRightChildLeaf = isLeafNode(rightChildIndex);\n" + " \n" + " leftChildIndex = getIndexWithInternalNodeMarkerRemoved(leftChildIndex);\n" + " rightChildIndex = getIndexWithInternalNodeMarkerRemoved(rightChildIndex);\n" + " \n" + " //leftRigidIndex/rightRigidIndex is not used if internal node\n" + " int leftRigidIndex = (isLeftChildLeaf) ? mortonCodesAndAabbIndices[leftChildIndex].m_value : -1;\n" + " int rightRigidIndex = (isRightChildLeaf) ? mortonCodesAndAabbIndices[rightChildIndex].m_value : -1;\n" + " \n" + " b3AabbCL leftChildAabb = (isLeftChildLeaf) ? leafNodeAabbs[leftRigidIndex] : internalNodeAabbs[leftChildIndex];\n" + " b3AabbCL rightChildAabb = (isRightChildLeaf) ? leafNodeAabbs[rightRigidIndex] : internalNodeAabbs[rightChildIndex];\n" + " \n" + " b3AabbCL mergedAabb;\n" + " mergedAabb.m_min = b3Min(leftChildAabb.m_min, rightChildAabb.m_min);\n" + " mergedAabb.m_max = b3Max(leftChildAabb.m_max, rightChildAabb.m_max);\n" + " internalNodeAabbs[internalNodeIndex] = mergedAabb;\n" + " }\n" + "}\n" + "__kernel void findLeafIndexRanges(__global int2* internalNodeChildNodes, __global int2* out_leafIndexRanges, int numInternalNodes)\n" + "{\n" + " int internalNodeIndex = get_global_id(0);\n" + " if(internalNodeIndex >= numInternalNodes) return;\n" + " \n" + " int numLeafNodes = numInternalNodes + 1;\n" + " \n" + " int2 childNodes = internalNodeChildNodes[internalNodeIndex];\n" + " \n" + " int2 leafIndexRange; //x == min leaf index, y == max leaf index\n" + " \n" + " //Find lowest leaf index covered by this internal node\n" + " {\n" + " int lowestIndex = childNodes.x; //childNodes.x == Left child\n" + " while( !isLeafNode(lowestIndex) ) lowestIndex = internalNodeChildNodes[ getIndexWithInternalNodeMarkerRemoved(lowestIndex) ].x;\n" + " leafIndexRange.x = lowestIndex;\n" + " }\n" + " \n" + " //Find highest leaf index covered by this internal node\n" + " {\n" + " int highestIndex = childNodes.y; //childNodes.y == Right child\n" + " while( !isLeafNode(highestIndex) ) highestIndex = internalNodeChildNodes[ getIndexWithInternalNodeMarkerRemoved(highestIndex) ].y;\n" + " leafIndexRange.y = highestIndex;\n" + " }\n" + " \n" + " //\n" + " out_leafIndexRanges[internalNodeIndex] = leafIndexRange;\n" + "}\n"; diff --git a/src/Bullet3OpenCL/BroadphaseCollision/kernels/sapKernels.h b/src/Bullet3OpenCL/BroadphaseCollision/kernels/sapKernels.h index 04d40fcf2..d6999b94c 100644 --- a/src/Bullet3OpenCL/BroadphaseCollision/kernels/sapKernels.h +++ b/src/Bullet3OpenCL/BroadphaseCollision/kernels/sapKernels.h @@ -1,342 +1,341 @@ //this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project -static const char* sapCL= \ -"/*\n" -"Copyright (c) 2012 Advanced Micro Devices, Inc. \n" -"This software is provided 'as-is', without any express or implied warranty.\n" -"In no event will the authors be held liable for any damages arising from the use of this software.\n" -"Permission is granted to anyone to use this software for any purpose, \n" -"including commercial applications, and to alter it and redistribute it freely, \n" -"subject to the following restrictions:\n" -"1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" -"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" -"3. This notice may not be removed or altered from any source distribution.\n" -"*/\n" -"//Originally written by Erwin Coumans\n" -"#define NEW_PAIR_MARKER -1\n" -"typedef struct \n" -"{\n" -" union\n" -" {\n" -" float4 m_min;\n" -" float m_minElems[4];\n" -" int m_minIndices[4];\n" -" };\n" -" union\n" -" {\n" -" float4 m_max;\n" -" float m_maxElems[4];\n" -" int m_maxIndices[4];\n" -" };\n" -"} btAabbCL;\n" -"/// conservative test for overlap between two aabbs\n" -"bool TestAabbAgainstAabb2(const btAabbCL* aabb1, __local const btAabbCL* aabb2);\n" -"bool TestAabbAgainstAabb2(const btAabbCL* aabb1, __local const btAabbCL* aabb2)\n" -"{\n" -" bool overlap = true;\n" -" overlap = (aabb1->m_min.x > aabb2->m_max.x || aabb1->m_max.x < aabb2->m_min.x) ? false : overlap;\n" -" overlap = (aabb1->m_min.z > aabb2->m_max.z || aabb1->m_max.z < aabb2->m_min.z) ? false : overlap;\n" -" overlap = (aabb1->m_min.y > aabb2->m_max.y || aabb1->m_max.y < aabb2->m_min.y) ? false : overlap;\n" -" return overlap;\n" -"}\n" -"bool TestAabbAgainstAabb2GlobalGlobal(__global const btAabbCL* aabb1, __global const btAabbCL* aabb2);\n" -"bool TestAabbAgainstAabb2GlobalGlobal(__global const btAabbCL* aabb1, __global const btAabbCL* aabb2)\n" -"{\n" -" bool overlap = true;\n" -" overlap = (aabb1->m_min.x > aabb2->m_max.x || aabb1->m_max.x < aabb2->m_min.x) ? false : overlap;\n" -" overlap = (aabb1->m_min.z > aabb2->m_max.z || aabb1->m_max.z < aabb2->m_min.z) ? false : overlap;\n" -" overlap = (aabb1->m_min.y > aabb2->m_max.y || aabb1->m_max.y < aabb2->m_min.y) ? false : overlap;\n" -" return overlap;\n" -"}\n" -"bool TestAabbAgainstAabb2Global(const btAabbCL* aabb1, __global const btAabbCL* aabb2);\n" -"bool TestAabbAgainstAabb2Global(const btAabbCL* aabb1, __global const btAabbCL* aabb2)\n" -"{\n" -" bool overlap = true;\n" -" overlap = (aabb1->m_min.x > aabb2->m_max.x || aabb1->m_max.x < aabb2->m_min.x) ? false : overlap;\n" -" overlap = (aabb1->m_min.z > aabb2->m_max.z || aabb1->m_max.z < aabb2->m_min.z) ? false : overlap;\n" -" overlap = (aabb1->m_min.y > aabb2->m_max.y || aabb1->m_max.y < aabb2->m_min.y) ? false : overlap;\n" -" return overlap;\n" -"}\n" -"__kernel void computePairsKernelTwoArrays( __global const btAabbCL* unsortedAabbs, __global const int* unsortedAabbMapping, __global const int* unsortedAabbMapping2, volatile __global int4* pairsOut,volatile __global int* pairCount, int numUnsortedAabbs, int numUnSortedAabbs2, int axis, int maxPairs)\n" -"{\n" -" int i = get_global_id(0);\n" -" if (i>=numUnsortedAabbs)\n" -" return;\n" -" int j = get_global_id(1);\n" -" if (j>=numUnSortedAabbs2)\n" -" return;\n" -" __global const btAabbCL* unsortedAabbPtr = &unsortedAabbs[unsortedAabbMapping[i]];\n" -" __global const btAabbCL* unsortedAabbPtr2 = &unsortedAabbs[unsortedAabbMapping2[j]];\n" -" if (TestAabbAgainstAabb2GlobalGlobal(unsortedAabbPtr,unsortedAabbPtr2))\n" -" {\n" -" int4 myPair;\n" -" \n" -" int xIndex = unsortedAabbPtr[0].m_minIndices[3];\n" -" int yIndex = unsortedAabbPtr2[0].m_minIndices[3];\n" -" if (xIndex>yIndex)\n" -" {\n" -" int tmp = xIndex;\n" -" xIndex=yIndex;\n" -" yIndex=tmp;\n" -" }\n" -" \n" -" myPair.x = xIndex;\n" -" myPair.y = yIndex;\n" -" myPair.z = NEW_PAIR_MARKER;\n" -" myPair.w = NEW_PAIR_MARKER;\n" -" int curPair = atomic_inc (pairCount);\n" -" if (curPair=numObjects)\n" -" return;\n" -" for (int j=i+1;j=numObjects)\n" -" return;\n" -" for (int j=i+1;j=numObjects && !localBreak)\n" -" {\n" -" atomic_inc(breakRequest);\n" -" localBreak = 1;\n" -" }\n" -" barrier(CLK_LOCAL_MEM_FENCE);\n" -" \n" -" if (!localBreak)\n" -" {\n" -" if (TestAabbAgainstAabb2GlobalGlobal(&aabbs[i],&aabbs[j]))\n" -" {\n" -" int4 myPair;\n" -" myPair.x = aabbs[i].m_minIndices[3];\n" -" myPair.y = aabbs[j].m_minIndices[3];\n" -" myPair.z = NEW_PAIR_MARKER;\n" -" myPair.w = NEW_PAIR_MARKER;\n" -" int curPair = atomic_inc (pairCount);\n" -" if (curPair=numObjects && !localBreak)\n" -" {\n" -" atomic_inc(breakRequest);\n" -" localBreak = 1;\n" -" }\n" -" barrier(CLK_LOCAL_MEM_FENCE);\n" -" \n" -" if (!localBreak)\n" -" {\n" -" if (TestAabbAgainstAabb2(&myAabb,&localAabbs[localCount+localId+1]))\n" -" {\n" -" int4 myPair;\n" -" myPair.x = myAabb.m_minIndices[3];\n" -" myPair.y = localAabbs[localCount+localId+1].m_minIndices[3];\n" -" myPair.z = NEW_PAIR_MARKER;\n" -" myPair.w = NEW_PAIR_MARKER;\n" -" int curPair = atomic_inc (pairCount);\n" -" if (curPair> 31) | 0x80000000;\n" -" return f ^ mask;\n" -"}\n" -"float IFloatFlip(unsigned int f);\n" -"float IFloatFlip(unsigned int f)\n" -"{\n" -" unsigned int mask = ((f >> 31) - 1) | 0x80000000;\n" -" unsigned int fl = f ^ mask;\n" -" return *(float*)&fl;\n" -"}\n" -"__kernel void copyAabbsKernel( __global const btAabbCL* allAabbs, __global btAabbCL* destAabbs, int numObjects)\n" -"{\n" -" int i = get_global_id(0);\n" -" if (i>=numObjects)\n" -" return;\n" -" int src = destAabbs[i].m_maxIndices[3];\n" -" destAabbs[i] = allAabbs[src];\n" -" destAabbs[i].m_maxIndices[3] = src;\n" -"}\n" -"__kernel void flipFloatKernel( __global const btAabbCL* allAabbs, __global const int* smallAabbMapping, __global int2* sortData, int numObjects, int axis)\n" -"{\n" -" int i = get_global_id(0);\n" -" if (i>=numObjects)\n" -" return;\n" -" \n" -" \n" -" sortData[i].x = FloatFlip(allAabbs[smallAabbMapping[i]].m_minElems[axis]);\n" -" sortData[i].y = i;\n" -" \n" -"}\n" -"__kernel void scatterKernel( __global const btAabbCL* allAabbs, __global const int* smallAabbMapping, volatile __global const int2* sortData, __global btAabbCL* sortedAabbs, int numObjects)\n" -"{\n" -" int i = get_global_id(0);\n" -" if (i>=numObjects)\n" -" return;\n" -" \n" -" sortedAabbs[i] = allAabbs[smallAabbMapping[sortData[i].y]];\n" -"}\n" -"__kernel void prepareSumVarianceKernel( __global const btAabbCL* allAabbs, __global const int* smallAabbMapping, __global float4* sum, __global float4* sum2,int numAabbs)\n" -"{\n" -" int i = get_global_id(0);\n" -" if (i>=numAabbs)\n" -" return;\n" -" \n" -" btAabbCL smallAabb = allAabbs[smallAabbMapping[i]];\n" -" \n" -" float4 s;\n" -" s = (smallAabb.m_max+smallAabb.m_min)*0.5f;\n" -" sum[i]=s;\n" -" sum2[i]=s*s; \n" -"}\n" -; +static const char* sapCL = + "/*\n" + "Copyright (c) 2012 Advanced Micro Devices, Inc. \n" + "This software is provided 'as-is', without any express or implied warranty.\n" + "In no event will the authors be held liable for any damages arising from the use of this software.\n" + "Permission is granted to anyone to use this software for any purpose, \n" + "including commercial applications, and to alter it and redistribute it freely, \n" + "subject to the following restrictions:\n" + "1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" + "2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" + "3. This notice may not be removed or altered from any source distribution.\n" + "*/\n" + "//Originally written by Erwin Coumans\n" + "#define NEW_PAIR_MARKER -1\n" + "typedef struct \n" + "{\n" + " union\n" + " {\n" + " float4 m_min;\n" + " float m_minElems[4];\n" + " int m_minIndices[4];\n" + " };\n" + " union\n" + " {\n" + " float4 m_max;\n" + " float m_maxElems[4];\n" + " int m_maxIndices[4];\n" + " };\n" + "} btAabbCL;\n" + "/// conservative test for overlap between two aabbs\n" + "bool TestAabbAgainstAabb2(const btAabbCL* aabb1, __local const btAabbCL* aabb2);\n" + "bool TestAabbAgainstAabb2(const btAabbCL* aabb1, __local const btAabbCL* aabb2)\n" + "{\n" + " bool overlap = true;\n" + " overlap = (aabb1->m_min.x > aabb2->m_max.x || aabb1->m_max.x < aabb2->m_min.x) ? false : overlap;\n" + " overlap = (aabb1->m_min.z > aabb2->m_max.z || aabb1->m_max.z < aabb2->m_min.z) ? false : overlap;\n" + " overlap = (aabb1->m_min.y > aabb2->m_max.y || aabb1->m_max.y < aabb2->m_min.y) ? false : overlap;\n" + " return overlap;\n" + "}\n" + "bool TestAabbAgainstAabb2GlobalGlobal(__global const btAabbCL* aabb1, __global const btAabbCL* aabb2);\n" + "bool TestAabbAgainstAabb2GlobalGlobal(__global const btAabbCL* aabb1, __global const btAabbCL* aabb2)\n" + "{\n" + " bool overlap = true;\n" + " overlap = (aabb1->m_min.x > aabb2->m_max.x || aabb1->m_max.x < aabb2->m_min.x) ? false : overlap;\n" + " overlap = (aabb1->m_min.z > aabb2->m_max.z || aabb1->m_max.z < aabb2->m_min.z) ? false : overlap;\n" + " overlap = (aabb1->m_min.y > aabb2->m_max.y || aabb1->m_max.y < aabb2->m_min.y) ? false : overlap;\n" + " return overlap;\n" + "}\n" + "bool TestAabbAgainstAabb2Global(const btAabbCL* aabb1, __global const btAabbCL* aabb2);\n" + "bool TestAabbAgainstAabb2Global(const btAabbCL* aabb1, __global const btAabbCL* aabb2)\n" + "{\n" + " bool overlap = true;\n" + " overlap = (aabb1->m_min.x > aabb2->m_max.x || aabb1->m_max.x < aabb2->m_min.x) ? false : overlap;\n" + " overlap = (aabb1->m_min.z > aabb2->m_max.z || aabb1->m_max.z < aabb2->m_min.z) ? false : overlap;\n" + " overlap = (aabb1->m_min.y > aabb2->m_max.y || aabb1->m_max.y < aabb2->m_min.y) ? false : overlap;\n" + " return overlap;\n" + "}\n" + "__kernel void computePairsKernelTwoArrays( __global const btAabbCL* unsortedAabbs, __global const int* unsortedAabbMapping, __global const int* unsortedAabbMapping2, volatile __global int4* pairsOut,volatile __global int* pairCount, int numUnsortedAabbs, int numUnSortedAabbs2, int axis, int maxPairs)\n" + "{\n" + " int i = get_global_id(0);\n" + " if (i>=numUnsortedAabbs)\n" + " return;\n" + " int j = get_global_id(1);\n" + " if (j>=numUnSortedAabbs2)\n" + " return;\n" + " __global const btAabbCL* unsortedAabbPtr = &unsortedAabbs[unsortedAabbMapping[i]];\n" + " __global const btAabbCL* unsortedAabbPtr2 = &unsortedAabbs[unsortedAabbMapping2[j]];\n" + " if (TestAabbAgainstAabb2GlobalGlobal(unsortedAabbPtr,unsortedAabbPtr2))\n" + " {\n" + " int4 myPair;\n" + " \n" + " int xIndex = unsortedAabbPtr[0].m_minIndices[3];\n" + " int yIndex = unsortedAabbPtr2[0].m_minIndices[3];\n" + " if (xIndex>yIndex)\n" + " {\n" + " int tmp = xIndex;\n" + " xIndex=yIndex;\n" + " yIndex=tmp;\n" + " }\n" + " \n" + " myPair.x = xIndex;\n" + " myPair.y = yIndex;\n" + " myPair.z = NEW_PAIR_MARKER;\n" + " myPair.w = NEW_PAIR_MARKER;\n" + " int curPair = atomic_inc (pairCount);\n" + " if (curPair=numObjects)\n" + " return;\n" + " for (int j=i+1;j=numObjects)\n" + " return;\n" + " for (int j=i+1;j=numObjects && !localBreak)\n" + " {\n" + " atomic_inc(breakRequest);\n" + " localBreak = 1;\n" + " }\n" + " barrier(CLK_LOCAL_MEM_FENCE);\n" + " \n" + " if (!localBreak)\n" + " {\n" + " if (TestAabbAgainstAabb2GlobalGlobal(&aabbs[i],&aabbs[j]))\n" + " {\n" + " int4 myPair;\n" + " myPair.x = aabbs[i].m_minIndices[3];\n" + " myPair.y = aabbs[j].m_minIndices[3];\n" + " myPair.z = NEW_PAIR_MARKER;\n" + " myPair.w = NEW_PAIR_MARKER;\n" + " int curPair = atomic_inc (pairCount);\n" + " if (curPair=numObjects && !localBreak)\n" + " {\n" + " atomic_inc(breakRequest);\n" + " localBreak = 1;\n" + " }\n" + " barrier(CLK_LOCAL_MEM_FENCE);\n" + " \n" + " if (!localBreak)\n" + " {\n" + " if (TestAabbAgainstAabb2(&myAabb,&localAabbs[localCount+localId+1]))\n" + " {\n" + " int4 myPair;\n" + " myPair.x = myAabb.m_minIndices[3];\n" + " myPair.y = localAabbs[localCount+localId+1].m_minIndices[3];\n" + " myPair.z = NEW_PAIR_MARKER;\n" + " myPair.w = NEW_PAIR_MARKER;\n" + " int curPair = atomic_inc (pairCount);\n" + " if (curPair> 31) | 0x80000000;\n" + " return f ^ mask;\n" + "}\n" + "float IFloatFlip(unsigned int f);\n" + "float IFloatFlip(unsigned int f)\n" + "{\n" + " unsigned int mask = ((f >> 31) - 1) | 0x80000000;\n" + " unsigned int fl = f ^ mask;\n" + " return *(float*)&fl;\n" + "}\n" + "__kernel void copyAabbsKernel( __global const btAabbCL* allAabbs, __global btAabbCL* destAabbs, int numObjects)\n" + "{\n" + " int i = get_global_id(0);\n" + " if (i>=numObjects)\n" + " return;\n" + " int src = destAabbs[i].m_maxIndices[3];\n" + " destAabbs[i] = allAabbs[src];\n" + " destAabbs[i].m_maxIndices[3] = src;\n" + "}\n" + "__kernel void flipFloatKernel( __global const btAabbCL* allAabbs, __global const int* smallAabbMapping, __global int2* sortData, int numObjects, int axis)\n" + "{\n" + " int i = get_global_id(0);\n" + " if (i>=numObjects)\n" + " return;\n" + " \n" + " \n" + " sortData[i].x = FloatFlip(allAabbs[smallAabbMapping[i]].m_minElems[axis]);\n" + " sortData[i].y = i;\n" + " \n" + "}\n" + "__kernel void scatterKernel( __global const btAabbCL* allAabbs, __global const int* smallAabbMapping, volatile __global const int2* sortData, __global btAabbCL* sortedAabbs, int numObjects)\n" + "{\n" + " int i = get_global_id(0);\n" + " if (i>=numObjects)\n" + " return;\n" + " \n" + " sortedAabbs[i] = allAabbs[smallAabbMapping[sortData[i].y]];\n" + "}\n" + "__kernel void prepareSumVarianceKernel( __global const btAabbCL* allAabbs, __global const int* smallAabbMapping, __global float4* sum, __global float4* sum2,int numAabbs)\n" + "{\n" + " int i = get_global_id(0);\n" + " if (i>=numAabbs)\n" + " return;\n" + " \n" + " btAabbCL smallAabb = allAabbs[smallAabbMapping[i]];\n" + " \n" + " float4 s;\n" + " s = (smallAabb.m_max+smallAabb.m_min)*0.5f;\n" + " sum[i]=s;\n" + " sum2[i]=s*s; \n" + "}\n"; diff --git a/src/Bullet3OpenCL/Initialize/b3OpenCLInclude.h b/src/Bullet3OpenCL/Initialize/b3OpenCLInclude.h index e79182d7c..614653826 100644 --- a/src/Bullet3OpenCL/Initialize/b3OpenCLInclude.h +++ b/src/Bullet3OpenCL/Initialize/b3OpenCLInclude.h @@ -17,7 +17,7 @@ subject to the following restrictions: #define B3_OPENCL_INCLUDE_H #ifdef B3_USE_CLEW - #include "clew/clew.h" +#include "clew/clew.h" #else #ifdef __APPLE__ @@ -25,7 +25,7 @@ subject to the following restrictions: #include #else #include -#include //clLogMessagesToStderrAPPLE +#include //clLogMessagesToStderrAPPLE #endif #else #ifdef USE_MINICL @@ -34,15 +34,18 @@ subject to the following restrictions: #include #ifdef _WIN32 #include "CL/cl_gl.h" -#endif //_WIN32 +#endif //_WIN32 #endif -#endif //__APPLE__ -#endif //B3_USE_CLEW +#endif //__APPLE__ +#endif //B3_USE_CLEW #include #include -#define oclCHECKERROR(a, b) if((a)!=(b)) { printf("OCL Error : %d\n", (a)); assert((a) == (b)); } - - -#endif //B3_OPENCL_INCLUDE_H +#define oclCHECKERROR(a, b) \ + if ((a) != (b)) \ + { \ + printf("OCL Error : %d\n", (a)); \ + assert((a) == (b)); \ + } +#endif //B3_OPENCL_INCLUDE_H diff --git a/src/Bullet3OpenCL/Initialize/b3OpenCLUtils.cpp b/src/Bullet3OpenCL/Initialize/b3OpenCLUtils.cpp index 896191c89..fe54ea5ec 100644 --- a/src/Bullet3OpenCL/Initialize/b3OpenCLUtils.cpp +++ b/src/Bullet3OpenCL/Initialize/b3OpenCLUtils.cpp @@ -16,7 +16,6 @@ subject to the following restrictions: //Original author: Roman Ponomarev //Mostly Reimplemented by Erwin Coumans - bool gDebugForceLoadingFromSource = false; bool gDebugSkipLoadingBinary = false; @@ -25,7 +24,7 @@ bool gDebugSkipLoadingBinary = false; #include #ifdef _WIN32 -#pragma warning (disable:4996) +#pragma warning(disable : 4996) #endif #include "b3OpenCLUtils.h" //#include "b3OpenCLInclude.h" @@ -33,7 +32,7 @@ bool gDebugSkipLoadingBinary = false; #include #include -#define B3_MAX_CL_DEVICES 16 //who needs 16 devices? +#define B3_MAX_CL_DEVICES 16 //who needs 16 devices? #ifdef _WIN32 #include @@ -46,53 +45,49 @@ bool gDebugSkipLoadingBinary = false; #endif -static const char* sCachedBinaryPath="cache"; - +static const char* sCachedBinaryPath = "cache"; //Set the preferred platform vendor using the OpenCL SDK static const char* spPlatformVendor = #if defined(CL_PLATFORM_MINI_CL) -"MiniCL, SCEA"; + "MiniCL, SCEA"; #elif defined(CL_PLATFORM_AMD) -"Advanced Micro Devices, Inc."; + "Advanced Micro Devices, Inc."; #elif defined(CL_PLATFORM_NVIDIA) -"NVIDIA Corporation"; + "NVIDIA Corporation"; #elif defined(CL_PLATFORM_INTEL) -"Intel(R) Corporation"; + "Intel(R) Corporation"; #elif defined(B3_USE_CLEW) -"clew (OpenCL Extension Wrangler library)"; + "clew (OpenCL Extension Wrangler library)"; #else -"Unknown Vendor"; + "Unknown Vendor"; #endif #ifndef CL_PLATFORM_MINI_CL #ifdef _WIN32 #ifndef B3_USE_CLEW #include "CL/cl_gl.h" -#endif //B3_USE_CLEW -#endif //_WIN32 +#endif //B3_USE_CLEW +#endif //_WIN32 #endif - -void MyFatalBreakAPPLE( const char * errstr , - const void * private_info , - size_t cb , - void * user_data ) +void MyFatalBreakAPPLE(const char* errstr, + const void* private_info, + size_t cb, + void* user_data) { - + const char* patloc = strstr(errstr, "Warning"); + //find out if it is a warning or error, exit if error - const char* patloc = strstr(errstr, "Warning"); - //find out if it is a warning or error, exit if error - - if (patloc) - { + if (patloc) + { b3Warning("Warning: %s\n", errstr); - } else - { + } + else + { b3Error("Error: %s\n", errstr); - b3Assert(0); - } - + b3Assert(0); + } } #ifdef B3_USE_CLEW @@ -102,30 +97,31 @@ int b3OpenCLUtils_clewInit() int result = -1; #ifdef _WIN32 - const char* cl = "OpenCL.dll"; + const char* cl = "OpenCL.dll"; #elif defined __APPLE__ - const char* cl = "/System/Library/Frameworks/OpenCL.framework/Versions/Current/OpenCL"; -#else//presumable Linux? - //linux (tested on Ubuntu 12.10 with Catalyst 13.4 beta drivers, not that there is no symbolic link from libOpenCL.so - const char* cl = "libOpenCL.so.1"; - result = clewInit(cl); - if (result != CLEW_SUCCESS) - { - cl = "libOpenCL.so"; - } else - { - clewExit(); - } + const char* cl = "/System/Library/Frameworks/OpenCL.framework/Versions/Current/OpenCL"; +#else //presumable Linux? \ + //linux (tested on Ubuntu 12.10 with Catalyst 13.4 beta drivers, not that there is no symbolic link from libOpenCL.so + const char* cl = "libOpenCL.so.1"; + result = clewInit(cl); + if (result != CLEW_SUCCESS) + { + cl = "libOpenCL.so"; + } + else + { + clewExit(); + } #endif - result = clewInit(cl); - if (result!=CLEW_SUCCESS) - { - b3Error("clewInit failed with error code %d\n",result); - } - else - { - b3Printf("clewInit succesfull using %s\n",cl); - } + result = clewInit(cl); + if (result != CLEW_SUCCESS) + { + b3Error("clewInit failed with error code %d\n", result); + } + else + { + b3Printf("clewInit succesfull using %s\n", cl); + } return result; } #endif @@ -136,19 +132,18 @@ int b3OpenCLUtils_getNumPlatforms(cl_int* pErrNum) b3OpenCLUtils_clewInit(); #endif - cl_platform_id pPlatforms[10] = { 0 }; + cl_platform_id pPlatforms[10] = {0}; - cl_uint numPlatforms = 0; - cl_int ciErrNum = clGetPlatformIDs(10, pPlatforms, &numPlatforms); + cl_uint numPlatforms = 0; + cl_int ciErrNum = clGetPlatformIDs(10, pPlatforms, &numPlatforms); //cl_int ciErrNum = clGetPlatformIDs(0, NULL, &numPlatforms); - if(ciErrNum != CL_SUCCESS) + if (ciErrNum != CL_SUCCESS) { - if(pErrNum != NULL) + if (pErrNum != NULL) *pErrNum = ciErrNum; } return numPlatforms; - } const char* b3OpenCLUtils_getSdkVendorName() @@ -164,28 +159,28 @@ void b3OpenCLUtils_setCachePath(const char* path) cl_platform_id b3OpenCLUtils_getPlatform(int platformIndex0, cl_int* pErrNum) { #ifdef B3_USE_CLEW - b3OpenCLUtils_clewInit(); + b3OpenCLUtils_clewInit(); #endif cl_platform_id platform = 0; - unsigned int platformIndex = (unsigned int )platformIndex0; + unsigned int platformIndex = (unsigned int)platformIndex0; cl_uint numPlatforms; cl_int ciErrNum = clGetPlatformIDs(0, NULL, &numPlatforms); - if (platformIndexm_platformVendor,NULL); - oclCHECKERROR(ciErrNum,CL_SUCCESS); - ciErrNum = clGetPlatformInfo( platform,CL_PLATFORM_NAME,B3_MAX_STRING_LENGTH,platformInfo->m_platformName,NULL); - oclCHECKERROR(ciErrNum,CL_SUCCESS); - ciErrNum = clGetPlatformInfo( platform,CL_PLATFORM_VERSION,B3_MAX_STRING_LENGTH,platformInfo->m_platformVersion,NULL); - oclCHECKERROR(ciErrNum,CL_SUCCESS); + ciErrNum = clGetPlatformInfo(platform, CL_PLATFORM_VENDOR, B3_MAX_STRING_LENGTH, platformInfo->m_platformVendor, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + ciErrNum = clGetPlatformInfo(platform, CL_PLATFORM_NAME, B3_MAX_STRING_LENGTH, platformInfo->m_platformName, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); + ciErrNum = clGetPlatformInfo(platform, CL_PLATFORM_VERSION, B3_MAX_STRING_LENGTH, platformInfo->m_platformVersion, NULL); + oclCHECKERROR(ciErrNum, CL_SUCCESS); } -void b3OpenCLUtils_printPlatformInfo( cl_platform_id platform) +void b3OpenCLUtils_printPlatformInfo(cl_platform_id platform) { b3OpenCLPlatformInfo platformInfo; - b3OpenCLUtils::getPlatformInfo (platform, &platformInfo); + b3OpenCLUtils::getPlatformInfo(platform, &platformInfo); b3Printf("Platform info:\n"); - b3Printf(" CL_PLATFORM_VENDOR: \t\t\t%s\n",platformInfo.m_platformVendor); - b3Printf(" CL_PLATFORM_NAME: \t\t\t%s\n",platformInfo.m_platformName); - b3Printf(" CL_PLATFORM_VERSION: \t\t\t%s\n",platformInfo.m_platformVersion); + b3Printf(" CL_PLATFORM_VENDOR: \t\t\t%s\n", platformInfo.m_platformVendor); + b3Printf(" CL_PLATFORM_NAME: \t\t\t%s\n", platformInfo.m_platformName); + b3Printf(" CL_PLATFORM_VERSION: \t\t\t%s\n", platformInfo.m_platformVersion); } - - cl_context b3OpenCLUtils_createContextFromPlatform(cl_platform_id platform, cl_device_type deviceType, cl_int* pErrNum, void* pGLContext, void* pGLDC, int preferredDeviceIndex, int preferredPlatformIndex) { cl_context retContext = 0; - cl_int ciErrNum=0; + cl_int ciErrNum = 0; cl_uint num_entries; cl_device_id devices[B3_MAX_CL_DEVICES]; cl_uint num_devices; @@ -228,7 +221,7 @@ cl_context b3OpenCLUtils_createContextFromPlatform(cl_platform_id platform, cl_d * If we could find our platform, use it. Otherwise pass a NULL and get whatever the * implementation thinks we should be using. */ - cl_context_properties cps[7] = {0,0,0,0,0,0,0}; + cl_context_properties cps[7] = {0, 0, 0, 0, 0, 0, 0}; cps[0] = CL_CONTEXT_PLATFORM; cps[1] = (cl_context_properties)platform; #ifdef _WIN32 @@ -240,25 +233,24 @@ cl_context b3OpenCLUtils_createContextFromPlatform(cl_platform_id platform, cl_d cps[4] = CL_WGL_HDC_KHR; cps[5] = (cl_context_properties)pGLDC; } -#endif //B3_USE_CLEW -#endif //_WIN32 +#endif //B3_USE_CLEW +#endif //_WIN32 num_entries = B3_MAX_CL_DEVICES; - - num_devices=-1; + num_devices = -1; ciErrNum = clGetDeviceIDs( platform, deviceType, - num_entries, - devices, - &num_devices); + num_entries, + devices, + &num_devices); - if (ciErrNum<0) - { - b3Printf("clGetDeviceIDs returned %d\n",ciErrNum); - return 0; - } + if (ciErrNum < 0) + { + b3Printf("clGetDeviceIDs returned %d\n", ciErrNum); + return 0; + } cprops = (NULL == platform) ? NULL : cps; if (!num_devices) @@ -268,32 +260,33 @@ cl_context b3OpenCLUtils_createContextFromPlatform(cl_platform_id platform, cl_d { //search for the GPU that relates to the OpenCL context unsigned int i; - for (i=0;i=0 && (unsigned int)preferredDeviceIndex= 0 && (unsigned int)preferredDeviceIndex < num_devices) { //create a context of the preferred device index - retContext = clCreateContext(cprops,1,&devices[preferredDeviceIndex],NULL,NULL,&ciErrNum); - } else + retContext = clCreateContext(cprops, 1, &devices[preferredDeviceIndex], NULL, NULL, &ciErrNum); + } + else { //create a context of all devices -#if defined (__APPLE__) - retContext = clCreateContext(cprops,num_devices,devices,MyFatalBreakAPPLE,NULL,&ciErrNum); +#if defined(__APPLE__) + retContext = clCreateContext(cprops, num_devices, devices, MyFatalBreakAPPLE, NULL, &ciErrNum); #else - b3Printf("numDevices=%d\n",num_devices); + b3Printf("numDevices=%d\n", num_devices); - retContext = clCreateContext(cprops,num_devices,devices,NULL,NULL,&ciErrNum); + retContext = clCreateContext(cprops, num_devices, devices, NULL, NULL, &ciErrNum); #endif } } - if(pErrNum != NULL) + if (pErrNum != NULL) { *pErrNum = ciErrNum; }; @@ -301,60 +294,58 @@ cl_context b3OpenCLUtils_createContextFromPlatform(cl_platform_id platform, cl_d return retContext; } -cl_context b3OpenCLUtils_createContextFromType(cl_device_type deviceType, cl_int* pErrNum, void* pGLContext, void* pGLDC , int preferredDeviceIndex, int preferredPlatformIndex, cl_platform_id* retPlatformId) +cl_context b3OpenCLUtils_createContextFromType(cl_device_type deviceType, cl_int* pErrNum, void* pGLContext, void* pGLDC, int preferredDeviceIndex, int preferredPlatformIndex, cl_platform_id* retPlatformId) { #ifdef B3_USE_CLEW - b3OpenCLUtils_clewInit(); + b3OpenCLUtils_clewInit(); #endif - cl_uint numPlatforms; cl_context retContext = 0; unsigned int i; cl_int ciErrNum = clGetPlatformIDs(0, NULL, &numPlatforms); - if(ciErrNum != CL_SUCCESS) + if (ciErrNum != CL_SUCCESS) { - if(pErrNum != NULL) *pErrNum = ciErrNum; + if (pErrNum != NULL) *pErrNum = ciErrNum; return NULL; } - if(numPlatforms > 0) + if (numPlatforms > 0) { - cl_platform_id* platforms = (cl_platform_id*) malloc (sizeof(cl_platform_id)*numPlatforms); + cl_platform_id* platforms = (cl_platform_id*)malloc(sizeof(cl_platform_id) * numPlatforms); ciErrNum = clGetPlatformIDs(numPlatforms, platforms, NULL); - if(ciErrNum != CL_SUCCESS) + if (ciErrNum != CL_SUCCESS) { - if(pErrNum != NULL) + if (pErrNum != NULL) *pErrNum = ciErrNum; free(platforms); return NULL; } - - - for ( i = 0; i < numPlatforms; ++i) + for (i = 0; i < numPlatforms; ++i) { char pbuf[128]; - ciErrNum = clGetPlatformInfo( platforms[i], - CL_PLATFORM_VENDOR, - sizeof(pbuf), - pbuf, - NULL); - if(ciErrNum != CL_SUCCESS) + ciErrNum = clGetPlatformInfo(platforms[i], + CL_PLATFORM_VENDOR, + sizeof(pbuf), + pbuf, + NULL); + if (ciErrNum != CL_SUCCESS) { - if(pErrNum != NULL) *pErrNum = ciErrNum; + if (pErrNum != NULL) *pErrNum = ciErrNum; return NULL; } - if (preferredPlatformIndex>=0 && i==preferredPlatformIndex) + if (preferredPlatformIndex >= 0 && i == preferredPlatformIndex) { cl_platform_id tmpPlatform = platforms[0]; platforms[0] = platforms[i]; platforms[i] = tmpPlatform; break; - } else + } + else { - if(!strcmp(pbuf, spPlatformVendor)) + if (!strcmp(pbuf, spPlatformVendor)) { cl_platform_id tmpPlatform = platforms[0]; platforms[0] = platforms[i]; @@ -368,11 +359,11 @@ cl_context b3OpenCLUtils_createContextFromType(cl_device_type deviceType, cl_int cl_platform_id platform = platforms[i]; assert(platform); - retContext = b3OpenCLUtils_createContextFromPlatform(platform,deviceType,pErrNum,pGLContext,pGLDC,preferredDeviceIndex,preferredPlatformIndex); + retContext = b3OpenCLUtils_createContextFromPlatform(platform, deviceType, pErrNum, pGLContext, pGLDC, preferredDeviceIndex, preferredPlatformIndex); if (retContext) { -// printf("OpenCL platform details:\n"); + // printf("OpenCL platform details:\n"); b3OpenCLPlatformInfo platformInfo; b3OpenCLUtils::getPlatformInfo(platform, &platformInfo); @@ -384,12 +375,11 @@ cl_context b3OpenCLUtils_createContextFromType(cl_device_type deviceType, cl_int } } - free (platforms); + free(platforms); } return retContext; } - ////////////////////////////////////////////////////////////////////////////// //! Gets the id of the nth device from the context //! @@ -403,16 +393,17 @@ cl_device_id b3OpenCLUtils_getDevice(cl_context cxMainContext, int deviceIndex) size_t szParmDataBytes; cl_device_id* cdDevices; - cl_device_id device ; + cl_device_id device; // get the list of devices associated with context clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, 0, NULL, &szParmDataBytes); - if( szParmDataBytes / sizeof(cl_device_id) < (unsigned int)deviceIndex ) { + if (szParmDataBytes / sizeof(cl_device_id) < (unsigned int)deviceIndex) + { return (cl_device_id)-1; } - cdDevices = (cl_device_id*) malloc(szParmDataBytes); + cdDevices = (cl_device_id*)malloc(szParmDataBytes); clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, szParmDataBytes, cdDevices, NULL); @@ -427,12 +418,10 @@ int b3OpenCLUtils_getNumDevices(cl_context cxMainContext) size_t szParamDataBytes; int device_count; clGetContextInfo(cxMainContext, CL_CONTEXT_DEVICES, 0, NULL, &szParamDataBytes); - device_count = (int) szParamDataBytes/ sizeof(cl_device_id); + device_count = (int)szParamDataBytes / sizeof(cl_device_id); return device_count; } - - void b3OpenCLUtils::getDeviceInfo(cl_device_id device, b3OpenCLDeviceInfo* info) { // CL_DEVICE_NAME @@ -514,23 +503,22 @@ void b3OpenCLUtils::getDeviceInfo(cl_device_id device, b3OpenCLDeviceInfo* info) clGetDeviceInfo(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE, sizeof(cl_uint), &info->m_vecWidthDouble, NULL); } - void b3OpenCLUtils_printDeviceInfo(cl_device_id device) { b3OpenCLDeviceInfo info; - b3OpenCLUtils::getDeviceInfo(device,&info); + b3OpenCLUtils::getDeviceInfo(device, &info); b3Printf("Device Info:\n"); b3Printf(" CL_DEVICE_NAME: \t\t\t%s\n", info.m_deviceName); b3Printf(" CL_DEVICE_VENDOR: \t\t\t%s\n", info.m_deviceVendor); b3Printf(" CL_DRIVER_VERSION: \t\t\t%s\n", info.m_driverVersion); - if( info.m_deviceType & CL_DEVICE_TYPE_CPU ) + if (info.m_deviceType & CL_DEVICE_TYPE_CPU) b3Printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_CPU"); - if( info.m_deviceType & CL_DEVICE_TYPE_GPU ) + if (info.m_deviceType & CL_DEVICE_TYPE_GPU) b3Printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_GPU"); - if( info.m_deviceType & CL_DEVICE_TYPE_ACCELERATOR ) + if (info.m_deviceType & CL_DEVICE_TYPE_ACCELERATOR) b3Printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_ACCELERATOR"); - if( info.m_deviceType & CL_DEVICE_TYPE_DEFAULT ) + if (info.m_deviceType & CL_DEVICE_TYPE_DEFAULT) b3Printf(" CL_DEVICE_TYPE:\t\t\t%s\n", "CL_DEVICE_TYPE_DEFAULT"); b3Printf(" CL_DEVICE_MAX_COMPUTE_UNITS:\t\t%u\n", info.m_computeUnits); @@ -539,15 +527,15 @@ void b3OpenCLUtils_printDeviceInfo(cl_device_id device) b3Printf(" CL_DEVICE_MAX_WORK_GROUP_SIZE:\t%u\n", info.m_workgroupSize); b3Printf(" CL_DEVICE_MAX_CLOCK_FREQUENCY:\t%u MHz\n", info.m_clockFrequency); b3Printf(" CL_DEVICE_ADDRESS_BITS:\t\t%u\n", info.m_addressBits); - b3Printf(" CL_DEVICE_MAX_MEM_ALLOC_SIZE:\t\t%u MByte\n", (unsigned int)(info.m_maxMemAllocSize/ (1024 * 1024))); - b3Printf(" CL_DEVICE_GLOBAL_MEM_SIZE:\t\t%u MByte\n", (unsigned int)(info.m_globalMemSize/ (1024 * 1024))); - b3Printf(" CL_DEVICE_ERROR_CORRECTION_SUPPORT:\t%s\n", info.m_errorCorrectionSupport== CL_TRUE ? "yes" : "no"); + b3Printf(" CL_DEVICE_MAX_MEM_ALLOC_SIZE:\t\t%u MByte\n", (unsigned int)(info.m_maxMemAllocSize / (1024 * 1024))); + b3Printf(" CL_DEVICE_GLOBAL_MEM_SIZE:\t\t%u MByte\n", (unsigned int)(info.m_globalMemSize / (1024 * 1024))); + b3Printf(" CL_DEVICE_ERROR_CORRECTION_SUPPORT:\t%s\n", info.m_errorCorrectionSupport == CL_TRUE ? "yes" : "no"); b3Printf(" CL_DEVICE_LOCAL_MEM_TYPE:\t\t%s\n", info.m_localMemType == 1 ? "local" : "global"); b3Printf(" CL_DEVICE_LOCAL_MEM_SIZE:\t\t%u KByte\n", (unsigned int)(info.m_localMemSize / 1024)); b3Printf(" CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE:\t%u KByte\n", (unsigned int)(info.m_constantBufferSize / 1024)); - if( info.m_queueProperties & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE ) + if (info.m_queueProperties & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE) b3Printf(" CL_DEVICE_QUEUE_PROPERTIES:\t\t%s\n", "CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE"); - if( info.m_queueProperties & CL_QUEUE_PROFILING_ENABLE ) + if (info.m_queueProperties & CL_QUEUE_PROFILING_ENABLE) b3Printf(" CL_DEVICE_QUEUE_PROPERTIES:\t\t%s\n", "CL_QUEUE_PROFILING_ENABLE"); b3Printf(" CL_DEVICE_IMAGE_SUPPORT:\t\t%u\n", info.m_imageSupport); @@ -562,7 +550,7 @@ void b3OpenCLUtils_printDeviceInfo(cl_device_id device) b3Printf("\t\t\t\t\t3D_MAX_DEPTH\t %u\n", info.m_image3dMaxDepth); if (*info.m_deviceExtensions != 0) { - b3Printf("\n CL_DEVICE_EXTENSIONS:%s\n",info.m_deviceExtensions); + b3Printf("\n CL_DEVICE_EXTENSIONS:%s\n", info.m_deviceExtensions); } else { @@ -570,36 +558,33 @@ void b3OpenCLUtils_printDeviceInfo(cl_device_id device) } b3Printf(" CL_DEVICE_PREFERRED_VECTOR_WIDTH_\t"); b3Printf("CHAR %u, SHORT %u, INT %u,LONG %u, FLOAT %u, DOUBLE %u\n\n\n", - info.m_vecWidthChar, info.m_vecWidthShort, info.m_vecWidthInt, info.m_vecWidthLong,info.m_vecWidthFloat, info.m_vecWidthDouble); - - + info.m_vecWidthChar, info.m_vecWidthShort, info.m_vecWidthInt, info.m_vecWidthLong, info.m_vecWidthFloat, info.m_vecWidthDouble); } - static const char* strip2(const char* name, const char* pattern) { - size_t const patlen = strlen(pattern); - size_t patcnt = 0; - const char * oriptr; - const char * patloc; - // find how many times the pattern occurs in the original string - for (oriptr = name; (patloc = strstr(oriptr, pattern)); oriptr = patloc + patlen) - { + size_t const patlen = strlen(pattern); + size_t patcnt = 0; + const char* oriptr; + const char* patloc; + // find how many times the pattern occurs in the original string + for (oriptr = name; (patloc = strstr(oriptr, pattern)); oriptr = patloc + patlen) + { patcnt++; - } - return oriptr; + } + return oriptr; } -cl_program b3OpenCLUtils_compileCLProgramFromString(cl_context clContext, cl_device_id device, const char* kernelSourceOrg, cl_int* pErrNum, const char* additionalMacrosArg , const char* clFileNameForCaching, bool disableBinaryCaching) +cl_program b3OpenCLUtils_compileCLProgramFromString(cl_context clContext, cl_device_id device, const char* kernelSourceOrg, cl_int* pErrNum, const char* additionalMacrosArg, const char* clFileNameForCaching, bool disableBinaryCaching) { - const char* additionalMacros = additionalMacrosArg?additionalMacrosArg:""; + const char* additionalMacros = additionalMacrosArg ? additionalMacrosArg : ""; if (disableBinaryCaching) { //kernelSourceOrg = 0; } - cl_program m_cpProgram=0; + cl_program m_cpProgram = 0; cl_int status; char binaryFileName[B3_MAX_STRING_LENGTH]; @@ -609,67 +594,64 @@ cl_program b3OpenCLUtils_compileCLProgramFromString(cl_context clContext, cl_dev const char* strippedName; int fileUpToDate = 0; #ifdef _WIN32 - int binaryFileValid=0; -#endif + int binaryFileValid = 0; +#endif if (!disableBinaryCaching && clFileNameForCaching) { clGetDeviceInfo(device, CL_DEVICE_NAME, 256, &deviceName, NULL); clGetDeviceInfo(device, CL_DRIVER_VERSION, 256, &driverVersion, NULL); - - strippedName = strip2(clFileNameForCaching,"\\"); - strippedName = strip2(strippedName,"/"); - + + strippedName = strip2(clFileNameForCaching, "\\"); + strippedName = strip2(strippedName, "/"); + #ifdef _MSC_VER - sprintf_s(binaryFileName,B3_MAX_STRING_LENGTH,"%s/%s.%s.%s.bin",sCachedBinaryPath,strippedName, deviceName,driverVersion ); + sprintf_s(binaryFileName, B3_MAX_STRING_LENGTH, "%s/%s.%s.%s.bin", sCachedBinaryPath, strippedName, deviceName, driverVersion); #else - sprintf(binaryFileName,"%s/%s.%s.%s.bin",sCachedBinaryPath,strippedName, deviceName,driverVersion ); + sprintf(binaryFileName, "%s/%s.%s.%s.bin", sCachedBinaryPath, strippedName, deviceName, driverVersion); #endif } - if (clFileNameForCaching && !(disableBinaryCaching || gDebugSkipLoadingBinary||gDebugForceLoadingFromSource) ) + if (clFileNameForCaching && !(disableBinaryCaching || gDebugSkipLoadingBinary || gDebugForceLoadingFromSource)) { - #ifdef _WIN32 - char* bla=0; - - + char* bla = 0; //printf("searching for %s\n", binaryFileName); - FILETIME modtimeBinary; - CreateDirectoryA(sCachedBinaryPath,0); + CreateDirectoryA(sCachedBinaryPath, 0); { - - HANDLE binaryFileHandle = CreateFileA(binaryFileName,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); - if (binaryFileHandle ==INVALID_HANDLE_VALUE) + HANDLE binaryFileHandle = CreateFileA(binaryFileName, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); + if (binaryFileHandle == INVALID_HANDLE_VALUE) { DWORD errorCode; errorCode = GetLastError(); switch (errorCode) { - case ERROR_FILE_NOT_FOUND: + case ERROR_FILE_NOT_FOUND: { b3Warning("\nCached file not found %s\n", binaryFileName); break; } - case ERROR_PATH_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: { b3Warning("\nCached file path not found %s\n", binaryFileName); break; } - default: + default: { b3Warning("\nFailed reading cached file with errorCode = %d\n", errorCode); } } - } else + } + else { - if (GetFileTime(binaryFileHandle, NULL, NULL, &modtimeBinary)==0) + if (GetFileTime(binaryFileHandle, NULL, NULL, &modtimeBinary) == 0) { DWORD errorCode; errorCode = GetLastError(); b3Warning("\nGetFileTime errorCode = %d\n", errorCode); - } else + } + else { binaryFileValid = 1; } @@ -678,37 +660,35 @@ cl_program b3OpenCLUtils_compileCLProgramFromString(cl_context clContext, cl_dev if (binaryFileValid) { - HANDLE srcFileHandle = CreateFileA(clFileNameForCaching,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); + HANDLE srcFileHandle = CreateFileA(clFileNameForCaching, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); - if (srcFileHandle==INVALID_HANDLE_VALUE) + if (srcFileHandle == INVALID_HANDLE_VALUE) { - const char* prefix[]={"./","../","../../","../../../","../../../../"}; - for (int i=0;(srcFileHandle==INVALID_HANDLE_VALUE) && i<5;i++) + const char* prefix[] = {"./", "../", "../../", "../../../", "../../../../"}; + for (int i = 0; (srcFileHandle == INVALID_HANDLE_VALUE) && i < 5; i++) { char relativeFileName[1024]; - sprintf(relativeFileName,"%s%s",prefix[i],clFileNameForCaching); - srcFileHandle = CreateFileA(relativeFileName,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0); + sprintf(relativeFileName, "%s%s", prefix[i], clFileNameForCaching); + srcFileHandle = CreateFileA(relativeFileName, GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); } - } - - if (srcFileHandle!=INVALID_HANDLE_VALUE) + if (srcFileHandle != INVALID_HANDLE_VALUE) { FILETIME modtimeSrc; - if (GetFileTime(srcFileHandle, NULL, NULL, &modtimeSrc)==0) + if (GetFileTime(srcFileHandle, NULL, NULL, &modtimeSrc) == 0) { DWORD errorCode; errorCode = GetLastError(); b3Warning("\nGetFileTime errorCode = %d\n", errorCode); } - if ( ( modtimeSrc.dwHighDateTime < modtimeBinary.dwHighDateTime) - ||(( modtimeSrc.dwHighDateTime == modtimeBinary.dwHighDateTime)&&(modtimeSrc.dwLowDateTime <= modtimeBinary.dwLowDateTime))) + if ((modtimeSrc.dwHighDateTime < modtimeBinary.dwHighDateTime) || ((modtimeSrc.dwHighDateTime == modtimeBinary.dwHighDateTime) && (modtimeSrc.dwLowDateTime <= modtimeBinary.dwLowDateTime))) { - fileUpToDate=1; - } else + fileUpToDate = 1; + } + else { - b3Warning("\nCached binary file out-of-date (%s)\n",binaryFileName); + b3Warning("\nCached binary file out-of-date (%s)\n", binaryFileName); } CloseHandle(srcFileHandle); } @@ -719,25 +699,25 @@ cl_program b3OpenCLUtils_compileCLProgramFromString(cl_context clContext, cl_dev errorCode = GetLastError(); switch (errorCode) { - case ERROR_FILE_NOT_FOUND: + case ERROR_FILE_NOT_FOUND: { b3Warning("\nSrc file not found %s\n", clFileNameForCaching); break; } - case ERROR_PATH_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: { b3Warning("\nSrc path not found %s\n", clFileNameForCaching); break; } - default: + default: { b3Warning("\nnSrc file reading errorCode = %d\n", errorCode); } } //we should make sure the src file exists so we can verify the timestamp with binary -// assert(0); - b3Warning("Warning: cannot find OpenCL kernel %s to verify timestamp of binary cached kernel %s\n",clFileNameForCaching, binaryFileName); + // assert(0); + b3Warning("Warning: cannot find OpenCL kernel %s to verify timestamp of binary cached kernel %s\n", clFileNameForCaching, binaryFileName); fileUpToDate = true; #else //if we cannot find the source, assume it is OK in release builds @@ -745,126 +725,109 @@ cl_program b3OpenCLUtils_compileCLProgramFromString(cl_context clContext, cl_dev #endif } } - - } - - #else - fileUpToDate = true; - if (mkdir(sCachedBinaryPath,0777) == -1) - { + fileUpToDate = true; + if (mkdir(sCachedBinaryPath, 0777) == -1) + { + } + else + { + b3Printf("Succesfully created cache directory: %s\n", sCachedBinaryPath); + } +#endif //_WIN32 } - else - { - b3Printf("Succesfully created cache directory: %s\n", sCachedBinaryPath); - } -#endif //_WIN32 - } - - - if( fileUpToDate) + + if (fileUpToDate) { #ifdef _MSC_VER FILE* file; - if (fopen_s(&file,binaryFileName, "rb")!=0) - file=0; + if (fopen_s(&file, binaryFileName, "rb") != 0) + file = 0; #else FILE* file = fopen(binaryFileName, "rb"); #endif - + if (file) { - size_t binarySize=0; - char* binary =0; - - fseek( file, 0L, SEEK_END ); - binarySize = ftell( file ); - rewind( file ); - binary = (char*)malloc(sizeof(char)*binarySize); + size_t binarySize = 0; + char* binary = 0; + + fseek(file, 0L, SEEK_END); + binarySize = ftell(file); + rewind(file); + binary = (char*)malloc(sizeof(char) * binarySize); int bytesRead; - bytesRead = fread( binary, sizeof(char), binarySize, file ); - fclose( file ); - - m_cpProgram = clCreateProgramWithBinary( clContext, 1,&device, &binarySize, (const unsigned char**)&binary, 0, &status ); - b3Assert( status == CL_SUCCESS ); - status = clBuildProgram( m_cpProgram, 1, &device, additionalMacros, 0, 0 ); - b3Assert( status == CL_SUCCESS ); - - if( status != CL_SUCCESS ) + bytesRead = fread(binary, sizeof(char), binarySize, file); + fclose(file); + + m_cpProgram = clCreateProgramWithBinary(clContext, 1, &device, &binarySize, (const unsigned char**)&binary, 0, &status); + b3Assert(status == CL_SUCCESS); + status = clBuildProgram(m_cpProgram, 1, &device, additionalMacros, 0, 0); + b3Assert(status == CL_SUCCESS); + + if (status != CL_SUCCESS) { - char *build_log; + char* build_log; size_t ret_val_size; clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size); - build_log = (char*)malloc(sizeof(char)*(ret_val_size+1)); + build_log = (char*)malloc(sizeof(char) * (ret_val_size + 1)); clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL); build_log[ret_val_size] = '\0'; b3Error("%s\n", build_log); - free (build_log); + free(build_log); b3Assert(0); m_cpProgram = 0; - b3Warning("clBuildProgram reported failure on cached binary: %s\n",binaryFileName); - - } else - { - b3Printf("clBuildProgram successfully compiled cached binary: %s\n",binaryFileName); + b3Warning("clBuildProgram reported failure on cached binary: %s\n", binaryFileName); } - free (binary); - - } else + else + { + b3Printf("clBuildProgram successfully compiled cached binary: %s\n", binaryFileName); + } + free(binary); + } + else { - b3Warning("Cannot open cached binary: %s\n",binaryFileName); + b3Warning("Cannot open cached binary: %s\n", binaryFileName); } } - - - - - - - - - + if (!m_cpProgram) { - cl_int localErrNum; char* compileFlags; int flagsize; - - const char* kernelSource = kernelSourceOrg; if (!kernelSourceOrg || gDebugForceLoadingFromSource) { if (clFileNameForCaching) { - FILE* file = fopen(clFileNameForCaching, "rb"); //in many cases the relative path is a few levels up the directory hierarchy, so try it if (!file) { - const char* prefix[]={"../","../../","../../../","../../../../"}; - for (int i=0;!file && i<3;i++) + const char* prefix[] = {"../", "../../", "../../../", "../../../../"}; + for (int i = 0; !file && i < 3; i++) { char relativeFileName[1024]; - sprintf(relativeFileName,"%s%s",prefix[i],clFileNameForCaching); + sprintf(relativeFileName, "%s%s", prefix[i], clFileNameForCaching); file = fopen(relativeFileName, "rb"); } } if (file) { - char* kernelSrc=0; - fseek( file, 0L, SEEK_END ); - int kernelSize = ftell( file ); - rewind( file ); - kernelSrc = (char*)malloc(kernelSize+1); + char* kernelSrc = 0; + fseek(file, 0L, SEEK_END); + int kernelSize = ftell(file); + rewind(file); + kernelSrc = (char*)malloc(kernelSize + 1); int readBytes; - readBytes = fread((void*)kernelSrc,1,kernelSize, file); + readBytes = fread((void*)kernelSrc, 1, kernelSize, file); kernelSrc[kernelSize] = 0; fclose(file); kernelSource = kernelSrc; @@ -873,15 +836,14 @@ cl_program b3OpenCLUtils_compileCLProgramFromString(cl_context clContext, cl_dev } size_t program_length = kernelSource ? strlen(kernelSource) : 0; -#ifdef MAC //or __APPLE__? +#ifdef MAC //or __APPLE__? char* flags = "-cl-mad-enable -DMAC "; #else const char* flags = ""; #endif - m_cpProgram = clCreateProgramWithSource(clContext, 1, (const char**)&kernelSource, &program_length, &localErrNum); - if (localErrNum!= CL_SUCCESS) + if (localErrNum != CL_SUCCESS) { if (pErrNum) *pErrNum = localErrNum; @@ -890,108 +852,100 @@ cl_program b3OpenCLUtils_compileCLProgramFromString(cl_context clContext, cl_dev // Build the program with 'mad' Optimization option - - - flagsize = sizeof(char)*(strlen(additionalMacros) + strlen(flags) + 5); - compileFlags = (char*) malloc(flagsize); + flagsize = sizeof(char) * (strlen(additionalMacros) + strlen(flags) + 5); + compileFlags = (char*)malloc(flagsize); #ifdef _MSC_VER - sprintf_s(compileFlags,flagsize, "%s %s", flags, additionalMacros); + sprintf_s(compileFlags, flagsize, "%s %s", flags, additionalMacros); #else sprintf(compileFlags, "%s %s", flags, additionalMacros); #endif localErrNum = clBuildProgram(m_cpProgram, 1, &device, compileFlags, NULL, NULL); - if (localErrNum!= CL_SUCCESS) + if (localErrNum != CL_SUCCESS) { - char *build_log; + char* build_log; size_t ret_val_size; clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &ret_val_size); - build_log = (char*) malloc(sizeof(char)*(ret_val_size+1)); + build_log = (char*)malloc(sizeof(char) * (ret_val_size + 1)); clGetProgramBuildInfo(m_cpProgram, device, CL_PROGRAM_BUILD_LOG, ret_val_size, build_log, NULL); // to be carefully, terminate with \0 // there's no information in the reference whether the string is 0 terminated or not build_log[ret_val_size] = '\0'; - b3Error("Error in clBuildProgram, Line %u in file %s, Log: \n%s\n !!!\n\n", __LINE__, __FILE__, build_log); - free (build_log); + free(build_log); if (pErrNum) *pErrNum = localErrNum; return 0; } - - if( !disableBinaryCaching && clFileNameForCaching ) - { // write to binary + if (!disableBinaryCaching && clFileNameForCaching) + { // write to binary cl_uint numAssociatedDevices; - status = clGetProgramInfo( m_cpProgram, CL_PROGRAM_NUM_DEVICES, sizeof(cl_uint), &numAssociatedDevices, 0 ); - b3Assert( status == CL_SUCCESS ); - if (numAssociatedDevices==1) + status = clGetProgramInfo(m_cpProgram, CL_PROGRAM_NUM_DEVICES, sizeof(cl_uint), &numAssociatedDevices, 0); + b3Assert(status == CL_SUCCESS); + if (numAssociatedDevices == 1) { - size_t binarySize; - char* binary ; + char* binary; - status = clGetProgramInfo( m_cpProgram, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &binarySize, 0 ); - b3Assert( status == CL_SUCCESS ); + status = clGetProgramInfo(m_cpProgram, CL_PROGRAM_BINARY_SIZES, sizeof(size_t), &binarySize, 0); + b3Assert(status == CL_SUCCESS); - binary = (char*)malloc(sizeof(char)*binarySize); + binary = (char*)malloc(sizeof(char) * binarySize); - status = clGetProgramInfo( m_cpProgram, CL_PROGRAM_BINARIES, sizeof(char*), &binary, 0 ); - b3Assert( status == CL_SUCCESS ); + status = clGetProgramInfo(m_cpProgram, CL_PROGRAM_BINARIES, sizeof(char*), &binary, 0); + b3Assert(status == CL_SUCCESS); { - FILE* file=0; + FILE* file = 0; #ifdef _MSC_VER - if (fopen_s(&file,binaryFileName, "wb")!=0) - file=0; + if (fopen_s(&file, binaryFileName, "wb") != 0) + file = 0; #else file = fopen(binaryFileName, "wb"); #endif if (file) { - fwrite( binary, sizeof(char), binarySize, file ); - fclose( file ); - } else + fwrite(binary, sizeof(char), binarySize, file); + fclose(file); + } + else { b3Warning("cannot write file %s\n", binaryFileName); } } - free (binary); + free(binary); } } free(compileFlags); - } return m_cpProgram; } - -cl_kernel b3OpenCLUtils_compileCLKernelFromString(cl_context clContext, cl_device_id device, const char* kernelSource, const char* kernelName, cl_int* pErrNum, cl_program prog, const char* additionalMacros ) +cl_kernel b3OpenCLUtils_compileCLKernelFromString(cl_context clContext, cl_device_id device, const char* kernelSource, const char* kernelName, cl_int* pErrNum, cl_program prog, const char* additionalMacros) { - cl_kernel kernel; cl_int localErrNum; cl_program m_cpProgram = prog; - b3Printf("compiling kernel %s ",kernelName); + b3Printf("compiling kernel %s ", kernelName); if (!m_cpProgram) { - m_cpProgram = b3OpenCLUtils_compileCLProgramFromString(clContext,device,kernelSource,pErrNum, additionalMacros,0, false); + m_cpProgram = b3OpenCLUtils_compileCLProgramFromString(clContext, device, kernelSource, pErrNum, additionalMacros, 0, false); } - // Create the kernel kernel = clCreateKernel(m_cpProgram, kernelName, &localErrNum); if (localErrNum != CL_SUCCESS) { b3Error("Error in clCreateKernel, Line %u in file %s, cannot find kernel function %s !!!\n\n", __LINE__, __FILE__, kernelName); - assert(0); + assert(0); if (pErrNum) *pErrNum = localErrNum; return 0; @@ -1003,9 +957,7 @@ cl_kernel b3OpenCLUtils_compileCLKernelFromString(cl_context clContext, cl_devic } b3Printf("ready. \n"); - if (pErrNum) - *pErrNum = CL_SUCCESS; + *pErrNum = CL_SUCCESS; return kernel; - } diff --git a/src/Bullet3OpenCL/Initialize/b3OpenCLUtils.h b/src/Bullet3OpenCL/Initialize/b3OpenCLUtils.h index db6466e76..6c82eed2a 100644 --- a/src/Bullet3OpenCL/Initialize/b3OpenCLUtils.h +++ b/src/Bullet3OpenCL/Initialize/b3OpenCLUtils.h @@ -22,42 +22,41 @@ subject to the following restrictions: #include "b3OpenCLInclude.h" #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif + ///C API for OpenCL utilities: convenience functions, see below for C++ API -///C API for OpenCL utilities: convenience functions, see below for C++ API + /// CL Context optionally takes a GL context. This is a generic type because we don't really want this code + /// to have to understand GL types. It is a HGLRC in _WIN32 or a GLXContext otherwise. + cl_context b3OpenCLUtils_createContextFromType(cl_device_type deviceType, cl_int* pErrNum, void* pGLCtx, void* pGLDC, int preferredDeviceIndex, int preferredPlatformIndex, cl_platform_id* platformId); -/// CL Context optionally takes a GL context. This is a generic type because we don't really want this code -/// to have to understand GL types. It is a HGLRC in _WIN32 or a GLXContext otherwise. -cl_context b3OpenCLUtils_createContextFromType(cl_device_type deviceType, cl_int* pErrNum, void* pGLCtx , void* pGLDC , int preferredDeviceIndex , int preferredPlatformIndex, cl_platform_id* platformId); - -int b3OpenCLUtils_getNumDevices(cl_context cxMainContext); + int b3OpenCLUtils_getNumDevices(cl_context cxMainContext); -cl_device_id b3OpenCLUtils_getDevice(cl_context cxMainContext, int nr); + cl_device_id b3OpenCLUtils_getDevice(cl_context cxMainContext, int nr); -void b3OpenCLUtils_printDeviceInfo(cl_device_id device); + void b3OpenCLUtils_printDeviceInfo(cl_device_id device); -cl_kernel b3OpenCLUtils_compileCLKernelFromString( cl_context clContext,cl_device_id device, const char* kernelSource, const char* kernelName, cl_int* pErrNum, cl_program prog,const char* additionalMacros); + cl_kernel b3OpenCLUtils_compileCLKernelFromString(cl_context clContext, cl_device_id device, const char* kernelSource, const char* kernelName, cl_int* pErrNum, cl_program prog, const char* additionalMacros); -//optional -cl_program b3OpenCLUtils_compileCLProgramFromString( cl_context clContext,cl_device_id device, const char* kernelSource, cl_int* pErrNum,const char* additionalMacros , const char* srcFileNameForCaching, bool disableBinaryCaching); + //optional + cl_program b3OpenCLUtils_compileCLProgramFromString(cl_context clContext, cl_device_id device, const char* kernelSource, cl_int* pErrNum, const char* additionalMacros, const char* srcFileNameForCaching, bool disableBinaryCaching); -//the following optional APIs provide access using specific platform information -int b3OpenCLUtils_getNumPlatforms(cl_int* pErrNum); + //the following optional APIs provide access using specific platform information + int b3OpenCLUtils_getNumPlatforms(cl_int* pErrNum); -///get the nr'th platform, where nr is in the range [0..getNumPlatforms) -cl_platform_id b3OpenCLUtils_getPlatform(int nr, cl_int* pErrNum); + ///get the nr'th platform, where nr is in the range [0..getNumPlatforms) + cl_platform_id b3OpenCLUtils_getPlatform(int nr, cl_int* pErrNum); + void b3OpenCLUtils_printPlatformInfo(cl_platform_id platform); -void b3OpenCLUtils_printPlatformInfo(cl_platform_id platform); + const char* b3OpenCLUtils_getSdkVendorName(); -const char* b3OpenCLUtils_getSdkVendorName(); - -///set the path (directory/folder) where the compiled OpenCL kernel are stored -void b3OpenCLUtils_setCachePath(const char* path); - -cl_context b3OpenCLUtils_createContextFromPlatform(cl_platform_id platform, cl_device_type deviceType, cl_int* pErrNum, void* pGLCtx , void* pGLDC ,int preferredDeviceIndex , int preferredPlatformIndex); + ///set the path (directory/folder) where the compiled OpenCL kernel are stored + void b3OpenCLUtils_setCachePath(const char* path); + + cl_context b3OpenCLUtils_createContextFromPlatform(cl_platform_id platform, cl_device_type deviceType, cl_int* pErrNum, void* pGLCtx, void* pGLDC, int preferredDeviceIndex, int preferredPlatformIndex); #ifdef __cplusplus } @@ -71,37 +70,35 @@ typedef struct char m_driverVersion[B3_MAX_STRING_LENGTH]; char m_deviceExtensions[B3_MAX_STRING_LENGTH]; - cl_device_type m_deviceType; - cl_uint m_computeUnits; - size_t m_workitemDims; - size_t m_workItemSize[3]; - size_t m_image2dMaxWidth; - size_t m_image2dMaxHeight; - size_t m_image3dMaxWidth; - size_t m_image3dMaxHeight; - size_t m_image3dMaxDepth; - size_t m_workgroupSize; - cl_uint m_clockFrequency; - cl_ulong m_constantBufferSize; - cl_ulong m_localMemSize; - cl_ulong m_globalMemSize; - cl_bool m_errorCorrectionSupport; + cl_device_type m_deviceType; + cl_uint m_computeUnits; + size_t m_workitemDims; + size_t m_workItemSize[3]; + size_t m_image2dMaxWidth; + size_t m_image2dMaxHeight; + size_t m_image3dMaxWidth; + size_t m_image3dMaxHeight; + size_t m_image3dMaxDepth; + size_t m_workgroupSize; + cl_uint m_clockFrequency; + cl_ulong m_constantBufferSize; + cl_ulong m_localMemSize; + cl_ulong m_globalMemSize; + cl_bool m_errorCorrectionSupport; cl_device_local_mem_type m_localMemType; - cl_uint m_maxReadImageArgs; - cl_uint m_maxWriteImageArgs; + cl_uint m_maxReadImageArgs; + cl_uint m_maxWriteImageArgs; - - - cl_uint m_addressBits; - cl_ulong m_maxMemAllocSize; + cl_uint m_addressBits; + cl_ulong m_maxMemAllocSize; cl_command_queue_properties m_queueProperties; - cl_bool m_imageSupport; - cl_uint m_vecWidthChar; - cl_uint m_vecWidthShort; - cl_uint m_vecWidthInt; - cl_uint m_vecWidthLong; - cl_uint m_vecWidthFloat; - cl_uint m_vecWidthDouble; + cl_bool m_imageSupport; + cl_uint m_vecWidthChar; + cl_uint m_vecWidthShort; + cl_uint m_vecWidthInt; + cl_uint m_vecWidthLong; + cl_uint m_vecWidthFloat; + cl_uint m_vecWidthDouble; } b3OpenCLDeviceInfo; @@ -110,33 +107,32 @@ struct b3OpenCLPlatformInfo char m_platformVendor[B3_MAX_STRING_LENGTH]; char m_platformName[B3_MAX_STRING_LENGTH]; char m_platformVersion[B3_MAX_STRING_LENGTH]; - + b3OpenCLPlatformInfo() { - m_platformVendor[0]=0; - m_platformName[0]=0; - m_platformVersion[0]=0; + m_platformVendor[0] = 0; + m_platformName[0] = 0; + m_platformVersion[0] = 0; } }; - ///C++ API for OpenCL utilities: convenience functions struct b3OpenCLUtils { /// CL Context optionally takes a GL context. This is a generic type because we don't really want this code /// to have to understand GL types. It is a HGLRC in _WIN32 or a GLXContext otherwise. - static inline cl_context createContextFromType(cl_device_type deviceType, cl_int* pErrNum, void* pGLCtx = 0, void* pGLDC = 0, int preferredDeviceIndex = -1, int preferredPlatformIndex= - 1, cl_platform_id* platformId=0) + static inline cl_context createContextFromType(cl_device_type deviceType, cl_int* pErrNum, void* pGLCtx = 0, void* pGLDC = 0, int preferredDeviceIndex = -1, int preferredPlatformIndex = -1, cl_platform_id* platformId = 0) { - return b3OpenCLUtils_createContextFromType(deviceType, pErrNum, pGLCtx , pGLDC , preferredDeviceIndex, preferredPlatformIndex, platformId); + return b3OpenCLUtils_createContextFromType(deviceType, pErrNum, pGLCtx, pGLDC, preferredDeviceIndex, preferredPlatformIndex, platformId); } - + static inline int getNumDevices(cl_context cxMainContext) { return b3OpenCLUtils_getNumDevices(cxMainContext); } static inline cl_device_id getDevice(cl_context cxMainContext, int nr) { - return b3OpenCLUtils_getDevice(cxMainContext,nr); + return b3OpenCLUtils_getDevice(cxMainContext, nr); } static void getDeviceInfo(cl_device_id device, b3OpenCLDeviceInfo* info); @@ -146,28 +142,28 @@ struct b3OpenCLUtils b3OpenCLUtils_printDeviceInfo(device); } - static inline cl_kernel compileCLKernelFromString( cl_context clContext,cl_device_id device, const char* kernelSource, const char* kernelName, cl_int* pErrNum=0, cl_program prog=0,const char* additionalMacros = "" ) + static inline cl_kernel compileCLKernelFromString(cl_context clContext, cl_device_id device, const char* kernelSource, const char* kernelName, cl_int* pErrNum = 0, cl_program prog = 0, const char* additionalMacros = "") { - return b3OpenCLUtils_compileCLKernelFromString(clContext,device, kernelSource, kernelName, pErrNum, prog,additionalMacros); + return b3OpenCLUtils_compileCLKernelFromString(clContext, device, kernelSource, kernelName, pErrNum, prog, additionalMacros); } //optional - static inline cl_program compileCLProgramFromString( cl_context clContext,cl_device_id device, const char* kernelSource, cl_int* pErrNum=0,const char* additionalMacros = "" , const char* srcFileNameForCaching=0, bool disableBinaryCaching=false) + static inline cl_program compileCLProgramFromString(cl_context clContext, cl_device_id device, const char* kernelSource, cl_int* pErrNum = 0, const char* additionalMacros = "", const char* srcFileNameForCaching = 0, bool disableBinaryCaching = false) { - return b3OpenCLUtils_compileCLProgramFromString(clContext,device, kernelSource, pErrNum,additionalMacros, srcFileNameForCaching, disableBinaryCaching); + return b3OpenCLUtils_compileCLProgramFromString(clContext, device, kernelSource, pErrNum, additionalMacros, srcFileNameForCaching, disableBinaryCaching); } //the following optional APIs provide access using specific platform information - static inline int getNumPlatforms(cl_int* pErrNum=0) + static inline int getNumPlatforms(cl_int* pErrNum = 0) { return b3OpenCLUtils_getNumPlatforms(pErrNum); } ///get the nr'th platform, where nr is in the range [0..getNumPlatforms) - static inline cl_platform_id getPlatform(int nr, cl_int* pErrNum=0) + static inline cl_platform_id getPlatform(int nr, cl_int* pErrNum = 0) { - return b3OpenCLUtils_getPlatform(nr,pErrNum); + return b3OpenCLUtils_getPlatform(nr, pErrNum); } - + static void getPlatformInfo(cl_platform_id platform, b3OpenCLPlatformInfo* platformInfo); static inline void printPlatformInfo(cl_platform_id platform) @@ -179,9 +175,9 @@ struct b3OpenCLUtils { return b3OpenCLUtils_getSdkVendorName(); } - static inline cl_context createContextFromPlatform(cl_platform_id platform, cl_device_type deviceType, cl_int* pErrNum, void* pGLCtx = 0, void* pGLDC = 0,int preferredDeviceIndex = -1, int preferredPlatformIndex= -1) + static inline cl_context createContextFromPlatform(cl_platform_id platform, cl_device_type deviceType, cl_int* pErrNum, void* pGLCtx = 0, void* pGLDC = 0, int preferredDeviceIndex = -1, int preferredPlatformIndex = -1) { - return b3OpenCLUtils_createContextFromPlatform(platform, deviceType, pErrNum, pGLCtx,pGLDC,preferredDeviceIndex, preferredPlatformIndex); + return b3OpenCLUtils_createContextFromPlatform(platform, deviceType, pErrNum, pGLCtx, pGLDC, preferredDeviceIndex, preferredPlatformIndex); } static void setCachePath(const char* path) { @@ -189,6 +185,6 @@ struct b3OpenCLUtils } }; -#endif //__cplusplus +#endif //__cplusplus -#endif // B3_OPENCL_UTILS_H +#endif // B3_OPENCL_UTILS_H diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3BvhInfo.h b/src/Bullet3OpenCL/NarrowphaseCollision/b3BvhInfo.h index 872f03950..27835bb74 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3BvhInfo.h +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3BvhInfo.h @@ -5,14 +5,13 @@ struct b3BvhInfo { - b3Vector3 m_aabbMin; - b3Vector3 m_aabbMax; - b3Vector3 m_quantization; - int m_numNodes; - int m_numSubTrees; - int m_nodeOffset; - int m_subTreeOffset; - + b3Vector3 m_aabbMin; + b3Vector3 m_aabbMax; + b3Vector3 m_quantization; + int m_numNodes; + int m_numSubTrees; + int m_nodeOffset; + int m_subTreeOffset; }; -#endif //B3_BVH_INFO_H \ No newline at end of file +#endif //B3_BVH_INFO_H \ No newline at end of file diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3ContactCache.cpp b/src/Bullet3OpenCL/NarrowphaseCollision/b3ContactCache.cpp index cb30ee939..4db717f8c 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3ContactCache.cpp +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3ContactCache.cpp @@ -15,7 +15,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "b3ContactCache.h" #include "Bullet3Common/b3Transform.h" @@ -69,7 +68,7 @@ int b3ContactCache::sortCachedPoints(const b3Vector3& pt) maxPenetration = m_pointCache[i].getDistance(); } } -#endif //KEEP_DEEPEST_POINT +#endif //KEEP_DEEPEST_POINT b3Scalar res0(b3Scalar(0.)),res1(b3Scalar(0.)),res2(b3Scalar(0.)),res3(b3Scalar(0.)); @@ -251,8 +250,4 @@ void b3ContactCache::refreshContactPoints(const b3Transform& trA,const b3Transfo } - - - - #endif diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3ContactCache.h b/src/Bullet3OpenCL/NarrowphaseCollision/b3ContactCache.h index d6c9b0a07..a15fd0b2a 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3ContactCache.h +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3ContactCache.h @@ -17,17 +17,13 @@ subject to the following restrictions: #ifndef B3_CONTACT_CACHE_H #define B3_CONTACT_CACHE_H - #include "Bullet3Common/b3Vector3.h" #include "Bullet3Common/b3Transform.h" #include "Bullet3Common/b3AlignedAllocator.h" - ///maximum contact breaking and merging threshold extern b3Scalar gContactBreakingThreshold; - - #define MANIFOLD_CACHE_SIZE 4 ///b3ContactCache is a contact point cache, it stays persistent as long as objects are overlapping in the broadphase. @@ -37,24 +33,16 @@ extern b3Scalar gContactBreakingThreshold; ///reduces the cache to 4 points, when more then 4 points are added, using following rules: ///the contact point with deepest penetration is always kept, and it tries to maximuze the area covered by the points ///note that some pairs of objects might have more then one contact manifold. -B3_ATTRIBUTE_ALIGNED16( class) b3ContactCache +B3_ATTRIBUTE_ALIGNED16(class) +b3ContactCache { - - - - /// sort cached points so most isolated points come first - int sortCachedPoints(const b3Vector3& pt); - - + int sortCachedPoints(const b3Vector3& pt); public: - B3_DECLARE_ALIGNED_ALLOCATOR(); - - - int addManifoldPoint( const b3Vector3& newPoint); + int addManifoldPoint(const b3Vector3& newPoint); /*void replaceContactPoint(const b3Vector3& newPoint,int insertIndex) { @@ -63,18 +51,12 @@ public: } */ - - static bool validContactDistance(const b3Vector3& pt); - + /// calculated new worldspace coordinates and depth, and reject points that exceed the collision margin - static void refreshContactPoints( const b3Transform& trA,const b3Transform& trB, struct b3Contact4Data& newContactCache); - - static void removeContactPoint(struct b3Contact4Data& newContactCache,int i); - + static void refreshContactPoints(const b3Transform& trA, const b3Transform& trB, struct b3Contact4Data& newContactCache); + static void removeContactPoint(struct b3Contact4Data & newContactCache, int i); }; - - -#endif //B3_CONTACT_CACHE_H +#endif //B3_CONTACT_CACHE_H diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3ConvexHullContact.cpp b/src/Bullet3OpenCL/NarrowphaseCollision/b3ConvexHullContact.cpp index fb435aa7f..54a104c5c 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3ConvexHullContact.cpp +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3ConvexHullContact.cpp @@ -16,19 +16,18 @@ subject to the following restrictions: bool findSeparatingAxisOnGpu = true; bool splitSearchSepAxisConcave = false; bool splitSearchSepAxisConvex = true; -bool useMprGpu = true;//use mpr for edge-edge (+contact point) or sat. Needs testing on main OpenCL platforms, before enabling... +bool useMprGpu = true; //use mpr for edge-edge (+contact point) or sat. Needs testing on main OpenCL platforms, before enabling... bool bvhTraversalKernelGPU = true; bool findConcaveSeparatingAxisKernelGPU = true; -bool clipConcaveFacesAndFindContactsCPU = false;//false;//true; -bool clipConvexFacesAndFindContactsCPU = false;//false;//true; -bool reduceConcaveContactsOnGPU = true;//false; -bool reduceConvexContactsOnGPU = true;//false; +bool clipConcaveFacesAndFindContactsCPU = false; //false;//true; +bool clipConvexFacesAndFindContactsCPU = false; //false;//true; +bool reduceConcaveContactsOnGPU = true; //false; +bool reduceConvexContactsOnGPU = true; //false; bool findConvexClippingFacesGPU = true; -bool useGjk = false;///option for CPU/host testing, when findSeparatingAxisOnGpu = false -bool useGjkContacts = false;//////option for CPU/host testing when findSeparatingAxisOnGpu = false +bool useGjk = false; ///option for CPU/host testing, when findSeparatingAxisOnGpu = false +bool useGjkContacts = false; //////option for CPU/host testing when findSeparatingAxisOnGpu = false - -static int myframecount=0;///for testing +static int myframecount = 0; ///for testing ///This file was written by Erwin Coumans ///Separating axis rest based on work from Pierre Terdiman, see @@ -42,10 +41,10 @@ static int myframecount=0;///for testing //#define PERSISTENT_CONTACTS_HOST #endif -int b3g_actualSATPairTests=0; +int b3g_actualSATPairTests = 0; #include "b3ConvexHullContact.h" -#include //memcpy +#include //memcpy #include "Bullet3Collision/NarrowPhaseCollision/shared/b3ConvexPolyhedronData.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3MprPenetration.h" @@ -54,8 +53,7 @@ int b3g_actualSATPairTests=0; typedef b3AlignedObjectArray b3VertexArray; - -#include //for FLT_MAX +#include //for FLT_MAX #include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h" #include "Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h" //#include "AdlQuaternion.h" @@ -69,7 +67,6 @@ typedef b3AlignedObjectArray b3VertexArray; #include "kernels/bvhTraversal.h" #include "kernels/primitiveContacts.h" - #include "Bullet3Geometry/b3AabbUtil.h" #define BT_NARROWPHASE_SAT_PATH "src/Bullet3OpenCL/NarrowphaseCollision/kernels/sat.cl" @@ -77,12 +74,10 @@ typedef b3AlignedObjectArray b3VertexArray; #define BT_NARROWPHASE_MPR_PATH "src/Bullet3OpenCL/NarrowphaseCollision/kernels/mpr.cl" - #define BT_NARROWPHASE_CLIPHULL_PATH "src/Bullet3OpenCL/NarrowphaseCollision/kernels/satClipHullContacts.cl" #define BT_NARROWPHASE_BVH_TRAVERSAL_PATH "src/Bullet3OpenCL/NarrowphaseCollision/kernels/bvhTraversal.cl" #define BT_NARROWPHASE_PRIMITIVE_CONTACT_PATH "src/Bullet3OpenCL/NarrowphaseCollision/kernels/primitiveContacts.cl" - #ifndef __global #define __global #endif @@ -91,204 +86,184 @@ typedef b3AlignedObjectArray b3VertexArray; #define __kernel #endif - #include "Bullet3Collision/NarrowPhaseCollision/shared/b3BvhTraversal.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3FindConcaveSatAxis.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3ClipFaces.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3NewContactReduction.h" - - #define dot3F4 b3Dot -GpuSatCollision::GpuSatCollision(cl_context ctx,cl_device_id device, cl_command_queue q ) -:m_context(ctx), -m_device(device), -m_queue(q), +GpuSatCollision::GpuSatCollision(cl_context ctx, cl_device_id device, cl_command_queue q) + : m_context(ctx), + m_device(device), + m_queue(q), -m_findSeparatingAxisKernel(0), -m_findSeparatingAxisVertexFaceKernel(0), -m_findSeparatingAxisEdgeEdgeKernel(0), -m_unitSphereDirections(m_context,m_queue), + m_findSeparatingAxisKernel(0), + m_findSeparatingAxisVertexFaceKernel(0), + m_findSeparatingAxisEdgeEdgeKernel(0), + m_unitSphereDirections(m_context, m_queue), -m_totalContactsOut(m_context, m_queue), -m_sepNormals(m_context, m_queue), -m_dmins(m_context,m_queue), + m_totalContactsOut(m_context, m_queue), + m_sepNormals(m_context, m_queue), + m_dmins(m_context, m_queue), -m_hasSeparatingNormals(m_context, m_queue), -m_concaveSepNormals(m_context, m_queue), -m_concaveHasSeparatingNormals(m_context,m_queue), -m_numConcavePairsOut(m_context, m_queue), + m_hasSeparatingNormals(m_context, m_queue), + m_concaveSepNormals(m_context, m_queue), + m_concaveHasSeparatingNormals(m_context, m_queue), + m_numConcavePairsOut(m_context, m_queue), + m_gpuCompoundPairs(m_context, m_queue), -m_gpuCompoundPairs(m_context, m_queue), + m_gpuCompoundSepNormals(m_context, m_queue), + m_gpuHasCompoundSepNormals(m_context, m_queue), - -m_gpuCompoundSepNormals(m_context, m_queue), -m_gpuHasCompoundSepNormals(m_context, m_queue), - -m_numCompoundPairsOut(m_context, m_queue) + m_numCompoundPairsOut(m_context, m_queue) { m_totalContactsOut.push_back(0); - - cl_int errNum=0; + + cl_int errNum = 0; if (1) { const char* mprSrc = mprKernelsCL; - + const char* srcConcave = satConcaveKernelsCL; - char flags[1024]={0}; -//#ifdef CL_PLATFORM_INTEL -// sprintf(flags,"-g -s \"%s\"","C:/develop/bullet3_experiments2/opencl/gpu_narrowphase/kernels/sat.cl"); -//#endif - m_mprPenetrationKernel = 0; + char flags[1024] = {0}; + //#ifdef CL_PLATFORM_INTEL + // sprintf(flags,"-g -s \"%s\"","C:/develop/bullet3_experiments2/opencl/gpu_narrowphase/kernels/sat.cl"); + //#endif + m_mprPenetrationKernel = 0; m_findSeparatingAxisUnitSphereKernel = 0; if (useMprGpu) { - cl_program mprProg = b3OpenCLUtils::compileCLProgramFromString(m_context,m_device,mprSrc,&errNum,flags,BT_NARROWPHASE_MPR_PATH); - b3Assert(errNum==CL_SUCCESS); - - m_mprPenetrationKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,mprSrc, "mprPenetrationKernel",&errNum,mprProg ); + cl_program mprProg = b3OpenCLUtils::compileCLProgramFromString(m_context, m_device, mprSrc, &errNum, flags, BT_NARROWPHASE_MPR_PATH); + b3Assert(errNum == CL_SUCCESS); + + m_mprPenetrationKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, mprSrc, "mprPenetrationKernel", &errNum, mprProg); b3Assert(m_mprPenetrationKernel); - b3Assert(errNum==CL_SUCCESS); + b3Assert(errNum == CL_SUCCESS); - m_findSeparatingAxisUnitSphereKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,mprSrc, "findSeparatingAxisUnitSphereKernel",&errNum,mprProg ); + m_findSeparatingAxisUnitSphereKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, mprSrc, "findSeparatingAxisUnitSphereKernel", &errNum, mprProg); b3Assert(m_findSeparatingAxisUnitSphereKernel); - b3Assert(errNum==CL_SUCCESS); + b3Assert(errNum == CL_SUCCESS); - - int numDirections = sizeof(unitSphere162)/sizeof(b3Vector3); + int numDirections = sizeof(unitSphere162) / sizeof(b3Vector3); m_unitSphereDirections.resize(numDirections); - m_unitSphereDirections.copyFromHostPointer(unitSphere162,numDirections,0,true); - - + m_unitSphereDirections.copyFromHostPointer(unitSphere162, numDirections, 0, true); } + cl_program satProg = b3OpenCLUtils::compileCLProgramFromString(m_context, m_device, satKernelsCL, &errNum, flags, BT_NARROWPHASE_SAT_PATH); + b3Assert(errNum == CL_SUCCESS); - cl_program satProg = b3OpenCLUtils::compileCLProgramFromString(m_context,m_device,satKernelsCL,&errNum,flags,BT_NARROWPHASE_SAT_PATH); - b3Assert(errNum==CL_SUCCESS); + cl_program satConcaveProg = b3OpenCLUtils::compileCLProgramFromString(m_context, m_device, srcConcave, &errNum, flags, BT_NARROWPHASE_SAT_CONCAVE_PATH); + b3Assert(errNum == CL_SUCCESS); - cl_program satConcaveProg = b3OpenCLUtils::compileCLProgramFromString(m_context,m_device,srcConcave,&errNum,flags,BT_NARROWPHASE_SAT_CONCAVE_PATH); - b3Assert(errNum==CL_SUCCESS); - - m_findSeparatingAxisKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,satKernelsCL, "findSeparatingAxisKernel",&errNum,satProg ); + m_findSeparatingAxisKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, satKernelsCL, "findSeparatingAxisKernel", &errNum, satProg); b3Assert(m_findSeparatingAxisKernel); - b3Assert(errNum==CL_SUCCESS); + b3Assert(errNum == CL_SUCCESS); - - m_findSeparatingAxisVertexFaceKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,satKernelsCL, "findSeparatingAxisVertexFaceKernel",&errNum,satProg ); + m_findSeparatingAxisVertexFaceKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, satKernelsCL, "findSeparatingAxisVertexFaceKernel", &errNum, satProg); b3Assert(m_findSeparatingAxisVertexFaceKernel); - m_findSeparatingAxisEdgeEdgeKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,satKernelsCL, "findSeparatingAxisEdgeEdgeKernel",&errNum,satProg ); + m_findSeparatingAxisEdgeEdgeKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, satKernelsCL, "findSeparatingAxisEdgeEdgeKernel", &errNum, satProg); b3Assert(m_findSeparatingAxisVertexFaceKernel); - - m_findConcaveSeparatingAxisKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,satKernelsCL, "findConcaveSeparatingAxisKernel",&errNum,satProg ); + m_findConcaveSeparatingAxisKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, satKernelsCL, "findConcaveSeparatingAxisKernel", &errNum, satProg); b3Assert(m_findConcaveSeparatingAxisKernel); - b3Assert(errNum==CL_SUCCESS); - - m_findConcaveSeparatingAxisVertexFaceKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,srcConcave, "findConcaveSeparatingAxisVertexFaceKernel",&errNum,satConcaveProg ); + b3Assert(errNum == CL_SUCCESS); + + m_findConcaveSeparatingAxisVertexFaceKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, srcConcave, "findConcaveSeparatingAxisVertexFaceKernel", &errNum, satConcaveProg); b3Assert(m_findConcaveSeparatingAxisVertexFaceKernel); - b3Assert(errNum==CL_SUCCESS); - - m_findConcaveSeparatingAxisEdgeEdgeKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,srcConcave, "findConcaveSeparatingAxisEdgeEdgeKernel",&errNum,satConcaveProg ); + b3Assert(errNum == CL_SUCCESS); + + m_findConcaveSeparatingAxisEdgeEdgeKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, srcConcave, "findConcaveSeparatingAxisEdgeEdgeKernel", &errNum, satConcaveProg); b3Assert(m_findConcaveSeparatingAxisEdgeEdgeKernel); - b3Assert(errNum==CL_SUCCESS); - - - - - m_findCompoundPairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,satKernelsCL, "findCompoundPairsKernel",&errNum,satProg ); + b3Assert(errNum == CL_SUCCESS); + + m_findCompoundPairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, satKernelsCL, "findCompoundPairsKernel", &errNum, satProg); b3Assert(m_findCompoundPairsKernel); - b3Assert(errNum==CL_SUCCESS); - m_processCompoundPairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,satKernelsCL, "processCompoundPairsKernel",&errNum,satProg ); + b3Assert(errNum == CL_SUCCESS); + m_processCompoundPairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, satKernelsCL, "processCompoundPairsKernel", &errNum, satProg); b3Assert(m_processCompoundPairsKernel); - b3Assert(errNum==CL_SUCCESS); + b3Assert(errNum == CL_SUCCESS); } if (1) { const char* srcClip = satClipKernelsCL; - char flags[1024]={0}; -//#ifdef CL_PLATFORM_INTEL -// sprintf(flags,"-g -s \"%s\"","C:/develop/bullet3_experiments2/opencl/gpu_narrowphase/kernels/satClipHullContacts.cl"); -//#endif + char flags[1024] = {0}; + //#ifdef CL_PLATFORM_INTEL + // sprintf(flags,"-g -s \"%s\"","C:/develop/bullet3_experiments2/opencl/gpu_narrowphase/kernels/satClipHullContacts.cl"); + //#endif - cl_program satClipContactsProg = b3OpenCLUtils::compileCLProgramFromString(m_context,m_device,srcClip,&errNum,flags,BT_NARROWPHASE_CLIPHULL_PATH); - b3Assert(errNum==CL_SUCCESS); + cl_program satClipContactsProg = b3OpenCLUtils::compileCLProgramFromString(m_context, m_device, srcClip, &errNum, flags, BT_NARROWPHASE_CLIPHULL_PATH); + b3Assert(errNum == CL_SUCCESS); - m_clipHullHullKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,srcClip, "clipHullHullKernel",&errNum,satClipContactsProg); - b3Assert(errNum==CL_SUCCESS); + m_clipHullHullKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, srcClip, "clipHullHullKernel", &errNum, satClipContactsProg); + b3Assert(errNum == CL_SUCCESS); - m_clipCompoundsHullHullKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,srcClip, "clipCompoundsHullHullKernel",&errNum,satClipContactsProg); - b3Assert(errNum==CL_SUCCESS); - + m_clipCompoundsHullHullKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, srcClip, "clipCompoundsHullHullKernel", &errNum, satClipContactsProg); + b3Assert(errNum == CL_SUCCESS); - m_findClippingFacesKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,srcClip, "findClippingFacesKernel",&errNum,satClipContactsProg); - b3Assert(errNum==CL_SUCCESS); + m_findClippingFacesKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, srcClip, "findClippingFacesKernel", &errNum, satClipContactsProg); + b3Assert(errNum == CL_SUCCESS); - m_clipFacesAndFindContacts = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,srcClip, "clipFacesAndFindContactsKernel",&errNum,satClipContactsProg); - b3Assert(errNum==CL_SUCCESS); + m_clipFacesAndFindContacts = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, srcClip, "clipFacesAndFindContactsKernel", &errNum, satClipContactsProg); + b3Assert(errNum == CL_SUCCESS); - m_clipHullHullConcaveConvexKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,srcClip, "clipHullHullConcaveConvexKernel",&errNum,satClipContactsProg); - b3Assert(errNum==CL_SUCCESS); + m_clipHullHullConcaveConvexKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, srcClip, "clipHullHullConcaveConvexKernel", &errNum, satClipContactsProg); + b3Assert(errNum == CL_SUCCESS); -// m_extractManifoldAndAddContactKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,srcClip, "extractManifoldAndAddContactKernel",&errNum,satClipContactsProg); - // b3Assert(errNum==CL_SUCCESS); + // m_extractManifoldAndAddContactKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,srcClip, "extractManifoldAndAddContactKernel",&errNum,satClipContactsProg); + // b3Assert(errNum==CL_SUCCESS); - m_newContactReductionKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,srcClip, - "newContactReductionKernel",&errNum,satClipContactsProg); - b3Assert(errNum==CL_SUCCESS); + m_newContactReductionKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, srcClip, + "newContactReductionKernel", &errNum, satClipContactsProg); + b3Assert(errNum == CL_SUCCESS); } - else + else { - m_clipHullHullKernel=0; + m_clipHullHullKernel = 0; m_clipCompoundsHullHullKernel = 0; - m_findClippingFacesKernel = 0; - m_newContactReductionKernel=0; - m_clipFacesAndFindContacts = 0; + m_findClippingFacesKernel = 0; + m_newContactReductionKernel = 0; + m_clipFacesAndFindContacts = 0; m_clipHullHullConcaveConvexKernel = 0; -// m_extractManifoldAndAddContactKernel = 0; + // m_extractManifoldAndAddContactKernel = 0; } - if (1) + if (1) { const char* srcBvh = bvhTraversalKernelCL; - cl_program bvhTraversalProg = b3OpenCLUtils::compileCLProgramFromString(m_context,m_device,srcBvh,&errNum,"",BT_NARROWPHASE_BVH_TRAVERSAL_PATH); - b3Assert(errNum==CL_SUCCESS); - - m_bvhTraversalKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,srcBvh, "bvhTraversalKernel",&errNum,bvhTraversalProg,""); - b3Assert(errNum==CL_SUCCESS); + cl_program bvhTraversalProg = b3OpenCLUtils::compileCLProgramFromString(m_context, m_device, srcBvh, &errNum, "", BT_NARROWPHASE_BVH_TRAVERSAL_PATH); + b3Assert(errNum == CL_SUCCESS); + m_bvhTraversalKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, srcBvh, "bvhTraversalKernel", &errNum, bvhTraversalProg, ""); + b3Assert(errNum == CL_SUCCESS); } - - { - const char* primitiveContactsSrc = primitiveContactsKernelsCL; - cl_program primitiveContactsProg = b3OpenCLUtils::compileCLProgramFromString(m_context,m_device,primitiveContactsSrc,&errNum,"",BT_NARROWPHASE_PRIMITIVE_CONTACT_PATH); - b3Assert(errNum==CL_SUCCESS); - m_primitiveContactsKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,primitiveContactsSrc, "primitiveContactsKernel",&errNum,primitiveContactsProg,""); - b3Assert(errNum==CL_SUCCESS); + { + const char* primitiveContactsSrc = primitiveContactsKernelsCL; + cl_program primitiveContactsProg = b3OpenCLUtils::compileCLProgramFromString(m_context, m_device, primitiveContactsSrc, &errNum, "", BT_NARROWPHASE_PRIMITIVE_CONTACT_PATH); + b3Assert(errNum == CL_SUCCESS); - m_findConcaveSphereContactsKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,primitiveContactsSrc, "findConcaveSphereContactsKernel",&errNum,primitiveContactsProg ); - b3Assert(errNum==CL_SUCCESS); + m_primitiveContactsKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, primitiveContactsSrc, "primitiveContactsKernel", &errNum, primitiveContactsProg, ""); + b3Assert(errNum == CL_SUCCESS); + + m_findConcaveSphereContactsKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, primitiveContactsSrc, "findConcaveSphereContactsKernel", &errNum, primitiveContactsProg); + b3Assert(errNum == CL_SUCCESS); b3Assert(m_findConcaveSphereContactsKernel); - m_processCompoundPairsPrimitivesKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device,primitiveContactsSrc, "processCompoundPairsPrimitivesKernel",&errNum,primitiveContactsProg,""); - b3Assert(errNum==CL_SUCCESS); + m_processCompoundPairsPrimitivesKernel = b3OpenCLUtils::compileCLKernelFromString(m_context, m_device, primitiveContactsSrc, "processCompoundPairsPrimitivesKernel", &errNum, primitiveContactsProg, ""); + b3Assert(errNum == CL_SUCCESS); b3Assert(m_processCompoundPairsPrimitivesKernel); - - } - - + } } GpuSatCollision::~GpuSatCollision() { - if (m_findSeparatingAxisVertexFaceKernel) clReleaseKernel(m_findSeparatingAxisVertexFaceKernel); @@ -301,17 +276,15 @@ GpuSatCollision::~GpuSatCollision() if (m_mprPenetrationKernel) clReleaseKernel(m_mprPenetrationKernel); - if (m_findSeparatingAxisKernel) clReleaseKernel(m_findSeparatingAxisKernel); - if (m_findConcaveSeparatingAxisVertexFaceKernel) - clReleaseKernel(m_findConcaveSeparatingAxisVertexFaceKernel); + if (m_findConcaveSeparatingAxisVertexFaceKernel) + clReleaseKernel(m_findConcaveSeparatingAxisVertexFaceKernel); + + if (m_findConcaveSeparatingAxisEdgeEdgeKernel) + clReleaseKernel(m_findConcaveSeparatingAxisEdgeEdgeKernel); - - if (m_findConcaveSeparatingAxisEdgeEdgeKernel) - clReleaseKernel(m_findConcaveSeparatingAxisEdgeEdgeKernel); - if (m_findConcaveSeparatingAxisKernel) clReleaseKernel(m_findConcaveSeparatingAxisKernel); @@ -320,17 +293,17 @@ GpuSatCollision::~GpuSatCollision() if (m_processCompoundPairsKernel) clReleaseKernel(m_processCompoundPairsKernel); - - if (m_findClippingFacesKernel) - clReleaseKernel(m_findClippingFacesKernel); - - if (m_clipFacesAndFindContacts) - clReleaseKernel(m_clipFacesAndFindContacts); - if (m_newContactReductionKernel) - clReleaseKernel(m_newContactReductionKernel); + + if (m_findClippingFacesKernel) + clReleaseKernel(m_findClippingFacesKernel); + + if (m_clipFacesAndFindContacts) + clReleaseKernel(m_clipFacesAndFindContacts); + if (m_newContactReductionKernel) + clReleaseKernel(m_newContactReductionKernel); if (m_primitiveContactsKernel) clReleaseKernel(m_primitiveContactsKernel); - + if (m_findConcaveSphereContactsKernel) clReleaseKernel(m_findConcaveSphereContactsKernel); @@ -344,12 +317,11 @@ GpuSatCollision::~GpuSatCollision() if (m_clipHullHullConcaveConvexKernel) clReleaseKernel(m_clipHullHullConcaveConvexKernel); -// if (m_extractManifoldAndAddContactKernel) + // if (m_extractManifoldAndAddContactKernel) // clReleaseKernel(m_extractManifoldAndAddContactKernel); if (m_bvhTraversalKernel) clReleaseKernel(m_bvhTraversalKernel); - } struct MyTriangleCallback : public b3NodeOverlapCallback @@ -359,14 +331,13 @@ struct MyTriangleCallback : public b3NodeOverlapCallback virtual void processNode(int subPart, int triangleIndex) { - printf("bodyIndexA %d, bodyIndexB %d\n",m_bodyIndexA,m_bodyIndexB); + printf("bodyIndexA %d, bodyIndexB %d\n", m_bodyIndexA, m_bodyIndexB); printf("triangleIndex %d\n", triangleIndex); } }; - #define float4 b3Vector3 -#define make_float4(x,y,z,w) b3MakeVector3(x,y,z,w) +#define make_float4(x, y, z, w) b3MakeVector3(x, y, z, w) float signedDistanceFromPointToPlane(const float4& point, const float4& planeEqn, float4* closestPointOnFace) { @@ -377,9 +348,7 @@ float signedDistanceFromPointToPlane(const float4& point, const float4& planeEqn return dist; } - - -#define cross3(a,b) (a.cross(b)) +#define cross3(a, b) (a.cross(b)) b3Vector3 transform(const b3Vector3* v, const b3Vector3* pos, const b3Quaternion* orn) { b3Transform tr; @@ -390,184 +359,170 @@ b3Vector3 transform(const b3Vector3* v, const b3Vector3* pos, const b3Quaternion return res; } - -inline bool IsPointInPolygon(const float4& p, - const b3GpuFace* face, +inline bool IsPointInPolygon(const float4& p, + const b3GpuFace* face, const float4* baseVertex, - const int* convexIndices, - float4* out) + const int* convexIndices, + float4* out) { - float4 a; - float4 b; - float4 ab; - float4 ap; - float4 v; + float4 a; + float4 b; + float4 ab; + float4 ap; + float4 v; - float4 plane = b3MakeVector3(face->m_plane.x,face->m_plane.y,face->m_plane.z,0.f); - - if (face->m_numIndices<2) + float4 plane = b3MakeVector3(face->m_plane.x, face->m_plane.y, face->m_plane.z, 0.f); + + if (face->m_numIndices < 2) return false; - - float4 v0 = baseVertex[convexIndices[face->m_indexOffset + face->m_numIndices-1]]; + float4 v0 = baseVertex[convexIndices[face->m_indexOffset + face->m_numIndices - 1]]; b = v0; - for(unsigned i=0; i != face->m_numIndices; ++i) - { + for (unsigned i = 0; i != face->m_numIndices; ++i) + { a = b; float4 vi = baseVertex[convexIndices[face->m_indexOffset + i]]; b = vi; - ab = b-a; - ap = p-a; - v = cross3(ab,plane); + ab = b - a; + ap = p - a; + v = cross3(ab, plane); - if (b3Dot(ap, v) > 0.f) - { - float ab_m2 = b3Dot(ab, ab); - float rt = ab_m2 != 0.f ? b3Dot(ab, ap) / ab_m2 : 0.f; - if (rt <= 0.f) - { - *out = a; - } - else if (rt >= 1.f) - { - *out = b; - } - else - { - float s = 1.f - rt; + if (b3Dot(ap, v) > 0.f) + { + float ab_m2 = b3Dot(ab, ab); + float rt = ab_m2 != 0.f ? b3Dot(ab, ap) / ab_m2 : 0.f; + if (rt <= 0.f) + { + *out = a; + } + else if (rt >= 1.f) + { + *out = b; + } + else + { + float s = 1.f - rt; out[0].x = s * a.x + rt * b.x; out[0].y = s * a.y + rt * b.y; out[0].z = s * a.z + rt * b.z; - } - return false; - } - } - return true; + } + return false; + } + } + return true; } #define normalize3(a) (a.normalize()) - -int extractManifoldSequentialGlobal( const float4* p, int nPoints, const float4& nearNormal, b3Int4* contactIdx) +int extractManifoldSequentialGlobal(const float4* p, int nPoints, const float4& nearNormal, b3Int4* contactIdx) { - if( nPoints == 0 ) - return 0; - - if (nPoints <=4) - return nPoints; - - - if (nPoints >64) - nPoints = 64; - - float4 center = b3MakeVector3(0,0,0,0); + if (nPoints == 0) + return 0; + + if (nPoints <= 4) + return nPoints; + + if (nPoints > 64) + nPoints = 64; + + float4 center = b3MakeVector3(0, 0, 0, 0); { - - for (int i=0;i& vertices, b3Scalar& min, b3Scalar& max) +inline void project(const b3ConvexPolyhedronData& hull, const float4& pos, const b3Quaternion& orn, const float4& dir, const b3AlignedObjectArray& vertices, b3Scalar& min, b3Scalar& max) { min = FLT_MAX; max = -FLT_MAX; int numVerts = hull.m_numVertices; - const float4 localDir = b3QuatRotate(orn.inverse(),dir); + const float4 localDir = b3QuatRotate(orn.inverse(), dir); - b3Scalar offset = dot3F4(pos,dir); + b3Scalar offset = dot3F4(pos, dir); - for(int i=0;i max) max = dp; + if (dp < min) min = dp; + if (dp > max) max = dp; } - if(min>max) + if (min > max) { b3Scalar tmp = min; min = max; @@ -577,50 +532,48 @@ inline void project(const b3ConvexPolyhedronData& hull, const float4& pos, cons max += offset; } - -static bool TestSepAxis(const b3ConvexPolyhedronData& hullA, const b3ConvexPolyhedronData& hullB, - const float4& posA,const b3Quaternion& ornA, - const float4& posB,const b3Quaternion& ornB, - const float4& sep_axis, const b3AlignedObjectArray& verticesA,const b3AlignedObjectArray& verticesB,b3Scalar& depth) +static bool TestSepAxis(const b3ConvexPolyhedronData& hullA, const b3ConvexPolyhedronData& hullB, + const float4& posA, const b3Quaternion& ornA, + const float4& posB, const b3Quaternion& ornB, + const float4& sep_axis, const b3AlignedObjectArray& verticesA, const b3AlignedObjectArray& verticesB, b3Scalar& depth) { - b3Scalar Min0,Max0; - b3Scalar Min1,Max1; - project(hullA,posA,ornA,sep_axis,verticesA, Min0, Max0); - project(hullB,posB,ornB, sep_axis,verticesB, Min1, Max1); + b3Scalar Min0, Max0; + b3Scalar Min1, Max1; + project(hullA, posA, ornA, sep_axis, verticesA, Min0, Max0); + project(hullB, posB, ornB, sep_axis, verticesB, Min1, Max1); - if(Max0=0.0f); + assert(d0 >= 0.0f); b3Scalar d1 = Max1 - Min0; - assert(d1>=0.0f); - depth = d0= 0.0f); + depth = d0 < d1 ? d0 : d1; return true; } inline bool IsAlmostZero(const b3Vector3& v) { - if(fabsf(v.x)>1e-6 || fabsf(v.y)>1e-6 || fabsf(v.z)>1e-6) return false; + if (fabsf(v.x) > 1e-6 || fabsf(v.y) > 1e-6 || fabsf(v.z) > 1e-6) return false; return true; } +static bool findSeparatingAxis(const b3ConvexPolyhedronData& hullA, const b3ConvexPolyhedronData& hullB, + const float4& posA1, + const b3Quaternion& ornA, + const float4& posB1, + const b3Quaternion& ornB, + const b3AlignedObjectArray& verticesA, + const b3AlignedObjectArray& uniqueEdgesA, + const b3AlignedObjectArray& facesA, + const b3AlignedObjectArray& indicesA, + const b3AlignedObjectArray& verticesB, + const b3AlignedObjectArray& uniqueEdgesB, + const b3AlignedObjectArray& facesB, + const b3AlignedObjectArray& indicesB, -static bool findSeparatingAxis( const b3ConvexPolyhedronData& hullA, const b3ConvexPolyhedronData& hullB, - const float4& posA1, - const b3Quaternion& ornA, - const float4& posB1, - const b3Quaternion& ornB, - const b3AlignedObjectArray& verticesA, - const b3AlignedObjectArray& uniqueEdgesA, - const b3AlignedObjectArray& facesA, - const b3AlignedObjectArray& indicesA, - const b3AlignedObjectArray& verticesB, - const b3AlignedObjectArray& uniqueEdgesB, - const b3AlignedObjectArray& facesB, - const b3AlignedObjectArray& indicesB, - - b3Vector3& sep) + b3Vector3& sep) { B3_PROFILE("findSeparatingAxis"); @@ -629,41 +582,40 @@ static bool findSeparatingAxis( const b3ConvexPolyhedronData& hullA, const b3Con posA.w = 0.f; float4 posB = posB1; posB.w = 0.f; -//#ifdef TEST_INTERNAL_OBJECTS + //#ifdef TEST_INTERNAL_OBJECTS float4 c0local = (float4&)hullA.m_localCenter; float4 c0 = transform(&c0local, &posA, &ornA); float4 c1local = (float4&)hullB.m_localCenter; - float4 c1 = transform(&c1local,&posB,&ornB); + float4 c1 = transform(&c1local, &posB, &ornB); const float4 deltaC2 = c0 - c1; -//#endif + //#endif b3Scalar dmin = FLT_MAX; - int curPlaneTests=0; + int curPlaneTests = 0; int numFacesA = hullA.m_numFaces; // Test normals from hullA - for(int i=0;i0.0f) + if ((dot3F4(-deltaC2, (float4&)sep)) > 0.0f) sep = -sep; return true; } - -bool findSeparatingAxisEdgeEdge( __global const b3ConvexPolyhedronData* hullA, __global const b3ConvexPolyhedronData* hullB, - const b3Float4& posA1, - const b3Quat& ornA, - const b3Float4& posB1, - const b3Quat& ornB, - const b3Float4& DeltaC2, - __global const b3AlignedObjectArray& vertices, - __global const b3AlignedObjectArray& uniqueEdges, - __global const b3AlignedObjectArray& faces, - __global const b3AlignedObjectArray& indices, - float4* sep, - float* dmin) +bool findSeparatingAxisEdgeEdge(__global const b3ConvexPolyhedronData* hullA, __global const b3ConvexPolyhedronData* hullB, + const b3Float4& posA1, + const b3Quat& ornA, + const b3Float4& posB1, + const b3Quat& ornB, + const b3Float4& DeltaC2, + __global const b3AlignedObjectArray& vertices, + __global const b3AlignedObjectArray& uniqueEdges, + __global const b3AlignedObjectArray& faces, + __global const b3AlignedObjectArray& indices, + float4* sep, + float* dmin) { -// int i = get_global_id(0); + // int i = get_global_id(0); float4 posA = posA1; posA.w = 0.f; @@ -776,97 +723,89 @@ bool findSeparatingAxisEdgeEdge( __global const b3ConvexPolyhedronData* hullA, _ int curEdgeEdge = 0; // Test edges - for(int e0=0;e0m_numUniqueEdges;e0++) + for (int e0 = 0; e0 < hullA->m_numUniqueEdges; e0++) { - const float4 edge0 = uniqueEdges[hullA->m_uniqueEdgesOffset+e0]; - float4 edge0World = b3QuatRotate(ornA,edge0); + const float4 edge0 = uniqueEdges[hullA->m_uniqueEdgesOffset + e0]; + float4 edge0World = b3QuatRotate(ornA, edge0); - for(int e1=0;e1m_numUniqueEdges;e1++) + for (int e1 = 0; e1 < hullB->m_numUniqueEdges; e1++) { - const float4 edge1 = uniqueEdges[hullB->m_uniqueEdgesOffset+e1]; - float4 edge1World = b3QuatRotate(ornB,edge1); + const float4 edge1 = uniqueEdges[hullB->m_uniqueEdgesOffset + e1]; + float4 edge1World = b3QuatRotate(ornB, edge1); - - float4 crossje = cross3(edge0World,edge1World); + float4 crossje = cross3(edge0World, edge1World); curEdgeEdge++; - if(!IsAlmostZero(crossje)) + if (!IsAlmostZero(crossje)) { crossje = normalize3(crossje); - if (dot3F4(DeltaC2,crossje)<0) - crossje*=-1.f; - + if (dot3F4(DeltaC2, crossje) < 0) + crossje *= -1.f; + float dist; bool result = true; { - float Min0,Max0; - float Min1,Max1; - project(*hullA,posA,ornA,crossje,vertices, Min0, Max0); - project(*hullB,posB,ornB,crossje,vertices, Min1, Max1); - - if(Max00.0f) + if ((dot3F4(-DeltaC2, *sep)) > 0.0f) { *sep = -(*sep); } return true; } - -__inline float4 lerp3(const float4& a,const float4& b, float t) +__inline float4 lerp3(const float4& a, const float4& b, float t) { - return b3MakeVector3( a.x + (b.x - a.x) * t, - a.y + (b.y - a.y) * t, - a.z + (b.z - a.z) * t, - 0.f); + return b3MakeVector3(a.x + (b.x - a.x) * t, + a.y + (b.y - a.y) * t, + a.z + (b.z - a.z) * t, + 0.f); } - // Clips a face to the back of a plane, return the number of vertices out, stored in ppVtxOut -int clipFace(const float4* pVtxIn, int numVertsIn, float4& planeNormalWS,float planeEqWS, float4* ppVtxOut) +int clipFace(const float4* pVtxIn, int numVertsIn, float4& planeNormalWS, float planeEqWS, float4* ppVtxOut) { - int ve; float ds, de; int numVertsOut = 0; if (numVertsIn < 2) return 0; - float4 firstVertex=pVtxIn[numVertsIn-1]; + float4 firstVertex = pVtxIn[numVertsIn - 1]; float4 endVertex = pVtxIn[0]; - - ds = dot3F4(planeNormalWS,firstVertex)+planeEqWS; + + ds = dot3F4(planeNormalWS, firstVertex) + planeEqWS; for (ve = 0; ve < numVertsIn; ve++) { - endVertex=pVtxIn[ve]; + endVertex = pVtxIn[ve]; - de = dot3F4(planeNormalWS,endVertex)+planeEqWS; + de = dot3F4(planeNormalWS, endVertex) + planeEqWS; - if (ds<0) + if (ds < 0) { - if (de<0) + if (de < 0) { // Start < 0, end < 0, so output endVertex ppVtxOut[numVertsOut++] = endVertex; @@ -874,15 +813,15 @@ int clipFace(const float4* pVtxIn, int numVertsIn, float4& planeNormalWS,float p else { // Start < 0, end >= 0, so output intersection - ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) ); + ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex, (ds * 1.f / (ds - de))); } } else { - if (de<0) + if (de < 0) { // Start >= 0, end < 0 so output intersection and end - ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) ); + ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex, (ds * 1.f / (ds - de))); ppVtxOut[numVertsOut++] = endVertex; } } @@ -892,36 +831,35 @@ int clipFace(const float4* pVtxIn, int numVertsIn, float4& planeNormalWS,float p return numVertsOut; } - -int clipFaceAgainstHull(const float4& separatingNormal, const b3ConvexPolyhedronData* hullA, - const float4& posA, const b3Quaternion& ornA, float4* worldVertsB1, int numWorldVertsB1, - float4* worldVertsB2, int capacityWorldVertsB2, - const float minDist, float maxDist, - const b3AlignedObjectArray& verticesA, const b3AlignedObjectArray& facesA, const b3AlignedObjectArray& indicesA, - //const float4* verticesB, const b3GpuFace* facesB, const int* indicesB, - float4* contactsOut, - int contactCapacity) +int clipFaceAgainstHull(const float4& separatingNormal, const b3ConvexPolyhedronData* hullA, + const float4& posA, const b3Quaternion& ornA, float4* worldVertsB1, int numWorldVertsB1, + float4* worldVertsB2, int capacityWorldVertsB2, + const float minDist, float maxDist, + const b3AlignedObjectArray& verticesA, const b3AlignedObjectArray& facesA, const b3AlignedObjectArray& indicesA, + //const float4* verticesB, const b3GpuFace* facesB, const int* indicesB, + float4* contactsOut, + int contactCapacity) { int numContactsOut = 0; float4* pVtxIn = worldVertsB1; float4* pVtxOut = worldVertsB2; - + int numVertsIn = numWorldVertsB1; int numVertsOut = 0; - int closestFaceA=-1; + int closestFaceA = -1; { float dmin = FLT_MAX; - for(int face=0;facem_numFaces;face++) + for (int face = 0; face < hullA->m_numFaces; face++) { const float4 Normal = b3MakeVector3( - facesA[hullA->m_faceOffset+face].m_plane.x, - facesA[hullA->m_faceOffset+face].m_plane.y, - facesA[hullA->m_faceOffset+face].m_plane.z,0.f); - const float4 faceANormalWS = b3QuatRotate(ornA,Normal); - - float d = dot3F4(faceANormalWS,separatingNormal); + facesA[hullA->m_faceOffset + face].m_plane.x, + facesA[hullA->m_faceOffset + face].m_plane.y, + facesA[hullA->m_faceOffset + face].m_plane.z, 0.f); + const float4 faceANormalWS = b3QuatRotate(ornA, Normal); + + float d = dot3F4(faceANormalWS, separatingNormal); if (d < dmin) { dmin = d; @@ -929,33 +867,33 @@ int clipFaceAgainstHull(const float4& separatingNormal, const b3ConvexPolyhedron } } } - if (closestFaceA<0) + if (closestFaceA < 0) return numContactsOut; - b3GpuFace polyA = facesA[hullA->m_faceOffset+closestFaceA]; + b3GpuFace polyA = facesA[hullA->m_faceOffset + closestFaceA]; // clip polygon to back of planes of all faces of hull A that are adjacent to witness face -// int numContacts = numWorldVertsB1; + // int numContacts = numWorldVertsB1; int numVerticesA = polyA.m_numIndices; - for(int e0=0;e0m_vertexOffset+indicesA[polyA.m_indexOffset+e0]]; - const float4 b = verticesA[hullA->m_vertexOffset+indicesA[polyA.m_indexOffset+((e0+1)%numVerticesA)]]; + const float4 a = verticesA[hullA->m_vertexOffset + indicesA[polyA.m_indexOffset + e0]]; + const float4 b = verticesA[hullA->m_vertexOffset + indicesA[polyA.m_indexOffset + ((e0 + 1) % numVerticesA)]]; const float4 edge0 = a - b; - const float4 WorldEdge0 = b3QuatRotate(ornA,edge0); - float4 planeNormalA = make_float4(polyA.m_plane.x,polyA.m_plane.y,polyA.m_plane.z,0.f); - float4 worldPlaneAnormal1 = b3QuatRotate(ornA,planeNormalA); + const float4 WorldEdge0 = b3QuatRotate(ornA, edge0); + float4 planeNormalA = make_float4(polyA.m_plane.x, polyA.m_plane.y, polyA.m_plane.z, 0.f); + float4 worldPlaneAnormal1 = b3QuatRotate(ornA, planeNormalA); + + float4 planeNormalWS1 = -cross3(WorldEdge0, worldPlaneAnormal1); + float4 worldA1 = transform(&a, &posA, &ornA); + float planeEqWS1 = -dot3F4(worldA1, planeNormalWS1); - float4 planeNormalWS1 = -cross3(WorldEdge0,worldPlaneAnormal1); - float4 worldA1 = transform(&a,&posA,&ornA); - float planeEqWS1 = -dot3F4(worldA1,planeNormalWS1); - float4 planeNormalWS = planeNormalWS1; - float planeEqWS=planeEqWS1; - + float planeEqWS = planeEqWS1; + //clip face //clipFace(*pVtxIn, *pVtxOut,planeNormalWS,planeEqWS); - numVertsOut = clipFace(pVtxIn, numVertsIn, planeNormalWS,planeEqWS, pVtxOut); + numVertsOut = clipFace(pVtxIn, numVertsIn, planeNormalWS, planeEqWS, pVtxOut); //btSwap(pVtxIn,pVtxOut); float4* tmp = pVtxOut; @@ -965,32 +903,32 @@ int clipFaceAgainstHull(const float4& separatingNormal, const b3ConvexPolyhedron numVertsOut = 0; } - // only keep points that are behind the witness face { - float4 localPlaneNormal = make_float4(polyA.m_plane.x,polyA.m_plane.y,polyA.m_plane.z,0.f); + float4 localPlaneNormal = make_float4(polyA.m_plane.x, polyA.m_plane.y, polyA.m_plane.z, 0.f); float localPlaneEq = polyA.m_plane.w; - float4 planeNormalWS = b3QuatRotate(ornA,localPlaneNormal); - float planeEqWS=localPlaneEq-dot3F4(planeNormalWS,posA); - for (int i=0;i& verticesA, const b3AlignedObjectArray& facesA, const b3AlignedObjectArray& indicesA, + const b3AlignedObjectArray& verticesB, const b3AlignedObjectArray& facesB, const b3AlignedObjectArray& indicesB, - -static int clipHullAgainstHull(const float4& separatingNormal, - const b3ConvexPolyhedronData& hullA, const b3ConvexPolyhedronData& hullB, - const float4& posA, const b3Quaternion& ornA,const float4& posB, const b3Quaternion& ornB, - float4* worldVertsB1, float4* worldVertsB2, int capacityWorldVerts, - const float minDist, float maxDist, - const b3AlignedObjectArray& verticesA, const b3AlignedObjectArray& facesA, const b3AlignedObjectArray& indicesA, - const b3AlignedObjectArray& verticesB, const b3AlignedObjectArray& facesB, const b3AlignedObjectArray& indicesB, - - float4* contactsOut, - int contactCapacity) + float4* contactsOut, + int contactCapacity) { int numContactsOut = 0; - int numWorldVertsB1= 0; - + int numWorldVertsB1 = 0; + B3_PROFILE("clipHullAgainstHull"); -// float curMaxDist=maxDist; - int closestFaceB=-1; + // float curMaxDist=maxDist; + int closestFaceB = -1; float dmax = -FLT_MAX; { //B3_PROFILE("closestFaceB"); - if (hullB.m_numFaces!=1) + if (hullB.m_numFaces != 1) { //printf("wtf\n"); } static bool once = true; //printf("separatingNormal=%f,%f,%f\n",separatingNormal.x,separatingNormal.y,separatingNormal.z); - - for(int face=0;facem_numIndices;i++) + for (int i = 0; i < faceB->m_numIndices; i++) { - float4 vert = verticesB[hullB.m_vertexOffset+indicesB[faceB->m_indexOffset+i]]; - printf("vert[%d] = %f,%f,%f\n",i,vert.x,vert.y,vert.z); + float4 vert = verticesB[hullB.m_vertexOffset + indicesB[faceB->m_indexOffset + i]]; + printf("vert[%d] = %f,%f,%f\n", i, vert.x, vert.y, vert.z); } } -#endif //BT_DEBUG_SAT_FACE - //if (facesB[hullB.m_faceOffset+face].m_numIndices>2) +#endif //BT_DEBUG_SAT_FACE \ + //if (facesB[hullB.m_faceOffset+face].m_numIndices>2) { - const float4 Normal = b3MakeVector3(facesB[hullB.m_faceOffset+face].m_plane.x, - facesB[hullB.m_faceOffset+face].m_plane.y, facesB[hullB.m_faceOffset+face].m_plane.z,0.f); + const float4 Normal = b3MakeVector3(facesB[hullB.m_faceOffset + face].m_plane.x, + facesB[hullB.m_faceOffset + face].m_plane.y, facesB[hullB.m_faceOffset + face].m_plane.z, 0.f); const float4 WorldNormal = b3QuatRotate(ornB, Normal); #ifdef BT_DEBUG_SAT_FACE if (once) - printf("faceNormal = %f,%f,%f\n",Normal.x,Normal.y,Normal.z); + printf("faceNormal = %f,%f,%f\n", Normal.x, Normal.y, Normal.z); #endif - float d = dot3F4(WorldNormal,separatingNormal); + float d = dot3F4(WorldNormal, separatingNormal); if (d > dmax) { dmax = d; @@ -1064,184 +1000,176 @@ static int clipHullAgainstHull(const float4& separatingNormal, once = false; } - - b3Assert(closestFaceB>=0); + b3Assert(closestFaceB >= 0); { //B3_PROFILE("worldVertsB1"); - const b3GpuFace& polyB = facesB[hullB.m_faceOffset+closestFaceB]; + const b3GpuFace& polyB = facesB[hullB.m_faceOffset + closestFaceB]; const int numVertices = polyB.m_numIndices; - for(int e0=0;e0=0) + if (closestFaceB >= 0) { //B3_PROFILE("clipFaceAgainstHull"); - numContactsOut = clipFaceAgainstHull((float4&)separatingNormal, &hullA, - posA,ornA, - worldVertsB1,numWorldVertsB1,worldVertsB2,capacityWorldVerts, minDist, maxDist, - verticesA, facesA, indicesA, - contactsOut,contactCapacity); + numContactsOut = clipFaceAgainstHull((float4&)separatingNormal, &hullA, + posA, ornA, + worldVertsB1, numWorldVertsB1, worldVertsB2, capacityWorldVerts, minDist, maxDist, + verticesA, facesA, indicesA, + contactsOut, contactCapacity); } return numContactsOut; } - - - - - -#define PARALLEL_SUM(v, n) for(int j=1; j v[i+offset].y)? v[i]: v[i+offset]; } -#define REDUCE_MIN(v, n) {int i=0;\ -for(int offset=0; offset v[i + offset].y) ? v[i] : v[i + offset]; \ + } +#define REDUCE_MIN(v, n) \ + { \ + int i = 0; \ + for (int offset = 0; offset < n; offset++) v[i] = (v[i].y < v[i + offset].y) ? v[i] : v[i + offset]; \ + } int extractManifold(const float4* p, int nPoints, const float4& nearNormal, b3Int4* contactIdx) { - if( nPoints == 0 ) - return 0; - - if (nPoints <=4) - return nPoints; - - - if (nPoints >64) - nPoints = 64; - - float4 center = make_float4(0,0,0,0); + if (nPoints == 0) + return 0; + + if (nPoints <= 4) + return nPoints; + + if (nPoints > 64) + nPoints = 64; + + float4 center = make_float4(0, 0, 0, 0); { - - for (int i=0;i* bodyBuf, - b3AlignedObjectArray* globalContactOut, - int& nContacts, - - const b3AlignedObjectArray& hostConvexDataA, - const b3AlignedObjectArray& hostConvexDataB, - - const b3AlignedObjectArray& verticesA, - const b3AlignedObjectArray& uniqueEdgesA, - const b3AlignedObjectArray& facesA, - const b3AlignedObjectArray& indicesA, - - const b3AlignedObjectArray& verticesB, - const b3AlignedObjectArray& uniqueEdgesB, - const b3AlignedObjectArray& facesB, - const b3AlignedObjectArray& indicesB, + const b3AlignedObjectArray* bodyBuf, + b3AlignedObjectArray* globalContactOut, + int& nContacts, - const b3AlignedObjectArray& hostCollidablesA, - const b3AlignedObjectArray& hostCollidablesB, - const b3Vector3& sepNormalWorldSpace, - int maxContactCapacity ) + const b3AlignedObjectArray& hostConvexDataA, + const b3AlignedObjectArray& hostConvexDataB, + + const b3AlignedObjectArray& verticesA, + const b3AlignedObjectArray& uniqueEdgesA, + const b3AlignedObjectArray& facesA, + const b3AlignedObjectArray& indicesA, + + const b3AlignedObjectArray& verticesB, + const b3AlignedObjectArray& uniqueEdgesB, + const b3AlignedObjectArray& facesB, + const b3AlignedObjectArray& indicesB, + + const b3AlignedObjectArray& hostCollidablesA, + const b3AlignedObjectArray& hostCollidablesB, + const b3Vector3& sepNormalWorldSpace, + int maxContactCapacity) { int contactIndex = -1; b3ConvexPolyhedronData hullA, hullB; - - b3Collidable colA = hostCollidablesA[collidableIndexA]; - hullA = hostConvexDataA[colA.m_shapeIndex]; - //printf("numvertsA = %d\n",hullA.m_numVertices); - - - b3Collidable colB = hostCollidablesB[collidableIndexB]; - hullB = hostConvexDataB[colB.m_shapeIndex]; - //printf("numvertsB = %d\n",hullB.m_numVertices); - - + + b3Collidable colA = hostCollidablesA[collidableIndexA]; + hullA = hostConvexDataA[colA.m_shapeIndex]; + //printf("numvertsA = %d\n",hullA.m_numVertices); + + b3Collidable colB = hostCollidablesB[collidableIndexB]; + hullB = hostConvexDataB[colB.m_shapeIndex]; + //printf("numvertsB = %d\n",hullB.m_numVertices); + float4 contactsOut[MAX_VERTS]; int localContactCapacity = MAX_VERTS; @@ -1249,133 +1177,125 @@ int clipHullHullSingle( b3Assert(_finite(bodyBuf->at(bodyIndexA).m_pos.x)); b3Assert(_finite(bodyBuf->at(bodyIndexB).m_pos.x)); #endif - - + { - float4 worldVertsB1[MAX_VERTS]; float4 worldVertsB2[MAX_VERTS]; int capacityWorldVerts = MAX_VERTS; - float4 hostNormal = make_float4(sepNormalWorldSpace.x,sepNormalWorldSpace.y,sepNormalWorldSpace.z,0.f); + float4 hostNormal = make_float4(sepNormalWorldSpace.x, sepNormalWorldSpace.y, sepNormalWorldSpace.z, 0.f); int shapeA = hostCollidablesA[collidableIndexA].m_shapeIndex; int shapeB = hostCollidablesB[collidableIndexB].m_shapeIndex; b3Scalar minDist = -1; b3Scalar maxDist = 0.; - - - b3Transform trA,trB; + b3Transform trA, trB; { - //B3_PROFILE("transform computation"); - //trA.setIdentity(); - trA.setOrigin(b3MakeVector3(posA.x,posA.y,posA.z)); - trA.setRotation(b3Quaternion(ornA.x,ornA.y,ornA.z,ornA.w)); - - //trB.setIdentity(); - trB.setOrigin(b3MakeVector3(posB.x,posB.y,posB.z)); - trB.setRotation(b3Quaternion(ornB.x,ornB.y,ornB.z,ornB.w)); + //B3_PROFILE("transform computation"); + //trA.setIdentity(); + trA.setOrigin(b3MakeVector3(posA.x, posA.y, posA.z)); + trA.setRotation(b3Quaternion(ornA.x, ornA.y, ornA.z, ornA.w)); + + //trB.setIdentity(); + trB.setOrigin(b3MakeVector3(posB.x, posB.y, posB.z)); + trB.setRotation(b3Quaternion(ornB.x, ornB.y, ornB.z, ornB.w)); } b3Quaternion trAorn = trA.getRotation(); - b3Quaternion trBorn = trB.getRotation(); - - int numContactsOut = clipHullAgainstHull(hostNormal, - hostConvexDataA.at(shapeA), - hostConvexDataB.at(shapeB), - (float4&)trA.getOrigin(), (b3Quaternion&)trAorn, - (float4&)trB.getOrigin(), (b3Quaternion&)trBorn, - worldVertsB1,worldVertsB2,capacityWorldVerts, - minDist, maxDist, - verticesA, facesA,indicesA, - verticesB, facesB,indicesB, - - contactsOut,localContactCapacity); + b3Quaternion trBorn = trB.getRotation(); - if (numContactsOut>0) + int numContactsOut = clipHullAgainstHull(hostNormal, + hostConvexDataA.at(shapeA), + hostConvexDataB.at(shapeB), + (float4&)trA.getOrigin(), (b3Quaternion&)trAorn, + (float4&)trB.getOrigin(), (b3Quaternion&)trBorn, + worldVertsB1, worldVertsB2, capacityWorldVerts, + minDist, maxDist, + verticesA, facesA, indicesA, + verticesB, facesB, indicesB, + + contactsOut, localContactCapacity); + + if (numContactsOut > 0) { B3_PROFILE("overlap"); float4 normalOnSurfaceB = (float4&)hostNormal; - + b3Int4 contactIdx; contactIdx.x = 0; contactIdx.y = 1; contactIdx.z = 2; contactIdx.w = 3; - + int numPoints = 0; - + { - // B3_PROFILE("extractManifold"); - numPoints = extractManifold(contactsOut, numContactsOut, normalOnSurfaceB, &contactIdx); + // B3_PROFILE("extractManifold"); + numPoints = extractManifold(contactsOut, numContactsOut, normalOnSurfaceB, &contactIdx); } - + b3Assert(numPoints); - - if (nContactsexpand(); b3Contact4& contact = globalContactOut->at(nContacts); - contact.m_batchIdx = 0;//i; - contact.m_bodyAPtrAndSignBit = (bodyBuf->at(bodyIndexA).m_invMass==0)? -bodyIndexA:bodyIndexA; - contact.m_bodyBPtrAndSignBit = (bodyBuf->at(bodyIndexB).m_invMass==0)? -bodyIndexB:bodyIndexB; + contact.m_batchIdx = 0; //i; + contact.m_bodyAPtrAndSignBit = (bodyBuf->at(bodyIndexA).m_invMass == 0) ? -bodyIndexA : bodyIndexA; + contact.m_bodyBPtrAndSignBit = (bodyBuf->at(bodyIndexB).m_invMass == 0) ? -bodyIndexB : bodyIndexB; contact.m_frictionCoeffCmp = 45874; contact.m_restituitionCoeffCmp = 0; - - // float distance = 0.f; - for (int p=0;pm_numVertices;i++) + + for (int i = 0; i < hullB->m_numVertices; i++) { - b3Vector3 vtx = convexVertices[hullB->m_vertexOffset+i]; + b3Vector3 vtx = convexVertices[hullB->m_vertexOffset + i]; float curDot = vtx.dot(planeNormalInConvex); - - if (curDot>maxDot) + if (curDot > maxDot) { - hitVertex=i; - maxDot=curDot; + hitVertex = i; + maxDot = curDot; hitVtx = vtx; //make sure the deepest points is always included - if (numPoints==MAX_PLANE_CONVEX_POINTS) + if (numPoints == MAX_PLANE_CONVEX_POINTS) numPoints--; } - if (numPoints4) + + if (numPoints > 4) { - numReducedPoints = extractManifoldSequentialGlobal( contactPoints, numPoints, planeNormalInConvex, &contactIdx); + numReducedPoints = extractManifoldSequentialGlobal(contactPoints, numPoints, planeNormalInConvex, &contactIdx); } int dstIdx; -// dstIdx = nGlobalContactsOut++;//AppendInc( nGlobalContactsOut, dstIdx ); - - if (numReducedPoints>0) + // dstIdx = nGlobalContactsOut++;//AppendInc( nGlobalContactsOut, dstIdx ); + + if (numReducedPoints > 0) { if (nGlobalContactsOut < maxContactCapacity) { - dstIdx=nGlobalContactsOut; + dstIdx = nGlobalContactsOut; nGlobalContactsOut++; b3Contact4* c = &globalContactsOut[dstIdx]; @@ -1462,38 +1380,33 @@ void computeContactPlaneConvex(int pairIndex, c->setRestituitionCoeff(0.f); c->m_batchIdx = pairIndex; - c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass==0?-bodyIndexA:bodyIndexA; - c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass==0?-bodyIndexB:bodyIndexB; - for (int i=0;im_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass == 0 ? -bodyIndexA : bodyIndexA; + c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass == 0 ? -bodyIndexB : bodyIndexB; + for (int i = 0; i < numReducedPoints; i++) { b3Vector3 pOnB1 = contactPoints[contactIdx.s[i]]; c->m_worldPosB[i] = pOnB1; } c->m_worldNormalOnB.w = (b3Scalar)numReducedPoints; - }//if (dstIdx < numPairs) - } - + } //if (dstIdx < numPairs) + } - -// printf("computeContactPlaneConvex\n"); + // printf("computeContactPlaneConvex\n"); } - - -B3_FORCE_INLINE b3Vector3 MyUnQuantize(const unsigned short* vecIn, const b3Vector3& quantization, const b3Vector3& bvhAabbMin) - { - b3Vector3 vecOut; - vecOut.setValue( - (b3Scalar)(vecIn[0]) / (quantization.x), - (b3Scalar)(vecIn[1]) / (quantization.y), - (b3Scalar)(vecIn[2]) / (quantization.z)); - vecOut += bvhAabbMin; - return vecOut; - } +B3_FORCE_INLINE b3Vector3 MyUnQuantize(const unsigned short* vecIn, const b3Vector3& quantization, const b3Vector3& bvhAabbMin) +{ + b3Vector3 vecOut; + vecOut.setValue( + (b3Scalar)(vecIn[0]) / (quantization.x), + (b3Scalar)(vecIn[1]) / (quantization.y), + (b3Scalar)(vecIn[2]) / (quantization.z)); + vecOut += bvhAabbMin; + return vecOut; +} void traverseTreeTree() { - } #include "Bullet3Common/shared/b3Mat3x3.h" @@ -1503,44 +1416,40 @@ int maxNumAabbChecks = 0; int maxDepth = 0; // work-in-progress -__kernel void findCompoundPairsKernel( +__kernel void findCompoundPairsKernel( int pairIndex, int bodyIndexA, int bodyIndexB, int collidableIndexA, int collidableIndexB, - __global const b3RigidBodyData* rigidBodies, + __global const b3RigidBodyData* rigidBodies, __global const b3Collidable* collidables, - __global const b3ConvexPolyhedronData* convexShapes, + __global const b3ConvexPolyhedronData* convexShapes, __global const b3AlignedObjectArray& vertices, __global const b3AlignedObjectArray& aabbsWorldSpace, __global const b3AlignedObjectArray& aabbsLocalSpace, __global const b3GpuChildShape* gpuChildShapes, __global b3Int4* gpuCompoundPairsOut, - __global int* numCompoundPairsOut, + __global int* numCompoundPairsOut, int maxNumCompoundPairsCapacity, - b3AlignedObjectArray& treeNodesCPU, - b3AlignedObjectArray& subTreesCPU, - b3AlignedObjectArray& bvhInfoCPU - ) + b3AlignedObjectArray& treeNodesCPU, + b3AlignedObjectArray& subTreesCPU, + b3AlignedObjectArray& bvhInfoCPU) { - numAabbChecks=0; - maxNumAabbChecks=0; -// int i = pairIndex; + numAabbChecks = 0; + maxNumAabbChecks = 0; + // int i = pairIndex; { - - int shapeIndexA = collidables[collidableIndexA].m_shapeIndex; int shapeIndexB = collidables[collidableIndexB].m_shapeIndex; - //once the broadphase avoids static-static pairs, we can remove this test - if ((rigidBodies[bodyIndexA].m_invMass==0) &&(rigidBodies[bodyIndexB].m_invMass==0)) + if ((rigidBodies[bodyIndexA].m_invMass == 0) && (rigidBodies[bodyIndexB].m_invMass == 0)) { return; } - if ((collidables[collidableIndexA].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS) &&(collidables[collidableIndexB].m_shapeType==SHAPE_COMPOUND_OF_CONVEX_HULLS)) + if ((collidables[collidableIndexA].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS) && (collidables[collidableIndexB].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS)) { int bvhA = collidables[collidableIndexA].m_compoundBvhIndex; int bvhB = collidables[collidableIndexB].m_compoundBvhIndex; @@ -1548,9 +1457,8 @@ __kernel void findCompoundPairsKernel( int subTreesOffsetA = bvhInfoCPU[bvhA].m_subTreeOffset; int subTreesOffsetB = bvhInfoCPU[bvhB].m_subTreeOffset; - int numSubTreesB = bvhInfoCPU[bvhB].m_numSubTrees; - + float4 posA = rigidBodies[bodyIndexA].m_pos; b3Quat ornA = rigidBodies[bodyIndexA].m_quat; @@ -1567,41 +1475,37 @@ __kernel void findCompoundPairsKernel( transB.setOrigin(posB); transB.setRotation(ornB); - - - for (int p=0;p nodeStack; b3Int2 node0; @@ -1610,33 +1514,33 @@ __kernel void findCompoundPairsKernel( int maxStackDepth = 1024; nodeStack.resize(maxStackDepth); - int depth=0; - nodeStack[depth++]=node0; + int depth = 0; + nodeStack[depth++] = node0; do { if (depth > maxDepth) { - maxDepth=depth; - printf("maxDepth=%d\n",maxDepth); + maxDepth = depth; + printf("maxDepth=%d\n", maxDepth); } b3Int2 node = nodeStack[--depth]; - - b3Vector3 aMinLocal = MyUnQuantize(treeNodesCPU[node.x].m_quantizedAabbMin,bvhInfoCPU[bvhA].m_quantization,bvhInfoCPU[bvhA].m_aabbMin); - b3Vector3 aMaxLocal = MyUnQuantize(treeNodesCPU[node.x].m_quantizedAabbMax,bvhInfoCPU[bvhA].m_quantization,bvhInfoCPU[bvhA].m_aabbMin); - b3Vector3 bMinLocal = MyUnQuantize(treeNodesCPU[node.y].m_quantizedAabbMin,bvhInfoCPU[bvhB].m_quantization,bvhInfoCPU[bvhB].m_aabbMin); - b3Vector3 bMaxLocal = MyUnQuantize(treeNodesCPU[node.y].m_quantizedAabbMax,bvhInfoCPU[bvhB].m_quantization,bvhInfoCPU[bvhB].m_aabbMin); + b3Vector3 aMinLocal = MyUnQuantize(treeNodesCPU[node.x].m_quantizedAabbMin, bvhInfoCPU[bvhA].m_quantization, bvhInfoCPU[bvhA].m_aabbMin); + b3Vector3 aMaxLocal = MyUnQuantize(treeNodesCPU[node.x].m_quantizedAabbMax, bvhInfoCPU[bvhA].m_quantization, bvhInfoCPU[bvhA].m_aabbMin); - float margin=0.f; - b3Vector3 aabbAMinOut,aabbAMaxOut; - b3TransformAabb2(aMinLocal,aMaxLocal, margin,transA.getOrigin(),transA.getRotation(),&aabbAMinOut,&aabbAMaxOut); + b3Vector3 bMinLocal = MyUnQuantize(treeNodesCPU[node.y].m_quantizedAabbMin, bvhInfoCPU[bvhB].m_quantization, bvhInfoCPU[bvhB].m_aabbMin); + b3Vector3 bMaxLocal = MyUnQuantize(treeNodesCPU[node.y].m_quantizedAabbMax, bvhInfoCPU[bvhB].m_quantization, bvhInfoCPU[bvhB].m_aabbMin); - b3Vector3 aabbBMinOut,aabbBMaxOut; - b3TransformAabb2(bMinLocal,bMaxLocal, margin,transB.getOrigin(),transB.getRotation(),&aabbBMinOut,&aabbBMaxOut); + float margin = 0.f; + b3Vector3 aabbAMinOut, aabbAMaxOut; + b3TransformAabb2(aMinLocal, aMaxLocal, margin, transA.getOrigin(), transA.getRotation(), &aabbAMinOut, &aabbAMaxOut); + + b3Vector3 aabbBMinOut, aabbBMaxOut; + b3TransformAabb2(bMinLocal, bMaxLocal, margin, transB.getOrigin(), transB.getRotation(), &aabbBMinOut, &aabbBMaxOut); numAabbChecks++; - bool nodeOverlap = b3TestAabbAgainstAabb(aabbAMinOut,aabbAMaxOut,aabbBMinOut,aabbBMaxOut); + bool nodeOverlap = b3TestAabbAgainstAabb(aabbAMinOut, aabbAMaxOut, aabbBMinOut, aabbBMaxOut); if (nodeOverlap) { bool isLeafA = treeNodesCPU[node.x].isLeafNode(); @@ -1645,23 +1549,23 @@ __kernel void findCompoundPairsKernel( bool isInternalB = !isLeafB; //fail, even though it might hit two leaf nodes - if (depth+4>maxStackDepth && !(isLeafA && isLeafB)) + if (depth + 4 > maxStackDepth && !(isLeafA && isLeafB)) { b3Error("Error: traversal exceeded maxStackDepth\n"); continue; } - if(isInternalA) + if (isInternalA) { - int nodeAleftChild = node.x+1; - bool isNodeALeftChildLeaf = treeNodesCPU[node.x+1].isLeafNode(); - int nodeArightChild = isNodeALeftChildLeaf? node.x+2 : node.x+1 + treeNodesCPU[node.x+1].getEscapeIndex(); + int nodeAleftChild = node.x + 1; + bool isNodeALeftChildLeaf = treeNodesCPU[node.x + 1].isLeafNode(); + int nodeArightChild = isNodeALeftChildLeaf ? node.x + 2 : node.x + 1 + treeNodesCPU[node.x + 1].getEscapeIndex(); - if(isInternalB) - { - int nodeBleftChild = node.y+1; - bool isNodeBLeftChildLeaf = treeNodesCPU[node.y+1].isLeafNode(); - int nodeBrightChild = isNodeBLeftChildLeaf? node.y+2 : node.y+1 + treeNodesCPU[node.y+1].getEscapeIndex(); + if (isInternalB) + { + int nodeBleftChild = node.y + 1; + bool isNodeBLeftChildLeaf = treeNodesCPU[node.y + 1].isLeafNode(); + int nodeBrightChild = isNodeBLeftChildLeaf ? node.y + 2 : node.y + 1 + treeNodesCPU[node.y + 1].getEscapeIndex(); nodeStack[depth++] = b3MakeInt2(nodeAleftChild, nodeBleftChild); nodeStack[depth++] = b3MakeInt2(nodeArightChild, nodeBleftChild); @@ -1670,90 +1574,83 @@ __kernel void findCompoundPairsKernel( } else { - nodeStack[depth++] = b3MakeInt2(nodeAleftChild,node.y); - nodeStack[depth++] = b3MakeInt2(nodeArightChild,node.y); + nodeStack[depth++] = b3MakeInt2(nodeAleftChild, node.y); + nodeStack[depth++] = b3MakeInt2(nodeArightChild, node.y); } } else { - if(isInternalB) + if (isInternalB) { - int nodeBleftChild = node.y+1; - bool isNodeBLeftChildLeaf = treeNodesCPU[node.y+1].isLeafNode(); - int nodeBrightChild = isNodeBLeftChildLeaf? node.y+2 : node.y+1 + treeNodesCPU[node.y+1].getEscapeIndex(); - nodeStack[depth++] = b3MakeInt2(node.x,nodeBleftChild); - nodeStack[depth++] = b3MakeInt2(node.x,nodeBrightChild); + int nodeBleftChild = node.y + 1; + bool isNodeBLeftChildLeaf = treeNodesCPU[node.y + 1].isLeafNode(); + int nodeBrightChild = isNodeBLeftChildLeaf ? node.y + 2 : node.y + 1 + treeNodesCPU[node.y + 1].getEscapeIndex(); + nodeStack[depth++] = b3MakeInt2(node.x, nodeBleftChild); + nodeStack[depth++] = b3MakeInt2(node.x, nodeBrightChild); } else { int compoundPairIdx = b3AtomicInc(numCompoundPairsOut); - if (compoundPairIdx& vertices, - __global const b3AlignedObjectArray& uniqueEdges, - __global const b3AlignedObjectArray& faces, - __global const b3AlignedObjectArray& indices, - __global b3Aabb* aabbs, - __global const b3GpuChildShape* gpuChildShapes, - __global b3AlignedObjectArray& gpuCompoundSepNormalsOut, - __global b3AlignedObjectArray& gpuHasCompoundSepNormalsOut, - int numCompoundPairs, - int i - ) +__kernel void processCompoundPairsKernel(__global const b3Int4* gpuCompoundPairs, + __global const b3RigidBodyData* rigidBodies, + __global const b3Collidable* collidables, + __global const b3ConvexPolyhedronData* convexShapes, + __global const b3AlignedObjectArray& vertices, + __global const b3AlignedObjectArray& uniqueEdges, + __global const b3AlignedObjectArray& faces, + __global const b3AlignedObjectArray& indices, + __global b3Aabb* aabbs, + __global const b3GpuChildShape* gpuChildShapes, + __global b3AlignedObjectArray& gpuCompoundSepNormalsOut, + __global b3AlignedObjectArray& gpuHasCompoundSepNormalsOut, + int numCompoundPairs, + int i) { - -// int i = get_global_id(0); - if (i= 0) { collidableIndexA = gpuChildShapes[childShapeIndexA].m_shapeIndex; float4 childPosA = gpuChildShapes[childShapeIndexA].m_childPosition; - b3Quat childOrnA = gpuChildShapes[childShapeIndexA].m_childOrientation; - float4 newPosA = b3QuatRotate(ornA,childPosA)+posA; - b3Quat newOrnA = b3QuatMul(ornA,childOrnA); + b3Quat childOrnA = gpuChildShapes[childShapeIndexA].m_childOrientation; + float4 newPosA = b3QuatRotate(ornA, childPosA) + posA; + b3Quat newOrnA = b3QuatMul(ornA, childOrnA); posA = newPosA; ornA = newOrnA; - } else + } + else { collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx; } - - if (childShapeIndexB>=0) + + if (childShapeIndexB >= 0) { collidableIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex; float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition; b3Quat childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation; - float4 newPosB = b3QuatRotate(ornB,childPosB)+posB; - b3Quat newOrnB = b3QuatMul(ornB,childOrnB); + float4 newPosB = b3QuatRotate(ornB, childPosB) + posB; + b3Quat newOrnB = b3QuatMul(ornB, childOrnB); posB = newPosB; ornB = newOrnB; - } else - { - collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx; } - + else + { + collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx; + } + gpuHasCompoundSepNormalsOut[i] = 0; - + int shapeIndexA = collidables[collidableIndexA].m_shapeIndex; int shapeIndexB = collidables[collidableIndexB].m_shapeIndex; - + int shapeTypeA = collidables[collidableIndexA].m_shapeType; int shapeTypeB = collidables[collidableIndexB].m_shapeType; - if ((shapeTypeA != SHAPE_CONVEX_HULL) || (shapeTypeB != SHAPE_CONVEX_HULL)) { @@ -1959,145 +1851,142 @@ __kernel void processCompoundPairsKernel( __global const b3Int4* gpuCompoundPa } int hasSeparatingAxis = 5; - - // int numFacesA = convexShapes[shapeIndexA].m_numFaces; + + // int numFacesA = convexShapes[shapeIndexA].m_numFaces; float dmin = FLT_MAX; posA.w = 0.f; posB.w = 0.f; float4 c0local = convexShapes[shapeIndexA].m_localCenter; float4 c0 = transform(&c0local, &posA, &ornA); float4 c1local = convexShapes[shapeIndexB].m_localCenter; - float4 c1 = transform(&c1local,&posB,&ornB); + float4 c1 = transform(&c1local, &posB, &ornB); const float4 DeltaC2 = c0 - c1; - float4 sepNormal = make_float4(1,0,0,0); -// bool sepA = findSeparatingAxis( convexShapes[shapeIndexA], convexShapes[shapeIndexB],posA,ornA,posB,ornB,DeltaC2,vertices,uniqueEdges,faces,indices,&sepNormal,&dmin); - bool sepA = findSeparatingAxis( convexShapes[shapeIndexA], convexShapes[shapeIndexB],posA,ornA,posB,ornB,vertices,uniqueEdges,faces,indices,vertices,uniqueEdges,faces,indices,sepNormal);//,&dmin); - + float4 sepNormal = make_float4(1, 0, 0, 0); + // bool sepA = findSeparatingAxis( convexShapes[shapeIndexA], convexShapes[shapeIndexB],posA,ornA,posB,ornB,DeltaC2,vertices,uniqueEdges,faces,indices,&sepNormal,&dmin); + bool sepA = findSeparatingAxis(convexShapes[shapeIndexA], convexShapes[shapeIndexB], posA, ornA, posB, ornB, vertices, uniqueEdges, faces, indices, vertices, uniqueEdges, faces, indices, sepNormal); //,&dmin); + hasSeparatingAxis = 4; if (!sepA) { hasSeparatingAxis = 0; - } else + } + else { - bool sepB = findSeparatingAxis( convexShapes[shapeIndexB],convexShapes[shapeIndexA],posB,ornB,posA,ornA,vertices,uniqueEdges,faces,indices,vertices,uniqueEdges,faces,indices,sepNormal);//,&dmin); + bool sepB = findSeparatingAxis(convexShapes[shapeIndexB], convexShapes[shapeIndexA], posB, ornB, posA, ornA, vertices, uniqueEdges, faces, indices, vertices, uniqueEdges, faces, indices, sepNormal); //,&dmin); if (!sepB) { hasSeparatingAxis = 0; - } else//(!sepB) + } + else //(!sepB) { - bool sepEE = findSeparatingAxisEdgeEdge( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,posB,ornB,DeltaC2,vertices,uniqueEdges,faces,indices,&sepNormal,&dmin); + bool sepEE = findSeparatingAxisEdgeEdge(&convexShapes[shapeIndexA], &convexShapes[shapeIndexB], posA, ornA, posB, ornB, DeltaC2, vertices, uniqueEdges, faces, indices, &sepNormal, &dmin); if (sepEE) { - gpuCompoundSepNormalsOut[i] = sepNormal;//fastNormalize4(sepNormal); - gpuHasCompoundSepNormalsOut[i] = 1; - }//sepEE - }//(!sepB) - }//(!sepA) - - + gpuCompoundSepNormalsOut[i] = sepNormal; //fastNormalize4(sepNormal); + gpuHasCompoundSepNormalsOut[i] = 1; + } //sepEE + } //(!sepB) + } //(!sepA) } - } - -__kernel void clipCompoundsHullHullKernel( __global const b3Int4* gpuCompoundPairs, - __global const b3RigidBodyData* rigidBodies, - __global const b3Collidable* collidables, - __global const b3ConvexPolyhedronData* convexShapes, - __global const b3AlignedObjectArray& vertices, - __global const b3AlignedObjectArray& uniqueEdges, - __global const b3AlignedObjectArray& faces, - __global const b3AlignedObjectArray& indices, - __global const b3GpuChildShape* gpuChildShapes, - __global const b3AlignedObjectArray& gpuCompoundSepNormalsOut, - __global const b3AlignedObjectArray& gpuHasCompoundSepNormalsOut, - __global struct b3Contact4Data* globalContactsOut, - int* nGlobalContactsOut, - int numCompoundPairs, int maxContactCapacity, int i) +__kernel void clipCompoundsHullHullKernel(__global const b3Int4* gpuCompoundPairs, + __global const b3RigidBodyData* rigidBodies, + __global const b3Collidable* collidables, + __global const b3ConvexPolyhedronData* convexShapes, + __global const b3AlignedObjectArray& vertices, + __global const b3AlignedObjectArray& uniqueEdges, + __global const b3AlignedObjectArray& faces, + __global const b3AlignedObjectArray& indices, + __global const b3GpuChildShape* gpuChildShapes, + __global const b3AlignedObjectArray& gpuCompoundSepNormalsOut, + __global const b3AlignedObjectArray& gpuHasCompoundSepNormalsOut, + __global struct b3Contact4Data* globalContactsOut, + int* nGlobalContactsOut, + int numCompoundPairs, int maxContactCapacity, int i) { - -// int i = get_global_id(0); + // int i = get_global_id(0); int pairIndex = i; - + float4 worldVertsB1[64]; float4 worldVertsB2[64]; - int capacityWorldVerts = 64; + int capacityWorldVerts = 64; float4 localContactsOut[64]; - int localContactCapacity=64; - + int localContactCapacity = 64; + float minDist = -1e30f; float maxDist = 0.0f; - if (i= 0) { collidableIndexA = gpuChildShapes[childShapeIndexA].m_shapeIndex; float4 childPosA = gpuChildShapes[childShapeIndexA].m_childPosition; b3Quat childOrnA = gpuChildShapes[childShapeIndexA].m_childOrientation; - float4 newPosA = b3QuatRotate(ornA,childPosA)+posA; - b3Quat newOrnA = b3QuatMul(ornA,childOrnA); + float4 newPosA = b3QuatRotate(ornA, childPosA) + posA; + b3Quat newOrnA = b3QuatMul(ornA, childOrnA); posA = newPosA; ornA = newOrnA; - } else + } + else { collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx; } - - if (childShapeIndexB>=0) + + if (childShapeIndexB >= 0) { collidableIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex; float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition; - b3Quat childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation; - float4 newPosB = b3QuatRotate(ornB,childPosB)+posB; - b3Quat newOrnB = b3QuatMul(ornB,childOrnB); + b3Quat childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation; + float4 newPosB = b3QuatRotate(ornB, childPosB) + posB; + b3Quat newOrnB = b3QuatMul(ornB, childOrnB); posB = newPosB; ornB = newOrnB; - } else - { - collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx; } - + else + { + collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx; + } + int shapeIndexA = collidables[collidableIndexA].m_shapeIndex; int shapeIndexB = collidables[collidableIndexB].m_shapeIndex; - + int numLocalContactsOut = clipHullAgainstHull(gpuCompoundSepNormalsOut[i], - convexShapes[shapeIndexA], convexShapes[shapeIndexB], - posA,ornA, - posB,ornB, - worldVertsB1,worldVertsB2,capacityWorldVerts, - minDist, maxDist, - vertices,faces,indices, - vertices,faces,indices, - localContactsOut,localContactCapacity); - - if (numLocalContactsOut>0) - { + convexShapes[shapeIndexA], convexShapes[shapeIndexB], + posA, ornA, + posB, ornB, + worldVertsB1, worldVertsB2, capacityWorldVerts, + minDist, maxDist, + vertices, faces, indices, + vertices, faces, indices, + localContactsOut, localContactCapacity); + + if (numLocalContactsOut > 0) + { float4 normal = -gpuCompoundSepNormalsOut[i]; int nPoints = numLocalContactsOut; float4* pointsIn = localContactsOut; - b3Int4 contactIdx;// = {-1,-1,-1,-1}; + b3Int4 contactIdx; // = {-1,-1,-1,-1}; contactIdx.s[0] = 0; contactIdx.s[1] = 1; @@ -2105,111 +1994,106 @@ __kernel void clipCompoundsHullHullKernel( __global const b3Int4* gpuCompoundP contactIdx.s[3] = 3; int nReducedContacts = extractManifoldSequentialGlobal(pointsIn, nPoints, normal, &contactIdx); - + int dstIdx; - dstIdx = b3AtomicInc( nGlobalContactsOut); - if ((dstIdx+nReducedContacts) < maxContactCapacity) + dstIdx = b3AtomicInc(nGlobalContactsOut); + if ((dstIdx + nReducedContacts) < maxContactCapacity) { - __global struct b3Contact4Data* c = globalContactsOut+ dstIdx; + __global struct b3Contact4Data* c = globalContactsOut + dstIdx; c->m_worldNormalOnB = -normal; - c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff); + c->m_restituitionCoeffCmp = (0.f * 0xffff); + c->m_frictionCoeffCmp = (0.7f * 0xffff); c->m_batchIdx = pairIndex; int bodyA = gpuCompoundPairs[pairIndex].x; int bodyB = gpuCompoundPairs[pairIndex].y; - c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA; - c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB; + c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass == 0 ? -bodyA : bodyA; + c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass == 0 ? -bodyB : bodyB; c->m_childIndexA = childShapeIndexA; c->m_childIndexB = childShapeIndexB; - for (int i=0;im_worldPosB[i] = pointsIn[contactIdx.s[i]]; } - b3Contact4Data_setNumPoints(c,nReducedContacts); + b3Contact4Data_setNumPoints(c, nReducedContacts); } - - }// if (numContactsOut>0) - }// if (gpuHasCompoundSepNormalsOut[i]) - }// if (i0) + } // if (gpuHasCompoundSepNormalsOut[i]) + } // if (i& hostAabbsWorldSpace, - const b3AlignedObjectArray& hostAabbsLocalSpace, + int bodyIndexA, int bodyIndexB, + int collidableIndexA, int collidableIndexB, + const b3RigidBodyData* rigidBodies, + const b3Collidable* collidables, + const b3ConvexPolyhedronData* convexShapes, + const b3GpuChildShape* cpuChildShapes, + const b3AlignedObjectArray& hostAabbsWorldSpace, + const b3AlignedObjectArray& hostAabbsLocalSpace, - const b3AlignedObjectArray& convexVertices, - const b3AlignedObjectArray& hostUniqueEdges, - const b3AlignedObjectArray& convexIndices, - const b3AlignedObjectArray& faces, - - b3Contact4* globalContactsOut, - int& nGlobalContactsOut, - int maxContactCapacity, - b3AlignedObjectArray& treeNodesCPU, - b3AlignedObjectArray& subTreesCPU, - b3AlignedObjectArray& bvhInfoCPU - ) + const b3AlignedObjectArray& convexVertices, + const b3AlignedObjectArray& hostUniqueEdges, + const b3AlignedObjectArray& convexIndices, + const b3AlignedObjectArray& faces, + + b3Contact4* globalContactsOut, + int& nGlobalContactsOut, + int maxContactCapacity, + b3AlignedObjectArray& treeNodesCPU, + b3AlignedObjectArray& subTreesCPU, + b3AlignedObjectArray& bvhInfoCPU) { - int shapeTypeB = collidables[collidableIndexB].m_shapeType; b3Assert(shapeTypeB == SHAPE_COMPOUND_OF_CONVEX_HULLS); b3AlignedObjectArray cpuCompoundPairsOut; - int numCompoundPairsOut=0; - int maxNumCompoundPairsCapacity = 8192;//1024; + int numCompoundPairsOut = 0; + int maxNumCompoundPairsCapacity = 8192; //1024; cpuCompoundPairsOut.resize(maxNumCompoundPairsCapacity); // work-in-progress - findCompoundPairsKernel( - pairIndex, - bodyIndexA,bodyIndexB, - collidableIndexA,collidableIndexB, - rigidBodies, - collidables, - convexShapes, - convexVertices, - hostAabbsWorldSpace, - hostAabbsLocalSpace, - cpuChildShapes, - &cpuCompoundPairsOut[0], - &numCompoundPairsOut, - maxNumCompoundPairsCapacity , - treeNodesCPU, - subTreesCPU, - bvhInfoCPU - ); + findCompoundPairsKernel( + pairIndex, + bodyIndexA, bodyIndexB, + collidableIndexA, collidableIndexB, + rigidBodies, + collidables, + convexShapes, + convexVertices, + hostAabbsWorldSpace, + hostAabbsLocalSpace, + cpuChildShapes, + &cpuCompoundPairsOut[0], + &numCompoundPairsOut, + maxNumCompoundPairsCapacity, + treeNodesCPU, + subTreesCPU, + bvhInfoCPU); - printf("maxNumAabbChecks=%d\n",maxNumAabbChecks); - if (numCompoundPairsOut>maxNumCompoundPairsCapacity) + printf("maxNumAabbChecks=%d\n", maxNumAabbChecks); + if (numCompoundPairsOut > maxNumCompoundPairsCapacity) { - b3Error("numCompoundPairsOut exceeded maxNumCompoundPairsCapacity (%d)\n",maxNumCompoundPairsCapacity); - numCompoundPairsOut=maxNumCompoundPairsCapacity; + b3Error("numCompoundPairsOut exceeded maxNumCompoundPairsCapacity (%d)\n", maxNumCompoundPairsCapacity); + numCompoundPairsOut = maxNumCompoundPairsCapacity; } b3AlignedObjectArray cpuCompoundSepNormalsOut; b3AlignedObjectArray cpuHasCompoundSepNormalsOut; cpuCompoundSepNormalsOut.resize(numCompoundPairsOut); cpuHasCompoundSepNormalsOut.resize(numCompoundPairsOut); - for (int i=0;im_numVertices;i++) + + for (int i = 0; i < hullB->m_numVertices; i++) { - b3Vector3 vtx = convexVertices[hullB->m_vertexOffset+i]; + b3Vector3 vtx = convexVertices[hullB->m_vertexOffset + i]; float curDot = vtx.dot(planeNormalInConvex); - - if (curDot>maxDot) + if (curDot > maxDot) { - hitVertex=i; - maxDot=curDot; + hitVertex = i; + maxDot = curDot; hitVtx = vtx; //make sure the deepest points is always included - if (numPoints==MAX_PLANE_CONVEX_POINTS) + if (numPoints == MAX_PLANE_CONVEX_POINTS) numPoints--; } - if (numPoints4) + + if (numPoints > 4) { - numReducedPoints = extractManifoldSequentialGlobal( contactPoints, numPoints, planeNormalInConvex, &contactIdx); + numReducedPoints = extractManifoldSequentialGlobal(contactPoints, numPoints, planeNormalInConvex, &contactIdx); } int dstIdx; - // dstIdx = nGlobalContactsOut++;//AppendInc( nGlobalContactsOut, dstIdx ); - - if (numReducedPoints>0) + // dstIdx = nGlobalContactsOut++;//AppendInc( nGlobalContactsOut, dstIdx ); + + if (numReducedPoints > 0) { if (nGlobalContactsOut < maxContactCapacity) { - dstIdx=nGlobalContactsOut; + dstIdx = nGlobalContactsOut; nGlobalContactsOut++; b3Contact4* c = &globalContactsOut[dstIdx]; @@ -2430,48 +2307,37 @@ void computeContactPlaneCompound(int pairIndex, c->setRestituitionCoeff(0.f); c->m_batchIdx = pairIndex; - c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass==0?-bodyIndexA:bodyIndexA; - c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass==0?-bodyIndexB:bodyIndexB; - for (int i=0;im_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass == 0 ? -bodyIndexA : bodyIndexA; + c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass == 0 ? -bodyIndexB : bodyIndexB; + for (int i = 0; i < numReducedPoints; i++) { b3Vector3 pOnB1 = contactPoints[contactIdx.s[i]]; c->m_worldPosB[i] = pOnB1; } c->m_worldNormalOnB.w = (b3Scalar)numReducedPoints; - }//if (dstIdx < numPairs) - } - + } //if (dstIdx < numPairs) + } } - - } - - - - -void computeContactSphereConvex(int pairIndex, - int bodyIndexA, int bodyIndexB, - int collidableIndexA, int collidableIndexB, - const b3RigidBodyData* rigidBodies, - const b3Collidable* collidables, - const b3ConvexPolyhedronData* convexShapes, - const b3Vector3* convexVertices, - const int* convexIndices, - const b3GpuFace* faces, - b3Contact4* globalContactsOut, - int& nGlobalContactsOut, - int maxContactCapacity) +void computeContactSphereConvex(int pairIndex, + int bodyIndexA, int bodyIndexB, + int collidableIndexA, int collidableIndexB, + const b3RigidBodyData* rigidBodies, + const b3Collidable* collidables, + const b3ConvexPolyhedronData* convexShapes, + const b3Vector3* convexVertices, + const int* convexIndices, + const b3GpuFace* faces, + b3Contact4* globalContactsOut, + int& nGlobalContactsOut, + int maxContactCapacity) { - float radius = collidables[collidableIndexA].m_radius; float4 spherePos1 = rigidBodies[bodyIndexA].m_pos; b3Quaternion sphereOrn = rigidBodies[bodyIndexA].m_quat; - - float4 pos = rigidBodies[bodyIndexB].m_pos; - b3Quaternion quat = rigidBodies[bodyIndexB].m_quat; @@ -2487,64 +2353,65 @@ void computeContactSphereConvex(int pairIndex, int shapeIndex = collidables[collidableIndex].m_shapeIndex; int numFaces = convexShapes[shapeIndex].m_numFaces; float4 closestPnt = b3MakeVector3(0, 0, 0, 0); -// float4 hitNormalWorld = b3MakeVector3(0, 0, 0, 0); - float minDist = -1000000.f; // TODO: What is the largest/smallest float? + // float4 hitNormalWorld = b3MakeVector3(0, 0, 0, 0); + float minDist = -1000000.f; // TODO: What is the largest/smallest float? bool bCollide = true; int region = -1; float4 localHitNormal; - for ( int f = 0; f < numFaces; f++ ) + for (int f = 0; f < numFaces; f++) { - b3GpuFace face = faces[convexShapes[shapeIndex].m_faceOffset+f]; + b3GpuFace face = faces[convexShapes[shapeIndex].m_faceOffset + f]; float4 planeEqn; - float4 localPlaneNormal = b3MakeVector3(face.m_plane.x,face.m_plane.y,face.m_plane.z,0.f); - float4 n1 = localPlaneNormal;//quatRotate(quat,localPlaneNormal); + float4 localPlaneNormal = b3MakeVector3(face.m_plane.x, face.m_plane.y, face.m_plane.z, 0.f); + float4 n1 = localPlaneNormal; //quatRotate(quat,localPlaneNormal); planeEqn = n1; planeEqn[3] = face.m_plane.w; float4 pntReturn; float dist = signedDistanceFromPointToPlane(spherePos, planeEqn, &pntReturn); - if ( dist > radius) + if (dist > radius) { bCollide = false; break; } - if ( dist > 0 ) + if (dist > 0) { //might hit an edge or vertex b3Vector3 out; bool isInPoly = IsPointInPolygon(spherePos, - &face, - &convexVertices[convexShapes[shapeIndex].m_vertexOffset], - convexIndices, - &out); + &face, + &convexVertices[convexShapes[shapeIndex].m_vertexOffset], + convexIndices, + &out); if (isInPoly) { - if (dist>minDist) + if (dist > minDist) { minDist = dist; closestPnt = pntReturn; localHitNormal = planeEqn; - region=1; + region = 1; } - } else + } + else { - b3Vector3 tmp = spherePos-out; + b3Vector3 tmp = spherePos - out; b3Scalar l2 = tmp.length2(); - if (l2minDist) + dist = b3Sqrt(l2); + if (dist > minDist) { minDist = dist; closestPnt = out; - localHitNormal = tmp/dist; - region=2; + localHitNormal = tmp / dist; + region = 2; } - - } else + } + else { bCollide = false; break; @@ -2553,12 +2420,12 @@ void computeContactSphereConvex(int pairIndex, } else { - if ( dist > minDist ) + if (dist > minDist) { minDist = dist; closestPnt = pntReturn; localHitNormal = planeEqn; - region=3; + region = 3; } } } @@ -2567,128 +2434,113 @@ void computeContactSphereConvex(int pairIndex, if (bCollide && minDist > -10000) { - - float4 normalOnSurfaceB1 = tr.getBasis()*localHitNormal;//-hitNormalWorld; + float4 normalOnSurfaceB1 = tr.getBasis() * localHitNormal; //-hitNormalWorld; float4 pOnB1 = tr(closestPnt); //printf("dist ,%f,",minDist); - float actualDepth = minDist-radius; - if (actualDepth<0) + float actualDepth = minDist - radius; + if (actualDepth < 0) { - //printf("actualDepth = ,%f,", actualDepth); - //printf("normalOnSurfaceB1 = ,%f,%f,%f,", normalOnSurfaceB1.x,normalOnSurfaceB1.y,normalOnSurfaceB1.z); - //printf("region=,%d,\n", region); - pOnB1[3] = actualDepth; + //printf("actualDepth = ,%f,", actualDepth); + //printf("normalOnSurfaceB1 = ,%f,%f,%f,", normalOnSurfaceB1.x,normalOnSurfaceB1.y,normalOnSurfaceB1.z); + //printf("region=,%d,\n", region); + pOnB1[3] = actualDepth; - int dstIdx; -// dstIdx = nGlobalContactsOut++;//AppendInc( nGlobalContactsOut, dstIdx ); - - if (nGlobalContactsOut < maxContactCapacity) - { - dstIdx=nGlobalContactsOut; - nGlobalContactsOut++; + int dstIdx; + // dstIdx = nGlobalContactsOut++;//AppendInc( nGlobalContactsOut, dstIdx ); - b3Contact4* c = &globalContactsOut[dstIdx]; - c->m_worldNormalOnB = normalOnSurfaceB1; - c->setFrictionCoeff(0.7); - c->setRestituitionCoeff(0.f); + if (nGlobalContactsOut < maxContactCapacity) + { + dstIdx = nGlobalContactsOut; + nGlobalContactsOut++; - c->m_batchIdx = pairIndex; - c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass==0?-bodyIndexA:bodyIndexA; - c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass==0?-bodyIndexB:bodyIndexB; - c->m_worldPosB[0] = pOnB1; - int numPoints = 1; - c->m_worldNormalOnB.w = (b3Scalar)numPoints; - }//if (dstIdx < numPairs) + b3Contact4* c = &globalContactsOut[dstIdx]; + c->m_worldNormalOnB = normalOnSurfaceB1; + c->setFrictionCoeff(0.7); + c->setRestituitionCoeff(0.f); + + c->m_batchIdx = pairIndex; + c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass == 0 ? -bodyIndexA : bodyIndexA; + c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass == 0 ? -bodyIndexB : bodyIndexB; + c->m_worldPosB[0] = pOnB1; + int numPoints = 1; + c->m_worldNormalOnB.w = (b3Scalar)numPoints; + } //if (dstIdx < numPairs) } - }//if (hasCollision) - + } //if (hasCollision) } - - - int computeContactConvexConvex2( - int pairIndex, - int bodyIndexA, int bodyIndexB, - int collidableIndexA, int collidableIndexB, - const b3AlignedObjectArray& rigidBodies, - const b3AlignedObjectArray& collidables, - const b3AlignedObjectArray& convexShapes, - const b3AlignedObjectArray& convexVertices, - const b3AlignedObjectArray& uniqueEdges, - const b3AlignedObjectArray& convexIndices, - const b3AlignedObjectArray& faces, - b3AlignedObjectArray& globalContactsOut, - int& nGlobalContactsOut, - int maxContactCapacity, - const b3AlignedObjectArray& oldContacts - ) + int pairIndex, + int bodyIndexA, int bodyIndexB, + int collidableIndexA, int collidableIndexB, + const b3AlignedObjectArray& rigidBodies, + const b3AlignedObjectArray& collidables, + const b3AlignedObjectArray& convexShapes, + const b3AlignedObjectArray& convexVertices, + const b3AlignedObjectArray& uniqueEdges, + const b3AlignedObjectArray& convexIndices, + const b3AlignedObjectArray& faces, + b3AlignedObjectArray& globalContactsOut, + int& nGlobalContactsOut, + int maxContactCapacity, + const b3AlignedObjectArray& oldContacts) { int contactIndex = -1; b3Vector3 posA = rigidBodies[bodyIndexA].m_pos; b3Quaternion ornA = rigidBodies[bodyIndexA].m_quat; b3Vector3 posB = rigidBodies[bodyIndexB].m_pos; b3Quaternion ornB = rigidBodies[bodyIndexB].m_quat; - b3ConvexPolyhedronData hullA, hullB; - + b3Vector3 sepNormalWorldSpace; - + b3Collidable colA = collidables[collidableIndexA]; + hullA = convexShapes[colA.m_shapeIndex]; + //printf("numvertsA = %d\n",hullA.m_numVertices); - b3Collidable colA = collidables[collidableIndexA]; - hullA = convexShapes[colA.m_shapeIndex]; - //printf("numvertsA = %d\n",hullA.m_numVertices); - - - b3Collidable colB = collidables[collidableIndexB]; - hullB = convexShapes[colB.m_shapeIndex]; - //printf("numvertsB = %d\n",hullB.m_numVertices); + b3Collidable colB = collidables[collidableIndexB]; + hullB = convexShapes[colB.m_shapeIndex]; + //printf("numvertsB = %d\n",hullB.m_numVertices); -// int contactCapacity = MAX_VERTS; + // int contactCapacity = MAX_VERTS; //int numContactsOut=0; - #ifdef _WIN32 b3Assert(_finite(rigidBodies[bodyIndexA].m_pos.x)); b3Assert(_finite(rigidBodies[bodyIndexB].m_pos.x)); #endif - - bool foundSepAxis = findSeparatingAxis(hullA,hullB, - posA, - ornA, - posB, - ornB, - convexVertices,uniqueEdges,faces,convexIndices, - convexVertices,uniqueEdges,faces,convexIndices, - - sepNormalWorldSpace - ); + bool foundSepAxis = findSeparatingAxis(hullA, hullB, + posA, + ornA, + posB, + ornB, + + convexVertices, uniqueEdges, faces, convexIndices, + convexVertices, uniqueEdges, faces, convexIndices, + + sepNormalWorldSpace); - if (foundSepAxis) { - - contactIndex = clipHullHullSingle( bodyIndexA, bodyIndexB, - posA,ornA, - posB,ornB, + posA, ornA, + posB, ornB, collidableIndexA, collidableIndexB, - &rigidBodies, + &rigidBodies, &globalContactsOut, nGlobalContactsOut, - + convexShapes, convexShapes, - - convexVertices, - uniqueEdges, + + convexVertices, + uniqueEdges, faces, convexIndices, - + convexVertices, uniqueEdges, faces, @@ -2698,50 +2550,42 @@ int computeContactConvexConvex2( collidables, sepNormalWorldSpace, maxContactCapacity); - } return contactIndex; } +void GpuSatCollision::computeConvexConvexContactsGPUSAT(b3OpenCLArray* pairs, int nPairs, + const b3OpenCLArray* bodyBuf, + b3OpenCLArray* contactOut, int& nContacts, + const b3OpenCLArray* oldContacts, + int maxContactCapacity, + int compoundPairCapacity, + const b3OpenCLArray& convexData, + const b3OpenCLArray& gpuVertices, + const b3OpenCLArray& gpuUniqueEdges, + const b3OpenCLArray& gpuFaces, + const b3OpenCLArray& gpuIndices, + const b3OpenCLArray& gpuCollidables, + const b3OpenCLArray& gpuChildShapes, + const b3OpenCLArray& clAabbsWorldSpace, + const b3OpenCLArray& clAabbsLocalSpace, + b3OpenCLArray& worldVertsB1GPU, + b3OpenCLArray& clippingFacesOutGPU, + b3OpenCLArray& worldNormalsAGPU, + b3OpenCLArray& worldVertsA1GPU, + b3OpenCLArray& worldVertsB2GPU, + b3AlignedObjectArray& bvhDataUnused, + b3OpenCLArray* treeNodesGPU, + b3OpenCLArray* subTreesGPU, + b3OpenCLArray* bvhInfo, - - - -void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* pairs, int nPairs, - const b3OpenCLArray* bodyBuf, - b3OpenCLArray* contactOut, int& nContacts, - const b3OpenCLArray* oldContacts, - int maxContactCapacity, - int compoundPairCapacity, - const b3OpenCLArray& convexData, - const b3OpenCLArray& gpuVertices, - const b3OpenCLArray& gpuUniqueEdges, - const b3OpenCLArray& gpuFaces, - const b3OpenCLArray& gpuIndices, - const b3OpenCLArray& gpuCollidables, - const b3OpenCLArray& gpuChildShapes, - - const b3OpenCLArray& clAabbsWorldSpace, - const b3OpenCLArray& clAabbsLocalSpace, - - b3OpenCLArray& worldVertsB1GPU, - b3OpenCLArray& clippingFacesOutGPU, - b3OpenCLArray& worldNormalsAGPU, - b3OpenCLArray& worldVertsA1GPU, - b3OpenCLArray& worldVertsB2GPU, - b3AlignedObjectArray& bvhDataUnused, - b3OpenCLArray* treeNodesGPU, - b3OpenCLArray* subTreesGPU, - b3OpenCLArray* bvhInfo, - - int numObjects, - int maxTriConvexPairCapacity, - b3OpenCLArray& triangleConvexPairsOut, - int& numTriConvexPairsOut - ) + int numObjects, + int maxTriConvexPairCapacity, + b3OpenCLArray& triangleConvexPairsOut, + int& numTriConvexPairsOut) { myframecount++; @@ -2750,14 +2594,13 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* #ifdef CHECK_ON_HOST - - b3AlignedObjectArray treeNodesCPU; + b3AlignedObjectArray treeNodesCPU; treeNodesGPU->copyToHost(treeNodesCPU); - b3AlignedObjectArray subTreesCPU; + b3AlignedObjectArray subTreesCPU; subTreesGPU->copyToHost(subTreesCPU); - b3AlignedObjectArray bvhInfoCPU; + b3AlignedObjectArray bvhInfoCPU; bvhInfo->copyToHost(bvhInfoCPU); b3AlignedObjectArray hostAabbsWorldSpace; @@ -2772,8 +2615,6 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* b3AlignedObjectArray hostBodyBuf; bodyBuf->copyToHost(hostBodyBuf); - - b3AlignedObjectArray hostConvexData; convexData.copyToHost(hostConvexData); @@ -2788,10 +2629,9 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* gpuIndices.copyToHost(hostIndices); b3AlignedObjectArray hostCollidables; gpuCollidables.copyToHost(hostCollidables); - + b3AlignedObjectArray cpuChildShapes; gpuChildShapes.copyToHost(cpuChildShapes); - b3AlignedObjectArray hostTriangleConvexPairs; @@ -2802,16 +2642,15 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* } b3AlignedObjectArray oldHostContacts; - + if (oldContacts->size()) { oldContacts->copyToHost(oldHostContacts); } - hostContacts.resize(maxContactCapacity); - for (int i=0;i* if (hostCollidables[collidableIndexA].m_shapeType == SHAPE_SPHERE && hostCollidables[collidableIndexB].m_shapeType == SHAPE_CONVEX_HULL) { - computeContactSphereConvex(i,bodyIndexA,bodyIndexB,collidableIndexA,collidableIndexB,&hostBodyBuf[0], - &hostCollidables[0],&hostConvexData[0],&hostVertices[0],&hostIndices[0],&hostFaces[0],&hostContacts[0],nContacts,maxContactCapacity); + computeContactSphereConvex(i, bodyIndexA, bodyIndexB, collidableIndexA, collidableIndexB, &hostBodyBuf[0], + &hostCollidables[0], &hostConvexData[0], &hostVertices[0], &hostIndices[0], &hostFaces[0], &hostContacts[0], nContacts, maxContactCapacity); } if (hostCollidables[collidableIndexA].m_shapeType == SHAPE_CONVEX_HULL && hostCollidables[collidableIndexB].m_shapeType == SHAPE_SPHERE) { - computeContactSphereConvex(i,bodyIndexB,bodyIndexA,collidableIndexB,collidableIndexA,&hostBodyBuf[0], - &hostCollidables[0],&hostConvexData[0],&hostVertices[0],&hostIndices[0],&hostFaces[0],&hostContacts[0],nContacts,maxContactCapacity); + computeContactSphereConvex(i, bodyIndexB, bodyIndexA, collidableIndexB, collidableIndexA, &hostBodyBuf[0], + &hostCollidables[0], &hostConvexData[0], &hostVertices[0], &hostIndices[0], &hostFaces[0], &hostContacts[0], nContacts, maxContactCapacity); //printf("convex-sphere\n"); - } if (hostCollidables[collidableIndexA].m_shapeType == SHAPE_CONVEX_HULL && hostCollidables[collidableIndexB].m_shapeType == SHAPE_PLANE) { - computeContactPlaneConvex(i,bodyIndexB,bodyIndexA,collidableIndexB,collidableIndexA,&hostBodyBuf[0], - &hostCollidables[0],&hostConvexData[0],&hostVertices[0],&hostIndices[0],&hostFaces[0],&hostContacts[0],nContacts,maxContactCapacity); -// printf("convex-plane\n"); - + computeContactPlaneConvex(i, bodyIndexB, bodyIndexA, collidableIndexB, collidableIndexA, &hostBodyBuf[0], + &hostCollidables[0], &hostConvexData[0], &hostVertices[0], &hostIndices[0], &hostFaces[0], &hostContacts[0], nContacts, maxContactCapacity); + // printf("convex-plane\n"); } if (hostCollidables[collidableIndexA].m_shapeType == SHAPE_PLANE && hostCollidables[collidableIndexB].m_shapeType == SHAPE_CONVEX_HULL) { - computeContactPlaneConvex(i,bodyIndexA,bodyIndexB,collidableIndexA,collidableIndexB,&hostBodyBuf[0], - &hostCollidables[0],&hostConvexData[0],&hostVertices[0],&hostIndices[0],&hostFaces[0],&hostContacts[0],nContacts,maxContactCapacity); -// printf("plane-convex\n"); - + computeContactPlaneConvex(i, bodyIndexA, bodyIndexB, collidableIndexA, collidableIndexB, &hostBodyBuf[0], + &hostCollidables[0], &hostConvexData[0], &hostVertices[0], &hostIndices[0], &hostFaces[0], &hostContacts[0], nContacts, maxContactCapacity); + // printf("plane-convex\n"); } - if (hostCollidables[collidableIndexA].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS && + if (hostCollidables[collidableIndexA].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS && hostCollidables[collidableIndexB].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS) { - computeContactCompoundCompound(i,bodyIndexB,bodyIndexA,collidableIndexB,collidableIndexA,&hostBodyBuf[0], - &hostCollidables[0],&hostConvexData[0],&cpuChildShapes[0], hostAabbsWorldSpace,hostAabbsLocalSpace,hostVertices,hostUniqueEdges,hostIndices,hostFaces,&hostContacts[0], - nContacts,maxContactCapacity,treeNodesCPU,subTreesCPU,bvhInfoCPU); -// printf("convex-plane\n"); - + computeContactCompoundCompound(i, bodyIndexB, bodyIndexA, collidableIndexB, collidableIndexA, &hostBodyBuf[0], + &hostCollidables[0], &hostConvexData[0], &cpuChildShapes[0], hostAabbsWorldSpace, hostAabbsLocalSpace, hostVertices, hostUniqueEdges, hostIndices, hostFaces, &hostContacts[0], + nContacts, maxContactCapacity, treeNodesCPU, subTreesCPU, bvhInfoCPU); + // printf("convex-plane\n"); } - - if (hostCollidables[collidableIndexA].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS && + if (hostCollidables[collidableIndexA].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS && hostCollidables[collidableIndexB].m_shapeType == SHAPE_PLANE) { - computeContactPlaneCompound(i,bodyIndexB,bodyIndexA,collidableIndexB,collidableIndexA,&hostBodyBuf[0], - &hostCollidables[0],&hostConvexData[0],&cpuChildShapes[0], &hostVertices[0],&hostIndices[0],&hostFaces[0],&hostContacts[0],nContacts,maxContactCapacity); -// printf("convex-plane\n"); - + computeContactPlaneCompound(i, bodyIndexB, bodyIndexA, collidableIndexB, collidableIndexA, &hostBodyBuf[0], + &hostCollidables[0], &hostConvexData[0], &cpuChildShapes[0], &hostVertices[0], &hostIndices[0], &hostFaces[0], &hostContacts[0], nContacts, maxContactCapacity); + // printf("convex-plane\n"); } if (hostCollidables[collidableIndexA].m_shapeType == SHAPE_PLANE && hostCollidables[collidableIndexB].m_shapeType == SHAPE_COMPOUND_OF_CONVEX_HULLS) { - computeContactPlaneCompound(i,bodyIndexA,bodyIndexB,collidableIndexA,collidableIndexB,&hostBodyBuf[0], - &hostCollidables[0],&hostConvexData[0],&cpuChildShapes[0],&hostVertices[0],&hostIndices[0],&hostFaces[0],&hostContacts[0],nContacts,maxContactCapacity); -// printf("plane-convex\n"); - + computeContactPlaneCompound(i, bodyIndexA, bodyIndexB, collidableIndexA, collidableIndexB, &hostBodyBuf[0], + &hostCollidables[0], &hostConvexData[0], &cpuChildShapes[0], &hostVertices[0], &hostIndices[0], &hostFaces[0], &hostContacts[0], nContacts, maxContactCapacity); + // printf("plane-convex\n"); } if (hostCollidables[collidableIndexA].m_shapeType == SHAPE_CONVEX_HULL && hostCollidables[collidableIndexB].m_shapeType == SHAPE_CONVEX_HULL) { //printf("hostPairs[i].z=%d\n",hostPairs[i].z); - int contactIndex = computeContactConvexConvex2( i,bodyIndexA,bodyIndexB,collidableIndexA,collidableIndexB,hostBodyBuf, hostCollidables,hostConvexData,hostVertices,hostUniqueEdges,hostIndices,hostFaces,hostContacts,nContacts,maxContactCapacity,oldHostContacts); + int contactIndex = computeContactConvexConvex2(i, bodyIndexA, bodyIndexB, collidableIndexA, collidableIndexB, hostBodyBuf, hostCollidables, hostConvexData, hostVertices, hostUniqueEdges, hostIndices, hostFaces, hostContacts, nContacts, maxContactCapacity, oldHostContacts); //int contactIndex = computeContactConvexConvex(hostPairs,i,bodyIndexA,bodyIndexB,collidableIndexA,collidableIndexB,hostBodyBuf,hostCollidables,hostConvexData,hostVertices,hostUniqueEdges,hostIndices,hostFaces,hostContacts,nContacts,maxContactCapacity,oldHostContacts); - - if (contactIndex>=0) + if (contactIndex >= 0) { -// printf("convex convex contactIndex = %d\n",contactIndex); + // printf("convex convex contactIndex = %d\n",contactIndex); hostPairs[i].z = contactIndex; } -// printf("plane-convex\n"); - + // printf("plane-convex\n"); } - - } if (hostPairs.size()) @@ -2908,81 +2736,76 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* hostContacts.resize(nContacts); if (nContacts) - { - - contactOut->copyFromHost(hostContacts); - } else + { + contactOut->copyFromHost(hostContacts); + } + else { contactOut->resize(0); - } + } - m_totalContactsOut.copyFromHostPointer(&nContacts,1,0,true); - //printf("(HOST) nContacts = %d\n",nContacts); + m_totalContactsOut.copyFromHostPointer(&nContacts, 1, 0, true); + //printf("(HOST) nContacts = %d\n",nContacts); #else { if (nPairs) { - m_totalContactsOut.copyFromHostPointer(&nContacts,1,0,true); + m_totalContactsOut.copyFromHostPointer(&nContacts, 1, 0, true); B3_PROFILE("primitiveContactsKernel"); b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( pairs->getBufferCL(), true ), - b3BufferInfoCL( bodyBuf->getBufferCL(),true), - b3BufferInfoCL( gpuCollidables.getBufferCL(),true), - b3BufferInfoCL( convexData.getBufferCL(),true), - b3BufferInfoCL( gpuVertices.getBufferCL(),true), - b3BufferInfoCL( gpuUniqueEdges.getBufferCL(),true), - b3BufferInfoCL( gpuFaces.getBufferCL(),true), - b3BufferInfoCL( gpuIndices.getBufferCL(),true), - b3BufferInfoCL( contactOut->getBufferCL()), - b3BufferInfoCL( m_totalContactsOut.getBufferCL()) - }; - - b3LauncherCL launcher(m_queue, m_primitiveContactsKernel,"m_primitiveContactsKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( nPairs ); + b3BufferInfoCL(pairs->getBufferCL(), true), + b3BufferInfoCL(bodyBuf->getBufferCL(), true), + b3BufferInfoCL(gpuCollidables.getBufferCL(), true), + b3BufferInfoCL(convexData.getBufferCL(), true), + b3BufferInfoCL(gpuVertices.getBufferCL(), true), + b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true), + b3BufferInfoCL(gpuFaces.getBufferCL(), true), + b3BufferInfoCL(gpuIndices.getBufferCL(), true), + b3BufferInfoCL(contactOut->getBufferCL()), + b3BufferInfoCL(m_totalContactsOut.getBufferCL())}; + + b3LauncherCL launcher(m_queue, m_primitiveContactsKernel, "m_primitiveContactsKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(nPairs); launcher.setConst(maxContactCapacity); int num = nPairs; - launcher.launch1D( num); + launcher.launch1D(num); clFinish(m_queue); - + nContacts = m_totalContactsOut.at(0); contactOut->resize(nContacts); } } - -#endif//CHECK_ON_HOST - +#endif //CHECK_ON_HOST + B3_PROFILE("computeConvexConvexContactsGPUSAT"); - // printf("nContacts = %d\n",nContacts); - - + // printf("nContacts = %d\n",nContacts); + m_sepNormals.resize(nPairs); m_hasSeparatingNormals.resize(nPairs); - - int concaveCapacity=maxTriConvexPairCapacity; + + int concaveCapacity = maxTriConvexPairCapacity; m_concaveSepNormals.resize(concaveCapacity); m_concaveHasSeparatingNormals.resize(concaveCapacity); m_numConcavePairsOut.resize(0); m_numConcavePairsOut.push_back(0); - m_gpuCompoundPairs.resize(compoundPairCapacity); m_gpuCompoundSepNormals.resize(compoundPairCapacity); - - + m_gpuHasCompoundSepNormals.resize(compoundPairCapacity); - + m_numCompoundPairsOut.resize(0); m_numCompoundPairsOut.push_back(0); int numCompoundPairs = 0; - int numConcavePairs =0; + int numConcavePairs = 0; { clFinish(m_queue); @@ -2991,33 +2814,30 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* m_dmins.resize(nPairs); if (splitSearchSepAxisConvex) { - - if (useMprGpu) { nContacts = m_totalContactsOut.at(0); { B3_PROFILE("mprPenetrationKernel"); - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( pairs->getBufferCL(), true ), - b3BufferInfoCL( bodyBuf->getBufferCL(),true), - b3BufferInfoCL( gpuCollidables.getBufferCL(),true), - b3BufferInfoCL( convexData.getBufferCL(),true), - b3BufferInfoCL( gpuVertices.getBufferCL(),true), - b3BufferInfoCL( m_sepNormals.getBufferCL()), - b3BufferInfoCL( m_hasSeparatingNormals.getBufferCL()), - b3BufferInfoCL( contactOut->getBufferCL()), - b3BufferInfoCL( m_totalContactsOut.getBufferCL()) - }; + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(pairs->getBufferCL(), true), + b3BufferInfoCL(bodyBuf->getBufferCL(), true), + b3BufferInfoCL(gpuCollidables.getBufferCL(), true), + b3BufferInfoCL(convexData.getBufferCL(), true), + b3BufferInfoCL(gpuVertices.getBufferCL(), true), + b3BufferInfoCL(m_sepNormals.getBufferCL()), + b3BufferInfoCL(m_hasSeparatingNormals.getBufferCL()), + b3BufferInfoCL(contactOut->getBufferCL()), + b3BufferInfoCL(m_totalContactsOut.getBufferCL())}; - b3LauncherCL launcher(m_queue, m_mprPenetrationKernel,"mprPenetrationKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); + b3LauncherCL launcher(m_queue, m_mprPenetrationKernel, "mprPenetrationKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); launcher.setConst(maxContactCapacity); - launcher.setConst( nPairs ); + launcher.setConst(nPairs); int num = nPairs; - launcher.launch1D( num); + launcher.launch1D(num); clFinish(m_queue); /* b3AlignedObjectArrayhostHasSepAxis; @@ -3027,173 +2847,160 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* */ nContacts = m_totalContactsOut.at(0); contactOut->resize(nContacts); - // printf("nContacts (after mprPenetrationKernel) = %d\n",nContacts); - if (nContacts>maxContactCapacity) + // printf("nContacts (after mprPenetrationKernel) = %d\n",nContacts); + if (nContacts > maxContactCapacity) { - b3Error("Error: contacts exceeds capacity (%d/%d)\n", nContacts, maxContactCapacity); nContacts = maxContactCapacity; } - } } - + if (1) { - if (1) { - { - B3_PROFILE("findSeparatingAxisVertexFaceKernel"); - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( pairs->getBufferCL(), true ), - b3BufferInfoCL( bodyBuf->getBufferCL(),true), - b3BufferInfoCL( gpuCollidables.getBufferCL(),true), - b3BufferInfoCL( convexData.getBufferCL(),true), - b3BufferInfoCL( gpuVertices.getBufferCL(),true), - b3BufferInfoCL( gpuUniqueEdges.getBufferCL(),true), - b3BufferInfoCL( gpuFaces.getBufferCL(),true), - b3BufferInfoCL( gpuIndices.getBufferCL(),true), - b3BufferInfoCL( clAabbsWorldSpace.getBufferCL(),true), - b3BufferInfoCL( m_sepNormals.getBufferCL()), - b3BufferInfoCL( m_hasSeparatingNormals.getBufferCL()), - b3BufferInfoCL( m_dmins.getBufferCL()) - }; + { + B3_PROFILE("findSeparatingAxisVertexFaceKernel"); + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(pairs->getBufferCL(), true), + b3BufferInfoCL(bodyBuf->getBufferCL(), true), + b3BufferInfoCL(gpuCollidables.getBufferCL(), true), + b3BufferInfoCL(convexData.getBufferCL(), true), + b3BufferInfoCL(gpuVertices.getBufferCL(), true), + b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true), + b3BufferInfoCL(gpuFaces.getBufferCL(), true), + b3BufferInfoCL(gpuIndices.getBufferCL(), true), + b3BufferInfoCL(clAabbsWorldSpace.getBufferCL(), true), + b3BufferInfoCL(m_sepNormals.getBufferCL()), + b3BufferInfoCL(m_hasSeparatingNormals.getBufferCL()), + b3BufferInfoCL(m_dmins.getBufferCL())}; - b3LauncherCL launcher(m_queue, m_findSeparatingAxisVertexFaceKernel,"findSeparatingAxisVertexFaceKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( nPairs ); + b3LauncherCL launcher(m_queue, m_findSeparatingAxisVertexFaceKernel, "findSeparatingAxisVertexFaceKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(nPairs); - int num = nPairs; - launcher.launch1D( num); - clFinish(m_queue); - } + int num = nPairs; + launcher.launch1D(num); + clFinish(m_queue); + } + int numDirections = sizeof(unitSphere162) / sizeof(b3Vector3); - int numDirections = sizeof(unitSphere162)/sizeof(b3Vector3); - - { - B3_PROFILE("findSeparatingAxisEdgeEdgeKernel"); - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( pairs->getBufferCL(), true ), - b3BufferInfoCL( bodyBuf->getBufferCL(),true), - b3BufferInfoCL( gpuCollidables.getBufferCL(),true), - b3BufferInfoCL( convexData.getBufferCL(),true), - b3BufferInfoCL( gpuVertices.getBufferCL(),true), - b3BufferInfoCL( gpuUniqueEdges.getBufferCL(),true), - b3BufferInfoCL( gpuFaces.getBufferCL(),true), - b3BufferInfoCL( gpuIndices.getBufferCL(),true), - b3BufferInfoCL( clAabbsWorldSpace.getBufferCL(),true), - b3BufferInfoCL( m_sepNormals.getBufferCL()), - b3BufferInfoCL( m_hasSeparatingNormals.getBufferCL()), - b3BufferInfoCL( m_dmins.getBufferCL()), - b3BufferInfoCL( m_unitSphereDirections.getBufferCL(),true) + { + B3_PROFILE("findSeparatingAxisEdgeEdgeKernel"); + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(pairs->getBufferCL(), true), + b3BufferInfoCL(bodyBuf->getBufferCL(), true), + b3BufferInfoCL(gpuCollidables.getBufferCL(), true), + b3BufferInfoCL(convexData.getBufferCL(), true), + b3BufferInfoCL(gpuVertices.getBufferCL(), true), + b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true), + b3BufferInfoCL(gpuFaces.getBufferCL(), true), + b3BufferInfoCL(gpuIndices.getBufferCL(), true), + b3BufferInfoCL(clAabbsWorldSpace.getBufferCL(), true), + b3BufferInfoCL(m_sepNormals.getBufferCL()), + b3BufferInfoCL(m_hasSeparatingNormals.getBufferCL()), + b3BufferInfoCL(m_dmins.getBufferCL()), + b3BufferInfoCL(m_unitSphereDirections.getBufferCL(), true) - }; + }; - b3LauncherCL launcher(m_queue, m_findSeparatingAxisEdgeEdgeKernel,"findSeparatingAxisEdgeEdgeKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( numDirections); - launcher.setConst( nPairs ); - int num = nPairs; - launcher.launch1D( num); - clFinish(m_queue); - - } + b3LauncherCL launcher(m_queue, m_findSeparatingAxisEdgeEdgeKernel, "findSeparatingAxisEdgeEdgeKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(numDirections); + launcher.setConst(nPairs); + int num = nPairs; + launcher.launch1D(num); + clFinish(m_queue); + } } if (useMprGpu) { B3_PROFILE("findSeparatingAxisUnitSphereKernel"); - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( pairs->getBufferCL(), true ), - b3BufferInfoCL( bodyBuf->getBufferCL(),true), - b3BufferInfoCL( gpuCollidables.getBufferCL(),true), - b3BufferInfoCL( convexData.getBufferCL(),true), - b3BufferInfoCL( gpuVertices.getBufferCL(),true), - b3BufferInfoCL( m_unitSphereDirections.getBufferCL(),true), - b3BufferInfoCL( m_sepNormals.getBufferCL()), - b3BufferInfoCL( m_hasSeparatingNormals.getBufferCL()), - b3BufferInfoCL( m_dmins.getBufferCL()) - }; + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(pairs->getBufferCL(), true), + b3BufferInfoCL(bodyBuf->getBufferCL(), true), + b3BufferInfoCL(gpuCollidables.getBufferCL(), true), + b3BufferInfoCL(convexData.getBufferCL(), true), + b3BufferInfoCL(gpuVertices.getBufferCL(), true), + b3BufferInfoCL(m_unitSphereDirections.getBufferCL(), true), + b3BufferInfoCL(m_sepNormals.getBufferCL()), + b3BufferInfoCL(m_hasSeparatingNormals.getBufferCL()), + b3BufferInfoCL(m_dmins.getBufferCL())}; - b3LauncherCL launcher(m_queue, m_findSeparatingAxisUnitSphereKernel,"findSeparatingAxisUnitSphereKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - int numDirections = sizeof(unitSphere162)/sizeof(b3Vector3); - launcher.setConst( numDirections); + b3LauncherCL launcher(m_queue, m_findSeparatingAxisUnitSphereKernel, "findSeparatingAxisUnitSphereKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + int numDirections = sizeof(unitSphere162) / sizeof(b3Vector3); + launcher.setConst(numDirections); + + launcher.setConst(nPairs); - launcher.setConst( nPairs ); - int num = nPairs; - launcher.launch1D( num); + launcher.launch1D(num); clFinish(m_queue); } + } } - - - } else + else { B3_PROFILE("findSeparatingAxisKernel"); - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( pairs->getBufferCL(), true ), - b3BufferInfoCL( bodyBuf->getBufferCL(),true), - b3BufferInfoCL( gpuCollidables.getBufferCL(),true), - b3BufferInfoCL( convexData.getBufferCL(),true), - b3BufferInfoCL( gpuVertices.getBufferCL(),true), - b3BufferInfoCL( gpuUniqueEdges.getBufferCL(),true), - b3BufferInfoCL( gpuFaces.getBufferCL(),true), - b3BufferInfoCL( gpuIndices.getBufferCL(),true), - b3BufferInfoCL( clAabbsWorldSpace.getBufferCL(),true), - b3BufferInfoCL( m_sepNormals.getBufferCL()), - b3BufferInfoCL( m_hasSeparatingNormals.getBufferCL()) - }; + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(pairs->getBufferCL(), true), + b3BufferInfoCL(bodyBuf->getBufferCL(), true), + b3BufferInfoCL(gpuCollidables.getBufferCL(), true), + b3BufferInfoCL(convexData.getBufferCL(), true), + b3BufferInfoCL(gpuVertices.getBufferCL(), true), + b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true), + b3BufferInfoCL(gpuFaces.getBufferCL(), true), + b3BufferInfoCL(gpuIndices.getBufferCL(), true), + b3BufferInfoCL(clAabbsWorldSpace.getBufferCL(), true), + b3BufferInfoCL(m_sepNormals.getBufferCL()), + b3BufferInfoCL(m_hasSeparatingNormals.getBufferCL())}; - b3LauncherCL launcher(m_queue, m_findSeparatingAxisKernel,"m_findSeparatingAxisKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( nPairs ); + b3LauncherCL launcher(m_queue, m_findSeparatingAxisKernel, "m_findSeparatingAxisKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(nPairs); int num = nPairs; - launcher.launch1D( num); + launcher.launch1D(num); clFinish(m_queue); } - - } - else - { - + else + { B3_PROFILE("findSeparatingAxisKernel CPU"); - - - b3AlignedObjectArray hostPairs; - pairs->copyToHost(hostPairs); - b3AlignedObjectArray hostBodyBuf; - bodyBuf->copyToHost(hostBodyBuf); - b3AlignedObjectArray hostCollidables; - gpuCollidables.copyToHost(hostCollidables); - - b3AlignedObjectArray cpuChildShapes; - gpuChildShapes.copyToHost(cpuChildShapes); - - b3AlignedObjectArray hostConvexShapeData; - convexData.copyToHost(hostConvexShapeData); - - b3AlignedObjectArray hostVertices; - gpuVertices.copyToHost(hostVertices); - - b3AlignedObjectArray hostHasSepAxis; - hostHasSepAxis.resize(nPairs); - b3AlignedObjectArray hostSepAxis; - hostSepAxis.resize(nPairs); - - b3AlignedObjectArray hostUniqueEdges; - gpuUniqueEdges.copyToHost(hostUniqueEdges); - b3AlignedObjectArray hostFaces; - gpuFaces.copyToHost(hostFaces); - - b3AlignedObjectArray hostIndices; - gpuIndices.copyToHost(hostIndices); - + b3AlignedObjectArray hostPairs; + pairs->copyToHost(hostPairs); + b3AlignedObjectArray hostBodyBuf; + bodyBuf->copyToHost(hostBodyBuf); + + b3AlignedObjectArray hostCollidables; + gpuCollidables.copyToHost(hostCollidables); + + b3AlignedObjectArray cpuChildShapes; + gpuChildShapes.copyToHost(cpuChildShapes); + + b3AlignedObjectArray hostConvexShapeData; + convexData.copyToHost(hostConvexShapeData); + + b3AlignedObjectArray hostVertices; + gpuVertices.copyToHost(hostVertices); + + b3AlignedObjectArray hostHasSepAxis; + hostHasSepAxis.resize(nPairs); + b3AlignedObjectArray hostSepAxis; + hostSepAxis.resize(nPairs); + + b3AlignedObjectArray hostUniqueEdges; + gpuUniqueEdges.copyToHost(hostUniqueEdges); + b3AlignedObjectArray hostFaces; + gpuFaces.copyToHost(hostFaces); + + b3AlignedObjectArray hostIndices; + gpuIndices.copyToHost(hostIndices); + b3AlignedObjectArray hostContacts; if (nContacts) { @@ -3201,61 +3008,56 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* } hostContacts.resize(maxContactCapacity); int nGlobalContactsOut = nContacts; - - - for (int i=0;i* &sepAxis, &dmin); if (hasSepAxisB) { - bool hasEdgeEdge =b3FindSeparatingAxisEdgeEdge(convexShapeA, convexShapeB, posA, ornA, posB, ornB, DeltaC2, - &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0), - &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0), - &sepAxis, &dmin,false); - + bool hasEdgeEdge = b3FindSeparatingAxisEdgeEdge(convexShapeA, convexShapeB, posA, ornA, posB, ornB, DeltaC2, + &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0), + &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0), + &sepAxis, &dmin, false); + if (hasEdgeEdge) { hostHasSepAxis[i] = 1; @@ -3282,163 +3084,150 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* if (hostHasSepAxis[i]) { int pairIndex = i; - + bool useMpr = true; if (useMpr) { - int res=0; + int res = 0; float depth = 0.f; - b3Vector3 sepAxis2 = b3MakeVector3(1,0,0); - b3Vector3 resultPointOnBWorld = b3MakeVector3(0,0,0); + b3Vector3 sepAxis2 = b3MakeVector3(1, 0, 0); + b3Vector3 resultPointOnBWorld = b3MakeVector3(0, 0, 0); - float depthOut; - b3Vector3 dirOut; - b3Vector3 posOut; - + float depthOut; + b3Vector3 dirOut; + b3Vector3 posOut; - //res = b3MprPenetration(bodyIndexA,bodyIndexB,hostBodyBuf,hostConvexShapeData,hostCollidables,hostVertices,&mprConfig,&depthOut,&dirOut,&posOut); - res = b3MprPenetration(pairIndex,bodyIndexA,bodyIndexB,&hostBodyBuf[0],&hostConvexShapeData[0],&hostCollidables[0],&hostVertices[0],&hostSepAxis[0],&hostHasSepAxis[0],&depthOut,&dirOut,&posOut); - depth = depthOut; - sepAxis2 = b3MakeVector3(-dirOut.x,-dirOut.y,-dirOut.z); - resultPointOnBWorld = posOut; - //hostHasSepAxis[i] = 0; + //res = b3MprPenetration(bodyIndexA,bodyIndexB,hostBodyBuf,hostConvexShapeData,hostCollidables,hostVertices,&mprConfig,&depthOut,&dirOut,&posOut); + res = b3MprPenetration(pairIndex, bodyIndexA, bodyIndexB, &hostBodyBuf[0], &hostConvexShapeData[0], &hostCollidables[0], &hostVertices[0], &hostSepAxis[0], &hostHasSepAxis[0], &depthOut, &dirOut, &posOut); + depth = depthOut; + sepAxis2 = b3MakeVector3(-dirOut.x, -dirOut.y, -dirOut.z); + resultPointOnBWorld = posOut; + //hostHasSepAxis[i] = 0; - - if (res==0) - { - //add point? - //printf("depth = %f\n",depth); - //printf("normal = %f,%f,%f\n",dir.v[0],dir.v[1],dir.v[2]); - //qprintf("pos = %f,%f,%f\n",pos.v[0],pos.v[1],pos.v[2]); - - - - float dist=0.f; - - const b3ConvexPolyhedronData& hullA = hostConvexShapeData[hostCollidables[hostBodyBuf[bodyIndexA].m_collidableIdx].m_shapeIndex]; - const b3ConvexPolyhedronData& hullB = hostConvexShapeData[hostCollidables[hostBodyBuf[bodyIndexB].m_collidableIdx].m_shapeIndex]; - - if(b3TestSepAxis( &hullA, &hullB, posA,ornA,posB,ornB,&sepAxis2, &hostVertices[0], &hostVertices[0],&dist)) + if (res == 0) { - if (depth > dist) + //add point? + //printf("depth = %f\n",depth); + //printf("normal = %f,%f,%f\n",dir.v[0],dir.v[1],dir.v[2]); + //qprintf("pos = %f,%f,%f\n",pos.v[0],pos.v[1],pos.v[2]); + + float dist = 0.f; + + const b3ConvexPolyhedronData& hullA = hostConvexShapeData[hostCollidables[hostBodyBuf[bodyIndexA].m_collidableIdx].m_shapeIndex]; + const b3ConvexPolyhedronData& hullB = hostConvexShapeData[hostCollidables[hostBodyBuf[bodyIndexB].m_collidableIdx].m_shapeIndex]; + + if (b3TestSepAxis(&hullA, &hullB, posA, ornA, posB, ornB, &sepAxis2, &hostVertices[0], &hostVertices[0], &dist)) { - float diff = depth - dist; - - static float maxdiff = 0.f; - if (maxdiff < diff) + if (depth > dist) { - maxdiff = diff; - printf("maxdiff = %20.10f\n",maxdiff); + float diff = depth - dist; + + static float maxdiff = 0.f; + if (maxdiff < diff) + { + maxdiff = diff; + printf("maxdiff = %20.10f\n", maxdiff); + } } } - } - if (depth > dmin) - { - b3Vector3 oldAxis = hostSepAxis[i]; - depth = dmin; - sepAxis2 = oldAxis; - } - - - - if(b3TestSepAxis( &hullA, &hullB, posA,ornA,posB,ornB,&sepAxis2, &hostVertices[0], &hostVertices[0],&dist)) - { - if (depth > dist) + if (depth > dmin) { - float diff = depth - dist; - //printf("?diff = %f\n",diff ); - static float maxdiff = 0.f; - if (maxdiff < diff) + b3Vector3 oldAxis = hostSepAxis[i]; + depth = dmin; + sepAxis2 = oldAxis; + } + + if (b3TestSepAxis(&hullA, &hullB, posA, ornA, posB, ornB, &sepAxis2, &hostVertices[0], &hostVertices[0], &dist)) + { + if (depth > dist) { - maxdiff = diff; - printf("maxdiff = %20.10f\n",maxdiff); + float diff = depth - dist; + //printf("?diff = %f\n",diff ); + static float maxdiff = 0.f; + if (maxdiff < diff) + { + maxdiff = diff; + printf("maxdiff = %20.10f\n", maxdiff); + } } + //this is used for SAT + //hostHasSepAxis[i] = 1; + //hostSepAxis[i] = sepAxis2; + + //add contact point + + //int contactIndex = nGlobalContactsOut; + b3Contact4& newContact = hostContacts.at(nGlobalContactsOut); + nGlobalContactsOut++; + newContact.m_batchIdx = 0; //i; + newContact.m_bodyAPtrAndSignBit = (hostBodyBuf.at(bodyIndexA).m_invMass == 0) ? -bodyIndexA : bodyIndexA; + newContact.m_bodyBPtrAndSignBit = (hostBodyBuf.at(bodyIndexB).m_invMass == 0) ? -bodyIndexB : bodyIndexB; + + newContact.m_frictionCoeffCmp = 45874; + newContact.m_restituitionCoeffCmp = 0; + + static float maxDepth = 0.f; + + if (depth > maxDepth) + { + maxDepth = depth; + printf("MPR maxdepth = %f\n", maxDepth); + } + + resultPointOnBWorld.w = -depth; + newContact.m_worldPosB[0] = resultPointOnBWorld; + //b3Vector3 resultPointOnAWorld = resultPointOnBWorld+depth*sepAxis2; + newContact.m_worldNormalOnB = sepAxis2; + newContact.m_worldNormalOnB.w = (b3Scalar)1; } - //this is used for SAT - //hostHasSepAxis[i] = 1; - //hostSepAxis[i] = sepAxis2; - - //add contact point - - //int contactIndex = nGlobalContactsOut; - b3Contact4& newContact = hostContacts.at(nGlobalContactsOut); - nGlobalContactsOut++; - newContact.m_batchIdx = 0;//i; - newContact.m_bodyAPtrAndSignBit = (hostBodyBuf.at(bodyIndexA).m_invMass==0)? -bodyIndexA:bodyIndexA; - newContact.m_bodyBPtrAndSignBit = (hostBodyBuf.at(bodyIndexB).m_invMass==0)? -bodyIndexB:bodyIndexB; - - newContact.m_frictionCoeffCmp = 45874; - newContact.m_restituitionCoeffCmp = 0; - - - static float maxDepth = 0.f; - - if (depth > maxDepth) + else { - maxDepth = depth; - printf("MPR maxdepth = %f\n",maxDepth ); - + printf("rejected\n"); } - - - resultPointOnBWorld.w = -depth; - newContact.m_worldPosB[0] = resultPointOnBWorld; - //b3Vector3 resultPointOnAWorld = resultPointOnBWorld+depth*sepAxis2; - newContact.m_worldNormalOnB = sepAxis2; - newContact.m_worldNormalOnB.w = (b3Scalar)1; - } else - { - printf("rejected\n"); } - - } - } else + else { - - - - //int contactIndex = computeContactConvexConvex2( i,bodyIndexA,bodyIndexB,collidableIndexA,collidableIndexB,hostBodyBuf, hostCollidables,hostConvexData,hostVertices,hostUniqueEdges,hostIndices,hostFaces,hostContacts,nContacts,maxContactCapacity,oldHostContacts); - b3AlignedObjectArray oldHostContacts; + //int contactIndex = computeContactConvexConvex2( i,bodyIndexA,bodyIndexB,collidableIndexA,collidableIndexB,hostBodyBuf, hostCollidables,hostConvexData,hostVertices,hostUniqueEdges,hostIndices,hostFaces,hostContacts,nContacts,maxContactCapacity,oldHostContacts); + b3AlignedObjectArray oldHostContacts; int result; - result = computeContactConvexConvex2( //hostPairs, - pairIndex, - bodyIndexA, bodyIndexB, - collidableIndexA, collidableIndexB, - hostBodyBuf, - hostCollidables, - hostConvexShapeData, - hostVertices, - hostUniqueEdges, - hostIndices, - hostFaces, - hostContacts, - nGlobalContactsOut, - maxContactCapacity, - oldHostContacts - //hostHasSepAxis, - //hostSepAxis - - ); - }//mpr - }//hostHasSepAxis[i] = 1; - - } else + result = computeContactConvexConvex2( //hostPairs, + pairIndex, + bodyIndexA, bodyIndexB, + collidableIndexA, collidableIndexB, + hostBodyBuf, + hostCollidables, + hostConvexShapeData, + hostVertices, + hostUniqueEdges, + hostIndices, + hostFaces, + hostContacts, + nGlobalContactsOut, + maxContactCapacity, + oldHostContacts + //hostHasSepAxis, + //hostSepAxis + + ); + } //mpr + } //hostHasSepAxis[i] = 1; + } + else { - b3Vector3 c0local = hostConvexShapeData[shapeIndexA].m_localCenter; b3Vector3 c0 = b3TransformPoint(c0local, posA, ornA); b3Vector3 c1local = hostConvexShapeData[shapeIndexB].m_localCenter; - b3Vector3 c1 = b3TransformPoint(c1local,posB,ornB); + b3Vector3 c1 = b3TransformPoint(c1local, posB, ornB); b3Vector3 DeltaC2 = c0 - c1; - + b3Vector3 sepAxis; - + bool hasSepAxisA = b3FindSeparatingAxis(convexShapeA, convexShapeB, posA, ornA, posB, ornB, DeltaC2, - &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0), - &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0), - &sepAxis, &dmin); - + &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0), + &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0), + &sepAxis, &dmin); + if (hasSepAxisA) { bool hasSepAxisB = b3FindSeparatingAxis(convexShapeB, convexShapeA, posB, ornB, posA, ornA, DeltaC2, @@ -3447,11 +3236,11 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* &sepAxis, &dmin); if (hasSepAxisB) { - bool hasEdgeEdge =b3FindSeparatingAxisEdgeEdge(convexShapeA, convexShapeB, posA, ornA, posB, ornB, DeltaC2, - &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0), - &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0), - &sepAxis, &dmin,true); - + bool hasEdgeEdge = b3FindSeparatingAxisEdgeEdge(convexShapeA, convexShapeB, posA, ornA, posB, ornB, DeltaC2, + &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0), + &hostVertices.at(0), &hostUniqueEdges.at(0), &hostFaces.at(0), &hostIndices.at(0), + &sepAxis, &dmin, true); + if (hasEdgeEdge) { hostHasSepAxis[i] = 1; @@ -3460,21 +3249,21 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* } } } - } - - if (useGjkContacts)//nGlobalContactsOut>0) + } + + if (useGjkContacts) //nGlobalContactsOut>0) { //printf("nGlobalContactsOut=%d\n",nGlobalContactsOut); nContacts = nGlobalContactsOut; contactOut->copyFromHost(hostContacts); - - m_totalContactsOut.copyFromHostPointer(&nContacts,1,0,true); + + m_totalContactsOut.copyFromHostPointer(&nContacts, 1, 0, true); } - - m_hasSeparatingNormals.copyFromHost(hostHasSepAxis); - m_sepNormals.copyFromHost(hostSepAxis); - - /* + + m_hasSeparatingNormals.copyFromHost(hostHasSepAxis); + m_sepNormals.copyFromHost(hostSepAxis); + + /* //double-check results from GPU (comment-out the 'else' so both paths are executed b3AlignedObjectArray checkHasSepAxis; m_hasSeparatingNormals.copyToHost(checkHasSepAxis); @@ -3491,352 +3280,314 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* //m_hasSeparatingNormals.copyFromHost(hostHasSepAxis); // m_sepNormals.copyFromHost(hostSepAxis); */ - } - - - numCompoundPairs = m_numCompoundPairsOut.at(0); - bool useGpuFindCompoundPairs=true; - if (useGpuFindCompoundPairs) - { - B3_PROFILE("findCompoundPairsKernel"); - b3BufferInfoCL bInfo[] = - { - b3BufferInfoCL( pairs->getBufferCL(), true ), - b3BufferInfoCL( bodyBuf->getBufferCL(),true), - b3BufferInfoCL( gpuCollidables.getBufferCL(),true), - b3BufferInfoCL( convexData.getBufferCL(),true), - b3BufferInfoCL( gpuVertices.getBufferCL(),true), - b3BufferInfoCL( gpuUniqueEdges.getBufferCL(),true), - b3BufferInfoCL( gpuFaces.getBufferCL(),true), - b3BufferInfoCL( gpuIndices.getBufferCL(),true), - b3BufferInfoCL( clAabbsLocalSpace.getBufferCL(),true), - b3BufferInfoCL( gpuChildShapes.getBufferCL(),true), - b3BufferInfoCL( m_gpuCompoundPairs.getBufferCL()), - b3BufferInfoCL( m_numCompoundPairsOut.getBufferCL()), - b3BufferInfoCL(subTreesGPU->getBufferCL()), - b3BufferInfoCL(treeNodesGPU->getBufferCL()), - b3BufferInfoCL(bvhInfo->getBufferCL()) - }; + } - b3LauncherCL launcher(m_queue, m_findCompoundPairsKernel,"m_findCompoundPairsKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( nPairs ); - launcher.setConst( compoundPairCapacity); + numCompoundPairs = m_numCompoundPairsOut.at(0); + bool useGpuFindCompoundPairs = true; + if (useGpuFindCompoundPairs) + { + B3_PROFILE("findCompoundPairsKernel"); + b3BufferInfoCL bInfo[] = + { + b3BufferInfoCL(pairs->getBufferCL(), true), + b3BufferInfoCL(bodyBuf->getBufferCL(), true), + b3BufferInfoCL(gpuCollidables.getBufferCL(), true), + b3BufferInfoCL(convexData.getBufferCL(), true), + b3BufferInfoCL(gpuVertices.getBufferCL(), true), + b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true), + b3BufferInfoCL(gpuFaces.getBufferCL(), true), + b3BufferInfoCL(gpuIndices.getBufferCL(), true), + b3BufferInfoCL(clAabbsLocalSpace.getBufferCL(), true), + b3BufferInfoCL(gpuChildShapes.getBufferCL(), true), + b3BufferInfoCL(m_gpuCompoundPairs.getBufferCL()), + b3BufferInfoCL(m_numCompoundPairsOut.getBufferCL()), + b3BufferInfoCL(subTreesGPU->getBufferCL()), + b3BufferInfoCL(treeNodesGPU->getBufferCL()), + b3BufferInfoCL(bvhInfo->getBufferCL())}; - int num = nPairs; - launcher.launch1D( num); - clFinish(m_queue); + b3LauncherCL launcher(m_queue, m_findCompoundPairsKernel, "m_findCompoundPairsKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(nPairs); + launcher.setConst(compoundPairCapacity); - numCompoundPairs = m_numCompoundPairsOut.at(0); - //printf("numCompoundPairs =%d\n",numCompoundPairs ); - if (numCompoundPairs) - { - //printf("numCompoundPairs=%d\n",numCompoundPairs); - } - + int num = nPairs; + launcher.launch1D(num); + clFinish(m_queue); - } else - { + numCompoundPairs = m_numCompoundPairsOut.at(0); + //printf("numCompoundPairs =%d\n",numCompoundPairs ); + if (numCompoundPairs) + { + //printf("numCompoundPairs=%d\n",numCompoundPairs); + } + } + else + { + b3AlignedObjectArray treeNodesCPU; + treeNodesGPU->copyToHost(treeNodesCPU); + b3AlignedObjectArray subTreesCPU; + subTreesGPU->copyToHost(subTreesCPU); - b3AlignedObjectArray treeNodesCPU; - treeNodesGPU->copyToHost(treeNodesCPU); + b3AlignedObjectArray bvhInfoCPU; + bvhInfo->copyToHost(bvhInfoCPU); - b3AlignedObjectArray subTreesCPU; - subTreesGPU->copyToHost(subTreesCPU); + b3AlignedObjectArray hostAabbsWorldSpace; + clAabbsWorldSpace.copyToHost(hostAabbsWorldSpace); - b3AlignedObjectArray bvhInfoCPU; - bvhInfo->copyToHost(bvhInfoCPU); + b3AlignedObjectArray hostAabbsLocalSpace; + clAabbsLocalSpace.copyToHost(hostAabbsLocalSpace); - b3AlignedObjectArray hostAabbsWorldSpace; - clAabbsWorldSpace.copyToHost(hostAabbsWorldSpace); + b3AlignedObjectArray hostPairs; + pairs->copyToHost(hostPairs); - b3AlignedObjectArray hostAabbsLocalSpace; - clAabbsLocalSpace.copyToHost(hostAabbsLocalSpace); + b3AlignedObjectArray hostBodyBuf; + bodyBuf->copyToHost(hostBodyBuf); - b3AlignedObjectArray hostPairs; - pairs->copyToHost(hostPairs); + b3AlignedObjectArray cpuCompoundPairsOut; + cpuCompoundPairsOut.resize(compoundPairCapacity); - b3AlignedObjectArray hostBodyBuf; - bodyBuf->copyToHost(hostBodyBuf); + b3AlignedObjectArray hostCollidables; + gpuCollidables.copyToHost(hostCollidables); + b3AlignedObjectArray cpuChildShapes; + gpuChildShapes.copyToHost(cpuChildShapes); - b3AlignedObjectArray cpuCompoundPairsOut; - cpuCompoundPairsOut.resize(compoundPairCapacity); + b3AlignedObjectArray hostConvexData; + convexData.copyToHost(hostConvexData); - b3AlignedObjectArray hostCollidables; - gpuCollidables.copyToHost(hostCollidables); + b3AlignedObjectArray hostVertices; + gpuVertices.copyToHost(hostVertices); - b3AlignedObjectArray cpuChildShapes; - gpuChildShapes.copyToHost(cpuChildShapes); - - b3AlignedObjectArray hostConvexData; - convexData.copyToHost(hostConvexData); - - b3AlignedObjectArray hostVertices; - gpuVertices.copyToHost(hostVertices); - - - - - for (int pairIndex=0;pairIndex compoundPairCapacity) - { - b3Error("Exceeded compound pair capacity (%d/%d)\n", numCompoundPairs, compoundPairCapacity); - numCompoundPairs = compoundPairCapacity; - } + if (numCompoundPairs > compoundPairCapacity) + { + b3Error("Exceeded compound pair capacity (%d/%d)\n", numCompoundPairs, compoundPairCapacity); + numCompoundPairs = compoundPairCapacity; + } - + m_gpuCompoundPairs.resize(numCompoundPairs); + m_gpuHasCompoundSepNormals.resize(numCompoundPairs); + m_gpuCompoundSepNormals.resize(numCompoundPairs); - m_gpuCompoundPairs.resize(numCompoundPairs); - m_gpuHasCompoundSepNormals.resize(numCompoundPairs); - m_gpuCompoundSepNormals.resize(numCompoundPairs); - + if (numCompoundPairs) + { + B3_PROFILE("processCompoundPairsPrimitivesKernel"); + b3BufferInfoCL bInfo[] = + { + b3BufferInfoCL(m_gpuCompoundPairs.getBufferCL(), true), + b3BufferInfoCL(bodyBuf->getBufferCL(), true), + b3BufferInfoCL(gpuCollidables.getBufferCL(), true), + b3BufferInfoCL(convexData.getBufferCL(), true), + b3BufferInfoCL(gpuVertices.getBufferCL(), true), + b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true), + b3BufferInfoCL(gpuFaces.getBufferCL(), true), + b3BufferInfoCL(gpuIndices.getBufferCL(), true), + b3BufferInfoCL(clAabbsWorldSpace.getBufferCL(), true), + b3BufferInfoCL(gpuChildShapes.getBufferCL(), true), + b3BufferInfoCL(contactOut->getBufferCL()), + b3BufferInfoCL(m_totalContactsOut.getBufferCL())}; - if (numCompoundPairs) - { - B3_PROFILE("processCompoundPairsPrimitivesKernel"); - b3BufferInfoCL bInfo[] = - { - b3BufferInfoCL( m_gpuCompoundPairs.getBufferCL(), true ), - b3BufferInfoCL( bodyBuf->getBufferCL(),true), - b3BufferInfoCL( gpuCollidables.getBufferCL(),true), - b3BufferInfoCL( convexData.getBufferCL(),true), - b3BufferInfoCL( gpuVertices.getBufferCL(),true), - b3BufferInfoCL( gpuUniqueEdges.getBufferCL(),true), - b3BufferInfoCL( gpuFaces.getBufferCL(),true), - b3BufferInfoCL( gpuIndices.getBufferCL(),true), - b3BufferInfoCL( clAabbsWorldSpace.getBufferCL(),true), - b3BufferInfoCL( gpuChildShapes.getBufferCL(),true), - b3BufferInfoCL( contactOut->getBufferCL()), - b3BufferInfoCL( m_totalContactsOut.getBufferCL()) - }; + b3LauncherCL launcher(m_queue, m_processCompoundPairsPrimitivesKernel, "m_processCompoundPairsPrimitivesKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(numCompoundPairs); + launcher.setConst(maxContactCapacity); - b3LauncherCL launcher(m_queue, m_processCompoundPairsPrimitivesKernel,"m_processCompoundPairsPrimitivesKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( numCompoundPairs ); - launcher.setConst(maxContactCapacity); + int num = numCompoundPairs; + launcher.launch1D(num); + clFinish(m_queue); + nContacts = m_totalContactsOut.at(0); + //printf("nContacts (after processCompoundPairsPrimitivesKernel) = %d\n",nContacts); + if (nContacts > maxContactCapacity) + { + b3Error("Error: contacts exceeds capacity (%d/%d)\n", nContacts, maxContactCapacity); + nContacts = maxContactCapacity; + } + } - int num = numCompoundPairs; - launcher.launch1D( num); - clFinish(m_queue); - nContacts = m_totalContactsOut.at(0); - //printf("nContacts (after processCompoundPairsPrimitivesKernel) = %d\n",nContacts); - if (nContacts>maxContactCapacity) - { - - b3Error("Error: contacts exceeds capacity (%d/%d)\n", nContacts, maxContactCapacity); - nContacts = maxContactCapacity; - } - } - + if (numCompoundPairs) + { + B3_PROFILE("processCompoundPairsKernel"); + b3BufferInfoCL bInfo[] = + { + b3BufferInfoCL(m_gpuCompoundPairs.getBufferCL(), true), + b3BufferInfoCL(bodyBuf->getBufferCL(), true), + b3BufferInfoCL(gpuCollidables.getBufferCL(), true), + b3BufferInfoCL(convexData.getBufferCL(), true), + b3BufferInfoCL(gpuVertices.getBufferCL(), true), + b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true), + b3BufferInfoCL(gpuFaces.getBufferCL(), true), + b3BufferInfoCL(gpuIndices.getBufferCL(), true), + b3BufferInfoCL(clAabbsWorldSpace.getBufferCL(), true), + b3BufferInfoCL(gpuChildShapes.getBufferCL(), true), + b3BufferInfoCL(m_gpuCompoundSepNormals.getBufferCL()), + b3BufferInfoCL(m_gpuHasCompoundSepNormals.getBufferCL())}; - if (numCompoundPairs) - { - B3_PROFILE("processCompoundPairsKernel"); - b3BufferInfoCL bInfo[] = - { - b3BufferInfoCL( m_gpuCompoundPairs.getBufferCL(), true ), - b3BufferInfoCL( bodyBuf->getBufferCL(),true), - b3BufferInfoCL( gpuCollidables.getBufferCL(),true), - b3BufferInfoCL( convexData.getBufferCL(),true), - b3BufferInfoCL( gpuVertices.getBufferCL(),true), - b3BufferInfoCL( gpuUniqueEdges.getBufferCL(),true), - b3BufferInfoCL( gpuFaces.getBufferCL(),true), - b3BufferInfoCL( gpuIndices.getBufferCL(),true), - b3BufferInfoCL( clAabbsWorldSpace.getBufferCL(),true), - b3BufferInfoCL( gpuChildShapes.getBufferCL(),true), - b3BufferInfoCL( m_gpuCompoundSepNormals.getBufferCL()), - b3BufferInfoCL( m_gpuHasCompoundSepNormals.getBufferCL()) - }; + b3LauncherCL launcher(m_queue, m_processCompoundPairsKernel, "m_processCompoundPairsKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(numCompoundPairs); - b3LauncherCL launcher(m_queue, m_processCompoundPairsKernel,"m_processCompoundPairsKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( numCompoundPairs ); + int num = numCompoundPairs; + launcher.launch1D(num); + clFinish(m_queue); + } - int num = numCompoundPairs; - launcher.launch1D( num); - clFinish(m_queue); - - } + //printf("numConcave = %d\n",numConcave); - - //printf("numConcave = %d\n",numConcave); - - - -// printf("hostNormals.size()=%d\n",hostNormals.size()); + // printf("hostNormals.size()=%d\n",hostNormals.size()); //int numPairs = pairCount.at(0); - - - } int vertexFaceCapacity = 64; - - { //now perform the tree query on GPU - - - - + if (treeNodesGPU->size() && treeNodesGPU->size()) { if (bvhTraversalKernelGPU) { - B3_PROFILE("m_bvhTraversalKernel"); - - + numConcavePairs = m_numConcavePairsOut.at(0); - - b3LauncherCL launcher(m_queue, m_bvhTraversalKernel,"m_bvhTraversalKernel"); - launcher.setBuffer( pairs->getBufferCL()); - launcher.setBuffer( bodyBuf->getBufferCL()); - launcher.setBuffer( gpuCollidables.getBufferCL()); - launcher.setBuffer( clAabbsWorldSpace.getBufferCL()); - launcher.setBuffer( triangleConvexPairsOut.getBufferCL()); - launcher.setBuffer( m_numConcavePairsOut.getBufferCL()); - launcher.setBuffer( subTreesGPU->getBufferCL()); - launcher.setBuffer( treeNodesGPU->getBufferCL()); - launcher.setBuffer( bvhInfo->getBufferCL()); - - launcher.setConst( nPairs ); - launcher.setConst( maxTriConvexPairCapacity); + + b3LauncherCL launcher(m_queue, m_bvhTraversalKernel, "m_bvhTraversalKernel"); + launcher.setBuffer(pairs->getBufferCL()); + launcher.setBuffer(bodyBuf->getBufferCL()); + launcher.setBuffer(gpuCollidables.getBufferCL()); + launcher.setBuffer(clAabbsWorldSpace.getBufferCL()); + launcher.setBuffer(triangleConvexPairsOut.getBufferCL()); + launcher.setBuffer(m_numConcavePairsOut.getBufferCL()); + launcher.setBuffer(subTreesGPU->getBufferCL()); + launcher.setBuffer(treeNodesGPU->getBufferCL()); + launcher.setBuffer(bvhInfo->getBufferCL()); + + launcher.setConst(nPairs); + launcher.setConst(maxTriConvexPairCapacity); int num = nPairs; - launcher.launch1D( num); + launcher.launch1D(num); clFinish(m_queue); numConcavePairs = m_numConcavePairsOut.at(0); - } else + } + else { - b3AlignedObjectArray hostPairs; - pairs->copyToHost(hostPairs); - b3AlignedObjectArray hostBodyBuf; - bodyBuf->copyToHost(hostBodyBuf); - b3AlignedObjectArray hostCollidables; - gpuCollidables.copyToHost(hostCollidables); - b3AlignedObjectArray hostAabbsWorldSpace; - clAabbsWorldSpace.copyToHost(hostAabbsWorldSpace); + b3AlignedObjectArray hostPairs; + pairs->copyToHost(hostPairs); + b3AlignedObjectArray hostBodyBuf; + bodyBuf->copyToHost(hostBodyBuf); + b3AlignedObjectArray hostCollidables; + gpuCollidables.copyToHost(hostCollidables); + b3AlignedObjectArray hostAabbsWorldSpace; + clAabbsWorldSpace.copyToHost(hostAabbsWorldSpace); - //int maxTriConvexPairCapacity, - b3AlignedObjectArray triangleConvexPairsOutHost; - triangleConvexPairsOutHost.resize(maxTriConvexPairCapacity); + //int maxTriConvexPairCapacity, + b3AlignedObjectArray triangleConvexPairsOutHost; + triangleConvexPairsOutHost.resize(maxTriConvexPairCapacity); - //int numTriConvexPairsOutHost=0; - numConcavePairs = 0; - //m_numConcavePairsOut + //int numTriConvexPairsOutHost=0; + numConcavePairs = 0; + //m_numConcavePairsOut - b3AlignedObjectArray treeNodesCPU; - treeNodesGPU->copyToHost(treeNodesCPU); - b3AlignedObjectArray subTreesCPU; - subTreesGPU->copyToHost(subTreesCPU); - b3AlignedObjectArray bvhInfoCPU; - bvhInfo->copyToHost(bvhInfoCPU); - //compute it... + b3AlignedObjectArray treeNodesCPU; + treeNodesGPU->copyToHost(treeNodesCPU); + b3AlignedObjectArray subTreesCPU; + subTreesGPU->copyToHost(subTreesCPU); + b3AlignedObjectArray bvhInfoCPU; + bvhInfo->copyToHost(bvhInfoCPU); + //compute it... - volatile int hostNumConcavePairsOut=0; + volatile int hostNumConcavePairsOut = 0; - // - for (int i=0;i maxTriConvexPairCapacity) { static int exceeded_maxTriConvexPairCapacity_count = 0; b3Error("Exceeded the maxTriConvexPairCapacity (found %d but max is %d, it happened %d times)\n", - numConcavePairs,maxTriConvexPairCapacity,exceeded_maxTriConvexPairCapacity_count++); + numConcavePairs, maxTriConvexPairCapacity, exceeded_maxTriConvexPairCapacity_count++); numConcavePairs = maxTriConvexPairCapacity; } triangleConvexPairsOut.resize(numConcavePairs); - + if (numConcavePairs) { - - - - clippingFacesOutGPU.resize(numConcavePairs); worldNormalsAGPU.resize(numConcavePairs); - worldVertsA1GPU.resize(vertexFaceCapacity*(numConcavePairs)); - worldVertsB1GPU.resize(vertexFaceCapacity*(numConcavePairs)); - + worldVertsA1GPU.resize(vertexFaceCapacity * (numConcavePairs)); + worldVertsB1GPU.resize(vertexFaceCapacity * (numConcavePairs)); if (findConcaveSeparatingAxisKernelGPU) { - /* m_concaveHasSeparatingNormals.copyFromHost(concaveHasSeparatingNormalsCPU); clippingFacesOutGPU.copyFromHost(clippingFacesOutCPU); @@ -3846,236 +3597,213 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* */ //now perform a SAT test for each triangle-convex element (stored in triangleConvexPairsOut) - if (splitSearchSepAxisConcave) - { - //printf("numConcavePairs = %d\n",numConcavePairs); - m_dmins.resize(numConcavePairs); - { - B3_PROFILE("findConcaveSeparatingAxisVertexFaceKernel"); - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( triangleConvexPairsOut.getBufferCL() ), - b3BufferInfoCL( bodyBuf->getBufferCL(),true), - b3BufferInfoCL( gpuCollidables.getBufferCL(),true), - b3BufferInfoCL( convexData.getBufferCL(),true), - b3BufferInfoCL( gpuVertices.getBufferCL(),true), - b3BufferInfoCL( gpuUniqueEdges.getBufferCL(),true), - b3BufferInfoCL( gpuFaces.getBufferCL(),true), - b3BufferInfoCL( gpuIndices.getBufferCL(),true), - b3BufferInfoCL( gpuChildShapes.getBufferCL(),true), - b3BufferInfoCL( clAabbsWorldSpace.getBufferCL(),true), - b3BufferInfoCL( m_concaveSepNormals.getBufferCL()), - b3BufferInfoCL( m_concaveHasSeparatingNormals.getBufferCL()), - b3BufferInfoCL( clippingFacesOutGPU.getBufferCL()), - b3BufferInfoCL( worldVertsA1GPU.getBufferCL()), - b3BufferInfoCL(worldNormalsAGPU.getBufferCL()), - b3BufferInfoCL(worldVertsB1GPU.getBufferCL()), - b3BufferInfoCL(m_dmins.getBufferCL()) - }; - - b3LauncherCL launcher(m_queue, m_findConcaveSeparatingAxisVertexFaceKernel,"m_findConcaveSeparatingAxisVertexFaceKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst(vertexFaceCapacity); - launcher.setConst( numConcavePairs ); - - int num = numConcavePairs; - launcher.launch1D( num); - clFinish(m_queue); - - - } -// numConcavePairs = 0; - if (1) - { - B3_PROFILE("findConcaveSeparatingAxisEdgeEdgeKernel"); - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( triangleConvexPairsOut.getBufferCL() ), - b3BufferInfoCL( bodyBuf->getBufferCL(),true), - b3BufferInfoCL( gpuCollidables.getBufferCL(),true), - b3BufferInfoCL( convexData.getBufferCL(),true), - b3BufferInfoCL( gpuVertices.getBufferCL(),true), - b3BufferInfoCL( gpuUniqueEdges.getBufferCL(),true), - b3BufferInfoCL( gpuFaces.getBufferCL(),true), - b3BufferInfoCL( gpuIndices.getBufferCL(),true), - b3BufferInfoCL( gpuChildShapes.getBufferCL(),true), - b3BufferInfoCL( clAabbsWorldSpace.getBufferCL(),true), - b3BufferInfoCL( m_concaveSepNormals.getBufferCL()), - b3BufferInfoCL( m_concaveHasSeparatingNormals.getBufferCL()), - b3BufferInfoCL( clippingFacesOutGPU.getBufferCL()), - b3BufferInfoCL( worldVertsA1GPU.getBufferCL()), - b3BufferInfoCL(worldNormalsAGPU.getBufferCL()), - b3BufferInfoCL(worldVertsB1GPU.getBufferCL()), - b3BufferInfoCL(m_dmins.getBufferCL()) - }; - - b3LauncherCL launcher(m_queue, m_findConcaveSeparatingAxisEdgeEdgeKernel,"m_findConcaveSeparatingAxisEdgeEdgeKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst(vertexFaceCapacity); - launcher.setConst( numConcavePairs ); - - int num = numConcavePairs; - launcher.launch1D( num); - clFinish(m_queue); - } - - - // numConcavePairs = 0; - - - - - - - } else - { - B3_PROFILE("findConcaveSeparatingAxisKernel"); - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( triangleConvexPairsOut.getBufferCL() ), - b3BufferInfoCL( bodyBuf->getBufferCL(),true), - b3BufferInfoCL( gpuCollidables.getBufferCL(),true), - b3BufferInfoCL( convexData.getBufferCL(),true), - b3BufferInfoCL( gpuVertices.getBufferCL(),true), - b3BufferInfoCL( gpuUniqueEdges.getBufferCL(),true), - b3BufferInfoCL( gpuFaces.getBufferCL(),true), - b3BufferInfoCL( gpuIndices.getBufferCL(),true), - b3BufferInfoCL( gpuChildShapes.getBufferCL(),true), - b3BufferInfoCL( clAabbsWorldSpace.getBufferCL(),true), - b3BufferInfoCL( m_concaveSepNormals.getBufferCL()), - b3BufferInfoCL( m_concaveHasSeparatingNormals.getBufferCL()), - b3BufferInfoCL( clippingFacesOutGPU.getBufferCL()), - b3BufferInfoCL( worldVertsA1GPU.getBufferCL()), - b3BufferInfoCL(worldNormalsAGPU.getBufferCL()), - b3BufferInfoCL(worldVertsB1GPU.getBufferCL()) - }; - - b3LauncherCL launcher(m_queue, m_findConcaveSeparatingAxisKernel,"m_findConcaveSeparatingAxisKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst(vertexFaceCapacity); - launcher.setConst( numConcavePairs ); - - int num = numConcavePairs; - launcher.launch1D( num); - clFinish(m_queue); - } - - - } else - { - - b3AlignedObjectArray clippingFacesOutCPU; - b3AlignedObjectArray worldVertsA1CPU; - b3AlignedObjectArray worldNormalsACPU; - b3AlignedObjectArray worldVertsB1CPU; - b3AlignedObjectArrayconcaveHasSeparatingNormalsCPU; - - b3AlignedObjectArray triangleConvexPairsOutHost; - triangleConvexPairsOut.copyToHost(triangleConvexPairsOutHost); - //triangleConvexPairsOutHost.resize(maxTriConvexPairCapacity); - b3AlignedObjectArray hostBodyBuf; - bodyBuf->copyToHost(hostBodyBuf); - b3AlignedObjectArray hostCollidables; - gpuCollidables.copyToHost(hostCollidables); - b3AlignedObjectArray hostAabbsWorldSpace; - clAabbsWorldSpace.copyToHost(hostAabbsWorldSpace); - - b3AlignedObjectArray hostConvexData; - convexData.copyToHost(hostConvexData); - - b3AlignedObjectArray hostVertices; - gpuVertices.copyToHost(hostVertices); - - b3AlignedObjectArray hostUniqueEdges; - gpuUniqueEdges.copyToHost(hostUniqueEdges); - b3AlignedObjectArray hostFaces; - gpuFaces.copyToHost(hostFaces); - b3AlignedObjectArray hostIndices; - gpuIndices.copyToHost(hostIndices); - b3AlignedObjectArray cpuChildShapes; - gpuChildShapes.copyToHost(cpuChildShapes); - - - - b3AlignedObjectArray concaveSepNormalsHost; - m_concaveSepNormals.copyToHost(concaveSepNormalsHost); - concaveHasSeparatingNormalsCPU.resize(concaveSepNormalsHost.size()); - - b3GpuChildShape* childShapePointerCPU = 0; - if (cpuChildShapes.size()) - childShapePointerCPU = &cpuChildShapes.at(0); - - clippingFacesOutCPU.resize(clippingFacesOutGPU.size()); - worldVertsA1CPU.resize(worldVertsA1GPU.size()); - worldNormalsACPU.resize(worldNormalsAGPU.size()); - worldVertsB1CPU.resize(worldVertsB1GPU.size()); - - for (int i=0;igetBufferCL(), true), + b3BufferInfoCL(gpuCollidables.getBufferCL(), true), + b3BufferInfoCL(convexData.getBufferCL(), true), + b3BufferInfoCL(gpuVertices.getBufferCL(), true), + b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true), + b3BufferInfoCL(gpuFaces.getBufferCL(), true), + b3BufferInfoCL(gpuIndices.getBufferCL(), true), + b3BufferInfoCL(gpuChildShapes.getBufferCL(), true), + b3BufferInfoCL(clAabbsWorldSpace.getBufferCL(), true), + b3BufferInfoCL(m_concaveSepNormals.getBufferCL()), + b3BufferInfoCL(m_concaveHasSeparatingNormals.getBufferCL()), + b3BufferInfoCL(clippingFacesOutGPU.getBufferCL()), + b3BufferInfoCL(worldVertsA1GPU.getBufferCL()), + b3BufferInfoCL(worldNormalsAGPU.getBufferCL()), + b3BufferInfoCL(worldVertsB1GPU.getBufferCL()), + b3BufferInfoCL(m_dmins.getBufferCL())}; - m_concaveSepNormals.copyFromHost(concaveSepNormalsHost); - m_concaveHasSeparatingNormals.copyFromHost(concaveHasSeparatingNormalsCPU); - clippingFacesOutGPU.copyFromHost(clippingFacesOutCPU); - worldVertsA1GPU.copyFromHost(worldVertsA1CPU); - worldNormalsAGPU.copyFromHost(worldNormalsACPU); - worldVertsB1GPU.copyFromHost(worldVertsB1CPU); + b3LauncherCL launcher(m_queue, m_findConcaveSeparatingAxisVertexFaceKernel, "m_findConcaveSeparatingAxisVertexFaceKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(vertexFaceCapacity); + launcher.setConst(numConcavePairs); + int num = numConcavePairs; + launcher.launch1D(num); + clFinish(m_queue); + } + // numConcavePairs = 0; + if (1) + { + B3_PROFILE("findConcaveSeparatingAxisEdgeEdgeKernel"); + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(triangleConvexPairsOut.getBufferCL()), + b3BufferInfoCL(bodyBuf->getBufferCL(), true), + b3BufferInfoCL(gpuCollidables.getBufferCL(), true), + b3BufferInfoCL(convexData.getBufferCL(), true), + b3BufferInfoCL(gpuVertices.getBufferCL(), true), + b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true), + b3BufferInfoCL(gpuFaces.getBufferCL(), true), + b3BufferInfoCL(gpuIndices.getBufferCL(), true), + b3BufferInfoCL(gpuChildShapes.getBufferCL(), true), + b3BufferInfoCL(clAabbsWorldSpace.getBufferCL(), true), + b3BufferInfoCL(m_concaveSepNormals.getBufferCL()), + b3BufferInfoCL(m_concaveHasSeparatingNormals.getBufferCL()), + b3BufferInfoCL(clippingFacesOutGPU.getBufferCL()), + b3BufferInfoCL(worldVertsA1GPU.getBufferCL()), + b3BufferInfoCL(worldNormalsAGPU.getBufferCL()), + b3BufferInfoCL(worldVertsB1GPU.getBufferCL()), + b3BufferInfoCL(m_dmins.getBufferCL())}; + b3LauncherCL launcher(m_queue, m_findConcaveSeparatingAxisEdgeEdgeKernel, "m_findConcaveSeparatingAxisEdgeEdgeKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(vertexFaceCapacity); + launcher.setConst(numConcavePairs); + int num = numConcavePairs; + launcher.launch1D(num); + clFinish(m_queue); + } + + // numConcavePairs = 0; + } + else + { + B3_PROFILE("findConcaveSeparatingAxisKernel"); + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(triangleConvexPairsOut.getBufferCL()), + b3BufferInfoCL(bodyBuf->getBufferCL(), true), + b3BufferInfoCL(gpuCollidables.getBufferCL(), true), + b3BufferInfoCL(convexData.getBufferCL(), true), + b3BufferInfoCL(gpuVertices.getBufferCL(), true), + b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true), + b3BufferInfoCL(gpuFaces.getBufferCL(), true), + b3BufferInfoCL(gpuIndices.getBufferCL(), true), + b3BufferInfoCL(gpuChildShapes.getBufferCL(), true), + b3BufferInfoCL(clAabbsWorldSpace.getBufferCL(), true), + b3BufferInfoCL(m_concaveSepNormals.getBufferCL()), + b3BufferInfoCL(m_concaveHasSeparatingNormals.getBufferCL()), + b3BufferInfoCL(clippingFacesOutGPU.getBufferCL()), + b3BufferInfoCL(worldVertsA1GPU.getBufferCL()), + b3BufferInfoCL(worldNormalsAGPU.getBufferCL()), + b3BufferInfoCL(worldVertsB1GPU.getBufferCL())}; + + b3LauncherCL launcher(m_queue, m_findConcaveSeparatingAxisKernel, "m_findConcaveSeparatingAxisKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(vertexFaceCapacity); + launcher.setConst(numConcavePairs); + + int num = numConcavePairs; + launcher.launch1D(num); + clFinish(m_queue); + } } -// b3AlignedObjectArray cpuCompoundSepNormals; -// m_concaveSepNormals.copyToHost(cpuCompoundSepNormals); -// b3AlignedObjectArray cpuConcavePairs; -// triangleConvexPairsOut.copyToHost(cpuConcavePairs); + else + { + b3AlignedObjectArray clippingFacesOutCPU; + b3AlignedObjectArray worldVertsA1CPU; + b3AlignedObjectArray worldNormalsACPU; + b3AlignedObjectArray worldVertsB1CPU; + b3AlignedObjectArray concaveHasSeparatingNormalsCPU; + b3AlignedObjectArray triangleConvexPairsOutHost; + triangleConvexPairsOut.copyToHost(triangleConvexPairsOutHost); + //triangleConvexPairsOutHost.resize(maxTriConvexPairCapacity); + b3AlignedObjectArray hostBodyBuf; + bodyBuf->copyToHost(hostBodyBuf); + b3AlignedObjectArray hostCollidables; + gpuCollidables.copyToHost(hostCollidables); + b3AlignedObjectArray hostAabbsWorldSpace; + clAabbsWorldSpace.copyToHost(hostAabbsWorldSpace); + b3AlignedObjectArray hostConvexData; + convexData.copyToHost(hostConvexData); + + b3AlignedObjectArray hostVertices; + gpuVertices.copyToHost(hostVertices); + + b3AlignedObjectArray hostUniqueEdges; + gpuUniqueEdges.copyToHost(hostUniqueEdges); + b3AlignedObjectArray hostFaces; + gpuFaces.copyToHost(hostFaces); + b3AlignedObjectArray hostIndices; + gpuIndices.copyToHost(hostIndices); + b3AlignedObjectArray cpuChildShapes; + gpuChildShapes.copyToHost(cpuChildShapes); + + b3AlignedObjectArray concaveSepNormalsHost; + m_concaveSepNormals.copyToHost(concaveSepNormalsHost); + concaveHasSeparatingNormalsCPU.resize(concaveSepNormalsHost.size()); + + b3GpuChildShape* childShapePointerCPU = 0; + if (cpuChildShapes.size()) + childShapePointerCPU = &cpuChildShapes.at(0); + + clippingFacesOutCPU.resize(clippingFacesOutGPU.size()); + worldVertsA1CPU.resize(worldVertsA1GPU.size()); + worldNormalsACPU.resize(worldNormalsAGPU.size()); + worldVertsB1CPU.resize(worldVertsB1GPU.size()); + + for (int i = 0; i < numConcavePairs; i++) + { + b3FindConcaveSeparatingAxisKernel(&triangleConvexPairsOutHost.at(0), + &hostBodyBuf.at(0), + &hostCollidables.at(0), + &hostConvexData.at(0), &hostVertices.at(0), &hostUniqueEdges.at(0), + &hostFaces.at(0), &hostIndices.at(0), childShapePointerCPU, + &hostAabbsWorldSpace.at(0), + &concaveSepNormalsHost.at(0), + &clippingFacesOutCPU.at(0), + &worldVertsA1CPU.at(0), + &worldNormalsACPU.at(0), + &worldVertsB1CPU.at(0), + &concaveHasSeparatingNormalsCPU.at(0), + vertexFaceCapacity, + numConcavePairs, i); + }; + + m_concaveSepNormals.copyFromHost(concaveSepNormalsHost); + m_concaveHasSeparatingNormals.copyFromHost(concaveHasSeparatingNormalsCPU); + clippingFacesOutGPU.copyFromHost(clippingFacesOutCPU); + worldVertsA1GPU.copyFromHost(worldVertsA1CPU); + worldNormalsAGPU.copyFromHost(worldNormalsACPU); + worldVertsB1GPU.copyFromHost(worldVertsB1CPU); + } + // b3AlignedObjectArray cpuCompoundSepNormals; + // m_concaveSepNormals.copyToHost(cpuCompoundSepNormals); + // b3AlignedObjectArray cpuConcavePairs; + // triangleConvexPairsOut.copyToHost(cpuConcavePairs); } } - - } if (numConcavePairs) { - if (numConcavePairs) + if (numConcavePairs) { B3_PROFILE("findConcaveSphereContactsKernel"); - nContacts = m_totalContactsOut.at(0); -// printf("nContacts1 = %d\n",nContacts); - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( triangleConvexPairsOut.getBufferCL() ), - b3BufferInfoCL( bodyBuf->getBufferCL(),true), - b3BufferInfoCL( gpuCollidables.getBufferCL(),true), - b3BufferInfoCL( convexData.getBufferCL(),true), - b3BufferInfoCL( gpuVertices.getBufferCL(),true), - b3BufferInfoCL( gpuUniqueEdges.getBufferCL(),true), - b3BufferInfoCL( gpuFaces.getBufferCL(),true), - b3BufferInfoCL( gpuIndices.getBufferCL(),true), - b3BufferInfoCL( clAabbsWorldSpace.getBufferCL(),true), - b3BufferInfoCL( contactOut->getBufferCL()), - b3BufferInfoCL( m_totalContactsOut.getBufferCL()) - }; + nContacts = m_totalContactsOut.at(0); + // printf("nContacts1 = %d\n",nContacts); + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(triangleConvexPairsOut.getBufferCL()), + b3BufferInfoCL(bodyBuf->getBufferCL(), true), + b3BufferInfoCL(gpuCollidables.getBufferCL(), true), + b3BufferInfoCL(convexData.getBufferCL(), true), + b3BufferInfoCL(gpuVertices.getBufferCL(), true), + b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true), + b3BufferInfoCL(gpuFaces.getBufferCL(), true), + b3BufferInfoCL(gpuIndices.getBufferCL(), true), + b3BufferInfoCL(clAabbsWorldSpace.getBufferCL(), true), + b3BufferInfoCL(contactOut->getBufferCL()), + b3BufferInfoCL(m_totalContactsOut.getBufferCL())}; - b3LauncherCL launcher(m_queue, m_findConcaveSphereContactsKernel,"m_findConcaveSphereContactsKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); + b3LauncherCL launcher(m_queue, m_findConcaveSphereContactsKernel, "m_findConcaveSphereContactsKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); - launcher.setConst( numConcavePairs ); + launcher.setConst(numConcavePairs); launcher.setConst(maxContactCapacity); int num = numConcavePairs; - launcher.launch1D( num); + launcher.launch1D(num); clFinish(m_queue); nContacts = m_totalContactsOut.at(0); //printf("nContacts (after findConcaveSphereContactsKernel) = %d\n",nContacts); @@ -4088,11 +3816,8 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* nContacts = maxContactCapacity; } } - } - - #ifdef __APPLE__ bool contactClippingOnGpu = true; #else @@ -4101,9 +3826,8 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* if (contactClippingOnGpu) { - m_totalContactsOut.copyFromHostPointer(&nContacts,1,0,true); -// printf("nContacts3 = %d\n",nContacts); - + m_totalContactsOut.copyFromHostPointer(&nContacts, 1, 0, true); + // printf("nContacts3 = %d\n",nContacts); //B3_PROFILE("clipHullHullKernel"); @@ -4122,15 +3846,12 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* if (breakupConcaveConvexKernel) { - - worldVertsB2GPU.resize(vertexFaceCapacity*numConcavePairs); - + worldVertsB2GPU.resize(vertexFaceCapacity * numConcavePairs); //clipFacesAndFindContacts if (clipConcaveFacesAndFindContactsCPU) { - b3AlignedObjectArray clippingFacesOutCPU; b3AlignedObjectArray worldVertsA1CPU; b3AlignedObjectArray worldNormalsACPU; @@ -4141,120 +3862,108 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* worldNormalsAGPU.copyToHost(worldNormalsACPU); worldVertsB1GPU.copyToHost(worldVertsB1CPU); - - - b3AlignedObjectArrayconcaveHasSeparatingNormalsCPU; + b3AlignedObjectArray concaveHasSeparatingNormalsCPU; m_concaveHasSeparatingNormals.copyToHost(concaveHasSeparatingNormalsCPU); b3AlignedObjectArray concaveSepNormalsHost; m_concaveSepNormals.copyToHost(concaveSepNormalsHost); - b3AlignedObjectArray worldVertsB2CPU; + b3AlignedObjectArray worldVertsB2CPU; worldVertsB2CPU.resize(worldVertsB2GPU.size()); - - for (int i=0;ireserve(newContactCapacity); if (reduceConcaveContactsOnGPU) { -// printf("newReservation = %d\n",newReservation); + // printf("newReservation = %d\n",newReservation); { B3_PROFILE("newContactReductionKernel"); b3BufferInfoCL bInfo[] = - { - b3BufferInfoCL( triangleConvexPairsOut.getBufferCL(), true ), - b3BufferInfoCL( bodyBuf->getBufferCL(),true), - b3BufferInfoCL( m_concaveSepNormals.getBufferCL()), - b3BufferInfoCL( m_concaveHasSeparatingNormals.getBufferCL()), - b3BufferInfoCL( contactOut->getBufferCL()), - b3BufferInfoCL( clippingFacesOutGPU.getBufferCL()), - b3BufferInfoCL( worldVertsB2GPU.getBufferCL()), - b3BufferInfoCL( m_totalContactsOut.getBufferCL()) - }; + { + b3BufferInfoCL(triangleConvexPairsOut.getBufferCL(), true), + b3BufferInfoCL(bodyBuf->getBufferCL(), true), + b3BufferInfoCL(m_concaveSepNormals.getBufferCL()), + b3BufferInfoCL(m_concaveHasSeparatingNormals.getBufferCL()), + b3BufferInfoCL(contactOut->getBufferCL()), + b3BufferInfoCL(clippingFacesOutGPU.getBufferCL()), + b3BufferInfoCL(worldVertsB2GPU.getBufferCL()), + b3BufferInfoCL(m_totalContactsOut.getBufferCL())}; - b3LauncherCL launcher(m_queue, m_newContactReductionKernel,"m_newContactReductionKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); + b3LauncherCL launcher(m_queue, m_newContactReductionKernel, "m_newContactReductionKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); launcher.setConst(vertexFaceCapacity); launcher.setConst(newContactCapacity); - launcher.setConst( numConcavePairs ); + launcher.setConst(numConcavePairs); int num = numConcavePairs; - launcher.launch1D( num); + launcher.launch1D(num); } nContacts = m_totalContactsOut.at(0); contactOut->resize(nContacts); //printf("contactOut4 (after newContactReductionKernel) = %d\n",nContacts); - }else + } + else { - volatile int nGlobalContactsOut = nContacts; b3AlignedObjectArray triangleConvexPairsOutHost; triangleConvexPairsOut.copyToHost(triangleConvexPairsOutHost); b3AlignedObjectArray hostBodyBuf; bodyBuf->copyToHost(hostBodyBuf); - b3AlignedObjectArrayconcaveHasSeparatingNormalsCPU; + b3AlignedObjectArray concaveHasSeparatingNormalsCPU; m_concaveHasSeparatingNormals.copyToHost(concaveHasSeparatingNormalsCPU); b3AlignedObjectArray concaveSepNormalsHost; m_concaveSepNormals.copyToHost(concaveSepNormalsHost); - b3AlignedObjectArray hostContacts; if (nContacts) { @@ -4268,67 +3977,59 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* clippingFacesOutGPU.copyToHost(clippingFacesOutCPU); worldVertsB2GPU.copyToHost(worldVertsB2CPU); - - - for (int i=0;iresize(nContacts); hostContacts.resize(nContacts); //printf("contactOut4 (after newContactReductionKernel) = %d\n",nContacts); contactOut->copyFromHost(hostContacts); } - } //re-use? - - - } else + } + else { B3_PROFILE("clipHullHullConcaveConvexKernel"); nContacts = m_totalContactsOut.at(0); int newContactCapacity = contactOut->capacity(); //printf("contactOut5 = %d\n",nContacts); - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( triangleConvexPairsOut.getBufferCL(), true ), - b3BufferInfoCL( bodyBuf->getBufferCL(),true), - b3BufferInfoCL( gpuCollidables.getBufferCL(),true), - b3BufferInfoCL( convexData.getBufferCL(),true), - b3BufferInfoCL( gpuVertices.getBufferCL(),true), - b3BufferInfoCL( gpuUniqueEdges.getBufferCL(),true), - b3BufferInfoCL( gpuFaces.getBufferCL(),true), - b3BufferInfoCL( gpuIndices.getBufferCL(),true), - b3BufferInfoCL( gpuChildShapes.getBufferCL(),true), - b3BufferInfoCL( m_concaveSepNormals.getBufferCL()), - b3BufferInfoCL( contactOut->getBufferCL()), - b3BufferInfoCL( m_totalContactsOut.getBufferCL()) - }; - b3LauncherCL launcher(m_queue, m_clipHullHullConcaveConvexKernel,"m_clipHullHullConcaveConvexKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(triangleConvexPairsOut.getBufferCL(), true), + b3BufferInfoCL(bodyBuf->getBufferCL(), true), + b3BufferInfoCL(gpuCollidables.getBufferCL(), true), + b3BufferInfoCL(convexData.getBufferCL(), true), + b3BufferInfoCL(gpuVertices.getBufferCL(), true), + b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true), + b3BufferInfoCL(gpuFaces.getBufferCL(), true), + b3BufferInfoCL(gpuIndices.getBufferCL(), true), + b3BufferInfoCL(gpuChildShapes.getBufferCL(), true), + b3BufferInfoCL(m_concaveSepNormals.getBufferCL()), + b3BufferInfoCL(contactOut->getBufferCL()), + b3BufferInfoCL(m_totalContactsOut.getBufferCL())}; + b3LauncherCL launcher(m_queue, m_clipHullHullConcaveConvexKernel, "m_clipHullHullConcaveConvexKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); launcher.setConst(newContactCapacity); - launcher.setConst( numConcavePairs ); + launcher.setConst(numConcavePairs); int num = numConcavePairs; - launcher.launch1D( num); + launcher.launch1D(num); clFinish(m_queue); nContacts = m_totalContactsOut.at(0); contactOut->resize(nContacts); @@ -4337,12 +4038,10 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* contactOut->copyToHost(cpuContacts); } // printf("nContacts after = %d\n", nContacts); - }//numConcavePairs - - + } //numConcavePairs //convex-convex contact clipping - + bool breakupKernel = false; #ifdef __APPLE__ @@ -4350,166 +4049,149 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* #endif #ifdef CHECK_ON_HOST - bool computeConvexConvex = false; + bool computeConvexConvex = false; #else - bool computeConvexConvex = true; -#endif//CHECK_ON_HOST + bool computeConvexConvex = true; +#endif //CHECK_ON_HOST if (computeConvexConvex) { B3_PROFILE("clipHullHullKernel"); - if (breakupKernel) - { - - - - - worldVertsB1GPU.resize(vertexFaceCapacity*nPairs); - clippingFacesOutGPU.resize(nPairs); - worldNormalsAGPU.resize(nPairs); - worldVertsA1GPU.resize(vertexFaceCapacity*nPairs); - worldVertsB2GPU.resize(vertexFaceCapacity*nPairs); - - if (findConvexClippingFacesGPU) + if (breakupKernel) { - B3_PROFILE("findClippingFacesKernel"); - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( pairs->getBufferCL(), true ), - b3BufferInfoCL( bodyBuf->getBufferCL(),true), - b3BufferInfoCL( gpuCollidables.getBufferCL(),true), - b3BufferInfoCL( convexData.getBufferCL(),true), - b3BufferInfoCL( gpuVertices.getBufferCL(),true), - b3BufferInfoCL( gpuUniqueEdges.getBufferCL(),true), - b3BufferInfoCL( gpuFaces.getBufferCL(),true), - b3BufferInfoCL( gpuIndices.getBufferCL(),true), - b3BufferInfoCL( m_sepNormals.getBufferCL()), - b3BufferInfoCL( m_hasSeparatingNormals.getBufferCL()), - b3BufferInfoCL( clippingFacesOutGPU.getBufferCL()), - b3BufferInfoCL( worldVertsA1GPU.getBufferCL()), - b3BufferInfoCL( worldNormalsAGPU.getBufferCL()), - b3BufferInfoCL( worldVertsB1GPU.getBufferCL()) - }; + worldVertsB1GPU.resize(vertexFaceCapacity * nPairs); + clippingFacesOutGPU.resize(nPairs); + worldNormalsAGPU.resize(nPairs); + worldVertsA1GPU.resize(vertexFaceCapacity * nPairs); + worldVertsB2GPU.resize(vertexFaceCapacity * nPairs); - b3LauncherCL launcher(m_queue, m_findClippingFacesKernel,"m_findClippingFacesKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( vertexFaceCapacity); - launcher.setConst( nPairs ); - int num = nPairs; - launcher.launch1D( num); - clFinish(m_queue); - - } else - { - - float minDist = -1e30f; - float maxDist = 0.02f; - - b3AlignedObjectArray hostConvexData; - convexData.copyToHost(hostConvexData); - b3AlignedObjectArray hostCollidables; - gpuCollidables.copyToHost(hostCollidables); - - b3AlignedObjectArray hostHasSepNormals; - m_hasSeparatingNormals.copyToHost(hostHasSepNormals); - b3AlignedObjectArray cpuSepNormals; - m_sepNormals.copyToHost(cpuSepNormals); - - b3AlignedObjectArray hostPairs; - pairs->copyToHost(hostPairs); - b3AlignedObjectArray hostBodyBuf; - bodyBuf->copyToHost(hostBodyBuf); - - - //worldVertsB1GPU.resize(vertexFaceCapacity*nPairs); - b3AlignedObjectArray worldVertsB1CPU; - worldVertsB1GPU.copyToHost(worldVertsB1CPU); - - b3AlignedObjectArray clippingFacesOutCPU; - clippingFacesOutGPU.copyToHost(clippingFacesOutCPU); - - b3AlignedObjectArray worldNormalsACPU; - worldNormalsACPU.resize(nPairs); - - b3AlignedObjectArray worldVertsA1CPU; - worldVertsA1CPU.resize(worldVertsA1GPU.size()); - - - b3AlignedObjectArray hostVertices; - gpuVertices.copyToHost(hostVertices); - b3AlignedObjectArray hostFaces; - gpuFaces.copyToHost(hostFaces); - b3AlignedObjectArray hostIndices; - gpuIndices.copyToHost(hostIndices); - - - for (int i=0;igetBufferCL(), true), + b3BufferInfoCL(bodyBuf->getBufferCL(), true), + b3BufferInfoCL(gpuCollidables.getBufferCL(), true), + b3BufferInfoCL(convexData.getBufferCL(), true), + b3BufferInfoCL(gpuVertices.getBufferCL(), true), + b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true), + b3BufferInfoCL(gpuFaces.getBufferCL(), true), + b3BufferInfoCL(gpuIndices.getBufferCL(), true), + b3BufferInfoCL(m_sepNormals.getBufferCL()), + b3BufferInfoCL(m_hasSeparatingNormals.getBufferCL()), + b3BufferInfoCL(clippingFacesOutGPU.getBufferCL()), + b3BufferInfoCL(worldVertsA1GPU.getBufferCL()), + b3BufferInfoCL(worldNormalsAGPU.getBufferCL()), + b3BufferInfoCL(worldVertsB1GPU.getBufferCL())}; - int bodyIndexA = hostPairs[i].x; - int bodyIndexB = hostPairs[i].y; - - int collidableIndexA = hostBodyBuf[bodyIndexA].m_collidableIdx; - int collidableIndexB = hostBodyBuf[bodyIndexB].m_collidableIdx; - - int shapeIndexA = hostCollidables[collidableIndexA].m_shapeIndex; - int shapeIndexB = hostCollidables[collidableIndexB].m_shapeIndex; - - - if (hostHasSepNormals[i]) - { - b3FindClippingFaces(cpuSepNormals[i], - &hostConvexData[shapeIndexA], - &hostConvexData[shapeIndexB], - hostBodyBuf[bodyIndexA].m_pos,hostBodyBuf[bodyIndexA].m_quat, - hostBodyBuf[bodyIndexB].m_pos,hostBodyBuf[bodyIndexB].m_quat, - &worldVertsA1CPU.at(0),&worldNormalsACPU.at(0), - &worldVertsB1CPU.at(0), - vertexFaceCapacity,minDist,maxDist, - &hostVertices.at(0),&hostFaces.at(0), - &hostIndices.at(0), - &hostVertices.at(0),&hostFaces.at(0), - &hostIndices.at(0),&clippingFacesOutCPU.at(0),i); - } + b3LauncherCL launcher(m_queue, m_findClippingFacesKernel, "m_findClippingFacesKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(vertexFaceCapacity); + launcher.setConst(nPairs); + int num = nPairs; + launcher.launch1D(num); + clFinish(m_queue); } - - clippingFacesOutGPU.copyFromHost(clippingFacesOutCPU); - worldVertsA1GPU.copyFromHost(worldVertsA1CPU); - worldNormalsAGPU.copyFromHost(worldNormalsACPU); - worldVertsB1GPU.copyFromHost(worldVertsB1CPU); - - } - - - - - - ///clip face B against face A, reduce contacts and append them to a global contact array - if (1) - { - if (clipConvexFacesAndFindContactsCPU) + else { + float minDist = -1e30f; + float maxDist = 0.02f; - //b3AlignedObjectArray hostPairs; - //pairs->copyToHost(hostPairs); + b3AlignedObjectArray hostConvexData; + convexData.copyToHost(hostConvexData); + b3AlignedObjectArray hostCollidables; + gpuCollidables.copyToHost(hostCollidables); - b3AlignedObjectArray hostSepNormals; - m_sepNormals.copyToHost(hostSepNormals); - b3AlignedObjectArray hostHasSepAxis; - m_hasSeparatingNormals.copyToHost(hostHasSepAxis); + b3AlignedObjectArray hostHasSepNormals; + m_hasSeparatingNormals.copyToHost(hostHasSepNormals); + b3AlignedObjectArray cpuSepNormals; + m_sepNormals.copyToHost(cpuSepNormals); - b3AlignedObjectArray hostClippingFaces; - clippingFacesOutGPU.copyToHost(hostClippingFaces); - b3AlignedObjectArray worldVertsB2CPU; - worldVertsB2CPU.resize(vertexFaceCapacity*nPairs); - - b3AlignedObjectArrayworldVertsA1CPU; - worldVertsA1GPU.copyToHost(worldVertsA1CPU); - b3AlignedObjectArray worldNormalsACPU; - worldNormalsAGPU.copyToHost(worldNormalsACPU); + b3AlignedObjectArray hostPairs; + pairs->copyToHost(hostPairs); + b3AlignedObjectArray hostBodyBuf; + bodyBuf->copyToHost(hostBodyBuf); - b3AlignedObjectArray worldVertsB1CPU; + //worldVertsB1GPU.resize(vertexFaceCapacity*nPairs); + b3AlignedObjectArray worldVertsB1CPU; worldVertsB1GPU.copyToHost(worldVertsB1CPU); - /* + b3AlignedObjectArray clippingFacesOutCPU; + clippingFacesOutGPU.copyToHost(clippingFacesOutCPU); + + b3AlignedObjectArray worldNormalsACPU; + worldNormalsACPU.resize(nPairs); + + b3AlignedObjectArray worldVertsA1CPU; + worldVertsA1CPU.resize(worldVertsA1GPU.size()); + + b3AlignedObjectArray hostVertices; + gpuVertices.copyToHost(hostVertices); + b3AlignedObjectArray hostFaces; + gpuFaces.copyToHost(hostFaces); + b3AlignedObjectArray hostIndices; + gpuIndices.copyToHost(hostIndices); + + for (int i = 0; i < nPairs; i++) + { + int bodyIndexA = hostPairs[i].x; + int bodyIndexB = hostPairs[i].y; + + int collidableIndexA = hostBodyBuf[bodyIndexA].m_collidableIdx; + int collidableIndexB = hostBodyBuf[bodyIndexB].m_collidableIdx; + + int shapeIndexA = hostCollidables[collidableIndexA].m_shapeIndex; + int shapeIndexB = hostCollidables[collidableIndexB].m_shapeIndex; + + if (hostHasSepNormals[i]) + { + b3FindClippingFaces(cpuSepNormals[i], + &hostConvexData[shapeIndexA], + &hostConvexData[shapeIndexB], + hostBodyBuf[bodyIndexA].m_pos, hostBodyBuf[bodyIndexA].m_quat, + hostBodyBuf[bodyIndexB].m_pos, hostBodyBuf[bodyIndexB].m_quat, + &worldVertsA1CPU.at(0), &worldNormalsACPU.at(0), + &worldVertsB1CPU.at(0), + vertexFaceCapacity, minDist, maxDist, + &hostVertices.at(0), &hostFaces.at(0), + &hostIndices.at(0), + &hostVertices.at(0), &hostFaces.at(0), + &hostIndices.at(0), &clippingFacesOutCPU.at(0), i); + } + } + + clippingFacesOutGPU.copyFromHost(clippingFacesOutCPU); + worldVertsA1GPU.copyFromHost(worldVertsA1CPU); + worldNormalsAGPU.copyFromHost(worldNormalsACPU); + worldVertsB1GPU.copyFromHost(worldVertsB1CPU); + } + + ///clip face B against face A, reduce contacts and append them to a global contact array + if (1) + { + if (clipConvexFacesAndFindContactsCPU) + { + //b3AlignedObjectArray hostPairs; + //pairs->copyToHost(hostPairs); + + b3AlignedObjectArray hostSepNormals; + m_sepNormals.copyToHost(hostSepNormals); + b3AlignedObjectArray hostHasSepAxis; + m_hasSeparatingNormals.copyToHost(hostHasSepAxis); + + b3AlignedObjectArray hostClippingFaces; + clippingFacesOutGPU.copyToHost(hostClippingFaces); + b3AlignedObjectArray worldVertsB2CPU; + worldVertsB2CPU.resize(vertexFaceCapacity * nPairs); + + b3AlignedObjectArray worldVertsA1CPU; + worldVertsA1GPU.copyToHost(worldVertsA1CPU); + b3AlignedObjectArray worldNormalsACPU; + worldNormalsAGPU.copyToHost(worldNormalsACPU); + + b3AlignedObjectArray worldVertsB1CPU; + worldVertsB1GPU.copyToHost(worldVertsB1CPU); + + /* __global const b3Float4* separatingNormals, __global const int* hasSeparatingAxis, __global b3Int4* clippingFacesOut, @@ -4520,214 +4202,207 @@ void GpuSatCollision::computeConvexConvexContactsGPUSAT( b3OpenCLArray* int vertexFaceCapacity, int pairIndex */ - for (int i=0;ireserve(newContactCapacity); - - if (reduceConvexContactsOnGPU) - { + for (int i = 0; i < nPairs; i++) { - B3_PROFILE("newContactReductionKernel"); - b3BufferInfoCL bInfo[] = - { - b3BufferInfoCL( pairs->getBufferCL(), true ), - b3BufferInfoCL( bodyBuf->getBufferCL(),true), - b3BufferInfoCL( m_sepNormals.getBufferCL()), - b3BufferInfoCL( m_hasSeparatingNormals.getBufferCL()), - b3BufferInfoCL( contactOut->getBufferCL()), - b3BufferInfoCL( clippingFacesOutGPU.getBufferCL()), - b3BufferInfoCL( worldVertsB2GPU.getBufferCL()), - b3BufferInfoCL( m_totalContactsOut.getBufferCL()) - }; - - b3LauncherCL launcher(m_queue, m_newContactReductionKernel,"m_newContactReductionKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst(vertexFaceCapacity); - launcher.setConst(newContactCapacity); - launcher.setConst( nPairs ); - int num = nPairs; - - launcher.launch1D( num); - } - nContacts = m_totalContactsOut.at(0); - contactOut->resize(nContacts); - } else - { - - volatile int nGlobalContactsOut = nContacts; - b3AlignedObjectArray hostPairs; - pairs->copyToHost(hostPairs); - b3AlignedObjectArray hostBodyBuf; - bodyBuf->copyToHost(hostBodyBuf); - b3AlignedObjectArray hostSepNormals; - m_sepNormals.copyToHost(hostSepNormals); - b3AlignedObjectArray hostHasSepAxis; - m_hasSeparatingNormals.copyToHost(hostHasSepAxis); - b3AlignedObjectArray hostContactsOut; - contactOut->copyToHost(hostContactsOut); - hostContactsOut.resize(newContactCapacity); - - b3AlignedObjectArray hostClippingFaces; - clippingFacesOutGPU.copyToHost(hostClippingFaces); - b3AlignedObjectArray worldVertsB2CPU; - worldVertsB2GPU.copyToHost(worldVertsB2CPU); - - for (int i=0;icopyFromHost(hostContactsOut); + clippingFacesOutGPU.copyFromHost(hostClippingFaces); + worldVertsB2GPU.copyFromHost(worldVertsB2CPU); + } + else + { + B3_PROFILE("clipFacesAndFindContacts"); + //nContacts = m_totalContactsOut.at(0); + //int h = m_hasSeparatingNormals.at(0); + //int4 p = clippingFacesOutGPU.at(0); + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(m_sepNormals.getBufferCL()), + b3BufferInfoCL(m_hasSeparatingNormals.getBufferCL()), + b3BufferInfoCL(clippingFacesOutGPU.getBufferCL()), + b3BufferInfoCL(worldVertsA1GPU.getBufferCL()), + b3BufferInfoCL(worldNormalsAGPU.getBufferCL()), + b3BufferInfoCL(worldVertsB1GPU.getBufferCL()), + b3BufferInfoCL(worldVertsB2GPU.getBufferCL())}; + + b3LauncherCL launcher(m_queue, m_clipFacesAndFindContacts, "m_clipFacesAndFindContacts"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(vertexFaceCapacity); + + launcher.setConst(nPairs); + int debugMode = 0; + launcher.setConst(debugMode); + int num = nPairs; + launcher.launch1D(num); + clFinish(m_queue); + } + + { + nContacts = m_totalContactsOut.at(0); + //printf("nContacts = %d\n",nContacts); + + int newContactCapacity = nContacts + nPairs; + contactOut->reserve(newContactCapacity); + + if (reduceConvexContactsOnGPU) + { + { + B3_PROFILE("newContactReductionKernel"); + b3BufferInfoCL bInfo[] = + { + b3BufferInfoCL(pairs->getBufferCL(), true), + b3BufferInfoCL(bodyBuf->getBufferCL(), true), + b3BufferInfoCL(m_sepNormals.getBufferCL()), + b3BufferInfoCL(m_hasSeparatingNormals.getBufferCL()), + b3BufferInfoCL(contactOut->getBufferCL()), + b3BufferInfoCL(clippingFacesOutGPU.getBufferCL()), + b3BufferInfoCL(worldVertsB2GPU.getBufferCL()), + b3BufferInfoCL(m_totalContactsOut.getBufferCL())}; + + b3LauncherCL launcher(m_queue, m_newContactReductionKernel, "m_newContactReductionKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(vertexFaceCapacity); + launcher.setConst(newContactCapacity); + launcher.setConst(nPairs); + int num = nPairs; + + launcher.launch1D(num); + } + nContacts = m_totalContactsOut.at(0); + contactOut->resize(nContacts); + } + else + { + volatile int nGlobalContactsOut = nContacts; + b3AlignedObjectArray hostPairs; + pairs->copyToHost(hostPairs); + b3AlignedObjectArray hostBodyBuf; + bodyBuf->copyToHost(hostBodyBuf); + b3AlignedObjectArray hostSepNormals; + m_sepNormals.copyToHost(hostSepNormals); + b3AlignedObjectArray hostHasSepAxis; + m_hasSeparatingNormals.copyToHost(hostHasSepAxis); + b3AlignedObjectArray hostContactsOut; + contactOut->copyToHost(hostContactsOut); + hostContactsOut.resize(newContactCapacity); + + b3AlignedObjectArray hostClippingFaces; + clippingFacesOutGPU.copyToHost(hostClippingFaces); + b3AlignedObjectArray worldVertsB2CPU; + worldVertsB2GPU.copyToHost(worldVertsB2CPU); + + for (int i = 0; i < nPairs; i++) + { + b3NewContactReductionKernel(&hostPairs.at(0), + &hostBodyBuf.at(0), + &hostSepNormals.at(0), + &hostHasSepAxis.at(0), + &hostContactsOut.at(0), + &hostClippingFaces.at(0), + &worldVertsB2CPU.at(0), + &nGlobalContactsOut, + vertexFaceCapacity, + newContactCapacity, + nPairs, + i); + } + + nContacts = nGlobalContactsOut; + m_totalContactsOut.copyFromHostPointer(&nContacts, 1, 0, true); + hostContactsOut.resize(nContacts); + //printf("contactOut4 (after newContactReductionKernel) = %d\n",nContacts); + contactOut->copyFromHost(hostContactsOut); + } + // b3Contact4 pt = contactOut->at(0); + // printf("nContacts = %d\n",nContacts); } - // b3Contact4 pt = contactOut->at(0); - // printf("nContacts = %d\n",nContacts); } } - } - else//breakupKernel - { + else //breakupKernel + { + if (nPairs) + { + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(pairs->getBufferCL(), true), + b3BufferInfoCL(bodyBuf->getBufferCL(), true), + b3BufferInfoCL(gpuCollidables.getBufferCL(), true), + b3BufferInfoCL(convexData.getBufferCL(), true), + b3BufferInfoCL(gpuVertices.getBufferCL(), true), + b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true), + b3BufferInfoCL(gpuFaces.getBufferCL(), true), + b3BufferInfoCL(gpuIndices.getBufferCL(), true), + b3BufferInfoCL(m_sepNormals.getBufferCL()), + b3BufferInfoCL(m_hasSeparatingNormals.getBufferCL()), + b3BufferInfoCL(contactOut->getBufferCL()), + b3BufferInfoCL(m_totalContactsOut.getBufferCL())}; + b3LauncherCL launcher(m_queue, m_clipHullHullKernel, "m_clipHullHullKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(nPairs); + launcher.setConst(maxContactCapacity); - if (nPairs) + int num = nPairs; + launcher.launch1D(num); + clFinish(m_queue); + + nContacts = m_totalContactsOut.at(0); + if (nContacts >= maxContactCapacity) + { + b3Error("Exceeded contact capacity (%d/%d)\n", nContacts, maxContactCapacity); + nContacts = maxContactCapacity; + } + contactOut->resize(nContacts); + } + } + + int nCompoundsPairs = m_gpuCompoundPairs.size(); + + if (nCompoundsPairs) { b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( pairs->getBufferCL(), true ), - b3BufferInfoCL( bodyBuf->getBufferCL(),true), - b3BufferInfoCL( gpuCollidables.getBufferCL(),true), - b3BufferInfoCL( convexData.getBufferCL(),true), - b3BufferInfoCL( gpuVertices.getBufferCL(),true), - b3BufferInfoCL( gpuUniqueEdges.getBufferCL(),true), - b3BufferInfoCL( gpuFaces.getBufferCL(),true), - b3BufferInfoCL( gpuIndices.getBufferCL(),true), - b3BufferInfoCL( m_sepNormals.getBufferCL()), - b3BufferInfoCL( m_hasSeparatingNormals.getBufferCL()), - b3BufferInfoCL( contactOut->getBufferCL()), - b3BufferInfoCL( m_totalContactsOut.getBufferCL()) - }; - b3LauncherCL launcher(m_queue, m_clipHullHullKernel,"m_clipHullHullKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( nPairs ); + b3BufferInfoCL(m_gpuCompoundPairs.getBufferCL(), true), + b3BufferInfoCL(bodyBuf->getBufferCL(), true), + b3BufferInfoCL(gpuCollidables.getBufferCL(), true), + b3BufferInfoCL(convexData.getBufferCL(), true), + b3BufferInfoCL(gpuVertices.getBufferCL(), true), + b3BufferInfoCL(gpuUniqueEdges.getBufferCL(), true), + b3BufferInfoCL(gpuFaces.getBufferCL(), true), + b3BufferInfoCL(gpuIndices.getBufferCL(), true), + b3BufferInfoCL(gpuChildShapes.getBufferCL(), true), + b3BufferInfoCL(m_gpuCompoundSepNormals.getBufferCL(), true), + b3BufferInfoCL(m_gpuHasCompoundSepNormals.getBufferCL(), true), + b3BufferInfoCL(contactOut->getBufferCL()), + b3BufferInfoCL(m_totalContactsOut.getBufferCL())}; + b3LauncherCL launcher(m_queue, m_clipCompoundsHullHullKernel, "m_clipCompoundsHullHullKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(nCompoundsPairs); launcher.setConst(maxContactCapacity); - int num = nPairs; - launcher.launch1D( num); + int num = nCompoundsPairs; + launcher.launch1D(num); clFinish(m_queue); nContacts = m_totalContactsOut.at(0); - if (nContacts >= maxContactCapacity) + if (nContacts > maxContactCapacity) { - b3Error("Exceeded contact capacity (%d/%d)\n",nContacts,maxContactCapacity); + b3Error("Error: contacts exceeds capacity (%d/%d)\n", nContacts, maxContactCapacity); nContacts = maxContactCapacity; } contactOut->resize(nContacts); - } + } //if nCompoundsPairs } - - - int nCompoundsPairs = m_gpuCompoundPairs.size(); - - if (nCompoundsPairs) - { - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( m_gpuCompoundPairs.getBufferCL(), true ), - b3BufferInfoCL( bodyBuf->getBufferCL(),true), - b3BufferInfoCL( gpuCollidables.getBufferCL(),true), - b3BufferInfoCL( convexData.getBufferCL(),true), - b3BufferInfoCL( gpuVertices.getBufferCL(),true), - b3BufferInfoCL( gpuUniqueEdges.getBufferCL(),true), - b3BufferInfoCL( gpuFaces.getBufferCL(),true), - b3BufferInfoCL( gpuIndices.getBufferCL(),true), - b3BufferInfoCL( gpuChildShapes.getBufferCL(),true), - b3BufferInfoCL( m_gpuCompoundSepNormals.getBufferCL(),true), - b3BufferInfoCL( m_gpuHasCompoundSepNormals.getBufferCL(),true), - b3BufferInfoCL( contactOut->getBufferCL()), - b3BufferInfoCL( m_totalContactsOut.getBufferCL()) - }; - b3LauncherCL launcher(m_queue, m_clipCompoundsHullHullKernel,"m_clipCompoundsHullHullKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( nCompoundsPairs ); - launcher.setConst(maxContactCapacity); - - int num = nCompoundsPairs; - launcher.launch1D( num); - clFinish(m_queue); - - nContacts = m_totalContactsOut.at(0); - if (nContacts>maxContactCapacity) - { - - b3Error("Error: contacts exceeds capacity (%d/%d)\n", nContacts, maxContactCapacity); - nContacts = maxContactCapacity; - } - contactOut->resize(nContacts); - }//if nCompoundsPairs - } - }//contactClippingOnGpu + } //contactClippingOnGpu //printf("nContacts end = %d\n",nContacts); - + //printf("frameCount = %d\n",frameCount++); } diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3ConvexHullContact.h b/src/Bullet3OpenCL/NarrowphaseCollision/b3ConvexHullContact.h index e24c1579c..53e8c4ed4 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3ConvexHullContact.h +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3ConvexHullContact.h @@ -17,102 +17,90 @@ //#include "../../dynamics/basic_demo/Stubs/ChNarrowPhase.h" - - - struct GpuSatCollision { - cl_context m_context; - cl_device_id m_device; - cl_command_queue m_queue; - cl_kernel m_findSeparatingAxisKernel; - cl_kernel m_mprPenetrationKernel; - cl_kernel m_findSeparatingAxisUnitSphereKernel; - + cl_context m_context; + cl_device_id m_device; + cl_command_queue m_queue; + cl_kernel m_findSeparatingAxisKernel; + cl_kernel m_mprPenetrationKernel; + cl_kernel m_findSeparatingAxisUnitSphereKernel; cl_kernel m_findSeparatingAxisVertexFaceKernel; cl_kernel m_findSeparatingAxisEdgeEdgeKernel; - - cl_kernel m_findConcaveSeparatingAxisKernel; - cl_kernel m_findConcaveSeparatingAxisVertexFaceKernel; - cl_kernel m_findConcaveSeparatingAxisEdgeEdgeKernel; - - - - - cl_kernel m_findCompoundPairsKernel; - cl_kernel m_processCompoundPairsKernel; - cl_kernel m_clipHullHullKernel; - cl_kernel m_clipCompoundsHullHullKernel; - - cl_kernel m_clipFacesAndFindContacts; - cl_kernel m_findClippingFacesKernel; - - cl_kernel m_clipHullHullConcaveConvexKernel; -// cl_kernel m_extractManifoldAndAddContactKernel; - cl_kernel m_newContactReductionKernel; + cl_kernel m_findConcaveSeparatingAxisKernel; + cl_kernel m_findConcaveSeparatingAxisVertexFaceKernel; + cl_kernel m_findConcaveSeparatingAxisEdgeEdgeKernel; - cl_kernel m_bvhTraversalKernel; - cl_kernel m_primitiveContactsKernel; - cl_kernel m_findConcaveSphereContactsKernel; + cl_kernel m_findCompoundPairsKernel; + cl_kernel m_processCompoundPairsKernel; + + cl_kernel m_clipHullHullKernel; + cl_kernel m_clipCompoundsHullHullKernel; + + cl_kernel m_clipFacesAndFindContacts; + cl_kernel m_findClippingFacesKernel; + + cl_kernel m_clipHullHullConcaveConvexKernel; + // cl_kernel m_extractManifoldAndAddContactKernel; + cl_kernel m_newContactReductionKernel; + + cl_kernel m_bvhTraversalKernel; + cl_kernel m_primitiveContactsKernel; + cl_kernel m_findConcaveSphereContactsKernel; + + cl_kernel m_processCompoundPairsPrimitivesKernel; - cl_kernel m_processCompoundPairsPrimitivesKernel; - b3OpenCLArray m_unitSphereDirections; - b3OpenCLArray m_totalContactsOut; + b3OpenCLArray m_totalContactsOut; b3OpenCLArray m_sepNormals; b3OpenCLArray m_dmins; - b3OpenCLArray m_hasSeparatingNormals; + b3OpenCLArray m_hasSeparatingNormals; b3OpenCLArray m_concaveSepNormals; - b3OpenCLArray m_concaveHasSeparatingNormals; - b3OpenCLArray m_numConcavePairsOut; + b3OpenCLArray m_concaveHasSeparatingNormals; + b3OpenCLArray m_numConcavePairsOut; b3OpenCLArray m_gpuCompoundPairs; b3OpenCLArray m_gpuCompoundSepNormals; - b3OpenCLArray m_gpuHasCompoundSepNormals; - b3OpenCLArray m_numCompoundPairsOut; - + b3OpenCLArray m_gpuHasCompoundSepNormals; + b3OpenCLArray m_numCompoundPairsOut; - GpuSatCollision(cl_context ctx,cl_device_id device, cl_command_queue q ); + GpuSatCollision(cl_context ctx, cl_device_id device, cl_command_queue q); virtual ~GpuSatCollision(); - - void computeConvexConvexContactsGPUSAT( b3OpenCLArray* pairs, int nPairs, - const b3OpenCLArray* bodyBuf, - b3OpenCLArray* contactOut, int& nContacts, - const b3OpenCLArray* oldContacts, - int maxContactCapacity, - int compoundPairCapacity, - const b3OpenCLArray& hostConvexData, - const b3OpenCLArray& vertices, - const b3OpenCLArray& uniqueEdges, - const b3OpenCLArray& faces, - const b3OpenCLArray& indices, - const b3OpenCLArray& gpuCollidables, - const b3OpenCLArray& gpuChildShapes, - - const b3OpenCLArray& clAabbsWorldSpace, - const b3OpenCLArray& clAabbsLocalSpace, - - b3OpenCLArray& worldVertsB1GPU, - b3OpenCLArray& clippingFacesOutGPU, - b3OpenCLArray& worldNormalsAGPU, - b3OpenCLArray& worldVertsA1GPU, - b3OpenCLArray& worldVertsB2GPU, - b3AlignedObjectArray& bvhData, - b3OpenCLArray* treeNodesGPU, - b3OpenCLArray* subTreesGPU, - b3OpenCLArray* bvhInfo, - int numObjects, - int maxTriConvexPairCapacity, - b3OpenCLArray& triangleConvexPairs, - int& numTriConvexPairsOut - ); + void computeConvexConvexContactsGPUSAT(b3OpenCLArray* pairs, int nPairs, + const b3OpenCLArray* bodyBuf, + b3OpenCLArray* contactOut, int& nContacts, + const b3OpenCLArray* oldContacts, + int maxContactCapacity, + int compoundPairCapacity, + const b3OpenCLArray& hostConvexData, + const b3OpenCLArray& vertices, + const b3OpenCLArray& uniqueEdges, + const b3OpenCLArray& faces, + const b3OpenCLArray& indices, + const b3OpenCLArray& gpuCollidables, + const b3OpenCLArray& gpuChildShapes, + const b3OpenCLArray& clAabbsWorldSpace, + const b3OpenCLArray& clAabbsLocalSpace, + b3OpenCLArray& worldVertsB1GPU, + b3OpenCLArray& clippingFacesOutGPU, + b3OpenCLArray& worldNormalsAGPU, + b3OpenCLArray& worldVertsA1GPU, + b3OpenCLArray& worldVertsB2GPU, + b3AlignedObjectArray& bvhData, + b3OpenCLArray* treeNodesGPU, + b3OpenCLArray* subTreesGPU, + b3OpenCLArray* bvhInfo, + int numObjects, + int maxTriConvexPairCapacity, + b3OpenCLArray& triangleConvexPairs, + int& numTriConvexPairsOut); }; -#endif //_CONVEX_HULL_CONTACT_H +#endif //_CONVEX_HULL_CONTACT_H diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3ConvexPolyhedronCL.h b/src/Bullet3OpenCL/NarrowphaseCollision/b3ConvexPolyhedronCL.h index 337100fb1..c4cf70007 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3ConvexPolyhedronCL.h +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3ConvexPolyhedronCL.h @@ -4,6 +4,4 @@ #include "Bullet3Common/b3Transform.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3ConvexPolyhedronData.h" - - -#endif //CONVEX_POLYHEDRON_CL +#endif //CONVEX_POLYHEDRON_CL diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3GjkEpa.cpp b/src/Bullet3OpenCL/NarrowphaseCollision/b3GjkEpa.cpp index d636f983c..974b246f0 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3GjkEpa.cpp +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3GjkEpa.cpp @@ -29,902 +29,951 @@ GJK-EPA collision solver by Nathanael Presson, 2008 namespace gjkepa2_impl2 { +// Config - // Config +/* GJK */ +#define GJK_MAX_ITERATIONS 128 +#define GJK_ACCURACY ((b3Scalar)0.0001) +#define GJK_MIN_DISTANCE ((b3Scalar)0.0001) +#define GJK_DUPLICATED_EPS ((b3Scalar)0.0001) +#define GJK_SIMPLEX2_EPS ((b3Scalar)0.0) +#define GJK_SIMPLEX3_EPS ((b3Scalar)0.0) +#define GJK_SIMPLEX4_EPS ((b3Scalar)0.0) - /* GJK */ -#define GJK_MAX_ITERATIONS 128 -#define GJK_ACCURACY ((b3Scalar)0.0001) -#define GJK_MIN_DISTANCE ((b3Scalar)0.0001) -#define GJK_DUPLICATED_EPS ((b3Scalar)0.0001) -#define GJK_SIMPLEX2_EPS ((b3Scalar)0.0) -#define GJK_SIMPLEX3_EPS ((b3Scalar)0.0) -#define GJK_SIMPLEX4_EPS ((b3Scalar)0.0) +/* EPA */ +#define EPA_MAX_VERTICES 64 +#define EPA_MAX_FACES (EPA_MAX_VERTICES * 2) +#define EPA_MAX_ITERATIONS 255 +#define EPA_ACCURACY ((b3Scalar)0.0001) +#define EPA_FALLBACK (10 * EPA_ACCURACY) +#define EPA_PLANE_EPS ((b3Scalar)0.00001) +#define EPA_INSIDE_EPS ((b3Scalar)0.01) - /* EPA */ -#define EPA_MAX_VERTICES 64 -#define EPA_MAX_FACES (EPA_MAX_VERTICES*2) -#define EPA_MAX_ITERATIONS 255 -#define EPA_ACCURACY ((b3Scalar)0.0001) -#define EPA_FALLBACK (10*EPA_ACCURACY) -#define EPA_PLANE_EPS ((b3Scalar)0.00001) -#define EPA_INSIDE_EPS ((b3Scalar)0.01) +// Shorthands +// MinkowskiDiff +struct b3MinkowskiDiff +{ + const b3ConvexPolyhedronData* m_shapes[2]; - // Shorthands - + b3Matrix3x3 m_toshape1; + b3Transform m_toshape0; - // MinkowskiDiff - struct b3MinkowskiDiff + bool m_enableMargin; + + void EnableMargin(bool enable) { - - - const b3ConvexPolyhedronData* m_shapes[2]; - - - b3Matrix3x3 m_toshape1; - b3Transform m_toshape0; - - bool m_enableMargin; - - - void EnableMargin(bool enable) + m_enableMargin = enable; + } + inline b3Vector3 Support0(const b3Vector3& d, const b3AlignedObjectArray& verticesA) const + { + if (m_enableMargin) { - m_enableMargin = enable; - } - inline b3Vector3 Support0(const b3Vector3& d, const b3AlignedObjectArray& verticesA) const - { - if (m_enableMargin) - { - return localGetSupportVertexWithMargin(d,m_shapes[0],verticesA,0.f); - } else - { - return localGetSupportVertexWithoutMargin(d,m_shapes[0],verticesA); - } + return localGetSupportVertexWithMargin(d, m_shapes[0], verticesA, 0.f); } - inline b3Vector3 Support1(const b3Vector3& d, const b3AlignedObjectArray& verticesB) const + else { - if (m_enableMargin) - { - return m_toshape0*(localGetSupportVertexWithMargin(m_toshape1*d,m_shapes[1],verticesB,0.f)); - } else - { - return m_toshape0*(localGetSupportVertexWithoutMargin(m_toshape1*d,m_shapes[1],verticesB)); - } + return localGetSupportVertexWithoutMargin(d, m_shapes[0], verticesA); } + } + inline b3Vector3 Support1(const b3Vector3& d, const b3AlignedObjectArray& verticesB) const + { + if (m_enableMargin) + { + return m_toshape0 * (localGetSupportVertexWithMargin(m_toshape1 * d, m_shapes[1], verticesB, 0.f)); + } + else + { + return m_toshape0 * (localGetSupportVertexWithoutMargin(m_toshape1 * d, m_shapes[1], verticesB)); + } + } - inline b3Vector3 Support(const b3Vector3& d, const b3AlignedObjectArray& verticesA, const b3AlignedObjectArray& verticesB) const - { - return(Support0(d,verticesA)-Support1(-d,verticesB)); - } - b3Vector3 Support(const b3Vector3& d,unsigned int index,const b3AlignedObjectArray& verticesA, const b3AlignedObjectArray& verticesB) const - { - if(index) - return(Support1(d,verticesA)); - else - return(Support0(d,verticesB)); - } + inline b3Vector3 Support(const b3Vector3& d, const b3AlignedObjectArray& verticesA, const b3AlignedObjectArray& verticesB) const + { + return (Support0(d, verticesA) - Support1(-d, verticesB)); + } + b3Vector3 Support(const b3Vector3& d, unsigned int index, const b3AlignedObjectArray& verticesA, const b3AlignedObjectArray& verticesB) const + { + if (index) + return (Support1(d, verticesA)); + else + return (Support0(d, verticesB)); + } +}; + +typedef b3MinkowskiDiff tShape; + +// GJK +struct b3GJK +{ + /* Types */ + struct sSV + { + b3Vector3 d, w; }; - - typedef b3MinkowskiDiff tShape; - - - // GJK - struct b3GJK + struct sSimplex { - /* Types */ - struct sSV + sSV* c[4]; + b3Scalar p[4]; + unsigned int rank; + }; + struct eStatus + { + enum _ { - b3Vector3 d,w; - }; - struct sSimplex - { - sSV* c[4]; - b3Scalar p[4]; - unsigned int rank; - }; - struct eStatus { enum _ { Valid, Inside, - Failed };}; - /* Fields */ - tShape m_shape; - const b3AlignedObjectArray& m_verticesA; - const b3AlignedObjectArray& m_verticesB; - b3Vector3 m_ray; - b3Scalar m_distance; - sSimplex m_simplices[2]; - sSV m_store[4]; - sSV* m_free[4]; - unsigned int m_nfree; - unsigned int m_current; - sSimplex* m_simplex; - eStatus::_ m_status; - /* Methods */ - b3GJK(const b3AlignedObjectArray& verticesA,const b3AlignedObjectArray& verticesB) - :m_verticesA(verticesA),m_verticesB(verticesB) - { - Initialize(); - } - void Initialize() - { - m_ray = b3MakeVector3(0,0,0); - m_nfree = 0; - m_status = eStatus::Failed; - m_current = 0; - m_distance = 0; - } - eStatus::_ Evaluate(const tShape& shapearg,const b3Vector3& guess) - { - unsigned int iterations=0; - b3Scalar sqdist=0; - b3Scalar alpha=0; - b3Vector3 lastw[4]; - unsigned int clastw=0; - /* Initialize solver */ - m_free[0] = &m_store[0]; - m_free[1] = &m_store[1]; - m_free[2] = &m_store[2]; - m_free[3] = &m_store[3]; - m_nfree = 4; - m_current = 0; - m_status = eStatus::Valid; - m_shape = shapearg; - m_distance = 0; - /* Initialize simplex */ - m_simplices[0].rank = 0; - m_ray = guess; - const b3Scalar sqrl= m_ray.length2(); - appendvertice(m_simplices[0],sqrl>0?-m_ray:b3MakeVector3(1,0,0)); - m_simplices[0].p[0] = 1; - m_ray = m_simplices[0].c[0]->w; - sqdist = sqrl; - lastw[0] = - lastw[1] = - lastw[2] = - lastw[3] = m_ray; - /* Loop */ - do { - const unsigned int next=1-m_current; - sSimplex& cs=m_simplices[m_current]; - sSimplex& ns=m_simplices[next]; - /* Check zero */ - const b3Scalar rl=m_ray.length(); - if(rlw; - bool found=false; - for(unsigned int i=0;i<4;++i) - { - if((w-lastw[i]).length2()w, - cs.c[1]->w, - weights,mask);break; - case 3: sqdist=projectorigin( cs.c[0]->w, - cs.c[1]->w, - cs.c[2]->w, - weights,mask);break; - case 4: sqdist=projectorigin( cs.c[0]->w, - cs.c[1]->w, - cs.c[2]->w, - cs.c[3]->w, - weights,mask);break; - } - if(sqdist>=0) - {/* Valid */ - ns.rank = 0; - m_ray = b3MakeVector3(0,0,0); - m_current = next; - for(unsigned int i=0,ni=cs.rank;iw*weights[i]; - } - else - { - m_free[m_nfree++] = cs.c[i]; - } - } - if(mask==15) m_status=eStatus::Inside; - } - else - {/* Return old simplex */ - removevertice(m_simplices[m_current]); - break; - } - m_status=((++iterations)rank) - { - case 1: - { - for(unsigned int i=0;i<3;++i) - { - b3Vector3 axis=b3MakeVector3(0,0,0); - axis[i]=1; - appendvertice(*m_simplex, axis); - if(EncloseOrigin()) return(true); - removevertice(*m_simplex); - appendvertice(*m_simplex,-axis); - if(EncloseOrigin()) return(true); - removevertice(*m_simplex); - } - } - break; - case 2: - { - const b3Vector3 d=m_simplex->c[1]->w-m_simplex->c[0]->w; - for(unsigned int i=0;i<3;++i) - { - b3Vector3 axis=b3MakeVector3(0,0,0); - axis[i]=1; - const b3Vector3 p=b3Cross(d,axis); - if(p.length2()>0) - { - appendvertice(*m_simplex, p); - if(EncloseOrigin()) return(true); - removevertice(*m_simplex); - appendvertice(*m_simplex,-p); - if(EncloseOrigin()) return(true); - removevertice(*m_simplex); - } - } - } - break; - case 3: - { - const b3Vector3 n=b3Cross(m_simplex->c[1]->w-m_simplex->c[0]->w, - m_simplex->c[2]->w-m_simplex->c[0]->w); - if(n.length2()>0) - { - appendvertice(*m_simplex,n); - if(EncloseOrigin()) return(true); - removevertice(*m_simplex); - appendvertice(*m_simplex,-n); - if(EncloseOrigin()) return(true); - removevertice(*m_simplex); - } - } - break; - case 4: - { - if(b3Fabs(det( m_simplex->c[0]->w-m_simplex->c[3]->w, - m_simplex->c[1]->w-m_simplex->c[3]->w, - m_simplex->c[2]->w-m_simplex->c[3]->w))>0) - return(true); - } - break; - } - return(false); - } - /* Internals */ - void getsupport(const b3Vector3& d,sSV& sv) const - { - sv.d = d/d.length(); - sv.w = m_shape.Support(sv.d,m_verticesA,m_verticesB); - } - void removevertice(sSimplex& simplex) - { - m_free[m_nfree++]=simplex.c[--simplex.rank]; - } - void appendvertice(sSimplex& simplex,const b3Vector3& v) - { - simplex.p[simplex.rank]=0; - simplex.c[simplex.rank]=m_free[--m_nfree]; - getsupport(v,*simplex.c[simplex.rank++]); - } - static b3Scalar det(const b3Vector3& a,const b3Vector3& b,const b3Vector3& c) - { - return( a.y*b.z*c.x+a.z*b.x*c.y- - a.x*b.z*c.y-a.y*b.x*c.z+ - a.x*b.y*c.z-a.z*b.y*c.x); - } - static b3Scalar projectorigin( const b3Vector3& a, - const b3Vector3& b, - b3Scalar* w,unsigned int& m) - { - const b3Vector3 d=b-a; - const b3Scalar l=d.length2(); - if(l>GJK_SIMPLEX2_EPS) - { - const b3Scalar t(l>0?-b3Dot(a,d)/l:0); - if(t>=1) { w[0]=0;w[1]=1;m=2;return(b.length2()); } - else if(t<=0) { w[0]=1;w[1]=0;m=1;return(a.length2()); } - else { w[0]=1-(w[1]=t);m=3;return((a+d*t).length2()); } - } - return(-1); - } - static b3Scalar projectorigin( const b3Vector3& a, - const b3Vector3& b, - const b3Vector3& c, - b3Scalar* w,unsigned int& m) - { - static const unsigned int imd3[]={1,2,0}; - const b3Vector3* vt[]={&a,&b,&c}; - const b3Vector3 dl[]={a-b,b-c,c-a}; - const b3Vector3 n=b3Cross(dl[0],dl[1]); - const b3Scalar l=n.length2(); - if(l>GJK_SIMPLEX3_EPS) - { - b3Scalar mindist=-1; - b3Scalar subw[2]={0.f,0.f}; - unsigned int subm(0); - for(unsigned int i=0;i<3;++i) - { - if(b3Dot(*vt[i],b3Cross(dl[i],n))>0) - { - const unsigned int j=imd3[i]; - const b3Scalar subd(projectorigin(*vt[i],*vt[j],subw,subm)); - if((mindist<0)||(subd(((subm&1)?1<GJK_SIMPLEX4_EPS)) - { - b3Scalar mindist=-1; - b3Scalar subw[3]={0.f,0.f,0.f}; - unsigned int subm(0); - for(unsigned int i=0;i<3;++i) - { - const unsigned int j=imd3[i]; - const b3Scalar s=vl*b3Dot(d,b3Cross(dl[i],dl[j])); - if(s>0) - { - const b3Scalar subd=projectorigin(*vt[i],*vt[j],d,subw,subm); - if((mindist<0)||(subd((subm&1?1<& m_verticesA; + const b3AlignedObjectArray& m_verticesB; + b3Vector3 m_ray; + b3Scalar m_distance; + sSimplex m_simplices[2]; + sSV m_store[4]; + sSV* m_free[4]; + unsigned int m_nfree; + unsigned int m_current; + sSimplex* m_simplex; + eStatus::_ m_status; + /* Methods */ + b3GJK(const b3AlignedObjectArray& verticesA, const b3AlignedObjectArray& verticesB) + : m_verticesA(verticesA), m_verticesB(verticesB) { - /* Types */ - typedef b3GJK::sSV sSV; - struct sFace + Initialize(); + } + void Initialize() + { + m_ray = b3MakeVector3(0, 0, 0); + m_nfree = 0; + m_status = eStatus::Failed; + m_current = 0; + m_distance = 0; + } + eStatus::_ Evaluate(const tShape& shapearg, const b3Vector3& guess) + { + unsigned int iterations = 0; + b3Scalar sqdist = 0; + b3Scalar alpha = 0; + b3Vector3 lastw[4]; + unsigned int clastw = 0; + /* Initialize solver */ + m_free[0] = &m_store[0]; + m_free[1] = &m_store[1]; + m_free[2] = &m_store[2]; + m_free[3] = &m_store[3]; + m_nfree = 4; + m_current = 0; + m_status = eStatus::Valid; + m_shape = shapearg; + m_distance = 0; + /* Initialize simplex */ + m_simplices[0].rank = 0; + m_ray = guess; + const b3Scalar sqrl = m_ray.length2(); + appendvertice(m_simplices[0], sqrl > 0 ? -m_ray : b3MakeVector3(1, 0, 0)); + m_simplices[0].p[0] = 1; + m_ray = m_simplices[0].c[0]->w; + sqdist = sqrl; + lastw[0] = + lastw[1] = + lastw[2] = + lastw[3] = m_ray; + /* Loop */ + do { - b3Vector3 n; - b3Scalar d; - sSV* c[3]; - sFace* f[3]; - sFace* l[2]; - unsigned char e[3]; - unsigned char pass; - }; - struct sList + const unsigned int next = 1 - m_current; + sSimplex& cs = m_simplices[m_current]; + sSimplex& ns = m_simplices[next]; + /* Check zero */ + const b3Scalar rl = m_ray.length(); + if (rl < GJK_MIN_DISTANCE) + { /* Touching or inside */ + m_status = eStatus::Inside; + break; + } + /* Append new vertice in -'v' direction */ + appendvertice(cs, -m_ray); + const b3Vector3& w = cs.c[cs.rank - 1]->w; + bool found = false; + for (unsigned int i = 0; i < 4; ++i) + { + if ((w - lastw[i]).length2() < GJK_DUPLICATED_EPS) + { + found = true; + break; + } + } + if (found) + { /* Return old simplex */ + removevertice(m_simplices[m_current]); + break; + } + else + { /* Update lastw */ + lastw[clastw = (clastw + 1) & 3] = w; + } + /* Check for termination */ + const b3Scalar omega = b3Dot(m_ray, w) / rl; + alpha = b3Max(omega, alpha); + if (((rl - alpha) - (GJK_ACCURACY * rl)) <= 0) + { /* Return old simplex */ + removevertice(m_simplices[m_current]); + break; + } + /* Reduce simplex */ + b3Scalar weights[4]; + unsigned int mask = 0; + switch (cs.rank) + { + case 2: + sqdist = projectorigin(cs.c[0]->w, + cs.c[1]->w, + weights, mask); + break; + case 3: + sqdist = projectorigin(cs.c[0]->w, + cs.c[1]->w, + cs.c[2]->w, + weights, mask); + break; + case 4: + sqdist = projectorigin(cs.c[0]->w, + cs.c[1]->w, + cs.c[2]->w, + cs.c[3]->w, + weights, mask); + break; + } + if (sqdist >= 0) + { /* Valid */ + ns.rank = 0; + m_ray = b3MakeVector3(0, 0, 0); + m_current = next; + for (unsigned int i = 0, ni = cs.rank; i < ni; ++i) + { + if (mask & (1 << i)) + { + ns.c[ns.rank] = cs.c[i]; + ns.p[ns.rank++] = weights[i]; + m_ray += cs.c[i]->w * weights[i]; + } + else + { + m_free[m_nfree++] = cs.c[i]; + } + } + if (mask == 15) m_status = eStatus::Inside; + } + else + { /* Return old simplex */ + removevertice(m_simplices[m_current]); + break; + } + m_status = ((++iterations) < GJK_MAX_ITERATIONS) ? m_status : eStatus::Failed; + } while (m_status == eStatus::Valid); + m_simplex = &m_simplices[m_current]; + switch (m_status) { - sFace* root; - unsigned int count; - sList() : root(0),count(0) {} - }; - struct sHorizon + case eStatus::Valid: + m_distance = m_ray.length(); + break; + case eStatus::Inside: + m_distance = 0; + break; + default: + { + } + } + return (m_status); + } + bool EncloseOrigin() + { + switch (m_simplex->rank) + { + case 1: + { + for (unsigned int i = 0; i < 3; ++i) + { + b3Vector3 axis = b3MakeVector3(0, 0, 0); + axis[i] = 1; + appendvertice(*m_simplex, axis); + if (EncloseOrigin()) return (true); + removevertice(*m_simplex); + appendvertice(*m_simplex, -axis); + if (EncloseOrigin()) return (true); + removevertice(*m_simplex); + } + } + break; + case 2: + { + const b3Vector3 d = m_simplex->c[1]->w - m_simplex->c[0]->w; + for (unsigned int i = 0; i < 3; ++i) + { + b3Vector3 axis = b3MakeVector3(0, 0, 0); + axis[i] = 1; + const b3Vector3 p = b3Cross(d, axis); + if (p.length2() > 0) + { + appendvertice(*m_simplex, p); + if (EncloseOrigin()) return (true); + removevertice(*m_simplex); + appendvertice(*m_simplex, -p); + if (EncloseOrigin()) return (true); + removevertice(*m_simplex); + } + } + } + break; + case 3: + { + const b3Vector3 n = b3Cross(m_simplex->c[1]->w - m_simplex->c[0]->w, + m_simplex->c[2]->w - m_simplex->c[0]->w); + if (n.length2() > 0) + { + appendvertice(*m_simplex, n); + if (EncloseOrigin()) return (true); + removevertice(*m_simplex); + appendvertice(*m_simplex, -n); + if (EncloseOrigin()) return (true); + removevertice(*m_simplex); + } + } + break; + case 4: + { + if (b3Fabs(det(m_simplex->c[0]->w - m_simplex->c[3]->w, + m_simplex->c[1]->w - m_simplex->c[3]->w, + m_simplex->c[2]->w - m_simplex->c[3]->w)) > 0) + return (true); + } + break; + } + return (false); + } + /* Internals */ + void getsupport(const b3Vector3& d, sSV& sv) const + { + sv.d = d / d.length(); + sv.w = m_shape.Support(sv.d, m_verticesA, m_verticesB); + } + void removevertice(sSimplex& simplex) + { + m_free[m_nfree++] = simplex.c[--simplex.rank]; + } + void appendvertice(sSimplex& simplex, const b3Vector3& v) + { + simplex.p[simplex.rank] = 0; + simplex.c[simplex.rank] = m_free[--m_nfree]; + getsupport(v, *simplex.c[simplex.rank++]); + } + static b3Scalar det(const b3Vector3& a, const b3Vector3& b, const b3Vector3& c) + { + return (a.y * b.z * c.x + a.z * b.x * c.y - + a.x * b.z * c.y - a.y * b.x * c.z + + a.x * b.y * c.z - a.z * b.y * c.x); + } + static b3Scalar projectorigin(const b3Vector3& a, + const b3Vector3& b, + b3Scalar* w, unsigned int& m) + { + const b3Vector3 d = b - a; + const b3Scalar l = d.length2(); + if (l > GJK_SIMPLEX2_EPS) + { + const b3Scalar t(l > 0 ? -b3Dot(a, d) / l : 0); + if (t >= 1) + { + w[0] = 0; + w[1] = 1; + m = 2; + return (b.length2()); + } + else if (t <= 0) + { + w[0] = 1; + w[1] = 0; + m = 1; + return (a.length2()); + } + else + { + w[0] = 1 - (w[1] = t); + m = 3; + return ((a + d * t).length2()); + } + } + return (-1); + } + static b3Scalar projectorigin(const b3Vector3& a, + const b3Vector3& b, + const b3Vector3& c, + b3Scalar* w, unsigned int& m) + { + static const unsigned int imd3[] = {1, 2, 0}; + const b3Vector3* vt[] = {&a, &b, &c}; + const b3Vector3 dl[] = {a - b, b - c, c - a}; + const b3Vector3 n = b3Cross(dl[0], dl[1]); + const b3Scalar l = n.length2(); + if (l > GJK_SIMPLEX3_EPS) + { + b3Scalar mindist = -1; + b3Scalar subw[2] = {0.f, 0.f}; + unsigned int subm(0); + for (unsigned int i = 0; i < 3; ++i) + { + if (b3Dot(*vt[i], b3Cross(dl[i], n)) > 0) + { + const unsigned int j = imd3[i]; + const b3Scalar subd(projectorigin(*vt[i], *vt[j], subw, subm)); + if ((mindist < 0) || (subd < mindist)) + { + mindist = subd; + m = static_cast(((subm & 1) ? 1 << i : 0) + ((subm & 2) ? 1 << j : 0)); + w[i] = subw[0]; + w[j] = subw[1]; + w[imd3[j]] = 0; + } + } + } + if (mindist < 0) + { + const b3Scalar d = b3Dot(a, n); + const b3Scalar s = b3Sqrt(l); + const b3Vector3 p = n * (d / l); + mindist = p.length2(); + m = 7; + w[0] = (b3Cross(dl[1], b - p)).length() / s; + w[1] = (b3Cross(dl[2], c - p)).length() / s; + w[2] = 1 - (w[0] + w[1]); + } + return (mindist); + } + return (-1); + } + static b3Scalar projectorigin(const b3Vector3& a, + const b3Vector3& b, + const b3Vector3& c, + const b3Vector3& d, + b3Scalar* w, unsigned int& m) + { + static const unsigned int imd3[] = {1, 2, 0}; + const b3Vector3* vt[] = {&a, &b, &c, &d}; + const b3Vector3 dl[] = {a - d, b - d, c - d}; + const b3Scalar vl = det(dl[0], dl[1], dl[2]); + const bool ng = (vl * b3Dot(a, b3Cross(b - c, a - b))) <= 0; + if (ng && (b3Fabs(vl) > GJK_SIMPLEX4_EPS)) + { + b3Scalar mindist = -1; + b3Scalar subw[3] = {0.f, 0.f, 0.f}; + unsigned int subm(0); + for (unsigned int i = 0; i < 3; ++i) + { + const unsigned int j = imd3[i]; + const b3Scalar s = vl * b3Dot(d, b3Cross(dl[i], dl[j])); + if (s > 0) + { + const b3Scalar subd = projectorigin(*vt[i], *vt[j], d, subw, subm); + if ((mindist < 0) || (subd < mindist)) + { + mindist = subd; + m = static_cast((subm & 1 ? 1 << i : 0) + + (subm & 2 ? 1 << j : 0) + + (subm & 4 ? 8 : 0)); + w[i] = subw[0]; + w[j] = subw[1]; + w[imd3[j]] = 0; + w[3] = subw[2]; + } + } + } + if (mindist < 0) + { + mindist = 0; + m = 15; + w[0] = det(c, b, d) / vl; + w[1] = det(a, c, d) / vl; + w[2] = det(b, a, d) / vl; + w[3] = 1 - (w[0] + w[1] + w[2]); + } + return (mindist); + } + return (-1); + } +}; + +// EPA +struct b3EPA +{ + /* Types */ + typedef b3GJK::sSV sSV; + struct sFace + { + b3Vector3 n; + b3Scalar d; + sSV* c[3]; + sFace* f[3]; + sFace* l[2]; + unsigned char e[3]; + unsigned char pass; + }; + struct sList + { + sFace* root; + unsigned int count; + sList() : root(0), count(0) {} + }; + struct sHorizon + { + sFace* cf; + sFace* ff; + unsigned int nf; + sHorizon() : cf(0), ff(0), nf(0) {} + }; + struct eStatus + { + enum _ { - sFace* cf; - sFace* ff; - unsigned int nf; - sHorizon() : cf(0),ff(0),nf(0) {} - }; - struct eStatus { enum _ { Valid, Touching, Degenerated, NonConvex, - InvalidHull, + InvalidHull, OutOfFaces, OutOfVertices, AccuraryReached, FallBack, - Failed };}; - /* Fields */ - eStatus::_ m_status; - b3GJK::sSimplex m_result; - b3Vector3 m_normal; - b3Scalar m_depth; - sSV m_sv_store[EPA_MAX_VERTICES]; - sFace m_fc_store[EPA_MAX_FACES]; - unsigned int m_nextsv; - sList m_hull; - sList m_stock; - /* Methods */ - b3EPA() - { - Initialize(); - } - - - static inline void bind(sFace* fa,unsigned int ea,sFace* fb,unsigned int eb) - { - fa->e[ea]=(unsigned char)eb;fa->f[ea]=fb; - fb->e[eb]=(unsigned char)ea;fb->f[eb]=fa; - } - static inline void append(sList& list,sFace* face) - { - face->l[0] = 0; - face->l[1] = list.root; - if(list.root) list.root->l[0]=face; - list.root = face; - ++list.count; - } - static inline void remove(sList& list,sFace* face) - { - if(face->l[1]) face->l[1]->l[0]=face->l[0]; - if(face->l[0]) face->l[0]->l[1]=face->l[1]; - if(face==list.root) list.root=face->l[1]; - --list.count; - } - - - void Initialize() - { - m_status = eStatus::Failed; - m_normal = b3MakeVector3(0,0,0); - m_depth = 0; - m_nextsv = 0; - for(unsigned int i=0;i1)&&gjk.EncloseOrigin()) - { - - /* Clean up */ - while(m_hull.root) - { - sFace* f = m_hull.root; - remove(m_hull,f); - append(m_stock,f); - } - m_status = eStatus::Valid; - m_nextsv = 0; - /* Orient simplex */ - if(gjk.det( simplex.c[0]->w-simplex.c[3]->w, - simplex.c[1]->w-simplex.c[3]->w, - simplex.c[2]->w-simplex.c[3]->w)<0) - { - b3Swap(simplex.c[0],simplex.c[1]); - b3Swap(simplex.p[0],simplex.p[1]); - } - /* Build initial hull */ - sFace* tetra[]={newface(simplex.c[0],simplex.c[1],simplex.c[2],true), - newface(simplex.c[1],simplex.c[0],simplex.c[3],true), - newface(simplex.c[2],simplex.c[1],simplex.c[3],true), - newface(simplex.c[0],simplex.c[2],simplex.c[3],true)}; - if(m_hull.count==4) - { - sFace* best=findbest(); - sFace outer=*best; - unsigned int pass=0; - unsigned int iterations=0; - bind(tetra[0],0,tetra[1],0); - bind(tetra[0],1,tetra[2],0); - bind(tetra[0],2,tetra[3],0); - bind(tetra[1],1,tetra[3],2); - bind(tetra[1],2,tetra[2],1); - bind(tetra[2],2,tetra[3],1); - m_status=eStatus::Valid; - for(;iterationspass = (unsigned char)(++pass); - gjk.getsupport(best->n,*w); - const b3Scalar wdist=b3Dot(best->n,w->w)-best->d; - if(wdist>EPA_ACCURACY) - { - for(unsigned int j=0;(j<3)&&valid;++j) - { - valid&=expand( pass,w, - best->f[j],best->e[j], - horizon); - } - if(valid&&(horizon.nf>=3)) - { - bind(horizon.cf,1,horizon.ff,2); - remove(m_hull,best); - append(m_stock,best); - best=findbest(); - outer=*best; - } else { - m_status=eStatus::Failed; - //m_status=eStatus::InvalidHull; - break; } - } else { m_status=eStatus::AccuraryReached;break; } - } else { m_status=eStatus::OutOfVertices;break; } - } - const b3Vector3 projection=outer.n*outer.d; - m_normal = outer.n; - m_depth = outer.d; - m_result.rank = 3; - m_result.c[0] = outer.c[0]; - m_result.c[1] = outer.c[1]; - m_result.c[2] = outer.c[2]; - m_result.p[0] = b3Cross( outer.c[1]->w-projection, - outer.c[2]->w-projection).length(); - m_result.p[1] = b3Cross( outer.c[2]->w-projection, - outer.c[0]->w-projection).length(); - m_result.p[2] = b3Cross( outer.c[0]->w-projection, - outer.c[1]->w-projection).length(); - const b3Scalar sum=m_result.p[0]+m_result.p[1]+m_result.p[2]; - m_result.p[0] /= sum; - m_result.p[1] /= sum; - m_result.p[2] /= sum; - return(m_status); - } - } - /* Fallback */ - m_status = eStatus::FallBack; - m_normal = -guess; - const b3Scalar nl=m_normal.length(); - if(nl>0) - m_normal = m_normal/nl; - else - m_normal = b3MakeVector3(1,0,0); - m_depth = 0; - m_result.rank=1; - m_result.c[0]=simplex.c[0]; - m_result.p[0]=1; - return(m_status); - } - bool getedgedist(sFace* face, sSV* a, sSV* b, b3Scalar& dist) - { - const b3Vector3 ba = b->w - a->w; - const b3Vector3 n_ab = b3Cross(ba, face->n); // Outward facing edge normal direction, on triangle plane - const b3Scalar a_dot_nab = b3Dot(a->w, n_ab); // Only care about the sign to determine inside/outside, so not normalization required - - if(a_dot_nab < 0) - { - // Outside of edge a->b - - const b3Scalar ba_l2 = ba.length2(); - const b3Scalar a_dot_ba = b3Dot(a->w, ba); - const b3Scalar b_dot_ba = b3Dot(b->w, ba); - - if(a_dot_ba > 0) - { - // Pick distance vertex a - dist = a->w.length(); - } - else if(b_dot_ba < 0) - { - // Pick distance vertex b - dist = b->w.length(); - } - else - { - // Pick distance to edge a->b - const b3Scalar a_dot_b = b3Dot(a->w, b->w); - dist = b3Sqrt(b3Max((a->w.length2() * b->w.length2() - a_dot_b * a_dot_b) / ba_l2, (b3Scalar)0)); - } - - return true; - } - - return false; - } - sFace* newface(sSV* a,sSV* b,sSV* c,bool forced) - { - if(m_stock.root) - { - sFace* face=m_stock.root; - remove(m_stock,face); - append(m_hull,face); - face->pass = 0; - face->c[0] = a; - face->c[1] = b; - face->c[2] = c; - face->n = b3Cross(b->w-a->w,c->w-a->w); - const b3Scalar l=face->n.length(); - const bool v=l>EPA_ACCURACY; - - if(v) - { - if(!(getedgedist(face, a, b, face->d) || - getedgedist(face, b, c, face->d) || - getedgedist(face, c, a, face->d))) - { - // Origin projects to the interior of the triangle - // Use distance to triangle plane - face->d = b3Dot(a->w, face->n) / l; - } - - face->n /= l; - if(forced || (face->d >= -EPA_PLANE_EPS)) - { - return face; - } - else - m_status=eStatus::NonConvex; - } - else - m_status=eStatus::Degenerated; - - remove(m_hull, face); - append(m_stock, face); - return 0; - - } - m_status = m_stock.root ? eStatus::OutOfVertices : eStatus::OutOfFaces; - return 0; - } - sFace* findbest() - { - sFace* minf=m_hull.root; - b3Scalar mind=minf->d*minf->d; - for(sFace* f=minf->l[1];f;f=f->l[1]) - { - const b3Scalar sqd=f->d*f->d; - if(sqdpass!=pass) - { - const unsigned int e1=i1m3[e]; - if((b3Dot(f->n,w->w)-f->d)<-EPA_PLANE_EPS) - { - sFace* nf=newface(f->c[e1],f->c[e],w,false); - if(nf) - { - bind(nf,0,f,e); - if(horizon.cf) bind(horizon.cf,1,nf,2); else horizon.ff=nf; - horizon.cf=nf; - ++horizon.nf; - return(true); - } - } - else - { - const unsigned int e2=i2m3[e]; - f->pass = (unsigned char)pass; - if( expand(pass,w,f->f[e1],f->e[e1],horizon)&& - expand(pass,w,f->f[e2],f->e[e2],horizon)) - { - remove(m_hull,f); - append(m_stock,f); - return(true); - } - } - } - return(false); - } - + Failed + }; }; - - // - static void Initialize(const b3Transform& transA, const b3Transform& transB, - const b3ConvexPolyhedronData* hullA, const b3ConvexPolyhedronData* hullB, - const b3AlignedObjectArray& verticesA, - const b3AlignedObjectArray& verticesB, - b3GjkEpaSolver2::sResults& results, - tShape& shape, - bool withmargins) + /* Fields */ + eStatus::_ m_status; + b3GJK::sSimplex m_result; + b3Vector3 m_normal; + b3Scalar m_depth; + sSV m_sv_store[EPA_MAX_VERTICES]; + sFace m_fc_store[EPA_MAX_FACES]; + unsigned int m_nextsv; + sList m_hull; + sList m_stock; + /* Methods */ + b3EPA() { - /* Results */ - results.witnesses[0] = - results.witnesses[1] = b3MakeVector3(0,0,0); - results.status = b3GjkEpaSolver2::sResults::Separated; - /* Shape */ - shape.m_shapes[0] = hullA; - shape.m_shapes[1] = hullB; - shape.m_toshape1 = transB.getBasis().transposeTimes(transA.getBasis()); - shape.m_toshape0 = transA.inverseTimes(transB); - shape.EnableMargin(withmargins); + Initialize(); } + static inline void bind(sFace* fa, unsigned int ea, sFace* fb, unsigned int eb) + { + fa->e[ea] = (unsigned char)eb; + fa->f[ea] = fb; + fb->e[eb] = (unsigned char)ea; + fb->f[eb] = fa; + } + static inline void append(sList& list, sFace* face) + { + face->l[0] = 0; + face->l[1] = list.root; + if (list.root) list.root->l[0] = face; + list.root = face; + ++list.count; + } + static inline void remove(sList& list, sFace* face) + { + if (face->l[1]) face->l[1]->l[0] = face->l[0]; + if (face->l[0]) face->l[0]->l[1] = face->l[1]; + if (face == list.root) list.root = face->l[1]; + --list.count; + } + + void Initialize() + { + m_status = eStatus::Failed; + m_normal = b3MakeVector3(0, 0, 0); + m_depth = 0; + m_nextsv = 0; + for (unsigned int i = 0; i < EPA_MAX_FACES; ++i) + { + append(m_stock, &m_fc_store[EPA_MAX_FACES - i - 1]); + } + } + eStatus::_ Evaluate(b3GJK& gjk, const b3Vector3& guess) + { + b3GJK::sSimplex& simplex = *gjk.m_simplex; + if ((simplex.rank > 1) && gjk.EncloseOrigin()) + { + /* Clean up */ + while (m_hull.root) + { + sFace* f = m_hull.root; + remove(m_hull, f); + append(m_stock, f); + } + m_status = eStatus::Valid; + m_nextsv = 0; + /* Orient simplex */ + if (gjk.det(simplex.c[0]->w - simplex.c[3]->w, + simplex.c[1]->w - simplex.c[3]->w, + simplex.c[2]->w - simplex.c[3]->w) < 0) + { + b3Swap(simplex.c[0], simplex.c[1]); + b3Swap(simplex.p[0], simplex.p[1]); + } + /* Build initial hull */ + sFace* tetra[] = {newface(simplex.c[0], simplex.c[1], simplex.c[2], true), + newface(simplex.c[1], simplex.c[0], simplex.c[3], true), + newface(simplex.c[2], simplex.c[1], simplex.c[3], true), + newface(simplex.c[0], simplex.c[2], simplex.c[3], true)}; + if (m_hull.count == 4) + { + sFace* best = findbest(); + sFace outer = *best; + unsigned int pass = 0; + unsigned int iterations = 0; + bind(tetra[0], 0, tetra[1], 0); + bind(tetra[0], 1, tetra[2], 0); + bind(tetra[0], 2, tetra[3], 0); + bind(tetra[1], 1, tetra[3], 2); + bind(tetra[1], 2, tetra[2], 1); + bind(tetra[2], 2, tetra[3], 1); + m_status = eStatus::Valid; + for (; iterations < EPA_MAX_ITERATIONS; ++iterations) + { + if (m_nextsv < EPA_MAX_VERTICES) + { + sHorizon horizon; + sSV* w = &m_sv_store[m_nextsv++]; + bool valid = true; + best->pass = (unsigned char)(++pass); + gjk.getsupport(best->n, *w); + const b3Scalar wdist = b3Dot(best->n, w->w) - best->d; + if (wdist > EPA_ACCURACY) + { + for (unsigned int j = 0; (j < 3) && valid; ++j) + { + valid &= expand(pass, w, + best->f[j], best->e[j], + horizon); + } + if (valid && (horizon.nf >= 3)) + { + bind(horizon.cf, 1, horizon.ff, 2); + remove(m_hull, best); + append(m_stock, best); + best = findbest(); + outer = *best; + } + else + { + m_status = eStatus::Failed; + //m_status=eStatus::InvalidHull; + break; + } + } + else + { + m_status = eStatus::AccuraryReached; + break; + } + } + else + { + m_status = eStatus::OutOfVertices; + break; + } + } + const b3Vector3 projection = outer.n * outer.d; + m_normal = outer.n; + m_depth = outer.d; + m_result.rank = 3; + m_result.c[0] = outer.c[0]; + m_result.c[1] = outer.c[1]; + m_result.c[2] = outer.c[2]; + m_result.p[0] = b3Cross(outer.c[1]->w - projection, + outer.c[2]->w - projection) + .length(); + m_result.p[1] = b3Cross(outer.c[2]->w - projection, + outer.c[0]->w - projection) + .length(); + m_result.p[2] = b3Cross(outer.c[0]->w - projection, + outer.c[1]->w - projection) + .length(); + const b3Scalar sum = m_result.p[0] + m_result.p[1] + m_result.p[2]; + m_result.p[0] /= sum; + m_result.p[1] /= sum; + m_result.p[2] /= sum; + return (m_status); + } + } + /* Fallback */ + m_status = eStatus::FallBack; + m_normal = -guess; + const b3Scalar nl = m_normal.length(); + if (nl > 0) + m_normal = m_normal / nl; + else + m_normal = b3MakeVector3(1, 0, 0); + m_depth = 0; + m_result.rank = 1; + m_result.c[0] = simplex.c[0]; + m_result.p[0] = 1; + return (m_status); + } + bool getedgedist(sFace* face, sSV* a, sSV* b, b3Scalar& dist) + { + const b3Vector3 ba = b->w - a->w; + const b3Vector3 n_ab = b3Cross(ba, face->n); // Outward facing edge normal direction, on triangle plane + const b3Scalar a_dot_nab = b3Dot(a->w, n_ab); // Only care about the sign to determine inside/outside, so not normalization required + + if (a_dot_nab < 0) + { + // Outside of edge a->b + + const b3Scalar ba_l2 = ba.length2(); + const b3Scalar a_dot_ba = b3Dot(a->w, ba); + const b3Scalar b_dot_ba = b3Dot(b->w, ba); + + if (a_dot_ba > 0) + { + // Pick distance vertex a + dist = a->w.length(); + } + else if (b_dot_ba < 0) + { + // Pick distance vertex b + dist = b->w.length(); + } + else + { + // Pick distance to edge a->b + const b3Scalar a_dot_b = b3Dot(a->w, b->w); + dist = b3Sqrt(b3Max((a->w.length2() * b->w.length2() - a_dot_b * a_dot_b) / ba_l2, (b3Scalar)0)); + } + + return true; + } + + return false; + } + sFace* newface(sSV* a, sSV* b, sSV* c, bool forced) + { + if (m_stock.root) + { + sFace* face = m_stock.root; + remove(m_stock, face); + append(m_hull, face); + face->pass = 0; + face->c[0] = a; + face->c[1] = b; + face->c[2] = c; + face->n = b3Cross(b->w - a->w, c->w - a->w); + const b3Scalar l = face->n.length(); + const bool v = l > EPA_ACCURACY; + + if (v) + { + if (!(getedgedist(face, a, b, face->d) || + getedgedist(face, b, c, face->d) || + getedgedist(face, c, a, face->d))) + { + // Origin projects to the interior of the triangle + // Use distance to triangle plane + face->d = b3Dot(a->w, face->n) / l; + } + + face->n /= l; + if (forced || (face->d >= -EPA_PLANE_EPS)) + { + return face; + } + else + m_status = eStatus::NonConvex; + } + else + m_status = eStatus::Degenerated; + + remove(m_hull, face); + append(m_stock, face); + return 0; + } + m_status = m_stock.root ? eStatus::OutOfVertices : eStatus::OutOfFaces; + return 0; + } + sFace* findbest() + { + sFace* minf = m_hull.root; + b3Scalar mind = minf->d * minf->d; + for (sFace* f = minf->l[1]; f; f = f->l[1]) + { + const b3Scalar sqd = f->d * f->d; + if (sqd < mind) + { + minf = f; + mind = sqd; + } + } + return (minf); + } + bool expand(unsigned int pass, sSV* w, sFace* f, unsigned int e, sHorizon& horizon) + { + static const unsigned int i1m3[] = {1, 2, 0}; + static const unsigned int i2m3[] = {2, 0, 1}; + if (f->pass != pass) + { + const unsigned int e1 = i1m3[e]; + if ((b3Dot(f->n, w->w) - f->d) < -EPA_PLANE_EPS) + { + sFace* nf = newface(f->c[e1], f->c[e], w, false); + if (nf) + { + bind(nf, 0, f, e); + if (horizon.cf) + bind(horizon.cf, 1, nf, 2); + else + horizon.ff = nf; + horizon.cf = nf; + ++horizon.nf; + return (true); + } + } + else + { + const unsigned int e2 = i2m3[e]; + f->pass = (unsigned char)pass; + if (expand(pass, w, f->f[e1], f->e[e1], horizon) && + expand(pass, w, f->f[e2], f->e[e2], horizon)) + { + remove(m_hull, f); + append(m_stock, f); + return (true); + } + } + } + return (false); + } +}; + +// +static void Initialize(const b3Transform& transA, const b3Transform& transB, + const b3ConvexPolyhedronData* hullA, const b3ConvexPolyhedronData* hullB, + const b3AlignedObjectArray& verticesA, + const b3AlignedObjectArray& verticesB, + b3GjkEpaSolver2::sResults& results, + tShape& shape, + bool withmargins) +{ + /* Results */ + results.witnesses[0] = + results.witnesses[1] = b3MakeVector3(0, 0, 0); + results.status = b3GjkEpaSolver2::sResults::Separated; + /* Shape */ + shape.m_shapes[0] = hullA; + shape.m_shapes[1] = hullB; + shape.m_toshape1 = transB.getBasis().transposeTimes(transA.getBasis()); + shape.m_toshape0 = transA.inverseTimes(transB); + shape.EnableMargin(withmargins); } +} // namespace gjkepa2_impl2 + // // Api // -using namespace gjkepa2_impl2; +using namespace gjkepa2_impl2; // -int b3GjkEpaSolver2::StackSizeRequirement() +int b3GjkEpaSolver2::StackSizeRequirement() { - return(sizeof(b3GJK)+sizeof(b3EPA)); + return (sizeof(b3GJK) + sizeof(b3EPA)); } // -bool b3GjkEpaSolver2::Distance( const b3Transform& transA, const b3Transform& transB, - const b3ConvexPolyhedronData* hullA, const b3ConvexPolyhedronData* hullB, - const b3AlignedObjectArray& verticesA, - const b3AlignedObjectArray& verticesB, - const b3Vector3& guess, - sResults& results) +bool b3GjkEpaSolver2::Distance(const b3Transform& transA, const b3Transform& transB, + const b3ConvexPolyhedronData* hullA, const b3ConvexPolyhedronData* hullB, + const b3AlignedObjectArray& verticesA, + const b3AlignedObjectArray& verticesB, + const b3Vector3& guess, + sResults& results) { - tShape shape; - Initialize(transA,transB,hullA,hullB,verticesA,verticesB,results,shape,false); - b3GJK gjk(verticesA,verticesB); - b3GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,guess); - if(gjk_status==b3GJK::eStatus::Valid) + tShape shape; + Initialize(transA, transB, hullA, hullB, verticesA, verticesB, results, shape, false); + b3GJK gjk(verticesA, verticesB); + b3GJK::eStatus::_ gjk_status = gjk.Evaluate(shape, guess); + if (gjk_status == b3GJK::eStatus::Valid) { - b3Vector3 w0=b3MakeVector3(0,0,0); - b3Vector3 w1=b3MakeVector3(0,0,0); - for(unsigned int i=0;irank;++i) + b3Vector3 w0 = b3MakeVector3(0, 0, 0); + b3Vector3 w1 = b3MakeVector3(0, 0, 0); + for (unsigned int i = 0; i < gjk.m_simplex->rank; ++i) { - const b3Scalar p=gjk.m_simplex->p[i]; - w0+=shape.Support( gjk.m_simplex->c[i]->d,0,verticesA,verticesB)*p; - w1+=shape.Support(-gjk.m_simplex->c[i]->d,1,verticesA,verticesB)*p; + const b3Scalar p = gjk.m_simplex->p[i]; + w0 += shape.Support(gjk.m_simplex->c[i]->d, 0, verticesA, verticesB) * p; + w1 += shape.Support(-gjk.m_simplex->c[i]->d, 1, verticesA, verticesB) * p; } - results.witnesses[0] = transA*w0; - results.witnesses[1] = transA*w1; - results.normal = w0-w1; - results.distance = results.normal.length(); - results.normal /= results.distance>GJK_MIN_DISTANCE?results.distance:1; - return(true); + results.witnesses[0] = transA * w0; + results.witnesses[1] = transA * w1; + results.normal = w0 - w1; + results.distance = results.normal.length(); + results.normal /= results.distance > GJK_MIN_DISTANCE ? results.distance : 1; + return (true); } else { - results.status = gjk_status==b3GJK::eStatus::Inside? - sResults::Penetrating : - sResults::GJK_Failed ; - return(false); + results.status = gjk_status == b3GJK::eStatus::Inside ? sResults::Penetrating : sResults::GJK_Failed; + return (false); } } // -bool b3GjkEpaSolver2::Penetration( const b3Transform& transA, const b3Transform& transB, - const b3ConvexPolyhedronData* hullA, const b3ConvexPolyhedronData* hullB, - const b3AlignedObjectArray& verticesA, - const b3AlignedObjectArray& verticesB, - const b3Vector3& guess, - sResults& results, - bool usemargins) +bool b3GjkEpaSolver2::Penetration(const b3Transform& transA, const b3Transform& transB, + const b3ConvexPolyhedronData* hullA, const b3ConvexPolyhedronData* hullB, + const b3AlignedObjectArray& verticesA, + const b3AlignedObjectArray& verticesB, + const b3Vector3& guess, + sResults& results, + bool usemargins) { - - tShape shape; - Initialize(transA,transB,hullA,hullB,verticesA,verticesB,results,shape,usemargins); - b3GJK gjk(verticesA,verticesB); - b3GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,guess); - switch(gjk_status) + tShape shape; + Initialize(transA, transB, hullA, hullB, verticesA, verticesB, results, shape, usemargins); + b3GJK gjk(verticesA, verticesB); + b3GJK::eStatus::_ gjk_status = gjk.Evaluate(shape, guess); + switch (gjk_status) { - case b3GJK::eStatus::Inside: + case b3GJK::eStatus::Inside: { - b3EPA epa; - b3EPA::eStatus::_ epa_status=epa.Evaluate(gjk,-guess); - if(epa_status!=b3EPA::eStatus::Failed) + b3EPA epa; + b3EPA::eStatus::_ epa_status = epa.Evaluate(gjk, -guess); + if (epa_status != b3EPA::eStatus::Failed) { - b3Vector3 w0=b3MakeVector3(0,0,0); - for(unsigned int i=0;id,0,verticesA,verticesB)*epa.m_result.p[i]; + w0 += shape.Support(epa.m_result.c[i]->d, 0, verticesA, verticesB) * epa.m_result.p[i]; } - results.status = sResults::Penetrating; - results.witnesses[0] = transA*w0; - results.witnesses[1] = transA*(w0-epa.m_normal*epa.m_depth); - results.normal = -epa.m_normal; - results.distance = -epa.m_depth; - return(true); - } else results.status=sResults::EPA_Failed; + results.status = sResults::Penetrating; + results.witnesses[0] = transA * w0; + results.witnesses[1] = transA * (w0 - epa.m_normal * epa.m_depth); + results.normal = -epa.m_normal; + results.distance = -epa.m_depth; + return (true); + } + else + results.status = sResults::EPA_Failed; } break; - case b3GJK::eStatus::Failed: - results.status=sResults::GJK_Failed; - break; + case b3GJK::eStatus::Failed: + results.status = sResults::GJK_Failed; + break; default: - { - } + { + } } - return(false); + return (false); } - #if 0 // b3Scalar b3GjkEpaSolver2::SignedDistance(const b3Vector3& position, @@ -994,8 +1043,7 @@ bool b3GjkEpaSolver2::SignedDistance(const btConvexShape* shape0, } #endif - -/* Symbols cleanup */ +/* Symbols cleanup */ #undef GJK_MAX_ITERATIONS #undef GJK_ACCURACY diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3GjkEpa.h b/src/Bullet3OpenCL/NarrowphaseCollision/b3GjkEpa.h index 976238a04..7db32c630 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3GjkEpa.h +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3GjkEpa.h @@ -29,40 +29,39 @@ GJK-EPA collision solver by Nathanael Presson, 2008 #include "Bullet3Common/b3Transform.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3ConvexPolyhedronData.h" - ///btGjkEpaSolver contributed under zlib by Nathanael Presson -struct b3GjkEpaSolver2 +struct b3GjkEpaSolver2 { -struct sResults + struct sResults { - enum eStatus + enum eStatus { - Separated, /* Shapes doesnt penetrate */ - Penetrating, /* Shapes are penetrating */ - GJK_Failed, /* GJK phase fail, no big issue, shapes are probably just 'touching' */ - EPA_Failed /* EPA phase fail, bigger problem, need to save parameters, and debug */ - } status; - b3Vector3 witnesses[2]; - b3Vector3 normal; - b3Scalar distance; + Separated, /* Shapes doesnt penetrate */ + Penetrating, /* Shapes are penetrating */ + GJK_Failed, /* GJK phase fail, no big issue, shapes are probably just 'touching' */ + EPA_Failed /* EPA phase fail, bigger problem, need to save parameters, and debug */ + } status; + b3Vector3 witnesses[2]; + b3Vector3 normal; + b3Scalar distance; }; -static int StackSizeRequirement(); + static int StackSizeRequirement(); -static bool Distance( const b3Transform& transA, const b3Transform& transB, - const b3ConvexPolyhedronData* hullA, const b3ConvexPolyhedronData* hullB, - const b3AlignedObjectArray& verticesA, - const b3AlignedObjectArray& verticesB, - const b3Vector3& guess, - sResults& results); + static bool Distance(const b3Transform& transA, const b3Transform& transB, + const b3ConvexPolyhedronData* hullA, const b3ConvexPolyhedronData* hullB, + const b3AlignedObjectArray& verticesA, + const b3AlignedObjectArray& verticesB, + const b3Vector3& guess, + sResults& results); -static bool Penetration( const b3Transform& transA, const b3Transform& transB, - const b3ConvexPolyhedronData* hullA, const b3ConvexPolyhedronData* hullB, + static bool Penetration(const b3Transform& transA, const b3Transform& transB, + const b3ConvexPolyhedronData* hullA, const b3ConvexPolyhedronData* hullB, const b3AlignedObjectArray& verticesA, const b3AlignedObjectArray& verticesB, const b3Vector3& guess, sResults& results, - bool usemargins=true); + bool usemargins = true); #if 0 static b3Scalar SignedDistance( const b3Vector3& position, b3Scalar margin, @@ -74,9 +73,7 @@ static bool SignedDistance( const btConvexShape* shape0,const btTransform& wtrs const btConvexShape* shape1,const btTransform& wtrs1, const b3Vector3& guess, sResults& results); -#endif - +#endif }; -#endif //B3_GJK_EPA2_H - +#endif //B3_GJK_EPA2_H diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3OptimizedBvh.cpp b/src/Bullet3OpenCL/NarrowphaseCollision/b3OptimizedBvh.cpp index e9e51d5a3..6f2c5251a 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3OptimizedBvh.cpp +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3OptimizedBvh.cpp @@ -13,50 +13,45 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "b3OptimizedBvh.h" #include "b3StridingMeshInterface.h" #include "Bullet3Geometry/b3AabbUtil.h" - b3OptimizedBvh::b3OptimizedBvh() -{ +{ } b3OptimizedBvh::~b3OptimizedBvh() { } - void b3OptimizedBvh::build(b3StridingMeshInterface* triangles, bool useQuantizedAabbCompression, const b3Vector3& bvhAabbMin, const b3Vector3& bvhAabbMax) { m_useQuantization = useQuantizedAabbCompression; - // NodeArray triangleNodes; - struct NodeTriangleCallback : public b3InternalTriangleIndexCallback + struct NodeTriangleCallback : public b3InternalTriangleIndexCallback { - - NodeArray& m_triangleNodes; + NodeArray& m_triangleNodes; NodeTriangleCallback& operator=(NodeTriangleCallback& other) { m_triangleNodes.copyFromArray(other.m_triangleNodes); return *this; } - - NodeTriangleCallback(NodeArray& triangleNodes) - :m_triangleNodes(triangleNodes) + + NodeTriangleCallback(NodeArray& triangleNodes) + : m_triangleNodes(triangleNodes) { } - virtual void internalProcessTriangleIndex(b3Vector3* triangle,int partId,int triangleIndex) + virtual void internalProcessTriangleIndex(b3Vector3* triangle, int partId, int triangleIndex) { b3OptimizedBvhNode node; - b3Vector3 aabbMin,aabbMax; - aabbMin.setValue(b3Scalar(B3_LARGE_FLOAT),b3Scalar(B3_LARGE_FLOAT),b3Scalar(B3_LARGE_FLOAT)); - aabbMax.setValue(b3Scalar(-B3_LARGE_FLOAT),b3Scalar(-B3_LARGE_FLOAT),b3Scalar(-B3_LARGE_FLOAT)); + b3Vector3 aabbMin, aabbMax; + aabbMin.setValue(b3Scalar(B3_LARGE_FLOAT), b3Scalar(B3_LARGE_FLOAT), b3Scalar(B3_LARGE_FLOAT)); + aabbMax.setValue(b3Scalar(-B3_LARGE_FLOAT), b3Scalar(-B3_LARGE_FLOAT), b3Scalar(-B3_LARGE_FLOAT)); aabbMin.setMin(triangle[0]); aabbMax.setMax(triangle[0]); aabbMin.setMin(triangle[1]); @@ -69,17 +64,17 @@ void b3OptimizedBvh::build(b3StridingMeshInterface* triangles, bool useQuantized node.m_aabbMaxOrg = aabbMax; node.m_escapeIndex = -1; - + //for child nodes node.m_subPart = partId; node.m_triangleIndex = triangleIndex; m_triangleNodes.push_back(node); } }; - struct QuantizedNodeTriangleCallback : public b3InternalTriangleIndexCallback + struct QuantizedNodeTriangleCallback : public b3InternalTriangleIndexCallback { - QuantizedNodeArray& m_triangleNodes; - const b3QuantizedBvh* m_optimizedTree; // for quantization + QuantizedNodeArray& m_triangleNodes; + const b3QuantizedBvh* m_optimizedTree; // for quantization QuantizedNodeTriangleCallback& operator=(QuantizedNodeTriangleCallback& other) { @@ -88,23 +83,23 @@ void b3OptimizedBvh::build(b3StridingMeshInterface* triangles, bool useQuantized return *this; } - QuantizedNodeTriangleCallback(QuantizedNodeArray& triangleNodes,const b3QuantizedBvh* tree) - :m_triangleNodes(triangleNodes),m_optimizedTree(tree) + QuantizedNodeTriangleCallback(QuantizedNodeArray& triangleNodes, const b3QuantizedBvh* tree) + : m_triangleNodes(triangleNodes), m_optimizedTree(tree) { } - virtual void internalProcessTriangleIndex(b3Vector3* triangle,int partId,int triangleIndex) + virtual void internalProcessTriangleIndex(b3Vector3* triangle, int partId, int triangleIndex) { // The partId and triangle index must fit in the same (positive) integer - b3Assert(partId < (1<=0); + b3Assert(triangleIndex >= 0); b3QuantizedBvhNode node; - b3Vector3 aabbMin,aabbMax; - aabbMin.setValue(b3Scalar(B3_LARGE_FLOAT),b3Scalar(B3_LARGE_FLOAT),b3Scalar(B3_LARGE_FLOAT)); - aabbMax.setValue(b3Scalar(-B3_LARGE_FLOAT),b3Scalar(-B3_LARGE_FLOAT),b3Scalar(-B3_LARGE_FLOAT)); + b3Vector3 aabbMin, aabbMax; + aabbMin.setValue(b3Scalar(B3_LARGE_FLOAT), b3Scalar(B3_LARGE_FLOAT), b3Scalar(B3_LARGE_FLOAT)); + aabbMax.setValue(b3Scalar(-B3_LARGE_FLOAT), b3Scalar(-B3_LARGE_FLOAT), b3Scalar(-B3_LARGE_FLOAT)); aabbMin.setMin(triangle[0]); aabbMax.setMax(triangle[0]); aabbMin.setMin(triangle[1]); @@ -131,59 +126,52 @@ void b3OptimizedBvh::build(b3StridingMeshInterface* triangles, bool useQuantized aabbMin.setZ(aabbMin.getZ() - MIN_AABB_HALF_DIMENSION); } - m_optimizedTree->quantize(&node.m_quantizedAabbMin[0],aabbMin,0); - m_optimizedTree->quantize(&node.m_quantizedAabbMax[0],aabbMax,1); + m_optimizedTree->quantize(&node.m_quantizedAabbMin[0], aabbMin, 0); + m_optimizedTree->quantize(&node.m_quantizedAabbMax[0], aabbMax, 1); - node.m_escapeIndexOrTriangleIndex = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | triangleIndex; + node.m_escapeIndexOrTriangleIndex = (partId << (31 - MAX_NUM_PARTS_IN_BITS)) | triangleIndex; m_triangleNodes.push_back(node); } }; - - int numLeafNodes = 0; - if (m_useQuantization) { - //initialize quantization values - setQuantizationValues(bvhAabbMin,bvhAabbMax); + setQuantizationValues(bvhAabbMin, bvhAabbMax); - QuantizedNodeTriangleCallback callback(m_quantizedLeafNodes,this); + QuantizedNodeTriangleCallback callback(m_quantizedLeafNodes, this); - - triangles->InternalProcessAllTriangles(&callback,m_bvhAabbMin,m_bvhAabbMax); + triangles->InternalProcessAllTriangles(&callback, m_bvhAabbMin, m_bvhAabbMax); //now we have an array of leafnodes in m_leafNodes numLeafNodes = m_quantizedLeafNodes.size(); - - m_quantizedContiguousNodes.resize(2*numLeafNodes); - - - } else + m_quantizedContiguousNodes.resize(2 * numLeafNodes); + } + else { - NodeTriangleCallback callback(m_leafNodes); + NodeTriangleCallback callback(m_leafNodes); - b3Vector3 aabbMin=b3MakeVector3(b3Scalar(-B3_LARGE_FLOAT),b3Scalar(-B3_LARGE_FLOAT),b3Scalar(-B3_LARGE_FLOAT)); - b3Vector3 aabbMax=b3MakeVector3(b3Scalar(B3_LARGE_FLOAT),b3Scalar(B3_LARGE_FLOAT),b3Scalar(B3_LARGE_FLOAT)); + b3Vector3 aabbMin = b3MakeVector3(b3Scalar(-B3_LARGE_FLOAT), b3Scalar(-B3_LARGE_FLOAT), b3Scalar(-B3_LARGE_FLOAT)); + b3Vector3 aabbMax = b3MakeVector3(b3Scalar(B3_LARGE_FLOAT), b3Scalar(B3_LARGE_FLOAT), b3Scalar(B3_LARGE_FLOAT)); - triangles->InternalProcessAllTriangles(&callback,aabbMin,aabbMax); + triangles->InternalProcessAllTriangles(&callback, aabbMin, aabbMax); //now we have an array of leafnodes in m_leafNodes numLeafNodes = m_leafNodes.size(); - m_contiguousNodes.resize(2*numLeafNodes); + m_contiguousNodes.resize(2 * numLeafNodes); } m_curNodeIndex = 0; - buildTree(0,numLeafNodes); + buildTree(0, numLeafNodes); ///if the entire tree is small then subtree size, we need to create a header info for the tree - if(m_useQuantization && !m_SubtreeHeaders.size()) + if (m_useQuantization && !m_SubtreeHeaders.size()) { b3BvhSubtreeInfo& subtree = m_SubtreeHeaders.expand(); subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[0]); @@ -199,37 +187,29 @@ void b3OptimizedBvh::build(b3StridingMeshInterface* triangles, bool useQuantized m_leafNodes.clear(); } - - - -void b3OptimizedBvh::refit(b3StridingMeshInterface* meshInterface,const b3Vector3& aabbMin,const b3Vector3& aabbMax) +void b3OptimizedBvh::refit(b3StridingMeshInterface* meshInterface, const b3Vector3& aabbMin, const b3Vector3& aabbMax) { if (m_useQuantization) { + setQuantizationValues(aabbMin, aabbMax); - setQuantizationValues(aabbMin,aabbMax); - - updateBvhNodes(meshInterface,0,m_curNodeIndex,0); + updateBvhNodes(meshInterface, 0, m_curNodeIndex, 0); ///now update all subtree headers int i; - for (i=0;im_SubtreeHeaders.size();i++) + for (i = 0; i < this->m_SubtreeHeaders.size(); i++) { b3BvhSubtreeInfo& subtree = m_SubtreeHeaders[i]; //PCK: unsigned instead of bool - unsigned overlap = b3TestQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax); + unsigned overlap = b3TestQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin, quantizedQueryAabbMax, subtree.m_quantizedAabbMin, subtree.m_quantizedAabbMax); if (overlap != 0) { - updateBvhNodes(meshInterface,subtree.m_rootNodeIndex,subtree.m_rootNodeIndex+subtree.m_subtreeSize,i); + updateBvhNodes(meshInterface, subtree.m_rootNodeIndex, subtree.m_rootNodeIndex + subtree.m_subtreeSize, i); subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[subtree.m_rootNodeIndex]); } } - } -void b3OptimizedBvh::updateBvhNodes(b3StridingMeshInterface* meshInterface,int firstNode,int endNode,int index) +void b3OptimizedBvh::updateBvhNodes(b3StridingMeshInterface* meshInterface, int firstNode, int endNode, int index) { (void)index; b3Assert(m_useQuantization); - int curNodeSubPart=-1; + int curNodeSubPart = -1; //get access info to trianglemesh data - const unsigned char *vertexbase = 0; - int numverts = 0; - PHY_ScalarType type = PHY_INTEGER; - int stride = 0; - const unsigned char *indexbase = 0; - int indexstride = 0; - int numfaces = 0; - PHY_ScalarType indicestype = PHY_INTEGER; + const unsigned char* vertexbase = 0; + int numverts = 0; + PHY_ScalarType type = PHY_INTEGER; + int stride = 0; + const unsigned char* indexbase = 0; + int indexstride = 0; + int numfaces = 0; + PHY_ScalarType indicestype = PHY_INTEGER; - b3Vector3 triangleVerts[3]; - b3Vector3 aabbMin,aabbMax; - const b3Vector3& meshScaling = meshInterface->getScaling(); - - int i; - for (i=endNode-1;i>=firstNode;i--) + b3Vector3 triangleVerts[3]; + b3Vector3 aabbMin, aabbMax; + const b3Vector3& meshScaling = meshInterface->getScaling(); + + int i; + for (i = endNode - 1; i >= firstNode; i--) + { + b3QuantizedBvhNode& curNode = m_quantizedContiguousNodes[i]; + if (curNode.isLeafNode()) { - - - b3QuantizedBvhNode& curNode = m_quantizedContiguousNodes[i]; - if (curNode.isLeafNode()) + //recalc aabb from triangle data + int nodeSubPart = curNode.getPartId(); + int nodeTriangleIndex = curNode.getTriangleIndex(); + if (nodeSubPart != curNodeSubPart) { - //recalc aabb from triangle data - int nodeSubPart = curNode.getPartId(); - int nodeTriangleIndex = curNode.getTriangleIndex(); - if (nodeSubPart != curNodeSubPart) - { - if (curNodeSubPart >= 0) - meshInterface->unLockReadOnlyVertexBase(curNodeSubPart); - meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,nodeSubPart); + if (curNodeSubPart >= 0) + meshInterface->unLockReadOnlyVertexBase(curNodeSubPart); + meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase, numverts, type, stride, &indexbase, indexstride, numfaces, indicestype, nodeSubPart); - curNodeSubPart = nodeSubPart; - b3Assert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT); - } - //triangles->getLockedReadOnlyVertexIndexBase(vertexBase,numVerts, + curNodeSubPart = nodeSubPart; + b3Assert(indicestype == PHY_INTEGER || indicestype == PHY_SHORT); + } + //triangles->getLockedReadOnlyVertexIndexBase(vertexBase,numVerts, - unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride); - - - for (int j=2;j>=0;j--) - { - - int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; - if (type == PHY_FLOAT) - { - float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); - triangleVerts[j] = b3MakeVector3( - graphicsbase[0]*meshScaling.getX(), - graphicsbase[1]*meshScaling.getY(), - graphicsbase[2]*meshScaling.getZ()); - } - else - { - double* graphicsbase = (double*)(vertexbase+graphicsindex*stride); - triangleVerts[j] = b3MakeVector3( b3Scalar(graphicsbase[0]*meshScaling.getX()), b3Scalar(graphicsbase[1]*meshScaling.getY()), b3Scalar(graphicsbase[2]*meshScaling.getZ())); - } - } + unsigned int* gfxbase = (unsigned int*)(indexbase + nodeTriangleIndex * indexstride); - - - aabbMin.setValue(b3Scalar(B3_LARGE_FLOAT),b3Scalar(B3_LARGE_FLOAT),b3Scalar(B3_LARGE_FLOAT)); - aabbMax.setValue(b3Scalar(-B3_LARGE_FLOAT),b3Scalar(-B3_LARGE_FLOAT),b3Scalar(-B3_LARGE_FLOAT)); - aabbMin.setMin(triangleVerts[0]); - aabbMax.setMax(triangleVerts[0]); - aabbMin.setMin(triangleVerts[1]); - aabbMax.setMax(triangleVerts[1]); - aabbMin.setMin(triangleVerts[2]); - aabbMax.setMax(triangleVerts[2]); - - quantize(&curNode.m_quantizedAabbMin[0],aabbMin,0); - quantize(&curNode.m_quantizedAabbMax[0],aabbMax,1); - - } else + for (int j = 2; j >= 0; j--) { - //combine aabb from both children - - b3QuantizedBvhNode* leftChildNode = &m_quantizedContiguousNodes[i+1]; - - b3QuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? &m_quantizedContiguousNodes[i+2] : - &m_quantizedContiguousNodes[i+1+leftChildNode->getEscapeIndex()]; - - + int graphicsindex = indicestype == PHY_SHORT ? ((unsigned short*)gfxbase)[j] : gfxbase[j]; + if (type == PHY_FLOAT) { - for (int i=0;i<3;i++) - { - curNode.m_quantizedAabbMin[i] = leftChildNode->m_quantizedAabbMin[i]; - if (curNode.m_quantizedAabbMin[i]>rightChildNode->m_quantizedAabbMin[i]) - curNode.m_quantizedAabbMin[i]=rightChildNode->m_quantizedAabbMin[i]; - - curNode.m_quantizedAabbMax[i] = leftChildNode->m_quantizedAabbMax[i]; - if (curNode.m_quantizedAabbMax[i] < rightChildNode->m_quantizedAabbMax[i]) - curNode.m_quantizedAabbMax[i] = rightChildNode->m_quantizedAabbMax[i]; - } + float* graphicsbase = (float*)(vertexbase + graphicsindex * stride); + triangleVerts[j] = b3MakeVector3( + graphicsbase[0] * meshScaling.getX(), + graphicsbase[1] * meshScaling.getY(), + graphicsbase[2] * meshScaling.getZ()); + } + else + { + double* graphicsbase = (double*)(vertexbase + graphicsindex * stride); + triangleVerts[j] = b3MakeVector3(b3Scalar(graphicsbase[0] * meshScaling.getX()), b3Scalar(graphicsbase[1] * meshScaling.getY()), b3Scalar(graphicsbase[2] * meshScaling.getZ())); } } + aabbMin.setValue(b3Scalar(B3_LARGE_FLOAT), b3Scalar(B3_LARGE_FLOAT), b3Scalar(B3_LARGE_FLOAT)); + aabbMax.setValue(b3Scalar(-B3_LARGE_FLOAT), b3Scalar(-B3_LARGE_FLOAT), b3Scalar(-B3_LARGE_FLOAT)); + aabbMin.setMin(triangleVerts[0]); + aabbMax.setMax(triangleVerts[0]); + aabbMin.setMin(triangleVerts[1]); + aabbMax.setMax(triangleVerts[1]); + aabbMin.setMin(triangleVerts[2]); + aabbMax.setMax(triangleVerts[2]); + + quantize(&curNode.m_quantizedAabbMin[0], aabbMin, 0); + quantize(&curNode.m_quantizedAabbMax[0], aabbMax, 1); } + else + { + //combine aabb from both children - if (curNodeSubPart >= 0) - meshInterface->unLockReadOnlyVertexBase(curNodeSubPart); + b3QuantizedBvhNode* leftChildNode = &m_quantizedContiguousNodes[i + 1]; - + b3QuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? &m_quantizedContiguousNodes[i + 2] : &m_quantizedContiguousNodes[i + 1 + leftChildNode->getEscapeIndex()]; + + { + for (int i = 0; i < 3; i++) + { + curNode.m_quantizedAabbMin[i] = leftChildNode->m_quantizedAabbMin[i]; + if (curNode.m_quantizedAabbMin[i] > rightChildNode->m_quantizedAabbMin[i]) + curNode.m_quantizedAabbMin[i] = rightChildNode->m_quantizedAabbMin[i]; + + curNode.m_quantizedAabbMax[i] = leftChildNode->m_quantizedAabbMax[i]; + if (curNode.m_quantizedAabbMax[i] < rightChildNode->m_quantizedAabbMax[i]) + curNode.m_quantizedAabbMax[i] = rightChildNode->m_quantizedAabbMax[i]; + } + } + } + } + + if (curNodeSubPart >= 0) + meshInterface->unLockReadOnlyVertexBase(curNodeSubPart); } ///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place' -b3OptimizedBvh* b3OptimizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian) +b3OptimizedBvh* b3OptimizedBvh::deSerializeInPlace(void* i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian) { - b3QuantizedBvh* bvh = b3QuantizedBvh::deSerializeInPlace(i_alignedDataBuffer,i_dataBufferSize,i_swapEndian); - + b3QuantizedBvh* bvh = b3QuantizedBvh::deSerializeInPlace(i_alignedDataBuffer, i_dataBufferSize, i_swapEndian); + //we don't add additional data so just do a static upcast return static_cast(bvh); } diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3OptimizedBvh.h b/src/Bullet3OpenCL/NarrowphaseCollision/b3OptimizedBvh.h index 0272ef83b..128655293 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3OptimizedBvh.h +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3OptimizedBvh.h @@ -22,44 +22,35 @@ subject to the following restrictions: class b3StridingMeshInterface; - ///The b3OptimizedBvh extends the b3QuantizedBvh to create AABB tree for triangle meshes, through the b3StridingMeshInterface. -B3_ATTRIBUTE_ALIGNED16(class) b3OptimizedBvh : public b3QuantizedBvh +B3_ATTRIBUTE_ALIGNED16(class) +b3OptimizedBvh : public b3QuantizedBvh { - public: B3_DECLARE_ALIGNED_ALLOCATOR(); protected: - public: - b3OptimizedBvh(); virtual ~b3OptimizedBvh(); - void build(b3StridingMeshInterface* triangles,bool useQuantizedAabbCompression, const b3Vector3& bvhAabbMin, const b3Vector3& bvhAabbMax); + void build(b3StridingMeshInterface * triangles, bool useQuantizedAabbCompression, const b3Vector3& bvhAabbMin, const b3Vector3& bvhAabbMax); - void refit(b3StridingMeshInterface* triangles,const b3Vector3& aabbMin,const b3Vector3& aabbMax); + void refit(b3StridingMeshInterface * triangles, const b3Vector3& aabbMin, const b3Vector3& aabbMax); - void refitPartial(b3StridingMeshInterface* triangles,const b3Vector3& aabbMin, const b3Vector3& aabbMax); + void refitPartial(b3StridingMeshInterface * triangles, const b3Vector3& aabbMin, const b3Vector3& aabbMax); - void updateBvhNodes(b3StridingMeshInterface* meshInterface,int firstNode,int endNode,int index); + void updateBvhNodes(b3StridingMeshInterface * meshInterface, int firstNode, int endNode, int index); /// Data buffer MUST be 16 byte aligned - virtual bool serializeInPlace(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const + virtual bool serializeInPlace(void* o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const { - return b3QuantizedBvh::serialize(o_alignedDataBuffer,i_dataBufferSize,i_swapEndian); - + return b3QuantizedBvh::serialize(o_alignedDataBuffer, i_dataBufferSize, i_swapEndian); } ///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place' - static b3OptimizedBvh *deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian); - - + static b3OptimizedBvh* deSerializeInPlace(void* i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian); }; - -#endif //B3_OPTIMIZED_BVH_H - - +#endif //B3_OPTIMIZED_BVH_H diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3QuantizedBvh.cpp b/src/Bullet3OpenCL/NarrowphaseCollision/b3QuantizedBvh.cpp index 52027e111..9a448495f 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3QuantizedBvh.cpp +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3QuantizedBvh.cpp @@ -17,46 +17,40 @@ subject to the following restrictions: #include "Bullet3Geometry/b3AabbUtil.h" - #define RAYAABB2 -b3QuantizedBvh::b3QuantizedBvh() : - m_bulletVersion(B3_BULLET_VERSION), - m_useQuantization(false), - m_traversalMode(TRAVERSAL_STACKLESS_CACHE_FRIENDLY) - //m_traversalMode(TRAVERSAL_STACKLESS) - //m_traversalMode(TRAVERSAL_RECURSIVE) - ,m_subtreeHeaderCount(0) //PCK: add this line +b3QuantizedBvh::b3QuantizedBvh() : m_bulletVersion(B3_BULLET_VERSION), + m_useQuantization(false), + m_traversalMode(TRAVERSAL_STACKLESS_CACHE_FRIENDLY) + //m_traversalMode(TRAVERSAL_STACKLESS) + //m_traversalMode(TRAVERSAL_RECURSIVE) + , + m_subtreeHeaderCount(0) //PCK: add this line { - m_bvhAabbMin.setValue(-B3_INFINITY,-B3_INFINITY,-B3_INFINITY); - m_bvhAabbMax.setValue(B3_INFINITY,B3_INFINITY,B3_INFINITY); + m_bvhAabbMin.setValue(-B3_INFINITY, -B3_INFINITY, -B3_INFINITY); + m_bvhAabbMax.setValue(B3_INFINITY, B3_INFINITY, B3_INFINITY); } - - - - void b3QuantizedBvh::buildInternal() { ///assumes that caller filled in the m_quantizedLeafNodes m_useQuantization = true; int numLeafNodes = 0; - + if (m_useQuantization) { //now we have an array of leafnodes in m_leafNodes numLeafNodes = m_quantizedLeafNodes.size(); - m_quantizedContiguousNodes.resize(2*numLeafNodes); - + m_quantizedContiguousNodes.resize(2 * numLeafNodes); } m_curNodeIndex = 0; - buildTree(0,numLeafNodes); + buildTree(0, numLeafNodes); ///if the entire tree is small then subtree size, we need to create a header info for the tree - if(m_useQuantization && !m_SubtreeHeaders.size()) + if (m_useQuantization && !m_SubtreeHeaders.size()) { b3BvhSubtreeInfo& subtree = m_SubtreeHeaders.expand(); subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[0]); @@ -72,35 +66,27 @@ void b3QuantizedBvh::buildInternal() m_leafNodes.clear(); } - - ///just for debugging, to visualize the individual patches/subtrees #ifdef DEBUG_PATCH_COLORS -b3Vector3 color[4]= -{ - b3Vector3(1,0,0), - b3Vector3(0,1,0), - b3Vector3(0,0,1), - b3Vector3(0,1,1) -}; -#endif //DEBUG_PATCH_COLORS +b3Vector3 color[4] = + { + b3Vector3(1, 0, 0), + b3Vector3(0, 1, 0), + b3Vector3(0, 0, 1), + b3Vector3(0, 1, 1)}; +#endif //DEBUG_PATCH_COLORS - - -void b3QuantizedBvh::setQuantizationValues(const b3Vector3& bvhAabbMin,const b3Vector3& bvhAabbMax,b3Scalar quantizationMargin) +void b3QuantizedBvh::setQuantizationValues(const b3Vector3& bvhAabbMin, const b3Vector3& bvhAabbMax, b3Scalar quantizationMargin) { //enlarge the AABB to avoid division by zero when initializing the quantization values - b3Vector3 clampValue =b3MakeVector3(quantizationMargin,quantizationMargin,quantizationMargin); + b3Vector3 clampValue = b3MakeVector3(quantizationMargin, quantizationMargin, quantizationMargin); m_bvhAabbMin = bvhAabbMin - clampValue; m_bvhAabbMax = bvhAabbMax + clampValue; b3Vector3 aabbSize = m_bvhAabbMax - m_bvhAabbMin; - m_bvhQuantization = b3MakeVector3(b3Scalar(65533.0),b3Scalar(65533.0),b3Scalar(65533.0)) / aabbSize; + m_bvhQuantization = b3MakeVector3(b3Scalar(65533.0), b3Scalar(65533.0), b3Scalar(65533.0)) / aabbSize; m_useQuantization = true; } - - - b3QuantizedBvh::~b3QuantizedBvh() { } @@ -108,104 +94,100 @@ b3QuantizedBvh::~b3QuantizedBvh() #ifdef DEBUG_TREE_BUILDING int gStackDepth = 0; int gMaxStackDepth = 0; -#endif //DEBUG_TREE_BUILDING +#endif //DEBUG_TREE_BUILDING -void b3QuantizedBvh::buildTree (int startIndex,int endIndex) +void b3QuantizedBvh::buildTree(int startIndex, int endIndex) { #ifdef DEBUG_TREE_BUILDING gStackDepth++; if (gStackDepth > gMaxStackDepth) gMaxStackDepth = gStackDepth; -#endif //DEBUG_TREE_BUILDING - +#endif //DEBUG_TREE_BUILDING int splitAxis, splitIndex, i; - int numIndices =endIndex-startIndex; + int numIndices = endIndex - startIndex; int curIndex = m_curNodeIndex; - b3Assert(numIndices>0); + b3Assert(numIndices > 0); - if (numIndices==1) + if (numIndices == 1) { #ifdef DEBUG_TREE_BUILDING gStackDepth--; -#endif //DEBUG_TREE_BUILDING - - assignInternalNodeFromLeafNode(m_curNodeIndex,startIndex); +#endif //DEBUG_TREE_BUILDING + + assignInternalNodeFromLeafNode(m_curNodeIndex, startIndex); m_curNodeIndex++; - return; + return; } //calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'. - - splitAxis = calcSplittingAxis(startIndex,endIndex); - splitIndex = sortAndCalcSplittingIndex(startIndex,endIndex,splitAxis); + splitAxis = calcSplittingAxis(startIndex, endIndex); + + splitIndex = sortAndCalcSplittingIndex(startIndex, endIndex, splitAxis); int internalNodeIndex = m_curNodeIndex; - + //set the min aabb to 'inf' or a max value, and set the max aabb to a -inf/minimum value. //the aabb will be expanded during buildTree/mergeInternalNodeAabb with actual node values - setInternalNodeAabbMin(m_curNodeIndex,m_bvhAabbMax);//can't use b3Vector3(B3_INFINITY,B3_INFINITY,B3_INFINITY)) because of quantization - setInternalNodeAabbMax(m_curNodeIndex,m_bvhAabbMin);//can't use b3Vector3(-B3_INFINITY,-B3_INFINITY,-B3_INFINITY)) because of quantization - - - for (i=startIndex;im_escapeIndex; - + int leftChildNodexIndex = m_curNodeIndex; //build left child tree - buildTree(startIndex,splitIndex); + buildTree(startIndex, splitIndex); int rightChildNodexIndex = m_curNodeIndex; //build right child tree - buildTree(splitIndex,endIndex); + buildTree(splitIndex, endIndex); #ifdef DEBUG_TREE_BUILDING gStackDepth--; -#endif //DEBUG_TREE_BUILDING +#endif //DEBUG_TREE_BUILDING int escapeIndex = m_curNodeIndex - curIndex; if (m_useQuantization) { //escapeIndex is the number of nodes of this subtree - const int sizeQuantizedNode =sizeof(b3QuantizedBvhNode); + const int sizeQuantizedNode = sizeof(b3QuantizedBvhNode); const int treeSizeInBytes = escapeIndex * sizeQuantizedNode; if (treeSizeInBytes > MAX_SUBTREE_SIZE_IN_BYTES) { - updateSubtreeHeaders(leftChildNodexIndex,rightChildNodexIndex); + updateSubtreeHeaders(leftChildNodexIndex, rightChildNodexIndex); } - } else + } + else { - } - setInternalNodeEscapeIndex(internalNodeIndex,escapeIndex); - + setInternalNodeEscapeIndex(internalNodeIndex, escapeIndex); } -void b3QuantizedBvh::updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex) +void b3QuantizedBvh::updateSubtreeHeaders(int leftChildNodexIndex, int rightChildNodexIndex) { b3Assert(m_useQuantization); b3QuantizedBvhNode& leftChildNode = m_quantizedContiguousNodes[leftChildNodexIndex]; int leftSubTreeSize = leftChildNode.isLeafNode() ? 1 : leftChildNode.getEscapeIndex(); - int leftSubTreeSizeInBytes = leftSubTreeSize * static_cast(sizeof(b3QuantizedBvhNode)); - + int leftSubTreeSizeInBytes = leftSubTreeSize * static_cast(sizeof(b3QuantizedBvhNode)); + b3QuantizedBvhNode& rightChildNode = m_quantizedContiguousNodes[rightChildNodexIndex]; int rightSubTreeSize = rightChildNode.isLeafNode() ? 1 : rightChildNode.getEscapeIndex(); - int rightSubTreeSizeInBytes = rightSubTreeSize * static_cast(sizeof(b3QuantizedBvhNode)); + int rightSubTreeSizeInBytes = rightSubTreeSize * static_cast(sizeof(b3QuantizedBvhNode)); - if(leftSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES) + if (leftSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES) { b3BvhSubtreeInfo& subtree = m_SubtreeHeaders.expand(); subtree.setAabbFromQuantizeNode(leftChildNode); @@ -213,7 +195,7 @@ void b3QuantizedBvh::updateSubtreeHeaders(int leftChildNodexIndex,int rightChild subtree.m_subtreeSize = leftSubTreeSize; } - if(rightSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES) + if (rightSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES) { b3BvhSubtreeInfo& subtree = m_SubtreeHeaders.expand(); subtree.setAabbFromQuantizeNode(rightChildNode); @@ -225,32 +207,31 @@ void b3QuantizedBvh::updateSubtreeHeaders(int leftChildNodexIndex,int rightChild m_subtreeHeaderCount = m_SubtreeHeaders.size(); } - -int b3QuantizedBvh::sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis) +int b3QuantizedBvh::sortAndCalcSplittingIndex(int startIndex, int endIndex, int splitAxis) { int i; - int splitIndex =startIndex; + int splitIndex = startIndex; int numIndices = endIndex - startIndex; b3Scalar splitValue; - b3Vector3 means=b3MakeVector3(b3Scalar(0.),b3Scalar(0.),b3Scalar(0.)); - for (i=startIndex;i splitValue) { //swap - swapLeafNodes(i,splitIndex); + swapLeafNodes(i, splitIndex); splitIndex++; } } @@ -260,56 +241,53 @@ int b3QuantizedBvh::sortAndCalcSplittingIndex(int startIndex,int endIndex,int sp //unbalanced1 is unsafe: it can cause stack overflows //bool unbalanced1 = ((splitIndex==startIndex) || (splitIndex == (endIndex-1))); - //unbalanced2 should work too: always use center (perfect balanced trees) + //unbalanced2 should work too: always use center (perfect balanced trees) //bool unbalanced2 = true; //this should be safe too: - int rangeBalancedIndices = numIndices/3; - bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices))); - + int rangeBalancedIndices = numIndices / 3; + bool unbalanced = ((splitIndex <= (startIndex + rangeBalancedIndices)) || (splitIndex >= (endIndex - 1 - rangeBalancedIndices))); + if (unbalanced) { - splitIndex = startIndex+ (numIndices>>1); + splitIndex = startIndex + (numIndices >> 1); } - bool unbal = (splitIndex==startIndex) || (splitIndex == (endIndex)); + bool unbal = (splitIndex == startIndex) || (splitIndex == (endIndex)); (void)unbal; b3Assert(!unbal); return splitIndex; } - -int b3QuantizedBvh::calcSplittingAxis(int startIndex,int endIndex) +int b3QuantizedBvh::calcSplittingAxis(int startIndex, int endIndex) { int i; - b3Vector3 means=b3MakeVector3(b3Scalar(0.),b3Scalar(0.),b3Scalar(0.)); - b3Vector3 variance=b3MakeVector3(b3Scalar(0.),b3Scalar(0.),b3Scalar(0.)); - int numIndices = endIndex-startIndex; + b3Vector3 means = b3MakeVector3(b3Scalar(0.), b3Scalar(0.), b3Scalar(0.)); + b3Vector3 variance = b3MakeVector3(b3Scalar(0.), b3Scalar(0.), b3Scalar(0.)); + int numIndices = endIndex - startIndex; - for (i=startIndex;im_aabbMinOrg,rootNode->m_aabbMaxOrg); + aabbOverlap = b3TestAabbAgainstAabb2(aabbMin, aabbMax, rootNode->m_aabbMinOrg, rootNode->m_aabbMaxOrg); isLeafNode = rootNode->m_escapeIndex == -1; - + //PCK: unsigned instead of bool if (isLeafNode && (aabbOverlap != 0)) { - nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex); - } - + nodeCallback->processNode(rootNode->m_subPart, rootNode->m_triangleIndex); + } + //PCK: unsigned instead of bool if ((aabbOverlap != 0) || isLeafNode) { rootNode++; curIndex++; - } else + } + else { escapeIndex = rootNode->m_escapeIndex; rootNode += escapeIndex; @@ -389,7 +367,6 @@ void b3QuantizedBvh::walkStacklessTree(b3NodeOverlapCallback* nodeCallback,const } if (b3s_maxIterations < walkIterations) b3s_maxIterations = walkIterations; - } /* @@ -413,39 +390,38 @@ void b3QuantizedBvh::walkTree(b3OptimizedBvhNode* rootNode,b3NodeOverlapCallback } */ -void b3QuantizedBvh::walkRecursiveQuantizedTreeAgainstQueryAabb(const b3QuantizedBvhNode* currentNode,b3NodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const +void b3QuantizedBvh::walkRecursiveQuantizedTreeAgainstQueryAabb(const b3QuantizedBvhNode* currentNode, b3NodeOverlapCallback* nodeCallback, unsigned short int* quantizedQueryAabbMin, unsigned short int* quantizedQueryAabbMax) const { b3Assert(m_useQuantization); - + bool isLeafNode; //PCK: unsigned instead of bool unsigned aabbOverlap; //PCK: unsigned instead of bool - aabbOverlap = b3TestQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,currentNode->m_quantizedAabbMin,currentNode->m_quantizedAabbMax); + aabbOverlap = b3TestQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin, quantizedQueryAabbMax, currentNode->m_quantizedAabbMin, currentNode->m_quantizedAabbMax); isLeafNode = currentNode->isLeafNode(); - + //PCK: unsigned instead of bool if (aabbOverlap != 0) { if (isLeafNode) { - nodeCallback->processNode(currentNode->getPartId(),currentNode->getTriangleIndex()); - } else + nodeCallback->processNode(currentNode->getPartId(), currentNode->getTriangleIndex()); + } + else { //process left and right children - const b3QuantizedBvhNode* leftChildNode = currentNode+1; - walkRecursiveQuantizedTreeAgainstQueryAabb(leftChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax); + const b3QuantizedBvhNode* leftChildNode = currentNode + 1; + walkRecursiveQuantizedTreeAgainstQueryAabb(leftChildNode, nodeCallback, quantizedQueryAabbMin, quantizedQueryAabbMax); - const b3QuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? leftChildNode+1:leftChildNode+leftChildNode->getEscapeIndex(); - walkRecursiveQuantizedTreeAgainstQueryAabb(rightChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax); + const b3QuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? leftChildNode + 1 : leftChildNode + leftChildNode->getEscapeIndex(); + walkRecursiveQuantizedTreeAgainstQueryAabb(rightChildNode, nodeCallback, quantizedQueryAabbMin, quantizedQueryAabbMax); } - } + } } - - -void b3QuantizedBvh::walkStacklessTreeAgainstRay(b3NodeOverlapCallback* nodeCallback, const b3Vector3& raySource, const b3Vector3& rayTarget, const b3Vector3& aabbMin, const b3Vector3& aabbMax, int startNodeIndex,int endNodeIndex) const +void b3QuantizedBvh::walkStacklessTreeAgainstRay(b3NodeOverlapCallback* nodeCallback, const b3Vector3& raySource, const b3Vector3& rayTarget, const b3Vector3& aabbMin, const b3Vector3& aabbMax, int startNodeIndex, int endNodeIndex) const { b3Assert(!m_useQuantization); @@ -454,11 +430,11 @@ void b3QuantizedBvh::walkStacklessTreeAgainstRay(b3NodeOverlapCallback* nodeCall int walkIterations = 0; bool isLeafNode; //PCK: unsigned instead of bool - unsigned aabbOverlap=0; - unsigned rayBoxOverlap=0; + unsigned aabbOverlap = 0; + unsigned rayBoxOverlap = 0; b3Scalar lambda_max = 1.0; - - /* Quick pruning by quantized box */ + + /* Quick pruning by quantized box */ b3Vector3 rayAabbMin = raySource; b3Vector3 rayAabbMax = raySource; rayAabbMin.setMin(rayTarget); @@ -469,15 +445,15 @@ void b3QuantizedBvh::walkStacklessTreeAgainstRay(b3NodeOverlapCallback* nodeCall rayAabbMax += aabbMax; #ifdef RAYAABB2 - b3Vector3 rayDir = (rayTarget-raySource); - rayDir.normalize (); - lambda_max = rayDir.dot(rayTarget-raySource); + b3Vector3 rayDir = (rayTarget - raySource); + rayDir.normalize(); + lambda_max = rayDir.dot(rayTarget - raySource); ///what about division by zero? --> just set rayDirection[i] to 1.0 b3Vector3 rayDirectionInverse; rayDirectionInverse[0] = rayDir[0] == b3Scalar(0.0) ? b3Scalar(B3_LARGE_FLOAT) : b3Scalar(1.0) / rayDir[0]; rayDirectionInverse[1] = rayDir[1] == b3Scalar(0.0) ? b3Scalar(B3_LARGE_FLOAT) : b3Scalar(1.0) / rayDir[1]; rayDirectionInverse[2] = rayDir[2] == b3Scalar(0.0) ? b3Scalar(B3_LARGE_FLOAT) : b3Scalar(1.0) / rayDir[2]; - unsigned int sign[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0}; + unsigned int sign[3] = {rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0}; #endif b3Vector3 bounds[2]; @@ -486,7 +462,7 @@ void b3QuantizedBvh::walkStacklessTreeAgainstRay(b3NodeOverlapCallback* nodeCall { b3Scalar param = 1.0; //catch bugs in tree data - b3Assert (walkIterations < m_curNodeIndex); + b3Assert(walkIterations < m_curNodeIndex); walkIterations++; @@ -496,34 +472,35 @@ void b3QuantizedBvh::walkStacklessTreeAgainstRay(b3NodeOverlapCallback* nodeCall bounds[0] -= aabbMax; bounds[1] -= aabbMin; - aabbOverlap = b3TestAabbAgainstAabb2(rayAabbMin,rayAabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg); + aabbOverlap = b3TestAabbAgainstAabb2(rayAabbMin, rayAabbMax, rootNode->m_aabbMinOrg, rootNode->m_aabbMaxOrg); //perhaps profile if it is worth doing the aabbOverlap test first #ifdef RAYAABB2 - ///careful with this check: need to check division by zero (above) and fix the unQuantize method - ///thanks Joerg/hiker for the reproduction case! - ///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858 - rayBoxOverlap = aabbOverlap ? b3RayAabb2 (raySource, rayDirectionInverse, sign, bounds, param, 0.0f, lambda_max) : false; + ///careful with this check: need to check division by zero (above) and fix the unQuantize method + ///thanks Joerg/hiker for the reproduction case! + ///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858 + rayBoxOverlap = aabbOverlap ? b3RayAabb2(raySource, rayDirectionInverse, sign, bounds, param, 0.0f, lambda_max) : false; #else b3Vector3 normal; - rayBoxOverlap = b3RayAabb(raySource, rayTarget,bounds[0],bounds[1],param, normal); + rayBoxOverlap = b3RayAabb(raySource, rayTarget, bounds[0], bounds[1], param, normal); #endif isLeafNode = rootNode->m_escapeIndex == -1; - + //PCK: unsigned instead of bool if (isLeafNode && (rayBoxOverlap != 0)) { - nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex); - } - + nodeCallback->processNode(rootNode->m_subPart, rootNode->m_triangleIndex); + } + //PCK: unsigned instead of bool if ((rayBoxOverlap != 0) || isLeafNode) { rootNode++; curIndex++; - } else + } + else { escapeIndex = rootNode->m_escapeIndex; rootNode += escapeIndex; @@ -532,15 +509,12 @@ void b3QuantizedBvh::walkStacklessTreeAgainstRay(b3NodeOverlapCallback* nodeCall } if (b3s_maxIterations < walkIterations) b3s_maxIterations = walkIterations; - } - - -void b3QuantizedBvh::walkStacklessQuantizedTreeAgainstRay(b3NodeOverlapCallback* nodeCallback, const b3Vector3& raySource, const b3Vector3& rayTarget, const b3Vector3& aabbMin, const b3Vector3& aabbMax, int startNodeIndex,int endNodeIndex) const +void b3QuantizedBvh::walkStacklessQuantizedTreeAgainstRay(b3NodeOverlapCallback* nodeCallback, const b3Vector3& raySource, const b3Vector3& rayTarget, const b3Vector3& aabbMin, const b3Vector3& aabbMax, int startNodeIndex, int endNodeIndex) const { b3Assert(m_useQuantization); - + int curIndex = startNodeIndex; int walkIterations = 0; int subTreeSize = endNodeIndex - startNodeIndex; @@ -548,7 +522,7 @@ void b3QuantizedBvh::walkStacklessQuantizedTreeAgainstRay(b3NodeOverlapCallback* const b3QuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[startNodeIndex]; int escapeIndex; - + bool isLeafNode; //PCK: unsigned instead of bool unsigned boxBoxOverlap = 0; @@ -557,14 +531,14 @@ void b3QuantizedBvh::walkStacklessQuantizedTreeAgainstRay(b3NodeOverlapCallback* b3Scalar lambda_max = 1.0; #ifdef RAYAABB2 - b3Vector3 rayDirection = (rayTarget-raySource); - rayDirection.normalize (); - lambda_max = rayDirection.dot(rayTarget-raySource); + b3Vector3 rayDirection = (rayTarget - raySource); + rayDirection.normalize(); + lambda_max = rayDirection.dot(rayTarget - raySource); ///what about division by zero? --> just set rayDirection[i] to 1.0 rayDirection[0] = rayDirection[0] == b3Scalar(0.0) ? b3Scalar(B3_LARGE_FLOAT) : b3Scalar(1.0) / rayDirection[0]; rayDirection[1] = rayDirection[1] == b3Scalar(0.0) ? b3Scalar(B3_LARGE_FLOAT) : b3Scalar(1.0) / rayDirection[1]; rayDirection[2] = rayDirection[2] == b3Scalar(0.0) ? b3Scalar(B3_LARGE_FLOAT) : b3Scalar(1.0) / rayDirection[2]; - unsigned int sign[3] = { rayDirection[0] < 0.0, rayDirection[1] < 0.0, rayDirection[2] < 0.0}; + unsigned int sign[3] = {rayDirection[0] < 0.0, rayDirection[1] < 0.0, rayDirection[2] < 0.0}; #endif /* Quick pruning by quantized box */ @@ -579,37 +553,36 @@ void b3QuantizedBvh::walkStacklessQuantizedTreeAgainstRay(b3NodeOverlapCallback* unsigned short int quantizedQueryAabbMin[3]; unsigned short int quantizedQueryAabbMax[3]; - quantizeWithClamp(quantizedQueryAabbMin,rayAabbMin,0); - quantizeWithClamp(quantizedQueryAabbMax,rayAabbMax,1); + quantizeWithClamp(quantizedQueryAabbMin, rayAabbMin, 0); + quantizeWithClamp(quantizedQueryAabbMax, rayAabbMax, 1); while (curIndex < endNodeIndex) { - //#define VISUALLY_ANALYZE_BVH 1 #ifdef VISUALLY_ANALYZE_BVH //some code snippet to debugDraw aabb, to visually analyze bvh structure static int drawPatch = 0; //need some global access to a debugDrawer extern b3IDebugDraw* debugDrawerPtr; - if (curIndex==drawPatch) + if (curIndex == drawPatch) { - b3Vector3 aabbMin,aabbMax; + b3Vector3 aabbMin, aabbMax; aabbMin = unQuantize(rootNode->m_quantizedAabbMin); aabbMax = unQuantize(rootNode->m_quantizedAabbMax); - b3Vector3 color(1,0,0); - debugDrawerPtr->drawAabb(aabbMin,aabbMax,color); + b3Vector3 color(1, 0, 0); + debugDrawerPtr->drawAabb(aabbMin, aabbMax, color); } -#endif//VISUALLY_ANALYZE_BVH +#endif //VISUALLY_ANALYZE_BVH //catch bugs in tree data - b3Assert (walkIterations < subTreeSize); + b3Assert(walkIterations < subTreeSize); walkIterations++; //PCK: unsigned instead of bool // only interested if this is closer than any previous hit b3Scalar param = 1.0; rayBoxOverlap = 0; - boxBoxOverlap = b3TestQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax); + boxBoxOverlap = b3TestQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin, quantizedQueryAabbMax, rootNode->m_quantizedAabbMin, rootNode->m_quantizedAabbMax); isLeafNode = rootNode->isLeafNode(); if (boxBoxOverlap) { @@ -634,24 +607,25 @@ void b3QuantizedBvh::walkStacklessQuantizedTreeAgainstRay(b3NodeOverlapCallback* ///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858 //B3_PROFILE("b3RayAabb2"); - rayBoxOverlap = b3RayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0f, lambda_max); - + rayBoxOverlap = b3RayAabb2(raySource, rayDirection, sign, bounds, param, 0.0f, lambda_max); + #else - rayBoxOverlap = true;//b3RayAabb(raySource, rayTarget, bounds[0], bounds[1], param, normal); + rayBoxOverlap = true; //b3RayAabb(raySource, rayTarget, bounds[0], bounds[1], param, normal); #endif } - + if (isLeafNode && rayBoxOverlap) { - nodeCallback->processNode(rootNode->getPartId(),rootNode->getTriangleIndex()); + nodeCallback->processNode(rootNode->getPartId(), rootNode->getTriangleIndex()); } - + //PCK: unsigned instead of bool if ((rayBoxOverlap != 0) || isLeafNode) { rootNode++; curIndex++; - } else + } + else { escapeIndex = rootNode->getEscapeIndex(); rootNode += escapeIndex; @@ -660,13 +634,12 @@ void b3QuantizedBvh::walkStacklessQuantizedTreeAgainstRay(b3NodeOverlapCallback* } if (b3s_maxIterations < walkIterations) b3s_maxIterations = walkIterations; - } -void b3QuantizedBvh::walkStacklessQuantizedTree(b3NodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const +void b3QuantizedBvh::walkStacklessQuantizedTree(b3NodeOverlapCallback* nodeCallback, unsigned short int* quantizedQueryAabbMin, unsigned short int* quantizedQueryAabbMax, int startNodeIndex, int endNodeIndex) const { b3Assert(m_useQuantization); - + int curIndex = startNodeIndex; int walkIterations = 0; int subTreeSize = endNodeIndex - startNodeIndex; @@ -674,49 +647,49 @@ void b3QuantizedBvh::walkStacklessQuantizedTree(b3NodeOverlapCallback* nodeCallb const b3QuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[startNodeIndex]; int escapeIndex; - + bool isLeafNode; //PCK: unsigned instead of bool unsigned aabbOverlap; while (curIndex < endNodeIndex) { - //#define VISUALLY_ANALYZE_BVH 1 #ifdef VISUALLY_ANALYZE_BVH //some code snippet to debugDraw aabb, to visually analyze bvh structure static int drawPatch = 0; //need some global access to a debugDrawer extern b3IDebugDraw* debugDrawerPtr; - if (curIndex==drawPatch) + if (curIndex == drawPatch) { - b3Vector3 aabbMin,aabbMax; + b3Vector3 aabbMin, aabbMax; aabbMin = unQuantize(rootNode->m_quantizedAabbMin); aabbMax = unQuantize(rootNode->m_quantizedAabbMax); - b3Vector3 color(1,0,0); - debugDrawerPtr->drawAabb(aabbMin,aabbMax,color); + b3Vector3 color(1, 0, 0); + debugDrawerPtr->drawAabb(aabbMin, aabbMax, color); } -#endif//VISUALLY_ANALYZE_BVH +#endif //VISUALLY_ANALYZE_BVH //catch bugs in tree data - b3Assert (walkIterations < subTreeSize); + b3Assert(walkIterations < subTreeSize); walkIterations++; //PCK: unsigned instead of bool - aabbOverlap = b3TestQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax); + aabbOverlap = b3TestQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin, quantizedQueryAabbMax, rootNode->m_quantizedAabbMin, rootNode->m_quantizedAabbMax); isLeafNode = rootNode->isLeafNode(); - + if (isLeafNode && aabbOverlap) { - nodeCallback->processNode(rootNode->getPartId(),rootNode->getTriangleIndex()); - } - + nodeCallback->processNode(rootNode->getPartId(), rootNode->getTriangleIndex()); + } + //PCK: unsigned instead of bool if ((aabbOverlap != 0) || isLeafNode) { rootNode++; curIndex++; - } else + } + else { escapeIndex = rootNode->getEscapeIndex(); rootNode += escapeIndex; @@ -725,40 +698,36 @@ void b3QuantizedBvh::walkStacklessQuantizedTree(b3NodeOverlapCallback* nodeCallb } if (b3s_maxIterations < walkIterations) b3s_maxIterations = walkIterations; - } //This traversal can be called from Playstation 3 SPU -void b3QuantizedBvh::walkStacklessQuantizedTreeCacheFriendly(b3NodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const +void b3QuantizedBvh::walkStacklessQuantizedTreeCacheFriendly(b3NodeOverlapCallback* nodeCallback, unsigned short int* quantizedQueryAabbMin, unsigned short int* quantizedQueryAabbMax) const { b3Assert(m_useQuantization); int i; - - for (i=0;im_SubtreeHeaders.size();i++) + for (i = 0; i < this->m_SubtreeHeaders.size(); i++) { const b3BvhSubtreeInfo& subtree = m_SubtreeHeaders[i]; //PCK: unsigned instead of bool - unsigned overlap = b3TestQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax); + unsigned overlap = b3TestQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin, quantizedQueryAabbMax, subtree.m_quantizedAabbMin, subtree.m_quantizedAabbMax); if (overlap != 0) { - walkStacklessQuantizedTree(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax, - subtree.m_rootNodeIndex, - subtree.m_rootNodeIndex+subtree.m_subtreeSize); + walkStacklessQuantizedTree(nodeCallback, quantizedQueryAabbMin, quantizedQueryAabbMax, + subtree.m_rootNodeIndex, + subtree.m_rootNodeIndex + subtree.m_subtreeSize); } } } - -void b3QuantizedBvh::reportRayOverlappingNodex (b3NodeOverlapCallback* nodeCallback, const b3Vector3& raySource, const b3Vector3& rayTarget) const +void b3QuantizedBvh::reportRayOverlappingNodex(b3NodeOverlapCallback* nodeCallback, const b3Vector3& raySource, const b3Vector3& rayTarget) const { - reportBoxCastOverlappingNodex(nodeCallback,raySource,rayTarget,b3MakeVector3(0,0,0),b3MakeVector3(0,0,0)); + reportBoxCastOverlappingNodex(nodeCallback, raySource, rayTarget, b3MakeVector3(0, 0, 0), b3MakeVector3(0, 0, 0)); } - -void b3QuantizedBvh::reportBoxCastOverlappingNodex(b3NodeOverlapCallback* nodeCallback, const b3Vector3& raySource, const b3Vector3& rayTarget, const b3Vector3& aabbMin,const b3Vector3& aabbMax) const +void b3QuantizedBvh::reportBoxCastOverlappingNodex(b3NodeOverlapCallback* nodeCallback, const b3Vector3& raySource, const b3Vector3& rayTarget, const b3Vector3& aabbMin, const b3Vector3& aabbMax) const { //always use stackless @@ -782,31 +751,31 @@ void b3QuantizedBvh::reportBoxCastOverlappingNodex(b3NodeOverlapCallback* nodeCa reportAabbOverlappingNodex(nodeCallback,qaabbMin,qaabbMax); } */ - } - -void b3QuantizedBvh::swapLeafNodes(int i,int splitIndex) +void b3QuantizedBvh::swapLeafNodes(int i, int splitIndex) { if (m_useQuantization) { - b3QuantizedBvhNode tmp = m_quantizedLeafNodes[i]; - m_quantizedLeafNodes[i] = m_quantizedLeafNodes[splitIndex]; - m_quantizedLeafNodes[splitIndex] = tmp; - } else + b3QuantizedBvhNode tmp = m_quantizedLeafNodes[i]; + m_quantizedLeafNodes[i] = m_quantizedLeafNodes[splitIndex]; + m_quantizedLeafNodes[splitIndex] = tmp; + } + else { - b3OptimizedBvhNode tmp = m_leafNodes[i]; - m_leafNodes[i] = m_leafNodes[splitIndex]; - m_leafNodes[splitIndex] = tmp; + b3OptimizedBvhNode tmp = m_leafNodes[i]; + m_leafNodes[i] = m_leafNodes[splitIndex]; + m_leafNodes[splitIndex] = tmp; } } -void b3QuantizedBvh::assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex) +void b3QuantizedBvh::assignInternalNodeFromLeafNode(int internalNode, int leafNodeIndex) { if (m_useQuantization) { m_quantizedContiguousNodes[internalNode] = m_quantizedLeafNodes[leafNodeIndex]; - } else + } + else { m_contiguousNodes[internalNode] = m_leafNodes[leafNodeIndex]; } @@ -823,11 +792,10 @@ static const unsigned BVH_ALIGNMENT_MASK = BVH_ALIGNMENT-1; static const unsigned BVH_ALIGNMENT_BLOCKS = 2; #endif - unsigned int b3QuantizedBvh::getAlignmentSerializationPadding() { // I changed this to 0 since the extra padding is not needed or used. - return 0;//BVH_ALIGNMENT_BLOCKS * BVH_ALIGNMENT; + return 0; //BVH_ALIGNMENT_BLOCKS * BVH_ALIGNMENT; } unsigned b3QuantizedBvh::calculateSerializeBufferSize() const @@ -841,12 +809,12 @@ unsigned b3QuantizedBvh::calculateSerializeBufferSize() const return baseSize + m_curNodeIndex * sizeof(b3OptimizedBvhNode); } -bool b3QuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian) const +bool b3QuantizedBvh::serialize(void* o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian) const { b3Assert(m_subtreeHeaderCount == m_SubtreeHeaders.size()); m_subtreeHeaderCount = m_SubtreeHeaders.size(); -/* if (i_dataBufferSize < calculateSerializeBufferSize() || o_alignedDataBuffer == NULL || (((unsigned)o_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0)) + /* if (i_dataBufferSize < calculateSerializeBufferSize() || o_alignedDataBuffer == NULL || (((unsigned)o_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0)) { ///check alignedment for buffer? b3Assert(0); @@ -854,7 +822,7 @@ bool b3QuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBuffe } */ - b3QuantizedBvh *targetBvh = (b3QuantizedBvh *)o_alignedDataBuffer; + b3QuantizedBvh* targetBvh = (b3QuantizedBvh*)o_alignedDataBuffer; // construct the class so the virtual function table, etc will be set up // Also, m_leafNodes and m_quantizedLeafNodes will be initialized to default values by the constructor @@ -864,10 +832,9 @@ bool b3QuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBuffe { targetBvh->m_curNodeIndex = static_cast(b3SwapEndian(m_curNodeIndex)); - - b3SwapVector3Endian(m_bvhAabbMin,targetBvh->m_bvhAabbMin); - b3SwapVector3Endian(m_bvhAabbMax,targetBvh->m_bvhAabbMax); - b3SwapVector3Endian(m_bvhQuantization,targetBvh->m_bvhQuantization); + b3SwapVector3Endian(m_bvhAabbMin, targetBvh->m_bvhAabbMin); + b3SwapVector3Endian(m_bvhAabbMax, targetBvh->m_bvhAabbMax); + b3SwapVector3Endian(m_bvhQuantization, targetBvh->m_bvhQuantization); targetBvh->m_traversalMode = (b3TraversalMode)b3SwapEndian(m_traversalMode); targetBvh->m_subtreeHeaderCount = static_cast(b3SwapEndian(m_subtreeHeaderCount)); @@ -884,12 +851,12 @@ bool b3QuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBuffe targetBvh->m_useQuantization = m_useQuantization; - unsigned char *nodeData = (unsigned char *)targetBvh; + unsigned char* nodeData = (unsigned char*)targetBvh; nodeData += sizeof(b3QuantizedBvh); - - unsigned sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; + + unsigned sizeToAdd = 0; //(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; nodeData += sizeToAdd; - + int nodeCount = m_curNodeIndex; if (m_useQuantization) @@ -915,7 +882,6 @@ bool b3QuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBuffe { for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) { - targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]; targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]; targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]; @@ -925,8 +891,6 @@ bool b3QuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBuffe targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]; targetBvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex; - - } } nodeData += sizeof(b3QuantizedBvhNode) * nodeCount; @@ -972,7 +936,7 @@ bool b3QuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBuffe targetBvh->m_contiguousNodes.initializeFromBuffer(NULL, 0, 0); } - sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; + sizeToAdd = 0; //(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; nodeData += sizeToAdd; // Now serialize the subtree headers @@ -1027,14 +991,13 @@ bool b3QuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBuffe return true; } -b3QuantizedBvh *b3QuantizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian) +b3QuantizedBvh* b3QuantizedBvh::deSerializeInPlace(void* i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian) { - - if (i_alignedDataBuffer == NULL)// || (((unsigned)i_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0)) + if (i_alignedDataBuffer == NULL) // || (((unsigned)i_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0)) { return NULL; } - b3QuantizedBvh *bvh = (b3QuantizedBvh *)i_alignedDataBuffer; + b3QuantizedBvh* bvh = (b3QuantizedBvh*)i_alignedDataBuffer; if (i_swapEndian) { @@ -1056,12 +1019,12 @@ b3QuantizedBvh *b3QuantizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, un return NULL; } - unsigned char *nodeData = (unsigned char *)bvh; + unsigned char* nodeData = (unsigned char*)bvh; nodeData += sizeof(b3QuantizedBvh); - - unsigned sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; + + unsigned sizeToAdd = 0; //(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; nodeData += sizeToAdd; - + int nodeCount = bvh->m_curNodeIndex; // Must call placement new to fill in virtual function table, etc, but we don't want to overwrite most data, so call a special version of the constructor @@ -1099,7 +1062,7 @@ b3QuantizedBvh *b3QuantizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, un { b3UnSwapVector3Endian(bvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg); b3UnSwapVector3Endian(bvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg); - + bvh->m_contiguousNodes[nodeIndex].m_escapeIndex = static_cast(b3SwapEndian(bvh->m_contiguousNodes[nodeIndex].m_escapeIndex)); bvh->m_contiguousNodes[nodeIndex].m_subPart = static_cast(b3SwapEndian(bvh->m_contiguousNodes[nodeIndex].m_subPart)); bvh->m_contiguousNodes[nodeIndex].m_triangleIndex = static_cast(b3SwapEndian(bvh->m_contiguousNodes[nodeIndex].m_triangleIndex)); @@ -1108,7 +1071,7 @@ b3QuantizedBvh *b3QuantizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, un nodeData += sizeof(b3OptimizedBvhNode) * nodeCount; } - sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; + sizeToAdd = 0; //(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; nodeData += sizeToAdd; // Now serialize the subtree headers @@ -1134,13 +1097,11 @@ b3QuantizedBvh *b3QuantizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, un } // Constructor that prevents b3Vector3's default constructor from being called -b3QuantizedBvh::b3QuantizedBvh(b3QuantizedBvh &self, bool /* ownsMemory */) : -m_bvhAabbMin(self.m_bvhAabbMin), -m_bvhAabbMax(self.m_bvhAabbMax), -m_bvhQuantization(self.m_bvhQuantization), -m_bulletVersion(B3_BULLET_VERSION) +b3QuantizedBvh::b3QuantizedBvh(b3QuantizedBvh& self, bool /* ownsMemory */) : m_bvhAabbMin(self.m_bvhAabbMin), + m_bvhAabbMax(self.m_bvhAabbMax), + m_bvhQuantization(self.m_bvhQuantization), + m_bulletVersion(B3_BULLET_VERSION) { - } void b3QuantizedBvh::deSerializeFloat(struct b3QuantizedBvhFloatData& quantizedBvhFloatData) @@ -1150,8 +1111,8 @@ void b3QuantizedBvh::deSerializeFloat(struct b3QuantizedBvhFloatData& quantizedB m_bvhQuantization.deSerializeFloat(quantizedBvhFloatData.m_bvhQuantization); m_curNodeIndex = quantizedBvhFloatData.m_curNodeIndex; - m_useQuantization = quantizedBvhFloatData.m_useQuantization!=0; - + m_useQuantization = quantizedBvhFloatData.m_useQuantization != 0; + { int numElem = quantizedBvhFloatData.m_numContiguousLeafNodes; m_contiguousNodes.resize(numElem); @@ -1160,7 +1121,7 @@ void b3QuantizedBvh::deSerializeFloat(struct b3QuantizedBvhFloatData& quantizedB { b3OptimizedBvhNodeFloatData* memPtr = quantizedBvhFloatData.m_contiguousNodesPtr; - for (int i=0;im_aabbMaxOrg); m_contiguousNodes[i].m_aabbMinOrg.deSerializeFloat(memPtr->m_aabbMinOrg); @@ -1174,11 +1135,11 @@ void b3QuantizedBvh::deSerializeFloat(struct b3QuantizedBvhFloatData& quantizedB { int numElem = quantizedBvhFloatData.m_numQuantizedContiguousNodes; m_quantizedContiguousNodes.resize(numElem); - + if (numElem) { b3QuantizedBvhNodeData* memPtr = quantizedBvhFloatData.m_quantizedContiguousNodesPtr; - for (int i=0;im_escapeIndexOrTriangleIndex; m_quantizedContiguousNodes[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0]; @@ -1192,16 +1153,16 @@ void b3QuantizedBvh::deSerializeFloat(struct b3QuantizedBvhFloatData& quantizedB } m_traversalMode = b3TraversalMode(quantizedBvhFloatData.m_traversalMode); - + { int numElem = quantizedBvhFloatData.m_numSubtreeHeaders; m_SubtreeHeaders.resize(numElem); if (numElem) { b3BvhSubtreeInfoData* memPtr = quantizedBvhFloatData.m_subTreeInfoPtr; - for (int i=0;im_quantizedAabbMax[0] ; + m_SubtreeHeaders[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0]; m_SubtreeHeaders[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1]; m_SubtreeHeaders[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2]; m_SubtreeHeaders[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0]; @@ -1221,8 +1182,8 @@ void b3QuantizedBvh::deSerializeDouble(struct b3QuantizedBvhDoubleData& quantize m_bvhQuantization.deSerializeDouble(quantizedBvhDoubleData.m_bvhQuantization); m_curNodeIndex = quantizedBvhDoubleData.m_curNodeIndex; - m_useQuantization = quantizedBvhDoubleData.m_useQuantization!=0; - + m_useQuantization = quantizedBvhDoubleData.m_useQuantization != 0; + { int numElem = quantizedBvhDoubleData.m_numContiguousLeafNodes; m_contiguousNodes.resize(numElem); @@ -1231,7 +1192,7 @@ void b3QuantizedBvh::deSerializeDouble(struct b3QuantizedBvhDoubleData& quantize { b3OptimizedBvhNodeDoubleData* memPtr = quantizedBvhDoubleData.m_contiguousNodesPtr; - for (int i=0;im_aabbMaxOrg); m_contiguousNodes[i].m_aabbMinOrg.deSerializeDouble(memPtr->m_aabbMinOrg); @@ -1245,11 +1206,11 @@ void b3QuantizedBvh::deSerializeDouble(struct b3QuantizedBvhDoubleData& quantize { int numElem = quantizedBvhDoubleData.m_numQuantizedContiguousNodes; m_quantizedContiguousNodes.resize(numElem); - + if (numElem) { b3QuantizedBvhNodeData* memPtr = quantizedBvhDoubleData.m_quantizedContiguousNodesPtr; - for (int i=0;im_escapeIndexOrTriangleIndex; m_quantizedContiguousNodes[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0]; @@ -1263,16 +1224,16 @@ void b3QuantizedBvh::deSerializeDouble(struct b3QuantizedBvhDoubleData& quantize } m_traversalMode = b3TraversalMode(quantizedBvhDoubleData.m_traversalMode); - + { int numElem = quantizedBvhDoubleData.m_numSubtreeHeaders; m_SubtreeHeaders.resize(numElem); if (numElem) { b3BvhSubtreeInfoData* memPtr = quantizedBvhDoubleData.m_subTreeInfoPtr; - for (int i=0;im_quantizedAabbMax[0] ; + m_SubtreeHeaders[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0]; m_SubtreeHeaders[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1]; m_SubtreeHeaders[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2]; m_SubtreeHeaders[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0]; @@ -1283,19 +1244,11 @@ void b3QuantizedBvh::deSerializeDouble(struct b3QuantizedBvhDoubleData& quantize } } } - } - - ///fills the dataBuffer and returns the struct name (and 0 on failure) -const char* b3QuantizedBvh::serialize(void* dataBuffer, b3Serializer* serializer) const +const char* b3QuantizedBvh::serialize(void* dataBuffer, b3Serializer* serializer) const { b3Assert(0); return 0; } - - - - - diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3QuantizedBvh.h b/src/Bullet3OpenCL/NarrowphaseCollision/b3QuantizedBvh.h index 63c523c75..48b41abca 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3QuantizedBvh.h +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3QuantizedBvh.h @@ -22,11 +22,11 @@ class b3Serializer; #ifdef DEBUG_CHECK_DEQUANTIZATION #ifdef __SPU__ #define printf spu_printf -#endif //__SPU__ +#endif //__SPU__ #include #include -#endif //DEBUG_CHECK_DEQUANTIZATION +#endif //DEBUG_CHECK_DEQUANTIZATION #include "Bullet3Common/b3Vector3.h" #include "Bullet3Common/b3AlignedAllocator.h" @@ -44,13 +44,10 @@ class b3Serializer; #include "Bullet3Collision/NarrowPhaseCollision/shared/b3QuantizedBvhNodeData.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3BvhSubtreeInfoData.h" - - //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vclrf__m128.asp - //Note: currently we have 16 bytes per quantized node -#define MAX_SUBTREE_SIZE_IN_BYTES 2048 +#define MAX_SUBTREE_SIZE_IN_BYTES 2048 // 10 gives the potential for 1024 parts, with at most 2^21 (2097152) (minus one // actually) triangles each (since the sign bit is reserved @@ -58,7 +55,8 @@ class b3Serializer; ///b3QuantizedBvhNode is a compressed aabb node, 16 bytes. ///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range). -B3_ATTRIBUTE_ALIGNED16 (struct) b3QuantizedBvhNode : public b3QuantizedBvhNodeData +B3_ATTRIBUTE_ALIGNED16(struct) +b3QuantizedBvhNode : public b3QuantizedBvhNodeData { B3_DECLARE_ALIGNED_ALLOCATOR(); @@ -72,48 +70,48 @@ B3_ATTRIBUTE_ALIGNED16 (struct) b3QuantizedBvhNode : public b3QuantizedBvhNodeDa b3Assert(!isLeafNode()); return -m_escapeIndexOrTriangleIndex; } - int getTriangleIndex() const + int getTriangleIndex() const { b3Assert(isLeafNode()); - unsigned int x=0; - unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS); + unsigned int x = 0; + unsigned int y = (~(x & 0)) << (31 - MAX_NUM_PARTS_IN_BITS); // Get only the lower bits where the triangle index is stored - return (m_escapeIndexOrTriangleIndex&~(y)); + return (m_escapeIndexOrTriangleIndex & ~(y)); } - int getPartId() const + int getPartId() const { b3Assert(isLeafNode()); // Get only the highest bits where the part index is stored - return (m_escapeIndexOrTriangleIndex>>(31-MAX_NUM_PARTS_IN_BITS)); + return (m_escapeIndexOrTriangleIndex >> (31 - MAX_NUM_PARTS_IN_BITS)); } -} -; +}; /// b3OptimizedBvhNode contains both internal and leaf node information. /// Total node size is 44 bytes / node. You can use the compressed version of 16 bytes. -B3_ATTRIBUTE_ALIGNED16 (struct) b3OptimizedBvhNode +B3_ATTRIBUTE_ALIGNED16(struct) +b3OptimizedBvhNode { B3_DECLARE_ALIGNED_ALLOCATOR(); //32 bytes - b3Vector3 m_aabbMinOrg; - b3Vector3 m_aabbMaxOrg; + b3Vector3 m_aabbMinOrg; + b3Vector3 m_aabbMaxOrg; //4 - int m_escapeIndex; + int m_escapeIndex; //8 //for child nodes - int m_subPart; - int m_triangleIndex; + int m_subPart; + int m_triangleIndex; -//pad the size to 64 bytes - char m_padding[20]; + //pad the size to 64 bytes + char m_padding[20]; }; - ///b3BvhSubtreeInfo provides info to gather a subtree of limited size -B3_ATTRIBUTE_ALIGNED16(class) b3BvhSubtreeInfo : public b3BvhSubtreeInfoData +B3_ATTRIBUTE_ALIGNED16(class) +b3BvhSubtreeInfo : public b3BvhSubtreeInfoData { public: B3_DECLARE_ALIGNED_ALLOCATOR(); @@ -123,8 +121,7 @@ public: //memset(&m_padding[0], 0, sizeof(m_padding)); } - - void setAabbFromQuantizeNode(const b3QuantizedBvhNode& quantizedNode) + void setAabbFromQuantizeNode(const b3QuantizedBvhNode& quantizedNode) { m_quantizedAabbMin[0] = quantizedNode.m_quantizedAabbMin[0]; m_quantizedAabbMin[1] = quantizedNode.m_quantizedAabbMin[1]; @@ -133,14 +130,12 @@ public: m_quantizedAabbMax[1] = quantizedNode.m_quantizedAabbMax[1]; m_quantizedAabbMax[2] = quantizedNode.m_quantizedAabbMax[2]; } -} -; - +}; class b3NodeOverlapCallback { public: - virtual ~b3NodeOverlapCallback() {}; + virtual ~b3NodeOverlapCallback(){}; virtual void processNode(int subPart, int triangleIndex) = 0; }; @@ -148,18 +143,16 @@ public: #include "Bullet3Common/b3AlignedAllocator.h" #include "Bullet3Common/b3AlignedObjectArray.h" - - ///for code readability: -typedef b3AlignedObjectArray NodeArray; -typedef b3AlignedObjectArray QuantizedNodeArray; -typedef b3AlignedObjectArray BvhSubtreeInfoArray; - +typedef b3AlignedObjectArray NodeArray; +typedef b3AlignedObjectArray QuantizedNodeArray; +typedef b3AlignedObjectArray BvhSubtreeInfoArray; ///The b3QuantizedBvh class stores an AABB tree that can be quickly traversed on CPU and Cell SPU. ///It is used by the b3BvhTriangleMeshShape as midphase ///It is recommended to use quantization for better performance and lower memory requirements. -B3_ATTRIBUTE_ALIGNED16(class) b3QuantizedBvh +B3_ATTRIBUTE_ALIGNED16(class) +b3QuantizedBvh { public: enum b3TraversalMode @@ -169,56 +162,48 @@ public: TRAVERSAL_RECURSIVE }; - - - - b3Vector3 m_bvhAabbMin; - b3Vector3 m_bvhAabbMax; - b3Vector3 m_bvhQuantization; + b3Vector3 m_bvhAabbMin; + b3Vector3 m_bvhAabbMax; + b3Vector3 m_bvhQuantization; protected: - int m_bulletVersion; //for serialization versioning. It could also be used to detect endianess. + int m_bulletVersion; //for serialization versioning. It could also be used to detect endianess. - int m_curNodeIndex; + int m_curNodeIndex; //quantization data - bool m_useQuantization; + bool m_useQuantization; + NodeArray m_leafNodes; + NodeArray m_contiguousNodes; + QuantizedNodeArray m_quantizedLeafNodes; + QuantizedNodeArray m_quantizedContiguousNodes; - - NodeArray m_leafNodes; - NodeArray m_contiguousNodes; - QuantizedNodeArray m_quantizedLeafNodes; - QuantizedNodeArray m_quantizedContiguousNodes; - - b3TraversalMode m_traversalMode; - BvhSubtreeInfoArray m_SubtreeHeaders; + b3TraversalMode m_traversalMode; + BvhSubtreeInfoArray m_SubtreeHeaders; //This is only used for serialization so we don't have to add serialization directly to b3AlignedObjectArray mutable int m_subtreeHeaderCount; - - - - ///two versions, one for quantized and normal nodes. This allows code-reuse while maintaining readability (no template/macro!) ///this might be refactored into a virtual, it is usually not calculated at run-time - void setInternalNodeAabbMin(int nodeIndex, const b3Vector3& aabbMin) + void setInternalNodeAabbMin(int nodeIndex, const b3Vector3& aabbMin) { if (m_useQuantization) { - quantize(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] ,aabbMin,0); - } else + quantize(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0], aabbMin, 0); + } + else { m_contiguousNodes[nodeIndex].m_aabbMinOrg = aabbMin; - } } - void setInternalNodeAabbMax(int nodeIndex,const b3Vector3& aabbMax) + void setInternalNodeAabbMax(int nodeIndex, const b3Vector3& aabbMax) { if (m_useQuantization) { - quantize(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0],aabbMax,1); - } else + quantize(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0], aabbMax, 1); + } + else { m_contiguousNodes[nodeIndex].m_aabbMaxOrg = aabbMax; } @@ -232,115 +217,102 @@ protected: } //non-quantized return m_leafNodes[nodeIndex].m_aabbMinOrg; - } b3Vector3 getAabbMax(int nodeIndex) const { if (m_useQuantization) { return unQuantize(&m_quantizedLeafNodes[nodeIndex].m_quantizedAabbMax[0]); - } + } //non-quantized return m_leafNodes[nodeIndex].m_aabbMaxOrg; - } - - void setInternalNodeEscapeIndex(int nodeIndex, int escapeIndex) + void setInternalNodeEscapeIndex(int nodeIndex, int escapeIndex) { if (m_useQuantization) { m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = -escapeIndex; - } + } else { m_contiguousNodes[nodeIndex].m_escapeIndex = escapeIndex; } - } - void mergeInternalNodeAabb(int nodeIndex,const b3Vector3& newAabbMin,const b3Vector3& newAabbMax) + void mergeInternalNodeAabb(int nodeIndex, const b3Vector3& newAabbMin, const b3Vector3& newAabbMax) { if (m_useQuantization) { unsigned short int quantizedAabbMin[3]; unsigned short int quantizedAabbMax[3]; - quantize(quantizedAabbMin,newAabbMin,0); - quantize(quantizedAabbMax,newAabbMax,1); - for (int i=0;i<3;i++) + quantize(quantizedAabbMin, newAabbMin, 0); + quantize(quantizedAabbMax, newAabbMax, 1); + for (int i = 0; i < 3; i++) { if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] > quantizedAabbMin[i]) m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] = quantizedAabbMin[i]; if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] < quantizedAabbMax[i]) m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] = quantizedAabbMax[i]; - } - } else + } + else { //non-quantized m_contiguousNodes[nodeIndex].m_aabbMinOrg.setMin(newAabbMin); - m_contiguousNodes[nodeIndex].m_aabbMaxOrg.setMax(newAabbMax); + m_contiguousNodes[nodeIndex].m_aabbMaxOrg.setMax(newAabbMax); } } - void swapLeafNodes(int firstIndex,int secondIndex); + void swapLeafNodes(int firstIndex, int secondIndex); - void assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex); + void assignInternalNodeFromLeafNode(int internalNode, int leafNodeIndex); protected: + void buildTree(int startIndex, int endIndex); - + int calcSplittingAxis(int startIndex, int endIndex); - void buildTree (int startIndex,int endIndex); + int sortAndCalcSplittingIndex(int startIndex, int endIndex, int splitAxis); - int calcSplittingAxis(int startIndex,int endIndex); + void walkStacklessTree(b3NodeOverlapCallback * nodeCallback, const b3Vector3& aabbMin, const b3Vector3& aabbMax) const; - int sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis); - - void walkStacklessTree(b3NodeOverlapCallback* nodeCallback,const b3Vector3& aabbMin,const b3Vector3& aabbMax) const; - - void walkStacklessQuantizedTreeAgainstRay(b3NodeOverlapCallback* nodeCallback, const b3Vector3& raySource, const b3Vector3& rayTarget, const b3Vector3& aabbMin, const b3Vector3& aabbMax, int startNodeIndex,int endNodeIndex) const; - void walkStacklessQuantizedTree(b3NodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const; - void walkStacklessTreeAgainstRay(b3NodeOverlapCallback* nodeCallback, const b3Vector3& raySource, const b3Vector3& rayTarget, const b3Vector3& aabbMin, const b3Vector3& aabbMax, int startNodeIndex,int endNodeIndex) const; + void walkStacklessQuantizedTreeAgainstRay(b3NodeOverlapCallback * nodeCallback, const b3Vector3& raySource, const b3Vector3& rayTarget, const b3Vector3& aabbMin, const b3Vector3& aabbMax, int startNodeIndex, int endNodeIndex) const; + void walkStacklessQuantizedTree(b3NodeOverlapCallback * nodeCallback, unsigned short int* quantizedQueryAabbMin, unsigned short int* quantizedQueryAabbMax, int startNodeIndex, int endNodeIndex) const; + void walkStacklessTreeAgainstRay(b3NodeOverlapCallback * nodeCallback, const b3Vector3& raySource, const b3Vector3& rayTarget, const b3Vector3& aabbMin, const b3Vector3& aabbMax, int startNodeIndex, int endNodeIndex) const; ///tree traversal designed for small-memory processors like PS3 SPU - void walkStacklessQuantizedTreeCacheFriendly(b3NodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const; + void walkStacklessQuantizedTreeCacheFriendly(b3NodeOverlapCallback * nodeCallback, unsigned short int* quantizedQueryAabbMin, unsigned short int* quantizedQueryAabbMax) const; ///use the 16-byte stackless 'skipindex' node tree to do a recursive traversal - void walkRecursiveQuantizedTreeAgainstQueryAabb(const b3QuantizedBvhNode* currentNode,b3NodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const; + void walkRecursiveQuantizedTreeAgainstQueryAabb(const b3QuantizedBvhNode* currentNode, b3NodeOverlapCallback* nodeCallback, unsigned short int* quantizedQueryAabbMin, unsigned short int* quantizedQueryAabbMax) const; ///use the 16-byte stackless 'skipindex' node tree to do a recursive traversal - void walkRecursiveQuantizedTreeAgainstQuantizedTree(const b3QuantizedBvhNode* treeNodeA,const b3QuantizedBvhNode* treeNodeB,b3NodeOverlapCallback* nodeCallback) const; - + void walkRecursiveQuantizedTreeAgainstQuantizedTree(const b3QuantizedBvhNode* treeNodeA, const b3QuantizedBvhNode* treeNodeB, b3NodeOverlapCallback* nodeCallback) const; - - - void updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex); + void updateSubtreeHeaders(int leftChildNodexIndex, int rightChildNodexIndex); public: - B3_DECLARE_ALIGNED_ALLOCATOR(); b3QuantizedBvh(); virtual ~b3QuantizedBvh(); - ///***************************************** expert/internal use only ************************* - void setQuantizationValues(const b3Vector3& bvhAabbMin,const b3Vector3& bvhAabbMax,b3Scalar quantizationMargin=b3Scalar(1.0)); - QuantizedNodeArray& getLeafNodeArray() { return m_quantizedLeafNodes; } + void setQuantizationValues(const b3Vector3& bvhAabbMin, const b3Vector3& bvhAabbMax, b3Scalar quantizationMargin = b3Scalar(1.0)); + QuantizedNodeArray& getLeafNodeArray() { return m_quantizedLeafNodes; } ///buildInternal is expert use only: assumes that setQuantizationValues and LeafNodeArray are initialized - void buildInternal(); + void buildInternal(); ///***************************************** expert/internal use only ************************* - void reportAabbOverlappingNodex(b3NodeOverlapCallback* nodeCallback,const b3Vector3& aabbMin,const b3Vector3& aabbMax) const; - void reportRayOverlappingNodex (b3NodeOverlapCallback* nodeCallback, const b3Vector3& raySource, const b3Vector3& rayTarget) const; - void reportBoxCastOverlappingNodex(b3NodeOverlapCallback* nodeCallback, const b3Vector3& raySource, const b3Vector3& rayTarget, const b3Vector3& aabbMin,const b3Vector3& aabbMax) const; + void reportAabbOverlappingNodex(b3NodeOverlapCallback * nodeCallback, const b3Vector3& aabbMin, const b3Vector3& aabbMax) const; + void reportRayOverlappingNodex(b3NodeOverlapCallback * nodeCallback, const b3Vector3& raySource, const b3Vector3& rayTarget) const; + void reportBoxCastOverlappingNodex(b3NodeOverlapCallback * nodeCallback, const b3Vector3& raySource, const b3Vector3& rayTarget, const b3Vector3& aabbMin, const b3Vector3& aabbMax) const; - B3_FORCE_INLINE void quantize(unsigned short* out, const b3Vector3& point,int isMax) const + B3_FORCE_INLINE void quantize(unsigned short* out, const b3Vector3& point, int isMax) const { - b3Assert(m_useQuantization); b3Assert(point.getX() <= m_bvhAabbMax.getX()); @@ -357,16 +329,16 @@ public: ///@todo: double-check this if (isMax) { - out[0] = (unsigned short) (((unsigned short)(v.getX()+b3Scalar(1.)) | 1)); - out[1] = (unsigned short) (((unsigned short)(v.getY()+b3Scalar(1.)) | 1)); - out[2] = (unsigned short) (((unsigned short)(v.getZ()+b3Scalar(1.)) | 1)); - } else - { - out[0] = (unsigned short) (((unsigned short)(v.getX()) & 0xfffe)); - out[1] = (unsigned short) (((unsigned short)(v.getY()) & 0xfffe)); - out[2] = (unsigned short) (((unsigned short)(v.getZ()) & 0xfffe)); + out[0] = (unsigned short)(((unsigned short)(v.getX() + b3Scalar(1.)) | 1)); + out[1] = (unsigned short)(((unsigned short)(v.getY() + b3Scalar(1.)) | 1)); + out[2] = (unsigned short)(((unsigned short)(v.getZ() + b3Scalar(1.)) | 1)); + } + else + { + out[0] = (unsigned short)(((unsigned short)(v.getX()) & 0xfffe)); + out[1] = (unsigned short)(((unsigned short)(v.getY()) & 0xfffe)); + out[2] = (unsigned short)(((unsigned short)(v.getZ()) & 0xfffe)); } - #ifdef DEBUG_CHECK_DEQUANTIZATION b3Vector3 newPoint = unQuantize(out); @@ -374,105 +346,97 @@ public: { if (newPoint.getX() < point.getX()) { - printf("unconservative X, diffX = %f, oldX=%f,newX=%f\n",newPoint.getX()-point.getX(), newPoint.getX(),point.getX()); + printf("unconservative X, diffX = %f, oldX=%f,newX=%f\n", newPoint.getX() - point.getX(), newPoint.getX(), point.getX()); } if (newPoint.getY() < point.getY()) { - printf("unconservative Y, diffY = %f, oldY=%f,newY=%f\n",newPoint.getY()-point.getY(), newPoint.getY(),point.getY()); + printf("unconservative Y, diffY = %f, oldY=%f,newY=%f\n", newPoint.getY() - point.getY(), newPoint.getY(), point.getY()); } if (newPoint.getZ() < point.getZ()) { - - printf("unconservative Z, diffZ = %f, oldZ=%f,newZ=%f\n",newPoint.getZ()-point.getZ(), newPoint.getZ(),point.getZ()); + printf("unconservative Z, diffZ = %f, oldZ=%f,newZ=%f\n", newPoint.getZ() - point.getZ(), newPoint.getZ(), point.getZ()); } - } else + } + else { if (newPoint.getX() > point.getX()) { - printf("unconservative X, diffX = %f, oldX=%f,newX=%f\n",newPoint.getX()-point.getX(), newPoint.getX(),point.getX()); + printf("unconservative X, diffX = %f, oldX=%f,newX=%f\n", newPoint.getX() - point.getX(), newPoint.getX(), point.getX()); } if (newPoint.getY() > point.getY()) { - printf("unconservative Y, diffY = %f, oldY=%f,newY=%f\n",newPoint.getY()-point.getY(), newPoint.getY(),point.getY()); + printf("unconservative Y, diffY = %f, oldY=%f,newY=%f\n", newPoint.getY() - point.getY(), newPoint.getY(), point.getY()); } if (newPoint.getZ() > point.getZ()) { - printf("unconservative Z, diffZ = %f, oldZ=%f,newZ=%f\n",newPoint.getZ()-point.getZ(), newPoint.getZ(),point.getZ()); + printf("unconservative Z, diffZ = %f, oldZ=%f,newZ=%f\n", newPoint.getZ() - point.getZ(), newPoint.getZ(), point.getZ()); } } -#endif //DEBUG_CHECK_DEQUANTIZATION - +#endif //DEBUG_CHECK_DEQUANTIZATION } - - B3_FORCE_INLINE void quantizeWithClamp(unsigned short* out, const b3Vector3& point2,int isMax) const + B3_FORCE_INLINE void quantizeWithClamp(unsigned short* out, const b3Vector3& point2, int isMax) const { - b3Assert(m_useQuantization); b3Vector3 clampedPoint(point2); clampedPoint.setMax(m_bvhAabbMin); clampedPoint.setMin(m_bvhAabbMax); - quantize(out,clampedPoint,isMax); - + quantize(out, clampedPoint, isMax); } - - B3_FORCE_INLINE b3Vector3 unQuantize(const unsigned short* vecIn) const + + B3_FORCE_INLINE b3Vector3 unQuantize(const unsigned short* vecIn) const { - b3Vector3 vecOut; - vecOut.setValue( + b3Vector3 vecOut; + vecOut.setValue( (b3Scalar)(vecIn[0]) / (m_bvhQuantization.getX()), (b3Scalar)(vecIn[1]) / (m_bvhQuantization.getY()), (b3Scalar)(vecIn[2]) / (m_bvhQuantization.getZ())); - vecOut += m_bvhAabbMin; - return vecOut; + vecOut += m_bvhAabbMin; + return vecOut; } ///setTraversalMode let's you choose between stackless, recursive or stackless cache friendly tree traversal. Note this is only implemented for quantized trees. - void setTraversalMode(b3TraversalMode traversalMode) + void setTraversalMode(b3TraversalMode traversalMode) { m_traversalMode = traversalMode; } - - B3_FORCE_INLINE QuantizedNodeArray& getQuantizedNodeArray() - { - return m_quantizedContiguousNodes; + B3_FORCE_INLINE QuantizedNodeArray& getQuantizedNodeArray() + { + return m_quantizedContiguousNodes; } - - B3_FORCE_INLINE BvhSubtreeInfoArray& getSubtreeInfoArray() + B3_FORCE_INLINE BvhSubtreeInfoArray& getSubtreeInfoArray() { return m_SubtreeHeaders; } -//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////// /////Calculate space needed to store BVH for serialization unsigned calculateSerializeBufferSize() const; /// Data buffer MUST be 16 byte aligned - virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const; + virtual bool serialize(void* o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const; ///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place' - static b3QuantizedBvh *deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian); + static b3QuantizedBvh* deSerializeInPlace(void* i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian); static unsigned int getAlignmentSerializationPadding(); -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// - - virtual int calculateSerializeBufferSizeNew() const; + virtual int calculateSerializeBufferSizeNew() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, b3Serializer* serializer) const; + virtual const char* serialize(void* dataBuffer, b3Serializer* serializer) const; - virtual void deSerializeFloat(struct b3QuantizedBvhFloatData& quantizedBvhFloatData); + virtual void deSerializeFloat(struct b3QuantizedBvhFloatData & quantizedBvhFloatData); - virtual void deSerializeDouble(struct b3QuantizedBvhDoubleData& quantizedBvhDoubleData); + virtual void deSerializeDouble(struct b3QuantizedBvhDoubleData & quantizedBvhDoubleData); - -//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////// B3_FORCE_INLINE bool isQuantized() { @@ -483,74 +447,65 @@ private: // Special "copy" constructor that allows for in-place deserialization // Prevents b3Vector3's default constructor from being called, but doesn't inialize much else // ownsMemory should most likely be false if deserializing, and if you are not, don't call this (it also changes the function signature, which we need) - b3QuantizedBvh(b3QuantizedBvh &other, bool ownsMemory); - -} -; - + b3QuantizedBvh(b3QuantizedBvh & other, bool ownsMemory); +}; struct b3OptimizedBvhNodeFloatData { - b3Vector3FloatData m_aabbMinOrg; - b3Vector3FloatData m_aabbMaxOrg; - int m_escapeIndex; - int m_subPart; - int m_triangleIndex; + b3Vector3FloatData m_aabbMinOrg; + b3Vector3FloatData m_aabbMaxOrg; + int m_escapeIndex; + int m_subPart; + int m_triangleIndex; char m_pad[4]; }; struct b3OptimizedBvhNodeDoubleData { - b3Vector3DoubleData m_aabbMinOrg; - b3Vector3DoubleData m_aabbMaxOrg; - int m_escapeIndex; - int m_subPart; - int m_triangleIndex; - char m_pad[4]; + b3Vector3DoubleData m_aabbMinOrg; + b3Vector3DoubleData m_aabbMaxOrg; + int m_escapeIndex; + int m_subPart; + int m_triangleIndex; + char m_pad[4]; }; - - -struct b3QuantizedBvhFloatData +struct b3QuantizedBvhFloatData { - b3Vector3FloatData m_bvhAabbMin; - b3Vector3FloatData m_bvhAabbMax; - b3Vector3FloatData m_bvhQuantization; - int m_curNodeIndex; - int m_useQuantization; - int m_numContiguousLeafNodes; - int m_numQuantizedContiguousNodes; - b3OptimizedBvhNodeFloatData *m_contiguousNodesPtr; - b3QuantizedBvhNodeData *m_quantizedContiguousNodesPtr; - b3BvhSubtreeInfoData *m_subTreeInfoPtr; - int m_traversalMode; - int m_numSubtreeHeaders; - + b3Vector3FloatData m_bvhAabbMin; + b3Vector3FloatData m_bvhAabbMax; + b3Vector3FloatData m_bvhQuantization; + int m_curNodeIndex; + int m_useQuantization; + int m_numContiguousLeafNodes; + int m_numQuantizedContiguousNodes; + b3OptimizedBvhNodeFloatData* m_contiguousNodesPtr; + b3QuantizedBvhNodeData* m_quantizedContiguousNodesPtr; + b3BvhSubtreeInfoData* m_subTreeInfoPtr; + int m_traversalMode; + int m_numSubtreeHeaders; }; -struct b3QuantizedBvhDoubleData +struct b3QuantizedBvhDoubleData { - b3Vector3DoubleData m_bvhAabbMin; - b3Vector3DoubleData m_bvhAabbMax; - b3Vector3DoubleData m_bvhQuantization; - int m_curNodeIndex; - int m_useQuantization; - int m_numContiguousLeafNodes; - int m_numQuantizedContiguousNodes; - b3OptimizedBvhNodeDoubleData *m_contiguousNodesPtr; - b3QuantizedBvhNodeData *m_quantizedContiguousNodesPtr; + b3Vector3DoubleData m_bvhAabbMin; + b3Vector3DoubleData m_bvhAabbMax; + b3Vector3DoubleData m_bvhQuantization; + int m_curNodeIndex; + int m_useQuantization; + int m_numContiguousLeafNodes; + int m_numQuantizedContiguousNodes; + b3OptimizedBvhNodeDoubleData* m_contiguousNodesPtr; + b3QuantizedBvhNodeData* m_quantizedContiguousNodesPtr; - int m_traversalMode; - int m_numSubtreeHeaders; - b3BvhSubtreeInfoData *m_subTreeInfoPtr; + int m_traversalMode; + int m_numSubtreeHeaders; + b3BvhSubtreeInfoData* m_subTreeInfoPtr; }; - -B3_FORCE_INLINE int b3QuantizedBvh::calculateSerializeBufferSizeNew() const +B3_FORCE_INLINE int b3QuantizedBvh::calculateSerializeBufferSizeNew() const { return sizeof(b3QuantizedBvhData); } - - -#endif //B3_QUANTIZED_BVH_H +#endif //B3_QUANTIZED_BVH_H diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3StridingMeshInterface.cpp b/src/Bullet3OpenCL/NarrowphaseCollision/b3StridingMeshInterface.cpp index 4d97f7f62..6b0c941f2 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3StridingMeshInterface.cpp +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3StridingMeshInterface.cpp @@ -15,35 +15,32 @@ subject to the following restrictions: #include "b3StridingMeshInterface.h" - b3StridingMeshInterface::~b3StridingMeshInterface() { - } - -void b3StridingMeshInterface::InternalProcessAllTriangles(b3InternalTriangleIndexCallback* callback,const b3Vector3& aabbMin,const b3Vector3& aabbMax) const +void b3StridingMeshInterface::InternalProcessAllTriangles(b3InternalTriangleIndexCallback* callback, const b3Vector3& aabbMin, const b3Vector3& aabbMax) const { (void)aabbMin; (void)aabbMax; int numtotalphysicsverts = 0; - int part,graphicssubparts = getNumSubParts(); - const unsigned char * vertexbase; - const unsigned char * indexbase; + int part, graphicssubparts = getNumSubParts(); + const unsigned char* vertexbase; + const unsigned char* indexbase; int indexstride; PHY_ScalarType type; PHY_ScalarType gfxindextype; - int stride,numverts,numtriangles; + int stride, numverts, numtriangles; int gfxindex; b3Vector3 triangle[3]; b3Vector3 meshScaling = getScaling(); ///if the number of parts is big, the performance might drop due to the innerloop switch on indextype - for (part=0;partinternalProcessTriangleIndex(triangle, part, gfxindex); + } + break; + } + case PHY_SHORT: + { + for (gfxindex = 0; gfxindex < numtriangles; gfxindex++) + { + unsigned short int* tri_indices = (unsigned short int*)(indexbase + gfxindex * indexstride); + graphicsbase = (float*)(vertexbase + tri_indices[0] * stride); + triangle[0].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ()); + graphicsbase = (float*)(vertexbase + tri_indices[1] * stride); + triangle[1].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ()); + graphicsbase = (float*)(vertexbase + tri_indices[2] * stride); + triangle[2].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ()); + callback->internalProcessTriangleIndex(triangle, part, gfxindex); + } + break; + } + case PHY_UCHAR: + { + for (gfxindex = 0; gfxindex < numtriangles; gfxindex++) + { + unsigned char* tri_indices = (unsigned char*)(indexbase + gfxindex * indexstride); + graphicsbase = (float*)(vertexbase + tri_indices[0] * stride); + triangle[0].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ()); + graphicsbase = (float*)(vertexbase + tri_indices[1] * stride); + triangle[1].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ()); + graphicsbase = (float*)(vertexbase + tri_indices[2] * stride); + triangle[2].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ()); + callback->internalProcessTriangleIndex(triangle, part, gfxindex); + } + break; + } + default: + b3Assert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT)); + } + break; + } - switch (gfxindextype) - { - case PHY_INTEGER: - { - for (gfxindex=0;gfxindexinternalProcessTriangleIndex(triangle,part,gfxindex); - } - break; - } - case PHY_SHORT: - { - for (gfxindex=0;gfxindexinternalProcessTriangleIndex(triangle,part,gfxindex); - } - break; - } - case PHY_UCHAR: - { - for (gfxindex=0;gfxindexinternalProcessTriangleIndex(triangle,part,gfxindex); - } - break; - } - default: - b3Assert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT)); - } - break; - } - - case PHY_DOUBLE: + case PHY_DOUBLE: { double* graphicsbase; switch (gfxindextype) { - case PHY_INTEGER: + case PHY_INTEGER: { - for (gfxindex=0;gfxindexinternalProcessTriangleIndex(triangle,part,gfxindex); + unsigned int* tri_indices = (unsigned int*)(indexbase + gfxindex * indexstride); + graphicsbase = (double*)(vertexbase + tri_indices[0] * stride); + triangle[0].setValue((b3Scalar)graphicsbase[0] * meshScaling.getX(), (b3Scalar)graphicsbase[1] * meshScaling.getY(), (b3Scalar)graphicsbase[2] * meshScaling.getZ()); + graphicsbase = (double*)(vertexbase + tri_indices[1] * stride); + triangle[1].setValue((b3Scalar)graphicsbase[0] * meshScaling.getX(), (b3Scalar)graphicsbase[1] * meshScaling.getY(), (b3Scalar)graphicsbase[2] * meshScaling.getZ()); + graphicsbase = (double*)(vertexbase + tri_indices[2] * stride); + triangle[2].setValue((b3Scalar)graphicsbase[0] * meshScaling.getX(), (b3Scalar)graphicsbase[1] * meshScaling.getY(), (b3Scalar)graphicsbase[2] * meshScaling.getZ()); + callback->internalProcessTriangleIndex(triangle, part, gfxindex); } break; } - case PHY_SHORT: + case PHY_SHORT: { - for (gfxindex=0;gfxindexinternalProcessTriangleIndex(triangle,part,gfxindex); + unsigned short int* tri_indices = (unsigned short int*)(indexbase + gfxindex * indexstride); + graphicsbase = (double*)(vertexbase + tri_indices[0] * stride); + triangle[0].setValue((b3Scalar)graphicsbase[0] * meshScaling.getX(), (b3Scalar)graphicsbase[1] * meshScaling.getY(), (b3Scalar)graphicsbase[2] * meshScaling.getZ()); + graphicsbase = (double*)(vertexbase + tri_indices[1] * stride); + triangle[1].setValue((b3Scalar)graphicsbase[0] * meshScaling.getX(), (b3Scalar)graphicsbase[1] * meshScaling.getY(), (b3Scalar)graphicsbase[2] * meshScaling.getZ()); + graphicsbase = (double*)(vertexbase + tri_indices[2] * stride); + triangle[2].setValue((b3Scalar)graphicsbase[0] * meshScaling.getX(), (b3Scalar)graphicsbase[1] * meshScaling.getY(), (b3Scalar)graphicsbase[2] * meshScaling.getZ()); + callback->internalProcessTriangleIndex(triangle, part, gfxindex); } break; } - case PHY_UCHAR: + case PHY_UCHAR: { - for (gfxindex=0;gfxindexinternalProcessTriangleIndex(triangle,part,gfxindex); + unsigned char* tri_indices = (unsigned char*)(indexbase + gfxindex * indexstride); + graphicsbase = (double*)(vertexbase + tri_indices[0] * stride); + triangle[0].setValue((b3Scalar)graphicsbase[0] * meshScaling.getX(), (b3Scalar)graphicsbase[1] * meshScaling.getY(), (b3Scalar)graphicsbase[2] * meshScaling.getZ()); + graphicsbase = (double*)(vertexbase + tri_indices[1] * stride); + triangle[1].setValue((b3Scalar)graphicsbase[0] * meshScaling.getX(), (b3Scalar)graphicsbase[1] * meshScaling.getY(), (b3Scalar)graphicsbase[2] * meshScaling.getZ()); + graphicsbase = (double*)(vertexbase + tri_indices[2] * stride); + triangle[2].setValue((b3Scalar)graphicsbase[0] * meshScaling.getX(), (b3Scalar)graphicsbase[1] * meshScaling.getY(), (b3Scalar)graphicsbase[2] * meshScaling.getZ()); + callback->internalProcessTriangleIndex(triangle, part, gfxindex); } break; } - default: - b3Assert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT)); + default: + b3Assert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT)); } break; } - default: - b3Assert((type == PHY_FLOAT) || (type == PHY_DOUBLE)); + default: + b3Assert((type == PHY_FLOAT) || (type == PHY_DOUBLE)); } unLockReadOnlyVertexBase(part); } } -void b3StridingMeshInterface::calculateAabbBruteForce(b3Vector3& aabbMin,b3Vector3& aabbMax) +void b3StridingMeshInterface::calculateAabbBruteForce(b3Vector3& aabbMin, b3Vector3& aabbMax) { - - struct AabbCalculationCallback : public b3InternalTriangleIndexCallback + struct AabbCalculationCallback : public b3InternalTriangleIndexCallback { - b3Vector3 m_aabbMin; - b3Vector3 m_aabbMax; + b3Vector3 m_aabbMin; + b3Vector3 m_aabbMax; AabbCalculationCallback() { - m_aabbMin.setValue(b3Scalar(B3_LARGE_FLOAT),b3Scalar(B3_LARGE_FLOAT),b3Scalar(B3_LARGE_FLOAT)); - m_aabbMax.setValue(b3Scalar(-B3_LARGE_FLOAT),b3Scalar(-B3_LARGE_FLOAT),b3Scalar(-B3_LARGE_FLOAT)); + m_aabbMin.setValue(b3Scalar(B3_LARGE_FLOAT), b3Scalar(B3_LARGE_FLOAT), b3Scalar(B3_LARGE_FLOAT)); + m_aabbMax.setValue(b3Scalar(-B3_LARGE_FLOAT), b3Scalar(-B3_LARGE_FLOAT), b3Scalar(-B3_LARGE_FLOAT)); } - virtual void internalProcessTriangleIndex(b3Vector3* triangle,int partId,int triangleIndex) + virtual void internalProcessTriangleIndex(b3Vector3* triangle, int partId, int triangleIndex) { (void)partId; (void)triangleIndex; @@ -202,13 +197,11 @@ void b3StridingMeshInterface::calculateAabbBruteForce(b3Vector3& aabbMin,b3Vecto }; //first calculate the total aabb for all triangles - AabbCalculationCallback aabbCallback; - aabbMin.setValue(b3Scalar(-B3_LARGE_FLOAT),b3Scalar(-B3_LARGE_FLOAT),b3Scalar(-B3_LARGE_FLOAT)); - aabbMax.setValue(b3Scalar(B3_LARGE_FLOAT),b3Scalar(B3_LARGE_FLOAT),b3Scalar(B3_LARGE_FLOAT)); - InternalProcessAllTriangles(&aabbCallback,aabbMin,aabbMax); + AabbCalculationCallback aabbCallback; + aabbMin.setValue(b3Scalar(-B3_LARGE_FLOAT), b3Scalar(-B3_LARGE_FLOAT), b3Scalar(-B3_LARGE_FLOAT)); + aabbMax.setValue(b3Scalar(B3_LARGE_FLOAT), b3Scalar(B3_LARGE_FLOAT), b3Scalar(B3_LARGE_FLOAT)); + InternalProcessAllTriangles(&aabbCallback, aabbMin, aabbMax); aabbMin = aabbCallback.m_aabbMin; aabbMax = aabbCallback.m_aabbMax; } - - diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3StridingMeshInterface.h b/src/Bullet3OpenCL/NarrowphaseCollision/b3StridingMeshInterface.h index 9513f68f7..087b30f3e 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3StridingMeshInterface.h +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3StridingMeshInterface.h @@ -20,148 +20,139 @@ subject to the following restrictions: #include "b3TriangleCallback.h" //#include "b3ConcaveShape.h" - -enum PHY_ScalarType { - PHY_FLOAT, PHY_DOUBLE, PHY_INTEGER, PHY_SHORT, - PHY_FIXEDPOINT88, PHY_UCHAR +enum PHY_ScalarType +{ + PHY_FLOAT, + PHY_DOUBLE, + PHY_INTEGER, + PHY_SHORT, + PHY_FIXEDPOINT88, + PHY_UCHAR }; - /// The b3StridingMeshInterface is the interface class for high performance generic access to triangle meshes, used in combination with b3BvhTriangleMeshShape and some other collision shapes. /// Using index striding of 3*sizeof(integer) it can use triangle arrays, using index striding of 1*sizeof(integer) it can handle triangle strips. /// It allows for sharing graphics and collision meshes. Also it provides locking/unlocking of graphics meshes that are in gpu memory. -B3_ATTRIBUTE_ALIGNED16(class ) b3StridingMeshInterface +B3_ATTRIBUTE_ALIGNED16(class) +b3StridingMeshInterface { - protected: - - b3Vector3 m_scaling; +protected: + b3Vector3 m_scaling; - public: - B3_DECLARE_ALIGNED_ALLOCATOR(); - - b3StridingMeshInterface() :m_scaling(b3MakeVector3(b3Scalar(1.),b3Scalar(1.),b3Scalar(1.))) - { +public: + B3_DECLARE_ALIGNED_ALLOCATOR(); - } + b3StridingMeshInterface() : m_scaling(b3MakeVector3(b3Scalar(1.), b3Scalar(1.), b3Scalar(1.))) + { + } - virtual ~b3StridingMeshInterface(); + virtual ~b3StridingMeshInterface(); + virtual void InternalProcessAllTriangles(b3InternalTriangleIndexCallback * callback, const b3Vector3& aabbMin, const b3Vector3& aabbMax) const; + ///brute force method to calculate aabb + void calculateAabbBruteForce(b3Vector3 & aabbMin, b3Vector3 & aabbMax); - virtual void InternalProcessAllTriangles(b3InternalTriangleIndexCallback* callback,const b3Vector3& aabbMin,const b3Vector3& aabbMax) const; + /// get read and write access to a subpart of a triangle mesh + /// this subpart has a continuous array of vertices and indices + /// in this way the mesh can be handled as chunks of memory with striding + /// very similar to OpenGL vertexarray support + /// make a call to unLockVertexBase when the read and write access is finished + virtual void getLockedVertexIndexBase(unsigned char** vertexbase, int& numverts, PHY_ScalarType& type, int& stride, unsigned char** indexbase, int& indexstride, int& numfaces, PHY_ScalarType& indicestype, int subpart = 0) = 0; - ///brute force method to calculate aabb - void calculateAabbBruteForce(b3Vector3& aabbMin,b3Vector3& aabbMax); + virtual void getLockedReadOnlyVertexIndexBase(const unsigned char** vertexbase, int& numverts, PHY_ScalarType& type, int& stride, const unsigned char** indexbase, int& indexstride, int& numfaces, PHY_ScalarType& indicestype, int subpart = 0) const = 0; - /// get read and write access to a subpart of a triangle mesh - /// this subpart has a continuous array of vertices and indices - /// in this way the mesh can be handled as chunks of memory with striding - /// very similar to OpenGL vertexarray support - /// make a call to unLockVertexBase when the read and write access is finished - virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0)=0; - - virtual void getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0) const=0; - - /// unLockVertexBase finishes the access to a subpart of the triangle mesh - /// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished - virtual void unLockVertexBase(int subpart)=0; + /// unLockVertexBase finishes the access to a subpart of the triangle mesh + /// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished + virtual void unLockVertexBase(int subpart) = 0; - virtual void unLockReadOnlyVertexBase(int subpart) const=0; + virtual void unLockReadOnlyVertexBase(int subpart) const = 0; + /// getNumSubParts returns the number of seperate subparts + /// each subpart has a continuous array of vertices and indices + virtual int getNumSubParts() const = 0; - /// getNumSubParts returns the number of seperate subparts - /// each subpart has a continuous array of vertices and indices - virtual int getNumSubParts() const=0; + virtual void preallocateVertices(int numverts) = 0; + virtual void preallocateIndices(int numindices) = 0; - virtual void preallocateVertices(int numverts)=0; - virtual void preallocateIndices(int numindices)=0; + virtual bool hasPremadeAabb() const { return false; } + virtual void setPremadeAabb(const b3Vector3& aabbMin, const b3Vector3& aabbMax) const + { + (void)aabbMin; + (void)aabbMax; + } + virtual void getPremadeAabb(b3Vector3 * aabbMin, b3Vector3 * aabbMax) const + { + (void)aabbMin; + (void)aabbMax; + } - virtual bool hasPremadeAabb() const { return false; } - virtual void setPremadeAabb(const b3Vector3& aabbMin, const b3Vector3& aabbMax ) const - { - (void) aabbMin; - (void) aabbMax; - } - virtual void getPremadeAabb(b3Vector3* aabbMin, b3Vector3* aabbMax ) const - { - (void) aabbMin; - (void) aabbMax; - } - - const b3Vector3& getScaling() const { - return m_scaling; - } - void setScaling(const b3Vector3& scaling) - { - m_scaling = scaling; - } - - virtual int calculateSerializeBufferSize() const; - - ///fills the dataBuffer and returns the struct name (and 0 on failure) - //virtual const char* serialize(void* dataBuffer, b3Serializer* serializer) const; + const b3Vector3& getScaling() const + { + return m_scaling; + } + void setScaling(const b3Vector3& scaling) + { + m_scaling = scaling; + } + virtual int calculateSerializeBufferSize() const; + ///fills the dataBuffer and returns the struct name (and 0 on failure) + //virtual const char* serialize(void* dataBuffer, b3Serializer* serializer) const; }; -struct b3IntIndexData +struct b3IntIndexData { - int m_value; + int m_value; }; -struct b3ShortIntIndexData +struct b3ShortIntIndexData { short m_value; char m_pad[2]; }; -struct b3ShortIntIndexTripletData +struct b3ShortIntIndexTripletData { - short m_values[3]; - char m_pad[2]; + short m_values[3]; + char m_pad[2]; }; -struct b3CharIndexTripletData +struct b3CharIndexTripletData { unsigned char m_values[3]; - char m_pad; + char m_pad; }; - ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 -struct b3MeshPartData +struct b3MeshPartData { - b3Vector3FloatData *m_vertices3f; - b3Vector3DoubleData *m_vertices3d; + b3Vector3FloatData* m_vertices3f; + b3Vector3DoubleData* m_vertices3d; - b3IntIndexData *m_indices32; - b3ShortIntIndexTripletData *m_3indices16; - b3CharIndexTripletData *m_3indices8; + b3IntIndexData* m_indices32; + b3ShortIntIndexTripletData* m_3indices16; + b3CharIndexTripletData* m_3indices8; - b3ShortIntIndexData *m_indices16;//backwards compatibility + b3ShortIntIndexData* m_indices16; //backwards compatibility - int m_numTriangles;//length of m_indices = m_numTriangles - int m_numVertices; + int m_numTriangles; //length of m_indices = m_numTriangles + int m_numVertices; }; - ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 -struct b3StridingMeshInterfaceData +struct b3StridingMeshInterfaceData { - b3MeshPartData *m_meshPartsPtr; - b3Vector3FloatData m_scaling; - int m_numMeshParts; + b3MeshPartData* m_meshPartsPtr; + b3Vector3FloatData m_scaling; + int m_numMeshParts; char m_padding[4]; }; - - - -B3_FORCE_INLINE int b3StridingMeshInterface::calculateSerializeBufferSize() const +B3_FORCE_INLINE int b3StridingMeshInterface::calculateSerializeBufferSize() const { return sizeof(b3StridingMeshInterfaceData); } - - -#endif //B3_STRIDING_MESHINTERFACE_H +#endif //B3_STRIDING_MESHINTERFACE_H diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3SupportMappings.h b/src/Bullet3OpenCL/NarrowphaseCollision/b3SupportMappings.h index d073ee57c..9ca1e2294 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3SupportMappings.h +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3SupportMappings.h @@ -6,33 +6,29 @@ #include "Bullet3Common/b3AlignedObjectArray.h" #include "b3VectorFloat4.h" - struct b3GjkPairDetector; - - -inline b3Vector3 localGetSupportVertexWithMargin(const float4& supportVec,const struct b3ConvexPolyhedronData* hull, - const b3AlignedObjectArray& verticesA, b3Scalar margin) +inline b3Vector3 localGetSupportVertexWithMargin(const float4& supportVec, const struct b3ConvexPolyhedronData* hull, + const b3AlignedObjectArray& verticesA, b3Scalar margin) { - b3Vector3 supVec = b3MakeVector3(b3Scalar(0.),b3Scalar(0.),b3Scalar(0.)); + b3Vector3 supVec = b3MakeVector3(b3Scalar(0.), b3Scalar(0.), b3Scalar(0.)); b3Scalar maxDot = b3Scalar(-B3_LARGE_FLOAT); - // Here we take advantage of dot(a, b*c) = dot(a*b, c). Note: This is true mathematically, but not numerically. - if( 0 < hull->m_numVertices ) - { - const b3Vector3 scaled = supportVec; - int index = (int) scaled.maxDot( &verticesA[hull->m_vertexOffset], hull->m_numVertices, maxDot); - return verticesA[hull->m_vertexOffset+index]; - } - - return supVec; + // Here we take advantage of dot(a, b*c) = dot(a*b, c). Note: This is true mathematically, but not numerically. + if (0 < hull->m_numVertices) + { + const b3Vector3 scaled = supportVec; + int index = (int)scaled.maxDot(&verticesA[hull->m_vertexOffset], hull->m_numVertices, maxDot); + return verticesA[hull->m_vertexOffset + index]; + } + return supVec; } -inline b3Vector3 localGetSupportVertexWithoutMargin(const float4& supportVec,const struct b3ConvexPolyhedronData* hull, - const b3AlignedObjectArray& verticesA) +inline b3Vector3 localGetSupportVertexWithoutMargin(const float4& supportVec, const struct b3ConvexPolyhedronData* hull, + const b3AlignedObjectArray& verticesA) { - return localGetSupportVertexWithMargin(supportVec,hull,verticesA,0.f); + return localGetSupportVertexWithMargin(supportVec, hull, verticesA, 0.f); } -#endif //B3_SUPPORT_MAPPINGS_H +#endif //B3_SUPPORT_MAPPINGS_H diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3TriangleCallback.cpp b/src/Bullet3OpenCL/NarrowphaseCollision/b3TriangleCallback.cpp index 906645188..3908c6de8 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3TriangleCallback.cpp +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3TriangleCallback.cpp @@ -17,12 +17,8 @@ subject to the following restrictions: b3TriangleCallback::~b3TriangleCallback() { - } - b3InternalTriangleIndexCallback::~b3InternalTriangleIndexCallback() { - } - diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3TriangleCallback.h b/src/Bullet3OpenCL/NarrowphaseCollision/b3TriangleCallback.h index 3059fa4f2..a0fd3e7ac 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3TriangleCallback.h +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3TriangleCallback.h @@ -18,13 +18,11 @@ subject to the following restrictions: #include "Bullet3Common/b3Vector3.h" - ///The b3TriangleCallback provides a callback for each overlapping triangle when calling processAllTriangles. ///This callback is called by processAllTriangles for all b3ConcaveShape derived class, such as b3BvhTriangleMeshShape, b3StaticPlaneShape and b3HeightfieldTerrainShape. class b3TriangleCallback { public: - virtual ~b3TriangleCallback(); virtual void processTriangle(b3Vector3* triangle, int partId, int triangleIndex) = 0; }; @@ -32,11 +30,8 @@ public: class b3InternalTriangleIndexCallback { public: - virtual ~b3InternalTriangleIndexCallback(); - virtual void internalProcessTriangleIndex(b3Vector3* triangle,int partId,int triangleIndex) = 0; + virtual void internalProcessTriangleIndex(b3Vector3* triangle, int partId, int triangleIndex) = 0; }; - - -#endif //B3_TRIANGLE_CALLBACK_H +#endif //B3_TRIANGLE_CALLBACK_H diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3TriangleIndexVertexArray.cpp b/src/Bullet3OpenCL/NarrowphaseCollision/b3TriangleIndexVertexArray.cpp index a0f59babb..73faadbdd 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3TriangleIndexVertexArray.cpp +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3TriangleIndexVertexArray.cpp @@ -15,81 +15,76 @@ subject to the following restrictions: #include "b3TriangleIndexVertexArray.h" -b3TriangleIndexVertexArray::b3TriangleIndexVertexArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride,int numVertices,b3Scalar* vertexBase,int vertexStride) -: m_hasAabb(0) +b3TriangleIndexVertexArray::b3TriangleIndexVertexArray(int numTriangles, int* triangleIndexBase, int triangleIndexStride, int numVertices, b3Scalar* vertexBase, int vertexStride) + : m_hasAabb(0) { b3IndexedMesh mesh; mesh.m_numTriangles = numTriangles; - mesh.m_triangleIndexBase = (const unsigned char *)triangleIndexBase; + mesh.m_triangleIndexBase = (const unsigned char*)triangleIndexBase; mesh.m_triangleIndexStride = triangleIndexStride; mesh.m_numVertices = numVertices; - mesh.m_vertexBase = (const unsigned char *)vertexBase; + mesh.m_vertexBase = (const unsigned char*)vertexBase; mesh.m_vertexStride = vertexStride; addIndexedMesh(mesh); - } b3TriangleIndexVertexArray::~b3TriangleIndexVertexArray() { - } -void b3TriangleIndexVertexArray::getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) +void b3TriangleIndexVertexArray::getLockedVertexIndexBase(unsigned char** vertexbase, int& numverts, PHY_ScalarType& type, int& vertexStride, unsigned char** indexbase, int& indexstride, int& numfaces, PHY_ScalarType& indicestype, int subpart) { - b3Assert(subpart< getNumSubParts() ); + b3Assert(subpart < getNumSubParts()); b3IndexedMesh& mesh = m_indexedMeshes[subpart]; numverts = mesh.m_numVertices; - (*vertexbase) = (unsigned char *) mesh.m_vertexBase; + (*vertexbase) = (unsigned char*)mesh.m_vertexBase; - type = mesh.m_vertexType; + type = mesh.m_vertexType; vertexStride = mesh.m_vertexStride; numfaces = mesh.m_numTriangles; - (*indexbase) = (unsigned char *)mesh.m_triangleIndexBase; + (*indexbase) = (unsigned char*)mesh.m_triangleIndexBase; indexstride = mesh.m_triangleIndexStride; indicestype = mesh.m_indexType; } -void b3TriangleIndexVertexArray::getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) const +void b3TriangleIndexVertexArray::getLockedReadOnlyVertexIndexBase(const unsigned char** vertexbase, int& numverts, PHY_ScalarType& type, int& vertexStride, const unsigned char** indexbase, int& indexstride, int& numfaces, PHY_ScalarType& indicestype, int subpart) const { const b3IndexedMesh& mesh = m_indexedMeshes[subpart]; numverts = mesh.m_numVertices; - (*vertexbase) = (const unsigned char *)mesh.m_vertexBase; + (*vertexbase) = (const unsigned char*)mesh.m_vertexBase; + + type = mesh.m_vertexType; - type = mesh.m_vertexType; - vertexStride = mesh.m_vertexStride; numfaces = mesh.m_numTriangles; - (*indexbase) = (const unsigned char *)mesh.m_triangleIndexBase; + (*indexbase) = (const unsigned char*)mesh.m_triangleIndexBase; indexstride = mesh.m_triangleIndexStride; indicestype = mesh.m_indexType; } -bool b3TriangleIndexVertexArray::hasPremadeAabb() const +bool b3TriangleIndexVertexArray::hasPremadeAabb() const { return (m_hasAabb == 1); } - -void b3TriangleIndexVertexArray::setPremadeAabb(const b3Vector3& aabbMin, const b3Vector3& aabbMax ) const +void b3TriangleIndexVertexArray::setPremadeAabb(const b3Vector3& aabbMin, const b3Vector3& aabbMax) const { m_aabbMin = aabbMin; m_aabbMax = aabbMax; - m_hasAabb = 1; // this is intentionally an int see notes in header + m_hasAabb = 1; // this is intentionally an int see notes in header } -void b3TriangleIndexVertexArray::getPremadeAabb(b3Vector3* aabbMin, b3Vector3* aabbMax ) const +void b3TriangleIndexVertexArray::getPremadeAabb(b3Vector3* aabbMin, b3Vector3* aabbMax) const { *aabbMin = m_aabbMin; *aabbMax = m_aabbMax; } - - diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3TriangleIndexVertexArray.h b/src/Bullet3OpenCL/NarrowphaseCollision/b3TriangleIndexVertexArray.h index d26b2893b..b6ceb8df1 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3TriangleIndexVertexArray.h +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3TriangleIndexVertexArray.h @@ -20,62 +20,59 @@ subject to the following restrictions: #include "Bullet3Common/b3AlignedObjectArray.h" #include "Bullet3Common/b3Scalar.h" - ///The b3IndexedMesh indexes a single vertex and index array. Multiple b3IndexedMesh objects can be passed into a b3TriangleIndexVertexArray using addIndexedMesh. ///Instead of the number of indices, we pass the number of triangles. -B3_ATTRIBUTE_ALIGNED16( struct) b3IndexedMesh +B3_ATTRIBUTE_ALIGNED16(struct) +b3IndexedMesh { B3_DECLARE_ALIGNED_ALLOCATOR(); - int m_numTriangles; - const unsigned char * m_triangleIndexBase; - // Size in byte of the indices for one triangle (3*sizeof(index_type) if the indices are tightly packed) - int m_triangleIndexStride; - int m_numVertices; - const unsigned char * m_vertexBase; - // Size of a vertex, in bytes - int m_vertexStride; + int m_numTriangles; + const unsigned char* m_triangleIndexBase; + // Size in byte of the indices for one triangle (3*sizeof(index_type) if the indices are tightly packed) + int m_triangleIndexStride; + int m_numVertices; + const unsigned char* m_vertexBase; + // Size of a vertex, in bytes + int m_vertexStride; - // The index type is set when adding an indexed mesh to the - // b3TriangleIndexVertexArray, do not set it manually - PHY_ScalarType m_indexType; + // The index type is set when adding an indexed mesh to the + // b3TriangleIndexVertexArray, do not set it manually + PHY_ScalarType m_indexType; - // The vertex type has a default type similar to Bullet's precision mode (float or double) - // but can be set manually if you for example run Bullet with double precision but have - // mesh data in single precision.. - PHY_ScalarType m_vertexType; + // The vertex type has a default type similar to Bullet's precision mode (float or double) + // but can be set manually if you for example run Bullet with double precision but have + // mesh data in single precision.. + PHY_ScalarType m_vertexType; - - b3IndexedMesh() - :m_indexType(PHY_INTEGER), + b3IndexedMesh() + : m_indexType(PHY_INTEGER), #ifdef B3_USE_DOUBLE_PRECISION - m_vertexType(PHY_DOUBLE) -#else // B3_USE_DOUBLE_PRECISION - m_vertexType(PHY_FLOAT) -#endif // B3_USE_DOUBLE_PRECISION - { - } -} -; + m_vertexType(PHY_DOUBLE) +#else // B3_USE_DOUBLE_PRECISION + m_vertexType(PHY_FLOAT) +#endif // B3_USE_DOUBLE_PRECISION + { + } +}; - -typedef b3AlignedObjectArray IndexedMeshArray; +typedef b3AlignedObjectArray IndexedMeshArray; ///The b3TriangleIndexVertexArray allows to access multiple triangle meshes, by indexing into existing triangle/index arrays. ///Additional meshes can be added using addIndexedMesh ///No duplcate is made of the vertex/index data, it only indexes into external vertex/index arrays. ///So keep those arrays around during the lifetime of this b3TriangleIndexVertexArray. -B3_ATTRIBUTE_ALIGNED16( class) b3TriangleIndexVertexArray : public b3StridingMeshInterface +B3_ATTRIBUTE_ALIGNED16(class) +b3TriangleIndexVertexArray : public b3StridingMeshInterface { protected: - IndexedMeshArray m_indexedMeshes; + IndexedMeshArray m_indexedMeshes; int m_pad[2]; - mutable int m_hasAabb; // using int instead of bool to maintain alignment + mutable int m_hasAabb; // using int instead of bool to maintain alignment mutable b3Vector3 m_aabbMin; mutable b3Vector3 m_aabbMax; public: - B3_DECLARE_ALIGNED_ALLOCATOR(); b3TriangleIndexVertexArray() : m_hasAabb(0) @@ -85,49 +82,47 @@ public: virtual ~b3TriangleIndexVertexArray(); //just to be backwards compatible - b3TriangleIndexVertexArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride,int numVertices,b3Scalar* vertexBase,int vertexStride); - - void addIndexedMesh(const b3IndexedMesh& mesh, PHY_ScalarType indexType = PHY_INTEGER) + b3TriangleIndexVertexArray(int numTriangles, int* triangleIndexBase, int triangleIndexStride, int numVertices, b3Scalar* vertexBase, int vertexStride); + + void addIndexedMesh(const b3IndexedMesh& mesh, PHY_ScalarType indexType = PHY_INTEGER) { m_indexedMeshes.push_back(mesh); - m_indexedMeshes[m_indexedMeshes.size()-1].m_indexType = indexType; + m_indexedMeshes[m_indexedMeshes.size() - 1].m_indexType = indexType; } - - - virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0); - virtual void getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0) const; + virtual void getLockedVertexIndexBase(unsigned char** vertexbase, int& numverts, PHY_ScalarType& type, int& vertexStride, unsigned char** indexbase, int& indexstride, int& numfaces, PHY_ScalarType& indicestype, int subpart = 0); + + virtual void getLockedReadOnlyVertexIndexBase(const unsigned char** vertexbase, int& numverts, PHY_ScalarType& type, int& vertexStride, const unsigned char** indexbase, int& indexstride, int& numfaces, PHY_ScalarType& indicestype, int subpart = 0) const; /// unLockVertexBase finishes the access to a subpart of the triangle mesh /// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished - virtual void unLockVertexBase(int subpart) {(void)subpart;} + virtual void unLockVertexBase(int subpart) { (void)subpart; } - virtual void unLockReadOnlyVertexBase(int subpart) const {(void)subpart;} + virtual void unLockReadOnlyVertexBase(int subpart) const { (void)subpart; } /// getNumSubParts returns the number of seperate subparts /// each subpart has a continuous array of vertices and indices - virtual int getNumSubParts() const { + virtual int getNumSubParts() const + { return (int)m_indexedMeshes.size(); } - IndexedMeshArray& getIndexedMeshArray() + IndexedMeshArray& getIndexedMeshArray() { return m_indexedMeshes; } - const IndexedMeshArray& getIndexedMeshArray() const + const IndexedMeshArray& getIndexedMeshArray() const { return m_indexedMeshes; } - virtual void preallocateVertices(int numverts){(void) numverts;} - virtual void preallocateIndices(int numindices){(void) numindices;} + virtual void preallocateVertices(int numverts) { (void)numverts; } + virtual void preallocateIndices(int numindices) { (void)numindices; } - virtual bool hasPremadeAabb() const; - virtual void setPremadeAabb(const b3Vector3& aabbMin, const b3Vector3& aabbMax ) const; - virtual void getPremadeAabb(b3Vector3* aabbMin, b3Vector3* aabbMax ) const; + virtual bool hasPremadeAabb() const; + virtual void setPremadeAabb(const b3Vector3& aabbMin, const b3Vector3& aabbMax) const; + virtual void getPremadeAabb(b3Vector3 * aabbMin, b3Vector3 * aabbMax) const; +}; -} -; - -#endif //B3_TRIANGLE_INDEX_VERTEX_ARRAY_H +#endif //B3_TRIANGLE_INDEX_VERTEX_ARRAY_H diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3VectorFloat4.h b/src/Bullet3OpenCL/NarrowphaseCollision/b3VectorFloat4.h index f6f65f771..5cc4b5a62 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3VectorFloat4.h +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3VectorFloat4.h @@ -7,5 +7,4 @@ #define float4 b3Vector3 //#define make_float4(x,y,z,w) b3Vector4(x,y,z,w) - -#endif //B3_VECTOR_FLOAT4_H +#endif //B3_VECTOR_FLOAT4_H diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3VoronoiSimplexSolver.cpp b/src/Bullet3OpenCL/NarrowphaseCollision/b3VoronoiSimplexSolver.cpp index cf3d5ef49..dae61d458 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3VoronoiSimplexSolver.cpp +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3VoronoiSimplexSolver.cpp @@ -23,26 +23,24 @@ subject to the following restrictions: */ - #include "b3VoronoiSimplexSolver.h" -#define VERTA 0 -#define VERTB 1 -#define VERTC 2 -#define VERTD 3 +#define VERTA 0 +#define VERTB 1 +#define VERTC 2 +#define VERTD 3 #define B3_CATCH_DEGENERATE_TETRAHEDRON 1 -void b3VoronoiSimplexSolver::removeVertex(int index) +void b3VoronoiSimplexSolver::removeVertex(int index) { - - b3Assert(m_numVertices>0); + b3Assert(m_numVertices > 0); m_numVertices--; m_simplexVectorW[index] = m_simplexVectorW[m_numVertices]; m_simplexPointsP[index] = m_simplexPointsP[m_numVertices]; m_simplexPointsQ[index] = m_simplexPointsQ[m_numVertices]; } -void b3VoronoiSimplexSolver::reduceVertices (const b3UsageBitfield& usedVerts) +void b3VoronoiSimplexSolver::reduceVertices(const b3UsageBitfield& usedVerts) { if ((numVertices() >= 4) && (!usedVerts.usedVertexD)) removeVertex(3); @@ -52,29 +50,22 @@ void b3VoronoiSimplexSolver::reduceVertices (const b3UsageBitfield& usedVerts) if ((numVertices() >= 2) && (!usedVerts.usedVertexB)) removeVertex(1); - + if ((numVertices() >= 1) && (!usedVerts.usedVertexA)) removeVertex(0); - } - - - - //clear the simplex, remove all the vertices void b3VoronoiSimplexSolver::reset() { m_cachedValidClosest = false; m_numVertices = 0; m_needsUpdate = true; - m_lastW = b3MakeVector3(b3Scalar(B3_LARGE_FLOAT),b3Scalar(B3_LARGE_FLOAT),b3Scalar(B3_LARGE_FLOAT)); + m_lastW = b3MakeVector3(b3Scalar(B3_LARGE_FLOAT), b3Scalar(B3_LARGE_FLOAT), b3Scalar(B3_LARGE_FLOAT)); m_cachedBC.reset(); } - - - //add a vertex +//add a vertex void b3VoronoiSimplexSolver::addVertex(const b3Vector3& w, const b3Vector3& p, const b3Vector3& q) { m_lastW = w; @@ -87,9 +78,8 @@ void b3VoronoiSimplexSolver::addVertex(const b3Vector3& w, const b3Vector3& p, c m_numVertices++; } -bool b3VoronoiSimplexSolver::updateClosestVectorAndPoints() +bool b3VoronoiSimplexSolver::updateClosestVectorAndPoints() { - if (m_needsUpdate) { m_cachedBC.reset(); @@ -98,127 +88,131 @@ bool b3VoronoiSimplexSolver::updateClosestVectorAndPoints() switch (numVertices()) { - case 0: + case 0: m_cachedValidClosest = false; break; - case 1: + case 1: { m_cachedP1 = m_simplexPointsP[0]; m_cachedP2 = m_simplexPointsQ[0]; - m_cachedV = m_cachedP1-m_cachedP2; //== m_simplexVectorW[0] + m_cachedV = m_cachedP1 - m_cachedP2; //== m_simplexVectorW[0] m_cachedBC.reset(); - m_cachedBC.setBarycentricCoordinates(b3Scalar(1.),b3Scalar(0.),b3Scalar(0.),b3Scalar(0.)); + m_cachedBC.setBarycentricCoordinates(b3Scalar(1.), b3Scalar(0.), b3Scalar(0.), b3Scalar(0.)); m_cachedValidClosest = m_cachedBC.isValid(); break; }; - case 2: + case 2: { - //closest point origin from line segment - const b3Vector3& from = m_simplexVectorW[0]; - const b3Vector3& to = m_simplexVectorW[1]; - b3Vector3 nearest; + //closest point origin from line segment + const b3Vector3& from = m_simplexVectorW[0]; + const b3Vector3& to = m_simplexVectorW[1]; + b3Vector3 nearest; - b3Vector3 p =b3MakeVector3(b3Scalar(0.),b3Scalar(0.),b3Scalar(0.)); - b3Vector3 diff = p - from; - b3Vector3 v = to - from; - b3Scalar t = v.dot(diff); - - if (t > 0) { - b3Scalar dotVV = v.dot(v); - if (t < dotVV) { - t /= dotVV; - diff -= t*v; - m_cachedBC.m_usedVertices.usedVertexA = true; - m_cachedBC.m_usedVertices.usedVertexB = true; - } else { - t = 1; - diff -= v; - //reduce to 1 point - m_cachedBC.m_usedVertices.usedVertexB = true; - } - } else + b3Vector3 p = b3MakeVector3(b3Scalar(0.), b3Scalar(0.), b3Scalar(0.)); + b3Vector3 diff = p - from; + b3Vector3 v = to - from; + b3Scalar t = v.dot(diff); + + if (t > 0) + { + b3Scalar dotVV = v.dot(v); + if (t < dotVV) { - t = 0; - //reduce to 1 point + t /= dotVV; + diff -= t * v; m_cachedBC.m_usedVertices.usedVertexA = true; + m_cachedBC.m_usedVertices.usedVertexB = true; } - m_cachedBC.setBarycentricCoordinates(1-t,t); - nearest = from + t*v; + else + { + t = 1; + diff -= v; + //reduce to 1 point + m_cachedBC.m_usedVertices.usedVertexB = true; + } + } + else + { + t = 0; + //reduce to 1 point + m_cachedBC.m_usedVertices.usedVertexA = true; + } + m_cachedBC.setBarycentricCoordinates(1 - t, t); + nearest = from + t * v; - m_cachedP1 = m_simplexPointsP[0] + t * (m_simplexPointsP[1] - m_simplexPointsP[0]); - m_cachedP2 = m_simplexPointsQ[0] + t * (m_simplexPointsQ[1] - m_simplexPointsQ[0]); - m_cachedV = m_cachedP1 - m_cachedP2; - - reduceVertices(m_cachedBC.m_usedVertices); + m_cachedP1 = m_simplexPointsP[0] + t * (m_simplexPointsP[1] - m_simplexPointsP[0]); + m_cachedP2 = m_simplexPointsQ[0] + t * (m_simplexPointsQ[1] - m_simplexPointsQ[0]); + m_cachedV = m_cachedP1 - m_cachedP2; - m_cachedValidClosest = m_cachedBC.isValid(); - break; + reduceVertices(m_cachedBC.m_usedVertices); + + m_cachedValidClosest = m_cachedBC.isValid(); + break; } - case 3: - { - //closest point origin from triangle - b3Vector3 p =b3MakeVector3(b3Scalar(0.),b3Scalar(0.),b3Scalar(0.)); - - const b3Vector3& a = m_simplexVectorW[0]; - const b3Vector3& b = m_simplexVectorW[1]; - const b3Vector3& c = m_simplexVectorW[2]; - - closestPtPointTriangle(p,a,b,c,m_cachedBC); - m_cachedP1 = m_simplexPointsP[0] * m_cachedBC.m_barycentricCoords[0] + - m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] + - m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2]; - - m_cachedP2 = m_simplexPointsQ[0] * m_cachedBC.m_barycentricCoords[0] + - m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] + - m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2]; - - m_cachedV = m_cachedP1-m_cachedP2; - - reduceVertices (m_cachedBC.m_usedVertices); - m_cachedValidClosest = m_cachedBC.isValid(); - - break; - } - case 4: + case 3: { + //closest point origin from triangle + b3Vector3 p = b3MakeVector3(b3Scalar(0.), b3Scalar(0.), b3Scalar(0.)); + + const b3Vector3& a = m_simplexVectorW[0]; + const b3Vector3& b = m_simplexVectorW[1]; + const b3Vector3& c = m_simplexVectorW[2]; + + closestPtPointTriangle(p, a, b, c, m_cachedBC); + m_cachedP1 = m_simplexPointsP[0] * m_cachedBC.m_barycentricCoords[0] + + m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] + + m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2]; + + m_cachedP2 = m_simplexPointsQ[0] * m_cachedBC.m_barycentricCoords[0] + + m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] + + m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2]; + + m_cachedV = m_cachedP1 - m_cachedP2; + + reduceVertices(m_cachedBC.m_usedVertices); + m_cachedValidClosest = m_cachedBC.isValid(); + + break; + } + case 4: + { + b3Vector3 p = b3MakeVector3(b3Scalar(0.), b3Scalar(0.), b3Scalar(0.)); - - b3Vector3 p =b3MakeVector3(b3Scalar(0.),b3Scalar(0.),b3Scalar(0.)); - const b3Vector3& a = m_simplexVectorW[0]; const b3Vector3& b = m_simplexVectorW[1]; const b3Vector3& c = m_simplexVectorW[2]; const b3Vector3& d = m_simplexVectorW[3]; - bool hasSeperation = closestPtPointTetrahedron(p,a,b,c,d,m_cachedBC); + bool hasSeperation = closestPtPointTetrahedron(p, a, b, c, d, m_cachedBC); if (hasSeperation) { - m_cachedP1 = m_simplexPointsP[0] * m_cachedBC.m_barycentricCoords[0] + - m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] + - m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2] + - m_simplexPointsP[3] * m_cachedBC.m_barycentricCoords[3]; + m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] + + m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2] + + m_simplexPointsP[3] * m_cachedBC.m_barycentricCoords[3]; m_cachedP2 = m_simplexPointsQ[0] * m_cachedBC.m_barycentricCoords[0] + - m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] + - m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2] + - m_simplexPointsQ[3] * m_cachedBC.m_barycentricCoords[3]; + m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] + + m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2] + + m_simplexPointsQ[3] * m_cachedBC.m_barycentricCoords[3]; - m_cachedV = m_cachedP1-m_cachedP2; - reduceVertices (m_cachedBC.m_usedVertices); - } else + m_cachedV = m_cachedP1 - m_cachedP2; + reduceVertices(m_cachedBC.m_usedVertices); + } + else { -// printf("sub distance got penetration\n"); + // printf("sub distance got penetration\n"); if (m_cachedBC.m_degenerate) { m_cachedValidClosest = false; - } else + } + else { m_cachedValidClosest = true; //degenerate case == false, penetration = true + zero - m_cachedV.setValue(b3Scalar(0.),b3Scalar(0.),b3Scalar(0.)); + m_cachedV.setValue(b3Scalar(0.), b3Scalar(0.), b3Scalar(0.)); } break; } @@ -228,7 +222,7 @@ bool b3VoronoiSimplexSolver::updateClosestVectorAndPoints() //closest point origin from tetrahedron break; } - default: + default: { m_cachedValidClosest = false; } @@ -236,7 +230,6 @@ bool b3VoronoiSimplexSolver::updateClosestVectorAndPoints() } return m_cachedValidClosest; - } //return/calculate the closest vertex @@ -247,13 +240,11 @@ bool b3VoronoiSimplexSolver::closest(b3Vector3& v) return succes; } - - b3Scalar b3VoronoiSimplexSolver::maxVertex() { int i, numverts = numVertices(); b3Scalar maxV = b3Scalar(0.); - for (i=0;i= b3Scalar(0.0) && d4 <= d3) + // Check if P in vertex region outside B + b3Vector3 bp = p - b; + b3Scalar d3 = ab.dot(bp); + b3Scalar d4 = ac.dot(bp); + if (d3 >= b3Scalar(0.0) && d4 <= d3) { result.m_closestPointOnSimplex = b; result.m_usedVertices.usedVertexB = true; - result.setBarycentricCoordinates(0,1,0); + result.setBarycentricCoordinates(0, 1, 0); - return true; // b; // barycentric coordinates (0,1,0) + return true; // b; // barycentric coordinates (0,1,0) } - // Check if P in edge region of AB, if so return projection of P onto AB - b3Scalar vc = d1*d4 - d3*d2; - if (vc <= b3Scalar(0.0) && d1 >= b3Scalar(0.0) && d3 <= b3Scalar(0.0)) { - b3Scalar v = d1 / (d1 - d3); + // Check if P in edge region of AB, if so return projection of P onto AB + b3Scalar vc = d1 * d4 - d3 * d2; + if (vc <= b3Scalar(0.0) && d1 >= b3Scalar(0.0) && d3 <= b3Scalar(0.0)) + { + b3Scalar v = d1 / (d1 - d3); result.m_closestPointOnSimplex = a + v * ab; result.m_usedVertices.usedVertexA = true; result.m_usedVertices.usedVertexB = true; - result.setBarycentricCoordinates(1-v,v,0); + result.setBarycentricCoordinates(1 - v, v, 0); return true; - //return a + v * ab; // barycentric coordinates (1-v,v,0) - } + //return a + v * ab; // barycentric coordinates (1-v,v,0) + } - // Check if P in vertex region outside C - b3Vector3 cp = p - c; - b3Scalar d5 = ab.dot(cp); - b3Scalar d6 = ac.dot(cp); - if (d6 >= b3Scalar(0.0) && d5 <= d6) + // Check if P in vertex region outside C + b3Vector3 cp = p - c; + b3Scalar d5 = ab.dot(cp); + b3Scalar d6 = ac.dot(cp); + if (d6 >= b3Scalar(0.0) && d5 <= d6) { result.m_closestPointOnSimplex = c; result.m_usedVertices.usedVertexC = true; - result.setBarycentricCoordinates(0,0,1); - return true;//c; // barycentric coordinates (0,0,1) + result.setBarycentricCoordinates(0, 0, 1); + return true; //c; // barycentric coordinates (0,0,1) } - // Check if P in edge region of AC, if so return projection of P onto AC - b3Scalar vb = d5*d2 - d1*d6; - if (vb <= b3Scalar(0.0) && d2 >= b3Scalar(0.0) && d6 <= b3Scalar(0.0)) { - b3Scalar w = d2 / (d2 - d6); + // Check if P in edge region of AC, if so return projection of P onto AC + b3Scalar vb = d5 * d2 - d1 * d6; + if (vb <= b3Scalar(0.0) && d2 >= b3Scalar(0.0) && d6 <= b3Scalar(0.0)) + { + b3Scalar w = d2 / (d2 - d6); result.m_closestPointOnSimplex = a + w * ac; result.m_usedVertices.usedVertexA = true; result.m_usedVertices.usedVertexC = true; - result.setBarycentricCoordinates(1-w,0,w); + result.setBarycentricCoordinates(1 - w, 0, w); return true; - //return a + w * ac; // barycentric coordinates (1-w,0,w) - } + //return a + w * ac; // barycentric coordinates (1-w,0,w) + } + + // Check if P in edge region of BC, if so return projection of P onto BC + b3Scalar va = d3 * d6 - d5 * d4; + if (va <= b3Scalar(0.0) && (d4 - d3) >= b3Scalar(0.0) && (d5 - d6) >= b3Scalar(0.0)) + { + b3Scalar w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); - // Check if P in edge region of BC, if so return projection of P onto BC - b3Scalar va = d3*d6 - d5*d4; - if (va <= b3Scalar(0.0) && (d4 - d3) >= b3Scalar(0.0) && (d5 - d6) >= b3Scalar(0.0)) { - b3Scalar w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); - result.m_closestPointOnSimplex = b + w * (c - b); result.m_usedVertices.usedVertexB = true; result.m_usedVertices.usedVertexC = true; - result.setBarycentricCoordinates(0,1-w,w); - return true; - // return b + w * (c - b); // barycentric coordinates (0,1-w,w) - } + result.setBarycentricCoordinates(0, 1 - w, w); + return true; + // return b + w * (c - b); // barycentric coordinates (0,1-w,w) + } + + // P inside face region. Compute Q through its barycentric coordinates (u,v,w) + b3Scalar denom = b3Scalar(1.0) / (va + vb + vc); + b3Scalar v = vb * denom; + b3Scalar w = vc * denom; - // P inside face region. Compute Q through its barycentric coordinates (u,v,w) - b3Scalar denom = b3Scalar(1.0) / (va + vb + vc); - b3Scalar v = vb * denom; - b3Scalar w = vc * denom; - result.m_closestPointOnSimplex = a + ab * v + ac * w; result.m_usedVertices.usedVertexA = true; result.m_usedVertices.usedVertexB = true; result.m_usedVertices.usedVertexC = true; - result.setBarycentricCoordinates(1-v-w,v,w); - + result.setBarycentricCoordinates(1 - v - w, v, w); + return true; -// return a + ab * v + ac * w; // = u*a + v*b + w*c, u = va * denom = b3Scalar(1.0) - v - w - + // return a + ab * v + ac * w; // = u*a + v*b + w*c, u = va * denom = b3Scalar(1.0) - v - w } - - - - /// Test if point p and d lie on opposite sides of plane through abc int b3VoronoiSimplexSolver::pointOutsideOfPlane(const b3Vector3& p, const b3Vector3& a, const b3Vector3& b, const b3Vector3& c, const b3Vector3& d) { - b3Vector3 normal = (b-a).cross(c-a); + b3Vector3 normal = (b - a).cross(c - a); - b3Scalar signp = (p - a).dot(normal); // [AP AB AC] - b3Scalar signd = (d - a).dot( normal); // [AD AB AC] + b3Scalar signp = (p - a).dot(normal); // [AP AB AC] + b3Scalar signd = (d - a).dot(normal); // [AD AB AC] #ifdef B3_CATCH_DEGENERATE_TETRAHEDRON #ifdef BT_USE_DOUBLE_PRECISION -if (signd * signd < (b3Scalar(1e-8) * b3Scalar(1e-8))) + if (signd * signd < (b3Scalar(1e-8) * b3Scalar(1e-8))) { return -1; } #else if (signd * signd < (b3Scalar(1e-4) * b3Scalar(1e-4))) { -// printf("affine dependent/degenerate\n");// + // printf("affine dependent/degenerate\n");// return -1; } #endif #endif // Points on opposite sides if expression signs are opposite - return signp * signd < b3Scalar(0.); + return signp * signd < b3Scalar(0.); } - -bool b3VoronoiSimplexSolver::closestPtPointTetrahedron(const b3Vector3& p, const b3Vector3& a, const b3Vector3& b, const b3Vector3& c, const b3Vector3& d, b3SubSimplexClosestResult& finalResult) +bool b3VoronoiSimplexSolver::closestPtPointTetrahedron(const b3Vector3& p, const b3Vector3& a, const b3Vector3& b, const b3Vector3& c, const b3Vector3& d, b3SubSimplexClosestResult& finalResult) { b3SubSimplexClosestResult tempResult; - // Start out assuming point inside all halfspaces, so closest to itself + // Start out assuming point inside all halfspaces, so closest to itself finalResult.m_closestPointOnSimplex = p; finalResult.m_usedVertices.reset(); - finalResult.m_usedVertices.usedVertexA = true; + finalResult.m_usedVertices.usedVertexA = true; finalResult.m_usedVertices.usedVertexB = true; finalResult.m_usedVertices.usedVertexC = true; finalResult.m_usedVertices.usedVertexD = true; - int pointOutsideABC = pointOutsideOfPlane(p, a, b, c, d); + int pointOutsideABC = pointOutsideOfPlane(p, a, b, c, d); int pointOutsideACD = pointOutsideOfPlane(p, a, c, d, b); - int pointOutsideADB = pointOutsideOfPlane(p, a, d, b, c); - int pointOutsideBDC = pointOutsideOfPlane(p, b, d, c, a); + int pointOutsideADB = pointOutsideOfPlane(p, a, d, b, c); + int pointOutsideBDC = pointOutsideOfPlane(p, b, d, c, a); - if (pointOutsideABC < 0 || pointOutsideACD < 0 || pointOutsideADB < 0 || pointOutsideBDC < 0) - { - finalResult.m_degenerate = true; - return false; - } - - if (!pointOutsideABC && !pointOutsideACD && !pointOutsideADB && !pointOutsideBDC) - { - return false; - } - - - b3Scalar bestSqDist = FLT_MAX; - // If point outside face abc then compute closest point on abc - if (pointOutsideABC) + if (pointOutsideABC < 0 || pointOutsideACD < 0 || pointOutsideADB < 0 || pointOutsideBDC < 0) { - closestPtPointTriangle(p, a, b, c,tempResult); + finalResult.m_degenerate = true; + return false; + } + + if (!pointOutsideABC && !pointOutsideACD && !pointOutsideADB && !pointOutsideBDC) + { + return false; + } + + b3Scalar bestSqDist = FLT_MAX; + // If point outside face abc then compute closest point on abc + if (pointOutsideABC) + { + closestPtPointTriangle(p, a, b, c, tempResult); b3Vector3 q = tempResult.m_closestPointOnSimplex; - - b3Scalar sqDist = (q - p).dot( q - p); - // Update best closest point if (squared) distance is less than current best - if (sqDist < bestSqDist) { + + b3Scalar sqDist = (q - p).dot(q - p); + // Update best closest point if (squared) distance is less than current best + if (sqDist < bestSqDist) + { bestSqDist = sqDist; finalResult.m_closestPointOnSimplex = q; //convert result bitmask! @@ -501,25 +478,22 @@ bool b3VoronoiSimplexSolver::closestPtPointTetrahedron(const b3Vector3& p, const finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexB; finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexC; finalResult.setBarycentricCoordinates( - tempResult.m_barycentricCoords[VERTA], - tempResult.m_barycentricCoords[VERTB], - tempResult.m_barycentricCoords[VERTC], - 0 - ); - + tempResult.m_barycentricCoords[VERTA], + tempResult.m_barycentricCoords[VERTB], + tempResult.m_barycentricCoords[VERTC], + 0); } - } - + } // Repeat test for face acd - if (pointOutsideACD) + if (pointOutsideACD) { - closestPtPointTriangle(p, a, c, d,tempResult); + closestPtPointTriangle(p, a, c, d, tempResult); b3Vector3 q = tempResult.m_closestPointOnSimplex; //convert result bitmask! - b3Scalar sqDist = (q - p).dot( q - p); - if (sqDist < bestSqDist) + b3Scalar sqDist = (q - p).dot(q - p); + if (sqDist < bestSqDist) { bestSqDist = sqDist; finalResult.m_closestPointOnSimplex = q; @@ -529,52 +503,46 @@ bool b3VoronoiSimplexSolver::closestPtPointTetrahedron(const b3Vector3& p, const finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexB; finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexC; finalResult.setBarycentricCoordinates( - tempResult.m_barycentricCoords[VERTA], - 0, - tempResult.m_barycentricCoords[VERTB], - tempResult.m_barycentricCoords[VERTC] - ); - + tempResult.m_barycentricCoords[VERTA], + 0, + tempResult.m_barycentricCoords[VERTB], + tempResult.m_barycentricCoords[VERTC]); } - } - // Repeat test for face adb + } + // Repeat test for face adb - if (pointOutsideADB) { - closestPtPointTriangle(p, a, d, b,tempResult); + closestPtPointTriangle(p, a, d, b, tempResult); b3Vector3 q = tempResult.m_closestPointOnSimplex; //convert result bitmask! - b3Scalar sqDist = (q - p).dot( q - p); - if (sqDist < bestSqDist) + b3Scalar sqDist = (q - p).dot(q - p); + if (sqDist < bestSqDist) { bestSqDist = sqDist; finalResult.m_closestPointOnSimplex = q; finalResult.m_usedVertices.reset(); finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA; finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexC; - + finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexB; finalResult.setBarycentricCoordinates( - tempResult.m_barycentricCoords[VERTA], - tempResult.m_barycentricCoords[VERTC], - 0, - tempResult.m_barycentricCoords[VERTB] - ); - + tempResult.m_barycentricCoords[VERTA], + tempResult.m_barycentricCoords[VERTC], + 0, + tempResult.m_barycentricCoords[VERTB]); } - } - // Repeat test for face bdc - + } + // Repeat test for face bdc if (pointOutsideBDC) { - closestPtPointTriangle(p, b, d, c,tempResult); + closestPtPointTriangle(p, b, d, c, tempResult); b3Vector3 q = tempResult.m_closestPointOnSimplex; //convert result bitmask! - b3Scalar sqDist = (q - p).dot( q - p); - if (sqDist < bestSqDist) + b3Scalar sqDist = (q - p).dot(q - p); + if (sqDist < bestSqDist) { bestSqDist = sqDist; finalResult.m_closestPointOnSimplex = q; @@ -585,25 +553,22 @@ bool b3VoronoiSimplexSolver::closestPtPointTetrahedron(const b3Vector3& p, const finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexB; finalResult.setBarycentricCoordinates( - 0, - tempResult.m_barycentricCoords[VERTA], - tempResult.m_barycentricCoords[VERTC], - tempResult.m_barycentricCoords[VERTB] - ); - + 0, + tempResult.m_barycentricCoords[VERTA], + tempResult.m_barycentricCoords[VERTC], + tempResult.m_barycentricCoords[VERTB]); } - } + } //help! we ended up full ! - + if (finalResult.m_usedVertices.usedVertexA && finalResult.m_usedVertices.usedVertexB && finalResult.m_usedVertices.usedVertexC && - finalResult.m_usedVertices.usedVertexD) + finalResult.m_usedVertices.usedVertexD) { return true; } - return true; + return true; } - diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/b3VoronoiSimplexSolver.h b/src/Bullet3OpenCL/NarrowphaseCollision/b3VoronoiSimplexSolver.h index a6e27667d..b40b16997 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/b3VoronoiSimplexSolver.h +++ b/src/Bullet3OpenCL/NarrowphaseCollision/b3VoronoiSimplexSolver.h @@ -13,22 +13,19 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #ifndef B3_VORONOI_SIMPLEX_SOLVER_H #define B3_VORONOI_SIMPLEX_SOLVER_H #include "Bullet3Common/b3Vector3.h" - #define VORONOI_SIMPLEX_MAX_VERTS 5 ///disable next define, or use defaultCollisionConfiguration->getSimplexSolver()->setEqualVertexThreshold(0.f) to disable/configure //#define BT_USE_EQUAL_VERTEX_THRESHOLD #define VORONOI_DEFAULT_EQUAL_VERTEX_THRESHOLD 0.0001f - -struct b3UsageBitfield{ +struct b3UsageBitfield +{ b3UsageBitfield() { reset(); @@ -41,137 +38,127 @@ struct b3UsageBitfield{ usedVertexC = false; usedVertexD = false; } - unsigned short usedVertexA : 1; - unsigned short usedVertexB : 1; - unsigned short usedVertexC : 1; - unsigned short usedVertexD : 1; - unsigned short unused1 : 1; - unsigned short unused2 : 1; - unsigned short unused3 : 1; - unsigned short unused4 : 1; + unsigned short usedVertexA : 1; + unsigned short usedVertexB : 1; + unsigned short usedVertexC : 1; + unsigned short usedVertexD : 1; + unsigned short unused1 : 1; + unsigned short unused2 : 1; + unsigned short unused3 : 1; + unsigned short unused4 : 1; }; - -struct b3SubSimplexClosestResult +struct b3SubSimplexClosestResult { - b3Vector3 m_closestPointOnSimplex; + b3Vector3 m_closestPointOnSimplex; //MASK for m_usedVertices - //stores the simplex vertex-usage, using the MASK, + //stores the simplex vertex-usage, using the MASK, // if m_usedVertices & MASK then the related vertex is used - b3UsageBitfield m_usedVertices; - b3Scalar m_barycentricCoords[4]; + b3UsageBitfield m_usedVertices; + b3Scalar m_barycentricCoords[4]; bool m_degenerate; - void reset() + void reset() { m_degenerate = false; setBarycentricCoordinates(); m_usedVertices.reset(); } - bool isValid() + bool isValid() { bool valid = (m_barycentricCoords[0] >= b3Scalar(0.)) && - (m_barycentricCoords[1] >= b3Scalar(0.)) && - (m_barycentricCoords[2] >= b3Scalar(0.)) && - (m_barycentricCoords[3] >= b3Scalar(0.)); - + (m_barycentricCoords[1] >= b3Scalar(0.)) && + (m_barycentricCoords[2] >= b3Scalar(0.)) && + (m_barycentricCoords[3] >= b3Scalar(0.)); return valid; } - void setBarycentricCoordinates(b3Scalar a=b3Scalar(0.),b3Scalar b=b3Scalar(0.),b3Scalar c=b3Scalar(0.),b3Scalar d=b3Scalar(0.)) + void setBarycentricCoordinates(b3Scalar a = b3Scalar(0.), b3Scalar b = b3Scalar(0.), b3Scalar c = b3Scalar(0.), b3Scalar d = b3Scalar(0.)) { m_barycentricCoords[0] = a; m_barycentricCoords[1] = b; m_barycentricCoords[2] = c; m_barycentricCoords[3] = d; } - }; /// b3VoronoiSimplexSolver is an implementation of the closest point distance algorithm from a 1-4 points simplex to the origin. /// Can be used with GJK, as an alternative to Johnson distance algorithm. -B3_ATTRIBUTE_ALIGNED16(class) b3VoronoiSimplexSolver +B3_ATTRIBUTE_ALIGNED16(class) +b3VoronoiSimplexSolver { public: - B3_DECLARE_ALIGNED_ALLOCATOR(); - int m_numVertices; + int m_numVertices; - b3Vector3 m_simplexVectorW[VORONOI_SIMPLEX_MAX_VERTS]; - b3Vector3 m_simplexPointsP[VORONOI_SIMPLEX_MAX_VERTS]; - b3Vector3 m_simplexPointsQ[VORONOI_SIMPLEX_MAX_VERTS]; + b3Vector3 m_simplexVectorW[VORONOI_SIMPLEX_MAX_VERTS]; + b3Vector3 m_simplexPointsP[VORONOI_SIMPLEX_MAX_VERTS]; + b3Vector3 m_simplexPointsQ[VORONOI_SIMPLEX_MAX_VERTS]; - - - b3Vector3 m_cachedP1; - b3Vector3 m_cachedP2; - b3Vector3 m_cachedV; - b3Vector3 m_lastW; - - b3Scalar m_equalVertexThreshold; - bool m_cachedValidClosest; + b3Vector3 m_cachedP1; + b3Vector3 m_cachedP2; + b3Vector3 m_cachedV; + b3Vector3 m_lastW; + b3Scalar m_equalVertexThreshold; + bool m_cachedValidClosest; b3SubSimplexClosestResult m_cachedBC; - bool m_needsUpdate; - - void removeVertex(int index); - void reduceVertices (const b3UsageBitfield& usedVerts); - bool updateClosestVectorAndPoints(); + bool m_needsUpdate; - bool closestPtPointTetrahedron(const b3Vector3& p, const b3Vector3& a, const b3Vector3& b, const b3Vector3& c, const b3Vector3& d, b3SubSimplexClosestResult& finalResult); - int pointOutsideOfPlane(const b3Vector3& p, const b3Vector3& a, const b3Vector3& b, const b3Vector3& c, const b3Vector3& d); - bool closestPtPointTriangle(const b3Vector3& p, const b3Vector3& a, const b3Vector3& b, const b3Vector3& c,b3SubSimplexClosestResult& result); + void removeVertex(int index); + void reduceVertices(const b3UsageBitfield& usedVerts); + bool updateClosestVectorAndPoints(); + + bool closestPtPointTetrahedron(const b3Vector3& p, const b3Vector3& a, const b3Vector3& b, const b3Vector3& c, const b3Vector3& d, b3SubSimplexClosestResult& finalResult); + int pointOutsideOfPlane(const b3Vector3& p, const b3Vector3& a, const b3Vector3& b, const b3Vector3& c, const b3Vector3& d); + bool closestPtPointTriangle(const b3Vector3& p, const b3Vector3& a, const b3Vector3& b, const b3Vector3& c, b3SubSimplexClosestResult& result); public: - b3VoronoiSimplexSolver() - : m_equalVertexThreshold(VORONOI_DEFAULT_EQUAL_VERTEX_THRESHOLD) + : m_equalVertexThreshold(VORONOI_DEFAULT_EQUAL_VERTEX_THRESHOLD) { } - void reset(); + void reset(); - void addVertex(const b3Vector3& w, const b3Vector3& p, const b3Vector3& q); + void addVertex(const b3Vector3& w, const b3Vector3& p, const b3Vector3& q); - void setEqualVertexThreshold(b3Scalar threshold) - { - m_equalVertexThreshold = threshold; - } + void setEqualVertexThreshold(b3Scalar threshold) + { + m_equalVertexThreshold = threshold; + } - b3Scalar getEqualVertexThreshold() const - { - return m_equalVertexThreshold; - } + b3Scalar getEqualVertexThreshold() const + { + return m_equalVertexThreshold; + } - bool closest(b3Vector3& v); + bool closest(b3Vector3 & v); - b3Scalar maxVertex(); + b3Scalar maxVertex(); - bool fullSimplex() const - { - return (m_numVertices == 4); - } + bool fullSimplex() const + { + return (m_numVertices == 4); + } - int getSimplex(b3Vector3 *pBuf, b3Vector3 *qBuf, b3Vector3 *yBuf) const; + int getSimplex(b3Vector3 * pBuf, b3Vector3 * qBuf, b3Vector3 * yBuf) const; - bool inSimplex(const b3Vector3& w); - - void backup_closest(b3Vector3& v) ; + bool inSimplex(const b3Vector3& w); - bool emptySimplex() const ; + void backup_closest(b3Vector3 & v); - void compute_points(b3Vector3& p1, b3Vector3& p2) ; - - int numVertices() const - { - return m_numVertices; - } + bool emptySimplex() const; + void compute_points(b3Vector3 & p1, b3Vector3 & p2); + int numVertices() const + { + return m_numVertices; + } }; -#endif //B3_VORONOI_SIMPLEX_SOLVER_H - +#endif //B3_VORONOI_SIMPLEX_SOLVER_H diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/kernels/bvhTraversal.h b/src/Bullet3OpenCL/NarrowphaseCollision/kernels/bvhTraversal.h index 4b3b49eae..f1df8a697 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/kernels/bvhTraversal.h +++ b/src/Bullet3OpenCL/NarrowphaseCollision/kernels/bvhTraversal.h @@ -1,258 +1,257 @@ //this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project -static const char* bvhTraversalKernelCL= \ -"//keep this enum in sync with the CPU version (in btCollidable.h)\n" -"//written by Erwin Coumans\n" -"#define SHAPE_CONVEX_HULL 3\n" -"#define SHAPE_CONCAVE_TRIMESH 5\n" -"#define TRIANGLE_NUM_CONVEX_FACES 5\n" -"#define SHAPE_COMPOUND_OF_CONVEX_HULLS 6\n" -"#define SHAPE_SPHERE 7\n" -"typedef unsigned int u32;\n" -"#define MAX_NUM_PARTS_IN_BITS 10\n" -"///btQuantizedBvhNode is a compressed aabb node, 16 bytes.\n" -"///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range).\n" -"typedef struct\n" -"{\n" -" //12 bytes\n" -" unsigned short int m_quantizedAabbMin[3];\n" -" unsigned short int m_quantizedAabbMax[3];\n" -" //4 bytes\n" -" int m_escapeIndexOrTriangleIndex;\n" -"} btQuantizedBvhNode;\n" -"typedef struct\n" -"{\n" -" float4 m_aabbMin;\n" -" float4 m_aabbMax;\n" -" float4 m_quantization;\n" -" int m_numNodes;\n" -" int m_numSubTrees;\n" -" int m_nodeOffset;\n" -" int m_subTreeOffset;\n" -"} b3BvhInfo;\n" -"int getTriangleIndex(const btQuantizedBvhNode* rootNode)\n" -"{\n" -" unsigned int x=0;\n" -" unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS);\n" -" // Get only the lower bits where the triangle index is stored\n" -" return (rootNode->m_escapeIndexOrTriangleIndex&~(y));\n" -"}\n" -"int isLeaf(const btQuantizedBvhNode* rootNode)\n" -"{\n" -" //skipindex is negative (internal node), triangleindex >=0 (leafnode)\n" -" return (rootNode->m_escapeIndexOrTriangleIndex >= 0)? 1 : 0;\n" -"}\n" -" \n" -"int getEscapeIndex(const btQuantizedBvhNode* rootNode)\n" -"{\n" -" return -rootNode->m_escapeIndexOrTriangleIndex;\n" -"}\n" -"typedef struct\n" -"{\n" -" //12 bytes\n" -" unsigned short int m_quantizedAabbMin[3];\n" -" unsigned short int m_quantizedAabbMax[3];\n" -" //4 bytes, points to the root of the subtree\n" -" int m_rootNodeIndex;\n" -" //4 bytes\n" -" int m_subtreeSize;\n" -" int m_padding[3];\n" -"} btBvhSubtreeInfo;\n" -"///keep this in sync with btCollidable.h\n" -"typedef struct\n" -"{\n" -" int m_numChildShapes;\n" -" int blaat2;\n" -" int m_shapeType;\n" -" int m_shapeIndex;\n" -" \n" -"} btCollidableGpu;\n" -"typedef struct\n" -"{\n" -" float4 m_childPosition;\n" -" float4 m_childOrientation;\n" -" int m_shapeIndex;\n" -" int m_unused0;\n" -" int m_unused1;\n" -" int m_unused2;\n" -"} btGpuChildShape;\n" -"typedef struct\n" -"{\n" -" float4 m_pos;\n" -" float4 m_quat;\n" -" float4 m_linVel;\n" -" float4 m_angVel;\n" -" u32 m_collidableIdx;\n" -" float m_invMass;\n" -" float m_restituitionCoeff;\n" -" float m_frictionCoeff;\n" -"} BodyData;\n" -"typedef struct \n" -"{\n" -" union\n" -" {\n" -" float4 m_min;\n" -" float m_minElems[4];\n" -" int m_minIndices[4];\n" -" };\n" -" union\n" -" {\n" -" float4 m_max;\n" -" float m_maxElems[4];\n" -" int m_maxIndices[4];\n" -" };\n" -"} btAabbCL;\n" -"int testQuantizedAabbAgainstQuantizedAabb(\n" -" const unsigned short int* aabbMin1,\n" -" const unsigned short int* aabbMax1,\n" -" const unsigned short int* aabbMin2,\n" -" const unsigned short int* aabbMax2)\n" -"{\n" -" //int overlap = 1;\n" -" if (aabbMin1[0] > aabbMax2[0])\n" -" return 0;\n" -" if (aabbMax1[0] < aabbMin2[0])\n" -" return 0;\n" -" if (aabbMin1[1] > aabbMax2[1])\n" -" return 0;\n" -" if (aabbMax1[1] < aabbMin2[1])\n" -" return 0;\n" -" if (aabbMin1[2] > aabbMax2[2])\n" -" return 0;\n" -" if (aabbMax1[2] < aabbMin2[2])\n" -" return 0;\n" -" return 1;\n" -" //overlap = ((aabbMin1[0] > aabbMax2[0]) || (aabbMax1[0] < aabbMin2[0])) ? 0 : overlap;\n" -" //overlap = ((aabbMin1[2] > aabbMax2[2]) || (aabbMax1[2] < aabbMin2[2])) ? 0 : overlap;\n" -" //overlap = ((aabbMin1[1] > aabbMax2[1]) || (aabbMax1[1] < aabbMin2[1])) ? 0 : overlap;\n" -" //return overlap;\n" -"}\n" -"void quantizeWithClamp(unsigned short* out, float4 point2,int isMax, float4 bvhAabbMin, float4 bvhAabbMax, float4 bvhQuantization)\n" -"{\n" -" float4 clampedPoint = max(point2,bvhAabbMin);\n" -" clampedPoint = min (clampedPoint, bvhAabbMax);\n" -" float4 v = (clampedPoint - bvhAabbMin) * bvhQuantization;\n" -" if (isMax)\n" -" {\n" -" out[0] = (unsigned short) (((unsigned short)(v.x+1.f) | 1));\n" -" out[1] = (unsigned short) (((unsigned short)(v.y+1.f) | 1));\n" -" out[2] = (unsigned short) (((unsigned short)(v.z+1.f) | 1));\n" -" } else\n" -" {\n" -" out[0] = (unsigned short) (((unsigned short)(v.x) & 0xfffe));\n" -" out[1] = (unsigned short) (((unsigned short)(v.y) & 0xfffe));\n" -" out[2] = (unsigned short) (((unsigned short)(v.z) & 0xfffe));\n" -" }\n" -"}\n" -"// work-in-progress\n" -"__kernel void bvhTraversalKernel( __global const int4* pairs, \n" -" __global const BodyData* rigidBodies, \n" -" __global const btCollidableGpu* collidables,\n" -" __global btAabbCL* aabbs,\n" -" __global int4* concavePairsOut,\n" -" __global volatile int* numConcavePairsOut,\n" -" __global const btBvhSubtreeInfo* subtreeHeadersRoot,\n" -" __global const btQuantizedBvhNode* quantizedNodesRoot,\n" -" __global const b3BvhInfo* bvhInfos,\n" -" int numPairs,\n" -" int maxNumConcavePairsCapacity)\n" -"{\n" -" int id = get_global_id(0);\n" -" if (id>=numPairs)\n" -" return;\n" -" \n" -" int bodyIndexA = pairs[id].x;\n" -" int bodyIndexB = pairs[id].y;\n" -" int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;\n" -" int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;\n" -" \n" -" //once the broadphase avoids static-static pairs, we can remove this test\n" -" if ((rigidBodies[bodyIndexA].m_invMass==0) &&(rigidBodies[bodyIndexB].m_invMass==0))\n" -" {\n" -" return;\n" -" }\n" -" \n" -" if (collidables[collidableIndexA].m_shapeType!=SHAPE_CONCAVE_TRIMESH)\n" -" return;\n" -" int shapeTypeB = collidables[collidableIndexB].m_shapeType;\n" -" \n" -" if (shapeTypeB!=SHAPE_CONVEX_HULL &&\n" -" shapeTypeB!=SHAPE_SPHERE &&\n" -" shapeTypeB!=SHAPE_COMPOUND_OF_CONVEX_HULLS\n" -" )\n" -" return;\n" -" b3BvhInfo bvhInfo = bvhInfos[collidables[collidableIndexA].m_numChildShapes];\n" -" float4 bvhAabbMin = bvhInfo.m_aabbMin;\n" -" float4 bvhAabbMax = bvhInfo.m_aabbMax;\n" -" float4 bvhQuantization = bvhInfo.m_quantization;\n" -" int numSubtreeHeaders = bvhInfo.m_numSubTrees;\n" -" __global const btBvhSubtreeInfo* subtreeHeaders = &subtreeHeadersRoot[bvhInfo.m_subTreeOffset];\n" -" __global const btQuantizedBvhNode* quantizedNodes = &quantizedNodesRoot[bvhInfo.m_nodeOffset];\n" -" \n" -" unsigned short int quantizedQueryAabbMin[3];\n" -" unsigned short int quantizedQueryAabbMax[3];\n" -" quantizeWithClamp(quantizedQueryAabbMin,aabbs[bodyIndexB].m_min,false,bvhAabbMin, bvhAabbMax,bvhQuantization);\n" -" quantizeWithClamp(quantizedQueryAabbMax,aabbs[bodyIndexB].m_max,true ,bvhAabbMin, bvhAabbMax,bvhQuantization);\n" -" \n" -" for (int i=0;im_escapeIndexOrTriangleIndex&~(y));\n" + "}\n" + "int isLeaf(const btQuantizedBvhNode* rootNode)\n" + "{\n" + " //skipindex is negative (internal node), triangleindex >=0 (leafnode)\n" + " return (rootNode->m_escapeIndexOrTriangleIndex >= 0)? 1 : 0;\n" + "}\n" + " \n" + "int getEscapeIndex(const btQuantizedBvhNode* rootNode)\n" + "{\n" + " return -rootNode->m_escapeIndexOrTriangleIndex;\n" + "}\n" + "typedef struct\n" + "{\n" + " //12 bytes\n" + " unsigned short int m_quantizedAabbMin[3];\n" + " unsigned short int m_quantizedAabbMax[3];\n" + " //4 bytes, points to the root of the subtree\n" + " int m_rootNodeIndex;\n" + " //4 bytes\n" + " int m_subtreeSize;\n" + " int m_padding[3];\n" + "} btBvhSubtreeInfo;\n" + "///keep this in sync with btCollidable.h\n" + "typedef struct\n" + "{\n" + " int m_numChildShapes;\n" + " int blaat2;\n" + " int m_shapeType;\n" + " int m_shapeIndex;\n" + " \n" + "} btCollidableGpu;\n" + "typedef struct\n" + "{\n" + " float4 m_childPosition;\n" + " float4 m_childOrientation;\n" + " int m_shapeIndex;\n" + " int m_unused0;\n" + " int m_unused1;\n" + " int m_unused2;\n" + "} btGpuChildShape;\n" + "typedef struct\n" + "{\n" + " float4 m_pos;\n" + " float4 m_quat;\n" + " float4 m_linVel;\n" + " float4 m_angVel;\n" + " u32 m_collidableIdx;\n" + " float m_invMass;\n" + " float m_restituitionCoeff;\n" + " float m_frictionCoeff;\n" + "} BodyData;\n" + "typedef struct \n" + "{\n" + " union\n" + " {\n" + " float4 m_min;\n" + " float m_minElems[4];\n" + " int m_minIndices[4];\n" + " };\n" + " union\n" + " {\n" + " float4 m_max;\n" + " float m_maxElems[4];\n" + " int m_maxIndices[4];\n" + " };\n" + "} btAabbCL;\n" + "int testQuantizedAabbAgainstQuantizedAabb(\n" + " const unsigned short int* aabbMin1,\n" + " const unsigned short int* aabbMax1,\n" + " const unsigned short int* aabbMin2,\n" + " const unsigned short int* aabbMax2)\n" + "{\n" + " //int overlap = 1;\n" + " if (aabbMin1[0] > aabbMax2[0])\n" + " return 0;\n" + " if (aabbMax1[0] < aabbMin2[0])\n" + " return 0;\n" + " if (aabbMin1[1] > aabbMax2[1])\n" + " return 0;\n" + " if (aabbMax1[1] < aabbMin2[1])\n" + " return 0;\n" + " if (aabbMin1[2] > aabbMax2[2])\n" + " return 0;\n" + " if (aabbMax1[2] < aabbMin2[2])\n" + " return 0;\n" + " return 1;\n" + " //overlap = ((aabbMin1[0] > aabbMax2[0]) || (aabbMax1[0] < aabbMin2[0])) ? 0 : overlap;\n" + " //overlap = ((aabbMin1[2] > aabbMax2[2]) || (aabbMax1[2] < aabbMin2[2])) ? 0 : overlap;\n" + " //overlap = ((aabbMin1[1] > aabbMax2[1]) || (aabbMax1[1] < aabbMin2[1])) ? 0 : overlap;\n" + " //return overlap;\n" + "}\n" + "void quantizeWithClamp(unsigned short* out, float4 point2,int isMax, float4 bvhAabbMin, float4 bvhAabbMax, float4 bvhQuantization)\n" + "{\n" + " float4 clampedPoint = max(point2,bvhAabbMin);\n" + " clampedPoint = min (clampedPoint, bvhAabbMax);\n" + " float4 v = (clampedPoint - bvhAabbMin) * bvhQuantization;\n" + " if (isMax)\n" + " {\n" + " out[0] = (unsigned short) (((unsigned short)(v.x+1.f) | 1));\n" + " out[1] = (unsigned short) (((unsigned short)(v.y+1.f) | 1));\n" + " out[2] = (unsigned short) (((unsigned short)(v.z+1.f) | 1));\n" + " } else\n" + " {\n" + " out[0] = (unsigned short) (((unsigned short)(v.x) & 0xfffe));\n" + " out[1] = (unsigned short) (((unsigned short)(v.y) & 0xfffe));\n" + " out[2] = (unsigned short) (((unsigned short)(v.z) & 0xfffe));\n" + " }\n" + "}\n" + "// work-in-progress\n" + "__kernel void bvhTraversalKernel( __global const int4* pairs, \n" + " __global const BodyData* rigidBodies, \n" + " __global const btCollidableGpu* collidables,\n" + " __global btAabbCL* aabbs,\n" + " __global int4* concavePairsOut,\n" + " __global volatile int* numConcavePairsOut,\n" + " __global const btBvhSubtreeInfo* subtreeHeadersRoot,\n" + " __global const btQuantizedBvhNode* quantizedNodesRoot,\n" + " __global const b3BvhInfo* bvhInfos,\n" + " int numPairs,\n" + " int maxNumConcavePairsCapacity)\n" + "{\n" + " int id = get_global_id(0);\n" + " if (id>=numPairs)\n" + " return;\n" + " \n" + " int bodyIndexA = pairs[id].x;\n" + " int bodyIndexB = pairs[id].y;\n" + " int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;\n" + " int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;\n" + " \n" + " //once the broadphase avoids static-static pairs, we can remove this test\n" + " if ((rigidBodies[bodyIndexA].m_invMass==0) &&(rigidBodies[bodyIndexB].m_invMass==0))\n" + " {\n" + " return;\n" + " }\n" + " \n" + " if (collidables[collidableIndexA].m_shapeType!=SHAPE_CONCAVE_TRIMESH)\n" + " return;\n" + " int shapeTypeB = collidables[collidableIndexB].m_shapeType;\n" + " \n" + " if (shapeTypeB!=SHAPE_CONVEX_HULL &&\n" + " shapeTypeB!=SHAPE_SPHERE &&\n" + " shapeTypeB!=SHAPE_COMPOUND_OF_CONVEX_HULLS\n" + " )\n" + " return;\n" + " b3BvhInfo bvhInfo = bvhInfos[collidables[collidableIndexA].m_numChildShapes];\n" + " float4 bvhAabbMin = bvhInfo.m_aabbMin;\n" + " float4 bvhAabbMax = bvhInfo.m_aabbMax;\n" + " float4 bvhQuantization = bvhInfo.m_quantization;\n" + " int numSubtreeHeaders = bvhInfo.m_numSubTrees;\n" + " __global const btBvhSubtreeInfo* subtreeHeaders = &subtreeHeadersRoot[bvhInfo.m_subTreeOffset];\n" + " __global const btQuantizedBvhNode* quantizedNodes = &quantizedNodesRoot[bvhInfo.m_nodeOffset];\n" + " \n" + " unsigned short int quantizedQueryAabbMin[3];\n" + " unsigned short int quantizedQueryAabbMax[3];\n" + " quantizeWithClamp(quantizedQueryAabbMin,aabbs[bodyIndexB].m_min,false,bvhAabbMin, bvhAabbMax,bvhQuantization);\n" + " quantizeWithClamp(quantizedQueryAabbMax,aabbs[bodyIndexB].m_max,true ,bvhAabbMin, bvhAabbMax,bvhQuantization);\n" + " \n" + " for (int i=0;i\n" -" *\n" -" * This file was ported from mpr.c file, part of libccd.\n" -" * The Minkoski Portal Refinement implementation was ported \n" -" * to OpenCL by Erwin Coumans for the Bullet 3 Physics library.\n" -" * at http://github.com/erwincoumans/bullet3\n" -" *\n" -" * Distributed under the OSI-approved BSD License (the \"License\");\n" -" * see .\n" -" * This software is distributed WITHOUT ANY WARRANTY; without even the\n" -" * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" -" * See the License for more information.\n" -" */\n" -"#ifndef B3_MPR_PENETRATION_H\n" -"#define B3_MPR_PENETRATION_H\n" -"#ifndef B3_PLATFORM_DEFINITIONS_H\n" -"#define B3_PLATFORM_DEFINITIONS_H\n" -"struct MyTest\n" -"{\n" -" int bla;\n" -"};\n" -"#ifdef __cplusplus\n" -"#else\n" -"//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n" -"#define B3_LARGE_FLOAT 1e18f\n" -"#define B3_INFINITY 1e18f\n" -"#define b3Assert(a)\n" -"#define b3ConstArray(a) __global const a*\n" -"#define b3AtomicInc atomic_inc\n" -"#define b3AtomicAdd atomic_add\n" -"#define b3Fabs fabs\n" -"#define b3Sqrt native_sqrt\n" -"#define b3Sin native_sin\n" -"#define b3Cos native_cos\n" -"#define B3_STATIC\n" -"#endif\n" -"#endif\n" -"#ifndef B3_FLOAT4_H\n" -"#define B3_FLOAT4_H\n" -"#ifndef B3_PLATFORM_DEFINITIONS_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif\n" -"#endif\n" -"#ifdef __cplusplus\n" -"#else\n" -" typedef float4 b3Float4;\n" -" #define b3Float4ConstArg const b3Float4\n" -" #define b3MakeFloat4 (float4)\n" -" float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" -" {\n" -" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" -" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" -" return dot(a1, b1);\n" -" }\n" -" b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" -" {\n" -" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" -" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" -" return cross(a1, b1);\n" -" }\n" -" #define b3MinFloat4 min\n" -" #define b3MaxFloat4 max\n" -" #define b3Normalized(a) normalize(a)\n" -"#endif \n" -" \n" -"inline bool b3IsAlmostZero(b3Float4ConstArg v)\n" -"{\n" -" if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" -" return false;\n" -" return true;\n" -"}\n" -"inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" -"{\n" -" float maxDot = -B3_INFINITY;\n" -" int i = 0;\n" -" int ptIndex = -1;\n" -" for( i = 0; i < vecLen; i++ )\n" -" {\n" -" float dot = b3Dot3F4(vecArray[i],vec);\n" -" \n" -" if( dot > maxDot )\n" -" {\n" -" maxDot = dot;\n" -" ptIndex = i;\n" -" }\n" -" }\n" -" b3Assert(ptIndex>=0);\n" -" if (ptIndex<0)\n" -" {\n" -" ptIndex = 0;\n" -" }\n" -" *dotOut = maxDot;\n" -" return ptIndex;\n" -"}\n" -"#endif //B3_FLOAT4_H\n" -"#ifndef B3_RIGIDBODY_DATA_H\n" -"#define B3_RIGIDBODY_DATA_H\n" -"#ifndef B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_FLOAT4_H\n" -"#ifndef B3_QUAT_H\n" -"#define B3_QUAT_H\n" -"#ifndef B3_PLATFORM_DEFINITIONS_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif\n" -"#endif\n" -"#ifndef B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -" typedef float4 b3Quat;\n" -" #define b3QuatConstArg const b3Quat\n" -" \n" -" \n" -"inline float4 b3FastNormalize4(float4 v)\n" -"{\n" -" v = (float4)(v.xyz,0.f);\n" -" return fast_normalize(v);\n" -"}\n" -" \n" -"inline b3Quat b3QuatMul(b3Quat a, b3Quat b);\n" -"inline b3Quat b3QuatNormalized(b3QuatConstArg in);\n" -"inline b3Quat b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec);\n" -"inline b3Quat b3QuatInvert(b3QuatConstArg q);\n" -"inline b3Quat b3QuatInverse(b3QuatConstArg q);\n" -"inline b3Quat b3QuatMul(b3QuatConstArg a, b3QuatConstArg b)\n" -"{\n" -" b3Quat ans;\n" -" ans = b3Cross3( a, b );\n" -" ans += a.w*b+b.w*a;\n" -"// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" -" ans.w = a.w*b.w - b3Dot3F4(a, b);\n" -" return ans;\n" -"}\n" -"inline b3Quat b3QuatNormalized(b3QuatConstArg in)\n" -"{\n" -" b3Quat q;\n" -" q=in;\n" -" //return b3FastNormalize4(in);\n" -" float len = native_sqrt(dot(q, q));\n" -" if(len > 0.f)\n" -" {\n" -" q *= 1.f / len;\n" -" }\n" -" else\n" -" {\n" -" q.x = q.y = q.z = 0.f;\n" -" q.w = 1.f;\n" -" }\n" -" return q;\n" -"}\n" -"inline float4 b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" -"{\n" -" b3Quat qInv = b3QuatInvert( q );\n" -" float4 vcpy = vec;\n" -" vcpy.w = 0.f;\n" -" float4 out = b3QuatMul(b3QuatMul(q,vcpy),qInv);\n" -" return out;\n" -"}\n" -"inline b3Quat b3QuatInverse(b3QuatConstArg q)\n" -"{\n" -" return (b3Quat)(-q.xyz, q.w);\n" -"}\n" -"inline b3Quat b3QuatInvert(b3QuatConstArg q)\n" -"{\n" -" return (b3Quat)(-q.xyz, q.w);\n" -"}\n" -"inline float4 b3QuatInvRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" -"{\n" -" return b3QuatRotate( b3QuatInvert( q ), vec );\n" -"}\n" -"inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)\n" -"{\n" -" return b3QuatRotate( orientation, point ) + (translation);\n" -"}\n" -" \n" -"#endif \n" -"#endif //B3_QUAT_H\n" -"#ifndef B3_MAT3x3_H\n" -"#define B3_MAT3x3_H\n" -"#ifndef B3_QUAT_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_QUAT_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"typedef struct\n" -"{\n" -" b3Float4 m_row[3];\n" -"}b3Mat3x3;\n" -"#define b3Mat3x3ConstArg const b3Mat3x3\n" -"#define b3GetRow(m,row) (m.m_row[row])\n" -"inline b3Mat3x3 b3QuatGetRotationMatrix(b3Quat quat)\n" -"{\n" -" b3Float4 quat2 = (b3Float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f);\n" -" b3Mat3x3 out;\n" -" out.m_row[0].x=1-2*quat2.y-2*quat2.z;\n" -" out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z;\n" -" out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y;\n" -" out.m_row[0].w = 0.f;\n" -" out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z;\n" -" out.m_row[1].y=1-2*quat2.x-2*quat2.z;\n" -" out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x;\n" -" out.m_row[1].w = 0.f;\n" -" out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y;\n" -" out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x;\n" -" out.m_row[2].z=1-2*quat2.x-2*quat2.y;\n" -" out.m_row[2].w = 0.f;\n" -" return out;\n" -"}\n" -"inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg matIn)\n" -"{\n" -" b3Mat3x3 out;\n" -" out.m_row[0] = fabs(matIn.m_row[0]);\n" -" out.m_row[1] = fabs(matIn.m_row[1]);\n" -" out.m_row[2] = fabs(matIn.m_row[2]);\n" -" return out;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtZero();\n" -"__inline\n" -"b3Mat3x3 mtIdentity();\n" -"__inline\n" -"b3Mat3x3 mtTranspose(b3Mat3x3 m);\n" -"__inline\n" -"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b);\n" -"__inline\n" -"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b);\n" -"__inline\n" -"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b);\n" -"__inline\n" -"b3Mat3x3 mtZero()\n" -"{\n" -" b3Mat3x3 m;\n" -" m.m_row[0] = (b3Float4)(0.f);\n" -" m.m_row[1] = (b3Float4)(0.f);\n" -" m.m_row[2] = (b3Float4)(0.f);\n" -" return m;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtIdentity()\n" -"{\n" -" b3Mat3x3 m;\n" -" m.m_row[0] = (b3Float4)(1,0,0,0);\n" -" m.m_row[1] = (b3Float4)(0,1,0,0);\n" -" m.m_row[2] = (b3Float4)(0,0,1,0);\n" -" return m;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtTranspose(b3Mat3x3 m)\n" -"{\n" -" b3Mat3x3 out;\n" -" out.m_row[0] = (b3Float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n" -" out.m_row[1] = (b3Float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n" -" out.m_row[2] = (b3Float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n" -" return out;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b)\n" -"{\n" -" b3Mat3x3 transB;\n" -" transB = mtTranspose( b );\n" -" b3Mat3x3 ans;\n" -" // why this doesn't run when 0ing in the for{}\n" -" a.m_row[0].w = 0.f;\n" -" a.m_row[1].w = 0.f;\n" -" a.m_row[2].w = 0.f;\n" -" for(int i=0; i<3; i++)\n" -" {\n" -"// a.m_row[i].w = 0.f;\n" -" ans.m_row[i].x = b3Dot3F4(a.m_row[i],transB.m_row[0]);\n" -" ans.m_row[i].y = b3Dot3F4(a.m_row[i],transB.m_row[1]);\n" -" ans.m_row[i].z = b3Dot3F4(a.m_row[i],transB.m_row[2]);\n" -" ans.m_row[i].w = 0.f;\n" -" }\n" -" return ans;\n" -"}\n" -"__inline\n" -"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b)\n" -"{\n" -" b3Float4 ans;\n" -" ans.x = b3Dot3F4( a.m_row[0], b );\n" -" ans.y = b3Dot3F4( a.m_row[1], b );\n" -" ans.z = b3Dot3F4( a.m_row[2], b );\n" -" ans.w = 0.f;\n" -" return ans;\n" -"}\n" -"__inline\n" -"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b)\n" -"{\n" -" b3Float4 colx = b3MakeFloat4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" -" b3Float4 coly = b3MakeFloat4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" -" b3Float4 colz = b3MakeFloat4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" -" b3Float4 ans;\n" -" ans.x = b3Dot3F4( a, colx );\n" -" ans.y = b3Dot3F4( a, coly );\n" -" ans.z = b3Dot3F4( a, colz );\n" -" return ans;\n" -"}\n" -"#endif\n" -"#endif //B3_MAT3x3_H\n" -"typedef struct b3RigidBodyData b3RigidBodyData_t;\n" -"struct b3RigidBodyData\n" -"{\n" -" b3Float4 m_pos;\n" -" b3Quat m_quat;\n" -" b3Float4 m_linVel;\n" -" b3Float4 m_angVel;\n" -" int m_collidableIdx;\n" -" float m_invMass;\n" -" float m_restituitionCoeff;\n" -" float m_frictionCoeff;\n" -"};\n" -"typedef struct b3InertiaData b3InertiaData_t;\n" -"struct b3InertiaData\n" -"{\n" -" b3Mat3x3 m_invInertiaWorld;\n" -" b3Mat3x3 m_initInvInertia;\n" -"};\n" -"#endif //B3_RIGIDBODY_DATA_H\n" -" \n" -"#ifndef B3_CONVEX_POLYHEDRON_DATA_H\n" -"#define B3_CONVEX_POLYHEDRON_DATA_H\n" -"#ifndef B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_FLOAT4_H\n" -"#ifndef B3_QUAT_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_QUAT_H\n" -"typedef struct b3GpuFace b3GpuFace_t;\n" -"struct b3GpuFace\n" -"{\n" -" b3Float4 m_plane;\n" -" int m_indexOffset;\n" -" int m_numIndices;\n" -" int m_unusedPadding1;\n" -" int m_unusedPadding2;\n" -"};\n" -"typedef struct b3ConvexPolyhedronData b3ConvexPolyhedronData_t;\n" -"struct b3ConvexPolyhedronData\n" -"{\n" -" b3Float4 m_localCenter;\n" -" b3Float4 m_extents;\n" -" b3Float4 mC;\n" -" b3Float4 mE;\n" -" float m_radius;\n" -" int m_faceOffset;\n" -" int m_numFaces;\n" -" int m_numVertices;\n" -" int m_vertexOffset;\n" -" int m_uniqueEdgesOffset;\n" -" int m_numUniqueEdges;\n" -" int m_unused;\n" -"};\n" -"#endif //B3_CONVEX_POLYHEDRON_DATA_H\n" -"#ifndef B3_COLLIDABLE_H\n" -"#define B3_COLLIDABLE_H\n" -"#ifndef B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_FLOAT4_H\n" -"#ifndef B3_QUAT_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_QUAT_H\n" -"enum b3ShapeTypes\n" -"{\n" -" SHAPE_HEIGHT_FIELD=1,\n" -" SHAPE_CONVEX_HULL=3,\n" -" SHAPE_PLANE=4,\n" -" SHAPE_CONCAVE_TRIMESH=5,\n" -" SHAPE_COMPOUND_OF_CONVEX_HULLS=6,\n" -" SHAPE_SPHERE=7,\n" -" MAX_NUM_SHAPE_TYPES,\n" -"};\n" -"typedef struct b3Collidable b3Collidable_t;\n" -"struct b3Collidable\n" -"{\n" -" union {\n" -" int m_numChildShapes;\n" -" int m_bvhIndex;\n" -" };\n" -" union\n" -" {\n" -" float m_radius;\n" -" int m_compoundBvhIndex;\n" -" };\n" -" int m_shapeType;\n" -" int m_shapeIndex;\n" -"};\n" -"typedef struct b3GpuChildShape b3GpuChildShape_t;\n" -"struct b3GpuChildShape\n" -"{\n" -" b3Float4 m_childPosition;\n" -" b3Quat m_childOrientation;\n" -" int m_shapeIndex;\n" -" int m_unused0;\n" -" int m_unused1;\n" -" int m_unused2;\n" -"};\n" -"struct b3CompoundOverlappingPair\n" -"{\n" -" int m_bodyIndexA;\n" -" int m_bodyIndexB;\n" -"// int m_pairType;\n" -" int m_childShapeIndexA;\n" -" int m_childShapeIndexB;\n" -"};\n" -"#endif //B3_COLLIDABLE_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#define B3_MPR_SQRT sqrt\n" -"#endif\n" -"#define B3_MPR_FMIN(x, y) ((x) < (y) ? (x) : (y))\n" -"#define B3_MPR_FABS fabs\n" -"#define B3_MPR_TOLERANCE 1E-6f\n" -"#define B3_MPR_MAX_ITERATIONS 1000\n" -"struct _b3MprSupport_t \n" -"{\n" -" b3Float4 v; //!< Support point in minkowski sum\n" -" b3Float4 v1; //!< Support point in obj1\n" -" b3Float4 v2; //!< Support point in obj2\n" -"};\n" -"typedef struct _b3MprSupport_t b3MprSupport_t;\n" -"struct _b3MprSimplex_t \n" -"{\n" -" b3MprSupport_t ps[4];\n" -" int last; //!< index of last added point\n" -"};\n" -"typedef struct _b3MprSimplex_t b3MprSimplex_t;\n" -"inline b3MprSupport_t* b3MprSimplexPointW(b3MprSimplex_t *s, int idx)\n" -"{\n" -" return &s->ps[idx];\n" -"}\n" -"inline void b3MprSimplexSetSize(b3MprSimplex_t *s, int size)\n" -"{\n" -" s->last = size - 1;\n" -"}\n" -"inline int b3MprSimplexSize(const b3MprSimplex_t *s)\n" -"{\n" -" return s->last + 1;\n" -"}\n" -"inline const b3MprSupport_t* b3MprSimplexPoint(const b3MprSimplex_t* s, int idx)\n" -"{\n" -" // here is no check on boundaries\n" -" return &s->ps[idx];\n" -"}\n" -"inline void b3MprSupportCopy(b3MprSupport_t *d, const b3MprSupport_t *s)\n" -"{\n" -" *d = *s;\n" -"}\n" -"inline void b3MprSimplexSet(b3MprSimplex_t *s, size_t pos, const b3MprSupport_t *a)\n" -"{\n" -" b3MprSupportCopy(s->ps + pos, a);\n" -"}\n" -"inline void b3MprSimplexSwap(b3MprSimplex_t *s, size_t pos1, size_t pos2)\n" -"{\n" -" b3MprSupport_t supp;\n" -" b3MprSupportCopy(&supp, &s->ps[pos1]);\n" -" b3MprSupportCopy(&s->ps[pos1], &s->ps[pos2]);\n" -" b3MprSupportCopy(&s->ps[pos2], &supp);\n" -"}\n" -"inline int b3MprIsZero(float val)\n" -"{\n" -" return B3_MPR_FABS(val) < FLT_EPSILON;\n" -"}\n" -"inline int b3MprEq(float _a, float _b)\n" -"{\n" -" float ab;\n" -" float a, b;\n" -" ab = B3_MPR_FABS(_a - _b);\n" -" if (B3_MPR_FABS(ab) < FLT_EPSILON)\n" -" return 1;\n" -" a = B3_MPR_FABS(_a);\n" -" b = B3_MPR_FABS(_b);\n" -" if (b > a){\n" -" return ab < FLT_EPSILON * b;\n" -" }else{\n" -" return ab < FLT_EPSILON * a;\n" -" }\n" -"}\n" -"inline int b3MprVec3Eq(const b3Float4* a, const b3Float4 *b)\n" -"{\n" -" return b3MprEq((*a).x, (*b).x)\n" -" && b3MprEq((*a).y, (*b).y)\n" -" && b3MprEq((*a).z, (*b).z);\n" -"}\n" -"inline b3Float4 b3LocalGetSupportVertex(b3Float4ConstArg supportVec,__global const b3ConvexPolyhedronData_t* hull, b3ConstArray(b3Float4) verticesA)\n" -"{\n" -" b3Float4 supVec = b3MakeFloat4(0,0,0,0);\n" -" float maxDot = -B3_LARGE_FLOAT;\n" -" if( 0 < hull->m_numVertices )\n" -" {\n" -" const b3Float4 scaled = supportVec;\n" -" int index = b3MaxDot(scaled, &verticesA[hull->m_vertexOffset], hull->m_numVertices, &maxDot);\n" -" return verticesA[hull->m_vertexOffset+index];\n" -" }\n" -" return supVec;\n" -"}\n" -"B3_STATIC void b3MprConvexSupport(int pairIndex,int bodyIndex, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, \n" -" b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, \n" -" b3ConstArray(b3Collidable_t) cpuCollidables,\n" -" b3ConstArray(b3Float4) cpuVertices,\n" -" __global b3Float4* sepAxis,\n" -" const b3Float4* _dir, b3Float4* outp, int logme)\n" -"{\n" -" //dir is in worldspace, move to local space\n" -" \n" -" b3Float4 pos = cpuBodyBuf[bodyIndex].m_pos;\n" -" b3Quat orn = cpuBodyBuf[bodyIndex].m_quat;\n" -" \n" -" b3Float4 dir = b3MakeFloat4((*_dir).x,(*_dir).y,(*_dir).z,0.f);\n" -" \n" -" const b3Float4 localDir = b3QuatRotate(b3QuatInverse(orn),dir);\n" -" \n" -" //find local support vertex\n" -" int colIndex = cpuBodyBuf[bodyIndex].m_collidableIdx;\n" -" \n" -" b3Assert(cpuCollidables[colIndex].m_shapeType==SHAPE_CONVEX_HULL);\n" -" __global const b3ConvexPolyhedronData_t* hull = &cpuConvexData[cpuCollidables[colIndex].m_shapeIndex];\n" -" \n" -" b3Float4 pInA;\n" -" if (logme)\n" -" {\n" -" b3Float4 supVec = b3MakeFloat4(0,0,0,0);\n" -" float maxDot = -B3_LARGE_FLOAT;\n" -" if( 0 < hull->m_numVertices )\n" -" {\n" -" const b3Float4 scaled = localDir;\n" -" int index = b3MaxDot(scaled, &cpuVertices[hull->m_vertexOffset], hull->m_numVertices, &maxDot);\n" -" pInA = cpuVertices[hull->m_vertexOffset+index];\n" -" \n" -" }\n" -" } else\n" -" {\n" -" pInA = b3LocalGetSupportVertex(localDir,hull,cpuVertices);\n" -" }\n" -" //move vertex to world space\n" -" *outp = b3TransformPoint(pInA,pos,orn);\n" -" \n" -"}\n" -"inline void b3MprSupport(int pairIndex,int bodyIndexA, int bodyIndexB, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, \n" -" b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, \n" -" b3ConstArray(b3Collidable_t) cpuCollidables,\n" -" b3ConstArray(b3Float4) cpuVertices,\n" -" __global b3Float4* sepAxis,\n" -" const b3Float4* _dir, b3MprSupport_t *supp)\n" -"{\n" -" b3Float4 dir;\n" -" dir = *_dir;\n" -" b3MprConvexSupport(pairIndex,bodyIndexA,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices,sepAxis,&dir, &supp->v1,0);\n" -" dir = *_dir*-1.f;\n" -" b3MprConvexSupport(pairIndex,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices,sepAxis,&dir, &supp->v2,0);\n" -" supp->v = supp->v1 - supp->v2;\n" -"}\n" -"inline void b3FindOrigin(int bodyIndexA, int bodyIndexB, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, b3MprSupport_t *center)\n" -"{\n" -" center->v1 = cpuBodyBuf[bodyIndexA].m_pos;\n" -" center->v2 = cpuBodyBuf[bodyIndexB].m_pos;\n" -" center->v = center->v1 - center->v2;\n" -"}\n" -"inline void b3MprVec3Set(b3Float4 *v, float x, float y, float z)\n" -"{\n" -" (*v).x = x;\n" -" (*v).y = y;\n" -" (*v).z = z;\n" -" (*v).w = 0.f;\n" -"}\n" -"inline void b3MprVec3Add(b3Float4 *v, const b3Float4 *w)\n" -"{\n" -" (*v).x += (*w).x;\n" -" (*v).y += (*w).y;\n" -" (*v).z += (*w).z;\n" -"}\n" -"inline void b3MprVec3Copy(b3Float4 *v, const b3Float4 *w)\n" -"{\n" -" *v = *w;\n" -"}\n" -"inline void b3MprVec3Scale(b3Float4 *d, float k)\n" -"{\n" -" *d *= k;\n" -"}\n" -"inline float b3MprVec3Dot(const b3Float4 *a, const b3Float4 *b)\n" -"{\n" -" float dot;\n" -" dot = b3Dot3F4(*a,*b);\n" -" return dot;\n" -"}\n" -"inline float b3MprVec3Len2(const b3Float4 *v)\n" -"{\n" -" return b3MprVec3Dot(v, v);\n" -"}\n" -"inline void b3MprVec3Normalize(b3Float4 *d)\n" -"{\n" -" float k = 1.f / B3_MPR_SQRT(b3MprVec3Len2(d));\n" -" b3MprVec3Scale(d, k);\n" -"}\n" -"inline void b3MprVec3Cross(b3Float4 *d, const b3Float4 *a, const b3Float4 *b)\n" -"{\n" -" *d = b3Cross3(*a,*b);\n" -" \n" -"}\n" -"inline void b3MprVec3Sub2(b3Float4 *d, const b3Float4 *v, const b3Float4 *w)\n" -"{\n" -" *d = *v - *w;\n" -"}\n" -"inline void b3PortalDir(const b3MprSimplex_t *portal, b3Float4 *dir)\n" -"{\n" -" b3Float4 v2v1, v3v1;\n" -" b3MprVec3Sub2(&v2v1, &b3MprSimplexPoint(portal, 2)->v,\n" -" &b3MprSimplexPoint(portal, 1)->v);\n" -" b3MprVec3Sub2(&v3v1, &b3MprSimplexPoint(portal, 3)->v,\n" -" &b3MprSimplexPoint(portal, 1)->v);\n" -" b3MprVec3Cross(dir, &v2v1, &v3v1);\n" -" b3MprVec3Normalize(dir);\n" -"}\n" -"inline int portalEncapsulesOrigin(const b3MprSimplex_t *portal,\n" -" const b3Float4 *dir)\n" -"{\n" -" float dot;\n" -" dot = b3MprVec3Dot(dir, &b3MprSimplexPoint(portal, 1)->v);\n" -" return b3MprIsZero(dot) || dot > 0.f;\n" -"}\n" -"inline int portalReachTolerance(const b3MprSimplex_t *portal,\n" -" const b3MprSupport_t *v4,\n" -" const b3Float4 *dir)\n" -"{\n" -" float dv1, dv2, dv3, dv4;\n" -" float dot1, dot2, dot3;\n" -" // find the smallest dot product of dir and {v1-v4, v2-v4, v3-v4}\n" -" dv1 = b3MprVec3Dot(&b3MprSimplexPoint(portal, 1)->v, dir);\n" -" dv2 = b3MprVec3Dot(&b3MprSimplexPoint(portal, 2)->v, dir);\n" -" dv3 = b3MprVec3Dot(&b3MprSimplexPoint(portal, 3)->v, dir);\n" -" dv4 = b3MprVec3Dot(&v4->v, dir);\n" -" dot1 = dv4 - dv1;\n" -" dot2 = dv4 - dv2;\n" -" dot3 = dv4 - dv3;\n" -" dot1 = B3_MPR_FMIN(dot1, dot2);\n" -" dot1 = B3_MPR_FMIN(dot1, dot3);\n" -" return b3MprEq(dot1, B3_MPR_TOLERANCE) || dot1 < B3_MPR_TOLERANCE;\n" -"}\n" -"inline int portalCanEncapsuleOrigin(const b3MprSimplex_t *portal, \n" -" const b3MprSupport_t *v4,\n" -" const b3Float4 *dir)\n" -"{\n" -" float dot;\n" -" dot = b3MprVec3Dot(&v4->v, dir);\n" -" return b3MprIsZero(dot) || dot > 0.f;\n" -"}\n" -"inline void b3ExpandPortal(b3MprSimplex_t *portal,\n" -" const b3MprSupport_t *v4)\n" -"{\n" -" float dot;\n" -" b3Float4 v4v0;\n" -" b3MprVec3Cross(&v4v0, &v4->v, &b3MprSimplexPoint(portal, 0)->v);\n" -" dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 1)->v, &v4v0);\n" -" if (dot > 0.f){\n" -" dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 2)->v, &v4v0);\n" -" if (dot > 0.f){\n" -" b3MprSimplexSet(portal, 1, v4);\n" -" }else{\n" -" b3MprSimplexSet(portal, 3, v4);\n" -" }\n" -" }else{\n" -" dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 3)->v, &v4v0);\n" -" if (dot > 0.f){\n" -" b3MprSimplexSet(portal, 2, v4);\n" -" }else{\n" -" b3MprSimplexSet(portal, 1, v4);\n" -" }\n" -" }\n" -"}\n" -"B3_STATIC int b3DiscoverPortal(int pairIndex, int bodyIndexA, int bodyIndexB, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, \n" -" b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, \n" -" b3ConstArray(b3Collidable_t) cpuCollidables,\n" -" b3ConstArray(b3Float4) cpuVertices,\n" -" __global b3Float4* sepAxis,\n" -" __global int* hasSepAxis,\n" -" b3MprSimplex_t *portal)\n" -"{\n" -" b3Float4 dir, va, vb;\n" -" float dot;\n" -" int cont;\n" -" \n" -" \n" -" // vertex 0 is center of portal\n" -" b3FindOrigin(bodyIndexA,bodyIndexB,cpuBodyBuf, b3MprSimplexPointW(portal, 0));\n" -" // vertex 0 is center of portal\n" -" b3MprSimplexSetSize(portal, 1);\n" -" \n" -" b3Float4 zero = b3MakeFloat4(0,0,0,0);\n" -" b3Float4* b3mpr_vec3_origin = &zero;\n" -" if (b3MprVec3Eq(&b3MprSimplexPoint(portal, 0)->v, b3mpr_vec3_origin)){\n" -" // Portal's center lies on origin (0,0,0) => we know that objects\n" -" // intersect but we would need to know penetration info.\n" -" // So move center little bit...\n" -" b3MprVec3Set(&va, FLT_EPSILON * 10.f, 0.f, 0.f);\n" -" b3MprVec3Add(&b3MprSimplexPointW(portal, 0)->v, &va);\n" -" }\n" -" // vertex 1 = support in direction of origin\n" -" b3MprVec3Copy(&dir, &b3MprSimplexPoint(portal, 0)->v);\n" -" b3MprVec3Scale(&dir, -1.f);\n" -" b3MprVec3Normalize(&dir);\n" -" b3MprSupport(pairIndex,bodyIndexA,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices, sepAxis,&dir, b3MprSimplexPointW(portal, 1));\n" -" b3MprSimplexSetSize(portal, 2);\n" -" // test if origin isn't outside of v1\n" -" dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 1)->v, &dir);\n" -" \n" -" if (b3MprIsZero(dot) || dot < 0.f)\n" -" return -1;\n" -" // vertex 2\n" -" b3MprVec3Cross(&dir, &b3MprSimplexPoint(portal, 0)->v,\n" -" &b3MprSimplexPoint(portal, 1)->v);\n" -" if (b3MprIsZero(b3MprVec3Len2(&dir))){\n" -" if (b3MprVec3Eq(&b3MprSimplexPoint(portal, 1)->v, b3mpr_vec3_origin)){\n" -" // origin lies on v1\n" -" return 1;\n" -" }else{\n" -" // origin lies on v0-v1 segment\n" -" return 2;\n" -" }\n" -" }\n" -" b3MprVec3Normalize(&dir);\n" -" b3MprSupport(pairIndex,bodyIndexA,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices, sepAxis,&dir, b3MprSimplexPointW(portal, 2));\n" -" \n" -" dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 2)->v, &dir);\n" -" if (b3MprIsZero(dot) || dot < 0.f)\n" -" return -1;\n" -" b3MprSimplexSetSize(portal, 3);\n" -" // vertex 3 direction\n" -" b3MprVec3Sub2(&va, &b3MprSimplexPoint(portal, 1)->v,\n" -" &b3MprSimplexPoint(portal, 0)->v);\n" -" b3MprVec3Sub2(&vb, &b3MprSimplexPoint(portal, 2)->v,\n" -" &b3MprSimplexPoint(portal, 0)->v);\n" -" b3MprVec3Cross(&dir, &va, &vb);\n" -" b3MprVec3Normalize(&dir);\n" -" // it is better to form portal faces to be oriented \"outside\" origin\n" -" dot = b3MprVec3Dot(&dir, &b3MprSimplexPoint(portal, 0)->v);\n" -" if (dot > 0.f){\n" -" b3MprSimplexSwap(portal, 1, 2);\n" -" b3MprVec3Scale(&dir, -1.f);\n" -" }\n" -" while (b3MprSimplexSize(portal) < 4){\n" -" b3MprSupport(pairIndex,bodyIndexA,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices, sepAxis,&dir, b3MprSimplexPointW(portal, 3));\n" -" \n" -" dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 3)->v, &dir);\n" -" if (b3MprIsZero(dot) || dot < 0.f)\n" -" return -1;\n" -" cont = 0;\n" -" // test if origin is outside (v1, v0, v3) - set v2 as v3 and\n" -" // continue\n" -" b3MprVec3Cross(&va, &b3MprSimplexPoint(portal, 1)->v,\n" -" &b3MprSimplexPoint(portal, 3)->v);\n" -" dot = b3MprVec3Dot(&va, &b3MprSimplexPoint(portal, 0)->v);\n" -" if (dot < 0.f && !b3MprIsZero(dot)){\n" -" b3MprSimplexSet(portal, 2, b3MprSimplexPoint(portal, 3));\n" -" cont = 1;\n" -" }\n" -" if (!cont){\n" -" // test if origin is outside (v3, v0, v2) - set v1 as v3 and\n" -" // continue\n" -" b3MprVec3Cross(&va, &b3MprSimplexPoint(portal, 3)->v,\n" -" &b3MprSimplexPoint(portal, 2)->v);\n" -" dot = b3MprVec3Dot(&va, &b3MprSimplexPoint(portal, 0)->v);\n" -" if (dot < 0.f && !b3MprIsZero(dot)){\n" -" b3MprSimplexSet(portal, 1, b3MprSimplexPoint(portal, 3));\n" -" cont = 1;\n" -" }\n" -" }\n" -" if (cont){\n" -" b3MprVec3Sub2(&va, &b3MprSimplexPoint(portal, 1)->v,\n" -" &b3MprSimplexPoint(portal, 0)->v);\n" -" b3MprVec3Sub2(&vb, &b3MprSimplexPoint(portal, 2)->v,\n" -" &b3MprSimplexPoint(portal, 0)->v);\n" -" b3MprVec3Cross(&dir, &va, &vb);\n" -" b3MprVec3Normalize(&dir);\n" -" }else{\n" -" b3MprSimplexSetSize(portal, 4);\n" -" }\n" -" }\n" -" return 0;\n" -"}\n" -"B3_STATIC int b3RefinePortal(int pairIndex,int bodyIndexA, int bodyIndexB, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, \n" -" b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, \n" -" b3ConstArray(b3Collidable_t) cpuCollidables,\n" -" b3ConstArray(b3Float4) cpuVertices,\n" -" __global b3Float4* sepAxis,\n" -" b3MprSimplex_t *portal)\n" -"{\n" -" b3Float4 dir;\n" -" b3MprSupport_t v4;\n" -" for (int i=0;iv,\n" -" &b3MprSimplexPoint(portal, 2)->v);\n" -" b[0] = b3MprVec3Dot(&vec, &b3MprSimplexPoint(portal, 3)->v);\n" -" b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 3)->v,\n" -" &b3MprSimplexPoint(portal, 2)->v);\n" -" b[1] = b3MprVec3Dot(&vec, &b3MprSimplexPoint(portal, 0)->v);\n" -" b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 0)->v,\n" -" &b3MprSimplexPoint(portal, 1)->v);\n" -" b[2] = b3MprVec3Dot(&vec, &b3MprSimplexPoint(portal, 3)->v);\n" -" b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 2)->v,\n" -" &b3MprSimplexPoint(portal, 1)->v);\n" -" b[3] = b3MprVec3Dot(&vec, &b3MprSimplexPoint(portal, 0)->v);\n" -" sum = b[0] + b[1] + b[2] + b[3];\n" -" if (b3MprIsZero(sum) || sum < 0.f){\n" -" b[0] = 0.f;\n" -" b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 2)->v,\n" -" &b3MprSimplexPoint(portal, 3)->v);\n" -" b[1] = b3MprVec3Dot(&vec, &dir);\n" -" b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 3)->v,\n" -" &b3MprSimplexPoint(portal, 1)->v);\n" -" b[2] = b3MprVec3Dot(&vec, &dir);\n" -" b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 1)->v,\n" -" &b3MprSimplexPoint(portal, 2)->v);\n" -" b[3] = b3MprVec3Dot(&vec, &dir);\n" -" sum = b[1] + b[2] + b[3];\n" -" }\n" -" inv = 1.f / sum;\n" -" b3MprVec3Copy(&p1, b3mpr_vec3_origin);\n" -" b3MprVec3Copy(&p2, b3mpr_vec3_origin);\n" -" for (i = 0; i < 4; i++){\n" -" b3MprVec3Copy(&vec, &b3MprSimplexPoint(portal, i)->v1);\n" -" b3MprVec3Scale(&vec, b[i]);\n" -" b3MprVec3Add(&p1, &vec);\n" -" b3MprVec3Copy(&vec, &b3MprSimplexPoint(portal, i)->v2);\n" -" b3MprVec3Scale(&vec, b[i]);\n" -" b3MprVec3Add(&p2, &vec);\n" -" }\n" -" b3MprVec3Scale(&p1, inv);\n" -" b3MprVec3Scale(&p2, inv);\n" -" b3MprVec3Copy(pos, &p1);\n" -" b3MprVec3Add(pos, &p2);\n" -" b3MprVec3Scale(pos, 0.5);\n" -"}\n" -"inline float b3MprVec3Dist2(const b3Float4 *a, const b3Float4 *b)\n" -"{\n" -" b3Float4 ab;\n" -" b3MprVec3Sub2(&ab, a, b);\n" -" return b3MprVec3Len2(&ab);\n" -"}\n" -"inline float _b3MprVec3PointSegmentDist2(const b3Float4 *P,\n" -" const b3Float4 *x0,\n" -" const b3Float4 *b,\n" -" b3Float4 *witness)\n" -"{\n" -" // The computation comes from solving equation of segment:\n" -" // S(t) = x0 + t.d\n" -" // where - x0 is initial point of segment\n" -" // - d is direction of segment from x0 (|d| > 0)\n" -" // - t belongs to <0, 1> interval\n" -" // \n" -" // Than, distance from a segment to some point P can be expressed:\n" -" // D(t) = |x0 + t.d - P|^2\n" -" // which is distance from any point on segment. Minimization\n" -" // of this function brings distance from P to segment.\n" -" // Minimization of D(t) leads to simple quadratic equation that's\n" -" // solving is straightforward.\n" -" //\n" -" // Bonus of this method is witness point for free.\n" -" float dist, t;\n" -" b3Float4 d, a;\n" -" // direction of segment\n" -" b3MprVec3Sub2(&d, b, x0);\n" -" // precompute vector from P to x0\n" -" b3MprVec3Sub2(&a, x0, P);\n" -" t = -1.f * b3MprVec3Dot(&a, &d);\n" -" t /= b3MprVec3Len2(&d);\n" -" if (t < 0.f || b3MprIsZero(t)){\n" -" dist = b3MprVec3Dist2(x0, P);\n" -" if (witness)\n" -" b3MprVec3Copy(witness, x0);\n" -" }else if (t > 1.f || b3MprEq(t, 1.f)){\n" -" dist = b3MprVec3Dist2(b, P);\n" -" if (witness)\n" -" b3MprVec3Copy(witness, b);\n" -" }else{\n" -" if (witness){\n" -" b3MprVec3Copy(witness, &d);\n" -" b3MprVec3Scale(witness, t);\n" -" b3MprVec3Add(witness, x0);\n" -" dist = b3MprVec3Dist2(witness, P);\n" -" }else{\n" -" // recycling variables\n" -" b3MprVec3Scale(&d, t);\n" -" b3MprVec3Add(&d, &a);\n" -" dist = b3MprVec3Len2(&d);\n" -" }\n" -" }\n" -" return dist;\n" -"}\n" -"inline float b3MprVec3PointTriDist2(const b3Float4 *P,\n" -" const b3Float4 *x0, const b3Float4 *B,\n" -" const b3Float4 *C,\n" -" b3Float4 *witness)\n" -"{\n" -" // Computation comes from analytic expression for triangle (x0, B, C)\n" -" // T(s, t) = x0 + s.d1 + t.d2, where d1 = B - x0 and d2 = C - x0 and\n" -" // Then equation for distance is:\n" -" // D(s, t) = | T(s, t) - P |^2\n" -" // This leads to minimization of quadratic function of two variables.\n" -" // The solution from is taken only if s is between 0 and 1, t is\n" -" // between 0 and 1 and t + s < 1, otherwise distance from segment is\n" -" // computed.\n" -" b3Float4 d1, d2, a;\n" -" float u, v, w, p, q, r;\n" -" float s, t, dist, dist2;\n" -" b3Float4 witness2;\n" -" b3MprVec3Sub2(&d1, B, x0);\n" -" b3MprVec3Sub2(&d2, C, x0);\n" -" b3MprVec3Sub2(&a, x0, P);\n" -" u = b3MprVec3Dot(&a, &a);\n" -" v = b3MprVec3Dot(&d1, &d1);\n" -" w = b3MprVec3Dot(&d2, &d2);\n" -" p = b3MprVec3Dot(&a, &d1);\n" -" q = b3MprVec3Dot(&a, &d2);\n" -" r = b3MprVec3Dot(&d1, &d2);\n" -" s = (q * r - w * p) / (w * v - r * r);\n" -" t = (-s * r - q) / w;\n" -" if ((b3MprIsZero(s) || s > 0.f)\n" -" && (b3MprEq(s, 1.f) || s < 1.f)\n" -" && (b3MprIsZero(t) || t > 0.f)\n" -" && (b3MprEq(t, 1.f) || t < 1.f)\n" -" && (b3MprEq(t + s, 1.f) || t + s < 1.f)){\n" -" if (witness){\n" -" b3MprVec3Scale(&d1, s);\n" -" b3MprVec3Scale(&d2, t);\n" -" b3MprVec3Copy(witness, x0);\n" -" b3MprVec3Add(witness, &d1);\n" -" b3MprVec3Add(witness, &d2);\n" -" dist = b3MprVec3Dist2(witness, P);\n" -" }else{\n" -" dist = s * s * v;\n" -" dist += t * t * w;\n" -" dist += 2.f * s * t * r;\n" -" dist += 2.f * s * p;\n" -" dist += 2.f * t * q;\n" -" dist += u;\n" -" }\n" -" }else{\n" -" dist = _b3MprVec3PointSegmentDist2(P, x0, B, witness);\n" -" dist2 = _b3MprVec3PointSegmentDist2(P, x0, C, &witness2);\n" -" if (dist2 < dist){\n" -" dist = dist2;\n" -" if (witness)\n" -" b3MprVec3Copy(witness, &witness2);\n" -" }\n" -" dist2 = _b3MprVec3PointSegmentDist2(P, B, C, &witness2);\n" -" if (dist2 < dist){\n" -" dist = dist2;\n" -" if (witness)\n" -" b3MprVec3Copy(witness, &witness2);\n" -" }\n" -" }\n" -" return dist;\n" -"}\n" -"B3_STATIC void b3FindPenetr(int pairIndex,int bodyIndexA, int bodyIndexB, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, \n" -" b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, \n" -" b3ConstArray(b3Collidable_t) cpuCollidables,\n" -" b3ConstArray(b3Float4) cpuVertices,\n" -" __global b3Float4* sepAxis,\n" -" b3MprSimplex_t *portal,\n" -" float *depth, b3Float4 *pdir, b3Float4 *pos)\n" -"{\n" -" b3Float4 dir;\n" -" b3MprSupport_t v4;\n" -" unsigned long iterations;\n" -" b3Float4 zero = b3MakeFloat4(0,0,0,0);\n" -" b3Float4* b3mpr_vec3_origin = &zero;\n" -" iterations = 1UL;\n" -" for (int i=0;i find penetration info\n" -" if (portalReachTolerance(portal, &v4, &dir)\n" -" || iterations ==B3_MPR_MAX_ITERATIONS)\n" -" {\n" -" *depth = b3MprVec3PointTriDist2(b3mpr_vec3_origin,&b3MprSimplexPoint(portal, 1)->v,&b3MprSimplexPoint(portal, 2)->v,&b3MprSimplexPoint(portal, 3)->v,pdir);\n" -" *depth = B3_MPR_SQRT(*depth);\n" -" \n" -" if (b3MprIsZero((*pdir).x) && b3MprIsZero((*pdir).y) && b3MprIsZero((*pdir).z))\n" -" {\n" -" \n" -" *pdir = dir;\n" -" } \n" -" b3MprVec3Normalize(pdir);\n" -" \n" -" // barycentric coordinates:\n" -" b3FindPos(portal, pos);\n" -" return;\n" -" }\n" -" b3ExpandPortal(portal, &v4);\n" -" iterations++;\n" -" }\n" -"}\n" -"B3_STATIC void b3FindPenetrTouch(b3MprSimplex_t *portal,float *depth, b3Float4 *dir, b3Float4 *pos)\n" -"{\n" -" // Touching contact on portal's v1 - so depth is zero and direction\n" -" // is unimportant and pos can be guessed\n" -" *depth = 0.f;\n" -" b3Float4 zero = b3MakeFloat4(0,0,0,0);\n" -" b3Float4* b3mpr_vec3_origin = &zero;\n" -" b3MprVec3Copy(dir, b3mpr_vec3_origin);\n" -" b3MprVec3Copy(pos, &b3MprSimplexPoint(portal, 1)->v1);\n" -" b3MprVec3Add(pos, &b3MprSimplexPoint(portal, 1)->v2);\n" -" b3MprVec3Scale(pos, 0.5);\n" -"}\n" -"B3_STATIC void b3FindPenetrSegment(b3MprSimplex_t *portal,\n" -" float *depth, b3Float4 *dir, b3Float4 *pos)\n" -"{\n" -" \n" -" // Origin lies on v0-v1 segment.\n" -" // Depth is distance to v1, direction also and position must be\n" -" // computed\n" -" b3MprVec3Copy(pos, &b3MprSimplexPoint(portal, 1)->v1);\n" -" b3MprVec3Add(pos, &b3MprSimplexPoint(portal, 1)->v2);\n" -" b3MprVec3Scale(pos, 0.5f);\n" -" \n" -" b3MprVec3Copy(dir, &b3MprSimplexPoint(portal, 1)->v);\n" -" *depth = B3_MPR_SQRT(b3MprVec3Len2(dir));\n" -" b3MprVec3Normalize(dir);\n" -"}\n" -"inline int b3MprPenetration(int pairIndex, int bodyIndexA, int bodyIndexB,\n" -" b3ConstArray(b3RigidBodyData_t) cpuBodyBuf,\n" -" b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, \n" -" b3ConstArray(b3Collidable_t) cpuCollidables,\n" -" b3ConstArray(b3Float4) cpuVertices,\n" -" __global b3Float4* sepAxis,\n" -" __global int* hasSepAxis,\n" -" float *depthOut, b3Float4* dirOut, b3Float4* posOut)\n" -"{\n" -" \n" -" b3MprSimplex_t portal;\n" -" \n" -"// if (!hasSepAxis[pairIndex])\n" -" // return -1;\n" -" \n" -" hasSepAxis[pairIndex] = 0;\n" -" int res;\n" -" // Phase 1: Portal discovery\n" -" res = b3DiscoverPortal(pairIndex,bodyIndexA,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices,sepAxis,hasSepAxis, &portal);\n" -" \n" -" \n" -" //sepAxis[pairIndex] = *pdir;//or -dir?\n" -" switch (res)\n" -" {\n" -" case 0:\n" -" {\n" -" // Phase 2: Portal refinement\n" -" \n" -" res = b3RefinePortal(pairIndex,bodyIndexA,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices, sepAxis,&portal);\n" -" if (res < 0)\n" -" return -1;\n" -" // Phase 3. Penetration info\n" -" b3FindPenetr(pairIndex,bodyIndexA,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices, sepAxis,&portal, depthOut, dirOut, posOut);\n" -" hasSepAxis[pairIndex] = 1;\n" -" sepAxis[pairIndex] = -*dirOut;\n" -" break;\n" -" }\n" -" case 1:\n" -" {\n" -" // Touching contact on portal's v1.\n" -" b3FindPenetrTouch(&portal, depthOut, dirOut, posOut);\n" -" break;\n" -" }\n" -" case 2:\n" -" {\n" -" \n" -" b3FindPenetrSegment( &portal, depthOut, dirOut, posOut);\n" -" break;\n" -" }\n" -" default:\n" -" {\n" -" hasSepAxis[pairIndex]=0;\n" -" //if (res < 0)\n" -" //{\n" -" // Origin isn't inside portal - no collision.\n" -" return -1;\n" -" //}\n" -" }\n" -" };\n" -" \n" -" return 0;\n" -"};\n" -"#endif //B3_MPR_PENETRATION_H\n" -"#ifndef B3_CONTACT4DATA_H\n" -"#define B3_CONTACT4DATA_H\n" -"#ifndef B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_FLOAT4_H\n" -"typedef struct b3Contact4Data b3Contact4Data_t;\n" -"struct b3Contact4Data\n" -"{\n" -" b3Float4 m_worldPosB[4];\n" -"// b3Float4 m_localPosA[4];\n" -"// b3Float4 m_localPosB[4];\n" -" b3Float4 m_worldNormalOnB; // w: m_nPoints\n" -" unsigned short m_restituitionCoeffCmp;\n" -" unsigned short m_frictionCoeffCmp;\n" -" int m_batchIdx;\n" -" int m_bodyAPtrAndSignBit;//x:m_bodyAPtr, y:m_bodyBPtr\n" -" int m_bodyBPtrAndSignBit;\n" -" int m_childIndexA;\n" -" int m_childIndexB;\n" -" int m_unused1;\n" -" int m_unused2;\n" -"};\n" -"inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact)\n" -"{\n" -" return (int)contact->m_worldNormalOnB.w;\n" -"};\n" -"inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints)\n" -"{\n" -" contact->m_worldNormalOnB.w = (float)numPoints;\n" -"};\n" -"#endif //B3_CONTACT4DATA_H\n" -"#define AppendInc(x, out) out = atomic_inc(x)\n" -"#define GET_NPOINTS(x) (x).m_worldNormalOnB.w\n" -"#ifdef cl_ext_atomic_counters_32\n" -" #pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n" -"#else\n" -" #define counter32_t volatile __global int*\n" -"#endif\n" -"__kernel void mprPenetrationKernel( __global int4* pairs,\n" -" __global const b3RigidBodyData_t* rigidBodies, \n" -" __global const b3Collidable_t* collidables,\n" -" __global const b3ConvexPolyhedronData_t* convexShapes, \n" -" __global const float4* vertices,\n" -" __global float4* separatingNormals,\n" -" __global int* hasSeparatingAxis,\n" -" __global struct b3Contact4Data* restrict globalContactsOut,\n" -" counter32_t nGlobalContactsOut,\n" -" int contactCapacity,\n" -" int numPairs)\n" -"{\n" -" int i = get_global_id(0);\n" -" int pairIndex = i;\n" -" if (im_worldNormalOnB = -dirOut;//normal;\n" -" c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" -" c->m_batchIdx = pairIndex;\n" -" int bodyA = pairs[pairIndex].x;\n" -" int bodyB = pairs[pairIndex].y;\n" -" c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0 ? -bodyA:bodyA;\n" -" c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0 ? -bodyB:bodyB;\n" -" c->m_childIndexA = -1;\n" -" c->m_childIndexB = -1;\n" -" //for (int i=0;im_worldPosB[0] = posOut;//localPoints[contactIdx[i]];\n" -" GET_NPOINTS(*c) = 1;//nContacts;\n" -" }\n" -" }\n" -" }\n" -"}\n" -"typedef float4 Quaternion;\n" -"#define make_float4 (float4)\n" -"__inline\n" -"float dot3F4(float4 a, float4 b)\n" -"{\n" -" float4 a1 = make_float4(a.xyz,0.f);\n" -" float4 b1 = make_float4(b.xyz,0.f);\n" -" return dot(a1, b1);\n" -"}\n" -"__inline\n" -"float4 cross3(float4 a, float4 b)\n" -"{\n" -" return cross(a,b);\n" -"}\n" -"__inline\n" -"Quaternion qtMul(Quaternion a, Quaternion b)\n" -"{\n" -" Quaternion ans;\n" -" ans = cross3( a, b );\n" -" ans += a.w*b+b.w*a;\n" -"// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" -" ans.w = a.w*b.w - dot3F4(a, b);\n" -" return ans;\n" -"}\n" -"__inline\n" -"Quaternion qtInvert(Quaternion q)\n" -"{\n" -" return (Quaternion)(-q.xyz, q.w);\n" -"}\n" -"__inline\n" -"float4 qtRotate(Quaternion q, float4 vec)\n" -"{\n" -" Quaternion qInv = qtInvert( q );\n" -" float4 vcpy = vec;\n" -" vcpy.w = 0.f;\n" -" float4 out = qtMul(qtMul(q,vcpy),qInv);\n" -" return out;\n" -"}\n" -"__inline\n" -"float4 transform(const float4* p, const float4* translation, const Quaternion* orientation)\n" -"{\n" -" return qtRotate( *orientation, *p ) + (*translation);\n" -"}\n" -"__inline\n" -"float4 qtInvRotate(const Quaternion q, float4 vec)\n" -"{\n" -" return qtRotate( qtInvert( q ), vec );\n" -"}\n" -"inline void project(__global const b3ConvexPolyhedronData_t* hull, const float4 pos, const float4 orn, \n" -"const float4* dir, __global const float4* vertices, float* min, float* max)\n" -"{\n" -" min[0] = FLT_MAX;\n" -" max[0] = -FLT_MAX;\n" -" int numVerts = hull->m_numVertices;\n" -" const float4 localDir = qtInvRotate(orn,*dir);\n" -" float offset = dot(pos,*dir);\n" -" for(int i=0;im_vertexOffset+i],localDir);\n" -" if(dp < min[0]) \n" -" min[0] = dp;\n" -" if(dp > max[0]) \n" -" max[0] = dp;\n" -" }\n" -" if(min[0]>max[0])\n" -" {\n" -" float tmp = min[0];\n" -" min[0] = max[0];\n" -" max[0] = tmp;\n" -" }\n" -" min[0] += offset;\n" -" max[0] += offset;\n" -"}\n" -"bool findSeparatingAxisUnitSphere( __global const b3ConvexPolyhedronData_t* hullA, __global const b3ConvexPolyhedronData_t* hullB, \n" -" const float4 posA1,\n" -" const float4 ornA,\n" -" const float4 posB1,\n" -" const float4 ornB,\n" -" const float4 DeltaC2,\n" -" __global const float4* vertices,\n" -" __global const float4* unitSphereDirections,\n" -" int numUnitSphereDirections,\n" -" float4* sep,\n" -" float* dmin)\n" -"{\n" -" \n" -" float4 posA = posA1;\n" -" posA.w = 0.f;\n" -" float4 posB = posB1;\n" -" posB.w = 0.f;\n" -" int curPlaneTests=0;\n" -" int curEdgeEdge = 0;\n" -" // Test unit sphere directions\n" -" for (int i=0;i0)\n" -" crossje *= -1.f;\n" -" {\n" -" float dist;\n" -" bool result = true;\n" -" float Min0,Max0;\n" -" float Min1,Max1;\n" -" project(hullA,posA,ornA,&crossje,vertices, &Min0, &Max0);\n" -" project(hullB,posB,ornB,&crossje,vertices, &Min1, &Max1);\n" -" \n" -" if(Max00.0f)\n" -" {\n" -" *sep = -(*sep);\n" -" }\n" -" return true;\n" -"}\n" -"__kernel void findSeparatingAxisUnitSphereKernel( __global const int4* pairs, \n" -" __global const b3RigidBodyData_t* rigidBodies, \n" -" __global const b3Collidable_t* collidables,\n" -" __global const b3ConvexPolyhedronData_t* convexShapes, \n" -" __global const float4* vertices,\n" -" __global const float4* unitSphereDirections,\n" -" __global float4* separatingNormals,\n" -" __global int* hasSeparatingAxis,\n" -" __global float* dmins,\n" -" int numUnitSphereDirections,\n" -" int numPairs\n" -" )\n" -"{\n" -" int i = get_global_id(0);\n" -" \n" -" if (inumUnitSphereDirections)\n" -" {\n" -" bool sepEE = findSeparatingAxisUnitSphere( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,\n" -" posB,ornB,\n" -" DeltaC2,\n" -" vertices,unitSphereDirections,numUnitSphereDirections,&sepNormal,&dmin);\n" -" if (!sepEE)\n" -" {\n" -" hasSeparatingAxis[i] = 0;\n" -" } else\n" -" {\n" -" hasSeparatingAxis[i] = 1;\n" -" separatingNormals[i] = sepNormal;\n" -" }\n" -" }\n" -" } //if (hasSeparatingAxis[i])\n" -" }//(i\n" + " *\n" + " * This file was ported from mpr.c file, part of libccd.\n" + " * The Minkoski Portal Refinement implementation was ported \n" + " * to OpenCL by Erwin Coumans for the Bullet 3 Physics library.\n" + " * at http://github.com/erwincoumans/bullet3\n" + " *\n" + " * Distributed under the OSI-approved BSD License (the \"License\");\n" + " * see .\n" + " * This software is distributed WITHOUT ANY WARRANTY; without even the\n" + " * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n" + " * See the License for more information.\n" + " */\n" + "#ifndef B3_MPR_PENETRATION_H\n" + "#define B3_MPR_PENETRATION_H\n" + "#ifndef B3_PLATFORM_DEFINITIONS_H\n" + "#define B3_PLATFORM_DEFINITIONS_H\n" + "struct MyTest\n" + "{\n" + " int bla;\n" + "};\n" + "#ifdef __cplusplus\n" + "#else\n" + "//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n" + "#define B3_LARGE_FLOAT 1e18f\n" + "#define B3_INFINITY 1e18f\n" + "#define b3Assert(a)\n" + "#define b3ConstArray(a) __global const a*\n" + "#define b3AtomicInc atomic_inc\n" + "#define b3AtomicAdd atomic_add\n" + "#define b3Fabs fabs\n" + "#define b3Sqrt native_sqrt\n" + "#define b3Sin native_sin\n" + "#define b3Cos native_cos\n" + "#define B3_STATIC\n" + "#endif\n" + "#endif\n" + "#ifndef B3_FLOAT4_H\n" + "#define B3_FLOAT4_H\n" + "#ifndef B3_PLATFORM_DEFINITIONS_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif\n" + "#endif\n" + "#ifdef __cplusplus\n" + "#else\n" + " typedef float4 b3Float4;\n" + " #define b3Float4ConstArg const b3Float4\n" + " #define b3MakeFloat4 (float4)\n" + " float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" + " {\n" + " float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" + " float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" + " return dot(a1, b1);\n" + " }\n" + " b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" + " {\n" + " float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" + " float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" + " return cross(a1, b1);\n" + " }\n" + " #define b3MinFloat4 min\n" + " #define b3MaxFloat4 max\n" + " #define b3Normalized(a) normalize(a)\n" + "#endif \n" + " \n" + "inline bool b3IsAlmostZero(b3Float4ConstArg v)\n" + "{\n" + " if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" + " return false;\n" + " return true;\n" + "}\n" + "inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" + "{\n" + " float maxDot = -B3_INFINITY;\n" + " int i = 0;\n" + " int ptIndex = -1;\n" + " for( i = 0; i < vecLen; i++ )\n" + " {\n" + " float dot = b3Dot3F4(vecArray[i],vec);\n" + " \n" + " if( dot > maxDot )\n" + " {\n" + " maxDot = dot;\n" + " ptIndex = i;\n" + " }\n" + " }\n" + " b3Assert(ptIndex>=0);\n" + " if (ptIndex<0)\n" + " {\n" + " ptIndex = 0;\n" + " }\n" + " *dotOut = maxDot;\n" + " return ptIndex;\n" + "}\n" + "#endif //B3_FLOAT4_H\n" + "#ifndef B3_RIGIDBODY_DATA_H\n" + "#define B3_RIGIDBODY_DATA_H\n" + "#ifndef B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_FLOAT4_H\n" + "#ifndef B3_QUAT_H\n" + "#define B3_QUAT_H\n" + "#ifndef B3_PLATFORM_DEFINITIONS_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif\n" + "#endif\n" + "#ifndef B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + " typedef float4 b3Quat;\n" + " #define b3QuatConstArg const b3Quat\n" + " \n" + " \n" + "inline float4 b3FastNormalize4(float4 v)\n" + "{\n" + " v = (float4)(v.xyz,0.f);\n" + " return fast_normalize(v);\n" + "}\n" + " \n" + "inline b3Quat b3QuatMul(b3Quat a, b3Quat b);\n" + "inline b3Quat b3QuatNormalized(b3QuatConstArg in);\n" + "inline b3Quat b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec);\n" + "inline b3Quat b3QuatInvert(b3QuatConstArg q);\n" + "inline b3Quat b3QuatInverse(b3QuatConstArg q);\n" + "inline b3Quat b3QuatMul(b3QuatConstArg a, b3QuatConstArg b)\n" + "{\n" + " b3Quat ans;\n" + " ans = b3Cross3( a, b );\n" + " ans += a.w*b+b.w*a;\n" + "// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" + " ans.w = a.w*b.w - b3Dot3F4(a, b);\n" + " return ans;\n" + "}\n" + "inline b3Quat b3QuatNormalized(b3QuatConstArg in)\n" + "{\n" + " b3Quat q;\n" + " q=in;\n" + " //return b3FastNormalize4(in);\n" + " float len = native_sqrt(dot(q, q));\n" + " if(len > 0.f)\n" + " {\n" + " q *= 1.f / len;\n" + " }\n" + " else\n" + " {\n" + " q.x = q.y = q.z = 0.f;\n" + " q.w = 1.f;\n" + " }\n" + " return q;\n" + "}\n" + "inline float4 b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" + "{\n" + " b3Quat qInv = b3QuatInvert( q );\n" + " float4 vcpy = vec;\n" + " vcpy.w = 0.f;\n" + " float4 out = b3QuatMul(b3QuatMul(q,vcpy),qInv);\n" + " return out;\n" + "}\n" + "inline b3Quat b3QuatInverse(b3QuatConstArg q)\n" + "{\n" + " return (b3Quat)(-q.xyz, q.w);\n" + "}\n" + "inline b3Quat b3QuatInvert(b3QuatConstArg q)\n" + "{\n" + " return (b3Quat)(-q.xyz, q.w);\n" + "}\n" + "inline float4 b3QuatInvRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" + "{\n" + " return b3QuatRotate( b3QuatInvert( q ), vec );\n" + "}\n" + "inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)\n" + "{\n" + " return b3QuatRotate( orientation, point ) + (translation);\n" + "}\n" + " \n" + "#endif \n" + "#endif //B3_QUAT_H\n" + "#ifndef B3_MAT3x3_H\n" + "#define B3_MAT3x3_H\n" + "#ifndef B3_QUAT_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_QUAT_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "typedef struct\n" + "{\n" + " b3Float4 m_row[3];\n" + "}b3Mat3x3;\n" + "#define b3Mat3x3ConstArg const b3Mat3x3\n" + "#define b3GetRow(m,row) (m.m_row[row])\n" + "inline b3Mat3x3 b3QuatGetRotationMatrix(b3Quat quat)\n" + "{\n" + " b3Float4 quat2 = (b3Float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f);\n" + " b3Mat3x3 out;\n" + " out.m_row[0].x=1-2*quat2.y-2*quat2.z;\n" + " out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z;\n" + " out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y;\n" + " out.m_row[0].w = 0.f;\n" + " out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z;\n" + " out.m_row[1].y=1-2*quat2.x-2*quat2.z;\n" + " out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x;\n" + " out.m_row[1].w = 0.f;\n" + " out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y;\n" + " out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x;\n" + " out.m_row[2].z=1-2*quat2.x-2*quat2.y;\n" + " out.m_row[2].w = 0.f;\n" + " return out;\n" + "}\n" + "inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg matIn)\n" + "{\n" + " b3Mat3x3 out;\n" + " out.m_row[0] = fabs(matIn.m_row[0]);\n" + " out.m_row[1] = fabs(matIn.m_row[1]);\n" + " out.m_row[2] = fabs(matIn.m_row[2]);\n" + " return out;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtZero();\n" + "__inline\n" + "b3Mat3x3 mtIdentity();\n" + "__inline\n" + "b3Mat3x3 mtTranspose(b3Mat3x3 m);\n" + "__inline\n" + "b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b);\n" + "__inline\n" + "b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b);\n" + "__inline\n" + "b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b);\n" + "__inline\n" + "b3Mat3x3 mtZero()\n" + "{\n" + " b3Mat3x3 m;\n" + " m.m_row[0] = (b3Float4)(0.f);\n" + " m.m_row[1] = (b3Float4)(0.f);\n" + " m.m_row[2] = (b3Float4)(0.f);\n" + " return m;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtIdentity()\n" + "{\n" + " b3Mat3x3 m;\n" + " m.m_row[0] = (b3Float4)(1,0,0,0);\n" + " m.m_row[1] = (b3Float4)(0,1,0,0);\n" + " m.m_row[2] = (b3Float4)(0,0,1,0);\n" + " return m;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtTranspose(b3Mat3x3 m)\n" + "{\n" + " b3Mat3x3 out;\n" + " out.m_row[0] = (b3Float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n" + " out.m_row[1] = (b3Float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n" + " out.m_row[2] = (b3Float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n" + " return out;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b)\n" + "{\n" + " b3Mat3x3 transB;\n" + " transB = mtTranspose( b );\n" + " b3Mat3x3 ans;\n" + " // why this doesn't run when 0ing in the for{}\n" + " a.m_row[0].w = 0.f;\n" + " a.m_row[1].w = 0.f;\n" + " a.m_row[2].w = 0.f;\n" + " for(int i=0; i<3; i++)\n" + " {\n" + "// a.m_row[i].w = 0.f;\n" + " ans.m_row[i].x = b3Dot3F4(a.m_row[i],transB.m_row[0]);\n" + " ans.m_row[i].y = b3Dot3F4(a.m_row[i],transB.m_row[1]);\n" + " ans.m_row[i].z = b3Dot3F4(a.m_row[i],transB.m_row[2]);\n" + " ans.m_row[i].w = 0.f;\n" + " }\n" + " return ans;\n" + "}\n" + "__inline\n" + "b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b)\n" + "{\n" + " b3Float4 ans;\n" + " ans.x = b3Dot3F4( a.m_row[0], b );\n" + " ans.y = b3Dot3F4( a.m_row[1], b );\n" + " ans.z = b3Dot3F4( a.m_row[2], b );\n" + " ans.w = 0.f;\n" + " return ans;\n" + "}\n" + "__inline\n" + "b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b)\n" + "{\n" + " b3Float4 colx = b3MakeFloat4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" + " b3Float4 coly = b3MakeFloat4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" + " b3Float4 colz = b3MakeFloat4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" + " b3Float4 ans;\n" + " ans.x = b3Dot3F4( a, colx );\n" + " ans.y = b3Dot3F4( a, coly );\n" + " ans.z = b3Dot3F4( a, colz );\n" + " return ans;\n" + "}\n" + "#endif\n" + "#endif //B3_MAT3x3_H\n" + "typedef struct b3RigidBodyData b3RigidBodyData_t;\n" + "struct b3RigidBodyData\n" + "{\n" + " b3Float4 m_pos;\n" + " b3Quat m_quat;\n" + " b3Float4 m_linVel;\n" + " b3Float4 m_angVel;\n" + " int m_collidableIdx;\n" + " float m_invMass;\n" + " float m_restituitionCoeff;\n" + " float m_frictionCoeff;\n" + "};\n" + "typedef struct b3InertiaData b3InertiaData_t;\n" + "struct b3InertiaData\n" + "{\n" + " b3Mat3x3 m_invInertiaWorld;\n" + " b3Mat3x3 m_initInvInertia;\n" + "};\n" + "#endif //B3_RIGIDBODY_DATA_H\n" + " \n" + "#ifndef B3_CONVEX_POLYHEDRON_DATA_H\n" + "#define B3_CONVEX_POLYHEDRON_DATA_H\n" + "#ifndef B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_FLOAT4_H\n" + "#ifndef B3_QUAT_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_QUAT_H\n" + "typedef struct b3GpuFace b3GpuFace_t;\n" + "struct b3GpuFace\n" + "{\n" + " b3Float4 m_plane;\n" + " int m_indexOffset;\n" + " int m_numIndices;\n" + " int m_unusedPadding1;\n" + " int m_unusedPadding2;\n" + "};\n" + "typedef struct b3ConvexPolyhedronData b3ConvexPolyhedronData_t;\n" + "struct b3ConvexPolyhedronData\n" + "{\n" + " b3Float4 m_localCenter;\n" + " b3Float4 m_extents;\n" + " b3Float4 mC;\n" + " b3Float4 mE;\n" + " float m_radius;\n" + " int m_faceOffset;\n" + " int m_numFaces;\n" + " int m_numVertices;\n" + " int m_vertexOffset;\n" + " int m_uniqueEdgesOffset;\n" + " int m_numUniqueEdges;\n" + " int m_unused;\n" + "};\n" + "#endif //B3_CONVEX_POLYHEDRON_DATA_H\n" + "#ifndef B3_COLLIDABLE_H\n" + "#define B3_COLLIDABLE_H\n" + "#ifndef B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_FLOAT4_H\n" + "#ifndef B3_QUAT_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_QUAT_H\n" + "enum b3ShapeTypes\n" + "{\n" + " SHAPE_HEIGHT_FIELD=1,\n" + " SHAPE_CONVEX_HULL=3,\n" + " SHAPE_PLANE=4,\n" + " SHAPE_CONCAVE_TRIMESH=5,\n" + " SHAPE_COMPOUND_OF_CONVEX_HULLS=6,\n" + " SHAPE_SPHERE=7,\n" + " MAX_NUM_SHAPE_TYPES,\n" + "};\n" + "typedef struct b3Collidable b3Collidable_t;\n" + "struct b3Collidable\n" + "{\n" + " union {\n" + " int m_numChildShapes;\n" + " int m_bvhIndex;\n" + " };\n" + " union\n" + " {\n" + " float m_radius;\n" + " int m_compoundBvhIndex;\n" + " };\n" + " int m_shapeType;\n" + " int m_shapeIndex;\n" + "};\n" + "typedef struct b3GpuChildShape b3GpuChildShape_t;\n" + "struct b3GpuChildShape\n" + "{\n" + " b3Float4 m_childPosition;\n" + " b3Quat m_childOrientation;\n" + " int m_shapeIndex;\n" + " int m_unused0;\n" + " int m_unused1;\n" + " int m_unused2;\n" + "};\n" + "struct b3CompoundOverlappingPair\n" + "{\n" + " int m_bodyIndexA;\n" + " int m_bodyIndexB;\n" + "// int m_pairType;\n" + " int m_childShapeIndexA;\n" + " int m_childShapeIndexB;\n" + "};\n" + "#endif //B3_COLLIDABLE_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#define B3_MPR_SQRT sqrt\n" + "#endif\n" + "#define B3_MPR_FMIN(x, y) ((x) < (y) ? (x) : (y))\n" + "#define B3_MPR_FABS fabs\n" + "#define B3_MPR_TOLERANCE 1E-6f\n" + "#define B3_MPR_MAX_ITERATIONS 1000\n" + "struct _b3MprSupport_t \n" + "{\n" + " b3Float4 v; //!< Support point in minkowski sum\n" + " b3Float4 v1; //!< Support point in obj1\n" + " b3Float4 v2; //!< Support point in obj2\n" + "};\n" + "typedef struct _b3MprSupport_t b3MprSupport_t;\n" + "struct _b3MprSimplex_t \n" + "{\n" + " b3MprSupport_t ps[4];\n" + " int last; //!< index of last added point\n" + "};\n" + "typedef struct _b3MprSimplex_t b3MprSimplex_t;\n" + "inline b3MprSupport_t* b3MprSimplexPointW(b3MprSimplex_t *s, int idx)\n" + "{\n" + " return &s->ps[idx];\n" + "}\n" + "inline void b3MprSimplexSetSize(b3MprSimplex_t *s, int size)\n" + "{\n" + " s->last = size - 1;\n" + "}\n" + "inline int b3MprSimplexSize(const b3MprSimplex_t *s)\n" + "{\n" + " return s->last + 1;\n" + "}\n" + "inline const b3MprSupport_t* b3MprSimplexPoint(const b3MprSimplex_t* s, int idx)\n" + "{\n" + " // here is no check on boundaries\n" + " return &s->ps[idx];\n" + "}\n" + "inline void b3MprSupportCopy(b3MprSupport_t *d, const b3MprSupport_t *s)\n" + "{\n" + " *d = *s;\n" + "}\n" + "inline void b3MprSimplexSet(b3MprSimplex_t *s, size_t pos, const b3MprSupport_t *a)\n" + "{\n" + " b3MprSupportCopy(s->ps + pos, a);\n" + "}\n" + "inline void b3MprSimplexSwap(b3MprSimplex_t *s, size_t pos1, size_t pos2)\n" + "{\n" + " b3MprSupport_t supp;\n" + " b3MprSupportCopy(&supp, &s->ps[pos1]);\n" + " b3MprSupportCopy(&s->ps[pos1], &s->ps[pos2]);\n" + " b3MprSupportCopy(&s->ps[pos2], &supp);\n" + "}\n" + "inline int b3MprIsZero(float val)\n" + "{\n" + " return B3_MPR_FABS(val) < FLT_EPSILON;\n" + "}\n" + "inline int b3MprEq(float _a, float _b)\n" + "{\n" + " float ab;\n" + " float a, b;\n" + " ab = B3_MPR_FABS(_a - _b);\n" + " if (B3_MPR_FABS(ab) < FLT_EPSILON)\n" + " return 1;\n" + " a = B3_MPR_FABS(_a);\n" + " b = B3_MPR_FABS(_b);\n" + " if (b > a){\n" + " return ab < FLT_EPSILON * b;\n" + " }else{\n" + " return ab < FLT_EPSILON * a;\n" + " }\n" + "}\n" + "inline int b3MprVec3Eq(const b3Float4* a, const b3Float4 *b)\n" + "{\n" + " return b3MprEq((*a).x, (*b).x)\n" + " && b3MprEq((*a).y, (*b).y)\n" + " && b3MprEq((*a).z, (*b).z);\n" + "}\n" + "inline b3Float4 b3LocalGetSupportVertex(b3Float4ConstArg supportVec,__global const b3ConvexPolyhedronData_t* hull, b3ConstArray(b3Float4) verticesA)\n" + "{\n" + " b3Float4 supVec = b3MakeFloat4(0,0,0,0);\n" + " float maxDot = -B3_LARGE_FLOAT;\n" + " if( 0 < hull->m_numVertices )\n" + " {\n" + " const b3Float4 scaled = supportVec;\n" + " int index = b3MaxDot(scaled, &verticesA[hull->m_vertexOffset], hull->m_numVertices, &maxDot);\n" + " return verticesA[hull->m_vertexOffset+index];\n" + " }\n" + " return supVec;\n" + "}\n" + "B3_STATIC void b3MprConvexSupport(int pairIndex,int bodyIndex, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, \n" + " b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, \n" + " b3ConstArray(b3Collidable_t) cpuCollidables,\n" + " b3ConstArray(b3Float4) cpuVertices,\n" + " __global b3Float4* sepAxis,\n" + " const b3Float4* _dir, b3Float4* outp, int logme)\n" + "{\n" + " //dir is in worldspace, move to local space\n" + " \n" + " b3Float4 pos = cpuBodyBuf[bodyIndex].m_pos;\n" + " b3Quat orn = cpuBodyBuf[bodyIndex].m_quat;\n" + " \n" + " b3Float4 dir = b3MakeFloat4((*_dir).x,(*_dir).y,(*_dir).z,0.f);\n" + " \n" + " const b3Float4 localDir = b3QuatRotate(b3QuatInverse(orn),dir);\n" + " \n" + " //find local support vertex\n" + " int colIndex = cpuBodyBuf[bodyIndex].m_collidableIdx;\n" + " \n" + " b3Assert(cpuCollidables[colIndex].m_shapeType==SHAPE_CONVEX_HULL);\n" + " __global const b3ConvexPolyhedronData_t* hull = &cpuConvexData[cpuCollidables[colIndex].m_shapeIndex];\n" + " \n" + " b3Float4 pInA;\n" + " if (logme)\n" + " {\n" + " b3Float4 supVec = b3MakeFloat4(0,0,0,0);\n" + " float maxDot = -B3_LARGE_FLOAT;\n" + " if( 0 < hull->m_numVertices )\n" + " {\n" + " const b3Float4 scaled = localDir;\n" + " int index = b3MaxDot(scaled, &cpuVertices[hull->m_vertexOffset], hull->m_numVertices, &maxDot);\n" + " pInA = cpuVertices[hull->m_vertexOffset+index];\n" + " \n" + " }\n" + " } else\n" + " {\n" + " pInA = b3LocalGetSupportVertex(localDir,hull,cpuVertices);\n" + " }\n" + " //move vertex to world space\n" + " *outp = b3TransformPoint(pInA,pos,orn);\n" + " \n" + "}\n" + "inline void b3MprSupport(int pairIndex,int bodyIndexA, int bodyIndexB, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, \n" + " b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, \n" + " b3ConstArray(b3Collidable_t) cpuCollidables,\n" + " b3ConstArray(b3Float4) cpuVertices,\n" + " __global b3Float4* sepAxis,\n" + " const b3Float4* _dir, b3MprSupport_t *supp)\n" + "{\n" + " b3Float4 dir;\n" + " dir = *_dir;\n" + " b3MprConvexSupport(pairIndex,bodyIndexA,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices,sepAxis,&dir, &supp->v1,0);\n" + " dir = *_dir*-1.f;\n" + " b3MprConvexSupport(pairIndex,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices,sepAxis,&dir, &supp->v2,0);\n" + " supp->v = supp->v1 - supp->v2;\n" + "}\n" + "inline void b3FindOrigin(int bodyIndexA, int bodyIndexB, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, b3MprSupport_t *center)\n" + "{\n" + " center->v1 = cpuBodyBuf[bodyIndexA].m_pos;\n" + " center->v2 = cpuBodyBuf[bodyIndexB].m_pos;\n" + " center->v = center->v1 - center->v2;\n" + "}\n" + "inline void b3MprVec3Set(b3Float4 *v, float x, float y, float z)\n" + "{\n" + " (*v).x = x;\n" + " (*v).y = y;\n" + " (*v).z = z;\n" + " (*v).w = 0.f;\n" + "}\n" + "inline void b3MprVec3Add(b3Float4 *v, const b3Float4 *w)\n" + "{\n" + " (*v).x += (*w).x;\n" + " (*v).y += (*w).y;\n" + " (*v).z += (*w).z;\n" + "}\n" + "inline void b3MprVec3Copy(b3Float4 *v, const b3Float4 *w)\n" + "{\n" + " *v = *w;\n" + "}\n" + "inline void b3MprVec3Scale(b3Float4 *d, float k)\n" + "{\n" + " *d *= k;\n" + "}\n" + "inline float b3MprVec3Dot(const b3Float4 *a, const b3Float4 *b)\n" + "{\n" + " float dot;\n" + " dot = b3Dot3F4(*a,*b);\n" + " return dot;\n" + "}\n" + "inline float b3MprVec3Len2(const b3Float4 *v)\n" + "{\n" + " return b3MprVec3Dot(v, v);\n" + "}\n" + "inline void b3MprVec3Normalize(b3Float4 *d)\n" + "{\n" + " float k = 1.f / B3_MPR_SQRT(b3MprVec3Len2(d));\n" + " b3MprVec3Scale(d, k);\n" + "}\n" + "inline void b3MprVec3Cross(b3Float4 *d, const b3Float4 *a, const b3Float4 *b)\n" + "{\n" + " *d = b3Cross3(*a,*b);\n" + " \n" + "}\n" + "inline void b3MprVec3Sub2(b3Float4 *d, const b3Float4 *v, const b3Float4 *w)\n" + "{\n" + " *d = *v - *w;\n" + "}\n" + "inline void b3PortalDir(const b3MprSimplex_t *portal, b3Float4 *dir)\n" + "{\n" + " b3Float4 v2v1, v3v1;\n" + " b3MprVec3Sub2(&v2v1, &b3MprSimplexPoint(portal, 2)->v,\n" + " &b3MprSimplexPoint(portal, 1)->v);\n" + " b3MprVec3Sub2(&v3v1, &b3MprSimplexPoint(portal, 3)->v,\n" + " &b3MprSimplexPoint(portal, 1)->v);\n" + " b3MprVec3Cross(dir, &v2v1, &v3v1);\n" + " b3MprVec3Normalize(dir);\n" + "}\n" + "inline int portalEncapsulesOrigin(const b3MprSimplex_t *portal,\n" + " const b3Float4 *dir)\n" + "{\n" + " float dot;\n" + " dot = b3MprVec3Dot(dir, &b3MprSimplexPoint(portal, 1)->v);\n" + " return b3MprIsZero(dot) || dot > 0.f;\n" + "}\n" + "inline int portalReachTolerance(const b3MprSimplex_t *portal,\n" + " const b3MprSupport_t *v4,\n" + " const b3Float4 *dir)\n" + "{\n" + " float dv1, dv2, dv3, dv4;\n" + " float dot1, dot2, dot3;\n" + " // find the smallest dot product of dir and {v1-v4, v2-v4, v3-v4}\n" + " dv1 = b3MprVec3Dot(&b3MprSimplexPoint(portal, 1)->v, dir);\n" + " dv2 = b3MprVec3Dot(&b3MprSimplexPoint(portal, 2)->v, dir);\n" + " dv3 = b3MprVec3Dot(&b3MprSimplexPoint(portal, 3)->v, dir);\n" + " dv4 = b3MprVec3Dot(&v4->v, dir);\n" + " dot1 = dv4 - dv1;\n" + " dot2 = dv4 - dv2;\n" + " dot3 = dv4 - dv3;\n" + " dot1 = B3_MPR_FMIN(dot1, dot2);\n" + " dot1 = B3_MPR_FMIN(dot1, dot3);\n" + " return b3MprEq(dot1, B3_MPR_TOLERANCE) || dot1 < B3_MPR_TOLERANCE;\n" + "}\n" + "inline int portalCanEncapsuleOrigin(const b3MprSimplex_t *portal, \n" + " const b3MprSupport_t *v4,\n" + " const b3Float4 *dir)\n" + "{\n" + " float dot;\n" + " dot = b3MprVec3Dot(&v4->v, dir);\n" + " return b3MprIsZero(dot) || dot > 0.f;\n" + "}\n" + "inline void b3ExpandPortal(b3MprSimplex_t *portal,\n" + " const b3MprSupport_t *v4)\n" + "{\n" + " float dot;\n" + " b3Float4 v4v0;\n" + " b3MprVec3Cross(&v4v0, &v4->v, &b3MprSimplexPoint(portal, 0)->v);\n" + " dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 1)->v, &v4v0);\n" + " if (dot > 0.f){\n" + " dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 2)->v, &v4v0);\n" + " if (dot > 0.f){\n" + " b3MprSimplexSet(portal, 1, v4);\n" + " }else{\n" + " b3MprSimplexSet(portal, 3, v4);\n" + " }\n" + " }else{\n" + " dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 3)->v, &v4v0);\n" + " if (dot > 0.f){\n" + " b3MprSimplexSet(portal, 2, v4);\n" + " }else{\n" + " b3MprSimplexSet(portal, 1, v4);\n" + " }\n" + " }\n" + "}\n" + "B3_STATIC int b3DiscoverPortal(int pairIndex, int bodyIndexA, int bodyIndexB, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, \n" + " b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, \n" + " b3ConstArray(b3Collidable_t) cpuCollidables,\n" + " b3ConstArray(b3Float4) cpuVertices,\n" + " __global b3Float4* sepAxis,\n" + " __global int* hasSepAxis,\n" + " b3MprSimplex_t *portal)\n" + "{\n" + " b3Float4 dir, va, vb;\n" + " float dot;\n" + " int cont;\n" + " \n" + " \n" + " // vertex 0 is center of portal\n" + " b3FindOrigin(bodyIndexA,bodyIndexB,cpuBodyBuf, b3MprSimplexPointW(portal, 0));\n" + " // vertex 0 is center of portal\n" + " b3MprSimplexSetSize(portal, 1);\n" + " \n" + " b3Float4 zero = b3MakeFloat4(0,0,0,0);\n" + " b3Float4* b3mpr_vec3_origin = &zero;\n" + " if (b3MprVec3Eq(&b3MprSimplexPoint(portal, 0)->v, b3mpr_vec3_origin)){\n" + " // Portal's center lies on origin (0,0,0) => we know that objects\n" + " // intersect but we would need to know penetration info.\n" + " // So move center little bit...\n" + " b3MprVec3Set(&va, FLT_EPSILON * 10.f, 0.f, 0.f);\n" + " b3MprVec3Add(&b3MprSimplexPointW(portal, 0)->v, &va);\n" + " }\n" + " // vertex 1 = support in direction of origin\n" + " b3MprVec3Copy(&dir, &b3MprSimplexPoint(portal, 0)->v);\n" + " b3MprVec3Scale(&dir, -1.f);\n" + " b3MprVec3Normalize(&dir);\n" + " b3MprSupport(pairIndex,bodyIndexA,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices, sepAxis,&dir, b3MprSimplexPointW(portal, 1));\n" + " b3MprSimplexSetSize(portal, 2);\n" + " // test if origin isn't outside of v1\n" + " dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 1)->v, &dir);\n" + " \n" + " if (b3MprIsZero(dot) || dot < 0.f)\n" + " return -1;\n" + " // vertex 2\n" + " b3MprVec3Cross(&dir, &b3MprSimplexPoint(portal, 0)->v,\n" + " &b3MprSimplexPoint(portal, 1)->v);\n" + " if (b3MprIsZero(b3MprVec3Len2(&dir))){\n" + " if (b3MprVec3Eq(&b3MprSimplexPoint(portal, 1)->v, b3mpr_vec3_origin)){\n" + " // origin lies on v1\n" + " return 1;\n" + " }else{\n" + " // origin lies on v0-v1 segment\n" + " return 2;\n" + " }\n" + " }\n" + " b3MprVec3Normalize(&dir);\n" + " b3MprSupport(pairIndex,bodyIndexA,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices, sepAxis,&dir, b3MprSimplexPointW(portal, 2));\n" + " \n" + " dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 2)->v, &dir);\n" + " if (b3MprIsZero(dot) || dot < 0.f)\n" + " return -1;\n" + " b3MprSimplexSetSize(portal, 3);\n" + " // vertex 3 direction\n" + " b3MprVec3Sub2(&va, &b3MprSimplexPoint(portal, 1)->v,\n" + " &b3MprSimplexPoint(portal, 0)->v);\n" + " b3MprVec3Sub2(&vb, &b3MprSimplexPoint(portal, 2)->v,\n" + " &b3MprSimplexPoint(portal, 0)->v);\n" + " b3MprVec3Cross(&dir, &va, &vb);\n" + " b3MprVec3Normalize(&dir);\n" + " // it is better to form portal faces to be oriented \"outside\" origin\n" + " dot = b3MprVec3Dot(&dir, &b3MprSimplexPoint(portal, 0)->v);\n" + " if (dot > 0.f){\n" + " b3MprSimplexSwap(portal, 1, 2);\n" + " b3MprVec3Scale(&dir, -1.f);\n" + " }\n" + " while (b3MprSimplexSize(portal) < 4){\n" + " b3MprSupport(pairIndex,bodyIndexA,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices, sepAxis,&dir, b3MprSimplexPointW(portal, 3));\n" + " \n" + " dot = b3MprVec3Dot(&b3MprSimplexPoint(portal, 3)->v, &dir);\n" + " if (b3MprIsZero(dot) || dot < 0.f)\n" + " return -1;\n" + " cont = 0;\n" + " // test if origin is outside (v1, v0, v3) - set v2 as v3 and\n" + " // continue\n" + " b3MprVec3Cross(&va, &b3MprSimplexPoint(portal, 1)->v,\n" + " &b3MprSimplexPoint(portal, 3)->v);\n" + " dot = b3MprVec3Dot(&va, &b3MprSimplexPoint(portal, 0)->v);\n" + " if (dot < 0.f && !b3MprIsZero(dot)){\n" + " b3MprSimplexSet(portal, 2, b3MprSimplexPoint(portal, 3));\n" + " cont = 1;\n" + " }\n" + " if (!cont){\n" + " // test if origin is outside (v3, v0, v2) - set v1 as v3 and\n" + " // continue\n" + " b3MprVec3Cross(&va, &b3MprSimplexPoint(portal, 3)->v,\n" + " &b3MprSimplexPoint(portal, 2)->v);\n" + " dot = b3MprVec3Dot(&va, &b3MprSimplexPoint(portal, 0)->v);\n" + " if (dot < 0.f && !b3MprIsZero(dot)){\n" + " b3MprSimplexSet(portal, 1, b3MprSimplexPoint(portal, 3));\n" + " cont = 1;\n" + " }\n" + " }\n" + " if (cont){\n" + " b3MprVec3Sub2(&va, &b3MprSimplexPoint(portal, 1)->v,\n" + " &b3MprSimplexPoint(portal, 0)->v);\n" + " b3MprVec3Sub2(&vb, &b3MprSimplexPoint(portal, 2)->v,\n" + " &b3MprSimplexPoint(portal, 0)->v);\n" + " b3MprVec3Cross(&dir, &va, &vb);\n" + " b3MprVec3Normalize(&dir);\n" + " }else{\n" + " b3MprSimplexSetSize(portal, 4);\n" + " }\n" + " }\n" + " return 0;\n" + "}\n" + "B3_STATIC int b3RefinePortal(int pairIndex,int bodyIndexA, int bodyIndexB, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, \n" + " b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, \n" + " b3ConstArray(b3Collidable_t) cpuCollidables,\n" + " b3ConstArray(b3Float4) cpuVertices,\n" + " __global b3Float4* sepAxis,\n" + " b3MprSimplex_t *portal)\n" + "{\n" + " b3Float4 dir;\n" + " b3MprSupport_t v4;\n" + " for (int i=0;iv,\n" + " &b3MprSimplexPoint(portal, 2)->v);\n" + " b[0] = b3MprVec3Dot(&vec, &b3MprSimplexPoint(portal, 3)->v);\n" + " b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 3)->v,\n" + " &b3MprSimplexPoint(portal, 2)->v);\n" + " b[1] = b3MprVec3Dot(&vec, &b3MprSimplexPoint(portal, 0)->v);\n" + " b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 0)->v,\n" + " &b3MprSimplexPoint(portal, 1)->v);\n" + " b[2] = b3MprVec3Dot(&vec, &b3MprSimplexPoint(portal, 3)->v);\n" + " b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 2)->v,\n" + " &b3MprSimplexPoint(portal, 1)->v);\n" + " b[3] = b3MprVec3Dot(&vec, &b3MprSimplexPoint(portal, 0)->v);\n" + " sum = b[0] + b[1] + b[2] + b[3];\n" + " if (b3MprIsZero(sum) || sum < 0.f){\n" + " b[0] = 0.f;\n" + " b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 2)->v,\n" + " &b3MprSimplexPoint(portal, 3)->v);\n" + " b[1] = b3MprVec3Dot(&vec, &dir);\n" + " b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 3)->v,\n" + " &b3MprSimplexPoint(portal, 1)->v);\n" + " b[2] = b3MprVec3Dot(&vec, &dir);\n" + " b3MprVec3Cross(&vec, &b3MprSimplexPoint(portal, 1)->v,\n" + " &b3MprSimplexPoint(portal, 2)->v);\n" + " b[3] = b3MprVec3Dot(&vec, &dir);\n" + " sum = b[1] + b[2] + b[3];\n" + " }\n" + " inv = 1.f / sum;\n" + " b3MprVec3Copy(&p1, b3mpr_vec3_origin);\n" + " b3MprVec3Copy(&p2, b3mpr_vec3_origin);\n" + " for (i = 0; i < 4; i++){\n" + " b3MprVec3Copy(&vec, &b3MprSimplexPoint(portal, i)->v1);\n" + " b3MprVec3Scale(&vec, b[i]);\n" + " b3MprVec3Add(&p1, &vec);\n" + " b3MprVec3Copy(&vec, &b3MprSimplexPoint(portal, i)->v2);\n" + " b3MprVec3Scale(&vec, b[i]);\n" + " b3MprVec3Add(&p2, &vec);\n" + " }\n" + " b3MprVec3Scale(&p1, inv);\n" + " b3MprVec3Scale(&p2, inv);\n" + " b3MprVec3Copy(pos, &p1);\n" + " b3MprVec3Add(pos, &p2);\n" + " b3MprVec3Scale(pos, 0.5);\n" + "}\n" + "inline float b3MprVec3Dist2(const b3Float4 *a, const b3Float4 *b)\n" + "{\n" + " b3Float4 ab;\n" + " b3MprVec3Sub2(&ab, a, b);\n" + " return b3MprVec3Len2(&ab);\n" + "}\n" + "inline float _b3MprVec3PointSegmentDist2(const b3Float4 *P,\n" + " const b3Float4 *x0,\n" + " const b3Float4 *b,\n" + " b3Float4 *witness)\n" + "{\n" + " // The computation comes from solving equation of segment:\n" + " // S(t) = x0 + t.d\n" + " // where - x0 is initial point of segment\n" + " // - d is direction of segment from x0 (|d| > 0)\n" + " // - t belongs to <0, 1> interval\n" + " // \n" + " // Than, distance from a segment to some point P can be expressed:\n" + " // D(t) = |x0 + t.d - P|^2\n" + " // which is distance from any point on segment. Minimization\n" + " // of this function brings distance from P to segment.\n" + " // Minimization of D(t) leads to simple quadratic equation that's\n" + " // solving is straightforward.\n" + " //\n" + " // Bonus of this method is witness point for free.\n" + " float dist, t;\n" + " b3Float4 d, a;\n" + " // direction of segment\n" + " b3MprVec3Sub2(&d, b, x0);\n" + " // precompute vector from P to x0\n" + " b3MprVec3Sub2(&a, x0, P);\n" + " t = -1.f * b3MprVec3Dot(&a, &d);\n" + " t /= b3MprVec3Len2(&d);\n" + " if (t < 0.f || b3MprIsZero(t)){\n" + " dist = b3MprVec3Dist2(x0, P);\n" + " if (witness)\n" + " b3MprVec3Copy(witness, x0);\n" + " }else if (t > 1.f || b3MprEq(t, 1.f)){\n" + " dist = b3MprVec3Dist2(b, P);\n" + " if (witness)\n" + " b3MprVec3Copy(witness, b);\n" + " }else{\n" + " if (witness){\n" + " b3MprVec3Copy(witness, &d);\n" + " b3MprVec3Scale(witness, t);\n" + " b3MprVec3Add(witness, x0);\n" + " dist = b3MprVec3Dist2(witness, P);\n" + " }else{\n" + " // recycling variables\n" + " b3MprVec3Scale(&d, t);\n" + " b3MprVec3Add(&d, &a);\n" + " dist = b3MprVec3Len2(&d);\n" + " }\n" + " }\n" + " return dist;\n" + "}\n" + "inline float b3MprVec3PointTriDist2(const b3Float4 *P,\n" + " const b3Float4 *x0, const b3Float4 *B,\n" + " const b3Float4 *C,\n" + " b3Float4 *witness)\n" + "{\n" + " // Computation comes from analytic expression for triangle (x0, B, C)\n" + " // T(s, t) = x0 + s.d1 + t.d2, where d1 = B - x0 and d2 = C - x0 and\n" + " // Then equation for distance is:\n" + " // D(s, t) = | T(s, t) - P |^2\n" + " // This leads to minimization of quadratic function of two variables.\n" + " // The solution from is taken only if s is between 0 and 1, t is\n" + " // between 0 and 1 and t + s < 1, otherwise distance from segment is\n" + " // computed.\n" + " b3Float4 d1, d2, a;\n" + " float u, v, w, p, q, r;\n" + " float s, t, dist, dist2;\n" + " b3Float4 witness2;\n" + " b3MprVec3Sub2(&d1, B, x0);\n" + " b3MprVec3Sub2(&d2, C, x0);\n" + " b3MprVec3Sub2(&a, x0, P);\n" + " u = b3MprVec3Dot(&a, &a);\n" + " v = b3MprVec3Dot(&d1, &d1);\n" + " w = b3MprVec3Dot(&d2, &d2);\n" + " p = b3MprVec3Dot(&a, &d1);\n" + " q = b3MprVec3Dot(&a, &d2);\n" + " r = b3MprVec3Dot(&d1, &d2);\n" + " s = (q * r - w * p) / (w * v - r * r);\n" + " t = (-s * r - q) / w;\n" + " if ((b3MprIsZero(s) || s > 0.f)\n" + " && (b3MprEq(s, 1.f) || s < 1.f)\n" + " && (b3MprIsZero(t) || t > 0.f)\n" + " && (b3MprEq(t, 1.f) || t < 1.f)\n" + " && (b3MprEq(t + s, 1.f) || t + s < 1.f)){\n" + " if (witness){\n" + " b3MprVec3Scale(&d1, s);\n" + " b3MprVec3Scale(&d2, t);\n" + " b3MprVec3Copy(witness, x0);\n" + " b3MprVec3Add(witness, &d1);\n" + " b3MprVec3Add(witness, &d2);\n" + " dist = b3MprVec3Dist2(witness, P);\n" + " }else{\n" + " dist = s * s * v;\n" + " dist += t * t * w;\n" + " dist += 2.f * s * t * r;\n" + " dist += 2.f * s * p;\n" + " dist += 2.f * t * q;\n" + " dist += u;\n" + " }\n" + " }else{\n" + " dist = _b3MprVec3PointSegmentDist2(P, x0, B, witness);\n" + " dist2 = _b3MprVec3PointSegmentDist2(P, x0, C, &witness2);\n" + " if (dist2 < dist){\n" + " dist = dist2;\n" + " if (witness)\n" + " b3MprVec3Copy(witness, &witness2);\n" + " }\n" + " dist2 = _b3MprVec3PointSegmentDist2(P, B, C, &witness2);\n" + " if (dist2 < dist){\n" + " dist = dist2;\n" + " if (witness)\n" + " b3MprVec3Copy(witness, &witness2);\n" + " }\n" + " }\n" + " return dist;\n" + "}\n" + "B3_STATIC void b3FindPenetr(int pairIndex,int bodyIndexA, int bodyIndexB, b3ConstArray(b3RigidBodyData_t) cpuBodyBuf, \n" + " b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, \n" + " b3ConstArray(b3Collidable_t) cpuCollidables,\n" + " b3ConstArray(b3Float4) cpuVertices,\n" + " __global b3Float4* sepAxis,\n" + " b3MprSimplex_t *portal,\n" + " float *depth, b3Float4 *pdir, b3Float4 *pos)\n" + "{\n" + " b3Float4 dir;\n" + " b3MprSupport_t v4;\n" + " unsigned long iterations;\n" + " b3Float4 zero = b3MakeFloat4(0,0,0,0);\n" + " b3Float4* b3mpr_vec3_origin = &zero;\n" + " iterations = 1UL;\n" + " for (int i=0;i find penetration info\n" + " if (portalReachTolerance(portal, &v4, &dir)\n" + " || iterations ==B3_MPR_MAX_ITERATIONS)\n" + " {\n" + " *depth = b3MprVec3PointTriDist2(b3mpr_vec3_origin,&b3MprSimplexPoint(portal, 1)->v,&b3MprSimplexPoint(portal, 2)->v,&b3MprSimplexPoint(portal, 3)->v,pdir);\n" + " *depth = B3_MPR_SQRT(*depth);\n" + " \n" + " if (b3MprIsZero((*pdir).x) && b3MprIsZero((*pdir).y) && b3MprIsZero((*pdir).z))\n" + " {\n" + " \n" + " *pdir = dir;\n" + " } \n" + " b3MprVec3Normalize(pdir);\n" + " \n" + " // barycentric coordinates:\n" + " b3FindPos(portal, pos);\n" + " return;\n" + " }\n" + " b3ExpandPortal(portal, &v4);\n" + " iterations++;\n" + " }\n" + "}\n" + "B3_STATIC void b3FindPenetrTouch(b3MprSimplex_t *portal,float *depth, b3Float4 *dir, b3Float4 *pos)\n" + "{\n" + " // Touching contact on portal's v1 - so depth is zero and direction\n" + " // is unimportant and pos can be guessed\n" + " *depth = 0.f;\n" + " b3Float4 zero = b3MakeFloat4(0,0,0,0);\n" + " b3Float4* b3mpr_vec3_origin = &zero;\n" + " b3MprVec3Copy(dir, b3mpr_vec3_origin);\n" + " b3MprVec3Copy(pos, &b3MprSimplexPoint(portal, 1)->v1);\n" + " b3MprVec3Add(pos, &b3MprSimplexPoint(portal, 1)->v2);\n" + " b3MprVec3Scale(pos, 0.5);\n" + "}\n" + "B3_STATIC void b3FindPenetrSegment(b3MprSimplex_t *portal,\n" + " float *depth, b3Float4 *dir, b3Float4 *pos)\n" + "{\n" + " \n" + " // Origin lies on v0-v1 segment.\n" + " // Depth is distance to v1, direction also and position must be\n" + " // computed\n" + " b3MprVec3Copy(pos, &b3MprSimplexPoint(portal, 1)->v1);\n" + " b3MprVec3Add(pos, &b3MprSimplexPoint(portal, 1)->v2);\n" + " b3MprVec3Scale(pos, 0.5f);\n" + " \n" + " b3MprVec3Copy(dir, &b3MprSimplexPoint(portal, 1)->v);\n" + " *depth = B3_MPR_SQRT(b3MprVec3Len2(dir));\n" + " b3MprVec3Normalize(dir);\n" + "}\n" + "inline int b3MprPenetration(int pairIndex, int bodyIndexA, int bodyIndexB,\n" + " b3ConstArray(b3RigidBodyData_t) cpuBodyBuf,\n" + " b3ConstArray(b3ConvexPolyhedronData_t) cpuConvexData, \n" + " b3ConstArray(b3Collidable_t) cpuCollidables,\n" + " b3ConstArray(b3Float4) cpuVertices,\n" + " __global b3Float4* sepAxis,\n" + " __global int* hasSepAxis,\n" + " float *depthOut, b3Float4* dirOut, b3Float4* posOut)\n" + "{\n" + " \n" + " b3MprSimplex_t portal;\n" + " \n" + "// if (!hasSepAxis[pairIndex])\n" + " // return -1;\n" + " \n" + " hasSepAxis[pairIndex] = 0;\n" + " int res;\n" + " // Phase 1: Portal discovery\n" + " res = b3DiscoverPortal(pairIndex,bodyIndexA,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices,sepAxis,hasSepAxis, &portal);\n" + " \n" + " \n" + " //sepAxis[pairIndex] = *pdir;//or -dir?\n" + " switch (res)\n" + " {\n" + " case 0:\n" + " {\n" + " // Phase 2: Portal refinement\n" + " \n" + " res = b3RefinePortal(pairIndex,bodyIndexA,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices, sepAxis,&portal);\n" + " if (res < 0)\n" + " return -1;\n" + " // Phase 3. Penetration info\n" + " b3FindPenetr(pairIndex,bodyIndexA,bodyIndexB,cpuBodyBuf,cpuConvexData,cpuCollidables,cpuVertices, sepAxis,&portal, depthOut, dirOut, posOut);\n" + " hasSepAxis[pairIndex] = 1;\n" + " sepAxis[pairIndex] = -*dirOut;\n" + " break;\n" + " }\n" + " case 1:\n" + " {\n" + " // Touching contact on portal's v1.\n" + " b3FindPenetrTouch(&portal, depthOut, dirOut, posOut);\n" + " break;\n" + " }\n" + " case 2:\n" + " {\n" + " \n" + " b3FindPenetrSegment( &portal, depthOut, dirOut, posOut);\n" + " break;\n" + " }\n" + " default:\n" + " {\n" + " hasSepAxis[pairIndex]=0;\n" + " //if (res < 0)\n" + " //{\n" + " // Origin isn't inside portal - no collision.\n" + " return -1;\n" + " //}\n" + " }\n" + " };\n" + " \n" + " return 0;\n" + "};\n" + "#endif //B3_MPR_PENETRATION_H\n" + "#ifndef B3_CONTACT4DATA_H\n" + "#define B3_CONTACT4DATA_H\n" + "#ifndef B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_FLOAT4_H\n" + "typedef struct b3Contact4Data b3Contact4Data_t;\n" + "struct b3Contact4Data\n" + "{\n" + " b3Float4 m_worldPosB[4];\n" + "// b3Float4 m_localPosA[4];\n" + "// b3Float4 m_localPosB[4];\n" + " b3Float4 m_worldNormalOnB; // w: m_nPoints\n" + " unsigned short m_restituitionCoeffCmp;\n" + " unsigned short m_frictionCoeffCmp;\n" + " int m_batchIdx;\n" + " int m_bodyAPtrAndSignBit;//x:m_bodyAPtr, y:m_bodyBPtr\n" + " int m_bodyBPtrAndSignBit;\n" + " int m_childIndexA;\n" + " int m_childIndexB;\n" + " int m_unused1;\n" + " int m_unused2;\n" + "};\n" + "inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact)\n" + "{\n" + " return (int)contact->m_worldNormalOnB.w;\n" + "};\n" + "inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints)\n" + "{\n" + " contact->m_worldNormalOnB.w = (float)numPoints;\n" + "};\n" + "#endif //B3_CONTACT4DATA_H\n" + "#define AppendInc(x, out) out = atomic_inc(x)\n" + "#define GET_NPOINTS(x) (x).m_worldNormalOnB.w\n" + "#ifdef cl_ext_atomic_counters_32\n" + " #pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n" + "#else\n" + " #define counter32_t volatile __global int*\n" + "#endif\n" + "__kernel void mprPenetrationKernel( __global int4* pairs,\n" + " __global const b3RigidBodyData_t* rigidBodies, \n" + " __global const b3Collidable_t* collidables,\n" + " __global const b3ConvexPolyhedronData_t* convexShapes, \n" + " __global const float4* vertices,\n" + " __global float4* separatingNormals,\n" + " __global int* hasSeparatingAxis,\n" + " __global struct b3Contact4Data* restrict globalContactsOut,\n" + " counter32_t nGlobalContactsOut,\n" + " int contactCapacity,\n" + " int numPairs)\n" + "{\n" + " int i = get_global_id(0);\n" + " int pairIndex = i;\n" + " if (im_worldNormalOnB = -dirOut;//normal;\n" + " c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" + " c->m_batchIdx = pairIndex;\n" + " int bodyA = pairs[pairIndex].x;\n" + " int bodyB = pairs[pairIndex].y;\n" + " c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0 ? -bodyA:bodyA;\n" + " c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0 ? -bodyB:bodyB;\n" + " c->m_childIndexA = -1;\n" + " c->m_childIndexB = -1;\n" + " //for (int i=0;im_worldPosB[0] = posOut;//localPoints[contactIdx[i]];\n" + " GET_NPOINTS(*c) = 1;//nContacts;\n" + " }\n" + " }\n" + " }\n" + "}\n" + "typedef float4 Quaternion;\n" + "#define make_float4 (float4)\n" + "__inline\n" + "float dot3F4(float4 a, float4 b)\n" + "{\n" + " float4 a1 = make_float4(a.xyz,0.f);\n" + " float4 b1 = make_float4(b.xyz,0.f);\n" + " return dot(a1, b1);\n" + "}\n" + "__inline\n" + "float4 cross3(float4 a, float4 b)\n" + "{\n" + " return cross(a,b);\n" + "}\n" + "__inline\n" + "Quaternion qtMul(Quaternion a, Quaternion b)\n" + "{\n" + " Quaternion ans;\n" + " ans = cross3( a, b );\n" + " ans += a.w*b+b.w*a;\n" + "// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" + " ans.w = a.w*b.w - dot3F4(a, b);\n" + " return ans;\n" + "}\n" + "__inline\n" + "Quaternion qtInvert(Quaternion q)\n" + "{\n" + " return (Quaternion)(-q.xyz, q.w);\n" + "}\n" + "__inline\n" + "float4 qtRotate(Quaternion q, float4 vec)\n" + "{\n" + " Quaternion qInv = qtInvert( q );\n" + " float4 vcpy = vec;\n" + " vcpy.w = 0.f;\n" + " float4 out = qtMul(qtMul(q,vcpy),qInv);\n" + " return out;\n" + "}\n" + "__inline\n" + "float4 transform(const float4* p, const float4* translation, const Quaternion* orientation)\n" + "{\n" + " return qtRotate( *orientation, *p ) + (*translation);\n" + "}\n" + "__inline\n" + "float4 qtInvRotate(const Quaternion q, float4 vec)\n" + "{\n" + " return qtRotate( qtInvert( q ), vec );\n" + "}\n" + "inline void project(__global const b3ConvexPolyhedronData_t* hull, const float4 pos, const float4 orn, \n" + "const float4* dir, __global const float4* vertices, float* min, float* max)\n" + "{\n" + " min[0] = FLT_MAX;\n" + " max[0] = -FLT_MAX;\n" + " int numVerts = hull->m_numVertices;\n" + " const float4 localDir = qtInvRotate(orn,*dir);\n" + " float offset = dot(pos,*dir);\n" + " for(int i=0;im_vertexOffset+i],localDir);\n" + " if(dp < min[0]) \n" + " min[0] = dp;\n" + " if(dp > max[0]) \n" + " max[0] = dp;\n" + " }\n" + " if(min[0]>max[0])\n" + " {\n" + " float tmp = min[0];\n" + " min[0] = max[0];\n" + " max[0] = tmp;\n" + " }\n" + " min[0] += offset;\n" + " max[0] += offset;\n" + "}\n" + "bool findSeparatingAxisUnitSphere( __global const b3ConvexPolyhedronData_t* hullA, __global const b3ConvexPolyhedronData_t* hullB, \n" + " const float4 posA1,\n" + " const float4 ornA,\n" + " const float4 posB1,\n" + " const float4 ornB,\n" + " const float4 DeltaC2,\n" + " __global const float4* vertices,\n" + " __global const float4* unitSphereDirections,\n" + " int numUnitSphereDirections,\n" + " float4* sep,\n" + " float* dmin)\n" + "{\n" + " \n" + " float4 posA = posA1;\n" + " posA.w = 0.f;\n" + " float4 posB = posB1;\n" + " posB.w = 0.f;\n" + " int curPlaneTests=0;\n" + " int curEdgeEdge = 0;\n" + " // Test unit sphere directions\n" + " for (int i=0;i0)\n" + " crossje *= -1.f;\n" + " {\n" + " float dist;\n" + " bool result = true;\n" + " float Min0,Max0;\n" + " float Min1,Max1;\n" + " project(hullA,posA,ornA,&crossje,vertices, &Min0, &Max0);\n" + " project(hullB,posB,ornB,&crossje,vertices, &Min1, &Max1);\n" + " \n" + " if(Max00.0f)\n" + " {\n" + " *sep = -(*sep);\n" + " }\n" + " return true;\n" + "}\n" + "__kernel void findSeparatingAxisUnitSphereKernel( __global const int4* pairs, \n" + " __global const b3RigidBodyData_t* rigidBodies, \n" + " __global const b3Collidable_t* collidables,\n" + " __global const b3ConvexPolyhedronData_t* convexShapes, \n" + " __global const float4* vertices,\n" + " __global const float4* unitSphereDirections,\n" + " __global float4* separatingNormals,\n" + " __global int* hasSeparatingAxis,\n" + " __global float* dmins,\n" + " int numUnitSphereDirections,\n" + " int numPairs\n" + " )\n" + "{\n" + " int i = get_global_id(0);\n" + " \n" + " if (inumUnitSphereDirections)\n" + " {\n" + " bool sepEE = findSeparatingAxisUnitSphere( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,\n" + " posB,ornB,\n" + " DeltaC2,\n" + " vertices,unitSphereDirections,numUnitSphereDirections,&sepNormal,&dmin);\n" + " if (!sepEE)\n" + " {\n" + " hasSeparatingAxis[i] = 0;\n" + " } else\n" + " {\n" + " hasSeparatingAxis[i] = 1;\n" + " separatingNormals[i] = sepNormal;\n" + " }\n" + " }\n" + " } //if (hasSeparatingAxis[i])\n" + " }//(i1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" -" return false;\n" -" return true;\n" -"}\n" -"inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" -"{\n" -" float maxDot = -B3_INFINITY;\n" -" int i = 0;\n" -" int ptIndex = -1;\n" -" for( i = 0; i < vecLen; i++ )\n" -" {\n" -" float dot = b3Dot3F4(vecArray[i],vec);\n" -" \n" -" if( dot > maxDot )\n" -" {\n" -" maxDot = dot;\n" -" ptIndex = i;\n" -" }\n" -" }\n" -" b3Assert(ptIndex>=0);\n" -" if (ptIndex<0)\n" -" {\n" -" ptIndex = 0;\n" -" }\n" -" *dotOut = maxDot;\n" -" return ptIndex;\n" -"}\n" -"#endif //B3_FLOAT4_H\n" -"typedef struct b3Contact4Data b3Contact4Data_t;\n" -"struct b3Contact4Data\n" -"{\n" -" b3Float4 m_worldPosB[4];\n" -"// b3Float4 m_localPosA[4];\n" -"// b3Float4 m_localPosB[4];\n" -" b3Float4 m_worldNormalOnB; // w: m_nPoints\n" -" unsigned short m_restituitionCoeffCmp;\n" -" unsigned short m_frictionCoeffCmp;\n" -" int m_batchIdx;\n" -" int m_bodyAPtrAndSignBit;//x:m_bodyAPtr, y:m_bodyBPtr\n" -" int m_bodyBPtrAndSignBit;\n" -" int m_childIndexA;\n" -" int m_childIndexB;\n" -" int m_unused1;\n" -" int m_unused2;\n" -"};\n" -"inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact)\n" -"{\n" -" return (int)contact->m_worldNormalOnB.w;\n" -"};\n" -"inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints)\n" -"{\n" -" contact->m_worldNormalOnB.w = (float)numPoints;\n" -"};\n" -"#endif //B3_CONTACT4DATA_H\n" -"#define SHAPE_CONVEX_HULL 3\n" -"#define SHAPE_PLANE 4\n" -"#define SHAPE_CONCAVE_TRIMESH 5\n" -"#define SHAPE_COMPOUND_OF_CONVEX_HULLS 6\n" -"#define SHAPE_SPHERE 7\n" -"#pragma OPENCL EXTENSION cl_amd_printf : enable\n" -"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n" -"#ifdef cl_ext_atomic_counters_32\n" -"#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n" -"#else\n" -"#define counter32_t volatile __global int*\n" -"#endif\n" -"#define GET_GROUP_IDX get_group_id(0)\n" -"#define GET_LOCAL_IDX get_local_id(0)\n" -"#define GET_GLOBAL_IDX get_global_id(0)\n" -"#define GET_GROUP_SIZE get_local_size(0)\n" -"#define GET_NUM_GROUPS get_num_groups(0)\n" -"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" -"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" -"#define AtomInc(x) atom_inc(&(x))\n" -"#define AtomInc1(x, out) out = atom_inc(&(x))\n" -"#define AppendInc(x, out) out = atomic_inc(x)\n" -"#define AtomAdd(x, value) atom_add(&(x), value)\n" -"#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n" -"#define AtomXhg(x, value) atom_xchg ( &(x), value )\n" -"#define max2 max\n" -"#define min2 min\n" -"typedef unsigned int u32;\n" -"typedef struct \n" -"{\n" -" union\n" -" {\n" -" float4 m_min;\n" -" float m_minElems[4];\n" -" int m_minIndices[4];\n" -" };\n" -" union\n" -" {\n" -" float4 m_max;\n" -" float m_maxElems[4];\n" -" int m_maxIndices[4];\n" -" };\n" -"} btAabbCL;\n" -"///keep this in sync with btCollidable.h\n" -"typedef struct\n" -"{\n" -" int m_numChildShapes;\n" -" float m_radius;\n" -" int m_shapeType;\n" -" int m_shapeIndex;\n" -" \n" -"} btCollidableGpu;\n" -"typedef struct\n" -"{\n" -" float4 m_childPosition;\n" -" float4 m_childOrientation;\n" -" int m_shapeIndex;\n" -" int m_unused0;\n" -" int m_unused1;\n" -" int m_unused2;\n" -"} btGpuChildShape;\n" -"#define GET_NPOINTS(x) (x).m_worldNormalOnB.w\n" -"typedef struct\n" -"{\n" -" float4 m_pos;\n" -" float4 m_quat;\n" -" float4 m_linVel;\n" -" float4 m_angVel;\n" -" u32 m_collidableIdx; \n" -" float m_invMass;\n" -" float m_restituitionCoeff;\n" -" float m_frictionCoeff;\n" -"} BodyData;\n" -"typedef struct \n" -"{\n" -" float4 m_localCenter;\n" -" float4 m_extents;\n" -" float4 mC;\n" -" float4 mE;\n" -" \n" -" float m_radius;\n" -" int m_faceOffset;\n" -" int m_numFaces;\n" -" int m_numVertices;\n" -" \n" -" int m_vertexOffset;\n" -" int m_uniqueEdgesOffset;\n" -" int m_numUniqueEdges;\n" -" int m_unused;\n" -"} ConvexPolyhedronCL;\n" -"typedef struct\n" -"{\n" -" float4 m_plane;\n" -" int m_indexOffset;\n" -" int m_numIndices;\n" -"} btGpuFace;\n" -"#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n" -"#define make_float4 (float4)\n" -"#define make_float2 (float2)\n" -"#define make_uint4 (uint4)\n" -"#define make_int4 (int4)\n" -"#define make_uint2 (uint2)\n" -"#define make_int2 (int2)\n" -"__inline\n" -"float fastDiv(float numerator, float denominator)\n" -"{\n" -" return native_divide(numerator, denominator); \n" -"// return numerator/denominator; \n" -"}\n" -"__inline\n" -"float4 fastDiv4(float4 numerator, float4 denominator)\n" -"{\n" -" return native_divide(numerator, denominator); \n" -"}\n" -"__inline\n" -"float4 cross3(float4 a, float4 b)\n" -"{\n" -" return cross(a,b);\n" -"}\n" -"//#define dot3F4 dot\n" -"__inline\n" -"float dot3F4(float4 a, float4 b)\n" -"{\n" -" float4 a1 = make_float4(a.xyz,0.f);\n" -" float4 b1 = make_float4(b.xyz,0.f);\n" -" return dot(a1, b1);\n" -"}\n" -"__inline\n" -"float4 fastNormalize4(float4 v)\n" -"{\n" -" return fast_normalize(v);\n" -"}\n" -"///////////////////////////////////////\n" -"// Quaternion\n" -"///////////////////////////////////////\n" -"typedef float4 Quaternion;\n" -"__inline\n" -"Quaternion qtMul(Quaternion a, Quaternion b);\n" -"__inline\n" -"Quaternion qtNormalize(Quaternion in);\n" -"__inline\n" -"float4 qtRotate(Quaternion q, float4 vec);\n" -"__inline\n" -"Quaternion qtInvert(Quaternion q);\n" -"__inline\n" -"Quaternion qtMul(Quaternion a, Quaternion b)\n" -"{\n" -" Quaternion ans;\n" -" ans = cross3( a, b );\n" -" ans += a.w*b+b.w*a;\n" -"// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" -" ans.w = a.w*b.w - dot3F4(a, b);\n" -" return ans;\n" -"}\n" -"__inline\n" -"Quaternion qtNormalize(Quaternion in)\n" -"{\n" -" return fastNormalize4(in);\n" -"// in /= length( in );\n" -"// return in;\n" -"}\n" -"__inline\n" -"float4 qtRotate(Quaternion q, float4 vec)\n" -"{\n" -" Quaternion qInv = qtInvert( q );\n" -" float4 vcpy = vec;\n" -" vcpy.w = 0.f;\n" -" float4 out = qtMul(qtMul(q,vcpy),qInv);\n" -" return out;\n" -"}\n" -"__inline\n" -"Quaternion qtInvert(Quaternion q)\n" -"{\n" -" return (Quaternion)(-q.xyz, q.w);\n" -"}\n" -"__inline\n" -"float4 qtInvRotate(const Quaternion q, float4 vec)\n" -"{\n" -" return qtRotate( qtInvert( q ), vec );\n" -"}\n" -"__inline\n" -"float4 transform(const float4* p, const float4* translation, const Quaternion* orientation)\n" -"{\n" -" return qtRotate( *orientation, *p ) + (*translation);\n" -"}\n" -"void trInverse(float4 translationIn, Quaternion orientationIn,\n" -" float4* translationOut, Quaternion* orientationOut)\n" -"{\n" -" *orientationOut = qtInvert(orientationIn);\n" -" *translationOut = qtRotate(*orientationOut, -translationIn);\n" -"}\n" -"void trMul(float4 translationA, Quaternion orientationA,\n" -" float4 translationB, Quaternion orientationB,\n" -" float4* translationOut, Quaternion* orientationOut)\n" -"{\n" -" *orientationOut = qtMul(orientationA,orientationB);\n" -" *translationOut = transform(&translationB,&translationA,&orientationA);\n" -"}\n" -"__inline\n" -"float4 normalize3(const float4 a)\n" -"{\n" -" float4 n = make_float4(a.x, a.y, a.z, 0.f);\n" -" return fastNormalize4( n );\n" -"}\n" -"__inline float4 lerp3(const float4 a,const float4 b, float t)\n" -"{\n" -" return make_float4( a.x + (b.x - a.x) * t,\n" -" a.y + (b.y - a.y) * t,\n" -" a.z + (b.z - a.z) * t,\n" -" 0.f);\n" -"}\n" -"float signedDistanceFromPointToPlane(float4 point, float4 planeEqn, float4* closestPointOnFace)\n" -"{\n" -" float4 n = (float4)(planeEqn.x, planeEqn.y, planeEqn.z, 0);\n" -" float dist = dot3F4(n, point) + planeEqn.w;\n" -" *closestPointOnFace = point - dist * n;\n" -" return dist;\n" -"}\n" -"inline bool IsPointInPolygon(float4 p, \n" -" const btGpuFace* face,\n" -" __global const float4* baseVertex,\n" -" __global const int* convexIndices,\n" -" float4* out)\n" -"{\n" -" float4 a;\n" -" float4 b;\n" -" float4 ab;\n" -" float4 ap;\n" -" float4 v;\n" -" float4 plane = make_float4(face->m_plane.x,face->m_plane.y,face->m_plane.z,0.f);\n" -" \n" -" if (face->m_numIndices<2)\n" -" return false;\n" -" \n" -" float4 v0 = baseVertex[convexIndices[face->m_indexOffset + face->m_numIndices-1]];\n" -" \n" -" b = v0;\n" -" for(unsigned i=0; i != face->m_numIndices; ++i)\n" -" {\n" -" a = b;\n" -" float4 vi = baseVertex[convexIndices[face->m_indexOffset + i]];\n" -" b = vi;\n" -" ab = b-a;\n" -" ap = p-a;\n" -" v = cross3(ab,plane);\n" -" if (dot(ap, v) > 0.f)\n" -" {\n" -" float ab_m2 = dot(ab, ab);\n" -" float rt = ab_m2 != 0.f ? dot(ab, ap) / ab_m2 : 0.f;\n" -" if (rt <= 0.f)\n" -" {\n" -" *out = a;\n" -" }\n" -" else if (rt >= 1.f) \n" -" {\n" -" *out = b;\n" -" }\n" -" else\n" -" {\n" -" float s = 1.f - rt;\n" -" out[0].x = s * a.x + rt * b.x;\n" -" out[0].y = s * a.y + rt * b.y;\n" -" out[0].z = s * a.z + rt * b.z;\n" -" }\n" -" return false;\n" -" }\n" -" }\n" -" return true;\n" -"}\n" -"void computeContactSphereConvex(int pairIndex,\n" -" int bodyIndexA, int bodyIndexB, \n" -" int collidableIndexA, int collidableIndexB, \n" -" __global const BodyData* rigidBodies, \n" -" __global const btCollidableGpu* collidables,\n" -" __global const ConvexPolyhedronCL* convexShapes,\n" -" __global const float4* convexVertices,\n" -" __global const int* convexIndices,\n" -" __global const btGpuFace* faces,\n" -" __global struct b3Contact4Data* restrict globalContactsOut,\n" -" counter32_t nGlobalContactsOut,\n" -" int maxContactCapacity,\n" -" float4 spherePos2,\n" -" float radius,\n" -" float4 pos,\n" -" float4 quat\n" -" )\n" -"{\n" -" float4 invPos;\n" -" float4 invOrn;\n" -" trInverse(pos,quat, &invPos,&invOrn);\n" -" float4 spherePos = transform(&spherePos2,&invPos,&invOrn);\n" -" int shapeIndex = collidables[collidableIndexB].m_shapeIndex;\n" -" int numFaces = convexShapes[shapeIndex].m_numFaces;\n" -" float4 closestPnt = (float4)(0, 0, 0, 0);\n" -" float4 hitNormalWorld = (float4)(0, 0, 0, 0);\n" -" float minDist = -1000000.f;\n" -" bool bCollide = true;\n" -" for ( int f = 0; f < numFaces; f++ )\n" -" {\n" -" btGpuFace face = faces[convexShapes[shapeIndex].m_faceOffset+f];\n" -" // set up a plane equation \n" -" float4 planeEqn;\n" -" float4 n1 = face.m_plane;\n" -" n1.w = 0.f;\n" -" planeEqn = n1;\n" -" planeEqn.w = face.m_plane.w;\n" -" \n" -" \n" -" // compute a signed distance from the vertex in cloth to the face of rigidbody.\n" -" float4 pntReturn;\n" -" float dist = signedDistanceFromPointToPlane(spherePos, planeEqn, &pntReturn);\n" -" // If the distance is positive, the plane is a separating plane. \n" -" if ( dist > radius )\n" -" {\n" -" bCollide = false;\n" -" break;\n" -" }\n" -" if (dist>0)\n" -" {\n" -" //might hit an edge or vertex\n" -" float4 out;\n" -" float4 zeroPos = make_float4(0,0,0,0);\n" -" bool isInPoly = IsPointInPolygon(spherePos,\n" -" &face,\n" -" &convexVertices[convexShapes[shapeIndex].m_vertexOffset],\n" -" convexIndices,\n" -" &out);\n" -" if (isInPoly)\n" -" {\n" -" if (dist>minDist)\n" -" {\n" -" minDist = dist;\n" -" closestPnt = pntReturn;\n" -" hitNormalWorld = planeEqn;\n" -" \n" -" }\n" -" } else\n" -" {\n" -" float4 tmp = spherePos-out;\n" -" float l2 = dot(tmp,tmp);\n" -" if (l2minDist)\n" -" {\n" -" minDist = dist;\n" -" closestPnt = out;\n" -" hitNormalWorld = tmp/dist;\n" -" \n" -" }\n" -" \n" -" } else\n" -" {\n" -" bCollide = false;\n" -" break;\n" -" }\n" -" }\n" -" } else\n" -" {\n" -" if ( dist > minDist )\n" -" {\n" -" minDist = dist;\n" -" closestPnt = pntReturn;\n" -" hitNormalWorld.xyz = planeEqn.xyz;\n" -" }\n" -" }\n" -" \n" -" }\n" -" \n" -" if (bCollide && minDist > -10000)\n" -" {\n" -" float4 normalOnSurfaceB1 = qtRotate(quat,-hitNormalWorld);\n" -" float4 pOnB1 = transform(&closestPnt,&pos,&quat);\n" -" \n" -" float actualDepth = minDist-radius;\n" -" if (actualDepth<=0.f)\n" -" {\n" -" \n" -" pOnB1.w = actualDepth;\n" -" int dstIdx;\n" -" AppendInc( nGlobalContactsOut, dstIdx );\n" -" \n" -" \n" -" if (1)//dstIdx < maxContactCapacity)\n" -" {\n" -" __global struct b3Contact4Data* c = &globalContactsOut[dstIdx];\n" -" c->m_worldNormalOnB = -normalOnSurfaceB1;\n" -" c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" -" c->m_batchIdx = pairIndex;\n" -" c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass==0?-bodyIndexA:bodyIndexA;\n" -" c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass==0?-bodyIndexB:bodyIndexB;\n" -" c->m_worldPosB[0] = pOnB1;\n" -" c->m_childIndexA = -1;\n" -" c->m_childIndexB = -1;\n" -" GET_NPOINTS(*c) = 1;\n" -" } \n" -" }\n" -" }//if (hasCollision)\n" -"}\n" -" \n" -"int extractManifoldSequential(const float4* p, int nPoints, float4 nearNormal, int4* contactIdx)\n" -"{\n" -" if( nPoints == 0 )\n" -" return 0;\n" -" \n" -" if (nPoints <=4)\n" -" return nPoints;\n" -" \n" -" \n" -" if (nPoints >64)\n" -" nPoints = 64;\n" -" \n" -" float4 center = make_float4(0.f);\n" -" {\n" -" \n" -" for (int i=0;im_numVertices;i++)\n" -" {\n" -" float4 vtx = convexVertices[hullB->m_vertexOffset+i];\n" -" float curDot = dot(vtx,planeNormalInConvex);\n" -" if (curDot>maxDot)\n" -" {\n" -" hitVertex=i;\n" -" maxDot=curDot;\n" -" hitVtx = vtx;\n" -" //make sure the deepest points is always included\n" -" if (numPoints==MAX_PLANE_CONVEX_POINTS)\n" -" numPoints--;\n" -" }\n" -" if (numPoints4)\n" -" {\n" -" numReducedPoints = extractManifoldSequential( contactPoints, numPoints, planeNormalInConvex, &contactIdx);\n" -" }\n" -" if (numReducedPoints>0)\n" -" {\n" -" int dstIdx;\n" -" AppendInc( nGlobalContactsOut, dstIdx );\n" -" if (dstIdx < maxContactCapacity)\n" -" {\n" -" resultIndex = dstIdx;\n" -" __global struct b3Contact4Data* c = &globalContactsOut[dstIdx];\n" -" c->m_worldNormalOnB = -planeNormalWorld;\n" -" //c->setFrictionCoeff(0.7);\n" -" //c->setRestituitionCoeff(0.f);\n" -" c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" -" c->m_batchIdx = pairIndex;\n" -" c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass==0?-bodyIndexA:bodyIndexA;\n" -" c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass==0?-bodyIndexB:bodyIndexB;\n" -" c->m_childIndexA = -1;\n" -" c->m_childIndexB = -1;\n" -" switch (numReducedPoints)\n" -" {\n" -" case 4:\n" -" c->m_worldPosB[3] = contactPoints[contactIdx.w];\n" -" case 3:\n" -" c->m_worldPosB[2] = contactPoints[contactIdx.z];\n" -" case 2:\n" -" c->m_worldPosB[1] = contactPoints[contactIdx.y];\n" -" case 1:\n" -" c->m_worldPosB[0] = contactPoints[contactIdx.x];\n" -" default:\n" -" {\n" -" }\n" -" };\n" -" \n" -" GET_NPOINTS(*c) = numReducedPoints;\n" -" }//if (dstIdx < numPairs)\n" -" } \n" -" return resultIndex;\n" -"}\n" -"void computeContactPlaneSphere(int pairIndex,\n" -" int bodyIndexA, int bodyIndexB, \n" -" int collidableIndexA, int collidableIndexB, \n" -" __global const BodyData* rigidBodies, \n" -" __global const btCollidableGpu* collidables,\n" -" __global const btGpuFace* faces,\n" -" __global struct b3Contact4Data* restrict globalContactsOut,\n" -" counter32_t nGlobalContactsOut,\n" -" int maxContactCapacity)\n" -"{\n" -" float4 planeEq = faces[collidables[collidableIndexA].m_shapeIndex].m_plane;\n" -" float radius = collidables[collidableIndexB].m_radius;\n" -" float4 posA1 = rigidBodies[bodyIndexA].m_pos;\n" -" float4 ornA1 = rigidBodies[bodyIndexA].m_quat;\n" -" float4 posB1 = rigidBodies[bodyIndexB].m_pos;\n" -" float4 ornB1 = rigidBodies[bodyIndexB].m_quat;\n" -" \n" -" bool hasCollision = false;\n" -" float4 planeNormal1 = make_float4(planeEq.x,planeEq.y,planeEq.z,0.f);\n" -" float planeConstant = planeEq.w;\n" -" float4 convexInPlaneTransPos1; Quaternion convexInPlaneTransOrn1;\n" -" {\n" -" float4 invPosA;Quaternion invOrnA;\n" -" trInverse(posA1,ornA1,&invPosA,&invOrnA);\n" -" trMul(invPosA,invOrnA,posB1,ornB1,&convexInPlaneTransPos1,&convexInPlaneTransOrn1);\n" -" }\n" -" float4 planeInConvexPos1; Quaternion planeInConvexOrn1;\n" -" {\n" -" float4 invPosB;Quaternion invOrnB;\n" -" trInverse(posB1,ornB1,&invPosB,&invOrnB);\n" -" trMul(invPosB,invOrnB,posA1,ornA1,&planeInConvexPos1,&planeInConvexOrn1); \n" -" }\n" -" float4 vtx1 = qtRotate(planeInConvexOrn1,-planeNormal1)*radius;\n" -" float4 vtxInPlane1 = transform(&vtx1,&convexInPlaneTransPos1,&convexInPlaneTransOrn1);\n" -" float distance = dot3F4(planeNormal1,vtxInPlane1) - planeConstant;\n" -" hasCollision = distance < 0.f;//m_manifoldPtr->getContactBreakingThreshold();\n" -" if (hasCollision)\n" -" {\n" -" float4 vtxInPlaneProjected1 = vtxInPlane1 - distance*planeNormal1;\n" -" float4 vtxInPlaneWorld1 = transform(&vtxInPlaneProjected1,&posA1,&ornA1);\n" -" float4 normalOnSurfaceB1 = qtRotate(ornA1,planeNormal1);\n" -" float4 pOnB1 = vtxInPlaneWorld1+normalOnSurfaceB1*distance;\n" -" pOnB1.w = distance;\n" -" int dstIdx;\n" -" AppendInc( nGlobalContactsOut, dstIdx );\n" -" \n" -" if (dstIdx < maxContactCapacity)\n" -" {\n" -" __global struct b3Contact4Data* c = &globalContactsOut[dstIdx];\n" -" c->m_worldNormalOnB = -normalOnSurfaceB1;\n" -" c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" -" c->m_batchIdx = pairIndex;\n" -" c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass==0?-bodyIndexA:bodyIndexA;\n" -" c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass==0?-bodyIndexB:bodyIndexB;\n" -" c->m_worldPosB[0] = pOnB1;\n" -" c->m_childIndexA = -1;\n" -" c->m_childIndexB = -1;\n" -" GET_NPOINTS(*c) = 1;\n" -" }//if (dstIdx < numPairs)\n" -" }//if (hasCollision)\n" -"}\n" -"__kernel void primitiveContactsKernel( __global int4* pairs, \n" -" __global const BodyData* rigidBodies, \n" -" __global const btCollidableGpu* collidables,\n" -" __global const ConvexPolyhedronCL* convexShapes, \n" -" __global const float4* vertices,\n" -" __global const float4* uniqueEdges,\n" -" __global const btGpuFace* faces,\n" -" __global const int* indices,\n" -" __global struct b3Contact4Data* restrict globalContactsOut,\n" -" counter32_t nGlobalContactsOut,\n" -" int numPairs, int maxContactCapacity)\n" -"{\n" -" int i = get_global_id(0);\n" -" int pairIndex = i;\n" -" \n" -" float4 worldVertsB1[64];\n" -" float4 worldVertsB2[64];\n" -" int capacityWorldVerts = 64; \n" -" float4 localContactsOut[64];\n" -" int localContactCapacity=64;\n" -" \n" -" float minDist = -1e30f;\n" -" float maxDist = 0.02f;\n" -" if (i=0)\n" -" pairs[pairIndex].z = contactIndex;\n" -" return;\n" -" }\n" -" if (collidables[collidableIndexA].m_shapeType == SHAPE_CONVEX_HULL &&\n" -" collidables[collidableIndexB].m_shapeType == SHAPE_PLANE)\n" -" {\n" -" float4 posA;\n" -" posA = rigidBodies[bodyIndexA].m_pos;\n" -" Quaternion ornA;\n" -" ornA = rigidBodies[bodyIndexA].m_quat;\n" -" int contactIndex = computeContactPlaneConvex( pairIndex, bodyIndexB,bodyIndexA, collidableIndexB,collidableIndexA, \n" -" rigidBodies,collidables,convexShapes,vertices,indices,\n" -" faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity,posA,ornA);\n" -" if (contactIndex>=0)\n" -" pairs[pairIndex].z = contactIndex;\n" -" return;\n" -" }\n" -" if (collidables[collidableIndexA].m_shapeType == SHAPE_PLANE &&\n" -" collidables[collidableIndexB].m_shapeType == SHAPE_SPHERE)\n" -" {\n" -" computeContactPlaneSphere(pairIndex, bodyIndexA, bodyIndexB, collidableIndexA, collidableIndexB, \n" -" rigidBodies,collidables,faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity);\n" -" return;\n" -" }\n" -" if (collidables[collidableIndexA].m_shapeType == SHAPE_SPHERE &&\n" -" collidables[collidableIndexB].m_shapeType == SHAPE_PLANE)\n" -" {\n" -" computeContactPlaneSphere( pairIndex, bodyIndexB,bodyIndexA, collidableIndexB,collidableIndexA, \n" -" rigidBodies,collidables,\n" -" faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity);\n" -" return;\n" -" }\n" -" \n" -" \n" -" if (collidables[collidableIndexA].m_shapeType == SHAPE_SPHERE &&\n" -" collidables[collidableIndexB].m_shapeType == SHAPE_CONVEX_HULL)\n" -" {\n" -" \n" -" float4 spherePos = rigidBodies[bodyIndexA].m_pos;\n" -" float sphereRadius = collidables[collidableIndexA].m_radius;\n" -" float4 convexPos = rigidBodies[bodyIndexB].m_pos;\n" -" float4 convexOrn = rigidBodies[bodyIndexB].m_quat;\n" -" computeContactSphereConvex(pairIndex, bodyIndexA, bodyIndexB, collidableIndexA, collidableIndexB, \n" -" rigidBodies,collidables,convexShapes,vertices,indices,faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity,\n" -" spherePos,sphereRadius,convexPos,convexOrn);\n" -" return;\n" -" }\n" -" if (collidables[collidableIndexA].m_shapeType == SHAPE_CONVEX_HULL &&\n" -" collidables[collidableIndexB].m_shapeType == SHAPE_SPHERE)\n" -" {\n" -" \n" -" float4 spherePos = rigidBodies[bodyIndexB].m_pos;\n" -" float sphereRadius = collidables[collidableIndexB].m_radius;\n" -" float4 convexPos = rigidBodies[bodyIndexA].m_pos;\n" -" float4 convexOrn = rigidBodies[bodyIndexA].m_quat;\n" -" computeContactSphereConvex(pairIndex, bodyIndexB, bodyIndexA, collidableIndexB, collidableIndexA, \n" -" rigidBodies,collidables,convexShapes,vertices,indices,faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity,\n" -" spherePos,sphereRadius,convexPos,convexOrn);\n" -" return;\n" -" }\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" if (collidables[collidableIndexA].m_shapeType == SHAPE_SPHERE &&\n" -" collidables[collidableIndexB].m_shapeType == SHAPE_SPHERE)\n" -" {\n" -" //sphere-sphere\n" -" float radiusA = collidables[collidableIndexA].m_radius;\n" -" float radiusB = collidables[collidableIndexB].m_radius;\n" -" float4 posA = rigidBodies[bodyIndexA].m_pos;\n" -" float4 posB = rigidBodies[bodyIndexB].m_pos;\n" -" float4 diff = posA-posB;\n" -" float len = length(diff);\n" -" \n" -" ///iff distance positive, don't generate a new contact\n" -" if ( len <= (radiusA+radiusB))\n" -" {\n" -" ///distance (negative means penetration)\n" -" float dist = len - (radiusA+radiusB);\n" -" float4 normalOnSurfaceB = make_float4(1.f,0.f,0.f,0.f);\n" -" if (len > 0.00001)\n" -" {\n" -" normalOnSurfaceB = diff / len;\n" -" }\n" -" float4 contactPosB = posB + normalOnSurfaceB*radiusB;\n" -" contactPosB.w = dist;\n" -" \n" -" int dstIdx;\n" -" AppendInc( nGlobalContactsOut, dstIdx );\n" -" \n" -" if (dstIdx < maxContactCapacity)\n" -" {\n" -" __global struct b3Contact4Data* c = &globalContactsOut[dstIdx];\n" -" c->m_worldNormalOnB = normalOnSurfaceB;\n" -" c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" -" c->m_batchIdx = pairIndex;\n" -" int bodyA = pairs[pairIndex].x;\n" -" int bodyB = pairs[pairIndex].y;\n" -" c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA;\n" -" c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB;\n" -" c->m_worldPosB[0] = contactPosB;\n" -" c->m_childIndexA = -1;\n" -" c->m_childIndexB = -1;\n" -" GET_NPOINTS(*c) = 1;\n" -" }//if (dstIdx < numPairs)\n" -" }//if ( len <= (radiusA+radiusB))\n" -" return;\n" -" }//SHAPE_SPHERE SHAPE_SPHERE\n" -" }// if (i= 0)\n" -" {\n" -" collidableIndexA = gpuChildShapes[childShapeIndexA].m_shapeIndex;\n" -" float4 childPosA = gpuChildShapes[childShapeIndexA].m_childPosition;\n" -" float4 childOrnA = gpuChildShapes[childShapeIndexA].m_childOrientation;\n" -" float4 newPosA = qtRotate(ornA,childPosA)+posA;\n" -" float4 newOrnA = qtMul(ornA,childOrnA);\n" -" posA = newPosA;\n" -" ornA = newOrnA;\n" -" } else\n" -" {\n" -" collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;\n" -" }\n" -" \n" -" if (childShapeIndexB>=0)\n" -" {\n" -" collidableIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex;\n" -" float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition;\n" -" float4 childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation;\n" -" float4 newPosB = transform(&childPosB,&posB,&ornB);\n" -" float4 newOrnB = qtMul(ornB,childOrnB);\n" -" posB = newPosB;\n" -" ornB = newOrnB;\n" -" } else\n" -" {\n" -" collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx; \n" -" }\n" -" \n" -" int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;\n" -" int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;\n" -" \n" -" int shapeTypeA = collidables[collidableIndexA].m_shapeType;\n" -" int shapeTypeB = collidables[collidableIndexB].m_shapeType;\n" -" int pairIndex = i;\n" -" if ((shapeTypeA == SHAPE_PLANE) && (shapeTypeB==SHAPE_CONVEX_HULL))\n" -" {\n" -" computeContactPlaneConvex( pairIndex, bodyIndexA,bodyIndexB, collidableIndexA,collidableIndexB, \n" -" rigidBodies,collidables,convexShapes,vertices,indices,\n" -" faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity,posB,ornB);\n" -" return;\n" -" }\n" -" if ((shapeTypeA == SHAPE_CONVEX_HULL) && (shapeTypeB==SHAPE_PLANE))\n" -" {\n" -" computeContactPlaneConvex( pairIndex, bodyIndexB,bodyIndexA, collidableIndexB,collidableIndexA, \n" -" rigidBodies,collidables,convexShapes,vertices,indices,\n" -" faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity,posA,ornA);\n" -" return;\n" -" }\n" -" if ((shapeTypeA == SHAPE_CONVEX_HULL) && (shapeTypeB == SHAPE_SPHERE))\n" -" {\n" -" float4 spherePos = rigidBodies[bodyIndexB].m_pos;\n" -" float sphereRadius = collidables[collidableIndexB].m_radius;\n" -" float4 convexPos = posA;\n" -" float4 convexOrn = ornA;\n" -" \n" -" computeContactSphereConvex(pairIndex, bodyIndexB, bodyIndexA , collidableIndexB,collidableIndexA, \n" -" rigidBodies,collidables,convexShapes,vertices,indices,faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity,\n" -" spherePos,sphereRadius,convexPos,convexOrn);\n" -" \n" -" return;\n" -" }\n" -" if ((shapeTypeA == SHAPE_SPHERE) && (shapeTypeB == SHAPE_CONVEX_HULL))\n" -" {\n" -" float4 spherePos = rigidBodies[bodyIndexA].m_pos;\n" -" float sphereRadius = collidables[collidableIndexA].m_radius;\n" -" float4 convexPos = posB;\n" -" float4 convexOrn = ornB;\n" -" \n" -" computeContactSphereConvex(pairIndex, bodyIndexA, bodyIndexB, collidableIndexA, collidableIndexB, \n" -" rigidBodies,collidables,convexShapes,vertices,indices,faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity,\n" -" spherePos,sphereRadius,convexPos,convexOrn);\n" -" \n" -" return;\n" -" }\n" -" }// if (i 0 && r2 > 0 && r3 > 0 )\n" -" return true;\n" -" if ( r1 <= 0 && r2 <= 0 && r3 <= 0 ) \n" -" return true;\n" -" return false;\n" -"}\n" -"float segmentSqrDistance(float4 from, float4 to,float4 p, float4* nearest) \n" -"{\n" -" float4 diff = p - from;\n" -" float4 v = to - from;\n" -" float t = dot(v,diff);\n" -" \n" -" if (t > 0) \n" -" {\n" -" float dotVV = dot(v,v);\n" -" if (t < dotVV) \n" -" {\n" -" t /= dotVV;\n" -" diff -= t*v;\n" -" } else \n" -" {\n" -" t = 1;\n" -" diff -= v;\n" -" }\n" -" } else\n" -" {\n" -" t = 0;\n" -" }\n" -" *nearest = from + t*v;\n" -" return dot(diff,diff); \n" -"}\n" -"void computeContactSphereTriangle(int pairIndex,\n" -" int bodyIndexA, int bodyIndexB,\n" -" int collidableIndexA, int collidableIndexB, \n" -" __global const BodyData* rigidBodies, \n" -" __global const btCollidableGpu* collidables,\n" -" const float4* triangleVertices,\n" -" __global struct b3Contact4Data* restrict globalContactsOut,\n" -" counter32_t nGlobalContactsOut,\n" -" int maxContactCapacity,\n" -" float4 spherePos2,\n" -" float radius,\n" -" float4 pos,\n" -" float4 quat,\n" -" int faceIndex\n" -" )\n" -"{\n" -" float4 invPos;\n" -" float4 invOrn;\n" -" trInverse(pos,quat, &invPos,&invOrn);\n" -" float4 spherePos = transform(&spherePos2,&invPos,&invOrn);\n" -" int numFaces = 3;\n" -" float4 closestPnt = (float4)(0, 0, 0, 0);\n" -" float4 hitNormalWorld = (float4)(0, 0, 0, 0);\n" -" float minDist = -1000000.f;\n" -" bool bCollide = false;\n" -" \n" -" //////////////////////////////////////\n" -" float4 sphereCenter;\n" -" sphereCenter = spherePos;\n" -" const float4* vertices = triangleVertices;\n" -" float contactBreakingThreshold = 0.f;//todo?\n" -" float radiusWithThreshold = radius + contactBreakingThreshold;\n" -" float4 edge10;\n" -" edge10 = vertices[1]-vertices[0];\n" -" edge10.w = 0.f;//is this needed?\n" -" float4 edge20;\n" -" edge20 = vertices[2]-vertices[0];\n" -" edge20.w = 0.f;//is this needed?\n" -" float4 normal = cross3(edge10,edge20);\n" -" normal = normalize(normal);\n" -" float4 p1ToCenter;\n" -" p1ToCenter = sphereCenter - vertices[0];\n" -" \n" -" float distanceFromPlane = dot(p1ToCenter,normal);\n" -" if (distanceFromPlane < 0.f)\n" -" {\n" -" //triangle facing the other way\n" -" distanceFromPlane *= -1.f;\n" -" normal *= -1.f;\n" -" }\n" -" hitNormalWorld = normal;\n" -" bool isInsideContactPlane = distanceFromPlane < radiusWithThreshold;\n" -" \n" -" // Check for contact / intersection\n" -" bool hasContact = false;\n" -" float4 contactPoint;\n" -" if (isInsideContactPlane) \n" -" {\n" -" \n" -" if (pointInTriangle(vertices,&normal, &sphereCenter)) \n" -" {\n" -" // Inside the contact wedge - touches a point on the shell plane\n" -" hasContact = true;\n" -" contactPoint = sphereCenter - normal*distanceFromPlane;\n" -" \n" -" } else {\n" -" // Could be inside one of the contact capsules\n" -" float contactCapsuleRadiusSqr = radiusWithThreshold*radiusWithThreshold;\n" -" float4 nearestOnEdge;\n" -" int numEdges = 3;\n" -" for (int i = 0; i < numEdges; i++) \n" -" {\n" -" float4 pa =vertices[i];\n" -" float4 pb = vertices[(i+1)%3];\n" -" float distanceSqr = segmentSqrDistance(pa,pb,sphereCenter, &nearestOnEdge);\n" -" if (distanceSqr < contactCapsuleRadiusSqr) \n" -" {\n" -" // Yep, we're inside a capsule\n" -" hasContact = true;\n" -" contactPoint = nearestOnEdge;\n" -" \n" -" }\n" -" \n" -" }\n" -" }\n" -" }\n" -" if (hasContact) \n" -" {\n" -" closestPnt = contactPoint;\n" -" float4 contactToCenter = sphereCenter - contactPoint;\n" -" minDist = length(contactToCenter);\n" -" if (minDist>FLT_EPSILON)\n" -" {\n" -" hitNormalWorld = normalize(contactToCenter);//*(1./minDist);\n" -" bCollide = true;\n" -" }\n" -" \n" -" }\n" -" /////////////////////////////////////\n" -" if (bCollide && minDist > -10000)\n" -" {\n" -" \n" -" float4 normalOnSurfaceB1 = qtRotate(quat,-hitNormalWorld);\n" -" float4 pOnB1 = transform(&closestPnt,&pos,&quat);\n" -" float actualDepth = minDist-radius;\n" -" \n" -" if (actualDepth<=0.f)\n" -" {\n" -" pOnB1.w = actualDepth;\n" -" int dstIdx;\n" -" \n" -" float lenSqr = dot3F4(normalOnSurfaceB1,normalOnSurfaceB1);\n" -" if (lenSqr>FLT_EPSILON)\n" -" {\n" -" AppendInc( nGlobalContactsOut, dstIdx );\n" -" \n" -" if (dstIdx < maxContactCapacity)\n" -" {\n" -" __global struct b3Contact4Data* c = &globalContactsOut[dstIdx];\n" -" c->m_worldNormalOnB = -normalOnSurfaceB1;\n" -" c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" -" c->m_batchIdx = pairIndex;\n" -" c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass==0?-bodyIndexA:bodyIndexA;\n" -" c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass==0?-bodyIndexB:bodyIndexB;\n" -" c->m_worldPosB[0] = pOnB1;\n" -" c->m_childIndexA = -1;\n" -" c->m_childIndexB = faceIndex;\n" -" GET_NPOINTS(*c) = 1;\n" -" } \n" -" }\n" -" }\n" -" }//if (hasCollision)\n" -"}\n" -"// work-in-progress\n" -"__kernel void findConcaveSphereContactsKernel( __global int4* concavePairs,\n" -" __global const BodyData* rigidBodies,\n" -" __global const btCollidableGpu* collidables,\n" -" __global const ConvexPolyhedronCL* convexShapes, \n" -" __global const float4* vertices,\n" -" __global const float4* uniqueEdges,\n" -" __global const btGpuFace* faces,\n" -" __global const int* indices,\n" -" __global btAabbCL* aabbs,\n" -" __global struct b3Contact4Data* restrict globalContactsOut,\n" -" counter32_t nGlobalContactsOut,\n" -" int numConcavePairs, int maxContactCapacity\n" -" )\n" -"{\n" -" int i = get_global_id(0);\n" -" if (i>=numConcavePairs)\n" -" return;\n" -" int pairIdx = i;\n" -" int bodyIndexA = concavePairs[i].x;\n" -" int bodyIndexB = concavePairs[i].y;\n" -" int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;\n" -" int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;\n" -" int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;\n" -" int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;\n" -" if (collidables[collidableIndexB].m_shapeType==SHAPE_SPHERE)\n" -" {\n" -" int f = concavePairs[i].z;\n" -" btGpuFace face = faces[convexShapes[shapeIndexA].m_faceOffset+f];\n" -" \n" -" float4 verticesA[3];\n" -" for (int i=0;i<3;i++)\n" -" {\n" -" int index = indices[face.m_indexOffset+i];\n" -" float4 vert = vertices[convexShapes[shapeIndexA].m_vertexOffset+index];\n" -" verticesA[i] = vert;\n" -" }\n" -" float4 spherePos = rigidBodies[bodyIndexB].m_pos;\n" -" float sphereRadius = collidables[collidableIndexB].m_radius;\n" -" float4 convexPos = rigidBodies[bodyIndexA].m_pos;\n" -" float4 convexOrn = rigidBodies[bodyIndexA].m_quat;\n" -" computeContactSphereTriangle(i, bodyIndexB, bodyIndexA, collidableIndexB, collidableIndexA, \n" -" rigidBodies,collidables,\n" -" verticesA,\n" -" globalContactsOut, nGlobalContactsOut,maxContactCapacity,\n" -" spherePos,sphereRadius,convexPos,convexOrn, f);\n" -" return;\n" -" }\n" -"}\n" -; +static const char* primitiveContactsKernelsCL = + "#ifndef B3_CONTACT4DATA_H\n" + "#define B3_CONTACT4DATA_H\n" + "#ifndef B3_FLOAT4_H\n" + "#define B3_FLOAT4_H\n" + "#ifndef B3_PLATFORM_DEFINITIONS_H\n" + "#define B3_PLATFORM_DEFINITIONS_H\n" + "struct MyTest\n" + "{\n" + " int bla;\n" + "};\n" + "#ifdef __cplusplus\n" + "#else\n" + "//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n" + "#define B3_LARGE_FLOAT 1e18f\n" + "#define B3_INFINITY 1e18f\n" + "#define b3Assert(a)\n" + "#define b3ConstArray(a) __global const a*\n" + "#define b3AtomicInc atomic_inc\n" + "#define b3AtomicAdd atomic_add\n" + "#define b3Fabs fabs\n" + "#define b3Sqrt native_sqrt\n" + "#define b3Sin native_sin\n" + "#define b3Cos native_cos\n" + "#define B3_STATIC\n" + "#endif\n" + "#endif\n" + "#ifdef __cplusplus\n" + "#else\n" + " typedef float4 b3Float4;\n" + " #define b3Float4ConstArg const b3Float4\n" + " #define b3MakeFloat4 (float4)\n" + " float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" + " {\n" + " float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" + " float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" + " return dot(a1, b1);\n" + " }\n" + " b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" + " {\n" + " float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" + " float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" + " return cross(a1, b1);\n" + " }\n" + " #define b3MinFloat4 min\n" + " #define b3MaxFloat4 max\n" + " #define b3Normalized(a) normalize(a)\n" + "#endif \n" + " \n" + "inline bool b3IsAlmostZero(b3Float4ConstArg v)\n" + "{\n" + " if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" + " return false;\n" + " return true;\n" + "}\n" + "inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" + "{\n" + " float maxDot = -B3_INFINITY;\n" + " int i = 0;\n" + " int ptIndex = -1;\n" + " for( i = 0; i < vecLen; i++ )\n" + " {\n" + " float dot = b3Dot3F4(vecArray[i],vec);\n" + " \n" + " if( dot > maxDot )\n" + " {\n" + " maxDot = dot;\n" + " ptIndex = i;\n" + " }\n" + " }\n" + " b3Assert(ptIndex>=0);\n" + " if (ptIndex<0)\n" + " {\n" + " ptIndex = 0;\n" + " }\n" + " *dotOut = maxDot;\n" + " return ptIndex;\n" + "}\n" + "#endif //B3_FLOAT4_H\n" + "typedef struct b3Contact4Data b3Contact4Data_t;\n" + "struct b3Contact4Data\n" + "{\n" + " b3Float4 m_worldPosB[4];\n" + "// b3Float4 m_localPosA[4];\n" + "// b3Float4 m_localPosB[4];\n" + " b3Float4 m_worldNormalOnB; // w: m_nPoints\n" + " unsigned short m_restituitionCoeffCmp;\n" + " unsigned short m_frictionCoeffCmp;\n" + " int m_batchIdx;\n" + " int m_bodyAPtrAndSignBit;//x:m_bodyAPtr, y:m_bodyBPtr\n" + " int m_bodyBPtrAndSignBit;\n" + " int m_childIndexA;\n" + " int m_childIndexB;\n" + " int m_unused1;\n" + " int m_unused2;\n" + "};\n" + "inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact)\n" + "{\n" + " return (int)contact->m_worldNormalOnB.w;\n" + "};\n" + "inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints)\n" + "{\n" + " contact->m_worldNormalOnB.w = (float)numPoints;\n" + "};\n" + "#endif //B3_CONTACT4DATA_H\n" + "#define SHAPE_CONVEX_HULL 3\n" + "#define SHAPE_PLANE 4\n" + "#define SHAPE_CONCAVE_TRIMESH 5\n" + "#define SHAPE_COMPOUND_OF_CONVEX_HULLS 6\n" + "#define SHAPE_SPHERE 7\n" + "#pragma OPENCL EXTENSION cl_amd_printf : enable\n" + "#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" + "#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n" + "#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n" + "#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n" + "#ifdef cl_ext_atomic_counters_32\n" + "#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n" + "#else\n" + "#define counter32_t volatile __global int*\n" + "#endif\n" + "#define GET_GROUP_IDX get_group_id(0)\n" + "#define GET_LOCAL_IDX get_local_id(0)\n" + "#define GET_GLOBAL_IDX get_global_id(0)\n" + "#define GET_GROUP_SIZE get_local_size(0)\n" + "#define GET_NUM_GROUPS get_num_groups(0)\n" + "#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" + "#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" + "#define AtomInc(x) atom_inc(&(x))\n" + "#define AtomInc1(x, out) out = atom_inc(&(x))\n" + "#define AppendInc(x, out) out = atomic_inc(x)\n" + "#define AtomAdd(x, value) atom_add(&(x), value)\n" + "#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n" + "#define AtomXhg(x, value) atom_xchg ( &(x), value )\n" + "#define max2 max\n" + "#define min2 min\n" + "typedef unsigned int u32;\n" + "typedef struct \n" + "{\n" + " union\n" + " {\n" + " float4 m_min;\n" + " float m_minElems[4];\n" + " int m_minIndices[4];\n" + " };\n" + " union\n" + " {\n" + " float4 m_max;\n" + " float m_maxElems[4];\n" + " int m_maxIndices[4];\n" + " };\n" + "} btAabbCL;\n" + "///keep this in sync with btCollidable.h\n" + "typedef struct\n" + "{\n" + " int m_numChildShapes;\n" + " float m_radius;\n" + " int m_shapeType;\n" + " int m_shapeIndex;\n" + " \n" + "} btCollidableGpu;\n" + "typedef struct\n" + "{\n" + " float4 m_childPosition;\n" + " float4 m_childOrientation;\n" + " int m_shapeIndex;\n" + " int m_unused0;\n" + " int m_unused1;\n" + " int m_unused2;\n" + "} btGpuChildShape;\n" + "#define GET_NPOINTS(x) (x).m_worldNormalOnB.w\n" + "typedef struct\n" + "{\n" + " float4 m_pos;\n" + " float4 m_quat;\n" + " float4 m_linVel;\n" + " float4 m_angVel;\n" + " u32 m_collidableIdx; \n" + " float m_invMass;\n" + " float m_restituitionCoeff;\n" + " float m_frictionCoeff;\n" + "} BodyData;\n" + "typedef struct \n" + "{\n" + " float4 m_localCenter;\n" + " float4 m_extents;\n" + " float4 mC;\n" + " float4 mE;\n" + " \n" + " float m_radius;\n" + " int m_faceOffset;\n" + " int m_numFaces;\n" + " int m_numVertices;\n" + " \n" + " int m_vertexOffset;\n" + " int m_uniqueEdgesOffset;\n" + " int m_numUniqueEdges;\n" + " int m_unused;\n" + "} ConvexPolyhedronCL;\n" + "typedef struct\n" + "{\n" + " float4 m_plane;\n" + " int m_indexOffset;\n" + " int m_numIndices;\n" + "} btGpuFace;\n" + "#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n" + "#define make_float4 (float4)\n" + "#define make_float2 (float2)\n" + "#define make_uint4 (uint4)\n" + "#define make_int4 (int4)\n" + "#define make_uint2 (uint2)\n" + "#define make_int2 (int2)\n" + "__inline\n" + "float fastDiv(float numerator, float denominator)\n" + "{\n" + " return native_divide(numerator, denominator); \n" + "// return numerator/denominator; \n" + "}\n" + "__inline\n" + "float4 fastDiv4(float4 numerator, float4 denominator)\n" + "{\n" + " return native_divide(numerator, denominator); \n" + "}\n" + "__inline\n" + "float4 cross3(float4 a, float4 b)\n" + "{\n" + " return cross(a,b);\n" + "}\n" + "//#define dot3F4 dot\n" + "__inline\n" + "float dot3F4(float4 a, float4 b)\n" + "{\n" + " float4 a1 = make_float4(a.xyz,0.f);\n" + " float4 b1 = make_float4(b.xyz,0.f);\n" + " return dot(a1, b1);\n" + "}\n" + "__inline\n" + "float4 fastNormalize4(float4 v)\n" + "{\n" + " return fast_normalize(v);\n" + "}\n" + "///////////////////////////////////////\n" + "// Quaternion\n" + "///////////////////////////////////////\n" + "typedef float4 Quaternion;\n" + "__inline\n" + "Quaternion qtMul(Quaternion a, Quaternion b);\n" + "__inline\n" + "Quaternion qtNormalize(Quaternion in);\n" + "__inline\n" + "float4 qtRotate(Quaternion q, float4 vec);\n" + "__inline\n" + "Quaternion qtInvert(Quaternion q);\n" + "__inline\n" + "Quaternion qtMul(Quaternion a, Quaternion b)\n" + "{\n" + " Quaternion ans;\n" + " ans = cross3( a, b );\n" + " ans += a.w*b+b.w*a;\n" + "// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" + " ans.w = a.w*b.w - dot3F4(a, b);\n" + " return ans;\n" + "}\n" + "__inline\n" + "Quaternion qtNormalize(Quaternion in)\n" + "{\n" + " return fastNormalize4(in);\n" + "// in /= length( in );\n" + "// return in;\n" + "}\n" + "__inline\n" + "float4 qtRotate(Quaternion q, float4 vec)\n" + "{\n" + " Quaternion qInv = qtInvert( q );\n" + " float4 vcpy = vec;\n" + " vcpy.w = 0.f;\n" + " float4 out = qtMul(qtMul(q,vcpy),qInv);\n" + " return out;\n" + "}\n" + "__inline\n" + "Quaternion qtInvert(Quaternion q)\n" + "{\n" + " return (Quaternion)(-q.xyz, q.w);\n" + "}\n" + "__inline\n" + "float4 qtInvRotate(const Quaternion q, float4 vec)\n" + "{\n" + " return qtRotate( qtInvert( q ), vec );\n" + "}\n" + "__inline\n" + "float4 transform(const float4* p, const float4* translation, const Quaternion* orientation)\n" + "{\n" + " return qtRotate( *orientation, *p ) + (*translation);\n" + "}\n" + "void trInverse(float4 translationIn, Quaternion orientationIn,\n" + " float4* translationOut, Quaternion* orientationOut)\n" + "{\n" + " *orientationOut = qtInvert(orientationIn);\n" + " *translationOut = qtRotate(*orientationOut, -translationIn);\n" + "}\n" + "void trMul(float4 translationA, Quaternion orientationA,\n" + " float4 translationB, Quaternion orientationB,\n" + " float4* translationOut, Quaternion* orientationOut)\n" + "{\n" + " *orientationOut = qtMul(orientationA,orientationB);\n" + " *translationOut = transform(&translationB,&translationA,&orientationA);\n" + "}\n" + "__inline\n" + "float4 normalize3(const float4 a)\n" + "{\n" + " float4 n = make_float4(a.x, a.y, a.z, 0.f);\n" + " return fastNormalize4( n );\n" + "}\n" + "__inline float4 lerp3(const float4 a,const float4 b, float t)\n" + "{\n" + " return make_float4( a.x + (b.x - a.x) * t,\n" + " a.y + (b.y - a.y) * t,\n" + " a.z + (b.z - a.z) * t,\n" + " 0.f);\n" + "}\n" + "float signedDistanceFromPointToPlane(float4 point, float4 planeEqn, float4* closestPointOnFace)\n" + "{\n" + " float4 n = (float4)(planeEqn.x, planeEqn.y, planeEqn.z, 0);\n" + " float dist = dot3F4(n, point) + planeEqn.w;\n" + " *closestPointOnFace = point - dist * n;\n" + " return dist;\n" + "}\n" + "inline bool IsPointInPolygon(float4 p, \n" + " const btGpuFace* face,\n" + " __global const float4* baseVertex,\n" + " __global const int* convexIndices,\n" + " float4* out)\n" + "{\n" + " float4 a;\n" + " float4 b;\n" + " float4 ab;\n" + " float4 ap;\n" + " float4 v;\n" + " float4 plane = make_float4(face->m_plane.x,face->m_plane.y,face->m_plane.z,0.f);\n" + " \n" + " if (face->m_numIndices<2)\n" + " return false;\n" + " \n" + " float4 v0 = baseVertex[convexIndices[face->m_indexOffset + face->m_numIndices-1]];\n" + " \n" + " b = v0;\n" + " for(unsigned i=0; i != face->m_numIndices; ++i)\n" + " {\n" + " a = b;\n" + " float4 vi = baseVertex[convexIndices[face->m_indexOffset + i]];\n" + " b = vi;\n" + " ab = b-a;\n" + " ap = p-a;\n" + " v = cross3(ab,plane);\n" + " if (dot(ap, v) > 0.f)\n" + " {\n" + " float ab_m2 = dot(ab, ab);\n" + " float rt = ab_m2 != 0.f ? dot(ab, ap) / ab_m2 : 0.f;\n" + " if (rt <= 0.f)\n" + " {\n" + " *out = a;\n" + " }\n" + " else if (rt >= 1.f) \n" + " {\n" + " *out = b;\n" + " }\n" + " else\n" + " {\n" + " float s = 1.f - rt;\n" + " out[0].x = s * a.x + rt * b.x;\n" + " out[0].y = s * a.y + rt * b.y;\n" + " out[0].z = s * a.z + rt * b.z;\n" + " }\n" + " return false;\n" + " }\n" + " }\n" + " return true;\n" + "}\n" + "void computeContactSphereConvex(int pairIndex,\n" + " int bodyIndexA, int bodyIndexB, \n" + " int collidableIndexA, int collidableIndexB, \n" + " __global const BodyData* rigidBodies, \n" + " __global const btCollidableGpu* collidables,\n" + " __global const ConvexPolyhedronCL* convexShapes,\n" + " __global const float4* convexVertices,\n" + " __global const int* convexIndices,\n" + " __global const btGpuFace* faces,\n" + " __global struct b3Contact4Data* restrict globalContactsOut,\n" + " counter32_t nGlobalContactsOut,\n" + " int maxContactCapacity,\n" + " float4 spherePos2,\n" + " float radius,\n" + " float4 pos,\n" + " float4 quat\n" + " )\n" + "{\n" + " float4 invPos;\n" + " float4 invOrn;\n" + " trInverse(pos,quat, &invPos,&invOrn);\n" + " float4 spherePos = transform(&spherePos2,&invPos,&invOrn);\n" + " int shapeIndex = collidables[collidableIndexB].m_shapeIndex;\n" + " int numFaces = convexShapes[shapeIndex].m_numFaces;\n" + " float4 closestPnt = (float4)(0, 0, 0, 0);\n" + " float4 hitNormalWorld = (float4)(0, 0, 0, 0);\n" + " float minDist = -1000000.f;\n" + " bool bCollide = true;\n" + " for ( int f = 0; f < numFaces; f++ )\n" + " {\n" + " btGpuFace face = faces[convexShapes[shapeIndex].m_faceOffset+f];\n" + " // set up a plane equation \n" + " float4 planeEqn;\n" + " float4 n1 = face.m_plane;\n" + " n1.w = 0.f;\n" + " planeEqn = n1;\n" + " planeEqn.w = face.m_plane.w;\n" + " \n" + " \n" + " // compute a signed distance from the vertex in cloth to the face of rigidbody.\n" + " float4 pntReturn;\n" + " float dist = signedDistanceFromPointToPlane(spherePos, planeEqn, &pntReturn);\n" + " // If the distance is positive, the plane is a separating plane. \n" + " if ( dist > radius )\n" + " {\n" + " bCollide = false;\n" + " break;\n" + " }\n" + " if (dist>0)\n" + " {\n" + " //might hit an edge or vertex\n" + " float4 out;\n" + " float4 zeroPos = make_float4(0,0,0,0);\n" + " bool isInPoly = IsPointInPolygon(spherePos,\n" + " &face,\n" + " &convexVertices[convexShapes[shapeIndex].m_vertexOffset],\n" + " convexIndices,\n" + " &out);\n" + " if (isInPoly)\n" + " {\n" + " if (dist>minDist)\n" + " {\n" + " minDist = dist;\n" + " closestPnt = pntReturn;\n" + " hitNormalWorld = planeEqn;\n" + " \n" + " }\n" + " } else\n" + " {\n" + " float4 tmp = spherePos-out;\n" + " float l2 = dot(tmp,tmp);\n" + " if (l2minDist)\n" + " {\n" + " minDist = dist;\n" + " closestPnt = out;\n" + " hitNormalWorld = tmp/dist;\n" + " \n" + " }\n" + " \n" + " } else\n" + " {\n" + " bCollide = false;\n" + " break;\n" + " }\n" + " }\n" + " } else\n" + " {\n" + " if ( dist > minDist )\n" + " {\n" + " minDist = dist;\n" + " closestPnt = pntReturn;\n" + " hitNormalWorld.xyz = planeEqn.xyz;\n" + " }\n" + " }\n" + " \n" + " }\n" + " \n" + " if (bCollide && minDist > -10000)\n" + " {\n" + " float4 normalOnSurfaceB1 = qtRotate(quat,-hitNormalWorld);\n" + " float4 pOnB1 = transform(&closestPnt,&pos,&quat);\n" + " \n" + " float actualDepth = minDist-radius;\n" + " if (actualDepth<=0.f)\n" + " {\n" + " \n" + " pOnB1.w = actualDepth;\n" + " int dstIdx;\n" + " AppendInc( nGlobalContactsOut, dstIdx );\n" + " \n" + " \n" + " if (1)//dstIdx < maxContactCapacity)\n" + " {\n" + " __global struct b3Contact4Data* c = &globalContactsOut[dstIdx];\n" + " c->m_worldNormalOnB = -normalOnSurfaceB1;\n" + " c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" + " c->m_batchIdx = pairIndex;\n" + " c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass==0?-bodyIndexA:bodyIndexA;\n" + " c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass==0?-bodyIndexB:bodyIndexB;\n" + " c->m_worldPosB[0] = pOnB1;\n" + " c->m_childIndexA = -1;\n" + " c->m_childIndexB = -1;\n" + " GET_NPOINTS(*c) = 1;\n" + " } \n" + " }\n" + " }//if (hasCollision)\n" + "}\n" + " \n" + "int extractManifoldSequential(const float4* p, int nPoints, float4 nearNormal, int4* contactIdx)\n" + "{\n" + " if( nPoints == 0 )\n" + " return 0;\n" + " \n" + " if (nPoints <=4)\n" + " return nPoints;\n" + " \n" + " \n" + " if (nPoints >64)\n" + " nPoints = 64;\n" + " \n" + " float4 center = make_float4(0.f);\n" + " {\n" + " \n" + " for (int i=0;im_numVertices;i++)\n" + " {\n" + " float4 vtx = convexVertices[hullB->m_vertexOffset+i];\n" + " float curDot = dot(vtx,planeNormalInConvex);\n" + " if (curDot>maxDot)\n" + " {\n" + " hitVertex=i;\n" + " maxDot=curDot;\n" + " hitVtx = vtx;\n" + " //make sure the deepest points is always included\n" + " if (numPoints==MAX_PLANE_CONVEX_POINTS)\n" + " numPoints--;\n" + " }\n" + " if (numPoints4)\n" + " {\n" + " numReducedPoints = extractManifoldSequential( contactPoints, numPoints, planeNormalInConvex, &contactIdx);\n" + " }\n" + " if (numReducedPoints>0)\n" + " {\n" + " int dstIdx;\n" + " AppendInc( nGlobalContactsOut, dstIdx );\n" + " if (dstIdx < maxContactCapacity)\n" + " {\n" + " resultIndex = dstIdx;\n" + " __global struct b3Contact4Data* c = &globalContactsOut[dstIdx];\n" + " c->m_worldNormalOnB = -planeNormalWorld;\n" + " //c->setFrictionCoeff(0.7);\n" + " //c->setRestituitionCoeff(0.f);\n" + " c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" + " c->m_batchIdx = pairIndex;\n" + " c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass==0?-bodyIndexA:bodyIndexA;\n" + " c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass==0?-bodyIndexB:bodyIndexB;\n" + " c->m_childIndexA = -1;\n" + " c->m_childIndexB = -1;\n" + " switch (numReducedPoints)\n" + " {\n" + " case 4:\n" + " c->m_worldPosB[3] = contactPoints[contactIdx.w];\n" + " case 3:\n" + " c->m_worldPosB[2] = contactPoints[contactIdx.z];\n" + " case 2:\n" + " c->m_worldPosB[1] = contactPoints[contactIdx.y];\n" + " case 1:\n" + " c->m_worldPosB[0] = contactPoints[contactIdx.x];\n" + " default:\n" + " {\n" + " }\n" + " };\n" + " \n" + " GET_NPOINTS(*c) = numReducedPoints;\n" + " }//if (dstIdx < numPairs)\n" + " } \n" + " return resultIndex;\n" + "}\n" + "void computeContactPlaneSphere(int pairIndex,\n" + " int bodyIndexA, int bodyIndexB, \n" + " int collidableIndexA, int collidableIndexB, \n" + " __global const BodyData* rigidBodies, \n" + " __global const btCollidableGpu* collidables,\n" + " __global const btGpuFace* faces,\n" + " __global struct b3Contact4Data* restrict globalContactsOut,\n" + " counter32_t nGlobalContactsOut,\n" + " int maxContactCapacity)\n" + "{\n" + " float4 planeEq = faces[collidables[collidableIndexA].m_shapeIndex].m_plane;\n" + " float radius = collidables[collidableIndexB].m_radius;\n" + " float4 posA1 = rigidBodies[bodyIndexA].m_pos;\n" + " float4 ornA1 = rigidBodies[bodyIndexA].m_quat;\n" + " float4 posB1 = rigidBodies[bodyIndexB].m_pos;\n" + " float4 ornB1 = rigidBodies[bodyIndexB].m_quat;\n" + " \n" + " bool hasCollision = false;\n" + " float4 planeNormal1 = make_float4(planeEq.x,planeEq.y,planeEq.z,0.f);\n" + " float planeConstant = planeEq.w;\n" + " float4 convexInPlaneTransPos1; Quaternion convexInPlaneTransOrn1;\n" + " {\n" + " float4 invPosA;Quaternion invOrnA;\n" + " trInverse(posA1,ornA1,&invPosA,&invOrnA);\n" + " trMul(invPosA,invOrnA,posB1,ornB1,&convexInPlaneTransPos1,&convexInPlaneTransOrn1);\n" + " }\n" + " float4 planeInConvexPos1; Quaternion planeInConvexOrn1;\n" + " {\n" + " float4 invPosB;Quaternion invOrnB;\n" + " trInverse(posB1,ornB1,&invPosB,&invOrnB);\n" + " trMul(invPosB,invOrnB,posA1,ornA1,&planeInConvexPos1,&planeInConvexOrn1); \n" + " }\n" + " float4 vtx1 = qtRotate(planeInConvexOrn1,-planeNormal1)*radius;\n" + " float4 vtxInPlane1 = transform(&vtx1,&convexInPlaneTransPos1,&convexInPlaneTransOrn1);\n" + " float distance = dot3F4(planeNormal1,vtxInPlane1) - planeConstant;\n" + " hasCollision = distance < 0.f;//m_manifoldPtr->getContactBreakingThreshold();\n" + " if (hasCollision)\n" + " {\n" + " float4 vtxInPlaneProjected1 = vtxInPlane1 - distance*planeNormal1;\n" + " float4 vtxInPlaneWorld1 = transform(&vtxInPlaneProjected1,&posA1,&ornA1);\n" + " float4 normalOnSurfaceB1 = qtRotate(ornA1,planeNormal1);\n" + " float4 pOnB1 = vtxInPlaneWorld1+normalOnSurfaceB1*distance;\n" + " pOnB1.w = distance;\n" + " int dstIdx;\n" + " AppendInc( nGlobalContactsOut, dstIdx );\n" + " \n" + " if (dstIdx < maxContactCapacity)\n" + " {\n" + " __global struct b3Contact4Data* c = &globalContactsOut[dstIdx];\n" + " c->m_worldNormalOnB = -normalOnSurfaceB1;\n" + " c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" + " c->m_batchIdx = pairIndex;\n" + " c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass==0?-bodyIndexA:bodyIndexA;\n" + " c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass==0?-bodyIndexB:bodyIndexB;\n" + " c->m_worldPosB[0] = pOnB1;\n" + " c->m_childIndexA = -1;\n" + " c->m_childIndexB = -1;\n" + " GET_NPOINTS(*c) = 1;\n" + " }//if (dstIdx < numPairs)\n" + " }//if (hasCollision)\n" + "}\n" + "__kernel void primitiveContactsKernel( __global int4* pairs, \n" + " __global const BodyData* rigidBodies, \n" + " __global const btCollidableGpu* collidables,\n" + " __global const ConvexPolyhedronCL* convexShapes, \n" + " __global const float4* vertices,\n" + " __global const float4* uniqueEdges,\n" + " __global const btGpuFace* faces,\n" + " __global const int* indices,\n" + " __global struct b3Contact4Data* restrict globalContactsOut,\n" + " counter32_t nGlobalContactsOut,\n" + " int numPairs, int maxContactCapacity)\n" + "{\n" + " int i = get_global_id(0);\n" + " int pairIndex = i;\n" + " \n" + " float4 worldVertsB1[64];\n" + " float4 worldVertsB2[64];\n" + " int capacityWorldVerts = 64; \n" + " float4 localContactsOut[64];\n" + " int localContactCapacity=64;\n" + " \n" + " float minDist = -1e30f;\n" + " float maxDist = 0.02f;\n" + " if (i=0)\n" + " pairs[pairIndex].z = contactIndex;\n" + " return;\n" + " }\n" + " if (collidables[collidableIndexA].m_shapeType == SHAPE_CONVEX_HULL &&\n" + " collidables[collidableIndexB].m_shapeType == SHAPE_PLANE)\n" + " {\n" + " float4 posA;\n" + " posA = rigidBodies[bodyIndexA].m_pos;\n" + " Quaternion ornA;\n" + " ornA = rigidBodies[bodyIndexA].m_quat;\n" + " int contactIndex = computeContactPlaneConvex( pairIndex, bodyIndexB,bodyIndexA, collidableIndexB,collidableIndexA, \n" + " rigidBodies,collidables,convexShapes,vertices,indices,\n" + " faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity,posA,ornA);\n" + " if (contactIndex>=0)\n" + " pairs[pairIndex].z = contactIndex;\n" + " return;\n" + " }\n" + " if (collidables[collidableIndexA].m_shapeType == SHAPE_PLANE &&\n" + " collidables[collidableIndexB].m_shapeType == SHAPE_SPHERE)\n" + " {\n" + " computeContactPlaneSphere(pairIndex, bodyIndexA, bodyIndexB, collidableIndexA, collidableIndexB, \n" + " rigidBodies,collidables,faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity);\n" + " return;\n" + " }\n" + " if (collidables[collidableIndexA].m_shapeType == SHAPE_SPHERE &&\n" + " collidables[collidableIndexB].m_shapeType == SHAPE_PLANE)\n" + " {\n" + " computeContactPlaneSphere( pairIndex, bodyIndexB,bodyIndexA, collidableIndexB,collidableIndexA, \n" + " rigidBodies,collidables,\n" + " faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity);\n" + " return;\n" + " }\n" + " \n" + " \n" + " if (collidables[collidableIndexA].m_shapeType == SHAPE_SPHERE &&\n" + " collidables[collidableIndexB].m_shapeType == SHAPE_CONVEX_HULL)\n" + " {\n" + " \n" + " float4 spherePos = rigidBodies[bodyIndexA].m_pos;\n" + " float sphereRadius = collidables[collidableIndexA].m_radius;\n" + " float4 convexPos = rigidBodies[bodyIndexB].m_pos;\n" + " float4 convexOrn = rigidBodies[bodyIndexB].m_quat;\n" + " computeContactSphereConvex(pairIndex, bodyIndexA, bodyIndexB, collidableIndexA, collidableIndexB, \n" + " rigidBodies,collidables,convexShapes,vertices,indices,faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity,\n" + " spherePos,sphereRadius,convexPos,convexOrn);\n" + " return;\n" + " }\n" + " if (collidables[collidableIndexA].m_shapeType == SHAPE_CONVEX_HULL &&\n" + " collidables[collidableIndexB].m_shapeType == SHAPE_SPHERE)\n" + " {\n" + " \n" + " float4 spherePos = rigidBodies[bodyIndexB].m_pos;\n" + " float sphereRadius = collidables[collidableIndexB].m_radius;\n" + " float4 convexPos = rigidBodies[bodyIndexA].m_pos;\n" + " float4 convexOrn = rigidBodies[bodyIndexA].m_quat;\n" + " computeContactSphereConvex(pairIndex, bodyIndexB, bodyIndexA, collidableIndexB, collidableIndexA, \n" + " rigidBodies,collidables,convexShapes,vertices,indices,faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity,\n" + " spherePos,sphereRadius,convexPos,convexOrn);\n" + " return;\n" + " }\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " \n" + " if (collidables[collidableIndexA].m_shapeType == SHAPE_SPHERE &&\n" + " collidables[collidableIndexB].m_shapeType == SHAPE_SPHERE)\n" + " {\n" + " //sphere-sphere\n" + " float radiusA = collidables[collidableIndexA].m_radius;\n" + " float radiusB = collidables[collidableIndexB].m_radius;\n" + " float4 posA = rigidBodies[bodyIndexA].m_pos;\n" + " float4 posB = rigidBodies[bodyIndexB].m_pos;\n" + " float4 diff = posA-posB;\n" + " float len = length(diff);\n" + " \n" + " ///iff distance positive, don't generate a new contact\n" + " if ( len <= (radiusA+radiusB))\n" + " {\n" + " ///distance (negative means penetration)\n" + " float dist = len - (radiusA+radiusB);\n" + " float4 normalOnSurfaceB = make_float4(1.f,0.f,0.f,0.f);\n" + " if (len > 0.00001)\n" + " {\n" + " normalOnSurfaceB = diff / len;\n" + " }\n" + " float4 contactPosB = posB + normalOnSurfaceB*radiusB;\n" + " contactPosB.w = dist;\n" + " \n" + " int dstIdx;\n" + " AppendInc( nGlobalContactsOut, dstIdx );\n" + " \n" + " if (dstIdx < maxContactCapacity)\n" + " {\n" + " __global struct b3Contact4Data* c = &globalContactsOut[dstIdx];\n" + " c->m_worldNormalOnB = normalOnSurfaceB;\n" + " c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" + " c->m_batchIdx = pairIndex;\n" + " int bodyA = pairs[pairIndex].x;\n" + " int bodyB = pairs[pairIndex].y;\n" + " c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA;\n" + " c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB;\n" + " c->m_worldPosB[0] = contactPosB;\n" + " c->m_childIndexA = -1;\n" + " c->m_childIndexB = -1;\n" + " GET_NPOINTS(*c) = 1;\n" + " }//if (dstIdx < numPairs)\n" + " }//if ( len <= (radiusA+radiusB))\n" + " return;\n" + " }//SHAPE_SPHERE SHAPE_SPHERE\n" + " }// if (i= 0)\n" + " {\n" + " collidableIndexA = gpuChildShapes[childShapeIndexA].m_shapeIndex;\n" + " float4 childPosA = gpuChildShapes[childShapeIndexA].m_childPosition;\n" + " float4 childOrnA = gpuChildShapes[childShapeIndexA].m_childOrientation;\n" + " float4 newPosA = qtRotate(ornA,childPosA)+posA;\n" + " float4 newOrnA = qtMul(ornA,childOrnA);\n" + " posA = newPosA;\n" + " ornA = newOrnA;\n" + " } else\n" + " {\n" + " collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;\n" + " }\n" + " \n" + " if (childShapeIndexB>=0)\n" + " {\n" + " collidableIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex;\n" + " float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition;\n" + " float4 childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation;\n" + " float4 newPosB = transform(&childPosB,&posB,&ornB);\n" + " float4 newOrnB = qtMul(ornB,childOrnB);\n" + " posB = newPosB;\n" + " ornB = newOrnB;\n" + " } else\n" + " {\n" + " collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx; \n" + " }\n" + " \n" + " int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;\n" + " int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;\n" + " \n" + " int shapeTypeA = collidables[collidableIndexA].m_shapeType;\n" + " int shapeTypeB = collidables[collidableIndexB].m_shapeType;\n" + " int pairIndex = i;\n" + " if ((shapeTypeA == SHAPE_PLANE) && (shapeTypeB==SHAPE_CONVEX_HULL))\n" + " {\n" + " computeContactPlaneConvex( pairIndex, bodyIndexA,bodyIndexB, collidableIndexA,collidableIndexB, \n" + " rigidBodies,collidables,convexShapes,vertices,indices,\n" + " faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity,posB,ornB);\n" + " return;\n" + " }\n" + " if ((shapeTypeA == SHAPE_CONVEX_HULL) && (shapeTypeB==SHAPE_PLANE))\n" + " {\n" + " computeContactPlaneConvex( pairIndex, bodyIndexB,bodyIndexA, collidableIndexB,collidableIndexA, \n" + " rigidBodies,collidables,convexShapes,vertices,indices,\n" + " faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity,posA,ornA);\n" + " return;\n" + " }\n" + " if ((shapeTypeA == SHAPE_CONVEX_HULL) && (shapeTypeB == SHAPE_SPHERE))\n" + " {\n" + " float4 spherePos = rigidBodies[bodyIndexB].m_pos;\n" + " float sphereRadius = collidables[collidableIndexB].m_radius;\n" + " float4 convexPos = posA;\n" + " float4 convexOrn = ornA;\n" + " \n" + " computeContactSphereConvex(pairIndex, bodyIndexB, bodyIndexA , collidableIndexB,collidableIndexA, \n" + " rigidBodies,collidables,convexShapes,vertices,indices,faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity,\n" + " spherePos,sphereRadius,convexPos,convexOrn);\n" + " \n" + " return;\n" + " }\n" + " if ((shapeTypeA == SHAPE_SPHERE) && (shapeTypeB == SHAPE_CONVEX_HULL))\n" + " {\n" + " float4 spherePos = rigidBodies[bodyIndexA].m_pos;\n" + " float sphereRadius = collidables[collidableIndexA].m_radius;\n" + " float4 convexPos = posB;\n" + " float4 convexOrn = ornB;\n" + " \n" + " computeContactSphereConvex(pairIndex, bodyIndexA, bodyIndexB, collidableIndexA, collidableIndexB, \n" + " rigidBodies,collidables,convexShapes,vertices,indices,faces, globalContactsOut, nGlobalContactsOut,maxContactCapacity,\n" + " spherePos,sphereRadius,convexPos,convexOrn);\n" + " \n" + " return;\n" + " }\n" + " }// if (i 0 && r2 > 0 && r3 > 0 )\n" + " return true;\n" + " if ( r1 <= 0 && r2 <= 0 && r3 <= 0 ) \n" + " return true;\n" + " return false;\n" + "}\n" + "float segmentSqrDistance(float4 from, float4 to,float4 p, float4* nearest) \n" + "{\n" + " float4 diff = p - from;\n" + " float4 v = to - from;\n" + " float t = dot(v,diff);\n" + " \n" + " if (t > 0) \n" + " {\n" + " float dotVV = dot(v,v);\n" + " if (t < dotVV) \n" + " {\n" + " t /= dotVV;\n" + " diff -= t*v;\n" + " } else \n" + " {\n" + " t = 1;\n" + " diff -= v;\n" + " }\n" + " } else\n" + " {\n" + " t = 0;\n" + " }\n" + " *nearest = from + t*v;\n" + " return dot(diff,diff); \n" + "}\n" + "void computeContactSphereTriangle(int pairIndex,\n" + " int bodyIndexA, int bodyIndexB,\n" + " int collidableIndexA, int collidableIndexB, \n" + " __global const BodyData* rigidBodies, \n" + " __global const btCollidableGpu* collidables,\n" + " const float4* triangleVertices,\n" + " __global struct b3Contact4Data* restrict globalContactsOut,\n" + " counter32_t nGlobalContactsOut,\n" + " int maxContactCapacity,\n" + " float4 spherePos2,\n" + " float radius,\n" + " float4 pos,\n" + " float4 quat,\n" + " int faceIndex\n" + " )\n" + "{\n" + " float4 invPos;\n" + " float4 invOrn;\n" + " trInverse(pos,quat, &invPos,&invOrn);\n" + " float4 spherePos = transform(&spherePos2,&invPos,&invOrn);\n" + " int numFaces = 3;\n" + " float4 closestPnt = (float4)(0, 0, 0, 0);\n" + " float4 hitNormalWorld = (float4)(0, 0, 0, 0);\n" + " float minDist = -1000000.f;\n" + " bool bCollide = false;\n" + " \n" + " //////////////////////////////////////\n" + " float4 sphereCenter;\n" + " sphereCenter = spherePos;\n" + " const float4* vertices = triangleVertices;\n" + " float contactBreakingThreshold = 0.f;//todo?\n" + " float radiusWithThreshold = radius + contactBreakingThreshold;\n" + " float4 edge10;\n" + " edge10 = vertices[1]-vertices[0];\n" + " edge10.w = 0.f;//is this needed?\n" + " float4 edge20;\n" + " edge20 = vertices[2]-vertices[0];\n" + " edge20.w = 0.f;//is this needed?\n" + " float4 normal = cross3(edge10,edge20);\n" + " normal = normalize(normal);\n" + " float4 p1ToCenter;\n" + " p1ToCenter = sphereCenter - vertices[0];\n" + " \n" + " float distanceFromPlane = dot(p1ToCenter,normal);\n" + " if (distanceFromPlane < 0.f)\n" + " {\n" + " //triangle facing the other way\n" + " distanceFromPlane *= -1.f;\n" + " normal *= -1.f;\n" + " }\n" + " hitNormalWorld = normal;\n" + " bool isInsideContactPlane = distanceFromPlane < radiusWithThreshold;\n" + " \n" + " // Check for contact / intersection\n" + " bool hasContact = false;\n" + " float4 contactPoint;\n" + " if (isInsideContactPlane) \n" + " {\n" + " \n" + " if (pointInTriangle(vertices,&normal, &sphereCenter)) \n" + " {\n" + " // Inside the contact wedge - touches a point on the shell plane\n" + " hasContact = true;\n" + " contactPoint = sphereCenter - normal*distanceFromPlane;\n" + " \n" + " } else {\n" + " // Could be inside one of the contact capsules\n" + " float contactCapsuleRadiusSqr = radiusWithThreshold*radiusWithThreshold;\n" + " float4 nearestOnEdge;\n" + " int numEdges = 3;\n" + " for (int i = 0; i < numEdges; i++) \n" + " {\n" + " float4 pa =vertices[i];\n" + " float4 pb = vertices[(i+1)%3];\n" + " float distanceSqr = segmentSqrDistance(pa,pb,sphereCenter, &nearestOnEdge);\n" + " if (distanceSqr < contactCapsuleRadiusSqr) \n" + " {\n" + " // Yep, we're inside a capsule\n" + " hasContact = true;\n" + " contactPoint = nearestOnEdge;\n" + " \n" + " }\n" + " \n" + " }\n" + " }\n" + " }\n" + " if (hasContact) \n" + " {\n" + " closestPnt = contactPoint;\n" + " float4 contactToCenter = sphereCenter - contactPoint;\n" + " minDist = length(contactToCenter);\n" + " if (minDist>FLT_EPSILON)\n" + " {\n" + " hitNormalWorld = normalize(contactToCenter);//*(1./minDist);\n" + " bCollide = true;\n" + " }\n" + " \n" + " }\n" + " /////////////////////////////////////\n" + " if (bCollide && minDist > -10000)\n" + " {\n" + " \n" + " float4 normalOnSurfaceB1 = qtRotate(quat,-hitNormalWorld);\n" + " float4 pOnB1 = transform(&closestPnt,&pos,&quat);\n" + " float actualDepth = minDist-radius;\n" + " \n" + " if (actualDepth<=0.f)\n" + " {\n" + " pOnB1.w = actualDepth;\n" + " int dstIdx;\n" + " \n" + " float lenSqr = dot3F4(normalOnSurfaceB1,normalOnSurfaceB1);\n" + " if (lenSqr>FLT_EPSILON)\n" + " {\n" + " AppendInc( nGlobalContactsOut, dstIdx );\n" + " \n" + " if (dstIdx < maxContactCapacity)\n" + " {\n" + " __global struct b3Contact4Data* c = &globalContactsOut[dstIdx];\n" + " c->m_worldNormalOnB = -normalOnSurfaceB1;\n" + " c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" + " c->m_batchIdx = pairIndex;\n" + " c->m_bodyAPtrAndSignBit = rigidBodies[bodyIndexA].m_invMass==0?-bodyIndexA:bodyIndexA;\n" + " c->m_bodyBPtrAndSignBit = rigidBodies[bodyIndexB].m_invMass==0?-bodyIndexB:bodyIndexB;\n" + " c->m_worldPosB[0] = pOnB1;\n" + " c->m_childIndexA = -1;\n" + " c->m_childIndexB = faceIndex;\n" + " GET_NPOINTS(*c) = 1;\n" + " } \n" + " }\n" + " }\n" + " }//if (hasCollision)\n" + "}\n" + "// work-in-progress\n" + "__kernel void findConcaveSphereContactsKernel( __global int4* concavePairs,\n" + " __global const BodyData* rigidBodies,\n" + " __global const btCollidableGpu* collidables,\n" + " __global const ConvexPolyhedronCL* convexShapes, \n" + " __global const float4* vertices,\n" + " __global const float4* uniqueEdges,\n" + " __global const btGpuFace* faces,\n" + " __global const int* indices,\n" + " __global btAabbCL* aabbs,\n" + " __global struct b3Contact4Data* restrict globalContactsOut,\n" + " counter32_t nGlobalContactsOut,\n" + " int numConcavePairs, int maxContactCapacity\n" + " )\n" + "{\n" + " int i = get_global_id(0);\n" + " if (i>=numConcavePairs)\n" + " return;\n" + " int pairIdx = i;\n" + " int bodyIndexA = concavePairs[i].x;\n" + " int bodyIndexB = concavePairs[i].y;\n" + " int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;\n" + " int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;\n" + " int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;\n" + " int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;\n" + " if (collidables[collidableIndexB].m_shapeType==SHAPE_SPHERE)\n" + " {\n" + " int f = concavePairs[i].z;\n" + " btGpuFace face = faces[convexShapes[shapeIndexA].m_faceOffset+f];\n" + " \n" + " float4 verticesA[3];\n" + " for (int i=0;i<3;i++)\n" + " {\n" + " int index = indices[face.m_indexOffset+i];\n" + " float4 vert = vertices[convexShapes[shapeIndexA].m_vertexOffset+index];\n" + " verticesA[i] = vert;\n" + " }\n" + " float4 spherePos = rigidBodies[bodyIndexB].m_pos;\n" + " float sphereRadius = collidables[collidableIndexB].m_radius;\n" + " float4 convexPos = rigidBodies[bodyIndexA].m_pos;\n" + " float4 convexOrn = rigidBodies[bodyIndexA].m_quat;\n" + " computeContactSphereTriangle(i, bodyIndexB, bodyIndexA, collidableIndexB, collidableIndexA, \n" + " rigidBodies,collidables,\n" + " verticesA,\n" + " globalContactsOut, nGlobalContactsOut,maxContactCapacity,\n" + " spherePos,sphereRadius,convexPos,convexOrn, f);\n" + " return;\n" + " }\n" + "}\n"; diff --git a/src/Bullet3OpenCL/NarrowphaseCollision/kernels/satClipHullContacts.h b/src/Bullet3OpenCL/NarrowphaseCollision/kernels/satClipHullContacts.h index f0ecfc785..907809d8b 100644 --- a/src/Bullet3OpenCL/NarrowphaseCollision/kernels/satClipHullContacts.h +++ b/src/Bullet3OpenCL/NarrowphaseCollision/kernels/satClipHullContacts.h @@ -1,2099 +1,2098 @@ //this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project -static const char* satClipKernelsCL= \ -"#define TRIANGLE_NUM_CONVEX_FACES 5\n" -"#pragma OPENCL EXTENSION cl_amd_printf : enable\n" -"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n" -"#ifdef cl_ext_atomic_counters_32\n" -"#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n" -"#else\n" -"#define counter32_t volatile __global int*\n" -"#endif\n" -"#define GET_GROUP_IDX get_group_id(0)\n" -"#define GET_LOCAL_IDX get_local_id(0)\n" -"#define GET_GLOBAL_IDX get_global_id(0)\n" -"#define GET_GROUP_SIZE get_local_size(0)\n" -"#define GET_NUM_GROUPS get_num_groups(0)\n" -"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" -"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" -"#define AtomInc(x) atom_inc(&(x))\n" -"#define AtomInc1(x, out) out = atom_inc(&(x))\n" -"#define AppendInc(x, out) out = atomic_inc(x)\n" -"#define AtomAdd(x, value) atom_add(&(x), value)\n" -"#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n" -"#define AtomXhg(x, value) atom_xchg ( &(x), value )\n" -"#define max2 max\n" -"#define min2 min\n" -"typedef unsigned int u32;\n" -"#ifndef B3_CONTACT4DATA_H\n" -"#define B3_CONTACT4DATA_H\n" -"#ifndef B3_FLOAT4_H\n" -"#define B3_FLOAT4_H\n" -"#ifndef B3_PLATFORM_DEFINITIONS_H\n" -"#define B3_PLATFORM_DEFINITIONS_H\n" -"struct MyTest\n" -"{\n" -" int bla;\n" -"};\n" -"#ifdef __cplusplus\n" -"#else\n" -"//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n" -"#define B3_LARGE_FLOAT 1e18f\n" -"#define B3_INFINITY 1e18f\n" -"#define b3Assert(a)\n" -"#define b3ConstArray(a) __global const a*\n" -"#define b3AtomicInc atomic_inc\n" -"#define b3AtomicAdd atomic_add\n" -"#define b3Fabs fabs\n" -"#define b3Sqrt native_sqrt\n" -"#define b3Sin native_sin\n" -"#define b3Cos native_cos\n" -"#define B3_STATIC\n" -"#endif\n" -"#endif\n" -"#ifdef __cplusplus\n" -"#else\n" -" typedef float4 b3Float4;\n" -" #define b3Float4ConstArg const b3Float4\n" -" #define b3MakeFloat4 (float4)\n" -" float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" -" {\n" -" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" -" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" -" return dot(a1, b1);\n" -" }\n" -" b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" -" {\n" -" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" -" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" -" return cross(a1, b1);\n" -" }\n" -" #define b3MinFloat4 min\n" -" #define b3MaxFloat4 max\n" -" #define b3Normalized(a) normalize(a)\n" -"#endif \n" -" \n" -"inline bool b3IsAlmostZero(b3Float4ConstArg v)\n" -"{\n" -" if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" -" return false;\n" -" return true;\n" -"}\n" -"inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" -"{\n" -" float maxDot = -B3_INFINITY;\n" -" int i = 0;\n" -" int ptIndex = -1;\n" -" for( i = 0; i < vecLen; i++ )\n" -" {\n" -" float dot = b3Dot3F4(vecArray[i],vec);\n" -" \n" -" if( dot > maxDot )\n" -" {\n" -" maxDot = dot;\n" -" ptIndex = i;\n" -" }\n" -" }\n" -" b3Assert(ptIndex>=0);\n" -" if (ptIndex<0)\n" -" {\n" -" ptIndex = 0;\n" -" }\n" -" *dotOut = maxDot;\n" -" return ptIndex;\n" -"}\n" -"#endif //B3_FLOAT4_H\n" -"typedef struct b3Contact4Data b3Contact4Data_t;\n" -"struct b3Contact4Data\n" -"{\n" -" b3Float4 m_worldPosB[4];\n" -"// b3Float4 m_localPosA[4];\n" -"// b3Float4 m_localPosB[4];\n" -" b3Float4 m_worldNormalOnB; // w: m_nPoints\n" -" unsigned short m_restituitionCoeffCmp;\n" -" unsigned short m_frictionCoeffCmp;\n" -" int m_batchIdx;\n" -" int m_bodyAPtrAndSignBit;//x:m_bodyAPtr, y:m_bodyBPtr\n" -" int m_bodyBPtrAndSignBit;\n" -" int m_childIndexA;\n" -" int m_childIndexB;\n" -" int m_unused1;\n" -" int m_unused2;\n" -"};\n" -"inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact)\n" -"{\n" -" return (int)contact->m_worldNormalOnB.w;\n" -"};\n" -"inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints)\n" -"{\n" -" contact->m_worldNormalOnB.w = (float)numPoints;\n" -"};\n" -"#endif //B3_CONTACT4DATA_H\n" -"#ifndef B3_CONVEX_POLYHEDRON_DATA_H\n" -"#define B3_CONVEX_POLYHEDRON_DATA_H\n" -"#ifndef B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_FLOAT4_H\n" -"#ifndef B3_QUAT_H\n" -"#define B3_QUAT_H\n" -"#ifndef B3_PLATFORM_DEFINITIONS_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif\n" -"#endif\n" -"#ifndef B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -" typedef float4 b3Quat;\n" -" #define b3QuatConstArg const b3Quat\n" -" \n" -" \n" -"inline float4 b3FastNormalize4(float4 v)\n" -"{\n" -" v = (float4)(v.xyz,0.f);\n" -" return fast_normalize(v);\n" -"}\n" -" \n" -"inline b3Quat b3QuatMul(b3Quat a, b3Quat b);\n" -"inline b3Quat b3QuatNormalized(b3QuatConstArg in);\n" -"inline b3Quat b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec);\n" -"inline b3Quat b3QuatInvert(b3QuatConstArg q);\n" -"inline b3Quat b3QuatInverse(b3QuatConstArg q);\n" -"inline b3Quat b3QuatMul(b3QuatConstArg a, b3QuatConstArg b)\n" -"{\n" -" b3Quat ans;\n" -" ans = b3Cross3( a, b );\n" -" ans += a.w*b+b.w*a;\n" -"// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" -" ans.w = a.w*b.w - b3Dot3F4(a, b);\n" -" return ans;\n" -"}\n" -"inline b3Quat b3QuatNormalized(b3QuatConstArg in)\n" -"{\n" -" b3Quat q;\n" -" q=in;\n" -" //return b3FastNormalize4(in);\n" -" float len = native_sqrt(dot(q, q));\n" -" if(len > 0.f)\n" -" {\n" -" q *= 1.f / len;\n" -" }\n" -" else\n" -" {\n" -" q.x = q.y = q.z = 0.f;\n" -" q.w = 1.f;\n" -" }\n" -" return q;\n" -"}\n" -"inline float4 b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" -"{\n" -" b3Quat qInv = b3QuatInvert( q );\n" -" float4 vcpy = vec;\n" -" vcpy.w = 0.f;\n" -" float4 out = b3QuatMul(b3QuatMul(q,vcpy),qInv);\n" -" return out;\n" -"}\n" -"inline b3Quat b3QuatInverse(b3QuatConstArg q)\n" -"{\n" -" return (b3Quat)(-q.xyz, q.w);\n" -"}\n" -"inline b3Quat b3QuatInvert(b3QuatConstArg q)\n" -"{\n" -" return (b3Quat)(-q.xyz, q.w);\n" -"}\n" -"inline float4 b3QuatInvRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" -"{\n" -" return b3QuatRotate( b3QuatInvert( q ), vec );\n" -"}\n" -"inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)\n" -"{\n" -" return b3QuatRotate( orientation, point ) + (translation);\n" -"}\n" -" \n" -"#endif \n" -"#endif //B3_QUAT_H\n" -"typedef struct b3GpuFace b3GpuFace_t;\n" -"struct b3GpuFace\n" -"{\n" -" b3Float4 m_plane;\n" -" int m_indexOffset;\n" -" int m_numIndices;\n" -" int m_unusedPadding1;\n" -" int m_unusedPadding2;\n" -"};\n" -"typedef struct b3ConvexPolyhedronData b3ConvexPolyhedronData_t;\n" -"struct b3ConvexPolyhedronData\n" -"{\n" -" b3Float4 m_localCenter;\n" -" b3Float4 m_extents;\n" -" b3Float4 mC;\n" -" b3Float4 mE;\n" -" float m_radius;\n" -" int m_faceOffset;\n" -" int m_numFaces;\n" -" int m_numVertices;\n" -" int m_vertexOffset;\n" -" int m_uniqueEdgesOffset;\n" -" int m_numUniqueEdges;\n" -" int m_unused;\n" -"};\n" -"#endif //B3_CONVEX_POLYHEDRON_DATA_H\n" -"#ifndef B3_COLLIDABLE_H\n" -"#define B3_COLLIDABLE_H\n" -"#ifndef B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_FLOAT4_H\n" -"#ifndef B3_QUAT_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_QUAT_H\n" -"enum b3ShapeTypes\n" -"{\n" -" SHAPE_HEIGHT_FIELD=1,\n" -" SHAPE_CONVEX_HULL=3,\n" -" SHAPE_PLANE=4,\n" -" SHAPE_CONCAVE_TRIMESH=5,\n" -" SHAPE_COMPOUND_OF_CONVEX_HULLS=6,\n" -" SHAPE_SPHERE=7,\n" -" MAX_NUM_SHAPE_TYPES,\n" -"};\n" -"typedef struct b3Collidable b3Collidable_t;\n" -"struct b3Collidable\n" -"{\n" -" union {\n" -" int m_numChildShapes;\n" -" int m_bvhIndex;\n" -" };\n" -" union\n" -" {\n" -" float m_radius;\n" -" int m_compoundBvhIndex;\n" -" };\n" -" int m_shapeType;\n" -" int m_shapeIndex;\n" -"};\n" -"typedef struct b3GpuChildShape b3GpuChildShape_t;\n" -"struct b3GpuChildShape\n" -"{\n" -" b3Float4 m_childPosition;\n" -" b3Quat m_childOrientation;\n" -" int m_shapeIndex;\n" -" int m_unused0;\n" -" int m_unused1;\n" -" int m_unused2;\n" -"};\n" -"struct b3CompoundOverlappingPair\n" -"{\n" -" int m_bodyIndexA;\n" -" int m_bodyIndexB;\n" -"// int m_pairType;\n" -" int m_childShapeIndexA;\n" -" int m_childShapeIndexB;\n" -"};\n" -"#endif //B3_COLLIDABLE_H\n" -"#ifndef B3_RIGIDBODY_DATA_H\n" -"#define B3_RIGIDBODY_DATA_H\n" -"#ifndef B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_FLOAT4_H\n" -"#ifndef B3_QUAT_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_QUAT_H\n" -"#ifndef B3_MAT3x3_H\n" -"#define B3_MAT3x3_H\n" -"#ifndef B3_QUAT_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_QUAT_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"typedef struct\n" -"{\n" -" b3Float4 m_row[3];\n" -"}b3Mat3x3;\n" -"#define b3Mat3x3ConstArg const b3Mat3x3\n" -"#define b3GetRow(m,row) (m.m_row[row])\n" -"inline b3Mat3x3 b3QuatGetRotationMatrix(b3Quat quat)\n" -"{\n" -" b3Float4 quat2 = (b3Float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f);\n" -" b3Mat3x3 out;\n" -" out.m_row[0].x=1-2*quat2.y-2*quat2.z;\n" -" out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z;\n" -" out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y;\n" -" out.m_row[0].w = 0.f;\n" -" out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z;\n" -" out.m_row[1].y=1-2*quat2.x-2*quat2.z;\n" -" out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x;\n" -" out.m_row[1].w = 0.f;\n" -" out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y;\n" -" out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x;\n" -" out.m_row[2].z=1-2*quat2.x-2*quat2.y;\n" -" out.m_row[2].w = 0.f;\n" -" return out;\n" -"}\n" -"inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg matIn)\n" -"{\n" -" b3Mat3x3 out;\n" -" out.m_row[0] = fabs(matIn.m_row[0]);\n" -" out.m_row[1] = fabs(matIn.m_row[1]);\n" -" out.m_row[2] = fabs(matIn.m_row[2]);\n" -" return out;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtZero();\n" -"__inline\n" -"b3Mat3x3 mtIdentity();\n" -"__inline\n" -"b3Mat3x3 mtTranspose(b3Mat3x3 m);\n" -"__inline\n" -"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b);\n" -"__inline\n" -"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b);\n" -"__inline\n" -"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b);\n" -"__inline\n" -"b3Mat3x3 mtZero()\n" -"{\n" -" b3Mat3x3 m;\n" -" m.m_row[0] = (b3Float4)(0.f);\n" -" m.m_row[1] = (b3Float4)(0.f);\n" -" m.m_row[2] = (b3Float4)(0.f);\n" -" return m;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtIdentity()\n" -"{\n" -" b3Mat3x3 m;\n" -" m.m_row[0] = (b3Float4)(1,0,0,0);\n" -" m.m_row[1] = (b3Float4)(0,1,0,0);\n" -" m.m_row[2] = (b3Float4)(0,0,1,0);\n" -" return m;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtTranspose(b3Mat3x3 m)\n" -"{\n" -" b3Mat3x3 out;\n" -" out.m_row[0] = (b3Float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n" -" out.m_row[1] = (b3Float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n" -" out.m_row[2] = (b3Float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n" -" return out;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b)\n" -"{\n" -" b3Mat3x3 transB;\n" -" transB = mtTranspose( b );\n" -" b3Mat3x3 ans;\n" -" // why this doesn't run when 0ing in the for{}\n" -" a.m_row[0].w = 0.f;\n" -" a.m_row[1].w = 0.f;\n" -" a.m_row[2].w = 0.f;\n" -" for(int i=0; i<3; i++)\n" -" {\n" -"// a.m_row[i].w = 0.f;\n" -" ans.m_row[i].x = b3Dot3F4(a.m_row[i],transB.m_row[0]);\n" -" ans.m_row[i].y = b3Dot3F4(a.m_row[i],transB.m_row[1]);\n" -" ans.m_row[i].z = b3Dot3F4(a.m_row[i],transB.m_row[2]);\n" -" ans.m_row[i].w = 0.f;\n" -" }\n" -" return ans;\n" -"}\n" -"__inline\n" -"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b)\n" -"{\n" -" b3Float4 ans;\n" -" ans.x = b3Dot3F4( a.m_row[0], b );\n" -" ans.y = b3Dot3F4( a.m_row[1], b );\n" -" ans.z = b3Dot3F4( a.m_row[2], b );\n" -" ans.w = 0.f;\n" -" return ans;\n" -"}\n" -"__inline\n" -"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b)\n" -"{\n" -" b3Float4 colx = b3MakeFloat4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" -" b3Float4 coly = b3MakeFloat4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" -" b3Float4 colz = b3MakeFloat4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" -" b3Float4 ans;\n" -" ans.x = b3Dot3F4( a, colx );\n" -" ans.y = b3Dot3F4( a, coly );\n" -" ans.z = b3Dot3F4( a, colz );\n" -" return ans;\n" -"}\n" -"#endif\n" -"#endif //B3_MAT3x3_H\n" -"typedef struct b3RigidBodyData b3RigidBodyData_t;\n" -"struct b3RigidBodyData\n" -"{\n" -" b3Float4 m_pos;\n" -" b3Quat m_quat;\n" -" b3Float4 m_linVel;\n" -" b3Float4 m_angVel;\n" -" int m_collidableIdx;\n" -" float m_invMass;\n" -" float m_restituitionCoeff;\n" -" float m_frictionCoeff;\n" -"};\n" -"typedef struct b3InertiaData b3InertiaData_t;\n" -"struct b3InertiaData\n" -"{\n" -" b3Mat3x3 m_invInertiaWorld;\n" -" b3Mat3x3 m_initInvInertia;\n" -"};\n" -"#endif //B3_RIGIDBODY_DATA_H\n" -" \n" -"#define GET_NPOINTS(x) (x).m_worldNormalOnB.w\n" -"#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n" -"#define make_float4 (float4)\n" -"#define make_float2 (float2)\n" -"#define make_uint4 (uint4)\n" -"#define make_int4 (int4)\n" -"#define make_uint2 (uint2)\n" -"#define make_int2 (int2)\n" -"__inline\n" -"float fastDiv(float numerator, float denominator)\n" -"{\n" -" return native_divide(numerator, denominator); \n" -"// return numerator/denominator; \n" -"}\n" -"__inline\n" -"float4 fastDiv4(float4 numerator, float4 denominator)\n" -"{\n" -" return native_divide(numerator, denominator); \n" -"}\n" -"__inline\n" -"float4 cross3(float4 a, float4 b)\n" -"{\n" -" return cross(a,b);\n" -"}\n" -"//#define dot3F4 dot\n" -"__inline\n" -"float dot3F4(float4 a, float4 b)\n" -"{\n" -" float4 a1 = make_float4(a.xyz,0.f);\n" -" float4 b1 = make_float4(b.xyz,0.f);\n" -" return dot(a1, b1);\n" -"}\n" -"__inline\n" -"float4 fastNormalize4(float4 v)\n" -"{\n" -" return fast_normalize(v);\n" -"}\n" -"///////////////////////////////////////\n" -"// Quaternion\n" -"///////////////////////////////////////\n" -"typedef float4 Quaternion;\n" -"__inline\n" -"Quaternion qtMul(Quaternion a, Quaternion b);\n" -"__inline\n" -"Quaternion qtNormalize(Quaternion in);\n" -"__inline\n" -"float4 qtRotate(Quaternion q, float4 vec);\n" -"__inline\n" -"Quaternion qtInvert(Quaternion q);\n" -"__inline\n" -"Quaternion qtMul(Quaternion a, Quaternion b)\n" -"{\n" -" Quaternion ans;\n" -" ans = cross3( a, b );\n" -" ans += a.w*b+b.w*a;\n" -"// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" -" ans.w = a.w*b.w - dot3F4(a, b);\n" -" return ans;\n" -"}\n" -"__inline\n" -"Quaternion qtNormalize(Quaternion in)\n" -"{\n" -" return fastNormalize4(in);\n" -"// in /= length( in );\n" -"// return in;\n" -"}\n" -"__inline\n" -"float4 qtRotate(Quaternion q, float4 vec)\n" -"{\n" -" Quaternion qInv = qtInvert( q );\n" -" float4 vcpy = vec;\n" -" vcpy.w = 0.f;\n" -" float4 out = qtMul(qtMul(q,vcpy),qInv);\n" -" return out;\n" -"}\n" -"__inline\n" -"Quaternion qtInvert(Quaternion q)\n" -"{\n" -" return (Quaternion)(-q.xyz, q.w);\n" -"}\n" -"__inline\n" -"float4 qtInvRotate(const Quaternion q, float4 vec)\n" -"{\n" -" return qtRotate( qtInvert( q ), vec );\n" -"}\n" -"__inline\n" -"float4 transform(const float4* p, const float4* translation, const Quaternion* orientation)\n" -"{\n" -" return qtRotate( *orientation, *p ) + (*translation);\n" -"}\n" -"__inline\n" -"float4 normalize3(const float4 a)\n" -"{\n" -" float4 n = make_float4(a.x, a.y, a.z, 0.f);\n" -" return fastNormalize4( n );\n" -"}\n" -"__inline float4 lerp3(const float4 a,const float4 b, float t)\n" -"{\n" -" return make_float4( a.x + (b.x - a.x) * t,\n" -" a.y + (b.y - a.y) * t,\n" -" a.z + (b.z - a.z) * t,\n" -" 0.f);\n" -"}\n" -"// Clips a face to the back of a plane, return the number of vertices out, stored in ppVtxOut\n" -"int clipFaceGlobal(__global const float4* pVtxIn, int numVertsIn, float4 planeNormalWS,float planeEqWS, __global float4* ppVtxOut)\n" -"{\n" -" \n" -" int ve;\n" -" float ds, de;\n" -" int numVertsOut = 0;\n" -" //double-check next test\n" -" if (numVertsIn < 2)\n" -" return 0;\n" -" \n" -" float4 firstVertex=pVtxIn[numVertsIn-1];\n" -" float4 endVertex = pVtxIn[0];\n" -" \n" -" ds = dot3F4(planeNormalWS,firstVertex)+planeEqWS;\n" -" \n" -" for (ve = 0; ve < numVertsIn; ve++)\n" -" {\n" -" endVertex=pVtxIn[ve];\n" -" de = dot3F4(planeNormalWS,endVertex)+planeEqWS;\n" -" if (ds<0)\n" -" {\n" -" if (de<0)\n" -" {\n" -" // Start < 0, end < 0, so output endVertex\n" -" ppVtxOut[numVertsOut++] = endVertex;\n" -" }\n" -" else\n" -" {\n" -" // Start < 0, end >= 0, so output intersection\n" -" ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) );\n" -" }\n" -" }\n" -" else\n" -" {\n" -" if (de<0)\n" -" {\n" -" // Start >= 0, end < 0 so output intersection and end\n" -" ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) );\n" -" ppVtxOut[numVertsOut++] = endVertex;\n" -" }\n" -" }\n" -" firstVertex = endVertex;\n" -" ds = de;\n" -" }\n" -" return numVertsOut;\n" -"}\n" -"// Clips a face to the back of a plane, return the number of vertices out, stored in ppVtxOut\n" -"int clipFace(const float4* pVtxIn, int numVertsIn, float4 planeNormalWS,float planeEqWS, float4* ppVtxOut)\n" -"{\n" -" \n" -" int ve;\n" -" float ds, de;\n" -" int numVertsOut = 0;\n" -"//double-check next test\n" -" if (numVertsIn < 2)\n" -" return 0;\n" -" float4 firstVertex=pVtxIn[numVertsIn-1];\n" -" float4 endVertex = pVtxIn[0];\n" -" \n" -" ds = dot3F4(planeNormalWS,firstVertex)+planeEqWS;\n" -" for (ve = 0; ve < numVertsIn; ve++)\n" -" {\n" -" endVertex=pVtxIn[ve];\n" -" de = dot3F4(planeNormalWS,endVertex)+planeEqWS;\n" -" if (ds<0)\n" -" {\n" -" if (de<0)\n" -" {\n" -" // Start < 0, end < 0, so output endVertex\n" -" ppVtxOut[numVertsOut++] = endVertex;\n" -" }\n" -" else\n" -" {\n" -" // Start < 0, end >= 0, so output intersection\n" -" ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) );\n" -" }\n" -" }\n" -" else\n" -" {\n" -" if (de<0)\n" -" {\n" -" // Start >= 0, end < 0 so output intersection and end\n" -" ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) );\n" -" ppVtxOut[numVertsOut++] = endVertex;\n" -" }\n" -" }\n" -" firstVertex = endVertex;\n" -" ds = de;\n" -" }\n" -" return numVertsOut;\n" -"}\n" -"int clipFaceAgainstHull(const float4 separatingNormal, __global const b3ConvexPolyhedronData_t* hullA, \n" -" const float4 posA, const Quaternion ornA, float4* worldVertsB1, int numWorldVertsB1,\n" -" float4* worldVertsB2, int capacityWorldVertsB2,\n" -" const float minDist, float maxDist,\n" -" __global const float4* vertices,\n" -" __global const b3GpuFace_t* faces,\n" -" __global const int* indices,\n" -" float4* contactsOut,\n" -" int contactCapacity)\n" -"{\n" -" int numContactsOut = 0;\n" -" float4* pVtxIn = worldVertsB1;\n" -" float4* pVtxOut = worldVertsB2;\n" -" \n" -" int numVertsIn = numWorldVertsB1;\n" -" int numVertsOut = 0;\n" -" int closestFaceA=-1;\n" -" {\n" -" float dmin = FLT_MAX;\n" -" for(int face=0;facem_numFaces;face++)\n" -" {\n" -" const float4 Normal = make_float4(\n" -" faces[hullA->m_faceOffset+face].m_plane.x, \n" -" faces[hullA->m_faceOffset+face].m_plane.y, \n" -" faces[hullA->m_faceOffset+face].m_plane.z,0.f);\n" -" const float4 faceANormalWS = qtRotate(ornA,Normal);\n" -" \n" -" float d = dot3F4(faceANormalWS,separatingNormal);\n" -" if (d < dmin)\n" -" {\n" -" dmin = d;\n" -" closestFaceA = face;\n" -" }\n" -" }\n" -" }\n" -" if (closestFaceA<0)\n" -" return numContactsOut;\n" -" b3GpuFace_t polyA = faces[hullA->m_faceOffset+closestFaceA];\n" -" // clip polygon to back of planes of all faces of hull A that are adjacent to witness face\n" -" int numVerticesA = polyA.m_numIndices;\n" -" for(int e0=0;e0m_vertexOffset+indices[polyA.m_indexOffset+e0]];\n" -" const float4 b = vertices[hullA->m_vertexOffset+indices[polyA.m_indexOffset+((e0+1)%numVerticesA)]];\n" -" const float4 edge0 = a - b;\n" -" const float4 WorldEdge0 = qtRotate(ornA,edge0);\n" -" float4 planeNormalA = make_float4(polyA.m_plane.x,polyA.m_plane.y,polyA.m_plane.z,0.f);\n" -" float4 worldPlaneAnormal1 = qtRotate(ornA,planeNormalA);\n" -" float4 planeNormalWS1 = -cross3(WorldEdge0,worldPlaneAnormal1);\n" -" float4 worldA1 = transform(&a,&posA,&ornA);\n" -" float planeEqWS1 = -dot3F4(worldA1,planeNormalWS1);\n" -" \n" -" float4 planeNormalWS = planeNormalWS1;\n" -" float planeEqWS=planeEqWS1;\n" -" \n" -" //clip face\n" -" //clipFace(*pVtxIn, *pVtxOut,planeNormalWS,planeEqWS);\n" -" numVertsOut = clipFace(pVtxIn, numVertsIn, planeNormalWS,planeEqWS, pVtxOut);\n" -" //btSwap(pVtxIn,pVtxOut);\n" -" float4* tmp = pVtxOut;\n" -" pVtxOut = pVtxIn;\n" -" pVtxIn = tmp;\n" -" numVertsIn = numVertsOut;\n" -" numVertsOut = 0;\n" -" }\n" -" \n" -" // only keep points that are behind the witness face\n" -" {\n" -" float4 localPlaneNormal = make_float4(polyA.m_plane.x,polyA.m_plane.y,polyA.m_plane.z,0.f);\n" -" float localPlaneEq = polyA.m_plane.w;\n" -" float4 planeNormalWS = qtRotate(ornA,localPlaneNormal);\n" -" float planeEqWS=localPlaneEq-dot3F4(planeNormalWS,posA);\n" -" for (int i=0;im_numFaces;face++)\n" -" {\n" -" const float4 Normal = make_float4(\n" -" facesA[hullA->m_faceOffset+face].m_plane.x, \n" -" facesA[hullA->m_faceOffset+face].m_plane.y, \n" -" facesA[hullA->m_faceOffset+face].m_plane.z,0.f);\n" -" const float4 faceANormalWS = qtRotate(ornA,Normal);\n" -" \n" -" float d = dot3F4(faceANormalWS,separatingNormal);\n" -" if (d < dmin)\n" -" {\n" -" dmin = d;\n" -" closestFaceA = face;\n" -" }\n" -" }\n" -" }\n" -" if (closestFaceA<0)\n" -" return numContactsOut;\n" -" b3GpuFace_t polyA = facesA[hullA->m_faceOffset+closestFaceA];\n" -" // clip polygon to back of planes of all faces of hull A that are adjacent to witness face\n" -" int numVerticesA = polyA.m_numIndices;\n" -" for(int e0=0;e0m_vertexOffset+indicesA[polyA.m_indexOffset+e0]];\n" -" const float4 b = verticesA[hullA->m_vertexOffset+indicesA[polyA.m_indexOffset+((e0+1)%numVerticesA)]];\n" -" const float4 edge0 = a - b;\n" -" const float4 WorldEdge0 = qtRotate(ornA,edge0);\n" -" float4 planeNormalA = make_float4(polyA.m_plane.x,polyA.m_plane.y,polyA.m_plane.z,0.f);\n" -" float4 worldPlaneAnormal1 = qtRotate(ornA,planeNormalA);\n" -" float4 planeNormalWS1 = -cross3(WorldEdge0,worldPlaneAnormal1);\n" -" float4 worldA1 = transform(&a,&posA,&ornA);\n" -" float planeEqWS1 = -dot3F4(worldA1,planeNormalWS1);\n" -" \n" -" float4 planeNormalWS = planeNormalWS1;\n" -" float planeEqWS=planeEqWS1;\n" -" \n" -" //clip face\n" -" //clipFace(*pVtxIn, *pVtxOut,planeNormalWS,planeEqWS);\n" -" numVertsOut = clipFace(pVtxIn, numVertsIn, planeNormalWS,planeEqWS, pVtxOut);\n" -" //btSwap(pVtxIn,pVtxOut);\n" -" float4* tmp = pVtxOut;\n" -" pVtxOut = pVtxIn;\n" -" pVtxIn = tmp;\n" -" numVertsIn = numVertsOut;\n" -" numVertsOut = 0;\n" -" }\n" -" \n" -" // only keep points that are behind the witness face\n" -" {\n" -" float4 localPlaneNormal = make_float4(polyA.m_plane.x,polyA.m_plane.y,polyA.m_plane.z,0.f);\n" -" float localPlaneEq = polyA.m_plane.w;\n" -" float4 planeNormalWS = qtRotate(ornA,localPlaneNormal);\n" -" float planeEqWS=localPlaneEq-dot3F4(planeNormalWS,posA);\n" -" for (int i=0;im_numFaces;face++)\n" -" {\n" -" const float4 Normal = make_float4(faces[hullB->m_faceOffset+face].m_plane.x, \n" -" faces[hullB->m_faceOffset+face].m_plane.y, faces[hullB->m_faceOffset+face].m_plane.z,0.f);\n" -" const float4 WorldNormal = qtRotate(ornB, Normal);\n" -" float d = dot3F4(WorldNormal,separatingNormal);\n" -" if (d > dmax)\n" -" {\n" -" dmax = d;\n" -" closestFaceB = face;\n" -" }\n" -" }\n" -" }\n" -" {\n" -" const b3GpuFace_t polyB = faces[hullB->m_faceOffset+closestFaceB];\n" -" const int numVertices = polyB.m_numIndices;\n" -" for(int e0=0;e0m_vertexOffset+indices[polyB.m_indexOffset+e0]];\n" -" worldVertsB1[numWorldVertsB1++] = transform(&b,&posB,&ornB);\n" -" }\n" -" }\n" -" if (closestFaceB>=0)\n" -" {\n" -" numContactsOut = clipFaceAgainstHull(separatingNormal, hullA, \n" -" posA,ornA,\n" -" worldVertsB1,numWorldVertsB1,worldVertsB2,capacityWorldVerts, minDist, maxDist,vertices,\n" -" faces,\n" -" indices,localContactsOut,localContactCapacity);\n" -" }\n" -" return numContactsOut;\n" -"}\n" -"int clipHullAgainstHullLocalA(const float4 separatingNormal,\n" -" const b3ConvexPolyhedronData_t* hullA, __global const b3ConvexPolyhedronData_t* hullB, \n" -" const float4 posA, const Quaternion ornA,const float4 posB, const Quaternion ornB, \n" -" float4* worldVertsB1, float4* worldVertsB2, int capacityWorldVerts,\n" -" const float minDist, float maxDist,\n" -" const float4* verticesA,\n" -" const b3GpuFace_t* facesA,\n" -" const int* indicesA,\n" -" __global const float4* verticesB,\n" -" __global const b3GpuFace_t* facesB,\n" -" __global const int* indicesB,\n" -" float4* localContactsOut,\n" -" int localContactCapacity)\n" -"{\n" -" int numContactsOut = 0;\n" -" int numWorldVertsB1= 0;\n" -" int closestFaceB=-1;\n" -" float dmax = -FLT_MAX;\n" -" {\n" -" for(int face=0;facem_numFaces;face++)\n" -" {\n" -" const float4 Normal = make_float4(facesB[hullB->m_faceOffset+face].m_plane.x, \n" -" facesB[hullB->m_faceOffset+face].m_plane.y, facesB[hullB->m_faceOffset+face].m_plane.z,0.f);\n" -" const float4 WorldNormal = qtRotate(ornB, Normal);\n" -" float d = dot3F4(WorldNormal,separatingNormal);\n" -" if (d > dmax)\n" -" {\n" -" dmax = d;\n" -" closestFaceB = face;\n" -" }\n" -" }\n" -" }\n" -" {\n" -" const b3GpuFace_t polyB = facesB[hullB->m_faceOffset+closestFaceB];\n" -" const int numVertices = polyB.m_numIndices;\n" -" for(int e0=0;e0m_vertexOffset+indicesB[polyB.m_indexOffset+e0]];\n" -" worldVertsB1[numWorldVertsB1++] = transform(&b,&posB,&ornB);\n" -" }\n" -" }\n" -" if (closestFaceB>=0)\n" -" {\n" -" numContactsOut = clipFaceAgainstHullLocalA(separatingNormal, hullA, \n" -" posA,ornA,\n" -" worldVertsB1,numWorldVertsB1,worldVertsB2,capacityWorldVerts, minDist, maxDist,\n" -" verticesA,facesA,indicesA,\n" -" verticesB,facesB,indicesB,\n" -" localContactsOut,localContactCapacity);\n" -" }\n" -" return numContactsOut;\n" -"}\n" -"#define PARALLEL_SUM(v, n) for(int j=1; j v[i+offset].y)? v[i]: v[i+offset]; }\n" -"#define REDUCE_MIN(v, n) {int i=0; for(int offset=0; offset64)\n" -" nPoints = 64;\n" -" \n" -" float4 center = make_float4(0.f);\n" -" {\n" -" \n" -" for (int i=0;i a[ie].x )? a[0].x: a[ie].x;\n" -" a[0].y = (a[0].y > a[ie].y )? a[0].y: a[ie].y;\n" -" a[0].z = (a[0].z > a[ie].z )? a[0].z: a[ie].z;\n" -" a[0].w = (a[0].w > a[ie].w )? a[0].w: a[ie].w;\n" -" }\n" -" idx[0] = (int)a[0].x & 0xff;\n" -" idx[1] = (int)a[0].y & 0xff;\n" -" idx[2] = (int)a[0].z & 0xff;\n" -" idx[3] = (int)a[0].w & 0xff;\n" -" }\n" -" }\n" -" {\n" -" float2 h[64];\n" -" PARALLEL_DO( h[ie] = make_float2((float)ie, p[ie].w), nPoints );\n" -" REDUCE_MIN( h, nPoints );\n" -" max00 = h[0];\n" -" }\n" -" }\n" -" contactIdx[0] = idx[0];\n" -" contactIdx[1] = idx[1];\n" -" contactIdx[2] = idx[2];\n" -" contactIdx[3] = idx[3];\n" -" return 4;\n" -" }\n" -"}\n" -"__kernel void extractManifoldAndAddContactKernel(__global const int4* pairs, \n" -" __global const b3RigidBodyData_t* rigidBodies, \n" -" __global const float4* closestPointsWorld,\n" -" __global const float4* separatingNormalsWorld,\n" -" __global const int* contactCounts,\n" -" __global const int* contactOffsets,\n" -" __global struct b3Contact4Data* restrict contactsOut,\n" -" counter32_t nContactsOut,\n" -" int contactCapacity,\n" -" int numPairs,\n" -" int pairIndex\n" -" )\n" -"{\n" -" int idx = get_global_id(0);\n" -" \n" -" if (idxm_worldNormalOnB = -normal;\n" -" c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" -" c->m_batchIdx = idx;\n" -" int bodyA = pairs[pairIndex].x;\n" -" int bodyB = pairs[pairIndex].y;\n" -" c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0 ? -bodyA:bodyA;\n" -" c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0 ? -bodyB:bodyB;\n" -" c->m_childIndexA = -1;\n" -" c->m_childIndexB = -1;\n" -" for (int i=0;im_worldPosB[i] = localPoints[contactIdx[i]];\n" -" }\n" -" GET_NPOINTS(*c) = nContacts;\n" -" }\n" -" }\n" -"}\n" -"void trInverse(float4 translationIn, Quaternion orientationIn,\n" -" float4* translationOut, Quaternion* orientationOut)\n" -"{\n" -" *orientationOut = qtInvert(orientationIn);\n" -" *translationOut = qtRotate(*orientationOut, -translationIn);\n" -"}\n" -"void trMul(float4 translationA, Quaternion orientationA,\n" -" float4 translationB, Quaternion orientationB,\n" -" float4* translationOut, Quaternion* orientationOut)\n" -"{\n" -" *orientationOut = qtMul(orientationA,orientationB);\n" -" *translationOut = transform(&translationB,&translationA,&orientationA);\n" -"}\n" -"__kernel void clipHullHullKernel( __global int4* pairs, \n" -" __global const b3RigidBodyData_t* rigidBodies, \n" -" __global const b3Collidable_t* collidables,\n" -" __global const b3ConvexPolyhedronData_t* convexShapes, \n" -" __global const float4* vertices,\n" -" __global const float4* uniqueEdges,\n" -" __global const b3GpuFace_t* faces,\n" -" __global const int* indices,\n" -" __global const float4* separatingNormals,\n" -" __global const int* hasSeparatingAxis,\n" -" __global struct b3Contact4Data* restrict globalContactsOut,\n" -" counter32_t nGlobalContactsOut,\n" -" int numPairs,\n" -" int contactCapacity)\n" -"{\n" -" int i = get_global_id(0);\n" -" int pairIndex = i;\n" -" \n" -" float4 worldVertsB1[64];\n" -" float4 worldVertsB2[64];\n" -" int capacityWorldVerts = 64; \n" -" float4 localContactsOut[64];\n" -" int localContactCapacity=64;\n" -" \n" -" float minDist = -1e30f;\n" -" float maxDist = 0.02f;\n" -" if (i0)\n" -" {\n" -" float4 normal = -separatingNormals[i];\n" -" int nPoints = numLocalContactsOut;\n" -" float4* pointsIn = localContactsOut;\n" -" int contactIdx[4];// = {-1,-1,-1,-1};\n" -" contactIdx[0] = -1;\n" -" contactIdx[1] = -1;\n" -" contactIdx[2] = -1;\n" -" contactIdx[3] = -1;\n" -" \n" -" int nReducedContacts = extractManifoldSequential(pointsIn, nPoints, normal, contactIdx);\n" -" \n" -" \n" -" int mprContactIndex = pairs[pairIndex].z;\n" -" int dstIdx = mprContactIndex;\n" -" if (dstIdx<0)\n" -" {\n" -" AppendInc( nGlobalContactsOut, dstIdx );\n" -" }\n" -" if (dstIdxm_worldNormalOnB = -normal;\n" -" c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" -" c->m_batchIdx = pairIndex;\n" -" int bodyA = pairs[pairIndex].x;\n" -" int bodyB = pairs[pairIndex].y;\n" -" c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA;\n" -" c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB;\n" -" c->m_childIndexA = -1;\n" -" c->m_childIndexB = -1;\n" -" for (int i=0;i0||(mprContactIndex<0))\n" -" {\n" -" c->m_worldPosB[i] = pointsIn[contactIdx[i]];\n" -" }\n" -" }\n" -" GET_NPOINTS(*c) = nReducedContacts;\n" -" }\n" -" \n" -" }// if (numContactsOut>0)\n" -" }// if (hasSeparatingAxis[i])\n" -" }// if (i= 0)\n" -" {\n" -" collidableIndexA = gpuChildShapes[childShapeIndexA].m_shapeIndex;\n" -" float4 childPosA = gpuChildShapes[childShapeIndexA].m_childPosition;\n" -" float4 childOrnA = gpuChildShapes[childShapeIndexA].m_childOrientation;\n" -" float4 newPosA = qtRotate(ornA,childPosA)+posA;\n" -" float4 newOrnA = qtMul(ornA,childOrnA);\n" -" posA = newPosA;\n" -" ornA = newOrnA;\n" -" } else\n" -" {\n" -" collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;\n" -" }\n" -" \n" -" if (childShapeIndexB>=0)\n" -" {\n" -" collidableIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex;\n" -" float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition;\n" -" float4 childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation;\n" -" float4 newPosB = transform(&childPosB,&posB,&ornB);\n" -" float4 newOrnB = qtMul(ornB,childOrnB);\n" -" posB = newPosB;\n" -" ornB = newOrnB;\n" -" } else\n" -" {\n" -" collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx; \n" -" }\n" -" \n" -" int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;\n" -" int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;\n" -" \n" -" int numLocalContactsOut = clipHullAgainstHull(gpuCompoundSepNormalsOut[i],\n" -" &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],\n" -" posA,ornA,\n" -" posB,ornB,\n" -" worldVertsB1,worldVertsB2,capacityWorldVerts,\n" -" minDist, maxDist,\n" -" vertices,faces,indices,\n" -" localContactsOut,localContactCapacity);\n" -" \n" -" if (numLocalContactsOut>0)\n" -" {\n" -" float4 normal = -gpuCompoundSepNormalsOut[i];\n" -" int nPoints = numLocalContactsOut;\n" -" float4* pointsIn = localContactsOut;\n" -" int contactIdx[4];// = {-1,-1,-1,-1};\n" -" contactIdx[0] = -1;\n" -" contactIdx[1] = -1;\n" -" contactIdx[2] = -1;\n" -" contactIdx[3] = -1;\n" -" \n" -" int nReducedContacts = extractManifoldSequential(pointsIn, nPoints, normal, contactIdx);\n" -" \n" -" int dstIdx;\n" -" AppendInc( nGlobalContactsOut, dstIdx );\n" -" if ((dstIdx+nReducedContacts) < maxContactCapacity)\n" -" {\n" -" __global struct b3Contact4Data* c = globalContactsOut+ dstIdx;\n" -" c->m_worldNormalOnB = -normal;\n" -" c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" -" c->m_batchIdx = pairIndex;\n" -" int bodyA = gpuCompoundPairs[pairIndex].x;\n" -" int bodyB = gpuCompoundPairs[pairIndex].y;\n" -" c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA;\n" -" c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB;\n" -" c->m_childIndexA = childShapeIndexA;\n" -" c->m_childIndexB = childShapeIndexB;\n" -" for (int i=0;im_worldPosB[i] = pointsIn[contactIdx[i]];\n" -" }\n" -" GET_NPOINTS(*c) = nReducedContacts;\n" -" }\n" -" \n" -" }// if (numContactsOut>0)\n" -" }// if (gpuHasCompoundSepNormalsOut[i])\n" -" }// if (i 0.00001)\n" -" {\n" -" normalOnSurfaceB = diff / len;\n" -" }\n" -" float4 contactPosB = posB + normalOnSurfaceB*radiusB;\n" -" contactPosB.w = dist;\n" -" \n" -" int dstIdx;\n" -" AppendInc( nGlobalContactsOut, dstIdx );\n" -" if (dstIdx < contactCapacity)\n" -" {\n" -" __global struct b3Contact4Data* c = &globalContactsOut[dstIdx];\n" -" c->m_worldNormalOnB = -normalOnSurfaceB;\n" -" c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" -" c->m_batchIdx = pairIndex;\n" -" int bodyA = pairs[pairIndex].x;\n" -" int bodyB = pairs[pairIndex].y;\n" -" c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA;\n" -" c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB;\n" -" c->m_worldPosB[0] = contactPosB;\n" -" c->m_childIndexA = -1;\n" -" c->m_childIndexB = -1;\n" -" GET_NPOINTS(*c) = 1;\n" -" }//if (dstIdx < numPairs)\n" -" }//if ( len <= (radiusA+radiusB))\n" -" }//SHAPE_SPHERE SHAPE_SPHERE\n" -" }//if (i0)\n" -" {\n" -" float4 normal = -separatingNormals[i];\n" -" int nPoints = numLocalContactsOut;\n" -" float4* pointsIn = localContactsOut;\n" -" int contactIdx[4];// = {-1,-1,-1,-1};\n" -" contactIdx[0] = -1;\n" -" contactIdx[1] = -1;\n" -" contactIdx[2] = -1;\n" -" contactIdx[3] = -1;\n" -" \n" -" int nReducedContacts = extractManifoldSequential(pointsIn, nPoints, normal, contactIdx);\n" -" \n" -" int dstIdx;\n" -" AppendInc( nGlobalContactsOut, dstIdx );\n" -" if (dstIdxm_worldNormalOnB = -normal;\n" -" c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" -" c->m_batchIdx = pairIndex;\n" -" int bodyA = concavePairsIn[pairIndex].x;\n" -" int bodyB = concavePairsIn[pairIndex].y;\n" -" c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA;\n" -" c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB;\n" -" c->m_childIndexA = childShapeIndexA;\n" -" c->m_childIndexB = childShapeIndexB;\n" -" for (int i=0;im_worldPosB[i] = pointsIn[contactIdx[i]];\n" -" }\n" -" GET_NPOINTS(*c) = nReducedContacts;\n" -" }\n" -" \n" -" }// if (numContactsOut>0)\n" -" }// if (im_numFaces;face++)\n" -" {\n" -" const float4 Normal = make_float4(faces[hullB->m_faceOffset+face].m_plane.x,\n" -" faces[hullB->m_faceOffset+face].m_plane.y, faces[hullB->m_faceOffset+face].m_plane.z,0.f);\n" -" const float4 WorldNormal = qtRotate(ornB, Normal);\n" -" float d = dot3F4(WorldNormal,separatingNormal);\n" -" if (d > dmax)\n" -" {\n" -" dmax = d;\n" -" closestFaceB = face;\n" -" }\n" -" }\n" -" }\n" -" \n" -" {\n" -" const b3GpuFace_t polyB = faces[hullB->m_faceOffset+closestFaceB];\n" -" const int numVertices = polyB.m_numIndices;\n" -" for(int e0=0;e0m_vertexOffset+indices[polyB.m_indexOffset+e0]];\n" -" worldVertsB1[pairIndex*capacityWorldVerts+numWorldVertsB1++] = transform(&b,&posB,&ornB);\n" -" }\n" -" }\n" -" \n" -" int closestFaceA=-1;\n" -" {\n" -" float dmin = FLT_MAX;\n" -" for(int face=0;facem_numFaces;face++)\n" -" {\n" -" const float4 Normal = make_float4(\n" -" faces[hullA->m_faceOffset+face].m_plane.x,\n" -" faces[hullA->m_faceOffset+face].m_plane.y,\n" -" faces[hullA->m_faceOffset+face].m_plane.z,\n" -" 0.f);\n" -" const float4 faceANormalWS = qtRotate(ornA,Normal);\n" -" \n" -" float d = dot3F4(faceANormalWS,separatingNormal);\n" -" if (d < dmin)\n" -" {\n" -" dmin = d;\n" -" closestFaceA = face;\n" -" worldNormalsA1[pairIndex] = faceANormalWS;\n" -" }\n" -" }\n" -" }\n" -" \n" -" int numVerticesA = faces[hullA->m_faceOffset+closestFaceA].m_numIndices;\n" -" for(int e0=0;e0m_vertexOffset+indices[faces[hullA->m_faceOffset+closestFaceA].m_indexOffset+e0]];\n" -" worldVertsA1[pairIndex*capacityWorldVerts+e0] = transform(&a, &posA,&ornA);\n" -" }\n" -" \n" -" clippingFaces[pairIndex].x = closestFaceA;\n" -" clippingFaces[pairIndex].y = closestFaceB;\n" -" clippingFaces[pairIndex].z = numVerticesA;\n" -" clippingFaces[pairIndex].w = numWorldVertsB1;\n" -" \n" -" \n" -" return numContactsOut;\n" -"}\n" -"int clipFaces(__global float4* worldVertsA1,\n" -" __global float4* worldNormalsA1,\n" -" __global float4* worldVertsB1,\n" -" __global float4* worldVertsB2, \n" -" int capacityWorldVertsB2,\n" -" const float minDist, float maxDist,\n" -" __global int4* clippingFaces,\n" -" int pairIndex)\n" -"{\n" -" int numContactsOut = 0;\n" -" \n" -" int closestFaceA = clippingFaces[pairIndex].x;\n" -" int closestFaceB = clippingFaces[pairIndex].y;\n" -" int numVertsInA = clippingFaces[pairIndex].z;\n" -" int numVertsInB = clippingFaces[pairIndex].w;\n" -" \n" -" int numVertsOut = 0;\n" -" \n" -" if (closestFaceA<0)\n" -" return numContactsOut;\n" -" \n" -" __global float4* pVtxIn = &worldVertsB1[pairIndex*capacityWorldVertsB2];\n" -" __global float4* pVtxOut = &worldVertsB2[pairIndex*capacityWorldVertsB2];\n" -" \n" -" \n" -" \n" -" // clip polygon to back of planes of all faces of hull A that are adjacent to witness face\n" -" \n" -" for(int e0=0;e0=0)\n" -" {\n" -" \n" -" \n" -" \n" -" // clip polygon to back of planes of all faces of hull A that are adjacent to witness face\n" -" \n" -" for(int e0=0;e00)\n" -" {\n" -" __global float4* pointsIn = &worldVertsB2[pairIndex*vertexFaceCapacity];\n" -" float4 normal = -separatingNormals[i];\n" -" \n" -" int nReducedContacts = extractManifoldSequentialGlobal(pointsIn, nPoints, normal, &contactIdx);\n" -" \n" -" int mprContactIndex = pairs[pairIndex].z;\n" -" int dstIdx = mprContactIndex;\n" -" if (dstIdx<0)\n" -" {\n" -" AppendInc( nGlobalContactsOut, dstIdx );\n" -" }\n" -"//#if 0\n" -" \n" -" if (dstIdx < contactCapacity)\n" -" {\n" -" __global struct b3Contact4Data* c = &globalContactsOut[dstIdx];\n" -" c->m_worldNormalOnB = -normal;\n" -" c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" -" c->m_batchIdx = pairIndex;\n" -" int bodyA = pairs[pairIndex].x;\n" -" int bodyB = pairs[pairIndex].y;\n" -" pairs[pairIndex].w = dstIdx;\n" -" c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA;\n" -" c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB;\n" -" c->m_childIndexA =-1;\n" -" c->m_childIndexB =-1;\n" -" switch (nReducedContacts)\n" -" {\n" -" case 4:\n" -" c->m_worldPosB[3] = pointsIn[contactIdx.w];\n" -" case 3:\n" -" c->m_worldPosB[2] = pointsIn[contactIdx.z];\n" -" case 2:\n" -" c->m_worldPosB[1] = pointsIn[contactIdx.y];\n" -" case 1:\n" -" if (mprContactIndex<0)//test\n" -" c->m_worldPosB[0] = pointsIn[contactIdx.x];\n" -" default:\n" -" {\n" -" }\n" -" };\n" -" \n" -" GET_NPOINTS(*c) = nReducedContacts;\n" -" \n" -" }\n" -" \n" -" \n" -"//#endif\n" -" \n" -" }// if (numContactsOut>0)\n" -" }// if (hasSeparatingAxis[i])\n" -" }// if (i1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" + " return false;\n" + " return true;\n" + "}\n" + "inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" + "{\n" + " float maxDot = -B3_INFINITY;\n" + " int i = 0;\n" + " int ptIndex = -1;\n" + " for( i = 0; i < vecLen; i++ )\n" + " {\n" + " float dot = b3Dot3F4(vecArray[i],vec);\n" + " \n" + " if( dot > maxDot )\n" + " {\n" + " maxDot = dot;\n" + " ptIndex = i;\n" + " }\n" + " }\n" + " b3Assert(ptIndex>=0);\n" + " if (ptIndex<0)\n" + " {\n" + " ptIndex = 0;\n" + " }\n" + " *dotOut = maxDot;\n" + " return ptIndex;\n" + "}\n" + "#endif //B3_FLOAT4_H\n" + "typedef struct b3Contact4Data b3Contact4Data_t;\n" + "struct b3Contact4Data\n" + "{\n" + " b3Float4 m_worldPosB[4];\n" + "// b3Float4 m_localPosA[4];\n" + "// b3Float4 m_localPosB[4];\n" + " b3Float4 m_worldNormalOnB; // w: m_nPoints\n" + " unsigned short m_restituitionCoeffCmp;\n" + " unsigned short m_frictionCoeffCmp;\n" + " int m_batchIdx;\n" + " int m_bodyAPtrAndSignBit;//x:m_bodyAPtr, y:m_bodyBPtr\n" + " int m_bodyBPtrAndSignBit;\n" + " int m_childIndexA;\n" + " int m_childIndexB;\n" + " int m_unused1;\n" + " int m_unused2;\n" + "};\n" + "inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact)\n" + "{\n" + " return (int)contact->m_worldNormalOnB.w;\n" + "};\n" + "inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints)\n" + "{\n" + " contact->m_worldNormalOnB.w = (float)numPoints;\n" + "};\n" + "#endif //B3_CONTACT4DATA_H\n" + "#ifndef B3_CONVEX_POLYHEDRON_DATA_H\n" + "#define B3_CONVEX_POLYHEDRON_DATA_H\n" + "#ifndef B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_FLOAT4_H\n" + "#ifndef B3_QUAT_H\n" + "#define B3_QUAT_H\n" + "#ifndef B3_PLATFORM_DEFINITIONS_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif\n" + "#endif\n" + "#ifndef B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + " typedef float4 b3Quat;\n" + " #define b3QuatConstArg const b3Quat\n" + " \n" + " \n" + "inline float4 b3FastNormalize4(float4 v)\n" + "{\n" + " v = (float4)(v.xyz,0.f);\n" + " return fast_normalize(v);\n" + "}\n" + " \n" + "inline b3Quat b3QuatMul(b3Quat a, b3Quat b);\n" + "inline b3Quat b3QuatNormalized(b3QuatConstArg in);\n" + "inline b3Quat b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec);\n" + "inline b3Quat b3QuatInvert(b3QuatConstArg q);\n" + "inline b3Quat b3QuatInverse(b3QuatConstArg q);\n" + "inline b3Quat b3QuatMul(b3QuatConstArg a, b3QuatConstArg b)\n" + "{\n" + " b3Quat ans;\n" + " ans = b3Cross3( a, b );\n" + " ans += a.w*b+b.w*a;\n" + "// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" + " ans.w = a.w*b.w - b3Dot3F4(a, b);\n" + " return ans;\n" + "}\n" + "inline b3Quat b3QuatNormalized(b3QuatConstArg in)\n" + "{\n" + " b3Quat q;\n" + " q=in;\n" + " //return b3FastNormalize4(in);\n" + " float len = native_sqrt(dot(q, q));\n" + " if(len > 0.f)\n" + " {\n" + " q *= 1.f / len;\n" + " }\n" + " else\n" + " {\n" + " q.x = q.y = q.z = 0.f;\n" + " q.w = 1.f;\n" + " }\n" + " return q;\n" + "}\n" + "inline float4 b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" + "{\n" + " b3Quat qInv = b3QuatInvert( q );\n" + " float4 vcpy = vec;\n" + " vcpy.w = 0.f;\n" + " float4 out = b3QuatMul(b3QuatMul(q,vcpy),qInv);\n" + " return out;\n" + "}\n" + "inline b3Quat b3QuatInverse(b3QuatConstArg q)\n" + "{\n" + " return (b3Quat)(-q.xyz, q.w);\n" + "}\n" + "inline b3Quat b3QuatInvert(b3QuatConstArg q)\n" + "{\n" + " return (b3Quat)(-q.xyz, q.w);\n" + "}\n" + "inline float4 b3QuatInvRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" + "{\n" + " return b3QuatRotate( b3QuatInvert( q ), vec );\n" + "}\n" + "inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)\n" + "{\n" + " return b3QuatRotate( orientation, point ) + (translation);\n" + "}\n" + " \n" + "#endif \n" + "#endif //B3_QUAT_H\n" + "typedef struct b3GpuFace b3GpuFace_t;\n" + "struct b3GpuFace\n" + "{\n" + " b3Float4 m_plane;\n" + " int m_indexOffset;\n" + " int m_numIndices;\n" + " int m_unusedPadding1;\n" + " int m_unusedPadding2;\n" + "};\n" + "typedef struct b3ConvexPolyhedronData b3ConvexPolyhedronData_t;\n" + "struct b3ConvexPolyhedronData\n" + "{\n" + " b3Float4 m_localCenter;\n" + " b3Float4 m_extents;\n" + " b3Float4 mC;\n" + " b3Float4 mE;\n" + " float m_radius;\n" + " int m_faceOffset;\n" + " int m_numFaces;\n" + " int m_numVertices;\n" + " int m_vertexOffset;\n" + " int m_uniqueEdgesOffset;\n" + " int m_numUniqueEdges;\n" + " int m_unused;\n" + "};\n" + "#endif //B3_CONVEX_POLYHEDRON_DATA_H\n" + "#ifndef B3_COLLIDABLE_H\n" + "#define B3_COLLIDABLE_H\n" + "#ifndef B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_FLOAT4_H\n" + "#ifndef B3_QUAT_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_QUAT_H\n" + "enum b3ShapeTypes\n" + "{\n" + " SHAPE_HEIGHT_FIELD=1,\n" + " SHAPE_CONVEX_HULL=3,\n" + " SHAPE_PLANE=4,\n" + " SHAPE_CONCAVE_TRIMESH=5,\n" + " SHAPE_COMPOUND_OF_CONVEX_HULLS=6,\n" + " SHAPE_SPHERE=7,\n" + " MAX_NUM_SHAPE_TYPES,\n" + "};\n" + "typedef struct b3Collidable b3Collidable_t;\n" + "struct b3Collidable\n" + "{\n" + " union {\n" + " int m_numChildShapes;\n" + " int m_bvhIndex;\n" + " };\n" + " union\n" + " {\n" + " float m_radius;\n" + " int m_compoundBvhIndex;\n" + " };\n" + " int m_shapeType;\n" + " int m_shapeIndex;\n" + "};\n" + "typedef struct b3GpuChildShape b3GpuChildShape_t;\n" + "struct b3GpuChildShape\n" + "{\n" + " b3Float4 m_childPosition;\n" + " b3Quat m_childOrientation;\n" + " int m_shapeIndex;\n" + " int m_unused0;\n" + " int m_unused1;\n" + " int m_unused2;\n" + "};\n" + "struct b3CompoundOverlappingPair\n" + "{\n" + " int m_bodyIndexA;\n" + " int m_bodyIndexB;\n" + "// int m_pairType;\n" + " int m_childShapeIndexA;\n" + " int m_childShapeIndexB;\n" + "};\n" + "#endif //B3_COLLIDABLE_H\n" + "#ifndef B3_RIGIDBODY_DATA_H\n" + "#define B3_RIGIDBODY_DATA_H\n" + "#ifndef B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_FLOAT4_H\n" + "#ifndef B3_QUAT_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_QUAT_H\n" + "#ifndef B3_MAT3x3_H\n" + "#define B3_MAT3x3_H\n" + "#ifndef B3_QUAT_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_QUAT_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "typedef struct\n" + "{\n" + " b3Float4 m_row[3];\n" + "}b3Mat3x3;\n" + "#define b3Mat3x3ConstArg const b3Mat3x3\n" + "#define b3GetRow(m,row) (m.m_row[row])\n" + "inline b3Mat3x3 b3QuatGetRotationMatrix(b3Quat quat)\n" + "{\n" + " b3Float4 quat2 = (b3Float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f);\n" + " b3Mat3x3 out;\n" + " out.m_row[0].x=1-2*quat2.y-2*quat2.z;\n" + " out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z;\n" + " out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y;\n" + " out.m_row[0].w = 0.f;\n" + " out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z;\n" + " out.m_row[1].y=1-2*quat2.x-2*quat2.z;\n" + " out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x;\n" + " out.m_row[1].w = 0.f;\n" + " out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y;\n" + " out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x;\n" + " out.m_row[2].z=1-2*quat2.x-2*quat2.y;\n" + " out.m_row[2].w = 0.f;\n" + " return out;\n" + "}\n" + "inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg matIn)\n" + "{\n" + " b3Mat3x3 out;\n" + " out.m_row[0] = fabs(matIn.m_row[0]);\n" + " out.m_row[1] = fabs(matIn.m_row[1]);\n" + " out.m_row[2] = fabs(matIn.m_row[2]);\n" + " return out;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtZero();\n" + "__inline\n" + "b3Mat3x3 mtIdentity();\n" + "__inline\n" + "b3Mat3x3 mtTranspose(b3Mat3x3 m);\n" + "__inline\n" + "b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b);\n" + "__inline\n" + "b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b);\n" + "__inline\n" + "b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b);\n" + "__inline\n" + "b3Mat3x3 mtZero()\n" + "{\n" + " b3Mat3x3 m;\n" + " m.m_row[0] = (b3Float4)(0.f);\n" + " m.m_row[1] = (b3Float4)(0.f);\n" + " m.m_row[2] = (b3Float4)(0.f);\n" + " return m;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtIdentity()\n" + "{\n" + " b3Mat3x3 m;\n" + " m.m_row[0] = (b3Float4)(1,0,0,0);\n" + " m.m_row[1] = (b3Float4)(0,1,0,0);\n" + " m.m_row[2] = (b3Float4)(0,0,1,0);\n" + " return m;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtTranspose(b3Mat3x3 m)\n" + "{\n" + " b3Mat3x3 out;\n" + " out.m_row[0] = (b3Float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n" + " out.m_row[1] = (b3Float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n" + " out.m_row[2] = (b3Float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n" + " return out;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b)\n" + "{\n" + " b3Mat3x3 transB;\n" + " transB = mtTranspose( b );\n" + " b3Mat3x3 ans;\n" + " // why this doesn't run when 0ing in the for{}\n" + " a.m_row[0].w = 0.f;\n" + " a.m_row[1].w = 0.f;\n" + " a.m_row[2].w = 0.f;\n" + " for(int i=0; i<3; i++)\n" + " {\n" + "// a.m_row[i].w = 0.f;\n" + " ans.m_row[i].x = b3Dot3F4(a.m_row[i],transB.m_row[0]);\n" + " ans.m_row[i].y = b3Dot3F4(a.m_row[i],transB.m_row[1]);\n" + " ans.m_row[i].z = b3Dot3F4(a.m_row[i],transB.m_row[2]);\n" + " ans.m_row[i].w = 0.f;\n" + " }\n" + " return ans;\n" + "}\n" + "__inline\n" + "b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b)\n" + "{\n" + " b3Float4 ans;\n" + " ans.x = b3Dot3F4( a.m_row[0], b );\n" + " ans.y = b3Dot3F4( a.m_row[1], b );\n" + " ans.z = b3Dot3F4( a.m_row[2], b );\n" + " ans.w = 0.f;\n" + " return ans;\n" + "}\n" + "__inline\n" + "b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b)\n" + "{\n" + " b3Float4 colx = b3MakeFloat4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" + " b3Float4 coly = b3MakeFloat4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" + " b3Float4 colz = b3MakeFloat4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" + " b3Float4 ans;\n" + " ans.x = b3Dot3F4( a, colx );\n" + " ans.y = b3Dot3F4( a, coly );\n" + " ans.z = b3Dot3F4( a, colz );\n" + " return ans;\n" + "}\n" + "#endif\n" + "#endif //B3_MAT3x3_H\n" + "typedef struct b3RigidBodyData b3RigidBodyData_t;\n" + "struct b3RigidBodyData\n" + "{\n" + " b3Float4 m_pos;\n" + " b3Quat m_quat;\n" + " b3Float4 m_linVel;\n" + " b3Float4 m_angVel;\n" + " int m_collidableIdx;\n" + " float m_invMass;\n" + " float m_restituitionCoeff;\n" + " float m_frictionCoeff;\n" + "};\n" + "typedef struct b3InertiaData b3InertiaData_t;\n" + "struct b3InertiaData\n" + "{\n" + " b3Mat3x3 m_invInertiaWorld;\n" + " b3Mat3x3 m_initInvInertia;\n" + "};\n" + "#endif //B3_RIGIDBODY_DATA_H\n" + " \n" + "#define GET_NPOINTS(x) (x).m_worldNormalOnB.w\n" + "#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n" + "#define make_float4 (float4)\n" + "#define make_float2 (float2)\n" + "#define make_uint4 (uint4)\n" + "#define make_int4 (int4)\n" + "#define make_uint2 (uint2)\n" + "#define make_int2 (int2)\n" + "__inline\n" + "float fastDiv(float numerator, float denominator)\n" + "{\n" + " return native_divide(numerator, denominator); \n" + "// return numerator/denominator; \n" + "}\n" + "__inline\n" + "float4 fastDiv4(float4 numerator, float4 denominator)\n" + "{\n" + " return native_divide(numerator, denominator); \n" + "}\n" + "__inline\n" + "float4 cross3(float4 a, float4 b)\n" + "{\n" + " return cross(a,b);\n" + "}\n" + "//#define dot3F4 dot\n" + "__inline\n" + "float dot3F4(float4 a, float4 b)\n" + "{\n" + " float4 a1 = make_float4(a.xyz,0.f);\n" + " float4 b1 = make_float4(b.xyz,0.f);\n" + " return dot(a1, b1);\n" + "}\n" + "__inline\n" + "float4 fastNormalize4(float4 v)\n" + "{\n" + " return fast_normalize(v);\n" + "}\n" + "///////////////////////////////////////\n" + "// Quaternion\n" + "///////////////////////////////////////\n" + "typedef float4 Quaternion;\n" + "__inline\n" + "Quaternion qtMul(Quaternion a, Quaternion b);\n" + "__inline\n" + "Quaternion qtNormalize(Quaternion in);\n" + "__inline\n" + "float4 qtRotate(Quaternion q, float4 vec);\n" + "__inline\n" + "Quaternion qtInvert(Quaternion q);\n" + "__inline\n" + "Quaternion qtMul(Quaternion a, Quaternion b)\n" + "{\n" + " Quaternion ans;\n" + " ans = cross3( a, b );\n" + " ans += a.w*b+b.w*a;\n" + "// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" + " ans.w = a.w*b.w - dot3F4(a, b);\n" + " return ans;\n" + "}\n" + "__inline\n" + "Quaternion qtNormalize(Quaternion in)\n" + "{\n" + " return fastNormalize4(in);\n" + "// in /= length( in );\n" + "// return in;\n" + "}\n" + "__inline\n" + "float4 qtRotate(Quaternion q, float4 vec)\n" + "{\n" + " Quaternion qInv = qtInvert( q );\n" + " float4 vcpy = vec;\n" + " vcpy.w = 0.f;\n" + " float4 out = qtMul(qtMul(q,vcpy),qInv);\n" + " return out;\n" + "}\n" + "__inline\n" + "Quaternion qtInvert(Quaternion q)\n" + "{\n" + " return (Quaternion)(-q.xyz, q.w);\n" + "}\n" + "__inline\n" + "float4 qtInvRotate(const Quaternion q, float4 vec)\n" + "{\n" + " return qtRotate( qtInvert( q ), vec );\n" + "}\n" + "__inline\n" + "float4 transform(const float4* p, const float4* translation, const Quaternion* orientation)\n" + "{\n" + " return qtRotate( *orientation, *p ) + (*translation);\n" + "}\n" + "__inline\n" + "float4 normalize3(const float4 a)\n" + "{\n" + " float4 n = make_float4(a.x, a.y, a.z, 0.f);\n" + " return fastNormalize4( n );\n" + "}\n" + "__inline float4 lerp3(const float4 a,const float4 b, float t)\n" + "{\n" + " return make_float4( a.x + (b.x - a.x) * t,\n" + " a.y + (b.y - a.y) * t,\n" + " a.z + (b.z - a.z) * t,\n" + " 0.f);\n" + "}\n" + "// Clips a face to the back of a plane, return the number of vertices out, stored in ppVtxOut\n" + "int clipFaceGlobal(__global const float4* pVtxIn, int numVertsIn, float4 planeNormalWS,float planeEqWS, __global float4* ppVtxOut)\n" + "{\n" + " \n" + " int ve;\n" + " float ds, de;\n" + " int numVertsOut = 0;\n" + " //double-check next test\n" + " if (numVertsIn < 2)\n" + " return 0;\n" + " \n" + " float4 firstVertex=pVtxIn[numVertsIn-1];\n" + " float4 endVertex = pVtxIn[0];\n" + " \n" + " ds = dot3F4(planeNormalWS,firstVertex)+planeEqWS;\n" + " \n" + " for (ve = 0; ve < numVertsIn; ve++)\n" + " {\n" + " endVertex=pVtxIn[ve];\n" + " de = dot3F4(planeNormalWS,endVertex)+planeEqWS;\n" + " if (ds<0)\n" + " {\n" + " if (de<0)\n" + " {\n" + " // Start < 0, end < 0, so output endVertex\n" + " ppVtxOut[numVertsOut++] = endVertex;\n" + " }\n" + " else\n" + " {\n" + " // Start < 0, end >= 0, so output intersection\n" + " ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) );\n" + " }\n" + " }\n" + " else\n" + " {\n" + " if (de<0)\n" + " {\n" + " // Start >= 0, end < 0 so output intersection and end\n" + " ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) );\n" + " ppVtxOut[numVertsOut++] = endVertex;\n" + " }\n" + " }\n" + " firstVertex = endVertex;\n" + " ds = de;\n" + " }\n" + " return numVertsOut;\n" + "}\n" + "// Clips a face to the back of a plane, return the number of vertices out, stored in ppVtxOut\n" + "int clipFace(const float4* pVtxIn, int numVertsIn, float4 planeNormalWS,float planeEqWS, float4* ppVtxOut)\n" + "{\n" + " \n" + " int ve;\n" + " float ds, de;\n" + " int numVertsOut = 0;\n" + "//double-check next test\n" + " if (numVertsIn < 2)\n" + " return 0;\n" + " float4 firstVertex=pVtxIn[numVertsIn-1];\n" + " float4 endVertex = pVtxIn[0];\n" + " \n" + " ds = dot3F4(planeNormalWS,firstVertex)+planeEqWS;\n" + " for (ve = 0; ve < numVertsIn; ve++)\n" + " {\n" + " endVertex=pVtxIn[ve];\n" + " de = dot3F4(planeNormalWS,endVertex)+planeEqWS;\n" + " if (ds<0)\n" + " {\n" + " if (de<0)\n" + " {\n" + " // Start < 0, end < 0, so output endVertex\n" + " ppVtxOut[numVertsOut++] = endVertex;\n" + " }\n" + " else\n" + " {\n" + " // Start < 0, end >= 0, so output intersection\n" + " ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) );\n" + " }\n" + " }\n" + " else\n" + " {\n" + " if (de<0)\n" + " {\n" + " // Start >= 0, end < 0 so output intersection and end\n" + " ppVtxOut[numVertsOut++] = lerp3(firstVertex, endVertex,(ds * 1.f/(ds - de)) );\n" + " ppVtxOut[numVertsOut++] = endVertex;\n" + " }\n" + " }\n" + " firstVertex = endVertex;\n" + " ds = de;\n" + " }\n" + " return numVertsOut;\n" + "}\n" + "int clipFaceAgainstHull(const float4 separatingNormal, __global const b3ConvexPolyhedronData_t* hullA, \n" + " const float4 posA, const Quaternion ornA, float4* worldVertsB1, int numWorldVertsB1,\n" + " float4* worldVertsB2, int capacityWorldVertsB2,\n" + " const float minDist, float maxDist,\n" + " __global const float4* vertices,\n" + " __global const b3GpuFace_t* faces,\n" + " __global const int* indices,\n" + " float4* contactsOut,\n" + " int contactCapacity)\n" + "{\n" + " int numContactsOut = 0;\n" + " float4* pVtxIn = worldVertsB1;\n" + " float4* pVtxOut = worldVertsB2;\n" + " \n" + " int numVertsIn = numWorldVertsB1;\n" + " int numVertsOut = 0;\n" + " int closestFaceA=-1;\n" + " {\n" + " float dmin = FLT_MAX;\n" + " for(int face=0;facem_numFaces;face++)\n" + " {\n" + " const float4 Normal = make_float4(\n" + " faces[hullA->m_faceOffset+face].m_plane.x, \n" + " faces[hullA->m_faceOffset+face].m_plane.y, \n" + " faces[hullA->m_faceOffset+face].m_plane.z,0.f);\n" + " const float4 faceANormalWS = qtRotate(ornA,Normal);\n" + " \n" + " float d = dot3F4(faceANormalWS,separatingNormal);\n" + " if (d < dmin)\n" + " {\n" + " dmin = d;\n" + " closestFaceA = face;\n" + " }\n" + " }\n" + " }\n" + " if (closestFaceA<0)\n" + " return numContactsOut;\n" + " b3GpuFace_t polyA = faces[hullA->m_faceOffset+closestFaceA];\n" + " // clip polygon to back of planes of all faces of hull A that are adjacent to witness face\n" + " int numVerticesA = polyA.m_numIndices;\n" + " for(int e0=0;e0m_vertexOffset+indices[polyA.m_indexOffset+e0]];\n" + " const float4 b = vertices[hullA->m_vertexOffset+indices[polyA.m_indexOffset+((e0+1)%numVerticesA)]];\n" + " const float4 edge0 = a - b;\n" + " const float4 WorldEdge0 = qtRotate(ornA,edge0);\n" + " float4 planeNormalA = make_float4(polyA.m_plane.x,polyA.m_plane.y,polyA.m_plane.z,0.f);\n" + " float4 worldPlaneAnormal1 = qtRotate(ornA,planeNormalA);\n" + " float4 planeNormalWS1 = -cross3(WorldEdge0,worldPlaneAnormal1);\n" + " float4 worldA1 = transform(&a,&posA,&ornA);\n" + " float planeEqWS1 = -dot3F4(worldA1,planeNormalWS1);\n" + " \n" + " float4 planeNormalWS = planeNormalWS1;\n" + " float planeEqWS=planeEqWS1;\n" + " \n" + " //clip face\n" + " //clipFace(*pVtxIn, *pVtxOut,planeNormalWS,planeEqWS);\n" + " numVertsOut = clipFace(pVtxIn, numVertsIn, planeNormalWS,planeEqWS, pVtxOut);\n" + " //btSwap(pVtxIn,pVtxOut);\n" + " float4* tmp = pVtxOut;\n" + " pVtxOut = pVtxIn;\n" + " pVtxIn = tmp;\n" + " numVertsIn = numVertsOut;\n" + " numVertsOut = 0;\n" + " }\n" + " \n" + " // only keep points that are behind the witness face\n" + " {\n" + " float4 localPlaneNormal = make_float4(polyA.m_plane.x,polyA.m_plane.y,polyA.m_plane.z,0.f);\n" + " float localPlaneEq = polyA.m_plane.w;\n" + " float4 planeNormalWS = qtRotate(ornA,localPlaneNormal);\n" + " float planeEqWS=localPlaneEq-dot3F4(planeNormalWS,posA);\n" + " for (int i=0;im_numFaces;face++)\n" + " {\n" + " const float4 Normal = make_float4(\n" + " facesA[hullA->m_faceOffset+face].m_plane.x, \n" + " facesA[hullA->m_faceOffset+face].m_plane.y, \n" + " facesA[hullA->m_faceOffset+face].m_plane.z,0.f);\n" + " const float4 faceANormalWS = qtRotate(ornA,Normal);\n" + " \n" + " float d = dot3F4(faceANormalWS,separatingNormal);\n" + " if (d < dmin)\n" + " {\n" + " dmin = d;\n" + " closestFaceA = face;\n" + " }\n" + " }\n" + " }\n" + " if (closestFaceA<0)\n" + " return numContactsOut;\n" + " b3GpuFace_t polyA = facesA[hullA->m_faceOffset+closestFaceA];\n" + " // clip polygon to back of planes of all faces of hull A that are adjacent to witness face\n" + " int numVerticesA = polyA.m_numIndices;\n" + " for(int e0=0;e0m_vertexOffset+indicesA[polyA.m_indexOffset+e0]];\n" + " const float4 b = verticesA[hullA->m_vertexOffset+indicesA[polyA.m_indexOffset+((e0+1)%numVerticesA)]];\n" + " const float4 edge0 = a - b;\n" + " const float4 WorldEdge0 = qtRotate(ornA,edge0);\n" + " float4 planeNormalA = make_float4(polyA.m_plane.x,polyA.m_plane.y,polyA.m_plane.z,0.f);\n" + " float4 worldPlaneAnormal1 = qtRotate(ornA,planeNormalA);\n" + " float4 planeNormalWS1 = -cross3(WorldEdge0,worldPlaneAnormal1);\n" + " float4 worldA1 = transform(&a,&posA,&ornA);\n" + " float planeEqWS1 = -dot3F4(worldA1,planeNormalWS1);\n" + " \n" + " float4 planeNormalWS = planeNormalWS1;\n" + " float planeEqWS=planeEqWS1;\n" + " \n" + " //clip face\n" + " //clipFace(*pVtxIn, *pVtxOut,planeNormalWS,planeEqWS);\n" + " numVertsOut = clipFace(pVtxIn, numVertsIn, planeNormalWS,planeEqWS, pVtxOut);\n" + " //btSwap(pVtxIn,pVtxOut);\n" + " float4* tmp = pVtxOut;\n" + " pVtxOut = pVtxIn;\n" + " pVtxIn = tmp;\n" + " numVertsIn = numVertsOut;\n" + " numVertsOut = 0;\n" + " }\n" + " \n" + " // only keep points that are behind the witness face\n" + " {\n" + " float4 localPlaneNormal = make_float4(polyA.m_plane.x,polyA.m_plane.y,polyA.m_plane.z,0.f);\n" + " float localPlaneEq = polyA.m_plane.w;\n" + " float4 planeNormalWS = qtRotate(ornA,localPlaneNormal);\n" + " float planeEqWS=localPlaneEq-dot3F4(planeNormalWS,posA);\n" + " for (int i=0;im_numFaces;face++)\n" + " {\n" + " const float4 Normal = make_float4(faces[hullB->m_faceOffset+face].m_plane.x, \n" + " faces[hullB->m_faceOffset+face].m_plane.y, faces[hullB->m_faceOffset+face].m_plane.z,0.f);\n" + " const float4 WorldNormal = qtRotate(ornB, Normal);\n" + " float d = dot3F4(WorldNormal,separatingNormal);\n" + " if (d > dmax)\n" + " {\n" + " dmax = d;\n" + " closestFaceB = face;\n" + " }\n" + " }\n" + " }\n" + " {\n" + " const b3GpuFace_t polyB = faces[hullB->m_faceOffset+closestFaceB];\n" + " const int numVertices = polyB.m_numIndices;\n" + " for(int e0=0;e0m_vertexOffset+indices[polyB.m_indexOffset+e0]];\n" + " worldVertsB1[numWorldVertsB1++] = transform(&b,&posB,&ornB);\n" + " }\n" + " }\n" + " if (closestFaceB>=0)\n" + " {\n" + " numContactsOut = clipFaceAgainstHull(separatingNormal, hullA, \n" + " posA,ornA,\n" + " worldVertsB1,numWorldVertsB1,worldVertsB2,capacityWorldVerts, minDist, maxDist,vertices,\n" + " faces,\n" + " indices,localContactsOut,localContactCapacity);\n" + " }\n" + " return numContactsOut;\n" + "}\n" + "int clipHullAgainstHullLocalA(const float4 separatingNormal,\n" + " const b3ConvexPolyhedronData_t* hullA, __global const b3ConvexPolyhedronData_t* hullB, \n" + " const float4 posA, const Quaternion ornA,const float4 posB, const Quaternion ornB, \n" + " float4* worldVertsB1, float4* worldVertsB2, int capacityWorldVerts,\n" + " const float minDist, float maxDist,\n" + " const float4* verticesA,\n" + " const b3GpuFace_t* facesA,\n" + " const int* indicesA,\n" + " __global const float4* verticesB,\n" + " __global const b3GpuFace_t* facesB,\n" + " __global const int* indicesB,\n" + " float4* localContactsOut,\n" + " int localContactCapacity)\n" + "{\n" + " int numContactsOut = 0;\n" + " int numWorldVertsB1= 0;\n" + " int closestFaceB=-1;\n" + " float dmax = -FLT_MAX;\n" + " {\n" + " for(int face=0;facem_numFaces;face++)\n" + " {\n" + " const float4 Normal = make_float4(facesB[hullB->m_faceOffset+face].m_plane.x, \n" + " facesB[hullB->m_faceOffset+face].m_plane.y, facesB[hullB->m_faceOffset+face].m_plane.z,0.f);\n" + " const float4 WorldNormal = qtRotate(ornB, Normal);\n" + " float d = dot3F4(WorldNormal,separatingNormal);\n" + " if (d > dmax)\n" + " {\n" + " dmax = d;\n" + " closestFaceB = face;\n" + " }\n" + " }\n" + " }\n" + " {\n" + " const b3GpuFace_t polyB = facesB[hullB->m_faceOffset+closestFaceB];\n" + " const int numVertices = polyB.m_numIndices;\n" + " for(int e0=0;e0m_vertexOffset+indicesB[polyB.m_indexOffset+e0]];\n" + " worldVertsB1[numWorldVertsB1++] = transform(&b,&posB,&ornB);\n" + " }\n" + " }\n" + " if (closestFaceB>=0)\n" + " {\n" + " numContactsOut = clipFaceAgainstHullLocalA(separatingNormal, hullA, \n" + " posA,ornA,\n" + " worldVertsB1,numWorldVertsB1,worldVertsB2,capacityWorldVerts, minDist, maxDist,\n" + " verticesA,facesA,indicesA,\n" + " verticesB,facesB,indicesB,\n" + " localContactsOut,localContactCapacity);\n" + " }\n" + " return numContactsOut;\n" + "}\n" + "#define PARALLEL_SUM(v, n) for(int j=1; j v[i+offset].y)? v[i]: v[i+offset]; }\n" + "#define REDUCE_MIN(v, n) {int i=0; for(int offset=0; offset64)\n" + " nPoints = 64;\n" + " \n" + " float4 center = make_float4(0.f);\n" + " {\n" + " \n" + " for (int i=0;i a[ie].x )? a[0].x: a[ie].x;\n" + " a[0].y = (a[0].y > a[ie].y )? a[0].y: a[ie].y;\n" + " a[0].z = (a[0].z > a[ie].z )? a[0].z: a[ie].z;\n" + " a[0].w = (a[0].w > a[ie].w )? a[0].w: a[ie].w;\n" + " }\n" + " idx[0] = (int)a[0].x & 0xff;\n" + " idx[1] = (int)a[0].y & 0xff;\n" + " idx[2] = (int)a[0].z & 0xff;\n" + " idx[3] = (int)a[0].w & 0xff;\n" + " }\n" + " }\n" + " {\n" + " float2 h[64];\n" + " PARALLEL_DO( h[ie] = make_float2((float)ie, p[ie].w), nPoints );\n" + " REDUCE_MIN( h, nPoints );\n" + " max00 = h[0];\n" + " }\n" + " }\n" + " contactIdx[0] = idx[0];\n" + " contactIdx[1] = idx[1];\n" + " contactIdx[2] = idx[2];\n" + " contactIdx[3] = idx[3];\n" + " return 4;\n" + " }\n" + "}\n" + "__kernel void extractManifoldAndAddContactKernel(__global const int4* pairs, \n" + " __global const b3RigidBodyData_t* rigidBodies, \n" + " __global const float4* closestPointsWorld,\n" + " __global const float4* separatingNormalsWorld,\n" + " __global const int* contactCounts,\n" + " __global const int* contactOffsets,\n" + " __global struct b3Contact4Data* restrict contactsOut,\n" + " counter32_t nContactsOut,\n" + " int contactCapacity,\n" + " int numPairs,\n" + " int pairIndex\n" + " )\n" + "{\n" + " int idx = get_global_id(0);\n" + " \n" + " if (idxm_worldNormalOnB = -normal;\n" + " c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" + " c->m_batchIdx = idx;\n" + " int bodyA = pairs[pairIndex].x;\n" + " int bodyB = pairs[pairIndex].y;\n" + " c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0 ? -bodyA:bodyA;\n" + " c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0 ? -bodyB:bodyB;\n" + " c->m_childIndexA = -1;\n" + " c->m_childIndexB = -1;\n" + " for (int i=0;im_worldPosB[i] = localPoints[contactIdx[i]];\n" + " }\n" + " GET_NPOINTS(*c) = nContacts;\n" + " }\n" + " }\n" + "}\n" + "void trInverse(float4 translationIn, Quaternion orientationIn,\n" + " float4* translationOut, Quaternion* orientationOut)\n" + "{\n" + " *orientationOut = qtInvert(orientationIn);\n" + " *translationOut = qtRotate(*orientationOut, -translationIn);\n" + "}\n" + "void trMul(float4 translationA, Quaternion orientationA,\n" + " float4 translationB, Quaternion orientationB,\n" + " float4* translationOut, Quaternion* orientationOut)\n" + "{\n" + " *orientationOut = qtMul(orientationA,orientationB);\n" + " *translationOut = transform(&translationB,&translationA,&orientationA);\n" + "}\n" + "__kernel void clipHullHullKernel( __global int4* pairs, \n" + " __global const b3RigidBodyData_t* rigidBodies, \n" + " __global const b3Collidable_t* collidables,\n" + " __global const b3ConvexPolyhedronData_t* convexShapes, \n" + " __global const float4* vertices,\n" + " __global const float4* uniqueEdges,\n" + " __global const b3GpuFace_t* faces,\n" + " __global const int* indices,\n" + " __global const float4* separatingNormals,\n" + " __global const int* hasSeparatingAxis,\n" + " __global struct b3Contact4Data* restrict globalContactsOut,\n" + " counter32_t nGlobalContactsOut,\n" + " int numPairs,\n" + " int contactCapacity)\n" + "{\n" + " int i = get_global_id(0);\n" + " int pairIndex = i;\n" + " \n" + " float4 worldVertsB1[64];\n" + " float4 worldVertsB2[64];\n" + " int capacityWorldVerts = 64; \n" + " float4 localContactsOut[64];\n" + " int localContactCapacity=64;\n" + " \n" + " float minDist = -1e30f;\n" + " float maxDist = 0.02f;\n" + " if (i0)\n" + " {\n" + " float4 normal = -separatingNormals[i];\n" + " int nPoints = numLocalContactsOut;\n" + " float4* pointsIn = localContactsOut;\n" + " int contactIdx[4];// = {-1,-1,-1,-1};\n" + " contactIdx[0] = -1;\n" + " contactIdx[1] = -1;\n" + " contactIdx[2] = -1;\n" + " contactIdx[3] = -1;\n" + " \n" + " int nReducedContacts = extractManifoldSequential(pointsIn, nPoints, normal, contactIdx);\n" + " \n" + " \n" + " int mprContactIndex = pairs[pairIndex].z;\n" + " int dstIdx = mprContactIndex;\n" + " if (dstIdx<0)\n" + " {\n" + " AppendInc( nGlobalContactsOut, dstIdx );\n" + " }\n" + " if (dstIdxm_worldNormalOnB = -normal;\n" + " c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" + " c->m_batchIdx = pairIndex;\n" + " int bodyA = pairs[pairIndex].x;\n" + " int bodyB = pairs[pairIndex].y;\n" + " c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA;\n" + " c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB;\n" + " c->m_childIndexA = -1;\n" + " c->m_childIndexB = -1;\n" + " for (int i=0;i0||(mprContactIndex<0))\n" + " {\n" + " c->m_worldPosB[i] = pointsIn[contactIdx[i]];\n" + " }\n" + " }\n" + " GET_NPOINTS(*c) = nReducedContacts;\n" + " }\n" + " \n" + " }// if (numContactsOut>0)\n" + " }// if (hasSeparatingAxis[i])\n" + " }// if (i= 0)\n" + " {\n" + " collidableIndexA = gpuChildShapes[childShapeIndexA].m_shapeIndex;\n" + " float4 childPosA = gpuChildShapes[childShapeIndexA].m_childPosition;\n" + " float4 childOrnA = gpuChildShapes[childShapeIndexA].m_childOrientation;\n" + " float4 newPosA = qtRotate(ornA,childPosA)+posA;\n" + " float4 newOrnA = qtMul(ornA,childOrnA);\n" + " posA = newPosA;\n" + " ornA = newOrnA;\n" + " } else\n" + " {\n" + " collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;\n" + " }\n" + " \n" + " if (childShapeIndexB>=0)\n" + " {\n" + " collidableIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex;\n" + " float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition;\n" + " float4 childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation;\n" + " float4 newPosB = transform(&childPosB,&posB,&ornB);\n" + " float4 newOrnB = qtMul(ornB,childOrnB);\n" + " posB = newPosB;\n" + " ornB = newOrnB;\n" + " } else\n" + " {\n" + " collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx; \n" + " }\n" + " \n" + " int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;\n" + " int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;\n" + " \n" + " int numLocalContactsOut = clipHullAgainstHull(gpuCompoundSepNormalsOut[i],\n" + " &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],\n" + " posA,ornA,\n" + " posB,ornB,\n" + " worldVertsB1,worldVertsB2,capacityWorldVerts,\n" + " minDist, maxDist,\n" + " vertices,faces,indices,\n" + " localContactsOut,localContactCapacity);\n" + " \n" + " if (numLocalContactsOut>0)\n" + " {\n" + " float4 normal = -gpuCompoundSepNormalsOut[i];\n" + " int nPoints = numLocalContactsOut;\n" + " float4* pointsIn = localContactsOut;\n" + " int contactIdx[4];// = {-1,-1,-1,-1};\n" + " contactIdx[0] = -1;\n" + " contactIdx[1] = -1;\n" + " contactIdx[2] = -1;\n" + " contactIdx[3] = -1;\n" + " \n" + " int nReducedContacts = extractManifoldSequential(pointsIn, nPoints, normal, contactIdx);\n" + " \n" + " int dstIdx;\n" + " AppendInc( nGlobalContactsOut, dstIdx );\n" + " if ((dstIdx+nReducedContacts) < maxContactCapacity)\n" + " {\n" + " __global struct b3Contact4Data* c = globalContactsOut+ dstIdx;\n" + " c->m_worldNormalOnB = -normal;\n" + " c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" + " c->m_batchIdx = pairIndex;\n" + " int bodyA = gpuCompoundPairs[pairIndex].x;\n" + " int bodyB = gpuCompoundPairs[pairIndex].y;\n" + " c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA;\n" + " c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB;\n" + " c->m_childIndexA = childShapeIndexA;\n" + " c->m_childIndexB = childShapeIndexB;\n" + " for (int i=0;im_worldPosB[i] = pointsIn[contactIdx[i]];\n" + " }\n" + " GET_NPOINTS(*c) = nReducedContacts;\n" + " }\n" + " \n" + " }// if (numContactsOut>0)\n" + " }// if (gpuHasCompoundSepNormalsOut[i])\n" + " }// if (i 0.00001)\n" + " {\n" + " normalOnSurfaceB = diff / len;\n" + " }\n" + " float4 contactPosB = posB + normalOnSurfaceB*radiusB;\n" + " contactPosB.w = dist;\n" + " \n" + " int dstIdx;\n" + " AppendInc( nGlobalContactsOut, dstIdx );\n" + " if (dstIdx < contactCapacity)\n" + " {\n" + " __global struct b3Contact4Data* c = &globalContactsOut[dstIdx];\n" + " c->m_worldNormalOnB = -normalOnSurfaceB;\n" + " c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" + " c->m_batchIdx = pairIndex;\n" + " int bodyA = pairs[pairIndex].x;\n" + " int bodyB = pairs[pairIndex].y;\n" + " c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA;\n" + " c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB;\n" + " c->m_worldPosB[0] = contactPosB;\n" + " c->m_childIndexA = -1;\n" + " c->m_childIndexB = -1;\n" + " GET_NPOINTS(*c) = 1;\n" + " }//if (dstIdx < numPairs)\n" + " }//if ( len <= (radiusA+radiusB))\n" + " }//SHAPE_SPHERE SHAPE_SPHERE\n" + " }//if (i0)\n" + " {\n" + " float4 normal = -separatingNormals[i];\n" + " int nPoints = numLocalContactsOut;\n" + " float4* pointsIn = localContactsOut;\n" + " int contactIdx[4];// = {-1,-1,-1,-1};\n" + " contactIdx[0] = -1;\n" + " contactIdx[1] = -1;\n" + " contactIdx[2] = -1;\n" + " contactIdx[3] = -1;\n" + " \n" + " int nReducedContacts = extractManifoldSequential(pointsIn, nPoints, normal, contactIdx);\n" + " \n" + " int dstIdx;\n" + " AppendInc( nGlobalContactsOut, dstIdx );\n" + " if (dstIdxm_worldNormalOnB = -normal;\n" + " c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" + " c->m_batchIdx = pairIndex;\n" + " int bodyA = concavePairsIn[pairIndex].x;\n" + " int bodyB = concavePairsIn[pairIndex].y;\n" + " c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA;\n" + " c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB;\n" + " c->m_childIndexA = childShapeIndexA;\n" + " c->m_childIndexB = childShapeIndexB;\n" + " for (int i=0;im_worldPosB[i] = pointsIn[contactIdx[i]];\n" + " }\n" + " GET_NPOINTS(*c) = nReducedContacts;\n" + " }\n" + " \n" + " }// if (numContactsOut>0)\n" + " }// if (im_numFaces;face++)\n" + " {\n" + " const float4 Normal = make_float4(faces[hullB->m_faceOffset+face].m_plane.x,\n" + " faces[hullB->m_faceOffset+face].m_plane.y, faces[hullB->m_faceOffset+face].m_plane.z,0.f);\n" + " const float4 WorldNormal = qtRotate(ornB, Normal);\n" + " float d = dot3F4(WorldNormal,separatingNormal);\n" + " if (d > dmax)\n" + " {\n" + " dmax = d;\n" + " closestFaceB = face;\n" + " }\n" + " }\n" + " }\n" + " \n" + " {\n" + " const b3GpuFace_t polyB = faces[hullB->m_faceOffset+closestFaceB];\n" + " const int numVertices = polyB.m_numIndices;\n" + " for(int e0=0;e0m_vertexOffset+indices[polyB.m_indexOffset+e0]];\n" + " worldVertsB1[pairIndex*capacityWorldVerts+numWorldVertsB1++] = transform(&b,&posB,&ornB);\n" + " }\n" + " }\n" + " \n" + " int closestFaceA=-1;\n" + " {\n" + " float dmin = FLT_MAX;\n" + " for(int face=0;facem_numFaces;face++)\n" + " {\n" + " const float4 Normal = make_float4(\n" + " faces[hullA->m_faceOffset+face].m_plane.x,\n" + " faces[hullA->m_faceOffset+face].m_plane.y,\n" + " faces[hullA->m_faceOffset+face].m_plane.z,\n" + " 0.f);\n" + " const float4 faceANormalWS = qtRotate(ornA,Normal);\n" + " \n" + " float d = dot3F4(faceANormalWS,separatingNormal);\n" + " if (d < dmin)\n" + " {\n" + " dmin = d;\n" + " closestFaceA = face;\n" + " worldNormalsA1[pairIndex] = faceANormalWS;\n" + " }\n" + " }\n" + " }\n" + " \n" + " int numVerticesA = faces[hullA->m_faceOffset+closestFaceA].m_numIndices;\n" + " for(int e0=0;e0m_vertexOffset+indices[faces[hullA->m_faceOffset+closestFaceA].m_indexOffset+e0]];\n" + " worldVertsA1[pairIndex*capacityWorldVerts+e0] = transform(&a, &posA,&ornA);\n" + " }\n" + " \n" + " clippingFaces[pairIndex].x = closestFaceA;\n" + " clippingFaces[pairIndex].y = closestFaceB;\n" + " clippingFaces[pairIndex].z = numVerticesA;\n" + " clippingFaces[pairIndex].w = numWorldVertsB1;\n" + " \n" + " \n" + " return numContactsOut;\n" + "}\n" + "int clipFaces(__global float4* worldVertsA1,\n" + " __global float4* worldNormalsA1,\n" + " __global float4* worldVertsB1,\n" + " __global float4* worldVertsB2, \n" + " int capacityWorldVertsB2,\n" + " const float minDist, float maxDist,\n" + " __global int4* clippingFaces,\n" + " int pairIndex)\n" + "{\n" + " int numContactsOut = 0;\n" + " \n" + " int closestFaceA = clippingFaces[pairIndex].x;\n" + " int closestFaceB = clippingFaces[pairIndex].y;\n" + " int numVertsInA = clippingFaces[pairIndex].z;\n" + " int numVertsInB = clippingFaces[pairIndex].w;\n" + " \n" + " int numVertsOut = 0;\n" + " \n" + " if (closestFaceA<0)\n" + " return numContactsOut;\n" + " \n" + " __global float4* pVtxIn = &worldVertsB1[pairIndex*capacityWorldVertsB2];\n" + " __global float4* pVtxOut = &worldVertsB2[pairIndex*capacityWorldVertsB2];\n" + " \n" + " \n" + " \n" + " // clip polygon to back of planes of all faces of hull A that are adjacent to witness face\n" + " \n" + " for(int e0=0;e0=0)\n" + " {\n" + " \n" + " \n" + " \n" + " // clip polygon to back of planes of all faces of hull A that are adjacent to witness face\n" + " \n" + " for(int e0=0;e00)\n" + " {\n" + " __global float4* pointsIn = &worldVertsB2[pairIndex*vertexFaceCapacity];\n" + " float4 normal = -separatingNormals[i];\n" + " \n" + " int nReducedContacts = extractManifoldSequentialGlobal(pointsIn, nPoints, normal, &contactIdx);\n" + " \n" + " int mprContactIndex = pairs[pairIndex].z;\n" + " int dstIdx = mprContactIndex;\n" + " if (dstIdx<0)\n" + " {\n" + " AppendInc( nGlobalContactsOut, dstIdx );\n" + " }\n" + "//#if 0\n" + " \n" + " if (dstIdx < contactCapacity)\n" + " {\n" + " __global struct b3Contact4Data* c = &globalContactsOut[dstIdx];\n" + " c->m_worldNormalOnB = -normal;\n" + " c->m_restituitionCoeffCmp = (0.f*0xffff);c->m_frictionCoeffCmp = (0.7f*0xffff);\n" + " c->m_batchIdx = pairIndex;\n" + " int bodyA = pairs[pairIndex].x;\n" + " int bodyB = pairs[pairIndex].y;\n" + " pairs[pairIndex].w = dstIdx;\n" + " c->m_bodyAPtrAndSignBit = rigidBodies[bodyA].m_invMass==0?-bodyA:bodyA;\n" + " c->m_bodyBPtrAndSignBit = rigidBodies[bodyB].m_invMass==0?-bodyB:bodyB;\n" + " c->m_childIndexA =-1;\n" + " c->m_childIndexB =-1;\n" + " switch (nReducedContacts)\n" + " {\n" + " case 4:\n" + " c->m_worldPosB[3] = pointsIn[contactIdx.w];\n" + " case 3:\n" + " c->m_worldPosB[2] = pointsIn[contactIdx.z];\n" + " case 2:\n" + " c->m_worldPosB[1] = pointsIn[contactIdx.y];\n" + " case 1:\n" + " if (mprContactIndex<0)//test\n" + " c->m_worldPosB[0] = pointsIn[contactIdx.x];\n" + " default:\n" + " {\n" + " }\n" + " };\n" + " \n" + " GET_NPOINTS(*c) = nReducedContacts;\n" + " \n" + " }\n" + " \n" + " \n" + "//#endif\n" + " \n" + " }// if (numContactsOut>0)\n" + " }// if (hasSeparatingAxis[i])\n" + " }// if (im_escapeIndexOrTriangleIndex&~(y));\n" -"}\n" -"int getTriangleIndexGlobal(__global const b3QuantizedBvhNode* rootNode)\n" -"{\n" -" unsigned int x=0;\n" -" unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS);\n" -" // Get only the lower bits where the triangle index is stored\n" -" return (rootNode->m_escapeIndexOrTriangleIndex&~(y));\n" -"}\n" -"int isLeafNode(const b3QuantizedBvhNode* rootNode)\n" -"{\n" -" //skipindex is negative (internal node), triangleindex >=0 (leafnode)\n" -" return (rootNode->m_escapeIndexOrTriangleIndex >= 0)? 1 : 0;\n" -"}\n" -"int isLeafNodeGlobal(__global const b3QuantizedBvhNode* rootNode)\n" -"{\n" -" //skipindex is negative (internal node), triangleindex >=0 (leafnode)\n" -" return (rootNode->m_escapeIndexOrTriangleIndex >= 0)? 1 : 0;\n" -"}\n" -" \n" -"int getEscapeIndex(const b3QuantizedBvhNode* rootNode)\n" -"{\n" -" return -rootNode->m_escapeIndexOrTriangleIndex;\n" -"}\n" -"int getEscapeIndexGlobal(__global const b3QuantizedBvhNode* rootNode)\n" -"{\n" -" return -rootNode->m_escapeIndexOrTriangleIndex;\n" -"}\n" -"typedef struct\n" -"{\n" -" //12 bytes\n" -" unsigned short int m_quantizedAabbMin[3];\n" -" unsigned short int m_quantizedAabbMax[3];\n" -" //4 bytes, points to the root of the subtree\n" -" int m_rootNodeIndex;\n" -" //4 bytes\n" -" int m_subtreeSize;\n" -" int m_padding[3];\n" -"} b3BvhSubtreeInfo;\n" -"typedef struct\n" -"{\n" -" float4 m_childPosition;\n" -" float4 m_childOrientation;\n" -" int m_shapeIndex;\n" -" int m_unused0;\n" -" int m_unused1;\n" -" int m_unused2;\n" -"} btGpuChildShape;\n" -"typedef struct\n" -"{\n" -" float4 m_pos;\n" -" float4 m_quat;\n" -" float4 m_linVel;\n" -" float4 m_angVel;\n" -" u32 m_collidableIdx;\n" -" float m_invMass;\n" -" float m_restituitionCoeff;\n" -" float m_frictionCoeff;\n" -"} BodyData;\n" -"typedef struct \n" -"{\n" -" float4 m_localCenter;\n" -" float4 m_extents;\n" -" float4 mC;\n" -" float4 mE;\n" -" \n" -" float m_radius;\n" -" int m_faceOffset;\n" -" int m_numFaces;\n" -" int m_numVertices;\n" -" int m_vertexOffset;\n" -" int m_uniqueEdgesOffset;\n" -" int m_numUniqueEdges;\n" -" int m_unused;\n" -"} ConvexPolyhedronCL;\n" -"typedef struct \n" -"{\n" -" union\n" -" {\n" -" float4 m_min;\n" -" float m_minElems[4];\n" -" int m_minIndices[4];\n" -" };\n" -" union\n" -" {\n" -" float4 m_max;\n" -" float m_maxElems[4];\n" -" int m_maxIndices[4];\n" -" };\n" -"} btAabbCL;\n" -"#ifndef B3_AABB_H\n" -"#define B3_AABB_H\n" -"#ifndef B3_FLOAT4_H\n" -"#define B3_FLOAT4_H\n" -"#ifndef B3_PLATFORM_DEFINITIONS_H\n" -"#define B3_PLATFORM_DEFINITIONS_H\n" -"struct MyTest\n" -"{\n" -" int bla;\n" -"};\n" -"#ifdef __cplusplus\n" -"#else\n" -"//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n" -"#define B3_LARGE_FLOAT 1e18f\n" -"#define B3_INFINITY 1e18f\n" -"#define b3Assert(a)\n" -"#define b3ConstArray(a) __global const a*\n" -"#define b3AtomicInc atomic_inc\n" -"#define b3AtomicAdd atomic_add\n" -"#define b3Fabs fabs\n" -"#define b3Sqrt native_sqrt\n" -"#define b3Sin native_sin\n" -"#define b3Cos native_cos\n" -"#define B3_STATIC\n" -"#endif\n" -"#endif\n" -"#ifdef __cplusplus\n" -"#else\n" -" typedef float4 b3Float4;\n" -" #define b3Float4ConstArg const b3Float4\n" -" #define b3MakeFloat4 (float4)\n" -" float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" -" {\n" -" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" -" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" -" return dot(a1, b1);\n" -" }\n" -" b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" -" {\n" -" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" -" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" -" return cross(a1, b1);\n" -" }\n" -" #define b3MinFloat4 min\n" -" #define b3MaxFloat4 max\n" -" #define b3Normalized(a) normalize(a)\n" -"#endif \n" -" \n" -"inline bool b3IsAlmostZero(b3Float4ConstArg v)\n" -"{\n" -" if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" -" return false;\n" -" return true;\n" -"}\n" -"inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" -"{\n" -" float maxDot = -B3_INFINITY;\n" -" int i = 0;\n" -" int ptIndex = -1;\n" -" for( i = 0; i < vecLen; i++ )\n" -" {\n" -" float dot = b3Dot3F4(vecArray[i],vec);\n" -" \n" -" if( dot > maxDot )\n" -" {\n" -" maxDot = dot;\n" -" ptIndex = i;\n" -" }\n" -" }\n" -" b3Assert(ptIndex>=0);\n" -" if (ptIndex<0)\n" -" {\n" -" ptIndex = 0;\n" -" }\n" -" *dotOut = maxDot;\n" -" return ptIndex;\n" -"}\n" -"#endif //B3_FLOAT4_H\n" -"#ifndef B3_MAT3x3_H\n" -"#define B3_MAT3x3_H\n" -"#ifndef B3_QUAT_H\n" -"#define B3_QUAT_H\n" -"#ifndef B3_PLATFORM_DEFINITIONS_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif\n" -"#endif\n" -"#ifndef B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -" typedef float4 b3Quat;\n" -" #define b3QuatConstArg const b3Quat\n" -" \n" -" \n" -"inline float4 b3FastNormalize4(float4 v)\n" -"{\n" -" v = (float4)(v.xyz,0.f);\n" -" return fast_normalize(v);\n" -"}\n" -" \n" -"inline b3Quat b3QuatMul(b3Quat a, b3Quat b);\n" -"inline b3Quat b3QuatNormalized(b3QuatConstArg in);\n" -"inline b3Quat b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec);\n" -"inline b3Quat b3QuatInvert(b3QuatConstArg q);\n" -"inline b3Quat b3QuatInverse(b3QuatConstArg q);\n" -"inline b3Quat b3QuatMul(b3QuatConstArg a, b3QuatConstArg b)\n" -"{\n" -" b3Quat ans;\n" -" ans = b3Cross3( a, b );\n" -" ans += a.w*b+b.w*a;\n" -"// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" -" ans.w = a.w*b.w - b3Dot3F4(a, b);\n" -" return ans;\n" -"}\n" -"inline b3Quat b3QuatNormalized(b3QuatConstArg in)\n" -"{\n" -" b3Quat q;\n" -" q=in;\n" -" //return b3FastNormalize4(in);\n" -" float len = native_sqrt(dot(q, q));\n" -" if(len > 0.f)\n" -" {\n" -" q *= 1.f / len;\n" -" }\n" -" else\n" -" {\n" -" q.x = q.y = q.z = 0.f;\n" -" q.w = 1.f;\n" -" }\n" -" return q;\n" -"}\n" -"inline float4 b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" -"{\n" -" b3Quat qInv = b3QuatInvert( q );\n" -" float4 vcpy = vec;\n" -" vcpy.w = 0.f;\n" -" float4 out = b3QuatMul(b3QuatMul(q,vcpy),qInv);\n" -" return out;\n" -"}\n" -"inline b3Quat b3QuatInverse(b3QuatConstArg q)\n" -"{\n" -" return (b3Quat)(-q.xyz, q.w);\n" -"}\n" -"inline b3Quat b3QuatInvert(b3QuatConstArg q)\n" -"{\n" -" return (b3Quat)(-q.xyz, q.w);\n" -"}\n" -"inline float4 b3QuatInvRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" -"{\n" -" return b3QuatRotate( b3QuatInvert( q ), vec );\n" -"}\n" -"inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)\n" -"{\n" -" return b3QuatRotate( orientation, point ) + (translation);\n" -"}\n" -" \n" -"#endif \n" -"#endif //B3_QUAT_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"typedef struct\n" -"{\n" -" b3Float4 m_row[3];\n" -"}b3Mat3x3;\n" -"#define b3Mat3x3ConstArg const b3Mat3x3\n" -"#define b3GetRow(m,row) (m.m_row[row])\n" -"inline b3Mat3x3 b3QuatGetRotationMatrix(b3Quat quat)\n" -"{\n" -" b3Float4 quat2 = (b3Float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f);\n" -" b3Mat3x3 out;\n" -" out.m_row[0].x=1-2*quat2.y-2*quat2.z;\n" -" out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z;\n" -" out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y;\n" -" out.m_row[0].w = 0.f;\n" -" out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z;\n" -" out.m_row[1].y=1-2*quat2.x-2*quat2.z;\n" -" out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x;\n" -" out.m_row[1].w = 0.f;\n" -" out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y;\n" -" out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x;\n" -" out.m_row[2].z=1-2*quat2.x-2*quat2.y;\n" -" out.m_row[2].w = 0.f;\n" -" return out;\n" -"}\n" -"inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg matIn)\n" -"{\n" -" b3Mat3x3 out;\n" -" out.m_row[0] = fabs(matIn.m_row[0]);\n" -" out.m_row[1] = fabs(matIn.m_row[1]);\n" -" out.m_row[2] = fabs(matIn.m_row[2]);\n" -" return out;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtZero();\n" -"__inline\n" -"b3Mat3x3 mtIdentity();\n" -"__inline\n" -"b3Mat3x3 mtTranspose(b3Mat3x3 m);\n" -"__inline\n" -"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b);\n" -"__inline\n" -"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b);\n" -"__inline\n" -"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b);\n" -"__inline\n" -"b3Mat3x3 mtZero()\n" -"{\n" -" b3Mat3x3 m;\n" -" m.m_row[0] = (b3Float4)(0.f);\n" -" m.m_row[1] = (b3Float4)(0.f);\n" -" m.m_row[2] = (b3Float4)(0.f);\n" -" return m;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtIdentity()\n" -"{\n" -" b3Mat3x3 m;\n" -" m.m_row[0] = (b3Float4)(1,0,0,0);\n" -" m.m_row[1] = (b3Float4)(0,1,0,0);\n" -" m.m_row[2] = (b3Float4)(0,0,1,0);\n" -" return m;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtTranspose(b3Mat3x3 m)\n" -"{\n" -" b3Mat3x3 out;\n" -" out.m_row[0] = (b3Float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n" -" out.m_row[1] = (b3Float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n" -" out.m_row[2] = (b3Float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n" -" return out;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b)\n" -"{\n" -" b3Mat3x3 transB;\n" -" transB = mtTranspose( b );\n" -" b3Mat3x3 ans;\n" -" // why this doesn't run when 0ing in the for{}\n" -" a.m_row[0].w = 0.f;\n" -" a.m_row[1].w = 0.f;\n" -" a.m_row[2].w = 0.f;\n" -" for(int i=0; i<3; i++)\n" -" {\n" -"// a.m_row[i].w = 0.f;\n" -" ans.m_row[i].x = b3Dot3F4(a.m_row[i],transB.m_row[0]);\n" -" ans.m_row[i].y = b3Dot3F4(a.m_row[i],transB.m_row[1]);\n" -" ans.m_row[i].z = b3Dot3F4(a.m_row[i],transB.m_row[2]);\n" -" ans.m_row[i].w = 0.f;\n" -" }\n" -" return ans;\n" -"}\n" -"__inline\n" -"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b)\n" -"{\n" -" b3Float4 ans;\n" -" ans.x = b3Dot3F4( a.m_row[0], b );\n" -" ans.y = b3Dot3F4( a.m_row[1], b );\n" -" ans.z = b3Dot3F4( a.m_row[2], b );\n" -" ans.w = 0.f;\n" -" return ans;\n" -"}\n" -"__inline\n" -"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b)\n" -"{\n" -" b3Float4 colx = b3MakeFloat4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" -" b3Float4 coly = b3MakeFloat4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" -" b3Float4 colz = b3MakeFloat4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" -" b3Float4 ans;\n" -" ans.x = b3Dot3F4( a, colx );\n" -" ans.y = b3Dot3F4( a, coly );\n" -" ans.z = b3Dot3F4( a, colz );\n" -" return ans;\n" -"}\n" -"#endif\n" -"#endif //B3_MAT3x3_H\n" -"typedef struct b3Aabb b3Aabb_t;\n" -"struct b3Aabb\n" -"{\n" -" union\n" -" {\n" -" float m_min[4];\n" -" b3Float4 m_minVec;\n" -" int m_minIndices[4];\n" -" };\n" -" union\n" -" {\n" -" float m_max[4];\n" -" b3Float4 m_maxVec;\n" -" int m_signedMaxIndices[4];\n" -" };\n" -"};\n" -"inline void b3TransformAabb2(b3Float4ConstArg localAabbMin,b3Float4ConstArg localAabbMax, float margin,\n" -" b3Float4ConstArg pos,\n" -" b3QuatConstArg orn,\n" -" b3Float4* aabbMinOut,b3Float4* aabbMaxOut)\n" -"{\n" -" b3Float4 localHalfExtents = 0.5f*(localAabbMax-localAabbMin);\n" -" localHalfExtents+=b3MakeFloat4(margin,margin,margin,0.f);\n" -" b3Float4 localCenter = 0.5f*(localAabbMax+localAabbMin);\n" -" b3Mat3x3 m;\n" -" m = b3QuatGetRotationMatrix(orn);\n" -" b3Mat3x3 abs_b = b3AbsoluteMat3x3(m);\n" -" b3Float4 center = b3TransformPoint(localCenter,pos,orn);\n" -" \n" -" b3Float4 extent = b3MakeFloat4(b3Dot3F4(localHalfExtents,b3GetRow(abs_b,0)),\n" -" b3Dot3F4(localHalfExtents,b3GetRow(abs_b,1)),\n" -" b3Dot3F4(localHalfExtents,b3GetRow(abs_b,2)),\n" -" 0.f);\n" -" *aabbMinOut = center-extent;\n" -" *aabbMaxOut = center+extent;\n" -"}\n" -"/// conservative test for overlap between two aabbs\n" -"inline bool b3TestAabbAgainstAabb(b3Float4ConstArg aabbMin1,b3Float4ConstArg aabbMax1,\n" -" b3Float4ConstArg aabbMin2, b3Float4ConstArg aabbMax2)\n" -"{\n" -" bool overlap = true;\n" -" overlap = (aabbMin1.x > aabbMax2.x || aabbMax1.x < aabbMin2.x) ? false : overlap;\n" -" overlap = (aabbMin1.z > aabbMax2.z || aabbMax1.z < aabbMin2.z) ? false : overlap;\n" -" overlap = (aabbMin1.y > aabbMax2.y || aabbMax1.y < aabbMin2.y) ? false : overlap;\n" -" return overlap;\n" -"}\n" -"#endif //B3_AABB_H\n" -"/*\n" -"Bullet Continuous Collision Detection and Physics Library\n" -"Copyright (c) 2003-2013 Erwin Coumans http://bulletphysics.org\n" -"This software is provided 'as-is', without any express or implied warranty.\n" -"In no event will the authors be held liable for any damages arising from the use of this software.\n" -"Permission is granted to anyone to use this software for any purpose,\n" -"including commercial applications, and to alter it and redistribute it freely,\n" -"subject to the following restrictions:\n" -"1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" -"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" -"3. This notice may not be removed or altered from any source distribution.\n" -"*/\n" -"#ifndef B3_INT2_H\n" -"#define B3_INT2_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#define b3UnsignedInt2 uint2\n" -"#define b3Int2 int2\n" -"#define b3MakeInt2 (int2)\n" -"#endif //__cplusplus\n" -"#endif\n" -"typedef struct\n" -"{\n" -" float4 m_plane;\n" -" int m_indexOffset;\n" -" int m_numIndices;\n" -"} btGpuFace;\n" -"#define make_float4 (float4)\n" -"__inline\n" -"float4 cross3(float4 a, float4 b)\n" -"{\n" -" return cross(a,b);\n" -" \n" -"// float4 a1 = make_float4(a.xyz,0.f);\n" -"// float4 b1 = make_float4(b.xyz,0.f);\n" -"// return cross(a1,b1);\n" -"//float4 c = make_float4(a.y*b.z - a.z*b.y,a.z*b.x - a.x*b.z,a.x*b.y - a.y*b.x,0.f);\n" -" \n" -" // float4 c = make_float4(a.y*b.z - a.z*b.y,1.f,a.x*b.y - a.y*b.x,0.f);\n" -" \n" -" //return c;\n" -"}\n" -"__inline\n" -"float dot3F4(float4 a, float4 b)\n" -"{\n" -" float4 a1 = make_float4(a.xyz,0.f);\n" -" float4 b1 = make_float4(b.xyz,0.f);\n" -" return dot(a1, b1);\n" -"}\n" -"__inline\n" -"float4 fastNormalize4(float4 v)\n" -"{\n" -" v = make_float4(v.xyz,0.f);\n" -" return fast_normalize(v);\n" -"}\n" -"///////////////////////////////////////\n" -"// Quaternion\n" -"///////////////////////////////////////\n" -"typedef float4 Quaternion;\n" -"__inline\n" -"Quaternion qtMul(Quaternion a, Quaternion b);\n" -"__inline\n" -"Quaternion qtNormalize(Quaternion in);\n" -"__inline\n" -"float4 qtRotate(Quaternion q, float4 vec);\n" -"__inline\n" -"Quaternion qtInvert(Quaternion q);\n" -"__inline\n" -"Quaternion qtMul(Quaternion a, Quaternion b)\n" -"{\n" -" Quaternion ans;\n" -" ans = cross3( a, b );\n" -" ans += a.w*b+b.w*a;\n" -"// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" -" ans.w = a.w*b.w - dot3F4(a, b);\n" -" return ans;\n" -"}\n" -"__inline\n" -"Quaternion qtNormalize(Quaternion in)\n" -"{\n" -" return fastNormalize4(in);\n" -"// in /= length( in );\n" -"// return in;\n" -"}\n" -"__inline\n" -"float4 qtRotate(Quaternion q, float4 vec)\n" -"{\n" -" Quaternion qInv = qtInvert( q );\n" -" float4 vcpy = vec;\n" -" vcpy.w = 0.f;\n" -" float4 out = qtMul(qtMul(q,vcpy),qInv);\n" -" return out;\n" -"}\n" -"__inline\n" -"Quaternion qtInvert(Quaternion q)\n" -"{\n" -" return (Quaternion)(-q.xyz, q.w);\n" -"}\n" -"__inline\n" -"float4 qtInvRotate(const Quaternion q, float4 vec)\n" -"{\n" -" return qtRotate( qtInvert( q ), vec );\n" -"}\n" -"__inline\n" -"float4 transform(const float4* p, const float4* translation, const Quaternion* orientation)\n" -"{\n" -" return qtRotate( *orientation, *p ) + (*translation);\n" -"}\n" -"__inline\n" -"float4 normalize3(const float4 a)\n" -"{\n" -" float4 n = make_float4(a.x, a.y, a.z, 0.f);\n" -" return fastNormalize4( n );\n" -"}\n" -"inline void projectLocal(const ConvexPolyhedronCL* hull, const float4 pos, const float4 orn, \n" -"const float4* dir, const float4* vertices, float* min, float* max)\n" -"{\n" -" min[0] = FLT_MAX;\n" -" max[0] = -FLT_MAX;\n" -" int numVerts = hull->m_numVertices;\n" -" const float4 localDir = qtInvRotate(orn,*dir);\n" -" float offset = dot(pos,*dir);\n" -" for(int i=0;im_vertexOffset+i],localDir);\n" -" if(dp < min[0]) \n" -" min[0] = dp;\n" -" if(dp > max[0]) \n" -" max[0] = dp;\n" -" }\n" -" if(min[0]>max[0])\n" -" {\n" -" float tmp = min[0];\n" -" min[0] = max[0];\n" -" max[0] = tmp;\n" -" }\n" -" min[0] += offset;\n" -" max[0] += offset;\n" -"}\n" -"inline void project(__global const ConvexPolyhedronCL* hull, const float4 pos, const float4 orn, \n" -"const float4* dir, __global const float4* vertices, float* min, float* max)\n" -"{\n" -" min[0] = FLT_MAX;\n" -" max[0] = -FLT_MAX;\n" -" int numVerts = hull->m_numVertices;\n" -" const float4 localDir = qtInvRotate(orn,*dir);\n" -" float offset = dot(pos,*dir);\n" -" for(int i=0;im_vertexOffset+i],localDir);\n" -" if(dp < min[0]) \n" -" min[0] = dp;\n" -" if(dp > max[0]) \n" -" max[0] = dp;\n" -" }\n" -" if(min[0]>max[0])\n" -" {\n" -" float tmp = min[0];\n" -" min[0] = max[0];\n" -" max[0] = tmp;\n" -" }\n" -" min[0] += offset;\n" -" max[0] += offset;\n" -"}\n" -"inline bool TestSepAxisLocalA(const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB, \n" -" const float4 posA,const float4 ornA,\n" -" const float4 posB,const float4 ornB,\n" -" float4* sep_axis, const float4* verticesA, __global const float4* verticesB,float* depth)\n" -"{\n" -" float Min0,Max0;\n" -" float Min1,Max1;\n" -" projectLocal(hullA,posA,ornA,sep_axis,verticesA, &Min0, &Max0);\n" -" project(hullB,posB,ornB, sep_axis,verticesB, &Min1, &Max1);\n" -" if(Max01e-6f || fabs(v.y)>1e-6f || fabs(v.z)>1e-6f)\n" -" return false;\n" -" return true;\n" -"}\n" -"bool findSeparatingAxisLocalA( const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB, \n" -" const float4 posA1,\n" -" const float4 ornA,\n" -" const float4 posB1,\n" -" const float4 ornB,\n" -" const float4 DeltaC2,\n" -" \n" -" const float4* verticesA, \n" -" const float4* uniqueEdgesA, \n" -" const btGpuFace* facesA,\n" -" const int* indicesA,\n" -" __global const float4* verticesB, \n" -" __global const float4* uniqueEdgesB, \n" -" __global const btGpuFace* facesB,\n" -" __global const int* indicesB,\n" -" float4* sep,\n" -" float* dmin)\n" -"{\n" -" \n" -" float4 posA = posA1;\n" -" posA.w = 0.f;\n" -" float4 posB = posB1;\n" -" posB.w = 0.f;\n" -" int curPlaneTests=0;\n" -" {\n" -" int numFacesA = hullA->m_numFaces;\n" -" // Test normals from hullA\n" -" for(int i=0;im_faceOffset+i].m_plane;\n" -" float4 faceANormalWS = qtRotate(ornA,normal);\n" -" if (dot3F4(DeltaC2,faceANormalWS)<0)\n" -" faceANormalWS*=-1.f;\n" -" curPlaneTests++;\n" -" float d;\n" -" if(!TestSepAxisLocalA( hullA, hullB, posA,ornA,posB,ornB,&faceANormalWS, verticesA, verticesB,&d))\n" -" return false;\n" -" if(d<*dmin)\n" -" {\n" -" *dmin = d;\n" -" *sep = faceANormalWS;\n" -" }\n" -" }\n" -" }\n" -" if((dot3F4(-DeltaC2,*sep))>0.0f)\n" -" {\n" -" *sep = -(*sep);\n" -" }\n" -" return true;\n" -"}\n" -"bool findSeparatingAxisLocalB( __global const ConvexPolyhedronCL* hullA, const ConvexPolyhedronCL* hullB, \n" -" const float4 posA1,\n" -" const float4 ornA,\n" -" const float4 posB1,\n" -" const float4 ornB,\n" -" const float4 DeltaC2,\n" -" __global const float4* verticesA, \n" -" __global const float4* uniqueEdgesA, \n" -" __global const btGpuFace* facesA,\n" -" __global const int* indicesA,\n" -" const float4* verticesB,\n" -" const float4* uniqueEdgesB, \n" -" const btGpuFace* facesB,\n" -" const int* indicesB,\n" -" float4* sep,\n" -" float* dmin)\n" -"{\n" -" float4 posA = posA1;\n" -" posA.w = 0.f;\n" -" float4 posB = posB1;\n" -" posB.w = 0.f;\n" -" int curPlaneTests=0;\n" -" {\n" -" int numFacesA = hullA->m_numFaces;\n" -" // Test normals from hullA\n" -" for(int i=0;im_faceOffset+i].m_plane;\n" -" float4 faceANormalWS = qtRotate(ornA,normal);\n" -" if (dot3F4(DeltaC2,faceANormalWS)<0)\n" -" faceANormalWS *= -1.f;\n" -" curPlaneTests++;\n" -" float d;\n" -" if(!TestSepAxisLocalA( hullB, hullA, posB,ornB,posA,ornA, &faceANormalWS, verticesB,verticesA, &d))\n" -" return false;\n" -" if(d<*dmin)\n" -" {\n" -" *dmin = d;\n" -" *sep = faceANormalWS;\n" -" }\n" -" }\n" -" }\n" -" if((dot3F4(-DeltaC2,*sep))>0.0f)\n" -" {\n" -" *sep = -(*sep);\n" -" }\n" -" return true;\n" -"}\n" -"bool findSeparatingAxisEdgeEdgeLocalA( const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB, \n" -" const float4 posA1,\n" -" const float4 ornA,\n" -" const float4 posB1,\n" -" const float4 ornB,\n" -" const float4 DeltaC2,\n" -" const float4* verticesA, \n" -" const float4* uniqueEdgesA, \n" -" const btGpuFace* facesA,\n" -" const int* indicesA,\n" -" __global const float4* verticesB, \n" -" __global const float4* uniqueEdgesB, \n" -" __global const btGpuFace* facesB,\n" -" __global const int* indicesB,\n" -" float4* sep,\n" -" float* dmin)\n" -"{\n" -" float4 posA = posA1;\n" -" posA.w = 0.f;\n" -" float4 posB = posB1;\n" -" posB.w = 0.f;\n" -" int curPlaneTests=0;\n" -" int curEdgeEdge = 0;\n" -" // Test edges\n" -" for(int e0=0;e0m_numUniqueEdges;e0++)\n" -" {\n" -" const float4 edge0 = uniqueEdgesA[hullA->m_uniqueEdgesOffset+e0];\n" -" float4 edge0World = qtRotate(ornA,edge0);\n" -" for(int e1=0;e1m_numUniqueEdges;e1++)\n" -" {\n" -" const float4 edge1 = uniqueEdgesB[hullB->m_uniqueEdgesOffset+e1];\n" -" float4 edge1World = qtRotate(ornB,edge1);\n" -" float4 crossje = cross3(edge0World,edge1World);\n" -" curEdgeEdge++;\n" -" if(!IsAlmostZero(crossje))\n" -" {\n" -" crossje = normalize3(crossje);\n" -" if (dot3F4(DeltaC2,crossje)<0)\n" -" crossje *= -1.f;\n" -" float dist;\n" -" bool result = true;\n" -" {\n" -" float Min0,Max0;\n" -" float Min1,Max1;\n" -" projectLocal(hullA,posA,ornA,&crossje,verticesA, &Min0, &Max0);\n" -" project(hullB,posB,ornB,&crossje,verticesB, &Min1, &Max1);\n" -" \n" -" if(Max00.0f)\n" -" {\n" -" *sep = -(*sep);\n" -" }\n" -" return true;\n" -"}\n" -"inline int findClippingFaces(const float4 separatingNormal,\n" -" const ConvexPolyhedronCL* hullA, \n" -" __global const ConvexPolyhedronCL* hullB,\n" -" const float4 posA, const Quaternion ornA,const float4 posB, const Quaternion ornB,\n" -" __global float4* worldVertsA1,\n" -" __global float4* worldNormalsA1,\n" -" __global float4* worldVertsB1,\n" -" int capacityWorldVerts,\n" -" const float minDist, float maxDist,\n" -" const float4* verticesA,\n" -" const btGpuFace* facesA,\n" -" const int* indicesA,\n" -" __global const float4* verticesB,\n" -" __global const btGpuFace* facesB,\n" -" __global const int* indicesB,\n" -" __global int4* clippingFaces, int pairIndex)\n" -"{\n" -" int numContactsOut = 0;\n" -" int numWorldVertsB1= 0;\n" -" \n" -" \n" -" int closestFaceB=0;\n" -" float dmax = -FLT_MAX;\n" -" \n" -" {\n" -" for(int face=0;facem_numFaces;face++)\n" -" {\n" -" const float4 Normal = make_float4(facesB[hullB->m_faceOffset+face].m_plane.x,\n" -" facesB[hullB->m_faceOffset+face].m_plane.y, facesB[hullB->m_faceOffset+face].m_plane.z,0.f);\n" -" const float4 WorldNormal = qtRotate(ornB, Normal);\n" -" float d = dot3F4(WorldNormal,separatingNormal);\n" -" if (d > dmax)\n" -" {\n" -" dmax = d;\n" -" closestFaceB = face;\n" -" }\n" -" }\n" -" }\n" -" \n" -" {\n" -" const btGpuFace polyB = facesB[hullB->m_faceOffset+closestFaceB];\n" -" int numVertices = polyB.m_numIndices;\n" -" if (numVertices>capacityWorldVerts)\n" -" numVertices = capacityWorldVerts;\n" -" if (numVertices<0)\n" -" numVertices = 0;\n" -" \n" -" for(int e0=0;e0m_vertexOffset+indicesB[polyB.m_indexOffset+e0]];\n" -" worldVertsB1[pairIndex*capacityWorldVerts+numWorldVertsB1++] = transform(&b,&posB,&ornB);\n" -" }\n" -" }\n" -" }\n" -" \n" -" int closestFaceA=0;\n" -" {\n" -" float dmin = FLT_MAX;\n" -" for(int face=0;facem_numFaces;face++)\n" -" {\n" -" const float4 Normal = make_float4(\n" -" facesA[hullA->m_faceOffset+face].m_plane.x,\n" -" facesA[hullA->m_faceOffset+face].m_plane.y,\n" -" facesA[hullA->m_faceOffset+face].m_plane.z,\n" -" 0.f);\n" -" const float4 faceANormalWS = qtRotate(ornA,Normal);\n" -" \n" -" float d = dot3F4(faceANormalWS,separatingNormal);\n" -" if (d < dmin)\n" -" {\n" -" dmin = d;\n" -" closestFaceA = face;\n" -" worldNormalsA1[pairIndex] = faceANormalWS;\n" -" }\n" -" }\n" -" }\n" -" \n" -" int numVerticesA = facesA[hullA->m_faceOffset+closestFaceA].m_numIndices;\n" -" if (numVerticesA>capacityWorldVerts)\n" -" numVerticesA = capacityWorldVerts;\n" -" if (numVerticesA<0)\n" -" numVerticesA=0;\n" -" \n" -" for(int e0=0;e0m_vertexOffset+indicesA[facesA[hullA->m_faceOffset+closestFaceA].m_indexOffset+e0]];\n" -" worldVertsA1[pairIndex*capacityWorldVerts+e0] = transform(&a, &posA,&ornA);\n" -" }\n" -" }\n" -" \n" -" clippingFaces[pairIndex].x = closestFaceA;\n" -" clippingFaces[pairIndex].y = closestFaceB;\n" -" clippingFaces[pairIndex].z = numVerticesA;\n" -" clippingFaces[pairIndex].w = numWorldVertsB1;\n" -" \n" -" \n" -" return numContactsOut;\n" -"}\n" -"// work-in-progress\n" -"__kernel void findConcaveSeparatingAxisVertexFaceKernel( __global int4* concavePairs,\n" -" __global const BodyData* rigidBodies,\n" -" __global const btCollidableGpu* collidables,\n" -" __global const ConvexPolyhedronCL* convexShapes,\n" -" __global const float4* vertices,\n" -" __global const float4* uniqueEdges,\n" -" __global const btGpuFace* faces,\n" -" __global const int* indices,\n" -" __global const btGpuChildShape* gpuChildShapes,\n" -" __global btAabbCL* aabbs,\n" -" __global float4* concaveSeparatingNormalsOut,\n" -" __global int* concaveHasSeparatingNormals,\n" -" __global int4* clippingFacesOut,\n" -" __global float4* worldVertsA1GPU,\n" -" __global float4* worldNormalsAGPU,\n" -" __global float4* worldVertsB1GPU,\n" -" __global float* dmins,\n" -" int vertexFaceCapacity,\n" -" int numConcavePairs\n" -" )\n" -"{\n" -" \n" -" int i = get_global_id(0);\n" -" if (i>=numConcavePairs)\n" -" return;\n" -" \n" -" concaveHasSeparatingNormals[i] = 0;\n" -" \n" -" int pairIdx = i;\n" -" \n" -" int bodyIndexA = concavePairs[i].x;\n" -" int bodyIndexB = concavePairs[i].y;\n" -" \n" -" int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;\n" -" int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;\n" -" \n" -" int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;\n" -" int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;\n" -" \n" -" if (collidables[collidableIndexB].m_shapeType!=SHAPE_CONVEX_HULL&&\n" -" collidables[collidableIndexB].m_shapeType!=SHAPE_COMPOUND_OF_CONVEX_HULLS)\n" -" {\n" -" concavePairs[pairIdx].w = -1;\n" -" return;\n" -" }\n" -" \n" -" \n" -" \n" -" int numFacesA = convexShapes[shapeIndexA].m_numFaces;\n" -" int numActualConcaveConvexTests = 0;\n" -" \n" -" int f = concavePairs[i].z;\n" -" \n" -" bool overlap = false;\n" -" \n" -" ConvexPolyhedronCL convexPolyhedronA;\n" -" \n" -" //add 3 vertices of the triangle\n" -" convexPolyhedronA.m_numVertices = 3;\n" -" convexPolyhedronA.m_vertexOffset = 0;\n" -" float4 localCenter = make_float4(0.f,0.f,0.f,0.f);\n" -" \n" -" btGpuFace face = faces[convexShapes[shapeIndexA].m_faceOffset+f];\n" -" float4 triMinAabb, triMaxAabb;\n" -" btAabbCL triAabb;\n" -" triAabb.m_min = make_float4(1e30f,1e30f,1e30f,0.f);\n" -" triAabb.m_max = make_float4(-1e30f,-1e30f,-1e30f,0.f);\n" -" \n" -" float4 verticesA[3];\n" -" for (int i=0;i<3;i++)\n" -" {\n" -" int index = indices[face.m_indexOffset+i];\n" -" float4 vert = vertices[convexShapes[shapeIndexA].m_vertexOffset+index];\n" -" verticesA[i] = vert;\n" -" localCenter += vert;\n" -" \n" -" triAabb.m_min = min(triAabb.m_min,vert);\n" -" triAabb.m_max = max(triAabb.m_max,vert);\n" -" \n" -" }\n" -" \n" -" overlap = true;\n" -" overlap = (triAabb.m_min.x > aabbs[bodyIndexB].m_max.x || triAabb.m_max.x < aabbs[bodyIndexB].m_min.x) ? false : overlap;\n" -" overlap = (triAabb.m_min.z > aabbs[bodyIndexB].m_max.z || triAabb.m_max.z < aabbs[bodyIndexB].m_min.z) ? false : overlap;\n" -" overlap = (triAabb.m_min.y > aabbs[bodyIndexB].m_max.y || triAabb.m_max.y < aabbs[bodyIndexB].m_min.y) ? false : overlap;\n" -" \n" -" if (overlap)\n" -" {\n" -" float dmin = FLT_MAX;\n" -" int hasSeparatingAxis=5;\n" -" float4 sepAxis=make_float4(1,2,3,4);\n" -" \n" -" int localCC=0;\n" -" numActualConcaveConvexTests++;\n" -" \n" -" //a triangle has 3 unique edges\n" -" convexPolyhedronA.m_numUniqueEdges = 3;\n" -" convexPolyhedronA.m_uniqueEdgesOffset = 0;\n" -" float4 uniqueEdgesA[3];\n" -" \n" -" uniqueEdgesA[0] = (verticesA[1]-verticesA[0]);\n" -" uniqueEdgesA[1] = (verticesA[2]-verticesA[1]);\n" -" uniqueEdgesA[2] = (verticesA[0]-verticesA[2]);\n" -" \n" -" \n" -" convexPolyhedronA.m_faceOffset = 0;\n" -" \n" -" float4 normal = make_float4(face.m_plane.x,face.m_plane.y,face.m_plane.z,0.f);\n" -" \n" -" btGpuFace facesA[TRIANGLE_NUM_CONVEX_FACES];\n" -" int indicesA[3+3+2+2+2];\n" -" int curUsedIndices=0;\n" -" int fidx=0;\n" -" \n" -" //front size of triangle\n" -" {\n" -" facesA[fidx].m_indexOffset=curUsedIndices;\n" -" indicesA[0] = 0;\n" -" indicesA[1] = 1;\n" -" indicesA[2] = 2;\n" -" curUsedIndices+=3;\n" -" float c = face.m_plane.w;\n" -" facesA[fidx].m_plane.x = normal.x;\n" -" facesA[fidx].m_plane.y = normal.y;\n" -" facesA[fidx].m_plane.z = normal.z;\n" -" facesA[fidx].m_plane.w = c;\n" -" facesA[fidx].m_numIndices=3;\n" -" }\n" -" fidx++;\n" -" //back size of triangle\n" -" {\n" -" facesA[fidx].m_indexOffset=curUsedIndices;\n" -" indicesA[3]=2;\n" -" indicesA[4]=1;\n" -" indicesA[5]=0;\n" -" curUsedIndices+=3;\n" -" float c = dot(normal,verticesA[0]);\n" -" float c1 = -face.m_plane.w;\n" -" facesA[fidx].m_plane.x = -normal.x;\n" -" facesA[fidx].m_plane.y = -normal.y;\n" -" facesA[fidx].m_plane.z = -normal.z;\n" -" facesA[fidx].m_plane.w = c;\n" -" facesA[fidx].m_numIndices=3;\n" -" }\n" -" fidx++;\n" -" \n" -" bool addEdgePlanes = true;\n" -" if (addEdgePlanes)\n" -" {\n" -" int numVertices=3;\n" -" int prevVertex = numVertices-1;\n" -" for (int i=0;i=numConcavePairs)\n" -" return;\n" -" \n" -" if (!concaveHasSeparatingNormals[i])\n" -" return;\n" -" \n" -" int pairIdx = i;\n" -" \n" -" int bodyIndexA = concavePairs[i].x;\n" -" int bodyIndexB = concavePairs[i].y;\n" -" \n" -" int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;\n" -" int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;\n" -" \n" -" int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;\n" -" int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;\n" -" \n" -" \n" -" int numFacesA = convexShapes[shapeIndexA].m_numFaces;\n" -" int numActualConcaveConvexTests = 0;\n" -" \n" -" int f = concavePairs[i].z;\n" -" \n" -" bool overlap = false;\n" -" \n" -" ConvexPolyhedronCL convexPolyhedronA;\n" -" \n" -" //add 3 vertices of the triangle\n" -" convexPolyhedronA.m_numVertices = 3;\n" -" convexPolyhedronA.m_vertexOffset = 0;\n" -" float4 localCenter = make_float4(0.f,0.f,0.f,0.f);\n" -" \n" -" btGpuFace face = faces[convexShapes[shapeIndexA].m_faceOffset+f];\n" -" float4 triMinAabb, triMaxAabb;\n" -" btAabbCL triAabb;\n" -" triAabb.m_min = make_float4(1e30f,1e30f,1e30f,0.f);\n" -" triAabb.m_max = make_float4(-1e30f,-1e30f,-1e30f,0.f);\n" -" \n" -" float4 verticesA[3];\n" -" for (int i=0;i<3;i++)\n" -" {\n" -" int index = indices[face.m_indexOffset+i];\n" -" float4 vert = vertices[convexShapes[shapeIndexA].m_vertexOffset+index];\n" -" verticesA[i] = vert;\n" -" localCenter += vert;\n" -" \n" -" triAabb.m_min = min(triAabb.m_min,vert);\n" -" triAabb.m_max = max(triAabb.m_max,vert);\n" -" \n" -" }\n" -" \n" -" overlap = true;\n" -" overlap = (triAabb.m_min.x > aabbs[bodyIndexB].m_max.x || triAabb.m_max.x < aabbs[bodyIndexB].m_min.x) ? false : overlap;\n" -" overlap = (triAabb.m_min.z > aabbs[bodyIndexB].m_max.z || triAabb.m_max.z < aabbs[bodyIndexB].m_min.z) ? false : overlap;\n" -" overlap = (triAabb.m_min.y > aabbs[bodyIndexB].m_max.y || triAabb.m_max.y < aabbs[bodyIndexB].m_min.y) ? false : overlap;\n" -" \n" -" if (overlap)\n" -" {\n" -" float dmin = dmins[i];\n" -" int hasSeparatingAxis=5;\n" -" float4 sepAxis=make_float4(1,2,3,4);\n" -" sepAxis = concaveSeparatingNormalsOut[pairIdx];\n" -" \n" -" int localCC=0;\n" -" numActualConcaveConvexTests++;\n" -" \n" -" //a triangle has 3 unique edges\n" -" convexPolyhedronA.m_numUniqueEdges = 3;\n" -" convexPolyhedronA.m_uniqueEdgesOffset = 0;\n" -" float4 uniqueEdgesA[3];\n" -" \n" -" uniqueEdgesA[0] = (verticesA[1]-verticesA[0]);\n" -" uniqueEdgesA[1] = (verticesA[2]-verticesA[1]);\n" -" uniqueEdgesA[2] = (verticesA[0]-verticesA[2]);\n" -" \n" -" \n" -" convexPolyhedronA.m_faceOffset = 0;\n" -" \n" -" float4 normal = make_float4(face.m_plane.x,face.m_plane.y,face.m_plane.z,0.f);\n" -" \n" -" btGpuFace facesA[TRIANGLE_NUM_CONVEX_FACES];\n" -" int indicesA[3+3+2+2+2];\n" -" int curUsedIndices=0;\n" -" int fidx=0;\n" -" \n" -" //front size of triangle\n" -" {\n" -" facesA[fidx].m_indexOffset=curUsedIndices;\n" -" indicesA[0] = 0;\n" -" indicesA[1] = 1;\n" -" indicesA[2] = 2;\n" -" curUsedIndices+=3;\n" -" float c = face.m_plane.w;\n" -" facesA[fidx].m_plane.x = normal.x;\n" -" facesA[fidx].m_plane.y = normal.y;\n" -" facesA[fidx].m_plane.z = normal.z;\n" -" facesA[fidx].m_plane.w = c;\n" -" facesA[fidx].m_numIndices=3;\n" -" }\n" -" fidx++;\n" -" //back size of triangle\n" -" {\n" -" facesA[fidx].m_indexOffset=curUsedIndices;\n" -" indicesA[3]=2;\n" -" indicesA[4]=1;\n" -" indicesA[5]=0;\n" -" curUsedIndices+=3;\n" -" float c = dot(normal,verticesA[0]);\n" -" float c1 = -face.m_plane.w;\n" -" facesA[fidx].m_plane.x = -normal.x;\n" -" facesA[fidx].m_plane.y = -normal.y;\n" -" facesA[fidx].m_plane.z = -normal.z;\n" -" facesA[fidx].m_plane.w = c;\n" -" facesA[fidx].m_numIndices=3;\n" -" }\n" -" fidx++;\n" -" \n" -" bool addEdgePlanes = true;\n" -" if (addEdgePlanes)\n" -" {\n" -" int numVertices=3;\n" -" int prevVertex = numVertices-1;\n" -" for (int i=0;im_escapeIndexOrTriangleIndex&~(y));\n" + "}\n" + "int getTriangleIndexGlobal(__global const b3QuantizedBvhNode* rootNode)\n" + "{\n" + " unsigned int x=0;\n" + " unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS);\n" + " // Get only the lower bits where the triangle index is stored\n" + " return (rootNode->m_escapeIndexOrTriangleIndex&~(y));\n" + "}\n" + "int isLeafNode(const b3QuantizedBvhNode* rootNode)\n" + "{\n" + " //skipindex is negative (internal node), triangleindex >=0 (leafnode)\n" + " return (rootNode->m_escapeIndexOrTriangleIndex >= 0)? 1 : 0;\n" + "}\n" + "int isLeafNodeGlobal(__global const b3QuantizedBvhNode* rootNode)\n" + "{\n" + " //skipindex is negative (internal node), triangleindex >=0 (leafnode)\n" + " return (rootNode->m_escapeIndexOrTriangleIndex >= 0)? 1 : 0;\n" + "}\n" + " \n" + "int getEscapeIndex(const b3QuantizedBvhNode* rootNode)\n" + "{\n" + " return -rootNode->m_escapeIndexOrTriangleIndex;\n" + "}\n" + "int getEscapeIndexGlobal(__global const b3QuantizedBvhNode* rootNode)\n" + "{\n" + " return -rootNode->m_escapeIndexOrTriangleIndex;\n" + "}\n" + "typedef struct\n" + "{\n" + " //12 bytes\n" + " unsigned short int m_quantizedAabbMin[3];\n" + " unsigned short int m_quantizedAabbMax[3];\n" + " //4 bytes, points to the root of the subtree\n" + " int m_rootNodeIndex;\n" + " //4 bytes\n" + " int m_subtreeSize;\n" + " int m_padding[3];\n" + "} b3BvhSubtreeInfo;\n" + "typedef struct\n" + "{\n" + " float4 m_childPosition;\n" + " float4 m_childOrientation;\n" + " int m_shapeIndex;\n" + " int m_unused0;\n" + " int m_unused1;\n" + " int m_unused2;\n" + "} btGpuChildShape;\n" + "typedef struct\n" + "{\n" + " float4 m_pos;\n" + " float4 m_quat;\n" + " float4 m_linVel;\n" + " float4 m_angVel;\n" + " u32 m_collidableIdx;\n" + " float m_invMass;\n" + " float m_restituitionCoeff;\n" + " float m_frictionCoeff;\n" + "} BodyData;\n" + "typedef struct \n" + "{\n" + " float4 m_localCenter;\n" + " float4 m_extents;\n" + " float4 mC;\n" + " float4 mE;\n" + " \n" + " float m_radius;\n" + " int m_faceOffset;\n" + " int m_numFaces;\n" + " int m_numVertices;\n" + " int m_vertexOffset;\n" + " int m_uniqueEdgesOffset;\n" + " int m_numUniqueEdges;\n" + " int m_unused;\n" + "} ConvexPolyhedronCL;\n" + "typedef struct \n" + "{\n" + " union\n" + " {\n" + " float4 m_min;\n" + " float m_minElems[4];\n" + " int m_minIndices[4];\n" + " };\n" + " union\n" + " {\n" + " float4 m_max;\n" + " float m_maxElems[4];\n" + " int m_maxIndices[4];\n" + " };\n" + "} btAabbCL;\n" + "#ifndef B3_AABB_H\n" + "#define B3_AABB_H\n" + "#ifndef B3_FLOAT4_H\n" + "#define B3_FLOAT4_H\n" + "#ifndef B3_PLATFORM_DEFINITIONS_H\n" + "#define B3_PLATFORM_DEFINITIONS_H\n" + "struct MyTest\n" + "{\n" + " int bla;\n" + "};\n" + "#ifdef __cplusplus\n" + "#else\n" + "//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n" + "#define B3_LARGE_FLOAT 1e18f\n" + "#define B3_INFINITY 1e18f\n" + "#define b3Assert(a)\n" + "#define b3ConstArray(a) __global const a*\n" + "#define b3AtomicInc atomic_inc\n" + "#define b3AtomicAdd atomic_add\n" + "#define b3Fabs fabs\n" + "#define b3Sqrt native_sqrt\n" + "#define b3Sin native_sin\n" + "#define b3Cos native_cos\n" + "#define B3_STATIC\n" + "#endif\n" + "#endif\n" + "#ifdef __cplusplus\n" + "#else\n" + " typedef float4 b3Float4;\n" + " #define b3Float4ConstArg const b3Float4\n" + " #define b3MakeFloat4 (float4)\n" + " float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" + " {\n" + " float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" + " float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" + " return dot(a1, b1);\n" + " }\n" + " b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" + " {\n" + " float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" + " float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" + " return cross(a1, b1);\n" + " }\n" + " #define b3MinFloat4 min\n" + " #define b3MaxFloat4 max\n" + " #define b3Normalized(a) normalize(a)\n" + "#endif \n" + " \n" + "inline bool b3IsAlmostZero(b3Float4ConstArg v)\n" + "{\n" + " if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" + " return false;\n" + " return true;\n" + "}\n" + "inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" + "{\n" + " float maxDot = -B3_INFINITY;\n" + " int i = 0;\n" + " int ptIndex = -1;\n" + " for( i = 0; i < vecLen; i++ )\n" + " {\n" + " float dot = b3Dot3F4(vecArray[i],vec);\n" + " \n" + " if( dot > maxDot )\n" + " {\n" + " maxDot = dot;\n" + " ptIndex = i;\n" + " }\n" + " }\n" + " b3Assert(ptIndex>=0);\n" + " if (ptIndex<0)\n" + " {\n" + " ptIndex = 0;\n" + " }\n" + " *dotOut = maxDot;\n" + " return ptIndex;\n" + "}\n" + "#endif //B3_FLOAT4_H\n" + "#ifndef B3_MAT3x3_H\n" + "#define B3_MAT3x3_H\n" + "#ifndef B3_QUAT_H\n" + "#define B3_QUAT_H\n" + "#ifndef B3_PLATFORM_DEFINITIONS_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif\n" + "#endif\n" + "#ifndef B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + " typedef float4 b3Quat;\n" + " #define b3QuatConstArg const b3Quat\n" + " \n" + " \n" + "inline float4 b3FastNormalize4(float4 v)\n" + "{\n" + " v = (float4)(v.xyz,0.f);\n" + " return fast_normalize(v);\n" + "}\n" + " \n" + "inline b3Quat b3QuatMul(b3Quat a, b3Quat b);\n" + "inline b3Quat b3QuatNormalized(b3QuatConstArg in);\n" + "inline b3Quat b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec);\n" + "inline b3Quat b3QuatInvert(b3QuatConstArg q);\n" + "inline b3Quat b3QuatInverse(b3QuatConstArg q);\n" + "inline b3Quat b3QuatMul(b3QuatConstArg a, b3QuatConstArg b)\n" + "{\n" + " b3Quat ans;\n" + " ans = b3Cross3( a, b );\n" + " ans += a.w*b+b.w*a;\n" + "// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" + " ans.w = a.w*b.w - b3Dot3F4(a, b);\n" + " return ans;\n" + "}\n" + "inline b3Quat b3QuatNormalized(b3QuatConstArg in)\n" + "{\n" + " b3Quat q;\n" + " q=in;\n" + " //return b3FastNormalize4(in);\n" + " float len = native_sqrt(dot(q, q));\n" + " if(len > 0.f)\n" + " {\n" + " q *= 1.f / len;\n" + " }\n" + " else\n" + " {\n" + " q.x = q.y = q.z = 0.f;\n" + " q.w = 1.f;\n" + " }\n" + " return q;\n" + "}\n" + "inline float4 b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" + "{\n" + " b3Quat qInv = b3QuatInvert( q );\n" + " float4 vcpy = vec;\n" + " vcpy.w = 0.f;\n" + " float4 out = b3QuatMul(b3QuatMul(q,vcpy),qInv);\n" + " return out;\n" + "}\n" + "inline b3Quat b3QuatInverse(b3QuatConstArg q)\n" + "{\n" + " return (b3Quat)(-q.xyz, q.w);\n" + "}\n" + "inline b3Quat b3QuatInvert(b3QuatConstArg q)\n" + "{\n" + " return (b3Quat)(-q.xyz, q.w);\n" + "}\n" + "inline float4 b3QuatInvRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" + "{\n" + " return b3QuatRotate( b3QuatInvert( q ), vec );\n" + "}\n" + "inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)\n" + "{\n" + " return b3QuatRotate( orientation, point ) + (translation);\n" + "}\n" + " \n" + "#endif \n" + "#endif //B3_QUAT_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "typedef struct\n" + "{\n" + " b3Float4 m_row[3];\n" + "}b3Mat3x3;\n" + "#define b3Mat3x3ConstArg const b3Mat3x3\n" + "#define b3GetRow(m,row) (m.m_row[row])\n" + "inline b3Mat3x3 b3QuatGetRotationMatrix(b3Quat quat)\n" + "{\n" + " b3Float4 quat2 = (b3Float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f);\n" + " b3Mat3x3 out;\n" + " out.m_row[0].x=1-2*quat2.y-2*quat2.z;\n" + " out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z;\n" + " out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y;\n" + " out.m_row[0].w = 0.f;\n" + " out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z;\n" + " out.m_row[1].y=1-2*quat2.x-2*quat2.z;\n" + " out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x;\n" + " out.m_row[1].w = 0.f;\n" + " out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y;\n" + " out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x;\n" + " out.m_row[2].z=1-2*quat2.x-2*quat2.y;\n" + " out.m_row[2].w = 0.f;\n" + " return out;\n" + "}\n" + "inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg matIn)\n" + "{\n" + " b3Mat3x3 out;\n" + " out.m_row[0] = fabs(matIn.m_row[0]);\n" + " out.m_row[1] = fabs(matIn.m_row[1]);\n" + " out.m_row[2] = fabs(matIn.m_row[2]);\n" + " return out;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtZero();\n" + "__inline\n" + "b3Mat3x3 mtIdentity();\n" + "__inline\n" + "b3Mat3x3 mtTranspose(b3Mat3x3 m);\n" + "__inline\n" + "b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b);\n" + "__inline\n" + "b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b);\n" + "__inline\n" + "b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b);\n" + "__inline\n" + "b3Mat3x3 mtZero()\n" + "{\n" + " b3Mat3x3 m;\n" + " m.m_row[0] = (b3Float4)(0.f);\n" + " m.m_row[1] = (b3Float4)(0.f);\n" + " m.m_row[2] = (b3Float4)(0.f);\n" + " return m;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtIdentity()\n" + "{\n" + " b3Mat3x3 m;\n" + " m.m_row[0] = (b3Float4)(1,0,0,0);\n" + " m.m_row[1] = (b3Float4)(0,1,0,0);\n" + " m.m_row[2] = (b3Float4)(0,0,1,0);\n" + " return m;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtTranspose(b3Mat3x3 m)\n" + "{\n" + " b3Mat3x3 out;\n" + " out.m_row[0] = (b3Float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n" + " out.m_row[1] = (b3Float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n" + " out.m_row[2] = (b3Float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n" + " return out;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b)\n" + "{\n" + " b3Mat3x3 transB;\n" + " transB = mtTranspose( b );\n" + " b3Mat3x3 ans;\n" + " // why this doesn't run when 0ing in the for{}\n" + " a.m_row[0].w = 0.f;\n" + " a.m_row[1].w = 0.f;\n" + " a.m_row[2].w = 0.f;\n" + " for(int i=0; i<3; i++)\n" + " {\n" + "// a.m_row[i].w = 0.f;\n" + " ans.m_row[i].x = b3Dot3F4(a.m_row[i],transB.m_row[0]);\n" + " ans.m_row[i].y = b3Dot3F4(a.m_row[i],transB.m_row[1]);\n" + " ans.m_row[i].z = b3Dot3F4(a.m_row[i],transB.m_row[2]);\n" + " ans.m_row[i].w = 0.f;\n" + " }\n" + " return ans;\n" + "}\n" + "__inline\n" + "b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b)\n" + "{\n" + " b3Float4 ans;\n" + " ans.x = b3Dot3F4( a.m_row[0], b );\n" + " ans.y = b3Dot3F4( a.m_row[1], b );\n" + " ans.z = b3Dot3F4( a.m_row[2], b );\n" + " ans.w = 0.f;\n" + " return ans;\n" + "}\n" + "__inline\n" + "b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b)\n" + "{\n" + " b3Float4 colx = b3MakeFloat4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" + " b3Float4 coly = b3MakeFloat4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" + " b3Float4 colz = b3MakeFloat4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" + " b3Float4 ans;\n" + " ans.x = b3Dot3F4( a, colx );\n" + " ans.y = b3Dot3F4( a, coly );\n" + " ans.z = b3Dot3F4( a, colz );\n" + " return ans;\n" + "}\n" + "#endif\n" + "#endif //B3_MAT3x3_H\n" + "typedef struct b3Aabb b3Aabb_t;\n" + "struct b3Aabb\n" + "{\n" + " union\n" + " {\n" + " float m_min[4];\n" + " b3Float4 m_minVec;\n" + " int m_minIndices[4];\n" + " };\n" + " union\n" + " {\n" + " float m_max[4];\n" + " b3Float4 m_maxVec;\n" + " int m_signedMaxIndices[4];\n" + " };\n" + "};\n" + "inline void b3TransformAabb2(b3Float4ConstArg localAabbMin,b3Float4ConstArg localAabbMax, float margin,\n" + " b3Float4ConstArg pos,\n" + " b3QuatConstArg orn,\n" + " b3Float4* aabbMinOut,b3Float4* aabbMaxOut)\n" + "{\n" + " b3Float4 localHalfExtents = 0.5f*(localAabbMax-localAabbMin);\n" + " localHalfExtents+=b3MakeFloat4(margin,margin,margin,0.f);\n" + " b3Float4 localCenter = 0.5f*(localAabbMax+localAabbMin);\n" + " b3Mat3x3 m;\n" + " m = b3QuatGetRotationMatrix(orn);\n" + " b3Mat3x3 abs_b = b3AbsoluteMat3x3(m);\n" + " b3Float4 center = b3TransformPoint(localCenter,pos,orn);\n" + " \n" + " b3Float4 extent = b3MakeFloat4(b3Dot3F4(localHalfExtents,b3GetRow(abs_b,0)),\n" + " b3Dot3F4(localHalfExtents,b3GetRow(abs_b,1)),\n" + " b3Dot3F4(localHalfExtents,b3GetRow(abs_b,2)),\n" + " 0.f);\n" + " *aabbMinOut = center-extent;\n" + " *aabbMaxOut = center+extent;\n" + "}\n" + "/// conservative test for overlap between two aabbs\n" + "inline bool b3TestAabbAgainstAabb(b3Float4ConstArg aabbMin1,b3Float4ConstArg aabbMax1,\n" + " b3Float4ConstArg aabbMin2, b3Float4ConstArg aabbMax2)\n" + "{\n" + " bool overlap = true;\n" + " overlap = (aabbMin1.x > aabbMax2.x || aabbMax1.x < aabbMin2.x) ? false : overlap;\n" + " overlap = (aabbMin1.z > aabbMax2.z || aabbMax1.z < aabbMin2.z) ? false : overlap;\n" + " overlap = (aabbMin1.y > aabbMax2.y || aabbMax1.y < aabbMin2.y) ? false : overlap;\n" + " return overlap;\n" + "}\n" + "#endif //B3_AABB_H\n" + "/*\n" + "Bullet Continuous Collision Detection and Physics Library\n" + "Copyright (c) 2003-2013 Erwin Coumans http://bulletphysics.org\n" + "This software is provided 'as-is', without any express or implied warranty.\n" + "In no event will the authors be held liable for any damages arising from the use of this software.\n" + "Permission is granted to anyone to use this software for any purpose,\n" + "including commercial applications, and to alter it and redistribute it freely,\n" + "subject to the following restrictions:\n" + "1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" + "2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" + "3. This notice may not be removed or altered from any source distribution.\n" + "*/\n" + "#ifndef B3_INT2_H\n" + "#define B3_INT2_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#define b3UnsignedInt2 uint2\n" + "#define b3Int2 int2\n" + "#define b3MakeInt2 (int2)\n" + "#endif //__cplusplus\n" + "#endif\n" + "typedef struct\n" + "{\n" + " float4 m_plane;\n" + " int m_indexOffset;\n" + " int m_numIndices;\n" + "} btGpuFace;\n" + "#define make_float4 (float4)\n" + "__inline\n" + "float4 cross3(float4 a, float4 b)\n" + "{\n" + " return cross(a,b);\n" + " \n" + "// float4 a1 = make_float4(a.xyz,0.f);\n" + "// float4 b1 = make_float4(b.xyz,0.f);\n" + "// return cross(a1,b1);\n" + "//float4 c = make_float4(a.y*b.z - a.z*b.y,a.z*b.x - a.x*b.z,a.x*b.y - a.y*b.x,0.f);\n" + " \n" + " // float4 c = make_float4(a.y*b.z - a.z*b.y,1.f,a.x*b.y - a.y*b.x,0.f);\n" + " \n" + " //return c;\n" + "}\n" + "__inline\n" + "float dot3F4(float4 a, float4 b)\n" + "{\n" + " float4 a1 = make_float4(a.xyz,0.f);\n" + " float4 b1 = make_float4(b.xyz,0.f);\n" + " return dot(a1, b1);\n" + "}\n" + "__inline\n" + "float4 fastNormalize4(float4 v)\n" + "{\n" + " v = make_float4(v.xyz,0.f);\n" + " return fast_normalize(v);\n" + "}\n" + "///////////////////////////////////////\n" + "// Quaternion\n" + "///////////////////////////////////////\n" + "typedef float4 Quaternion;\n" + "__inline\n" + "Quaternion qtMul(Quaternion a, Quaternion b);\n" + "__inline\n" + "Quaternion qtNormalize(Quaternion in);\n" + "__inline\n" + "float4 qtRotate(Quaternion q, float4 vec);\n" + "__inline\n" + "Quaternion qtInvert(Quaternion q);\n" + "__inline\n" + "Quaternion qtMul(Quaternion a, Quaternion b)\n" + "{\n" + " Quaternion ans;\n" + " ans = cross3( a, b );\n" + " ans += a.w*b+b.w*a;\n" + "// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" + " ans.w = a.w*b.w - dot3F4(a, b);\n" + " return ans;\n" + "}\n" + "__inline\n" + "Quaternion qtNormalize(Quaternion in)\n" + "{\n" + " return fastNormalize4(in);\n" + "// in /= length( in );\n" + "// return in;\n" + "}\n" + "__inline\n" + "float4 qtRotate(Quaternion q, float4 vec)\n" + "{\n" + " Quaternion qInv = qtInvert( q );\n" + " float4 vcpy = vec;\n" + " vcpy.w = 0.f;\n" + " float4 out = qtMul(qtMul(q,vcpy),qInv);\n" + " return out;\n" + "}\n" + "__inline\n" + "Quaternion qtInvert(Quaternion q)\n" + "{\n" + " return (Quaternion)(-q.xyz, q.w);\n" + "}\n" + "__inline\n" + "float4 qtInvRotate(const Quaternion q, float4 vec)\n" + "{\n" + " return qtRotate( qtInvert( q ), vec );\n" + "}\n" + "__inline\n" + "float4 transform(const float4* p, const float4* translation, const Quaternion* orientation)\n" + "{\n" + " return qtRotate( *orientation, *p ) + (*translation);\n" + "}\n" + "__inline\n" + "float4 normalize3(const float4 a)\n" + "{\n" + " float4 n = make_float4(a.x, a.y, a.z, 0.f);\n" + " return fastNormalize4( n );\n" + "}\n" + "inline void projectLocal(const ConvexPolyhedronCL* hull, const float4 pos, const float4 orn, \n" + "const float4* dir, const float4* vertices, float* min, float* max)\n" + "{\n" + " min[0] = FLT_MAX;\n" + " max[0] = -FLT_MAX;\n" + " int numVerts = hull->m_numVertices;\n" + " const float4 localDir = qtInvRotate(orn,*dir);\n" + " float offset = dot(pos,*dir);\n" + " for(int i=0;im_vertexOffset+i],localDir);\n" + " if(dp < min[0]) \n" + " min[0] = dp;\n" + " if(dp > max[0]) \n" + " max[0] = dp;\n" + " }\n" + " if(min[0]>max[0])\n" + " {\n" + " float tmp = min[0];\n" + " min[0] = max[0];\n" + " max[0] = tmp;\n" + " }\n" + " min[0] += offset;\n" + " max[0] += offset;\n" + "}\n" + "inline void project(__global const ConvexPolyhedronCL* hull, const float4 pos, const float4 orn, \n" + "const float4* dir, __global const float4* vertices, float* min, float* max)\n" + "{\n" + " min[0] = FLT_MAX;\n" + " max[0] = -FLT_MAX;\n" + " int numVerts = hull->m_numVertices;\n" + " const float4 localDir = qtInvRotate(orn,*dir);\n" + " float offset = dot(pos,*dir);\n" + " for(int i=0;im_vertexOffset+i],localDir);\n" + " if(dp < min[0]) \n" + " min[0] = dp;\n" + " if(dp > max[0]) \n" + " max[0] = dp;\n" + " }\n" + " if(min[0]>max[0])\n" + " {\n" + " float tmp = min[0];\n" + " min[0] = max[0];\n" + " max[0] = tmp;\n" + " }\n" + " min[0] += offset;\n" + " max[0] += offset;\n" + "}\n" + "inline bool TestSepAxisLocalA(const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB, \n" + " const float4 posA,const float4 ornA,\n" + " const float4 posB,const float4 ornB,\n" + " float4* sep_axis, const float4* verticesA, __global const float4* verticesB,float* depth)\n" + "{\n" + " float Min0,Max0;\n" + " float Min1,Max1;\n" + " projectLocal(hullA,posA,ornA,sep_axis,verticesA, &Min0, &Max0);\n" + " project(hullB,posB,ornB, sep_axis,verticesB, &Min1, &Max1);\n" + " if(Max01e-6f || fabs(v.y)>1e-6f || fabs(v.z)>1e-6f)\n" + " return false;\n" + " return true;\n" + "}\n" + "bool findSeparatingAxisLocalA( const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB, \n" + " const float4 posA1,\n" + " const float4 ornA,\n" + " const float4 posB1,\n" + " const float4 ornB,\n" + " const float4 DeltaC2,\n" + " \n" + " const float4* verticesA, \n" + " const float4* uniqueEdgesA, \n" + " const btGpuFace* facesA,\n" + " const int* indicesA,\n" + " __global const float4* verticesB, \n" + " __global const float4* uniqueEdgesB, \n" + " __global const btGpuFace* facesB,\n" + " __global const int* indicesB,\n" + " float4* sep,\n" + " float* dmin)\n" + "{\n" + " \n" + " float4 posA = posA1;\n" + " posA.w = 0.f;\n" + " float4 posB = posB1;\n" + " posB.w = 0.f;\n" + " int curPlaneTests=0;\n" + " {\n" + " int numFacesA = hullA->m_numFaces;\n" + " // Test normals from hullA\n" + " for(int i=0;im_faceOffset+i].m_plane;\n" + " float4 faceANormalWS = qtRotate(ornA,normal);\n" + " if (dot3F4(DeltaC2,faceANormalWS)<0)\n" + " faceANormalWS*=-1.f;\n" + " curPlaneTests++;\n" + " float d;\n" + " if(!TestSepAxisLocalA( hullA, hullB, posA,ornA,posB,ornB,&faceANormalWS, verticesA, verticesB,&d))\n" + " return false;\n" + " if(d<*dmin)\n" + " {\n" + " *dmin = d;\n" + " *sep = faceANormalWS;\n" + " }\n" + " }\n" + " }\n" + " if((dot3F4(-DeltaC2,*sep))>0.0f)\n" + " {\n" + " *sep = -(*sep);\n" + " }\n" + " return true;\n" + "}\n" + "bool findSeparatingAxisLocalB( __global const ConvexPolyhedronCL* hullA, const ConvexPolyhedronCL* hullB, \n" + " const float4 posA1,\n" + " const float4 ornA,\n" + " const float4 posB1,\n" + " const float4 ornB,\n" + " const float4 DeltaC2,\n" + " __global const float4* verticesA, \n" + " __global const float4* uniqueEdgesA, \n" + " __global const btGpuFace* facesA,\n" + " __global const int* indicesA,\n" + " const float4* verticesB,\n" + " const float4* uniqueEdgesB, \n" + " const btGpuFace* facesB,\n" + " const int* indicesB,\n" + " float4* sep,\n" + " float* dmin)\n" + "{\n" + " float4 posA = posA1;\n" + " posA.w = 0.f;\n" + " float4 posB = posB1;\n" + " posB.w = 0.f;\n" + " int curPlaneTests=0;\n" + " {\n" + " int numFacesA = hullA->m_numFaces;\n" + " // Test normals from hullA\n" + " for(int i=0;im_faceOffset+i].m_plane;\n" + " float4 faceANormalWS = qtRotate(ornA,normal);\n" + " if (dot3F4(DeltaC2,faceANormalWS)<0)\n" + " faceANormalWS *= -1.f;\n" + " curPlaneTests++;\n" + " float d;\n" + " if(!TestSepAxisLocalA( hullB, hullA, posB,ornB,posA,ornA, &faceANormalWS, verticesB,verticesA, &d))\n" + " return false;\n" + " if(d<*dmin)\n" + " {\n" + " *dmin = d;\n" + " *sep = faceANormalWS;\n" + " }\n" + " }\n" + " }\n" + " if((dot3F4(-DeltaC2,*sep))>0.0f)\n" + " {\n" + " *sep = -(*sep);\n" + " }\n" + " return true;\n" + "}\n" + "bool findSeparatingAxisEdgeEdgeLocalA( const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB, \n" + " const float4 posA1,\n" + " const float4 ornA,\n" + " const float4 posB1,\n" + " const float4 ornB,\n" + " const float4 DeltaC2,\n" + " const float4* verticesA, \n" + " const float4* uniqueEdgesA, \n" + " const btGpuFace* facesA,\n" + " const int* indicesA,\n" + " __global const float4* verticesB, \n" + " __global const float4* uniqueEdgesB, \n" + " __global const btGpuFace* facesB,\n" + " __global const int* indicesB,\n" + " float4* sep,\n" + " float* dmin)\n" + "{\n" + " float4 posA = posA1;\n" + " posA.w = 0.f;\n" + " float4 posB = posB1;\n" + " posB.w = 0.f;\n" + " int curPlaneTests=0;\n" + " int curEdgeEdge = 0;\n" + " // Test edges\n" + " for(int e0=0;e0m_numUniqueEdges;e0++)\n" + " {\n" + " const float4 edge0 = uniqueEdgesA[hullA->m_uniqueEdgesOffset+e0];\n" + " float4 edge0World = qtRotate(ornA,edge0);\n" + " for(int e1=0;e1m_numUniqueEdges;e1++)\n" + " {\n" + " const float4 edge1 = uniqueEdgesB[hullB->m_uniqueEdgesOffset+e1];\n" + " float4 edge1World = qtRotate(ornB,edge1);\n" + " float4 crossje = cross3(edge0World,edge1World);\n" + " curEdgeEdge++;\n" + " if(!IsAlmostZero(crossje))\n" + " {\n" + " crossje = normalize3(crossje);\n" + " if (dot3F4(DeltaC2,crossje)<0)\n" + " crossje *= -1.f;\n" + " float dist;\n" + " bool result = true;\n" + " {\n" + " float Min0,Max0;\n" + " float Min1,Max1;\n" + " projectLocal(hullA,posA,ornA,&crossje,verticesA, &Min0, &Max0);\n" + " project(hullB,posB,ornB,&crossje,verticesB, &Min1, &Max1);\n" + " \n" + " if(Max00.0f)\n" + " {\n" + " *sep = -(*sep);\n" + " }\n" + " return true;\n" + "}\n" + "inline int findClippingFaces(const float4 separatingNormal,\n" + " const ConvexPolyhedronCL* hullA, \n" + " __global const ConvexPolyhedronCL* hullB,\n" + " const float4 posA, const Quaternion ornA,const float4 posB, const Quaternion ornB,\n" + " __global float4* worldVertsA1,\n" + " __global float4* worldNormalsA1,\n" + " __global float4* worldVertsB1,\n" + " int capacityWorldVerts,\n" + " const float minDist, float maxDist,\n" + " const float4* verticesA,\n" + " const btGpuFace* facesA,\n" + " const int* indicesA,\n" + " __global const float4* verticesB,\n" + " __global const btGpuFace* facesB,\n" + " __global const int* indicesB,\n" + " __global int4* clippingFaces, int pairIndex)\n" + "{\n" + " int numContactsOut = 0;\n" + " int numWorldVertsB1= 0;\n" + " \n" + " \n" + " int closestFaceB=0;\n" + " float dmax = -FLT_MAX;\n" + " \n" + " {\n" + " for(int face=0;facem_numFaces;face++)\n" + " {\n" + " const float4 Normal = make_float4(facesB[hullB->m_faceOffset+face].m_plane.x,\n" + " facesB[hullB->m_faceOffset+face].m_plane.y, facesB[hullB->m_faceOffset+face].m_plane.z,0.f);\n" + " const float4 WorldNormal = qtRotate(ornB, Normal);\n" + " float d = dot3F4(WorldNormal,separatingNormal);\n" + " if (d > dmax)\n" + " {\n" + " dmax = d;\n" + " closestFaceB = face;\n" + " }\n" + " }\n" + " }\n" + " \n" + " {\n" + " const btGpuFace polyB = facesB[hullB->m_faceOffset+closestFaceB];\n" + " int numVertices = polyB.m_numIndices;\n" + " if (numVertices>capacityWorldVerts)\n" + " numVertices = capacityWorldVerts;\n" + " if (numVertices<0)\n" + " numVertices = 0;\n" + " \n" + " for(int e0=0;e0m_vertexOffset+indicesB[polyB.m_indexOffset+e0]];\n" + " worldVertsB1[pairIndex*capacityWorldVerts+numWorldVertsB1++] = transform(&b,&posB,&ornB);\n" + " }\n" + " }\n" + " }\n" + " \n" + " int closestFaceA=0;\n" + " {\n" + " float dmin = FLT_MAX;\n" + " for(int face=0;facem_numFaces;face++)\n" + " {\n" + " const float4 Normal = make_float4(\n" + " facesA[hullA->m_faceOffset+face].m_plane.x,\n" + " facesA[hullA->m_faceOffset+face].m_plane.y,\n" + " facesA[hullA->m_faceOffset+face].m_plane.z,\n" + " 0.f);\n" + " const float4 faceANormalWS = qtRotate(ornA,Normal);\n" + " \n" + " float d = dot3F4(faceANormalWS,separatingNormal);\n" + " if (d < dmin)\n" + " {\n" + " dmin = d;\n" + " closestFaceA = face;\n" + " worldNormalsA1[pairIndex] = faceANormalWS;\n" + " }\n" + " }\n" + " }\n" + " \n" + " int numVerticesA = facesA[hullA->m_faceOffset+closestFaceA].m_numIndices;\n" + " if (numVerticesA>capacityWorldVerts)\n" + " numVerticesA = capacityWorldVerts;\n" + " if (numVerticesA<0)\n" + " numVerticesA=0;\n" + " \n" + " for(int e0=0;e0m_vertexOffset+indicesA[facesA[hullA->m_faceOffset+closestFaceA].m_indexOffset+e0]];\n" + " worldVertsA1[pairIndex*capacityWorldVerts+e0] = transform(&a, &posA,&ornA);\n" + " }\n" + " }\n" + " \n" + " clippingFaces[pairIndex].x = closestFaceA;\n" + " clippingFaces[pairIndex].y = closestFaceB;\n" + " clippingFaces[pairIndex].z = numVerticesA;\n" + " clippingFaces[pairIndex].w = numWorldVertsB1;\n" + " \n" + " \n" + " return numContactsOut;\n" + "}\n" + "// work-in-progress\n" + "__kernel void findConcaveSeparatingAxisVertexFaceKernel( __global int4* concavePairs,\n" + " __global const BodyData* rigidBodies,\n" + " __global const btCollidableGpu* collidables,\n" + " __global const ConvexPolyhedronCL* convexShapes,\n" + " __global const float4* vertices,\n" + " __global const float4* uniqueEdges,\n" + " __global const btGpuFace* faces,\n" + " __global const int* indices,\n" + " __global const btGpuChildShape* gpuChildShapes,\n" + " __global btAabbCL* aabbs,\n" + " __global float4* concaveSeparatingNormalsOut,\n" + " __global int* concaveHasSeparatingNormals,\n" + " __global int4* clippingFacesOut,\n" + " __global float4* worldVertsA1GPU,\n" + " __global float4* worldNormalsAGPU,\n" + " __global float4* worldVertsB1GPU,\n" + " __global float* dmins,\n" + " int vertexFaceCapacity,\n" + " int numConcavePairs\n" + " )\n" + "{\n" + " \n" + " int i = get_global_id(0);\n" + " if (i>=numConcavePairs)\n" + " return;\n" + " \n" + " concaveHasSeparatingNormals[i] = 0;\n" + " \n" + " int pairIdx = i;\n" + " \n" + " int bodyIndexA = concavePairs[i].x;\n" + " int bodyIndexB = concavePairs[i].y;\n" + " \n" + " int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;\n" + " int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;\n" + " \n" + " int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;\n" + " int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;\n" + " \n" + " if (collidables[collidableIndexB].m_shapeType!=SHAPE_CONVEX_HULL&&\n" + " collidables[collidableIndexB].m_shapeType!=SHAPE_COMPOUND_OF_CONVEX_HULLS)\n" + " {\n" + " concavePairs[pairIdx].w = -1;\n" + " return;\n" + " }\n" + " \n" + " \n" + " \n" + " int numFacesA = convexShapes[shapeIndexA].m_numFaces;\n" + " int numActualConcaveConvexTests = 0;\n" + " \n" + " int f = concavePairs[i].z;\n" + " \n" + " bool overlap = false;\n" + " \n" + " ConvexPolyhedronCL convexPolyhedronA;\n" + " \n" + " //add 3 vertices of the triangle\n" + " convexPolyhedronA.m_numVertices = 3;\n" + " convexPolyhedronA.m_vertexOffset = 0;\n" + " float4 localCenter = make_float4(0.f,0.f,0.f,0.f);\n" + " \n" + " btGpuFace face = faces[convexShapes[shapeIndexA].m_faceOffset+f];\n" + " float4 triMinAabb, triMaxAabb;\n" + " btAabbCL triAabb;\n" + " triAabb.m_min = make_float4(1e30f,1e30f,1e30f,0.f);\n" + " triAabb.m_max = make_float4(-1e30f,-1e30f,-1e30f,0.f);\n" + " \n" + " float4 verticesA[3];\n" + " for (int i=0;i<3;i++)\n" + " {\n" + " int index = indices[face.m_indexOffset+i];\n" + " float4 vert = vertices[convexShapes[shapeIndexA].m_vertexOffset+index];\n" + " verticesA[i] = vert;\n" + " localCenter += vert;\n" + " \n" + " triAabb.m_min = min(triAabb.m_min,vert);\n" + " triAabb.m_max = max(triAabb.m_max,vert);\n" + " \n" + " }\n" + " \n" + " overlap = true;\n" + " overlap = (triAabb.m_min.x > aabbs[bodyIndexB].m_max.x || triAabb.m_max.x < aabbs[bodyIndexB].m_min.x) ? false : overlap;\n" + " overlap = (triAabb.m_min.z > aabbs[bodyIndexB].m_max.z || triAabb.m_max.z < aabbs[bodyIndexB].m_min.z) ? false : overlap;\n" + " overlap = (triAabb.m_min.y > aabbs[bodyIndexB].m_max.y || triAabb.m_max.y < aabbs[bodyIndexB].m_min.y) ? false : overlap;\n" + " \n" + " if (overlap)\n" + " {\n" + " float dmin = FLT_MAX;\n" + " int hasSeparatingAxis=5;\n" + " float4 sepAxis=make_float4(1,2,3,4);\n" + " \n" + " int localCC=0;\n" + " numActualConcaveConvexTests++;\n" + " \n" + " //a triangle has 3 unique edges\n" + " convexPolyhedronA.m_numUniqueEdges = 3;\n" + " convexPolyhedronA.m_uniqueEdgesOffset = 0;\n" + " float4 uniqueEdgesA[3];\n" + " \n" + " uniqueEdgesA[0] = (verticesA[1]-verticesA[0]);\n" + " uniqueEdgesA[1] = (verticesA[2]-verticesA[1]);\n" + " uniqueEdgesA[2] = (verticesA[0]-verticesA[2]);\n" + " \n" + " \n" + " convexPolyhedronA.m_faceOffset = 0;\n" + " \n" + " float4 normal = make_float4(face.m_plane.x,face.m_plane.y,face.m_plane.z,0.f);\n" + " \n" + " btGpuFace facesA[TRIANGLE_NUM_CONVEX_FACES];\n" + " int indicesA[3+3+2+2+2];\n" + " int curUsedIndices=0;\n" + " int fidx=0;\n" + " \n" + " //front size of triangle\n" + " {\n" + " facesA[fidx].m_indexOffset=curUsedIndices;\n" + " indicesA[0] = 0;\n" + " indicesA[1] = 1;\n" + " indicesA[2] = 2;\n" + " curUsedIndices+=3;\n" + " float c = face.m_plane.w;\n" + " facesA[fidx].m_plane.x = normal.x;\n" + " facesA[fidx].m_plane.y = normal.y;\n" + " facesA[fidx].m_plane.z = normal.z;\n" + " facesA[fidx].m_plane.w = c;\n" + " facesA[fidx].m_numIndices=3;\n" + " }\n" + " fidx++;\n" + " //back size of triangle\n" + " {\n" + " facesA[fidx].m_indexOffset=curUsedIndices;\n" + " indicesA[3]=2;\n" + " indicesA[4]=1;\n" + " indicesA[5]=0;\n" + " curUsedIndices+=3;\n" + " float c = dot(normal,verticesA[0]);\n" + " float c1 = -face.m_plane.w;\n" + " facesA[fidx].m_plane.x = -normal.x;\n" + " facesA[fidx].m_plane.y = -normal.y;\n" + " facesA[fidx].m_plane.z = -normal.z;\n" + " facesA[fidx].m_plane.w = c;\n" + " facesA[fidx].m_numIndices=3;\n" + " }\n" + " fidx++;\n" + " \n" + " bool addEdgePlanes = true;\n" + " if (addEdgePlanes)\n" + " {\n" + " int numVertices=3;\n" + " int prevVertex = numVertices-1;\n" + " for (int i=0;i=numConcavePairs)\n" + " return;\n" + " \n" + " if (!concaveHasSeparatingNormals[i])\n" + " return;\n" + " \n" + " int pairIdx = i;\n" + " \n" + " int bodyIndexA = concavePairs[i].x;\n" + " int bodyIndexB = concavePairs[i].y;\n" + " \n" + " int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;\n" + " int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;\n" + " \n" + " int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;\n" + " int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;\n" + " \n" + " \n" + " int numFacesA = convexShapes[shapeIndexA].m_numFaces;\n" + " int numActualConcaveConvexTests = 0;\n" + " \n" + " int f = concavePairs[i].z;\n" + " \n" + " bool overlap = false;\n" + " \n" + " ConvexPolyhedronCL convexPolyhedronA;\n" + " \n" + " //add 3 vertices of the triangle\n" + " convexPolyhedronA.m_numVertices = 3;\n" + " convexPolyhedronA.m_vertexOffset = 0;\n" + " float4 localCenter = make_float4(0.f,0.f,0.f,0.f);\n" + " \n" + " btGpuFace face = faces[convexShapes[shapeIndexA].m_faceOffset+f];\n" + " float4 triMinAabb, triMaxAabb;\n" + " btAabbCL triAabb;\n" + " triAabb.m_min = make_float4(1e30f,1e30f,1e30f,0.f);\n" + " triAabb.m_max = make_float4(-1e30f,-1e30f,-1e30f,0.f);\n" + " \n" + " float4 verticesA[3];\n" + " for (int i=0;i<3;i++)\n" + " {\n" + " int index = indices[face.m_indexOffset+i];\n" + " float4 vert = vertices[convexShapes[shapeIndexA].m_vertexOffset+index];\n" + " verticesA[i] = vert;\n" + " localCenter += vert;\n" + " \n" + " triAabb.m_min = min(triAabb.m_min,vert);\n" + " triAabb.m_max = max(triAabb.m_max,vert);\n" + " \n" + " }\n" + " \n" + " overlap = true;\n" + " overlap = (triAabb.m_min.x > aabbs[bodyIndexB].m_max.x || triAabb.m_max.x < aabbs[bodyIndexB].m_min.x) ? false : overlap;\n" + " overlap = (triAabb.m_min.z > aabbs[bodyIndexB].m_max.z || triAabb.m_max.z < aabbs[bodyIndexB].m_min.z) ? false : overlap;\n" + " overlap = (triAabb.m_min.y > aabbs[bodyIndexB].m_max.y || triAabb.m_max.y < aabbs[bodyIndexB].m_min.y) ? false : overlap;\n" + " \n" + " if (overlap)\n" + " {\n" + " float dmin = dmins[i];\n" + " int hasSeparatingAxis=5;\n" + " float4 sepAxis=make_float4(1,2,3,4);\n" + " sepAxis = concaveSeparatingNormalsOut[pairIdx];\n" + " \n" + " int localCC=0;\n" + " numActualConcaveConvexTests++;\n" + " \n" + " //a triangle has 3 unique edges\n" + " convexPolyhedronA.m_numUniqueEdges = 3;\n" + " convexPolyhedronA.m_uniqueEdgesOffset = 0;\n" + " float4 uniqueEdgesA[3];\n" + " \n" + " uniqueEdgesA[0] = (verticesA[1]-verticesA[0]);\n" + " uniqueEdgesA[1] = (verticesA[2]-verticesA[1]);\n" + " uniqueEdgesA[2] = (verticesA[0]-verticesA[2]);\n" + " \n" + " \n" + " convexPolyhedronA.m_faceOffset = 0;\n" + " \n" + " float4 normal = make_float4(face.m_plane.x,face.m_plane.y,face.m_plane.z,0.f);\n" + " \n" + " btGpuFace facesA[TRIANGLE_NUM_CONVEX_FACES];\n" + " int indicesA[3+3+2+2+2];\n" + " int curUsedIndices=0;\n" + " int fidx=0;\n" + " \n" + " //front size of triangle\n" + " {\n" + " facesA[fidx].m_indexOffset=curUsedIndices;\n" + " indicesA[0] = 0;\n" + " indicesA[1] = 1;\n" + " indicesA[2] = 2;\n" + " curUsedIndices+=3;\n" + " float c = face.m_plane.w;\n" + " facesA[fidx].m_plane.x = normal.x;\n" + " facesA[fidx].m_plane.y = normal.y;\n" + " facesA[fidx].m_plane.z = normal.z;\n" + " facesA[fidx].m_plane.w = c;\n" + " facesA[fidx].m_numIndices=3;\n" + " }\n" + " fidx++;\n" + " //back size of triangle\n" + " {\n" + " facesA[fidx].m_indexOffset=curUsedIndices;\n" + " indicesA[3]=2;\n" + " indicesA[4]=1;\n" + " indicesA[5]=0;\n" + " curUsedIndices+=3;\n" + " float c = dot(normal,verticesA[0]);\n" + " float c1 = -face.m_plane.w;\n" + " facesA[fidx].m_plane.x = -normal.x;\n" + " facesA[fidx].m_plane.y = -normal.y;\n" + " facesA[fidx].m_plane.z = -normal.z;\n" + " facesA[fidx].m_plane.w = c;\n" + " facesA[fidx].m_numIndices=3;\n" + " }\n" + " fidx++;\n" + " \n" + " bool addEdgePlanes = true;\n" + " if (addEdgePlanes)\n" + " {\n" + " int numVertices=3;\n" + " int prevVertex = numVertices-1;\n" + " for (int i=0;im_escapeIndexOrTriangleIndex&~(y));\n" -"}\n" -"int getTriangleIndexGlobal(__global const b3QuantizedBvhNode* rootNode)\n" -"{\n" -" unsigned int x=0;\n" -" unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS);\n" -" // Get only the lower bits where the triangle index is stored\n" -" return (rootNode->m_escapeIndexOrTriangleIndex&~(y));\n" -"}\n" -"int isLeafNode(const b3QuantizedBvhNode* rootNode)\n" -"{\n" -" //skipindex is negative (internal node), triangleindex >=0 (leafnode)\n" -" return (rootNode->m_escapeIndexOrTriangleIndex >= 0)? 1 : 0;\n" -"}\n" -"int isLeafNodeGlobal(__global const b3QuantizedBvhNode* rootNode)\n" -"{\n" -" //skipindex is negative (internal node), triangleindex >=0 (leafnode)\n" -" return (rootNode->m_escapeIndexOrTriangleIndex >= 0)? 1 : 0;\n" -"}\n" -" \n" -"int getEscapeIndex(const b3QuantizedBvhNode* rootNode)\n" -"{\n" -" return -rootNode->m_escapeIndexOrTriangleIndex;\n" -"}\n" -"int getEscapeIndexGlobal(__global const b3QuantizedBvhNode* rootNode)\n" -"{\n" -" return -rootNode->m_escapeIndexOrTriangleIndex;\n" -"}\n" -"typedef struct\n" -"{\n" -" //12 bytes\n" -" unsigned short int m_quantizedAabbMin[3];\n" -" unsigned short int m_quantizedAabbMax[3];\n" -" //4 bytes, points to the root of the subtree\n" -" int m_rootNodeIndex;\n" -" //4 bytes\n" -" int m_subtreeSize;\n" -" int m_padding[3];\n" -"} b3BvhSubtreeInfo;\n" -"typedef struct\n" -"{\n" -" float4 m_childPosition;\n" -" float4 m_childOrientation;\n" -" int m_shapeIndex;\n" -" int m_unused0;\n" -" int m_unused1;\n" -" int m_unused2;\n" -"} btGpuChildShape;\n" -"typedef struct\n" -"{\n" -" float4 m_pos;\n" -" float4 m_quat;\n" -" float4 m_linVel;\n" -" float4 m_angVel;\n" -" u32 m_collidableIdx;\n" -" float m_invMass;\n" -" float m_restituitionCoeff;\n" -" float m_frictionCoeff;\n" -"} BodyData;\n" -"typedef struct \n" -"{\n" -" float4 m_localCenter;\n" -" float4 m_extents;\n" -" float4 mC;\n" -" float4 mE;\n" -" \n" -" float m_radius;\n" -" int m_faceOffset;\n" -" int m_numFaces;\n" -" int m_numVertices;\n" -" int m_vertexOffset;\n" -" int m_uniqueEdgesOffset;\n" -" int m_numUniqueEdges;\n" -" int m_unused;\n" -"} ConvexPolyhedronCL;\n" -"typedef struct \n" -"{\n" -" union\n" -" {\n" -" float4 m_min;\n" -" float m_minElems[4];\n" -" int m_minIndices[4];\n" -" };\n" -" union\n" -" {\n" -" float4 m_max;\n" -" float m_maxElems[4];\n" -" int m_maxIndices[4];\n" -" };\n" -"} btAabbCL;\n" -"#ifndef B3_AABB_H\n" -"#define B3_AABB_H\n" -"#ifndef B3_FLOAT4_H\n" -"#define B3_FLOAT4_H\n" -"#ifndef B3_PLATFORM_DEFINITIONS_H\n" -"#define B3_PLATFORM_DEFINITIONS_H\n" -"struct MyTest\n" -"{\n" -" int bla;\n" -"};\n" -"#ifdef __cplusplus\n" -"#else\n" -"//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n" -"#define B3_LARGE_FLOAT 1e18f\n" -"#define B3_INFINITY 1e18f\n" -"#define b3Assert(a)\n" -"#define b3ConstArray(a) __global const a*\n" -"#define b3AtomicInc atomic_inc\n" -"#define b3AtomicAdd atomic_add\n" -"#define b3Fabs fabs\n" -"#define b3Sqrt native_sqrt\n" -"#define b3Sin native_sin\n" -"#define b3Cos native_cos\n" -"#define B3_STATIC\n" -"#endif\n" -"#endif\n" -"#ifdef __cplusplus\n" -"#else\n" -" typedef float4 b3Float4;\n" -" #define b3Float4ConstArg const b3Float4\n" -" #define b3MakeFloat4 (float4)\n" -" float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" -" {\n" -" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" -" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" -" return dot(a1, b1);\n" -" }\n" -" b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" -" {\n" -" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" -" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" -" return cross(a1, b1);\n" -" }\n" -" #define b3MinFloat4 min\n" -" #define b3MaxFloat4 max\n" -" #define b3Normalized(a) normalize(a)\n" -"#endif \n" -" \n" -"inline bool b3IsAlmostZero(b3Float4ConstArg v)\n" -"{\n" -" if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" -" return false;\n" -" return true;\n" -"}\n" -"inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" -"{\n" -" float maxDot = -B3_INFINITY;\n" -" int i = 0;\n" -" int ptIndex = -1;\n" -" for( i = 0; i < vecLen; i++ )\n" -" {\n" -" float dot = b3Dot3F4(vecArray[i],vec);\n" -" \n" -" if( dot > maxDot )\n" -" {\n" -" maxDot = dot;\n" -" ptIndex = i;\n" -" }\n" -" }\n" -" b3Assert(ptIndex>=0);\n" -" if (ptIndex<0)\n" -" {\n" -" ptIndex = 0;\n" -" }\n" -" *dotOut = maxDot;\n" -" return ptIndex;\n" -"}\n" -"#endif //B3_FLOAT4_H\n" -"#ifndef B3_MAT3x3_H\n" -"#define B3_MAT3x3_H\n" -"#ifndef B3_QUAT_H\n" -"#define B3_QUAT_H\n" -"#ifndef B3_PLATFORM_DEFINITIONS_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif\n" -"#endif\n" -"#ifndef B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -" typedef float4 b3Quat;\n" -" #define b3QuatConstArg const b3Quat\n" -" \n" -" \n" -"inline float4 b3FastNormalize4(float4 v)\n" -"{\n" -" v = (float4)(v.xyz,0.f);\n" -" return fast_normalize(v);\n" -"}\n" -" \n" -"inline b3Quat b3QuatMul(b3Quat a, b3Quat b);\n" -"inline b3Quat b3QuatNormalized(b3QuatConstArg in);\n" -"inline b3Quat b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec);\n" -"inline b3Quat b3QuatInvert(b3QuatConstArg q);\n" -"inline b3Quat b3QuatInverse(b3QuatConstArg q);\n" -"inline b3Quat b3QuatMul(b3QuatConstArg a, b3QuatConstArg b)\n" -"{\n" -" b3Quat ans;\n" -" ans = b3Cross3( a, b );\n" -" ans += a.w*b+b.w*a;\n" -"// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" -" ans.w = a.w*b.w - b3Dot3F4(a, b);\n" -" return ans;\n" -"}\n" -"inline b3Quat b3QuatNormalized(b3QuatConstArg in)\n" -"{\n" -" b3Quat q;\n" -" q=in;\n" -" //return b3FastNormalize4(in);\n" -" float len = native_sqrt(dot(q, q));\n" -" if(len > 0.f)\n" -" {\n" -" q *= 1.f / len;\n" -" }\n" -" else\n" -" {\n" -" q.x = q.y = q.z = 0.f;\n" -" q.w = 1.f;\n" -" }\n" -" return q;\n" -"}\n" -"inline float4 b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" -"{\n" -" b3Quat qInv = b3QuatInvert( q );\n" -" float4 vcpy = vec;\n" -" vcpy.w = 0.f;\n" -" float4 out = b3QuatMul(b3QuatMul(q,vcpy),qInv);\n" -" return out;\n" -"}\n" -"inline b3Quat b3QuatInverse(b3QuatConstArg q)\n" -"{\n" -" return (b3Quat)(-q.xyz, q.w);\n" -"}\n" -"inline b3Quat b3QuatInvert(b3QuatConstArg q)\n" -"{\n" -" return (b3Quat)(-q.xyz, q.w);\n" -"}\n" -"inline float4 b3QuatInvRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" -"{\n" -" return b3QuatRotate( b3QuatInvert( q ), vec );\n" -"}\n" -"inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)\n" -"{\n" -" return b3QuatRotate( orientation, point ) + (translation);\n" -"}\n" -" \n" -"#endif \n" -"#endif //B3_QUAT_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"typedef struct\n" -"{\n" -" b3Float4 m_row[3];\n" -"}b3Mat3x3;\n" -"#define b3Mat3x3ConstArg const b3Mat3x3\n" -"#define b3GetRow(m,row) (m.m_row[row])\n" -"inline b3Mat3x3 b3QuatGetRotationMatrix(b3Quat quat)\n" -"{\n" -" b3Float4 quat2 = (b3Float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f);\n" -" b3Mat3x3 out;\n" -" out.m_row[0].x=1-2*quat2.y-2*quat2.z;\n" -" out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z;\n" -" out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y;\n" -" out.m_row[0].w = 0.f;\n" -" out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z;\n" -" out.m_row[1].y=1-2*quat2.x-2*quat2.z;\n" -" out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x;\n" -" out.m_row[1].w = 0.f;\n" -" out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y;\n" -" out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x;\n" -" out.m_row[2].z=1-2*quat2.x-2*quat2.y;\n" -" out.m_row[2].w = 0.f;\n" -" return out;\n" -"}\n" -"inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg matIn)\n" -"{\n" -" b3Mat3x3 out;\n" -" out.m_row[0] = fabs(matIn.m_row[0]);\n" -" out.m_row[1] = fabs(matIn.m_row[1]);\n" -" out.m_row[2] = fabs(matIn.m_row[2]);\n" -" return out;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtZero();\n" -"__inline\n" -"b3Mat3x3 mtIdentity();\n" -"__inline\n" -"b3Mat3x3 mtTranspose(b3Mat3x3 m);\n" -"__inline\n" -"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b);\n" -"__inline\n" -"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b);\n" -"__inline\n" -"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b);\n" -"__inline\n" -"b3Mat3x3 mtZero()\n" -"{\n" -" b3Mat3x3 m;\n" -" m.m_row[0] = (b3Float4)(0.f);\n" -" m.m_row[1] = (b3Float4)(0.f);\n" -" m.m_row[2] = (b3Float4)(0.f);\n" -" return m;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtIdentity()\n" -"{\n" -" b3Mat3x3 m;\n" -" m.m_row[0] = (b3Float4)(1,0,0,0);\n" -" m.m_row[1] = (b3Float4)(0,1,0,0);\n" -" m.m_row[2] = (b3Float4)(0,0,1,0);\n" -" return m;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtTranspose(b3Mat3x3 m)\n" -"{\n" -" b3Mat3x3 out;\n" -" out.m_row[0] = (b3Float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n" -" out.m_row[1] = (b3Float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n" -" out.m_row[2] = (b3Float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n" -" return out;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b)\n" -"{\n" -" b3Mat3x3 transB;\n" -" transB = mtTranspose( b );\n" -" b3Mat3x3 ans;\n" -" // why this doesn't run when 0ing in the for{}\n" -" a.m_row[0].w = 0.f;\n" -" a.m_row[1].w = 0.f;\n" -" a.m_row[2].w = 0.f;\n" -" for(int i=0; i<3; i++)\n" -" {\n" -"// a.m_row[i].w = 0.f;\n" -" ans.m_row[i].x = b3Dot3F4(a.m_row[i],transB.m_row[0]);\n" -" ans.m_row[i].y = b3Dot3F4(a.m_row[i],transB.m_row[1]);\n" -" ans.m_row[i].z = b3Dot3F4(a.m_row[i],transB.m_row[2]);\n" -" ans.m_row[i].w = 0.f;\n" -" }\n" -" return ans;\n" -"}\n" -"__inline\n" -"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b)\n" -"{\n" -" b3Float4 ans;\n" -" ans.x = b3Dot3F4( a.m_row[0], b );\n" -" ans.y = b3Dot3F4( a.m_row[1], b );\n" -" ans.z = b3Dot3F4( a.m_row[2], b );\n" -" ans.w = 0.f;\n" -" return ans;\n" -"}\n" -"__inline\n" -"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b)\n" -"{\n" -" b3Float4 colx = b3MakeFloat4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" -" b3Float4 coly = b3MakeFloat4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" -" b3Float4 colz = b3MakeFloat4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" -" b3Float4 ans;\n" -" ans.x = b3Dot3F4( a, colx );\n" -" ans.y = b3Dot3F4( a, coly );\n" -" ans.z = b3Dot3F4( a, colz );\n" -" return ans;\n" -"}\n" -"#endif\n" -"#endif //B3_MAT3x3_H\n" -"typedef struct b3Aabb b3Aabb_t;\n" -"struct b3Aabb\n" -"{\n" -" union\n" -" {\n" -" float m_min[4];\n" -" b3Float4 m_minVec;\n" -" int m_minIndices[4];\n" -" };\n" -" union\n" -" {\n" -" float m_max[4];\n" -" b3Float4 m_maxVec;\n" -" int m_signedMaxIndices[4];\n" -" };\n" -"};\n" -"inline void b3TransformAabb2(b3Float4ConstArg localAabbMin,b3Float4ConstArg localAabbMax, float margin,\n" -" b3Float4ConstArg pos,\n" -" b3QuatConstArg orn,\n" -" b3Float4* aabbMinOut,b3Float4* aabbMaxOut)\n" -"{\n" -" b3Float4 localHalfExtents = 0.5f*(localAabbMax-localAabbMin);\n" -" localHalfExtents+=b3MakeFloat4(margin,margin,margin,0.f);\n" -" b3Float4 localCenter = 0.5f*(localAabbMax+localAabbMin);\n" -" b3Mat3x3 m;\n" -" m = b3QuatGetRotationMatrix(orn);\n" -" b3Mat3x3 abs_b = b3AbsoluteMat3x3(m);\n" -" b3Float4 center = b3TransformPoint(localCenter,pos,orn);\n" -" \n" -" b3Float4 extent = b3MakeFloat4(b3Dot3F4(localHalfExtents,b3GetRow(abs_b,0)),\n" -" b3Dot3F4(localHalfExtents,b3GetRow(abs_b,1)),\n" -" b3Dot3F4(localHalfExtents,b3GetRow(abs_b,2)),\n" -" 0.f);\n" -" *aabbMinOut = center-extent;\n" -" *aabbMaxOut = center+extent;\n" -"}\n" -"/// conservative test for overlap between two aabbs\n" -"inline bool b3TestAabbAgainstAabb(b3Float4ConstArg aabbMin1,b3Float4ConstArg aabbMax1,\n" -" b3Float4ConstArg aabbMin2, b3Float4ConstArg aabbMax2)\n" -"{\n" -" bool overlap = true;\n" -" overlap = (aabbMin1.x > aabbMax2.x || aabbMax1.x < aabbMin2.x) ? false : overlap;\n" -" overlap = (aabbMin1.z > aabbMax2.z || aabbMax1.z < aabbMin2.z) ? false : overlap;\n" -" overlap = (aabbMin1.y > aabbMax2.y || aabbMax1.y < aabbMin2.y) ? false : overlap;\n" -" return overlap;\n" -"}\n" -"#endif //B3_AABB_H\n" -"/*\n" -"Bullet Continuous Collision Detection and Physics Library\n" -"Copyright (c) 2003-2013 Erwin Coumans http://bulletphysics.org\n" -"This software is provided 'as-is', without any express or implied warranty.\n" -"In no event will the authors be held liable for any damages arising from the use of this software.\n" -"Permission is granted to anyone to use this software for any purpose,\n" -"including commercial applications, and to alter it and redistribute it freely,\n" -"subject to the following restrictions:\n" -"1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" -"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" -"3. This notice may not be removed or altered from any source distribution.\n" -"*/\n" -"#ifndef B3_INT2_H\n" -"#define B3_INT2_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#define b3UnsignedInt2 uint2\n" -"#define b3Int2 int2\n" -"#define b3MakeInt2 (int2)\n" -"#endif //__cplusplus\n" -"#endif\n" -"typedef struct\n" -"{\n" -" float4 m_plane;\n" -" int m_indexOffset;\n" -" int m_numIndices;\n" -"} btGpuFace;\n" -"#define make_float4 (float4)\n" -"__inline\n" -"float4 cross3(float4 a, float4 b)\n" -"{\n" -" return cross(a,b);\n" -" \n" -"// float4 a1 = make_float4(a.xyz,0.f);\n" -"// float4 b1 = make_float4(b.xyz,0.f);\n" -"// return cross(a1,b1);\n" -"//float4 c = make_float4(a.y*b.z - a.z*b.y,a.z*b.x - a.x*b.z,a.x*b.y - a.y*b.x,0.f);\n" -" \n" -" // float4 c = make_float4(a.y*b.z - a.z*b.y,1.f,a.x*b.y - a.y*b.x,0.f);\n" -" \n" -" //return c;\n" -"}\n" -"__inline\n" -"float dot3F4(float4 a, float4 b)\n" -"{\n" -" float4 a1 = make_float4(a.xyz,0.f);\n" -" float4 b1 = make_float4(b.xyz,0.f);\n" -" return dot(a1, b1);\n" -"}\n" -"__inline\n" -"float4 fastNormalize4(float4 v)\n" -"{\n" -" v = make_float4(v.xyz,0.f);\n" -" return fast_normalize(v);\n" -"}\n" -"///////////////////////////////////////\n" -"// Quaternion\n" -"///////////////////////////////////////\n" -"typedef float4 Quaternion;\n" -"__inline\n" -"Quaternion qtMul(Quaternion a, Quaternion b);\n" -"__inline\n" -"Quaternion qtNormalize(Quaternion in);\n" -"__inline\n" -"float4 qtRotate(Quaternion q, float4 vec);\n" -"__inline\n" -"Quaternion qtInvert(Quaternion q);\n" -"__inline\n" -"Quaternion qtMul(Quaternion a, Quaternion b)\n" -"{\n" -" Quaternion ans;\n" -" ans = cross3( a, b );\n" -" ans += a.w*b+b.w*a;\n" -"// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" -" ans.w = a.w*b.w - dot3F4(a, b);\n" -" return ans;\n" -"}\n" -"__inline\n" -"Quaternion qtNormalize(Quaternion in)\n" -"{\n" -" return fastNormalize4(in);\n" -"// in /= length( in );\n" -"// return in;\n" -"}\n" -"__inline\n" -"float4 qtRotate(Quaternion q, float4 vec)\n" -"{\n" -" Quaternion qInv = qtInvert( q );\n" -" float4 vcpy = vec;\n" -" vcpy.w = 0.f;\n" -" float4 out = qtMul(qtMul(q,vcpy),qInv);\n" -" return out;\n" -"}\n" -"__inline\n" -"Quaternion qtInvert(Quaternion q)\n" -"{\n" -" return (Quaternion)(-q.xyz, q.w);\n" -"}\n" -"__inline\n" -"float4 qtInvRotate(const Quaternion q, float4 vec)\n" -"{\n" -" return qtRotate( qtInvert( q ), vec );\n" -"}\n" -"__inline\n" -"float4 transform(const float4* p, const float4* translation, const Quaternion* orientation)\n" -"{\n" -" return qtRotate( *orientation, *p ) + (*translation);\n" -"}\n" -"__inline\n" -"float4 normalize3(const float4 a)\n" -"{\n" -" float4 n = make_float4(a.x, a.y, a.z, 0.f);\n" -" return fastNormalize4( n );\n" -"}\n" -"inline void projectLocal(const ConvexPolyhedronCL* hull, const float4 pos, const float4 orn, \n" -"const float4* dir, const float4* vertices, float* min, float* max)\n" -"{\n" -" min[0] = FLT_MAX;\n" -" max[0] = -FLT_MAX;\n" -" int numVerts = hull->m_numVertices;\n" -" const float4 localDir = qtInvRotate(orn,*dir);\n" -" float offset = dot(pos,*dir);\n" -" for(int i=0;im_vertexOffset+i],localDir);\n" -" if(dp < min[0]) \n" -" min[0] = dp;\n" -" if(dp > max[0]) \n" -" max[0] = dp;\n" -" }\n" -" if(min[0]>max[0])\n" -" {\n" -" float tmp = min[0];\n" -" min[0] = max[0];\n" -" max[0] = tmp;\n" -" }\n" -" min[0] += offset;\n" -" max[0] += offset;\n" -"}\n" -"inline void project(__global const ConvexPolyhedronCL* hull, const float4 pos, const float4 orn, \n" -"const float4* dir, __global const float4* vertices, float* min, float* max)\n" -"{\n" -" min[0] = FLT_MAX;\n" -" max[0] = -FLT_MAX;\n" -" int numVerts = hull->m_numVertices;\n" -" const float4 localDir = qtInvRotate(orn,*dir);\n" -" float offset = dot(pos,*dir);\n" -" for(int i=0;im_vertexOffset+i],localDir);\n" -" if(dp < min[0]) \n" -" min[0] = dp;\n" -" if(dp > max[0]) \n" -" max[0] = dp;\n" -" }\n" -" if(min[0]>max[0])\n" -" {\n" -" float tmp = min[0];\n" -" min[0] = max[0];\n" -" max[0] = tmp;\n" -" }\n" -" min[0] += offset;\n" -" max[0] += offset;\n" -"}\n" -"inline bool TestSepAxisLocalA(const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB, \n" -" const float4 posA,const float4 ornA,\n" -" const float4 posB,const float4 ornB,\n" -" float4* sep_axis, const float4* verticesA, __global const float4* verticesB,float* depth)\n" -"{\n" -" float Min0,Max0;\n" -" float Min1,Max1;\n" -" projectLocal(hullA,posA,ornA,sep_axis,verticesA, &Min0, &Max0);\n" -" project(hullB,posB,ornB, sep_axis,verticesB, &Min1, &Max1);\n" -" if(Max01e-6f || fabs(v.y)>1e-6f || fabs(v.z)>1e-6f)\n" -" return false;\n" -" return true;\n" -"}\n" -"bool findSeparatingAxisLocalA( const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB, \n" -" const float4 posA1,\n" -" const float4 ornA,\n" -" const float4 posB1,\n" -" const float4 ornB,\n" -" const float4 DeltaC2,\n" -" \n" -" const float4* verticesA, \n" -" const float4* uniqueEdgesA, \n" -" const btGpuFace* facesA,\n" -" const int* indicesA,\n" -" __global const float4* verticesB, \n" -" __global const float4* uniqueEdgesB, \n" -" __global const btGpuFace* facesB,\n" -" __global const int* indicesB,\n" -" float4* sep,\n" -" float* dmin)\n" -"{\n" -" \n" -" float4 posA = posA1;\n" -" posA.w = 0.f;\n" -" float4 posB = posB1;\n" -" posB.w = 0.f;\n" -" int curPlaneTests=0;\n" -" {\n" -" int numFacesA = hullA->m_numFaces;\n" -" // Test normals from hullA\n" -" for(int i=0;im_faceOffset+i].m_plane;\n" -" float4 faceANormalWS = qtRotate(ornA,normal);\n" -" if (dot3F4(DeltaC2,faceANormalWS)<0)\n" -" faceANormalWS*=-1.f;\n" -" curPlaneTests++;\n" -" float d;\n" -" if(!TestSepAxisLocalA( hullA, hullB, posA,ornA,posB,ornB,&faceANormalWS, verticesA, verticesB,&d))\n" -" return false;\n" -" if(d<*dmin)\n" -" {\n" -" *dmin = d;\n" -" *sep = faceANormalWS;\n" -" }\n" -" }\n" -" }\n" -" if((dot3F4(-DeltaC2,*sep))>0.0f)\n" -" {\n" -" *sep = -(*sep);\n" -" }\n" -" return true;\n" -"}\n" -"bool findSeparatingAxisLocalB( __global const ConvexPolyhedronCL* hullA, const ConvexPolyhedronCL* hullB, \n" -" const float4 posA1,\n" -" const float4 ornA,\n" -" const float4 posB1,\n" -" const float4 ornB,\n" -" const float4 DeltaC2,\n" -" __global const float4* verticesA, \n" -" __global const float4* uniqueEdgesA, \n" -" __global const btGpuFace* facesA,\n" -" __global const int* indicesA,\n" -" const float4* verticesB,\n" -" const float4* uniqueEdgesB, \n" -" const btGpuFace* facesB,\n" -" const int* indicesB,\n" -" float4* sep,\n" -" float* dmin)\n" -"{\n" -" float4 posA = posA1;\n" -" posA.w = 0.f;\n" -" float4 posB = posB1;\n" -" posB.w = 0.f;\n" -" int curPlaneTests=0;\n" -" {\n" -" int numFacesA = hullA->m_numFaces;\n" -" // Test normals from hullA\n" -" for(int i=0;im_faceOffset+i].m_plane;\n" -" float4 faceANormalWS = qtRotate(ornA,normal);\n" -" if (dot3F4(DeltaC2,faceANormalWS)<0)\n" -" faceANormalWS *= -1.f;\n" -" curPlaneTests++;\n" -" float d;\n" -" if(!TestSepAxisLocalA( hullB, hullA, posB,ornB,posA,ornA, &faceANormalWS, verticesB,verticesA, &d))\n" -" return false;\n" -" if(d<*dmin)\n" -" {\n" -" *dmin = d;\n" -" *sep = faceANormalWS;\n" -" }\n" -" }\n" -" }\n" -" if((dot3F4(-DeltaC2,*sep))>0.0f)\n" -" {\n" -" *sep = -(*sep);\n" -" }\n" -" return true;\n" -"}\n" -"bool findSeparatingAxisEdgeEdgeLocalA( const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB, \n" -" const float4 posA1,\n" -" const float4 ornA,\n" -" const float4 posB1,\n" -" const float4 ornB,\n" -" const float4 DeltaC2,\n" -" const float4* verticesA, \n" -" const float4* uniqueEdgesA, \n" -" const btGpuFace* facesA,\n" -" const int* indicesA,\n" -" __global const float4* verticesB, \n" -" __global const float4* uniqueEdgesB, \n" -" __global const btGpuFace* facesB,\n" -" __global const int* indicesB,\n" -" float4* sep,\n" -" float* dmin)\n" -"{\n" -" float4 posA = posA1;\n" -" posA.w = 0.f;\n" -" float4 posB = posB1;\n" -" posB.w = 0.f;\n" -" int curPlaneTests=0;\n" -" int curEdgeEdge = 0;\n" -" // Test edges\n" -" for(int e0=0;e0m_numUniqueEdges;e0++)\n" -" {\n" -" const float4 edge0 = uniqueEdgesA[hullA->m_uniqueEdgesOffset+e0];\n" -" float4 edge0World = qtRotate(ornA,edge0);\n" -" for(int e1=0;e1m_numUniqueEdges;e1++)\n" -" {\n" -" const float4 edge1 = uniqueEdgesB[hullB->m_uniqueEdgesOffset+e1];\n" -" float4 edge1World = qtRotate(ornB,edge1);\n" -" float4 crossje = cross3(edge0World,edge1World);\n" -" curEdgeEdge++;\n" -" if(!IsAlmostZero(crossje))\n" -" {\n" -" crossje = normalize3(crossje);\n" -" if (dot3F4(DeltaC2,crossje)<0)\n" -" crossje *= -1.f;\n" -" float dist;\n" -" bool result = true;\n" -" {\n" -" float Min0,Max0;\n" -" float Min1,Max1;\n" -" projectLocal(hullA,posA,ornA,&crossje,verticesA, &Min0, &Max0);\n" -" project(hullB,posB,ornB,&crossje,verticesB, &Min1, &Max1);\n" -" \n" -" if(Max00.0f)\n" -" {\n" -" *sep = -(*sep);\n" -" }\n" -" return true;\n" -"}\n" -"inline bool TestSepAxis(__global const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB, \n" -" const float4 posA,const float4 ornA,\n" -" const float4 posB,const float4 ornB,\n" -" float4* sep_axis, __global const float4* vertices,float* depth)\n" -"{\n" -" float Min0,Max0;\n" -" float Min1,Max1;\n" -" project(hullA,posA,ornA,sep_axis,vertices, &Min0, &Max0);\n" -" project(hullB,posB,ornB, sep_axis,vertices, &Min1, &Max1);\n" -" if(Max0m_numFaces;\n" -" // Test normals from hullA\n" -" for(int i=0;im_faceOffset+i].m_plane;\n" -" float4 faceANormalWS = qtRotate(ornA,normal);\n" -" \n" -" if (dot3F4(DeltaC2,faceANormalWS)<0)\n" -" faceANormalWS*=-1.f;\n" -" \n" -" curPlaneTests++;\n" -" \n" -" float d;\n" -" if(!TestSepAxis( hullA, hullB, posA,ornA,posB,ornB,&faceANormalWS, vertices,&d))\n" -" return false;\n" -" \n" -" if(d<*dmin)\n" -" {\n" -" *dmin = d;\n" -" *sep = faceANormalWS;\n" -" }\n" -" }\n" -" }\n" -" if((dot3F4(-DeltaC2,*sep))>0.0f)\n" -" {\n" -" *sep = -(*sep);\n" -" }\n" -" \n" -" return true;\n" -"}\n" -"bool findSeparatingAxisUnitSphere( __global const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB, \n" -" const float4 posA1,\n" -" const float4 ornA,\n" -" const float4 posB1,\n" -" const float4 ornB,\n" -" const float4 DeltaC2,\n" -" __global const float4* vertices,\n" -" __global const float4* unitSphereDirections,\n" -" int numUnitSphereDirections,\n" -" float4* sep,\n" -" float* dmin)\n" -"{\n" -" \n" -" float4 posA = posA1;\n" -" posA.w = 0.f;\n" -" float4 posB = posB1;\n" -" posB.w = 0.f;\n" -" int curPlaneTests=0;\n" -" int curEdgeEdge = 0;\n" -" // Test unit sphere directions\n" -" for (int i=0;i0)\n" -" crossje *= -1.f;\n" -" {\n" -" float dist;\n" -" bool result = true;\n" -" float Min0,Max0;\n" -" float Min1,Max1;\n" -" project(hullA,posA,ornA,&crossje,vertices, &Min0, &Max0);\n" -" project(hullB,posB,ornB,&crossje,vertices, &Min1, &Max1);\n" -" \n" -" if(Max00.0f)\n" -" {\n" -" *sep = -(*sep);\n" -" }\n" -" return true;\n" -"}\n" -"bool findSeparatingAxisEdgeEdge( __global const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB, \n" -" const float4 posA1,\n" -" const float4 ornA,\n" -" const float4 posB1,\n" -" const float4 ornB,\n" -" const float4 DeltaC2,\n" -" __global const float4* vertices, \n" -" __global const float4* uniqueEdges, \n" -" __global const btGpuFace* faces,\n" -" __global const int* indices,\n" -" float4* sep,\n" -" float* dmin)\n" -"{\n" -" \n" -" float4 posA = posA1;\n" -" posA.w = 0.f;\n" -" float4 posB = posB1;\n" -" posB.w = 0.f;\n" -" int curPlaneTests=0;\n" -" int curEdgeEdge = 0;\n" -" // Test edges\n" -" for(int e0=0;e0m_numUniqueEdges;e0++)\n" -" {\n" -" const float4 edge0 = uniqueEdges[hullA->m_uniqueEdgesOffset+e0];\n" -" float4 edge0World = qtRotate(ornA,edge0);\n" -" for(int e1=0;e1m_numUniqueEdges;e1++)\n" -" {\n" -" const float4 edge1 = uniqueEdges[hullB->m_uniqueEdgesOffset+e1];\n" -" float4 edge1World = qtRotate(ornB,edge1);\n" -" float4 crossje = cross3(edge0World,edge1World);\n" -" curEdgeEdge++;\n" -" if(!IsAlmostZero(crossje))\n" -" {\n" -" crossje = normalize3(crossje);\n" -" if (dot3F4(DeltaC2,crossje)<0)\n" -" crossje*=-1.f;\n" -" \n" -" float dist;\n" -" bool result = true;\n" -" {\n" -" float Min0,Max0;\n" -" float Min1,Max1;\n" -" project(hullA,posA,ornA,&crossje,vertices, &Min0, &Max0);\n" -" project(hullB,posB,ornB,&crossje,vertices, &Min1, &Max1);\n" -" \n" -" if(Max00.0f)\n" -" {\n" -" *sep = -(*sep);\n" -" }\n" -" return true;\n" -"}\n" -"// work-in-progress\n" -"__kernel void processCompoundPairsKernel( __global const int4* gpuCompoundPairs,\n" -" __global const BodyData* rigidBodies, \n" -" __global const btCollidableGpu* collidables,\n" -" __global const ConvexPolyhedronCL* convexShapes, \n" -" __global const float4* vertices,\n" -" __global const float4* uniqueEdges,\n" -" __global const btGpuFace* faces,\n" -" __global const int* indices,\n" -" __global btAabbCL* aabbs,\n" -" __global const btGpuChildShape* gpuChildShapes,\n" -" __global volatile float4* gpuCompoundSepNormalsOut,\n" -" __global volatile int* gpuHasCompoundSepNormalsOut,\n" -" int numCompoundPairs\n" -" )\n" -"{\n" -" int i = get_global_id(0);\n" -" if (i= 0)\n" -" {\n" -" collidableIndexA = gpuChildShapes[childShapeIndexA].m_shapeIndex;\n" -" float4 childPosA = gpuChildShapes[childShapeIndexA].m_childPosition;\n" -" float4 childOrnA = gpuChildShapes[childShapeIndexA].m_childOrientation;\n" -" float4 newPosA = qtRotate(ornA,childPosA)+posA;\n" -" float4 newOrnA = qtMul(ornA,childOrnA);\n" -" posA = newPosA;\n" -" ornA = newOrnA;\n" -" } else\n" -" {\n" -" collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;\n" -" }\n" -" \n" -" if (childShapeIndexB>=0)\n" -" {\n" -" collidableIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex;\n" -" float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition;\n" -" float4 childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation;\n" -" float4 newPosB = transform(&childPosB,&posB,&ornB);\n" -" float4 newOrnB = qtMul(ornB,childOrnB);\n" -" posB = newPosB;\n" -" ornB = newOrnB;\n" -" } else\n" -" {\n" -" collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx; \n" -" }\n" -" \n" -" gpuHasCompoundSepNormalsOut[i] = 0;\n" -" \n" -" int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;\n" -" int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;\n" -" \n" -" int shapeTypeA = collidables[collidableIndexA].m_shapeType;\n" -" int shapeTypeB = collidables[collidableIndexB].m_shapeType;\n" -" \n" -" if ((shapeTypeA != SHAPE_CONVEX_HULL) || (shapeTypeB != SHAPE_CONVEX_HULL))\n" -" {\n" -" return;\n" -" }\n" -" int hasSeparatingAxis = 5;\n" -" \n" -" int numFacesA = convexShapes[shapeIndexA].m_numFaces;\n" -" float dmin = FLT_MAX;\n" -" posA.w = 0.f;\n" -" posB.w = 0.f;\n" -" float4 c0local = convexShapes[shapeIndexA].m_localCenter;\n" -" float4 c0 = transform(&c0local, &posA, &ornA);\n" -" float4 c1local = convexShapes[shapeIndexB].m_localCenter;\n" -" float4 c1 = transform(&c1local,&posB,&ornB);\n" -" const float4 DeltaC2 = c0 - c1;\n" -" float4 sepNormal = make_float4(1,0,0,0);\n" -" bool sepA = findSeparatingAxis( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,posB,ornB,DeltaC2,vertices,uniqueEdges,faces,indices,&sepNormal,&dmin);\n" -" hasSeparatingAxis = 4;\n" -" if (!sepA)\n" -" {\n" -" hasSeparatingAxis = 0;\n" -" } else\n" -" {\n" -" bool sepB = findSeparatingAxis( &convexShapes[shapeIndexB],&convexShapes[shapeIndexA],posB,ornB,posA,ornA,DeltaC2,vertices,uniqueEdges,faces,indices,&sepNormal,&dmin);\n" -" if (!sepB)\n" -" {\n" -" hasSeparatingAxis = 0;\n" -" } else//(!sepB)\n" -" {\n" -" bool sepEE = findSeparatingAxisEdgeEdge( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,posB,ornB,DeltaC2,vertices,uniqueEdges,faces,indices,&sepNormal,&dmin);\n" -" if (sepEE)\n" -" {\n" -" gpuCompoundSepNormalsOut[i] = sepNormal;//fastNormalize4(sepNormal);\n" -" gpuHasCompoundSepNormalsOut[i] = 1;\n" -" }//sepEE\n" -" }//(!sepB)\n" -" }//(!sepA)\n" -" \n" -" \n" -" }\n" -" \n" -"}\n" -"inline b3Float4 MyUnQuantize(const unsigned short* vecIn, b3Float4 quantization, b3Float4 bvhAabbMin)\n" -"{\n" -" b3Float4 vecOut;\n" -" vecOut = b3MakeFloat4(\n" -" (float)(vecIn[0]) / (quantization.x),\n" -" (float)(vecIn[1]) / (quantization.y),\n" -" (float)(vecIn[2]) / (quantization.z),\n" -" 0.f);\n" -" vecOut += bvhAabbMin;\n" -" return vecOut;\n" -"}\n" -"inline b3Float4 MyUnQuantizeGlobal(__global const unsigned short* vecIn, b3Float4 quantization, b3Float4 bvhAabbMin)\n" -"{\n" -" b3Float4 vecOut;\n" -" vecOut = b3MakeFloat4(\n" -" (float)(vecIn[0]) / (quantization.x),\n" -" (float)(vecIn[1]) / (quantization.y),\n" -" (float)(vecIn[2]) / (quantization.z),\n" -" 0.f);\n" -" vecOut += bvhAabbMin;\n" -" return vecOut;\n" -"}\n" -"// work-in-progress\n" -"__kernel void findCompoundPairsKernel( __global const int4* pairs, \n" -" __global const BodyData* rigidBodies, \n" -" __global const btCollidableGpu* collidables,\n" -" __global const ConvexPolyhedronCL* convexShapes, \n" -" __global const float4* vertices,\n" -" __global const float4* uniqueEdges,\n" -" __global const btGpuFace* faces,\n" -" __global const int* indices,\n" -" __global b3Aabb_t* aabbLocalSpace,\n" -" __global const btGpuChildShape* gpuChildShapes,\n" -" __global volatile int4* gpuCompoundPairsOut,\n" -" __global volatile int* numCompoundPairsOut,\n" -" __global const b3BvhSubtreeInfo* subtrees,\n" -" __global const b3QuantizedBvhNode* quantizedNodes,\n" -" __global const b3BvhInfo* bvhInfos,\n" -" int numPairs,\n" -" int maxNumCompoundPairsCapacity\n" -" )\n" -"{\n" -" int i = get_global_id(0);\n" -" if (imaxStackDepth && !(isLeafA && isLeafB))\n" -" {\n" -" //printf(\"Error: traversal exceeded maxStackDepth\");\n" -" continue;\n" -" }\n" -" if(isInternalA)\n" -" {\n" -" int nodeAleftChild = node.x+1;\n" -" bool isNodeALeftChildLeaf = isLeafNodeGlobal(&quantizedNodes[node.x+1]);\n" -" int nodeArightChild = isNodeALeftChildLeaf? node.x+2 : node.x+1 + getEscapeIndexGlobal(&quantizedNodes[node.x+1]);\n" -" if(isInternalB)\n" -" { \n" -" int nodeBleftChild = node.y+1;\n" -" bool isNodeBLeftChildLeaf = isLeafNodeGlobal(&quantizedNodes[node.y+1]);\n" -" int nodeBrightChild = isNodeBLeftChildLeaf? node.y+2 : node.y+1 + getEscapeIndexGlobal(&quantizedNodes[node.y+1]);\n" -" nodeStack[depth++] = b3MakeInt2(nodeAleftChild, nodeBleftChild);\n" -" nodeStack[depth++] = b3MakeInt2(nodeArightChild, nodeBleftChild);\n" -" nodeStack[depth++] = b3MakeInt2(nodeAleftChild, nodeBrightChild);\n" -" nodeStack[depth++] = b3MakeInt2(nodeArightChild, nodeBrightChild);\n" -" }\n" -" else\n" -" {\n" -" nodeStack[depth++] = b3MakeInt2(nodeAleftChild,node.y);\n" -" nodeStack[depth++] = b3MakeInt2(nodeArightChild,node.y);\n" -" }\n" -" }\n" -" else\n" -" {\n" -" if(isInternalB)\n" -" {\n" -" int nodeBleftChild = node.y+1;\n" -" bool isNodeBLeftChildLeaf = isLeafNodeGlobal(&quantizedNodes[node.y+1]);\n" -" int nodeBrightChild = isNodeBLeftChildLeaf? node.y+2 : node.y+1 + getEscapeIndexGlobal(&quantizedNodes[node.y+1]);\n" -" nodeStack[depth++] = b3MakeInt2(node.x,nodeBleftChild);\n" -" nodeStack[depth++] = b3MakeInt2(node.x,nodeBrightChild);\n" -" }\n" -" else\n" -" {\n" -" int compoundPairIdx = atomic_inc(numCompoundPairsOut);\n" -" if (compoundPairIdxm_numFaces;face++)\n" -" {\n" -" const float4 Normal = make_float4(facesB[hullB->m_faceOffset+face].m_plane.x,\n" -" facesB[hullB->m_faceOffset+face].m_plane.y, facesB[hullB->m_faceOffset+face].m_plane.z,0.f);\n" -" const float4 WorldNormal = qtRotate(ornB, Normal);\n" -" float d = dot3F4(WorldNormal,separatingNormal);\n" -" if (d > dmax)\n" -" {\n" -" dmax = d;\n" -" closestFaceB = face;\n" -" }\n" -" }\n" -" }\n" -" \n" -" {\n" -" const btGpuFace polyB = facesB[hullB->m_faceOffset+closestFaceB];\n" -" int numVertices = polyB.m_numIndices;\n" -" if (numVertices>capacityWorldVerts)\n" -" numVertices = capacityWorldVerts;\n" -" \n" -" for(int e0=0;e0m_vertexOffset+indicesB[polyB.m_indexOffset+e0]];\n" -" worldVertsB1[pairIndex*capacityWorldVerts+numWorldVertsB1++] = transform(&b,&posB,&ornB);\n" -" }\n" -" }\n" -" }\n" -" \n" -" int closestFaceA=0;\n" -" {\n" -" float dmin = FLT_MAX;\n" -" for(int face=0;facem_numFaces;face++)\n" -" {\n" -" const float4 Normal = make_float4(\n" -" facesA[hullA->m_faceOffset+face].m_plane.x,\n" -" facesA[hullA->m_faceOffset+face].m_plane.y,\n" -" facesA[hullA->m_faceOffset+face].m_plane.z,\n" -" 0.f);\n" -" const float4 faceANormalWS = qtRotate(ornA,Normal);\n" -" \n" -" float d = dot3F4(faceANormalWS,separatingNormal);\n" -" if (d < dmin)\n" -" {\n" -" dmin = d;\n" -" closestFaceA = face;\n" -" worldNormalsA1[pairIndex] = faceANormalWS;\n" -" }\n" -" }\n" -" }\n" -" \n" -" int numVerticesA = facesA[hullA->m_faceOffset+closestFaceA].m_numIndices;\n" -" if (numVerticesA>capacityWorldVerts)\n" -" numVerticesA = capacityWorldVerts;\n" -" \n" -" for(int e0=0;e0m_vertexOffset+indicesA[facesA[hullA->m_faceOffset+closestFaceA].m_indexOffset+e0]];\n" -" worldVertsA1[pairIndex*capacityWorldVerts+e0] = transform(&a, &posA,&ornA);\n" -" }\n" -" }\n" -" \n" -" clippingFaces[pairIndex].x = closestFaceA;\n" -" clippingFaces[pairIndex].y = closestFaceB;\n" -" clippingFaces[pairIndex].z = numVerticesA;\n" -" clippingFaces[pairIndex].w = numWorldVertsB1;\n" -" \n" -" \n" -" return numContactsOut;\n" -"}\n" -"// work-in-progress\n" -"__kernel void findConcaveSeparatingAxisKernel( __global int4* concavePairs,\n" -" __global const BodyData* rigidBodies,\n" -" __global const btCollidableGpu* collidables,\n" -" __global const ConvexPolyhedronCL* convexShapes, \n" -" __global const float4* vertices,\n" -" __global const float4* uniqueEdges,\n" -" __global const btGpuFace* faces,\n" -" __global const int* indices,\n" -" __global const btGpuChildShape* gpuChildShapes,\n" -" __global btAabbCL* aabbs,\n" -" __global float4* concaveSeparatingNormalsOut,\n" -" __global int* concaveHasSeparatingNormals,\n" -" __global int4* clippingFacesOut,\n" -" __global float4* worldVertsA1GPU,\n" -" __global float4* worldNormalsAGPU,\n" -" __global float4* worldVertsB1GPU,\n" -" int vertexFaceCapacity,\n" -" int numConcavePairs\n" -" )\n" -"{\n" -" int i = get_global_id(0);\n" -" if (i>=numConcavePairs)\n" -" return;\n" -" concaveHasSeparatingNormals[i] = 0;\n" -" int pairIdx = i;\n" -" int bodyIndexA = concavePairs[i].x;\n" -" int bodyIndexB = concavePairs[i].y;\n" -" int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;\n" -" int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;\n" -" int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;\n" -" int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;\n" -" if (collidables[collidableIndexB].m_shapeType!=SHAPE_CONVEX_HULL&&\n" -" collidables[collidableIndexB].m_shapeType!=SHAPE_COMPOUND_OF_CONVEX_HULLS)\n" -" {\n" -" concavePairs[pairIdx].w = -1;\n" -" return;\n" -" }\n" -" int numFacesA = convexShapes[shapeIndexA].m_numFaces;\n" -" int numActualConcaveConvexTests = 0;\n" -" \n" -" int f = concavePairs[i].z;\n" -" \n" -" bool overlap = false;\n" -" \n" -" ConvexPolyhedronCL convexPolyhedronA;\n" -" //add 3 vertices of the triangle\n" -" convexPolyhedronA.m_numVertices = 3;\n" -" convexPolyhedronA.m_vertexOffset = 0;\n" -" float4 localCenter = make_float4(0.f,0.f,0.f,0.f);\n" -" btGpuFace face = faces[convexShapes[shapeIndexA].m_faceOffset+f];\n" -" float4 triMinAabb, triMaxAabb;\n" -" btAabbCL triAabb;\n" -" triAabb.m_min = make_float4(1e30f,1e30f,1e30f,0.f);\n" -" triAabb.m_max = make_float4(-1e30f,-1e30f,-1e30f,0.f);\n" -" \n" -" float4 verticesA[3];\n" -" for (int i=0;i<3;i++)\n" -" {\n" -" int index = indices[face.m_indexOffset+i];\n" -" float4 vert = vertices[convexShapes[shapeIndexA].m_vertexOffset+index];\n" -" verticesA[i] = vert;\n" -" localCenter += vert;\n" -" \n" -" triAabb.m_min = min(triAabb.m_min,vert); \n" -" triAabb.m_max = max(triAabb.m_max,vert); \n" -" }\n" -" overlap = true;\n" -" overlap = (triAabb.m_min.x > aabbs[bodyIndexB].m_max.x || triAabb.m_max.x < aabbs[bodyIndexB].m_min.x) ? false : overlap;\n" -" overlap = (triAabb.m_min.z > aabbs[bodyIndexB].m_max.z || triAabb.m_max.z < aabbs[bodyIndexB].m_min.z) ? false : overlap;\n" -" overlap = (triAabb.m_min.y > aabbs[bodyIndexB].m_max.y || triAabb.m_max.y < aabbs[bodyIndexB].m_min.y) ? false : overlap;\n" -" \n" -" if (overlap)\n" -" {\n" -" float dmin = FLT_MAX;\n" -" int hasSeparatingAxis=5;\n" -" float4 sepAxis=make_float4(1,2,3,4);\n" -" int localCC=0;\n" -" numActualConcaveConvexTests++;\n" -" //a triangle has 3 unique edges\n" -" convexPolyhedronA.m_numUniqueEdges = 3;\n" -" convexPolyhedronA.m_uniqueEdgesOffset = 0;\n" -" float4 uniqueEdgesA[3];\n" -" \n" -" uniqueEdgesA[0] = (verticesA[1]-verticesA[0]);\n" -" uniqueEdgesA[1] = (verticesA[2]-verticesA[1]);\n" -" uniqueEdgesA[2] = (verticesA[0]-verticesA[2]);\n" -" convexPolyhedronA.m_faceOffset = 0;\n" -" \n" -" float4 normal = make_float4(face.m_plane.x,face.m_plane.y,face.m_plane.z,0.f);\n" -" \n" -" btGpuFace facesA[TRIANGLE_NUM_CONVEX_FACES];\n" -" int indicesA[3+3+2+2+2];\n" -" int curUsedIndices=0;\n" -" int fidx=0;\n" -" //front size of triangle\n" -" {\n" -" facesA[fidx].m_indexOffset=curUsedIndices;\n" -" indicesA[0] = 0;\n" -" indicesA[1] = 1;\n" -" indicesA[2] = 2;\n" -" curUsedIndices+=3;\n" -" float c = face.m_plane.w;\n" -" facesA[fidx].m_plane.x = normal.x;\n" -" facesA[fidx].m_plane.y = normal.y;\n" -" facesA[fidx].m_plane.z = normal.z;\n" -" facesA[fidx].m_plane.w = c;\n" -" facesA[fidx].m_numIndices=3;\n" -" }\n" -" fidx++;\n" -" //back size of triangle\n" -" {\n" -" facesA[fidx].m_indexOffset=curUsedIndices;\n" -" indicesA[3]=2;\n" -" indicesA[4]=1;\n" -" indicesA[5]=0;\n" -" curUsedIndices+=3;\n" -" float c = dot(normal,verticesA[0]);\n" -" float c1 = -face.m_plane.w;\n" -" facesA[fidx].m_plane.x = -normal.x;\n" -" facesA[fidx].m_plane.y = -normal.y;\n" -" facesA[fidx].m_plane.z = -normal.z;\n" -" facesA[fidx].m_plane.w = c;\n" -" facesA[fidx].m_numIndices=3;\n" -" }\n" -" fidx++;\n" -" bool addEdgePlanes = true;\n" -" if (addEdgePlanes)\n" -" {\n" -" int numVertices=3;\n" -" int prevVertex = numVertices-1;\n" -" for (int i=0;im_escapeIndexOrTriangleIndex&~(y));\n" + "}\n" + "int getTriangleIndexGlobal(__global const b3QuantizedBvhNode* rootNode)\n" + "{\n" + " unsigned int x=0;\n" + " unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS);\n" + " // Get only the lower bits where the triangle index is stored\n" + " return (rootNode->m_escapeIndexOrTriangleIndex&~(y));\n" + "}\n" + "int isLeafNode(const b3QuantizedBvhNode* rootNode)\n" + "{\n" + " //skipindex is negative (internal node), triangleindex >=0 (leafnode)\n" + " return (rootNode->m_escapeIndexOrTriangleIndex >= 0)? 1 : 0;\n" + "}\n" + "int isLeafNodeGlobal(__global const b3QuantizedBvhNode* rootNode)\n" + "{\n" + " //skipindex is negative (internal node), triangleindex >=0 (leafnode)\n" + " return (rootNode->m_escapeIndexOrTriangleIndex >= 0)? 1 : 0;\n" + "}\n" + " \n" + "int getEscapeIndex(const b3QuantizedBvhNode* rootNode)\n" + "{\n" + " return -rootNode->m_escapeIndexOrTriangleIndex;\n" + "}\n" + "int getEscapeIndexGlobal(__global const b3QuantizedBvhNode* rootNode)\n" + "{\n" + " return -rootNode->m_escapeIndexOrTriangleIndex;\n" + "}\n" + "typedef struct\n" + "{\n" + " //12 bytes\n" + " unsigned short int m_quantizedAabbMin[3];\n" + " unsigned short int m_quantizedAabbMax[3];\n" + " //4 bytes, points to the root of the subtree\n" + " int m_rootNodeIndex;\n" + " //4 bytes\n" + " int m_subtreeSize;\n" + " int m_padding[3];\n" + "} b3BvhSubtreeInfo;\n" + "typedef struct\n" + "{\n" + " float4 m_childPosition;\n" + " float4 m_childOrientation;\n" + " int m_shapeIndex;\n" + " int m_unused0;\n" + " int m_unused1;\n" + " int m_unused2;\n" + "} btGpuChildShape;\n" + "typedef struct\n" + "{\n" + " float4 m_pos;\n" + " float4 m_quat;\n" + " float4 m_linVel;\n" + " float4 m_angVel;\n" + " u32 m_collidableIdx;\n" + " float m_invMass;\n" + " float m_restituitionCoeff;\n" + " float m_frictionCoeff;\n" + "} BodyData;\n" + "typedef struct \n" + "{\n" + " float4 m_localCenter;\n" + " float4 m_extents;\n" + " float4 mC;\n" + " float4 mE;\n" + " \n" + " float m_radius;\n" + " int m_faceOffset;\n" + " int m_numFaces;\n" + " int m_numVertices;\n" + " int m_vertexOffset;\n" + " int m_uniqueEdgesOffset;\n" + " int m_numUniqueEdges;\n" + " int m_unused;\n" + "} ConvexPolyhedronCL;\n" + "typedef struct \n" + "{\n" + " union\n" + " {\n" + " float4 m_min;\n" + " float m_minElems[4];\n" + " int m_minIndices[4];\n" + " };\n" + " union\n" + " {\n" + " float4 m_max;\n" + " float m_maxElems[4];\n" + " int m_maxIndices[4];\n" + " };\n" + "} btAabbCL;\n" + "#ifndef B3_AABB_H\n" + "#define B3_AABB_H\n" + "#ifndef B3_FLOAT4_H\n" + "#define B3_FLOAT4_H\n" + "#ifndef B3_PLATFORM_DEFINITIONS_H\n" + "#define B3_PLATFORM_DEFINITIONS_H\n" + "struct MyTest\n" + "{\n" + " int bla;\n" + "};\n" + "#ifdef __cplusplus\n" + "#else\n" + "//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n" + "#define B3_LARGE_FLOAT 1e18f\n" + "#define B3_INFINITY 1e18f\n" + "#define b3Assert(a)\n" + "#define b3ConstArray(a) __global const a*\n" + "#define b3AtomicInc atomic_inc\n" + "#define b3AtomicAdd atomic_add\n" + "#define b3Fabs fabs\n" + "#define b3Sqrt native_sqrt\n" + "#define b3Sin native_sin\n" + "#define b3Cos native_cos\n" + "#define B3_STATIC\n" + "#endif\n" + "#endif\n" + "#ifdef __cplusplus\n" + "#else\n" + " typedef float4 b3Float4;\n" + " #define b3Float4ConstArg const b3Float4\n" + " #define b3MakeFloat4 (float4)\n" + " float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" + " {\n" + " float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" + " float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" + " return dot(a1, b1);\n" + " }\n" + " b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" + " {\n" + " float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" + " float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" + " return cross(a1, b1);\n" + " }\n" + " #define b3MinFloat4 min\n" + " #define b3MaxFloat4 max\n" + " #define b3Normalized(a) normalize(a)\n" + "#endif \n" + " \n" + "inline bool b3IsAlmostZero(b3Float4ConstArg v)\n" + "{\n" + " if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" + " return false;\n" + " return true;\n" + "}\n" + "inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" + "{\n" + " float maxDot = -B3_INFINITY;\n" + " int i = 0;\n" + " int ptIndex = -1;\n" + " for( i = 0; i < vecLen; i++ )\n" + " {\n" + " float dot = b3Dot3F4(vecArray[i],vec);\n" + " \n" + " if( dot > maxDot )\n" + " {\n" + " maxDot = dot;\n" + " ptIndex = i;\n" + " }\n" + " }\n" + " b3Assert(ptIndex>=0);\n" + " if (ptIndex<0)\n" + " {\n" + " ptIndex = 0;\n" + " }\n" + " *dotOut = maxDot;\n" + " return ptIndex;\n" + "}\n" + "#endif //B3_FLOAT4_H\n" + "#ifndef B3_MAT3x3_H\n" + "#define B3_MAT3x3_H\n" + "#ifndef B3_QUAT_H\n" + "#define B3_QUAT_H\n" + "#ifndef B3_PLATFORM_DEFINITIONS_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif\n" + "#endif\n" + "#ifndef B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + " typedef float4 b3Quat;\n" + " #define b3QuatConstArg const b3Quat\n" + " \n" + " \n" + "inline float4 b3FastNormalize4(float4 v)\n" + "{\n" + " v = (float4)(v.xyz,0.f);\n" + " return fast_normalize(v);\n" + "}\n" + " \n" + "inline b3Quat b3QuatMul(b3Quat a, b3Quat b);\n" + "inline b3Quat b3QuatNormalized(b3QuatConstArg in);\n" + "inline b3Quat b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec);\n" + "inline b3Quat b3QuatInvert(b3QuatConstArg q);\n" + "inline b3Quat b3QuatInverse(b3QuatConstArg q);\n" + "inline b3Quat b3QuatMul(b3QuatConstArg a, b3QuatConstArg b)\n" + "{\n" + " b3Quat ans;\n" + " ans = b3Cross3( a, b );\n" + " ans += a.w*b+b.w*a;\n" + "// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" + " ans.w = a.w*b.w - b3Dot3F4(a, b);\n" + " return ans;\n" + "}\n" + "inline b3Quat b3QuatNormalized(b3QuatConstArg in)\n" + "{\n" + " b3Quat q;\n" + " q=in;\n" + " //return b3FastNormalize4(in);\n" + " float len = native_sqrt(dot(q, q));\n" + " if(len > 0.f)\n" + " {\n" + " q *= 1.f / len;\n" + " }\n" + " else\n" + " {\n" + " q.x = q.y = q.z = 0.f;\n" + " q.w = 1.f;\n" + " }\n" + " return q;\n" + "}\n" + "inline float4 b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" + "{\n" + " b3Quat qInv = b3QuatInvert( q );\n" + " float4 vcpy = vec;\n" + " vcpy.w = 0.f;\n" + " float4 out = b3QuatMul(b3QuatMul(q,vcpy),qInv);\n" + " return out;\n" + "}\n" + "inline b3Quat b3QuatInverse(b3QuatConstArg q)\n" + "{\n" + " return (b3Quat)(-q.xyz, q.w);\n" + "}\n" + "inline b3Quat b3QuatInvert(b3QuatConstArg q)\n" + "{\n" + " return (b3Quat)(-q.xyz, q.w);\n" + "}\n" + "inline float4 b3QuatInvRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" + "{\n" + " return b3QuatRotate( b3QuatInvert( q ), vec );\n" + "}\n" + "inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)\n" + "{\n" + " return b3QuatRotate( orientation, point ) + (translation);\n" + "}\n" + " \n" + "#endif \n" + "#endif //B3_QUAT_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "typedef struct\n" + "{\n" + " b3Float4 m_row[3];\n" + "}b3Mat3x3;\n" + "#define b3Mat3x3ConstArg const b3Mat3x3\n" + "#define b3GetRow(m,row) (m.m_row[row])\n" + "inline b3Mat3x3 b3QuatGetRotationMatrix(b3Quat quat)\n" + "{\n" + " b3Float4 quat2 = (b3Float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f);\n" + " b3Mat3x3 out;\n" + " out.m_row[0].x=1-2*quat2.y-2*quat2.z;\n" + " out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z;\n" + " out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y;\n" + " out.m_row[0].w = 0.f;\n" + " out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z;\n" + " out.m_row[1].y=1-2*quat2.x-2*quat2.z;\n" + " out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x;\n" + " out.m_row[1].w = 0.f;\n" + " out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y;\n" + " out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x;\n" + " out.m_row[2].z=1-2*quat2.x-2*quat2.y;\n" + " out.m_row[2].w = 0.f;\n" + " return out;\n" + "}\n" + "inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg matIn)\n" + "{\n" + " b3Mat3x3 out;\n" + " out.m_row[0] = fabs(matIn.m_row[0]);\n" + " out.m_row[1] = fabs(matIn.m_row[1]);\n" + " out.m_row[2] = fabs(matIn.m_row[2]);\n" + " return out;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtZero();\n" + "__inline\n" + "b3Mat3x3 mtIdentity();\n" + "__inline\n" + "b3Mat3x3 mtTranspose(b3Mat3x3 m);\n" + "__inline\n" + "b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b);\n" + "__inline\n" + "b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b);\n" + "__inline\n" + "b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b);\n" + "__inline\n" + "b3Mat3x3 mtZero()\n" + "{\n" + " b3Mat3x3 m;\n" + " m.m_row[0] = (b3Float4)(0.f);\n" + " m.m_row[1] = (b3Float4)(0.f);\n" + " m.m_row[2] = (b3Float4)(0.f);\n" + " return m;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtIdentity()\n" + "{\n" + " b3Mat3x3 m;\n" + " m.m_row[0] = (b3Float4)(1,0,0,0);\n" + " m.m_row[1] = (b3Float4)(0,1,0,0);\n" + " m.m_row[2] = (b3Float4)(0,0,1,0);\n" + " return m;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtTranspose(b3Mat3x3 m)\n" + "{\n" + " b3Mat3x3 out;\n" + " out.m_row[0] = (b3Float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n" + " out.m_row[1] = (b3Float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n" + " out.m_row[2] = (b3Float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n" + " return out;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b)\n" + "{\n" + " b3Mat3x3 transB;\n" + " transB = mtTranspose( b );\n" + " b3Mat3x3 ans;\n" + " // why this doesn't run when 0ing in the for{}\n" + " a.m_row[0].w = 0.f;\n" + " a.m_row[1].w = 0.f;\n" + " a.m_row[2].w = 0.f;\n" + " for(int i=0; i<3; i++)\n" + " {\n" + "// a.m_row[i].w = 0.f;\n" + " ans.m_row[i].x = b3Dot3F4(a.m_row[i],transB.m_row[0]);\n" + " ans.m_row[i].y = b3Dot3F4(a.m_row[i],transB.m_row[1]);\n" + " ans.m_row[i].z = b3Dot3F4(a.m_row[i],transB.m_row[2]);\n" + " ans.m_row[i].w = 0.f;\n" + " }\n" + " return ans;\n" + "}\n" + "__inline\n" + "b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b)\n" + "{\n" + " b3Float4 ans;\n" + " ans.x = b3Dot3F4( a.m_row[0], b );\n" + " ans.y = b3Dot3F4( a.m_row[1], b );\n" + " ans.z = b3Dot3F4( a.m_row[2], b );\n" + " ans.w = 0.f;\n" + " return ans;\n" + "}\n" + "__inline\n" + "b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b)\n" + "{\n" + " b3Float4 colx = b3MakeFloat4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" + " b3Float4 coly = b3MakeFloat4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" + " b3Float4 colz = b3MakeFloat4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" + " b3Float4 ans;\n" + " ans.x = b3Dot3F4( a, colx );\n" + " ans.y = b3Dot3F4( a, coly );\n" + " ans.z = b3Dot3F4( a, colz );\n" + " return ans;\n" + "}\n" + "#endif\n" + "#endif //B3_MAT3x3_H\n" + "typedef struct b3Aabb b3Aabb_t;\n" + "struct b3Aabb\n" + "{\n" + " union\n" + " {\n" + " float m_min[4];\n" + " b3Float4 m_minVec;\n" + " int m_minIndices[4];\n" + " };\n" + " union\n" + " {\n" + " float m_max[4];\n" + " b3Float4 m_maxVec;\n" + " int m_signedMaxIndices[4];\n" + " };\n" + "};\n" + "inline void b3TransformAabb2(b3Float4ConstArg localAabbMin,b3Float4ConstArg localAabbMax, float margin,\n" + " b3Float4ConstArg pos,\n" + " b3QuatConstArg orn,\n" + " b3Float4* aabbMinOut,b3Float4* aabbMaxOut)\n" + "{\n" + " b3Float4 localHalfExtents = 0.5f*(localAabbMax-localAabbMin);\n" + " localHalfExtents+=b3MakeFloat4(margin,margin,margin,0.f);\n" + " b3Float4 localCenter = 0.5f*(localAabbMax+localAabbMin);\n" + " b3Mat3x3 m;\n" + " m = b3QuatGetRotationMatrix(orn);\n" + " b3Mat3x3 abs_b = b3AbsoluteMat3x3(m);\n" + " b3Float4 center = b3TransformPoint(localCenter,pos,orn);\n" + " \n" + " b3Float4 extent = b3MakeFloat4(b3Dot3F4(localHalfExtents,b3GetRow(abs_b,0)),\n" + " b3Dot3F4(localHalfExtents,b3GetRow(abs_b,1)),\n" + " b3Dot3F4(localHalfExtents,b3GetRow(abs_b,2)),\n" + " 0.f);\n" + " *aabbMinOut = center-extent;\n" + " *aabbMaxOut = center+extent;\n" + "}\n" + "/// conservative test for overlap between two aabbs\n" + "inline bool b3TestAabbAgainstAabb(b3Float4ConstArg aabbMin1,b3Float4ConstArg aabbMax1,\n" + " b3Float4ConstArg aabbMin2, b3Float4ConstArg aabbMax2)\n" + "{\n" + " bool overlap = true;\n" + " overlap = (aabbMin1.x > aabbMax2.x || aabbMax1.x < aabbMin2.x) ? false : overlap;\n" + " overlap = (aabbMin1.z > aabbMax2.z || aabbMax1.z < aabbMin2.z) ? false : overlap;\n" + " overlap = (aabbMin1.y > aabbMax2.y || aabbMax1.y < aabbMin2.y) ? false : overlap;\n" + " return overlap;\n" + "}\n" + "#endif //B3_AABB_H\n" + "/*\n" + "Bullet Continuous Collision Detection and Physics Library\n" + "Copyright (c) 2003-2013 Erwin Coumans http://bulletphysics.org\n" + "This software is provided 'as-is', without any express or implied warranty.\n" + "In no event will the authors be held liable for any damages arising from the use of this software.\n" + "Permission is granted to anyone to use this software for any purpose,\n" + "including commercial applications, and to alter it and redistribute it freely,\n" + "subject to the following restrictions:\n" + "1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" + "2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" + "3. This notice may not be removed or altered from any source distribution.\n" + "*/\n" + "#ifndef B3_INT2_H\n" + "#define B3_INT2_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#define b3UnsignedInt2 uint2\n" + "#define b3Int2 int2\n" + "#define b3MakeInt2 (int2)\n" + "#endif //__cplusplus\n" + "#endif\n" + "typedef struct\n" + "{\n" + " float4 m_plane;\n" + " int m_indexOffset;\n" + " int m_numIndices;\n" + "} btGpuFace;\n" + "#define make_float4 (float4)\n" + "__inline\n" + "float4 cross3(float4 a, float4 b)\n" + "{\n" + " return cross(a,b);\n" + " \n" + "// float4 a1 = make_float4(a.xyz,0.f);\n" + "// float4 b1 = make_float4(b.xyz,0.f);\n" + "// return cross(a1,b1);\n" + "//float4 c = make_float4(a.y*b.z - a.z*b.y,a.z*b.x - a.x*b.z,a.x*b.y - a.y*b.x,0.f);\n" + " \n" + " // float4 c = make_float4(a.y*b.z - a.z*b.y,1.f,a.x*b.y - a.y*b.x,0.f);\n" + " \n" + " //return c;\n" + "}\n" + "__inline\n" + "float dot3F4(float4 a, float4 b)\n" + "{\n" + " float4 a1 = make_float4(a.xyz,0.f);\n" + " float4 b1 = make_float4(b.xyz,0.f);\n" + " return dot(a1, b1);\n" + "}\n" + "__inline\n" + "float4 fastNormalize4(float4 v)\n" + "{\n" + " v = make_float4(v.xyz,0.f);\n" + " return fast_normalize(v);\n" + "}\n" + "///////////////////////////////////////\n" + "// Quaternion\n" + "///////////////////////////////////////\n" + "typedef float4 Quaternion;\n" + "__inline\n" + "Quaternion qtMul(Quaternion a, Quaternion b);\n" + "__inline\n" + "Quaternion qtNormalize(Quaternion in);\n" + "__inline\n" + "float4 qtRotate(Quaternion q, float4 vec);\n" + "__inline\n" + "Quaternion qtInvert(Quaternion q);\n" + "__inline\n" + "Quaternion qtMul(Quaternion a, Quaternion b)\n" + "{\n" + " Quaternion ans;\n" + " ans = cross3( a, b );\n" + " ans += a.w*b+b.w*a;\n" + "// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" + " ans.w = a.w*b.w - dot3F4(a, b);\n" + " return ans;\n" + "}\n" + "__inline\n" + "Quaternion qtNormalize(Quaternion in)\n" + "{\n" + " return fastNormalize4(in);\n" + "// in /= length( in );\n" + "// return in;\n" + "}\n" + "__inline\n" + "float4 qtRotate(Quaternion q, float4 vec)\n" + "{\n" + " Quaternion qInv = qtInvert( q );\n" + " float4 vcpy = vec;\n" + " vcpy.w = 0.f;\n" + " float4 out = qtMul(qtMul(q,vcpy),qInv);\n" + " return out;\n" + "}\n" + "__inline\n" + "Quaternion qtInvert(Quaternion q)\n" + "{\n" + " return (Quaternion)(-q.xyz, q.w);\n" + "}\n" + "__inline\n" + "float4 qtInvRotate(const Quaternion q, float4 vec)\n" + "{\n" + " return qtRotate( qtInvert( q ), vec );\n" + "}\n" + "__inline\n" + "float4 transform(const float4* p, const float4* translation, const Quaternion* orientation)\n" + "{\n" + " return qtRotate( *orientation, *p ) + (*translation);\n" + "}\n" + "__inline\n" + "float4 normalize3(const float4 a)\n" + "{\n" + " float4 n = make_float4(a.x, a.y, a.z, 0.f);\n" + " return fastNormalize4( n );\n" + "}\n" + "inline void projectLocal(const ConvexPolyhedronCL* hull, const float4 pos, const float4 orn, \n" + "const float4* dir, const float4* vertices, float* min, float* max)\n" + "{\n" + " min[0] = FLT_MAX;\n" + " max[0] = -FLT_MAX;\n" + " int numVerts = hull->m_numVertices;\n" + " const float4 localDir = qtInvRotate(orn,*dir);\n" + " float offset = dot(pos,*dir);\n" + " for(int i=0;im_vertexOffset+i],localDir);\n" + " if(dp < min[0]) \n" + " min[0] = dp;\n" + " if(dp > max[0]) \n" + " max[0] = dp;\n" + " }\n" + " if(min[0]>max[0])\n" + " {\n" + " float tmp = min[0];\n" + " min[0] = max[0];\n" + " max[0] = tmp;\n" + " }\n" + " min[0] += offset;\n" + " max[0] += offset;\n" + "}\n" + "inline void project(__global const ConvexPolyhedronCL* hull, const float4 pos, const float4 orn, \n" + "const float4* dir, __global const float4* vertices, float* min, float* max)\n" + "{\n" + " min[0] = FLT_MAX;\n" + " max[0] = -FLT_MAX;\n" + " int numVerts = hull->m_numVertices;\n" + " const float4 localDir = qtInvRotate(orn,*dir);\n" + " float offset = dot(pos,*dir);\n" + " for(int i=0;im_vertexOffset+i],localDir);\n" + " if(dp < min[0]) \n" + " min[0] = dp;\n" + " if(dp > max[0]) \n" + " max[0] = dp;\n" + " }\n" + " if(min[0]>max[0])\n" + " {\n" + " float tmp = min[0];\n" + " min[0] = max[0];\n" + " max[0] = tmp;\n" + " }\n" + " min[0] += offset;\n" + " max[0] += offset;\n" + "}\n" + "inline bool TestSepAxisLocalA(const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB, \n" + " const float4 posA,const float4 ornA,\n" + " const float4 posB,const float4 ornB,\n" + " float4* sep_axis, const float4* verticesA, __global const float4* verticesB,float* depth)\n" + "{\n" + " float Min0,Max0;\n" + " float Min1,Max1;\n" + " projectLocal(hullA,posA,ornA,sep_axis,verticesA, &Min0, &Max0);\n" + " project(hullB,posB,ornB, sep_axis,verticesB, &Min1, &Max1);\n" + " if(Max01e-6f || fabs(v.y)>1e-6f || fabs(v.z)>1e-6f)\n" + " return false;\n" + " return true;\n" + "}\n" + "bool findSeparatingAxisLocalA( const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB, \n" + " const float4 posA1,\n" + " const float4 ornA,\n" + " const float4 posB1,\n" + " const float4 ornB,\n" + " const float4 DeltaC2,\n" + " \n" + " const float4* verticesA, \n" + " const float4* uniqueEdgesA, \n" + " const btGpuFace* facesA,\n" + " const int* indicesA,\n" + " __global const float4* verticesB, \n" + " __global const float4* uniqueEdgesB, \n" + " __global const btGpuFace* facesB,\n" + " __global const int* indicesB,\n" + " float4* sep,\n" + " float* dmin)\n" + "{\n" + " \n" + " float4 posA = posA1;\n" + " posA.w = 0.f;\n" + " float4 posB = posB1;\n" + " posB.w = 0.f;\n" + " int curPlaneTests=0;\n" + " {\n" + " int numFacesA = hullA->m_numFaces;\n" + " // Test normals from hullA\n" + " for(int i=0;im_faceOffset+i].m_plane;\n" + " float4 faceANormalWS = qtRotate(ornA,normal);\n" + " if (dot3F4(DeltaC2,faceANormalWS)<0)\n" + " faceANormalWS*=-1.f;\n" + " curPlaneTests++;\n" + " float d;\n" + " if(!TestSepAxisLocalA( hullA, hullB, posA,ornA,posB,ornB,&faceANormalWS, verticesA, verticesB,&d))\n" + " return false;\n" + " if(d<*dmin)\n" + " {\n" + " *dmin = d;\n" + " *sep = faceANormalWS;\n" + " }\n" + " }\n" + " }\n" + " if((dot3F4(-DeltaC2,*sep))>0.0f)\n" + " {\n" + " *sep = -(*sep);\n" + " }\n" + " return true;\n" + "}\n" + "bool findSeparatingAxisLocalB( __global const ConvexPolyhedronCL* hullA, const ConvexPolyhedronCL* hullB, \n" + " const float4 posA1,\n" + " const float4 ornA,\n" + " const float4 posB1,\n" + " const float4 ornB,\n" + " const float4 DeltaC2,\n" + " __global const float4* verticesA, \n" + " __global const float4* uniqueEdgesA, \n" + " __global const btGpuFace* facesA,\n" + " __global const int* indicesA,\n" + " const float4* verticesB,\n" + " const float4* uniqueEdgesB, \n" + " const btGpuFace* facesB,\n" + " const int* indicesB,\n" + " float4* sep,\n" + " float* dmin)\n" + "{\n" + " float4 posA = posA1;\n" + " posA.w = 0.f;\n" + " float4 posB = posB1;\n" + " posB.w = 0.f;\n" + " int curPlaneTests=0;\n" + " {\n" + " int numFacesA = hullA->m_numFaces;\n" + " // Test normals from hullA\n" + " for(int i=0;im_faceOffset+i].m_plane;\n" + " float4 faceANormalWS = qtRotate(ornA,normal);\n" + " if (dot3F4(DeltaC2,faceANormalWS)<0)\n" + " faceANormalWS *= -1.f;\n" + " curPlaneTests++;\n" + " float d;\n" + " if(!TestSepAxisLocalA( hullB, hullA, posB,ornB,posA,ornA, &faceANormalWS, verticesB,verticesA, &d))\n" + " return false;\n" + " if(d<*dmin)\n" + " {\n" + " *dmin = d;\n" + " *sep = faceANormalWS;\n" + " }\n" + " }\n" + " }\n" + " if((dot3F4(-DeltaC2,*sep))>0.0f)\n" + " {\n" + " *sep = -(*sep);\n" + " }\n" + " return true;\n" + "}\n" + "bool findSeparatingAxisEdgeEdgeLocalA( const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB, \n" + " const float4 posA1,\n" + " const float4 ornA,\n" + " const float4 posB1,\n" + " const float4 ornB,\n" + " const float4 DeltaC2,\n" + " const float4* verticesA, \n" + " const float4* uniqueEdgesA, \n" + " const btGpuFace* facesA,\n" + " const int* indicesA,\n" + " __global const float4* verticesB, \n" + " __global const float4* uniqueEdgesB, \n" + " __global const btGpuFace* facesB,\n" + " __global const int* indicesB,\n" + " float4* sep,\n" + " float* dmin)\n" + "{\n" + " float4 posA = posA1;\n" + " posA.w = 0.f;\n" + " float4 posB = posB1;\n" + " posB.w = 0.f;\n" + " int curPlaneTests=0;\n" + " int curEdgeEdge = 0;\n" + " // Test edges\n" + " for(int e0=0;e0m_numUniqueEdges;e0++)\n" + " {\n" + " const float4 edge0 = uniqueEdgesA[hullA->m_uniqueEdgesOffset+e0];\n" + " float4 edge0World = qtRotate(ornA,edge0);\n" + " for(int e1=0;e1m_numUniqueEdges;e1++)\n" + " {\n" + " const float4 edge1 = uniqueEdgesB[hullB->m_uniqueEdgesOffset+e1];\n" + " float4 edge1World = qtRotate(ornB,edge1);\n" + " float4 crossje = cross3(edge0World,edge1World);\n" + " curEdgeEdge++;\n" + " if(!IsAlmostZero(crossje))\n" + " {\n" + " crossje = normalize3(crossje);\n" + " if (dot3F4(DeltaC2,crossje)<0)\n" + " crossje *= -1.f;\n" + " float dist;\n" + " bool result = true;\n" + " {\n" + " float Min0,Max0;\n" + " float Min1,Max1;\n" + " projectLocal(hullA,posA,ornA,&crossje,verticesA, &Min0, &Max0);\n" + " project(hullB,posB,ornB,&crossje,verticesB, &Min1, &Max1);\n" + " \n" + " if(Max00.0f)\n" + " {\n" + " *sep = -(*sep);\n" + " }\n" + " return true;\n" + "}\n" + "inline bool TestSepAxis(__global const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB, \n" + " const float4 posA,const float4 ornA,\n" + " const float4 posB,const float4 ornB,\n" + " float4* sep_axis, __global const float4* vertices,float* depth)\n" + "{\n" + " float Min0,Max0;\n" + " float Min1,Max1;\n" + " project(hullA,posA,ornA,sep_axis,vertices, &Min0, &Max0);\n" + " project(hullB,posB,ornB, sep_axis,vertices, &Min1, &Max1);\n" + " if(Max0m_numFaces;\n" + " // Test normals from hullA\n" + " for(int i=0;im_faceOffset+i].m_plane;\n" + " float4 faceANormalWS = qtRotate(ornA,normal);\n" + " \n" + " if (dot3F4(DeltaC2,faceANormalWS)<0)\n" + " faceANormalWS*=-1.f;\n" + " \n" + " curPlaneTests++;\n" + " \n" + " float d;\n" + " if(!TestSepAxis( hullA, hullB, posA,ornA,posB,ornB,&faceANormalWS, vertices,&d))\n" + " return false;\n" + " \n" + " if(d<*dmin)\n" + " {\n" + " *dmin = d;\n" + " *sep = faceANormalWS;\n" + " }\n" + " }\n" + " }\n" + " if((dot3F4(-DeltaC2,*sep))>0.0f)\n" + " {\n" + " *sep = -(*sep);\n" + " }\n" + " \n" + " return true;\n" + "}\n" + "bool findSeparatingAxisUnitSphere( __global const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB, \n" + " const float4 posA1,\n" + " const float4 ornA,\n" + " const float4 posB1,\n" + " const float4 ornB,\n" + " const float4 DeltaC2,\n" + " __global const float4* vertices,\n" + " __global const float4* unitSphereDirections,\n" + " int numUnitSphereDirections,\n" + " float4* sep,\n" + " float* dmin)\n" + "{\n" + " \n" + " float4 posA = posA1;\n" + " posA.w = 0.f;\n" + " float4 posB = posB1;\n" + " posB.w = 0.f;\n" + " int curPlaneTests=0;\n" + " int curEdgeEdge = 0;\n" + " // Test unit sphere directions\n" + " for (int i=0;i0)\n" + " crossje *= -1.f;\n" + " {\n" + " float dist;\n" + " bool result = true;\n" + " float Min0,Max0;\n" + " float Min1,Max1;\n" + " project(hullA,posA,ornA,&crossje,vertices, &Min0, &Max0);\n" + " project(hullB,posB,ornB,&crossje,vertices, &Min1, &Max1);\n" + " \n" + " if(Max00.0f)\n" + " {\n" + " *sep = -(*sep);\n" + " }\n" + " return true;\n" + "}\n" + "bool findSeparatingAxisEdgeEdge( __global const ConvexPolyhedronCL* hullA, __global const ConvexPolyhedronCL* hullB, \n" + " const float4 posA1,\n" + " const float4 ornA,\n" + " const float4 posB1,\n" + " const float4 ornB,\n" + " const float4 DeltaC2,\n" + " __global const float4* vertices, \n" + " __global const float4* uniqueEdges, \n" + " __global const btGpuFace* faces,\n" + " __global const int* indices,\n" + " float4* sep,\n" + " float* dmin)\n" + "{\n" + " \n" + " float4 posA = posA1;\n" + " posA.w = 0.f;\n" + " float4 posB = posB1;\n" + " posB.w = 0.f;\n" + " int curPlaneTests=0;\n" + " int curEdgeEdge = 0;\n" + " // Test edges\n" + " for(int e0=0;e0m_numUniqueEdges;e0++)\n" + " {\n" + " const float4 edge0 = uniqueEdges[hullA->m_uniqueEdgesOffset+e0];\n" + " float4 edge0World = qtRotate(ornA,edge0);\n" + " for(int e1=0;e1m_numUniqueEdges;e1++)\n" + " {\n" + " const float4 edge1 = uniqueEdges[hullB->m_uniqueEdgesOffset+e1];\n" + " float4 edge1World = qtRotate(ornB,edge1);\n" + " float4 crossje = cross3(edge0World,edge1World);\n" + " curEdgeEdge++;\n" + " if(!IsAlmostZero(crossje))\n" + " {\n" + " crossje = normalize3(crossje);\n" + " if (dot3F4(DeltaC2,crossje)<0)\n" + " crossje*=-1.f;\n" + " \n" + " float dist;\n" + " bool result = true;\n" + " {\n" + " float Min0,Max0;\n" + " float Min1,Max1;\n" + " project(hullA,posA,ornA,&crossje,vertices, &Min0, &Max0);\n" + " project(hullB,posB,ornB,&crossje,vertices, &Min1, &Max1);\n" + " \n" + " if(Max00.0f)\n" + " {\n" + " *sep = -(*sep);\n" + " }\n" + " return true;\n" + "}\n" + "// work-in-progress\n" + "__kernel void processCompoundPairsKernel( __global const int4* gpuCompoundPairs,\n" + " __global const BodyData* rigidBodies, \n" + " __global const btCollidableGpu* collidables,\n" + " __global const ConvexPolyhedronCL* convexShapes, \n" + " __global const float4* vertices,\n" + " __global const float4* uniqueEdges,\n" + " __global const btGpuFace* faces,\n" + " __global const int* indices,\n" + " __global btAabbCL* aabbs,\n" + " __global const btGpuChildShape* gpuChildShapes,\n" + " __global volatile float4* gpuCompoundSepNormalsOut,\n" + " __global volatile int* gpuHasCompoundSepNormalsOut,\n" + " int numCompoundPairs\n" + " )\n" + "{\n" + " int i = get_global_id(0);\n" + " if (i= 0)\n" + " {\n" + " collidableIndexA = gpuChildShapes[childShapeIndexA].m_shapeIndex;\n" + " float4 childPosA = gpuChildShapes[childShapeIndexA].m_childPosition;\n" + " float4 childOrnA = gpuChildShapes[childShapeIndexA].m_childOrientation;\n" + " float4 newPosA = qtRotate(ornA,childPosA)+posA;\n" + " float4 newOrnA = qtMul(ornA,childOrnA);\n" + " posA = newPosA;\n" + " ornA = newOrnA;\n" + " } else\n" + " {\n" + " collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;\n" + " }\n" + " \n" + " if (childShapeIndexB>=0)\n" + " {\n" + " collidableIndexB = gpuChildShapes[childShapeIndexB].m_shapeIndex;\n" + " float4 childPosB = gpuChildShapes[childShapeIndexB].m_childPosition;\n" + " float4 childOrnB = gpuChildShapes[childShapeIndexB].m_childOrientation;\n" + " float4 newPosB = transform(&childPosB,&posB,&ornB);\n" + " float4 newOrnB = qtMul(ornB,childOrnB);\n" + " posB = newPosB;\n" + " ornB = newOrnB;\n" + " } else\n" + " {\n" + " collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx; \n" + " }\n" + " \n" + " gpuHasCompoundSepNormalsOut[i] = 0;\n" + " \n" + " int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;\n" + " int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;\n" + " \n" + " int shapeTypeA = collidables[collidableIndexA].m_shapeType;\n" + " int shapeTypeB = collidables[collidableIndexB].m_shapeType;\n" + " \n" + " if ((shapeTypeA != SHAPE_CONVEX_HULL) || (shapeTypeB != SHAPE_CONVEX_HULL))\n" + " {\n" + " return;\n" + " }\n" + " int hasSeparatingAxis = 5;\n" + " \n" + " int numFacesA = convexShapes[shapeIndexA].m_numFaces;\n" + " float dmin = FLT_MAX;\n" + " posA.w = 0.f;\n" + " posB.w = 0.f;\n" + " float4 c0local = convexShapes[shapeIndexA].m_localCenter;\n" + " float4 c0 = transform(&c0local, &posA, &ornA);\n" + " float4 c1local = convexShapes[shapeIndexB].m_localCenter;\n" + " float4 c1 = transform(&c1local,&posB,&ornB);\n" + " const float4 DeltaC2 = c0 - c1;\n" + " float4 sepNormal = make_float4(1,0,0,0);\n" + " bool sepA = findSeparatingAxis( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,posB,ornB,DeltaC2,vertices,uniqueEdges,faces,indices,&sepNormal,&dmin);\n" + " hasSeparatingAxis = 4;\n" + " if (!sepA)\n" + " {\n" + " hasSeparatingAxis = 0;\n" + " } else\n" + " {\n" + " bool sepB = findSeparatingAxis( &convexShapes[shapeIndexB],&convexShapes[shapeIndexA],posB,ornB,posA,ornA,DeltaC2,vertices,uniqueEdges,faces,indices,&sepNormal,&dmin);\n" + " if (!sepB)\n" + " {\n" + " hasSeparatingAxis = 0;\n" + " } else//(!sepB)\n" + " {\n" + " bool sepEE = findSeparatingAxisEdgeEdge( &convexShapes[shapeIndexA], &convexShapes[shapeIndexB],posA,ornA,posB,ornB,DeltaC2,vertices,uniqueEdges,faces,indices,&sepNormal,&dmin);\n" + " if (sepEE)\n" + " {\n" + " gpuCompoundSepNormalsOut[i] = sepNormal;//fastNormalize4(sepNormal);\n" + " gpuHasCompoundSepNormalsOut[i] = 1;\n" + " }//sepEE\n" + " }//(!sepB)\n" + " }//(!sepA)\n" + " \n" + " \n" + " }\n" + " \n" + "}\n" + "inline b3Float4 MyUnQuantize(const unsigned short* vecIn, b3Float4 quantization, b3Float4 bvhAabbMin)\n" + "{\n" + " b3Float4 vecOut;\n" + " vecOut = b3MakeFloat4(\n" + " (float)(vecIn[0]) / (quantization.x),\n" + " (float)(vecIn[1]) / (quantization.y),\n" + " (float)(vecIn[2]) / (quantization.z),\n" + " 0.f);\n" + " vecOut += bvhAabbMin;\n" + " return vecOut;\n" + "}\n" + "inline b3Float4 MyUnQuantizeGlobal(__global const unsigned short* vecIn, b3Float4 quantization, b3Float4 bvhAabbMin)\n" + "{\n" + " b3Float4 vecOut;\n" + " vecOut = b3MakeFloat4(\n" + " (float)(vecIn[0]) / (quantization.x),\n" + " (float)(vecIn[1]) / (quantization.y),\n" + " (float)(vecIn[2]) / (quantization.z),\n" + " 0.f);\n" + " vecOut += bvhAabbMin;\n" + " return vecOut;\n" + "}\n" + "// work-in-progress\n" + "__kernel void findCompoundPairsKernel( __global const int4* pairs, \n" + " __global const BodyData* rigidBodies, \n" + " __global const btCollidableGpu* collidables,\n" + " __global const ConvexPolyhedronCL* convexShapes, \n" + " __global const float4* vertices,\n" + " __global const float4* uniqueEdges,\n" + " __global const btGpuFace* faces,\n" + " __global const int* indices,\n" + " __global b3Aabb_t* aabbLocalSpace,\n" + " __global const btGpuChildShape* gpuChildShapes,\n" + " __global volatile int4* gpuCompoundPairsOut,\n" + " __global volatile int* numCompoundPairsOut,\n" + " __global const b3BvhSubtreeInfo* subtrees,\n" + " __global const b3QuantizedBvhNode* quantizedNodes,\n" + " __global const b3BvhInfo* bvhInfos,\n" + " int numPairs,\n" + " int maxNumCompoundPairsCapacity\n" + " )\n" + "{\n" + " int i = get_global_id(0);\n" + " if (imaxStackDepth && !(isLeafA && isLeafB))\n" + " {\n" + " //printf(\"Error: traversal exceeded maxStackDepth\");\n" + " continue;\n" + " }\n" + " if(isInternalA)\n" + " {\n" + " int nodeAleftChild = node.x+1;\n" + " bool isNodeALeftChildLeaf = isLeafNodeGlobal(&quantizedNodes[node.x+1]);\n" + " int nodeArightChild = isNodeALeftChildLeaf? node.x+2 : node.x+1 + getEscapeIndexGlobal(&quantizedNodes[node.x+1]);\n" + " if(isInternalB)\n" + " { \n" + " int nodeBleftChild = node.y+1;\n" + " bool isNodeBLeftChildLeaf = isLeafNodeGlobal(&quantizedNodes[node.y+1]);\n" + " int nodeBrightChild = isNodeBLeftChildLeaf? node.y+2 : node.y+1 + getEscapeIndexGlobal(&quantizedNodes[node.y+1]);\n" + " nodeStack[depth++] = b3MakeInt2(nodeAleftChild, nodeBleftChild);\n" + " nodeStack[depth++] = b3MakeInt2(nodeArightChild, nodeBleftChild);\n" + " nodeStack[depth++] = b3MakeInt2(nodeAleftChild, nodeBrightChild);\n" + " nodeStack[depth++] = b3MakeInt2(nodeArightChild, nodeBrightChild);\n" + " }\n" + " else\n" + " {\n" + " nodeStack[depth++] = b3MakeInt2(nodeAleftChild,node.y);\n" + " nodeStack[depth++] = b3MakeInt2(nodeArightChild,node.y);\n" + " }\n" + " }\n" + " else\n" + " {\n" + " if(isInternalB)\n" + " {\n" + " int nodeBleftChild = node.y+1;\n" + " bool isNodeBLeftChildLeaf = isLeafNodeGlobal(&quantizedNodes[node.y+1]);\n" + " int nodeBrightChild = isNodeBLeftChildLeaf? node.y+2 : node.y+1 + getEscapeIndexGlobal(&quantizedNodes[node.y+1]);\n" + " nodeStack[depth++] = b3MakeInt2(node.x,nodeBleftChild);\n" + " nodeStack[depth++] = b3MakeInt2(node.x,nodeBrightChild);\n" + " }\n" + " else\n" + " {\n" + " int compoundPairIdx = atomic_inc(numCompoundPairsOut);\n" + " if (compoundPairIdxm_numFaces;face++)\n" + " {\n" + " const float4 Normal = make_float4(facesB[hullB->m_faceOffset+face].m_plane.x,\n" + " facesB[hullB->m_faceOffset+face].m_plane.y, facesB[hullB->m_faceOffset+face].m_plane.z,0.f);\n" + " const float4 WorldNormal = qtRotate(ornB, Normal);\n" + " float d = dot3F4(WorldNormal,separatingNormal);\n" + " if (d > dmax)\n" + " {\n" + " dmax = d;\n" + " closestFaceB = face;\n" + " }\n" + " }\n" + " }\n" + " \n" + " {\n" + " const btGpuFace polyB = facesB[hullB->m_faceOffset+closestFaceB];\n" + " int numVertices = polyB.m_numIndices;\n" + " if (numVertices>capacityWorldVerts)\n" + " numVertices = capacityWorldVerts;\n" + " \n" + " for(int e0=0;e0m_vertexOffset+indicesB[polyB.m_indexOffset+e0]];\n" + " worldVertsB1[pairIndex*capacityWorldVerts+numWorldVertsB1++] = transform(&b,&posB,&ornB);\n" + " }\n" + " }\n" + " }\n" + " \n" + " int closestFaceA=0;\n" + " {\n" + " float dmin = FLT_MAX;\n" + " for(int face=0;facem_numFaces;face++)\n" + " {\n" + " const float4 Normal = make_float4(\n" + " facesA[hullA->m_faceOffset+face].m_plane.x,\n" + " facesA[hullA->m_faceOffset+face].m_plane.y,\n" + " facesA[hullA->m_faceOffset+face].m_plane.z,\n" + " 0.f);\n" + " const float4 faceANormalWS = qtRotate(ornA,Normal);\n" + " \n" + " float d = dot3F4(faceANormalWS,separatingNormal);\n" + " if (d < dmin)\n" + " {\n" + " dmin = d;\n" + " closestFaceA = face;\n" + " worldNormalsA1[pairIndex] = faceANormalWS;\n" + " }\n" + " }\n" + " }\n" + " \n" + " int numVerticesA = facesA[hullA->m_faceOffset+closestFaceA].m_numIndices;\n" + " if (numVerticesA>capacityWorldVerts)\n" + " numVerticesA = capacityWorldVerts;\n" + " \n" + " for(int e0=0;e0m_vertexOffset+indicesA[facesA[hullA->m_faceOffset+closestFaceA].m_indexOffset+e0]];\n" + " worldVertsA1[pairIndex*capacityWorldVerts+e0] = transform(&a, &posA,&ornA);\n" + " }\n" + " }\n" + " \n" + " clippingFaces[pairIndex].x = closestFaceA;\n" + " clippingFaces[pairIndex].y = closestFaceB;\n" + " clippingFaces[pairIndex].z = numVerticesA;\n" + " clippingFaces[pairIndex].w = numWorldVertsB1;\n" + " \n" + " \n" + " return numContactsOut;\n" + "}\n" + "// work-in-progress\n" + "__kernel void findConcaveSeparatingAxisKernel( __global int4* concavePairs,\n" + " __global const BodyData* rigidBodies,\n" + " __global const btCollidableGpu* collidables,\n" + " __global const ConvexPolyhedronCL* convexShapes, \n" + " __global const float4* vertices,\n" + " __global const float4* uniqueEdges,\n" + " __global const btGpuFace* faces,\n" + " __global const int* indices,\n" + " __global const btGpuChildShape* gpuChildShapes,\n" + " __global btAabbCL* aabbs,\n" + " __global float4* concaveSeparatingNormalsOut,\n" + " __global int* concaveHasSeparatingNormals,\n" + " __global int4* clippingFacesOut,\n" + " __global float4* worldVertsA1GPU,\n" + " __global float4* worldNormalsAGPU,\n" + " __global float4* worldVertsB1GPU,\n" + " int vertexFaceCapacity,\n" + " int numConcavePairs\n" + " )\n" + "{\n" + " int i = get_global_id(0);\n" + " if (i>=numConcavePairs)\n" + " return;\n" + " concaveHasSeparatingNormals[i] = 0;\n" + " int pairIdx = i;\n" + " int bodyIndexA = concavePairs[i].x;\n" + " int bodyIndexB = concavePairs[i].y;\n" + " int collidableIndexA = rigidBodies[bodyIndexA].m_collidableIdx;\n" + " int collidableIndexB = rigidBodies[bodyIndexB].m_collidableIdx;\n" + " int shapeIndexA = collidables[collidableIndexA].m_shapeIndex;\n" + " int shapeIndexB = collidables[collidableIndexB].m_shapeIndex;\n" + " if (collidables[collidableIndexB].m_shapeType!=SHAPE_CONVEX_HULL&&\n" + " collidables[collidableIndexB].m_shapeType!=SHAPE_COMPOUND_OF_CONVEX_HULLS)\n" + " {\n" + " concavePairs[pairIdx].w = -1;\n" + " return;\n" + " }\n" + " int numFacesA = convexShapes[shapeIndexA].m_numFaces;\n" + " int numActualConcaveConvexTests = 0;\n" + " \n" + " int f = concavePairs[i].z;\n" + " \n" + " bool overlap = false;\n" + " \n" + " ConvexPolyhedronCL convexPolyhedronA;\n" + " //add 3 vertices of the triangle\n" + " convexPolyhedronA.m_numVertices = 3;\n" + " convexPolyhedronA.m_vertexOffset = 0;\n" + " float4 localCenter = make_float4(0.f,0.f,0.f,0.f);\n" + " btGpuFace face = faces[convexShapes[shapeIndexA].m_faceOffset+f];\n" + " float4 triMinAabb, triMaxAabb;\n" + " btAabbCL triAabb;\n" + " triAabb.m_min = make_float4(1e30f,1e30f,1e30f,0.f);\n" + " triAabb.m_max = make_float4(-1e30f,-1e30f,-1e30f,0.f);\n" + " \n" + " float4 verticesA[3];\n" + " for (int i=0;i<3;i++)\n" + " {\n" + " int index = indices[face.m_indexOffset+i];\n" + " float4 vert = vertices[convexShapes[shapeIndexA].m_vertexOffset+index];\n" + " verticesA[i] = vert;\n" + " localCenter += vert;\n" + " \n" + " triAabb.m_min = min(triAabb.m_min,vert); \n" + " triAabb.m_max = max(triAabb.m_max,vert); \n" + " }\n" + " overlap = true;\n" + " overlap = (triAabb.m_min.x > aabbs[bodyIndexB].m_max.x || triAabb.m_max.x < aabbs[bodyIndexB].m_min.x) ? false : overlap;\n" + " overlap = (triAabb.m_min.z > aabbs[bodyIndexB].m_max.z || triAabb.m_max.z < aabbs[bodyIndexB].m_min.z) ? false : overlap;\n" + " overlap = (triAabb.m_min.y > aabbs[bodyIndexB].m_max.y || triAabb.m_max.y < aabbs[bodyIndexB].m_min.y) ? false : overlap;\n" + " \n" + " if (overlap)\n" + " {\n" + " float dmin = FLT_MAX;\n" + " int hasSeparatingAxis=5;\n" + " float4 sepAxis=make_float4(1,2,3,4);\n" + " int localCC=0;\n" + " numActualConcaveConvexTests++;\n" + " //a triangle has 3 unique edges\n" + " convexPolyhedronA.m_numUniqueEdges = 3;\n" + " convexPolyhedronA.m_uniqueEdgesOffset = 0;\n" + " float4 uniqueEdgesA[3];\n" + " \n" + " uniqueEdgesA[0] = (verticesA[1]-verticesA[0]);\n" + " uniqueEdgesA[1] = (verticesA[2]-verticesA[1]);\n" + " uniqueEdgesA[2] = (verticesA[0]-verticesA[2]);\n" + " convexPolyhedronA.m_faceOffset = 0;\n" + " \n" + " float4 normal = make_float4(face.m_plane.x,face.m_plane.y,face.m_plane.z,0.f);\n" + " \n" + " btGpuFace facesA[TRIANGLE_NUM_CONVEX_FACES];\n" + " int indicesA[3+3+2+2+2];\n" + " int curUsedIndices=0;\n" + " int fidx=0;\n" + " //front size of triangle\n" + " {\n" + " facesA[fidx].m_indexOffset=curUsedIndices;\n" + " indicesA[0] = 0;\n" + " indicesA[1] = 1;\n" + " indicesA[2] = 2;\n" + " curUsedIndices+=3;\n" + " float c = face.m_plane.w;\n" + " facesA[fidx].m_plane.x = normal.x;\n" + " facesA[fidx].m_plane.y = normal.y;\n" + " facesA[fidx].m_plane.z = normal.z;\n" + " facesA[fidx].m_plane.w = c;\n" + " facesA[fidx].m_numIndices=3;\n" + " }\n" + " fidx++;\n" + " //back size of triangle\n" + " {\n" + " facesA[fidx].m_indexOffset=curUsedIndices;\n" + " indicesA[3]=2;\n" + " indicesA[4]=1;\n" + " indicesA[5]=0;\n" + " curUsedIndices+=3;\n" + " float c = dot(normal,verticesA[0]);\n" + " float c1 = -face.m_plane.w;\n" + " facesA[fidx].m_plane.x = -normal.x;\n" + " facesA[fidx].m_plane.y = -normal.y;\n" + " facesA[fidx].m_plane.z = -normal.z;\n" + " facesA[fidx].m_plane.w = c;\n" + " facesA[fidx].m_numIndices=3;\n" + " }\n" + " fidx++;\n" + " bool addEdgePlanes = true;\n" + " if (addEdgePlanes)\n" + " {\n" + " int numVertices=3;\n" + " int prevVertex = numVertices-1;\n" + " for (int i=0;i( device, 1, BufferBase::BUFFER_CONST ); - - m_lower = (maxSize == 0)? 0: new b3OpenCLArray(ctx,queue,maxSize ); - m_upper = (maxSize == 0)? 0: new b3OpenCLArray(ctx,queue, maxSize ); - m_filler = new b3FillCL(ctx,device,queue); + m_lower = (maxSize == 0) ? 0 : new b3OpenCLArray(ctx, queue, maxSize); + m_upper = (maxSize == 0) ? 0 : new b3OpenCLArray(ctx, queue, maxSize); + + m_filler = new b3FillCL(ctx, device, queue); } b3BoundSearchCL::~b3BoundSearchCL() { - delete m_lower; delete m_upper; delete m_filler; - + clReleaseKernel(m_lowerSortDataKernel); clReleaseKernel(m_upperSortDataKernel); clReleaseKernel(m_subtractKernel); - - } - -void b3BoundSearchCL::execute(b3OpenCLArray& src, int nSrc, b3OpenCLArray& dst, int nDst, Option option ) +void b3BoundSearchCL::execute(b3OpenCLArray& src, int nSrc, b3OpenCLArray& dst, int nDst, Option option) { b3Int4 constBuffer; constBuffer.x = nSrc; constBuffer.y = nDst; - if( option == BOUND_LOWER ) + if (option == BOUND_LOWER) { - b3BufferInfoCL bInfo[] = { b3BufferInfoCL( src.getBufferCL(), true ), b3BufferInfoCL( dst.getBufferCL()) }; + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(src.getBufferCL(), true), b3BufferInfoCL(dst.getBufferCL())}; - b3LauncherCL launcher( m_queue, m_lowerSortDataKernel,"m_lowerSortDataKernel" ); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( nSrc ); - launcher.setConst( nDst ); - - launcher.launch1D( nSrc, 64 ); + b3LauncherCL launcher(m_queue, m_lowerSortDataKernel, "m_lowerSortDataKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(nSrc); + launcher.setConst(nDst); + + launcher.launch1D(nSrc, 64); } - else if( option == BOUND_UPPER ) + else if (option == BOUND_UPPER) { - b3BufferInfoCL bInfo[] = { b3BufferInfoCL( src.getBufferCL(), true ), b3BufferInfoCL( dst.getBufferCL() ) }; + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(src.getBufferCL(), true), b3BufferInfoCL(dst.getBufferCL())}; - b3LauncherCL launcher(m_queue, m_upperSortDataKernel,"m_upperSortDataKernel" ); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( nSrc ); - launcher.setConst( nDst ); + b3LauncherCL launcher(m_queue, m_upperSortDataKernel, "m_upperSortDataKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(nSrc); + launcher.setConst(nDst); - launcher.launch1D( nSrc, 64 ); + launcher.launch1D(nSrc, 64); } - else if( option == COUNT ) + else if (option == COUNT) { - b3Assert( m_lower ); - b3Assert( m_upper ); - b3Assert( m_lower->capacity() <= (int)nDst ); - b3Assert( m_upper->capacity() <= (int)nDst ); + b3Assert(m_lower); + b3Assert(m_upper); + b3Assert(m_lower->capacity() <= (int)nDst); + b3Assert(m_upper->capacity() <= (int)nDst); int zero = 0; - m_filler->execute( *m_lower, zero, nDst ); - m_filler->execute( *m_upper, zero, nDst ); + m_filler->execute(*m_lower, zero, nDst); + m_filler->execute(*m_upper, zero, nDst); - execute( src, nSrc, *m_lower, nDst, BOUND_LOWER ); - execute( src, nSrc, *m_upper, nDst, BOUND_UPPER ); + execute(src, nSrc, *m_lower, nDst, BOUND_LOWER); + execute(src, nSrc, *m_upper, nDst, BOUND_UPPER); { - b3BufferInfoCL bInfo[] = { b3BufferInfoCL( m_upper->getBufferCL(), true ), b3BufferInfoCL( m_lower->getBufferCL(), true ), b3BufferInfoCL( dst.getBufferCL() ) }; + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(m_upper->getBufferCL(), true), b3BufferInfoCL(m_lower->getBufferCL(), true), b3BufferInfoCL(dst.getBufferCL())}; - b3LauncherCL launcher( m_queue, m_subtractKernel ,"m_subtractKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( nSrc ); - launcher.setConst( nDst ); + b3LauncherCL launcher(m_queue, m_subtractKernel, "m_subtractKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(nSrc); + launcher.setConst(nDst); - launcher.launch1D( nDst, 64 ); + launcher.launch1D(nDst, 64); } } else { - b3Assert( 0 ); + b3Assert(0); } - } - -void b3BoundSearchCL::executeHost( b3AlignedObjectArray& src, int nSrc, - b3AlignedObjectArray& dst, int nDst, Option option ) +void b3BoundSearchCL::executeHost(b3AlignedObjectArray& src, int nSrc, + b3AlignedObjectArray& dst, int nDst, Option option) { + for (int i = 0; i < nSrc - 1; i++) + b3Assert(src[i].m_key <= src[i + 1].m_key); - - for(int i=0; i& src, int nS } } } - else if( option == BOUND_UPPER ) + else if (option == BOUND_UPPER) { - for(int i=1; i& src, int nS } } } - else if( option == COUNT ) + else if (option == COUNT) { b3AlignedObjectArray lower; - lower.resize(nDst ); + lower.resize(nDst); b3AlignedObjectArray upper; - upper.resize(nDst ); + upper.resize(nDst); - for(int i=0; i* m_constbtOpenCLArray; - b3OpenCLArray* m_lower; - b3OpenCLArray* m_upper; - - b3FillCL* m_filler; - - b3BoundSearchCL(cl_context context, cl_device_id device, cl_command_queue queue, int size); + b3OpenCLArray* m_constbtOpenCLArray; + b3OpenCLArray* m_lower; + b3OpenCLArray* m_upper; - virtual ~b3BoundSearchCL(); + b3FillCL* m_filler; - // src has to be src[i].m_key <= src[i+1].m_key - void execute( b3OpenCLArray& src, int nSrc, b3OpenCLArray& dst, int nDst, Option option = BOUND_LOWER ); + b3BoundSearchCL(cl_context context, cl_device_id device, cl_command_queue queue, int size); - void executeHost( b3AlignedObjectArray& src, int nSrc, b3AlignedObjectArray& dst, int nDst, Option option = BOUND_LOWER); + virtual ~b3BoundSearchCL(); + + // src has to be src[i].m_key <= src[i+1].m_key + void execute(b3OpenCLArray& src, int nSrc, b3OpenCLArray& dst, int nDst, Option option = BOUND_LOWER); + + void executeHost(b3AlignedObjectArray& src, int nSrc, b3AlignedObjectArray& dst, int nDst, Option option = BOUND_LOWER); }; - -#endif //B3_BOUNDSEARCH_H +#endif //B3_BOUNDSEARCH_H diff --git a/src/Bullet3OpenCL/ParallelPrimitives/b3BufferInfoCL.h b/src/Bullet3OpenCL/ParallelPrimitives/b3BufferInfoCL.h index 52f219ae3..35fc467b2 100644 --- a/src/Bullet3OpenCL/ParallelPrimitives/b3BufferInfoCL.h +++ b/src/Bullet3OpenCL/ParallelPrimitives/b3BufferInfoCL.h @@ -4,16 +4,15 @@ #include "b3OpenCLArray.h" - struct b3BufferInfoCL { //b3BufferInfoCL(){} -// template - b3BufferInfoCL(cl_mem buff, bool isReadOnly = false): m_clBuffer(buff), m_isReadOnly(isReadOnly){} + // template + b3BufferInfoCL(cl_mem buff, bool isReadOnly = false) : m_clBuffer(buff), m_isReadOnly(isReadOnly) {} cl_mem m_clBuffer; bool m_isReadOnly; }; -#endif //B3_BUFFER_INFO_CL_H +#endif //B3_BUFFER_INFO_CL_H diff --git a/src/Bullet3OpenCL/ParallelPrimitives/b3FillCL.cpp b/src/Bullet3OpenCL/ParallelPrimitives/b3FillCL.cpp index f05c2648f..bd25bb210 100644 --- a/src/Bullet3OpenCL/ParallelPrimitives/b3FillCL.cpp +++ b/src/Bullet3OpenCL/ParallelPrimitives/b3FillCL.cpp @@ -8,29 +8,26 @@ #include "kernels/FillKernelsCL.h" b3FillCL::b3FillCL(cl_context ctx, cl_device_id device, cl_command_queue queue) -:m_commandQueue(queue) + : m_commandQueue(queue) { const char* kernelSource = fillKernelsCL; cl_int pErrNum; const char* additionalMacros = ""; - cl_program fillProg = b3OpenCLUtils::compileCLProgramFromString( ctx, device, kernelSource, &pErrNum,additionalMacros, FILL_CL_PROGRAM_PATH); + cl_program fillProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, kernelSource, &pErrNum, additionalMacros, FILL_CL_PROGRAM_PATH); b3Assert(fillProg); - m_fillIntKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "FillIntKernel", &pErrNum, fillProg,additionalMacros ); + m_fillIntKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, kernelSource, "FillIntKernel", &pErrNum, fillProg, additionalMacros); b3Assert(m_fillIntKernel); - m_fillUnsignedIntKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "FillUnsignedIntKernel", &pErrNum, fillProg,additionalMacros ); + m_fillUnsignedIntKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, kernelSource, "FillUnsignedIntKernel", &pErrNum, fillProg, additionalMacros); b3Assert(m_fillIntKernel); - m_fillFloatKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "FillFloatKernel", &pErrNum, fillProg,additionalMacros ); + m_fillFloatKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, kernelSource, "FillFloatKernel", &pErrNum, fillProg, additionalMacros); b3Assert(m_fillFloatKernel); - - - m_fillKernelInt2 = b3OpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "FillInt2Kernel", &pErrNum, fillProg,additionalMacros ); + m_fillKernelInt2 = b3OpenCLUtils::compileCLKernelFromString(ctx, device, kernelSource, "FillInt2Kernel", &pErrNum, fillProg, additionalMacros); b3Assert(m_fillKernelInt2); - } b3FillCL::~b3FillCL() @@ -39,88 +36,84 @@ b3FillCL::~b3FillCL() clReleaseKernel(m_fillIntKernel); clReleaseKernel(m_fillUnsignedIntKernel); clReleaseKernel(m_fillFloatKernel); - } void b3FillCL::execute(b3OpenCLArray& src, const float value, int n, int offset) { - b3Assert( n>0 ); + b3Assert(n > 0); { - b3LauncherCL launcher( m_commandQueue, m_fillFloatKernel,"m_fillFloatKernel" ); - launcher.setBuffer( src.getBufferCL()); - launcher.setConst( n ); - launcher.setConst( value ); - launcher.setConst( offset); + b3LauncherCL launcher(m_commandQueue, m_fillFloatKernel, "m_fillFloatKernel"); + launcher.setBuffer(src.getBufferCL()); + launcher.setConst(n); + launcher.setConst(value); + launcher.setConst(offset); - launcher.launch1D( n ); + launcher.launch1D(n); } } void b3FillCL::execute(b3OpenCLArray& src, const int value, int n, int offset) { - b3Assert( n>0 ); - + b3Assert(n > 0); { - b3LauncherCL launcher( m_commandQueue, m_fillIntKernel ,"m_fillIntKernel"); + b3LauncherCL launcher(m_commandQueue, m_fillIntKernel, "m_fillIntKernel"); launcher.setBuffer(src.getBufferCL()); - launcher.setConst( n); - launcher.setConst( value); - launcher.setConst( offset); - launcher.launch1D( n ); + launcher.setConst(n); + launcher.setConst(value); + launcher.setConst(offset); + launcher.launch1D(n); } } - void b3FillCL::execute(b3OpenCLArray& src, const unsigned int value, int n, int offset) { - b3Assert( n>0 ); + b3Assert(n > 0); { - b3BufferInfoCL bInfo[] = { b3BufferInfoCL( src.getBufferCL() ) }; + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(src.getBufferCL())}; - b3LauncherCL launcher( m_commandQueue, m_fillUnsignedIntKernel,"m_fillUnsignedIntKernel" ); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( n ); - launcher.setConst(value); + b3LauncherCL launcher(m_commandQueue, m_fillUnsignedIntKernel, "m_fillUnsignedIntKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(n); + launcher.setConst(value); launcher.setConst(offset); - launcher.launch1D( n ); + launcher.launch1D(n); } } -void b3FillCL::executeHost(b3AlignedObjectArray &src, const b3Int2 &value, int n, int offset) +void b3FillCL::executeHost(b3AlignedObjectArray& src, const b3Int2& value, int n, int offset) { - for (int i=0;i &src, const int value, int n, int offset) +void b3FillCL::executeHost(b3AlignedObjectArray& src, const int value, int n, int offset) { - for (int i=0;i &src, const b3Int2 &value, int n, int offset) +void b3FillCL::execute(b3OpenCLArray& src, const b3Int2& value, int n, int offset) { - b3Assert( n>0 ); - + b3Assert(n > 0); { - b3BufferInfoCL bInfo[] = { b3BufferInfoCL( src.getBufferCL() ) }; + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(src.getBufferCL())}; - b3LauncherCL launcher(m_commandQueue, m_fillKernelInt2,"m_fillKernelInt2"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); + b3LauncherCL launcher(m_commandQueue, m_fillKernelInt2, "m_fillKernelInt2"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); launcher.setConst(n); launcher.setConst(value); launcher.setConst(offset); //( constBuffer ); - launcher.launch1D( n ); + launcher.launch1D(n); } } diff --git a/src/Bullet3OpenCL/ParallelPrimitives/b3FillCL.h b/src/Bullet3OpenCL/ParallelPrimitives/b3FillCL.h index 1609676b9..c92c3e511 100644 --- a/src/Bullet3OpenCL/ParallelPrimitives/b3FillCL.h +++ b/src/Bullet3OpenCL/ParallelPrimitives/b3FillCL.h @@ -7,57 +7,46 @@ #include "Bullet3Common/shared/b3Int2.h" #include "Bullet3Common/shared/b3Int4.h" - class b3FillCL { - - cl_command_queue m_commandQueue; - - cl_kernel m_fillKernelInt2; - cl_kernel m_fillIntKernel; - cl_kernel m_fillUnsignedIntKernel; - cl_kernel m_fillFloatKernel; + cl_command_queue m_commandQueue; - public: - - struct b3ConstData - { - union - { - b3Int4 m_data; - b3UnsignedInt4 m_UnsignedData; - }; - int m_offset; - int m_n; - int m_padding[2]; - }; - -protected: + cl_kernel m_fillKernelInt2; + cl_kernel m_fillIntKernel; + cl_kernel m_fillUnsignedIntKernel; + cl_kernel m_fillFloatKernel; public: + struct b3ConstData + { + union { + b3Int4 m_data; + b3UnsignedInt4 m_UnsignedData; + }; + int m_offset; + int m_n; + int m_padding[2]; + }; - b3FillCL(cl_context ctx, cl_device_id device, cl_command_queue queue); +protected: +public: + b3FillCL(cl_context ctx, cl_device_id device, cl_command_queue queue); - virtual ~b3FillCL(); + virtual ~b3FillCL(); - void execute(b3OpenCLArray& src, const unsigned int value, int n, int offset = 0); - - void execute(b3OpenCLArray& src, const int value, int n, int offset = 0); + void execute(b3OpenCLArray& src, const unsigned int value, int n, int offset = 0); - void execute(b3OpenCLArray& src, const float value, int n, int offset = 0); + void execute(b3OpenCLArray& src, const int value, int n, int offset = 0); - void execute(b3OpenCLArray& src, const b3Int2& value, int n, int offset = 0); + void execute(b3OpenCLArray& src, const float value, int n, int offset = 0); - void executeHost(b3AlignedObjectArray &src, const b3Int2 &value, int n, int offset); + void execute(b3OpenCLArray& src, const b3Int2& value, int n, int offset = 0); - void executeHost(b3AlignedObjectArray &src, const int value, int n, int offset); + void executeHost(b3AlignedObjectArray& src, const b3Int2& value, int n, int offset); + + void executeHost(b3AlignedObjectArray& src, const int value, int n, int offset); // void execute(b3OpenCLArray& src, const b3Int4& value, int n, int offset = 0); - }; - - - - -#endif //B3_FILL_CL_H +#endif //B3_FILL_CL_H diff --git a/src/Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.cpp b/src/Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.cpp index 94590d11c..c97d02eb4 100644 --- a/src/Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.cpp +++ b/src/Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.cpp @@ -1,13 +1,13 @@ #include "b3LauncherCL.h" bool gDebugLauncherCL = false; - + b3LauncherCL::b3LauncherCL(cl_command_queue queue, cl_kernel kernel, const char* name) -:m_commandQueue(queue), -m_kernel(kernel), -m_idx(0), -m_enableSerialization(false), -m_name(name) + : m_commandQueue(queue), + m_kernel(kernel), + m_idx(0), + m_enableSerialization(false), + m_name(name) { if (gDebugLauncherCL) { @@ -15,59 +15,58 @@ m_name(name) printf("[%d] Prepare to launch OpenCL kernel %s\n", counter++, name); } - m_serializationSizeInBytes = sizeof(int); + m_serializationSizeInBytes = sizeof(int); } - + b3LauncherCL::~b3LauncherCL() - { - for (int i=0;i - - int b3LauncherCL::deserializeArgs(unsigned char* buf, int bufSize, cl_context ctx) { - int index=0; - - int numArguments = *(int*) &buf[index]; - index+=sizeof(int); - - for (int i=0;im_isBuffer) - { - b3OpenCLArray* clData = new b3OpenCLArray(ctx,m_commandQueue, arg->m_argSizeInBytes); - clData->resize(arg->m_argSizeInBytes); - - clData->copyFromHostPointer(&buf[index], arg->m_argSizeInBytes); - - arg->m_clBuffer = clData->getBufferCL(); - - m_arrays.push_back(clData); - - cl_int status = clSetKernelArg( m_kernel, m_idx++, sizeof(cl_mem), &arg->m_clBuffer); - b3Assert( status == CL_SUCCESS ); - index+=arg->m_argSizeInBytes; - } else - { - cl_int status = clSetKernelArg( m_kernel, m_idx++, arg->m_argSizeInBytes, &arg->m_argData); - b3Assert( status == CL_SUCCESS ); - } + int numArguments = *(int*)&buf[index]; + index += sizeof(int); + + for (int i = 0; i < numArguments; i++) + { + b3KernelArgDataUnaligned* arg = (b3KernelArgDataUnaligned*)&buf[index]; + + index += sizeof(b3KernelArgData); + if (arg->m_isBuffer) + { + b3OpenCLArray* clData = new b3OpenCLArray(ctx, m_commandQueue, arg->m_argSizeInBytes); + clData->resize(arg->m_argSizeInBytes); + + clData->copyFromHostPointer(&buf[index], arg->m_argSizeInBytes); + + arg->m_clBuffer = clData->getBufferCL(); + + m_arrays.push_back(clData); + + cl_int status = clSetKernelArg(m_kernel, m_idx++, sizeof(cl_mem), &arg->m_clBuffer); + b3Assert(status == CL_SUCCESS); + index += arg->m_argSizeInBytes; + } + else + { + cl_int status = clSetKernelArg(m_kernel, m_idx++, arg->m_argSizeInBytes, &arg->m_argData); + b3Assert(status == CL_SUCCESS); + } b3KernelArgData b; - memcpy(&b,arg,sizeof(b3KernelArgDataUnaligned)); - m_kernelArguments.push_back(b); - } -m_serializationSizeInBytes = index; - return index; + memcpy(&b, arg, sizeof(b3KernelArgDataUnaligned)); + m_kernelArguments.push_back(b); + } + m_serializationSizeInBytes = index; + return index; } int b3LauncherCL::validateResults(unsigned char* goldBuffer, int goldBufferCapacity, cl_context ctx) - { - int index=0; - - int numArguments = *(int*) &goldBuffer[index]; - index+=sizeof(int); +{ + int index = 0; + + int numArguments = *(int*)&goldBuffer[index]; + index += sizeof(int); if (numArguments != m_kernelArguments.size()) { - printf("failed validation: expected %d arguments, found %d\n",numArguments, m_kernelArguments.size()); + printf("failed validation: expected %d arguments, found %d\n", numArguments, m_kernelArguments.size()); return -1; } - - for (int ii=0;iim_argSizeInBytes) { - printf("failed validation: argument %d sizeInBytes expected: %d, found %d\n",ii, argGold->m_argSizeInBytes, m_kernelArguments[ii].m_argSizeInBytes); + printf("failed validation: argument %d sizeInBytes expected: %d, found %d\n", ii, argGold->m_argSizeInBytes, m_kernelArguments[ii].m_argSizeInBytes); return -2; } @@ -184,125 +180,117 @@ int b3LauncherCL::validateResults(unsigned char* goldBuffer, int goldBufferCapac if (expected != found) { - printf("failed validation: argument %d isBuffer expected: %d, found %d\n",ii,expected, found); + printf("failed validation: argument %d isBuffer expected: %d, found %d\n", ii, expected, found); return -3; } } - index+=sizeof(b3KernelArgData); + index += sizeof(b3KernelArgData); if (argGold->m_isBuffer) - { - - unsigned char* memBuf= (unsigned char*) malloc(m_kernelArguments[ii].m_argSizeInBytes); + { + unsigned char* memBuf = (unsigned char*)malloc(m_kernelArguments[ii].m_argSizeInBytes); unsigned char* goldBuf = &goldBuffer[index]; - for (int j=0;jm_argSizeInBytes; - } else - { - + index += argGold->m_argSizeInBytes; + } + else + { //compare content - for (int b=0;bm_argData[b]; - int found =m_kernelArguments[ii].m_argData[b]; + int found = m_kernelArguments[ii].m_argData[b]; if (expected != found) { printf("failed validation: argument %d const data at byte position %d expected: %d, found %d\n", - ii, b, expected, found); + ii, b, expected, found); return -5; } } - - } - } - return index; - + } + } + return index; } int b3LauncherCL::serializeArguments(unsigned char* destBuffer, int destBufferCapacity) { -//initialize to known values -for (int i=0;i=m_serializationSizeInBytes); - - //todo: use the b3Serializer for this to allow for 32/64bit, endianness etc - int numArguments = m_kernelArguments.size(); - int curBufferSize = 0; - int* dest = (int*)&destBuffer[curBufferSize]; - *dest = numArguments; - curBufferSize += sizeof(int); - - - - for (int i=0;im_kernelArguments.size();i++) - { - b3KernelArgData* arg = (b3KernelArgData*) &destBuffer[curBufferSize]; - *arg = m_kernelArguments[i]; - curBufferSize+=sizeof(b3KernelArgData); - if (arg->m_isBuffer==1) - { - //copy the OpenCL buffer content - cl_int status = 0; - status = clEnqueueReadBuffer( m_commandQueue, arg->m_clBuffer, 0, 0, arg->m_argSizeInBytes, - &destBuffer[curBufferSize], 0,0,0 ); - b3Assert( status==CL_SUCCESS ); - clFinish(m_commandQueue); - curBufferSize+=arg->m_argSizeInBytes; - } - - } - return curBufferSize; + assert(destBufferCapacity >= m_serializationSizeInBytes); + + //todo: use the b3Serializer for this to allow for 32/64bit, endianness etc + int numArguments = m_kernelArguments.size(); + int curBufferSize = 0; + int* dest = (int*)&destBuffer[curBufferSize]; + *dest = numArguments; + curBufferSize += sizeof(int); + + for (int i = 0; i < this->m_kernelArguments.size(); i++) + { + b3KernelArgData* arg = (b3KernelArgData*)&destBuffer[curBufferSize]; + *arg = m_kernelArguments[i]; + curBufferSize += sizeof(b3KernelArgData); + if (arg->m_isBuffer == 1) + { + //copy the OpenCL buffer content + cl_int status = 0; + status = clEnqueueReadBuffer(m_commandQueue, arg->m_clBuffer, 0, 0, arg->m_argSizeInBytes, + &destBuffer[curBufferSize], 0, 0, 0); + b3Assert(status == CL_SUCCESS); + clFinish(m_commandQueue); + curBufferSize += arg->m_argSizeInBytes; + } + } + return curBufferSize; } void b3LauncherCL::serializeToFile(const char* fileName, int numWorkItems) { int num = numWorkItems; int buffSize = getSerializationBufferSize(); - unsigned char* buf = new unsigned char[buffSize+sizeof(int)]; - for (int i=0;i m_kernelArguments; - int m_serializationSizeInBytes; - bool m_enableSerialization; + + b3AlignedObjectArray m_kernelArguments; + int m_serializationSizeInBytes; + bool m_enableSerialization; const char* m_name; - public: - b3AlignedObjectArray* > m_arrays; - - b3LauncherCL(cl_command_queue queue, cl_kernel kernel, const char* name); - - virtual ~b3LauncherCL(); - - void setBuffer( cl_mem clBuffer); +public: + b3AlignedObjectArray*> m_arrays; - void setBuffers( b3BufferInfoCL* buffInfo, int n ); - - int getSerializationBufferSize() const - { - return m_serializationSizeInBytes; - } - - int deserializeArgs(unsigned char* buf, int bufSize, cl_context ctx); + b3LauncherCL(cl_command_queue queue, cl_kernel kernel, const char* name); + + virtual ~b3LauncherCL(); + + void setBuffer(cl_mem clBuffer); + + void setBuffers(b3BufferInfoCL* buffInfo, int n); + + int getSerializationBufferSize() const + { + return m_serializationSizeInBytes; + } + + int deserializeArgs(unsigned char* buf, int bufSize, cl_context ctx); inline int validateResults(unsigned char* goldBuffer, int goldBufferCapacity, cl_context ctx); - int serializeArguments(unsigned char* destBuffer, int destBufferCapacity); - + int serializeArguments(unsigned char* destBuffer, int destBufferCapacity); + int getNumArguments() const { return m_kernelArguments.size(); @@ -75,61 +72,57 @@ class b3LauncherCL void serializeToFile(const char* fileName, int numWorkItems); - template - inline void setConst( const T& consts ) - { - int sz=sizeof(T); - b3Assert(sz<=B3_CL_MAX_ARG_SIZE); + template + inline void setConst(const T& consts) + { + int sz = sizeof(T); + b3Assert(sz <= B3_CL_MAX_ARG_SIZE); - if (m_enableSerialization) - { - b3KernelArgData kernelArg; - kernelArg.m_argIndex = m_idx; - kernelArg.m_isBuffer = 0; - T* destArg = (T*)kernelArg.m_argData; - *destArg = consts; - kernelArg.m_argSizeInBytes = sizeof(T); - m_kernelArguments.push_back(kernelArg); - m_serializationSizeInBytes+=sizeof(b3KernelArgData); - } - - cl_int status = clSetKernelArg( m_kernel, m_idx++, sz, &consts ); - b3Assert( status == CL_SUCCESS ); + if (m_enableSerialization) + { + b3KernelArgData kernelArg; + kernelArg.m_argIndex = m_idx; + kernelArg.m_isBuffer = 0; + T* destArg = (T*)kernelArg.m_argData; + *destArg = consts; + kernelArg.m_argSizeInBytes = sizeof(T); + m_kernelArguments.push_back(kernelArg); + m_serializationSizeInBytes += sizeof(b3KernelArgData); } - inline void launch1D( int numThreads, int localSize = 64) - { - launch2D( numThreads, 1, localSize, 1 ); - } + cl_int status = clSetKernelArg(m_kernel, m_idx++, sz, &consts); + b3Assert(status == CL_SUCCESS); + } - inline void launch2D( int numThreadsX, int numThreadsY, int localSizeX, int localSizeY ) - { - size_t gRange[3] = {1,1,1}; - size_t lRange[3] = {1,1,1}; - lRange[0] = localSizeX; - lRange[1] = localSizeY; - gRange[0] = b3Max((size_t)1, (numThreadsX/lRange[0])+(!(numThreadsX%lRange[0])?0:1)); - gRange[0] *= lRange[0]; - gRange[1] = b3Max((size_t)1, (numThreadsY/lRange[1])+(!(numThreadsY%lRange[1])?0:1)); - gRange[1] *= lRange[1]; + inline void launch1D(int numThreads, int localSize = 64) + { + launch2D(numThreads, 1, localSize, 1); + } - cl_int status = clEnqueueNDRangeKernel( m_commandQueue, - m_kernel, 2, NULL, gRange, lRange, 0,0,0 ); - if (status != CL_SUCCESS) - { - printf("Error: OpenCL status = %d\n",status); - } - b3Assert( status == CL_SUCCESS ); + inline void launch2D(int numThreadsX, int numThreadsY, int localSizeX, int localSizeY) + { + size_t gRange[3] = {1, 1, 1}; + size_t lRange[3] = {1, 1, 1}; + lRange[0] = localSizeX; + lRange[1] = localSizeY; + gRange[0] = b3Max((size_t)1, (numThreadsX / lRange[0]) + (!(numThreadsX % lRange[0]) ? 0 : 1)); + gRange[0] *= lRange[0]; + gRange[1] = b3Max((size_t)1, (numThreadsY / lRange[1]) + (!(numThreadsY % lRange[1]) ? 0 : 1)); + gRange[1] *= lRange[1]; - } - - void enableSerialization(bool serialize) + cl_int status = clEnqueueNDRangeKernel(m_commandQueue, + m_kernel, 2, NULL, gRange, lRange, 0, 0, 0); + if (status != CL_SUCCESS) { - m_enableSerialization = serialize; + printf("Error: OpenCL status = %d\n", status); } - + b3Assert(status == CL_SUCCESS); + } + + void enableSerialization(bool serialize) + { + m_enableSerialization = serialize; + } }; - - -#endif //B3_LAUNCHER_CL_H +#endif //B3_LAUNCHER_CL_H diff --git a/src/Bullet3OpenCL/ParallelPrimitives/b3OpenCLArray.h b/src/Bullet3OpenCL/ParallelPrimitives/b3OpenCLArray.h index d70c30f53..e837cceb6 100644 --- a/src/Bullet3OpenCL/ParallelPrimitives/b3OpenCLArray.h +++ b/src/Bullet3OpenCL/ParallelPrimitives/b3OpenCLArray.h @@ -7,16 +7,16 @@ template class b3OpenCLArray { - size_t m_size; - size_t m_capacity; - cl_mem m_clBuffer; + size_t m_size; + size_t m_capacity; + cl_mem m_clBuffer; - cl_context m_clContext; + cl_context m_clContext; cl_command_queue m_commandQueue; - bool m_ownsMemory; + bool m_ownsMemory; - bool m_allowGrowingCapacity; + bool m_allowGrowingCapacity; void deallocate() { @@ -25,22 +25,19 @@ class b3OpenCLArray clReleaseMemObject(m_clBuffer); } m_clBuffer = 0; - m_capacity=0; + m_capacity = 0; } b3OpenCLArray& operator=(const b3OpenCLArray& src); - B3_FORCE_INLINE size_t allocSize(size_t size) - { - return (size ? size*2 : 1); - } + B3_FORCE_INLINE size_t allocSize(size_t size) + { + return (size ? size * 2 : 1); + } public: - - b3OpenCLArray(cl_context ctx, cl_command_queue queue, size_t initialCapacity=0, bool allowGrowingCapacity=true) - :m_size(0), m_capacity(0),m_clBuffer(0), - m_clContext(ctx),m_commandQueue(queue), - m_ownsMemory(true),m_allowGrowingCapacity(true) + b3OpenCLArray(cl_context ctx, cl_command_queue queue, size_t initialCapacity = 0, bool allowGrowingCapacity = true) + : m_size(0), m_capacity(0), m_clBuffer(0), m_clContext(ctx), m_commandQueue(queue), m_ownsMemory(true), m_allowGrowingCapacity(true) { if (initialCapacity) { @@ -60,34 +57,32 @@ public: m_capacity = sizeInElements; } -// we could enable this assignment, but need to make sure to avoid accidental deep copies -// b3OpenCLArray& operator=(const b3AlignedObjectArray& src) -// { -// copyFromArray(src); -// return *this; -// } + // we could enable this assignment, but need to make sure to avoid accidental deep copies + // b3OpenCLArray& operator=(const b3AlignedObjectArray& src) + // { + // copyFromArray(src); + // return *this; + // } - - cl_mem getBufferCL() const + cl_mem getBufferCL() const { return m_clBuffer; } - virtual ~b3OpenCLArray() { deallocate(); - m_size=0; - m_capacity=0; + m_size = 0; + m_capacity = 0; } - B3_FORCE_INLINE bool push_back(const T& _Val,bool waitForCompletion=true) + B3_FORCE_INLINE bool push_back(const T& _Val, bool waitForCompletion = true) { bool result = true; size_t sz = size(); - if( sz == capacity() ) + if (sz == capacity()) { - result = reserve( allocSize(size()) ); + result = reserve(allocSize(size())); } copyFromHostPointer(&_Val, 1, sz, waitForCompletion); m_size++; @@ -96,23 +91,23 @@ public: B3_FORCE_INLINE T forcedAt(size_t n) const { - b3Assert(n>=0); - b3Assert(n= 0); + b3Assert(n < capacity()); T elem; - copyToHostPointer(&elem,1,n,true); + copyToHostPointer(&elem, 1, n, true); return elem; } B3_FORCE_INLINE T at(size_t n) const { - b3Assert(n>=0); - b3Assert(n= 0); + b3Assert(n < size()); T elem; - copyToHostPointer(&elem,1,n,true); + copyToHostPointer(&elem, 1, n, true); return elem; } - B3_FORCE_INLINE bool resize(size_t newsize, bool copyOldContents=true) + B3_FORCE_INLINE bool resize(size_t newsize, bool copyOldContents = true) { bool result = true; size_t curSize = size(); @@ -120,11 +115,12 @@ public: if (newsize < curSize) { //leave the OpenCL memory for now - } else + } + else { if (newsize > size()) { - result = reserve(newsize,copyOldContents); + result = reserve(newsize, copyOldContents); } //leave new data uninitialized (init in debug mode?) @@ -134,7 +130,8 @@ public: if (result) { m_size = newsize; - } else + } + else { m_size = 0; } @@ -146,25 +143,25 @@ public: return m_size; } - B3_FORCE_INLINE size_t capacity() const + B3_FORCE_INLINE size_t capacity() const { return m_capacity; } - B3_FORCE_INLINE bool reserve(size_t _Count, bool copyOldContents=true) + B3_FORCE_INLINE bool reserve(size_t _Count, bool copyOldContents = true) { - bool result=true; + bool result = true; // determine new minimum length of allocated storage if (capacity() < _Count) - { // not enough room, reallocate + { // not enough room, reallocate if (m_allowGrowingCapacity) { cl_int ciErrNum; //create a new OpenCL buffer - size_t memSizeInBytes = sizeof(T)*_Count; + size_t memSizeInBytes = sizeof(T) * _Count; cl_mem buf = clCreateBuffer(m_clContext, CL_MEM_READ_WRITE, memSizeInBytes, NULL, &ciErrNum); - if (ciErrNum!=CL_SUCCESS) + if (ciErrNum != CL_SUCCESS) { b3Error("OpenCL out-of-memory\n"); _Count = 0; @@ -173,13 +170,13 @@ public: //#define B3_ALWAYS_INITIALIZE_OPENCL_BUFFERS #ifdef B3_ALWAYS_INITIALIZE_OPENCL_BUFFERS unsigned char* src = (unsigned char*)malloc(memSizeInBytes); - for (size_t i=0;i 0); + b3Assert(numElements <= m_size); - b3Assert(numElements>0); - b3Assert(numElements<=m_size); + size_t srcOffsetBytes = sizeof(T) * firstElem; + size_t dstOffsetInBytes = sizeof(T) * dstOffsetInElems; - size_t srcOffsetBytes = sizeof(T)*firstElem; - size_t dstOffsetInBytes = sizeof(T)*dstOffsetInElems; + status = clEnqueueCopyBuffer(m_commandQueue, m_clBuffer, destination, + srcOffsetBytes, dstOffsetInBytes, sizeof(T) * numElements, 0, 0, 0); - status = clEnqueueCopyBuffer( m_commandQueue, m_clBuffer, destination, - srcOffsetBytes, dstOffsetInBytes, sizeof(T)*numElements, 0, 0, 0 ); - - b3Assert( status == CL_SUCCESS ); + b3Assert(status == CL_SUCCESS); } - void copyFromHost(const b3AlignedObjectArray& srcArray, bool waitForCompletion=true) + void copyFromHost(const b3AlignedObjectArray& srcArray, bool waitForCompletion = true) { size_t newSize = srcArray.size(); bool copyOldContents = false; - resize (newSize,copyOldContents); + resize(newSize, copyOldContents); if (newSize) - copyFromHostPointer(&srcArray[0],newSize,0,waitForCompletion); - + copyFromHostPointer(&srcArray[0], newSize, 0, waitForCompletion); } - void copyFromHostPointer(const T* src, size_t numElems, size_t destFirstElem= 0, bool waitForCompletion=true) + void copyFromHostPointer(const T* src, size_t numElems, size_t destFirstElem = 0, bool waitForCompletion = true) { - b3Assert(numElems+destFirstElem <= capacity()); + b3Assert(numElems + destFirstElem <= capacity()); - if (numElems+destFirstElem) + if (numElems + destFirstElem) { cl_int status = 0; - size_t sizeInBytes=sizeof(T)*numElems; - status = clEnqueueWriteBuffer( m_commandQueue, m_clBuffer, 0, sizeof(T)*destFirstElem, sizeInBytes, - src, 0,0,0 ); - b3Assert(status == CL_SUCCESS ); + size_t sizeInBytes = sizeof(T) * numElems; + status = clEnqueueWriteBuffer(m_commandQueue, m_clBuffer, 0, sizeof(T) * destFirstElem, sizeInBytes, + src, 0, 0, 0); + b3Assert(status == CL_SUCCESS); if (waitForCompletion) clFinish(m_commandQueue); - } else + } + else { b3Error("copyFromHostPointer invalid range\n"); } } - - void copyToHost(b3AlignedObjectArray& destArray, bool waitForCompletion=true) const + void copyToHost(b3AlignedObjectArray& destArray, bool waitForCompletion = true) const { destArray.resize(this->size()); if (size()) - copyToHostPointer(&destArray[0], size(),0,waitForCompletion); + copyToHostPointer(&destArray[0], size(), 0, waitForCompletion); } - void copyToHostPointer(T* destPtr, size_t numElem, size_t srcFirstElem=0, bool waitForCompletion=true) const + void copyToHostPointer(T* destPtr, size_t numElem, size_t srcFirstElem = 0, bool waitForCompletion = true) const { - b3Assert(numElem+srcFirstElem <= capacity()); + b3Assert(numElem + srcFirstElem <= capacity()); - if(numElem+srcFirstElem <= capacity()) + if (numElem + srcFirstElem <= capacity()) { cl_int status = 0; - status = clEnqueueReadBuffer( m_commandQueue, m_clBuffer, 0, sizeof(T)*srcFirstElem, sizeof(T)*numElem, - destPtr, 0,0,0 ); - b3Assert( status==CL_SUCCESS ); + status = clEnqueueReadBuffer(m_commandQueue, m_clBuffer, 0, sizeof(T) * srcFirstElem, sizeof(T) * numElem, + destPtr, 0, 0, 0); + b3Assert(status == CL_SUCCESS); if (waitForCompletion) clFinish(m_commandQueue); - } else + } + else { b3Error("copyToHostPointer invalid range\n"); } @@ -296,11 +292,9 @@ public: resize(newSize); if (size()) { - src.copyToCL(m_clBuffer,size()); + src.copyToCL(m_clBuffer, size()); } } - }; - -#endif //B3_OPENCL_ARRAY_H +#endif //B3_OPENCL_ARRAY_H diff --git a/src/Bullet3OpenCL/ParallelPrimitives/b3PrefixScanCL.cpp b/src/Bullet3OpenCL/ParallelPrimitives/b3PrefixScanCL.cpp index 42cd19774..822b51163 100644 --- a/src/Bullet3OpenCL/ParallelPrimitives/b3PrefixScanCL.cpp +++ b/src/Bullet3OpenCL/ParallelPrimitives/b3PrefixScanCL.cpp @@ -7,25 +7,24 @@ #include "kernels/PrefixScanKernelsCL.h" b3PrefixScanCL::b3PrefixScanCL(cl_context ctx, cl_device_id device, cl_command_queue queue, int size) -:m_commandQueue(queue) + : m_commandQueue(queue) { const char* scanKernelSource = prefixScanKernelsCL; cl_int pErrNum; - char* additionalMacros=0; + char* additionalMacros = 0; - m_workBuffer = new b3OpenCLArray(ctx,queue,size); - cl_program scanProg = b3OpenCLUtils::compileCLProgramFromString( ctx, device, scanKernelSource, &pErrNum,additionalMacros, B3_PREFIXSCAN_PROG_PATH); + m_workBuffer = new b3OpenCLArray(ctx, queue, size); + cl_program scanProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, scanKernelSource, &pErrNum, additionalMacros, B3_PREFIXSCAN_PROG_PATH); b3Assert(scanProg); - m_localScanKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, scanKernelSource, "LocalScanKernel", &pErrNum, scanProg,additionalMacros ); - b3Assert(m_localScanKernel ); - m_blockSumKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, scanKernelSource, "TopLevelScanKernel", &pErrNum, scanProg,additionalMacros ); - b3Assert(m_blockSumKernel ); - m_propagationKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, scanKernelSource, "AddOffsetKernel", &pErrNum, scanProg,additionalMacros ); - b3Assert(m_propagationKernel ); + m_localScanKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, scanKernelSource, "LocalScanKernel", &pErrNum, scanProg, additionalMacros); + b3Assert(m_localScanKernel); + m_blockSumKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, scanKernelSource, "TopLevelScanKernel", &pErrNum, scanProg, additionalMacros); + b3Assert(m_blockSumKernel); + m_propagationKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, scanKernelSource, "AddOffsetKernel", &pErrNum, scanProg, additionalMacros); + b3Assert(m_propagationKernel); } - b3PrefixScanCL::~b3PrefixScanCL() { delete m_workBuffer; @@ -34,20 +33,19 @@ b3PrefixScanCL::~b3PrefixScanCL() clReleaseKernel(m_propagationKernel); } -template +template T b3NextPowerOf2(T n) { n -= 1; - for(int i=0; i>i); - return n+1; + for (int i = 0; i < sizeof(T) * 8; i++) + n = n | (n >> i); + return n + 1; } void b3PrefixScanCL::execute(b3OpenCLArray& src, b3OpenCLArray& dst, int n, unsigned int* sum) { - -// b3Assert( data->m_option == EXCLUSIVE ); - const unsigned int numBlocks = (const unsigned int)( (n+BLOCK_SIZE*2-1)/(BLOCK_SIZE*2) ); + // b3Assert( data->m_option == EXCLUSIVE ); + const unsigned int numBlocks = (const unsigned int)((n + BLOCK_SIZE * 2 - 1) / (BLOCK_SIZE * 2)); dst.resize(src.size()); m_workBuffer->resize(src.size()); @@ -55,55 +53,51 @@ void b3PrefixScanCL::execute(b3OpenCLArray& src, b3OpenCLArray* srcNative = &src; b3OpenCLArray* dstNative = &dst; - - { - b3BufferInfoCL bInfo[] = { b3BufferInfoCL( dstNative->getBufferCL() ), b3BufferInfoCL( srcNative->getBufferCL() ), b3BufferInfoCL( m_workBuffer->getBufferCL() ) }; - b3LauncherCL launcher( m_commandQueue, m_localScanKernel,"m_localScanKernel" ); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( constBuffer ); - launcher.launch1D( numBlocks*BLOCK_SIZE, BLOCK_SIZE ); + { + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(dstNative->getBufferCL()), b3BufferInfoCL(srcNative->getBufferCL()), b3BufferInfoCL(m_workBuffer->getBufferCL())}; + + b3LauncherCL launcher(m_commandQueue, m_localScanKernel, "m_localScanKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(constBuffer); + launcher.launch1D(numBlocks * BLOCK_SIZE, BLOCK_SIZE); } { - b3BufferInfoCL bInfo[] = { b3BufferInfoCL( m_workBuffer->getBufferCL() ) }; + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(m_workBuffer->getBufferCL())}; - b3LauncherCL launcher( m_commandQueue, m_blockSumKernel,"m_blockSumKernel" ); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( constBuffer ); - launcher.launch1D( BLOCK_SIZE, BLOCK_SIZE ); + b3LauncherCL launcher(m_commandQueue, m_blockSumKernel, "m_blockSumKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(constBuffer); + launcher.launch1D(BLOCK_SIZE, BLOCK_SIZE); } - - if( numBlocks > 1 ) + if (numBlocks > 1) { - b3BufferInfoCL bInfo[] = { b3BufferInfoCL( dstNative->getBufferCL() ), b3BufferInfoCL( m_workBuffer->getBufferCL() ) }; - b3LauncherCL launcher( m_commandQueue, m_propagationKernel,"m_propagationKernel" ); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( constBuffer ); - launcher.launch1D( (numBlocks-1)*BLOCK_SIZE, BLOCK_SIZE ); + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(dstNative->getBufferCL()), b3BufferInfoCL(m_workBuffer->getBufferCL())}; + b3LauncherCL launcher(m_commandQueue, m_propagationKernel, "m_propagationKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(constBuffer); + launcher.launch1D((numBlocks - 1) * BLOCK_SIZE, BLOCK_SIZE); } - - if( sum ) + if (sum) { clFinish(m_commandQueue); - dstNative->copyToHostPointer(sum,1,n-1,true); + dstNative->copyToHostPointer(sum, 1, n - 1, true); } - } - void b3PrefixScanCL::executeHost(b3AlignedObjectArray& src, b3AlignedObjectArray& dst, int n, unsigned int* sum) { unsigned int s = 0; //if( data->m_option == EXCLUSIVE ) { - for(int i=0; i& src, b3Alig } */ - if( sum ) + if (sum) { - *sum = dst[n-1]; + *sum = dst[n - 1]; } } \ No newline at end of file diff --git a/src/Bullet3OpenCL/ParallelPrimitives/b3PrefixScanCL.h b/src/Bullet3OpenCL/ParallelPrimitives/b3PrefixScanCL.h index a9a2e61b9..346efa0c7 100644 --- a/src/Bullet3OpenCL/ParallelPrimitives/b3PrefixScanCL.h +++ b/src/Bullet3OpenCL/ParallelPrimitives/b3PrefixScanCL.h @@ -13,9 +13,9 @@ class b3PrefixScanCL BLOCK_SIZE = 128 }; -// Option m_option; + // Option m_option; - cl_command_queue m_commandQueue; + cl_command_queue m_commandQueue; cl_kernel m_localScanKernel; cl_kernel m_blockSumKernel; @@ -23,15 +23,13 @@ class b3PrefixScanCL b3OpenCLArray* m_workBuffer; - - public: - - b3PrefixScanCL(cl_context ctx, cl_device_id device, cl_command_queue queue,int size=0); +public: + b3PrefixScanCL(cl_context ctx, cl_device_id device, cl_command_queue queue, int size = 0); virtual ~b3PrefixScanCL(); void execute(b3OpenCLArray& src, b3OpenCLArray& dst, int n, unsigned int* sum = 0); - void executeHost(b3AlignedObjectArray& src, b3AlignedObjectArray& dst, int n, unsigned int* sum=0); + void executeHost(b3AlignedObjectArray& src, b3AlignedObjectArray& dst, int n, unsigned int* sum = 0); }; -#endif //B3_PREFIX_SCAN_CL_H +#endif //B3_PREFIX_SCAN_CL_H diff --git a/src/Bullet3OpenCL/ParallelPrimitives/b3PrefixScanFloat4CL.cpp b/src/Bullet3OpenCL/ParallelPrimitives/b3PrefixScanFloat4CL.cpp index 80560d793..1cac97c98 100644 --- a/src/Bullet3OpenCL/ParallelPrimitives/b3PrefixScanFloat4CL.cpp +++ b/src/Bullet3OpenCL/ParallelPrimitives/b3PrefixScanFloat4CL.cpp @@ -7,25 +7,24 @@ #include "kernels/PrefixScanKernelsFloat4CL.h" b3PrefixScanFloat4CL::b3PrefixScanFloat4CL(cl_context ctx, cl_device_id device, cl_command_queue queue, int size) -:m_commandQueue(queue) + : m_commandQueue(queue) { const char* scanKernelSource = prefixScanKernelsFloat4CL; cl_int pErrNum; - char* additionalMacros=0; + char* additionalMacros = 0; - m_workBuffer = new b3OpenCLArray(ctx,queue,size); - cl_program scanProg = b3OpenCLUtils::compileCLProgramFromString( ctx, device, scanKernelSource, &pErrNum,additionalMacros, B3_PREFIXSCAN_FLOAT4_PROG_PATH); + m_workBuffer = new b3OpenCLArray(ctx, queue, size); + cl_program scanProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, scanKernelSource, &pErrNum, additionalMacros, B3_PREFIXSCAN_FLOAT4_PROG_PATH); b3Assert(scanProg); - m_localScanKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, scanKernelSource, "LocalScanKernel", &pErrNum, scanProg,additionalMacros ); - b3Assert(m_localScanKernel ); - m_blockSumKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, scanKernelSource, "TopLevelScanKernel", &pErrNum, scanProg,additionalMacros ); - b3Assert(m_blockSumKernel ); - m_propagationKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, scanKernelSource, "AddOffsetKernel", &pErrNum, scanProg,additionalMacros ); - b3Assert(m_propagationKernel ); + m_localScanKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, scanKernelSource, "LocalScanKernel", &pErrNum, scanProg, additionalMacros); + b3Assert(m_localScanKernel); + m_blockSumKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, scanKernelSource, "TopLevelScanKernel", &pErrNum, scanProg, additionalMacros); + b3Assert(m_blockSumKernel); + m_propagationKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, scanKernelSource, "AddOffsetKernel", &pErrNum, scanProg, additionalMacros); + b3Assert(m_propagationKernel); } - b3PrefixScanFloat4CL::~b3PrefixScanFloat4CL() { delete m_workBuffer; @@ -34,20 +33,19 @@ b3PrefixScanFloat4CL::~b3PrefixScanFloat4CL() clReleaseKernel(m_propagationKernel); } -template +template T b3NextPowerOf2(T n) { n -= 1; - for(int i=0; i>i); - return n+1; + for (int i = 0; i < sizeof(T) * 8; i++) + n = n | (n >> i); + return n + 1; } void b3PrefixScanFloat4CL::execute(b3OpenCLArray& src, b3OpenCLArray& dst, int n, b3Vector3* sum) { - -// b3Assert( data->m_option == EXCLUSIVE ); - const unsigned int numBlocks = (const unsigned int)( (n+BLOCK_SIZE*2-1)/(BLOCK_SIZE*2) ); + // b3Assert( data->m_option == EXCLUSIVE ); + const unsigned int numBlocks = (const unsigned int)((n + BLOCK_SIZE * 2 - 1) / (BLOCK_SIZE * 2)); dst.resize(src.size()); m_workBuffer->resize(src.size()); @@ -55,55 +53,51 @@ void b3PrefixScanFloat4CL::execute(b3OpenCLArray& src, b3OpenCLArray< b3Int4 constBuffer; constBuffer.x = n; constBuffer.y = numBlocks; - constBuffer.z = (int)b3NextPowerOf2( numBlocks ); + constBuffer.z = (int)b3NextPowerOf2(numBlocks); b3OpenCLArray* srcNative = &src; b3OpenCLArray* dstNative = &dst; - - { - b3BufferInfoCL bInfo[] = { b3BufferInfoCL( dstNative->getBufferCL() ), b3BufferInfoCL( srcNative->getBufferCL() ), b3BufferInfoCL( m_workBuffer->getBufferCL() ) }; - b3LauncherCL launcher( m_commandQueue, m_localScanKernel ,"m_localScanKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( constBuffer ); - launcher.launch1D( numBlocks*BLOCK_SIZE, BLOCK_SIZE ); + { + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(dstNative->getBufferCL()), b3BufferInfoCL(srcNative->getBufferCL()), b3BufferInfoCL(m_workBuffer->getBufferCL())}; + + b3LauncherCL launcher(m_commandQueue, m_localScanKernel, "m_localScanKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(constBuffer); + launcher.launch1D(numBlocks * BLOCK_SIZE, BLOCK_SIZE); } { - b3BufferInfoCL bInfo[] = { b3BufferInfoCL( m_workBuffer->getBufferCL() ) }; + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(m_workBuffer->getBufferCL())}; - b3LauncherCL launcher( m_commandQueue, m_blockSumKernel ,"m_blockSumKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( constBuffer ); - launcher.launch1D( BLOCK_SIZE, BLOCK_SIZE ); + b3LauncherCL launcher(m_commandQueue, m_blockSumKernel, "m_blockSumKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(constBuffer); + launcher.launch1D(BLOCK_SIZE, BLOCK_SIZE); } - - if( numBlocks > 1 ) + if (numBlocks > 1) { - b3BufferInfoCL bInfo[] = { b3BufferInfoCL( dstNative->getBufferCL() ), b3BufferInfoCL( m_workBuffer->getBufferCL() ) }; - b3LauncherCL launcher( m_commandQueue, m_propagationKernel ,"m_propagationKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( constBuffer ); - launcher.launch1D( (numBlocks-1)*BLOCK_SIZE, BLOCK_SIZE ); + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(dstNative->getBufferCL()), b3BufferInfoCL(m_workBuffer->getBufferCL())}; + b3LauncherCL launcher(m_commandQueue, m_propagationKernel, "m_propagationKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(constBuffer); + launcher.launch1D((numBlocks - 1) * BLOCK_SIZE, BLOCK_SIZE); } - - if( sum ) + if (sum) { clFinish(m_commandQueue); - dstNative->copyToHostPointer(sum,1,n-1,true); + dstNative->copyToHostPointer(sum, 1, n - 1, true); } - } - void b3PrefixScanFloat4CL::executeHost(b3AlignedObjectArray& src, b3AlignedObjectArray& dst, int n, b3Vector3* sum) { - b3Vector3 s=b3MakeVector3(0,0,0); + b3Vector3 s = b3MakeVector3(0, 0, 0); //if( data->m_option == EXCLUSIVE ) { - for(int i=0; i& src, b3A } */ - if( sum ) + if (sum) { - *sum = dst[n-1]; + *sum = dst[n - 1]; } } \ No newline at end of file diff --git a/src/Bullet3OpenCL/ParallelPrimitives/b3PrefixScanFloat4CL.h b/src/Bullet3OpenCL/ParallelPrimitives/b3PrefixScanFloat4CL.h index 2c8003c1b..122b0bfd6 100644 --- a/src/Bullet3OpenCL/ParallelPrimitives/b3PrefixScanFloat4CL.h +++ b/src/Bullet3OpenCL/ParallelPrimitives/b3PrefixScanFloat4CL.h @@ -14,9 +14,9 @@ class b3PrefixScanFloat4CL BLOCK_SIZE = 128 }; -// Option m_option; + // Option m_option; - cl_command_queue m_commandQueue; + cl_command_queue m_commandQueue; cl_kernel m_localScanKernel; cl_kernel m_blockSumKernel; @@ -24,10 +24,8 @@ class b3PrefixScanFloat4CL b3OpenCLArray* m_workBuffer; - - public: - - b3PrefixScanFloat4CL(cl_context ctx, cl_device_id device, cl_command_queue queue,int size=0); +public: + b3PrefixScanFloat4CL(cl_context ctx, cl_device_id device, cl_command_queue queue, int size = 0); virtual ~b3PrefixScanFloat4CL(); @@ -35,4 +33,4 @@ class b3PrefixScanFloat4CL void executeHost(b3AlignedObjectArray& src, b3AlignedObjectArray& dst, int n, b3Vector3* sum); }; -#endif //B3_PREFIX_SCAN_CL_H +#endif //B3_PREFIX_SCAN_CL_H diff --git a/src/Bullet3OpenCL/ParallelPrimitives/b3RadixSort32CL.cpp b/src/Bullet3OpenCL/ParallelPrimitives/b3RadixSort32CL.cpp index f11ae4bcd..e86af6583 100644 --- a/src/Bullet3OpenCL/ParallelPrimitives/b3RadixSort32CL.cpp +++ b/src/Bullet3OpenCL/ParallelPrimitives/b3RadixSort32CL.cpp @@ -10,21 +10,20 @@ #include "kernels/RadixSort32KernelsCL.h" b3RadixSort32CL::b3RadixSort32CL(cl_context ctx, cl_device_id device, cl_command_queue queue, int initialCapacity) -:m_commandQueue(queue) + : m_commandQueue(queue) { b3OpenCLDeviceInfo info; - b3OpenCLUtils::getDeviceInfo(device,&info); - m_deviceCPU = (info.m_deviceType & CL_DEVICE_TYPE_CPU)!=0; + b3OpenCLUtils::getDeviceInfo(device, &info); + m_deviceCPU = (info.m_deviceType & CL_DEVICE_TYPE_CPU) != 0; - m_workBuffer1 = new b3OpenCLArray(ctx,queue); - m_workBuffer2 = new b3OpenCLArray(ctx,queue); - m_workBuffer3 = new b3OpenCLArray(ctx,queue); - m_workBuffer3a = new b3OpenCLArray(ctx,queue); - m_workBuffer4 = new b3OpenCLArray(ctx,queue); - m_workBuffer4a = new b3OpenCLArray(ctx,queue); + m_workBuffer1 = new b3OpenCLArray(ctx, queue); + m_workBuffer2 = new b3OpenCLArray(ctx, queue); + m_workBuffer3 = new b3OpenCLArray(ctx, queue); + m_workBuffer3a = new b3OpenCLArray(ctx, queue); + m_workBuffer4 = new b3OpenCLArray(ctx, queue); + m_workBuffer4a = new b3OpenCLArray(ctx, queue); - - if (initialCapacity>0) + if (initialCapacity > 0) { m_workBuffer1->resize(initialCapacity); m_workBuffer3->resize(initialCapacity); @@ -33,45 +32,40 @@ b3RadixSort32CL::b3RadixSort32CL(cl_context ctx, cl_device_id device, cl_command m_workBuffer4a->resize(initialCapacity); } - m_scan = new b3PrefixScanCL(ctx,device,queue); - m_fill = new b3FillCL(ctx,device,queue); - + m_scan = new b3PrefixScanCL(ctx, device, queue); + m_fill = new b3FillCL(ctx, device, queue); + const char* additionalMacros = ""; cl_int pErrNum; const char* kernelSource = radixSort32KernelsCL; - - cl_program sortProg = b3OpenCLUtils::compileCLProgramFromString( ctx, device, kernelSource, &pErrNum,additionalMacros, RADIXSORT32_PATH); + + cl_program sortProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, kernelSource, &pErrNum, additionalMacros, RADIXSORT32_PATH); b3Assert(sortProg); - m_streamCountSortDataKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "StreamCountSortDataKernel", &pErrNum, sortProg,additionalMacros ); - b3Assert(m_streamCountSortDataKernel ); + m_streamCountSortDataKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, kernelSource, "StreamCountSortDataKernel", &pErrNum, sortProg, additionalMacros); + b3Assert(m_streamCountSortDataKernel); - - - m_streamCountKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "StreamCountKernel", &pErrNum, sortProg,additionalMacros ); + m_streamCountKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, kernelSource, "StreamCountKernel", &pErrNum, sortProg, additionalMacros); b3Assert(m_streamCountKernel); - - if (m_deviceCPU) { - - m_sortAndScatterSortDataKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "SortAndScatterSortDataKernelSerial", &pErrNum, sortProg,additionalMacros ); + m_sortAndScatterSortDataKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, kernelSource, "SortAndScatterSortDataKernelSerial", &pErrNum, sortProg, additionalMacros); b3Assert(m_sortAndScatterSortDataKernel); - m_sortAndScatterKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "SortAndScatterKernelSerial", &pErrNum, sortProg,additionalMacros ); - b3Assert(m_sortAndScatterKernel); - } else - { - m_sortAndScatterSortDataKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "SortAndScatterSortDataKernel", &pErrNum, sortProg,additionalMacros ); - b3Assert(m_sortAndScatterSortDataKernel); - m_sortAndScatterKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "SortAndScatterKernel", &pErrNum, sortProg,additionalMacros ); + m_sortAndScatterKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, kernelSource, "SortAndScatterKernelSerial", &pErrNum, sortProg, additionalMacros); b3Assert(m_sortAndScatterKernel); } - - m_prefixScanKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, kernelSource, "PrefixScanKernel", &pErrNum, sortProg,additionalMacros ); + else + { + m_sortAndScatterSortDataKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, kernelSource, "SortAndScatterSortDataKernel", &pErrNum, sortProg, additionalMacros); + b3Assert(m_sortAndScatterSortDataKernel); + m_sortAndScatterKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, kernelSource, "SortAndScatterKernel", &pErrNum, sortProg, additionalMacros); + b3Assert(m_sortAndScatterKernel); + } + + m_prefixScanKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, kernelSource, "PrefixScanKernel", &pErrNum, sortProg, additionalMacros); b3Assert(m_prefixScanKernel); - } b3RadixSort32CL::~b3RadixSort32CL() @@ -96,8 +90,7 @@ void b3RadixSort32CL::executeHost(b3AlignedObjectArray& inout, int s { int n = inout.size(); const int BITS_PER_PASS = 8; - const int NUM_TABLES = (1<& inout, int s workbuffer.resize(inout.size()); b3SortData* dst = &workbuffer[0]; - int count=0; - for(int startBit=0; startBit> startBit) & (NUM_TABLES-1); + int tableIdx = (src[i].m_key >> startBit) & (NUM_TABLES - 1); tables[tableIdx]++; } //#define TEST #ifdef TEST - printf("histogram size=%d\n",NUM_TABLES); - for (int i=0;i& inout, int s } // distribute - for(int i=0; i> startBit) & (NUM_TABLES-1); - + int tableIdx = (src[i].m_key >> startBit) & (NUM_TABLES - 1); + dst[tables[tableIdx] + counter[tableIdx]] = src[i]; - counter[tableIdx] ++; + counter[tableIdx]++; } - b3Swap( src, dst ); + b3Swap(src, dst); count++; } - if (count&1) + if (count & 1) { - b3Assert(0);//need to copy - + b3Assert(0); //need to copy } } void b3RadixSort32CL::executeHost(b3OpenCLArray& keyValuesInOut, int sortBits /* = 32 */) { - b3AlignedObjectArray inout; keyValuesInOut.copyToHost(inout); - executeHost(inout,sortBits); + executeHost(inout, sortBits); keyValuesInOut.copyFromHost(inout); } -void b3RadixSort32CL::execute(b3OpenCLArray& keysIn, b3OpenCLArray& keysOut, b3OpenCLArray& valuesIn, - b3OpenCLArray& valuesOut, int n, int sortBits) +void b3RadixSort32CL::execute(b3OpenCLArray& keysIn, b3OpenCLArray& keysOut, b3OpenCLArray& valuesIn, + b3OpenCLArray& valuesOut, int n, int sortBits) { - } //#define DEBUG_RADIXSORT //#define DEBUG_RADIXSORT2 - void b3RadixSort32CL::execute(b3OpenCLArray& keyValuesInOut, int sortBits /* = 32 */) { - int originalSize = keyValuesInOut.size(); int workingSize = originalSize; - - + int dataAlignment = DATA_ALIGNMENT; #ifdef DEBUG_RADIXSORT2 - b3AlignedObjectArray test2; - keyValuesInOut.copyToHost(test2); - printf("numElem = %d\n",test2.size()); - for (int i=0;i test2; + keyValuesInOut.copyToHost(test2); + printf("numElem = %d\n", test2.size()); + for (int i = 0; i < test2.size(); i++) + { + printf("test2[%d].m_key=%d\n", i, test2[i].m_key); + printf("test2[%d].m_value=%d\n", i, test2[i].m_value); + } +#endif //DEBUG_RADIXSORT2 + b3OpenCLArray* src = 0; - if (workingSize%dataAlignment) + if (workingSize % dataAlignment) { - workingSize += dataAlignment-(workingSize%dataAlignment); + workingSize += dataAlignment - (workingSize % dataAlignment); m_workBuffer4->copyFromOpenCLArray(keyValuesInOut); m_workBuffer4->resize(workingSize); b3SortData fillValue; @@ -216,327 +202,301 @@ void b3RadixSort32CL::execute(b3OpenCLArray& keyValuesInOut, int sor #define USE_BTFILL #ifdef USE_BTFILL - m_fill->execute((b3OpenCLArray&)*m_workBuffer4,(b3Int2&)fillValue,workingSize-originalSize,originalSize); + m_fill->execute((b3OpenCLArray&)*m_workBuffer4, (b3Int2&)fillValue, workingSize - originalSize, originalSize); #else //fill the remaining bits (very slow way, todo: fill on GPU/OpenCL side) - - for (int i=originalSize; icopyFromHostPointer(&fillValue,1,i); + m_workBuffer4->copyFromHostPointer(&fillValue, 1, i); } -#endif//USE_BTFILL +#endif //USE_BTFILL src = m_workBuffer4; - } else + } + else { src = &keyValuesInOut; m_workBuffer4->resize(0); } - - b3Assert( workingSize%DATA_ALIGNMENT == 0 ); - int minCap = NUM_BUCKET*NUM_WGS; + b3Assert(workingSize % DATA_ALIGNMENT == 0); + int minCap = NUM_BUCKET * NUM_WGS; int n = workingSize; m_workBuffer1->resize(minCap); m_workBuffer3->resize(workingSize); - -// ADLASSERT( ELEMENTS_PER_WORK_ITEM == 4 ); - b3Assert( BITS_PER_PASS == 4 ); - b3Assert( WG_SIZE == 64 ); - b3Assert( (sortBits&0x3) == 0 ); + // ADLASSERT( ELEMENTS_PER_WORK_ITEM == 4 ); + b3Assert(BITS_PER_PASS == 4); + b3Assert(WG_SIZE == 64); + b3Assert((sortBits & 0x3) == 0); - - b3OpenCLArray* dst = m_workBuffer3; b3OpenCLArray* srcHisto = m_workBuffer1; b3OpenCLArray* destHisto = m_workBuffer2; - int nWGs = NUM_WGS; b3ConstData cdata; { - int blockSize = ELEMENTS_PER_WORK_ITEM*WG_SIZE;//set at 256 - int nBlocks = (n+blockSize-1)/(blockSize); + int blockSize = ELEMENTS_PER_WORK_ITEM * WG_SIZE; //set at 256 + int nBlocks = (n + blockSize - 1) / (blockSize); cdata.m_n = n; cdata.m_nWGs = NUM_WGS; cdata.m_startBit = 0; - cdata.m_nBlocksPerWG = (nBlocks + cdata.m_nWGs - 1)/cdata.m_nWGs; - if( nBlocks < NUM_WGS ) + cdata.m_nBlocksPerWG = (nBlocks + cdata.m_nWGs - 1) / cdata.m_nWGs; + if (nBlocks < NUM_WGS) { cdata.m_nBlocksPerWG = 1; nWGs = nBlocks; } } - int count=0; - for(int ib=0; ibsize()) { - b3BufferInfoCL bInfo[] = { b3BufferInfoCL( src->getBufferCL(), true ), b3BufferInfoCL( srcHisto->getBufferCL() ) }; - b3LauncherCL launcher(m_commandQueue, m_streamCountSortDataKernel,"m_streamCountSortDataKernel"); + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(src->getBufferCL(), true), b3BufferInfoCL(srcHisto->getBufferCL())}; + b3LauncherCL launcher(m_commandQueue, m_streamCountSortDataKernel, "m_streamCountSortDataKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( cdata ); - - int num = NUM_WGS*WG_SIZE; - launcher.launch1D( num, WG_SIZE ); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(cdata); + + int num = NUM_WGS * WG_SIZE; + launcher.launch1D(num, WG_SIZE); } - - #ifdef DEBUG_RADIXSORT b3AlignedObjectArray testHist; srcHisto->copyToHost(testHist); - printf("ib = %d, testHist size = %d, non zero elements:\n",ib, testHist.size()); - for (int i=0;igetBufferCL() ) }; - b3LauncherCL launcher( m_commandQueue, m_prefixScanKernel,"m_prefixScanKernel" ); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( cdata ); - launcher.launch1D( 128, 128 ); + { // prefix scan group histogram + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(srcHisto->getBufferCL())}; + b3LauncherCL launcher(m_commandQueue, m_prefixScanKernel, "m_prefixScanKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(cdata); + launcher.launch1D(128, 128); destHisto = srcHisto; - }else + } + else { //unsigned int sum; //for debugging - m_scan->execute(*srcHisto,*destHisto,1920,0);//,&sum); + m_scan->execute(*srcHisto, *destHisto, 1920, 0); //,&sum); } - #ifdef DEBUG_RADIXSORT destHisto->copyToHost(testHist); - printf("ib = %d, testHist size = %d, non zero elements:\n",ib, testHist.size()); - for (int i=0;isize()) - {// local sort and distribute - b3BufferInfoCL bInfo[] = { b3BufferInfoCL( src->getBufferCL(), true ), b3BufferInfoCL( destHisto->getBufferCL(), true ), b3BufferInfoCL( dst->getBufferCL() )}; - b3LauncherCL launcher( m_commandQueue, m_sortAndScatterSortDataKernel,"m_sortAndScatterSortDataKernel" ); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( cdata ); - launcher.launch1D( nWGs*WG_SIZE, WG_SIZE ); - + { // local sort and distribute + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(src->getBufferCL(), true), b3BufferInfoCL(destHisto->getBufferCL(), true), b3BufferInfoCL(dst->getBufferCL())}; + b3LauncherCL launcher(m_commandQueue, m_sortAndScatterSortDataKernel, "m_sortAndScatterSortDataKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(cdata); + launcher.launch1D(nWGs * WG_SIZE, WG_SIZE); } #else - { + { #define NUM_TABLES 16 //#define SEQUENTIAL #ifdef SEQUENTIAL - int counter2[NUM_TABLES]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - int tables[NUM_TABLES]; - int startBit = ib; - - destHisto->copyToHost(testHist); - b3AlignedObjectArray srcHost; - b3AlignedObjectArray dstHost; - dstHost.resize(src->size()); - - src->copyToHost(srcHost); - - for (int i=0;i> startBit) & (NUM_TABLES-1); - - dstHost[tables[tableIdx] + counter2[tableIdx]] = srcHost[i]; - counter2[tableIdx] ++; - } - - + int counter2[NUM_TABLES] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int tables[NUM_TABLES]; + int startBit = ib; + + destHisto->copyToHost(testHist); + b3AlignedObjectArray srcHost; + b3AlignedObjectArray dstHost; + dstHost.resize(src->size()); + + src->copyToHost(srcHost); + + for (int i = 0; i < NUM_TABLES; i++) + { + tables[i] = testHist[i * NUM_WGS]; + } + + // distribute + for (int i = 0; i < n; i++) + { + int tableIdx = (srcHost[i].m_key >> startBit) & (NUM_TABLES - 1); + + dstHost[tables[tableIdx] + counter2[tableIdx]] = srcHost[i]; + counter2[tableIdx]++; + } + #else - - int counter2[NUM_TABLES]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - - int tables[NUM_TABLES]; - b3AlignedObjectArray dstHostOK; - dstHostOK.resize(src->size()); - destHisto->copyToHost(testHist); - b3AlignedObjectArray srcHost; - src->copyToHost(srcHost); - - int blockSize = 256; - int nBlocksPerWG = cdata.m_nBlocksPerWG; - int startBit = ib; + int counter2[NUM_TABLES] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - { - for (int i=0;i> startBit) & (NUM_TABLES-1); - - dstHostOK[tables[tableIdx] + counter2[tableIdx]] = srcHost[i]; - counter2[tableIdx] ++; - } + int tables[NUM_TABLES]; + b3AlignedObjectArray dstHostOK; + dstHostOK.resize(src->size()); - - } - - - b3AlignedObjectArray dstHost; - dstHost.resize(src->size()); - - - int counter[NUM_TABLES]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - - - - for (int wgIdx=0;wgIdxcopyToHost(testHist); + b3AlignedObjectArray srcHost; + src->copyToHost(srcHost); - int nBlocks = (n)/blockSize - nBlocksPerWG*wgIdx; - - for(int iblock=0; iblock> startBit) & (NUM_TABLES-1); - - int destIndex = testHist[tableIdx*NUM_WGS+wgIdx] + counter[tableIdx]; - - b3SortData ok = dstHostOK[destIndex]; - - if (ok.m_key != srcHost[i].m_key) - { - printf("ok.m_key = %d, srcHost[i].m_key = %d\n", ok.m_key,srcHost[i].m_key ); - printf("(ok.m_value = %d, srcHost[i].m_value = %d)\n", ok.m_value,srcHost[i].m_value ); - } - if (ok.m_value != srcHost[i].m_value) - { - - printf("ok.m_value = %d, srcHost[i].m_value = %d\n", ok.m_value,srcHost[i].m_value ); - printf("(ok.m_key = %d, srcHost[i].m_key = %d)\n", ok.m_key,srcHost[i].m_key ); + int blockSize = 256; + int nBlocksPerWG = cdata.m_nBlocksPerWG; + int startBit = ib; + + { + for (int i = 0; i < NUM_TABLES; i++) + { + tables[i] = testHist[i * NUM_WGS]; + } + + // distribute + for (int i = 0; i < n; i++) + { + int tableIdx = (srcHost[i].m_key >> startBit) & (NUM_TABLES - 1); + + dstHostOK[tables[tableIdx] + counter2[tableIdx]] = srcHost[i]; + counter2[tableIdx]++; + } + } + + b3AlignedObjectArray dstHost; + dstHost.resize(src->size()); + + int counter[NUM_TABLES] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + for (int wgIdx = 0; wgIdx < NUM_WGS; wgIdx++) + { + int counter[NUM_TABLES] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + + int nBlocks = (n) / blockSize - nBlocksPerWG * wgIdx; + + for (int iblock = 0; iblock < b3Min(cdata.m_nBlocksPerWG, nBlocks); iblock++) + { + for (int lIdx = 0; lIdx < 64; lIdx++) + { + int addr = iblock * blockSize + blockSize * cdata.m_nBlocksPerWG * wgIdx + ELEMENTS_PER_WORK_ITEM * lIdx; + + // MY_HISTOGRAM( localKeys.x ) ++ is much expensive than atomic add as it requires read and write while atomics can just add on AMD + // Using registers didn't perform well. It seems like use localKeys to address requires a lot of alu ops + // AMD: AtomInc performs better while NV prefers ++ + for (int j = 0; j < ELEMENTS_PER_WORK_ITEM; j++) + { + if (addr + j < n) + { + // printf ("addr+j=%d\n", addr+j); + + int i = addr + j; + + int tableIdx = (srcHost[i].m_key >> startBit) & (NUM_TABLES - 1); + + int destIndex = testHist[tableIdx * NUM_WGS + wgIdx] + counter[tableIdx]; + + b3SortData ok = dstHostOK[destIndex]; + + if (ok.m_key != srcHost[i].m_key) + { + printf("ok.m_key = %d, srcHost[i].m_key = %d\n", ok.m_key, srcHost[i].m_key); + printf("(ok.m_value = %d, srcHost[i].m_value = %d)\n", ok.m_value, srcHost[i].m_value); + } + if (ok.m_value != srcHost[i].m_value) + { + printf("ok.m_value = %d, srcHost[i].m_value = %d\n", ok.m_value, srcHost[i].m_value); + printf("(ok.m_key = %d, srcHost[i].m_key = %d)\n", ok.m_key, srcHost[i].m_key); + } + + dstHost[destIndex] = srcHost[i]; + counter[tableIdx]++; + } + } + } + } + } + +#endif //SEQUENTIAL + + dst->copyFromHost(dstHost); + } +#endif //USE_GPU - } - - dstHost[destIndex] = srcHost[i]; - counter[tableIdx] ++; - - } - } - } - } - } - - -#endif //SEQUENTIAL - - dst->copyFromHost(dstHost); - } -#endif//USE_GPU - - - #ifdef DEBUG_RADIXSORT destHisto->copyToHost(testHist); - printf("ib = %d, testHist size = %d, non zero elements:\n",ib, testHist.size()); - for (int i=0;isize()) @@ -545,153 +505,137 @@ void b3RadixSort32CL::execute(b3OpenCLArray& keyValuesInOut, int sor keyValuesInOut.copyFromOpenCLArray(*m_workBuffer4); } - #ifdef DEBUG_RADIXSORT - keyValuesInOut.copyToHost(test2); - - printf("numElem = %d\n",test2.size()); - for (int i=0;i& keysInOut, int sortBits /* = 32 */) { int originalSize = keysInOut.size(); int workingSize = originalSize; - - + int dataAlignment = DATA_ALIGNMENT; b3OpenCLArray* src = 0; - if (workingSize%dataAlignment) + if (workingSize % dataAlignment) { - workingSize += dataAlignment-(workingSize%dataAlignment); + workingSize += dataAlignment - (workingSize % dataAlignment); m_workBuffer4a->copyFromOpenCLArray(keysInOut); m_workBuffer4a->resize(workingSize); unsigned int fillValue = 0xffffffff; - - m_fill->execute(*m_workBuffer4a,fillValue,workingSize-originalSize,originalSize); + + m_fill->execute(*m_workBuffer4a, fillValue, workingSize - originalSize, originalSize); src = m_workBuffer4a; - } else + } + else { src = &keysInOut; m_workBuffer4a->resize(0); } - - - - b3Assert( workingSize%DATA_ALIGNMENT == 0 ); - int minCap = NUM_BUCKET*NUM_WGS; + b3Assert(workingSize % DATA_ALIGNMENT == 0); + int minCap = NUM_BUCKET * NUM_WGS; int n = workingSize; - m_workBuffer1->resize(minCap); m_workBuffer3->resize(workingSize); m_workBuffer3a->resize(workingSize); -// ADLASSERT( ELEMENTS_PER_WORK_ITEM == 4 ); - b3Assert( BITS_PER_PASS == 4 ); - b3Assert( WG_SIZE == 64 ); - b3Assert( (sortBits&0x3) == 0 ); + // ADLASSERT( ELEMENTS_PER_WORK_ITEM == 4 ); + b3Assert(BITS_PER_PASS == 4); + b3Assert(WG_SIZE == 64); + b3Assert((sortBits & 0x3) == 0); - - b3OpenCLArray* dst = m_workBuffer3a; b3OpenCLArray* srcHisto = m_workBuffer1; b3OpenCLArray* destHisto = m_workBuffer2; - int nWGs = NUM_WGS; b3ConstData cdata; { - int blockSize = ELEMENTS_PER_WORK_ITEM*WG_SIZE;//set at 256 - int nBlocks = (n+blockSize-1)/(blockSize); + int blockSize = ELEMENTS_PER_WORK_ITEM * WG_SIZE; //set at 256 + int nBlocks = (n + blockSize - 1) / (blockSize); cdata.m_n = n; cdata.m_nWGs = NUM_WGS; cdata.m_startBit = 0; - cdata.m_nBlocksPerWG = (nBlocks + cdata.m_nWGs - 1)/cdata.m_nWGs; - if( nBlocks < NUM_WGS ) + cdata.m_nBlocksPerWG = (nBlocks + cdata.m_nWGs - 1) / cdata.m_nWGs; + if (nBlocks < NUM_WGS) { cdata.m_nBlocksPerWG = 1; nWGs = nBlocks; } } - int count=0; - for(int ib=0; ibsize()) { - b3BufferInfoCL bInfo[] = { b3BufferInfoCL( src->getBufferCL(), true ), b3BufferInfoCL( srcHisto->getBufferCL() ) }; - b3LauncherCL launcher(m_commandQueue, m_streamCountKernel,"m_streamCountKernel"); + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(src->getBufferCL(), true), b3BufferInfoCL(srcHisto->getBufferCL())}; + b3LauncherCL launcher(m_commandQueue, m_streamCountKernel, "m_streamCountKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( cdata ); - - int num = NUM_WGS*WG_SIZE; - launcher.launch1D( num, WG_SIZE ); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(cdata); + + int num = NUM_WGS * WG_SIZE; + launcher.launch1D(num, WG_SIZE); } - - //fast prefix scan is not working properly on Mac OSX yet #ifdef __APPLE__ - bool fastScan=false; + bool fastScan = false; #else - bool fastScan=!m_deviceCPU; + bool fastScan = !m_deviceCPU; #endif if (fastScan) - {// prefix scan group histogram - b3BufferInfoCL bInfo[] = { b3BufferInfoCL( srcHisto->getBufferCL() ) }; - b3LauncherCL launcher( m_commandQueue, m_prefixScanKernel,"m_prefixScanKernel" ); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( cdata ); - launcher.launch1D( 128, 128 ); + { // prefix scan group histogram + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(srcHisto->getBufferCL())}; + b3LauncherCL launcher(m_commandQueue, m_prefixScanKernel, "m_prefixScanKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(cdata); + launcher.launch1D(128, 128); destHisto = srcHisto; - }else + } + else { //unsigned int sum; //for debugging - m_scan->execute(*srcHisto,*destHisto,1920,0);//,&sum); + m_scan->execute(*srcHisto, *destHisto, 1920, 0); //,&sum); } if (src->size()) - {// local sort and distribute - b3BufferInfoCL bInfo[] = { b3BufferInfoCL( src->getBufferCL(), true ), b3BufferInfoCL( destHisto->getBufferCL(), true ), b3BufferInfoCL( dst->getBufferCL() )}; - b3LauncherCL launcher( m_commandQueue, m_sortAndScatterKernel ,"m_sortAndScatterKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( cdata ); - launcher.launch1D( nWGs*WG_SIZE, WG_SIZE ); - + { // local sort and distribute + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(src->getBufferCL(), true), b3BufferInfoCL(destHisto->getBufferCL(), true), b3BufferInfoCL(dst->getBufferCL())}; + b3LauncherCL launcher(m_commandQueue, m_sortAndScatterKernel, "m_sortAndScatterKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(cdata); + launcher.launch1D(nWGs * WG_SIZE, WG_SIZE); } - - b3Swap(src, dst ); - b3Swap(srcHisto,destHisto); - count++; + b3Swap(src, dst); + b3Swap(srcHisto, destHisto); + + count++; } - - if (count&1) + + if (count & 1) { - b3Assert(0);//need to copy from workbuffer to keyValuesInOut + b3Assert(0); //need to copy from workbuffer to keyValuesInOut } if (m_workBuffer4a->size()) @@ -699,12 +643,4 @@ void b3RadixSort32CL::execute(b3OpenCLArray& keysInOut, int sortBi m_workBuffer4a->resize(originalSize); keysInOut.copyFromOpenCLArray(*m_workBuffer4a); } - } - - - - - - - diff --git a/src/Bullet3OpenCL/ParallelPrimitives/b3RadixSort32CL.h b/src/Bullet3OpenCL/ParallelPrimitives/b3RadixSort32CL.h index 975bd80e5..69caf182d 100644 --- a/src/Bullet3OpenCL/ParallelPrimitives/b3RadixSort32CL.h +++ b/src/Bullet3OpenCL/ParallelPrimitives/b3RadixSort32CL.h @@ -6,90 +6,79 @@ struct b3SortData { - union - { + union { unsigned int m_key; unsigned int x; }; - union - { + union { unsigned int m_value; unsigned int y; - }; }; #include "b3BufferInfoCL.h" -class b3RadixSort32CL +class b3RadixSort32CL { + b3OpenCLArray* m_workBuffer1; + b3OpenCLArray* m_workBuffer2; - b3OpenCLArray* m_workBuffer1; - b3OpenCLArray* m_workBuffer2; - - b3OpenCLArray* m_workBuffer3; - b3OpenCLArray* m_workBuffer4; + b3OpenCLArray* m_workBuffer3; + b3OpenCLArray* m_workBuffer4; - b3OpenCLArray* m_workBuffer3a; - b3OpenCLArray* m_workBuffer4a; + b3OpenCLArray* m_workBuffer3a; + b3OpenCLArray* m_workBuffer4a; - cl_command_queue m_commandQueue; + cl_command_queue m_commandQueue; - cl_kernel m_streamCountSortDataKernel; - cl_kernel m_streamCountKernel; + cl_kernel m_streamCountSortDataKernel; + cl_kernel m_streamCountKernel; - cl_kernel m_prefixScanKernel; - cl_kernel m_sortAndScatterSortDataKernel; - cl_kernel m_sortAndScatterKernel; + cl_kernel m_prefixScanKernel; + cl_kernel m_sortAndScatterSortDataKernel; + cl_kernel m_sortAndScatterKernel; + bool m_deviceCPU; - bool m_deviceCPU; - - class b3PrefixScanCL* m_scan; - class b3FillCL* m_fill; + class b3PrefixScanCL* m_scan; + class b3FillCL* m_fill; public: struct b3ConstData - { - int m_n; - int m_nWGs; - int m_startBit; - int m_nBlocksPerWG; - }; + { + int m_n; + int m_nWGs; + int m_startBit; + int m_nBlocksPerWG; + }; enum - { - DATA_ALIGNMENT = 256, - WG_SIZE = 64, - BLOCK_SIZE = 256, - ELEMENTS_PER_WORK_ITEM = (BLOCK_SIZE/WG_SIZE), - BITS_PER_PASS = 4, - NUM_BUCKET=(1<& keysIn, b3OpenCLArray& keysOut, b3OpenCLArray& valuesIn, + b3OpenCLArray& valuesOut, int n, int sortBits = 32); - void execute(b3OpenCLArray& keysIn, b3OpenCLArray& keysOut, b3OpenCLArray& valuesIn, - b3OpenCLArray& valuesOut, int n, int sortBits = 32); - - ///keys only - void execute(b3OpenCLArray& keysInOut, int sortBits = 32 ); - - void execute(b3OpenCLArray& keyValuesInOut, int sortBits = 32 ); - void executeHost(b3OpenCLArray& keyValuesInOut, int sortBits = 32); - void executeHost(b3AlignedObjectArray& keyValuesInOut, int sortBits = 32); + ///keys only + void execute(b3OpenCLArray& keysInOut, int sortBits = 32); + void execute(b3OpenCLArray& keyValuesInOut, int sortBits = 32); + void executeHost(b3OpenCLArray& keyValuesInOut, int sortBits = 32); + void executeHost(b3AlignedObjectArray& keyValuesInOut, int sortBits = 32); }; -#endif //B3_RADIXSORT32_H - +#endif //B3_RADIXSORT32_H diff --git a/src/Bullet3OpenCL/ParallelPrimitives/kernels/BoundSearchKernelsCL.h b/src/Bullet3OpenCL/ParallelPrimitives/kernels/BoundSearchKernelsCL.h index 9c9e84713..1758dd41e 100644 --- a/src/Bullet3OpenCL/ParallelPrimitives/kernels/BoundSearchKernelsCL.h +++ b/src/Bullet3OpenCL/ParallelPrimitives/kernels/BoundSearchKernelsCL.h @@ -1,87 +1,86 @@ //this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project -static const char* boundSearchKernelsCL= \ -"/*\n" -"Copyright (c) 2012 Advanced Micro Devices, Inc. \n" -"This software is provided 'as-is', without any express or implied warranty.\n" -"In no event will the authors be held liable for any damages arising from the use of this software.\n" -"Permission is granted to anyone to use this software for any purpose, \n" -"including commercial applications, and to alter it and redistribute it freely, \n" -"subject to the following restrictions:\n" -"1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" -"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" -"3. This notice may not be removed or altered from any source distribution.\n" -"*/\n" -"//Originally written by Takahiro Harada\n" -"typedef unsigned int u32;\n" -"#define GET_GROUP_IDX get_group_id(0)\n" -"#define GET_LOCAL_IDX get_local_id(0)\n" -"#define GET_GLOBAL_IDX get_global_id(0)\n" -"#define GET_GROUP_SIZE get_local_size(0)\n" -"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" -"typedef struct\n" -"{\n" -" u32 m_key; \n" -" u32 m_value;\n" -"}SortData;\n" -"typedef struct\n" -"{\n" -" u32 m_nSrc;\n" -" u32 m_nDst;\n" -" u32 m_padding[2];\n" -"} ConstBuffer;\n" -"__attribute__((reqd_work_group_size(64,1,1)))\n" -"__kernel\n" -"void SearchSortDataLowerKernel(__global SortData* src, __global u32 *dst, \n" -" unsigned int nSrc, unsigned int nDst)\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX;\n" -" if( gIdx < nSrc )\n" -" {\n" -" SortData first; first.m_key = (u32)(-1); first.m_value = (u32)(-1);\n" -" SortData end; end.m_key = nDst; end.m_value = nDst;\n" -" SortData iData = (gIdx==0)? first: src[gIdx-1];\n" -" SortData jData = (gIdx==nSrc)? end: src[gIdx];\n" -" if( iData.m_key != jData.m_key )\n" -" {\n" -"// for(u32 k=iData.m_key+1; k<=min(jData.m_key, nDst-1); k++)\n" -" u32 k = jData.m_key;\n" -" {\n" -" dst[k] = gIdx;\n" -" }\n" -" }\n" -" }\n" -"}\n" -"__attribute__((reqd_work_group_size(64,1,1)))\n" -"__kernel\n" -"void SearchSortDataUpperKernel(__global SortData* src, __global u32 *dst, \n" -" unsigned int nSrc, unsigned int nDst)\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX+1;\n" -" if( gIdx < nSrc+1 )\n" -" {\n" -" SortData first; first.m_key = 0; first.m_value = 0;\n" -" SortData end; end.m_key = nDst; end.m_value = nDst;\n" -" SortData iData = src[gIdx-1];\n" -" SortData jData = (gIdx==nSrc)? end: src[gIdx];\n" -" if( iData.m_key != jData.m_key )\n" -" {\n" -" u32 k = iData.m_key;\n" -" {\n" -" dst[k] = gIdx;\n" -" }\n" -" }\n" -" }\n" -"}\n" -"__attribute__((reqd_work_group_size(64,1,1)))\n" -"__kernel\n" -"void SubtractKernel(__global u32* A, __global u32 *B, __global u32 *C, \n" -" unsigned int nSrc, unsigned int nDst)\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX;\n" -" \n" -" if( gIdx < nDst )\n" -" {\n" -" C[gIdx] = A[gIdx] - B[gIdx];\n" -" }\n" -"}\n" -; +static const char* boundSearchKernelsCL = + "/*\n" + "Copyright (c) 2012 Advanced Micro Devices, Inc. \n" + "This software is provided 'as-is', without any express or implied warranty.\n" + "In no event will the authors be held liable for any damages arising from the use of this software.\n" + "Permission is granted to anyone to use this software for any purpose, \n" + "including commercial applications, and to alter it and redistribute it freely, \n" + "subject to the following restrictions:\n" + "1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" + "2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" + "3. This notice may not be removed or altered from any source distribution.\n" + "*/\n" + "//Originally written by Takahiro Harada\n" + "typedef unsigned int u32;\n" + "#define GET_GROUP_IDX get_group_id(0)\n" + "#define GET_LOCAL_IDX get_local_id(0)\n" + "#define GET_GLOBAL_IDX get_global_id(0)\n" + "#define GET_GROUP_SIZE get_local_size(0)\n" + "#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" + "typedef struct\n" + "{\n" + " u32 m_key; \n" + " u32 m_value;\n" + "}SortData;\n" + "typedef struct\n" + "{\n" + " u32 m_nSrc;\n" + " u32 m_nDst;\n" + " u32 m_padding[2];\n" + "} ConstBuffer;\n" + "__attribute__((reqd_work_group_size(64,1,1)))\n" + "__kernel\n" + "void SearchSortDataLowerKernel(__global SortData* src, __global u32 *dst, \n" + " unsigned int nSrc, unsigned int nDst)\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX;\n" + " if( gIdx < nSrc )\n" + " {\n" + " SortData first; first.m_key = (u32)(-1); first.m_value = (u32)(-1);\n" + " SortData end; end.m_key = nDst; end.m_value = nDst;\n" + " SortData iData = (gIdx==0)? first: src[gIdx-1];\n" + " SortData jData = (gIdx==nSrc)? end: src[gIdx];\n" + " if( iData.m_key != jData.m_key )\n" + " {\n" + "// for(u32 k=iData.m_key+1; k<=min(jData.m_key, nDst-1); k++)\n" + " u32 k = jData.m_key;\n" + " {\n" + " dst[k] = gIdx;\n" + " }\n" + " }\n" + " }\n" + "}\n" + "__attribute__((reqd_work_group_size(64,1,1)))\n" + "__kernel\n" + "void SearchSortDataUpperKernel(__global SortData* src, __global u32 *dst, \n" + " unsigned int nSrc, unsigned int nDst)\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX+1;\n" + " if( gIdx < nSrc+1 )\n" + " {\n" + " SortData first; first.m_key = 0; first.m_value = 0;\n" + " SortData end; end.m_key = nDst; end.m_value = nDst;\n" + " SortData iData = src[gIdx-1];\n" + " SortData jData = (gIdx==nSrc)? end: src[gIdx];\n" + " if( iData.m_key != jData.m_key )\n" + " {\n" + " u32 k = iData.m_key;\n" + " {\n" + " dst[k] = gIdx;\n" + " }\n" + " }\n" + " }\n" + "}\n" + "__attribute__((reqd_work_group_size(64,1,1)))\n" + "__kernel\n" + "void SubtractKernel(__global u32* A, __global u32 *B, __global u32 *C, \n" + " unsigned int nSrc, unsigned int nDst)\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX;\n" + " \n" + " if( gIdx < nDst )\n" + " {\n" + " C[gIdx] = A[gIdx] - B[gIdx];\n" + " }\n" + "}\n"; diff --git a/src/Bullet3OpenCL/ParallelPrimitives/kernels/CopyKernelsCL.h b/src/Bullet3OpenCL/ParallelPrimitives/kernels/CopyKernelsCL.h index e5670e3cd..33c927946 100644 --- a/src/Bullet3OpenCL/ParallelPrimitives/kernels/CopyKernelsCL.h +++ b/src/Bullet3OpenCL/ParallelPrimitives/kernels/CopyKernelsCL.h @@ -1,132 +1,131 @@ //this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project -static const char* copyKernelsCL= \ -"/*\n" -"Copyright (c) 2012 Advanced Micro Devices, Inc. \n" -"\n" -"This software is provided 'as-is', without any express or implied warranty.\n" -"In no event will the authors be held liable for any damages arising from the use of this software.\n" -"Permission is granted to anyone to use this software for any purpose, \n" -"including commercial applications, and to alter it and redistribute it freely, \n" -"subject to the following restrictions:\n" -"\n" -"1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" -"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" -"3. This notice may not be removed or altered from any source distribution.\n" -"*/\n" -"//Originally written by Takahiro Harada\n" -"\n" -"#pragma OPENCL EXTENSION cl_amd_printf : enable\n" -"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" -"\n" -"typedef unsigned int u32;\n" -"#define GET_GROUP_IDX get_group_id(0)\n" -"#define GET_LOCAL_IDX get_local_id(0)\n" -"#define GET_GLOBAL_IDX get_global_id(0)\n" -"#define GET_GROUP_SIZE get_local_size(0)\n" -"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" -"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" -"#define AtomInc(x) atom_inc(&(x))\n" -"#define AtomInc1(x, out) out = atom_inc(&(x))\n" -"\n" -"#define make_uint4 (uint4)\n" -"#define make_uint2 (uint2)\n" -"#define make_int2 (int2)\n" -"\n" -"typedef struct\n" -"{\n" -" int m_n;\n" -" int m_padding[3];\n" -"} ConstBuffer;\n" -"\n" -"\n" -"\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(64,1,1)))\n" -"void Copy1F4Kernel(__global float4* dst, __global float4* src, \n" -" ConstBuffer cb)\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX;\n" -"\n" -" if( gIdx < cb.m_n )\n" -" {\n" -" float4 a0 = src[gIdx];\n" -"\n" -" dst[ gIdx ] = a0;\n" -" }\n" -"}\n" -"\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(64,1,1)))\n" -"void Copy2F4Kernel(__global float4* dst, __global float4* src, \n" -" ConstBuffer cb)\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX;\n" -"\n" -" if( 2*gIdx <= cb.m_n )\n" -" {\n" -" float4 a0 = src[gIdx*2+0];\n" -" float4 a1 = src[gIdx*2+1];\n" -"\n" -" dst[ gIdx*2+0 ] = a0;\n" -" dst[ gIdx*2+1 ] = a1;\n" -" }\n" -"}\n" -"\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(64,1,1)))\n" -"void Copy4F4Kernel(__global float4* dst, __global float4* src, \n" -" ConstBuffer cb)\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX;\n" -"\n" -" if( 4*gIdx <= cb.m_n )\n" -" {\n" -" int idx0 = gIdx*4+0;\n" -" int idx1 = gIdx*4+1;\n" -" int idx2 = gIdx*4+2;\n" -" int idx3 = gIdx*4+3;\n" -"\n" -" float4 a0 = src[idx0];\n" -" float4 a1 = src[idx1];\n" -" float4 a2 = src[idx2];\n" -" float4 a3 = src[idx3];\n" -"\n" -" dst[ idx0 ] = a0;\n" -" dst[ idx1 ] = a1;\n" -" dst[ idx2 ] = a2;\n" -" dst[ idx3 ] = a3;\n" -" }\n" -"}\n" -"\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(64,1,1)))\n" -"void CopyF1Kernel(__global float* dstF1, __global float* srcF1, \n" -" ConstBuffer cb)\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX;\n" -"\n" -" if( gIdx < cb.m_n )\n" -" {\n" -" float a0 = srcF1[gIdx];\n" -"\n" -" dstF1[ gIdx ] = a0;\n" -" }\n" -"}\n" -"\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(64,1,1)))\n" -"void CopyF2Kernel(__global float2* dstF2, __global float2* srcF2, \n" -" ConstBuffer cb)\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX;\n" -"\n" -" if( gIdx < cb.m_n )\n" -" {\n" -" float2 a0 = srcF2[gIdx];\n" -"\n" -" dstF2[ gIdx ] = a0;\n" -" }\n" -"}\n" -"\n" -"\n" -; +static const char* copyKernelsCL = + "/*\n" + "Copyright (c) 2012 Advanced Micro Devices, Inc. \n" + "\n" + "This software is provided 'as-is', without any express or implied warranty.\n" + "In no event will the authors be held liable for any damages arising from the use of this software.\n" + "Permission is granted to anyone to use this software for any purpose, \n" + "including commercial applications, and to alter it and redistribute it freely, \n" + "subject to the following restrictions:\n" + "\n" + "1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" + "2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" + "3. This notice may not be removed or altered from any source distribution.\n" + "*/\n" + "//Originally written by Takahiro Harada\n" + "\n" + "#pragma OPENCL EXTENSION cl_amd_printf : enable\n" + "#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" + "\n" + "typedef unsigned int u32;\n" + "#define GET_GROUP_IDX get_group_id(0)\n" + "#define GET_LOCAL_IDX get_local_id(0)\n" + "#define GET_GLOBAL_IDX get_global_id(0)\n" + "#define GET_GROUP_SIZE get_local_size(0)\n" + "#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" + "#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" + "#define AtomInc(x) atom_inc(&(x))\n" + "#define AtomInc1(x, out) out = atom_inc(&(x))\n" + "\n" + "#define make_uint4 (uint4)\n" + "#define make_uint2 (uint2)\n" + "#define make_int2 (int2)\n" + "\n" + "typedef struct\n" + "{\n" + " int m_n;\n" + " int m_padding[3];\n" + "} ConstBuffer;\n" + "\n" + "\n" + "\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(64,1,1)))\n" + "void Copy1F4Kernel(__global float4* dst, __global float4* src, \n" + " ConstBuffer cb)\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX;\n" + "\n" + " if( gIdx < cb.m_n )\n" + " {\n" + " float4 a0 = src[gIdx];\n" + "\n" + " dst[ gIdx ] = a0;\n" + " }\n" + "}\n" + "\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(64,1,1)))\n" + "void Copy2F4Kernel(__global float4* dst, __global float4* src, \n" + " ConstBuffer cb)\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX;\n" + "\n" + " if( 2*gIdx <= cb.m_n )\n" + " {\n" + " float4 a0 = src[gIdx*2+0];\n" + " float4 a1 = src[gIdx*2+1];\n" + "\n" + " dst[ gIdx*2+0 ] = a0;\n" + " dst[ gIdx*2+1 ] = a1;\n" + " }\n" + "}\n" + "\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(64,1,1)))\n" + "void Copy4F4Kernel(__global float4* dst, __global float4* src, \n" + " ConstBuffer cb)\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX;\n" + "\n" + " if( 4*gIdx <= cb.m_n )\n" + " {\n" + " int idx0 = gIdx*4+0;\n" + " int idx1 = gIdx*4+1;\n" + " int idx2 = gIdx*4+2;\n" + " int idx3 = gIdx*4+3;\n" + "\n" + " float4 a0 = src[idx0];\n" + " float4 a1 = src[idx1];\n" + " float4 a2 = src[idx2];\n" + " float4 a3 = src[idx3];\n" + "\n" + " dst[ idx0 ] = a0;\n" + " dst[ idx1 ] = a1;\n" + " dst[ idx2 ] = a2;\n" + " dst[ idx3 ] = a3;\n" + " }\n" + "}\n" + "\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(64,1,1)))\n" + "void CopyF1Kernel(__global float* dstF1, __global float* srcF1, \n" + " ConstBuffer cb)\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX;\n" + "\n" + " if( gIdx < cb.m_n )\n" + " {\n" + " float a0 = srcF1[gIdx];\n" + "\n" + " dstF1[ gIdx ] = a0;\n" + " }\n" + "}\n" + "\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(64,1,1)))\n" + "void CopyF2Kernel(__global float2* dstF2, __global float2* srcF2, \n" + " ConstBuffer cb)\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX;\n" + "\n" + " if( gIdx < cb.m_n )\n" + " {\n" + " float2 a0 = srcF2[gIdx];\n" + "\n" + " dstF2[ gIdx ] = a0;\n" + " }\n" + "}\n" + "\n" + "\n"; diff --git a/src/Bullet3OpenCL/ParallelPrimitives/kernels/FillKernelsCL.h b/src/Bullet3OpenCL/ParallelPrimitives/kernels/FillKernelsCL.h index 4f8b96e48..983e65227 100644 --- a/src/Bullet3OpenCL/ParallelPrimitives/kernels/FillKernelsCL.h +++ b/src/Bullet3OpenCL/ParallelPrimitives/kernels/FillKernelsCL.h @@ -1,91 +1,90 @@ //this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project -static const char* fillKernelsCL= \ -"/*\n" -"Copyright (c) 2012 Advanced Micro Devices, Inc. \n" -"This software is provided 'as-is', without any express or implied warranty.\n" -"In no event will the authors be held liable for any damages arising from the use of this software.\n" -"Permission is granted to anyone to use this software for any purpose, \n" -"including commercial applications, and to alter it and redistribute it freely, \n" -"subject to the following restrictions:\n" -"1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" -"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" -"3. This notice may not be removed or altered from any source distribution.\n" -"*/\n" -"//Originally written by Takahiro Harada\n" -"#pragma OPENCL EXTENSION cl_amd_printf : enable\n" -"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" -"typedef unsigned int u32;\n" -"#define GET_GROUP_IDX get_group_id(0)\n" -"#define GET_LOCAL_IDX get_local_id(0)\n" -"#define GET_GLOBAL_IDX get_global_id(0)\n" -"#define GET_GROUP_SIZE get_local_size(0)\n" -"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" -"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" -"#define AtomInc(x) atom_inc(&(x))\n" -"#define AtomInc1(x, out) out = atom_inc(&(x))\n" -"#define make_uint4 (uint4)\n" -"#define make_uint2 (uint2)\n" -"#define make_int2 (int2)\n" -"typedef struct\n" -"{\n" -" union\n" -" {\n" -" int4 m_data;\n" -" uint4 m_unsignedData;\n" -" float m_floatData;\n" -" };\n" -" int m_offset;\n" -" int m_n;\n" -" int m_padding[2];\n" -"} ConstBuffer;\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(64,1,1)))\n" -"void FillIntKernel(__global int* dstInt, int num_elements, int value, const int offset)\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX;\n" -" if( gIdx < num_elements )\n" -" {\n" -" dstInt[ offset+gIdx ] = value;\n" -" }\n" -"}\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(64,1,1)))\n" -"void FillFloatKernel(__global float* dstFloat, int num_elements, float value, const int offset)\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX;\n" -" if( gIdx < num_elements )\n" -" {\n" -" dstFloat[ offset+gIdx ] = value;\n" -" }\n" -"}\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(64,1,1)))\n" -"void FillUnsignedIntKernel(__global unsigned int* dstInt, const int num, const unsigned int value, const int offset)\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX;\n" -" if( gIdx < num )\n" -" {\n" -" dstInt[ offset+gIdx ] = value;\n" -" }\n" -"}\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(64,1,1)))\n" -"void FillInt2Kernel(__global int2* dstInt2, const int num, const int2 value, const int offset)\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX;\n" -" if( gIdx < num )\n" -" {\n" -" dstInt2[ gIdx + offset] = make_int2( value.x, value.y );\n" -" }\n" -"}\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(64,1,1)))\n" -"void FillInt4Kernel(__global int4* dstInt4, const int num, const int4 value, const int offset)\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX;\n" -" if( gIdx < num )\n" -" {\n" -" dstInt4[ offset+gIdx ] = value;\n" -" }\n" -"}\n" -; +static const char* fillKernelsCL = + "/*\n" + "Copyright (c) 2012 Advanced Micro Devices, Inc. \n" + "This software is provided 'as-is', without any express or implied warranty.\n" + "In no event will the authors be held liable for any damages arising from the use of this software.\n" + "Permission is granted to anyone to use this software for any purpose, \n" + "including commercial applications, and to alter it and redistribute it freely, \n" + "subject to the following restrictions:\n" + "1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" + "2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" + "3. This notice may not be removed or altered from any source distribution.\n" + "*/\n" + "//Originally written by Takahiro Harada\n" + "#pragma OPENCL EXTENSION cl_amd_printf : enable\n" + "#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" + "typedef unsigned int u32;\n" + "#define GET_GROUP_IDX get_group_id(0)\n" + "#define GET_LOCAL_IDX get_local_id(0)\n" + "#define GET_GLOBAL_IDX get_global_id(0)\n" + "#define GET_GROUP_SIZE get_local_size(0)\n" + "#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" + "#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" + "#define AtomInc(x) atom_inc(&(x))\n" + "#define AtomInc1(x, out) out = atom_inc(&(x))\n" + "#define make_uint4 (uint4)\n" + "#define make_uint2 (uint2)\n" + "#define make_int2 (int2)\n" + "typedef struct\n" + "{\n" + " union\n" + " {\n" + " int4 m_data;\n" + " uint4 m_unsignedData;\n" + " float m_floatData;\n" + " };\n" + " int m_offset;\n" + " int m_n;\n" + " int m_padding[2];\n" + "} ConstBuffer;\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(64,1,1)))\n" + "void FillIntKernel(__global int* dstInt, int num_elements, int value, const int offset)\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX;\n" + " if( gIdx < num_elements )\n" + " {\n" + " dstInt[ offset+gIdx ] = value;\n" + " }\n" + "}\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(64,1,1)))\n" + "void FillFloatKernel(__global float* dstFloat, int num_elements, float value, const int offset)\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX;\n" + " if( gIdx < num_elements )\n" + " {\n" + " dstFloat[ offset+gIdx ] = value;\n" + " }\n" + "}\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(64,1,1)))\n" + "void FillUnsignedIntKernel(__global unsigned int* dstInt, const int num, const unsigned int value, const int offset)\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX;\n" + " if( gIdx < num )\n" + " {\n" + " dstInt[ offset+gIdx ] = value;\n" + " }\n" + "}\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(64,1,1)))\n" + "void FillInt2Kernel(__global int2* dstInt2, const int num, const int2 value, const int offset)\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX;\n" + " if( gIdx < num )\n" + " {\n" + " dstInt2[ gIdx + offset] = make_int2( value.x, value.y );\n" + " }\n" + "}\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(64,1,1)))\n" + "void FillInt4Kernel(__global int4* dstInt4, const int num, const int4 value, const int offset)\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX;\n" + " if( gIdx < num )\n" + " {\n" + " dstInt4[ offset+gIdx ] = value;\n" + " }\n" + "}\n"; diff --git a/src/Bullet3OpenCL/ParallelPrimitives/kernels/PrefixScanKernelsCL.h b/src/Bullet3OpenCL/ParallelPrimitives/kernels/PrefixScanKernelsCL.h index 27baab833..fc5e7b865 100644 --- a/src/Bullet3OpenCL/ParallelPrimitives/kernels/PrefixScanKernelsCL.h +++ b/src/Bullet3OpenCL/ParallelPrimitives/kernels/PrefixScanKernelsCL.h @@ -1,129 +1,128 @@ //this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project -static const char* prefixScanKernelsCL= \ -"/*\n" -"Copyright (c) 2012 Advanced Micro Devices, Inc. \n" -"This software is provided 'as-is', without any express or implied warranty.\n" -"In no event will the authors be held liable for any damages arising from the use of this software.\n" -"Permission is granted to anyone to use this software for any purpose, \n" -"including commercial applications, and to alter it and redistribute it freely, \n" -"subject to the following restrictions:\n" -"1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" -"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" -"3. This notice may not be removed or altered from any source distribution.\n" -"*/\n" -"//Originally written by Takahiro Harada\n" -"typedef unsigned int u32;\n" -"#define GET_GROUP_IDX get_group_id(0)\n" -"#define GET_LOCAL_IDX get_local_id(0)\n" -"#define GET_GLOBAL_IDX get_global_id(0)\n" -"#define GET_GROUP_SIZE get_local_size(0)\n" -"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" -"// takahiro end\n" -"#define WG_SIZE 128 \n" -"#define m_numElems x\n" -"#define m_numBlocks y\n" -"#define m_numScanBlocks z\n" -"/*typedef struct\n" -"{\n" -" uint m_numElems;\n" -" uint m_numBlocks;\n" -" uint m_numScanBlocks;\n" -" uint m_padding[1];\n" -"} ConstBuffer;\n" -"*/\n" -"u32 ScanExclusive(__local u32* data, u32 n, int lIdx, int lSize)\n" -"{\n" -" u32 blocksum;\n" -" int offset = 1;\n" -" for(int nActive=n>>1; nActive>0; nActive>>=1, offset<<=1)\n" -" {\n" -" GROUP_LDS_BARRIER;\n" -" for(int iIdx=lIdx; iIdx>= 1;\n" -" for(int nActive=1; nActive>=1 )\n" -" {\n" -" GROUP_LDS_BARRIER;\n" -" for( int iIdx = lIdx; iIdx>1; nActive>0; nActive>>=1, offset<<=1)\n" + " {\n" + " GROUP_LDS_BARRIER;\n" + " for(int iIdx=lIdx; iIdx>= 1;\n" + " for(int nActive=1; nActive>=1 )\n" + " {\n" + " GROUP_LDS_BARRIER;\n" + " for( int iIdx = lIdx; iIdx>1; nActive>0; nActive>>=1, offset<<=1)\n" -" {\n" -" GROUP_LDS_BARRIER;\n" -" for(int iIdx=lIdx; iIdx>= 1;\n" -" for(int nActive=1; nActive>=1 )\n" -" {\n" -" GROUP_LDS_BARRIER;\n" -" for( int iIdx = lIdx; iIdx>1; nActive>0; nActive>>=1, offset<<=1)\n" + " {\n" + " GROUP_LDS_BARRIER;\n" + " for(int iIdx=lIdx; iIdx>= 1;\n" + " for(int nActive=1; nActive>=1 )\n" + " {\n" + " GROUP_LDS_BARRIER;\n" + " for( int iIdx = lIdx; iIdx 64 )\n" -" {\n" -" sorterSharedMemory[idx] += sorterSharedMemory[idx-64];\n" -" GROUP_MEM_FENCE;\n" -" }\n" -" sorterSharedMemory[idx-1] += sorterSharedMemory[idx-2];\n" -" GROUP_MEM_FENCE;\n" -" }\n" -"#else\n" -" if( lIdx < 64 )\n" -" {\n" -" sorterSharedMemory[idx] += sorterSharedMemory[idx-1];\n" -" GROUP_MEM_FENCE;\n" -" sorterSharedMemory[idx] += sorterSharedMemory[idx-2]; \n" -" GROUP_MEM_FENCE;\n" -" sorterSharedMemory[idx] += sorterSharedMemory[idx-4];\n" -" GROUP_MEM_FENCE;\n" -" sorterSharedMemory[idx] += sorterSharedMemory[idx-8];\n" -" GROUP_MEM_FENCE;\n" -" sorterSharedMemory[idx] += sorterSharedMemory[idx-16];\n" -" GROUP_MEM_FENCE;\n" -" sorterSharedMemory[idx] += sorterSharedMemory[idx-32];\n" -" GROUP_MEM_FENCE;\n" -" if( wgSize > 64 )\n" -" {\n" -" sorterSharedMemory[idx] += sorterSharedMemory[idx-64];\n" -" GROUP_MEM_FENCE;\n" -" }\n" -" sorterSharedMemory[idx-1] += sorterSharedMemory[idx-2];\n" -" GROUP_MEM_FENCE;\n" -" }\n" -"#endif\n" -" }\n" -" GROUP_LDS_BARRIER;\n" -" *totalSum = sorterSharedMemory[wgSize*2-1];\n" -" u32 addValue = sorterSharedMemory[lIdx+wgSize-1];\n" -" return addValue;\n" -"}\n" -"//__attribute__((reqd_work_group_size(128,1,1)))\n" -"uint4 localPrefixSum128V( uint4 pData, uint lIdx, uint* totalSum, __local u32* sorterSharedMemory )\n" -"{\n" -" u32 s4 = prefixScanVectorEx( &pData );\n" -" u32 rank = localPrefixSum( s4, lIdx, totalSum, sorterSharedMemory, 128 );\n" -" return pData + make_uint4( rank, rank, rank, rank );\n" -"}\n" -"//__attribute__((reqd_work_group_size(64,1,1)))\n" -"uint4 localPrefixSum64V( uint4 pData, uint lIdx, uint* totalSum, __local u32* sorterSharedMemory )\n" -"{\n" -" u32 s4 = prefixScanVectorEx( &pData );\n" -" u32 rank = localPrefixSum( s4, lIdx, totalSum, sorterSharedMemory, 64 );\n" -" return pData + make_uint4( rank, rank, rank, rank );\n" -"}\n" -"u32 unpack4Key( u32 key, int keyIdx ){ return (key>>(keyIdx*8)) & 0xff;}\n" -"u32 bit8Scan(u32 v)\n" -"{\n" -" return (v<<8) + (v<<16) + (v<<24);\n" -"}\n" -"//===\n" -"#define MY_HISTOGRAM(idx) localHistogramMat[(idx)*WG_SIZE+lIdx]\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" -"void StreamCountKernel( __global u32* gSrc, __global u32* histogramOut, int4 cb )\n" -"{\n" -" __local u32 localHistogramMat[NUM_BUCKET*WG_SIZE];\n" -" u32 gIdx = GET_GLOBAL_IDX;\n" -" u32 lIdx = GET_LOCAL_IDX;\n" -" u32 wgIdx = GET_GROUP_IDX;\n" -" u32 wgSize = GET_GROUP_SIZE;\n" -" const int startBit = cb.m_startBit;\n" -" const int n = cb.m_n;\n" -" const int nWGs = cb.m_nWGs;\n" -" const int nBlocksPerWG = cb.m_nBlocksPerWG;\n" -" for(int i=0; i>startBit) & 0xf;\n" -"#if defined(NV_GPU)\n" -" MY_HISTOGRAM( localKey )++;\n" -"#else\n" -" AtomInc( MY_HISTOGRAM( localKey ) );\n" -"#endif\n" -" }\n" -" }\n" -" }\n" -" GROUP_LDS_BARRIER;\n" -" \n" -" if( lIdx < NUM_BUCKET )\n" -" {\n" -" u32 sum = 0;\n" -" for(int i=0; i>startBit) & 0xf;\n" -"#if defined(NV_GPU)\n" -" MY_HISTOGRAM( localKey )++;\n" -"#else\n" -" AtomInc( MY_HISTOGRAM( localKey ) );\n" -"#endif\n" -" }\n" -" }\n" -" }\n" -" GROUP_LDS_BARRIER;\n" -" \n" -" if( lIdx < NUM_BUCKET )\n" -" {\n" -" u32 sum = 0;\n" -" for(int i=0; i>startBit) & mask, (sortData[1]>>startBit) & mask, (sortData[2]>>startBit) & mask, (sortData[3]>>startBit) & mask );\n" -" uint4 prefixSum = SELECT_UINT4( make_uint4(1,1,1,1), make_uint4(0,0,0,0), cmpResult != make_uint4(0,0,0,0) );\n" -" u32 total;\n" -" prefixSum = localPrefixSum64V( prefixSum, lIdx, &total, ldsSortData );\n" -" {\n" -" uint4 localAddr = make_uint4(lIdx*4+0,lIdx*4+1,lIdx*4+2,lIdx*4+3);\n" -" uint4 dstAddr = localAddr - prefixSum + make_uint4( total, total, total, total );\n" -" dstAddr = SELECT_UINT4( prefixSum, dstAddr, cmpResult != make_uint4(0, 0, 0, 0) );\n" -" GROUP_LDS_BARRIER;\n" -" ldsSortData[dstAddr.x] = sortData[0];\n" -" ldsSortData[dstAddr.y] = sortData[1];\n" -" ldsSortData[dstAddr.z] = sortData[2];\n" -" ldsSortData[dstAddr.w] = sortData[3];\n" -" GROUP_LDS_BARRIER;\n" -" sortData[0] = ldsSortData[localAddr.x];\n" -" sortData[1] = ldsSortData[localAddr.y];\n" -" sortData[2] = ldsSortData[localAddr.z];\n" -" sortData[3] = ldsSortData[localAddr.w];\n" -" GROUP_LDS_BARRIER;\n" -" }\n" -" }\n" -"}\n" -"// 2 scan, 2 exchange\n" -"void sort4Bits1(u32 sortData[4], int startBit, int lIdx, __local u32* ldsSortData)\n" -"{\n" -" for(uint ibit=0; ibit>(startBit+ibit)) & 0x3, \n" -" (sortData[1]>>(startBit+ibit)) & 0x3, \n" -" (sortData[2]>>(startBit+ibit)) & 0x3, \n" -" (sortData[3]>>(startBit+ibit)) & 0x3);\n" -" u32 key4;\n" -" u32 sKeyPacked[4] = { 0, 0, 0, 0 };\n" -" {\n" -" sKeyPacked[0] |= 1<<(8*b.x);\n" -" sKeyPacked[1] |= 1<<(8*b.y);\n" -" sKeyPacked[2] |= 1<<(8*b.z);\n" -" sKeyPacked[3] |= 1<<(8*b.w);\n" -" key4 = sKeyPacked[0] + sKeyPacked[1] + sKeyPacked[2] + sKeyPacked[3];\n" -" }\n" -" u32 rankPacked;\n" -" u32 sumPacked;\n" -" {\n" -" rankPacked = localPrefixSum( key4, lIdx, &sumPacked, ldsSortData, WG_SIZE );\n" -" }\n" -" GROUP_LDS_BARRIER;\n" -" u32 newOffset[4] = { 0,0,0,0 };\n" -" {\n" -" u32 sumScanned = bit8Scan( sumPacked );\n" -" u32 scannedKeys[4];\n" -" scannedKeys[0] = 1<<(8*b.x);\n" -" scannedKeys[1] = 1<<(8*b.y);\n" -" scannedKeys[2] = 1<<(8*b.z);\n" -" scannedKeys[3] = 1<<(8*b.w);\n" -" { // 4 scans at once\n" -" u32 sum4 = 0;\n" -" for(int ie=0; ie<4; ie++)\n" -" {\n" -" u32 tmp = scannedKeys[ie];\n" -" scannedKeys[ie] = sum4;\n" -" sum4 += tmp;\n" -" }\n" -" }\n" -" {\n" -" u32 sumPlusRank = sumScanned + rankPacked;\n" -" { u32 ie = b.x;\n" -" scannedKeys[0] += sumPlusRank;\n" -" newOffset[0] = unpack4Key( scannedKeys[0], ie );\n" -" }\n" -" { u32 ie = b.y;\n" -" scannedKeys[1] += sumPlusRank;\n" -" newOffset[1] = unpack4Key( scannedKeys[1], ie );\n" -" }\n" -" { u32 ie = b.z;\n" -" scannedKeys[2] += sumPlusRank;\n" -" newOffset[2] = unpack4Key( scannedKeys[2], ie );\n" -" }\n" -" { u32 ie = b.w;\n" -" scannedKeys[3] += sumPlusRank;\n" -" newOffset[3] = unpack4Key( scannedKeys[3], ie );\n" -" }\n" -" }\n" -" }\n" -" GROUP_LDS_BARRIER;\n" -" {\n" -" ldsSortData[newOffset[0]] = sortData[0];\n" -" ldsSortData[newOffset[1]] = sortData[1];\n" -" ldsSortData[newOffset[2]] = sortData[2];\n" -" ldsSortData[newOffset[3]] = sortData[3];\n" -" GROUP_LDS_BARRIER;\n" -" u32 dstAddr = 4*lIdx;\n" -" sortData[0] = ldsSortData[dstAddr+0];\n" -" sortData[1] = ldsSortData[dstAddr+1];\n" -" sortData[2] = ldsSortData[dstAddr+2];\n" -" sortData[3] = ldsSortData[dstAddr+3];\n" -" GROUP_LDS_BARRIER;\n" -" }\n" -" }\n" -"}\n" -"#define SET_HISTOGRAM(setIdx, key) ldsSortData[(setIdx)*NUM_BUCKET+key]\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" -"void SortAndScatterKernel( __global const u32* restrict gSrc, __global const u32* rHistogram, __global u32* restrict gDst, int4 cb )\n" -"{\n" -" __local u32 ldsSortData[WG_SIZE*ELEMENTS_PER_WORK_ITEM+16];\n" -" __local u32 localHistogramToCarry[NUM_BUCKET];\n" -" __local u32 localHistogram[NUM_BUCKET*2];\n" -" u32 gIdx = GET_GLOBAL_IDX;\n" -" u32 lIdx = GET_LOCAL_IDX;\n" -" u32 wgIdx = GET_GROUP_IDX;\n" -" u32 wgSize = GET_GROUP_SIZE;\n" -" const int n = cb.m_n;\n" -" const int nWGs = cb.m_nWGs;\n" -" const int startBit = cb.m_startBit;\n" -" const int nBlocksPerWG = cb.m_nBlocksPerWG;\n" -" if( lIdx < (NUM_BUCKET) )\n" -" {\n" -" localHistogramToCarry[lIdx] = rHistogram[lIdx*nWGs + wgIdx];\n" -" }\n" -" GROUP_LDS_BARRIER;\n" -" const int blockSize = ELEMENTS_PER_WORK_ITEM*WG_SIZE;\n" -" int nBlocks = n/blockSize - nBlocksPerWG*wgIdx;\n" -" int addr = blockSize*nBlocksPerWG*wgIdx + ELEMENTS_PER_WORK_ITEM*lIdx;\n" -" for(int iblock=0; iblock>startBit) & 0xf;\n" -" { // create histogram\n" -" u32 setIdx = lIdx/16;\n" -" if( lIdx < NUM_BUCKET )\n" -" {\n" -" localHistogram[lIdx] = 0;\n" -" }\n" -" ldsSortData[lIdx] = 0;\n" -" GROUP_LDS_BARRIER;\n" -" for(int i=0; i>(startBit+ibit)) & 0x3, \n" -" (sortData[1]>>(startBit+ibit)) & 0x3, \n" -" (sortData[2]>>(startBit+ibit)) & 0x3, \n" -" (sortData[3]>>(startBit+ibit)) & 0x3);\n" -" u32 key4;\n" -" u32 sKeyPacked[4] = { 0, 0, 0, 0 };\n" -" {\n" -" sKeyPacked[0] |= 1<<(8*b.x);\n" -" sKeyPacked[1] |= 1<<(8*b.y);\n" -" sKeyPacked[2] |= 1<<(8*b.z);\n" -" sKeyPacked[3] |= 1<<(8*b.w);\n" -" key4 = sKeyPacked[0] + sKeyPacked[1] + sKeyPacked[2] + sKeyPacked[3];\n" -" }\n" -" u32 rankPacked;\n" -" u32 sumPacked;\n" -" {\n" -" rankPacked = localPrefixSum( key4, lIdx, &sumPacked, ldsSortData, WG_SIZE );\n" -" }\n" -" GROUP_LDS_BARRIER;\n" -" u32 newOffset[4] = { 0,0,0,0 };\n" -" {\n" -" u32 sumScanned = bit8Scan( sumPacked );\n" -" u32 scannedKeys[4];\n" -" scannedKeys[0] = 1<<(8*b.x);\n" -" scannedKeys[1] = 1<<(8*b.y);\n" -" scannedKeys[2] = 1<<(8*b.z);\n" -" scannedKeys[3] = 1<<(8*b.w);\n" -" { // 4 scans at once\n" -" u32 sum4 = 0;\n" -" for(int ie=0; ie<4; ie++)\n" -" {\n" -" u32 tmp = scannedKeys[ie];\n" -" scannedKeys[ie] = sum4;\n" -" sum4 += tmp;\n" -" }\n" -" }\n" -" {\n" -" u32 sumPlusRank = sumScanned + rankPacked;\n" -" { u32 ie = b.x;\n" -" scannedKeys[0] += sumPlusRank;\n" -" newOffset[0] = unpack4Key( scannedKeys[0], ie );\n" -" }\n" -" { u32 ie = b.y;\n" -" scannedKeys[1] += sumPlusRank;\n" -" newOffset[1] = unpack4Key( scannedKeys[1], ie );\n" -" }\n" -" { u32 ie = b.z;\n" -" scannedKeys[2] += sumPlusRank;\n" -" newOffset[2] = unpack4Key( scannedKeys[2], ie );\n" -" }\n" -" { u32 ie = b.w;\n" -" scannedKeys[3] += sumPlusRank;\n" -" newOffset[3] = unpack4Key( scannedKeys[3], ie );\n" -" }\n" -" }\n" -" }\n" -" GROUP_LDS_BARRIER;\n" -" {\n" -" ldsSortData[newOffset[0]] = sortData[0];\n" -" ldsSortData[newOffset[1]] = sortData[1];\n" -" ldsSortData[newOffset[2]] = sortData[2];\n" -" ldsSortData[newOffset[3]] = sortData[3];\n" -" ldsSortVal[newOffset[0]] = sortVal[0];\n" -" ldsSortVal[newOffset[1]] = sortVal[1];\n" -" ldsSortVal[newOffset[2]] = sortVal[2];\n" -" ldsSortVal[newOffset[3]] = sortVal[3];\n" -" GROUP_LDS_BARRIER;\n" -" u32 dstAddr = 4*lIdx;\n" -" sortData[0] = ldsSortData[dstAddr+0];\n" -" sortData[1] = ldsSortData[dstAddr+1];\n" -" sortData[2] = ldsSortData[dstAddr+2];\n" -" sortData[3] = ldsSortData[dstAddr+3];\n" -" sortVal[0] = ldsSortVal[dstAddr+0];\n" -" sortVal[1] = ldsSortVal[dstAddr+1];\n" -" sortVal[2] = ldsSortVal[dstAddr+2];\n" -" sortVal[3] = ldsSortVal[dstAddr+3];\n" -" GROUP_LDS_BARRIER;\n" -" }\n" -" }\n" -"}\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" -"void SortAndScatterSortDataKernel( __global const SortDataCL* restrict gSrc, __global const u32* rHistogram, __global SortDataCL* restrict gDst, int4 cb)\n" -"{\n" -" __local int ldsSortData[WG_SIZE*ELEMENTS_PER_WORK_ITEM+16];\n" -" __local int ldsSortVal[WG_SIZE*ELEMENTS_PER_WORK_ITEM+16];\n" -" __local u32 localHistogramToCarry[NUM_BUCKET];\n" -" __local u32 localHistogram[NUM_BUCKET*2];\n" -" u32 gIdx = GET_GLOBAL_IDX;\n" -" u32 lIdx = GET_LOCAL_IDX;\n" -" u32 wgIdx = GET_GROUP_IDX;\n" -" u32 wgSize = GET_GROUP_SIZE;\n" -" const int n = cb.m_n;\n" -" const int nWGs = cb.m_nWGs;\n" -" const int startBit = cb.m_startBit;\n" -" const int nBlocksPerWG = cb.m_nBlocksPerWG;\n" -" if( lIdx < (NUM_BUCKET) )\n" -" {\n" -" localHistogramToCarry[lIdx] = rHistogram[lIdx*nWGs + wgIdx];\n" -" }\n" -" GROUP_LDS_BARRIER;\n" -" \n" -" const int blockSize = ELEMENTS_PER_WORK_ITEM*WG_SIZE;\n" -" int nBlocks = n/blockSize - nBlocksPerWG*wgIdx;\n" -" int addr = blockSize*nBlocksPerWG*wgIdx + ELEMENTS_PER_WORK_ITEM*lIdx;\n" -" for(int iblock=0; iblock>startBit) & 0xf;\n" -" { // create histogram\n" -" u32 setIdx = lIdx/16;\n" -" if( lIdx < NUM_BUCKET )\n" -" {\n" -" localHistogram[lIdx] = 0;\n" -" }\n" -" ldsSortData[lIdx] = 0;\n" -" GROUP_LDS_BARRIER;\n" -" for(int i=0; i0)\n" -" return;\n" -" \n" -" for (int c=0;c>startBit) & 0xf;//0xf = NUM_TABLES-1\n" -" gDst[rHistogram[tableIdx*nWGs+wgIdx] + counter[tableIdx]] = gSrc[i];\n" -" counter[tableIdx] ++;\n" -" }\n" -" }\n" -" }\n" -" }\n" -" \n" -"}\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" -"void SortAndScatterKernelSerial( __global const u32* restrict gSrc, __global const u32* rHistogram, __global u32* restrict gDst, int4 cb )\n" -"{\n" -" \n" -" u32 gIdx = GET_GLOBAL_IDX;\n" -" u32 realLocalIdx = GET_LOCAL_IDX;\n" -" u32 wgIdx = GET_GROUP_IDX;\n" -" u32 wgSize = GET_GROUP_SIZE;\n" -" const int startBit = cb.m_startBit;\n" -" const int n = cb.m_n;\n" -" const int nWGs = cb.m_nWGs;\n" -" const int nBlocksPerWG = cb.m_nBlocksPerWG;\n" -" int counter[NUM_BUCKET];\n" -" \n" -" if (realLocalIdx>0)\n" -" return;\n" -" \n" -" for (int c=0;c>startBit) & 0xf;//0xf = NUM_TABLES-1\n" -" gDst[rHistogram[tableIdx*nWGs+wgIdx] + counter[tableIdx]] = gSrc[i];\n" -" counter[tableIdx] ++;\n" -" }\n" -" }\n" -" }\n" -" }\n" -" \n" -"}\n" -; +static const char* radixSort32KernelsCL = + "/*\n" + "Bullet Continuous Collision Detection and Physics Library\n" + "Copyright (c) 2011 Advanced Micro Devices, Inc. http://bulletphysics.org\n" + "This software is provided 'as-is', without any express or implied warranty.\n" + "In no event will the authors be held liable for any damages arising from the use of this software.\n" + "Permission is granted to anyone to use this software for any purpose, \n" + "including commercial applications, and to alter it and redistribute it freely, \n" + "subject to the following restrictions:\n" + "1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" + "2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" + "3. This notice may not be removed or altered from any source distribution.\n" + "*/\n" + "//Author Takahiro Harada\n" + "//#pragma OPENCL EXTENSION cl_amd_printf : enable\n" + "#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" + "#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n" + "typedef unsigned int u32;\n" + "#define GET_GROUP_IDX get_group_id(0)\n" + "#define GET_LOCAL_IDX get_local_id(0)\n" + "#define GET_GLOBAL_IDX get_global_id(0)\n" + "#define GET_GROUP_SIZE get_local_size(0)\n" + "#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" + "#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" + "#define AtomInc(x) atom_inc(&(x))\n" + "#define AtomInc1(x, out) out = atom_inc(&(x))\n" + "#define AtomAdd(x, value) atom_add(&(x), value)\n" + "#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n" + "#define make_uint4 (uint4)\n" + "#define make_uint2 (uint2)\n" + "#define make_int2 (int2)\n" + "#define WG_SIZE 64\n" + "#define ELEMENTS_PER_WORK_ITEM (256/WG_SIZE)\n" + "#define BITS_PER_PASS 4\n" + "#define NUM_BUCKET (1< 64 )\n" + " {\n" + " sorterSharedMemory[idx] += sorterSharedMemory[idx-64];\n" + " GROUP_MEM_FENCE;\n" + " }\n" + " sorterSharedMemory[idx-1] += sorterSharedMemory[idx-2];\n" + " GROUP_MEM_FENCE;\n" + " }\n" + "#else\n" + " if( lIdx < 64 )\n" + " {\n" + " sorterSharedMemory[idx] += sorterSharedMemory[idx-1];\n" + " GROUP_MEM_FENCE;\n" + " sorterSharedMemory[idx] += sorterSharedMemory[idx-2]; \n" + " GROUP_MEM_FENCE;\n" + " sorterSharedMemory[idx] += sorterSharedMemory[idx-4];\n" + " GROUP_MEM_FENCE;\n" + " sorterSharedMemory[idx] += sorterSharedMemory[idx-8];\n" + " GROUP_MEM_FENCE;\n" + " sorterSharedMemory[idx] += sorterSharedMemory[idx-16];\n" + " GROUP_MEM_FENCE;\n" + " sorterSharedMemory[idx] += sorterSharedMemory[idx-32];\n" + " GROUP_MEM_FENCE;\n" + " if( wgSize > 64 )\n" + " {\n" + " sorterSharedMemory[idx] += sorterSharedMemory[idx-64];\n" + " GROUP_MEM_FENCE;\n" + " }\n" + " sorterSharedMemory[idx-1] += sorterSharedMemory[idx-2];\n" + " GROUP_MEM_FENCE;\n" + " }\n" + "#endif\n" + " }\n" + " GROUP_LDS_BARRIER;\n" + " *totalSum = sorterSharedMemory[wgSize*2-1];\n" + " u32 addValue = sorterSharedMemory[lIdx+wgSize-1];\n" + " return addValue;\n" + "}\n" + "//__attribute__((reqd_work_group_size(128,1,1)))\n" + "uint4 localPrefixSum128V( uint4 pData, uint lIdx, uint* totalSum, __local u32* sorterSharedMemory )\n" + "{\n" + " u32 s4 = prefixScanVectorEx( &pData );\n" + " u32 rank = localPrefixSum( s4, lIdx, totalSum, sorterSharedMemory, 128 );\n" + " return pData + make_uint4( rank, rank, rank, rank );\n" + "}\n" + "//__attribute__((reqd_work_group_size(64,1,1)))\n" + "uint4 localPrefixSum64V( uint4 pData, uint lIdx, uint* totalSum, __local u32* sorterSharedMemory )\n" + "{\n" + " u32 s4 = prefixScanVectorEx( &pData );\n" + " u32 rank = localPrefixSum( s4, lIdx, totalSum, sorterSharedMemory, 64 );\n" + " return pData + make_uint4( rank, rank, rank, rank );\n" + "}\n" + "u32 unpack4Key( u32 key, int keyIdx ){ return (key>>(keyIdx*8)) & 0xff;}\n" + "u32 bit8Scan(u32 v)\n" + "{\n" + " return (v<<8) + (v<<16) + (v<<24);\n" + "}\n" + "//===\n" + "#define MY_HISTOGRAM(idx) localHistogramMat[(idx)*WG_SIZE+lIdx]\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" + "void StreamCountKernel( __global u32* gSrc, __global u32* histogramOut, int4 cb )\n" + "{\n" + " __local u32 localHistogramMat[NUM_BUCKET*WG_SIZE];\n" + " u32 gIdx = GET_GLOBAL_IDX;\n" + " u32 lIdx = GET_LOCAL_IDX;\n" + " u32 wgIdx = GET_GROUP_IDX;\n" + " u32 wgSize = GET_GROUP_SIZE;\n" + " const int startBit = cb.m_startBit;\n" + " const int n = cb.m_n;\n" + " const int nWGs = cb.m_nWGs;\n" + " const int nBlocksPerWG = cb.m_nBlocksPerWG;\n" + " for(int i=0; i>startBit) & 0xf;\n" + "#if defined(NV_GPU)\n" + " MY_HISTOGRAM( localKey )++;\n" + "#else\n" + " AtomInc( MY_HISTOGRAM( localKey ) );\n" + "#endif\n" + " }\n" + " }\n" + " }\n" + " GROUP_LDS_BARRIER;\n" + " \n" + " if( lIdx < NUM_BUCKET )\n" + " {\n" + " u32 sum = 0;\n" + " for(int i=0; i>startBit) & 0xf;\n" + "#if defined(NV_GPU)\n" + " MY_HISTOGRAM( localKey )++;\n" + "#else\n" + " AtomInc( MY_HISTOGRAM( localKey ) );\n" + "#endif\n" + " }\n" + " }\n" + " }\n" + " GROUP_LDS_BARRIER;\n" + " \n" + " if( lIdx < NUM_BUCKET )\n" + " {\n" + " u32 sum = 0;\n" + " for(int i=0; i>startBit) & mask, (sortData[1]>>startBit) & mask, (sortData[2]>>startBit) & mask, (sortData[3]>>startBit) & mask );\n" + " uint4 prefixSum = SELECT_UINT4( make_uint4(1,1,1,1), make_uint4(0,0,0,0), cmpResult != make_uint4(0,0,0,0) );\n" + " u32 total;\n" + " prefixSum = localPrefixSum64V( prefixSum, lIdx, &total, ldsSortData );\n" + " {\n" + " uint4 localAddr = make_uint4(lIdx*4+0,lIdx*4+1,lIdx*4+2,lIdx*4+3);\n" + " uint4 dstAddr = localAddr - prefixSum + make_uint4( total, total, total, total );\n" + " dstAddr = SELECT_UINT4( prefixSum, dstAddr, cmpResult != make_uint4(0, 0, 0, 0) );\n" + " GROUP_LDS_BARRIER;\n" + " ldsSortData[dstAddr.x] = sortData[0];\n" + " ldsSortData[dstAddr.y] = sortData[1];\n" + " ldsSortData[dstAddr.z] = sortData[2];\n" + " ldsSortData[dstAddr.w] = sortData[3];\n" + " GROUP_LDS_BARRIER;\n" + " sortData[0] = ldsSortData[localAddr.x];\n" + " sortData[1] = ldsSortData[localAddr.y];\n" + " sortData[2] = ldsSortData[localAddr.z];\n" + " sortData[3] = ldsSortData[localAddr.w];\n" + " GROUP_LDS_BARRIER;\n" + " }\n" + " }\n" + "}\n" + "// 2 scan, 2 exchange\n" + "void sort4Bits1(u32 sortData[4], int startBit, int lIdx, __local u32* ldsSortData)\n" + "{\n" + " for(uint ibit=0; ibit>(startBit+ibit)) & 0x3, \n" + " (sortData[1]>>(startBit+ibit)) & 0x3, \n" + " (sortData[2]>>(startBit+ibit)) & 0x3, \n" + " (sortData[3]>>(startBit+ibit)) & 0x3);\n" + " u32 key4;\n" + " u32 sKeyPacked[4] = { 0, 0, 0, 0 };\n" + " {\n" + " sKeyPacked[0] |= 1<<(8*b.x);\n" + " sKeyPacked[1] |= 1<<(8*b.y);\n" + " sKeyPacked[2] |= 1<<(8*b.z);\n" + " sKeyPacked[3] |= 1<<(8*b.w);\n" + " key4 = sKeyPacked[0] + sKeyPacked[1] + sKeyPacked[2] + sKeyPacked[3];\n" + " }\n" + " u32 rankPacked;\n" + " u32 sumPacked;\n" + " {\n" + " rankPacked = localPrefixSum( key4, lIdx, &sumPacked, ldsSortData, WG_SIZE );\n" + " }\n" + " GROUP_LDS_BARRIER;\n" + " u32 newOffset[4] = { 0,0,0,0 };\n" + " {\n" + " u32 sumScanned = bit8Scan( sumPacked );\n" + " u32 scannedKeys[4];\n" + " scannedKeys[0] = 1<<(8*b.x);\n" + " scannedKeys[1] = 1<<(8*b.y);\n" + " scannedKeys[2] = 1<<(8*b.z);\n" + " scannedKeys[3] = 1<<(8*b.w);\n" + " { // 4 scans at once\n" + " u32 sum4 = 0;\n" + " for(int ie=0; ie<4; ie++)\n" + " {\n" + " u32 tmp = scannedKeys[ie];\n" + " scannedKeys[ie] = sum4;\n" + " sum4 += tmp;\n" + " }\n" + " }\n" + " {\n" + " u32 sumPlusRank = sumScanned + rankPacked;\n" + " { u32 ie = b.x;\n" + " scannedKeys[0] += sumPlusRank;\n" + " newOffset[0] = unpack4Key( scannedKeys[0], ie );\n" + " }\n" + " { u32 ie = b.y;\n" + " scannedKeys[1] += sumPlusRank;\n" + " newOffset[1] = unpack4Key( scannedKeys[1], ie );\n" + " }\n" + " { u32 ie = b.z;\n" + " scannedKeys[2] += sumPlusRank;\n" + " newOffset[2] = unpack4Key( scannedKeys[2], ie );\n" + " }\n" + " { u32 ie = b.w;\n" + " scannedKeys[3] += sumPlusRank;\n" + " newOffset[3] = unpack4Key( scannedKeys[3], ie );\n" + " }\n" + " }\n" + " }\n" + " GROUP_LDS_BARRIER;\n" + " {\n" + " ldsSortData[newOffset[0]] = sortData[0];\n" + " ldsSortData[newOffset[1]] = sortData[1];\n" + " ldsSortData[newOffset[2]] = sortData[2];\n" + " ldsSortData[newOffset[3]] = sortData[3];\n" + " GROUP_LDS_BARRIER;\n" + " u32 dstAddr = 4*lIdx;\n" + " sortData[0] = ldsSortData[dstAddr+0];\n" + " sortData[1] = ldsSortData[dstAddr+1];\n" + " sortData[2] = ldsSortData[dstAddr+2];\n" + " sortData[3] = ldsSortData[dstAddr+3];\n" + " GROUP_LDS_BARRIER;\n" + " }\n" + " }\n" + "}\n" + "#define SET_HISTOGRAM(setIdx, key) ldsSortData[(setIdx)*NUM_BUCKET+key]\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" + "void SortAndScatterKernel( __global const u32* restrict gSrc, __global const u32* rHistogram, __global u32* restrict gDst, int4 cb )\n" + "{\n" + " __local u32 ldsSortData[WG_SIZE*ELEMENTS_PER_WORK_ITEM+16];\n" + " __local u32 localHistogramToCarry[NUM_BUCKET];\n" + " __local u32 localHistogram[NUM_BUCKET*2];\n" + " u32 gIdx = GET_GLOBAL_IDX;\n" + " u32 lIdx = GET_LOCAL_IDX;\n" + " u32 wgIdx = GET_GROUP_IDX;\n" + " u32 wgSize = GET_GROUP_SIZE;\n" + " const int n = cb.m_n;\n" + " const int nWGs = cb.m_nWGs;\n" + " const int startBit = cb.m_startBit;\n" + " const int nBlocksPerWG = cb.m_nBlocksPerWG;\n" + " if( lIdx < (NUM_BUCKET) )\n" + " {\n" + " localHistogramToCarry[lIdx] = rHistogram[lIdx*nWGs + wgIdx];\n" + " }\n" + " GROUP_LDS_BARRIER;\n" + " const int blockSize = ELEMENTS_PER_WORK_ITEM*WG_SIZE;\n" + " int nBlocks = n/blockSize - nBlocksPerWG*wgIdx;\n" + " int addr = blockSize*nBlocksPerWG*wgIdx + ELEMENTS_PER_WORK_ITEM*lIdx;\n" + " for(int iblock=0; iblock>startBit) & 0xf;\n" + " { // create histogram\n" + " u32 setIdx = lIdx/16;\n" + " if( lIdx < NUM_BUCKET )\n" + " {\n" + " localHistogram[lIdx] = 0;\n" + " }\n" + " ldsSortData[lIdx] = 0;\n" + " GROUP_LDS_BARRIER;\n" + " for(int i=0; i>(startBit+ibit)) & 0x3, \n" + " (sortData[1]>>(startBit+ibit)) & 0x3, \n" + " (sortData[2]>>(startBit+ibit)) & 0x3, \n" + " (sortData[3]>>(startBit+ibit)) & 0x3);\n" + " u32 key4;\n" + " u32 sKeyPacked[4] = { 0, 0, 0, 0 };\n" + " {\n" + " sKeyPacked[0] |= 1<<(8*b.x);\n" + " sKeyPacked[1] |= 1<<(8*b.y);\n" + " sKeyPacked[2] |= 1<<(8*b.z);\n" + " sKeyPacked[3] |= 1<<(8*b.w);\n" + " key4 = sKeyPacked[0] + sKeyPacked[1] + sKeyPacked[2] + sKeyPacked[3];\n" + " }\n" + " u32 rankPacked;\n" + " u32 sumPacked;\n" + " {\n" + " rankPacked = localPrefixSum( key4, lIdx, &sumPacked, ldsSortData, WG_SIZE );\n" + " }\n" + " GROUP_LDS_BARRIER;\n" + " u32 newOffset[4] = { 0,0,0,0 };\n" + " {\n" + " u32 sumScanned = bit8Scan( sumPacked );\n" + " u32 scannedKeys[4];\n" + " scannedKeys[0] = 1<<(8*b.x);\n" + " scannedKeys[1] = 1<<(8*b.y);\n" + " scannedKeys[2] = 1<<(8*b.z);\n" + " scannedKeys[3] = 1<<(8*b.w);\n" + " { // 4 scans at once\n" + " u32 sum4 = 0;\n" + " for(int ie=0; ie<4; ie++)\n" + " {\n" + " u32 tmp = scannedKeys[ie];\n" + " scannedKeys[ie] = sum4;\n" + " sum4 += tmp;\n" + " }\n" + " }\n" + " {\n" + " u32 sumPlusRank = sumScanned + rankPacked;\n" + " { u32 ie = b.x;\n" + " scannedKeys[0] += sumPlusRank;\n" + " newOffset[0] = unpack4Key( scannedKeys[0], ie );\n" + " }\n" + " { u32 ie = b.y;\n" + " scannedKeys[1] += sumPlusRank;\n" + " newOffset[1] = unpack4Key( scannedKeys[1], ie );\n" + " }\n" + " { u32 ie = b.z;\n" + " scannedKeys[2] += sumPlusRank;\n" + " newOffset[2] = unpack4Key( scannedKeys[2], ie );\n" + " }\n" + " { u32 ie = b.w;\n" + " scannedKeys[3] += sumPlusRank;\n" + " newOffset[3] = unpack4Key( scannedKeys[3], ie );\n" + " }\n" + " }\n" + " }\n" + " GROUP_LDS_BARRIER;\n" + " {\n" + " ldsSortData[newOffset[0]] = sortData[0];\n" + " ldsSortData[newOffset[1]] = sortData[1];\n" + " ldsSortData[newOffset[2]] = sortData[2];\n" + " ldsSortData[newOffset[3]] = sortData[3];\n" + " ldsSortVal[newOffset[0]] = sortVal[0];\n" + " ldsSortVal[newOffset[1]] = sortVal[1];\n" + " ldsSortVal[newOffset[2]] = sortVal[2];\n" + " ldsSortVal[newOffset[3]] = sortVal[3];\n" + " GROUP_LDS_BARRIER;\n" + " u32 dstAddr = 4*lIdx;\n" + " sortData[0] = ldsSortData[dstAddr+0];\n" + " sortData[1] = ldsSortData[dstAddr+1];\n" + " sortData[2] = ldsSortData[dstAddr+2];\n" + " sortData[3] = ldsSortData[dstAddr+3];\n" + " sortVal[0] = ldsSortVal[dstAddr+0];\n" + " sortVal[1] = ldsSortVal[dstAddr+1];\n" + " sortVal[2] = ldsSortVal[dstAddr+2];\n" + " sortVal[3] = ldsSortVal[dstAddr+3];\n" + " GROUP_LDS_BARRIER;\n" + " }\n" + " }\n" + "}\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" + "void SortAndScatterSortDataKernel( __global const SortDataCL* restrict gSrc, __global const u32* rHistogram, __global SortDataCL* restrict gDst, int4 cb)\n" + "{\n" + " __local int ldsSortData[WG_SIZE*ELEMENTS_PER_WORK_ITEM+16];\n" + " __local int ldsSortVal[WG_SIZE*ELEMENTS_PER_WORK_ITEM+16];\n" + " __local u32 localHistogramToCarry[NUM_BUCKET];\n" + " __local u32 localHistogram[NUM_BUCKET*2];\n" + " u32 gIdx = GET_GLOBAL_IDX;\n" + " u32 lIdx = GET_LOCAL_IDX;\n" + " u32 wgIdx = GET_GROUP_IDX;\n" + " u32 wgSize = GET_GROUP_SIZE;\n" + " const int n = cb.m_n;\n" + " const int nWGs = cb.m_nWGs;\n" + " const int startBit = cb.m_startBit;\n" + " const int nBlocksPerWG = cb.m_nBlocksPerWG;\n" + " if( lIdx < (NUM_BUCKET) )\n" + " {\n" + " localHistogramToCarry[lIdx] = rHistogram[lIdx*nWGs + wgIdx];\n" + " }\n" + " GROUP_LDS_BARRIER;\n" + " \n" + " const int blockSize = ELEMENTS_PER_WORK_ITEM*WG_SIZE;\n" + " int nBlocks = n/blockSize - nBlocksPerWG*wgIdx;\n" + " int addr = blockSize*nBlocksPerWG*wgIdx + ELEMENTS_PER_WORK_ITEM*lIdx;\n" + " for(int iblock=0; iblock>startBit) & 0xf;\n" + " { // create histogram\n" + " u32 setIdx = lIdx/16;\n" + " if( lIdx < NUM_BUCKET )\n" + " {\n" + " localHistogram[lIdx] = 0;\n" + " }\n" + " ldsSortData[lIdx] = 0;\n" + " GROUP_LDS_BARRIER;\n" + " for(int i=0; i0)\n" + " return;\n" + " \n" + " for (int c=0;c>startBit) & 0xf;//0xf = NUM_TABLES-1\n" + " gDst[rHistogram[tableIdx*nWGs+wgIdx] + counter[tableIdx]] = gSrc[i];\n" + " counter[tableIdx] ++;\n" + " }\n" + " }\n" + " }\n" + " }\n" + " \n" + "}\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" + "void SortAndScatterKernelSerial( __global const u32* restrict gSrc, __global const u32* rHistogram, __global u32* restrict gDst, int4 cb )\n" + "{\n" + " \n" + " u32 gIdx = GET_GLOBAL_IDX;\n" + " u32 realLocalIdx = GET_LOCAL_IDX;\n" + " u32 wgIdx = GET_GROUP_IDX;\n" + " u32 wgSize = GET_GROUP_SIZE;\n" + " const int startBit = cb.m_startBit;\n" + " const int n = cb.m_n;\n" + " const int nWGs = cb.m_nWGs;\n" + " const int nBlocksPerWG = cb.m_nBlocksPerWG;\n" + " int counter[NUM_BUCKET];\n" + " \n" + " if (realLocalIdx>0)\n" + " return;\n" + " \n" + " for (int c=0;c>startBit) & 0xf;//0xf = NUM_TABLES-1\n" + " gDst[rHistogram[tableIdx*nWGs+wgIdx] + counter[tableIdx]] = gSrc[i];\n" + " counter[tableIdx] ++;\n" + " }\n" + " }\n" + " }\n" + " }\n" + " \n" + "}\n"; diff --git a/src/Bullet3OpenCL/Raycast/b3GpuRaycast.cpp b/src/Bullet3OpenCL/Raycast/b3GpuRaycast.cpp index 161e304f0..6571f3054 100644 --- a/src/Bullet3OpenCL/Raycast/b3GpuRaycast.cpp +++ b/src/Bullet3OpenCL/Raycast/b3GpuRaycast.cpp @@ -4,7 +4,6 @@ #include "Bullet3Collision/NarrowPhaseCollision/shared/b3RigidBodyData.h" #include "Bullet3OpenCL/RigidBody/b3GpuNarrowPhaseInternalData.h" - #include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h" #include "Bullet3OpenCL/ParallelPrimitives/b3OpenCLArray.h" #include "Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h" @@ -15,38 +14,35 @@ #include "Bullet3OpenCL/Raycast/kernels/rayCastKernels.h" - #define B3_RAYCAST_PATH "src/Bullet3OpenCL/Raycast/kernels/rayCastKernels.cl" - - struct b3GpuRaycastInternalData { cl_context m_context; cl_device_id m_device; - cl_command_queue m_q; + cl_command_queue m_q; cl_kernel m_raytraceKernel; cl_kernel m_raytracePairsKernel; cl_kernel m_findRayRigidPairIndexRanges; - + b3GpuParallelLinearBvh* m_plbvh; b3RadixSort32CL* m_radixSorter; b3FillCL* m_fill; - + //1 element per ray b3OpenCLArray* m_gpuRays; b3OpenCLArray* m_gpuHitResults; b3OpenCLArray* m_firstRayRigidPairIndexPerRay; b3OpenCLArray* m_numRayRigidPairsPerRay; - + //1 element per (ray index, rigid index) pair, where the ray intersects with the rigid's AABB b3OpenCLArray* m_gpuNumRayRigidPairs; - b3OpenCLArray* m_gpuRayRigidPairs; //x == ray index, y == rigid index - + b3OpenCLArray* m_gpuRayRigidPairs; //x == ray index, y == rigid index + int m_test; }; -b3GpuRaycast::b3GpuRaycast(cl_context ctx,cl_device_id device, cl_command_queue q) +b3GpuRaycast::b3GpuRaycast(cl_context ctx, cl_device_id device, cl_command_queue q) { m_data = new b3GpuRaycastInternalData; m_data->m_context = ctx; @@ -59,7 +55,7 @@ b3GpuRaycast::b3GpuRaycast(cl_context ctx,cl_device_id device, cl_command_queue m_data->m_plbvh = new b3GpuParallelLinearBvh(ctx, device, q); m_data->m_radixSorter = new b3RadixSort32CL(ctx, device, q); m_data->m_fill = new b3FillCL(ctx, device, q); - + m_data->m_gpuRays = new b3OpenCLArray(ctx, q); m_data->m_gpuHitResults = new b3OpenCLArray(ctx, q); m_data->m_firstRayRigidPairIndexPerRay = new b3OpenCLArray(ctx, q); @@ -68,19 +64,17 @@ b3GpuRaycast::b3GpuRaycast(cl_context ctx,cl_device_id device, cl_command_queue m_data->m_gpuRayRigidPairs = new b3OpenCLArray(ctx, q); { - cl_int errNum=0; - cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_data->m_context,m_data->m_device,rayCastKernelCL,&errNum,"",B3_RAYCAST_PATH); - b3Assert(errNum==CL_SUCCESS); - m_data->m_raytraceKernel = b3OpenCLUtils::compileCLKernelFromString(m_data->m_context, m_data->m_device,rayCastKernelCL, "rayCastKernel",&errNum,prog); - b3Assert(errNum==CL_SUCCESS); - m_data->m_raytracePairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_data->m_context, m_data->m_device,rayCastKernelCL, "rayCastPairsKernel",&errNum,prog); - b3Assert(errNum==CL_SUCCESS); - m_data->m_findRayRigidPairIndexRanges = b3OpenCLUtils::compileCLKernelFromString(m_data->m_context, m_data->m_device,rayCastKernelCL, "findRayRigidPairIndexRanges",&errNum,prog); - b3Assert(errNum==CL_SUCCESS); + cl_int errNum = 0; + cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_data->m_context, m_data->m_device, rayCastKernelCL, &errNum, "", B3_RAYCAST_PATH); + b3Assert(errNum == CL_SUCCESS); + m_data->m_raytraceKernel = b3OpenCLUtils::compileCLKernelFromString(m_data->m_context, m_data->m_device, rayCastKernelCL, "rayCastKernel", &errNum, prog); + b3Assert(errNum == CL_SUCCESS); + m_data->m_raytracePairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_data->m_context, m_data->m_device, rayCastKernelCL, "rayCastPairsKernel", &errNum, prog); + b3Assert(errNum == CL_SUCCESS); + m_data->m_findRayRigidPairIndexRanges = b3OpenCLUtils::compileCLKernelFromString(m_data->m_context, m_data->m_device, rayCastKernelCL, "findRayRigidPairIndexRanges", &errNum, prog); + b3Assert(errNum == CL_SUCCESS); clReleaseProgram(prog); } - - } b3GpuRaycast::~b3GpuRaycast() @@ -88,78 +82,80 @@ b3GpuRaycast::~b3GpuRaycast() clReleaseKernel(m_data->m_raytraceKernel); clReleaseKernel(m_data->m_raytracePairsKernel); clReleaseKernel(m_data->m_findRayRigidPairIndexRanges); - + delete m_data->m_plbvh; delete m_data->m_radixSorter; delete m_data->m_fill; - + delete m_data->m_gpuRays; delete m_data->m_gpuHitResults; delete m_data->m_firstRayRigidPairIndexPerRay; delete m_data->m_numRayRigidPairsPerRay; delete m_data->m_gpuNumRayRigidPairs; delete m_data->m_gpuRayRigidPairs; - + delete m_data; } -bool sphere_intersect(const b3Vector3& spherePos, b3Scalar radius, const b3Vector3& rayFrom, const b3Vector3& rayTo, float& hitFraction) +bool sphere_intersect(const b3Vector3& spherePos, b3Scalar radius, const b3Vector3& rayFrom, const b3Vector3& rayTo, float& hitFraction) { - b3Vector3 rs = rayFrom - spherePos; - b3Vector3 rayDir = rayTo-rayFrom; - - float A = b3Dot(rayDir,rayDir); - float B = b3Dot(rs, rayDir); - float C = b3Dot(rs, rs) - (radius * radius); - - float D = B * B - A*C; + b3Vector3 rs = rayFrom - spherePos; + b3Vector3 rayDir = rayTo - rayFrom; - if (D > 0.0) - { - float t = (-B - sqrt(D))/A; + float A = b3Dot(rayDir, rayDir); + float B = b3Dot(rs, rayDir); + float C = b3Dot(rs, rs) - (radius * radius); - if ( (t >= 0.0f) && (t < hitFraction) ) - { + float D = B * B - A * C; + + if (D > 0.0) + { + float t = (-B - sqrt(D)) / A; + + if ((t >= 0.0f) && (t < hitFraction)) + { hitFraction = t; - return true; + return true; } } return false; } bool rayConvex(const b3Vector3& rayFromLocal, const b3Vector3& rayToLocal, const b3ConvexPolyhedronData& poly, - const b3AlignedObjectArray& faces, float& hitFraction, b3Vector3& hitNormal) + const b3AlignedObjectArray& faces, float& hitFraction, b3Vector3& hitNormal) { float exitFraction = hitFraction; float enterFraction = -0.1f; - b3Vector3 curHitNormal=b3MakeVector3(0,0,0); - for (int i=0;i= 0.f) { - float fraction = fromPlaneDist / (fromPlaneDist-toPlaneDist); - if (exitFraction>fraction) + float fraction = fromPlaneDist / (fromPlaneDist - toPlaneDist); + if (exitFraction > fraction) { exitFraction = fraction; } - } - } else + } + } + else { - if (toPlaneDist<0.f) + if (toPlaneDist < 0.f) { - float fraction = fromPlaneDist / (fromPlaneDist-toPlaneDist); + float fraction = fromPlaneDist / (fromPlaneDist - toPlaneDist); if (enterFraction <= fraction) { enterFraction = fraction; curHitNormal = face.m_plane; curHitNormal.w = 0.f; } - } else + } + else { return false; } @@ -176,44 +172,41 @@ bool rayConvex(const b3Vector3& rayFromLocal, const b3Vector3& rayToLocal, const return true; } -void b3GpuRaycast::castRaysHost(const b3AlignedObjectArray& rays, b3AlignedObjectArray& hitResults, - int numBodies,const struct b3RigidBodyData* bodies, int numCollidables,const struct b3Collidable* collidables, const struct b3GpuNarrowPhaseInternalData* narrowphaseData) +void b3GpuRaycast::castRaysHost(const b3AlignedObjectArray& rays, b3AlignedObjectArray& hitResults, + int numBodies, const struct b3RigidBodyData* bodies, int numCollidables, const struct b3Collidable* collidables, const struct b3GpuNarrowPhaseInternalData* narrowphaseData) { - -// return castRays(rays,hitResults,numBodies,bodies,numCollidables,collidables); + // return castRays(rays,hitResults,numBodies,bodies,numCollidables,collidables); B3_PROFILE("castRaysHost"); - for (int r=0;r& rays, b3A b3Vector3 rayFromLocal = convexWorld2Local(rayFrom); b3Vector3 rayToLocal = convexWorld2Local(rayTo); - - + int shapeIndex = collidables[bodies[b].m_collidableIdx].m_shapeIndex; const b3ConvexPolyhedronData& poly = narrowphaseData->m_convexPolyhedra[shapeIndex]; - if (rayConvex(rayFromLocal, rayToLocal,poly,narrowphaseData->m_convexFaces, hitFraction, hitNormal)) + if (rayConvex(rayFromLocal, rayToLocal, poly, narrowphaseData->m_convexFaces, hitFraction, hitNormal)) { hitBodyIndex = b; } - break; } - default: + default: { - static bool once=true; + static bool once = true; if (once) { - once=false; + once = false; b3Warning("Raytest: unsupported shape type\n"); } } } } - if (hitBodyIndex>=0) + if (hitBodyIndex >= 0) { - hitResults[r].m_hitFraction = hitFraction; - hitResults[r].m_hitPoint.setInterpolate3(rays[r].m_from, rays[r].m_to,hitFraction); + hitResults[r].m_hitPoint.setInterpolate3(rays[r].m_from, rays[r].m_to, hitFraction); hitResults[r].m_hitNormal = hitNormal; hitResults[r].m_hitBody = hitBodyIndex; } - } } ///todo: add some acceleration structure (AABBs, tree etc) -void b3GpuRaycast::castRays(const b3AlignedObjectArray& rays, b3AlignedObjectArray& hitResults, - int numBodies,const struct b3RigidBodyData* bodies, int numCollidables, const struct b3Collidable* collidables, - const struct b3GpuNarrowPhaseInternalData* narrowphaseData, class b3GpuBroadphaseInterface* broadphase) +void b3GpuRaycast::castRays(const b3AlignedObjectArray& rays, b3AlignedObjectArray& hitResults, + int numBodies, const struct b3RigidBodyData* bodies, int numCollidables, const struct b3Collidable* collidables, + const struct b3GpuNarrowPhaseInternalData* narrowphaseData, class b3GpuBroadphaseInterface* broadphase) { //castRaysHost(rays,hitResults,numBodies,bodies,numCollidables,collidables,narrowphaseData); B3_PROFILE("castRaysGPU"); - + { B3_PROFILE("raycast copyFromHost"); m_data->m_gpuRays->copyFromHost(rays); m_data->m_gpuHitResults->copyFromHost(hitResults); - } - + int numRays = hitResults.size(); { m_data->m_firstRayRigidPairIndexPerRay->resize(numRays); m_data->m_numRayRigidPairsPerRay->resize(numRays); - + m_data->m_gpuNumRayRigidPairs->resize(1); m_data->m_gpuRayRigidPairs->resize(numRays * 16); } - + //run kernel const bool USE_BRUTE_FORCE_RAYCAST = false; - if(USE_BRUTE_FORCE_RAYCAST) + if (USE_BRUTE_FORCE_RAYCAST) { B3_PROFILE("raycast launch1D"); - b3LauncherCL launcher(m_data->m_q,m_data->m_raytraceKernel,"m_raytraceKernel"); + b3LauncherCL launcher(m_data->m_q, m_data->m_raytraceKernel, "m_raytraceKernel"); int numRays = rays.size(); launcher.setConst(numRays); @@ -299,93 +287,88 @@ void b3GpuRaycast::castRays(const b3AlignedObjectArray& rays, b3Align launcher.setBuffer(narrowphaseData->m_collidablesGPU->getBufferCL()); launcher.setBuffer(narrowphaseData->m_convexFacesGPU->getBufferCL()); launcher.setBuffer(narrowphaseData->m_convexPolyhedraGPU->getBufferCL()); - + launcher.launch1D(numRays); clFinish(m_data->m_q); } else { - m_data->m_plbvh->build( broadphase->getAllAabbsGPU(), broadphase->getSmallAabbIndicesGPU(), broadphase->getLargeAabbIndicesGPU() ); + m_data->m_plbvh->build(broadphase->getAllAabbsGPU(), broadphase->getSmallAabbIndicesGPU(), broadphase->getLargeAabbIndicesGPU()); m_data->m_plbvh->testRaysAgainstBvhAabbs(*m_data->m_gpuRays, *m_data->m_gpuNumRayRigidPairs, *m_data->m_gpuRayRigidPairs); - + int numRayRigidPairs = -1; m_data->m_gpuNumRayRigidPairs->copyToHostPointer(&numRayRigidPairs, 1); - if( numRayRigidPairs > m_data->m_gpuRayRigidPairs->size() ) + if (numRayRigidPairs > m_data->m_gpuRayRigidPairs->size()) { numRayRigidPairs = m_data->m_gpuRayRigidPairs->size(); m_data->m_gpuNumRayRigidPairs->copyFromHostPointer(&numRayRigidPairs, 1); } - - m_data->m_gpuRayRigidPairs->resize(numRayRigidPairs); //Radix sort needs b3OpenCLArray::size() to be correct - + + m_data->m_gpuRayRigidPairs->resize(numRayRigidPairs); //Radix sort needs b3OpenCLArray::size() to be correct + //Sort ray-rigid pairs by ray index { B3_PROFILE("sort ray-rigid pairs"); - m_data->m_radixSorter->execute( *reinterpret_cast< b3OpenCLArray* >(m_data->m_gpuRayRigidPairs) ); + m_data->m_radixSorter->execute(*reinterpret_cast*>(m_data->m_gpuRayRigidPairs)); } - + //detect start,count of each ray pair { B3_PROFILE("detect ray-rigid pair index ranges"); - + { B3_PROFILE("reset ray-rigid pair index ranges"); - - m_data->m_fill->execute(*m_data->m_firstRayRigidPairIndexPerRay, numRayRigidPairs, numRays); //atomic_min used to find first index + + m_data->m_fill->execute(*m_data->m_firstRayRigidPairIndexPerRay, numRayRigidPairs, numRays); //atomic_min used to find first index m_data->m_fill->execute(*m_data->m_numRayRigidPairsPerRay, 0, numRays); clFinish(m_data->m_q); } - - b3BufferInfoCL bufferInfo[] = - { - b3BufferInfoCL( m_data->m_gpuRayRigidPairs->getBufferCL() ), - - b3BufferInfoCL( m_data->m_firstRayRigidPairIndexPerRay->getBufferCL() ), - b3BufferInfoCL( m_data->m_numRayRigidPairsPerRay->getBufferCL() ) - }; - + + b3BufferInfoCL bufferInfo[] = + { + b3BufferInfoCL(m_data->m_gpuRayRigidPairs->getBufferCL()), + + b3BufferInfoCL(m_data->m_firstRayRigidPairIndexPerRay->getBufferCL()), + b3BufferInfoCL(m_data->m_numRayRigidPairsPerRay->getBufferCL())}; + b3LauncherCL launcher(m_data->m_q, m_data->m_findRayRigidPairIndexRanges, "m_findRayRigidPairIndexRanges"); - launcher.setBuffers( bufferInfo, sizeof(bufferInfo)/sizeof(b3BufferInfoCL) ); + launcher.setBuffers(bufferInfo, sizeof(bufferInfo) / sizeof(b3BufferInfoCL)); launcher.setConst(numRayRigidPairs); - + launcher.launch1D(numRayRigidPairs); clFinish(m_data->m_q); } - + { B3_PROFILE("ray-rigid intersection"); - - b3BufferInfoCL bufferInfo[] = - { - b3BufferInfoCL( m_data->m_gpuRays->getBufferCL() ), - b3BufferInfoCL( m_data->m_gpuHitResults->getBufferCL() ), - b3BufferInfoCL( m_data->m_firstRayRigidPairIndexPerRay->getBufferCL() ), - b3BufferInfoCL( m_data->m_numRayRigidPairsPerRay->getBufferCL() ), - - b3BufferInfoCL( narrowphaseData->m_bodyBufferGPU->getBufferCL() ), - b3BufferInfoCL( narrowphaseData->m_collidablesGPU->getBufferCL() ), - b3BufferInfoCL( narrowphaseData->m_convexFacesGPU->getBufferCL() ), - b3BufferInfoCL( narrowphaseData->m_convexPolyhedraGPU->getBufferCL() ), - - b3BufferInfoCL( m_data->m_gpuRayRigidPairs->getBufferCL() ) - }; - + + b3BufferInfoCL bufferInfo[] = + { + b3BufferInfoCL(m_data->m_gpuRays->getBufferCL()), + b3BufferInfoCL(m_data->m_gpuHitResults->getBufferCL()), + b3BufferInfoCL(m_data->m_firstRayRigidPairIndexPerRay->getBufferCL()), + b3BufferInfoCL(m_data->m_numRayRigidPairsPerRay->getBufferCL()), + + b3BufferInfoCL(narrowphaseData->m_bodyBufferGPU->getBufferCL()), + b3BufferInfoCL(narrowphaseData->m_collidablesGPU->getBufferCL()), + b3BufferInfoCL(narrowphaseData->m_convexFacesGPU->getBufferCL()), + b3BufferInfoCL(narrowphaseData->m_convexPolyhedraGPU->getBufferCL()), + + b3BufferInfoCL(m_data->m_gpuRayRigidPairs->getBufferCL())}; + b3LauncherCL launcher(m_data->m_q, m_data->m_raytracePairsKernel, "m_raytracePairsKernel"); - launcher.setBuffers( bufferInfo, sizeof(bufferInfo)/sizeof(b3BufferInfoCL) ); + launcher.setBuffers(bufferInfo, sizeof(bufferInfo) / sizeof(b3BufferInfoCL)); launcher.setConst(numRays); - + launcher.launch1D(numRays); clFinish(m_data->m_q); } } - - //copy results { B3_PROFILE("raycast copyToHost"); m_data->m_gpuHitResults->copyToHost(hitResults); } - } \ No newline at end of file diff --git a/src/Bullet3OpenCL/Raycast/b3GpuRaycast.h b/src/Bullet3OpenCL/Raycast/b3GpuRaycast.h index 3a5cf44b7..f1f6ffd40 100644 --- a/src/Bullet3OpenCL/Raycast/b3GpuRaycast.h +++ b/src/Bullet3OpenCL/Raycast/b3GpuRaycast.h @@ -7,26 +7,22 @@ #include "Bullet3Common/b3AlignedObjectArray.h" #include "Bullet3Collision/NarrowPhaseCollision/b3RaycastInfo.h" - - class b3GpuRaycast { protected: struct b3GpuRaycastInternalData* m_data; + public: - b3GpuRaycast(cl_context ctx,cl_device_id device, cl_command_queue q); + b3GpuRaycast(cl_context ctx, cl_device_id device, cl_command_queue q); virtual ~b3GpuRaycast(); - void castRaysHost(const b3AlignedObjectArray& raysIn, b3AlignedObjectArray& hitResults, - int numBodies, const struct b3RigidBodyData* bodies, int numCollidables, const struct b3Collidable* collidables, - const struct b3GpuNarrowPhaseInternalData* narrowphaseData); + void castRaysHost(const b3AlignedObjectArray& raysIn, b3AlignedObjectArray& hitResults, + int numBodies, const struct b3RigidBodyData* bodies, int numCollidables, const struct b3Collidable* collidables, + const struct b3GpuNarrowPhaseInternalData* narrowphaseData); - void castRays(const b3AlignedObjectArray& rays, b3AlignedObjectArray& hitResults, - int numBodies,const struct b3RigidBodyData* bodies, int numCollidables, const struct b3Collidable* collidables, - const struct b3GpuNarrowPhaseInternalData* narrowphaseData, class b3GpuBroadphaseInterface* broadphase); - - - + void castRays(const b3AlignedObjectArray& rays, b3AlignedObjectArray& hitResults, + int numBodies, const struct b3RigidBodyData* bodies, int numCollidables, const struct b3Collidable* collidables, + const struct b3GpuNarrowPhaseInternalData* narrowphaseData, class b3GpuBroadphaseInterface* broadphase); }; -#endif //B3_GPU_RAYCAST_H +#endif //B3_GPU_RAYCAST_H diff --git a/src/Bullet3OpenCL/Raycast/kernels/rayCastKernels.h b/src/Bullet3OpenCL/Raycast/kernels/rayCastKernels.h index 6257909a4..94f6a8eb9 100644 --- a/src/Bullet3OpenCL/Raycast/kernels/rayCastKernels.h +++ b/src/Bullet3OpenCL/Raycast/kernels/rayCastKernels.h @@ -1,381 +1,380 @@ //this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project -static const char* rayCastKernelCL= \ -"#define SHAPE_CONVEX_HULL 3\n" -"#define SHAPE_PLANE 4\n" -"#define SHAPE_CONCAVE_TRIMESH 5\n" -"#define SHAPE_COMPOUND_OF_CONVEX_HULLS 6\n" -"#define SHAPE_SPHERE 7\n" -"typedef struct\n" -"{\n" -" float4 m_from;\n" -" float4 m_to;\n" -"} b3RayInfo;\n" -"typedef struct\n" -"{\n" -" float m_hitFraction;\n" -" int m_hitResult0;\n" -" int m_hitResult1;\n" -" int m_hitResult2;\n" -" float4 m_hitPoint;\n" -" float4 m_hitNormal;\n" -"} b3RayHit;\n" -"typedef struct\n" -"{\n" -" float4 m_pos;\n" -" float4 m_quat;\n" -" float4 m_linVel;\n" -" float4 m_angVel;\n" -" unsigned int m_collidableIdx;\n" -" float m_invMass;\n" -" float m_restituitionCoeff;\n" -" float m_frictionCoeff;\n" -"} Body;\n" -"typedef struct Collidable\n" -"{\n" -" union {\n" -" int m_numChildShapes;\n" -" int m_bvhIndex;\n" -" };\n" -" float m_radius;\n" -" int m_shapeType;\n" -" int m_shapeIndex;\n" -"} Collidable;\n" -"typedef struct \n" -"{\n" -" float4 m_localCenter;\n" -" float4 m_extents;\n" -" float4 mC;\n" -" float4 mE;\n" -" float m_radius;\n" -" int m_faceOffset;\n" -" int m_numFaces;\n" -" int m_numVertices;\n" -" int m_vertexOffset;\n" -" int m_uniqueEdgesOffset;\n" -" int m_numUniqueEdges;\n" -" int m_unused;\n" -"} ConvexPolyhedronCL;\n" -"typedef struct\n" -"{\n" -" float4 m_plane;\n" -" int m_indexOffset;\n" -" int m_numIndices;\n" -"} b3GpuFace;\n" -"///////////////////////////////////////\n" -"// Quaternion\n" -"///////////////////////////////////////\n" -"typedef float4 Quaternion;\n" -"__inline\n" -" Quaternion qtMul(Quaternion a, Quaternion b);\n" -"__inline\n" -" Quaternion qtNormalize(Quaternion in);\n" -"__inline\n" -" Quaternion qtInvert(Quaternion q);\n" -"__inline\n" -" float dot3F4(float4 a, float4 b)\n" -"{\n" -" float4 a1 = (float4)(a.xyz,0.f);\n" -" float4 b1 = (float4)(b.xyz,0.f);\n" -" return dot(a1, b1);\n" -"}\n" -"__inline\n" -" Quaternion qtMul(Quaternion a, Quaternion b)\n" -"{\n" -" Quaternion ans;\n" -" ans = cross( a, b );\n" -" ans += a.w*b+b.w*a;\n" -" // ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" -" ans.w = a.w*b.w - dot3F4(a, b);\n" -" return ans;\n" -"}\n" -"__inline\n" -" Quaternion qtNormalize(Quaternion in)\n" -"{\n" -" return fast_normalize(in);\n" -" // in /= length( in );\n" -" // return in;\n" -"}\n" -"__inline\n" -" float4 qtRotate(Quaternion q, float4 vec)\n" -"{\n" -" Quaternion qInv = qtInvert( q );\n" -" float4 vcpy = vec;\n" -" vcpy.w = 0.f;\n" -" float4 out = qtMul(q,vcpy);\n" -" out = qtMul(out,qInv);\n" -" return out;\n" -"}\n" -"__inline\n" -" Quaternion qtInvert(Quaternion q)\n" -"{\n" -" return (Quaternion)(-q.xyz, q.w);\n" -"}\n" -"__inline\n" -" float4 qtInvRotate(const Quaternion q, float4 vec)\n" -"{\n" -" return qtRotate( qtInvert( q ), vec );\n" -"}\n" -"void trInverse(float4 translationIn, Quaternion orientationIn,\n" -" float4* translationOut, Quaternion* orientationOut)\n" -"{\n" -" *orientationOut = qtInvert(orientationIn);\n" -" *translationOut = qtRotate(*orientationOut, -translationIn);\n" -"}\n" -"bool rayConvex(float4 rayFromLocal, float4 rayToLocal, int numFaces, int faceOffset,\n" -" __global const b3GpuFace* faces, float* hitFraction, float4* hitNormal)\n" -"{\n" -" rayFromLocal.w = 0.f;\n" -" rayToLocal.w = 0.f;\n" -" bool result = true;\n" -" float exitFraction = hitFraction[0];\n" -" float enterFraction = -0.3f;\n" -" float4 curHitNormal = (float4)(0,0,0,0);\n" -" for (int i=0;i= 0.f)\n" -" {\n" -" float fraction = fromPlaneDist / (fromPlaneDist-toPlaneDist);\n" -" if (exitFraction>fraction)\n" -" {\n" -" exitFraction = fraction;\n" -" }\n" -" } \n" -" } else\n" -" {\n" -" if (toPlaneDist<0.f)\n" -" {\n" -" float fraction = fromPlaneDist / (fromPlaneDist-toPlaneDist);\n" -" if (enterFraction <= fraction)\n" -" {\n" -" enterFraction = fraction;\n" -" curHitNormal = face.m_plane;\n" -" curHitNormal.w = 0.f;\n" -" }\n" -" } else\n" -" {\n" -" result = false;\n" -" }\n" -" }\n" -" if (exitFraction <= enterFraction)\n" -" result = false;\n" -" }\n" -" if (enterFraction < 0.f)\n" -" {\n" -" result = false;\n" -" }\n" -" if (result)\n" -" { \n" -" hitFraction[0] = enterFraction;\n" -" hitNormal[0] = curHitNormal;\n" -" }\n" -" return result;\n" -"}\n" -"bool sphere_intersect(float4 spherePos, float radius, float4 rayFrom, float4 rayTo, float* hitFraction)\n" -"{\n" -" float4 rs = rayFrom - spherePos;\n" -" rs.w = 0.f;\n" -" float4 rayDir = rayTo-rayFrom;\n" -" rayDir.w = 0.f;\n" -" float A = dot(rayDir,rayDir);\n" -" float B = dot(rs, rayDir);\n" -" float C = dot(rs, rs) - (radius * radius);\n" -" float D = B * B - A*C;\n" -" if (D > 0.0f)\n" -" {\n" -" float t = (-B - sqrt(D))/A;\n" -" if ( (t >= 0.0f) && (t < (*hitFraction)) )\n" -" {\n" -" *hitFraction = t;\n" -" return true;\n" -" }\n" -" }\n" -" return false;\n" -"}\n" -"float4 setInterpolate3(float4 from, float4 to, float t)\n" -"{\n" -" float s = 1.0f - t;\n" -" float4 result;\n" -" result = s * from + t * to;\n" -" result.w = 0.f; \n" -" return result; \n" -"}\n" -"__kernel void rayCastKernel( \n" -" int numRays, \n" -" const __global b3RayInfo* rays, \n" -" __global b3RayHit* hitResults, \n" -" const int numBodies, \n" -" __global Body* bodies,\n" -" __global Collidable* collidables,\n" -" __global const b3GpuFace* faces,\n" -" __global const ConvexPolyhedronCL* convexShapes )\n" -"{\n" -" int i = get_global_id(0);\n" -" if (i>=numRays)\n" -" return;\n" -" hitResults[i].m_hitFraction = 1.f;\n" -" float4 rayFrom = rays[i].m_from;\n" -" float4 rayTo = rays[i].m_to;\n" -" float hitFraction = 1.f;\n" -" float4 hitPoint;\n" -" float4 hitNormal;\n" -" int hitBodyIndex= -1;\n" -" int cachedCollidableIndex = -1;\n" -" Collidable cachedCollidable;\n" -" for (int b=0;b=0)\n" -" {\n" -" hitPoint = setInterpolate3(rayFrom, rayTo,hitFraction);\n" -" hitResults[i].m_hitFraction = hitFraction;\n" -" hitResults[i].m_hitPoint = hitPoint;\n" -" hitResults[i].m_hitNormal = normalize(hitNormal);\n" -" hitResults[i].m_hitResult0 = hitBodyIndex;\n" -" }\n" -"}\n" -"__kernel void findRayRigidPairIndexRanges(__global int2* rayRigidPairs, \n" -" __global int* out_firstRayRigidPairIndexPerRay,\n" -" __global int* out_numRayRigidPairsPerRay,\n" -" int numRayRigidPairs)\n" -"{\n" -" int rayRigidPairIndex = get_global_id(0);\n" -" if (rayRigidPairIndex >= numRayRigidPairs) return;\n" -" \n" -" int rayIndex = rayRigidPairs[rayRigidPairIndex].x;\n" -" \n" -" atomic_min(&out_firstRayRigidPairIndexPerRay[rayIndex], rayRigidPairIndex);\n" -" atomic_inc(&out_numRayRigidPairsPerRay[rayIndex]);\n" -"}\n" -"__kernel void rayCastPairsKernel(const __global b3RayInfo* rays, \n" -" __global b3RayHit* hitResults, \n" -" __global int* firstRayRigidPairIndexPerRay,\n" -" __global int* numRayRigidPairsPerRay,\n" -" \n" -" __global Body* bodies,\n" -" __global Collidable* collidables,\n" -" __global const b3GpuFace* faces,\n" -" __global const ConvexPolyhedronCL* convexShapes,\n" -" \n" -" __global int2* rayRigidPairs,\n" -" int numRays)\n" -"{\n" -" int i = get_global_id(0);\n" -" if (i >= numRays) return;\n" -" \n" -" float4 rayFrom = rays[i].m_from;\n" -" float4 rayTo = rays[i].m_to;\n" -" \n" -" hitResults[i].m_hitFraction = 1.f;\n" -" \n" -" float hitFraction = 1.f;\n" -" float4 hitPoint;\n" -" float4 hitNormal;\n" -" int hitBodyIndex = -1;\n" -" \n" -" //\n" -" for(int pair = 0; pair < numRayRigidPairsPerRay[i]; ++pair)\n" -" {\n" -" int rayRigidPairIndex = pair + firstRayRigidPairIndexPerRay[i];\n" -" int b = rayRigidPairs[rayRigidPairIndex].y;\n" -" \n" -" if (hitResults[i].m_hitResult2 == b) continue;\n" -" \n" -" Body body = bodies[b];\n" -" Collidable rigidCollidable = collidables[body.m_collidableIdx];\n" -" \n" -" float4 pos = body.m_pos;\n" -" float4 orn = body.m_quat;\n" -" \n" -" if (rigidCollidable.m_shapeType == SHAPE_CONVEX_HULL)\n" -" {\n" -" float4 invPos = (float4)(0,0,0,0);\n" -" float4 invOrn = (float4)(0,0,0,0);\n" -" float4 rayFromLocal = (float4)(0,0,0,0);\n" -" float4 rayToLocal = (float4)(0,0,0,0);\n" -" invOrn = qtInvert(orn);\n" -" invPos = qtRotate(invOrn, -pos);\n" -" rayFromLocal = qtRotate( invOrn, rayFrom ) + invPos;\n" -" rayToLocal = qtRotate( invOrn, rayTo) + invPos;\n" -" rayFromLocal.w = 0.f;\n" -" rayToLocal.w = 0.f;\n" -" int numFaces = convexShapes[rigidCollidable.m_shapeIndex].m_numFaces;\n" -" int faceOffset = convexShapes[rigidCollidable.m_shapeIndex].m_faceOffset;\n" -" \n" -" if (numFaces && rayConvex(rayFromLocal, rayToLocal, numFaces, faceOffset,faces, &hitFraction, &hitNormal))\n" -" {\n" -" hitBodyIndex = b;\n" -" hitPoint = setInterpolate3(rayFrom, rayTo, hitFraction);\n" -" }\n" -" }\n" -" \n" -" if (rigidCollidable.m_shapeType == SHAPE_SPHERE)\n" -" {\n" -" float radius = rigidCollidable.m_radius;\n" -" \n" -" if (sphere_intersect(pos, radius, rayFrom, rayTo, &hitFraction))\n" -" {\n" -" hitBodyIndex = b;\n" -" hitPoint = setInterpolate3(rayFrom, rayTo, hitFraction);\n" -" hitNormal = (float4) (hitPoint - bodies[b].m_pos);\n" -" }\n" -" }\n" -" }\n" -" \n" -" if (hitBodyIndex >= 0)\n" -" {\n" -" hitResults[i].m_hitFraction = hitFraction;\n" -" hitResults[i].m_hitPoint = hitPoint;\n" -" hitResults[i].m_hitNormal = normalize(hitNormal);\n" -" hitResults[i].m_hitResult0 = hitBodyIndex;\n" -" }\n" -" \n" -"}\n" -; +static const char* rayCastKernelCL = + "#define SHAPE_CONVEX_HULL 3\n" + "#define SHAPE_PLANE 4\n" + "#define SHAPE_CONCAVE_TRIMESH 5\n" + "#define SHAPE_COMPOUND_OF_CONVEX_HULLS 6\n" + "#define SHAPE_SPHERE 7\n" + "typedef struct\n" + "{\n" + " float4 m_from;\n" + " float4 m_to;\n" + "} b3RayInfo;\n" + "typedef struct\n" + "{\n" + " float m_hitFraction;\n" + " int m_hitResult0;\n" + " int m_hitResult1;\n" + " int m_hitResult2;\n" + " float4 m_hitPoint;\n" + " float4 m_hitNormal;\n" + "} b3RayHit;\n" + "typedef struct\n" + "{\n" + " float4 m_pos;\n" + " float4 m_quat;\n" + " float4 m_linVel;\n" + " float4 m_angVel;\n" + " unsigned int m_collidableIdx;\n" + " float m_invMass;\n" + " float m_restituitionCoeff;\n" + " float m_frictionCoeff;\n" + "} Body;\n" + "typedef struct Collidable\n" + "{\n" + " union {\n" + " int m_numChildShapes;\n" + " int m_bvhIndex;\n" + " };\n" + " float m_radius;\n" + " int m_shapeType;\n" + " int m_shapeIndex;\n" + "} Collidable;\n" + "typedef struct \n" + "{\n" + " float4 m_localCenter;\n" + " float4 m_extents;\n" + " float4 mC;\n" + " float4 mE;\n" + " float m_radius;\n" + " int m_faceOffset;\n" + " int m_numFaces;\n" + " int m_numVertices;\n" + " int m_vertexOffset;\n" + " int m_uniqueEdgesOffset;\n" + " int m_numUniqueEdges;\n" + " int m_unused;\n" + "} ConvexPolyhedronCL;\n" + "typedef struct\n" + "{\n" + " float4 m_plane;\n" + " int m_indexOffset;\n" + " int m_numIndices;\n" + "} b3GpuFace;\n" + "///////////////////////////////////////\n" + "// Quaternion\n" + "///////////////////////////////////////\n" + "typedef float4 Quaternion;\n" + "__inline\n" + " Quaternion qtMul(Quaternion a, Quaternion b);\n" + "__inline\n" + " Quaternion qtNormalize(Quaternion in);\n" + "__inline\n" + " Quaternion qtInvert(Quaternion q);\n" + "__inline\n" + " float dot3F4(float4 a, float4 b)\n" + "{\n" + " float4 a1 = (float4)(a.xyz,0.f);\n" + " float4 b1 = (float4)(b.xyz,0.f);\n" + " return dot(a1, b1);\n" + "}\n" + "__inline\n" + " Quaternion qtMul(Quaternion a, Quaternion b)\n" + "{\n" + " Quaternion ans;\n" + " ans = cross( a, b );\n" + " ans += a.w*b+b.w*a;\n" + " // ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" + " ans.w = a.w*b.w - dot3F4(a, b);\n" + " return ans;\n" + "}\n" + "__inline\n" + " Quaternion qtNormalize(Quaternion in)\n" + "{\n" + " return fast_normalize(in);\n" + " // in /= length( in );\n" + " // return in;\n" + "}\n" + "__inline\n" + " float4 qtRotate(Quaternion q, float4 vec)\n" + "{\n" + " Quaternion qInv = qtInvert( q );\n" + " float4 vcpy = vec;\n" + " vcpy.w = 0.f;\n" + " float4 out = qtMul(q,vcpy);\n" + " out = qtMul(out,qInv);\n" + " return out;\n" + "}\n" + "__inline\n" + " Quaternion qtInvert(Quaternion q)\n" + "{\n" + " return (Quaternion)(-q.xyz, q.w);\n" + "}\n" + "__inline\n" + " float4 qtInvRotate(const Quaternion q, float4 vec)\n" + "{\n" + " return qtRotate( qtInvert( q ), vec );\n" + "}\n" + "void trInverse(float4 translationIn, Quaternion orientationIn,\n" + " float4* translationOut, Quaternion* orientationOut)\n" + "{\n" + " *orientationOut = qtInvert(orientationIn);\n" + " *translationOut = qtRotate(*orientationOut, -translationIn);\n" + "}\n" + "bool rayConvex(float4 rayFromLocal, float4 rayToLocal, int numFaces, int faceOffset,\n" + " __global const b3GpuFace* faces, float* hitFraction, float4* hitNormal)\n" + "{\n" + " rayFromLocal.w = 0.f;\n" + " rayToLocal.w = 0.f;\n" + " bool result = true;\n" + " float exitFraction = hitFraction[0];\n" + " float enterFraction = -0.3f;\n" + " float4 curHitNormal = (float4)(0,0,0,0);\n" + " for (int i=0;i= 0.f)\n" + " {\n" + " float fraction = fromPlaneDist / (fromPlaneDist-toPlaneDist);\n" + " if (exitFraction>fraction)\n" + " {\n" + " exitFraction = fraction;\n" + " }\n" + " } \n" + " } else\n" + " {\n" + " if (toPlaneDist<0.f)\n" + " {\n" + " float fraction = fromPlaneDist / (fromPlaneDist-toPlaneDist);\n" + " if (enterFraction <= fraction)\n" + " {\n" + " enterFraction = fraction;\n" + " curHitNormal = face.m_plane;\n" + " curHitNormal.w = 0.f;\n" + " }\n" + " } else\n" + " {\n" + " result = false;\n" + " }\n" + " }\n" + " if (exitFraction <= enterFraction)\n" + " result = false;\n" + " }\n" + " if (enterFraction < 0.f)\n" + " {\n" + " result = false;\n" + " }\n" + " if (result)\n" + " { \n" + " hitFraction[0] = enterFraction;\n" + " hitNormal[0] = curHitNormal;\n" + " }\n" + " return result;\n" + "}\n" + "bool sphere_intersect(float4 spherePos, float radius, float4 rayFrom, float4 rayTo, float* hitFraction)\n" + "{\n" + " float4 rs = rayFrom - spherePos;\n" + " rs.w = 0.f;\n" + " float4 rayDir = rayTo-rayFrom;\n" + " rayDir.w = 0.f;\n" + " float A = dot(rayDir,rayDir);\n" + " float B = dot(rs, rayDir);\n" + " float C = dot(rs, rs) - (radius * radius);\n" + " float D = B * B - A*C;\n" + " if (D > 0.0f)\n" + " {\n" + " float t = (-B - sqrt(D))/A;\n" + " if ( (t >= 0.0f) && (t < (*hitFraction)) )\n" + " {\n" + " *hitFraction = t;\n" + " return true;\n" + " }\n" + " }\n" + " return false;\n" + "}\n" + "float4 setInterpolate3(float4 from, float4 to, float t)\n" + "{\n" + " float s = 1.0f - t;\n" + " float4 result;\n" + " result = s * from + t * to;\n" + " result.w = 0.f; \n" + " return result; \n" + "}\n" + "__kernel void rayCastKernel( \n" + " int numRays, \n" + " const __global b3RayInfo* rays, \n" + " __global b3RayHit* hitResults, \n" + " const int numBodies, \n" + " __global Body* bodies,\n" + " __global Collidable* collidables,\n" + " __global const b3GpuFace* faces,\n" + " __global const ConvexPolyhedronCL* convexShapes )\n" + "{\n" + " int i = get_global_id(0);\n" + " if (i>=numRays)\n" + " return;\n" + " hitResults[i].m_hitFraction = 1.f;\n" + " float4 rayFrom = rays[i].m_from;\n" + " float4 rayTo = rays[i].m_to;\n" + " float hitFraction = 1.f;\n" + " float4 hitPoint;\n" + " float4 hitNormal;\n" + " int hitBodyIndex= -1;\n" + " int cachedCollidableIndex = -1;\n" + " Collidable cachedCollidable;\n" + " for (int b=0;b=0)\n" + " {\n" + " hitPoint = setInterpolate3(rayFrom, rayTo,hitFraction);\n" + " hitResults[i].m_hitFraction = hitFraction;\n" + " hitResults[i].m_hitPoint = hitPoint;\n" + " hitResults[i].m_hitNormal = normalize(hitNormal);\n" + " hitResults[i].m_hitResult0 = hitBodyIndex;\n" + " }\n" + "}\n" + "__kernel void findRayRigidPairIndexRanges(__global int2* rayRigidPairs, \n" + " __global int* out_firstRayRigidPairIndexPerRay,\n" + " __global int* out_numRayRigidPairsPerRay,\n" + " int numRayRigidPairs)\n" + "{\n" + " int rayRigidPairIndex = get_global_id(0);\n" + " if (rayRigidPairIndex >= numRayRigidPairs) return;\n" + " \n" + " int rayIndex = rayRigidPairs[rayRigidPairIndex].x;\n" + " \n" + " atomic_min(&out_firstRayRigidPairIndexPerRay[rayIndex], rayRigidPairIndex);\n" + " atomic_inc(&out_numRayRigidPairsPerRay[rayIndex]);\n" + "}\n" + "__kernel void rayCastPairsKernel(const __global b3RayInfo* rays, \n" + " __global b3RayHit* hitResults, \n" + " __global int* firstRayRigidPairIndexPerRay,\n" + " __global int* numRayRigidPairsPerRay,\n" + " \n" + " __global Body* bodies,\n" + " __global Collidable* collidables,\n" + " __global const b3GpuFace* faces,\n" + " __global const ConvexPolyhedronCL* convexShapes,\n" + " \n" + " __global int2* rayRigidPairs,\n" + " int numRays)\n" + "{\n" + " int i = get_global_id(0);\n" + " if (i >= numRays) return;\n" + " \n" + " float4 rayFrom = rays[i].m_from;\n" + " float4 rayTo = rays[i].m_to;\n" + " \n" + " hitResults[i].m_hitFraction = 1.f;\n" + " \n" + " float hitFraction = 1.f;\n" + " float4 hitPoint;\n" + " float4 hitNormal;\n" + " int hitBodyIndex = -1;\n" + " \n" + " //\n" + " for(int pair = 0; pair < numRayRigidPairsPerRay[i]; ++pair)\n" + " {\n" + " int rayRigidPairIndex = pair + firstRayRigidPairIndexPerRay[i];\n" + " int b = rayRigidPairs[rayRigidPairIndex].y;\n" + " \n" + " if (hitResults[i].m_hitResult2 == b) continue;\n" + " \n" + " Body body = bodies[b];\n" + " Collidable rigidCollidable = collidables[body.m_collidableIdx];\n" + " \n" + " float4 pos = body.m_pos;\n" + " float4 orn = body.m_quat;\n" + " \n" + " if (rigidCollidable.m_shapeType == SHAPE_CONVEX_HULL)\n" + " {\n" + " float4 invPos = (float4)(0,0,0,0);\n" + " float4 invOrn = (float4)(0,0,0,0);\n" + " float4 rayFromLocal = (float4)(0,0,0,0);\n" + " float4 rayToLocal = (float4)(0,0,0,0);\n" + " invOrn = qtInvert(orn);\n" + " invPos = qtRotate(invOrn, -pos);\n" + " rayFromLocal = qtRotate( invOrn, rayFrom ) + invPos;\n" + " rayToLocal = qtRotate( invOrn, rayTo) + invPos;\n" + " rayFromLocal.w = 0.f;\n" + " rayToLocal.w = 0.f;\n" + " int numFaces = convexShapes[rigidCollidable.m_shapeIndex].m_numFaces;\n" + " int faceOffset = convexShapes[rigidCollidable.m_shapeIndex].m_faceOffset;\n" + " \n" + " if (numFaces && rayConvex(rayFromLocal, rayToLocal, numFaces, faceOffset,faces, &hitFraction, &hitNormal))\n" + " {\n" + " hitBodyIndex = b;\n" + " hitPoint = setInterpolate3(rayFrom, rayTo, hitFraction);\n" + " }\n" + " }\n" + " \n" + " if (rigidCollidable.m_shapeType == SHAPE_SPHERE)\n" + " {\n" + " float radius = rigidCollidable.m_radius;\n" + " \n" + " if (sphere_intersect(pos, radius, rayFrom, rayTo, &hitFraction))\n" + " {\n" + " hitBodyIndex = b;\n" + " hitPoint = setInterpolate3(rayFrom, rayTo, hitFraction);\n" + " hitNormal = (float4) (hitPoint - bodies[b].m_pos);\n" + " }\n" + " }\n" + " }\n" + " \n" + " if (hitBodyIndex >= 0)\n" + " {\n" + " hitResults[i].m_hitFraction = hitFraction;\n" + " hitResults[i].m_hitPoint = hitPoint;\n" + " hitResults[i].m_hitNormal = normalize(hitNormal);\n" + " hitResults[i].m_hitResult0 = hitBodyIndex;\n" + " }\n" + " \n" + "}\n"; diff --git a/src/Bullet3OpenCL/RigidBody/b3GpuConstraint4.h b/src/Bullet3OpenCL/RigidBody/b3GpuConstraint4.h index c7478f54a..89c0142ab 100644 --- a/src/Bullet3OpenCL/RigidBody/b3GpuConstraint4.h +++ b/src/Bullet3OpenCL/RigidBody/b3GpuConstraint4.h @@ -5,14 +5,13 @@ #include "Bullet3Dynamics/shared/b3ContactConstraint4.h" - -B3_ATTRIBUTE_ALIGNED16(struct) b3GpuConstraint4 : public b3ContactConstraint4 +B3_ATTRIBUTE_ALIGNED16(struct) +b3GpuConstraint4 : public b3ContactConstraint4 { B3_DECLARE_ALIGNED_ALLOCATOR(); - inline void setFrictionCoeff(float value) { m_linear[3] = value; } - inline float getFrictionCoeff() const { return m_linear[3]; } + inline void setFrictionCoeff(float value) { m_linear[3] = value; } + inline float getFrictionCoeff() const { return m_linear[3]; } }; -#endif //B3_CONSTRAINT4_h - +#endif //B3_CONSTRAINT4_h diff --git a/src/Bullet3OpenCL/RigidBody/b3GpuGenericConstraint.cpp b/src/Bullet3OpenCL/RigidBody/b3GpuGenericConstraint.cpp index af687b54e..a271090af 100644 --- a/src/Bullet3OpenCL/RigidBody/b3GpuGenericConstraint.cpp +++ b/src/Bullet3OpenCL/RigidBody/b3GpuGenericConstraint.cpp @@ -19,11 +19,11 @@ subject to the following restrictions: #include #include "Bullet3Common/b3Transform.h" -void b3GpuGenericConstraint::getInfo1 (unsigned int* info,const b3RigidBodyData* bodies) +void b3GpuGenericConstraint::getInfo1(unsigned int* info, const b3RigidBodyData* bodies) { switch (m_constraintType) { - case B3_GPU_POINT2POINT_CONSTRAINT_TYPE: + case B3_GPU_POINT2POINT_CONSTRAINT_TYPE: { *info = 3; break; @@ -35,7 +35,7 @@ void b3GpuGenericConstraint::getInfo1 (unsigned int* info,const b3RigidBodyData* }; } -void getInfo2Point2Point(b3GpuGenericConstraint* constraint, b3GpuConstraintInfo2* info, const b3RigidBodyData* bodies) +void getInfo2Point2Point(b3GpuGenericConstraint* constraint, b3GpuConstraintInfo2* info, const b3RigidBodyData* bodies) { b3Transform trA; trA.setIdentity(); @@ -47,54 +47,52 @@ void getInfo2Point2Point(b3GpuGenericConstraint* constraint, b3GpuConstraintInfo trB.setOrigin(bodies[constraint->m_rbB].m_pos); trB.setRotation(bodies[constraint->m_rbB].m_quat); - // anchor points in global coordinates with respect to body PORs. - - // set jacobian - info->m_J1linearAxis[0] = 1; - info->m_J1linearAxis[info->rowskip+1] = 1; - info->m_J1linearAxis[2*info->rowskip+2] = 1; + // anchor points in global coordinates with respect to body PORs. - b3Vector3 a1 = trA.getBasis()*constraint->getPivotInA(); + // set jacobian + info->m_J1linearAxis[0] = 1; + info->m_J1linearAxis[info->rowskip + 1] = 1; + info->m_J1linearAxis[2 * info->rowskip + 2] = 1; + + b3Vector3 a1 = trA.getBasis() * constraint->getPivotInA(); //b3Vector3 a1a = b3QuatRotate(trA.getRotation(),constraint->getPivotInA()); { b3Vector3* angular0 = (b3Vector3*)(info->m_J1angularAxis); - b3Vector3* angular1 = (b3Vector3*)(info->m_J1angularAxis+info->rowskip); - b3Vector3* angular2 = (b3Vector3*)(info->m_J1angularAxis+2*info->rowskip); + b3Vector3* angular1 = (b3Vector3*)(info->m_J1angularAxis + info->rowskip); + b3Vector3* angular2 = (b3Vector3*)(info->m_J1angularAxis + 2 * info->rowskip); b3Vector3 a1neg = -a1; - a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2); + a1neg.getSkewSymmetricMatrix(angular0, angular1, angular2); } - + if (info->m_J2linearAxis) { info->m_J2linearAxis[0] = -1; - info->m_J2linearAxis[info->rowskip+1] = -1; - info->m_J2linearAxis[2*info->rowskip+2] = -1; + info->m_J2linearAxis[info->rowskip + 1] = -1; + info->m_J2linearAxis[2 * info->rowskip + 2] = -1; } - - b3Vector3 a2 = trB.getBasis()*constraint->getPivotInB(); - + + b3Vector3 a2 = trB.getBasis() * constraint->getPivotInB(); + { - // b3Vector3 a2n = -a2; + // b3Vector3 a2n = -a2; b3Vector3* angular0 = (b3Vector3*)(info->m_J2angularAxis); - b3Vector3* angular1 = (b3Vector3*)(info->m_J2angularAxis+info->rowskip); - b3Vector3* angular2 = (b3Vector3*)(info->m_J2angularAxis+2*info->rowskip); - a2.getSkewSymmetricMatrix(angular0,angular1,angular2); + b3Vector3* angular1 = (b3Vector3*)(info->m_J2angularAxis + info->rowskip); + b3Vector3* angular2 = (b3Vector3*)(info->m_J2angularAxis + 2 * info->rowskip); + a2.getSkewSymmetricMatrix(angular0, angular1, angular2); } - - - // set right hand side -// b3Scalar currERP = (m_flags & B3_P2P_FLAGS_ERP) ? m_erp : info->erp; + // set right hand side + // b3Scalar currERP = (m_flags & B3_P2P_FLAGS_ERP) ? m_erp : info->erp; b3Scalar currERP = info->erp; b3Scalar k = info->fps * currERP; - int j; - for (j=0; j<3; j++) - { - info->m_constraintError[j*info->rowskip] = k * (a2[j] + trB.getOrigin()[j] - a1[j] - trA.getOrigin()[j]); + int j; + for (j = 0; j < 3; j++) + { + info->m_constraintError[j * info->rowskip] = k * (a2[j] + trB.getOrigin()[j] - a1[j] - trA.getOrigin()[j]); //printf("info->m_constraintError[%d]=%f\n",j,info->m_constraintError[j]); - } + } #if 0 if(m_flags & B3_P2P_FLAGS_CFM) { @@ -117,21 +115,20 @@ void getInfo2Point2Point(b3GpuGenericConstraint* constraint, b3GpuConstraintInfo } info->m_damping = m_setting.m_damping; #endif - } -void b3GpuGenericConstraint::getInfo2 (b3GpuConstraintInfo2* info, const b3RigidBodyData* bodies) +void b3GpuGenericConstraint::getInfo2(b3GpuConstraintInfo2* info, const b3RigidBodyData* bodies) { switch (m_constraintType) { - case B3_GPU_POINT2POINT_CONSTRAINT_TYPE: + case B3_GPU_POINT2POINT_CONSTRAINT_TYPE: { - getInfo2Point2Point(this,info,bodies); + getInfo2Point2Point(this, info, bodies); break; }; default: - { - b3Assert(0); - } + { + b3Assert(0); + } }; } diff --git a/src/Bullet3OpenCL/RigidBody/b3GpuGenericConstraint.h b/src/Bullet3OpenCL/RigidBody/b3GpuGenericConstraint.h index 14b3ba7fe..1f163ba7d 100644 --- a/src/Bullet3OpenCL/RigidBody/b3GpuGenericConstraint.h +++ b/src/Bullet3OpenCL/RigidBody/b3GpuGenericConstraint.h @@ -20,37 +20,35 @@ subject to the following restrictions: struct b3RigidBodyData; enum B3_CONSTRAINT_FLAGS { - B3_CONSTRAINT_FLAG_ENABLED=1, + B3_CONSTRAINT_FLAG_ENABLED = 1, }; enum b3GpuGenericConstraintType { - B3_GPU_POINT2POINT_CONSTRAINT_TYPE=3, - B3_GPU_FIXED_CONSTRAINT_TYPE=4, -// B3_HINGE_CONSTRAINT_TYPE, -// B3_CONETWIST_CONSTRAINT_TYPE, -// B3_D6_CONSTRAINT_TYPE, -// B3_SLIDER_CONSTRAINT_TYPE, -// B3_CONTACT_CONSTRAINT_TYPE, -// B3_D6_SPRING_CONSTRAINT_TYPE, -// B3_GEAR_CONSTRAINT_TYPE, - + B3_GPU_POINT2POINT_CONSTRAINT_TYPE = 3, + B3_GPU_FIXED_CONSTRAINT_TYPE = 4, + // B3_HINGE_CONSTRAINT_TYPE, + // B3_CONETWIST_CONSTRAINT_TYPE, + // B3_D6_CONSTRAINT_TYPE, + // B3_SLIDER_CONSTRAINT_TYPE, + // B3_CONTACT_CONSTRAINT_TYPE, + // B3_D6_SPRING_CONSTRAINT_TYPE, + // B3_GEAR_CONSTRAINT_TYPE, + B3_GPU_MAX_CONSTRAINT_TYPE }; - - -struct b3GpuConstraintInfo2 +struct b3GpuConstraintInfo2 { // integrator parameters: frames per second (1/stepsize), default error // reduction parameter (0..1). - b3Scalar fps,erp; + b3Scalar fps, erp; // for the first and second body, pointers to two (linear and angular) // n*3 jacobian sub matrices, stored by rows. these matrices will have // been initialized to 0 on entry. if the second body is zero then the // J2xx pointers may be 0. - b3Scalar *m_J1linearAxis,*m_J1angularAxis,*m_J2linearAxis,*m_J2angularAxis; + b3Scalar *m_J1linearAxis, *m_J1angularAxis, *m_J2linearAxis, *m_J2angularAxis; // elements to jump from one row to the next in J's int rowskip; @@ -58,44 +56,44 @@ struct b3GpuConstraintInfo2 // right hand sides of the equation J*v = c + cfm * lambda. cfm is the // "constraint force mixing" vector. c is set to zero on entry, cfm is // set to a constant value (typically very small or zero) value on entry. - b3Scalar *m_constraintError,*cfm; + b3Scalar *m_constraintError, *cfm; // lo and hi limits for variables (set to -/+ infinity on entry). - b3Scalar *m_lowerLimit,*m_upperLimit; + b3Scalar *m_lowerLimit, *m_upperLimit; // findex vector for variables. see the LCP solver interface for a // description of what this does. this is set to -1 on entry. // note that the returned indexes are relative to the first index of // the constraint. - int *findex; + int* findex; // number of solver iterations int m_numIterations; //damping of the velocity - b3Scalar m_damping; + b3Scalar m_damping; }; - -B3_ATTRIBUTE_ALIGNED16(struct) b3GpuGenericConstraint +B3_ATTRIBUTE_ALIGNED16(struct) +b3GpuGenericConstraint { - int m_constraintType; - int m_rbA; - int m_rbB; - float m_breakingImpulseThreshold; + int m_constraintType; + int m_rbA; + int m_rbB; + float m_breakingImpulseThreshold; b3Vector3 m_pivotInA; b3Vector3 m_pivotInB; b3Quaternion m_relTargetAB; - int m_flags; + int m_flags; int m_uid; int m_padding[2]; - int getRigidBodyA() const + int getRigidBodyA() const { return m_rbA; } - int getRigidBodyB() const + int getRigidBodyB() const { return m_rbB; } @@ -121,12 +119,10 @@ B3_ATTRIBUTE_ALIGNED16(struct) b3GpuGenericConstraint } ///internal method used by the constraint solver, don't use them directly - void getInfo1 (unsigned int* info,const b3RigidBodyData* bodies); + void getInfo1(unsigned int* info, const b3RigidBodyData* bodies); ///internal method used by the constraint solver, don't use them directly - void getInfo2 (b3GpuConstraintInfo2* info, const b3RigidBodyData* bodies); - - + void getInfo2(b3GpuConstraintInfo2 * info, const b3RigidBodyData* bodies); }; -#endif //B3_GPU_GENERIC_CONSTRAINT_H \ No newline at end of file +#endif //B3_GPU_GENERIC_CONSTRAINT_H \ No newline at end of file diff --git a/src/Bullet3OpenCL/RigidBody/b3GpuJacobiContactSolver.cpp b/src/Bullet3OpenCL/RigidBody/b3GpuJacobiContactSolver.cpp index 179dfc4f2..089fb1f6a 100644 --- a/src/Bullet3OpenCL/RigidBody/b3GpuJacobiContactSolver.cpp +++ b/src/Bullet3OpenCL/RigidBody/b3GpuJacobiContactSolver.cpp @@ -2,7 +2,7 @@ #include "b3GpuJacobiContactSolver.h" #include "Bullet3Collision/NarrowPhaseCollision/b3Contact4.h" #include "Bullet3Common/b3AlignedObjectArray.h" -#include "Bullet3OpenCL/ParallelPrimitives/b3FillCL.h" //b3Int2 +#include "Bullet3OpenCL/ParallelPrimitives/b3FillCL.h" //b3Int2 class b3Vector3; #include "Bullet3OpenCL/ParallelPrimitives/b3RadixSort32CL.h" #include "Bullet3OpenCL/ParallelPrimitives/b3PrefixScanCL.h" @@ -15,89 +15,78 @@ class b3Vector3; #include "Bullet3Common/shared/b3Int4.h" #define SOLVER_UTILS_KERNEL_PATH "src/Bullet3OpenCL/RigidBody/kernels/solverUtils.cl" - struct b3GpuJacobiSolverInternalData { - //btRadixSort32CL* m_sort32; - //btBoundSearchCL* m_search; - b3PrefixScanCL* m_scan; + //btRadixSort32CL* m_sort32; + //btBoundSearchCL* m_search; + b3PrefixScanCL* m_scan; - b3OpenCLArray* m_bodyCount; - b3OpenCLArray* m_contactConstraintOffsets; - b3OpenCLArray* m_offsetSplitBodies; + b3OpenCLArray* m_bodyCount; + b3OpenCLArray* m_contactConstraintOffsets; + b3OpenCLArray* m_offsetSplitBodies; - b3OpenCLArray* m_deltaLinearVelocities; - b3OpenCLArray* m_deltaAngularVelocities; + b3OpenCLArray* m_deltaLinearVelocities; + b3OpenCLArray* m_deltaAngularVelocities; - b3AlignedObjectArray m_deltaLinearVelocitiesCPU; - b3AlignedObjectArray m_deltaAngularVelocitiesCPU; - - - - b3OpenCLArray* m_contactConstraints; - - b3FillCL* m_filler; - - - cl_kernel m_countBodiesKernel; - cl_kernel m_contactToConstraintSplitKernel; - cl_kernel m_clearVelocitiesKernel; - cl_kernel m_averageVelocitiesKernel; - cl_kernel m_updateBodyVelocitiesKernel; - cl_kernel m_solveContactKernel; - cl_kernel m_solveFrictionKernel; + b3AlignedObjectArray m_deltaLinearVelocitiesCPU; + b3AlignedObjectArray m_deltaAngularVelocitiesCPU; + b3OpenCLArray* m_contactConstraints; + b3FillCL* m_filler; + cl_kernel m_countBodiesKernel; + cl_kernel m_contactToConstraintSplitKernel; + cl_kernel m_clearVelocitiesKernel; + cl_kernel m_averageVelocitiesKernel; + cl_kernel m_updateBodyVelocitiesKernel; + cl_kernel m_solveContactKernel; + cl_kernel m_solveFrictionKernel; }; - b3GpuJacobiContactSolver::b3GpuJacobiContactSolver(cl_context ctx, cl_device_id device, cl_command_queue queue, int pairCapacity) - :m_context(ctx), - m_device(device), - m_queue(queue) + : m_context(ctx), + m_device(device), + m_queue(queue) { m_data = new b3GpuJacobiSolverInternalData; - m_data->m_scan = new b3PrefixScanCL(m_context,m_device,m_queue); - m_data->m_bodyCount = new b3OpenCLArray(m_context,m_queue); - m_data->m_filler = new b3FillCL(m_context,m_device,m_queue); - m_data->m_contactConstraintOffsets = new b3OpenCLArray(m_context,m_queue); - m_data->m_offsetSplitBodies = new b3OpenCLArray(m_context,m_queue); - m_data->m_contactConstraints = new b3OpenCLArray(m_context,m_queue); - m_data->m_deltaLinearVelocities = new b3OpenCLArray(m_context,m_queue); - m_data->m_deltaAngularVelocities = new b3OpenCLArray(m_context,m_queue); + m_data->m_scan = new b3PrefixScanCL(m_context, m_device, m_queue); + m_data->m_bodyCount = new b3OpenCLArray(m_context, m_queue); + m_data->m_filler = new b3FillCL(m_context, m_device, m_queue); + m_data->m_contactConstraintOffsets = new b3OpenCLArray(m_context, m_queue); + m_data->m_offsetSplitBodies = new b3OpenCLArray(m_context, m_queue); + m_data->m_contactConstraints = new b3OpenCLArray(m_context, m_queue); + m_data->m_deltaLinearVelocities = new b3OpenCLArray(m_context, m_queue); + m_data->m_deltaAngularVelocities = new b3OpenCLArray(m_context, m_queue); cl_int pErrNum; - const char* additionalMacros=""; + const char* additionalMacros = ""; const char* solverUtilsSource = solverUtilsCL; { - cl_program solverUtilsProg= b3OpenCLUtils::compileCLProgramFromString( ctx, device, solverUtilsSource, &pErrNum,additionalMacros, SOLVER_UTILS_KERNEL_PATH); + cl_program solverUtilsProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, solverUtilsSource, &pErrNum, additionalMacros, SOLVER_UTILS_KERNEL_PATH); b3Assert(solverUtilsProg); - m_data->m_countBodiesKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverUtilsSource, "CountBodiesKernel", &pErrNum, solverUtilsProg,additionalMacros ); + m_data->m_countBodiesKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverUtilsSource, "CountBodiesKernel", &pErrNum, solverUtilsProg, additionalMacros); b3Assert(m_data->m_countBodiesKernel); - m_data->m_contactToConstraintSplitKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverUtilsSource, "ContactToConstraintSplitKernel", &pErrNum, solverUtilsProg,additionalMacros ); + m_data->m_contactToConstraintSplitKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverUtilsSource, "ContactToConstraintSplitKernel", &pErrNum, solverUtilsProg, additionalMacros); b3Assert(m_data->m_contactToConstraintSplitKernel); - m_data->m_clearVelocitiesKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverUtilsSource, "ClearVelocitiesKernel", &pErrNum, solverUtilsProg,additionalMacros ); + m_data->m_clearVelocitiesKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverUtilsSource, "ClearVelocitiesKernel", &pErrNum, solverUtilsProg, additionalMacros); b3Assert(m_data->m_clearVelocitiesKernel); - m_data->m_averageVelocitiesKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverUtilsSource, "AverageVelocitiesKernel", &pErrNum, solverUtilsProg,additionalMacros ); + m_data->m_averageVelocitiesKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverUtilsSource, "AverageVelocitiesKernel", &pErrNum, solverUtilsProg, additionalMacros); b3Assert(m_data->m_averageVelocitiesKernel); - m_data->m_updateBodyVelocitiesKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverUtilsSource, "UpdateBodyVelocitiesKernel", &pErrNum, solverUtilsProg,additionalMacros ); + m_data->m_updateBodyVelocitiesKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverUtilsSource, "UpdateBodyVelocitiesKernel", &pErrNum, solverUtilsProg, additionalMacros); b3Assert(m_data->m_updateBodyVelocitiesKernel); - - m_data->m_solveContactKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverUtilsSource, "SolveContactJacobiKernel", &pErrNum, solverUtilsProg,additionalMacros ); - b3Assert(m_data->m_solveContactKernel ); + m_data->m_solveContactKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverUtilsSource, "SolveContactJacobiKernel", &pErrNum, solverUtilsProg, additionalMacros); + b3Assert(m_data->m_solveContactKernel); - m_data->m_solveFrictionKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverUtilsSource, "SolveFrictionJacobiKernel", &pErrNum, solverUtilsProg,additionalMacros ); + m_data->m_solveFrictionKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverUtilsSource, "SolveFrictionJacobiKernel", &pErrNum, solverUtilsProg, additionalMacros); b3Assert(m_data->m_solveFrictionKernel); } - } - b3GpuJacobiContactSolver::~b3GpuJacobiContactSolver() { clReleaseKernel(m_data->m_solveContactKernel); @@ -106,7 +95,7 @@ b3GpuJacobiContactSolver::~b3GpuJacobiContactSolver() clReleaseKernel(m_data->m_contactToConstraintSplitKernel); clReleaseKernel(m_data->m_averageVelocitiesKernel); clReleaseKernel(m_data->m_updateBodyVelocitiesKernel); - clReleaseKernel(m_data->m_clearVelocitiesKernel ); + clReleaseKernel(m_data->m_clearVelocitiesKernel); delete m_data->m_deltaLinearVelocities; delete m_data->m_deltaAngularVelocities; @@ -119,80 +108,70 @@ b3GpuJacobiContactSolver::~b3GpuJacobiContactSolver() delete m_data; } - - b3Vector3 make_float4(float v) { - return b3MakeVector3 (v,v,v); + return b3MakeVector3(v, v, v); } -b3Vector4 make_float4(float x,float y, float z, float w) +b3Vector4 make_float4(float x, float y, float z, float w) { - return b3MakeVector4 (x,y,z,w); + return b3MakeVector4(x, y, z, w); } - - static - inline - float calcRelVel(const b3Vector3& l0, const b3Vector3& l1, const b3Vector3& a0, const b3Vector3& a1, - const b3Vector3& linVel0, const b3Vector3& angVel0, const b3Vector3& linVel1, const b3Vector3& angVel1) - { - return b3Dot(l0, linVel0) + b3Dot(a0, angVel0) + b3Dot(l1, linVel1) + b3Dot(a1, angVel1); - } - - - static - inline - void setLinearAndAngular(const b3Vector3& n, const b3Vector3& r0, const b3Vector3& r1, - b3Vector3& linear, b3Vector3& angular0, b3Vector3& angular1) - { - linear = n; - angular0 = b3Cross(r0, n); - angular1 = -b3Cross(r1, n); - } - - -static __inline void solveContact(b3GpuConstraint4& cs, - const b3Vector3& posA, const b3Vector3& linVelARO, const b3Vector3& angVelARO, float invMassA, const b3Matrix3x3& invInertiaA, - const b3Vector3& posB, const b3Vector3& linVelBRO, const b3Vector3& angVelBRO, float invMassB, const b3Matrix3x3& invInertiaB, - float maxRambdaDt[4], float minRambdaDt[4], b3Vector3& dLinVelA, b3Vector3& dAngVelA, b3Vector3& dLinVelB, b3Vector3& dAngVelB) +static inline float calcRelVel(const b3Vector3& l0, const b3Vector3& l1, const b3Vector3& a0, const b3Vector3& a1, + const b3Vector3& linVel0, const b3Vector3& angVel0, const b3Vector3& linVel1, const b3Vector3& angVel1) { + return b3Dot(l0, linVel0) + b3Dot(a0, angVel0) + b3Dot(l1, linVel1) + b3Dot(a1, angVel1); +} +static inline void setLinearAndAngular(const b3Vector3& n, const b3Vector3& r0, const b3Vector3& r1, + b3Vector3& linear, b3Vector3& angular0, b3Vector3& angular1) +{ + linear = n; + angular0 = b3Cross(r0, n); + angular1 = -b3Cross(r1, n); +} - for(int ic=0; ic<4; ic++) +static __inline void solveContact(b3GpuConstraint4& cs, + const b3Vector3& posA, const b3Vector3& linVelARO, const b3Vector3& angVelARO, float invMassA, const b3Matrix3x3& invInertiaA, + const b3Vector3& posB, const b3Vector3& linVelBRO, const b3Vector3& angVelBRO, float invMassB, const b3Matrix3x3& invInertiaB, + float maxRambdaDt[4], float minRambdaDt[4], b3Vector3& dLinVelA, b3Vector3& dAngVelA, b3Vector3& dLinVelB, b3Vector3& dAngVelB) +{ + for (int ic = 0; ic < 4; ic++) { // dont necessary because this makes change to 0 - if( cs.m_jacCoeffInv[ic] == 0.f ) continue; + if (cs.m_jacCoeffInv[ic] == 0.f) continue; { b3Vector3 angular0, angular1, linear; b3Vector3 r0 = cs.m_worldPos[ic] - (b3Vector3&)posA; b3Vector3 r1 = cs.m_worldPos[ic] - (b3Vector3&)posB; - setLinearAndAngular( (const b3Vector3 &)cs.m_linear, (const b3Vector3 &)r0, (const b3Vector3 &)r1, linear, angular0, angular1 ); + setLinearAndAngular((const b3Vector3&)cs.m_linear, (const b3Vector3&)r0, (const b3Vector3&)r1, linear, angular0, angular1); - float rambdaDt = calcRelVel((const b3Vector3 &)cs.m_linear,(const b3Vector3 &) -cs.m_linear, angular0, angular1, - linVelARO+dLinVelA, angVelARO+dAngVelA, linVelBRO+dLinVelB, angVelBRO+dAngVelB ) + cs.m_b[ic]; + float rambdaDt = calcRelVel((const b3Vector3&)cs.m_linear, (const b3Vector3&)-cs.m_linear, angular0, angular1, + linVelARO + dLinVelA, angVelARO + dAngVelA, linVelBRO + dLinVelB, angVelBRO + dAngVelB) + + cs.m_b[ic]; rambdaDt *= cs.m_jacCoeffInv[ic]; { float prevSum = cs.m_appliedRambdaDt[ic]; float updated = prevSum; updated += rambdaDt; - updated = b3Max( updated, minRambdaDt[ic] ); - updated = b3Min( updated, maxRambdaDt[ic] ); + updated = b3Max(updated, minRambdaDt[ic]); + updated = b3Min(updated, maxRambdaDt[ic]); rambdaDt = updated - prevSum; cs.m_appliedRambdaDt[ic] = updated; } - b3Vector3 linImp0 = invMassA*linear*rambdaDt; - b3Vector3 linImp1 = invMassB*(-linear)*rambdaDt; - b3Vector3 angImp0 = (invInertiaA* angular0)*rambdaDt; - b3Vector3 angImp1 = (invInertiaB* angular1)*rambdaDt; + b3Vector3 linImp0 = invMassA * linear * rambdaDt; + b3Vector3 linImp1 = invMassB * (-linear) * rambdaDt; + b3Vector3 angImp0 = (invInertiaA * angular0) * rambdaDt; + b3Vector3 angImp1 = (invInertiaB * angular1) * rambdaDt; #ifdef _WIN32 - b3Assert(_finite(linImp0.getX())); + b3Assert(_finite(linImp0.getX())); b3Assert(_finite(linImp1.getX())); #endif - + if (invMassA) { dLinVelA += linImp0; @@ -207,43 +186,42 @@ static __inline void solveContact(b3GpuConstraint4& cs, } } - - void solveContact3(b3GpuConstraint4* cs, - b3Vector3* posAPtr, b3Vector3* linVelA, b3Vector3* angVelA, float invMassA, const b3Matrix3x3& invInertiaA, - b3Vector3* posBPtr, b3Vector3* linVelB, b3Vector3* angVelB, float invMassB, const b3Matrix3x3& invInertiaB, - b3Vector3* dLinVelA, b3Vector3* dAngVelA, b3Vector3* dLinVelB, b3Vector3* dAngVelB) + b3Vector3* posAPtr, b3Vector3* linVelA, b3Vector3* angVelA, float invMassA, const b3Matrix3x3& invInertiaA, + b3Vector3* posBPtr, b3Vector3* linVelB, b3Vector3* angVelB, float invMassB, const b3Matrix3x3& invInertiaB, + b3Vector3* dLinVelA, b3Vector3* dAngVelA, b3Vector3* dLinVelB, b3Vector3* dAngVelB) { float minRambdaDt = 0; float maxRambdaDt = FLT_MAX; - for(int ic=0; ic<4; ic++) + for (int ic = 0; ic < 4; ic++) { - if( cs->m_jacCoeffInv[ic] == 0.f ) continue; + if (cs->m_jacCoeffInv[ic] == 0.f) continue; b3Vector3 angular0, angular1, linear; b3Vector3 r0 = cs->m_worldPos[ic] - *posAPtr; b3Vector3 r1 = cs->m_worldPos[ic] - *posBPtr; - setLinearAndAngular( cs->m_linear, r0, r1, linear, angular0, angular1 ); + setLinearAndAngular(cs->m_linear, r0, r1, linear, angular0, angular1); - float rambdaDt = calcRelVel( cs->m_linear, -cs->m_linear, angular0, angular1, - *linVelA+*dLinVelA, *angVelA+*dAngVelA, *linVelB+*dLinVelB, *angVelB+*dAngVelB ) + cs->m_b[ic]; + float rambdaDt = calcRelVel(cs->m_linear, -cs->m_linear, angular0, angular1, + *linVelA + *dLinVelA, *angVelA + *dAngVelA, *linVelB + *dLinVelB, *angVelB + *dAngVelB) + + cs->m_b[ic]; rambdaDt *= cs->m_jacCoeffInv[ic]; { float prevSum = cs->m_appliedRambdaDt[ic]; float updated = prevSum; updated += rambdaDt; - updated = b3Max( updated, minRambdaDt ); - updated = b3Min( updated, maxRambdaDt ); + updated = b3Max(updated, minRambdaDt); + updated = b3Min(updated, maxRambdaDt); rambdaDt = updated - prevSum; cs->m_appliedRambdaDt[ic] = updated; } - b3Vector3 linImp0 = invMassA*linear*rambdaDt; - b3Vector3 linImp1 = invMassB*(-linear)*rambdaDt; - b3Vector3 angImp0 = (invInertiaA* angular0)*rambdaDt; - b3Vector3 angImp1 = (invInertiaB* angular1)*rambdaDt; + b3Vector3 linImp0 = invMassA * linear * rambdaDt; + b3Vector3 linImp1 = invMassB * (-linear) * rambdaDt; + b3Vector3 angImp0 = (invInertiaA * angular0) * rambdaDt; + b3Vector3 angImp1 = (invInertiaB * angular1) * rambdaDt; if (invMassA) { @@ -258,58 +236,56 @@ void solveContact3(b3GpuConstraint4* cs, } } - -static inline void solveFriction(b3GpuConstraint4& cs, - const b3Vector3& posA, const b3Vector3& linVelARO, const b3Vector3& angVelARO, float invMassA, const b3Matrix3x3& invInertiaA, - const b3Vector3& posB, const b3Vector3& linVelBRO, const b3Vector3& angVelBRO, float invMassB, const b3Matrix3x3& invInertiaB, - float maxRambdaDt[4], float minRambdaDt[4], b3Vector3& dLinVelA, b3Vector3& dAngVelA, b3Vector3& dLinVelB, b3Vector3& dAngVelB) +static inline void solveFriction(b3GpuConstraint4& cs, + const b3Vector3& posA, const b3Vector3& linVelARO, const b3Vector3& angVelARO, float invMassA, const b3Matrix3x3& invInertiaA, + const b3Vector3& posB, const b3Vector3& linVelBRO, const b3Vector3& angVelBRO, float invMassB, const b3Matrix3x3& invInertiaB, + float maxRambdaDt[4], float minRambdaDt[4], b3Vector3& dLinVelA, b3Vector3& dAngVelA, b3Vector3& dLinVelB, b3Vector3& dAngVelB) { + b3Vector3 linVelA = linVelARO + dLinVelA; + b3Vector3 linVelB = linVelBRO + dLinVelB; + b3Vector3 angVelA = angVelARO + dAngVelA; + b3Vector3 angVelB = angVelBRO + dAngVelB; - b3Vector3 linVelA = linVelARO+dLinVelA; - b3Vector3 linVelB = linVelBRO+dLinVelB; - b3Vector3 angVelA = angVelARO+dAngVelA; - b3Vector3 angVelB = angVelBRO+dAngVelB; - - if( cs.m_fJacCoeffInv[0] == 0 && cs.m_fJacCoeffInv[0] == 0 ) return; + if (cs.m_fJacCoeffInv[0] == 0 && cs.m_fJacCoeffInv[0] == 0) return; const b3Vector3& center = (const b3Vector3&)cs.m_center; b3Vector3 n = -(const b3Vector3&)cs.m_linear; b3Vector3 tangent[2]; -#if 1 - b3PlaneSpace1 (n, tangent[0],tangent[1]); +#if 1 + b3PlaneSpace1(n, tangent[0], tangent[1]); #else - b3Vector3 r = cs.m_worldPos[0]-center; - tangent[0] = cross3( n, r ); - tangent[1] = cross3( tangent[0], n ); - tangent[0] = normalize3( tangent[0] ); - tangent[1] = normalize3( tangent[1] ); + b3Vector3 r = cs.m_worldPos[0] - center; + tangent[0] = cross3(n, r); + tangent[1] = cross3(tangent[0], n); + tangent[0] = normalize3(tangent[0]); + tangent[1] = normalize3(tangent[1]); #endif b3Vector3 angular0, angular1, linear; b3Vector3 r0 = center - posA; b3Vector3 r1 = center - posB; - for(int i=0; i<2; i++) + for (int i = 0; i < 2; i++) { - setLinearAndAngular( tangent[i], r0, r1, linear, angular0, angular1 ); + setLinearAndAngular(tangent[i], r0, r1, linear, angular0, angular1); float rambdaDt = calcRelVel(linear, -linear, angular0, angular1, - linVelA, angVelA, linVelB, angVelB ); + linVelA, angVelA, linVelB, angVelB); rambdaDt *= cs.m_fJacCoeffInv[i]; - { - float prevSum = cs.m_fAppliedRambdaDt[i]; - float updated = prevSum; - updated += rambdaDt; - updated = b3Max( updated, minRambdaDt[i] ); - updated = b3Min( updated, maxRambdaDt[i] ); - rambdaDt = updated - prevSum; - cs.m_fAppliedRambdaDt[i] = updated; - } + { + float prevSum = cs.m_fAppliedRambdaDt[i]; + float updated = prevSum; + updated += rambdaDt; + updated = b3Max(updated, minRambdaDt[i]); + updated = b3Min(updated, maxRambdaDt[i]); + rambdaDt = updated - prevSum; + cs.m_fAppliedRambdaDt[i] = updated; + } - b3Vector3 linImp0 = invMassA*linear*rambdaDt; - b3Vector3 linImp1 = invMassB*(-linear)*rambdaDt; - b3Vector3 angImp0 = (invInertiaA* angular0)*rambdaDt; - b3Vector3 angImp1 = (invInertiaB* angular1)*rambdaDt; + b3Vector3 linImp0 = invMassA * linear * rambdaDt; + b3Vector3 linImp1 = invMassB * (-linear) * rambdaDt; + b3Vector3 angImp0 = (invInertiaA * angular0) * rambdaDt; + b3Vector3 angImp1 = (invInertiaB * angular1) * rambdaDt; #ifdef _WIN32 b3Assert(_finite(linImp0.getX())); b3Assert(_finite(linImp1.getX())); @@ -326,65 +302,58 @@ static inline void solveFriction(b3GpuConstraint4& cs, } } - { // angular damping for point constraint - b3Vector3 ab = ( posB - posA ).normalized(); - b3Vector3 ac = ( center - posA ).normalized(); - if( b3Dot( ab, ac ) > 0.95f || (invMassA == 0.f || invMassB == 0.f)) + { // angular damping for point constraint + b3Vector3 ab = (posB - posA).normalized(); + b3Vector3 ac = (center - posA).normalized(); + if (b3Dot(ab, ac) > 0.95f || (invMassA == 0.f || invMassB == 0.f)) { - float angNA = b3Dot( n, angVelA ); - float angNB = b3Dot( n, angVelB ); + float angNA = b3Dot(n, angVelA); + float angNB = b3Dot(n, angVelB); if (invMassA) - dAngVelA -= (angNA*0.1f)*n; + dAngVelA -= (angNA * 0.1f) * n; if (invMassB) - dAngVelB -= (angNB*0.1f)*n; + dAngVelB -= (angNB * 0.1f) * n; } } - } - - - float calcJacCoeff(const b3Vector3& linear0, const b3Vector3& linear1, const b3Vector3& angular0, const b3Vector3& angular1, - float invMass0, const b3Matrix3x3* invInertia0, float invMass1, const b3Matrix3x3* invInertia1, float countA, float countB) + float invMass0, const b3Matrix3x3* invInertia0, float invMass1, const b3Matrix3x3* invInertia1, float countA, float countB) { // linear0,1 are normlized - float jmj0 = invMass0;//dot3F4(linear0, linear0)*invMass0; - - float jmj1 = b3Dot(mtMul3(angular0,*invInertia0), angular0); - float jmj2 = invMass1;//dot3F4(linear1, linear1)*invMass1; - float jmj3 = b3Dot(mtMul3(angular1,*invInertia1), angular1); - return -1.f/((jmj0+jmj1)*countA+(jmj2+jmj3)*countB); -// return -1.f/((jmj0+jmj1)+(jmj2+jmj3)); + float jmj0 = invMass0; //dot3F4(linear0, linear0)*invMass0; + float jmj1 = b3Dot(mtMul3(angular0, *invInertia0), angular0); + float jmj2 = invMass1; //dot3F4(linear1, linear1)*invMass1; + float jmj3 = b3Dot(mtMul3(angular1, *invInertia1), angular1); + return -1.f / ((jmj0 + jmj1) * countA + (jmj2 + jmj3) * countB); + // return -1.f/((jmj0+jmj1)+(jmj2+jmj3)); } - -void setConstraint4( const b3Vector3& posA, const b3Vector3& linVelA, const b3Vector3& angVelA, float invMassA, const b3Matrix3x3& invInertiaA, - const b3Vector3& posB, const b3Vector3& linVelB, const b3Vector3& angVelB, float invMassB, const b3Matrix3x3& invInertiaB, - b3Contact4* src, float dt, float positionDrift, float positionConstraintCoeff, float countA, float countB, - b3GpuConstraint4* dstC ) +void setConstraint4(const b3Vector3& posA, const b3Vector3& linVelA, const b3Vector3& angVelA, float invMassA, const b3Matrix3x3& invInertiaA, + const b3Vector3& posB, const b3Vector3& linVelB, const b3Vector3& angVelB, float invMassB, const b3Matrix3x3& invInertiaB, + b3Contact4* src, float dt, float positionDrift, float positionConstraintCoeff, float countA, float countB, + b3GpuConstraint4* dstC) { dstC->m_bodyA = abs(src->m_bodyAPtrAndSignBit); dstC->m_bodyB = abs(src->m_bodyBPtrAndSignBit); - float dtInv = 1.f/dt; - for(int ic=0; ic<4; ic++) + float dtInv = 1.f / dt; + for (int ic = 0; ic < 4; ic++) { dstC->m_appliedRambdaDt[ic] = 0.f; } dstC->m_fJacCoeffInv[0] = dstC->m_fJacCoeffInv[1] = 0.f; - dstC->m_linear = src->m_worldNormalOnB; - dstC->m_linear[3] = 0.7f ;//src->getFrictionCoeff() ); - for(int ic=0; ic<4; ic++) + dstC->m_linear[3] = 0.7f; //src->getFrictionCoeff() ); + for (int ic = 0; ic < 4; ic++) { b3Vector3 r0 = src->m_worldPosB[ic] - posA; b3Vector3 r1 = src->m_worldPosB[ic] - posB; - if( ic >= src->m_worldNormalOnB[3] )//npoints + if (ic >= src->m_worldNormalOnB[3]) //npoints { dstC->m_jacCoeffInv[ic] = 0.f; continue; @@ -396,53 +365,53 @@ void setConstraint4( const b3Vector3& posA, const b3Vector3& linVelA, const b3Ve setLinearAndAngular(src->m_worldNormalOnB, r0, r1, linear, angular0, angular1); dstC->m_jacCoeffInv[ic] = calcJacCoeff(linear, -linear, angular0, angular1, - invMassA, &invInertiaA, invMassB, &invInertiaB ,countA,countB); + invMassA, &invInertiaA, invMassB, &invInertiaB, countA, countB); relVelN = calcRelVel(linear, -linear, angular0, angular1, - linVelA, angVelA, linVelB, angVelB); + linVelA, angVelA, linVelB, angVelB); - float e = 0.f;//src->getRestituitionCoeff(); - if( relVelN*relVelN < 0.004f ) + float e = 0.f; //src->getRestituitionCoeff(); + if (relVelN * relVelN < 0.004f) { e = 0.f; } - dstC->m_b[ic] = e*relVelN; + dstC->m_b[ic] = e * relVelN; //float penetration = src->m_worldPos[ic].w; - dstC->m_b[ic] += (src->m_worldPosB[ic][3] + positionDrift)*positionConstraintCoeff*dtInv; + dstC->m_b[ic] += (src->m_worldPosB[ic][3] + positionDrift) * positionConstraintCoeff * dtInv; dstC->m_appliedRambdaDt[ic] = 0.f; } } - if( src->m_worldNormalOnB[3] > 0 )//npoints - { // prepare friction + if (src->m_worldNormalOnB[3] > 0) //npoints + { // prepare friction b3Vector3 center = make_float4(0.f); - for(int i=0; im_worldNormalOnB[3]; i++) + for (int i = 0; i < src->m_worldNormalOnB[3]; i++) center += src->m_worldPosB[i]; center /= (float)src->m_worldNormalOnB[3]; b3Vector3 tangent[2]; - b3PlaneSpace1(src->m_worldNormalOnB,tangent[0],tangent[1]); - + b3PlaneSpace1(src->m_worldNormalOnB, tangent[0], tangent[1]); + b3Vector3 r[2]; r[0] = center - posA; r[1] = center - posB; - for(int i=0; i<2; i++) + for (int i = 0; i < 2; i++) { b3Vector3 linear, angular0, angular1; setLinearAndAngular(tangent[i], r[0], r[1], linear, angular0, angular1); dstC->m_fJacCoeffInv[i] = calcJacCoeff(linear, -linear, angular0, angular1, - invMassA, &invInertiaA, invMassB, &invInertiaB ,countA,countB); + invMassA, &invInertiaA, invMassB, &invInertiaB, countA, countB); dstC->m_fAppliedRambdaDt[i] = 0.f; } dstC->m_center = center; } - for(int i=0; i<4; i++) + for (int i = 0; i < 4; i++) { - if( im_worldNormalOnB[3] ) + if (i < src->m_worldNormalOnB[3]) { dstC->m_worldPos[i] = src->m_worldPosB[i]; } @@ -453,17 +422,14 @@ void setConstraint4( const b3Vector3& posA, const b3Vector3& linVelA, const b3Ve } } - - void ContactToConstraintKernel(b3Contact4* gContact, b3RigidBodyData* gBodies, b3InertiaData* gShapes, b3GpuConstraint4* gConstraintOut, int nContacts, -float dt, -float positionDrift, -float positionConstraintCoeff, int gIdx, b3AlignedObjectArray& bodyCount -) + float dt, + float positionDrift, + float positionConstraintCoeff, int gIdx, b3AlignedObjectArray& bodyCount) { //int gIdx = 0;//GET_GLOBAL_IDX; - - if( gIdx < nContacts ) + + if (gIdx < nContacts) { int aIdx = abs(gContact[gIdx].m_bodyAPtrAndSignBit); int bIdx = abs(gContact[gIdx].m_bodyBPtrAndSignBit); @@ -472,50 +438,46 @@ float positionConstraintCoeff, int gIdx, b3AlignedObjectArray& bod b3Vector3 linVelA = gBodies[aIdx].m_linVel; b3Vector3 angVelA = gBodies[aIdx].m_angVel; float invMassA = gBodies[aIdx].m_invMass; - b3Matrix3x3 invInertiaA = gShapes[aIdx].m_invInertiaWorld;//.m_invInertia; + b3Matrix3x3 invInertiaA = gShapes[aIdx].m_invInertiaWorld; //.m_invInertia; b3Vector3 posB = gBodies[bIdx].m_pos; b3Vector3 linVelB = gBodies[bIdx].m_linVel; b3Vector3 angVelB = gBodies[bIdx].m_angVel; float invMassB = gBodies[bIdx].m_invMass; - b3Matrix3x3 invInertiaB = gShapes[bIdx].m_invInertiaWorld;//m_invInertia; + b3Matrix3x3 invInertiaB = gShapes[bIdx].m_invInertiaWorld; //m_invInertia; b3GpuConstraint4 cs; float countA = invMassA ? (float)(bodyCount[aIdx]) : 1; float countB = invMassB ? (float)(bodyCount[bIdx]) : 1; - setConstraint4( posA, linVelA, angVelA, invMassA, invInertiaA, posB, linVelB, angVelB, invMassB, invInertiaB, - &gContact[gIdx], dt, positionDrift, positionConstraintCoeff,countA,countB, - &cs ); - + setConstraint4(posA, linVelA, angVelA, invMassA, invInertiaA, posB, linVelB, angVelB, invMassB, invInertiaB, + &gContact[gIdx], dt, positionDrift, positionConstraintCoeff, countA, countB, + &cs); - cs.m_batchIdx = gContact[gIdx].m_batchIdx; gConstraintOut[gIdx] = cs; } } - -void b3GpuJacobiContactSolver::solveGroupHost(b3RigidBodyData* bodies,b3InertiaData* inertias,int numBodies,b3Contact4* manifoldPtr, int numManifolds,const b3JacobiSolverInfo& solverInfo) +void b3GpuJacobiContactSolver::solveGroupHost(b3RigidBodyData* bodies, b3InertiaData* inertias, int numBodies, b3Contact4* manifoldPtr, int numManifolds, const b3JacobiSolverInfo& solverInfo) { B3_PROFILE("b3GpuJacobiContactSolver::solveGroup"); b3AlignedObjectArray bodyCount; bodyCount.resize(numBodies); - for (int i=0;i contactConstraintOffsets; contactConstraintOffsets.resize(numManifolds); - - for (int i=0;i offsetSplitBodies; offsetSplitBodies.resize(numBodies); unsigned int totalNumSplitBodies; - m_data->m_scan->executeHost(bodyCount,offsetSplitBodies,numBodies,&totalNumSplitBodies); - int numlastBody = bodyCount[numBodies-1]; + m_data->m_scan->executeHost(bodyCount, offsetSplitBodies, numBodies, &totalNumSplitBodies); + int numlastBody = bodyCount[numBodies - 1]; totalNumSplitBodies += numlastBody; - printf("totalNumSplitBodies = %d\n",totalNumSplitBodies); - - - - + printf("totalNumSplitBodies = %d\n", totalNumSplitBodies); b3AlignedObjectArray contactConstraints; contactConstraints.resize(numManifolds); - for (int i=0;i deltaLinearVelocities; b3AlignedObjectArray deltaAngularVelocities; deltaLinearVelocities.resize(totalNumSplitBodies); deltaAngularVelocities.resize(totalNumSplitBodies); - for (unsigned int i=0;isize(); - int numManifolds = numContacts;//manifoldPtr->size(); + int numManifolds = numContacts; //manifoldPtr->size(); { B3_PROFILE("resize"); m_data->m_bodyCount->resize(numBodies); } - - unsigned int val=0; - b3Int2 val2; - val2.x=0; - val2.y=0; - { + unsigned int val = 0; + b3Int2 val2; + val2.x = 0; + val2.y = 0; + + { B3_PROFILE("m_filler"); m_data->m_contactConstraintOffsets->resize(numManifolds); - m_data->m_filler->execute(*m_data->m_bodyCount,val,numBodies); - - - m_data->m_filler->execute(*m_data->m_contactConstraintOffsets,val2,numManifolds); + m_data->m_filler->execute(*m_data->m_bodyCount, val, numBodies); + + m_data->m_filler->execute(*m_data->m_contactConstraintOffsets, val2, numManifolds); } { B3_PROFILE("m_countBodiesKernel"); - b3LauncherCL launcher(this->m_queue,m_data->m_countBodiesKernel,"m_countBodiesKernel"); - launcher.setBuffer(contactBuf);//manifoldPtr->getBufferCL()); + b3LauncherCL launcher(this->m_queue, m_data->m_countBodiesKernel, "m_countBodiesKernel"); + launcher.setBuffer(contactBuf); //manifoldPtr->getBufferCL()); launcher.setBuffer(m_data->m_bodyCount->getBufferCL()); launcher.setBuffer(m_data->m_contactConstraintOffsets->getBufferCL()); launcher.setConst(numManifolds); launcher.setConst(solverInfo.m_fixedBodyIndex); launcher.launch1D(numManifolds); } - unsigned int totalNumSplitBodies=0; + unsigned int totalNumSplitBodies = 0; { B3_PROFILE("m_scan->execute"); - + m_data->m_offsetSplitBodies->resize(numBodies); - m_data->m_scan->execute(*m_data->m_bodyCount,*m_data->m_offsetSplitBodies,numBodies,&totalNumSplitBodies); - totalNumSplitBodies+=m_data->m_bodyCount->at(numBodies-1); + m_data->m_scan->execute(*m_data->m_bodyCount, *m_data->m_offsetSplitBodies, numBodies, &totalNumSplitBodies); + totalNumSplitBodies += m_data->m_bodyCount->at(numBodies - 1); } { @@ -812,50 +751,45 @@ void b3GpuJacobiContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_m //int numContacts = manifoldPtr->size(); m_data->m_contactConstraints->resize(numContacts); } - + { B3_PROFILE("contactToConstraintSplitKernel"); - b3LauncherCL launcher( m_queue, m_data->m_contactToConstraintSplitKernel,"m_contactToConstraintSplitKernel"); + b3LauncherCL launcher(m_queue, m_data->m_contactToConstraintSplitKernel, "m_contactToConstraintSplitKernel"); launcher.setBuffer(contactBuf); launcher.setBuffer(bodyBuf); launcher.setBuffer(inertiaBuf); launcher.setBuffer(m_data->m_contactConstraints->getBufferCL()); launcher.setBuffer(m_data->m_bodyCount->getBufferCL()); - launcher.setConst(numContacts); + launcher.setConst(numContacts); launcher.setConst(solverInfo.m_deltaTime); launcher.setConst(solverInfo.m_positionDrift); launcher.setConst(solverInfo.m_positionConstraintCoeff); - launcher.launch1D( numContacts, 64 ); - + launcher.launch1D(numContacts, 64); } - { B3_PROFILE("m_data->m_deltaLinearVelocities->resize"); m_data->m_deltaLinearVelocities->resize(totalNumSplitBodies); m_data->m_deltaAngularVelocities->resize(totalNumSplitBodies); } - - { B3_PROFILE("m_clearVelocitiesKernel"); - b3LauncherCL launch(m_queue,m_data->m_clearVelocitiesKernel,"m_clearVelocitiesKernel"); + b3LauncherCL launch(m_queue, m_data->m_clearVelocitiesKernel, "m_clearVelocitiesKernel"); launch.setBuffer(m_data->m_deltaAngularVelocities->getBufferCL()); launch.setBuffer(m_data->m_deltaLinearVelocities->getBufferCL()); launch.setConst(totalNumSplitBodies); launch.launch1D(totalNumSplitBodies); clFinish(m_queue); } - - + int maxIter = solverInfo.m_numIterations; - for (int iter = 0;iterm_solveContactKernel,"m_solveContactKernel" ); + b3LauncherCL launcher(m_queue, m_data->m_solveContactKernel, "m_solveContactKernel"); launcher.setBuffer(m_data->m_contactConstraints->getBufferCL()); launcher.setBuffer(bodyBuf); launcher.setBuffer(inertiaBuf); @@ -873,11 +807,9 @@ void b3GpuJacobiContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_m clFinish(m_queue); } - - { B3_PROFILE("average velocities"); - b3LauncherCL launcher( m_queue, m_data->m_averageVelocitiesKernel,"m_averageVelocitiesKernel"); + b3LauncherCL launcher(m_queue, m_data->m_averageVelocitiesKernel, "m_averageVelocitiesKernel"); launcher.setBuffer(bodyBuf); launcher.setBuffer(m_data->m_offsetSplitBodies->getBufferCL()); launcher.setBuffer(m_data->m_bodyCount->getBufferCL()); @@ -888,10 +820,9 @@ void b3GpuJacobiContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_m clFinish(m_queue); } - { B3_PROFILE("m_solveFrictionKernel"); - b3LauncherCL launcher( m_queue, m_data->m_solveFrictionKernel,"m_solveFrictionKernel"); + b3LauncherCL launcher(m_queue, m_data->m_solveFrictionKernel, "m_solveFrictionKernel"); launcher.setBuffer(m_data->m_contactConstraints->getBufferCL()); launcher.setBuffer(bodyBuf); launcher.setBuffer(inertiaBuf); @@ -909,10 +840,9 @@ void b3GpuJacobiContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_m clFinish(m_queue); } - { B3_PROFILE("average velocities"); - b3LauncherCL launcher( m_queue, m_data->m_averageVelocitiesKernel,"m_averageVelocitiesKernel"); + b3LauncherCL launcher(m_queue, m_data->m_averageVelocitiesKernel, "m_averageVelocitiesKernel"); launcher.setBuffer(bodyBuf); launcher.setBuffer(m_data->m_offsetSplitBodies->getBufferCL()); launcher.setBuffer(m_data->m_bodyCount->getBufferCL()); @@ -922,27 +852,20 @@ void b3GpuJacobiContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_m launcher.launch1D(numBodies); clFinish(m_queue); } - - - } - { - B3_PROFILE("update body velocities"); - b3LauncherCL launcher( m_queue, m_data->m_updateBodyVelocitiesKernel,"m_updateBodyVelocitiesKernel"); - launcher.setBuffer(bodyBuf); - launcher.setBuffer(m_data->m_offsetSplitBodies->getBufferCL()); - launcher.setBuffer(m_data->m_bodyCount->getBufferCL()); - launcher.setBuffer(m_data->m_deltaLinearVelocities->getBufferCL()); - launcher.setBuffer(m_data->m_deltaAngularVelocities->getBufferCL()); - launcher.setConst(numBodies); - launcher.launch1D(numBodies); - clFinish(m_queue); - } - - - + B3_PROFILE("update body velocities"); + b3LauncherCL launcher(m_queue, m_data->m_updateBodyVelocitiesKernel, "m_updateBodyVelocitiesKernel"); + launcher.setBuffer(bodyBuf); + launcher.setBuffer(m_data->m_offsetSplitBodies->getBufferCL()); + launcher.setBuffer(m_data->m_bodyCount->getBufferCL()); + launcher.setBuffer(m_data->m_deltaLinearVelocities->getBufferCL()); + launcher.setBuffer(m_data->m_deltaAngularVelocities->getBufferCL()); + launcher.setConst(numBodies); + launcher.launch1D(numBodies); + clFinish(m_queue); + } } #if 0 diff --git a/src/Bullet3OpenCL/RigidBody/b3GpuJacobiContactSolver.h b/src/Bullet3OpenCL/RigidBody/b3GpuJacobiContactSolver.h index b418f29ec..8281aee05 100644 --- a/src/Bullet3OpenCL/RigidBody/b3GpuJacobiContactSolver.h +++ b/src/Bullet3OpenCL/RigidBody/b3GpuJacobiContactSolver.h @@ -8,7 +8,6 @@ #include "Bullet3Collision/NarrowPhaseCollision/shared/b3Contact4Data.h" #include "Bullet3OpenCL/ParallelPrimitives/b3OpenCLArray.h" - //struct b3InertiaData; //b3InertiaData @@ -21,21 +20,20 @@ struct b3JacobiSolverInfo float m_deltaTime; float m_positionDrift; float m_positionConstraintCoeff; - int m_numIterations; + int m_numIterations; b3JacobiSolverInfo() - :m_fixedBodyIndex(0), - m_deltaTime(1./60.f), - m_positionDrift( 0.005f ), - m_positionConstraintCoeff( 0.99f ), - m_numIterations(7) + : m_fixedBodyIndex(0), + m_deltaTime(1. / 60.f), + m_positionDrift(0.005f), + m_positionConstraintCoeff(0.99f), + m_numIterations(7) { } }; class b3GpuJacobiContactSolver { protected: - struct b3GpuJacobiSolverInternalData* m_data; cl_context m_context; @@ -43,20 +41,16 @@ protected: cl_command_queue m_queue; public: - b3GpuJacobiContactSolver(cl_context ctx, cl_device_id device, cl_command_queue queue, int pairCapacity); virtual ~b3GpuJacobiContactSolver(); - void solveContacts(int numBodies, cl_mem bodyBuf, cl_mem inertiaBuf, int numContacts, cl_mem contactBuf, const struct b3Config& config, int static0Index); - void solveGroupHost(b3RigidBodyData* bodies,b3InertiaData* inertias,int numBodies,struct b3Contact4* manifoldPtr, int numManifolds,const b3JacobiSolverInfo& solverInfo); + void solveGroupHost(b3RigidBodyData* bodies, b3InertiaData* inertias, int numBodies, struct b3Contact4* manifoldPtr, int numManifolds, const b3JacobiSolverInfo& solverInfo); //void solveGroupHost(btRigidBodyCL* bodies,b3InertiaData* inertias,int numBodies,btContact4* manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btJacobiSolverInfo& solverInfo); //b3Scalar solveGroup(b3OpenCLArray* gpuBodies,b3OpenCLArray* gpuInertias, int numBodies,b3OpenCLArray* gpuConstraints,int numConstraints,const b3ContactSolverInfo& infoGlobal); //void solveGroup(btOpenCLArray* bodies,btOpenCLArray* inertias,btOpenCLArray* manifoldPtr,const btJacobiSolverInfo& solverInfo); //void solveGroupMixed(btOpenCLArray* bodies,btOpenCLArray* inertias,btOpenCLArray* manifoldPtr,const btJacobiSolverInfo& solverInfo); - }; -#endif //B3_GPU_JACOBI_CONTACT_SOLVER_H - +#endif //B3_GPU_JACOBI_CONTACT_SOLVER_H diff --git a/src/Bullet3OpenCL/RigidBody/b3GpuNarrowPhase.cpp b/src/Bullet3OpenCL/RigidBody/b3GpuNarrowPhase.cpp index 698fa15f9..2e4f6c157 100644 --- a/src/Bullet3OpenCL/RigidBody/b3GpuNarrowPhase.cpp +++ b/src/Bullet3OpenCL/RigidBody/b3GpuNarrowPhase.cpp @@ -1,6 +1,5 @@ #include "b3GpuNarrowPhase.h" - #include "Bullet3OpenCL/ParallelPrimitives/b3OpenCLArray.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3ConvexPolyhedronData.h" #include "Bullet3OpenCL/NarrowphaseCollision/b3ConvexHullContact.h" @@ -16,107 +15,87 @@ #include "Bullet3OpenCL/NarrowphaseCollision/b3QuantizedBvh.h" #include "Bullet3Collision/NarrowPhaseCollision/b3ConvexUtility.h" - - - b3GpuNarrowPhase::b3GpuNarrowPhase(cl_context ctx, cl_device_id device, cl_command_queue queue, const b3Config& config) -:m_data(0) ,m_planeBodyIndex(-1),m_static0Index(-1), -m_context(ctx), -m_device(device), -m_queue(queue) + : m_data(0), m_planeBodyIndex(-1), m_static0Index(-1), m_context(ctx), m_device(device), m_queue(queue) { - m_data = new b3GpuNarrowPhaseInternalData(); m_data->m_currentContactBuffer = 0; - memset(m_data,0,sizeof(b3GpuNarrowPhaseInternalData)); - + memset(m_data, 0, sizeof(b3GpuNarrowPhaseInternalData)); m_data->m_config = config; - - m_data->m_gpuSatCollision = new GpuSatCollision(ctx,device,queue); - - - m_data->m_triangleConvexPairs = new b3OpenCLArray(m_context,m_queue, config.m_maxTriConvexPairCapacity); + m_data->m_gpuSatCollision = new GpuSatCollision(ctx, device, queue); + + m_data->m_triangleConvexPairs = new b3OpenCLArray(m_context, m_queue, config.m_maxTriConvexPairCapacity); //m_data->m_convexPairsOutGPU = new b3OpenCLArray(ctx,queue,config.m_maxBroadphasePairs,false); //m_data->m_planePairs = new b3OpenCLArray(ctx,queue,config.m_maxBroadphasePairs,false); - + m_data->m_pBufContactOutCPU = new b3AlignedObjectArray(); m_data->m_pBufContactOutCPU->resize(config.m_maxBroadphasePairs); m_data->m_bodyBufferCPU = new b3AlignedObjectArray(); m_data->m_bodyBufferCPU->resize(config.m_maxConvexBodies); - + m_data->m_inertiaBufferCPU = new b3AlignedObjectArray(); m_data->m_inertiaBufferCPU->resize(config.m_maxConvexBodies); - - m_data->m_pBufContactBuffersGPU[0] = new b3OpenCLArray(ctx,queue, config.m_maxContactCapacity,true); - m_data->m_pBufContactBuffersGPU[1] = new b3OpenCLArray(ctx,queue, config.m_maxContactCapacity,true); - - m_data->m_inertiaBufferGPU = new b3OpenCLArray(ctx,queue,config.m_maxConvexBodies,false); - m_data->m_collidablesGPU = new b3OpenCLArray(ctx,queue,config.m_maxConvexShapes); + + m_data->m_pBufContactBuffersGPU[0] = new b3OpenCLArray(ctx, queue, config.m_maxContactCapacity, true); + m_data->m_pBufContactBuffersGPU[1] = new b3OpenCLArray(ctx, queue, config.m_maxContactCapacity, true); + + m_data->m_inertiaBufferGPU = new b3OpenCLArray(ctx, queue, config.m_maxConvexBodies, false); + m_data->m_collidablesGPU = new b3OpenCLArray(ctx, queue, config.m_maxConvexShapes); m_data->m_collidablesCPU.reserve(config.m_maxConvexShapes); m_data->m_localShapeAABBCPU = new b3AlignedObjectArray; - m_data->m_localShapeAABBGPU = new b3OpenCLArray(ctx,queue,config.m_maxConvexShapes); - - + m_data->m_localShapeAABBGPU = new b3OpenCLArray(ctx, queue, config.m_maxConvexShapes); + //m_data->m_solverDataGPU = adl::Solver::allocate(ctx,queue, config.m_maxBroadphasePairs,false); - m_data->m_bodyBufferGPU = new b3OpenCLArray(ctx,queue, config.m_maxConvexBodies,false); + m_data->m_bodyBufferGPU = new b3OpenCLArray(ctx, queue, config.m_maxConvexBodies, false); - m_data->m_convexFacesGPU = new b3OpenCLArray(ctx,queue,config.m_maxConvexShapes*config.m_maxFacesPerShape,false); - m_data->m_convexFaces.reserve(config.m_maxConvexShapes*config.m_maxFacesPerShape); + m_data->m_convexFacesGPU = new b3OpenCLArray(ctx, queue, config.m_maxConvexShapes * config.m_maxFacesPerShape, false); + m_data->m_convexFaces.reserve(config.m_maxConvexShapes * config.m_maxFacesPerShape); - m_data->m_gpuChildShapes = new b3OpenCLArray(ctx,queue,config.m_maxCompoundChildShapes,false); - - m_data->m_convexPolyhedraGPU = new b3OpenCLArray(ctx,queue,config.m_maxConvexShapes,false); + m_data->m_gpuChildShapes = new b3OpenCLArray(ctx, queue, config.m_maxCompoundChildShapes, false); + + m_data->m_convexPolyhedraGPU = new b3OpenCLArray(ctx, queue, config.m_maxConvexShapes, false); m_data->m_convexPolyhedra.reserve(config.m_maxConvexShapes); - m_data->m_uniqueEdgesGPU = new b3OpenCLArray(ctx,queue,config.m_maxConvexUniqueEdges,true); + m_data->m_uniqueEdgesGPU = new b3OpenCLArray(ctx, queue, config.m_maxConvexUniqueEdges, true); m_data->m_uniqueEdges.reserve(config.m_maxConvexUniqueEdges); - - - m_data->m_convexVerticesGPU = new b3OpenCLArray(ctx,queue,config.m_maxConvexVertices,true); + m_data->m_convexVerticesGPU = new b3OpenCLArray(ctx, queue, config.m_maxConvexVertices, true); m_data->m_convexVertices.reserve(config.m_maxConvexVertices); - m_data->m_convexIndicesGPU = new b3OpenCLArray(ctx,queue,config.m_maxConvexIndices,true); - m_data->m_convexIndices.reserve(config.m_maxConvexIndices); - - m_data->m_worldVertsB1GPU = new b3OpenCLArray(ctx,queue,config.m_maxConvexBodies*config.m_maxVerticesPerFace); - m_data->m_clippingFacesOutGPU = new b3OpenCLArray(ctx,queue,config.m_maxConvexBodies); - m_data->m_worldNormalsAGPU = new b3OpenCLArray(ctx,queue,config.m_maxConvexBodies); - m_data->m_worldVertsA1GPU = new b3OpenCLArray(ctx,queue,config.m_maxConvexBodies*config.m_maxVerticesPerFace); - m_data->m_worldVertsB2GPU = new b3OpenCLArray(ctx,queue,config.m_maxConvexBodies*config.m_maxVerticesPerFace); - - + m_data->m_convexIndicesGPU = new b3OpenCLArray(ctx, queue, config.m_maxConvexIndices, true); + m_data->m_convexIndices.reserve(config.m_maxConvexIndices); - m_data->m_convexData = new b3AlignedObjectArray(); + m_data->m_worldVertsB1GPU = new b3OpenCLArray(ctx, queue, config.m_maxConvexBodies * config.m_maxVerticesPerFace); + m_data->m_clippingFacesOutGPU = new b3OpenCLArray(ctx, queue, config.m_maxConvexBodies); + m_data->m_worldNormalsAGPU = new b3OpenCLArray(ctx, queue, config.m_maxConvexBodies); + m_data->m_worldVertsA1GPU = new b3OpenCLArray(ctx, queue, config.m_maxConvexBodies * config.m_maxVerticesPerFace); + m_data->m_worldVertsB2GPU = new b3OpenCLArray(ctx, queue, config.m_maxConvexBodies * config.m_maxVerticesPerFace); + + m_data->m_convexData = new b3AlignedObjectArray(); m_data->m_convexData->resize(config.m_maxConvexShapes); m_data->m_convexPolyhedra.resize(config.m_maxConvexShapes); - + m_data->m_numAcceleratedShapes = 0; m_data->m_numAcceleratedRigidBodies = 0; - - - m_data->m_subTreesGPU = new b3OpenCLArray(this->m_context,this->m_queue); - m_data->m_treeNodesGPU = new b3OpenCLArray(this->m_context,this->m_queue); - m_data->m_bvhInfoGPU = new b3OpenCLArray(this->m_context,this->m_queue); + + m_data->m_subTreesGPU = new b3OpenCLArray(this->m_context, this->m_queue); + m_data->m_treeNodesGPU = new b3OpenCLArray(this->m_context, this->m_queue); + m_data->m_bvhInfoGPU = new b3OpenCLArray(this->m_context, this->m_queue); //m_data->m_contactCGPU = new b3OpenCLArray(ctx,queue,config.m_maxBroadphasePairs,false); //m_data->m_frictionCGPU = new b3OpenCLArray::allocateFrictionConstraint( m_data->m_deviceCL, config.m_maxBroadphasePairs); - - - } - b3GpuNarrowPhase::~b3GpuNarrowPhase() { delete m_data->m_gpuSatCollision; - + delete m_data->m_triangleConvexPairs; //delete m_data->m_convexPairsOutGPU; //delete m_data->m_planePairs; @@ -126,7 +105,6 @@ b3GpuNarrowPhase::~b3GpuNarrowPhase() delete m_data->m_pBufContactBuffersGPU[0]; delete m_data->m_pBufContactBuffersGPU[1]; - delete m_data->m_inertiaBufferGPU; delete m_data->m_collidablesGPU; delete m_data->m_localShapeAABBCPU; @@ -139,18 +117,18 @@ b3GpuNarrowPhase::~b3GpuNarrowPhase() delete m_data->m_convexVerticesGPU; delete m_data->m_convexIndicesGPU; delete m_data->m_worldVertsB1GPU; - delete m_data->m_clippingFacesOutGPU; - delete m_data->m_worldNormalsAGPU; + delete m_data->m_clippingFacesOutGPU; + delete m_data->m_worldNormalsAGPU; delete m_data->m_worldVertsA1GPU; - delete m_data->m_worldVertsB2GPU; - + delete m_data->m_worldVertsB2GPU; + delete m_data->m_bvhInfoGPU; - for (int i=0;im_bvhData.size();i++) + for (int i = 0; i < m_data->m_bvhData.size(); i++) { delete m_data->m_bvhData[i]; } - for (int i=0;im_meshInterfaces.size();i++) + for (int i = 0; i < m_data->m_meshInterfaces.size(); i++) { delete m_data->m_meshInterfaces[i]; } @@ -159,198 +137,180 @@ b3GpuNarrowPhase::~b3GpuNarrowPhase() delete m_data->m_treeNodesGPU; delete m_data->m_subTreesGPU; - - delete m_data->m_convexData; + delete m_data->m_convexData; delete m_data; } - -int b3GpuNarrowPhase::allocateCollidable() +int b3GpuNarrowPhase::allocateCollidable() { int curSize = m_data->m_collidablesCPU.size(); - if (curSizem_config.m_maxConvexShapes) + if (curSize < m_data->m_config.m_maxConvexShapes) { m_data->m_collidablesCPU.expand(); return curSize; } else { - b3Error("allocateCollidable out-of-range %d\n",m_data->m_config.m_maxConvexShapes); + b3Error("allocateCollidable out-of-range %d\n", m_data->m_config.m_maxConvexShapes); } return -1; - } - - - - -int b3GpuNarrowPhase::registerSphereShape(float radius) +int b3GpuNarrowPhase::registerSphereShape(float radius) { int collidableIndex = allocateCollidable(); - if (collidableIndex<0) + if (collidableIndex < 0) return collidableIndex; - b3Collidable& col = getCollidableCpu(collidableIndex); col.m_shapeType = SHAPE_SPHERE; col.m_shapeIndex = 0; col.m_radius = radius; - - if (col.m_shapeIndex>=0) + + if (col.m_shapeIndex >= 0) { b3SapAabb aabb; - b3Vector3 myAabbMin=b3MakeVector3(-radius,-radius,-radius); - b3Vector3 myAabbMax=b3MakeVector3(radius,radius,radius); + b3Vector3 myAabbMin = b3MakeVector3(-radius, -radius, -radius); + b3Vector3 myAabbMax = b3MakeVector3(radius, radius, radius); - aabb.m_min[0] = myAabbMin[0];//s_convexHeightField->m_aabb.m_min.x; - aabb.m_min[1] = myAabbMin[1];//s_convexHeightField->m_aabb.m_min.y; - aabb.m_min[2] = myAabbMin[2];//s_convexHeightField->m_aabb.m_min.z; + aabb.m_min[0] = myAabbMin[0]; //s_convexHeightField->m_aabb.m_min.x; + aabb.m_min[1] = myAabbMin[1]; //s_convexHeightField->m_aabb.m_min.y; + aabb.m_min[2] = myAabbMin[2]; //s_convexHeightField->m_aabb.m_min.z; aabb.m_minIndices[3] = 0; - aabb.m_max[0] = myAabbMax[0];//s_convexHeightField->m_aabb.m_max.x; - aabb.m_max[1] = myAabbMax[1];//s_convexHeightField->m_aabb.m_max.y; - aabb.m_max[2] = myAabbMax[2];//s_convexHeightField->m_aabb.m_max.z; + aabb.m_max[0] = myAabbMax[0]; //s_convexHeightField->m_aabb.m_max.x; + aabb.m_max[1] = myAabbMax[1]; //s_convexHeightField->m_aabb.m_max.y; + aabb.m_max[2] = myAabbMax[2]; //s_convexHeightField->m_aabb.m_max.z; aabb.m_signedMaxIndices[3] = 0; m_data->m_localShapeAABBCPU->push_back(aabb); -// m_data->m_localShapeAABBGPU->push_back(aabb); + // m_data->m_localShapeAABBGPU->push_back(aabb); clFinish(m_queue); } - + return collidableIndex; } - int b3GpuNarrowPhase::registerFace(const b3Vector3& faceNormal, float faceConstant) { int faceOffset = m_data->m_convexFaces.size(); b3GpuFace& face = m_data->m_convexFaces.expand(); - face.m_plane = b3MakeVector3(faceNormal.x,faceNormal.y,faceNormal.z,faceConstant); + face.m_plane = b3MakeVector3(faceNormal.x, faceNormal.y, faceNormal.z, faceConstant); return faceOffset; } -int b3GpuNarrowPhase::registerPlaneShape(const b3Vector3& planeNormal, float planeConstant) +int b3GpuNarrowPhase::registerPlaneShape(const b3Vector3& planeNormal, float planeConstant) { int collidableIndex = allocateCollidable(); - if (collidableIndex<0) + if (collidableIndex < 0) return collidableIndex; - b3Collidable& col = getCollidableCpu(collidableIndex); col.m_shapeType = SHAPE_PLANE; - col.m_shapeIndex = registerFace(planeNormal,planeConstant); + col.m_shapeIndex = registerFace(planeNormal, planeConstant); col.m_radius = planeConstant; - - if (col.m_shapeIndex>=0) + + if (col.m_shapeIndex >= 0) { b3SapAabb aabb; aabb.m_min[0] = -1e30f; aabb.m_min[1] = -1e30f; aabb.m_min[2] = -1e30f; aabb.m_minIndices[3] = 0; - + aabb.m_max[0] = 1e30f; aabb.m_max[1] = 1e30f; aabb.m_max[2] = 1e30f; aabb.m_signedMaxIndices[3] = 0; m_data->m_localShapeAABBCPU->push_back(aabb); -// m_data->m_localShapeAABBGPU->push_back(aabb); + // m_data->m_localShapeAABBGPU->push_back(aabb); clFinish(m_queue); } - + return collidableIndex; } - -int b3GpuNarrowPhase::registerConvexHullShapeInternal(b3ConvexUtility* convexPtr,b3Collidable& col) +int b3GpuNarrowPhase::registerConvexHullShapeInternal(b3ConvexUtility* convexPtr, b3Collidable& col) { + m_data->m_convexData->resize(m_data->m_numAcceleratedShapes + 1); + m_data->m_convexPolyhedra.resize(m_data->m_numAcceleratedShapes + 1); - m_data->m_convexData->resize(m_data->m_numAcceleratedShapes+1); - m_data->m_convexPolyhedra.resize(m_data->m_numAcceleratedShapes+1); - - - b3ConvexPolyhedronData& convex = m_data->m_convexPolyhedra.at(m_data->m_convexPolyhedra.size()-1); + b3ConvexPolyhedronData& convex = m_data->m_convexPolyhedra.at(m_data->m_convexPolyhedra.size() - 1); convex.mC = convexPtr->mC; convex.mE = convexPtr->mE; - convex.m_extents= convexPtr->m_extents; + convex.m_extents = convexPtr->m_extents; convex.m_localCenter = convexPtr->m_localCenter; convex.m_radius = convexPtr->m_radius; - + convex.m_numUniqueEdges = convexPtr->m_uniqueEdges.size(); int edgeOffset = m_data->m_uniqueEdges.size(); convex.m_uniqueEdgesOffset = edgeOffset; - - m_data->m_uniqueEdges.resize(edgeOffset+convex.m_numUniqueEdges); - + + m_data->m_uniqueEdges.resize(edgeOffset + convex.m_numUniqueEdges); + //convex data here int i; - for ( i=0;im_uniqueEdges.size();i++) + for (i = 0; i < convexPtr->m_uniqueEdges.size(); i++) { - m_data->m_uniqueEdges[edgeOffset+i] = convexPtr->m_uniqueEdges[i]; + m_data->m_uniqueEdges[edgeOffset + i] = convexPtr->m_uniqueEdges[i]; } - + int faceOffset = m_data->m_convexFaces.size(); convex.m_faceOffset = faceOffset; convex.m_numFaces = convexPtr->m_faces.size(); - m_data->m_convexFaces.resize(faceOffset+convex.m_numFaces); - + m_data->m_convexFaces.resize(faceOffset + convex.m_numFaces); - for (i=0;im_faces.size();i++) + for (i = 0; i < convexPtr->m_faces.size(); i++) { - m_data->m_convexFaces[convex.m_faceOffset+i].m_plane = b3MakeVector3(convexPtr->m_faces[i].m_plane[0], - convexPtr->m_faces[i].m_plane[1], - convexPtr->m_faces[i].m_plane[2], - convexPtr->m_faces[i].m_plane[3]); + m_data->m_convexFaces[convex.m_faceOffset + i].m_plane = b3MakeVector3(convexPtr->m_faces[i].m_plane[0], + convexPtr->m_faces[i].m_plane[1], + convexPtr->m_faces[i].m_plane[2], + convexPtr->m_faces[i].m_plane[3]); - int indexOffset = m_data->m_convexIndices.size(); int numIndices = convexPtr->m_faces[i].m_indices.size(); - m_data->m_convexFaces[convex.m_faceOffset+i].m_numIndices = numIndices; - m_data->m_convexFaces[convex.m_faceOffset+i].m_indexOffset = indexOffset; - m_data->m_convexIndices.resize(indexOffset+numIndices); - for (int p=0;pm_convexFaces[convex.m_faceOffset + i].m_numIndices = numIndices; + m_data->m_convexFaces[convex.m_faceOffset + i].m_indexOffset = indexOffset; + m_data->m_convexIndices.resize(indexOffset + numIndices); + for (int p = 0; p < numIndices; p++) { - m_data->m_convexIndices[indexOffset+p] = convexPtr->m_faces[i].m_indices[p]; + m_data->m_convexIndices[indexOffset + p] = convexPtr->m_faces[i].m_indices[p]; } } - + convex.m_numVertices = convexPtr->m_vertices.size(); int vertexOffset = m_data->m_convexVertices.size(); - convex.m_vertexOffset =vertexOffset; - - m_data->m_convexVertices.resize(vertexOffset+convex.m_numVertices); - for (int i=0;im_vertices.size();i++) + convex.m_vertexOffset = vertexOffset; + + m_data->m_convexVertices.resize(vertexOffset + convex.m_numVertices); + for (int i = 0; i < convexPtr->m_vertices.size(); i++) { - m_data->m_convexVertices[vertexOffset+i] = convexPtr->m_vertices[i]; + m_data->m_convexVertices[vertexOffset + i] = convexPtr->m_vertices[i]; } (*m_data->m_convexData)[m_data->m_numAcceleratedShapes] = convexPtr; - - - + return m_data->m_numAcceleratedShapes++; } - -int b3GpuNarrowPhase::registerConvexHullShape(const float* vertices, int strideInBytes, int numVertices, const float* scaling) +int b3GpuNarrowPhase::registerConvexHullShape(const float* vertices, int strideInBytes, int numVertices, const float* scaling) { b3AlignedObjectArray verts; - unsigned char* vts = (unsigned char*) vertices; - for (int i=0;iinitializePolyhedralFeatures(&verts[0],verts.size(),merge); + utilPtr->initializePolyhedralFeatures(&verts[0], verts.size(), merge); } int collidableIndex = registerConvexHullShape(utilPtr); @@ -358,35 +318,34 @@ int b3GpuNarrowPhase::registerConvexHullShape(const float* vertices, int stride return collidableIndex; } -int b3GpuNarrowPhase::registerConvexHullShape(b3ConvexUtility* utilPtr) +int b3GpuNarrowPhase::registerConvexHullShape(b3ConvexUtility* utilPtr) { int collidableIndex = allocateCollidable(); - if (collidableIndex<0) + if (collidableIndex < 0) return collidableIndex; b3Collidable& col = getCollidableCpu(collidableIndex); col.m_shapeType = SHAPE_CONVEX_HULL; col.m_shapeIndex = -1; - - + { - b3Vector3 localCenter=b3MakeVector3(0,0,0); - for (int i=0;im_vertices.size();i++) - localCenter+=utilPtr->m_vertices[i]; - localCenter*= (1.f/utilPtr->m_vertices.size()); + b3Vector3 localCenter = b3MakeVector3(0, 0, 0); + for (int i = 0; i < utilPtr->m_vertices.size(); i++) + localCenter += utilPtr->m_vertices[i]; + localCenter *= (1.f / utilPtr->m_vertices.size()); utilPtr->m_localCenter = localCenter; - col.m_shapeIndex = registerConvexHullShapeInternal(utilPtr,col); + col.m_shapeIndex = registerConvexHullShapeInternal(utilPtr, col); } - if (col.m_shapeIndex>=0) + if (col.m_shapeIndex >= 0) { b3SapAabb aabb; - - b3Vector3 myAabbMin=b3MakeVector3(1e30f,1e30f,1e30f); - b3Vector3 myAabbMax=b3MakeVector3(-1e30f,-1e30f,-1e30f); - for (int i=0;im_vertices.size();i++) + b3Vector3 myAabbMin = b3MakeVector3(1e30f, 1e30f, 1e30f); + b3Vector3 myAabbMax = b3MakeVector3(-1e30f, -1e30f, -1e30f); + + for (int i = 0; i < utilPtr->m_vertices.size(); i++) { myAabbMin.setMin(utilPtr->m_vertices[i]); myAabbMax.setMax(utilPtr->m_vertices[i]); @@ -402,18 +361,16 @@ int b3GpuNarrowPhase::registerConvexHullShape(b3ConvexUtility* utilPtr) aabb.m_signedMaxIndices[3] = 0; m_data->m_localShapeAABBCPU->push_back(aabb); -// m_data->m_localShapeAABBGPU->push_back(aabb); + // m_data->m_localShapeAABBGPU->push_back(aabb); } - - return collidableIndex; + return collidableIndex; } -int b3GpuNarrowPhase::registerCompoundShape(b3AlignedObjectArray* childShapes) +int b3GpuNarrowPhase::registerCompoundShape(b3AlignedObjectArray* childShapes) { - int collidableIndex = allocateCollidable(); - if (collidableIndex<0) + if (collidableIndex < 0) return collidableIndex; b3Collidable& col = getCollidableCpu(collidableIndex); @@ -422,44 +379,41 @@ int b3GpuNarrowPhase::registerCompoundShape(b3AlignedObjectArraym_bvhInfoCPU.size(); { - b3Assert(col.m_shapeIndex+childShapes->size()m_config.m_maxCompoundChildShapes); - for (int i=0;isize();i++) + b3Assert(col.m_shapeIndex + childShapes->size() < m_data->m_config.m_maxCompoundChildShapes); + for (int i = 0; i < childShapes->size(); i++) { m_data->m_cpuChildShapes.push_back(childShapes->at(i)); } } - - col.m_numChildShapes = childShapes->size(); - - + b3SapAabb aabbLocalSpace; - b3Vector3 myAabbMin=b3MakeVector3(1e30f,1e30f,1e30f); - b3Vector3 myAabbMax=b3MakeVector3(-1e30f,-1e30f,-1e30f); - + b3Vector3 myAabbMin = b3MakeVector3(1e30f, 1e30f, 1e30f); + b3Vector3 myAabbMax = b3MakeVector3(-1e30f, -1e30f, -1e30f); + b3AlignedObjectArray childLocalAabbs; childLocalAabbs.resize(childShapes->size()); //compute local AABB of the compound of all children - for (int i=0;isize();i++) + for (int i = 0; i < childShapes->size(); i++) { int childColIndex = childShapes->at(i).m_shapeIndex; //b3Collidable& childCol = getCollidableCpu(childColIndex); - b3SapAabb aabbLoc =m_data->m_localShapeAABBCPU->at(childColIndex); + b3SapAabb aabbLoc = m_data->m_localShapeAABBCPU->at(childColIndex); - b3Vector3 childLocalAabbMin=b3MakeVector3(aabbLoc.m_min[0],aabbLoc.m_min[1],aabbLoc.m_min[2]); - b3Vector3 childLocalAabbMax=b3MakeVector3(aabbLoc.m_max[0],aabbLoc.m_max[1],aabbLoc.m_max[2]); - b3Vector3 aMin,aMax; + b3Vector3 childLocalAabbMin = b3MakeVector3(aabbLoc.m_min[0], aabbLoc.m_min[1], aabbLoc.m_min[2]); + b3Vector3 childLocalAabbMax = b3MakeVector3(aabbLoc.m_max[0], aabbLoc.m_max[1], aabbLoc.m_max[2]); + b3Vector3 aMin, aMax; b3Scalar margin(0.f); b3Transform childTr; childTr.setIdentity(); childTr.setOrigin(childShapes->at(i).m_childPosition); childTr.setRotation(b3Quaternion(childShapes->at(i).m_childOrientation)); - b3TransformAabb(childLocalAabbMin,childLocalAabbMax,margin,childTr,aMin,aMax); + b3TransformAabb(childLocalAabbMin, childLocalAabbMax, margin, childTr, aMin, aMax); myAabbMin.setMin(aMin); - myAabbMax.setMax(aMax); + myAabbMax.setMax(aMax); childLocalAabbs[i].m_min[0] = aMin[0]; childLocalAabbs[i].m_min[1] = aMin[1]; childLocalAabbs[i].m_min[2] = aMin[2]; @@ -469,36 +423,35 @@ int b3GpuNarrowPhase::registerCompoundShape(b3AlignedObjectArraym_aabb.m_min.x; - aabbLocalSpace.m_min[1]= myAabbMin[1];//s_convexHeightField->m_aabb.m_min.y; - aabbLocalSpace.m_min[2]= myAabbMin[2];//s_convexHeightField->m_aabb.m_min.z; + + aabbLocalSpace.m_min[0] = myAabbMin[0]; //s_convexHeightField->m_aabb.m_min.x; + aabbLocalSpace.m_min[1] = myAabbMin[1]; //s_convexHeightField->m_aabb.m_min.y; + aabbLocalSpace.m_min[2] = myAabbMin[2]; //s_convexHeightField->m_aabb.m_min.z; aabbLocalSpace.m_minIndices[3] = 0; - - aabbLocalSpace.m_max[0] = myAabbMax[0];//s_convexHeightField->m_aabb.m_max.x; - aabbLocalSpace.m_max[1]= myAabbMax[1];//s_convexHeightField->m_aabb.m_max.y; - aabbLocalSpace.m_max[2]= myAabbMax[2];//s_convexHeightField->m_aabb.m_max.z; + + aabbLocalSpace.m_max[0] = myAabbMax[0]; //s_convexHeightField->m_aabb.m_max.x; + aabbLocalSpace.m_max[1] = myAabbMax[1]; //s_convexHeightField->m_aabb.m_max.y; + aabbLocalSpace.m_max[2] = myAabbMax[2]; //s_convexHeightField->m_aabb.m_max.z; aabbLocalSpace.m_signedMaxIndices[3] = 0; - + m_data->m_localShapeAABBCPU->push_back(aabbLocalSpace); - b3QuantizedBvh* bvh = new b3QuantizedBvh; - bvh->setQuantizationValues(myAabbMin,myAabbMax); - QuantizedNodeArray& nodes = bvh->getLeafNodeArray(); + bvh->setQuantizationValues(myAabbMin, myAabbMax); + QuantizedNodeArray& nodes = bvh->getLeafNodeArray(); int numNodes = childShapes->size(); - for (int i=0;iquantize(&node.m_quantizedAabbMin[0],aabbMin,0); - bvh->quantize(&node.m_quantizedAabbMax[0],aabbMax,1); + bvh->quantize(&node.m_quantizedAabbMin[0], aabbMin, 0); + bvh->quantize(&node.m_quantizedAabbMax[0], aabbMax, 1); int partId = 0; - node.m_escapeIndexOrTriangleIndex = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | i; + node.m_escapeIndexOrTriangleIndex = (partId << (31 - MAX_NUM_PARTS_IN_BITS)) | i; nodes.push_back(node); } bvh->buildInternal(); @@ -511,7 +464,7 @@ int b3GpuNarrowPhase::registerCompoundShape(b3AlignedObjectArraym_bvhAabbMin; bvhInfo.m_aabbMax = bvh->m_bvhAabbMax; bvhInfo.m_quantization = bvh->m_bvhQuantization; @@ -520,80 +473,72 @@ int b3GpuNarrowPhase::registerCompoundShape(b3AlignedObjectArraym_treeNodesCPU.size(); bvhInfo.m_subTreeOffset = m_data->m_subTreesCPU.size(); - int numNewNodes = bvh->getQuantizedNodeArray().size(); + int numNewNodes = bvh->getQuantizedNodeArray().size(); - for (int i=0;igetQuantizedNodeArray()[i].isLeafNode()) { int orgIndex = bvh->getQuantizedNodeArray()[i].getTriangleIndex(); b3Vector3 nodeMinVec = bvh->unQuantize(bvh->getQuantizedNodeArray()[i].m_quantizedAabbMin); b3Vector3 nodeMaxVec = bvh->unQuantize(bvh->getQuantizedNodeArray()[i].m_quantizedAabbMax); - - for (int c=0;c<3;c++) + + for (int c = 0; c < 3; c++) { if (childLocalAabbs[orgIndex].m_min[c] < nodeMinVec[c]) { - printf("min org (%f) and new (%f) ? at i:%d,c:%d\n",childLocalAabbs[i].m_min[c],nodeMinVec[c],i,c); + printf("min org (%f) and new (%f) ? at i:%d,c:%d\n", childLocalAabbs[i].m_min[c], nodeMinVec[c], i, c); } if (childLocalAabbs[orgIndex].m_max[c] > nodeMaxVec[c]) { - printf("max org (%f) and new (%f) ? at i:%d,c:%d\n",childLocalAabbs[i].m_max[c],nodeMaxVec[c],i,c); + printf("max org (%f) and new (%f) ? at i:%d,c:%d\n", childLocalAabbs[i].m_max[c], nodeMaxVec[c], i, c); } - } } - } m_data->m_bvhInfoCPU.push_back(bvhInfo); int numNewSubtrees = bvh->getSubtreeInfoArray().size(); - m_data->m_subTreesCPU.reserve(m_data->m_subTreesCPU.size()+numNewSubtrees); - for (int i=0;im_subTreesCPU.reserve(m_data->m_subTreesCPU.size() + numNewSubtrees); + for (int i = 0; i < numNewSubtrees; i++) { m_data->m_subTreesCPU.push_back(bvh->getSubtreeInfoArray()[i]); } int numNewTreeNodes = bvh->getQuantizedNodeArray().size(); - for (int i=0;im_treeNodesCPU.push_back(bvh->getQuantizedNodeArray()[i]); } -// m_data->m_localShapeAABBGPU->push_back(aabbWS); + // m_data->m_localShapeAABBGPU->push_back(aabbWS); clFinish(m_queue); return collidableIndex; - } - -int b3GpuNarrowPhase::registerConcaveMesh(b3AlignedObjectArray* vertices, b3AlignedObjectArray* indices,const float* scaling1) +int b3GpuNarrowPhase::registerConcaveMesh(b3AlignedObjectArray* vertices, b3AlignedObjectArray* indices, const float* scaling1) { - - - b3Vector3 scaling=b3MakeVector3(scaling1[0],scaling1[1],scaling1[2]); + b3Vector3 scaling = b3MakeVector3(scaling1[0], scaling1[1], scaling1[2]); int collidableIndex = allocateCollidable(); - if (collidableIndex<0) + if (collidableIndex < 0) return collidableIndex; b3Collidable& col = getCollidableCpu(collidableIndex); - + col.m_shapeType = SHAPE_CONCAVE_TRIMESH; - col.m_shapeIndex = registerConcaveMeshShape(vertices,indices,col,scaling); + col.m_shapeIndex = registerConcaveMeshShape(vertices, indices, col, scaling); col.m_bvhIndex = m_data->m_bvhInfoCPU.size(); - b3SapAabb aabb; - b3Vector3 myAabbMin=b3MakeVector3(1e30f,1e30f,1e30f); - b3Vector3 myAabbMax=b3MakeVector3(-1e30f,-1e30f,-1e30f); + b3Vector3 myAabbMin = b3MakeVector3(1e30f, 1e30f, 1e30f); + b3Vector3 myAabbMax = b3MakeVector3(-1e30f, -1e30f, -1e30f); - for (int i=0;isize();i++) + for (int i = 0; i < vertices->size(); i++) { - b3Vector3 vtx(vertices->at(i)*scaling); + b3Vector3 vtx(vertices->at(i) * scaling); myAabbMin.setMin(vtx); myAabbMax.setMax(vtx); } @@ -603,27 +548,27 @@ int b3GpuNarrowPhase::registerConcaveMesh(b3AlignedObjectArray* vert aabb.m_minIndices[3] = 0; aabb.m_max[0] = myAabbMax[0]; - aabb.m_max[1]= myAabbMax[1]; - aabb.m_max[2]= myAabbMax[2]; - aabb.m_signedMaxIndices[3]= 0; + aabb.m_max[1] = myAabbMax[1]; + aabb.m_max[2] = myAabbMax[2]; + aabb.m_signedMaxIndices[3] = 0; m_data->m_localShapeAABBCPU->push_back(aabb); -// m_data->m_localShapeAABBGPU->push_back(aabb); + // m_data->m_localShapeAABBGPU->push_back(aabb); b3OptimizedBvh* bvh = new b3OptimizedBvh(); //void b3OptimizedBvh::build(b3StridingMeshInterface* triangles, bool useQuantizedAabbCompression, const b3Vector3& bvhAabbMin, const b3Vector3& bvhAabbMax) - + bool useQuantizedAabbCompression = true; - b3TriangleIndexVertexArray* meshInterface=new b3TriangleIndexVertexArray(); + b3TriangleIndexVertexArray* meshInterface = new b3TriangleIndexVertexArray(); m_data->m_meshInterfaces.push_back(meshInterface); b3IndexedMesh mesh; - mesh.m_numTriangles = indices->size()/3; + mesh.m_numTriangles = indices->size() / 3; mesh.m_numVertices = vertices->size(); - mesh.m_vertexBase = (const unsigned char *)&vertices->at(0).x; + mesh.m_vertexBase = (const unsigned char*)&vertices->at(0).x; mesh.m_vertexStride = sizeof(b3Vector3); - mesh.m_triangleIndexStride = 3 * sizeof(int);// or sizeof(int) - mesh.m_triangleIndexBase = (const unsigned char *)&indices->at(0); - + mesh.m_triangleIndexStride = 3 * sizeof(int); // or sizeof(int) + mesh.m_triangleIndexBase = (const unsigned char*)&indices->at(0); + meshInterface->addIndexedMesh(mesh); bvh->build(meshInterface, useQuantizedAabbCompression, (b3Vector3&)aabb.m_min, (b3Vector3&)aabb.m_max); m_data->m_bvhData.push_back(bvh); @@ -632,7 +577,7 @@ int b3GpuNarrowPhase::registerConcaveMesh(b3AlignedObjectArray* vert int numSubTrees = bvh->getSubtreeInfoArray().size(); b3BvhInfo bvhInfo; - + bvhInfo.m_aabbMin = bvh->m_bvhAabbMin; bvhInfo.m_aabbMax = bvh->m_bvhAabbMax; bvhInfo.m_quantization = bvh->m_bvhQuantization; @@ -643,97 +588,87 @@ int b3GpuNarrowPhase::registerConcaveMesh(b3AlignedObjectArray* vert m_data->m_bvhInfoCPU.push_back(bvhInfo); - int numNewSubtrees = bvh->getSubtreeInfoArray().size(); - m_data->m_subTreesCPU.reserve(m_data->m_subTreesCPU.size()+numNewSubtrees); - for (int i=0;im_subTreesCPU.reserve(m_data->m_subTreesCPU.size() + numNewSubtrees); + for (int i = 0; i < numNewSubtrees; i++) { m_data->m_subTreesCPU.push_back(bvh->getSubtreeInfoArray()[i]); } int numNewTreeNodes = bvh->getQuantizedNodeArray().size(); - for (int i=0;im_treeNodesCPU.push_back(bvh->getQuantizedNodeArray()[i]); } - - - return collidableIndex; } -int b3GpuNarrowPhase::registerConcaveMeshShape(b3AlignedObjectArray* vertices, b3AlignedObjectArray* indices,b3Collidable& col, const float* scaling1) +int b3GpuNarrowPhase::registerConcaveMeshShape(b3AlignedObjectArray* vertices, b3AlignedObjectArray* indices, b3Collidable& col, const float* scaling1) { + b3Vector3 scaling = b3MakeVector3(scaling1[0], scaling1[1], scaling1[2]); + m_data->m_convexData->resize(m_data->m_numAcceleratedShapes + 1); + m_data->m_convexPolyhedra.resize(m_data->m_numAcceleratedShapes + 1); - b3Vector3 scaling=b3MakeVector3(scaling1[0],scaling1[1],scaling1[2]); - - m_data->m_convexData->resize(m_data->m_numAcceleratedShapes+1); - m_data->m_convexPolyhedra.resize(m_data->m_numAcceleratedShapes+1); - - - b3ConvexPolyhedronData& convex = m_data->m_convexPolyhedra.at(m_data->m_convexPolyhedra.size()-1); - convex.mC = b3MakeVector3(0,0,0); - convex.mE = b3MakeVector3(0,0,0); - convex.m_extents= b3MakeVector3(0,0,0); - convex.m_localCenter = b3MakeVector3(0,0,0); + b3ConvexPolyhedronData& convex = m_data->m_convexPolyhedra.at(m_data->m_convexPolyhedra.size() - 1); + convex.mC = b3MakeVector3(0, 0, 0); + convex.mE = b3MakeVector3(0, 0, 0); + convex.m_extents = b3MakeVector3(0, 0, 0); + convex.m_localCenter = b3MakeVector3(0, 0, 0); convex.m_radius = 0.f; - + convex.m_numUniqueEdges = 0; int edgeOffset = m_data->m_uniqueEdges.size(); convex.m_uniqueEdgesOffset = edgeOffset; - + int faceOffset = m_data->m_convexFaces.size(); convex.m_faceOffset = faceOffset; - - convex.m_numFaces = indices->size()/3; - m_data->m_convexFaces.resize(faceOffset+convex.m_numFaces); - m_data->m_convexIndices.reserve(convex.m_numFaces*3); - for (int i=0;isize() / 3; + m_data->m_convexFaces.resize(faceOffset + convex.m_numFaces); + m_data->m_convexIndices.reserve(convex.m_numFaces * 3); + for (int i = 0; i < convex.m_numFaces; i++) { - if (i%256==0) + if (i % 256 == 0) { //printf("i=%d out of %d", i,convex.m_numFaces); } - b3Vector3 vert0(vertices->at(indices->at(i*3))*scaling); - b3Vector3 vert1(vertices->at(indices->at(i*3+1))*scaling); - b3Vector3 vert2(vertices->at(indices->at(i*3+2))*scaling); + b3Vector3 vert0(vertices->at(indices->at(i * 3)) * scaling); + b3Vector3 vert1(vertices->at(indices->at(i * 3 + 1)) * scaling); + b3Vector3 vert2(vertices->at(indices->at(i * 3 + 2)) * scaling); - b3Vector3 normal = ((vert1-vert0).cross(vert2-vert0)).normalize(); + b3Vector3 normal = ((vert1 - vert0).cross(vert2 - vert0)).normalize(); b3Scalar c = -(normal.dot(vert0)); - m_data->m_convexFaces[convex.m_faceOffset+i].m_plane = b3MakeVector4(normal.x,normal.y,normal.z,c); + m_data->m_convexFaces[convex.m_faceOffset + i].m_plane = b3MakeVector4(normal.x, normal.y, normal.z, c); int indexOffset = m_data->m_convexIndices.size(); int numIndices = 3; - m_data->m_convexFaces[convex.m_faceOffset+i].m_numIndices = numIndices; - m_data->m_convexFaces[convex.m_faceOffset+i].m_indexOffset = indexOffset; - m_data->m_convexIndices.resize(indexOffset+numIndices); - for (int p=0;pm_convexFaces[convex.m_faceOffset + i].m_numIndices = numIndices; + m_data->m_convexFaces[convex.m_faceOffset + i].m_indexOffset = indexOffset; + m_data->m_convexIndices.resize(indexOffset + numIndices); + for (int p = 0; p < numIndices; p++) { - int vi = indices->at(i*3+p); - m_data->m_convexIndices[indexOffset+p] = vi;//convexPtr->m_faces[i].m_indices[p]; + int vi = indices->at(i * 3 + p); + m_data->m_convexIndices[indexOffset + p] = vi; //convexPtr->m_faces[i].m_indices[p]; } } - + convex.m_numVertices = vertices->size(); int vertexOffset = m_data->m_convexVertices.size(); - convex.m_vertexOffset =vertexOffset; - m_data->m_convexVertices.resize(vertexOffset+convex.m_numVertices); - for (int i=0;isize();i++) + convex.m_vertexOffset = vertexOffset; + m_data->m_convexVertices.resize(vertexOffset + convex.m_numVertices); + for (int i = 0; i < vertices->size(); i++) { - m_data->m_convexVertices[vertexOffset+i] = vertices->at(i)*scaling; + m_data->m_convexVertices[vertexOffset + i] = vertices->at(i) * scaling; } (*m_data->m_convexData)[m_data->m_numAcceleratedShapes] = 0; - - + return m_data->m_numAcceleratedShapes++; } - - -cl_mem b3GpuNarrowPhase::getBodiesGpu() +cl_mem b3GpuNarrowPhase::getBodiesGpu() { return (cl_mem)m_data->m_bodyBufferGPU->getBufferCL(); } @@ -743,25 +678,21 @@ const struct b3RigidBodyData* b3GpuNarrowPhase::getBodiesCpu() const return &m_data->m_bodyBufferCPU->at(0); }; - - - -int b3GpuNarrowPhase::getNumBodiesGpu() const +int b3GpuNarrowPhase::getNumBodiesGpu() const { return m_data->m_bodyBufferGPU->size(); } -cl_mem b3GpuNarrowPhase::getBodyInertiasGpu() +cl_mem b3GpuNarrowPhase::getBodyInertiasGpu() { return (cl_mem)m_data->m_inertiaBufferGPU->getBufferCL(); } -int b3GpuNarrowPhase::getNumBodyInertiasGpu() const +int b3GpuNarrowPhase::getNumBodyInertiasGpu() const { return m_data->m_inertiaBufferGPU->size(); } - b3Collidable& b3GpuNarrowPhase::getCollidableCpu(int collidableIndex) { return m_data->m_collidablesCPU[collidableIndex]; @@ -789,25 +720,20 @@ const struct b3SapAabb* b3GpuNarrowPhase::getLocalSpaceAabbsCpu() const if (m_data->m_localShapeAABBCPU->size()) { return &m_data->m_localShapeAABBCPU->at(0); - } + } return 0; } - -cl_mem b3GpuNarrowPhase::getAabbLocalSpaceBufferGpu() +cl_mem b3GpuNarrowPhase::getAabbLocalSpaceBufferGpu() { return m_data->m_localShapeAABBGPU->getBufferCL(); } -int b3GpuNarrowPhase::getNumCollidablesGpu() const +int b3GpuNarrowPhase::getNumCollidablesGpu() const { return m_data->m_collidablesGPU->size(); } - - - - -int b3GpuNarrowPhase::getNumContactsGpu() const +int b3GpuNarrowPhase::getNumContactsGpu() const { return m_data->m_pBufContactBuffersGPU[m_data->m_currentContactBuffer]->size(); } @@ -824,37 +750,33 @@ const b3Contact4* b3GpuNarrowPhase::getContactsCPU() const void b3GpuNarrowPhase::computeContacts(cl_mem broadphasePairs, int numBroadphasePairs, cl_mem aabbsWorldSpace, int numObjects) { - cl_mem aabbsLocalSpace = m_data->m_localShapeAABBGPU->getBufferCL(); int nContactOut = 0; //swap buffer - m_data->m_currentContactBuffer=1-m_data->m_currentContactBuffer; + m_data->m_currentContactBuffer = 1 - m_data->m_currentContactBuffer; //int curSize = m_data->m_pBufContactBuffersGPU[m_data->m_currentContactBuffer]->size(); int maxTriConvexPairCapacity = m_data->m_config.m_maxTriConvexPairCapacity; - int numTriConvexPairsOut=0; - - b3OpenCLArray broadphasePairsGPU(m_context,m_queue); - broadphasePairsGPU.setFromOpenCLBuffer(broadphasePairs,numBroadphasePairs); + int numTriConvexPairsOut = 0; - + b3OpenCLArray broadphasePairsGPU(m_context, m_queue); + broadphasePairsGPU.setFromOpenCLBuffer(broadphasePairs, numBroadphasePairs); + b3OpenCLArray clAabbArrayWorldSpace(this->m_context, this->m_queue); + clAabbArrayWorldSpace.setFromOpenCLBuffer(aabbsWorldSpace, numObjects); - b3OpenCLArray clAabbArrayWorldSpace(this->m_context,this->m_queue); - clAabbArrayWorldSpace.setFromOpenCLBuffer(aabbsWorldSpace,numObjects); - - b3OpenCLArray clAabbArrayLocalSpace(this->m_context,this->m_queue); - clAabbArrayLocalSpace.setFromOpenCLBuffer(aabbsLocalSpace,numObjects); + b3OpenCLArray clAabbArrayLocalSpace(this->m_context, this->m_queue); + clAabbArrayLocalSpace.setFromOpenCLBuffer(aabbsLocalSpace, numObjects); m_data->m_gpuSatCollision->computeConvexConvexContactsGPUSAT( &broadphasePairsGPU, numBroadphasePairs, m_data->m_bodyBufferGPU, m_data->m_pBufContactBuffersGPU[m_data->m_currentContactBuffer], nContactOut, - m_data->m_pBufContactBuffersGPU[1-m_data->m_currentContactBuffer], + m_data->m_pBufContactBuffersGPU[1 - m_data->m_currentContactBuffer], m_data->m_config.m_maxContactCapacity, m_data->m_config.m_compoundPairCapacity, *m_data->m_convexPolyhedraGPU, @@ -878,8 +800,7 @@ void b3GpuNarrowPhase::computeContacts(cl_mem broadphasePairs, int numBroadphase numObjects, maxTriConvexPairCapacity, *m_data->m_triangleConvexPairs, - numTriConvexPairsOut - ); + numTriConvexPairsOut); /*b3AlignedObjectArray broadphasePairsCPU; broadphasePairsGPU.copyToHost(broadphasePairsCPU); @@ -892,105 +813,97 @@ const b3SapAabb& b3GpuNarrowPhase::getLocalSpaceAabb(int collidableIndex) const return m_data->m_localShapeAABBCPU->at(collidableIndex); } - - - - -int b3GpuNarrowPhase::registerRigidBody(int collidableIndex, float mass, const float* position, const float* orientation , const float* aabbMinPtr, const float* aabbMaxPtr,bool writeToGpu) +int b3GpuNarrowPhase::registerRigidBody(int collidableIndex, float mass, const float* position, const float* orientation, const float* aabbMinPtr, const float* aabbMaxPtr, bool writeToGpu) { - b3Vector3 aabbMin=b3MakeVector3(aabbMinPtr[0],aabbMinPtr[1],aabbMinPtr[2]); - b3Vector3 aabbMax=b3MakeVector3(aabbMaxPtr[0],aabbMaxPtr[1],aabbMaxPtr[2]); - + b3Vector3 aabbMin = b3MakeVector3(aabbMinPtr[0], aabbMinPtr[1], aabbMinPtr[2]); + b3Vector3 aabbMax = b3MakeVector3(aabbMaxPtr[0], aabbMaxPtr[1], aabbMaxPtr[2]); if (m_data->m_numAcceleratedRigidBodies >= (m_data->m_config.m_maxConvexBodies)) { - b3Error("registerRigidBody: exceeding the number of rigid bodies, %d > %d \n",m_data->m_numAcceleratedRigidBodies,m_data->m_config.m_maxConvexBodies); + b3Error("registerRigidBody: exceeding the number of rigid bodies, %d > %d \n", m_data->m_numAcceleratedRigidBodies, m_data->m_config.m_maxConvexBodies); return -1; } - - m_data->m_bodyBufferCPU->resize(m_data->m_numAcceleratedRigidBodies+1); - + + m_data->m_bodyBufferCPU->resize(m_data->m_numAcceleratedRigidBodies + 1); + b3RigidBodyData& body = m_data->m_bodyBufferCPU->at(m_data->m_numAcceleratedRigidBodies); - + float friction = 1.f; float restitution = 0.f; - + body.m_frictionCoeff = friction; body.m_restituitionCoeff = restitution; - body.m_angVel = b3MakeVector3(0,0,0); - body.m_linVel=b3MakeVector3(0,0,0);//.setZero(); - body.m_pos =b3MakeVector3(position[0],position[1],position[2]); - body.m_quat.setValue(orientation[0],orientation[1],orientation[2],orientation[3]); + body.m_angVel = b3MakeVector3(0, 0, 0); + body.m_linVel = b3MakeVector3(0, 0, 0); //.setZero(); + body.m_pos = b3MakeVector3(position[0], position[1], position[2]); + body.m_quat.setValue(orientation[0], orientation[1], orientation[2], orientation[3]); body.m_collidableIdx = collidableIndex; - if (collidableIndex>=0) + if (collidableIndex >= 0) { -// body.m_shapeType = m_data->m_collidablesCPU.at(collidableIndex).m_shapeType; - } else + // body.m_shapeType = m_data->m_collidablesCPU.at(collidableIndex).m_shapeType; + } + else { - // body.m_shapeType = CollisionShape::SHAPE_PLANE; + // body.m_shapeType = CollisionShape::SHAPE_PLANE; m_planeBodyIndex = m_data->m_numAcceleratedRigidBodies; } //body.m_shapeType = shapeType; - - - body.m_invMass = mass? 1.f/mass : 0.f; - + + body.m_invMass = mass ? 1.f / mass : 0.f; + if (writeToGpu) { - m_data->m_bodyBufferGPU->copyFromHostPointer(&body,1,m_data->m_numAcceleratedRigidBodies); + m_data->m_bodyBufferGPU->copyFromHostPointer(&body, 1, m_data->m_numAcceleratedRigidBodies); } - - b3InertiaData& shapeInfo = m_data->m_inertiaBufferCPU->at(m_data->m_numAcceleratedRigidBodies); - - if (mass==0.f) - { - if (m_data->m_numAcceleratedRigidBodies==0) - m_static0Index = 0; - - shapeInfo.m_initInvInertia.setValue(0,0,0,0,0,0,0,0,0); - shapeInfo.m_invInertiaWorld.setValue(0,0,0,0,0,0,0,0,0); - } else - { - - b3Assert(body.m_collidableIdx>=0); - - //approximate using the aabb of the shape - - //Aabb aabb = (*m_data->m_shapePointers)[shapeIndex]->m_aabb; - b3Vector3 halfExtents = (aabbMax-aabbMin);//*0.5f;//fake larger inertia makes demos more stable ;-) - - b3Vector3 localInertia; - - float lx=2.f*halfExtents[0]; - float ly=2.f*halfExtents[1]; - float lz=2.f*halfExtents[2]; - - localInertia.setValue( (mass/12.0f) * (ly*ly + lz*lz), - (mass/12.0f) * (lx*lx + lz*lz), - (mass/12.0f) * (lx*lx + ly*ly)); - - b3Vector3 invLocalInertia; - invLocalInertia[0] = 1.f/localInertia[0]; - invLocalInertia[1] = 1.f/localInertia[1]; - invLocalInertia[2] = 1.f/localInertia[2]; - invLocalInertia[3] = 0.f; - - shapeInfo.m_initInvInertia.setValue( - invLocalInertia[0], 0, 0, - 0, invLocalInertia[1], 0, - 0, 0, invLocalInertia[2]); - b3Matrix3x3 m (body.m_quat); + b3InertiaData& shapeInfo = m_data->m_inertiaBufferCPU->at(m_data->m_numAcceleratedRigidBodies); + + if (mass == 0.f) + { + if (m_data->m_numAcceleratedRigidBodies == 0) + m_static0Index = 0; + + shapeInfo.m_initInvInertia.setValue(0, 0, 0, 0, 0, 0, 0, 0, 0); + shapeInfo.m_invInertiaWorld.setValue(0, 0, 0, 0, 0, 0, 0, 0, 0); + } + else + { + b3Assert(body.m_collidableIdx >= 0); + + //approximate using the aabb of the shape + + //Aabb aabb = (*m_data->m_shapePointers)[shapeIndex]->m_aabb; + b3Vector3 halfExtents = (aabbMax - aabbMin); //*0.5f;//fake larger inertia makes demos more stable ;-) + + b3Vector3 localInertia; + + float lx = 2.f * halfExtents[0]; + float ly = 2.f * halfExtents[1]; + float lz = 2.f * halfExtents[2]; + + localInertia.setValue((mass / 12.0f) * (ly * ly + lz * lz), + (mass / 12.0f) * (lx * lx + lz * lz), + (mass / 12.0f) * (lx * lx + ly * ly)); + + b3Vector3 invLocalInertia; + invLocalInertia[0] = 1.f / localInertia[0]; + invLocalInertia[1] = 1.f / localInertia[1]; + invLocalInertia[2] = 1.f / localInertia[2]; + invLocalInertia[3] = 0.f; + + shapeInfo.m_initInvInertia.setValue( + invLocalInertia[0], 0, 0, + 0, invLocalInertia[1], 0, + 0, 0, invLocalInertia[2]); + + b3Matrix3x3 m(body.m_quat); shapeInfo.m_invInertiaWorld = m.scaled(invLocalInertia) * m.transpose(); - } - + if (writeToGpu) - m_data->m_inertiaBufferGPU->copyFromHostPointer(&shapeInfo,1,m_data->m_numAcceleratedRigidBodies); - - - + m_data->m_inertiaBufferGPU->copyFromHostPointer(&shapeInfo, 1, m_data->m_numAcceleratedRigidBodies); + return m_data->m_numAcceleratedRigidBodies++; } @@ -999,15 +912,13 @@ int b3GpuNarrowPhase::getNumRigidBodies() const return m_data->m_numAcceleratedRigidBodies; } -void b3GpuNarrowPhase::writeAllBodiesToGpu() +void b3GpuNarrowPhase::writeAllBodiesToGpu() { - if (m_data->m_localShapeAABBCPU->size()) { m_data->m_localShapeAABBGPU->copyFromHost(*m_data->m_localShapeAABBCPU); } - - + m_data->m_gpuChildShapes->copyFromHost(m_data->m_cpuChildShapes); m_data->m_convexFacesGPU->copyFromHost(m_data->m_convexFaces); m_data->m_convexPolyhedraGPU->copyFromHost(m_data->m_convexPolyhedra); @@ -1018,25 +929,21 @@ void b3GpuNarrowPhase::writeAllBodiesToGpu() m_data->m_treeNodesGPU->copyFromHost(m_data->m_treeNodesCPU); m_data->m_subTreesGPU->copyFromHost(m_data->m_subTreesCPU); - m_data->m_bodyBufferGPU->resize(m_data->m_numAcceleratedRigidBodies); m_data->m_inertiaBufferGPU->resize(m_data->m_numAcceleratedRigidBodies); - + if (m_data->m_numAcceleratedRigidBodies) { - m_data->m_bodyBufferGPU->copyFromHostPointer(&m_data->m_bodyBufferCPU->at(0),m_data->m_numAcceleratedRigidBodies); - m_data->m_inertiaBufferGPU->copyFromHostPointer(&m_data->m_inertiaBufferCPU->at(0),m_data->m_numAcceleratedRigidBodies); + m_data->m_bodyBufferGPU->copyFromHostPointer(&m_data->m_bodyBufferCPU->at(0), m_data->m_numAcceleratedRigidBodies); + m_data->m_inertiaBufferGPU->copyFromHostPointer(&m_data->m_inertiaBufferCPU->at(0), m_data->m_numAcceleratedRigidBodies); } - if (m_data->m_collidablesCPU.size()) + if (m_data->m_collidablesCPU.size()) { m_data->m_collidablesGPU->copyFromHost(m_data->m_collidablesCPU); } - - } - -void b3GpuNarrowPhase::reset() +void b3GpuNarrowPhase::reset() { m_data->m_numAcceleratedShapes = 0; m_data->m_numAcceleratedRigidBodies = 0; @@ -1053,21 +960,19 @@ void b3GpuNarrowPhase::reset() m_data->m_treeNodesCPU.resize(0); m_data->m_subTreesCPU.resize(0); m_data->m_bvhInfoCPU.resize(0); - } - -void b3GpuNarrowPhase::readbackAllBodiesToCpu() +void b3GpuNarrowPhase::readbackAllBodiesToCpu() { - m_data->m_bodyBufferGPU->copyToHostPointer(&m_data->m_bodyBufferCPU->at(0),m_data->m_numAcceleratedRigidBodies); + m_data->m_bodyBufferGPU->copyToHostPointer(&m_data->m_bodyBufferCPU->at(0), m_data->m_numAcceleratedRigidBodies); } -void b3GpuNarrowPhase::setObjectTransformCpu(float* position, float* orientation , int bodyIndex) +void b3GpuNarrowPhase::setObjectTransformCpu(float* position, float* orientation, int bodyIndex) { - if (bodyIndex>=0 && bodyIndexm_bodyBufferCPU->size()) + if (bodyIndex >= 0 && bodyIndex < m_data->m_bodyBufferCPU->size()) { - m_data->m_bodyBufferCPU->at(bodyIndex).m_pos=b3MakeVector3(position[0],position[1],position[2]); - m_data->m_bodyBufferCPU->at(bodyIndex).m_quat.setValue(orientation[0],orientation[1],orientation[2],orientation[3]); + m_data->m_bodyBufferCPU->at(bodyIndex).m_pos = b3MakeVector3(position[0], position[1], position[2]); + m_data->m_bodyBufferCPU->at(bodyIndex).m_quat.setValue(orientation[0], orientation[1], orientation[2], orientation[3]); } else { @@ -1076,24 +981,25 @@ void b3GpuNarrowPhase::setObjectTransformCpu(float* position, float* orientation } void b3GpuNarrowPhase::setObjectVelocityCpu(float* linVel, float* angVel, int bodyIndex) { - if (bodyIndex>=0 && bodyIndexm_bodyBufferCPU->size()) + if (bodyIndex >= 0 && bodyIndex < m_data->m_bodyBufferCPU->size()) { - m_data->m_bodyBufferCPU->at(bodyIndex).m_linVel=b3MakeVector3(linVel[0],linVel[1],linVel[2]); - m_data->m_bodyBufferCPU->at(bodyIndex).m_angVel=b3MakeVector3(angVel[0],angVel[1],angVel[2]); - } else + m_data->m_bodyBufferCPU->at(bodyIndex).m_linVel = b3MakeVector3(linVel[0], linVel[1], linVel[2]); + m_data->m_bodyBufferCPU->at(bodyIndex).m_angVel = b3MakeVector3(angVel[0], angVel[1], angVel[2]); + } + else { b3Warning("setObjectVelocityCpu out of range.\n"); } } -bool b3GpuNarrowPhase::getObjectTransformFromCpu(float* position, float* orientation , int bodyIndex) const +bool b3GpuNarrowPhase::getObjectTransformFromCpu(float* position, float* orientation, int bodyIndex) const { - if (bodyIndex>=0 && bodyIndexm_bodyBufferCPU->size()) + if (bodyIndex >= 0 && bodyIndex < m_data->m_bodyBufferCPU->size()) { position[0] = m_data->m_bodyBufferCPU->at(bodyIndex).m_pos.x; position[1] = m_data->m_bodyBufferCPU->at(bodyIndex).m_pos.y; position[2] = m_data->m_bodyBufferCPU->at(bodyIndex).m_pos.z; - position[3] = 1.f;//or 1 + position[3] = 1.f; //or 1 orientation[0] = m_data->m_bodyBufferCPU->at(bodyIndex).m_quat.x; orientation[1] = m_data->m_bodyBufferCPU->at(bodyIndex).m_quat.y; diff --git a/src/Bullet3OpenCL/RigidBody/b3GpuNarrowPhase.h b/src/Bullet3OpenCL/RigidBody/b3GpuNarrowPhase.h index 05ff3fd09..21a68de34 100644 --- a/src/Bullet3OpenCL/RigidBody/b3GpuNarrowPhase.h +++ b/src/Bullet3OpenCL/RigidBody/b3GpuNarrowPhase.h @@ -9,11 +9,10 @@ class b3GpuNarrowPhase { protected: - - struct b3GpuNarrowPhaseInternalData* m_data; + struct b3GpuNarrowPhaseInternalData* m_data; int m_acceleratedCompanionShapeIndex; int m_planeBodyIndex; - int m_static0Index; + int m_static0Index; cl_context m_context; cl_device_id m_device; @@ -23,64 +22,58 @@ protected: int registerConcaveMeshShape(b3AlignedObjectArray* vertices, b3AlignedObjectArray* indices, b3Collidable& col, const float* scaling); public: - - - - b3GpuNarrowPhase(cl_context vtx, cl_device_id dev, cl_command_queue q, const struct b3Config& config); virtual ~b3GpuNarrowPhase(void); - int registerSphereShape(float radius); - int registerPlaneShape(const b3Vector3& planeNormal, float planeConstant); + int registerSphereShape(float radius); + int registerPlaneShape(const b3Vector3& planeNormal, float planeConstant); int registerCompoundShape(b3AlignedObjectArray* childShapes); int registerFace(const b3Vector3& faceNormal, float faceConstant); - - int registerConcaveMesh(b3AlignedObjectArray* vertices, b3AlignedObjectArray* indices,const float* scaling); - + + int registerConcaveMesh(b3AlignedObjectArray* vertices, b3AlignedObjectArray* indices, const float* scaling); + //do they need to be merged? - - int registerConvexHullShape(b3ConvexUtility* utilPtr); - int registerConvexHullShape(const float* vertices, int strideInBytes, int numVertices, const float* scaling); - int registerRigidBody(int collidableIndex, float mass, const float* position, const float* orientation, const float* aabbMin, const float* aabbMax,bool writeToGpu); - void setObjectTransform(const float* position, const float* orientation , int bodyIndex); + int registerConvexHullShape(b3ConvexUtility* utilPtr); + int registerConvexHullShape(const float* vertices, int strideInBytes, int numVertices, const float* scaling); - void writeAllBodiesToGpu(); - void reset(); - void readbackAllBodiesToCpu(); - bool getObjectTransformFromCpu(float* position, float* orientation , int bodyIndex) const; + int registerRigidBody(int collidableIndex, float mass, const float* position, const float* orientation, const float* aabbMin, const float* aabbMax, bool writeToGpu); + void setObjectTransform(const float* position, const float* orientation, int bodyIndex); - void setObjectTransformCpu(float* position, float* orientation , int bodyIndex); + void writeAllBodiesToGpu(); + void reset(); + void readbackAllBodiesToCpu(); + bool getObjectTransformFromCpu(float* position, float* orientation, int bodyIndex) const; + + void setObjectTransformCpu(float* position, float* orientation, int bodyIndex); void setObjectVelocityCpu(float* linVel, float* angVel, int bodyIndex); - virtual void computeContacts(cl_mem broadphasePairs, int numBroadphasePairs, cl_mem aabbsWorldSpace, int numObjects); - - cl_mem getBodiesGpu(); + cl_mem getBodiesGpu(); const struct b3RigidBodyData* getBodiesCpu() const; //struct b3RigidBodyData* getBodiesCpu(); - int getNumBodiesGpu() const; + int getNumBodiesGpu() const; - cl_mem getBodyInertiasGpu(); - int getNumBodyInertiasGpu() const; + cl_mem getBodyInertiasGpu(); + int getNumBodyInertiasGpu() const; - cl_mem getCollidablesGpu(); + cl_mem getCollidablesGpu(); const struct b3Collidable* getCollidablesCpu() const; - int getNumCollidablesGpu() const; + int getNumCollidablesGpu() const; const struct b3SapAabb* getLocalSpaceAabbsCpu() const; const struct b3Contact4* getContactsCPU() const; - cl_mem getContactsGpu(); - int getNumContactsGpu() const; + cl_mem getContactsGpu(); + int getNumContactsGpu() const; + + cl_mem getAabbLocalSpaceBufferGpu(); - cl_mem getAabbLocalSpaceBufferGpu(); - int getNumRigidBodies() const; int allocateCollidable(); @@ -92,18 +85,17 @@ public: b3Collidable& getCollidableCpu(int collidableIndex); const b3Collidable& getCollidableCpu(int collidableIndex) const; - const b3GpuNarrowPhaseInternalData* getInternalData() const + const b3GpuNarrowPhaseInternalData* getInternalData() const { - return m_data; + return m_data; } - b3GpuNarrowPhaseInternalData* getInternalData() + b3GpuNarrowPhaseInternalData* getInternalData() { - return m_data; + return m_data; } const struct b3SapAabb& getLocalSpaceAabb(int collidableIndex) const; }; -#endif //B3_GPU_NARROWPHASE_H - +#endif //B3_GPU_NARROWPHASE_H diff --git a/src/Bullet3OpenCL/RigidBody/b3GpuNarrowPhaseInternalData.h b/src/Bullet3OpenCL/RigidBody/b3GpuNarrowPhaseInternalData.h index 8a7f1ea85..716a5ea0f 100644 --- a/src/Bullet3OpenCL/RigidBody/b3GpuNarrowPhaseInternalData.h +++ b/src/Bullet3OpenCL/RigidBody/b3GpuNarrowPhaseInternalData.h @@ -20,57 +20,53 @@ #include "Bullet3Common/shared/b3Int4.h" #include "Bullet3Common/shared/b3Int2.h" - class b3ConvexUtility; struct b3GpuNarrowPhaseInternalData { b3AlignedObjectArray* m_convexData; - + b3AlignedObjectArray m_convexPolyhedra; b3AlignedObjectArray m_uniqueEdges; b3AlignedObjectArray m_convexVertices; b3AlignedObjectArray m_convexIndices; - + b3OpenCLArray* m_convexPolyhedraGPU; b3OpenCLArray* m_uniqueEdgesGPU; b3OpenCLArray* m_convexVerticesGPU; b3OpenCLArray* m_convexIndicesGPU; - - b3OpenCLArray* m_worldVertsB1GPU; - b3OpenCLArray* m_clippingFacesOutGPU; - b3OpenCLArray* m_worldNormalsAGPU; - b3OpenCLArray* m_worldVertsA1GPU; - b3OpenCLArray* m_worldVertsB2GPU; - + + b3OpenCLArray* m_worldVertsB1GPU; + b3OpenCLArray* m_clippingFacesOutGPU; + b3OpenCLArray* m_worldNormalsAGPU; + b3OpenCLArray* m_worldVertsA1GPU; + b3OpenCLArray* m_worldVertsB2GPU; + b3AlignedObjectArray m_cpuChildShapes; - b3OpenCLArray* m_gpuChildShapes; - + b3OpenCLArray* m_gpuChildShapes; + b3AlignedObjectArray m_convexFaces; b3OpenCLArray* m_convexFacesGPU; - - struct GpuSatCollision* m_gpuSatCollision; - - - b3OpenCLArray* m_triangleConvexPairs; - - + + struct GpuSatCollision* m_gpuSatCollision; + + b3OpenCLArray* m_triangleConvexPairs; + b3OpenCLArray* m_pBufContactBuffersGPU[2]; - int m_currentContactBuffer; + int m_currentContactBuffer; b3AlignedObjectArray* m_pBufContactOutCPU; - - + b3AlignedObjectArray* m_bodyBufferCPU; b3OpenCLArray* m_bodyBufferGPU; - - b3AlignedObjectArray* m_inertiaBufferCPU; - b3OpenCLArray* m_inertiaBufferGPU; - + + b3AlignedObjectArray* m_inertiaBufferCPU; + b3OpenCLArray* m_inertiaBufferGPU; + int m_numAcceleratedShapes; int m_numAcceleratedRigidBodies; - - b3AlignedObjectArray m_collidablesCPU; - b3OpenCLArray* m_collidablesGPU; + + b3AlignedObjectArray m_collidablesCPU; + b3OpenCLArray* m_collidablesGPU; b3OpenCLArray* m_localShapeAABBGPU; b3AlignedObjectArray* m_localShapeAABBCPU; @@ -78,18 +74,16 @@ struct b3GpuNarrowPhaseInternalData b3AlignedObjectArray m_bvhData; b3AlignedObjectArray m_meshInterfaces; - b3AlignedObjectArray m_treeNodesCPU; - b3AlignedObjectArray m_subTreesCPU; + b3AlignedObjectArray m_treeNodesCPU; + b3AlignedObjectArray m_subTreesCPU; - b3AlignedObjectArray m_bvhInfoCPU; - b3OpenCLArray* m_bvhInfoGPU; - - b3OpenCLArray* m_treeNodesGPU; - b3OpenCLArray* m_subTreesGPU; - + b3AlignedObjectArray m_bvhInfoCPU; + b3OpenCLArray* m_bvhInfoGPU; - b3Config m_config; - + b3OpenCLArray* m_treeNodesGPU; + b3OpenCLArray* m_subTreesGPU; + + b3Config m_config; }; -#endif //B3_GPU_NARROWPHASE_INTERNAL_DATA_H +#endif //B3_GPU_NARROWPHASE_INTERNAL_DATA_H diff --git a/src/Bullet3OpenCL/RigidBody/b3GpuPgsConstraintSolver.cpp b/src/Bullet3OpenCL/RigidBody/b3GpuPgsConstraintSolver.cpp index 0d3d50c54..bd9d6bb04 100644 --- a/src/Bullet3OpenCL/RigidBody/b3GpuPgsConstraintSolver.cpp +++ b/src/Bullet3OpenCL/RigidBody/b3GpuPgsConstraintSolver.cpp @@ -14,11 +14,10 @@ subject to the following restrictions: */ //Originally written by Erwin Coumans - bool useGpuInitSolverBodies = true; bool useGpuInfo1 = true; -bool useGpuInfo2= true; -bool useGpuSolveJointConstraintRows=true; +bool useGpuInfo2 = true; +bool useGpuSolveJointConstraintRows = true; bool useGpuWriteBackVelocities = true; bool gpuBreakConstraints = true; @@ -29,27 +28,25 @@ bool gpuBreakConstraints = true; #include "Bullet3Dynamics/ConstraintSolver/b3TypedConstraint.h" #include #include "Bullet3Common/b3AlignedObjectArray.h" -#include //for memset +#include //for memset #include "Bullet3Collision/NarrowPhaseCollision/b3Contact4.h" #include "Bullet3OpenCL/ParallelPrimitives/b3OpenCLArray.h" #include "Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h" #include "Bullet3OpenCL/ParallelPrimitives/b3PrefixScanCL.h" -#include "Bullet3OpenCL/RigidBody/kernels/jointSolver.h" //solveConstraintRowsCL +#include "Bullet3OpenCL/RigidBody/kernels/jointSolver.h" //solveConstraintRowsCL #include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h" #define B3_JOINT_SOLVER_PATH "src/Bullet3OpenCL/RigidBody/kernels/jointSolver.cl" - struct b3GpuPgsJacobiSolverInternalData { - cl_context m_context; cl_device_id m_device; cl_command_queue m_queue; - b3PrefixScanCL* m_prefixScan; + b3PrefixScanCL* m_prefixScan; cl_kernel m_solveJointConstraintRowsKernels; cl_kernel m_initSolverBodiesKernel; @@ -59,31 +56,27 @@ struct b3GpuPgsJacobiSolverInternalData cl_kernel m_writeBackVelocitiesKernel; cl_kernel m_breakViolatedConstraintsKernel; - b3OpenCLArray* m_gpuConstraintRowOffsets; + b3OpenCLArray* m_gpuConstraintRowOffsets; - b3OpenCLArray* m_gpuSolverBodies; - b3OpenCLArray* m_gpuBatchConstraints; - b3OpenCLArray* m_gpuConstraintRows; - b3OpenCLArray* m_gpuConstraintInfo1; + b3OpenCLArray* m_gpuSolverBodies; + b3OpenCLArray* m_gpuBatchConstraints; + b3OpenCLArray* m_gpuConstraintRows; + b3OpenCLArray* m_gpuConstraintInfo1; -// b3AlignedObjectArray m_cpuSolverBodies; - b3AlignedObjectArray m_cpuBatchConstraints; - b3AlignedObjectArray m_cpuConstraintRows; - b3AlignedObjectArray m_cpuConstraintInfo1; - b3AlignedObjectArray m_cpuConstraintRowOffsets; + // b3AlignedObjectArray m_cpuSolverBodies; + b3AlignedObjectArray m_cpuBatchConstraints; + b3AlignedObjectArray m_cpuConstraintRows; + b3AlignedObjectArray m_cpuConstraintInfo1; + b3AlignedObjectArray m_cpuConstraintRowOffsets; - b3AlignedObjectArray m_cpuBodies; - b3AlignedObjectArray m_cpuInertias; + b3AlignedObjectArray m_cpuBodies; + b3AlignedObjectArray m_cpuInertias; - b3AlignedObjectArray m_cpuConstraints; - b3AlignedObjectArray m_batchSizes; - - + b3AlignedObjectArray m_batchSizes; }; - /* static b3Transform getWorldTransform(b3RigidBodyData* rb) { @@ -100,12 +93,12 @@ static const b3Matrix3x3& getInvInertiaTensorWorld(b3InertiaData* inertia) */ -static const b3Vector3& getLinearVelocity(b3RigidBodyData* rb) +static const b3Vector3& getLinearVelocity(b3RigidBodyData* rb) { return rb->m_linVel; } -static const b3Vector3& getAngularVelocity(b3RigidBodyData* rb) +static const b3Vector3& getAngularVelocity(b3RigidBodyData* rb) { return rb->m_angVel; } @@ -114,12 +107,9 @@ b3Vector3 getVelocityInLocalPoint(b3RigidBodyData* rb, const b3Vector3& rel_pos) { //we also calculate lin/ang velocity for kinematic objects return getLinearVelocity(rb) + getAngularVelocity(rb).cross(rel_pos); - } - - -b3GpuPgsConstraintSolver::b3GpuPgsConstraintSolver (cl_context ctx, cl_device_id device, cl_command_queue queue,bool usePgs) +b3GpuPgsConstraintSolver::b3GpuPgsConstraintSolver(cl_context ctx, cl_device_id device, cl_command_queue queue, bool usePgs) { m_usePgs = usePgs; m_gpuData = new b3GpuPgsJacobiSolverInternalData(); @@ -127,45 +117,40 @@ b3GpuPgsConstraintSolver::b3GpuPgsConstraintSolver (cl_context ctx, cl_device_id m_gpuData->m_device = device; m_gpuData->m_queue = queue; - m_gpuData->m_prefixScan = new b3PrefixScanCL(ctx,device,queue); + m_gpuData->m_prefixScan = new b3PrefixScanCL(ctx, device, queue); - m_gpuData->m_gpuConstraintRowOffsets = new b3OpenCLArray(m_gpuData->m_context,m_gpuData->m_queue); + m_gpuData->m_gpuConstraintRowOffsets = new b3OpenCLArray(m_gpuData->m_context, m_gpuData->m_queue); - m_gpuData->m_gpuSolverBodies = new b3OpenCLArray(m_gpuData->m_context,m_gpuData->m_queue); - m_gpuData->m_gpuBatchConstraints = new b3OpenCLArray(m_gpuData->m_context,m_gpuData->m_queue); - m_gpuData->m_gpuConstraintRows = new b3OpenCLArray(m_gpuData->m_context,m_gpuData->m_queue); - m_gpuData->m_gpuConstraintInfo1 = new b3OpenCLArray(m_gpuData->m_context,m_gpuData->m_queue); - cl_int errNum=0; + m_gpuData->m_gpuSolverBodies = new b3OpenCLArray(m_gpuData->m_context, m_gpuData->m_queue); + m_gpuData->m_gpuBatchConstraints = new b3OpenCLArray(m_gpuData->m_context, m_gpuData->m_queue); + m_gpuData->m_gpuConstraintRows = new b3OpenCLArray(m_gpuData->m_context, m_gpuData->m_queue); + m_gpuData->m_gpuConstraintInfo1 = new b3OpenCLArray(m_gpuData->m_context, m_gpuData->m_queue); + cl_int errNum = 0; { - cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_gpuData->m_context,m_gpuData->m_device,solveConstraintRowsCL,&errNum,"",B3_JOINT_SOLVER_PATH); + cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_gpuData->m_context, m_gpuData->m_device, solveConstraintRowsCL, &errNum, "", B3_JOINT_SOLVER_PATH); //cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_gpuData->m_context,m_gpuData->m_device,0,&errNum,"",B3_JOINT_SOLVER_PATH,true); - b3Assert(errNum==CL_SUCCESS); - m_gpuData->m_solveJointConstraintRowsKernels = b3OpenCLUtils::compileCLKernelFromString(m_gpuData->m_context, m_gpuData->m_device,solveConstraintRowsCL, "solveJointConstraintRows",&errNum,prog); - b3Assert(errNum==CL_SUCCESS); - m_gpuData->m_initSolverBodiesKernel = b3OpenCLUtils::compileCLKernelFromString(m_gpuData->m_context,m_gpuData->m_device,solveConstraintRowsCL,"initSolverBodies",&errNum,prog); - b3Assert(errNum==CL_SUCCESS); - m_gpuData->m_getInfo1Kernel = b3OpenCLUtils::compileCLKernelFromString(m_gpuData->m_context,m_gpuData->m_device,solveConstraintRowsCL,"getInfo1Kernel",&errNum,prog); - b3Assert(errNum==CL_SUCCESS); - m_gpuData->m_initBatchConstraintsKernel = b3OpenCLUtils::compileCLKernelFromString(m_gpuData->m_context,m_gpuData->m_device,solveConstraintRowsCL,"initBatchConstraintsKernel",&errNum,prog); - b3Assert(errNum==CL_SUCCESS); - m_gpuData->m_getInfo2Kernel= b3OpenCLUtils::compileCLKernelFromString(m_gpuData->m_context,m_gpuData->m_device,solveConstraintRowsCL,"getInfo2Kernel",&errNum,prog); - b3Assert(errNum==CL_SUCCESS); - m_gpuData->m_writeBackVelocitiesKernel = b3OpenCLUtils::compileCLKernelFromString(m_gpuData->m_context,m_gpuData->m_device,solveConstraintRowsCL,"writeBackVelocitiesKernel",&errNum,prog); - b3Assert(errNum==CL_SUCCESS); - m_gpuData->m_breakViolatedConstraintsKernel = b3OpenCLUtils::compileCLKernelFromString(m_gpuData->m_context,m_gpuData->m_device,solveConstraintRowsCL,"breakViolatedConstraintsKernel",&errNum,prog); - b3Assert(errNum==CL_SUCCESS); - - - + b3Assert(errNum == CL_SUCCESS); + m_gpuData->m_solveJointConstraintRowsKernels = b3OpenCLUtils::compileCLKernelFromString(m_gpuData->m_context, m_gpuData->m_device, solveConstraintRowsCL, "solveJointConstraintRows", &errNum, prog); + b3Assert(errNum == CL_SUCCESS); + m_gpuData->m_initSolverBodiesKernel = b3OpenCLUtils::compileCLKernelFromString(m_gpuData->m_context, m_gpuData->m_device, solveConstraintRowsCL, "initSolverBodies", &errNum, prog); + b3Assert(errNum == CL_SUCCESS); + m_gpuData->m_getInfo1Kernel = b3OpenCLUtils::compileCLKernelFromString(m_gpuData->m_context, m_gpuData->m_device, solveConstraintRowsCL, "getInfo1Kernel", &errNum, prog); + b3Assert(errNum == CL_SUCCESS); + m_gpuData->m_initBatchConstraintsKernel = b3OpenCLUtils::compileCLKernelFromString(m_gpuData->m_context, m_gpuData->m_device, solveConstraintRowsCL, "initBatchConstraintsKernel", &errNum, prog); + b3Assert(errNum == CL_SUCCESS); + m_gpuData->m_getInfo2Kernel = b3OpenCLUtils::compileCLKernelFromString(m_gpuData->m_context, m_gpuData->m_device, solveConstraintRowsCL, "getInfo2Kernel", &errNum, prog); + b3Assert(errNum == CL_SUCCESS); + m_gpuData->m_writeBackVelocitiesKernel = b3OpenCLUtils::compileCLKernelFromString(m_gpuData->m_context, m_gpuData->m_device, solveConstraintRowsCL, "writeBackVelocitiesKernel", &errNum, prog); + b3Assert(errNum == CL_SUCCESS); + m_gpuData->m_breakViolatedConstraintsKernel = b3OpenCLUtils::compileCLKernelFromString(m_gpuData->m_context, m_gpuData->m_device, solveConstraintRowsCL, "breakViolatedConstraintsKernel", &errNum, prog); + b3Assert(errNum == CL_SUCCESS); clReleaseProgram(prog); } - - } -b3GpuPgsConstraintSolver::~b3GpuPgsConstraintSolver () +b3GpuPgsConstraintSolver::~b3GpuPgsConstraintSolver() { clReleaseKernel(m_gpuData->m_solveJointConstraintRowsKernels); clReleaseKernel(m_gpuData->m_initSolverBodiesKernel); @@ -195,16 +180,12 @@ struct b3BatchConstraint static b3AlignedObjectArray batchConstraints; - -void b3GpuPgsConstraintSolver::recomputeBatches() +void b3GpuPgsConstraintSolver::recomputeBatches() { m_gpuData->m_batchSizes.clear(); } - - - -b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlySetup(b3OpenCLArray* gpuBodies, b3OpenCLArray* gpuInertias, int numBodies, b3OpenCLArray* gpuConstraints,int numConstraints,const b3ContactSolverInfo& infoGlobal) +b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlySetup(b3OpenCLArray* gpuBodies, b3OpenCLArray* gpuInertias, int numBodies, b3OpenCLArray* gpuConstraints, int numConstraints, const b3ContactSolverInfo& infoGlobal) { B3_PROFILE("GPU solveGroupCacheFriendlySetup"); batchConstraints.resize(numConstraints); @@ -212,7 +193,6 @@ b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlySetup(b3OpenCLArraym_gpuBodies->resize(numBodies); m_gpuData->m_gpuBodies->copyFromHostPointer(bodies,numBodies); @@ -223,15 +203,13 @@ b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlySetup(b3OpenCLArraym_gpuSolverBodies->resize(numBodies); - m_tmpSolverBodyPool.resize(numBodies); { - if (useGpuInitSolverBodies) { B3_PROFILE("m_initSolverBodiesKernel"); - b3LauncherCL launcher(m_gpuData->m_queue,m_gpuData->m_initSolverBodiesKernel,"m_initSolverBodiesKernel"); + b3LauncherCL launcher(m_gpuData->m_queue, m_gpuData->m_initSolverBodiesKernel, "m_initSolverBodiesKernel"); launcher.setBuffer(m_gpuData->m_gpuSolverBodies->getBufferCL()); launcher.setBuffer(gpuBodies->getBufferCL()); launcher.setConst(numBodies); @@ -239,48 +217,44 @@ b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlySetup(b3OpenCLArraym_queue); // m_gpuData->m_gpuSolverBodies->copyToHost(m_tmpSolverBodyPool); - } else + } + else { gpuBodies->copyToHost(m_gpuData->m_cpuBodies); - for (int i=0;im_cpuBodies[i]; b3GpuSolverBody& solverBody = m_tmpSolverBodyPool[i]; - initSolverBody(i,&solverBody,&body); + initSolverBody(i, &solverBody, &body); solverBody.m_originalBodyIndex = i; } m_gpuData->m_gpuSolverBodies->copyFromHost(m_tmpSolverBodyPool); } } -// int totalBodies = 0; + // int totalBodies = 0; int totalNumRows = 0; //b3RigidBody* rb0=0,*rb1=0; //if (1) { { - - // int i; m_tmpConstraintSizesPool.resizeNoInitialize(numConstraints); // b3OpenCLArray gpuConstraints(m_gpuData->m_context,m_gpuData->m_queue); - if (useGpuInfo1) { B3_PROFILE("info1 and init batchConstraint"); - + m_gpuData->m_gpuConstraintInfo1->resize(numConstraints); - if (1) { B3_PROFILE("getInfo1Kernel"); - b3LauncherCL launcher(m_gpuData->m_queue,m_gpuData->m_getInfo1Kernel,"m_getInfo1Kernel"); + b3LauncherCL launcher(m_gpuData->m_queue, m_gpuData->m_getInfo1Kernel, "m_getInfo1Kernel"); launcher.setBuffer(m_gpuData->m_gpuConstraintInfo1->getBufferCL()); launcher.setBuffer(gpuConstraints->getBufferCL()); launcher.setConst(numConstraints); @@ -288,19 +262,19 @@ b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlySetup(b3OpenCLArraym_queue); } - if (m_gpuData->m_batchSizes.size()==0) + if (m_gpuData->m_batchSizes.size() == 0) { B3_PROFILE("initBatchConstraintsKernel"); m_gpuData->m_gpuConstraintRowOffsets->resize(numConstraints); - unsigned int total=0; - m_gpuData->m_prefixScan->execute(*m_gpuData->m_gpuConstraintInfo1,*m_gpuData->m_gpuConstraintRowOffsets,numConstraints,&total); - unsigned int lastElem = m_gpuData->m_gpuConstraintInfo1->at(numConstraints-1); - totalNumRows = total+lastElem; + unsigned int total = 0; + m_gpuData->m_prefixScan->execute(*m_gpuData->m_gpuConstraintInfo1, *m_gpuData->m_gpuConstraintRowOffsets, numConstraints, &total); + unsigned int lastElem = m_gpuData->m_gpuConstraintInfo1->at(numConstraints - 1); + totalNumRows = total + lastElem; { B3_PROFILE("init batch constraints"); - b3LauncherCL launcher(m_gpuData->m_queue,m_gpuData->m_initBatchConstraintsKernel,"m_initBatchConstraintsKernel"); + b3LauncherCL launcher(m_gpuData->m_queue, m_gpuData->m_initBatchConstraintsKernel, "m_initBatchConstraintsKernel"); launcher.setBuffer(m_gpuData->m_gpuConstraintInfo1->getBufferCL()); launcher.setBuffer(m_gpuData->m_gpuConstraintRowOffsets->getBufferCL()); launcher.setBuffer(m_gpuData->m_gpuBatchConstraints->getBufferCL()); @@ -313,79 +287,74 @@ b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlySetup(b3OpenCLArraym_gpuBatchConstraints->copyToHost(batchConstraints); } - } + } else { - totalNumRows = 0; + totalNumRows = 0; gpuConstraints->copyToHost(m_gpuData->m_cpuConstraints); //calculate the total number of contraint rows - for (int i=0;im_cpuConstraints[i].isEnabled()) { - - m_gpuData->m_cpuConstraints[i].getInfo1(&info1,&m_gpuData->m_cpuBodies[0]); - } else + m_gpuData->m_cpuConstraints[i].getInfo1(&info1, &m_gpuData->m_cpuBodies[0]); + } + else { info1 = 0; } - + totalNumRows += info1; } m_gpuData->m_gpuBatchConstraints->copyFromHost(batchConstraints); m_gpuData->m_gpuConstraintInfo1->copyFromHost(m_tmpConstraintSizesPool); - } m_tmpSolverNonContactConstraintPool.resizeNoInitialize(totalNumRows); m_gpuData->m_gpuConstraintRows->resize(totalNumRows); - + // b3GpuConstraintArray verify; if (useGpuInfo2) { { - B3_PROFILE("getInfo2Kernel"); - b3LauncherCL launcher(m_gpuData->m_queue,m_gpuData->m_getInfo2Kernel,"m_getInfo2Kernel"); - launcher.setBuffer(m_gpuData->m_gpuConstraintRows->getBufferCL()); - launcher.setBuffer(m_gpuData->m_gpuConstraintInfo1->getBufferCL()); - launcher.setBuffer(m_gpuData->m_gpuConstraintRowOffsets->getBufferCL()); - launcher.setBuffer(gpuConstraints->getBufferCL()); - launcher.setBuffer(m_gpuData->m_gpuBatchConstraints->getBufferCL()); - launcher.setBuffer(gpuBodies->getBufferCL()); - launcher.setBuffer(gpuInertias->getBufferCL()); - launcher.setBuffer(m_gpuData->m_gpuSolverBodies->getBufferCL()); - launcher.setConst(infoGlobal.m_timeStep); - launcher.setConst(infoGlobal.m_erp); - launcher.setConst(infoGlobal.m_globalCfm); - launcher.setConst(infoGlobal.m_damping); - launcher.setConst(infoGlobal.m_numIterations); - launcher.setConst(numConstraints); - launcher.launch1D(numConstraints); - clFinish(m_gpuData->m_queue); + B3_PROFILE("getInfo2Kernel"); + b3LauncherCL launcher(m_gpuData->m_queue, m_gpuData->m_getInfo2Kernel, "m_getInfo2Kernel"); + launcher.setBuffer(m_gpuData->m_gpuConstraintRows->getBufferCL()); + launcher.setBuffer(m_gpuData->m_gpuConstraintInfo1->getBufferCL()); + launcher.setBuffer(m_gpuData->m_gpuConstraintRowOffsets->getBufferCL()); + launcher.setBuffer(gpuConstraints->getBufferCL()); + launcher.setBuffer(m_gpuData->m_gpuBatchConstraints->getBufferCL()); + launcher.setBuffer(gpuBodies->getBufferCL()); + launcher.setBuffer(gpuInertias->getBufferCL()); + launcher.setBuffer(m_gpuData->m_gpuSolverBodies->getBufferCL()); + launcher.setConst(infoGlobal.m_timeStep); + launcher.setConst(infoGlobal.m_erp); + launcher.setConst(infoGlobal.m_globalCfm); + launcher.setConst(infoGlobal.m_damping); + launcher.setConst(infoGlobal.m_numIterations); + launcher.setConst(numConstraints); + launcher.launch1D(numConstraints); + clFinish(m_gpuData->m_queue); - if (m_gpuData->m_batchSizes.size()==0) - m_gpuData->m_gpuBatchConstraints->copyToHost(batchConstraints); - //m_gpuData->m_gpuConstraintRows->copyToHost(verify); - //m_gpuData->m_gpuConstraintRows->copyToHost(m_tmpSolverNonContactConstraintPool); - - - - } - } + if (m_gpuData->m_batchSizes.size() == 0) + m_gpuData->m_gpuBatchConstraints->copyToHost(batchConstraints); + //m_gpuData->m_gpuConstraintRows->copyToHost(verify); + //m_gpuData->m_gpuConstraintRows->copyToHost(m_tmpSolverNonContactConstraintPool); + } + } else { - gpuInertias->copyToHost(m_gpuData->m_cpuInertias); - ///setup the b3SolverConstraints - - for (int i=0;im_cpuConstraints[i]; - b3RigidBodyData& rbA = m_gpuData->m_cpuBodies[ constraint.getRigidBodyA()]; + b3RigidBodyData& rbA = m_gpuData->m_cpuBodies[constraint.getRigidBodyA()]; //b3RigidBody& rbA = constraint.getRigidBodyA(); - // b3RigidBody& rbB = constraint.getRigidBodyB(); - b3RigidBodyData& rbB = m_gpuData->m_cpuBodies[ constraint.getRigidBodyB()]; - - + // b3RigidBody& rbB = constraint.getRigidBodyB(); + b3RigidBodyData& rbB = m_gpuData->m_cpuBodies[constraint.getRigidBodyB()]; - int solverBodyIdA = constraint.getRigidBodyA();//getOrInitSolverBody(constraint.getRigidBodyA(),bodies,inertias); - int solverBodyIdB = constraint.getRigidBodyB();//getOrInitSolverBody(constraint.getRigidBodyB(),bodies,inertias); + int solverBodyIdA = constraint.getRigidBodyA(); //getOrInitSolverBody(constraint.getRigidBodyA(),bodies,inertias); + int solverBodyIdB = constraint.getRigidBodyB(); //getOrInitSolverBody(constraint.getRigidBodyB(),bodies,inertias); b3GpuSolverBody* bodyAPtr = &m_tmpSolverBodyPool[solverBodyIdA]; b3GpuSolverBody* bodyBPtr = &m_tmpSolverBodyPool[solverBodyIdB]; @@ -410,7 +377,8 @@ b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlySetup(b3OpenCLArraygetOverrideNumSolverIterations() > 0 ? constraint->getOverrideNumSolverIterations() : infoGlobal.m_numIterations; - if (overrideNumSolverIterations>m_maxOverrideNumSolverIterations) + int overrideNumSolverIterations = 0; //constraint->getOverrideNumSolverIterations() > 0 ? constraint->getOverrideNumSolverIterations() : infoGlobal.m_numIterations; + if (overrideNumSolverIterations > m_maxOverrideNumSolverIterations) m_maxOverrideNumSolverIterations = overrideNumSolverIterations; - int j; - for ( j=0;jinternalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f); - bodyAPtr->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f); - bodyAPtr->internalGetPushVelocity().setValue(0.f,0.f,0.f); - bodyAPtr->internalGetTurnVelocity().setValue(0.f,0.f,0.f); - bodyBPtr->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f); - bodyBPtr->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f); - bodyBPtr->internalGetPushVelocity().setValue(0.f,0.f,0.f); - bodyBPtr->internalGetTurnVelocity().setValue(0.f,0.f,0.f); - + bodyAPtr->internalGetDeltaLinearVelocity().setValue(0.f, 0.f, 0.f); + bodyAPtr->internalGetDeltaAngularVelocity().setValue(0.f, 0.f, 0.f); + bodyAPtr->internalGetPushVelocity().setValue(0.f, 0.f, 0.f); + bodyAPtr->internalGetTurnVelocity().setValue(0.f, 0.f, 0.f); + bodyBPtr->internalGetDeltaLinearVelocity().setValue(0.f, 0.f, 0.f); + bodyBPtr->internalGetDeltaAngularVelocity().setValue(0.f, 0.f, 0.f); + bodyBPtr->internalGetPushVelocity().setValue(0.f, 0.f, 0.f); + bodyBPtr->internalGetTurnVelocity().setValue(0.f, 0.f, 0.f); b3GpuConstraintInfo2 info2; - info2.fps = 1.f/infoGlobal.m_timeStep; + info2.fps = 1.f / infoGlobal.m_timeStep; info2.erp = infoGlobal.m_erp; info2.m_J1linearAxis = currentConstraintRow->m_contactNormal; info2.m_J1angularAxis = currentConstraintRow->m_relpos1CrossNormal; info2.m_J2linearAxis = 0; info2.m_J2angularAxis = currentConstraintRow->m_relpos2CrossNormal; - info2.rowskip = sizeof(b3GpuSolverConstraint)/sizeof(b3Scalar);//check this + info2.rowskip = sizeof(b3GpuSolverConstraint) / sizeof(b3Scalar); //check this ///the size of b3GpuSolverConstraint needs be a multiple of b3Scalar - b3Assert(info2.rowskip*sizeof(b3Scalar)== sizeof(b3GpuSolverConstraint)); + b3Assert(info2.rowskip * sizeof(b3Scalar) == sizeof(b3GpuSolverConstraint)); info2.m_constraintError = ¤tConstraintRow->m_rhs; currentConstraintRow->m_cfm = infoGlobal.m_globalCfm; info2.m_damping = infoGlobal.m_damping; @@ -494,47 +460,45 @@ b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlySetup(b3OpenCLArraym_lowerLimit; info2.m_upperLimit = ¤tConstraintRow->m_upperLimit; info2.m_numIterations = infoGlobal.m_numIterations; - m_gpuData->m_cpuConstraints[i].getInfo2(&info2,&m_gpuData->m_cpuBodies[0]); + m_gpuData->m_cpuConstraints[i].getInfo2(&info2, &m_gpuData->m_cpuBodies[0]); ///finalize the constraint setup - for ( j=0;j=m_gpuData->m_cpuConstraints[i].getBreakingImpulseThreshold()) + if (solverConstraint.m_upperLimit >= m_gpuData->m_cpuConstraints[i].getBreakingImpulseThreshold()) { solverConstraint.m_upperLimit = m_gpuData->m_cpuConstraints[i].getBreakingImpulseThreshold(); } - if (solverConstraint.m_lowerLimit<=-m_gpuData->m_cpuConstraints[i].getBreakingImpulseThreshold()) + if (solverConstraint.m_lowerLimit <= -m_gpuData->m_cpuConstraints[i].getBreakingImpulseThreshold()) { solverConstraint.m_lowerLimit = -m_gpuData->m_cpuConstraints[i].getBreakingImpulseThreshold(); } - // solverConstraint.m_originalContactPoint = constraint; - - b3Matrix3x3& invInertiaWorldA= m_gpuData->m_cpuInertias[constraint.getRigidBodyA()].m_invInertiaWorld; - { + // solverConstraint.m_originalContactPoint = constraint; + b3Matrix3x3& invInertiaWorldA = m_gpuData->m_cpuInertias[constraint.getRigidBodyA()].m_invInertiaWorld; + { //b3Vector3 angularFactorA(1,1,1); const b3Vector3& ftorqueAxis1 = solverConstraint.m_relpos1CrossNormal; - solverConstraint.m_angularComponentA = invInertiaWorldA*ftorqueAxis1;//*angularFactorA; + solverConstraint.m_angularComponentA = invInertiaWorldA * ftorqueAxis1; //*angularFactorA; } - - b3Matrix3x3& invInertiaWorldB= m_gpuData->m_cpuInertias[constraint.getRigidBodyB()].m_invInertiaWorld; - { + b3Matrix3x3& invInertiaWorldB = m_gpuData->m_cpuInertias[constraint.getRigidBodyB()].m_invInertiaWorld; + { const b3Vector3& ftorqueAxis2 = solverConstraint.m_relpos2CrossNormal; - solverConstraint.m_angularComponentB = invInertiaWorldB*ftorqueAxis2;//*constraint.getRigidBodyB().getAngularFactor(); + solverConstraint.m_angularComponentB = invInertiaWorldB * ftorqueAxis2; //*constraint.getRigidBodyB().getAngularFactor(); } { //it is ok to use solverConstraint.m_contactNormal instead of -solverConstraint.m_contactNormal //because it gets multiplied iMJlB - b3Vector3 iMJlA = solverConstraint.m_contactNormal*rbA.m_invMass; - b3Vector3 iMJaA = invInertiaWorldA*solverConstraint.m_relpos1CrossNormal; - b3Vector3 iMJlB = solverConstraint.m_contactNormal*rbB.m_invMass;//sign of normal? - b3Vector3 iMJaB = invInertiaWorldB*solverConstraint.m_relpos2CrossNormal; + b3Vector3 iMJlA = solverConstraint.m_contactNormal * rbA.m_invMass; + b3Vector3 iMJaA = invInertiaWorldA * solverConstraint.m_relpos1CrossNormal; + b3Vector3 iMJlB = solverConstraint.m_contactNormal * rbB.m_invMass; //sign of normal? + b3Vector3 iMJaB = invInertiaWorldB * solverConstraint.m_relpos2CrossNormal; b3Scalar sum = iMJlA.dot(solverConstraint.m_contactNormal); sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal); @@ -542,10 +506,9 @@ b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlySetup(b3OpenCLArray B3_EPSILON); - solverConstraint.m_jacDiagABInv = fsum>B3_EPSILON?b3Scalar(1.)/sum : 0.f; + solverConstraint.m_jacDiagABInv = fsum > B3_EPSILON ? b3Scalar(1.) / sum : 0.f; } - ///fix rhs ///todo: add force/torque accelerators { @@ -553,94 +516,80 @@ b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlySetup(b3OpenCLArraym_gpuConstraintRows->copyFromHost(m_tmpSolverNonContactConstraintPool); m_gpuData->m_gpuConstraintInfo1->copyFromHost(m_tmpConstraintSizesPool); - if (m_gpuData->m_batchSizes.size()==0) + if (m_gpuData->m_batchSizes.size() == 0) m_gpuData->m_gpuBatchConstraints->copyFromHost(batchConstraints); else m_gpuData->m_gpuBatchConstraints->copyToHost(batchConstraints); m_gpuData->m_gpuSolverBodies->copyFromHost(m_tmpSolverBodyPool); - - - }//end useGpuInfo2 - - + } //end useGpuInfo2 } #ifdef B3_SUPPORT_CONTACT_CONSTRAINTS { int i; - for (i=0;im_deltaLinearVelocity += linearComponent*impulseMagnitude*body->m_linearFactor; - body->m_deltaAngularVelocity += angularComponent*(impulseMagnitude*body->m_angularFactor); + body->m_deltaLinearVelocity += linearComponent * impulseMagnitude * body->m_linearFactor; + body->m_deltaAngularVelocity += angularComponent * (impulseMagnitude * body->m_angularFactor); } - -void resolveSingleConstraintRowGeneric2( b3GpuSolverBody* body1, b3GpuSolverBody* body2, b3GpuSolverConstraint* c) +void resolveSingleConstraintRowGeneric2(b3GpuSolverBody* body1, b3GpuSolverBody* body2, b3GpuSolverConstraint* c) { - float deltaImpulse = c->m_rhs-b3Scalar(c->m_appliedImpulse)*c->m_cfm; - float deltaVel1Dotn = b3Dot(c->m_contactNormal,body1->m_deltaLinearVelocity) + b3Dot(c->m_relpos1CrossNormal,body1->m_deltaAngularVelocity); - float deltaVel2Dotn = -b3Dot(c->m_contactNormal,body2->m_deltaLinearVelocity) + b3Dot(c->m_relpos2CrossNormal,body2->m_deltaAngularVelocity); + float deltaImpulse = c->m_rhs - b3Scalar(c->m_appliedImpulse) * c->m_cfm; + float deltaVel1Dotn = b3Dot(c->m_contactNormal, body1->m_deltaLinearVelocity) + b3Dot(c->m_relpos1CrossNormal, body1->m_deltaAngularVelocity); + float deltaVel2Dotn = -b3Dot(c->m_contactNormal, body2->m_deltaLinearVelocity) + b3Dot(c->m_relpos2CrossNormal, body2->m_deltaAngularVelocity); - deltaImpulse -= deltaVel1Dotn*c->m_jacDiagABInv; - deltaImpulse -= deltaVel2Dotn*c->m_jacDiagABInv; + deltaImpulse -= deltaVel1Dotn * c->m_jacDiagABInv; + deltaImpulse -= deltaVel2Dotn * c->m_jacDiagABInv; float sum = b3Scalar(c->m_appliedImpulse) + deltaImpulse; if (sum < c->m_lowerLimit) { - deltaImpulse = c->m_lowerLimit-b3Scalar(c->m_appliedImpulse); + deltaImpulse = c->m_lowerLimit - b3Scalar(c->m_appliedImpulse); c->m_appliedImpulse = c->m_lowerLimit; } - else if (sum > c->m_upperLimit) + else if (sum > c->m_upperLimit) { - deltaImpulse = c->m_upperLimit-b3Scalar(c->m_appliedImpulse); + deltaImpulse = c->m_upperLimit - b3Scalar(c->m_appliedImpulse); c->m_appliedImpulse = c->m_upperLimit; } else @@ -648,64 +597,56 @@ void resolveSingleConstraintRowGeneric2( b3GpuSolverBody* body1, b3GpuSolverBod c->m_appliedImpulse = sum; } - internalApplyImpulse(body1,c->m_contactNormal*body1->m_invMass,c->m_angularComponentA,deltaImpulse); - internalApplyImpulse(body2,-c->m_contactNormal*body2->m_invMass,c->m_angularComponentB,deltaImpulse); - + internalApplyImpulse(body1, c->m_contactNormal * body1->m_invMass, c->m_angularComponentA, deltaImpulse); + internalApplyImpulse(body2, -c->m_contactNormal * body2->m_invMass, c->m_angularComponentB, deltaImpulse); } - - -void b3GpuPgsConstraintSolver::initSolverBody(int bodyIndex, b3GpuSolverBody* solverBody, b3RigidBodyData* rb) +void b3GpuPgsConstraintSolver::initSolverBody(int bodyIndex, b3GpuSolverBody* solverBody, b3RigidBodyData* rb) { - - solverBody->m_deltaLinearVelocity.setValue(0.f,0.f,0.f); - solverBody->m_deltaAngularVelocity.setValue(0.f,0.f,0.f); - solverBody->internalGetPushVelocity().setValue(0.f,0.f,0.f); - solverBody->internalGetTurnVelocity().setValue(0.f,0.f,0.f); + solverBody->m_deltaLinearVelocity.setValue(0.f, 0.f, 0.f); + solverBody->m_deltaAngularVelocity.setValue(0.f, 0.f, 0.f); + solverBody->internalGetPushVelocity().setValue(0.f, 0.f, 0.f); + solverBody->internalGetTurnVelocity().setValue(0.f, 0.f, 0.f); b3Assert(rb); -// solverBody->m_worldTransform = getWorldTransform(rb); - solverBody->internalSetInvMass(b3MakeVector3(rb->m_invMass,rb->m_invMass,rb->m_invMass)); + // solverBody->m_worldTransform = getWorldTransform(rb); + solverBody->internalSetInvMass(b3MakeVector3(rb->m_invMass, rb->m_invMass, rb->m_invMass)); solverBody->m_originalBodyIndex = bodyIndex; - solverBody->m_angularFactor = b3MakeVector3(1,1,1); - solverBody->m_linearFactor = b3MakeVector3(1,1,1); + solverBody->m_angularFactor = b3MakeVector3(1, 1, 1); + solverBody->m_linearFactor = b3MakeVector3(1, 1, 1); solverBody->m_linearVelocity = getLinearVelocity(rb); solverBody->m_angularVelocity = getAngularVelocity(rb); } - -void b3GpuPgsConstraintSolver::averageVelocities() +void b3GpuPgsConstraintSolver::averageVelocities() { } - -b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlyIterations(b3OpenCLArray* gpuConstraints1,int numConstraints,const b3ContactSolverInfo& infoGlobal) +b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlyIterations(b3OpenCLArray* gpuConstraints1, int numConstraints, const b3ContactSolverInfo& infoGlobal) { //only create the batches once. //@todo: incrementally update batches when constraints are added/activated and/or removed/deactivated B3_PROFILE("GpuSolveGroupCacheFriendlyIterations"); - bool createBatches = m_gpuData->m_batchSizes.size()==0; + bool createBatches = m_gpuData->m_batchSizes.size() == 0; { - if (createBatches) { - m_gpuData->m_batchSizes.resize(0); { m_gpuData->m_gpuBatchConstraints->copyToHost(batchConstraints); B3_PROFILE("batch joints"); - b3Assert(batchConstraints.size()==numConstraints); - int simdWidth =numConstraints+1; + b3Assert(batchConstraints.size() == numConstraints); + int simdWidth = numConstraints + 1; int numBodies = m_tmpSolverBodyPool.size(); - sortConstraintByBatch3( &batchConstraints[0], numConstraints, simdWidth , m_staticIdx, numBodies); + sortConstraintByBatch3(&batchConstraints[0], numConstraints, simdWidth, m_staticIdx, numBodies); m_gpuData->m_gpuBatchConstraints->copyFromHost(batchConstraints); - } - } else + } + else { /*b3AlignedObjectArray cpuCheckBatches; m_gpuData->m_gpuBatchConstraints->copyToHost(cpuCheckBatches); @@ -715,12 +656,11 @@ b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlyIterations(b3OpenCLArr //>copyFromHost(batchConstraints); } int maxIterations = infoGlobal.m_numIterations; - + bool useBatching = true; - if (useBatching ) + if (useBatching) { - if (!useGpuSolveJointConstraintRows) { B3_PROFILE("copy to host"); @@ -730,24 +670,21 @@ b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlyIterations(b3OpenCLArr m_gpuData->m_gpuConstraintInfo1->copyToHost(m_gpuData->m_cpuConstraintInfo1); m_gpuData->m_gpuConstraintRowOffsets->copyToHost(m_gpuData->m_cpuConstraintRowOffsets); gpuConstraints1->copyToHost(m_gpuData->m_cpuConstraints); - } - for ( int iteration = 0 ; iteration< maxIterations ; iteration++) + for (int iteration = 0; iteration < maxIterations; iteration++) { - int batchOffset = 0; - int constraintOffset=0; + int constraintOffset = 0; int numBatches = m_gpuData->m_batchSizes.size(); - for (int bb=0;bbm_batchSizes[bb]; - if (useGpuSolveJointConstraintRows) { B3_PROFILE("solveJointConstraintRowsKernels"); - + /* __kernel void solveJointConstraintRows(__global b3GpuSolverBody* solverBodies, __global b3BatchConstraint* batchConstraints, @@ -758,53 +695,48 @@ b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlyIterations(b3OpenCLArr int batchOffset, int numConstraintsInBatch*/ - - b3LauncherCL launcher(m_gpuData->m_queue,m_gpuData->m_solveJointConstraintRowsKernels,"m_solveJointConstraintRowsKernels"); + b3LauncherCL launcher(m_gpuData->m_queue, m_gpuData->m_solveJointConstraintRowsKernels, "m_solveJointConstraintRowsKernels"); launcher.setBuffer(m_gpuData->m_gpuSolverBodies->getBufferCL()); launcher.setBuffer(m_gpuData->m_gpuBatchConstraints->getBufferCL()); launcher.setBuffer(m_gpuData->m_gpuConstraintRows->getBufferCL()); launcher.setBuffer(m_gpuData->m_gpuConstraintInfo1->getBufferCL()); launcher.setBuffer(m_gpuData->m_gpuConstraintRowOffsets->getBufferCL()); - launcher.setBuffer(gpuConstraints1->getBufferCL());//to detect disabled constraints + launcher.setBuffer(gpuConstraints1->getBufferCL()); //to detect disabled constraints launcher.setConst(batchOffset); launcher.setConst(numConstraintsInBatch); launcher.launch1D(numConstraintsInBatch); - - - } else//useGpu + } + else //useGpu { - - - - for (int b=0;bm_cpuConstraints[c.m_originalConstraintIndex]; - if (constraint->m_flags&B3_CONSTRAINT_FLAG_ENABLED) + if (constraint->m_flags & B3_CONSTRAINT_FLAG_ENABLED) { int numConstraintRows = m_gpuData->m_cpuConstraintInfo1[c.m_originalConstraintIndex]; int constraintOffset = m_gpuData->m_cpuConstraintRowOffsets[c.m_originalConstraintIndex]; - - for (int jj=0;jjm_queue); return 0.f; } - - - static b3AlignedObjectArray bodyUsed; static b3AlignedObjectArray curUsed; - - -inline int b3GpuPgsConstraintSolver::sortConstraintByBatch3( b3BatchConstraint* cs, int numConstraints, int simdWidth , int staticIdx, int numBodies) +inline int b3GpuPgsConstraintSolver::sortConstraintByBatch3(b3BatchConstraint* cs, int numConstraints, int simdWidth, int staticIdx, int numBodies) { //int sz = sizeof(b3BatchConstraint); B3_PROFILE("sortConstraintByBatch3"); - + static int maxSwaps = 0; int numSwaps = 0; - curUsed.resize(2*simdWidth); + curUsed.resize(2 * simdWidth); static int maxNumConstraints = 0; - if (maxNumConstraintsm_batchSizes.push_back(nCurrentBatch); - batchIdx ++; + batchIdx++; } } - + #if defined(_DEBUG) - // debugPrintf( "nBatches: %d\n", batchIdx ); - for(int i=0; i* gpuBodies, b3OpenCLArray* gpuInertias, - int numBodies, b3OpenCLArray* gpuConstraints,int numConstraints, const b3ContactSolverInfo& infoGlobal) +b3Scalar b3GpuPgsConstraintSolver::solveGroup(b3OpenCLArray* gpuBodies, b3OpenCLArray* gpuInertias, + int numBodies, b3OpenCLArray* gpuConstraints, int numConstraints, const b3ContactSolverInfo& infoGlobal) { - B3_PROFILE("solveJoints"); //you need to provide at least some bodies - - solveGroupCacheFriendlySetup( gpuBodies, gpuInertias,numBodies,gpuConstraints, numConstraints,infoGlobal); - solveGroupCacheFriendlyIterations(gpuConstraints, numConstraints,infoGlobal); + solveGroupCacheFriendlySetup(gpuBodies, gpuInertias, numBodies, gpuConstraints, numConstraints, infoGlobal); + + solveGroupCacheFriendlyIterations(gpuConstraints, numConstraints, infoGlobal); + + solveGroupCacheFriendlyFinish(gpuBodies, gpuInertias, numBodies, gpuConstraints, numConstraints, infoGlobal); - solveGroupCacheFriendlyFinish(gpuBodies, gpuInertias,numBodies, gpuConstraints, numConstraints, infoGlobal); - return 0.f; } -void b3GpuPgsConstraintSolver::solveJoints(int numBodies, b3OpenCLArray* gpuBodies, b3OpenCLArray* gpuInertias, - int numConstraints, b3OpenCLArray* gpuConstraints) +void b3GpuPgsConstraintSolver::solveJoints(int numBodies, b3OpenCLArray* gpuBodies, b3OpenCLArray* gpuInertias, + int numConstraints, b3OpenCLArray* gpuConstraints) { b3ContactSolverInfo infoGlobal; infoGlobal.m_splitImpulse = false; - infoGlobal.m_timeStep = 1.f/60.f; - infoGlobal.m_numIterations = 4;//4; -// infoGlobal.m_solverMode|=B3_SOLVER_USE_2_FRICTION_DIRECTIONS|B3_SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS|B3_SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION; + infoGlobal.m_timeStep = 1.f / 60.f; + infoGlobal.m_numIterations = 4; //4; + // infoGlobal.m_solverMode|=B3_SOLVER_USE_2_FRICTION_DIRECTIONS|B3_SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS|B3_SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION; //infoGlobal.m_solverMode|=B3_SOLVER_USE_2_FRICTION_DIRECTIONS|B3_SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS; - infoGlobal.m_solverMode|=B3_SOLVER_USE_2_FRICTION_DIRECTIONS; + infoGlobal.m_solverMode |= B3_SOLVER_USE_2_FRICTION_DIRECTIONS; //if (infoGlobal.m_solverMode & B3_SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS) //if ((infoGlobal.m_solverMode & B3_SOLVER_USE_2_FRICTION_DIRECTIONS) && (infoGlobal.m_solverMode & B3_SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION)) - - - solveGroup(gpuBodies,gpuInertias,numBodies,gpuConstraints,numConstraints,infoGlobal); + solveGroup(gpuBodies, gpuInertias, numBodies, gpuConstraints, numConstraints, infoGlobal); } //b3AlignedObjectArray testBodies; - -b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlyFinish(b3OpenCLArray* gpuBodies,b3OpenCLArray* gpuInertias,int numBodies,b3OpenCLArray* gpuConstraints,int numConstraints,const b3ContactSolverInfo& infoGlobal) +b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlyFinish(b3OpenCLArray* gpuBodies, b3OpenCLArray* gpuInertias, int numBodies, b3OpenCLArray* gpuConstraints, int numConstraints, const b3ContactSolverInfo& infoGlobal) { B3_PROFILE("solveGroupCacheFriendlyFinish"); -// int numPoolConstraints = m_tmpSolverContactConstraintPool.size(); -// int i,j; - + // int numPoolConstraints = m_tmpSolverContactConstraintPool.size(); + // int i,j; { if (gpuBreakConstraints) { B3_PROFILE("breakViolatedConstraintsKernel"); - b3LauncherCL launcher(m_gpuData->m_queue,m_gpuData->m_breakViolatedConstraintsKernel,"m_breakViolatedConstraintsKernel"); + b3LauncherCL launcher(m_gpuData->m_queue, m_gpuData->m_breakViolatedConstraintsKernel, "m_breakViolatedConstraintsKernel"); launcher.setBuffer(gpuConstraints->getBufferCL()); launcher.setBuffer(m_gpuData->m_gpuConstraintInfo1->getBufferCL()); launcher.setBuffer(m_gpuData->m_gpuConstraintRowOffsets->getBufferCL()); launcher.setBuffer(m_gpuData->m_gpuConstraintRows->getBufferCL()); launcher.setConst(numConstraints); launcher.launch1D(numConstraints); - } else + } + else { gpuConstraints->copyToHost(m_gpuData->m_cpuConstraints); m_gpuData->m_gpuBatchConstraints->copyToHost(m_gpuData->m_cpuBatchConstraints); @@ -1056,31 +970,28 @@ b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlyFinish(b3OpenCLArraym_gpuConstraintInfo1->copyToHost(m_gpuData->m_cpuConstraintInfo1); m_gpuData->m_gpuConstraintRowOffsets->copyToHost(m_gpuData->m_cpuConstraintRowOffsets); - for (int cid=0;cidm_cpuConstraintRowOffsets[originalConstraintIndex]; int numRows = m_gpuData->m_cpuConstraintInfo1[originalConstraintIndex]; if (numRows) { - - // printf("cid=%d, breakingThreshold =%f\n",cid,breakingThreshold); - for (int i=0;im_cpuConstraintRows[rowIndex].m_originalConstraintIndex; float breakingThreshold = m_gpuData->m_cpuConstraints[orgConstraintIndex].m_breakingImpulseThreshold; - // printf("rows[%d].m_appliedImpulse=%f\n",rowIndex,rows[rowIndex].m_appliedImpulse); + // printf("rows[%d].m_appliedImpulse=%f\n",rowIndex,rows[rowIndex].m_appliedImpulse); if (b3Fabs(m_gpuData->m_cpuConstraintRows[rowIndex].m_appliedImpulse) >= breakingThreshold) { - - m_gpuData->m_cpuConstraints[orgConstraintIndex].m_flags =0;//&= ~B3_CONSTRAINT_FLAG_ENABLED; + m_gpuData->m_cpuConstraints[orgConstraintIndex].m_flags = 0; //&= ~B3_CONSTRAINT_FLAG_ENABLED; } } } } - gpuConstraints->copyFromHost(m_gpuData->m_cpuConstraints); } } @@ -1090,28 +1001,27 @@ b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlyFinish(b3OpenCLArraym_queue,m_gpuData->m_writeBackVelocitiesKernel,"m_writeBackVelocitiesKernel"); + b3LauncherCL launcher(m_gpuData->m_queue, m_gpuData->m_writeBackVelocitiesKernel, "m_writeBackVelocitiesKernel"); launcher.setBuffer(gpuBodies->getBufferCL()); launcher.setBuffer(m_gpuData->m_gpuSolverBodies->getBufferCL()); launcher.setConst(numBodies); launcher.launch1D(numBodies); clFinish(m_gpuData->m_queue); -// m_gpuData->m_gpuSolverBodies->copyToHost(m_tmpSolverBodyPool); -// m_gpuData->m_gpuBodies->copyToHostPointer(bodies,numBodies); + // m_gpuData->m_gpuSolverBodies->copyToHost(m_tmpSolverBodyPool); + // m_gpuData->m_gpuBodies->copyToHostPointer(bodies,numBodies); //m_gpuData->m_gpuBodies->copyToHost(testBodies); - - } + } else { B3_PROFILE("CPU write back velocities and transforms"); m_gpuData->m_gpuSolverBodies->copyToHost(m_tmpSolverBodyPool); gpuBodies->copyToHost(m_gpuData->m_cpuBodies); - for ( int i=0;im_cpuBodies[bodyIndex]; if (body->m_invMass) @@ -1125,11 +1035,12 @@ b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlyFinish(b3OpenCLArraym_linVel = m_tmpSolverBodyPool[i].m_linearVelocity; body->m_angVel = m_tmpSolverBodyPool[i].m_angularVelocity; - } else + } + else { b3Assert(0); } - /* + /* if (infoGlobal.m_splitImpulse) { body->m_pos = m_tmpSolverBodyPool[i].m_worldTransform.getOrigin(); @@ -1139,10 +1050,9 @@ b3Scalar b3GpuPgsConstraintSolver::solveGroupCacheFriendlyFinish(b3OpenCLArraycopyFromHost(m_gpuData->m_cpuBodies); - } } diff --git a/src/Bullet3OpenCL/RigidBody/b3GpuPgsConstraintSolver.h b/src/Bullet3OpenCL/RigidBody/b3GpuPgsConstraintSolver.h index ec0e3f73d..00bc544f0 100644 --- a/src/Bullet3OpenCL/RigidBody/b3GpuPgsConstraintSolver.h +++ b/src/Bullet3OpenCL/RigidBody/b3GpuPgsConstraintSolver.h @@ -19,7 +19,6 @@ subject to the following restrictions: struct b3Contact4; struct b3ContactPoint; - class b3Dispatcher; #include "Bullet3Dynamics/ConstraintSolver/b3TypedConstraint.h" @@ -38,41 +37,40 @@ class b3GpuPgsConstraintSolver protected: int m_staticIdx; struct b3GpuPgsJacobiSolverInternalData* m_gpuData; - protected: - b3AlignedObjectArray m_tmpSolverBodyPool; - b3GpuConstraintArray m_tmpSolverContactConstraintPool; - b3GpuConstraintArray m_tmpSolverNonContactConstraintPool; - b3GpuConstraintArray m_tmpSolverContactFrictionConstraintPool; - b3GpuConstraintArray m_tmpSolverContactRollingFrictionConstraintPool; + +protected: + b3AlignedObjectArray m_tmpSolverBodyPool; + b3GpuConstraintArray m_tmpSolverContactConstraintPool; + b3GpuConstraintArray m_tmpSolverNonContactConstraintPool; + b3GpuConstraintArray m_tmpSolverContactFrictionConstraintPool; + b3GpuConstraintArray m_tmpSolverContactRollingFrictionConstraintPool; b3AlignedObjectArray m_tmpConstraintSizesPool; - - bool m_usePgs; - void averageVelocities(); + bool m_usePgs; + void averageVelocities(); - int m_maxOverrideNumSolverIterations; + int m_maxOverrideNumSolverIterations; - int m_numSplitImpulseRecoveries; + int m_numSplitImpulseRecoveries; -// int getOrInitSolverBody(int bodyIndex, b3RigidBodyData* bodies,b3InertiaData* inertias); - void initSolverBody(int bodyIndex, b3GpuSolverBody* solverBody, b3RigidBodyData* rb); + // int getOrInitSolverBody(int bodyIndex, b3RigidBodyData* bodies,b3InertiaData* inertias); + void initSolverBody(int bodyIndex, b3GpuSolverBody* solverBody, b3RigidBodyData* rb); public: - b3GpuPgsConstraintSolver (cl_context ctx, cl_device_id device, cl_command_queue queue,bool usePgs); - virtual~b3GpuPgsConstraintSolver (); + b3GpuPgsConstraintSolver(cl_context ctx, cl_device_id device, cl_command_queue queue, bool usePgs); + virtual ~b3GpuPgsConstraintSolver(); - virtual b3Scalar solveGroupCacheFriendlyIterations(b3OpenCLArray* gpuConstraints1,int numConstraints,const b3ContactSolverInfo& infoGlobal); - virtual b3Scalar solveGroupCacheFriendlySetup(b3OpenCLArray* gpuBodies, b3OpenCLArray* gpuInertias, int numBodies,b3OpenCLArray* gpuConstraints,int numConstraints,const b3ContactSolverInfo& infoGlobal); - b3Scalar solveGroupCacheFriendlyFinish(b3OpenCLArray* gpuBodies,b3OpenCLArray* gpuInertias,int numBodies,b3OpenCLArray* gpuConstraints,int numConstraints,const b3ContactSolverInfo& infoGlobal); + virtual b3Scalar solveGroupCacheFriendlyIterations(b3OpenCLArray* gpuConstraints1, int numConstraints, const b3ContactSolverInfo& infoGlobal); + virtual b3Scalar solveGroupCacheFriendlySetup(b3OpenCLArray* gpuBodies, b3OpenCLArray* gpuInertias, int numBodies, b3OpenCLArray* gpuConstraints, int numConstraints, const b3ContactSolverInfo& infoGlobal); + b3Scalar solveGroupCacheFriendlyFinish(b3OpenCLArray* gpuBodies, b3OpenCLArray* gpuInertias, int numBodies, b3OpenCLArray* gpuConstraints, int numConstraints, const b3ContactSolverInfo& infoGlobal); + b3Scalar solveGroup(b3OpenCLArray* gpuBodies, b3OpenCLArray* gpuInertias, int numBodies, b3OpenCLArray* gpuConstraints, int numConstraints, const b3ContactSolverInfo& infoGlobal); + void solveJoints(int numBodies, b3OpenCLArray* gpuBodies, b3OpenCLArray* gpuInertias, + int numConstraints, b3OpenCLArray* gpuConstraints); - b3Scalar solveGroup(b3OpenCLArray* gpuBodies,b3OpenCLArray* gpuInertias, int numBodies,b3OpenCLArray* gpuConstraints,int numConstraints,const b3ContactSolverInfo& infoGlobal); - void solveJoints(int numBodies, b3OpenCLArray* gpuBodies, b3OpenCLArray* gpuInertias, - int numConstraints, b3OpenCLArray* gpuConstraints); - - int sortConstraintByBatch3( struct b3BatchConstraint* cs, int numConstraints, int simdWidth , int staticIdx, int numBodies); - void recomputeBatches(); + int sortConstraintByBatch3(struct b3BatchConstraint* cs, int numConstraints, int simdWidth, int staticIdx, int numBodies); + void recomputeBatches(); }; -#endif //B3_GPU_PGS_CONSTRAINT_SOLVER_H +#endif //B3_GPU_PGS_CONSTRAINT_SOLVER_H diff --git a/src/Bullet3OpenCL/RigidBody/b3GpuPgsContactSolver.cpp b/src/Bullet3OpenCL/RigidBody/b3GpuPgsContactSolver.cpp index f0b0abd5e..e3d235a4f 100644 --- a/src/Bullet3OpenCL/RigidBody/b3GpuPgsContactSolver.cpp +++ b/src/Bullet3OpenCL/RigidBody/b3GpuPgsContactSolver.cpp @@ -2,7 +2,7 @@ bool gUseLargeBatches = false; bool gCpuBatchContacts = false; bool gCpuSolveConstraint = false; -bool gCpuRadixSort=false; +bool gCpuRadixSort = false; bool gCpuSetSortData = false; bool gCpuSortContactsDeterminism = false; bool gUseCpuCopyConstraints = false; @@ -11,7 +11,6 @@ bool gReorderContactsOnCpu = false; bool optionalSortContactsDeterminism = true; - #include "b3GpuPgsContactSolver.h" #include "Bullet3OpenCL/ParallelPrimitives/b3RadixSort32CL.h" @@ -23,7 +22,6 @@ bool optionalSortContactsDeterminism = true; #include "Bullet3Collision/NarrowPhaseCollision/b3Config.h" #include "b3Solver.h" - #define B3_SOLVER_SETUP_KERNEL_PATH "src/Bullet3OpenCL/RigidBody/kernels/solverSetup.cl" #define B3_SOLVER_SETUP2_KERNEL_PATH "src/Bullet3OpenCL/RigidBody/kernels/solverSetup2.cl" #define B3_SOLVER_CONTACT_KERNEL_PATH "src/Bullet3OpenCL/RigidBody/kernels/solveContact.cl" @@ -38,11 +36,7 @@ bool optionalSortContactsDeterminism = true; #include "kernels/batchingKernels.h" #include "kernels/batchingKernelsNew.h" - - - - -struct b3GpuBatchingPgsSolverInternalData +struct b3GpuBatchingPgsSolverInternalData { cl_context m_context; cl_device_id m_device; @@ -53,9 +47,9 @@ struct b3GpuBatchingPgsSolverInternalData b3OpenCLArray* m_contactCGPU; b3OpenCLArray* m_numConstraints; b3OpenCLArray* m_offsets; - - b3Solver* m_solverGPU; - + + b3Solver* m_solverGPU; + cl_kernel m_batchingKernel; cl_kernel m_batchingKernelNew; cl_kernel m_solveContactKernel; @@ -67,17 +61,14 @@ struct b3GpuBatchingPgsSolverInternalData cl_kernel m_reorderContactKernel; cl_kernel m_copyConstraintKernel; - cl_kernel m_setDeterminismSortDataBodyAKernel; - cl_kernel m_setDeterminismSortDataBodyBKernel; - cl_kernel m_setDeterminismSortDataChildShapeAKernel; - cl_kernel m_setDeterminismSortDataChildShapeBKernel; + cl_kernel m_setDeterminismSortDataBodyAKernel; + cl_kernel m_setDeterminismSortDataBodyBKernel; + cl_kernel m_setDeterminismSortDataChildShapeAKernel; + cl_kernel m_setDeterminismSortDataChildShapeBKernel; - - - - class b3RadixSort32CL* m_sort32; - class b3BoundSearchCL* m_search; - class b3PrefixScanCL* m_scan; + class b3RadixSort32CL* m_sort32; + class b3BoundSearchCL* m_search; + class b3PrefixScanCL* m_scan; b3OpenCLArray* m_sortDataBuffer; b3OpenCLArray* m_contactBuffer; @@ -85,63 +76,56 @@ struct b3GpuBatchingPgsSolverInternalData b3OpenCLArray* m_bodyBufferGPU; b3OpenCLArray* m_inertiaBufferGPU; b3OpenCLArray* m_pBufContactOutGPU; - - b3OpenCLArray* m_pBufContactOutGPUCopy; - b3OpenCLArray* m_contactKeyValues; + b3OpenCLArray* m_pBufContactOutGPUCopy; + b3OpenCLArray* m_contactKeyValues; b3AlignedObjectArray m_idxBuffer; b3AlignedObjectArray m_sortData; b3AlignedObjectArray m_old; - b3AlignedObjectArray m_batchSizes; - b3OpenCLArray* m_batchSizesGpu; - + b3AlignedObjectArray m_batchSizes; + b3OpenCLArray* m_batchSizesGpu; }; - - -b3GpuPgsContactSolver::b3GpuPgsContactSolver(cl_context ctx,cl_device_id device, cl_command_queue q,int pairCapacity) +b3GpuPgsContactSolver::b3GpuPgsContactSolver(cl_context ctx, cl_device_id device, cl_command_queue q, int pairCapacity) { - m_debugOutput=0; + m_debugOutput = 0; m_data = new b3GpuBatchingPgsSolverInternalData; m_data->m_context = ctx; m_data->m_device = device; m_data->m_queue = q; m_data->m_pairCapacity = pairCapacity; m_data->m_nIterations = 4; - m_data->m_batchSizesGpu = new b3OpenCLArray(ctx,q); - m_data->m_bodyBufferGPU = new b3OpenCLArray(ctx,q); - m_data->m_inertiaBufferGPU = new b3OpenCLArray(ctx,q); - m_data->m_pBufContactOutGPU = new b3OpenCLArray(ctx,q); + m_data->m_batchSizesGpu = new b3OpenCLArray(ctx, q); + m_data->m_bodyBufferGPU = new b3OpenCLArray(ctx, q); + m_data->m_inertiaBufferGPU = new b3OpenCLArray(ctx, q); + m_data->m_pBufContactOutGPU = new b3OpenCLArray(ctx, q); - m_data->m_pBufContactOutGPUCopy = new b3OpenCLArray(ctx,q); - m_data->m_contactKeyValues = new b3OpenCLArray(ctx,q); + m_data->m_pBufContactOutGPUCopy = new b3OpenCLArray(ctx, q); + m_data->m_contactKeyValues = new b3OpenCLArray(ctx, q); + m_data->m_solverGPU = new b3Solver(ctx, device, q, 512 * 1024); - m_data->m_solverGPU = new b3Solver(ctx,device,q,512*1024); + m_data->m_sort32 = new b3RadixSort32CL(ctx, device, m_data->m_queue); + m_data->m_scan = new b3PrefixScanCL(ctx, device, m_data->m_queue, B3_SOLVER_N_CELLS); + m_data->m_search = new b3BoundSearchCL(ctx, device, m_data->m_queue, B3_SOLVER_N_CELLS); - m_data->m_sort32 = new b3RadixSort32CL(ctx,device,m_data->m_queue); - m_data->m_scan = new b3PrefixScanCL(ctx,device,m_data->m_queue,B3_SOLVER_N_CELLS); - m_data->m_search = new b3BoundSearchCL(ctx,device,m_data->m_queue,B3_SOLVER_N_CELLS); + const int sortSize = B3NEXTMULTIPLEOF(pairCapacity, 512); - const int sortSize = B3NEXTMULTIPLEOF( pairCapacity, 512 ); + m_data->m_sortDataBuffer = new b3OpenCLArray(ctx, m_data->m_queue, sortSize); + m_data->m_contactBuffer = new b3OpenCLArray(ctx, m_data->m_queue); - m_data->m_sortDataBuffer = new b3OpenCLArray(ctx,m_data->m_queue,sortSize); - m_data->m_contactBuffer = new b3OpenCLArray(ctx,m_data->m_queue); - - m_data->m_numConstraints = new b3OpenCLArray(ctx,m_data->m_queue,B3_SOLVER_N_CELLS); + m_data->m_numConstraints = new b3OpenCLArray(ctx, m_data->m_queue, B3_SOLVER_N_CELLS); m_data->m_numConstraints->resize(B3_SOLVER_N_CELLS); - m_data->m_contactCGPU = new b3OpenCLArray(ctx,q,pairCapacity); + m_data->m_contactCGPU = new b3OpenCLArray(ctx, q, pairCapacity); - m_data->m_offsets = new b3OpenCLArray( ctx,m_data->m_queue,B3_SOLVER_N_CELLS); + m_data->m_offsets = new b3OpenCLArray(ctx, m_data->m_queue, B3_SOLVER_N_CELLS); m_data->m_offsets->resize(B3_SOLVER_N_CELLS); const char* additionalMacros = ""; //const char* srcFileNameForCaching=""; - - cl_int pErrNum; const char* batchKernelSource = batchingKernelsCL; const char* batchKernelNewSource = batchingKernelsNewCL; @@ -149,88 +133,73 @@ b3GpuPgsContactSolver::b3GpuPgsContactSolver(cl_context ctx,cl_device_id device, const char* solverSetup2Source = solverSetup2CL; const char* solveContactSource = solveContactCL; const char* solveFrictionSource = solveFrictionCL; - - + { - - cl_program solveContactProg= b3OpenCLUtils::compileCLProgramFromString( ctx, device, solveContactSource, &pErrNum,additionalMacros, B3_SOLVER_CONTACT_KERNEL_PATH); + cl_program solveContactProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, solveContactSource, &pErrNum, additionalMacros, B3_SOLVER_CONTACT_KERNEL_PATH); b3Assert(solveContactProg); - - cl_program solveFrictionProg= b3OpenCLUtils::compileCLProgramFromString( ctx, device, solveFrictionSource, &pErrNum,additionalMacros, B3_SOLVER_FRICTION_KERNEL_PATH); + + cl_program solveFrictionProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, solveFrictionSource, &pErrNum, additionalMacros, B3_SOLVER_FRICTION_KERNEL_PATH); b3Assert(solveFrictionProg); - cl_program solverSetup2Prog= b3OpenCLUtils::compileCLProgramFromString( ctx, device, solverSetup2Source, &pErrNum,additionalMacros, B3_SOLVER_SETUP2_KERNEL_PATH); - - + cl_program solverSetup2Prog = b3OpenCLUtils::compileCLProgramFromString(ctx, device, solverSetup2Source, &pErrNum, additionalMacros, B3_SOLVER_SETUP2_KERNEL_PATH); + b3Assert(solverSetup2Prog); - - cl_program solverSetupProg= b3OpenCLUtils::compileCLProgramFromString( ctx, device, solverSetupSource, &pErrNum,additionalMacros, B3_SOLVER_SETUP_KERNEL_PATH); + cl_program solverSetupProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, solverSetupSource, &pErrNum, additionalMacros, B3_SOLVER_SETUP_KERNEL_PATH); b3Assert(solverSetupProg); - - - m_data->m_solveFrictionKernel= b3OpenCLUtils::compileCLKernelFromString( ctx, device, solveFrictionSource, "BatchSolveKernelFriction", &pErrNum, solveFrictionProg,additionalMacros ); + + m_data->m_solveFrictionKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solveFrictionSource, "BatchSolveKernelFriction", &pErrNum, solveFrictionProg, additionalMacros); b3Assert(m_data->m_solveFrictionKernel); - m_data->m_solveContactKernel= b3OpenCLUtils::compileCLKernelFromString( ctx, device, solveContactSource, "BatchSolveKernelContact", &pErrNum, solveContactProg,additionalMacros ); + m_data->m_solveContactKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solveContactSource, "BatchSolveKernelContact", &pErrNum, solveContactProg, additionalMacros); b3Assert(m_data->m_solveContactKernel); - m_data->m_solveSingleContactKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solveContactSource, "solveSingleContactKernel", &pErrNum, solveContactProg,additionalMacros ); + m_data->m_solveSingleContactKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solveContactSource, "solveSingleContactKernel", &pErrNum, solveContactProg, additionalMacros); b3Assert(m_data->m_solveSingleContactKernel); - m_data->m_solveSingleFrictionKernel =b3OpenCLUtils::compileCLKernelFromString( ctx, device, solveFrictionSource, "solveSingleFrictionKernel", &pErrNum, solveFrictionProg,additionalMacros ); + m_data->m_solveSingleFrictionKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solveFrictionSource, "solveSingleFrictionKernel", &pErrNum, solveFrictionProg, additionalMacros); b3Assert(m_data->m_solveSingleFrictionKernel); - - m_data->m_contactToConstraintKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverSetupSource, "ContactToConstraintKernel", &pErrNum, solverSetupProg,additionalMacros ); + + m_data->m_contactToConstraintKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetupSource, "ContactToConstraintKernel", &pErrNum, solverSetupProg, additionalMacros); b3Assert(m_data->m_contactToConstraintKernel); - - m_data->m_setSortDataKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "SetSortDataKernel", &pErrNum, solverSetup2Prog,additionalMacros ); + + m_data->m_setSortDataKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "SetSortDataKernel", &pErrNum, solverSetup2Prog, additionalMacros); b3Assert(m_data->m_setSortDataKernel); - m_data->m_setDeterminismSortDataBodyAKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "SetDeterminismSortDataBodyA", &pErrNum, solverSetup2Prog,additionalMacros ); + m_data->m_setDeterminismSortDataBodyAKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "SetDeterminismSortDataBodyA", &pErrNum, solverSetup2Prog, additionalMacros); b3Assert(m_data->m_setDeterminismSortDataBodyAKernel); - m_data->m_setDeterminismSortDataBodyBKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "SetDeterminismSortDataBodyB", &pErrNum, solverSetup2Prog,additionalMacros ); + m_data->m_setDeterminismSortDataBodyBKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "SetDeterminismSortDataBodyB", &pErrNum, solverSetup2Prog, additionalMacros); b3Assert(m_data->m_setDeterminismSortDataBodyBKernel); - m_data->m_setDeterminismSortDataChildShapeAKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "SetDeterminismSortDataChildShapeA", &pErrNum, solverSetup2Prog,additionalMacros ); + m_data->m_setDeterminismSortDataChildShapeAKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "SetDeterminismSortDataChildShapeA", &pErrNum, solverSetup2Prog, additionalMacros); b3Assert(m_data->m_setDeterminismSortDataChildShapeAKernel); - m_data->m_setDeterminismSortDataChildShapeBKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "SetDeterminismSortDataChildShapeB", &pErrNum, solverSetup2Prog,additionalMacros ); + m_data->m_setDeterminismSortDataChildShapeBKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "SetDeterminismSortDataChildShapeB", &pErrNum, solverSetup2Prog, additionalMacros); b3Assert(m_data->m_setDeterminismSortDataChildShapeBKernel); - - m_data->m_reorderContactKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "ReorderContactKernel", &pErrNum, solverSetup2Prog,additionalMacros ); + m_data->m_reorderContactKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "ReorderContactKernel", &pErrNum, solverSetup2Prog, additionalMacros); b3Assert(m_data->m_reorderContactKernel); - - m_data->m_copyConstraintKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "CopyConstraintKernel", &pErrNum, solverSetup2Prog,additionalMacros ); + m_data->m_copyConstraintKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "CopyConstraintKernel", &pErrNum, solverSetup2Prog, additionalMacros); b3Assert(m_data->m_copyConstraintKernel); - } { - cl_program batchingProg = b3OpenCLUtils::compileCLProgramFromString( ctx, device, batchKernelSource, &pErrNum,additionalMacros, B3_BATCHING_PATH); + cl_program batchingProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, batchKernelSource, &pErrNum, additionalMacros, B3_BATCHING_PATH); b3Assert(batchingProg); - - m_data->m_batchingKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, batchKernelSource, "CreateBatches", &pErrNum, batchingProg,additionalMacros ); + + m_data->m_batchingKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, batchKernelSource, "CreateBatches", &pErrNum, batchingProg, additionalMacros); b3Assert(m_data->m_batchingKernel); } - + { - cl_program batchingNewProg = b3OpenCLUtils::compileCLProgramFromString( ctx, device, batchKernelNewSource, &pErrNum,additionalMacros, B3_BATCHING_NEW_PATH); + cl_program batchingNewProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, batchKernelNewSource, &pErrNum, additionalMacros, B3_BATCHING_NEW_PATH); b3Assert(batchingNewProg); - - m_data->m_batchingKernelNew = b3OpenCLUtils::compileCLKernelFromString( ctx, device, batchKernelNewSource, "CreateBatchesNew", &pErrNum, batchingNewProg,additionalMacros ); + + m_data->m_batchingKernelNew = b3OpenCLUtils::compileCLKernelFromString(ctx, device, batchKernelNewSource, "CreateBatchesNew", &pErrNum, batchingNewProg, additionalMacros); b3Assert(m_data->m_batchingKernelNew); } - - - - - - - } b3GpuPgsContactSolver::~b3GpuPgsContactSolver() @@ -242,8 +211,6 @@ b3GpuPgsContactSolver::~b3GpuPgsContactSolver() delete m_data->m_pBufContactOutGPUCopy; delete m_data->m_contactKeyValues; - - delete m_data->m_contactCGPU; delete m_data->m_numConstraints; delete m_data->m_offsets; @@ -259,29 +226,25 @@ b3GpuPgsContactSolver::~b3GpuPgsContactSolver() clReleaseKernel(m_data->m_batchingKernelNew); clReleaseKernel(m_data->m_solveSingleContactKernel); clReleaseKernel(m_data->m_solveSingleFrictionKernel); - clReleaseKernel( m_data->m_solveContactKernel); - clReleaseKernel( m_data->m_solveFrictionKernel); + clReleaseKernel(m_data->m_solveContactKernel); + clReleaseKernel(m_data->m_solveFrictionKernel); - clReleaseKernel( m_data->m_contactToConstraintKernel); - clReleaseKernel( m_data->m_setSortDataKernel); - clReleaseKernel( m_data->m_reorderContactKernel); - clReleaseKernel( m_data->m_copyConstraintKernel); + clReleaseKernel(m_data->m_contactToConstraintKernel); + clReleaseKernel(m_data->m_setSortDataKernel); + clReleaseKernel(m_data->m_reorderContactKernel); + clReleaseKernel(m_data->m_copyConstraintKernel); clReleaseKernel(m_data->m_setDeterminismSortDataBodyAKernel); clReleaseKernel(m_data->m_setDeterminismSortDataBodyBKernel); clReleaseKernel(m_data->m_setDeterminismSortDataChildShapeAKernel); clReleaseKernel(m_data->m_setDeterminismSortDataChildShapeBKernel); - - delete m_data; } - - struct b3ConstraintCfg { - b3ConstraintCfg( float dt = 0.f ): m_positionDrift( 0.005f ), m_positionConstraintCoeff( 0.2f ), m_dt(dt), m_staticIdx(0) {} + b3ConstraintCfg(float dt = 0.f) : m_positionDrift(0.005f), m_positionConstraintCoeff(0.2f), m_dt(dt), m_staticIdx(0) {} float m_positionDrift; float m_positionConstraintCoeff; @@ -291,354 +254,306 @@ struct b3ConstraintCfg int m_staticIdx; }; - - -void b3GpuPgsContactSolver::solveContactConstraintBatchSizes( const b3OpenCLArray* bodyBuf, const b3OpenCLArray* shapeBuf, - b3OpenCLArray* constraint, void* additionalData, int n ,int maxNumBatches,int numIterations, const b3AlignedObjectArray* batchSizes)//const b3OpenCLArray* gpuBatchSizes) +void b3GpuPgsContactSolver::solveContactConstraintBatchSizes(const b3OpenCLArray* bodyBuf, const b3OpenCLArray* shapeBuf, + b3OpenCLArray* constraint, void* additionalData, int n, int maxNumBatches, int numIterations, const b3AlignedObjectArray* batchSizes) //const b3OpenCLArray* gpuBatchSizes) { B3_PROFILE("solveContactConstraintBatchSizes"); - int numBatches = batchSizes->size()/B3_MAX_NUM_BATCHES; - for(int iter=0; itersize() / B3_MAX_NUM_BATCHES; + for (int iter = 0; iter < numIterations; iter++) { - - for (int cellId=0;cellIdat(cellId*B3_MAX_NUM_BATCHES+ii); + int numInBatch = batchSizes->at(cellId * B3_MAX_NUM_BATCHES + ii); if (!numInBatch) break; { - b3LauncherCL launcher( m_data->m_queue, m_data->m_solveSingleContactKernel,"m_solveSingleContactKernel" ); - launcher.setBuffer(bodyBuf->getBufferCL() ); - launcher.setBuffer(shapeBuf->getBufferCL() ); - launcher.setBuffer( constraint->getBufferCL() ); + b3LauncherCL launcher(m_data->m_queue, m_data->m_solveSingleContactKernel, "m_solveSingleContactKernel"); + launcher.setBuffer(bodyBuf->getBufferCL()); + launcher.setBuffer(shapeBuf->getBufferCL()); + launcher.setBuffer(constraint->getBufferCL()); launcher.setConst(cellId); launcher.setConst(offset); launcher.setConst(numInBatch); launcher.launch1D(numInBatch); - offset+=numInBatch; + offset += numInBatch; } } } } - - for(int iter=0; iterat(cellId*B3_MAX_NUM_BATCHES+ii); + int numInBatch = batchSizes->at(cellId * B3_MAX_NUM_BATCHES + ii); if (!numInBatch) break; { - b3LauncherCL launcher( m_data->m_queue, m_data->m_solveSingleFrictionKernel,"m_solveSingleFrictionKernel" ); - launcher.setBuffer(bodyBuf->getBufferCL() ); - launcher.setBuffer(shapeBuf->getBufferCL() ); - launcher.setBuffer( constraint->getBufferCL() ); + b3LauncherCL launcher(m_data->m_queue, m_data->m_solveSingleFrictionKernel, "m_solveSingleFrictionKernel"); + launcher.setBuffer(bodyBuf->getBufferCL()); + launcher.setBuffer(shapeBuf->getBufferCL()); + launcher.setBuffer(constraint->getBufferCL()); launcher.setConst(cellId); launcher.setConst(offset); launcher.setConst(numInBatch); launcher.launch1D(numInBatch); - offset+=numInBatch; + offset += numInBatch; } } } } } -void b3GpuPgsContactSolver::solveContactConstraint( const b3OpenCLArray* bodyBuf, const b3OpenCLArray* shapeBuf, - b3OpenCLArray* constraint, void* additionalData, int n ,int maxNumBatches,int numIterations, const b3AlignedObjectArray* batchSizes)//,const b3OpenCLArray* gpuBatchSizes) +void b3GpuPgsContactSolver::solveContactConstraint(const b3OpenCLArray* bodyBuf, const b3OpenCLArray* shapeBuf, + b3OpenCLArray* constraint, void* additionalData, int n, int maxNumBatches, int numIterations, const b3AlignedObjectArray* batchSizes) //,const b3OpenCLArray* gpuBatchSizes) { - //sort the contacts - - b3Int4 cdata = b3MakeInt4( n, 0, 0, 0 ); + b3Int4 cdata = b3MakeInt4(n, 0, 0, 0); { - const int nn = B3_SOLVER_N_CELLS; cdata.x = 0; - cdata.y = maxNumBatches;//250; + cdata.y = maxNumBatches; //250; - - int numWorkItems = 64*nn/B3_SOLVER_N_BATCHES; + int numWorkItems = 64 * nn / B3_SOLVER_N_BATCHES; #ifdef DEBUG_ME - SolverDebugInfo* debugInfo = new SolverDebugInfo[numWorkItems]; - adl::b3OpenCLArray gpuDebugInfo(data->m_device,numWorkItems); + SolverDebugInfo* debugInfo = new SolverDebugInfo[numWorkItems]; + adl::b3OpenCLArray gpuDebugInfo(data->m_device, numWorkItems); #endif - - { - B3_PROFILE("m_batchSolveKernel iterations"); - for(int iter=0; iterm_queue, m_data->m_solveContactKernel,"m_solveContactKernel" ); + b3LauncherCL launcher(m_data->m_queue, m_data->m_solveContactKernel, "m_solveContactKernel"); #if 1 - - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( bodyBuf->getBufferCL() ), - b3BufferInfoCL( shapeBuf->getBufferCL() ), - b3BufferInfoCL( constraint->getBufferCL() ), - b3BufferInfoCL( m_data->m_solverGPU->m_numConstraints->getBufferCL() ), - b3BufferInfoCL( m_data->m_solverGPU->m_offsets->getBufferCL() ) + b3BufferInfoCL bInfo[] = { + + b3BufferInfoCL(bodyBuf->getBufferCL()), + b3BufferInfoCL(shapeBuf->getBufferCL()), + b3BufferInfoCL(constraint->getBufferCL()), + b3BufferInfoCL(m_data->m_solverGPU->m_numConstraints->getBufferCL()), + b3BufferInfoCL(m_data->m_solverGPU->m_offsets->getBufferCL()) #ifdef DEBUG_ME - , b3BufferInfoCL(&gpuDebugInfo) + , + b3BufferInfoCL(&gpuDebugInfo) #endif - }; + }; - - - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setBuffer( m_data->m_solverGPU->m_batchSizes.getBufferCL()); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setBuffer(m_data->m_solverGPU->m_batchSizes.getBufferCL()); //launcher.setConst( cdata.x ); - launcher.setConst( cdata.y ); - launcher.setConst( cdata.z ); + launcher.setConst(cdata.y); + launcher.setConst(cdata.z); b3Int4 nSplit; nSplit.x = B3_SOLVER_N_SPLIT_X; nSplit.y = B3_SOLVER_N_SPLIT_Y; nSplit.z = B3_SOLVER_N_SPLIT_Z; - launcher.setConst( nSplit ); - launcher.launch1D( numWorkItems, 64 ); + launcher.setConst(nSplit); + launcher.launch1D(numWorkItems, 64); - #else - const char* fileName = "m_batchSolveKernel.bin"; - FILE* f = fopen(fileName,"rb"); - if (f) - { - int sizeInBytes=0; - if (fseek(f, 0, SEEK_END) || (sizeInBytes = ftell(f)) == EOF || fseek(f, 0, SEEK_SET)) - { - printf("error, cannot get file size\n"); - exit(0); - } - - unsigned char* buf = (unsigned char*) malloc(sizeInBytes); - fread(buf,sizeInBytes,1,f); - int serializedBytes = launcher.deserializeArgs(buf, sizeInBytes,m_context); - int num = *(int*)&buf[serializedBytes]; - - launcher.launch1D( num); + const char* fileName = "m_batchSolveKernel.bin"; + FILE* f = fopen(fileName, "rb"); + if (f) + { + int sizeInBytes = 0; + if (fseek(f, 0, SEEK_END) || (sizeInBytes = ftell(f)) == EOF || fseek(f, 0, SEEK_SET)) + { + printf("error, cannot get file size\n"); + exit(0); + } - //this clFinish is for testing on errors - clFinish(m_queue); - } + unsigned char* buf = (unsigned char*)malloc(sizeInBytes); + fread(buf, sizeInBytes, 1, f); + int serializedBytes = launcher.deserializeArgs(buf, sizeInBytes, m_context); + int num = *(int*)&buf[serializedBytes]; + + launcher.launch1D(num); + + //this clFinish is for testing on errors + clFinish(m_queue); + } #endif - #ifdef DEBUG_ME clFinish(m_queue); - gpuDebugInfo.read(debugInfo,numWorkItems); + gpuDebugInfo.read(debugInfo, numWorkItems); clFinish(m_queue); - for (int i=0;i0) + if (debugInfo[i].m_valInt2 > 0) { - printf("debugInfo[i].m_valInt2 = %d\n",i,debugInfo[i].m_valInt2); + printf("debugInfo[i].m_valInt2 = %d\n", i, debugInfo[i].m_valInt2); } - if (debugInfo[i].m_valInt3>0) + if (debugInfo[i].m_valInt3 > 0) { - printf("debugInfo[i].m_valInt3 = %d\n",i,debugInfo[i].m_valInt3); + printf("debugInfo[i].m_valInt3 = %d\n", i, debugInfo[i].m_valInt3); } } -#endif //DEBUG_ME - - +#endif //DEBUG_ME } } - + clFinish(m_data->m_queue); - - } cdata.x = 1; - bool applyFriction=true; + bool applyFriction = true; if (applyFriction) - { + { B3_PROFILE("m_batchSolveKernel iterations2"); - for(int iter=0; itergetBufferCL() ), - b3BufferInfoCL( shapeBuf->getBufferCL() ), - b3BufferInfoCL( constraint->getBufferCL() ), - b3BufferInfoCL( m_data->m_solverGPU->m_numConstraints->getBufferCL() ), - b3BufferInfoCL( m_data->m_solverGPU->m_offsets->getBufferCL() ) + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(bodyBuf->getBufferCL()), + b3BufferInfoCL(shapeBuf->getBufferCL()), + b3BufferInfoCL(constraint->getBufferCL()), + b3BufferInfoCL(m_data->m_solverGPU->m_numConstraints->getBufferCL()), + b3BufferInfoCL(m_data->m_solverGPU->m_offsets->getBufferCL()) #ifdef DEBUG_ME - ,b3BufferInfoCL(&gpuDebugInfo) -#endif //DEBUG_ME + , + b3BufferInfoCL(&gpuDebugInfo) +#endif //DEBUG_ME }; - b3LauncherCL launcher( m_data->m_queue, m_data->m_solveFrictionKernel,"m_solveFrictionKernel" ); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setBuffer( m_data->m_solverGPU->m_batchSizes.getBufferCL()); + b3LauncherCL launcher(m_data->m_queue, m_data->m_solveFrictionKernel, "m_solveFrictionKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setBuffer(m_data->m_solverGPU->m_batchSizes.getBufferCL()); //launcher.setConst( cdata.x ); - launcher.setConst( cdata.y ); - launcher.setConst( cdata.z ); + launcher.setConst(cdata.y); + launcher.setConst(cdata.z); - b3Int4 nSplit; + b3Int4 nSplit; nSplit.x = B3_SOLVER_N_SPLIT_X; nSplit.y = B3_SOLVER_N_SPLIT_Y; nSplit.z = B3_SOLVER_N_SPLIT_Z; - launcher.setConst( nSplit ); - - launcher.launch1D( 64*nn/B3_SOLVER_N_BATCHES, 64 ); + launcher.setConst(nSplit); + + launcher.launch1D(64 * nn / B3_SOLVER_N_BATCHES, 64); } } clFinish(m_data->m_queue); - } #ifdef DEBUG_ME delete[] debugInfo; -#endif //DEBUG_ME +#endif //DEBUG_ME } - - } - - - - - - - - - - -static bool sortfnc(const b3SortData& a,const b3SortData& b) +static bool sortfnc(const b3SortData& a, const b3SortData& b) { - return (a.m_keym_bodyBufferGPU->setFromOpenCLBuffer(bodyBuf,numBodies); - m_data->m_inertiaBufferGPU->setFromOpenCLBuffer(inertiaBuf,numBodies); - m_data->m_pBufContactOutGPU->setFromOpenCLBuffer(contactBuf,numContacts); + m_data->m_bodyBufferGPU->setFromOpenCLBuffer(bodyBuf, numBodies); + m_data->m_inertiaBufferGPU->setFromOpenCLBuffer(inertiaBuf, numBodies); + m_data->m_pBufContactOutGPU->setFromOpenCLBuffer(contactBuf, numContacts); if (optionalSortContactsDeterminism) { @@ -671,61 +581,61 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem m_data->m_pBufContactOutGPUCopy->resize(numContacts); m_data->m_contactKeyValues->resize(numContacts); - m_data->m_pBufContactOutGPU->copyToCL(m_data->m_pBufContactOutGPUCopy->getBufferCL(),numContacts,0,0); + m_data->m_pBufContactOutGPU->copyToCL(m_data->m_pBufContactOutGPUCopy->getBufferCL(), numContacts, 0, 0); { - b3LauncherCL launcher(m_data->m_queue, m_data->m_setDeterminismSortDataChildShapeBKernel,"m_setDeterminismSortDataChildShapeBKernel"); + b3LauncherCL launcher(m_data->m_queue, m_data->m_setDeterminismSortDataChildShapeBKernel, "m_setDeterminismSortDataChildShapeBKernel"); launcher.setBuffer(m_data->m_pBufContactOutGPUCopy->getBufferCL()); launcher.setBuffer(m_data->m_contactKeyValues->getBufferCL()); launcher.setConst(numContacts); - launcher.launch1D( numContacts, 64 ); + launcher.launch1D(numContacts, 64); } m_data->m_solverGPU->m_sort32->execute(*m_data->m_contactKeyValues); { - b3LauncherCL launcher(m_data->m_queue, m_data->m_setDeterminismSortDataChildShapeAKernel,"m_setDeterminismSortDataChildShapeAKernel"); + b3LauncherCL launcher(m_data->m_queue, m_data->m_setDeterminismSortDataChildShapeAKernel, "m_setDeterminismSortDataChildShapeAKernel"); launcher.setBuffer(m_data->m_pBufContactOutGPUCopy->getBufferCL()); launcher.setBuffer(m_data->m_contactKeyValues->getBufferCL()); launcher.setConst(numContacts); - launcher.launch1D( numContacts, 64 ); + launcher.launch1D(numContacts, 64); } m_data->m_solverGPU->m_sort32->execute(*m_data->m_contactKeyValues); { - b3LauncherCL launcher(m_data->m_queue, m_data->m_setDeterminismSortDataBodyBKernel,"m_setDeterminismSortDataBodyBKernel"); + b3LauncherCL launcher(m_data->m_queue, m_data->m_setDeterminismSortDataBodyBKernel, "m_setDeterminismSortDataBodyBKernel"); launcher.setBuffer(m_data->m_pBufContactOutGPUCopy->getBufferCL()); launcher.setBuffer(m_data->m_contactKeyValues->getBufferCL()); launcher.setConst(numContacts); - launcher.launch1D( numContacts, 64 ); + launcher.launch1D(numContacts, 64); } - + m_data->m_solverGPU->m_sort32->execute(*m_data->m_contactKeyValues); - + { - b3LauncherCL launcher(m_data->m_queue, m_data->m_setDeterminismSortDataBodyAKernel,"m_setDeterminismSortDataBodyAKernel"); + b3LauncherCL launcher(m_data->m_queue, m_data->m_setDeterminismSortDataBodyAKernel, "m_setDeterminismSortDataBodyAKernel"); launcher.setBuffer(m_data->m_pBufContactOutGPUCopy->getBufferCL()); launcher.setBuffer(m_data->m_contactKeyValues->getBufferCL()); launcher.setConst(numContacts); - launcher.launch1D( numContacts, 64 ); + launcher.launch1D(numContacts, 64); } m_data->m_solverGPU->m_sort32->execute(*m_data->m_contactKeyValues); { B3_PROFILE("gpu reorderContactKernel (determinism)"); - + b3Int4 cdata; cdata.x = numContacts; - + //b3BufferInfoCL bInfo[] = { b3BufferInfoCL( m_data->m_pBufContactOutGPU->getBufferCL() ), b3BufferInfoCL( m_data->m_solverGPU->m_contactBuffer2->getBufferCL()) // , b3BufferInfoCL( m_data->m_solverGPU->m_sortDataBuffer->getBufferCL()) }; - b3LauncherCL launcher(m_data->m_queue,m_data->m_solverGPU->m_reorderContactKernel,"m_reorderContactKernel"); + b3LauncherCL launcher(m_data->m_queue, m_data->m_solverGPU->m_reorderContactKernel, "m_reorderContactKernel"); launcher.setBuffer(m_data->m_pBufContactOutGPUCopy->getBufferCL()); launcher.setBuffer(m_data->m_pBufContactOutGPU->getBufferCL()); launcher.setBuffer(m_data->m_contactKeyValues->getBufferCL()); - launcher.setConst( cdata ); - launcher.launch1D( numContacts, 64 ); - } - - } else + launcher.setConst(cdata); + launcher.launch1D(numContacts, 64); + } + } + else { B3_PROFILE("CPU Sort contact constraints (determinism)"); b3AlignedObjectArray cpuConstraints; @@ -735,96 +645,80 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem { cpuConstraints.quickSort(b3ContactCmp); - for (int i=0;im_pBufContactOutGPU->copyFromHost(cpuConstraints); - if (m_debugOutput==100) + if (m_debugOutput == 100) { - for (int i=0;im_pBufContactOutGPU->size(); bool useSolver = true; - - if (useSolver) - { - float dt=1./60.; - b3ConstraintCfg csCfg( dt ); - csCfg.m_enableParallelSolve = true; - csCfg.m_batchCellSize = 6; - csCfg.m_staticIdx = static0Index; - - - b3OpenCLArray* bodyBuf = m_data->m_bodyBufferGPU; + if (useSolver) + { + float dt = 1. / 60.; + b3ConstraintCfg csCfg(dt); + csCfg.m_enableParallelSolve = true; + csCfg.m_batchCellSize = 6; + csCfg.m_staticIdx = static0Index; + + b3OpenCLArray* bodyBuf = m_data->m_bodyBufferGPU; + + void* additionalData = 0; //m_data->m_frictionCGPU; + const b3OpenCLArray* shapeBuf = m_data->m_inertiaBufferGPU; + b3OpenCLArray* contactConstraintOut = m_data->m_contactCGPU; + int nContacts = nContactOut; - void* additionalData = 0;//m_data->m_frictionCGPU; - const b3OpenCLArray* shapeBuf = m_data->m_inertiaBufferGPU; - b3OpenCLArray* contactConstraintOut = m_data->m_contactCGPU; - int nContacts = nContactOut; - - int maxNumBatches = 0; - + if (!gUseLargeBatches) - { - - if( m_data->m_solverGPU->m_contactBuffer2) - { - m_data->m_solverGPU->m_contactBuffer2->resize(nContacts); - } - - if( m_data->m_solverGPU->m_contactBuffer2 == 0 ) - { - m_data->m_solverGPU->m_contactBuffer2 = new b3OpenCLArray(m_data->m_context,m_data->m_queue, nContacts ); - m_data->m_solverGPU->m_contactBuffer2->resize(nContacts); - } - - //clFinish(m_data->m_queue); - - - + { + if (m_data->m_solverGPU->m_contactBuffer2) + { + m_data->m_solverGPU->m_contactBuffer2->resize(nContacts); + } + + if (m_data->m_solverGPU->m_contactBuffer2 == 0) + { + m_data->m_solverGPU->m_contactBuffer2 = new b3OpenCLArray(m_data->m_context, m_data->m_queue, nContacts); + m_data->m_solverGPU->m_contactBuffer2->resize(nContacts); + } + + //clFinish(m_data->m_queue); + { B3_PROFILE("batching"); //@todo: just reserve it, without copy of original contact (unless we use warmstarting) - - //const b3OpenCLArray* bodyNative = bodyBuf; - { - //b3OpenCLArray* bodyNative = b3OpenCLArrayUtils::map( data->m_device, bodyBuf ); //b3OpenCLArray* contactNative = b3OpenCLArrayUtils::map( data->m_device, contactsIn ); - const int sortAlignment = 512; // todo. get this out of sort - if( csCfg.m_enableParallelSolve ) + const int sortAlignment = 512; // todo. get this out of sort + if (csCfg.m_enableParallelSolve) { - - - int sortSize = B3NEXTMULTIPLEOF( nContacts, sortAlignment ); + int sortSize = B3NEXTMULTIPLEOF(nContacts, sortAlignment); b3OpenCLArray* countsNative = m_data->m_solverGPU->m_numConstraints; b3OpenCLArray* offsetsNative = m_data->m_solverGPU->m_offsets; - if (!gCpuSetSortData) - { // 2. set cell idx + { // 2. set cell idx B3_PROFILE("GPU set cell idx"); struct CB { @@ -834,29 +728,28 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem b3Int4 m_nSplit; }; - b3Assert( sortSize%64 == 0 ); + b3Assert(sortSize % 64 == 0); CB cdata; cdata.m_nContacts = nContacts; cdata.m_staticIdx = csCfg.m_staticIdx; - cdata.m_scale = 1.f/csCfg.m_batchCellSize; + cdata.m_scale = 1.f / csCfg.m_batchCellSize; cdata.m_nSplit.x = B3_SOLVER_N_SPLIT_X; cdata.m_nSplit.y = B3_SOLVER_N_SPLIT_Y; cdata.m_nSplit.z = B3_SOLVER_N_SPLIT_Z; m_data->m_solverGPU->m_sortDataBuffer->resize(nContacts); - - b3BufferInfoCL bInfo[] = { b3BufferInfoCL( m_data->m_pBufContactOutGPU->getBufferCL() ), b3BufferInfoCL( bodyBuf->getBufferCL()), b3BufferInfoCL( m_data->m_solverGPU->m_sortDataBuffer->getBufferCL()) }; - b3LauncherCL launcher(m_data->m_queue, m_data->m_solverGPU->m_setSortDataKernel,"m_setSortDataKernel" ); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( cdata.m_nContacts ); - launcher.setConst( cdata.m_scale ); + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(m_data->m_pBufContactOutGPU->getBufferCL()), b3BufferInfoCL(bodyBuf->getBufferCL()), b3BufferInfoCL(m_data->m_solverGPU->m_sortDataBuffer->getBufferCL())}; + b3LauncherCL launcher(m_data->m_queue, m_data->m_solverGPU->m_setSortDataKernel, "m_setSortDataKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(cdata.m_nContacts); + launcher.setConst(cdata.m_scale); launcher.setConst(cdata.m_nSplit); launcher.setConst(cdata.m_staticIdx); - - launcher.launch1D( sortSize, 64 ); - } else + launcher.launch1D(sortSize, 64); + } + else { m_data->m_solverGPU->m_sortDataBuffer->resize(nContacts); b3AlignedObjectArray sortDataCPU; @@ -866,22 +759,19 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem m_data->m_pBufContactOutGPU->copyToHost(contactCPU); b3AlignedObjectArray bodiesCPU; bodyBuf->copyToHost(bodiesCPU); - float scale = 1.f/csCfg.m_batchCellSize; + float scale = 1.f / csCfg.m_batchCellSize; b3Int4 nSplit; nSplit.x = B3_SOLVER_N_SPLIT_X; nSplit.y = B3_SOLVER_N_SPLIT_Y; nSplit.z = B3_SOLVER_N_SPLIT_Z; - SetSortDataCPU(&contactCPU[0], &bodiesCPU[0], &sortDataCPU[0], nContacts,scale,nSplit,csCfg.m_staticIdx); - + SetSortDataCPU(&contactCPU[0], &bodiesCPU[0], &sortDataCPU[0], nContacts, scale, nSplit, csCfg.m_staticIdx); m_data->m_solverGPU->m_sortDataBuffer->copyFromHost(sortDataCPU); } - - if (!gCpuRadixSort) - { // 3. sort by cell idx + { // 3. sort by cell idx B3_PROFILE("gpuRadixSort"); //int n = B3_SOLVER_N_SPLIT*B3_SOLVER_N_SPLIT; //int sortBit = 32; @@ -891,10 +781,8 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem //adl::RadixSort32::execute( data->m_sort32, *data->m_sortDataBuffer, sortSize ); b3OpenCLArray& keyValuesInOut = *(m_data->m_solverGPU->m_sortDataBuffer); this->m_data->m_solverGPU->m_sort32->execute(keyValuesInOut); - - - - } else + } + else { b3OpenCLArray& keyValuesInOut = *(m_data->m_solverGPU->m_sortDataBuffer); b3AlignedObjectArray hostValues; @@ -903,7 +791,6 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem keyValuesInOut.copyFromHost(hostValues); } - if (gUseScanHost) { // 4. find entries @@ -914,13 +801,11 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem b3AlignedObjectArray sortDataHost; m_data->m_solverGPU->m_sortDataBuffer->copyToHost(sortDataHost); - //m_data->m_solverGPU->m_search->executeHost(*m_data->m_solverGPU->m_sortDataBuffer,nContacts,*countsNative,B3_SOLVER_N_CELLS,b3BoundSearchCL::COUNT); - m_data->m_solverGPU->m_search->executeHost(sortDataHost,nContacts,countsHost,B3_SOLVER_N_CELLS,b3BoundSearchCL::COUNT); + m_data->m_solverGPU->m_search->executeHost(sortDataHost, nContacts, countsHost, B3_SOLVER_N_CELLS, b3BoundSearchCL::COUNT); countsNative->copyFromHost(countsHost); - //adl::BoundSearch::execute( data->m_search, *data->m_sortDataBuffer, nContacts, *countsNative, // B3_SOLVER_N_SPLIT*B3_SOLVER_N_SPLIT, adl::BoundSearchBase::COUNT ); @@ -929,24 +814,21 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem b3AlignedObjectArray offsetsHost; offsetsHost.resize(offsetsNative->size()); - - m_data->m_solverGPU->m_scan->executeHost(countsHost,offsetsHost, B3_SOLVER_N_CELLS);//,&sum ); + m_data->m_solverGPU->m_scan->executeHost(countsHost, offsetsHost, B3_SOLVER_N_CELLS); //,&sum ); offsetsNative->copyFromHost(offsetsHost); //printf("sum = %d\n",sum); - } else + } + else { // 4. find entries B3_PROFILE("gpuBoundSearch"); - m_data->m_solverGPU->m_search->execute(*m_data->m_solverGPU->m_sortDataBuffer,nContacts,*countsNative,B3_SOLVER_N_CELLS,b3BoundSearchCL::COUNT); - m_data->m_solverGPU->m_scan->execute(*countsNative,*offsetsNative, B3_SOLVER_N_CELLS);//,&sum ); - } - - - + m_data->m_solverGPU->m_search->execute(*m_data->m_solverGPU->m_sortDataBuffer, nContacts, *countsNative, B3_SOLVER_N_CELLS, b3BoundSearchCL::COUNT); + m_data->m_solverGPU->m_scan->execute(*countsNative, *offsetsNative, B3_SOLVER_N_CELLS); //,&sum ); + } if (nContacts) - { // 5. sort constraints by cellIdx + { // 5. sort constraints by cellIdx if (gReorderContactsOnCpu) { B3_PROFILE("cpu m_reorderContactKernel"); @@ -956,7 +838,7 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem b3AlignedObjectArray outContacts; m_data->m_pBufContactOutGPU->copyToHost(inContacts); outContacts.resize(inContacts.size()); - for (int i=0;im_pBufContactOutGPU->getBufferCL() ), - b3BufferInfoCL( m_data->m_solverGPU->m_contactBuffer2->getBufferCL()) - , b3BufferInfoCL( m_data->m_solverGPU->m_sortDataBuffer->getBufferCL()) }; + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(m_data->m_pBufContactOutGPU->getBufferCL()), + b3BufferInfoCL(m_data->m_solverGPU->m_contactBuffer2->getBufferCL()), b3BufferInfoCL(m_data->m_solverGPU->m_sortDataBuffer->getBufferCL())}; - b3LauncherCL launcher(m_data->m_queue,m_data->m_solverGPU->m_reorderContactKernel,"m_reorderContactKernel"); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( cdata ); - launcher.launch1D( nContacts, 64 ); + b3LauncherCL launcher(m_data->m_queue, m_data->m_solverGPU->m_reorderContactKernel, "m_reorderContactKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(cdata); + launcher.launch1D(nContacts, 64); } } - - - - } - } //clFinish(m_data->m_queue); @@ -1008,48 +885,46 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem // printf(",,,\n"); // } - if (nContacts) { - if (gUseCpuCopyConstraints) { - for (int i=0;im_pBufContactOutGPU->copyFromOpenCLArray(*m_data->m_solverGPU->m_contactBuffer2); - // m_data->m_solverGPU->m_contactBuffer2->getBufferCL(); - // m_data->m_pBufContactOutGPU->getBufferCL() + // m_data->m_solverGPU->m_contactBuffer2->getBufferCL(); + // m_data->m_pBufContactOutGPU->getBufferCL() } - - } else + } + else { B3_PROFILE("gpu m_copyConstraintKernel"); - b3Int4 cdata; cdata.x = nContacts; - b3BufferInfoCL bInfo[] = { - b3BufferInfoCL( m_data->m_solverGPU->m_contactBuffer2->getBufferCL() ), - b3BufferInfoCL( m_data->m_pBufContactOutGPU->getBufferCL() ) - }; + b3Int4 cdata; + cdata.x = nContacts; + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(m_data->m_solverGPU->m_contactBuffer2->getBufferCL()), + b3BufferInfoCL(m_data->m_pBufContactOutGPU->getBufferCL())}; - b3LauncherCL launcher(m_data->m_queue, m_data->m_solverGPU->m_copyConstraintKernel,"m_copyConstraintKernel" ); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); - launcher.setConst( cdata ); - launcher.launch1D( nContacts, 64 ); + b3LauncherCL launcher(m_data->m_queue, m_data->m_solverGPU->m_copyConstraintKernel, "m_copyConstraintKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); + launcher.setConst(cdata); + launcher.launch1D(nContacts, 64); //we use the clFinish for proper benchmark/profile clFinish(m_data->m_queue); } } - -// bool compareGPU = false; + // bool compareGPU = false; if (nContacts) { if (!gCpuBatchContacts) { B3_PROFILE("gpu batchContacts"); - maxNumBatches = 250;//250; - m_data->m_solverGPU->batchContacts( m_data->m_pBufContactOutGPU, nContacts, m_data->m_solverGPU->m_numConstraints, m_data->m_solverGPU->m_offsets, csCfg.m_staticIdx ); + maxNumBatches = 250; //250; + m_data->m_solverGPU->batchContacts(m_data->m_pBufContactOutGPU, nContacts, m_data->m_solverGPU->m_numConstraints, m_data->m_solverGPU->m_offsets, csCfg.m_staticIdx); clFinish(m_data->m_queue); - } else + } + else { B3_PROFILE("cpu batchContacts"); static b3AlignedObjectArray cpuContacts; @@ -1070,45 +945,43 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem offsetsNative->copyToHost(offsetsNativeHost); } - - int numNonzeroGrid=0; + int numNonzeroGrid = 0; if (gUseLargeBatches) { m_data->m_batchSizes.resize(B3_MAX_NUM_BATCHES); int totalNumConstraints = cpuContacts.size(); //int simdWidth =numBodies+1;//-1;//64;//-1;//32; - int numBatches = sortConstraintByBatch3( &cpuContacts[0], totalNumConstraints, totalNumConstraints+1,csCfg.m_staticIdx ,numBodies,&m_data->m_batchSizes[0]); // on GPU - maxNumBatches = b3Max(numBatches,maxNumBatches); + int numBatches = sortConstraintByBatch3(&cpuContacts[0], totalNumConstraints, totalNumConstraints + 1, csCfg.m_staticIdx, numBodies, &m_data->m_batchSizes[0]); // on GPU + maxNumBatches = b3Max(numBatches, maxNumBatches); static int globalMaxBatch = 0; - if (maxNumBatches>globalMaxBatch ) + if (maxNumBatches > globalMaxBatch) { - globalMaxBatch = maxNumBatches; - b3Printf("maxNumBatches = %d\n",maxNumBatches); + globalMaxBatch = maxNumBatches; + b3Printf("maxNumBatches = %d\n", maxNumBatches); } - - } else + } + else { - m_data->m_batchSizes.resize(B3_SOLVER_N_CELLS*B3_MAX_NUM_BATCHES); + m_data->m_batchSizes.resize(B3_SOLVER_N_CELLS * B3_MAX_NUM_BATCHES); B3_PROFILE("cpu batch grid"); - for(int i=0; im_batchSizes[i*B3_MAX_NUM_BATCHES]); // on GPU - maxNumBatches = b3Max(numBatches,maxNumBatches); + int simdWidth = numBodies + 1; //-1;//64;//-1;//32; + int numBatches = sortConstraintByBatch3(&cpuContacts[0] + offset, n, simdWidth, csCfg.m_staticIdx, numBodies, &m_data->m_batchSizes[i * B3_MAX_NUM_BATCHES]); // on GPU + maxNumBatches = b3Max(numBatches, maxNumBatches); static int globalMaxBatch = 0; - if (maxNumBatches>globalMaxBatch ) + if (maxNumBatches > globalMaxBatch) { - globalMaxBatch = maxNumBatches; - b3Printf("maxNumBatches = %d\n",maxNumBatches); + globalMaxBatch = maxNumBatches; + b3Printf("maxNumBatches = %d\n", maxNumBatches); } //we use the clFinish for proper benchmark/profile - } } //clFinish(m_data->m_queue); @@ -1117,22 +990,12 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem B3_PROFILE("m_contactBuffer->copyFromHost"); m_data->m_solverGPU->m_contactBuffer2->copyFromHost((b3AlignedObjectArray&)cpuContacts); } - - } - + } } + } + } - - - - - } - - - } - - - //printf("maxNumBatches = %d\n", maxNumBatches); + //printf("maxNumBatches = %d\n", maxNumBatches); if (gUseLargeBatches) { @@ -1140,58 +1003,52 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem { B3_PROFILE("cpu batchContacts"); static b3AlignedObjectArray cpuContacts; -// b3OpenCLArray* contactsIn = m_data->m_solverGPU->m_contactBuffer2; + // b3OpenCLArray* contactsIn = m_data->m_solverGPU->m_contactBuffer2; { B3_PROFILE("copyToHost"); m_data->m_pBufContactOutGPU->copyToHost(cpuContacts); } -// b3OpenCLArray* countsNative = m_data->m_solverGPU->m_numConstraints; -// b3OpenCLArray* offsetsNative = m_data->m_solverGPU->m_offsets; + // b3OpenCLArray* countsNative = m_data->m_solverGPU->m_numConstraints; + // b3OpenCLArray* offsetsNative = m_data->m_solverGPU->m_offsets; - - -// int numNonzeroGrid=0; + // int numNonzeroGrid=0; { m_data->m_batchSizes.resize(B3_MAX_NUM_BATCHES); int totalNumConstraints = cpuContacts.size(); - // int simdWidth =numBodies+1;//-1;//64;//-1;//32; - int numBatches = sortConstraintByBatch3( &cpuContacts[0], totalNumConstraints, totalNumConstraints+1,csCfg.m_staticIdx ,numBodies,&m_data->m_batchSizes[0]); // on GPU - maxNumBatches = b3Max(numBatches,maxNumBatches); + // int simdWidth =numBodies+1;//-1;//64;//-1;//32; + int numBatches = sortConstraintByBatch3(&cpuContacts[0], totalNumConstraints, totalNumConstraints + 1, csCfg.m_staticIdx, numBodies, &m_data->m_batchSizes[0]); // on GPU + maxNumBatches = b3Max(numBatches, maxNumBatches); static int globalMaxBatch = 0; - if (maxNumBatches>globalMaxBatch ) + if (maxNumBatches > globalMaxBatch) { - globalMaxBatch = maxNumBatches; - b3Printf("maxNumBatches = %d\n",maxNumBatches); + globalMaxBatch = maxNumBatches; + b3Printf("maxNumBatches = %d\n", maxNumBatches); } - } { B3_PROFILE("m_contactBuffer->copyFromHost"); m_data->m_solverGPU->m_contactBuffer2->copyFromHost((b3AlignedObjectArray&)cpuContacts); } - - } - + } } if (nContacts) { B3_PROFILE("gpu convertToConstraints"); - m_data->m_solverGPU->convertToConstraints( bodyBuf, - shapeBuf, m_data->m_solverGPU->m_contactBuffer2, - contactConstraintOut, - additionalData, nContacts, - (b3SolverBase::ConstraintCfg&) csCfg ); + m_data->m_solverGPU->convertToConstraints(bodyBuf, + shapeBuf, m_data->m_solverGPU->m_contactBuffer2, + contactConstraintOut, + additionalData, nContacts, + (b3SolverBase::ConstraintCfg&)csCfg); clFinish(m_data->m_queue); } - if (1) { int numIter = 4; - m_data->m_solverGPU->m_nIterations = numIter;//10 + m_data->m_solverGPU->m_nIterations = numIter; //10 if (!gCpuSolveConstraint) { B3_PROFILE("GPU solveContactConstraint"); @@ -1208,32 +1065,30 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem if (gUseLargeBatches) { - solveContactConstraintBatchSizes(m_data->m_bodyBufferGPU, - m_data->m_inertiaBufferGPU, - m_data->m_contactCGPU,0, - nContactOut , - maxNumBatches,numIter,&m_data->m_batchSizes); - } else + solveContactConstraintBatchSizes(m_data->m_bodyBufferGPU, + m_data->m_inertiaBufferGPU, + m_data->m_contactCGPU, 0, + nContactOut, + maxNumBatches, numIter, &m_data->m_batchSizes); + } + else { solveContactConstraint( - m_data->m_bodyBufferGPU, + m_data->m_bodyBufferGPU, m_data->m_inertiaBufferGPU, - m_data->m_contactCGPU,0, - nContactOut , - maxNumBatches,numIter,&m_data->m_batchSizes);//m_data->m_batchSizesGpu); + m_data->m_contactCGPU, 0, + nContactOut, + maxNumBatches, numIter, &m_data->m_batchSizes); //m_data->m_batchSizesGpu); } } else { B3_PROFILE("Host solveContactConstraint"); - m_data->m_solverGPU->solveContactConstraintHost(m_data->m_bodyBufferGPU, m_data->m_inertiaBufferGPU, m_data->m_contactCGPU,0, nContactOut ,maxNumBatches,&m_data->m_batchSizes); + m_data->m_solverGPU->solveContactConstraintHost(m_data->m_bodyBufferGPU, m_data->m_inertiaBufferGPU, m_data->m_contactCGPU, 0, nContactOut, maxNumBatches, &m_data->m_batchSizes); } - - - } - - + } + #if 0 if (0) { @@ -1244,114 +1099,96 @@ void b3GpuPgsContactSolver::solveContacts(int numBodies, cl_mem bodyBuf, cl_mem adl::DeviceUtils::waitForCompletion( m_data->m_deviceCL ); } #endif - - } - + } } - -void b3GpuPgsContactSolver::batchContacts( b3OpenCLArray* contacts, int nContacts, b3OpenCLArray* n, b3OpenCLArray* offsets, int staticIdx ) +void b3GpuPgsContactSolver::batchContacts(b3OpenCLArray* contacts, int nContacts, b3OpenCLArray* n, b3OpenCLArray* offsets, int staticIdx) { } - - - - - - - - - - b3AlignedObjectArray idxBuffer; b3AlignedObjectArray sortData; b3AlignedObjectArray old; - -inline int b3GpuPgsContactSolver::sortConstraintByBatch( b3Contact4* cs, int n, int simdWidth , int staticIdx, int numBodies) +inline int b3GpuPgsContactSolver::sortConstraintByBatch(b3Contact4* cs, int n, int simdWidth, int staticIdx, int numBodies) { - B3_PROFILE("sortConstraintByBatch"); int numIter = 0; - + sortData.resize(n); idxBuffer.resize(n); old.resize(n); - + unsigned int* idxSrc = &idxBuffer[0]; unsigned int* idxDst = &idxBuffer[0]; int nIdxSrc, nIdxDst; - + const int N_FLG = 256; - const int FLG_MASK = N_FLG-1; - unsigned int flg[N_FLG/32]; + const int FLG_MASK = N_FLG - 1; + unsigned int flg[N_FLG / 32]; #if defined(_DEBUG) - for(int i=0; i bodyUsed2; -inline int b3GpuPgsContactSolver::sortConstraintByBatch2( b3Contact4* cs, int numConstraints, int simdWidth , int staticIdx, int numBodies) +inline int b3GpuPgsContactSolver::sortConstraintByBatch2(b3Contact4* cs, int numConstraints, int simdWidth, int staticIdx, int numBodies) { - B3_PROFILE("sortConstraintByBatch2"); - - - bodyUsed2.resize(2*simdWidth); + bodyUsed2.resize(2 * simdWidth); - for (int q=0;q<2*simdWidth;q++) - bodyUsed2[q]=0; + for (int q = 0; q < 2 * simdWidth; q++) + bodyUsed2[q] = 0; int curBodyUsed = 0; int numIter = 0; - + m_data->m_sortData.resize(numConstraints); m_data->m_idxBuffer.resize(numConstraints); m_data->m_old.resize(numConstraints); - + unsigned int* idxSrc = &m_data->m_idxBuffer[0]; - + #if defined(_DEBUG) - for(int i=0; im_sortData[idx].m_key = batchIdx; m_data->m_sortData[idx].m_value = idx; - if (i!=numValidConstraints) + if (i != numValidConstraints) { b3Swap(idxSrc[i], idxSrc[numValidConstraints]); } @@ -1504,20 +1334,19 @@ inline int b3GpuPgsContactSolver::sortConstraintByBatch2( b3Contact4* cs, int nu numValidConstraints++; { nCurrentBatch++; - if( nCurrentBatch == simdWidth ) + if (nCurrentBatch == simdWidth) { nCurrentBatch = 0; - for(int i=0; im_old[0], cs, sizeof(b3Contact4)*numConstraints); - for(int i=0; im_old[0], cs, sizeof(b3Contact4) * numConstraints); + + for (int i = 0; i < numConstraints; i++) { b3Assert(m_data->m_sortData[idxSrc[i]].m_value == idxSrc[i]); int idx = m_data->m_sortData[idxSrc[i]].m_value; cs[i] = m_data->m_old[idx]; } } - + #if defined(_DEBUG) - // debugPrintf( "nBatches: %d\n", batchIdx ); - for(int i=0; i bodyUsed; b3AlignedObjectArray curUsed; - -inline int b3GpuPgsContactSolver::sortConstraintByBatch3( b3Contact4* cs, int numConstraints, int simdWidth , int staticIdx, int numBodies, int* batchSizes) +inline int b3GpuPgsContactSolver::sortConstraintByBatch3(b3Contact4* cs, int numConstraints, int simdWidth, int staticIdx, int numBodies, int* batchSizes) { - B3_PROFILE("sortConstraintByBatch3"); - + static int maxSwaps = 0; int numSwaps = 0; - curUsed.resize(2*simdWidth); + curUsed.resize(2 * simdWidth); static int maxNumConstraints = 0; - if (maxNumConstraintsm_sortData.resize(0); m_data->m_idxBuffer.resize(0); m_data->m_old.resize(0); - - + #if defined(_DEBUG) - for(int i=0; i=B3_MAX_NUM_BATCHES) + if (batchIdx >= B3_MAX_NUM_BATCHES) { b3Error("batchIdx>=B3_MAX_NUM_BATCHES"); b3Assert(0); @@ -1683,26 +1505,25 @@ inline int b3GpuPgsContactSolver::sortConstraintByBatch3( b3Contact4* cs, int nu batchSizes[batchIdx] += nCurrentBatch; - batchIdx ++; - + batchIdx++; } } - + #if defined(_DEBUG) - // debugPrintf( "nBatches: %d\n", batchIdx ); - for(int i=0; i* contacts, int nContacts, b3OpenCLArray* n, b3OpenCLArray* offsets, int staticIdx ); - - inline int sortConstraintByBatch( b3Contact4* cs, int n, int simdWidth , int staticIdx, int numBodies); - inline int sortConstraintByBatch2( b3Contact4* cs, int n, int simdWidth , int staticIdx, int numBodies); - inline int sortConstraintByBatch3( b3Contact4* cs, int n, int simdWidth , int staticIdx, int numBodies, int* batchSizes); - + void batchContacts(b3OpenCLArray* contacts, int nContacts, b3OpenCLArray* n, b3OpenCLArray* offsets, int staticIdx); - - void solveContactConstraintBatchSizes( const b3OpenCLArray* bodyBuf, const b3OpenCLArray* shapeBuf, - b3OpenCLArray* constraint, void* additionalData, int n ,int maxNumBatches, int numIterations, const b3AlignedObjectArray* batchSizes);//const b3OpenCLArray* gpuBatchSizes); + inline int sortConstraintByBatch(b3Contact4* cs, int n, int simdWidth, int staticIdx, int numBodies); + inline int sortConstraintByBatch2(b3Contact4* cs, int n, int simdWidth, int staticIdx, int numBodies); + inline int sortConstraintByBatch3(b3Contact4* cs, int n, int simdWidth, int staticIdx, int numBodies, int* batchSizes); - void solveContactConstraint( const b3OpenCLArray* bodyBuf, const b3OpenCLArray* shapeBuf, - b3OpenCLArray* constraint, void* additionalData, int n ,int maxNumBatches, int numIterations, const b3AlignedObjectArray* batchSizes);//const b3OpenCLArray* gpuBatchSizes); + void solveContactConstraintBatchSizes(const b3OpenCLArray* bodyBuf, const b3OpenCLArray* shapeBuf, + b3OpenCLArray* constraint, void* additionalData, int n, int maxNumBatches, int numIterations, const b3AlignedObjectArray* batchSizes); //const b3OpenCLArray* gpuBatchSizes); + + void solveContactConstraint(const b3OpenCLArray* bodyBuf, const b3OpenCLArray* shapeBuf, + b3OpenCLArray* constraint, void* additionalData, int n, int maxNumBatches, int numIterations, const b3AlignedObjectArray* batchSizes); //const b3OpenCLArray* gpuBatchSizes); public: - - b3GpuPgsContactSolver(cl_context ctx,cl_device_id device, cl_command_queue q,int pairCapacity); + b3GpuPgsContactSolver(cl_context ctx, cl_device_id device, cl_command_queue q, int pairCapacity); virtual ~b3GpuPgsContactSolver(); void solveContacts(int numBodies, cl_mem bodyBuf, cl_mem inertiaBuf, int numContacts, cl_mem contactBuf, const struct b3Config& config, int static0Index); - }; -#endif //B3_GPU_BATCHING_PGS_SOLVER_H - +#endif //B3_GPU_BATCHING_PGS_SOLVER_H diff --git a/src/Bullet3OpenCL/RigidBody/b3GpuRigidBodyPipeline.cpp b/src/Bullet3OpenCL/RigidBody/b3GpuRigidBodyPipeline.cpp index 783e44306..fef33ad1c 100644 --- a/src/Bullet3OpenCL/RigidBody/b3GpuRigidBodyPipeline.cpp +++ b/src/Bullet3OpenCL/RigidBody/b3GpuRigidBodyPipeline.cpp @@ -47,7 +47,7 @@ bool gClearPairsOnGpu = true; #define TEST_OTHER_GPU_SOLVER 1 #ifdef TEST_OTHER_GPU_SOLVER #include "b3GpuJacobiContactSolver.h" -#endif //TEST_OTHER_GPU_SOLVER +#endif //TEST_OTHER_GPU_SOLVER #include "Bullet3Collision/NarrowPhaseCollision/shared/b3RigidBodyData.h" #include "Bullet3Collision/NarrowPhaseCollision/b3Contact4.h" @@ -59,73 +59,68 @@ bool gClearPairsOnGpu = true; #include "Bullet3Collision/NarrowPhaseCollision/b3Config.h" #include "Bullet3OpenCL/Raycast/b3GpuRaycast.h" - #include "Bullet3Dynamics/shared/b3IntegrateTransforms.h" #include "Bullet3OpenCL/RigidBody/b3GpuNarrowPhaseInternalData.h" -b3GpuRigidBodyPipeline::b3GpuRigidBodyPipeline(cl_context ctx,cl_device_id device, cl_command_queue q,class b3GpuNarrowPhase* narrowphase, class b3GpuBroadphaseInterface* broadphaseSap , struct b3DynamicBvhBroadphase* broadphaseDbvt, const b3Config& config) +b3GpuRigidBodyPipeline::b3GpuRigidBodyPipeline(cl_context ctx, cl_device_id device, cl_command_queue q, class b3GpuNarrowPhase* narrowphase, class b3GpuBroadphaseInterface* broadphaseSap, struct b3DynamicBvhBroadphase* broadphaseDbvt, const b3Config& config) { m_data = new b3GpuRigidBodyPipelineInternalData; - m_data->m_constraintUid=0; + m_data->m_constraintUid = 0; m_data->m_config = config; m_data->m_context = ctx; m_data->m_device = device; m_data->m_queue = q; - m_data->m_solver = new b3PgsJacobiSolver(true);//new b3PgsJacobiSolver(true); - m_data->m_gpuSolver = new b3GpuPgsConstraintSolver(ctx,device,q,true);//new b3PgsJacobiSolver(true); - - m_data->m_allAabbsGPU = new b3OpenCLArray(ctx,q,config.m_maxConvexBodies); - m_data->m_overlappingPairsGPU = new b3OpenCLArray(ctx,q,config.m_maxBroadphasePairs); + m_data->m_solver = new b3PgsJacobiSolver(true); //new b3PgsJacobiSolver(true); + m_data->m_gpuSolver = new b3GpuPgsConstraintSolver(ctx, device, q, true); //new b3PgsJacobiSolver(true); - m_data->m_gpuConstraints = new b3OpenCLArray(ctx,q); + m_data->m_allAabbsGPU = new b3OpenCLArray(ctx, q, config.m_maxConvexBodies); + m_data->m_overlappingPairsGPU = new b3OpenCLArray(ctx, q, config.m_maxBroadphasePairs); + + m_data->m_gpuConstraints = new b3OpenCLArray(ctx, q); #ifdef TEST_OTHER_GPU_SOLVER - m_data->m_solver3 = new b3GpuJacobiContactSolver(ctx,device,q,config.m_maxBroadphasePairs); -#endif // TEST_OTHER_GPU_SOLVER - - m_data->m_solver2 = new b3GpuPgsContactSolver(ctx,device,q,config.m_maxBroadphasePairs); + m_data->m_solver3 = new b3GpuJacobiContactSolver(ctx, device, q, config.m_maxBroadphasePairs); +#endif // TEST_OTHER_GPU_SOLVER - m_data->m_raycaster = new b3GpuRaycast(ctx,device,q); + m_data->m_solver2 = new b3GpuPgsContactSolver(ctx, device, q, config.m_maxBroadphasePairs); + + m_data->m_raycaster = new b3GpuRaycast(ctx, device, q); - m_data->m_broadphaseDbvt = broadphaseDbvt; m_data->m_broadphaseSap = broadphaseSap; m_data->m_narrowphase = narrowphase; - m_data->m_gravity.setValue(0.f,-9.8f,0.f); + m_data->m_gravity.setValue(0.f, -9.8f, 0.f); - cl_int errNum=0; + cl_int errNum = 0; { - cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_data->m_context,m_data->m_device,integrateKernelCL,&errNum,"",B3_RIGIDBODY_INTEGRATE_PATH); - b3Assert(errNum==CL_SUCCESS); - m_data->m_integrateTransformsKernel = b3OpenCLUtils::compileCLKernelFromString(m_data->m_context, m_data->m_device,integrateKernelCL, "integrateTransformsKernel",&errNum,prog); - b3Assert(errNum==CL_SUCCESS); + cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_data->m_context, m_data->m_device, integrateKernelCL, &errNum, "", B3_RIGIDBODY_INTEGRATE_PATH); + b3Assert(errNum == CL_SUCCESS); + m_data->m_integrateTransformsKernel = b3OpenCLUtils::compileCLKernelFromString(m_data->m_context, m_data->m_device, integrateKernelCL, "integrateTransformsKernel", &errNum, prog); + b3Assert(errNum == CL_SUCCESS); clReleaseProgram(prog); } { - cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_data->m_context,m_data->m_device,updateAabbsKernelCL,&errNum,"",B3_RIGIDBODY_UPDATEAABB_PATH); - b3Assert(errNum==CL_SUCCESS); - m_data->m_updateAabbsKernel = b3OpenCLUtils::compileCLKernelFromString(m_data->m_context, m_data->m_device,updateAabbsKernelCL, "initializeGpuAabbsFull",&errNum,prog); - b3Assert(errNum==CL_SUCCESS); + cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_data->m_context, m_data->m_device, updateAabbsKernelCL, &errNum, "", B3_RIGIDBODY_UPDATEAABB_PATH); + b3Assert(errNum == CL_SUCCESS); + m_data->m_updateAabbsKernel = b3OpenCLUtils::compileCLKernelFromString(m_data->m_context, m_data->m_device, updateAabbsKernelCL, "initializeGpuAabbsFull", &errNum, prog); + b3Assert(errNum == CL_SUCCESS); - - m_data->m_clearOverlappingPairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_data->m_context, m_data->m_device,updateAabbsKernelCL, "clearOverlappingPairsKernel",&errNum,prog); - b3Assert(errNum==CL_SUCCESS); + m_data->m_clearOverlappingPairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_data->m_context, m_data->m_device, updateAabbsKernelCL, "clearOverlappingPairsKernel", &errNum, prog); + b3Assert(errNum == CL_SUCCESS); clReleaseProgram(prog); } - - } b3GpuRigidBodyPipeline::~b3GpuRigidBodyPipeline() { if (m_data->m_integrateTransformsKernel) clReleaseKernel(m_data->m_integrateTransformsKernel); - + if (m_data->m_updateAabbsKernel) clReleaseKernel(m_data->m_updateAabbsKernel); - + if (m_data->m_clearOverlappingPairsKernel) clReleaseKernel(m_data->m_clearOverlappingPairsKernel); delete m_data->m_raycaster; @@ -136,15 +131,14 @@ b3GpuRigidBodyPipeline::~b3GpuRigidBodyPipeline() #ifdef TEST_OTHER_GPU_SOLVER delete m_data->m_solver3; -#endif //TEST_OTHER_GPU_SOLVER - +#endif //TEST_OTHER_GPU_SOLVER + delete m_data->m_solver2; - - + delete m_data; } -void b3GpuRigidBodyPipeline::reset() +void b3GpuRigidBodyPipeline::reset() { m_data->m_gpuConstraints->resize(0); m_data->m_cpuConstraints.resize(0); @@ -152,30 +146,28 @@ void b3GpuRigidBodyPipeline::reset() m_data->m_allAabbsCPU.resize(0); } -void b3GpuRigidBodyPipeline::addConstraint(b3TypedConstraint* constraint) +void b3GpuRigidBodyPipeline::addConstraint(b3TypedConstraint* constraint) { m_data->m_joints.push_back(constraint); } -void b3GpuRigidBodyPipeline::removeConstraint(b3TypedConstraint* constraint) +void b3GpuRigidBodyPipeline::removeConstraint(b3TypedConstraint* constraint) { m_data->m_joints.remove(constraint); } - - -void b3GpuRigidBodyPipeline::removeConstraintByUid(int uid) +void b3GpuRigidBodyPipeline::removeConstraintByUid(int uid) { m_data->m_gpuSolver->recomputeBatches(); //slow linear search m_data->m_gpuConstraints->copyToHost(m_data->m_cpuConstraints); //remove - for (int i=0;im_cpuConstraints.size();i++) + for (int i = 0; i < m_data->m_cpuConstraints.size(); i++) { if (m_data->m_cpuConstraints[i].m_uid == uid) { //m_data->m_cpuConstraints.remove(m_data->m_cpuConstraints[i]); - m_data->m_cpuConstraints.swap(i,m_data->m_cpuConstraints.size()-1); + m_data->m_cpuConstraints.swap(i, m_data->m_cpuConstraints.size() - 1); m_data->m_cpuConstraints.pop_back(); break; @@ -185,13 +177,13 @@ void b3GpuRigidBodyPipeline::removeConstraintByUid(int uid) if (m_data->m_cpuConstraints.size()) { m_data->m_gpuConstraints->copyFromHost(m_data->m_cpuConstraints); - } else + } + else { m_data->m_gpuConstraints->resize(0); } - } -int b3GpuRigidBodyPipeline::createPoint2PointConstraint(int bodyA, int bodyB, const float* pivotInA, const float* pivotInB,float breakingThreshold) +int b3GpuRigidBodyPipeline::createPoint2PointConstraint(int bodyA, int bodyB, const float* pivotInA, const float* pivotInB, float breakingThreshold) { m_data->m_gpuSolver->recomputeBatches(); b3GpuGenericConstraint c; @@ -200,14 +192,14 @@ int b3GpuRigidBodyPipeline::createPoint2PointConstraint(int bodyA, int bodyB, co c.m_flags = B3_CONSTRAINT_FLAG_ENABLED; c.m_rbA = bodyA; c.m_rbB = bodyB; - c.m_pivotInA.setValue(pivotInA[0],pivotInA[1],pivotInA[2]); - c.m_pivotInB.setValue(pivotInB[0],pivotInB[1],pivotInB[2]); + c.m_pivotInA.setValue(pivotInA[0], pivotInA[1], pivotInA[2]); + c.m_pivotInB.setValue(pivotInB[0], pivotInB[1], pivotInB[2]); c.m_breakingImpulseThreshold = breakingThreshold; c.m_constraintType = B3_GPU_POINT2POINT_CONSTRAINT_TYPE; m_data->m_cpuConstraints.push_back(c); return c.m_uid; } -int b3GpuRigidBodyPipeline::createFixedConstraint(int bodyA, int bodyB, const float* pivotInA, const float* pivotInB, const float* relTargetAB,float breakingThreshold) +int b3GpuRigidBodyPipeline::createFixedConstraint(int bodyA, int bodyB, const float* pivotInA, const float* pivotInB, const float* relTargetAB, float breakingThreshold) { m_data->m_gpuSolver->recomputeBatches(); b3GpuGenericConstraint c; @@ -216,9 +208,9 @@ int b3GpuRigidBodyPipeline::createFixedConstraint(int bodyA, int bodyB, const fl c.m_flags = B3_CONSTRAINT_FLAG_ENABLED; c.m_rbA = bodyA; c.m_rbB = bodyB; - c.m_pivotInA.setValue(pivotInA[0],pivotInA[1],pivotInA[2]); - c.m_pivotInB.setValue(pivotInB[0],pivotInB[1],pivotInB[2]); - c.m_relTargetAB.setValue(relTargetAB[0],relTargetAB[1],relTargetAB[2],relTargetAB[3]); + c.m_pivotInA.setValue(pivotInA[0], pivotInA[1], pivotInA[2]); + c.m_pivotInB.setValue(pivotInB[0], pivotInB[1], pivotInB[2]); + c.m_relTargetAB.setValue(relTargetAB[0], relTargetAB[1], relTargetAB[2], relTargetAB[3]); c.m_breakingImpulseThreshold = breakingThreshold; c.m_constraintType = B3_GPU_FIXED_CONSTRAINT_TYPE; @@ -226,31 +218,28 @@ int b3GpuRigidBodyPipeline::createFixedConstraint(int bodyA, int bodyB, const fl return c.m_uid; } - -void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime) +void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime) { - //update worldspace AABBs from local AABB/worldtransform { B3_PROFILE("setupGpuAabbs"); setupGpuAabbsFull(); } - int numPairs =0; + int numPairs = 0; //compute overlapping pairs { - if (gUseDbvt) { { B3_PROFILE("setAabb"); m_data->m_allAabbsGPU->copyToHost(m_data->m_allAabbsCPU); - for (int i=0;im_allAabbsCPU.size();i++) + for (int i = 0; i < m_data->m_allAabbsCPU.size(); i++) { - b3Vector3 aabbMin=b3MakeVector3(m_data->m_allAabbsCPU[i].m_min[0],m_data->m_allAabbsCPU[i].m_min[1],m_data->m_allAabbsCPU[i].m_min[2]); - b3Vector3 aabbMax=b3MakeVector3(m_data->m_allAabbsCPU[i].m_max[0],m_data->m_allAabbsCPU[i].m_max[1],m_data->m_allAabbsCPU[i].m_max[2]); - m_data->m_broadphaseDbvt->setAabb(i,aabbMin,aabbMax,0); + b3Vector3 aabbMin = b3MakeVector3(m_data->m_allAabbsCPU[i].m_min[0], m_data->m_allAabbsCPU[i].m_min[1], m_data->m_allAabbsCPU[i].m_min[2]); + b3Vector3 aabbMax = b3MakeVector3(m_data->m_allAabbsCPU[i].m_max[0], m_data->m_allAabbsCPU[i].m_max[1], m_data->m_allAabbsCPU[i].m_max[2]); + m_data->m_broadphaseDbvt->setAabb(i, aabbMin, aabbMax, 0); } } @@ -259,13 +248,14 @@ void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime) m_data->m_broadphaseDbvt->calculateOverlappingPairs(); } numPairs = m_data->m_broadphaseDbvt->getOverlappingPairCache()->getNumOverlappingPairs(); - - } else + } + else { if (gUseCalculateOverlappingPairsHost) { m_data->m_broadphaseSap->calculateOverlappingPairsHost(m_data->m_config.m_maxBroadphasePairs); - } else + } + else { m_data->m_broadphaseSap->calculateOverlappingPairs(m_data->m_config.m_maxBroadphasePairs); } @@ -274,24 +264,24 @@ void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime) } //compute contact points -// printf("numPairs=%d\n",numPairs); - - int numContacts = 0; + // printf("numPairs=%d\n",numPairs); + int numContacts = 0; int numBodies = m_data->m_narrowphase->getNumRigidBodies(); if (numPairs) { - cl_mem pairs =0; - cl_mem aabbsWS =0; + cl_mem pairs = 0; + cl_mem aabbsWS = 0; if (gUseDbvt) { B3_PROFILE("m_overlappingPairsGPU->copyFromHost"); m_data->m_overlappingPairsGPU->copyFromHost(m_data->m_broadphaseDbvt->getOverlappingPairCache()->getOverlappingPairArray()); pairs = m_data->m_overlappingPairsGPU->getBufferCL(); aabbsWS = m_data->m_allAabbsGPU->getBufferCL(); - } else + } + else { pairs = m_data->m_broadphaseSap->getOverlappingPairBuffer(); aabbsWS = m_data->m_broadphaseSap->getAabbBufferWS(); @@ -302,31 +292,27 @@ void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime) //mark the contacts for each pair as 'unused' if (numPairs) { - b3OpenCLArray gpuPairs(this->m_data->m_context,m_data->m_queue); - gpuPairs.setFromOpenCLBuffer(pairs,numPairs); + b3OpenCLArray gpuPairs(this->m_data->m_context, m_data->m_queue); + gpuPairs.setFromOpenCLBuffer(pairs, numPairs); if (gClearPairsOnGpu) { - - //b3AlignedObjectArray hostPairs;//just for debugging //gpuPairs.copyToHost(hostPairs); - b3LauncherCL launcher(m_data->m_queue,m_data->m_clearOverlappingPairsKernel,"clearOverlappingPairsKernel"); + b3LauncherCL launcher(m_data->m_queue, m_data->m_clearOverlappingPairsKernel, "clearOverlappingPairsKernel"); launcher.setBuffer(pairs); launcher.setConst(numPairs); launcher.launch1D(numPairs); - //gpuPairs.copyToHost(hostPairs); - - - } else + } + else { b3AlignedObjectArray hostPairs; gpuPairs.copyToHost(hostPairs); - for (int i=0;im_narrowphase->computeContacts(pairs,numPairs,aabbsWS,numBodies); + m_data->m_narrowphase->computeContacts(pairs, numPairs, aabbsWS, numBodies); numContacts = m_data->m_narrowphase->getNumContactsGpu(); if (gUseDbvt) @@ -347,56 +333,54 @@ void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime) if (gDumpContactStats && numContacts) { m_data->m_narrowphase->getContactsGpu(); - + printf("numContacts = %d\n", numContacts); - int totalPoints = 0; + int totalPoints = 0; const b3Contact4* contacts = m_data->m_narrowphase->getContactsCPU(); - for (int i=0;igetNPoints(); } - printf("totalPoints=%d\n",totalPoints); - + printf("totalPoints=%d\n", totalPoints); } } - //convert contact points to contact constraints - + //solve constraints - b3OpenCLArray gpuBodies(m_data->m_context,m_data->m_queue,0,true); - gpuBodies.setFromOpenCLBuffer(m_data->m_narrowphase->getBodiesGpu(),m_data->m_narrowphase->getNumRigidBodies()); - b3OpenCLArray gpuInertias(m_data->m_context,m_data->m_queue,0,true); - gpuInertias.setFromOpenCLBuffer(m_data->m_narrowphase->getBodyInertiasGpu(),m_data->m_narrowphase->getNumRigidBodies()); - b3OpenCLArray gpuContacts(m_data->m_context,m_data->m_queue,0,true); - gpuContacts.setFromOpenCLBuffer(m_data->m_narrowphase->getContactsGpu(),m_data->m_narrowphase->getNumContactsGpu()); + b3OpenCLArray gpuBodies(m_data->m_context, m_data->m_queue, 0, true); + gpuBodies.setFromOpenCLBuffer(m_data->m_narrowphase->getBodiesGpu(), m_data->m_narrowphase->getNumRigidBodies()); + b3OpenCLArray gpuInertias(m_data->m_context, m_data->m_queue, 0, true); + gpuInertias.setFromOpenCLBuffer(m_data->m_narrowphase->getBodyInertiasGpu(), m_data->m_narrowphase->getNumRigidBodies()); + b3OpenCLArray gpuContacts(m_data->m_context, m_data->m_queue, 0, true); + gpuContacts.setFromOpenCLBuffer(m_data->m_narrowphase->getContactsGpu(), m_data->m_narrowphase->getNumContactsGpu()); - int numJoints = m_data->m_joints.size() ? m_data->m_joints.size() : m_data->m_cpuConstraints.size(); + int numJoints = m_data->m_joints.size() ? m_data->m_joints.size() : m_data->m_cpuConstraints.size(); if (useBullet2CpuSolver && numJoints) { - - // b3AlignedObjectArray hostContacts; + // b3AlignedObjectArray hostContacts; //gpuContacts.copyToHost(hostContacts); { - bool useGpu = m_data->m_joints.size()==0; + bool useGpu = m_data->m_joints.size() == 0; -// b3Contact4* contacts = numContacts? &hostContacts[0]: 0; + // b3Contact4* contacts = numContacts? &hostContacts[0]: 0; //m_data->m_solver->solveContacts(m_data->m_narrowphase->getNumBodiesGpu(),&hostBodies[0],&hostInertias[0],numContacts,contacts,numJoints, joints); if (useGpu) { - m_data->m_gpuSolver->solveJoints(m_data->m_narrowphase->getNumRigidBodies(),&gpuBodies,&gpuInertias,numJoints, m_data->m_gpuConstraints); - } else + m_data->m_gpuSolver->solveJoints(m_data->m_narrowphase->getNumRigidBodies(), &gpuBodies, &gpuInertias, numJoints, m_data->m_gpuConstraints); + } + else { b3AlignedObjectArray hostBodies; gpuBodies.copyToHost(hostBodies); b3AlignedObjectArray hostInertias; gpuInertias.copyToHost(hostInertias); - b3TypedConstraint** joints = numJoints? &m_data->m_joints[0] : 0; - m_data->m_solver->solveContacts(m_data->m_narrowphase->getNumRigidBodies(),&hostBodies[0],&hostInertias[0],0,0,numJoints, joints); + b3TypedConstraint** joints = numJoints ? &m_data->m_joints[0] : 0; + m_data->m_solver->solveContacts(m_data->m_narrowphase->getNumRigidBodies(), &hostBodies[0], &hostInertias[0], 0, 0, numJoints, joints); gpuBodies.copyFromHost(hostBodies); } } @@ -404,22 +388,20 @@ void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime) if (numContacts) { - #ifdef TEST_OTHER_GPU_SOLVER - + if (gUseJacobi) { bool useGpu = true; if (useGpu) { - bool forceHost = false; if (forceHost) { b3AlignedObjectArray hostBodies; b3AlignedObjectArray hostInertias; b3AlignedObjectArray hostContacts; - + { B3_PROFILE("copyToHost"); gpuBodies.copyToHost(hostBodies); @@ -429,25 +411,24 @@ void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime) { b3JacobiSolverInfo solverInfo; - m_data->m_solver3->solveGroupHost(&hostBodies[0], &hostInertias[0], hostBodies.size(),&hostContacts[0],hostContacts.size(),solverInfo); - - + m_data->m_solver3->solveGroupHost(&hostBodies[0], &hostInertias[0], hostBodies.size(), &hostContacts[0], hostContacts.size(), solverInfo); } { B3_PROFILE("copyFromHost"); gpuBodies.copyFromHost(hostBodies); } - } else - + } + else { int static0Index = m_data->m_narrowphase->getStatic0Index(); b3JacobiSolverInfo solverInfo; //m_data->m_solver3->solveContacts( >solveGroup(&gpuBodies, &gpuInertias, &gpuContacts,solverInfo); //m_data->m_solver3->solveContacts(m_data->m_narrowphase->getNumBodiesGpu(),&hostBodies[0],&hostInertias[0],numContacts,&hostContacts[0]); - m_data->m_solver3->solveContacts(numBodies, gpuBodies.getBufferCL(),gpuInertias.getBufferCL(),numContacts, gpuContacts.getBufferCL(),m_data->m_config, static0Index); + m_data->m_solver3->solveContacts(numBodies, gpuBodies.getBufferCL(), gpuInertias.getBufferCL(), numContacts, gpuContacts.getBufferCL(), m_data->m_config, static0Index); } - } else + } + else { b3AlignedObjectArray hostBodies; gpuBodies.copyToHost(hostBodies); @@ -460,17 +441,15 @@ void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime) } gpuBodies.copyFromHost(hostBodies); } - - } else -#endif //TEST_OTHER_GPU_SOLVER + } + else +#endif //TEST_OTHER_GPU_SOLVER { - int static0Index = m_data->m_narrowphase->getStatic0Index(); - m_data->m_solver2->solveContacts(numBodies, gpuBodies.getBufferCL(),gpuInertias.getBufferCL(),numContacts, gpuContacts.getBufferCL(),m_data->m_config, static0Index); - + m_data->m_solver2->solveContacts(numBodies, gpuBodies.getBufferCL(), gpuInertias.getBufferCL(), numContacts, gpuContacts.getBufferCL(), m_data->m_config, static0Index); + //m_data->m_solver4->solveContacts(m_data->m_narrowphase->getNumBodiesGpu(), gpuBodies.getBufferCL(), gpuInertias.getBufferCL(), numContacts, gpuContacts.getBufferCL()); - - + /*m_data->m_solver3->solveContactConstraintHost( (b3OpenCLArray*)&gpuBodies, (b3OpenCLArray*)&gpuInertias, @@ -481,11 +460,9 @@ void b3GpuRigidBodyPipeline::stepSimulation(float deltaTime) } integrate(deltaTime); - } - -void b3GpuRigidBodyPipeline::integrate(float timeStep) +void b3GpuRigidBodyPipeline::integrate(float timeStep) { //integrate int numBodies = m_data->m_narrowphase->getNumRigidBodies(); @@ -493,24 +470,25 @@ void b3GpuRigidBodyPipeline::integrate(float timeStep) if (gIntegrateOnCpu) { - if(numBodies) + if (numBodies) { - b3GpuNarrowPhaseInternalData* npData = m_data->m_narrowphase->getInternalData(); + b3GpuNarrowPhaseInternalData* npData = m_data->m_narrowphase->getInternalData(); npData->m_bodyBufferGPU->copyToHost(*npData->m_bodyBufferCPU); b3RigidBodyData_t* bodies = &npData->m_bodyBufferCPU->at(0); - for (int nodeID=0;nodeIDm_gravity); + integrateSingleTransform(bodies, nodeID, timeStep, angularDamp, m_data->m_gravity); } npData->m_bodyBufferGPU->copyFromHost(*npData->m_bodyBufferCPU); } - } else + } + else { - b3LauncherCL launcher(m_data->m_queue,m_data->m_integrateTransformsKernel,"m_integrateTransformsKernel"); + b3LauncherCL launcher(m_data->m_queue, m_data->m_integrateTransformsKernel, "m_integrateTransformsKernel"); launcher.setBuffer(m_data->m_narrowphase->getBodiesGpu()); - + launcher.setConst(numBodies); launcher.setConst(timeStep); launcher.setConst(angularDamp); @@ -519,12 +497,9 @@ void b3GpuRigidBodyPipeline::integrate(float timeStep) } } - - - -void b3GpuRigidBodyPipeline::setupGpuAabbsFull() +void b3GpuRigidBodyPipeline::setupGpuAabbsFull() { - cl_int ciErrNum=0; + cl_int ciErrNum = 0; int numBodies = m_data->m_narrowphase->getNumRigidBodies(); if (!numBodies) @@ -532,34 +507,35 @@ void b3GpuRigidBodyPipeline::setupGpuAabbsFull() if (gCalcWorldSpaceAabbOnCpu) { - if (numBodies) { if (gUseDbvt) { m_data->m_allAabbsCPU.resize(numBodies); m_data->m_narrowphase->readbackAllBodiesToCpu(); - for (int i=0;im_narrowphase->getBodiesCpu(), m_data->m_narrowphase->getCollidablesCpu(), m_data->m_narrowphase->getLocalSpaceAabbsCpu(),&m_data->m_allAabbsCPU[0]); + b3ComputeWorldAabb(i, m_data->m_narrowphase->getBodiesCpu(), m_data->m_narrowphase->getCollidablesCpu(), m_data->m_narrowphase->getLocalSpaceAabbsCpu(), &m_data->m_allAabbsCPU[0]); } m_data->m_allAabbsGPU->copyFromHost(m_data->m_allAabbsCPU); - } else + } + else { m_data->m_broadphaseSap->getAllAabbsCPU().resize(numBodies); m_data->m_narrowphase->readbackAllBodiesToCpu(); - for (int i=0;im_narrowphase->getBodiesCpu(), m_data->m_narrowphase->getCollidablesCpu(), m_data->m_narrowphase->getLocalSpaceAabbsCpu(),&m_data->m_broadphaseSap->getAllAabbsCPU()[0]); + b3ComputeWorldAabb(i, m_data->m_narrowphase->getBodiesCpu(), m_data->m_narrowphase->getCollidablesCpu(), m_data->m_narrowphase->getLocalSpaceAabbsCpu(), &m_data->m_broadphaseSap->getAllAabbsCPU()[0]); } m_data->m_broadphaseSap->getAllAabbsGPU().copyFromHost(m_data->m_broadphaseSap->getAllAabbsCPU()); //m_data->m_broadphaseSap->writeAabbsToGpu(); } } - } else + } + else { //__kernel void initializeGpuAabbsFull( const int numNodes, __global Body* gBodies,__global Collidable* collidables, __global b3AABBCL* plocalShapeAABB, __global b3AABBCL* pAABB) - b3LauncherCL launcher(m_data->m_queue,m_data->m_updateAabbsKernel,"m_updateAabbsKernel"); + b3LauncherCL launcher(m_data->m_queue, m_data->m_updateAabbsKernel, "m_updateAabbsKernel"); launcher.setConst(numBodies); cl_mem bodies = m_data->m_narrowphase->getBodiesGpu(); launcher.setBuffer(bodies); @@ -568,17 +544,18 @@ void b3GpuRigidBodyPipeline::setupGpuAabbsFull() cl_mem localAabbs = m_data->m_narrowphase->getAabbLocalSpaceBufferGpu(); launcher.setBuffer(localAabbs); - cl_mem worldAabbs =0; + cl_mem worldAabbs = 0; if (gUseDbvt) { worldAabbs = m_data->m_allAabbsGPU->getBufferCL(); - } else + } + else { worldAabbs = m_data->m_broadphaseSap->getAabbBufferWS(); } launcher.setBuffer(worldAabbs); launcher.launch1D(numBodies); - + oclCHECKERROR(ciErrNum, CL_SUCCESS); } @@ -595,78 +572,68 @@ void b3GpuRigidBodyPipeline::setupGpuAabbsFull() }; */ - - - - - } - - -cl_mem b3GpuRigidBodyPipeline::getBodyBuffer() +cl_mem b3GpuRigidBodyPipeline::getBodyBuffer() { return m_data->m_narrowphase->getBodiesGpu(); } -int b3GpuRigidBodyPipeline::getNumBodies() const +int b3GpuRigidBodyPipeline::getNumBodies() const { return m_data->m_narrowphase->getNumRigidBodies(); } -void b3GpuRigidBodyPipeline::setGravity(const float* grav) +void b3GpuRigidBodyPipeline::setGravity(const float* grav) { - m_data->m_gravity.setValue(grav[0],grav[1],grav[2]); + m_data->m_gravity.setValue(grav[0], grav[1], grav[2]); } -void b3GpuRigidBodyPipeline::copyConstraintsToHost() +void b3GpuRigidBodyPipeline::copyConstraintsToHost() { m_data->m_gpuConstraints->copyToHost(m_data->m_cpuConstraints); } -void b3GpuRigidBodyPipeline::writeAllInstancesToGpu() +void b3GpuRigidBodyPipeline::writeAllInstancesToGpu() { m_data->m_allAabbsGPU->copyFromHost(m_data->m_allAabbsCPU); m_data->m_gpuConstraints->copyFromHost(m_data->m_cpuConstraints); } - -int b3GpuRigidBodyPipeline::registerPhysicsInstance(float mass, const float* position, const float* orientation, int collidableIndex, int userIndex, bool writeInstanceToGpu) +int b3GpuRigidBodyPipeline::registerPhysicsInstance(float mass, const float* position, const float* orientation, int collidableIndex, int userIndex, bool writeInstanceToGpu) { - - b3Vector3 aabbMin=b3MakeVector3(0,0,0),aabbMax=b3MakeVector3(0,0,0); + b3Vector3 aabbMin = b3MakeVector3(0, 0, 0), aabbMax = b3MakeVector3(0, 0, 0); - - if (collidableIndex>=0) + if (collidableIndex >= 0) { b3SapAabb localAabb = m_data->m_narrowphase->getLocalSpaceAabb(collidableIndex); - b3Vector3 localAabbMin=b3MakeVector3(localAabb.m_min[0],localAabb.m_min[1],localAabb.m_min[2]); - b3Vector3 localAabbMax=b3MakeVector3(localAabb.m_max[0],localAabb.m_max[1],localAabb.m_max[2]); - + b3Vector3 localAabbMin = b3MakeVector3(localAabb.m_min[0], localAabb.m_min[1], localAabb.m_min[2]); + b3Vector3 localAabbMax = b3MakeVector3(localAabb.m_max[0], localAabb.m_max[1], localAabb.m_max[2]); + b3Scalar margin = 0.01f; b3Transform t; t.setIdentity(); - t.setOrigin(b3MakeVector3(position[0],position[1],position[2])); - t.setRotation(b3Quaternion(orientation[0],orientation[1],orientation[2],orientation[3])); - b3TransformAabb(localAabbMin,localAabbMax, margin,t,aabbMin,aabbMax); - } else + t.setOrigin(b3MakeVector3(position[0], position[1], position[2])); + t.setRotation(b3Quaternion(orientation[0], orientation[1], orientation[2], orientation[3])); + b3TransformAabb(localAabbMin, localAabbMax, margin, t, aabbMin, aabbMax); + } + else { b3Error("registerPhysicsInstance using invalid collidableIndex\n"); return -1; } - - + bool writeToGpu = false; int bodyIndex = m_data->m_narrowphase->getNumRigidBodies(); - bodyIndex = m_data->m_narrowphase->registerRigidBody(collidableIndex,mass,position,orientation,&aabbMin.getX(),&aabbMax.getX(),writeToGpu); + bodyIndex = m_data->m_narrowphase->registerRigidBody(collidableIndex, mass, position, orientation, &aabbMin.getX(), &aabbMax.getX(), writeToGpu); - if (bodyIndex>=0) + if (bodyIndex >= 0) { if (gUseDbvt) { - m_data->m_broadphaseDbvt->createProxy(aabbMin,aabbMax,bodyIndex,0,1,1); + m_data->m_broadphaseDbvt->createProxy(aabbMin, aabbMax, bodyIndex, 0, 1, 1); b3SapAabb aabb; - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) { aabb.m_min[i] = aabbMin[i]; aabb.m_max[i] = aabbMax[i]; @@ -677,14 +644,16 @@ int b3GpuRigidBodyPipeline::registerPhysicsInstance(float mass, const float* po { m_data->m_allAabbsGPU->copyFromHost(m_data->m_allAabbsCPU); } - } else + } + else { if (mass) { - m_data->m_broadphaseSap->createProxy(aabbMin,aabbMax,bodyIndex,1,1);//m_dispatcher); - } else + m_data->m_broadphaseSap->createProxy(aabbMin, aabbMax, bodyIndex, 1, 1); //m_dispatcher); + } + else { - m_data->m_broadphaseSap->createLargeProxy(aabbMin,aabbMax,bodyIndex,1,1);//m_dispatcher); + m_data->m_broadphaseSap->createLargeProxy(aabbMin, aabbMax, bodyIndex, 1, 1); //m_dispatcher); } } } @@ -699,10 +668,10 @@ int b3GpuRigidBodyPipeline::registerPhysicsInstance(float mass, const float* po return bodyIndex; } -void b3GpuRigidBodyPipeline::castRays(const b3AlignedObjectArray& rays, b3AlignedObjectArray& hitResults) +void b3GpuRigidBodyPipeline::castRays(const b3AlignedObjectArray& rays, b3AlignedObjectArray& hitResults) { - this->m_data->m_raycaster->castRays(rays,hitResults, - getNumBodies(),this->m_data->m_narrowphase->getBodiesCpu(), - m_data->m_narrowphase->getNumCollidablesGpu(), m_data->m_narrowphase->getCollidablesCpu(), - m_data->m_narrowphase->getInternalData(), m_data->m_broadphaseSap); + this->m_data->m_raycaster->castRays(rays, hitResults, + getNumBodies(), this->m_data->m_narrowphase->getBodiesCpu(), + m_data->m_narrowphase->getNumCollidablesGpu(), m_data->m_narrowphase->getCollidablesCpu(), + m_data->m_narrowphase->getInternalData(), m_data->m_broadphaseSap); } diff --git a/src/Bullet3OpenCL/RigidBody/b3GpuRigidBodyPipeline.h b/src/Bullet3OpenCL/RigidBody/b3GpuRigidBodyPipeline.h index b4eac6841..0e5c6fec1 100644 --- a/src/Bullet3OpenCL/RigidBody/b3GpuRigidBodyPipeline.h +++ b/src/Bullet3OpenCL/RigidBody/b3GpuRigidBodyPipeline.h @@ -25,50 +25,46 @@ subject to the following restrictions: class b3GpuRigidBodyPipeline { protected: - struct b3GpuRigidBodyPipelineInternalData* m_data; + struct b3GpuRigidBodyPipelineInternalData* m_data; int allocateCollidable(); public: - - - b3GpuRigidBodyPipeline(cl_context ctx,cl_device_id device, cl_command_queue q , class b3GpuNarrowPhase* narrowphase, class b3GpuBroadphaseInterface* broadphaseSap, struct b3DynamicBvhBroadphase* broadphaseDbvt, const b3Config& config); + b3GpuRigidBodyPipeline(cl_context ctx, cl_device_id device, cl_command_queue q, class b3GpuNarrowPhase* narrowphase, class b3GpuBroadphaseInterface* broadphaseSap, struct b3DynamicBvhBroadphase* broadphaseDbvt, const b3Config& config); virtual ~b3GpuRigidBodyPipeline(); - void stepSimulation(float deltaTime); - void integrate(float timeStep); - void setupGpuAabbsFull(); + void stepSimulation(float deltaTime); + void integrate(float timeStep); + void setupGpuAabbsFull(); - int registerConvexPolyhedron(class b3ConvexUtility* convex); + int registerConvexPolyhedron(class b3ConvexUtility* convex); //int registerConvexPolyhedron(const float* vertices, int strideInBytes, int numVertices, const float* scaling); //int registerSphereShape(float radius); //int registerPlaneShape(const b3Vector3& planeNormal, float planeConstant); - + //int registerConcaveMesh(b3AlignedObjectArray* vertices, b3AlignedObjectArray* indices, const float* scaling); //int registerCompoundShape(b3AlignedObjectArray* childShapes); - - int registerPhysicsInstance(float mass, const float* position, const float* orientation, int collisionShapeIndex, int userData, bool writeInstanceToGpu); + int registerPhysicsInstance(float mass, const float* position, const float* orientation, int collisionShapeIndex, int userData, bool writeInstanceToGpu); //if you passed "writeInstanceToGpu" false in the registerPhysicsInstance method (for performance) you need to call writeAllInstancesToGpu after all instances are registered - void writeAllInstancesToGpu(); - void copyConstraintsToHost(); - void setGravity(const float* grav); + void writeAllInstancesToGpu(); + void copyConstraintsToHost(); + void setGravity(const float* grav); void reset(); - - int createPoint2PointConstraint(int bodyA, int bodyB, const float* pivotInA, const float* pivotInB,float breakingThreshold); + + int createPoint2PointConstraint(int bodyA, int bodyB, const float* pivotInA, const float* pivotInB, float breakingThreshold); int createFixedConstraint(int bodyA, int bodyB, const float* pivotInA, const float* pivotInB, const float* relTargetAB, float breakingThreshold); void removeConstraintByUid(int uid); - void addConstraint(class b3TypedConstraint* constraint); - void removeConstraint(b3TypedConstraint* constraint); + void addConstraint(class b3TypedConstraint* constraint); + void removeConstraint(b3TypedConstraint* constraint); - void castRays(const b3AlignedObjectArray& rays, b3AlignedObjectArray& hitResults); + void castRays(const b3AlignedObjectArray& rays, b3AlignedObjectArray& hitResults); - cl_mem getBodyBuffer(); - - int getNumBodies() const; + cl_mem getBodyBuffer(); + int getNumBodies() const; }; -#endif //B3_GPU_RIGIDBODY_PIPELINE_H \ No newline at end of file +#endif //B3_GPU_RIGIDBODY_PIPELINE_H \ No newline at end of file diff --git a/src/Bullet3OpenCL/RigidBody/b3GpuRigidBodyPipelineInternalData.h b/src/Bullet3OpenCL/RigidBody/b3GpuRigidBodyPipelineInternalData.h index 5ac92f97d..e0a26fda1 100644 --- a/src/Bullet3OpenCL/RigidBody/b3GpuRigidBodyPipelineInternalData.h +++ b/src/Bullet3OpenCL/RigidBody/b3GpuRigidBodyPipelineInternalData.h @@ -22,52 +22,47 @@ subject to the following restrictions: #include "Bullet3OpenCL/ParallelPrimitives/b3OpenCLArray.h" #include "Bullet3Collision/NarrowPhaseCollision/shared/b3Collidable.h" - #include "Bullet3OpenCL/BroadphaseCollision/b3SapAabb.h" #include "Bullet3Dynamics/ConstraintSolver/b3TypedConstraint.h" #include "Bullet3Collision/NarrowPhaseCollision/b3Config.h" - - #include "Bullet3Collision/BroadPhaseCollision/b3OverlappingPair.h" #include "Bullet3OpenCL/RigidBody/b3GpuGenericConstraint.h" struct b3GpuRigidBodyPipelineInternalData { + cl_context m_context; + cl_device_id m_device; + cl_command_queue m_queue; - cl_context m_context; - cl_device_id m_device; - cl_command_queue m_queue; + cl_kernel m_integrateTransformsKernel; + cl_kernel m_updateAabbsKernel; + cl_kernel m_clearOverlappingPairsKernel; - cl_kernel m_integrateTransformsKernel; - cl_kernel m_updateAabbsKernel; - cl_kernel m_clearOverlappingPairsKernel; - class b3PgsJacobiSolver* m_solver; - + class b3GpuPgsConstraintSolver* m_gpuSolver; class b3GpuPgsContactSolver* m_solver2; class b3GpuJacobiContactSolver* m_solver3; class b3GpuRaycast* m_raycaster; - + class b3GpuBroadphaseInterface* m_broadphaseSap; - + struct b3DynamicBvhBroadphase* m_broadphaseDbvt; - b3OpenCLArray* m_allAabbsGPU; - b3AlignedObjectArray m_allAabbsCPU; - b3OpenCLArray* m_overlappingPairsGPU; + b3OpenCLArray* m_allAabbsGPU; + b3AlignedObjectArray m_allAabbsCPU; + b3OpenCLArray* m_overlappingPairsGPU; b3OpenCLArray* m_gpuConstraints; b3AlignedObjectArray m_cpuConstraints; b3AlignedObjectArray m_joints; - int m_constraintUid; - class b3GpuNarrowPhase* m_narrowphase; - b3Vector3 m_gravity; + int m_constraintUid; + class b3GpuNarrowPhase* m_narrowphase; + b3Vector3 m_gravity; - b3Config m_config; + b3Config m_config; }; -#endif //B3_GPU_RIGIDBODY_PIPELINE_INTERNAL_DATA_H - +#endif //B3_GPU_RIGIDBODY_PIPELINE_INTERNAL_DATA_H diff --git a/src/Bullet3OpenCL/RigidBody/b3GpuSolverBody.h b/src/Bullet3OpenCL/RigidBody/b3GpuSolverBody.h index f2a61801a..db815d9b3 100644 --- a/src/Bullet3OpenCL/RigidBody/b3GpuSolverBody.h +++ b/src/Bullet3OpenCL/RigidBody/b3GpuSolverBody.h @@ -13,11 +13,9 @@ subject to the following restrictions: */ //Originally written by Erwin Coumans - #ifndef B3_GPU_SOLVER_BODY_H #define B3_GPU_SOLVER_BODY_H - #include "Bullet3Common/b3Vector3.h" #include "Bullet3Common/b3Matrix3x3.h" @@ -27,29 +25,27 @@ subject to the following restrictions: ///Until we get other contributions, only use SIMD on Windows, when using Visual Studio 2008 or later, and not double precision #ifdef B3_USE_SSE #define USE_SIMD 1 -#endif // - - +#endif // ///The b3SolverBody is an internal datastructure for the constraint solver. Only necessary data is packed to increase cache coherence/performance. -B3_ATTRIBUTE_ALIGNED16 (struct) b3GpuSolverBody +B3_ATTRIBUTE_ALIGNED16(struct) +b3GpuSolverBody { B3_DECLARE_ALIGNED_ALLOCATOR(); -// b3Transform m_worldTransformUnused; - b3Vector3 m_deltaLinearVelocity; - b3Vector3 m_deltaAngularVelocity; - b3Vector3 m_angularFactor; - b3Vector3 m_linearFactor; - b3Vector3 m_invMass; - b3Vector3 m_pushVelocity; - b3Vector3 m_turnVelocity; - b3Vector3 m_linearVelocity; - b3Vector3 m_angularVelocity; + // b3Transform m_worldTransformUnused; + b3Vector3 m_deltaLinearVelocity; + b3Vector3 m_deltaAngularVelocity; + b3Vector3 m_angularFactor; + b3Vector3 m_linearFactor; + b3Vector3 m_invMass; + b3Vector3 m_pushVelocity; + b3Vector3 m_turnVelocity; + b3Vector3 m_linearVelocity; + b3Vector3 m_angularVelocity; - union - { - void* m_originalBody; - int m_originalBodyIndex; + union { + void* m_originalBody; + int m_originalBodyIndex; }; int padding[3]; @@ -65,44 +61,41 @@ B3_ATTRIBUTE_ALIGNED16 (struct) b3GpuSolverBody return m_worldTransform; } */ - B3_FORCE_INLINE void getVelocityInLocalPointObsolete(const b3Vector3& rel_pos, b3Vector3& velocity ) const + B3_FORCE_INLINE void getVelocityInLocalPointObsolete(const b3Vector3& rel_pos, b3Vector3& velocity) const { if (m_originalBody) - velocity = m_linearVelocity+m_deltaLinearVelocity + (m_angularVelocity+m_deltaAngularVelocity).cross(rel_pos); + velocity = m_linearVelocity + m_deltaLinearVelocity + (m_angularVelocity + m_deltaAngularVelocity).cross(rel_pos); else - velocity.setValue(0,0,0); + velocity.setValue(0, 0, 0); } - B3_FORCE_INLINE void getAngularVelocity(b3Vector3& angVel) const + B3_FORCE_INLINE void getAngularVelocity(b3Vector3 & angVel) const { if (m_originalBody) - angVel =m_angularVelocity+m_deltaAngularVelocity; + angVel = m_angularVelocity + m_deltaAngularVelocity; else - angVel.setValue(0,0,0); + angVel.setValue(0, 0, 0); } - //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position - B3_FORCE_INLINE void applyImpulse(const b3Vector3& linearComponent, const b3Vector3& angularComponent,const b3Scalar impulseMagnitude) + B3_FORCE_INLINE void applyImpulse(const b3Vector3& linearComponent, const b3Vector3& angularComponent, const b3Scalar impulseMagnitude) { if (m_originalBody) { - m_deltaLinearVelocity += linearComponent*impulseMagnitude*m_linearFactor; - m_deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor); + m_deltaLinearVelocity += linearComponent * impulseMagnitude * m_linearFactor; + m_deltaAngularVelocity += angularComponent * (impulseMagnitude * m_angularFactor); } } - B3_FORCE_INLINE void internalApplyPushImpulse(const b3Vector3& linearComponent, const b3Vector3& angularComponent,b3Scalar impulseMagnitude) + B3_FORCE_INLINE void internalApplyPushImpulse(const b3Vector3& linearComponent, const b3Vector3& angularComponent, b3Scalar impulseMagnitude) { if (m_originalBody) { - m_pushVelocity += linearComponent*impulseMagnitude*m_linearFactor; - m_turnVelocity += angularComponent*(impulseMagnitude*m_angularFactor); + m_pushVelocity += linearComponent * impulseMagnitude * m_linearFactor; + m_turnVelocity += angularComponent * (impulseMagnitude * m_angularFactor); } } - - const b3Vector3& getDeltaLinearVelocity() const { return m_deltaLinearVelocity; @@ -113,20 +106,19 @@ B3_ATTRIBUTE_ALIGNED16 (struct) b3GpuSolverBody return m_deltaAngularVelocity; } - const b3Vector3& getPushVelocity() const + const b3Vector3& getPushVelocity() const { return m_pushVelocity; } - const b3Vector3& getTurnVelocity() const + const b3Vector3& getTurnVelocity() const { return m_turnVelocity; } - //////////////////////////////////////////////// ///some internal methods, don't use them - + b3Vector3& internalGetDeltaLinearVelocity() { return m_deltaLinearVelocity; @@ -151,7 +143,7 @@ B3_ATTRIBUTE_ALIGNED16 (struct) b3GpuSolverBody { m_invMass = invMass; } - + b3Vector3& internalGetPushVelocity() { return m_pushVelocity; @@ -162,67 +154,57 @@ B3_ATTRIBUTE_ALIGNED16 (struct) b3GpuSolverBody return m_turnVelocity; } - B3_FORCE_INLINE void internalGetVelocityInLocalPointObsolete(const b3Vector3& rel_pos, b3Vector3& velocity ) const + B3_FORCE_INLINE void internalGetVelocityInLocalPointObsolete(const b3Vector3& rel_pos, b3Vector3& velocity) const { - velocity = m_linearVelocity+m_deltaLinearVelocity + (m_angularVelocity+m_deltaAngularVelocity).cross(rel_pos); + velocity = m_linearVelocity + m_deltaLinearVelocity + (m_angularVelocity + m_deltaAngularVelocity).cross(rel_pos); } - B3_FORCE_INLINE void internalGetAngularVelocity(b3Vector3& angVel) const + B3_FORCE_INLINE void internalGetAngularVelocity(b3Vector3 & angVel) const { - angVel = m_angularVelocity+m_deltaAngularVelocity; + angVel = m_angularVelocity + m_deltaAngularVelocity; } - //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position - B3_FORCE_INLINE void internalApplyImpulse(const b3Vector3& linearComponent, const b3Vector3& angularComponent,const b3Scalar impulseMagnitude) + B3_FORCE_INLINE void internalApplyImpulse(const b3Vector3& linearComponent, const b3Vector3& angularComponent, const b3Scalar impulseMagnitude) { //if (m_originalBody) { - m_deltaLinearVelocity += linearComponent*impulseMagnitude*m_linearFactor; - m_deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor); + m_deltaLinearVelocity += linearComponent * impulseMagnitude * m_linearFactor; + m_deltaAngularVelocity += angularComponent * (impulseMagnitude * m_angularFactor); } } - - - - void writebackVelocity() + void writebackVelocity() { //if (m_originalBody>=0) { - m_linearVelocity +=m_deltaLinearVelocity; + m_linearVelocity += m_deltaLinearVelocity; m_angularVelocity += m_deltaAngularVelocity; - + //m_originalBody->setCompanionId(-1); } } - - void writebackVelocityAndTransform(b3Scalar timeStep, b3Scalar splitImpulseTurnErp) + void writebackVelocityAndTransform(b3Scalar timeStep, b3Scalar splitImpulseTurnErp) { - (void) timeStep; + (void)timeStep; if (m_originalBody) { m_linearVelocity += m_deltaLinearVelocity; m_angularVelocity += m_deltaAngularVelocity; - + //correct the position/orientation based on push/turn recovery b3Transform newTransform; - if (m_pushVelocity[0]!=0.f || m_pushVelocity[1]!=0 || m_pushVelocity[2]!=0 || m_turnVelocity[0]!=0.f || m_turnVelocity[1]!=0 || m_turnVelocity[2]!=0) + if (m_pushVelocity[0] != 0.f || m_pushVelocity[1] != 0 || m_pushVelocity[2] != 0 || m_turnVelocity[0] != 0.f || m_turnVelocity[1] != 0 || m_turnVelocity[2] != 0) { - // b3Quaternion orn = m_worldTransform.getRotation(); -// b3TransformUtil::integrateTransform(m_worldTransform,m_pushVelocity,m_turnVelocity*splitImpulseTurnErp,timeStep,newTransform); -// m_worldTransform = newTransform; + // b3Quaternion orn = m_worldTransform.getRotation(); + // b3TransformUtil::integrateTransform(m_worldTransform,m_pushVelocity,m_turnVelocity*splitImpulseTurnErp,timeStep,newTransform); + // m_worldTransform = newTransform; } //m_worldTransform.setRotation(orn); //m_originalBody->setCompanionId(-1); } } - - - }; -#endif //B3_SOLVER_BODY_H - - +#endif //B3_SOLVER_BODY_H diff --git a/src/Bullet3OpenCL/RigidBody/b3GpuSolverConstraint.h b/src/Bullet3OpenCL/RigidBody/b3GpuSolverConstraint.h index 60d235baa..7d9eea243 100644 --- a/src/Bullet3OpenCL/RigidBody/b3GpuSolverConstraint.h +++ b/src/Bullet3OpenCL/RigidBody/b3GpuSolverConstraint.h @@ -13,11 +13,9 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef B3_GPU_SOLVER_CONSTRAINT_H #define B3_GPU_SOLVER_CONSTRAINT_H - #include "Bullet3Common/b3Vector3.h" #include "Bullet3Common/b3Matrix3x3.h" //#include "b3JacobianEntry.h" @@ -25,58 +23,51 @@ subject to the following restrictions: //#define NO_FRICTION_TANGENTIALS 1 - - ///1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and friction constraints. -B3_ATTRIBUTE_ALIGNED16 (struct) b3GpuSolverConstraint +B3_ATTRIBUTE_ALIGNED16(struct) +b3GpuSolverConstraint { B3_DECLARE_ALIGNED_ALLOCATOR(); - b3Vector3 m_relpos1CrossNormal; - b3Vector3 m_contactNormal; + b3Vector3 m_relpos1CrossNormal; + b3Vector3 m_contactNormal; - b3Vector3 m_relpos2CrossNormal; + b3Vector3 m_relpos2CrossNormal; //b3Vector3 m_contactNormal2;//usually m_contactNormal2 == -m_contactNormal - b3Vector3 m_angularComponentA; - b3Vector3 m_angularComponentB; - - mutable b3Scalar m_appliedPushImpulse; - mutable b3Scalar m_appliedImpulse; + b3Vector3 m_angularComponentA; + b3Vector3 m_angularComponentB; + + mutable b3Scalar m_appliedPushImpulse; + mutable b3Scalar m_appliedImpulse; int m_padding1; int m_padding2; - b3Scalar m_friction; - b3Scalar m_jacDiagABInv; - b3Scalar m_rhs; - b3Scalar m_cfm; - - b3Scalar m_lowerLimit; - b3Scalar m_upperLimit; - b3Scalar m_rhsPenetration; - union - { - void* m_originalContactPoint; - int m_originalConstraintIndex; - b3Scalar m_unusedPadding4; + b3Scalar m_friction; + b3Scalar m_jacDiagABInv; + b3Scalar m_rhs; + b3Scalar m_cfm; + + b3Scalar m_lowerLimit; + b3Scalar m_upperLimit; + b3Scalar m_rhsPenetration; + union { + void* m_originalContactPoint; + int m_originalConstraintIndex; + b3Scalar m_unusedPadding4; }; - int m_overrideNumSolverIterations; - int m_frictionIndex; + int m_overrideNumSolverIterations; + int m_frictionIndex; int m_solverBodyIdA; int m_solverBodyIdB; - - enum b3SolverConstraintType + enum b3SolverConstraintType { B3_SOLVER_CONTACT_1D = 0, B3_SOLVER_FRICTION_1D }; }; -typedef b3AlignedObjectArray b3GpuConstraintArray; - - -#endif //B3_GPU_SOLVER_CONSTRAINT_H - - +typedef b3AlignedObjectArray b3GpuConstraintArray; +#endif //B3_GPU_SOLVER_CONSTRAINT_H diff --git a/src/Bullet3OpenCL/RigidBody/b3Solver.cpp b/src/Bullet3OpenCL/RigidBody/b3Solver.cpp index 20bf6d47c..ccf67da1a 100644 --- a/src/Bullet3OpenCL/RigidBody/b3Solver.cpp +++ b/src/Bullet3OpenCL/RigidBody/b3Solver.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: */ //Originally written by Takahiro Harada - #include "b3Solver.h" ///useNewBatchingKernel is a rewritten kernel using just a single thread of the warp, for experiments @@ -38,7 +37,6 @@ bool gConvertConstraintOnCpu = false; #include "kernels/batchingKernels.h" #include "kernels/batchingKernelsNew.h" - #include "Bullet3OpenCL/ParallelPrimitives/b3LauncherCL.h" #include "Bullet3Common/b3Vector3.h" @@ -48,7 +46,7 @@ struct SolverDebugInfo int m_valInt1; int m_valInt2; int m_valInt3; - + int m_valInt4; int m_valInt5; int m_valInt6; @@ -59,11 +57,10 @@ struct SolverDebugInfo int m_valInt10; int m_valInt11; - int m_valInt12; - int m_valInt13; - int m_valInt14; - int m_valInt15; - + int m_valInt12; + int m_valInt13; + int m_valInt14; + int m_valInt15; float m_val0; float m_val1; @@ -71,9 +68,6 @@ struct SolverDebugInfo float m_val3; }; - - - class SolverDeviceInl { public: @@ -84,101 +78,89 @@ public: }; }; - - b3Solver::b3Solver(cl_context ctx, cl_device_id device, cl_command_queue queue, int pairCapacity) - : - m_context(ctx), - m_device(device), - m_queue(queue), - m_batchSizes(ctx,queue), - m_nIterations(4) + : m_context(ctx), + m_device(device), + m_queue(queue), + m_batchSizes(ctx, queue), + m_nIterations(4) { - m_sort32 = new b3RadixSort32CL(ctx,device,queue); - m_scan = new b3PrefixScanCL(ctx,device,queue,B3_SOLVER_N_CELLS); - m_search = new b3BoundSearchCL(ctx,device,queue,B3_SOLVER_N_CELLS); + m_sort32 = new b3RadixSort32CL(ctx, device, queue); + m_scan = new b3PrefixScanCL(ctx, device, queue, B3_SOLVER_N_CELLS); + m_search = new b3BoundSearchCL(ctx, device, queue, B3_SOLVER_N_CELLS); - const int sortSize = B3NEXTMULTIPLEOF( pairCapacity, 512 ); + const int sortSize = B3NEXTMULTIPLEOF(pairCapacity, 512); - m_sortDataBuffer = new b3OpenCLArray(ctx,queue,sortSize); - m_contactBuffer2 = new b3OpenCLArray(ctx,queue); + m_sortDataBuffer = new b3OpenCLArray(ctx, queue, sortSize); + m_contactBuffer2 = new b3OpenCLArray(ctx, queue); - m_numConstraints = new b3OpenCLArray(ctx,queue,B3_SOLVER_N_CELLS ); + m_numConstraints = new b3OpenCLArray(ctx, queue, B3_SOLVER_N_CELLS); m_numConstraints->resize(B3_SOLVER_N_CELLS); - m_offsets = new b3OpenCLArray( ctx,queue,B3_SOLVER_N_CELLS); + m_offsets = new b3OpenCLArray(ctx, queue, B3_SOLVER_N_CELLS); m_offsets->resize(B3_SOLVER_N_CELLS); const char* additionalMacros = ""; -// const char* srcFileNameForCaching=""; - - + // const char* srcFileNameForCaching=""; cl_int pErrNum; const char* batchKernelSource = batchingKernelsCL; const char* batchKernelNewSource = batchingKernelsNewCL; - + const char* solverSetupSource = solverSetupCL; const char* solverSetup2Source = solverSetup2CL; const char* solveContactSource = solveContactCL; const char* solveFrictionSource = solveFrictionCL; - - - + { - - cl_program solveContactProg= b3OpenCLUtils::compileCLProgramFromString( ctx, device, solveContactSource, &pErrNum,additionalMacros, B3_SOLVER_CONTACT_KERNEL_PATH); + cl_program solveContactProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, solveContactSource, &pErrNum, additionalMacros, B3_SOLVER_CONTACT_KERNEL_PATH); b3Assert(solveContactProg); - - cl_program solveFrictionProg= b3OpenCLUtils::compileCLProgramFromString( ctx, device, solveFrictionSource, &pErrNum,additionalMacros, B3_SOLVER_FRICTION_KERNEL_PATH); + + cl_program solveFrictionProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, solveFrictionSource, &pErrNum, additionalMacros, B3_SOLVER_FRICTION_KERNEL_PATH); b3Assert(solveFrictionProg); - cl_program solverSetup2Prog= b3OpenCLUtils::compileCLProgramFromString( ctx, device, solverSetup2Source, &pErrNum,additionalMacros, B3_SOLVER_SETUP2_KERNEL_PATH); + cl_program solverSetup2Prog = b3OpenCLUtils::compileCLProgramFromString(ctx, device, solverSetup2Source, &pErrNum, additionalMacros, B3_SOLVER_SETUP2_KERNEL_PATH); b3Assert(solverSetup2Prog); - - cl_program solverSetupProg= b3OpenCLUtils::compileCLProgramFromString( ctx, device, solverSetupSource, &pErrNum,additionalMacros, B3_SOLVER_SETUP_KERNEL_PATH); + cl_program solverSetupProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, solverSetupSource, &pErrNum, additionalMacros, B3_SOLVER_SETUP_KERNEL_PATH); b3Assert(solverSetupProg); - - - m_solveFrictionKernel= b3OpenCLUtils::compileCLKernelFromString( ctx, device, solveFrictionSource, "BatchSolveKernelFriction", &pErrNum, solveFrictionProg,additionalMacros ); + + m_solveFrictionKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solveFrictionSource, "BatchSolveKernelFriction", &pErrNum, solveFrictionProg, additionalMacros); b3Assert(m_solveFrictionKernel); - m_solveContactKernel= b3OpenCLUtils::compileCLKernelFromString( ctx, device, solveContactSource, "BatchSolveKernelContact", &pErrNum, solveContactProg,additionalMacros ); + m_solveContactKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solveContactSource, "BatchSolveKernelContact", &pErrNum, solveContactProg, additionalMacros); b3Assert(m_solveContactKernel); - - m_contactToConstraintKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverSetupSource, "ContactToConstraintKernel", &pErrNum, solverSetupProg,additionalMacros ); - b3Assert(m_contactToConstraintKernel); - - m_setSortDataKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "SetSortDataKernel", &pErrNum, solverSetup2Prog,additionalMacros ); - b3Assert(m_setSortDataKernel); - - m_reorderContactKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "ReorderContactKernel", &pErrNum, solverSetup2Prog,additionalMacros ); - b3Assert(m_reorderContactKernel); - - m_copyConstraintKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, solverSetup2Source, "CopyConstraintKernel", &pErrNum, solverSetup2Prog,additionalMacros ); + m_contactToConstraintKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetupSource, "ContactToConstraintKernel", &pErrNum, solverSetupProg, additionalMacros); + b3Assert(m_contactToConstraintKernel); + + m_setSortDataKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "SetSortDataKernel", &pErrNum, solverSetup2Prog, additionalMacros); + b3Assert(m_setSortDataKernel); + + m_reorderContactKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "ReorderContactKernel", &pErrNum, solverSetup2Prog, additionalMacros); + b3Assert(m_reorderContactKernel); + + m_copyConstraintKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, solverSetup2Source, "CopyConstraintKernel", &pErrNum, solverSetup2Prog, additionalMacros); b3Assert(m_copyConstraintKernel); - } { - cl_program batchingProg = b3OpenCLUtils::compileCLProgramFromString( ctx, device, batchKernelSource, &pErrNum,additionalMacros, B3_BATCHING_PATH); + cl_program batchingProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, batchKernelSource, &pErrNum, additionalMacros, B3_BATCHING_PATH); //cl_program batchingProg = b3OpenCLUtils::compileCLProgramFromString( ctx, device, 0, &pErrNum,additionalMacros, B3_BATCHING_PATH,true); b3Assert(batchingProg); - - m_batchingKernel = b3OpenCLUtils::compileCLKernelFromString( ctx, device, batchKernelSource, "CreateBatches", &pErrNum, batchingProg,additionalMacros ); + + m_batchingKernel = b3OpenCLUtils::compileCLKernelFromString(ctx, device, batchKernelSource, "CreateBatches", &pErrNum, batchingProg, additionalMacros); b3Assert(m_batchingKernel); } { - cl_program batchingNewProg = b3OpenCLUtils::compileCLProgramFromString( ctx, device, batchKernelNewSource, &pErrNum,additionalMacros, B3_BATCHING_NEW_PATH); + cl_program batchingNewProg = b3OpenCLUtils::compileCLProgramFromString(ctx, device, batchKernelNewSource, &pErrNum, additionalMacros, B3_BATCHING_NEW_PATH); b3Assert(batchingNewProg); - m_batchingKernelNew = b3OpenCLUtils::compileCLKernelFromString( ctx, device, batchKernelNewSource, "CreateBatchesNew", &pErrNum, batchingNewProg,additionalMacros ); + m_batchingKernelNew = b3OpenCLUtils::compileCLKernelFromString(ctx, device, batchKernelNewSource, "CreateBatchesNew", &pErrNum, batchingNewProg, additionalMacros); //m_batchingKernelNew = b3OpenCLUtils::compileCLKernelFromString( ctx, device, batchKernelNewSource, "CreateBatchesBruteForce", &pErrNum, batchingNewProg,additionalMacros ); b3Assert(m_batchingKernelNew); } } - + b3Solver::~b3Solver() { delete m_offsets; @@ -190,71 +172,68 @@ b3Solver::~b3Solver() delete m_scan; delete m_search; - clReleaseKernel(m_batchingKernel); clReleaseKernel(m_batchingKernelNew); - - clReleaseKernel( m_solveContactKernel); - clReleaseKernel( m_solveFrictionKernel); - clReleaseKernel( m_contactToConstraintKernel); - clReleaseKernel( m_setSortDataKernel); - clReleaseKernel( m_reorderContactKernel); - clReleaseKernel( m_copyConstraintKernel); - + clReleaseKernel(m_solveContactKernel); + clReleaseKernel(m_solveFrictionKernel); + + clReleaseKernel(m_contactToConstraintKernel); + clReleaseKernel(m_setSortDataKernel); + clReleaseKernel(m_reorderContactKernel); + clReleaseKernel(m_copyConstraintKernel); } - - - -template -static -__inline -void solveContact(b3GpuConstraint4& cs, - const b3Vector3& posA, b3Vector3& linVelA, b3Vector3& angVelA, float invMassA, const b3Matrix3x3& invInertiaA, - const b3Vector3& posB, b3Vector3& linVelB, b3Vector3& angVelB, float invMassB, const b3Matrix3x3& invInertiaB, - float maxRambdaDt[4], float minRambdaDt[4]) +template +static __inline void solveContact(b3GpuConstraint4& cs, + const b3Vector3& posA, b3Vector3& linVelA, b3Vector3& angVelA, float invMassA, const b3Matrix3x3& invInertiaA, + const b3Vector3& posB, b3Vector3& linVelB, b3Vector3& angVelB, float invMassB, const b3Matrix3x3& invInertiaB, + float maxRambdaDt[4], float minRambdaDt[4]) { + b3Vector3 dLinVelA; + dLinVelA.setZero(); + b3Vector3 dAngVelA; + dAngVelA.setZero(); + b3Vector3 dLinVelB; + dLinVelB.setZero(); + b3Vector3 dAngVelB; + dAngVelB.setZero(); - b3Vector3 dLinVelA; dLinVelA.setZero(); - b3Vector3 dAngVelA; dAngVelA.setZero(); - b3Vector3 dLinVelB; dLinVelB.setZero(); - b3Vector3 dAngVelB; dAngVelB.setZero(); - - for(int ic=0; ic<4; ic++) + for (int ic = 0; ic < 4; ic++) { // dont necessary because this makes change to 0 - if( cs.m_jacCoeffInv[ic] == 0.f ) continue; + if (cs.m_jacCoeffInv[ic] == 0.f) continue; { b3Vector3 angular0, angular1, linear; b3Vector3 r0 = cs.m_worldPos[ic] - (b3Vector3&)posA; b3Vector3 r1 = cs.m_worldPos[ic] - (b3Vector3&)posB; - setLinearAndAngular( (const b3Vector3 &)cs.m_linear, (const b3Vector3 &)r0, (const b3Vector3 &)r1, &linear, &angular0, &angular1 ); + setLinearAndAngular((const b3Vector3&)cs.m_linear, (const b3Vector3&)r0, (const b3Vector3&)r1, &linear, &angular0, &angular1); - float rambdaDt = calcRelVel((const b3Vector3 &)cs.m_linear,(const b3Vector3 &) -cs.m_linear, angular0, angular1, - linVelA, angVelA, linVelB, angVelB ) + cs.m_b[ic]; + float rambdaDt = calcRelVel((const b3Vector3&)cs.m_linear, (const b3Vector3&)-cs.m_linear, angular0, angular1, + linVelA, angVelA, linVelB, angVelB) + + cs.m_b[ic]; rambdaDt *= cs.m_jacCoeffInv[ic]; { float prevSum = cs.m_appliedRambdaDt[ic]; float updated = prevSum; updated += rambdaDt; - updated = b3Max( updated, minRambdaDt[ic] ); - updated = b3Min( updated, maxRambdaDt[ic] ); + updated = b3Max(updated, minRambdaDt[ic]); + updated = b3Min(updated, maxRambdaDt[ic]); rambdaDt = updated - prevSum; cs.m_appliedRambdaDt[ic] = updated; } - b3Vector3 linImp0 = invMassA*linear*rambdaDt; - b3Vector3 linImp1 = invMassB*(-linear)*rambdaDt; - b3Vector3 angImp0 = (invInertiaA* angular0)*rambdaDt; - b3Vector3 angImp1 = (invInertiaB* angular1)*rambdaDt; + b3Vector3 linImp0 = invMassA * linear * rambdaDt; + b3Vector3 linImp1 = invMassB * (-linear) * rambdaDt; + b3Vector3 angImp0 = (invInertiaA * angular0) * rambdaDt; + b3Vector3 angImp1 = (invInertiaB * angular1) * rambdaDt; #ifdef _WIN32 - b3Assert(_finite(linImp0.getX())); + b3Assert(_finite(linImp0.getX())); b3Assert(_finite(linImp1.getX())); #endif - if( JACOBI ) + if (JACOBI) { dLinVelA += linImp0; dAngVelA += angImp0; @@ -271,92 +250,83 @@ void solveContact(b3GpuConstraint4& cs, } } - if( JACOBI ) + if (JACOBI) { linVelA += dLinVelA; angVelA += dAngVelA; linVelB += dLinVelB; angVelB += dAngVelB; } - } +static __inline void solveFriction(b3GpuConstraint4& cs, + const b3Vector3& posA, b3Vector3& linVelA, b3Vector3& angVelA, float invMassA, const b3Matrix3x3& invInertiaA, + const b3Vector3& posB, b3Vector3& linVelB, b3Vector3& angVelB, float invMassB, const b3Matrix3x3& invInertiaB, + float maxRambdaDt[4], float minRambdaDt[4]) +{ + if (cs.m_fJacCoeffInv[0] == 0 && cs.m_fJacCoeffInv[0] == 0) return; + const b3Vector3& center = (const b3Vector3&)cs.m_center; + b3Vector3 n = -(const b3Vector3&)cs.m_linear; - - - static - __inline - void solveFriction(b3GpuConstraint4& cs, - const b3Vector3& posA, b3Vector3& linVelA, b3Vector3& angVelA, float invMassA, const b3Matrix3x3& invInertiaA, - const b3Vector3& posB, b3Vector3& linVelB, b3Vector3& angVelB, float invMassB, const b3Matrix3x3& invInertiaB, - float maxRambdaDt[4], float minRambdaDt[4]) - { - - if( cs.m_fJacCoeffInv[0] == 0 && cs.m_fJacCoeffInv[0] == 0 ) return; - const b3Vector3& center = (const b3Vector3&)cs.m_center; - - b3Vector3 n = -(const b3Vector3&)cs.m_linear; - - b3Vector3 tangent[2]; -#if 1 - b3PlaneSpace1 (n, tangent[0],tangent[1]); + b3Vector3 tangent[2]; +#if 1 + b3PlaneSpace1(n, tangent[0], tangent[1]); #else - b3Vector3 r = cs.m_worldPos[0]-center; - tangent[0] = cross3( n, r ); - tangent[1] = cross3( tangent[0], n ); - tangent[0] = normalize3( tangent[0] ); - tangent[1] = normalize3( tangent[1] ); + b3Vector3 r = cs.m_worldPos[0] - center; + tangent[0] = cross3(n, r); + tangent[1] = cross3(tangent[0], n); + tangent[0] = normalize3(tangent[0]); + tangent[1] = normalize3(tangent[1]); #endif - b3Vector3 angular0, angular1, linear; - b3Vector3 r0 = center - posA; - b3Vector3 r1 = center - posB; - for(int i=0; i<2; i++) + b3Vector3 angular0, angular1, linear; + b3Vector3 r0 = center - posA; + b3Vector3 r1 = center - posB; + for (int i = 0; i < 2; i++) + { + setLinearAndAngular(tangent[i], r0, r1, &linear, &angular0, &angular1); + float rambdaDt = calcRelVel(linear, -linear, angular0, angular1, + linVelA, angVelA, linVelB, angVelB); + rambdaDt *= cs.m_fJacCoeffInv[i]; + { - setLinearAndAngular( tangent[i], r0, r1, &linear, &angular0, &angular1 ); - float rambdaDt = calcRelVel(linear, -linear, angular0, angular1, - linVelA, angVelA, linVelB, angVelB ); - rambdaDt *= cs.m_fJacCoeffInv[i]; + float prevSum = cs.m_fAppliedRambdaDt[i]; + float updated = prevSum; + updated += rambdaDt; + updated = b3Max(updated, minRambdaDt[i]); + updated = b3Min(updated, maxRambdaDt[i]); + rambdaDt = updated - prevSum; + cs.m_fAppliedRambdaDt[i] = updated; + } - { - float prevSum = cs.m_fAppliedRambdaDt[i]; - float updated = prevSum; - updated += rambdaDt; - updated = b3Max( updated, minRambdaDt[i] ); - updated = b3Min( updated, maxRambdaDt[i] ); - rambdaDt = updated - prevSum; - cs.m_fAppliedRambdaDt[i] = updated; - } - - b3Vector3 linImp0 = invMassA*linear*rambdaDt; - b3Vector3 linImp1 = invMassB*(-linear)*rambdaDt; - b3Vector3 angImp0 = (invInertiaA* angular0)*rambdaDt; - b3Vector3 angImp1 = (invInertiaB* angular1)*rambdaDt; + b3Vector3 linImp0 = invMassA * linear * rambdaDt; + b3Vector3 linImp1 = invMassB * (-linear) * rambdaDt; + b3Vector3 angImp0 = (invInertiaA * angular0) * rambdaDt; + b3Vector3 angImp1 = (invInertiaB * angular1) * rambdaDt; #ifdef _WIN32 - b3Assert(_finite(linImp0.getX())); - b3Assert(_finite(linImp1.getX())); + b3Assert(_finite(linImp0.getX())); + b3Assert(_finite(linImp1.getX())); #endif - linVelA += linImp0; - angVelA += angImp0; - linVelB += linImp1; - angVelB += angImp1; - } - - { // angular damping for point constraint - b3Vector3 ab = ( posB - posA ).normalized(); - b3Vector3 ac = ( center - posA ).normalized(); - if( b3Dot( ab, ac ) > 0.95f || (invMassA == 0.f || invMassB == 0.f)) - { - float angNA = b3Dot( n, angVelA ); - float angNB = b3Dot( n, angVelB ); - - angVelA -= (angNA*0.1f)*n; - angVelB -= (angNB*0.1f)*n; - } - } - + linVelA += linImp0; + angVelA += angImp0; + linVelB += linImp1; + angVelB += angImp1; } + + { // angular damping for point constraint + b3Vector3 ab = (posB - posA).normalized(); + b3Vector3 ac = (center - posA).normalized(); + if (b3Dot(ab, ac) > 0.95f || (invMassA == 0.f || invMassB == 0.f)) + { + float angNA = b3Dot(n, angVelA); + float angNB = b3Dot(n, angVelB); + + angVelA -= (angNA * 0.1f) * n; + angVelB -= (angNB * 0.1f) * n; + } + } +} /* b3AlignedObjectArray& m_bodies; b3AlignedObjectArray& m_shapes; @@ -370,79 +340,69 @@ void solveContact(b3GpuConstraint4& cs, int m_maxNumBatches; */ -struct SolveTask// : public ThreadPool::Task +struct SolveTask // : public ThreadPool::Task { - SolveTask(b3AlignedObjectArray& bodies, b3AlignedObjectArray& shapes, b3AlignedObjectArray& constraints, - int start, int nConstraints,int maxNumBatches,b3AlignedObjectArray* wgUsedBodies, int curWgidx, b3AlignedObjectArray* batchSizes, int cellIndex) - : m_bodies( bodies ), m_shapes( shapes ), - m_constraints( constraints ), - m_batchSizes(batchSizes), - m_cellIndex(cellIndex), - m_curWgidx(curWgidx), - m_start( start ), - m_nConstraints( nConstraints ), - m_solveFriction( true ), - m_maxNumBatches(maxNumBatches) - {} + SolveTask(b3AlignedObjectArray& bodies, b3AlignedObjectArray& shapes, b3AlignedObjectArray& constraints, + int start, int nConstraints, int maxNumBatches, b3AlignedObjectArray* wgUsedBodies, int curWgidx, b3AlignedObjectArray* batchSizes, int cellIndex) + : m_bodies(bodies), m_shapes(shapes), m_constraints(constraints), m_batchSizes(batchSizes), m_cellIndex(cellIndex), m_curWgidx(curWgidx), m_start(start), m_nConstraints(nConstraints), m_solveFriction(true), m_maxNumBatches(maxNumBatches) + { + } - unsigned short int getType(){ return 0; } + unsigned short int getType() { return 0; } void run(int tIdx) { int offset = 0; - for (int ii=0;iiat(m_cellIndex*B3_MAX_NUM_BATCHES+ii); + int numInBatch = m_batchSizes->at(m_cellIndex * B3_MAX_NUM_BATCHES + ii); if (!numInBatch) break; - for (int jj=0;jj( m_constraints[i], (b3Vector3&)bodyA.m_pos, (b3Vector3&)bodyA.m_linVel, (b3Vector3&)bodyA.m_angVel, bodyA.m_invMass, (const b3Matrix3x3 &)m_shapes[aIdx].m_invInertiaWorld, - (b3Vector3&)bodyB.m_pos, (b3Vector3&)bodyB.m_linVel, (b3Vector3&)bodyB.m_angVel, bodyB.m_invMass, (const b3Matrix3x3 &)m_shapes[bIdx].m_invInertiaWorld, - maxRambdaDt, minRambdaDt ); + solveContact(m_constraints[i], (b3Vector3&)bodyA.m_pos, (b3Vector3&)bodyA.m_linVel, (b3Vector3&)bodyA.m_angVel, bodyA.m_invMass, (const b3Matrix3x3&)m_shapes[aIdx].m_invInertiaWorld, + (b3Vector3&)bodyB.m_pos, (b3Vector3&)bodyB.m_linVel, (b3Vector3&)bodyB.m_angVel, bodyB.m_invMass, (const b3Matrix3x3&)m_shapes[bIdx].m_invInertiaWorld, + maxRambdaDt, minRambdaDt); } else { - float maxRambdaDt[4] = {FLT_MAX,FLT_MAX,FLT_MAX,FLT_MAX}; - float minRambdaDt[4] = {0.f,0.f,0.f,0.f}; + float maxRambdaDt[4] = {FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX}; + float minRambdaDt[4] = {0.f, 0.f, 0.f, 0.f}; float sum = 0; - for(int j=0; j<4; j++) + for (int j = 0; j < 4; j++) { - sum +=m_constraints[i].m_appliedRambdaDt[j]; + sum += m_constraints[i].m_appliedRambdaDt[j]; } frictionCoeff = 0.7f; - for(int j=0; j<4; j++) + for (int j = 0; j < 4; j++) { - maxRambdaDt[j] = frictionCoeff*sum; + maxRambdaDt[j] = frictionCoeff * sum; minRambdaDt[j] = -maxRambdaDt[j]; } - solveFriction( m_constraints[i], (b3Vector3&)bodyA.m_pos, (b3Vector3&)bodyA.m_linVel, (b3Vector3&)bodyA.m_angVel, bodyA.m_invMass,(const b3Matrix3x3 &) m_shapes[aIdx].m_invInertiaWorld, - (b3Vector3&)bodyB.m_pos, (b3Vector3&)bodyB.m_linVel, (b3Vector3&)bodyB.m_angVel, bodyB.m_invMass,(const b3Matrix3x3 &) m_shapes[bIdx].m_invInertiaWorld, - maxRambdaDt, minRambdaDt ); - + solveFriction(m_constraints[i], (b3Vector3&)bodyA.m_pos, (b3Vector3&)bodyA.m_linVel, (b3Vector3&)bodyA.m_angVel, bodyA.m_invMass, (const b3Matrix3x3&)m_shapes[aIdx].m_invInertiaWorld, + (b3Vector3&)bodyB.m_pos, (b3Vector3&)bodyB.m_linVel, (b3Vector3&)bodyB.m_angVel, bodyB.m_invMass, (const b3Matrix3x3&)m_shapes[bIdx].m_invInertiaWorld, + maxRambdaDt, minRambdaDt); } } - offset+=numInBatch; - - + offset += numInBatch; } -/* for (int bb=0;bb=0; ic--) for(int ic=0; ic& m_bodies; @@ -508,11 +465,9 @@ struct SolveTask// : public ThreadPool::Task int m_maxNumBatches; }; - -void b3Solver::solveContactConstraintHost( b3OpenCLArray* bodyBuf, b3OpenCLArray* shapeBuf, - b3OpenCLArray* constraint, void* additionalData, int n ,int maxNumBatches,b3AlignedObjectArray* batchSizes) +void b3Solver::solveContactConstraintHost(b3OpenCLArray* bodyBuf, b3OpenCLArray* shapeBuf, + b3OpenCLArray* constraint, void* additionalData, int n, int maxNumBatches, b3AlignedObjectArray* batchSizes) { - #if 0 { int nSplitX = B3_SOLVER_N_SPLIT_X; @@ -571,114 +526,105 @@ void b3Solver::solveContactConstraintHost( b3OpenCLArray* body //printf("------------------------\n"); b3AlignedObjectArray offsetsHost; m_offsets->copyToHost(offsetsHost); - static int frame=0; - bool useBatches=true; + static int frame = 0; + bool useBatches = true; if (useBatches) { - for(int iter=0; iter usedBodies[B3_SOLVER_N_CELLS]; - for (int i=0;i=0;wgIdx--) - for (int wgIdx=0;wgIdx>2); - int remain= (wgIdx%((nSplitX*nSplitY)/4)); - int yIdx = (remain/(nSplitX/2))*2 + ((cellBatch&2)>>1); - int xIdx = (remain%(nSplitX/2))*2 + (cellBatch&1); - int cellIdx = xIdx+yIdx*nSplitX+zIdx*(nSplitX*nSplitY); - - - if( numConstraintsHost[cellIdx] == 0 ) + int zIdx = (wgIdx / ((nSplitX * nSplitY) / 4)) * 2 + ((cellBatch & 4) >> 2); + int remain = (wgIdx % ((nSplitX * nSplitY) / 4)); + int yIdx = (remain / (nSplitX / 2)) * 2 + ((cellBatch & 2) >> 1); + int xIdx = (remain % (nSplitX / 2)) * 2 + (cellBatch & 1); + int cellIdx = xIdx + yIdx * nSplitX + zIdx * (nSplitX * nSplitY); + + if (numConstraintsHost[cellIdx] == 0) continue; //printf("wgIdx %d: xIdx=%d, yIdx=%d, zIdx=%d, cellIdx=%d, cell Batch %d\n",wgIdx,xIdx,yIdx,zIdx,cellIdx,cellBatch); //printf("cell %d has %d constraints\n", cellIdx,numConstraintsHost[cellIdx]); if (zIdx) { - //printf("?\n"); + //printf("?\n"); } - if (iter==0) + if (iter == 0) { //printf("frame=%d, Cell xIdx=%x, yIdx=%d ",frame, xIdx,yIdx); //printf("cellBatch=%d, wgIdx=%d, #constraints in cell=%d\n",cellBatch,wgIdx,numConstraintsHost[cellIdx]); } const int start = offsetsHost[cellIdx]; int numConstraintsInCell = numConstraintsHost[cellIdx]; - // const int end = start + numConstraintsInCell; + // const int end = start + numConstraintsInCell; - SolveTask task( bodyNative, shapeNative, constraintNative, start, numConstraintsInCell ,maxNumBatches,usedBodies,wgIdx,batchSizes,cellIdx); + SolveTask task(bodyNative, shapeNative, constraintNative, start, numConstraintsInCell, maxNumBatches, usedBodies, wgIdx, batchSizes, cellIdx); task.m_solveFriction = false; task.run(0); - } } } - for(int iter=0; iter>2); - int remain= (wgIdx%((nSplitX*nSplitY)/4)); - int yIdx = (remain/(nSplitX/2))*2 + ((cellBatch&2)>>1); - int xIdx = (remain%(nSplitX/2))*2 + (cellBatch&1); - - int cellIdx = xIdx+yIdx*nSplitX+zIdx*(nSplitX*nSplitY); - - if( numConstraintsHost[cellIdx] == 0 ) + int zIdx = (wgIdx / ((nSplitX * nSplitY) / 4)) * 2 + ((cellBatch & 4) >> 2); + int remain = (wgIdx % ((nSplitX * nSplitY) / 4)); + int yIdx = (remain / (nSplitX / 2)) * 2 + ((cellBatch & 2) >> 1); + int xIdx = (remain % (nSplitX / 2)) * 2 + (cellBatch & 1); + + int cellIdx = xIdx + yIdx * nSplitX + zIdx * (nSplitX * nSplitY); + + if (numConstraintsHost[cellIdx] == 0) continue; - + //printf("yIdx=%d\n",yIdx); - + const int start = offsetsHost[cellIdx]; int numConstraintsInCell = numConstraintsHost[cellIdx]; - // const int end = start + numConstraintsInCell; + // const int end = start + numConstraintsInCell; - SolveTask task( bodyNative, shapeNative, constraintNative, start, numConstraintsInCell,maxNumBatches, 0,0,batchSizes,cellIdx); + SolveTask task(bodyNative, shapeNative, constraintNative, start, numConstraintsInCell, maxNumBatches, 0, 0, batchSizes, cellIdx); task.m_solveFriction = true; task.run(0); - } } } - - - } else + } + else { - for(int iter=0; iter* body shapeBuf->copyFromHost(shapeNative); constraint->copyFromHost(constraintNative); frame++; - } void checkConstraintBatch(const b3OpenCLArray* bodyBuf, - const b3OpenCLArray* shapeBuf, - b3OpenCLArray* constraint, - b3OpenCLArray* m_numConstraints, - b3OpenCLArray* m_offsets, - int batchId - ) + const b3OpenCLArray* shapeBuf, + b3OpenCLArray* constraint, + b3OpenCLArray* m_numConstraints, + b3OpenCLArray* m_offsets, + int batchId) { -// b3BufferInfoCL( m_numConstraints->getBufferCL() ), -// b3BufferInfoCL( m_offsets->getBufferCL() ) - + // b3BufferInfoCL( m_numConstraints->getBufferCL() ), + // b3BufferInfoCL( m_offsets->getBufferCL() ) + int cellBatch = batchId; const int nn = B3_SOLVER_N_CELLS; -// int numWorkItems = 64*nn/B3_SOLVER_N_BATCHES; + // int numWorkItems = 64*nn/B3_SOLVER_N_BATCHES; b3AlignedObjectArray gN; m_numConstraints->copyToHost(gN); @@ -712,243 +656,220 @@ void checkConstraintBatch(const b3OpenCLArray* bodyBuf, m_offsets->copyToHost(gOffsets); int nSplitX = B3_SOLVER_N_SPLIT_X; int nSplitY = B3_SOLVER_N_SPLIT_Y; - -// int bIdx = batchId; + + // int bIdx = batchId; b3AlignedObjectArray cpuConstraints; constraint->copyToHost(cpuConstraints); printf("batch = %d\n", batchId); - int numWorkgroups = nn/B3_SOLVER_N_BATCHES; + int numWorkgroups = nn / B3_SOLVER_N_BATCHES; b3AlignedObjectArray usedBodies; - - for (int wgIdx=0;wgIdx>2); - int remain = wgIdx%((nSplitX*nSplitY)); - int yIdx = (remain%(nSplitX/2))*2 + ((cellBatch&2)>>1); - int xIdx = (remain/(nSplitX/2))*2 + (cellBatch&1); + int zIdx = (wgIdx / ((nSplitX * nSplitY)) / 2) * 2 + ((cellBatch & 4) >> 2); + int remain = wgIdx % ((nSplitX * nSplitY)); + int yIdx = (remain % (nSplitX / 2)) * 2 + ((cellBatch & 2) >> 1); + int xIdx = (remain / (nSplitX / 2)) * 2 + (cellBatch & 1); - - int cellIdx = xIdx+yIdx*nSplitX+zIdx*(nSplitX*nSplitY); - printf("cellIdx=%d\n",cellIdx); - if( gN[cellIdx] == 0 ) + int cellIdx = xIdx + yIdx * nSplitX + zIdx * (nSplitX * nSplitY); + printf("cellIdx=%d\n", cellIdx); + if (gN[cellIdx] == 0) continue; const int start = gOffsets[cellIdx]; const int end = start + gN[cellIdx]; - for (int c=start;c* bodyBuf, const b3OpenCLArray* shapeBuf, - b3OpenCLArray* constraint, void* additionalData, int n ,int maxNumBatches) +void b3Solver::solveContactConstraint(const b3OpenCLArray* bodyBuf, const b3OpenCLArray* shapeBuf, + b3OpenCLArray* constraint, void* additionalData, int n, int maxNumBatches) { - - - b3Int4 cdata = b3MakeInt4( n, 0, 0, 0 ); + b3Int4 cdata = b3MakeInt4(n, 0, 0, 0); { - const int nn = B3_SOLVER_N_CELLS; cdata.x = 0; - cdata.y = maxNumBatches;//250; + cdata.y = maxNumBatches; //250; - - int numWorkItems = 64*nn/B3_SOLVER_N_BATCHES; + int numWorkItems = 64 * nn / B3_SOLVER_N_BATCHES; #ifdef DEBUG_ME - SolverDebugInfo* debugInfo = new SolverDebugInfo[numWorkItems]; - adl::b3OpenCLArray gpuDebugInfo(data->m_device,numWorkItems); + SolverDebugInfo* debugInfo = new SolverDebugInfo[numWorkItems]; + adl::b3OpenCLArray gpuDebugInfo(data->m_device, numWorkItems); #endif - - { - B3_PROFILE("m_batchSolveKernel iterations"); - for(int iter=0; itergetBufferCL() ), - b3BufferInfoCL( shapeBuf->getBufferCL() ), - b3BufferInfoCL( constraint->getBufferCL() ), - b3BufferInfoCL( m_numConstraints->getBufferCL() ), - b3BufferInfoCL( m_offsets->getBufferCL() ) + b3BufferInfoCL bInfo[] = { + + b3BufferInfoCL(bodyBuf->getBufferCL()), + b3BufferInfoCL(shapeBuf->getBufferCL()), + b3BufferInfoCL(constraint->getBufferCL()), + b3BufferInfoCL(m_numConstraints->getBufferCL()), + b3BufferInfoCL(m_offsets->getBufferCL()) #ifdef DEBUG_ME - , b3BufferInfoCL(&gpuDebugInfo) + , + b3BufferInfoCL(&gpuDebugInfo) #endif - }; + }; - - - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); //launcher.setConst( cdata.x ); - launcher.setConst( cdata.y ); - launcher.setConst( cdata.z ); - b3Int4 nSplit; + launcher.setConst(cdata.y); + launcher.setConst(cdata.z); + b3Int4 nSplit; nSplit.x = B3_SOLVER_N_SPLIT_X; nSplit.y = B3_SOLVER_N_SPLIT_Y; nSplit.z = B3_SOLVER_N_SPLIT_Z; - launcher.setConst( nSplit ); - launcher.launch1D( numWorkItems, 64 ); + launcher.setConst(nSplit); + launcher.launch1D(numWorkItems, 64); - #else - const char* fileName = "m_batchSolveKernel.bin"; - FILE* f = fopen(fileName,"rb"); - if (f) - { - int sizeInBytes=0; - if (fseek(f, 0, SEEK_END) || (sizeInBytes = ftell(f)) == EOF || fseek(f, 0, SEEK_SET)) - { - printf("error, cannot get file size\n"); - exit(0); - } - - unsigned char* buf = (unsigned char*) malloc(sizeInBytes); - fread(buf,sizeInBytes,1,f); - int serializedBytes = launcher.deserializeArgs(buf, sizeInBytes,m_context); - int num = *(int*)&buf[serializedBytes]; - - launcher.launch1D( num); + const char* fileName = "m_batchSolveKernel.bin"; + FILE* f = fopen(fileName, "rb"); + if (f) + { + int sizeInBytes = 0; + if (fseek(f, 0, SEEK_END) || (sizeInBytes = ftell(f)) == EOF || fseek(f, 0, SEEK_SET)) + { + printf("error, cannot get file size\n"); + exit(0); + } - //this clFinish is for testing on errors - clFinish(m_queue); - } + unsigned char* buf = (unsigned char*)malloc(sizeInBytes); + fread(buf, sizeInBytes, 1, f); + int serializedBytes = launcher.deserializeArgs(buf, sizeInBytes, m_context); + int num = *(int*)&buf[serializedBytes]; + + launcher.launch1D(num); + + //this clFinish is for testing on errors + clFinish(m_queue); + } #endif - #ifdef DEBUG_ME clFinish(m_queue); - gpuDebugInfo.read(debugInfo,numWorkItems); + gpuDebugInfo.read(debugInfo, numWorkItems); clFinish(m_queue); - for (int i=0;i0) + if (debugInfo[i].m_valInt2 > 0) { - printf("debugInfo[i].m_valInt2 = %d\n",i,debugInfo[i].m_valInt2); + printf("debugInfo[i].m_valInt2 = %d\n", i, debugInfo[i].m_valInt2); } - if (debugInfo[i].m_valInt3>0) + if (debugInfo[i].m_valInt3 > 0) { - printf("debugInfo[i].m_valInt3 = %d\n",i,debugInfo[i].m_valInt3); + printf("debugInfo[i].m_valInt3 = %d\n", i, debugInfo[i].m_valInt3); } } -#endif //DEBUG_ME - - +#endif //DEBUG_ME } } - + clFinish(m_queue); - - } cdata.x = 1; - bool applyFriction=true; + bool applyFriction = true; if (applyFriction) - { + { B3_PROFILE("m_batchSolveKernel iterations2"); - for(int iter=0; itergetBufferCL() ), - b3BufferInfoCL( shapeBuf->getBufferCL() ), - b3BufferInfoCL( constraint->getBufferCL() ), - b3BufferInfoCL( m_numConstraints->getBufferCL() ), - b3BufferInfoCL( m_offsets->getBufferCL() ) + b3BufferInfoCL bInfo[] = { + b3BufferInfoCL(bodyBuf->getBufferCL()), + b3BufferInfoCL(shapeBuf->getBufferCL()), + b3BufferInfoCL(constraint->getBufferCL()), + b3BufferInfoCL(m_numConstraints->getBufferCL()), + b3BufferInfoCL(m_offsets->getBufferCL()) #ifdef DEBUG_ME - ,b3BufferInfoCL(&gpuDebugInfo) -#endif //DEBUG_ME + , + b3BufferInfoCL(&gpuDebugInfo) +#endif //DEBUG_ME }; - b3LauncherCL launcher( m_queue, m_solveFrictionKernel,"m_solveFrictionKernel" ); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); + b3LauncherCL launcher(m_queue, m_solveFrictionKernel, "m_solveFrictionKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); //launcher.setConst( cdata.x ); - launcher.setConst( cdata.y ); - launcher.setConst( cdata.z ); - b3Int4 nSplit; + launcher.setConst(cdata.y); + launcher.setConst(cdata.z); + b3Int4 nSplit; nSplit.x = B3_SOLVER_N_SPLIT_X; nSplit.y = B3_SOLVER_N_SPLIT_Y; nSplit.z = B3_SOLVER_N_SPLIT_Z; - launcher.setConst( nSplit ); - - launcher.launch1D( 64*nn/B3_SOLVER_N_BATCHES, 64 ); + launcher.setConst(nSplit); + + launcher.launch1D(64 * nn / B3_SOLVER_N_BATCHES, 64); } } clFinish(m_queue); - } #ifdef DEBUG_ME delete[] debugInfo; -#endif //DEBUG_ME +#endif //DEBUG_ME } - - } -void b3Solver::convertToConstraints( const b3OpenCLArray* bodyBuf, - const b3OpenCLArray* shapeBuf, - b3OpenCLArray* contactsIn, b3OpenCLArray* contactCOut, void* additionalData, - int nContacts, const ConstraintCfg& cfg ) +void b3Solver::convertToConstraints(const b3OpenCLArray* bodyBuf, + const b3OpenCLArray* shapeBuf, + b3OpenCLArray* contactsIn, b3OpenCLArray* contactCOut, void* additionalData, + int nContacts, const ConstraintCfg& cfg) { -// b3OpenCLArray* constraintNative =0; + // b3OpenCLArray* constraintNative =0; contactCOut->resize(nContacts); struct CB { @@ -959,30 +880,28 @@ void b3Solver::convertToConstraints( const b3OpenCLArray* bodyB }; { - CB cdata; cdata.m_nContacts = nContacts; cdata.m_dt = cfg.m_dt; cdata.m_positionDrift = cfg.m_positionDrift; cdata.m_positionConstraintCoeff = cfg.m_positionConstraintCoeff; - if (gConvertConstraintOnCpu) { b3AlignedObjectArray gBodies; - bodyBuf->copyToHost(gBodies); + bodyBuf->copyToHost(gBodies); - b3AlignedObjectArray gContact; - contactsIn->copyToHost(gContact); + b3AlignedObjectArray gContact; + contactsIn->copyToHost(gContact); + + b3AlignedObjectArray gShapes; + shapeBuf->copyToHost(gShapes); + + b3AlignedObjectArray gConstraintOut; + gConstraintOut.resize(nContacts); - b3AlignedObjectArray gShapes; - shapeBuf->copyToHost(gShapes); - - b3AlignedObjectArray gConstraintOut; - gConstraintOut.resize(nContacts); - B3_PROFILE("cpu contactToConstraintKernel"); - for (int gIdx=0;gIdx* bodyB b3ContactConstraint4_t cs; - setConstraint4( posA, linVelA, angVelA, invMassA, invInertiaA, posB, linVelB, angVelB, invMassB, invInertiaB, - &gContact[gIdx], cdata.m_dt, cdata.m_positionDrift, cdata.m_positionConstraintCoeff, - &cs ); - + setConstraint4(posA, linVelA, angVelA, invMassA, invInertiaA, posB, linVelB, angVelB, invMassB, invInertiaB, + &gContact[gIdx], cdata.m_dt, cdata.m_positionDrift, cdata.m_positionConstraintCoeff, + &cs); + cs.m_batchIdx = gContact[gIdx].m_batchIdx; gConstraintOut[gIdx] = (b3GpuConstraint4&)cs; } contactCOut->copyFromHost(gConstraintOut); - - } else + } + else { B3_PROFILE("gpu m_contactToConstraintKernel"); - - b3BufferInfoCL bInfo[] = { b3BufferInfoCL( contactsIn->getBufferCL() ), b3BufferInfoCL( bodyBuf->getBufferCL() ), b3BufferInfoCL( shapeBuf->getBufferCL()), - b3BufferInfoCL( contactCOut->getBufferCL() )}; - b3LauncherCL launcher( m_queue, m_contactToConstraintKernel,"m_contactToConstraintKernel" ); - launcher.setBuffers( bInfo, sizeof(bInfo)/sizeof(b3BufferInfoCL) ); + b3BufferInfoCL bInfo[] = {b3BufferInfoCL(contactsIn->getBufferCL()), b3BufferInfoCL(bodyBuf->getBufferCL()), b3BufferInfoCL(shapeBuf->getBufferCL()), + b3BufferInfoCL(contactCOut->getBufferCL())}; + b3LauncherCL launcher(m_queue, m_contactToConstraintKernel, "m_contactToConstraintKernel"); + launcher.setBuffers(bInfo, sizeof(bInfo) / sizeof(b3BufferInfoCL)); //launcher.setConst( cdata ); - + launcher.setConst(cdata.m_nContacts); launcher.setConst(cdata.m_dt); launcher.setConst(cdata.m_positionDrift); launcher.setConst(cdata.m_positionConstraintCoeff); - - launcher.launch1D( nContacts, 64 ); - clFinish(m_queue); + launcher.launch1D(nContacts, 64); + clFinish(m_queue); } } - - } /* @@ -1115,28 +1030,24 @@ void b3Solver::sortContacts( const b3OpenCLArray* bodyBuf, } */ -void b3Solver::batchContacts( b3OpenCLArray* contacts, int nContacts, b3OpenCLArray* nNative, b3OpenCLArray* offsetsNative, int staticIdx ) +void b3Solver::batchContacts(b3OpenCLArray* contacts, int nContacts, b3OpenCLArray* nNative, b3OpenCLArray* offsetsNative, int staticIdx) { - - int numWorkItems = 64*B3_SOLVER_N_CELLS; + int numWorkItems = 64 * B3_SOLVER_N_CELLS; { B3_PROFILE("batch generation"); - + b3Int4 cdata; cdata.x = nContacts; cdata.y = 0; cdata.z = staticIdx; - #ifdef BATCH_DEBUG - SolverDebugInfo* debugInfo = new SolverDebugInfo[numWorkItems]; - adl::b3OpenCLArray gpuDebugInfo(data->m_device,numWorkItems); - memset(debugInfo,0,sizeof(SolverDebugInfo)*numWorkItems); - gpuDebugInfo.write(debugInfo,numWorkItems); + SolverDebugInfo* debugInfo = new SolverDebugInfo[numWorkItems]; + adl::b3OpenCLArray gpuDebugInfo(data->m_device, numWorkItems); + memset(debugInfo, 0, sizeof(SolverDebugInfo) * numWorkItems); + gpuDebugInfo.write(debugInfo, numWorkItems); #endif - - #if 0 b3BufferInfoCL bInfo[] = { b3BufferInfoCL( contacts->getBufferCL() ), @@ -1148,8 +1059,6 @@ void b3Solver::batchContacts( b3OpenCLArray* contacts, int nContact #endif }; #endif - - { m_batchSizes.resize(nNative->size()); @@ -1157,22 +1066,21 @@ void b3Solver::batchContacts( b3OpenCLArray* contacts, int nContact //b3LauncherCL launcher( m_queue, m_batchingKernel); cl_kernel k = useNewBatchingKernel ? m_batchingKernelNew : m_batchingKernel; - b3LauncherCL launcher( m_queue, k,"*batchingKernel"); - if (!useNewBatchingKernel ) + b3LauncherCL launcher(m_queue, k, "*batchingKernel"); + if (!useNewBatchingKernel) { - launcher.setBuffer( contacts->getBufferCL() ); + launcher.setBuffer(contacts->getBufferCL()); } - launcher.setBuffer( m_contactBuffer2->getBufferCL() ); - launcher.setBuffer( nNative->getBufferCL()); - launcher.setBuffer( offsetsNative->getBufferCL()); - + launcher.setBuffer(m_contactBuffer2->getBufferCL()); + launcher.setBuffer(nNative->getBufferCL()); + launcher.setBuffer(offsetsNative->getBufferCL()); + launcher.setBuffer(m_batchSizes.getBufferCL()); - //launcher.setConst( cdata ); - launcher.setConst(staticIdx); - - launcher.launch1D( numWorkItems, 64 ); + launcher.setConst(staticIdx); + + launcher.launch1D(numWorkItems, 64); //clFinish(m_queue); //b3AlignedObjectArray batchSizesCPU; //m_batchSizes.copyToHost(batchSizesCPU); @@ -1180,46 +1088,41 @@ void b3Solver::batchContacts( b3OpenCLArray* contacts, int nContact } #ifdef BATCH_DEBUG - aaaa - b3Contact4* hostContacts = new b3Contact4[nContacts]; - m_contactBuffer->read(hostContacts,nContacts); + aaaa + b3Contact4* hostContacts = new b3Contact4[nContacts]; + m_contactBuffer->read(hostContacts, nContacts); clFinish(m_queue); - gpuDebugInfo.read(debugInfo,numWorkItems); + gpuDebugInfo.read(debugInfo, numWorkItems); clFinish(m_queue); - for (int i=0;i0) + if (debugInfo[i].m_valInt1 > 0) { printf("catch\n"); } - if (debugInfo[i].m_valInt2>0) + if (debugInfo[i].m_valInt2 > 0) { printf("catch22\n"); } - if (debugInfo[i].m_valInt3>0) + if (debugInfo[i].m_valInt3 > 0) { printf("catch666\n"); } - if (debugInfo[i].m_valInt4>0) + if (debugInfo[i].m_valInt4 > 0) { printf("catch777\n"); } } delete[] debugInfo; -#endif //BATCH_DEBUG - +#endif //BATCH_DEBUG } -// copy buffer to buffer + // copy buffer to buffer //b3Assert(m_contactBuffer->size()==nContacts); //contacts->copyFromOpenCLArray( *m_contactBuffer); //clFinish(m_queue);//needed? - - - } - diff --git a/src/Bullet3OpenCL/RigidBody/b3Solver.h b/src/Bullet3OpenCL/RigidBody/b3Solver.h index b37f2f1be..ee63531d7 100644 --- a/src/Bullet3OpenCL/RigidBody/b3Solver.h +++ b/src/Bullet3OpenCL/RigidBody/b3Solver.h @@ -13,7 +13,6 @@ subject to the following restrictions: */ //Originally written by Takahiro Harada - #ifndef __ADL_SOLVER_H #define __ADL_SOLVER_H @@ -29,98 +28,83 @@ subject to the following restrictions: #include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h" - -#define B3NEXTMULTIPLEOF(num, alignment) (((num)/(alignment) + (((num)%(alignment)==0)?0:1))*(alignment)) +#define B3NEXTMULTIPLEOF(num, alignment) (((num) / (alignment) + (((num) % (alignment) == 0) ? 0 : 1)) * (alignment)) enum { - B3_SOLVER_N_SPLIT_X = 8,//16,//4, - B3_SOLVER_N_SPLIT_Y = 4,//16,//4, - B3_SOLVER_N_SPLIT_Z = 8,//, - B3_SOLVER_N_CELLS = B3_SOLVER_N_SPLIT_X*B3_SOLVER_N_SPLIT_Y*B3_SOLVER_N_SPLIT_Z, - B3_SOLVER_N_BATCHES = 8,//4,//8,//4, + B3_SOLVER_N_SPLIT_X = 8, //16,//4, + B3_SOLVER_N_SPLIT_Y = 4, //16,//4, + B3_SOLVER_N_SPLIT_Z = 8, //, + B3_SOLVER_N_CELLS = B3_SOLVER_N_SPLIT_X * B3_SOLVER_N_SPLIT_Y * B3_SOLVER_N_SPLIT_Z, + B3_SOLVER_N_BATCHES = 8, //4,//8,//4, B3_MAX_NUM_BATCHES = 128, }; class b3SolverBase { - public: - +public: + struct ConstraintCfg + { + ConstraintCfg(float dt = 0.f) : m_positionDrift(0.005f), m_positionConstraintCoeff(0.2f), m_dt(dt), m_staticIdx(-1) {} - struct ConstraintCfg - { - ConstraintCfg( float dt = 0.f ): m_positionDrift( 0.005f ), m_positionConstraintCoeff( 0.2f ), m_dt(dt), m_staticIdx(-1) {} - - float m_positionDrift; - float m_positionConstraintCoeff; - float m_dt; - bool m_enableParallelSolve; - float m_batchCellSize; - int m_staticIdx; - }; - + float m_positionDrift; + float m_positionConstraintCoeff; + float m_dt; + bool m_enableParallelSolve; + float m_batchCellSize; + int m_staticIdx; + }; }; class b3Solver : public b3SolverBase { - public: +public: + cl_context m_context; + cl_device_id m_device; + cl_command_queue m_queue; - cl_context m_context; - cl_device_id m_device; - cl_command_queue m_queue; - + b3OpenCLArray* m_numConstraints; + b3OpenCLArray* m_offsets; + b3OpenCLArray m_batchSizes; - b3OpenCLArray* m_numConstraints; - b3OpenCLArray* m_offsets; - b3OpenCLArray m_batchSizes; - - - int m_nIterations; - cl_kernel m_batchingKernel; - cl_kernel m_batchingKernelNew; - cl_kernel m_solveContactKernel; - cl_kernel m_solveFrictionKernel; - cl_kernel m_contactToConstraintKernel; - cl_kernel m_setSortDataKernel; - cl_kernel m_reorderContactKernel; - cl_kernel m_copyConstraintKernel; + int m_nIterations; + cl_kernel m_batchingKernel; + cl_kernel m_batchingKernelNew; + cl_kernel m_solveContactKernel; + cl_kernel m_solveFrictionKernel; + cl_kernel m_contactToConstraintKernel; + cl_kernel m_setSortDataKernel; + cl_kernel m_reorderContactKernel; + cl_kernel m_copyConstraintKernel; - class b3RadixSort32CL* m_sort32; - class b3BoundSearchCL* m_search; - class b3PrefixScanCL* m_scan; + class b3RadixSort32CL* m_sort32; + class b3BoundSearchCL* m_search; + class b3PrefixScanCL* m_scan; - b3OpenCLArray* m_sortDataBuffer; - b3OpenCLArray* m_contactBuffer2; + b3OpenCLArray* m_sortDataBuffer; + b3OpenCLArray* m_contactBuffer2; - enum - { - DYNAMIC_CONTACT_ALLOCATION_THRESHOLD = 2000000, - }; + enum + { + DYNAMIC_CONTACT_ALLOCATION_THRESHOLD = 2000000, + }; - + b3Solver(cl_context ctx, cl_device_id device, cl_command_queue queue, int pairCapacity); - - b3Solver(cl_context ctx, cl_device_id device, cl_command_queue queue, int pairCapacity); + virtual ~b3Solver(); - virtual ~b3Solver(); - - void solveContactConstraint( const b3OpenCLArray* bodyBuf, const b3OpenCLArray* inertiaBuf, - b3OpenCLArray* constraint, void* additionalData, int n ,int maxNumBatches); + void solveContactConstraint(const b3OpenCLArray* bodyBuf, const b3OpenCLArray* inertiaBuf, + b3OpenCLArray* constraint, void* additionalData, int n, int maxNumBatches); - void solveContactConstraintHost( b3OpenCLArray* bodyBuf, b3OpenCLArray* shapeBuf, - b3OpenCLArray* constraint, void* additionalData, int n ,int maxNumBatches, b3AlignedObjectArray* batchSizes); + void solveContactConstraintHost(b3OpenCLArray* bodyBuf, b3OpenCLArray* shapeBuf, + b3OpenCLArray* constraint, void* additionalData, int n, int maxNumBatches, b3AlignedObjectArray* batchSizes); + void convertToConstraints(const b3OpenCLArray* bodyBuf, + const b3OpenCLArray* shapeBuf, + b3OpenCLArray* contactsIn, b3OpenCLArray* contactCOut, void* additionalData, + int nContacts, const ConstraintCfg& cfg); - void convertToConstraints( const b3OpenCLArray* bodyBuf, - const b3OpenCLArray* shapeBuf, - b3OpenCLArray* contactsIn, b3OpenCLArray* contactCOut, void* additionalData, - int nContacts, const ConstraintCfg& cfg ); - - void batchContacts( b3OpenCLArray* contacts, int nContacts, b3OpenCLArray* n, b3OpenCLArray* offsets, int staticIdx ); - + void batchContacts(b3OpenCLArray* contacts, int nContacts, b3OpenCLArray* n, b3OpenCLArray* offsets, int staticIdx); }; - - - -#endif //__ADL_SOLVER_H +#endif //__ADL_SOLVER_H diff --git a/src/Bullet3OpenCL/RigidBody/kernels/batchingKernels.h b/src/Bullet3OpenCL/RigidBody/kernels/batchingKernels.h index 150eedc94..7c73c96ba 100644 --- a/src/Bullet3OpenCL/RigidBody/kernels/batchingKernels.h +++ b/src/Bullet3OpenCL/RigidBody/kernels/batchingKernels.h @@ -1,388 +1,387 @@ //this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project -static const char* batchingKernelsCL= \ -"/*\n" -"Copyright (c) 2012 Advanced Micro Devices, Inc. \n" -"This software is provided 'as-is', without any express or implied warranty.\n" -"In no event will the authors be held liable for any damages arising from the use of this software.\n" -"Permission is granted to anyone to use this software for any purpose, \n" -"including commercial applications, and to alter it and redistribute it freely, \n" -"subject to the following restrictions:\n" -"1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" -"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" -"3. This notice may not be removed or altered from any source distribution.\n" -"*/\n" -"//Originally written by Takahiro Harada\n" -"#ifndef B3_CONTACT4DATA_H\n" -"#define B3_CONTACT4DATA_H\n" -"#ifndef B3_FLOAT4_H\n" -"#define B3_FLOAT4_H\n" -"#ifndef B3_PLATFORM_DEFINITIONS_H\n" -"#define B3_PLATFORM_DEFINITIONS_H\n" -"struct MyTest\n" -"{\n" -" int bla;\n" -"};\n" -"#ifdef __cplusplus\n" -"#else\n" -"//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n" -"#define B3_LARGE_FLOAT 1e18f\n" -"#define B3_INFINITY 1e18f\n" -"#define b3Assert(a)\n" -"#define b3ConstArray(a) __global const a*\n" -"#define b3AtomicInc atomic_inc\n" -"#define b3AtomicAdd atomic_add\n" -"#define b3Fabs fabs\n" -"#define b3Sqrt native_sqrt\n" -"#define b3Sin native_sin\n" -"#define b3Cos native_cos\n" -"#define B3_STATIC\n" -"#endif\n" -"#endif\n" -"#ifdef __cplusplus\n" -"#else\n" -" typedef float4 b3Float4;\n" -" #define b3Float4ConstArg const b3Float4\n" -" #define b3MakeFloat4 (float4)\n" -" float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" -" {\n" -" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" -" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" -" return dot(a1, b1);\n" -" }\n" -" b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" -" {\n" -" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" -" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" -" return cross(a1, b1);\n" -" }\n" -" #define b3MinFloat4 min\n" -" #define b3MaxFloat4 max\n" -" #define b3Normalized(a) normalize(a)\n" -"#endif \n" -" \n" -"inline bool b3IsAlmostZero(b3Float4ConstArg v)\n" -"{\n" -" if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" -" return false;\n" -" return true;\n" -"}\n" -"inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" -"{\n" -" float maxDot = -B3_INFINITY;\n" -" int i = 0;\n" -" int ptIndex = -1;\n" -" for( i = 0; i < vecLen; i++ )\n" -" {\n" -" float dot = b3Dot3F4(vecArray[i],vec);\n" -" \n" -" if( dot > maxDot )\n" -" {\n" -" maxDot = dot;\n" -" ptIndex = i;\n" -" }\n" -" }\n" -" b3Assert(ptIndex>=0);\n" -" if (ptIndex<0)\n" -" {\n" -" ptIndex = 0;\n" -" }\n" -" *dotOut = maxDot;\n" -" return ptIndex;\n" -"}\n" -"#endif //B3_FLOAT4_H\n" -"typedef struct b3Contact4Data b3Contact4Data_t;\n" -"struct b3Contact4Data\n" -"{\n" -" b3Float4 m_worldPosB[4];\n" -"// b3Float4 m_localPosA[4];\n" -"// b3Float4 m_localPosB[4];\n" -" b3Float4 m_worldNormalOnB; // w: m_nPoints\n" -" unsigned short m_restituitionCoeffCmp;\n" -" unsigned short m_frictionCoeffCmp;\n" -" int m_batchIdx;\n" -" int m_bodyAPtrAndSignBit;//x:m_bodyAPtr, y:m_bodyBPtr\n" -" int m_bodyBPtrAndSignBit;\n" -" int m_childIndexA;\n" -" int m_childIndexB;\n" -" int m_unused1;\n" -" int m_unused2;\n" -"};\n" -"inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact)\n" -"{\n" -" return (int)contact->m_worldNormalOnB.w;\n" -"};\n" -"inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints)\n" -"{\n" -" contact->m_worldNormalOnB.w = (float)numPoints;\n" -"};\n" -"#endif //B3_CONTACT4DATA_H\n" -"#pragma OPENCL EXTENSION cl_amd_printf : enable\n" -"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n" -"#ifdef cl_ext_atomic_counters_32\n" -"#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n" -"#else\n" -"#define counter32_t volatile __global int*\n" -"#endif\n" -"typedef unsigned int u32;\n" -"typedef unsigned short u16;\n" -"typedef unsigned char u8;\n" -"#define GET_GROUP_IDX get_group_id(0)\n" -"#define GET_LOCAL_IDX get_local_id(0)\n" -"#define GET_GLOBAL_IDX get_global_id(0)\n" -"#define GET_GROUP_SIZE get_local_size(0)\n" -"#define GET_NUM_GROUPS get_num_groups(0)\n" -"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" -"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" -"#define AtomInc(x) atom_inc(&(x))\n" -"#define AtomInc1(x, out) out = atom_inc(&(x))\n" -"#define AppendInc(x, out) out = atomic_inc(x)\n" -"#define AtomAdd(x, value) atom_add(&(x), value)\n" -"#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n" -"#define AtomXhg(x, value) atom_xchg ( &(x), value )\n" -"#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n" -"#define make_float4 (float4)\n" -"#define make_float2 (float2)\n" -"#define make_uint4 (uint4)\n" -"#define make_int4 (int4)\n" -"#define make_uint2 (uint2)\n" -"#define make_int2 (int2)\n" -"#define max2 max\n" -"#define min2 min\n" -"#define WG_SIZE 64\n" -"typedef struct \n" -"{\n" -" int m_n;\n" -" int m_start;\n" -" int m_staticIdx;\n" -" int m_paddings[1];\n" -"} ConstBuffer;\n" -"typedef struct \n" -"{\n" -" int m_a;\n" -" int m_b;\n" -" u32 m_idx;\n" -"}Elem;\n" -"#define STACK_SIZE (WG_SIZE*10)\n" -"//#define STACK_SIZE (WG_SIZE)\n" -"#define RING_SIZE 1024\n" -"#define RING_SIZE_MASK (RING_SIZE-1)\n" -"#define CHECK_SIZE (WG_SIZE)\n" -"#define GET_RING_CAPACITY (RING_SIZE - ldsRingEnd)\n" -"#define RING_END ldsTmp\n" -"u32 readBuf(__local u32* buff, int idx)\n" -"{\n" -" idx = idx % (32*CHECK_SIZE);\n" -" int bitIdx = idx%32;\n" -" int bufIdx = idx/32;\n" -" return buff[bufIdx] & (1<> bitIdx)&1) == 0;\n" -"}\n" -"// batching on the GPU\n" -"__kernel void CreateBatches( __global const struct b3Contact4Data* gConstraints, __global struct b3Contact4Data* gConstraintsOut,\n" -" __global const u32* gN, __global const u32* gStart, __global int* batchSizes, \n" -" int m_staticIdx )\n" -"{\n" -" __local u32 ldsStackIdx[STACK_SIZE];\n" -" __local u32 ldsStackEnd;\n" -" __local Elem ldsRingElem[RING_SIZE];\n" -" __local u32 ldsRingEnd;\n" -" __local u32 ldsTmp;\n" -" __local u32 ldsCheckBuffer[CHECK_SIZE];\n" -" __local u32 ldsFixedBuffer[CHECK_SIZE];\n" -" __local u32 ldsGEnd;\n" -" __local u32 ldsDstEnd;\n" -" int wgIdx = GET_GROUP_IDX;\n" -" int lIdx = GET_LOCAL_IDX;\n" -" \n" -" const int m_n = gN[wgIdx];\n" -" const int m_start = gStart[wgIdx];\n" -" \n" -" if( lIdx == 0 )\n" -" {\n" -" ldsRingEnd = 0;\n" -" ldsGEnd = 0;\n" -" ldsStackEnd = 0;\n" -" ldsDstEnd = m_start;\n" -" }\n" -" \n" -" \n" -" \n" -"// while(1)\n" -"//was 250\n" -" int ie=0;\n" -" int maxBatch = 0;\n" -" for(ie=0; ie<50; ie++)\n" -" {\n" -" ldsFixedBuffer[lIdx] = 0;\n" -" for(int giter=0; giter<4; giter++)\n" -" {\n" -" int ringCap = GET_RING_CAPACITY;\n" -" \n" -" // 1. fill ring\n" -" if( ldsGEnd < m_n )\n" -" {\n" -" while( ringCap > WG_SIZE )\n" -" {\n" -" if( ldsGEnd >= m_n ) break;\n" -" if( lIdx < ringCap - WG_SIZE )\n" -" {\n" -" int srcIdx;\n" -" AtomInc1( ldsGEnd, srcIdx );\n" -" if( srcIdx < m_n )\n" -" {\n" -" int dstIdx;\n" -" AtomInc1( ldsRingEnd, dstIdx );\n" -" \n" -" int a = gConstraints[m_start+srcIdx].m_bodyAPtrAndSignBit;\n" -" int b = gConstraints[m_start+srcIdx].m_bodyBPtrAndSignBit;\n" -" ldsRingElem[dstIdx].m_a = (a>b)? b:a;\n" -" ldsRingElem[dstIdx].m_b = (a>b)? a:b;\n" -" ldsRingElem[dstIdx].m_idx = srcIdx;\n" -" }\n" -" }\n" -" ringCap = GET_RING_CAPACITY;\n" -" }\n" -" }\n" -" GROUP_LDS_BARRIER;\n" -" \n" -" // 2. fill stack\n" -" __local Elem* dst = ldsRingElem;\n" -" if( lIdx == 0 ) RING_END = 0;\n" -" int srcIdx=lIdx;\n" -" int end = ldsRingEnd;\n" -" {\n" -" for(int ii=0; ii1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" + " return false;\n" + " return true;\n" + "}\n" + "inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" + "{\n" + " float maxDot = -B3_INFINITY;\n" + " int i = 0;\n" + " int ptIndex = -1;\n" + " for( i = 0; i < vecLen; i++ )\n" + " {\n" + " float dot = b3Dot3F4(vecArray[i],vec);\n" + " \n" + " if( dot > maxDot )\n" + " {\n" + " maxDot = dot;\n" + " ptIndex = i;\n" + " }\n" + " }\n" + " b3Assert(ptIndex>=0);\n" + " if (ptIndex<0)\n" + " {\n" + " ptIndex = 0;\n" + " }\n" + " *dotOut = maxDot;\n" + " return ptIndex;\n" + "}\n" + "#endif //B3_FLOAT4_H\n" + "typedef struct b3Contact4Data b3Contact4Data_t;\n" + "struct b3Contact4Data\n" + "{\n" + " b3Float4 m_worldPosB[4];\n" + "// b3Float4 m_localPosA[4];\n" + "// b3Float4 m_localPosB[4];\n" + " b3Float4 m_worldNormalOnB; // w: m_nPoints\n" + " unsigned short m_restituitionCoeffCmp;\n" + " unsigned short m_frictionCoeffCmp;\n" + " int m_batchIdx;\n" + " int m_bodyAPtrAndSignBit;//x:m_bodyAPtr, y:m_bodyBPtr\n" + " int m_bodyBPtrAndSignBit;\n" + " int m_childIndexA;\n" + " int m_childIndexB;\n" + " int m_unused1;\n" + " int m_unused2;\n" + "};\n" + "inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact)\n" + "{\n" + " return (int)contact->m_worldNormalOnB.w;\n" + "};\n" + "inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints)\n" + "{\n" + " contact->m_worldNormalOnB.w = (float)numPoints;\n" + "};\n" + "#endif //B3_CONTACT4DATA_H\n" + "#pragma OPENCL EXTENSION cl_amd_printf : enable\n" + "#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" + "#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n" + "#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n" + "#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n" + "#ifdef cl_ext_atomic_counters_32\n" + "#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n" + "#else\n" + "#define counter32_t volatile __global int*\n" + "#endif\n" + "typedef unsigned int u32;\n" + "typedef unsigned short u16;\n" + "typedef unsigned char u8;\n" + "#define GET_GROUP_IDX get_group_id(0)\n" + "#define GET_LOCAL_IDX get_local_id(0)\n" + "#define GET_GLOBAL_IDX get_global_id(0)\n" + "#define GET_GROUP_SIZE get_local_size(0)\n" + "#define GET_NUM_GROUPS get_num_groups(0)\n" + "#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" + "#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" + "#define AtomInc(x) atom_inc(&(x))\n" + "#define AtomInc1(x, out) out = atom_inc(&(x))\n" + "#define AppendInc(x, out) out = atomic_inc(x)\n" + "#define AtomAdd(x, value) atom_add(&(x), value)\n" + "#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n" + "#define AtomXhg(x, value) atom_xchg ( &(x), value )\n" + "#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n" + "#define make_float4 (float4)\n" + "#define make_float2 (float2)\n" + "#define make_uint4 (uint4)\n" + "#define make_int4 (int4)\n" + "#define make_uint2 (uint2)\n" + "#define make_int2 (int2)\n" + "#define max2 max\n" + "#define min2 min\n" + "#define WG_SIZE 64\n" + "typedef struct \n" + "{\n" + " int m_n;\n" + " int m_start;\n" + " int m_staticIdx;\n" + " int m_paddings[1];\n" + "} ConstBuffer;\n" + "typedef struct \n" + "{\n" + " int m_a;\n" + " int m_b;\n" + " u32 m_idx;\n" + "}Elem;\n" + "#define STACK_SIZE (WG_SIZE*10)\n" + "//#define STACK_SIZE (WG_SIZE)\n" + "#define RING_SIZE 1024\n" + "#define RING_SIZE_MASK (RING_SIZE-1)\n" + "#define CHECK_SIZE (WG_SIZE)\n" + "#define GET_RING_CAPACITY (RING_SIZE - ldsRingEnd)\n" + "#define RING_END ldsTmp\n" + "u32 readBuf(__local u32* buff, int idx)\n" + "{\n" + " idx = idx % (32*CHECK_SIZE);\n" + " int bitIdx = idx%32;\n" + " int bufIdx = idx/32;\n" + " return buff[bufIdx] & (1<> bitIdx)&1) == 0;\n" + "}\n" + "// batching on the GPU\n" + "__kernel void CreateBatches( __global const struct b3Contact4Data* gConstraints, __global struct b3Contact4Data* gConstraintsOut,\n" + " __global const u32* gN, __global const u32* gStart, __global int* batchSizes, \n" + " int m_staticIdx )\n" + "{\n" + " __local u32 ldsStackIdx[STACK_SIZE];\n" + " __local u32 ldsStackEnd;\n" + " __local Elem ldsRingElem[RING_SIZE];\n" + " __local u32 ldsRingEnd;\n" + " __local u32 ldsTmp;\n" + " __local u32 ldsCheckBuffer[CHECK_SIZE];\n" + " __local u32 ldsFixedBuffer[CHECK_SIZE];\n" + " __local u32 ldsGEnd;\n" + " __local u32 ldsDstEnd;\n" + " int wgIdx = GET_GROUP_IDX;\n" + " int lIdx = GET_LOCAL_IDX;\n" + " \n" + " const int m_n = gN[wgIdx];\n" + " const int m_start = gStart[wgIdx];\n" + " \n" + " if( lIdx == 0 )\n" + " {\n" + " ldsRingEnd = 0;\n" + " ldsGEnd = 0;\n" + " ldsStackEnd = 0;\n" + " ldsDstEnd = m_start;\n" + " }\n" + " \n" + " \n" + " \n" + "// while(1)\n" + "//was 250\n" + " int ie=0;\n" + " int maxBatch = 0;\n" + " for(ie=0; ie<50; ie++)\n" + " {\n" + " ldsFixedBuffer[lIdx] = 0;\n" + " for(int giter=0; giter<4; giter++)\n" + " {\n" + " int ringCap = GET_RING_CAPACITY;\n" + " \n" + " // 1. fill ring\n" + " if( ldsGEnd < m_n )\n" + " {\n" + " while( ringCap > WG_SIZE )\n" + " {\n" + " if( ldsGEnd >= m_n ) break;\n" + " if( lIdx < ringCap - WG_SIZE )\n" + " {\n" + " int srcIdx;\n" + " AtomInc1( ldsGEnd, srcIdx );\n" + " if( srcIdx < m_n )\n" + " {\n" + " int dstIdx;\n" + " AtomInc1( ldsRingEnd, dstIdx );\n" + " \n" + " int a = gConstraints[m_start+srcIdx].m_bodyAPtrAndSignBit;\n" + " int b = gConstraints[m_start+srcIdx].m_bodyBPtrAndSignBit;\n" + " ldsRingElem[dstIdx].m_a = (a>b)? b:a;\n" + " ldsRingElem[dstIdx].m_b = (a>b)? a:b;\n" + " ldsRingElem[dstIdx].m_idx = srcIdx;\n" + " }\n" + " }\n" + " ringCap = GET_RING_CAPACITY;\n" + " }\n" + " }\n" + " GROUP_LDS_BARRIER;\n" + " \n" + " // 2. fill stack\n" + " __local Elem* dst = ldsRingElem;\n" + " if( lIdx == 0 ) RING_END = 0;\n" + " int srcIdx=lIdx;\n" + " int end = ldsRingEnd;\n" + " {\n" + " for(int ii=0; ii1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" -" return false;\n" -" return true;\n" -"}\n" -"inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" -"{\n" -" float maxDot = -B3_INFINITY;\n" -" int i = 0;\n" -" int ptIndex = -1;\n" -" for( i = 0; i < vecLen; i++ )\n" -" {\n" -" float dot = b3Dot3F4(vecArray[i],vec);\n" -" \n" -" if( dot > maxDot )\n" -" {\n" -" maxDot = dot;\n" -" ptIndex = i;\n" -" }\n" -" }\n" -" b3Assert(ptIndex>=0);\n" -" if (ptIndex<0)\n" -" {\n" -" ptIndex = 0;\n" -" }\n" -" *dotOut = maxDot;\n" -" return ptIndex;\n" -"}\n" -"#endif //B3_FLOAT4_H\n" -"typedef struct b3Contact4Data b3Contact4Data_t;\n" -"struct b3Contact4Data\n" -"{\n" -" b3Float4 m_worldPosB[4];\n" -"// b3Float4 m_localPosA[4];\n" -"// b3Float4 m_localPosB[4];\n" -" b3Float4 m_worldNormalOnB; // w: m_nPoints\n" -" unsigned short m_restituitionCoeffCmp;\n" -" unsigned short m_frictionCoeffCmp;\n" -" int m_batchIdx;\n" -" int m_bodyAPtrAndSignBit;//x:m_bodyAPtr, y:m_bodyBPtr\n" -" int m_bodyBPtrAndSignBit;\n" -" int m_childIndexA;\n" -" int m_childIndexB;\n" -" int m_unused1;\n" -" int m_unused2;\n" -"};\n" -"inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact)\n" -"{\n" -" return (int)contact->m_worldNormalOnB.w;\n" -"};\n" -"inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints)\n" -"{\n" -" contact->m_worldNormalOnB.w = (float)numPoints;\n" -"};\n" -"#endif //B3_CONTACT4DATA_H\n" -"#pragma OPENCL EXTENSION cl_amd_printf : enable\n" -"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n" -"#ifdef cl_ext_atomic_counters_32\n" -"#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n" -"#else\n" -"#define counter32_t volatile __global int*\n" -"#endif\n" -"#define SIMD_WIDTH 64\n" -"typedef unsigned int u32;\n" -"typedef unsigned short u16;\n" -"typedef unsigned char u8;\n" -"#define GET_GROUP_IDX get_group_id(0)\n" -"#define GET_LOCAL_IDX get_local_id(0)\n" -"#define GET_GLOBAL_IDX get_global_id(0)\n" -"#define GET_GROUP_SIZE get_local_size(0)\n" -"#define GET_NUM_GROUPS get_num_groups(0)\n" -"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" -"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" -"#define AtomInc(x) atom_inc(&(x))\n" -"#define AtomInc1(x, out) out = atom_inc(&(x))\n" -"#define AppendInc(x, out) out = atomic_inc(x)\n" -"#define AtomAdd(x, value) atom_add(&(x), value)\n" -"#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n" -"#define AtomXhg(x, value) atom_xchg ( &(x), value )\n" -"#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n" -"#define make_float4 (float4)\n" -"#define make_float2 (float2)\n" -"#define make_uint4 (uint4)\n" -"#define make_int4 (int4)\n" -"#define make_uint2 (uint2)\n" -"#define make_int2 (int2)\n" -"#define max2 max\n" -"#define min2 min\n" -"#define WG_SIZE 64\n" -"typedef struct \n" -"{\n" -" int m_n;\n" -" int m_start;\n" -" int m_staticIdx;\n" -" int m_paddings[1];\n" -"} ConstBuffer;\n" -"typedef struct \n" -"{\n" -" int m_a;\n" -" int m_b;\n" -" u32 m_idx;\n" -"}Elem;\n" -"// batching on the GPU\n" -"__kernel void CreateBatchesBruteForce( __global struct b3Contact4Data* gConstraints, __global const u32* gN, __global const u32* gStart, int m_staticIdx )\n" -"{\n" -" int wgIdx = GET_GROUP_IDX;\n" -" int lIdx = GET_LOCAL_IDX;\n" -" \n" -" const int m_n = gN[wgIdx];\n" -" const int m_start = gStart[wgIdx];\n" -" \n" -" if( lIdx == 0 )\n" -" {\n" -" for (int i=0;i> bitIdx)&1) == 0;\n" -"}\n" -"// batching on the GPU\n" -"__kernel void CreateBatchesNew( __global struct b3Contact4Data* gConstraints, __global const u32* gN, __global const u32* gStart, __global int* batchSizes, int staticIdx )\n" -"{\n" -" int wgIdx = GET_GROUP_IDX;\n" -" int lIdx = GET_LOCAL_IDX;\n" -" const int numConstraints = gN[wgIdx];\n" -" const int m_start = gStart[wgIdx];\n" -" b3Contact4Data_t tmp;\n" -" \n" -" __local u32 ldsFixedBuffer[CHECK_SIZE];\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" if( lIdx == 0 )\n" -" {\n" -" \n" -" \n" -" __global struct b3Contact4Data* cs = &gConstraints[m_start]; \n" -" \n" -" \n" -" int numValidConstraints = 0;\n" -" int batchIdx = 0;\n" -" while( numValidConstraints < numConstraints)\n" -" {\n" -" int nCurrentBatch = 0;\n" -" // clear flag\n" -" \n" -" for(int i=0; i1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" + " return false;\n" + " return true;\n" + "}\n" + "inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" + "{\n" + " float maxDot = -B3_INFINITY;\n" + " int i = 0;\n" + " int ptIndex = -1;\n" + " for( i = 0; i < vecLen; i++ )\n" + " {\n" + " float dot = b3Dot3F4(vecArray[i],vec);\n" + " \n" + " if( dot > maxDot )\n" + " {\n" + " maxDot = dot;\n" + " ptIndex = i;\n" + " }\n" + " }\n" + " b3Assert(ptIndex>=0);\n" + " if (ptIndex<0)\n" + " {\n" + " ptIndex = 0;\n" + " }\n" + " *dotOut = maxDot;\n" + " return ptIndex;\n" + "}\n" + "#endif //B3_FLOAT4_H\n" + "typedef struct b3Contact4Data b3Contact4Data_t;\n" + "struct b3Contact4Data\n" + "{\n" + " b3Float4 m_worldPosB[4];\n" + "// b3Float4 m_localPosA[4];\n" + "// b3Float4 m_localPosB[4];\n" + " b3Float4 m_worldNormalOnB; // w: m_nPoints\n" + " unsigned short m_restituitionCoeffCmp;\n" + " unsigned short m_frictionCoeffCmp;\n" + " int m_batchIdx;\n" + " int m_bodyAPtrAndSignBit;//x:m_bodyAPtr, y:m_bodyBPtr\n" + " int m_bodyBPtrAndSignBit;\n" + " int m_childIndexA;\n" + " int m_childIndexB;\n" + " int m_unused1;\n" + " int m_unused2;\n" + "};\n" + "inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact)\n" + "{\n" + " return (int)contact->m_worldNormalOnB.w;\n" + "};\n" + "inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints)\n" + "{\n" + " contact->m_worldNormalOnB.w = (float)numPoints;\n" + "};\n" + "#endif //B3_CONTACT4DATA_H\n" + "#pragma OPENCL EXTENSION cl_amd_printf : enable\n" + "#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" + "#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n" + "#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n" + "#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n" + "#ifdef cl_ext_atomic_counters_32\n" + "#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n" + "#else\n" + "#define counter32_t volatile __global int*\n" + "#endif\n" + "#define SIMD_WIDTH 64\n" + "typedef unsigned int u32;\n" + "typedef unsigned short u16;\n" + "typedef unsigned char u8;\n" + "#define GET_GROUP_IDX get_group_id(0)\n" + "#define GET_LOCAL_IDX get_local_id(0)\n" + "#define GET_GLOBAL_IDX get_global_id(0)\n" + "#define GET_GROUP_SIZE get_local_size(0)\n" + "#define GET_NUM_GROUPS get_num_groups(0)\n" + "#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" + "#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" + "#define AtomInc(x) atom_inc(&(x))\n" + "#define AtomInc1(x, out) out = atom_inc(&(x))\n" + "#define AppendInc(x, out) out = atomic_inc(x)\n" + "#define AtomAdd(x, value) atom_add(&(x), value)\n" + "#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n" + "#define AtomXhg(x, value) atom_xchg ( &(x), value )\n" + "#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n" + "#define make_float4 (float4)\n" + "#define make_float2 (float2)\n" + "#define make_uint4 (uint4)\n" + "#define make_int4 (int4)\n" + "#define make_uint2 (uint2)\n" + "#define make_int2 (int2)\n" + "#define max2 max\n" + "#define min2 min\n" + "#define WG_SIZE 64\n" + "typedef struct \n" + "{\n" + " int m_n;\n" + " int m_start;\n" + " int m_staticIdx;\n" + " int m_paddings[1];\n" + "} ConstBuffer;\n" + "typedef struct \n" + "{\n" + " int m_a;\n" + " int m_b;\n" + " u32 m_idx;\n" + "}Elem;\n" + "// batching on the GPU\n" + "__kernel void CreateBatchesBruteForce( __global struct b3Contact4Data* gConstraints, __global const u32* gN, __global const u32* gStart, int m_staticIdx )\n" + "{\n" + " int wgIdx = GET_GROUP_IDX;\n" + " int lIdx = GET_LOCAL_IDX;\n" + " \n" + " const int m_n = gN[wgIdx];\n" + " const int m_start = gStart[wgIdx];\n" + " \n" + " if( lIdx == 0 )\n" + " {\n" + " for (int i=0;i> bitIdx)&1) == 0;\n" + "}\n" + "// batching on the GPU\n" + "__kernel void CreateBatchesNew( __global struct b3Contact4Data* gConstraints, __global const u32* gN, __global const u32* gStart, __global int* batchSizes, int staticIdx )\n" + "{\n" + " int wgIdx = GET_GROUP_IDX;\n" + " int lIdx = GET_LOCAL_IDX;\n" + " const int numConstraints = gN[wgIdx];\n" + " const int m_start = gStart[wgIdx];\n" + " b3Contact4Data_t tmp;\n" + " \n" + " __local u32 ldsFixedBuffer[CHECK_SIZE];\n" + " \n" + " \n" + " \n" + " \n" + " \n" + " if( lIdx == 0 )\n" + " {\n" + " \n" + " \n" + " __global struct b3Contact4Data* cs = &gConstraints[m_start]; \n" + " \n" + " \n" + " int numValidConstraints = 0;\n" + " int batchIdx = 0;\n" + " while( numValidConstraints < numConstraints)\n" + " {\n" + " int nCurrentBatch = 0;\n" + " // clear flag\n" + " \n" + " for(int i=0; i1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" -" return false;\n" -" return true;\n" -"}\n" -"inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" -"{\n" -" float maxDot = -B3_INFINITY;\n" -" int i = 0;\n" -" int ptIndex = -1;\n" -" for( i = 0; i < vecLen; i++ )\n" -" {\n" -" float dot = b3Dot3F4(vecArray[i],vec);\n" -" \n" -" if( dot > maxDot )\n" -" {\n" -" maxDot = dot;\n" -" ptIndex = i;\n" -" }\n" -" }\n" -" b3Assert(ptIndex>=0);\n" -" if (ptIndex<0)\n" -" {\n" -" ptIndex = 0;\n" -" }\n" -" *dotOut = maxDot;\n" -" return ptIndex;\n" -"}\n" -"#endif //B3_FLOAT4_H\n" -"#ifndef B3_QUAT_H\n" -"#define B3_QUAT_H\n" -"#ifndef B3_PLATFORM_DEFINITIONS_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif\n" -"#endif\n" -"#ifndef B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -" typedef float4 b3Quat;\n" -" #define b3QuatConstArg const b3Quat\n" -" \n" -" \n" -"inline float4 b3FastNormalize4(float4 v)\n" -"{\n" -" v = (float4)(v.xyz,0.f);\n" -" return fast_normalize(v);\n" -"}\n" -" \n" -"inline b3Quat b3QuatMul(b3Quat a, b3Quat b);\n" -"inline b3Quat b3QuatNormalized(b3QuatConstArg in);\n" -"inline b3Quat b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec);\n" -"inline b3Quat b3QuatInvert(b3QuatConstArg q);\n" -"inline b3Quat b3QuatInverse(b3QuatConstArg q);\n" -"inline b3Quat b3QuatMul(b3QuatConstArg a, b3QuatConstArg b)\n" -"{\n" -" b3Quat ans;\n" -" ans = b3Cross3( a, b );\n" -" ans += a.w*b+b.w*a;\n" -"// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" -" ans.w = a.w*b.w - b3Dot3F4(a, b);\n" -" return ans;\n" -"}\n" -"inline b3Quat b3QuatNormalized(b3QuatConstArg in)\n" -"{\n" -" b3Quat q;\n" -" q=in;\n" -" //return b3FastNormalize4(in);\n" -" float len = native_sqrt(dot(q, q));\n" -" if(len > 0.f)\n" -" {\n" -" q *= 1.f / len;\n" -" }\n" -" else\n" -" {\n" -" q.x = q.y = q.z = 0.f;\n" -" q.w = 1.f;\n" -" }\n" -" return q;\n" -"}\n" -"inline float4 b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" -"{\n" -" b3Quat qInv = b3QuatInvert( q );\n" -" float4 vcpy = vec;\n" -" vcpy.w = 0.f;\n" -" float4 out = b3QuatMul(b3QuatMul(q,vcpy),qInv);\n" -" return out;\n" -"}\n" -"inline b3Quat b3QuatInverse(b3QuatConstArg q)\n" -"{\n" -" return (b3Quat)(-q.xyz, q.w);\n" -"}\n" -"inline b3Quat b3QuatInvert(b3QuatConstArg q)\n" -"{\n" -" return (b3Quat)(-q.xyz, q.w);\n" -"}\n" -"inline float4 b3QuatInvRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" -"{\n" -" return b3QuatRotate( b3QuatInvert( q ), vec );\n" -"}\n" -"inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)\n" -"{\n" -" return b3QuatRotate( orientation, point ) + (translation);\n" -"}\n" -" \n" -"#endif \n" -"#endif //B3_QUAT_H\n" -"#ifndef B3_MAT3x3_H\n" -"#define B3_MAT3x3_H\n" -"#ifndef B3_QUAT_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_QUAT_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"typedef struct\n" -"{\n" -" b3Float4 m_row[3];\n" -"}b3Mat3x3;\n" -"#define b3Mat3x3ConstArg const b3Mat3x3\n" -"#define b3GetRow(m,row) (m.m_row[row])\n" -"inline b3Mat3x3 b3QuatGetRotationMatrix(b3Quat quat)\n" -"{\n" -" b3Float4 quat2 = (b3Float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f);\n" -" b3Mat3x3 out;\n" -" out.m_row[0].x=1-2*quat2.y-2*quat2.z;\n" -" out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z;\n" -" out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y;\n" -" out.m_row[0].w = 0.f;\n" -" out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z;\n" -" out.m_row[1].y=1-2*quat2.x-2*quat2.z;\n" -" out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x;\n" -" out.m_row[1].w = 0.f;\n" -" out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y;\n" -" out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x;\n" -" out.m_row[2].z=1-2*quat2.x-2*quat2.y;\n" -" out.m_row[2].w = 0.f;\n" -" return out;\n" -"}\n" -"inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg matIn)\n" -"{\n" -" b3Mat3x3 out;\n" -" out.m_row[0] = fabs(matIn.m_row[0]);\n" -" out.m_row[1] = fabs(matIn.m_row[1]);\n" -" out.m_row[2] = fabs(matIn.m_row[2]);\n" -" return out;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtZero();\n" -"__inline\n" -"b3Mat3x3 mtIdentity();\n" -"__inline\n" -"b3Mat3x3 mtTranspose(b3Mat3x3 m);\n" -"__inline\n" -"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b);\n" -"__inline\n" -"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b);\n" -"__inline\n" -"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b);\n" -"__inline\n" -"b3Mat3x3 mtZero()\n" -"{\n" -" b3Mat3x3 m;\n" -" m.m_row[0] = (b3Float4)(0.f);\n" -" m.m_row[1] = (b3Float4)(0.f);\n" -" m.m_row[2] = (b3Float4)(0.f);\n" -" return m;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtIdentity()\n" -"{\n" -" b3Mat3x3 m;\n" -" m.m_row[0] = (b3Float4)(1,0,0,0);\n" -" m.m_row[1] = (b3Float4)(0,1,0,0);\n" -" m.m_row[2] = (b3Float4)(0,0,1,0);\n" -" return m;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtTranspose(b3Mat3x3 m)\n" -"{\n" -" b3Mat3x3 out;\n" -" out.m_row[0] = (b3Float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n" -" out.m_row[1] = (b3Float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n" -" out.m_row[2] = (b3Float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n" -" return out;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b)\n" -"{\n" -" b3Mat3x3 transB;\n" -" transB = mtTranspose( b );\n" -" b3Mat3x3 ans;\n" -" // why this doesn't run when 0ing in the for{}\n" -" a.m_row[0].w = 0.f;\n" -" a.m_row[1].w = 0.f;\n" -" a.m_row[2].w = 0.f;\n" -" for(int i=0; i<3; i++)\n" -" {\n" -"// a.m_row[i].w = 0.f;\n" -" ans.m_row[i].x = b3Dot3F4(a.m_row[i],transB.m_row[0]);\n" -" ans.m_row[i].y = b3Dot3F4(a.m_row[i],transB.m_row[1]);\n" -" ans.m_row[i].z = b3Dot3F4(a.m_row[i],transB.m_row[2]);\n" -" ans.m_row[i].w = 0.f;\n" -" }\n" -" return ans;\n" -"}\n" -"__inline\n" -"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b)\n" -"{\n" -" b3Float4 ans;\n" -" ans.x = b3Dot3F4( a.m_row[0], b );\n" -" ans.y = b3Dot3F4( a.m_row[1], b );\n" -" ans.z = b3Dot3F4( a.m_row[2], b );\n" -" ans.w = 0.f;\n" -" return ans;\n" -"}\n" -"__inline\n" -"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b)\n" -"{\n" -" b3Float4 colx = b3MakeFloat4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" -" b3Float4 coly = b3MakeFloat4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" -" b3Float4 colz = b3MakeFloat4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" -" b3Float4 ans;\n" -" ans.x = b3Dot3F4( a, colx );\n" -" ans.y = b3Dot3F4( a, coly );\n" -" ans.z = b3Dot3F4( a, colz );\n" -" return ans;\n" -"}\n" -"#endif\n" -"#endif //B3_MAT3x3_H\n" -"typedef struct b3RigidBodyData b3RigidBodyData_t;\n" -"struct b3RigidBodyData\n" -"{\n" -" b3Float4 m_pos;\n" -" b3Quat m_quat;\n" -" b3Float4 m_linVel;\n" -" b3Float4 m_angVel;\n" -" int m_collidableIdx;\n" -" float m_invMass;\n" -" float m_restituitionCoeff;\n" -" float m_frictionCoeff;\n" -"};\n" -"typedef struct b3InertiaData b3InertiaData_t;\n" -"struct b3InertiaData\n" -"{\n" -" b3Mat3x3 m_invInertiaWorld;\n" -" b3Mat3x3 m_initInvInertia;\n" -"};\n" -"#endif //B3_RIGIDBODY_DATA_H\n" -" \n" -"#ifndef B3_RIGIDBODY_DATA_H\n" -"#endif //B3_RIGIDBODY_DATA_H\n" -" \n" -"inline void integrateSingleTransform( __global b3RigidBodyData_t* bodies,int nodeID, float timeStep, float angularDamping, b3Float4ConstArg gravityAcceleration)\n" -"{\n" -" \n" -" if (bodies[nodeID].m_invMass != 0.f)\n" -" {\n" -" float BT_GPU_ANGULAR_MOTION_THRESHOLD = (0.25f * 3.14159254f);\n" -" //angular velocity\n" -" {\n" -" b3Float4 axis;\n" -" //add some hardcoded angular damping\n" -" bodies[nodeID].m_angVel.x *= angularDamping;\n" -" bodies[nodeID].m_angVel.y *= angularDamping;\n" -" bodies[nodeID].m_angVel.z *= angularDamping;\n" -" \n" -" b3Float4 angvel = bodies[nodeID].m_angVel;\n" -" float fAngle = b3Sqrt(b3Dot3F4(angvel, angvel));\n" -" \n" -" //limit the angular motion\n" -" if(fAngle*timeStep > BT_GPU_ANGULAR_MOTION_THRESHOLD)\n" -" {\n" -" fAngle = BT_GPU_ANGULAR_MOTION_THRESHOLD / timeStep;\n" -" }\n" -" if(fAngle < 0.001f)\n" -" {\n" -" // use Taylor's expansions of sync function\n" -" axis = angvel * (0.5f*timeStep-(timeStep*timeStep*timeStep)*0.020833333333f * fAngle * fAngle);\n" -" }\n" -" else\n" -" {\n" -" // sync(fAngle) = sin(c*fAngle)/t\n" -" axis = angvel * ( b3Sin(0.5f * fAngle * timeStep) / fAngle);\n" -" }\n" -" \n" -" b3Quat dorn;\n" -" dorn.x = axis.x;\n" -" dorn.y = axis.y;\n" -" dorn.z = axis.z;\n" -" dorn.w = b3Cos(fAngle * timeStep * 0.5f);\n" -" b3Quat orn0 = bodies[nodeID].m_quat;\n" -" b3Quat predictedOrn = b3QuatMul(dorn, orn0);\n" -" predictedOrn = b3QuatNormalized(predictedOrn);\n" -" bodies[nodeID].m_quat=predictedOrn;\n" -" }\n" -" //linear velocity \n" -" bodies[nodeID].m_pos += bodies[nodeID].m_linVel * timeStep;\n" -" \n" -" //apply gravity\n" -" bodies[nodeID].m_linVel += gravityAcceleration * timeStep;\n" -" \n" -" }\n" -" \n" -"}\n" -"inline void b3IntegrateTransform( __global b3RigidBodyData_t* body, float timeStep, float angularDamping, b3Float4ConstArg gravityAcceleration)\n" -"{\n" -" float BT_GPU_ANGULAR_MOTION_THRESHOLD = (0.25f * 3.14159254f);\n" -" \n" -" if( (body->m_invMass != 0.f))\n" -" {\n" -" //angular velocity\n" -" {\n" -" b3Float4 axis;\n" -" //add some hardcoded angular damping\n" -" body->m_angVel.x *= angularDamping;\n" -" body->m_angVel.y *= angularDamping;\n" -" body->m_angVel.z *= angularDamping;\n" -" \n" -" b3Float4 angvel = body->m_angVel;\n" -" float fAngle = b3Sqrt(b3Dot3F4(angvel, angvel));\n" -" //limit the angular motion\n" -" if(fAngle*timeStep > BT_GPU_ANGULAR_MOTION_THRESHOLD)\n" -" {\n" -" fAngle = BT_GPU_ANGULAR_MOTION_THRESHOLD / timeStep;\n" -" }\n" -" if(fAngle < 0.001f)\n" -" {\n" -" // use Taylor's expansions of sync function\n" -" axis = angvel * (0.5f*timeStep-(timeStep*timeStep*timeStep)*0.020833333333f * fAngle * fAngle);\n" -" }\n" -" else\n" -" {\n" -" // sync(fAngle) = sin(c*fAngle)/t\n" -" axis = angvel * ( b3Sin(0.5f * fAngle * timeStep) / fAngle);\n" -" }\n" -" b3Quat dorn;\n" -" dorn.x = axis.x;\n" -" dorn.y = axis.y;\n" -" dorn.z = axis.z;\n" -" dorn.w = b3Cos(fAngle * timeStep * 0.5f);\n" -" b3Quat orn0 = body->m_quat;\n" -" b3Quat predictedOrn = b3QuatMul(dorn, orn0);\n" -" predictedOrn = b3QuatNormalized(predictedOrn);\n" -" body->m_quat=predictedOrn;\n" -" }\n" -" //apply gravity\n" -" body->m_linVel += gravityAcceleration * timeStep;\n" -" //linear velocity \n" -" body->m_pos += body->m_linVel * timeStep;\n" -" \n" -" }\n" -" \n" -"}\n" -"__kernel void \n" -" integrateTransformsKernel( __global b3RigidBodyData_t* bodies,const int numNodes, float timeStep, float angularDamping, float4 gravityAcceleration)\n" -"{\n" -" int nodeID = get_global_id(0);\n" -" \n" -" if( nodeID < numNodes)\n" -" {\n" -" integrateSingleTransform(bodies,nodeID, timeStep, angularDamping,gravityAcceleration);\n" -" }\n" -"}\n" -; +static const char* integrateKernelCL = + "/*\n" + "Copyright (c) 2013 Advanced Micro Devices, Inc. \n" + "This software is provided 'as-is', without any express or implied warranty.\n" + "In no event will the authors be held liable for any damages arising from the use of this software.\n" + "Permission is granted to anyone to use this software for any purpose, \n" + "including commercial applications, and to alter it and redistribute it freely, \n" + "subject to the following restrictions:\n" + "1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" + "2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" + "3. This notice may not be removed or altered from any source distribution.\n" + "*/\n" + "//Originally written by Erwin Coumans\n" + "#ifndef B3_RIGIDBODY_DATA_H\n" + "#define B3_RIGIDBODY_DATA_H\n" + "#ifndef B3_FLOAT4_H\n" + "#define B3_FLOAT4_H\n" + "#ifndef B3_PLATFORM_DEFINITIONS_H\n" + "#define B3_PLATFORM_DEFINITIONS_H\n" + "struct MyTest\n" + "{\n" + " int bla;\n" + "};\n" + "#ifdef __cplusplus\n" + "#else\n" + "//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n" + "#define B3_LARGE_FLOAT 1e18f\n" + "#define B3_INFINITY 1e18f\n" + "#define b3Assert(a)\n" + "#define b3ConstArray(a) __global const a*\n" + "#define b3AtomicInc atomic_inc\n" + "#define b3AtomicAdd atomic_add\n" + "#define b3Fabs fabs\n" + "#define b3Sqrt native_sqrt\n" + "#define b3Sin native_sin\n" + "#define b3Cos native_cos\n" + "#define B3_STATIC\n" + "#endif\n" + "#endif\n" + "#ifdef __cplusplus\n" + "#else\n" + " typedef float4 b3Float4;\n" + " #define b3Float4ConstArg const b3Float4\n" + " #define b3MakeFloat4 (float4)\n" + " float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" + " {\n" + " float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" + " float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" + " return dot(a1, b1);\n" + " }\n" + " b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" + " {\n" + " float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" + " float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" + " return cross(a1, b1);\n" + " }\n" + " #define b3MinFloat4 min\n" + " #define b3MaxFloat4 max\n" + " #define b3Normalized(a) normalize(a)\n" + "#endif \n" + " \n" + "inline bool b3IsAlmostZero(b3Float4ConstArg v)\n" + "{\n" + " if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" + " return false;\n" + " return true;\n" + "}\n" + "inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" + "{\n" + " float maxDot = -B3_INFINITY;\n" + " int i = 0;\n" + " int ptIndex = -1;\n" + " for( i = 0; i < vecLen; i++ )\n" + " {\n" + " float dot = b3Dot3F4(vecArray[i],vec);\n" + " \n" + " if( dot > maxDot )\n" + " {\n" + " maxDot = dot;\n" + " ptIndex = i;\n" + " }\n" + " }\n" + " b3Assert(ptIndex>=0);\n" + " if (ptIndex<0)\n" + " {\n" + " ptIndex = 0;\n" + " }\n" + " *dotOut = maxDot;\n" + " return ptIndex;\n" + "}\n" + "#endif //B3_FLOAT4_H\n" + "#ifndef B3_QUAT_H\n" + "#define B3_QUAT_H\n" + "#ifndef B3_PLATFORM_DEFINITIONS_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif\n" + "#endif\n" + "#ifndef B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + " typedef float4 b3Quat;\n" + " #define b3QuatConstArg const b3Quat\n" + " \n" + " \n" + "inline float4 b3FastNormalize4(float4 v)\n" + "{\n" + " v = (float4)(v.xyz,0.f);\n" + " return fast_normalize(v);\n" + "}\n" + " \n" + "inline b3Quat b3QuatMul(b3Quat a, b3Quat b);\n" + "inline b3Quat b3QuatNormalized(b3QuatConstArg in);\n" + "inline b3Quat b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec);\n" + "inline b3Quat b3QuatInvert(b3QuatConstArg q);\n" + "inline b3Quat b3QuatInverse(b3QuatConstArg q);\n" + "inline b3Quat b3QuatMul(b3QuatConstArg a, b3QuatConstArg b)\n" + "{\n" + " b3Quat ans;\n" + " ans = b3Cross3( a, b );\n" + " ans += a.w*b+b.w*a;\n" + "// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" + " ans.w = a.w*b.w - b3Dot3F4(a, b);\n" + " return ans;\n" + "}\n" + "inline b3Quat b3QuatNormalized(b3QuatConstArg in)\n" + "{\n" + " b3Quat q;\n" + " q=in;\n" + " //return b3FastNormalize4(in);\n" + " float len = native_sqrt(dot(q, q));\n" + " if(len > 0.f)\n" + " {\n" + " q *= 1.f / len;\n" + " }\n" + " else\n" + " {\n" + " q.x = q.y = q.z = 0.f;\n" + " q.w = 1.f;\n" + " }\n" + " return q;\n" + "}\n" + "inline float4 b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" + "{\n" + " b3Quat qInv = b3QuatInvert( q );\n" + " float4 vcpy = vec;\n" + " vcpy.w = 0.f;\n" + " float4 out = b3QuatMul(b3QuatMul(q,vcpy),qInv);\n" + " return out;\n" + "}\n" + "inline b3Quat b3QuatInverse(b3QuatConstArg q)\n" + "{\n" + " return (b3Quat)(-q.xyz, q.w);\n" + "}\n" + "inline b3Quat b3QuatInvert(b3QuatConstArg q)\n" + "{\n" + " return (b3Quat)(-q.xyz, q.w);\n" + "}\n" + "inline float4 b3QuatInvRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" + "{\n" + " return b3QuatRotate( b3QuatInvert( q ), vec );\n" + "}\n" + "inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)\n" + "{\n" + " return b3QuatRotate( orientation, point ) + (translation);\n" + "}\n" + " \n" + "#endif \n" + "#endif //B3_QUAT_H\n" + "#ifndef B3_MAT3x3_H\n" + "#define B3_MAT3x3_H\n" + "#ifndef B3_QUAT_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_QUAT_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "typedef struct\n" + "{\n" + " b3Float4 m_row[3];\n" + "}b3Mat3x3;\n" + "#define b3Mat3x3ConstArg const b3Mat3x3\n" + "#define b3GetRow(m,row) (m.m_row[row])\n" + "inline b3Mat3x3 b3QuatGetRotationMatrix(b3Quat quat)\n" + "{\n" + " b3Float4 quat2 = (b3Float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f);\n" + " b3Mat3x3 out;\n" + " out.m_row[0].x=1-2*quat2.y-2*quat2.z;\n" + " out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z;\n" + " out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y;\n" + " out.m_row[0].w = 0.f;\n" + " out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z;\n" + " out.m_row[1].y=1-2*quat2.x-2*quat2.z;\n" + " out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x;\n" + " out.m_row[1].w = 0.f;\n" + " out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y;\n" + " out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x;\n" + " out.m_row[2].z=1-2*quat2.x-2*quat2.y;\n" + " out.m_row[2].w = 0.f;\n" + " return out;\n" + "}\n" + "inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg matIn)\n" + "{\n" + " b3Mat3x3 out;\n" + " out.m_row[0] = fabs(matIn.m_row[0]);\n" + " out.m_row[1] = fabs(matIn.m_row[1]);\n" + " out.m_row[2] = fabs(matIn.m_row[2]);\n" + " return out;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtZero();\n" + "__inline\n" + "b3Mat3x3 mtIdentity();\n" + "__inline\n" + "b3Mat3x3 mtTranspose(b3Mat3x3 m);\n" + "__inline\n" + "b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b);\n" + "__inline\n" + "b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b);\n" + "__inline\n" + "b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b);\n" + "__inline\n" + "b3Mat3x3 mtZero()\n" + "{\n" + " b3Mat3x3 m;\n" + " m.m_row[0] = (b3Float4)(0.f);\n" + " m.m_row[1] = (b3Float4)(0.f);\n" + " m.m_row[2] = (b3Float4)(0.f);\n" + " return m;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtIdentity()\n" + "{\n" + " b3Mat3x3 m;\n" + " m.m_row[0] = (b3Float4)(1,0,0,0);\n" + " m.m_row[1] = (b3Float4)(0,1,0,0);\n" + " m.m_row[2] = (b3Float4)(0,0,1,0);\n" + " return m;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtTranspose(b3Mat3x3 m)\n" + "{\n" + " b3Mat3x3 out;\n" + " out.m_row[0] = (b3Float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n" + " out.m_row[1] = (b3Float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n" + " out.m_row[2] = (b3Float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n" + " return out;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b)\n" + "{\n" + " b3Mat3x3 transB;\n" + " transB = mtTranspose( b );\n" + " b3Mat3x3 ans;\n" + " // why this doesn't run when 0ing in the for{}\n" + " a.m_row[0].w = 0.f;\n" + " a.m_row[1].w = 0.f;\n" + " a.m_row[2].w = 0.f;\n" + " for(int i=0; i<3; i++)\n" + " {\n" + "// a.m_row[i].w = 0.f;\n" + " ans.m_row[i].x = b3Dot3F4(a.m_row[i],transB.m_row[0]);\n" + " ans.m_row[i].y = b3Dot3F4(a.m_row[i],transB.m_row[1]);\n" + " ans.m_row[i].z = b3Dot3F4(a.m_row[i],transB.m_row[2]);\n" + " ans.m_row[i].w = 0.f;\n" + " }\n" + " return ans;\n" + "}\n" + "__inline\n" + "b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b)\n" + "{\n" + " b3Float4 ans;\n" + " ans.x = b3Dot3F4( a.m_row[0], b );\n" + " ans.y = b3Dot3F4( a.m_row[1], b );\n" + " ans.z = b3Dot3F4( a.m_row[2], b );\n" + " ans.w = 0.f;\n" + " return ans;\n" + "}\n" + "__inline\n" + "b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b)\n" + "{\n" + " b3Float4 colx = b3MakeFloat4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" + " b3Float4 coly = b3MakeFloat4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" + " b3Float4 colz = b3MakeFloat4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" + " b3Float4 ans;\n" + " ans.x = b3Dot3F4( a, colx );\n" + " ans.y = b3Dot3F4( a, coly );\n" + " ans.z = b3Dot3F4( a, colz );\n" + " return ans;\n" + "}\n" + "#endif\n" + "#endif //B3_MAT3x3_H\n" + "typedef struct b3RigidBodyData b3RigidBodyData_t;\n" + "struct b3RigidBodyData\n" + "{\n" + " b3Float4 m_pos;\n" + " b3Quat m_quat;\n" + " b3Float4 m_linVel;\n" + " b3Float4 m_angVel;\n" + " int m_collidableIdx;\n" + " float m_invMass;\n" + " float m_restituitionCoeff;\n" + " float m_frictionCoeff;\n" + "};\n" + "typedef struct b3InertiaData b3InertiaData_t;\n" + "struct b3InertiaData\n" + "{\n" + " b3Mat3x3 m_invInertiaWorld;\n" + " b3Mat3x3 m_initInvInertia;\n" + "};\n" + "#endif //B3_RIGIDBODY_DATA_H\n" + " \n" + "#ifndef B3_RIGIDBODY_DATA_H\n" + "#endif //B3_RIGIDBODY_DATA_H\n" + " \n" + "inline void integrateSingleTransform( __global b3RigidBodyData_t* bodies,int nodeID, float timeStep, float angularDamping, b3Float4ConstArg gravityAcceleration)\n" + "{\n" + " \n" + " if (bodies[nodeID].m_invMass != 0.f)\n" + " {\n" + " float BT_GPU_ANGULAR_MOTION_THRESHOLD = (0.25f * 3.14159254f);\n" + " //angular velocity\n" + " {\n" + " b3Float4 axis;\n" + " //add some hardcoded angular damping\n" + " bodies[nodeID].m_angVel.x *= angularDamping;\n" + " bodies[nodeID].m_angVel.y *= angularDamping;\n" + " bodies[nodeID].m_angVel.z *= angularDamping;\n" + " \n" + " b3Float4 angvel = bodies[nodeID].m_angVel;\n" + " float fAngle = b3Sqrt(b3Dot3F4(angvel, angvel));\n" + " \n" + " //limit the angular motion\n" + " if(fAngle*timeStep > BT_GPU_ANGULAR_MOTION_THRESHOLD)\n" + " {\n" + " fAngle = BT_GPU_ANGULAR_MOTION_THRESHOLD / timeStep;\n" + " }\n" + " if(fAngle < 0.001f)\n" + " {\n" + " // use Taylor's expansions of sync function\n" + " axis = angvel * (0.5f*timeStep-(timeStep*timeStep*timeStep)*0.020833333333f * fAngle * fAngle);\n" + " }\n" + " else\n" + " {\n" + " // sync(fAngle) = sin(c*fAngle)/t\n" + " axis = angvel * ( b3Sin(0.5f * fAngle * timeStep) / fAngle);\n" + " }\n" + " \n" + " b3Quat dorn;\n" + " dorn.x = axis.x;\n" + " dorn.y = axis.y;\n" + " dorn.z = axis.z;\n" + " dorn.w = b3Cos(fAngle * timeStep * 0.5f);\n" + " b3Quat orn0 = bodies[nodeID].m_quat;\n" + " b3Quat predictedOrn = b3QuatMul(dorn, orn0);\n" + " predictedOrn = b3QuatNormalized(predictedOrn);\n" + " bodies[nodeID].m_quat=predictedOrn;\n" + " }\n" + " //linear velocity \n" + " bodies[nodeID].m_pos += bodies[nodeID].m_linVel * timeStep;\n" + " \n" + " //apply gravity\n" + " bodies[nodeID].m_linVel += gravityAcceleration * timeStep;\n" + " \n" + " }\n" + " \n" + "}\n" + "inline void b3IntegrateTransform( __global b3RigidBodyData_t* body, float timeStep, float angularDamping, b3Float4ConstArg gravityAcceleration)\n" + "{\n" + " float BT_GPU_ANGULAR_MOTION_THRESHOLD = (0.25f * 3.14159254f);\n" + " \n" + " if( (body->m_invMass != 0.f))\n" + " {\n" + " //angular velocity\n" + " {\n" + " b3Float4 axis;\n" + " //add some hardcoded angular damping\n" + " body->m_angVel.x *= angularDamping;\n" + " body->m_angVel.y *= angularDamping;\n" + " body->m_angVel.z *= angularDamping;\n" + " \n" + " b3Float4 angvel = body->m_angVel;\n" + " float fAngle = b3Sqrt(b3Dot3F4(angvel, angvel));\n" + " //limit the angular motion\n" + " if(fAngle*timeStep > BT_GPU_ANGULAR_MOTION_THRESHOLD)\n" + " {\n" + " fAngle = BT_GPU_ANGULAR_MOTION_THRESHOLD / timeStep;\n" + " }\n" + " if(fAngle < 0.001f)\n" + " {\n" + " // use Taylor's expansions of sync function\n" + " axis = angvel * (0.5f*timeStep-(timeStep*timeStep*timeStep)*0.020833333333f * fAngle * fAngle);\n" + " }\n" + " else\n" + " {\n" + " // sync(fAngle) = sin(c*fAngle)/t\n" + " axis = angvel * ( b3Sin(0.5f * fAngle * timeStep) / fAngle);\n" + " }\n" + " b3Quat dorn;\n" + " dorn.x = axis.x;\n" + " dorn.y = axis.y;\n" + " dorn.z = axis.z;\n" + " dorn.w = b3Cos(fAngle * timeStep * 0.5f);\n" + " b3Quat orn0 = body->m_quat;\n" + " b3Quat predictedOrn = b3QuatMul(dorn, orn0);\n" + " predictedOrn = b3QuatNormalized(predictedOrn);\n" + " body->m_quat=predictedOrn;\n" + " }\n" + " //apply gravity\n" + " body->m_linVel += gravityAcceleration * timeStep;\n" + " //linear velocity \n" + " body->m_pos += body->m_linVel * timeStep;\n" + " \n" + " }\n" + " \n" + "}\n" + "__kernel void \n" + " integrateTransformsKernel( __global b3RigidBodyData_t* bodies,const int numNodes, float timeStep, float angularDamping, float4 gravityAcceleration)\n" + "{\n" + " int nodeID = get_global_id(0);\n" + " \n" + " if( nodeID < numNodes)\n" + " {\n" + " integrateSingleTransform(bodies,nodeID, timeStep, angularDamping,gravityAcceleration);\n" + " }\n" + "}\n"; diff --git a/src/Bullet3OpenCL/RigidBody/kernels/jointSolver.h b/src/Bullet3OpenCL/RigidBody/kernels/jointSolver.h index d48ecf6ea..c94b55851 100644 --- a/src/Bullet3OpenCL/RigidBody/kernels/jointSolver.h +++ b/src/Bullet3OpenCL/RigidBody/kernels/jointSolver.h @@ -1,721 +1,720 @@ //this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project -static const char* solveConstraintRowsCL= \ -"/*\n" -"Copyright (c) 2013 Advanced Micro Devices, Inc. \n" -"This software is provided 'as-is', without any express or implied warranty.\n" -"In no event will the authors be held liable for any damages arising from the use of this software.\n" -"Permission is granted to anyone to use this software for any purpose, \n" -"including commercial applications, and to alter it and redistribute it freely, \n" -"subject to the following restrictions:\n" -"1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" -"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" -"3. This notice may not be removed or altered from any source distribution.\n" -"*/\n" -"//Originally written by Erwin Coumans\n" -"#define B3_CONSTRAINT_FLAG_ENABLED 1\n" -"#define B3_GPU_POINT2POINT_CONSTRAINT_TYPE 3\n" -"#define B3_GPU_FIXED_CONSTRAINT_TYPE 4\n" -"#define MOTIONCLAMP 100000 //unused, for debugging/safety in case constraint solver fails\n" -"#define B3_INFINITY 1e30f\n" -"#define mymake_float4 (float4)\n" -"__inline float dot3F4(float4 a, float4 b)\n" -"{\n" -" float4 a1 = mymake_float4(a.xyz,0.f);\n" -" float4 b1 = mymake_float4(b.xyz,0.f);\n" -" return dot(a1, b1);\n" -"}\n" -"typedef float4 Quaternion;\n" -"typedef struct\n" -"{\n" -" float4 m_row[3];\n" -"}Matrix3x3;\n" -"__inline\n" -"float4 mtMul1(Matrix3x3 a, float4 b);\n" -"__inline\n" -"float4 mtMul3(float4 a, Matrix3x3 b);\n" -"__inline\n" -"float4 mtMul1(Matrix3x3 a, float4 b)\n" -"{\n" -" float4 ans;\n" -" ans.x = dot3F4( a.m_row[0], b );\n" -" ans.y = dot3F4( a.m_row[1], b );\n" -" ans.z = dot3F4( a.m_row[2], b );\n" -" ans.w = 0.f;\n" -" return ans;\n" -"}\n" -"__inline\n" -"float4 mtMul3(float4 a, Matrix3x3 b)\n" -"{\n" -" float4 colx = mymake_float4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" -" float4 coly = mymake_float4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" -" float4 colz = mymake_float4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" -" float4 ans;\n" -" ans.x = dot3F4( a, colx );\n" -" ans.y = dot3F4( a, coly );\n" -" ans.z = dot3F4( a, colz );\n" -" return ans;\n" -"}\n" -"typedef struct\n" -"{\n" -" Matrix3x3 m_invInertiaWorld;\n" -" Matrix3x3 m_initInvInertia;\n" -"} BodyInertia;\n" -"typedef struct\n" -"{\n" -" Matrix3x3 m_basis;//orientation\n" -" float4 m_origin;//transform\n" -"}b3Transform;\n" -"typedef struct\n" -"{\n" -"// b3Transform m_worldTransformUnused;\n" -" float4 m_deltaLinearVelocity;\n" -" float4 m_deltaAngularVelocity;\n" -" float4 m_angularFactor;\n" -" float4 m_linearFactor;\n" -" float4 m_invMass;\n" -" float4 m_pushVelocity;\n" -" float4 m_turnVelocity;\n" -" float4 m_linearVelocity;\n" -" float4 m_angularVelocity;\n" -" union \n" -" {\n" -" void* m_originalBody;\n" -" int m_originalBodyIndex;\n" -" };\n" -" int padding[3];\n" -"} b3GpuSolverBody;\n" -"typedef struct\n" -"{\n" -" float4 m_pos;\n" -" Quaternion m_quat;\n" -" float4 m_linVel;\n" -" float4 m_angVel;\n" -" unsigned int m_shapeIdx;\n" -" float m_invMass;\n" -" float m_restituitionCoeff;\n" -" float m_frictionCoeff;\n" -"} b3RigidBodyCL;\n" -"typedef struct\n" -"{\n" -" float4 m_relpos1CrossNormal;\n" -" float4 m_contactNormal;\n" -" float4 m_relpos2CrossNormal;\n" -" //float4 m_contactNormal2;//usually m_contactNormal2 == -m_contactNormal\n" -" float4 m_angularComponentA;\n" -" float4 m_angularComponentB;\n" -" \n" -" float m_appliedPushImpulse;\n" -" float m_appliedImpulse;\n" -" int m_padding1;\n" -" int m_padding2;\n" -" float m_friction;\n" -" float m_jacDiagABInv;\n" -" float m_rhs;\n" -" float m_cfm;\n" -" \n" -" float m_lowerLimit;\n" -" float m_upperLimit;\n" -" float m_rhsPenetration;\n" -" int m_originalConstraint;\n" -" int m_overrideNumSolverIterations;\n" -" int m_frictionIndex;\n" -" int m_solverBodyIdA;\n" -" int m_solverBodyIdB;\n" -"} b3SolverConstraint;\n" -"typedef struct \n" -"{\n" -" int m_bodyAPtrAndSignBit;\n" -" int m_bodyBPtrAndSignBit;\n" -" int m_originalConstraintIndex;\n" -" int m_batchId;\n" -"} b3BatchConstraint;\n" -"typedef struct \n" -"{\n" -" int m_constraintType;\n" -" int m_rbA;\n" -" int m_rbB;\n" -" float m_breakingImpulseThreshold;\n" -" float4 m_pivotInA;\n" -" float4 m_pivotInB;\n" -" Quaternion m_relTargetAB;\n" -" int m_flags;\n" -" int m_padding[3];\n" -"} b3GpuGenericConstraint;\n" -"/*b3Transform getWorldTransform(b3RigidBodyCL* rb)\n" -"{\n" -" b3Transform newTrans;\n" -" newTrans.setOrigin(rb->m_pos);\n" -" newTrans.setRotation(rb->m_quat);\n" -" return newTrans;\n" -"}*/\n" -"__inline\n" -"float4 cross3(float4 a, float4 b)\n" -"{\n" -" return cross(a,b);\n" -"}\n" -"__inline\n" -"float4 fastNormalize4(float4 v)\n" -"{\n" -" v = mymake_float4(v.xyz,0.f);\n" -" return fast_normalize(v);\n" -"}\n" -"__inline\n" -"Quaternion qtMul(Quaternion a, Quaternion b);\n" -"__inline\n" -"Quaternion qtNormalize(Quaternion in);\n" -"__inline\n" -"float4 qtRotate(Quaternion q, float4 vec);\n" -"__inline\n" -"Quaternion qtInvert(Quaternion q);\n" -"__inline\n" -"Quaternion qtMul(Quaternion a, Quaternion b)\n" -"{\n" -" Quaternion ans;\n" -" ans = cross3( a, b );\n" -" ans += a.w*b+b.w*a;\n" -"// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" -" ans.w = a.w*b.w - dot3F4(a, b);\n" -" return ans;\n" -"}\n" -"__inline\n" -"Quaternion qtNormalize(Quaternion in)\n" -"{\n" -" return fastNormalize4(in);\n" -"// in /= length( in );\n" -"// return in;\n" -"}\n" -"__inline\n" -"float4 qtRotate(Quaternion q, float4 vec)\n" -"{\n" -" Quaternion qInv = qtInvert( q );\n" -" float4 vcpy = vec;\n" -" vcpy.w = 0.f;\n" -" float4 out = qtMul(qtMul(q,vcpy),qInv);\n" -" return out;\n" -"}\n" -"__inline\n" -"Quaternion qtInvert(Quaternion q)\n" -"{\n" -" return (Quaternion)(-q.xyz, q.w);\n" -"}\n" -"__inline void internalApplyImpulse(__global b3GpuSolverBody* body, float4 linearComponent, float4 angularComponent,float impulseMagnitude)\n" -"{\n" -" body->m_deltaLinearVelocity += linearComponent*impulseMagnitude*body->m_linearFactor;\n" -" body->m_deltaAngularVelocity += angularComponent*(impulseMagnitude*body->m_angularFactor);\n" -"}\n" -"void resolveSingleConstraintRowGeneric(__global b3GpuSolverBody* body1, __global b3GpuSolverBody* body2, __global b3SolverConstraint* c)\n" -"{\n" -" float deltaImpulse = c->m_rhs-c->m_appliedImpulse*c->m_cfm;\n" -" float deltaVel1Dotn = dot3F4(c->m_contactNormal,body1->m_deltaLinearVelocity) + dot3F4(c->m_relpos1CrossNormal,body1->m_deltaAngularVelocity);\n" -" float deltaVel2Dotn = -dot3F4(c->m_contactNormal,body2->m_deltaLinearVelocity) + dot3F4(c->m_relpos2CrossNormal,body2->m_deltaAngularVelocity);\n" -" deltaImpulse -= deltaVel1Dotn*c->m_jacDiagABInv;\n" -" deltaImpulse -= deltaVel2Dotn*c->m_jacDiagABInv;\n" -" float sum = c->m_appliedImpulse + deltaImpulse;\n" -" if (sum < c->m_lowerLimit)\n" -" {\n" -" deltaImpulse = c->m_lowerLimit-c->m_appliedImpulse;\n" -" c->m_appliedImpulse = c->m_lowerLimit;\n" -" }\n" -" else if (sum > c->m_upperLimit) \n" -" {\n" -" deltaImpulse = c->m_upperLimit-c->m_appliedImpulse;\n" -" c->m_appliedImpulse = c->m_upperLimit;\n" -" }\n" -" else\n" -" {\n" -" c->m_appliedImpulse = sum;\n" -" }\n" -" internalApplyImpulse(body1,c->m_contactNormal*body1->m_invMass,c->m_angularComponentA,deltaImpulse);\n" -" internalApplyImpulse(body2,-c->m_contactNormal*body2->m_invMass,c->m_angularComponentB,deltaImpulse);\n" -"}\n" -"__kernel void solveJointConstraintRows(__global b3GpuSolverBody* solverBodies,\n" -" __global b3BatchConstraint* batchConstraints,\n" -" __global b3SolverConstraint* rows,\n" -" __global unsigned int* numConstraintRowsInfo1, \n" -" __global unsigned int* rowOffsets,\n" -" __global b3GpuGenericConstraint* constraints,\n" -" int batchOffset,\n" -" int numConstraintsInBatch\n" -" )\n" -"{\n" -" int b = get_global_id(0);\n" -" if (b>=numConstraintsInBatch)\n" -" return;\n" -" __global b3BatchConstraint* c = &batchConstraints[b+batchOffset];\n" -" int originalConstraintIndex = c->m_originalConstraintIndex;\n" -" if (constraints[originalConstraintIndex].m_flags&B3_CONSTRAINT_FLAG_ENABLED)\n" -" {\n" -" int numConstraintRows = numConstraintRowsInfo1[originalConstraintIndex];\n" -" int rowOffset = rowOffsets[originalConstraintIndex];\n" -" for (int jj=0;jjm_solverBodyIdA],&solverBodies[constraint->m_solverBodyIdB],constraint);\n" -" }\n" -" }\n" -"};\n" -"__kernel void initSolverBodies(__global b3GpuSolverBody* solverBodies,__global b3RigidBodyCL* bodiesCL, int numBodies)\n" -"{\n" -" int i = get_global_id(0);\n" -" if (i>=numBodies)\n" -" return;\n" -" __global b3GpuSolverBody* solverBody = &solverBodies[i];\n" -" __global b3RigidBodyCL* bodyCL = &bodiesCL[i];\n" -" solverBody->m_deltaLinearVelocity = (float4)(0.f,0.f,0.f,0.f);\n" -" solverBody->m_deltaAngularVelocity = (float4)(0.f,0.f,0.f,0.f);\n" -" solverBody->m_pushVelocity = (float4)(0.f,0.f,0.f,0.f);\n" -" solverBody->m_pushVelocity = (float4)(0.f,0.f,0.f,0.f);\n" -" solverBody->m_invMass = (float4)(bodyCL->m_invMass,bodyCL->m_invMass,bodyCL->m_invMass,0.f);\n" -" solverBody->m_originalBodyIndex = i;\n" -" solverBody->m_angularFactor = (float4)(1,1,1,0);\n" -" solverBody->m_linearFactor = (float4) (1,1,1,0);\n" -" solverBody->m_linearVelocity = bodyCL->m_linVel;\n" -" solverBody->m_angularVelocity = bodyCL->m_angVel;\n" -"}\n" -"__kernel void breakViolatedConstraintsKernel(__global b3GpuGenericConstraint* constraints, __global unsigned int* numConstraintRows, __global unsigned int* rowOffsets, __global b3SolverConstraint* rows, int numConstraints)\n" -"{\n" -" int cid = get_global_id(0);\n" -" if (cid>=numConstraints)\n" -" return;\n" -" int numRows = numConstraintRows[cid];\n" -" if (numRows)\n" -" {\n" -" for (int i=0;i= breakingThreshold)\n" -" {\n" -" constraints[cid].m_flags =0;//&= ~B3_CONSTRAINT_FLAG_ENABLED;\n" -" }\n" -" }\n" -" }\n" -"}\n" -"__kernel void getInfo1Kernel(__global unsigned int* infos, __global b3GpuGenericConstraint* constraints, int numConstraints)\n" -"{\n" -" int i = get_global_id(0);\n" -" if (i>=numConstraints)\n" -" return;\n" -" __global b3GpuGenericConstraint* constraint = &constraints[i];\n" -" switch (constraint->m_constraintType)\n" -" {\n" -" case B3_GPU_POINT2POINT_CONSTRAINT_TYPE:\n" -" {\n" -" infos[i] = 3;\n" -" break;\n" -" }\n" -" case B3_GPU_FIXED_CONSTRAINT_TYPE:\n" -" {\n" -" infos[i] = 6;\n" -" break;\n" -" }\n" -" default:\n" -" {\n" -" }\n" -" }\n" -"}\n" -"__kernel void initBatchConstraintsKernel(__global unsigned int* numConstraintRows, __global unsigned int* rowOffsets, \n" -" __global b3BatchConstraint* batchConstraints, \n" -" __global b3GpuGenericConstraint* constraints,\n" -" __global b3RigidBodyCL* bodies,\n" -" int numConstraints)\n" -"{\n" -" int i = get_global_id(0);\n" -" if (i>=numConstraints)\n" -" return;\n" -" int rbA = constraints[i].m_rbA;\n" -" int rbB = constraints[i].m_rbB;\n" -" batchConstraints[i].m_bodyAPtrAndSignBit = bodies[rbA].m_invMass != 0.f ? rbA : -rbA;\n" -" batchConstraints[i].m_bodyBPtrAndSignBit = bodies[rbB].m_invMass != 0.f ? rbB : -rbB;\n" -" batchConstraints[i].m_batchId = -1;\n" -" batchConstraints[i].m_originalConstraintIndex = i;\n" -"}\n" -"typedef struct\n" -"{\n" -" // integrator parameters: frames per second (1/stepsize), default error\n" -" // reduction parameter (0..1).\n" -" float fps,erp;\n" -" // for the first and second body, pointers to two (linear and angular)\n" -" // n*3 jacobian sub matrices, stored by rows. these matrices will have\n" -" // been initialized to 0 on entry. if the second body is zero then the\n" -" // J2xx pointers may be 0.\n" -" union \n" -" {\n" -" __global float4* m_J1linearAxisFloat4;\n" -" __global float* m_J1linearAxis;\n" -" };\n" -" union\n" -" {\n" -" __global float4* m_J1angularAxisFloat4;\n" -" __global float* m_J1angularAxis;\n" -" };\n" -" union\n" -" {\n" -" __global float4* m_J2linearAxisFloat4;\n" -" __global float* m_J2linearAxis;\n" -" };\n" -" union\n" -" {\n" -" __global float4* m_J2angularAxisFloat4;\n" -" __global float* m_J2angularAxis;\n" -" };\n" -" // elements to jump from one row to the next in J's\n" -" int rowskip;\n" -" // right hand sides of the equation J*v = c + cfm * lambda. cfm is the\n" -" // \"constraint force mixing\" vector. c is set to zero on entry, cfm is\n" -" // set to a constant value (typically very small or zero) value on entry.\n" -" __global float* m_constraintError;\n" -" __global float* cfm;\n" -" // lo and hi limits for variables (set to -/+ infinity on entry).\n" -" __global float* m_lowerLimit;\n" -" __global float* m_upperLimit;\n" -" // findex vector for variables. see the LCP solver interface for a\n" -" // description of what this does. this is set to -1 on entry.\n" -" // note that the returned indexes are relative to the first index of\n" -" // the constraint.\n" -" __global int *findex;\n" -" // number of solver iterations\n" -" int m_numIterations;\n" -" //damping of the velocity\n" -" float m_damping;\n" -"} b3GpuConstraintInfo2;\n" -"void getSkewSymmetricMatrix(float4 vecIn, __global float4* v0,__global float4* v1,__global float4* v2)\n" -"{\n" -" *v0 = (float4)(0. ,-vecIn.z ,vecIn.y,0.f);\n" -" *v1 = (float4)(vecIn.z ,0. ,-vecIn.x,0.f);\n" -" *v2 = (float4)(-vecIn.y ,vecIn.x ,0.f,0.f);\n" -"}\n" -"void getInfo2Point2Point(__global b3GpuGenericConstraint* constraint,b3GpuConstraintInfo2* info,__global b3RigidBodyCL* bodies)\n" -"{\n" -" float4 posA = bodies[constraint->m_rbA].m_pos;\n" -" Quaternion rotA = bodies[constraint->m_rbA].m_quat;\n" -" float4 posB = bodies[constraint->m_rbB].m_pos;\n" -" Quaternion rotB = bodies[constraint->m_rbB].m_quat;\n" -" // anchor points in global coordinates with respect to body PORs.\n" -" \n" -" // set jacobian\n" -" info->m_J1linearAxis[0] = 1;\n" -" info->m_J1linearAxis[info->rowskip+1] = 1;\n" -" info->m_J1linearAxis[2*info->rowskip+2] = 1;\n" -" float4 a1 = qtRotate(rotA,constraint->m_pivotInA);\n" -" {\n" -" __global float4* angular0 = (__global float4*)(info->m_J1angularAxis);\n" -" __global float4* angular1 = (__global float4*)(info->m_J1angularAxis+info->rowskip);\n" -" __global float4* angular2 = (__global float4*)(info->m_J1angularAxis+2*info->rowskip);\n" -" float4 a1neg = -a1;\n" -" getSkewSymmetricMatrix(a1neg,angular0,angular1,angular2);\n" -" }\n" -" if (info->m_J2linearAxis)\n" -" {\n" -" info->m_J2linearAxis[0] = -1;\n" -" info->m_J2linearAxis[info->rowskip+1] = -1;\n" -" info->m_J2linearAxis[2*info->rowskip+2] = -1;\n" -" }\n" -" \n" -" float4 a2 = qtRotate(rotB,constraint->m_pivotInB);\n" -" \n" -" {\n" -" // float4 a2n = -a2;\n" -" __global float4* angular0 = (__global float4*)(info->m_J2angularAxis);\n" -" __global float4* angular1 = (__global float4*)(info->m_J2angularAxis+info->rowskip);\n" -" __global float4* angular2 = (__global float4*)(info->m_J2angularAxis+2*info->rowskip);\n" -" getSkewSymmetricMatrix(a2,angular0,angular1,angular2);\n" -" }\n" -" \n" -" // set right hand side\n" -"// float currERP = (m_flags & B3_P2P_FLAGS_ERP) ? m_erp : info->erp;\n" -" float currERP = info->erp;\n" -" float k = info->fps * currERP;\n" -" int j;\n" -" float4 result = a2 + posB - a1 - posA;\n" -" float* resultPtr = &result;\n" -" for (j=0; j<3; j++)\n" -" {\n" -" info->m_constraintError[j*info->rowskip] = k * (resultPtr[j]);\n" -" }\n" -"}\n" -"Quaternion nearest( Quaternion first, Quaternion qd)\n" -"{\n" -" Quaternion diff,sum;\n" -" diff = first- qd;\n" -" sum = first + qd;\n" -" \n" -" if( dot(diff,diff) < dot(sum,sum) )\n" -" return qd;\n" -" return (-qd);\n" -"}\n" -"float b3Acos(float x) \n" -"{ \n" -" if (x<-1) \n" -" x=-1; \n" -" if (x>1) \n" -" x=1;\n" -" return acos(x); \n" -"}\n" -"float getAngle(Quaternion orn)\n" -"{\n" -" if (orn.w>=1.f)\n" -" orn.w=1.f;\n" -" float s = 2.f * b3Acos(orn.w);\n" -" return s;\n" -"}\n" -"void calculateDiffAxisAngleQuaternion( Quaternion orn0,Quaternion orn1a,float4* axis,float* angle)\n" -"{\n" -" Quaternion orn1 = nearest(orn0,orn1a);\n" -" \n" -" Quaternion dorn = qtMul(orn1,qtInvert(orn0));\n" -" *angle = getAngle(dorn);\n" -" *axis = (float4)(dorn.x,dorn.y,dorn.z,0.f);\n" -" \n" -" //check for axis length\n" -" float len = dot3F4(*axis,*axis);\n" -" if (len < FLT_EPSILON*FLT_EPSILON)\n" -" *axis = (float4)(1,0,0,0);\n" -" else\n" -" *axis /= sqrt(len);\n" -"}\n" -"void getInfo2FixedOrientation(__global b3GpuGenericConstraint* constraint,b3GpuConstraintInfo2* info,__global b3RigidBodyCL* bodies, int start_row)\n" -"{\n" -" Quaternion worldOrnA = bodies[constraint->m_rbA].m_quat;\n" -" Quaternion worldOrnB = bodies[constraint->m_rbB].m_quat;\n" -" int s = info->rowskip;\n" -" int start_index = start_row * s;\n" -" // 3 rows to make body rotations equal\n" -" info->m_J1angularAxis[start_index] = 1;\n" -" info->m_J1angularAxis[start_index + s + 1] = 1;\n" -" info->m_J1angularAxis[start_index + s*2+2] = 1;\n" -" if ( info->m_J2angularAxis)\n" -" {\n" -" info->m_J2angularAxis[start_index] = -1;\n" -" info->m_J2angularAxis[start_index + s+1] = -1;\n" -" info->m_J2angularAxis[start_index + s*2+2] = -1;\n" -" }\n" -" \n" -" float currERP = info->erp;\n" -" float k = info->fps * currERP;\n" -" float4 diff;\n" -" float angle;\n" -" float4 qrelCur = qtMul(worldOrnA,qtInvert(worldOrnB));\n" -" \n" -" calculateDiffAxisAngleQuaternion(constraint->m_relTargetAB,qrelCur,&diff,&angle);\n" -" diff*=-angle;\n" -" \n" -" float* resultPtr = &diff;\n" -" \n" -" for (int j=0; j<3; j++)\n" -" {\n" -" info->m_constraintError[(3+j)*info->rowskip] = k * resultPtr[j];\n" -" }\n" -" \n" -"}\n" -"__kernel void writeBackVelocitiesKernel(__global b3RigidBodyCL* bodies,__global b3GpuSolverBody* solverBodies,int numBodies)\n" -"{\n" -" int i = get_global_id(0);\n" -" if (i>=numBodies)\n" -" return;\n" -" if (bodies[i].m_invMass)\n" -" {\n" -"// if (length(solverBodies[i].m_deltaLinearVelocity)=numConstraints)\n" -" return;\n" -" \n" -" //for now, always initialize the batch info\n" -" int info1 = infos[i];\n" -" \n" -" __global b3SolverConstraint* currentConstraintRow = &solverConstraintRows[constraintRowOffsets[i]];\n" -" __global b3GpuGenericConstraint* constraint = &constraints[i];\n" -" __global b3RigidBodyCL* rbA = &bodies[ constraint->m_rbA];\n" -" __global b3RigidBodyCL* rbB = &bodies[ constraint->m_rbB];\n" -" int solverBodyIdA = constraint->m_rbA;\n" -" int solverBodyIdB = constraint->m_rbB;\n" -" __global b3GpuSolverBody* bodyAPtr = &solverBodies[solverBodyIdA];\n" -" __global b3GpuSolverBody* bodyBPtr = &solverBodies[solverBodyIdB];\n" -" if (rbA->m_invMass)\n" -" {\n" -" batchConstraints[i].m_bodyAPtrAndSignBit = solverBodyIdA;\n" -" } else\n" -" {\n" -"// if (!solverBodyIdA)\n" -"// m_staticIdx = 0;\n" -" batchConstraints[i].m_bodyAPtrAndSignBit = -solverBodyIdA;\n" -" }\n" -" if (rbB->m_invMass)\n" -" {\n" -" batchConstraints[i].m_bodyBPtrAndSignBit = solverBodyIdB;\n" -" } else\n" -" {\n" -"// if (!solverBodyIdB)\n" -"// m_staticIdx = 0;\n" -" batchConstraints[i].m_bodyBPtrAndSignBit = -solverBodyIdB;\n" -" }\n" -" if (info1)\n" -" {\n" -" int overrideNumSolverIterations = 0;//constraint->getOverrideNumSolverIterations() > 0 ? constraint->getOverrideNumSolverIterations() : infoGlobal.m_numIterations;\n" -"// if (overrideNumSolverIterations>m_maxOverrideNumSolverIterations)\n" -" // m_maxOverrideNumSolverIterations = overrideNumSolverIterations;\n" -" int j;\n" -" for ( j=0;jm_deltaLinearVelocity = (float4)(0,0,0,0);\n" -" bodyAPtr->m_deltaAngularVelocity = (float4)(0,0,0,0);\n" -" bodyAPtr->m_pushVelocity = (float4)(0,0,0,0);\n" -" bodyAPtr->m_turnVelocity = (float4)(0,0,0,0);\n" -" bodyBPtr->m_deltaLinearVelocity = (float4)(0,0,0,0);\n" -" bodyBPtr->m_deltaAngularVelocity = (float4)(0,0,0,0);\n" -" bodyBPtr->m_pushVelocity = (float4)(0,0,0,0);\n" -" bodyBPtr->m_turnVelocity = (float4)(0,0,0,0);\n" -" int rowskip = sizeof(b3SolverConstraint)/sizeof(float);//check this\n" -" \n" -" b3GpuConstraintInfo2 info2;\n" -" info2.fps = 1.f/timeStep;\n" -" info2.erp = globalErp;\n" -" info2.m_J1linearAxisFloat4 = ¤tConstraintRow->m_contactNormal;\n" -" info2.m_J1angularAxisFloat4 = ¤tConstraintRow->m_relpos1CrossNormal;\n" -" info2.m_J2linearAxisFloat4 = 0;\n" -" info2.m_J2angularAxisFloat4 = ¤tConstraintRow->m_relpos2CrossNormal;\n" -" info2.rowskip = sizeof(b3SolverConstraint)/sizeof(float);//check this\n" -" ///the size of b3SolverConstraint needs be a multiple of float\n" -"// b3Assert(info2.rowskip*sizeof(float)== sizeof(b3SolverConstraint));\n" -" info2.m_constraintError = ¤tConstraintRow->m_rhs;\n" -" currentConstraintRow->m_cfm = globalCfm;\n" -" info2.m_damping = globalDamping;\n" -" info2.cfm = ¤tConstraintRow->m_cfm;\n" -" info2.m_lowerLimit = ¤tConstraintRow->m_lowerLimit;\n" -" info2.m_upperLimit = ¤tConstraintRow->m_upperLimit;\n" -" info2.m_numIterations = globalNumIterations;\n" -" switch (constraint->m_constraintType)\n" -" {\n" -" case B3_GPU_POINT2POINT_CONSTRAINT_TYPE:\n" -" {\n" -" getInfo2Point2Point(constraint,&info2,bodies);\n" -" break;\n" -" }\n" -" case B3_GPU_FIXED_CONSTRAINT_TYPE:\n" -" {\n" -" getInfo2Point2Point(constraint,&info2,bodies);\n" -" getInfo2FixedOrientation(constraint,&info2,bodies,3);\n" -" break;\n" -" }\n" -" default:\n" -" {\n" -" }\n" -" }\n" -" ///finalize the constraint setup\n" -" for ( j=0;jm_upperLimit>=constraint->m_breakingImpulseThreshold)\n" -" {\n" -" solverConstraint->m_upperLimit = constraint->m_breakingImpulseThreshold;\n" -" }\n" -" if (solverConstraint->m_lowerLimit<=-constraint->m_breakingImpulseThreshold)\n" -" {\n" -" solverConstraint->m_lowerLimit = -constraint->m_breakingImpulseThreshold;\n" -" }\n" -"// solverConstraint->m_originalContactPoint = constraint;\n" -" \n" -" Matrix3x3 invInertiaWorldA= inertias[constraint->m_rbA].m_invInertiaWorld;\n" -" {\n" -" //float4 angularFactorA(1,1,1);\n" -" float4 ftorqueAxis1 = solverConstraint->m_relpos1CrossNormal;\n" -" solverConstraint->m_angularComponentA = mtMul1(invInertiaWorldA,ftorqueAxis1);//*angularFactorA;\n" -" }\n" -" \n" -" Matrix3x3 invInertiaWorldB= inertias[constraint->m_rbB].m_invInertiaWorld;\n" -" {\n" -" float4 ftorqueAxis2 = solverConstraint->m_relpos2CrossNormal;\n" -" solverConstraint->m_angularComponentB = mtMul1(invInertiaWorldB,ftorqueAxis2);//*constraint->m_rbB.getAngularFactor();\n" -" }\n" -" {\n" -" //it is ok to use solverConstraint->m_contactNormal instead of -solverConstraint->m_contactNormal\n" -" //because it gets multiplied iMJlB\n" -" float4 iMJlA = solverConstraint->m_contactNormal*rbA->m_invMass;\n" -" float4 iMJaA = mtMul3(solverConstraint->m_relpos1CrossNormal,invInertiaWorldA);\n" -" float4 iMJlB = solverConstraint->m_contactNormal*rbB->m_invMass;//sign of normal?\n" -" float4 iMJaB = mtMul3(solverConstraint->m_relpos2CrossNormal,invInertiaWorldB);\n" -" float sum = dot3F4(iMJlA,solverConstraint->m_contactNormal);\n" -" sum += dot3F4(iMJaA,solverConstraint->m_relpos1CrossNormal);\n" -" sum += dot3F4(iMJlB,solverConstraint->m_contactNormal);\n" -" sum += dot3F4(iMJaB,solverConstraint->m_relpos2CrossNormal);\n" -" float fsum = fabs(sum);\n" -" if (fsum>FLT_EPSILON)\n" -" {\n" -" solverConstraint->m_jacDiagABInv = 1.f/sum;\n" -" } else\n" -" {\n" -" solverConstraint->m_jacDiagABInv = 0.f;\n" -" }\n" -" }\n" -" ///fix rhs\n" -" ///todo: add force/torque accelerators\n" -" {\n" -" float rel_vel;\n" -" float vel1Dotn = dot3F4(solverConstraint->m_contactNormal,rbA->m_linVel) + dot3F4(solverConstraint->m_relpos1CrossNormal,rbA->m_angVel);\n" -" float vel2Dotn = -dot3F4(solverConstraint->m_contactNormal,rbB->m_linVel) + dot3F4(solverConstraint->m_relpos2CrossNormal,rbB->m_angVel);\n" -" rel_vel = vel1Dotn+vel2Dotn;\n" -" float restitution = 0.f;\n" -" float positionalError = solverConstraint->m_rhs;//already filled in by getConstraintInfo2\n" -" float velocityError = restitution - rel_vel * info2.m_damping;\n" -" float penetrationImpulse = positionalError*solverConstraint->m_jacDiagABInv;\n" -" float velocityImpulse = velocityError *solverConstraint->m_jacDiagABInv;\n" -" solverConstraint->m_rhs = penetrationImpulse+velocityImpulse;\n" -" solverConstraint->m_appliedImpulse = 0.f;\n" -" }\n" -" }\n" -" }\n" -"}\n" -; +static const char* solveConstraintRowsCL = + "/*\n" + "Copyright (c) 2013 Advanced Micro Devices, Inc. \n" + "This software is provided 'as-is', without any express or implied warranty.\n" + "In no event will the authors be held liable for any damages arising from the use of this software.\n" + "Permission is granted to anyone to use this software for any purpose, \n" + "including commercial applications, and to alter it and redistribute it freely, \n" + "subject to the following restrictions:\n" + "1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" + "2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" + "3. This notice may not be removed or altered from any source distribution.\n" + "*/\n" + "//Originally written by Erwin Coumans\n" + "#define B3_CONSTRAINT_FLAG_ENABLED 1\n" + "#define B3_GPU_POINT2POINT_CONSTRAINT_TYPE 3\n" + "#define B3_GPU_FIXED_CONSTRAINT_TYPE 4\n" + "#define MOTIONCLAMP 100000 //unused, for debugging/safety in case constraint solver fails\n" + "#define B3_INFINITY 1e30f\n" + "#define mymake_float4 (float4)\n" + "__inline float dot3F4(float4 a, float4 b)\n" + "{\n" + " float4 a1 = mymake_float4(a.xyz,0.f);\n" + " float4 b1 = mymake_float4(b.xyz,0.f);\n" + " return dot(a1, b1);\n" + "}\n" + "typedef float4 Quaternion;\n" + "typedef struct\n" + "{\n" + " float4 m_row[3];\n" + "}Matrix3x3;\n" + "__inline\n" + "float4 mtMul1(Matrix3x3 a, float4 b);\n" + "__inline\n" + "float4 mtMul3(float4 a, Matrix3x3 b);\n" + "__inline\n" + "float4 mtMul1(Matrix3x3 a, float4 b)\n" + "{\n" + " float4 ans;\n" + " ans.x = dot3F4( a.m_row[0], b );\n" + " ans.y = dot3F4( a.m_row[1], b );\n" + " ans.z = dot3F4( a.m_row[2], b );\n" + " ans.w = 0.f;\n" + " return ans;\n" + "}\n" + "__inline\n" + "float4 mtMul3(float4 a, Matrix3x3 b)\n" + "{\n" + " float4 colx = mymake_float4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" + " float4 coly = mymake_float4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" + " float4 colz = mymake_float4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" + " float4 ans;\n" + " ans.x = dot3F4( a, colx );\n" + " ans.y = dot3F4( a, coly );\n" + " ans.z = dot3F4( a, colz );\n" + " return ans;\n" + "}\n" + "typedef struct\n" + "{\n" + " Matrix3x3 m_invInertiaWorld;\n" + " Matrix3x3 m_initInvInertia;\n" + "} BodyInertia;\n" + "typedef struct\n" + "{\n" + " Matrix3x3 m_basis;//orientation\n" + " float4 m_origin;//transform\n" + "}b3Transform;\n" + "typedef struct\n" + "{\n" + "// b3Transform m_worldTransformUnused;\n" + " float4 m_deltaLinearVelocity;\n" + " float4 m_deltaAngularVelocity;\n" + " float4 m_angularFactor;\n" + " float4 m_linearFactor;\n" + " float4 m_invMass;\n" + " float4 m_pushVelocity;\n" + " float4 m_turnVelocity;\n" + " float4 m_linearVelocity;\n" + " float4 m_angularVelocity;\n" + " union \n" + " {\n" + " void* m_originalBody;\n" + " int m_originalBodyIndex;\n" + " };\n" + " int padding[3];\n" + "} b3GpuSolverBody;\n" + "typedef struct\n" + "{\n" + " float4 m_pos;\n" + " Quaternion m_quat;\n" + " float4 m_linVel;\n" + " float4 m_angVel;\n" + " unsigned int m_shapeIdx;\n" + " float m_invMass;\n" + " float m_restituitionCoeff;\n" + " float m_frictionCoeff;\n" + "} b3RigidBodyCL;\n" + "typedef struct\n" + "{\n" + " float4 m_relpos1CrossNormal;\n" + " float4 m_contactNormal;\n" + " float4 m_relpos2CrossNormal;\n" + " //float4 m_contactNormal2;//usually m_contactNormal2 == -m_contactNormal\n" + " float4 m_angularComponentA;\n" + " float4 m_angularComponentB;\n" + " \n" + " float m_appliedPushImpulse;\n" + " float m_appliedImpulse;\n" + " int m_padding1;\n" + " int m_padding2;\n" + " float m_friction;\n" + " float m_jacDiagABInv;\n" + " float m_rhs;\n" + " float m_cfm;\n" + " \n" + " float m_lowerLimit;\n" + " float m_upperLimit;\n" + " float m_rhsPenetration;\n" + " int m_originalConstraint;\n" + " int m_overrideNumSolverIterations;\n" + " int m_frictionIndex;\n" + " int m_solverBodyIdA;\n" + " int m_solverBodyIdB;\n" + "} b3SolverConstraint;\n" + "typedef struct \n" + "{\n" + " int m_bodyAPtrAndSignBit;\n" + " int m_bodyBPtrAndSignBit;\n" + " int m_originalConstraintIndex;\n" + " int m_batchId;\n" + "} b3BatchConstraint;\n" + "typedef struct \n" + "{\n" + " int m_constraintType;\n" + " int m_rbA;\n" + " int m_rbB;\n" + " float m_breakingImpulseThreshold;\n" + " float4 m_pivotInA;\n" + " float4 m_pivotInB;\n" + " Quaternion m_relTargetAB;\n" + " int m_flags;\n" + " int m_padding[3];\n" + "} b3GpuGenericConstraint;\n" + "/*b3Transform getWorldTransform(b3RigidBodyCL* rb)\n" + "{\n" + " b3Transform newTrans;\n" + " newTrans.setOrigin(rb->m_pos);\n" + " newTrans.setRotation(rb->m_quat);\n" + " return newTrans;\n" + "}*/\n" + "__inline\n" + "float4 cross3(float4 a, float4 b)\n" + "{\n" + " return cross(a,b);\n" + "}\n" + "__inline\n" + "float4 fastNormalize4(float4 v)\n" + "{\n" + " v = mymake_float4(v.xyz,0.f);\n" + " return fast_normalize(v);\n" + "}\n" + "__inline\n" + "Quaternion qtMul(Quaternion a, Quaternion b);\n" + "__inline\n" + "Quaternion qtNormalize(Quaternion in);\n" + "__inline\n" + "float4 qtRotate(Quaternion q, float4 vec);\n" + "__inline\n" + "Quaternion qtInvert(Quaternion q);\n" + "__inline\n" + "Quaternion qtMul(Quaternion a, Quaternion b)\n" + "{\n" + " Quaternion ans;\n" + " ans = cross3( a, b );\n" + " ans += a.w*b+b.w*a;\n" + "// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" + " ans.w = a.w*b.w - dot3F4(a, b);\n" + " return ans;\n" + "}\n" + "__inline\n" + "Quaternion qtNormalize(Quaternion in)\n" + "{\n" + " return fastNormalize4(in);\n" + "// in /= length( in );\n" + "// return in;\n" + "}\n" + "__inline\n" + "float4 qtRotate(Quaternion q, float4 vec)\n" + "{\n" + " Quaternion qInv = qtInvert( q );\n" + " float4 vcpy = vec;\n" + " vcpy.w = 0.f;\n" + " float4 out = qtMul(qtMul(q,vcpy),qInv);\n" + " return out;\n" + "}\n" + "__inline\n" + "Quaternion qtInvert(Quaternion q)\n" + "{\n" + " return (Quaternion)(-q.xyz, q.w);\n" + "}\n" + "__inline void internalApplyImpulse(__global b3GpuSolverBody* body, float4 linearComponent, float4 angularComponent,float impulseMagnitude)\n" + "{\n" + " body->m_deltaLinearVelocity += linearComponent*impulseMagnitude*body->m_linearFactor;\n" + " body->m_deltaAngularVelocity += angularComponent*(impulseMagnitude*body->m_angularFactor);\n" + "}\n" + "void resolveSingleConstraintRowGeneric(__global b3GpuSolverBody* body1, __global b3GpuSolverBody* body2, __global b3SolverConstraint* c)\n" + "{\n" + " float deltaImpulse = c->m_rhs-c->m_appliedImpulse*c->m_cfm;\n" + " float deltaVel1Dotn = dot3F4(c->m_contactNormal,body1->m_deltaLinearVelocity) + dot3F4(c->m_relpos1CrossNormal,body1->m_deltaAngularVelocity);\n" + " float deltaVel2Dotn = -dot3F4(c->m_contactNormal,body2->m_deltaLinearVelocity) + dot3F4(c->m_relpos2CrossNormal,body2->m_deltaAngularVelocity);\n" + " deltaImpulse -= deltaVel1Dotn*c->m_jacDiagABInv;\n" + " deltaImpulse -= deltaVel2Dotn*c->m_jacDiagABInv;\n" + " float sum = c->m_appliedImpulse + deltaImpulse;\n" + " if (sum < c->m_lowerLimit)\n" + " {\n" + " deltaImpulse = c->m_lowerLimit-c->m_appliedImpulse;\n" + " c->m_appliedImpulse = c->m_lowerLimit;\n" + " }\n" + " else if (sum > c->m_upperLimit) \n" + " {\n" + " deltaImpulse = c->m_upperLimit-c->m_appliedImpulse;\n" + " c->m_appliedImpulse = c->m_upperLimit;\n" + " }\n" + " else\n" + " {\n" + " c->m_appliedImpulse = sum;\n" + " }\n" + " internalApplyImpulse(body1,c->m_contactNormal*body1->m_invMass,c->m_angularComponentA,deltaImpulse);\n" + " internalApplyImpulse(body2,-c->m_contactNormal*body2->m_invMass,c->m_angularComponentB,deltaImpulse);\n" + "}\n" + "__kernel void solveJointConstraintRows(__global b3GpuSolverBody* solverBodies,\n" + " __global b3BatchConstraint* batchConstraints,\n" + " __global b3SolverConstraint* rows,\n" + " __global unsigned int* numConstraintRowsInfo1, \n" + " __global unsigned int* rowOffsets,\n" + " __global b3GpuGenericConstraint* constraints,\n" + " int batchOffset,\n" + " int numConstraintsInBatch\n" + " )\n" + "{\n" + " int b = get_global_id(0);\n" + " if (b>=numConstraintsInBatch)\n" + " return;\n" + " __global b3BatchConstraint* c = &batchConstraints[b+batchOffset];\n" + " int originalConstraintIndex = c->m_originalConstraintIndex;\n" + " if (constraints[originalConstraintIndex].m_flags&B3_CONSTRAINT_FLAG_ENABLED)\n" + " {\n" + " int numConstraintRows = numConstraintRowsInfo1[originalConstraintIndex];\n" + " int rowOffset = rowOffsets[originalConstraintIndex];\n" + " for (int jj=0;jjm_solverBodyIdA],&solverBodies[constraint->m_solverBodyIdB],constraint);\n" + " }\n" + " }\n" + "};\n" + "__kernel void initSolverBodies(__global b3GpuSolverBody* solverBodies,__global b3RigidBodyCL* bodiesCL, int numBodies)\n" + "{\n" + " int i = get_global_id(0);\n" + " if (i>=numBodies)\n" + " return;\n" + " __global b3GpuSolverBody* solverBody = &solverBodies[i];\n" + " __global b3RigidBodyCL* bodyCL = &bodiesCL[i];\n" + " solverBody->m_deltaLinearVelocity = (float4)(0.f,0.f,0.f,0.f);\n" + " solverBody->m_deltaAngularVelocity = (float4)(0.f,0.f,0.f,0.f);\n" + " solverBody->m_pushVelocity = (float4)(0.f,0.f,0.f,0.f);\n" + " solverBody->m_pushVelocity = (float4)(0.f,0.f,0.f,0.f);\n" + " solverBody->m_invMass = (float4)(bodyCL->m_invMass,bodyCL->m_invMass,bodyCL->m_invMass,0.f);\n" + " solverBody->m_originalBodyIndex = i;\n" + " solverBody->m_angularFactor = (float4)(1,1,1,0);\n" + " solverBody->m_linearFactor = (float4) (1,1,1,0);\n" + " solverBody->m_linearVelocity = bodyCL->m_linVel;\n" + " solverBody->m_angularVelocity = bodyCL->m_angVel;\n" + "}\n" + "__kernel void breakViolatedConstraintsKernel(__global b3GpuGenericConstraint* constraints, __global unsigned int* numConstraintRows, __global unsigned int* rowOffsets, __global b3SolverConstraint* rows, int numConstraints)\n" + "{\n" + " int cid = get_global_id(0);\n" + " if (cid>=numConstraints)\n" + " return;\n" + " int numRows = numConstraintRows[cid];\n" + " if (numRows)\n" + " {\n" + " for (int i=0;i= breakingThreshold)\n" + " {\n" + " constraints[cid].m_flags =0;//&= ~B3_CONSTRAINT_FLAG_ENABLED;\n" + " }\n" + " }\n" + " }\n" + "}\n" + "__kernel void getInfo1Kernel(__global unsigned int* infos, __global b3GpuGenericConstraint* constraints, int numConstraints)\n" + "{\n" + " int i = get_global_id(0);\n" + " if (i>=numConstraints)\n" + " return;\n" + " __global b3GpuGenericConstraint* constraint = &constraints[i];\n" + " switch (constraint->m_constraintType)\n" + " {\n" + " case B3_GPU_POINT2POINT_CONSTRAINT_TYPE:\n" + " {\n" + " infos[i] = 3;\n" + " break;\n" + " }\n" + " case B3_GPU_FIXED_CONSTRAINT_TYPE:\n" + " {\n" + " infos[i] = 6;\n" + " break;\n" + " }\n" + " default:\n" + " {\n" + " }\n" + " }\n" + "}\n" + "__kernel void initBatchConstraintsKernel(__global unsigned int* numConstraintRows, __global unsigned int* rowOffsets, \n" + " __global b3BatchConstraint* batchConstraints, \n" + " __global b3GpuGenericConstraint* constraints,\n" + " __global b3RigidBodyCL* bodies,\n" + " int numConstraints)\n" + "{\n" + " int i = get_global_id(0);\n" + " if (i>=numConstraints)\n" + " return;\n" + " int rbA = constraints[i].m_rbA;\n" + " int rbB = constraints[i].m_rbB;\n" + " batchConstraints[i].m_bodyAPtrAndSignBit = bodies[rbA].m_invMass != 0.f ? rbA : -rbA;\n" + " batchConstraints[i].m_bodyBPtrAndSignBit = bodies[rbB].m_invMass != 0.f ? rbB : -rbB;\n" + " batchConstraints[i].m_batchId = -1;\n" + " batchConstraints[i].m_originalConstraintIndex = i;\n" + "}\n" + "typedef struct\n" + "{\n" + " // integrator parameters: frames per second (1/stepsize), default error\n" + " // reduction parameter (0..1).\n" + " float fps,erp;\n" + " // for the first and second body, pointers to two (linear and angular)\n" + " // n*3 jacobian sub matrices, stored by rows. these matrices will have\n" + " // been initialized to 0 on entry. if the second body is zero then the\n" + " // J2xx pointers may be 0.\n" + " union \n" + " {\n" + " __global float4* m_J1linearAxisFloat4;\n" + " __global float* m_J1linearAxis;\n" + " };\n" + " union\n" + " {\n" + " __global float4* m_J1angularAxisFloat4;\n" + " __global float* m_J1angularAxis;\n" + " };\n" + " union\n" + " {\n" + " __global float4* m_J2linearAxisFloat4;\n" + " __global float* m_J2linearAxis;\n" + " };\n" + " union\n" + " {\n" + " __global float4* m_J2angularAxisFloat4;\n" + " __global float* m_J2angularAxis;\n" + " };\n" + " // elements to jump from one row to the next in J's\n" + " int rowskip;\n" + " // right hand sides of the equation J*v = c + cfm * lambda. cfm is the\n" + " // \"constraint force mixing\" vector. c is set to zero on entry, cfm is\n" + " // set to a constant value (typically very small or zero) value on entry.\n" + " __global float* m_constraintError;\n" + " __global float* cfm;\n" + " // lo and hi limits for variables (set to -/+ infinity on entry).\n" + " __global float* m_lowerLimit;\n" + " __global float* m_upperLimit;\n" + " // findex vector for variables. see the LCP solver interface for a\n" + " // description of what this does. this is set to -1 on entry.\n" + " // note that the returned indexes are relative to the first index of\n" + " // the constraint.\n" + " __global int *findex;\n" + " // number of solver iterations\n" + " int m_numIterations;\n" + " //damping of the velocity\n" + " float m_damping;\n" + "} b3GpuConstraintInfo2;\n" + "void getSkewSymmetricMatrix(float4 vecIn, __global float4* v0,__global float4* v1,__global float4* v2)\n" + "{\n" + " *v0 = (float4)(0. ,-vecIn.z ,vecIn.y,0.f);\n" + " *v1 = (float4)(vecIn.z ,0. ,-vecIn.x,0.f);\n" + " *v2 = (float4)(-vecIn.y ,vecIn.x ,0.f,0.f);\n" + "}\n" + "void getInfo2Point2Point(__global b3GpuGenericConstraint* constraint,b3GpuConstraintInfo2* info,__global b3RigidBodyCL* bodies)\n" + "{\n" + " float4 posA = bodies[constraint->m_rbA].m_pos;\n" + " Quaternion rotA = bodies[constraint->m_rbA].m_quat;\n" + " float4 posB = bodies[constraint->m_rbB].m_pos;\n" + " Quaternion rotB = bodies[constraint->m_rbB].m_quat;\n" + " // anchor points in global coordinates with respect to body PORs.\n" + " \n" + " // set jacobian\n" + " info->m_J1linearAxis[0] = 1;\n" + " info->m_J1linearAxis[info->rowskip+1] = 1;\n" + " info->m_J1linearAxis[2*info->rowskip+2] = 1;\n" + " float4 a1 = qtRotate(rotA,constraint->m_pivotInA);\n" + " {\n" + " __global float4* angular0 = (__global float4*)(info->m_J1angularAxis);\n" + " __global float4* angular1 = (__global float4*)(info->m_J1angularAxis+info->rowskip);\n" + " __global float4* angular2 = (__global float4*)(info->m_J1angularAxis+2*info->rowskip);\n" + " float4 a1neg = -a1;\n" + " getSkewSymmetricMatrix(a1neg,angular0,angular1,angular2);\n" + " }\n" + " if (info->m_J2linearAxis)\n" + " {\n" + " info->m_J2linearAxis[0] = -1;\n" + " info->m_J2linearAxis[info->rowskip+1] = -1;\n" + " info->m_J2linearAxis[2*info->rowskip+2] = -1;\n" + " }\n" + " \n" + " float4 a2 = qtRotate(rotB,constraint->m_pivotInB);\n" + " \n" + " {\n" + " // float4 a2n = -a2;\n" + " __global float4* angular0 = (__global float4*)(info->m_J2angularAxis);\n" + " __global float4* angular1 = (__global float4*)(info->m_J2angularAxis+info->rowskip);\n" + " __global float4* angular2 = (__global float4*)(info->m_J2angularAxis+2*info->rowskip);\n" + " getSkewSymmetricMatrix(a2,angular0,angular1,angular2);\n" + " }\n" + " \n" + " // set right hand side\n" + "// float currERP = (m_flags & B3_P2P_FLAGS_ERP) ? m_erp : info->erp;\n" + " float currERP = info->erp;\n" + " float k = info->fps * currERP;\n" + " int j;\n" + " float4 result = a2 + posB - a1 - posA;\n" + " float* resultPtr = &result;\n" + " for (j=0; j<3; j++)\n" + " {\n" + " info->m_constraintError[j*info->rowskip] = k * (resultPtr[j]);\n" + " }\n" + "}\n" + "Quaternion nearest( Quaternion first, Quaternion qd)\n" + "{\n" + " Quaternion diff,sum;\n" + " diff = first- qd;\n" + " sum = first + qd;\n" + " \n" + " if( dot(diff,diff) < dot(sum,sum) )\n" + " return qd;\n" + " return (-qd);\n" + "}\n" + "float b3Acos(float x) \n" + "{ \n" + " if (x<-1) \n" + " x=-1; \n" + " if (x>1) \n" + " x=1;\n" + " return acos(x); \n" + "}\n" + "float getAngle(Quaternion orn)\n" + "{\n" + " if (orn.w>=1.f)\n" + " orn.w=1.f;\n" + " float s = 2.f * b3Acos(orn.w);\n" + " return s;\n" + "}\n" + "void calculateDiffAxisAngleQuaternion( Quaternion orn0,Quaternion orn1a,float4* axis,float* angle)\n" + "{\n" + " Quaternion orn1 = nearest(orn0,orn1a);\n" + " \n" + " Quaternion dorn = qtMul(orn1,qtInvert(orn0));\n" + " *angle = getAngle(dorn);\n" + " *axis = (float4)(dorn.x,dorn.y,dorn.z,0.f);\n" + " \n" + " //check for axis length\n" + " float len = dot3F4(*axis,*axis);\n" + " if (len < FLT_EPSILON*FLT_EPSILON)\n" + " *axis = (float4)(1,0,0,0);\n" + " else\n" + " *axis /= sqrt(len);\n" + "}\n" + "void getInfo2FixedOrientation(__global b3GpuGenericConstraint* constraint,b3GpuConstraintInfo2* info,__global b3RigidBodyCL* bodies, int start_row)\n" + "{\n" + " Quaternion worldOrnA = bodies[constraint->m_rbA].m_quat;\n" + " Quaternion worldOrnB = bodies[constraint->m_rbB].m_quat;\n" + " int s = info->rowskip;\n" + " int start_index = start_row * s;\n" + " // 3 rows to make body rotations equal\n" + " info->m_J1angularAxis[start_index] = 1;\n" + " info->m_J1angularAxis[start_index + s + 1] = 1;\n" + " info->m_J1angularAxis[start_index + s*2+2] = 1;\n" + " if ( info->m_J2angularAxis)\n" + " {\n" + " info->m_J2angularAxis[start_index] = -1;\n" + " info->m_J2angularAxis[start_index + s+1] = -1;\n" + " info->m_J2angularAxis[start_index + s*2+2] = -1;\n" + " }\n" + " \n" + " float currERP = info->erp;\n" + " float k = info->fps * currERP;\n" + " float4 diff;\n" + " float angle;\n" + " float4 qrelCur = qtMul(worldOrnA,qtInvert(worldOrnB));\n" + " \n" + " calculateDiffAxisAngleQuaternion(constraint->m_relTargetAB,qrelCur,&diff,&angle);\n" + " diff*=-angle;\n" + " \n" + " float* resultPtr = &diff;\n" + " \n" + " for (int j=0; j<3; j++)\n" + " {\n" + " info->m_constraintError[(3+j)*info->rowskip] = k * resultPtr[j];\n" + " }\n" + " \n" + "}\n" + "__kernel void writeBackVelocitiesKernel(__global b3RigidBodyCL* bodies,__global b3GpuSolverBody* solverBodies,int numBodies)\n" + "{\n" + " int i = get_global_id(0);\n" + " if (i>=numBodies)\n" + " return;\n" + " if (bodies[i].m_invMass)\n" + " {\n" + "// if (length(solverBodies[i].m_deltaLinearVelocity)=numConstraints)\n" + " return;\n" + " \n" + " //for now, always initialize the batch info\n" + " int info1 = infos[i];\n" + " \n" + " __global b3SolverConstraint* currentConstraintRow = &solverConstraintRows[constraintRowOffsets[i]];\n" + " __global b3GpuGenericConstraint* constraint = &constraints[i];\n" + " __global b3RigidBodyCL* rbA = &bodies[ constraint->m_rbA];\n" + " __global b3RigidBodyCL* rbB = &bodies[ constraint->m_rbB];\n" + " int solverBodyIdA = constraint->m_rbA;\n" + " int solverBodyIdB = constraint->m_rbB;\n" + " __global b3GpuSolverBody* bodyAPtr = &solverBodies[solverBodyIdA];\n" + " __global b3GpuSolverBody* bodyBPtr = &solverBodies[solverBodyIdB];\n" + " if (rbA->m_invMass)\n" + " {\n" + " batchConstraints[i].m_bodyAPtrAndSignBit = solverBodyIdA;\n" + " } else\n" + " {\n" + "// if (!solverBodyIdA)\n" + "// m_staticIdx = 0;\n" + " batchConstraints[i].m_bodyAPtrAndSignBit = -solverBodyIdA;\n" + " }\n" + " if (rbB->m_invMass)\n" + " {\n" + " batchConstraints[i].m_bodyBPtrAndSignBit = solverBodyIdB;\n" + " } else\n" + " {\n" + "// if (!solverBodyIdB)\n" + "// m_staticIdx = 0;\n" + " batchConstraints[i].m_bodyBPtrAndSignBit = -solverBodyIdB;\n" + " }\n" + " if (info1)\n" + " {\n" + " int overrideNumSolverIterations = 0;//constraint->getOverrideNumSolverIterations() > 0 ? constraint->getOverrideNumSolverIterations() : infoGlobal.m_numIterations;\n" + "// if (overrideNumSolverIterations>m_maxOverrideNumSolverIterations)\n" + " // m_maxOverrideNumSolverIterations = overrideNumSolverIterations;\n" + " int j;\n" + " for ( j=0;jm_deltaLinearVelocity = (float4)(0,0,0,0);\n" + " bodyAPtr->m_deltaAngularVelocity = (float4)(0,0,0,0);\n" + " bodyAPtr->m_pushVelocity = (float4)(0,0,0,0);\n" + " bodyAPtr->m_turnVelocity = (float4)(0,0,0,0);\n" + " bodyBPtr->m_deltaLinearVelocity = (float4)(0,0,0,0);\n" + " bodyBPtr->m_deltaAngularVelocity = (float4)(0,0,0,0);\n" + " bodyBPtr->m_pushVelocity = (float4)(0,0,0,0);\n" + " bodyBPtr->m_turnVelocity = (float4)(0,0,0,0);\n" + " int rowskip = sizeof(b3SolverConstraint)/sizeof(float);//check this\n" + " \n" + " b3GpuConstraintInfo2 info2;\n" + " info2.fps = 1.f/timeStep;\n" + " info2.erp = globalErp;\n" + " info2.m_J1linearAxisFloat4 = ¤tConstraintRow->m_contactNormal;\n" + " info2.m_J1angularAxisFloat4 = ¤tConstraintRow->m_relpos1CrossNormal;\n" + " info2.m_J2linearAxisFloat4 = 0;\n" + " info2.m_J2angularAxisFloat4 = ¤tConstraintRow->m_relpos2CrossNormal;\n" + " info2.rowskip = sizeof(b3SolverConstraint)/sizeof(float);//check this\n" + " ///the size of b3SolverConstraint needs be a multiple of float\n" + "// b3Assert(info2.rowskip*sizeof(float)== sizeof(b3SolverConstraint));\n" + " info2.m_constraintError = ¤tConstraintRow->m_rhs;\n" + " currentConstraintRow->m_cfm = globalCfm;\n" + " info2.m_damping = globalDamping;\n" + " info2.cfm = ¤tConstraintRow->m_cfm;\n" + " info2.m_lowerLimit = ¤tConstraintRow->m_lowerLimit;\n" + " info2.m_upperLimit = ¤tConstraintRow->m_upperLimit;\n" + " info2.m_numIterations = globalNumIterations;\n" + " switch (constraint->m_constraintType)\n" + " {\n" + " case B3_GPU_POINT2POINT_CONSTRAINT_TYPE:\n" + " {\n" + " getInfo2Point2Point(constraint,&info2,bodies);\n" + " break;\n" + " }\n" + " case B3_GPU_FIXED_CONSTRAINT_TYPE:\n" + " {\n" + " getInfo2Point2Point(constraint,&info2,bodies);\n" + " getInfo2FixedOrientation(constraint,&info2,bodies,3);\n" + " break;\n" + " }\n" + " default:\n" + " {\n" + " }\n" + " }\n" + " ///finalize the constraint setup\n" + " for ( j=0;jm_upperLimit>=constraint->m_breakingImpulseThreshold)\n" + " {\n" + " solverConstraint->m_upperLimit = constraint->m_breakingImpulseThreshold;\n" + " }\n" + " if (solverConstraint->m_lowerLimit<=-constraint->m_breakingImpulseThreshold)\n" + " {\n" + " solverConstraint->m_lowerLimit = -constraint->m_breakingImpulseThreshold;\n" + " }\n" + "// solverConstraint->m_originalContactPoint = constraint;\n" + " \n" + " Matrix3x3 invInertiaWorldA= inertias[constraint->m_rbA].m_invInertiaWorld;\n" + " {\n" + " //float4 angularFactorA(1,1,1);\n" + " float4 ftorqueAxis1 = solverConstraint->m_relpos1CrossNormal;\n" + " solverConstraint->m_angularComponentA = mtMul1(invInertiaWorldA,ftorqueAxis1);//*angularFactorA;\n" + " }\n" + " \n" + " Matrix3x3 invInertiaWorldB= inertias[constraint->m_rbB].m_invInertiaWorld;\n" + " {\n" + " float4 ftorqueAxis2 = solverConstraint->m_relpos2CrossNormal;\n" + " solverConstraint->m_angularComponentB = mtMul1(invInertiaWorldB,ftorqueAxis2);//*constraint->m_rbB.getAngularFactor();\n" + " }\n" + " {\n" + " //it is ok to use solverConstraint->m_contactNormal instead of -solverConstraint->m_contactNormal\n" + " //because it gets multiplied iMJlB\n" + " float4 iMJlA = solverConstraint->m_contactNormal*rbA->m_invMass;\n" + " float4 iMJaA = mtMul3(solverConstraint->m_relpos1CrossNormal,invInertiaWorldA);\n" + " float4 iMJlB = solverConstraint->m_contactNormal*rbB->m_invMass;//sign of normal?\n" + " float4 iMJaB = mtMul3(solverConstraint->m_relpos2CrossNormal,invInertiaWorldB);\n" + " float sum = dot3F4(iMJlA,solverConstraint->m_contactNormal);\n" + " sum += dot3F4(iMJaA,solverConstraint->m_relpos1CrossNormal);\n" + " sum += dot3F4(iMJlB,solverConstraint->m_contactNormal);\n" + " sum += dot3F4(iMJaB,solverConstraint->m_relpos2CrossNormal);\n" + " float fsum = fabs(sum);\n" + " if (fsum>FLT_EPSILON)\n" + " {\n" + " solverConstraint->m_jacDiagABInv = 1.f/sum;\n" + " } else\n" + " {\n" + " solverConstraint->m_jacDiagABInv = 0.f;\n" + " }\n" + " }\n" + " ///fix rhs\n" + " ///todo: add force/torque accelerators\n" + " {\n" + " float rel_vel;\n" + " float vel1Dotn = dot3F4(solverConstraint->m_contactNormal,rbA->m_linVel) + dot3F4(solverConstraint->m_relpos1CrossNormal,rbA->m_angVel);\n" + " float vel2Dotn = -dot3F4(solverConstraint->m_contactNormal,rbB->m_linVel) + dot3F4(solverConstraint->m_relpos2CrossNormal,rbB->m_angVel);\n" + " rel_vel = vel1Dotn+vel2Dotn;\n" + " float restitution = 0.f;\n" + " float positionalError = solverConstraint->m_rhs;//already filled in by getConstraintInfo2\n" + " float velocityError = restitution - rel_vel * info2.m_damping;\n" + " float penetrationImpulse = positionalError*solverConstraint->m_jacDiagABInv;\n" + " float velocityImpulse = velocityError *solverConstraint->m_jacDiagABInv;\n" + " solverConstraint->m_rhs = penetrationImpulse+velocityImpulse;\n" + " solverConstraint->m_appliedImpulse = 0.f;\n" + " }\n" + " }\n" + " }\n" + "}\n"; diff --git a/src/Bullet3OpenCL/RigidBody/kernels/solveContact.h b/src/Bullet3OpenCL/RigidBody/kernels/solveContact.h index 15a049992..6e14ad51f 100644 --- a/src/Bullet3OpenCL/RigidBody/kernels/solveContact.h +++ b/src/Bullet3OpenCL/RigidBody/kernels/solveContact.h @@ -1,393 +1,392 @@ //this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project -static const char* solveContactCL= \ -"/*\n" -"Copyright (c) 2012 Advanced Micro Devices, Inc. \n" -"This software is provided 'as-is', without any express or implied warranty.\n" -"In no event will the authors be held liable for any damages arising from the use of this software.\n" -"Permission is granted to anyone to use this software for any purpose, \n" -"including commercial applications, and to alter it and redistribute it freely, \n" -"subject to the following restrictions:\n" -"1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" -"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" -"3. This notice may not be removed or altered from any source distribution.\n" -"*/\n" -"//Originally written by Takahiro Harada\n" -"//#pragma OPENCL EXTENSION cl_amd_printf : enable\n" -"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n" -"#ifdef cl_ext_atomic_counters_32\n" -"#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n" -"#else\n" -"#define counter32_t volatile global int*\n" -"#endif\n" -"typedef unsigned int u32;\n" -"typedef unsigned short u16;\n" -"typedef unsigned char u8;\n" -"#define GET_GROUP_IDX get_group_id(0)\n" -"#define GET_LOCAL_IDX get_local_id(0)\n" -"#define GET_GLOBAL_IDX get_global_id(0)\n" -"#define GET_GROUP_SIZE get_local_size(0)\n" -"#define GET_NUM_GROUPS get_num_groups(0)\n" -"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" -"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" -"#define AtomInc(x) atom_inc(&(x))\n" -"#define AtomInc1(x, out) out = atom_inc(&(x))\n" -"#define AppendInc(x, out) out = atomic_inc(x)\n" -"#define AtomAdd(x, value) atom_add(&(x), value)\n" -"#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n" -"#define AtomXhg(x, value) atom_xchg ( &(x), value )\n" -"#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n" -"#define mymake_float4 (float4)\n" -"//#define make_float2 (float2)\n" -"//#define make_uint4 (uint4)\n" -"//#define make_int4 (int4)\n" -"//#define make_uint2 (uint2)\n" -"//#define make_int2 (int2)\n" -"#define max2 max\n" -"#define min2 min\n" -"///////////////////////////////////////\n" -"// Vector\n" -"///////////////////////////////////////\n" -"__inline\n" -"float4 fastNormalize4(float4 v)\n" -"{\n" -" return fast_normalize(v);\n" -"}\n" -"__inline\n" -"float4 cross3(float4 a, float4 b)\n" -"{\n" -" return cross(a,b);\n" -"}\n" -"__inline\n" -"float dot3F4(float4 a, float4 b)\n" -"{\n" -" float4 a1 = mymake_float4(a.xyz,0.f);\n" -" float4 b1 = mymake_float4(b.xyz,0.f);\n" -" return dot(a1, b1);\n" -"}\n" -"__inline\n" -"float4 normalize3(const float4 a)\n" -"{\n" -" float4 n = mymake_float4(a.x, a.y, a.z, 0.f);\n" -" return fastNormalize4( n );\n" -"// float length = sqrtf(dot3F4(a, a));\n" -"// return 1.f/length * a;\n" -"}\n" -"///////////////////////////////////////\n" -"// Matrix3x3\n" -"///////////////////////////////////////\n" -"typedef struct\n" -"{\n" -" float4 m_row[3];\n" -"}Matrix3x3;\n" -"__inline\n" -"float4 mtMul1(Matrix3x3 a, float4 b);\n" -"__inline\n" -"float4 mtMul3(float4 a, Matrix3x3 b);\n" -"__inline\n" -"float4 mtMul1(Matrix3x3 a, float4 b)\n" -"{\n" -" float4 ans;\n" -" ans.x = dot3F4( a.m_row[0], b );\n" -" ans.y = dot3F4( a.m_row[1], b );\n" -" ans.z = dot3F4( a.m_row[2], b );\n" -" ans.w = 0.f;\n" -" return ans;\n" -"}\n" -"__inline\n" -"float4 mtMul3(float4 a, Matrix3x3 b)\n" -"{\n" -" float4 colx = mymake_float4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" -" float4 coly = mymake_float4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" -" float4 colz = mymake_float4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" -" float4 ans;\n" -" ans.x = dot3F4( a, colx );\n" -" ans.y = dot3F4( a, coly );\n" -" ans.z = dot3F4( a, colz );\n" -" return ans;\n" -"}\n" -"///////////////////////////////////////\n" -"// Quaternion\n" -"///////////////////////////////////////\n" -"typedef float4 Quaternion;\n" -"#define WG_SIZE 64\n" -"typedef struct\n" -"{\n" -" float4 m_pos;\n" -" Quaternion m_quat;\n" -" float4 m_linVel;\n" -" float4 m_angVel;\n" -" u32 m_shapeIdx;\n" -" float m_invMass;\n" -" float m_restituitionCoeff;\n" -" float m_frictionCoeff;\n" -"} Body;\n" -"typedef struct\n" -"{\n" -" Matrix3x3 m_invInertia;\n" -" Matrix3x3 m_initInvInertia;\n" -"} Shape;\n" -"typedef struct\n" -"{\n" -" float4 m_linear;\n" -" float4 m_worldPos[4];\n" -" float4 m_center; \n" -" float m_jacCoeffInv[4];\n" -" float m_b[4];\n" -" float m_appliedRambdaDt[4];\n" -" float m_fJacCoeffInv[2]; \n" -" float m_fAppliedRambdaDt[2]; \n" -" u32 m_bodyA;\n" -" u32 m_bodyB;\n" -" int m_batchIdx;\n" -" u32 m_paddings[1];\n" -"} Constraint4;\n" -"typedef struct\n" -"{\n" -" int m_nConstraints;\n" -" int m_start;\n" -" int m_batchIdx;\n" -" int m_nSplit;\n" -"// int m_paddings[1];\n" -"} ConstBuffer;\n" -"typedef struct\n" -"{\n" -" int m_solveFriction;\n" -" int m_maxBatch; // long batch really kills the performance\n" -" int m_batchIdx;\n" -" int m_nSplit;\n" -"// int m_paddings[1];\n" -"} ConstBufferBatchSolve;\n" -"void setLinearAndAngular( float4 n, float4 r0, float4 r1, float4* linear, float4* angular0, float4* angular1);\n" -"void setLinearAndAngular( float4 n, float4 r0, float4 r1, float4* linear, float4* angular0, float4* angular1)\n" -"{\n" -" *linear = mymake_float4(-n.xyz,0.f);\n" -" *angular0 = -cross3(r0, n);\n" -" *angular1 = cross3(r1, n);\n" -"}\n" -"float calcRelVel( float4 l0, float4 l1, float4 a0, float4 a1, float4 linVel0, float4 angVel0, float4 linVel1, float4 angVel1 );\n" -"float calcRelVel( float4 l0, float4 l1, float4 a0, float4 a1, float4 linVel0, float4 angVel0, float4 linVel1, float4 angVel1 )\n" -"{\n" -" return dot3F4(l0, linVel0) + dot3F4(a0, angVel0) + dot3F4(l1, linVel1) + dot3F4(a1, angVel1);\n" -"}\n" -"float calcJacCoeff(const float4 linear0, const float4 linear1, const float4 angular0, const float4 angular1,\n" -" float invMass0, const Matrix3x3* invInertia0, float invMass1, const Matrix3x3* invInertia1);\n" -"float calcJacCoeff(const float4 linear0, const float4 linear1, const float4 angular0, const float4 angular1,\n" -" float invMass0, const Matrix3x3* invInertia0, float invMass1, const Matrix3x3* invInertia1)\n" -"{\n" -" // linear0,1 are normlized\n" -" float jmj0 = invMass0;//dot3F4(linear0, linear0)*invMass0;\n" -" float jmj1 = dot3F4(mtMul3(angular0,*invInertia0), angular0);\n" -" float jmj2 = invMass1;//dot3F4(linear1, linear1)*invMass1;\n" -" float jmj3 = dot3F4(mtMul3(angular1,*invInertia1), angular1);\n" -" return -1.f/(jmj0+jmj1+jmj2+jmj3);\n" -"}\n" -"void solveContact(__global Constraint4* cs,\n" -" float4 posA, float4* linVelA, float4* angVelA, float invMassA, Matrix3x3 invInertiaA,\n" -" float4 posB, float4* linVelB, float4* angVelB, float invMassB, Matrix3x3 invInertiaB);\n" -"void solveContact(__global Constraint4* cs,\n" -" float4 posA, float4* linVelA, float4* angVelA, float invMassA, Matrix3x3 invInertiaA,\n" -" float4 posB, float4* linVelB, float4* angVelB, float invMassB, Matrix3x3 invInertiaB)\n" -"{\n" -" float minRambdaDt = 0;\n" -" float maxRambdaDt = FLT_MAX;\n" -" for(int ic=0; ic<4; ic++)\n" -" {\n" -" if( cs->m_jacCoeffInv[ic] == 0.f ) continue;\n" -" float4 angular0, angular1, linear;\n" -" float4 r0 = cs->m_worldPos[ic] - posA;\n" -" float4 r1 = cs->m_worldPos[ic] - posB;\n" -" setLinearAndAngular( -cs->m_linear, r0, r1, &linear, &angular0, &angular1 );\n" -" float rambdaDt = calcRelVel( cs->m_linear, -cs->m_linear, angular0, angular1, \n" -" *linVelA, *angVelA, *linVelB, *angVelB ) + cs->m_b[ic];\n" -" rambdaDt *= cs->m_jacCoeffInv[ic];\n" -" {\n" -" float prevSum = cs->m_appliedRambdaDt[ic];\n" -" float updated = prevSum;\n" -" updated += rambdaDt;\n" -" updated = max2( updated, minRambdaDt );\n" -" updated = min2( updated, maxRambdaDt );\n" -" rambdaDt = updated - prevSum;\n" -" cs->m_appliedRambdaDt[ic] = updated;\n" -" }\n" -" float4 linImp0 = invMassA*linear*rambdaDt;\n" -" float4 linImp1 = invMassB*(-linear)*rambdaDt;\n" -" float4 angImp0 = mtMul1(invInertiaA, angular0)*rambdaDt;\n" -" float4 angImp1 = mtMul1(invInertiaB, angular1)*rambdaDt;\n" -" *linVelA += linImp0;\n" -" *angVelA += angImp0;\n" -" *linVelB += linImp1;\n" -" *angVelB += angImp1;\n" -" }\n" -"}\n" -"void btPlaneSpace1 (const float4* n, float4* p, float4* q);\n" -" void btPlaneSpace1 (const float4* n, float4* p, float4* q)\n" -"{\n" -" if (fabs(n[0].z) > 0.70710678f) {\n" -" // choose p in y-z plane\n" -" float a = n[0].y*n[0].y + n[0].z*n[0].z;\n" -" float k = 1.f/sqrt(a);\n" -" p[0].x = 0;\n" -" p[0].y = -n[0].z*k;\n" -" p[0].z = n[0].y*k;\n" -" // set q = n x p\n" -" q[0].x = a*k;\n" -" q[0].y = -n[0].x*p[0].z;\n" -" q[0].z = n[0].x*p[0].y;\n" -" }\n" -" else {\n" -" // choose p in x-y plane\n" -" float a = n[0].x*n[0].x + n[0].y*n[0].y;\n" -" float k = 1.f/sqrt(a);\n" -" p[0].x = -n[0].y*k;\n" -" p[0].y = n[0].x*k;\n" -" p[0].z = 0;\n" -" // set q = n x p\n" -" q[0].x = -n[0].z*p[0].y;\n" -" q[0].y = n[0].z*p[0].x;\n" -" q[0].z = a*k;\n" -" }\n" -"}\n" -"void solveContactConstraint(__global Body* gBodies, __global Shape* gShapes, __global Constraint4* ldsCs);\n" -"void solveContactConstraint(__global Body* gBodies, __global Shape* gShapes, __global Constraint4* ldsCs)\n" -"{\n" -" //float frictionCoeff = ldsCs[0].m_linear.w;\n" -" int aIdx = ldsCs[0].m_bodyA;\n" -" int bIdx = ldsCs[0].m_bodyB;\n" -" float4 posA = gBodies[aIdx].m_pos;\n" -" float4 linVelA = gBodies[aIdx].m_linVel;\n" -" float4 angVelA = gBodies[aIdx].m_angVel;\n" -" float invMassA = gBodies[aIdx].m_invMass;\n" -" Matrix3x3 invInertiaA = gShapes[aIdx].m_invInertia;\n" -" float4 posB = gBodies[bIdx].m_pos;\n" -" float4 linVelB = gBodies[bIdx].m_linVel;\n" -" float4 angVelB = gBodies[bIdx].m_angVel;\n" -" float invMassB = gBodies[bIdx].m_invMass;\n" -" Matrix3x3 invInertiaB = gShapes[bIdx].m_invInertia;\n" -" solveContact( ldsCs, posA, &linVelA, &angVelA, invMassA, invInertiaA,\n" -" posB, &linVelB, &angVelB, invMassB, invInertiaB );\n" -" if (gBodies[aIdx].m_invMass)\n" -" {\n" -" gBodies[aIdx].m_linVel = linVelA;\n" -" gBodies[aIdx].m_angVel = angVelA;\n" -" } else\n" -" {\n" -" gBodies[aIdx].m_linVel = mymake_float4(0,0,0,0);\n" -" gBodies[aIdx].m_angVel = mymake_float4(0,0,0,0);\n" -" \n" -" }\n" -" if (gBodies[bIdx].m_invMass)\n" -" {\n" -" gBodies[bIdx].m_linVel = linVelB;\n" -" gBodies[bIdx].m_angVel = angVelB;\n" -" } else\n" -" {\n" -" gBodies[bIdx].m_linVel = mymake_float4(0,0,0,0);\n" -" gBodies[bIdx].m_angVel = mymake_float4(0,0,0,0);\n" -" \n" -" }\n" -"}\n" -"typedef struct \n" -"{\n" -" int m_valInt0;\n" -" int m_valInt1;\n" -" int m_valInt2;\n" -" int m_valInt3;\n" -" float m_val0;\n" -" float m_val1;\n" -" float m_val2;\n" -" float m_val3;\n" -"} SolverDebugInfo;\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" -"void BatchSolveKernelContact(__global Body* gBodies,\n" -" __global Shape* gShapes,\n" -" __global Constraint4* gConstraints,\n" -" __global int* gN,\n" -" __global int* gOffsets,\n" -" __global int* batchSizes,\n" -" int maxBatch1,\n" -" int cellBatch,\n" -" int4 nSplit\n" -" )\n" -"{\n" -" //__local int ldsBatchIdx[WG_SIZE+1];\n" -" __local int ldsCurBatch;\n" -" __local int ldsNextBatch;\n" -" __local int ldsStart;\n" -" int lIdx = GET_LOCAL_IDX;\n" -" int wgIdx = GET_GROUP_IDX;\n" -"// int gIdx = GET_GLOBAL_IDX;\n" -"// debugInfo[gIdx].m_valInt0 = gIdx;\n" -" //debugInfo[gIdx].m_valInt1 = GET_GROUP_SIZE;\n" -" \n" -" \n" -" int zIdx = (wgIdx/((nSplit.x*nSplit.y)/4))*2+((cellBatch&4)>>2);\n" -" int remain= (wgIdx%((nSplit.x*nSplit.y)/4));\n" -" int yIdx = (remain/(nSplit.x/2))*2 + ((cellBatch&2)>>1);\n" -" int xIdx = (remain%(nSplit.x/2))*2 + (cellBatch&1);\n" -" int cellIdx = xIdx+yIdx*nSplit.x+zIdx*(nSplit.x*nSplit.y);\n" -" //int xIdx = (wgIdx/(nSplit/2))*2 + (bIdx&1);\n" -" //int yIdx = (wgIdx%(nSplit/2))*2 + (bIdx>>1);\n" -" //int cellIdx = xIdx+yIdx*nSplit;\n" -" \n" -" if( gN[cellIdx] == 0 ) \n" -" return;\n" -" int maxBatch = batchSizes[cellIdx];\n" -" \n" -" \n" -" const int start = gOffsets[cellIdx];\n" -" const int end = start + gN[cellIdx];\n" -" \n" -" \n" -" \n" -" if( lIdx == 0 )\n" -" {\n" -" ldsCurBatch = 0;\n" -" ldsNextBatch = 0;\n" -" ldsStart = start;\n" -" }\n" -" GROUP_LDS_BARRIER;\n" -" int idx=ldsStart+lIdx;\n" -" while (ldsCurBatch < maxBatch)\n" -" {\n" -" for(; idxm_jacCoeffInv[ic] == 0.f ) continue;\n" + " float4 angular0, angular1, linear;\n" + " float4 r0 = cs->m_worldPos[ic] - posA;\n" + " float4 r1 = cs->m_worldPos[ic] - posB;\n" + " setLinearAndAngular( -cs->m_linear, r0, r1, &linear, &angular0, &angular1 );\n" + " float rambdaDt = calcRelVel( cs->m_linear, -cs->m_linear, angular0, angular1, \n" + " *linVelA, *angVelA, *linVelB, *angVelB ) + cs->m_b[ic];\n" + " rambdaDt *= cs->m_jacCoeffInv[ic];\n" + " {\n" + " float prevSum = cs->m_appliedRambdaDt[ic];\n" + " float updated = prevSum;\n" + " updated += rambdaDt;\n" + " updated = max2( updated, minRambdaDt );\n" + " updated = min2( updated, maxRambdaDt );\n" + " rambdaDt = updated - prevSum;\n" + " cs->m_appliedRambdaDt[ic] = updated;\n" + " }\n" + " float4 linImp0 = invMassA*linear*rambdaDt;\n" + " float4 linImp1 = invMassB*(-linear)*rambdaDt;\n" + " float4 angImp0 = mtMul1(invInertiaA, angular0)*rambdaDt;\n" + " float4 angImp1 = mtMul1(invInertiaB, angular1)*rambdaDt;\n" + " *linVelA += linImp0;\n" + " *angVelA += angImp0;\n" + " *linVelB += linImp1;\n" + " *angVelB += angImp1;\n" + " }\n" + "}\n" + "void btPlaneSpace1 (const float4* n, float4* p, float4* q);\n" + " void btPlaneSpace1 (const float4* n, float4* p, float4* q)\n" + "{\n" + " if (fabs(n[0].z) > 0.70710678f) {\n" + " // choose p in y-z plane\n" + " float a = n[0].y*n[0].y + n[0].z*n[0].z;\n" + " float k = 1.f/sqrt(a);\n" + " p[0].x = 0;\n" + " p[0].y = -n[0].z*k;\n" + " p[0].z = n[0].y*k;\n" + " // set q = n x p\n" + " q[0].x = a*k;\n" + " q[0].y = -n[0].x*p[0].z;\n" + " q[0].z = n[0].x*p[0].y;\n" + " }\n" + " else {\n" + " // choose p in x-y plane\n" + " float a = n[0].x*n[0].x + n[0].y*n[0].y;\n" + " float k = 1.f/sqrt(a);\n" + " p[0].x = -n[0].y*k;\n" + " p[0].y = n[0].x*k;\n" + " p[0].z = 0;\n" + " // set q = n x p\n" + " q[0].x = -n[0].z*p[0].y;\n" + " q[0].y = n[0].z*p[0].x;\n" + " q[0].z = a*k;\n" + " }\n" + "}\n" + "void solveContactConstraint(__global Body* gBodies, __global Shape* gShapes, __global Constraint4* ldsCs);\n" + "void solveContactConstraint(__global Body* gBodies, __global Shape* gShapes, __global Constraint4* ldsCs)\n" + "{\n" + " //float frictionCoeff = ldsCs[0].m_linear.w;\n" + " int aIdx = ldsCs[0].m_bodyA;\n" + " int bIdx = ldsCs[0].m_bodyB;\n" + " float4 posA = gBodies[aIdx].m_pos;\n" + " float4 linVelA = gBodies[aIdx].m_linVel;\n" + " float4 angVelA = gBodies[aIdx].m_angVel;\n" + " float invMassA = gBodies[aIdx].m_invMass;\n" + " Matrix3x3 invInertiaA = gShapes[aIdx].m_invInertia;\n" + " float4 posB = gBodies[bIdx].m_pos;\n" + " float4 linVelB = gBodies[bIdx].m_linVel;\n" + " float4 angVelB = gBodies[bIdx].m_angVel;\n" + " float invMassB = gBodies[bIdx].m_invMass;\n" + " Matrix3x3 invInertiaB = gShapes[bIdx].m_invInertia;\n" + " solveContact( ldsCs, posA, &linVelA, &angVelA, invMassA, invInertiaA,\n" + " posB, &linVelB, &angVelB, invMassB, invInertiaB );\n" + " if (gBodies[aIdx].m_invMass)\n" + " {\n" + " gBodies[aIdx].m_linVel = linVelA;\n" + " gBodies[aIdx].m_angVel = angVelA;\n" + " } else\n" + " {\n" + " gBodies[aIdx].m_linVel = mymake_float4(0,0,0,0);\n" + " gBodies[aIdx].m_angVel = mymake_float4(0,0,0,0);\n" + " \n" + " }\n" + " if (gBodies[bIdx].m_invMass)\n" + " {\n" + " gBodies[bIdx].m_linVel = linVelB;\n" + " gBodies[bIdx].m_angVel = angVelB;\n" + " } else\n" + " {\n" + " gBodies[bIdx].m_linVel = mymake_float4(0,0,0,0);\n" + " gBodies[bIdx].m_angVel = mymake_float4(0,0,0,0);\n" + " \n" + " }\n" + "}\n" + "typedef struct \n" + "{\n" + " int m_valInt0;\n" + " int m_valInt1;\n" + " int m_valInt2;\n" + " int m_valInt3;\n" + " float m_val0;\n" + " float m_val1;\n" + " float m_val2;\n" + " float m_val3;\n" + "} SolverDebugInfo;\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" + "void BatchSolveKernelContact(__global Body* gBodies,\n" + " __global Shape* gShapes,\n" + " __global Constraint4* gConstraints,\n" + " __global int* gN,\n" + " __global int* gOffsets,\n" + " __global int* batchSizes,\n" + " int maxBatch1,\n" + " int cellBatch,\n" + " int4 nSplit\n" + " )\n" + "{\n" + " //__local int ldsBatchIdx[WG_SIZE+1];\n" + " __local int ldsCurBatch;\n" + " __local int ldsNextBatch;\n" + " __local int ldsStart;\n" + " int lIdx = GET_LOCAL_IDX;\n" + " int wgIdx = GET_GROUP_IDX;\n" + "// int gIdx = GET_GLOBAL_IDX;\n" + "// debugInfo[gIdx].m_valInt0 = gIdx;\n" + " //debugInfo[gIdx].m_valInt1 = GET_GROUP_SIZE;\n" + " \n" + " \n" + " int zIdx = (wgIdx/((nSplit.x*nSplit.y)/4))*2+((cellBatch&4)>>2);\n" + " int remain= (wgIdx%((nSplit.x*nSplit.y)/4));\n" + " int yIdx = (remain/(nSplit.x/2))*2 + ((cellBatch&2)>>1);\n" + " int xIdx = (remain%(nSplit.x/2))*2 + (cellBatch&1);\n" + " int cellIdx = xIdx+yIdx*nSplit.x+zIdx*(nSplit.x*nSplit.y);\n" + " //int xIdx = (wgIdx/(nSplit/2))*2 + (bIdx&1);\n" + " //int yIdx = (wgIdx%(nSplit/2))*2 + (bIdx>>1);\n" + " //int cellIdx = xIdx+yIdx*nSplit;\n" + " \n" + " if( gN[cellIdx] == 0 ) \n" + " return;\n" + " int maxBatch = batchSizes[cellIdx];\n" + " \n" + " \n" + " const int start = gOffsets[cellIdx];\n" + " const int end = start + gN[cellIdx];\n" + " \n" + " \n" + " \n" + " if( lIdx == 0 )\n" + " {\n" + " ldsCurBatch = 0;\n" + " ldsNextBatch = 0;\n" + " ldsStart = start;\n" + " }\n" + " GROUP_LDS_BARRIER;\n" + " int idx=ldsStart+lIdx;\n" + " while (ldsCurBatch < maxBatch)\n" + " {\n" + " for(; idx 0.70710678f) {\n" -" // choose p in y-z plane\n" -" float a = n[0].y*n[0].y + n[0].z*n[0].z;\n" -" float k = 1.f/sqrt(a);\n" -" p[0].x = 0;\n" -" p[0].y = -n[0].z*k;\n" -" p[0].z = n[0].y*k;\n" -" // set q = n x p\n" -" q[0].x = a*k;\n" -" q[0].y = -n[0].x*p[0].z;\n" -" q[0].z = n[0].x*p[0].y;\n" -" }\n" -" else {\n" -" // choose p in x-y plane\n" -" float a = n[0].x*n[0].x + n[0].y*n[0].y;\n" -" float k = 1.f/sqrt(a);\n" -" p[0].x = -n[0].y*k;\n" -" p[0].y = n[0].x*k;\n" -" p[0].z = 0;\n" -" // set q = n x p\n" -" q[0].x = -n[0].z*p[0].y;\n" -" q[0].y = n[0].z*p[0].x;\n" -" q[0].z = a*k;\n" -" }\n" -"}\n" -"void solveFrictionConstraint(__global Body* gBodies, __global Shape* gShapes, __global Constraint4* ldsCs);\n" -"void solveFrictionConstraint(__global Body* gBodies, __global Shape* gShapes, __global Constraint4* ldsCs)\n" -"{\n" -" float frictionCoeff = ldsCs[0].m_linear.w;\n" -" int aIdx = ldsCs[0].m_bodyA;\n" -" int bIdx = ldsCs[0].m_bodyB;\n" -" float4 posA = gBodies[aIdx].m_pos;\n" -" float4 linVelA = gBodies[aIdx].m_linVel;\n" -" float4 angVelA = gBodies[aIdx].m_angVel;\n" -" float invMassA = gBodies[aIdx].m_invMass;\n" -" Matrix3x3 invInertiaA = gShapes[aIdx].m_invInertia;\n" -" float4 posB = gBodies[bIdx].m_pos;\n" -" float4 linVelB = gBodies[bIdx].m_linVel;\n" -" float4 angVelB = gBodies[bIdx].m_angVel;\n" -" float invMassB = gBodies[bIdx].m_invMass;\n" -" Matrix3x3 invInertiaB = gShapes[bIdx].m_invInertia;\n" -" \n" -" {\n" -" float maxRambdaDt[4] = {FLT_MAX,FLT_MAX,FLT_MAX,FLT_MAX};\n" -" float minRambdaDt[4] = {0.f,0.f,0.f,0.f};\n" -" float sum = 0;\n" -" for(int j=0; j<4; j++)\n" -" {\n" -" sum +=ldsCs[0].m_appliedRambdaDt[j];\n" -" }\n" -" frictionCoeff = 0.7f;\n" -" for(int j=0; j<4; j++)\n" -" {\n" -" maxRambdaDt[j] = frictionCoeff*sum;\n" -" minRambdaDt[j] = -maxRambdaDt[j];\n" -" }\n" -" \n" -"// solveFriction( ldsCs, posA, &linVelA, &angVelA, invMassA, invInertiaA,\n" -"// posB, &linVelB, &angVelB, invMassB, invInertiaB, maxRambdaDt, minRambdaDt );\n" -" \n" -" \n" -" {\n" -" \n" -" __global Constraint4* cs = ldsCs;\n" -" \n" -" if( cs->m_fJacCoeffInv[0] == 0 && cs->m_fJacCoeffInv[0] == 0 ) return;\n" -" const float4 center = cs->m_center;\n" -" \n" -" float4 n = -cs->m_linear;\n" -" \n" -" float4 tangent[2];\n" -" btPlaneSpace1(&n,&tangent[0],&tangent[1]);\n" -" float4 angular0, angular1, linear;\n" -" float4 r0 = center - posA;\n" -" float4 r1 = center - posB;\n" -" for(int i=0; i<2; i++)\n" -" {\n" -" setLinearAndAngular( tangent[i], r0, r1, &linear, &angular0, &angular1 );\n" -" float rambdaDt = calcRelVel(linear, -linear, angular0, angular1,\n" -" linVelA, angVelA, linVelB, angVelB );\n" -" rambdaDt *= cs->m_fJacCoeffInv[i];\n" -" \n" -" {\n" -" float prevSum = cs->m_fAppliedRambdaDt[i];\n" -" float updated = prevSum;\n" -" updated += rambdaDt;\n" -" updated = max2( updated, minRambdaDt[i] );\n" -" updated = min2( updated, maxRambdaDt[i] );\n" -" rambdaDt = updated - prevSum;\n" -" cs->m_fAppliedRambdaDt[i] = updated;\n" -" }\n" -" \n" -" float4 linImp0 = invMassA*linear*rambdaDt;\n" -" float4 linImp1 = invMassB*(-linear)*rambdaDt;\n" -" float4 angImp0 = mtMul1(invInertiaA, angular0)*rambdaDt;\n" -" float4 angImp1 = mtMul1(invInertiaB, angular1)*rambdaDt;\n" -" \n" -" linVelA += linImp0;\n" -" angVelA += angImp0;\n" -" linVelB += linImp1;\n" -" angVelB += angImp1;\n" -" }\n" -" { // angular damping for point constraint\n" -" float4 ab = normalize3( posB - posA );\n" -" float4 ac = normalize3( center - posA );\n" -" if( dot3F4( ab, ac ) > 0.95f || (invMassA == 0.f || invMassB == 0.f))\n" -" {\n" -" float angNA = dot3F4( n, angVelA );\n" -" float angNB = dot3F4( n, angVelB );\n" -" \n" -" angVelA -= (angNA*0.1f)*n;\n" -" angVelB -= (angNB*0.1f)*n;\n" -" }\n" -" }\n" -" }\n" -" \n" -" \n" -" }\n" -" if (gBodies[aIdx].m_invMass)\n" -" {\n" -" gBodies[aIdx].m_linVel = linVelA;\n" -" gBodies[aIdx].m_angVel = angVelA;\n" -" } else\n" -" {\n" -" gBodies[aIdx].m_linVel = mymake_float4(0,0,0,0);\n" -" gBodies[aIdx].m_angVel = mymake_float4(0,0,0,0);\n" -" }\n" -" if (gBodies[bIdx].m_invMass)\n" -" {\n" -" gBodies[bIdx].m_linVel = linVelB;\n" -" gBodies[bIdx].m_angVel = angVelB;\n" -" } else\n" -" {\n" -" gBodies[bIdx].m_linVel = mymake_float4(0,0,0,0);\n" -" gBodies[bIdx].m_angVel = mymake_float4(0,0,0,0);\n" -" }\n" -" \n" -"}\n" -"typedef struct \n" -"{\n" -" int m_valInt0;\n" -" int m_valInt1;\n" -" int m_valInt2;\n" -" int m_valInt3;\n" -" float m_val0;\n" -" float m_val1;\n" -" float m_val2;\n" -" float m_val3;\n" -"} SolverDebugInfo;\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" -"void BatchSolveKernelFriction(__global Body* gBodies,\n" -" __global Shape* gShapes,\n" -" __global Constraint4* gConstraints,\n" -" __global int* gN,\n" -" __global int* gOffsets,\n" -" __global int* batchSizes,\n" -" int maxBatch1,\n" -" int cellBatch,\n" -" int4 nSplit\n" -" )\n" -"{\n" -" //__local int ldsBatchIdx[WG_SIZE+1];\n" -" __local int ldsCurBatch;\n" -" __local int ldsNextBatch;\n" -" __local int ldsStart;\n" -" int lIdx = GET_LOCAL_IDX;\n" -" int wgIdx = GET_GROUP_IDX;\n" -"// int gIdx = GET_GLOBAL_IDX;\n" -"// debugInfo[gIdx].m_valInt0 = gIdx;\n" -" //debugInfo[gIdx].m_valInt1 = GET_GROUP_SIZE;\n" -" int zIdx = (wgIdx/((nSplit.x*nSplit.y)/4))*2+((cellBatch&4)>>2);\n" -" int remain= (wgIdx%((nSplit.x*nSplit.y)/4));\n" -" int yIdx = (remain/(nSplit.x/2))*2 + ((cellBatch&2)>>1);\n" -" int xIdx = (remain%(nSplit.x/2))*2 + (cellBatch&1);\n" -" int cellIdx = xIdx+yIdx*nSplit.x+zIdx*(nSplit.x*nSplit.y);\n" -" \n" -" if( gN[cellIdx] == 0 ) \n" -" return;\n" -" int maxBatch = batchSizes[cellIdx];\n" -" const int start = gOffsets[cellIdx];\n" -" const int end = start + gN[cellIdx];\n" -" \n" -" if( lIdx == 0 )\n" -" {\n" -" ldsCurBatch = 0;\n" -" ldsNextBatch = 0;\n" -" ldsStart = start;\n" -" }\n" -" GROUP_LDS_BARRIER;\n" -" int idx=ldsStart+lIdx;\n" -" while (ldsCurBatch < maxBatch)\n" -" {\n" -" for(; idx 0.70710678f) {\n" + " // choose p in y-z plane\n" + " float a = n[0].y*n[0].y + n[0].z*n[0].z;\n" + " float k = 1.f/sqrt(a);\n" + " p[0].x = 0;\n" + " p[0].y = -n[0].z*k;\n" + " p[0].z = n[0].y*k;\n" + " // set q = n x p\n" + " q[0].x = a*k;\n" + " q[0].y = -n[0].x*p[0].z;\n" + " q[0].z = n[0].x*p[0].y;\n" + " }\n" + " else {\n" + " // choose p in x-y plane\n" + " float a = n[0].x*n[0].x + n[0].y*n[0].y;\n" + " float k = 1.f/sqrt(a);\n" + " p[0].x = -n[0].y*k;\n" + " p[0].y = n[0].x*k;\n" + " p[0].z = 0;\n" + " // set q = n x p\n" + " q[0].x = -n[0].z*p[0].y;\n" + " q[0].y = n[0].z*p[0].x;\n" + " q[0].z = a*k;\n" + " }\n" + "}\n" + "void solveFrictionConstraint(__global Body* gBodies, __global Shape* gShapes, __global Constraint4* ldsCs);\n" + "void solveFrictionConstraint(__global Body* gBodies, __global Shape* gShapes, __global Constraint4* ldsCs)\n" + "{\n" + " float frictionCoeff = ldsCs[0].m_linear.w;\n" + " int aIdx = ldsCs[0].m_bodyA;\n" + " int bIdx = ldsCs[0].m_bodyB;\n" + " float4 posA = gBodies[aIdx].m_pos;\n" + " float4 linVelA = gBodies[aIdx].m_linVel;\n" + " float4 angVelA = gBodies[aIdx].m_angVel;\n" + " float invMassA = gBodies[aIdx].m_invMass;\n" + " Matrix3x3 invInertiaA = gShapes[aIdx].m_invInertia;\n" + " float4 posB = gBodies[bIdx].m_pos;\n" + " float4 linVelB = gBodies[bIdx].m_linVel;\n" + " float4 angVelB = gBodies[bIdx].m_angVel;\n" + " float invMassB = gBodies[bIdx].m_invMass;\n" + " Matrix3x3 invInertiaB = gShapes[bIdx].m_invInertia;\n" + " \n" + " {\n" + " float maxRambdaDt[4] = {FLT_MAX,FLT_MAX,FLT_MAX,FLT_MAX};\n" + " float minRambdaDt[4] = {0.f,0.f,0.f,0.f};\n" + " float sum = 0;\n" + " for(int j=0; j<4; j++)\n" + " {\n" + " sum +=ldsCs[0].m_appliedRambdaDt[j];\n" + " }\n" + " frictionCoeff = 0.7f;\n" + " for(int j=0; j<4; j++)\n" + " {\n" + " maxRambdaDt[j] = frictionCoeff*sum;\n" + " minRambdaDt[j] = -maxRambdaDt[j];\n" + " }\n" + " \n" + "// solveFriction( ldsCs, posA, &linVelA, &angVelA, invMassA, invInertiaA,\n" + "// posB, &linVelB, &angVelB, invMassB, invInertiaB, maxRambdaDt, minRambdaDt );\n" + " \n" + " \n" + " {\n" + " \n" + " __global Constraint4* cs = ldsCs;\n" + " \n" + " if( cs->m_fJacCoeffInv[0] == 0 && cs->m_fJacCoeffInv[0] == 0 ) return;\n" + " const float4 center = cs->m_center;\n" + " \n" + " float4 n = -cs->m_linear;\n" + " \n" + " float4 tangent[2];\n" + " btPlaneSpace1(&n,&tangent[0],&tangent[1]);\n" + " float4 angular0, angular1, linear;\n" + " float4 r0 = center - posA;\n" + " float4 r1 = center - posB;\n" + " for(int i=0; i<2; i++)\n" + " {\n" + " setLinearAndAngular( tangent[i], r0, r1, &linear, &angular0, &angular1 );\n" + " float rambdaDt = calcRelVel(linear, -linear, angular0, angular1,\n" + " linVelA, angVelA, linVelB, angVelB );\n" + " rambdaDt *= cs->m_fJacCoeffInv[i];\n" + " \n" + " {\n" + " float prevSum = cs->m_fAppliedRambdaDt[i];\n" + " float updated = prevSum;\n" + " updated += rambdaDt;\n" + " updated = max2( updated, minRambdaDt[i] );\n" + " updated = min2( updated, maxRambdaDt[i] );\n" + " rambdaDt = updated - prevSum;\n" + " cs->m_fAppliedRambdaDt[i] = updated;\n" + " }\n" + " \n" + " float4 linImp0 = invMassA*linear*rambdaDt;\n" + " float4 linImp1 = invMassB*(-linear)*rambdaDt;\n" + " float4 angImp0 = mtMul1(invInertiaA, angular0)*rambdaDt;\n" + " float4 angImp1 = mtMul1(invInertiaB, angular1)*rambdaDt;\n" + " \n" + " linVelA += linImp0;\n" + " angVelA += angImp0;\n" + " linVelB += linImp1;\n" + " angVelB += angImp1;\n" + " }\n" + " { // angular damping for point constraint\n" + " float4 ab = normalize3( posB - posA );\n" + " float4 ac = normalize3( center - posA );\n" + " if( dot3F4( ab, ac ) > 0.95f || (invMassA == 0.f || invMassB == 0.f))\n" + " {\n" + " float angNA = dot3F4( n, angVelA );\n" + " float angNB = dot3F4( n, angVelB );\n" + " \n" + " angVelA -= (angNA*0.1f)*n;\n" + " angVelB -= (angNB*0.1f)*n;\n" + " }\n" + " }\n" + " }\n" + " \n" + " \n" + " }\n" + " if (gBodies[aIdx].m_invMass)\n" + " {\n" + " gBodies[aIdx].m_linVel = linVelA;\n" + " gBodies[aIdx].m_angVel = angVelA;\n" + " } else\n" + " {\n" + " gBodies[aIdx].m_linVel = mymake_float4(0,0,0,0);\n" + " gBodies[aIdx].m_angVel = mymake_float4(0,0,0,0);\n" + " }\n" + " if (gBodies[bIdx].m_invMass)\n" + " {\n" + " gBodies[bIdx].m_linVel = linVelB;\n" + " gBodies[bIdx].m_angVel = angVelB;\n" + " } else\n" + " {\n" + " gBodies[bIdx].m_linVel = mymake_float4(0,0,0,0);\n" + " gBodies[bIdx].m_angVel = mymake_float4(0,0,0,0);\n" + " }\n" + " \n" + "}\n" + "typedef struct \n" + "{\n" + " int m_valInt0;\n" + " int m_valInt1;\n" + " int m_valInt2;\n" + " int m_valInt3;\n" + " float m_val0;\n" + " float m_val1;\n" + " float m_val2;\n" + " float m_val3;\n" + "} SolverDebugInfo;\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" + "void BatchSolveKernelFriction(__global Body* gBodies,\n" + " __global Shape* gShapes,\n" + " __global Constraint4* gConstraints,\n" + " __global int* gN,\n" + " __global int* gOffsets,\n" + " __global int* batchSizes,\n" + " int maxBatch1,\n" + " int cellBatch,\n" + " int4 nSplit\n" + " )\n" + "{\n" + " //__local int ldsBatchIdx[WG_SIZE+1];\n" + " __local int ldsCurBatch;\n" + " __local int ldsNextBatch;\n" + " __local int ldsStart;\n" + " int lIdx = GET_LOCAL_IDX;\n" + " int wgIdx = GET_GROUP_IDX;\n" + "// int gIdx = GET_GLOBAL_IDX;\n" + "// debugInfo[gIdx].m_valInt0 = gIdx;\n" + " //debugInfo[gIdx].m_valInt1 = GET_GROUP_SIZE;\n" + " int zIdx = (wgIdx/((nSplit.x*nSplit.y)/4))*2+((cellBatch&4)>>2);\n" + " int remain= (wgIdx%((nSplit.x*nSplit.y)/4));\n" + " int yIdx = (remain/(nSplit.x/2))*2 + ((cellBatch&2)>>1);\n" + " int xIdx = (remain%(nSplit.x/2))*2 + (cellBatch&1);\n" + " int cellIdx = xIdx+yIdx*nSplit.x+zIdx*(nSplit.x*nSplit.y);\n" + " \n" + " if( gN[cellIdx] == 0 ) \n" + " return;\n" + " int maxBatch = batchSizes[cellIdx];\n" + " const int start = gOffsets[cellIdx];\n" + " const int end = start + gN[cellIdx];\n" + " \n" + " if( lIdx == 0 )\n" + " {\n" + " ldsCurBatch = 0;\n" + " ldsNextBatch = 0;\n" + " ldsStart = start;\n" + " }\n" + " GROUP_LDS_BARRIER;\n" + " int idx=ldsStart+lIdx;\n" + " while (ldsCurBatch < maxBatch)\n" + " {\n" + " for(; idx1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" -" return false;\n" -" return true;\n" -"}\n" -"inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" -"{\n" -" float maxDot = -B3_INFINITY;\n" -" int i = 0;\n" -" int ptIndex = -1;\n" -" for( i = 0; i < vecLen; i++ )\n" -" {\n" -" float dot = b3Dot3F4(vecArray[i],vec);\n" -" \n" -" if( dot > maxDot )\n" -" {\n" -" maxDot = dot;\n" -" ptIndex = i;\n" -" }\n" -" }\n" -" b3Assert(ptIndex>=0);\n" -" if (ptIndex<0)\n" -" {\n" -" ptIndex = 0;\n" -" }\n" -" *dotOut = maxDot;\n" -" return ptIndex;\n" -"}\n" -"#endif //B3_FLOAT4_H\n" -"typedef struct b3Contact4Data b3Contact4Data_t;\n" -"struct b3Contact4Data\n" -"{\n" -" b3Float4 m_worldPosB[4];\n" -"// b3Float4 m_localPosA[4];\n" -"// b3Float4 m_localPosB[4];\n" -" b3Float4 m_worldNormalOnB; // w: m_nPoints\n" -" unsigned short m_restituitionCoeffCmp;\n" -" unsigned short m_frictionCoeffCmp;\n" -" int m_batchIdx;\n" -" int m_bodyAPtrAndSignBit;//x:m_bodyAPtr, y:m_bodyBPtr\n" -" int m_bodyBPtrAndSignBit;\n" -" int m_childIndexA;\n" -" int m_childIndexB;\n" -" int m_unused1;\n" -" int m_unused2;\n" -"};\n" -"inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact)\n" -"{\n" -" return (int)contact->m_worldNormalOnB.w;\n" -"};\n" -"inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints)\n" -"{\n" -" contact->m_worldNormalOnB.w = (float)numPoints;\n" -"};\n" -"#endif //B3_CONTACT4DATA_H\n" -"#ifndef B3_CONTACT_CONSTRAINT5_H\n" -"#define B3_CONTACT_CONSTRAINT5_H\n" -"#ifndef B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_FLOAT4_H\n" -"typedef struct b3ContactConstraint4 b3ContactConstraint4_t;\n" -"struct b3ContactConstraint4\n" -"{\n" -" b3Float4 m_linear;//normal?\n" -" b3Float4 m_worldPos[4];\n" -" b3Float4 m_center; // friction\n" -" float m_jacCoeffInv[4];\n" -" float m_b[4];\n" -" float m_appliedRambdaDt[4];\n" -" float m_fJacCoeffInv[2]; // friction\n" -" float m_fAppliedRambdaDt[2]; // friction\n" -" unsigned int m_bodyA;\n" -" unsigned int m_bodyB;\n" -" int m_batchIdx;\n" -" unsigned int m_paddings;\n" -"};\n" -"//inline void setFrictionCoeff(float value) { m_linear[3] = value; }\n" -"inline float b3GetFrictionCoeff(b3ContactConstraint4_t* constraint) \n" -"{\n" -" return constraint->m_linear.w; \n" -"}\n" -"#endif //B3_CONTACT_CONSTRAINT5_H\n" -"#ifndef B3_RIGIDBODY_DATA_H\n" -"#define B3_RIGIDBODY_DATA_H\n" -"#ifndef B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_FLOAT4_H\n" -"#ifndef B3_QUAT_H\n" -"#define B3_QUAT_H\n" -"#ifndef B3_PLATFORM_DEFINITIONS_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif\n" -"#endif\n" -"#ifndef B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -" typedef float4 b3Quat;\n" -" #define b3QuatConstArg const b3Quat\n" -" \n" -" \n" -"inline float4 b3FastNormalize4(float4 v)\n" -"{\n" -" v = (float4)(v.xyz,0.f);\n" -" return fast_normalize(v);\n" -"}\n" -" \n" -"inline b3Quat b3QuatMul(b3Quat a, b3Quat b);\n" -"inline b3Quat b3QuatNormalized(b3QuatConstArg in);\n" -"inline b3Quat b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec);\n" -"inline b3Quat b3QuatInvert(b3QuatConstArg q);\n" -"inline b3Quat b3QuatInverse(b3QuatConstArg q);\n" -"inline b3Quat b3QuatMul(b3QuatConstArg a, b3QuatConstArg b)\n" -"{\n" -" b3Quat ans;\n" -" ans = b3Cross3( a, b );\n" -" ans += a.w*b+b.w*a;\n" -"// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" -" ans.w = a.w*b.w - b3Dot3F4(a, b);\n" -" return ans;\n" -"}\n" -"inline b3Quat b3QuatNormalized(b3QuatConstArg in)\n" -"{\n" -" b3Quat q;\n" -" q=in;\n" -" //return b3FastNormalize4(in);\n" -" float len = native_sqrt(dot(q, q));\n" -" if(len > 0.f)\n" -" {\n" -" q *= 1.f / len;\n" -" }\n" -" else\n" -" {\n" -" q.x = q.y = q.z = 0.f;\n" -" q.w = 1.f;\n" -" }\n" -" return q;\n" -"}\n" -"inline float4 b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" -"{\n" -" b3Quat qInv = b3QuatInvert( q );\n" -" float4 vcpy = vec;\n" -" vcpy.w = 0.f;\n" -" float4 out = b3QuatMul(b3QuatMul(q,vcpy),qInv);\n" -" return out;\n" -"}\n" -"inline b3Quat b3QuatInverse(b3QuatConstArg q)\n" -"{\n" -" return (b3Quat)(-q.xyz, q.w);\n" -"}\n" -"inline b3Quat b3QuatInvert(b3QuatConstArg q)\n" -"{\n" -" return (b3Quat)(-q.xyz, q.w);\n" -"}\n" -"inline float4 b3QuatInvRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" -"{\n" -" return b3QuatRotate( b3QuatInvert( q ), vec );\n" -"}\n" -"inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)\n" -"{\n" -" return b3QuatRotate( orientation, point ) + (translation);\n" -"}\n" -" \n" -"#endif \n" -"#endif //B3_QUAT_H\n" -"#ifndef B3_MAT3x3_H\n" -"#define B3_MAT3x3_H\n" -"#ifndef B3_QUAT_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_QUAT_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"typedef struct\n" -"{\n" -" b3Float4 m_row[3];\n" -"}b3Mat3x3;\n" -"#define b3Mat3x3ConstArg const b3Mat3x3\n" -"#define b3GetRow(m,row) (m.m_row[row])\n" -"inline b3Mat3x3 b3QuatGetRotationMatrix(b3Quat quat)\n" -"{\n" -" b3Float4 quat2 = (b3Float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f);\n" -" b3Mat3x3 out;\n" -" out.m_row[0].x=1-2*quat2.y-2*quat2.z;\n" -" out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z;\n" -" out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y;\n" -" out.m_row[0].w = 0.f;\n" -" out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z;\n" -" out.m_row[1].y=1-2*quat2.x-2*quat2.z;\n" -" out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x;\n" -" out.m_row[1].w = 0.f;\n" -" out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y;\n" -" out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x;\n" -" out.m_row[2].z=1-2*quat2.x-2*quat2.y;\n" -" out.m_row[2].w = 0.f;\n" -" return out;\n" -"}\n" -"inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg matIn)\n" -"{\n" -" b3Mat3x3 out;\n" -" out.m_row[0] = fabs(matIn.m_row[0]);\n" -" out.m_row[1] = fabs(matIn.m_row[1]);\n" -" out.m_row[2] = fabs(matIn.m_row[2]);\n" -" return out;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtZero();\n" -"__inline\n" -"b3Mat3x3 mtIdentity();\n" -"__inline\n" -"b3Mat3x3 mtTranspose(b3Mat3x3 m);\n" -"__inline\n" -"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b);\n" -"__inline\n" -"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b);\n" -"__inline\n" -"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b);\n" -"__inline\n" -"b3Mat3x3 mtZero()\n" -"{\n" -" b3Mat3x3 m;\n" -" m.m_row[0] = (b3Float4)(0.f);\n" -" m.m_row[1] = (b3Float4)(0.f);\n" -" m.m_row[2] = (b3Float4)(0.f);\n" -" return m;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtIdentity()\n" -"{\n" -" b3Mat3x3 m;\n" -" m.m_row[0] = (b3Float4)(1,0,0,0);\n" -" m.m_row[1] = (b3Float4)(0,1,0,0);\n" -" m.m_row[2] = (b3Float4)(0,0,1,0);\n" -" return m;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtTranspose(b3Mat3x3 m)\n" -"{\n" -" b3Mat3x3 out;\n" -" out.m_row[0] = (b3Float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n" -" out.m_row[1] = (b3Float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n" -" out.m_row[2] = (b3Float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n" -" return out;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b)\n" -"{\n" -" b3Mat3x3 transB;\n" -" transB = mtTranspose( b );\n" -" b3Mat3x3 ans;\n" -" // why this doesn't run when 0ing in the for{}\n" -" a.m_row[0].w = 0.f;\n" -" a.m_row[1].w = 0.f;\n" -" a.m_row[2].w = 0.f;\n" -" for(int i=0; i<3; i++)\n" -" {\n" -"// a.m_row[i].w = 0.f;\n" -" ans.m_row[i].x = b3Dot3F4(a.m_row[i],transB.m_row[0]);\n" -" ans.m_row[i].y = b3Dot3F4(a.m_row[i],transB.m_row[1]);\n" -" ans.m_row[i].z = b3Dot3F4(a.m_row[i],transB.m_row[2]);\n" -" ans.m_row[i].w = 0.f;\n" -" }\n" -" return ans;\n" -"}\n" -"__inline\n" -"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b)\n" -"{\n" -" b3Float4 ans;\n" -" ans.x = b3Dot3F4( a.m_row[0], b );\n" -" ans.y = b3Dot3F4( a.m_row[1], b );\n" -" ans.z = b3Dot3F4( a.m_row[2], b );\n" -" ans.w = 0.f;\n" -" return ans;\n" -"}\n" -"__inline\n" -"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b)\n" -"{\n" -" b3Float4 colx = b3MakeFloat4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" -" b3Float4 coly = b3MakeFloat4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" -" b3Float4 colz = b3MakeFloat4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" -" b3Float4 ans;\n" -" ans.x = b3Dot3F4( a, colx );\n" -" ans.y = b3Dot3F4( a, coly );\n" -" ans.z = b3Dot3F4( a, colz );\n" -" return ans;\n" -"}\n" -"#endif\n" -"#endif //B3_MAT3x3_H\n" -"typedef struct b3RigidBodyData b3RigidBodyData_t;\n" -"struct b3RigidBodyData\n" -"{\n" -" b3Float4 m_pos;\n" -" b3Quat m_quat;\n" -" b3Float4 m_linVel;\n" -" b3Float4 m_angVel;\n" -" int m_collidableIdx;\n" -" float m_invMass;\n" -" float m_restituitionCoeff;\n" -" float m_frictionCoeff;\n" -"};\n" -"typedef struct b3InertiaData b3InertiaData_t;\n" -"struct b3InertiaData\n" -"{\n" -" b3Mat3x3 m_invInertiaWorld;\n" -" b3Mat3x3 m_initInvInertia;\n" -"};\n" -"#endif //B3_RIGIDBODY_DATA_H\n" -" \n" -"void b3PlaneSpace1 (b3Float4ConstArg n, b3Float4* p, b3Float4* q);\n" -" void b3PlaneSpace1 (b3Float4ConstArg n, b3Float4* p, b3Float4* q)\n" -"{\n" -" if (b3Fabs(n.z) > 0.70710678f) {\n" -" // choose p in y-z plane\n" -" float a = n.y*n.y + n.z*n.z;\n" -" float k = 1.f/sqrt(a);\n" -" p[0].x = 0;\n" -" p[0].y = -n.z*k;\n" -" p[0].z = n.y*k;\n" -" // set q = n x p\n" -" q[0].x = a*k;\n" -" q[0].y = -n.x*p[0].z;\n" -" q[0].z = n.x*p[0].y;\n" -" }\n" -" else {\n" -" // choose p in x-y plane\n" -" float a = n.x*n.x + n.y*n.y;\n" -" float k = 1.f/sqrt(a);\n" -" p[0].x = -n.y*k;\n" -" p[0].y = n.x*k;\n" -" p[0].z = 0;\n" -" // set q = n x p\n" -" q[0].x = -n.z*p[0].y;\n" -" q[0].y = n.z*p[0].x;\n" -" q[0].z = a*k;\n" -" }\n" -"}\n" -" \n" -"void setLinearAndAngular( b3Float4ConstArg n, b3Float4ConstArg r0, b3Float4ConstArg r1, b3Float4* linear, b3Float4* angular0, b3Float4* angular1)\n" -"{\n" -" *linear = b3MakeFloat4(n.x,n.y,n.z,0.f);\n" -" *angular0 = b3Cross3(r0, n);\n" -" *angular1 = -b3Cross3(r1, n);\n" -"}\n" -"float calcRelVel( b3Float4ConstArg l0, b3Float4ConstArg l1, b3Float4ConstArg a0, b3Float4ConstArg a1, b3Float4ConstArg linVel0,\n" -" b3Float4ConstArg angVel0, b3Float4ConstArg linVel1, b3Float4ConstArg angVel1 )\n" -"{\n" -" return b3Dot3F4(l0, linVel0) + b3Dot3F4(a0, angVel0) + b3Dot3F4(l1, linVel1) + b3Dot3F4(a1, angVel1);\n" -"}\n" -"float calcJacCoeff(b3Float4ConstArg linear0, b3Float4ConstArg linear1, b3Float4ConstArg angular0, b3Float4ConstArg angular1,\n" -" float invMass0, const b3Mat3x3* invInertia0, float invMass1, const b3Mat3x3* invInertia1)\n" -"{\n" -" // linear0,1 are normlized\n" -" float jmj0 = invMass0;//b3Dot3F4(linear0, linear0)*invMass0;\n" -" float jmj1 = b3Dot3F4(mtMul3(angular0,*invInertia0), angular0);\n" -" float jmj2 = invMass1;//b3Dot3F4(linear1, linear1)*invMass1;\n" -" float jmj3 = b3Dot3F4(mtMul3(angular1,*invInertia1), angular1);\n" -" return -1.f/(jmj0+jmj1+jmj2+jmj3);\n" -"}\n" -"void setConstraint4( b3Float4ConstArg posA, b3Float4ConstArg linVelA, b3Float4ConstArg angVelA, float invMassA, b3Mat3x3ConstArg invInertiaA,\n" -" b3Float4ConstArg posB, b3Float4ConstArg linVelB, b3Float4ConstArg angVelB, float invMassB, b3Mat3x3ConstArg invInertiaB, \n" -" __global struct b3Contact4Data* src, float dt, float positionDrift, float positionConstraintCoeff,\n" -" b3ContactConstraint4_t* dstC )\n" -"{\n" -" dstC->m_bodyA = abs(src->m_bodyAPtrAndSignBit);\n" -" dstC->m_bodyB = abs(src->m_bodyBPtrAndSignBit);\n" -" float dtInv = 1.f/dt;\n" -" for(int ic=0; ic<4; ic++)\n" -" {\n" -" dstC->m_appliedRambdaDt[ic] = 0.f;\n" -" }\n" -" dstC->m_fJacCoeffInv[0] = dstC->m_fJacCoeffInv[1] = 0.f;\n" -" dstC->m_linear = src->m_worldNormalOnB;\n" -" dstC->m_linear.w = 0.7f ;//src->getFrictionCoeff() );\n" -" for(int ic=0; ic<4; ic++)\n" -" {\n" -" b3Float4 r0 = src->m_worldPosB[ic] - posA;\n" -" b3Float4 r1 = src->m_worldPosB[ic] - posB;\n" -" if( ic >= src->m_worldNormalOnB.w )//npoints\n" -" {\n" -" dstC->m_jacCoeffInv[ic] = 0.f;\n" -" continue;\n" -" }\n" -" float relVelN;\n" -" {\n" -" b3Float4 linear, angular0, angular1;\n" -" setLinearAndAngular(src->m_worldNormalOnB, r0, r1, &linear, &angular0, &angular1);\n" -" dstC->m_jacCoeffInv[ic] = calcJacCoeff(linear, -linear, angular0, angular1,\n" -" invMassA, &invInertiaA, invMassB, &invInertiaB );\n" -" relVelN = calcRelVel(linear, -linear, angular0, angular1,\n" -" linVelA, angVelA, linVelB, angVelB);\n" -" float e = 0.f;//src->getRestituitionCoeff();\n" -" if( relVelN*relVelN < 0.004f ) e = 0.f;\n" -" dstC->m_b[ic] = e*relVelN;\n" -" //float penetration = src->m_worldPosB[ic].w;\n" -" dstC->m_b[ic] += (src->m_worldPosB[ic].w + positionDrift)*positionConstraintCoeff*dtInv;\n" -" dstC->m_appliedRambdaDt[ic] = 0.f;\n" -" }\n" -" }\n" -" if( src->m_worldNormalOnB.w > 0 )//npoints\n" -" { // prepare friction\n" -" b3Float4 center = b3MakeFloat4(0.f,0.f,0.f,0.f);\n" -" for(int i=0; im_worldNormalOnB.w; i++) \n" -" center += src->m_worldPosB[i];\n" -" center /= (float)src->m_worldNormalOnB.w;\n" -" b3Float4 tangent[2];\n" -" b3PlaneSpace1(src->m_worldNormalOnB,&tangent[0],&tangent[1]);\n" -" \n" -" b3Float4 r[2];\n" -" r[0] = center - posA;\n" -" r[1] = center - posB;\n" -" for(int i=0; i<2; i++)\n" -" {\n" -" b3Float4 linear, angular0, angular1;\n" -" setLinearAndAngular(tangent[i], r[0], r[1], &linear, &angular0, &angular1);\n" -" dstC->m_fJacCoeffInv[i] = calcJacCoeff(linear, -linear, angular0, angular1,\n" -" invMassA, &invInertiaA, invMassB, &invInertiaB );\n" -" dstC->m_fAppliedRambdaDt[i] = 0.f;\n" -" }\n" -" dstC->m_center = center;\n" -" }\n" -" for(int i=0; i<4; i++)\n" -" {\n" -" if( im_worldNormalOnB.w )\n" -" {\n" -" dstC->m_worldPos[i] = src->m_worldPosB[i];\n" -" }\n" -" else\n" -" {\n" -" dstC->m_worldPos[i] = b3MakeFloat4(0.f,0.f,0.f,0.f);\n" -" }\n" -" }\n" -"}\n" -"#pragma OPENCL EXTENSION cl_amd_printf : enable\n" -"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n" -"#ifdef cl_ext_atomic_counters_32\n" -"#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n" -"#else\n" -"#define counter32_t volatile global int*\n" -"#endif\n" -"typedef unsigned int u32;\n" -"typedef unsigned short u16;\n" -"typedef unsigned char u8;\n" -"#define GET_GROUP_IDX get_group_id(0)\n" -"#define GET_LOCAL_IDX get_local_id(0)\n" -"#define GET_GLOBAL_IDX get_global_id(0)\n" -"#define GET_GROUP_SIZE get_local_size(0)\n" -"#define GET_NUM_GROUPS get_num_groups(0)\n" -"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" -"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" -"#define AtomInc(x) atom_inc(&(x))\n" -"#define AtomInc1(x, out) out = atom_inc(&(x))\n" -"#define AppendInc(x, out) out = atomic_inc(x)\n" -"#define AtomAdd(x, value) atom_add(&(x), value)\n" -"#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n" -"#define AtomXhg(x, value) atom_xchg ( &(x), value )\n" -"#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n" -"#define make_float4 (float4)\n" -"#define make_float2 (float2)\n" -"#define make_uint4 (uint4)\n" -"#define make_int4 (int4)\n" -"#define make_uint2 (uint2)\n" -"#define make_int2 (int2)\n" -"#define max2 max\n" -"#define min2 min\n" -"///////////////////////////////////////\n" -"// Vector\n" -"///////////////////////////////////////\n" -"__inline\n" -"float fastDiv(float numerator, float denominator)\n" -"{\n" -" return native_divide(numerator, denominator); \n" -"// return numerator/denominator; \n" -"}\n" -"__inline\n" -"float4 fastDiv4(float4 numerator, float4 denominator)\n" -"{\n" -" return native_divide(numerator, denominator); \n" -"}\n" -"__inline\n" -"float fastSqrtf(float f2)\n" -"{\n" -" return native_sqrt(f2);\n" -"// return sqrt(f2);\n" -"}\n" -"__inline\n" -"float fastRSqrt(float f2)\n" -"{\n" -" return native_rsqrt(f2);\n" -"}\n" -"__inline\n" -"float fastLength4(float4 v)\n" -"{\n" -" return fast_length(v);\n" -"}\n" -"__inline\n" -"float4 fastNormalize4(float4 v)\n" -"{\n" -" return fast_normalize(v);\n" -"}\n" -"__inline\n" -"float sqrtf(float a)\n" -"{\n" -"// return sqrt(a);\n" -" return native_sqrt(a);\n" -"}\n" -"__inline\n" -"float4 cross3(float4 a, float4 b)\n" -"{\n" -" return cross(a,b);\n" -"}\n" -"__inline\n" -"float dot3F4(float4 a, float4 b)\n" -"{\n" -" float4 a1 = make_float4(a.xyz,0.f);\n" -" float4 b1 = make_float4(b.xyz,0.f);\n" -" return dot(a1, b1);\n" -"}\n" -"__inline\n" -"float length3(const float4 a)\n" -"{\n" -" return sqrtf(dot3F4(a,a));\n" -"}\n" -"__inline\n" -"float dot4(const float4 a, const float4 b)\n" -"{\n" -" return dot( a, b );\n" -"}\n" -"// for height\n" -"__inline\n" -"float dot3w1(const float4 point, const float4 eqn)\n" -"{\n" -" return dot3F4(point,eqn) + eqn.w;\n" -"}\n" -"__inline\n" -"float4 normalize3(const float4 a)\n" -"{\n" -" float4 n = make_float4(a.x, a.y, a.z, 0.f);\n" -" return fastNormalize4( n );\n" -"// float length = sqrtf(dot3F4(a, a));\n" -"// return 1.f/length * a;\n" -"}\n" -"__inline\n" -"float4 normalize4(const float4 a)\n" -"{\n" -" float length = sqrtf(dot4(a, a));\n" -" return 1.f/length * a;\n" -"}\n" -"__inline\n" -"float4 createEquation(const float4 a, const float4 b, const float4 c)\n" -"{\n" -" float4 eqn;\n" -" float4 ab = b-a;\n" -" float4 ac = c-a;\n" -" eqn = normalize3( cross3(ab, ac) );\n" -" eqn.w = -dot3F4(eqn,a);\n" -" return eqn;\n" -"}\n" -"#define WG_SIZE 64\n" -"typedef struct\n" -"{\n" -" int m_nConstraints;\n" -" int m_start;\n" -" int m_batchIdx;\n" -" int m_nSplit;\n" -"// int m_paddings[1];\n" -"} ConstBuffer;\n" -"typedef struct\n" -"{\n" -" int m_solveFriction;\n" -" int m_maxBatch; // long batch really kills the performance\n" -" int m_batchIdx;\n" -" int m_nSplit;\n" -"// int m_paddings[1];\n" -"} ConstBufferBatchSolve;\n" -" \n" -"typedef struct \n" -"{\n" -" int m_valInt0;\n" -" int m_valInt1;\n" -" int m_valInt2;\n" -" int m_valInt3;\n" -" float m_val0;\n" -" float m_val1;\n" -" float m_val2;\n" -" float m_val3;\n" -"} SolverDebugInfo;\n" -"typedef struct\n" -"{\n" -" int m_nContacts;\n" -" float m_dt;\n" -" float m_positionDrift;\n" -" float m_positionConstraintCoeff;\n" -"} ConstBufferCTC;\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" -"void ContactToConstraintKernel(__global struct b3Contact4Data* gContact, __global b3RigidBodyData_t* gBodies, __global b3InertiaData_t* gShapes, __global b3ContactConstraint4_t* gConstraintOut, \n" -"int nContacts,\n" -"float dt,\n" -"float positionDrift,\n" -"float positionConstraintCoeff\n" -")\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX;\n" -" \n" -" if( gIdx < nContacts )\n" -" {\n" -" int aIdx = abs(gContact[gIdx].m_bodyAPtrAndSignBit);\n" -" int bIdx = abs(gContact[gIdx].m_bodyBPtrAndSignBit);\n" -" float4 posA = gBodies[aIdx].m_pos;\n" -" float4 linVelA = gBodies[aIdx].m_linVel;\n" -" float4 angVelA = gBodies[aIdx].m_angVel;\n" -" float invMassA = gBodies[aIdx].m_invMass;\n" -" b3Mat3x3 invInertiaA = gShapes[aIdx].m_initInvInertia;\n" -" float4 posB = gBodies[bIdx].m_pos;\n" -" float4 linVelB = gBodies[bIdx].m_linVel;\n" -" float4 angVelB = gBodies[bIdx].m_angVel;\n" -" float invMassB = gBodies[bIdx].m_invMass;\n" -" b3Mat3x3 invInertiaB = gShapes[bIdx].m_initInvInertia;\n" -" b3ContactConstraint4_t cs;\n" -" setConstraint4( posA, linVelA, angVelA, invMassA, invInertiaA, posB, linVelB, angVelB, invMassB, invInertiaB,\n" -" &gContact[gIdx], dt, positionDrift, positionConstraintCoeff,\n" -" &cs );\n" -" \n" -" cs.m_batchIdx = gContact[gIdx].m_batchIdx;\n" -" gConstraintOut[gIdx] = cs;\n" -" }\n" -"}\n" -; +static const char* solverSetupCL = + "/*\n" + "Copyright (c) 2012 Advanced Micro Devices, Inc. \n" + "This software is provided 'as-is', without any express or implied warranty.\n" + "In no event will the authors be held liable for any damages arising from the use of this software.\n" + "Permission is granted to anyone to use this software for any purpose, \n" + "including commercial applications, and to alter it and redistribute it freely, \n" + "subject to the following restrictions:\n" + "1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" + "2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" + "3. This notice may not be removed or altered from any source distribution.\n" + "*/\n" + "//Originally written by Takahiro Harada\n" + "#ifndef B3_CONTACT4DATA_H\n" + "#define B3_CONTACT4DATA_H\n" + "#ifndef B3_FLOAT4_H\n" + "#define B3_FLOAT4_H\n" + "#ifndef B3_PLATFORM_DEFINITIONS_H\n" + "#define B3_PLATFORM_DEFINITIONS_H\n" + "struct MyTest\n" + "{\n" + " int bla;\n" + "};\n" + "#ifdef __cplusplus\n" + "#else\n" + "//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n" + "#define B3_LARGE_FLOAT 1e18f\n" + "#define B3_INFINITY 1e18f\n" + "#define b3Assert(a)\n" + "#define b3ConstArray(a) __global const a*\n" + "#define b3AtomicInc atomic_inc\n" + "#define b3AtomicAdd atomic_add\n" + "#define b3Fabs fabs\n" + "#define b3Sqrt native_sqrt\n" + "#define b3Sin native_sin\n" + "#define b3Cos native_cos\n" + "#define B3_STATIC\n" + "#endif\n" + "#endif\n" + "#ifdef __cplusplus\n" + "#else\n" + " typedef float4 b3Float4;\n" + " #define b3Float4ConstArg const b3Float4\n" + " #define b3MakeFloat4 (float4)\n" + " float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" + " {\n" + " float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" + " float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" + " return dot(a1, b1);\n" + " }\n" + " b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" + " {\n" + " float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" + " float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" + " return cross(a1, b1);\n" + " }\n" + " #define b3MinFloat4 min\n" + " #define b3MaxFloat4 max\n" + " #define b3Normalized(a) normalize(a)\n" + "#endif \n" + " \n" + "inline bool b3IsAlmostZero(b3Float4ConstArg v)\n" + "{\n" + " if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" + " return false;\n" + " return true;\n" + "}\n" + "inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" + "{\n" + " float maxDot = -B3_INFINITY;\n" + " int i = 0;\n" + " int ptIndex = -1;\n" + " for( i = 0; i < vecLen; i++ )\n" + " {\n" + " float dot = b3Dot3F4(vecArray[i],vec);\n" + " \n" + " if( dot > maxDot )\n" + " {\n" + " maxDot = dot;\n" + " ptIndex = i;\n" + " }\n" + " }\n" + " b3Assert(ptIndex>=0);\n" + " if (ptIndex<0)\n" + " {\n" + " ptIndex = 0;\n" + " }\n" + " *dotOut = maxDot;\n" + " return ptIndex;\n" + "}\n" + "#endif //B3_FLOAT4_H\n" + "typedef struct b3Contact4Data b3Contact4Data_t;\n" + "struct b3Contact4Data\n" + "{\n" + " b3Float4 m_worldPosB[4];\n" + "// b3Float4 m_localPosA[4];\n" + "// b3Float4 m_localPosB[4];\n" + " b3Float4 m_worldNormalOnB; // w: m_nPoints\n" + " unsigned short m_restituitionCoeffCmp;\n" + " unsigned short m_frictionCoeffCmp;\n" + " int m_batchIdx;\n" + " int m_bodyAPtrAndSignBit;//x:m_bodyAPtr, y:m_bodyBPtr\n" + " int m_bodyBPtrAndSignBit;\n" + " int m_childIndexA;\n" + " int m_childIndexB;\n" + " int m_unused1;\n" + " int m_unused2;\n" + "};\n" + "inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact)\n" + "{\n" + " return (int)contact->m_worldNormalOnB.w;\n" + "};\n" + "inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints)\n" + "{\n" + " contact->m_worldNormalOnB.w = (float)numPoints;\n" + "};\n" + "#endif //B3_CONTACT4DATA_H\n" + "#ifndef B3_CONTACT_CONSTRAINT5_H\n" + "#define B3_CONTACT_CONSTRAINT5_H\n" + "#ifndef B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_FLOAT4_H\n" + "typedef struct b3ContactConstraint4 b3ContactConstraint4_t;\n" + "struct b3ContactConstraint4\n" + "{\n" + " b3Float4 m_linear;//normal?\n" + " b3Float4 m_worldPos[4];\n" + " b3Float4 m_center; // friction\n" + " float m_jacCoeffInv[4];\n" + " float m_b[4];\n" + " float m_appliedRambdaDt[4];\n" + " float m_fJacCoeffInv[2]; // friction\n" + " float m_fAppliedRambdaDt[2]; // friction\n" + " unsigned int m_bodyA;\n" + " unsigned int m_bodyB;\n" + " int m_batchIdx;\n" + " unsigned int m_paddings;\n" + "};\n" + "//inline void setFrictionCoeff(float value) { m_linear[3] = value; }\n" + "inline float b3GetFrictionCoeff(b3ContactConstraint4_t* constraint) \n" + "{\n" + " return constraint->m_linear.w; \n" + "}\n" + "#endif //B3_CONTACT_CONSTRAINT5_H\n" + "#ifndef B3_RIGIDBODY_DATA_H\n" + "#define B3_RIGIDBODY_DATA_H\n" + "#ifndef B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_FLOAT4_H\n" + "#ifndef B3_QUAT_H\n" + "#define B3_QUAT_H\n" + "#ifndef B3_PLATFORM_DEFINITIONS_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif\n" + "#endif\n" + "#ifndef B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + " typedef float4 b3Quat;\n" + " #define b3QuatConstArg const b3Quat\n" + " \n" + " \n" + "inline float4 b3FastNormalize4(float4 v)\n" + "{\n" + " v = (float4)(v.xyz,0.f);\n" + " return fast_normalize(v);\n" + "}\n" + " \n" + "inline b3Quat b3QuatMul(b3Quat a, b3Quat b);\n" + "inline b3Quat b3QuatNormalized(b3QuatConstArg in);\n" + "inline b3Quat b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec);\n" + "inline b3Quat b3QuatInvert(b3QuatConstArg q);\n" + "inline b3Quat b3QuatInverse(b3QuatConstArg q);\n" + "inline b3Quat b3QuatMul(b3QuatConstArg a, b3QuatConstArg b)\n" + "{\n" + " b3Quat ans;\n" + " ans = b3Cross3( a, b );\n" + " ans += a.w*b+b.w*a;\n" + "// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" + " ans.w = a.w*b.w - b3Dot3F4(a, b);\n" + " return ans;\n" + "}\n" + "inline b3Quat b3QuatNormalized(b3QuatConstArg in)\n" + "{\n" + " b3Quat q;\n" + " q=in;\n" + " //return b3FastNormalize4(in);\n" + " float len = native_sqrt(dot(q, q));\n" + " if(len > 0.f)\n" + " {\n" + " q *= 1.f / len;\n" + " }\n" + " else\n" + " {\n" + " q.x = q.y = q.z = 0.f;\n" + " q.w = 1.f;\n" + " }\n" + " return q;\n" + "}\n" + "inline float4 b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" + "{\n" + " b3Quat qInv = b3QuatInvert( q );\n" + " float4 vcpy = vec;\n" + " vcpy.w = 0.f;\n" + " float4 out = b3QuatMul(b3QuatMul(q,vcpy),qInv);\n" + " return out;\n" + "}\n" + "inline b3Quat b3QuatInverse(b3QuatConstArg q)\n" + "{\n" + " return (b3Quat)(-q.xyz, q.w);\n" + "}\n" + "inline b3Quat b3QuatInvert(b3QuatConstArg q)\n" + "{\n" + " return (b3Quat)(-q.xyz, q.w);\n" + "}\n" + "inline float4 b3QuatInvRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" + "{\n" + " return b3QuatRotate( b3QuatInvert( q ), vec );\n" + "}\n" + "inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)\n" + "{\n" + " return b3QuatRotate( orientation, point ) + (translation);\n" + "}\n" + " \n" + "#endif \n" + "#endif //B3_QUAT_H\n" + "#ifndef B3_MAT3x3_H\n" + "#define B3_MAT3x3_H\n" + "#ifndef B3_QUAT_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_QUAT_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "typedef struct\n" + "{\n" + " b3Float4 m_row[3];\n" + "}b3Mat3x3;\n" + "#define b3Mat3x3ConstArg const b3Mat3x3\n" + "#define b3GetRow(m,row) (m.m_row[row])\n" + "inline b3Mat3x3 b3QuatGetRotationMatrix(b3Quat quat)\n" + "{\n" + " b3Float4 quat2 = (b3Float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f);\n" + " b3Mat3x3 out;\n" + " out.m_row[0].x=1-2*quat2.y-2*quat2.z;\n" + " out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z;\n" + " out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y;\n" + " out.m_row[0].w = 0.f;\n" + " out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z;\n" + " out.m_row[1].y=1-2*quat2.x-2*quat2.z;\n" + " out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x;\n" + " out.m_row[1].w = 0.f;\n" + " out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y;\n" + " out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x;\n" + " out.m_row[2].z=1-2*quat2.x-2*quat2.y;\n" + " out.m_row[2].w = 0.f;\n" + " return out;\n" + "}\n" + "inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg matIn)\n" + "{\n" + " b3Mat3x3 out;\n" + " out.m_row[0] = fabs(matIn.m_row[0]);\n" + " out.m_row[1] = fabs(matIn.m_row[1]);\n" + " out.m_row[2] = fabs(matIn.m_row[2]);\n" + " return out;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtZero();\n" + "__inline\n" + "b3Mat3x3 mtIdentity();\n" + "__inline\n" + "b3Mat3x3 mtTranspose(b3Mat3x3 m);\n" + "__inline\n" + "b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b);\n" + "__inline\n" + "b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b);\n" + "__inline\n" + "b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b);\n" + "__inline\n" + "b3Mat3x3 mtZero()\n" + "{\n" + " b3Mat3x3 m;\n" + " m.m_row[0] = (b3Float4)(0.f);\n" + " m.m_row[1] = (b3Float4)(0.f);\n" + " m.m_row[2] = (b3Float4)(0.f);\n" + " return m;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtIdentity()\n" + "{\n" + " b3Mat3x3 m;\n" + " m.m_row[0] = (b3Float4)(1,0,0,0);\n" + " m.m_row[1] = (b3Float4)(0,1,0,0);\n" + " m.m_row[2] = (b3Float4)(0,0,1,0);\n" + " return m;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtTranspose(b3Mat3x3 m)\n" + "{\n" + " b3Mat3x3 out;\n" + " out.m_row[0] = (b3Float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n" + " out.m_row[1] = (b3Float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n" + " out.m_row[2] = (b3Float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n" + " return out;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b)\n" + "{\n" + " b3Mat3x3 transB;\n" + " transB = mtTranspose( b );\n" + " b3Mat3x3 ans;\n" + " // why this doesn't run when 0ing in the for{}\n" + " a.m_row[0].w = 0.f;\n" + " a.m_row[1].w = 0.f;\n" + " a.m_row[2].w = 0.f;\n" + " for(int i=0; i<3; i++)\n" + " {\n" + "// a.m_row[i].w = 0.f;\n" + " ans.m_row[i].x = b3Dot3F4(a.m_row[i],transB.m_row[0]);\n" + " ans.m_row[i].y = b3Dot3F4(a.m_row[i],transB.m_row[1]);\n" + " ans.m_row[i].z = b3Dot3F4(a.m_row[i],transB.m_row[2]);\n" + " ans.m_row[i].w = 0.f;\n" + " }\n" + " return ans;\n" + "}\n" + "__inline\n" + "b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b)\n" + "{\n" + " b3Float4 ans;\n" + " ans.x = b3Dot3F4( a.m_row[0], b );\n" + " ans.y = b3Dot3F4( a.m_row[1], b );\n" + " ans.z = b3Dot3F4( a.m_row[2], b );\n" + " ans.w = 0.f;\n" + " return ans;\n" + "}\n" + "__inline\n" + "b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b)\n" + "{\n" + " b3Float4 colx = b3MakeFloat4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" + " b3Float4 coly = b3MakeFloat4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" + " b3Float4 colz = b3MakeFloat4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" + " b3Float4 ans;\n" + " ans.x = b3Dot3F4( a, colx );\n" + " ans.y = b3Dot3F4( a, coly );\n" + " ans.z = b3Dot3F4( a, colz );\n" + " return ans;\n" + "}\n" + "#endif\n" + "#endif //B3_MAT3x3_H\n" + "typedef struct b3RigidBodyData b3RigidBodyData_t;\n" + "struct b3RigidBodyData\n" + "{\n" + " b3Float4 m_pos;\n" + " b3Quat m_quat;\n" + " b3Float4 m_linVel;\n" + " b3Float4 m_angVel;\n" + " int m_collidableIdx;\n" + " float m_invMass;\n" + " float m_restituitionCoeff;\n" + " float m_frictionCoeff;\n" + "};\n" + "typedef struct b3InertiaData b3InertiaData_t;\n" + "struct b3InertiaData\n" + "{\n" + " b3Mat3x3 m_invInertiaWorld;\n" + " b3Mat3x3 m_initInvInertia;\n" + "};\n" + "#endif //B3_RIGIDBODY_DATA_H\n" + " \n" + "void b3PlaneSpace1 (b3Float4ConstArg n, b3Float4* p, b3Float4* q);\n" + " void b3PlaneSpace1 (b3Float4ConstArg n, b3Float4* p, b3Float4* q)\n" + "{\n" + " if (b3Fabs(n.z) > 0.70710678f) {\n" + " // choose p in y-z plane\n" + " float a = n.y*n.y + n.z*n.z;\n" + " float k = 1.f/sqrt(a);\n" + " p[0].x = 0;\n" + " p[0].y = -n.z*k;\n" + " p[0].z = n.y*k;\n" + " // set q = n x p\n" + " q[0].x = a*k;\n" + " q[0].y = -n.x*p[0].z;\n" + " q[0].z = n.x*p[0].y;\n" + " }\n" + " else {\n" + " // choose p in x-y plane\n" + " float a = n.x*n.x + n.y*n.y;\n" + " float k = 1.f/sqrt(a);\n" + " p[0].x = -n.y*k;\n" + " p[0].y = n.x*k;\n" + " p[0].z = 0;\n" + " // set q = n x p\n" + " q[0].x = -n.z*p[0].y;\n" + " q[0].y = n.z*p[0].x;\n" + " q[0].z = a*k;\n" + " }\n" + "}\n" + " \n" + "void setLinearAndAngular( b3Float4ConstArg n, b3Float4ConstArg r0, b3Float4ConstArg r1, b3Float4* linear, b3Float4* angular0, b3Float4* angular1)\n" + "{\n" + " *linear = b3MakeFloat4(n.x,n.y,n.z,0.f);\n" + " *angular0 = b3Cross3(r0, n);\n" + " *angular1 = -b3Cross3(r1, n);\n" + "}\n" + "float calcRelVel( b3Float4ConstArg l0, b3Float4ConstArg l1, b3Float4ConstArg a0, b3Float4ConstArg a1, b3Float4ConstArg linVel0,\n" + " b3Float4ConstArg angVel0, b3Float4ConstArg linVel1, b3Float4ConstArg angVel1 )\n" + "{\n" + " return b3Dot3F4(l0, linVel0) + b3Dot3F4(a0, angVel0) + b3Dot3F4(l1, linVel1) + b3Dot3F4(a1, angVel1);\n" + "}\n" + "float calcJacCoeff(b3Float4ConstArg linear0, b3Float4ConstArg linear1, b3Float4ConstArg angular0, b3Float4ConstArg angular1,\n" + " float invMass0, const b3Mat3x3* invInertia0, float invMass1, const b3Mat3x3* invInertia1)\n" + "{\n" + " // linear0,1 are normlized\n" + " float jmj0 = invMass0;//b3Dot3F4(linear0, linear0)*invMass0;\n" + " float jmj1 = b3Dot3F4(mtMul3(angular0,*invInertia0), angular0);\n" + " float jmj2 = invMass1;//b3Dot3F4(linear1, linear1)*invMass1;\n" + " float jmj3 = b3Dot3F4(mtMul3(angular1,*invInertia1), angular1);\n" + " return -1.f/(jmj0+jmj1+jmj2+jmj3);\n" + "}\n" + "void setConstraint4( b3Float4ConstArg posA, b3Float4ConstArg linVelA, b3Float4ConstArg angVelA, float invMassA, b3Mat3x3ConstArg invInertiaA,\n" + " b3Float4ConstArg posB, b3Float4ConstArg linVelB, b3Float4ConstArg angVelB, float invMassB, b3Mat3x3ConstArg invInertiaB, \n" + " __global struct b3Contact4Data* src, float dt, float positionDrift, float positionConstraintCoeff,\n" + " b3ContactConstraint4_t* dstC )\n" + "{\n" + " dstC->m_bodyA = abs(src->m_bodyAPtrAndSignBit);\n" + " dstC->m_bodyB = abs(src->m_bodyBPtrAndSignBit);\n" + " float dtInv = 1.f/dt;\n" + " for(int ic=0; ic<4; ic++)\n" + " {\n" + " dstC->m_appliedRambdaDt[ic] = 0.f;\n" + " }\n" + " dstC->m_fJacCoeffInv[0] = dstC->m_fJacCoeffInv[1] = 0.f;\n" + " dstC->m_linear = src->m_worldNormalOnB;\n" + " dstC->m_linear.w = 0.7f ;//src->getFrictionCoeff() );\n" + " for(int ic=0; ic<4; ic++)\n" + " {\n" + " b3Float4 r0 = src->m_worldPosB[ic] - posA;\n" + " b3Float4 r1 = src->m_worldPosB[ic] - posB;\n" + " if( ic >= src->m_worldNormalOnB.w )//npoints\n" + " {\n" + " dstC->m_jacCoeffInv[ic] = 0.f;\n" + " continue;\n" + " }\n" + " float relVelN;\n" + " {\n" + " b3Float4 linear, angular0, angular1;\n" + " setLinearAndAngular(src->m_worldNormalOnB, r0, r1, &linear, &angular0, &angular1);\n" + " dstC->m_jacCoeffInv[ic] = calcJacCoeff(linear, -linear, angular0, angular1,\n" + " invMassA, &invInertiaA, invMassB, &invInertiaB );\n" + " relVelN = calcRelVel(linear, -linear, angular0, angular1,\n" + " linVelA, angVelA, linVelB, angVelB);\n" + " float e = 0.f;//src->getRestituitionCoeff();\n" + " if( relVelN*relVelN < 0.004f ) e = 0.f;\n" + " dstC->m_b[ic] = e*relVelN;\n" + " //float penetration = src->m_worldPosB[ic].w;\n" + " dstC->m_b[ic] += (src->m_worldPosB[ic].w + positionDrift)*positionConstraintCoeff*dtInv;\n" + " dstC->m_appliedRambdaDt[ic] = 0.f;\n" + " }\n" + " }\n" + " if( src->m_worldNormalOnB.w > 0 )//npoints\n" + " { // prepare friction\n" + " b3Float4 center = b3MakeFloat4(0.f,0.f,0.f,0.f);\n" + " for(int i=0; im_worldNormalOnB.w; i++) \n" + " center += src->m_worldPosB[i];\n" + " center /= (float)src->m_worldNormalOnB.w;\n" + " b3Float4 tangent[2];\n" + " b3PlaneSpace1(src->m_worldNormalOnB,&tangent[0],&tangent[1]);\n" + " \n" + " b3Float4 r[2];\n" + " r[0] = center - posA;\n" + " r[1] = center - posB;\n" + " for(int i=0; i<2; i++)\n" + " {\n" + " b3Float4 linear, angular0, angular1;\n" + " setLinearAndAngular(tangent[i], r[0], r[1], &linear, &angular0, &angular1);\n" + " dstC->m_fJacCoeffInv[i] = calcJacCoeff(linear, -linear, angular0, angular1,\n" + " invMassA, &invInertiaA, invMassB, &invInertiaB );\n" + " dstC->m_fAppliedRambdaDt[i] = 0.f;\n" + " }\n" + " dstC->m_center = center;\n" + " }\n" + " for(int i=0; i<4; i++)\n" + " {\n" + " if( im_worldNormalOnB.w )\n" + " {\n" + " dstC->m_worldPos[i] = src->m_worldPosB[i];\n" + " }\n" + " else\n" + " {\n" + " dstC->m_worldPos[i] = b3MakeFloat4(0.f,0.f,0.f,0.f);\n" + " }\n" + " }\n" + "}\n" + "#pragma OPENCL EXTENSION cl_amd_printf : enable\n" + "#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" + "#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n" + "#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n" + "#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n" + "#ifdef cl_ext_atomic_counters_32\n" + "#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n" + "#else\n" + "#define counter32_t volatile global int*\n" + "#endif\n" + "typedef unsigned int u32;\n" + "typedef unsigned short u16;\n" + "typedef unsigned char u8;\n" + "#define GET_GROUP_IDX get_group_id(0)\n" + "#define GET_LOCAL_IDX get_local_id(0)\n" + "#define GET_GLOBAL_IDX get_global_id(0)\n" + "#define GET_GROUP_SIZE get_local_size(0)\n" + "#define GET_NUM_GROUPS get_num_groups(0)\n" + "#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" + "#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" + "#define AtomInc(x) atom_inc(&(x))\n" + "#define AtomInc1(x, out) out = atom_inc(&(x))\n" + "#define AppendInc(x, out) out = atomic_inc(x)\n" + "#define AtomAdd(x, value) atom_add(&(x), value)\n" + "#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n" + "#define AtomXhg(x, value) atom_xchg ( &(x), value )\n" + "#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n" + "#define make_float4 (float4)\n" + "#define make_float2 (float2)\n" + "#define make_uint4 (uint4)\n" + "#define make_int4 (int4)\n" + "#define make_uint2 (uint2)\n" + "#define make_int2 (int2)\n" + "#define max2 max\n" + "#define min2 min\n" + "///////////////////////////////////////\n" + "// Vector\n" + "///////////////////////////////////////\n" + "__inline\n" + "float fastDiv(float numerator, float denominator)\n" + "{\n" + " return native_divide(numerator, denominator); \n" + "// return numerator/denominator; \n" + "}\n" + "__inline\n" + "float4 fastDiv4(float4 numerator, float4 denominator)\n" + "{\n" + " return native_divide(numerator, denominator); \n" + "}\n" + "__inline\n" + "float fastSqrtf(float f2)\n" + "{\n" + " return native_sqrt(f2);\n" + "// return sqrt(f2);\n" + "}\n" + "__inline\n" + "float fastRSqrt(float f2)\n" + "{\n" + " return native_rsqrt(f2);\n" + "}\n" + "__inline\n" + "float fastLength4(float4 v)\n" + "{\n" + " return fast_length(v);\n" + "}\n" + "__inline\n" + "float4 fastNormalize4(float4 v)\n" + "{\n" + " return fast_normalize(v);\n" + "}\n" + "__inline\n" + "float sqrtf(float a)\n" + "{\n" + "// return sqrt(a);\n" + " return native_sqrt(a);\n" + "}\n" + "__inline\n" + "float4 cross3(float4 a, float4 b)\n" + "{\n" + " return cross(a,b);\n" + "}\n" + "__inline\n" + "float dot3F4(float4 a, float4 b)\n" + "{\n" + " float4 a1 = make_float4(a.xyz,0.f);\n" + " float4 b1 = make_float4(b.xyz,0.f);\n" + " return dot(a1, b1);\n" + "}\n" + "__inline\n" + "float length3(const float4 a)\n" + "{\n" + " return sqrtf(dot3F4(a,a));\n" + "}\n" + "__inline\n" + "float dot4(const float4 a, const float4 b)\n" + "{\n" + " return dot( a, b );\n" + "}\n" + "// for height\n" + "__inline\n" + "float dot3w1(const float4 point, const float4 eqn)\n" + "{\n" + " return dot3F4(point,eqn) + eqn.w;\n" + "}\n" + "__inline\n" + "float4 normalize3(const float4 a)\n" + "{\n" + " float4 n = make_float4(a.x, a.y, a.z, 0.f);\n" + " return fastNormalize4( n );\n" + "// float length = sqrtf(dot3F4(a, a));\n" + "// return 1.f/length * a;\n" + "}\n" + "__inline\n" + "float4 normalize4(const float4 a)\n" + "{\n" + " float length = sqrtf(dot4(a, a));\n" + " return 1.f/length * a;\n" + "}\n" + "__inline\n" + "float4 createEquation(const float4 a, const float4 b, const float4 c)\n" + "{\n" + " float4 eqn;\n" + " float4 ab = b-a;\n" + " float4 ac = c-a;\n" + " eqn = normalize3( cross3(ab, ac) );\n" + " eqn.w = -dot3F4(eqn,a);\n" + " return eqn;\n" + "}\n" + "#define WG_SIZE 64\n" + "typedef struct\n" + "{\n" + " int m_nConstraints;\n" + " int m_start;\n" + " int m_batchIdx;\n" + " int m_nSplit;\n" + "// int m_paddings[1];\n" + "} ConstBuffer;\n" + "typedef struct\n" + "{\n" + " int m_solveFriction;\n" + " int m_maxBatch; // long batch really kills the performance\n" + " int m_batchIdx;\n" + " int m_nSplit;\n" + "// int m_paddings[1];\n" + "} ConstBufferBatchSolve;\n" + " \n" + "typedef struct \n" + "{\n" + " int m_valInt0;\n" + " int m_valInt1;\n" + " int m_valInt2;\n" + " int m_valInt3;\n" + " float m_val0;\n" + " float m_val1;\n" + " float m_val2;\n" + " float m_val3;\n" + "} SolverDebugInfo;\n" + "typedef struct\n" + "{\n" + " int m_nContacts;\n" + " float m_dt;\n" + " float m_positionDrift;\n" + " float m_positionConstraintCoeff;\n" + "} ConstBufferCTC;\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" + "void ContactToConstraintKernel(__global struct b3Contact4Data* gContact, __global b3RigidBodyData_t* gBodies, __global b3InertiaData_t* gShapes, __global b3ContactConstraint4_t* gConstraintOut, \n" + "int nContacts,\n" + "float dt,\n" + "float positionDrift,\n" + "float positionConstraintCoeff\n" + ")\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX;\n" + " \n" + " if( gIdx < nContacts )\n" + " {\n" + " int aIdx = abs(gContact[gIdx].m_bodyAPtrAndSignBit);\n" + " int bIdx = abs(gContact[gIdx].m_bodyBPtrAndSignBit);\n" + " float4 posA = gBodies[aIdx].m_pos;\n" + " float4 linVelA = gBodies[aIdx].m_linVel;\n" + " float4 angVelA = gBodies[aIdx].m_angVel;\n" + " float invMassA = gBodies[aIdx].m_invMass;\n" + " b3Mat3x3 invInertiaA = gShapes[aIdx].m_initInvInertia;\n" + " float4 posB = gBodies[bIdx].m_pos;\n" + " float4 linVelB = gBodies[bIdx].m_linVel;\n" + " float4 angVelB = gBodies[bIdx].m_angVel;\n" + " float invMassB = gBodies[bIdx].m_invMass;\n" + " b3Mat3x3 invInertiaB = gShapes[bIdx].m_initInvInertia;\n" + " b3ContactConstraint4_t cs;\n" + " setConstraint4( posA, linVelA, angVelA, invMassA, invInertiaA, posB, linVelB, angVelB, invMassB, invInertiaB,\n" + " &gContact[gIdx], dt, positionDrift, positionConstraintCoeff,\n" + " &cs );\n" + " \n" + " cs.m_batchIdx = gContact[gIdx].m_batchIdx;\n" + " gConstraintOut[gIdx] = cs;\n" + " }\n" + "}\n"; diff --git a/src/Bullet3OpenCL/RigidBody/kernels/solverSetup2.h b/src/Bullet3OpenCL/RigidBody/kernels/solverSetup2.h index 1b5819f6c..1e6e3579b 100644 --- a/src/Bullet3OpenCL/RigidBody/kernels/solverSetup2.h +++ b/src/Bullet3OpenCL/RigidBody/kernels/solverSetup2.h @@ -1,601 +1,600 @@ //this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project -static const char* solverSetup2CL= \ -"/*\n" -"Copyright (c) 2012 Advanced Micro Devices, Inc. \n" -"This software is provided 'as-is', without any express or implied warranty.\n" -"In no event will the authors be held liable for any damages arising from the use of this software.\n" -"Permission is granted to anyone to use this software for any purpose, \n" -"including commercial applications, and to alter it and redistribute it freely, \n" -"subject to the following restrictions:\n" -"1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" -"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" -"3. This notice may not be removed or altered from any source distribution.\n" -"*/\n" -"//Originally written by Takahiro Harada\n" -"#ifndef B3_CONTACT4DATA_H\n" -"#define B3_CONTACT4DATA_H\n" -"#ifndef B3_FLOAT4_H\n" -"#define B3_FLOAT4_H\n" -"#ifndef B3_PLATFORM_DEFINITIONS_H\n" -"#define B3_PLATFORM_DEFINITIONS_H\n" -"struct MyTest\n" -"{\n" -" int bla;\n" -"};\n" -"#ifdef __cplusplus\n" -"#else\n" -"//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n" -"#define B3_LARGE_FLOAT 1e18f\n" -"#define B3_INFINITY 1e18f\n" -"#define b3Assert(a)\n" -"#define b3ConstArray(a) __global const a*\n" -"#define b3AtomicInc atomic_inc\n" -"#define b3AtomicAdd atomic_add\n" -"#define b3Fabs fabs\n" -"#define b3Sqrt native_sqrt\n" -"#define b3Sin native_sin\n" -"#define b3Cos native_cos\n" -"#define B3_STATIC\n" -"#endif\n" -"#endif\n" -"#ifdef __cplusplus\n" -"#else\n" -" typedef float4 b3Float4;\n" -" #define b3Float4ConstArg const b3Float4\n" -" #define b3MakeFloat4 (float4)\n" -" float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" -" {\n" -" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" -" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" -" return dot(a1, b1);\n" -" }\n" -" b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" -" {\n" -" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" -" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" -" return cross(a1, b1);\n" -" }\n" -" #define b3MinFloat4 min\n" -" #define b3MaxFloat4 max\n" -" #define b3Normalized(a) normalize(a)\n" -"#endif \n" -" \n" -"inline bool b3IsAlmostZero(b3Float4ConstArg v)\n" -"{\n" -" if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" -" return false;\n" -" return true;\n" -"}\n" -"inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" -"{\n" -" float maxDot = -B3_INFINITY;\n" -" int i = 0;\n" -" int ptIndex = -1;\n" -" for( i = 0; i < vecLen; i++ )\n" -" {\n" -" float dot = b3Dot3F4(vecArray[i],vec);\n" -" \n" -" if( dot > maxDot )\n" -" {\n" -" maxDot = dot;\n" -" ptIndex = i;\n" -" }\n" -" }\n" -" b3Assert(ptIndex>=0);\n" -" if (ptIndex<0)\n" -" {\n" -" ptIndex = 0;\n" -" }\n" -" *dotOut = maxDot;\n" -" return ptIndex;\n" -"}\n" -"#endif //B3_FLOAT4_H\n" -"typedef struct b3Contact4Data b3Contact4Data_t;\n" -"struct b3Contact4Data\n" -"{\n" -" b3Float4 m_worldPosB[4];\n" -"// b3Float4 m_localPosA[4];\n" -"// b3Float4 m_localPosB[4];\n" -" b3Float4 m_worldNormalOnB; // w: m_nPoints\n" -" unsigned short m_restituitionCoeffCmp;\n" -" unsigned short m_frictionCoeffCmp;\n" -" int m_batchIdx;\n" -" int m_bodyAPtrAndSignBit;//x:m_bodyAPtr, y:m_bodyBPtr\n" -" int m_bodyBPtrAndSignBit;\n" -" int m_childIndexA;\n" -" int m_childIndexB;\n" -" int m_unused1;\n" -" int m_unused2;\n" -"};\n" -"inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact)\n" -"{\n" -" return (int)contact->m_worldNormalOnB.w;\n" -"};\n" -"inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints)\n" -"{\n" -" contact->m_worldNormalOnB.w = (float)numPoints;\n" -"};\n" -"#endif //B3_CONTACT4DATA_H\n" -"#pragma OPENCL EXTENSION cl_amd_printf : enable\n" -"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n" -"#ifdef cl_ext_atomic_counters_32\n" -"#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n" -"#else\n" -"#define counter32_t volatile global int*\n" -"#endif\n" -"typedef unsigned int u32;\n" -"typedef unsigned short u16;\n" -"typedef unsigned char u8;\n" -"#define GET_GROUP_IDX get_group_id(0)\n" -"#define GET_LOCAL_IDX get_local_id(0)\n" -"#define GET_GLOBAL_IDX get_global_id(0)\n" -"#define GET_GROUP_SIZE get_local_size(0)\n" -"#define GET_NUM_GROUPS get_num_groups(0)\n" -"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" -"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" -"#define AtomInc(x) atom_inc(&(x))\n" -"#define AtomInc1(x, out) out = atom_inc(&(x))\n" -"#define AppendInc(x, out) out = atomic_inc(x)\n" -"#define AtomAdd(x, value) atom_add(&(x), value)\n" -"#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n" -"#define AtomXhg(x, value) atom_xchg ( &(x), value )\n" -"#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n" -"#define make_float4 (float4)\n" -"#define make_float2 (float2)\n" -"#define make_uint4 (uint4)\n" -"#define make_int4 (int4)\n" -"#define make_uint2 (uint2)\n" -"#define make_int2 (int2)\n" -"#define max2 max\n" -"#define min2 min\n" -"///////////////////////////////////////\n" -"// Vector\n" -"///////////////////////////////////////\n" -"__inline\n" -"float fastDiv(float numerator, float denominator)\n" -"{\n" -" return native_divide(numerator, denominator); \n" -"// return numerator/denominator; \n" -"}\n" -"__inline\n" -"float4 fastDiv4(float4 numerator, float4 denominator)\n" -"{\n" -" return native_divide(numerator, denominator); \n" -"}\n" -"__inline\n" -"float fastSqrtf(float f2)\n" -"{\n" -" return native_sqrt(f2);\n" -"// return sqrt(f2);\n" -"}\n" -"__inline\n" -"float fastRSqrt(float f2)\n" -"{\n" -" return native_rsqrt(f2);\n" -"}\n" -"__inline\n" -"float fastLength4(float4 v)\n" -"{\n" -" return fast_length(v);\n" -"}\n" -"__inline\n" -"float4 fastNormalize4(float4 v)\n" -"{\n" -" return fast_normalize(v);\n" -"}\n" -"__inline\n" -"float sqrtf(float a)\n" -"{\n" -"// return sqrt(a);\n" -" return native_sqrt(a);\n" -"}\n" -"__inline\n" -"float4 cross3(float4 a, float4 b)\n" -"{\n" -" return cross(a,b);\n" -"}\n" -"__inline\n" -"float dot3F4(float4 a, float4 b)\n" -"{\n" -" float4 a1 = make_float4(a.xyz,0.f);\n" -" float4 b1 = make_float4(b.xyz,0.f);\n" -" return dot(a1, b1);\n" -"}\n" -"__inline\n" -"float length3(const float4 a)\n" -"{\n" -" return sqrtf(dot3F4(a,a));\n" -"}\n" -"__inline\n" -"float dot4(const float4 a, const float4 b)\n" -"{\n" -" return dot( a, b );\n" -"}\n" -"// for height\n" -"__inline\n" -"float dot3w1(const float4 point, const float4 eqn)\n" -"{\n" -" return dot3F4(point,eqn) + eqn.w;\n" -"}\n" -"__inline\n" -"float4 normalize3(const float4 a)\n" -"{\n" -" float4 n = make_float4(a.x, a.y, a.z, 0.f);\n" -" return fastNormalize4( n );\n" -"// float length = sqrtf(dot3F4(a, a));\n" -"// return 1.f/length * a;\n" -"}\n" -"__inline\n" -"float4 normalize4(const float4 a)\n" -"{\n" -" float length = sqrtf(dot4(a, a));\n" -" return 1.f/length * a;\n" -"}\n" -"__inline\n" -"float4 createEquation(const float4 a, const float4 b, const float4 c)\n" -"{\n" -" float4 eqn;\n" -" float4 ab = b-a;\n" -" float4 ac = c-a;\n" -" eqn = normalize3( cross3(ab, ac) );\n" -" eqn.w = -dot3F4(eqn,a);\n" -" return eqn;\n" -"}\n" -"///////////////////////////////////////\n" -"// Matrix3x3\n" -"///////////////////////////////////////\n" -"typedef struct\n" -"{\n" -" float4 m_row[3];\n" -"}Matrix3x3;\n" -"__inline\n" -"Matrix3x3 mtZero();\n" -"__inline\n" -"Matrix3x3 mtIdentity();\n" -"__inline\n" -"Matrix3x3 mtTranspose(Matrix3x3 m);\n" -"__inline\n" -"Matrix3x3 mtMul(Matrix3x3 a, Matrix3x3 b);\n" -"__inline\n" -"float4 mtMul1(Matrix3x3 a, float4 b);\n" -"__inline\n" -"float4 mtMul3(float4 a, Matrix3x3 b);\n" -"__inline\n" -"Matrix3x3 mtZero()\n" -"{\n" -" Matrix3x3 m;\n" -" m.m_row[0] = (float4)(0.f);\n" -" m.m_row[1] = (float4)(0.f);\n" -" m.m_row[2] = (float4)(0.f);\n" -" return m;\n" -"}\n" -"__inline\n" -"Matrix3x3 mtIdentity()\n" -"{\n" -" Matrix3x3 m;\n" -" m.m_row[0] = (float4)(1,0,0,0);\n" -" m.m_row[1] = (float4)(0,1,0,0);\n" -" m.m_row[2] = (float4)(0,0,1,0);\n" -" return m;\n" -"}\n" -"__inline\n" -"Matrix3x3 mtTranspose(Matrix3x3 m)\n" -"{\n" -" Matrix3x3 out;\n" -" out.m_row[0] = (float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n" -" out.m_row[1] = (float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n" -" out.m_row[2] = (float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n" -" return out;\n" -"}\n" -"__inline\n" -"Matrix3x3 mtMul(Matrix3x3 a, Matrix3x3 b)\n" -"{\n" -" Matrix3x3 transB;\n" -" transB = mtTranspose( b );\n" -" Matrix3x3 ans;\n" -" // why this doesn't run when 0ing in the for{}\n" -" a.m_row[0].w = 0.f;\n" -" a.m_row[1].w = 0.f;\n" -" a.m_row[2].w = 0.f;\n" -" for(int i=0; i<3; i++)\n" -" {\n" -"// a.m_row[i].w = 0.f;\n" -" ans.m_row[i].x = dot3F4(a.m_row[i],transB.m_row[0]);\n" -" ans.m_row[i].y = dot3F4(a.m_row[i],transB.m_row[1]);\n" -" ans.m_row[i].z = dot3F4(a.m_row[i],transB.m_row[2]);\n" -" ans.m_row[i].w = 0.f;\n" -" }\n" -" return ans;\n" -"}\n" -"__inline\n" -"float4 mtMul1(Matrix3x3 a, float4 b)\n" -"{\n" -" float4 ans;\n" -" ans.x = dot3F4( a.m_row[0], b );\n" -" ans.y = dot3F4( a.m_row[1], b );\n" -" ans.z = dot3F4( a.m_row[2], b );\n" -" ans.w = 0.f;\n" -" return ans;\n" -"}\n" -"__inline\n" -"float4 mtMul3(float4 a, Matrix3x3 b)\n" -"{\n" -" float4 colx = make_float4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" -" float4 coly = make_float4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" -" float4 colz = make_float4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" -" float4 ans;\n" -" ans.x = dot3F4( a, colx );\n" -" ans.y = dot3F4( a, coly );\n" -" ans.z = dot3F4( a, colz );\n" -" return ans;\n" -"}\n" -"///////////////////////////////////////\n" -"// Quaternion\n" -"///////////////////////////////////////\n" -"typedef float4 Quaternion;\n" -"__inline\n" -"Quaternion qtMul(Quaternion a, Quaternion b);\n" -"__inline\n" -"Quaternion qtNormalize(Quaternion in);\n" -"__inline\n" -"float4 qtRotate(Quaternion q, float4 vec);\n" -"__inline\n" -"Quaternion qtInvert(Quaternion q);\n" -"__inline\n" -"Quaternion qtMul(Quaternion a, Quaternion b)\n" -"{\n" -" Quaternion ans;\n" -" ans = cross3( a, b );\n" -" ans += a.w*b+b.w*a;\n" -"// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" -" ans.w = a.w*b.w - dot3F4(a, b);\n" -" return ans;\n" -"}\n" -"__inline\n" -"Quaternion qtNormalize(Quaternion in)\n" -"{\n" -" return fastNormalize4(in);\n" -"// in /= length( in );\n" -"// return in;\n" -"}\n" -"__inline\n" -"float4 qtRotate(Quaternion q, float4 vec)\n" -"{\n" -" Quaternion qInv = qtInvert( q );\n" -" float4 vcpy = vec;\n" -" vcpy.w = 0.f;\n" -" float4 out = qtMul(qtMul(q,vcpy),qInv);\n" -" return out;\n" -"}\n" -"__inline\n" -"Quaternion qtInvert(Quaternion q)\n" -"{\n" -" return (Quaternion)(-q.xyz, q.w);\n" -"}\n" -"__inline\n" -"float4 qtInvRotate(const Quaternion q, float4 vec)\n" -"{\n" -" return qtRotate( qtInvert( q ), vec );\n" -"}\n" -"#define WG_SIZE 64\n" -"typedef struct\n" -"{\n" -" float4 m_pos;\n" -" Quaternion m_quat;\n" -" float4 m_linVel;\n" -" float4 m_angVel;\n" -" u32 m_shapeIdx;\n" -" float m_invMass;\n" -" float m_restituitionCoeff;\n" -" float m_frictionCoeff;\n" -"} Body;\n" -"typedef struct\n" -"{\n" -" Matrix3x3 m_invInertia;\n" -" Matrix3x3 m_initInvInertia;\n" -"} Shape;\n" -"typedef struct\n" -"{\n" -" float4 m_linear;\n" -" float4 m_worldPos[4];\n" -" float4 m_center; \n" -" float m_jacCoeffInv[4];\n" -" float m_b[4];\n" -" float m_appliedRambdaDt[4];\n" -" float m_fJacCoeffInv[2]; \n" -" float m_fAppliedRambdaDt[2]; \n" -" u32 m_bodyA;\n" -" u32 m_bodyB;\n" -" int m_batchIdx;\n" -" u32 m_paddings[1];\n" -"} Constraint4;\n" -"typedef struct\n" -"{\n" -" int m_nConstraints;\n" -" int m_start;\n" -" int m_batchIdx;\n" -" int m_nSplit;\n" -"// int m_paddings[1];\n" -"} ConstBuffer;\n" -"typedef struct\n" -"{\n" -" int m_solveFriction;\n" -" int m_maxBatch; // long batch really kills the performance\n" -" int m_batchIdx;\n" -" int m_nSplit;\n" -"// int m_paddings[1];\n" -"} ConstBufferBatchSolve;\n" -" \n" -"typedef struct \n" -"{\n" -" int m_valInt0;\n" -" int m_valInt1;\n" -" int m_valInt2;\n" -" int m_valInt3;\n" -" float m_val0;\n" -" float m_val1;\n" -" float m_val2;\n" -" float m_val3;\n" -"} SolverDebugInfo;\n" -"// others\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" -"void ReorderContactKernel(__global struct b3Contact4Data* in, __global struct b3Contact4Data* out, __global int2* sortData, int4 cb )\n" -"{\n" -" int nContacts = cb.x;\n" -" int gIdx = GET_GLOBAL_IDX;\n" -" if( gIdx < nContacts )\n" -" {\n" -" int srcIdx = sortData[gIdx].y;\n" -" out[gIdx] = in[srcIdx];\n" -" }\n" -"}\n" -"__kernel __attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" -"void SetDeterminismSortDataChildShapeB(__global struct b3Contact4Data* contactsIn, __global int2* sortDataOut, int nContacts)\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX;\n" -" if( gIdx < nContacts )\n" -" {\n" -" int2 sd;\n" -" sd.x = contactsIn[gIdx].m_childIndexB;\n" -" sd.y = gIdx;\n" -" sortDataOut[gIdx] = sd;\n" -" }\n" -"}\n" -"__kernel __attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" -"void SetDeterminismSortDataChildShapeA(__global struct b3Contact4Data* contactsIn, __global int2* sortDataInOut, int nContacts)\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX;\n" -" if( gIdx < nContacts )\n" -" {\n" -" int2 sdIn;\n" -" sdIn = sortDataInOut[gIdx];\n" -" int2 sdOut;\n" -" sdOut.x = contactsIn[sdIn.y].m_childIndexA;\n" -" sdOut.y = sdIn.y;\n" -" sortDataInOut[gIdx] = sdOut;\n" -" }\n" -"}\n" -"__kernel __attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" -"void SetDeterminismSortDataBodyA(__global struct b3Contact4Data* contactsIn, __global int2* sortDataInOut, int nContacts)\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX;\n" -" if( gIdx < nContacts )\n" -" {\n" -" int2 sdIn;\n" -" sdIn = sortDataInOut[gIdx];\n" -" int2 sdOut;\n" -" sdOut.x = contactsIn[sdIn.y].m_bodyAPtrAndSignBit;\n" -" sdOut.y = sdIn.y;\n" -" sortDataInOut[gIdx] = sdOut;\n" -" }\n" -"}\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" -"void SetDeterminismSortDataBodyB(__global struct b3Contact4Data* contactsIn, __global int2* sortDataInOut, int nContacts)\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX;\n" -" if( gIdx < nContacts )\n" -" {\n" -" int2 sdIn;\n" -" sdIn = sortDataInOut[gIdx];\n" -" int2 sdOut;\n" -" sdOut.x = contactsIn[sdIn.y].m_bodyBPtrAndSignBit;\n" -" sdOut.y = sdIn.y;\n" -" sortDataInOut[gIdx] = sdOut;\n" -" }\n" -"}\n" -"typedef struct\n" -"{\n" -" int m_nContacts;\n" -" int m_staticIdx;\n" -" float m_scale;\n" -" int m_nSplit;\n" -"} ConstBufferSSD;\n" -"__constant const int gridTable4x4[] = \n" -"{\n" -" 0,1,17,16,\n" -" 1,2,18,19,\n" -" 17,18,32,3,\n" -" 16,19,3,34\n" -"};\n" -"__constant const int gridTable8x8[] = \n" -"{\n" -" 0, 2, 3, 16, 17, 18, 19, 1,\n" -" 66, 64, 80, 67, 82, 81, 65, 83,\n" -" 131,144,128,130,147,129,145,146,\n" -" 208,195,194,192,193,211,210,209,\n" -" 21, 22, 23, 5, 4, 6, 7, 20,\n" -" 86, 85, 69, 87, 70, 68, 84, 71,\n" -" 151,133,149,150,135,148,132,134,\n" -" 197,27,214,213,212,199,198,196\n" -" \n" -"};\n" -"#define USE_SPATIAL_BATCHING 1\n" -"#define USE_4x4_GRID 1\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" -"void SetSortDataKernel(__global struct b3Contact4Data* gContact, __global Body* gBodies, __global int2* gSortDataOut, \n" -"int nContacts,float scale,int4 nSplit,int staticIdx)\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX;\n" -" \n" -" if( gIdx < nContacts )\n" -" {\n" -" int aPtrAndSignBit = gContact[gIdx].m_bodyAPtrAndSignBit;\n" -" int bPtrAndSignBit = gContact[gIdx].m_bodyBPtrAndSignBit;\n" -" int aIdx = abs(aPtrAndSignBit );\n" -" int bIdx = abs(bPtrAndSignBit);\n" -" bool aStatic = (aPtrAndSignBit<0) ||(aPtrAndSignBit==staticIdx);\n" -" bool bStatic = (bPtrAndSignBit<0) ||(bPtrAndSignBit==staticIdx);\n" -"#if USE_SPATIAL_BATCHING \n" -" int idx = (aStatic)? bIdx: aIdx;\n" -" float4 p = gBodies[idx].m_pos;\n" -" int xIdx = (int)((p.x-((p.x<0.f)?1.f:0.f))*scale) & (nSplit.x-1);\n" -" int yIdx = (int)((p.y-((p.y<0.f)?1.f:0.f))*scale) & (nSplit.y-1);\n" -" int zIdx = (int)((p.z-((p.z<0.f)?1.f:0.f))*scale) & (nSplit.z-1);\n" -" int newIndex = (xIdx+yIdx*nSplit.x+zIdx*nSplit.x*nSplit.y);\n" -" \n" -"#else//USE_SPATIAL_BATCHING\n" -" #if USE_4x4_GRID\n" -" int aa = aIdx&3;\n" -" int bb = bIdx&3;\n" -" if (aStatic)\n" -" aa = bb;\n" -" if (bStatic)\n" -" bb = aa;\n" -" int gridIndex = aa + bb*4;\n" -" int newIndex = gridTable4x4[gridIndex];\n" -" #else//USE_4x4_GRID\n" -" int aa = aIdx&7;\n" -" int bb = bIdx&7;\n" -" if (aStatic)\n" -" aa = bb;\n" -" if (bStatic)\n" -" bb = aa;\n" -" int gridIndex = aa + bb*8;\n" -" int newIndex = gridTable8x8[gridIndex];\n" -" #endif//USE_4x4_GRID\n" -"#endif//USE_SPATIAL_BATCHING\n" -" gSortDataOut[gIdx].x = newIndex;\n" -" gSortDataOut[gIdx].y = gIdx;\n" -" }\n" -" else\n" -" {\n" -" gSortDataOut[gIdx].x = 0xffffffff;\n" -" }\n" -"}\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" -"void CopyConstraintKernel(__global struct b3Contact4Data* gIn, __global struct b3Contact4Data* gOut, int4 cb )\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX;\n" -" if( gIdx < cb.x )\n" -" {\n" -" gOut[gIdx] = gIn[gIdx];\n" -" }\n" -"}\n" -; +static const char* solverSetup2CL = + "/*\n" + "Copyright (c) 2012 Advanced Micro Devices, Inc. \n" + "This software is provided 'as-is', without any express or implied warranty.\n" + "In no event will the authors be held liable for any damages arising from the use of this software.\n" + "Permission is granted to anyone to use this software for any purpose, \n" + "including commercial applications, and to alter it and redistribute it freely, \n" + "subject to the following restrictions:\n" + "1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" + "2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" + "3. This notice may not be removed or altered from any source distribution.\n" + "*/\n" + "//Originally written by Takahiro Harada\n" + "#ifndef B3_CONTACT4DATA_H\n" + "#define B3_CONTACT4DATA_H\n" + "#ifndef B3_FLOAT4_H\n" + "#define B3_FLOAT4_H\n" + "#ifndef B3_PLATFORM_DEFINITIONS_H\n" + "#define B3_PLATFORM_DEFINITIONS_H\n" + "struct MyTest\n" + "{\n" + " int bla;\n" + "};\n" + "#ifdef __cplusplus\n" + "#else\n" + "//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n" + "#define B3_LARGE_FLOAT 1e18f\n" + "#define B3_INFINITY 1e18f\n" + "#define b3Assert(a)\n" + "#define b3ConstArray(a) __global const a*\n" + "#define b3AtomicInc atomic_inc\n" + "#define b3AtomicAdd atomic_add\n" + "#define b3Fabs fabs\n" + "#define b3Sqrt native_sqrt\n" + "#define b3Sin native_sin\n" + "#define b3Cos native_cos\n" + "#define B3_STATIC\n" + "#endif\n" + "#endif\n" + "#ifdef __cplusplus\n" + "#else\n" + " typedef float4 b3Float4;\n" + " #define b3Float4ConstArg const b3Float4\n" + " #define b3MakeFloat4 (float4)\n" + " float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" + " {\n" + " float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" + " float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" + " return dot(a1, b1);\n" + " }\n" + " b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" + " {\n" + " float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" + " float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" + " return cross(a1, b1);\n" + " }\n" + " #define b3MinFloat4 min\n" + " #define b3MaxFloat4 max\n" + " #define b3Normalized(a) normalize(a)\n" + "#endif \n" + " \n" + "inline bool b3IsAlmostZero(b3Float4ConstArg v)\n" + "{\n" + " if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" + " return false;\n" + " return true;\n" + "}\n" + "inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" + "{\n" + " float maxDot = -B3_INFINITY;\n" + " int i = 0;\n" + " int ptIndex = -1;\n" + " for( i = 0; i < vecLen; i++ )\n" + " {\n" + " float dot = b3Dot3F4(vecArray[i],vec);\n" + " \n" + " if( dot > maxDot )\n" + " {\n" + " maxDot = dot;\n" + " ptIndex = i;\n" + " }\n" + " }\n" + " b3Assert(ptIndex>=0);\n" + " if (ptIndex<0)\n" + " {\n" + " ptIndex = 0;\n" + " }\n" + " *dotOut = maxDot;\n" + " return ptIndex;\n" + "}\n" + "#endif //B3_FLOAT4_H\n" + "typedef struct b3Contact4Data b3Contact4Data_t;\n" + "struct b3Contact4Data\n" + "{\n" + " b3Float4 m_worldPosB[4];\n" + "// b3Float4 m_localPosA[4];\n" + "// b3Float4 m_localPosB[4];\n" + " b3Float4 m_worldNormalOnB; // w: m_nPoints\n" + " unsigned short m_restituitionCoeffCmp;\n" + " unsigned short m_frictionCoeffCmp;\n" + " int m_batchIdx;\n" + " int m_bodyAPtrAndSignBit;//x:m_bodyAPtr, y:m_bodyBPtr\n" + " int m_bodyBPtrAndSignBit;\n" + " int m_childIndexA;\n" + " int m_childIndexB;\n" + " int m_unused1;\n" + " int m_unused2;\n" + "};\n" + "inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact)\n" + "{\n" + " return (int)contact->m_worldNormalOnB.w;\n" + "};\n" + "inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints)\n" + "{\n" + " contact->m_worldNormalOnB.w = (float)numPoints;\n" + "};\n" + "#endif //B3_CONTACT4DATA_H\n" + "#pragma OPENCL EXTENSION cl_amd_printf : enable\n" + "#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" + "#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n" + "#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n" + "#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n" + "#ifdef cl_ext_atomic_counters_32\n" + "#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n" + "#else\n" + "#define counter32_t volatile global int*\n" + "#endif\n" + "typedef unsigned int u32;\n" + "typedef unsigned short u16;\n" + "typedef unsigned char u8;\n" + "#define GET_GROUP_IDX get_group_id(0)\n" + "#define GET_LOCAL_IDX get_local_id(0)\n" + "#define GET_GLOBAL_IDX get_global_id(0)\n" + "#define GET_GROUP_SIZE get_local_size(0)\n" + "#define GET_NUM_GROUPS get_num_groups(0)\n" + "#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" + "#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" + "#define AtomInc(x) atom_inc(&(x))\n" + "#define AtomInc1(x, out) out = atom_inc(&(x))\n" + "#define AppendInc(x, out) out = atomic_inc(x)\n" + "#define AtomAdd(x, value) atom_add(&(x), value)\n" + "#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n" + "#define AtomXhg(x, value) atom_xchg ( &(x), value )\n" + "#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n" + "#define make_float4 (float4)\n" + "#define make_float2 (float2)\n" + "#define make_uint4 (uint4)\n" + "#define make_int4 (int4)\n" + "#define make_uint2 (uint2)\n" + "#define make_int2 (int2)\n" + "#define max2 max\n" + "#define min2 min\n" + "///////////////////////////////////////\n" + "// Vector\n" + "///////////////////////////////////////\n" + "__inline\n" + "float fastDiv(float numerator, float denominator)\n" + "{\n" + " return native_divide(numerator, denominator); \n" + "// return numerator/denominator; \n" + "}\n" + "__inline\n" + "float4 fastDiv4(float4 numerator, float4 denominator)\n" + "{\n" + " return native_divide(numerator, denominator); \n" + "}\n" + "__inline\n" + "float fastSqrtf(float f2)\n" + "{\n" + " return native_sqrt(f2);\n" + "// return sqrt(f2);\n" + "}\n" + "__inline\n" + "float fastRSqrt(float f2)\n" + "{\n" + " return native_rsqrt(f2);\n" + "}\n" + "__inline\n" + "float fastLength4(float4 v)\n" + "{\n" + " return fast_length(v);\n" + "}\n" + "__inline\n" + "float4 fastNormalize4(float4 v)\n" + "{\n" + " return fast_normalize(v);\n" + "}\n" + "__inline\n" + "float sqrtf(float a)\n" + "{\n" + "// return sqrt(a);\n" + " return native_sqrt(a);\n" + "}\n" + "__inline\n" + "float4 cross3(float4 a, float4 b)\n" + "{\n" + " return cross(a,b);\n" + "}\n" + "__inline\n" + "float dot3F4(float4 a, float4 b)\n" + "{\n" + " float4 a1 = make_float4(a.xyz,0.f);\n" + " float4 b1 = make_float4(b.xyz,0.f);\n" + " return dot(a1, b1);\n" + "}\n" + "__inline\n" + "float length3(const float4 a)\n" + "{\n" + " return sqrtf(dot3F4(a,a));\n" + "}\n" + "__inline\n" + "float dot4(const float4 a, const float4 b)\n" + "{\n" + " return dot( a, b );\n" + "}\n" + "// for height\n" + "__inline\n" + "float dot3w1(const float4 point, const float4 eqn)\n" + "{\n" + " return dot3F4(point,eqn) + eqn.w;\n" + "}\n" + "__inline\n" + "float4 normalize3(const float4 a)\n" + "{\n" + " float4 n = make_float4(a.x, a.y, a.z, 0.f);\n" + " return fastNormalize4( n );\n" + "// float length = sqrtf(dot3F4(a, a));\n" + "// return 1.f/length * a;\n" + "}\n" + "__inline\n" + "float4 normalize4(const float4 a)\n" + "{\n" + " float length = sqrtf(dot4(a, a));\n" + " return 1.f/length * a;\n" + "}\n" + "__inline\n" + "float4 createEquation(const float4 a, const float4 b, const float4 c)\n" + "{\n" + " float4 eqn;\n" + " float4 ab = b-a;\n" + " float4 ac = c-a;\n" + " eqn = normalize3( cross3(ab, ac) );\n" + " eqn.w = -dot3F4(eqn,a);\n" + " return eqn;\n" + "}\n" + "///////////////////////////////////////\n" + "// Matrix3x3\n" + "///////////////////////////////////////\n" + "typedef struct\n" + "{\n" + " float4 m_row[3];\n" + "}Matrix3x3;\n" + "__inline\n" + "Matrix3x3 mtZero();\n" + "__inline\n" + "Matrix3x3 mtIdentity();\n" + "__inline\n" + "Matrix3x3 mtTranspose(Matrix3x3 m);\n" + "__inline\n" + "Matrix3x3 mtMul(Matrix3x3 a, Matrix3x3 b);\n" + "__inline\n" + "float4 mtMul1(Matrix3x3 a, float4 b);\n" + "__inline\n" + "float4 mtMul3(float4 a, Matrix3x3 b);\n" + "__inline\n" + "Matrix3x3 mtZero()\n" + "{\n" + " Matrix3x3 m;\n" + " m.m_row[0] = (float4)(0.f);\n" + " m.m_row[1] = (float4)(0.f);\n" + " m.m_row[2] = (float4)(0.f);\n" + " return m;\n" + "}\n" + "__inline\n" + "Matrix3x3 mtIdentity()\n" + "{\n" + " Matrix3x3 m;\n" + " m.m_row[0] = (float4)(1,0,0,0);\n" + " m.m_row[1] = (float4)(0,1,0,0);\n" + " m.m_row[2] = (float4)(0,0,1,0);\n" + " return m;\n" + "}\n" + "__inline\n" + "Matrix3x3 mtTranspose(Matrix3x3 m)\n" + "{\n" + " Matrix3x3 out;\n" + " out.m_row[0] = (float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n" + " out.m_row[1] = (float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n" + " out.m_row[2] = (float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n" + " return out;\n" + "}\n" + "__inline\n" + "Matrix3x3 mtMul(Matrix3x3 a, Matrix3x3 b)\n" + "{\n" + " Matrix3x3 transB;\n" + " transB = mtTranspose( b );\n" + " Matrix3x3 ans;\n" + " // why this doesn't run when 0ing in the for{}\n" + " a.m_row[0].w = 0.f;\n" + " a.m_row[1].w = 0.f;\n" + " a.m_row[2].w = 0.f;\n" + " for(int i=0; i<3; i++)\n" + " {\n" + "// a.m_row[i].w = 0.f;\n" + " ans.m_row[i].x = dot3F4(a.m_row[i],transB.m_row[0]);\n" + " ans.m_row[i].y = dot3F4(a.m_row[i],transB.m_row[1]);\n" + " ans.m_row[i].z = dot3F4(a.m_row[i],transB.m_row[2]);\n" + " ans.m_row[i].w = 0.f;\n" + " }\n" + " return ans;\n" + "}\n" + "__inline\n" + "float4 mtMul1(Matrix3x3 a, float4 b)\n" + "{\n" + " float4 ans;\n" + " ans.x = dot3F4( a.m_row[0], b );\n" + " ans.y = dot3F4( a.m_row[1], b );\n" + " ans.z = dot3F4( a.m_row[2], b );\n" + " ans.w = 0.f;\n" + " return ans;\n" + "}\n" + "__inline\n" + "float4 mtMul3(float4 a, Matrix3x3 b)\n" + "{\n" + " float4 colx = make_float4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" + " float4 coly = make_float4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" + " float4 colz = make_float4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" + " float4 ans;\n" + " ans.x = dot3F4( a, colx );\n" + " ans.y = dot3F4( a, coly );\n" + " ans.z = dot3F4( a, colz );\n" + " return ans;\n" + "}\n" + "///////////////////////////////////////\n" + "// Quaternion\n" + "///////////////////////////////////////\n" + "typedef float4 Quaternion;\n" + "__inline\n" + "Quaternion qtMul(Quaternion a, Quaternion b);\n" + "__inline\n" + "Quaternion qtNormalize(Quaternion in);\n" + "__inline\n" + "float4 qtRotate(Quaternion q, float4 vec);\n" + "__inline\n" + "Quaternion qtInvert(Quaternion q);\n" + "__inline\n" + "Quaternion qtMul(Quaternion a, Quaternion b)\n" + "{\n" + " Quaternion ans;\n" + " ans = cross3( a, b );\n" + " ans += a.w*b+b.w*a;\n" + "// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" + " ans.w = a.w*b.w - dot3F4(a, b);\n" + " return ans;\n" + "}\n" + "__inline\n" + "Quaternion qtNormalize(Quaternion in)\n" + "{\n" + " return fastNormalize4(in);\n" + "// in /= length( in );\n" + "// return in;\n" + "}\n" + "__inline\n" + "float4 qtRotate(Quaternion q, float4 vec)\n" + "{\n" + " Quaternion qInv = qtInvert( q );\n" + " float4 vcpy = vec;\n" + " vcpy.w = 0.f;\n" + " float4 out = qtMul(qtMul(q,vcpy),qInv);\n" + " return out;\n" + "}\n" + "__inline\n" + "Quaternion qtInvert(Quaternion q)\n" + "{\n" + " return (Quaternion)(-q.xyz, q.w);\n" + "}\n" + "__inline\n" + "float4 qtInvRotate(const Quaternion q, float4 vec)\n" + "{\n" + " return qtRotate( qtInvert( q ), vec );\n" + "}\n" + "#define WG_SIZE 64\n" + "typedef struct\n" + "{\n" + " float4 m_pos;\n" + " Quaternion m_quat;\n" + " float4 m_linVel;\n" + " float4 m_angVel;\n" + " u32 m_shapeIdx;\n" + " float m_invMass;\n" + " float m_restituitionCoeff;\n" + " float m_frictionCoeff;\n" + "} Body;\n" + "typedef struct\n" + "{\n" + " Matrix3x3 m_invInertia;\n" + " Matrix3x3 m_initInvInertia;\n" + "} Shape;\n" + "typedef struct\n" + "{\n" + " float4 m_linear;\n" + " float4 m_worldPos[4];\n" + " float4 m_center; \n" + " float m_jacCoeffInv[4];\n" + " float m_b[4];\n" + " float m_appliedRambdaDt[4];\n" + " float m_fJacCoeffInv[2]; \n" + " float m_fAppliedRambdaDt[2]; \n" + " u32 m_bodyA;\n" + " u32 m_bodyB;\n" + " int m_batchIdx;\n" + " u32 m_paddings[1];\n" + "} Constraint4;\n" + "typedef struct\n" + "{\n" + " int m_nConstraints;\n" + " int m_start;\n" + " int m_batchIdx;\n" + " int m_nSplit;\n" + "// int m_paddings[1];\n" + "} ConstBuffer;\n" + "typedef struct\n" + "{\n" + " int m_solveFriction;\n" + " int m_maxBatch; // long batch really kills the performance\n" + " int m_batchIdx;\n" + " int m_nSplit;\n" + "// int m_paddings[1];\n" + "} ConstBufferBatchSolve;\n" + " \n" + "typedef struct \n" + "{\n" + " int m_valInt0;\n" + " int m_valInt1;\n" + " int m_valInt2;\n" + " int m_valInt3;\n" + " float m_val0;\n" + " float m_val1;\n" + " float m_val2;\n" + " float m_val3;\n" + "} SolverDebugInfo;\n" + "// others\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" + "void ReorderContactKernel(__global struct b3Contact4Data* in, __global struct b3Contact4Data* out, __global int2* sortData, int4 cb )\n" + "{\n" + " int nContacts = cb.x;\n" + " int gIdx = GET_GLOBAL_IDX;\n" + " if( gIdx < nContacts )\n" + " {\n" + " int srcIdx = sortData[gIdx].y;\n" + " out[gIdx] = in[srcIdx];\n" + " }\n" + "}\n" + "__kernel __attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" + "void SetDeterminismSortDataChildShapeB(__global struct b3Contact4Data* contactsIn, __global int2* sortDataOut, int nContacts)\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX;\n" + " if( gIdx < nContacts )\n" + " {\n" + " int2 sd;\n" + " sd.x = contactsIn[gIdx].m_childIndexB;\n" + " sd.y = gIdx;\n" + " sortDataOut[gIdx] = sd;\n" + " }\n" + "}\n" + "__kernel __attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" + "void SetDeterminismSortDataChildShapeA(__global struct b3Contact4Data* contactsIn, __global int2* sortDataInOut, int nContacts)\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX;\n" + " if( gIdx < nContacts )\n" + " {\n" + " int2 sdIn;\n" + " sdIn = sortDataInOut[gIdx];\n" + " int2 sdOut;\n" + " sdOut.x = contactsIn[sdIn.y].m_childIndexA;\n" + " sdOut.y = sdIn.y;\n" + " sortDataInOut[gIdx] = sdOut;\n" + " }\n" + "}\n" + "__kernel __attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" + "void SetDeterminismSortDataBodyA(__global struct b3Contact4Data* contactsIn, __global int2* sortDataInOut, int nContacts)\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX;\n" + " if( gIdx < nContacts )\n" + " {\n" + " int2 sdIn;\n" + " sdIn = sortDataInOut[gIdx];\n" + " int2 sdOut;\n" + " sdOut.x = contactsIn[sdIn.y].m_bodyAPtrAndSignBit;\n" + " sdOut.y = sdIn.y;\n" + " sortDataInOut[gIdx] = sdOut;\n" + " }\n" + "}\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" + "void SetDeterminismSortDataBodyB(__global struct b3Contact4Data* contactsIn, __global int2* sortDataInOut, int nContacts)\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX;\n" + " if( gIdx < nContacts )\n" + " {\n" + " int2 sdIn;\n" + " sdIn = sortDataInOut[gIdx];\n" + " int2 sdOut;\n" + " sdOut.x = contactsIn[sdIn.y].m_bodyBPtrAndSignBit;\n" + " sdOut.y = sdIn.y;\n" + " sortDataInOut[gIdx] = sdOut;\n" + " }\n" + "}\n" + "typedef struct\n" + "{\n" + " int m_nContacts;\n" + " int m_staticIdx;\n" + " float m_scale;\n" + " int m_nSplit;\n" + "} ConstBufferSSD;\n" + "__constant const int gridTable4x4[] = \n" + "{\n" + " 0,1,17,16,\n" + " 1,2,18,19,\n" + " 17,18,32,3,\n" + " 16,19,3,34\n" + "};\n" + "__constant const int gridTable8x8[] = \n" + "{\n" + " 0, 2, 3, 16, 17, 18, 19, 1,\n" + " 66, 64, 80, 67, 82, 81, 65, 83,\n" + " 131,144,128,130,147,129,145,146,\n" + " 208,195,194,192,193,211,210,209,\n" + " 21, 22, 23, 5, 4, 6, 7, 20,\n" + " 86, 85, 69, 87, 70, 68, 84, 71,\n" + " 151,133,149,150,135,148,132,134,\n" + " 197,27,214,213,212,199,198,196\n" + " \n" + "};\n" + "#define USE_SPATIAL_BATCHING 1\n" + "#define USE_4x4_GRID 1\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" + "void SetSortDataKernel(__global struct b3Contact4Data* gContact, __global Body* gBodies, __global int2* gSortDataOut, \n" + "int nContacts,float scale,int4 nSplit,int staticIdx)\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX;\n" + " \n" + " if( gIdx < nContacts )\n" + " {\n" + " int aPtrAndSignBit = gContact[gIdx].m_bodyAPtrAndSignBit;\n" + " int bPtrAndSignBit = gContact[gIdx].m_bodyBPtrAndSignBit;\n" + " int aIdx = abs(aPtrAndSignBit );\n" + " int bIdx = abs(bPtrAndSignBit);\n" + " bool aStatic = (aPtrAndSignBit<0) ||(aPtrAndSignBit==staticIdx);\n" + " bool bStatic = (bPtrAndSignBit<0) ||(bPtrAndSignBit==staticIdx);\n" + "#if USE_SPATIAL_BATCHING \n" + " int idx = (aStatic)? bIdx: aIdx;\n" + " float4 p = gBodies[idx].m_pos;\n" + " int xIdx = (int)((p.x-((p.x<0.f)?1.f:0.f))*scale) & (nSplit.x-1);\n" + " int yIdx = (int)((p.y-((p.y<0.f)?1.f:0.f))*scale) & (nSplit.y-1);\n" + " int zIdx = (int)((p.z-((p.z<0.f)?1.f:0.f))*scale) & (nSplit.z-1);\n" + " int newIndex = (xIdx+yIdx*nSplit.x+zIdx*nSplit.x*nSplit.y);\n" + " \n" + "#else//USE_SPATIAL_BATCHING\n" + " #if USE_4x4_GRID\n" + " int aa = aIdx&3;\n" + " int bb = bIdx&3;\n" + " if (aStatic)\n" + " aa = bb;\n" + " if (bStatic)\n" + " bb = aa;\n" + " int gridIndex = aa + bb*4;\n" + " int newIndex = gridTable4x4[gridIndex];\n" + " #else//USE_4x4_GRID\n" + " int aa = aIdx&7;\n" + " int bb = bIdx&7;\n" + " if (aStatic)\n" + " aa = bb;\n" + " if (bStatic)\n" + " bb = aa;\n" + " int gridIndex = aa + bb*8;\n" + " int newIndex = gridTable8x8[gridIndex];\n" + " #endif//USE_4x4_GRID\n" + "#endif//USE_SPATIAL_BATCHING\n" + " gSortDataOut[gIdx].x = newIndex;\n" + " gSortDataOut[gIdx].y = gIdx;\n" + " }\n" + " else\n" + " {\n" + " gSortDataOut[gIdx].x = 0xffffffff;\n" + " }\n" + "}\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" + "void CopyConstraintKernel(__global struct b3Contact4Data* gIn, __global struct b3Contact4Data* gOut, int4 cb )\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX;\n" + " if( gIdx < cb.x )\n" + " {\n" + " gOut[gIdx] = gIn[gIdx];\n" + " }\n" + "}\n"; diff --git a/src/Bullet3OpenCL/RigidBody/kernels/solverUtils.h b/src/Bullet3OpenCL/RigidBody/kernels/solverUtils.h index c0173ad9f..f4d98d994 100644 --- a/src/Bullet3OpenCL/RigidBody/kernels/solverUtils.h +++ b/src/Bullet3OpenCL/RigidBody/kernels/solverUtils.h @@ -1,909 +1,908 @@ //this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project -static const char* solverUtilsCL= \ -"/*\n" -"Copyright (c) 2013 Advanced Micro Devices, Inc. \n" -"This software is provided 'as-is', without any express or implied warranty.\n" -"In no event will the authors be held liable for any damages arising from the use of this software.\n" -"Permission is granted to anyone to use this software for any purpose, \n" -"including commercial applications, and to alter it and redistribute it freely, \n" -"subject to the following restrictions:\n" -"1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" -"2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" -"3. This notice may not be removed or altered from any source distribution.\n" -"*/\n" -"//Originally written by Erwin Coumans\n" -"#ifndef B3_CONTACT4DATA_H\n" -"#define B3_CONTACT4DATA_H\n" -"#ifndef B3_FLOAT4_H\n" -"#define B3_FLOAT4_H\n" -"#ifndef B3_PLATFORM_DEFINITIONS_H\n" -"#define B3_PLATFORM_DEFINITIONS_H\n" -"struct MyTest\n" -"{\n" -" int bla;\n" -"};\n" -"#ifdef __cplusplus\n" -"#else\n" -"//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n" -"#define B3_LARGE_FLOAT 1e18f\n" -"#define B3_INFINITY 1e18f\n" -"#define b3Assert(a)\n" -"#define b3ConstArray(a) __global const a*\n" -"#define b3AtomicInc atomic_inc\n" -"#define b3AtomicAdd atomic_add\n" -"#define b3Fabs fabs\n" -"#define b3Sqrt native_sqrt\n" -"#define b3Sin native_sin\n" -"#define b3Cos native_cos\n" -"#define B3_STATIC\n" -"#endif\n" -"#endif\n" -"#ifdef __cplusplus\n" -"#else\n" -" typedef float4 b3Float4;\n" -" #define b3Float4ConstArg const b3Float4\n" -" #define b3MakeFloat4 (float4)\n" -" float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" -" {\n" -" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" -" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" -" return dot(a1, b1);\n" -" }\n" -" b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" -" {\n" -" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" -" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" -" return cross(a1, b1);\n" -" }\n" -" #define b3MinFloat4 min\n" -" #define b3MaxFloat4 max\n" -" #define b3Normalized(a) normalize(a)\n" -"#endif \n" -" \n" -"inline bool b3IsAlmostZero(b3Float4ConstArg v)\n" -"{\n" -" if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" -" return false;\n" -" return true;\n" -"}\n" -"inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" -"{\n" -" float maxDot = -B3_INFINITY;\n" -" int i = 0;\n" -" int ptIndex = -1;\n" -" for( i = 0; i < vecLen; i++ )\n" -" {\n" -" float dot = b3Dot3F4(vecArray[i],vec);\n" -" \n" -" if( dot > maxDot )\n" -" {\n" -" maxDot = dot;\n" -" ptIndex = i;\n" -" }\n" -" }\n" -" b3Assert(ptIndex>=0);\n" -" if (ptIndex<0)\n" -" {\n" -" ptIndex = 0;\n" -" }\n" -" *dotOut = maxDot;\n" -" return ptIndex;\n" -"}\n" -"#endif //B3_FLOAT4_H\n" -"typedef struct b3Contact4Data b3Contact4Data_t;\n" -"struct b3Contact4Data\n" -"{\n" -" b3Float4 m_worldPosB[4];\n" -"// b3Float4 m_localPosA[4];\n" -"// b3Float4 m_localPosB[4];\n" -" b3Float4 m_worldNormalOnB; // w: m_nPoints\n" -" unsigned short m_restituitionCoeffCmp;\n" -" unsigned short m_frictionCoeffCmp;\n" -" int m_batchIdx;\n" -" int m_bodyAPtrAndSignBit;//x:m_bodyAPtr, y:m_bodyBPtr\n" -" int m_bodyBPtrAndSignBit;\n" -" int m_childIndexA;\n" -" int m_childIndexB;\n" -" int m_unused1;\n" -" int m_unused2;\n" -"};\n" -"inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact)\n" -"{\n" -" return (int)contact->m_worldNormalOnB.w;\n" -"};\n" -"inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints)\n" -"{\n" -" contact->m_worldNormalOnB.w = (float)numPoints;\n" -"};\n" -"#endif //B3_CONTACT4DATA_H\n" -"#pragma OPENCL EXTENSION cl_amd_printf : enable\n" -"#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n" -"#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n" -"#ifdef cl_ext_atomic_counters_32\n" -"#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n" -"#else\n" -"#define counter32_t volatile global int*\n" -"#endif\n" -"typedef unsigned int u32;\n" -"typedef unsigned short u16;\n" -"typedef unsigned char u8;\n" -"#define GET_GROUP_IDX get_group_id(0)\n" -"#define GET_LOCAL_IDX get_local_id(0)\n" -"#define GET_GLOBAL_IDX get_global_id(0)\n" -"#define GET_GROUP_SIZE get_local_size(0)\n" -"#define GET_NUM_GROUPS get_num_groups(0)\n" -"#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" -"#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" -"#define AtomInc(x) atom_inc(&(x))\n" -"#define AtomInc1(x, out) out = atom_inc(&(x))\n" -"#define AppendInc(x, out) out = atomic_inc(x)\n" -"#define AtomAdd(x, value) atom_add(&(x), value)\n" -"#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n" -"#define AtomXhg(x, value) atom_xchg ( &(x), value )\n" -"#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n" -"#define make_float4 (float4)\n" -"#define make_float2 (float2)\n" -"#define make_uint4 (uint4)\n" -"#define make_int4 (int4)\n" -"#define make_uint2 (uint2)\n" -"#define make_int2 (int2)\n" -"#define max2 max\n" -"#define min2 min\n" -"///////////////////////////////////////\n" -"// Vector\n" -"///////////////////////////////////////\n" -"__inline\n" -"float fastDiv(float numerator, float denominator)\n" -"{\n" -" return native_divide(numerator, denominator); \n" -"// return numerator/denominator; \n" -"}\n" -"__inline\n" -"float4 fastDiv4(float4 numerator, float4 denominator)\n" -"{\n" -" return native_divide(numerator, denominator); \n" -"}\n" -"__inline\n" -"float fastSqrtf(float f2)\n" -"{\n" -" return native_sqrt(f2);\n" -"// return sqrt(f2);\n" -"}\n" -"__inline\n" -"float fastRSqrt(float f2)\n" -"{\n" -" return native_rsqrt(f2);\n" -"}\n" -"__inline\n" -"float fastLength4(float4 v)\n" -"{\n" -" return fast_length(v);\n" -"}\n" -"__inline\n" -"float4 fastNormalize4(float4 v)\n" -"{\n" -" return fast_normalize(v);\n" -"}\n" -"__inline\n" -"float sqrtf(float a)\n" -"{\n" -"// return sqrt(a);\n" -" return native_sqrt(a);\n" -"}\n" -"__inline\n" -"float4 cross3(float4 a1, float4 b1)\n" -"{\n" -" float4 a=make_float4(a1.xyz,0.f);\n" -" float4 b=make_float4(b1.xyz,0.f);\n" -" //float4 a=a1;\n" -" //float4 b=b1;\n" -" return cross(a,b);\n" -"}\n" -"__inline\n" -"float dot3F4(float4 a, float4 b)\n" -"{\n" -" float4 a1 = make_float4(a.xyz,0.f);\n" -" float4 b1 = make_float4(b.xyz,0.f);\n" -" return dot(a1, b1);\n" -"}\n" -"__inline\n" -"float length3(const float4 a)\n" -"{\n" -" return sqrtf(dot3F4(a,a));\n" -"}\n" -"__inline\n" -"float dot4(const float4 a, const float4 b)\n" -"{\n" -" return dot( a, b );\n" -"}\n" -"// for height\n" -"__inline\n" -"float dot3w1(const float4 point, const float4 eqn)\n" -"{\n" -" return dot3F4(point,eqn) + eqn.w;\n" -"}\n" -"__inline\n" -"float4 normalize3(const float4 a)\n" -"{\n" -" float4 n = make_float4(a.x, a.y, a.z, 0.f);\n" -" return fastNormalize4( n );\n" -"// float length = sqrtf(dot3F4(a, a));\n" -"// return 1.f/length * a;\n" -"}\n" -"__inline\n" -"float4 normalize4(const float4 a)\n" -"{\n" -" float length = sqrtf(dot4(a, a));\n" -" return 1.f/length * a;\n" -"}\n" -"__inline\n" -"float4 createEquation(const float4 a, const float4 b, const float4 c)\n" -"{\n" -" float4 eqn;\n" -" float4 ab = b-a;\n" -" float4 ac = c-a;\n" -" eqn = normalize3( cross3(ab, ac) );\n" -" eqn.w = -dot3F4(eqn,a);\n" -" return eqn;\n" -"}\n" -"///////////////////////////////////////\n" -"// Matrix3x3\n" -"///////////////////////////////////////\n" -"typedef struct\n" -"{\n" -" float4 m_row[3];\n" -"}Matrix3x3;\n" -"__inline\n" -"Matrix3x3 mtZero();\n" -"__inline\n" -"Matrix3x3 mtIdentity();\n" -"__inline\n" -"Matrix3x3 mtTranspose(Matrix3x3 m);\n" -"__inline\n" -"Matrix3x3 mtMul(Matrix3x3 a, Matrix3x3 b);\n" -"__inline\n" -"float4 mtMul1(Matrix3x3 a, float4 b);\n" -"__inline\n" -"float4 mtMul3(float4 a, Matrix3x3 b);\n" -"__inline\n" -"Matrix3x3 mtZero()\n" -"{\n" -" Matrix3x3 m;\n" -" m.m_row[0] = (float4)(0.f);\n" -" m.m_row[1] = (float4)(0.f);\n" -" m.m_row[2] = (float4)(0.f);\n" -" return m;\n" -"}\n" -"__inline\n" -"Matrix3x3 mtIdentity()\n" -"{\n" -" Matrix3x3 m;\n" -" m.m_row[0] = (float4)(1,0,0,0);\n" -" m.m_row[1] = (float4)(0,1,0,0);\n" -" m.m_row[2] = (float4)(0,0,1,0);\n" -" return m;\n" -"}\n" -"__inline\n" -"Matrix3x3 mtTranspose(Matrix3x3 m)\n" -"{\n" -" Matrix3x3 out;\n" -" out.m_row[0] = (float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n" -" out.m_row[1] = (float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n" -" out.m_row[2] = (float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n" -" return out;\n" -"}\n" -"__inline\n" -"Matrix3x3 mtMul(Matrix3x3 a, Matrix3x3 b)\n" -"{\n" -" Matrix3x3 transB;\n" -" transB = mtTranspose( b );\n" -" Matrix3x3 ans;\n" -" // why this doesn't run when 0ing in the for{}\n" -" a.m_row[0].w = 0.f;\n" -" a.m_row[1].w = 0.f;\n" -" a.m_row[2].w = 0.f;\n" -" for(int i=0; i<3; i++)\n" -" {\n" -"// a.m_row[i].w = 0.f;\n" -" ans.m_row[i].x = dot3F4(a.m_row[i],transB.m_row[0]);\n" -" ans.m_row[i].y = dot3F4(a.m_row[i],transB.m_row[1]);\n" -" ans.m_row[i].z = dot3F4(a.m_row[i],transB.m_row[2]);\n" -" ans.m_row[i].w = 0.f;\n" -" }\n" -" return ans;\n" -"}\n" -"__inline\n" -"float4 mtMul1(Matrix3x3 a, float4 b)\n" -"{\n" -" float4 ans;\n" -" ans.x = dot3F4( a.m_row[0], b );\n" -" ans.y = dot3F4( a.m_row[1], b );\n" -" ans.z = dot3F4( a.m_row[2], b );\n" -" ans.w = 0.f;\n" -" return ans;\n" -"}\n" -"__inline\n" -"float4 mtMul3(float4 a, Matrix3x3 b)\n" -"{\n" -" float4 colx = make_float4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" -" float4 coly = make_float4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" -" float4 colz = make_float4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" -" float4 ans;\n" -" ans.x = dot3F4( a, colx );\n" -" ans.y = dot3F4( a, coly );\n" -" ans.z = dot3F4( a, colz );\n" -" return ans;\n" -"}\n" -"///////////////////////////////////////\n" -"// Quaternion\n" -"///////////////////////////////////////\n" -"typedef float4 Quaternion;\n" -"__inline\n" -"Quaternion qtMul(Quaternion a, Quaternion b);\n" -"__inline\n" -"Quaternion qtNormalize(Quaternion in);\n" -"__inline\n" -"float4 qtRotate(Quaternion q, float4 vec);\n" -"__inline\n" -"Quaternion qtInvert(Quaternion q);\n" -"__inline\n" -"Quaternion qtMul(Quaternion a, Quaternion b)\n" -"{\n" -" Quaternion ans;\n" -" ans = cross3( a, b );\n" -" ans += a.w*b+b.w*a;\n" -"// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" -" ans.w = a.w*b.w - dot3F4(a, b);\n" -" return ans;\n" -"}\n" -"__inline\n" -"Quaternion qtNormalize(Quaternion in)\n" -"{\n" -" return fastNormalize4(in);\n" -"// in /= length( in );\n" -"// return in;\n" -"}\n" -"__inline\n" -"float4 qtRotate(Quaternion q, float4 vec)\n" -"{\n" -" Quaternion qInv = qtInvert( q );\n" -" float4 vcpy = vec;\n" -" vcpy.w = 0.f;\n" -" float4 out = qtMul(qtMul(q,vcpy),qInv);\n" -" return out;\n" -"}\n" -"__inline\n" -"Quaternion qtInvert(Quaternion q)\n" -"{\n" -" return (Quaternion)(-q.xyz, q.w);\n" -"}\n" -"__inline\n" -"float4 qtInvRotate(const Quaternion q, float4 vec)\n" -"{\n" -" return qtRotate( qtInvert( q ), vec );\n" -"}\n" -"#define WG_SIZE 64\n" -"typedef struct\n" -"{\n" -" float4 m_pos;\n" -" Quaternion m_quat;\n" -" float4 m_linVel;\n" -" float4 m_angVel;\n" -" u32 m_shapeIdx;\n" -" float m_invMass;\n" -" float m_restituitionCoeff;\n" -" float m_frictionCoeff;\n" -"} Body;\n" -"typedef struct\n" -"{\n" -" Matrix3x3 m_invInertia;\n" -" Matrix3x3 m_initInvInertia;\n" -"} Shape;\n" -"typedef struct\n" -"{\n" -" float4 m_linear;\n" -" float4 m_worldPos[4];\n" -" float4 m_center; \n" -" float m_jacCoeffInv[4];\n" -" float m_b[4];\n" -" float m_appliedRambdaDt[4];\n" -" float m_fJacCoeffInv[2]; \n" -" float m_fAppliedRambdaDt[2]; \n" -" u32 m_bodyA;\n" -" u32 m_bodyB;\n" -" int m_batchIdx;\n" -" u32 m_paddings;\n" -"} Constraint4;\n" -"__kernel void CountBodiesKernel(__global struct b3Contact4Data* manifoldPtr, __global unsigned int* bodyCount, __global int2* contactConstraintOffsets, int numContactManifolds, int fixedBodyIndex)\n" -"{\n" -" int i = GET_GLOBAL_IDX;\n" -" \n" -" if( i < numContactManifolds)\n" -" {\n" -" int pa = manifoldPtr[i].m_bodyAPtrAndSignBit;\n" -" bool isFixedA = (pa <0) || (pa == fixedBodyIndex);\n" -" int bodyIndexA = abs(pa);\n" -" if (!isFixedA)\n" -" {\n" -" AtomInc1(bodyCount[bodyIndexA],contactConstraintOffsets[i].x);\n" -" }\n" -" barrier(CLK_GLOBAL_MEM_FENCE);\n" -" int pb = manifoldPtr[i].m_bodyBPtrAndSignBit;\n" -" bool isFixedB = (pb <0) || (pb == fixedBodyIndex);\n" -" int bodyIndexB = abs(pb);\n" -" if (!isFixedB)\n" -" {\n" -" AtomInc1(bodyCount[bodyIndexB],contactConstraintOffsets[i].y);\n" -" } \n" -" }\n" -"}\n" -"__kernel void ClearVelocitiesKernel(__global float4* linearVelocities,__global float4* angularVelocities, int numSplitBodies)\n" -"{\n" -" int i = GET_GLOBAL_IDX;\n" -" \n" -" if( i < numSplitBodies)\n" -" {\n" -" linearVelocities[i] = make_float4(0);\n" -" angularVelocities[i] = make_float4(0);\n" -" }\n" -"}\n" -"__kernel void AverageVelocitiesKernel(__global Body* gBodies,__global int* offsetSplitBodies,__global const unsigned int* bodyCount,\n" -"__global float4* deltaLinearVelocities, __global float4* deltaAngularVelocities, int numBodies)\n" -"{\n" -" int i = GET_GLOBAL_IDX;\n" -" if (i 0.70710678f) {\n" -" // choose p in y-z plane\n" -" float a = n.y*n.y + n.z*n.z;\n" -" float k = 1.f/sqrt(a);\n" -" p[0].x = 0;\n" -" p[0].y = -n.z*k;\n" -" p[0].z = n.y*k;\n" -" // set q = n x p\n" -" q[0].x = a*k;\n" -" q[0].y = -n.x*p[0].z;\n" -" q[0].z = n.x*p[0].y;\n" -" }\n" -" else {\n" -" // choose p in x-y plane\n" -" float a = n.x*n.x + n.y*n.y;\n" -" float k = 1.f/sqrt(a);\n" -" p[0].x = -n.y*k;\n" -" p[0].y = n.x*k;\n" -" p[0].z = 0;\n" -" // set q = n x p\n" -" q[0].x = -n.z*p[0].y;\n" -" q[0].y = n.z*p[0].x;\n" -" q[0].z = a*k;\n" -" }\n" -"}\n" -"void solveContact(__global Constraint4* cs,\n" -" float4 posA, float4* linVelA, float4* angVelA, float invMassA, Matrix3x3 invInertiaA,\n" -" float4 posB, float4* linVelB, float4* angVelB, float invMassB, Matrix3x3 invInertiaB,\n" -" float4* dLinVelA, float4* dAngVelA, float4* dLinVelB, float4* dAngVelB)\n" -"{\n" -" float minRambdaDt = 0;\n" -" float maxRambdaDt = FLT_MAX;\n" -" for(int ic=0; ic<4; ic++)\n" -" {\n" -" if( cs->m_jacCoeffInv[ic] == 0.f ) continue;\n" -" float4 angular0, angular1, linear;\n" -" float4 r0 = cs->m_worldPos[ic] - posA;\n" -" float4 r1 = cs->m_worldPos[ic] - posB;\n" -" setLinearAndAngular( cs->m_linear, r0, r1, &linear, &angular0, &angular1 );\n" -" \n" -" float rambdaDt = calcRelVel( cs->m_linear, -cs->m_linear, angular0, angular1, \n" -" *linVelA+*dLinVelA, *angVelA+*dAngVelA, *linVelB+*dLinVelB, *angVelB+*dAngVelB ) + cs->m_b[ic];\n" -" rambdaDt *= cs->m_jacCoeffInv[ic];\n" -" \n" -" {\n" -" float prevSum = cs->m_appliedRambdaDt[ic];\n" -" float updated = prevSum;\n" -" updated += rambdaDt;\n" -" updated = max2( updated, minRambdaDt );\n" -" updated = min2( updated, maxRambdaDt );\n" -" rambdaDt = updated - prevSum;\n" -" cs->m_appliedRambdaDt[ic] = updated;\n" -" }\n" -" \n" -" float4 linImp0 = invMassA*linear*rambdaDt;\n" -" float4 linImp1 = invMassB*(-linear)*rambdaDt;\n" -" float4 angImp0 = mtMul1(invInertiaA, angular0)*rambdaDt;\n" -" float4 angImp1 = mtMul1(invInertiaB, angular1)*rambdaDt;\n" -" \n" -" if (invMassA)\n" -" {\n" -" *dLinVelA += linImp0;\n" -" *dAngVelA += angImp0;\n" -" }\n" -" if (invMassB)\n" -" {\n" -" *dLinVelB += linImp1;\n" -" *dAngVelB += angImp1;\n" -" }\n" -" }\n" -"}\n" -"// solveContactConstraint( gBodies, gShapes, &gConstraints[i] ,contactConstraintOffsets,offsetSplitBodies, deltaLinearVelocities, deltaAngularVelocities);\n" -"void solveContactConstraint(__global Body* gBodies, __global Shape* gShapes, __global Constraint4* ldsCs, \n" -"__global int2* contactConstraintOffsets,__global unsigned int* offsetSplitBodies,\n" -"__global float4* deltaLinearVelocities, __global float4* deltaAngularVelocities)\n" -"{\n" -" //float frictionCoeff = ldsCs[0].m_linear.w;\n" -" int aIdx = ldsCs[0].m_bodyA;\n" -" int bIdx = ldsCs[0].m_bodyB;\n" -" float4 posA = gBodies[aIdx].m_pos;\n" -" float4 linVelA = gBodies[aIdx].m_linVel;\n" -" float4 angVelA = gBodies[aIdx].m_angVel;\n" -" float invMassA = gBodies[aIdx].m_invMass;\n" -" Matrix3x3 invInertiaA = gShapes[aIdx].m_invInertia;\n" -" float4 posB = gBodies[bIdx].m_pos;\n" -" float4 linVelB = gBodies[bIdx].m_linVel;\n" -" float4 angVelB = gBodies[bIdx].m_angVel;\n" -" float invMassB = gBodies[bIdx].m_invMass;\n" -" Matrix3x3 invInertiaB = gShapes[bIdx].m_invInertia;\n" -" \n" -" float4 dLinVelA = make_float4(0,0,0,0);\n" -" float4 dAngVelA = make_float4(0,0,0,0);\n" -" float4 dLinVelB = make_float4(0,0,0,0);\n" -" float4 dAngVelB = make_float4(0,0,0,0);\n" -" \n" -" int bodyOffsetA = offsetSplitBodies[aIdx];\n" -" int constraintOffsetA = contactConstraintOffsets[0].x;\n" -" int splitIndexA = bodyOffsetA+constraintOffsetA;\n" -" \n" -" if (invMassA)\n" -" {\n" -" dLinVelA = deltaLinearVelocities[splitIndexA];\n" -" dAngVelA = deltaAngularVelocities[splitIndexA];\n" -" }\n" -" int bodyOffsetB = offsetSplitBodies[bIdx];\n" -" int constraintOffsetB = contactConstraintOffsets[0].y;\n" -" int splitIndexB= bodyOffsetB+constraintOffsetB;\n" -" if (invMassB)\n" -" {\n" -" dLinVelB = deltaLinearVelocities[splitIndexB];\n" -" dAngVelB = deltaAngularVelocities[splitIndexB];\n" -" }\n" -" solveContact( ldsCs, posA, &linVelA, &angVelA, invMassA, invInertiaA,\n" -" posB, &linVelB, &angVelB, invMassB, invInertiaB ,&dLinVelA, &dAngVelA, &dLinVelB, &dAngVelB);\n" -" if (invMassA)\n" -" {\n" -" deltaLinearVelocities[splitIndexA] = dLinVelA;\n" -" deltaAngularVelocities[splitIndexA] = dAngVelA;\n" -" } \n" -" if (invMassB)\n" -" {\n" -" deltaLinearVelocities[splitIndexB] = dLinVelB;\n" -" deltaAngularVelocities[splitIndexB] = dAngVelB;\n" -" }\n" -"}\n" -"__kernel void SolveContactJacobiKernel(__global Constraint4* gConstraints, __global Body* gBodies, __global Shape* gShapes ,\n" -"__global int2* contactConstraintOffsets,__global unsigned int* offsetSplitBodies,__global float4* deltaLinearVelocities, __global float4* deltaAngularVelocities,\n" -"float deltaTime, float positionDrift, float positionConstraintCoeff, int fixedBodyIndex, int numManifolds\n" -")\n" -"{\n" -" int i = GET_GLOBAL_IDX;\n" -" if (im_fJacCoeffInv[0] == 0 && cs->m_fJacCoeffInv[0] == 0 ) return;\n" -" const float4 center = cs->m_center;\n" -" \n" -" float4 n = -cs->m_linear;\n" -" \n" -" float4 tangent[2];\n" -" btPlaneSpace1(n,&tangent[0],&tangent[1]);\n" -" float4 angular0, angular1, linear;\n" -" float4 r0 = center - posA;\n" -" float4 r1 = center - posB;\n" -" for(int i=0; i<2; i++)\n" -" {\n" -" setLinearAndAngular( tangent[i], r0, r1, &linear, &angular0, &angular1 );\n" -" float rambdaDt = calcRelVel(linear, -linear, angular0, angular1,\n" -" linVelA+dLinVelA, angVelA+dAngVelA, linVelB+dLinVelB, angVelB+dAngVelB );\n" -" rambdaDt *= cs->m_fJacCoeffInv[i];\n" -" \n" -" {\n" -" float prevSum = cs->m_fAppliedRambdaDt[i];\n" -" float updated = prevSum;\n" -" updated += rambdaDt;\n" -" updated = max2( updated, minRambdaDt[i] );\n" -" updated = min2( updated, maxRambdaDt[i] );\n" -" rambdaDt = updated - prevSum;\n" -" cs->m_fAppliedRambdaDt[i] = updated;\n" -" }\n" -" \n" -" float4 linImp0 = invMassA*linear*rambdaDt;\n" -" float4 linImp1 = invMassB*(-linear)*rambdaDt;\n" -" float4 angImp0 = mtMul1(invInertiaA, angular0)*rambdaDt;\n" -" float4 angImp1 = mtMul1(invInertiaB, angular1)*rambdaDt;\n" -" \n" -" dLinVelA += linImp0;\n" -" dAngVelA += angImp0;\n" -" dLinVelB += linImp1;\n" -" dAngVelB += angImp1;\n" -" }\n" -" { // angular damping for point constraint\n" -" float4 ab = normalize3( posB - posA );\n" -" float4 ac = normalize3( center - posA );\n" -" if( dot3F4( ab, ac ) > 0.95f || (invMassA == 0.f || invMassB == 0.f))\n" -" {\n" -" float angNA = dot3F4( n, angVelA );\n" -" float angNB = dot3F4( n, angVelB );\n" -" \n" -" dAngVelA -= (angNA*0.1f)*n;\n" -" dAngVelB -= (angNB*0.1f)*n;\n" -" }\n" -" }\n" -" }\n" -" \n" -" \n" -" }\n" -" if (invMassA)\n" -" {\n" -" deltaLinearVelocities[splitIndexA] = dLinVelA;\n" -" deltaAngularVelocities[splitIndexA] = dAngVelA;\n" -" } \n" -" if (invMassB)\n" -" {\n" -" deltaLinearVelocities[splitIndexB] = dLinVelB;\n" -" deltaAngularVelocities[splitIndexB] = dAngVelB;\n" -" }\n" -" \n" -"}\n" -"__kernel void SolveFrictionJacobiKernel(__global Constraint4* gConstraints, __global Body* gBodies, __global Shape* gShapes ,\n" -" __global int2* contactConstraintOffsets,__global unsigned int* offsetSplitBodies,\n" -" __global float4* deltaLinearVelocities, __global float4* deltaAngularVelocities,\n" -" float deltaTime, float positionDrift, float positionConstraintCoeff, int fixedBodyIndex, int numManifolds\n" -")\n" -"{\n" -" int i = GET_GLOBAL_IDX;\n" -" if (im_bodyA = abs(src->m_bodyAPtrAndSignBit);\n" -" dstC->m_bodyB = abs(src->m_bodyBPtrAndSignBit);\n" -" float dtInv = 1.f/dt;\n" -" for(int ic=0; ic<4; ic++)\n" -" {\n" -" dstC->m_appliedRambdaDt[ic] = 0.f;\n" -" }\n" -" dstC->m_fJacCoeffInv[0] = dstC->m_fJacCoeffInv[1] = 0.f;\n" -" dstC->m_linear = src->m_worldNormalOnB;\n" -" dstC->m_linear.w = 0.7f ;//src->getFrictionCoeff() );\n" -" for(int ic=0; ic<4; ic++)\n" -" {\n" -" float4 r0 = src->m_worldPosB[ic] - posA;\n" -" float4 r1 = src->m_worldPosB[ic] - posB;\n" -" if( ic >= src->m_worldNormalOnB.w )//npoints\n" -" {\n" -" dstC->m_jacCoeffInv[ic] = 0.f;\n" -" continue;\n" -" }\n" -" float relVelN;\n" -" {\n" -" float4 linear, angular0, angular1;\n" -" setLinearAndAngular(src->m_worldNormalOnB, r0, r1, &linear, &angular0, &angular1);\n" -" dstC->m_jacCoeffInv[ic] = calcJacCoeff(linear, -linear, angular0, angular1,\n" -" invMassA, &invInertiaA, invMassB, &invInertiaB , countA, countB);\n" -" relVelN = calcRelVel(linear, -linear, angular0, angular1,\n" -" linVelA, angVelA, linVelB, angVelB);\n" -" float e = 0.f;//src->getRestituitionCoeff();\n" -" if( relVelN*relVelN < 0.004f ) e = 0.f;\n" -" dstC->m_b[ic] = e*relVelN;\n" -" //float penetration = src->m_worldPosB[ic].w;\n" -" dstC->m_b[ic] += (src->m_worldPosB[ic].w + positionDrift)*positionConstraintCoeff*dtInv;\n" -" dstC->m_appliedRambdaDt[ic] = 0.f;\n" -" }\n" -" }\n" -" if( src->m_worldNormalOnB.w > 0 )//npoints\n" -" { // prepare friction\n" -" float4 center = make_float4(0.f);\n" -" for(int i=0; im_worldNormalOnB.w; i++) \n" -" center += src->m_worldPosB[i];\n" -" center /= (float)src->m_worldNormalOnB.w;\n" -" float4 tangent[2];\n" -" btPlaneSpace1(-src->m_worldNormalOnB,&tangent[0],&tangent[1]);\n" -" \n" -" float4 r[2];\n" -" r[0] = center - posA;\n" -" r[1] = center - posB;\n" -" for(int i=0; i<2; i++)\n" -" {\n" -" float4 linear, angular0, angular1;\n" -" setLinearAndAngular(tangent[i], r[0], r[1], &linear, &angular0, &angular1);\n" -" dstC->m_fJacCoeffInv[i] = calcJacCoeff(linear, -linear, angular0, angular1,\n" -" invMassA, &invInertiaA, invMassB, &invInertiaB ,countA, countB);\n" -" dstC->m_fAppliedRambdaDt[i] = 0.f;\n" -" }\n" -" dstC->m_center = center;\n" -" }\n" -" for(int i=0; i<4; i++)\n" -" {\n" -" if( im_worldNormalOnB.w )\n" -" {\n" -" dstC->m_worldPos[i] = src->m_worldPosB[i];\n" -" }\n" -" else\n" -" {\n" -" dstC->m_worldPos[i] = make_float4(0.f);\n" -" }\n" -" }\n" -"}\n" -"__kernel\n" -"__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" -"void ContactToConstraintSplitKernel(__global const struct b3Contact4Data* gContact, __global const Body* gBodies, __global const Shape* gShapes, __global Constraint4* gConstraintOut, \n" -"__global const unsigned int* bodyCount,\n" -"int nContacts,\n" -"float dt,\n" -"float positionDrift,\n" -"float positionConstraintCoeff\n" -")\n" -"{\n" -" int gIdx = GET_GLOBAL_IDX;\n" -" \n" -" if( gIdx < nContacts )\n" -" {\n" -" int aIdx = abs(gContact[gIdx].m_bodyAPtrAndSignBit);\n" -" int bIdx = abs(gContact[gIdx].m_bodyBPtrAndSignBit);\n" -" float4 posA = gBodies[aIdx].m_pos;\n" -" float4 linVelA = gBodies[aIdx].m_linVel;\n" -" float4 angVelA = gBodies[aIdx].m_angVel;\n" -" float invMassA = gBodies[aIdx].m_invMass;\n" -" Matrix3x3 invInertiaA = gShapes[aIdx].m_invInertia;\n" -" float4 posB = gBodies[bIdx].m_pos;\n" -" float4 linVelB = gBodies[bIdx].m_linVel;\n" -" float4 angVelB = gBodies[bIdx].m_angVel;\n" -" float invMassB = gBodies[bIdx].m_invMass;\n" -" Matrix3x3 invInertiaB = gShapes[bIdx].m_invInertia;\n" -" Constraint4 cs;\n" -" float countA = invMassA != 0.f ? (float)bodyCount[aIdx] : 1;\n" -" float countB = invMassB != 0.f ? (float)bodyCount[bIdx] : 1;\n" -" setConstraint4( posA, linVelA, angVelA, invMassA, invInertiaA, posB, linVelB, angVelB, invMassB, invInertiaB,\n" -" &gContact[gIdx], dt, positionDrift, positionConstraintCoeff,countA,countB,\n" -" &cs );\n" -" \n" -" cs.m_batchIdx = gContact[gIdx].m_batchIdx;\n" -" gConstraintOut[gIdx] = cs;\n" -" }\n" -"}\n" -; +static const char* solverUtilsCL = + "/*\n" + "Copyright (c) 2013 Advanced Micro Devices, Inc. \n" + "This software is provided 'as-is', without any express or implied warranty.\n" + "In no event will the authors be held liable for any damages arising from the use of this software.\n" + "Permission is granted to anyone to use this software for any purpose, \n" + "including commercial applications, and to alter it and redistribute it freely, \n" + "subject to the following restrictions:\n" + "1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.\n" + "2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.\n" + "3. This notice may not be removed or altered from any source distribution.\n" + "*/\n" + "//Originally written by Erwin Coumans\n" + "#ifndef B3_CONTACT4DATA_H\n" + "#define B3_CONTACT4DATA_H\n" + "#ifndef B3_FLOAT4_H\n" + "#define B3_FLOAT4_H\n" + "#ifndef B3_PLATFORM_DEFINITIONS_H\n" + "#define B3_PLATFORM_DEFINITIONS_H\n" + "struct MyTest\n" + "{\n" + " int bla;\n" + "};\n" + "#ifdef __cplusplus\n" + "#else\n" + "//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n" + "#define B3_LARGE_FLOAT 1e18f\n" + "#define B3_INFINITY 1e18f\n" + "#define b3Assert(a)\n" + "#define b3ConstArray(a) __global const a*\n" + "#define b3AtomicInc atomic_inc\n" + "#define b3AtomicAdd atomic_add\n" + "#define b3Fabs fabs\n" + "#define b3Sqrt native_sqrt\n" + "#define b3Sin native_sin\n" + "#define b3Cos native_cos\n" + "#define B3_STATIC\n" + "#endif\n" + "#endif\n" + "#ifdef __cplusplus\n" + "#else\n" + " typedef float4 b3Float4;\n" + " #define b3Float4ConstArg const b3Float4\n" + " #define b3MakeFloat4 (float4)\n" + " float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" + " {\n" + " float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" + " float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" + " return dot(a1, b1);\n" + " }\n" + " b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" + " {\n" + " float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" + " float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" + " return cross(a1, b1);\n" + " }\n" + " #define b3MinFloat4 min\n" + " #define b3MaxFloat4 max\n" + " #define b3Normalized(a) normalize(a)\n" + "#endif \n" + " \n" + "inline bool b3IsAlmostZero(b3Float4ConstArg v)\n" + "{\n" + " if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" + " return false;\n" + " return true;\n" + "}\n" + "inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" + "{\n" + " float maxDot = -B3_INFINITY;\n" + " int i = 0;\n" + " int ptIndex = -1;\n" + " for( i = 0; i < vecLen; i++ )\n" + " {\n" + " float dot = b3Dot3F4(vecArray[i],vec);\n" + " \n" + " if( dot > maxDot )\n" + " {\n" + " maxDot = dot;\n" + " ptIndex = i;\n" + " }\n" + " }\n" + " b3Assert(ptIndex>=0);\n" + " if (ptIndex<0)\n" + " {\n" + " ptIndex = 0;\n" + " }\n" + " *dotOut = maxDot;\n" + " return ptIndex;\n" + "}\n" + "#endif //B3_FLOAT4_H\n" + "typedef struct b3Contact4Data b3Contact4Data_t;\n" + "struct b3Contact4Data\n" + "{\n" + " b3Float4 m_worldPosB[4];\n" + "// b3Float4 m_localPosA[4];\n" + "// b3Float4 m_localPosB[4];\n" + " b3Float4 m_worldNormalOnB; // w: m_nPoints\n" + " unsigned short m_restituitionCoeffCmp;\n" + " unsigned short m_frictionCoeffCmp;\n" + " int m_batchIdx;\n" + " int m_bodyAPtrAndSignBit;//x:m_bodyAPtr, y:m_bodyBPtr\n" + " int m_bodyBPtrAndSignBit;\n" + " int m_childIndexA;\n" + " int m_childIndexB;\n" + " int m_unused1;\n" + " int m_unused2;\n" + "};\n" + "inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact)\n" + "{\n" + " return (int)contact->m_worldNormalOnB.w;\n" + "};\n" + "inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints)\n" + "{\n" + " contact->m_worldNormalOnB.w = (float)numPoints;\n" + "};\n" + "#endif //B3_CONTACT4DATA_H\n" + "#pragma OPENCL EXTENSION cl_amd_printf : enable\n" + "#pragma OPENCL EXTENSION cl_khr_local_int32_base_atomics : enable\n" + "#pragma OPENCL EXTENSION cl_khr_global_int32_base_atomics : enable\n" + "#pragma OPENCL EXTENSION cl_khr_local_int32_extended_atomics : enable\n" + "#pragma OPENCL EXTENSION cl_khr_global_int32_extended_atomics : enable\n" + "#ifdef cl_ext_atomic_counters_32\n" + "#pragma OPENCL EXTENSION cl_ext_atomic_counters_32 : enable\n" + "#else\n" + "#define counter32_t volatile global int*\n" + "#endif\n" + "typedef unsigned int u32;\n" + "typedef unsigned short u16;\n" + "typedef unsigned char u8;\n" + "#define GET_GROUP_IDX get_group_id(0)\n" + "#define GET_LOCAL_IDX get_local_id(0)\n" + "#define GET_GLOBAL_IDX get_global_id(0)\n" + "#define GET_GROUP_SIZE get_local_size(0)\n" + "#define GET_NUM_GROUPS get_num_groups(0)\n" + "#define GROUP_LDS_BARRIER barrier(CLK_LOCAL_MEM_FENCE)\n" + "#define GROUP_MEM_FENCE mem_fence(CLK_LOCAL_MEM_FENCE)\n" + "#define AtomInc(x) atom_inc(&(x))\n" + "#define AtomInc1(x, out) out = atom_inc(&(x))\n" + "#define AppendInc(x, out) out = atomic_inc(x)\n" + "#define AtomAdd(x, value) atom_add(&(x), value)\n" + "#define AtomCmpxhg(x, cmp, value) atom_cmpxchg( &(x), cmp, value )\n" + "#define AtomXhg(x, value) atom_xchg ( &(x), value )\n" + "#define SELECT_UINT4( b, a, condition ) select( b,a,condition )\n" + "#define make_float4 (float4)\n" + "#define make_float2 (float2)\n" + "#define make_uint4 (uint4)\n" + "#define make_int4 (int4)\n" + "#define make_uint2 (uint2)\n" + "#define make_int2 (int2)\n" + "#define max2 max\n" + "#define min2 min\n" + "///////////////////////////////////////\n" + "// Vector\n" + "///////////////////////////////////////\n" + "__inline\n" + "float fastDiv(float numerator, float denominator)\n" + "{\n" + " return native_divide(numerator, denominator); \n" + "// return numerator/denominator; \n" + "}\n" + "__inline\n" + "float4 fastDiv4(float4 numerator, float4 denominator)\n" + "{\n" + " return native_divide(numerator, denominator); \n" + "}\n" + "__inline\n" + "float fastSqrtf(float f2)\n" + "{\n" + " return native_sqrt(f2);\n" + "// return sqrt(f2);\n" + "}\n" + "__inline\n" + "float fastRSqrt(float f2)\n" + "{\n" + " return native_rsqrt(f2);\n" + "}\n" + "__inline\n" + "float fastLength4(float4 v)\n" + "{\n" + " return fast_length(v);\n" + "}\n" + "__inline\n" + "float4 fastNormalize4(float4 v)\n" + "{\n" + " return fast_normalize(v);\n" + "}\n" + "__inline\n" + "float sqrtf(float a)\n" + "{\n" + "// return sqrt(a);\n" + " return native_sqrt(a);\n" + "}\n" + "__inline\n" + "float4 cross3(float4 a1, float4 b1)\n" + "{\n" + " float4 a=make_float4(a1.xyz,0.f);\n" + " float4 b=make_float4(b1.xyz,0.f);\n" + " //float4 a=a1;\n" + " //float4 b=b1;\n" + " return cross(a,b);\n" + "}\n" + "__inline\n" + "float dot3F4(float4 a, float4 b)\n" + "{\n" + " float4 a1 = make_float4(a.xyz,0.f);\n" + " float4 b1 = make_float4(b.xyz,0.f);\n" + " return dot(a1, b1);\n" + "}\n" + "__inline\n" + "float length3(const float4 a)\n" + "{\n" + " return sqrtf(dot3F4(a,a));\n" + "}\n" + "__inline\n" + "float dot4(const float4 a, const float4 b)\n" + "{\n" + " return dot( a, b );\n" + "}\n" + "// for height\n" + "__inline\n" + "float dot3w1(const float4 point, const float4 eqn)\n" + "{\n" + " return dot3F4(point,eqn) + eqn.w;\n" + "}\n" + "__inline\n" + "float4 normalize3(const float4 a)\n" + "{\n" + " float4 n = make_float4(a.x, a.y, a.z, 0.f);\n" + " return fastNormalize4( n );\n" + "// float length = sqrtf(dot3F4(a, a));\n" + "// return 1.f/length * a;\n" + "}\n" + "__inline\n" + "float4 normalize4(const float4 a)\n" + "{\n" + " float length = sqrtf(dot4(a, a));\n" + " return 1.f/length * a;\n" + "}\n" + "__inline\n" + "float4 createEquation(const float4 a, const float4 b, const float4 c)\n" + "{\n" + " float4 eqn;\n" + " float4 ab = b-a;\n" + " float4 ac = c-a;\n" + " eqn = normalize3( cross3(ab, ac) );\n" + " eqn.w = -dot3F4(eqn,a);\n" + " return eqn;\n" + "}\n" + "///////////////////////////////////////\n" + "// Matrix3x3\n" + "///////////////////////////////////////\n" + "typedef struct\n" + "{\n" + " float4 m_row[3];\n" + "}Matrix3x3;\n" + "__inline\n" + "Matrix3x3 mtZero();\n" + "__inline\n" + "Matrix3x3 mtIdentity();\n" + "__inline\n" + "Matrix3x3 mtTranspose(Matrix3x3 m);\n" + "__inline\n" + "Matrix3x3 mtMul(Matrix3x3 a, Matrix3x3 b);\n" + "__inline\n" + "float4 mtMul1(Matrix3x3 a, float4 b);\n" + "__inline\n" + "float4 mtMul3(float4 a, Matrix3x3 b);\n" + "__inline\n" + "Matrix3x3 mtZero()\n" + "{\n" + " Matrix3x3 m;\n" + " m.m_row[0] = (float4)(0.f);\n" + " m.m_row[1] = (float4)(0.f);\n" + " m.m_row[2] = (float4)(0.f);\n" + " return m;\n" + "}\n" + "__inline\n" + "Matrix3x3 mtIdentity()\n" + "{\n" + " Matrix3x3 m;\n" + " m.m_row[0] = (float4)(1,0,0,0);\n" + " m.m_row[1] = (float4)(0,1,0,0);\n" + " m.m_row[2] = (float4)(0,0,1,0);\n" + " return m;\n" + "}\n" + "__inline\n" + "Matrix3x3 mtTranspose(Matrix3x3 m)\n" + "{\n" + " Matrix3x3 out;\n" + " out.m_row[0] = (float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n" + " out.m_row[1] = (float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n" + " out.m_row[2] = (float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n" + " return out;\n" + "}\n" + "__inline\n" + "Matrix3x3 mtMul(Matrix3x3 a, Matrix3x3 b)\n" + "{\n" + " Matrix3x3 transB;\n" + " transB = mtTranspose( b );\n" + " Matrix3x3 ans;\n" + " // why this doesn't run when 0ing in the for{}\n" + " a.m_row[0].w = 0.f;\n" + " a.m_row[1].w = 0.f;\n" + " a.m_row[2].w = 0.f;\n" + " for(int i=0; i<3; i++)\n" + " {\n" + "// a.m_row[i].w = 0.f;\n" + " ans.m_row[i].x = dot3F4(a.m_row[i],transB.m_row[0]);\n" + " ans.m_row[i].y = dot3F4(a.m_row[i],transB.m_row[1]);\n" + " ans.m_row[i].z = dot3F4(a.m_row[i],transB.m_row[2]);\n" + " ans.m_row[i].w = 0.f;\n" + " }\n" + " return ans;\n" + "}\n" + "__inline\n" + "float4 mtMul1(Matrix3x3 a, float4 b)\n" + "{\n" + " float4 ans;\n" + " ans.x = dot3F4( a.m_row[0], b );\n" + " ans.y = dot3F4( a.m_row[1], b );\n" + " ans.z = dot3F4( a.m_row[2], b );\n" + " ans.w = 0.f;\n" + " return ans;\n" + "}\n" + "__inline\n" + "float4 mtMul3(float4 a, Matrix3x3 b)\n" + "{\n" + " float4 colx = make_float4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" + " float4 coly = make_float4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" + " float4 colz = make_float4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" + " float4 ans;\n" + " ans.x = dot3F4( a, colx );\n" + " ans.y = dot3F4( a, coly );\n" + " ans.z = dot3F4( a, colz );\n" + " return ans;\n" + "}\n" + "///////////////////////////////////////\n" + "// Quaternion\n" + "///////////////////////////////////////\n" + "typedef float4 Quaternion;\n" + "__inline\n" + "Quaternion qtMul(Quaternion a, Quaternion b);\n" + "__inline\n" + "Quaternion qtNormalize(Quaternion in);\n" + "__inline\n" + "float4 qtRotate(Quaternion q, float4 vec);\n" + "__inline\n" + "Quaternion qtInvert(Quaternion q);\n" + "__inline\n" + "Quaternion qtMul(Quaternion a, Quaternion b)\n" + "{\n" + " Quaternion ans;\n" + " ans = cross3( a, b );\n" + " ans += a.w*b+b.w*a;\n" + "// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" + " ans.w = a.w*b.w - dot3F4(a, b);\n" + " return ans;\n" + "}\n" + "__inline\n" + "Quaternion qtNormalize(Quaternion in)\n" + "{\n" + " return fastNormalize4(in);\n" + "// in /= length( in );\n" + "// return in;\n" + "}\n" + "__inline\n" + "float4 qtRotate(Quaternion q, float4 vec)\n" + "{\n" + " Quaternion qInv = qtInvert( q );\n" + " float4 vcpy = vec;\n" + " vcpy.w = 0.f;\n" + " float4 out = qtMul(qtMul(q,vcpy),qInv);\n" + " return out;\n" + "}\n" + "__inline\n" + "Quaternion qtInvert(Quaternion q)\n" + "{\n" + " return (Quaternion)(-q.xyz, q.w);\n" + "}\n" + "__inline\n" + "float4 qtInvRotate(const Quaternion q, float4 vec)\n" + "{\n" + " return qtRotate( qtInvert( q ), vec );\n" + "}\n" + "#define WG_SIZE 64\n" + "typedef struct\n" + "{\n" + " float4 m_pos;\n" + " Quaternion m_quat;\n" + " float4 m_linVel;\n" + " float4 m_angVel;\n" + " u32 m_shapeIdx;\n" + " float m_invMass;\n" + " float m_restituitionCoeff;\n" + " float m_frictionCoeff;\n" + "} Body;\n" + "typedef struct\n" + "{\n" + " Matrix3x3 m_invInertia;\n" + " Matrix3x3 m_initInvInertia;\n" + "} Shape;\n" + "typedef struct\n" + "{\n" + " float4 m_linear;\n" + " float4 m_worldPos[4];\n" + " float4 m_center; \n" + " float m_jacCoeffInv[4];\n" + " float m_b[4];\n" + " float m_appliedRambdaDt[4];\n" + " float m_fJacCoeffInv[2]; \n" + " float m_fAppliedRambdaDt[2]; \n" + " u32 m_bodyA;\n" + " u32 m_bodyB;\n" + " int m_batchIdx;\n" + " u32 m_paddings;\n" + "} Constraint4;\n" + "__kernel void CountBodiesKernel(__global struct b3Contact4Data* manifoldPtr, __global unsigned int* bodyCount, __global int2* contactConstraintOffsets, int numContactManifolds, int fixedBodyIndex)\n" + "{\n" + " int i = GET_GLOBAL_IDX;\n" + " \n" + " if( i < numContactManifolds)\n" + " {\n" + " int pa = manifoldPtr[i].m_bodyAPtrAndSignBit;\n" + " bool isFixedA = (pa <0) || (pa == fixedBodyIndex);\n" + " int bodyIndexA = abs(pa);\n" + " if (!isFixedA)\n" + " {\n" + " AtomInc1(bodyCount[bodyIndexA],contactConstraintOffsets[i].x);\n" + " }\n" + " barrier(CLK_GLOBAL_MEM_FENCE);\n" + " int pb = manifoldPtr[i].m_bodyBPtrAndSignBit;\n" + " bool isFixedB = (pb <0) || (pb == fixedBodyIndex);\n" + " int bodyIndexB = abs(pb);\n" + " if (!isFixedB)\n" + " {\n" + " AtomInc1(bodyCount[bodyIndexB],contactConstraintOffsets[i].y);\n" + " } \n" + " }\n" + "}\n" + "__kernel void ClearVelocitiesKernel(__global float4* linearVelocities,__global float4* angularVelocities, int numSplitBodies)\n" + "{\n" + " int i = GET_GLOBAL_IDX;\n" + " \n" + " if( i < numSplitBodies)\n" + " {\n" + " linearVelocities[i] = make_float4(0);\n" + " angularVelocities[i] = make_float4(0);\n" + " }\n" + "}\n" + "__kernel void AverageVelocitiesKernel(__global Body* gBodies,__global int* offsetSplitBodies,__global const unsigned int* bodyCount,\n" + "__global float4* deltaLinearVelocities, __global float4* deltaAngularVelocities, int numBodies)\n" + "{\n" + " int i = GET_GLOBAL_IDX;\n" + " if (i 0.70710678f) {\n" + " // choose p in y-z plane\n" + " float a = n.y*n.y + n.z*n.z;\n" + " float k = 1.f/sqrt(a);\n" + " p[0].x = 0;\n" + " p[0].y = -n.z*k;\n" + " p[0].z = n.y*k;\n" + " // set q = n x p\n" + " q[0].x = a*k;\n" + " q[0].y = -n.x*p[0].z;\n" + " q[0].z = n.x*p[0].y;\n" + " }\n" + " else {\n" + " // choose p in x-y plane\n" + " float a = n.x*n.x + n.y*n.y;\n" + " float k = 1.f/sqrt(a);\n" + " p[0].x = -n.y*k;\n" + " p[0].y = n.x*k;\n" + " p[0].z = 0;\n" + " // set q = n x p\n" + " q[0].x = -n.z*p[0].y;\n" + " q[0].y = n.z*p[0].x;\n" + " q[0].z = a*k;\n" + " }\n" + "}\n" + "void solveContact(__global Constraint4* cs,\n" + " float4 posA, float4* linVelA, float4* angVelA, float invMassA, Matrix3x3 invInertiaA,\n" + " float4 posB, float4* linVelB, float4* angVelB, float invMassB, Matrix3x3 invInertiaB,\n" + " float4* dLinVelA, float4* dAngVelA, float4* dLinVelB, float4* dAngVelB)\n" + "{\n" + " float minRambdaDt = 0;\n" + " float maxRambdaDt = FLT_MAX;\n" + " for(int ic=0; ic<4; ic++)\n" + " {\n" + " if( cs->m_jacCoeffInv[ic] == 0.f ) continue;\n" + " float4 angular0, angular1, linear;\n" + " float4 r0 = cs->m_worldPos[ic] - posA;\n" + " float4 r1 = cs->m_worldPos[ic] - posB;\n" + " setLinearAndAngular( cs->m_linear, r0, r1, &linear, &angular0, &angular1 );\n" + " \n" + " float rambdaDt = calcRelVel( cs->m_linear, -cs->m_linear, angular0, angular1, \n" + " *linVelA+*dLinVelA, *angVelA+*dAngVelA, *linVelB+*dLinVelB, *angVelB+*dAngVelB ) + cs->m_b[ic];\n" + " rambdaDt *= cs->m_jacCoeffInv[ic];\n" + " \n" + " {\n" + " float prevSum = cs->m_appliedRambdaDt[ic];\n" + " float updated = prevSum;\n" + " updated += rambdaDt;\n" + " updated = max2( updated, minRambdaDt );\n" + " updated = min2( updated, maxRambdaDt );\n" + " rambdaDt = updated - prevSum;\n" + " cs->m_appliedRambdaDt[ic] = updated;\n" + " }\n" + " \n" + " float4 linImp0 = invMassA*linear*rambdaDt;\n" + " float4 linImp1 = invMassB*(-linear)*rambdaDt;\n" + " float4 angImp0 = mtMul1(invInertiaA, angular0)*rambdaDt;\n" + " float4 angImp1 = mtMul1(invInertiaB, angular1)*rambdaDt;\n" + " \n" + " if (invMassA)\n" + " {\n" + " *dLinVelA += linImp0;\n" + " *dAngVelA += angImp0;\n" + " }\n" + " if (invMassB)\n" + " {\n" + " *dLinVelB += linImp1;\n" + " *dAngVelB += angImp1;\n" + " }\n" + " }\n" + "}\n" + "// solveContactConstraint( gBodies, gShapes, &gConstraints[i] ,contactConstraintOffsets,offsetSplitBodies, deltaLinearVelocities, deltaAngularVelocities);\n" + "void solveContactConstraint(__global Body* gBodies, __global Shape* gShapes, __global Constraint4* ldsCs, \n" + "__global int2* contactConstraintOffsets,__global unsigned int* offsetSplitBodies,\n" + "__global float4* deltaLinearVelocities, __global float4* deltaAngularVelocities)\n" + "{\n" + " //float frictionCoeff = ldsCs[0].m_linear.w;\n" + " int aIdx = ldsCs[0].m_bodyA;\n" + " int bIdx = ldsCs[0].m_bodyB;\n" + " float4 posA = gBodies[aIdx].m_pos;\n" + " float4 linVelA = gBodies[aIdx].m_linVel;\n" + " float4 angVelA = gBodies[aIdx].m_angVel;\n" + " float invMassA = gBodies[aIdx].m_invMass;\n" + " Matrix3x3 invInertiaA = gShapes[aIdx].m_invInertia;\n" + " float4 posB = gBodies[bIdx].m_pos;\n" + " float4 linVelB = gBodies[bIdx].m_linVel;\n" + " float4 angVelB = gBodies[bIdx].m_angVel;\n" + " float invMassB = gBodies[bIdx].m_invMass;\n" + " Matrix3x3 invInertiaB = gShapes[bIdx].m_invInertia;\n" + " \n" + " float4 dLinVelA = make_float4(0,0,0,0);\n" + " float4 dAngVelA = make_float4(0,0,0,0);\n" + " float4 dLinVelB = make_float4(0,0,0,0);\n" + " float4 dAngVelB = make_float4(0,0,0,0);\n" + " \n" + " int bodyOffsetA = offsetSplitBodies[aIdx];\n" + " int constraintOffsetA = contactConstraintOffsets[0].x;\n" + " int splitIndexA = bodyOffsetA+constraintOffsetA;\n" + " \n" + " if (invMassA)\n" + " {\n" + " dLinVelA = deltaLinearVelocities[splitIndexA];\n" + " dAngVelA = deltaAngularVelocities[splitIndexA];\n" + " }\n" + " int bodyOffsetB = offsetSplitBodies[bIdx];\n" + " int constraintOffsetB = contactConstraintOffsets[0].y;\n" + " int splitIndexB= bodyOffsetB+constraintOffsetB;\n" + " if (invMassB)\n" + " {\n" + " dLinVelB = deltaLinearVelocities[splitIndexB];\n" + " dAngVelB = deltaAngularVelocities[splitIndexB];\n" + " }\n" + " solveContact( ldsCs, posA, &linVelA, &angVelA, invMassA, invInertiaA,\n" + " posB, &linVelB, &angVelB, invMassB, invInertiaB ,&dLinVelA, &dAngVelA, &dLinVelB, &dAngVelB);\n" + " if (invMassA)\n" + " {\n" + " deltaLinearVelocities[splitIndexA] = dLinVelA;\n" + " deltaAngularVelocities[splitIndexA] = dAngVelA;\n" + " } \n" + " if (invMassB)\n" + " {\n" + " deltaLinearVelocities[splitIndexB] = dLinVelB;\n" + " deltaAngularVelocities[splitIndexB] = dAngVelB;\n" + " }\n" + "}\n" + "__kernel void SolveContactJacobiKernel(__global Constraint4* gConstraints, __global Body* gBodies, __global Shape* gShapes ,\n" + "__global int2* contactConstraintOffsets,__global unsigned int* offsetSplitBodies,__global float4* deltaLinearVelocities, __global float4* deltaAngularVelocities,\n" + "float deltaTime, float positionDrift, float positionConstraintCoeff, int fixedBodyIndex, int numManifolds\n" + ")\n" + "{\n" + " int i = GET_GLOBAL_IDX;\n" + " if (im_fJacCoeffInv[0] == 0 && cs->m_fJacCoeffInv[0] == 0 ) return;\n" + " const float4 center = cs->m_center;\n" + " \n" + " float4 n = -cs->m_linear;\n" + " \n" + " float4 tangent[2];\n" + " btPlaneSpace1(n,&tangent[0],&tangent[1]);\n" + " float4 angular0, angular1, linear;\n" + " float4 r0 = center - posA;\n" + " float4 r1 = center - posB;\n" + " for(int i=0; i<2; i++)\n" + " {\n" + " setLinearAndAngular( tangent[i], r0, r1, &linear, &angular0, &angular1 );\n" + " float rambdaDt = calcRelVel(linear, -linear, angular0, angular1,\n" + " linVelA+dLinVelA, angVelA+dAngVelA, linVelB+dLinVelB, angVelB+dAngVelB );\n" + " rambdaDt *= cs->m_fJacCoeffInv[i];\n" + " \n" + " {\n" + " float prevSum = cs->m_fAppliedRambdaDt[i];\n" + " float updated = prevSum;\n" + " updated += rambdaDt;\n" + " updated = max2( updated, minRambdaDt[i] );\n" + " updated = min2( updated, maxRambdaDt[i] );\n" + " rambdaDt = updated - prevSum;\n" + " cs->m_fAppliedRambdaDt[i] = updated;\n" + " }\n" + " \n" + " float4 linImp0 = invMassA*linear*rambdaDt;\n" + " float4 linImp1 = invMassB*(-linear)*rambdaDt;\n" + " float4 angImp0 = mtMul1(invInertiaA, angular0)*rambdaDt;\n" + " float4 angImp1 = mtMul1(invInertiaB, angular1)*rambdaDt;\n" + " \n" + " dLinVelA += linImp0;\n" + " dAngVelA += angImp0;\n" + " dLinVelB += linImp1;\n" + " dAngVelB += angImp1;\n" + " }\n" + " { // angular damping for point constraint\n" + " float4 ab = normalize3( posB - posA );\n" + " float4 ac = normalize3( center - posA );\n" + " if( dot3F4( ab, ac ) > 0.95f || (invMassA == 0.f || invMassB == 0.f))\n" + " {\n" + " float angNA = dot3F4( n, angVelA );\n" + " float angNB = dot3F4( n, angVelB );\n" + " \n" + " dAngVelA -= (angNA*0.1f)*n;\n" + " dAngVelB -= (angNB*0.1f)*n;\n" + " }\n" + " }\n" + " }\n" + " \n" + " \n" + " }\n" + " if (invMassA)\n" + " {\n" + " deltaLinearVelocities[splitIndexA] = dLinVelA;\n" + " deltaAngularVelocities[splitIndexA] = dAngVelA;\n" + " } \n" + " if (invMassB)\n" + " {\n" + " deltaLinearVelocities[splitIndexB] = dLinVelB;\n" + " deltaAngularVelocities[splitIndexB] = dAngVelB;\n" + " }\n" + " \n" + "}\n" + "__kernel void SolveFrictionJacobiKernel(__global Constraint4* gConstraints, __global Body* gBodies, __global Shape* gShapes ,\n" + " __global int2* contactConstraintOffsets,__global unsigned int* offsetSplitBodies,\n" + " __global float4* deltaLinearVelocities, __global float4* deltaAngularVelocities,\n" + " float deltaTime, float positionDrift, float positionConstraintCoeff, int fixedBodyIndex, int numManifolds\n" + ")\n" + "{\n" + " int i = GET_GLOBAL_IDX;\n" + " if (im_bodyA = abs(src->m_bodyAPtrAndSignBit);\n" + " dstC->m_bodyB = abs(src->m_bodyBPtrAndSignBit);\n" + " float dtInv = 1.f/dt;\n" + " for(int ic=0; ic<4; ic++)\n" + " {\n" + " dstC->m_appliedRambdaDt[ic] = 0.f;\n" + " }\n" + " dstC->m_fJacCoeffInv[0] = dstC->m_fJacCoeffInv[1] = 0.f;\n" + " dstC->m_linear = src->m_worldNormalOnB;\n" + " dstC->m_linear.w = 0.7f ;//src->getFrictionCoeff() );\n" + " for(int ic=0; ic<4; ic++)\n" + " {\n" + " float4 r0 = src->m_worldPosB[ic] - posA;\n" + " float4 r1 = src->m_worldPosB[ic] - posB;\n" + " if( ic >= src->m_worldNormalOnB.w )//npoints\n" + " {\n" + " dstC->m_jacCoeffInv[ic] = 0.f;\n" + " continue;\n" + " }\n" + " float relVelN;\n" + " {\n" + " float4 linear, angular0, angular1;\n" + " setLinearAndAngular(src->m_worldNormalOnB, r0, r1, &linear, &angular0, &angular1);\n" + " dstC->m_jacCoeffInv[ic] = calcJacCoeff(linear, -linear, angular0, angular1,\n" + " invMassA, &invInertiaA, invMassB, &invInertiaB , countA, countB);\n" + " relVelN = calcRelVel(linear, -linear, angular0, angular1,\n" + " linVelA, angVelA, linVelB, angVelB);\n" + " float e = 0.f;//src->getRestituitionCoeff();\n" + " if( relVelN*relVelN < 0.004f ) e = 0.f;\n" + " dstC->m_b[ic] = e*relVelN;\n" + " //float penetration = src->m_worldPosB[ic].w;\n" + " dstC->m_b[ic] += (src->m_worldPosB[ic].w + positionDrift)*positionConstraintCoeff*dtInv;\n" + " dstC->m_appliedRambdaDt[ic] = 0.f;\n" + " }\n" + " }\n" + " if( src->m_worldNormalOnB.w > 0 )//npoints\n" + " { // prepare friction\n" + " float4 center = make_float4(0.f);\n" + " for(int i=0; im_worldNormalOnB.w; i++) \n" + " center += src->m_worldPosB[i];\n" + " center /= (float)src->m_worldNormalOnB.w;\n" + " float4 tangent[2];\n" + " btPlaneSpace1(-src->m_worldNormalOnB,&tangent[0],&tangent[1]);\n" + " \n" + " float4 r[2];\n" + " r[0] = center - posA;\n" + " r[1] = center - posB;\n" + " for(int i=0; i<2; i++)\n" + " {\n" + " float4 linear, angular0, angular1;\n" + " setLinearAndAngular(tangent[i], r[0], r[1], &linear, &angular0, &angular1);\n" + " dstC->m_fJacCoeffInv[i] = calcJacCoeff(linear, -linear, angular0, angular1,\n" + " invMassA, &invInertiaA, invMassB, &invInertiaB ,countA, countB);\n" + " dstC->m_fAppliedRambdaDt[i] = 0.f;\n" + " }\n" + " dstC->m_center = center;\n" + " }\n" + " for(int i=0; i<4; i++)\n" + " {\n" + " if( im_worldNormalOnB.w )\n" + " {\n" + " dstC->m_worldPos[i] = src->m_worldPosB[i];\n" + " }\n" + " else\n" + " {\n" + " dstC->m_worldPos[i] = make_float4(0.f);\n" + " }\n" + " }\n" + "}\n" + "__kernel\n" + "__attribute__((reqd_work_group_size(WG_SIZE,1,1)))\n" + "void ContactToConstraintSplitKernel(__global const struct b3Contact4Data* gContact, __global const Body* gBodies, __global const Shape* gShapes, __global Constraint4* gConstraintOut, \n" + "__global const unsigned int* bodyCount,\n" + "int nContacts,\n" + "float dt,\n" + "float positionDrift,\n" + "float positionConstraintCoeff\n" + ")\n" + "{\n" + " int gIdx = GET_GLOBAL_IDX;\n" + " \n" + " if( gIdx < nContacts )\n" + " {\n" + " int aIdx = abs(gContact[gIdx].m_bodyAPtrAndSignBit);\n" + " int bIdx = abs(gContact[gIdx].m_bodyBPtrAndSignBit);\n" + " float4 posA = gBodies[aIdx].m_pos;\n" + " float4 linVelA = gBodies[aIdx].m_linVel;\n" + " float4 angVelA = gBodies[aIdx].m_angVel;\n" + " float invMassA = gBodies[aIdx].m_invMass;\n" + " Matrix3x3 invInertiaA = gShapes[aIdx].m_invInertia;\n" + " float4 posB = gBodies[bIdx].m_pos;\n" + " float4 linVelB = gBodies[bIdx].m_linVel;\n" + " float4 angVelB = gBodies[bIdx].m_angVel;\n" + " float invMassB = gBodies[bIdx].m_invMass;\n" + " Matrix3x3 invInertiaB = gShapes[bIdx].m_invInertia;\n" + " Constraint4 cs;\n" + " float countA = invMassA != 0.f ? (float)bodyCount[aIdx] : 1;\n" + " float countB = invMassB != 0.f ? (float)bodyCount[bIdx] : 1;\n" + " setConstraint4( posA, linVelA, angVelA, invMassA, invInertiaA, posB, linVelB, angVelB, invMassB, invInertiaB,\n" + " &gContact[gIdx], dt, positionDrift, positionConstraintCoeff,countA,countB,\n" + " &cs );\n" + " \n" + " cs.m_batchIdx = gContact[gIdx].m_batchIdx;\n" + " gConstraintOut[gIdx] = cs;\n" + " }\n" + "}\n"; diff --git a/src/Bullet3OpenCL/RigidBody/kernels/updateAabbsKernel.h b/src/Bullet3OpenCL/RigidBody/kernels/updateAabbsKernel.h index d70e74017..bb949b202 100644 --- a/src/Bullet3OpenCL/RigidBody/kernels/updateAabbsKernel.h +++ b/src/Bullet3OpenCL/RigidBody/kernels/updateAabbsKernel.h @@ -1,483 +1,482 @@ //this file is autogenerated using stringify.bat (premake --stringify) in the build folder of this project -static const char* updateAabbsKernelCL= \ -"#ifndef B3_UPDATE_AABBS_H\n" -"#define B3_UPDATE_AABBS_H\n" -"#ifndef B3_AABB_H\n" -"#define B3_AABB_H\n" -"#ifndef B3_FLOAT4_H\n" -"#define B3_FLOAT4_H\n" -"#ifndef B3_PLATFORM_DEFINITIONS_H\n" -"#define B3_PLATFORM_DEFINITIONS_H\n" -"struct MyTest\n" -"{\n" -" int bla;\n" -"};\n" -"#ifdef __cplusplus\n" -"#else\n" -"//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n" -"#define B3_LARGE_FLOAT 1e18f\n" -"#define B3_INFINITY 1e18f\n" -"#define b3Assert(a)\n" -"#define b3ConstArray(a) __global const a*\n" -"#define b3AtomicInc atomic_inc\n" -"#define b3AtomicAdd atomic_add\n" -"#define b3Fabs fabs\n" -"#define b3Sqrt native_sqrt\n" -"#define b3Sin native_sin\n" -"#define b3Cos native_cos\n" -"#define B3_STATIC\n" -"#endif\n" -"#endif\n" -"#ifdef __cplusplus\n" -"#else\n" -" typedef float4 b3Float4;\n" -" #define b3Float4ConstArg const b3Float4\n" -" #define b3MakeFloat4 (float4)\n" -" float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" -" {\n" -" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" -" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" -" return dot(a1, b1);\n" -" }\n" -" b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" -" {\n" -" float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" -" float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" -" return cross(a1, b1);\n" -" }\n" -" #define b3MinFloat4 min\n" -" #define b3MaxFloat4 max\n" -" #define b3Normalized(a) normalize(a)\n" -"#endif \n" -" \n" -"inline bool b3IsAlmostZero(b3Float4ConstArg v)\n" -"{\n" -" if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" -" return false;\n" -" return true;\n" -"}\n" -"inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" -"{\n" -" float maxDot = -B3_INFINITY;\n" -" int i = 0;\n" -" int ptIndex = -1;\n" -" for( i = 0; i < vecLen; i++ )\n" -" {\n" -" float dot = b3Dot3F4(vecArray[i],vec);\n" -" \n" -" if( dot > maxDot )\n" -" {\n" -" maxDot = dot;\n" -" ptIndex = i;\n" -" }\n" -" }\n" -" b3Assert(ptIndex>=0);\n" -" if (ptIndex<0)\n" -" {\n" -" ptIndex = 0;\n" -" }\n" -" *dotOut = maxDot;\n" -" return ptIndex;\n" -"}\n" -"#endif //B3_FLOAT4_H\n" -"#ifndef B3_MAT3x3_H\n" -"#define B3_MAT3x3_H\n" -"#ifndef B3_QUAT_H\n" -"#define B3_QUAT_H\n" -"#ifndef B3_PLATFORM_DEFINITIONS_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif\n" -"#endif\n" -"#ifndef B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -" typedef float4 b3Quat;\n" -" #define b3QuatConstArg const b3Quat\n" -" \n" -" \n" -"inline float4 b3FastNormalize4(float4 v)\n" -"{\n" -" v = (float4)(v.xyz,0.f);\n" -" return fast_normalize(v);\n" -"}\n" -" \n" -"inline b3Quat b3QuatMul(b3Quat a, b3Quat b);\n" -"inline b3Quat b3QuatNormalized(b3QuatConstArg in);\n" -"inline b3Quat b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec);\n" -"inline b3Quat b3QuatInvert(b3QuatConstArg q);\n" -"inline b3Quat b3QuatInverse(b3QuatConstArg q);\n" -"inline b3Quat b3QuatMul(b3QuatConstArg a, b3QuatConstArg b)\n" -"{\n" -" b3Quat ans;\n" -" ans = b3Cross3( a, b );\n" -" ans += a.w*b+b.w*a;\n" -"// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" -" ans.w = a.w*b.w - b3Dot3F4(a, b);\n" -" return ans;\n" -"}\n" -"inline b3Quat b3QuatNormalized(b3QuatConstArg in)\n" -"{\n" -" b3Quat q;\n" -" q=in;\n" -" //return b3FastNormalize4(in);\n" -" float len = native_sqrt(dot(q, q));\n" -" if(len > 0.f)\n" -" {\n" -" q *= 1.f / len;\n" -" }\n" -" else\n" -" {\n" -" q.x = q.y = q.z = 0.f;\n" -" q.w = 1.f;\n" -" }\n" -" return q;\n" -"}\n" -"inline float4 b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" -"{\n" -" b3Quat qInv = b3QuatInvert( q );\n" -" float4 vcpy = vec;\n" -" vcpy.w = 0.f;\n" -" float4 out = b3QuatMul(b3QuatMul(q,vcpy),qInv);\n" -" return out;\n" -"}\n" -"inline b3Quat b3QuatInverse(b3QuatConstArg q)\n" -"{\n" -" return (b3Quat)(-q.xyz, q.w);\n" -"}\n" -"inline b3Quat b3QuatInvert(b3QuatConstArg q)\n" -"{\n" -" return (b3Quat)(-q.xyz, q.w);\n" -"}\n" -"inline float4 b3QuatInvRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" -"{\n" -" return b3QuatRotate( b3QuatInvert( q ), vec );\n" -"}\n" -"inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)\n" -"{\n" -" return b3QuatRotate( orientation, point ) + (translation);\n" -"}\n" -" \n" -"#endif \n" -"#endif //B3_QUAT_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"typedef struct\n" -"{\n" -" b3Float4 m_row[3];\n" -"}b3Mat3x3;\n" -"#define b3Mat3x3ConstArg const b3Mat3x3\n" -"#define b3GetRow(m,row) (m.m_row[row])\n" -"inline b3Mat3x3 b3QuatGetRotationMatrix(b3Quat quat)\n" -"{\n" -" b3Float4 quat2 = (b3Float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f);\n" -" b3Mat3x3 out;\n" -" out.m_row[0].x=1-2*quat2.y-2*quat2.z;\n" -" out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z;\n" -" out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y;\n" -" out.m_row[0].w = 0.f;\n" -" out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z;\n" -" out.m_row[1].y=1-2*quat2.x-2*quat2.z;\n" -" out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x;\n" -" out.m_row[1].w = 0.f;\n" -" out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y;\n" -" out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x;\n" -" out.m_row[2].z=1-2*quat2.x-2*quat2.y;\n" -" out.m_row[2].w = 0.f;\n" -" return out;\n" -"}\n" -"inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg matIn)\n" -"{\n" -" b3Mat3x3 out;\n" -" out.m_row[0] = fabs(matIn.m_row[0]);\n" -" out.m_row[1] = fabs(matIn.m_row[1]);\n" -" out.m_row[2] = fabs(matIn.m_row[2]);\n" -" return out;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtZero();\n" -"__inline\n" -"b3Mat3x3 mtIdentity();\n" -"__inline\n" -"b3Mat3x3 mtTranspose(b3Mat3x3 m);\n" -"__inline\n" -"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b);\n" -"__inline\n" -"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b);\n" -"__inline\n" -"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b);\n" -"__inline\n" -"b3Mat3x3 mtZero()\n" -"{\n" -" b3Mat3x3 m;\n" -" m.m_row[0] = (b3Float4)(0.f);\n" -" m.m_row[1] = (b3Float4)(0.f);\n" -" m.m_row[2] = (b3Float4)(0.f);\n" -" return m;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtIdentity()\n" -"{\n" -" b3Mat3x3 m;\n" -" m.m_row[0] = (b3Float4)(1,0,0,0);\n" -" m.m_row[1] = (b3Float4)(0,1,0,0);\n" -" m.m_row[2] = (b3Float4)(0,0,1,0);\n" -" return m;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtTranspose(b3Mat3x3 m)\n" -"{\n" -" b3Mat3x3 out;\n" -" out.m_row[0] = (b3Float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n" -" out.m_row[1] = (b3Float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n" -" out.m_row[2] = (b3Float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n" -" return out;\n" -"}\n" -"__inline\n" -"b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b)\n" -"{\n" -" b3Mat3x3 transB;\n" -" transB = mtTranspose( b );\n" -" b3Mat3x3 ans;\n" -" // why this doesn't run when 0ing in the for{}\n" -" a.m_row[0].w = 0.f;\n" -" a.m_row[1].w = 0.f;\n" -" a.m_row[2].w = 0.f;\n" -" for(int i=0; i<3; i++)\n" -" {\n" -"// a.m_row[i].w = 0.f;\n" -" ans.m_row[i].x = b3Dot3F4(a.m_row[i],transB.m_row[0]);\n" -" ans.m_row[i].y = b3Dot3F4(a.m_row[i],transB.m_row[1]);\n" -" ans.m_row[i].z = b3Dot3F4(a.m_row[i],transB.m_row[2]);\n" -" ans.m_row[i].w = 0.f;\n" -" }\n" -" return ans;\n" -"}\n" -"__inline\n" -"b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b)\n" -"{\n" -" b3Float4 ans;\n" -" ans.x = b3Dot3F4( a.m_row[0], b );\n" -" ans.y = b3Dot3F4( a.m_row[1], b );\n" -" ans.z = b3Dot3F4( a.m_row[2], b );\n" -" ans.w = 0.f;\n" -" return ans;\n" -"}\n" -"__inline\n" -"b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b)\n" -"{\n" -" b3Float4 colx = b3MakeFloat4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" -" b3Float4 coly = b3MakeFloat4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" -" b3Float4 colz = b3MakeFloat4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" -" b3Float4 ans;\n" -" ans.x = b3Dot3F4( a, colx );\n" -" ans.y = b3Dot3F4( a, coly );\n" -" ans.z = b3Dot3F4( a, colz );\n" -" return ans;\n" -"}\n" -"#endif\n" -"#endif //B3_MAT3x3_H\n" -"typedef struct b3Aabb b3Aabb_t;\n" -"struct b3Aabb\n" -"{\n" -" union\n" -" {\n" -" float m_min[4];\n" -" b3Float4 m_minVec;\n" -" int m_minIndices[4];\n" -" };\n" -" union\n" -" {\n" -" float m_max[4];\n" -" b3Float4 m_maxVec;\n" -" int m_signedMaxIndices[4];\n" -" };\n" -"};\n" -"inline void b3TransformAabb2(b3Float4ConstArg localAabbMin,b3Float4ConstArg localAabbMax, float margin,\n" -" b3Float4ConstArg pos,\n" -" b3QuatConstArg orn,\n" -" b3Float4* aabbMinOut,b3Float4* aabbMaxOut)\n" -"{\n" -" b3Float4 localHalfExtents = 0.5f*(localAabbMax-localAabbMin);\n" -" localHalfExtents+=b3MakeFloat4(margin,margin,margin,0.f);\n" -" b3Float4 localCenter = 0.5f*(localAabbMax+localAabbMin);\n" -" b3Mat3x3 m;\n" -" m = b3QuatGetRotationMatrix(orn);\n" -" b3Mat3x3 abs_b = b3AbsoluteMat3x3(m);\n" -" b3Float4 center = b3TransformPoint(localCenter,pos,orn);\n" -" \n" -" b3Float4 extent = b3MakeFloat4(b3Dot3F4(localHalfExtents,b3GetRow(abs_b,0)),\n" -" b3Dot3F4(localHalfExtents,b3GetRow(abs_b,1)),\n" -" b3Dot3F4(localHalfExtents,b3GetRow(abs_b,2)),\n" -" 0.f);\n" -" *aabbMinOut = center-extent;\n" -" *aabbMaxOut = center+extent;\n" -"}\n" -"/// conservative test for overlap between two aabbs\n" -"inline bool b3TestAabbAgainstAabb(b3Float4ConstArg aabbMin1,b3Float4ConstArg aabbMax1,\n" -" b3Float4ConstArg aabbMin2, b3Float4ConstArg aabbMax2)\n" -"{\n" -" bool overlap = true;\n" -" overlap = (aabbMin1.x > aabbMax2.x || aabbMax1.x < aabbMin2.x) ? false : overlap;\n" -" overlap = (aabbMin1.z > aabbMax2.z || aabbMax1.z < aabbMin2.z) ? false : overlap;\n" -" overlap = (aabbMin1.y > aabbMax2.y || aabbMax1.y < aabbMin2.y) ? false : overlap;\n" -" return overlap;\n" -"}\n" -"#endif //B3_AABB_H\n" -"#ifndef B3_COLLIDABLE_H\n" -"#define B3_COLLIDABLE_H\n" -"#ifndef B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_FLOAT4_H\n" -"#ifndef B3_QUAT_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_QUAT_H\n" -"enum b3ShapeTypes\n" -"{\n" -" SHAPE_HEIGHT_FIELD=1,\n" -" SHAPE_CONVEX_HULL=3,\n" -" SHAPE_PLANE=4,\n" -" SHAPE_CONCAVE_TRIMESH=5,\n" -" SHAPE_COMPOUND_OF_CONVEX_HULLS=6,\n" -" SHAPE_SPHERE=7,\n" -" MAX_NUM_SHAPE_TYPES,\n" -"};\n" -"typedef struct b3Collidable b3Collidable_t;\n" -"struct b3Collidable\n" -"{\n" -" union {\n" -" int m_numChildShapes;\n" -" int m_bvhIndex;\n" -" };\n" -" union\n" -" {\n" -" float m_radius;\n" -" int m_compoundBvhIndex;\n" -" };\n" -" int m_shapeType;\n" -" union\n" -" {\n" -" int m_shapeIndex;\n" -" float m_height;\n" -" };\n" -"};\n" -"typedef struct b3GpuChildShape b3GpuChildShape_t;\n" -"struct b3GpuChildShape\n" -"{\n" -" b3Float4 m_childPosition;\n" -" b3Quat m_childOrientation;\n" -" union\n" -" {\n" -" int m_shapeIndex;//used for SHAPE_COMPOUND_OF_CONVEX_HULLS\n" -" int m_capsuleAxis;\n" -" };\n" -" union \n" -" {\n" -" float m_radius;//used for childshape of SHAPE_COMPOUND_OF_SPHERES or SHAPE_COMPOUND_OF_CAPSULES\n" -" int m_numChildShapes;//used for compound shape\n" -" };\n" -" union \n" -" {\n" -" float m_height;//used for childshape of SHAPE_COMPOUND_OF_CAPSULES\n" -" int m_collidableShapeIndex;\n" -" };\n" -" int m_shapeType;\n" -"};\n" -"struct b3CompoundOverlappingPair\n" -"{\n" -" int m_bodyIndexA;\n" -" int m_bodyIndexB;\n" -"// int m_pairType;\n" -" int m_childShapeIndexA;\n" -" int m_childShapeIndexB;\n" -"};\n" -"#endif //B3_COLLIDABLE_H\n" -"#ifndef B3_RIGIDBODY_DATA_H\n" -"#define B3_RIGIDBODY_DATA_H\n" -"#ifndef B3_FLOAT4_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_FLOAT4_H\n" -"#ifndef B3_QUAT_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif \n" -"#endif //B3_QUAT_H\n" -"#ifndef B3_MAT3x3_H\n" -"#ifdef __cplusplus\n" -"#else\n" -"#endif\n" -"#endif //B3_MAT3x3_H\n" -"typedef struct b3RigidBodyData b3RigidBodyData_t;\n" -"struct b3RigidBodyData\n" -"{\n" -" b3Float4 m_pos;\n" -" b3Quat m_quat;\n" -" b3Float4 m_linVel;\n" -" b3Float4 m_angVel;\n" -" int m_collidableIdx;\n" -" float m_invMass;\n" -" float m_restituitionCoeff;\n" -" float m_frictionCoeff;\n" -"};\n" -"typedef struct b3InertiaData b3InertiaData_t;\n" -"struct b3InertiaData\n" -"{\n" -" b3Mat3x3 m_invInertiaWorld;\n" -" b3Mat3x3 m_initInvInertia;\n" -"};\n" -"#endif //B3_RIGIDBODY_DATA_H\n" -" \n" -"void b3ComputeWorldAabb( int bodyId, __global const b3RigidBodyData_t* bodies, __global const b3Collidable_t* collidables, __global const b3Aabb_t* localShapeAABB, __global b3Aabb_t* worldAabbs)\n" -"{\n" -" __global const b3RigidBodyData_t* body = &bodies[bodyId];\n" -" b3Float4 position = body->m_pos;\n" -" b3Quat orientation = body->m_quat;\n" -" \n" -" int collidableIndex = body->m_collidableIdx;\n" -" int shapeIndex = collidables[collidableIndex].m_shapeIndex;\n" -" \n" -" if (shapeIndex>=0)\n" -" {\n" -" \n" -" b3Aabb_t localAabb = localShapeAABB[collidableIndex];\n" -" b3Aabb_t worldAabb;\n" -" \n" -" b3Float4 aabbAMinOut,aabbAMaxOut; \n" -" float margin = 0.f;\n" -" b3TransformAabb2(localAabb.m_minVec,localAabb.m_maxVec,margin,position,orientation,&aabbAMinOut,&aabbAMaxOut);\n" -" \n" -" worldAabb.m_minVec =aabbAMinOut;\n" -" worldAabb.m_minIndices[3] = bodyId;\n" -" worldAabb.m_maxVec = aabbAMaxOut;\n" -" worldAabb.m_signedMaxIndices[3] = body[bodyId].m_invMass==0.f? 0 : 1;\n" -" worldAabbs[bodyId] = worldAabb;\n" -" }\n" -"}\n" -"#endif //B3_UPDATE_AABBS_H\n" -"__kernel void initializeGpuAabbsFull( const int numNodes, __global b3RigidBodyData_t* gBodies,__global b3Collidable_t* collidables, __global b3Aabb_t* plocalShapeAABB, __global b3Aabb_t* pAABB)\n" -"{\n" -" int nodeID = get_global_id(0);\n" -" if( nodeID < numNodes )\n" -" {\n" -" b3ComputeWorldAabb(nodeID, gBodies, collidables, plocalShapeAABB,pAABB);\n" -" }\n" -"}\n" -"__kernel void clearOverlappingPairsKernel( __global int4* pairs, int numPairs)\n" -"{\n" -" int pairId = get_global_id(0);\n" -" if( pairId< numPairs )\n" -" {\n" -" pairs[pairId].z = 0xffffffff;\n" -" }\n" -"}\n" -; +static const char* updateAabbsKernelCL = + "#ifndef B3_UPDATE_AABBS_H\n" + "#define B3_UPDATE_AABBS_H\n" + "#ifndef B3_AABB_H\n" + "#define B3_AABB_H\n" + "#ifndef B3_FLOAT4_H\n" + "#define B3_FLOAT4_H\n" + "#ifndef B3_PLATFORM_DEFINITIONS_H\n" + "#define B3_PLATFORM_DEFINITIONS_H\n" + "struct MyTest\n" + "{\n" + " int bla;\n" + "};\n" + "#ifdef __cplusplus\n" + "#else\n" + "//keep B3_LARGE_FLOAT*B3_LARGE_FLOAT < FLT_MAX\n" + "#define B3_LARGE_FLOAT 1e18f\n" + "#define B3_INFINITY 1e18f\n" + "#define b3Assert(a)\n" + "#define b3ConstArray(a) __global const a*\n" + "#define b3AtomicInc atomic_inc\n" + "#define b3AtomicAdd atomic_add\n" + "#define b3Fabs fabs\n" + "#define b3Sqrt native_sqrt\n" + "#define b3Sin native_sin\n" + "#define b3Cos native_cos\n" + "#define B3_STATIC\n" + "#endif\n" + "#endif\n" + "#ifdef __cplusplus\n" + "#else\n" + " typedef float4 b3Float4;\n" + " #define b3Float4ConstArg const b3Float4\n" + " #define b3MakeFloat4 (float4)\n" + " float b3Dot3F4(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" + " {\n" + " float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" + " float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" + " return dot(a1, b1);\n" + " }\n" + " b3Float4 b3Cross3(b3Float4ConstArg v0,b3Float4ConstArg v1)\n" + " {\n" + " float4 a1 = b3MakeFloat4(v0.xyz,0.f);\n" + " float4 b1 = b3MakeFloat4(v1.xyz,0.f);\n" + " return cross(a1, b1);\n" + " }\n" + " #define b3MinFloat4 min\n" + " #define b3MaxFloat4 max\n" + " #define b3Normalized(a) normalize(a)\n" + "#endif \n" + " \n" + "inline bool b3IsAlmostZero(b3Float4ConstArg v)\n" + "{\n" + " if(b3Fabs(v.x)>1e-6 || b3Fabs(v.y)>1e-6 || b3Fabs(v.z)>1e-6) \n" + " return false;\n" + " return true;\n" + "}\n" + "inline int b3MaxDot( b3Float4ConstArg vec, __global const b3Float4* vecArray, int vecLen, float* dotOut )\n" + "{\n" + " float maxDot = -B3_INFINITY;\n" + " int i = 0;\n" + " int ptIndex = -1;\n" + " for( i = 0; i < vecLen; i++ )\n" + " {\n" + " float dot = b3Dot3F4(vecArray[i],vec);\n" + " \n" + " if( dot > maxDot )\n" + " {\n" + " maxDot = dot;\n" + " ptIndex = i;\n" + " }\n" + " }\n" + " b3Assert(ptIndex>=0);\n" + " if (ptIndex<0)\n" + " {\n" + " ptIndex = 0;\n" + " }\n" + " *dotOut = maxDot;\n" + " return ptIndex;\n" + "}\n" + "#endif //B3_FLOAT4_H\n" + "#ifndef B3_MAT3x3_H\n" + "#define B3_MAT3x3_H\n" + "#ifndef B3_QUAT_H\n" + "#define B3_QUAT_H\n" + "#ifndef B3_PLATFORM_DEFINITIONS_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif\n" + "#endif\n" + "#ifndef B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + " typedef float4 b3Quat;\n" + " #define b3QuatConstArg const b3Quat\n" + " \n" + " \n" + "inline float4 b3FastNormalize4(float4 v)\n" + "{\n" + " v = (float4)(v.xyz,0.f);\n" + " return fast_normalize(v);\n" + "}\n" + " \n" + "inline b3Quat b3QuatMul(b3Quat a, b3Quat b);\n" + "inline b3Quat b3QuatNormalized(b3QuatConstArg in);\n" + "inline b3Quat b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec);\n" + "inline b3Quat b3QuatInvert(b3QuatConstArg q);\n" + "inline b3Quat b3QuatInverse(b3QuatConstArg q);\n" + "inline b3Quat b3QuatMul(b3QuatConstArg a, b3QuatConstArg b)\n" + "{\n" + " b3Quat ans;\n" + " ans = b3Cross3( a, b );\n" + " ans += a.w*b+b.w*a;\n" + "// ans.w = a.w*b.w - (a.x*b.x+a.y*b.y+a.z*b.z);\n" + " ans.w = a.w*b.w - b3Dot3F4(a, b);\n" + " return ans;\n" + "}\n" + "inline b3Quat b3QuatNormalized(b3QuatConstArg in)\n" + "{\n" + " b3Quat q;\n" + " q=in;\n" + " //return b3FastNormalize4(in);\n" + " float len = native_sqrt(dot(q, q));\n" + " if(len > 0.f)\n" + " {\n" + " q *= 1.f / len;\n" + " }\n" + " else\n" + " {\n" + " q.x = q.y = q.z = 0.f;\n" + " q.w = 1.f;\n" + " }\n" + " return q;\n" + "}\n" + "inline float4 b3QuatRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" + "{\n" + " b3Quat qInv = b3QuatInvert( q );\n" + " float4 vcpy = vec;\n" + " vcpy.w = 0.f;\n" + " float4 out = b3QuatMul(b3QuatMul(q,vcpy),qInv);\n" + " return out;\n" + "}\n" + "inline b3Quat b3QuatInverse(b3QuatConstArg q)\n" + "{\n" + " return (b3Quat)(-q.xyz, q.w);\n" + "}\n" + "inline b3Quat b3QuatInvert(b3QuatConstArg q)\n" + "{\n" + " return (b3Quat)(-q.xyz, q.w);\n" + "}\n" + "inline float4 b3QuatInvRotate(b3QuatConstArg q, b3QuatConstArg vec)\n" + "{\n" + " return b3QuatRotate( b3QuatInvert( q ), vec );\n" + "}\n" + "inline b3Float4 b3TransformPoint(b3Float4ConstArg point, b3Float4ConstArg translation, b3QuatConstArg orientation)\n" + "{\n" + " return b3QuatRotate( orientation, point ) + (translation);\n" + "}\n" + " \n" + "#endif \n" + "#endif //B3_QUAT_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "typedef struct\n" + "{\n" + " b3Float4 m_row[3];\n" + "}b3Mat3x3;\n" + "#define b3Mat3x3ConstArg const b3Mat3x3\n" + "#define b3GetRow(m,row) (m.m_row[row])\n" + "inline b3Mat3x3 b3QuatGetRotationMatrix(b3Quat quat)\n" + "{\n" + " b3Float4 quat2 = (b3Float4)(quat.x*quat.x, quat.y*quat.y, quat.z*quat.z, 0.f);\n" + " b3Mat3x3 out;\n" + " out.m_row[0].x=1-2*quat2.y-2*quat2.z;\n" + " out.m_row[0].y=2*quat.x*quat.y-2*quat.w*quat.z;\n" + " out.m_row[0].z=2*quat.x*quat.z+2*quat.w*quat.y;\n" + " out.m_row[0].w = 0.f;\n" + " out.m_row[1].x=2*quat.x*quat.y+2*quat.w*quat.z;\n" + " out.m_row[1].y=1-2*quat2.x-2*quat2.z;\n" + " out.m_row[1].z=2*quat.y*quat.z-2*quat.w*quat.x;\n" + " out.m_row[1].w = 0.f;\n" + " out.m_row[2].x=2*quat.x*quat.z-2*quat.w*quat.y;\n" + " out.m_row[2].y=2*quat.y*quat.z+2*quat.w*quat.x;\n" + " out.m_row[2].z=1-2*quat2.x-2*quat2.y;\n" + " out.m_row[2].w = 0.f;\n" + " return out;\n" + "}\n" + "inline b3Mat3x3 b3AbsoluteMat3x3(b3Mat3x3ConstArg matIn)\n" + "{\n" + " b3Mat3x3 out;\n" + " out.m_row[0] = fabs(matIn.m_row[0]);\n" + " out.m_row[1] = fabs(matIn.m_row[1]);\n" + " out.m_row[2] = fabs(matIn.m_row[2]);\n" + " return out;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtZero();\n" + "__inline\n" + "b3Mat3x3 mtIdentity();\n" + "__inline\n" + "b3Mat3x3 mtTranspose(b3Mat3x3 m);\n" + "__inline\n" + "b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b);\n" + "__inline\n" + "b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b);\n" + "__inline\n" + "b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b);\n" + "__inline\n" + "b3Mat3x3 mtZero()\n" + "{\n" + " b3Mat3x3 m;\n" + " m.m_row[0] = (b3Float4)(0.f);\n" + " m.m_row[1] = (b3Float4)(0.f);\n" + " m.m_row[2] = (b3Float4)(0.f);\n" + " return m;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtIdentity()\n" + "{\n" + " b3Mat3x3 m;\n" + " m.m_row[0] = (b3Float4)(1,0,0,0);\n" + " m.m_row[1] = (b3Float4)(0,1,0,0);\n" + " m.m_row[2] = (b3Float4)(0,0,1,0);\n" + " return m;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtTranspose(b3Mat3x3 m)\n" + "{\n" + " b3Mat3x3 out;\n" + " out.m_row[0] = (b3Float4)(m.m_row[0].x, m.m_row[1].x, m.m_row[2].x, 0.f);\n" + " out.m_row[1] = (b3Float4)(m.m_row[0].y, m.m_row[1].y, m.m_row[2].y, 0.f);\n" + " out.m_row[2] = (b3Float4)(m.m_row[0].z, m.m_row[1].z, m.m_row[2].z, 0.f);\n" + " return out;\n" + "}\n" + "__inline\n" + "b3Mat3x3 mtMul(b3Mat3x3 a, b3Mat3x3 b)\n" + "{\n" + " b3Mat3x3 transB;\n" + " transB = mtTranspose( b );\n" + " b3Mat3x3 ans;\n" + " // why this doesn't run when 0ing in the for{}\n" + " a.m_row[0].w = 0.f;\n" + " a.m_row[1].w = 0.f;\n" + " a.m_row[2].w = 0.f;\n" + " for(int i=0; i<3; i++)\n" + " {\n" + "// a.m_row[i].w = 0.f;\n" + " ans.m_row[i].x = b3Dot3F4(a.m_row[i],transB.m_row[0]);\n" + " ans.m_row[i].y = b3Dot3F4(a.m_row[i],transB.m_row[1]);\n" + " ans.m_row[i].z = b3Dot3F4(a.m_row[i],transB.m_row[2]);\n" + " ans.m_row[i].w = 0.f;\n" + " }\n" + " return ans;\n" + "}\n" + "__inline\n" + "b3Float4 mtMul1(b3Mat3x3 a, b3Float4 b)\n" + "{\n" + " b3Float4 ans;\n" + " ans.x = b3Dot3F4( a.m_row[0], b );\n" + " ans.y = b3Dot3F4( a.m_row[1], b );\n" + " ans.z = b3Dot3F4( a.m_row[2], b );\n" + " ans.w = 0.f;\n" + " return ans;\n" + "}\n" + "__inline\n" + "b3Float4 mtMul3(b3Float4 a, b3Mat3x3 b)\n" + "{\n" + " b3Float4 colx = b3MakeFloat4(b.m_row[0].x, b.m_row[1].x, b.m_row[2].x, 0);\n" + " b3Float4 coly = b3MakeFloat4(b.m_row[0].y, b.m_row[1].y, b.m_row[2].y, 0);\n" + " b3Float4 colz = b3MakeFloat4(b.m_row[0].z, b.m_row[1].z, b.m_row[2].z, 0);\n" + " b3Float4 ans;\n" + " ans.x = b3Dot3F4( a, colx );\n" + " ans.y = b3Dot3F4( a, coly );\n" + " ans.z = b3Dot3F4( a, colz );\n" + " return ans;\n" + "}\n" + "#endif\n" + "#endif //B3_MAT3x3_H\n" + "typedef struct b3Aabb b3Aabb_t;\n" + "struct b3Aabb\n" + "{\n" + " union\n" + " {\n" + " float m_min[4];\n" + " b3Float4 m_minVec;\n" + " int m_minIndices[4];\n" + " };\n" + " union\n" + " {\n" + " float m_max[4];\n" + " b3Float4 m_maxVec;\n" + " int m_signedMaxIndices[4];\n" + " };\n" + "};\n" + "inline void b3TransformAabb2(b3Float4ConstArg localAabbMin,b3Float4ConstArg localAabbMax, float margin,\n" + " b3Float4ConstArg pos,\n" + " b3QuatConstArg orn,\n" + " b3Float4* aabbMinOut,b3Float4* aabbMaxOut)\n" + "{\n" + " b3Float4 localHalfExtents = 0.5f*(localAabbMax-localAabbMin);\n" + " localHalfExtents+=b3MakeFloat4(margin,margin,margin,0.f);\n" + " b3Float4 localCenter = 0.5f*(localAabbMax+localAabbMin);\n" + " b3Mat3x3 m;\n" + " m = b3QuatGetRotationMatrix(orn);\n" + " b3Mat3x3 abs_b = b3AbsoluteMat3x3(m);\n" + " b3Float4 center = b3TransformPoint(localCenter,pos,orn);\n" + " \n" + " b3Float4 extent = b3MakeFloat4(b3Dot3F4(localHalfExtents,b3GetRow(abs_b,0)),\n" + " b3Dot3F4(localHalfExtents,b3GetRow(abs_b,1)),\n" + " b3Dot3F4(localHalfExtents,b3GetRow(abs_b,2)),\n" + " 0.f);\n" + " *aabbMinOut = center-extent;\n" + " *aabbMaxOut = center+extent;\n" + "}\n" + "/// conservative test for overlap between two aabbs\n" + "inline bool b3TestAabbAgainstAabb(b3Float4ConstArg aabbMin1,b3Float4ConstArg aabbMax1,\n" + " b3Float4ConstArg aabbMin2, b3Float4ConstArg aabbMax2)\n" + "{\n" + " bool overlap = true;\n" + " overlap = (aabbMin1.x > aabbMax2.x || aabbMax1.x < aabbMin2.x) ? false : overlap;\n" + " overlap = (aabbMin1.z > aabbMax2.z || aabbMax1.z < aabbMin2.z) ? false : overlap;\n" + " overlap = (aabbMin1.y > aabbMax2.y || aabbMax1.y < aabbMin2.y) ? false : overlap;\n" + " return overlap;\n" + "}\n" + "#endif //B3_AABB_H\n" + "#ifndef B3_COLLIDABLE_H\n" + "#define B3_COLLIDABLE_H\n" + "#ifndef B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_FLOAT4_H\n" + "#ifndef B3_QUAT_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_QUAT_H\n" + "enum b3ShapeTypes\n" + "{\n" + " SHAPE_HEIGHT_FIELD=1,\n" + " SHAPE_CONVEX_HULL=3,\n" + " SHAPE_PLANE=4,\n" + " SHAPE_CONCAVE_TRIMESH=5,\n" + " SHAPE_COMPOUND_OF_CONVEX_HULLS=6,\n" + " SHAPE_SPHERE=7,\n" + " MAX_NUM_SHAPE_TYPES,\n" + "};\n" + "typedef struct b3Collidable b3Collidable_t;\n" + "struct b3Collidable\n" + "{\n" + " union {\n" + " int m_numChildShapes;\n" + " int m_bvhIndex;\n" + " };\n" + " union\n" + " {\n" + " float m_radius;\n" + " int m_compoundBvhIndex;\n" + " };\n" + " int m_shapeType;\n" + " union\n" + " {\n" + " int m_shapeIndex;\n" + " float m_height;\n" + " };\n" + "};\n" + "typedef struct b3GpuChildShape b3GpuChildShape_t;\n" + "struct b3GpuChildShape\n" + "{\n" + " b3Float4 m_childPosition;\n" + " b3Quat m_childOrientation;\n" + " union\n" + " {\n" + " int m_shapeIndex;//used for SHAPE_COMPOUND_OF_CONVEX_HULLS\n" + " int m_capsuleAxis;\n" + " };\n" + " union \n" + " {\n" + " float m_radius;//used for childshape of SHAPE_COMPOUND_OF_SPHERES or SHAPE_COMPOUND_OF_CAPSULES\n" + " int m_numChildShapes;//used for compound shape\n" + " };\n" + " union \n" + " {\n" + " float m_height;//used for childshape of SHAPE_COMPOUND_OF_CAPSULES\n" + " int m_collidableShapeIndex;\n" + " };\n" + " int m_shapeType;\n" + "};\n" + "struct b3CompoundOverlappingPair\n" + "{\n" + " int m_bodyIndexA;\n" + " int m_bodyIndexB;\n" + "// int m_pairType;\n" + " int m_childShapeIndexA;\n" + " int m_childShapeIndexB;\n" + "};\n" + "#endif //B3_COLLIDABLE_H\n" + "#ifndef B3_RIGIDBODY_DATA_H\n" + "#define B3_RIGIDBODY_DATA_H\n" + "#ifndef B3_FLOAT4_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_FLOAT4_H\n" + "#ifndef B3_QUAT_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif \n" + "#endif //B3_QUAT_H\n" + "#ifndef B3_MAT3x3_H\n" + "#ifdef __cplusplus\n" + "#else\n" + "#endif\n" + "#endif //B3_MAT3x3_H\n" + "typedef struct b3RigidBodyData b3RigidBodyData_t;\n" + "struct b3RigidBodyData\n" + "{\n" + " b3Float4 m_pos;\n" + " b3Quat m_quat;\n" + " b3Float4 m_linVel;\n" + " b3Float4 m_angVel;\n" + " int m_collidableIdx;\n" + " float m_invMass;\n" + " float m_restituitionCoeff;\n" + " float m_frictionCoeff;\n" + "};\n" + "typedef struct b3InertiaData b3InertiaData_t;\n" + "struct b3InertiaData\n" + "{\n" + " b3Mat3x3 m_invInertiaWorld;\n" + " b3Mat3x3 m_initInvInertia;\n" + "};\n" + "#endif //B3_RIGIDBODY_DATA_H\n" + " \n" + "void b3ComputeWorldAabb( int bodyId, __global const b3RigidBodyData_t* bodies, __global const b3Collidable_t* collidables, __global const b3Aabb_t* localShapeAABB, __global b3Aabb_t* worldAabbs)\n" + "{\n" + " __global const b3RigidBodyData_t* body = &bodies[bodyId];\n" + " b3Float4 position = body->m_pos;\n" + " b3Quat orientation = body->m_quat;\n" + " \n" + " int collidableIndex = body->m_collidableIdx;\n" + " int shapeIndex = collidables[collidableIndex].m_shapeIndex;\n" + " \n" + " if (shapeIndex>=0)\n" + " {\n" + " \n" + " b3Aabb_t localAabb = localShapeAABB[collidableIndex];\n" + " b3Aabb_t worldAabb;\n" + " \n" + " b3Float4 aabbAMinOut,aabbAMaxOut; \n" + " float margin = 0.f;\n" + " b3TransformAabb2(localAabb.m_minVec,localAabb.m_maxVec,margin,position,orientation,&aabbAMinOut,&aabbAMaxOut);\n" + " \n" + " worldAabb.m_minVec =aabbAMinOut;\n" + " worldAabb.m_minIndices[3] = bodyId;\n" + " worldAabb.m_maxVec = aabbAMaxOut;\n" + " worldAabb.m_signedMaxIndices[3] = body[bodyId].m_invMass==0.f? 0 : 1;\n" + " worldAabbs[bodyId] = worldAabb;\n" + " }\n" + "}\n" + "#endif //B3_UPDATE_AABBS_H\n" + "__kernel void initializeGpuAabbsFull( const int numNodes, __global b3RigidBodyData_t* gBodies,__global b3Collidable_t* collidables, __global b3Aabb_t* plocalShapeAABB, __global b3Aabb_t* pAABB)\n" + "{\n" + " int nodeID = get_global_id(0);\n" + " if( nodeID < numNodes )\n" + " {\n" + " b3ComputeWorldAabb(nodeID, gBodies, collidables, plocalShapeAABB,pAABB);\n" + " }\n" + "}\n" + "__kernel void clearOverlappingPairsKernel( __global int4* pairs, int numPairs)\n" + "{\n" + " int pairId = get_global_id(0);\n" + " if( pairId< numPairs )\n" + " {\n" + " pairs[pairId].z = 0xffffffff;\n" + " }\n" + "}\n"; diff --git a/src/Bullet3Serialize/Bullet2FileLoader/autogenerated/bullet2.h b/src/Bullet3Serialize/Bullet2FileLoader/autogenerated/bullet2.h index a6b57b1a1..eaa27dfe8 100644 --- a/src/Bullet3Serialize/Bullet2FileLoader/autogenerated/bullet2.h +++ b/src/Bullet3Serialize/Bullet2FileLoader/autogenerated/bullet2.h @@ -19,1035 +19,969 @@ // Auto generated from Bullet/Extras/HeaderGenerator/bulletGenerate.py #ifndef __BULLET2_H__ #define __BULLET2_H__ -namespace Bullet3SerializeBullet2 { - +namespace Bullet3SerializeBullet2 +{ // put an empty struct in the case -typedef struct bInvalidHandle { +typedef struct bInvalidHandle +{ int unused; -}bInvalidHandle; +} bInvalidHandle; - class PointerArray; - class b3PhysicsSystem; - class ListBase; - class b3Vector3FloatData; - class b3Vector3DoubleData; - class b3Matrix3x3FloatData; - class b3Matrix3x3DoubleData; - class b3TransformFloatData; - class b3TransformDoubleData; - class b3BvhSubtreeInfoData; - class b3OptimizedBvhNodeFloatData; - class b3OptimizedBvhNodeDoubleData; - class b3QuantizedBvhNodeData; - class b3QuantizedBvhFloatData; - class b3QuantizedBvhDoubleData; - class b3CollisionShapeData; - class b3StaticPlaneShapeData; - class b3ConvexInternalShapeData; - class b3PositionAndRadius; - class b3MultiSphereShapeData; - class b3IntIndexData; - class b3ShortIntIndexData; - class b3ShortIntIndexTripletData; - class b3CharIndexTripletData; - class b3MeshPartData; - class b3StridingMeshInterfaceData; - class b3TriangleMeshShapeData; - class b3ScaledTriangleMeshShapeData; - class b3CompoundShapeChildData; - class b3CompoundShapeData; - class b3CylinderShapeData; - class b3CapsuleShapeData; - class b3TriangleInfoData; - class b3TriangleInfoMapData; - class b3GImpactMeshShapeData; - class b3ConvexHullShapeData; - class b3CollisionObjectDoubleData; - class b3CollisionObjectFloatData; - class b3DynamicsWorldDoubleData; - class b3DynamicsWorldFloatData; - class b3RigidBodyFloatData; - class b3RigidBodyDoubleData; - class b3ConstraintInfo1; - class b3TypedConstraintData; - class b3Point2PointConstraintFloatData; - class b3Point2PointConstraintDoubleData; - class b3HingeConstraintDoubleData; - class b3HingeConstraintFloatData; - class b3ConeTwistConstraintData; - class b3Generic6DofConstraintData; - class b3Generic6DofSpringConstraintData; - class b3SliderConstraintData; - class b3ContactSolverInfoDoubleData; - class b3ContactSolverInfoFloatData; - class SoftBodyMaterialData; - class SoftBodyNodeData; - class SoftBodyLinkData; - class SoftBodyFaceData; - class SoftBodyTetraData; - class SoftRigidAnchorData; - class SoftBodyConfigData; - class SoftBodyPoseData; - class SoftBodyClusterData; - class b3SoftBodyJointData; - class b3SoftBodyFloatData; +class PointerArray; +class b3PhysicsSystem; +class ListBase; +class b3Vector3FloatData; +class b3Vector3DoubleData; +class b3Matrix3x3FloatData; +class b3Matrix3x3DoubleData; +class b3TransformFloatData; +class b3TransformDoubleData; +class b3BvhSubtreeInfoData; +class b3OptimizedBvhNodeFloatData; +class b3OptimizedBvhNodeDoubleData; +class b3QuantizedBvhNodeData; +class b3QuantizedBvhFloatData; +class b3QuantizedBvhDoubleData; +class b3CollisionShapeData; +class b3StaticPlaneShapeData; +class b3ConvexInternalShapeData; +class b3PositionAndRadius; +class b3MultiSphereShapeData; +class b3IntIndexData; +class b3ShortIntIndexData; +class b3ShortIntIndexTripletData; +class b3CharIndexTripletData; +class b3MeshPartData; +class b3StridingMeshInterfaceData; +class b3TriangleMeshShapeData; +class b3ScaledTriangleMeshShapeData; +class b3CompoundShapeChildData; +class b3CompoundShapeData; +class b3CylinderShapeData; +class b3CapsuleShapeData; +class b3TriangleInfoData; +class b3TriangleInfoMapData; +class b3GImpactMeshShapeData; +class b3ConvexHullShapeData; +class b3CollisionObjectDoubleData; +class b3CollisionObjectFloatData; +class b3DynamicsWorldDoubleData; +class b3DynamicsWorldFloatData; +class b3RigidBodyFloatData; +class b3RigidBodyDoubleData; +class b3ConstraintInfo1; +class b3TypedConstraintData; +class b3Point2PointConstraintFloatData; +class b3Point2PointConstraintDoubleData; +class b3HingeConstraintDoubleData; +class b3HingeConstraintFloatData; +class b3ConeTwistConstraintData; +class b3Generic6DofConstraintData; +class b3Generic6DofSpringConstraintData; +class b3SliderConstraintData; +class b3ContactSolverInfoDoubleData; +class b3ContactSolverInfoFloatData; +class SoftBodyMaterialData; +class SoftBodyNodeData; +class SoftBodyLinkData; +class SoftBodyFaceData; +class SoftBodyTetraData; +class SoftRigidAnchorData; +class SoftBodyConfigData; +class SoftBodyPoseData; +class SoftBodyClusterData; +class b3SoftBodyJointData; +class b3SoftBodyFloatData; // -------------------------------------------------- // - class PointerArray - { - public: - int m_size; - int m_capacity; - void *m_data; - }; - +class PointerArray +{ +public: + int m_size; + int m_capacity; + void *m_data; +}; // -------------------------------------------------- // - class b3PhysicsSystem - { - public: - PointerArray m_collisionShapes; - PointerArray m_collisionObjects; - PointerArray m_constraints; - }; - +class b3PhysicsSystem +{ +public: + PointerArray m_collisionShapes; + PointerArray m_collisionObjects; + PointerArray m_constraints; +}; // -------------------------------------------------- // - class ListBase - { - public: - void *first; - void *last; - }; - +class ListBase +{ +public: + void *first; + void *last; +}; // -------------------------------------------------- // - class b3Vector3FloatData - { - public: - float m_floats[4]; - }; - +class b3Vector3FloatData +{ +public: + float m_floats[4]; +}; // -------------------------------------------------- // - class b3Vector3DoubleData - { - public: - double m_floats[4]; - }; - +class b3Vector3DoubleData +{ +public: + double m_floats[4]; +}; // -------------------------------------------------- // - class b3Matrix3x3FloatData - { - public: - b3Vector3FloatData m_el[3]; - }; - +class b3Matrix3x3FloatData +{ +public: + b3Vector3FloatData m_el[3]; +}; // -------------------------------------------------- // - class b3Matrix3x3DoubleData - { - public: - b3Vector3DoubleData m_el[3]; - }; - +class b3Matrix3x3DoubleData +{ +public: + b3Vector3DoubleData m_el[3]; +}; // -------------------------------------------------- // - class b3TransformFloatData - { - public: - b3Matrix3x3FloatData m_basis; - b3Vector3FloatData m_origin; - }; - +class b3TransformFloatData +{ +public: + b3Matrix3x3FloatData m_basis; + b3Vector3FloatData m_origin; +}; // -------------------------------------------------- // - class b3TransformDoubleData - { - public: - b3Matrix3x3DoubleData m_basis; - b3Vector3DoubleData m_origin; - }; - +class b3TransformDoubleData +{ +public: + b3Matrix3x3DoubleData m_basis; + b3Vector3DoubleData m_origin; +}; // -------------------------------------------------- // - class b3BvhSubtreeInfoData - { - public: - int m_rootNodeIndex; - int m_subtreeSize; - short m_quantizedAabbMin[3]; - short m_quantizedAabbMax[3]; - }; - +class b3BvhSubtreeInfoData +{ +public: + int m_rootNodeIndex; + int m_subtreeSize; + short m_quantizedAabbMin[3]; + short m_quantizedAabbMax[3]; +}; // -------------------------------------------------- // - class b3OptimizedBvhNodeFloatData - { - public: - b3Vector3FloatData m_aabbMinOrg; - b3Vector3FloatData m_aabbMaxOrg; - int m_escapeIndex; - int m_subPart; - int m_triangleIndex; - char m_pad[4]; - }; - +class b3OptimizedBvhNodeFloatData +{ +public: + b3Vector3FloatData m_aabbMinOrg; + b3Vector3FloatData m_aabbMaxOrg; + int m_escapeIndex; + int m_subPart; + int m_triangleIndex; + char m_pad[4]; +}; // -------------------------------------------------- // - class b3OptimizedBvhNodeDoubleData - { - public: - b3Vector3DoubleData m_aabbMinOrg; - b3Vector3DoubleData m_aabbMaxOrg; - int m_escapeIndex; - int m_subPart; - int m_triangleIndex; - char m_pad[4]; - }; - +class b3OptimizedBvhNodeDoubleData +{ +public: + b3Vector3DoubleData m_aabbMinOrg; + b3Vector3DoubleData m_aabbMaxOrg; + int m_escapeIndex; + int m_subPart; + int m_triangleIndex; + char m_pad[4]; +}; // -------------------------------------------------- // - class b3QuantizedBvhNodeData - { - public: - short m_quantizedAabbMin[3]; - short m_quantizedAabbMax[3]; - int m_escapeIndexOrTriangleIndex; - }; - +class b3QuantizedBvhNodeData +{ +public: + short m_quantizedAabbMin[3]; + short m_quantizedAabbMax[3]; + int m_escapeIndexOrTriangleIndex; +}; // -------------------------------------------------- // - class b3QuantizedBvhFloatData - { - public: - b3Vector3FloatData m_bvhAabbMin; - b3Vector3FloatData m_bvhAabbMax; - b3Vector3FloatData m_bvhQuantization; - int m_curNodeIndex; - int m_useQuantization; - int m_numContiguousLeafNodes; - int m_numQuantizedContiguousNodes; - b3OptimizedBvhNodeFloatData *m_contiguousNodesPtr; - b3QuantizedBvhNodeData *m_quantizedContiguousNodesPtr; - b3BvhSubtreeInfoData *m_subTreeInfoPtr; - int m_traversalMode; - int m_numSubtreeHeaders; - }; - +class b3QuantizedBvhFloatData +{ +public: + b3Vector3FloatData m_bvhAabbMin; + b3Vector3FloatData m_bvhAabbMax; + b3Vector3FloatData m_bvhQuantization; + int m_curNodeIndex; + int m_useQuantization; + int m_numContiguousLeafNodes; + int m_numQuantizedContiguousNodes; + b3OptimizedBvhNodeFloatData *m_contiguousNodesPtr; + b3QuantizedBvhNodeData *m_quantizedContiguousNodesPtr; + b3BvhSubtreeInfoData *m_subTreeInfoPtr; + int m_traversalMode; + int m_numSubtreeHeaders; +}; // -------------------------------------------------- // - class b3QuantizedBvhDoubleData - { - public: - b3Vector3DoubleData m_bvhAabbMin; - b3Vector3DoubleData m_bvhAabbMax; - b3Vector3DoubleData m_bvhQuantization; - int m_curNodeIndex; - int m_useQuantization; - int m_numContiguousLeafNodes; - int m_numQuantizedContiguousNodes; - b3OptimizedBvhNodeDoubleData *m_contiguousNodesPtr; - b3QuantizedBvhNodeData *m_quantizedContiguousNodesPtr; - int m_traversalMode; - int m_numSubtreeHeaders; - b3BvhSubtreeInfoData *m_subTreeInfoPtr; - }; - +class b3QuantizedBvhDoubleData +{ +public: + b3Vector3DoubleData m_bvhAabbMin; + b3Vector3DoubleData m_bvhAabbMax; + b3Vector3DoubleData m_bvhQuantization; + int m_curNodeIndex; + int m_useQuantization; + int m_numContiguousLeafNodes; + int m_numQuantizedContiguousNodes; + b3OptimizedBvhNodeDoubleData *m_contiguousNodesPtr; + b3QuantizedBvhNodeData *m_quantizedContiguousNodesPtr; + int m_traversalMode; + int m_numSubtreeHeaders; + b3BvhSubtreeInfoData *m_subTreeInfoPtr; +}; // -------------------------------------------------- // - class b3CollisionShapeData - { - public: - char *m_name; - int m_shapeType; - char m_padding[4]; - }; - +class b3CollisionShapeData +{ +public: + char *m_name; + int m_shapeType; + char m_padding[4]; +}; // -------------------------------------------------- // - class b3StaticPlaneShapeData - { - public: - b3CollisionShapeData m_collisionShapeData; - b3Vector3FloatData m_localScaling; - b3Vector3FloatData m_planeNormal; - float m_planeConstant; - char m_pad[4]; - }; - +class b3StaticPlaneShapeData +{ +public: + b3CollisionShapeData m_collisionShapeData; + b3Vector3FloatData m_localScaling; + b3Vector3FloatData m_planeNormal; + float m_planeConstant; + char m_pad[4]; +}; // -------------------------------------------------- // - class b3ConvexInternalShapeData - { - public: - b3CollisionShapeData m_collisionShapeData; - b3Vector3FloatData m_localScaling; - b3Vector3FloatData m_implicitShapeDimensions; - float m_collisionMargin; - int m_padding; - }; - +class b3ConvexInternalShapeData +{ +public: + b3CollisionShapeData m_collisionShapeData; + b3Vector3FloatData m_localScaling; + b3Vector3FloatData m_implicitShapeDimensions; + float m_collisionMargin; + int m_padding; +}; // -------------------------------------------------- // - class b3PositionAndRadius - { - public: - b3Vector3FloatData m_pos; - float m_radius; - }; - +class b3PositionAndRadius +{ +public: + b3Vector3FloatData m_pos; + float m_radius; +}; // -------------------------------------------------- // - class b3MultiSphereShapeData - { - public: - b3ConvexInternalShapeData m_convexInternalShapeData; - b3PositionAndRadius *m_localPositionArrayPtr; - int m_localPositionArraySize; - char m_padding[4]; - }; - +class b3MultiSphereShapeData +{ +public: + b3ConvexInternalShapeData m_convexInternalShapeData; + b3PositionAndRadius *m_localPositionArrayPtr; + int m_localPositionArraySize; + char m_padding[4]; +}; // -------------------------------------------------- // - class b3IntIndexData - { - public: - int m_value; - }; - +class b3IntIndexData +{ +public: + int m_value; +}; // -------------------------------------------------- // - class b3ShortIntIndexData - { - public: - short m_value; - char m_pad[2]; - }; - +class b3ShortIntIndexData +{ +public: + short m_value; + char m_pad[2]; +}; // -------------------------------------------------- // - class b3ShortIntIndexTripletData - { - public: - short m_values[3]; - char m_pad[2]; - }; - +class b3ShortIntIndexTripletData +{ +public: + short m_values[3]; + char m_pad[2]; +}; // -------------------------------------------------- // - class b3CharIndexTripletData - { - public: - char m_values[3]; - char m_pad; - }; - +class b3CharIndexTripletData +{ +public: + char m_values[3]; + char m_pad; +}; // -------------------------------------------------- // - class b3MeshPartData - { - public: - b3Vector3FloatData *m_vertices3f; - b3Vector3DoubleData *m_vertices3d; - b3IntIndexData *m_indices32; - b3ShortIntIndexTripletData *m_3indices16; - b3CharIndexTripletData *m_3indices8; - b3ShortIntIndexData *m_indices16; - int m_numTriangles; - int m_numVertices; - }; - +class b3MeshPartData +{ +public: + b3Vector3FloatData *m_vertices3f; + b3Vector3DoubleData *m_vertices3d; + b3IntIndexData *m_indices32; + b3ShortIntIndexTripletData *m_3indices16; + b3CharIndexTripletData *m_3indices8; + b3ShortIntIndexData *m_indices16; + int m_numTriangles; + int m_numVertices; +}; // -------------------------------------------------- // - class b3StridingMeshInterfaceData - { - public: - b3MeshPartData *m_meshPartsPtr; - b3Vector3FloatData m_scaling; - int m_numMeshParts; - char m_padding[4]; - }; - +class b3StridingMeshInterfaceData +{ +public: + b3MeshPartData *m_meshPartsPtr; + b3Vector3FloatData m_scaling; + int m_numMeshParts; + char m_padding[4]; +}; // -------------------------------------------------- // - class b3TriangleMeshShapeData - { - public: - b3CollisionShapeData m_collisionShapeData; - b3StridingMeshInterfaceData m_meshInterface; - b3QuantizedBvhFloatData *m_quantizedFloatBvh; - b3QuantizedBvhDoubleData *m_quantizedDoubleBvh; - b3TriangleInfoMapData *m_triangleInfoMap; - float m_collisionMargin; - char m_pad3[4]; - }; - +class b3TriangleMeshShapeData +{ +public: + b3CollisionShapeData m_collisionShapeData; + b3StridingMeshInterfaceData m_meshInterface; + b3QuantizedBvhFloatData *m_quantizedFloatBvh; + b3QuantizedBvhDoubleData *m_quantizedDoubleBvh; + b3TriangleInfoMapData *m_triangleInfoMap; + float m_collisionMargin; + char m_pad3[4]; +}; // -------------------------------------------------- // - class b3ScaledTriangleMeshShapeData - { - public: - b3TriangleMeshShapeData m_trimeshShapeData; - b3Vector3FloatData m_localScaling; - }; - +class b3ScaledTriangleMeshShapeData +{ +public: + b3TriangleMeshShapeData m_trimeshShapeData; + b3Vector3FloatData m_localScaling; +}; // -------------------------------------------------- // - class b3CompoundShapeChildData - { - public: - b3TransformFloatData m_transform; - b3CollisionShapeData *m_childShape; - int m_childShapeType; - float m_childMargin; - }; - +class b3CompoundShapeChildData +{ +public: + b3TransformFloatData m_transform; + b3CollisionShapeData *m_childShape; + int m_childShapeType; + float m_childMargin; +}; // -------------------------------------------------- // - class b3CompoundShapeData - { - public: - b3CollisionShapeData m_collisionShapeData; - b3CompoundShapeChildData *m_childShapePtr; - int m_numChildShapes; - float m_collisionMargin; - }; - +class b3CompoundShapeData +{ +public: + b3CollisionShapeData m_collisionShapeData; + b3CompoundShapeChildData *m_childShapePtr; + int m_numChildShapes; + float m_collisionMargin; +}; // -------------------------------------------------- // - class b3CylinderShapeData - { - public: - b3ConvexInternalShapeData m_convexInternalShapeData; - int m_upAxis; - char m_padding[4]; - }; - +class b3CylinderShapeData +{ +public: + b3ConvexInternalShapeData m_convexInternalShapeData; + int m_upAxis; + char m_padding[4]; +}; // -------------------------------------------------- // - class b3CapsuleShapeData - { - public: - b3ConvexInternalShapeData m_convexInternalShapeData; - int m_upAxis; - char m_padding[4]; - }; - +class b3CapsuleShapeData +{ +public: + b3ConvexInternalShapeData m_convexInternalShapeData; + int m_upAxis; + char m_padding[4]; +}; // -------------------------------------------------- // - class b3TriangleInfoData - { - public: - int m_flags; - float m_edgeV0V1Angle; - float m_edgeV1V2Angle; - float m_edgeV2V0Angle; - }; - +class b3TriangleInfoData +{ +public: + int m_flags; + float m_edgeV0V1Angle; + float m_edgeV1V2Angle; + float m_edgeV2V0Angle; +}; // -------------------------------------------------- // - class b3TriangleInfoMapData - { - public: - int *m_hashTablePtr; - int *m_nextPtr; - b3TriangleInfoData *m_valueArrayPtr; - int *m_keyArrayPtr; - float m_convexEpsilon; - float m_planarEpsilon; - float m_equalVertexThreshold; - float m_edgeDistanceThreshold; - float m_zeroAreaThreshold; - int m_nextSize; - int m_hashTableSize; - int m_numValues; - int m_numKeys; - char m_padding[4]; - }; - +class b3TriangleInfoMapData +{ +public: + int *m_hashTablePtr; + int *m_nextPtr; + b3TriangleInfoData *m_valueArrayPtr; + int *m_keyArrayPtr; + float m_convexEpsilon; + float m_planarEpsilon; + float m_equalVertexThreshold; + float m_edgeDistanceThreshold; + float m_zeroAreaThreshold; + int m_nextSize; + int m_hashTableSize; + int m_numValues; + int m_numKeys; + char m_padding[4]; +}; // -------------------------------------------------- // - class b3GImpactMeshShapeData - { - public: - b3CollisionShapeData m_collisionShapeData; - b3StridingMeshInterfaceData m_meshInterface; - b3Vector3FloatData m_localScaling; - float m_collisionMargin; - int m_gimpactSubType; - }; - +class b3GImpactMeshShapeData +{ +public: + b3CollisionShapeData m_collisionShapeData; + b3StridingMeshInterfaceData m_meshInterface; + b3Vector3FloatData m_localScaling; + float m_collisionMargin; + int m_gimpactSubType; +}; // -------------------------------------------------- // - class b3ConvexHullShapeData - { - public: - b3ConvexInternalShapeData m_convexInternalShapeData; - b3Vector3FloatData *m_unscaledPointsFloatPtr; - b3Vector3DoubleData *m_unscaledPointsDoublePtr; - int m_numUnscaledPoints; - char m_padding3[4]; - }; - +class b3ConvexHullShapeData +{ +public: + b3ConvexInternalShapeData m_convexInternalShapeData; + b3Vector3FloatData *m_unscaledPointsFloatPtr; + b3Vector3DoubleData *m_unscaledPointsDoublePtr; + int m_numUnscaledPoints; + char m_padding3[4]; +}; // -------------------------------------------------- // - class b3CollisionObjectDoubleData - { - public: - void *m_broadphaseHandle; - void *m_collisionShape; - b3CollisionShapeData *m_rootCollisionShape; - char *m_name; - b3TransformDoubleData m_worldTransform; - b3TransformDoubleData m_interpolationWorldTransform; - b3Vector3DoubleData m_interpolationLinearVelocity; - b3Vector3DoubleData m_interpolationAngularVelocity; - b3Vector3DoubleData m_anisotropicFriction; - double m_contactProcessingThreshold; - double m_deactivationTime; - double m_friction; - double m_rollingFriction; - double m_restitution; - double m_hitFraction; - double m_ccdSweptSphereRadius; - double m_ccdMotionThreshold; - int m_hasAnisotropicFriction; - int m_collisionFlags; - int m_islandTag1; - int m_companionId; - int m_activationState1; - int m_internalType; - int m_checkCollideWith; - char m_padding[4]; - }; - +class b3CollisionObjectDoubleData +{ +public: + void *m_broadphaseHandle; + void *m_collisionShape; + b3CollisionShapeData *m_rootCollisionShape; + char *m_name; + b3TransformDoubleData m_worldTransform; + b3TransformDoubleData m_interpolationWorldTransform; + b3Vector3DoubleData m_interpolationLinearVelocity; + b3Vector3DoubleData m_interpolationAngularVelocity; + b3Vector3DoubleData m_anisotropicFriction; + double m_contactProcessingThreshold; + double m_deactivationTime; + double m_friction; + double m_rollingFriction; + double m_restitution; + double m_hitFraction; + double m_ccdSweptSphereRadius; + double m_ccdMotionThreshold; + int m_hasAnisotropicFriction; + int m_collisionFlags; + int m_islandTag1; + int m_companionId; + int m_activationState1; + int m_internalType; + int m_checkCollideWith; + char m_padding[4]; +}; // -------------------------------------------------- // - class b3CollisionObjectFloatData - { - public: - void *m_broadphaseHandle; - void *m_collisionShape; - b3CollisionShapeData *m_rootCollisionShape; - char *m_name; - b3TransformFloatData m_worldTransform; - b3TransformFloatData m_interpolationWorldTransform; - b3Vector3FloatData m_interpolationLinearVelocity; - b3Vector3FloatData m_interpolationAngularVelocity; - b3Vector3FloatData m_anisotropicFriction; - float m_contactProcessingThreshold; - float m_deactivationTime; - float m_friction; - float m_rollingFriction; - float m_restitution; - float m_hitFraction; - float m_ccdSweptSphereRadius; - float m_ccdMotionThreshold; - int m_hasAnisotropicFriction; - int m_collisionFlags; - int m_islandTag1; - int m_companionId; - int m_activationState1; - int m_internalType; - int m_checkCollideWith; - char m_padding[4]; - }; - - +class b3CollisionObjectFloatData +{ +public: + void *m_broadphaseHandle; + void *m_collisionShape; + b3CollisionShapeData *m_rootCollisionShape; + char *m_name; + b3TransformFloatData m_worldTransform; + b3TransformFloatData m_interpolationWorldTransform; + b3Vector3FloatData m_interpolationLinearVelocity; + b3Vector3FloatData m_interpolationAngularVelocity; + b3Vector3FloatData m_anisotropicFriction; + float m_contactProcessingThreshold; + float m_deactivationTime; + float m_friction; + float m_rollingFriction; + float m_restitution; + float m_hitFraction; + float m_ccdSweptSphereRadius; + float m_ccdMotionThreshold; + int m_hasAnisotropicFriction; + int m_collisionFlags; + int m_islandTag1; + int m_companionId; + int m_activationState1; + int m_internalType; + int m_checkCollideWith; + char m_padding[4]; +}; // -------------------------------------------------- // - class b3RigidBodyFloatData - { - public: - b3CollisionObjectFloatData m_collisionObjectData; - b3Matrix3x3FloatData m_invInertiaTensorWorld; - b3Vector3FloatData m_linearVelocity; - b3Vector3FloatData m_angularVelocity; - b3Vector3FloatData m_angularFactor; - b3Vector3FloatData m_linearFactor; - b3Vector3FloatData m_gravity; - b3Vector3FloatData m_gravity_acceleration; - b3Vector3FloatData m_invInertiaLocal; - b3Vector3FloatData m_totalForce; - b3Vector3FloatData m_totalTorque; - float m_inverseMass; - float m_linearDamping; - float m_angularDamping; - float m_additionalDampingFactor; - float m_additionalLinearDampingThresholdSqr; - float m_additionalAngularDampingThresholdSqr; - float m_additionalAngularDampingFactor; - float m_linearSleepingThreshold; - float m_angularSleepingThreshold; - int m_additionalDamping; - }; - +class b3RigidBodyFloatData +{ +public: + b3CollisionObjectFloatData m_collisionObjectData; + b3Matrix3x3FloatData m_invInertiaTensorWorld; + b3Vector3FloatData m_linearVelocity; + b3Vector3FloatData m_angularVelocity; + b3Vector3FloatData m_angularFactor; + b3Vector3FloatData m_linearFactor; + b3Vector3FloatData m_gravity; + b3Vector3FloatData m_gravity_acceleration; + b3Vector3FloatData m_invInertiaLocal; + b3Vector3FloatData m_totalForce; + b3Vector3FloatData m_totalTorque; + float m_inverseMass; + float m_linearDamping; + float m_angularDamping; + float m_additionalDampingFactor; + float m_additionalLinearDampingThresholdSqr; + float m_additionalAngularDampingThresholdSqr; + float m_additionalAngularDampingFactor; + float m_linearSleepingThreshold; + float m_angularSleepingThreshold; + int m_additionalDamping; +}; // -------------------------------------------------- // - class b3RigidBodyDoubleData - { - public: - b3CollisionObjectDoubleData m_collisionObjectData; - b3Matrix3x3DoubleData m_invInertiaTensorWorld; - b3Vector3DoubleData m_linearVelocity; - b3Vector3DoubleData m_angularVelocity; - b3Vector3DoubleData m_angularFactor; - b3Vector3DoubleData m_linearFactor; - b3Vector3DoubleData m_gravity; - b3Vector3DoubleData m_gravity_acceleration; - b3Vector3DoubleData m_invInertiaLocal; - b3Vector3DoubleData m_totalForce; - b3Vector3DoubleData m_totalTorque; - double m_inverseMass; - double m_linearDamping; - double m_angularDamping; - double m_additionalDampingFactor; - double m_additionalLinearDampingThresholdSqr; - double m_additionalAngularDampingThresholdSqr; - double m_additionalAngularDampingFactor; - double m_linearSleepingThreshold; - double m_angularSleepingThreshold; - int m_additionalDamping; - char m_padding[4]; - }; - +class b3RigidBodyDoubleData +{ +public: + b3CollisionObjectDoubleData m_collisionObjectData; + b3Matrix3x3DoubleData m_invInertiaTensorWorld; + b3Vector3DoubleData m_linearVelocity; + b3Vector3DoubleData m_angularVelocity; + b3Vector3DoubleData m_angularFactor; + b3Vector3DoubleData m_linearFactor; + b3Vector3DoubleData m_gravity; + b3Vector3DoubleData m_gravity_acceleration; + b3Vector3DoubleData m_invInertiaLocal; + b3Vector3DoubleData m_totalForce; + b3Vector3DoubleData m_totalTorque; + double m_inverseMass; + double m_linearDamping; + double m_angularDamping; + double m_additionalDampingFactor; + double m_additionalLinearDampingThresholdSqr; + double m_additionalAngularDampingThresholdSqr; + double m_additionalAngularDampingFactor; + double m_linearSleepingThreshold; + double m_angularSleepingThreshold; + int m_additionalDamping; + char m_padding[4]; +}; // -------------------------------------------------- // - class b3ConstraintInfo1 - { - public: - int m_numConstraintRows; - int nub; - }; - +class b3ConstraintInfo1 +{ +public: + int m_numConstraintRows; + int nub; +}; // -------------------------------------------------- // - class b3TypedConstraintData - { - public: - bInvalidHandle *m_rbA; - bInvalidHandle *m_rbB; - char *m_name; - int m_objectType; - int m_userConstraintType; - int m_userConstraintId; - int m_needsFeedback; - float m_appliedImpulse; - float m_dbgDrawSize; - int m_disableCollisionsBetweenLinkedBodies; - int m_overrideNumSolverIterations; - float m_breakingImpulseThreshold; - int m_isEnabled; - }; - +class b3TypedConstraintData +{ +public: + bInvalidHandle *m_rbA; + bInvalidHandle *m_rbB; + char *m_name; + int m_objectType; + int m_userConstraintType; + int m_userConstraintId; + int m_needsFeedback; + float m_appliedImpulse; + float m_dbgDrawSize; + int m_disableCollisionsBetweenLinkedBodies; + int m_overrideNumSolverIterations; + float m_breakingImpulseThreshold; + int m_isEnabled; +}; // -------------------------------------------------- // - class b3Point2PointConstraintFloatData - { - public: - b3TypedConstraintData m_typeConstraintData; - b3Vector3FloatData m_pivotInA; - b3Vector3FloatData m_pivotInB; - }; - +class b3Point2PointConstraintFloatData +{ +public: + b3TypedConstraintData m_typeConstraintData; + b3Vector3FloatData m_pivotInA; + b3Vector3FloatData m_pivotInB; +}; // -------------------------------------------------- // - class b3Point2PointConstraintDoubleData - { - public: - b3TypedConstraintData m_typeConstraintData; - b3Vector3DoubleData m_pivotInA; - b3Vector3DoubleData m_pivotInB; - }; - +class b3Point2PointConstraintDoubleData +{ +public: + b3TypedConstraintData m_typeConstraintData; + b3Vector3DoubleData m_pivotInA; + b3Vector3DoubleData m_pivotInB; +}; // -------------------------------------------------- // - class b3HingeConstraintDoubleData - { - public: - b3TypedConstraintData m_typeConstraintData; - b3TransformDoubleData m_rbAFrame; - b3TransformDoubleData m_rbBFrame; - int m_useReferenceFrameA; - int m_angularOnly; - int m_enableAngularMotor; - float m_motorTargetVelocity; - float m_maxMotorImpulse; - float m_lowerLimit; - float m_upperLimit; - float m_limitSoftness; - float m_biasFactor; - float m_relaxationFactor; - }; - +class b3HingeConstraintDoubleData +{ +public: + b3TypedConstraintData m_typeConstraintData; + b3TransformDoubleData m_rbAFrame; + b3TransformDoubleData m_rbBFrame; + int m_useReferenceFrameA; + int m_angularOnly; + int m_enableAngularMotor; + float m_motorTargetVelocity; + float m_maxMotorImpulse; + float m_lowerLimit; + float m_upperLimit; + float m_limitSoftness; + float m_biasFactor; + float m_relaxationFactor; +}; // -------------------------------------------------- // - class b3HingeConstraintFloatData - { - public: - b3TypedConstraintData m_typeConstraintData; - b3TransformFloatData m_rbAFrame; - b3TransformFloatData m_rbBFrame; - int m_useReferenceFrameA; - int m_angularOnly; - int m_enableAngularMotor; - float m_motorTargetVelocity; - float m_maxMotorImpulse; - float m_lowerLimit; - float m_upperLimit; - float m_limitSoftness; - float m_biasFactor; - float m_relaxationFactor; - }; - +class b3HingeConstraintFloatData +{ +public: + b3TypedConstraintData m_typeConstraintData; + b3TransformFloatData m_rbAFrame; + b3TransformFloatData m_rbBFrame; + int m_useReferenceFrameA; + int m_angularOnly; + int m_enableAngularMotor; + float m_motorTargetVelocity; + float m_maxMotorImpulse; + float m_lowerLimit; + float m_upperLimit; + float m_limitSoftness; + float m_biasFactor; + float m_relaxationFactor; +}; // -------------------------------------------------- // - class b3ConeTwistConstraintData - { - public: - b3TypedConstraintData m_typeConstraintData; - b3TransformFloatData m_rbAFrame; - b3TransformFloatData m_rbBFrame; - float m_swingSpan1; - float m_swingSpan2; - float m_twistSpan; - float m_limitSoftness; - float m_biasFactor; - float m_relaxationFactor; - float m_damping; - char m_pad[4]; - }; - +class b3ConeTwistConstraintData +{ +public: + b3TypedConstraintData m_typeConstraintData; + b3TransformFloatData m_rbAFrame; + b3TransformFloatData m_rbBFrame; + float m_swingSpan1; + float m_swingSpan2; + float m_twistSpan; + float m_limitSoftness; + float m_biasFactor; + float m_relaxationFactor; + float m_damping; + char m_pad[4]; +}; // -------------------------------------------------- // - class b3Generic6DofConstraintData - { - public: - b3TypedConstraintData m_typeConstraintData; - b3TransformFloatData m_rbAFrame; - b3TransformFloatData m_rbBFrame; - b3Vector3FloatData m_linearUpperLimit; - b3Vector3FloatData m_linearLowerLimit; - b3Vector3FloatData m_angularUpperLimit; - b3Vector3FloatData m_angularLowerLimit; - int m_useLinearReferenceFrameA; - int m_useOffsetForConstraintFrame; - }; - +class b3Generic6DofConstraintData +{ +public: + b3TypedConstraintData m_typeConstraintData; + b3TransformFloatData m_rbAFrame; + b3TransformFloatData m_rbBFrame; + b3Vector3FloatData m_linearUpperLimit; + b3Vector3FloatData m_linearLowerLimit; + b3Vector3FloatData m_angularUpperLimit; + b3Vector3FloatData m_angularLowerLimit; + int m_useLinearReferenceFrameA; + int m_useOffsetForConstraintFrame; +}; // -------------------------------------------------- // - class b3Generic6DofSpringConstraintData - { - public: - b3Generic6DofConstraintData m_6dofData; - int m_springEnabled[6]; - float m_equilibriumPoint[6]; - float m_springStiffness[6]; - float m_springDamping[6]; - }; - +class b3Generic6DofSpringConstraintData +{ +public: + b3Generic6DofConstraintData m_6dofData; + int m_springEnabled[6]; + float m_equilibriumPoint[6]; + float m_springStiffness[6]; + float m_springDamping[6]; +}; // -------------------------------------------------- // - class b3SliderConstraintData - { - public: - b3TypedConstraintData m_typeConstraintData; - b3TransformFloatData m_rbAFrame; - b3TransformFloatData m_rbBFrame; - float m_linearUpperLimit; - float m_linearLowerLimit; - float m_angularUpperLimit; - float m_angularLowerLimit; - int m_useLinearReferenceFrameA; - int m_useOffsetForConstraintFrame; - }; - +class b3SliderConstraintData +{ +public: + b3TypedConstraintData m_typeConstraintData; + b3TransformFloatData m_rbAFrame; + b3TransformFloatData m_rbBFrame; + float m_linearUpperLimit; + float m_linearLowerLimit; + float m_angularUpperLimit; + float m_angularLowerLimit; + int m_useLinearReferenceFrameA; + int m_useOffsetForConstraintFrame; +}; // -------------------------------------------------- // - class b3ContactSolverInfoDoubleData - { - public: - double m_tau; - double m_damping; - double m_friction; - double m_timeStep; - double m_restitution; - double m_maxErrorReduction; - double m_sor; - double m_erp; - double m_erp2; - double m_globalCfm; - double m_splitImpulsePenetrationThreshold; - double m_splitImpulseTurnErp; - double m_linearSlop; - double m_warmstartingFactor; - double m_maxGyroscopicForce; - double m_singleAxisRollingFrictionThreshold; - int m_numIterations; - int m_solverMode; - int m_restingContactRestitutionThreshold; - int m_minimumSolverBatchSize; - int m_splitImpulse; - char m_padding[4]; - }; - +class b3ContactSolverInfoDoubleData +{ +public: + double m_tau; + double m_damping; + double m_friction; + double m_timeStep; + double m_restitution; + double m_maxErrorReduction; + double m_sor; + double m_erp; + double m_erp2; + double m_globalCfm; + double m_splitImpulsePenetrationThreshold; + double m_splitImpulseTurnErp; + double m_linearSlop; + double m_warmstartingFactor; + double m_maxGyroscopicForce; + double m_singleAxisRollingFrictionThreshold; + int m_numIterations; + int m_solverMode; + int m_restingContactRestitutionThreshold; + int m_minimumSolverBatchSize; + int m_splitImpulse; + char m_padding[4]; +}; // -------------------------------------------------- // - class b3ContactSolverInfoFloatData - { - public: - float m_tau; - float m_damping; - float m_friction; - float m_timeStep; - float m_restitution; - float m_maxErrorReduction; - float m_sor; - float m_erp; - float m_erp2; - float m_globalCfm; - float m_splitImpulsePenetrationThreshold; - float m_splitImpulseTurnErp; - float m_linearSlop; - float m_warmstartingFactor; - float m_maxGyroscopicForce; - float m_singleAxisRollingFrictionThreshold; - int m_numIterations; - int m_solverMode; - int m_restingContactRestitutionThreshold; - int m_minimumSolverBatchSize; - int m_splitImpulse; - char m_padding[4]; - }; - - - // -------------------------------------------------- // - class b3DynamicsWorldDoubleData - { - public: - b3ContactSolverInfoDoubleData m_solverInfo; - b3Vector3DoubleData m_gravity; - }; - +class b3ContactSolverInfoFloatData +{ +public: + float m_tau; + float m_damping; + float m_friction; + float m_timeStep; + float m_restitution; + float m_maxErrorReduction; + float m_sor; + float m_erp; + float m_erp2; + float m_globalCfm; + float m_splitImpulsePenetrationThreshold; + float m_splitImpulseTurnErp; + float m_linearSlop; + float m_warmstartingFactor; + float m_maxGyroscopicForce; + float m_singleAxisRollingFrictionThreshold; + int m_numIterations; + int m_solverMode; + int m_restingContactRestitutionThreshold; + int m_minimumSolverBatchSize; + int m_splitImpulse; + char m_padding[4]; +}; // -------------------------------------------------- // - class b3DynamicsWorldFloatData - { - public: - b3ContactSolverInfoFloatData m_solverInfo; - b3Vector3FloatData m_gravity; - }; - - +class b3DynamicsWorldDoubleData +{ +public: + b3ContactSolverInfoDoubleData m_solverInfo; + b3Vector3DoubleData m_gravity; +}; // -------------------------------------------------- // - class SoftBodyMaterialData - { - public: - float m_linearStiffness; - float m_angularStiffness; - float m_volumeStiffness; - int m_flags; - }; - +class b3DynamicsWorldFloatData +{ +public: + b3ContactSolverInfoFloatData m_solverInfo; + b3Vector3FloatData m_gravity; +}; // -------------------------------------------------- // - class SoftBodyNodeData - { - public: - SoftBodyMaterialData *m_material; - b3Vector3FloatData m_position; - b3Vector3FloatData m_previousPosition; - b3Vector3FloatData m_velocity; - b3Vector3FloatData m_accumulatedForce; - b3Vector3FloatData m_normal; - float m_inverseMass; - float m_area; - int m_attach; - int m_pad; - }; - +class SoftBodyMaterialData +{ +public: + float m_linearStiffness; + float m_angularStiffness; + float m_volumeStiffness; + int m_flags; +}; // -------------------------------------------------- // - class SoftBodyLinkData - { - public: - SoftBodyMaterialData *m_material; - int m_nodeIndices[2]; - float m_restLength; - int m_bbending; - }; - +class SoftBodyNodeData +{ +public: + SoftBodyMaterialData *m_material; + b3Vector3FloatData m_position; + b3Vector3FloatData m_previousPosition; + b3Vector3FloatData m_velocity; + b3Vector3FloatData m_accumulatedForce; + b3Vector3FloatData m_normal; + float m_inverseMass; + float m_area; + int m_attach; + int m_pad; +}; // -------------------------------------------------- // - class SoftBodyFaceData - { - public: - b3Vector3FloatData m_normal; - SoftBodyMaterialData *m_material; - int m_nodeIndices[3]; - float m_restArea; - }; - +class SoftBodyLinkData +{ +public: + SoftBodyMaterialData *m_material; + int m_nodeIndices[2]; + float m_restLength; + int m_bbending; +}; // -------------------------------------------------- // - class SoftBodyTetraData - { - public: - b3Vector3FloatData m_c0[4]; - SoftBodyMaterialData *m_material; - int m_nodeIndices[4]; - float m_restVolume; - float m_c1; - float m_c2; - int m_pad; - }; - +class SoftBodyFaceData +{ +public: + b3Vector3FloatData m_normal; + SoftBodyMaterialData *m_material; + int m_nodeIndices[3]; + float m_restArea; +}; // -------------------------------------------------- // - class SoftRigidAnchorData - { - public: - b3Matrix3x3FloatData m_c0; - b3Vector3FloatData m_c1; - b3Vector3FloatData m_localFrame; - bInvalidHandle *m_rigidBody; - int m_nodeIndex; - float m_c2; - }; - +class SoftBodyTetraData +{ +public: + b3Vector3FloatData m_c0[4]; + SoftBodyMaterialData *m_material; + int m_nodeIndices[4]; + float m_restVolume; + float m_c1; + float m_c2; + int m_pad; +}; // -------------------------------------------------- // - class SoftBodyConfigData - { - public: - int m_aeroModel; - float m_baumgarte; - float m_damping; - float m_drag; - float m_lift; - float m_pressure; - float m_volume; - float m_dynamicFriction; - float m_poseMatch; - float m_rigidContactHardness; - float m_kineticContactHardness; - float m_softContactHardness; - float m_anchorHardness; - float m_softRigidClusterHardness; - float m_softKineticClusterHardness; - float m_softSoftClusterHardness; - float m_softRigidClusterImpulseSplit; - float m_softKineticClusterImpulseSplit; - float m_softSoftClusterImpulseSplit; - float m_maxVolume; - float m_timeScale; - int m_velocityIterations; - int m_positionIterations; - int m_driftIterations; - int m_clusterIterations; - int m_collisionFlags; - }; - +class SoftRigidAnchorData +{ +public: + b3Matrix3x3FloatData m_c0; + b3Vector3FloatData m_c1; + b3Vector3FloatData m_localFrame; + bInvalidHandle *m_rigidBody; + int m_nodeIndex; + float m_c2; +}; // -------------------------------------------------- // - class SoftBodyPoseData - { - public: - b3Matrix3x3FloatData m_rot; - b3Matrix3x3FloatData m_scale; - b3Matrix3x3FloatData m_aqq; - b3Vector3FloatData m_com; - b3Vector3FloatData *m_positions; - float *m_weights; - int m_numPositions; - int m_numWeigts; - int m_bvolume; - int m_bframe; - float m_restVolume; - int m_pad; - }; - +class SoftBodyConfigData +{ +public: + int m_aeroModel; + float m_baumgarte; + float m_damping; + float m_drag; + float m_lift; + float m_pressure; + float m_volume; + float m_dynamicFriction; + float m_poseMatch; + float m_rigidContactHardness; + float m_kineticContactHardness; + float m_softContactHardness; + float m_anchorHardness; + float m_softRigidClusterHardness; + float m_softKineticClusterHardness; + float m_softSoftClusterHardness; + float m_softRigidClusterImpulseSplit; + float m_softKineticClusterImpulseSplit; + float m_softSoftClusterImpulseSplit; + float m_maxVolume; + float m_timeScale; + int m_velocityIterations; + int m_positionIterations; + int m_driftIterations; + int m_clusterIterations; + int m_collisionFlags; +}; // -------------------------------------------------- // - class SoftBodyClusterData - { - public: - b3TransformFloatData m_framexform; - b3Matrix3x3FloatData m_locii; - b3Matrix3x3FloatData m_invwi; - b3Vector3FloatData m_com; - b3Vector3FloatData m_vimpulses[2]; - b3Vector3FloatData m_dimpulses[2]; - b3Vector3FloatData m_lv; - b3Vector3FloatData m_av; - b3Vector3FloatData *m_framerefs; - int *m_nodeIndices; - float *m_masses; - int m_numFrameRefs; - int m_numNodes; - int m_numMasses; - float m_idmass; - float m_imass; - int m_nvimpulses; - int m_ndimpulses; - float m_ndamping; - float m_ldamping; - float m_adamping; - float m_matching; - float m_maxSelfCollisionImpulse; - float m_selfCollisionImpulseFactor; - int m_containsAnchor; - int m_collide; - int m_clusterIndex; - }; - +class SoftBodyPoseData +{ +public: + b3Matrix3x3FloatData m_rot; + b3Matrix3x3FloatData m_scale; + b3Matrix3x3FloatData m_aqq; + b3Vector3FloatData m_com; + b3Vector3FloatData *m_positions; + float *m_weights; + int m_numPositions; + int m_numWeigts; + int m_bvolume; + int m_bframe; + float m_restVolume; + int m_pad; +}; // -------------------------------------------------- // - class b3SoftBodyJointData - { - public: - void *m_bodyA; - void *m_bodyB; - b3Vector3FloatData m_refs[2]; - float m_cfm; - float m_erp; - float m_split; - int m_delete; - b3Vector3FloatData m_relPosition[2]; - int m_bodyAtype; - int m_bodyBtype; - int m_jointType; - int m_pad; - }; - +class SoftBodyClusterData +{ +public: + b3TransformFloatData m_framexform; + b3Matrix3x3FloatData m_locii; + b3Matrix3x3FloatData m_invwi; + b3Vector3FloatData m_com; + b3Vector3FloatData m_vimpulses[2]; + b3Vector3FloatData m_dimpulses[2]; + b3Vector3FloatData m_lv; + b3Vector3FloatData m_av; + b3Vector3FloatData *m_framerefs; + int *m_nodeIndices; + float *m_masses; + int m_numFrameRefs; + int m_numNodes; + int m_numMasses; + float m_idmass; + float m_imass; + int m_nvimpulses; + int m_ndimpulses; + float m_ndamping; + float m_ldamping; + float m_adamping; + float m_matching; + float m_maxSelfCollisionImpulse; + float m_selfCollisionImpulseFactor; + int m_containsAnchor; + int m_collide; + int m_clusterIndex; +}; // -------------------------------------------------- // - class b3SoftBodyFloatData - { - public: - b3CollisionObjectFloatData m_collisionObjectData; - SoftBodyPoseData *m_pose; - SoftBodyMaterialData **m_materials; - SoftBodyNodeData *m_nodes; - SoftBodyLinkData *m_links; - SoftBodyFaceData *m_faces; - SoftBodyTetraData *m_tetrahedra; - SoftRigidAnchorData *m_anchors; - SoftBodyClusterData *m_clusters; - b3SoftBodyJointData *m_joints; - int m_numMaterials; - int m_numNodes; - int m_numLinks; - int m_numFaces; - int m_numTetrahedra; - int m_numAnchors; - int m_numClusters; - int m_numJoints; - SoftBodyConfigData m_config; - }; +class b3SoftBodyJointData +{ +public: + void *m_bodyA; + void *m_bodyB; + b3Vector3FloatData m_refs[2]; + float m_cfm; + float m_erp; + float m_split; + int m_delete; + b3Vector3FloatData m_relPosition[2]; + int m_bodyAtype; + int m_bodyBtype; + int m_jointType; + int m_pad; +}; +// -------------------------------------------------- // +class b3SoftBodyFloatData +{ +public: + b3CollisionObjectFloatData m_collisionObjectData; + SoftBodyPoseData *m_pose; + SoftBodyMaterialData **m_materials; + SoftBodyNodeData *m_nodes; + SoftBodyLinkData *m_links; + SoftBodyFaceData *m_faces; + SoftBodyTetraData *m_tetrahedra; + SoftRigidAnchorData *m_anchors; + SoftBodyClusterData *m_clusters; + b3SoftBodyJointData *m_joints; + int m_numMaterials; + int m_numNodes; + int m_numLinks; + int m_numFaces; + int m_numTetrahedra; + int m_numAnchors; + int m_numClusters; + int m_numJoints; + SoftBodyConfigData m_config; +}; -} -#endif//__BULLET2_H__ \ No newline at end of file +} // namespace Bullet3SerializeBullet2 +#endif //__BULLET2_H__ \ No newline at end of file diff --git a/src/Bullet3Serialize/Bullet2FileLoader/b3BulletFile.cpp b/src/Bullet3Serialize/Bullet2FileLoader/b3BulletFile.cpp index c3ceb8388..d2a716367 100644 --- a/src/Bullet3Serialize/Bullet2FileLoader/b3BulletFile.cpp +++ b/src/Bullet3Serialize/Bullet2FileLoader/b3BulletFile.cpp @@ -17,12 +17,11 @@ subject to the following restrictions: #include "b3Defines.h" #include "b3DNA.h" -#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__) +#if !defined(__CELLOS_LV2__) && !defined(__MWERKS__) #include #endif #include - // 32 && 64 bit versions #ifdef B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES #ifdef _WIN64 @@ -31,130 +30,116 @@ extern int b3s_bulletDNAlen64; #else extern char b3s_bulletDNAstr[]; extern int b3s_bulletDNAlen; -#endif //_WIN64 -#else//B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +#endif //_WIN64 +#else //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES extern char b3s_bulletDNAstr64[]; extern int b3s_bulletDNAlen64; extern char b3s_bulletDNAstr[]; extern int b3s_bulletDNAlen; -#endif //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +#endif //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES using namespace bParse; b3BulletFile::b3BulletFile() -:bFile("", "BULLET ") + : bFile("", "BULLET ") { - mMemoryDNA = new bDNA(); //this memory gets released in the bFile::~bFile destructor,@todo not consistent with the rule 'who allocates it, has to deallocate it" + mMemoryDNA = new bDNA(); //this memory gets released in the bFile::~bFile destructor,@todo not consistent with the rule 'who allocates it, has to deallocate it" m_DnaCopy = 0; - #ifdef B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES #ifdef _WIN64 - m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen64,16); - memcpy(m_DnaCopy,b3s_bulletDNAstr64,b3s_bulletDNAlen64); - mMemoryDNA->init(m_DnaCopy,b3s_bulletDNAlen64); -#else//_WIN64 - m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen,16); - memcpy(m_DnaCopy,b3s_bulletDNAstr,b3s_bulletDNAlen); - mMemoryDNA->init(m_DnaCopy,b3s_bulletDNAlen); -#endif//_WIN64 -#else//B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES + m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen64, 16); + memcpy(m_DnaCopy, b3s_bulletDNAstr64, b3s_bulletDNAlen64); + mMemoryDNA->init(m_DnaCopy, b3s_bulletDNAlen64); +#else //_WIN64 + m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen, 16); + memcpy(m_DnaCopy, b3s_bulletDNAstr, b3s_bulletDNAlen); + mMemoryDNA->init(m_DnaCopy, b3s_bulletDNAlen); +#endif //_WIN64 +#else //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES if (VOID_IS_8) { - m_DnaCopy = (char*) b3AlignedAlloc(b3s_bulletDNAlen64,16); - memcpy(m_DnaCopy,b3s_bulletDNAstr64,b3s_bulletDNAlen64); - mMemoryDNA->init(m_DnaCopy,b3s_bulletDNAlen64); + m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen64, 16); + memcpy(m_DnaCopy, b3s_bulletDNAstr64, b3s_bulletDNAlen64); + mMemoryDNA->init(m_DnaCopy, b3s_bulletDNAlen64); } else { - m_DnaCopy =(char*) b3AlignedAlloc(b3s_bulletDNAlen,16); - memcpy(m_DnaCopy,b3s_bulletDNAstr,b3s_bulletDNAlen); - mMemoryDNA->init(m_DnaCopy,b3s_bulletDNAlen); + m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen, 16); + memcpy(m_DnaCopy, b3s_bulletDNAstr, b3s_bulletDNAlen); + mMemoryDNA->init(m_DnaCopy, b3s_bulletDNAlen); } -#endif//B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +#endif //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES } - - b3BulletFile::b3BulletFile(const char* fileName) -:bFile(fileName, "BULLET ") + : bFile(fileName, "BULLET ") { m_DnaCopy = 0; } - - -b3BulletFile::b3BulletFile(char *memoryBuffer, int len) -:bFile(memoryBuffer,len, "BULLET ") +b3BulletFile::b3BulletFile(char* memoryBuffer, int len) + : bFile(memoryBuffer, len, "BULLET ") { m_DnaCopy = 0; } - b3BulletFile::~b3BulletFile() { if (m_DnaCopy) b3AlignedFree(m_DnaCopy); - while (m_dataBlocks.size()) { - char* dataBlock = m_dataBlocks[m_dataBlocks.size()-1]; + char* dataBlock = m_dataBlocks[m_dataBlocks.size() - 1]; delete[] dataBlock; m_dataBlocks.pop_back(); } - } - - // ----------------------------------------------------- // void b3BulletFile::parseData() { -// printf ("Building datablocks"); -// printf ("Chunk size = %d",CHUNK_HEADER_LEN); -// printf ("File chunk size = %d",ChunkUtils::getOffset(mFlags)); + // printf ("Building datablocks"); + // printf ("Chunk size = %d",CHUNK_HEADER_LEN); + // printf ("File chunk size = %d",ChunkUtils::getOffset(mFlags)); - const bool brokenDNA = (mFlags&FD_BROKEN_DNA)!=0; + const bool brokenDNA = (mFlags & FD_BROKEN_DNA) != 0; //const bool swap = (mFlags&FD_ENDIAN_SWAP)!=0; - mDataStart = 12; - char *dataPtr = mFileBuffer+mDataStart; + char* dataPtr = mFileBuffer + mDataStart; bChunkInd dataChunk; dataChunk.code = 0; - //dataPtr += ChunkUtils::getNextBlock(&dataChunk, dataPtr, mFlags); int seek = getNextBlock(&dataChunk, dataPtr, mFlags); - - - if (mFlags &FD_ENDIAN_SWAP) + + if (mFlags & FD_ENDIAN_SWAP) swapLen(dataPtr); //dataPtr += ChunkUtils::getOffset(mFlags); - char *dataPtrHead = 0; + char* dataPtrHead = 0; while (dataChunk.code != B3_DNA1) { - if (!brokenDNA || (dataChunk.code != B3_QUANTIZED_BVH_CODE) ) + if (!brokenDNA || (dataChunk.code != B3_QUANTIZED_BVH_CODE)) { - // one behind if (dataChunk.code == B3_SDNA) break; //if (dataChunk.code == DNA1) break; // same as (BHEAD+DATA dependency) - dataPtrHead = dataPtr+ChunkUtils::getOffset(mFlags); - if (dataChunk.dna_nr>=0) + dataPtrHead = dataPtr + ChunkUtils::getOffset(mFlags); + if (dataChunk.dna_nr >= 0) { - char *id = readStruct(dataPtrHead, dataChunk); + char* id = readStruct(dataPtrHead, dataChunk); // lookup maps if (id) @@ -171,96 +156,91 @@ void b3BulletFile::parseData() if (dataChunk.code == B3_SOFTBODY_CODE) { - m_softBodies.push_back((bStructHandle*) id); + m_softBodies.push_back((bStructHandle*)id); } - + if (dataChunk.code == B3_RIGIDBODY_CODE) { - m_rigidBodies.push_back((bStructHandle*) id); + m_rigidBodies.push_back((bStructHandle*)id); } if (dataChunk.code == B3_DYNAMICSWORLD_CODE) { - m_dynamicsWorldInfo.push_back((bStructHandle*) id); + m_dynamicsWorldInfo.push_back((bStructHandle*)id); } if (dataChunk.code == B3_CONSTRAINT_CODE) { - m_constraints.push_back((bStructHandle*) id); + m_constraints.push_back((bStructHandle*)id); } if (dataChunk.code == B3_QUANTIZED_BVH_CODE) { - m_bvhs.push_back((bStructHandle*) id); + m_bvhs.push_back((bStructHandle*)id); } if (dataChunk.code == B3_TRIANLGE_INFO_MAP) { - m_triangleInfoMaps.push_back((bStructHandle*) id); + m_triangleInfoMaps.push_back((bStructHandle*)id); } if (dataChunk.code == B3_COLLISIONOBJECT_CODE) { - m_collisionObjects.push_back((bStructHandle*) id); + m_collisionObjects.push_back((bStructHandle*)id); } if (dataChunk.code == B3_SHAPE_CODE) { - m_collisionShapes.push_back((bStructHandle*) id); + m_collisionShapes.push_back((bStructHandle*)id); } - // if (dataChunk.code == GLOB) - // { - // m_glob = (bStructHandle*) id; - // } - } else + // if (dataChunk.code == GLOB) + // { + // m_glob = (bStructHandle*) id; + // } + } + else { //printf("unknown chunk\n"); mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)dataPtrHead); } - } else + } + else { printf("skipping B3_QUANTIZED_BVH_CODE due to broken DNA\n"); } - dataPtr += seek; - seek = getNextBlock(&dataChunk, dataPtr, mFlags); - if (mFlags &FD_ENDIAN_SWAP) + seek = getNextBlock(&dataChunk, dataPtr, mFlags); + if (mFlags & FD_ENDIAN_SWAP) swapLen(dataPtr); if (seek < 0) break; } - } -void b3BulletFile::addDataBlock(char* dataBlock) +void b3BulletFile::addDataBlock(char* dataBlock) { m_dataBlocks.push_back(dataBlock); - } - - - -void b3BulletFile::writeDNA(FILE* fp) +void b3BulletFile::writeDNA(FILE* fp) { - bChunkInd dataChunk; dataChunk.code = B3_DNA1; dataChunk.dna_nr = 0; dataChunk.nr = 1; -#ifdef B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +#ifdef B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES if (VOID_IS_8) { #ifdef _WIN64 dataChunk.len = b3s_bulletDNAlen64; dataChunk.oldPtr = b3s_bulletDNAstr64; - fwrite(&dataChunk,sizeof(bChunkInd),1,fp); - fwrite(b3s_bulletDNAstr64, b3s_bulletDNAlen64,1,fp); + fwrite(&dataChunk, sizeof(bChunkInd), 1, fp); + fwrite(b3s_bulletDNAstr64, b3s_bulletDNAlen64, 1, fp); #else b3Assert(0); #endif @@ -270,43 +250,42 @@ void b3BulletFile::writeDNA(FILE* fp) #ifndef _WIN64 dataChunk.len = b3s_bulletDNAlen; dataChunk.oldPtr = b3s_bulletDNAstr; - fwrite(&dataChunk,sizeof(bChunkInd),1,fp); - fwrite(b3s_bulletDNAstr, b3s_bulletDNAlen,1,fp); -#else//_WIN64 + fwrite(&dataChunk, sizeof(bChunkInd), 1, fp); + fwrite(b3s_bulletDNAstr, b3s_bulletDNAlen, 1, fp); +#else //_WIN64 b3Assert(0); -#endif//_WIN64 +#endif //_WIN64 } -#else//B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +#else //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES if (VOID_IS_8) { dataChunk.len = b3s_bulletDNAlen64; dataChunk.oldPtr = b3s_bulletDNAstr64; - fwrite(&dataChunk,sizeof(bChunkInd),1,fp); - fwrite(b3s_bulletDNAstr64, b3s_bulletDNAlen64,1,fp); + fwrite(&dataChunk, sizeof(bChunkInd), 1, fp); + fwrite(b3s_bulletDNAstr64, b3s_bulletDNAlen64, 1, fp); } else { dataChunk.len = b3s_bulletDNAlen; dataChunk.oldPtr = b3s_bulletDNAstr; - fwrite(&dataChunk,sizeof(bChunkInd),1,fp); - fwrite(b3s_bulletDNAstr, b3s_bulletDNAlen,1,fp); + fwrite(&dataChunk, sizeof(bChunkInd), 1, fp); + fwrite(b3s_bulletDNAstr, b3s_bulletDNAlen, 1, fp); } -#endif//B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +#endif //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES } - -void b3BulletFile::parse(int verboseMode) +void b3BulletFile::parse(int verboseMode) { #ifdef B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES if (VOID_IS_8) { #ifdef _WIN64 - + if (m_DnaCopy) delete m_DnaCopy; - m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen64,16); - memcpy(m_DnaCopy,b3s_bulletDNAstr64,b3s_bulletDNAlen64); - parseInternal(verboseMode,(char*)b3s_bulletDNAstr64,b3s_bulletDNAlen64); + m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen64, 16); + memcpy(m_DnaCopy, b3s_bulletDNAstr64, b3s_bulletDNAlen64); + parseInternal(verboseMode, (char*)b3s_bulletDNAstr64, b3s_bulletDNAlen64); #else b3Assert(0); #endif @@ -317,93 +296,91 @@ void b3BulletFile::parse(int verboseMode) if (m_DnaCopy) delete m_DnaCopy; - m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen,16); - memcpy(m_DnaCopy,b3s_bulletDNAstr,b3s_bulletDNAlen); - parseInternal(verboseMode,m_DnaCopy,b3s_bulletDNAlen); + m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen, 16); + memcpy(m_DnaCopy, b3s_bulletDNAstr, b3s_bulletDNAlen); + parseInternal(verboseMode, m_DnaCopy, b3s_bulletDNAlen); #else b3Assert(0); #endif } -#else//B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES +#else //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES if (VOID_IS_8) { if (m_DnaCopy) delete m_DnaCopy; - m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen64,16); - memcpy(m_DnaCopy,b3s_bulletDNAstr64,b3s_bulletDNAlen64); - parseInternal(verboseMode,m_DnaCopy,b3s_bulletDNAlen64); + m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen64, 16); + memcpy(m_DnaCopy, b3s_bulletDNAstr64, b3s_bulletDNAlen64); + parseInternal(verboseMode, m_DnaCopy, b3s_bulletDNAlen64); } else { if (m_DnaCopy) delete m_DnaCopy; - m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen,16); - memcpy(m_DnaCopy,b3s_bulletDNAstr,b3s_bulletDNAlen); - parseInternal(verboseMode,m_DnaCopy,b3s_bulletDNAlen); + m_DnaCopy = (char*)b3AlignedAlloc(b3s_bulletDNAlen, 16); + memcpy(m_DnaCopy, b3s_bulletDNAstr, b3s_bulletDNAlen); + parseInternal(verboseMode, m_DnaCopy, b3s_bulletDNAlen); } -#endif//B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES - - //the parsing will convert to cpu endian - mFlags &=~FD_ENDIAN_SWAP; +#endif //B3_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES - int littleEndian= 1; - littleEndian= ((char*)&littleEndian)[0]; - - mFileBuffer[8] = littleEndian?'v':'V'; - + //the parsing will convert to cpu endian + mFlags &= ~FD_ENDIAN_SWAP; + + int littleEndian = 1; + littleEndian = ((char*)&littleEndian)[0]; + + mFileBuffer[8] = littleEndian ? 'v' : 'V'; } // experimental -int b3BulletFile::write(const char* fileName, bool fixupPointers) +int b3BulletFile::write(const char* fileName, bool fixupPointers) { - FILE *fp = fopen(fileName, "wb"); + FILE* fp = fopen(fileName, "wb"); if (fp) { - char header[B3_SIZEOFBLENDERHEADER] ; + char header[B3_SIZEOFBLENDERHEADER]; memcpy(header, m_headerString, 7); - int endian= 1; - endian= ((char*)&endian)[0]; + int endian = 1; + endian = ((char*)&endian)[0]; if (endian) { header[7] = '_'; - } else + } + else { header[7] = '-'; } if (VOID_IS_8) { - header[8]='V'; - } else + header[8] = 'V'; + } + else { - header[8]='v'; + header[8] = 'v'; } header[9] = '2'; header[10] = '7'; header[11] = '5'; - - fwrite(header,B3_SIZEOFBLENDERHEADER,1,fp); + + fwrite(header, B3_SIZEOFBLENDERHEADER, 1, fp); writeChunks(fp, fixupPointers); writeDNA(fp); fclose(fp); - - } else + } + else { - printf("Error: cannot open file %s for writing\n",fileName); + printf("Error: cannot open file %s for writing\n", fileName); return 0; } return 1; } - - -void b3BulletFile::addStruct(const char* structType,void* data, int len, void* oldPtr, int code) +void b3BulletFile::addStruct(const char* structType, void* data, int len, void* oldPtr, int code) { - bParse::bChunkInd dataChunk; dataChunk.code = code; dataChunk.nr = 1; @@ -412,11 +389,11 @@ void b3BulletFile::addStruct(const char* structType,void* data, int len, void* o dataChunk.oldPtr = oldPtr; ///Perform structure size validation - short* structInfo= mMemoryDNA->getStruct(dataChunk.dna_nr); + short* structInfo = mMemoryDNA->getStruct(dataChunk.dna_nr); int elemBytes; - elemBytes= mMemoryDNA->getLength(structInfo[0]); -// int elemBytes = mMemoryDNA->getElementSize(structInfo[0],structInfo[1]); - assert(len==elemBytes); + elemBytes = mMemoryDNA->getLength(structInfo[0]); + // int elemBytes = mMemoryDNA->getElementSize(structInfo[0],structInfo[1]); + assert(len == elemBytes); mLibPointers.insert(dataChunk.oldPtr, (bStructHandle*)data); m_chunks.push_back(dataChunk); diff --git a/src/Bullet3Serialize/Bullet2FileLoader/b3BulletFile.h b/src/Bullet3Serialize/Bullet2FileLoader/b3BulletFile.h index fb1b9b0dd..ede1d378a 100644 --- a/src/Bullet3Serialize/Bullet2FileLoader/b3BulletFile.h +++ b/src/Bullet3Serialize/Bullet2FileLoader/b3BulletFile.h @@ -16,68 +16,59 @@ subject to the following restrictions: #ifndef B3_BULLET_FILE_H #define B3_BULLET_FILE_H - #include "b3File.h" #include "Bullet3Common/b3AlignedObjectArray.h" #include "b3Defines.h" #include "Bullet3Serialize/Bullet2FileLoader/b3Serializer.h" +namespace bParse +{ +// ----------------------------------------------------- // +class b3BulletFile : public bFile +{ +protected: + char* m_DnaCopy; +public: + b3AlignedObjectArray m_softBodies; -namespace bParse { + b3AlignedObjectArray m_rigidBodies; - // ----------------------------------------------------- // - class b3BulletFile : public bFile - { - + b3AlignedObjectArray m_collisionObjects; - protected: - - char* m_DnaCopy; - - public: + b3AlignedObjectArray m_collisionShapes; - b3AlignedObjectArray m_softBodies; + b3AlignedObjectArray m_constraints; - b3AlignedObjectArray m_rigidBodies; + b3AlignedObjectArray m_bvhs; - b3AlignedObjectArray m_collisionObjects; + b3AlignedObjectArray m_triangleInfoMaps; - b3AlignedObjectArray m_collisionShapes; + b3AlignedObjectArray m_dynamicsWorldInfo; - b3AlignedObjectArray m_constraints; + b3AlignedObjectArray m_dataBlocks; + b3BulletFile(); - b3AlignedObjectArray m_bvhs; + b3BulletFile(const char* fileName); - b3AlignedObjectArray m_triangleInfoMaps; + b3BulletFile(char* memoryBuffer, int len); - b3AlignedObjectArray m_dynamicsWorldInfo; + virtual ~b3BulletFile(); - b3AlignedObjectArray m_dataBlocks; - b3BulletFile(); + virtual void addDataBlock(char* dataBlock); - b3BulletFile(const char* fileName); + // experimental + virtual int write(const char* fileName, bool fixupPointers = false); - b3BulletFile(char *memoryBuffer, int len); + virtual void parse(int verboseMode); - virtual ~b3BulletFile(); + virtual void parseData(); - virtual void addDataBlock(char* dataBlock); - + virtual void writeDNA(FILE* fp); - // experimental - virtual int write(const char* fileName, bool fixupPointers=false); - - virtual void parse(int verboseMode); - - virtual void parseData(); - - virtual void writeDNA(FILE* fp); - - void addStruct(const char* structType,void* data, int len, void* oldPtr, int code); - - }; + void addStruct(const char* structType, void* data, int len, void* oldPtr, int code); }; +}; // namespace bParse -#endif //B3_BULLET_FILE_H +#endif //B3_BULLET_FILE_H diff --git a/src/Bullet3Serialize/Bullet2FileLoader/b3Chunk.cpp b/src/Bullet3Serialize/Bullet2FileLoader/b3Chunk.cpp index c0e1bb708..ff75ff8cc 100644 --- a/src/Bullet3Serialize/Bullet2FileLoader/b3Chunk.cpp +++ b/src/Bullet3Serialize/Bullet2FileLoader/b3Chunk.cpp @@ -17,15 +17,13 @@ subject to the following restrictions: #include "b3Defines.h" #include "b3File.h" -#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__) +#if !defined(__CELLOS_LV2__) && !defined(__MWERKS__) #include #endif #include - using namespace bParse; - // ----------------------------------------------------- // short ChunkUtils::swapShort(short sht) { @@ -57,19 +55,15 @@ int ChunkUtils::getOffset(int flags) if (VOID_IS_8) { - if (flags &FD_BITS_VARIES) + if (flags & FD_BITS_VARIES) res = sizeof(bChunkPtr4); } else { - if (flags &FD_BITS_VARIES) + if (flags & FD_BITS_VARIES) res = sizeof(bChunkPtr8); } return res; } - - - - //eof diff --git a/src/Bullet3Serialize/Bullet2FileLoader/b3Chunk.h b/src/Bullet3Serialize/Bullet2FileLoader/b3Chunk.h index 03ecb6b4f..c9d0f37d9 100644 --- a/src/Bullet3Serialize/Bullet2FileLoader/b3Chunk.h +++ b/src/Bullet3Serialize/Bullet2FileLoader/b3Chunk.h @@ -16,77 +16,69 @@ subject to the following restrictions: #ifndef __BCHUNK_H__ #define __BCHUNK_H__ -#if defined (_WIN32) && ! defined (__MINGW32__) - #define b3Long64 __int64 -#elif defined (__MINGW32__) - #include - #define b3Long64 int64_t +#if defined(_WIN32) && !defined(__MINGW32__) +#define b3Long64 __int64 +#elif defined(__MINGW32__) +#include +#define b3Long64 int64_t #else - #define b3Long64 long long +#define b3Long64 long long #endif - -namespace bParse { - - - // ----------------------------------------------------- // - class bChunkPtr4 - { - public: - bChunkPtr4(){} - int code; - int len; - union - { - int m_uniqueInt; - }; - int dna_nr; - int nr; +namespace bParse +{ +// ----------------------------------------------------- // +class bChunkPtr4 +{ +public: + bChunkPtr4() {} + int code; + int len; + union { + int m_uniqueInt; }; + int dna_nr; + int nr; +}; - // ----------------------------------------------------- // - class bChunkPtr8 - { - public: - bChunkPtr8(){} - int code, len; - union - { - b3Long64 oldPrev; - int m_uniqueInts[2]; - }; - int dna_nr, nr; +// ----------------------------------------------------- // +class bChunkPtr8 +{ +public: + bChunkPtr8() {} + int code, len; + union { + b3Long64 oldPrev; + int m_uniqueInts[2]; }; + int dna_nr, nr; +}; - // ----------------------------------------------------- // - class bChunkInd - { - public: - bChunkInd(){} - int code, len; - void *oldPtr; - int dna_nr, nr; - }; +// ----------------------------------------------------- // +class bChunkInd +{ +public: + bChunkInd() {} + int code, len; + void *oldPtr; + int dna_nr, nr; +}; +// ----------------------------------------------------- // +class ChunkUtils +{ +public: + // file chunk offset + static int getOffset(int flags); - // ----------------------------------------------------- // - class ChunkUtils - { - public: - - // file chunk offset - static int getOffset(int flags); + // endian utils + static short swapShort(short sht); + static int swapInt(int inte); + static b3Long64 swapLong64(b3Long64 lng); +}; - // endian utils - static short swapShort(short sht); - static int swapInt(int inte); - static b3Long64 swapLong64(b3Long64 lng); +const int CHUNK_HEADER_LEN = ((sizeof(bChunkInd))); +const bool VOID_IS_8 = ((sizeof(void *) == 8)); +} // namespace bParse - }; - - - const int CHUNK_HEADER_LEN = ((sizeof(bChunkInd))); - const bool VOID_IS_8 = ((sizeof(void*)==8)); -} - -#endif//__BCHUNK_H__ +#endif //__BCHUNK_H__ diff --git a/src/Bullet3Serialize/Bullet2FileLoader/b3Common.h b/src/Bullet3Serialize/Bullet2FileLoader/b3Common.h index 2792d8403..5884fad4d 100644 --- a/src/Bullet3Serialize/Bullet2FileLoader/b3Common.h +++ b/src/Bullet3Serialize/Bullet2FileLoader/b3Common.h @@ -16,24 +16,25 @@ subject to the following restrictions: #ifndef __BCOMMON_H__ #define __BCOMMON_H__ - #include //#include "bLog.h" #include "Bullet3Common/b3AlignedObjectArray.h" #include "Bullet3Common/b3HashMap.h" -namespace bParse { +namespace bParse +{ +class bMain; +class bFileData; +class bFile; +class bDNA; - class bMain; - class bFileData; - class bFile; - class bDNA; +// delete void* undefined +typedef struct bStructHandle +{ + int unused; +} bStructHandle; +typedef b3AlignedObjectArray bListBasePtr; +typedef b3HashMap bPtrMap; +} // namespace bParse - // delete void* undefined - typedef struct bStructHandle {int unused;}bStructHandle; - typedef b3AlignedObjectArray bListBasePtr; - typedef b3HashMap bPtrMap; -} - - -#endif//__BCOMMON_H__ +#endif //__BCOMMON_H__ diff --git a/src/Bullet3Serialize/Bullet2FileLoader/b3DNA.cpp b/src/Bullet3Serialize/Bullet2FileLoader/b3DNA.cpp index 0fe505692..09c8f2385 100644 --- a/src/Bullet3Serialize/Bullet2FileLoader/b3DNA.cpp +++ b/src/Bullet3Serialize/Bullet2FileLoader/b3DNA.cpp @@ -23,13 +23,11 @@ subject to the following restrictions: //this define will force traversal of structures, to check backward (and forward) compatibility //#define TEST_BACKWARD_FORWARD_COMPATIBILITY - using namespace bParse; - // ----------------------------------------------------- // bDNA::bDNA() - : mPtrLen(0) + : mPtrLen(0) { // -- } @@ -43,7 +41,7 @@ bDNA::~bDNA() // ----------------------------------------------------- // bool bDNA::lessThan(bDNA *file) { - return ( m_Names.size() < file->m_Names.size()); + return (m_Names.size() < file->m_Names.size()); } // ----------------------------------------------------- // @@ -53,36 +51,31 @@ char *bDNA::getName(int ind) return m_Names[ind].m_name; } - // ----------------------------------------------------- // char *bDNA::getType(int ind) { - assert(ind<= (int)mTypes.size()); + assert(ind <= (int)mTypes.size()); return mTypes[ind]; } - // ----------------------------------------------------- // short *bDNA::getStruct(int ind) { - assert(ind <= (int)mStructs.size()); + assert(ind <= (int)mStructs.size()); return mStructs[ind]; } - // ----------------------------------------------------- // short bDNA::getLength(int ind) { - assert(ind <= (int)mTlens.size()); + assert(ind <= (int)mTlens.size()); return mTlens[ind]; } - // ----------------------------------------------------- // int bDNA::getReverseType(short type) { - - int* intPtr = mStructReverse.find(type); + int *intPtr = mStructReverse.find(type); if (intPtr) return *intPtr; @@ -92,12 +85,11 @@ int bDNA::getReverseType(short type) // ----------------------------------------------------- // int bDNA::getReverseType(const char *type) { - b3HashString key(type); - int* valuePtr = mTypeLookup.find(key); + int *valuePtr = mTypeLookup.find(key); if (valuePtr) return *valuePtr; - + return -1; } @@ -110,22 +102,22 @@ int bDNA::getNumStructs() // ----------------------------------------------------- // bool bDNA::flagNotEqual(int dna_nr) { - assert(dna_nr <= (int)mCMPFlags.size()); + assert(dna_nr <= (int)mCMPFlags.size()); return mCMPFlags[dna_nr] == FDF_STRUCT_NEQU; } // ----------------------------------------------------- // bool bDNA::flagEqual(int dna_nr) { - assert(dna_nr <= (int)mCMPFlags.size()); + assert(dna_nr <= (int)mCMPFlags.size()); int flag = mCMPFlags[dna_nr]; - return flag == FDF_STRUCT_EQU; + return flag == FDF_STRUCT_EQU; } // ----------------------------------------------------- // bool bDNA::flagNone(int dna_nr) { - assert(dna_nr <= (int)mCMPFlags.size()); + assert(dna_nr <= (int)mCMPFlags.size()); return mCMPFlags[dna_nr] == FDF_NONE; } @@ -143,15 +135,15 @@ void bDNA::initRecurseCmpFlags(int iter) short *oldStrc = mStructs[iter]; short type = oldStrc[0]; - for (int i=0; i<(int)mStructs.size(); i++) + for (int i = 0; i < (int)mStructs.size(); i++) { - if (i != iter && mCMPFlags[i] == FDF_STRUCT_EQU ) + if (i != iter && mCMPFlags[i] == FDF_STRUCT_EQU) { short *curStruct = mStructs[i]; int eleLen = curStruct[1]; - curStruct+=2; + curStruct += 2; - for (int j=0; jgetReverseType(typeName); if (newLookup == -1) { @@ -210,71 +198,61 @@ void bDNA::initCmpFlags(bDNA *memDNA) if (oldLookup < memDNA->mStructs.size()) { short *curStruct = memDNA->mStructs[oldLookup]; -#endif - - +#endif - // rebuild... - mCMPFlags[i] = FDF_STRUCT_NEQU; + // rebuild... + mCMPFlags[i] = FDF_STRUCT_NEQU; #ifndef TEST_BACKWARD_FORWARD_COMPATIBILITY - if (curStruct[1] == oldStruct[1]) + if (curStruct[1] == oldStruct[1]) + { + // type len same ... + if (mTlens[oldStruct[0]] == memDNA->mTlens[curStruct[0]]) { - // type len same ... - if (mTlens[oldStruct[0]] == memDNA->mTlens[curStruct[0]]) + bool isSame = true; + int elementLength = oldStruct[1]; + + curStruct += 2; + oldStruct += 2; + + for (int j = 0; j < elementLength; j++, curStruct += 2, oldStruct += 2) { - bool isSame = true; - int elementLength = oldStruct[1]; - - - curStruct+=2; - oldStruct+=2; - - - for (int j=0; jmTypes[curStruct[0]]) != 0) { - // type the same - //const char* typeFileDNA = mTypes[oldStruct[0]]; - //const char* typeMemDNA = mTypes[curStruct[0]]; - if (strcmp(mTypes[oldStruct[0]], memDNA->mTypes[curStruct[0]])!=0) - { - isSame=false; - break; - } - - // name the same - if (strcmp(m_Names[oldStruct[1]].m_name, memDNA->m_Names[curStruct[1]].m_name)!=0) - { - isSame=false; - break; - } + isSame = false; + break; + } + + // name the same + if (strcmp(m_Names[oldStruct[1]].m_name, memDNA->m_Names[curStruct[1]].m_name) != 0) + { + isSame = false; + break; } - // flag valid == - if (isSame) - mCMPFlags[i] = FDF_STRUCT_EQU; } + // flag valid == + if (isSame) + mCMPFlags[i] = FDF_STRUCT_EQU; } -#endif } - } - - - - - - // recurse in - for ( i=0; i<(int)mStructs.size(); i++) - { - if (mCMPFlags[i] == FDF_STRUCT_NEQU) - initRecurseCmpFlags(i); +#endif } } +// recurse in +for (i = 0; i < (int)mStructs.size(); i++) +{ + if (mCMPFlags[i] == FDF_STRUCT_NEQU) + initRecurseCmpFlags(i); +} +} - - -static int name_is_array(char* name, int* dim1, int* dim2) { +static int name_is_array(char *name, int *dim1, int *dim2) +{ int len = strlen(name); /*fprintf(stderr,"[%s]",name);*/ /*if (len >= 1) { @@ -284,58 +262,77 @@ static int name_is_array(char* name, int* dim1, int* dim2) { return 0;*/ char *bp; int num; - if (dim1) { + if (dim1) + { *dim1 = 1; } - if (dim2) { + if (dim2) + { *dim2 = 1; } bp = strchr(name, '['); - if (!bp) { + if (!bp) + { return 0; } num = 0; - while (++bp < name+len-1) { + while (++bp < name + len - 1) + { const char c = *bp; - if (c == ']') { + if (c == ']') + { break; } - if (c <= '9' && c >= '0') { + if (c <= '9' && c >= '0') + { num *= 10; num += (c - '0'); - } else { + } + else + { printf("array parse error.\n"); return 0; } } - if (dim2) { + if (dim2) + { *dim2 = num; } /* find second dim, if any. */ bp = strchr(bp, '['); - if (!bp) { + if (!bp) + { return 1; /* at least we got the first dim. */ } num = 0; - while (++bp < name+len-1) { + while (++bp < name + len - 1) + { const char c = *bp; - if (c == ']') { + if (c == ']') + { break; } - if (c <= '9' && c >= '0') { + if (c <= '9' && c >= '0') + { num *= 10; num += (c - '0'); - } else { + } + else + { printf("array2 parse error.\n"); return 1; } } - if (dim1) { - if (dim2) { + if (dim1) + { + if (dim2) + { *dim1 = *dim2; *dim2 = num; - } else { + } + else + { *dim1 = num; } } @@ -343,14 +340,15 @@ static int name_is_array(char* name, int* dim1, int* dim2) { return 1; } - // ----------------------------------------------------- // void bDNA::init(char *data, int len, bool swap) { - int *intPtr=0;short *shtPtr=0; - char *cp = 0;int dataLen =0; + int *intPtr = 0; + short *shtPtr = 0; + char *cp = 0; + int dataLen = 0; //long nr=0; - intPtr = (int*)data; + intPtr = (int *)data; /* SDNA (4 bytes) (magic number) @@ -360,38 +358,35 @@ void bDNA::init(char *data, int len, bool swap) */ - if (strncmp(data, "SDNA", 4)==0) + if (strncmp(data, "SDNA", 4) == 0) { // skip ++ NAME - intPtr++; intPtr++; + intPtr++; + intPtr++; } - - // Parse names - if (swap) + if (swap) { *intPtr = ChunkUtils::swapInt(*intPtr); } dataLen = *intPtr; intPtr++; - cp = (char*)intPtr; + cp = (char *)intPtr; int i; - for ( i=0; i */ - intPtr = (int*)cp; - assert(strncmp(cp, "TYPE", 4)==0); intPtr++; + intPtr = (int *)cp; + assert(strncmp(cp, "TYPE", 4) == 0); + intPtr++; - if (swap) + if (swap) { *intPtr = ChunkUtils::swapInt(*intPtr); } dataLen = *intPtr; intPtr++; - cp = (char*)intPtr; - for ( i=0; i */ - intPtr = (int*)shtPtr; - cp = (char*)intPtr; - assert(strncmp(cp, "STRC", 4)==0); intPtr++; + intPtr = (int *)shtPtr; + cp = (char *)intPtr; + assert(strncmp(cp, "STRC", 4) == 0); + intPtr++; - if (swap) + if (swap) { *intPtr = ChunkUtils::swapInt(*intPtr); } dataLen = *intPtr; intPtr++; - - shtPtr = (short*)intPtr; - for ( i=0; i mCMPFlags; - int getArraySize(char* str); - int getArraySizeNew(short name) - { - const bNameInfo& nameInfo = m_Names[name]; - return nameInfo.m_dim0*nameInfo.m_dim1; - } - int getElementSize(short type, short name) - { - const bNameInfo& nameInfo = m_Names[name]; - int size = nameInfo.m_isPointer ? mPtrLen*nameInfo.m_dim0*nameInfo.m_dim1 : mTlens[type]*nameInfo.m_dim0*nameInfo.m_dim1; - return size; - } + b3AlignedObjectArray m_Names; + b3AlignedObjectArray mTypes; + b3AlignedObjectArray mStructs; + b3AlignedObjectArray mTlens; + b3HashMap mStructReverse; + b3HashMap mTypeLookup; - int getNumNames() const - { - return m_Names.size(); - } + int mPtrLen; +}; +} // namespace bParse - char *getName(int ind); - char *getType(int ind); - short *getStruct(int ind); - short getLength(int ind); - int getReverseType(short type); - int getReverseType(const char *type); - - - int getNumStructs(); - - // - bool lessThan(bDNA* other); - - void initCmpFlags(bDNA *memDNA); - bool flagNotEqual(int dna_nr); - bool flagEqual(int dna_nr); - bool flagNone(int dna_nr); - - - int getPointerSize(); - - void dumpTypeDefinitions(); - - - private: - enum FileDNAFlags - { - FDF_NONE=0, - FDF_STRUCT_NEQU, - FDF_STRUCT_EQU - }; - - void initRecurseCmpFlags(int i); - - b3AlignedObjectArray mCMPFlags; - - b3AlignedObjectArray m_Names; - b3AlignedObjectArray mTypes; - b3AlignedObjectArray mStructs; - b3AlignedObjectArray mTlens; - b3HashMap mStructReverse; - b3HashMap mTypeLookup; - - int mPtrLen; - - - - - }; -} - - -#endif//__BDNA_H__ +#endif //__BDNA_H__ diff --git a/src/Bullet3Serialize/Bullet2FileLoader/b3Defines.h b/src/Bullet3Serialize/Bullet2FileLoader/b3Defines.h index 8f28d3c44..0524c94db 100644 --- a/src/Bullet3Serialize/Bullet2FileLoader/b3Defines.h +++ b/src/Bullet3Serialize/Bullet2FileLoader/b3Defines.h @@ -19,118 +19,131 @@ #ifndef __B_DEFINES_H__ #define __B_DEFINES_H__ - // MISC defines, see BKE_global.h, BKE_utildefines.h #define B3_SIZEOFBLENDERHEADER 12 - // ------------------------------------------------------------ -#if defined(__sgi) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__) -# define B3_MAKE_ID(a,b,c,d) ( (int)(a)<<24 | (int)(b)<<16 | (c)<<8 | (d) ) +#if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined(__PPC__) || defined(__ppc__) || defined(__BIG_ENDIAN__) +#define B3_MAKE_ID(a, b, c, d) ((int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d)) #else -# define B3_MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) ) -#endif - - -// ------------------------------------------------------------ -#if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__) -# define B3_MAKE_ID2(c, d) ( (c)<<8 | (d) ) -#else -# define B3_MAKE_ID2(c, d) ( (d)<<8 | (c) ) +#define B3_MAKE_ID(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a)) #endif // ------------------------------------------------------------ -#define B3_ID_SCE B3_MAKE_ID2('S', 'C') -#define B3_ID_LI B3_MAKE_ID2('L', 'I') -#define B3_ID_OB B3_MAKE_ID2('O', 'B') -#define B3_ID_ME B3_MAKE_ID2('M', 'E') -#define B3_ID_CU B3_MAKE_ID2('C', 'U') -#define B3_ID_MB B3_MAKE_ID2('M', 'B') -#define B3_ID_MA B3_MAKE_ID2('M', 'A') -#define B3_ID_TE B3_MAKE_ID2('T', 'E') -#define B3_ID_IM B3_MAKE_ID2('I', 'M') -#define B3_ID_IK B3_MAKE_ID2('I', 'K') -#define B3_ID_WV B3_MAKE_ID2('W', 'V') -#define B3_ID_LT B3_MAKE_ID2('L', 'T') -#define B3_ID_SE B3_MAKE_ID2('S', 'E') -#define B3_ID_LF B3_MAKE_ID2('L', 'F') -#define B3_ID_LA B3_MAKE_ID2('L', 'A') -#define B3_ID_CA B3_MAKE_ID2('C', 'A') -#define B3_ID_IP B3_MAKE_ID2('I', 'P') -#define B3_ID_KE B3_MAKE_ID2('K', 'E') -#define B3_ID_WO B3_MAKE_ID2('W', 'O') -#define B3_ID_SCR B3_MAKE_ID2('S', 'R') -#define B3_ID_VF B3_MAKE_ID2('V', 'F') -#define B3_ID_TXT B3_MAKE_ID2('T', 'X') -#define B3_ID_SO B3_MAKE_ID2('S', 'O') -#define B3_ID_SAMPLE B3_MAKE_ID2('S', 'A') -#define B3_ID_GR B3_MAKE_ID2('G', 'R') -#define B3_ID_ID B3_MAKE_ID2('I', 'D') -#define B3_ID_AR B3_MAKE_ID2('A', 'R') -#define B3_ID_AC B3_MAKE_ID2('A', 'C') -#define B3_ID_SCRIPT B3_MAKE_ID2('P', 'Y') -#define B3_ID_FLUIDSIM B3_MAKE_ID2('F', 'S') -#define B3_ID_NT B3_MAKE_ID2('N', 'T') -#define B3_ID_BR B3_MAKE_ID2('B', 'R') - - -#define B3_ID_SEQ B3_MAKE_ID2('S', 'Q') -#define B3_ID_CO B3_MAKE_ID2('C', 'O') -#define B3_ID_PO B3_MAKE_ID2('A', 'C') -#define B3_ID_NLA B3_MAKE_ID2('N', 'L') - -#define B3_ID_VS B3_MAKE_ID2('V', 'S') -#define B3_ID_VN B3_MAKE_ID2('V', 'N') - +#if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined(__PPC__) || defined(__ppc__) || defined(__BIG_ENDIAN__) +#define B3_MAKE_ID2(c, d) ((c) << 8 | (d)) +#else +#define B3_MAKE_ID2(c, d) ((d) << 8 | (c)) +#endif // ------------------------------------------------------------ -#define B3_FORM B3_MAKE_ID('F','O','R','M') -#define B3_DDG1 B3_MAKE_ID('3','D','G','1') -#define B3_DDG2 B3_MAKE_ID('3','D','G','2') -#define B3_DDG3 B3_MAKE_ID('3','D','G','3') -#define B3_DDG4 B3_MAKE_ID('3','D','G','4') -#define B3_GOUR B3_MAKE_ID('G','O','U','R') -#define B3_BLEN B3_MAKE_ID('B','L','E','N') -#define B3_DER_ B3_MAKE_ID('D','E','R','_') -#define B3_V100 B3_MAKE_ID('V','1','0','0') -#define B3_DATA B3_MAKE_ID('D','A','T','A') -#define B3_GLOB B3_MAKE_ID('G','L','O','B') -#define B3_IMAG B3_MAKE_ID('I','M','A','G') -#define B3_TEST B3_MAKE_ID('T','E','S','T') -#define B3_USER B3_MAKE_ID('U','S','E','R') +#define B3_ID_SCE B3_MAKE_ID2('S', 'C') +#define B3_ID_LI B3_MAKE_ID2('L', 'I') +#define B3_ID_OB B3_MAKE_ID2('O', 'B') +#define B3_ID_ME B3_MAKE_ID2('M', 'E') +#define B3_ID_CU B3_MAKE_ID2('C', 'U') +#define B3_ID_MB B3_MAKE_ID2('M', 'B') +#define B3_ID_MA B3_MAKE_ID2('M', 'A') +#define B3_ID_TE B3_MAKE_ID2('T', 'E') +#define B3_ID_IM B3_MAKE_ID2('I', 'M') +#define B3_ID_IK B3_MAKE_ID2('I', 'K') +#define B3_ID_WV B3_MAKE_ID2('W', 'V') +#define B3_ID_LT B3_MAKE_ID2('L', 'T') +#define B3_ID_SE B3_MAKE_ID2('S', 'E') +#define B3_ID_LF B3_MAKE_ID2('L', 'F') +#define B3_ID_LA B3_MAKE_ID2('L', 'A') +#define B3_ID_CA B3_MAKE_ID2('C', 'A') +#define B3_ID_IP B3_MAKE_ID2('I', 'P') +#define B3_ID_KE B3_MAKE_ID2('K', 'E') +#define B3_ID_WO B3_MAKE_ID2('W', 'O') +#define B3_ID_SCR B3_MAKE_ID2('S', 'R') +#define B3_ID_VF B3_MAKE_ID2('V', 'F') +#define B3_ID_TXT B3_MAKE_ID2('T', 'X') +#define B3_ID_SO B3_MAKE_ID2('S', 'O') +#define B3_ID_SAMPLE B3_MAKE_ID2('S', 'A') +#define B3_ID_GR B3_MAKE_ID2('G', 'R') +#define B3_ID_ID B3_MAKE_ID2('I', 'D') +#define B3_ID_AR B3_MAKE_ID2('A', 'R') +#define B3_ID_AC B3_MAKE_ID2('A', 'C') +#define B3_ID_SCRIPT B3_MAKE_ID2('P', 'Y') +#define B3_ID_FLUIDSIM B3_MAKE_ID2('F', 'S') +#define B3_ID_NT B3_MAKE_ID2('N', 'T') +#define B3_ID_BR B3_MAKE_ID2('B', 'R') +#define B3_ID_SEQ B3_MAKE_ID2('S', 'Q') +#define B3_ID_CO B3_MAKE_ID2('C', 'O') +#define B3_ID_PO B3_MAKE_ID2('A', 'C') +#define B3_ID_NLA B3_MAKE_ID2('N', 'L') + +#define B3_ID_VS B3_MAKE_ID2('V', 'S') +#define B3_ID_VN B3_MAKE_ID2('V', 'N') // ------------------------------------------------------------ -#define B3_DNA1 B3_MAKE_ID('D','N','A','1') -#define B3_REND B3_MAKE_ID('R','E','N','D') -#define B3_ENDB B3_MAKE_ID('E','N','D','B') -#define B3_NAME B3_MAKE_ID('N','A','M','E') -#define B3_SDNA B3_MAKE_ID('S','D','N','A') -#define B3_TYPE B3_MAKE_ID('T','Y','P','E') -#define B3_TLEN B3_MAKE_ID('T','L','E','N') -#define B3_STRC B3_MAKE_ID('S','T','R','C') - +#define B3_FORM B3_MAKE_ID('F', 'O', 'R', 'M') +#define B3_DDG1 B3_MAKE_ID('3', 'D', 'G', '1') +#define B3_DDG2 B3_MAKE_ID('3', 'D', 'G', '2') +#define B3_DDG3 B3_MAKE_ID('3', 'D', 'G', '3') +#define B3_DDG4 B3_MAKE_ID('3', 'D', 'G', '4') +#define B3_GOUR B3_MAKE_ID('G', 'O', 'U', 'R') +#define B3_BLEN B3_MAKE_ID('B', 'L', 'E', 'N') +#define B3_DER_ B3_MAKE_ID('D', 'E', 'R', '_') +#define B3_V100 B3_MAKE_ID('V', '1', '0', '0') +#define B3_DATA B3_MAKE_ID('D', 'A', 'T', 'A') +#define B3_GLOB B3_MAKE_ID('G', 'L', 'O', 'B') +#define B3_IMAG B3_MAKE_ID('I', 'M', 'A', 'G') +#define B3_TEST B3_MAKE_ID('T', 'E', 'S', 'T') +#define B3_USER B3_MAKE_ID('U', 'S', 'E', 'R') // ------------------------------------------------------------ -#define B3_SWITCH_INT(a) { \ - char s_i, *p_i; \ - p_i= (char *)&(a); \ - s_i=p_i[0]; p_i[0]=p_i[3]; p_i[3]=s_i; \ - s_i=p_i[1]; p_i[1]=p_i[2]; p_i[2]=s_i; } +#define B3_DNA1 B3_MAKE_ID('D', 'N', 'A', '1') +#define B3_REND B3_MAKE_ID('R', 'E', 'N', 'D') +#define B3_ENDB B3_MAKE_ID('E', 'N', 'D', 'B') +#define B3_NAME B3_MAKE_ID('N', 'A', 'M', 'E') +#define B3_SDNA B3_MAKE_ID('S', 'D', 'N', 'A') +#define B3_TYPE B3_MAKE_ID('T', 'Y', 'P', 'E') +#define B3_TLEN B3_MAKE_ID('T', 'L', 'E', 'N') +#define B3_STRC B3_MAKE_ID('S', 'T', 'R', 'C') // ------------------------------------------------------------ -#define B3_SWITCH_SHORT(a) { \ - char s_i, *p_i; \ - p_i= (char *)&(a); \ - s_i=p_i[0]; p_i[0]=p_i[1]; p_i[1]=s_i; } +#define B3_SWITCH_INT(a) \ + { \ + char s_i, *p_i; \ + p_i = (char *)&(a); \ + s_i = p_i[0]; \ + p_i[0] = p_i[3]; \ + p_i[3] = s_i; \ + s_i = p_i[1]; \ + p_i[1] = p_i[2]; \ + p_i[2] = s_i; \ + } // ------------------------------------------------------------ -#define B3_SWITCH_LONGINT(a) { \ - char s_i, *p_i; \ - p_i= (char *)&(a); \ - s_i=p_i[0]; p_i[0]=p_i[7]; p_i[7]=s_i; \ - s_i=p_i[1]; p_i[1]=p_i[6]; p_i[6]=s_i; \ - s_i=p_i[2]; p_i[2]=p_i[5]; p_i[5]=s_i; \ - s_i=p_i[3]; p_i[3]=p_i[4]; p_i[4]=s_i; } +#define B3_SWITCH_SHORT(a) \ + { \ + char s_i, *p_i; \ + p_i = (char *)&(a); \ + s_i = p_i[0]; \ + p_i[0] = p_i[1]; \ + p_i[1] = s_i; \ + } -#endif//__B_DEFINES_H__ +// ------------------------------------------------------------ +#define B3_SWITCH_LONGINT(a) \ + { \ + char s_i, *p_i; \ + p_i = (char *)&(a); \ + s_i = p_i[0]; \ + p_i[0] = p_i[7]; \ + p_i[7] = s_i; \ + s_i = p_i[1]; \ + p_i[1] = p_i[6]; \ + p_i[6] = s_i; \ + s_i = p_i[2]; \ + p_i[2] = p_i[5]; \ + p_i[5] = s_i; \ + s_i = p_i[3]; \ + p_i[3] = p_i[4]; \ + p_i[4] = s_i; \ + } + +#endif //__B_DEFINES_H__ diff --git a/src/Bullet3Serialize/Bullet2FileLoader/b3File.cpp b/src/Bullet3Serialize/Bullet2FileLoader/b3File.cpp index 432f7fc2b..145de62db 100644 --- a/src/Bullet3Serialize/Bullet2FileLoader/b3File.cpp +++ b/src/Bullet3Serialize/Bullet2FileLoader/b3File.cpp @@ -29,39 +29,38 @@ subject to the following restrictions: using namespace bParse; #define MAX_STRLEN 1024 -const char* getCleanName(const char* memName, char* buffer) +const char *getCleanName(const char *memName, char *buffer) { int slen = strlen(memName); - assert(slen 0) { - if (strncmp((tempBuffer + ChunkUtils::getOffset(mFlags)), "SDNANAME", 8) ==0) + if (strncmp((tempBuffer + ChunkUtils::getOffset(mFlags)), "SDNANAME", 8) == 0) dna.oldPtr = (tempBuffer + ChunkUtils::getOffset(mFlags)); - else dna.oldPtr = 0; + else + dna.oldPtr = 0; } - else dna.oldPtr = 0; + else + dna.oldPtr = 0; } // Some Bullet files are missing the DNA1 block // In Blender it's DNA1 + ChunkUtils::getOffset() + SDNA + NAME // In Bullet tests its SDNA + NAME - else if (strncmp(tempBuffer, "SDNANAME", 8) ==0) + else if (strncmp(tempBuffer, "SDNANAME", 8) == 0) { dna.oldPtr = blenderData + i; - dna.len = mFileLen-i; + dna.len = mFileLen - i; // Also no REND block, so exit now. - if (mVersion==276) break; + if (mVersion == 276) break; } - if (mDataStart && dna.oldPtr) break; + if (mDataStart && dna.oldPtr) break; tempBuffer++; } if (!dna.oldPtr || !dna.len) @@ -239,43 +231,35 @@ void bFile::parseInternal(int verboseMode, char* memDna,int memDnaLength) return; } - mFileDNA = new bDNA(); - ///mFileDNA->init will convert part of DNA file endianness to current CPU endianness if necessary - mFileDNA->init((char*)dna.oldPtr, dna.len, (mFlags & FD_ENDIAN_SWAP)!=0); + mFileDNA->init((char *)dna.oldPtr, dna.len, (mFlags & FD_ENDIAN_SWAP) != 0); - - if (mVersion==276) + if (mVersion == 276) { int i; - for (i=0;igetNumNames();i++) + for (i = 0; i < mFileDNA->getNumNames(); i++) { - if (strcmp(mFileDNA->getName(i),"int")==0) + if (strcmp(mFileDNA->getName(i), "int") == 0) { mFlags |= FD_BROKEN_DNA; } } - if ((mFlags&FD_BROKEN_DNA)!=0) + if ((mFlags & FD_BROKEN_DNA) != 0) { //printf("warning: fixing some broken DNA version\n"); } } - - if (verboseMode & FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS) mFileDNA->dumpTypeDefinitions(); mMemoryDNA = new bDNA(); - int littleEndian= 1; - littleEndian= ((char*)&littleEndian)[0]; - - mMemoryDNA->init(memDna,memDnaLength,littleEndian==0); - - + int littleEndian = 1; + littleEndian = ((char *)&littleEndian)[0]; + mMemoryDNA->init(memDna, memDnaLength, littleEndian == 0); ///@todo we need a better version check, add version/sub version info from FileGlobal into memory DNA/header files if (mMemoryDNA->getNumNames() != mFileDNA->getNumNames()) @@ -290,7 +274,6 @@ void bFile::parseInternal(int verboseMode, char* memDna,int memDnaLength) //printf ("Warning, file DNA is newer than built in."); } - mFileDNA->initCmpFlags(mMemoryDNA); parseData(); @@ -298,102 +281,95 @@ void bFile::parseInternal(int verboseMode, char* memDna,int memDnaLength) resolvePointers(verboseMode); updateOldPointers(); - - } - - // ----------------------------------------------------- // -void bFile::swap(char *head, bChunkInd& dataChunk, bool ignoreEndianFlag) +void bFile::swap(char *head, bChunkInd &dataChunk, bool ignoreEndianFlag) { char *data = head; short *strc = mFileDNA->getStruct(dataChunk.dna_nr); - - const char s[] = "SoftBodyMaterialData"; int szs = sizeof(s); - if (strncmp((char*)&dataChunk.code,"ARAY",4)==0) + if (strncmp((char *)&dataChunk.code, "ARAY", 4) == 0) { short *oldStruct = mFileDNA->getStruct(dataChunk.dna_nr); char *oldType = mFileDNA->getType(oldStruct[0]); - if (strncmp(oldType,s,szs)==0) + if (strncmp(oldType, s, szs) == 0) { return; } } - int len = mFileDNA->getLength(strc[0]); - for (int i=0; icode & 0xFFFF)==0) - c->code >>=16; + bChunkPtr4 *c = (bChunkPtr4 *)dataPtr; + if ((c->code & 0xFFFF) == 0) + c->code >>= 16; B3_SWITCH_INT(c->len); B3_SWITCH_INT(c->dna_nr); B3_SWITCH_INT(c->nr); - } else - { - bChunkPtr8* c = (bChunkPtr8*) dataPtr; - if ((c->code & 0xFFFF)==0) - c->code >>=16; - B3_SWITCH_INT(c->len); - B3_SWITCH_INT(c->dna_nr); - B3_SWITCH_INT(c->nr); - } - } else - { - if (mFlags &FD_BITS_VARIES) + else { - bChunkPtr8*c = (bChunkPtr8*) dataPtr; - if ((c->code & 0xFFFF)==0) - c->code >>=16; + bChunkPtr8 *c = (bChunkPtr8 *)dataPtr; + if ((c->code & 0xFFFF) == 0) + c->code >>= 16; B3_SWITCH_INT(c->len); B3_SWITCH_INT(c->dna_nr); B3_SWITCH_INT(c->nr); - - } else - { - bChunkPtr4* c = (bChunkPtr4*) dataPtr; - if ((c->code & 0xFFFF)==0) - c->code >>=16; - B3_SWITCH_INT(c->len); - - B3_SWITCH_INT(c->dna_nr); - B3_SWITCH_INT(c->nr); - } } + else + { + if (mFlags & FD_BITS_VARIES) + { + bChunkPtr8 *c = (bChunkPtr8 *)dataPtr; + if ((c->code & 0xFFFF) == 0) + c->code >>= 16; + B3_SWITCH_INT(c->len); + B3_SWITCH_INT(c->dna_nr); + B3_SWITCH_INT(c->nr); + } + else + { + bChunkPtr4 *c = (bChunkPtr4 *)dataPtr; + if ((c->code & 0xFFFF) == 0) + c->code >>= 16; + B3_SWITCH_INT(c->len); + B3_SWITCH_INT(c->dna_nr); + B3_SWITCH_INT(c->nr); + } + } } - -void bFile::swapDNA(char* ptr) +void bFile::swapDNA(char *ptr) { - bool swap = ((mFlags & FD_ENDIAN_SWAP)!=0); + bool swap = ((mFlags & FD_ENDIAN_SWAP) != 0); - char* data = &ptr[20]; -// void bDNA::init(char *data, int len, bool swap) - int *intPtr=0;short *shtPtr=0; - char *cp = 0;int dataLen =0; + char *data = &ptr[20]; + // void bDNA::init(char *data, int len, bool swap) + int *intPtr = 0; + short *shtPtr = 0; + char *cp = 0; + int dataLen = 0; //long nr=0; - intPtr = (int*)data; + intPtr = (int *)data; /* SDNA (4 bytes) (magic number) @@ -403,14 +379,13 @@ void bFile::swapDNA(char* ptr) */ - if (strncmp(data, "SDNA", 4)==0) + if (strncmp(data, "SDNA", 4) == 0) { // skip ++ NAME - intPtr++; intPtr++; + intPtr++; + intPtr++; } - - // Parse names if (swap) dataLen = ChunkUtils::swapInt(*intPtr); @@ -420,16 +395,15 @@ void bFile::swapDNA(char* ptr) *intPtr = ChunkUtils::swapInt(*intPtr); intPtr++; - cp = (char*)intPtr; + cp = (char *)intPtr; int i; - for ( i=0; i */ - intPtr = (int*)cp; - assert(strncmp(cp, "TYPE", 4)==0); intPtr++; + intPtr = (int *)cp; + assert(strncmp(cp, "TYPE", 4) == 0); + intPtr++; if (swap) dataLen = ChunkUtils::swapInt(*intPtr); @@ -450,14 +425,14 @@ void bFile::swapDNA(char* ptr) intPtr++; - cp = (char*)intPtr; - for ( i=0; i */ - intPtr = (int*)shtPtr; - cp = (char*)intPtr; - assert(strncmp(cp, "STRC", 4)==0); + intPtr = (int *)shtPtr; + cp = (char *)intPtr; + assert(strncmp(cp, "STRC", 4) == 0); intPtr++; if (swap) @@ -505,66 +480,56 @@ void bFile::swapDNA(char* ptr) intPtr++; - - shtPtr = (short*)intPtr; - for ( i=0; i=0) + if (dataChunk.dna_nr >= 0) { - swap(dataPtrHead, dataChunk,ignoreEndianFlag); - } else + swap(dataPtrHead, dataChunk, ignoreEndianFlag); + } + else { //printf("unknown chunk\n"); } @@ -602,7 +568,7 @@ void bFile::preSwap() // next please! dataPtr += seek; - seek = getNextBlock(&dataChunk, dataPtr, mFlags); + seek = getNextBlock(&dataChunk, dataPtr, mFlags); if (seek < 0) break; } @@ -610,56 +576,50 @@ void bFile::preSwap() if (mFlags & FD_ENDIAN_SWAP) { mFlags &= ~FD_ENDIAN_SWAP; - } else + } + else { mFlags |= FD_ENDIAN_SWAP; } - - - } - // ----------------------------------------------------- // -char* bFile::readStruct(char *head, bChunkInd& dataChunk) +char *bFile::readStruct(char *head, bChunkInd &dataChunk) { bool ignoreEndianFlag = false; if (mFlags & FD_ENDIAN_SWAP) swap(head, dataChunk, ignoreEndianFlag); - - if (!mFileDNA->flagEqual(dataChunk.dna_nr)) { // Ouch! need to rebuild the struct - short *oldStruct,*curStruct; + short *oldStruct, *curStruct; char *oldType, *newType; int oldLen, curLen, reverseOld; - oldStruct = mFileDNA->getStruct(dataChunk.dna_nr); oldType = mFileDNA->getType(oldStruct[0]); oldLen = mFileDNA->getLength(oldStruct[0]); - if ((mFlags&FD_BROKEN_DNA)!=0) + if ((mFlags & FD_BROKEN_DNA) != 0) { - if ((strcmp(oldType,"b3QuantizedBvhNodeData")==0)&&oldLen==20) + if ((strcmp(oldType, "b3QuantizedBvhNodeData") == 0) && oldLen == 20) { return 0; } - if ((strcmp(oldType,"b3ShortIntIndexData")==0)) + if ((strcmp(oldType, "b3ShortIntIndexData") == 0)) { int allocLen = 2; - char *dataAlloc = new char[(dataChunk.nr*allocLen)+1]; - memset(dataAlloc, 0, (dataChunk.nr*allocLen)+1); - short* dest = (short*) dataAlloc; - const short* src = (short*) head; - for (int i=0;igetReverseType(oldType); - if ((reverseOld!=-1)) + if ((reverseOld != -1)) { // make sure it's here //assert(reverseOld!= -1 && "getReverseType() returned -1, struct required!"); @@ -686,39 +644,38 @@ char* bFile::readStruct(char *head, bChunkInd& dataChunk) newType = mMemoryDNA->getType(curStruct[0]); curLen = mMemoryDNA->getLength(curStruct[0]); - - // make sure it's the same - assert((strcmp(oldType, newType)==0) && "internal error, struct mismatch!"); - + assert((strcmp(oldType, newType) == 0) && "internal error, struct mismatch!"); // numBlocks * length - int allocLen = (curLen); - char *dataAlloc = new char[(dataChunk.nr*allocLen)+1]; - memset(dataAlloc, 0, (dataChunk.nr*allocLen)); + int allocLen = (curLen); + char *dataAlloc = new char[(dataChunk.nr * allocLen) + 1]; + memset(dataAlloc, 0, (dataChunk.nr * allocLen)); // track allocated addDataBlock(dataAlloc); char *cur = dataAlloc; char *old = head; - for (int block=0; blockgetStruct(dataChunk.dna_nr); oldType = mFileDNA->getType(oldStruct[0]); - printf("%s equal structure, just memcpy\n",oldType); -#endif // + printf("%s equal structure, just memcpy\n", oldType); +#endif // } - - char *dataAlloc = new char[(dataChunk.len)+1]; - memset(dataAlloc, 0, dataChunk.len+1); - + char *dataAlloc = new char[(dataChunk.len) + 1]; + memset(dataAlloc, 0, dataChunk.len + 1); // track allocated addDataBlock(dataAlloc); memcpy(dataAlloc, head, dataChunk.len); return dataAlloc; - } - // ----------------------------------------------------- // void bFile::parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bool fixupPointers) { @@ -751,7 +704,7 @@ void bFile::parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bo if (new_dna == -1) return; //disable this, because we need to fixup pointers/ListBase - if (0)//mFileDNA->flagEqual(old_dna)) + if (0) //mFileDNA->flagEqual(old_dna)) { short *strc = mFileDNA->getStruct(old_dna); int len = mFileDNA->getLength(strc[0]); @@ -766,31 +719,29 @@ void bFile::parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bo int elementLength, size, revType, old_nr, new_nr, fpLen; short firstStructType; - // File to memory lookup memoryStruct = mMemoryDNA->getStruct(new_dna); fileStruct = mFileDNA->getStruct(old_dna); firstStruct = fileStruct; - filePtrOld = fileStruct; firstStructType = mMemoryDNA->getStruct(0)[0]; // Get number of elements elementLength = memoryStruct[1]; - memoryStruct+=2; + memoryStruct += 2; - cpc = strcPtr; cpo = 0; - for (int ele=0; elegetType(memoryStruct[0]); memName = mMemoryDNA->getName(memoryStruct[1]); - size = mMemoryDNA->getElementSize(memoryStruct[0], memoryStruct[1]); revType = mMemoryDNA->getReverseType(memoryStruct[0]); - if (revType != -1 && memoryStruct[0]>=firstStructType && memName[0] != '*') + if (revType != -1 && memoryStruct[0] >= firstStructType && memName[0] != '*') { cpo = getFileElement(firstStruct, memName, memType, dtPtr, &filePtrOld); if (cpo) @@ -799,94 +750,92 @@ void bFile::parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bo old_nr = mFileDNA->getReverseType(memType); new_nr = revType; fpLen = mFileDNA->getElementSize(filePtrOld[0], filePtrOld[1]); - if (arrayLen==1) + if (arrayLen == 1) { - parseStruct(cpc, cpo, old_nr, new_nr,fixupPointers); - } else + parseStruct(cpc, cpo, old_nr, new_nr, fixupPointers); + } + else { - char* tmpCpc = cpc; - char* tmpCpo = cpo; + char *tmpCpc = cpc; + char *tmpCpo = cpo; - for (int i=0;i3 && type <8) + if (type > 3 && type < 8) { char c; char *cp = data; - for (int i=0; igetPointerSize(); @@ -910,84 +857,79 @@ void bFile::safeSwapPtr(char *dst, const char *src) if (!src && !dst) return; - if (ptrFile == ptrMem) { memcpy(dst, src, ptrMem); } - else if (ptrMem==4 && ptrFile==8) + else if (ptrMem == 4 && ptrFile == 8) { - b3PointerUid* oldPtr = (b3PointerUid*)src; - b3PointerUid* newPtr = (b3PointerUid*)dst; + b3PointerUid *oldPtr = (b3PointerUid *)src; + b3PointerUid *newPtr = (b3PointerUid *)dst; if (oldPtr->m_uniqueIds[0] == oldPtr->m_uniqueIds[1]) { //Bullet stores the 32bit unique ID in both upper and lower part of 64bit pointers //so it can be used to distinguish between .blend and .bullet newPtr->m_uniqueIds[0] = oldPtr->m_uniqueIds[0]; - } else + } + else { //deal with pointers the Blender .blend style way, see //readfile.c in the Blender source tree - b3Long64 longValue = *((b3Long64*)src); + b3Long64 longValue = *((b3Long64 *)src); //endian swap for 64bit pointer otherwise truncation will fail due to trailing zeros if (mFlags & FD_ENDIAN_SWAP) B3_SWITCH_LONGINT(longValue); - *((int*)dst) = (int)(longValue>>3); + *((int *)dst) = (int)(longValue >> 3); } - } - else if (ptrMem==8 && ptrFile==4) + else if (ptrMem == 8 && ptrFile == 4) { - b3PointerUid* oldPtr = (b3PointerUid*)src; - b3PointerUid* newPtr = (b3PointerUid*)dst; + b3PointerUid *oldPtr = (b3PointerUid *)src; + b3PointerUid *newPtr = (b3PointerUid *)dst; if (oldPtr->m_uniqueIds[0] == oldPtr->m_uniqueIds[1]) { newPtr->m_uniqueIds[0] = oldPtr->m_uniqueIds[0]; newPtr->m_uniqueIds[1] = 0; - } else + } + else { - *((b3Long64*)dst)= *((int*)src); + *((b3Long64 *)dst) = *((int *)src); } } else { - printf ("%d %d\n", ptrFile,ptrMem); + printf("%d %d\n", ptrFile, ptrMem); assert(0 && "Invalid pointer len"); } - - } - // ----------------------------------------------------- // -void bFile::getMatchingFileDNA(short* dna_addr, const char* lookupName, const char* lookupType, char *strcData, char *data, bool fixupPointers) +void bFile::getMatchingFileDNA(short *dna_addr, const char *lookupName, const char *lookupType, char *strcData, char *data, bool fixupPointers) { // find the matching memory dna data // to the file being loaded. Fill the // memory with the file data... int len = dna_addr[1]; - dna_addr+=2; + dna_addr += 2; - for (int i=0; igetType(dna_addr[0]); - const char* name = mFileDNA->getName(dna_addr[1]); - - + const char *type = mFileDNA->getType(dna_addr[0]); + const char *name = mFileDNA->getName(dna_addr[1]); int eleLen = mFileDNA->getElementSize(dna_addr[0], dna_addr[1]); - if ((mFlags&FD_BROKEN_DNA)!=0) + if ((mFlags & FD_BROKEN_DNA) != 0) { - if ((strcmp(type,"short")==0)&&(strcmp(name,"int")==0)) + if ((strcmp(type, "short") == 0) && (strcmp(name, "int") == 0)) { eleLen = 0; } } - if (strcmp(lookupName, name)==0) + if (strcmp(lookupName, name) == 0) { //int arrayLenold = mFileDNA->getArraySize((char*)name.c_str()); int arrayLen = mFileDNA->getArraySizeNew(dna_addr[1]); @@ -998,7 +940,7 @@ void bFile::getMatchingFileDNA(short* dna_addr, const char* lookupName, const c // cast pointers int ptrFile = mFileDNA->getPointerSize(); int ptrMem = mMemoryDNA->getPointerSize(); - safeSwapPtr(strcData,data); + safeSwapPtr(strcData, data); if (fixupPointers) { @@ -1007,11 +949,11 @@ void bFile::getMatchingFileDNA(short* dna_addr, const char* lookupName, const c //void **sarray = (void**)strcData; //void **darray = (void**)data; - char *cpc, *cpo; - cpc = (char*)strcData; - cpo = (char*)data; + char *cpc, *cpo; + cpc = (char *)strcData; + cpo = (char *)data; - for (int a=0; agetStruct(old_nr); + short *old = firstStruct; //mFileDNA->getStruct(old_nr); int elementLength = old[1]; - old+=2; + old += 2; - for (int i=0; igetType(old[0]); - char* name = mFileDNA->getName(old[1]); + char *type = mFileDNA->getType(old[0]); + char *name = mFileDNA->getName(old[1]); int len = mFileDNA->getElementSize(old[0], old[1]); - if (strcmp(lookupName, name)==0) + if (strcmp(lookupName, name) == 0) { - if (strcmp(type, lookupType)==0) + if (strcmp(type, lookupType) == 0) { if (foundPos) *foundPos = old; @@ -1070,46 +1010,46 @@ char* bFile::getFileElement(short *firstStruct, char *lookupName, char *lookupTy } return 0; } - data+=len; + data += len; } return 0; } - // ----------------------------------------------------- // -void bFile::swapStruct(int dna_nr, char *data,bool ignoreEndianFlag) +void bFile::swapStruct(int dna_nr, char *data, bool ignoreEndianFlag) { if (dna_nr == -1) return; short *strc = mFileDNA->getStruct(dna_nr); //short *firstStrc = strc; - int elementLen= strc[1]; - strc+=2; + int elementLen = strc[1]; + strc += 2; short first = mFileDNA->getStruct(0)[0]; char *buf = data; - for (int i=0; igetType(strc[0]); char *name = mFileDNA->getName(strc[1]); int size = mFileDNA->getElementSize(strc[0], strc[1]); - if (strc[0] >= first && name[0]!='*') + if (strc[0] >= first && name[0] != '*') { int old_nr = mFileDNA->getReverseType(type); int arrayLen = mFileDNA->getArraySizeNew(strc[1]); - if (arrayLen==1) + if (arrayLen == 1) { - swapStruct(old_nr,buf,ignoreEndianFlag); - } else + swapStruct(old_nr, buf, ignoreEndianFlag); + } + else { - char* tmpBuf = buf; - for (int i=0;igetArraySize(name); int arrayLen = mFileDNA->getArraySizeNew(strc[1]); //assert(arrayLenOld == arrayLen); - swapData(buf, strc[0], arrayLen,ignoreEndianFlag); + swapData(buf, strc[0], arrayLen, ignoreEndianFlag); } - buf+=size; + buf += size; } } void bFile::resolvePointersMismatch() { -// printf("resolvePointersStructMismatch\n"); + // printf("resolvePointersStructMismatch\n"); int i; - for (i=0;i< m_pointerFixupArray.size();i++) + for (i = 0; i < m_pointerFixupArray.size(); i++) { - char* cur = m_pointerFixupArray.at(i); - void** ptrptr = (void**) cur; - void* ptr = *ptrptr; + char *cur = m_pointerFixupArray.at(i); + void **ptrptr = (void **)cur; + void *ptr = *ptrptr; ptr = findLibPointer(ptr); if (ptr) { //printf("Fixup pointer!\n"); *(ptrptr) = ptr; - } else + } + else { -// printf("pointer not found: %x\n",cur); + // printf("pointer not found: %x\n",cur); } } - - for (i=0; igetPointerSize(); int ptrFile = mFileDNA->getPointerSize(); - int blockLen = block->len / ptrFile; void *onptr = findLibPointer(*ptrptr); @@ -1168,16 +1107,16 @@ void bFile::resolvePointersMismatch() addDataBlock(newPtr); memset(newPtr, 0, blockLen * ptrMem); - void **onarray = (void**)onptr; - char *oldPtr = (char*)onarray; + void **onarray = (void **)onptr; + char *oldPtr = (char *)onarray; int p = 0; while (blockLen-- > 0) { b3PointerUid dp = {{0}}; - safeSwapPtr((char*)dp.m_uniqueIds, oldPtr); + safeSwapPtr((char *)dp.m_uniqueIds, oldPtr); - void **tptr = (void**)(newPtr + p * ptrMem); + void **tptr = (void **)(newPtr + p * ptrMem); *tptr = findLibPointer(dp.m_ptr); oldPtr += ptrFile; @@ -1190,70 +1129,63 @@ void bFile::resolvePointersMismatch() } } - ///this loop only works fine if the Blender DNA structure of the file matches the headerfiles -void bFile::resolvePointersChunk(const bChunkInd& dataChunk, int verboseMode) +void bFile::resolvePointersChunk(const bChunkInd &dataChunk, int verboseMode) { - bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA; + bParse::bDNA *fileDna = mFileDNA ? mFileDNA : mMemoryDNA; - short int* oldStruct = fileDna->getStruct(dataChunk.dna_nr); + short int *oldStruct = fileDna->getStruct(dataChunk.dna_nr); short oldLen = fileDna->getLength(oldStruct[0]); //char* structType = fileDna->getType(oldStruct[0]); - char* cur = (char*)findLibPointer(dataChunk.oldPtr); - for (int block=0; blockgetStruct(0)[0]; - char* memType; - char* memName; - short firstStructType = fileDna->getStruct(0)[0]; + char *elemPtr = strcPtr; - - char* elemPtr= strcPtr; - - short int* oldStruct = fileDna->getStruct(dna_nr); + short int *oldStruct = fileDna->getStruct(dna_nr); int elementLength = oldStruct[1]; - oldStruct+=2; + oldStruct += 2; int totalSize = 0; - for (int ele=0; elegetType(oldStruct[0]); memName = fileDna->getName(oldStruct[1]); - - int arrayLen = fileDna->getArraySizeNew(oldStruct[1]); if (memName[0] == '*') { if (arrayLen > 1) { - void **array= (void**)elemPtr; - for (int a=0; a ",&memName[1]); + printf("<%s type=\"pointer\"> ", &memName[1]); printf("%p ", array[a]); - printf("\n",&memName[1]); + printf("\n", &memName[1]); } array[a] = findLibPointer(array[a]); @@ -1261,266 +1193,259 @@ int bFile::resolvePointersStructRecursive(char *strcPtr, int dna_nr, int verbose } else { - void** ptrptr = (void**) elemPtr; - void* ptr = *ptrptr; + void **ptrptr = (void **)elemPtr; + void *ptr = *ptrptr; if (verboseMode & FD_VERBOSE_EXPORT_XML) { - for (int i=0;i ",&memName[1]); + printf("<%s type=\"pointer\"> ", &memName[1]); printf("%p ", ptr); - printf("\n",&memName[1]); + printf("\n", &memName[1]); } ptr = findLibPointer(ptr); if (ptr) { - // printf("Fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr); + // printf("Fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr); *(ptrptr) = ptr; if (memName[1] == '*' && ptrptr && *ptrptr) { // This will only work if the given **array is continuous - void **array= (void**)*(ptrptr); - void *np= array[0]; - int n=0; + void **array = (void **)*(ptrptr); + void *np = array[0]; + int n = 0; while (np) { - np= findLibPointer(array[n]); - if (np) array[n]= np; + np = findLibPointer(array[n]); + if (np) array[n] = np; n++; } } - } else + } + else { - // printf("Cannot fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr); + // printf("Cannot fixup pointer at 0x%x from 0x%x to 0x%x!\n",ptrptr,*ptrptr,ptr); } } - } else + } + else { int revType = fileDna->getReverseType(oldStruct[0]); - if (oldStruct[0]>=firstStructType) //revType != -1 && + if (oldStruct[0] >= firstStructType) //revType != -1 && { char cleanName[MAX_STRLEN]; - getCleanName(memName,cleanName); + getCleanName(memName, cleanName); int arrayLen = fileDna->getArraySizeNew(oldStruct[1]); int byteOffset = 0; if (verboseMode & FD_VERBOSE_EXPORT_XML) { - for (int i=0;i1) + if (arrayLen > 1) { - printf("<%s type=\"%s\" count=%d>\n",cleanName,memType, arrayLen); - } else + printf("<%s type=\"%s\" count=%d>\n", cleanName, memType, arrayLen); + } + else { - printf("<%s type=\"%s\">\n",cleanName,memType); + printf("<%s type=\"%s\">\n", cleanName, memType); } } - for (int i=0;i\n",cleanName); + printf("\n", cleanName); } - } else + } + else { //export a simple type if (verboseMode & FD_VERBOSE_EXPORT_XML) { - - if (arrayLen>MAX_ARRAY_LENGTH) + if (arrayLen > MAX_ARRAY_LENGTH) { printf("too long\n"); - } else + } + else { //printf("%s %s\n",memType,memName); - bool isIntegerType = (strcmp(memType,"char")==0) || (strcmp(memType,"int")==0) || (strcmp(memType,"short")==0); + bool isIntegerType = (strcmp(memType, "char") == 0) || (strcmp(memType, "int") == 0) || (strcmp(memType, "short") == 0); if (isIntegerType) { - const char* newtype="int"; + const char *newtype = "int"; int dbarray[MAX_ARRAY_LENGTH]; - int* dbPtr = 0; - char* tmp = elemPtr; + int *dbPtr = 0; + char *tmp = elemPtr; dbPtr = &dbarray[0]; if (dbPtr) { char cleanName[MAX_STRLEN]; - getCleanName(memName,cleanName); + getCleanName(memName, cleanName); int i; - getElement(arrayLen, newtype,memType, tmp, (char*)dbPtr); - for (i=0;i",cleanName,memType); + if (arrayLen == 1) + printf("<%s type=\"%s\">", cleanName, memType); else - printf("<%s type=\"%s\" count=%d>",cleanName,memType,arrayLen); - for (i=0;i\n",cleanName); + printf("<%s type=\"%s\" count=%d>", cleanName, memType, arrayLen); + for (i = 0; i < arrayLen; i++) + printf(" %d ", dbPtr[i]); + printf("\n", cleanName); } - } else + } + else { - const char* newtype="double"; + const char *newtype = "double"; double dbarray[MAX_ARRAY_LENGTH]; - double* dbPtr = 0; - char* tmp = elemPtr; + double *dbPtr = 0; + char *tmp = elemPtr; dbPtr = &dbarray[0]; if (dbPtr) { int i; - getElement(arrayLen, newtype,memType, tmp, (char*)dbPtr); - for (i=0;i",memName,memType); + printf("<%s type=\"%s\">", memName, memType); } else { - printf("<%s type=\"%s\" count=%d>",cleanName,memType,arrayLen); + printf("<%s type=\"%s\" count=%d>", cleanName, memType, arrayLen); } - for (i=0;i\n",cleanName); + for (i = 0; i < arrayLen; i++) + printf(" %f ", dbPtr[i]); + printf("\n", cleanName); } } } - } } } int size = fileDna->getElementSize(oldStruct[0], oldStruct[1]); totalSize += size; - elemPtr+=size; - + elemPtr += size; } return totalSize; } - ///Resolve pointers replaces the original pointers in structures, and linked lists by the new in-memory structures void bFile::resolvePointers(int verboseMode) { - bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA; + bParse::bDNA *fileDna = mFileDNA ? mFileDNA : mMemoryDNA; //char *dataPtr = mFileBuffer+mDataStart; - if (1) //mFlags & (FD_BITS_VARIES | FD_VERSION_VARIES)) + if (1) //mFlags & (FD_BITS_VARIES | FD_VERSION_VARIES)) { resolvePointersMismatch(); } { - if (verboseMode & FD_VERBOSE_EXPORT_XML) { printf("\n"); int numitems = m_chunks.size(); printf("\n", b3GetVersion(), numitems); } - for (int i=0;iflagEqual(dataChunk.dna_nr)) { //dataChunk.len - short int* oldStruct = fileDna->getStruct(dataChunk.dna_nr); - char* oldType = fileDna->getType(oldStruct[0]); + short int *oldStruct = fileDna->getStruct(dataChunk.dna_nr); + char *oldType = fileDna->getType(oldStruct[0]); if (verboseMode & FD_VERBOSE_EXPORT_XML) - printf(" <%s pointer=%p>\n",oldType,dataChunk.oldPtr); + printf(" <%s pointer=%p>\n", oldType, dataChunk.oldPtr); resolvePointersChunk(dataChunk, verboseMode); if (verboseMode & FD_VERBOSE_EXPORT_XML) - printf(" \n",oldType); - } else + printf(" \n", oldType); + } + else { //printf("skipping mStruct\n"); } } - if (verboseMode & FD_VERBOSE_EXPORT_XML) - { - printf("\n"); - } + if (verboseMode & FD_VERBOSE_EXPORT_XML) + { + printf("\n"); + } } - - } - // ----------------------------------------------------- // -void* bFile::findLibPointer(void *ptr) +void *bFile::findLibPointer(void *ptr) { - - bStructHandle** ptrptr = getLibPointers().find(ptr); + bStructHandle **ptrptr = getLibPointers().find(ptr); if (ptrptr) return *ptrptr; return 0; } - -void bFile::updateOldPointers() +void bFile::updateOldPointers() { int i; - for (i=0;igetStruct(dataChunk.dna_nr); - char* typeName = dna->getType(newStruct[0]); - printf("%3d: %s ",i,typeName); + short *newStruct = dna->getStruct(dataChunk.dna_nr); + char *typeName = dna->getType(newStruct[0]); + printf("%3d: %s ", i, typeName); - printf("code=%s ",codestr); + printf("code=%s ", codestr); - printf("ptr=%p ",dataChunk.oldPtr); - printf("len=%d ",dataChunk.len); - printf("nr=%d ",dataChunk.nr); - if (dataChunk.nr!=1) + printf("ptr=%p ", dataChunk.oldPtr); + printf("len=%d ", dataChunk.len); + printf("nr=%d ", dataChunk.nr); + if (dataChunk.nr != 1) { printf("not 1\n"); } printf("\n"); - - - - } #if 0 @@ -1536,20 +1461,18 @@ void bFile::dumpChunks(bParse::bDNA* dna) printf("\n"); } #endif - } - -void bFile::writeChunks(FILE* fp, bool fixupPointers) +void bFile::writeChunks(FILE *fp, bool fixupPointers) { - bParse::bDNA* fileDna = mFileDNA ? mFileDNA : mMemoryDNA; + bParse::bDNA *fileDna = mFileDNA ? mFileDNA : mMemoryDNA; - for (int i=0;igetReverseType(oldType); - - if ((reverseOld!=-1)) + if ((reverseOld != -1)) { // make sure it's here //assert(reverseOld!= -1 && "getReverseType() returned -1, struct required!"); @@ -1568,50 +1490,47 @@ void bFile::writeChunks(FILE* fp, bool fixupPointers) curStruct = mMemoryDNA->getStruct(reverseOld); newType = mMemoryDNA->getType(curStruct[0]); // make sure it's the same - assert((strcmp(oldType, newType)==0) && "internal error, struct mismatch!"); - + assert((strcmp(oldType, newType) == 0) && "internal error, struct mismatch!"); curLen = mMemoryDNA->getLength(curStruct[0]); dataChunk.dna_nr = reverseOld; - if (strcmp("Link",oldType)!=0) + if (strcmp("Link", oldType) != 0) { dataChunk.len = curLen * dataChunk.nr; - } else + } + else { -// printf("keep length of link = %d\n",dataChunk.len); + // printf("keep length of link = %d\n",dataChunk.len); } //write the structure header - fwrite(&dataChunk,sizeof(bChunkInd),1,fp); + fwrite(&dataChunk, sizeof(bChunkInd), 1, fp); - - - short int* curStruct1; + short int *curStruct1; curStruct1 = mMemoryDNA->getStruct(dataChunk.dna_nr); assert(curStruct1 == curStruct); - char* cur = fixupPointers ? (char*)findLibPointer(dataChunk.oldPtr) : (char*)dataChunk.oldPtr; + char *cur = fixupPointers ? (char *)findLibPointer(dataChunk.oldPtr) : (char *)dataChunk.oldPtr; //write the actual contents of the structure(s) - fwrite(cur,dataChunk.len,1,fp); - } else + fwrite(cur, dataChunk.len, 1, fp); + } + else { printf("serious error, struct mismatch: don't write\n"); } } - } - // ----------------------------------------------------- // -int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags) +int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags) { bool swap = false; bool varies = false; - if (flags &FD_ENDIAN_SWAP) + if (flags & FD_ENDIAN_SWAP) swap = true; - if (flags &FD_BITS_VARIES) + if (flags & FD_BITS_VARIES) varies = true; if (VOID_IS_8) @@ -1621,27 +1540,25 @@ int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int fl bChunkPtr4 head; memcpy(&head, dataPtr, sizeof(bChunkPtr4)); - bChunkPtr8 chunk; - chunk.code = head.code; - chunk.len = head.len; + chunk.code = head.code; + chunk.len = head.len; chunk.m_uniqueInts[0] = head.m_uniqueInt; chunk.m_uniqueInts[1] = 0; - chunk.dna_nr = head.dna_nr; - chunk.nr = head.nr; + chunk.dna_nr = head.dna_nr; + chunk.nr = head.nr; if (swap) { - if ((chunk.code & 0xFFFF)==0) - chunk.code >>=16; + if ((chunk.code & 0xFFFF) == 0) + chunk.code >>= 16; B3_SWITCH_INT(chunk.len); B3_SWITCH_INT(chunk.dna_nr); B3_SWITCH_INT(chunk.nr); } - memcpy(dataChunk, &chunk, sizeof(bChunkInd)); } else @@ -1651,8 +1568,8 @@ int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int fl if (swap) { - if ((c.code & 0xFFFF)==0) - c.code >>=16; + if ((c.code & 0xFFFF) == 0) + c.code >>= 16; B3_SWITCH_INT(c.len); B3_SWITCH_INT(c.dna_nr); @@ -1669,31 +1586,30 @@ int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int fl bChunkPtr8 head; memcpy(&head, dataPtr, sizeof(bChunkPtr8)); - bChunkPtr4 chunk; chunk.code = head.code; chunk.len = head.len; - if (head.m_uniqueInts[0]==head.m_uniqueInts[1]) + if (head.m_uniqueInts[0] == head.m_uniqueInts[1]) { chunk.m_uniqueInt = head.m_uniqueInts[0]; - } else + } + else { - b3Long64 oldPtr =0; + b3Long64 oldPtr = 0; memcpy(&oldPtr, &head.m_uniqueInts[0], 8); if (swap) B3_SWITCH_LONGINT(oldPtr); chunk.m_uniqueInt = (int)(oldPtr >> 3); } - chunk.dna_nr = head.dna_nr; chunk.nr = head.nr; if (swap) { - if ((chunk.code & 0xFFFF)==0) - chunk.code >>=16; + if ((chunk.code & 0xFFFF) == 0) + chunk.code >>= 16; B3_SWITCH_INT(chunk.len); B3_SWITCH_INT(chunk.dna_nr); @@ -1709,8 +1625,8 @@ int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int fl if (swap) { - if ((c.code & 0xFFFF)==0) - c.code >>=16; + if ((c.code & 0xFFFF) == 0) + c.code >>= 16; B3_SWITCH_INT(c.len); B3_SWITCH_INT(c.dna_nr); @@ -1731,9 +1647,7 @@ int bFile::getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int fl print (dataChunk->dna_nr); print (dataChunk->nr); #endif - return (dataChunk->len+ChunkUtils::getOffset(flags)); + return (dataChunk->len + ChunkUtils::getOffset(flags)); } - - //eof diff --git a/src/Bullet3Serialize/Bullet2FileLoader/b3File.h b/src/Bullet3Serialize/Bullet2FileLoader/b3File.h index 861056806..bda229cfb 100644 --- a/src/Bullet3Serialize/Bullet2FileLoader/b3File.h +++ b/src/Bullet3Serialize/Bullet2FileLoader/b3File.h @@ -20,146 +20,139 @@ subject to the following restrictions: #include "b3Chunk.h" #include -namespace bParse { +namespace bParse +{ +// ----------------------------------------------------- // +enum bFileFlags +{ + FD_INVALID = 0, + FD_OK = 1, + FD_VOID_IS_8 = 2, + FD_ENDIAN_SWAP = 4, + FD_FILE_64 = 8, + FD_BITS_VARIES = 16, + FD_VERSION_VARIES = 32, + FD_DOUBLE_PRECISION = 64, + FD_BROKEN_DNA = 128 +}; - // ----------------------------------------------------- // - enum bFileFlags +enum bFileVerboseMode +{ + FD_VERBOSE_EXPORT_XML = 1, + FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS = 2, + FD_VERBOSE_DUMP_CHUNKS = 4, + FD_VERBOSE_DUMP_FILE_INFO = 8, +}; +// ----------------------------------------------------- // +class bFile +{ +protected: + char m_headerString[7]; + + bool mOwnsBuffer; + char *mFileBuffer; + int mFileLen; + int mVersion; + + bPtrMap mLibPointers; + + int mDataStart; + bDNA *mFileDNA; + bDNA *mMemoryDNA; + + b3AlignedObjectArray m_pointerFixupArray; + b3AlignedObjectArray m_pointerPtrFixupArray; + + b3AlignedObjectArray m_chunks; + b3HashMap m_chunkPtrPtrMap; + + // + + bPtrMap mDataPointers; + + int mFlags; + + // //////////////////////////////////////////////////////////////////////////// + + // buffer offset util + int getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags); + void safeSwapPtr(char *dst, const char *src); + + virtual void parseHeader(); + + virtual void parseData() = 0; + + void resolvePointersMismatch(); + void resolvePointersChunk(const bChunkInd &dataChunk, int verboseMode); + + int resolvePointersStructRecursive(char *strcPtr, int old_dna, int verboseMode, int recursion); + //void swapPtr(char *dst, char *src); + + void parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bool fixupPointers); + void getMatchingFileDNA(short *old, const char *lookupName, const char *lookupType, char *strcData, char *data, bool fixupPointers); + char *getFileElement(short *firstStruct, char *lookupName, char *lookupType, char *data, short **foundPos); + + void swap(char *head, class bChunkInd &ch, bool ignoreEndianFlag); + void swapData(char *data, short type, int arraySize, bool ignoreEndianFlag); + void swapStruct(int dna_nr, char *data, bool ignoreEndianFlag); + void swapLen(char *dataPtr); + void swapDNA(char *ptr); + + char *readStruct(char *head, class bChunkInd &chunk); + char *getAsString(int code); + + void parseInternal(int verboseMode, char *memDna, int memDnaLength); + +public: + bFile(const char *filename, const char headerString[7]); + + //todo: make memoryBuffer const char + //bFile( const char *memoryBuffer, int len); + bFile(char *memoryBuffer, int len, const char headerString[7]); + virtual ~bFile(); + + bDNA *getFileDNA() { - FD_INVALID =0, - FD_OK =1, - FD_VOID_IS_8 =2, - FD_ENDIAN_SWAP =4, - FD_FILE_64 =8, - FD_BITS_VARIES =16, - FD_VERSION_VARIES = 32, - FD_DOUBLE_PRECISION =64, - FD_BROKEN_DNA = 128 - }; + return mFileDNA; + } - enum bFileVerboseMode + virtual void addDataBlock(char *dataBlock) = 0; + + int getFlags() const { - FD_VERBOSE_EXPORT_XML = 1, - FD_VERBOSE_DUMP_DNA_TYPE_DEFINITIONS = 2, - FD_VERBOSE_DUMP_CHUNKS = 4, - FD_VERBOSE_DUMP_FILE_INFO=8, - }; - // ----------------------------------------------------- // - class bFile + return mFlags; + } + + bPtrMap &getLibPointers() { - protected: - - char m_headerString[7]; + return mLibPointers; + } - bool mOwnsBuffer; - char* mFileBuffer; - int mFileLen; - int mVersion; + void *findLibPointer(void *ptr); + bool ok(); - bPtrMap mLibPointers; + virtual void parse(int verboseMode) = 0; - int mDataStart; - bDNA* mFileDNA; - bDNA* mMemoryDNA; + virtual int write(const char *fileName, bool fixupPointers = false) = 0; - b3AlignedObjectArray m_pointerFixupArray; - b3AlignedObjectArray m_pointerPtrFixupArray; - - b3AlignedObjectArray m_chunks; - b3HashMap m_chunkPtrPtrMap; + virtual void writeChunks(FILE *fp, bool fixupPointers); - // - - bPtrMap mDataPointers; + virtual void writeDNA(FILE *fp) = 0; - - int mFlags; + void updateOldPointers(); + void resolvePointers(int verboseMode); - // //////////////////////////////////////////////////////////////////////////// + void dumpChunks(bDNA *dna); - // buffer offset util - int getNextBlock(bChunkInd *dataChunk, const char *dataPtr, const int flags); - void safeSwapPtr(char *dst, const char *src); + int getVersion() const + { + return mVersion; + } + //pre-swap the endianness, so that data loaded on a target with different endianness doesn't need to be swapped + void preSwap(); + void writeFile(const char *fileName); +}; +} // namespace bParse - virtual void parseHeader(); - - virtual void parseData() = 0; - - void resolvePointersMismatch(); - void resolvePointersChunk(const bChunkInd& dataChunk, int verboseMode); - - int resolvePointersStructRecursive(char *strcPtr, int old_dna, int verboseMode, int recursion); - //void swapPtr(char *dst, char *src); - - void parseStruct(char *strcPtr, char *dtPtr, int old_dna, int new_dna, bool fixupPointers); - void getMatchingFileDNA(short* old, const char* lookupName, const char* lookupType, char *strcData, char *data, bool fixupPointers); - char* getFileElement(short *firstStruct, char *lookupName, char *lookupType, char *data, short **foundPos); - - - void swap(char *head, class bChunkInd& ch, bool ignoreEndianFlag); - void swapData(char *data, short type, int arraySize, bool ignoreEndianFlag); - void swapStruct(int dna_nr, char *data, bool ignoreEndianFlag); - void swapLen(char *dataPtr); - void swapDNA(char* ptr); - - - char* readStruct(char *head, class bChunkInd& chunk); - char *getAsString(int code); - - void parseInternal(int verboseMode, char* memDna,int memDnaLength); - - public: - bFile(const char *filename, const char headerString[7]); - - //todo: make memoryBuffer const char - //bFile( const char *memoryBuffer, int len); - bFile( char *memoryBuffer, int len, const char headerString[7]); - virtual ~bFile(); - - bDNA* getFileDNA() - { - return mFileDNA; - } - - virtual void addDataBlock(char* dataBlock) = 0; - - int getFlags() const - { - return mFlags; - } - - bPtrMap& getLibPointers() - { - return mLibPointers; - } - - void* findLibPointer(void *ptr); - - bool ok(); - - virtual void parse(int verboseMode) = 0; - - virtual int write(const char* fileName, bool fixupPointers=false) = 0; - - virtual void writeChunks(FILE* fp, bool fixupPointers ); - - virtual void writeDNA(FILE* fp) = 0; - - void updateOldPointers(); - void resolvePointers(int verboseMode); - - void dumpChunks(bDNA* dna); - - int getVersion() const - { - return mVersion; - } - //pre-swap the endianness, so that data loaded on a target with different endianness doesn't need to be swapped - void preSwap(); - void writeFile(const char* fileName); - - }; -} - - -#endif//__BFILE_H__ +#endif //__BFILE_H__ diff --git a/src/Bullet3Serialize/Bullet2FileLoader/b3Serializer.cpp b/src/Bullet3Serialize/Bullet2FileLoader/b3Serializer.cpp index c6a2a832a..ea4a8e200 100644 --- a/src/Bullet3Serialize/Bullet2FileLoader/b3Serializer.cpp +++ b/src/Bullet3Serialize/Bullet2FileLoader/b3Serializer.cpp @@ -1,908 +1,18062 @@ -char b3s_bulletDNAstr[]= { -char(83),char(68),char(78),char(65),char(78),char(65),char(77),char(69),char(63),char(1),char(0),char(0),char(109),char(95),char(115),char(105),char(122),char(101),char(0),char(109), -char(95),char(99),char(97),char(112),char(97),char(99),char(105),char(116),char(121),char(0),char(42),char(109),char(95),char(100),char(97),char(116),char(97),char(0),char(109),char(95), -char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(83),char(104),char(97),char(112),char(101),char(115),char(0),char(109),char(95),char(99),char(111), -char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99),char(116),char(115),char(0),char(109),char(95),char(99),char(111),char(110), -char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(115),char(0),char(42),char(102),char(105),char(114),char(115),char(116),char(0),char(42),char(108),char(97),char(115), -char(116),char(0),char(109),char(95),char(102),char(108),char(111),char(97),char(116),char(115),char(91),char(52),char(93),char(0),char(109),char(95),char(101),char(108),char(91),char(51), -char(93),char(0),char(109),char(95),char(98),char(97),char(115),char(105),char(115),char(0),char(109),char(95),char(111),char(114),char(105),char(103),char(105),char(110),char(0),char(109), -char(95),char(114),char(111),char(111),char(116),char(78),char(111),char(100),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(115),char(117),char(98), -char(116),char(114),char(101),char(101),char(83),char(105),char(122),char(101),char(0),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100), -char(65),char(97),char(98),char(98),char(77),char(105),char(110),char(91),char(51),char(93),char(0),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122), -char(101),char(100),char(65),char(97),char(98),char(98),char(77),char(97),char(120),char(91),char(51),char(93),char(0),char(109),char(95),char(97),char(97),char(98),char(98),char(77), -char(105),char(110),char(79),char(114),char(103),char(0),char(109),char(95),char(97),char(97),char(98),char(98),char(77),char(97),char(120),char(79),char(114),char(103),char(0),char(109), -char(95),char(101),char(115),char(99),char(97),char(112),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(115),char(117),char(98),char(80),char(97), -char(114),char(116),char(0),char(109),char(95),char(116),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109), -char(95),char(112),char(97),char(100),char(91),char(52),char(93),char(0),char(109),char(95),char(101),char(115),char(99),char(97),char(112),char(101),char(73),char(110),char(100),char(101), -char(120),char(79),char(114),char(84),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(98), -char(118),char(104),char(65),char(97),char(98),char(98),char(77),char(105),char(110),char(0),char(109),char(95),char(98),char(118),char(104),char(65),char(97),char(98),char(98),char(77), -char(97),char(120),char(0),char(109),char(95),char(98),char(118),char(104),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(97),char(116),char(105),char(111),char(110), -char(0),char(109),char(95),char(99),char(117),char(114),char(78),char(111),char(100),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(117),char(115), -char(101),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(97),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(110),char(117),char(109),char(67), -char(111),char(110),char(116),char(105),char(103),char(117),char(111),char(117),char(115),char(76),char(101),char(97),char(102),char(78),char(111),char(100),char(101),char(115),char(0),char(109), -char(95),char(110),char(117),char(109),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(67),char(111),char(110),char(116),char(105),char(103),char(117), -char(111),char(117),char(115),char(78),char(111),char(100),char(101),char(115),char(0),char(42),char(109),char(95),char(99),char(111),char(110),char(116),char(105),char(103),char(117),char(111), -char(117),char(115),char(78),char(111),char(100),char(101),char(115),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105), -char(122),char(101),char(100),char(67),char(111),char(110),char(116),char(105),char(103),char(117),char(111),char(117),char(115),char(78),char(111),char(100),char(101),char(115),char(80),char(116), -char(114),char(0),char(42),char(109),char(95),char(115),char(117),char(98),char(84),char(114),char(101),char(101),char(73),char(110),char(102),char(111),char(80),char(116),char(114),char(0), -char(109),char(95),char(116),char(114),char(97),char(118),char(101),char(114),char(115),char(97),char(108),char(77),char(111),char(100),char(101),char(0),char(109),char(95),char(110),char(117), -char(109),char(83),char(117),char(98),char(116),char(114),char(101),char(101),char(72),char(101),char(97),char(100),char(101),char(114),char(115),char(0),char(42),char(109),char(95),char(110), -char(97),char(109),char(101),char(0),char(109),char(95),char(115),char(104),char(97),char(112),char(101),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(112),char(97), -char(100),char(100),char(105),char(110),char(103),char(91),char(52),char(93),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110), -char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(108),char(111),char(99),char(97),char(108),char(83),char(99),char(97), -char(108),char(105),char(110),char(103),char(0),char(109),char(95),char(112),char(108),char(97),char(110),char(101),char(78),char(111),char(114),char(109),char(97),char(108),char(0),char(109), -char(95),char(112),char(108),char(97),char(110),char(101),char(67),char(111),char(110),char(115),char(116),char(97),char(110),char(116),char(0),char(109),char(95),char(105),char(109),char(112), -char(108),char(105),char(99),char(105),char(116),char(83),char(104),char(97),char(112),char(101),char(68),char(105),char(109),char(101),char(110),char(115),char(105),char(111),char(110),char(115), -char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(77),char(97),char(114),char(103),char(105),char(110),char(0),char(109), -char(95),char(112),char(97),char(100),char(100),char(105),char(110),char(103),char(0),char(109),char(95),char(112),char(111),char(115),char(0),char(109),char(95),char(114),char(97),char(100), -char(105),char(117),char(115),char(0),char(109),char(95),char(99),char(111),char(110),char(118),char(101),char(120),char(73),char(110),char(116),char(101),char(114),char(110),char(97),char(108), -char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(42),char(109),char(95),char(108),char(111),char(99),char(97),char(108),char(80),char(111), -char(115),char(105),char(116),char(105),char(111),char(110),char(65),char(114),char(114),char(97),char(121),char(80),char(116),char(114),char(0),char(109),char(95),char(108),char(111),char(99), -char(97),char(108),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(65),char(114),char(114),char(97),char(121),char(83),char(105),char(122),char(101),char(0), -char(109),char(95),char(118),char(97),char(108),char(117),char(101),char(0),char(109),char(95),char(112),char(97),char(100),char(91),char(50),char(93),char(0),char(109),char(95),char(118), -char(97),char(108),char(117),char(101),char(115),char(91),char(51),char(93),char(0),char(109),char(95),char(112),char(97),char(100),char(0),char(42),char(109),char(95),char(118),char(101), -char(114),char(116),char(105),char(99),char(101),char(115),char(51),char(102),char(0),char(42),char(109),char(95),char(118),char(101),char(114),char(116),char(105),char(99),char(101),char(115), -char(51),char(100),char(0),char(42),char(109),char(95),char(105),char(110),char(100),char(105),char(99),char(101),char(115),char(51),char(50),char(0),char(42),char(109),char(95),char(51), -char(105),char(110),char(100),char(105),char(99),char(101),char(115),char(49),char(54),char(0),char(42),char(109),char(95),char(51),char(105),char(110),char(100),char(105),char(99),char(101), -char(115),char(56),char(0),char(42),char(109),char(95),char(105),char(110),char(100),char(105),char(99),char(101),char(115),char(49),char(54),char(0),char(109),char(95),char(110),char(117), -char(109),char(84),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(86),char(101),char(114),char(116), -char(105),char(99),char(101),char(115),char(0),char(42),char(109),char(95),char(109),char(101),char(115),char(104),char(80),char(97),char(114),char(116),char(115),char(80),char(116),char(114), -char(0),char(109),char(95),char(115),char(99),char(97),char(108),char(105),char(110),char(103),char(0),char(109),char(95),char(110),char(117),char(109),char(77),char(101),char(115),char(104), -char(80),char(97),char(114),char(116),char(115),char(0),char(109),char(95),char(109),char(101),char(115),char(104),char(73),char(110),char(116),char(101),char(114),char(102),char(97),char(99), -char(101),char(0),char(42),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(70),char(108),char(111),char(97),char(116),char(66), -char(118),char(104),char(0),char(42),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(68),char(111),char(117),char(98),char(108), -char(101),char(66),char(118),char(104),char(0),char(42),char(109),char(95),char(116),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(102),char(111), -char(77),char(97),char(112),char(0),char(109),char(95),char(112),char(97),char(100),char(51),char(91),char(52),char(93),char(0),char(109),char(95),char(116),char(114),char(105),char(109), -char(101),char(115),char(104),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(116),char(114),char(97),char(110),char(115), -char(102),char(111),char(114),char(109),char(0),char(42),char(109),char(95),char(99),char(104),char(105),char(108),char(100),char(83),char(104),char(97),char(112),char(101),char(0),char(109), -char(95),char(99),char(104),char(105),char(108),char(100),char(83),char(104),char(97),char(112),char(101),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(99),char(104), -char(105),char(108),char(100),char(77),char(97),char(114),char(103),char(105),char(110),char(0),char(42),char(109),char(95),char(99),char(104),char(105),char(108),char(100),char(83),char(104), -char(97),char(112),char(101),char(80),char(116),char(114),char(0),char(109),char(95),char(110),char(117),char(109),char(67),char(104),char(105),char(108),char(100),char(83),char(104),char(97), -char(112),char(101),char(115),char(0),char(109),char(95),char(117),char(112),char(65),char(120),char(105),char(115),char(0),char(109),char(95),char(102),char(108),char(97),char(103),char(115), -char(0),char(109),char(95),char(101),char(100),char(103),char(101),char(86),char(48),char(86),char(49),char(65),char(110),char(103),char(108),char(101),char(0),char(109),char(95),char(101), -char(100),char(103),char(101),char(86),char(49),char(86),char(50),char(65),char(110),char(103),char(108),char(101),char(0),char(109),char(95),char(101),char(100),char(103),char(101),char(86), -char(50),char(86),char(48),char(65),char(110),char(103),char(108),char(101),char(0),char(42),char(109),char(95),char(104),char(97),char(115),char(104),char(84),char(97),char(98),char(108), -char(101),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(110),char(101),char(120),char(116),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(118), -char(97),char(108),char(117),char(101),char(65),char(114),char(114),char(97),char(121),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(107),char(101),char(121),char(65), -char(114),char(114),char(97),char(121),char(80),char(116),char(114),char(0),char(109),char(95),char(99),char(111),char(110),char(118),char(101),char(120),char(69),char(112),char(115),char(105), -char(108),char(111),char(110),char(0),char(109),char(95),char(112),char(108),char(97),char(110),char(97),char(114),char(69),char(112),char(115),char(105),char(108),char(111),char(110),char(0), -char(109),char(95),char(101),char(113),char(117),char(97),char(108),char(86),char(101),char(114),char(116),char(101),char(120),char(84),char(104),char(114),char(101),char(115),char(104),char(111), -char(108),char(100),char(0),char(109),char(95),char(101),char(100),char(103),char(101),char(68),char(105),char(115),char(116),char(97),char(110),char(99),char(101),char(84),char(104),char(114), -char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(122),char(101),char(114),char(111),char(65),char(114),char(101),char(97),char(84),char(104),char(114), -char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(110),char(101),char(120),char(116),char(83),char(105),char(122),char(101),char(0),char(109),char(95), -char(104),char(97),char(115),char(104),char(84),char(97),char(98),char(108),char(101),char(83),char(105),char(122),char(101),char(0),char(109),char(95),char(110),char(117),char(109),char(86), -char(97),char(108),char(117),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(75),char(101),char(121),char(115),char(0),char(109),char(95),char(103),char(105), -char(109),char(112),char(97),char(99),char(116),char(83),char(117),char(98),char(84),char(121),char(112),char(101),char(0),char(42),char(109),char(95),char(117),char(110),char(115),char(99), -char(97),char(108),char(101),char(100),char(80),char(111),char(105),char(110),char(116),char(115),char(70),char(108),char(111),char(97),char(116),char(80),char(116),char(114),char(0),char(42), -char(109),char(95),char(117),char(110),char(115),char(99),char(97),char(108),char(101),char(100),char(80),char(111),char(105),char(110),char(116),char(115),char(68),char(111),char(117),char(98), -char(108),char(101),char(80),char(116),char(114),char(0),char(109),char(95),char(110),char(117),char(109),char(85),char(110),char(115),char(99),char(97),char(108),char(101),char(100),char(80), -char(111),char(105),char(110),char(116),char(115),char(0),char(109),char(95),char(112),char(97),char(100),char(100),char(105),char(110),char(103),char(51),char(91),char(52),char(93),char(0), -char(42),char(109),char(95),char(98),char(114),char(111),char(97),char(100),char(112),char(104),char(97),char(115),char(101),char(72),char(97),char(110),char(100),char(108),char(101),char(0), -char(42),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(83),char(104),char(97),char(112),char(101),char(0),char(42),char(109), -char(95),char(114),char(111),char(111),char(116),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(83),char(104),char(97),char(112),char(101),char(0), -char(109),char(95),char(119),char(111),char(114),char(108),char(100),char(84),char(114),char(97),char(110),char(115),char(102),char(111),char(114),char(109),char(0),char(109),char(95),char(105), -char(110),char(116),char(101),char(114),char(112),char(111),char(108),char(97),char(116),char(105),char(111),char(110),char(87),char(111),char(114),char(108),char(100),char(84),char(114),char(97), -char(110),char(115),char(102),char(111),char(114),char(109),char(0),char(109),char(95),char(105),char(110),char(116),char(101),char(114),char(112),char(111),char(108),char(97),char(116),char(105), -char(111),char(110),char(76),char(105),char(110),char(101),char(97),char(114),char(86),char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(105), -char(110),char(116),char(101),char(114),char(112),char(111),char(108),char(97),char(116),char(105),char(111),char(110),char(65),char(110),char(103),char(117),char(108),char(97),char(114),char(86), -char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(110),char(105),char(115),char(111),char(116),char(114),char(111),char(112),char(105), -char(99),char(70),char(114),char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(99),char(111),char(110),char(116),char(97),char(99),char(116),char(80), -char(114),char(111),char(99),char(101),char(115),char(115),char(105),char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109), -char(95),char(100),char(101),char(97),char(99),char(116),char(105),char(118),char(97),char(116),char(105),char(111),char(110),char(84),char(105),char(109),char(101),char(0),char(109),char(95), -char(102),char(114),char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(114),char(111),char(108),char(108),char(105),char(110),char(103),char(70),char(114), -char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(105),char(116),char(117),char(116),char(105),char(111),char(110), -char(0),char(109),char(95),char(104),char(105),char(116),char(70),char(114),char(97),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(99),char(99),char(100), -char(83),char(119),char(101),char(112),char(116),char(83),char(112),char(104),char(101),char(114),char(101),char(82),char(97),char(100),char(105),char(117),char(115),char(0),char(109),char(95), -char(99),char(99),char(100),char(77),char(111),char(116),char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109), -char(95),char(104),char(97),char(115),char(65),char(110),char(105),char(115),char(111),char(116),char(114),char(111),char(112),char(105),char(99),char(70),char(114),char(105),char(99),char(116), -char(105),char(111),char(110),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(70),char(108),char(97),char(103),char(115), -char(0),char(109),char(95),char(105),char(115),char(108),char(97),char(110),char(100),char(84),char(97),char(103),char(49),char(0),char(109),char(95),char(99),char(111),char(109),char(112), -char(97),char(110),char(105),char(111),char(110),char(73),char(100),char(0),char(109),char(95),char(97),char(99),char(116),char(105),char(118),char(97),char(116),char(105),char(111),char(110), -char(83),char(116),char(97),char(116),char(101),char(49),char(0),char(109),char(95),char(105),char(110),char(116),char(101),char(114),char(110),char(97),char(108),char(84),char(121),char(112), -char(101),char(0),char(109),char(95),char(99),char(104),char(101),char(99),char(107),char(67),char(111),char(108),char(108),char(105),char(100),char(101),char(87),char(105),char(116),char(104), -char(0),char(109),char(95),char(115),char(111),char(108),char(118),char(101),char(114),char(73),char(110),char(102),char(111),char(0),char(109),char(95),char(103),char(114),char(97),char(118), -char(105),char(116),char(121),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99), -char(116),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(105),char(110),char(118),char(73),char(110),char(101),char(114),char(116),char(105),char(97),char(84),char(101), -char(110),char(115),char(111),char(114),char(87),char(111),char(114),char(108),char(100),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(86),char(101), -char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(86),char(101),char(108),char(111), -char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(70),char(97),char(99),char(116),char(111),char(114), -char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(103),char(114), -char(97),char(118),char(105),char(116),char(121),char(95),char(97),char(99),char(99),char(101),char(108),char(101),char(114),char(97),char(116),char(105),char(111),char(110),char(0),char(109), -char(95),char(105),char(110),char(118),char(73),char(110),char(101),char(114),char(116),char(105),char(97),char(76),char(111),char(99),char(97),char(108),char(0),char(109),char(95),char(116), -char(111),char(116),char(97),char(108),char(70),char(111),char(114),char(99),char(101),char(0),char(109),char(95),char(116),char(111),char(116),char(97),char(108),char(84),char(111),char(114), -char(113),char(117),char(101),char(0),char(109),char(95),char(105),char(110),char(118),char(101),char(114),char(115),char(101),char(77),char(97),char(115),char(115),char(0),char(109),char(95), -char(108),char(105),char(110),char(101),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(97),char(110),char(103),char(117), -char(108),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(97),char(100),char(100),char(105),char(116),char(105),char(111), -char(110),char(97),char(108),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(97), -char(100),char(100),char(105),char(116),char(105),char(111),char(110),char(97),char(108),char(76),char(105),char(110),char(101),char(97),char(114),char(68),char(97),char(109),char(112),char(105), -char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(83),char(113),char(114),char(0),char(109),char(95),char(97),char(100),char(100), -char(105),char(116),char(105),char(111),char(110),char(97),char(108),char(65),char(110),char(103),char(117),char(108),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110), -char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(83),char(113),char(114),char(0),char(109),char(95),char(97),char(100),char(100),char(105), -char(116),char(105),char(111),char(110),char(97),char(108),char(65),char(110),char(103),char(117),char(108),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110),char(103), -char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(83),char(108),char(101),char(101),char(112), -char(105),char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108), -char(97),char(114),char(83),char(108),char(101),char(101),char(112),char(105),char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0), -char(109),char(95),char(97),char(100),char(100),char(105),char(116),char(105),char(111),char(110),char(97),char(108),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(0), -char(109),char(95),char(110),char(117),char(109),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(82),char(111),char(119),char(115),char(0), -char(110),char(117),char(98),char(0),char(42),char(109),char(95),char(114),char(98),char(65),char(0),char(42),char(109),char(95),char(114),char(98),char(66),char(0),char(109),char(95), -char(111),char(98),char(106),char(101),char(99),char(116),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(117),char(115),char(101),char(114),char(67),char(111),char(110), -char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(117),char(115),char(101),char(114),char(67),char(111), -char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(73),char(100),char(0),char(109),char(95),char(110),char(101),char(101),char(100),char(115),char(70),char(101), -char(101),char(100),char(98),char(97),char(99),char(107),char(0),char(109),char(95),char(97),char(112),char(112),char(108),char(105),char(101),char(100),char(73),char(109),char(112),char(117), -char(108),char(115),char(101),char(0),char(109),char(95),char(100),char(98),char(103),char(68),char(114),char(97),char(119),char(83),char(105),char(122),char(101),char(0),char(109),char(95), -char(100),char(105),char(115),char(97),char(98),char(108),char(101),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(115),char(66),char(101),char(116), -char(119),char(101),char(101),char(110),char(76),char(105),char(110),char(107),char(101),char(100),char(66),char(111),char(100),char(105),char(101),char(115),char(0),char(109),char(95),char(111), -char(118),char(101),char(114),char(114),char(105),char(100),char(101),char(78),char(117),char(109),char(83),char(111),char(108),char(118),char(101),char(114),char(73),char(116),char(101),char(114), -char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(98),char(114),char(101),char(97),char(107),char(105),char(110),char(103),char(73),char(109),char(112), -char(117),char(108),char(115),char(101),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(105),char(115),char(69),char(110), -char(97),char(98),char(108),char(101),char(100),char(0),char(109),char(95),char(116),char(121),char(112),char(101),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105), -char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(112),char(105),char(118),char(111),char(116),char(73),char(110),char(65),char(0),char(109),char(95), -char(112),char(105),char(118),char(111),char(116),char(73),char(110),char(66),char(0),char(109),char(95),char(114),char(98),char(65),char(70),char(114),char(97),char(109),char(101),char(0), -char(109),char(95),char(114),char(98),char(66),char(70),char(114),char(97),char(109),char(101),char(0),char(109),char(95),char(117),char(115),char(101),char(82),char(101),char(102),char(101), -char(114),char(101),char(110),char(99),char(101),char(70),char(114),char(97),char(109),char(101),char(65),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97), -char(114),char(79),char(110),char(108),char(121),char(0),char(109),char(95),char(101),char(110),char(97),char(98),char(108),char(101),char(65),char(110),char(103),char(117),char(108),char(97), -char(114),char(77),char(111),char(116),char(111),char(114),char(0),char(109),char(95),char(109),char(111),char(116),char(111),char(114),char(84),char(97),char(114),char(103),char(101),char(116), -char(86),char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(109),char(97),char(120),char(77),char(111),char(116),char(111),char(114),char(73), -char(109),char(112),char(117),char(108),char(115),char(101),char(0),char(109),char(95),char(108),char(111),char(119),char(101),char(114),char(76),char(105),char(109),char(105),char(116),char(0), -char(109),char(95),char(117),char(112),char(112),char(101),char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(108),char(105),char(109),char(105),char(116), -char(83),char(111),char(102),char(116),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(98),char(105),char(97),char(115),char(70),char(97),char(99),char(116),char(111), -char(114),char(0),char(109),char(95),char(114),char(101),char(108),char(97),char(120),char(97),char(116),char(105),char(111),char(110),char(70),char(97),char(99),char(116),char(111),char(114), -char(0),char(109),char(95),char(115),char(119),char(105),char(110),char(103),char(83),char(112),char(97),char(110),char(49),char(0),char(109),char(95),char(115),char(119),char(105),char(110), -char(103),char(83),char(112),char(97),char(110),char(50),char(0),char(109),char(95),char(116),char(119),char(105),char(115),char(116),char(83),char(112),char(97),char(110),char(0),char(109), -char(95),char(100),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(85),char(112),char(112), -char(101),char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(76),char(111),char(119),char(101), -char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(85),char(112),char(112),char(101), -char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(76),char(111),char(119),char(101), -char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(117),char(115),char(101),char(76),char(105),char(110),char(101),char(97),char(114),char(82),char(101), -char(102),char(101),char(114),char(101),char(110),char(99),char(101),char(70),char(114),char(97),char(109),char(101),char(65),char(0),char(109),char(95),char(117),char(115),char(101),char(79), -char(102),char(102),char(115),char(101),char(116),char(70),char(111),char(114),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(70),char(114), -char(97),char(109),char(101),char(0),char(109),char(95),char(54),char(100),char(111),char(102),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(115),char(112),char(114), -char(105),char(110),char(103),char(69),char(110),char(97),char(98),char(108),char(101),char(100),char(91),char(54),char(93),char(0),char(109),char(95),char(101),char(113),char(117),char(105), -char(108),char(105),char(98),char(114),char(105),char(117),char(109),char(80),char(111),char(105),char(110),char(116),char(91),char(54),char(93),char(0),char(109),char(95),char(115),char(112), -char(114),char(105),char(110),char(103),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(91),char(54),char(93),char(0),char(109),char(95),char(115), -char(112),char(114),char(105),char(110),char(103),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(91),char(54),char(93),char(0),char(109),char(95),char(116),char(97), -char(117),char(0),char(109),char(95),char(116),char(105),char(109),char(101),char(83),char(116),char(101),char(112),char(0),char(109),char(95),char(109),char(97),char(120),char(69),char(114), -char(114),char(111),char(114),char(82),char(101),char(100),char(117),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(115),char(111),char(114),char(0),char(109), -char(95),char(101),char(114),char(112),char(0),char(109),char(95),char(101),char(114),char(112),char(50),char(0),char(109),char(95),char(103),char(108),char(111),char(98),char(97),char(108), -char(67),char(102),char(109),char(0),char(109),char(95),char(115),char(112),char(108),char(105),char(116),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(80),char(101), -char(110),char(101),char(116),char(114),char(97),char(116),char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109), -char(95),char(115),char(112),char(108),char(105),char(116),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(84),char(117),char(114),char(110),char(69),char(114),char(112), -char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(83),char(108),char(111),char(112),char(0),char(109),char(95),char(119),char(97),char(114),char(109), -char(115),char(116),char(97),char(114),char(116),char(105),char(110),char(103),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(109),char(97),char(120), -char(71),char(121),char(114),char(111),char(115),char(99),char(111),char(112),char(105),char(99),char(70),char(111),char(114),char(99),char(101),char(0),char(109),char(95),char(115),char(105), -char(110),char(103),char(108),char(101),char(65),char(120),char(105),char(115),char(82),char(111),char(108),char(108),char(105),char(110),char(103),char(70),char(114),char(105),char(99),char(116), -char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(110),char(117),char(109),char(73),char(116), -char(101),char(114),char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(115),char(111),char(108),char(118),char(101),char(114),char(77),char(111),char(100), -char(101),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(105),char(110),char(103),char(67),char(111),char(110),char(116),char(97),char(99),char(116),char(82),char(101), -char(115),char(116),char(105),char(116),char(117),char(116),char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109), -char(95),char(109),char(105),char(110),char(105),char(109),char(117),char(109),char(83),char(111),char(108),char(118),char(101),char(114),char(66),char(97),char(116),char(99),char(104),char(83), -char(105),char(122),char(101),char(0),char(109),char(95),char(115),char(112),char(108),char(105),char(116),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(0),char(109), -char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(97), -char(110),char(103),char(117),char(108),char(97),char(114),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(118),char(111), -char(108),char(117),char(109),char(101),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(0),char(42),char(109),char(95),char(109),char(97),char(116), -char(101),char(114),char(105),char(97),char(108),char(0),char(109),char(95),char(112),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(112), -char(114),char(101),char(118),char(105),char(111),char(117),char(115),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(118),char(101), -char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(99),char(99),char(117),char(109),char(117),char(108),char(97),char(116),char(101),char(100), -char(70),char(111),char(114),char(99),char(101),char(0),char(109),char(95),char(110),char(111),char(114),char(109),char(97),char(108),char(0),char(109),char(95),char(97),char(114),char(101), -char(97),char(0),char(109),char(95),char(97),char(116),char(116),char(97),char(99),char(104),char(0),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100), -char(105),char(99),char(101),char(115),char(91),char(50),char(93),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(76),char(101),char(110),char(103),char(116),char(104), -char(0),char(109),char(95),char(98),char(98),char(101),char(110),char(100),char(105),char(110),char(103),char(0),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110), -char(100),char(105),char(99),char(101),char(115),char(91),char(51),char(93),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(65),char(114),char(101),char(97),char(0), -char(109),char(95),char(99),char(48),char(91),char(52),char(93),char(0),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100),char(105),char(99),char(101), -char(115),char(91),char(52),char(93),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(86),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95), -char(99),char(49),char(0),char(109),char(95),char(99),char(50),char(0),char(109),char(95),char(99),char(48),char(0),char(109),char(95),char(108),char(111),char(99),char(97),char(108), -char(70),char(114),char(97),char(109),char(101),char(0),char(42),char(109),char(95),char(114),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(0),char(109), -char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(97),char(101),char(114),char(111),char(77),char(111),char(100), -char(101),char(108),char(0),char(109),char(95),char(98),char(97),char(117),char(109),char(103),char(97),char(114),char(116),char(101),char(0),char(109),char(95),char(100),char(114),char(97), -char(103),char(0),char(109),char(95),char(108),char(105),char(102),char(116),char(0),char(109),char(95),char(112),char(114),char(101),char(115),char(115),char(117),char(114),char(101),char(0), -char(109),char(95),char(118),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95),char(100),char(121),char(110),char(97),char(109),char(105),char(99),char(70),char(114), -char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(112),char(111),char(115),char(101),char(77),char(97),char(116),char(99),char(104),char(0),char(109), -char(95),char(114),char(105),char(103),char(105),char(100),char(67),char(111),char(110),char(116),char(97),char(99),char(116),char(72),char(97),char(114),char(100),char(110),char(101),char(115), -char(115),char(0),char(109),char(95),char(107),char(105),char(110),char(101),char(116),char(105),char(99),char(67),char(111),char(110),char(116),char(97),char(99),char(116),char(72),char(97), -char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(67),char(111),char(110),char(116),char(97),char(99),char(116), -char(72),char(97),char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(97),char(110),char(99),char(104),char(111),char(114),char(72),char(97),char(114), -char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(82),char(105),char(103),char(105),char(100),char(67),char(108),char(117), -char(115),char(116),char(101),char(114),char(72),char(97),char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(75), -char(105),char(110),char(101),char(116),char(105),char(99),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(72),char(97),char(114),char(100),char(110),char(101),char(115), -char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(83),char(111),char(102),char(116),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(72), -char(97),char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(82),char(105),char(103),char(105),char(100),char(67), -char(108),char(117),char(115),char(116),char(101),char(114),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(83),char(112),char(108),char(105),char(116),char(0),char(109), -char(95),char(115),char(111),char(102),char(116),char(75),char(105),char(110),char(101),char(116),char(105),char(99),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(73), -char(109),char(112),char(117),char(108),char(115),char(101),char(83),char(112),char(108),char(105),char(116),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(83),char(111), -char(102),char(116),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(83),char(112),char(108),char(105), -char(116),char(0),char(109),char(95),char(109),char(97),char(120),char(86),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95),char(116),char(105),char(109),char(101), -char(83),char(99),char(97),char(108),char(101),char(0),char(109),char(95),char(118),char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(73),char(116),char(101),char(114), -char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(112),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(73),char(116),char(101), -char(114),char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(100),char(114),char(105),char(102),char(116),char(73),char(116),char(101),char(114),char(97), -char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(99),char(108),char(117),char(115),char(116),char(101),char(114),char(73),char(116),char(101),char(114),char(97), -char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(114),char(111),char(116),char(0),char(109),char(95),char(115),char(99),char(97),char(108),char(101),char(0), -char(109),char(95),char(97),char(113),char(113),char(0),char(109),char(95),char(99),char(111),char(109),char(0),char(42),char(109),char(95),char(112),char(111),char(115),char(105),char(116), -char(105),char(111),char(110),char(115),char(0),char(42),char(109),char(95),char(119),char(101),char(105),char(103),char(104),char(116),char(115),char(0),char(109),char(95),char(110),char(117), -char(109),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(87),char(101),char(105),char(103), -char(116),char(115),char(0),char(109),char(95),char(98),char(118),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95),char(98),char(102),char(114),char(97),char(109), -char(101),char(0),char(109),char(95),char(102),char(114),char(97),char(109),char(101),char(120),char(102),char(111),char(114),char(109),char(0),char(109),char(95),char(108),char(111),char(99), -char(105),char(105),char(0),char(109),char(95),char(105),char(110),char(118),char(119),char(105),char(0),char(109),char(95),char(118),char(105),char(109),char(112),char(117),char(108),char(115), -char(101),char(115),char(91),char(50),char(93),char(0),char(109),char(95),char(100),char(105),char(109),char(112),char(117),char(108),char(115),char(101),char(115),char(91),char(50),char(93), -char(0),char(109),char(95),char(108),char(118),char(0),char(109),char(95),char(97),char(118),char(0),char(42),char(109),char(95),char(102),char(114),char(97),char(109),char(101),char(114), -char(101),char(102),char(115),char(0),char(42),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100),char(105),char(99),char(101),char(115),char(0),char(42), -char(109),char(95),char(109),char(97),char(115),char(115),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(70),char(114),char(97),char(109),char(101),char(82), -char(101),char(102),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(78),char(111),char(100),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109), -char(77),char(97),char(115),char(115),char(101),char(115),char(0),char(109),char(95),char(105),char(100),char(109),char(97),char(115),char(115),char(0),char(109),char(95),char(105),char(109), -char(97),char(115),char(115),char(0),char(109),char(95),char(110),char(118),char(105),char(109),char(112),char(117),char(108),char(115),char(101),char(115),char(0),char(109),char(95),char(110), -char(100),char(105),char(109),char(112),char(117),char(108),char(115),char(101),char(115),char(0),char(109),char(95),char(110),char(100),char(97),char(109),char(112),char(105),char(110),char(103), -char(0),char(109),char(95),char(108),char(100),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(97),char(100),char(97),char(109),char(112),char(105), -char(110),char(103),char(0),char(109),char(95),char(109),char(97),char(116),char(99),char(104),char(105),char(110),char(103),char(0),char(109),char(95),char(109),char(97),char(120),char(83), -char(101),char(108),char(102),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(0), -char(109),char(95),char(115),char(101),char(108),char(102),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(73),char(109),char(112),char(117),char(108), -char(115),char(101),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(99),char(111),char(110),char(116),char(97),char(105),char(110),char(115),char(65), -char(110),char(99),char(104),char(111),char(114),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(100),char(101),char(0),char(109),char(95),char(99),char(108), -char(117),char(115),char(116),char(101),char(114),char(73),char(110),char(100),char(101),char(120),char(0),char(42),char(109),char(95),char(98),char(111),char(100),char(121),char(65),char(0), -char(42),char(109),char(95),char(98),char(111),char(100),char(121),char(66),char(0),char(109),char(95),char(114),char(101),char(102),char(115),char(91),char(50),char(93),char(0),char(109), -char(95),char(99),char(102),char(109),char(0),char(109),char(95),char(115),char(112),char(108),char(105),char(116),char(0),char(109),char(95),char(100),char(101),char(108),char(101),char(116), -char(101),char(0),char(109),char(95),char(114),char(101),char(108),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(91),char(50),char(93),char(0),char(109), -char(95),char(98),char(111),char(100),char(121),char(65),char(116),char(121),char(112),char(101),char(0),char(109),char(95),char(98),char(111),char(100),char(121),char(66),char(116),char(121), -char(112),char(101),char(0),char(109),char(95),char(106),char(111),char(105),char(110),char(116),char(84),char(121),char(112),char(101),char(0),char(42),char(109),char(95),char(112),char(111), -char(115),char(101),char(0),char(42),char(42),char(109),char(95),char(109),char(97),char(116),char(101),char(114),char(105),char(97),char(108),char(115),char(0),char(42),char(109),char(95), -char(110),char(111),char(100),char(101),char(115),char(0),char(42),char(109),char(95),char(108),char(105),char(110),char(107),char(115),char(0),char(42),char(109),char(95),char(102),char(97), -char(99),char(101),char(115),char(0),char(42),char(109),char(95),char(116),char(101),char(116),char(114),char(97),char(104),char(101),char(100),char(114),char(97),char(0),char(42),char(109), -char(95),char(97),char(110),char(99),char(104),char(111),char(114),char(115),char(0),char(42),char(109),char(95),char(99),char(108),char(117),char(115),char(116),char(101),char(114),char(115), -char(0),char(42),char(109),char(95),char(106),char(111),char(105),char(110),char(116),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(77),char(97),char(116),char(101), -char(114),char(105),char(97),char(108),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(76),char(105),char(110),char(107),char(115),char(0),char(109),char(95),char(110), -char(117),char(109),char(70),char(97),char(99),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(84),char(101),char(116),char(114),char(97),char(104),char(101), -char(100),char(114),char(97),char(0),char(109),char(95),char(110),char(117),char(109),char(65),char(110),char(99),char(104),char(111),char(114),char(115),char(0),char(109),char(95),char(110), -char(117),char(109),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(74),char(111),char(105),char(110), -char(116),char(115),char(0),char(109),char(95),char(99),char(111),char(110),char(102),char(105),char(103),char(0),char(84),char(89),char(80),char(69),char(76),char(0),char(0),char(0), -char(99),char(104),char(97),char(114),char(0),char(117),char(99),char(104),char(97),char(114),char(0),char(115),char(104),char(111),char(114),char(116),char(0),char(117),char(115),char(104), -char(111),char(114),char(116),char(0),char(105),char(110),char(116),char(0),char(108),char(111),char(110),char(103),char(0),char(117),char(108),char(111),char(110),char(103),char(0),char(102), -char(108),char(111),char(97),char(116),char(0),char(100),char(111),char(117),char(98),char(108),char(101),char(0),char(118),char(111),char(105),char(100),char(0),char(80),char(111),char(105), -char(110),char(116),char(101),char(114),char(65),char(114),char(114),char(97),char(121),char(0),char(98),char(116),char(80),char(104),char(121),char(115),char(105),char(99),char(115),char(83), -char(121),char(115),char(116),char(101),char(109),char(0),char(76),char(105),char(115),char(116),char(66),char(97),char(115),char(101),char(0),char(98),char(116),char(86),char(101),char(99), -char(116),char(111),char(114),char(51),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(86),char(101),char(99),char(116), -char(111),char(114),char(51),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(77),char(97),char(116),char(114), -char(105),char(120),char(51),char(120),char(51),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(77),char(97),char(116), -char(114),char(105),char(120),char(51),char(120),char(51),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84), -char(114),char(97),char(110),char(115),char(102),char(111),char(114),char(109),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116), -char(84),char(114),char(97),char(110),char(115),char(102),char(111),char(114),char(109),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0), -char(98),char(116),char(66),char(118),char(104),char(83),char(117),char(98),char(116),char(114),char(101),char(101),char(73),char(110),char(102),char(111),char(68),char(97),char(116),char(97), -char(0),char(98),char(116),char(79),char(112),char(116),char(105),char(109),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(78),char(111),char(100),char(101),char(70), -char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(79),char(112),char(116),char(105),char(109),char(105),char(122),char(101),char(100), -char(66),char(118),char(104),char(78),char(111),char(100),char(101),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116), -char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(78),char(111),char(100),char(101),char(68),char(97),char(116),char(97), -char(0),char(98),char(116),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(70),char(108),char(111),char(97),char(116), -char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(68), -char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111), -char(110),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(83),char(116),char(97),char(116),char(105),char(99),char(80), -char(108),char(97),char(110),char(101),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(118), -char(101),char(120),char(73),char(110),char(116),char(101),char(114),char(110),char(97),char(108),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0), -char(98),char(116),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(65),char(110),char(100),char(82),char(97),char(100),char(105),char(117),char(115),char(0), -char(98),char(116),char(77),char(117),char(108),char(116),char(105),char(83),char(112),char(104),char(101),char(114),char(101),char(83),char(104),char(97),char(112),char(101),char(68),char(97), -char(116),char(97),char(0),char(98),char(116),char(73),char(110),char(116),char(73),char(110),char(100),char(101),char(120),char(68),char(97),char(116),char(97),char(0),char(98),char(116), -char(83),char(104),char(111),char(114),char(116),char(73),char(110),char(116),char(73),char(110),char(100),char(101),char(120),char(68),char(97),char(116),char(97),char(0),char(98),char(116), -char(83),char(104),char(111),char(114),char(116),char(73),char(110),char(116),char(73),char(110),char(100),char(101),char(120),char(84),char(114),char(105),char(112),char(108),char(101),char(116), -char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(104),char(97),char(114),char(73),char(110),char(100),char(101),char(120),char(84),char(114),char(105),char(112), -char(108),char(101),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(77),char(101),char(115),char(104),char(80),char(97),char(114),char(116),char(68),char(97), -char(116),char(97),char(0),char(98),char(116),char(83),char(116),char(114),char(105),char(100),char(105),char(110),char(103),char(77),char(101),char(115),char(104),char(73),char(110),char(116), -char(101),char(114),char(102),char(97),char(99),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84),char(114),char(105),char(97),char(110),char(103),char(108), -char(101),char(77),char(101),char(115),char(104),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84),char(114),char(105), -char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(102),char(111),char(77),char(97),char(112),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(83), -char(99),char(97),char(108),char(101),char(100),char(84),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(77),char(101),char(115),char(104),char(83),char(104),char(97), -char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(109),char(112),char(111),char(117),char(110),char(100),char(83),char(104),char(97), -char(112),char(101),char(67),char(104),char(105),char(108),char(100),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(109),char(112),char(111),char(117), -char(110),char(100),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(121),char(108),char(105),char(110),char(100), -char(101),char(114),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(97),char(112),char(115),char(117),char(108), -char(101),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84),char(114),char(105),char(97),char(110),char(103),char(108), -char(101),char(73),char(110),char(102),char(111),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(71),char(73),char(109),char(112),char(97),char(99),char(116),char(77), -char(101),char(115),char(104),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(118),char(101), -char(120),char(72),char(117),char(108),char(108),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(108), -char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99),char(116),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97), -char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99),char(116), -char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(68),char(121),char(110),char(97),char(109),char(105),char(99),char(115), -char(87),char(111),char(114),char(108),char(100),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111), -char(110),char(116),char(97),char(99),char(116),char(83),char(111),char(108),char(118),char(101),char(114),char(73),char(110),char(102),char(111),char(68),char(111),char(117),char(98),char(108), -char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(68),char(121),char(110),char(97),char(109),char(105),char(99),char(115),char(87),char(111),char(114),char(108), -char(100),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(116),char(97),char(99),char(116), -char(83),char(111),char(108),char(118),char(101),char(114),char(73),char(110),char(102),char(111),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0), -char(98),char(116),char(82),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97), -char(0),char(98),char(116),char(82),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97), -char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(73),char(110),char(102),char(111),char(49), -char(0),char(98),char(116),char(84),char(121),char(112),char(101),char(100),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(97), -char(116),char(97),char(0),char(98),char(116),char(82),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(68),char(97),char(116),char(97),char(0),char(98), -char(116),char(80),char(111),char(105),char(110),char(116),char(50),char(80),char(111),char(105),char(110),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105), -char(110),char(116),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(80),char(111),char(105),char(110),char(116),char(50), -char(80),char(111),char(105),char(110),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(111),char(117),char(98),char(108), -char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(72),char(105),char(110),char(103),char(101),char(67),char(111),char(110),char(115),char(116),char(114),char(97), -char(105),char(110),char(116),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(72),char(105),char(110),char(103), -char(101),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97), -char(0),char(98),char(116),char(67),char(111),char(110),char(101),char(84),char(119),char(105),char(115),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105), -char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(71),char(101),char(110),char(101),char(114),char(105),char(99),char(54),char(68),char(111),char(102), -char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(71),char(101),char(110), -char(101),char(114),char(105),char(99),char(54),char(68),char(111),char(102),char(83),char(112),char(114),char(105),char(110),char(103),char(67),char(111),char(110),char(115),char(116),char(114), -char(97),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(83),char(108),char(105),char(100),char(101),char(114),char(67),char(111),char(110), -char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121), -char(77),char(97),char(116),char(101),char(114),char(105),char(97),char(108),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100), -char(121),char(78),char(111),char(100),char(101),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(76),char(105), -char(110),char(107),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(70),char(97),char(99),char(101),char(68), -char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(84),char(101),char(116),char(114),char(97),char(68),char(97),char(116), -char(97),char(0),char(83),char(111),char(102),char(116),char(82),char(105),char(103),char(105),char(100),char(65),char(110),char(99),char(104),char(111),char(114),char(68),char(97),char(116), -char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(67),char(111),char(110),char(102),char(105),char(103),char(68),char(97),char(116),char(97), -char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(80),char(111),char(115),char(101),char(68),char(97),char(116),char(97),char(0),char(83),char(111), -char(102),char(116),char(66),char(111),char(100),char(121),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(68),char(97),char(116),char(97),char(0),char(98),char(116), -char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(74),char(111),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116), -char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(0),char(0), -char(84),char(76),char(69),char(78),char(1),char(0),char(1),char(0),char(2),char(0),char(2),char(0),char(4),char(0),char(4),char(0),char(4),char(0),char(4),char(0), -char(8),char(0),char(0),char(0),char(12),char(0),char(36),char(0),char(8),char(0),char(16),char(0),char(32),char(0),char(48),char(0),char(96),char(0),char(64),char(0), -char(-128),char(0),char(20),char(0),char(48),char(0),char(80),char(0),char(16),char(0),char(84),char(0),char(-124),char(0),char(12),char(0),char(52),char(0),char(52),char(0), -char(20),char(0),char(64),char(0),char(4),char(0),char(4),char(0),char(8),char(0),char(4),char(0),char(32),char(0),char(28),char(0),char(60),char(0),char(56),char(0), -char(76),char(0),char(76),char(0),char(24),char(0),char(60),char(0),char(60),char(0),char(16),char(0),char(64),char(0),char(68),char(0),char(-48),char(1),char(0),char(1), -char(-72),char(0),char(-104),char(0),char(104),char(0),char(88),char(0),char(-24),char(1),char(-96),char(3),char(8),char(0),char(52),char(0),char(0),char(0),char(84),char(0), -char(116),char(0),char(92),char(1),char(-36),char(0),char(-44),char(0),char(-4),char(0),char(92),char(1),char(-52),char(0),char(16),char(0),char(100),char(0),char(20),char(0), -char(36),char(0),char(100),char(0),char(92),char(0),char(104),char(0),char(-64),char(0),char(92),char(1),char(104),char(0),char(-84),char(1),char(83),char(84),char(82),char(67), -char(65),char(0),char(0),char(0),char(10),char(0),char(3),char(0),char(4),char(0),char(0),char(0),char(4),char(0),char(1),char(0),char(9),char(0),char(2),char(0), -char(11),char(0),char(3),char(0),char(10),char(0),char(3),char(0),char(10),char(0),char(4),char(0),char(10),char(0),char(5),char(0),char(12),char(0),char(2),char(0), -char(9),char(0),char(6),char(0),char(9),char(0),char(7),char(0),char(13),char(0),char(1),char(0),char(7),char(0),char(8),char(0),char(14),char(0),char(1),char(0), -char(8),char(0),char(8),char(0),char(15),char(0),char(1),char(0),char(13),char(0),char(9),char(0),char(16),char(0),char(1),char(0),char(14),char(0),char(9),char(0), -char(17),char(0),char(2),char(0),char(15),char(0),char(10),char(0),char(13),char(0),char(11),char(0),char(18),char(0),char(2),char(0),char(16),char(0),char(10),char(0), -char(14),char(0),char(11),char(0),char(19),char(0),char(4),char(0),char(4),char(0),char(12),char(0),char(4),char(0),char(13),char(0),char(2),char(0),char(14),char(0), -char(2),char(0),char(15),char(0),char(20),char(0),char(6),char(0),char(13),char(0),char(16),char(0),char(13),char(0),char(17),char(0),char(4),char(0),char(18),char(0), -char(4),char(0),char(19),char(0),char(4),char(0),char(20),char(0),char(0),char(0),char(21),char(0),char(21),char(0),char(6),char(0),char(14),char(0),char(16),char(0), -char(14),char(0),char(17),char(0),char(4),char(0),char(18),char(0),char(4),char(0),char(19),char(0),char(4),char(0),char(20),char(0),char(0),char(0),char(21),char(0), -char(22),char(0),char(3),char(0),char(2),char(0),char(14),char(0),char(2),char(0),char(15),char(0),char(4),char(0),char(22),char(0),char(23),char(0),char(12),char(0), -char(13),char(0),char(23),char(0),char(13),char(0),char(24),char(0),char(13),char(0),char(25),char(0),char(4),char(0),char(26),char(0),char(4),char(0),char(27),char(0), -char(4),char(0),char(28),char(0),char(4),char(0),char(29),char(0),char(20),char(0),char(30),char(0),char(22),char(0),char(31),char(0),char(19),char(0),char(32),char(0), -char(4),char(0),char(33),char(0),char(4),char(0),char(34),char(0),char(24),char(0),char(12),char(0),char(14),char(0),char(23),char(0),char(14),char(0),char(24),char(0), -char(14),char(0),char(25),char(0),char(4),char(0),char(26),char(0),char(4),char(0),char(27),char(0),char(4),char(0),char(28),char(0),char(4),char(0),char(29),char(0), -char(21),char(0),char(30),char(0),char(22),char(0),char(31),char(0),char(4),char(0),char(33),char(0),char(4),char(0),char(34),char(0),char(19),char(0),char(32),char(0), -char(25),char(0),char(3),char(0),char(0),char(0),char(35),char(0),char(4),char(0),char(36),char(0),char(0),char(0),char(37),char(0),char(26),char(0),char(5),char(0), -char(25),char(0),char(38),char(0),char(13),char(0),char(39),char(0),char(13),char(0),char(40),char(0),char(7),char(0),char(41),char(0),char(0),char(0),char(21),char(0), -char(27),char(0),char(5),char(0),char(25),char(0),char(38),char(0),char(13),char(0),char(39),char(0),char(13),char(0),char(42),char(0),char(7),char(0),char(43),char(0), -char(4),char(0),char(44),char(0),char(28),char(0),char(2),char(0),char(13),char(0),char(45),char(0),char(7),char(0),char(46),char(0),char(29),char(0),char(4),char(0), -char(27),char(0),char(47),char(0),char(28),char(0),char(48),char(0),char(4),char(0),char(49),char(0),char(0),char(0),char(37),char(0),char(30),char(0),char(1),char(0), -char(4),char(0),char(50),char(0),char(31),char(0),char(2),char(0),char(2),char(0),char(50),char(0),char(0),char(0),char(51),char(0),char(32),char(0),char(2),char(0), -char(2),char(0),char(52),char(0),char(0),char(0),char(51),char(0),char(33),char(0),char(2),char(0),char(0),char(0),char(52),char(0),char(0),char(0),char(53),char(0), -char(34),char(0),char(8),char(0),char(13),char(0),char(54),char(0),char(14),char(0),char(55),char(0),char(30),char(0),char(56),char(0),char(32),char(0),char(57),char(0), -char(33),char(0),char(58),char(0),char(31),char(0),char(59),char(0),char(4),char(0),char(60),char(0),char(4),char(0),char(61),char(0),char(35),char(0),char(4),char(0), -char(34),char(0),char(62),char(0),char(13),char(0),char(63),char(0),char(4),char(0),char(64),char(0),char(0),char(0),char(37),char(0),char(36),char(0),char(7),char(0), -char(25),char(0),char(38),char(0),char(35),char(0),char(65),char(0),char(23),char(0),char(66),char(0),char(24),char(0),char(67),char(0),char(37),char(0),char(68),char(0), -char(7),char(0),char(43),char(0),char(0),char(0),char(69),char(0),char(38),char(0),char(2),char(0),char(36),char(0),char(70),char(0),char(13),char(0),char(39),char(0), -char(39),char(0),char(4),char(0),char(17),char(0),char(71),char(0),char(25),char(0),char(72),char(0),char(4),char(0),char(73),char(0),char(7),char(0),char(74),char(0), -char(40),char(0),char(4),char(0),char(25),char(0),char(38),char(0),char(39),char(0),char(75),char(0),char(4),char(0),char(76),char(0),char(7),char(0),char(43),char(0), -char(41),char(0),char(3),char(0),char(27),char(0),char(47),char(0),char(4),char(0),char(77),char(0),char(0),char(0),char(37),char(0),char(42),char(0),char(3),char(0), -char(27),char(0),char(47),char(0),char(4),char(0),char(77),char(0),char(0),char(0),char(37),char(0),char(43),char(0),char(4),char(0),char(4),char(0),char(78),char(0), -char(7),char(0),char(79),char(0),char(7),char(0),char(80),char(0),char(7),char(0),char(81),char(0),char(37),char(0),char(14),char(0),char(4),char(0),char(82),char(0), -char(4),char(0),char(83),char(0),char(43),char(0),char(84),char(0),char(4),char(0),char(85),char(0),char(7),char(0),char(86),char(0),char(7),char(0),char(87),char(0), -char(7),char(0),char(88),char(0),char(7),char(0),char(89),char(0),char(7),char(0),char(90),char(0),char(4),char(0),char(91),char(0),char(4),char(0),char(92),char(0), -char(4),char(0),char(93),char(0),char(4),char(0),char(94),char(0),char(0),char(0),char(37),char(0),char(44),char(0),char(5),char(0),char(25),char(0),char(38),char(0), -char(35),char(0),char(65),char(0),char(13),char(0),char(39),char(0),char(7),char(0),char(43),char(0),char(4),char(0),char(95),char(0),char(45),char(0),char(5),char(0), -char(27),char(0),char(47),char(0),char(13),char(0),char(96),char(0),char(14),char(0),char(97),char(0),char(4),char(0),char(98),char(0),char(0),char(0),char(99),char(0), -char(46),char(0),char(25),char(0),char(9),char(0),char(100),char(0),char(9),char(0),char(101),char(0),char(25),char(0),char(102),char(0),char(0),char(0),char(35),char(0), -char(18),char(0),char(103),char(0),char(18),char(0),char(104),char(0),char(14),char(0),char(105),char(0),char(14),char(0),char(106),char(0),char(14),char(0),char(107),char(0), -char(8),char(0),char(108),char(0),char(8),char(0),char(109),char(0),char(8),char(0),char(110),char(0),char(8),char(0),char(111),char(0),char(8),char(0),char(112),char(0), -char(8),char(0),char(113),char(0),char(8),char(0),char(114),char(0),char(8),char(0),char(115),char(0),char(4),char(0),char(116),char(0),char(4),char(0),char(117),char(0), -char(4),char(0),char(118),char(0),char(4),char(0),char(119),char(0),char(4),char(0),char(120),char(0),char(4),char(0),char(121),char(0),char(4),char(0),char(122),char(0), -char(0),char(0),char(37),char(0),char(47),char(0),char(25),char(0),char(9),char(0),char(100),char(0),char(9),char(0),char(101),char(0),char(25),char(0),char(102),char(0), -char(0),char(0),char(35),char(0),char(17),char(0),char(103),char(0),char(17),char(0),char(104),char(0),char(13),char(0),char(105),char(0),char(13),char(0),char(106),char(0), -char(13),char(0),char(107),char(0),char(7),char(0),char(108),char(0),char(7),char(0),char(109),char(0),char(7),char(0),char(110),char(0),char(7),char(0),char(111),char(0), -char(7),char(0),char(112),char(0),char(7),char(0),char(113),char(0),char(7),char(0),char(114),char(0),char(7),char(0),char(115),char(0),char(4),char(0),char(116),char(0), -char(4),char(0),char(117),char(0),char(4),char(0),char(118),char(0),char(4),char(0),char(119),char(0),char(4),char(0),char(120),char(0),char(4),char(0),char(121),char(0), -char(4),char(0),char(122),char(0),char(0),char(0),char(37),char(0),char(48),char(0),char(2),char(0),char(49),char(0),char(123),char(0),char(14),char(0),char(124),char(0), -char(50),char(0),char(2),char(0),char(51),char(0),char(123),char(0),char(13),char(0),char(124),char(0),char(52),char(0),char(21),char(0),char(47),char(0),char(125),char(0), -char(15),char(0),char(126),char(0),char(13),char(0),char(127),char(0),char(13),char(0),char(-128),char(0),char(13),char(0),char(-127),char(0),char(13),char(0),char(-126),char(0), -char(13),char(0),char(124),char(0),char(13),char(0),char(-125),char(0),char(13),char(0),char(-124),char(0),char(13),char(0),char(-123),char(0),char(13),char(0),char(-122),char(0), -char(7),char(0),char(-121),char(0),char(7),char(0),char(-120),char(0),char(7),char(0),char(-119),char(0),char(7),char(0),char(-118),char(0),char(7),char(0),char(-117),char(0), -char(7),char(0),char(-116),char(0),char(7),char(0),char(-115),char(0),char(7),char(0),char(-114),char(0),char(7),char(0),char(-113),char(0),char(4),char(0),char(-112),char(0), -char(53),char(0),char(22),char(0),char(46),char(0),char(125),char(0),char(16),char(0),char(126),char(0),char(14),char(0),char(127),char(0),char(14),char(0),char(-128),char(0), -char(14),char(0),char(-127),char(0),char(14),char(0),char(-126),char(0),char(14),char(0),char(124),char(0),char(14),char(0),char(-125),char(0),char(14),char(0),char(-124),char(0), -char(14),char(0),char(-123),char(0),char(14),char(0),char(-122),char(0),char(8),char(0),char(-121),char(0),char(8),char(0),char(-120),char(0),char(8),char(0),char(-119),char(0), -char(8),char(0),char(-118),char(0),char(8),char(0),char(-117),char(0),char(8),char(0),char(-116),char(0),char(8),char(0),char(-115),char(0),char(8),char(0),char(-114),char(0), -char(8),char(0),char(-113),char(0),char(4),char(0),char(-112),char(0),char(0),char(0),char(37),char(0),char(54),char(0),char(2),char(0),char(4),char(0),char(-111),char(0), -char(4),char(0),char(-110),char(0),char(55),char(0),char(13),char(0),char(56),char(0),char(-109),char(0),char(56),char(0),char(-108),char(0),char(0),char(0),char(35),char(0), -char(4),char(0),char(-107),char(0),char(4),char(0),char(-106),char(0),char(4),char(0),char(-105),char(0),char(4),char(0),char(-104),char(0),char(7),char(0),char(-103),char(0), -char(7),char(0),char(-102),char(0),char(4),char(0),char(-101),char(0),char(4),char(0),char(-100),char(0),char(7),char(0),char(-99),char(0),char(4),char(0),char(-98),char(0), -char(57),char(0),char(3),char(0),char(55),char(0),char(-97),char(0),char(13),char(0),char(-96),char(0),char(13),char(0),char(-95),char(0),char(58),char(0),char(3),char(0), -char(55),char(0),char(-97),char(0),char(14),char(0),char(-96),char(0),char(14),char(0),char(-95),char(0),char(59),char(0),char(13),char(0),char(55),char(0),char(-97),char(0), -char(18),char(0),char(-94),char(0),char(18),char(0),char(-93),char(0),char(4),char(0),char(-92),char(0),char(4),char(0),char(-91),char(0),char(4),char(0),char(-90),char(0), -char(7),char(0),char(-89),char(0),char(7),char(0),char(-88),char(0),char(7),char(0),char(-87),char(0),char(7),char(0),char(-86),char(0),char(7),char(0),char(-85),char(0), -char(7),char(0),char(-84),char(0),char(7),char(0),char(-83),char(0),char(60),char(0),char(13),char(0),char(55),char(0),char(-97),char(0),char(17),char(0),char(-94),char(0), -char(17),char(0),char(-93),char(0),char(4),char(0),char(-92),char(0),char(4),char(0),char(-91),char(0),char(4),char(0),char(-90),char(0),char(7),char(0),char(-89),char(0), -char(7),char(0),char(-88),char(0),char(7),char(0),char(-87),char(0),char(7),char(0),char(-86),char(0),char(7),char(0),char(-85),char(0),char(7),char(0),char(-84),char(0), -char(7),char(0),char(-83),char(0),char(61),char(0),char(11),char(0),char(55),char(0),char(-97),char(0),char(17),char(0),char(-94),char(0),char(17),char(0),char(-93),char(0), -char(7),char(0),char(-82),char(0),char(7),char(0),char(-81),char(0),char(7),char(0),char(-80),char(0),char(7),char(0),char(-85),char(0),char(7),char(0),char(-84),char(0), -char(7),char(0),char(-83),char(0),char(7),char(0),char(-79),char(0),char(0),char(0),char(21),char(0),char(62),char(0),char(9),char(0),char(55),char(0),char(-97),char(0), -char(17),char(0),char(-94),char(0),char(17),char(0),char(-93),char(0),char(13),char(0),char(-78),char(0),char(13),char(0),char(-77),char(0),char(13),char(0),char(-76),char(0), -char(13),char(0),char(-75),char(0),char(4),char(0),char(-74),char(0),char(4),char(0),char(-73),char(0),char(63),char(0),char(5),char(0),char(62),char(0),char(-72),char(0), -char(4),char(0),char(-71),char(0),char(7),char(0),char(-70),char(0),char(7),char(0),char(-69),char(0),char(7),char(0),char(-68),char(0),char(64),char(0),char(9),char(0), -char(55),char(0),char(-97),char(0),char(17),char(0),char(-94),char(0),char(17),char(0),char(-93),char(0),char(7),char(0),char(-78),char(0),char(7),char(0),char(-77),char(0), -char(7),char(0),char(-76),char(0),char(7),char(0),char(-75),char(0),char(4),char(0),char(-74),char(0),char(4),char(0),char(-73),char(0),char(49),char(0),char(22),char(0), -char(8),char(0),char(-67),char(0),char(8),char(0),char(-79),char(0),char(8),char(0),char(110),char(0),char(8),char(0),char(-66),char(0),char(8),char(0),char(112),char(0), -char(8),char(0),char(-65),char(0),char(8),char(0),char(-64),char(0),char(8),char(0),char(-63),char(0),char(8),char(0),char(-62),char(0),char(8),char(0),char(-61),char(0), -char(8),char(0),char(-60),char(0),char(8),char(0),char(-59),char(0),char(8),char(0),char(-58),char(0),char(8),char(0),char(-57),char(0),char(8),char(0),char(-56),char(0), -char(8),char(0),char(-55),char(0),char(4),char(0),char(-54),char(0),char(4),char(0),char(-53),char(0),char(4),char(0),char(-52),char(0),char(4),char(0),char(-51),char(0), -char(4),char(0),char(-50),char(0),char(0),char(0),char(37),char(0),char(51),char(0),char(22),char(0),char(7),char(0),char(-67),char(0),char(7),char(0),char(-79),char(0), -char(7),char(0),char(110),char(0),char(7),char(0),char(-66),char(0),char(7),char(0),char(112),char(0),char(7),char(0),char(-65),char(0),char(7),char(0),char(-64),char(0), -char(7),char(0),char(-63),char(0),char(7),char(0),char(-62),char(0),char(7),char(0),char(-61),char(0),char(7),char(0),char(-60),char(0),char(7),char(0),char(-59),char(0), -char(7),char(0),char(-58),char(0),char(7),char(0),char(-57),char(0),char(7),char(0),char(-56),char(0),char(7),char(0),char(-55),char(0),char(4),char(0),char(-54),char(0), -char(4),char(0),char(-53),char(0),char(4),char(0),char(-52),char(0),char(4),char(0),char(-51),char(0),char(4),char(0),char(-50),char(0),char(0),char(0),char(37),char(0), -char(65),char(0),char(4),char(0),char(7),char(0),char(-49),char(0),char(7),char(0),char(-48),char(0),char(7),char(0),char(-47),char(0),char(4),char(0),char(78),char(0), -char(66),char(0),char(10),char(0),char(65),char(0),char(-46),char(0),char(13),char(0),char(-45),char(0),char(13),char(0),char(-44),char(0),char(13),char(0),char(-43),char(0), -char(13),char(0),char(-42),char(0),char(13),char(0),char(-41),char(0),char(7),char(0),char(-121),char(0),char(7),char(0),char(-40),char(0),char(4),char(0),char(-39),char(0), -char(4),char(0),char(53),char(0),char(67),char(0),char(4),char(0),char(65),char(0),char(-46),char(0),char(4),char(0),char(-38),char(0),char(7),char(0),char(-37),char(0), -char(4),char(0),char(-36),char(0),char(68),char(0),char(4),char(0),char(13),char(0),char(-41),char(0),char(65),char(0),char(-46),char(0),char(4),char(0),char(-35),char(0), -char(7),char(0),char(-34),char(0),char(69),char(0),char(7),char(0),char(13),char(0),char(-33),char(0),char(65),char(0),char(-46),char(0),char(4),char(0),char(-32),char(0), -char(7),char(0),char(-31),char(0),char(7),char(0),char(-30),char(0),char(7),char(0),char(-29),char(0),char(4),char(0),char(53),char(0),char(70),char(0),char(6),char(0), -char(15),char(0),char(-28),char(0),char(13),char(0),char(-30),char(0),char(13),char(0),char(-27),char(0),char(56),char(0),char(-26),char(0),char(4),char(0),char(-25),char(0), -char(7),char(0),char(-29),char(0),char(71),char(0),char(26),char(0),char(4),char(0),char(-24),char(0),char(7),char(0),char(-23),char(0),char(7),char(0),char(-79),char(0), -char(7),char(0),char(-22),char(0),char(7),char(0),char(-21),char(0),char(7),char(0),char(-20),char(0),char(7),char(0),char(-19),char(0),char(7),char(0),char(-18),char(0), -char(7),char(0),char(-17),char(0),char(7),char(0),char(-16),char(0),char(7),char(0),char(-15),char(0),char(7),char(0),char(-14),char(0),char(7),char(0),char(-13),char(0), -char(7),char(0),char(-12),char(0),char(7),char(0),char(-11),char(0),char(7),char(0),char(-10),char(0),char(7),char(0),char(-9),char(0),char(7),char(0),char(-8),char(0), -char(7),char(0),char(-7),char(0),char(7),char(0),char(-6),char(0),char(7),char(0),char(-5),char(0),char(4),char(0),char(-4),char(0),char(4),char(0),char(-3),char(0), -char(4),char(0),char(-2),char(0),char(4),char(0),char(-1),char(0),char(4),char(0),char(117),char(0),char(72),char(0),char(12),char(0),char(15),char(0),char(0),char(1), -char(15),char(0),char(1),char(1),char(15),char(0),char(2),char(1),char(13),char(0),char(3),char(1),char(13),char(0),char(4),char(1),char(7),char(0),char(5),char(1), -char(4),char(0),char(6),char(1),char(4),char(0),char(7),char(1),char(4),char(0),char(8),char(1),char(4),char(0),char(9),char(1),char(7),char(0),char(-31),char(0), -char(4),char(0),char(53),char(0),char(73),char(0),char(27),char(0),char(17),char(0),char(10),char(1),char(15),char(0),char(11),char(1),char(15),char(0),char(12),char(1), -char(13),char(0),char(3),char(1),char(13),char(0),char(13),char(1),char(13),char(0),char(14),char(1),char(13),char(0),char(15),char(1),char(13),char(0),char(16),char(1), -char(13),char(0),char(17),char(1),char(4),char(0),char(18),char(1),char(7),char(0),char(19),char(1),char(4),char(0),char(20),char(1),char(4),char(0),char(21),char(1), -char(4),char(0),char(22),char(1),char(7),char(0),char(23),char(1),char(7),char(0),char(24),char(1),char(4),char(0),char(25),char(1),char(4),char(0),char(26),char(1), -char(7),char(0),char(27),char(1),char(7),char(0),char(28),char(1),char(7),char(0),char(29),char(1),char(7),char(0),char(30),char(1),char(7),char(0),char(31),char(1), -char(7),char(0),char(32),char(1),char(4),char(0),char(33),char(1),char(4),char(0),char(34),char(1),char(4),char(0),char(35),char(1),char(74),char(0),char(12),char(0), -char(9),char(0),char(36),char(1),char(9),char(0),char(37),char(1),char(13),char(0),char(38),char(1),char(7),char(0),char(39),char(1),char(7),char(0),char(-63),char(0), -char(7),char(0),char(40),char(1),char(4),char(0),char(41),char(1),char(13),char(0),char(42),char(1),char(4),char(0),char(43),char(1),char(4),char(0),char(44),char(1), -char(4),char(0),char(45),char(1),char(4),char(0),char(53),char(0),char(75),char(0),char(19),char(0),char(47),char(0),char(125),char(0),char(72),char(0),char(46),char(1), -char(65),char(0),char(47),char(1),char(66),char(0),char(48),char(1),char(67),char(0),char(49),char(1),char(68),char(0),char(50),char(1),char(69),char(0),char(51),char(1), -char(70),char(0),char(52),char(1),char(73),char(0),char(53),char(1),char(74),char(0),char(54),char(1),char(4),char(0),char(55),char(1),char(4),char(0),char(21),char(1), -char(4),char(0),char(56),char(1),char(4),char(0),char(57),char(1),char(4),char(0),char(58),char(1),char(4),char(0),char(59),char(1),char(4),char(0),char(60),char(1), -char(4),char(0),char(61),char(1),char(71),char(0),char(62),char(1),}; -int b3s_bulletDNAlen= sizeof(b3s_bulletDNAstr); -char b3s_bulletDNAstr64[]= { -char(83),char(68),char(78),char(65),char(78),char(65),char(77),char(69),char(63),char(1),char(0),char(0),char(109),char(95),char(115),char(105),char(122),char(101),char(0),char(109), -char(95),char(99),char(97),char(112),char(97),char(99),char(105),char(116),char(121),char(0),char(42),char(109),char(95),char(100),char(97),char(116),char(97),char(0),char(109),char(95), -char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(83),char(104),char(97),char(112),char(101),char(115),char(0),char(109),char(95),char(99),char(111), -char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99),char(116),char(115),char(0),char(109),char(95),char(99),char(111),char(110), -char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(115),char(0),char(42),char(102),char(105),char(114),char(115),char(116),char(0),char(42),char(108),char(97),char(115), -char(116),char(0),char(109),char(95),char(102),char(108),char(111),char(97),char(116),char(115),char(91),char(52),char(93),char(0),char(109),char(95),char(101),char(108),char(91),char(51), -char(93),char(0),char(109),char(95),char(98),char(97),char(115),char(105),char(115),char(0),char(109),char(95),char(111),char(114),char(105),char(103),char(105),char(110),char(0),char(109), -char(95),char(114),char(111),char(111),char(116),char(78),char(111),char(100),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(115),char(117),char(98), -char(116),char(114),char(101),char(101),char(83),char(105),char(122),char(101),char(0),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100), -char(65),char(97),char(98),char(98),char(77),char(105),char(110),char(91),char(51),char(93),char(0),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122), -char(101),char(100),char(65),char(97),char(98),char(98),char(77),char(97),char(120),char(91),char(51),char(93),char(0),char(109),char(95),char(97),char(97),char(98),char(98),char(77), -char(105),char(110),char(79),char(114),char(103),char(0),char(109),char(95),char(97),char(97),char(98),char(98),char(77),char(97),char(120),char(79),char(114),char(103),char(0),char(109), -char(95),char(101),char(115),char(99),char(97),char(112),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(115),char(117),char(98),char(80),char(97), -char(114),char(116),char(0),char(109),char(95),char(116),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109), -char(95),char(112),char(97),char(100),char(91),char(52),char(93),char(0),char(109),char(95),char(101),char(115),char(99),char(97),char(112),char(101),char(73),char(110),char(100),char(101), -char(120),char(79),char(114),char(84),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(98), -char(118),char(104),char(65),char(97),char(98),char(98),char(77),char(105),char(110),char(0),char(109),char(95),char(98),char(118),char(104),char(65),char(97),char(98),char(98),char(77), -char(97),char(120),char(0),char(109),char(95),char(98),char(118),char(104),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(97),char(116),char(105),char(111),char(110), -char(0),char(109),char(95),char(99),char(117),char(114),char(78),char(111),char(100),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(117),char(115), -char(101),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(97),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(110),char(117),char(109),char(67), -char(111),char(110),char(116),char(105),char(103),char(117),char(111),char(117),char(115),char(76),char(101),char(97),char(102),char(78),char(111),char(100),char(101),char(115),char(0),char(109), -char(95),char(110),char(117),char(109),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(67),char(111),char(110),char(116),char(105),char(103),char(117), -char(111),char(117),char(115),char(78),char(111),char(100),char(101),char(115),char(0),char(42),char(109),char(95),char(99),char(111),char(110),char(116),char(105),char(103),char(117),char(111), -char(117),char(115),char(78),char(111),char(100),char(101),char(115),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105), -char(122),char(101),char(100),char(67),char(111),char(110),char(116),char(105),char(103),char(117),char(111),char(117),char(115),char(78),char(111),char(100),char(101),char(115),char(80),char(116), -char(114),char(0),char(42),char(109),char(95),char(115),char(117),char(98),char(84),char(114),char(101),char(101),char(73),char(110),char(102),char(111),char(80),char(116),char(114),char(0), -char(109),char(95),char(116),char(114),char(97),char(118),char(101),char(114),char(115),char(97),char(108),char(77),char(111),char(100),char(101),char(0),char(109),char(95),char(110),char(117), -char(109),char(83),char(117),char(98),char(116),char(114),char(101),char(101),char(72),char(101),char(97),char(100),char(101),char(114),char(115),char(0),char(42),char(109),char(95),char(110), -char(97),char(109),char(101),char(0),char(109),char(95),char(115),char(104),char(97),char(112),char(101),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(112),char(97), -char(100),char(100),char(105),char(110),char(103),char(91),char(52),char(93),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110), -char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(108),char(111),char(99),char(97),char(108),char(83),char(99),char(97), -char(108),char(105),char(110),char(103),char(0),char(109),char(95),char(112),char(108),char(97),char(110),char(101),char(78),char(111),char(114),char(109),char(97),char(108),char(0),char(109), -char(95),char(112),char(108),char(97),char(110),char(101),char(67),char(111),char(110),char(115),char(116),char(97),char(110),char(116),char(0),char(109),char(95),char(105),char(109),char(112), -char(108),char(105),char(99),char(105),char(116),char(83),char(104),char(97),char(112),char(101),char(68),char(105),char(109),char(101),char(110),char(115),char(105),char(111),char(110),char(115), -char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(77),char(97),char(114),char(103),char(105),char(110),char(0),char(109), -char(95),char(112),char(97),char(100),char(100),char(105),char(110),char(103),char(0),char(109),char(95),char(112),char(111),char(115),char(0),char(109),char(95),char(114),char(97),char(100), -char(105),char(117),char(115),char(0),char(109),char(95),char(99),char(111),char(110),char(118),char(101),char(120),char(73),char(110),char(116),char(101),char(114),char(110),char(97),char(108), -char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(42),char(109),char(95),char(108),char(111),char(99),char(97),char(108),char(80),char(111), -char(115),char(105),char(116),char(105),char(111),char(110),char(65),char(114),char(114),char(97),char(121),char(80),char(116),char(114),char(0),char(109),char(95),char(108),char(111),char(99), -char(97),char(108),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(65),char(114),char(114),char(97),char(121),char(83),char(105),char(122),char(101),char(0), -char(109),char(95),char(118),char(97),char(108),char(117),char(101),char(0),char(109),char(95),char(112),char(97),char(100),char(91),char(50),char(93),char(0),char(109),char(95),char(118), -char(97),char(108),char(117),char(101),char(115),char(91),char(51),char(93),char(0),char(109),char(95),char(112),char(97),char(100),char(0),char(42),char(109),char(95),char(118),char(101), -char(114),char(116),char(105),char(99),char(101),char(115),char(51),char(102),char(0),char(42),char(109),char(95),char(118),char(101),char(114),char(116),char(105),char(99),char(101),char(115), -char(51),char(100),char(0),char(42),char(109),char(95),char(105),char(110),char(100),char(105),char(99),char(101),char(115),char(51),char(50),char(0),char(42),char(109),char(95),char(51), -char(105),char(110),char(100),char(105),char(99),char(101),char(115),char(49),char(54),char(0),char(42),char(109),char(95),char(51),char(105),char(110),char(100),char(105),char(99),char(101), -char(115),char(56),char(0),char(42),char(109),char(95),char(105),char(110),char(100),char(105),char(99),char(101),char(115),char(49),char(54),char(0),char(109),char(95),char(110),char(117), -char(109),char(84),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(86),char(101),char(114),char(116), -char(105),char(99),char(101),char(115),char(0),char(42),char(109),char(95),char(109),char(101),char(115),char(104),char(80),char(97),char(114),char(116),char(115),char(80),char(116),char(114), -char(0),char(109),char(95),char(115),char(99),char(97),char(108),char(105),char(110),char(103),char(0),char(109),char(95),char(110),char(117),char(109),char(77),char(101),char(115),char(104), -char(80),char(97),char(114),char(116),char(115),char(0),char(109),char(95),char(109),char(101),char(115),char(104),char(73),char(110),char(116),char(101),char(114),char(102),char(97),char(99), -char(101),char(0),char(42),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(70),char(108),char(111),char(97),char(116),char(66), -char(118),char(104),char(0),char(42),char(109),char(95),char(113),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(68),char(111),char(117),char(98),char(108), -char(101),char(66),char(118),char(104),char(0),char(42),char(109),char(95),char(116),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(102),char(111), -char(77),char(97),char(112),char(0),char(109),char(95),char(112),char(97),char(100),char(51),char(91),char(52),char(93),char(0),char(109),char(95),char(116),char(114),char(105),char(109), -char(101),char(115),char(104),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(116),char(114),char(97),char(110),char(115), -char(102),char(111),char(114),char(109),char(0),char(42),char(109),char(95),char(99),char(104),char(105),char(108),char(100),char(83),char(104),char(97),char(112),char(101),char(0),char(109), -char(95),char(99),char(104),char(105),char(108),char(100),char(83),char(104),char(97),char(112),char(101),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(99),char(104), -char(105),char(108),char(100),char(77),char(97),char(114),char(103),char(105),char(110),char(0),char(42),char(109),char(95),char(99),char(104),char(105),char(108),char(100),char(83),char(104), -char(97),char(112),char(101),char(80),char(116),char(114),char(0),char(109),char(95),char(110),char(117),char(109),char(67),char(104),char(105),char(108),char(100),char(83),char(104),char(97), -char(112),char(101),char(115),char(0),char(109),char(95),char(117),char(112),char(65),char(120),char(105),char(115),char(0),char(109),char(95),char(102),char(108),char(97),char(103),char(115), -char(0),char(109),char(95),char(101),char(100),char(103),char(101),char(86),char(48),char(86),char(49),char(65),char(110),char(103),char(108),char(101),char(0),char(109),char(95),char(101), -char(100),char(103),char(101),char(86),char(49),char(86),char(50),char(65),char(110),char(103),char(108),char(101),char(0),char(109),char(95),char(101),char(100),char(103),char(101),char(86), -char(50),char(86),char(48),char(65),char(110),char(103),char(108),char(101),char(0),char(42),char(109),char(95),char(104),char(97),char(115),char(104),char(84),char(97),char(98),char(108), -char(101),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(110),char(101),char(120),char(116),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(118), -char(97),char(108),char(117),char(101),char(65),char(114),char(114),char(97),char(121),char(80),char(116),char(114),char(0),char(42),char(109),char(95),char(107),char(101),char(121),char(65), -char(114),char(114),char(97),char(121),char(80),char(116),char(114),char(0),char(109),char(95),char(99),char(111),char(110),char(118),char(101),char(120),char(69),char(112),char(115),char(105), -char(108),char(111),char(110),char(0),char(109),char(95),char(112),char(108),char(97),char(110),char(97),char(114),char(69),char(112),char(115),char(105),char(108),char(111),char(110),char(0), -char(109),char(95),char(101),char(113),char(117),char(97),char(108),char(86),char(101),char(114),char(116),char(101),char(120),char(84),char(104),char(114),char(101),char(115),char(104),char(111), -char(108),char(100),char(0),char(109),char(95),char(101),char(100),char(103),char(101),char(68),char(105),char(115),char(116),char(97),char(110),char(99),char(101),char(84),char(104),char(114), -char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(122),char(101),char(114),char(111),char(65),char(114),char(101),char(97),char(84),char(104),char(114), -char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(110),char(101),char(120),char(116),char(83),char(105),char(122),char(101),char(0),char(109),char(95), -char(104),char(97),char(115),char(104),char(84),char(97),char(98),char(108),char(101),char(83),char(105),char(122),char(101),char(0),char(109),char(95),char(110),char(117),char(109),char(86), -char(97),char(108),char(117),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(75),char(101),char(121),char(115),char(0),char(109),char(95),char(103),char(105), -char(109),char(112),char(97),char(99),char(116),char(83),char(117),char(98),char(84),char(121),char(112),char(101),char(0),char(42),char(109),char(95),char(117),char(110),char(115),char(99), -char(97),char(108),char(101),char(100),char(80),char(111),char(105),char(110),char(116),char(115),char(70),char(108),char(111),char(97),char(116),char(80),char(116),char(114),char(0),char(42), -char(109),char(95),char(117),char(110),char(115),char(99),char(97),char(108),char(101),char(100),char(80),char(111),char(105),char(110),char(116),char(115),char(68),char(111),char(117),char(98), -char(108),char(101),char(80),char(116),char(114),char(0),char(109),char(95),char(110),char(117),char(109),char(85),char(110),char(115),char(99),char(97),char(108),char(101),char(100),char(80), -char(111),char(105),char(110),char(116),char(115),char(0),char(109),char(95),char(112),char(97),char(100),char(100),char(105),char(110),char(103),char(51),char(91),char(52),char(93),char(0), -char(42),char(109),char(95),char(98),char(114),char(111),char(97),char(100),char(112),char(104),char(97),char(115),char(101),char(72),char(97),char(110),char(100),char(108),char(101),char(0), -char(42),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(83),char(104),char(97),char(112),char(101),char(0),char(42),char(109), -char(95),char(114),char(111),char(111),char(116),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(83),char(104),char(97),char(112),char(101),char(0), -char(109),char(95),char(119),char(111),char(114),char(108),char(100),char(84),char(114),char(97),char(110),char(115),char(102),char(111),char(114),char(109),char(0),char(109),char(95),char(105), -char(110),char(116),char(101),char(114),char(112),char(111),char(108),char(97),char(116),char(105),char(111),char(110),char(87),char(111),char(114),char(108),char(100),char(84),char(114),char(97), -char(110),char(115),char(102),char(111),char(114),char(109),char(0),char(109),char(95),char(105),char(110),char(116),char(101),char(114),char(112),char(111),char(108),char(97),char(116),char(105), -char(111),char(110),char(76),char(105),char(110),char(101),char(97),char(114),char(86),char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(105), -char(110),char(116),char(101),char(114),char(112),char(111),char(108),char(97),char(116),char(105),char(111),char(110),char(65),char(110),char(103),char(117),char(108),char(97),char(114),char(86), -char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(110),char(105),char(115),char(111),char(116),char(114),char(111),char(112),char(105), -char(99),char(70),char(114),char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(99),char(111),char(110),char(116),char(97),char(99),char(116),char(80), -char(114),char(111),char(99),char(101),char(115),char(115),char(105),char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109), -char(95),char(100),char(101),char(97),char(99),char(116),char(105),char(118),char(97),char(116),char(105),char(111),char(110),char(84),char(105),char(109),char(101),char(0),char(109),char(95), -char(102),char(114),char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(114),char(111),char(108),char(108),char(105),char(110),char(103),char(70),char(114), -char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(105),char(116),char(117),char(116),char(105),char(111),char(110), -char(0),char(109),char(95),char(104),char(105),char(116),char(70),char(114),char(97),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(99),char(99),char(100), -char(83),char(119),char(101),char(112),char(116),char(83),char(112),char(104),char(101),char(114),char(101),char(82),char(97),char(100),char(105),char(117),char(115),char(0),char(109),char(95), -char(99),char(99),char(100),char(77),char(111),char(116),char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109), -char(95),char(104),char(97),char(115),char(65),char(110),char(105),char(115),char(111),char(116),char(114),char(111),char(112),char(105),char(99),char(70),char(114),char(105),char(99),char(116), -char(105),char(111),char(110),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(70),char(108),char(97),char(103),char(115), -char(0),char(109),char(95),char(105),char(115),char(108),char(97),char(110),char(100),char(84),char(97),char(103),char(49),char(0),char(109),char(95),char(99),char(111),char(109),char(112), -char(97),char(110),char(105),char(111),char(110),char(73),char(100),char(0),char(109),char(95),char(97),char(99),char(116),char(105),char(118),char(97),char(116),char(105),char(111),char(110), -char(83),char(116),char(97),char(116),char(101),char(49),char(0),char(109),char(95),char(105),char(110),char(116),char(101),char(114),char(110),char(97),char(108),char(84),char(121),char(112), -char(101),char(0),char(109),char(95),char(99),char(104),char(101),char(99),char(107),char(67),char(111),char(108),char(108),char(105),char(100),char(101),char(87),char(105),char(116),char(104), -char(0),char(109),char(95),char(115),char(111),char(108),char(118),char(101),char(114),char(73),char(110),char(102),char(111),char(0),char(109),char(95),char(103),char(114),char(97),char(118), -char(105),char(116),char(121),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99), -char(116),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(105),char(110),char(118),char(73),char(110),char(101),char(114),char(116),char(105),char(97),char(84),char(101), -char(110),char(115),char(111),char(114),char(87),char(111),char(114),char(108),char(100),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(86),char(101), -char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(86),char(101),char(108),char(111), -char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(70),char(97),char(99),char(116),char(111),char(114), -char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(103),char(114), -char(97),char(118),char(105),char(116),char(121),char(95),char(97),char(99),char(99),char(101),char(108),char(101),char(114),char(97),char(116),char(105),char(111),char(110),char(0),char(109), -char(95),char(105),char(110),char(118),char(73),char(110),char(101),char(114),char(116),char(105),char(97),char(76),char(111),char(99),char(97),char(108),char(0),char(109),char(95),char(116), -char(111),char(116),char(97),char(108),char(70),char(111),char(114),char(99),char(101),char(0),char(109),char(95),char(116),char(111),char(116),char(97),char(108),char(84),char(111),char(114), -char(113),char(117),char(101),char(0),char(109),char(95),char(105),char(110),char(118),char(101),char(114),char(115),char(101),char(77),char(97),char(115),char(115),char(0),char(109),char(95), -char(108),char(105),char(110),char(101),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(97),char(110),char(103),char(117), -char(108),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(97),char(100),char(100),char(105),char(116),char(105),char(111), -char(110),char(97),char(108),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(97), -char(100),char(100),char(105),char(116),char(105),char(111),char(110),char(97),char(108),char(76),char(105),char(110),char(101),char(97),char(114),char(68),char(97),char(109),char(112),char(105), -char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(83),char(113),char(114),char(0),char(109),char(95),char(97),char(100),char(100), -char(105),char(116),char(105),char(111),char(110),char(97),char(108),char(65),char(110),char(103),char(117),char(108),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110), -char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(83),char(113),char(114),char(0),char(109),char(95),char(97),char(100),char(100),char(105), -char(116),char(105),char(111),char(110),char(97),char(108),char(65),char(110),char(103),char(117),char(108),char(97),char(114),char(68),char(97),char(109),char(112),char(105),char(110),char(103), -char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(83),char(108),char(101),char(101),char(112), -char(105),char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108), -char(97),char(114),char(83),char(108),char(101),char(101),char(112),char(105),char(110),char(103),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0), -char(109),char(95),char(97),char(100),char(100),char(105),char(116),char(105),char(111),char(110),char(97),char(108),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(0), -char(109),char(95),char(110),char(117),char(109),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(82),char(111),char(119),char(115),char(0), -char(110),char(117),char(98),char(0),char(42),char(109),char(95),char(114),char(98),char(65),char(0),char(42),char(109),char(95),char(114),char(98),char(66),char(0),char(109),char(95), -char(111),char(98),char(106),char(101),char(99),char(116),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(117),char(115),char(101),char(114),char(67),char(111),char(110), -char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(84),char(121),char(112),char(101),char(0),char(109),char(95),char(117),char(115),char(101),char(114),char(67),char(111), -char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(73),char(100),char(0),char(109),char(95),char(110),char(101),char(101),char(100),char(115),char(70),char(101), -char(101),char(100),char(98),char(97),char(99),char(107),char(0),char(109),char(95),char(97),char(112),char(112),char(108),char(105),char(101),char(100),char(73),char(109),char(112),char(117), -char(108),char(115),char(101),char(0),char(109),char(95),char(100),char(98),char(103),char(68),char(114),char(97),char(119),char(83),char(105),char(122),char(101),char(0),char(109),char(95), -char(100),char(105),char(115),char(97),char(98),char(108),char(101),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(115),char(66),char(101),char(116), -char(119),char(101),char(101),char(110),char(76),char(105),char(110),char(107),char(101),char(100),char(66),char(111),char(100),char(105),char(101),char(115),char(0),char(109),char(95),char(111), -char(118),char(101),char(114),char(114),char(105),char(100),char(101),char(78),char(117),char(109),char(83),char(111),char(108),char(118),char(101),char(114),char(73),char(116),char(101),char(114), -char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(98),char(114),char(101),char(97),char(107),char(105),char(110),char(103),char(73),char(109),char(112), -char(117),char(108),char(115),char(101),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(105),char(115),char(69),char(110), -char(97),char(98),char(108),char(101),char(100),char(0),char(109),char(95),char(116),char(121),char(112),char(101),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105), -char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(112),char(105),char(118),char(111),char(116),char(73),char(110),char(65),char(0),char(109),char(95), -char(112),char(105),char(118),char(111),char(116),char(73),char(110),char(66),char(0),char(109),char(95),char(114),char(98),char(65),char(70),char(114),char(97),char(109),char(101),char(0), -char(109),char(95),char(114),char(98),char(66),char(70),char(114),char(97),char(109),char(101),char(0),char(109),char(95),char(117),char(115),char(101),char(82),char(101),char(102),char(101), -char(114),char(101),char(110),char(99),char(101),char(70),char(114),char(97),char(109),char(101),char(65),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97), -char(114),char(79),char(110),char(108),char(121),char(0),char(109),char(95),char(101),char(110),char(97),char(98),char(108),char(101),char(65),char(110),char(103),char(117),char(108),char(97), -char(114),char(77),char(111),char(116),char(111),char(114),char(0),char(109),char(95),char(109),char(111),char(116),char(111),char(114),char(84),char(97),char(114),char(103),char(101),char(116), -char(86),char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(109),char(97),char(120),char(77),char(111),char(116),char(111),char(114),char(73), -char(109),char(112),char(117),char(108),char(115),char(101),char(0),char(109),char(95),char(108),char(111),char(119),char(101),char(114),char(76),char(105),char(109),char(105),char(116),char(0), -char(109),char(95),char(117),char(112),char(112),char(101),char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(108),char(105),char(109),char(105),char(116), -char(83),char(111),char(102),char(116),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(98),char(105),char(97),char(115),char(70),char(97),char(99),char(116),char(111), -char(114),char(0),char(109),char(95),char(114),char(101),char(108),char(97),char(120),char(97),char(116),char(105),char(111),char(110),char(70),char(97),char(99),char(116),char(111),char(114), -char(0),char(109),char(95),char(115),char(119),char(105),char(110),char(103),char(83),char(112),char(97),char(110),char(49),char(0),char(109),char(95),char(115),char(119),char(105),char(110), -char(103),char(83),char(112),char(97),char(110),char(50),char(0),char(109),char(95),char(116),char(119),char(105),char(115),char(116),char(83),char(112),char(97),char(110),char(0),char(109), -char(95),char(100),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(85),char(112),char(112), -char(101),char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(76),char(111),char(119),char(101), -char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(85),char(112),char(112),char(101), -char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(97),char(110),char(103),char(117),char(108),char(97),char(114),char(76),char(111),char(119),char(101), -char(114),char(76),char(105),char(109),char(105),char(116),char(0),char(109),char(95),char(117),char(115),char(101),char(76),char(105),char(110),char(101),char(97),char(114),char(82),char(101), -char(102),char(101),char(114),char(101),char(110),char(99),char(101),char(70),char(114),char(97),char(109),char(101),char(65),char(0),char(109),char(95),char(117),char(115),char(101),char(79), -char(102),char(102),char(115),char(101),char(116),char(70),char(111),char(114),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(70),char(114), -char(97),char(109),char(101),char(0),char(109),char(95),char(54),char(100),char(111),char(102),char(68),char(97),char(116),char(97),char(0),char(109),char(95),char(115),char(112),char(114), -char(105),char(110),char(103),char(69),char(110),char(97),char(98),char(108),char(101),char(100),char(91),char(54),char(93),char(0),char(109),char(95),char(101),char(113),char(117),char(105), -char(108),char(105),char(98),char(114),char(105),char(117),char(109),char(80),char(111),char(105),char(110),char(116),char(91),char(54),char(93),char(0),char(109),char(95),char(115),char(112), -char(114),char(105),char(110),char(103),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(91),char(54),char(93),char(0),char(109),char(95),char(115), -char(112),char(114),char(105),char(110),char(103),char(68),char(97),char(109),char(112),char(105),char(110),char(103),char(91),char(54),char(93),char(0),char(109),char(95),char(116),char(97), -char(117),char(0),char(109),char(95),char(116),char(105),char(109),char(101),char(83),char(116),char(101),char(112),char(0),char(109),char(95),char(109),char(97),char(120),char(69),char(114), -char(114),char(111),char(114),char(82),char(101),char(100),char(117),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(115),char(111),char(114),char(0),char(109), -char(95),char(101),char(114),char(112),char(0),char(109),char(95),char(101),char(114),char(112),char(50),char(0),char(109),char(95),char(103),char(108),char(111),char(98),char(97),char(108), -char(67),char(102),char(109),char(0),char(109),char(95),char(115),char(112),char(108),char(105),char(116),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(80),char(101), -char(110),char(101),char(116),char(114),char(97),char(116),char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109), -char(95),char(115),char(112),char(108),char(105),char(116),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(84),char(117),char(114),char(110),char(69),char(114),char(112), -char(0),char(109),char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(83),char(108),char(111),char(112),char(0),char(109),char(95),char(119),char(97),char(114),char(109), -char(115),char(116),char(97),char(114),char(116),char(105),char(110),char(103),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(109),char(97),char(120), -char(71),char(121),char(114),char(111),char(115),char(99),char(111),char(112),char(105),char(99),char(70),char(111),char(114),char(99),char(101),char(0),char(109),char(95),char(115),char(105), -char(110),char(103),char(108),char(101),char(65),char(120),char(105),char(115),char(82),char(111),char(108),char(108),char(105),char(110),char(103),char(70),char(114),char(105),char(99),char(116), -char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109),char(95),char(110),char(117),char(109),char(73),char(116), -char(101),char(114),char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(115),char(111),char(108),char(118),char(101),char(114),char(77),char(111),char(100), -char(101),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(105),char(110),char(103),char(67),char(111),char(110),char(116),char(97),char(99),char(116),char(82),char(101), -char(115),char(116),char(105),char(116),char(117),char(116),char(105),char(111),char(110),char(84),char(104),char(114),char(101),char(115),char(104),char(111),char(108),char(100),char(0),char(109), -char(95),char(109),char(105),char(110),char(105),char(109),char(117),char(109),char(83),char(111),char(108),char(118),char(101),char(114),char(66),char(97),char(116),char(99),char(104),char(83), -char(105),char(122),char(101),char(0),char(109),char(95),char(115),char(112),char(108),char(105),char(116),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(0),char(109), -char(95),char(108),char(105),char(110),char(101),char(97),char(114),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(97), -char(110),char(103),char(117),char(108),char(97),char(114),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(118),char(111), -char(108),char(117),char(109),char(101),char(83),char(116),char(105),char(102),char(102),char(110),char(101),char(115),char(115),char(0),char(42),char(109),char(95),char(109),char(97),char(116), -char(101),char(114),char(105),char(97),char(108),char(0),char(109),char(95),char(112),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(112), -char(114),char(101),char(118),char(105),char(111),char(117),char(115),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(118),char(101), -char(108),char(111),char(99),char(105),char(116),char(121),char(0),char(109),char(95),char(97),char(99),char(99),char(117),char(109),char(117),char(108),char(97),char(116),char(101),char(100), -char(70),char(111),char(114),char(99),char(101),char(0),char(109),char(95),char(110),char(111),char(114),char(109),char(97),char(108),char(0),char(109),char(95),char(97),char(114),char(101), -char(97),char(0),char(109),char(95),char(97),char(116),char(116),char(97),char(99),char(104),char(0),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100), -char(105),char(99),char(101),char(115),char(91),char(50),char(93),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(76),char(101),char(110),char(103),char(116),char(104), -char(0),char(109),char(95),char(98),char(98),char(101),char(110),char(100),char(105),char(110),char(103),char(0),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110), -char(100),char(105),char(99),char(101),char(115),char(91),char(51),char(93),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(65),char(114),char(101),char(97),char(0), -char(109),char(95),char(99),char(48),char(91),char(52),char(93),char(0),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100),char(105),char(99),char(101), -char(115),char(91),char(52),char(93),char(0),char(109),char(95),char(114),char(101),char(115),char(116),char(86),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95), -char(99),char(49),char(0),char(109),char(95),char(99),char(50),char(0),char(109),char(95),char(99),char(48),char(0),char(109),char(95),char(108),char(111),char(99),char(97),char(108), -char(70),char(114),char(97),char(109),char(101),char(0),char(42),char(109),char(95),char(114),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(0),char(109), -char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100),char(101),char(120),char(0),char(109),char(95),char(97),char(101),char(114),char(111),char(77),char(111),char(100), -char(101),char(108),char(0),char(109),char(95),char(98),char(97),char(117),char(109),char(103),char(97),char(114),char(116),char(101),char(0),char(109),char(95),char(100),char(114),char(97), -char(103),char(0),char(109),char(95),char(108),char(105),char(102),char(116),char(0),char(109),char(95),char(112),char(114),char(101),char(115),char(115),char(117),char(114),char(101),char(0), -char(109),char(95),char(118),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95),char(100),char(121),char(110),char(97),char(109),char(105),char(99),char(70),char(114), -char(105),char(99),char(116),char(105),char(111),char(110),char(0),char(109),char(95),char(112),char(111),char(115),char(101),char(77),char(97),char(116),char(99),char(104),char(0),char(109), -char(95),char(114),char(105),char(103),char(105),char(100),char(67),char(111),char(110),char(116),char(97),char(99),char(116),char(72),char(97),char(114),char(100),char(110),char(101),char(115), -char(115),char(0),char(109),char(95),char(107),char(105),char(110),char(101),char(116),char(105),char(99),char(67),char(111),char(110),char(116),char(97),char(99),char(116),char(72),char(97), -char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(67),char(111),char(110),char(116),char(97),char(99),char(116), -char(72),char(97),char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(97),char(110),char(99),char(104),char(111),char(114),char(72),char(97),char(114), -char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(82),char(105),char(103),char(105),char(100),char(67),char(108),char(117), -char(115),char(116),char(101),char(114),char(72),char(97),char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(75), -char(105),char(110),char(101),char(116),char(105),char(99),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(72),char(97),char(114),char(100),char(110),char(101),char(115), -char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(83),char(111),char(102),char(116),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(72), -char(97),char(114),char(100),char(110),char(101),char(115),char(115),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(82),char(105),char(103),char(105),char(100),char(67), -char(108),char(117),char(115),char(116),char(101),char(114),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(83),char(112),char(108),char(105),char(116),char(0),char(109), -char(95),char(115),char(111),char(102),char(116),char(75),char(105),char(110),char(101),char(116),char(105),char(99),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(73), -char(109),char(112),char(117),char(108),char(115),char(101),char(83),char(112),char(108),char(105),char(116),char(0),char(109),char(95),char(115),char(111),char(102),char(116),char(83),char(111), -char(102),char(116),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(83),char(112),char(108),char(105), -char(116),char(0),char(109),char(95),char(109),char(97),char(120),char(86),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95),char(116),char(105),char(109),char(101), -char(83),char(99),char(97),char(108),char(101),char(0),char(109),char(95),char(118),char(101),char(108),char(111),char(99),char(105),char(116),char(121),char(73),char(116),char(101),char(114), -char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(112),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(73),char(116),char(101), -char(114),char(97),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(100),char(114),char(105),char(102),char(116),char(73),char(116),char(101),char(114),char(97), -char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(99),char(108),char(117),char(115),char(116),char(101),char(114),char(73),char(116),char(101),char(114),char(97), -char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(114),char(111),char(116),char(0),char(109),char(95),char(115),char(99),char(97),char(108),char(101),char(0), -char(109),char(95),char(97),char(113),char(113),char(0),char(109),char(95),char(99),char(111),char(109),char(0),char(42),char(109),char(95),char(112),char(111),char(115),char(105),char(116), -char(105),char(111),char(110),char(115),char(0),char(42),char(109),char(95),char(119),char(101),char(105),char(103),char(104),char(116),char(115),char(0),char(109),char(95),char(110),char(117), -char(109),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(87),char(101),char(105),char(103), -char(116),char(115),char(0),char(109),char(95),char(98),char(118),char(111),char(108),char(117),char(109),char(101),char(0),char(109),char(95),char(98),char(102),char(114),char(97),char(109), -char(101),char(0),char(109),char(95),char(102),char(114),char(97),char(109),char(101),char(120),char(102),char(111),char(114),char(109),char(0),char(109),char(95),char(108),char(111),char(99), -char(105),char(105),char(0),char(109),char(95),char(105),char(110),char(118),char(119),char(105),char(0),char(109),char(95),char(118),char(105),char(109),char(112),char(117),char(108),char(115), -char(101),char(115),char(91),char(50),char(93),char(0),char(109),char(95),char(100),char(105),char(109),char(112),char(117),char(108),char(115),char(101),char(115),char(91),char(50),char(93), -char(0),char(109),char(95),char(108),char(118),char(0),char(109),char(95),char(97),char(118),char(0),char(42),char(109),char(95),char(102),char(114),char(97),char(109),char(101),char(114), -char(101),char(102),char(115),char(0),char(42),char(109),char(95),char(110),char(111),char(100),char(101),char(73),char(110),char(100),char(105),char(99),char(101),char(115),char(0),char(42), -char(109),char(95),char(109),char(97),char(115),char(115),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(70),char(114),char(97),char(109),char(101),char(82), -char(101),char(102),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(78),char(111),char(100),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109), -char(77),char(97),char(115),char(115),char(101),char(115),char(0),char(109),char(95),char(105),char(100),char(109),char(97),char(115),char(115),char(0),char(109),char(95),char(105),char(109), -char(97),char(115),char(115),char(0),char(109),char(95),char(110),char(118),char(105),char(109),char(112),char(117),char(108),char(115),char(101),char(115),char(0),char(109),char(95),char(110), -char(100),char(105),char(109),char(112),char(117),char(108),char(115),char(101),char(115),char(0),char(109),char(95),char(110),char(100),char(97),char(109),char(112),char(105),char(110),char(103), -char(0),char(109),char(95),char(108),char(100),char(97),char(109),char(112),char(105),char(110),char(103),char(0),char(109),char(95),char(97),char(100),char(97),char(109),char(112),char(105), -char(110),char(103),char(0),char(109),char(95),char(109),char(97),char(116),char(99),char(104),char(105),char(110),char(103),char(0),char(109),char(95),char(109),char(97),char(120),char(83), -char(101),char(108),char(102),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(73),char(109),char(112),char(117),char(108),char(115),char(101),char(0), -char(109),char(95),char(115),char(101),char(108),char(102),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(73),char(109),char(112),char(117),char(108), -char(115),char(101),char(70),char(97),char(99),char(116),char(111),char(114),char(0),char(109),char(95),char(99),char(111),char(110),char(116),char(97),char(105),char(110),char(115),char(65), -char(110),char(99),char(104),char(111),char(114),char(0),char(109),char(95),char(99),char(111),char(108),char(108),char(105),char(100),char(101),char(0),char(109),char(95),char(99),char(108), -char(117),char(115),char(116),char(101),char(114),char(73),char(110),char(100),char(101),char(120),char(0),char(42),char(109),char(95),char(98),char(111),char(100),char(121),char(65),char(0), -char(42),char(109),char(95),char(98),char(111),char(100),char(121),char(66),char(0),char(109),char(95),char(114),char(101),char(102),char(115),char(91),char(50),char(93),char(0),char(109), -char(95),char(99),char(102),char(109),char(0),char(109),char(95),char(115),char(112),char(108),char(105),char(116),char(0),char(109),char(95),char(100),char(101),char(108),char(101),char(116), -char(101),char(0),char(109),char(95),char(114),char(101),char(108),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(91),char(50),char(93),char(0),char(109), -char(95),char(98),char(111),char(100),char(121),char(65),char(116),char(121),char(112),char(101),char(0),char(109),char(95),char(98),char(111),char(100),char(121),char(66),char(116),char(121), -char(112),char(101),char(0),char(109),char(95),char(106),char(111),char(105),char(110),char(116),char(84),char(121),char(112),char(101),char(0),char(42),char(109),char(95),char(112),char(111), -char(115),char(101),char(0),char(42),char(42),char(109),char(95),char(109),char(97),char(116),char(101),char(114),char(105),char(97),char(108),char(115),char(0),char(42),char(109),char(95), -char(110),char(111),char(100),char(101),char(115),char(0),char(42),char(109),char(95),char(108),char(105),char(110),char(107),char(115),char(0),char(42),char(109),char(95),char(102),char(97), -char(99),char(101),char(115),char(0),char(42),char(109),char(95),char(116),char(101),char(116),char(114),char(97),char(104),char(101),char(100),char(114),char(97),char(0),char(42),char(109), -char(95),char(97),char(110),char(99),char(104),char(111),char(114),char(115),char(0),char(42),char(109),char(95),char(99),char(108),char(117),char(115),char(116),char(101),char(114),char(115), -char(0),char(42),char(109),char(95),char(106),char(111),char(105),char(110),char(116),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(77),char(97),char(116),char(101), -char(114),char(105),char(97),char(108),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(76),char(105),char(110),char(107),char(115),char(0),char(109),char(95),char(110), -char(117),char(109),char(70),char(97),char(99),char(101),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(84),char(101),char(116),char(114),char(97),char(104),char(101), -char(100),char(114),char(97),char(0),char(109),char(95),char(110),char(117),char(109),char(65),char(110),char(99),char(104),char(111),char(114),char(115),char(0),char(109),char(95),char(110), -char(117),char(109),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(115),char(0),char(109),char(95),char(110),char(117),char(109),char(74),char(111),char(105),char(110), -char(116),char(115),char(0),char(109),char(95),char(99),char(111),char(110),char(102),char(105),char(103),char(0),char(84),char(89),char(80),char(69),char(76),char(0),char(0),char(0), -char(99),char(104),char(97),char(114),char(0),char(117),char(99),char(104),char(97),char(114),char(0),char(115),char(104),char(111),char(114),char(116),char(0),char(117),char(115),char(104), -char(111),char(114),char(116),char(0),char(105),char(110),char(116),char(0),char(108),char(111),char(110),char(103),char(0),char(117),char(108),char(111),char(110),char(103),char(0),char(102), -char(108),char(111),char(97),char(116),char(0),char(100),char(111),char(117),char(98),char(108),char(101),char(0),char(118),char(111),char(105),char(100),char(0),char(80),char(111),char(105), -char(110),char(116),char(101),char(114),char(65),char(114),char(114),char(97),char(121),char(0),char(98),char(116),char(80),char(104),char(121),char(115),char(105),char(99),char(115),char(83), -char(121),char(115),char(116),char(101),char(109),char(0),char(76),char(105),char(115),char(116),char(66),char(97),char(115),char(101),char(0),char(98),char(116),char(86),char(101),char(99), -char(116),char(111),char(114),char(51),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(86),char(101),char(99),char(116), -char(111),char(114),char(51),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(77),char(97),char(116),char(114), -char(105),char(120),char(51),char(120),char(51),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(77),char(97),char(116), -char(114),char(105),char(120),char(51),char(120),char(51),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84), -char(114),char(97),char(110),char(115),char(102),char(111),char(114),char(109),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116), -char(84),char(114),char(97),char(110),char(115),char(102),char(111),char(114),char(109),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0), -char(98),char(116),char(66),char(118),char(104),char(83),char(117),char(98),char(116),char(114),char(101),char(101),char(73),char(110),char(102),char(111),char(68),char(97),char(116),char(97), -char(0),char(98),char(116),char(79),char(112),char(116),char(105),char(109),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(78),char(111),char(100),char(101),char(70), -char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(79),char(112),char(116),char(105),char(109),char(105),char(122),char(101),char(100), -char(66),char(118),char(104),char(78),char(111),char(100),char(101),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116), -char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(78),char(111),char(100),char(101),char(68),char(97),char(116),char(97), -char(0),char(98),char(116),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(70),char(108),char(111),char(97),char(116), -char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(81),char(117),char(97),char(110),char(116),char(105),char(122),char(101),char(100),char(66),char(118),char(104),char(68), -char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111), -char(110),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(83),char(116),char(97),char(116),char(105),char(99),char(80), -char(108),char(97),char(110),char(101),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(118), -char(101),char(120),char(73),char(110),char(116),char(101),char(114),char(110),char(97),char(108),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0), -char(98),char(116),char(80),char(111),char(115),char(105),char(116),char(105),char(111),char(110),char(65),char(110),char(100),char(82),char(97),char(100),char(105),char(117),char(115),char(0), -char(98),char(116),char(77),char(117),char(108),char(116),char(105),char(83),char(112),char(104),char(101),char(114),char(101),char(83),char(104),char(97),char(112),char(101),char(68),char(97), -char(116),char(97),char(0),char(98),char(116),char(73),char(110),char(116),char(73),char(110),char(100),char(101),char(120),char(68),char(97),char(116),char(97),char(0),char(98),char(116), -char(83),char(104),char(111),char(114),char(116),char(73),char(110),char(116),char(73),char(110),char(100),char(101),char(120),char(68),char(97),char(116),char(97),char(0),char(98),char(116), -char(83),char(104),char(111),char(114),char(116),char(73),char(110),char(116),char(73),char(110),char(100),char(101),char(120),char(84),char(114),char(105),char(112),char(108),char(101),char(116), -char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(104),char(97),char(114),char(73),char(110),char(100),char(101),char(120),char(84),char(114),char(105),char(112), -char(108),char(101),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(77),char(101),char(115),char(104),char(80),char(97),char(114),char(116),char(68),char(97), -char(116),char(97),char(0),char(98),char(116),char(83),char(116),char(114),char(105),char(100),char(105),char(110),char(103),char(77),char(101),char(115),char(104),char(73),char(110),char(116), -char(101),char(114),char(102),char(97),char(99),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84),char(114),char(105),char(97),char(110),char(103),char(108), -char(101),char(77),char(101),char(115),char(104),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84),char(114),char(105), -char(97),char(110),char(103),char(108),char(101),char(73),char(110),char(102),char(111),char(77),char(97),char(112),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(83), -char(99),char(97),char(108),char(101),char(100),char(84),char(114),char(105),char(97),char(110),char(103),char(108),char(101),char(77),char(101),char(115),char(104),char(83),char(104),char(97), -char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(109),char(112),char(111),char(117),char(110),char(100),char(83),char(104),char(97), -char(112),char(101),char(67),char(104),char(105),char(108),char(100),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(109),char(112),char(111),char(117), -char(110),char(100),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(121),char(108),char(105),char(110),char(100), -char(101),char(114),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(97),char(112),char(115),char(117),char(108), -char(101),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(84),char(114),char(105),char(97),char(110),char(103),char(108), -char(101),char(73),char(110),char(102),char(111),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(71),char(73),char(109),char(112),char(97),char(99),char(116),char(77), -char(101),char(115),char(104),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(118),char(101), -char(120),char(72),char(117),char(108),char(108),char(83),char(104),char(97),char(112),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(108), -char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99),char(116),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97), -char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(108),char(108),char(105),char(115),char(105),char(111),char(110),char(79),char(98),char(106),char(101),char(99),char(116), -char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(68),char(121),char(110),char(97),char(109),char(105),char(99),char(115), -char(87),char(111),char(114),char(108),char(100),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111), -char(110),char(116),char(97),char(99),char(116),char(83),char(111),char(108),char(118),char(101),char(114),char(73),char(110),char(102),char(111),char(68),char(111),char(117),char(98),char(108), -char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(68),char(121),char(110),char(97),char(109),char(105),char(99),char(115),char(87),char(111),char(114),char(108), -char(100),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(116),char(97),char(99),char(116), -char(83),char(111),char(108),char(118),char(101),char(114),char(73),char(110),char(102),char(111),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0), -char(98),char(116),char(82),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97), -char(0),char(98),char(116),char(82),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97), -char(116),char(97),char(0),char(98),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(73),char(110),char(102),char(111),char(49), -char(0),char(98),char(116),char(84),char(121),char(112),char(101),char(100),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(97), -char(116),char(97),char(0),char(98),char(116),char(82),char(105),char(103),char(105),char(100),char(66),char(111),char(100),char(121),char(68),char(97),char(116),char(97),char(0),char(98), -char(116),char(80),char(111),char(105),char(110),char(116),char(50),char(80),char(111),char(105),char(110),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105), -char(110),char(116),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(80),char(111),char(105),char(110),char(116),char(50), -char(80),char(111),char(105),char(110),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(111),char(117),char(98),char(108), -char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(72),char(105),char(110),char(103),char(101),char(67),char(111),char(110),char(115),char(116),char(114),char(97), -char(105),char(110),char(116),char(68),char(111),char(117),char(98),char(108),char(101),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(72),char(105),char(110),char(103), -char(101),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97), -char(0),char(98),char(116),char(67),char(111),char(110),char(101),char(84),char(119),char(105),char(115),char(116),char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105), -char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(71),char(101),char(110),char(101),char(114),char(105),char(99),char(54),char(68),char(111),char(102), -char(67),char(111),char(110),char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(71),char(101),char(110), -char(101),char(114),char(105),char(99),char(54),char(68),char(111),char(102),char(83),char(112),char(114),char(105),char(110),char(103),char(67),char(111),char(110),char(115),char(116),char(114), -char(97),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116),char(83),char(108),char(105),char(100),char(101),char(114),char(67),char(111),char(110), -char(115),char(116),char(114),char(97),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121), -char(77),char(97),char(116),char(101),char(114),char(105),char(97),char(108),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100), -char(121),char(78),char(111),char(100),char(101),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(76),char(105), -char(110),char(107),char(68),char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(70),char(97),char(99),char(101),char(68), -char(97),char(116),char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(84),char(101),char(116),char(114),char(97),char(68),char(97),char(116), -char(97),char(0),char(83),char(111),char(102),char(116),char(82),char(105),char(103),char(105),char(100),char(65),char(110),char(99),char(104),char(111),char(114),char(68),char(97),char(116), -char(97),char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(67),char(111),char(110),char(102),char(105),char(103),char(68),char(97),char(116),char(97), -char(0),char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(80),char(111),char(115),char(101),char(68),char(97),char(116),char(97),char(0),char(83),char(111), -char(102),char(116),char(66),char(111),char(100),char(121),char(67),char(108),char(117),char(115),char(116),char(101),char(114),char(68),char(97),char(116),char(97),char(0),char(98),char(116), -char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(74),char(111),char(105),char(110),char(116),char(68),char(97),char(116),char(97),char(0),char(98),char(116), -char(83),char(111),char(102),char(116),char(66),char(111),char(100),char(121),char(70),char(108),char(111),char(97),char(116),char(68),char(97),char(116),char(97),char(0),char(0),char(0), -char(84),char(76),char(69),char(78),char(1),char(0),char(1),char(0),char(2),char(0),char(2),char(0),char(4),char(0),char(4),char(0),char(4),char(0),char(4),char(0), -char(8),char(0),char(0),char(0),char(16),char(0),char(48),char(0),char(16),char(0),char(16),char(0),char(32),char(0),char(48),char(0),char(96),char(0),char(64),char(0), -char(-128),char(0),char(20),char(0),char(48),char(0),char(80),char(0),char(16),char(0),char(96),char(0),char(-112),char(0),char(16),char(0),char(56),char(0),char(56),char(0), -char(20),char(0),char(72),char(0),char(4),char(0),char(4),char(0),char(8),char(0),char(4),char(0),char(56),char(0),char(32),char(0),char(80),char(0),char(72),char(0), -char(96),char(0),char(80),char(0),char(32),char(0),char(64),char(0),char(64),char(0),char(16),char(0),char(72),char(0),char(80),char(0),char(-32),char(1),char(16),char(1), -char(-72),char(0),char(-104),char(0),char(104),char(0),char(88),char(0),char(-8),char(1),char(-80),char(3),char(8),char(0),char(64),char(0),char(0),char(0),char(96),char(0), -char(-128),char(0),char(104),char(1),char(-24),char(0),char(-32),char(0),char(8),char(1),char(104),char(1),char(-40),char(0),char(16),char(0),char(104),char(0),char(24),char(0), -char(40),char(0),char(104),char(0),char(96),char(0),char(104),char(0),char(-56),char(0),char(104),char(1),char(112),char(0),char(-32),char(1),char(83),char(84),char(82),char(67), -char(65),char(0),char(0),char(0),char(10),char(0),char(3),char(0),char(4),char(0),char(0),char(0),char(4),char(0),char(1),char(0),char(9),char(0),char(2),char(0), -char(11),char(0),char(3),char(0),char(10),char(0),char(3),char(0),char(10),char(0),char(4),char(0),char(10),char(0),char(5),char(0),char(12),char(0),char(2),char(0), -char(9),char(0),char(6),char(0),char(9),char(0),char(7),char(0),char(13),char(0),char(1),char(0),char(7),char(0),char(8),char(0),char(14),char(0),char(1),char(0), -char(8),char(0),char(8),char(0),char(15),char(0),char(1),char(0),char(13),char(0),char(9),char(0),char(16),char(0),char(1),char(0),char(14),char(0),char(9),char(0), -char(17),char(0),char(2),char(0),char(15),char(0),char(10),char(0),char(13),char(0),char(11),char(0),char(18),char(0),char(2),char(0),char(16),char(0),char(10),char(0), -char(14),char(0),char(11),char(0),char(19),char(0),char(4),char(0),char(4),char(0),char(12),char(0),char(4),char(0),char(13),char(0),char(2),char(0),char(14),char(0), -char(2),char(0),char(15),char(0),char(20),char(0),char(6),char(0),char(13),char(0),char(16),char(0),char(13),char(0),char(17),char(0),char(4),char(0),char(18),char(0), -char(4),char(0),char(19),char(0),char(4),char(0),char(20),char(0),char(0),char(0),char(21),char(0),char(21),char(0),char(6),char(0),char(14),char(0),char(16),char(0), -char(14),char(0),char(17),char(0),char(4),char(0),char(18),char(0),char(4),char(0),char(19),char(0),char(4),char(0),char(20),char(0),char(0),char(0),char(21),char(0), -char(22),char(0),char(3),char(0),char(2),char(0),char(14),char(0),char(2),char(0),char(15),char(0),char(4),char(0),char(22),char(0),char(23),char(0),char(12),char(0), -char(13),char(0),char(23),char(0),char(13),char(0),char(24),char(0),char(13),char(0),char(25),char(0),char(4),char(0),char(26),char(0),char(4),char(0),char(27),char(0), -char(4),char(0),char(28),char(0),char(4),char(0),char(29),char(0),char(20),char(0),char(30),char(0),char(22),char(0),char(31),char(0),char(19),char(0),char(32),char(0), -char(4),char(0),char(33),char(0),char(4),char(0),char(34),char(0),char(24),char(0),char(12),char(0),char(14),char(0),char(23),char(0),char(14),char(0),char(24),char(0), -char(14),char(0),char(25),char(0),char(4),char(0),char(26),char(0),char(4),char(0),char(27),char(0),char(4),char(0),char(28),char(0),char(4),char(0),char(29),char(0), -char(21),char(0),char(30),char(0),char(22),char(0),char(31),char(0),char(4),char(0),char(33),char(0),char(4),char(0),char(34),char(0),char(19),char(0),char(32),char(0), -char(25),char(0),char(3),char(0),char(0),char(0),char(35),char(0),char(4),char(0),char(36),char(0),char(0),char(0),char(37),char(0),char(26),char(0),char(5),char(0), -char(25),char(0),char(38),char(0),char(13),char(0),char(39),char(0),char(13),char(0),char(40),char(0),char(7),char(0),char(41),char(0),char(0),char(0),char(21),char(0), -char(27),char(0),char(5),char(0),char(25),char(0),char(38),char(0),char(13),char(0),char(39),char(0),char(13),char(0),char(42),char(0),char(7),char(0),char(43),char(0), -char(4),char(0),char(44),char(0),char(28),char(0),char(2),char(0),char(13),char(0),char(45),char(0),char(7),char(0),char(46),char(0),char(29),char(0),char(4),char(0), -char(27),char(0),char(47),char(0),char(28),char(0),char(48),char(0),char(4),char(0),char(49),char(0),char(0),char(0),char(37),char(0),char(30),char(0),char(1),char(0), -char(4),char(0),char(50),char(0),char(31),char(0),char(2),char(0),char(2),char(0),char(50),char(0),char(0),char(0),char(51),char(0),char(32),char(0),char(2),char(0), -char(2),char(0),char(52),char(0),char(0),char(0),char(51),char(0),char(33),char(0),char(2),char(0),char(0),char(0),char(52),char(0),char(0),char(0),char(53),char(0), -char(34),char(0),char(8),char(0),char(13),char(0),char(54),char(0),char(14),char(0),char(55),char(0),char(30),char(0),char(56),char(0),char(32),char(0),char(57),char(0), -char(33),char(0),char(58),char(0),char(31),char(0),char(59),char(0),char(4),char(0),char(60),char(0),char(4),char(0),char(61),char(0),char(35),char(0),char(4),char(0), -char(34),char(0),char(62),char(0),char(13),char(0),char(63),char(0),char(4),char(0),char(64),char(0),char(0),char(0),char(37),char(0),char(36),char(0),char(7),char(0), -char(25),char(0),char(38),char(0),char(35),char(0),char(65),char(0),char(23),char(0),char(66),char(0),char(24),char(0),char(67),char(0),char(37),char(0),char(68),char(0), -char(7),char(0),char(43),char(0),char(0),char(0),char(69),char(0),char(38),char(0),char(2),char(0),char(36),char(0),char(70),char(0),char(13),char(0),char(39),char(0), -char(39),char(0),char(4),char(0),char(17),char(0),char(71),char(0),char(25),char(0),char(72),char(0),char(4),char(0),char(73),char(0),char(7),char(0),char(74),char(0), -char(40),char(0),char(4),char(0),char(25),char(0),char(38),char(0),char(39),char(0),char(75),char(0),char(4),char(0),char(76),char(0),char(7),char(0),char(43),char(0), -char(41),char(0),char(3),char(0),char(27),char(0),char(47),char(0),char(4),char(0),char(77),char(0),char(0),char(0),char(37),char(0),char(42),char(0),char(3),char(0), -char(27),char(0),char(47),char(0),char(4),char(0),char(77),char(0),char(0),char(0),char(37),char(0),char(43),char(0),char(4),char(0),char(4),char(0),char(78),char(0), -char(7),char(0),char(79),char(0),char(7),char(0),char(80),char(0),char(7),char(0),char(81),char(0),char(37),char(0),char(14),char(0),char(4),char(0),char(82),char(0), -char(4),char(0),char(83),char(0),char(43),char(0),char(84),char(0),char(4),char(0),char(85),char(0),char(7),char(0),char(86),char(0),char(7),char(0),char(87),char(0), -char(7),char(0),char(88),char(0),char(7),char(0),char(89),char(0),char(7),char(0),char(90),char(0),char(4),char(0),char(91),char(0),char(4),char(0),char(92),char(0), -char(4),char(0),char(93),char(0),char(4),char(0),char(94),char(0),char(0),char(0),char(37),char(0),char(44),char(0),char(5),char(0),char(25),char(0),char(38),char(0), -char(35),char(0),char(65),char(0),char(13),char(0),char(39),char(0),char(7),char(0),char(43),char(0),char(4),char(0),char(95),char(0),char(45),char(0),char(5),char(0), -char(27),char(0),char(47),char(0),char(13),char(0),char(96),char(0),char(14),char(0),char(97),char(0),char(4),char(0),char(98),char(0),char(0),char(0),char(99),char(0), -char(46),char(0),char(25),char(0),char(9),char(0),char(100),char(0),char(9),char(0),char(101),char(0),char(25),char(0),char(102),char(0),char(0),char(0),char(35),char(0), -char(18),char(0),char(103),char(0),char(18),char(0),char(104),char(0),char(14),char(0),char(105),char(0),char(14),char(0),char(106),char(0),char(14),char(0),char(107),char(0), -char(8),char(0),char(108),char(0),char(8),char(0),char(109),char(0),char(8),char(0),char(110),char(0),char(8),char(0),char(111),char(0),char(8),char(0),char(112),char(0), -char(8),char(0),char(113),char(0),char(8),char(0),char(114),char(0),char(8),char(0),char(115),char(0),char(4),char(0),char(116),char(0),char(4),char(0),char(117),char(0), -char(4),char(0),char(118),char(0),char(4),char(0),char(119),char(0),char(4),char(0),char(120),char(0),char(4),char(0),char(121),char(0),char(4),char(0),char(122),char(0), -char(0),char(0),char(37),char(0),char(47),char(0),char(25),char(0),char(9),char(0),char(100),char(0),char(9),char(0),char(101),char(0),char(25),char(0),char(102),char(0), -char(0),char(0),char(35),char(0),char(17),char(0),char(103),char(0),char(17),char(0),char(104),char(0),char(13),char(0),char(105),char(0),char(13),char(0),char(106),char(0), -char(13),char(0),char(107),char(0),char(7),char(0),char(108),char(0),char(7),char(0),char(109),char(0),char(7),char(0),char(110),char(0),char(7),char(0),char(111),char(0), -char(7),char(0),char(112),char(0),char(7),char(0),char(113),char(0),char(7),char(0),char(114),char(0),char(7),char(0),char(115),char(0),char(4),char(0),char(116),char(0), -char(4),char(0),char(117),char(0),char(4),char(0),char(118),char(0),char(4),char(0),char(119),char(0),char(4),char(0),char(120),char(0),char(4),char(0),char(121),char(0), -char(4),char(0),char(122),char(0),char(0),char(0),char(37),char(0),char(48),char(0),char(2),char(0),char(49),char(0),char(123),char(0),char(14),char(0),char(124),char(0), -char(50),char(0),char(2),char(0),char(51),char(0),char(123),char(0),char(13),char(0),char(124),char(0),char(52),char(0),char(21),char(0),char(47),char(0),char(125),char(0), -char(15),char(0),char(126),char(0),char(13),char(0),char(127),char(0),char(13),char(0),char(-128),char(0),char(13),char(0),char(-127),char(0),char(13),char(0),char(-126),char(0), -char(13),char(0),char(124),char(0),char(13),char(0),char(-125),char(0),char(13),char(0),char(-124),char(0),char(13),char(0),char(-123),char(0),char(13),char(0),char(-122),char(0), -char(7),char(0),char(-121),char(0),char(7),char(0),char(-120),char(0),char(7),char(0),char(-119),char(0),char(7),char(0),char(-118),char(0),char(7),char(0),char(-117),char(0), -char(7),char(0),char(-116),char(0),char(7),char(0),char(-115),char(0),char(7),char(0),char(-114),char(0),char(7),char(0),char(-113),char(0),char(4),char(0),char(-112),char(0), -char(53),char(0),char(22),char(0),char(46),char(0),char(125),char(0),char(16),char(0),char(126),char(0),char(14),char(0),char(127),char(0),char(14),char(0),char(-128),char(0), -char(14),char(0),char(-127),char(0),char(14),char(0),char(-126),char(0),char(14),char(0),char(124),char(0),char(14),char(0),char(-125),char(0),char(14),char(0),char(-124),char(0), -char(14),char(0),char(-123),char(0),char(14),char(0),char(-122),char(0),char(8),char(0),char(-121),char(0),char(8),char(0),char(-120),char(0),char(8),char(0),char(-119),char(0), -char(8),char(0),char(-118),char(0),char(8),char(0),char(-117),char(0),char(8),char(0),char(-116),char(0),char(8),char(0),char(-115),char(0),char(8),char(0),char(-114),char(0), -char(8),char(0),char(-113),char(0),char(4),char(0),char(-112),char(0),char(0),char(0),char(37),char(0),char(54),char(0),char(2),char(0),char(4),char(0),char(-111),char(0), -char(4),char(0),char(-110),char(0),char(55),char(0),char(13),char(0),char(56),char(0),char(-109),char(0),char(56),char(0),char(-108),char(0),char(0),char(0),char(35),char(0), -char(4),char(0),char(-107),char(0),char(4),char(0),char(-106),char(0),char(4),char(0),char(-105),char(0),char(4),char(0),char(-104),char(0),char(7),char(0),char(-103),char(0), -char(7),char(0),char(-102),char(0),char(4),char(0),char(-101),char(0),char(4),char(0),char(-100),char(0),char(7),char(0),char(-99),char(0),char(4),char(0),char(-98),char(0), -char(57),char(0),char(3),char(0),char(55),char(0),char(-97),char(0),char(13),char(0),char(-96),char(0),char(13),char(0),char(-95),char(0),char(58),char(0),char(3),char(0), -char(55),char(0),char(-97),char(0),char(14),char(0),char(-96),char(0),char(14),char(0),char(-95),char(0),char(59),char(0),char(13),char(0),char(55),char(0),char(-97),char(0), -char(18),char(0),char(-94),char(0),char(18),char(0),char(-93),char(0),char(4),char(0),char(-92),char(0),char(4),char(0),char(-91),char(0),char(4),char(0),char(-90),char(0), -char(7),char(0),char(-89),char(0),char(7),char(0),char(-88),char(0),char(7),char(0),char(-87),char(0),char(7),char(0),char(-86),char(0),char(7),char(0),char(-85),char(0), -char(7),char(0),char(-84),char(0),char(7),char(0),char(-83),char(0),char(60),char(0),char(13),char(0),char(55),char(0),char(-97),char(0),char(17),char(0),char(-94),char(0), -char(17),char(0),char(-93),char(0),char(4),char(0),char(-92),char(0),char(4),char(0),char(-91),char(0),char(4),char(0),char(-90),char(0),char(7),char(0),char(-89),char(0), -char(7),char(0),char(-88),char(0),char(7),char(0),char(-87),char(0),char(7),char(0),char(-86),char(0),char(7),char(0),char(-85),char(0),char(7),char(0),char(-84),char(0), -char(7),char(0),char(-83),char(0),char(61),char(0),char(11),char(0),char(55),char(0),char(-97),char(0),char(17),char(0),char(-94),char(0),char(17),char(0),char(-93),char(0), -char(7),char(0),char(-82),char(0),char(7),char(0),char(-81),char(0),char(7),char(0),char(-80),char(0),char(7),char(0),char(-85),char(0),char(7),char(0),char(-84),char(0), -char(7),char(0),char(-83),char(0),char(7),char(0),char(-79),char(0),char(0),char(0),char(21),char(0),char(62),char(0),char(9),char(0),char(55),char(0),char(-97),char(0), -char(17),char(0),char(-94),char(0),char(17),char(0),char(-93),char(0),char(13),char(0),char(-78),char(0),char(13),char(0),char(-77),char(0),char(13),char(0),char(-76),char(0), -char(13),char(0),char(-75),char(0),char(4),char(0),char(-74),char(0),char(4),char(0),char(-73),char(0),char(63),char(0),char(5),char(0),char(62),char(0),char(-72),char(0), -char(4),char(0),char(-71),char(0),char(7),char(0),char(-70),char(0),char(7),char(0),char(-69),char(0),char(7),char(0),char(-68),char(0),char(64),char(0),char(9),char(0), -char(55),char(0),char(-97),char(0),char(17),char(0),char(-94),char(0),char(17),char(0),char(-93),char(0),char(7),char(0),char(-78),char(0),char(7),char(0),char(-77),char(0), -char(7),char(0),char(-76),char(0),char(7),char(0),char(-75),char(0),char(4),char(0),char(-74),char(0),char(4),char(0),char(-73),char(0),char(49),char(0),char(22),char(0), -char(8),char(0),char(-67),char(0),char(8),char(0),char(-79),char(0),char(8),char(0),char(110),char(0),char(8),char(0),char(-66),char(0),char(8),char(0),char(112),char(0), -char(8),char(0),char(-65),char(0),char(8),char(0),char(-64),char(0),char(8),char(0),char(-63),char(0),char(8),char(0),char(-62),char(0),char(8),char(0),char(-61),char(0), -char(8),char(0),char(-60),char(0),char(8),char(0),char(-59),char(0),char(8),char(0),char(-58),char(0),char(8),char(0),char(-57),char(0),char(8),char(0),char(-56),char(0), -char(8),char(0),char(-55),char(0),char(4),char(0),char(-54),char(0),char(4),char(0),char(-53),char(0),char(4),char(0),char(-52),char(0),char(4),char(0),char(-51),char(0), -char(4),char(0),char(-50),char(0),char(0),char(0),char(37),char(0),char(51),char(0),char(22),char(0),char(7),char(0),char(-67),char(0),char(7),char(0),char(-79),char(0), -char(7),char(0),char(110),char(0),char(7),char(0),char(-66),char(0),char(7),char(0),char(112),char(0),char(7),char(0),char(-65),char(0),char(7),char(0),char(-64),char(0), -char(7),char(0),char(-63),char(0),char(7),char(0),char(-62),char(0),char(7),char(0),char(-61),char(0),char(7),char(0),char(-60),char(0),char(7),char(0),char(-59),char(0), -char(7),char(0),char(-58),char(0),char(7),char(0),char(-57),char(0),char(7),char(0),char(-56),char(0),char(7),char(0),char(-55),char(0),char(4),char(0),char(-54),char(0), -char(4),char(0),char(-53),char(0),char(4),char(0),char(-52),char(0),char(4),char(0),char(-51),char(0),char(4),char(0),char(-50),char(0),char(0),char(0),char(37),char(0), -char(65),char(0),char(4),char(0),char(7),char(0),char(-49),char(0),char(7),char(0),char(-48),char(0),char(7),char(0),char(-47),char(0),char(4),char(0),char(78),char(0), -char(66),char(0),char(10),char(0),char(65),char(0),char(-46),char(0),char(13),char(0),char(-45),char(0),char(13),char(0),char(-44),char(0),char(13),char(0),char(-43),char(0), -char(13),char(0),char(-42),char(0),char(13),char(0),char(-41),char(0),char(7),char(0),char(-121),char(0),char(7),char(0),char(-40),char(0),char(4),char(0),char(-39),char(0), -char(4),char(0),char(53),char(0),char(67),char(0),char(4),char(0),char(65),char(0),char(-46),char(0),char(4),char(0),char(-38),char(0),char(7),char(0),char(-37),char(0), -char(4),char(0),char(-36),char(0),char(68),char(0),char(4),char(0),char(13),char(0),char(-41),char(0),char(65),char(0),char(-46),char(0),char(4),char(0),char(-35),char(0), -char(7),char(0),char(-34),char(0),char(69),char(0),char(7),char(0),char(13),char(0),char(-33),char(0),char(65),char(0),char(-46),char(0),char(4),char(0),char(-32),char(0), -char(7),char(0),char(-31),char(0),char(7),char(0),char(-30),char(0),char(7),char(0),char(-29),char(0),char(4),char(0),char(53),char(0),char(70),char(0),char(6),char(0), -char(15),char(0),char(-28),char(0),char(13),char(0),char(-30),char(0),char(13),char(0),char(-27),char(0),char(56),char(0),char(-26),char(0),char(4),char(0),char(-25),char(0), -char(7),char(0),char(-29),char(0),char(71),char(0),char(26),char(0),char(4),char(0),char(-24),char(0),char(7),char(0),char(-23),char(0),char(7),char(0),char(-79),char(0), -char(7),char(0),char(-22),char(0),char(7),char(0),char(-21),char(0),char(7),char(0),char(-20),char(0),char(7),char(0),char(-19),char(0),char(7),char(0),char(-18),char(0), -char(7),char(0),char(-17),char(0),char(7),char(0),char(-16),char(0),char(7),char(0),char(-15),char(0),char(7),char(0),char(-14),char(0),char(7),char(0),char(-13),char(0), -char(7),char(0),char(-12),char(0),char(7),char(0),char(-11),char(0),char(7),char(0),char(-10),char(0),char(7),char(0),char(-9),char(0),char(7),char(0),char(-8),char(0), -char(7),char(0),char(-7),char(0),char(7),char(0),char(-6),char(0),char(7),char(0),char(-5),char(0),char(4),char(0),char(-4),char(0),char(4),char(0),char(-3),char(0), -char(4),char(0),char(-2),char(0),char(4),char(0),char(-1),char(0),char(4),char(0),char(117),char(0),char(72),char(0),char(12),char(0),char(15),char(0),char(0),char(1), -char(15),char(0),char(1),char(1),char(15),char(0),char(2),char(1),char(13),char(0),char(3),char(1),char(13),char(0),char(4),char(1),char(7),char(0),char(5),char(1), -char(4),char(0),char(6),char(1),char(4),char(0),char(7),char(1),char(4),char(0),char(8),char(1),char(4),char(0),char(9),char(1),char(7),char(0),char(-31),char(0), -char(4),char(0),char(53),char(0),char(73),char(0),char(27),char(0),char(17),char(0),char(10),char(1),char(15),char(0),char(11),char(1),char(15),char(0),char(12),char(1), -char(13),char(0),char(3),char(1),char(13),char(0),char(13),char(1),char(13),char(0),char(14),char(1),char(13),char(0),char(15),char(1),char(13),char(0),char(16),char(1), -char(13),char(0),char(17),char(1),char(4),char(0),char(18),char(1),char(7),char(0),char(19),char(1),char(4),char(0),char(20),char(1),char(4),char(0),char(21),char(1), -char(4),char(0),char(22),char(1),char(7),char(0),char(23),char(1),char(7),char(0),char(24),char(1),char(4),char(0),char(25),char(1),char(4),char(0),char(26),char(1), -char(7),char(0),char(27),char(1),char(7),char(0),char(28),char(1),char(7),char(0),char(29),char(1),char(7),char(0),char(30),char(1),char(7),char(0),char(31),char(1), -char(7),char(0),char(32),char(1),char(4),char(0),char(33),char(1),char(4),char(0),char(34),char(1),char(4),char(0),char(35),char(1),char(74),char(0),char(12),char(0), -char(9),char(0),char(36),char(1),char(9),char(0),char(37),char(1),char(13),char(0),char(38),char(1),char(7),char(0),char(39),char(1),char(7),char(0),char(-63),char(0), -char(7),char(0),char(40),char(1),char(4),char(0),char(41),char(1),char(13),char(0),char(42),char(1),char(4),char(0),char(43),char(1),char(4),char(0),char(44),char(1), -char(4),char(0),char(45),char(1),char(4),char(0),char(53),char(0),char(75),char(0),char(19),char(0),char(47),char(0),char(125),char(0),char(72),char(0),char(46),char(1), -char(65),char(0),char(47),char(1),char(66),char(0),char(48),char(1),char(67),char(0),char(49),char(1),char(68),char(0),char(50),char(1),char(69),char(0),char(51),char(1), -char(70),char(0),char(52),char(1),char(73),char(0),char(53),char(1),char(74),char(0),char(54),char(1),char(4),char(0),char(55),char(1),char(4),char(0),char(21),char(1), -char(4),char(0),char(56),char(1),char(4),char(0),char(57),char(1),char(4),char(0),char(58),char(1),char(4),char(0),char(59),char(1),char(4),char(0),char(60),char(1), -char(4),char(0),char(61),char(1),char(71),char(0),char(62),char(1),}; -int b3s_bulletDNAlen64= sizeof(b3s_bulletDNAstr64); +char b3s_bulletDNAstr[] = { + char(83), + char(68), + char(78), + char(65), + char(78), + char(65), + char(77), + char(69), + char(63), + char(1), + char(0), + char(0), + char(109), + char(95), + char(115), + char(105), + char(122), + char(101), + char(0), + char(109), + char(95), + char(99), + char(97), + char(112), + char(97), + char(99), + char(105), + char(116), + char(121), + char(0), + char(42), + char(109), + char(95), + char(100), + char(97), + char(116), + char(97), + char(0), + char(109), + char(95), + char(99), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(83), + char(104), + char(97), + char(112), + char(101), + char(115), + char(0), + char(109), + char(95), + char(99), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(79), + char(98), + char(106), + char(101), + char(99), + char(116), + char(115), + char(0), + char(109), + char(95), + char(99), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(115), + char(0), + char(42), + char(102), + char(105), + char(114), + char(115), + char(116), + char(0), + char(42), + char(108), + char(97), + char(115), + char(116), + char(0), + char(109), + char(95), + char(102), + char(108), + char(111), + char(97), + char(116), + char(115), + char(91), + char(52), + char(93), + char(0), + char(109), + char(95), + char(101), + char(108), + char(91), + char(51), + char(93), + char(0), + char(109), + char(95), + char(98), + char(97), + char(115), + char(105), + char(115), + char(0), + char(109), + char(95), + char(111), + char(114), + char(105), + char(103), + char(105), + char(110), + char(0), + char(109), + char(95), + char(114), + char(111), + char(111), + char(116), + char(78), + char(111), + char(100), + char(101), + char(73), + char(110), + char(100), + char(101), + char(120), + char(0), + char(109), + char(95), + char(115), + char(117), + char(98), + char(116), + char(114), + char(101), + char(101), + char(83), + char(105), + char(122), + char(101), + char(0), + char(109), + char(95), + char(113), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(101), + char(100), + char(65), + char(97), + char(98), + char(98), + char(77), + char(105), + char(110), + char(91), + char(51), + char(93), + char(0), + char(109), + char(95), + char(113), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(101), + char(100), + char(65), + char(97), + char(98), + char(98), + char(77), + char(97), + char(120), + char(91), + char(51), + char(93), + char(0), + char(109), + char(95), + char(97), + char(97), + char(98), + char(98), + char(77), + char(105), + char(110), + char(79), + char(114), + char(103), + char(0), + char(109), + char(95), + char(97), + char(97), + char(98), + char(98), + char(77), + char(97), + char(120), + char(79), + char(114), + char(103), + char(0), + char(109), + char(95), + char(101), + char(115), + char(99), + char(97), + char(112), + char(101), + char(73), + char(110), + char(100), + char(101), + char(120), + char(0), + char(109), + char(95), + char(115), + char(117), + char(98), + char(80), + char(97), + char(114), + char(116), + char(0), + char(109), + char(95), + char(116), + char(114), + char(105), + char(97), + char(110), + char(103), + char(108), + char(101), + char(73), + char(110), + char(100), + char(101), + char(120), + char(0), + char(109), + char(95), + char(112), + char(97), + char(100), + char(91), + char(52), + char(93), + char(0), + char(109), + char(95), + char(101), + char(115), + char(99), + char(97), + char(112), + char(101), + char(73), + char(110), + char(100), + char(101), + char(120), + char(79), + char(114), + char(84), + char(114), + char(105), + char(97), + char(110), + char(103), + char(108), + char(101), + char(73), + char(110), + char(100), + char(101), + char(120), + char(0), + char(109), + char(95), + char(98), + char(118), + char(104), + char(65), + char(97), + char(98), + char(98), + char(77), + char(105), + char(110), + char(0), + char(109), + char(95), + char(98), + char(118), + char(104), + char(65), + char(97), + char(98), + char(98), + char(77), + char(97), + char(120), + char(0), + char(109), + char(95), + char(98), + char(118), + char(104), + char(81), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(97), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(99), + char(117), + char(114), + char(78), + char(111), + char(100), + char(101), + char(73), + char(110), + char(100), + char(101), + char(120), + char(0), + char(109), + char(95), + char(117), + char(115), + char(101), + char(81), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(97), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(67), + char(111), + char(110), + char(116), + char(105), + char(103), + char(117), + char(111), + char(117), + char(115), + char(76), + char(101), + char(97), + char(102), + char(78), + char(111), + char(100), + char(101), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(81), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(101), + char(100), + char(67), + char(111), + char(110), + char(116), + char(105), + char(103), + char(117), + char(111), + char(117), + char(115), + char(78), + char(111), + char(100), + char(101), + char(115), + char(0), + char(42), + char(109), + char(95), + char(99), + char(111), + char(110), + char(116), + char(105), + char(103), + char(117), + char(111), + char(117), + char(115), + char(78), + char(111), + char(100), + char(101), + char(115), + char(80), + char(116), + char(114), + char(0), + char(42), + char(109), + char(95), + char(113), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(101), + char(100), + char(67), + char(111), + char(110), + char(116), + char(105), + char(103), + char(117), + char(111), + char(117), + char(115), + char(78), + char(111), + char(100), + char(101), + char(115), + char(80), + char(116), + char(114), + char(0), + char(42), + char(109), + char(95), + char(115), + char(117), + char(98), + char(84), + char(114), + char(101), + char(101), + char(73), + char(110), + char(102), + char(111), + char(80), + char(116), + char(114), + char(0), + char(109), + char(95), + char(116), + char(114), + char(97), + char(118), + char(101), + char(114), + char(115), + char(97), + char(108), + char(77), + char(111), + char(100), + char(101), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(83), + char(117), + char(98), + char(116), + char(114), + char(101), + char(101), + char(72), + char(101), + char(97), + char(100), + char(101), + char(114), + char(115), + char(0), + char(42), + char(109), + char(95), + char(110), + char(97), + char(109), + char(101), + char(0), + char(109), + char(95), + char(115), + char(104), + char(97), + char(112), + char(101), + char(84), + char(121), + char(112), + char(101), + char(0), + char(109), + char(95), + char(112), + char(97), + char(100), + char(100), + char(105), + char(110), + char(103), + char(91), + char(52), + char(93), + char(0), + char(109), + char(95), + char(99), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(109), + char(95), + char(108), + char(111), + char(99), + char(97), + char(108), + char(83), + char(99), + char(97), + char(108), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(112), + char(108), + char(97), + char(110), + char(101), + char(78), + char(111), + char(114), + char(109), + char(97), + char(108), + char(0), + char(109), + char(95), + char(112), + char(108), + char(97), + char(110), + char(101), + char(67), + char(111), + char(110), + char(115), + char(116), + char(97), + char(110), + char(116), + char(0), + char(109), + char(95), + char(105), + char(109), + char(112), + char(108), + char(105), + char(99), + char(105), + char(116), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(105), + char(109), + char(101), + char(110), + char(115), + char(105), + char(111), + char(110), + char(115), + char(0), + char(109), + char(95), + char(99), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(77), + char(97), + char(114), + char(103), + char(105), + char(110), + char(0), + char(109), + char(95), + char(112), + char(97), + char(100), + char(100), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(112), + char(111), + char(115), + char(0), + char(109), + char(95), + char(114), + char(97), + char(100), + char(105), + char(117), + char(115), + char(0), + char(109), + char(95), + char(99), + char(111), + char(110), + char(118), + char(101), + char(120), + char(73), + char(110), + char(116), + char(101), + char(114), + char(110), + char(97), + char(108), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(42), + char(109), + char(95), + char(108), + char(111), + char(99), + char(97), + char(108), + char(80), + char(111), + char(115), + char(105), + char(116), + char(105), + char(111), + char(110), + char(65), + char(114), + char(114), + char(97), + char(121), + char(80), + char(116), + char(114), + char(0), + char(109), + char(95), + char(108), + char(111), + char(99), + char(97), + char(108), + char(80), + char(111), + char(115), + char(105), + char(116), + char(105), + char(111), + char(110), + char(65), + char(114), + char(114), + char(97), + char(121), + char(83), + char(105), + char(122), + char(101), + char(0), + char(109), + char(95), + char(118), + char(97), + char(108), + char(117), + char(101), + char(0), + char(109), + char(95), + char(112), + char(97), + char(100), + char(91), + char(50), + char(93), + char(0), + char(109), + char(95), + char(118), + char(97), + char(108), + char(117), + char(101), + char(115), + char(91), + char(51), + char(93), + char(0), + char(109), + char(95), + char(112), + char(97), + char(100), + char(0), + char(42), + char(109), + char(95), + char(118), + char(101), + char(114), + char(116), + char(105), + char(99), + char(101), + char(115), + char(51), + char(102), + char(0), + char(42), + char(109), + char(95), + char(118), + char(101), + char(114), + char(116), + char(105), + char(99), + char(101), + char(115), + char(51), + char(100), + char(0), + char(42), + char(109), + char(95), + char(105), + char(110), + char(100), + char(105), + char(99), + char(101), + char(115), + char(51), + char(50), + char(0), + char(42), + char(109), + char(95), + char(51), + char(105), + char(110), + char(100), + char(105), + char(99), + char(101), + char(115), + char(49), + char(54), + char(0), + char(42), + char(109), + char(95), + char(51), + char(105), + char(110), + char(100), + char(105), + char(99), + char(101), + char(115), + char(56), + char(0), + char(42), + char(109), + char(95), + char(105), + char(110), + char(100), + char(105), + char(99), + char(101), + char(115), + char(49), + char(54), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(84), + char(114), + char(105), + char(97), + char(110), + char(103), + char(108), + char(101), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(86), + char(101), + char(114), + char(116), + char(105), + char(99), + char(101), + char(115), + char(0), + char(42), + char(109), + char(95), + char(109), + char(101), + char(115), + char(104), + char(80), + char(97), + char(114), + char(116), + char(115), + char(80), + char(116), + char(114), + char(0), + char(109), + char(95), + char(115), + char(99), + char(97), + char(108), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(77), + char(101), + char(115), + char(104), + char(80), + char(97), + char(114), + char(116), + char(115), + char(0), + char(109), + char(95), + char(109), + char(101), + char(115), + char(104), + char(73), + char(110), + char(116), + char(101), + char(114), + char(102), + char(97), + char(99), + char(101), + char(0), + char(42), + char(109), + char(95), + char(113), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(101), + char(100), + char(70), + char(108), + char(111), + char(97), + char(116), + char(66), + char(118), + char(104), + char(0), + char(42), + char(109), + char(95), + char(113), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(101), + char(100), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(66), + char(118), + char(104), + char(0), + char(42), + char(109), + char(95), + char(116), + char(114), + char(105), + char(97), + char(110), + char(103), + char(108), + char(101), + char(73), + char(110), + char(102), + char(111), + char(77), + char(97), + char(112), + char(0), + char(109), + char(95), + char(112), + char(97), + char(100), + char(51), + char(91), + char(52), + char(93), + char(0), + char(109), + char(95), + char(116), + char(114), + char(105), + char(109), + char(101), + char(115), + char(104), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(109), + char(95), + char(116), + char(114), + char(97), + char(110), + char(115), + char(102), + char(111), + char(114), + char(109), + char(0), + char(42), + char(109), + char(95), + char(99), + char(104), + char(105), + char(108), + char(100), + char(83), + char(104), + char(97), + char(112), + char(101), + char(0), + char(109), + char(95), + char(99), + char(104), + char(105), + char(108), + char(100), + char(83), + char(104), + char(97), + char(112), + char(101), + char(84), + char(121), + char(112), + char(101), + char(0), + char(109), + char(95), + char(99), + char(104), + char(105), + char(108), + char(100), + char(77), + char(97), + char(114), + char(103), + char(105), + char(110), + char(0), + char(42), + char(109), + char(95), + char(99), + char(104), + char(105), + char(108), + char(100), + char(83), + char(104), + char(97), + char(112), + char(101), + char(80), + char(116), + char(114), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(67), + char(104), + char(105), + char(108), + char(100), + char(83), + char(104), + char(97), + char(112), + char(101), + char(115), + char(0), + char(109), + char(95), + char(117), + char(112), + char(65), + char(120), + char(105), + char(115), + char(0), + char(109), + char(95), + char(102), + char(108), + char(97), + char(103), + char(115), + char(0), + char(109), + char(95), + char(101), + char(100), + char(103), + char(101), + char(86), + char(48), + char(86), + char(49), + char(65), + char(110), + char(103), + char(108), + char(101), + char(0), + char(109), + char(95), + char(101), + char(100), + char(103), + char(101), + char(86), + char(49), + char(86), + char(50), + char(65), + char(110), + char(103), + char(108), + char(101), + char(0), + char(109), + char(95), + char(101), + char(100), + char(103), + char(101), + char(86), + char(50), + char(86), + char(48), + char(65), + char(110), + char(103), + char(108), + char(101), + char(0), + char(42), + char(109), + char(95), + char(104), + char(97), + char(115), + char(104), + char(84), + char(97), + char(98), + char(108), + char(101), + char(80), + char(116), + char(114), + char(0), + char(42), + char(109), + char(95), + char(110), + char(101), + char(120), + char(116), + char(80), + char(116), + char(114), + char(0), + char(42), + char(109), + char(95), + char(118), + char(97), + char(108), + char(117), + char(101), + char(65), + char(114), + char(114), + char(97), + char(121), + char(80), + char(116), + char(114), + char(0), + char(42), + char(109), + char(95), + char(107), + char(101), + char(121), + char(65), + char(114), + char(114), + char(97), + char(121), + char(80), + char(116), + char(114), + char(0), + char(109), + char(95), + char(99), + char(111), + char(110), + char(118), + char(101), + char(120), + char(69), + char(112), + char(115), + char(105), + char(108), + char(111), + char(110), + char(0), + char(109), + char(95), + char(112), + char(108), + char(97), + char(110), + char(97), + char(114), + char(69), + char(112), + char(115), + char(105), + char(108), + char(111), + char(110), + char(0), + char(109), + char(95), + char(101), + char(113), + char(117), + char(97), + char(108), + char(86), + char(101), + char(114), + char(116), + char(101), + char(120), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(101), + char(100), + char(103), + char(101), + char(68), + char(105), + char(115), + char(116), + char(97), + char(110), + char(99), + char(101), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(122), + char(101), + char(114), + char(111), + char(65), + char(114), + char(101), + char(97), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(110), + char(101), + char(120), + char(116), + char(83), + char(105), + char(122), + char(101), + char(0), + char(109), + char(95), + char(104), + char(97), + char(115), + char(104), + char(84), + char(97), + char(98), + char(108), + char(101), + char(83), + char(105), + char(122), + char(101), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(86), + char(97), + char(108), + char(117), + char(101), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(75), + char(101), + char(121), + char(115), + char(0), + char(109), + char(95), + char(103), + char(105), + char(109), + char(112), + char(97), + char(99), + char(116), + char(83), + char(117), + char(98), + char(84), + char(121), + char(112), + char(101), + char(0), + char(42), + char(109), + char(95), + char(117), + char(110), + char(115), + char(99), + char(97), + char(108), + char(101), + char(100), + char(80), + char(111), + char(105), + char(110), + char(116), + char(115), + char(70), + char(108), + char(111), + char(97), + char(116), + char(80), + char(116), + char(114), + char(0), + char(42), + char(109), + char(95), + char(117), + char(110), + char(115), + char(99), + char(97), + char(108), + char(101), + char(100), + char(80), + char(111), + char(105), + char(110), + char(116), + char(115), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(80), + char(116), + char(114), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(85), + char(110), + char(115), + char(99), + char(97), + char(108), + char(101), + char(100), + char(80), + char(111), + char(105), + char(110), + char(116), + char(115), + char(0), + char(109), + char(95), + char(112), + char(97), + char(100), + char(100), + char(105), + char(110), + char(103), + char(51), + char(91), + char(52), + char(93), + char(0), + char(42), + char(109), + char(95), + char(98), + char(114), + char(111), + char(97), + char(100), + char(112), + char(104), + char(97), + char(115), + char(101), + char(72), + char(97), + char(110), + char(100), + char(108), + char(101), + char(0), + char(42), + char(109), + char(95), + char(99), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(83), + char(104), + char(97), + char(112), + char(101), + char(0), + char(42), + char(109), + char(95), + char(114), + char(111), + char(111), + char(116), + char(67), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(83), + char(104), + char(97), + char(112), + char(101), + char(0), + char(109), + char(95), + char(119), + char(111), + char(114), + char(108), + char(100), + char(84), + char(114), + char(97), + char(110), + char(115), + char(102), + char(111), + char(114), + char(109), + char(0), + char(109), + char(95), + char(105), + char(110), + char(116), + char(101), + char(114), + char(112), + char(111), + char(108), + char(97), + char(116), + char(105), + char(111), + char(110), + char(87), + char(111), + char(114), + char(108), + char(100), + char(84), + char(114), + char(97), + char(110), + char(115), + char(102), + char(111), + char(114), + char(109), + char(0), + char(109), + char(95), + char(105), + char(110), + char(116), + char(101), + char(114), + char(112), + char(111), + char(108), + char(97), + char(116), + char(105), + char(111), + char(110), + char(76), + char(105), + char(110), + char(101), + char(97), + char(114), + char(86), + char(101), + char(108), + char(111), + char(99), + char(105), + char(116), + char(121), + char(0), + char(109), + char(95), + char(105), + char(110), + char(116), + char(101), + char(114), + char(112), + char(111), + char(108), + char(97), + char(116), + char(105), + char(111), + char(110), + char(65), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(86), + char(101), + char(108), + char(111), + char(99), + char(105), + char(116), + char(121), + char(0), + char(109), + char(95), + char(97), + char(110), + char(105), + char(115), + char(111), + char(116), + char(114), + char(111), + char(112), + char(105), + char(99), + char(70), + char(114), + char(105), + char(99), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(99), + char(111), + char(110), + char(116), + char(97), + char(99), + char(116), + char(80), + char(114), + char(111), + char(99), + char(101), + char(115), + char(115), + char(105), + char(110), + char(103), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(100), + char(101), + char(97), + char(99), + char(116), + char(105), + char(118), + char(97), + char(116), + char(105), + char(111), + char(110), + char(84), + char(105), + char(109), + char(101), + char(0), + char(109), + char(95), + char(102), + char(114), + char(105), + char(99), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(114), + char(111), + char(108), + char(108), + char(105), + char(110), + char(103), + char(70), + char(114), + char(105), + char(99), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(114), + char(101), + char(115), + char(116), + char(105), + char(116), + char(117), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(104), + char(105), + char(116), + char(70), + char(114), + char(97), + char(99), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(99), + char(99), + char(100), + char(83), + char(119), + char(101), + char(112), + char(116), + char(83), + char(112), + char(104), + char(101), + char(114), + char(101), + char(82), + char(97), + char(100), + char(105), + char(117), + char(115), + char(0), + char(109), + char(95), + char(99), + char(99), + char(100), + char(77), + char(111), + char(116), + char(105), + char(111), + char(110), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(104), + char(97), + char(115), + char(65), + char(110), + char(105), + char(115), + char(111), + char(116), + char(114), + char(111), + char(112), + char(105), + char(99), + char(70), + char(114), + char(105), + char(99), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(99), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(70), + char(108), + char(97), + char(103), + char(115), + char(0), + char(109), + char(95), + char(105), + char(115), + char(108), + char(97), + char(110), + char(100), + char(84), + char(97), + char(103), + char(49), + char(0), + char(109), + char(95), + char(99), + char(111), + char(109), + char(112), + char(97), + char(110), + char(105), + char(111), + char(110), + char(73), + char(100), + char(0), + char(109), + char(95), + char(97), + char(99), + char(116), + char(105), + char(118), + char(97), + char(116), + char(105), + char(111), + char(110), + char(83), + char(116), + char(97), + char(116), + char(101), + char(49), + char(0), + char(109), + char(95), + char(105), + char(110), + char(116), + char(101), + char(114), + char(110), + char(97), + char(108), + char(84), + char(121), + char(112), + char(101), + char(0), + char(109), + char(95), + char(99), + char(104), + char(101), + char(99), + char(107), + char(67), + char(111), + char(108), + char(108), + char(105), + char(100), + char(101), + char(87), + char(105), + char(116), + char(104), + char(0), + char(109), + char(95), + char(115), + char(111), + char(108), + char(118), + char(101), + char(114), + char(73), + char(110), + char(102), + char(111), + char(0), + char(109), + char(95), + char(103), + char(114), + char(97), + char(118), + char(105), + char(116), + char(121), + char(0), + char(109), + char(95), + char(99), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(79), + char(98), + char(106), + char(101), + char(99), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(109), + char(95), + char(105), + char(110), + char(118), + char(73), + char(110), + char(101), + char(114), + char(116), + char(105), + char(97), + char(84), + char(101), + char(110), + char(115), + char(111), + char(114), + char(87), + char(111), + char(114), + char(108), + char(100), + char(0), + char(109), + char(95), + char(108), + char(105), + char(110), + char(101), + char(97), + char(114), + char(86), + char(101), + char(108), + char(111), + char(99), + char(105), + char(116), + char(121), + char(0), + char(109), + char(95), + char(97), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(86), + char(101), + char(108), + char(111), + char(99), + char(105), + char(116), + char(121), + char(0), + char(109), + char(95), + char(97), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(70), + char(97), + char(99), + char(116), + char(111), + char(114), + char(0), + char(109), + char(95), + char(108), + char(105), + char(110), + char(101), + char(97), + char(114), + char(70), + char(97), + char(99), + char(116), + char(111), + char(114), + char(0), + char(109), + char(95), + char(103), + char(114), + char(97), + char(118), + char(105), + char(116), + char(121), + char(95), + char(97), + char(99), + char(99), + char(101), + char(108), + char(101), + char(114), + char(97), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(105), + char(110), + char(118), + char(73), + char(110), + char(101), + char(114), + char(116), + char(105), + char(97), + char(76), + char(111), + char(99), + char(97), + char(108), + char(0), + char(109), + char(95), + char(116), + char(111), + char(116), + char(97), + char(108), + char(70), + char(111), + char(114), + char(99), + char(101), + char(0), + char(109), + char(95), + char(116), + char(111), + char(116), + char(97), + char(108), + char(84), + char(111), + char(114), + char(113), + char(117), + char(101), + char(0), + char(109), + char(95), + char(105), + char(110), + char(118), + char(101), + char(114), + char(115), + char(101), + char(77), + char(97), + char(115), + char(115), + char(0), + char(109), + char(95), + char(108), + char(105), + char(110), + char(101), + char(97), + char(114), + char(68), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(97), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(68), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(97), + char(100), + char(100), + char(105), + char(116), + char(105), + char(111), + char(110), + char(97), + char(108), + char(68), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(70), + char(97), + char(99), + char(116), + char(111), + char(114), + char(0), + char(109), + char(95), + char(97), + char(100), + char(100), + char(105), + char(116), + char(105), + char(111), + char(110), + char(97), + char(108), + char(76), + char(105), + char(110), + char(101), + char(97), + char(114), + char(68), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(83), + char(113), + char(114), + char(0), + char(109), + char(95), + char(97), + char(100), + char(100), + char(105), + char(116), + char(105), + char(111), + char(110), + char(97), + char(108), + char(65), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(68), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(83), + char(113), + char(114), + char(0), + char(109), + char(95), + char(97), + char(100), + char(100), + char(105), + char(116), + char(105), + char(111), + char(110), + char(97), + char(108), + char(65), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(68), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(70), + char(97), + char(99), + char(116), + char(111), + char(114), + char(0), + char(109), + char(95), + char(108), + char(105), + char(110), + char(101), + char(97), + char(114), + char(83), + char(108), + char(101), + char(101), + char(112), + char(105), + char(110), + char(103), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(97), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(83), + char(108), + char(101), + char(101), + char(112), + char(105), + char(110), + char(103), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(97), + char(100), + char(100), + char(105), + char(116), + char(105), + char(111), + char(110), + char(97), + char(108), + char(68), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(82), + char(111), + char(119), + char(115), + char(0), + char(110), + char(117), + char(98), + char(0), + char(42), + char(109), + char(95), + char(114), + char(98), + char(65), + char(0), + char(42), + char(109), + char(95), + char(114), + char(98), + char(66), + char(0), + char(109), + char(95), + char(111), + char(98), + char(106), + char(101), + char(99), + char(116), + char(84), + char(121), + char(112), + char(101), + char(0), + char(109), + char(95), + char(117), + char(115), + char(101), + char(114), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(84), + char(121), + char(112), + char(101), + char(0), + char(109), + char(95), + char(117), + char(115), + char(101), + char(114), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(73), + char(100), + char(0), + char(109), + char(95), + char(110), + char(101), + char(101), + char(100), + char(115), + char(70), + char(101), + char(101), + char(100), + char(98), + char(97), + char(99), + char(107), + char(0), + char(109), + char(95), + char(97), + char(112), + char(112), + char(108), + char(105), + char(101), + char(100), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(0), + char(109), + char(95), + char(100), + char(98), + char(103), + char(68), + char(114), + char(97), + char(119), + char(83), + char(105), + char(122), + char(101), + char(0), + char(109), + char(95), + char(100), + char(105), + char(115), + char(97), + char(98), + char(108), + char(101), + char(67), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(115), + char(66), + char(101), + char(116), + char(119), + char(101), + char(101), + char(110), + char(76), + char(105), + char(110), + char(107), + char(101), + char(100), + char(66), + char(111), + char(100), + char(105), + char(101), + char(115), + char(0), + char(109), + char(95), + char(111), + char(118), + char(101), + char(114), + char(114), + char(105), + char(100), + char(101), + char(78), + char(117), + char(109), + char(83), + char(111), + char(108), + char(118), + char(101), + char(114), + char(73), + char(116), + char(101), + char(114), + char(97), + char(116), + char(105), + char(111), + char(110), + char(115), + char(0), + char(109), + char(95), + char(98), + char(114), + char(101), + char(97), + char(107), + char(105), + char(110), + char(103), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(105), + char(115), + char(69), + char(110), + char(97), + char(98), + char(108), + char(101), + char(100), + char(0), + char(109), + char(95), + char(116), + char(121), + char(112), + char(101), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(109), + char(95), + char(112), + char(105), + char(118), + char(111), + char(116), + char(73), + char(110), + char(65), + char(0), + char(109), + char(95), + char(112), + char(105), + char(118), + char(111), + char(116), + char(73), + char(110), + char(66), + char(0), + char(109), + char(95), + char(114), + char(98), + char(65), + char(70), + char(114), + char(97), + char(109), + char(101), + char(0), + char(109), + char(95), + char(114), + char(98), + char(66), + char(70), + char(114), + char(97), + char(109), + char(101), + char(0), + char(109), + char(95), + char(117), + char(115), + char(101), + char(82), + char(101), + char(102), + char(101), + char(114), + char(101), + char(110), + char(99), + char(101), + char(70), + char(114), + char(97), + char(109), + char(101), + char(65), + char(0), + char(109), + char(95), + char(97), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(79), + char(110), + char(108), + char(121), + char(0), + char(109), + char(95), + char(101), + char(110), + char(97), + char(98), + char(108), + char(101), + char(65), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(77), + char(111), + char(116), + char(111), + char(114), + char(0), + char(109), + char(95), + char(109), + char(111), + char(116), + char(111), + char(114), + char(84), + char(97), + char(114), + char(103), + char(101), + char(116), + char(86), + char(101), + char(108), + char(111), + char(99), + char(105), + char(116), + char(121), + char(0), + char(109), + char(95), + char(109), + char(97), + char(120), + char(77), + char(111), + char(116), + char(111), + char(114), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(0), + char(109), + char(95), + char(108), + char(111), + char(119), + char(101), + char(114), + char(76), + char(105), + char(109), + char(105), + char(116), + char(0), + char(109), + char(95), + char(117), + char(112), + char(112), + char(101), + char(114), + char(76), + char(105), + char(109), + char(105), + char(116), + char(0), + char(109), + char(95), + char(108), + char(105), + char(109), + char(105), + char(116), + char(83), + char(111), + char(102), + char(116), + char(110), + char(101), + char(115), + char(115), + char(0), + char(109), + char(95), + char(98), + char(105), + char(97), + char(115), + char(70), + char(97), + char(99), + char(116), + char(111), + char(114), + char(0), + char(109), + char(95), + char(114), + char(101), + char(108), + char(97), + char(120), + char(97), + char(116), + char(105), + char(111), + char(110), + char(70), + char(97), + char(99), + char(116), + char(111), + char(114), + char(0), + char(109), + char(95), + char(115), + char(119), + char(105), + char(110), + char(103), + char(83), + char(112), + char(97), + char(110), + char(49), + char(0), + char(109), + char(95), + char(115), + char(119), + char(105), + char(110), + char(103), + char(83), + char(112), + char(97), + char(110), + char(50), + char(0), + char(109), + char(95), + char(116), + char(119), + char(105), + char(115), + char(116), + char(83), + char(112), + char(97), + char(110), + char(0), + char(109), + char(95), + char(100), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(108), + char(105), + char(110), + char(101), + char(97), + char(114), + char(85), + char(112), + char(112), + char(101), + char(114), + char(76), + char(105), + char(109), + char(105), + char(116), + char(0), + char(109), + char(95), + char(108), + char(105), + char(110), + char(101), + char(97), + char(114), + char(76), + char(111), + char(119), + char(101), + char(114), + char(76), + char(105), + char(109), + char(105), + char(116), + char(0), + char(109), + char(95), + char(97), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(85), + char(112), + char(112), + char(101), + char(114), + char(76), + char(105), + char(109), + char(105), + char(116), + char(0), + char(109), + char(95), + char(97), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(76), + char(111), + char(119), + char(101), + char(114), + char(76), + char(105), + char(109), + char(105), + char(116), + char(0), + char(109), + char(95), + char(117), + char(115), + char(101), + char(76), + char(105), + char(110), + char(101), + char(97), + char(114), + char(82), + char(101), + char(102), + char(101), + char(114), + char(101), + char(110), + char(99), + char(101), + char(70), + char(114), + char(97), + char(109), + char(101), + char(65), + char(0), + char(109), + char(95), + char(117), + char(115), + char(101), + char(79), + char(102), + char(102), + char(115), + char(101), + char(116), + char(70), + char(111), + char(114), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(70), + char(114), + char(97), + char(109), + char(101), + char(0), + char(109), + char(95), + char(54), + char(100), + char(111), + char(102), + char(68), + char(97), + char(116), + char(97), + char(0), + char(109), + char(95), + char(115), + char(112), + char(114), + char(105), + char(110), + char(103), + char(69), + char(110), + char(97), + char(98), + char(108), + char(101), + char(100), + char(91), + char(54), + char(93), + char(0), + char(109), + char(95), + char(101), + char(113), + char(117), + char(105), + char(108), + char(105), + char(98), + char(114), + char(105), + char(117), + char(109), + char(80), + char(111), + char(105), + char(110), + char(116), + char(91), + char(54), + char(93), + char(0), + char(109), + char(95), + char(115), + char(112), + char(114), + char(105), + char(110), + char(103), + char(83), + char(116), + char(105), + char(102), + char(102), + char(110), + char(101), + char(115), + char(115), + char(91), + char(54), + char(93), + char(0), + char(109), + char(95), + char(115), + char(112), + char(114), + char(105), + char(110), + char(103), + char(68), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(91), + char(54), + char(93), + char(0), + char(109), + char(95), + char(116), + char(97), + char(117), + char(0), + char(109), + char(95), + char(116), + char(105), + char(109), + char(101), + char(83), + char(116), + char(101), + char(112), + char(0), + char(109), + char(95), + char(109), + char(97), + char(120), + char(69), + char(114), + char(114), + char(111), + char(114), + char(82), + char(101), + char(100), + char(117), + char(99), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(115), + char(111), + char(114), + char(0), + char(109), + char(95), + char(101), + char(114), + char(112), + char(0), + char(109), + char(95), + char(101), + char(114), + char(112), + char(50), + char(0), + char(109), + char(95), + char(103), + char(108), + char(111), + char(98), + char(97), + char(108), + char(67), + char(102), + char(109), + char(0), + char(109), + char(95), + char(115), + char(112), + char(108), + char(105), + char(116), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(80), + char(101), + char(110), + char(101), + char(116), + char(114), + char(97), + char(116), + char(105), + char(111), + char(110), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(115), + char(112), + char(108), + char(105), + char(116), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(84), + char(117), + char(114), + char(110), + char(69), + char(114), + char(112), + char(0), + char(109), + char(95), + char(108), + char(105), + char(110), + char(101), + char(97), + char(114), + char(83), + char(108), + char(111), + char(112), + char(0), + char(109), + char(95), + char(119), + char(97), + char(114), + char(109), + char(115), + char(116), + char(97), + char(114), + char(116), + char(105), + char(110), + char(103), + char(70), + char(97), + char(99), + char(116), + char(111), + char(114), + char(0), + char(109), + char(95), + char(109), + char(97), + char(120), + char(71), + char(121), + char(114), + char(111), + char(115), + char(99), + char(111), + char(112), + char(105), + char(99), + char(70), + char(111), + char(114), + char(99), + char(101), + char(0), + char(109), + char(95), + char(115), + char(105), + char(110), + char(103), + char(108), + char(101), + char(65), + char(120), + char(105), + char(115), + char(82), + char(111), + char(108), + char(108), + char(105), + char(110), + char(103), + char(70), + char(114), + char(105), + char(99), + char(116), + char(105), + char(111), + char(110), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(73), + char(116), + char(101), + char(114), + char(97), + char(116), + char(105), + char(111), + char(110), + char(115), + char(0), + char(109), + char(95), + char(115), + char(111), + char(108), + char(118), + char(101), + char(114), + char(77), + char(111), + char(100), + char(101), + char(0), + char(109), + char(95), + char(114), + char(101), + char(115), + char(116), + char(105), + char(110), + char(103), + char(67), + char(111), + char(110), + char(116), + char(97), + char(99), + char(116), + char(82), + char(101), + char(115), + char(116), + char(105), + char(116), + char(117), + char(116), + char(105), + char(111), + char(110), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(109), + char(105), + char(110), + char(105), + char(109), + char(117), + char(109), + char(83), + char(111), + char(108), + char(118), + char(101), + char(114), + char(66), + char(97), + char(116), + char(99), + char(104), + char(83), + char(105), + char(122), + char(101), + char(0), + char(109), + char(95), + char(115), + char(112), + char(108), + char(105), + char(116), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(0), + char(109), + char(95), + char(108), + char(105), + char(110), + char(101), + char(97), + char(114), + char(83), + char(116), + char(105), + char(102), + char(102), + char(110), + char(101), + char(115), + char(115), + char(0), + char(109), + char(95), + char(97), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(83), + char(116), + char(105), + char(102), + char(102), + char(110), + char(101), + char(115), + char(115), + char(0), + char(109), + char(95), + char(118), + char(111), + char(108), + char(117), + char(109), + char(101), + char(83), + char(116), + char(105), + char(102), + char(102), + char(110), + char(101), + char(115), + char(115), + char(0), + char(42), + char(109), + char(95), + char(109), + char(97), + char(116), + char(101), + char(114), + char(105), + char(97), + char(108), + char(0), + char(109), + char(95), + char(112), + char(111), + char(115), + char(105), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(112), + char(114), + char(101), + char(118), + char(105), + char(111), + char(117), + char(115), + char(80), + char(111), + char(115), + char(105), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(118), + char(101), + char(108), + char(111), + char(99), + char(105), + char(116), + char(121), + char(0), + char(109), + char(95), + char(97), + char(99), + char(99), + char(117), + char(109), + char(117), + char(108), + char(97), + char(116), + char(101), + char(100), + char(70), + char(111), + char(114), + char(99), + char(101), + char(0), + char(109), + char(95), + char(110), + char(111), + char(114), + char(109), + char(97), + char(108), + char(0), + char(109), + char(95), + char(97), + char(114), + char(101), + char(97), + char(0), + char(109), + char(95), + char(97), + char(116), + char(116), + char(97), + char(99), + char(104), + char(0), + char(109), + char(95), + char(110), + char(111), + char(100), + char(101), + char(73), + char(110), + char(100), + char(105), + char(99), + char(101), + char(115), + char(91), + char(50), + char(93), + char(0), + char(109), + char(95), + char(114), + char(101), + char(115), + char(116), + char(76), + char(101), + char(110), + char(103), + char(116), + char(104), + char(0), + char(109), + char(95), + char(98), + char(98), + char(101), + char(110), + char(100), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(110), + char(111), + char(100), + char(101), + char(73), + char(110), + char(100), + char(105), + char(99), + char(101), + char(115), + char(91), + char(51), + char(93), + char(0), + char(109), + char(95), + char(114), + char(101), + char(115), + char(116), + char(65), + char(114), + char(101), + char(97), + char(0), + char(109), + char(95), + char(99), + char(48), + char(91), + char(52), + char(93), + char(0), + char(109), + char(95), + char(110), + char(111), + char(100), + char(101), + char(73), + char(110), + char(100), + char(105), + char(99), + char(101), + char(115), + char(91), + char(52), + char(93), + char(0), + char(109), + char(95), + char(114), + char(101), + char(115), + char(116), + char(86), + char(111), + char(108), + char(117), + char(109), + char(101), + char(0), + char(109), + char(95), + char(99), + char(49), + char(0), + char(109), + char(95), + char(99), + char(50), + char(0), + char(109), + char(95), + char(99), + char(48), + char(0), + char(109), + char(95), + char(108), + char(111), + char(99), + char(97), + char(108), + char(70), + char(114), + char(97), + char(109), + char(101), + char(0), + char(42), + char(109), + char(95), + char(114), + char(105), + char(103), + char(105), + char(100), + char(66), + char(111), + char(100), + char(121), + char(0), + char(109), + char(95), + char(110), + char(111), + char(100), + char(101), + char(73), + char(110), + char(100), + char(101), + char(120), + char(0), + char(109), + char(95), + char(97), + char(101), + char(114), + char(111), + char(77), + char(111), + char(100), + char(101), + char(108), + char(0), + char(109), + char(95), + char(98), + char(97), + char(117), + char(109), + char(103), + char(97), + char(114), + char(116), + char(101), + char(0), + char(109), + char(95), + char(100), + char(114), + char(97), + char(103), + char(0), + char(109), + char(95), + char(108), + char(105), + char(102), + char(116), + char(0), + char(109), + char(95), + char(112), + char(114), + char(101), + char(115), + char(115), + char(117), + char(114), + char(101), + char(0), + char(109), + char(95), + char(118), + char(111), + char(108), + char(117), + char(109), + char(101), + char(0), + char(109), + char(95), + char(100), + char(121), + char(110), + char(97), + char(109), + char(105), + char(99), + char(70), + char(114), + char(105), + char(99), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(112), + char(111), + char(115), + char(101), + char(77), + char(97), + char(116), + char(99), + char(104), + char(0), + char(109), + char(95), + char(114), + char(105), + char(103), + char(105), + char(100), + char(67), + char(111), + char(110), + char(116), + char(97), + char(99), + char(116), + char(72), + char(97), + char(114), + char(100), + char(110), + char(101), + char(115), + char(115), + char(0), + char(109), + char(95), + char(107), + char(105), + char(110), + char(101), + char(116), + char(105), + char(99), + char(67), + char(111), + char(110), + char(116), + char(97), + char(99), + char(116), + char(72), + char(97), + char(114), + char(100), + char(110), + char(101), + char(115), + char(115), + char(0), + char(109), + char(95), + char(115), + char(111), + char(102), + char(116), + char(67), + char(111), + char(110), + char(116), + char(97), + char(99), + char(116), + char(72), + char(97), + char(114), + char(100), + char(110), + char(101), + char(115), + char(115), + char(0), + char(109), + char(95), + char(97), + char(110), + char(99), + char(104), + char(111), + char(114), + char(72), + char(97), + char(114), + char(100), + char(110), + char(101), + char(115), + char(115), + char(0), + char(109), + char(95), + char(115), + char(111), + char(102), + char(116), + char(82), + char(105), + char(103), + char(105), + char(100), + char(67), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(72), + char(97), + char(114), + char(100), + char(110), + char(101), + char(115), + char(115), + char(0), + char(109), + char(95), + char(115), + char(111), + char(102), + char(116), + char(75), + char(105), + char(110), + char(101), + char(116), + char(105), + char(99), + char(67), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(72), + char(97), + char(114), + char(100), + char(110), + char(101), + char(115), + char(115), + char(0), + char(109), + char(95), + char(115), + char(111), + char(102), + char(116), + char(83), + char(111), + char(102), + char(116), + char(67), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(72), + char(97), + char(114), + char(100), + char(110), + char(101), + char(115), + char(115), + char(0), + char(109), + char(95), + char(115), + char(111), + char(102), + char(116), + char(82), + char(105), + char(103), + char(105), + char(100), + char(67), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(83), + char(112), + char(108), + char(105), + char(116), + char(0), + char(109), + char(95), + char(115), + char(111), + char(102), + char(116), + char(75), + char(105), + char(110), + char(101), + char(116), + char(105), + char(99), + char(67), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(83), + char(112), + char(108), + char(105), + char(116), + char(0), + char(109), + char(95), + char(115), + char(111), + char(102), + char(116), + char(83), + char(111), + char(102), + char(116), + char(67), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(83), + char(112), + char(108), + char(105), + char(116), + char(0), + char(109), + char(95), + char(109), + char(97), + char(120), + char(86), + char(111), + char(108), + char(117), + char(109), + char(101), + char(0), + char(109), + char(95), + char(116), + char(105), + char(109), + char(101), + char(83), + char(99), + char(97), + char(108), + char(101), + char(0), + char(109), + char(95), + char(118), + char(101), + char(108), + char(111), + char(99), + char(105), + char(116), + char(121), + char(73), + char(116), + char(101), + char(114), + char(97), + char(116), + char(105), + char(111), + char(110), + char(115), + char(0), + char(109), + char(95), + char(112), + char(111), + char(115), + char(105), + char(116), + char(105), + char(111), + char(110), + char(73), + char(116), + char(101), + char(114), + char(97), + char(116), + char(105), + char(111), + char(110), + char(115), + char(0), + char(109), + char(95), + char(100), + char(114), + char(105), + char(102), + char(116), + char(73), + char(116), + char(101), + char(114), + char(97), + char(116), + char(105), + char(111), + char(110), + char(115), + char(0), + char(109), + char(95), + char(99), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(73), + char(116), + char(101), + char(114), + char(97), + char(116), + char(105), + char(111), + char(110), + char(115), + char(0), + char(109), + char(95), + char(114), + char(111), + char(116), + char(0), + char(109), + char(95), + char(115), + char(99), + char(97), + char(108), + char(101), + char(0), + char(109), + char(95), + char(97), + char(113), + char(113), + char(0), + char(109), + char(95), + char(99), + char(111), + char(109), + char(0), + char(42), + char(109), + char(95), + char(112), + char(111), + char(115), + char(105), + char(116), + char(105), + char(111), + char(110), + char(115), + char(0), + char(42), + char(109), + char(95), + char(119), + char(101), + char(105), + char(103), + char(104), + char(116), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(80), + char(111), + char(115), + char(105), + char(116), + char(105), + char(111), + char(110), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(87), + char(101), + char(105), + char(103), + char(116), + char(115), + char(0), + char(109), + char(95), + char(98), + char(118), + char(111), + char(108), + char(117), + char(109), + char(101), + char(0), + char(109), + char(95), + char(98), + char(102), + char(114), + char(97), + char(109), + char(101), + char(0), + char(109), + char(95), + char(102), + char(114), + char(97), + char(109), + char(101), + char(120), + char(102), + char(111), + char(114), + char(109), + char(0), + char(109), + char(95), + char(108), + char(111), + char(99), + char(105), + char(105), + char(0), + char(109), + char(95), + char(105), + char(110), + char(118), + char(119), + char(105), + char(0), + char(109), + char(95), + char(118), + char(105), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(115), + char(91), + char(50), + char(93), + char(0), + char(109), + char(95), + char(100), + char(105), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(115), + char(91), + char(50), + char(93), + char(0), + char(109), + char(95), + char(108), + char(118), + char(0), + char(109), + char(95), + char(97), + char(118), + char(0), + char(42), + char(109), + char(95), + char(102), + char(114), + char(97), + char(109), + char(101), + char(114), + char(101), + char(102), + char(115), + char(0), + char(42), + char(109), + char(95), + char(110), + char(111), + char(100), + char(101), + char(73), + char(110), + char(100), + char(105), + char(99), + char(101), + char(115), + char(0), + char(42), + char(109), + char(95), + char(109), + char(97), + char(115), + char(115), + char(101), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(70), + char(114), + char(97), + char(109), + char(101), + char(82), + char(101), + char(102), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(78), + char(111), + char(100), + char(101), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(77), + char(97), + char(115), + char(115), + char(101), + char(115), + char(0), + char(109), + char(95), + char(105), + char(100), + char(109), + char(97), + char(115), + char(115), + char(0), + char(109), + char(95), + char(105), + char(109), + char(97), + char(115), + char(115), + char(0), + char(109), + char(95), + char(110), + char(118), + char(105), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(115), + char(0), + char(109), + char(95), + char(110), + char(100), + char(105), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(115), + char(0), + char(109), + char(95), + char(110), + char(100), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(108), + char(100), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(97), + char(100), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(109), + char(97), + char(116), + char(99), + char(104), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(109), + char(97), + char(120), + char(83), + char(101), + char(108), + char(102), + char(67), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(0), + char(109), + char(95), + char(115), + char(101), + char(108), + char(102), + char(67), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(70), + char(97), + char(99), + char(116), + char(111), + char(114), + char(0), + char(109), + char(95), + char(99), + char(111), + char(110), + char(116), + char(97), + char(105), + char(110), + char(115), + char(65), + char(110), + char(99), + char(104), + char(111), + char(114), + char(0), + char(109), + char(95), + char(99), + char(111), + char(108), + char(108), + char(105), + char(100), + char(101), + char(0), + char(109), + char(95), + char(99), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(73), + char(110), + char(100), + char(101), + char(120), + char(0), + char(42), + char(109), + char(95), + char(98), + char(111), + char(100), + char(121), + char(65), + char(0), + char(42), + char(109), + char(95), + char(98), + char(111), + char(100), + char(121), + char(66), + char(0), + char(109), + char(95), + char(114), + char(101), + char(102), + char(115), + char(91), + char(50), + char(93), + char(0), + char(109), + char(95), + char(99), + char(102), + char(109), + char(0), + char(109), + char(95), + char(115), + char(112), + char(108), + char(105), + char(116), + char(0), + char(109), + char(95), + char(100), + char(101), + char(108), + char(101), + char(116), + char(101), + char(0), + char(109), + char(95), + char(114), + char(101), + char(108), + char(80), + char(111), + char(115), + char(105), + char(116), + char(105), + char(111), + char(110), + char(91), + char(50), + char(93), + char(0), + char(109), + char(95), + char(98), + char(111), + char(100), + char(121), + char(65), + char(116), + char(121), + char(112), + char(101), + char(0), + char(109), + char(95), + char(98), + char(111), + char(100), + char(121), + char(66), + char(116), + char(121), + char(112), + char(101), + char(0), + char(109), + char(95), + char(106), + char(111), + char(105), + char(110), + char(116), + char(84), + char(121), + char(112), + char(101), + char(0), + char(42), + char(109), + char(95), + char(112), + char(111), + char(115), + char(101), + char(0), + char(42), + char(42), + char(109), + char(95), + char(109), + char(97), + char(116), + char(101), + char(114), + char(105), + char(97), + char(108), + char(115), + char(0), + char(42), + char(109), + char(95), + char(110), + char(111), + char(100), + char(101), + char(115), + char(0), + char(42), + char(109), + char(95), + char(108), + char(105), + char(110), + char(107), + char(115), + char(0), + char(42), + char(109), + char(95), + char(102), + char(97), + char(99), + char(101), + char(115), + char(0), + char(42), + char(109), + char(95), + char(116), + char(101), + char(116), + char(114), + char(97), + char(104), + char(101), + char(100), + char(114), + char(97), + char(0), + char(42), + char(109), + char(95), + char(97), + char(110), + char(99), + char(104), + char(111), + char(114), + char(115), + char(0), + char(42), + char(109), + char(95), + char(99), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(115), + char(0), + char(42), + char(109), + char(95), + char(106), + char(111), + char(105), + char(110), + char(116), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(77), + char(97), + char(116), + char(101), + char(114), + char(105), + char(97), + char(108), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(76), + char(105), + char(110), + char(107), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(70), + char(97), + char(99), + char(101), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(84), + char(101), + char(116), + char(114), + char(97), + char(104), + char(101), + char(100), + char(114), + char(97), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(65), + char(110), + char(99), + char(104), + char(111), + char(114), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(67), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(74), + char(111), + char(105), + char(110), + char(116), + char(115), + char(0), + char(109), + char(95), + char(99), + char(111), + char(110), + char(102), + char(105), + char(103), + char(0), + char(84), + char(89), + char(80), + char(69), + char(76), + char(0), + char(0), + char(0), + char(99), + char(104), + char(97), + char(114), + char(0), + char(117), + char(99), + char(104), + char(97), + char(114), + char(0), + char(115), + char(104), + char(111), + char(114), + char(116), + char(0), + char(117), + char(115), + char(104), + char(111), + char(114), + char(116), + char(0), + char(105), + char(110), + char(116), + char(0), + char(108), + char(111), + char(110), + char(103), + char(0), + char(117), + char(108), + char(111), + char(110), + char(103), + char(0), + char(102), + char(108), + char(111), + char(97), + char(116), + char(0), + char(100), + char(111), + char(117), + char(98), + char(108), + char(101), + char(0), + char(118), + char(111), + char(105), + char(100), + char(0), + char(80), + char(111), + char(105), + char(110), + char(116), + char(101), + char(114), + char(65), + char(114), + char(114), + char(97), + char(121), + char(0), + char(98), + char(116), + char(80), + char(104), + char(121), + char(115), + char(105), + char(99), + char(115), + char(83), + char(121), + char(115), + char(116), + char(101), + char(109), + char(0), + char(76), + char(105), + char(115), + char(116), + char(66), + char(97), + char(115), + char(101), + char(0), + char(98), + char(116), + char(86), + char(101), + char(99), + char(116), + char(111), + char(114), + char(51), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(86), + char(101), + char(99), + char(116), + char(111), + char(114), + char(51), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(77), + char(97), + char(116), + char(114), + char(105), + char(120), + char(51), + char(120), + char(51), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(77), + char(97), + char(116), + char(114), + char(105), + char(120), + char(51), + char(120), + char(51), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(84), + char(114), + char(97), + char(110), + char(115), + char(102), + char(111), + char(114), + char(109), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(84), + char(114), + char(97), + char(110), + char(115), + char(102), + char(111), + char(114), + char(109), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(66), + char(118), + char(104), + char(83), + char(117), + char(98), + char(116), + char(114), + char(101), + char(101), + char(73), + char(110), + char(102), + char(111), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(79), + char(112), + char(116), + char(105), + char(109), + char(105), + char(122), + char(101), + char(100), + char(66), + char(118), + char(104), + char(78), + char(111), + char(100), + char(101), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(79), + char(112), + char(116), + char(105), + char(109), + char(105), + char(122), + char(101), + char(100), + char(66), + char(118), + char(104), + char(78), + char(111), + char(100), + char(101), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(81), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(101), + char(100), + char(66), + char(118), + char(104), + char(78), + char(111), + char(100), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(81), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(101), + char(100), + char(66), + char(118), + char(104), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(81), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(101), + char(100), + char(66), + char(118), + char(104), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(83), + char(116), + char(97), + char(116), + char(105), + char(99), + char(80), + char(108), + char(97), + char(110), + char(101), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(110), + char(118), + char(101), + char(120), + char(73), + char(110), + char(116), + char(101), + char(114), + char(110), + char(97), + char(108), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(80), + char(111), + char(115), + char(105), + char(116), + char(105), + char(111), + char(110), + char(65), + char(110), + char(100), + char(82), + char(97), + char(100), + char(105), + char(117), + char(115), + char(0), + char(98), + char(116), + char(77), + char(117), + char(108), + char(116), + char(105), + char(83), + char(112), + char(104), + char(101), + char(114), + char(101), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(73), + char(110), + char(116), + char(73), + char(110), + char(100), + char(101), + char(120), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(83), + char(104), + char(111), + char(114), + char(116), + char(73), + char(110), + char(116), + char(73), + char(110), + char(100), + char(101), + char(120), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(83), + char(104), + char(111), + char(114), + char(116), + char(73), + char(110), + char(116), + char(73), + char(110), + char(100), + char(101), + char(120), + char(84), + char(114), + char(105), + char(112), + char(108), + char(101), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(104), + char(97), + char(114), + char(73), + char(110), + char(100), + char(101), + char(120), + char(84), + char(114), + char(105), + char(112), + char(108), + char(101), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(77), + char(101), + char(115), + char(104), + char(80), + char(97), + char(114), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(83), + char(116), + char(114), + char(105), + char(100), + char(105), + char(110), + char(103), + char(77), + char(101), + char(115), + char(104), + char(73), + char(110), + char(116), + char(101), + char(114), + char(102), + char(97), + char(99), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(84), + char(114), + char(105), + char(97), + char(110), + char(103), + char(108), + char(101), + char(77), + char(101), + char(115), + char(104), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(84), + char(114), + char(105), + char(97), + char(110), + char(103), + char(108), + char(101), + char(73), + char(110), + char(102), + char(111), + char(77), + char(97), + char(112), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(83), + char(99), + char(97), + char(108), + char(101), + char(100), + char(84), + char(114), + char(105), + char(97), + char(110), + char(103), + char(108), + char(101), + char(77), + char(101), + char(115), + char(104), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(109), + char(112), + char(111), + char(117), + char(110), + char(100), + char(83), + char(104), + char(97), + char(112), + char(101), + char(67), + char(104), + char(105), + char(108), + char(100), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(109), + char(112), + char(111), + char(117), + char(110), + char(100), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(121), + char(108), + char(105), + char(110), + char(100), + char(101), + char(114), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(97), + char(112), + char(115), + char(117), + char(108), + char(101), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(84), + char(114), + char(105), + char(97), + char(110), + char(103), + char(108), + char(101), + char(73), + char(110), + char(102), + char(111), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(71), + char(73), + char(109), + char(112), + char(97), + char(99), + char(116), + char(77), + char(101), + char(115), + char(104), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(110), + char(118), + char(101), + char(120), + char(72), + char(117), + char(108), + char(108), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(79), + char(98), + char(106), + char(101), + char(99), + char(116), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(79), + char(98), + char(106), + char(101), + char(99), + char(116), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(68), + char(121), + char(110), + char(97), + char(109), + char(105), + char(99), + char(115), + char(87), + char(111), + char(114), + char(108), + char(100), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(110), + char(116), + char(97), + char(99), + char(116), + char(83), + char(111), + char(108), + char(118), + char(101), + char(114), + char(73), + char(110), + char(102), + char(111), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(68), + char(121), + char(110), + char(97), + char(109), + char(105), + char(99), + char(115), + char(87), + char(111), + char(114), + char(108), + char(100), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(110), + char(116), + char(97), + char(99), + char(116), + char(83), + char(111), + char(108), + char(118), + char(101), + char(114), + char(73), + char(110), + char(102), + char(111), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(82), + char(105), + char(103), + char(105), + char(100), + char(66), + char(111), + char(100), + char(121), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(82), + char(105), + char(103), + char(105), + char(100), + char(66), + char(111), + char(100), + char(121), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(73), + char(110), + char(102), + char(111), + char(49), + char(0), + char(98), + char(116), + char(84), + char(121), + char(112), + char(101), + char(100), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(82), + char(105), + char(103), + char(105), + char(100), + char(66), + char(111), + char(100), + char(121), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(80), + char(111), + char(105), + char(110), + char(116), + char(50), + char(80), + char(111), + char(105), + char(110), + char(116), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(80), + char(111), + char(105), + char(110), + char(116), + char(50), + char(80), + char(111), + char(105), + char(110), + char(116), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(72), + char(105), + char(110), + char(103), + char(101), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(72), + char(105), + char(110), + char(103), + char(101), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(110), + char(101), + char(84), + char(119), + char(105), + char(115), + char(116), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(71), + char(101), + char(110), + char(101), + char(114), + char(105), + char(99), + char(54), + char(68), + char(111), + char(102), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(71), + char(101), + char(110), + char(101), + char(114), + char(105), + char(99), + char(54), + char(68), + char(111), + char(102), + char(83), + char(112), + char(114), + char(105), + char(110), + char(103), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(83), + char(108), + char(105), + char(100), + char(101), + char(114), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(83), + char(111), + char(102), + char(116), + char(66), + char(111), + char(100), + char(121), + char(77), + char(97), + char(116), + char(101), + char(114), + char(105), + char(97), + char(108), + char(68), + char(97), + char(116), + char(97), + char(0), + char(83), + char(111), + char(102), + char(116), + char(66), + char(111), + char(100), + char(121), + char(78), + char(111), + char(100), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(83), + char(111), + char(102), + char(116), + char(66), + char(111), + char(100), + char(121), + char(76), + char(105), + char(110), + char(107), + char(68), + char(97), + char(116), + char(97), + char(0), + char(83), + char(111), + char(102), + char(116), + char(66), + char(111), + char(100), + char(121), + char(70), + char(97), + char(99), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(83), + char(111), + char(102), + char(116), + char(66), + char(111), + char(100), + char(121), + char(84), + char(101), + char(116), + char(114), + char(97), + char(68), + char(97), + char(116), + char(97), + char(0), + char(83), + char(111), + char(102), + char(116), + char(82), + char(105), + char(103), + char(105), + char(100), + char(65), + char(110), + char(99), + char(104), + char(111), + char(114), + char(68), + char(97), + char(116), + char(97), + char(0), + char(83), + char(111), + char(102), + char(116), + char(66), + char(111), + char(100), + char(121), + char(67), + char(111), + char(110), + char(102), + char(105), + char(103), + char(68), + char(97), + char(116), + char(97), + char(0), + char(83), + char(111), + char(102), + char(116), + char(66), + char(111), + char(100), + char(121), + char(80), + char(111), + char(115), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(83), + char(111), + char(102), + char(116), + char(66), + char(111), + char(100), + char(121), + char(67), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(83), + char(111), + char(102), + char(116), + char(66), + char(111), + char(100), + char(121), + char(74), + char(111), + char(105), + char(110), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(83), + char(111), + char(102), + char(116), + char(66), + char(111), + char(100), + char(121), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(0), + char(0), + char(84), + char(76), + char(69), + char(78), + char(1), + char(0), + char(1), + char(0), + char(2), + char(0), + char(2), + char(0), + char(4), + char(0), + char(4), + char(0), + char(4), + char(0), + char(4), + char(0), + char(8), + char(0), + char(0), + char(0), + char(12), + char(0), + char(36), + char(0), + char(8), + char(0), + char(16), + char(0), + char(32), + char(0), + char(48), + char(0), + char(96), + char(0), + char(64), + char(0), + char(-128), + char(0), + char(20), + char(0), + char(48), + char(0), + char(80), + char(0), + char(16), + char(0), + char(84), + char(0), + char(-124), + char(0), + char(12), + char(0), + char(52), + char(0), + char(52), + char(0), + char(20), + char(0), + char(64), + char(0), + char(4), + char(0), + char(4), + char(0), + char(8), + char(0), + char(4), + char(0), + char(32), + char(0), + char(28), + char(0), + char(60), + char(0), + char(56), + char(0), + char(76), + char(0), + char(76), + char(0), + char(24), + char(0), + char(60), + char(0), + char(60), + char(0), + char(16), + char(0), + char(64), + char(0), + char(68), + char(0), + char(-48), + char(1), + char(0), + char(1), + char(-72), + char(0), + char(-104), + char(0), + char(104), + char(0), + char(88), + char(0), + char(-24), + char(1), + char(-96), + char(3), + char(8), + char(0), + char(52), + char(0), + char(0), + char(0), + char(84), + char(0), + char(116), + char(0), + char(92), + char(1), + char(-36), + char(0), + char(-44), + char(0), + char(-4), + char(0), + char(92), + char(1), + char(-52), + char(0), + char(16), + char(0), + char(100), + char(0), + char(20), + char(0), + char(36), + char(0), + char(100), + char(0), + char(92), + char(0), + char(104), + char(0), + char(-64), + char(0), + char(92), + char(1), + char(104), + char(0), + char(-84), + char(1), + char(83), + char(84), + char(82), + char(67), + char(65), + char(0), + char(0), + char(0), + char(10), + char(0), + char(3), + char(0), + char(4), + char(0), + char(0), + char(0), + char(4), + char(0), + char(1), + char(0), + char(9), + char(0), + char(2), + char(0), + char(11), + char(0), + char(3), + char(0), + char(10), + char(0), + char(3), + char(0), + char(10), + char(0), + char(4), + char(0), + char(10), + char(0), + char(5), + char(0), + char(12), + char(0), + char(2), + char(0), + char(9), + char(0), + char(6), + char(0), + char(9), + char(0), + char(7), + char(0), + char(13), + char(0), + char(1), + char(0), + char(7), + char(0), + char(8), + char(0), + char(14), + char(0), + char(1), + char(0), + char(8), + char(0), + char(8), + char(0), + char(15), + char(0), + char(1), + char(0), + char(13), + char(0), + char(9), + char(0), + char(16), + char(0), + char(1), + char(0), + char(14), + char(0), + char(9), + char(0), + char(17), + char(0), + char(2), + char(0), + char(15), + char(0), + char(10), + char(0), + char(13), + char(0), + char(11), + char(0), + char(18), + char(0), + char(2), + char(0), + char(16), + char(0), + char(10), + char(0), + char(14), + char(0), + char(11), + char(0), + char(19), + char(0), + char(4), + char(0), + char(4), + char(0), + char(12), + char(0), + char(4), + char(0), + char(13), + char(0), + char(2), + char(0), + char(14), + char(0), + char(2), + char(0), + char(15), + char(0), + char(20), + char(0), + char(6), + char(0), + char(13), + char(0), + char(16), + char(0), + char(13), + char(0), + char(17), + char(0), + char(4), + char(0), + char(18), + char(0), + char(4), + char(0), + char(19), + char(0), + char(4), + char(0), + char(20), + char(0), + char(0), + char(0), + char(21), + char(0), + char(21), + char(0), + char(6), + char(0), + char(14), + char(0), + char(16), + char(0), + char(14), + char(0), + char(17), + char(0), + char(4), + char(0), + char(18), + char(0), + char(4), + char(0), + char(19), + char(0), + char(4), + char(0), + char(20), + char(0), + char(0), + char(0), + char(21), + char(0), + char(22), + char(0), + char(3), + char(0), + char(2), + char(0), + char(14), + char(0), + char(2), + char(0), + char(15), + char(0), + char(4), + char(0), + char(22), + char(0), + char(23), + char(0), + char(12), + char(0), + char(13), + char(0), + char(23), + char(0), + char(13), + char(0), + char(24), + char(0), + char(13), + char(0), + char(25), + char(0), + char(4), + char(0), + char(26), + char(0), + char(4), + char(0), + char(27), + char(0), + char(4), + char(0), + char(28), + char(0), + char(4), + char(0), + char(29), + char(0), + char(20), + char(0), + char(30), + char(0), + char(22), + char(0), + char(31), + char(0), + char(19), + char(0), + char(32), + char(0), + char(4), + char(0), + char(33), + char(0), + char(4), + char(0), + char(34), + char(0), + char(24), + char(0), + char(12), + char(0), + char(14), + char(0), + char(23), + char(0), + char(14), + char(0), + char(24), + char(0), + char(14), + char(0), + char(25), + char(0), + char(4), + char(0), + char(26), + char(0), + char(4), + char(0), + char(27), + char(0), + char(4), + char(0), + char(28), + char(0), + char(4), + char(0), + char(29), + char(0), + char(21), + char(0), + char(30), + char(0), + char(22), + char(0), + char(31), + char(0), + char(4), + char(0), + char(33), + char(0), + char(4), + char(0), + char(34), + char(0), + char(19), + char(0), + char(32), + char(0), + char(25), + char(0), + char(3), + char(0), + char(0), + char(0), + char(35), + char(0), + char(4), + char(0), + char(36), + char(0), + char(0), + char(0), + char(37), + char(0), + char(26), + char(0), + char(5), + char(0), + char(25), + char(0), + char(38), + char(0), + char(13), + char(0), + char(39), + char(0), + char(13), + char(0), + char(40), + char(0), + char(7), + char(0), + char(41), + char(0), + char(0), + char(0), + char(21), + char(0), + char(27), + char(0), + char(5), + char(0), + char(25), + char(0), + char(38), + char(0), + char(13), + char(0), + char(39), + char(0), + char(13), + char(0), + char(42), + char(0), + char(7), + char(0), + char(43), + char(0), + char(4), + char(0), + char(44), + char(0), + char(28), + char(0), + char(2), + char(0), + char(13), + char(0), + char(45), + char(0), + char(7), + char(0), + char(46), + char(0), + char(29), + char(0), + char(4), + char(0), + char(27), + char(0), + char(47), + char(0), + char(28), + char(0), + char(48), + char(0), + char(4), + char(0), + char(49), + char(0), + char(0), + char(0), + char(37), + char(0), + char(30), + char(0), + char(1), + char(0), + char(4), + char(0), + char(50), + char(0), + char(31), + char(0), + char(2), + char(0), + char(2), + char(0), + char(50), + char(0), + char(0), + char(0), + char(51), + char(0), + char(32), + char(0), + char(2), + char(0), + char(2), + char(0), + char(52), + char(0), + char(0), + char(0), + char(51), + char(0), + char(33), + char(0), + char(2), + char(0), + char(0), + char(0), + char(52), + char(0), + char(0), + char(0), + char(53), + char(0), + char(34), + char(0), + char(8), + char(0), + char(13), + char(0), + char(54), + char(0), + char(14), + char(0), + char(55), + char(0), + char(30), + char(0), + char(56), + char(0), + char(32), + char(0), + char(57), + char(0), + char(33), + char(0), + char(58), + char(0), + char(31), + char(0), + char(59), + char(0), + char(4), + char(0), + char(60), + char(0), + char(4), + char(0), + char(61), + char(0), + char(35), + char(0), + char(4), + char(0), + char(34), + char(0), + char(62), + char(0), + char(13), + char(0), + char(63), + char(0), + char(4), + char(0), + char(64), + char(0), + char(0), + char(0), + char(37), + char(0), + char(36), + char(0), + char(7), + char(0), + char(25), + char(0), + char(38), + char(0), + char(35), + char(0), + char(65), + char(0), + char(23), + char(0), + char(66), + char(0), + char(24), + char(0), + char(67), + char(0), + char(37), + char(0), + char(68), + char(0), + char(7), + char(0), + char(43), + char(0), + char(0), + char(0), + char(69), + char(0), + char(38), + char(0), + char(2), + char(0), + char(36), + char(0), + char(70), + char(0), + char(13), + char(0), + char(39), + char(0), + char(39), + char(0), + char(4), + char(0), + char(17), + char(0), + char(71), + char(0), + char(25), + char(0), + char(72), + char(0), + char(4), + char(0), + char(73), + char(0), + char(7), + char(0), + char(74), + char(0), + char(40), + char(0), + char(4), + char(0), + char(25), + char(0), + char(38), + char(0), + char(39), + char(0), + char(75), + char(0), + char(4), + char(0), + char(76), + char(0), + char(7), + char(0), + char(43), + char(0), + char(41), + char(0), + char(3), + char(0), + char(27), + char(0), + char(47), + char(0), + char(4), + char(0), + char(77), + char(0), + char(0), + char(0), + char(37), + char(0), + char(42), + char(0), + char(3), + char(0), + char(27), + char(0), + char(47), + char(0), + char(4), + char(0), + char(77), + char(0), + char(0), + char(0), + char(37), + char(0), + char(43), + char(0), + char(4), + char(0), + char(4), + char(0), + char(78), + char(0), + char(7), + char(0), + char(79), + char(0), + char(7), + char(0), + char(80), + char(0), + char(7), + char(0), + char(81), + char(0), + char(37), + char(0), + char(14), + char(0), + char(4), + char(0), + char(82), + char(0), + char(4), + char(0), + char(83), + char(0), + char(43), + char(0), + char(84), + char(0), + char(4), + char(0), + char(85), + char(0), + char(7), + char(0), + char(86), + char(0), + char(7), + char(0), + char(87), + char(0), + char(7), + char(0), + char(88), + char(0), + char(7), + char(0), + char(89), + char(0), + char(7), + char(0), + char(90), + char(0), + char(4), + char(0), + char(91), + char(0), + char(4), + char(0), + char(92), + char(0), + char(4), + char(0), + char(93), + char(0), + char(4), + char(0), + char(94), + char(0), + char(0), + char(0), + char(37), + char(0), + char(44), + char(0), + char(5), + char(0), + char(25), + char(0), + char(38), + char(0), + char(35), + char(0), + char(65), + char(0), + char(13), + char(0), + char(39), + char(0), + char(7), + char(0), + char(43), + char(0), + char(4), + char(0), + char(95), + char(0), + char(45), + char(0), + char(5), + char(0), + char(27), + char(0), + char(47), + char(0), + char(13), + char(0), + char(96), + char(0), + char(14), + char(0), + char(97), + char(0), + char(4), + char(0), + char(98), + char(0), + char(0), + char(0), + char(99), + char(0), + char(46), + char(0), + char(25), + char(0), + char(9), + char(0), + char(100), + char(0), + char(9), + char(0), + char(101), + char(0), + char(25), + char(0), + char(102), + char(0), + char(0), + char(0), + char(35), + char(0), + char(18), + char(0), + char(103), + char(0), + char(18), + char(0), + char(104), + char(0), + char(14), + char(0), + char(105), + char(0), + char(14), + char(0), + char(106), + char(0), + char(14), + char(0), + char(107), + char(0), + char(8), + char(0), + char(108), + char(0), + char(8), + char(0), + char(109), + char(0), + char(8), + char(0), + char(110), + char(0), + char(8), + char(0), + char(111), + char(0), + char(8), + char(0), + char(112), + char(0), + char(8), + char(0), + char(113), + char(0), + char(8), + char(0), + char(114), + char(0), + char(8), + char(0), + char(115), + char(0), + char(4), + char(0), + char(116), + char(0), + char(4), + char(0), + char(117), + char(0), + char(4), + char(0), + char(118), + char(0), + char(4), + char(0), + char(119), + char(0), + char(4), + char(0), + char(120), + char(0), + char(4), + char(0), + char(121), + char(0), + char(4), + char(0), + char(122), + char(0), + char(0), + char(0), + char(37), + char(0), + char(47), + char(0), + char(25), + char(0), + char(9), + char(0), + char(100), + char(0), + char(9), + char(0), + char(101), + char(0), + char(25), + char(0), + char(102), + char(0), + char(0), + char(0), + char(35), + char(0), + char(17), + char(0), + char(103), + char(0), + char(17), + char(0), + char(104), + char(0), + char(13), + char(0), + char(105), + char(0), + char(13), + char(0), + char(106), + char(0), + char(13), + char(0), + char(107), + char(0), + char(7), + char(0), + char(108), + char(0), + char(7), + char(0), + char(109), + char(0), + char(7), + char(0), + char(110), + char(0), + char(7), + char(0), + char(111), + char(0), + char(7), + char(0), + char(112), + char(0), + char(7), + char(0), + char(113), + char(0), + char(7), + char(0), + char(114), + char(0), + char(7), + char(0), + char(115), + char(0), + char(4), + char(0), + char(116), + char(0), + char(4), + char(0), + char(117), + char(0), + char(4), + char(0), + char(118), + char(0), + char(4), + char(0), + char(119), + char(0), + char(4), + char(0), + char(120), + char(0), + char(4), + char(0), + char(121), + char(0), + char(4), + char(0), + char(122), + char(0), + char(0), + char(0), + char(37), + char(0), + char(48), + char(0), + char(2), + char(0), + char(49), + char(0), + char(123), + char(0), + char(14), + char(0), + char(124), + char(0), + char(50), + char(0), + char(2), + char(0), + char(51), + char(0), + char(123), + char(0), + char(13), + char(0), + char(124), + char(0), + char(52), + char(0), + char(21), + char(0), + char(47), + char(0), + char(125), + char(0), + char(15), + char(0), + char(126), + char(0), + char(13), + char(0), + char(127), + char(0), + char(13), + char(0), + char(-128), + char(0), + char(13), + char(0), + char(-127), + char(0), + char(13), + char(0), + char(-126), + char(0), + char(13), + char(0), + char(124), + char(0), + char(13), + char(0), + char(-125), + char(0), + char(13), + char(0), + char(-124), + char(0), + char(13), + char(0), + char(-123), + char(0), + char(13), + char(0), + char(-122), + char(0), + char(7), + char(0), + char(-121), + char(0), + char(7), + char(0), + char(-120), + char(0), + char(7), + char(0), + char(-119), + char(0), + char(7), + char(0), + char(-118), + char(0), + char(7), + char(0), + char(-117), + char(0), + char(7), + char(0), + char(-116), + char(0), + char(7), + char(0), + char(-115), + char(0), + char(7), + char(0), + char(-114), + char(0), + char(7), + char(0), + char(-113), + char(0), + char(4), + char(0), + char(-112), + char(0), + char(53), + char(0), + char(22), + char(0), + char(46), + char(0), + char(125), + char(0), + char(16), + char(0), + char(126), + char(0), + char(14), + char(0), + char(127), + char(0), + char(14), + char(0), + char(-128), + char(0), + char(14), + char(0), + char(-127), + char(0), + char(14), + char(0), + char(-126), + char(0), + char(14), + char(0), + char(124), + char(0), + char(14), + char(0), + char(-125), + char(0), + char(14), + char(0), + char(-124), + char(0), + char(14), + char(0), + char(-123), + char(0), + char(14), + char(0), + char(-122), + char(0), + char(8), + char(0), + char(-121), + char(0), + char(8), + char(0), + char(-120), + char(0), + char(8), + char(0), + char(-119), + char(0), + char(8), + char(0), + char(-118), + char(0), + char(8), + char(0), + char(-117), + char(0), + char(8), + char(0), + char(-116), + char(0), + char(8), + char(0), + char(-115), + char(0), + char(8), + char(0), + char(-114), + char(0), + char(8), + char(0), + char(-113), + char(0), + char(4), + char(0), + char(-112), + char(0), + char(0), + char(0), + char(37), + char(0), + char(54), + char(0), + char(2), + char(0), + char(4), + char(0), + char(-111), + char(0), + char(4), + char(0), + char(-110), + char(0), + char(55), + char(0), + char(13), + char(0), + char(56), + char(0), + char(-109), + char(0), + char(56), + char(0), + char(-108), + char(0), + char(0), + char(0), + char(35), + char(0), + char(4), + char(0), + char(-107), + char(0), + char(4), + char(0), + char(-106), + char(0), + char(4), + char(0), + char(-105), + char(0), + char(4), + char(0), + char(-104), + char(0), + char(7), + char(0), + char(-103), + char(0), + char(7), + char(0), + char(-102), + char(0), + char(4), + char(0), + char(-101), + char(0), + char(4), + char(0), + char(-100), + char(0), + char(7), + char(0), + char(-99), + char(0), + char(4), + char(0), + char(-98), + char(0), + char(57), + char(0), + char(3), + char(0), + char(55), + char(0), + char(-97), + char(0), + char(13), + char(0), + char(-96), + char(0), + char(13), + char(0), + char(-95), + char(0), + char(58), + char(0), + char(3), + char(0), + char(55), + char(0), + char(-97), + char(0), + char(14), + char(0), + char(-96), + char(0), + char(14), + char(0), + char(-95), + char(0), + char(59), + char(0), + char(13), + char(0), + char(55), + char(0), + char(-97), + char(0), + char(18), + char(0), + char(-94), + char(0), + char(18), + char(0), + char(-93), + char(0), + char(4), + char(0), + char(-92), + char(0), + char(4), + char(0), + char(-91), + char(0), + char(4), + char(0), + char(-90), + char(0), + char(7), + char(0), + char(-89), + char(0), + char(7), + char(0), + char(-88), + char(0), + char(7), + char(0), + char(-87), + char(0), + char(7), + char(0), + char(-86), + char(0), + char(7), + char(0), + char(-85), + char(0), + char(7), + char(0), + char(-84), + char(0), + char(7), + char(0), + char(-83), + char(0), + char(60), + char(0), + char(13), + char(0), + char(55), + char(0), + char(-97), + char(0), + char(17), + char(0), + char(-94), + char(0), + char(17), + char(0), + char(-93), + char(0), + char(4), + char(0), + char(-92), + char(0), + char(4), + char(0), + char(-91), + char(0), + char(4), + char(0), + char(-90), + char(0), + char(7), + char(0), + char(-89), + char(0), + char(7), + char(0), + char(-88), + char(0), + char(7), + char(0), + char(-87), + char(0), + char(7), + char(0), + char(-86), + char(0), + char(7), + char(0), + char(-85), + char(0), + char(7), + char(0), + char(-84), + char(0), + char(7), + char(0), + char(-83), + char(0), + char(61), + char(0), + char(11), + char(0), + char(55), + char(0), + char(-97), + char(0), + char(17), + char(0), + char(-94), + char(0), + char(17), + char(0), + char(-93), + char(0), + char(7), + char(0), + char(-82), + char(0), + char(7), + char(0), + char(-81), + char(0), + char(7), + char(0), + char(-80), + char(0), + char(7), + char(0), + char(-85), + char(0), + char(7), + char(0), + char(-84), + char(0), + char(7), + char(0), + char(-83), + char(0), + char(7), + char(0), + char(-79), + char(0), + char(0), + char(0), + char(21), + char(0), + char(62), + char(0), + char(9), + char(0), + char(55), + char(0), + char(-97), + char(0), + char(17), + char(0), + char(-94), + char(0), + char(17), + char(0), + char(-93), + char(0), + char(13), + char(0), + char(-78), + char(0), + char(13), + char(0), + char(-77), + char(0), + char(13), + char(0), + char(-76), + char(0), + char(13), + char(0), + char(-75), + char(0), + char(4), + char(0), + char(-74), + char(0), + char(4), + char(0), + char(-73), + char(0), + char(63), + char(0), + char(5), + char(0), + char(62), + char(0), + char(-72), + char(0), + char(4), + char(0), + char(-71), + char(0), + char(7), + char(0), + char(-70), + char(0), + char(7), + char(0), + char(-69), + char(0), + char(7), + char(0), + char(-68), + char(0), + char(64), + char(0), + char(9), + char(0), + char(55), + char(0), + char(-97), + char(0), + char(17), + char(0), + char(-94), + char(0), + char(17), + char(0), + char(-93), + char(0), + char(7), + char(0), + char(-78), + char(0), + char(7), + char(0), + char(-77), + char(0), + char(7), + char(0), + char(-76), + char(0), + char(7), + char(0), + char(-75), + char(0), + char(4), + char(0), + char(-74), + char(0), + char(4), + char(0), + char(-73), + char(0), + char(49), + char(0), + char(22), + char(0), + char(8), + char(0), + char(-67), + char(0), + char(8), + char(0), + char(-79), + char(0), + char(8), + char(0), + char(110), + char(0), + char(8), + char(0), + char(-66), + char(0), + char(8), + char(0), + char(112), + char(0), + char(8), + char(0), + char(-65), + char(0), + char(8), + char(0), + char(-64), + char(0), + char(8), + char(0), + char(-63), + char(0), + char(8), + char(0), + char(-62), + char(0), + char(8), + char(0), + char(-61), + char(0), + char(8), + char(0), + char(-60), + char(0), + char(8), + char(0), + char(-59), + char(0), + char(8), + char(0), + char(-58), + char(0), + char(8), + char(0), + char(-57), + char(0), + char(8), + char(0), + char(-56), + char(0), + char(8), + char(0), + char(-55), + char(0), + char(4), + char(0), + char(-54), + char(0), + char(4), + char(0), + char(-53), + char(0), + char(4), + char(0), + char(-52), + char(0), + char(4), + char(0), + char(-51), + char(0), + char(4), + char(0), + char(-50), + char(0), + char(0), + char(0), + char(37), + char(0), + char(51), + char(0), + char(22), + char(0), + char(7), + char(0), + char(-67), + char(0), + char(7), + char(0), + char(-79), + char(0), + char(7), + char(0), + char(110), + char(0), + char(7), + char(0), + char(-66), + char(0), + char(7), + char(0), + char(112), + char(0), + char(7), + char(0), + char(-65), + char(0), + char(7), + char(0), + char(-64), + char(0), + char(7), + char(0), + char(-63), + char(0), + char(7), + char(0), + char(-62), + char(0), + char(7), + char(0), + char(-61), + char(0), + char(7), + char(0), + char(-60), + char(0), + char(7), + char(0), + char(-59), + char(0), + char(7), + char(0), + char(-58), + char(0), + char(7), + char(0), + char(-57), + char(0), + char(7), + char(0), + char(-56), + char(0), + char(7), + char(0), + char(-55), + char(0), + char(4), + char(0), + char(-54), + char(0), + char(4), + char(0), + char(-53), + char(0), + char(4), + char(0), + char(-52), + char(0), + char(4), + char(0), + char(-51), + char(0), + char(4), + char(0), + char(-50), + char(0), + char(0), + char(0), + char(37), + char(0), + char(65), + char(0), + char(4), + char(0), + char(7), + char(0), + char(-49), + char(0), + char(7), + char(0), + char(-48), + char(0), + char(7), + char(0), + char(-47), + char(0), + char(4), + char(0), + char(78), + char(0), + char(66), + char(0), + char(10), + char(0), + char(65), + char(0), + char(-46), + char(0), + char(13), + char(0), + char(-45), + char(0), + char(13), + char(0), + char(-44), + char(0), + char(13), + char(0), + char(-43), + char(0), + char(13), + char(0), + char(-42), + char(0), + char(13), + char(0), + char(-41), + char(0), + char(7), + char(0), + char(-121), + char(0), + char(7), + char(0), + char(-40), + char(0), + char(4), + char(0), + char(-39), + char(0), + char(4), + char(0), + char(53), + char(0), + char(67), + char(0), + char(4), + char(0), + char(65), + char(0), + char(-46), + char(0), + char(4), + char(0), + char(-38), + char(0), + char(7), + char(0), + char(-37), + char(0), + char(4), + char(0), + char(-36), + char(0), + char(68), + char(0), + char(4), + char(0), + char(13), + char(0), + char(-41), + char(0), + char(65), + char(0), + char(-46), + char(0), + char(4), + char(0), + char(-35), + char(0), + char(7), + char(0), + char(-34), + char(0), + char(69), + char(0), + char(7), + char(0), + char(13), + char(0), + char(-33), + char(0), + char(65), + char(0), + char(-46), + char(0), + char(4), + char(0), + char(-32), + char(0), + char(7), + char(0), + char(-31), + char(0), + char(7), + char(0), + char(-30), + char(0), + char(7), + char(0), + char(-29), + char(0), + char(4), + char(0), + char(53), + char(0), + char(70), + char(0), + char(6), + char(0), + char(15), + char(0), + char(-28), + char(0), + char(13), + char(0), + char(-30), + char(0), + char(13), + char(0), + char(-27), + char(0), + char(56), + char(0), + char(-26), + char(0), + char(4), + char(0), + char(-25), + char(0), + char(7), + char(0), + char(-29), + char(0), + char(71), + char(0), + char(26), + char(0), + char(4), + char(0), + char(-24), + char(0), + char(7), + char(0), + char(-23), + char(0), + char(7), + char(0), + char(-79), + char(0), + char(7), + char(0), + char(-22), + char(0), + char(7), + char(0), + char(-21), + char(0), + char(7), + char(0), + char(-20), + char(0), + char(7), + char(0), + char(-19), + char(0), + char(7), + char(0), + char(-18), + char(0), + char(7), + char(0), + char(-17), + char(0), + char(7), + char(0), + char(-16), + char(0), + char(7), + char(0), + char(-15), + char(0), + char(7), + char(0), + char(-14), + char(0), + char(7), + char(0), + char(-13), + char(0), + char(7), + char(0), + char(-12), + char(0), + char(7), + char(0), + char(-11), + char(0), + char(7), + char(0), + char(-10), + char(0), + char(7), + char(0), + char(-9), + char(0), + char(7), + char(0), + char(-8), + char(0), + char(7), + char(0), + char(-7), + char(0), + char(7), + char(0), + char(-6), + char(0), + char(7), + char(0), + char(-5), + char(0), + char(4), + char(0), + char(-4), + char(0), + char(4), + char(0), + char(-3), + char(0), + char(4), + char(0), + char(-2), + char(0), + char(4), + char(0), + char(-1), + char(0), + char(4), + char(0), + char(117), + char(0), + char(72), + char(0), + char(12), + char(0), + char(15), + char(0), + char(0), + char(1), + char(15), + char(0), + char(1), + char(1), + char(15), + char(0), + char(2), + char(1), + char(13), + char(0), + char(3), + char(1), + char(13), + char(0), + char(4), + char(1), + char(7), + char(0), + char(5), + char(1), + char(4), + char(0), + char(6), + char(1), + char(4), + char(0), + char(7), + char(1), + char(4), + char(0), + char(8), + char(1), + char(4), + char(0), + char(9), + char(1), + char(7), + char(0), + char(-31), + char(0), + char(4), + char(0), + char(53), + char(0), + char(73), + char(0), + char(27), + char(0), + char(17), + char(0), + char(10), + char(1), + char(15), + char(0), + char(11), + char(1), + char(15), + char(0), + char(12), + char(1), + char(13), + char(0), + char(3), + char(1), + char(13), + char(0), + char(13), + char(1), + char(13), + char(0), + char(14), + char(1), + char(13), + char(0), + char(15), + char(1), + char(13), + char(0), + char(16), + char(1), + char(13), + char(0), + char(17), + char(1), + char(4), + char(0), + char(18), + char(1), + char(7), + char(0), + char(19), + char(1), + char(4), + char(0), + char(20), + char(1), + char(4), + char(0), + char(21), + char(1), + char(4), + char(0), + char(22), + char(1), + char(7), + char(0), + char(23), + char(1), + char(7), + char(0), + char(24), + char(1), + char(4), + char(0), + char(25), + char(1), + char(4), + char(0), + char(26), + char(1), + char(7), + char(0), + char(27), + char(1), + char(7), + char(0), + char(28), + char(1), + char(7), + char(0), + char(29), + char(1), + char(7), + char(0), + char(30), + char(1), + char(7), + char(0), + char(31), + char(1), + char(7), + char(0), + char(32), + char(1), + char(4), + char(0), + char(33), + char(1), + char(4), + char(0), + char(34), + char(1), + char(4), + char(0), + char(35), + char(1), + char(74), + char(0), + char(12), + char(0), + char(9), + char(0), + char(36), + char(1), + char(9), + char(0), + char(37), + char(1), + char(13), + char(0), + char(38), + char(1), + char(7), + char(0), + char(39), + char(1), + char(7), + char(0), + char(-63), + char(0), + char(7), + char(0), + char(40), + char(1), + char(4), + char(0), + char(41), + char(1), + char(13), + char(0), + char(42), + char(1), + char(4), + char(0), + char(43), + char(1), + char(4), + char(0), + char(44), + char(1), + char(4), + char(0), + char(45), + char(1), + char(4), + char(0), + char(53), + char(0), + char(75), + char(0), + char(19), + char(0), + char(47), + char(0), + char(125), + char(0), + char(72), + char(0), + char(46), + char(1), + char(65), + char(0), + char(47), + char(1), + char(66), + char(0), + char(48), + char(1), + char(67), + char(0), + char(49), + char(1), + char(68), + char(0), + char(50), + char(1), + char(69), + char(0), + char(51), + char(1), + char(70), + char(0), + char(52), + char(1), + char(73), + char(0), + char(53), + char(1), + char(74), + char(0), + char(54), + char(1), + char(4), + char(0), + char(55), + char(1), + char(4), + char(0), + char(21), + char(1), + char(4), + char(0), + char(56), + char(1), + char(4), + char(0), + char(57), + char(1), + char(4), + char(0), + char(58), + char(1), + char(4), + char(0), + char(59), + char(1), + char(4), + char(0), + char(60), + char(1), + char(4), + char(0), + char(61), + char(1), + char(71), + char(0), + char(62), + char(1), +}; +int b3s_bulletDNAlen = sizeof(b3s_bulletDNAstr); +char b3s_bulletDNAstr64[] = { + char(83), + char(68), + char(78), + char(65), + char(78), + char(65), + char(77), + char(69), + char(63), + char(1), + char(0), + char(0), + char(109), + char(95), + char(115), + char(105), + char(122), + char(101), + char(0), + char(109), + char(95), + char(99), + char(97), + char(112), + char(97), + char(99), + char(105), + char(116), + char(121), + char(0), + char(42), + char(109), + char(95), + char(100), + char(97), + char(116), + char(97), + char(0), + char(109), + char(95), + char(99), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(83), + char(104), + char(97), + char(112), + char(101), + char(115), + char(0), + char(109), + char(95), + char(99), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(79), + char(98), + char(106), + char(101), + char(99), + char(116), + char(115), + char(0), + char(109), + char(95), + char(99), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(115), + char(0), + char(42), + char(102), + char(105), + char(114), + char(115), + char(116), + char(0), + char(42), + char(108), + char(97), + char(115), + char(116), + char(0), + char(109), + char(95), + char(102), + char(108), + char(111), + char(97), + char(116), + char(115), + char(91), + char(52), + char(93), + char(0), + char(109), + char(95), + char(101), + char(108), + char(91), + char(51), + char(93), + char(0), + char(109), + char(95), + char(98), + char(97), + char(115), + char(105), + char(115), + char(0), + char(109), + char(95), + char(111), + char(114), + char(105), + char(103), + char(105), + char(110), + char(0), + char(109), + char(95), + char(114), + char(111), + char(111), + char(116), + char(78), + char(111), + char(100), + char(101), + char(73), + char(110), + char(100), + char(101), + char(120), + char(0), + char(109), + char(95), + char(115), + char(117), + char(98), + char(116), + char(114), + char(101), + char(101), + char(83), + char(105), + char(122), + char(101), + char(0), + char(109), + char(95), + char(113), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(101), + char(100), + char(65), + char(97), + char(98), + char(98), + char(77), + char(105), + char(110), + char(91), + char(51), + char(93), + char(0), + char(109), + char(95), + char(113), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(101), + char(100), + char(65), + char(97), + char(98), + char(98), + char(77), + char(97), + char(120), + char(91), + char(51), + char(93), + char(0), + char(109), + char(95), + char(97), + char(97), + char(98), + char(98), + char(77), + char(105), + char(110), + char(79), + char(114), + char(103), + char(0), + char(109), + char(95), + char(97), + char(97), + char(98), + char(98), + char(77), + char(97), + char(120), + char(79), + char(114), + char(103), + char(0), + char(109), + char(95), + char(101), + char(115), + char(99), + char(97), + char(112), + char(101), + char(73), + char(110), + char(100), + char(101), + char(120), + char(0), + char(109), + char(95), + char(115), + char(117), + char(98), + char(80), + char(97), + char(114), + char(116), + char(0), + char(109), + char(95), + char(116), + char(114), + char(105), + char(97), + char(110), + char(103), + char(108), + char(101), + char(73), + char(110), + char(100), + char(101), + char(120), + char(0), + char(109), + char(95), + char(112), + char(97), + char(100), + char(91), + char(52), + char(93), + char(0), + char(109), + char(95), + char(101), + char(115), + char(99), + char(97), + char(112), + char(101), + char(73), + char(110), + char(100), + char(101), + char(120), + char(79), + char(114), + char(84), + char(114), + char(105), + char(97), + char(110), + char(103), + char(108), + char(101), + char(73), + char(110), + char(100), + char(101), + char(120), + char(0), + char(109), + char(95), + char(98), + char(118), + char(104), + char(65), + char(97), + char(98), + char(98), + char(77), + char(105), + char(110), + char(0), + char(109), + char(95), + char(98), + char(118), + char(104), + char(65), + char(97), + char(98), + char(98), + char(77), + char(97), + char(120), + char(0), + char(109), + char(95), + char(98), + char(118), + char(104), + char(81), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(97), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(99), + char(117), + char(114), + char(78), + char(111), + char(100), + char(101), + char(73), + char(110), + char(100), + char(101), + char(120), + char(0), + char(109), + char(95), + char(117), + char(115), + char(101), + char(81), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(97), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(67), + char(111), + char(110), + char(116), + char(105), + char(103), + char(117), + char(111), + char(117), + char(115), + char(76), + char(101), + char(97), + char(102), + char(78), + char(111), + char(100), + char(101), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(81), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(101), + char(100), + char(67), + char(111), + char(110), + char(116), + char(105), + char(103), + char(117), + char(111), + char(117), + char(115), + char(78), + char(111), + char(100), + char(101), + char(115), + char(0), + char(42), + char(109), + char(95), + char(99), + char(111), + char(110), + char(116), + char(105), + char(103), + char(117), + char(111), + char(117), + char(115), + char(78), + char(111), + char(100), + char(101), + char(115), + char(80), + char(116), + char(114), + char(0), + char(42), + char(109), + char(95), + char(113), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(101), + char(100), + char(67), + char(111), + char(110), + char(116), + char(105), + char(103), + char(117), + char(111), + char(117), + char(115), + char(78), + char(111), + char(100), + char(101), + char(115), + char(80), + char(116), + char(114), + char(0), + char(42), + char(109), + char(95), + char(115), + char(117), + char(98), + char(84), + char(114), + char(101), + char(101), + char(73), + char(110), + char(102), + char(111), + char(80), + char(116), + char(114), + char(0), + char(109), + char(95), + char(116), + char(114), + char(97), + char(118), + char(101), + char(114), + char(115), + char(97), + char(108), + char(77), + char(111), + char(100), + char(101), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(83), + char(117), + char(98), + char(116), + char(114), + char(101), + char(101), + char(72), + char(101), + char(97), + char(100), + char(101), + char(114), + char(115), + char(0), + char(42), + char(109), + char(95), + char(110), + char(97), + char(109), + char(101), + char(0), + char(109), + char(95), + char(115), + char(104), + char(97), + char(112), + char(101), + char(84), + char(121), + char(112), + char(101), + char(0), + char(109), + char(95), + char(112), + char(97), + char(100), + char(100), + char(105), + char(110), + char(103), + char(91), + char(52), + char(93), + char(0), + char(109), + char(95), + char(99), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(109), + char(95), + char(108), + char(111), + char(99), + char(97), + char(108), + char(83), + char(99), + char(97), + char(108), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(112), + char(108), + char(97), + char(110), + char(101), + char(78), + char(111), + char(114), + char(109), + char(97), + char(108), + char(0), + char(109), + char(95), + char(112), + char(108), + char(97), + char(110), + char(101), + char(67), + char(111), + char(110), + char(115), + char(116), + char(97), + char(110), + char(116), + char(0), + char(109), + char(95), + char(105), + char(109), + char(112), + char(108), + char(105), + char(99), + char(105), + char(116), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(105), + char(109), + char(101), + char(110), + char(115), + char(105), + char(111), + char(110), + char(115), + char(0), + char(109), + char(95), + char(99), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(77), + char(97), + char(114), + char(103), + char(105), + char(110), + char(0), + char(109), + char(95), + char(112), + char(97), + char(100), + char(100), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(112), + char(111), + char(115), + char(0), + char(109), + char(95), + char(114), + char(97), + char(100), + char(105), + char(117), + char(115), + char(0), + char(109), + char(95), + char(99), + char(111), + char(110), + char(118), + char(101), + char(120), + char(73), + char(110), + char(116), + char(101), + char(114), + char(110), + char(97), + char(108), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(42), + char(109), + char(95), + char(108), + char(111), + char(99), + char(97), + char(108), + char(80), + char(111), + char(115), + char(105), + char(116), + char(105), + char(111), + char(110), + char(65), + char(114), + char(114), + char(97), + char(121), + char(80), + char(116), + char(114), + char(0), + char(109), + char(95), + char(108), + char(111), + char(99), + char(97), + char(108), + char(80), + char(111), + char(115), + char(105), + char(116), + char(105), + char(111), + char(110), + char(65), + char(114), + char(114), + char(97), + char(121), + char(83), + char(105), + char(122), + char(101), + char(0), + char(109), + char(95), + char(118), + char(97), + char(108), + char(117), + char(101), + char(0), + char(109), + char(95), + char(112), + char(97), + char(100), + char(91), + char(50), + char(93), + char(0), + char(109), + char(95), + char(118), + char(97), + char(108), + char(117), + char(101), + char(115), + char(91), + char(51), + char(93), + char(0), + char(109), + char(95), + char(112), + char(97), + char(100), + char(0), + char(42), + char(109), + char(95), + char(118), + char(101), + char(114), + char(116), + char(105), + char(99), + char(101), + char(115), + char(51), + char(102), + char(0), + char(42), + char(109), + char(95), + char(118), + char(101), + char(114), + char(116), + char(105), + char(99), + char(101), + char(115), + char(51), + char(100), + char(0), + char(42), + char(109), + char(95), + char(105), + char(110), + char(100), + char(105), + char(99), + char(101), + char(115), + char(51), + char(50), + char(0), + char(42), + char(109), + char(95), + char(51), + char(105), + char(110), + char(100), + char(105), + char(99), + char(101), + char(115), + char(49), + char(54), + char(0), + char(42), + char(109), + char(95), + char(51), + char(105), + char(110), + char(100), + char(105), + char(99), + char(101), + char(115), + char(56), + char(0), + char(42), + char(109), + char(95), + char(105), + char(110), + char(100), + char(105), + char(99), + char(101), + char(115), + char(49), + char(54), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(84), + char(114), + char(105), + char(97), + char(110), + char(103), + char(108), + char(101), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(86), + char(101), + char(114), + char(116), + char(105), + char(99), + char(101), + char(115), + char(0), + char(42), + char(109), + char(95), + char(109), + char(101), + char(115), + char(104), + char(80), + char(97), + char(114), + char(116), + char(115), + char(80), + char(116), + char(114), + char(0), + char(109), + char(95), + char(115), + char(99), + char(97), + char(108), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(77), + char(101), + char(115), + char(104), + char(80), + char(97), + char(114), + char(116), + char(115), + char(0), + char(109), + char(95), + char(109), + char(101), + char(115), + char(104), + char(73), + char(110), + char(116), + char(101), + char(114), + char(102), + char(97), + char(99), + char(101), + char(0), + char(42), + char(109), + char(95), + char(113), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(101), + char(100), + char(70), + char(108), + char(111), + char(97), + char(116), + char(66), + char(118), + char(104), + char(0), + char(42), + char(109), + char(95), + char(113), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(101), + char(100), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(66), + char(118), + char(104), + char(0), + char(42), + char(109), + char(95), + char(116), + char(114), + char(105), + char(97), + char(110), + char(103), + char(108), + char(101), + char(73), + char(110), + char(102), + char(111), + char(77), + char(97), + char(112), + char(0), + char(109), + char(95), + char(112), + char(97), + char(100), + char(51), + char(91), + char(52), + char(93), + char(0), + char(109), + char(95), + char(116), + char(114), + char(105), + char(109), + char(101), + char(115), + char(104), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(109), + char(95), + char(116), + char(114), + char(97), + char(110), + char(115), + char(102), + char(111), + char(114), + char(109), + char(0), + char(42), + char(109), + char(95), + char(99), + char(104), + char(105), + char(108), + char(100), + char(83), + char(104), + char(97), + char(112), + char(101), + char(0), + char(109), + char(95), + char(99), + char(104), + char(105), + char(108), + char(100), + char(83), + char(104), + char(97), + char(112), + char(101), + char(84), + char(121), + char(112), + char(101), + char(0), + char(109), + char(95), + char(99), + char(104), + char(105), + char(108), + char(100), + char(77), + char(97), + char(114), + char(103), + char(105), + char(110), + char(0), + char(42), + char(109), + char(95), + char(99), + char(104), + char(105), + char(108), + char(100), + char(83), + char(104), + char(97), + char(112), + char(101), + char(80), + char(116), + char(114), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(67), + char(104), + char(105), + char(108), + char(100), + char(83), + char(104), + char(97), + char(112), + char(101), + char(115), + char(0), + char(109), + char(95), + char(117), + char(112), + char(65), + char(120), + char(105), + char(115), + char(0), + char(109), + char(95), + char(102), + char(108), + char(97), + char(103), + char(115), + char(0), + char(109), + char(95), + char(101), + char(100), + char(103), + char(101), + char(86), + char(48), + char(86), + char(49), + char(65), + char(110), + char(103), + char(108), + char(101), + char(0), + char(109), + char(95), + char(101), + char(100), + char(103), + char(101), + char(86), + char(49), + char(86), + char(50), + char(65), + char(110), + char(103), + char(108), + char(101), + char(0), + char(109), + char(95), + char(101), + char(100), + char(103), + char(101), + char(86), + char(50), + char(86), + char(48), + char(65), + char(110), + char(103), + char(108), + char(101), + char(0), + char(42), + char(109), + char(95), + char(104), + char(97), + char(115), + char(104), + char(84), + char(97), + char(98), + char(108), + char(101), + char(80), + char(116), + char(114), + char(0), + char(42), + char(109), + char(95), + char(110), + char(101), + char(120), + char(116), + char(80), + char(116), + char(114), + char(0), + char(42), + char(109), + char(95), + char(118), + char(97), + char(108), + char(117), + char(101), + char(65), + char(114), + char(114), + char(97), + char(121), + char(80), + char(116), + char(114), + char(0), + char(42), + char(109), + char(95), + char(107), + char(101), + char(121), + char(65), + char(114), + char(114), + char(97), + char(121), + char(80), + char(116), + char(114), + char(0), + char(109), + char(95), + char(99), + char(111), + char(110), + char(118), + char(101), + char(120), + char(69), + char(112), + char(115), + char(105), + char(108), + char(111), + char(110), + char(0), + char(109), + char(95), + char(112), + char(108), + char(97), + char(110), + char(97), + char(114), + char(69), + char(112), + char(115), + char(105), + char(108), + char(111), + char(110), + char(0), + char(109), + char(95), + char(101), + char(113), + char(117), + char(97), + char(108), + char(86), + char(101), + char(114), + char(116), + char(101), + char(120), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(101), + char(100), + char(103), + char(101), + char(68), + char(105), + char(115), + char(116), + char(97), + char(110), + char(99), + char(101), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(122), + char(101), + char(114), + char(111), + char(65), + char(114), + char(101), + char(97), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(110), + char(101), + char(120), + char(116), + char(83), + char(105), + char(122), + char(101), + char(0), + char(109), + char(95), + char(104), + char(97), + char(115), + char(104), + char(84), + char(97), + char(98), + char(108), + char(101), + char(83), + char(105), + char(122), + char(101), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(86), + char(97), + char(108), + char(117), + char(101), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(75), + char(101), + char(121), + char(115), + char(0), + char(109), + char(95), + char(103), + char(105), + char(109), + char(112), + char(97), + char(99), + char(116), + char(83), + char(117), + char(98), + char(84), + char(121), + char(112), + char(101), + char(0), + char(42), + char(109), + char(95), + char(117), + char(110), + char(115), + char(99), + char(97), + char(108), + char(101), + char(100), + char(80), + char(111), + char(105), + char(110), + char(116), + char(115), + char(70), + char(108), + char(111), + char(97), + char(116), + char(80), + char(116), + char(114), + char(0), + char(42), + char(109), + char(95), + char(117), + char(110), + char(115), + char(99), + char(97), + char(108), + char(101), + char(100), + char(80), + char(111), + char(105), + char(110), + char(116), + char(115), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(80), + char(116), + char(114), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(85), + char(110), + char(115), + char(99), + char(97), + char(108), + char(101), + char(100), + char(80), + char(111), + char(105), + char(110), + char(116), + char(115), + char(0), + char(109), + char(95), + char(112), + char(97), + char(100), + char(100), + char(105), + char(110), + char(103), + char(51), + char(91), + char(52), + char(93), + char(0), + char(42), + char(109), + char(95), + char(98), + char(114), + char(111), + char(97), + char(100), + char(112), + char(104), + char(97), + char(115), + char(101), + char(72), + char(97), + char(110), + char(100), + char(108), + char(101), + char(0), + char(42), + char(109), + char(95), + char(99), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(83), + char(104), + char(97), + char(112), + char(101), + char(0), + char(42), + char(109), + char(95), + char(114), + char(111), + char(111), + char(116), + char(67), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(83), + char(104), + char(97), + char(112), + char(101), + char(0), + char(109), + char(95), + char(119), + char(111), + char(114), + char(108), + char(100), + char(84), + char(114), + char(97), + char(110), + char(115), + char(102), + char(111), + char(114), + char(109), + char(0), + char(109), + char(95), + char(105), + char(110), + char(116), + char(101), + char(114), + char(112), + char(111), + char(108), + char(97), + char(116), + char(105), + char(111), + char(110), + char(87), + char(111), + char(114), + char(108), + char(100), + char(84), + char(114), + char(97), + char(110), + char(115), + char(102), + char(111), + char(114), + char(109), + char(0), + char(109), + char(95), + char(105), + char(110), + char(116), + char(101), + char(114), + char(112), + char(111), + char(108), + char(97), + char(116), + char(105), + char(111), + char(110), + char(76), + char(105), + char(110), + char(101), + char(97), + char(114), + char(86), + char(101), + char(108), + char(111), + char(99), + char(105), + char(116), + char(121), + char(0), + char(109), + char(95), + char(105), + char(110), + char(116), + char(101), + char(114), + char(112), + char(111), + char(108), + char(97), + char(116), + char(105), + char(111), + char(110), + char(65), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(86), + char(101), + char(108), + char(111), + char(99), + char(105), + char(116), + char(121), + char(0), + char(109), + char(95), + char(97), + char(110), + char(105), + char(115), + char(111), + char(116), + char(114), + char(111), + char(112), + char(105), + char(99), + char(70), + char(114), + char(105), + char(99), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(99), + char(111), + char(110), + char(116), + char(97), + char(99), + char(116), + char(80), + char(114), + char(111), + char(99), + char(101), + char(115), + char(115), + char(105), + char(110), + char(103), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(100), + char(101), + char(97), + char(99), + char(116), + char(105), + char(118), + char(97), + char(116), + char(105), + char(111), + char(110), + char(84), + char(105), + char(109), + char(101), + char(0), + char(109), + char(95), + char(102), + char(114), + char(105), + char(99), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(114), + char(111), + char(108), + char(108), + char(105), + char(110), + char(103), + char(70), + char(114), + char(105), + char(99), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(114), + char(101), + char(115), + char(116), + char(105), + char(116), + char(117), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(104), + char(105), + char(116), + char(70), + char(114), + char(97), + char(99), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(99), + char(99), + char(100), + char(83), + char(119), + char(101), + char(112), + char(116), + char(83), + char(112), + char(104), + char(101), + char(114), + char(101), + char(82), + char(97), + char(100), + char(105), + char(117), + char(115), + char(0), + char(109), + char(95), + char(99), + char(99), + char(100), + char(77), + char(111), + char(116), + char(105), + char(111), + char(110), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(104), + char(97), + char(115), + char(65), + char(110), + char(105), + char(115), + char(111), + char(116), + char(114), + char(111), + char(112), + char(105), + char(99), + char(70), + char(114), + char(105), + char(99), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(99), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(70), + char(108), + char(97), + char(103), + char(115), + char(0), + char(109), + char(95), + char(105), + char(115), + char(108), + char(97), + char(110), + char(100), + char(84), + char(97), + char(103), + char(49), + char(0), + char(109), + char(95), + char(99), + char(111), + char(109), + char(112), + char(97), + char(110), + char(105), + char(111), + char(110), + char(73), + char(100), + char(0), + char(109), + char(95), + char(97), + char(99), + char(116), + char(105), + char(118), + char(97), + char(116), + char(105), + char(111), + char(110), + char(83), + char(116), + char(97), + char(116), + char(101), + char(49), + char(0), + char(109), + char(95), + char(105), + char(110), + char(116), + char(101), + char(114), + char(110), + char(97), + char(108), + char(84), + char(121), + char(112), + char(101), + char(0), + char(109), + char(95), + char(99), + char(104), + char(101), + char(99), + char(107), + char(67), + char(111), + char(108), + char(108), + char(105), + char(100), + char(101), + char(87), + char(105), + char(116), + char(104), + char(0), + char(109), + char(95), + char(115), + char(111), + char(108), + char(118), + char(101), + char(114), + char(73), + char(110), + char(102), + char(111), + char(0), + char(109), + char(95), + char(103), + char(114), + char(97), + char(118), + char(105), + char(116), + char(121), + char(0), + char(109), + char(95), + char(99), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(79), + char(98), + char(106), + char(101), + char(99), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(109), + char(95), + char(105), + char(110), + char(118), + char(73), + char(110), + char(101), + char(114), + char(116), + char(105), + char(97), + char(84), + char(101), + char(110), + char(115), + char(111), + char(114), + char(87), + char(111), + char(114), + char(108), + char(100), + char(0), + char(109), + char(95), + char(108), + char(105), + char(110), + char(101), + char(97), + char(114), + char(86), + char(101), + char(108), + char(111), + char(99), + char(105), + char(116), + char(121), + char(0), + char(109), + char(95), + char(97), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(86), + char(101), + char(108), + char(111), + char(99), + char(105), + char(116), + char(121), + char(0), + char(109), + char(95), + char(97), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(70), + char(97), + char(99), + char(116), + char(111), + char(114), + char(0), + char(109), + char(95), + char(108), + char(105), + char(110), + char(101), + char(97), + char(114), + char(70), + char(97), + char(99), + char(116), + char(111), + char(114), + char(0), + char(109), + char(95), + char(103), + char(114), + char(97), + char(118), + char(105), + char(116), + char(121), + char(95), + char(97), + char(99), + char(99), + char(101), + char(108), + char(101), + char(114), + char(97), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(105), + char(110), + char(118), + char(73), + char(110), + char(101), + char(114), + char(116), + char(105), + char(97), + char(76), + char(111), + char(99), + char(97), + char(108), + char(0), + char(109), + char(95), + char(116), + char(111), + char(116), + char(97), + char(108), + char(70), + char(111), + char(114), + char(99), + char(101), + char(0), + char(109), + char(95), + char(116), + char(111), + char(116), + char(97), + char(108), + char(84), + char(111), + char(114), + char(113), + char(117), + char(101), + char(0), + char(109), + char(95), + char(105), + char(110), + char(118), + char(101), + char(114), + char(115), + char(101), + char(77), + char(97), + char(115), + char(115), + char(0), + char(109), + char(95), + char(108), + char(105), + char(110), + char(101), + char(97), + char(114), + char(68), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(97), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(68), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(97), + char(100), + char(100), + char(105), + char(116), + char(105), + char(111), + char(110), + char(97), + char(108), + char(68), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(70), + char(97), + char(99), + char(116), + char(111), + char(114), + char(0), + char(109), + char(95), + char(97), + char(100), + char(100), + char(105), + char(116), + char(105), + char(111), + char(110), + char(97), + char(108), + char(76), + char(105), + char(110), + char(101), + char(97), + char(114), + char(68), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(83), + char(113), + char(114), + char(0), + char(109), + char(95), + char(97), + char(100), + char(100), + char(105), + char(116), + char(105), + char(111), + char(110), + char(97), + char(108), + char(65), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(68), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(83), + char(113), + char(114), + char(0), + char(109), + char(95), + char(97), + char(100), + char(100), + char(105), + char(116), + char(105), + char(111), + char(110), + char(97), + char(108), + char(65), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(68), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(70), + char(97), + char(99), + char(116), + char(111), + char(114), + char(0), + char(109), + char(95), + char(108), + char(105), + char(110), + char(101), + char(97), + char(114), + char(83), + char(108), + char(101), + char(101), + char(112), + char(105), + char(110), + char(103), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(97), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(83), + char(108), + char(101), + char(101), + char(112), + char(105), + char(110), + char(103), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(97), + char(100), + char(100), + char(105), + char(116), + char(105), + char(111), + char(110), + char(97), + char(108), + char(68), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(82), + char(111), + char(119), + char(115), + char(0), + char(110), + char(117), + char(98), + char(0), + char(42), + char(109), + char(95), + char(114), + char(98), + char(65), + char(0), + char(42), + char(109), + char(95), + char(114), + char(98), + char(66), + char(0), + char(109), + char(95), + char(111), + char(98), + char(106), + char(101), + char(99), + char(116), + char(84), + char(121), + char(112), + char(101), + char(0), + char(109), + char(95), + char(117), + char(115), + char(101), + char(114), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(84), + char(121), + char(112), + char(101), + char(0), + char(109), + char(95), + char(117), + char(115), + char(101), + char(114), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(73), + char(100), + char(0), + char(109), + char(95), + char(110), + char(101), + char(101), + char(100), + char(115), + char(70), + char(101), + char(101), + char(100), + char(98), + char(97), + char(99), + char(107), + char(0), + char(109), + char(95), + char(97), + char(112), + char(112), + char(108), + char(105), + char(101), + char(100), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(0), + char(109), + char(95), + char(100), + char(98), + char(103), + char(68), + char(114), + char(97), + char(119), + char(83), + char(105), + char(122), + char(101), + char(0), + char(109), + char(95), + char(100), + char(105), + char(115), + char(97), + char(98), + char(108), + char(101), + char(67), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(115), + char(66), + char(101), + char(116), + char(119), + char(101), + char(101), + char(110), + char(76), + char(105), + char(110), + char(107), + char(101), + char(100), + char(66), + char(111), + char(100), + char(105), + char(101), + char(115), + char(0), + char(109), + char(95), + char(111), + char(118), + char(101), + char(114), + char(114), + char(105), + char(100), + char(101), + char(78), + char(117), + char(109), + char(83), + char(111), + char(108), + char(118), + char(101), + char(114), + char(73), + char(116), + char(101), + char(114), + char(97), + char(116), + char(105), + char(111), + char(110), + char(115), + char(0), + char(109), + char(95), + char(98), + char(114), + char(101), + char(97), + char(107), + char(105), + char(110), + char(103), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(105), + char(115), + char(69), + char(110), + char(97), + char(98), + char(108), + char(101), + char(100), + char(0), + char(109), + char(95), + char(116), + char(121), + char(112), + char(101), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(109), + char(95), + char(112), + char(105), + char(118), + char(111), + char(116), + char(73), + char(110), + char(65), + char(0), + char(109), + char(95), + char(112), + char(105), + char(118), + char(111), + char(116), + char(73), + char(110), + char(66), + char(0), + char(109), + char(95), + char(114), + char(98), + char(65), + char(70), + char(114), + char(97), + char(109), + char(101), + char(0), + char(109), + char(95), + char(114), + char(98), + char(66), + char(70), + char(114), + char(97), + char(109), + char(101), + char(0), + char(109), + char(95), + char(117), + char(115), + char(101), + char(82), + char(101), + char(102), + char(101), + char(114), + char(101), + char(110), + char(99), + char(101), + char(70), + char(114), + char(97), + char(109), + char(101), + char(65), + char(0), + char(109), + char(95), + char(97), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(79), + char(110), + char(108), + char(121), + char(0), + char(109), + char(95), + char(101), + char(110), + char(97), + char(98), + char(108), + char(101), + char(65), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(77), + char(111), + char(116), + char(111), + char(114), + char(0), + char(109), + char(95), + char(109), + char(111), + char(116), + char(111), + char(114), + char(84), + char(97), + char(114), + char(103), + char(101), + char(116), + char(86), + char(101), + char(108), + char(111), + char(99), + char(105), + char(116), + char(121), + char(0), + char(109), + char(95), + char(109), + char(97), + char(120), + char(77), + char(111), + char(116), + char(111), + char(114), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(0), + char(109), + char(95), + char(108), + char(111), + char(119), + char(101), + char(114), + char(76), + char(105), + char(109), + char(105), + char(116), + char(0), + char(109), + char(95), + char(117), + char(112), + char(112), + char(101), + char(114), + char(76), + char(105), + char(109), + char(105), + char(116), + char(0), + char(109), + char(95), + char(108), + char(105), + char(109), + char(105), + char(116), + char(83), + char(111), + char(102), + char(116), + char(110), + char(101), + char(115), + char(115), + char(0), + char(109), + char(95), + char(98), + char(105), + char(97), + char(115), + char(70), + char(97), + char(99), + char(116), + char(111), + char(114), + char(0), + char(109), + char(95), + char(114), + char(101), + char(108), + char(97), + char(120), + char(97), + char(116), + char(105), + char(111), + char(110), + char(70), + char(97), + char(99), + char(116), + char(111), + char(114), + char(0), + char(109), + char(95), + char(115), + char(119), + char(105), + char(110), + char(103), + char(83), + char(112), + char(97), + char(110), + char(49), + char(0), + char(109), + char(95), + char(115), + char(119), + char(105), + char(110), + char(103), + char(83), + char(112), + char(97), + char(110), + char(50), + char(0), + char(109), + char(95), + char(116), + char(119), + char(105), + char(115), + char(116), + char(83), + char(112), + char(97), + char(110), + char(0), + char(109), + char(95), + char(100), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(108), + char(105), + char(110), + char(101), + char(97), + char(114), + char(85), + char(112), + char(112), + char(101), + char(114), + char(76), + char(105), + char(109), + char(105), + char(116), + char(0), + char(109), + char(95), + char(108), + char(105), + char(110), + char(101), + char(97), + char(114), + char(76), + char(111), + char(119), + char(101), + char(114), + char(76), + char(105), + char(109), + char(105), + char(116), + char(0), + char(109), + char(95), + char(97), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(85), + char(112), + char(112), + char(101), + char(114), + char(76), + char(105), + char(109), + char(105), + char(116), + char(0), + char(109), + char(95), + char(97), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(76), + char(111), + char(119), + char(101), + char(114), + char(76), + char(105), + char(109), + char(105), + char(116), + char(0), + char(109), + char(95), + char(117), + char(115), + char(101), + char(76), + char(105), + char(110), + char(101), + char(97), + char(114), + char(82), + char(101), + char(102), + char(101), + char(114), + char(101), + char(110), + char(99), + char(101), + char(70), + char(114), + char(97), + char(109), + char(101), + char(65), + char(0), + char(109), + char(95), + char(117), + char(115), + char(101), + char(79), + char(102), + char(102), + char(115), + char(101), + char(116), + char(70), + char(111), + char(114), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(70), + char(114), + char(97), + char(109), + char(101), + char(0), + char(109), + char(95), + char(54), + char(100), + char(111), + char(102), + char(68), + char(97), + char(116), + char(97), + char(0), + char(109), + char(95), + char(115), + char(112), + char(114), + char(105), + char(110), + char(103), + char(69), + char(110), + char(97), + char(98), + char(108), + char(101), + char(100), + char(91), + char(54), + char(93), + char(0), + char(109), + char(95), + char(101), + char(113), + char(117), + char(105), + char(108), + char(105), + char(98), + char(114), + char(105), + char(117), + char(109), + char(80), + char(111), + char(105), + char(110), + char(116), + char(91), + char(54), + char(93), + char(0), + char(109), + char(95), + char(115), + char(112), + char(114), + char(105), + char(110), + char(103), + char(83), + char(116), + char(105), + char(102), + char(102), + char(110), + char(101), + char(115), + char(115), + char(91), + char(54), + char(93), + char(0), + char(109), + char(95), + char(115), + char(112), + char(114), + char(105), + char(110), + char(103), + char(68), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(91), + char(54), + char(93), + char(0), + char(109), + char(95), + char(116), + char(97), + char(117), + char(0), + char(109), + char(95), + char(116), + char(105), + char(109), + char(101), + char(83), + char(116), + char(101), + char(112), + char(0), + char(109), + char(95), + char(109), + char(97), + char(120), + char(69), + char(114), + char(114), + char(111), + char(114), + char(82), + char(101), + char(100), + char(117), + char(99), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(115), + char(111), + char(114), + char(0), + char(109), + char(95), + char(101), + char(114), + char(112), + char(0), + char(109), + char(95), + char(101), + char(114), + char(112), + char(50), + char(0), + char(109), + char(95), + char(103), + char(108), + char(111), + char(98), + char(97), + char(108), + char(67), + char(102), + char(109), + char(0), + char(109), + char(95), + char(115), + char(112), + char(108), + char(105), + char(116), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(80), + char(101), + char(110), + char(101), + char(116), + char(114), + char(97), + char(116), + char(105), + char(111), + char(110), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(115), + char(112), + char(108), + char(105), + char(116), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(84), + char(117), + char(114), + char(110), + char(69), + char(114), + char(112), + char(0), + char(109), + char(95), + char(108), + char(105), + char(110), + char(101), + char(97), + char(114), + char(83), + char(108), + char(111), + char(112), + char(0), + char(109), + char(95), + char(119), + char(97), + char(114), + char(109), + char(115), + char(116), + char(97), + char(114), + char(116), + char(105), + char(110), + char(103), + char(70), + char(97), + char(99), + char(116), + char(111), + char(114), + char(0), + char(109), + char(95), + char(109), + char(97), + char(120), + char(71), + char(121), + char(114), + char(111), + char(115), + char(99), + char(111), + char(112), + char(105), + char(99), + char(70), + char(111), + char(114), + char(99), + char(101), + char(0), + char(109), + char(95), + char(115), + char(105), + char(110), + char(103), + char(108), + char(101), + char(65), + char(120), + char(105), + char(115), + char(82), + char(111), + char(108), + char(108), + char(105), + char(110), + char(103), + char(70), + char(114), + char(105), + char(99), + char(116), + char(105), + char(111), + char(110), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(73), + char(116), + char(101), + char(114), + char(97), + char(116), + char(105), + char(111), + char(110), + char(115), + char(0), + char(109), + char(95), + char(115), + char(111), + char(108), + char(118), + char(101), + char(114), + char(77), + char(111), + char(100), + char(101), + char(0), + char(109), + char(95), + char(114), + char(101), + char(115), + char(116), + char(105), + char(110), + char(103), + char(67), + char(111), + char(110), + char(116), + char(97), + char(99), + char(116), + char(82), + char(101), + char(115), + char(116), + char(105), + char(116), + char(117), + char(116), + char(105), + char(111), + char(110), + char(84), + char(104), + char(114), + char(101), + char(115), + char(104), + char(111), + char(108), + char(100), + char(0), + char(109), + char(95), + char(109), + char(105), + char(110), + char(105), + char(109), + char(117), + char(109), + char(83), + char(111), + char(108), + char(118), + char(101), + char(114), + char(66), + char(97), + char(116), + char(99), + char(104), + char(83), + char(105), + char(122), + char(101), + char(0), + char(109), + char(95), + char(115), + char(112), + char(108), + char(105), + char(116), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(0), + char(109), + char(95), + char(108), + char(105), + char(110), + char(101), + char(97), + char(114), + char(83), + char(116), + char(105), + char(102), + char(102), + char(110), + char(101), + char(115), + char(115), + char(0), + char(109), + char(95), + char(97), + char(110), + char(103), + char(117), + char(108), + char(97), + char(114), + char(83), + char(116), + char(105), + char(102), + char(102), + char(110), + char(101), + char(115), + char(115), + char(0), + char(109), + char(95), + char(118), + char(111), + char(108), + char(117), + char(109), + char(101), + char(83), + char(116), + char(105), + char(102), + char(102), + char(110), + char(101), + char(115), + char(115), + char(0), + char(42), + char(109), + char(95), + char(109), + char(97), + char(116), + char(101), + char(114), + char(105), + char(97), + char(108), + char(0), + char(109), + char(95), + char(112), + char(111), + char(115), + char(105), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(112), + char(114), + char(101), + char(118), + char(105), + char(111), + char(117), + char(115), + char(80), + char(111), + char(115), + char(105), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(118), + char(101), + char(108), + char(111), + char(99), + char(105), + char(116), + char(121), + char(0), + char(109), + char(95), + char(97), + char(99), + char(99), + char(117), + char(109), + char(117), + char(108), + char(97), + char(116), + char(101), + char(100), + char(70), + char(111), + char(114), + char(99), + char(101), + char(0), + char(109), + char(95), + char(110), + char(111), + char(114), + char(109), + char(97), + char(108), + char(0), + char(109), + char(95), + char(97), + char(114), + char(101), + char(97), + char(0), + char(109), + char(95), + char(97), + char(116), + char(116), + char(97), + char(99), + char(104), + char(0), + char(109), + char(95), + char(110), + char(111), + char(100), + char(101), + char(73), + char(110), + char(100), + char(105), + char(99), + char(101), + char(115), + char(91), + char(50), + char(93), + char(0), + char(109), + char(95), + char(114), + char(101), + char(115), + char(116), + char(76), + char(101), + char(110), + char(103), + char(116), + char(104), + char(0), + char(109), + char(95), + char(98), + char(98), + char(101), + char(110), + char(100), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(110), + char(111), + char(100), + char(101), + char(73), + char(110), + char(100), + char(105), + char(99), + char(101), + char(115), + char(91), + char(51), + char(93), + char(0), + char(109), + char(95), + char(114), + char(101), + char(115), + char(116), + char(65), + char(114), + char(101), + char(97), + char(0), + char(109), + char(95), + char(99), + char(48), + char(91), + char(52), + char(93), + char(0), + char(109), + char(95), + char(110), + char(111), + char(100), + char(101), + char(73), + char(110), + char(100), + char(105), + char(99), + char(101), + char(115), + char(91), + char(52), + char(93), + char(0), + char(109), + char(95), + char(114), + char(101), + char(115), + char(116), + char(86), + char(111), + char(108), + char(117), + char(109), + char(101), + char(0), + char(109), + char(95), + char(99), + char(49), + char(0), + char(109), + char(95), + char(99), + char(50), + char(0), + char(109), + char(95), + char(99), + char(48), + char(0), + char(109), + char(95), + char(108), + char(111), + char(99), + char(97), + char(108), + char(70), + char(114), + char(97), + char(109), + char(101), + char(0), + char(42), + char(109), + char(95), + char(114), + char(105), + char(103), + char(105), + char(100), + char(66), + char(111), + char(100), + char(121), + char(0), + char(109), + char(95), + char(110), + char(111), + char(100), + char(101), + char(73), + char(110), + char(100), + char(101), + char(120), + char(0), + char(109), + char(95), + char(97), + char(101), + char(114), + char(111), + char(77), + char(111), + char(100), + char(101), + char(108), + char(0), + char(109), + char(95), + char(98), + char(97), + char(117), + char(109), + char(103), + char(97), + char(114), + char(116), + char(101), + char(0), + char(109), + char(95), + char(100), + char(114), + char(97), + char(103), + char(0), + char(109), + char(95), + char(108), + char(105), + char(102), + char(116), + char(0), + char(109), + char(95), + char(112), + char(114), + char(101), + char(115), + char(115), + char(117), + char(114), + char(101), + char(0), + char(109), + char(95), + char(118), + char(111), + char(108), + char(117), + char(109), + char(101), + char(0), + char(109), + char(95), + char(100), + char(121), + char(110), + char(97), + char(109), + char(105), + char(99), + char(70), + char(114), + char(105), + char(99), + char(116), + char(105), + char(111), + char(110), + char(0), + char(109), + char(95), + char(112), + char(111), + char(115), + char(101), + char(77), + char(97), + char(116), + char(99), + char(104), + char(0), + char(109), + char(95), + char(114), + char(105), + char(103), + char(105), + char(100), + char(67), + char(111), + char(110), + char(116), + char(97), + char(99), + char(116), + char(72), + char(97), + char(114), + char(100), + char(110), + char(101), + char(115), + char(115), + char(0), + char(109), + char(95), + char(107), + char(105), + char(110), + char(101), + char(116), + char(105), + char(99), + char(67), + char(111), + char(110), + char(116), + char(97), + char(99), + char(116), + char(72), + char(97), + char(114), + char(100), + char(110), + char(101), + char(115), + char(115), + char(0), + char(109), + char(95), + char(115), + char(111), + char(102), + char(116), + char(67), + char(111), + char(110), + char(116), + char(97), + char(99), + char(116), + char(72), + char(97), + char(114), + char(100), + char(110), + char(101), + char(115), + char(115), + char(0), + char(109), + char(95), + char(97), + char(110), + char(99), + char(104), + char(111), + char(114), + char(72), + char(97), + char(114), + char(100), + char(110), + char(101), + char(115), + char(115), + char(0), + char(109), + char(95), + char(115), + char(111), + char(102), + char(116), + char(82), + char(105), + char(103), + char(105), + char(100), + char(67), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(72), + char(97), + char(114), + char(100), + char(110), + char(101), + char(115), + char(115), + char(0), + char(109), + char(95), + char(115), + char(111), + char(102), + char(116), + char(75), + char(105), + char(110), + char(101), + char(116), + char(105), + char(99), + char(67), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(72), + char(97), + char(114), + char(100), + char(110), + char(101), + char(115), + char(115), + char(0), + char(109), + char(95), + char(115), + char(111), + char(102), + char(116), + char(83), + char(111), + char(102), + char(116), + char(67), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(72), + char(97), + char(114), + char(100), + char(110), + char(101), + char(115), + char(115), + char(0), + char(109), + char(95), + char(115), + char(111), + char(102), + char(116), + char(82), + char(105), + char(103), + char(105), + char(100), + char(67), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(83), + char(112), + char(108), + char(105), + char(116), + char(0), + char(109), + char(95), + char(115), + char(111), + char(102), + char(116), + char(75), + char(105), + char(110), + char(101), + char(116), + char(105), + char(99), + char(67), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(83), + char(112), + char(108), + char(105), + char(116), + char(0), + char(109), + char(95), + char(115), + char(111), + char(102), + char(116), + char(83), + char(111), + char(102), + char(116), + char(67), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(83), + char(112), + char(108), + char(105), + char(116), + char(0), + char(109), + char(95), + char(109), + char(97), + char(120), + char(86), + char(111), + char(108), + char(117), + char(109), + char(101), + char(0), + char(109), + char(95), + char(116), + char(105), + char(109), + char(101), + char(83), + char(99), + char(97), + char(108), + char(101), + char(0), + char(109), + char(95), + char(118), + char(101), + char(108), + char(111), + char(99), + char(105), + char(116), + char(121), + char(73), + char(116), + char(101), + char(114), + char(97), + char(116), + char(105), + char(111), + char(110), + char(115), + char(0), + char(109), + char(95), + char(112), + char(111), + char(115), + char(105), + char(116), + char(105), + char(111), + char(110), + char(73), + char(116), + char(101), + char(114), + char(97), + char(116), + char(105), + char(111), + char(110), + char(115), + char(0), + char(109), + char(95), + char(100), + char(114), + char(105), + char(102), + char(116), + char(73), + char(116), + char(101), + char(114), + char(97), + char(116), + char(105), + char(111), + char(110), + char(115), + char(0), + char(109), + char(95), + char(99), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(73), + char(116), + char(101), + char(114), + char(97), + char(116), + char(105), + char(111), + char(110), + char(115), + char(0), + char(109), + char(95), + char(114), + char(111), + char(116), + char(0), + char(109), + char(95), + char(115), + char(99), + char(97), + char(108), + char(101), + char(0), + char(109), + char(95), + char(97), + char(113), + char(113), + char(0), + char(109), + char(95), + char(99), + char(111), + char(109), + char(0), + char(42), + char(109), + char(95), + char(112), + char(111), + char(115), + char(105), + char(116), + char(105), + char(111), + char(110), + char(115), + char(0), + char(42), + char(109), + char(95), + char(119), + char(101), + char(105), + char(103), + char(104), + char(116), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(80), + char(111), + char(115), + char(105), + char(116), + char(105), + char(111), + char(110), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(87), + char(101), + char(105), + char(103), + char(116), + char(115), + char(0), + char(109), + char(95), + char(98), + char(118), + char(111), + char(108), + char(117), + char(109), + char(101), + char(0), + char(109), + char(95), + char(98), + char(102), + char(114), + char(97), + char(109), + char(101), + char(0), + char(109), + char(95), + char(102), + char(114), + char(97), + char(109), + char(101), + char(120), + char(102), + char(111), + char(114), + char(109), + char(0), + char(109), + char(95), + char(108), + char(111), + char(99), + char(105), + char(105), + char(0), + char(109), + char(95), + char(105), + char(110), + char(118), + char(119), + char(105), + char(0), + char(109), + char(95), + char(118), + char(105), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(115), + char(91), + char(50), + char(93), + char(0), + char(109), + char(95), + char(100), + char(105), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(115), + char(91), + char(50), + char(93), + char(0), + char(109), + char(95), + char(108), + char(118), + char(0), + char(109), + char(95), + char(97), + char(118), + char(0), + char(42), + char(109), + char(95), + char(102), + char(114), + char(97), + char(109), + char(101), + char(114), + char(101), + char(102), + char(115), + char(0), + char(42), + char(109), + char(95), + char(110), + char(111), + char(100), + char(101), + char(73), + char(110), + char(100), + char(105), + char(99), + char(101), + char(115), + char(0), + char(42), + char(109), + char(95), + char(109), + char(97), + char(115), + char(115), + char(101), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(70), + char(114), + char(97), + char(109), + char(101), + char(82), + char(101), + char(102), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(78), + char(111), + char(100), + char(101), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(77), + char(97), + char(115), + char(115), + char(101), + char(115), + char(0), + char(109), + char(95), + char(105), + char(100), + char(109), + char(97), + char(115), + char(115), + char(0), + char(109), + char(95), + char(105), + char(109), + char(97), + char(115), + char(115), + char(0), + char(109), + char(95), + char(110), + char(118), + char(105), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(115), + char(0), + char(109), + char(95), + char(110), + char(100), + char(105), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(115), + char(0), + char(109), + char(95), + char(110), + char(100), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(108), + char(100), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(97), + char(100), + char(97), + char(109), + char(112), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(109), + char(97), + char(116), + char(99), + char(104), + char(105), + char(110), + char(103), + char(0), + char(109), + char(95), + char(109), + char(97), + char(120), + char(83), + char(101), + char(108), + char(102), + char(67), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(0), + char(109), + char(95), + char(115), + char(101), + char(108), + char(102), + char(67), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(73), + char(109), + char(112), + char(117), + char(108), + char(115), + char(101), + char(70), + char(97), + char(99), + char(116), + char(111), + char(114), + char(0), + char(109), + char(95), + char(99), + char(111), + char(110), + char(116), + char(97), + char(105), + char(110), + char(115), + char(65), + char(110), + char(99), + char(104), + char(111), + char(114), + char(0), + char(109), + char(95), + char(99), + char(111), + char(108), + char(108), + char(105), + char(100), + char(101), + char(0), + char(109), + char(95), + char(99), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(73), + char(110), + char(100), + char(101), + char(120), + char(0), + char(42), + char(109), + char(95), + char(98), + char(111), + char(100), + char(121), + char(65), + char(0), + char(42), + char(109), + char(95), + char(98), + char(111), + char(100), + char(121), + char(66), + char(0), + char(109), + char(95), + char(114), + char(101), + char(102), + char(115), + char(91), + char(50), + char(93), + char(0), + char(109), + char(95), + char(99), + char(102), + char(109), + char(0), + char(109), + char(95), + char(115), + char(112), + char(108), + char(105), + char(116), + char(0), + char(109), + char(95), + char(100), + char(101), + char(108), + char(101), + char(116), + char(101), + char(0), + char(109), + char(95), + char(114), + char(101), + char(108), + char(80), + char(111), + char(115), + char(105), + char(116), + char(105), + char(111), + char(110), + char(91), + char(50), + char(93), + char(0), + char(109), + char(95), + char(98), + char(111), + char(100), + char(121), + char(65), + char(116), + char(121), + char(112), + char(101), + char(0), + char(109), + char(95), + char(98), + char(111), + char(100), + char(121), + char(66), + char(116), + char(121), + char(112), + char(101), + char(0), + char(109), + char(95), + char(106), + char(111), + char(105), + char(110), + char(116), + char(84), + char(121), + char(112), + char(101), + char(0), + char(42), + char(109), + char(95), + char(112), + char(111), + char(115), + char(101), + char(0), + char(42), + char(42), + char(109), + char(95), + char(109), + char(97), + char(116), + char(101), + char(114), + char(105), + char(97), + char(108), + char(115), + char(0), + char(42), + char(109), + char(95), + char(110), + char(111), + char(100), + char(101), + char(115), + char(0), + char(42), + char(109), + char(95), + char(108), + char(105), + char(110), + char(107), + char(115), + char(0), + char(42), + char(109), + char(95), + char(102), + char(97), + char(99), + char(101), + char(115), + char(0), + char(42), + char(109), + char(95), + char(116), + char(101), + char(116), + char(114), + char(97), + char(104), + char(101), + char(100), + char(114), + char(97), + char(0), + char(42), + char(109), + char(95), + char(97), + char(110), + char(99), + char(104), + char(111), + char(114), + char(115), + char(0), + char(42), + char(109), + char(95), + char(99), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(115), + char(0), + char(42), + char(109), + char(95), + char(106), + char(111), + char(105), + char(110), + char(116), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(77), + char(97), + char(116), + char(101), + char(114), + char(105), + char(97), + char(108), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(76), + char(105), + char(110), + char(107), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(70), + char(97), + char(99), + char(101), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(84), + char(101), + char(116), + char(114), + char(97), + char(104), + char(101), + char(100), + char(114), + char(97), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(65), + char(110), + char(99), + char(104), + char(111), + char(114), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(67), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(115), + char(0), + char(109), + char(95), + char(110), + char(117), + char(109), + char(74), + char(111), + char(105), + char(110), + char(116), + char(115), + char(0), + char(109), + char(95), + char(99), + char(111), + char(110), + char(102), + char(105), + char(103), + char(0), + char(84), + char(89), + char(80), + char(69), + char(76), + char(0), + char(0), + char(0), + char(99), + char(104), + char(97), + char(114), + char(0), + char(117), + char(99), + char(104), + char(97), + char(114), + char(0), + char(115), + char(104), + char(111), + char(114), + char(116), + char(0), + char(117), + char(115), + char(104), + char(111), + char(114), + char(116), + char(0), + char(105), + char(110), + char(116), + char(0), + char(108), + char(111), + char(110), + char(103), + char(0), + char(117), + char(108), + char(111), + char(110), + char(103), + char(0), + char(102), + char(108), + char(111), + char(97), + char(116), + char(0), + char(100), + char(111), + char(117), + char(98), + char(108), + char(101), + char(0), + char(118), + char(111), + char(105), + char(100), + char(0), + char(80), + char(111), + char(105), + char(110), + char(116), + char(101), + char(114), + char(65), + char(114), + char(114), + char(97), + char(121), + char(0), + char(98), + char(116), + char(80), + char(104), + char(121), + char(115), + char(105), + char(99), + char(115), + char(83), + char(121), + char(115), + char(116), + char(101), + char(109), + char(0), + char(76), + char(105), + char(115), + char(116), + char(66), + char(97), + char(115), + char(101), + char(0), + char(98), + char(116), + char(86), + char(101), + char(99), + char(116), + char(111), + char(114), + char(51), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(86), + char(101), + char(99), + char(116), + char(111), + char(114), + char(51), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(77), + char(97), + char(116), + char(114), + char(105), + char(120), + char(51), + char(120), + char(51), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(77), + char(97), + char(116), + char(114), + char(105), + char(120), + char(51), + char(120), + char(51), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(84), + char(114), + char(97), + char(110), + char(115), + char(102), + char(111), + char(114), + char(109), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(84), + char(114), + char(97), + char(110), + char(115), + char(102), + char(111), + char(114), + char(109), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(66), + char(118), + char(104), + char(83), + char(117), + char(98), + char(116), + char(114), + char(101), + char(101), + char(73), + char(110), + char(102), + char(111), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(79), + char(112), + char(116), + char(105), + char(109), + char(105), + char(122), + char(101), + char(100), + char(66), + char(118), + char(104), + char(78), + char(111), + char(100), + char(101), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(79), + char(112), + char(116), + char(105), + char(109), + char(105), + char(122), + char(101), + char(100), + char(66), + char(118), + char(104), + char(78), + char(111), + char(100), + char(101), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(81), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(101), + char(100), + char(66), + char(118), + char(104), + char(78), + char(111), + char(100), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(81), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(101), + char(100), + char(66), + char(118), + char(104), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(81), + char(117), + char(97), + char(110), + char(116), + char(105), + char(122), + char(101), + char(100), + char(66), + char(118), + char(104), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(83), + char(116), + char(97), + char(116), + char(105), + char(99), + char(80), + char(108), + char(97), + char(110), + char(101), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(110), + char(118), + char(101), + char(120), + char(73), + char(110), + char(116), + char(101), + char(114), + char(110), + char(97), + char(108), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(80), + char(111), + char(115), + char(105), + char(116), + char(105), + char(111), + char(110), + char(65), + char(110), + char(100), + char(82), + char(97), + char(100), + char(105), + char(117), + char(115), + char(0), + char(98), + char(116), + char(77), + char(117), + char(108), + char(116), + char(105), + char(83), + char(112), + char(104), + char(101), + char(114), + char(101), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(73), + char(110), + char(116), + char(73), + char(110), + char(100), + char(101), + char(120), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(83), + char(104), + char(111), + char(114), + char(116), + char(73), + char(110), + char(116), + char(73), + char(110), + char(100), + char(101), + char(120), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(83), + char(104), + char(111), + char(114), + char(116), + char(73), + char(110), + char(116), + char(73), + char(110), + char(100), + char(101), + char(120), + char(84), + char(114), + char(105), + char(112), + char(108), + char(101), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(104), + char(97), + char(114), + char(73), + char(110), + char(100), + char(101), + char(120), + char(84), + char(114), + char(105), + char(112), + char(108), + char(101), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(77), + char(101), + char(115), + char(104), + char(80), + char(97), + char(114), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(83), + char(116), + char(114), + char(105), + char(100), + char(105), + char(110), + char(103), + char(77), + char(101), + char(115), + char(104), + char(73), + char(110), + char(116), + char(101), + char(114), + char(102), + char(97), + char(99), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(84), + char(114), + char(105), + char(97), + char(110), + char(103), + char(108), + char(101), + char(77), + char(101), + char(115), + char(104), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(84), + char(114), + char(105), + char(97), + char(110), + char(103), + char(108), + char(101), + char(73), + char(110), + char(102), + char(111), + char(77), + char(97), + char(112), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(83), + char(99), + char(97), + char(108), + char(101), + char(100), + char(84), + char(114), + char(105), + char(97), + char(110), + char(103), + char(108), + char(101), + char(77), + char(101), + char(115), + char(104), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(109), + char(112), + char(111), + char(117), + char(110), + char(100), + char(83), + char(104), + char(97), + char(112), + char(101), + char(67), + char(104), + char(105), + char(108), + char(100), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(109), + char(112), + char(111), + char(117), + char(110), + char(100), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(121), + char(108), + char(105), + char(110), + char(100), + char(101), + char(114), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(97), + char(112), + char(115), + char(117), + char(108), + char(101), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(84), + char(114), + char(105), + char(97), + char(110), + char(103), + char(108), + char(101), + char(73), + char(110), + char(102), + char(111), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(71), + char(73), + char(109), + char(112), + char(97), + char(99), + char(116), + char(77), + char(101), + char(115), + char(104), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(110), + char(118), + char(101), + char(120), + char(72), + char(117), + char(108), + char(108), + char(83), + char(104), + char(97), + char(112), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(79), + char(98), + char(106), + char(101), + char(99), + char(116), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(108), + char(108), + char(105), + char(115), + char(105), + char(111), + char(110), + char(79), + char(98), + char(106), + char(101), + char(99), + char(116), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(68), + char(121), + char(110), + char(97), + char(109), + char(105), + char(99), + char(115), + char(87), + char(111), + char(114), + char(108), + char(100), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(110), + char(116), + char(97), + char(99), + char(116), + char(83), + char(111), + char(108), + char(118), + char(101), + char(114), + char(73), + char(110), + char(102), + char(111), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(68), + char(121), + char(110), + char(97), + char(109), + char(105), + char(99), + char(115), + char(87), + char(111), + char(114), + char(108), + char(100), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(110), + char(116), + char(97), + char(99), + char(116), + char(83), + char(111), + char(108), + char(118), + char(101), + char(114), + char(73), + char(110), + char(102), + char(111), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(82), + char(105), + char(103), + char(105), + char(100), + char(66), + char(111), + char(100), + char(121), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(82), + char(105), + char(103), + char(105), + char(100), + char(66), + char(111), + char(100), + char(121), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(73), + char(110), + char(102), + char(111), + char(49), + char(0), + char(98), + char(116), + char(84), + char(121), + char(112), + char(101), + char(100), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(82), + char(105), + char(103), + char(105), + char(100), + char(66), + char(111), + char(100), + char(121), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(80), + char(111), + char(105), + char(110), + char(116), + char(50), + char(80), + char(111), + char(105), + char(110), + char(116), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(80), + char(111), + char(105), + char(110), + char(116), + char(50), + char(80), + char(111), + char(105), + char(110), + char(116), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(72), + char(105), + char(110), + char(103), + char(101), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(68), + char(111), + char(117), + char(98), + char(108), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(72), + char(105), + char(110), + char(103), + char(101), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(67), + char(111), + char(110), + char(101), + char(84), + char(119), + char(105), + char(115), + char(116), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(71), + char(101), + char(110), + char(101), + char(114), + char(105), + char(99), + char(54), + char(68), + char(111), + char(102), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(71), + char(101), + char(110), + char(101), + char(114), + char(105), + char(99), + char(54), + char(68), + char(111), + char(102), + char(83), + char(112), + char(114), + char(105), + char(110), + char(103), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(83), + char(108), + char(105), + char(100), + char(101), + char(114), + char(67), + char(111), + char(110), + char(115), + char(116), + char(114), + char(97), + char(105), + char(110), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(83), + char(111), + char(102), + char(116), + char(66), + char(111), + char(100), + char(121), + char(77), + char(97), + char(116), + char(101), + char(114), + char(105), + char(97), + char(108), + char(68), + char(97), + char(116), + char(97), + char(0), + char(83), + char(111), + char(102), + char(116), + char(66), + char(111), + char(100), + char(121), + char(78), + char(111), + char(100), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(83), + char(111), + char(102), + char(116), + char(66), + char(111), + char(100), + char(121), + char(76), + char(105), + char(110), + char(107), + char(68), + char(97), + char(116), + char(97), + char(0), + char(83), + char(111), + char(102), + char(116), + char(66), + char(111), + char(100), + char(121), + char(70), + char(97), + char(99), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(83), + char(111), + char(102), + char(116), + char(66), + char(111), + char(100), + char(121), + char(84), + char(101), + char(116), + char(114), + char(97), + char(68), + char(97), + char(116), + char(97), + char(0), + char(83), + char(111), + char(102), + char(116), + char(82), + char(105), + char(103), + char(105), + char(100), + char(65), + char(110), + char(99), + char(104), + char(111), + char(114), + char(68), + char(97), + char(116), + char(97), + char(0), + char(83), + char(111), + char(102), + char(116), + char(66), + char(111), + char(100), + char(121), + char(67), + char(111), + char(110), + char(102), + char(105), + char(103), + char(68), + char(97), + char(116), + char(97), + char(0), + char(83), + char(111), + char(102), + char(116), + char(66), + char(111), + char(100), + char(121), + char(80), + char(111), + char(115), + char(101), + char(68), + char(97), + char(116), + char(97), + char(0), + char(83), + char(111), + char(102), + char(116), + char(66), + char(111), + char(100), + char(121), + char(67), + char(108), + char(117), + char(115), + char(116), + char(101), + char(114), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(83), + char(111), + char(102), + char(116), + char(66), + char(111), + char(100), + char(121), + char(74), + char(111), + char(105), + char(110), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(98), + char(116), + char(83), + char(111), + char(102), + char(116), + char(66), + char(111), + char(100), + char(121), + char(70), + char(108), + char(111), + char(97), + char(116), + char(68), + char(97), + char(116), + char(97), + char(0), + char(0), + char(0), + char(84), + char(76), + char(69), + char(78), + char(1), + char(0), + char(1), + char(0), + char(2), + char(0), + char(2), + char(0), + char(4), + char(0), + char(4), + char(0), + char(4), + char(0), + char(4), + char(0), + char(8), + char(0), + char(0), + char(0), + char(16), + char(0), + char(48), + char(0), + char(16), + char(0), + char(16), + char(0), + char(32), + char(0), + char(48), + char(0), + char(96), + char(0), + char(64), + char(0), + char(-128), + char(0), + char(20), + char(0), + char(48), + char(0), + char(80), + char(0), + char(16), + char(0), + char(96), + char(0), + char(-112), + char(0), + char(16), + char(0), + char(56), + char(0), + char(56), + char(0), + char(20), + char(0), + char(72), + char(0), + char(4), + char(0), + char(4), + char(0), + char(8), + char(0), + char(4), + char(0), + char(56), + char(0), + char(32), + char(0), + char(80), + char(0), + char(72), + char(0), + char(96), + char(0), + char(80), + char(0), + char(32), + char(0), + char(64), + char(0), + char(64), + char(0), + char(16), + char(0), + char(72), + char(0), + char(80), + char(0), + char(-32), + char(1), + char(16), + char(1), + char(-72), + char(0), + char(-104), + char(0), + char(104), + char(0), + char(88), + char(0), + char(-8), + char(1), + char(-80), + char(3), + char(8), + char(0), + char(64), + char(0), + char(0), + char(0), + char(96), + char(0), + char(-128), + char(0), + char(104), + char(1), + char(-24), + char(0), + char(-32), + char(0), + char(8), + char(1), + char(104), + char(1), + char(-40), + char(0), + char(16), + char(0), + char(104), + char(0), + char(24), + char(0), + char(40), + char(0), + char(104), + char(0), + char(96), + char(0), + char(104), + char(0), + char(-56), + char(0), + char(104), + char(1), + char(112), + char(0), + char(-32), + char(1), + char(83), + char(84), + char(82), + char(67), + char(65), + char(0), + char(0), + char(0), + char(10), + char(0), + char(3), + char(0), + char(4), + char(0), + char(0), + char(0), + char(4), + char(0), + char(1), + char(0), + char(9), + char(0), + char(2), + char(0), + char(11), + char(0), + char(3), + char(0), + char(10), + char(0), + char(3), + char(0), + char(10), + char(0), + char(4), + char(0), + char(10), + char(0), + char(5), + char(0), + char(12), + char(0), + char(2), + char(0), + char(9), + char(0), + char(6), + char(0), + char(9), + char(0), + char(7), + char(0), + char(13), + char(0), + char(1), + char(0), + char(7), + char(0), + char(8), + char(0), + char(14), + char(0), + char(1), + char(0), + char(8), + char(0), + char(8), + char(0), + char(15), + char(0), + char(1), + char(0), + char(13), + char(0), + char(9), + char(0), + char(16), + char(0), + char(1), + char(0), + char(14), + char(0), + char(9), + char(0), + char(17), + char(0), + char(2), + char(0), + char(15), + char(0), + char(10), + char(0), + char(13), + char(0), + char(11), + char(0), + char(18), + char(0), + char(2), + char(0), + char(16), + char(0), + char(10), + char(0), + char(14), + char(0), + char(11), + char(0), + char(19), + char(0), + char(4), + char(0), + char(4), + char(0), + char(12), + char(0), + char(4), + char(0), + char(13), + char(0), + char(2), + char(0), + char(14), + char(0), + char(2), + char(0), + char(15), + char(0), + char(20), + char(0), + char(6), + char(0), + char(13), + char(0), + char(16), + char(0), + char(13), + char(0), + char(17), + char(0), + char(4), + char(0), + char(18), + char(0), + char(4), + char(0), + char(19), + char(0), + char(4), + char(0), + char(20), + char(0), + char(0), + char(0), + char(21), + char(0), + char(21), + char(0), + char(6), + char(0), + char(14), + char(0), + char(16), + char(0), + char(14), + char(0), + char(17), + char(0), + char(4), + char(0), + char(18), + char(0), + char(4), + char(0), + char(19), + char(0), + char(4), + char(0), + char(20), + char(0), + char(0), + char(0), + char(21), + char(0), + char(22), + char(0), + char(3), + char(0), + char(2), + char(0), + char(14), + char(0), + char(2), + char(0), + char(15), + char(0), + char(4), + char(0), + char(22), + char(0), + char(23), + char(0), + char(12), + char(0), + char(13), + char(0), + char(23), + char(0), + char(13), + char(0), + char(24), + char(0), + char(13), + char(0), + char(25), + char(0), + char(4), + char(0), + char(26), + char(0), + char(4), + char(0), + char(27), + char(0), + char(4), + char(0), + char(28), + char(0), + char(4), + char(0), + char(29), + char(0), + char(20), + char(0), + char(30), + char(0), + char(22), + char(0), + char(31), + char(0), + char(19), + char(0), + char(32), + char(0), + char(4), + char(0), + char(33), + char(0), + char(4), + char(0), + char(34), + char(0), + char(24), + char(0), + char(12), + char(0), + char(14), + char(0), + char(23), + char(0), + char(14), + char(0), + char(24), + char(0), + char(14), + char(0), + char(25), + char(0), + char(4), + char(0), + char(26), + char(0), + char(4), + char(0), + char(27), + char(0), + char(4), + char(0), + char(28), + char(0), + char(4), + char(0), + char(29), + char(0), + char(21), + char(0), + char(30), + char(0), + char(22), + char(0), + char(31), + char(0), + char(4), + char(0), + char(33), + char(0), + char(4), + char(0), + char(34), + char(0), + char(19), + char(0), + char(32), + char(0), + char(25), + char(0), + char(3), + char(0), + char(0), + char(0), + char(35), + char(0), + char(4), + char(0), + char(36), + char(0), + char(0), + char(0), + char(37), + char(0), + char(26), + char(0), + char(5), + char(0), + char(25), + char(0), + char(38), + char(0), + char(13), + char(0), + char(39), + char(0), + char(13), + char(0), + char(40), + char(0), + char(7), + char(0), + char(41), + char(0), + char(0), + char(0), + char(21), + char(0), + char(27), + char(0), + char(5), + char(0), + char(25), + char(0), + char(38), + char(0), + char(13), + char(0), + char(39), + char(0), + char(13), + char(0), + char(42), + char(0), + char(7), + char(0), + char(43), + char(0), + char(4), + char(0), + char(44), + char(0), + char(28), + char(0), + char(2), + char(0), + char(13), + char(0), + char(45), + char(0), + char(7), + char(0), + char(46), + char(0), + char(29), + char(0), + char(4), + char(0), + char(27), + char(0), + char(47), + char(0), + char(28), + char(0), + char(48), + char(0), + char(4), + char(0), + char(49), + char(0), + char(0), + char(0), + char(37), + char(0), + char(30), + char(0), + char(1), + char(0), + char(4), + char(0), + char(50), + char(0), + char(31), + char(0), + char(2), + char(0), + char(2), + char(0), + char(50), + char(0), + char(0), + char(0), + char(51), + char(0), + char(32), + char(0), + char(2), + char(0), + char(2), + char(0), + char(52), + char(0), + char(0), + char(0), + char(51), + char(0), + char(33), + char(0), + char(2), + char(0), + char(0), + char(0), + char(52), + char(0), + char(0), + char(0), + char(53), + char(0), + char(34), + char(0), + char(8), + char(0), + char(13), + char(0), + char(54), + char(0), + char(14), + char(0), + char(55), + char(0), + char(30), + char(0), + char(56), + char(0), + char(32), + char(0), + char(57), + char(0), + char(33), + char(0), + char(58), + char(0), + char(31), + char(0), + char(59), + char(0), + char(4), + char(0), + char(60), + char(0), + char(4), + char(0), + char(61), + char(0), + char(35), + char(0), + char(4), + char(0), + char(34), + char(0), + char(62), + char(0), + char(13), + char(0), + char(63), + char(0), + char(4), + char(0), + char(64), + char(0), + char(0), + char(0), + char(37), + char(0), + char(36), + char(0), + char(7), + char(0), + char(25), + char(0), + char(38), + char(0), + char(35), + char(0), + char(65), + char(0), + char(23), + char(0), + char(66), + char(0), + char(24), + char(0), + char(67), + char(0), + char(37), + char(0), + char(68), + char(0), + char(7), + char(0), + char(43), + char(0), + char(0), + char(0), + char(69), + char(0), + char(38), + char(0), + char(2), + char(0), + char(36), + char(0), + char(70), + char(0), + char(13), + char(0), + char(39), + char(0), + char(39), + char(0), + char(4), + char(0), + char(17), + char(0), + char(71), + char(0), + char(25), + char(0), + char(72), + char(0), + char(4), + char(0), + char(73), + char(0), + char(7), + char(0), + char(74), + char(0), + char(40), + char(0), + char(4), + char(0), + char(25), + char(0), + char(38), + char(0), + char(39), + char(0), + char(75), + char(0), + char(4), + char(0), + char(76), + char(0), + char(7), + char(0), + char(43), + char(0), + char(41), + char(0), + char(3), + char(0), + char(27), + char(0), + char(47), + char(0), + char(4), + char(0), + char(77), + char(0), + char(0), + char(0), + char(37), + char(0), + char(42), + char(0), + char(3), + char(0), + char(27), + char(0), + char(47), + char(0), + char(4), + char(0), + char(77), + char(0), + char(0), + char(0), + char(37), + char(0), + char(43), + char(0), + char(4), + char(0), + char(4), + char(0), + char(78), + char(0), + char(7), + char(0), + char(79), + char(0), + char(7), + char(0), + char(80), + char(0), + char(7), + char(0), + char(81), + char(0), + char(37), + char(0), + char(14), + char(0), + char(4), + char(0), + char(82), + char(0), + char(4), + char(0), + char(83), + char(0), + char(43), + char(0), + char(84), + char(0), + char(4), + char(0), + char(85), + char(0), + char(7), + char(0), + char(86), + char(0), + char(7), + char(0), + char(87), + char(0), + char(7), + char(0), + char(88), + char(0), + char(7), + char(0), + char(89), + char(0), + char(7), + char(0), + char(90), + char(0), + char(4), + char(0), + char(91), + char(0), + char(4), + char(0), + char(92), + char(0), + char(4), + char(0), + char(93), + char(0), + char(4), + char(0), + char(94), + char(0), + char(0), + char(0), + char(37), + char(0), + char(44), + char(0), + char(5), + char(0), + char(25), + char(0), + char(38), + char(0), + char(35), + char(0), + char(65), + char(0), + char(13), + char(0), + char(39), + char(0), + char(7), + char(0), + char(43), + char(0), + char(4), + char(0), + char(95), + char(0), + char(45), + char(0), + char(5), + char(0), + char(27), + char(0), + char(47), + char(0), + char(13), + char(0), + char(96), + char(0), + char(14), + char(0), + char(97), + char(0), + char(4), + char(0), + char(98), + char(0), + char(0), + char(0), + char(99), + char(0), + char(46), + char(0), + char(25), + char(0), + char(9), + char(0), + char(100), + char(0), + char(9), + char(0), + char(101), + char(0), + char(25), + char(0), + char(102), + char(0), + char(0), + char(0), + char(35), + char(0), + char(18), + char(0), + char(103), + char(0), + char(18), + char(0), + char(104), + char(0), + char(14), + char(0), + char(105), + char(0), + char(14), + char(0), + char(106), + char(0), + char(14), + char(0), + char(107), + char(0), + char(8), + char(0), + char(108), + char(0), + char(8), + char(0), + char(109), + char(0), + char(8), + char(0), + char(110), + char(0), + char(8), + char(0), + char(111), + char(0), + char(8), + char(0), + char(112), + char(0), + char(8), + char(0), + char(113), + char(0), + char(8), + char(0), + char(114), + char(0), + char(8), + char(0), + char(115), + char(0), + char(4), + char(0), + char(116), + char(0), + char(4), + char(0), + char(117), + char(0), + char(4), + char(0), + char(118), + char(0), + char(4), + char(0), + char(119), + char(0), + char(4), + char(0), + char(120), + char(0), + char(4), + char(0), + char(121), + char(0), + char(4), + char(0), + char(122), + char(0), + char(0), + char(0), + char(37), + char(0), + char(47), + char(0), + char(25), + char(0), + char(9), + char(0), + char(100), + char(0), + char(9), + char(0), + char(101), + char(0), + char(25), + char(0), + char(102), + char(0), + char(0), + char(0), + char(35), + char(0), + char(17), + char(0), + char(103), + char(0), + char(17), + char(0), + char(104), + char(0), + char(13), + char(0), + char(105), + char(0), + char(13), + char(0), + char(106), + char(0), + char(13), + char(0), + char(107), + char(0), + char(7), + char(0), + char(108), + char(0), + char(7), + char(0), + char(109), + char(0), + char(7), + char(0), + char(110), + char(0), + char(7), + char(0), + char(111), + char(0), + char(7), + char(0), + char(112), + char(0), + char(7), + char(0), + char(113), + char(0), + char(7), + char(0), + char(114), + char(0), + char(7), + char(0), + char(115), + char(0), + char(4), + char(0), + char(116), + char(0), + char(4), + char(0), + char(117), + char(0), + char(4), + char(0), + char(118), + char(0), + char(4), + char(0), + char(119), + char(0), + char(4), + char(0), + char(120), + char(0), + char(4), + char(0), + char(121), + char(0), + char(4), + char(0), + char(122), + char(0), + char(0), + char(0), + char(37), + char(0), + char(48), + char(0), + char(2), + char(0), + char(49), + char(0), + char(123), + char(0), + char(14), + char(0), + char(124), + char(0), + char(50), + char(0), + char(2), + char(0), + char(51), + char(0), + char(123), + char(0), + char(13), + char(0), + char(124), + char(0), + char(52), + char(0), + char(21), + char(0), + char(47), + char(0), + char(125), + char(0), + char(15), + char(0), + char(126), + char(0), + char(13), + char(0), + char(127), + char(0), + char(13), + char(0), + char(-128), + char(0), + char(13), + char(0), + char(-127), + char(0), + char(13), + char(0), + char(-126), + char(0), + char(13), + char(0), + char(124), + char(0), + char(13), + char(0), + char(-125), + char(0), + char(13), + char(0), + char(-124), + char(0), + char(13), + char(0), + char(-123), + char(0), + char(13), + char(0), + char(-122), + char(0), + char(7), + char(0), + char(-121), + char(0), + char(7), + char(0), + char(-120), + char(0), + char(7), + char(0), + char(-119), + char(0), + char(7), + char(0), + char(-118), + char(0), + char(7), + char(0), + char(-117), + char(0), + char(7), + char(0), + char(-116), + char(0), + char(7), + char(0), + char(-115), + char(0), + char(7), + char(0), + char(-114), + char(0), + char(7), + char(0), + char(-113), + char(0), + char(4), + char(0), + char(-112), + char(0), + char(53), + char(0), + char(22), + char(0), + char(46), + char(0), + char(125), + char(0), + char(16), + char(0), + char(126), + char(0), + char(14), + char(0), + char(127), + char(0), + char(14), + char(0), + char(-128), + char(0), + char(14), + char(0), + char(-127), + char(0), + char(14), + char(0), + char(-126), + char(0), + char(14), + char(0), + char(124), + char(0), + char(14), + char(0), + char(-125), + char(0), + char(14), + char(0), + char(-124), + char(0), + char(14), + char(0), + char(-123), + char(0), + char(14), + char(0), + char(-122), + char(0), + char(8), + char(0), + char(-121), + char(0), + char(8), + char(0), + char(-120), + char(0), + char(8), + char(0), + char(-119), + char(0), + char(8), + char(0), + char(-118), + char(0), + char(8), + char(0), + char(-117), + char(0), + char(8), + char(0), + char(-116), + char(0), + char(8), + char(0), + char(-115), + char(0), + char(8), + char(0), + char(-114), + char(0), + char(8), + char(0), + char(-113), + char(0), + char(4), + char(0), + char(-112), + char(0), + char(0), + char(0), + char(37), + char(0), + char(54), + char(0), + char(2), + char(0), + char(4), + char(0), + char(-111), + char(0), + char(4), + char(0), + char(-110), + char(0), + char(55), + char(0), + char(13), + char(0), + char(56), + char(0), + char(-109), + char(0), + char(56), + char(0), + char(-108), + char(0), + char(0), + char(0), + char(35), + char(0), + char(4), + char(0), + char(-107), + char(0), + char(4), + char(0), + char(-106), + char(0), + char(4), + char(0), + char(-105), + char(0), + char(4), + char(0), + char(-104), + char(0), + char(7), + char(0), + char(-103), + char(0), + char(7), + char(0), + char(-102), + char(0), + char(4), + char(0), + char(-101), + char(0), + char(4), + char(0), + char(-100), + char(0), + char(7), + char(0), + char(-99), + char(0), + char(4), + char(0), + char(-98), + char(0), + char(57), + char(0), + char(3), + char(0), + char(55), + char(0), + char(-97), + char(0), + char(13), + char(0), + char(-96), + char(0), + char(13), + char(0), + char(-95), + char(0), + char(58), + char(0), + char(3), + char(0), + char(55), + char(0), + char(-97), + char(0), + char(14), + char(0), + char(-96), + char(0), + char(14), + char(0), + char(-95), + char(0), + char(59), + char(0), + char(13), + char(0), + char(55), + char(0), + char(-97), + char(0), + char(18), + char(0), + char(-94), + char(0), + char(18), + char(0), + char(-93), + char(0), + char(4), + char(0), + char(-92), + char(0), + char(4), + char(0), + char(-91), + char(0), + char(4), + char(0), + char(-90), + char(0), + char(7), + char(0), + char(-89), + char(0), + char(7), + char(0), + char(-88), + char(0), + char(7), + char(0), + char(-87), + char(0), + char(7), + char(0), + char(-86), + char(0), + char(7), + char(0), + char(-85), + char(0), + char(7), + char(0), + char(-84), + char(0), + char(7), + char(0), + char(-83), + char(0), + char(60), + char(0), + char(13), + char(0), + char(55), + char(0), + char(-97), + char(0), + char(17), + char(0), + char(-94), + char(0), + char(17), + char(0), + char(-93), + char(0), + char(4), + char(0), + char(-92), + char(0), + char(4), + char(0), + char(-91), + char(0), + char(4), + char(0), + char(-90), + char(0), + char(7), + char(0), + char(-89), + char(0), + char(7), + char(0), + char(-88), + char(0), + char(7), + char(0), + char(-87), + char(0), + char(7), + char(0), + char(-86), + char(0), + char(7), + char(0), + char(-85), + char(0), + char(7), + char(0), + char(-84), + char(0), + char(7), + char(0), + char(-83), + char(0), + char(61), + char(0), + char(11), + char(0), + char(55), + char(0), + char(-97), + char(0), + char(17), + char(0), + char(-94), + char(0), + char(17), + char(0), + char(-93), + char(0), + char(7), + char(0), + char(-82), + char(0), + char(7), + char(0), + char(-81), + char(0), + char(7), + char(0), + char(-80), + char(0), + char(7), + char(0), + char(-85), + char(0), + char(7), + char(0), + char(-84), + char(0), + char(7), + char(0), + char(-83), + char(0), + char(7), + char(0), + char(-79), + char(0), + char(0), + char(0), + char(21), + char(0), + char(62), + char(0), + char(9), + char(0), + char(55), + char(0), + char(-97), + char(0), + char(17), + char(0), + char(-94), + char(0), + char(17), + char(0), + char(-93), + char(0), + char(13), + char(0), + char(-78), + char(0), + char(13), + char(0), + char(-77), + char(0), + char(13), + char(0), + char(-76), + char(0), + char(13), + char(0), + char(-75), + char(0), + char(4), + char(0), + char(-74), + char(0), + char(4), + char(0), + char(-73), + char(0), + char(63), + char(0), + char(5), + char(0), + char(62), + char(0), + char(-72), + char(0), + char(4), + char(0), + char(-71), + char(0), + char(7), + char(0), + char(-70), + char(0), + char(7), + char(0), + char(-69), + char(0), + char(7), + char(0), + char(-68), + char(0), + char(64), + char(0), + char(9), + char(0), + char(55), + char(0), + char(-97), + char(0), + char(17), + char(0), + char(-94), + char(0), + char(17), + char(0), + char(-93), + char(0), + char(7), + char(0), + char(-78), + char(0), + char(7), + char(0), + char(-77), + char(0), + char(7), + char(0), + char(-76), + char(0), + char(7), + char(0), + char(-75), + char(0), + char(4), + char(0), + char(-74), + char(0), + char(4), + char(0), + char(-73), + char(0), + char(49), + char(0), + char(22), + char(0), + char(8), + char(0), + char(-67), + char(0), + char(8), + char(0), + char(-79), + char(0), + char(8), + char(0), + char(110), + char(0), + char(8), + char(0), + char(-66), + char(0), + char(8), + char(0), + char(112), + char(0), + char(8), + char(0), + char(-65), + char(0), + char(8), + char(0), + char(-64), + char(0), + char(8), + char(0), + char(-63), + char(0), + char(8), + char(0), + char(-62), + char(0), + char(8), + char(0), + char(-61), + char(0), + char(8), + char(0), + char(-60), + char(0), + char(8), + char(0), + char(-59), + char(0), + char(8), + char(0), + char(-58), + char(0), + char(8), + char(0), + char(-57), + char(0), + char(8), + char(0), + char(-56), + char(0), + char(8), + char(0), + char(-55), + char(0), + char(4), + char(0), + char(-54), + char(0), + char(4), + char(0), + char(-53), + char(0), + char(4), + char(0), + char(-52), + char(0), + char(4), + char(0), + char(-51), + char(0), + char(4), + char(0), + char(-50), + char(0), + char(0), + char(0), + char(37), + char(0), + char(51), + char(0), + char(22), + char(0), + char(7), + char(0), + char(-67), + char(0), + char(7), + char(0), + char(-79), + char(0), + char(7), + char(0), + char(110), + char(0), + char(7), + char(0), + char(-66), + char(0), + char(7), + char(0), + char(112), + char(0), + char(7), + char(0), + char(-65), + char(0), + char(7), + char(0), + char(-64), + char(0), + char(7), + char(0), + char(-63), + char(0), + char(7), + char(0), + char(-62), + char(0), + char(7), + char(0), + char(-61), + char(0), + char(7), + char(0), + char(-60), + char(0), + char(7), + char(0), + char(-59), + char(0), + char(7), + char(0), + char(-58), + char(0), + char(7), + char(0), + char(-57), + char(0), + char(7), + char(0), + char(-56), + char(0), + char(7), + char(0), + char(-55), + char(0), + char(4), + char(0), + char(-54), + char(0), + char(4), + char(0), + char(-53), + char(0), + char(4), + char(0), + char(-52), + char(0), + char(4), + char(0), + char(-51), + char(0), + char(4), + char(0), + char(-50), + char(0), + char(0), + char(0), + char(37), + char(0), + char(65), + char(0), + char(4), + char(0), + char(7), + char(0), + char(-49), + char(0), + char(7), + char(0), + char(-48), + char(0), + char(7), + char(0), + char(-47), + char(0), + char(4), + char(0), + char(78), + char(0), + char(66), + char(0), + char(10), + char(0), + char(65), + char(0), + char(-46), + char(0), + char(13), + char(0), + char(-45), + char(0), + char(13), + char(0), + char(-44), + char(0), + char(13), + char(0), + char(-43), + char(0), + char(13), + char(0), + char(-42), + char(0), + char(13), + char(0), + char(-41), + char(0), + char(7), + char(0), + char(-121), + char(0), + char(7), + char(0), + char(-40), + char(0), + char(4), + char(0), + char(-39), + char(0), + char(4), + char(0), + char(53), + char(0), + char(67), + char(0), + char(4), + char(0), + char(65), + char(0), + char(-46), + char(0), + char(4), + char(0), + char(-38), + char(0), + char(7), + char(0), + char(-37), + char(0), + char(4), + char(0), + char(-36), + char(0), + char(68), + char(0), + char(4), + char(0), + char(13), + char(0), + char(-41), + char(0), + char(65), + char(0), + char(-46), + char(0), + char(4), + char(0), + char(-35), + char(0), + char(7), + char(0), + char(-34), + char(0), + char(69), + char(0), + char(7), + char(0), + char(13), + char(0), + char(-33), + char(0), + char(65), + char(0), + char(-46), + char(0), + char(4), + char(0), + char(-32), + char(0), + char(7), + char(0), + char(-31), + char(0), + char(7), + char(0), + char(-30), + char(0), + char(7), + char(0), + char(-29), + char(0), + char(4), + char(0), + char(53), + char(0), + char(70), + char(0), + char(6), + char(0), + char(15), + char(0), + char(-28), + char(0), + char(13), + char(0), + char(-30), + char(0), + char(13), + char(0), + char(-27), + char(0), + char(56), + char(0), + char(-26), + char(0), + char(4), + char(0), + char(-25), + char(0), + char(7), + char(0), + char(-29), + char(0), + char(71), + char(0), + char(26), + char(0), + char(4), + char(0), + char(-24), + char(0), + char(7), + char(0), + char(-23), + char(0), + char(7), + char(0), + char(-79), + char(0), + char(7), + char(0), + char(-22), + char(0), + char(7), + char(0), + char(-21), + char(0), + char(7), + char(0), + char(-20), + char(0), + char(7), + char(0), + char(-19), + char(0), + char(7), + char(0), + char(-18), + char(0), + char(7), + char(0), + char(-17), + char(0), + char(7), + char(0), + char(-16), + char(0), + char(7), + char(0), + char(-15), + char(0), + char(7), + char(0), + char(-14), + char(0), + char(7), + char(0), + char(-13), + char(0), + char(7), + char(0), + char(-12), + char(0), + char(7), + char(0), + char(-11), + char(0), + char(7), + char(0), + char(-10), + char(0), + char(7), + char(0), + char(-9), + char(0), + char(7), + char(0), + char(-8), + char(0), + char(7), + char(0), + char(-7), + char(0), + char(7), + char(0), + char(-6), + char(0), + char(7), + char(0), + char(-5), + char(0), + char(4), + char(0), + char(-4), + char(0), + char(4), + char(0), + char(-3), + char(0), + char(4), + char(0), + char(-2), + char(0), + char(4), + char(0), + char(-1), + char(0), + char(4), + char(0), + char(117), + char(0), + char(72), + char(0), + char(12), + char(0), + char(15), + char(0), + char(0), + char(1), + char(15), + char(0), + char(1), + char(1), + char(15), + char(0), + char(2), + char(1), + char(13), + char(0), + char(3), + char(1), + char(13), + char(0), + char(4), + char(1), + char(7), + char(0), + char(5), + char(1), + char(4), + char(0), + char(6), + char(1), + char(4), + char(0), + char(7), + char(1), + char(4), + char(0), + char(8), + char(1), + char(4), + char(0), + char(9), + char(1), + char(7), + char(0), + char(-31), + char(0), + char(4), + char(0), + char(53), + char(0), + char(73), + char(0), + char(27), + char(0), + char(17), + char(0), + char(10), + char(1), + char(15), + char(0), + char(11), + char(1), + char(15), + char(0), + char(12), + char(1), + char(13), + char(0), + char(3), + char(1), + char(13), + char(0), + char(13), + char(1), + char(13), + char(0), + char(14), + char(1), + char(13), + char(0), + char(15), + char(1), + char(13), + char(0), + char(16), + char(1), + char(13), + char(0), + char(17), + char(1), + char(4), + char(0), + char(18), + char(1), + char(7), + char(0), + char(19), + char(1), + char(4), + char(0), + char(20), + char(1), + char(4), + char(0), + char(21), + char(1), + char(4), + char(0), + char(22), + char(1), + char(7), + char(0), + char(23), + char(1), + char(7), + char(0), + char(24), + char(1), + char(4), + char(0), + char(25), + char(1), + char(4), + char(0), + char(26), + char(1), + char(7), + char(0), + char(27), + char(1), + char(7), + char(0), + char(28), + char(1), + char(7), + char(0), + char(29), + char(1), + char(7), + char(0), + char(30), + char(1), + char(7), + char(0), + char(31), + char(1), + char(7), + char(0), + char(32), + char(1), + char(4), + char(0), + char(33), + char(1), + char(4), + char(0), + char(34), + char(1), + char(4), + char(0), + char(35), + char(1), + char(74), + char(0), + char(12), + char(0), + char(9), + char(0), + char(36), + char(1), + char(9), + char(0), + char(37), + char(1), + char(13), + char(0), + char(38), + char(1), + char(7), + char(0), + char(39), + char(1), + char(7), + char(0), + char(-63), + char(0), + char(7), + char(0), + char(40), + char(1), + char(4), + char(0), + char(41), + char(1), + char(13), + char(0), + char(42), + char(1), + char(4), + char(0), + char(43), + char(1), + char(4), + char(0), + char(44), + char(1), + char(4), + char(0), + char(45), + char(1), + char(4), + char(0), + char(53), + char(0), + char(75), + char(0), + char(19), + char(0), + char(47), + char(0), + char(125), + char(0), + char(72), + char(0), + char(46), + char(1), + char(65), + char(0), + char(47), + char(1), + char(66), + char(0), + char(48), + char(1), + char(67), + char(0), + char(49), + char(1), + char(68), + char(0), + char(50), + char(1), + char(69), + char(0), + char(51), + char(1), + char(70), + char(0), + char(52), + char(1), + char(73), + char(0), + char(53), + char(1), + char(74), + char(0), + char(54), + char(1), + char(4), + char(0), + char(55), + char(1), + char(4), + char(0), + char(21), + char(1), + char(4), + char(0), + char(56), + char(1), + char(4), + char(0), + char(57), + char(1), + char(4), + char(0), + char(58), + char(1), + char(4), + char(0), + char(59), + char(1), + char(4), + char(0), + char(60), + char(1), + char(4), + char(0), + char(61), + char(1), + char(71), + char(0), + char(62), + char(1), +}; +int b3s_bulletDNAlen64 = sizeof(b3s_bulletDNAstr64); diff --git a/src/Bullet3Serialize/Bullet2FileLoader/b3Serializer.h b/src/Bullet3Serialize/Bullet2FileLoader/b3Serializer.h index 1c1ce4376..d9e153e23 100644 --- a/src/Bullet3Serialize/Bullet2FileLoader/b3Serializer.h +++ b/src/Bullet3Serialize/Bullet2FileLoader/b3Serializer.h @@ -16,158 +16,142 @@ subject to the following restrictions: #ifndef B3_SERIALIZER_H #define B3_SERIALIZER_H -#include "Bullet3Common/b3Scalar.h" // has definitions like B3_FORCE_INLINE +#include "Bullet3Common/b3Scalar.h" // has definitions like B3_FORCE_INLINE #include "Bullet3Common/b3StackAlloc.h" #include "Bullet3Common/b3HashMap.h" -#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__) +#if !defined(__CELLOS_LV2__) && !defined(__MWERKS__) #include #endif #include - - extern char b3s_bulletDNAstr[]; extern int b3s_bulletDNAlen; extern char b3s_bulletDNAstr64[]; extern int b3s_bulletDNAlen64; -B3_FORCE_INLINE int b3StrLen(const char* str) +B3_FORCE_INLINE int b3StrLen(const char* str) { - if (!str) - return(0); + if (!str) + return (0); int len = 0; - + while (*str != 0) { - str++; - len++; - } + str++; + len++; + } - return len; + return len; } - class b3Chunk { public: - int m_chunkCode; - int m_length; - void *m_oldPtr; - int m_dna_nr; - int m_number; + int m_chunkCode; + int m_length; + void* m_oldPtr; + int m_dna_nr; + int m_number; }; -enum b3SerializationFlags +enum b3SerializationFlags { B3_SERIALIZE_NO_BVH = 1, B3_SERIALIZE_NO_TRIANGLEINFOMAP = 2, B3_SERIALIZE_NO_DUPLICATE_ASSERT = 4 }; -class b3Serializer +class b3Serializer { - public: - virtual ~b3Serializer() {} - virtual const unsigned char* getBufferPointer() const = 0; + virtual const unsigned char* getBufferPointer() const = 0; - virtual int getCurrentBufferSize() const = 0; + virtual int getCurrentBufferSize() const = 0; - virtual b3Chunk* allocate(size_t size, int numElements) = 0; + virtual b3Chunk* allocate(size_t size, int numElements) = 0; - virtual void finalizeChunk(b3Chunk* chunk, const char* structType, int chunkCode,void* oldPtr)= 0; + virtual void finalizeChunk(b3Chunk* chunk, const char* structType, int chunkCode, void* oldPtr) = 0; - virtual void* findPointer(void* oldPtr) = 0; + virtual void* findPointer(void* oldPtr) = 0; - virtual void* getUniquePointer(void*oldPtr) = 0; + virtual void* getUniquePointer(void* oldPtr) = 0; - virtual void startSerialization() = 0; - - virtual void finishSerialization() = 0; + virtual void startSerialization() = 0; - virtual const char* findNameForPointer(const void* ptr) const = 0; + virtual void finishSerialization() = 0; - virtual void registerNameForPointer(const void* ptr, const char* name) = 0; + virtual const char* findNameForPointer(const void* ptr) const = 0; - virtual void serializeName(const char* ptr) = 0; + virtual void registerNameForPointer(const void* ptr, const char* name) = 0; - virtual int getSerializationFlags() const = 0; - - virtual void setSerializationFlags(int flags) = 0; + virtual void serializeName(const char* ptr) = 0; + virtual int getSerializationFlags() const = 0; + virtual void setSerializationFlags(int flags) = 0; }; - - #define B3_HEADER_LENGTH 12 -#if defined(__sgi) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__) -# define B3_MAKE_ID(a,b,c,d) ( (int)(a)<<24 | (int)(b)<<16 | (c)<<8 | (d) ) +#if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined(__PPC__) || defined(__ppc__) || defined(__BIG_ENDIAN__) +#define B3_MAKE_ID(a, b, c, d) ((int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d)) #else -# define B3_MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) ) +#define B3_MAKE_ID(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a)) #endif -#define B3_SOFTBODY_CODE B3_MAKE_ID('S','B','D','Y') -#define B3_COLLISIONOBJECT_CODE B3_MAKE_ID('C','O','B','J') -#define B3_RIGIDBODY_CODE B3_MAKE_ID('R','B','D','Y') -#define B3_CONSTRAINT_CODE B3_MAKE_ID('C','O','N','S') -#define B3_BOXSHAPE_CODE B3_MAKE_ID('B','O','X','S') -#define B3_QUANTIZED_BVH_CODE B3_MAKE_ID('Q','B','V','H') -#define B3_TRIANLGE_INFO_MAP B3_MAKE_ID('T','M','A','P') -#define B3_SHAPE_CODE B3_MAKE_ID('S','H','A','P') -#define B3_ARRAY_CODE B3_MAKE_ID('A','R','A','Y') -#define B3_SBMATERIAL_CODE B3_MAKE_ID('S','B','M','T') -#define B3_SBNODE_CODE B3_MAKE_ID('S','B','N','D') -#define B3_DYNAMICSWORLD_CODE B3_MAKE_ID('D','W','L','D') -#define B3_DNA_CODE B3_MAKE_ID('D','N','A','1') +#define B3_SOFTBODY_CODE B3_MAKE_ID('S', 'B', 'D', 'Y') +#define B3_COLLISIONOBJECT_CODE B3_MAKE_ID('C', 'O', 'B', 'J') +#define B3_RIGIDBODY_CODE B3_MAKE_ID('R', 'B', 'D', 'Y') +#define B3_CONSTRAINT_CODE B3_MAKE_ID('C', 'O', 'N', 'S') +#define B3_BOXSHAPE_CODE B3_MAKE_ID('B', 'O', 'X', 'S') +#define B3_QUANTIZED_BVH_CODE B3_MAKE_ID('Q', 'B', 'V', 'H') +#define B3_TRIANLGE_INFO_MAP B3_MAKE_ID('T', 'M', 'A', 'P') +#define B3_SHAPE_CODE B3_MAKE_ID('S', 'H', 'A', 'P') +#define B3_ARRAY_CODE B3_MAKE_ID('A', 'R', 'A', 'Y') +#define B3_SBMATERIAL_CODE B3_MAKE_ID('S', 'B', 'M', 'T') +#define B3_SBNODE_CODE B3_MAKE_ID('S', 'B', 'N', 'D') +#define B3_DYNAMICSWORLD_CODE B3_MAKE_ID('D', 'W', 'L', 'D') +#define B3_DNA_CODE B3_MAKE_ID('D', 'N', 'A', '1') - -struct b3PointerUid +struct b3PointerUid { - union - { - void* m_ptr; - int m_uniqueIds[2]; + union { + void* m_ptr; + int m_uniqueIds[2]; }; }; ///The b3DefaultSerializer is the main Bullet serialization class. ///The constructor takes an optional argument for backwards compatibility, it is recommended to leave this empty/zero. -class b3DefaultSerializer : public b3Serializer +class b3DefaultSerializer : public b3Serializer { + b3AlignedObjectArray mTypes; + b3AlignedObjectArray mStructs; + b3AlignedObjectArray mTlens; + b3HashMap mStructReverse; + b3HashMap mTypeLookup; + b3HashMap m_chunkP; - b3AlignedObjectArray mTypes; - b3AlignedObjectArray mStructs; - b3AlignedObjectArray mTlens; - b3HashMap mStructReverse; - b3HashMap mTypeLookup; + b3HashMap m_nameMap; - - b3HashMap m_chunkP; - - b3HashMap m_nameMap; + b3HashMap m_uniquePointers; + int m_uniqueIdGenerator; - b3HashMap m_uniquePointers; - int m_uniqueIdGenerator; + int m_totalSize; + unsigned char* m_buffer; + int m_currentSize; + void* m_dna; + int m_dnaLength; - int m_totalSize; - unsigned char* m_buffer; - int m_currentSize; - void* m_dna; - int m_dnaLength; + int m_serializationFlags; - int m_serializationFlags; + b3AlignedObjectArray m_chunkPtrs; - - b3AlignedObjectArray m_chunkPtrs; - protected: - - virtual void* findPointer(void* oldPtr) + virtual void* findPointer(void* oldPtr) { void** ptr = m_chunkP.find(oldPtr); if (ptr && *ptr) @@ -175,48 +159,43 @@ protected: return 0; } - + void writeDNA() + { + b3Chunk* dnaChunk = allocate(m_dnaLength, 1); + memcpy(dnaChunk->m_oldPtr, m_dna, m_dnaLength); + finalizeChunk(dnaChunk, "DNA1", B3_DNA_CODE, m_dna); + } + int getReverseType(const char* type) const + { + b3HashString key(type); + const int* valuePtr = mTypeLookup.find(key); + if (valuePtr) + return *valuePtr; + return -1; + } - void writeDNA() - { - b3Chunk* dnaChunk = allocate(m_dnaLength,1); - memcpy(dnaChunk->m_oldPtr,m_dna,m_dnaLength); - finalizeChunk(dnaChunk,"DNA1",B3_DNA_CODE, m_dna); - } + void initDNA(const char* bdnaOrg, int dnalen) + { + ///was already initialized + if (m_dna) + return; - int getReverseType(const char *type) const - { + int littleEndian = 1; + littleEndian = ((char*)&littleEndian)[0]; - b3HashString key(type); - const int* valuePtr = mTypeLookup.find(key); - if (valuePtr) - return *valuePtr; - - return -1; - } + m_dna = b3AlignedAlloc(dnalen, 16); + memcpy(m_dna, bdnaOrg, dnalen); + m_dnaLength = dnalen; - void initDNA(const char* bdnaOrg,int dnalen) - { - ///was already initialized - if (m_dna) - return; + int* intPtr = 0; + short* shtPtr = 0; + char* cp = 0; + int dataLen = 0; + intPtr = (int*)m_dna; - int littleEndian= 1; - littleEndian= ((char*)&littleEndian)[0]; - - - m_dna = b3AlignedAlloc(dnalen,16); - memcpy(m_dna,bdnaOrg,dnalen); - m_dnaLength = dnalen; - - int *intPtr=0; - short *shtPtr=0; - char *cp = 0;int dataLen =0; - intPtr = (int*)m_dna; - - /* + /* SDNA (4 bytes) (magic number) NAME (4 bytes) (4 bytes) amount of names (int) @@ -224,81 +203,81 @@ protected: */ - if (strncmp((const char*)m_dna, "SDNA", 4)==0) - { - // skip ++ NAME - intPtr++; intPtr++; - } - - // Parse names - if (!littleEndian) - *intPtr = b3SwapEndian(*intPtr); - - dataLen = *intPtr; - + if (strncmp((const char*)m_dna, "SDNA", 4) == 0) + { + // skip ++ NAME intPtr++; + intPtr++; + } - cp = (char*)intPtr; - int i; - for ( i=0; i amount of types (int) */ - intPtr = (int*)cp; - b3Assert(strncmp(cp, "TYPE", 4)==0); intPtr++; + intPtr = (int*)cp; + b3Assert(strncmp(cp, "TYPE", 4) == 0); + intPtr++; - if (!littleEndian) - *intPtr = b3SwapEndian(*intPtr); - - dataLen = *intPtr; - intPtr++; + if (!littleEndian) + *intPtr = b3SwapEndian(*intPtr); - - cp = (char*)intPtr; - for (i=0; i (short) the lengths of types */ - // Parse type lens - intPtr = (int*)cp; - b3Assert(strncmp(cp, "TLEN", 4)==0); intPtr++; + // Parse type lens + intPtr = (int*)cp; + b3Assert(strncmp(cp, "TLEN", 4) == 0); + intPtr++; - dataLen = (int)mTypes.size(); + dataLen = (int)mTypes.size(); - shtPtr = (short*)intPtr; - for (i=0; i amount of structs (int) @@ -309,331 +288,314 @@ protected: */ - intPtr = (int*)shtPtr; - cp = (char*)intPtr; - b3Assert(strncmp(cp, "STRC", 4)==0); intPtr++; + intPtr = (int*)shtPtr; + cp = (char*)intPtr; + b3Assert(strncmp(cp, "STRC", 4) == 0); + intPtr++; + + if (!littleEndian) + *intPtr = b3SwapEndian(*intPtr); + dataLen = *intPtr; + intPtr++; + + shtPtr = (short*)intPtr; + for (i = 0; i < dataLen; i++) + { + mStructs.push_back(shtPtr); if (!littleEndian) - *intPtr = b3SwapEndian(*intPtr); - dataLen = *intPtr ; - intPtr++; - - - shtPtr = (short*)intPtr; - for (i=0; im_length; + memcpy(currentPtr, m_chunkPtrs[i], curLength); + b3AlignedFree(m_chunkPtrs[i]); + currentPtr += curLength; + mysize += curLength; } - - if (littleEndian) - { - buffer[8]='v'; - } else - { - buffer[8]='V'; - } - - - buffer[9] = '2'; - buffer[10] = '8'; - buffer[11] = '1'; - } - virtual void startSerialization() - { - m_uniqueIdGenerator= 1; - if (m_totalSize) - { - unsigned char* buffer = internalAlloc(B3_HEADER_LENGTH); - writeHeader(buffer); - } - - } + mTypes.clear(); + mStructs.clear(); + mTlens.clear(); + mStructReverse.clear(); + mTypeLookup.clear(); + m_chunkP.clear(); + m_nameMap.clear(); + m_uniquePointers.clear(); + m_chunkPtrs.clear(); + } - virtual void finishSerialization() - { - writeDNA(); - - //if we didn't pre-allocate a buffer, we need to create a contiguous buffer now - int mysize = 0; - if (!m_totalSize) - { - if (m_buffer) - b3AlignedFree(m_buffer); - - m_currentSize += B3_HEADER_LENGTH; - m_buffer = (unsigned char*)b3AlignedAlloc(m_currentSize,16); - - unsigned char* currentPtr = m_buffer; - writeHeader(m_buffer); - currentPtr += B3_HEADER_LENGTH; - mysize+=B3_HEADER_LENGTH; - for (int i=0;i< m_chunkPtrs.size();i++) - { - int curLength = sizeof(b3Chunk)+m_chunkPtrs[i]->m_length; - memcpy(currentPtr,m_chunkPtrs[i], curLength); - b3AlignedFree(m_chunkPtrs[i]); - currentPtr+=curLength; - mysize+=curLength; - } - } - - mTypes.clear(); - mStructs.clear(); - mTlens.clear(); - mStructReverse.clear(); - mTypeLookup.clear(); - m_chunkP.clear(); - m_nameMap.clear(); - m_uniquePointers.clear(); - m_chunkPtrs.clear(); - } - - virtual void* getUniquePointer(void*oldPtr) - { - if (!oldPtr) - return 0; - - b3PointerUid* uptr = (b3PointerUid*)m_uniquePointers.find(oldPtr); - if (uptr) - { - return uptr->m_ptr; - } - m_uniqueIdGenerator++; - - b3PointerUid uid; - uid.m_uniqueIds[0] = m_uniqueIdGenerator; - uid.m_uniqueIds[1] = m_uniqueIdGenerator; - m_uniquePointers.insert(oldPtr,uid); - return uid.m_ptr; - - } - - virtual const unsigned char* getBufferPointer() const - { - return m_buffer; - } - - virtual int getCurrentBufferSize() const - { - return m_currentSize; - } - - virtual void finalizeChunk(b3Chunk* chunk, const char* structType, int chunkCode,void* oldPtr) - { - if (!(m_serializationFlags&B3_SERIALIZE_NO_DUPLICATE_ASSERT)) - { - b3Assert(!findPointer(oldPtr)); - } - - chunk->m_dna_nr = getReverseType(structType); - - chunk->m_chunkCode = chunkCode; - - void* uniquePtr = getUniquePointer(oldPtr); - - m_chunkP.insert(oldPtr,uniquePtr);//chunk->m_oldPtr); - chunk->m_oldPtr = uniquePtr;//oldPtr; - - } - - - virtual unsigned char* internalAlloc(size_t size) - { - unsigned char* ptr = 0; - - if (m_totalSize) - { - ptr = m_buffer+m_currentSize; - m_currentSize += int(size); - b3Assert(m_currentSizem_chunkCode = 0; - chunk->m_oldPtr = data; - chunk->m_length = int(size)*numElements; - chunk->m_number = numElements; - - m_chunkPtrs.push_back(chunk); - - - return chunk; - } - - virtual const char* findNameForPointer(const void* ptr) const - { - const char*const * namePtr = m_nameMap.find(ptr); - if (namePtr && *namePtr) - return *namePtr; + virtual void* getUniquePointer(void* oldPtr) + { + if (!oldPtr) return 0; + b3PointerUid* uptr = (b3PointerUid*)m_uniquePointers.find(oldPtr); + if (uptr) + { + return uptr->m_ptr; + } + m_uniqueIdGenerator++; + + b3PointerUid uid; + uid.m_uniqueIds[0] = m_uniqueIdGenerator; + uid.m_uniqueIds[1] = m_uniqueIdGenerator; + m_uniquePointers.insert(oldPtr, uid); + return uid.m_ptr; + } + + virtual const unsigned char* getBufferPointer() const + { + return m_buffer; + } + + virtual int getCurrentBufferSize() const + { + return m_currentSize; + } + + virtual void finalizeChunk(b3Chunk* chunk, const char* structType, int chunkCode, void* oldPtr) + { + if (!(m_serializationFlags & B3_SERIALIZE_NO_DUPLICATE_ASSERT)) + { + b3Assert(!findPointer(oldPtr)); } - virtual void registerNameForPointer(const void* ptr, const char* name) - { - m_nameMap.insert(ptr,name); - } + chunk->m_dna_nr = getReverseType(structType); - virtual void serializeName(const char* name) + chunk->m_chunkCode = chunkCode; + + void* uniquePtr = getUniquePointer(oldPtr); + + m_chunkP.insert(oldPtr, uniquePtr); //chunk->m_oldPtr); + chunk->m_oldPtr = uniquePtr; //oldPtr; + } + + virtual unsigned char* internalAlloc(size_t size) + { + unsigned char* ptr = 0; + + if (m_totalSize) { - if (name) + ptr = m_buffer + m_currentSize; + m_currentSize += int(size); + b3Assert(m_currentSize < m_totalSize); + } + else + { + ptr = (unsigned char*)b3AlignedAlloc(size, 16); + m_currentSize += int(size); + } + return ptr; + } + + virtual b3Chunk* allocate(size_t size, int numElements) + { + unsigned char* ptr = internalAlloc(int(size) * numElements + sizeof(b3Chunk)); + + unsigned char* data = ptr + sizeof(b3Chunk); + + b3Chunk* chunk = (b3Chunk*)ptr; + chunk->m_chunkCode = 0; + chunk->m_oldPtr = data; + chunk->m_length = int(size) * numElements; + chunk->m_number = numElements; + + m_chunkPtrs.push_back(chunk); + + return chunk; + } + + virtual const char* findNameForPointer(const void* ptr) const + { + const char* const* namePtr = m_nameMap.find(ptr); + if (namePtr && *namePtr) + return *namePtr; + return 0; + } + + virtual void registerNameForPointer(const void* ptr, const char* name) + { + m_nameMap.insert(ptr, name); + } + + virtual void serializeName(const char* name) + { + if (name) + { + //don't serialize name twice + if (findPointer((void*)name)) + return; + + int len = b3StrLen(name); + if (len) { - //don't serialize name twice - if (findPointer((void*)name)) - return; + int newLen = len + 1; + int padding = ((newLen + 3) & ~3) - newLen; + newLen += padding; - int len = b3StrLen(name); - if (len) + //serialize name string now + b3Chunk* chunk = allocate(sizeof(char), newLen); + char* destinationName = (char*)chunk->m_oldPtr; + for (int i = 0; i < len; i++) { - - int newLen = len+1; - int padding = ((newLen+3)&~3)-newLen; - newLen += padding; - - //serialize name string now - b3Chunk* chunk = allocate(sizeof(char),newLen); - char* destinationName = (char*)chunk->m_oldPtr; - for (int i=0;i(worldAabbMin,worldAabbMax,0xfffe,0xffff,maxHandles,pairCache,disableRaycastAccelerator) +btAxisSweep3::btAxisSweep3(const btVector3& worldAabbMin, const btVector3& worldAabbMax, unsigned short int maxHandles, btOverlappingPairCache* pairCache, bool disableRaycastAccelerator) + : btAxisSweep3Internal(worldAabbMin, worldAabbMax, 0xfffe, 0xffff, maxHandles, pairCache, disableRaycastAccelerator) { // 1 handle is reserved as sentinel btAssert(maxHandles > 1 && maxHandles < 32767); - } - -bt32BitAxisSweep3::bt32BitAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned int maxHandles , btOverlappingPairCache* pairCache , bool disableRaycastAccelerator) -:btAxisSweep3Internal(worldAabbMin,worldAabbMax,0xfffffffe,0x7fffffff,maxHandles,pairCache,disableRaycastAccelerator) +bt32BitAxisSweep3::bt32BitAxisSweep3(const btVector3& worldAabbMin, const btVector3& worldAabbMax, unsigned int maxHandles, btOverlappingPairCache* pairCache, bool disableRaycastAccelerator) + : btAxisSweep3Internal(worldAabbMin, worldAabbMax, 0xfffffffe, 0x7fffffff, maxHandles, pairCache, disableRaycastAccelerator) { // 1 handle is reserved as sentinel btAssert(maxHandles > 1 && maxHandles < 2147483647); diff --git a/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h b/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h index a3648df1a..1e42f25f3 100644 --- a/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h +++ b/src/BulletCollision/BroadphaseCollision/btAxisSweep3.h @@ -33,9 +33,7 @@ class btAxisSweep3 : public btAxisSweep3Internal { public: - - btAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false); - + btAxisSweep3(const btVector3& worldAabbMin, const btVector3& worldAabbMax, unsigned short int maxHandles = 16384, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false); }; /// The bt32BitAxisSweep3 allows higher precision quantization and more objects compared to the btAxisSweep3 sweep and prune. @@ -44,9 +42,7 @@ public: class bt32BitAxisSweep3 : public btAxisSweep3Internal { public: - - bt32BitAxisSweep3(const btVector3& worldAabbMin,const btVector3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false); - + bt32BitAxisSweep3(const btVector3& worldAabbMin, const btVector3& worldAabbMax, unsigned int maxHandles = 1500000, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false); }; #endif diff --git a/src/BulletCollision/BroadphaseCollision/btAxisSweep3Internal.h b/src/BulletCollision/BroadphaseCollision/btAxisSweep3Internal.h index 323aa96dc..2ee35528f 100644 --- a/src/BulletCollision/BroadphaseCollision/btAxisSweep3Internal.h +++ b/src/BulletCollision/BroadphaseCollision/btAxisSweep3Internal.h @@ -36,172 +36,158 @@ template class btAxisSweep3Internal : public btBroadphaseInterface { protected: - - BP_FP_INT_TYPE m_bpHandleMask; - BP_FP_INT_TYPE m_handleSentinel; + BP_FP_INT_TYPE m_bpHandleMask; + BP_FP_INT_TYPE m_handleSentinel; public: - - BT_DECLARE_ALIGNED_ALLOCATOR(); + BT_DECLARE_ALIGNED_ALLOCATOR(); class Edge { public: - BP_FP_INT_TYPE m_pos; // low bit is min/max + BP_FP_INT_TYPE m_pos; // low bit is min/max BP_FP_INT_TYPE m_handle; - BP_FP_INT_TYPE IsMax() const {return static_cast(m_pos & 1);} + BP_FP_INT_TYPE IsMax() const { return static_cast(m_pos & 1); } }; public: - class Handle : public btBroadphaseProxy + class Handle : public btBroadphaseProxy { public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - + BT_DECLARE_ALIGNED_ALLOCATOR(); + // indexes into the edge arrays - BP_FP_INT_TYPE m_minEdges[3], m_maxEdges[3]; // 6 * 2 = 12 -// BP_FP_INT_TYPE m_uniqueId; - btBroadphaseProxy* m_dbvtProxy;//for faster raycast + BP_FP_INT_TYPE m_minEdges[3], m_maxEdges[3]; // 6 * 2 = 12 + // BP_FP_INT_TYPE m_uniqueId; + btBroadphaseProxy* m_dbvtProxy; //for faster raycast //void* m_pOwner; this is now in btBroadphaseProxy.m_clientObject - - SIMD_FORCE_INLINE void SetNextFree(BP_FP_INT_TYPE next) {m_minEdges[0] = next;} - SIMD_FORCE_INLINE BP_FP_INT_TYPE GetNextFree() const {return m_minEdges[0];} - }; // 24 bytes + 24 for Edge structures = 44 bytes total per entry - + SIMD_FORCE_INLINE void SetNextFree(BP_FP_INT_TYPE next) { m_minEdges[0] = next; } + SIMD_FORCE_INLINE BP_FP_INT_TYPE GetNextFree() const { return m_minEdges[0]; } + }; // 24 bytes + 24 for Edge structures = 44 bytes total per entry + protected: - btVector3 m_worldAabbMin; // overall system bounds - btVector3 m_worldAabbMax; // overall system bounds + btVector3 m_worldAabbMin; // overall system bounds + btVector3 m_worldAabbMax; // overall system bounds - btVector3 m_quantize; // scaling factor for quantization + btVector3 m_quantize; // scaling factor for quantization - BP_FP_INT_TYPE m_numHandles; // number of active handles - BP_FP_INT_TYPE m_maxHandles; // max number of handles - Handle* m_pHandles; // handles pool - - BP_FP_INT_TYPE m_firstFreeHandle; // free handles list + BP_FP_INT_TYPE m_numHandles; // number of active handles + BP_FP_INT_TYPE m_maxHandles; // max number of handles + Handle* m_pHandles; // handles pool - Edge* m_pEdges[3]; // edge arrays for the 3 axes (each array has m_maxHandles * 2 + 2 sentinel entries) + BP_FP_INT_TYPE m_firstFreeHandle; // free handles list + + Edge* m_pEdges[3]; // edge arrays for the 3 axes (each array has m_maxHandles * 2 + 2 sentinel entries) void* m_pEdgesRawPtr[3]; btOverlappingPairCache* m_pairCache; ///btOverlappingPairCallback is an additional optional user callback for adding/removing overlapping pairs, similar interface to btOverlappingPairCache. btOverlappingPairCallback* m_userPairCallback; - - bool m_ownsPairCache; - int m_invalidPair; + bool m_ownsPairCache; + + int m_invalidPair; ///additional dynamic aabb structure, used to accelerate ray cast queries. ///can be disabled using a optional argument in the constructor - btDbvtBroadphase* m_raycastAccelerator; - btOverlappingPairCache* m_nullPairCache; - + btDbvtBroadphase* m_raycastAccelerator; + btOverlappingPairCache* m_nullPairCache; // allocation/deallocation BP_FP_INT_TYPE allocHandle(); void freeHandle(BP_FP_INT_TYPE handle); - - bool testOverlap2D(const Handle* pHandleA, const Handle* pHandleB,int axis0,int axis1); + bool testOverlap2D(const Handle* pHandleA, const Handle* pHandleB, int axis0, int axis1); #ifdef DEBUG_BROADPHASE - void debugPrintAxis(int axis,bool checkCardinality=true); -#endif //DEBUG_BROADPHASE + void debugPrintAxis(int axis, bool checkCardinality = true); +#endif //DEBUG_BROADPHASE //Overlap* AddOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB); //void RemoveOverlap(BP_FP_INT_TYPE handleA, BP_FP_INT_TYPE handleB); - - - void sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); - void sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); - void sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); - void sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps ); + void sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps); + void sortMinUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps); + void sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps); + void sortMaxUp(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps); public: + btAxisSweep3Internal(const btVector3& worldAabbMin, const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache = 0, bool disableRaycastAccelerator = false); - btAxisSweep3Internal(const btVector3& worldAabbMin,const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE maxHandles = 16384, btOverlappingPairCache* pairCache=0,bool disableRaycastAccelerator = false); - - virtual ~btAxisSweep3Internal(); + virtual ~btAxisSweep3Internal(); BP_FP_INT_TYPE getNumHandles() const { return m_numHandles; } - virtual void calculateOverlappingPairs(btDispatcher* dispatcher); - - BP_FP_INT_TYPE addHandle(const btVector3& aabbMin,const btVector3& aabbMax, void* pOwner, int collisionFilterGroup, int collisionFilterMask,btDispatcher* dispatcher); - void removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher); - void updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher); - SIMD_FORCE_INLINE Handle* getHandle(BP_FP_INT_TYPE index) const {return m_pHandles + index;} + virtual void calculateOverlappingPairs(btDispatcher* dispatcher); + + BP_FP_INT_TYPE addHandle(const btVector3& aabbMin, const btVector3& aabbMax, void* pOwner, int collisionFilterGroup, int collisionFilterMask, btDispatcher* dispatcher); + void removeHandle(BP_FP_INT_TYPE handle, btDispatcher* dispatcher); + void updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin, const btVector3& aabbMax, btDispatcher* dispatcher); + SIMD_FORCE_INLINE Handle* getHandle(BP_FP_INT_TYPE index) const { return m_pHandles + index; } virtual void resetPool(btDispatcher* dispatcher); - void processAllOverlappingPairs(btOverlapCallback* callback); + void processAllOverlappingPairs(btOverlapCallback* callback); //Broadphase Interface - virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr , int collisionFilterGroup, int collisionFilterMask,btDispatcher* dispatcher); - virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); - virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher); - virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const; - - virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0)); - virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback); + virtual btBroadphaseProxy* createProxy(const btVector3& aabbMin, const btVector3& aabbMax, int shapeType, void* userPtr, int collisionFilterGroup, int collisionFilterMask, btDispatcher* dispatcher); + virtual void destroyProxy(btBroadphaseProxy* proxy, btDispatcher* dispatcher); + virtual void setAabb(btBroadphaseProxy* proxy, const btVector3& aabbMin, const btVector3& aabbMax, btDispatcher* dispatcher); + virtual void getAabb(btBroadphaseProxy* proxy, btVector3& aabbMin, btVector3& aabbMax) const; + + virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin = btVector3(0, 0, 0), const btVector3& aabbMax = btVector3(0, 0, 0)); + virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback); - void quantize(BP_FP_INT_TYPE* out, const btVector3& point, int isMax) const; ///unQuantize should be conservative: aabbMin/aabbMax should be larger then 'getAabb' result - void unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const; - - bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); + void unQuantize(btBroadphaseProxy* proxy, btVector3& aabbMin, btVector3& aabbMax) const; - btOverlappingPairCache* getOverlappingPairCache() + bool testAabbOverlap(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1); + + btOverlappingPairCache* getOverlappingPairCache() { return m_pairCache; } - const btOverlappingPairCache* getOverlappingPairCache() const + const btOverlappingPairCache* getOverlappingPairCache() const { return m_pairCache; } - void setOverlappingPairUserCallback(btOverlappingPairCallback* pairCallback) + void setOverlappingPairUserCallback(btOverlappingPairCallback* pairCallback) { m_userPairCallback = pairCallback; } - const btOverlappingPairCallback* getOverlappingPairUserCallback() const + const btOverlappingPairCallback* getOverlappingPairUserCallback() const { return m_userPairCallback; } ///getAabb returns the axis aligned bounding box in the 'global' coordinate frame ///will add some transform later - virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const + virtual void getBroadphaseAabb(btVector3& aabbMin, btVector3& aabbMax) const { aabbMin = m_worldAabbMin; aabbMax = m_worldAabbMax; } - virtual void printStats() + virtual void printStats() { -/* printf("btAxisSweep3.h\n"); + /* printf("btAxisSweep3.h\n"); printf("numHandles = %d, maxHandles = %d\n",m_numHandles,m_maxHandles); printf("aabbMin=%f,%f,%f,aabbMax=%f,%f,%f\n",m_worldAabbMin.getX(),m_worldAabbMin.getY(),m_worldAabbMin.getZ(), m_worldAabbMax.getX(),m_worldAabbMax.getY(),m_worldAabbMax.getZ()); */ - } - }; //////////////////////////////////////////////////////////////////// - - - #ifdef DEBUG_BROADPHASE #include @@ -209,75 +195,73 @@ template void btAxisSweep3::debugPrintAxis(int axis, bool checkCardinality) { int numEdges = m_pHandles[0].m_maxEdges[axis]; - printf("SAP Axis %d, numEdges=%d\n",axis,numEdges); + printf("SAP Axis %d, numEdges=%d\n", axis, numEdges); int i; - for (i=0;im_handle); - int handleIndex = pEdge->IsMax()? pHandlePrev->m_maxEdges[axis] : pHandlePrev->m_minEdges[axis]; + int handleIndex = pEdge->IsMax() ? pHandlePrev->m_maxEdges[axis] : pHandlePrev->m_minEdges[axis]; char beginOrEnd; - beginOrEnd=pEdge->IsMax()?'E':'B'; - printf(" [%c,h=%d,p=%x,i=%d]\n",beginOrEnd,pEdge->m_handle,pEdge->m_pos,handleIndex); + beginOrEnd = pEdge->IsMax() ? 'E' : 'B'; + printf(" [%c,h=%d,p=%x,i=%d]\n", beginOrEnd, pEdge->m_handle, pEdge->m_pos, handleIndex); } if (checkCardinality) - btAssert(numEdges == m_numHandles*2+1); + btAssert(numEdges == m_numHandles * 2 + 1); } -#endif //DEBUG_BROADPHASE +#endif //DEBUG_BROADPHASE template -btBroadphaseProxy* btAxisSweep3Internal::createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, int collisionFilterGroup, int collisionFilterMask,btDispatcher* dispatcher) +btBroadphaseProxy* btAxisSweep3Internal::createProxy(const btVector3& aabbMin, const btVector3& aabbMax, int shapeType, void* userPtr, int collisionFilterGroup, int collisionFilterMask, btDispatcher* dispatcher) { - (void)shapeType; - BP_FP_INT_TYPE handleId = addHandle(aabbMin,aabbMax, userPtr,collisionFilterGroup,collisionFilterMask,dispatcher); - - Handle* handle = getHandle(handleId); - - if (m_raycastAccelerator) - { - btBroadphaseProxy* rayProxy = m_raycastAccelerator->createProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask,dispatcher); - handle->m_dbvtProxy = rayProxy; - } - return handle; + (void)shapeType; + BP_FP_INT_TYPE handleId = addHandle(aabbMin, aabbMax, userPtr, collisionFilterGroup, collisionFilterMask, dispatcher); + + Handle* handle = getHandle(handleId); + + if (m_raycastAccelerator) + { + btBroadphaseProxy* rayProxy = m_raycastAccelerator->createProxy(aabbMin, aabbMax, shapeType, userPtr, collisionFilterGroup, collisionFilterMask, dispatcher); + handle->m_dbvtProxy = rayProxy; + } + return handle; } - - template -void btAxisSweep3Internal::destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher) +void btAxisSweep3Internal::destroyProxy(btBroadphaseProxy* proxy, btDispatcher* dispatcher) { Handle* handle = static_cast(proxy); if (m_raycastAccelerator) - m_raycastAccelerator->destroyProxy(handle->m_dbvtProxy,dispatcher); + m_raycastAccelerator->destroyProxy(handle->m_dbvtProxy, dispatcher); removeHandle(static_cast(handle->m_uniqueId), dispatcher); } template -void btAxisSweep3Internal::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher) +void btAxisSweep3Internal::setAabb(btBroadphaseProxy* proxy, const btVector3& aabbMin, const btVector3& aabbMax, btDispatcher* dispatcher) { Handle* handle = static_cast(proxy); handle->m_aabbMin = aabbMin; handle->m_aabbMax = aabbMax; - updateHandle(static_cast(handle->m_uniqueId), aabbMin, aabbMax,dispatcher); + updateHandle(static_cast(handle->m_uniqueId), aabbMin, aabbMax, dispatcher); if (m_raycastAccelerator) - m_raycastAccelerator->setAabb(handle->m_dbvtProxy,aabbMin,aabbMax,dispatcher); - + m_raycastAccelerator->setAabb(handle->m_dbvtProxy, aabbMin, aabbMax, dispatcher); } template -void btAxisSweep3Internal::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin,const btVector3& aabbMax) +void btAxisSweep3Internal::rayTest(const btVector3& rayFrom, const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin, const btVector3& aabbMax) { if (m_raycastAccelerator) { - m_raycastAccelerator->rayTest(rayFrom,rayTo,rayCallback,aabbMin,aabbMax); - } else + m_raycastAccelerator->rayTest(rayFrom, rayTo, rayCallback, aabbMin, aabbMax); + } + else { //choose axis? BP_FP_INT_TYPE axis = 0; //for each proxy - for (BP_FP_INT_TYPE i=1;i::rayTest(const btVector3& rayFrom,cons } template -void btAxisSweep3Internal::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback) +void btAxisSweep3Internal::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback) { if (m_raycastAccelerator) { - m_raycastAccelerator->aabbTest(aabbMin,aabbMax,callback); - } else + m_raycastAccelerator->aabbTest(aabbMin, aabbMax, callback); + } + else { //choose axis? BP_FP_INT_TYPE axis = 0; //for each proxy - for (BP_FP_INT_TYPE i=1;im_aabbMin,handle->m_aabbMax)) + if (TestAabbAgainstAabb2(aabbMin, aabbMax, handle->m_aabbMin, handle->m_aabbMax)) { callback.process(handle); } @@ -312,66 +297,60 @@ void btAxisSweep3Internal::aabbTest(const btVector3& aabbMin, co } } - - template -void btAxisSweep3Internal::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const +void btAxisSweep3Internal::getAabb(btBroadphaseProxy* proxy, btVector3& aabbMin, btVector3& aabbMax) const { Handle* pHandle = static_cast(proxy); aabbMin = pHandle->m_aabbMin; aabbMax = pHandle->m_aabbMax; } - template -void btAxisSweep3Internal::unQuantize(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const +void btAxisSweep3Internal::unQuantize(btBroadphaseProxy* proxy, btVector3& aabbMin, btVector3& aabbMax) const { Handle* pHandle = static_cast(proxy); unsigned short vecInMin[3]; unsigned short vecInMax[3]; - vecInMin[0] = m_pEdges[0][pHandle->m_minEdges[0]].m_pos ; - vecInMax[0] = m_pEdges[0][pHandle->m_maxEdges[0]].m_pos +1 ; - vecInMin[1] = m_pEdges[1][pHandle->m_minEdges[1]].m_pos ; - vecInMax[1] = m_pEdges[1][pHandle->m_maxEdges[1]].m_pos +1 ; - vecInMin[2] = m_pEdges[2][pHandle->m_minEdges[2]].m_pos ; - vecInMax[2] = m_pEdges[2][pHandle->m_maxEdges[2]].m_pos +1 ; - - aabbMin.setValue((btScalar)(vecInMin[0]) / (m_quantize.getX()),(btScalar)(vecInMin[1]) / (m_quantize.getY()),(btScalar)(vecInMin[2]) / (m_quantize.getZ())); + vecInMin[0] = m_pEdges[0][pHandle->m_minEdges[0]].m_pos; + vecInMax[0] = m_pEdges[0][pHandle->m_maxEdges[0]].m_pos + 1; + vecInMin[1] = m_pEdges[1][pHandle->m_minEdges[1]].m_pos; + vecInMax[1] = m_pEdges[1][pHandle->m_maxEdges[1]].m_pos + 1; + vecInMin[2] = m_pEdges[2][pHandle->m_minEdges[2]].m_pos; + vecInMax[2] = m_pEdges[2][pHandle->m_maxEdges[2]].m_pos + 1; + + aabbMin.setValue((btScalar)(vecInMin[0]) / (m_quantize.getX()), (btScalar)(vecInMin[1]) / (m_quantize.getY()), (btScalar)(vecInMin[2]) / (m_quantize.getZ())); aabbMin += m_worldAabbMin; - - aabbMax.setValue((btScalar)(vecInMax[0]) / (m_quantize.getX()),(btScalar)(vecInMax[1]) / (m_quantize.getY()),(btScalar)(vecInMax[2]) / (m_quantize.getZ())); + + aabbMax.setValue((btScalar)(vecInMax[0]) / (m_quantize.getX()), (btScalar)(vecInMax[1]) / (m_quantize.getY()), (btScalar)(vecInMax[2]) / (m_quantize.getZ())); aabbMax += m_worldAabbMin; } - - - template -btAxisSweep3Internal::btAxisSweep3Internal(const btVector3& worldAabbMin,const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel,BP_FP_INT_TYPE userMaxHandles, btOverlappingPairCache* pairCache , bool disableRaycastAccelerator) -:m_bpHandleMask(handleMask), -m_handleSentinel(handleSentinel), -m_pairCache(pairCache), -m_userPairCallback(0), -m_ownsPairCache(false), -m_invalidPair(0), -m_raycastAccelerator(0) +btAxisSweep3Internal::btAxisSweep3Internal(const btVector3& worldAabbMin, const btVector3& worldAabbMax, BP_FP_INT_TYPE handleMask, BP_FP_INT_TYPE handleSentinel, BP_FP_INT_TYPE userMaxHandles, btOverlappingPairCache* pairCache, bool disableRaycastAccelerator) + : m_bpHandleMask(handleMask), + m_handleSentinel(handleSentinel), + m_pairCache(pairCache), + m_userPairCallback(0), + m_ownsPairCache(false), + m_invalidPair(0), + m_raycastAccelerator(0) { - BP_FP_INT_TYPE maxHandles = static_cast(userMaxHandles+1);//need to add one sentinel handle + BP_FP_INT_TYPE maxHandles = static_cast(userMaxHandles + 1); //need to add one sentinel handle if (!m_pairCache) { - void* ptr = btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16); - m_pairCache = new(ptr) btHashedOverlappingPairCache(); + void* ptr = btAlignedAlloc(sizeof(btHashedOverlappingPairCache), 16); + m_pairCache = new (ptr) btHashedOverlappingPairCache(); m_ownsPairCache = true; } if (!disableRaycastAccelerator) { - m_nullPairCache = new (btAlignedAlloc(sizeof(btNullPairCache),16)) btNullPairCache(); - m_raycastAccelerator = new (btAlignedAlloc(sizeof(btDbvtBroadphase),16)) btDbvtBroadphase(m_nullPairCache);//m_pairCache); - m_raycastAccelerator->m_deferedcollide = true;//don't add/remove pairs + m_nullPairCache = new (btAlignedAlloc(sizeof(btNullPairCache), 16)) btNullPairCache(); + m_raycastAccelerator = new (btAlignedAlloc(sizeof(btDbvtBroadphase), 16)) btDbvtBroadphase(m_nullPairCache); //m_pairCache); + m_raycastAccelerator->m_deferedcollide = true; //don't add/remove pairs } //btAssert(bounds.HasVolume()); @@ -382,13 +361,13 @@ m_raycastAccelerator(0) btVector3 aabbSize = m_worldAabbMax - m_worldAabbMin; - BP_FP_INT_TYPE maxInt = m_handleSentinel; + BP_FP_INT_TYPE maxInt = m_handleSentinel; - m_quantize = btVector3(btScalar(maxInt),btScalar(maxInt),btScalar(maxInt)) / aabbSize; + m_quantize = btVector3(btScalar(maxInt), btScalar(maxInt), btScalar(maxInt)) / aabbSize; // allocate handles buffer, using btAlignedAlloc, and put all handles on free list m_pHandles = new Handle[maxHandles]; - + m_maxHandles = maxHandles; m_numHandles = 0; @@ -404,14 +383,14 @@ m_raycastAccelerator(0) // allocate edge buffers for (int i = 0; i < 3; i++) { - m_pEdgesRawPtr[i] = btAlignedAlloc(sizeof(Edge)*maxHandles*2,16); - m_pEdges[i] = new(m_pEdgesRawPtr[i]) Edge[maxHandles * 2]; + m_pEdgesRawPtr[i] = btAlignedAlloc(sizeof(Edge) * maxHandles * 2, 16); + m_pEdges[i] = new (m_pEdgesRawPtr[i]) Edge[maxHandles * 2]; } } //removed overlap management // make boundary sentinels - + m_pHandles[0].m_clientObject = 0; for (int axis = 0; axis < 3; axis++) @@ -425,10 +404,8 @@ m_raycastAccelerator(0) m_pEdges[axis][1].m_handle = 0; #ifdef DEBUG_BROADPHASE debugPrintAxis(axis); -#endif //DEBUG_BROADPHASE - +#endif //DEBUG_BROADPHASE } - } template @@ -439,14 +416,14 @@ btAxisSweep3Internal::~btAxisSweep3Internal() m_nullPairCache->~btOverlappingPairCache(); btAlignedFree(m_nullPairCache); m_raycastAccelerator->~btDbvtBroadphase(); - btAlignedFree (m_raycastAccelerator); + btAlignedFree(m_raycastAccelerator); } for (int i = 2; i >= 0; i--) { btAlignedFree(m_pEdgesRawPtr[i]); } - delete [] m_pHandles; + delete[] m_pHandles; if (m_ownsPairCache) { @@ -470,13 +447,12 @@ void btAxisSweep3Internal::quantize(BP_FP_INT_TYPE* out, const b out[2] = (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v.getZ() & m_bpHandleMask) | isMax); #else btVector3 v = (point - m_worldAabbMin) * m_quantize; - out[0]=(v[0]<=0)?(BP_FP_INT_TYPE)isMax:(v[0]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[0]&m_bpHandleMask)|isMax); - out[1]=(v[1]<=0)?(BP_FP_INT_TYPE)isMax:(v[1]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[1]&m_bpHandleMask)|isMax); - out[2]=(v[2]<=0)?(BP_FP_INT_TYPE)isMax:(v[2]>=m_handleSentinel)?(BP_FP_INT_TYPE)((m_handleSentinel&m_bpHandleMask)|isMax):(BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[2]&m_bpHandleMask)|isMax); -#endif //OLD_CLAMPING_METHOD + out[0] = (v[0] <= 0) ? (BP_FP_INT_TYPE)isMax : (v[0] >= m_handleSentinel) ? (BP_FP_INT_TYPE)((m_handleSentinel & m_bpHandleMask) | isMax) : (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[0] & m_bpHandleMask) | isMax); + out[1] = (v[1] <= 0) ? (BP_FP_INT_TYPE)isMax : (v[1] >= m_handleSentinel) ? (BP_FP_INT_TYPE)((m_handleSentinel & m_bpHandleMask) | isMax) : (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[1] & m_bpHandleMask) | isMax); + out[2] = (v[2] <= 0) ? (BP_FP_INT_TYPE)isMax : (v[2] >= m_handleSentinel) ? (BP_FP_INT_TYPE)((m_handleSentinel & m_bpHandleMask) | isMax) : (BP_FP_INT_TYPE)(((BP_FP_INT_TYPE)v[2] & m_bpHandleMask) | isMax); +#endif //OLD_CLAMPING_METHOD } - template BP_FP_INT_TYPE btAxisSweep3Internal::allocHandle() { @@ -500,9 +476,8 @@ void btAxisSweep3Internal::freeHandle(BP_FP_INT_TYPE handle) m_numHandles--; } - template -BP_FP_INT_TYPE btAxisSweep3Internal::addHandle(const btVector3& aabbMin,const btVector3& aabbMax, void* pOwner, int collisionFilterGroup, int collisionFilterMask,btDispatcher* dispatcher) +BP_FP_INT_TYPE btAxisSweep3Internal::addHandle(const btVector3& aabbMin, const btVector3& aabbMax, void* pOwner, int collisionFilterGroup, int collisionFilterMask, btDispatcher* dispatcher) { // quantize the bounds BP_FP_INT_TYPE min[3], max[3]; @@ -511,10 +486,9 @@ BP_FP_INT_TYPE btAxisSweep3Internal::addHandle(const btVector3& // allocate a handle BP_FP_INT_TYPE handle = allocHandle(); - Handle* pHandle = getHandle(handle); - + pHandle->m_uniqueId = static_cast(handle); //pHandle->m_pOverlaps = 0; pHandle->m_clientObject = pOwner; @@ -524,11 +498,9 @@ BP_FP_INT_TYPE btAxisSweep3Internal::addHandle(const btVector3& // compute current limit of edge arrays BP_FP_INT_TYPE limit = static_cast(m_numHandles * 2); - // insert new edges just inside the max boundary edge for (BP_FP_INT_TYPE axis = 0; axis < 3; axis++) { - m_pHandles[0].m_maxEdges[axis] += 2; m_pEdges[axis][limit + 1] = m_pEdges[axis][limit - 1]; @@ -544,22 +516,19 @@ BP_FP_INT_TYPE btAxisSweep3Internal::addHandle(const btVector3& } // now sort the new edges to their correct position - sortMinDown(0, pHandle->m_minEdges[0], dispatcher,false); - sortMaxDown(0, pHandle->m_maxEdges[0], dispatcher,false); - sortMinDown(1, pHandle->m_minEdges[1], dispatcher,false); - sortMaxDown(1, pHandle->m_maxEdges[1], dispatcher,false); - sortMinDown(2, pHandle->m_minEdges[2], dispatcher,true); - sortMaxDown(2, pHandle->m_maxEdges[2], dispatcher,true); - + sortMinDown(0, pHandle->m_minEdges[0], dispatcher, false); + sortMaxDown(0, pHandle->m_maxEdges[0], dispatcher, false); + sortMinDown(1, pHandle->m_minEdges[1], dispatcher, false); + sortMaxDown(1, pHandle->m_maxEdges[1], dispatcher, false); + sortMinDown(2, pHandle->m_minEdges[2], dispatcher, true); + sortMaxDown(2, pHandle->m_maxEdges[2], dispatcher, true); return handle; } - template -void btAxisSweep3Internal::removeHandle(BP_FP_INT_TYPE handle,btDispatcher* dispatcher) +void btAxisSweep3Internal::removeHandle(BP_FP_INT_TYPE handle, btDispatcher* dispatcher) { - Handle* pHandle = getHandle(handle); //explicitly remove the pairs containing the proxy @@ -567,50 +536,43 @@ void btAxisSweep3Internal::removeHandle(BP_FP_INT_TYPE handle,bt ///@todo: compare performance if (!m_pairCache->hasDeferredRemoval()) { - m_pairCache->removeOverlappingPairsContainingProxy(pHandle,dispatcher); + m_pairCache->removeOverlappingPairsContainingProxy(pHandle, dispatcher); } // compute current limit of edge arrays int limit = static_cast(m_numHandles * 2); - + int axis; - for (axis = 0;axis<3;axis++) + for (axis = 0; axis < 3; axis++) { m_pHandles[0].m_maxEdges[axis] -= 2; } // remove the edges by sorting them up to the end of the list - for ( axis = 0; axis < 3; axis++) + for (axis = 0; axis < 3; axis++) { Edge* pEdges = m_pEdges[axis]; BP_FP_INT_TYPE max = pHandle->m_maxEdges[axis]; pEdges[max].m_pos = m_handleSentinel; - sortMaxUp(axis,max,dispatcher,false); - + sortMaxUp(axis, max, dispatcher, false); BP_FP_INT_TYPE i = pHandle->m_minEdges[axis]; pEdges[i].m_pos = m_handleSentinel; + sortMinUp(axis, i, dispatcher, false); - sortMinUp(axis,i,dispatcher,false); + pEdges[limit - 1].m_handle = 0; + pEdges[limit - 1].m_pos = m_handleSentinel; - pEdges[limit-1].m_handle = 0; - pEdges[limit-1].m_pos = m_handleSentinel; - #ifdef DEBUG_BROADPHASE - debugPrintAxis(axis,false); -#endif //DEBUG_BROADPHASE - - + debugPrintAxis(axis, false); +#endif //DEBUG_BROADPHASE } - // free the handle freeHandle(handle); - - } template @@ -625,19 +587,16 @@ void btAxisSweep3Internal::resetPool(btDispatcher* /*dispatcher* m_pHandles[m_maxHandles - 1].SetNextFree(0); } } -} - +} //#include template -void btAxisSweep3Internal::calculateOverlappingPairs(btDispatcher* dispatcher) +void btAxisSweep3Internal::calculateOverlappingPairs(btDispatcher* dispatcher) { - if (m_pairCache->hasDeferredRemoval()) { - - btBroadphasePairArray& overlappingPairArray = m_pairCache->getOverlappingPairArray(); + btBroadphasePairArray& overlappingPairArray = m_pairCache->getOverlappingPairArray(); //perform a sort, to find duplicates and to sort 'invalid' pairs to the end overlappingPairArray.quickSort(btBroadphasePairSortPredicate()); @@ -645,18 +604,15 @@ void btAxisSweep3Internal::calculateOverlappingPairs(btDispatche overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); m_invalidPair = 0; - int i; btBroadphasePair previousPair; previousPair.m_pProxy0 = 0; previousPair.m_pProxy1 = 0; previousPair.m_algorithm = 0; - - - for (i=0;i::calculateOverlappingPairs(btDispatche if (!isDuplicate) { ///important to use an AABB test that is consistent with the broadphase - bool hasOverlap = testAabbOverlap(pair.m_pProxy0,pair.m_pProxy1); + bool hasOverlap = testAabbOverlap(pair.m_pProxy0, pair.m_pProxy1); if (hasOverlap) { - needsRemoval = false;//callback->processOverlap(pair); - } else + needsRemoval = false; //callback->processOverlap(pair); + } + else { needsRemoval = true; } - } else + } + else { //remove duplicate needsRemoval = true; //should have no algorithm btAssert(!pair.m_algorithm); } - + if (needsRemoval) { - m_pairCache->cleanOverlappingPair(pair,dispatcher); + m_pairCache->cleanOverlappingPair(pair, dispatcher); - // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); - // m_overlappingPairArray.pop_back(); + // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); + // m_overlappingPairArray.pop_back(); pair.m_pProxy0 = 0; pair.m_pProxy1 = 0; m_invalidPair++; - } + } + } - } - - ///if you don't like to skip the invalid pairs in the array, execute following code: - #define CLEAN_INVALID_PAIRS 1 - #ifdef CLEAN_INVALID_PAIRS +///if you don't like to skip the invalid pairs in the array, execute following code: +#define CLEAN_INVALID_PAIRS 1 +#ifdef CLEAN_INVALID_PAIRS //perform a sort, to sort 'invalid' pairs to the end overlappingPairArray.quickSort(btBroadphasePairSortPredicate()); overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); m_invalidPair = 0; - #endif//CLEAN_INVALID_PAIRS - +#endif //CLEAN_INVALID_PAIRS + //printf("overlappingPairArray.size()=%d\n",overlappingPairArray.size()); } - } - template -bool btAxisSweep3Internal::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) +bool btAxisSweep3Internal::testAabbOverlap(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) { const Handle* pHandleA = static_cast(proxy0); const Handle* pHandleB = static_cast(proxy1); - + //optimization 1: check the array index (memory address), instead of the m_pos for (int axis = 0; axis < 3; axis++) - { - if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] || - pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis]) - { - return false; - } - } + { + if (pHandleA->m_maxEdges[axis] < pHandleB->m_minEdges[axis] || + pHandleB->m_maxEdges[axis] < pHandleA->m_minEdges[axis]) + { + return false; + } + } return true; } template -bool btAxisSweep3Internal::testOverlap2D(const Handle* pHandleA, const Handle* pHandleB,int axis0,int axis1) +bool btAxisSweep3Internal::testOverlap2D(const Handle* pHandleA, const Handle* pHandleB, int axis0, int axis1) { //optimization 1: check the array index (memory address), instead of the m_pos - if (pHandleA->m_maxEdges[axis0] < pHandleB->m_minEdges[axis0] || + if (pHandleA->m_maxEdges[axis0] < pHandleB->m_minEdges[axis0] || pHandleB->m_maxEdges[axis0] < pHandleA->m_minEdges[axis0] || pHandleA->m_maxEdges[axis1] < pHandleB->m_minEdges[axis1] || - pHandleB->m_maxEdges[axis1] < pHandleA->m_minEdges[axis1]) - { - return false; - } + pHandleB->m_maxEdges[axis1] < pHandleA->m_minEdges[axis1]) + { + return false; + } return true; } template -void btAxisSweep3Internal::updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher) +void btAxisSweep3Internal::updateHandle(BP_FP_INT_TYPE handle, const btVector3& aabbMin, const btVector3& aabbMax, btDispatcher* dispatcher) { -// btAssert(bounds.IsFinite()); + // btAssert(bounds.IsFinite()); //btAssert(bounds.HasVolume()); Handle* pHandle = getHandle(handle); @@ -776,34 +731,28 @@ void btAxisSweep3Internal::updateHandle(BP_FP_INT_TYPE handle, c // expand (only adds overlaps) if (dmin < 0) - sortMinDown(axis, emin,dispatcher,true); + sortMinDown(axis, emin, dispatcher, true); if (dmax > 0) - sortMaxUp(axis, emax,dispatcher,true); + sortMaxUp(axis, emax, dispatcher, true); // shrink (only removes overlaps) if (dmin > 0) - sortMinUp(axis, emin,dispatcher,true); + sortMinUp(axis, emin, dispatcher, true); if (dmax < 0) - sortMaxDown(axis, emax,dispatcher,true); + sortMaxDown(axis, emax, dispatcher, true); #ifdef DEBUG_BROADPHASE - debugPrintAxis(axis); -#endif //DEBUG_BROADPHASE + debugPrintAxis(axis); +#endif //DEBUG_BROADPHASE } - - } - - - // sorting a min edge downwards can only ever *add* overlaps template void btAxisSweep3Internal::sortMinDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* /* dispatcher */, bool updateOverlaps) { - Edge* pEdge = m_pEdges[axis] + edge; Edge* pPrev = pEdge - 1; Handle* pHandleEdge = getHandle(pEdge->m_handle); @@ -815,16 +764,15 @@ void btAxisSweep3Internal::sortMinDown(int axis, BP_FP_INT_TYPE if (pPrev->IsMax()) { // if previous edge is a maximum check the bounds and add an overlap if necessary - const int axis1 = (1 << axis) & 3; - const int axis2 = (1 << axis1) & 3; - if (updateOverlaps && testOverlap2D(pHandleEdge, pHandlePrev,axis1,axis2)) + const int axis1 = (1 << axis) & 3; + const int axis2 = (1 << axis1) & 3; + if (updateOverlaps && testOverlap2D(pHandleEdge, pHandlePrev, axis1, axis2)) { - m_pairCache->addOverlappingPair(pHandleEdge,pHandlePrev); + m_pairCache->addOverlappingPair(pHandleEdge, pHandlePrev); if (m_userPairCallback) - m_userPairCallback->addOverlappingPair(pHandleEdge,pHandlePrev); + m_userPairCallback->addOverlappingPair(pHandleEdge, pHandlePrev); //AddOverlap(pEdge->m_handle, pPrev->m_handle); - } // update edge reference in other handle @@ -847,8 +795,7 @@ void btAxisSweep3Internal::sortMinDown(int axis, BP_FP_INT_TYPE #ifdef DEBUG_BROADPHASE debugPrintAxis(axis); -#endif //DEBUG_BROADPHASE - +#endif //DEBUG_BROADPHASE } // sorting a min edge upwards can only ever *remove* overlaps @@ -867,25 +814,21 @@ void btAxisSweep3Internal::sortMinUp(int axis, BP_FP_INT_TYPE ed { Handle* handle0 = getHandle(pEdge->m_handle); Handle* handle1 = getHandle(pNext->m_handle); - const int axis1 = (1 << axis) & 3; - const int axis2 = (1 << axis1) & 3; - + const int axis1 = (1 << axis) & 3; + const int axis2 = (1 << axis1) & 3; + // if next edge is maximum remove any overlap between the two handles - if (updateOverlaps + if (updateOverlaps #ifdef USE_OVERLAP_TEST_ON_REMOVES - && testOverlap2D(handle0,handle1,axis1,axis2) -#endif //USE_OVERLAP_TEST_ON_REMOVES - ) + && testOverlap2D(handle0, handle1, axis1, axis2) +#endif //USE_OVERLAP_TEST_ON_REMOVES + ) { - - - m_pairCache->removeOverlappingPair(handle0,handle1,dispatcher); + m_pairCache->removeOverlappingPair(handle0, handle1, dispatcher); if (m_userPairCallback) - m_userPairCallback->removeOverlappingPair(handle0,handle1,dispatcher); - + m_userPairCallback->removeOverlappingPair(handle0, handle1, dispatcher); } - // update edge reference in other handle pHandleNext->m_maxEdges[axis]--; } @@ -903,15 +846,12 @@ void btAxisSweep3Internal::sortMinUp(int axis, BP_FP_INT_TYPE ed pEdge++; pNext++; } - - } // sorting a max edge downwards can only ever *remove* overlaps template void btAxisSweep3Internal::sortMaxDown(int axis, BP_FP_INT_TYPE edge, btDispatcher* dispatcher, bool updateOverlaps) { - Edge* pEdge = m_pEdges[axis] + edge; Edge* pPrev = pEdge - 1; Handle* pHandleEdge = getHandle(pEdge->m_handle); @@ -925,28 +865,25 @@ void btAxisSweep3Internal::sortMaxDown(int axis, BP_FP_INT_TYPE // if previous edge was a minimum remove any overlap between the two handles Handle* handle0 = getHandle(pEdge->m_handle); Handle* handle1 = getHandle(pPrev->m_handle); - const int axis1 = (1 << axis) & 3; - const int axis2 = (1 << axis1) & 3; + const int axis1 = (1 << axis) & 3; + const int axis2 = (1 << axis1) & 3; - if (updateOverlaps + if (updateOverlaps #ifdef USE_OVERLAP_TEST_ON_REMOVES - && testOverlap2D(handle0,handle1,axis1,axis2) -#endif //USE_OVERLAP_TEST_ON_REMOVES - ) + && testOverlap2D(handle0, handle1, axis1, axis2) +#endif //USE_OVERLAP_TEST_ON_REMOVES + ) { //this is done during the overlappingpairarray iteration/narrowphase collision - - m_pairCache->removeOverlappingPair(handle0,handle1,dispatcher); + m_pairCache->removeOverlappingPair(handle0, handle1, dispatcher); if (m_userPairCallback) - m_userPairCallback->removeOverlappingPair(handle0,handle1,dispatcher); - - - + m_userPairCallback->removeOverlappingPair(handle0, handle1, dispatcher); } // update edge reference in other handle - pHandlePrev->m_minEdges[axis]++;; + pHandlePrev->m_minEdges[axis]++; + ; } else pHandlePrev->m_maxEdges[axis]++; @@ -963,11 +900,9 @@ void btAxisSweep3Internal::sortMaxDown(int axis, BP_FP_INT_TYPE pPrev--; } - #ifdef DEBUG_BROADPHASE debugPrintAxis(axis); -#endif //DEBUG_BROADPHASE - +#endif //DEBUG_BROADPHASE } // sorting a max edge upwards can only ever *add* overlaps @@ -982,19 +917,19 @@ void btAxisSweep3Internal::sortMaxUp(int axis, BP_FP_INT_TYPE ed { Handle* pHandleNext = getHandle(pNext->m_handle); - const int axis1 = (1 << axis) & 3; - const int axis2 = (1 << axis1) & 3; + const int axis1 = (1 << axis) & 3; + const int axis2 = (1 << axis1) & 3; if (!pNext->IsMax()) { // if next edge is a minimum check the bounds and add an overlap if necessary - if (updateOverlaps && testOverlap2D(pHandleEdge, pHandleNext,axis1,axis2)) + if (updateOverlaps && testOverlap2D(pHandleEdge, pHandleNext, axis1, axis2)) { Handle* handle0 = getHandle(pEdge->m_handle); Handle* handle1 = getHandle(pNext->m_handle); - m_pairCache->addOverlappingPair(handle0,handle1); + m_pairCache->addOverlappingPair(handle0, handle1); if (m_userPairCallback) - m_userPairCallback->addOverlappingPair(handle0,handle1); + m_userPairCallback->addOverlappingPair(handle0, handle1); } // update edge reference in other handle @@ -1014,7 +949,6 @@ void btAxisSweep3Internal::sortMaxUp(int axis, BP_FP_INT_TYPE ed pEdge++; pNext++; } - } #endif diff --git a/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h b/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h index fb68e0024..b097eca5f 100644 --- a/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h +++ b/src/BulletCollision/BroadphaseCollision/btBroadphaseInterface.h @@ -13,10 +13,8 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ -#ifndef BT_BROADPHASE_INTERFACE_H -#define BT_BROADPHASE_INTERFACE_H - - +#ifndef BT_BROADPHASE_INTERFACE_H +#define BT_BROADPHASE_INTERFACE_H struct btDispatcherInfo; class btDispatcher; @@ -24,27 +22,23 @@ class btDispatcher; class btOverlappingPairCache; - - -struct btBroadphaseAabbCallback +struct btBroadphaseAabbCallback { virtual ~btBroadphaseAabbCallback() {} - virtual bool process(const btBroadphaseProxy* proxy) = 0; + virtual bool process(const btBroadphaseProxy* proxy) = 0; }; - -struct btBroadphaseRayCallback : public btBroadphaseAabbCallback +struct btBroadphaseRayCallback : public btBroadphaseAabbCallback { ///added some cached data to accelerate ray-AABB tests - btVector3 m_rayDirectionInverse; - unsigned int m_signs[3]; - btScalar m_lambda_max; + btVector3 m_rayDirectionInverse; + unsigned int m_signs[3]; + btScalar m_lambda_max; virtual ~btBroadphaseRayCallback() {} - + protected: - - btBroadphaseRayCallback() {} + btBroadphaseRayCallback() {} }; #include "LinearMath/btVector3.h" @@ -57,30 +51,29 @@ class btBroadphaseInterface public: virtual ~btBroadphaseInterface() {} - virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr, int collisionFilterGroup, int collisionFilterMask, btDispatcher* dispatcher) =0; - virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher)=0; - virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher)=0; - virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const =0; + virtual btBroadphaseProxy* createProxy(const btVector3& aabbMin, const btVector3& aabbMax, int shapeType, void* userPtr, int collisionFilterGroup, int collisionFilterMask, btDispatcher* dispatcher) = 0; + virtual void destroyProxy(btBroadphaseProxy* proxy, btDispatcher* dispatcher) = 0; + virtual void setAabb(btBroadphaseProxy* proxy, const btVector3& aabbMin, const btVector3& aabbMax, btDispatcher* dispatcher) = 0; + virtual void getAabb(btBroadphaseProxy* proxy, btVector3& aabbMin, btVector3& aabbMax) const = 0; - virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0)) = 0; + virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin = btVector3(0, 0, 0), const btVector3& aabbMax = btVector3(0, 0, 0)) = 0; - virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback) = 0; + virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback) = 0; ///calculateOverlappingPairs is optional: incremental algorithms (sweep and prune) might do it during the set aabb - virtual void calculateOverlappingPairs(btDispatcher* dispatcher)=0; + virtual void calculateOverlappingPairs(btDispatcher* dispatcher) = 0; - virtual btOverlappingPairCache* getOverlappingPairCache()=0; - virtual const btOverlappingPairCache* getOverlappingPairCache() const =0; + virtual btOverlappingPairCache* getOverlappingPairCache() = 0; + virtual const btOverlappingPairCache* getOverlappingPairCache() const = 0; ///getAabb returns the axis aligned bounding box in the 'global' coordinate frame ///will add some transform later - virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const =0; + virtual void getBroadphaseAabb(btVector3& aabbMin, btVector3& aabbMax) const = 0; ///reset broadphase internal structures, to ensure determinism/reproducability - virtual void resetPool(btDispatcher* dispatcher) { (void) dispatcher; }; - - virtual void printStats() = 0; + virtual void resetPool(btDispatcher* dispatcher) { (void)dispatcher; }; + virtual void printStats() = 0; }; -#endif //BT_BROADPHASE_INTERFACE_H +#endif //BT_BROADPHASE_INTERFACE_H diff --git a/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp b/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp index 0fd4ef46b..7ee065aac 100644 --- a/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp +++ b/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.cpp @@ -15,4 +15,4 @@ subject to the following restrictions: #include "btBroadphaseProxy.h" -BT_NOT_EMPTY_FILE // fix warning LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library +BT_NOT_EMPTY_FILE // fix warning LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library diff --git a/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h b/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h index f6e1202a6..825caeef5 100644 --- a/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h +++ b/src/BulletCollision/BroadphaseCollision/btBroadphaseProxy.h @@ -16,11 +16,10 @@ subject to the following restrictions: #ifndef BT_BROADPHASE_PROXY_H #define BT_BROADPHASE_PROXY_H -#include "LinearMath/btScalar.h" //for SIMD_FORCE_INLINE +#include "LinearMath/btScalar.h" //for SIMD_FORCE_INLINE #include "LinearMath/btVector3.h" #include "LinearMath/btAlignedAllocator.h" - /// btDispatcher uses these types /// IMPORTANT NOTE:The types are ordered polyhedral, implicit convex and concave /// to facilitate type checking @@ -35,8 +34,8 @@ enum BroadphaseNativeTypes CONVEX_HULL_SHAPE_PROXYTYPE, CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE, CUSTOM_POLYHEDRAL_SHAPE_TYPE, -//implicit convex shapes -IMPLICIT_CONVEX_SHAPES_START_HERE, + //implicit convex shapes + IMPLICIT_CONVEX_SHAPES_START_HERE, SPHERE_SHAPE_PROXYTYPE, MULTI_SPHERE_SHAPE_PROXYTYPE, CAPSULE_SHAPE_PROXYTYPE, @@ -49,8 +48,8 @@ IMPLICIT_CONVEX_SHAPES_START_HERE, BOX_2D_SHAPE_PROXYTYPE, CONVEX_2D_SHAPE_PROXYTYPE, CUSTOM_CONVEX_SHAPE_TYPE, -//concave shapes -CONCAVE_SHAPES_START_HERE, + //concave shapes + CONCAVE_SHAPES_START_HERE, //keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy! TRIANGLE_MESH_SHAPE_PROXYTYPE, SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE, @@ -58,16 +57,16 @@ CONCAVE_SHAPES_START_HERE, FAST_CONCAVE_MESH_PROXYTYPE, //terrain TERRAIN_SHAPE_PROXYTYPE, -///Used for GIMPACT Trimesh integration + ///Used for GIMPACT Trimesh integration GIMPACT_SHAPE_PROXYTYPE, -///Multimaterial mesh - MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE, - + ///Multimaterial mesh + MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE, + EMPTY_SHAPE_PROXYTYPE, STATIC_PLANE_PROXYTYPE, CUSTOM_CONCAVE_SHAPE_TYPE, - SDF_SHAPE_PROXYTYPE=CUSTOM_CONCAVE_SHAPE_TYPE, -CONCAVE_SHAPES_END_HERE, + SDF_SHAPE_PROXYTYPE = CUSTOM_CONCAVE_SHAPE_TYPE, + CONCAVE_SHAPES_END_HERE, COMPOUND_SHAPE_PROXYTYPE, @@ -77,38 +76,37 @@ CONCAVE_SHAPES_END_HERE, INVALID_SHAPE_PROXYTYPE, MAX_BROADPHASE_COLLISION_TYPES - + }; - -///The btBroadphaseProxy is the main class that can be used with the Bullet broadphases. +///The btBroadphaseProxy is the main class that can be used with the Bullet broadphases. ///It stores collision shape type information, collision filter information and a client object, typically a btCollisionObject or btRigidBody. -ATTRIBUTE_ALIGNED16(struct) btBroadphaseProxy +ATTRIBUTE_ALIGNED16(struct) +btBroadphaseProxy { + BT_DECLARE_ALIGNED_ALLOCATOR(); -BT_DECLARE_ALIGNED_ALLOCATOR(); - ///optional filtering to cull potential collisions enum CollisionFilterGroups { - DefaultFilter = 1, - StaticFilter = 2, - KinematicFilter = 4, - DebrisFilter = 8, - SensorTrigger = 16, - CharacterFilter = 32, - AllFilter = -1 //all bits sets: DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger + DefaultFilter = 1, + StaticFilter = 2, + KinematicFilter = 4, + DebrisFilter = 8, + SensorTrigger = 16, + CharacterFilter = 32, + AllFilter = -1 //all bits sets: DefaultFilter | StaticFilter | KinematicFilter | DebrisFilter | SensorTrigger }; //Usually the client btCollisionObject or Rigidbody class - void* m_clientObject; - int m_collisionFilterGroup; - int m_collisionFilterMask; + void* m_clientObject; + int m_collisionFilterGroup; + int m_collisionFilterMask; - int m_uniqueId;//m_uniqueId is introduced for paircache. could get rid of this, by calculating the address offset etc. + int m_uniqueId; //m_uniqueId is introduced for paircache. could get rid of this, by calculating the address offset etc. - btVector3 m_aabbMin; - btVector3 m_aabbMax; + btVector3 m_aabbMin; + btVector3 m_aabbMax; SIMD_FORCE_INLINE int getUid() const { @@ -116,47 +114,45 @@ BT_DECLARE_ALIGNED_ALLOCATOR(); } //used for memory pools - btBroadphaseProxy() :m_clientObject(0) + btBroadphaseProxy() : m_clientObject(0) { } - btBroadphaseProxy(const btVector3& aabbMin,const btVector3& aabbMax,void* userPtr, int collisionFilterGroup, int collisionFilterMask) - :m_clientObject(userPtr), - m_collisionFilterGroup(collisionFilterGroup), - m_collisionFilterMask(collisionFilterMask), - m_aabbMin(aabbMin), - m_aabbMax(aabbMax) + btBroadphaseProxy(const btVector3& aabbMin, const btVector3& aabbMax, void* userPtr, int collisionFilterGroup, int collisionFilterMask) + : m_clientObject(userPtr), + m_collisionFilterGroup(collisionFilterGroup), + m_collisionFilterMask(collisionFilterMask), + m_aabbMin(aabbMin), + m_aabbMax(aabbMax) { } - - static SIMD_FORCE_INLINE bool isPolyhedral(int proxyType) { - return (proxyType < IMPLICIT_CONVEX_SHAPES_START_HERE); + return (proxyType < IMPLICIT_CONVEX_SHAPES_START_HERE); } - static SIMD_FORCE_INLINE bool isConvex(int proxyType) + static SIMD_FORCE_INLINE bool isConvex(int proxyType) { return (proxyType < CONCAVE_SHAPES_START_HERE); } - static SIMD_FORCE_INLINE bool isNonMoving(int proxyType) + static SIMD_FORCE_INLINE bool isNonMoving(int proxyType) { - return (isConcave(proxyType) && !(proxyType==GIMPACT_SHAPE_PROXYTYPE)); + return (isConcave(proxyType) && !(proxyType == GIMPACT_SHAPE_PROXYTYPE)); } - static SIMD_FORCE_INLINE bool isConcave(int proxyType) + static SIMD_FORCE_INLINE bool isConcave(int proxyType) { return ((proxyType > CONCAVE_SHAPES_START_HERE) && - (proxyType < CONCAVE_SHAPES_END_HERE)); + (proxyType < CONCAVE_SHAPES_END_HERE)); } - static SIMD_FORCE_INLINE bool isCompound(int proxyType) + static SIMD_FORCE_INLINE bool isCompound(int proxyType) { return (proxyType == COMPOUND_SHAPE_PROXYTYPE); } - static SIMD_FORCE_INLINE bool isSoftBody(int proxyType) + static SIMD_FORCE_INLINE bool isSoftBody(int proxyType) { return (proxyType == SOFTBODY_SHAPE_PROXYTYPE); } @@ -168,67 +164,62 @@ BT_DECLARE_ALIGNED_ALLOCATOR(); static SIMD_FORCE_INLINE bool isConvex2d(int proxyType) { - return (proxyType == BOX_2D_SHAPE_PROXYTYPE) || (proxyType == CONVEX_2D_SHAPE_PROXYTYPE); + return (proxyType == BOX_2D_SHAPE_PROXYTYPE) || (proxyType == CONVEX_2D_SHAPE_PROXYTYPE); } - - -} -; +}; class btCollisionAlgorithm; struct btBroadphaseProxy; - - ///The btBroadphasePair class contains a pair of aabb-overlapping objects. ///A btDispatcher can search a btCollisionAlgorithm that performs exact/narrowphase collision detection on the actual collision shapes. -ATTRIBUTE_ALIGNED16(struct) btBroadphasePair +ATTRIBUTE_ALIGNED16(struct) +btBroadphasePair { - btBroadphasePair () - : - m_pProxy0(0), - m_pProxy1(0), - m_algorithm(0), - m_internalInfo1(0) + btBroadphasePair() + : m_pProxy0(0), + m_pProxy1(0), + m_algorithm(0), + m_internalInfo1(0) { } -BT_DECLARE_ALIGNED_ALLOCATOR(); + BT_DECLARE_ALIGNED_ALLOCATOR(); btBroadphasePair(const btBroadphasePair& other) - : m_pProxy0(other.m_pProxy0), - m_pProxy1(other.m_pProxy1), - m_algorithm(other.m_algorithm), - m_internalInfo1(other.m_internalInfo1) + : m_pProxy0(other.m_pProxy0), + m_pProxy1(other.m_pProxy1), + m_algorithm(other.m_algorithm), + m_internalInfo1(other.m_internalInfo1) { } - btBroadphasePair(btBroadphaseProxy& proxy0,btBroadphaseProxy& proxy1) + btBroadphasePair(btBroadphaseProxy & proxy0, btBroadphaseProxy & proxy1) { - //keep them sorted, so the std::set operations work if (proxy0.m_uniqueId < proxy1.m_uniqueId) - { - m_pProxy0 = &proxy0; - m_pProxy1 = &proxy1; - } - else - { - m_pProxy0 = &proxy1; - m_pProxy1 = &proxy0; - } + { + m_pProxy0 = &proxy0; + m_pProxy1 = &proxy1; + } + else + { + m_pProxy0 = &proxy1; + m_pProxy1 = &proxy0; + } m_algorithm = 0; m_internalInfo1 = 0; - } - + btBroadphaseProxy* m_pProxy0; btBroadphaseProxy* m_pProxy1; - - mutable btCollisionAlgorithm* m_algorithm; - union { void* m_internalInfo1; int m_internalTmpValue;};//don't use this data, it will be removed in future version. + mutable btCollisionAlgorithm* m_algorithm; + union { + void* m_internalInfo1; + int m_internalTmpValue; + }; //don't use this data, it will be removed in future version. }; /* @@ -240,31 +231,25 @@ SIMD_FORCE_INLINE bool operator<(const btBroadphasePair& a, const btBroadphasePa } */ - - class btBroadphasePairSortPredicate { - public: +public: + bool operator()(const btBroadphasePair& a, const btBroadphasePair& b) const + { + const int uidA0 = a.m_pProxy0 ? a.m_pProxy0->m_uniqueId : -1; + const int uidB0 = b.m_pProxy0 ? b.m_pProxy0->m_uniqueId : -1; + const int uidA1 = a.m_pProxy1 ? a.m_pProxy1->m_uniqueId : -1; + const int uidB1 = b.m_pProxy1 ? b.m_pProxy1->m_uniqueId : -1; - bool operator() ( const btBroadphasePair& a, const btBroadphasePair& b ) const - { - const int uidA0 = a.m_pProxy0 ? a.m_pProxy0->m_uniqueId : -1; - const int uidB0 = b.m_pProxy0 ? b.m_pProxy0->m_uniqueId : -1; - const int uidA1 = a.m_pProxy1 ? a.m_pProxy1->m_uniqueId : -1; - const int uidB1 = b.m_pProxy1 ? b.m_pProxy1->m_uniqueId : -1; - - return uidA0 > uidB0 || - (a.m_pProxy0 == b.m_pProxy0 && uidA1 > uidB1) || - (a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 == b.m_pProxy1 && a.m_algorithm > b.m_algorithm); - } + return uidA0 > uidB0 || + (a.m_pProxy0 == b.m_pProxy0 && uidA1 > uidB1) || + (a.m_pProxy0 == b.m_pProxy0 && a.m_pProxy1 == b.m_pProxy1 && a.m_algorithm > b.m_algorithm); + } }; - -SIMD_FORCE_INLINE bool operator==(const btBroadphasePair& a, const btBroadphasePair& b) +SIMD_FORCE_INLINE bool operator==(const btBroadphasePair& a, const btBroadphasePair& b) { - return (a.m_pProxy0 == b.m_pProxy0) && (a.m_pProxy1 == b.m_pProxy1); + return (a.m_pProxy0 == b.m_pProxy0) && (a.m_pProxy1 == b.m_pProxy1); } - -#endif //BT_BROADPHASE_PROXY_H - +#endif //BT_BROADPHASE_PROXY_H diff --git a/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp b/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp index c95d1be0f..6e36d3bd7 100644 --- a/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp +++ b/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.cpp @@ -20,4 +20,3 @@ btCollisionAlgorithm::btCollisionAlgorithm(const btCollisionAlgorithmConstructio { m_dispatcher = ci.m_dispatcher1; } - diff --git a/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h b/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h index 405656236..b00c0b1b4 100644 --- a/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h +++ b/src/BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h @@ -25,57 +25,51 @@ class btManifoldResult; class btCollisionObject; struct btCollisionObjectWrapper; struct btDispatcherInfo; -class btPersistentManifold; +class btPersistentManifold; -typedef btAlignedObjectArray btManifoldArray; +typedef btAlignedObjectArray btManifoldArray; struct btCollisionAlgorithmConstructionInfo { btCollisionAlgorithmConstructionInfo() - :m_dispatcher1(0), - m_manifold(0) + : m_dispatcher1(0), + m_manifold(0) { } - btCollisionAlgorithmConstructionInfo(btDispatcher* dispatcher,int temp) - :m_dispatcher1(dispatcher) + btCollisionAlgorithmConstructionInfo(btDispatcher* dispatcher, int temp) + : m_dispatcher1(dispatcher) { (void)temp; } - btDispatcher* m_dispatcher1; - btPersistentManifold* m_manifold; - -// int getDispatcherId(); + btDispatcher* m_dispatcher1; + btPersistentManifold* m_manifold; + // int getDispatcherId(); }; - ///btCollisionAlgorithm is an collision interface that is compatible with the Broadphase and btDispatcher. ///It is persistent over frames class btCollisionAlgorithm { +protected: + btDispatcher* m_dispatcher; protected: + // int getDispatcherId(); - btDispatcher* m_dispatcher; - -protected: -// int getDispatcherId(); - public: - - btCollisionAlgorithm() {}; + btCollisionAlgorithm(){}; btCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci); - virtual ~btCollisionAlgorithm() {}; + virtual ~btCollisionAlgorithm(){}; - virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0; + virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) = 0; - virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) = 0; + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) = 0; - virtual void getAllContactManifolds(btManifoldArray& manifoldArray) = 0; + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) = 0; }; - -#endif //BT_COLLISION_ALGORITHM_H +#endif //BT_COLLISION_ALGORITHM_H diff --git a/src/BulletCollision/BroadphaseCollision/btDbvt.cpp b/src/BulletCollision/BroadphaseCollision/btDbvt.cpp index d791d0741..37156fd58 100644 --- a/src/BulletCollision/BroadphaseCollision/btDbvt.cpp +++ b/src/BulletCollision/BroadphaseCollision/btDbvt.cpp @@ -17,210 +17,225 @@ subject to the following restrictions: #include "btDbvt.h" // -typedef btAlignedObjectArray tNodeArray; -typedef btAlignedObjectArray tConstNodeArray; +typedef btAlignedObjectArray tNodeArray; +typedef btAlignedObjectArray tConstNodeArray; // struct btDbvtNodeEnumerator : btDbvt::ICollide { - tConstNodeArray nodes; + tConstNodeArray nodes; void Process(const btDbvtNode* n) { nodes.push_back(n); } }; // -static DBVT_INLINE int indexof(const btDbvtNode* node) +static DBVT_INLINE int indexof(const btDbvtNode* node) { - return(node->parent->childs[1]==node); + return (node->parent->childs[1] == node); } // -static DBVT_INLINE btDbvtVolume merge( const btDbvtVolume& a, +static DBVT_INLINE btDbvtVolume merge(const btDbvtVolume& a, const btDbvtVolume& b) { -#if (DBVT_MERGE_IMPL==DBVT_IMPL_SSE) - ATTRIBUTE_ALIGNED16( char locals[sizeof(btDbvtAabbMm)]); - btDbvtVolume* ptr = (btDbvtVolume*) locals; - btDbvtVolume& res=*ptr; +#if (DBVT_MERGE_IMPL == DBVT_IMPL_SSE) + ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtAabbMm)]); + btDbvtVolume* ptr = (btDbvtVolume*)locals; + btDbvtVolume& res = *ptr; #else - btDbvtVolume res; + btDbvtVolume res; #endif - Merge(a,b,res); - return(res); + Merge(a, b, res); + return (res); } // volume+edge lengths -static DBVT_INLINE btScalar size(const btDbvtVolume& a) +static DBVT_INLINE btScalar size(const btDbvtVolume& a) { - const btVector3 edges=a.Lengths(); - return( edges.x()*edges.y()*edges.z()+ - edges.x()+edges.y()+edges.z()); + const btVector3 edges = a.Lengths(); + return (edges.x() * edges.y() * edges.z() + + edges.x() + edges.y() + edges.z()); } // -static void getmaxdepth(const btDbvtNode* node,int depth,int& maxdepth) +static void getmaxdepth(const btDbvtNode* node, int depth, int& maxdepth) { - if(node->isinternal()) + if (node->isinternal()) { - getmaxdepth(node->childs[0],depth+1,maxdepth); - getmaxdepth(node->childs[1],depth+1,maxdepth); - } else maxdepth=btMax(maxdepth,depth); + getmaxdepth(node->childs[0], depth + 1, maxdepth); + getmaxdepth(node->childs[1], depth + 1, maxdepth); + } + else + maxdepth = btMax(maxdepth, depth); } // -static DBVT_INLINE void deletenode( btDbvt* pdbvt, - btDbvtNode* node) +static DBVT_INLINE void deletenode(btDbvt* pdbvt, + btDbvtNode* node) { btAlignedFree(pdbvt->m_free); - pdbvt->m_free=node; + pdbvt->m_free = node; } // -static void recursedeletenode( btDbvt* pdbvt, - btDbvtNode* node) +static void recursedeletenode(btDbvt* pdbvt, + btDbvtNode* node) { - if(!node->isleaf()) + if (!node->isleaf()) { - recursedeletenode(pdbvt,node->childs[0]); - recursedeletenode(pdbvt,node->childs[1]); + recursedeletenode(pdbvt, node->childs[0]); + recursedeletenode(pdbvt, node->childs[1]); } - if(node==pdbvt->m_root) pdbvt->m_root=0; - deletenode(pdbvt,node); + if (node == pdbvt->m_root) pdbvt->m_root = 0; + deletenode(pdbvt, node); } // -static DBVT_INLINE btDbvtNode* createnode( btDbvt* pdbvt, - btDbvtNode* parent, - void* data) +static DBVT_INLINE btDbvtNode* createnode(btDbvt* pdbvt, + btDbvtNode* parent, + void* data) { - btDbvtNode* node; - if(pdbvt->m_free) - { node=pdbvt->m_free;pdbvt->m_free=0; } - else - { node=new(btAlignedAlloc(sizeof(btDbvtNode),16)) btDbvtNode(); } - node->parent = parent; - node->data = data; - node->childs[1] = 0; - return(node); -} - -// -static DBVT_INLINE btDbvtNode* createnode( btDbvt* pdbvt, - btDbvtNode* parent, - const btDbvtVolume& volume, - void* data) -{ - btDbvtNode* node=createnode(pdbvt,parent,data); - node->volume=volume; - return(node); -} - -// -static DBVT_INLINE btDbvtNode* createnode( btDbvt* pdbvt, - btDbvtNode* parent, - const btDbvtVolume& volume0, - const btDbvtVolume& volume1, - void* data) -{ - btDbvtNode* node=createnode(pdbvt,parent,data); - Merge(volume0,volume1,node->volume); - return(node); -} - -// -static void insertleaf( btDbvt* pdbvt, - btDbvtNode* root, - btDbvtNode* leaf) -{ - if(!pdbvt->m_root) + btDbvtNode* node; + if (pdbvt->m_free) { - pdbvt->m_root = leaf; - leaf->parent = 0; + node = pdbvt->m_free; + pdbvt->m_free = 0; } else { - if(!root->isleaf()) + node = new (btAlignedAlloc(sizeof(btDbvtNode), 16)) btDbvtNode(); + } + node->parent = parent; + node->data = data; + node->childs[1] = 0; + return (node); +} + +// +static DBVT_INLINE btDbvtNode* createnode(btDbvt* pdbvt, + btDbvtNode* parent, + const btDbvtVolume& volume, + void* data) +{ + btDbvtNode* node = createnode(pdbvt, parent, data); + node->volume = volume; + return (node); +} + +// +static DBVT_INLINE btDbvtNode* createnode(btDbvt* pdbvt, + btDbvtNode* parent, + const btDbvtVolume& volume0, + const btDbvtVolume& volume1, + void* data) +{ + btDbvtNode* node = createnode(pdbvt, parent, data); + Merge(volume0, volume1, node->volume); + return (node); +} + +// +static void insertleaf(btDbvt* pdbvt, + btDbvtNode* root, + btDbvtNode* leaf) +{ + if (!pdbvt->m_root) + { + pdbvt->m_root = leaf; + leaf->parent = 0; + } + else + { + if (!root->isleaf()) { - do { - root=root->childs[Select( leaf->volume, - root->childs[0]->volume, - root->childs[1]->volume)]; - } while(!root->isleaf()); + do + { + root = root->childs[Select(leaf->volume, + root->childs[0]->volume, + root->childs[1]->volume)]; + } while (!root->isleaf()); } - btDbvtNode* prev=root->parent; - btDbvtNode* node=createnode(pdbvt,prev,leaf->volume,root->volume,0); - if(prev) + btDbvtNode* prev = root->parent; + btDbvtNode* node = createnode(pdbvt, prev, leaf->volume, root->volume, 0); + if (prev) { - prev->childs[indexof(root)] = node; - node->childs[0] = root;root->parent=node; - node->childs[1] = leaf;leaf->parent=node; - do { - if(!prev->volume.Contain(node->volume)) - Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume); + prev->childs[indexof(root)] = node; + node->childs[0] = root; + root->parent = node; + node->childs[1] = leaf; + leaf->parent = node; + do + { + if (!prev->volume.Contain(node->volume)) + Merge(prev->childs[0]->volume, prev->childs[1]->volume, prev->volume); else break; - node=prev; - } while(0!=(prev=node->parent)); + node = prev; + } while (0 != (prev = node->parent)); } else { - node->childs[0] = root;root->parent=node; - node->childs[1] = leaf;leaf->parent=node; - pdbvt->m_root = node; + node->childs[0] = root; + root->parent = node; + node->childs[1] = leaf; + leaf->parent = node; + pdbvt->m_root = node; } } } // -static btDbvtNode* removeleaf( btDbvt* pdbvt, - btDbvtNode* leaf) +static btDbvtNode* removeleaf(btDbvt* pdbvt, + btDbvtNode* leaf) { - if(leaf==pdbvt->m_root) + if (leaf == pdbvt->m_root) { - pdbvt->m_root=0; - return(0); + pdbvt->m_root = 0; + return (0); } else { - btDbvtNode* parent=leaf->parent; - btDbvtNode* prev=parent->parent; - btDbvtNode* sibling=parent->childs[1-indexof(leaf)]; - if(prev) + btDbvtNode* parent = leaf->parent; + btDbvtNode* prev = parent->parent; + btDbvtNode* sibling = parent->childs[1 - indexof(leaf)]; + if (prev) { - prev->childs[indexof(parent)]=sibling; - sibling->parent=prev; - deletenode(pdbvt,parent); - while(prev) + prev->childs[indexof(parent)] = sibling; + sibling->parent = prev; + deletenode(pdbvt, parent); + while (prev) { - const btDbvtVolume pb=prev->volume; - Merge(prev->childs[0]->volume,prev->childs[1]->volume,prev->volume); - if(NotEqual(pb,prev->volume)) + const btDbvtVolume pb = prev->volume; + Merge(prev->childs[0]->volume, prev->childs[1]->volume, prev->volume); + if (NotEqual(pb, prev->volume)) { - prev=prev->parent; - } else break; + prev = prev->parent; + } + else + break; } - return(prev?prev:pdbvt->m_root); + return (prev ? prev : pdbvt->m_root); } else - { - pdbvt->m_root=sibling; - sibling->parent=0; - deletenode(pdbvt,parent); - return(pdbvt->m_root); - } + { + pdbvt->m_root = sibling; + sibling->parent = 0; + deletenode(pdbvt, parent); + return (pdbvt->m_root); + } } } // -static void fetchleaves(btDbvt* pdbvt, - btDbvtNode* root, - tNodeArray& leaves, - int depth=-1) +static void fetchleaves(btDbvt* pdbvt, + btDbvtNode* root, + tNodeArray& leaves, + int depth = -1) { - if(root->isinternal()&&depth) + if (root->isinternal() && depth) { - fetchleaves(pdbvt,root->childs[0],leaves,depth-1); - fetchleaves(pdbvt,root->childs[1],leaves,depth-1); - deletenode(pdbvt,root); + fetchleaves(pdbvt, root->childs[0], leaves, depth - 1); + fetchleaves(pdbvt, root->childs[1], leaves, depth - 1); + deletenode(pdbvt, root); } else { @@ -229,51 +244,50 @@ static void fetchleaves(btDbvt* pdbvt, } // -static bool leftOfAxis( const btDbvtNode* node, - const btVector3& org, - const btVector3& axis) +static bool leftOfAxis(const btDbvtNode* node, + const btVector3& org, + const btVector3& axis) { return btDot(axis, node->volume.Center() - org) <= 0; } - // Partitions leaves such that leaves[0, n) are on the // left of axis, and leaves[n, count) are on the right // of axis. returns N. -static int split( btDbvtNode** leaves, - int count, - const btVector3& org, - const btVector3& axis) +static int split(btDbvtNode** leaves, + int count, + const btVector3& org, + const btVector3& axis) { - int begin=0; - int end=count; - for(;;) + int begin = 0; + int end = count; + for (;;) { - while(begin!=end && leftOfAxis(leaves[begin],org,axis)) + while (begin != end && leftOfAxis(leaves[begin], org, axis)) { ++begin; } - if(begin==end) + if (begin == end) { break; } - while(begin!=end && !leftOfAxis(leaves[end-1],org,axis)) + while (begin != end && !leftOfAxis(leaves[end - 1], org, axis)) { --end; } - if(begin==end) + if (begin == end) { break; } // swap out of place nodes --end; - btDbvtNode* temp=leaves[begin]; - leaves[begin]=leaves[end]; - leaves[end]=temp; + btDbvtNode* temp = leaves[begin]; + leaves[begin] = leaves[end]; + leaves[end] = temp; ++begin; } @@ -281,150 +295,153 @@ static int split( btDbvtNode** leaves, } // -static btDbvtVolume bounds( btDbvtNode** leaves, - int count) +static btDbvtVolume bounds(btDbvtNode** leaves, + int count) { -#if DBVT_MERGE_IMPL==DBVT_IMPL_SSE - ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtVolume)]); - btDbvtVolume* ptr = (btDbvtVolume*) locals; - btDbvtVolume& volume=*ptr; - volume=leaves[0]->volume; +#if DBVT_MERGE_IMPL == DBVT_IMPL_SSE + ATTRIBUTE_ALIGNED16(char locals[sizeof(btDbvtVolume)]); + btDbvtVolume* ptr = (btDbvtVolume*)locals; + btDbvtVolume& volume = *ptr; + volume = leaves[0]->volume; #else - btDbvtVolume volume=leaves[0]->volume; + btDbvtVolume volume = leaves[0]->volume; #endif - for(int i=1,ni=count;ivolume,volume); + Merge(volume, leaves[i]->volume, volume); } - return(volume); + return (volume); } // -static void bottomup( btDbvt* pdbvt, - btDbvtNode** leaves, - int count) +static void bottomup(btDbvt* pdbvt, + btDbvtNode** leaves, + int count) { - while(count>1) + while (count > 1) { - btScalar minsize=SIMD_INFINITY; - int minidx[2]={-1,-1}; - for(int i=0;ivolume,leaves[j]->volume)); - if(szvolume, leaves[j]->volume)); + if (sz < minsize) { - minsize = sz; - minidx[0] = i; - minidx[1] = j; + minsize = sz; + minidx[0] = i; + minidx[1] = j; } } } - btDbvtNode* n[] = {leaves[minidx[0]],leaves[minidx[1]]}; - btDbvtNode* p = createnode(pdbvt,0,n[0]->volume,n[1]->volume,0); - p->childs[0] = n[0]; - p->childs[1] = n[1]; - n[0]->parent = p; - n[1]->parent = p; - leaves[minidx[0]] = p; - leaves[minidx[1]] = leaves[count-1]; + btDbvtNode* n[] = {leaves[minidx[0]], leaves[minidx[1]]}; + btDbvtNode* p = createnode(pdbvt, 0, n[0]->volume, n[1]->volume, 0); + p->childs[0] = n[0]; + p->childs[1] = n[1]; + n[0]->parent = p; + n[1]->parent = p; + leaves[minidx[0]] = p; + leaves[minidx[1]] = leaves[count - 1]; --count; } } // -static btDbvtNode* topdown(btDbvt* pdbvt, - btDbvtNode** leaves, - int count, - int bu_treshold) +static btDbvtNode* topdown(btDbvt* pdbvt, + btDbvtNode** leaves, + int count, + int bu_treshold) { - static const btVector3 axis[]={btVector3(1,0,0), - btVector3(0,1,0), - btVector3(0,0,1)}; - btAssert(bu_treshold>2); - if(count>1) + static const btVector3 axis[] = {btVector3(1, 0, 0), + btVector3(0, 1, 0), + btVector3(0, 0, 1)}; + btAssert(bu_treshold > 2); + if (count > 1) { - if(count>bu_treshold) + if (count > bu_treshold) { - const btDbvtVolume vol=bounds(leaves,count); - const btVector3 org=vol.Center(); - int partition; - int bestaxis=-1; - int bestmidp=count; - int splitcount[3][2]={{0,0},{0,0},{0,0}}; + const btDbvtVolume vol = bounds(leaves, count); + const btVector3 org = vol.Center(); + int partition; + int bestaxis = -1; + int bestmidp = count; + int splitcount[3][2] = {{0, 0}, {0, 0}, {0, 0}}; int i; - for( i=0;ivolume.Center()-org; - for(int j=0;j<3;++j) + const btVector3 x = leaves[i]->volume.Center() - org; + for (int j = 0; j < 3; ++j) { - ++splitcount[j][btDot(x,axis[j])>0?1:0]; + ++splitcount[j][btDot(x, axis[j]) > 0 ? 1 : 0]; } } - for( i=0;i<3;++i) + for (i = 0; i < 3; ++i) { - if((splitcount[i][0]>0)&&(splitcount[i][1]>0)) + if ((splitcount[i][0] > 0) && (splitcount[i][1] > 0)) { - const int midp=(int)btFabs(btScalar(splitcount[i][0]-splitcount[i][1])); - if(midp=0) + if (bestaxis >= 0) { - partition=split(leaves,count,org,axis[bestaxis]); - btAssert(partition!=0 && partition!=count); + partition = split(leaves, count, org, axis[bestaxis]); + btAssert(partition != 0 && partition != count); } else { - partition=count/2+1; + partition = count / 2 + 1; } - btDbvtNode* node=createnode(pdbvt,0,vol,0); - node->childs[0]=topdown(pdbvt,&leaves[0],partition,bu_treshold); - node->childs[1]=topdown(pdbvt,&leaves[partition],count-partition,bu_treshold); - node->childs[0]->parent=node; - node->childs[1]->parent=node; - return(node); + btDbvtNode* node = createnode(pdbvt, 0, vol, 0); + node->childs[0] = topdown(pdbvt, &leaves[0], partition, bu_treshold); + node->childs[1] = topdown(pdbvt, &leaves[partition], count - partition, bu_treshold); + node->childs[0]->parent = node; + node->childs[1]->parent = node; + return (node); } else { - bottomup(pdbvt,leaves,count); - return(leaves[0]); + bottomup(pdbvt, leaves, count); + return (leaves[0]); } } - return(leaves[0]); + return (leaves[0]); } // -static DBVT_INLINE btDbvtNode* sort(btDbvtNode* n,btDbvtNode*& r) +static DBVT_INLINE btDbvtNode* sort(btDbvtNode* n, btDbvtNode*& r) { - btDbvtNode* p=n->parent; + btDbvtNode* p = n->parent; btAssert(n->isinternal()); - if(p>n) + if (p > n) { - const int i=indexof(n); - const int j=1-i; - btDbvtNode* s=p->childs[j]; - btDbvtNode* q=p->parent; - btAssert(n==p->childs[i]); - if(q) q->childs[indexof(p)]=n; else r=n; - s->parent=n; - p->parent=n; - n->parent=q; - p->childs[0]=n->childs[0]; - p->childs[1]=n->childs[1]; - n->childs[0]->parent=p; - n->childs[1]->parent=p; - n->childs[i]=p; - n->childs[j]=s; - btSwap(p->volume,n->volume); - return(p); + const int i = indexof(n); + const int j = 1 - i; + btDbvtNode* s = p->childs[j]; + btDbvtNode* q = p->parent; + btAssert(n == p->childs[i]); + if (q) + q->childs[indexof(p)] = n; + else + r = n; + s->parent = n; + p->parent = n; + n->parent = q; + p->childs[0] = n->childs[0]; + p->childs[1] = n->childs[1]; + n->childs[0]->parent = p; + n->childs[1]->parent = p; + n->childs[i] = p; + n->childs[j] = s; + btSwap(p->volume, n->volume); + return (p); } - return(n); + return (n); } #if 0 @@ -442,11 +459,11 @@ static DBVT_INLINE btDbvtNode* walkup(btDbvtNode* n,int count) // btDbvt::btDbvt() { - m_root = 0; - m_free = 0; - m_lkhd = -1; - m_leaves = 0; - m_opath = 0; + m_root = 0; + m_free = 0; + m_lkhd = -1; + m_leaves = 0; + m_opath = 0; } // @@ -456,228 +473,233 @@ btDbvt::~btDbvt() } // -void btDbvt::clear() +void btDbvt::clear() { - if(m_root) - recursedeletenode(this,m_root); + if (m_root) + recursedeletenode(this, m_root); btAlignedFree(m_free); - m_free=0; - m_lkhd = -1; + m_free = 0; + m_lkhd = -1; m_stkStack.clear(); - m_opath = 0; - + m_opath = 0; } // -void btDbvt::optimizeBottomUp() +void btDbvt::optimizeBottomUp() { - if(m_root) + if (m_root) { tNodeArray leaves; leaves.reserve(m_leaves); - fetchleaves(this,m_root,leaves); - bottomup(this,&leaves[0],leaves.size()); - m_root=leaves[0]; + fetchleaves(this, m_root, leaves); + bottomup(this, &leaves[0], leaves.size()); + m_root = leaves[0]; } } // -void btDbvt::optimizeTopDown(int bu_treshold) +void btDbvt::optimizeTopDown(int bu_treshold) { - if(m_root) + if (m_root) { - tNodeArray leaves; + tNodeArray leaves; leaves.reserve(m_leaves); - fetchleaves(this,m_root,leaves); - m_root=topdown(this,&leaves[0],leaves.size(),bu_treshold); + fetchleaves(this, m_root, leaves); + m_root = topdown(this, &leaves[0], leaves.size(), bu_treshold); } } // -void btDbvt::optimizeIncremental(int passes) +void btDbvt::optimizeIncremental(int passes) { - if(passes<0) passes=m_leaves; - if(m_root&&(passes>0)) + if (passes < 0) passes = m_leaves; + if (m_root && (passes > 0)) { - do { - btDbvtNode* node=m_root; - unsigned bit=0; - while(node->isinternal()) + do + { + btDbvtNode* node = m_root; + unsigned bit = 0; + while (node->isinternal()) { - node=sort(node,m_root)->childs[(m_opath>>bit)&1]; - bit=(bit+1)&(sizeof(unsigned)*8-1); + node = sort(node, m_root)->childs[(m_opath >> bit) & 1]; + bit = (bit + 1) & (sizeof(unsigned) * 8 - 1); } update(node); ++m_opath; - } while(--passes); + } while (--passes); } } // -btDbvtNode* btDbvt::insert(const btDbvtVolume& volume,void* data) +btDbvtNode* btDbvt::insert(const btDbvtVolume& volume, void* data) { - btDbvtNode* leaf=createnode(this,0,volume,data); - insertleaf(this,m_root,leaf); + btDbvtNode* leaf = createnode(this, 0, volume, data); + insertleaf(this, m_root, leaf); ++m_leaves; - return(leaf); + return (leaf); } // -void btDbvt::update(btDbvtNode* leaf,int lookahead) +void btDbvt::update(btDbvtNode* leaf, int lookahead) { - btDbvtNode* root=removeleaf(this,leaf); - if(root) + btDbvtNode* root = removeleaf(this, leaf); + if (root) { - if(lookahead>=0) + if (lookahead >= 0) { - for(int i=0;(iparent;++i) + for (int i = 0; (i < lookahead) && root->parent; ++i) { - root=root->parent; + root = root->parent; } - } else root=m_root; + } + else + root = m_root; } - insertleaf(this,root,leaf); + insertleaf(this, root, leaf); } // -void btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume) +void btDbvt::update(btDbvtNode* leaf, btDbvtVolume& volume) { - btDbvtNode* root=removeleaf(this,leaf); - if(root) + btDbvtNode* root = removeleaf(this, leaf); + if (root) { - if(m_lkhd>=0) + if (m_lkhd >= 0) { - for(int i=0;(iparent;++i) + for (int i = 0; (i < m_lkhd) && root->parent; ++i) { - root=root->parent; + root = root->parent; } - } else root=m_root; + } + else + root = m_root; } - leaf->volume=volume; - insertleaf(this,root,leaf); + leaf->volume = volume; + insertleaf(this, root, leaf); } // -bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity,btScalar margin) +bool btDbvt::update(btDbvtNode* leaf, btDbvtVolume& volume, const btVector3& velocity, btScalar margin) { - if(leaf->volume.Contain(volume)) return(false); - volume.Expand(btVector3(margin,margin,margin)); + if (leaf->volume.Contain(volume)) return (false); + volume.Expand(btVector3(margin, margin, margin)); volume.SignedExpand(velocity); - update(leaf,volume); - return(true); + update(leaf, volume); + return (true); } // -bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity) +bool btDbvt::update(btDbvtNode* leaf, btDbvtVolume& volume, const btVector3& velocity) { - if(leaf->volume.Contain(volume)) return(false); + if (leaf->volume.Contain(volume)) return (false); volume.SignedExpand(velocity); - update(leaf,volume); - return(true); + update(leaf, volume); + return (true); } // -bool btDbvt::update(btDbvtNode* leaf,btDbvtVolume& volume,btScalar margin) +bool btDbvt::update(btDbvtNode* leaf, btDbvtVolume& volume, btScalar margin) { - if(leaf->volume.Contain(volume)) return(false); - volume.Expand(btVector3(margin,margin,margin)); - update(leaf,volume); - return(true); + if (leaf->volume.Contain(volume)) return (false); + volume.Expand(btVector3(margin, margin, margin)); + update(leaf, volume); + return (true); } // -void btDbvt::remove(btDbvtNode* leaf) +void btDbvt::remove(btDbvtNode* leaf) { - removeleaf(this,leaf); - deletenode(this,leaf); + removeleaf(this, leaf); + deletenode(this, leaf); --m_leaves; } // -void btDbvt::write(IWriter* iwriter) const +void btDbvt::write(IWriter* iwriter) const { - btDbvtNodeEnumerator nodes; - nodes.nodes.reserve(m_leaves*2); - enumNodes(m_root,nodes); - iwriter->Prepare(m_root,nodes.nodes.size()); - for(int i=0;iPrepare(m_root, nodes.nodes.size()); + for (int i = 0; i < nodes.nodes.size(); ++i) { - const btDbvtNode* n=nodes.nodes[i]; - int p=-1; - if(n->parent) p=nodes.nodes.findLinearSearch(n->parent); - if(n->isinternal()) + const btDbvtNode* n = nodes.nodes[i]; + int p = -1; + if (n->parent) p = nodes.nodes.findLinearSearch(n->parent); + if (n->isinternal()) { - const int c0=nodes.nodes.findLinearSearch(n->childs[0]); - const int c1=nodes.nodes.findLinearSearch(n->childs[1]); - iwriter->WriteNode(n,i,p,c0,c1); + const int c0 = nodes.nodes.findLinearSearch(n->childs[0]); + const int c1 = nodes.nodes.findLinearSearch(n->childs[1]); + iwriter->WriteNode(n, i, p, c0, c1); } else { - iwriter->WriteLeaf(n,i,p); - } + iwriter->WriteLeaf(n, i, p); + } } } // -void btDbvt::clone(btDbvt& dest,IClone* iclone) const +void btDbvt::clone(btDbvt& dest, IClone* iclone) const { dest.clear(); - if(m_root!=0) - { - btAlignedObjectArray stack; + if (m_root != 0) + { + btAlignedObjectArray stack; stack.reserve(m_leaves); - stack.push_back(sStkCLN(m_root,0)); - do { - const int i=stack.size()-1; - const sStkCLN e=stack[i]; - btDbvtNode* n=createnode(&dest,e.parent,e.node->volume,e.node->data); + stack.push_back(sStkCLN(m_root, 0)); + do + { + const int i = stack.size() - 1; + const sStkCLN e = stack[i]; + btDbvtNode* n = createnode(&dest, e.parent, e.node->volume, e.node->data); stack.pop_back(); - if(e.parent!=0) - e.parent->childs[i&1]=n; + if (e.parent != 0) + e.parent->childs[i & 1] = n; else - dest.m_root=n; - if(e.node->isinternal()) + dest.m_root = n; + if (e.node->isinternal()) { - stack.push_back(sStkCLN(e.node->childs[0],n)); - stack.push_back(sStkCLN(e.node->childs[1],n)); + stack.push_back(sStkCLN(e.node->childs[0], n)); + stack.push_back(sStkCLN(e.node->childs[1], n)); } else { iclone->CloneLeaf(n); } - } while(stack.size()>0); + } while (stack.size() > 0); } } // -int btDbvt::maxdepth(const btDbvtNode* node) +int btDbvt::maxdepth(const btDbvtNode* node) { - int depth=0; - if(node) getmaxdepth(node,1,depth); - return(depth); + int depth = 0; + if (node) getmaxdepth(node, 1, depth); + return (depth); } // -int btDbvt::countLeaves(const btDbvtNode* node) +int btDbvt::countLeaves(const btDbvtNode* node) { - if(node->isinternal()) - return(countLeaves(node->childs[0])+countLeaves(node->childs[1])); + if (node->isinternal()) + return (countLeaves(node->childs[0]) + countLeaves(node->childs[1])); else - return(1); + return (1); } // -void btDbvt::extractLeaves(const btDbvtNode* node,btAlignedObjectArray& leaves) +void btDbvt::extractLeaves(const btDbvtNode* node, btAlignedObjectArray& leaves) { - if(node->isinternal()) + if (node->isinternal()) { - extractLeaves(node->childs[0],leaves); - extractLeaves(node->childs[1],leaves); + extractLeaves(node->childs[0], leaves); + extractLeaves(node->childs[1], leaves); } else { leaves.push_back(node); - } + } } // @@ -726,603 +748,608 @@ struct btDbvtBenchmark { struct NilPolicy : btDbvt::ICollide { - NilPolicy() : m_pcount(0),m_depth(-SIMD_INFINITY),m_checksort(true) {} - void Process(const btDbvtNode*,const btDbvtNode*) { ++m_pcount; } - void Process(const btDbvtNode*) { ++m_pcount; } - void Process(const btDbvtNode*,btScalar depth) + NilPolicy() : m_pcount(0), m_depth(-SIMD_INFINITY), m_checksort(true) {} + void Process(const btDbvtNode*, const btDbvtNode*) { ++m_pcount; } + void Process(const btDbvtNode*) { ++m_pcount; } + void Process(const btDbvtNode*, btScalar depth) { ++m_pcount; - if(m_checksort) - { if(depth>=m_depth) m_depth=depth; else printf("wrong depth: %f (should be >= %f)\r\n",depth,m_depth); } + if (m_checksort) + { + if (depth >= m_depth) + m_depth = depth; + else + printf("wrong depth: %f (should be >= %f)\r\n", depth, m_depth); + } } - int m_pcount; - btScalar m_depth; - bool m_checksort; + int m_pcount; + btScalar m_depth; + bool m_checksort; }; struct P14 : btDbvt::ICollide { struct Node { - const btDbvtNode* leaf; - btScalar depth; + const btDbvtNode* leaf; + btScalar depth; }; - void Process(const btDbvtNode* leaf,btScalar depth) + void Process(const btDbvtNode* leaf, btScalar depth) { - Node n; - n.leaf = leaf; - n.depth = depth; + Node n; + n.leaf = leaf; + n.depth = depth; } - static int sortfnc(const Node& a,const Node& b) + static int sortfnc(const Node& a, const Node& b) { - if(a.depthb.depth) return(-1); - return(0); + if (a.depth < b.depth) return (+1); + if (a.depth > b.depth) return (-1); + return (0); } - btAlignedObjectArray m_nodes; + btAlignedObjectArray m_nodes; }; struct P15 : btDbvt::ICollide { struct Node { - const btDbvtNode* leaf; - btScalar depth; + const btDbvtNode* leaf; + btScalar depth; }; void Process(const btDbvtNode* leaf) { - Node n; - n.leaf = leaf; - n.depth = dot(leaf->volume.Center(),m_axis); + Node n; + n.leaf = leaf; + n.depth = dot(leaf->volume.Center(), m_axis); } - static int sortfnc(const Node& a,const Node& b) + static int sortfnc(const Node& a, const Node& b) { - if(a.depthb.depth) return(-1); - return(0); + if (a.depth < b.depth) return (+1); + if (a.depth > b.depth) return (-1); + return (0); } - btAlignedObjectArray m_nodes; - btVector3 m_axis; + btAlignedObjectArray m_nodes; + btVector3 m_axis; }; - static btScalar RandUnit() + static btScalar RandUnit() { - return(rand()/(btScalar)RAND_MAX); + return (rand() / (btScalar)RAND_MAX); } - static btVector3 RandVector3() + static btVector3 RandVector3() { - return(btVector3(RandUnit(),RandUnit(),RandUnit())); + return (btVector3(RandUnit(), RandUnit(), RandUnit())); } - static btVector3 RandVector3(btScalar cs) + static btVector3 RandVector3(btScalar cs) { - return(RandVector3()*cs-btVector3(cs,cs,cs)/2); + return (RandVector3() * cs - btVector3(cs, cs, cs) / 2); } - static btDbvtVolume RandVolume(btScalar cs,btScalar eb,btScalar es) + static btDbvtVolume RandVolume(btScalar cs, btScalar eb, btScalar es) { - return(btDbvtVolume::FromCE(RandVector3(cs),btVector3(eb,eb,eb)+RandVector3()*es)); + return (btDbvtVolume::FromCE(RandVector3(cs), btVector3(eb, eb, eb) + RandVector3() * es)); } - static btTransform RandTransform(btScalar cs) + static btTransform RandTransform(btScalar cs) { - btTransform t; + btTransform t; t.setOrigin(RandVector3(cs)); - t.setRotation(btQuaternion(RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2,RandUnit()*SIMD_PI*2).normalized()); - return(t); + t.setRotation(btQuaternion(RandUnit() * SIMD_PI * 2, RandUnit() * SIMD_PI * 2, RandUnit() * SIMD_PI * 2).normalized()); + return (t); } - static void RandTree(btScalar cs,btScalar eb,btScalar es,int leaves,btDbvt& dbvt) + static void RandTree(btScalar cs, btScalar eb, btScalar es, int leaves, btDbvt& dbvt) { dbvt.clear(); - for(int i=0;i volumes; - btAlignedObjectArray results; + btAlignedObjectArray volumes; + btAlignedObjectArray results; volumes.resize(cfgLeaves); results.resize(cfgLeaves); - for(int i=0;i volumes; - btAlignedObjectArray results; + btAlignedObjectArray volumes; + btAlignedObjectArray results; volumes.resize(cfgLeaves); results.resize(cfgLeaves); - for(int i=0;i transforms; - btDbvtBenchmark::NilPolicy policy; + btDbvt dbvt[2]; + btAlignedObjectArray transforms; + btDbvtBenchmark::NilPolicy policy; transforms.resize(cfgBenchmark5_Iterations); - for(int i=0;i transforms; - btDbvtBenchmark::NilPolicy policy; + btDbvt dbvt; + btAlignedObjectArray transforms; + btDbvtBenchmark::NilPolicy policy; transforms.resize(cfgBenchmark6_Iterations); - for(int i=0;i rayorg; - btAlignedObjectArray raydir; - btDbvtBenchmark::NilPolicy policy; + btDbvt dbvt; + btAlignedObjectArray rayorg; + btAlignedObjectArray raydir; + btDbvtBenchmark::NilPolicy policy; rayorg.resize(cfgBenchmark7_Iterations); raydir.resize(cfgBenchmark7_Iterations); - for(int i=0;i leaves; - btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); + btDbvt dbvt; + btAlignedObjectArray leaves; + btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt); dbvt.optimizeTopDown(); - dbvt.extractLeaves(dbvt.m_root,leaves); + dbvt.extractLeaves(dbvt.m_root, leaves); printf("[9] updates (teleport): "); wallclock.reset(); - for(int i=0;i(leaves[rand()%cfgLeaves]), - btDbvtBenchmark::RandVolume(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale)); + dbvt.update(const_cast(leaves[rand() % cfgLeaves]), + btDbvtBenchmark::RandVolume(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale)); } } - const int time=(int)wallclock.getTimeMilliseconds(); - const int up=cfgBenchmark9_Passes*cfgBenchmark9_Iterations; - printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark9_Reference)*100/time,up*1000/time); + const int time = (int)wallclock.getTimeMilliseconds(); + const int up = cfgBenchmark9_Passes * cfgBenchmark9_Iterations; + printf("%u ms (%i%%),(%u u/s)\r\n", time, (time - cfgBenchmark9_Reference) * 100 / time, up * 1000 / time); } - if(cfgBenchmark10_Enable) - {// Benchmark 10 + if (cfgBenchmark10_Enable) + { // Benchmark 10 srand(380843); - btDbvt dbvt; - btAlignedObjectArray leaves; - btAlignedObjectArray vectors; + btDbvt dbvt; + btAlignedObjectArray leaves; + btAlignedObjectArray vectors; vectors.resize(cfgBenchmark10_Iterations); - for(int i=0;i(leaves[rand()%cfgLeaves]); - btDbvtVolume v=btDbvtVolume::FromMM(l->volume.Mins()+d,l->volume.Maxs()+d); - dbvt.update(l,v); + for (int j = 0; j < cfgBenchmark10_Iterations; ++j) + { + const btVector3& d = vectors[j]; + btDbvtNode* l = const_cast(leaves[rand() % cfgLeaves]); + btDbvtVolume v = btDbvtVolume::FromMM(l->volume.Mins() + d, l->volume.Maxs() + d); + dbvt.update(l, v); } } - const int time=(int)wallclock.getTimeMilliseconds(); - const int up=cfgBenchmark10_Passes*cfgBenchmark10_Iterations; - printf("%u ms (%i%%),(%u u/s)\r\n",time,(time-cfgBenchmark10_Reference)*100/time,up*1000/time); + const int time = (int)wallclock.getTimeMilliseconds(); + const int up = cfgBenchmark10_Passes * cfgBenchmark10_Iterations; + printf("%u ms (%i%%),(%u u/s)\r\n", time, (time - cfgBenchmark10_Reference) * 100 / time, up * 1000 / time); } - if(cfgBenchmark11_Enable) - {// Benchmark 11 + if (cfgBenchmark11_Enable) + { // Benchmark 11 srand(380843); - btDbvt dbvt; - btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); + btDbvt dbvt; + btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt); dbvt.optimizeTopDown(); printf("[11] optimize (incremental): "); - wallclock.reset(); - for(int i=0;i volumes; - btAlignedObjectArray results; + btAlignedObjectArray volumes; + btAlignedObjectArray results; volumes.resize(cfgLeaves); results.resize(cfgLeaves); - for(int i=0;i vectors; - btDbvtBenchmark::NilPolicy policy; + btDbvt dbvt; + btAlignedObjectArray vectors; + btDbvtBenchmark::NilPolicy policy; vectors.resize(cfgBenchmark13_Iterations); - for(int i=0;i vectors; - btDbvtBenchmark::P14 policy; + btDbvt dbvt; + btAlignedObjectArray vectors; + btDbvtBenchmark::P14 policy; vectors.resize(cfgBenchmark14_Iterations); - for(int i=0;i vectors; - btDbvtBenchmark::P15 policy; + btDbvt dbvt; + btAlignedObjectArray vectors; + btDbvtBenchmark::P15 policy; vectors.resize(cfgBenchmark15_Iterations); - for(int i=0;i batch; - btDbvtBenchmark::RandTree(cfgVolumeCenterScale,cfgVolumeExentsBase,cfgVolumeExentsScale,cfgLeaves,dbvt); + btDbvt dbvt; + btAlignedObjectArray batch; + btDbvtBenchmark::RandTree(cfgVolumeCenterScale, cfgVolumeExentsBase, cfgVolumeExentsScale, cfgLeaves, dbvt); dbvt.optimizeTopDown(); batch.reserve(cfgBenchmark16_BatchCount); - printf("[16] insert/remove batch(%u): ",cfgBenchmark16_BatchCount); + printf("[16] insert/remove batch(%u): ", cfgBenchmark16_BatchCount); wallclock.reset(); - for(int i=0;i volumes; - btAlignedObjectArray results; - btAlignedObjectArray indices; + btAlignedObjectArray volumes; + btAlignedObjectArray results; + btAlignedObjectArray indices; volumes.resize(cfgLeaves); results.resize(cfgLeaves); indices.resize(cfgLeaves); - for(int i=0;i= 1400) -#define DBVT_USE_TEMPLATE 1 +#if (defined(_MSC_VER) && _MSC_VER >= 1400) +#define DBVT_USE_TEMPLATE 1 #else -#define DBVT_USE_TEMPLATE 0 +#define DBVT_USE_TEMPLATE 0 #endif #else -#define DBVT_USE_TEMPLATE 0 +#define DBVT_USE_TEMPLATE 0 #endif // Use only intrinsics instead of inline asm -#define DBVT_USE_INTRINSIC_SSE 1 +#define DBVT_USE_INTRINSIC_SSE 1 // Using memmov for collideOCL -#define DBVT_USE_MEMMOVE 1 +#define DBVT_USE_MEMMOVE 1 // Enable benchmarking code -#define DBVT_ENABLE_BENCHMARK 0 +#define DBVT_ENABLE_BENCHMARK 0 // Inlining -#define DBVT_INLINE SIMD_FORCE_INLINE +#define DBVT_INLINE SIMD_FORCE_INLINE // Specific methods implementation //SSE gives errors on a MSVC 7.1 -#if defined (BT_USE_SSE) //&& defined (_WIN32) -#define DBVT_SELECT_IMPL DBVT_IMPL_SSE -#define DBVT_MERGE_IMPL DBVT_IMPL_SSE -#define DBVT_INT0_IMPL DBVT_IMPL_SSE +#if defined(BT_USE_SSE) //&& defined (_WIN32) +#define DBVT_SELECT_IMPL DBVT_IMPL_SSE +#define DBVT_MERGE_IMPL DBVT_IMPL_SSE +#define DBVT_INT0_IMPL DBVT_IMPL_SSE #else -#define DBVT_SELECT_IMPL DBVT_IMPL_GENERIC -#define DBVT_MERGE_IMPL DBVT_IMPL_GENERIC -#define DBVT_INT0_IMPL DBVT_IMPL_GENERIC +#define DBVT_SELECT_IMPL DBVT_IMPL_GENERIC +#define DBVT_MERGE_IMPL DBVT_IMPL_GENERIC +#define DBVT_INT0_IMPL DBVT_IMPL_GENERIC #endif -#if (DBVT_SELECT_IMPL==DBVT_IMPL_SSE)|| \ - (DBVT_MERGE_IMPL==DBVT_IMPL_SSE)|| \ - (DBVT_INT0_IMPL==DBVT_IMPL_SSE) +#if (DBVT_SELECT_IMPL == DBVT_IMPL_SSE) || \ + (DBVT_MERGE_IMPL == DBVT_IMPL_SSE) || \ + (DBVT_INT0_IMPL == DBVT_IMPL_SSE) #include #endif @@ -78,21 +77,24 @@ subject to the following restrictions: // #if DBVT_USE_TEMPLATE -#define DBVT_VIRTUAL +#define DBVT_VIRTUAL #define DBVT_VIRTUAL_DTOR(a) -#define DBVT_PREFIX template -#define DBVT_IPOLICY T& policy -#define DBVT_CHECKTYPE static const ICollide& typechecker=*(T*)1;(void)typechecker; +#define DBVT_PREFIX template +#define DBVT_IPOLICY T& policy +#define DBVT_CHECKTYPE \ + static const ICollide& typechecker = *(T*)1; \ + (void)typechecker; #else -#define DBVT_VIRTUAL_DTOR(a) virtual ~a() {} -#define DBVT_VIRTUAL virtual +#define DBVT_VIRTUAL_DTOR(a) \ + virtual ~a() {} +#define DBVT_VIRTUAL virtual #define DBVT_PREFIX -#define DBVT_IPOLICY ICollide& policy +#define DBVT_IPOLICY ICollide& policy #define DBVT_CHECKTYPE #endif #if DBVT_USE_MEMMOVE -#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__) +#if !defined(__CELLOS_LV2__) && !defined(__MWERKS__) #include #endif #include @@ -122,194 +124,193 @@ subject to the following restrictions: #error "DBVT_INT0_IMPL undefined" #endif - // // Defaults volumes // -/* btDbvtAabbMm */ -struct btDbvtAabbMm +/* btDbvtAabbMm */ +struct btDbvtAabbMm { - DBVT_INLINE btVector3 Center() const { return((mi+mx)/2); } - DBVT_INLINE btVector3 Lengths() const { return(mx-mi); } - DBVT_INLINE btVector3 Extents() const { return((mx-mi)/2); } - DBVT_INLINE const btVector3& Mins() const { return(mi); } - DBVT_INLINE const btVector3& Maxs() const { return(mx); } - static inline btDbvtAabbMm FromCE(const btVector3& c,const btVector3& e); - static inline btDbvtAabbMm FromCR(const btVector3& c,btScalar r); - static inline btDbvtAabbMm FromMM(const btVector3& mi,const btVector3& mx); - static inline btDbvtAabbMm FromPoints(const btVector3* pts,int n); - static inline btDbvtAabbMm FromPoints(const btVector3** ppts,int n); - DBVT_INLINE void Expand(const btVector3& e); - DBVT_INLINE void SignedExpand(const btVector3& e); - DBVT_INLINE bool Contain(const btDbvtAabbMm& a) const; - DBVT_INLINE int Classify(const btVector3& n,btScalar o,int s) const; - DBVT_INLINE btScalar ProjectMinimum(const btVector3& v,unsigned signs) const; - DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a, - const btDbvtAabbMm& b); - - DBVT_INLINE friend bool Intersect( const btDbvtAabbMm& a, - const btVector3& b); + DBVT_INLINE btVector3 Center() const { return ((mi + mx) / 2); } + DBVT_INLINE btVector3 Lengths() const { return (mx - mi); } + DBVT_INLINE btVector3 Extents() const { return ((mx - mi) / 2); } + DBVT_INLINE const btVector3& Mins() const { return (mi); } + DBVT_INLINE const btVector3& Maxs() const { return (mx); } + static inline btDbvtAabbMm FromCE(const btVector3& c, const btVector3& e); + static inline btDbvtAabbMm FromCR(const btVector3& c, btScalar r); + static inline btDbvtAabbMm FromMM(const btVector3& mi, const btVector3& mx); + static inline btDbvtAabbMm FromPoints(const btVector3* pts, int n); + static inline btDbvtAabbMm FromPoints(const btVector3** ppts, int n); + DBVT_INLINE void Expand(const btVector3& e); + DBVT_INLINE void SignedExpand(const btVector3& e); + DBVT_INLINE bool Contain(const btDbvtAabbMm& a) const; + DBVT_INLINE int Classify(const btVector3& n, btScalar o, int s) const; + DBVT_INLINE btScalar ProjectMinimum(const btVector3& v, unsigned signs) const; + DBVT_INLINE friend bool Intersect(const btDbvtAabbMm& a, + const btDbvtAabbMm& b); + + DBVT_INLINE friend bool Intersect(const btDbvtAabbMm& a, + const btVector3& b); + + DBVT_INLINE friend btScalar Proximity(const btDbvtAabbMm& a, + const btDbvtAabbMm& b); + DBVT_INLINE friend int Select(const btDbvtAabbMm& o, + const btDbvtAabbMm& a, + const btDbvtAabbMm& b); + DBVT_INLINE friend void Merge(const btDbvtAabbMm& a, + const btDbvtAabbMm& b, + btDbvtAabbMm& r); + DBVT_INLINE friend bool NotEqual(const btDbvtAabbMm& a, + const btDbvtAabbMm& b); + + DBVT_INLINE btVector3& tMins() { return (mi); } + DBVT_INLINE btVector3& tMaxs() { return (mx); } - DBVT_INLINE friend btScalar Proximity( const btDbvtAabbMm& a, - const btDbvtAabbMm& b); - DBVT_INLINE friend int Select( const btDbvtAabbMm& o, - const btDbvtAabbMm& a, - const btDbvtAabbMm& b); - DBVT_INLINE friend void Merge( const btDbvtAabbMm& a, - const btDbvtAabbMm& b, - btDbvtAabbMm& r); - DBVT_INLINE friend bool NotEqual( const btDbvtAabbMm& a, - const btDbvtAabbMm& b); - - DBVT_INLINE btVector3& tMins() { return(mi); } - DBVT_INLINE btVector3& tMaxs() { return(mx); } - private: - DBVT_INLINE void AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const; + DBVT_INLINE void AddSpan(const btVector3& d, btScalar& smi, btScalar& smx) const; + private: - btVector3 mi,mx; + btVector3 mi, mx; }; -// Types -typedef btDbvtAabbMm btDbvtVolume; +// Types +typedef btDbvtAabbMm btDbvtVolume; -/* btDbvtNode */ -struct btDbvtNode +/* btDbvtNode */ +struct btDbvtNode { - btDbvtVolume volume; - btDbvtNode* parent; - DBVT_INLINE bool isleaf() const { return(childs[1]==0); } - DBVT_INLINE bool isinternal() const { return(!isleaf()); } - union - { - btDbvtNode* childs[2]; - void* data; - int dataAsInt; + btDbvtVolume volume; + btDbvtNode* parent; + DBVT_INLINE bool isleaf() const { return (childs[1] == 0); } + DBVT_INLINE bool isinternal() const { return (!isleaf()); } + union { + btDbvtNode* childs[2]; + void* data; + int dataAsInt; }; }; typedef btAlignedObjectArray btNodeStack; - ///The btDbvt class implements a fast dynamic bounding volume tree based on axis aligned bounding boxes (aabb tree). ///This btDbvt is used for soft body collision detection and for the btDbvtBroadphase. It has a fast insert, remove and update of nodes. ///Unlike the btQuantizedBvh, nodes can be dynamically moved around, which allows for change in topology of the underlying data structure. -struct btDbvt +struct btDbvt { - /* Stack element */ - struct sStkNN + /* Stack element */ + struct sStkNN { - const btDbvtNode* a; - const btDbvtNode* b; + const btDbvtNode* a; + const btDbvtNode* b; sStkNN() {} - sStkNN(const btDbvtNode* na,const btDbvtNode* nb) : a(na),b(nb) {} + sStkNN(const btDbvtNode* na, const btDbvtNode* nb) : a(na), b(nb) {} }; - struct sStkNP + struct sStkNP { - const btDbvtNode* node; - int mask; - sStkNP(const btDbvtNode* n,unsigned m) : node(n),mask(m) {} + const btDbvtNode* node; + int mask; + sStkNP(const btDbvtNode* n, unsigned m) : node(n), mask(m) {} }; - struct sStkNPS + struct sStkNPS { - const btDbvtNode* node; - int mask; - btScalar value; + const btDbvtNode* node; + int mask; + btScalar value; sStkNPS() {} - sStkNPS(const btDbvtNode* n,unsigned m,btScalar v) : node(n),mask(m),value(v) {} + sStkNPS(const btDbvtNode* n, unsigned m, btScalar v) : node(n), mask(m), value(v) {} }; - struct sStkCLN + struct sStkCLN { - const btDbvtNode* node; - btDbvtNode* parent; - sStkCLN(const btDbvtNode* n,btDbvtNode* p) : node(n),parent(p) {} + const btDbvtNode* node; + btDbvtNode* parent; + sStkCLN(const btDbvtNode* n, btDbvtNode* p) : node(n), parent(p) {} }; // Policies/Interfaces - /* ICollide */ - struct ICollide - { + /* ICollide */ + struct ICollide + { DBVT_VIRTUAL_DTOR(ICollide) - DBVT_VIRTUAL void Process(const btDbvtNode*,const btDbvtNode*) {} - DBVT_VIRTUAL void Process(const btDbvtNode*) {} - DBVT_VIRTUAL void Process(const btDbvtNode* n,btScalar) { Process(n); } - DBVT_VIRTUAL bool Descent(const btDbvtNode*) { return(true); } - DBVT_VIRTUAL bool AllLeaves(const btDbvtNode*) { return(true); } + DBVT_VIRTUAL void Process(const btDbvtNode*, const btDbvtNode*) {} + DBVT_VIRTUAL void Process(const btDbvtNode*) {} + DBVT_VIRTUAL void Process(const btDbvtNode* n, btScalar) { Process(n); } + DBVT_VIRTUAL bool Descent(const btDbvtNode*) { return (true); } + DBVT_VIRTUAL bool AllLeaves(const btDbvtNode*) { return (true); } }; - /* IWriter */ - struct IWriter + /* IWriter */ + struct IWriter { virtual ~IWriter() {} - virtual void Prepare(const btDbvtNode* root,int numnodes)=0; - virtual void WriteNode(const btDbvtNode*,int index,int parent,int child0,int child1)=0; - virtual void WriteLeaf(const btDbvtNode*,int index,int parent)=0; + virtual void Prepare(const btDbvtNode* root, int numnodes) = 0; + virtual void WriteNode(const btDbvtNode*, int index, int parent, int child0, int child1) = 0; + virtual void WriteLeaf(const btDbvtNode*, int index, int parent) = 0; }; - /* IClone */ - struct IClone + /* IClone */ + struct IClone { - virtual ~IClone() {} - virtual void CloneLeaf(btDbvtNode*) {} + virtual ~IClone() {} + virtual void CloneLeaf(btDbvtNode*) {} }; // Constants - enum { - SIMPLE_STACKSIZE = 64, - DOUBLE_STACKSIZE = SIMPLE_STACKSIZE*2 + enum + { + SIMPLE_STACKSIZE = 64, + DOUBLE_STACKSIZE = SIMPLE_STACKSIZE * 2 }; // Fields - btDbvtNode* m_root; - btDbvtNode* m_free; - int m_lkhd; - int m_leaves; - unsigned m_opath; - - - btAlignedObjectArray m_stkStack; + btDbvtNode* m_root; + btDbvtNode* m_free; + int m_lkhd; + int m_leaves; + unsigned m_opath; + btAlignedObjectArray m_stkStack; // Methods btDbvt(); ~btDbvt(); - void clear(); - bool empty() const { return(0==m_root); } - void optimizeBottomUp(); - void optimizeTopDown(int bu_treshold=128); - void optimizeIncremental(int passes); - btDbvtNode* insert(const btDbvtVolume& box,void* data); - void update(btDbvtNode* leaf,int lookahead=-1); - void update(btDbvtNode* leaf,btDbvtVolume& volume); - bool update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity,btScalar margin); - bool update(btDbvtNode* leaf,btDbvtVolume& volume,const btVector3& velocity); - bool update(btDbvtNode* leaf,btDbvtVolume& volume,btScalar margin); - void remove(btDbvtNode* leaf); - void write(IWriter* iwriter) const; - void clone(btDbvt& dest,IClone* iclone=0) const; - static int maxdepth(const btDbvtNode* node); - static int countLeaves(const btDbvtNode* node); - static void extractLeaves(const btDbvtNode* node,btAlignedObjectArray& leaves); + void clear(); + bool empty() const { return (0 == m_root); } + void optimizeBottomUp(); + void optimizeTopDown(int bu_treshold = 128); + void optimizeIncremental(int passes); + btDbvtNode* insert(const btDbvtVolume& box, void* data); + void update(btDbvtNode* leaf, int lookahead = -1); + void update(btDbvtNode* leaf, btDbvtVolume& volume); + bool update(btDbvtNode* leaf, btDbvtVolume& volume, const btVector3& velocity, btScalar margin); + bool update(btDbvtNode* leaf, btDbvtVolume& volume, const btVector3& velocity); + bool update(btDbvtNode* leaf, btDbvtVolume& volume, btScalar margin); + void remove(btDbvtNode* leaf); + void write(IWriter* iwriter) const; + void clone(btDbvt& dest, IClone* iclone = 0) const; + static int maxdepth(const btDbvtNode* node); + static int countLeaves(const btDbvtNode* node); + static void extractLeaves(const btDbvtNode* node, btAlignedObjectArray& leaves); #if DBVT_ENABLE_BENCHMARK - static void benchmark(); + static void benchmark(); #else - static void benchmark(){} + static void benchmark() + { + } #endif // DBVT_IPOLICY must support ICollide policy/interface DBVT_PREFIX - static void enumNodes( const btDbvtNode* root, - DBVT_IPOLICY); + static void enumNodes(const btDbvtNode* root, + DBVT_IPOLICY); DBVT_PREFIX - static void enumLeaves( const btDbvtNode* root, - DBVT_IPOLICY); + static void enumLeaves(const btDbvtNode* root, + DBVT_IPOLICY); DBVT_PREFIX - void collideTT( const btDbvtNode* root0, - const btDbvtNode* root1, - DBVT_IPOLICY); + void collideTT(const btDbvtNode* root0, + const btDbvtNode* root1, + DBVT_IPOLICY); DBVT_PREFIX - void collideTTpersistentStack( const btDbvtNode* root0, - const btDbvtNode* root1, - DBVT_IPOLICY); + void collideTTpersistentStack(const btDbvtNode* root0, + const btDbvtNode* root1, + DBVT_IPOLICY); #if 0 DBVT_PREFIX void collideTT( const btDbvtNode* root0, @@ -325,82 +326,89 @@ struct btDbvt #endif DBVT_PREFIX - void collideTV( const btDbvtNode* root, - const btDbvtVolume& volume, - DBVT_IPOLICY) const; - + void collideTV(const btDbvtNode* root, + const btDbvtVolume& volume, + DBVT_IPOLICY) const; + DBVT_PREFIX - void collideTVNoStackAlloc( const btDbvtNode* root, - const btDbvtVolume& volume, - btNodeStack& stack, - DBVT_IPOLICY) const; - - - - + void collideTVNoStackAlloc(const btDbvtNode* root, + const btDbvtVolume& volume, + btNodeStack& stack, + DBVT_IPOLICY) const; + ///rayTest is a re-entrant ray test, and can be called in parallel as long as the btAlignedAlloc is thread-safe (uses locking etc) ///rayTest is slower than rayTestInternal, because it builds a local stack, using memory allocations, and it recomputes signs/rayDirectionInverses each time DBVT_PREFIX - static void rayTest( const btDbvtNode* root, - const btVector3& rayFrom, - const btVector3& rayTo, - DBVT_IPOLICY); + static void rayTest(const btDbvtNode* root, + const btVector3& rayFrom, + const btVector3& rayTo, + DBVT_IPOLICY); ///rayTestInternal is faster than rayTest, because it uses a persistent stack (to reduce dynamic memory allocations to a minimum) and it uses precomputed signs/rayInverseDirections ///rayTestInternal is used by btDbvtBroadphase to accelerate world ray casts DBVT_PREFIX - void rayTestInternal( const btDbvtNode* root, - const btVector3& rayFrom, - const btVector3& rayTo, - const btVector3& rayDirectionInverse, - unsigned int signs[3], - btScalar lambda_max, - const btVector3& aabbMin, - const btVector3& aabbMax, - btAlignedObjectArray& stack, - DBVT_IPOLICY) const; + void rayTestInternal(const btDbvtNode* root, + const btVector3& rayFrom, + const btVector3& rayTo, + const btVector3& rayDirectionInverse, + unsigned int signs[3], + btScalar lambda_max, + const btVector3& aabbMin, + const btVector3& aabbMax, + btAlignedObjectArray& stack, + DBVT_IPOLICY) const; DBVT_PREFIX - static void collideKDOP(const btDbvtNode* root, - const btVector3* normals, - const btScalar* offsets, - int count, - DBVT_IPOLICY); + static void collideKDOP(const btDbvtNode* root, + const btVector3* normals, + const btScalar* offsets, + int count, + DBVT_IPOLICY); DBVT_PREFIX - static void collideOCL( const btDbvtNode* root, - const btVector3* normals, - const btScalar* offsets, - const btVector3& sortaxis, - int count, - DBVT_IPOLICY, - bool fullsort=true); + static void collideOCL(const btDbvtNode* root, + const btVector3* normals, + const btScalar* offsets, + const btVector3& sortaxis, + int count, + DBVT_IPOLICY, + bool fullsort = true); DBVT_PREFIX - static void collideTU( const btDbvtNode* root, - DBVT_IPOLICY); - // Helpers - static DBVT_INLINE int nearest(const int* i,const btDbvt::sStkNPS* a,btScalar v,int l,int h) + static void collideTU(const btDbvtNode* root, + DBVT_IPOLICY); + // Helpers + static DBVT_INLINE int nearest(const int* i, const btDbvt::sStkNPS* a, btScalar v, int l, int h) { - int m=0; - while(l>1; - if(a[i[m]].value>=v) l=m+1; else h=m; + m = (l + h) >> 1; + if (a[i[m]].value >= v) + l = m + 1; + else + h = m; } - return(h); + return (h); } - static DBVT_INLINE int allocate( btAlignedObjectArray& ifree, - btAlignedObjectArray& stock, - const sStkNPS& value) + static DBVT_INLINE int allocate(btAlignedObjectArray& ifree, + btAlignedObjectArray& stock, + const sStkNPS& value) { - int i; - if(ifree.size()>0) - { i=ifree[ifree.size()-1];ifree.pop_back();stock[i]=value; } + int i; + if (ifree.size() > 0) + { + i = ifree[ifree.size() - 1]; + ifree.pop_back(); + stock[i] = value; + } else - { i=stock.size();stock.push_back(value); } - return(i); + { + i = stock.size(); + stock.push_back(value); + } + return (i); } // private: - btDbvt(const btDbvt&) {} + btDbvt(const btDbvt&) {} }; // @@ -408,227 +416,252 @@ private: // // -inline btDbvtAabbMm btDbvtAabbMm::FromCE(const btVector3& c,const btVector3& e) +inline btDbvtAabbMm btDbvtAabbMm::FromCE(const btVector3& c, const btVector3& e) { btDbvtAabbMm box; - box.mi=c-e;box.mx=c+e; - return(box); + box.mi = c - e; + box.mx = c + e; + return (box); } // -inline btDbvtAabbMm btDbvtAabbMm::FromCR(const btVector3& c,btScalar r) +inline btDbvtAabbMm btDbvtAabbMm::FromCR(const btVector3& c, btScalar r) { - return(FromCE(c,btVector3(r,r,r))); + return (FromCE(c, btVector3(r, r, r))); } // -inline btDbvtAabbMm btDbvtAabbMm::FromMM(const btVector3& mi,const btVector3& mx) +inline btDbvtAabbMm btDbvtAabbMm::FromMM(const btVector3& mi, const btVector3& mx) { btDbvtAabbMm box; - box.mi=mi;box.mx=mx; - return(box); + box.mi = mi; + box.mx = mx; + return (box); } // -inline btDbvtAabbMm btDbvtAabbMm::FromPoints(const btVector3* pts,int n) +inline btDbvtAabbMm btDbvtAabbMm::FromPoints(const btVector3* pts, int n) { btDbvtAabbMm box; - box.mi=box.mx=pts[0]; - for(int i=1;i0) mx.setX(mx.x()+e[0]); else mi.setX(mi.x()+e[0]); - if(e.y()>0) mx.setY(mx.y()+e[1]); else mi.setY(mi.y()+e[1]); - if(e.z()>0) mx.setZ(mx.z()+e[2]); else mi.setZ(mi.z()+e[2]); + if (e.x() > 0) + mx.setX(mx.x() + e[0]); + else + mi.setX(mi.x() + e[0]); + if (e.y() > 0) + mx.setY(mx.y() + e[1]); + else + mi.setY(mi.y() + e[1]); + if (e.z() > 0) + mx.setZ(mx.z() + e[2]); + else + mi.setZ(mi.z() + e[2]); } // -DBVT_INLINE bool btDbvtAabbMm::Contain(const btDbvtAabbMm& a) const +DBVT_INLINE bool btDbvtAabbMm::Contain(const btDbvtAabbMm& a) const { - return( (mi.x()<=a.mi.x())&& - (mi.y()<=a.mi.y())&& - (mi.z()<=a.mi.z())&& - (mx.x()>=a.mx.x())&& - (mx.y()>=a.mx.y())&& - (mx.z()>=a.mx.z())); + return ((mi.x() <= a.mi.x()) && + (mi.y() <= a.mi.y()) && + (mi.z() <= a.mi.z()) && + (mx.x() >= a.mx.x()) && + (mx.y() >= a.mx.y()) && + (mx.z() >= a.mx.z())); } // -DBVT_INLINE int btDbvtAabbMm::Classify(const btVector3& n,btScalar o,int s) const +DBVT_INLINE int btDbvtAabbMm::Classify(const btVector3& n, btScalar o, int s) const { - btVector3 pi,px; - switch(s) + btVector3 pi, px; + switch (s) { - case (0+0+0): px=btVector3(mi.x(),mi.y(),mi.z()); - pi=btVector3(mx.x(),mx.y(),mx.z());break; - case (1+0+0): px=btVector3(mx.x(),mi.y(),mi.z()); - pi=btVector3(mi.x(),mx.y(),mx.z());break; - case (0+2+0): px=btVector3(mi.x(),mx.y(),mi.z()); - pi=btVector3(mx.x(),mi.y(),mx.z());break; - case (1+2+0): px=btVector3(mx.x(),mx.y(),mi.z()); - pi=btVector3(mi.x(),mi.y(),mx.z());break; - case (0+0+4): px=btVector3(mi.x(),mi.y(),mx.z()); - pi=btVector3(mx.x(),mx.y(),mi.z());break; - case (1+0+4): px=btVector3(mx.x(),mi.y(),mx.z()); - pi=btVector3(mi.x(),mx.y(),mi.z());break; - case (0+2+4): px=btVector3(mi.x(),mx.y(),mx.z()); - pi=btVector3(mx.x(),mi.y(),mi.z());break; - case (1+2+4): px=btVector3(mx.x(),mx.y(),mx.z()); - pi=btVector3(mi.x(),mi.y(),mi.z());break; + case (0 + 0 + 0): + px = btVector3(mi.x(), mi.y(), mi.z()); + pi = btVector3(mx.x(), mx.y(), mx.z()); + break; + case (1 + 0 + 0): + px = btVector3(mx.x(), mi.y(), mi.z()); + pi = btVector3(mi.x(), mx.y(), mx.z()); + break; + case (0 + 2 + 0): + px = btVector3(mi.x(), mx.y(), mi.z()); + pi = btVector3(mx.x(), mi.y(), mx.z()); + break; + case (1 + 2 + 0): + px = btVector3(mx.x(), mx.y(), mi.z()); + pi = btVector3(mi.x(), mi.y(), mx.z()); + break; + case (0 + 0 + 4): + px = btVector3(mi.x(), mi.y(), mx.z()); + pi = btVector3(mx.x(), mx.y(), mi.z()); + break; + case (1 + 0 + 4): + px = btVector3(mx.x(), mi.y(), mx.z()); + pi = btVector3(mi.x(), mx.y(), mi.z()); + break; + case (0 + 2 + 4): + px = btVector3(mi.x(), mx.y(), mx.z()); + pi = btVector3(mx.x(), mi.y(), mi.z()); + break; + case (1 + 2 + 4): + px = btVector3(mx.x(), mx.y(), mx.z()); + pi = btVector3(mi.x(), mi.y(), mi.z()); + break; } - if((btDot(n,px)+o)<0) return(-1); - if((btDot(n,pi)+o)>=0) return(+1); - return(0); + if ((btDot(n, px) + o) < 0) return (-1); + if ((btDot(n, pi) + o) >= 0) return (+1); + return (0); } // -DBVT_INLINE btScalar btDbvtAabbMm::ProjectMinimum(const btVector3& v,unsigned signs) const +DBVT_INLINE btScalar btDbvtAabbMm::ProjectMinimum(const btVector3& v, unsigned signs) const { - const btVector3* b[]={&mx,&mi}; - const btVector3 p( b[(signs>>0)&1]->x(), - b[(signs>>1)&1]->y(), - b[(signs>>2)&1]->z()); - return(btDot(p,v)); + const btVector3* b[] = {&mx, &mi}; + const btVector3 p(b[(signs >> 0) & 1]->x(), + b[(signs >> 1) & 1]->y(), + b[(signs >> 2) & 1]->z()); + return (btDot(p, v)); } // -DBVT_INLINE void btDbvtAabbMm::AddSpan(const btVector3& d,btScalar& smi,btScalar& smx) const +DBVT_INLINE void btDbvtAabbMm::AddSpan(const btVector3& d, btScalar& smi, btScalar& smx) const { - for(int i=0;i<3;++i) + for (int i = 0; i < 3; ++i) { - if(d[i]<0) - { smi+=mx[i]*d[i];smx+=mi[i]*d[i]; } + if (d[i] < 0) + { + smi += mx[i] * d[i]; + smx += mi[i] * d[i]; + } else - { smi+=mi[i]*d[i];smx+=mx[i]*d[i]; } + { + smi += mi[i] * d[i]; + smx += mx[i] * d[i]; + } } } // -DBVT_INLINE bool Intersect( const btDbvtAabbMm& a, - const btDbvtAabbMm& b) +DBVT_INLINE bool Intersect(const btDbvtAabbMm& a, + const btDbvtAabbMm& b) { -#if DBVT_INT0_IMPL == DBVT_IMPL_SSE - const __m128 rt(_mm_or_ps( _mm_cmplt_ps(_mm_load_ps(b.mx),_mm_load_ps(a.mi)), - _mm_cmplt_ps(_mm_load_ps(a.mx),_mm_load_ps(b.mi)))); -#if defined (_WIN32) - const __int32* pu((const __int32*)&rt); +#if DBVT_INT0_IMPL == DBVT_IMPL_SSE + const __m128 rt(_mm_or_ps(_mm_cmplt_ps(_mm_load_ps(b.mx), _mm_load_ps(a.mi)), + _mm_cmplt_ps(_mm_load_ps(a.mx), _mm_load_ps(b.mi)))); +#if defined(_WIN32) + const __int32* pu((const __int32*)&rt); #else - const int* pu((const int*)&rt); + const int* pu((const int*)&rt); #endif - return((pu[0]|pu[1]|pu[2])==0); + return ((pu[0] | pu[1] | pu[2]) == 0); #else - return( (a.mi.x()<=b.mx.x())&& - (a.mx.x()>=b.mi.x())&& - (a.mi.y()<=b.mx.y())&& - (a.mx.y()>=b.mi.y())&& - (a.mi.z()<=b.mx.z())&& - (a.mx.z()>=b.mi.z())); + return ((a.mi.x() <= b.mx.x()) && + (a.mx.x() >= b.mi.x()) && + (a.mi.y() <= b.mx.y()) && + (a.mx.y() >= b.mi.y()) && + (a.mi.z() <= b.mx.z()) && + (a.mx.z() >= b.mi.z())); #endif } - - // -DBVT_INLINE bool Intersect( const btDbvtAabbMm& a, - const btVector3& b) +DBVT_INLINE bool Intersect(const btDbvtAabbMm& a, + const btVector3& b) { - return( (b.x()>=a.mi.x())&& - (b.y()>=a.mi.y())&& - (b.z()>=a.mi.z())&& - (b.x()<=a.mx.x())&& - (b.y()<=a.mx.y())&& - (b.z()<=a.mx.z())); + return ((b.x() >= a.mi.x()) && + (b.y() >= a.mi.y()) && + (b.z() >= a.mi.z()) && + (b.x() <= a.mx.x()) && + (b.y() <= a.mx.y()) && + (b.z() <= a.mx.z())); } - - - - ////////////////////////////////////// - // -DBVT_INLINE btScalar Proximity( const btDbvtAabbMm& a, - const btDbvtAabbMm& b) -{ - const btVector3 d=(a.mi+a.mx)-(b.mi+b.mx); - return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z())); -} - - - -// -DBVT_INLINE int Select( const btDbvtAabbMm& o, - const btDbvtAabbMm& a, +DBVT_INLINE btScalar Proximity(const btDbvtAabbMm& a, const btDbvtAabbMm& b) { -#if DBVT_SELECT_IMPL == DBVT_IMPL_SSE - -#if defined (_WIN32) - static ATTRIBUTE_ALIGNED16(const unsigned __int32) mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x7fffffff}; + const btVector3 d = (a.mi + a.mx) - (b.mi + b.mx); + return (btFabs(d.x()) + btFabs(d.y()) + btFabs(d.z())); +} + +// +DBVT_INLINE int Select(const btDbvtAabbMm& o, + const btDbvtAabbMm& a, + const btDbvtAabbMm& b) +{ +#if DBVT_SELECT_IMPL == DBVT_IMPL_SSE + +#if defined(_WIN32) + static ATTRIBUTE_ALIGNED16(const unsigned __int32) mask[] = {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x7fffffff}; #else - static ATTRIBUTE_ALIGNED16(const unsigned int) mask[]={0x7fffffff,0x7fffffff,0x7fffffff,0x00000000 /*0x7fffffff*/}; + static ATTRIBUTE_ALIGNED16(const unsigned int) mask[] = {0x7fffffff, 0x7fffffff, 0x7fffffff, 0x00000000 /*0x7fffffff*/}; #endif ///@todo: the intrinsic version is 11% slower #if DBVT_USE_INTRINSIC_SSE - union btSSEUnion ///NOTE: if we use more intrinsics, move btSSEUnion into the LinearMath directory + union btSSEUnion ///NOTE: if we use more intrinsics, move btSSEUnion into the LinearMath directory { - __m128 ssereg; - float floats[4]; - int ints[4]; + __m128 ssereg; + float floats[4]; + int ints[4]; }; - __m128 omi(_mm_load_ps(o.mi)); - omi=_mm_add_ps(omi,_mm_load_ps(o.mx)); - __m128 ami(_mm_load_ps(a.mi)); - ami=_mm_add_ps(ami,_mm_load_ps(a.mx)); - ami=_mm_sub_ps(ami,omi); - ami=_mm_and_ps(ami,_mm_load_ps((const float*)mask)); - __m128 bmi(_mm_load_ps(b.mi)); - bmi=_mm_add_ps(bmi,_mm_load_ps(b.mx)); - bmi=_mm_sub_ps(bmi,omi); - bmi=_mm_and_ps(bmi,_mm_load_ps((const float*)mask)); - __m128 t0(_mm_movehl_ps(ami,ami)); - ami=_mm_add_ps(ami,t0); - ami=_mm_add_ss(ami,_mm_shuffle_ps(ami,ami,1)); - __m128 t1(_mm_movehl_ps(bmi,bmi)); - bmi=_mm_add_ps(bmi,t1); - bmi=_mm_add_ss(bmi,_mm_shuffle_ps(bmi,bmi,1)); - + __m128 omi(_mm_load_ps(o.mi)); + omi = _mm_add_ps(omi, _mm_load_ps(o.mx)); + __m128 ami(_mm_load_ps(a.mi)); + ami = _mm_add_ps(ami, _mm_load_ps(a.mx)); + ami = _mm_sub_ps(ami, omi); + ami = _mm_and_ps(ami, _mm_load_ps((const float*)mask)); + __m128 bmi(_mm_load_ps(b.mi)); + bmi = _mm_add_ps(bmi, _mm_load_ps(b.mx)); + bmi = _mm_sub_ps(bmi, omi); + bmi = _mm_and_ps(bmi, _mm_load_ps((const float*)mask)); + __m128 t0(_mm_movehl_ps(ami, ami)); + ami = _mm_add_ps(ami, t0); + ami = _mm_add_ss(ami, _mm_shuffle_ps(ami, ami, 1)); + __m128 t1(_mm_movehl_ps(bmi, bmi)); + bmi = _mm_add_ps(bmi, t1); + bmi = _mm_add_ss(bmi, _mm_shuffle_ps(bmi, bmi, 1)); + btSSEUnion tmp; - tmp.ssereg = _mm_cmple_ss(bmi,ami); - return tmp.ints[0]&1; + tmp.ssereg = _mm_cmple_ss(bmi, ami); + return tmp.ints[0] & 1; #else - ATTRIBUTE_ALIGNED16(__int32 r[1]); + ATTRIBUTE_ALIGNED16(__int32 r[1]); __asm { mov eax,o @@ -656,46 +689,52 @@ DBVT_INLINE int Select( const btDbvtAabbMm& o, cmpless xmm2,xmm1 movss r,xmm2 } - return(r[0]&1); + return (r[0] & 1); #endif #else - return(Proximity(o,a)b.mx[i]) r.mx[i]=a.mx[i]; else r.mx[i]=b.mx[i]; + if (a.mi[i] < b.mi[i]) + r.mi[i] = a.mi[i]; + else + r.mi[i] = b.mi[i]; + if (a.mx[i] > b.mx[i]) + r.mx[i] = a.mx[i]; + else + r.mx[i] = b.mx[i]; } #endif } // -DBVT_INLINE bool NotEqual( const btDbvtAabbMm& a, - const btDbvtAabbMm& b) +DBVT_INLINE bool NotEqual(const btDbvtAabbMm& a, + const btDbvtAabbMm& b) { - return( (a.mi.x()!=b.mi.x())|| - (a.mi.y()!=b.mi.y())|| - (a.mi.z()!=b.mi.z())|| - (a.mx.x()!=b.mx.x())|| - (a.mx.y()!=b.mx.y())|| - (a.mx.z()!=b.mx.z())); + return ((a.mi.x() != b.mi.x()) || + (a.mi.y() != b.mi.y()) || + (a.mi.z() != b.mi.z()) || + (a.mx.x() != b.mx.x()) || + (a.mx.y() != b.mx.y()) || + (a.mx.z() != b.mx.z())); } // @@ -704,162 +743,162 @@ DBVT_INLINE bool NotEqual( const btDbvtAabbMm& a, // DBVT_PREFIX -inline void btDbvt::enumNodes( const btDbvtNode* root, - DBVT_IPOLICY) +inline void btDbvt::enumNodes(const btDbvtNode* root, + DBVT_IPOLICY) { DBVT_CHECKTYPE - policy.Process(root); - if(root->isinternal()) + policy.Process(root); + if (root->isinternal()) { - enumNodes(root->childs[0],policy); - enumNodes(root->childs[1],policy); + enumNodes(root->childs[0], policy); + enumNodes(root->childs[1], policy); } } // DBVT_PREFIX -inline void btDbvt::enumLeaves( const btDbvtNode* root, - DBVT_IPOLICY) +inline void btDbvt::enumLeaves(const btDbvtNode* root, + DBVT_IPOLICY) { DBVT_CHECKTYPE - if(root->isinternal()) - { - enumLeaves(root->childs[0],policy); - enumLeaves(root->childs[1],policy); - } - else - { - policy.Process(root); - } + if (root->isinternal()) + { + enumLeaves(root->childs[0], policy); + enumLeaves(root->childs[1], policy); + } + else + { + policy.Process(root); + } } // DBVT_PREFIX -inline void btDbvt::collideTT( const btDbvtNode* root0, - const btDbvtNode* root1, - DBVT_IPOLICY) +inline void btDbvt::collideTT(const btDbvtNode* root0, + const btDbvtNode* root1, + DBVT_IPOLICY) { DBVT_CHECKTYPE - if(root0&&root1) + if (root0 && root1) + { + int depth = 1; + int treshold = DOUBLE_STACKSIZE - 4; + btAlignedObjectArray stkStack; + stkStack.resize(DOUBLE_STACKSIZE); + stkStack[0] = sStkNN(root0, root1); + do { - int depth=1; - int treshold=DOUBLE_STACKSIZE-4; - btAlignedObjectArray stkStack; - stkStack.resize(DOUBLE_STACKSIZE); - stkStack[0]=sStkNN(root0,root1); - do { - sStkNN p=stkStack[--depth]; - if(depth>treshold) + sStkNN p = stkStack[--depth]; + if (depth > treshold) + { + stkStack.resize(stkStack.size() * 2); + treshold = stkStack.size() - 4; + } + if (p.a == p.b) + { + if (p.a->isinternal()) { - stkStack.resize(stkStack.size()*2); - treshold=stkStack.size()-4; + stkStack[depth++] = sStkNN(p.a->childs[0], p.a->childs[0]); + stkStack[depth++] = sStkNN(p.a->childs[1], p.a->childs[1]); + stkStack[depth++] = sStkNN(p.a->childs[0], p.a->childs[1]); } - if(p.a==p.b) + } + else if (Intersect(p.a->volume, p.b->volume)) + { + if (p.a->isinternal()) { - if(p.a->isinternal()) + if (p.b->isinternal()) { - stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]); - stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]); - stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]); - } - } - else if(Intersect(p.a->volume,p.b->volume)) - { - if(p.a->isinternal()) - { - if(p.b->isinternal()) - { - stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]); - stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]); - stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]); - stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]); - } - else - { - stkStack[depth++]=sStkNN(p.a->childs[0],p.b); - stkStack[depth++]=sStkNN(p.a->childs[1],p.b); - } + stkStack[depth++] = sStkNN(p.a->childs[0], p.b->childs[0]); + stkStack[depth++] = sStkNN(p.a->childs[1], p.b->childs[0]); + stkStack[depth++] = sStkNN(p.a->childs[0], p.b->childs[1]); + stkStack[depth++] = sStkNN(p.a->childs[1], p.b->childs[1]); } else { - if(p.b->isinternal()) - { - stkStack[depth++]=sStkNN(p.a,p.b->childs[0]); - stkStack[depth++]=sStkNN(p.a,p.b->childs[1]); - } - else - { - policy.Process(p.a,p.b); - } + stkStack[depth++] = sStkNN(p.a->childs[0], p.b); + stkStack[depth++] = sStkNN(p.a->childs[1], p.b); } } - } while(depth); - } + else + { + if (p.b->isinternal()) + { + stkStack[depth++] = sStkNN(p.a, p.b->childs[0]); + stkStack[depth++] = sStkNN(p.a, p.b->childs[1]); + } + else + { + policy.Process(p.a, p.b); + } + } + } + } while (depth); + } } - - DBVT_PREFIX -inline void btDbvt::collideTTpersistentStack( const btDbvtNode* root0, - const btDbvtNode* root1, - DBVT_IPOLICY) +inline void btDbvt::collideTTpersistentStack(const btDbvtNode* root0, + const btDbvtNode* root1, + DBVT_IPOLICY) { DBVT_CHECKTYPE - if(root0&&root1) + if (root0 && root1) + { + int depth = 1; + int treshold = DOUBLE_STACKSIZE - 4; + + m_stkStack.resize(DOUBLE_STACKSIZE); + m_stkStack[0] = sStkNN(root0, root1); + do { - int depth=1; - int treshold=DOUBLE_STACKSIZE-4; - - m_stkStack.resize(DOUBLE_STACKSIZE); - m_stkStack[0]=sStkNN(root0,root1); - do { - sStkNN p=m_stkStack[--depth]; - if(depth>treshold) + sStkNN p = m_stkStack[--depth]; + if (depth > treshold) + { + m_stkStack.resize(m_stkStack.size() * 2); + treshold = m_stkStack.size() - 4; + } + if (p.a == p.b) + { + if (p.a->isinternal()) { - m_stkStack.resize(m_stkStack.size()*2); - treshold=m_stkStack.size()-4; + m_stkStack[depth++] = sStkNN(p.a->childs[0], p.a->childs[0]); + m_stkStack[depth++] = sStkNN(p.a->childs[1], p.a->childs[1]); + m_stkStack[depth++] = sStkNN(p.a->childs[0], p.a->childs[1]); } - if(p.a==p.b) + } + else if (Intersect(p.a->volume, p.b->volume)) + { + if (p.a->isinternal()) { - if(p.a->isinternal()) + if (p.b->isinternal()) { - m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[0]); - m_stkStack[depth++]=sStkNN(p.a->childs[1],p.a->childs[1]); - m_stkStack[depth++]=sStkNN(p.a->childs[0],p.a->childs[1]); - } - } - else if(Intersect(p.a->volume,p.b->volume)) - { - if(p.a->isinternal()) - { - if(p.b->isinternal()) - { - m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[0]); - m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[0]); - m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b->childs[1]); - m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b->childs[1]); - } - else - { - m_stkStack[depth++]=sStkNN(p.a->childs[0],p.b); - m_stkStack[depth++]=sStkNN(p.a->childs[1],p.b); - } + m_stkStack[depth++] = sStkNN(p.a->childs[0], p.b->childs[0]); + m_stkStack[depth++] = sStkNN(p.a->childs[1], p.b->childs[0]); + m_stkStack[depth++] = sStkNN(p.a->childs[0], p.b->childs[1]); + m_stkStack[depth++] = sStkNN(p.a->childs[1], p.b->childs[1]); } else { - if(p.b->isinternal()) - { - m_stkStack[depth++]=sStkNN(p.a,p.b->childs[0]); - m_stkStack[depth++]=sStkNN(p.a,p.b->childs[1]); - } - else - { - policy.Process(p.a,p.b); - } + m_stkStack[depth++] = sStkNN(p.a->childs[0], p.b); + m_stkStack[depth++] = sStkNN(p.a->childs[1], p.b); } } - } while(depth); - } + else + { + if (p.b->isinternal()) + { + m_stkStack[depth++] = sStkNN(p.a, p.b->childs[0]); + m_stkStack[depth++] = sStkNN(p.a, p.b->childs[1]); + } + else + { + policy.Process(p.a, p.b); + } + } + } + } while (depth); + } } #if 0 @@ -929,33 +968,35 @@ inline void btDbvt::collideTT( const btDbvtNode* root0, const btTransform xform=xform0.inverse()*xform1; collideTT(root0,root1,xform,policy); } -#endif +#endif DBVT_PREFIX -inline void btDbvt::collideTV( const btDbvtNode* root, - const btDbvtVolume& vol, - DBVT_IPOLICY) const +inline void btDbvt::collideTV(const btDbvtNode* root, + const btDbvtVolume& vol, + DBVT_IPOLICY) const { DBVT_CHECKTYPE - if(root) + if (root) { - ATTRIBUTE_ALIGNED16(btDbvtVolume) volume(vol); - btAlignedObjectArray stack; + ATTRIBUTE_ALIGNED16(btDbvtVolume) + volume(vol); + btAlignedObjectArray stack; stack.resize(0); #ifndef BT_DISABLE_STACK_TEMP_MEMORY - char tempmemory[SIMPLE_STACKSIZE*sizeof(const btDbvtNode*)]; + char tempmemory[SIMPLE_STACKSIZE * sizeof(const btDbvtNode*)]; stack.initializeFromBuffer(tempmemory, 0, SIMPLE_STACKSIZE); #else stack.reserve(SIMPLE_STACKSIZE); -#endif //BT_DISABLE_STACK_TEMP_MEMORY +#endif //BT_DISABLE_STACK_TEMP_MEMORY stack.push_back(root); - do { - const btDbvtNode* n=stack[stack.size()-1]; + do + { + const btDbvtNode* n = stack[stack.size() - 1]; stack.pop_back(); - if(Intersect(n->volume,volume)) + if (Intersect(n->volume, volume)) { - if(n->isinternal()) + if (n->isinternal()) { stack.push_back(n->childs[0]); stack.push_back(n->childs[1]); @@ -965,30 +1006,32 @@ inline void btDbvt::collideTV( const btDbvtNode* root, policy.Process(n); } } - } while(stack.size()>0); + } while (stack.size() > 0); } } // DBVT_PREFIX -inline void btDbvt::collideTVNoStackAlloc( const btDbvtNode* root, - const btDbvtVolume& vol, - btNodeStack& stack, - DBVT_IPOLICY) const +inline void btDbvt::collideTVNoStackAlloc(const btDbvtNode* root, + const btDbvtVolume& vol, + btNodeStack& stack, + DBVT_IPOLICY) const { DBVT_CHECKTYPE - if(root) + if (root) { - ATTRIBUTE_ALIGNED16(btDbvtVolume) volume(vol); + ATTRIBUTE_ALIGNED16(btDbvtVolume) + volume(vol); stack.resize(0); stack.reserve(SIMPLE_STACKSIZE); stack.push_back(root); - do { - const btDbvtNode* n=stack[stack.size()-1]; + do + { + const btDbvtNode* n = stack[stack.size() - 1]; stack.pop_back(); - if(Intersect(n->volume,volume)) + if (Intersect(n->volume, volume)) { - if(n->isinternal()) + if (n->isinternal()) { stack.push_back(n->childs[0]); stack.push_back(n->childs[1]); @@ -998,328 +1041,346 @@ inline void btDbvt::collideTVNoStackAlloc( const btDbvtNode* root, policy.Process(n); } } - } while(stack.size()>0); + } while (stack.size() > 0); } } - DBVT_PREFIX -inline void btDbvt::rayTestInternal( const btDbvtNode* root, - const btVector3& rayFrom, - const btVector3& rayTo, - const btVector3& rayDirectionInverse, - unsigned int signs[3], - btScalar lambda_max, - const btVector3& aabbMin, - const btVector3& aabbMax, - btAlignedObjectArray& stack, - DBVT_IPOLICY ) const +inline void btDbvt::rayTestInternal(const btDbvtNode* root, + const btVector3& rayFrom, + const btVector3& rayTo, + const btVector3& rayDirectionInverse, + unsigned int signs[3], + btScalar lambda_max, + const btVector3& aabbMin, + const btVector3& aabbMax, + btAlignedObjectArray& stack, + DBVT_IPOLICY) const { - (void) rayTo; + (void)rayTo; DBVT_CHECKTYPE - if(root) + if (root) { btVector3 resultNormal; - int depth=1; - int treshold=DOUBLE_STACKSIZE-2; + int depth = 1; + int treshold = DOUBLE_STACKSIZE - 2; stack.resize(DOUBLE_STACKSIZE); - stack[0]=root; + stack[0] = root; btVector3 bounds[2]; - do + do { - const btDbvtNode* node=stack[--depth]; - bounds[0] = node->volume.Mins()-aabbMax; - bounds[1] = node->volume.Maxs()-aabbMin; - btScalar tmin=1.f,lambda_min=0.f; - unsigned int result1=false; - result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max); - if(result1) + const btDbvtNode* node = stack[--depth]; + bounds[0] = node->volume.Mins() - aabbMax; + bounds[1] = node->volume.Maxs() - aabbMin; + btScalar tmin = 1.f, lambda_min = 0.f; + unsigned int result1 = false; + result1 = btRayAabb2(rayFrom, rayDirectionInverse, signs, bounds, tmin, lambda_min, lambda_max); + if (result1) { - if(node->isinternal()) + if (node->isinternal()) { - if(depth>treshold) + if (depth > treshold) { - stack.resize(stack.size()*2); - treshold=stack.size()-2; + stack.resize(stack.size() * 2); + treshold = stack.size() - 2; } - stack[depth++]=node->childs[0]; - stack[depth++]=node->childs[1]; + stack[depth++] = node->childs[0]; + stack[depth++] = node->childs[1]; } else { policy.Process(node); } } - } while(depth); + } while (depth); } } // DBVT_PREFIX -inline void btDbvt::rayTest( const btDbvtNode* root, - const btVector3& rayFrom, - const btVector3& rayTo, +inline void btDbvt::rayTest(const btDbvtNode* root, + const btVector3& rayFrom, + const btVector3& rayTo, + DBVT_IPOLICY) +{ + DBVT_CHECKTYPE + if (root) + { + btVector3 rayDir = (rayTo - rayFrom); + rayDir.normalize(); + + ///what about division by zero? --> just set rayDirection[i] to INF/BT_LARGE_FLOAT + btVector3 rayDirectionInverse; + rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0]; + rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1]; + rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2]; + unsigned int signs[3] = {rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0}; + + btScalar lambda_max = rayDir.dot(rayTo - rayFrom); + + btVector3 resultNormal; + + btAlignedObjectArray stack; + + int depth = 1; + int treshold = DOUBLE_STACKSIZE - 2; + + char tempmemory[DOUBLE_STACKSIZE * sizeof(const btDbvtNode*)]; +#ifndef BT_DISABLE_STACK_TEMP_MEMORY + stack.initializeFromBuffer(tempmemory, DOUBLE_STACKSIZE, DOUBLE_STACKSIZE); +#else //BT_DISABLE_STACK_TEMP_MEMORY + stack.resize(DOUBLE_STACKSIZE); +#endif //BT_DISABLE_STACK_TEMP_MEMORY + stack[0] = root; + btVector3 bounds[2]; + do + { + const btDbvtNode* node = stack[--depth]; + + bounds[0] = node->volume.Mins(); + bounds[1] = node->volume.Maxs(); + + btScalar tmin = 1.f, lambda_min = 0.f; + unsigned int result1 = btRayAabb2(rayFrom, rayDirectionInverse, signs, bounds, tmin, lambda_min, lambda_max); + +#ifdef COMPARE_BTRAY_AABB2 + btScalar param = 1.f; + bool result2 = btRayAabb(rayFrom, rayTo, node->volume.Mins(), node->volume.Maxs(), param, resultNormal); + btAssert(result1 == result2); +#endif //TEST_BTRAY_AABB2 + + if (result1) + { + if (node->isinternal()) + { + if (depth > treshold) + { + stack.resize(stack.size() * 2); + treshold = stack.size() - 2; + } + stack[depth++] = node->childs[0]; + stack[depth++] = node->childs[1]; + } + else + { + policy.Process(node); + } + } + } while (depth); + } +} + +// +DBVT_PREFIX +inline void btDbvt::collideKDOP(const btDbvtNode* root, + const btVector3* normals, + const btScalar* offsets, + int count, DBVT_IPOLICY) { DBVT_CHECKTYPE - if(root) + if (root) + { + const int inside = (1 << count) - 1; + btAlignedObjectArray stack; + int signs[sizeof(unsigned) * 8]; + btAssert(count < int(sizeof(signs) / sizeof(signs[0]))); + for (int i = 0; i < count; ++i) { - btVector3 rayDir = (rayTo-rayFrom); - rayDir.normalize (); - - ///what about division by zero? --> just set rayDirection[i] to INF/BT_LARGE_FLOAT - btVector3 rayDirectionInverse; - rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0]; - rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1]; - rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2]; - unsigned int signs[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0}; - - btScalar lambda_max = rayDir.dot(rayTo-rayFrom); - - btVector3 resultNormal; - - btAlignedObjectArray stack; - - int depth=1; - int treshold=DOUBLE_STACKSIZE-2; - - char tempmemory[DOUBLE_STACKSIZE * sizeof(const btDbvtNode*)]; -#ifndef BT_DISABLE_STACK_TEMP_MEMORY - stack.initializeFromBuffer(tempmemory, DOUBLE_STACKSIZE, DOUBLE_STACKSIZE); -#else//BT_DISABLE_STACK_TEMP_MEMORY - stack.resize(DOUBLE_STACKSIZE); -#endif //BT_DISABLE_STACK_TEMP_MEMORY - stack[0]=root; - btVector3 bounds[2]; - do { - const btDbvtNode* node=stack[--depth]; - - bounds[0] = node->volume.Mins(); - bounds[1] = node->volume.Maxs(); - - btScalar tmin=1.f,lambda_min=0.f; - unsigned int result1 = btRayAabb2(rayFrom,rayDirectionInverse,signs,bounds,tmin,lambda_min,lambda_max); - -#ifdef COMPARE_BTRAY_AABB2 - btScalar param=1.f; - bool result2 = btRayAabb(rayFrom,rayTo,node->volume.Mins(),node->volume.Maxs(),param,resultNormal); - btAssert(result1 == result2); -#endif //TEST_BTRAY_AABB2 - - if(result1) - { - if(node->isinternal()) - { - if(depth>treshold) - { - stack.resize(stack.size()*2); - treshold=stack.size()-2; - } - stack[depth++]=node->childs[0]; - stack[depth++]=node->childs[1]; - } - else - { - policy.Process(node); - } - } - } while(depth); - + signs[i] = ((normals[i].x() >= 0) ? 1 : 0) + + ((normals[i].y() >= 0) ? 2 : 0) + + ((normals[i].z() >= 0) ? 4 : 0); } -} - -// -DBVT_PREFIX -inline void btDbvt::collideKDOP(const btDbvtNode* root, - const btVector3* normals, - const btScalar* offsets, - int count, - DBVT_IPOLICY) -{ - DBVT_CHECKTYPE - if(root) + stack.reserve(SIMPLE_STACKSIZE); + stack.push_back(sStkNP(root, 0)); + do { - const int inside=(1< stack; - int signs[sizeof(unsigned)*8]; - btAssert(count=0)?1:0)+ - ((normals[i].y()>=0)?2:0)+ - ((normals[i].z()>=0)?4:0); + if (0 == (se.mask & j)) + { + const int side = se.node->volume.Classify(normals[i], offsets[i], signs[i]); + switch (side) + { + case -1: + out = true; + break; + case +1: + se.mask |= j; + break; + } + } } - stack.reserve(SIMPLE_STACKSIZE); - stack.push_back(sStkNP(root,0)); - do { - sStkNP se=stack[stack.size()-1]; - bool out=false; - stack.pop_back(); - for(int i=0,j=1;(!out)&&(ivolume.Classify(normals[i],offsets[i],signs[i]); - switch(side) - { - case -1: out=true;break; - case +1: se.mask|=j;break; - } - } - } - if(!out) - { - if((se.mask!=inside)&&(se.node->isinternal())) - { - stack.push_back(sStkNP(se.node->childs[0],se.mask)); - stack.push_back(sStkNP(se.node->childs[1],se.mask)); - } - else - { - if(policy.AllLeaves(se.node)) enumLeaves(se.node,policy); - } - } - } while(stack.size()); - } -} - -// -DBVT_PREFIX -inline void btDbvt::collideOCL( const btDbvtNode* root, - const btVector3* normals, - const btScalar* offsets, - const btVector3& sortaxis, - int count, - DBVT_IPOLICY, - bool fsort) -{ - DBVT_CHECKTYPE - if(root) - { - const unsigned srtsgns=(sortaxis[0]>=0?1:0)+ - (sortaxis[1]>=0?2:0)+ - (sortaxis[2]>=0?4:0); - const int inside=(1< stock; - btAlignedObjectArray ifree; - btAlignedObjectArray stack; - int signs[sizeof(unsigned)*8]; - btAssert(count=0)?1:0)+ - ((normals[i].y()>=0)?2:0)+ - ((normals[i].z()>=0)?4:0); + if ((se.mask != inside) && (se.node->isinternal())) + { + stack.push_back(sStkNP(se.node->childs[0], se.mask)); + stack.push_back(sStkNP(se.node->childs[1], se.mask)); + } + else + { + if (policy.AllLeaves(se.node)) enumLeaves(se.node, policy); + } } - stock.reserve(SIMPLE_STACKSIZE); - stack.reserve(SIMPLE_STACKSIZE); - ifree.reserve(SIMPLE_STACKSIZE); - stack.push_back(allocate(ifree,stock,sStkNPS(root,0,root->volume.ProjectMinimum(sortaxis,srtsgns)))); - do { - const int id=stack[stack.size()-1]; - sStkNPS se=stock[id]; - stack.pop_back();ifree.push_back(id); - if(se.mask!=inside) - { - bool out=false; - for(int i=0,j=1;(!out)&&(ivolume.Classify(normals[i],offsets[i],signs[i]); - switch(side) - { - case -1: out=true;break; - case +1: se.mask|=j;break; - } - } - } - if(out) continue; - } - if(policy.Descent(se.node)) - { - if(se.node->isinternal()) - { - const btDbvtNode* pns[]={ se.node->childs[0],se.node->childs[1]}; - sStkNPS nes[]={ sStkNPS(pns[0],se.mask,pns[0]->volume.ProjectMinimum(sortaxis,srtsgns)), - sStkNPS(pns[1],se.mask,pns[1]->volume.ProjectMinimum(sortaxis,srtsgns))}; - const int q=nes[0].value0)) - { - /* Insert 0 */ - j=nearest(&stack[0],&stock[0],nes[q].value,0,stack.size()); - stack.push_back(0); - - //void * memmove ( void * destination, const void * source, size_t num ); - -#if DBVT_USE_MEMMOVE - { - int num_items_to_move = stack.size()-1-j; - if(num_items_to_move > 0) - memmove(&stack[j+1],&stack[j],sizeof(int)*num_items_to_move); - } -#else - for(int k=stack.size()-1;k>j;--k) { - stack[k]=stack[k-1]; - } -#endif - stack[j]=allocate(ifree,stock,nes[q]); - /* Insert 1 */ - j=nearest(&stack[0],&stock[0],nes[1-q].value,j,stack.size()); - stack.push_back(0); -#if DBVT_USE_MEMMOVE - { - int num_items_to_move = stack.size()-1-j; - if(num_items_to_move > 0) - memmove(&stack[j+1],&stack[j],sizeof(int)*num_items_to_move); - } -#else - for(int k=stack.size()-1;k>j;--k) { - stack[k]=stack[k-1]; - } -#endif - stack[j]=allocate(ifree,stock,nes[1-q]); - } - else - { - stack.push_back(allocate(ifree,stock,nes[q])); - stack.push_back(allocate(ifree,stock,nes[1-q])); - } - } - else - { - policy.Process(se.node,se.value); - } - } - } while(stack.size()); - } + } while (stack.size()); + } } // DBVT_PREFIX -inline void btDbvt::collideTU( const btDbvtNode* root, - DBVT_IPOLICY) +inline void btDbvt::collideOCL(const btDbvtNode* root, + const btVector3* normals, + const btScalar* offsets, + const btVector3& sortaxis, + int count, + DBVT_IPOLICY, + bool fsort) { DBVT_CHECKTYPE - if(root) + if (root) + { + const unsigned srtsgns = (sortaxis[0] >= 0 ? 1 : 0) + + (sortaxis[1] >= 0 ? 2 : 0) + + (sortaxis[2] >= 0 ? 4 : 0); + const int inside = (1 << count) - 1; + btAlignedObjectArray stock; + btAlignedObjectArray ifree; + btAlignedObjectArray stack; + int signs[sizeof(unsigned) * 8]; + btAssert(count < int(sizeof(signs) / sizeof(signs[0]))); + for (int i = 0; i < count; ++i) { - btAlignedObjectArray stack; - stack.reserve(SIMPLE_STACKSIZE); - stack.push_back(root); - do { - const btDbvtNode* n=stack[stack.size()-1]; - stack.pop_back(); - if(policy.Descent(n)) - { - if(n->isinternal()) - { stack.push_back(n->childs[0]);stack.push_back(n->childs[1]); } - else - { policy.Process(n); } - } - } while(stack.size()>0); + signs[i] = ((normals[i].x() >= 0) ? 1 : 0) + + ((normals[i].y() >= 0) ? 2 : 0) + + ((normals[i].z() >= 0) ? 4 : 0); } + stock.reserve(SIMPLE_STACKSIZE); + stack.reserve(SIMPLE_STACKSIZE); + ifree.reserve(SIMPLE_STACKSIZE); + stack.push_back(allocate(ifree, stock, sStkNPS(root, 0, root->volume.ProjectMinimum(sortaxis, srtsgns)))); + do + { + const int id = stack[stack.size() - 1]; + sStkNPS se = stock[id]; + stack.pop_back(); + ifree.push_back(id); + if (se.mask != inside) + { + bool out = false; + for (int i = 0, j = 1; (!out) && (i < count); ++i, j <<= 1) + { + if (0 == (se.mask & j)) + { + const int side = se.node->volume.Classify(normals[i], offsets[i], signs[i]); + switch (side) + { + case -1: + out = true; + break; + case +1: + se.mask |= j; + break; + } + } + } + if (out) continue; + } + if (policy.Descent(se.node)) + { + if (se.node->isinternal()) + { + const btDbvtNode* pns[] = {se.node->childs[0], se.node->childs[1]}; + sStkNPS nes[] = {sStkNPS(pns[0], se.mask, pns[0]->volume.ProjectMinimum(sortaxis, srtsgns)), + sStkNPS(pns[1], se.mask, pns[1]->volume.ProjectMinimum(sortaxis, srtsgns))}; + const int q = nes[0].value < nes[1].value ? 1 : 0; + int j = stack.size(); + if (fsort && (j > 0)) + { + /* Insert 0 */ + j = nearest(&stack[0], &stock[0], nes[q].value, 0, stack.size()); + stack.push_back(0); + + //void * memmove ( void * destination, const void * source, size_t num ); + +#if DBVT_USE_MEMMOVE + { + int num_items_to_move = stack.size() - 1 - j; + if (num_items_to_move > 0) + memmove(&stack[j + 1], &stack[j], sizeof(int) * num_items_to_move); + } +#else + for (int k = stack.size() - 1; k > j; --k) + { + stack[k] = stack[k - 1]; + } +#endif + stack[j] = allocate(ifree, stock, nes[q]); + /* Insert 1 */ + j = nearest(&stack[0], &stock[0], nes[1 - q].value, j, stack.size()); + stack.push_back(0); +#if DBVT_USE_MEMMOVE + { + int num_items_to_move = stack.size() - 1 - j; + if (num_items_to_move > 0) + memmove(&stack[j + 1], &stack[j], sizeof(int) * num_items_to_move); + } +#else + for (int k = stack.size() - 1; k > j; --k) + { + stack[k] = stack[k - 1]; + } +#endif + stack[j] = allocate(ifree, stock, nes[1 - q]); + } + else + { + stack.push_back(allocate(ifree, stock, nes[q])); + stack.push_back(allocate(ifree, stock, nes[1 - q])); + } + } + else + { + policy.Process(se.node, se.value); + } + } + } while (stack.size()); + } +} + +// +DBVT_PREFIX +inline void btDbvt::collideTU(const btDbvtNode* root, + DBVT_IPOLICY) +{ + DBVT_CHECKTYPE + if (root) + { + btAlignedObjectArray stack; + stack.reserve(SIMPLE_STACKSIZE); + stack.push_back(root); + do + { + const btDbvtNode* n = stack[stack.size() - 1]; + stack.pop_back(); + if (policy.Descent(n)) + { + if (n->isinternal()) + { + stack.push_back(n->childs[0]); + stack.push_back(n->childs[1]); + } + else + { + policy.Process(n); + } + } + } while (stack.size() > 0); + } } // diff --git a/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp b/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp index 14cd1a31e..69e9ee748 100644 --- a/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp +++ b/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.cpp @@ -22,28 +22,27 @@ btScalar gDbvtMargin = btScalar(0.05); // Profiling // -#if DBVT_BP_PROFILE||DBVT_BP_ENABLE_BENCHMARK +#if DBVT_BP_PROFILE || DBVT_BP_ENABLE_BENCHMARK #include #endif #if DBVT_BP_PROFILE -struct ProfileScope +struct ProfileScope { - __forceinline ProfileScope(btClock& clock,unsigned long& value) : - m_clock(&clock),m_value(&value),m_base(clock.getTimeMicroseconds()) + __forceinline ProfileScope(btClock& clock, unsigned long& value) : m_clock(&clock), m_value(&value), m_base(clock.getTimeMicroseconds()) { } __forceinline ~ProfileScope() { - (*m_value)+=m_clock->getTimeMicroseconds()-m_base; + (*m_value) += m_clock->getTimeMicroseconds() - m_base; } - btClock* m_clock; - unsigned long* m_value; - unsigned long m_base; + btClock* m_clock; + unsigned long* m_value; + unsigned long m_base; }; -#define SPC(_value_) ProfileScope spc_scope(m_clock,_value_) +#define SPC(_value_) ProfileScope spc_scope(m_clock, _value_) #else -#define SPC(_value_) +#define SPC(_value_) #endif // @@ -52,66 +51,75 @@ struct ProfileScope // template -static inline void listappend(T* item,T*& list) +static inline void listappend(T* item, T*& list) { - item->links[0]=0; - item->links[1]=list; - if(list) list->links[0]=item; - list=item; + item->links[0] = 0; + item->links[1] = list; + if (list) list->links[0] = item; + list = item; } // template -static inline void listremove(T* item,T*& list) +static inline void listremove(T* item, T*& list) { - if(item->links[0]) item->links[0]->links[1]=item->links[1]; else list=item->links[1]; - if(item->links[1]) item->links[1]->links[0]=item->links[0]; + if (item->links[0]) + item->links[0]->links[1] = item->links[1]; + else + list = item->links[1]; + if (item->links[1]) item->links[1]->links[0] = item->links[0]; } // template -static inline int listcount(T* root) +static inline int listcount(T* root) { - int n=0; - while(root) { ++n;root=root->links[1]; } - return(n); + int n = 0; + while (root) + { + ++n; + root = root->links[1]; + } + return (n); } // template -static inline void clear(T& value) +static inline void clear(T& value) { - static const struct ZeroDummy : T {} zerodummy; - value=zerodummy; + static const struct ZeroDummy : T + { + } zerodummy; + value = zerodummy; } // // Colliders // -/* Tree collider */ -struct btDbvtTreeCollider : btDbvt::ICollide +/* Tree collider */ +struct btDbvtTreeCollider : btDbvt::ICollide { - btDbvtBroadphase* pbp; - btDbvtProxy* proxy; + btDbvtBroadphase* pbp; + btDbvtProxy* proxy; btDbvtTreeCollider(btDbvtBroadphase* p) : pbp(p) {} - void Process(const btDbvtNode* na,const btDbvtNode* nb) + void Process(const btDbvtNode* na, const btDbvtNode* nb) { - if(na!=nb) + if (na != nb) { - btDbvtProxy* pa=(btDbvtProxy*)na->data; - btDbvtProxy* pb=(btDbvtProxy*)nb->data; + btDbvtProxy* pa = (btDbvtProxy*)na->data; + btDbvtProxy* pb = (btDbvtProxy*)nb->data; #if DBVT_BP_SORTPAIRS - if(pa->m_uniqueId>pb->m_uniqueId) - btSwap(pa,pb); + if (pa->m_uniqueId > pb->m_uniqueId) + btSwap(pa, pb); #endif - pbp->m_paircache->addOverlappingPair(pa,pb); + pbp->m_paircache->addOverlappingPair(pa, pb); ++pbp->m_newpairs; } } - void Process(const btDbvtNode* n) + void Process(const btDbvtNode* n) { - Process(n,proxy->leaf); + Process(n, proxy->leaf); } }; @@ -122,31 +130,31 @@ struct btDbvtTreeCollider : btDbvt::ICollide // btDbvtBroadphase::btDbvtBroadphase(btOverlappingPairCache* paircache) { - m_deferedcollide = false; - m_needcleanup = true; - m_releasepaircache = (paircache!=0)?false:true; - m_prediction = 0; - m_stageCurrent = 0; - m_fixedleft = 0; - m_fupdates = 1; - m_dupdates = 0; - m_cupdates = 10; - m_newpairs = 1; - m_updates_call = 0; - m_updates_done = 0; - m_updates_ratio = 0; - m_paircache = paircache? paircache : new(btAlignedAlloc(sizeof(btHashedOverlappingPairCache),16)) btHashedOverlappingPairCache(); - m_gid = 0; - m_pid = 0; - m_cid = 0; - for(int i=0;i<=STAGECOUNT;++i) + m_deferedcollide = false; + m_needcleanup = true; + m_releasepaircache = (paircache != 0) ? false : true; + m_prediction = 0; + m_stageCurrent = 0; + m_fixedleft = 0; + m_fupdates = 1; + m_dupdates = 0; + m_cupdates = 10; + m_newpairs = 1; + m_updates_call = 0; + m_updates_done = 0; + m_updates_ratio = 0; + m_paircache = paircache ? paircache : new (btAlignedAlloc(sizeof(btHashedOverlappingPairCache), 16)) btHashedOverlappingPairCache(); + m_gid = 0; + m_pid = 0; + m_cid = 0; + for (int i = 0; i <= STAGECOUNT; ++i) { - m_stageRoots[i]=0; + m_stageRoots[i] = 0; } #if BT_THREADSAFE - m_rayTestStacks.resize(BT_MAX_THREAD_COUNT); + m_rayTestStacks.resize(BT_MAX_THREAD_COUNT); #else - m_rayTestStacks.resize(1); + m_rayTestStacks.resize(1); #endif #if DBVT_BP_PROFILE clear(m_profiling); @@ -156,7 +164,7 @@ btDbvtBroadphase::btDbvtBroadphase(btOverlappingPairCache* paircache) // btDbvtBroadphase::~btDbvtBroadphase() { - if(m_releasepaircache) + if (m_releasepaircache) { m_paircache->~btOverlappingPairCache(); btAlignedFree(m_paircache); @@ -164,302 +172,292 @@ btDbvtBroadphase::~btDbvtBroadphase() } // -btBroadphaseProxy* btDbvtBroadphase::createProxy( const btVector3& aabbMin, - const btVector3& aabbMax, - int /*shapeType*/, - void* userPtr, - int collisionFilterGroup, - int collisionFilterMask, - btDispatcher* /*dispatcher*/) +btBroadphaseProxy* btDbvtBroadphase::createProxy(const btVector3& aabbMin, + const btVector3& aabbMax, + int /*shapeType*/, + void* userPtr, + int collisionFilterGroup, + int collisionFilterMask, + btDispatcher* /*dispatcher*/) { - btDbvtProxy* proxy=new(btAlignedAlloc(sizeof(btDbvtProxy),16)) btDbvtProxy( aabbMin,aabbMax,userPtr, - collisionFilterGroup, - collisionFilterMask); + btDbvtProxy* proxy = new (btAlignedAlloc(sizeof(btDbvtProxy), 16)) btDbvtProxy(aabbMin, aabbMax, userPtr, + collisionFilterGroup, + collisionFilterMask); - btDbvtAabbMm aabb = btDbvtVolume::FromMM(aabbMin,aabbMax); + btDbvtAabbMm aabb = btDbvtVolume::FromMM(aabbMin, aabbMax); //bproxy->aabb = btDbvtVolume::FromMM(aabbMin,aabbMax); - proxy->stage = m_stageCurrent; - proxy->m_uniqueId = ++m_gid; - proxy->leaf = m_sets[0].insert(aabb,proxy); - listappend(proxy,m_stageRoots[m_stageCurrent]); - if(!m_deferedcollide) + proxy->stage = m_stageCurrent; + proxy->m_uniqueId = ++m_gid; + proxy->leaf = m_sets[0].insert(aabb, proxy); + listappend(proxy, m_stageRoots[m_stageCurrent]); + if (!m_deferedcollide) { - btDbvtTreeCollider collider(this); - collider.proxy=proxy; - m_sets[0].collideTV(m_sets[0].m_root,aabb,collider); - m_sets[1].collideTV(m_sets[1].m_root,aabb,collider); + btDbvtTreeCollider collider(this); + collider.proxy = proxy; + m_sets[0].collideTV(m_sets[0].m_root, aabb, collider); + m_sets[1].collideTV(m_sets[1].m_root, aabb, collider); } - return(proxy); + return (proxy); } // -void btDbvtBroadphase::destroyProxy( btBroadphaseProxy* absproxy, - btDispatcher* dispatcher) +void btDbvtBroadphase::destroyProxy(btBroadphaseProxy* absproxy, + btDispatcher* dispatcher) { - btDbvtProxy* proxy=(btDbvtProxy*)absproxy; - if(proxy->stage==STAGECOUNT) + btDbvtProxy* proxy = (btDbvtProxy*)absproxy; + if (proxy->stage == STAGECOUNT) m_sets[1].remove(proxy->leaf); else m_sets[0].remove(proxy->leaf); - listremove(proxy,m_stageRoots[proxy->stage]); - m_paircache->removeOverlappingPairsContainingProxy(proxy,dispatcher); + listremove(proxy, m_stageRoots[proxy->stage]); + m_paircache->removeOverlappingPairsContainingProxy(proxy, dispatcher); btAlignedFree(proxy); - m_needcleanup=true; + m_needcleanup = true; } -void btDbvtBroadphase::getAabb(btBroadphaseProxy* absproxy,btVector3& aabbMin, btVector3& aabbMax ) const +void btDbvtBroadphase::getAabb(btBroadphaseProxy* absproxy, btVector3& aabbMin, btVector3& aabbMax) const { - btDbvtProxy* proxy=(btDbvtProxy*)absproxy; + btDbvtProxy* proxy = (btDbvtProxy*)absproxy; aabbMin = proxy->m_aabbMin; aabbMax = proxy->m_aabbMax; } -struct BroadphaseRayTester : btDbvt::ICollide +struct BroadphaseRayTester : btDbvt::ICollide { btBroadphaseRayCallback& m_rayCallback; BroadphaseRayTester(btBroadphaseRayCallback& orgCallback) - :m_rayCallback(orgCallback) + : m_rayCallback(orgCallback) { } - void Process(const btDbvtNode* leaf) + void Process(const btDbvtNode* leaf) { - btDbvtProxy* proxy=(btDbvtProxy*)leaf->data; + btDbvtProxy* proxy = (btDbvtProxy*)leaf->data; m_rayCallback.process(proxy); } -}; +}; -void btDbvtBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback,const btVector3& aabbMin,const btVector3& aabbMax) +void btDbvtBroadphase::rayTest(const btVector3& rayFrom, const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin, const btVector3& aabbMax) { BroadphaseRayTester callback(rayCallback); - btAlignedObjectArray* stack = &m_rayTestStacks[0]; + btAlignedObjectArray* stack = &m_rayTestStacks[0]; #if BT_THREADSAFE - // for this function to be threadsafe, each thread must have a separate copy - // of this stack. This could be thread-local static to avoid dynamic allocations, - // instead of just a local. - int threadIndex = btGetCurrentThreadIndex(); - btAlignedObjectArray localStack; - if (threadIndex < m_rayTestStacks.size()) - { - // use per-thread preallocated stack if possible to avoid dynamic allocations - stack = &m_rayTestStacks[threadIndex]; - } - else - { - stack = &localStack; - } + // for this function to be threadsafe, each thread must have a separate copy + // of this stack. This could be thread-local static to avoid dynamic allocations, + // instead of just a local. + int threadIndex = btGetCurrentThreadIndex(); + btAlignedObjectArray localStack; + if (threadIndex < m_rayTestStacks.size()) + { + // use per-thread preallocated stack if possible to avoid dynamic allocations + stack = &m_rayTestStacks[threadIndex]; + } + else + { + stack = &localStack; + } #endif - m_sets[0].rayTestInternal( m_sets[0].m_root, - rayFrom, - rayTo, - rayCallback.m_rayDirectionInverse, - rayCallback.m_signs, - rayCallback.m_lambda_max, - aabbMin, - aabbMax, - *stack, - callback); - - m_sets[1].rayTestInternal( m_sets[1].m_root, - rayFrom, - rayTo, - rayCallback.m_rayDirectionInverse, - rayCallback.m_signs, - rayCallback.m_lambda_max, - aabbMin, - aabbMax, - *stack, - callback); + m_sets[0].rayTestInternal(m_sets[0].m_root, + rayFrom, + rayTo, + rayCallback.m_rayDirectionInverse, + rayCallback.m_signs, + rayCallback.m_lambda_max, + aabbMin, + aabbMax, + *stack, + callback); + m_sets[1].rayTestInternal(m_sets[1].m_root, + rayFrom, + rayTo, + rayCallback.m_rayDirectionInverse, + rayCallback.m_signs, + rayCallback.m_lambda_max, + aabbMin, + aabbMax, + *stack, + callback); } - -struct BroadphaseAabbTester : btDbvt::ICollide +struct BroadphaseAabbTester : btDbvt::ICollide { btBroadphaseAabbCallback& m_aabbCallback; BroadphaseAabbTester(btBroadphaseAabbCallback& orgCallback) - :m_aabbCallback(orgCallback) + : m_aabbCallback(orgCallback) { } - void Process(const btDbvtNode* leaf) + void Process(const btDbvtNode* leaf) { - btDbvtProxy* proxy=(btDbvtProxy*)leaf->data; + btDbvtProxy* proxy = (btDbvtProxy*)leaf->data; m_aabbCallback.process(proxy); } -}; +}; -void btDbvtBroadphase::aabbTest(const btVector3& aabbMin,const btVector3& aabbMax,btBroadphaseAabbCallback& aabbCallback) +void btDbvtBroadphase::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& aabbCallback) { BroadphaseAabbTester callback(aabbCallback); - const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(aabbMin,aabbMax); - //process all children, that overlap with the given AABB bounds - m_sets[0].collideTV(m_sets[0].m_root,bounds,callback); - m_sets[1].collideTV(m_sets[1].m_root,bounds,callback); - + const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds = btDbvtVolume::FromMM(aabbMin, aabbMax); + //process all children, that overlap with the given AABB bounds + m_sets[0].collideTV(m_sets[0].m_root, bounds, callback); + m_sets[1].collideTV(m_sets[1].m_root, bounds, callback); } - - // -void btDbvtBroadphase::setAabb( btBroadphaseProxy* absproxy, - const btVector3& aabbMin, - const btVector3& aabbMax, - btDispatcher* /*dispatcher*/) +void btDbvtBroadphase::setAabb(btBroadphaseProxy* absproxy, + const btVector3& aabbMin, + const btVector3& aabbMax, + btDispatcher* /*dispatcher*/) { - btDbvtProxy* proxy=(btDbvtProxy*)absproxy; - ATTRIBUTE_ALIGNED16(btDbvtVolume) aabb=btDbvtVolume::FromMM(aabbMin,aabbMax); + btDbvtProxy* proxy = (btDbvtProxy*)absproxy; + ATTRIBUTE_ALIGNED16(btDbvtVolume) + aabb = btDbvtVolume::FromMM(aabbMin, aabbMax); #if DBVT_BP_PREVENTFALSEUPDATE - if(NotEqual(aabb,proxy->leaf->volume)) + if (NotEqual(aabb, proxy->leaf->volume)) #endif { - bool docollide=false; - if(proxy->stage==STAGECOUNT) - {/* fixed -> dynamic set */ + bool docollide = false; + if (proxy->stage == STAGECOUNT) + { /* fixed -> dynamic set */ m_sets[1].remove(proxy->leaf); - proxy->leaf=m_sets[0].insert(aabb,proxy); - docollide=true; + proxy->leaf = m_sets[0].insert(aabb, proxy); + docollide = true; } else - {/* dynamic set */ + { /* dynamic set */ ++m_updates_call; - if(Intersect(proxy->leaf->volume,aabb)) - {/* Moving */ + if (Intersect(proxy->leaf->volume, aabb)) + { /* Moving */ - const btVector3 delta=aabbMin-proxy->m_aabbMin; - btVector3 velocity(((proxy->m_aabbMax-proxy->m_aabbMin)/2)*m_prediction); - if(delta[0]<0) velocity[0]=-velocity[0]; - if(delta[1]<0) velocity[1]=-velocity[1]; - if(delta[2]<0) velocity[2]=-velocity[2]; + const btVector3 delta = aabbMin - proxy->m_aabbMin; + btVector3 velocity(((proxy->m_aabbMax - proxy->m_aabbMin) / 2) * m_prediction); + if (delta[0] < 0) velocity[0] = -velocity[0]; + if (delta[1] < 0) velocity[1] = -velocity[1]; + if (delta[2] < 0) velocity[2] = -velocity[2]; if ( m_sets[0].update(proxy->leaf, aabb, velocity, gDbvtMargin) - ) + ) { ++m_updates_done; - docollide=true; + docollide = true; } } else - {/* Teleporting */ - m_sets[0].update(proxy->leaf,aabb); + { /* Teleporting */ + m_sets[0].update(proxy->leaf, aabb); ++m_updates_done; - docollide=true; - } + docollide = true; + } } - listremove(proxy,m_stageRoots[proxy->stage]); + listremove(proxy, m_stageRoots[proxy->stage]); proxy->m_aabbMin = aabbMin; proxy->m_aabbMax = aabbMax; - proxy->stage = m_stageCurrent; - listappend(proxy,m_stageRoots[m_stageCurrent]); - if(docollide) + proxy->stage = m_stageCurrent; + listappend(proxy, m_stageRoots[m_stageCurrent]); + if (docollide) { - m_needcleanup=true; - if(!m_deferedcollide) + m_needcleanup = true; + if (!m_deferedcollide) { - btDbvtTreeCollider collider(this); - m_sets[1].collideTTpersistentStack(m_sets[1].m_root,proxy->leaf,collider); - m_sets[0].collideTTpersistentStack(m_sets[0].m_root,proxy->leaf,collider); + btDbvtTreeCollider collider(this); + m_sets[1].collideTTpersistentStack(m_sets[1].m_root, proxy->leaf, collider); + m_sets[0].collideTTpersistentStack(m_sets[0].m_root, proxy->leaf, collider); } - } + } } } - // -void btDbvtBroadphase::setAabbForceUpdate( btBroadphaseProxy* absproxy, - const btVector3& aabbMin, - const btVector3& aabbMax, - btDispatcher* /*dispatcher*/) +void btDbvtBroadphase::setAabbForceUpdate(btBroadphaseProxy* absproxy, + const btVector3& aabbMin, + const btVector3& aabbMax, + btDispatcher* /*dispatcher*/) { - btDbvtProxy* proxy=(btDbvtProxy*)absproxy; - ATTRIBUTE_ALIGNED16(btDbvtVolume) aabb=btDbvtVolume::FromMM(aabbMin,aabbMax); - bool docollide=false; - if(proxy->stage==STAGECOUNT) - {/* fixed -> dynamic set */ + btDbvtProxy* proxy = (btDbvtProxy*)absproxy; + ATTRIBUTE_ALIGNED16(btDbvtVolume) + aabb = btDbvtVolume::FromMM(aabbMin, aabbMax); + bool docollide = false; + if (proxy->stage == STAGECOUNT) + { /* fixed -> dynamic set */ m_sets[1].remove(proxy->leaf); - proxy->leaf=m_sets[0].insert(aabb,proxy); - docollide=true; + proxy->leaf = m_sets[0].insert(aabb, proxy); + docollide = true; } else - {/* dynamic set */ + { /* dynamic set */ ++m_updates_call; - /* Teleporting */ - m_sets[0].update(proxy->leaf,aabb); + /* Teleporting */ + m_sets[0].update(proxy->leaf, aabb); ++m_updates_done; - docollide=true; + docollide = true; } - listremove(proxy,m_stageRoots[proxy->stage]); + listremove(proxy, m_stageRoots[proxy->stage]); proxy->m_aabbMin = aabbMin; proxy->m_aabbMax = aabbMax; - proxy->stage = m_stageCurrent; - listappend(proxy,m_stageRoots[m_stageCurrent]); - if(docollide) + proxy->stage = m_stageCurrent; + listappend(proxy, m_stageRoots[m_stageCurrent]); + if (docollide) { - m_needcleanup=true; - if(!m_deferedcollide) + m_needcleanup = true; + if (!m_deferedcollide) { - btDbvtTreeCollider collider(this); - m_sets[1].collideTTpersistentStack(m_sets[1].m_root,proxy->leaf,collider); - m_sets[0].collideTTpersistentStack(m_sets[0].m_root,proxy->leaf,collider); + btDbvtTreeCollider collider(this); + m_sets[1].collideTTpersistentStack(m_sets[1].m_root, proxy->leaf, collider); + m_sets[0].collideTTpersistentStack(m_sets[0].m_root, proxy->leaf, collider); } - } + } } // -void btDbvtBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) +void btDbvtBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) { collide(dispatcher); #if DBVT_BP_PROFILE - if(0==(m_pid%DBVT_BP_PROFILING_RATE)) - { - printf("fixed(%u) dynamics(%u) pairs(%u)\r\n",m_sets[1].m_leaves,m_sets[0].m_leaves,m_paircache->getNumOverlappingPairs()); - unsigned int total=m_profiling.m_total; - if(total<=0) total=1; - printf("ddcollide: %u%% (%uus)\r\n",(50+m_profiling.m_ddcollide*100)/total,m_profiling.m_ddcollide/DBVT_BP_PROFILING_RATE); - printf("fdcollide: %u%% (%uus)\r\n",(50+m_profiling.m_fdcollide*100)/total,m_profiling.m_fdcollide/DBVT_BP_PROFILING_RATE); - printf("cleanup: %u%% (%uus)\r\n",(50+m_profiling.m_cleanup*100)/total,m_profiling.m_cleanup/DBVT_BP_PROFILING_RATE); - printf("total: %uus\r\n",total/DBVT_BP_PROFILING_RATE); - const unsigned long sum=m_profiling.m_ddcollide+ - m_profiling.m_fdcollide+ - m_profiling.m_cleanup; - printf("leaked: %u%% (%uus)\r\n",100-((50+sum*100)/total),(total-sum)/DBVT_BP_PROFILING_RATE); - printf("job counts: %u%%\r\n",(m_profiling.m_jobcount*100)/((m_sets[0].m_leaves+m_sets[1].m_leaves)*DBVT_BP_PROFILING_RATE)); + if (0 == (m_pid % DBVT_BP_PROFILING_RATE)) + { + printf("fixed(%u) dynamics(%u) pairs(%u)\r\n", m_sets[1].m_leaves, m_sets[0].m_leaves, m_paircache->getNumOverlappingPairs()); + unsigned int total = m_profiling.m_total; + if (total <= 0) total = 1; + printf("ddcollide: %u%% (%uus)\r\n", (50 + m_profiling.m_ddcollide * 100) / total, m_profiling.m_ddcollide / DBVT_BP_PROFILING_RATE); + printf("fdcollide: %u%% (%uus)\r\n", (50 + m_profiling.m_fdcollide * 100) / total, m_profiling.m_fdcollide / DBVT_BP_PROFILING_RATE); + printf("cleanup: %u%% (%uus)\r\n", (50 + m_profiling.m_cleanup * 100) / total, m_profiling.m_cleanup / DBVT_BP_PROFILING_RATE); + printf("total: %uus\r\n", total / DBVT_BP_PROFILING_RATE); + const unsigned long sum = m_profiling.m_ddcollide + + m_profiling.m_fdcollide + + m_profiling.m_cleanup; + printf("leaked: %u%% (%uus)\r\n", 100 - ((50 + sum * 100) / total), (total - sum) / DBVT_BP_PROFILING_RATE); + printf("job counts: %u%%\r\n", (m_profiling.m_jobcount * 100) / ((m_sets[0].m_leaves + m_sets[1].m_leaves) * DBVT_BP_PROFILING_RATE)); clear(m_profiling); m_clock.reset(); } #endif performDeferredRemoval(dispatcher); - } void btDbvtBroadphase::performDeferredRemoval(btDispatcher* dispatcher) { - if (m_paircache->hasDeferredRemoval()) { - - btBroadphasePairArray& overlappingPairArray = m_paircache->getOverlappingPairArray(); + btBroadphasePairArray& overlappingPairArray = m_paircache->getOverlappingPairArray(); //perform a sort, to find duplicates and to sort 'invalid' pairs to the end overlappingPairArray.quickSort(btBroadphasePairSortPredicate()); int invalidPair = 0; - int i; btBroadphasePair previousPair; previousPair.m_pProxy0 = 0; previousPair.m_pProxy1 = 0; previousPair.m_algorithm = 0; - - - for (i=0;ileaf->volume,pb->leaf->volume); + btDbvtProxy* pa = (btDbvtProxy*)pair.m_pProxy0; + btDbvtProxy* pb = (btDbvtProxy*)pair.m_pProxy1; + bool hasOverlap = Intersect(pa->leaf->volume, pb->leaf->volume); if (hasOverlap) { needsRemoval = false; - } else + } + else { needsRemoval = true; } - } else + } + else { //remove duplicate needsRemoval = true; //should have no algorithm btAssert(!pair.m_algorithm); } - + if (needsRemoval) { - m_paircache->cleanOverlappingPair(pair,dispatcher); + m_paircache->cleanOverlappingPair(pair, dispatcher); pair.m_pProxy0 = 0; pair.m_pProxy1 = 0; invalidPair++; - } - + } } //perform a sort, to sort 'invalid' pairs to the end @@ -508,7 +507,7 @@ void btDbvtBroadphase::performDeferredRemoval(btDispatcher* dispatcher) } // -void btDbvtBroadphase::collide(btDispatcher* dispatcher) +void btDbvtBroadphase::collide(btDispatcher* dispatcher) { /*printf("---------------------------------------------------------\n"); printf("m_sets[0].m_leaves=%d\n",m_sets[0].m_leaves); @@ -525,295 +524,303 @@ void btDbvtBroadphase::collide(btDispatcher* dispatcher) } */ - - SPC(m_profiling.m_total); - /* optimize */ - m_sets[0].optimizeIncremental(1+(m_sets[0].m_leaves*m_dupdates)/100); - if(m_fixedleft) + /* optimize */ + m_sets[0].optimizeIncremental(1 + (m_sets[0].m_leaves * m_dupdates) / 100); + if (m_fixedleft) { - const int count=1+(m_sets[1].m_leaves*m_fupdates)/100; - m_sets[1].optimizeIncremental(1+(m_sets[1].m_leaves*m_fupdates)/100); - m_fixedleft=btMax(0,m_fixedleft-count); + const int count = 1 + (m_sets[1].m_leaves * m_fupdates) / 100; + m_sets[1].optimizeIncremental(1 + (m_sets[1].m_leaves * m_fupdates) / 100); + m_fixedleft = btMax(0, m_fixedleft - count); } - /* dynamic -> fixed set */ - m_stageCurrent=(m_stageCurrent+1)%STAGECOUNT; - btDbvtProxy* current=m_stageRoots[m_stageCurrent]; - if(current) + /* dynamic -> fixed set */ + m_stageCurrent = (m_stageCurrent + 1) % STAGECOUNT; + btDbvtProxy* current = m_stageRoots[m_stageCurrent]; + if (current) { #if DBVT_BP_ACCURATESLEEPING - btDbvtTreeCollider collider(this); + btDbvtTreeCollider collider(this); #endif - do { - btDbvtProxy* next=current->links[1]; - listremove(current,m_stageRoots[current->stage]); - listappend(current,m_stageRoots[STAGECOUNT]); + do + { + btDbvtProxy* next = current->links[1]; + listremove(current, m_stageRoots[current->stage]); + listappend(current, m_stageRoots[STAGECOUNT]); #if DBVT_BP_ACCURATESLEEPING - m_paircache->removeOverlappingPairsContainingProxy(current,dispatcher); - collider.proxy=current; - btDbvt::collideTV(m_sets[0].m_root,current->aabb,collider); - btDbvt::collideTV(m_sets[1].m_root,current->aabb,collider); + m_paircache->removeOverlappingPairsContainingProxy(current, dispatcher); + collider.proxy = current; + btDbvt::collideTV(m_sets[0].m_root, current->aabb, collider); + btDbvt::collideTV(m_sets[1].m_root, current->aabb, collider); #endif m_sets[0].remove(current->leaf); - ATTRIBUTE_ALIGNED16(btDbvtVolume) curAabb=btDbvtVolume::FromMM(current->m_aabbMin,current->m_aabbMax); - current->leaf = m_sets[1].insert(curAabb,current); - current->stage = STAGECOUNT; - current = next; - } while(current); - m_fixedleft=m_sets[1].m_leaves; - m_needcleanup=true; + ATTRIBUTE_ALIGNED16(btDbvtVolume) + curAabb = btDbvtVolume::FromMM(current->m_aabbMin, current->m_aabbMax); + current->leaf = m_sets[1].insert(curAabb, current); + current->stage = STAGECOUNT; + current = next; + } while (current); + m_fixedleft = m_sets[1].m_leaves; + m_needcleanup = true; } - /* collide dynamics */ + /* collide dynamics */ { - btDbvtTreeCollider collider(this); - if(m_deferedcollide) + btDbvtTreeCollider collider(this); + if (m_deferedcollide) { SPC(m_profiling.m_fdcollide); - m_sets[0].collideTTpersistentStack(m_sets[0].m_root,m_sets[1].m_root,collider); + m_sets[0].collideTTpersistentStack(m_sets[0].m_root, m_sets[1].m_root, collider); } - if(m_deferedcollide) + if (m_deferedcollide) { SPC(m_profiling.m_ddcollide); - m_sets[0].collideTTpersistentStack(m_sets[0].m_root,m_sets[0].m_root,collider); + m_sets[0].collideTTpersistentStack(m_sets[0].m_root, m_sets[0].m_root, collider); } } - /* clean up */ - if(m_needcleanup) + /* clean up */ + if (m_needcleanup) { SPC(m_profiling.m_cleanup); - btBroadphasePairArray& pairs=m_paircache->getOverlappingPairArray(); - if(pairs.size()>0) + btBroadphasePairArray& pairs = m_paircache->getOverlappingPairArray(); + if (pairs.size() > 0) { - - int ni=btMin(pairs.size(),btMax(m_newpairs,(pairs.size()*m_cupdates)/100)); - for(int i=0;i(m_newpairs, (pairs.size() * m_cupdates) / 100)); + for (int i = 0; i < ni; ++i) { - btBroadphasePair& p=pairs[(m_cid+i)%pairs.size()]; - btDbvtProxy* pa=(btDbvtProxy*)p.m_pProxy0; - btDbvtProxy* pb=(btDbvtProxy*)p.m_pProxy1; - if(!Intersect(pa->leaf->volume,pb->leaf->volume)) + btBroadphasePair& p = pairs[(m_cid + i) % pairs.size()]; + btDbvtProxy* pa = (btDbvtProxy*)p.m_pProxy0; + btDbvtProxy* pb = (btDbvtProxy*)p.m_pProxy1; + if (!Intersect(pa->leaf->volume, pb->leaf->volume)) { #if DBVT_BP_SORTPAIRS - if(pa->m_uniqueId>pb->m_uniqueId) - btSwap(pa,pb); + if (pa->m_uniqueId > pb->m_uniqueId) + btSwap(pa, pb); #endif - m_paircache->removeOverlappingPair(pa,pb,dispatcher); - --ni;--i; + m_paircache->removeOverlappingPair(pa, pb, dispatcher); + --ni; + --i; } } - if(pairs.size()>0) m_cid=(m_cid+ni)%pairs.size(); else m_cid=0; + if (pairs.size() > 0) + m_cid = (m_cid + ni) % pairs.size(); + else + m_cid = 0; } } ++m_pid; - m_newpairs=1; - m_needcleanup=false; - if(m_updates_call>0) - { m_updates_ratio=m_updates_done/(btScalar)m_updates_call; } + m_newpairs = 1; + m_needcleanup = false; + if (m_updates_call > 0) + { + m_updates_ratio = m_updates_done / (btScalar)m_updates_call; + } else - { m_updates_ratio=0; } - m_updates_done/=2; - m_updates_call/=2; + { + m_updates_ratio = 0; + } + m_updates_done /= 2; + m_updates_call /= 2; } // -void btDbvtBroadphase::optimize() +void btDbvtBroadphase::optimize() { m_sets[0].optimizeTopDown(); m_sets[1].optimizeTopDown(); } // -btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() +btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() { - return(m_paircache); + return (m_paircache); } // -const btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() const +const btOverlappingPairCache* btDbvtBroadphase::getOverlappingPairCache() const { - return(m_paircache); + return (m_paircache); } // -void btDbvtBroadphase::getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const +void btDbvtBroadphase::getBroadphaseAabb(btVector3& aabbMin, btVector3& aabbMax) const { + ATTRIBUTE_ALIGNED16(btDbvtVolume) + bounds; - ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds; - - if(!m_sets[0].empty()) - if(!m_sets[1].empty()) Merge( m_sets[0].m_root->volume, - m_sets[1].m_root->volume,bounds); + if (!m_sets[0].empty()) + if (!m_sets[1].empty()) + Merge(m_sets[0].m_root->volume, + m_sets[1].m_root->volume, bounds); else - bounds=m_sets[0].m_root->volume; - else if(!m_sets[1].empty()) bounds=m_sets[1].m_root->volume; + bounds = m_sets[0].m_root->volume; + else if (!m_sets[1].empty()) + bounds = m_sets[1].m_root->volume; else - bounds=btDbvtVolume::FromCR(btVector3(0,0,0),0); - aabbMin=bounds.Mins(); - aabbMax=bounds.Maxs(); + bounds = btDbvtVolume::FromCR(btVector3(0, 0, 0), 0); + aabbMin = bounds.Mins(); + aabbMax = bounds.Maxs(); } void btDbvtBroadphase::resetPool(btDispatcher* dispatcher) { - int totalObjects = m_sets[0].m_leaves + m_sets[1].m_leaves; if (!totalObjects) { //reset internal dynamic tree data structures m_sets[0].clear(); m_sets[1].clear(); - - m_deferedcollide = false; - m_needcleanup = true; - m_stageCurrent = 0; - m_fixedleft = 0; - m_fupdates = 1; - m_dupdates = 0; - m_cupdates = 10; - m_newpairs = 1; - m_updates_call = 0; - m_updates_done = 0; - m_updates_ratio = 0; - - m_gid = 0; - m_pid = 0; - m_cid = 0; - for(int i=0;i<=STAGECOUNT;++i) + + m_deferedcollide = false; + m_needcleanup = true; + m_stageCurrent = 0; + m_fixedleft = 0; + m_fupdates = 1; + m_dupdates = 0; + m_cupdates = 10; + m_newpairs = 1; + m_updates_call = 0; + m_updates_done = 0; + m_updates_ratio = 0; + + m_gid = 0; + m_pid = 0; + m_cid = 0; + for (int i = 0; i <= STAGECOUNT; ++i) { - m_stageRoots[i]=0; + m_stageRoots[i] = 0; } } } // -void btDbvtBroadphase::printStats() -{} +void btDbvtBroadphase::printStats() +{ +} // #if DBVT_BP_ENABLE_BENCHMARK -struct btBroadphaseBenchmark +struct btBroadphaseBenchmark { - struct Experiment + struct Experiment { - const char* name; - int object_count; - int update_count; - int spawn_count; - int iterations; - btScalar speed; - btScalar amplitude; + const char* name; + int object_count; + int update_count; + int spawn_count; + int iterations; + btScalar speed; + btScalar amplitude; }; - struct Object + struct Object { - btVector3 center; - btVector3 extents; - btBroadphaseProxy* proxy; - btScalar time; - void update(btScalar speed,btScalar amplitude,btBroadphaseInterface* pbi) + btVector3 center; + btVector3 extents; + btBroadphaseProxy* proxy; + btScalar time; + void update(btScalar speed, btScalar amplitude, btBroadphaseInterface* pbi) { - time += speed; - center[0] = btCos(time*(btScalar)2.17)*amplitude+ - btSin(time)*amplitude/2; - center[1] = btCos(time*(btScalar)1.38)*amplitude+ - btSin(time)*amplitude; - center[2] = btSin(time*(btScalar)0.777)*amplitude; - pbi->setAabb(proxy,center-extents,center+extents,0); + time += speed; + center[0] = btCos(time * (btScalar)2.17) * amplitude + + btSin(time) * amplitude / 2; + center[1] = btCos(time * (btScalar)1.38) * amplitude + + btSin(time) * amplitude; + center[2] = btSin(time * (btScalar)0.777) * amplitude; + pbi->setAabb(proxy, center - extents, center + extents, 0); } }; - static int UnsignedRand(int range=RAND_MAX-1) { return(rand()%(range+1)); } - static btScalar UnitRand() { return(UnsignedRand(16384)/(btScalar)16384); } - static void OutputTime(const char* name,btClock& c,unsigned count=0) + static int UnsignedRand(int range = RAND_MAX - 1) { return (rand() % (range + 1)); } + static btScalar UnitRand() { return (UnsignedRand(16384) / (btScalar)16384); } + static void OutputTime(const char* name, btClock& c, unsigned count = 0) { - const unsigned long us=c.getTimeMicroseconds(); - const unsigned long ms=(us+500)/1000; - const btScalar sec=us/(btScalar)(1000*1000); - if(count>0) - printf("%s : %u us (%u ms), %.2f/s\r\n",name,us,ms,count/sec); + const unsigned long us = c.getTimeMicroseconds(); + const unsigned long ms = (us + 500) / 1000; + const btScalar sec = us / (btScalar)(1000 * 1000); + if (count > 0) + printf("%s : %u us (%u ms), %.2f/s\r\n", name, us, ms, count / sec); else - printf("%s : %u us (%u ms)\r\n",name,us,ms); + printf("%s : %u us (%u ms)\r\n", name, us, ms); } }; -void btDbvtBroadphase::benchmark(btBroadphaseInterface* pbi) +void btDbvtBroadphase::benchmark(btBroadphaseInterface* pbi) { - static const btBroadphaseBenchmark::Experiment experiments[]= - { - {"1024o.10%",1024,10,0,8192,(btScalar)0.005,(btScalar)100}, - /*{"4096o.10%",4096,10,0,8192,(btScalar)0.005,(btScalar)100}, + static const btBroadphaseBenchmark::Experiment experiments[] = + { + {"1024o.10%", 1024, 10, 0, 8192, (btScalar)0.005, (btScalar)100}, + /*{"4096o.10%",4096,10,0,8192,(btScalar)0.005,(btScalar)100}, {"8192o.10%",8192,10,0,8192,(btScalar)0.005,(btScalar)100},*/ - }; - static const int nexperiments=sizeof(experiments)/sizeof(experiments[0]); - btAlignedObjectArray objects; - btClock wallclock; - /* Begin */ - for(int iexp=0;iexp objects; + btClock wallclock; + /* Begin */ + for (int iexp = 0; iexp < nexperiments; ++iexp) { - const btBroadphaseBenchmark::Experiment& experiment=experiments[iexp]; - const int object_count=experiment.object_count; - const int update_count=(object_count*experiment.update_count)/100; - const int spawn_count=(object_count*experiment.spawn_count)/100; - const btScalar speed=experiment.speed; - const btScalar amplitude=experiment.amplitude; - printf("Experiment #%u '%s':\r\n",iexp,experiment.name); - printf("\tObjects: %u\r\n",object_count); - printf("\tUpdate: %u\r\n",update_count); - printf("\tSpawn: %u\r\n",spawn_count); - printf("\tSpeed: %f\r\n",speed); - printf("\tAmplitude: %f\r\n",amplitude); + const btBroadphaseBenchmark::Experiment& experiment = experiments[iexp]; + const int object_count = experiment.object_count; + const int update_count = (object_count * experiment.update_count) / 100; + const int spawn_count = (object_count * experiment.spawn_count) / 100; + const btScalar speed = experiment.speed; + const btScalar amplitude = experiment.amplitude; + printf("Experiment #%u '%s':\r\n", iexp, experiment.name); + printf("\tObjects: %u\r\n", object_count); + printf("\tUpdate: %u\r\n", update_count); + printf("\tSpawn: %u\r\n", spawn_count); + printf("\tSpeed: %f\r\n", speed); + printf("\tAmplitude: %f\r\n", amplitude); srand(180673); - /* Create objects */ + /* Create objects */ wallclock.reset(); objects.reserve(object_count); - for(int i=0;icenter[0]=btBroadphaseBenchmark::UnitRand()*50; - po->center[1]=btBroadphaseBenchmark::UnitRand()*50; - po->center[2]=btBroadphaseBenchmark::UnitRand()*50; - po->extents[0]=btBroadphaseBenchmark::UnitRand()*2+2; - po->extents[1]=btBroadphaseBenchmark::UnitRand()*2+2; - po->extents[2]=btBroadphaseBenchmark::UnitRand()*2+2; - po->time=btBroadphaseBenchmark::UnitRand()*2000; - po->proxy=pbi->createProxy(po->center-po->extents,po->center+po->extents,0,po,1,1,0,0); + btBroadphaseBenchmark::Object* po = new btBroadphaseBenchmark::Object(); + po->center[0] = btBroadphaseBenchmark::UnitRand() * 50; + po->center[1] = btBroadphaseBenchmark::UnitRand() * 50; + po->center[2] = btBroadphaseBenchmark::UnitRand() * 50; + po->extents[0] = btBroadphaseBenchmark::UnitRand() * 2 + 2; + po->extents[1] = btBroadphaseBenchmark::UnitRand() * 2 + 2; + po->extents[2] = btBroadphaseBenchmark::UnitRand() * 2 + 2; + po->time = btBroadphaseBenchmark::UnitRand() * 2000; + po->proxy = pbi->createProxy(po->center - po->extents, po->center + po->extents, 0, po, 1, 1, 0, 0); objects.push_back(po); } - btBroadphaseBenchmark::OutputTime("\tInitialization",wallclock); - /* First update */ + btBroadphaseBenchmark::OutputTime("\tInitialization", wallclock); + /* First update */ wallclock.reset(); - for(int i=0;iupdate(speed,amplitude,pbi); + objects[i]->update(speed, amplitude, pbi); } - btBroadphaseBenchmark::OutputTime("\tFirst update",wallclock); - /* Updates */ + btBroadphaseBenchmark::OutputTime("\tFirst update", wallclock); + /* Updates */ wallclock.reset(); - for(int i=0;iupdate(speed,amplitude,pbi); + for (int j = 0; j < update_count; ++j) + { + objects[j]->update(speed, amplitude, pbi); } pbi->calculateOverlappingPairs(0); } - btBroadphaseBenchmark::OutputTime("\tUpdate",wallclock,experiment.iterations); - /* Clean up */ + btBroadphaseBenchmark::OutputTime("\tUpdate", wallclock, experiment.iterations); + /* Clean up */ wallclock.reset(); - for(int i=0;idestroyProxy(objects[i]->proxy,0); + pbi->destroyProxy(objects[i]->proxy, 0); delete objects[i]; } objects.resize(0); - btBroadphaseBenchmark::OutputTime("\tRelease",wallclock); + btBroadphaseBenchmark::OutputTime("\tRelease", wallclock); } - } #else -void btDbvtBroadphase::benchmark(btBroadphaseInterface*) -{} +void btDbvtBroadphase::benchmark(btBroadphaseInterface*) +{ +} #endif #if DBVT_BP_PROFILE -#undef SPC +#undef SPC #endif - diff --git a/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h b/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h index 90b333d84..a71feef53 100644 --- a/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h +++ b/src/BulletCollision/BroadphaseCollision/btDbvtBroadphase.h @@ -24,16 +24,16 @@ subject to the following restrictions: // Compile time config // -#define DBVT_BP_PROFILE 0 +#define DBVT_BP_PROFILE 0 //#define DBVT_BP_SORTPAIRS 1 -#define DBVT_BP_PREVENTFALSEUPDATE 0 -#define DBVT_BP_ACCURATESLEEPING 0 -#define DBVT_BP_ENABLE_BENCHMARK 0 +#define DBVT_BP_PREVENTFALSEUPDATE 0 +#define DBVT_BP_ACCURATESLEEPING 0 +#define DBVT_BP_ENABLE_BENCHMARK 0 //#define DBVT_BP_MARGIN (btScalar)0.05 extern btScalar gDbvtMargin; #if DBVT_BP_PROFILE -#define DBVT_BP_PROFILING_RATE 256 +#define DBVT_BP_PROFILING_RATE 256 #include "LinearMath/btQuickprof.h" #endif @@ -42,90 +42,90 @@ extern btScalar gDbvtMargin; // struct btDbvtProxy : btBroadphaseProxy { - /* Fields */ + /* Fields */ //btDbvtAabbMm aabb; - btDbvtNode* leaf; - btDbvtProxy* links[2]; - int stage; - /* ctor */ - btDbvtProxy(const btVector3& aabbMin,const btVector3& aabbMax,void* userPtr, int collisionFilterGroup, int collisionFilterMask) : - btBroadphaseProxy(aabbMin,aabbMax,userPtr,collisionFilterGroup,collisionFilterMask) + btDbvtNode* leaf; + btDbvtProxy* links[2]; + int stage; + /* ctor */ + btDbvtProxy(const btVector3& aabbMin, const btVector3& aabbMax, void* userPtr, int collisionFilterGroup, int collisionFilterMask) : btBroadphaseProxy(aabbMin, aabbMax, userPtr, collisionFilterGroup, collisionFilterMask) { - links[0]=links[1]=0; + links[0] = links[1] = 0; } }; -typedef btAlignedObjectArray btDbvtProxyArray; +typedef btAlignedObjectArray btDbvtProxyArray; ///The btDbvtBroadphase implements a broadphase using two dynamic AABB bounding volume hierarchies/trees (see btDbvt). ///One tree is used for static/non-moving objects, and another tree is used for dynamic objects. Objects can move from one tree to the other. ///This is a very fast broadphase, especially for very dynamic worlds where many objects are moving. Its insert/add and remove of objects is generally faster than the sweep and prune broadphases btAxisSweep3 and bt32BitAxisSweep3. -struct btDbvtBroadphase : btBroadphaseInterface +struct btDbvtBroadphase : btBroadphaseInterface { - /* Config */ - enum { - DYNAMIC_SET = 0, /* Dynamic set index */ - FIXED_SET = 1, /* Fixed set index */ - STAGECOUNT = 2 /* Number of stages */ + /* Config */ + enum + { + DYNAMIC_SET = 0, /* Dynamic set index */ + FIXED_SET = 1, /* Fixed set index */ + STAGECOUNT = 2 /* Number of stages */ }; - /* Fields */ - btDbvt m_sets[2]; // Dbvt sets - btDbvtProxy* m_stageRoots[STAGECOUNT+1]; // Stages list - btOverlappingPairCache* m_paircache; // Pair cache - btScalar m_prediction; // Velocity prediction - int m_stageCurrent; // Current stage - int m_fupdates; // % of fixed updates per frame - int m_dupdates; // % of dynamic updates per frame - int m_cupdates; // % of cleanup updates per frame - int m_newpairs; // Number of pairs created - int m_fixedleft; // Fixed optimization left - unsigned m_updates_call; // Number of updates call - unsigned m_updates_done; // Number of updates done - btScalar m_updates_ratio; // m_updates_done/m_updates_call - int m_pid; // Parse id - int m_cid; // Cleanup index - int m_gid; // Gen id - bool m_releasepaircache; // Release pair cache on delete - bool m_deferedcollide; // Defere dynamic/static collision to collide call - bool m_needcleanup; // Need to run cleanup? - btAlignedObjectArray< btAlignedObjectArray > m_rayTestStacks; + /* Fields */ + btDbvt m_sets[2]; // Dbvt sets + btDbvtProxy* m_stageRoots[STAGECOUNT + 1]; // Stages list + btOverlappingPairCache* m_paircache; // Pair cache + btScalar m_prediction; // Velocity prediction + int m_stageCurrent; // Current stage + int m_fupdates; // % of fixed updates per frame + int m_dupdates; // % of dynamic updates per frame + int m_cupdates; // % of cleanup updates per frame + int m_newpairs; // Number of pairs created + int m_fixedleft; // Fixed optimization left + unsigned m_updates_call; // Number of updates call + unsigned m_updates_done; // Number of updates done + btScalar m_updates_ratio; // m_updates_done/m_updates_call + int m_pid; // Parse id + int m_cid; // Cleanup index + int m_gid; // Gen id + bool m_releasepaircache; // Release pair cache on delete + bool m_deferedcollide; // Defere dynamic/static collision to collide call + bool m_needcleanup; // Need to run cleanup? + btAlignedObjectArray > m_rayTestStacks; #if DBVT_BP_PROFILE - btClock m_clock; - struct { - unsigned long m_total; - unsigned long m_ddcollide; - unsigned long m_fdcollide; - unsigned long m_cleanup; - unsigned long m_jobcount; - } m_profiling; + btClock m_clock; + struct + { + unsigned long m_total; + unsigned long m_ddcollide; + unsigned long m_fdcollide; + unsigned long m_cleanup; + unsigned long m_jobcount; + } m_profiling; #endif - /* Methods */ - btDbvtBroadphase(btOverlappingPairCache* paircache=0); + /* Methods */ + btDbvtBroadphase(btOverlappingPairCache* paircache = 0); ~btDbvtBroadphase(); - void collide(btDispatcher* dispatcher); - void optimize(); - + void collide(btDispatcher* dispatcher); + void optimize(); + /* btBroadphaseInterface Implementation */ - btBroadphaseProxy* createProxy(const btVector3& aabbMin,const btVector3& aabbMax,int shapeType,void* userPtr, int collisionFilterGroup, int collisionFilterMask,btDispatcher* dispatcher); - virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); - virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* dispatcher); - virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0), const btVector3& aabbMax = btVector3(0,0,0)); - virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback); - - virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const; - virtual void calculateOverlappingPairs(btDispatcher* dispatcher); - virtual btOverlappingPairCache* getOverlappingPairCache(); - virtual const btOverlappingPairCache* getOverlappingPairCache() const; - virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const; - virtual void printStats(); + btBroadphaseProxy* createProxy(const btVector3& aabbMin, const btVector3& aabbMax, int shapeType, void* userPtr, int collisionFilterGroup, int collisionFilterMask, btDispatcher* dispatcher); + virtual void destroyProxy(btBroadphaseProxy* proxy, btDispatcher* dispatcher); + virtual void setAabb(btBroadphaseProxy* proxy, const btVector3& aabbMin, const btVector3& aabbMax, btDispatcher* dispatcher); + virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin = btVector3(0, 0, 0), const btVector3& aabbMax = btVector3(0, 0, 0)); + virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback); + virtual void getAabb(btBroadphaseProxy* proxy, btVector3& aabbMin, btVector3& aabbMax) const; + virtual void calculateOverlappingPairs(btDispatcher* dispatcher); + virtual btOverlappingPairCache* getOverlappingPairCache(); + virtual const btOverlappingPairCache* getOverlappingPairCache() const; + virtual void getBroadphaseAabb(btVector3& aabbMin, btVector3& aabbMax) const; + virtual void printStats(); ///reset broadphase internal structures, to ensure determinism/reproducability virtual void resetPool(btDispatcher* dispatcher); - void performDeferredRemoval(btDispatcher* dispatcher); - - void setVelocityPrediction(btScalar prediction) + void performDeferredRemoval(btDispatcher* dispatcher); + + void setVelocityPrediction(btScalar prediction) { m_prediction = prediction; } @@ -134,15 +134,13 @@ struct btDbvtBroadphase : btBroadphaseInterface return m_prediction; } - ///this setAabbForceUpdate is similar to setAabb but always forces the aabb update. + ///this setAabbForceUpdate is similar to setAabb but always forces the aabb update. ///it is not part of the btBroadphaseInterface but specific to btDbvtBroadphase. ///it bypasses certain optimizations that prevent aabb updates (when the aabb shrinks), see ///http://code.google.com/p/bullet/issues/detail?id=223 - void setAabbForceUpdate( btBroadphaseProxy* absproxy,const btVector3& aabbMin,const btVector3& aabbMax,btDispatcher* /*dispatcher*/); - - static void benchmark(btBroadphaseInterface*); - + void setAabbForceUpdate(btBroadphaseProxy* absproxy, const btVector3& aabbMin, const btVector3& aabbMax, btDispatcher* /*dispatcher*/); + static void benchmark(btBroadphaseInterface*); }; #endif diff --git a/src/BulletCollision/BroadphaseCollision/btDispatcher.cpp b/src/BulletCollision/BroadphaseCollision/btDispatcher.cpp index 20768225b..d76d408aa 100644 --- a/src/BulletCollision/BroadphaseCollision/btDispatcher.cpp +++ b/src/BulletCollision/BroadphaseCollision/btDispatcher.cpp @@ -17,6 +17,4 @@ subject to the following restrictions: btDispatcher::~btDispatcher() { - } - diff --git a/src/BulletCollision/BroadphaseCollision/btDispatcher.h b/src/BulletCollision/BroadphaseCollision/btDispatcher.h index a0e4c1892..b09b7d4d4 100644 --- a/src/BulletCollision/BroadphaseCollision/btDispatcher.h +++ b/src/BulletCollision/BroadphaseCollision/btDispatcher.h @@ -20,7 +20,7 @@ subject to the following restrictions: class btCollisionAlgorithm; struct btBroadphaseProxy; class btRigidBody; -class btCollisionObject; +class btCollisionObject; class btOverlappingPairCache; struct btCollisionObjectWrapper; @@ -35,35 +35,34 @@ struct btDispatcherInfo DISPATCH_CONTINUOUS }; btDispatcherInfo() - :m_timeStep(btScalar(0.)), - m_stepCount(0), - m_dispatchFunc(DISPATCH_DISCRETE), - m_timeOfImpact(btScalar(1.)), - m_useContinuous(true), - m_debugDraw(0), - m_enableSatConvex(false), - m_enableSPU(true), - m_useEpa(true), - m_allowedCcdPenetration(btScalar(0.04)), - m_useConvexConservativeDistanceUtil(false), - m_convexConservativeDistanceThreshold(0.0f), - m_deterministicOverlappingPairs(false) + : m_timeStep(btScalar(0.)), + m_stepCount(0), + m_dispatchFunc(DISPATCH_DISCRETE), + m_timeOfImpact(btScalar(1.)), + m_useContinuous(true), + m_debugDraw(0), + m_enableSatConvex(false), + m_enableSPU(true), + m_useEpa(true), + m_allowedCcdPenetration(btScalar(0.04)), + m_useConvexConservativeDistanceUtil(false), + m_convexConservativeDistanceThreshold(0.0f), + m_deterministicOverlappingPairs(false) { - } - btScalar m_timeStep; - int m_stepCount; - int m_dispatchFunc; - mutable btScalar m_timeOfImpact; - bool m_useContinuous; - class btIDebugDraw* m_debugDraw; - bool m_enableSatConvex; - bool m_enableSPU; - bool m_useEpa; - btScalar m_allowedCcdPenetration; - bool m_useConvexConservativeDistanceUtil; - btScalar m_convexConservativeDistanceThreshold; - bool m_deterministicOverlappingPairs; + btScalar m_timeStep; + int m_stepCount; + int m_dispatchFunc; + mutable btScalar m_timeOfImpact; + bool m_useContinuous; + class btIDebugDraw* m_debugDraw; + bool m_enableSatConvex; + bool m_enableSPU; + bool m_useEpa; + btScalar m_allowedCcdPenetration; + bool m_useConvexConservativeDistanceUtil; + btScalar m_convexConservativeDistanceThreshold; + bool m_deterministicOverlappingPairs; }; enum ebtDispatcherQueryType @@ -76,40 +75,36 @@ enum ebtDispatcherQueryType ///For example for pairwise collision detection, calculating contact points stored in btPersistentManifold or user callbacks (game logic). class btDispatcher { - - public: - virtual ~btDispatcher() ; + virtual ~btDispatcher(); - virtual btCollisionAlgorithm* findAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btPersistentManifold* sharedManifold, ebtDispatcherQueryType queryType) = 0; + virtual btCollisionAlgorithm* findAlgorithm(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, btPersistentManifold* sharedManifold, ebtDispatcherQueryType queryType) = 0; - virtual btPersistentManifold* getNewManifold(const btCollisionObject* b0,const btCollisionObject* b1)=0; + virtual btPersistentManifold* getNewManifold(const btCollisionObject* b0, const btCollisionObject* b1) = 0; - virtual void releaseManifold(btPersistentManifold* manifold)=0; + virtual void releaseManifold(btPersistentManifold* manifold) = 0; - virtual void clearManifold(btPersistentManifold* manifold)=0; + virtual void clearManifold(btPersistentManifold* manifold) = 0; - virtual bool needsCollision(const btCollisionObject* body0,const btCollisionObject* body1) = 0; + virtual bool needsCollision(const btCollisionObject* body0, const btCollisionObject* body1) = 0; - virtual bool needsResponse(const btCollisionObject* body0,const btCollisionObject* body1)=0; + virtual bool needsResponse(const btCollisionObject* body0, const btCollisionObject* body1) = 0; - virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) =0; + virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache, const btDispatcherInfo& dispatchInfo, btDispatcher* dispatcher) = 0; virtual int getNumManifolds() const = 0; virtual btPersistentManifold* getManifoldByIndexInternal(int index) = 0; - virtual btPersistentManifold** getInternalManifoldPointer() = 0; + virtual btPersistentManifold** getInternalManifoldPointer() = 0; - virtual btPoolAllocator* getInternalManifoldPool() = 0; + virtual btPoolAllocator* getInternalManifoldPool() = 0; - virtual const btPoolAllocator* getInternalManifoldPool() const = 0; + virtual const btPoolAllocator* getInternalManifoldPool() const = 0; - virtual void* allocateCollisionAlgorithm(int size) = 0; - - virtual void freeCollisionAlgorithm(void* ptr) = 0; + virtual void* allocateCollisionAlgorithm(int size) = 0; + virtual void freeCollisionAlgorithm(void* ptr) = 0; }; - -#endif //BT_DISPATCHER_H +#endif //BT_DISPATCHER_H diff --git a/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp b/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp index 9e3337c5f..8ce1087c9 100644 --- a/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp +++ b/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.cpp @@ -13,8 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "btOverlappingPairCache.h" #include "btDispatcher.h" @@ -23,121 +21,95 @@ subject to the following restrictions: #include - - - - -btHashedOverlappingPairCache::btHashedOverlappingPairCache(): - m_overlapFilterCallback(0), - m_ghostPairCallback(0) +btHashedOverlappingPairCache::btHashedOverlappingPairCache() : m_overlapFilterCallback(0), + m_ghostPairCallback(0) { - int initialAllocatedSize= 2; + int initialAllocatedSize = 2; m_overlappingPairArray.reserve(initialAllocatedSize); growTables(); } - - - btHashedOverlappingPairCache::~btHashedOverlappingPairCache() { } - - -void btHashedOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher) +void btHashedOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair, btDispatcher* dispatcher) { if (pair.m_algorithm && dispatcher) { { pair.m_algorithm->~btCollisionAlgorithm(); dispatcher->freeCollisionAlgorithm(pair.m_algorithm); - pair.m_algorithm=0; + pair.m_algorithm = 0; } } } - - - -void btHashedOverlappingPairCache::cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher) +void btHashedOverlappingPairCache::cleanProxyFromPairs(btBroadphaseProxy* proxy, btDispatcher* dispatcher) { - - class CleanPairCallback : public btOverlapCallback + class CleanPairCallback : public btOverlapCallback { btBroadphaseProxy* m_cleanProxy; - btOverlappingPairCache* m_pairCache; + btOverlappingPairCache* m_pairCache; btDispatcher* m_dispatcher; public: - CleanPairCallback(btBroadphaseProxy* cleanProxy,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) - :m_cleanProxy(cleanProxy), - m_pairCache(pairCache), - m_dispatcher(dispatcher) + CleanPairCallback(btBroadphaseProxy* cleanProxy, btOverlappingPairCache* pairCache, btDispatcher* dispatcher) + : m_cleanProxy(cleanProxy), + m_pairCache(pairCache), + m_dispatcher(dispatcher) { } - virtual bool processOverlap(btBroadphasePair& pair) + virtual bool processOverlap(btBroadphasePair& pair) { if ((pair.m_pProxy0 == m_cleanProxy) || (pair.m_pProxy1 == m_cleanProxy)) { - m_pairCache->cleanOverlappingPair(pair,m_dispatcher); + m_pairCache->cleanOverlappingPair(pair, m_dispatcher); } return false; } - }; - CleanPairCallback cleanPairs(proxy,this,dispatcher); - - processAllOverlappingPairs(&cleanPairs,dispatcher); + CleanPairCallback cleanPairs(proxy, this, dispatcher); + processAllOverlappingPairs(&cleanPairs, dispatcher); } - - - -void btHashedOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher) +void btHashedOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy, btDispatcher* dispatcher) { - - class RemovePairCallback : public btOverlapCallback + class RemovePairCallback : public btOverlapCallback { btBroadphaseProxy* m_obsoleteProxy; public: RemovePairCallback(btBroadphaseProxy* obsoleteProxy) - :m_obsoleteProxy(obsoleteProxy) + : m_obsoleteProxy(obsoleteProxy) { } - virtual bool processOverlap(btBroadphasePair& pair) + virtual bool processOverlap(btBroadphasePair& pair) { return ((pair.m_pProxy0 == m_obsoleteProxy) || - (pair.m_pProxy1 == m_obsoleteProxy)); + (pair.m_pProxy1 == m_obsoleteProxy)); } - }; - RemovePairCallback removeCallback(proxy); - processAllOverlappingPairs(&removeCallback,dispatcher); + processAllOverlappingPairs(&removeCallback, dispatcher); } - - - - btBroadphasePair* btHashedOverlappingPairCache::findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) { - if(proxy0->m_uniqueId>proxy1->m_uniqueId) - btSwap(proxy0,proxy1); + if (proxy0->m_uniqueId > proxy1->m_uniqueId) + btSwap(proxy0, proxy1); int proxyId1 = proxy0->getUid(); int proxyId2 = proxy1->getUid(); /*if (proxyId1 > proxyId2) btSwap(proxyId1, proxyId2);*/ - int hash = static_cast(getHash(static_cast(proxyId1), static_cast(proxyId2)) & (m_overlappingPairArray.capacity()-1)); + int hash = static_cast(getHash(static_cast(proxyId1), static_cast(proxyId2)) & (m_overlappingPairArray.capacity() - 1)); if (hash >= m_hashTable.size()) { @@ -162,9 +134,8 @@ btBroadphasePair* btHashedOverlappingPairCache::findPair(btBroadphaseProxy* prox //#include -void btHashedOverlappingPairCache::growTables() +void btHashedOverlappingPairCache::growTables() { - int newCapacity = m_overlappingPairArray.capacity(); if (m_hashTable.size() < newCapacity) @@ -175,10 +146,9 @@ void btHashedOverlappingPairCache::growTables() m_hashTable.resize(newCapacity); m_next.resize(newCapacity); - int i; - for (i= 0; i < newCapacity; ++i) + for (i = 0; i < newCapacity; ++i) { m_hashTable[i] = BT_NULL_PAIR; } @@ -187,35 +157,31 @@ void btHashedOverlappingPairCache::growTables() m_next[i] = BT_NULL_PAIR; } - for(i=0;igetUid(); int proxyId2 = pair.m_pProxy1->getUid(); /*if (proxyId1 > proxyId2) btSwap(proxyId1, proxyId2);*/ - int hashValue = static_cast(getHash(static_cast(proxyId1),static_cast(proxyId2)) & (m_overlappingPairArray.capacity()-1)); // New hash value with new mask + int hashValue = static_cast(getHash(static_cast(proxyId1), static_cast(proxyId2)) & (m_overlappingPairArray.capacity() - 1)); // New hash value with new mask m_next[i] = m_hashTable[hashValue]; m_hashTable[hashValue] = i; } - - } } btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) { - if(proxy0->m_uniqueId>proxy1->m_uniqueId) - btSwap(proxy0,proxy1); + if (proxy0->m_uniqueId > proxy1->m_uniqueId) + btSwap(proxy0, proxy1); int proxyId1 = proxy0->getUid(); int proxyId2 = proxy1->getUid(); /*if (proxyId1 > proxyId2) btSwap(proxyId1, proxyId2);*/ - int hash = static_cast(getHash(static_cast(proxyId1),static_cast(proxyId2)) & (m_overlappingPairArray.capacity()-1)); // New hash value with new mask - + int hash = static_cast(getHash(static_cast(proxyId1), static_cast(proxyId2)) & (m_overlappingPairArray.capacity() - 1)); // New hash value with new mask btBroadphasePair* pair = internalFindPair(proxy0, proxy1, hash); if (pair != NULL) @@ -237,7 +203,7 @@ btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProx //this is where we add an actual pair, so also call the 'ghost' if (m_ghostPairCallback) - m_ghostPairCallback->addOverlappingPair(proxy0,proxy1); + m_ghostPairCallback->addOverlappingPair(proxy0, proxy1); int newCapacity = m_overlappingPairArray.capacity(); @@ -245,15 +211,14 @@ btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProx { growTables(); //hash with new capacity - hash = static_cast(getHash(static_cast(proxyId1),static_cast(proxyId2)) & (m_overlappingPairArray.capacity()-1)); + hash = static_cast(getHash(static_cast(proxyId1), static_cast(proxyId2)) & (m_overlappingPairArray.capacity() - 1)); } - - pair = new (mem) btBroadphasePair(*proxy0,*proxy1); -// pair->m_pProxy0 = proxy0; -// pair->m_pProxy1 = proxy1; + + pair = new (mem) btBroadphasePair(*proxy0, *proxy1); + // pair->m_pProxy0 = proxy0; + // pair->m_pProxy1 = proxy1; pair->m_algorithm = 0; pair->m_internalTmpValue = 0; - m_next[count] = m_hashTable[hash]; m_hashTable[hash] = count; @@ -261,19 +226,17 @@ btBroadphasePair* btHashedOverlappingPairCache::internalAddPair(btBroadphaseProx return pair; } - - -void* btHashedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1,btDispatcher* dispatcher) +void* btHashedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1, btDispatcher* dispatcher) { - if(proxy0->m_uniqueId>proxy1->m_uniqueId) - btSwap(proxy0,proxy1); + if (proxy0->m_uniqueId > proxy1->m_uniqueId) + btSwap(proxy0, proxy1); int proxyId1 = proxy0->getUid(); int proxyId2 = proxy1->getUid(); /*if (proxyId1 > proxyId2) btSwap(proxyId1, proxyId2);*/ - int hash = static_cast(getHash(static_cast(proxyId1),static_cast(proxyId2)) & (m_overlappingPairArray.capacity()-1)); + int hash = static_cast(getHash(static_cast(proxyId1), static_cast(proxyId2)) & (m_overlappingPairArray.capacity() - 1)); btBroadphasePair* pair = internalFindPair(proxy0, proxy1, hash); if (pair == NULL) @@ -281,7 +244,7 @@ void* btHashedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* pro return 0; } - cleanOverlappingPair(*pair,dispatcher); + cleanOverlappingPair(*pair, dispatcher); void* userData = pair->m_internalInfo1; @@ -319,7 +282,7 @@ void* btHashedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* pro int lastPairIndex = m_overlappingPairArray.size() - 1; if (m_ghostPairCallback) - m_ghostPairCallback->removeOverlappingPair(proxy0, proxy1,dispatcher); + m_ghostPairCallback->removeOverlappingPair(proxy0, proxy1, dispatcher); // If the removed pair is the last pair, we are done. if (lastPairIndex == pairIndex) @@ -330,8 +293,8 @@ void* btHashedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* pro // Remove the last pair from the hash table. const btBroadphasePair* last = &m_overlappingPairArray[lastPairIndex]; - /* missing swap here too, Nat. */ - int lastHash = static_cast(getHash(static_cast(last->m_pProxy0->getUid()), static_cast(last->m_pProxy1->getUid())) & (m_overlappingPairArray.capacity()-1)); + /* missing swap here too, Nat. */ + int lastHash = static_cast(getHash(static_cast(last->m_pProxy0->getUid()), static_cast(last->m_pProxy1->getUid())) & (m_overlappingPairArray.capacity() - 1)); index = m_hashTable[lastHash]; btAssert(index != BT_NULL_PAIR); @@ -366,20 +329,20 @@ void* btHashedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* pro } //#include #include "LinearMath/btQuickprof.h" -void btHashedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback,btDispatcher* dispatcher) +void btHashedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback, btDispatcher* dispatcher) { BT_PROFILE("btHashedOverlappingPairCache::processAllOverlappingPairs"); int i; -// printf("m_overlappingPairArray.size()=%d\n",m_overlappingPairArray.size()); - for (i=0;iprocessOverlap(*pair)) { - removeOverlappingPair(pair->m_pProxy0,pair->m_pProxy1,dispatcher); - } else + removeOverlappingPair(pair->m_pProxy0, pair->m_pProxy1, dispatcher); + } + else { i++; } @@ -388,83 +351,83 @@ void btHashedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* struct MyPairIndex { - int m_orgIndex; - int m_uidA0; - int m_uidA1; + int m_orgIndex; + int m_uidA0; + int m_uidA1; }; class MyPairIndeSortPredicate { public: - - bool operator() ( const MyPairIndex& a, const MyPairIndex& b ) const - { - const int uidA0 = a.m_uidA0; - const int uidB0 = b.m_uidA0; - const int uidA1 = a.m_uidA1; - const int uidB1 = b.m_uidA1; - return uidA0 > uidB0 || (uidA0 == uidB0 && uidA1 > uidB1); - } + bool operator()(const MyPairIndex& a, const MyPairIndex& b) const + { + const int uidA0 = a.m_uidA0; + const int uidB0 = b.m_uidA0; + const int uidA1 = a.m_uidA1; + const int uidB1 = b.m_uidA1; + return uidA0 > uidB0 || (uidA0 == uidB0 && uidA1 > uidB1); + } }; -void btHashedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback,btDispatcher* dispatcher, const struct btDispatcherInfo& dispatchInfo) +void btHashedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback, btDispatcher* dispatcher, const struct btDispatcherInfo& dispatchInfo) { - if (dispatchInfo.m_deterministicOverlappingPairs) - { - btBroadphasePairArray& pa = getOverlappingPairArray(); - btAlignedObjectArray indices; - { - BT_PROFILE("sortOverlappingPairs"); - indices.resize(pa.size()); - for (int i=0;im_uniqueId : -1; - const int uidA1 = p.m_pProxy1 ? p.m_pProxy1->m_uniqueId : -1; - - indices[i].m_uidA0 = uidA0; - indices[i].m_uidA1 = uidA1; - indices[i].m_orgIndex = i; - } - indices.quickSort(MyPairIndeSortPredicate()); - } - { - BT_PROFILE("btHashedOverlappingPairCache::processAllOverlappingPairs"); - int i; - for (i=0;iprocessOverlap(*pair)) - { - removeOverlappingPair(pair->m_pProxy0,pair->m_pProxy1,dispatcher); - } else - { - i++; - } - } - } - } else - { - processAllOverlappingPairs(callback, dispatcher); - } + if (dispatchInfo.m_deterministicOverlappingPairs) + { + btBroadphasePairArray& pa = getOverlappingPairArray(); + btAlignedObjectArray indices; + { + BT_PROFILE("sortOverlappingPairs"); + indices.resize(pa.size()); + for (int i = 0; i < indices.size(); i++) + { + const btBroadphasePair& p = pa[i]; + const int uidA0 = p.m_pProxy0 ? p.m_pProxy0->m_uniqueId : -1; + const int uidA1 = p.m_pProxy1 ? p.m_pProxy1->m_uniqueId : -1; + + indices[i].m_uidA0 = uidA0; + indices[i].m_uidA1 = uidA1; + indices[i].m_orgIndex = i; + } + indices.quickSort(MyPairIndeSortPredicate()); + } + { + BT_PROFILE("btHashedOverlappingPairCache::processAllOverlappingPairs"); + int i; + for (i = 0; i < indices.size();) + { + btBroadphasePair* pair = &pa[indices[i].m_orgIndex]; + if (callback->processOverlap(*pair)) + { + removeOverlappingPair(pair->m_pProxy0, pair->m_pProxy1, dispatcher); + } + else + { + i++; + } + } + } + } + else + { + processAllOverlappingPairs(callback, dispatcher); + } } - -void btHashedOverlappingPairCache::sortOverlappingPairs(btDispatcher* dispatcher) +void btHashedOverlappingPairCache::sortOverlappingPairs(btDispatcher* dispatcher) { ///need to keep hashmap in sync with pair address, so rebuild all btBroadphasePairArray tmpPairs; int i; - for (i=0;iremoveOverlappingPair(proxy0, proxy1,dispatcher); - - m_overlappingPairArray.swap(findIndex,m_overlappingPairArray.capacity()-1); + m_ghostPairCallback->removeOverlappingPair(proxy0, proxy1, dispatcher); + + m_overlappingPairArray.swap(findIndex, m_overlappingPairArray.capacity() - 1); m_overlappingPairArray.pop_back(); return userData; } @@ -505,95 +465,73 @@ void* btSortedOverlappingPairCache::removeOverlappingPair(btBroadphaseProxy* pro return 0; } - - - - - - - -btBroadphasePair* btSortedOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) +btBroadphasePair* btSortedOverlappingPairCache::addOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) { //don't add overlap with own btAssert(proxy0 != proxy1); - if (!needsBroadphaseCollision(proxy0,proxy1)) + if (!needsBroadphaseCollision(proxy0, proxy1)) return 0; - - void* mem = &m_overlappingPairArray.expandNonInitializing(); - btBroadphasePair* pair = new (mem) btBroadphasePair(*proxy0,*proxy1); - if (m_ghostPairCallback) + void* mem = &m_overlappingPairArray.expandNonInitializing(); + btBroadphasePair* pair = new (mem) btBroadphasePair(*proxy0, *proxy1); + + if (m_ghostPairCallback) m_ghostPairCallback->addOverlappingPair(proxy0, proxy1); return pair; - } ///this findPair becomes really slow. Either sort the list to speedup the query, or ///use a different solution. It is mainly used for Removing overlapping pairs. Removal could be delayed. ///we could keep a linked list in each proxy, and store pair in one of the proxies (with lowest memory address) ///Also we can use a 2D bitmap, which can be useful for a future GPU implementation - btBroadphasePair* btSortedOverlappingPairCache::findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) +btBroadphasePair* btSortedOverlappingPairCache::findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) { - if (!needsBroadphaseCollision(proxy0,proxy1)) + if (!needsBroadphaseCollision(proxy0, proxy1)) return 0; - btBroadphasePair tmpPair(*proxy0,*proxy1); + btBroadphasePair tmpPair(*proxy0, *proxy1); int findIndex = m_overlappingPairArray.findLinearSearch(tmpPair); if (findIndex < m_overlappingPairArray.size()) { //btAssert(it != m_overlappingPairSet.end()); - btBroadphasePair* pair = &m_overlappingPairArray[findIndex]; + btBroadphasePair* pair = &m_overlappingPairArray[findIndex]; return pair; } return 0; } - - - - - - - - - //#include -void btSortedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback,btDispatcher* dispatcher) +void btSortedOverlappingPairCache::processAllOverlappingPairs(btOverlapCallback* callback, btDispatcher* dispatcher) { - int i; - for (i=0;iprocessOverlap(*pair)) { - cleanOverlappingPair(*pair,dispatcher); + cleanOverlappingPair(*pair, dispatcher); pair->m_pProxy0 = 0; pair->m_pProxy1 = 0; - m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); + m_overlappingPairArray.swap(i, m_overlappingPairArray.size() - 1); m_overlappingPairArray.pop_back(); - } else + } + else { i++; } } } - - - -btSortedOverlappingPairCache::btSortedOverlappingPairCache(): - m_blockedForChanges(false), - m_hasDeferredRemoval(true), - m_overlapFilterCallback(0), - m_ghostPairCallback(0) +btSortedOverlappingPairCache::btSortedOverlappingPairCache() : m_blockedForChanges(false), + m_hasDeferredRemoval(true), + m_overlapFilterCallback(0), + m_ghostPairCallback(0) { - int initialAllocatedSize= 2; + int initialAllocatedSize = 2; m_overlappingPairArray.reserve(initialAllocatedSize); } @@ -601,81 +539,73 @@ btSortedOverlappingPairCache::~btSortedOverlappingPairCache() { } -void btSortedOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher) +void btSortedOverlappingPairCache::cleanOverlappingPair(btBroadphasePair& pair, btDispatcher* dispatcher) { if (pair.m_algorithm) { { pair.m_algorithm->~btCollisionAlgorithm(); dispatcher->freeCollisionAlgorithm(pair.m_algorithm); - pair.m_algorithm=0; + pair.m_algorithm = 0; } } } - -void btSortedOverlappingPairCache::cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher) +void btSortedOverlappingPairCache::cleanProxyFromPairs(btBroadphaseProxy* proxy, btDispatcher* dispatcher) { - - class CleanPairCallback : public btOverlapCallback + class CleanPairCallback : public btOverlapCallback { btBroadphaseProxy* m_cleanProxy; - btOverlappingPairCache* m_pairCache; + btOverlappingPairCache* m_pairCache; btDispatcher* m_dispatcher; public: - CleanPairCallback(btBroadphaseProxy* cleanProxy,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) - :m_cleanProxy(cleanProxy), - m_pairCache(pairCache), - m_dispatcher(dispatcher) + CleanPairCallback(btBroadphaseProxy* cleanProxy, btOverlappingPairCache* pairCache, btDispatcher* dispatcher) + : m_cleanProxy(cleanProxy), + m_pairCache(pairCache), + m_dispatcher(dispatcher) { } - virtual bool processOverlap(btBroadphasePair& pair) + virtual bool processOverlap(btBroadphasePair& pair) { if ((pair.m_pProxy0 == m_cleanProxy) || (pair.m_pProxy1 == m_cleanProxy)) { - m_pairCache->cleanOverlappingPair(pair,m_dispatcher); + m_pairCache->cleanOverlappingPair(pair, m_dispatcher); } return false; } - }; - CleanPairCallback cleanPairs(proxy,this,dispatcher); - - processAllOverlappingPairs(&cleanPairs,dispatcher); + CleanPairCallback cleanPairs(proxy, this, dispatcher); + processAllOverlappingPairs(&cleanPairs, dispatcher); } - -void btSortedOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher) +void btSortedOverlappingPairCache::removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy, btDispatcher* dispatcher) { - - class RemovePairCallback : public btOverlapCallback + class RemovePairCallback : public btOverlapCallback { btBroadphaseProxy* m_obsoleteProxy; public: RemovePairCallback(btBroadphaseProxy* obsoleteProxy) - :m_obsoleteProxy(obsoleteProxy) + : m_obsoleteProxy(obsoleteProxy) { } - virtual bool processOverlap(btBroadphasePair& pair) + virtual bool processOverlap(btBroadphasePair& pair) { return ((pair.m_pProxy0 == m_obsoleteProxy) || - (pair.m_pProxy1 == m_obsoleteProxy)); + (pair.m_pProxy1 == m_obsoleteProxy)); } - }; RemovePairCallback removeCallback(proxy); - processAllOverlappingPairs(&removeCallback,dispatcher); + processAllOverlappingPairs(&removeCallback, dispatcher); } -void btSortedOverlappingPairCache::sortOverlappingPairs(btDispatcher* dispatcher) +void btSortedOverlappingPairCache::sortOverlappingPairs(btDispatcher* dispatcher) { //should already be sorted } - diff --git a/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h b/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h index 7a38d34f0..a85782bc8 100644 --- a/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h +++ b/src/BulletCollision/BroadphaseCollision/btOverlappingPairCache.h @@ -16,7 +16,6 @@ subject to the following restrictions: #ifndef BT_OVERLAPPING_PAIR_CACHE_H #define BT_OVERLAPPING_PAIR_CACHE_H - #include "btBroadphaseInterface.h" #include "btBroadphaseProxy.h" #include "btOverlappingPairCallback.h" @@ -24,177 +23,163 @@ subject to the following restrictions: #include "LinearMath/btAlignedObjectArray.h" class btDispatcher; -typedef btAlignedObjectArray btBroadphasePairArray; +typedef btAlignedObjectArray btBroadphasePairArray; -struct btOverlapCallback +struct btOverlapCallback { virtual ~btOverlapCallback() - {} + { + } //return true for deletion of the pair - virtual bool processOverlap(btBroadphasePair& pair) = 0; - + virtual bool processOverlap(btBroadphasePair& pair) = 0; }; struct btOverlapFilterCallback { virtual ~btOverlapFilterCallback() - {} + { + } // return true when pairs need collision - virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const = 0; + virtual bool needBroadphaseCollision(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) const = 0; }; - - - - - - -const int BT_NULL_PAIR=0xffffffff; +const int BT_NULL_PAIR = 0xffffffff; ///The btOverlappingPairCache provides an interface for overlapping pair management (add, remove, storage), used by the btBroadphaseInterface broadphases. ///The btHashedOverlappingPairCache and btSortedOverlappingPairCache classes are two implementations. class btOverlappingPairCache : public btOverlappingPairCallback { public: - virtual ~btOverlappingPairCache() {} // this is needed so we can get to the derived class destructor + virtual ~btOverlappingPairCache() {} // this is needed so we can get to the derived class destructor - virtual btBroadphasePair* getOverlappingPairArrayPtr() = 0; - - virtual const btBroadphasePair* getOverlappingPairArrayPtr() const = 0; + virtual btBroadphasePair* getOverlappingPairArrayPtr() = 0; - virtual btBroadphasePairArray& getOverlappingPairArray() = 0; + virtual const btBroadphasePair* getOverlappingPairArrayPtr() const = 0; - virtual void cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher) = 0; + virtual btBroadphasePairArray& getOverlappingPairArray() = 0; + + virtual void cleanOverlappingPair(btBroadphasePair& pair, btDispatcher* dispatcher) = 0; virtual int getNumOverlappingPairs() const = 0; - virtual void cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher) = 0; + virtual void cleanProxyFromPairs(btBroadphaseProxy* proxy, btDispatcher* dispatcher) = 0; - virtual void setOverlapFilterCallback(btOverlapFilterCallback* callback) = 0; + virtual void setOverlapFilterCallback(btOverlapFilterCallback* callback) = 0; - virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher) = 0; + virtual void processAllOverlappingPairs(btOverlapCallback*, btDispatcher* dispatcher) = 0; - virtual void processAllOverlappingPairs(btOverlapCallback* callback,btDispatcher* dispatcher, const struct btDispatcherInfo& dispatchInfo) + virtual void processAllOverlappingPairs(btOverlapCallback* callback, btDispatcher* dispatcher, const struct btDispatcherInfo& dispatchInfo) { processAllOverlappingPairs(callback, dispatcher); } virtual btBroadphasePair* findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) = 0; - virtual bool hasDeferredRemoval() = 0; - - virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback)=0; - - virtual void sortOverlappingPairs(btDispatcher* dispatcher) = 0; + virtual bool hasDeferredRemoval() = 0; + virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback) = 0; + virtual void sortOverlappingPairs(btDispatcher* dispatcher) = 0; }; /// Hash-space based Pair Cache, thanks to Erin Catto, Box2D, http://www.box2d.org, and Pierre Terdiman, Codercorner, http://codercorner.com -ATTRIBUTE_ALIGNED16(class) btHashedOverlappingPairCache : public btOverlappingPairCache +ATTRIBUTE_ALIGNED16(class) +btHashedOverlappingPairCache : public btOverlappingPairCache { - btBroadphasePairArray m_overlappingPairArray; + btBroadphasePairArray m_overlappingPairArray; btOverlapFilterCallback* m_overlapFilterCallback; protected: - - btAlignedObjectArray m_hashTable; - btAlignedObjectArray m_next; - btOverlappingPairCallback* m_ghostPairCallback; - + btAlignedObjectArray m_hashTable; + btAlignedObjectArray m_next; + btOverlappingPairCallback* m_ghostPairCallback; public: BT_DECLARE_ALIGNED_ALLOCATOR(); - + btHashedOverlappingPairCache(); virtual ~btHashedOverlappingPairCache(); - - void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); + void removeOverlappingPairsContainingProxy(btBroadphaseProxy * proxy, btDispatcher * dispatcher); - virtual void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher); - - SIMD_FORCE_INLINE bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const + virtual void* removeOverlappingPair(btBroadphaseProxy * proxy0, btBroadphaseProxy * proxy1, btDispatcher * dispatcher); + + SIMD_FORCE_INLINE bool needsBroadphaseCollision(btBroadphaseProxy * proxy0, btBroadphaseProxy * proxy1) const { if (m_overlapFilterCallback) - return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1); + return m_overlapFilterCallback->needBroadphaseCollision(proxy0, proxy1); bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); - + return collides; } // Add a pair and return the new pair. If the pair already exists, // no new pair is created and the old one is returned. - virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) + virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy * proxy0, btBroadphaseProxy * proxy1) { - if (!needsBroadphaseCollision(proxy0,proxy1)) + if (!needsBroadphaseCollision(proxy0, proxy1)) return 0; - return internalAddPair(proxy0,proxy1); + return internalAddPair(proxy0, proxy1); } - + void cleanProxyFromPairs(btBroadphaseProxy * proxy, btDispatcher * dispatcher); - void cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher); + virtual void processAllOverlappingPairs(btOverlapCallback*, btDispatcher * dispatcher); - - virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher); + virtual void processAllOverlappingPairs(btOverlapCallback * callback, btDispatcher * dispatcher, const struct btDispatcherInfo& dispatchInfo); - virtual void processAllOverlappingPairs(btOverlapCallback* callback,btDispatcher* dispatcher, const struct btDispatcherInfo& dispatchInfo); - - virtual btBroadphasePair* getOverlappingPairArrayPtr() + virtual btBroadphasePair* getOverlappingPairArrayPtr() { return &m_overlappingPairArray[0]; } - const btBroadphasePair* getOverlappingPairArrayPtr() const + const btBroadphasePair* getOverlappingPairArrayPtr() const { return &m_overlappingPairArray[0]; } - btBroadphasePairArray& getOverlappingPairArray() + btBroadphasePairArray& getOverlappingPairArray() { return m_overlappingPairArray; } - const btBroadphasePairArray& getOverlappingPairArray() const + const btBroadphasePairArray& getOverlappingPairArray() const { return m_overlappingPairArray; } - void cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher); + void cleanOverlappingPair(btBroadphasePair & pair, btDispatcher * dispatcher); - - - btBroadphasePair* findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1); + btBroadphasePair* findPair(btBroadphaseProxy * proxy0, btBroadphaseProxy * proxy1); int GetCount() const { return m_overlappingPairArray.size(); } -// btBroadphasePair* GetPairs() { return m_pairs; } + // btBroadphasePair* GetPairs() { return m_pairs; } btOverlapFilterCallback* getOverlapFilterCallback() { return m_overlapFilterCallback; } - void setOverlapFilterCallback(btOverlapFilterCallback* callback) + void setOverlapFilterCallback(btOverlapFilterCallback * callback) { m_overlapFilterCallback = callback; } - int getNumOverlappingPairs() const + int getNumOverlappingPairs() const { return m_overlappingPairArray.size(); } -private: - - btBroadphasePair* internalAddPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); - void growTables(); +private: + btBroadphasePair* internalAddPair(btBroadphaseProxy * proxy0, btBroadphaseProxy * proxy1); + + void growTables(); SIMD_FORCE_INLINE bool equalsPair(const btBroadphasePair& pair, int proxyId1, int proxyId2) - { + { return pair.m_pProxy0->getUid() == proxyId1 && pair.m_pProxy1->getUid() == proxyId2; } @@ -214,40 +199,37 @@ private: } */ - SIMD_FORCE_INLINE unsigned int getHash(unsigned int proxyId1, unsigned int proxyId2) { unsigned int key = proxyId1 | (proxyId2 << 16); // Thomas Wang's hash key += ~(key << 15); - key ^= (key >> 10); - key += (key << 3); - key ^= (key >> 6); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); key += ~(key << 11); - key ^= (key >> 16); + key ^= (key >> 16); return key; } - - - SIMD_FORCE_INLINE btBroadphasePair* internalFindPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1, int hash) + SIMD_FORCE_INLINE btBroadphasePair* internalFindPair(btBroadphaseProxy * proxy0, btBroadphaseProxy * proxy1, int hash) { int proxyId1 = proxy0->getUid(); int proxyId2 = proxy1->getUid(); - #if 0 // wrong, 'equalsPair' use unsorted uids, copy-past devil striked again. Nat. +#if 0 // wrong, 'equalsPair' use unsorted uids, copy-past devil striked again. Nat. if (proxyId1 > proxyId2) btSwap(proxyId1, proxyId2); - #endif +#endif int index = m_hashTable[hash]; - - while( index != BT_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false) + + while (index != BT_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyId1, proxyId2) == false) { index = m_next[index]; } - if ( index == BT_NULL_PAIR ) + if (index == BT_NULL_PAIR) { return NULL; } @@ -257,155 +239,136 @@ private: return &m_overlappingPairArray[index]; } - virtual bool hasDeferredRemoval() + virtual bool hasDeferredRemoval() { return false; } - virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback) + virtual void setInternalGhostPairCallback(btOverlappingPairCallback * ghostPairCallback) { m_ghostPairCallback = ghostPairCallback; } - virtual void sortOverlappingPairs(btDispatcher* dispatcher); - - - + virtual void sortOverlappingPairs(btDispatcher * dispatcher); }; - - - ///btSortedOverlappingPairCache maintains the objects with overlapping AABB ///Typically managed by the Broadphase, Axis3Sweep or btSimpleBroadphase -class btSortedOverlappingPairCache : public btOverlappingPairCache +class btSortedOverlappingPairCache : public btOverlappingPairCache { - protected: - //avoid brute-force finding all the time - btBroadphasePairArray m_overlappingPairArray; +protected: + //avoid brute-force finding all the time + btBroadphasePairArray m_overlappingPairArray; - //during the dispatch, check that user doesn't destroy/create proxy - bool m_blockedForChanges; + //during the dispatch, check that user doesn't destroy/create proxy + bool m_blockedForChanges; - ///by default, do the removal during the pair traversal - bool m_hasDeferredRemoval; - - //if set, use the callback instead of the built in filter in needBroadphaseCollision - btOverlapFilterCallback* m_overlapFilterCallback; + ///by default, do the removal during the pair traversal + bool m_hasDeferredRemoval; - btOverlappingPairCallback* m_ghostPairCallback; + //if set, use the callback instead of the built in filter in needBroadphaseCollision + btOverlapFilterCallback* m_overlapFilterCallback; - public: - - btSortedOverlappingPairCache(); - virtual ~btSortedOverlappingPairCache(); + btOverlappingPairCallback* m_ghostPairCallback; - virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* dispatcher); +public: + btSortedOverlappingPairCache(); + virtual ~btSortedOverlappingPairCache(); - void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher); + virtual void processAllOverlappingPairs(btOverlapCallback*, btDispatcher* dispatcher); - void cleanOverlappingPair(btBroadphasePair& pair,btDispatcher* dispatcher); - - btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); + void* removeOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1, btDispatcher* dispatcher); - btBroadphasePair* findPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); - - - void cleanProxyFromPairs(btBroadphaseProxy* proxy,btDispatcher* dispatcher); + void cleanOverlappingPair(btBroadphasePair& pair, btDispatcher* dispatcher); - void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); + btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1); + btBroadphasePair* findPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1); - inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) const - { - if (m_overlapFilterCallback) - return m_overlapFilterCallback->needBroadphaseCollision(proxy0,proxy1); + void cleanProxyFromPairs(btBroadphaseProxy* proxy, btDispatcher* dispatcher); - bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; - collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); - - return collides; - } - - btBroadphasePairArray& getOverlappingPairArray() - { - return m_overlappingPairArray; - } + void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy, btDispatcher* dispatcher); - const btBroadphasePairArray& getOverlappingPairArray() const - { - return m_overlappingPairArray; - } + inline bool needsBroadphaseCollision(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) const + { + if (m_overlapFilterCallback) + return m_overlapFilterCallback->needBroadphaseCollision(proxy0, proxy1); - + bool collides = (proxy0->m_collisionFilterGroup & proxy1->m_collisionFilterMask) != 0; + collides = collides && (proxy1->m_collisionFilterGroup & proxy0->m_collisionFilterMask); + return collides; + } - btBroadphasePair* getOverlappingPairArrayPtr() - { - return &m_overlappingPairArray[0]; - } + btBroadphasePairArray& getOverlappingPairArray() + { + return m_overlappingPairArray; + } - const btBroadphasePair* getOverlappingPairArrayPtr() const - { - return &m_overlappingPairArray[0]; - } + const btBroadphasePairArray& getOverlappingPairArray() const + { + return m_overlappingPairArray; + } - int getNumOverlappingPairs() const - { - return m_overlappingPairArray.size(); - } - - btOverlapFilterCallback* getOverlapFilterCallback() - { - return m_overlapFilterCallback; - } + btBroadphasePair* getOverlappingPairArrayPtr() + { + return &m_overlappingPairArray[0]; + } - void setOverlapFilterCallback(btOverlapFilterCallback* callback) - { - m_overlapFilterCallback = callback; - } + const btBroadphasePair* getOverlappingPairArrayPtr() const + { + return &m_overlappingPairArray[0]; + } - virtual bool hasDeferredRemoval() - { - return m_hasDeferredRemoval; - } + int getNumOverlappingPairs() const + { + return m_overlappingPairArray.size(); + } - virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback) - { - m_ghostPairCallback = ghostPairCallback; - } + btOverlapFilterCallback* getOverlapFilterCallback() + { + return m_overlapFilterCallback; + } - virtual void sortOverlappingPairs(btDispatcher* dispatcher); - + void setOverlapFilterCallback(btOverlapFilterCallback* callback) + { + m_overlapFilterCallback = callback; + } + virtual bool hasDeferredRemoval() + { + return m_hasDeferredRemoval; + } + + virtual void setInternalGhostPairCallback(btOverlappingPairCallback* ghostPairCallback) + { + m_ghostPairCallback = ghostPairCallback; + } + + virtual void sortOverlappingPairs(btDispatcher* dispatcher); }; - - ///btNullPairCache skips add/removal of overlapping pairs. Userful for benchmarking and unit testing. class btNullPairCache : public btOverlappingPairCache { - - btBroadphasePairArray m_overlappingPairArray; + btBroadphasePairArray m_overlappingPairArray; public: - - virtual btBroadphasePair* getOverlappingPairArrayPtr() + virtual btBroadphasePair* getOverlappingPairArrayPtr() { return &m_overlappingPairArray[0]; } - const btBroadphasePair* getOverlappingPairArrayPtr() const + const btBroadphasePair* getOverlappingPairArrayPtr() const { return &m_overlappingPairArray[0]; } - btBroadphasePairArray& getOverlappingPairArray() + btBroadphasePairArray& getOverlappingPairArray() { return m_overlappingPairArray; } - - virtual void cleanOverlappingPair(btBroadphasePair& /*pair*/,btDispatcher* /*dispatcher*/) - { + virtual void cleanOverlappingPair(btBroadphasePair& /*pair*/, btDispatcher* /*dispatcher*/) + { } virtual int getNumOverlappingPairs() const @@ -413,16 +376,15 @@ public: return 0; } - virtual void cleanProxyFromPairs(btBroadphaseProxy* /*proxy*/,btDispatcher* /*dispatcher*/) - { - - } - - virtual void setOverlapFilterCallback(btOverlapFilterCallback* /*callback*/) + virtual void cleanProxyFromPairs(btBroadphaseProxy* /*proxy*/, btDispatcher* /*dispatcher*/) { } - virtual void processAllOverlappingPairs(btOverlapCallback*,btDispatcher* /*dispatcher*/) + virtual void setOverlapFilterCallback(btOverlapFilterCallback* /*callback*/) + { + } + + virtual void processAllOverlappingPairs(btOverlapCallback*, btDispatcher* /*dispatcher*/) { } @@ -431,39 +393,33 @@ public: return 0; } - virtual bool hasDeferredRemoval() + virtual bool hasDeferredRemoval() { return true; } - virtual void setInternalGhostPairCallback(btOverlappingPairCallback* /* ghostPairCallback */) + virtual void setInternalGhostPairCallback(btOverlappingPairCallback* /* ghostPairCallback */) { - } - virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/) + virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* /*proxy0*/, btBroadphaseProxy* /*proxy1*/) { return 0; } - virtual void* removeOverlappingPair(btBroadphaseProxy* /*proxy0*/,btBroadphaseProxy* /*proxy1*/,btDispatcher* /*dispatcher*/) + virtual void* removeOverlappingPair(btBroadphaseProxy* /*proxy0*/, btBroadphaseProxy* /*proxy1*/, btDispatcher* /*dispatcher*/) { return 0; } - virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* /*proxy0*/,btDispatcher* /*dispatcher*/) + virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* /*proxy0*/, btDispatcher* /*dispatcher*/) { } - - virtual void sortOverlappingPairs(btDispatcher* dispatcher) + + virtual void sortOverlappingPairs(btDispatcher* dispatcher) { - (void) dispatcher; + (void)dispatcher; } - - }; - -#endif //BT_OVERLAPPING_PAIR_CACHE_H - - +#endif //BT_OVERLAPPING_PAIR_CACHE_H diff --git a/src/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h b/src/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h index 3e069fa5e..d16c72542 100644 --- a/src/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h +++ b/src/BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h @@ -18,26 +18,24 @@ subject to the following restrictions: #define OVERLAPPING_PAIR_CALLBACK_H class btDispatcher; -struct btBroadphasePair; +struct btBroadphasePair; ///The btOverlappingPairCallback class is an additional optional broadphase user callback for adding/removing overlapping pairs, similar interface to btOverlappingPairCache. class btOverlappingPairCallback { protected: - btOverlappingPairCallback() {} - + btOverlappingPairCallback() {} + public: virtual ~btOverlappingPairCallback() { - } - - virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) = 0; - virtual void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher) = 0; + virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) = 0; - virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy0,btDispatcher* dispatcher) = 0; + virtual void* removeOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1, btDispatcher* dispatcher) = 0; + virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* proxy0, btDispatcher* dispatcher) = 0; }; -#endif //OVERLAPPING_PAIR_CALLBACK_H +#endif //OVERLAPPING_PAIR_CALLBACK_H diff --git a/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp b/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp index 875d89c53..b814fd84d 100644 --- a/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp +++ b/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.cpp @@ -21,43 +21,38 @@ subject to the following restrictions: #define RAYAABB2 -btQuantizedBvh::btQuantizedBvh() : - m_bulletVersion(BT_BULLET_VERSION), - m_useQuantization(false), - //m_traversalMode(TRAVERSAL_STACKLESS_CACHE_FRIENDLY) - m_traversalMode(TRAVERSAL_STACKLESS) - //m_traversalMode(TRAVERSAL_RECURSIVE) - ,m_subtreeHeaderCount(0) //PCK: add this line +btQuantizedBvh::btQuantizedBvh() : m_bulletVersion(BT_BULLET_VERSION), + m_useQuantization(false), + //m_traversalMode(TRAVERSAL_STACKLESS_CACHE_FRIENDLY) + m_traversalMode(TRAVERSAL_STACKLESS) + //m_traversalMode(TRAVERSAL_RECURSIVE) + , + m_subtreeHeaderCount(0) //PCK: add this line { - m_bvhAabbMin.setValue(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY); - m_bvhAabbMax.setValue(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY); + m_bvhAabbMin.setValue(-SIMD_INFINITY, -SIMD_INFINITY, -SIMD_INFINITY); + m_bvhAabbMax.setValue(SIMD_INFINITY, SIMD_INFINITY, SIMD_INFINITY); } - - - - void btQuantizedBvh::buildInternal() { ///assumes that caller filled in the m_quantizedLeafNodes m_useQuantization = true; int numLeafNodes = 0; - + if (m_useQuantization) { //now we have an array of leafnodes in m_leafNodes numLeafNodes = m_quantizedLeafNodes.size(); - m_quantizedContiguousNodes.resize(2*numLeafNodes); - + m_quantizedContiguousNodes.resize(2 * numLeafNodes); } m_curNodeIndex = 0; - buildTree(0,numLeafNodes); + buildTree(0, numLeafNodes); ///if the entire tree is small then subtree size, we need to create a header info for the tree - if(m_useQuantization && !m_SubtreeHeaders.size()) + if (m_useQuantization && !m_SubtreeHeaders.size()) { btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand(); subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[0]); @@ -73,29 +68,24 @@ void btQuantizedBvh::buildInternal() m_leafNodes.clear(); } - - ///just for debugging, to visualize the individual patches/subtrees #ifdef DEBUG_PATCH_COLORS -btVector3 color[4]= -{ - btVector3(1,0,0), - btVector3(0,1,0), - btVector3(0,0,1), - btVector3(0,1,1) -}; -#endif //DEBUG_PATCH_COLORS +btVector3 color[4] = + { + btVector3(1, 0, 0), + btVector3(0, 1, 0), + btVector3(0, 0, 1), + btVector3(0, 1, 1)}; +#endif //DEBUG_PATCH_COLORS - - -void btQuantizedBvh::setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin) +void btQuantizedBvh::setQuantizationValues(const btVector3& bvhAabbMin, const btVector3& bvhAabbMax, btScalar quantizationMargin) { //enlarge the AABB to avoid division by zero when initializing the quantization values - btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin); + btVector3 clampValue(quantizationMargin, quantizationMargin, quantizationMargin); m_bvhAabbMin = bvhAabbMin - clampValue; m_bvhAabbMax = bvhAabbMax + clampValue; btVector3 aabbSize = m_bvhAabbMax - m_bvhAabbMin; - m_bvhQuantization = btVector3(btScalar(65533.0),btScalar(65533.0),btScalar(65533.0)) / aabbSize; + m_bvhQuantization = btVector3(btScalar(65533.0), btScalar(65533.0), btScalar(65533.0)) / aabbSize; m_useQuantization = true; @@ -103,25 +93,22 @@ void btQuantizedBvh::setQuantizationValues(const btVector3& bvhAabbMin,const btV unsigned short vecIn[3]; btVector3 v; { - quantize(vecIn,m_bvhAabbMin,false); + quantize(vecIn, m_bvhAabbMin, false); v = unQuantize(vecIn); - m_bvhAabbMin.setMin(v-clampValue); - } - aabbSize = m_bvhAabbMax - m_bvhAabbMin; - m_bvhQuantization = btVector3(btScalar(65533.0),btScalar(65533.0),btScalar(65533.0)) / aabbSize; - { - quantize(vecIn,m_bvhAabbMax,true); - v = unQuantize(vecIn); - m_bvhAabbMax.setMax(v+clampValue); + m_bvhAabbMin.setMin(v - clampValue); } aabbSize = m_bvhAabbMax - m_bvhAabbMin; - m_bvhQuantization = btVector3(btScalar(65533.0),btScalar(65533.0),btScalar(65533.0)) / aabbSize; + m_bvhQuantization = btVector3(btScalar(65533.0), btScalar(65533.0), btScalar(65533.0)) / aabbSize; + { + quantize(vecIn, m_bvhAabbMax, true); + v = unQuantize(vecIn); + m_bvhAabbMax.setMax(v + clampValue); + } + aabbSize = m_bvhAabbMax - m_bvhAabbMin; + m_bvhQuantization = btVector3(btScalar(65533.0), btScalar(65533.0), btScalar(65533.0)) / aabbSize; } } - - - btQuantizedBvh::~btQuantizedBvh() { } @@ -129,104 +116,100 @@ btQuantizedBvh::~btQuantizedBvh() #ifdef DEBUG_TREE_BUILDING int gStackDepth = 0; int gMaxStackDepth = 0; -#endif //DEBUG_TREE_BUILDING +#endif //DEBUG_TREE_BUILDING -void btQuantizedBvh::buildTree (int startIndex,int endIndex) +void btQuantizedBvh::buildTree(int startIndex, int endIndex) { #ifdef DEBUG_TREE_BUILDING gStackDepth++; if (gStackDepth > gMaxStackDepth) gMaxStackDepth = gStackDepth; -#endif //DEBUG_TREE_BUILDING - +#endif //DEBUG_TREE_BUILDING int splitAxis, splitIndex, i; - int numIndices =endIndex-startIndex; + int numIndices = endIndex - startIndex; int curIndex = m_curNodeIndex; - btAssert(numIndices>0); + btAssert(numIndices > 0); - if (numIndices==1) + if (numIndices == 1) { #ifdef DEBUG_TREE_BUILDING gStackDepth--; -#endif //DEBUG_TREE_BUILDING - - assignInternalNodeFromLeafNode(m_curNodeIndex,startIndex); +#endif //DEBUG_TREE_BUILDING + + assignInternalNodeFromLeafNode(m_curNodeIndex, startIndex); m_curNodeIndex++; - return; + return; } //calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'. - - splitAxis = calcSplittingAxis(startIndex,endIndex); - splitIndex = sortAndCalcSplittingIndex(startIndex,endIndex,splitAxis); + splitAxis = calcSplittingAxis(startIndex, endIndex); + + splitIndex = sortAndCalcSplittingIndex(startIndex, endIndex, splitAxis); int internalNodeIndex = m_curNodeIndex; - + //set the min aabb to 'inf' or a max value, and set the max aabb to a -inf/minimum value. //the aabb will be expanded during buildTree/mergeInternalNodeAabb with actual node values - setInternalNodeAabbMin(m_curNodeIndex,m_bvhAabbMax);//can't use btVector3(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY)) because of quantization - setInternalNodeAabbMax(m_curNodeIndex,m_bvhAabbMin);//can't use btVector3(-SIMD_INFINITY,-SIMD_INFINITY,-SIMD_INFINITY)) because of quantization - - - for (i=startIndex;im_escapeIndex; - + int leftChildNodexIndex = m_curNodeIndex; //build left child tree - buildTree(startIndex,splitIndex); + buildTree(startIndex, splitIndex); int rightChildNodexIndex = m_curNodeIndex; //build right child tree - buildTree(splitIndex,endIndex); + buildTree(splitIndex, endIndex); #ifdef DEBUG_TREE_BUILDING gStackDepth--; -#endif //DEBUG_TREE_BUILDING +#endif //DEBUG_TREE_BUILDING int escapeIndex = m_curNodeIndex - curIndex; if (m_useQuantization) { //escapeIndex is the number of nodes of this subtree - const int sizeQuantizedNode =sizeof(btQuantizedBvhNode); + const int sizeQuantizedNode = sizeof(btQuantizedBvhNode); const int treeSizeInBytes = escapeIndex * sizeQuantizedNode; if (treeSizeInBytes > MAX_SUBTREE_SIZE_IN_BYTES) { - updateSubtreeHeaders(leftChildNodexIndex,rightChildNodexIndex); + updateSubtreeHeaders(leftChildNodexIndex, rightChildNodexIndex); } - } else + } + else { - } - setInternalNodeEscapeIndex(internalNodeIndex,escapeIndex); - + setInternalNodeEscapeIndex(internalNodeIndex, escapeIndex); } -void btQuantizedBvh::updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex) +void btQuantizedBvh::updateSubtreeHeaders(int leftChildNodexIndex, int rightChildNodexIndex) { btAssert(m_useQuantization); btQuantizedBvhNode& leftChildNode = m_quantizedContiguousNodes[leftChildNodexIndex]; int leftSubTreeSize = leftChildNode.isLeafNode() ? 1 : leftChildNode.getEscapeIndex(); - int leftSubTreeSizeInBytes = leftSubTreeSize * static_cast(sizeof(btQuantizedBvhNode)); - + int leftSubTreeSizeInBytes = leftSubTreeSize * static_cast(sizeof(btQuantizedBvhNode)); + btQuantizedBvhNode& rightChildNode = m_quantizedContiguousNodes[rightChildNodexIndex]; int rightSubTreeSize = rightChildNode.isLeafNode() ? 1 : rightChildNode.getEscapeIndex(); - int rightSubTreeSizeInBytes = rightSubTreeSize * static_cast(sizeof(btQuantizedBvhNode)); + int rightSubTreeSizeInBytes = rightSubTreeSize * static_cast(sizeof(btQuantizedBvhNode)); - if(leftSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES) + if (leftSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES) { btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand(); subtree.setAabbFromQuantizeNode(leftChildNode); @@ -234,7 +217,7 @@ void btQuantizedBvh::updateSubtreeHeaders(int leftChildNodexIndex,int rightChild subtree.m_subtreeSize = leftSubTreeSize; } - if(rightSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES) + if (rightSubTreeSizeInBytes <= MAX_SUBTREE_SIZE_IN_BYTES) { btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand(); subtree.setAabbFromQuantizeNode(rightChildNode); @@ -246,32 +229,31 @@ void btQuantizedBvh::updateSubtreeHeaders(int leftChildNodexIndex,int rightChild m_subtreeHeaderCount = m_SubtreeHeaders.size(); } - -int btQuantizedBvh::sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis) +int btQuantizedBvh::sortAndCalcSplittingIndex(int startIndex, int endIndex, int splitAxis) { int i; - int splitIndex =startIndex; + int splitIndex = startIndex; int numIndices = endIndex - startIndex; btScalar splitValue; - btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.)); - for (i=startIndex;i splitValue) { //swap - swapLeafNodes(i,splitIndex); + swapLeafNodes(i, splitIndex); splitIndex++; } } @@ -281,56 +263,53 @@ int btQuantizedBvh::sortAndCalcSplittingIndex(int startIndex,int endIndex,int sp //unbalanced1 is unsafe: it can cause stack overflows //bool unbalanced1 = ((splitIndex==startIndex) || (splitIndex == (endIndex-1))); - //unbalanced2 should work too: always use center (perfect balanced trees) + //unbalanced2 should work too: always use center (perfect balanced trees) //bool unbalanced2 = true; //this should be safe too: - int rangeBalancedIndices = numIndices/3; - bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices))); - + int rangeBalancedIndices = numIndices / 3; + bool unbalanced = ((splitIndex <= (startIndex + rangeBalancedIndices)) || (splitIndex >= (endIndex - 1 - rangeBalancedIndices))); + if (unbalanced) { - splitIndex = startIndex+ (numIndices>>1); + splitIndex = startIndex + (numIndices >> 1); } - bool unbal = (splitIndex==startIndex) || (splitIndex == (endIndex)); + bool unbal = (splitIndex == startIndex) || (splitIndex == (endIndex)); (void)unbal; btAssert(!unbal); return splitIndex; } - -int btQuantizedBvh::calcSplittingAxis(int startIndex,int endIndex) +int btQuantizedBvh::calcSplittingAxis(int startIndex, int endIndex) { int i; - btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.)); - btVector3 variance(btScalar(0.),btScalar(0.),btScalar(0.)); - int numIndices = endIndex-startIndex; + btVector3 means(btScalar(0.), btScalar(0.), btScalar(0.)); + btVector3 variance(btScalar(0.), btScalar(0.), btScalar(0.)); + int numIndices = endIndex - startIndex; - for (i=startIndex;im_aabbMinOrg,rootNode->m_aabbMaxOrg); + aabbOverlap = TestAabbAgainstAabb2(aabbMin, aabbMax, rootNode->m_aabbMinOrg, rootNode->m_aabbMaxOrg); isLeafNode = rootNode->m_escapeIndex == -1; - + //PCK: unsigned instead of bool if (isLeafNode && (aabbOverlap != 0)) { - nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex); - } - + nodeCallback->processNode(rootNode->m_subPart, rootNode->m_triangleIndex); + } + //PCK: unsigned instead of bool if ((aabbOverlap != 0) || isLeafNode) { rootNode++; curIndex++; - } else + } + else { escapeIndex = rootNode->m_escapeIndex; rootNode += escapeIndex; @@ -410,7 +389,6 @@ void btQuantizedBvh::walkStacklessTree(btNodeOverlapCallback* nodeCallback,const } if (maxIterations < walkIterations) maxIterations = walkIterations; - } /* @@ -434,39 +412,38 @@ void btQuantizedBvh::walkTree(btOptimizedBvhNode* rootNode,btNodeOverlapCallback } */ -void btQuantizedBvh::walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode,btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const +void btQuantizedBvh::walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode, btNodeOverlapCallback* nodeCallback, unsigned short int* quantizedQueryAabbMin, unsigned short int* quantizedQueryAabbMax) const { btAssert(m_useQuantization); - + bool isLeafNode; //PCK: unsigned instead of bool unsigned aabbOverlap; //PCK: unsigned instead of bool - aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,currentNode->m_quantizedAabbMin,currentNode->m_quantizedAabbMax); + aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin, quantizedQueryAabbMax, currentNode->m_quantizedAabbMin, currentNode->m_quantizedAabbMax); isLeafNode = currentNode->isLeafNode(); - + //PCK: unsigned instead of bool if (aabbOverlap != 0) { if (isLeafNode) { - nodeCallback->processNode(currentNode->getPartId(),currentNode->getTriangleIndex()); - } else + nodeCallback->processNode(currentNode->getPartId(), currentNode->getTriangleIndex()); + } + else { //process left and right children - const btQuantizedBvhNode* leftChildNode = currentNode+1; - walkRecursiveQuantizedTreeAgainstQueryAabb(leftChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax); + const btQuantizedBvhNode* leftChildNode = currentNode + 1; + walkRecursiveQuantizedTreeAgainstQueryAabb(leftChildNode, nodeCallback, quantizedQueryAabbMin, quantizedQueryAabbMax); - const btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? leftChildNode+1:leftChildNode+leftChildNode->getEscapeIndex(); - walkRecursiveQuantizedTreeAgainstQueryAabb(rightChildNode,nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax); + const btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? leftChildNode + 1 : leftChildNode + leftChildNode->getEscapeIndex(); + walkRecursiveQuantizedTreeAgainstQueryAabb(rightChildNode, nodeCallback, quantizedQueryAabbMin, quantizedQueryAabbMax); } - } + } } - - -void btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const +void btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex, int endNodeIndex) const { btAssert(!m_useQuantization); @@ -475,11 +452,11 @@ void btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCall int walkIterations = 0; bool isLeafNode; //PCK: unsigned instead of bool - unsigned aabbOverlap=0; - unsigned rayBoxOverlap=0; + unsigned aabbOverlap = 0; + unsigned rayBoxOverlap = 0; btScalar lambda_max = 1.0; - - /* Quick pruning by quantized box */ + + /* Quick pruning by quantized box */ btVector3 rayAabbMin = raySource; btVector3 rayAabbMax = raySource; rayAabbMin.setMin(rayTarget); @@ -490,15 +467,15 @@ void btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCall rayAabbMax += aabbMax; #ifdef RAYAABB2 - btVector3 rayDir = (rayTarget-raySource); - rayDir.normalize (); - lambda_max = rayDir.dot(rayTarget-raySource); + btVector3 rayDir = (rayTarget - raySource); + rayDir.normalize(); + lambda_max = rayDir.dot(rayTarget - raySource); ///what about division by zero? --> just set rayDirection[i] to 1.0 btVector3 rayDirectionInverse; rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0]; rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1]; rayDirectionInverse[2] = rayDir[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[2]; - unsigned int sign[3] = { rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0}; + unsigned int sign[3] = {rayDirectionInverse[0] < 0.0, rayDirectionInverse[1] < 0.0, rayDirectionInverse[2] < 0.0}; #endif btVector3 bounds[2]; @@ -507,7 +484,7 @@ void btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCall { btScalar param = 1.0; //catch bugs in tree data - btAssert (walkIterations < m_curNodeIndex); + btAssert(walkIterations < m_curNodeIndex); walkIterations++; @@ -517,34 +494,35 @@ void btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCall bounds[0] -= aabbMax; bounds[1] -= aabbMin; - aabbOverlap = TestAabbAgainstAabb2(rayAabbMin,rayAabbMax,rootNode->m_aabbMinOrg,rootNode->m_aabbMaxOrg); + aabbOverlap = TestAabbAgainstAabb2(rayAabbMin, rayAabbMax, rootNode->m_aabbMinOrg, rootNode->m_aabbMaxOrg); //perhaps profile if it is worth doing the aabbOverlap test first #ifdef RAYAABB2 - ///careful with this check: need to check division by zero (above) and fix the unQuantize method - ///thanks Joerg/hiker for the reproduction case! - ///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858 - rayBoxOverlap = aabbOverlap ? btRayAabb2 (raySource, rayDirectionInverse, sign, bounds, param, 0.0f, lambda_max) : false; + ///careful with this check: need to check division by zero (above) and fix the unQuantize method + ///thanks Joerg/hiker for the reproduction case! + ///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858 + rayBoxOverlap = aabbOverlap ? btRayAabb2(raySource, rayDirectionInverse, sign, bounds, param, 0.0f, lambda_max) : false; #else btVector3 normal; - rayBoxOverlap = btRayAabb(raySource, rayTarget,bounds[0],bounds[1],param, normal); + rayBoxOverlap = btRayAabb(raySource, rayTarget, bounds[0], bounds[1], param, normal); #endif isLeafNode = rootNode->m_escapeIndex == -1; - + //PCK: unsigned instead of bool if (isLeafNode && (rayBoxOverlap != 0)) { - nodeCallback->processNode(rootNode->m_subPart,rootNode->m_triangleIndex); - } - + nodeCallback->processNode(rootNode->m_subPart, rootNode->m_triangleIndex); + } + //PCK: unsigned instead of bool if ((rayBoxOverlap != 0) || isLeafNode) { rootNode++; curIndex++; - } else + } + else { escapeIndex = rootNode->m_escapeIndex; rootNode += escapeIndex; @@ -553,15 +531,12 @@ void btQuantizedBvh::walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCall } if (maxIterations < walkIterations) maxIterations = walkIterations; - } - - -void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const +void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex, int endNodeIndex) const { btAssert(m_useQuantization); - + int curIndex = startNodeIndex; int walkIterations = 0; int subTreeSize = endNodeIndex - startNodeIndex; @@ -569,7 +544,7 @@ void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[startNodeIndex]; int escapeIndex; - + bool isLeafNode; //PCK: unsigned instead of bool unsigned boxBoxOverlap = 0; @@ -578,14 +553,14 @@ void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* btScalar lambda_max = 1.0; #ifdef RAYAABB2 - btVector3 rayDirection = (rayTarget-raySource); - rayDirection.normalize (); - lambda_max = rayDirection.dot(rayTarget-raySource); + btVector3 rayDirection = (rayTarget - raySource); + rayDirection.normalize(); + lambda_max = rayDirection.dot(rayTarget - raySource); ///what about division by zero? --> just set rayDirection[i] to 1.0 rayDirection[0] = rayDirection[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[0]; rayDirection[1] = rayDirection[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[1]; rayDirection[2] = rayDirection[2] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDirection[2]; - unsigned int sign[3] = { rayDirection[0] < 0.0, rayDirection[1] < 0.0, rayDirection[2] < 0.0}; + unsigned int sign[3] = {rayDirection[0] < 0.0, rayDirection[1] < 0.0, rayDirection[2] < 0.0}; #endif /* Quick pruning by quantized box */ @@ -600,37 +575,36 @@ void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* unsigned short int quantizedQueryAabbMin[3]; unsigned short int quantizedQueryAabbMax[3]; - quantizeWithClamp(quantizedQueryAabbMin,rayAabbMin,0); - quantizeWithClamp(quantizedQueryAabbMax,rayAabbMax,1); + quantizeWithClamp(quantizedQueryAabbMin, rayAabbMin, 0); + quantizeWithClamp(quantizedQueryAabbMax, rayAabbMax, 1); while (curIndex < endNodeIndex) { - //#define VISUALLY_ANALYZE_BVH 1 #ifdef VISUALLY_ANALYZE_BVH //some code snippet to debugDraw aabb, to visually analyze bvh structure static int drawPatch = 0; //need some global access to a debugDrawer extern btIDebugDraw* debugDrawerPtr; - if (curIndex==drawPatch) + if (curIndex == drawPatch) { - btVector3 aabbMin,aabbMax; + btVector3 aabbMin, aabbMax; aabbMin = unQuantize(rootNode->m_quantizedAabbMin); aabbMax = unQuantize(rootNode->m_quantizedAabbMax); - btVector3 color(1,0,0); - debugDrawerPtr->drawAabb(aabbMin,aabbMax,color); + btVector3 color(1, 0, 0); + debugDrawerPtr->drawAabb(aabbMin, aabbMax, color); } -#endif//VISUALLY_ANALYZE_BVH +#endif //VISUALLY_ANALYZE_BVH //catch bugs in tree data - btAssert (walkIterations < subTreeSize); + btAssert(walkIterations < subTreeSize); walkIterations++; //PCK: unsigned instead of bool // only interested if this is closer than any previous hit btScalar param = 1.0; rayBoxOverlap = 0; - boxBoxOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax); + boxBoxOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin, quantizedQueryAabbMax, rootNode->m_quantizedAabbMin, rootNode->m_quantizedAabbMax); isLeafNode = rootNode->isLeafNode(); if (boxBoxOverlap) { @@ -655,24 +629,25 @@ void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* ///http://www.bulletphysics.com/Bullet/phpBB3/viewtopic.php?f=9&t=1858 //BT_PROFILE("btRayAabb2"); - rayBoxOverlap = btRayAabb2 (raySource, rayDirection, sign, bounds, param, 0.0f, lambda_max); - + rayBoxOverlap = btRayAabb2(raySource, rayDirection, sign, bounds, param, 0.0f, lambda_max); + #else - rayBoxOverlap = true;//btRayAabb(raySource, rayTarget, bounds[0], bounds[1], param, normal); + rayBoxOverlap = true; //btRayAabb(raySource, rayTarget, bounds[0], bounds[1], param, normal); #endif } - + if (isLeafNode && rayBoxOverlap) { - nodeCallback->processNode(rootNode->getPartId(),rootNode->getTriangleIndex()); + nodeCallback->processNode(rootNode->getPartId(), rootNode->getTriangleIndex()); } - + //PCK: unsigned instead of bool if ((rayBoxOverlap != 0) || isLeafNode) { rootNode++; curIndex++; - } else + } + else { escapeIndex = rootNode->getEscapeIndex(); rootNode += escapeIndex; @@ -681,13 +656,12 @@ void btQuantizedBvh::walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* } if (maxIterations < walkIterations) maxIterations = walkIterations; - } -void btQuantizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const +void btQuantizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback, unsigned short int* quantizedQueryAabbMin, unsigned short int* quantizedQueryAabbMax, int startNodeIndex, int endNodeIndex) const { btAssert(m_useQuantization); - + int curIndex = startNodeIndex; int walkIterations = 0; int subTreeSize = endNodeIndex - startNodeIndex; @@ -695,49 +669,49 @@ void btQuantizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallb const btQuantizedBvhNode* rootNode = &m_quantizedContiguousNodes[startNodeIndex]; int escapeIndex; - + bool isLeafNode; //PCK: unsigned instead of bool unsigned aabbOverlap; while (curIndex < endNodeIndex) { - //#define VISUALLY_ANALYZE_BVH 1 #ifdef VISUALLY_ANALYZE_BVH //some code snippet to debugDraw aabb, to visually analyze bvh structure static int drawPatch = 0; //need some global access to a debugDrawer extern btIDebugDraw* debugDrawerPtr; - if (curIndex==drawPatch) + if (curIndex == drawPatch) { - btVector3 aabbMin,aabbMax; + btVector3 aabbMin, aabbMax; aabbMin = unQuantize(rootNode->m_quantizedAabbMin); aabbMax = unQuantize(rootNode->m_quantizedAabbMax); - btVector3 color(1,0,0); - debugDrawerPtr->drawAabb(aabbMin,aabbMax,color); + btVector3 color(1, 0, 0); + debugDrawerPtr->drawAabb(aabbMin, aabbMax, color); } -#endif//VISUALLY_ANALYZE_BVH +#endif //VISUALLY_ANALYZE_BVH //catch bugs in tree data - btAssert (walkIterations < subTreeSize); + btAssert(walkIterations < subTreeSize); walkIterations++; //PCK: unsigned instead of bool - aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,rootNode->m_quantizedAabbMin,rootNode->m_quantizedAabbMax); + aabbOverlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin, quantizedQueryAabbMax, rootNode->m_quantizedAabbMin, rootNode->m_quantizedAabbMax); isLeafNode = rootNode->isLeafNode(); - + if (isLeafNode && aabbOverlap) { - nodeCallback->processNode(rootNode->getPartId(),rootNode->getTriangleIndex()); - } - + nodeCallback->processNode(rootNode->getPartId(), rootNode->getTriangleIndex()); + } + //PCK: unsigned instead of bool if ((aabbOverlap != 0) || isLeafNode) { rootNode++; curIndex++; - } else + } + else { escapeIndex = rootNode->getEscapeIndex(); rootNode += escapeIndex; @@ -746,40 +720,36 @@ void btQuantizedBvh::walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallb } if (maxIterations < walkIterations) maxIterations = walkIterations; - } //This traversal can be called from Playstation 3 SPU -void btQuantizedBvh::walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const +void btQuantizedBvh::walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback, unsigned short int* quantizedQueryAabbMin, unsigned short int* quantizedQueryAabbMax) const { btAssert(m_useQuantization); int i; - - for (i=0;im_SubtreeHeaders.size();i++) + for (i = 0; i < this->m_SubtreeHeaders.size(); i++) { const btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i]; //PCK: unsigned instead of bool - unsigned overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax); + unsigned overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin, quantizedQueryAabbMax, subtree.m_quantizedAabbMin, subtree.m_quantizedAabbMax); if (overlap != 0) { - walkStacklessQuantizedTree(nodeCallback,quantizedQueryAabbMin,quantizedQueryAabbMax, - subtree.m_rootNodeIndex, - subtree.m_rootNodeIndex+subtree.m_subtreeSize); + walkStacklessQuantizedTree(nodeCallback, quantizedQueryAabbMin, quantizedQueryAabbMax, + subtree.m_rootNodeIndex, + subtree.m_rootNodeIndex + subtree.m_subtreeSize); } } } - -void btQuantizedBvh::reportRayOverlappingNodex (btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget) const +void btQuantizedBvh::reportRayOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget) const { - reportBoxCastOverlappingNodex(nodeCallback,raySource,rayTarget,btVector3(0,0,0),btVector3(0,0,0)); + reportBoxCastOverlappingNodex(nodeCallback, raySource, rayTarget, btVector3(0, 0, 0), btVector3(0, 0, 0)); } - -void btQuantizedBvh::reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin,const btVector3& aabbMax) const +void btQuantizedBvh::reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax) const { //always use stackless @@ -803,31 +773,31 @@ void btQuantizedBvh::reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCa reportAabbOverlappingNodex(nodeCallback,qaabbMin,qaabbMax); } */ - } - -void btQuantizedBvh::swapLeafNodes(int i,int splitIndex) +void btQuantizedBvh::swapLeafNodes(int i, int splitIndex) { if (m_useQuantization) { - btQuantizedBvhNode tmp = m_quantizedLeafNodes[i]; - m_quantizedLeafNodes[i] = m_quantizedLeafNodes[splitIndex]; - m_quantizedLeafNodes[splitIndex] = tmp; - } else + btQuantizedBvhNode tmp = m_quantizedLeafNodes[i]; + m_quantizedLeafNodes[i] = m_quantizedLeafNodes[splitIndex]; + m_quantizedLeafNodes[splitIndex] = tmp; + } + else { - btOptimizedBvhNode tmp = m_leafNodes[i]; - m_leafNodes[i] = m_leafNodes[splitIndex]; - m_leafNodes[splitIndex] = tmp; + btOptimizedBvhNode tmp = m_leafNodes[i]; + m_leafNodes[i] = m_leafNodes[splitIndex]; + m_leafNodes[splitIndex] = tmp; } } -void btQuantizedBvh::assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex) +void btQuantizedBvh::assignInternalNodeFromLeafNode(int internalNode, int leafNodeIndex) { if (m_useQuantization) { m_quantizedContiguousNodes[internalNode] = m_quantizedLeafNodes[leafNodeIndex]; - } else + } + else { m_contiguousNodes[internalNode] = m_leafNodes[leafNodeIndex]; } @@ -844,11 +814,10 @@ static const unsigned BVH_ALIGNMENT_MASK = BVH_ALIGNMENT-1; static const unsigned BVH_ALIGNMENT_BLOCKS = 2; #endif - unsigned int btQuantizedBvh::getAlignmentSerializationPadding() { // I changed this to 0 since the extra padding is not needed or used. - return 0;//BVH_ALIGNMENT_BLOCKS * BVH_ALIGNMENT; + return 0; //BVH_ALIGNMENT_BLOCKS * BVH_ALIGNMENT; } unsigned btQuantizedBvh::calculateSerializeBufferSize() const @@ -862,12 +831,12 @@ unsigned btQuantizedBvh::calculateSerializeBufferSize() const return baseSize + m_curNodeIndex * sizeof(btOptimizedBvhNode); } -bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian) const +bool btQuantizedBvh::serialize(void* o_alignedDataBuffer, unsigned /*i_dataBufferSize */, bool i_swapEndian) const { btAssert(m_subtreeHeaderCount == m_SubtreeHeaders.size()); m_subtreeHeaderCount = m_SubtreeHeaders.size(); -/* if (i_dataBufferSize < calculateSerializeBufferSize() || o_alignedDataBuffer == NULL || (((unsigned)o_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0)) + /* if (i_dataBufferSize < calculateSerializeBufferSize() || o_alignedDataBuffer == NULL || (((unsigned)o_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0)) { ///check alignedment for buffer? btAssert(0); @@ -875,7 +844,7 @@ bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBuffe } */ - btQuantizedBvh *targetBvh = (btQuantizedBvh *)o_alignedDataBuffer; + btQuantizedBvh* targetBvh = (btQuantizedBvh*)o_alignedDataBuffer; // construct the class so the virtual function table, etc will be set up // Also, m_leafNodes and m_quantizedLeafNodes will be initialized to default values by the constructor @@ -885,10 +854,9 @@ bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBuffe { targetBvh->m_curNodeIndex = static_cast(btSwapEndian(m_curNodeIndex)); - - btSwapVector3Endian(m_bvhAabbMin,targetBvh->m_bvhAabbMin); - btSwapVector3Endian(m_bvhAabbMax,targetBvh->m_bvhAabbMax); - btSwapVector3Endian(m_bvhQuantization,targetBvh->m_bvhQuantization); + btSwapVector3Endian(m_bvhAabbMin, targetBvh->m_bvhAabbMin); + btSwapVector3Endian(m_bvhAabbMax, targetBvh->m_bvhAabbMax); + btSwapVector3Endian(m_bvhQuantization, targetBvh->m_bvhQuantization); targetBvh->m_traversalMode = (btTraversalMode)btSwapEndian(m_traversalMode); targetBvh->m_subtreeHeaderCount = static_cast(btSwapEndian(m_subtreeHeaderCount)); @@ -905,12 +873,12 @@ bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBuffe targetBvh->m_useQuantization = m_useQuantization; - unsigned char *nodeData = (unsigned char *)targetBvh; + unsigned char* nodeData = (unsigned char*)targetBvh; nodeData += sizeof(btQuantizedBvh); - - unsigned sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; + + unsigned sizeToAdd = 0; //(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; nodeData += sizeToAdd; - + int nodeCount = m_curNodeIndex; if (m_useQuantization) @@ -936,7 +904,6 @@ bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBuffe { for (int nodeIndex = 0; nodeIndex < nodeCount; nodeIndex++) { - targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0]; targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[1]; targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[2]; @@ -946,8 +913,6 @@ bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBuffe targetBvh->m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2] = m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[2]; targetBvh->m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex; - - } } nodeData += sizeof(btQuantizedBvhNode) * nodeCount; @@ -993,7 +958,7 @@ bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBuffe targetBvh->m_contiguousNodes.initializeFromBuffer(NULL, 0, 0); } - sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; + sizeToAdd = 0; //(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; nodeData += sizeToAdd; // Now serialize the subtree headers @@ -1048,14 +1013,13 @@ bool btQuantizedBvh::serialize(void *o_alignedDataBuffer, unsigned /*i_dataBuffe return true; } -btQuantizedBvh *btQuantizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian) +btQuantizedBvh* btQuantizedBvh::deSerializeInPlace(void* i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian) { - - if (i_alignedDataBuffer == NULL)// || (((unsigned)i_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0)) + if (i_alignedDataBuffer == NULL) // || (((unsigned)i_alignedDataBuffer & BVH_ALIGNMENT_MASK) != 0)) { return NULL; } - btQuantizedBvh *bvh = (btQuantizedBvh *)i_alignedDataBuffer; + btQuantizedBvh* bvh = (btQuantizedBvh*)i_alignedDataBuffer; if (i_swapEndian) { @@ -1077,12 +1041,12 @@ btQuantizedBvh *btQuantizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, un return NULL; } - unsigned char *nodeData = (unsigned char *)bvh; + unsigned char* nodeData = (unsigned char*)bvh; nodeData += sizeof(btQuantizedBvh); - - unsigned sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; + + unsigned sizeToAdd = 0; //(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; nodeData += sizeToAdd; - + int nodeCount = bvh->m_curNodeIndex; // Must call placement new to fill in virtual function table, etc, but we don't want to overwrite most data, so call a special version of the constructor @@ -1120,7 +1084,7 @@ btQuantizedBvh *btQuantizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, un { btUnSwapVector3Endian(bvh->m_contiguousNodes[nodeIndex].m_aabbMinOrg); btUnSwapVector3Endian(bvh->m_contiguousNodes[nodeIndex].m_aabbMaxOrg); - + bvh->m_contiguousNodes[nodeIndex].m_escapeIndex = static_cast(btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_escapeIndex)); bvh->m_contiguousNodes[nodeIndex].m_subPart = static_cast(btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_subPart)); bvh->m_contiguousNodes[nodeIndex].m_triangleIndex = static_cast(btSwapEndian(bvh->m_contiguousNodes[nodeIndex].m_triangleIndex)); @@ -1129,7 +1093,7 @@ btQuantizedBvh *btQuantizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, un nodeData += sizeof(btOptimizedBvhNode) * nodeCount; } - sizeToAdd = 0;//(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; + sizeToAdd = 0; //(BVH_ALIGNMENT-((unsigned)nodeData & BVH_ALIGNMENT_MASK))&BVH_ALIGNMENT_MASK; nodeData += sizeToAdd; // Now serialize the subtree headers @@ -1155,13 +1119,11 @@ btQuantizedBvh *btQuantizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, un } // Constructor that prevents btVector3's default constructor from being called -btQuantizedBvh::btQuantizedBvh(btQuantizedBvh &self, bool /* ownsMemory */) : -m_bvhAabbMin(self.m_bvhAabbMin), -m_bvhAabbMax(self.m_bvhAabbMax), -m_bvhQuantization(self.m_bvhQuantization), -m_bulletVersion(BT_BULLET_VERSION) +btQuantizedBvh::btQuantizedBvh(btQuantizedBvh& self, bool /* ownsMemory */) : m_bvhAabbMin(self.m_bvhAabbMin), + m_bvhAabbMax(self.m_bvhAabbMax), + m_bvhQuantization(self.m_bvhQuantization), + m_bulletVersion(BT_BULLET_VERSION) { - } void btQuantizedBvh::deSerializeFloat(struct btQuantizedBvhFloatData& quantizedBvhFloatData) @@ -1171,8 +1133,8 @@ void btQuantizedBvh::deSerializeFloat(struct btQuantizedBvhFloatData& quantizedB m_bvhQuantization.deSerializeFloat(quantizedBvhFloatData.m_bvhQuantization); m_curNodeIndex = quantizedBvhFloatData.m_curNodeIndex; - m_useQuantization = quantizedBvhFloatData.m_useQuantization!=0; - + m_useQuantization = quantizedBvhFloatData.m_useQuantization != 0; + { int numElem = quantizedBvhFloatData.m_numContiguousLeafNodes; m_contiguousNodes.resize(numElem); @@ -1181,7 +1143,7 @@ void btQuantizedBvh::deSerializeFloat(struct btQuantizedBvhFloatData& quantizedB { btOptimizedBvhNodeFloatData* memPtr = quantizedBvhFloatData.m_contiguousNodesPtr; - for (int i=0;im_aabbMaxOrg); m_contiguousNodes[i].m_aabbMinOrg.deSerializeFloat(memPtr->m_aabbMinOrg); @@ -1195,11 +1157,11 @@ void btQuantizedBvh::deSerializeFloat(struct btQuantizedBvhFloatData& quantizedB { int numElem = quantizedBvhFloatData.m_numQuantizedContiguousNodes; m_quantizedContiguousNodes.resize(numElem); - + if (numElem) { btQuantizedBvhNodeData* memPtr = quantizedBvhFloatData.m_quantizedContiguousNodesPtr; - for (int i=0;im_escapeIndexOrTriangleIndex; m_quantizedContiguousNodes[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0]; @@ -1213,16 +1175,16 @@ void btQuantizedBvh::deSerializeFloat(struct btQuantizedBvhFloatData& quantizedB } m_traversalMode = btTraversalMode(quantizedBvhFloatData.m_traversalMode); - + { int numElem = quantizedBvhFloatData.m_numSubtreeHeaders; m_SubtreeHeaders.resize(numElem); if (numElem) { btBvhSubtreeInfoData* memPtr = quantizedBvhFloatData.m_subTreeInfoPtr; - for (int i=0;im_quantizedAabbMax[0] ; + m_SubtreeHeaders[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0]; m_SubtreeHeaders[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1]; m_SubtreeHeaders[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2]; m_SubtreeHeaders[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0]; @@ -1242,8 +1204,8 @@ void btQuantizedBvh::deSerializeDouble(struct btQuantizedBvhDoubleData& quantize m_bvhQuantization.deSerializeDouble(quantizedBvhDoubleData.m_bvhQuantization); m_curNodeIndex = quantizedBvhDoubleData.m_curNodeIndex; - m_useQuantization = quantizedBvhDoubleData.m_useQuantization!=0; - + m_useQuantization = quantizedBvhDoubleData.m_useQuantization != 0; + { int numElem = quantizedBvhDoubleData.m_numContiguousLeafNodes; m_contiguousNodes.resize(numElem); @@ -1252,7 +1214,7 @@ void btQuantizedBvh::deSerializeDouble(struct btQuantizedBvhDoubleData& quantize { btOptimizedBvhNodeDoubleData* memPtr = quantizedBvhDoubleData.m_contiguousNodesPtr; - for (int i=0;im_aabbMaxOrg); m_contiguousNodes[i].m_aabbMinOrg.deSerializeDouble(memPtr->m_aabbMinOrg); @@ -1266,11 +1228,11 @@ void btQuantizedBvh::deSerializeDouble(struct btQuantizedBvhDoubleData& quantize { int numElem = quantizedBvhDoubleData.m_numQuantizedContiguousNodes; m_quantizedContiguousNodes.resize(numElem); - + if (numElem) { btQuantizedBvhNodeData* memPtr = quantizedBvhDoubleData.m_quantizedContiguousNodesPtr; - for (int i=0;im_escapeIndexOrTriangleIndex; m_quantizedContiguousNodes[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0]; @@ -1284,16 +1246,16 @@ void btQuantizedBvh::deSerializeDouble(struct btQuantizedBvhDoubleData& quantize } m_traversalMode = btTraversalMode(quantizedBvhDoubleData.m_traversalMode); - + { int numElem = quantizedBvhDoubleData.m_numSubtreeHeaders; m_SubtreeHeaders.resize(numElem); if (numElem) { btBvhSubtreeInfoData* memPtr = quantizedBvhDoubleData.m_subTreeInfoPtr; - for (int i=0;im_quantizedAabbMax[0] ; + m_SubtreeHeaders[i].m_quantizedAabbMax[0] = memPtr->m_quantizedAabbMax[0]; m_SubtreeHeaders[i].m_quantizedAabbMax[1] = memPtr->m_quantizedAabbMax[1]; m_SubtreeHeaders[i].m_quantizedAabbMax[2] = memPtr->m_quantizedAabbMax[2]; m_SubtreeHeaders[i].m_quantizedAabbMin[0] = memPtr->m_quantizedAabbMin[0]; @@ -1304,32 +1266,29 @@ void btQuantizedBvh::deSerializeDouble(struct btQuantizedBvhDoubleData& quantize } } } - } - - ///fills the dataBuffer and returns the struct name (and 0 on failure) -const char* btQuantizedBvh::serialize(void* dataBuffer, btSerializer* serializer) const +const char* btQuantizedBvh::serialize(void* dataBuffer, btSerializer* serializer) const { btQuantizedBvhData* quantizedData = (btQuantizedBvhData*)dataBuffer; - + m_bvhAabbMax.serialize(quantizedData->m_bvhAabbMax); m_bvhAabbMin.serialize(quantizedData->m_bvhAabbMin); m_bvhQuantization.serialize(quantizedData->m_bvhQuantization); quantizedData->m_curNodeIndex = m_curNodeIndex; quantizedData->m_useQuantization = m_useQuantization; - + quantizedData->m_numContiguousLeafNodes = m_contiguousNodes.size(); - quantizedData->m_contiguousNodesPtr = (btOptimizedBvhNodeData*) (m_contiguousNodes.size() ? serializer->getUniquePointer((void*)&m_contiguousNodes[0]) : 0); + quantizedData->m_contiguousNodesPtr = (btOptimizedBvhNodeData*)(m_contiguousNodes.size() ? serializer->getUniquePointer((void*)&m_contiguousNodes[0]) : 0); if (quantizedData->m_contiguousNodesPtr) { int sz = sizeof(btOptimizedBvhNodeData); int numElem = m_contiguousNodes.size(); - btChunk* chunk = serializer->allocate(sz,numElem); + btChunk* chunk = serializer->allocate(sz, numElem); btOptimizedBvhNodeData* memPtr = (btOptimizedBvhNodeData*)chunk->m_oldPtr; - for (int i=0;im_aabbMaxOrg); m_contiguousNodes[i].m_aabbMinOrg.serialize(memPtr->m_aabbMinOrg); @@ -1339,19 +1298,19 @@ const char* btQuantizedBvh::serialize(void* dataBuffer, btSerializer* serializer // Fill padding with zeros to appease msan. memset(memPtr->m_pad, 0, sizeof(memPtr->m_pad)); } - serializer->finalizeChunk(chunk,"btOptimizedBvhNodeData",BT_ARRAY_CODE,(void*)&m_contiguousNodes[0]); + serializer->finalizeChunk(chunk, "btOptimizedBvhNodeData", BT_ARRAY_CODE, (void*)&m_contiguousNodes[0]); } quantizedData->m_numQuantizedContiguousNodes = m_quantizedContiguousNodes.size(); -// printf("quantizedData->m_numQuantizedContiguousNodes=%d\n",quantizedData->m_numQuantizedContiguousNodes); - quantizedData->m_quantizedContiguousNodesPtr =(btQuantizedBvhNodeData*) (m_quantizedContiguousNodes.size() ? serializer->getUniquePointer((void*)&m_quantizedContiguousNodes[0]) : 0); + // printf("quantizedData->m_numQuantizedContiguousNodes=%d\n",quantizedData->m_numQuantizedContiguousNodes); + quantizedData->m_quantizedContiguousNodesPtr = (btQuantizedBvhNodeData*)(m_quantizedContiguousNodes.size() ? serializer->getUniquePointer((void*)&m_quantizedContiguousNodes[0]) : 0); if (quantizedData->m_quantizedContiguousNodesPtr) { int sz = sizeof(btQuantizedBvhNodeData); int numElem = m_quantizedContiguousNodes.size(); - btChunk* chunk = serializer->allocate(sz,numElem); + btChunk* chunk = serializer->allocate(sz, numElem); btQuantizedBvhNodeData* memPtr = (btQuantizedBvhNodeData*)chunk->m_oldPtr; - for (int i=0;im_escapeIndexOrTriangleIndex = m_quantizedContiguousNodes[i].m_escapeIndexOrTriangleIndex; memPtr->m_quantizedAabbMax[0] = m_quantizedContiguousNodes[i].m_quantizedAabbMax[0]; @@ -1361,20 +1320,20 @@ const char* btQuantizedBvh::serialize(void* dataBuffer, btSerializer* serializer memPtr->m_quantizedAabbMin[1] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[1]; memPtr->m_quantizedAabbMin[2] = m_quantizedContiguousNodes[i].m_quantizedAabbMin[2]; } - serializer->finalizeChunk(chunk,"btQuantizedBvhNodeData",BT_ARRAY_CODE,(void*)&m_quantizedContiguousNodes[0]); + serializer->finalizeChunk(chunk, "btQuantizedBvhNodeData", BT_ARRAY_CODE, (void*)&m_quantizedContiguousNodes[0]); } quantizedData->m_traversalMode = int(m_traversalMode); quantizedData->m_numSubtreeHeaders = m_SubtreeHeaders.size(); - quantizedData->m_subTreeInfoPtr = (btBvhSubtreeInfoData*) (m_SubtreeHeaders.size() ? serializer->getUniquePointer((void*)&m_SubtreeHeaders[0]) : 0); + quantizedData->m_subTreeInfoPtr = (btBvhSubtreeInfoData*)(m_SubtreeHeaders.size() ? serializer->getUniquePointer((void*)&m_SubtreeHeaders[0]) : 0); if (quantizedData->m_subTreeInfoPtr) { int sz = sizeof(btBvhSubtreeInfoData); int numElem = m_SubtreeHeaders.size(); - btChunk* chunk = serializer->allocate(sz,numElem); + btChunk* chunk = serializer->allocate(sz, numElem); btBvhSubtreeInfoData* memPtr = (btBvhSubtreeInfoData*)chunk->m_oldPtr; - for (int i=0;im_quantizedAabbMax[0] = m_SubtreeHeaders[i].m_quantizedAabbMax[0]; memPtr->m_quantizedAabbMax[1] = m_SubtreeHeaders[i].m_quantizedAabbMax[1]; @@ -1386,12 +1345,7 @@ const char* btQuantizedBvh::serialize(void* dataBuffer, btSerializer* serializer memPtr->m_rootNodeIndex = m_SubtreeHeaders[i].m_rootNodeIndex; memPtr->m_subtreeSize = m_SubtreeHeaders[i].m_subtreeSize; } - serializer->finalizeChunk(chunk,"btBvhSubtreeInfoData",BT_ARRAY_CODE,(void*)&m_SubtreeHeaders[0]); + serializer->finalizeChunk(chunk, "btBvhSubtreeInfoData", BT_ARRAY_CODE, (void*)&m_SubtreeHeaders[0]); } return btQuantizedBvhDataName; } - - - - - diff --git a/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h b/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h index 3dd5ac9bb..1c47b9ccf 100644 --- a/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h +++ b/src/BulletCollision/BroadphaseCollision/btQuantizedBvh.h @@ -22,11 +22,11 @@ class btSerializer; #ifdef DEBUG_CHECK_DEQUANTIZATION #ifdef __SPU__ #define printf spu_printf -#endif //__SPU__ +#endif //__SPU__ #include #include -#endif //DEBUG_CHECK_DEQUANTIZATION +#endif //DEBUG_CHECK_DEQUANTIZATION #include "LinearMath/btVector3.h" #include "LinearMath/btAlignedAllocator.h" @@ -41,13 +41,10 @@ class btSerializer; #define btQuantizedBvhDataName "btQuantizedBvhFloatData" #endif - - //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclang/html/vclrf__m128.asp - //Note: currently we have 16 bytes per quantized node -#define MAX_SUBTREE_SIZE_IN_BYTES 2048 +#define MAX_SUBTREE_SIZE_IN_BYTES 2048 // 10 gives the potential for 1024 parts, with at most 2^21 (2097152) (minus one // actually) triangles each (since the sign bit is reserved @@ -55,15 +52,16 @@ class btSerializer; ///btQuantizedBvhNode is a compressed aabb node, 16 bytes. ///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range). -ATTRIBUTE_ALIGNED16 (struct) btQuantizedBvhNode +ATTRIBUTE_ALIGNED16(struct) +btQuantizedBvhNode { BT_DECLARE_ALIGNED_ALLOCATOR(); //12 bytes - unsigned short int m_quantizedAabbMin[3]; - unsigned short int m_quantizedAabbMax[3]; + unsigned short int m_quantizedAabbMin[3]; + unsigned short int m_quantizedAabbMax[3]; //4 bytes - int m_escapeIndexOrTriangleIndex; + int m_escapeIndexOrTriangleIndex; bool isLeafNode() const { @@ -75,68 +73,67 @@ ATTRIBUTE_ALIGNED16 (struct) btQuantizedBvhNode btAssert(!isLeafNode()); return -m_escapeIndexOrTriangleIndex; } - int getTriangleIndex() const + int getTriangleIndex() const { btAssert(isLeafNode()); - unsigned int x=0; - unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS); + unsigned int x = 0; + unsigned int y = (~(x & 0)) << (31 - MAX_NUM_PARTS_IN_BITS); // Get only the lower bits where the triangle index is stored - return (m_escapeIndexOrTriangleIndex&~(y)); + return (m_escapeIndexOrTriangleIndex & ~(y)); } - int getPartId() const + int getPartId() const { btAssert(isLeafNode()); // Get only the highest bits where the part index is stored - return (m_escapeIndexOrTriangleIndex>>(31-MAX_NUM_PARTS_IN_BITS)); + return (m_escapeIndexOrTriangleIndex >> (31 - MAX_NUM_PARTS_IN_BITS)); } -} -; +}; /// btOptimizedBvhNode contains both internal and leaf node information. /// Total node size is 44 bytes / node. You can use the compressed version of 16 bytes. -ATTRIBUTE_ALIGNED16 (struct) btOptimizedBvhNode +ATTRIBUTE_ALIGNED16(struct) +btOptimizedBvhNode { BT_DECLARE_ALIGNED_ALLOCATOR(); //32 bytes - btVector3 m_aabbMinOrg; - btVector3 m_aabbMaxOrg; + btVector3 m_aabbMinOrg; + btVector3 m_aabbMaxOrg; //4 - int m_escapeIndex; + int m_escapeIndex; //8 //for child nodes - int m_subPart; - int m_triangleIndex; + int m_subPart; + int m_triangleIndex; -//pad the size to 64 bytes - char m_padding[20]; + //pad the size to 64 bytes + char m_padding[20]; }; - ///btBvhSubtreeInfo provides info to gather a subtree of limited size -ATTRIBUTE_ALIGNED16(class) btBvhSubtreeInfo +ATTRIBUTE_ALIGNED16(class) +btBvhSubtreeInfo { public: BT_DECLARE_ALIGNED_ALLOCATOR(); //12 bytes - unsigned short int m_quantizedAabbMin[3]; - unsigned short int m_quantizedAabbMax[3]; + unsigned short int m_quantizedAabbMin[3]; + unsigned short int m_quantizedAabbMax[3]; //4 bytes, points to the root of the subtree - int m_rootNodeIndex; + int m_rootNodeIndex; //4 bytes - int m_subtreeSize; - int m_padding[3]; + int m_subtreeSize; + int m_padding[3]; btBvhSubtreeInfo() { //memset(&m_padding[0], 0, sizeof(m_padding)); } - - void setAabbFromQuantizeNode(const btQuantizedBvhNode& quantizedNode) + void setAabbFromQuantizeNode(const btQuantizedBvhNode& quantizedNode) { m_quantizedAabbMin[0] = quantizedNode.m_quantizedAabbMin[0]; m_quantizedAabbMin[1] = quantizedNode.m_quantizedAabbMin[1]; @@ -145,14 +142,12 @@ public: m_quantizedAabbMax[1] = quantizedNode.m_quantizedAabbMax[1]; m_quantizedAabbMax[2] = quantizedNode.m_quantizedAabbMax[2]; } -} -; - +}; class btNodeOverlapCallback { public: - virtual ~btNodeOverlapCallback() {}; + virtual ~btNodeOverlapCallback(){}; virtual void processNode(int subPart, int triangleIndex) = 0; }; @@ -160,18 +155,16 @@ public: #include "LinearMath/btAlignedAllocator.h" #include "LinearMath/btAlignedObjectArray.h" - - ///for code readability: -typedef btAlignedObjectArray NodeArray; -typedef btAlignedObjectArray QuantizedNodeArray; -typedef btAlignedObjectArray BvhSubtreeInfoArray; - +typedef btAlignedObjectArray NodeArray; +typedef btAlignedObjectArray QuantizedNodeArray; +typedef btAlignedObjectArray BvhSubtreeInfoArray; ///The btQuantizedBvh class stores an AABB tree that can be quickly traversed on CPU and Cell SPU. ///It is used by the btBvhTriangleMeshShape as midphase. ///It is recommended to use quantization for better performance and lower memory requirements. -ATTRIBUTE_ALIGNED16(class) btQuantizedBvh +ATTRIBUTE_ALIGNED16(class) +btQuantizedBvh { public: enum btTraversalMode @@ -182,54 +175,47 @@ public: }; protected: + btVector3 m_bvhAabbMin; + btVector3 m_bvhAabbMax; + btVector3 m_bvhQuantization; + int m_bulletVersion; //for serialization versioning. It could also be used to detect endianess. - btVector3 m_bvhAabbMin; - btVector3 m_bvhAabbMax; - btVector3 m_bvhQuantization; - - int m_bulletVersion; //for serialization versioning. It could also be used to detect endianess. - - int m_curNodeIndex; + int m_curNodeIndex; //quantization data - bool m_useQuantization; + bool m_useQuantization; + NodeArray m_leafNodes; + NodeArray m_contiguousNodes; + QuantizedNodeArray m_quantizedLeafNodes; + QuantizedNodeArray m_quantizedContiguousNodes; - - NodeArray m_leafNodes; - NodeArray m_contiguousNodes; - QuantizedNodeArray m_quantizedLeafNodes; - QuantizedNodeArray m_quantizedContiguousNodes; - - btTraversalMode m_traversalMode; - BvhSubtreeInfoArray m_SubtreeHeaders; + btTraversalMode m_traversalMode; + BvhSubtreeInfoArray m_SubtreeHeaders; //This is only used for serialization so we don't have to add serialization directly to btAlignedObjectArray mutable int m_subtreeHeaderCount; - - - - ///two versions, one for quantized and normal nodes. This allows code-reuse while maintaining readability (no template/macro!) ///this might be refactored into a virtual, it is usually not calculated at run-time - void setInternalNodeAabbMin(int nodeIndex, const btVector3& aabbMin) + void setInternalNodeAabbMin(int nodeIndex, const btVector3& aabbMin) { if (m_useQuantization) { - quantize(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0] ,aabbMin,0); - } else + quantize(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[0], aabbMin, 0); + } + else { m_contiguousNodes[nodeIndex].m_aabbMinOrg = aabbMin; - } } - void setInternalNodeAabbMax(int nodeIndex,const btVector3& aabbMax) + void setInternalNodeAabbMax(int nodeIndex, const btVector3& aabbMax) { if (m_useQuantization) { - quantize(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0],aabbMax,1); - } else + quantize(&m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[0], aabbMax, 1); + } + else { m_contiguousNodes[nodeIndex].m_aabbMaxOrg = aabbMax; } @@ -243,115 +229,102 @@ protected: } //non-quantized return m_leafNodes[nodeIndex].m_aabbMinOrg; - } btVector3 getAabbMax(int nodeIndex) const { if (m_useQuantization) { return unQuantize(&m_quantizedLeafNodes[nodeIndex].m_quantizedAabbMax[0]); - } + } //non-quantized return m_leafNodes[nodeIndex].m_aabbMaxOrg; - } - - void setInternalNodeEscapeIndex(int nodeIndex, int escapeIndex) + void setInternalNodeEscapeIndex(int nodeIndex, int escapeIndex) { if (m_useQuantization) { m_quantizedContiguousNodes[nodeIndex].m_escapeIndexOrTriangleIndex = -escapeIndex; - } + } else { m_contiguousNodes[nodeIndex].m_escapeIndex = escapeIndex; } - } - void mergeInternalNodeAabb(int nodeIndex,const btVector3& newAabbMin,const btVector3& newAabbMax) + void mergeInternalNodeAabb(int nodeIndex, const btVector3& newAabbMin, const btVector3& newAabbMax) { if (m_useQuantization) { unsigned short int quantizedAabbMin[3]; unsigned short int quantizedAabbMax[3]; - quantize(quantizedAabbMin,newAabbMin,0); - quantize(quantizedAabbMax,newAabbMax,1); - for (int i=0;i<3;i++) + quantize(quantizedAabbMin, newAabbMin, 0); + quantize(quantizedAabbMax, newAabbMax, 1); + for (int i = 0; i < 3; i++) { if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] > quantizedAabbMin[i]) m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMin[i] = quantizedAabbMin[i]; if (m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] < quantizedAabbMax[i]) m_quantizedContiguousNodes[nodeIndex].m_quantizedAabbMax[i] = quantizedAabbMax[i]; - } - } else + } + else { //non-quantized m_contiguousNodes[nodeIndex].m_aabbMinOrg.setMin(newAabbMin); - m_contiguousNodes[nodeIndex].m_aabbMaxOrg.setMax(newAabbMax); + m_contiguousNodes[nodeIndex].m_aabbMaxOrg.setMax(newAabbMax); } } - void swapLeafNodes(int firstIndex,int secondIndex); + void swapLeafNodes(int firstIndex, int secondIndex); - void assignInternalNodeFromLeafNode(int internalNode,int leafNodeIndex); + void assignInternalNodeFromLeafNode(int internalNode, int leafNodeIndex); protected: + void buildTree(int startIndex, int endIndex); - + int calcSplittingAxis(int startIndex, int endIndex); - void buildTree (int startIndex,int endIndex); + int sortAndCalcSplittingIndex(int startIndex, int endIndex, int splitAxis); - int calcSplittingAxis(int startIndex,int endIndex); + void walkStacklessTree(btNodeOverlapCallback * nodeCallback, const btVector3& aabbMin, const btVector3& aabbMax) const; - int sortAndCalcSplittingIndex(int startIndex,int endIndex,int splitAxis); - - void walkStacklessTree(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const; - - void walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const; - void walkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,int startNodeIndex,int endNodeIndex) const; - void walkStacklessTreeAgainstRay(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex,int endNodeIndex) const; + void walkStacklessQuantizedTreeAgainstRay(btNodeOverlapCallback * nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex, int endNodeIndex) const; + void walkStacklessQuantizedTree(btNodeOverlapCallback * nodeCallback, unsigned short int* quantizedQueryAabbMin, unsigned short int* quantizedQueryAabbMax, int startNodeIndex, int endNodeIndex) const; + void walkStacklessTreeAgainstRay(btNodeOverlapCallback * nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax, int startNodeIndex, int endNodeIndex) const; ///tree traversal designed for small-memory processors like PS3 SPU - void walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const; + void walkStacklessQuantizedTreeCacheFriendly(btNodeOverlapCallback * nodeCallback, unsigned short int* quantizedQueryAabbMin, unsigned short int* quantizedQueryAabbMax) const; ///use the 16-byte stackless 'skipindex' node tree to do a recursive traversal - void walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode,btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax) const; + void walkRecursiveQuantizedTreeAgainstQueryAabb(const btQuantizedBvhNode* currentNode, btNodeOverlapCallback* nodeCallback, unsigned short int* quantizedQueryAabbMin, unsigned short int* quantizedQueryAabbMax) const; ///use the 16-byte stackless 'skipindex' node tree to do a recursive traversal - void walkRecursiveQuantizedTreeAgainstQuantizedTree(const btQuantizedBvhNode* treeNodeA,const btQuantizedBvhNode* treeNodeB,btNodeOverlapCallback* nodeCallback) const; - + void walkRecursiveQuantizedTreeAgainstQuantizedTree(const btQuantizedBvhNode* treeNodeA, const btQuantizedBvhNode* treeNodeB, btNodeOverlapCallback* nodeCallback) const; - - - void updateSubtreeHeaders(int leftChildNodexIndex,int rightChildNodexIndex); + void updateSubtreeHeaders(int leftChildNodexIndex, int rightChildNodexIndex); public: - BT_DECLARE_ALIGNED_ALLOCATOR(); btQuantizedBvh(); virtual ~btQuantizedBvh(); - ///***************************************** expert/internal use only ************************* - void setQuantizationValues(const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,btScalar quantizationMargin=btScalar(1.0)); - QuantizedNodeArray& getLeafNodeArray() { return m_quantizedLeafNodes; } + void setQuantizationValues(const btVector3& bvhAabbMin, const btVector3& bvhAabbMax, btScalar quantizationMargin = btScalar(1.0)); + QuantizedNodeArray& getLeafNodeArray() { return m_quantizedLeafNodes; } ///buildInternal is expert use only: assumes that setQuantizationValues and LeafNodeArray are initialized - void buildInternal(); + void buildInternal(); ///***************************************** expert/internal use only ************************* - void reportAabbOverlappingNodex(btNodeOverlapCallback* nodeCallback,const btVector3& aabbMin,const btVector3& aabbMax) const; - void reportRayOverlappingNodex (btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget) const; - void reportBoxCastOverlappingNodex(btNodeOverlapCallback* nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin,const btVector3& aabbMax) const; + void reportAabbOverlappingNodex(btNodeOverlapCallback * nodeCallback, const btVector3& aabbMin, const btVector3& aabbMax) const; + void reportRayOverlappingNodex(btNodeOverlapCallback * nodeCallback, const btVector3& raySource, const btVector3& rayTarget) const; + void reportBoxCastOverlappingNodex(btNodeOverlapCallback * nodeCallback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax) const; - SIMD_FORCE_INLINE void quantize(unsigned short* out, const btVector3& point,int isMax) const + SIMD_FORCE_INLINE void quantize(unsigned short* out, const btVector3& point, int isMax) const { - btAssert(m_useQuantization); btAssert(point.getX() <= m_bvhAabbMax.getX()); @@ -368,16 +341,16 @@ public: ///@todo: double-check this if (isMax) { - out[0] = (unsigned short) (((unsigned short)(v.getX()+btScalar(1.)) | 1)); - out[1] = (unsigned short) (((unsigned short)(v.getY()+btScalar(1.)) | 1)); - out[2] = (unsigned short) (((unsigned short)(v.getZ()+btScalar(1.)) | 1)); - } else - { - out[0] = (unsigned short) (((unsigned short)(v.getX()) & 0xfffe)); - out[1] = (unsigned short) (((unsigned short)(v.getY()) & 0xfffe)); - out[2] = (unsigned short) (((unsigned short)(v.getZ()) & 0xfffe)); + out[0] = (unsigned short)(((unsigned short)(v.getX() + btScalar(1.)) | 1)); + out[1] = (unsigned short)(((unsigned short)(v.getY() + btScalar(1.)) | 1)); + out[2] = (unsigned short)(((unsigned short)(v.getZ() + btScalar(1.)) | 1)); + } + else + { + out[0] = (unsigned short)(((unsigned short)(v.getX()) & 0xfffe)); + out[1] = (unsigned short)(((unsigned short)(v.getY()) & 0xfffe)); + out[2] = (unsigned short)(((unsigned short)(v.getZ()) & 0xfffe)); } - #ifdef DEBUG_CHECK_DEQUANTIZATION btVector3 newPoint = unQuantize(out); @@ -385,105 +358,97 @@ public: { if (newPoint.getX() < point.getX()) { - printf("unconservative X, diffX = %f, oldX=%f,newX=%f\n",newPoint.getX()-point.getX(), newPoint.getX(),point.getX()); + printf("unconservative X, diffX = %f, oldX=%f,newX=%f\n", newPoint.getX() - point.getX(), newPoint.getX(), point.getX()); } if (newPoint.getY() < point.getY()) { - printf("unconservative Y, diffY = %f, oldY=%f,newY=%f\n",newPoint.getY()-point.getY(), newPoint.getY(),point.getY()); + printf("unconservative Y, diffY = %f, oldY=%f,newY=%f\n", newPoint.getY() - point.getY(), newPoint.getY(), point.getY()); } if (newPoint.getZ() < point.getZ()) { - - printf("unconservative Z, diffZ = %f, oldZ=%f,newZ=%f\n",newPoint.getZ()-point.getZ(), newPoint.getZ(),point.getZ()); + printf("unconservative Z, diffZ = %f, oldZ=%f,newZ=%f\n", newPoint.getZ() - point.getZ(), newPoint.getZ(), point.getZ()); } - } else + } + else { if (newPoint.getX() > point.getX()) { - printf("unconservative X, diffX = %f, oldX=%f,newX=%f\n",newPoint.getX()-point.getX(), newPoint.getX(),point.getX()); + printf("unconservative X, diffX = %f, oldX=%f,newX=%f\n", newPoint.getX() - point.getX(), newPoint.getX(), point.getX()); } if (newPoint.getY() > point.getY()) { - printf("unconservative Y, diffY = %f, oldY=%f,newY=%f\n",newPoint.getY()-point.getY(), newPoint.getY(),point.getY()); + printf("unconservative Y, diffY = %f, oldY=%f,newY=%f\n", newPoint.getY() - point.getY(), newPoint.getY(), point.getY()); } if (newPoint.getZ() > point.getZ()) { - printf("unconservative Z, diffZ = %f, oldZ=%f,newZ=%f\n",newPoint.getZ()-point.getZ(), newPoint.getZ(),point.getZ()); + printf("unconservative Z, diffZ = %f, oldZ=%f,newZ=%f\n", newPoint.getZ() - point.getZ(), newPoint.getZ(), point.getZ()); } } -#endif //DEBUG_CHECK_DEQUANTIZATION - +#endif //DEBUG_CHECK_DEQUANTIZATION } - - SIMD_FORCE_INLINE void quantizeWithClamp(unsigned short* out, const btVector3& point2,int isMax) const + SIMD_FORCE_INLINE void quantizeWithClamp(unsigned short* out, const btVector3& point2, int isMax) const { - btAssert(m_useQuantization); btVector3 clampedPoint(point2); clampedPoint.setMax(m_bvhAabbMin); clampedPoint.setMin(m_bvhAabbMax); - quantize(out,clampedPoint,isMax); - + quantize(out, clampedPoint, isMax); } - - SIMD_FORCE_INLINE btVector3 unQuantize(const unsigned short* vecIn) const + + SIMD_FORCE_INLINE btVector3 unQuantize(const unsigned short* vecIn) const { - btVector3 vecOut; - vecOut.setValue( + btVector3 vecOut; + vecOut.setValue( (btScalar)(vecIn[0]) / (m_bvhQuantization.getX()), (btScalar)(vecIn[1]) / (m_bvhQuantization.getY()), (btScalar)(vecIn[2]) / (m_bvhQuantization.getZ())); - vecOut += m_bvhAabbMin; - return vecOut; + vecOut += m_bvhAabbMin; + return vecOut; } ///setTraversalMode let's you choose between stackless, recursive or stackless cache friendly tree traversal. Note this is only implemented for quantized trees. - void setTraversalMode(btTraversalMode traversalMode) + void setTraversalMode(btTraversalMode traversalMode) { m_traversalMode = traversalMode; } - - SIMD_FORCE_INLINE QuantizedNodeArray& getQuantizedNodeArray() - { - return m_quantizedContiguousNodes; + SIMD_FORCE_INLINE QuantizedNodeArray& getQuantizedNodeArray() + { + return m_quantizedContiguousNodes; } - - SIMD_FORCE_INLINE BvhSubtreeInfoArray& getSubtreeInfoArray() + SIMD_FORCE_INLINE BvhSubtreeInfoArray& getSubtreeInfoArray() { return m_SubtreeHeaders; } -//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////// /////Calculate space needed to store BVH for serialization unsigned calculateSerializeBufferSize() const; /// Data buffer MUST be 16 byte aligned - virtual bool serialize(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const; + virtual bool serialize(void* o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const; ///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place' - static btQuantizedBvh *deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian); + static btQuantizedBvh* deSerializeInPlace(void* i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian); static unsigned int getAlignmentSerializationPadding(); -////////////////////////////////////////////////////////////////////// + ////////////////////////////////////////////////////////////////////// - - virtual int calculateSerializeBufferSizeNew() const; + virtual int calculateSerializeBufferSizeNew() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; - virtual void deSerializeFloat(struct btQuantizedBvhFloatData& quantizedBvhFloatData); + virtual void deSerializeFloat(struct btQuantizedBvhFloatData & quantizedBvhFloatData); - virtual void deSerializeDouble(struct btQuantizedBvhDoubleData& quantizedBvhDoubleData); + virtual void deSerializeDouble(struct btQuantizedBvhDoubleData & quantizedBvhDoubleData); - -//////////////////////////////////////////////////////////////////// + //////////////////////////////////////////////////////////////////// SIMD_FORCE_INLINE bool isQuantized() { @@ -494,38 +459,37 @@ private: // Special "copy" constructor that allows for in-place deserialization // Prevents btVector3's default constructor from being called, but doesn't inialize much else // ownsMemory should most likely be false if deserializing, and if you are not, don't call this (it also changes the function signature, which we need) - btQuantizedBvh(btQuantizedBvh &other, bool ownsMemory); + btQuantizedBvh(btQuantizedBvh & other, bool ownsMemory); +}; -} -; - - -struct btBvhSubtreeInfoData +// clang-format off +// parser needs * with the name +struct btBvhSubtreeInfoData { - int m_rootNodeIndex; - int m_subtreeSize; + int m_rootNodeIndex; + int m_subtreeSize; unsigned short m_quantizedAabbMin[3]; unsigned short m_quantizedAabbMax[3]; }; struct btOptimizedBvhNodeFloatData { - btVector3FloatData m_aabbMinOrg; - btVector3FloatData m_aabbMaxOrg; - int m_escapeIndex; - int m_subPart; - int m_triangleIndex; + btVector3FloatData m_aabbMinOrg; + btVector3FloatData m_aabbMaxOrg; + int m_escapeIndex; + int m_subPart; + int m_triangleIndex; char m_pad[4]; }; struct btOptimizedBvhNodeDoubleData { - btVector3DoubleData m_aabbMinOrg; - btVector3DoubleData m_aabbMaxOrg; - int m_escapeIndex; - int m_subPart; - int m_triangleIndex; - char m_pad[4]; + btVector3DoubleData m_aabbMinOrg; + btVector3DoubleData m_aabbMaxOrg; + int m_escapeIndex; + int m_subPart; + int m_triangleIndex; + char m_pad[4]; }; @@ -569,13 +533,11 @@ struct btQuantizedBvhDoubleData int m_numSubtreeHeaders; btBvhSubtreeInfoData *m_subTreeInfoPtr; }; +// clang-format on - -SIMD_FORCE_INLINE int btQuantizedBvh::calculateSerializeBufferSizeNew() const +SIMD_FORCE_INLINE int btQuantizedBvh::calculateSerializeBufferSizeNew() const { return sizeof(btQuantizedBvhData); } - - -#endif //BT_QUANTIZED_BVH_H +#endif //BT_QUANTIZED_BVH_H diff --git a/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp b/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp index 5f89f960e..166cf771f 100644 --- a/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp +++ b/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.cpp @@ -24,50 +24,45 @@ subject to the following restrictions: #include -void btSimpleBroadphase::validate() +void btSimpleBroadphase::validate() { - for (int i=0;i= m_maxHandles) { btAssert(0); - return 0; //should never happen, but don't let the game crash ;-) + return 0; //should never happen, but don't let the game crash ;-) } - btAssert(aabbMin[0]<= aabbMax[0] && aabbMin[1]<= aabbMax[1] && aabbMin[2]<= aabbMax[2]); + btAssert(aabbMin[0] <= aabbMax[0] && aabbMin[1] <= aabbMax[1] && aabbMin[2] <= aabbMax[2]); int newHandleIndex = allocHandle(); - btSimpleBroadphaseProxy* proxy = new (&m_pHandles[newHandleIndex])btSimpleBroadphaseProxy(aabbMin,aabbMax,shapeType,userPtr,collisionFilterGroup,collisionFilterMask); + btSimpleBroadphaseProxy* proxy = new (&m_pHandles[newHandleIndex]) btSimpleBroadphaseProxy(aabbMin, aabbMax, shapeType, userPtr, collisionFilterGroup, collisionFilterMask); return proxy; } -class RemovingOverlapCallback : public btOverlapCallback +class RemovingOverlapCallback : public btOverlapCallback { protected: - virtual bool processOverlap(btBroadphasePair& pair) + virtual bool processOverlap(btBroadphasePair& pair) { (void)pair; btAssert(0); @@ -110,12 +104,13 @@ protected: class RemovePairContainingProxy { + btBroadphaseProxy* m_targetProxy; - btBroadphaseProxy* m_targetProxy; - public: +public: virtual ~RemovePairContainingProxy() { } + protected: virtual bool processOverlap(btBroadphasePair& pair) { @@ -126,38 +121,36 @@ protected: }; }; -void btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg,btDispatcher* dispatcher) +void btSimpleBroadphase::destroyProxy(btBroadphaseProxy* proxyOrg, btDispatcher* dispatcher) { - - btSimpleBroadphaseProxy* proxy0 = static_cast(proxyOrg); - freeHandle(proxy0); + btSimpleBroadphaseProxy* proxy0 = static_cast(proxyOrg); + freeHandle(proxy0); - m_pairCache->removeOverlappingPairsContainingProxy(proxyOrg,dispatcher); + m_pairCache->removeOverlappingPairsContainingProxy(proxyOrg, dispatcher); - //validate(); - + //validate(); } -void btSimpleBroadphase::getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const +void btSimpleBroadphase::getAabb(btBroadphaseProxy* proxy, btVector3& aabbMin, btVector3& aabbMax) const { const btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy); aabbMin = sbp->m_aabbMin; aabbMax = sbp->m_aabbMax; } -void btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* /*dispatcher*/) +void btSimpleBroadphase::setAabb(btBroadphaseProxy* proxy, const btVector3& aabbMin, const btVector3& aabbMax, btDispatcher* /*dispatcher*/) { btSimpleBroadphaseProxy* sbp = getSimpleProxyFromProxy(proxy); sbp->m_aabbMin = aabbMin; sbp->m_aabbMax = aabbMax; } -void btSimpleBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin,const btVector3& aabbMax) +void btSimpleBroadphase::rayTest(const btVector3& rayFrom, const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin, const btVector3& aabbMax) { - for (int i=0; i <= m_LastHandleIndex; i++) + for (int i = 0; i <= m_LastHandleIndex; i++) { btSimpleBroadphaseProxy* proxy = &m_pHandles[i]; - if(!proxy->m_clientObject) + if (!proxy->m_clientObject) { continue; } @@ -165,69 +158,59 @@ void btSimpleBroadphase::rayTest(const btVector3& rayFrom,const btVector3& rayTo } } - -void btSimpleBroadphase::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback) +void btSimpleBroadphase::aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback) { - for (int i=0; i <= m_LastHandleIndex; i++) + for (int i = 0; i <= m_LastHandleIndex; i++) { btSimpleBroadphaseProxy* proxy = &m_pHandles[i]; - if(!proxy->m_clientObject) + if (!proxy->m_clientObject) { continue; } - if (TestAabbAgainstAabb2(aabbMin,aabbMax,proxy->m_aabbMin,proxy->m_aabbMax)) + if (TestAabbAgainstAabb2(aabbMin, aabbMax, proxy->m_aabbMin, proxy->m_aabbMax)) { callback.process(proxy); } } } - - - - - - -bool btSimpleBroadphase::aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1) +bool btSimpleBroadphase::aabbOverlap(btSimpleBroadphaseProxy* proxy0, btSimpleBroadphaseProxy* proxy1) { - return proxy0->m_aabbMin[0] <= proxy1->m_aabbMax[0] && proxy1->m_aabbMin[0] <= proxy0->m_aabbMax[0] && + return proxy0->m_aabbMin[0] <= proxy1->m_aabbMax[0] && proxy1->m_aabbMin[0] <= proxy0->m_aabbMax[0] && proxy0->m_aabbMin[1] <= proxy1->m_aabbMax[1] && proxy1->m_aabbMin[1] <= proxy0->m_aabbMax[1] && proxy0->m_aabbMin[2] <= proxy1->m_aabbMax[2] && proxy1->m_aabbMin[2] <= proxy0->m_aabbMax[2]; - } - - //then remove non-overlapping ones class CheckOverlapCallback : public btOverlapCallback { public: virtual bool processOverlap(btBroadphasePair& pair) { - return (!btSimpleBroadphase::aabbOverlap(static_cast(pair.m_pProxy0),static_cast(pair.m_pProxy1))); + return (!btSimpleBroadphase::aabbOverlap(static_cast(pair.m_pProxy0), static_cast(pair.m_pProxy1))); } }; -void btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) +void btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) { //first check for new overlapping pairs - int i,j; + int i, j; if (m_numHandles >= 0) { int new_largest_index = -1; - for (i=0; i <= m_LastHandleIndex; i++) + for (i = 0; i <= m_LastHandleIndex; i++) { btSimpleBroadphaseProxy* proxy0 = &m_pHandles[i]; - if(!proxy0->m_clientObject) + if (!proxy0->m_clientObject) { continue; } new_largest_index = i; - for (j=i+1; j <= m_LastHandleIndex; j++) + for (j = i + 1; j <= m_LastHandleIndex; j++) { btSimpleBroadphaseProxy* proxy1 = &m_pHandles[j]; btAssert(proxy0 != proxy1); - if(!proxy1->m_clientObject) + if (!proxy1->m_clientObject) { continue; } @@ -235,19 +218,20 @@ void btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0); btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1); - if (aabbOverlap(p0,p1)) + if (aabbOverlap(p0, p1)) { - if ( !m_pairCache->findPair(proxy0,proxy1)) + if (!m_pairCache->findPair(proxy0, proxy1)) { - m_pairCache->addOverlappingPair(proxy0,proxy1); + m_pairCache->addOverlappingPair(proxy0, proxy1); } - } else + } + else { if (!m_pairCache->hasDeferredRemoval()) { - if ( m_pairCache->findPair(proxy0,proxy1)) + if (m_pairCache->findPair(proxy0, proxy1)) { - m_pairCache->removeOverlappingPair(proxy0,proxy1,dispatcher); + m_pairCache->removeOverlappingPair(proxy0, proxy1, dispatcher); } } } @@ -258,8 +242,7 @@ void btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) if (m_ownsPairCache && m_pairCache->hasDeferredRemoval()) { - - btBroadphasePairArray& overlappingPairArray = m_pairCache->getOverlappingPairArray(); + btBroadphasePairArray& overlappingPairArray = m_pairCache->getOverlappingPairArray(); //perform a sort, to find duplicates and to sort 'invalid' pairs to the end overlappingPairArray.quickSort(btBroadphasePairSortPredicate()); @@ -267,16 +250,13 @@ void btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); m_invalidPair = 0; - btBroadphasePair previousPair; previousPair.m_pProxy0 = 0; previousPair.m_pProxy1 = 0; previousPair.m_algorithm = 0; - - for (i=0;iprocessOverlap(pair); - } else + needsRemoval = false; //callback->processOverlap(pair); + } + else { needsRemoval = true; } - } else + } + else { //remove duplicate needsRemoval = true; @@ -306,7 +288,7 @@ void btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) if (needsRemoval) { - m_pairCache->cleanOverlappingPair(pair,dispatcher); + m_pairCache->cleanOverlappingPair(pair, dispatcher); // m_overlappingPairArray.swap(i,m_overlappingPairArray.size()-1); // m_overlappingPairArray.pop_back(); @@ -314,7 +296,6 @@ void btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) pair.m_pProxy1 = 0; m_invalidPair++; } - } ///if you don't like to skip the invalid pairs in the array, execute following code: @@ -326,21 +307,19 @@ void btSimpleBroadphase::calculateOverlappingPairs(btDispatcher* dispatcher) overlappingPairArray.resize(overlappingPairArray.size() - m_invalidPair); m_invalidPair = 0; -#endif//CLEAN_INVALID_PAIRS - +#endif //CLEAN_INVALID_PAIRS } } } - -bool btSimpleBroadphase::testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) +bool btSimpleBroadphase::testAabbOverlap(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) { btSimpleBroadphaseProxy* p0 = getSimpleProxyFromProxy(proxy0); btSimpleBroadphaseProxy* p1 = getSimpleProxyFromProxy(proxy1); - return aabbOverlap(p0,p1); + return aabbOverlap(p0, p1); } -void btSimpleBroadphase::resetPool(btDispatcher* dispatcher) +void btSimpleBroadphase::resetPool(btDispatcher* dispatcher) { //not yet } diff --git a/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h b/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h index d7a18e400..3e02fdc00 100644 --- a/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h +++ b/src/BulletCollision/BroadphaseCollision/btSimpleBroadphase.h @@ -16,57 +16,47 @@ subject to the following restrictions: #ifndef BT_SIMPLE_BROADPHASE_H #define BT_SIMPLE_BROADPHASE_H - #include "btOverlappingPairCache.h" - struct btSimpleBroadphaseProxy : public btBroadphaseProxy { - int m_nextFree; - -// int m_handleId; + int m_nextFree; - - btSimpleBroadphaseProxy() {}; + // int m_handleId; - btSimpleBroadphaseProxy(const btVector3& minpt,const btVector3& maxpt,int shapeType,void* userPtr, int collisionFilterGroup, int collisionFilterMask) - :btBroadphaseProxy(minpt,maxpt,userPtr,collisionFilterGroup,collisionFilterMask) + btSimpleBroadphaseProxy(){}; + + btSimpleBroadphaseProxy(const btVector3& minpt, const btVector3& maxpt, int shapeType, void* userPtr, int collisionFilterGroup, int collisionFilterMask) + : btBroadphaseProxy(minpt, maxpt, userPtr, collisionFilterGroup, collisionFilterMask) { (void)shapeType; } - - - SIMD_FORCE_INLINE void SetNextFree(int next) {m_nextFree = next;} - SIMD_FORCE_INLINE int GetNextFree() const {return m_nextFree;} - - - + SIMD_FORCE_INLINE void SetNextFree(int next) { m_nextFree = next; } + SIMD_FORCE_INLINE int GetNextFree() const { return m_nextFree; } }; ///The SimpleBroadphase is just a unit-test for btAxisSweep3, bt32BitAxisSweep3, or btDbvtBroadphase, so use those classes instead. ///It is a brute force aabb culling broadphase based on O(n^2) aabb checks class btSimpleBroadphase : public btBroadphaseInterface { - protected: + int m_numHandles; // number of active handles + int m_maxHandles; // max number of handles + int m_LastHandleIndex; - int m_numHandles; // number of active handles - int m_maxHandles; // max number of handles - int m_LastHandleIndex; - - btSimpleBroadphaseProxy* m_pHandles; // handles pool + btSimpleBroadphaseProxy* m_pHandles; // handles pool void* m_pHandlesRawPtr; - int m_firstFreeHandle; // free handles list - + int m_firstFreeHandle; // free handles list + int allocHandle() { btAssert(m_numHandles < m_maxHandles); int freeHandle = m_firstFreeHandle; m_firstFreeHandle = m_pHandles[freeHandle].GetNextFree(); m_numHandles++; - if(freeHandle > m_LastHandleIndex) + if (freeHandle > m_LastHandleIndex) { m_LastHandleIndex = freeHandle; } @@ -75,9 +65,9 @@ protected: void freeHandle(btSimpleBroadphaseProxy* proxy) { - int handle = int(proxy-m_pHandles); + int handle = int(proxy - m_pHandles); btAssert(handle >= 0 && handle < m_maxHandles); - if(handle == m_LastHandleIndex) + if (handle == m_LastHandleIndex) { m_LastHandleIndex--; } @@ -89,20 +79,18 @@ protected: m_numHandles--; } - btOverlappingPairCache* m_pairCache; - bool m_ownsPairCache; + btOverlappingPairCache* m_pairCache; + bool m_ownsPairCache; - int m_invalidPair; + int m_invalidPair; - - - inline btSimpleBroadphaseProxy* getSimpleProxyFromProxy(btBroadphaseProxy* proxy) + inline btSimpleBroadphaseProxy* getSimpleProxyFromProxy(btBroadphaseProxy* proxy) { btSimpleBroadphaseProxy* proxy0 = static_cast(proxy); return proxy0; } - inline const btSimpleBroadphaseProxy* getSimpleProxyFromProxy(btBroadphaseProxy* proxy) const + inline const btSimpleBroadphaseProxy* getSimpleProxyFromProxy(btBroadphaseProxy* proxy) const { const btSimpleBroadphaseProxy* proxy0 = static_cast(proxy); return proxy0; @@ -111,61 +99,50 @@ protected: ///reset broadphase internal structures, to ensure determinism/reproducability virtual void resetPool(btDispatcher* dispatcher); - - void validate(); + void validate(); protected: - - - - public: - btSimpleBroadphase(int maxProxies=16384,btOverlappingPairCache* overlappingPairCache=0); + btSimpleBroadphase(int maxProxies = 16384, btOverlappingPairCache* overlappingPairCache = 0); virtual ~btSimpleBroadphase(); + static bool aabbOverlap(btSimpleBroadphaseProxy* proxy0, btSimpleBroadphaseProxy* proxy1); - static bool aabbOverlap(btSimpleBroadphaseProxy* proxy0,btSimpleBroadphaseProxy* proxy1); + virtual btBroadphaseProxy* createProxy(const btVector3& aabbMin, const btVector3& aabbMax, int shapeType, void* userPtr, int collisionFilterGroup, int collisionFilterMask, btDispatcher* dispatcher); + virtual void calculateOverlappingPairs(btDispatcher* dispatcher); - virtual btBroadphaseProxy* createProxy( const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr , int collisionFilterGroup, int collisionFilterMask, btDispatcher* dispatcher); + virtual void destroyProxy(btBroadphaseProxy* proxy, btDispatcher* dispatcher); + virtual void setAabb(btBroadphaseProxy* proxy, const btVector3& aabbMin, const btVector3& aabbMax, btDispatcher* dispatcher); + virtual void getAabb(btBroadphaseProxy* proxy, btVector3& aabbMin, btVector3& aabbMax) const; - virtual void calculateOverlappingPairs(btDispatcher* dispatcher); + virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin = btVector3(0, 0, 0), const btVector3& aabbMax = btVector3(0, 0, 0)); + virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback); - virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher); - virtual void setAabb(btBroadphaseProxy* proxy,const btVector3& aabbMin,const btVector3& aabbMax, btDispatcher* dispatcher); - virtual void getAabb(btBroadphaseProxy* proxy,btVector3& aabbMin, btVector3& aabbMax ) const; - - virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback, const btVector3& aabbMin=btVector3(0,0,0),const btVector3& aabbMax=btVector3(0,0,0)); - virtual void aabbTest(const btVector3& aabbMin, const btVector3& aabbMax, btBroadphaseAabbCallback& callback); - - btOverlappingPairCache* getOverlappingPairCache() + btOverlappingPairCache* getOverlappingPairCache() { return m_pairCache; } - const btOverlappingPairCache* getOverlappingPairCache() const + const btOverlappingPairCache* getOverlappingPairCache() const { return m_pairCache; } - bool testAabbOverlap(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1); - + bool testAabbOverlap(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1); ///getAabb returns the axis aligned bounding box in the 'global' coordinate frame ///will add some transform later - virtual void getBroadphaseAabb(btVector3& aabbMin,btVector3& aabbMax) const + virtual void getBroadphaseAabb(btVector3& aabbMin, btVector3& aabbMax) const { - aabbMin.setValue(-BT_LARGE_FLOAT,-BT_LARGE_FLOAT,-BT_LARGE_FLOAT); - aabbMax.setValue(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT); + aabbMin.setValue(-BT_LARGE_FLOAT, -BT_LARGE_FLOAT, -BT_LARGE_FLOAT); + aabbMax.setValue(BT_LARGE_FLOAT, BT_LARGE_FLOAT, BT_LARGE_FLOAT); } - virtual void printStats() + virtual void printStats() { -// printf("btSimpleBroadphase.h\n"); -// printf("numHandles = %d, maxHandles = %d\n",m_numHandles,m_maxHandles); + // printf("btSimpleBroadphase.h\n"); + // printf("numHandles = %d, maxHandles = %d\n",m_numHandles,m_maxHandles); } }; - - -#endif //BT_SIMPLE_BROADPHASE_H - +#endif //BT_SIMPLE_BROADPHASE_H diff --git a/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp b/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp index e5bac8438..7647f6736 100644 --- a/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp +++ b/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.cpp @@ -18,94 +18,95 @@ subject to the following restrictions: #include "BulletCollision/CollisionShapes/btTriangleShape.h" #include "BulletCollision/CollisionShapes/btSphereShape.h" - -SphereTriangleDetector::SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle,btScalar contactBreakingThreshold) -:m_sphere(sphere), -m_triangle(triangle), -m_contactBreakingThreshold(contactBreakingThreshold) +SphereTriangleDetector::SphereTriangleDetector(btSphereShape* sphere, btTriangleShape* triangle, btScalar contactBreakingThreshold) + : m_sphere(sphere), + m_triangle(triangle), + m_contactBreakingThreshold(contactBreakingThreshold) { - } -void SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults) +void SphereTriangleDetector::getClosestPoints(const ClosestPointInput& input, Result& output, class btIDebugDraw* debugDraw, bool swapResults) { - (void)debugDraw; const btTransform& transformA = input.m_transformA; const btTransform& transformB = input.m_transformB; - btVector3 point,normal; + btVector3 point, normal; btScalar timeOfImpact = btScalar(1.); btScalar depth = btScalar(0.); -// output.m_distance = btScalar(BT_LARGE_FLOAT); + // output.m_distance = btScalar(BT_LARGE_FLOAT); //move sphere into triangle space - btTransform sphereInTr = transformB.inverseTimes(transformA); + btTransform sphereInTr = transformB.inverseTimes(transformA); - if (collide(sphereInTr.getOrigin(),point,normal,depth,timeOfImpact,m_contactBreakingThreshold)) + if (collide(sphereInTr.getOrigin(), point, normal, depth, timeOfImpact, m_contactBreakingThreshold)) { if (swapResults) { - btVector3 normalOnB = transformB.getBasis()*normal; + btVector3 normalOnB = transformB.getBasis() * normal; btVector3 normalOnA = -normalOnB; - btVector3 pointOnA = transformB*point+normalOnB*depth; - output.addContactPoint(normalOnA,pointOnA,depth); - } else + btVector3 pointOnA = transformB * point + normalOnB * depth; + output.addContactPoint(normalOnA, pointOnA, depth); + } + else { - output.addContactPoint(transformB.getBasis()*normal,transformB*point,depth); + output.addContactPoint(transformB.getBasis() * normal, transformB * point, depth); } } - } - - // See also geometrictools.com // Basic idea: D = |p - (lo + t0*lv)| where t0 = lv . (p - lo) / lv . lv -btScalar SegmentSqrDistance(const btVector3& from, const btVector3& to,const btVector3 &p, btVector3 &nearest); +btScalar SegmentSqrDistance(const btVector3& from, const btVector3& to, const btVector3& p, btVector3& nearest); -btScalar SegmentSqrDistance(const btVector3& from, const btVector3& to,const btVector3 &p, btVector3 &nearest) { +btScalar SegmentSqrDistance(const btVector3& from, const btVector3& to, const btVector3& p, btVector3& nearest) +{ btVector3 diff = p - from; btVector3 v = to - from; btScalar t = v.dot(diff); - - if (t > 0) { + + if (t > 0) + { btScalar dotVV = v.dot(v); - if (t < dotVV) { + if (t < dotVV) + { t /= dotVV; - diff -= t*v; - } else { + diff -= t * v; + } + else + { t = 1; diff -= v; } - } else + } + else t = 0; - nearest = from + t*v; - return diff.dot(diff); + nearest = from + t * v; + return diff.dot(diff); } -bool SphereTriangleDetector::facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal) { +bool SphereTriangleDetector::facecontains(const btVector3& p, const btVector3* vertices, btVector3& normal) +{ btVector3 lp(p); btVector3 lnormal(normal); - + return pointInTriangle(vertices, lnormal, &lp); } -bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold) +bool SphereTriangleDetector::collide(const btVector3& sphereCenter, btVector3& point, btVector3& resultNormal, btScalar& depth, btScalar& timeOfImpact, btScalar contactBreakingThreshold) { - const btVector3* vertices = &m_triangle->getVertexPtr(0); - + btScalar radius = m_sphere->getRadius(); btScalar radiusWithThreshold = radius + contactBreakingThreshold; - btVector3 normal = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[0]); + btVector3 normal = (vertices[1] - vertices[0]).cross(vertices[2] - vertices[0]); btScalar l2 = normal.length2(); bool hasContact = false; btVector3 contactPoint; - if (l2 >= SIMD_EPSILON*SIMD_EPSILON) + if (l2 >= SIMD_EPSILON * SIMD_EPSILON) { normal /= btSqrt(l2); @@ -120,54 +121,59 @@ bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &po } bool isInsideContactPlane = distanceFromPlane < radiusWithThreshold; - + // Check for contact / intersection - - if (isInsideContactPlane) { - if (facecontains(sphereCenter, vertices, normal)) { + + if (isInsideContactPlane) + { + if (facecontains(sphereCenter, vertices, normal)) + { // Inside the contact wedge - touches a point on the shell plane hasContact = true; - contactPoint = sphereCenter - normal*distanceFromPlane; + contactPoint = sphereCenter - normal * distanceFromPlane; } - else { + else + { // Could be inside one of the contact capsules - btScalar contactCapsuleRadiusSqr = radiusWithThreshold*radiusWithThreshold; + btScalar contactCapsuleRadiusSqr = radiusWithThreshold * radiusWithThreshold; btScalar minDistSqr = contactCapsuleRadiusSqr; btVector3 nearestOnEdge; - for (int i = 0; i < m_triangle->getNumEdges(); i++) { - + for (int i = 0; i < m_triangle->getNumEdges(); i++) + { btVector3 pa; btVector3 pb; m_triangle->getEdge(i, pa, pb); btScalar distanceSqr = SegmentSqrDistance(pa, pb, sphereCenter, nearestOnEdge); - if (distanceSqr < minDistSqr) { + if (distanceSqr < minDistSqr) + { // Yep, we're inside a capsule, and record the capsule with smallest distance minDistSqr = distanceSqr; hasContact = true; contactPoint = nearestOnEdge; } - } } } } - if (hasContact) { + if (hasContact) + { btVector3 contactToCentre = sphereCenter - contactPoint; btScalar distanceSqr = contactToCentre.length2(); - if (distanceSqr < radiusWithThreshold*radiusWithThreshold) + if (distanceSqr < radiusWithThreshold * radiusWithThreshold) { - if (distanceSqr>SIMD_EPSILON) + if (distanceSqr > SIMD_EPSILON) { btScalar distance = btSqrt(distanceSqr); resultNormal = contactToCentre; resultNormal.normalize(); point = contactPoint; - depth = -(radius-distance); - } else + depth = -(radius - distance); + } + else { resultNormal = normal; point = contactPoint; @@ -176,36 +182,34 @@ bool SphereTriangleDetector::collide(const btVector3& sphereCenter,btVector3 &po return true; } } - + return false; } - -bool SphereTriangleDetector::pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p ) +bool SphereTriangleDetector::pointInTriangle(const btVector3 vertices[], const btVector3& normal, btVector3* p) { const btVector3* p1 = &vertices[0]; const btVector3* p2 = &vertices[1]; const btVector3* p3 = &vertices[2]; - btVector3 edge1( *p2 - *p1 ); - btVector3 edge2( *p3 - *p2 ); - btVector3 edge3( *p1 - *p3 ); + btVector3 edge1(*p2 - *p1); + btVector3 edge2(*p3 - *p2); + btVector3 edge3(*p1 - *p3); - btVector3 p1_to_p( *p - *p1 ); - btVector3 p2_to_p( *p - *p2 ); - btVector3 p3_to_p( *p - *p3 ); + btVector3 p1_to_p(*p - *p1); + btVector3 p2_to_p(*p - *p2); + btVector3 p3_to_p(*p - *p3); + + btVector3 edge1_normal(edge1.cross(normal)); + btVector3 edge2_normal(edge2.cross(normal)); + btVector3 edge3_normal(edge3.cross(normal)); - btVector3 edge1_normal( edge1.cross(normal)); - btVector3 edge2_normal( edge2.cross(normal)); - btVector3 edge3_normal( edge3.cross(normal)); - btScalar r1, r2, r3; - r1 = edge1_normal.dot( p1_to_p ); - r2 = edge2_normal.dot( p2_to_p ); - r3 = edge3_normal.dot( p3_to_p ); - if ( ( r1 > 0 && r2 > 0 && r3 > 0 ) || - ( r1 <= 0 && r2 <= 0 && r3 <= 0 ) ) + r1 = edge1_normal.dot(p1_to_p); + r2 = edge2_normal.dot(p2_to_p); + r3 = edge3_normal.dot(p3_to_p); + if ((r1 > 0 && r2 > 0 && r3 > 0) || + (r1 <= 0 && r2 <= 0 && r3 <= 0)) return true; return false; - } diff --git a/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h b/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h index 22953af43..d47e47530 100644 --- a/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h +++ b/src/BulletCollision/CollisionDispatch/SphereTriangleDetector.h @@ -18,34 +18,26 @@ subject to the following restrictions: #include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" - - class btSphereShape; class btTriangleShape; - - /// sphere-triangle to match the btDiscreteCollisionDetectorInterface struct SphereTriangleDetector : public btDiscreteCollisionDetectorInterface { - virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false); + virtual void getClosestPoints(const ClosestPointInput& input, Result& output, class btIDebugDraw* debugDraw, bool swapResults = false); - SphereTriangleDetector(btSphereShape* sphere,btTriangleShape* triangle, btScalar contactBreakingThreshold); + SphereTriangleDetector(btSphereShape* sphere, btTriangleShape* triangle, btScalar contactBreakingThreshold); - virtual ~SphereTriangleDetector() {}; + virtual ~SphereTriangleDetector(){}; - bool collide(const btVector3& sphereCenter,btVector3 &point, btVector3& resultNormal, btScalar& depth, btScalar &timeOfImpact, btScalar contactBreakingThreshold); + bool collide(const btVector3& sphereCenter, btVector3& point, btVector3& resultNormal, btScalar& depth, btScalar& timeOfImpact, btScalar contactBreakingThreshold); private: - - - bool pointInTriangle(const btVector3 vertices[], const btVector3 &normal, btVector3 *p ); - bool facecontains(const btVector3 &p,const btVector3* vertices,btVector3& normal); + bool pointInTriangle(const btVector3 vertices[], const btVector3& normal, btVector3* p); + bool facecontains(const btVector3& p, const btVector3* vertices, btVector3& normal); btSphereShape* m_sphere; btTriangleShape* m_triangle; - btScalar m_contactBreakingThreshold; - + btScalar m_contactBreakingThreshold; }; -#endif //BT_SPHERE_TRIANGLE_DETECTOR_H - +#endif //BT_SPHERE_TRIANGLE_DETECTOR_H diff --git a/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp index 57f146493..ac5de45d2 100644 --- a/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp +++ b/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.cpp @@ -17,31 +17,31 @@ subject to the following restrictions: #include "btCollisionDispatcher.h" #include "btCollisionObject.h" -btActivatingCollisionAlgorithm::btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci) -:btCollisionAlgorithm(ci) +btActivatingCollisionAlgorithm::btActivatingCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) + : btCollisionAlgorithm(ci) //, //m_colObj0(0), //m_colObj1(0) { } -btActivatingCollisionAlgorithm::btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* ,const btCollisionObjectWrapper* ) -:btCollisionAlgorithm(ci) +btActivatingCollisionAlgorithm::btActivatingCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper*, const btCollisionObjectWrapper*) + : btCollisionAlgorithm(ci) //, //m_colObj0(0), //m_colObj1(0) { -// if (ci.m_dispatcher1->needsCollision(colObj0,colObj1)) -// { -// m_colObj0 = colObj0; -// m_colObj1 = colObj1; -// -// m_colObj0->activate(); -// m_colObj1->activate(); -// } + // if (ci.m_dispatcher1->needsCollision(colObj0,colObj1)) + // { + // m_colObj0 = colObj0; + // m_colObj1 = colObj1; + // + // m_colObj0->activate(); + // m_colObj1->activate(); + // } } btActivatingCollisionAlgorithm::~btActivatingCollisionAlgorithm() { -// m_colObj0->activate(); -// m_colObj1->activate(); + // m_colObj0->activate(); + // m_colObj1->activate(); } diff --git a/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h index 0e19f1ea3..862060571 100644 --- a/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h +++ b/src/BulletCollision/CollisionDispatch/btActivatingCollisionAlgorithm.h @@ -21,17 +21,15 @@ subject to the following restrictions: ///This class is not enabled yet (work-in-progress) to more aggressively activate objects. class btActivatingCollisionAlgorithm : public btCollisionAlgorithm { -// btCollisionObject* m_colObj0; -// btCollisionObject* m_colObj1; + // btCollisionObject* m_colObj0; + // btCollisionObject* m_colObj1; protected: + btActivatingCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci); - btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci); - - btActivatingCollisionAlgorithm (const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap); + btActivatingCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap); public: virtual ~btActivatingCollisionAlgorithm(); - }; -#endif //__BT_ACTIVATING_COLLISION_ALGORITHM_H +#endif //__BT_ACTIVATING_COLLISION_ALGORITHM_H diff --git a/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp index cabbb0bf6..6873a95d9 100644 --- a/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp +++ b/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.cpp @@ -26,61 +26,55 @@ subject to the following restrictions: #define USE_PERSISTENT_CONTACTS 1 -btBox2dBox2dCollisionAlgorithm::btBox2dBox2dCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* obj0Wrap,const btCollisionObjectWrapper* obj1Wrap) -: btActivatingCollisionAlgorithm(ci,obj0Wrap,obj1Wrap), -m_ownManifold(false), -m_manifoldPtr(mf) +btBox2dBox2dCollisionAlgorithm::btBox2dBox2dCollisionAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* obj0Wrap, const btCollisionObjectWrapper* obj1Wrap) + : btActivatingCollisionAlgorithm(ci, obj0Wrap, obj1Wrap), + m_ownManifold(false), + m_manifoldPtr(mf) { - if (!m_manifoldPtr && m_dispatcher->needsCollision(obj0Wrap->getCollisionObject(),obj1Wrap->getCollisionObject())) + if (!m_manifoldPtr && m_dispatcher->needsCollision(obj0Wrap->getCollisionObject(), obj1Wrap->getCollisionObject())) { - m_manifoldPtr = m_dispatcher->getNewManifold(obj0Wrap->getCollisionObject(),obj1Wrap->getCollisionObject()); + m_manifoldPtr = m_dispatcher->getNewManifold(obj0Wrap->getCollisionObject(), obj1Wrap->getCollisionObject()); m_ownManifold = true; } } btBox2dBox2dCollisionAlgorithm::~btBox2dBox2dCollisionAlgorithm() { - if (m_ownManifold) { if (m_manifoldPtr) m_dispatcher->releaseManifold(m_manifoldPtr); } - } - -void b2CollidePolygons(btManifoldResult* manifold, const btBox2dShape* polyA, const btTransform& xfA, const btBox2dShape* polyB, const btTransform& xfB); +void b2CollidePolygons(btManifoldResult* manifold, const btBox2dShape* polyA, const btTransform& xfA, const btBox2dShape* polyB, const btTransform& xfB); //#include -void btBox2dBox2dCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +void btBox2dBox2dCollisionAlgorithm::processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { if (!m_manifoldPtr) return; - const btBox2dShape* box0 = (const btBox2dShape*)body0Wrap->getCollisionShape(); const btBox2dShape* box1 = (const btBox2dShape*)body1Wrap->getCollisionShape(); resultOut->setPersistentManifold(m_manifoldPtr); - b2CollidePolygons(resultOut,box0,body0Wrap->getWorldTransform(),box1,body1Wrap->getWorldTransform()); + b2CollidePolygons(resultOut, box0, body0Wrap->getWorldTransform(), box1, body1Wrap->getWorldTransform()); // refreshContactPoints is only necessary when using persistent contact points. otherwise all points are newly added if (m_ownManifold) { resultOut->refreshContactPoints(); } - } -btScalar btBox2dBox2dCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* /*body0*/,btCollisionObject* /*body1*/,const btDispatcherInfo& /*dispatchInfo*/,btManifoldResult* /*resultOut*/) +btScalar btBox2dBox2dCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* /*body0*/, btCollisionObject* /*body1*/, const btDispatcherInfo& /*dispatchInfo*/, btManifoldResult* /*resultOut*/) { //not yet return 1.f; } - struct ClipVertex { btVector3 v; @@ -89,16 +83,16 @@ struct ClipVertex //b2ContactID id; }; -#define b2Dot(a,b) (a).dot(b) -#define b2Mul(a,b) (a)*(b) -#define b2MulT(a,b) (a).transpose()*(b) -#define b2Cross(a,b) (a).cross(b) -#define btCrossS(a,s) btVector3(s * a.getY(), -s * a.getX(),0.f) +#define b2Dot(a, b) (a).dot(b) +#define b2Mul(a, b) (a) * (b) +#define b2MulT(a, b) (a).transpose() * (b) +#define b2Cross(a, b) (a).cross(b) +#define btCrossS(a, s) btVector3(s* a.getY(), -s* a.getX(), 0.f) -int b2_maxManifoldPoints =2; +int b2_maxManifoldPoints = 2; static int ClipSegmentToLine(ClipVertex vOut[2], ClipVertex vIn[2], - const btVector3& normal, btScalar offset) + const btVector3& normal, btScalar offset) { // Start with no output points int numOut = 0; @@ -133,7 +127,7 @@ static int ClipSegmentToLine(ClipVertex vOut[2], ClipVertex vIn[2], // Find the separation between poly1 and poly2 for a give edge normal on poly1. static btScalar EdgeSeparation(const btBox2dShape* poly1, const btTransform& xf1, int edge1, - const btBox2dShape* poly2, const btTransform& xf2) + const btBox2dShape* poly2, const btTransform& xf2) { const btVector3* vertices1 = poly1->getVertices(); const btVector3* normals1 = poly1->getNormals(); @@ -151,8 +145,8 @@ static btScalar EdgeSeparation(const btBox2dShape* poly1, const btTransform& xf1 int index = 0; btScalar minDot = BT_LARGE_FLOAT; - if( count2 > 0 ) - index = (int) normal1.minDot( vertices2, count2, minDot); + if (count2 > 0) + index = (int)normal1.minDot(vertices2, count2, minDot); btVector3 v1 = b2Mul(xf1, vertices1[edge1]); btVector3 v2 = b2Mul(xf2, vertices2[index]); @@ -162,8 +156,8 @@ static btScalar EdgeSeparation(const btBox2dShape* poly1, const btTransform& xf1 // Find the max separation between poly1 and poly2 using edge normals from poly1. static btScalar FindMaxSeparation(int* edgeIndex, - const btBox2dShape* poly1, const btTransform& xf1, - const btBox2dShape* poly2, const btTransform& xf2) + const btBox2dShape* poly1, const btTransform& xf1, + const btBox2dShape* poly2, const btTransform& xf2) { int count1 = poly1->getVertexCount(); const btVector3* normals1 = poly1->getNormals(); @@ -174,9 +168,9 @@ static btScalar FindMaxSeparation(int* edgeIndex, // Find edge normal on poly1 that has the largest projection onto d. int edge = 0; - btScalar maxDot; - if( count1 > 0 ) - edge = (int) dLocal1.maxDot( normals1, count1, maxDot); + btScalar maxDot; + if (count1 > 0) + edge = (int)dLocal1.maxDot(normals1, count1, maxDot); // Get the separation for the edge normal. btScalar s = EdgeSeparation(poly1, xf1, edge, poly2, xf2); @@ -224,7 +218,7 @@ static btScalar FindMaxSeparation(int* edgeIndex, } // Perform a local search for the best edge normal. - for ( ; ; ) + for (;;) { if (increment == -1) edge = bestEdge - 1 >= 0 ? bestEdge - 1 : count1 - 1; @@ -285,14 +279,14 @@ static void FindIncidentEdge(ClipVertex c[2], int i2 = i1 + 1 < count2 ? i1 + 1 : 0; c[0].v = b2Mul(xf2, vertices2[i1]); -// c[0].id.features.referenceEdge = (unsigned char)edge1; -// c[0].id.features.incidentEdge = (unsigned char)i1; -// c[0].id.features.incidentVertex = 0; + // c[0].id.features.referenceEdge = (unsigned char)edge1; + // c[0].id.features.incidentEdge = (unsigned char)i1; + // c[0].id.features.incidentVertex = 0; c[1].v = b2Mul(xf2, vertices2[i2]); -// c[1].id.features.referenceEdge = (unsigned char)edge1; -// c[1].id.features.incidentEdge = (unsigned char)i2; -// c[1].id.features.incidentVertex = 1; + // c[1].id.features.referenceEdge = (unsigned char)edge1; + // c[1].id.features.incidentEdge = (unsigned char)i2; + // c[1].id.features.incidentVertex = 1; } // Find edge normal of max separation on A - return if separating axis is found @@ -303,10 +297,9 @@ static void FindIncidentEdge(ClipVertex c[2], // The normal points from 1 to 2 void b2CollidePolygons(btManifoldResult* manifold, - const btBox2dShape* polyA, const btTransform& xfA, - const btBox2dShape* polyB, const btTransform& xfB) + const btBox2dShape* polyA, const btTransform& xfA, + const btBox2dShape* polyB, const btTransform& xfB) { - int edgeA = 0; btScalar separationA = FindMaxSeparation(&edgeA, polyA, xfA, polyB, xfB); if (separationA > 0.0f) @@ -317,10 +310,10 @@ void b2CollidePolygons(btManifoldResult* manifold, if (separationB > 0.0f) return; - const btBox2dShape* poly1; // reference poly - const btBox2dShape* poly2; // incident poly + const btBox2dShape* poly1; // reference poly + const btBox2dShape* poly2; // incident poly btTransform xf1, xf2; - int edge1; // reference edge + int edge1; // reference edge unsigned char flip; const btScalar k_relativeTol = 0.98f; const btScalar k_absoluteTol = 0.001f; @@ -352,14 +345,13 @@ void b2CollidePolygons(btManifoldResult* manifold, const btVector3* vertices1 = poly1->getVertices(); btVector3 v11 = vertices1[edge1]; - btVector3 v12 = edge1 + 1 < count1 ? vertices1[edge1+1] : vertices1[0]; + btVector3 v12 = edge1 + 1 < count1 ? vertices1[edge1 + 1] : vertices1[0]; //btVector3 dv = v12 - v11; btVector3 sideNormal = b2Mul(xf1.getBasis(), v12 - v11); sideNormal.normalize(); btVector3 frontNormal = btCrossS(sideNormal, 1.0f); - - + v11 = b2Mul(xf1, v11); v12 = b2Mul(xf1, v12); @@ -369,13 +361,12 @@ void b2CollidePolygons(btManifoldResult* manifold, // Clip incident edge against extruded edge1 side edges. ClipVertex clipPoints1[2]; - clipPoints1[0].v.setValue(0,0,0); - clipPoints1[1].v.setValue(0,0,0); + clipPoints1[0].v.setValue(0, 0, 0); + clipPoints1[1].v.setValue(0, 0, 0); ClipVertex clipPoints2[2]; - clipPoints2[0].v.setValue(0,0,0); - clipPoints2[1].v.setValue(0,0,0); - + clipPoints2[0].v.setValue(0, 0, 0); + clipPoints2[1].v.setValue(0, 0, 0); int np; @@ -386,7 +377,7 @@ void b2CollidePolygons(btManifoldResult* manifold, return; // Clip to negative box side 1 - np = ClipSegmentToLine(clipPoints2, clipPoints1, sideNormal, sideOffset2); + np = ClipSegmentToLine(clipPoints2, clipPoints1, sideNormal, sideOffset2); if (np < 2) { @@ -403,19 +394,18 @@ void b2CollidePolygons(btManifoldResult* manifold, if (separation <= 0.0f) { - //b2ManifoldPoint* cp = manifold->points + pointCount; //btScalar separation = separation; //cp->localPoint1 = b2MulT(xfA, clipPoints2[i].v); //cp->localPoint2 = b2MulT(xfB, clipPoints2[i].v); - manifold->addContactPoint(-manifoldNormal,clipPoints2[i].v,separation); + manifold->addContactPoint(-manifoldNormal, clipPoints2[i].v, separation); -// cp->id = clipPoints2[i].id; -// cp->id.features.flip = flip; + // cp->id = clipPoints2[i].id; + // cp->id.features.flip = flip; ++pointCount; } } -// manifold->pointCount = pointCount;} + // manifold->pointCount = pointCount;} } diff --git a/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h index 6ea6e89bd..3b66d1fd0 100644 --- a/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h +++ b/src/BulletCollision/CollisionDispatch/btBox2dBox2dCollisionAlgorithm.h @@ -26,22 +26,22 @@ class btPersistentManifold; ///box-box collision detection class btBox2dBox2dCollisionAlgorithm : public btActivatingCollisionAlgorithm { - bool m_ownManifold; - btPersistentManifold* m_manifoldPtr; - + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + public: btBox2dBox2dCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) : btActivatingCollisionAlgorithm(ci) {} - virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - btBox2dBox2dCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap); + btBox2dBox2dCollisionAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap); virtual ~btBox2dBox2dCollisionAlgorithm(); - virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) { if (m_manifoldPtr && m_ownManifold) { @@ -49,18 +49,15 @@ public: } } - - struct CreateFunc :public btCollisionAlgorithmCreateFunc + struct CreateFunc : public btCollisionAlgorithmCreateFunc { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { int bbsize = sizeof(btBox2dBox2dCollisionAlgorithm); void* ptr = ci.m_dispatcher1->allocateCollisionAlgorithm(bbsize); - return new(ptr) btBox2dBox2dCollisionAlgorithm(0,ci,body0Wrap,body1Wrap); + return new (ptr) btBox2dBox2dCollisionAlgorithm(0, ci, body0Wrap, body1Wrap); } }; - }; -#endif //BT_BOX_2D_BOX_2D__COLLISION_ALGORITHM_H - +#endif //BT_BOX_2D_BOX_2D__COLLISION_ALGORITHM_H diff --git a/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp index ac68968f5..7a391e059 100644 --- a/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp +++ b/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.cpp @@ -21,14 +21,14 @@ subject to the following restrictions: #include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" #define USE_PERSISTENT_CONTACTS 1 -btBoxBoxCollisionAlgorithm::btBoxBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) -: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap), -m_ownManifold(false), -m_manifoldPtr(mf) +btBoxBoxCollisionAlgorithm::btBoxBoxCollisionAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) + : btActivatingCollisionAlgorithm(ci, body0Wrap, body1Wrap), + m_ownManifold(false), + m_manifoldPtr(mf) { - if (!m_manifoldPtr && m_dispatcher->needsCollision(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject())) + if (!m_manifoldPtr && m_dispatcher->needsCollision(body0Wrap->getCollisionObject(), body1Wrap->getCollisionObject())) { - m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject()); + m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(), body1Wrap->getCollisionObject()); m_ownManifold = true; } } @@ -42,30 +42,27 @@ btBoxBoxCollisionAlgorithm::~btBoxBoxCollisionAlgorithm() } } -void btBoxBoxCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +void btBoxBoxCollisionAlgorithm::processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { if (!m_manifoldPtr) return; - const btBoxShape* box0 = (btBoxShape*)body0Wrap->getCollisionShape(); const btBoxShape* box1 = (btBoxShape*)body1Wrap->getCollisionShape(); - - /// report a contact. internally this will be kept persistent, and contact reduction is done resultOut->setPersistentManifold(m_manifoldPtr); -#ifndef USE_PERSISTENT_CONTACTS +#ifndef USE_PERSISTENT_CONTACTS m_manifoldPtr->clearManifold(); -#endif //USE_PERSISTENT_CONTACTS +#endif //USE_PERSISTENT_CONTACTS btDiscreteCollisionDetectorInterface::ClosestPointInput input; input.m_maximumDistanceSquared = BT_LARGE_FLOAT; input.m_transformA = body0Wrap->getWorldTransform(); input.m_transformB = body1Wrap->getWorldTransform(); - btBoxBoxDetector detector(box0,box1); - detector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); + btBoxBoxDetector detector(box0, box1); + detector.getClosestPoints(input, *resultOut, dispatchInfo.m_debugDraw); #ifdef USE_PERSISTENT_CONTACTS // refreshContactPoints is only necessary when using persistent contact points. otherwise all points are newly added @@ -73,11 +70,10 @@ void btBoxBoxCollisionAlgorithm::processCollision (const btCollisionObjectWrappe { resultOut->refreshContactPoints(); } -#endif //USE_PERSISTENT_CONTACTS - +#endif //USE_PERSISTENT_CONTACTS } -btScalar btBoxBoxCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* /*body0*/,btCollisionObject* /*body1*/,const btDispatcherInfo& /*dispatchInfo*/,btManifoldResult* /*resultOut*/) +btScalar btBoxBoxCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* /*body0*/, btCollisionObject* /*body1*/, const btDispatcherInfo& /*dispatchInfo*/, btManifoldResult* /*resultOut*/) { //not yet return 1.f; diff --git a/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h index 59808df5a..eb2106576 100644 --- a/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h +++ b/src/BulletCollision/CollisionDispatch/btBoxBoxCollisionAlgorithm.h @@ -26,22 +26,22 @@ class btPersistentManifold; ///box-box collision detection class btBoxBoxCollisionAlgorithm : public btActivatingCollisionAlgorithm { - bool m_ownManifold; - btPersistentManifold* m_manifoldPtr; - + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + public: btBoxBoxCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) : btActivatingCollisionAlgorithm(ci) {} - virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - btBoxBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap); + btBoxBoxCollisionAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap); virtual ~btBoxBoxCollisionAlgorithm(); - virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) { if (m_manifoldPtr && m_ownManifold) { @@ -49,18 +49,15 @@ public: } } - - struct CreateFunc :public btCollisionAlgorithmCreateFunc + struct CreateFunc : public btCollisionAlgorithmCreateFunc { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { int bbsize = sizeof(btBoxBoxCollisionAlgorithm); void* ptr = ci.m_dispatcher1->allocateCollisionAlgorithm(bbsize); - return new(ptr) btBoxBoxCollisionAlgorithm(0,ci,body0Wrap,body1Wrap); + return new (ptr) btBoxBoxCollisionAlgorithm(0, ci, body0Wrap, body1Wrap); } }; - }; -#endif //BT_BOX_BOX__COLLISION_ALGORITHM_H - +#endif //BT_BOX_BOX__COLLISION_ALGORITHM_H diff --git a/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp b/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp index 7043bde34..202039956 100644 --- a/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp +++ b/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.cpp @@ -24,14 +24,12 @@ subject to the following restrictions: #include #include -btBoxBoxDetector::btBoxBoxDetector(const btBoxShape* box1,const btBoxShape* box2) -: m_box1(box1), -m_box2(box2) +btBoxBoxDetector::btBoxBoxDetector(const btBoxShape* box1, const btBoxShape* box2) + : m_box1(box1), + m_box2(box2) { - } - // given two boxes (p1,R1,side1) and (p2,R2,side2), collide them together and // generate contact points. this returns 0 if there is no contact otherwise // it returns the number of contacts generated. @@ -48,67 +46,66 @@ m_box2(box2) // collision functions. this function only fills in the position and depth // fields. struct dContactGeom; -#define dDOTpq(a,b,p,q) ((a)[0]*(b)[0] + (a)[p]*(b)[q] + (a)[2*(p)]*(b)[2*(q)]) +#define dDOTpq(a, b, p, q) ((a)[0] * (b)[0] + (a)[p] * (b)[q] + (a)[2 * (p)] * (b)[2 * (q)]) #define dInfinity FLT_MAX - /*PURE_INLINE btScalar dDOT (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,1,1); } PURE_INLINE btScalar dDOT13 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,1,3); } PURE_INLINE btScalar dDOT31 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,3,1); } PURE_INLINE btScalar dDOT33 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,3,3); } */ -static btScalar dDOT (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,1,1); } -static btScalar dDOT44 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,4,4); } -static btScalar dDOT41 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,4,1); } -static btScalar dDOT14 (const btScalar *a, const btScalar *b) { return dDOTpq(a,b,1,4); } -#define dMULTIPLYOP1_331(A,op,B,C) \ -{\ - (A)[0] op dDOT41((B),(C)); \ - (A)[1] op dDOT41((B+1),(C)); \ - (A)[2] op dDOT41((B+2),(C)); \ -} +static btScalar dDOT(const btScalar* a, const btScalar* b) { return dDOTpq(a, b, 1, 1); } +static btScalar dDOT44(const btScalar* a, const btScalar* b) { return dDOTpq(a, b, 4, 4); } +static btScalar dDOT41(const btScalar* a, const btScalar* b) { return dDOTpq(a, b, 4, 1); } +static btScalar dDOT14(const btScalar* a, const btScalar* b) { return dDOTpq(a, b, 1, 4); } +#define dMULTIPLYOP1_331(A, op, B, C) \ + { \ + (A)[0] op dDOT41((B), (C)); \ + (A)[1] op dDOT41((B + 1), (C)); \ + (A)[2] op dDOT41((B + 2), (C)); \ + } -#define dMULTIPLYOP0_331(A,op,B,C) \ -{ \ - (A)[0] op dDOT((B),(C)); \ - (A)[1] op dDOT((B+4),(C)); \ - (A)[2] op dDOT((B+8),(C)); \ -} +#define dMULTIPLYOP0_331(A, op, B, C) \ + { \ + (A)[0] op dDOT((B), (C)); \ + (A)[1] op dDOT((B + 4), (C)); \ + (A)[2] op dDOT((B + 8), (C)); \ + } -#define dMULTIPLY1_331(A,B,C) dMULTIPLYOP1_331(A,=,B,C) -#define dMULTIPLY0_331(A,B,C) dMULTIPLYOP0_331(A,=,B,C) +#define dMULTIPLY1_331(A, B, C) dMULTIPLYOP1_331(A, =, B, C) +#define dMULTIPLY0_331(A, B, C) dMULTIPLYOP0_331(A, =, B, C) -typedef btScalar dMatrix3[4*3]; +typedef btScalar dMatrix3[4 * 3]; -void dLineClosestApproach (const btVector3& pa, const btVector3& ua, - const btVector3& pb, const btVector3& ub, - btScalar *alpha, btScalar *beta); -void dLineClosestApproach (const btVector3& pa, const btVector3& ua, - const btVector3& pb, const btVector3& ub, - btScalar *alpha, btScalar *beta) +void dLineClosestApproach(const btVector3& pa, const btVector3& ua, + const btVector3& pb, const btVector3& ub, + btScalar* alpha, btScalar* beta); +void dLineClosestApproach(const btVector3& pa, const btVector3& ua, + const btVector3& pb, const btVector3& ub, + btScalar* alpha, btScalar* beta) { - btVector3 p; - p[0] = pb[0] - pa[0]; - p[1] = pb[1] - pa[1]; - p[2] = pb[2] - pa[2]; - btScalar uaub = dDOT(ua,ub); - btScalar q1 = dDOT(ua,p); - btScalar q2 = -dDOT(ub,p); - btScalar d = 1-uaub*uaub; - if (d <= btScalar(0.0001f)) { - // @@@ this needs to be made more robust - *alpha = 0; - *beta = 0; - } - else { - d = 1.f/d; - *alpha = (q1 + uaub*q2)*d; - *beta = (uaub*q1 + q2)*d; - } + btVector3 p; + p[0] = pb[0] - pa[0]; + p[1] = pb[1] - pa[1]; + p[2] = pb[2] - pa[2]; + btScalar uaub = dDOT(ua, ub); + btScalar q1 = dDOT(ua, p); + btScalar q2 = -dDOT(ub, p); + btScalar d = 1 - uaub * uaub; + if (d <= btScalar(0.0001f)) + { + // @@@ this needs to be made more robust + *alpha = 0; + *beta = 0; + } + else + { + d = 1.f / d; + *alpha = (q1 + uaub * q2) * d; + *beta = (uaub * q1 + q2) * d; + } } - - // find all the intersection points between the 2D rectangle with vertices // at (+/-h[0],+/-h[1]) and the 2D quadrilateral with vertices (p[0],p[1]), // (p[2],p[3]),(p[4],p[5]),(p[6],p[7]). @@ -117,60 +114,66 @@ void dLineClosestApproach (const btVector3& pa, const btVector3& ua, // the number of intersection points is returned by the function (this will // be in the range 0 to 8). -static int intersectRectQuad2 (btScalar h[2], btScalar p[8], btScalar ret[16]) +static int intersectRectQuad2(btScalar h[2], btScalar p[8], btScalar ret[16]) { - // q (and r) contain nq (and nr) coordinate points for the current (and - // chopped) polygons - int nq=4,nr=0; - btScalar buffer[16]; - btScalar *q = p; - btScalar *r = ret; - for (int dir=0; dir <= 1; dir++) { - // direction notation: xy[0] = x axis, xy[1] = y axis - for (int sign=-1; sign <= 1; sign += 2) { - // chop q along the line xy[dir] = sign*h[dir] - btScalar *pq = q; - btScalar *pr = r; - nr = 0; - for (int i=nq; i > 0; i--) { - // go through all points in q and all lines between adjacent points - if (sign*pq[dir] < h[dir]) { - // this point is inside the chopping line - pr[0] = pq[0]; - pr[1] = pq[1]; - pr += 2; - nr++; - if (nr & 8) { - q = r; - goto done; - } + // q (and r) contain nq (and nr) coordinate points for the current (and + // chopped) polygons + int nq = 4, nr = 0; + btScalar buffer[16]; + btScalar* q = p; + btScalar* r = ret; + for (int dir = 0; dir <= 1; dir++) + { + // direction notation: xy[0] = x axis, xy[1] = y axis + for (int sign = -1; sign <= 1; sign += 2) + { + // chop q along the line xy[dir] = sign*h[dir] + btScalar* pq = q; + btScalar* pr = r; + nr = 0; + for (int i = nq; i > 0; i--) + { + // go through all points in q and all lines between adjacent points + if (sign * pq[dir] < h[dir]) + { + // this point is inside the chopping line + pr[0] = pq[0]; + pr[1] = pq[1]; + pr += 2; + nr++; + if (nr & 8) + { + q = r; + goto done; + } + } + btScalar* nextq = (i > 1) ? pq + 2 : q; + if ((sign * pq[dir] < h[dir]) ^ (sign * nextq[dir] < h[dir])) + { + // this line crosses the chopping line + pr[1 - dir] = pq[1 - dir] + (nextq[1 - dir] - pq[1 - dir]) / + (nextq[dir] - pq[dir]) * (sign * h[dir] - pq[dir]); + pr[dir] = sign * h[dir]; + pr += 2; + nr++; + if (nr & 8) + { + q = r; + goto done; + } + } + pq += 2; + } + q = r; + r = (q == ret) ? buffer : ret; + nq = nr; + } } - btScalar *nextq = (i > 1) ? pq+2 : q; - if ((sign*pq[dir] < h[dir]) ^ (sign*nextq[dir] < h[dir])) { - // this line crosses the chopping line - pr[1-dir] = pq[1-dir] + (nextq[1-dir]-pq[1-dir]) / - (nextq[dir]-pq[dir]) * (sign*h[dir]-pq[dir]); - pr[dir] = sign*h[dir]; - pr += 2; - nr++; - if (nr & 8) { - q = r; - goto done; - } - } - pq += 2; - } - q = r; - r = (q==ret) ? buffer : ret; - nq = nr; - } - } - done: - if (q != ret) memcpy (ret,q,nr*2*sizeof(btScalar)); - return nr; +done: + if (q != ret) memcpy(ret, q, nr * 2 * sizeof(btScalar)); + return nr; } - #define M__PI 3.14159265f // given n points in the plane (array p, of size 2*n), generate m points that @@ -181,538 +184,584 @@ static int intersectRectQuad2 (btScalar h[2], btScalar p[8], btScalar ret[16]) // n must be in the range [1..8]. m must be in the range [1..n]. i0 must be // in the range [0..n-1]. -void cullPoints2 (int n, btScalar p[], int m, int i0, int iret[]); -void cullPoints2 (int n, btScalar p[], int m, int i0, int iret[]) +void cullPoints2(int n, btScalar p[], int m, int i0, int iret[]); +void cullPoints2(int n, btScalar p[], int m, int i0, int iret[]) { - // compute the centroid of the polygon in cx,cy - int i,j; - btScalar a,cx,cy,q; - if (n==1) { - cx = p[0]; - cy = p[1]; - } - else if (n==2) { - cx = btScalar(0.5)*(p[0] + p[2]); - cy = btScalar(0.5)*(p[1] + p[3]); - } - else { - a = 0; - cx = 0; - cy = 0; - for (i=0; i<(n-1); i++) { - q = p[i*2]*p[i*2+3] - p[i*2+2]*p[i*2+1]; - a += q; - cx += q*(p[i*2]+p[i*2+2]); - cy += q*(p[i*2+1]+p[i*2+3]); - } - q = p[n*2-2]*p[1] - p[0]*p[n*2-1]; - if (btFabs(a+q) > SIMD_EPSILON) + // compute the centroid of the polygon in cx,cy + int i, j; + btScalar a, cx, cy, q; + if (n == 1) { - a = 1.f/(btScalar(3.0)*(a+q)); - } else + cx = p[0]; + cy = p[1]; + } + else if (n == 2) { - a=BT_LARGE_FLOAT; + cx = btScalar(0.5) * (p[0] + p[2]); + cy = btScalar(0.5) * (p[1] + p[3]); } - cx = a*(cx + q*(p[n*2-2]+p[0])); - cy = a*(cy + q*(p[n*2-1]+p[1])); - } - - // compute the angle of each point w.r.t. the centroid - btScalar A[8]; - for (i=0; i M__PI) a -= 2*M__PI; - btScalar maxdiff=1e9,diff; - - *iret = i0; // iret is not allowed to keep this value, but it sometimes does, when diff=#QNAN0 - - for (i=0; i M__PI) diff = 2*M__PI - diff; - if (diff < maxdiff) { - maxdiff = diff; - *iret = i; + else + { + a = 0; + cx = 0; + cy = 0; + for (i = 0; i < (n - 1); i++) + { + q = p[i * 2] * p[i * 2 + 3] - p[i * 2 + 2] * p[i * 2 + 1]; + a += q; + cx += q * (p[i * 2] + p[i * 2 + 2]); + cy += q * (p[i * 2 + 1] + p[i * 2 + 3]); + } + q = p[n * 2 - 2] * p[1] - p[0] * p[n * 2 - 1]; + if (btFabs(a + q) > SIMD_EPSILON) + { + a = 1.f / (btScalar(3.0) * (a + q)); + } + else + { + a = BT_LARGE_FLOAT; + } + cx = a * (cx + q * (p[n * 2 - 2] + p[0])); + cy = a * (cy + q * (p[n * 2 - 1] + p[1])); } - } - } -#if defined(DEBUG) || defined (_DEBUG) - btAssert (*iret != i0); // ensure iret got set + + // compute the angle of each point w.r.t. the centroid + btScalar A[8]; + for (i = 0; i < n; i++) A[i] = btAtan2(p[i * 2 + 1] - cy, p[i * 2] - cx); + + // search for points that have angles closest to A[i0] + i*(2*pi/m). + int avail[8]; + for (i = 0; i < n; i++) avail[i] = 1; + avail[i0] = 0; + iret[0] = i0; + iret++; + for (j = 1; j < m; j++) + { + a = btScalar(j) * (2 * M__PI / m) + A[i0]; + if (a > M__PI) a -= 2 * M__PI; + btScalar maxdiff = 1e9, diff; + + *iret = i0; // iret is not allowed to keep this value, but it sometimes does, when diff=#QNAN0 + + for (i = 0; i < n; i++) + { + if (avail[i]) + { + diff = btFabs(A[i] - a); + if (diff > M__PI) diff = 2 * M__PI - diff; + if (diff < maxdiff) + { + maxdiff = diff; + *iret = i; + } + } + } +#if defined(DEBUG) || defined(_DEBUG) + btAssert(*iret != i0); // ensure iret got set #endif - avail[*iret] = 0; - iret++; - } + avail[*iret] = 0; + iret++; + } } - - -int dBoxBox2 (const btVector3& p1, const dMatrix3 R1, - const btVector3& side1, const btVector3& p2, - const dMatrix3 R2, const btVector3& side2, - btVector3& normal, btScalar *depth, int *return_code, - int maxc, dContactGeom * /*contact*/, int /*skip*/,btDiscreteCollisionDetectorInterface::Result& output); -int dBoxBox2 (const btVector3& p1, const dMatrix3 R1, - const btVector3& side1, const btVector3& p2, - const dMatrix3 R2, const btVector3& side2, - btVector3& normal, btScalar *depth, int *return_code, - int maxc, dContactGeom * /*contact*/, int /*skip*/,btDiscreteCollisionDetectorInterface::Result& output) +int dBoxBox2(const btVector3& p1, const dMatrix3 R1, + const btVector3& side1, const btVector3& p2, + const dMatrix3 R2, const btVector3& side2, + btVector3& normal, btScalar* depth, int* return_code, + int maxc, dContactGeom* /*contact*/, int /*skip*/, btDiscreteCollisionDetectorInterface::Result& output); +int dBoxBox2(const btVector3& p1, const dMatrix3 R1, + const btVector3& side1, const btVector3& p2, + const dMatrix3 R2, const btVector3& side2, + btVector3& normal, btScalar* depth, int* return_code, + int maxc, dContactGeom* /*contact*/, int /*skip*/, btDiscreteCollisionDetectorInterface::Result& output) { - const btScalar fudge_factor = btScalar(1.05); - btVector3 p,pp,normalC(0.f,0.f,0.f); - const btScalar *normalR = 0; - btScalar A[3],B[3],R11,R12,R13,R21,R22,R23,R31,R32,R33, - Q11,Q12,Q13,Q21,Q22,Q23,Q31,Q32,Q33,s,s2,l; - int i,j,invert_normal,code; + const btScalar fudge_factor = btScalar(1.05); + btVector3 p, pp, normalC(0.f, 0.f, 0.f); + const btScalar* normalR = 0; + btScalar A[3], B[3], R11, R12, R13, R21, R22, R23, R31, R32, R33, + Q11, Q12, Q13, Q21, Q22, Q23, Q31, Q32, Q33, s, s2, l; + int i, j, invert_normal, code; - // get vector from centers of box 1 to box 2, relative to box 1 - p = p2 - p1; - dMULTIPLY1_331 (pp,R1,p); // get pp = p relative to body 1 + // get vector from centers of box 1 to box 2, relative to box 1 + p = p2 - p1; + dMULTIPLY1_331(pp, R1, p); // get pp = p relative to body 1 - // get side lengths / 2 - A[0] = side1[0]*btScalar(0.5); - A[1] = side1[1]*btScalar(0.5); - A[2] = side1[2]*btScalar(0.5); - B[0] = side2[0]*btScalar(0.5); - B[1] = side2[1]*btScalar(0.5); - B[2] = side2[2]*btScalar(0.5); + // get side lengths / 2 + A[0] = side1[0] * btScalar(0.5); + A[1] = side1[1] * btScalar(0.5); + A[2] = side1[2] * btScalar(0.5); + B[0] = side2[0] * btScalar(0.5); + B[1] = side2[1] * btScalar(0.5); + B[2] = side2[2] * btScalar(0.5); - // Rij is R1'*R2, i.e. the relative rotation between R1 and R2 - R11 = dDOT44(R1+0,R2+0); R12 = dDOT44(R1+0,R2+1); R13 = dDOT44(R1+0,R2+2); - R21 = dDOT44(R1+1,R2+0); R22 = dDOT44(R1+1,R2+1); R23 = dDOT44(R1+1,R2+2); - R31 = dDOT44(R1+2,R2+0); R32 = dDOT44(R1+2,R2+1); R33 = dDOT44(R1+2,R2+2); + // Rij is R1'*R2, i.e. the relative rotation between R1 and R2 + R11 = dDOT44(R1 + 0, R2 + 0); + R12 = dDOT44(R1 + 0, R2 + 1); + R13 = dDOT44(R1 + 0, R2 + 2); + R21 = dDOT44(R1 + 1, R2 + 0); + R22 = dDOT44(R1 + 1, R2 + 1); + R23 = dDOT44(R1 + 1, R2 + 2); + R31 = dDOT44(R1 + 2, R2 + 0); + R32 = dDOT44(R1 + 2, R2 + 1); + R33 = dDOT44(R1 + 2, R2 + 2); - Q11 = btFabs(R11); Q12 = btFabs(R12); Q13 = btFabs(R13); - Q21 = btFabs(R21); Q22 = btFabs(R22); Q23 = btFabs(R23); - Q31 = btFabs(R31); Q32 = btFabs(R32); Q33 = btFabs(R33); + Q11 = btFabs(R11); + Q12 = btFabs(R12); + Q13 = btFabs(R13); + Q21 = btFabs(R21); + Q22 = btFabs(R22); + Q23 = btFabs(R23); + Q31 = btFabs(R31); + Q32 = btFabs(R32); + Q33 = btFabs(R33); - // for all 15 possible separating axes: - // * see if the axis separates the boxes. if so, return 0. - // * find the depth of the penetration along the separating axis (s2) - // * if this is the largest depth so far, record it. - // the normal vector will be set to the separating axis with the smallest - // depth. note: normalR is set to point to a column of R1 or R2 if that is - // the smallest depth normal so far. otherwise normalR is 0 and normalC is - // set to a vector relative to body 1. invert_normal is 1 if the sign of - // the normal should be flipped. + // for all 15 possible separating axes: + // * see if the axis separates the boxes. if so, return 0. + // * find the depth of the penetration along the separating axis (s2) + // * if this is the largest depth so far, record it. + // the normal vector will be set to the separating axis with the smallest + // depth. note: normalR is set to point to a column of R1 or R2 if that is + // the smallest depth normal so far. otherwise normalR is 0 and normalC is + // set to a vector relative to body 1. invert_normal is 1 if the sign of + // the normal should be flipped. -#define TST(expr1,expr2,norm,cc) \ - s2 = btFabs(expr1) - (expr2); \ - if (s2 > 0) return 0; \ - if (s2 > s) { \ - s = s2; \ - normalR = norm; \ - invert_normal = ((expr1) < 0); \ - code = (cc); \ - } +#define TST(expr1, expr2, norm, cc) \ + s2 = btFabs(expr1) - (expr2); \ + if (s2 > 0) return 0; \ + if (s2 > s) \ + { \ + s = s2; \ + normalR = norm; \ + invert_normal = ((expr1) < 0); \ + code = (cc); \ + } - s = -dInfinity; - invert_normal = 0; - code = 0; + s = -dInfinity; + invert_normal = 0; + code = 0; - // separating axis = u1,u2,u3 - TST (pp[0],(A[0] + B[0]*Q11 + B[1]*Q12 + B[2]*Q13),R1+0,1); - TST (pp[1],(A[1] + B[0]*Q21 + B[1]*Q22 + B[2]*Q23),R1+1,2); - TST (pp[2],(A[2] + B[0]*Q31 + B[1]*Q32 + B[2]*Q33),R1+2,3); + // separating axis = u1,u2,u3 + TST(pp[0], (A[0] + B[0] * Q11 + B[1] * Q12 + B[2] * Q13), R1 + 0, 1); + TST(pp[1], (A[1] + B[0] * Q21 + B[1] * Q22 + B[2] * Q23), R1 + 1, 2); + TST(pp[2], (A[2] + B[0] * Q31 + B[1] * Q32 + B[2] * Q33), R1 + 2, 3); - // separating axis = v1,v2,v3 - TST (dDOT41(R2+0,p),(A[0]*Q11 + A[1]*Q21 + A[2]*Q31 + B[0]),R2+0,4); - TST (dDOT41(R2+1,p),(A[0]*Q12 + A[1]*Q22 + A[2]*Q32 + B[1]),R2+1,5); - TST (dDOT41(R2+2,p),(A[0]*Q13 + A[1]*Q23 + A[2]*Q33 + B[2]),R2+2,6); + // separating axis = v1,v2,v3 + TST(dDOT41(R2 + 0, p), (A[0] * Q11 + A[1] * Q21 + A[2] * Q31 + B[0]), R2 + 0, 4); + TST(dDOT41(R2 + 1, p), (A[0] * Q12 + A[1] * Q22 + A[2] * Q32 + B[1]), R2 + 1, 5); + TST(dDOT41(R2 + 2, p), (A[0] * Q13 + A[1] * Q23 + A[2] * Q33 + B[2]), R2 + 2, 6); - // note: cross product axes need to be scaled when s is computed. - // normal (n1,n2,n3) is relative to box 1. + // note: cross product axes need to be scaled when s is computed. + // normal (n1,n2,n3) is relative to box 1. #undef TST -#define TST(expr1,expr2,n1,n2,n3,cc) \ - s2 = btFabs(expr1) - (expr2); \ - if (s2 > SIMD_EPSILON) return 0; \ - l = btSqrt((n1)*(n1) + (n2)*(n2) + (n3)*(n3)); \ - if (l > SIMD_EPSILON) { \ - s2 /= l; \ - if (s2*fudge_factor > s) { \ - s = s2; \ - normalR = 0; \ - normalC[0] = (n1)/l; normalC[1] = (n2)/l; normalC[2] = (n3)/l; \ - invert_normal = ((expr1) < 0); \ - code = (cc); \ - } \ - } +#define TST(expr1, expr2, n1, n2, n3, cc) \ + s2 = btFabs(expr1) - (expr2); \ + if (s2 > SIMD_EPSILON) return 0; \ + l = btSqrt((n1) * (n1) + (n2) * (n2) + (n3) * (n3)); \ + if (l > SIMD_EPSILON) \ + { \ + s2 /= l; \ + if (s2 * fudge_factor > s) \ + { \ + s = s2; \ + normalR = 0; \ + normalC[0] = (n1) / l; \ + normalC[1] = (n2) / l; \ + normalC[2] = (n3) / l; \ + invert_normal = ((expr1) < 0); \ + code = (cc); \ + } \ + } - btScalar fudge2 (1.0e-5f); + btScalar fudge2(1.0e-5f); - Q11 += fudge2; - Q12 += fudge2; - Q13 += fudge2; + Q11 += fudge2; + Q12 += fudge2; + Q13 += fudge2; - Q21 += fudge2; - Q22 += fudge2; - Q23 += fudge2; + Q21 += fudge2; + Q22 += fudge2; + Q23 += fudge2; - Q31 += fudge2; - Q32 += fudge2; - Q33 += fudge2; + Q31 += fudge2; + Q32 += fudge2; + Q33 += fudge2; - // separating axis = u1 x (v1,v2,v3) - TST(pp[2]*R21-pp[1]*R31,(A[1]*Q31+A[2]*Q21+B[1]*Q13+B[2]*Q12),0,-R31,R21,7); - TST(pp[2]*R22-pp[1]*R32,(A[1]*Q32+A[2]*Q22+B[0]*Q13+B[2]*Q11),0,-R32,R22,8); - TST(pp[2]*R23-pp[1]*R33,(A[1]*Q33+A[2]*Q23+B[0]*Q12+B[1]*Q11),0,-R33,R23,9); + // separating axis = u1 x (v1,v2,v3) + TST(pp[2] * R21 - pp[1] * R31, (A[1] * Q31 + A[2] * Q21 + B[1] * Q13 + B[2] * Q12), 0, -R31, R21, 7); + TST(pp[2] * R22 - pp[1] * R32, (A[1] * Q32 + A[2] * Q22 + B[0] * Q13 + B[2] * Q11), 0, -R32, R22, 8); + TST(pp[2] * R23 - pp[1] * R33, (A[1] * Q33 + A[2] * Q23 + B[0] * Q12 + B[1] * Q11), 0, -R33, R23, 9); - // separating axis = u2 x (v1,v2,v3) - TST(pp[0]*R31-pp[2]*R11,(A[0]*Q31+A[2]*Q11+B[1]*Q23+B[2]*Q22),R31,0,-R11,10); - TST(pp[0]*R32-pp[2]*R12,(A[0]*Q32+A[2]*Q12+B[0]*Q23+B[2]*Q21),R32,0,-R12,11); - TST(pp[0]*R33-pp[2]*R13,(A[0]*Q33+A[2]*Q13+B[0]*Q22+B[1]*Q21),R33,0,-R13,12); + // separating axis = u2 x (v1,v2,v3) + TST(pp[0] * R31 - pp[2] * R11, (A[0] * Q31 + A[2] * Q11 + B[1] * Q23 + B[2] * Q22), R31, 0, -R11, 10); + TST(pp[0] * R32 - pp[2] * R12, (A[0] * Q32 + A[2] * Q12 + B[0] * Q23 + B[2] * Q21), R32, 0, -R12, 11); + TST(pp[0] * R33 - pp[2] * R13, (A[0] * Q33 + A[2] * Q13 + B[0] * Q22 + B[1] * Q21), R33, 0, -R13, 12); - // separating axis = u3 x (v1,v2,v3) - TST(pp[1]*R11-pp[0]*R21,(A[0]*Q21+A[1]*Q11+B[1]*Q33+B[2]*Q32),-R21,R11,0,13); - TST(pp[1]*R12-pp[0]*R22,(A[0]*Q22+A[1]*Q12+B[0]*Q33+B[2]*Q31),-R22,R12,0,14); - TST(pp[1]*R13-pp[0]*R23,(A[0]*Q23+A[1]*Q13+B[0]*Q32+B[1]*Q31),-R23,R13,0,15); + // separating axis = u3 x (v1,v2,v3) + TST(pp[1] * R11 - pp[0] * R21, (A[0] * Q21 + A[1] * Q11 + B[1] * Q33 + B[2] * Q32), -R21, R11, 0, 13); + TST(pp[1] * R12 - pp[0] * R22, (A[0] * Q22 + A[1] * Q12 + B[0] * Q33 + B[2] * Q31), -R22, R12, 0, 14); + TST(pp[1] * R13 - pp[0] * R23, (A[0] * Q23 + A[1] * Q13 + B[0] * Q32 + B[1] * Q31), -R23, R13, 0, 15); #undef TST - if (!code) return 0; - - // if we get to this point, the boxes interpenetrate. compute the normal - // in global coordinates. - if (normalR) { - normal[0] = normalR[0]; - normal[1] = normalR[4]; - normal[2] = normalR[8]; - } - else { - dMULTIPLY0_331 (normal,R1,normalC); - } - if (invert_normal) { - normal[0] = -normal[0]; - normal[1] = -normal[1]; - normal[2] = -normal[2]; - } - *depth = -s; - - // compute contact point(s) - - if (code > 6) { - // an edge from box 1 touches an edge from box 2. - // find a point pa on the intersecting edge of box 1 - btVector3 pa; - btScalar sign; - for (i=0; i<3; i++) pa[i] = p1[i]; - for (j=0; j<3; j++) { - sign = (dDOT14(normal,R1+j) > 0) ? btScalar(1.0) : btScalar(-1.0); - for (i=0; i<3; i++) pa[i] += sign * A[j] * R1[i*4+j]; - } - - // find a point pb on the intersecting edge of box 2 - btVector3 pb; - for (i=0; i<3; i++) pb[i] = p2[i]; - for (j=0; j<3; j++) { - sign = (dDOT14(normal,R2+j) > 0) ? btScalar(-1.0) : btScalar(1.0); - for (i=0; i<3; i++) pb[i] += sign * B[j] * R2[i*4+j]; - } - - btScalar alpha,beta; - btVector3 ua,ub; - for (i=0; i<3; i++) ua[i] = R1[((code)-7)/3 + i*4]; - for (i=0; i<3; i++) ub[i] = R2[((code)-7)%3 + i*4]; - - dLineClosestApproach (pa,ua,pb,ub,&alpha,&beta); - for (i=0; i<3; i++) pa[i] += ua[i]*alpha; - for (i=0; i<3; i++) pb[i] += ub[i]*beta; + if (!code) return 0; + // if we get to this point, the boxes interpenetrate. compute the normal + // in global coordinates. + if (normalR) { - - //contact[0].pos[i] = btScalar(0.5)*(pa[i]+pb[i]); - //contact[0].depth = *depth; - btVector3 pointInWorld; + normal[0] = normalR[0]; + normal[1] = normalR[4]; + normal[2] = normalR[8]; + } + else + { + dMULTIPLY0_331(normal, R1, normalC); + } + if (invert_normal) + { + normal[0] = -normal[0]; + normal[1] = -normal[1]; + normal[2] = -normal[2]; + } + *depth = -s; + + // compute contact point(s) + + if (code > 6) + { + // an edge from box 1 touches an edge from box 2. + // find a point pa on the intersecting edge of box 1 + btVector3 pa; + btScalar sign; + for (i = 0; i < 3; i++) pa[i] = p1[i]; + for (j = 0; j < 3; j++) + { + sign = (dDOT14(normal, R1 + j) > 0) ? btScalar(1.0) : btScalar(-1.0); + for (i = 0; i < 3; i++) pa[i] += sign * A[j] * R1[i * 4 + j]; + } + + // find a point pb on the intersecting edge of box 2 + btVector3 pb; + for (i = 0; i < 3; i++) pb[i] = p2[i]; + for (j = 0; j < 3; j++) + { + sign = (dDOT14(normal, R2 + j) > 0) ? btScalar(-1.0) : btScalar(1.0); + for (i = 0; i < 3; i++) pb[i] += sign * B[j] * R2[i * 4 + j]; + } + + btScalar alpha, beta; + btVector3 ua, ub; + for (i = 0; i < 3; i++) ua[i] = R1[((code)-7) / 3 + i * 4]; + for (i = 0; i < 3; i++) ub[i] = R2[((code)-7) % 3 + i * 4]; + + dLineClosestApproach(pa, ua, pb, ub, &alpha, &beta); + for (i = 0; i < 3; i++) pa[i] += ua[i] * alpha; + for (i = 0; i < 3; i++) pb[i] += ub[i] * beta; + + { + //contact[0].pos[i] = btScalar(0.5)*(pa[i]+pb[i]); + //contact[0].depth = *depth; + btVector3 pointInWorld; #ifdef USE_CENTER_POINT - for (i=0; i<3; i++) - pointInWorld[i] = (pa[i]+pb[i])*btScalar(0.5); - output.addContactPoint(-normal,pointInWorld,-*depth); + for (i = 0; i < 3; i++) + pointInWorld[i] = (pa[i] + pb[i]) * btScalar(0.5); + output.addContactPoint(-normal, pointInWorld, -*depth); #else - output.addContactPoint(-normal,pb,-*depth); + output.addContactPoint(-normal, pb, -*depth); -#endif // - *return_code = code; +#endif // + *return_code = code; + } + return 1; } - return 1; - } - // okay, we have a face-something intersection (because the separating - // axis is perpendicular to a face). define face 'a' to be the reference - // face (i.e. the normal vector is perpendicular to this) and face 'b' to be - // the incident face (the closest face of the other box). + // okay, we have a face-something intersection (because the separating + // axis is perpendicular to a face). define face 'a' to be the reference + // face (i.e. the normal vector is perpendicular to this) and face 'b' to be + // the incident face (the closest face of the other box). - const btScalar *Ra,*Rb,*pa,*pb,*Sa,*Sb; - if (code <= 3) { - Ra = R1; - Rb = R2; - pa = p1; - pb = p2; - Sa = A; - Sb = B; - } - else { - Ra = R2; - Rb = R1; - pa = p2; - pb = p1; - Sa = B; - Sb = A; - } - - // nr = normal vector of reference face dotted with axes of incident box. - // anr = absolute values of nr. - btVector3 normal2,nr,anr; - if (code <= 3) { - normal2[0] = normal[0]; - normal2[1] = normal[1]; - normal2[2] = normal[2]; - } - else { - normal2[0] = -normal[0]; - normal2[1] = -normal[1]; - normal2[2] = -normal[2]; - } - dMULTIPLY1_331 (nr,Rb,normal2); - anr[0] = btFabs (nr[0]); - anr[1] = btFabs (nr[1]); - anr[2] = btFabs (nr[2]); - - // find the largest compontent of anr: this corresponds to the normal - // for the indident face. the other axis numbers of the indicent face - // are stored in a1,a2. - int lanr,a1,a2; - if (anr[1] > anr[0]) { - if (anr[1] > anr[2]) { - a1 = 0; - lanr = 1; - a2 = 2; - } - else { - a1 = 0; - a2 = 1; - lanr = 2; - } - } - else { - if (anr[0] > anr[2]) { - lanr = 0; - a1 = 1; - a2 = 2; - } - else { - a1 = 0; - a2 = 1; - lanr = 2; - } - } - - // compute center point of incident face, in reference-face coordinates - btVector3 center; - if (nr[lanr] < 0) { - for (i=0; i<3; i++) center[i] = pb[i] - pa[i] + Sb[lanr] * Rb[i*4+lanr]; - } - else { - for (i=0; i<3; i++) center[i] = pb[i] - pa[i] - Sb[lanr] * Rb[i*4+lanr]; - } - - // find the normal and non-normal axis numbers of the reference box - int codeN,code1,code2; - if (code <= 3) codeN = code-1; else codeN = code-4; - if (codeN==0) { - code1 = 1; - code2 = 2; - } - else if (codeN==1) { - code1 = 0; - code2 = 2; - } - else { - code1 = 0; - code2 = 1; - } - - // find the four corners of the incident face, in reference-face coordinates - btScalar quad[8]; // 2D coordinate of incident face (x,y pairs) - btScalar c1,c2,m11,m12,m21,m22; - c1 = dDOT14 (center,Ra+code1); - c2 = dDOT14 (center,Ra+code2); - // optimize this? - we have already computed this data above, but it is not - // stored in an easy-to-index format. for now it's quicker just to recompute - // the four dot products. - m11 = dDOT44 (Ra+code1,Rb+a1); - m12 = dDOT44 (Ra+code1,Rb+a2); - m21 = dDOT44 (Ra+code2,Rb+a1); - m22 = dDOT44 (Ra+code2,Rb+a2); - { - btScalar k1 = m11*Sb[a1]; - btScalar k2 = m21*Sb[a1]; - btScalar k3 = m12*Sb[a2]; - btScalar k4 = m22*Sb[a2]; - quad[0] = c1 - k1 - k3; - quad[1] = c2 - k2 - k4; - quad[2] = c1 - k1 + k3; - quad[3] = c2 - k2 + k4; - quad[4] = c1 + k1 + k3; - quad[5] = c2 + k2 + k4; - quad[6] = c1 + k1 - k3; - quad[7] = c2 + k2 - k4; - } - - // find the size of the reference face - btScalar rect[2]; - rect[0] = Sa[code1]; - rect[1] = Sa[code2]; - - // intersect the incident and reference faces - btScalar ret[16]; - int n = intersectRectQuad2 (rect,quad,ret); - if (n < 1) return 0; // this should never happen - - // convert the intersection points into reference-face coordinates, - // and compute the contact position and depth for each point. only keep - // those points that have a positive (penetrating) depth. delete points in - // the 'ret' array as necessary so that 'point' and 'ret' correspond. - btScalar point[3*8]; // penetrating contact points - btScalar dep[8]; // depths for those points - btScalar det1 = 1.f/(m11*m22 - m12*m21); - m11 *= det1; - m12 *= det1; - m21 *= det1; - m22 *= det1; - int cnum = 0; // number of penetrating contact points found - for (j=0; j < n; j++) { - btScalar k1 = m22*(ret[j*2]-c1) - m12*(ret[j*2+1]-c2); - btScalar k2 = -m21*(ret[j*2]-c1) + m11*(ret[j*2+1]-c2); - for (i=0; i<3; i++) point[cnum*3+i] = - center[i] + k1*Rb[i*4+a1] + k2*Rb[i*4+a2]; - dep[cnum] = Sa[codeN] - dDOT(normal2,point+cnum*3); - if (dep[cnum] >= 0) { - ret[cnum*2] = ret[j*2]; - ret[cnum*2+1] = ret[j*2+1]; - cnum++; - } - } - if (cnum < 1) return 0; // this should never happen - - // we can't generate more contacts than we actually have - if (maxc > cnum) maxc = cnum; - if (maxc < 1) maxc = 1; - - if (cnum <= maxc) { - - if (code<4) - { - // we have less contacts than we need, so we use them all - for (j=0; j < cnum; j++) + const btScalar *Ra, *Rb, *pa, *pb, *Sa, *Sb; + if (code <= 3) { - btVector3 pointInWorld; - for (i=0; i<3; i++) - pointInWorld[i] = point[j*3+i] + pa[i]; - output.addContactPoint(-normal,pointInWorld,-dep[j]); + Ra = R1; + Rb = R2; + pa = p1; + pb = p2; + Sa = A; + Sb = B; + } + else + { + Ra = R2; + Rb = R1; + pa = p2; + pb = p1; + Sa = B; + Sb = A; + } - } - } else - { - // we have less contacts than we need, so we use them all - for (j=0; j < cnum; j++) + // nr = normal vector of reference face dotted with axes of incident box. + // anr = absolute values of nr. + btVector3 normal2, nr, anr; + if (code <= 3) + { + normal2[0] = normal[0]; + normal2[1] = normal[1]; + normal2[2] = normal[2]; + } + else + { + normal2[0] = -normal[0]; + normal2[1] = -normal[1]; + normal2[2] = -normal[2]; + } + dMULTIPLY1_331(nr, Rb, normal2); + anr[0] = btFabs(nr[0]); + anr[1] = btFabs(nr[1]); + anr[2] = btFabs(nr[2]); + + // find the largest compontent of anr: this corresponds to the normal + // for the indident face. the other axis numbers of the indicent face + // are stored in a1,a2. + int lanr, a1, a2; + if (anr[1] > anr[0]) + { + if (anr[1] > anr[2]) { - btVector3 pointInWorld; - for (i=0; i<3; i++) - pointInWorld[i] = point[j*3+i] + pa[i]-normal[i]*dep[j]; + a1 = 0; + lanr = 1; + a2 = 2; + } + else + { + a1 = 0; + a2 = 1; + lanr = 2; + } + } + else + { + if (anr[0] > anr[2]) + { + lanr = 0; + a1 = 1; + a2 = 2; + } + else + { + a1 = 0; + a2 = 1; + lanr = 2; + } + } + + // compute center point of incident face, in reference-face coordinates + btVector3 center; + if (nr[lanr] < 0) + { + for (i = 0; i < 3; i++) center[i] = pb[i] - pa[i] + Sb[lanr] * Rb[i * 4 + lanr]; + } + else + { + for (i = 0; i < 3; i++) center[i] = pb[i] - pa[i] - Sb[lanr] * Rb[i * 4 + lanr]; + } + + // find the normal and non-normal axis numbers of the reference box + int codeN, code1, code2; + if (code <= 3) + codeN = code - 1; + else + codeN = code - 4; + if (codeN == 0) + { + code1 = 1; + code2 = 2; + } + else if (codeN == 1) + { + code1 = 0; + code2 = 2; + } + else + { + code1 = 0; + code2 = 1; + } + + // find the four corners of the incident face, in reference-face coordinates + btScalar quad[8]; // 2D coordinate of incident face (x,y pairs) + btScalar c1, c2, m11, m12, m21, m22; + c1 = dDOT14(center, Ra + code1); + c2 = dDOT14(center, Ra + code2); + // optimize this? - we have already computed this data above, but it is not + // stored in an easy-to-index format. for now it's quicker just to recompute + // the four dot products. + m11 = dDOT44(Ra + code1, Rb + a1); + m12 = dDOT44(Ra + code1, Rb + a2); + m21 = dDOT44(Ra + code2, Rb + a1); + m22 = dDOT44(Ra + code2, Rb + a2); + { + btScalar k1 = m11 * Sb[a1]; + btScalar k2 = m21 * Sb[a1]; + btScalar k3 = m12 * Sb[a2]; + btScalar k4 = m22 * Sb[a2]; + quad[0] = c1 - k1 - k3; + quad[1] = c2 - k2 - k4; + quad[2] = c1 - k1 + k3; + quad[3] = c2 - k2 + k4; + quad[4] = c1 + k1 + k3; + quad[5] = c2 + k2 + k4; + quad[6] = c1 + k1 - k3; + quad[7] = c2 + k2 - k4; + } + + // find the size of the reference face + btScalar rect[2]; + rect[0] = Sa[code1]; + rect[1] = Sa[code2]; + + // intersect the incident and reference faces + btScalar ret[16]; + int n = intersectRectQuad2(rect, quad, ret); + if (n < 1) return 0; // this should never happen + + // convert the intersection points into reference-face coordinates, + // and compute the contact position and depth for each point. only keep + // those points that have a positive (penetrating) depth. delete points in + // the 'ret' array as necessary so that 'point' and 'ret' correspond. + btScalar point[3 * 8]; // penetrating contact points + btScalar dep[8]; // depths for those points + btScalar det1 = 1.f / (m11 * m22 - m12 * m21); + m11 *= det1; + m12 *= det1; + m21 *= det1; + m22 *= det1; + int cnum = 0; // number of penetrating contact points found + for (j = 0; j < n; j++) + { + btScalar k1 = m22 * (ret[j * 2] - c1) - m12 * (ret[j * 2 + 1] - c2); + btScalar k2 = -m21 * (ret[j * 2] - c1) + m11 * (ret[j * 2 + 1] - c2); + for (i = 0; i < 3; i++) point[cnum * 3 + i] = + center[i] + k1 * Rb[i * 4 + a1] + k2 * Rb[i * 4 + a2]; + dep[cnum] = Sa[codeN] - dDOT(normal2, point + cnum * 3); + if (dep[cnum] >= 0) + { + ret[cnum * 2] = ret[j * 2]; + ret[cnum * 2 + 1] = ret[j * 2 + 1]; + cnum++; + } + } + if (cnum < 1) return 0; // this should never happen + + // we can't generate more contacts than we actually have + if (maxc > cnum) maxc = cnum; + if (maxc < 1) maxc = 1; + + if (cnum <= maxc) + { + if (code < 4) + { + // we have less contacts than we need, so we use them all + for (j = 0; j < cnum; j++) + { + btVector3 pointInWorld; + for (i = 0; i < 3; i++) + pointInWorld[i] = point[j * 3 + i] + pa[i]; + output.addContactPoint(-normal, pointInWorld, -dep[j]); + } + } + else + { + // we have less contacts than we need, so we use them all + for (j = 0; j < cnum; j++) + { + btVector3 pointInWorld; + for (i = 0; i < 3; i++) + pointInWorld[i] = point[j * 3 + i] + pa[i] - normal[i] * dep[j]; //pointInWorld[i] = point[j*3+i] + pa[i]; - output.addContactPoint(-normal,pointInWorld,-dep[j]); + output.addContactPoint(-normal, pointInWorld, -dep[j]); + } } - } - } - else { - // we have more contacts than are wanted, some of them must be culled. - // find the deepest point, it is always the first contact. - int i1 = 0; - btScalar maxdepth = dep[0]; - for (i=1; i maxdepth) { - maxdepth = dep[i]; - i1 = i; - } - } - - int iret[8]; - cullPoints2 (cnum,ret,maxc,i1,iret); - - for (j=0; j < maxc; j++) { -// dContactGeom *con = CONTACT(contact,skip*j); - // for (i=0; i<3; i++) con->pos[i] = point[iret[j]*3+i] + pa[i]; - // con->depth = dep[iret[j]]; - - btVector3 posInWorld; - for (i=0; i<3; i++) - posInWorld[i] = point[iret[j]*3+i] + pa[i]; - if (code<4) - { - output.addContactPoint(-normal,posInWorld,-dep[iret[j]]); - } else + } + else + { + // we have more contacts than are wanted, some of them must be culled. + // find the deepest point, it is always the first contact. + int i1 = 0; + btScalar maxdepth = dep[0]; + for (i = 1; i < cnum; i++) { - output.addContactPoint(-normal,posInWorld-normal*dep[iret[j]],-dep[iret[j]]); + if (dep[i] > maxdepth) + { + maxdepth = dep[i]; + i1 = i; + } } - } - cnum = maxc; - } - *return_code = code; - return cnum; + int iret[8]; + cullPoints2(cnum, ret, maxc, i1, iret); + + for (j = 0; j < maxc; j++) + { + // dContactGeom *con = CONTACT(contact,skip*j); + // for (i=0; i<3; i++) con->pos[i] = point[iret[j]*3+i] + pa[i]; + // con->depth = dep[iret[j]]; + + btVector3 posInWorld; + for (i = 0; i < 3; i++) + posInWorld[i] = point[iret[j] * 3 + i] + pa[i]; + if (code < 4) + { + output.addContactPoint(-normal, posInWorld, -dep[iret[j]]); + } + else + { + output.addContactPoint(-normal, posInWorld - normal * dep[iret[j]], -dep[iret[j]]); + } + } + cnum = maxc; + } + + *return_code = code; + return cnum; } -void btBoxBoxDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* /*debugDraw*/,bool /*swapResults*/) +void btBoxBoxDetector::getClosestPoints(const ClosestPointInput& input, Result& output, class btIDebugDraw* /*debugDraw*/, bool /*swapResults*/) { - const btTransform& transformA = input.m_transformA; const btTransform& transformB = input.m_transformB; - + int skip = 0; - dContactGeom *contact = 0; + dContactGeom* contact = 0; dMatrix3 R1; dMatrix3 R2; - for (int j=0;j<3;j++) + for (int j = 0; j < 3; j++) { - R1[0+4*j] = transformA.getBasis()[j].x(); - R2[0+4*j] = transformB.getBasis()[j].x(); + R1[0 + 4 * j] = transformA.getBasis()[j].x(); + R2[0 + 4 * j] = transformB.getBasis()[j].x(); - R1[1+4*j] = transformA.getBasis()[j].y(); - R2[1+4*j] = transformB.getBasis()[j].y(); - - - R1[2+4*j] = transformA.getBasis()[j].z(); - R2[2+4*j] = transformB.getBasis()[j].z(); + R1[1 + 4 * j] = transformA.getBasis()[j].y(); + R2[1 + 4 * j] = transformB.getBasis()[j].y(); + R1[2 + 4 * j] = transformA.getBasis()[j].z(); + R2[2 + 4 * j] = transformB.getBasis()[j].z(); } - - btVector3 normal; btScalar depth; int return_code; int maxc = 4; - - dBoxBox2 (transformA.getOrigin(), - R1, - 2.f*m_box1->getHalfExtentsWithMargin(), - transformB.getOrigin(), - R2, - 2.f*m_box2->getHalfExtentsWithMargin(), - normal, &depth, &return_code, - maxc, contact, skip, - output - ); - + dBoxBox2(transformA.getOrigin(), + R1, + 2.f * m_box1->getHalfExtentsWithMargin(), + transformB.getOrigin(), + R2, + 2.f * m_box2->getHalfExtentsWithMargin(), + normal, &depth, &return_code, + maxc, contact, skip, + output); } diff --git a/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.h b/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.h index 392437770..9f7d988fc 100644 --- a/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.h +++ b/src/BulletCollision/CollisionDispatch/btBoxBoxDetector.h @@ -19,11 +19,9 @@ subject to the following restrictions: #ifndef BT_BOX_BOX_DETECTOR_H #define BT_BOX_BOX_DETECTOR_H - class btBoxShape; #include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h" - /// btBoxBoxDetector wraps the ODE box-box collision detector /// re-distributed under the Zlib license with permission from Russell L. Smith struct btBoxBoxDetector : public btDiscreteCollisionDetectorInterface @@ -32,13 +30,11 @@ struct btBoxBoxDetector : public btDiscreteCollisionDetectorInterface const btBoxShape* m_box2; public: + btBoxBoxDetector(const btBoxShape* box1, const btBoxShape* box2); - btBoxBoxDetector(const btBoxShape* box1,const btBoxShape* box2); - - virtual ~btBoxBoxDetector() {}; - - virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false); + virtual ~btBoxBoxDetector(){}; + virtual void getClosestPoints(const ClosestPointInput& input, Result& output, class btIDebugDraw* debugDraw, bool swapResults = false); }; -#endif //BT_BOX_BOX_DETECTOR_H +#endif //BT_BOX_BOX_DETECTOR_H diff --git a/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h b/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h index 35f77d4e6..d6e15f555 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h +++ b/src/BulletCollision/CollisionDispatch/btCollisionConfiguration.h @@ -23,11 +23,9 @@ class btPoolAllocator; ///btCollisionConfiguration allows to configure Bullet collision detection ///stack allocator size, default collision algorithms and persistent manifold pool size ///@todo: describe the meaning -class btCollisionConfiguration +class btCollisionConfiguration { - public: - virtual ~btCollisionConfiguration() { } @@ -37,13 +35,9 @@ public: virtual btPoolAllocator* getCollisionAlgorithmPool() = 0; - - virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1) =0; + virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1) = 0; virtual btCollisionAlgorithmCreateFunc* getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1) = 0; - - }; -#endif //BT_COLLISION_CONFIGURATION - +#endif //BT_COLLISION_CONFIGURATION diff --git a/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h b/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h index 62ee66c4e..bd8128493 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h +++ b/src/BulletCollision/CollisionDispatch/btCollisionCreateFunc.h @@ -26,20 +26,18 @@ struct btCollisionAlgorithmConstructionInfo; struct btCollisionAlgorithmCreateFunc { bool m_swapped; - + btCollisionAlgorithmCreateFunc() - :m_swapped(false) + : m_swapped(false) { } virtual ~btCollisionAlgorithmCreateFunc(){}; - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& , const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo&, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { - (void)body0Wrap; (void)body1Wrap; return 0; } }; -#endif //BT_COLLISION_CREATE_FUNC - +#endif //BT_COLLISION_CREATE_FUNC diff --git a/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp b/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp index f8794dec4..25b2b1ea4 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp +++ b/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.cpp @@ -13,8 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "btCollisionDispatcher.h" #include "LinearMath/btQuickprof.h" @@ -31,40 +29,34 @@ subject to the following restrictions: #include #endif - -btCollisionDispatcher::btCollisionDispatcher (btCollisionConfiguration* collisionConfiguration): -m_dispatcherFlags(btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD), - m_collisionConfiguration(collisionConfiguration) +btCollisionDispatcher::btCollisionDispatcher(btCollisionConfiguration* collisionConfiguration) : m_dispatcherFlags(btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD), + m_collisionConfiguration(collisionConfiguration) { int i; setNearCallback(defaultNearCallback); - + m_collisionAlgorithmPoolAllocator = collisionConfiguration->getCollisionAlgorithmPool(); m_persistentManifoldPoolAllocator = collisionConfiguration->getPersistentManifoldPool(); - for (i=0;igetCollisionAlgorithmCreateFunc(i,j); + m_doubleDispatchContactPoints[i][j] = m_collisionConfiguration->getCollisionAlgorithmCreateFunc(i, j); btAssert(m_doubleDispatchContactPoints[i][j]); m_doubleDispatchClosestPoints[i][j] = m_collisionConfiguration->getClosestPointsAlgorithmCreateFunc(i, j); - } } - - } - -void btCollisionDispatcher::registerCollisionCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc) +void btCollisionDispatcher::registerCollisionCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc* createFunc) { m_doubleDispatchContactPoints[proxyType0][proxyType1] = createFunc; } -void btCollisionDispatcher::registerClosestPointsCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc) +void btCollisionDispatcher::registerClosestPointsCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc* createFunc) { m_doubleDispatchClosestPoints[proxyType0][proxyType1] = createFunc; } @@ -73,35 +65,33 @@ btCollisionDispatcher::~btCollisionDispatcher() { } -btPersistentManifold* btCollisionDispatcher::getNewManifold(const btCollisionObject* body0,const btCollisionObject* body1) -{ +btPersistentManifold* btCollisionDispatcher::getNewManifold(const btCollisionObject* body0, const btCollisionObject* body1) +{ //btAssert(gNumManifold < 65535); - - //optional relative contact breaking threshold, turned on by default (use setDispatcherFlags to switch off feature for improved performance) - - btScalar contactBreakingThreshold = (m_dispatcherFlags & btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD) ? - btMin(body0->getCollisionShape()->getContactBreakingThreshold(gContactBreakingThreshold) , body1->getCollisionShape()->getContactBreakingThreshold(gContactBreakingThreshold)) - : gContactBreakingThreshold ; - btScalar contactProcessingThreshold = btMin(body0->getContactProcessingThreshold(),body1->getContactProcessingThreshold()); - - void* mem = m_persistentManifoldPoolAllocator->allocate( sizeof( btPersistentManifold ) ); - if (NULL == mem) + btScalar contactBreakingThreshold = (m_dispatcherFlags & btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD) ? btMin(body0->getCollisionShape()->getContactBreakingThreshold(gContactBreakingThreshold), body1->getCollisionShape()->getContactBreakingThreshold(gContactBreakingThreshold)) + : gContactBreakingThreshold; + + btScalar contactProcessingThreshold = btMin(body0->getContactProcessingThreshold(), body1->getContactProcessingThreshold()); + + void* mem = m_persistentManifoldPoolAllocator->allocate(sizeof(btPersistentManifold)); + if (NULL == mem) { - //we got a pool memory overflow, by default we fallback to dynamically allocate memory. If we require a contiguous contact pool then assert. - if ((m_dispatcherFlags&CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION)==0) + //we got a pool memory overflow, by default we fallback to dynamically allocate memory. If we require a contiguous contact pool then assert. + if ((m_dispatcherFlags & CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION) == 0) { - mem = btAlignedAlloc(sizeof(btPersistentManifold),16); - } else + mem = btAlignedAlloc(sizeof(btPersistentManifold), 16); + } + else { btAssert(0); //make sure to increase the m_defaultMaxPersistentManifoldPoolSize in the btDefaultCollisionConstructionInfo/btDefaultCollisionConfiguration return 0; } } - btPersistentManifold* manifold = new(mem) btPersistentManifold (body0,body1,0,contactBreakingThreshold,contactProcessingThreshold); + btPersistentManifold* manifold = new (mem) btPersistentManifold(body0, body1, 0, contactBreakingThreshold, contactProcessingThreshold); manifold->m_index1a = m_manifoldsPtr.size(); m_manifoldsPtr.push_back(manifold); @@ -113,17 +103,14 @@ void btCollisionDispatcher::clearManifold(btPersistentManifold* manifold) manifold->clearManifold(); } - void btCollisionDispatcher::releaseManifold(btPersistentManifold* manifold) { - - //printf("releaseManifold: gNumManifold %d\n",gNumManifold); clearManifold(manifold); int findIndex = manifold->m_index1a; btAssert(findIndex < m_manifoldsPtr.size()); - m_manifoldsPtr.swap(findIndex,m_manifoldsPtr.size()-1); + m_manifoldsPtr.swap(findIndex, m_manifoldsPtr.size() - 1); m_manifoldsPtr[findIndex]->m_index1a = findIndex; m_manifoldsPtr.pop_back(); @@ -131,19 +118,15 @@ void btCollisionDispatcher::releaseManifold(btPersistentManifold* manifold) if (m_persistentManifoldPoolAllocator->validPtr(manifold)) { m_persistentManifoldPoolAllocator->freeMemory(manifold); - } else + } + else { btAlignedFree(manifold); } - } - - - -btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btPersistentManifold* sharedManifold, ebtDispatcherQueryType algoType) +btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, btPersistentManifold* sharedManifold, ebtDispatcherQueryType algoType) { - btCollisionAlgorithmConstructionInfo ci; ci.m_dispatcher1 = this; @@ -161,21 +144,18 @@ btCollisionAlgorithm* btCollisionDispatcher::findAlgorithm(const btCollisionObje return algo; } - - - -bool btCollisionDispatcher::needsResponse(const btCollisionObject* body0,const btCollisionObject* body1) +bool btCollisionDispatcher::needsResponse(const btCollisionObject* body0, const btCollisionObject* body1) { //here you can do filtering - bool hasResponse = + bool hasResponse = (body0->hasContactResponse() && body1->hasContactResponse()); //no response between two static/kinematic bodies: hasResponse = hasResponse && - ((!body0->isStaticOrKinematicObject()) ||(! body1->isStaticOrKinematicObject())); + ((!body0->isStaticOrKinematicObject()) || (!body1->isStaticOrKinematicObject())); return hasResponse; } -bool btCollisionDispatcher::needsCollision(const btCollisionObject* body0,const btCollisionObject* body1) +bool btCollisionDispatcher::needsCollision(const btCollisionObject* body0, const btCollisionObject* body1) { btAssert(body0); btAssert(body1); @@ -192,31 +172,27 @@ bool btCollisionDispatcher::needsCollision(const btCollisionObject* body0,const printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n"); } } -#endif //BT_DEBUG +#endif //BT_DEBUG if ((!body0->isActive()) && (!body1->isActive())) needsCollision = false; else if ((!body0->checkCollideWith(body1)) || (!body1->checkCollideWith(body0))) needsCollision = false; - - return needsCollision ; + return needsCollision; } - - ///interface for iterating all overlapping collision pairs, no matter how those pairs are stored (array, set, map etc) ///this is useful for the collision dispatcher. class btCollisionPairCallback : public btOverlapCallback { const btDispatcherInfo& m_dispatchInfo; - btCollisionDispatcher* m_dispatcher; + btCollisionDispatcher* m_dispatcher; public: - - btCollisionPairCallback(const btDispatcherInfo& dispatchInfo,btCollisionDispatcher* dispatcher) - :m_dispatchInfo(dispatchInfo), - m_dispatcher(dispatcher) + btCollisionPairCallback(const btDispatcherInfo& dispatchInfo, btCollisionDispatcher* dispatcher) + : m_dispatchInfo(dispatchInfo), + m_dispatcher(dispatcher) { } @@ -228,87 +204,76 @@ public: } */ - virtual ~btCollisionPairCallback() {} - - virtual bool processOverlap(btBroadphasePair& pair) + virtual bool processOverlap(btBroadphasePair& pair) { - (*m_dispatcher->getNearCallback())(pair,*m_dispatcher,m_dispatchInfo); + (*m_dispatcher->getNearCallback())(pair, *m_dispatcher, m_dispatchInfo); return false; } }; - - - -void btCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) +void btCollisionDispatcher::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache, const btDispatcherInfo& dispatchInfo, btDispatcher* dispatcher) { //m_blockedForChanges = true; - btCollisionPairCallback collisionCallback(dispatchInfo,this); + btCollisionPairCallback collisionCallback(dispatchInfo, this); - { + { BT_PROFILE("processAllOverlappingPairs"); - pairCache->processAllOverlappingPairs(&collisionCallback,dispatcher, dispatchInfo); + pairCache->processAllOverlappingPairs(&collisionCallback, dispatcher, dispatchInfo); } //m_blockedForChanges = false; - } - - //by default, Bullet will use this near callback void btCollisionDispatcher::defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo) { - btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject; - btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject; + btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject; + btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject; - if (dispatcher.needsCollision(colObj0,colObj1)) + if (dispatcher.needsCollision(colObj0, colObj1)) + { + btCollisionObjectWrapper obj0Wrap(0, colObj0->getCollisionShape(), colObj0, colObj0->getWorldTransform(), -1, -1); + btCollisionObjectWrapper obj1Wrap(0, colObj1->getCollisionShape(), colObj1, colObj1->getWorldTransform(), -1, -1); + + //dispatcher will keep algorithms persistent in the collision pair + if (!collisionPair.m_algorithm) { - btCollisionObjectWrapper obj0Wrap(0,colObj0->getCollisionShape(),colObj0,colObj0->getWorldTransform(),-1,-1); - btCollisionObjectWrapper obj1Wrap(0,colObj1->getCollisionShape(),colObj1,colObj1->getWorldTransform(),-1,-1); - - - //dispatcher will keep algorithms persistent in the collision pair - if (!collisionPair.m_algorithm) - { - collisionPair.m_algorithm = dispatcher.findAlgorithm(&obj0Wrap,&obj1Wrap,0, BT_CONTACT_POINT_ALGORITHMS); - } - - if (collisionPair.m_algorithm) - { - btManifoldResult contactPointResult(&obj0Wrap,&obj1Wrap); - - if (dispatchInfo.m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE) - { - //discrete collision detection query - - collisionPair.m_algorithm->processCollision(&obj0Wrap,&obj1Wrap,dispatchInfo,&contactPointResult); - } else - { - //continuous collision detection query, time of impact (toi) - btScalar toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0,colObj1,dispatchInfo,&contactPointResult); - if (dispatchInfo.m_timeOfImpact > toi) - dispatchInfo.m_timeOfImpact = toi; - - } - } + collisionPair.m_algorithm = dispatcher.findAlgorithm(&obj0Wrap, &obj1Wrap, 0, BT_CONTACT_POINT_ALGORITHMS); } -} + if (collisionPair.m_algorithm) + { + btManifoldResult contactPointResult(&obj0Wrap, &obj1Wrap); + if (dispatchInfo.m_dispatchFunc == btDispatcherInfo::DISPATCH_DISCRETE) + { + //discrete collision detection query + + collisionPair.m_algorithm->processCollision(&obj0Wrap, &obj1Wrap, dispatchInfo, &contactPointResult); + } + else + { + //continuous collision detection query, time of impact (toi) + btScalar toi = collisionPair.m_algorithm->calculateTimeOfImpact(colObj0, colObj1, dispatchInfo, &contactPointResult); + if (dispatchInfo.m_timeOfImpact > toi) + dispatchInfo.m_timeOfImpact = toi; + } + } + } +} void* btCollisionDispatcher::allocateCollisionAlgorithm(int size) { - void* mem = m_collisionAlgorithmPoolAllocator->allocate( size ); - if (NULL == mem) - { - //warn user for overflow? - return btAlignedAlloc(static_cast(size), 16); - } - return mem; + void* mem = m_collisionAlgorithmPoolAllocator->allocate(size); + if (NULL == mem) + { + //warn user for overflow? + return btAlignedAlloc(static_cast(size), 16); + } + return mem; } void btCollisionDispatcher::freeCollisionAlgorithm(void* ptr) @@ -316,7 +281,8 @@ void btCollisionDispatcher::freeCollisionAlgorithm(void* ptr) if (m_collisionAlgorithmPoolAllocator->validPtr(ptr)) { m_collisionAlgorithmPoolAllocator->freeMemory(ptr); - } else + } + else { btAlignedFree(ptr); } diff --git a/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h b/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h index b97ee3c1b..6b9f5e23a 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h +++ b/src/BulletCollision/CollisionDispatch/btCollisionDispatcher.h @@ -37,35 +37,30 @@ class btCollisionDispatcher; ///user can override this nearcallback for collision filtering and more finegrained control over collision detection typedef void (*btNearCallback)(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo); - ///btCollisionDispatcher supports algorithms that handle ConvexConvex and ConvexConcave collision pairs. ///Time of Impact, Closest Points and Penetration Depth. class btCollisionDispatcher : public btDispatcher { - protected: + int m_dispatcherFlags; - int m_dispatcherFlags; + btAlignedObjectArray m_manifoldsPtr; - btAlignedObjectArray m_manifoldsPtr; + btManifoldResult m_defaultManifoldResult; - btManifoldResult m_defaultManifoldResult; + btNearCallback m_nearCallback; - btNearCallback m_nearCallback; - - btPoolAllocator* m_collisionAlgorithmPoolAllocator; + btPoolAllocator* m_collisionAlgorithmPoolAllocator; - btPoolAllocator* m_persistentManifoldPoolAllocator; + btPoolAllocator* m_persistentManifoldPoolAllocator; btCollisionAlgorithmCreateFunc* m_doubleDispatchContactPoints[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES]; btCollisionAlgorithmCreateFunc* m_doubleDispatchClosestPoints[MAX_BROADPHASE_COLLISION_TYPES][MAX_BROADPHASE_COLLISION_TYPES]; - btCollisionConfiguration* m_collisionConfiguration; - + btCollisionConfiguration* m_collisionConfiguration; public: - enum DispatcherFlags { CD_STATIC_STATIC_REPORTED = 1, @@ -73,103 +68,100 @@ public: CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION = 4 }; - int getDispatcherFlags() const + int getDispatcherFlags() const { return m_dispatcherFlags; } - void setDispatcherFlags(int flags) + void setDispatcherFlags(int flags) { m_dispatcherFlags = flags; } ///registerCollisionCreateFunc allows registration of custom/alternative collision create functions - void registerCollisionCreateFunc(int proxyType0,int proxyType1, btCollisionAlgorithmCreateFunc* createFunc); + void registerCollisionCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc* createFunc); - void registerClosestPointsCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc *createFunc); + void registerClosestPointsCreateFunc(int proxyType0, int proxyType1, btCollisionAlgorithmCreateFunc* createFunc); - int getNumManifolds() const - { - return int( m_manifoldsPtr.size()); - } - - btPersistentManifold** getInternalManifoldPointer() + int getNumManifolds() const { - return m_manifoldsPtr.size()? &m_manifoldsPtr[0] : 0; + return int(m_manifoldsPtr.size()); } - btPersistentManifold* getManifoldByIndexInternal(int index) + btPersistentManifold** getInternalManifoldPointer() + { + return m_manifoldsPtr.size() ? &m_manifoldsPtr[0] : 0; + } + + btPersistentManifold* getManifoldByIndexInternal(int index) { return m_manifoldsPtr[index]; } - const btPersistentManifold* getManifoldByIndexInternal(int index) const + const btPersistentManifold* getManifoldByIndexInternal(int index) const { return m_manifoldsPtr[index]; } - btCollisionDispatcher (btCollisionConfiguration* collisionConfiguration); + btCollisionDispatcher(btCollisionConfiguration* collisionConfiguration); virtual ~btCollisionDispatcher(); - virtual btPersistentManifold* getNewManifold(const btCollisionObject* b0,const btCollisionObject* b1); - - virtual void releaseManifold(btPersistentManifold* manifold); + virtual btPersistentManifold* getNewManifold(const btCollisionObject* b0, const btCollisionObject* b1); + virtual void releaseManifold(btPersistentManifold* manifold); virtual void clearManifold(btPersistentManifold* manifold); - btCollisionAlgorithm* findAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btPersistentManifold* sharedManifold, ebtDispatcherQueryType queryType); - - virtual bool needsCollision(const btCollisionObject* body0,const btCollisionObject* body1); - - virtual bool needsResponse(const btCollisionObject* body0,const btCollisionObject* body1); - - virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) ; + btCollisionAlgorithm* findAlgorithm(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, btPersistentManifold* sharedManifold, ebtDispatcherQueryType queryType); - void setNearCallback(btNearCallback nearCallback) + virtual bool needsCollision(const btCollisionObject* body0, const btCollisionObject* body1); + + virtual bool needsResponse(const btCollisionObject* body0, const btCollisionObject* body1); + + virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache, const btDispatcherInfo& dispatchInfo, btDispatcher* dispatcher); + + void setNearCallback(btNearCallback nearCallback) { - m_nearCallback = nearCallback; + m_nearCallback = nearCallback; } - btNearCallback getNearCallback() const + btNearCallback getNearCallback() const { return m_nearCallback; } //by default, Bullet will use this near callback - static void defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo); + static void defaultNearCallback(btBroadphasePair& collisionPair, btCollisionDispatcher& dispatcher, const btDispatcherInfo& dispatchInfo); - virtual void* allocateCollisionAlgorithm(int size); + virtual void* allocateCollisionAlgorithm(int size); - virtual void freeCollisionAlgorithm(void* ptr); + virtual void freeCollisionAlgorithm(void* ptr); - btCollisionConfiguration* getCollisionConfiguration() + btCollisionConfiguration* getCollisionConfiguration() { return m_collisionConfiguration; } - const btCollisionConfiguration* getCollisionConfiguration() const + const btCollisionConfiguration* getCollisionConfiguration() const { return m_collisionConfiguration; } - void setCollisionConfiguration(btCollisionConfiguration* config) + void setCollisionConfiguration(btCollisionConfiguration* config) { m_collisionConfiguration = config; } - virtual btPoolAllocator* getInternalManifoldPool() + virtual btPoolAllocator* getInternalManifoldPool() { return m_persistentManifoldPoolAllocator; } - virtual const btPoolAllocator* getInternalManifoldPool() const + virtual const btPoolAllocator* getInternalManifoldPool() const { return m_persistentManifoldPoolAllocator; } - }; -#endif //BT_COLLISION__DISPATCHER_H - +#endif //BT_COLLISION__DISPATCHER_H diff --git a/src/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.cpp b/src/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.cpp index 075860c50..6fe56538d 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.cpp +++ b/src/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.cpp @@ -13,8 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "btCollisionDispatcherMt.h" #include "LinearMath/btQuickprof.h" @@ -27,138 +25,132 @@ subject to the following restrictions: #include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h" #include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" - -btCollisionDispatcherMt::btCollisionDispatcherMt( btCollisionConfiguration* config, int grainSize ) - : btCollisionDispatcher( config ) +btCollisionDispatcherMt::btCollisionDispatcherMt(btCollisionConfiguration* config, int grainSize) + : btCollisionDispatcher(config) { - m_batchUpdating = false; - m_grainSize = grainSize; // iterations per task + m_batchUpdating = false; + m_grainSize = grainSize; // iterations per task } - -btPersistentManifold* btCollisionDispatcherMt::getNewManifold( const btCollisionObject* body0, const btCollisionObject* body1 ) +btPersistentManifold* btCollisionDispatcherMt::getNewManifold(const btCollisionObject* body0, const btCollisionObject* body1) { - //optional relative contact breaking threshold, turned on by default (use setDispatcherFlags to switch off feature for improved performance) + //optional relative contact breaking threshold, turned on by default (use setDispatcherFlags to switch off feature for improved performance) - btScalar contactBreakingThreshold = ( m_dispatcherFlags & btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD ) ? - btMin( body0->getCollisionShape()->getContactBreakingThreshold( gContactBreakingThreshold ), body1->getCollisionShape()->getContactBreakingThreshold( gContactBreakingThreshold ) ) - : gContactBreakingThreshold; + btScalar contactBreakingThreshold = (m_dispatcherFlags & btCollisionDispatcher::CD_USE_RELATIVE_CONTACT_BREAKING_THRESHOLD) ? btMin(body0->getCollisionShape()->getContactBreakingThreshold(gContactBreakingThreshold), body1->getCollisionShape()->getContactBreakingThreshold(gContactBreakingThreshold)) + : gContactBreakingThreshold; - btScalar contactProcessingThreshold = btMin( body0->getContactProcessingThreshold(), body1->getContactProcessingThreshold() ); + btScalar contactProcessingThreshold = btMin(body0->getContactProcessingThreshold(), body1->getContactProcessingThreshold()); - void* mem = m_persistentManifoldPoolAllocator->allocate( sizeof( btPersistentManifold ) ); - if ( NULL == mem ) - { - //we got a pool memory overflow, by default we fallback to dynamically allocate memory. If we require a contiguous contact pool then assert. - if ( ( m_dispatcherFlags&CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION ) == 0 ) - { - mem = btAlignedAlloc( sizeof( btPersistentManifold ), 16 ); - } - else - { - btAssert( 0 ); - //make sure to increase the m_defaultMaxPersistentManifoldPoolSize in the btDefaultCollisionConstructionInfo/btDefaultCollisionConfiguration - return 0; - } - } - btPersistentManifold* manifold = new( mem ) btPersistentManifold( body0, body1, 0, contactBreakingThreshold, contactProcessingThreshold ); - if ( !m_batchUpdating ) - { - // batch updater will update manifold pointers array after finishing, so - // only need to update array when not batch-updating - //btAssert( !btThreadsAreRunning() ); - manifold->m_index1a = m_manifoldsPtr.size(); - m_manifoldsPtr.push_back( manifold ); - } + void* mem = m_persistentManifoldPoolAllocator->allocate(sizeof(btPersistentManifold)); + if (NULL == mem) + { + //we got a pool memory overflow, by default we fallback to dynamically allocate memory. If we require a contiguous contact pool then assert. + if ((m_dispatcherFlags & CD_DISABLE_CONTACTPOOL_DYNAMIC_ALLOCATION) == 0) + { + mem = btAlignedAlloc(sizeof(btPersistentManifold), 16); + } + else + { + btAssert(0); + //make sure to increase the m_defaultMaxPersistentManifoldPoolSize in the btDefaultCollisionConstructionInfo/btDefaultCollisionConfiguration + return 0; + } + } + btPersistentManifold* manifold = new (mem) btPersistentManifold(body0, body1, 0, contactBreakingThreshold, contactProcessingThreshold); + if (!m_batchUpdating) + { + // batch updater will update manifold pointers array after finishing, so + // only need to update array when not batch-updating + //btAssert( !btThreadsAreRunning() ); + manifold->m_index1a = m_manifoldsPtr.size(); + m_manifoldsPtr.push_back(manifold); + } - return manifold; + return manifold; } -void btCollisionDispatcherMt::releaseManifold( btPersistentManifold* manifold ) +void btCollisionDispatcherMt::releaseManifold(btPersistentManifold* manifold) { - clearManifold( manifold ); - //btAssert( !btThreadsAreRunning() ); - if ( !m_batchUpdating ) - { - // batch updater will update manifold pointers array after finishing, so - // only need to update array when not batch-updating - int findIndex = manifold->m_index1a; - btAssert( findIndex < m_manifoldsPtr.size() ); - m_manifoldsPtr.swap( findIndex, m_manifoldsPtr.size() - 1 ); - m_manifoldsPtr[ findIndex ]->m_index1a = findIndex; - m_manifoldsPtr.pop_back(); - } + clearManifold(manifold); + //btAssert( !btThreadsAreRunning() ); + if (!m_batchUpdating) + { + // batch updater will update manifold pointers array after finishing, so + // only need to update array when not batch-updating + int findIndex = manifold->m_index1a; + btAssert(findIndex < m_manifoldsPtr.size()); + m_manifoldsPtr.swap(findIndex, m_manifoldsPtr.size() - 1); + m_manifoldsPtr[findIndex]->m_index1a = findIndex; + m_manifoldsPtr.pop_back(); + } - manifold->~btPersistentManifold(); - if ( m_persistentManifoldPoolAllocator->validPtr( manifold ) ) - { - m_persistentManifoldPoolAllocator->freeMemory( manifold ); - } - else - { - btAlignedFree( manifold ); - } + manifold->~btPersistentManifold(); + if (m_persistentManifoldPoolAllocator->validPtr(manifold)) + { + m_persistentManifoldPoolAllocator->freeMemory(manifold); + } + else + { + btAlignedFree(manifold); + } } struct CollisionDispatcherUpdater : public btIParallelForBody { - btBroadphasePair* mPairArray; - btNearCallback mCallback; - btCollisionDispatcher* mDispatcher; - const btDispatcherInfo* mInfo; + btBroadphasePair* mPairArray; + btNearCallback mCallback; + btCollisionDispatcher* mDispatcher; + const btDispatcherInfo* mInfo; - CollisionDispatcherUpdater() - { - mPairArray = NULL; - mCallback = NULL; - mDispatcher = NULL; - mInfo = NULL; - } - void forLoop( int iBegin, int iEnd ) const - { - for ( int i = iBegin; i < iEnd; ++i ) - { - btBroadphasePair* pair = &mPairArray[ i ]; - mCallback( *pair, *mDispatcher, *mInfo ); - } - } + CollisionDispatcherUpdater() + { + mPairArray = NULL; + mCallback = NULL; + mDispatcher = NULL; + mInfo = NULL; + } + void forLoop(int iBegin, int iEnd) const + { + for (int i = iBegin; i < iEnd; ++i) + { + btBroadphasePair* pair = &mPairArray[i]; + mCallback(*pair, *mDispatcher, *mInfo); + } + } }; - -void btCollisionDispatcherMt::dispatchAllCollisionPairs( btOverlappingPairCache* pairCache, const btDispatcherInfo& info, btDispatcher* dispatcher ) +void btCollisionDispatcherMt::dispatchAllCollisionPairs(btOverlappingPairCache* pairCache, const btDispatcherInfo& info, btDispatcher* dispatcher) { - int pairCount = pairCache->getNumOverlappingPairs(); - if ( pairCount == 0 ) - { - return; - } - CollisionDispatcherUpdater updater; - updater.mCallback = getNearCallback(); - updater.mPairArray = pairCache->getOverlappingPairArrayPtr(); - updater.mDispatcher = this; - updater.mInfo = &info; + int pairCount = pairCache->getNumOverlappingPairs(); + if (pairCount == 0) + { + return; + } + CollisionDispatcherUpdater updater; + updater.mCallback = getNearCallback(); + updater.mPairArray = pairCache->getOverlappingPairArrayPtr(); + updater.mDispatcher = this; + updater.mInfo = &info; - m_batchUpdating = true; - btParallelFor( 0, pairCount, m_grainSize, updater ); - m_batchUpdating = false; + m_batchUpdating = true; + btParallelFor(0, pairCount, m_grainSize, updater); + m_batchUpdating = false; - // reconstruct the manifolds array to ensure determinism - m_manifoldsPtr.resizeNoInitialize( 0 ); + // reconstruct the manifolds array to ensure determinism + m_manifoldsPtr.resizeNoInitialize(0); - btBroadphasePair* pairs = pairCache->getOverlappingPairArrayPtr(); - for ( int i = 0; i < pairCount; ++i ) - { - if (btCollisionAlgorithm* algo = pairs[ i ].m_algorithm) - { - algo->getAllContactManifolds( m_manifoldsPtr ); - } - } + btBroadphasePair* pairs = pairCache->getOverlappingPairArrayPtr(); + for (int i = 0; i < pairCount; ++i) + { + if (btCollisionAlgorithm* algo = pairs[i].m_algorithm) + { + algo->getAllContactManifolds(m_manifoldsPtr); + } + } - // update the indices (used when releasing manifolds) - for ( int i = 0; i < m_manifoldsPtr.size(); ++i ) - { - m_manifoldsPtr[ i ]->m_index1a = i; - } + // update the indices (used when releasing manifolds) + for (int i = 0; i < m_manifoldsPtr.size(); ++i) + { + m_manifoldsPtr[i]->m_index1a = i; + } } - - diff --git a/src/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.h b/src/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.h index f1d7eafdc..28eba7f32 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.h +++ b/src/BulletCollision/CollisionDispatch/btCollisionDispatcherMt.h @@ -19,21 +19,19 @@ subject to the following restrictions: #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" #include "LinearMath/btThreads.h" - class btCollisionDispatcherMt : public btCollisionDispatcher { public: - btCollisionDispatcherMt( btCollisionConfiguration* config, int grainSize = 40 ); + btCollisionDispatcherMt(btCollisionConfiguration* config, int grainSize = 40); - virtual btPersistentManifold* getNewManifold( const btCollisionObject* body0, const btCollisionObject* body1 ) BT_OVERRIDE; - virtual void releaseManifold( btPersistentManifold* manifold ) BT_OVERRIDE; + virtual btPersistentManifold* getNewManifold(const btCollisionObject* body0, const btCollisionObject* body1) BT_OVERRIDE; + virtual void releaseManifold(btPersistentManifold* manifold) BT_OVERRIDE; - virtual void dispatchAllCollisionPairs( btOverlappingPairCache* pairCache, const btDispatcherInfo& info, btDispatcher* dispatcher ) BT_OVERRIDE; + virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache, const btDispatcherInfo& info, btDispatcher* dispatcher) BT_OVERRIDE; protected: - bool m_batchUpdating; - int m_grainSize; + bool m_batchUpdating; + int m_grainSize; }; -#endif //BT_COLLISION_DISPATCHER_MT_H - +#endif //BT_COLLISION_DISPATCHER_MT_H diff --git a/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp b/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp index 05f96a14b..98a02d0c4 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp +++ b/src/BulletCollision/CollisionDispatch/btCollisionObject.cpp @@ -13,42 +13,41 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btCollisionObject.h" #include "LinearMath/btSerializer.h" #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" btCollisionObject::btCollisionObject() - : m_interpolationLinearVelocity(0.f, 0.f, 0.f), - m_interpolationAngularVelocity(0.f, 0.f, 0.f), - m_anisotropicFriction(1.f,1.f,1.f), - m_hasAnisotropicFriction(false), - m_contactProcessingThreshold(BT_LARGE_FLOAT), - m_broadphaseHandle(0), - m_collisionShape(0), - m_extensionPointer(0), - m_rootCollisionShape(0), - m_collisionFlags(btCollisionObject::CF_STATIC_OBJECT), - m_islandTag1(-1), - m_companionId(-1), - m_worldArrayIndex(-1), - m_activationState1(1), - m_deactivationTime(btScalar(0.)), - m_friction(btScalar(0.5)), - m_restitution(btScalar(0.)), - m_rollingFriction(0.0f), - m_spinningFriction(0.f), - m_contactDamping(.1), - m_contactStiffness(BT_LARGE_FLOAT), - m_internalType(CO_COLLISION_OBJECT), - m_userObjectPointer(0), - m_userIndex2(-1), - m_userIndex(-1), - m_hitFraction(btScalar(1.)), - m_ccdSweptSphereRadius(btScalar(0.)), - m_ccdMotionThreshold(btScalar(0.)), - m_checkCollideWith(false), - m_updateRevision(0) + : m_interpolationLinearVelocity(0.f, 0.f, 0.f), + m_interpolationAngularVelocity(0.f, 0.f, 0.f), + m_anisotropicFriction(1.f, 1.f, 1.f), + m_hasAnisotropicFriction(false), + m_contactProcessingThreshold(BT_LARGE_FLOAT), + m_broadphaseHandle(0), + m_collisionShape(0), + m_extensionPointer(0), + m_rootCollisionShape(0), + m_collisionFlags(btCollisionObject::CF_STATIC_OBJECT), + m_islandTag1(-1), + m_companionId(-1), + m_worldArrayIndex(-1), + m_activationState1(1), + m_deactivationTime(btScalar(0.)), + m_friction(btScalar(0.5)), + m_restitution(btScalar(0.)), + m_rollingFriction(0.0f), + m_spinningFriction(0.f), + m_contactDamping(.1), + m_contactStiffness(BT_LARGE_FLOAT), + m_internalType(CO_COLLISION_OBJECT), + m_userObjectPointer(0), + m_userIndex2(-1), + m_userIndex(-1), + m_hitFraction(btScalar(1.)), + m_ccdSweptSphereRadius(btScalar(0.)), + m_ccdMotionThreshold(btScalar(0.)), + m_checkCollideWith(false), + m_updateRevision(0) { m_worldTransform.setIdentity(); m_interpolationWorldTransform.setIdentity(); @@ -59,8 +58,8 @@ btCollisionObject::~btCollisionObject() } void btCollisionObject::setActivationState(int newState) const -{ - if ( (m_activationState1 != DISABLE_DEACTIVATION) && (m_activationState1 != DISABLE_SIMULATION)) +{ + if ((m_activationState1 != DISABLE_DEACTIVATION) && (m_activationState1 != DISABLE_SIMULATION)) m_activationState1 = newState; } @@ -71,7 +70,7 @@ void btCollisionObject::forceActivationState(int newState) const void btCollisionObject::activate(bool forceActivation) const { - if (forceActivation || !(m_collisionFlags & (CF_STATIC_OBJECT|CF_KINEMATIC_OBJECT))) + if (forceActivation || !(m_collisionFlags & (CF_STATIC_OBJECT | CF_KINEMATIC_OBJECT))) { setActivationState(ACTIVE_TAG); m_deactivationTime = btScalar(0.); @@ -80,7 +79,6 @@ void btCollisionObject::activate(bool forceActivation) const const char* btCollisionObject::serialize(void* dataBuffer, btSerializer* serializer) const { - btCollisionObjectData* dataOut = (btCollisionObjectData*)dataBuffer; m_worldTransform.serialize(dataOut->m_worldTransform); @@ -92,7 +90,7 @@ const char* btCollisionObject::serialize(void* dataBuffer, btSerializer* seriali dataOut->m_contactProcessingThreshold = m_contactProcessingThreshold; dataOut->m_broadphaseHandle = 0; dataOut->m_collisionShape = serializer->getUniquePointer(m_collisionShape); - dataOut->m_rootCollisionShape = 0;//@todo + dataOut->m_rootCollisionShape = 0; //@todo dataOut->m_collisionFlags = m_collisionFlags; dataOut->m_islandTag1 = m_islandTag1; dataOut->m_companionId = m_companionId; @@ -104,8 +102,8 @@ const char* btCollisionObject::serialize(void* dataBuffer, btSerializer* seriali dataOut->m_contactStiffness = m_contactStiffness; dataOut->m_restitution = m_restitution; dataOut->m_internalType = m_internalType; - - char* name = (char*) serializer->findNameForPointer(this); + + char* name = (char*)serializer->findNameForPointer(this); dataOut->m_name = (char*)serializer->getUniquePointer(name); if (dataOut->m_name) { @@ -130,11 +128,10 @@ const char* btCollisionObject::serialize(void* dataBuffer, btSerializer* seriali return btCollisionObjectDataName; } - void btCollisionObject::serializeSingleObject(class btSerializer* serializer) const { int len = calculateSerializeBufferSize(); - btChunk* chunk = serializer->allocate(len,1); + btChunk* chunk = serializer->allocate(len, 1); const char* structType = serialize(chunk->m_oldPtr, serializer); - serializer->finalizeChunk(chunk,structType,BT_COLLISIONOBJECT_CODE,(void*)this); + serializer->finalizeChunk(chunk, structType, BT_COLLISIONOBJECT_CODE, (void*)this); } diff --git a/src/BulletCollision/CollisionDispatch/btCollisionObject.h b/src/BulletCollision/CollisionDispatch/btCollisionObject.h index 135f8a033..56b3d89e5 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionObject.h +++ b/src/BulletCollision/CollisionDispatch/btCollisionObject.h @@ -25,8 +25,8 @@ subject to the following restrictions: #define DISABLE_DEACTIVATION 4 #define DISABLE_SIMULATION 5 -struct btBroadphaseProxy; -class btCollisionShape; +struct btBroadphaseProxy; +class btCollisionShape; struct btCollisionShapeData; #include "LinearMath/btMotionState.h" #include "LinearMath/btAlignedAllocator.h" @@ -42,123 +42,118 @@ typedef btAlignedObjectArray btCollisionObjectArray; #define btCollisionObjectDataName "btCollisionObjectFloatData" #endif - -/// btCollisionObject can be used to manage collision detection objects. +/// btCollisionObject can be used to manage collision detection objects. /// btCollisionObject maintains all information that is needed for a collision detection: Shape, Transform and AABB proxy. /// They can be added to the btCollisionWorld. -ATTRIBUTE_ALIGNED16(class) btCollisionObject +ATTRIBUTE_ALIGNED16(class) +btCollisionObject { - protected: - - btTransform m_worldTransform; + btTransform m_worldTransform; ///m_interpolationWorldTransform is used for CCD and interpolation ///it can be either previous or future (predicted) transform - btTransform m_interpolationWorldTransform; - //those two are experimental: just added for bullet time effect, so you can still apply impulses (directly modifying velocities) + btTransform m_interpolationWorldTransform; + //those two are experimental: just added for bullet time effect, so you can still apply impulses (directly modifying velocities) //without destroying the continuous interpolated motion (which uses this interpolation velocities) - btVector3 m_interpolationLinearVelocity; - btVector3 m_interpolationAngularVelocity; - - btVector3 m_anisotropicFriction; - int m_hasAnisotropicFriction; - btScalar m_contactProcessingThreshold; + btVector3 m_interpolationLinearVelocity; + btVector3 m_interpolationAngularVelocity; - btBroadphaseProxy* m_broadphaseHandle; - btCollisionShape* m_collisionShape; + btVector3 m_anisotropicFriction; + int m_hasAnisotropicFriction; + btScalar m_contactProcessingThreshold; + + btBroadphaseProxy* m_broadphaseHandle; + btCollisionShape* m_collisionShape; ///m_extensionPointer is used by some internal low-level Bullet extensions. - void* m_extensionPointer; - + void* m_extensionPointer; + ///m_rootCollisionShape is temporarily used to store the original collision shape ///The m_collisionShape might be temporarily replaced by a child collision shape during collision detection purposes ///If it is NULL, the m_collisionShape is not temporarily replaced. - btCollisionShape* m_rootCollisionShape; + btCollisionShape* m_rootCollisionShape; - int m_collisionFlags; + int m_collisionFlags; - int m_islandTag1; - int m_companionId; - int m_worldArrayIndex; // index of object in world's collisionObjects array + int m_islandTag1; + int m_companionId; + int m_worldArrayIndex; // index of object in world's collisionObjects array - mutable int m_activationState1; - mutable btScalar m_deactivationTime; + mutable int m_activationState1; + mutable btScalar m_deactivationTime; - btScalar m_friction; - btScalar m_restitution; - btScalar m_rollingFriction;//torsional friction orthogonal to contact normal (useful to stop spheres rolling forever) - btScalar m_spinningFriction; // torsional friction around the contact normal (useful for grasping) - btScalar m_contactDamping; - btScalar m_contactStiffness; - - + btScalar m_friction; + btScalar m_restitution; + btScalar m_rollingFriction; //torsional friction orthogonal to contact normal (useful to stop spheres rolling forever) + btScalar m_spinningFriction; // torsional friction around the contact normal (useful for grasping) + btScalar m_contactDamping; + btScalar m_contactStiffness; ///m_internalType is reserved to distinguish Bullet's btCollisionObject, btRigidBody, btSoftBody, btGhostObject etc. ///do not assign your own m_internalType unless you write a new dynamics object class. - int m_internalType; + int m_internalType; ///users can point to their objects, m_userPointer is not used by Bullet, see setUserPointer/getUserPointer - void* m_userObjectPointer; + void* m_userObjectPointer; - int m_userIndex2; - - int m_userIndex; + int m_userIndex2; + + int m_userIndex; ///time of impact calculation - btScalar m_hitFraction; - + btScalar m_hitFraction; + ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm:: - btScalar m_ccdSweptSphereRadius; + btScalar m_ccdSweptSphereRadius; /// Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold - btScalar m_ccdMotionThreshold; - + btScalar m_ccdMotionThreshold; + /// If some object should have elaborate collision filtering by sub-classes - int m_checkCollideWith; + int m_checkCollideWith; btAlignedObjectArray m_objectsWithoutCollisionCheck; ///internal update revision number. It will be increased when the object changes. This allows some subsystems to perform lazy evaluation. - int m_updateRevision; + int m_updateRevision; - btVector3 m_customDebugColorRGB; + btVector3 m_customDebugColorRGB; public: - BT_DECLARE_ALIGNED_ALLOCATOR(); enum CollisionFlags { - CF_STATIC_OBJECT= 1, - CF_KINEMATIC_OBJECT= 2, + CF_STATIC_OBJECT = 1, + CF_KINEMATIC_OBJECT = 2, CF_NO_CONTACT_RESPONSE = 4, - CF_CUSTOM_MATERIAL_CALLBACK = 8,//this allows per-triangle material (friction/restitution) + CF_CUSTOM_MATERIAL_CALLBACK = 8, //this allows per-triangle material (friction/restitution) CF_CHARACTER_OBJECT = 16, - CF_DISABLE_VISUALIZE_OBJECT = 32, //disable debug drawing - CF_DISABLE_SPU_COLLISION_PROCESSING = 64,//disable parallel/SPU processing + CF_DISABLE_VISUALIZE_OBJECT = 32, //disable debug drawing + CF_DISABLE_SPU_COLLISION_PROCESSING = 64, //disable parallel/SPU processing CF_HAS_CONTACT_STIFFNESS_DAMPING = 128, CF_HAS_CUSTOM_DEBUG_RENDERING_COLOR = 256, CF_HAS_FRICTION_ANCHOR = 512, CF_HAS_COLLISION_SOUND_TRIGGER = 1024 }; - enum CollisionObjectTypes + enum CollisionObjectTypes { - CO_COLLISION_OBJECT =1, - CO_RIGID_BODY=2, + CO_COLLISION_OBJECT = 1, + CO_RIGID_BODY = 2, ///CO_GHOST_OBJECT keeps track of all objects overlapping its AABB and that pass its collision filter ///It is useful for collision sensors, explosion objects, character controller etc. - CO_GHOST_OBJECT=4, - CO_SOFT_BODY=8, - CO_HF_FLUID=16, - CO_USER_TYPE=32, - CO_FEATHERSTONE_LINK=64 + CO_GHOST_OBJECT = 4, + CO_SOFT_BODY = 8, + CO_HF_FLUID = 16, + CO_USER_TYPE = 32, + CO_FEATHERSTONE_LINK = 64 }; enum AnisotropicFrictionFlags { - CF_ANISOTROPIC_FRICTION_DISABLED=0, + CF_ANISOTROPIC_FRICTION_DISABLED = 0, CF_ANISOTROPIC_FRICTION = 1, CF_ANISOTROPIC_ROLLING_FRICTION = 2 }; @@ -166,76 +161,77 @@ public: SIMD_FORCE_INLINE bool mergesSimulationIslands() const { ///static objects, kinematic and object without contact response don't merge islands - return ((m_collisionFlags & (CF_STATIC_OBJECT | CF_KINEMATIC_OBJECT | CF_NO_CONTACT_RESPONSE) )==0); + return ((m_collisionFlags & (CF_STATIC_OBJECT | CF_KINEMATIC_OBJECT | CF_NO_CONTACT_RESPONSE)) == 0); } const btVector3& getAnisotropicFriction() const { return m_anisotropicFriction; } - void setAnisotropicFriction(const btVector3& anisotropicFriction, int frictionMode = CF_ANISOTROPIC_FRICTION) + void setAnisotropicFriction(const btVector3& anisotropicFriction, int frictionMode = CF_ANISOTROPIC_FRICTION) { m_anisotropicFriction = anisotropicFriction; - bool isUnity = (anisotropicFriction[0]!=1.f) || (anisotropicFriction[1]!=1.f) || (anisotropicFriction[2]!=1.f); - m_hasAnisotropicFriction = isUnity?frictionMode : 0; + bool isUnity = (anisotropicFriction[0] != 1.f) || (anisotropicFriction[1] != 1.f) || (anisotropicFriction[2] != 1.f); + m_hasAnisotropicFriction = isUnity ? frictionMode : 0; } - bool hasAnisotropicFriction(int frictionMode = CF_ANISOTROPIC_FRICTION) const + bool hasAnisotropicFriction(int frictionMode = CF_ANISOTROPIC_FRICTION) const { - return (m_hasAnisotropicFriction&frictionMode)!=0; + return (m_hasAnisotropicFriction & frictionMode) != 0; } ///the constraint solver can discard solving contacts, if the distance is above this threshold. 0 by default. ///Note that using contacts with positive distance can improve stability. It increases, however, the chance of colliding with degerate contacts, such as 'interior' triangle edges - void setContactProcessingThreshold( btScalar contactProcessingThreshold) + void setContactProcessingThreshold(btScalar contactProcessingThreshold) { m_contactProcessingThreshold = contactProcessingThreshold; } - btScalar getContactProcessingThreshold() const + btScalar getContactProcessingThreshold() const { return m_contactProcessingThreshold; } - SIMD_FORCE_INLINE bool isStaticObject() const { + SIMD_FORCE_INLINE bool isStaticObject() const + { return (m_collisionFlags & CF_STATIC_OBJECT) != 0; } - SIMD_FORCE_INLINE bool isKinematicObject() const + SIMD_FORCE_INLINE bool isKinematicObject() const { return (m_collisionFlags & CF_KINEMATIC_OBJECT) != 0; } - SIMD_FORCE_INLINE bool isStaticOrKinematicObject() const + SIMD_FORCE_INLINE bool isStaticOrKinematicObject() const { - return (m_collisionFlags & (CF_KINEMATIC_OBJECT | CF_STATIC_OBJECT)) != 0 ; + return (m_collisionFlags & (CF_KINEMATIC_OBJECT | CF_STATIC_OBJECT)) != 0; } - SIMD_FORCE_INLINE bool hasContactResponse() const { - return (m_collisionFlags & CF_NO_CONTACT_RESPONSE)==0; + SIMD_FORCE_INLINE bool hasContactResponse() const + { + return (m_collisionFlags & CF_NO_CONTACT_RESPONSE) == 0; } - btCollisionObject(); virtual ~btCollisionObject(); - virtual void setCollisionShape(btCollisionShape* collisionShape) + virtual void setCollisionShape(btCollisionShape * collisionShape) { m_updateRevision++; m_collisionShape = collisionShape; m_rootCollisionShape = collisionShape; } - SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const + SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const { return m_collisionShape; } - SIMD_FORCE_INLINE btCollisionShape* getCollisionShape() + SIMD_FORCE_INLINE btCollisionShape* getCollisionShape() { return m_collisionShape; } - void setIgnoreCollisionCheck(const btCollisionObject* co, bool ignoreCollisionCheck) + void setIgnoreCollisionCheck(const btCollisionObject* co, bool ignoreCollisionCheck) { if (ignoreCollisionCheck) { @@ -253,7 +249,7 @@ public: m_checkCollideWith = m_objectsWithoutCollisionCheck.size() > 0; } - virtual bool checkCollideWithOverride(const btCollisionObject* co) const + virtual bool checkCollideWithOverride(const btCollisionObject* co) const { int index = m_objectsWithoutCollisionCheck.findLinearSearch(co); if (index < m_objectsWithoutCollisionCheck.size()) @@ -263,317 +259,309 @@ public: return true; } - - - - ///Avoid using this internal API call, the extension pointer is used by some Bullet extensions. + ///Avoid using this internal API call, the extension pointer is used by some Bullet extensions. ///If you need to store your own user pointer, use 'setUserPointer/getUserPointer' instead. - void* internalGetExtensionPointer() const + void* internalGetExtensionPointer() const { return m_extensionPointer; } ///Avoid using this internal API call, the extension pointer is used by some Bullet extensions ///If you need to store your own user pointer, use 'setUserPointer/getUserPointer' instead. - void internalSetExtensionPointer(void* pointer) + void internalSetExtensionPointer(void* pointer) { m_extensionPointer = pointer; } - SIMD_FORCE_INLINE int getActivationState() const { return m_activationState1;} - + SIMD_FORCE_INLINE int getActivationState() const { return m_activationState1; } + void setActivationState(int newState) const; - void setDeactivationTime(btScalar time) + void setDeactivationTime(btScalar time) { m_deactivationTime = time; } - btScalar getDeactivationTime() const + btScalar getDeactivationTime() const { return m_deactivationTime; } void forceActivationState(int newState) const; - void activate(bool forceActivation = false) const; + void activate(bool forceActivation = false) const; SIMD_FORCE_INLINE bool isActive() const { return ((getActivationState() != ISLAND_SLEEPING) && (getActivationState() != DISABLE_SIMULATION)); } - void setRestitution(btScalar rest) + void setRestitution(btScalar rest) { m_updateRevision++; m_restitution = rest; } - btScalar getRestitution() const + btScalar getRestitution() const { return m_restitution; } - void setFriction(btScalar frict) + void setFriction(btScalar frict) { m_updateRevision++; m_friction = frict; } - btScalar getFriction() const + btScalar getFriction() const { return m_friction; } - void setRollingFriction(btScalar frict) + void setRollingFriction(btScalar frict) { m_updateRevision++; m_rollingFriction = frict; } - btScalar getRollingFriction() const + btScalar getRollingFriction() const { return m_rollingFriction; } - void setSpinningFriction(btScalar frict) - { - m_updateRevision++; - m_spinningFriction = frict; - } - btScalar getSpinningFriction() const - { - return m_spinningFriction; - } - void setContactStiffnessAndDamping(btScalar stiffness, btScalar damping) + void setSpinningFriction(btScalar frict) + { + m_updateRevision++; + m_spinningFriction = frict; + } + btScalar getSpinningFriction() const + { + return m_spinningFriction; + } + void setContactStiffnessAndDamping(btScalar stiffness, btScalar damping) { m_updateRevision++; m_contactStiffness = stiffness; m_contactDamping = damping; - - m_collisionFlags |=CF_HAS_CONTACT_STIFFNESS_DAMPING; - - //avoid divisions by zero... - if (m_contactStiffness< SIMD_EPSILON) - { - m_contactStiffness = SIMD_EPSILON; - } + + m_collisionFlags |= CF_HAS_CONTACT_STIFFNESS_DAMPING; + + //avoid divisions by zero... + if (m_contactStiffness < SIMD_EPSILON) + { + m_contactStiffness = SIMD_EPSILON; + } } - - btScalar getContactStiffness() const + + btScalar getContactStiffness() const { return m_contactStiffness; } - - btScalar getContactDamping() const + + btScalar getContactDamping() const { return m_contactDamping; } - + ///reserved for Bullet internal usage - int getInternalType() const + int getInternalType() const { return m_internalType; } - btTransform& getWorldTransform() + btTransform& getWorldTransform() { return m_worldTransform; } - const btTransform& getWorldTransform() const + const btTransform& getWorldTransform() const { return m_worldTransform; } - void setWorldTransform(const btTransform& worldTrans) + void setWorldTransform(const btTransform& worldTrans) { m_updateRevision++; m_worldTransform = worldTrans; } - - SIMD_FORCE_INLINE btBroadphaseProxy* getBroadphaseHandle() + SIMD_FORCE_INLINE btBroadphaseProxy* getBroadphaseHandle() { return m_broadphaseHandle; } - SIMD_FORCE_INLINE const btBroadphaseProxy* getBroadphaseHandle() const + SIMD_FORCE_INLINE const btBroadphaseProxy* getBroadphaseHandle() const { return m_broadphaseHandle; } - void setBroadphaseHandle(btBroadphaseProxy* handle) + void setBroadphaseHandle(btBroadphaseProxy * handle) { m_broadphaseHandle = handle; } - - const btTransform& getInterpolationWorldTransform() const + const btTransform& getInterpolationWorldTransform() const { return m_interpolationWorldTransform; } - btTransform& getInterpolationWorldTransform() + btTransform& getInterpolationWorldTransform() { return m_interpolationWorldTransform; } - void setInterpolationWorldTransform(const btTransform& trans) + void setInterpolationWorldTransform(const btTransform& trans) { m_updateRevision++; m_interpolationWorldTransform = trans; } - void setInterpolationLinearVelocity(const btVector3& linvel) + void setInterpolationLinearVelocity(const btVector3& linvel) { m_updateRevision++; m_interpolationLinearVelocity = linvel; } - void setInterpolationAngularVelocity(const btVector3& angvel) + void setInterpolationAngularVelocity(const btVector3& angvel) { m_updateRevision++; m_interpolationAngularVelocity = angvel; } - const btVector3& getInterpolationLinearVelocity() const + const btVector3& getInterpolationLinearVelocity() const { return m_interpolationLinearVelocity; } - const btVector3& getInterpolationAngularVelocity() const + const btVector3& getInterpolationAngularVelocity() const { return m_interpolationAngularVelocity; } SIMD_FORCE_INLINE int getIslandTag() const { - return m_islandTag1; + return m_islandTag1; } - void setIslandTag(int tag) + void setIslandTag(int tag) { m_islandTag1 = tag; } SIMD_FORCE_INLINE int getCompanionId() const { - return m_companionId; + return m_companionId; } - void setCompanionId(int id) + void setCompanionId(int id) { m_companionId = id; } - SIMD_FORCE_INLINE int getWorldArrayIndex() const - { - return m_worldArrayIndex; - } - - // only should be called by CollisionWorld - void setWorldArrayIndex(int ix) - { - m_worldArrayIndex = ix; - } - - SIMD_FORCE_INLINE btScalar getHitFraction() const + SIMD_FORCE_INLINE int getWorldArrayIndex() const { - return m_hitFraction; + return m_worldArrayIndex; } - void setHitFraction(btScalar hitFraction) + // only should be called by CollisionWorld + void setWorldArrayIndex(int ix) + { + m_worldArrayIndex = ix; + } + + SIMD_FORCE_INLINE btScalar getHitFraction() const + { + return m_hitFraction; + } + + void setHitFraction(btScalar hitFraction) { m_hitFraction = hitFraction; } - - SIMD_FORCE_INLINE int getCollisionFlags() const + SIMD_FORCE_INLINE int getCollisionFlags() const { return m_collisionFlags; } - void setCollisionFlags(int flags) + void setCollisionFlags(int flags) { m_collisionFlags = flags; } - + ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm:: - btScalar getCcdSweptSphereRadius() const + btScalar getCcdSweptSphereRadius() const { return m_ccdSweptSphereRadius; } ///Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm:: - void setCcdSweptSphereRadius(btScalar radius) + void setCcdSweptSphereRadius(btScalar radius) { m_ccdSweptSphereRadius = radius; } - btScalar getCcdMotionThreshold() const + btScalar getCcdMotionThreshold() const { return m_ccdMotionThreshold; } - btScalar getCcdSquareMotionThreshold() const + btScalar getCcdSquareMotionThreshold() const { - return m_ccdMotionThreshold*m_ccdMotionThreshold; + return m_ccdMotionThreshold * m_ccdMotionThreshold; } - - /// Don't do continuous collision detection if the motion (in one step) is less then m_ccdMotionThreshold - void setCcdMotionThreshold(btScalar ccdMotionThreshold) + void setCcdMotionThreshold(btScalar ccdMotionThreshold) { m_ccdMotionThreshold = ccdMotionThreshold; } ///users can point to their objects, userPointer is not used by Bullet - void* getUserPointer() const + void* getUserPointer() const { return m_userObjectPointer; } - int getUserIndex() const + int getUserIndex() const { return m_userIndex; } - - int getUserIndex2() const + + int getUserIndex2() const { return m_userIndex2; } - + ///users can point to their objects, userPointer is not used by Bullet - void setUserPointer(void* userPointer) + void setUserPointer(void* userPointer) { m_userObjectPointer = userPointer; } ///users can point to their objects, userPointer is not used by Bullet - void setUserIndex(int index) + void setUserIndex(int index) { m_userIndex = index; } - - void setUserIndex2(int index) + + void setUserIndex2(int index) { m_userIndex2 = index; } - int getUpdateRevisionInternal() const + int getUpdateRevisionInternal() const { return m_updateRevision; } - void setCustomDebugColor(const btVector3& colorRGB) + void setCustomDebugColor(const btVector3& colorRGB) { m_customDebugColorRGB = colorRGB; m_collisionFlags |= CF_HAS_CUSTOM_DEBUG_RENDERING_COLOR; } - void removeCustomDebugColor() + void removeCustomDebugColor() { m_collisionFlags &= ~CF_HAS_CUSTOM_DEBUG_RENDERING_COLOR; } - bool getCustomDebugColor(btVector3& colorRGB) const + bool getCustomDebugColor(btVector3 & colorRGB) const { - bool hasCustomColor = (0!=(m_collisionFlags&CF_HAS_CUSTOM_DEBUG_RENDERING_COLOR)); + bool hasCustomColor = (0 != (m_collisionFlags & CF_HAS_CUSTOM_DEBUG_RENDERING_COLOR)); if (hasCustomColor) { colorRGB = m_customDebugColorRGB; @@ -589,15 +577,16 @@ public: return true; } - virtual int calculateSerializeBufferSize() const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const; - - virtual void serializeSingleObject(class btSerializer* serializer) const; + virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const; + virtual void serializeSingleObject(class btSerializer * serializer) const; }; +// clang-format off + ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 struct btCollisionObjectDoubleData { @@ -667,14 +656,11 @@ struct btCollisionObjectFloatData int m_collisionFilterMask; int m_uniqueId; }; +// clang-format on - - -SIMD_FORCE_INLINE int btCollisionObject::calculateSerializeBufferSize() const +SIMD_FORCE_INLINE int btCollisionObject::calculateSerializeBufferSize() const { return sizeof(btCollisionObjectData); } - - -#endif //BT_COLLISION_OBJECT_H +#endif //BT_COLLISION_OBJECT_H diff --git a/src/BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h b/src/BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h index 952440b7d..1cc4a5ac5 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h +++ b/src/BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h @@ -1,25 +1,25 @@ #ifndef BT_COLLISION_OBJECT_WRAPPER_H #define BT_COLLISION_OBJECT_WRAPPER_H -///btCollisionObjectWrapperis an internal data structure. +///btCollisionObjectWrapperis an internal data structure. ///Most users can ignore this and use btCollisionObject and btCollisionShape instead class btCollisionShape; class btCollisionObject; class btTransform; -#include "LinearMath/btScalar.h" // for SIMD_FORCE_INLINE definition +#include "LinearMath/btScalar.h" // for SIMD_FORCE_INLINE definition #define BT_DECLARE_STACK_ONLY_OBJECT \ - private: \ - void* operator new(size_t size); \ - void operator delete(void*); +private: \ + void* operator new(size_t size); \ + void operator delete(void*); struct btCollisionObjectWrapper; struct btCollisionObjectWrapper { -BT_DECLARE_STACK_ONLY_OBJECT + BT_DECLARE_STACK_ONLY_OBJECT private: - btCollisionObjectWrapper(const btCollisionObjectWrapper&); // not implemented. Not allowed. + btCollisionObjectWrapper(const btCollisionObjectWrapper&); // not implemented. Not allowed. btCollisionObjectWrapper* operator=(const btCollisionObjectWrapper&); public: @@ -27,17 +27,17 @@ public: const btCollisionShape* m_shape; const btCollisionObject* m_collisionObject; const btTransform& m_worldTransform; - int m_partId; - int m_index; + int m_partId; + int m_index; btCollisionObjectWrapper(const btCollisionObjectWrapper* parent, const btCollisionShape* shape, const btCollisionObject* collisionObject, const btTransform& worldTransform, int partId, int index) - : m_parent(parent), m_shape(shape), m_collisionObject(collisionObject), m_worldTransform(worldTransform), - m_partId(partId), m_index(index) - {} + : m_parent(parent), m_shape(shape), m_collisionObject(collisionObject), m_worldTransform(worldTransform), m_partId(partId), m_index(index) + { + } SIMD_FORCE_INLINE const btTransform& getWorldTransform() const { return m_worldTransform; } SIMD_FORCE_INLINE const btCollisionObject* getCollisionObject() const { return m_collisionObject; } SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const { return m_shape; } }; -#endif //BT_COLLISION_OBJECT_WRAPPER_H +#endif //BT_COLLISION_OBJECT_WRAPPER_H diff --git a/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp b/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp index a16b29539..782e9efaf 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp +++ b/src/BulletCollision/CollisionDispatch/btCollisionWorld.cpp @@ -19,9 +19,9 @@ subject to the following restrictions: #include "BulletCollision/CollisionShapes/btCollisionShape.h" #include "BulletCollision/CollisionShapes/btConvexShape.h" #include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" -#include "BulletCollision/CollisionShapes/btSphereShape.h" //for raycasting -#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" //for raycasting -#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h" //for raycasting +#include "BulletCollision/CollisionShapes/btSphereShape.h" //for raycasting +#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" //for raycasting +#include "BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h" //for raycasting #include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h" #include "BulletCollision/CollisionShapes/btCompoundShape.h" #include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" @@ -38,7 +38,6 @@ subject to the following restrictions: //#define DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION - //#define USE_BRUTEFORCE_RAYBROADPHASE 1 //RECALCULATE_AABB is slower, but benefit is that you don't need to call 'stepSimulation' or 'updateAabbs' before using a rayTest //#define RECALCULATE_AABB_RAYCAST 1 @@ -48,7 +47,6 @@ subject to the following restrictions: #include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h" #include "BulletCollision/CollisionDispatch/btCollisionConfiguration.h" - ///for debug drawing //for debug rendering @@ -65,25 +63,21 @@ subject to the following restrictions: #include "BulletCollision/CollisionShapes/btTriangleMeshShape.h" #include "BulletCollision/CollisionShapes/btStaticPlaneShape.h" - - -btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache, btCollisionConfiguration* collisionConfiguration) -:m_dispatcher1(dispatcher), -m_broadphasePairCache(pairCache), -m_debugDrawer(0), -m_forceUpdateAllAabbs(true) +btCollisionWorld::btCollisionWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btCollisionConfiguration* collisionConfiguration) + : m_dispatcher1(dispatcher), + m_broadphasePairCache(pairCache), + m_debugDrawer(0), + m_forceUpdateAllAabbs(true) { } - btCollisionWorld::~btCollisionWorld() { - //clean up remaining objects int i; - for (i=0;igetBroadphaseHandle(); if (bp) @@ -91,101 +85,83 @@ btCollisionWorld::~btCollisionWorld() // // only clear the cached algorithms // - getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1); - getBroadphase()->destroyProxy(bp,m_dispatcher1); + getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp, m_dispatcher1); + getBroadphase()->destroyProxy(bp, m_dispatcher1); collisionObject->setBroadphaseHandle(0); } } - - } - - - - - - - -void btCollisionWorld::refreshBroadphaseProxy(btCollisionObject* collisionObject) +void btCollisionWorld::refreshBroadphaseProxy(btCollisionObject* collisionObject) { if (collisionObject->getBroadphaseHandle()) { int collisionFilterGroup = collisionObject->getBroadphaseHandle()->m_collisionFilterGroup; int collisionFilterMask = collisionObject->getBroadphaseHandle()->m_collisionFilterMask; - - - getBroadphase()->destroyProxy(collisionObject->getBroadphaseHandle(),getDispatcher()); - - //calculate new AABB + + getBroadphase()->destroyProxy(collisionObject->getBroadphaseHandle(), getDispatcher()); + + //calculate new AABB btTransform trans = collisionObject->getWorldTransform(); - btVector3 minAabb; - btVector3 maxAabb; - collisionObject->getCollisionShape()->getAabb(trans,minAabb,maxAabb); + btVector3 minAabb; + btVector3 maxAabb; + collisionObject->getCollisionShape()->getAabb(trans, minAabb, maxAabb); int type = collisionObject->getCollisionShape()->getShapeType(); - collisionObject->setBroadphaseHandle( getBroadphase()->createProxy( + collisionObject->setBroadphaseHandle(getBroadphase()->createProxy( minAabb, maxAabb, type, collisionObject, collisionFilterGroup, collisionFilterMask, - m_dispatcher1)) ; + m_dispatcher1)); } } -void btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask) +void btCollisionWorld::addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask) { - btAssert(collisionObject); //check that the object isn't already added - btAssert( m_collisionObjects.findLinearSearch(collisionObject) == m_collisionObjects.size()); - btAssert(collisionObject->getWorldArrayIndex() == -1); // do not add the same object to more than one collision world + btAssert(m_collisionObjects.findLinearSearch(collisionObject) == m_collisionObjects.size()); + btAssert(collisionObject->getWorldArrayIndex() == -1); // do not add the same object to more than one collision world - collisionObject->setWorldArrayIndex(m_collisionObjects.size()); + collisionObject->setWorldArrayIndex(m_collisionObjects.size()); m_collisionObjects.push_back(collisionObject); //calculate new AABB btTransform trans = collisionObject->getWorldTransform(); - btVector3 minAabb; - btVector3 maxAabb; - collisionObject->getCollisionShape()->getAabb(trans,minAabb,maxAabb); + btVector3 minAabb; + btVector3 maxAabb; + collisionObject->getCollisionShape()->getAabb(trans, minAabb, maxAabb); int type = collisionObject->getCollisionShape()->getShapeType(); - collisionObject->setBroadphaseHandle( getBroadphase()->createProxy( + collisionObject->setBroadphaseHandle(getBroadphase()->createProxy( minAabb, maxAabb, type, collisionObject, collisionFilterGroup, collisionFilterMask, - m_dispatcher1)) ; - - - - - + m_dispatcher1)); } - - -void btCollisionWorld::updateSingleAabb(btCollisionObject* colObj) +void btCollisionWorld::updateSingleAabb(btCollisionObject* colObj) { - btVector3 minAabb,maxAabb; - colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb); + btVector3 minAabb, maxAabb; + colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb, maxAabb); //need to increase the aabb for contact thresholds - btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold); + btVector3 contactThreshold(gContactBreakingThreshold, gContactBreakingThreshold, gContactBreakingThreshold); minAabb -= contactThreshold; maxAabb += contactThreshold; - if(getDispatchInfo().m_useContinuous && colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY && !colObj->isStaticOrKinematicObject()) + if (getDispatchInfo().m_useContinuous && colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY && !colObj->isStaticOrKinematicObject()) { - btVector3 minAabb2,maxAabb2; - colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2); + btVector3 minAabb2, maxAabb2; + colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(), minAabb2, maxAabb2); minAabb2 -= contactThreshold; maxAabb2 += contactThreshold; minAabb.setMin(minAabb2); @@ -195,10 +171,11 @@ void btCollisionWorld::updateSingleAabb(btCollisionObject* colObj) btBroadphaseInterface* bp = (btBroadphaseInterface*)m_broadphasePairCache; //moving objects should be moderately sized, probably something wrong if not - if ( colObj->isStaticObject() || ((maxAabb-minAabb).length2() < btScalar(1e12))) + if (colObj->isStaticObject() || ((maxAabb - minAabb).length2() < btScalar(1e12))) { - bp->setAabb(colObj->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1); - } else + bp->setAabb(colObj->getBroadphaseHandle(), minAabb, maxAabb, m_dispatcher1); + } + else { //something went wrong, investigate //this assert is unwanted in 3D modelers (danger of loosing work) @@ -216,15 +193,15 @@ void btCollisionWorld::updateSingleAabb(btCollisionObject* colObj) } } -void btCollisionWorld::updateAabbs() +void btCollisionWorld::updateAabbs() { BT_PROFILE("updateAabbs"); btTransform predictedTrans; - for ( int i=0;igetWorldArrayIndex() == i); + btAssert(colObj->getWorldArrayIndex() == i); //only update aabb of active objects if (m_forceUpdateAllAabbs || colObj->isActive()) @@ -234,14 +211,13 @@ void btCollisionWorld::updateAabbs() } } - -void btCollisionWorld::computeOverlappingPairs() +void btCollisionWorld::computeOverlappingPairs() { BT_PROFILE("calculateOverlappingPairs"); m_broadphasePairCache->calculateOverlappingPairs(m_dispatcher1); } -void btCollisionWorld::performDiscreteCollisionDetection() +void btCollisionWorld::performDiscreteCollisionDetection() { BT_PROFILE("performDiscreteCollisionDetection"); @@ -255,69 +231,61 @@ void btCollisionWorld::performDiscreteCollisionDetection() { BT_PROFILE("dispatchAllCollisionPairs"); if (dispatcher) - dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(),dispatchInfo,m_dispatcher1); + dispatcher->dispatchAllCollisionPairs(m_broadphasePairCache->getOverlappingPairCache(), dispatchInfo, m_dispatcher1); } - } - - -void btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject) +void btCollisionWorld::removeCollisionObject(btCollisionObject* collisionObject) { - - //bool removeFromBroadphase = false; { - btBroadphaseProxy* bp = collisionObject->getBroadphaseHandle(); if (bp) { // // only clear the cached algorithms // - getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp,m_dispatcher1); - getBroadphase()->destroyProxy(bp,m_dispatcher1); + getBroadphase()->getOverlappingPairCache()->cleanProxyFromPairs(bp, m_dispatcher1); + getBroadphase()->destroyProxy(bp, m_dispatcher1); collisionObject->setBroadphaseHandle(0); } } - - int iObj = collisionObject->getWorldArrayIndex(); -// btAssert(iObj >= 0 && iObj < m_collisionObjects.size()); // trying to remove an object that was never added or already removed previously? - if (iObj >= 0 && iObj < m_collisionObjects.size()) - { - btAssert(collisionObject == m_collisionObjects[iObj]); - m_collisionObjects.swap(iObj, m_collisionObjects.size()-1); - m_collisionObjects.pop_back(); - if (iObj < m_collisionObjects.size()) - { - m_collisionObjects[iObj]->setWorldArrayIndex(iObj); - } - } - else - { - // slow linear search - //swapremove - m_collisionObjects.remove(collisionObject); - } - collisionObject->setWorldArrayIndex(-1); + int iObj = collisionObject->getWorldArrayIndex(); + // btAssert(iObj >= 0 && iObj < m_collisionObjects.size()); // trying to remove an object that was never added or already removed previously? + if (iObj >= 0 && iObj < m_collisionObjects.size()) + { + btAssert(collisionObject == m_collisionObjects[iObj]); + m_collisionObjects.swap(iObj, m_collisionObjects.size() - 1); + m_collisionObjects.pop_back(); + if (iObj < m_collisionObjects.size()) + { + m_collisionObjects[iObj]->setWorldArrayIndex(iObj); + } + } + else + { + // slow linear search + //swapremove + m_collisionObjects.remove(collisionObject); + } + collisionObject->setWorldArrayIndex(-1); } - -void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans, - btCollisionObject* collisionObject, - const btCollisionShape* collisionShape, - const btTransform& colObjWorldTransform, - RayResultCallback& resultCallback) +void btCollisionWorld::rayTestSingle(const btTransform& rayFromTrans, const btTransform& rayToTrans, + btCollisionObject* collisionObject, + const btCollisionShape* collisionShape, + const btTransform& colObjWorldTransform, + RayResultCallback& resultCallback) { - btCollisionObjectWrapper colObWrap(0,collisionShape,collisionObject,colObjWorldTransform,-1,-1); - btCollisionWorld::rayTestSingleInternal(rayFromTrans,rayToTrans,&colObWrap,resultCallback); + btCollisionObjectWrapper colObWrap(0, collisionShape, collisionObject, colObjWorldTransform, -1, -1); + btCollisionWorld::rayTestSingleInternal(rayFromTrans, rayToTrans, &colObWrap, resultCallback); } -void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,const btTransform& rayToTrans, - const btCollisionObjectWrapper* collisionObjectWrap, - RayResultCallback& resultCallback) +void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans, const btTransform& rayToTrans, + const btCollisionObjectWrapper* collisionObjectWrap, + RayResultCallback& resultCallback) { btSphereShape pointShape(btScalar(0.0)); pointShape.setMargin(0.f); @@ -331,12 +299,12 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con btConvexCast::CastResult castResult; castResult.m_fraction = resultCallback.m_closestHitFraction; - btConvexShape* convexShape = (btConvexShape*) collisionShape; - btVoronoiSimplexSolver simplexSolver; - btSubsimplexConvexCast subSimplexConvexCaster(castShape,convexShape,&simplexSolver); - - btGjkConvexCast gjkConvexCaster(castShape,convexShape,&simplexSolver); - + btConvexShape* convexShape = (btConvexShape*)collisionShape; + btVoronoiSimplexSolver simplexSolver; + btSubsimplexConvexCast subSimplexConvexCaster(castShape, convexShape, &simplexSolver); + + btGjkConvexCast gjkConvexCaster(castShape, convexShape, &simplexSolver); + //btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0); btConvexCast* convexCasterPtr = 0; @@ -345,10 +313,10 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con convexCasterPtr = &gjkConvexCaster; else convexCasterPtr = &subSimplexConvexCaster; - + btConvexCast& convexCaster = *convexCasterPtr; - if (convexCaster.calcTimeOfImpact(rayFromTrans,rayToTrans,colObjWorldTransform,colObjWorldTransform,castResult)) + if (convexCaster.calcTimeOfImpact(rayFromTrans, rayToTrans, colObjWorldTransform, colObjWorldTransform, castResult)) { //add hit if (castResult.m_normal.length2() > btScalar(0.0001)) @@ -359,81 +327,75 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con #ifdef USE_SUBSIMPLEX_CONVEX_CAST //rotate normal into worldspace castResult.m_normal = rayFromTrans.getBasis() * castResult.m_normal; -#endif //USE_SUBSIMPLEX_CONVEX_CAST +#endif //USE_SUBSIMPLEX_CONVEX_CAST castResult.m_normal.normalize(); - btCollisionWorld::LocalRayResult localRayResult - ( + btCollisionWorld::LocalRayResult localRayResult( collisionObjectWrap->getCollisionObject(), 0, castResult.m_normal, - castResult.m_fraction - ); + castResult.m_fraction); bool normalInWorldSpace = true; resultCallback.addSingleResult(localRayResult, normalInWorldSpace); - } } } - } else { + } + else + { if (collisionShape->isConcave()) { - //ConvexCast::CastResult - struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback + struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback + { + btCollisionWorld::RayResultCallback* m_resultCallback; + const btCollisionObject* m_collisionObject; + const btConcaveShape* m_triangleMesh; + + btTransform m_colObjWorldTransform; + + BridgeTriangleRaycastCallback(const btVector3& from, const btVector3& to, + btCollisionWorld::RayResultCallback* resultCallback, const btCollisionObject* collisionObject, const btConcaveShape* triangleMesh, const btTransform& colObjWorldTransform) : //@BP Mod + btTriangleRaycastCallback(from, to, resultCallback->m_flags), + m_resultCallback(resultCallback), + m_collisionObject(collisionObject), + m_triangleMesh(triangleMesh), + m_colObjWorldTransform(colObjWorldTransform) { - btCollisionWorld::RayResultCallback* m_resultCallback; - const btCollisionObject* m_collisionObject; - const btConcaveShape* m_triangleMesh; + } - btTransform m_colObjWorldTransform; + virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex) + { + btCollisionWorld::LocalShapeInfo shapeInfo; + shapeInfo.m_shapePart = partId; + shapeInfo.m_triangleIndex = triangleIndex; - BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to, - btCollisionWorld::RayResultCallback* resultCallback, const btCollisionObject* collisionObject,const btConcaveShape* triangleMesh,const btTransform& colObjWorldTransform): - //@BP Mod - btTriangleRaycastCallback(from,to, resultCallback->m_flags), - m_resultCallback(resultCallback), - m_collisionObject(collisionObject), - m_triangleMesh(triangleMesh), - m_colObjWorldTransform(colObjWorldTransform) - { - } + btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal; + btCollisionWorld::LocalRayResult rayResult(m_collisionObject, + &shapeInfo, + hitNormalWorld, + hitFraction); - virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex ) - { - btCollisionWorld::LocalShapeInfo shapeInfo; - shapeInfo.m_shapePart = partId; - shapeInfo.m_triangleIndex = triangleIndex; - - btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal; - - btCollisionWorld::LocalRayResult rayResult - (m_collisionObject, - &shapeInfo, - hitNormalWorld, - hitFraction); - - bool normalInWorldSpace = true; - return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace); - } - - }; + bool normalInWorldSpace = true; + return m_resultCallback->addSingleResult(rayResult, normalInWorldSpace); + } + }; btTransform worldTocollisionObject = colObjWorldTransform.inverse(); btVector3 rayFromLocal = worldTocollisionObject * rayFromTrans.getOrigin(); btVector3 rayToLocal = worldTocollisionObject * rayToTrans.getOrigin(); // BT_PROFILE("rayTestConcave"); - if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE) + if (collisionShape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) { ///optimized version for btBvhTriangleMeshShape btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape; - - BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),triangleMesh,colObjWorldTransform); + + BridgeTriangleRaycastCallback rcb(rayFromLocal, rayToLocal, &resultCallback, collisionObjectWrap->getCollisionObject(), triangleMesh, colObjWorldTransform); rcb.m_hitFraction = resultCallback.m_closestHitFraction; - triangleMesh->performRaycast(&rcb,rayFromLocal,rayToLocal); + triangleMesh->performRaycast(&rcb, rayFromLocal, rayToLocal); } else if (collisionShape->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) { @@ -445,7 +407,7 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con btVector3 scale = scaledTriangleMesh->getLocalScaling(); btVector3 rayFromLocalScaled = rayFromLocal / scale; btVector3 rayToLocalScaled = rayToLocal / scale; - + //perform raycast in the underlying btBvhTriangleMeshShape BridgeTriangleRaycastCallback rcb(rayFromLocalScaled, rayToLocalScaled, &resultCallback, collisionObjectWrap->getCollisionObject(), triangleMesh, colObjWorldTransform); rcb.m_hitFraction = resultCallback.m_closestHitFraction; @@ -466,45 +428,40 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con struct BridgeTriangleRaycastCallback : public btTriangleRaycastCallback { btCollisionWorld::RayResultCallback* m_resultCallback; - const btCollisionObject* m_collisionObject; - btConcaveShape* m_triangleMesh; + const btCollisionObject* m_collisionObject; + btConcaveShape* m_triangleMesh; btTransform m_colObjWorldTransform; - BridgeTriangleRaycastCallback( const btVector3& from,const btVector3& to, - btCollisionWorld::RayResultCallback* resultCallback, const btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& colObjWorldTransform): - //@BP Mod - btTriangleRaycastCallback(from,to, resultCallback->m_flags), - m_resultCallback(resultCallback), - m_collisionObject(collisionObject), - m_triangleMesh(triangleMesh), - m_colObjWorldTransform(colObjWorldTransform) + BridgeTriangleRaycastCallback(const btVector3& from, const btVector3& to, + btCollisionWorld::RayResultCallback* resultCallback, const btCollisionObject* collisionObject, btConcaveShape* triangleMesh, const btTransform& colObjWorldTransform) : //@BP Mod + btTriangleRaycastCallback(from, to, resultCallback->m_flags), + m_resultCallback(resultCallback), + m_collisionObject(collisionObject), + m_triangleMesh(triangleMesh), + m_colObjWorldTransform(colObjWorldTransform) { } - - virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex ) + virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex) { - btCollisionWorld::LocalShapeInfo shapeInfo; + btCollisionWorld::LocalShapeInfo shapeInfo; shapeInfo.m_shapePart = partId; shapeInfo.m_triangleIndex = triangleIndex; btVector3 hitNormalWorld = m_colObjWorldTransform.getBasis() * hitNormalLocal; - btCollisionWorld::LocalRayResult rayResult - (m_collisionObject, - &shapeInfo, - hitNormalWorld, - hitFraction); + btCollisionWorld::LocalRayResult rayResult(m_collisionObject, + &shapeInfo, + hitNormalWorld, + hitFraction); - bool normalInWorldSpace = true; - return m_resultCallback->addSingleResult(rayResult,normalInWorldSpace); + bool normalInWorldSpace = true; + return m_resultCallback->addSingleResult(rayResult, normalInWorldSpace); } - }; - - BridgeTriangleRaycastCallback rcb(rayFromLocal,rayToLocal,&resultCallback,collisionObjectWrap->getCollisionObject(),concaveShape, colObjWorldTransform); + BridgeTriangleRaycastCallback rcb(rayFromLocal, rayToLocal, &resultCallback, collisionObjectWrap->getCollisionObject(), concaveShape, colObjWorldTransform); rcb.m_hitFraction = resultCallback.m_closestHitFraction; btVector3 rayAabbMinLocal = rayFromLocal; @@ -512,9 +469,11 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con btVector3 rayAabbMaxLocal = rayFromLocal; rayAabbMaxLocal.setMax(rayToLocal); - concaveShape->processAllTriangles(&rcb,rayAabbMinLocal,rayAabbMaxLocal); + concaveShape->processAllTriangles(&rcb, rayAabbMinLocal, rayAabbMaxLocal); } - } else { + } + else + { // BT_PROFILE("rayTestCompound"); if (collisionShape->isCompound()) { @@ -522,10 +481,10 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con { RayResultCallback* m_userCallback; int m_i; - - LocalInfoAdder2 (int i, RayResultCallback *user) + + LocalInfoAdder2(int i, RayResultCallback* user) : m_userCallback(user), m_i(i) - { + { m_closestHitFraction = m_userCallback->m_closestHitFraction; m_flags = m_userCallback->m_flags; } @@ -534,7 +493,7 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con return m_userCallback->needsCollision(p); } - virtual btScalar addSingleResult (btCollisionWorld::LocalRayResult &r, bool b) + virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& r, bool b) { btCollisionWorld::LocalShapeInfo shapeInfo; shapeInfo.m_shapePart = -1; @@ -547,7 +506,7 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con return result; } }; - + struct RayTester : btDbvt::ICollide { const btCollisionObject* m_collisionObject; @@ -556,33 +515,29 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con const btTransform& m_rayFromTrans; const btTransform& m_rayToTrans; RayResultCallback& m_resultCallback; - + RayTester(const btCollisionObject* collisionObject, - const btCompoundShape* compoundShape, - const btTransform& colObjWorldTransform, - const btTransform& rayFromTrans, - const btTransform& rayToTrans, - RayResultCallback& resultCallback): - m_collisionObject(collisionObject), - m_compoundShape(compoundShape), - m_colObjWorldTransform(colObjWorldTransform), - m_rayFromTrans(rayFromTrans), - m_rayToTrans(rayToTrans), - m_resultCallback(resultCallback) + const btCompoundShape* compoundShape, + const btTransform& colObjWorldTransform, + const btTransform& rayFromTrans, + const btTransform& rayToTrans, + RayResultCallback& resultCallback) : m_collisionObject(collisionObject), + m_compoundShape(compoundShape), + m_colObjWorldTransform(colObjWorldTransform), + m_rayFromTrans(rayFromTrans), + m_rayToTrans(rayToTrans), + m_resultCallback(resultCallback) { - } - + void ProcessLeaf(int i) { const btCollisionShape* childCollisionShape = m_compoundShape->getChildShape(i); const btTransform& childTrans = m_compoundShape->getChildTransform(i); btTransform childWorldTrans = m_colObjWorldTransform * childTrans; - - btCollisionObjectWrapper tmpOb(0,childCollisionShape,m_collisionObject,childWorldTrans,-1,i); - // replace collision shape so that callback can determine the triangle - + btCollisionObjectWrapper tmpOb(0, childCollisionShape, m_collisionObject, childWorldTrans, -1, i); + // replace collision shape so that callback can determine the triangle LocalInfoAdder2 my_cb(i, &m_resultCallback); @@ -591,19 +546,17 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con m_rayToTrans, &tmpOb, my_cb); - } - + void Process(const btDbvtNode* leaf) { ProcessLeaf(leaf->dataAsInt); } }; - + const btCompoundShape* compoundShape = static_cast(collisionShape); const btDbvt* dbvt = compoundShape->getDynamicAabbTree(); - RayTester rayCB( collisionObjectWrap->getCollisionObject(), compoundShape, @@ -611,39 +564,39 @@ void btCollisionWorld::rayTestSingleInternal(const btTransform& rayFromTrans,con rayFromTrans, rayToTrans, resultCallback); -#ifndef DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION +#ifndef DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION if (dbvt) { btVector3 localRayFrom = colObjWorldTransform.inverseTimes(rayFromTrans).getOrigin(); btVector3 localRayTo = colObjWorldTransform.inverseTimes(rayToTrans).getOrigin(); - btDbvt::rayTest(dbvt->m_root, localRayFrom , localRayTo, rayCB); + btDbvt::rayTest(dbvt->m_root, localRayFrom, localRayTo, rayCB); } else -#endif //DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION +#endif //DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION { for (int i = 0, n = compoundShape->getNumChildShapes(); i < n; ++i) { rayCB.ProcessLeaf(i); - } + } } } } } } -void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans, - btCollisionObject* collisionObject, - const btCollisionShape* collisionShape, - const btTransform& colObjWorldTransform, - ConvexResultCallback& resultCallback, btScalar allowedPenetration) +void btCollisionWorld::objectQuerySingle(const btConvexShape* castShape, const btTransform& convexFromTrans, const btTransform& convexToTrans, + btCollisionObject* collisionObject, + const btCollisionShape* collisionShape, + const btTransform& colObjWorldTransform, + ConvexResultCallback& resultCallback, btScalar allowedPenetration) { - btCollisionObjectWrapper tmpOb(0,collisionShape,collisionObject,colObjWorldTransform,-1,-1); - btCollisionWorld::objectQuerySingleInternal(castShape,convexFromTrans,convexToTrans,&tmpOb,resultCallback,allowedPenetration); + btCollisionObjectWrapper tmpOb(0, collisionShape, collisionObject, colObjWorldTransform, -1, -1); + btCollisionWorld::objectQuerySingleInternal(castShape, convexFromTrans, convexToTrans, &tmpOb, resultCallback, allowedPenetration); } -void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans, - const btCollisionObjectWrapper* colObjWrap, - ConvexResultCallback& resultCallback, btScalar allowedPenetration) +void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape, const btTransform& convexFromTrans, const btTransform& convexToTrans, + const btCollisionObjectWrapper* colObjWrap, + ConvexResultCallback& resultCallback, btScalar allowedPenetration) { const btCollisionShape* collisionShape = colObjWrap->getCollisionShape(); const btTransform& colObjWorldTransform = colObjWrap->getWorldTransform(); @@ -653,21 +606,19 @@ void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape, //BT_PROFILE("convexSweepConvex"); btConvexCast::CastResult castResult; castResult.m_allowedPenetration = allowedPenetration; - castResult.m_fraction = resultCallback.m_closestHitFraction;//btScalar(1.);//?? + castResult.m_fraction = resultCallback.m_closestHitFraction; //btScalar(1.);//?? - btConvexShape* convexShape = (btConvexShape*) collisionShape; - btVoronoiSimplexSolver simplexSolver; - btGjkEpaPenetrationDepthSolver gjkEpaPenetrationSolver; + btConvexShape* convexShape = (btConvexShape*)collisionShape; + btVoronoiSimplexSolver simplexSolver; + btGjkEpaPenetrationDepthSolver gjkEpaPenetrationSolver; - btContinuousConvexCollision convexCaster1(castShape,convexShape,&simplexSolver,&gjkEpaPenetrationSolver); + btContinuousConvexCollision convexCaster1(castShape, convexShape, &simplexSolver, &gjkEpaPenetrationSolver); //btGjkConvexCast convexCaster2(castShape,convexShape,&simplexSolver); //btSubsimplexConvexCast convexCaster3(castShape,convexShape,&simplexSolver); btConvexCast* castPtr = &convexCaster1; - - - if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult)) + if (castPtr->calcTimeOfImpact(convexFromTrans, convexToTrans, colObjWorldTransform, colObjWorldTransform, castResult)) { //add hit if (castResult.m_normal.length2() > btScalar(0.0001)) @@ -675,25 +626,24 @@ void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape, if (castResult.m_fraction < resultCallback.m_closestHitFraction) { castResult.m_normal.normalize(); - btCollisionWorld::LocalConvexResult localConvexResult - ( + btCollisionWorld::LocalConvexResult localConvexResult( colObjWrap->getCollisionObject(), 0, castResult.m_normal, castResult.m_hitPoint, - castResult.m_fraction - ); + castResult.m_fraction); bool normalInWorldSpace = true; resultCallback.addSingleResult(localConvexResult, normalInWorldSpace); - } } } - } else { + } + else + { if (collisionShape->isConcave()) { - if (collisionShape->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE) + if (collisionShape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) { //BT_PROFILE("convexSweepbtBvhTriangleMesh"); btBvhTriangleMeshShape* triangleMesh = (btBvhTriangleMeshShape*)collisionShape; @@ -707,62 +657,57 @@ void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape, struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback { btCollisionWorld::ConvexResultCallback* m_resultCallback; - const btCollisionObject* m_collisionObject; - btTriangleMeshShape* m_triangleMesh; + const btCollisionObject* m_collisionObject; + btTriangleMeshShape* m_triangleMesh; - BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to, - btCollisionWorld::ConvexResultCallback* resultCallback, const btCollisionObject* collisionObject,btTriangleMeshShape* triangleMesh, const btTransform& triangleToWorld): - btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()), - m_resultCallback(resultCallback), - m_collisionObject(collisionObject), - m_triangleMesh(triangleMesh) + BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from, const btTransform& to, + btCollisionWorld::ConvexResultCallback* resultCallback, const btCollisionObject* collisionObject, btTriangleMeshShape* triangleMesh, const btTransform& triangleToWorld) : btTriangleConvexcastCallback(castShape, from, to, triangleToWorld, triangleMesh->getMargin()), + m_resultCallback(resultCallback), + m_collisionObject(collisionObject), + m_triangleMesh(triangleMesh) { } - - virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex ) + virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex) { - btCollisionWorld::LocalShapeInfo shapeInfo; + btCollisionWorld::LocalShapeInfo shapeInfo; shapeInfo.m_shapePart = partId; shapeInfo.m_triangleIndex = triangleIndex; if (hitFraction <= m_resultCallback->m_closestHitFraction) { + btCollisionWorld::LocalConvexResult convexResult(m_collisionObject, + &shapeInfo, + hitNormalLocal, + hitPointLocal, + hitFraction); - btCollisionWorld::LocalConvexResult convexResult - (m_collisionObject, - &shapeInfo, - hitNormalLocal, - hitPointLocal, - hitFraction); + bool normalInWorldSpace = true; - bool normalInWorldSpace = true; - - - return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace); + return m_resultCallback->addSingleResult(convexResult, normalInWorldSpace); } return hitFraction; } - }; - BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,colObjWrap->getCollisionObject(),triangleMesh, colObjWorldTransform); + BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans, convexToTrans, &resultCallback, colObjWrap->getCollisionObject(), triangleMesh, colObjWorldTransform); tccb.m_hitFraction = resultCallback.m_closestHitFraction; tccb.m_allowedPenetration = allowedPenetration; btVector3 boxMinLocal, boxMaxLocal; castShape->getAabb(rotationXform, boxMinLocal, boxMaxLocal); - triangleMesh->performConvexcast(&tccb,convexFromLocal,convexToLocal,boxMinLocal, boxMaxLocal); - } else + triangleMesh->performConvexcast(&tccb, convexFromLocal, convexToLocal, boxMinLocal, boxMaxLocal); + } + else { - if (collisionShape->getShapeType()==STATIC_PLANE_PROXYTYPE) + if (collisionShape->getShapeType() == STATIC_PLANE_PROXYTYPE) { btConvexCast::CastResult castResult; castResult.m_allowedPenetration = allowedPenetration; castResult.m_fraction = resultCallback.m_closestHitFraction; - btStaticPlaneShape* planeShape = (btStaticPlaneShape*) collisionShape; - btContinuousConvexCollision convexCaster1(castShape,planeShape); + btStaticPlaneShape* planeShape = (btStaticPlaneShape*)collisionShape; + btContinuousConvexCollision convexCaster1(castShape, planeShape); btConvexCast* castPtr = &convexCaster1; - if (castPtr->calcTimeOfImpact(convexFromTrans,convexToTrans,colObjWorldTransform,colObjWorldTransform,castResult)) + if (castPtr->calcTimeOfImpact(convexFromTrans, convexToTrans, colObjWorldTransform, colObjWorldTransform, castResult)) { //add hit if (castResult.m_normal.length2() > btScalar(0.0001)) @@ -770,22 +715,20 @@ void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape, if (castResult.m_fraction < resultCallback.m_closestHitFraction) { castResult.m_normal.normalize(); - btCollisionWorld::LocalConvexResult localConvexResult - ( + btCollisionWorld::LocalConvexResult localConvexResult( colObjWrap->getCollisionObject(), 0, castResult.m_normal, castResult.m_hitPoint, - castResult.m_fraction - ); + castResult.m_fraction); bool normalInWorldSpace = true; resultCallback.addSingleResult(localConvexResult, normalInWorldSpace); } } } - - } else + } + else { //BT_PROFILE("convexSweepConcave"); btConcaveShape* concaveShape = (btConcaveShape*)collisionShape; @@ -799,44 +742,39 @@ void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape, struct BridgeTriangleConvexcastCallback : public btTriangleConvexcastCallback { btCollisionWorld::ConvexResultCallback* m_resultCallback; - const btCollisionObject* m_collisionObject; - btConcaveShape* m_triangleMesh; + const btCollisionObject* m_collisionObject; + btConcaveShape* m_triangleMesh; - BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from,const btTransform& to, - btCollisionWorld::ConvexResultCallback* resultCallback, const btCollisionObject* collisionObject,btConcaveShape* triangleMesh, const btTransform& triangleToWorld): - btTriangleConvexcastCallback(castShape, from,to, triangleToWorld, triangleMesh->getMargin()), - m_resultCallback(resultCallback), - m_collisionObject(collisionObject), - m_triangleMesh(triangleMesh) + BridgeTriangleConvexcastCallback(const btConvexShape* castShape, const btTransform& from, const btTransform& to, + btCollisionWorld::ConvexResultCallback* resultCallback, const btCollisionObject* collisionObject, btConcaveShape* triangleMesh, const btTransform& triangleToWorld) : btTriangleConvexcastCallback(castShape, from, to, triangleToWorld, triangleMesh->getMargin()), + m_resultCallback(resultCallback), + m_collisionObject(collisionObject), + m_triangleMesh(triangleMesh) { } - - virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex ) + virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex) { - btCollisionWorld::LocalShapeInfo shapeInfo; + btCollisionWorld::LocalShapeInfo shapeInfo; shapeInfo.m_shapePart = partId; shapeInfo.m_triangleIndex = triangleIndex; if (hitFraction <= m_resultCallback->m_closestHitFraction) { + btCollisionWorld::LocalConvexResult convexResult(m_collisionObject, + &shapeInfo, + hitNormalLocal, + hitPointLocal, + hitFraction); - btCollisionWorld::LocalConvexResult convexResult - (m_collisionObject, - &shapeInfo, - hitNormalLocal, - hitPointLocal, - hitFraction); + bool normalInWorldSpace = true; - bool normalInWorldSpace = true; - - return m_resultCallback->addSingleResult(convexResult,normalInWorldSpace); + return m_resultCallback->addSingleResult(convexResult, normalInWorldSpace); } return hitFraction; } - }; - BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans,convexToTrans,&resultCallback,colObjWrap->getCollisionObject(),concaveShape, colObjWorldTransform); + BridgeTriangleConvexcastCallback tccb(castShape, convexFromTrans, convexToTrans, &resultCallback, colObjWrap->getCollisionObject(), concaveShape, colObjWorldTransform); tccb.m_hitFraction = resultCallback.m_closestHitFraction; tccb.m_allowedPenetration = allowedPenetration; btVector3 boxMinLocal, boxMaxLocal; @@ -848,35 +786,37 @@ void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape, rayAabbMaxLocal.setMax(convexToLocal); rayAabbMinLocal += boxMinLocal; rayAabbMaxLocal += boxMaxLocal; - concaveShape->processAllTriangles(&tccb,rayAabbMinLocal,rayAabbMaxLocal); + concaveShape->processAllTriangles(&tccb, rayAabbMinLocal, rayAabbMaxLocal); } } - } else { + } + else + { if (collisionShape->isCompound()) { - struct btCompoundLeafCallback : btDbvt::ICollide + struct btCompoundLeafCallback : btDbvt::ICollide { btCompoundLeafCallback( - const btCollisionObjectWrapper* colObjWrap, - const btConvexShape* castShape, - const btTransform& convexFromTrans, - const btTransform& convexToTrans, - btScalar allowedPenetration, - const btCompoundShape* compoundShape, - const btTransform& colObjWorldTransform, - ConvexResultCallback& resultCallback) - : - m_colObjWrap(colObjWrap), - m_castShape(castShape), - m_convexFromTrans(convexFromTrans), - m_convexToTrans(convexToTrans), - m_allowedPenetration(allowedPenetration), - m_compoundShape(compoundShape), - m_colObjWorldTransform(colObjWorldTransform), - m_resultCallback(resultCallback) { + const btCollisionObjectWrapper* colObjWrap, + const btConvexShape* castShape, + const btTransform& convexFromTrans, + const btTransform& convexToTrans, + btScalar allowedPenetration, + const btCompoundShape* compoundShape, + const btTransform& colObjWorldTransform, + ConvexResultCallback& resultCallback) + : m_colObjWrap(colObjWrap), + m_castShape(castShape), + m_convexFromTrans(convexFromTrans), + m_convexToTrans(convexToTrans), + m_allowedPenetration(allowedPenetration), + m_compoundShape(compoundShape), + m_colObjWorldTransform(colObjWorldTransform), + m_resultCallback(resultCallback) + { } - const btCollisionObjectWrapper* m_colObjWrap; + const btCollisionObjectWrapper* m_colObjWrap; const btConvexShape* m_castShape; const btTransform& m_convexFromTrans; const btTransform& m_convexToTrans; @@ -886,16 +826,16 @@ void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape, ConvexResultCallback& m_resultCallback; public: - - void ProcessChild(int index, const btTransform& childTrans, const btCollisionShape* childCollisionShape) + void ProcessChild(int index, const btTransform& childTrans, const btCollisionShape* childCollisionShape) { btTransform childWorldTrans = m_colObjWorldTransform * childTrans; - struct LocalInfoAdder : public ConvexResultCallback { + struct LocalInfoAdder : public ConvexResultCallback + { ConvexResultCallback* m_userCallback; int m_i; - LocalInfoAdder(int i, ConvexResultCallback *user) + LocalInfoAdder(int i, ConvexResultCallback* user) : m_userCallback(user), m_i(i) { m_closestHitFraction = m_userCallback->m_closestHitFraction; @@ -904,9 +844,9 @@ void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape, { return m_userCallback->needsCollision(p); } - virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& r, bool b) + virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& r, bool b) { - btCollisionWorld::LocalShapeInfo shapeInfo; + btCollisionWorld::LocalShapeInfo shapeInfo; shapeInfo.m_shapePart = -1; shapeInfo.m_triangleIndex = m_i; if (r.m_localShapeInfo == NULL) @@ -914,7 +854,6 @@ void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape, const btScalar result = m_userCallback->addSingleResult(r, b); m_closestHitFraction = m_userCallback->m_closestHitFraction; return result; - } }; @@ -925,7 +864,7 @@ void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape, objectQuerySingleInternal(m_castShape, m_convexFromTrans, m_convexToTrans, &tmpObj, my_cb, m_allowedPenetration); } - void Process(const btDbvtNode* leaf) + void Process(const btDbvtNode* leaf) { // Processing leaf node int index = leaf->dataAsInt; @@ -950,15 +889,18 @@ void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape, fromLocalAabbMax.setMax(toLocalAabbMax); btCompoundLeafCallback callback(colObjWrap, castShape, convexFromTrans, convexToTrans, - allowedPenetration, compoundShape, colObjWorldTransform, resultCallback); + allowedPenetration, compoundShape, colObjWorldTransform, resultCallback); const btDbvt* tree = compoundShape->getDynamicAabbTree(); - if (tree) { - const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds = btDbvtVolume::FromMM(fromLocalAabbMin, fromLocalAabbMax); + if (tree) + { + const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds = btDbvtVolume::FromMM(fromLocalAabbMin, fromLocalAabbMax); tree->collideTV(tree->m_root, bounds, callback); - } else { + } + else + { int i; - for (i=0;igetNumChildShapes();i++) + for (i = 0; i < compoundShape->getNumChildShapes(); i++) { const btCollisionShape* childCollisionShape = compoundShape->getChildShape(i); btTransform childTrans = compoundShape->getChildTransform(i); @@ -970,33 +912,31 @@ void btCollisionWorld::objectQuerySingleInternal(const btConvexShape* castShape, } } - struct btSingleRayCallback : public btBroadphaseRayCallback { + btVector3 m_rayFromWorld; + btVector3 m_rayToWorld; + btTransform m_rayFromTrans; + btTransform m_rayToTrans; + btVector3 m_hitNormal; - btVector3 m_rayFromWorld; - btVector3 m_rayToWorld; - btTransform m_rayFromTrans; - btTransform m_rayToTrans; - btVector3 m_hitNormal; + const btCollisionWorld* m_world; + btCollisionWorld::RayResultCallback& m_resultCallback; - const btCollisionWorld* m_world; - btCollisionWorld::RayResultCallback& m_resultCallback; - - btSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btCollisionWorld* world,btCollisionWorld::RayResultCallback& resultCallback) - :m_rayFromWorld(rayFromWorld), - m_rayToWorld(rayToWorld), - m_world(world), - m_resultCallback(resultCallback) + btSingleRayCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld, const btCollisionWorld* world, btCollisionWorld::RayResultCallback& resultCallback) + : m_rayFromWorld(rayFromWorld), + m_rayToWorld(rayToWorld), + m_world(world), + m_resultCallback(resultCallback) { m_rayFromTrans.setIdentity(); m_rayFromTrans.setOrigin(m_rayFromWorld); m_rayToTrans.setIdentity(); m_rayToTrans.setOrigin(m_rayToWorld); - btVector3 rayDir = (rayToWorld-rayFromWorld); + btVector3 rayDir = (rayToWorld - rayFromWorld); - rayDir.normalize (); + rayDir.normalize(); ///what about division by zero? --> just set rayDirection[i] to INF/BT_LARGE_FLOAT m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0]; m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[1]; @@ -1005,22 +945,19 @@ struct btSingleRayCallback : public btBroadphaseRayCallback m_signs[1] = m_rayDirectionInverse[1] < 0.0; m_signs[2] = m_rayDirectionInverse[2] < 0.0; - m_lambda_max = rayDir.dot(m_rayToWorld-m_rayFromWorld); - + m_lambda_max = rayDir.dot(m_rayToWorld - m_rayFromWorld); } - - - virtual bool process(const btBroadphaseProxy* proxy) + virtual bool process(const btBroadphaseProxy* proxy) { ///terminate further ray tests, once the closestHitFraction reached zero if (m_resultCallback.m_closestHitFraction == btScalar(0.f)) return false; - btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject; + btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject; //only perform raycast if filterMask matches - if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) + if (m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) { //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); //btVector3 collisionObjectAabbMin,collisionObjectAabbMax; @@ -1038,57 +975,53 @@ struct btSingleRayCallback : public btBroadphaseRayCallback //culling already done by broadphase //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal)) { - m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans, - collisionObject, - collisionObject->getCollisionShape(), - collisionObject->getWorldTransform(), - m_resultCallback); + m_world->rayTestSingle(m_rayFromTrans, m_rayToTrans, + collisionObject, + collisionObject->getCollisionShape(), + collisionObject->getWorldTransform(), + m_resultCallback); } } return true; } }; -void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const +void btCollisionWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const { //BT_PROFILE("rayTest"); /// use the broadphase to accelerate the search for objects, based on their aabb /// and for each object with ray-aabb overlap, perform an exact ray test - btSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback); + btSingleRayCallback rayCB(rayFromWorld, rayToWorld, this, resultCallback); #ifndef USE_BRUTEFORCE_RAYBROADPHASE - m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB); + m_broadphasePairCache->rayTest(rayFromWorld, rayToWorld, rayCB); #else - for (int i=0;igetNumCollisionObjects();i++) + for (int i = 0; i < this->getNumCollisionObjects(); i++) { rayCB.process(m_collisionObjects[i]->getBroadphaseHandle()); - } -#endif //USE_BRUTEFORCE_RAYBROADPHASE - + } +#endif //USE_BRUTEFORCE_RAYBROADPHASE } - struct btSingleSweepCallback : public btBroadphaseRayCallback { - - btTransform m_convexFromTrans; - btTransform m_convexToTrans; - btVector3 m_hitNormal; - const btCollisionWorld* m_world; - btCollisionWorld::ConvexResultCallback& m_resultCallback; - btScalar m_allowedCcdPenetration; + btTransform m_convexFromTrans; + btTransform m_convexToTrans; + btVector3 m_hitNormal; + const btCollisionWorld* m_world; + btCollisionWorld::ConvexResultCallback& m_resultCallback; + btScalar m_allowedCcdPenetration; const btConvexShape* m_castShape; - - btSingleSweepCallback(const btConvexShape* castShape, const btTransform& convexFromTrans,const btTransform& convexToTrans,const btCollisionWorld* world,btCollisionWorld::ConvexResultCallback& resultCallback,btScalar allowedPenetration) - :m_convexFromTrans(convexFromTrans), - m_convexToTrans(convexToTrans), - m_world(world), - m_resultCallback(resultCallback), - m_allowedCcdPenetration(allowedPenetration), - m_castShape(castShape) + btSingleSweepCallback(const btConvexShape* castShape, const btTransform& convexFromTrans, const btTransform& convexToTrans, const btCollisionWorld* world, btCollisionWorld::ConvexResultCallback& resultCallback, btScalar allowedPenetration) + : m_convexFromTrans(convexFromTrans), + m_convexToTrans(convexToTrans), + m_world(world), + m_resultCallback(resultCallback), + m_allowedCcdPenetration(allowedPenetration), + m_castShape(castShape) { - btVector3 unnormalizedRayDir = (m_convexToTrans.getOrigin()-m_convexFromTrans.getOrigin()); + btVector3 unnormalizedRayDir = (m_convexToTrans.getOrigin() - m_convexFromTrans.getOrigin()); btVector3 rayDir = unnormalizedRayDir.normalized(); ///what about division by zero? --> just set rayDirection[i] to INF/BT_LARGE_FLOAT m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(BT_LARGE_FLOAT) : btScalar(1.0) / rayDir[0]; @@ -1099,109 +1032,102 @@ struct btSingleSweepCallback : public btBroadphaseRayCallback m_signs[2] = m_rayDirectionInverse[2] < 0.0; m_lambda_max = rayDir.dot(unnormalizedRayDir); - } - virtual bool process(const btBroadphaseProxy* proxy) + virtual bool process(const btBroadphaseProxy* proxy) { ///terminate further convex sweep tests, once the closestHitFraction reached zero if (m_resultCallback.m_closestHitFraction == btScalar(0.f)) return false; - btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject; + btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject; //only perform raycast if filterMask matches - if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) { + if (m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) + { //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); - m_world->objectQuerySingle(m_castShape, m_convexFromTrans,m_convexToTrans, - collisionObject, - collisionObject->getCollisionShape(), - collisionObject->getWorldTransform(), - m_resultCallback, - m_allowedCcdPenetration); + m_world->objectQuerySingle(m_castShape, m_convexFromTrans, m_convexToTrans, + collisionObject, + collisionObject->getCollisionShape(), + collisionObject->getWorldTransform(), + m_resultCallback, + m_allowedCcdPenetration); } return true; } }; - - -void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const +void btCollisionWorld::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const { - BT_PROFILE("convexSweepTest"); /// use the broadphase to accelerate the search for objects, based on their aabb /// and for each object with ray-aabb overlap, perform an exact ray test /// unfortunately the implementation for rayTest and convexSweepTest duplicated, albeit practically identical - - - btTransform convexFromTrans,convexToTrans; + btTransform convexFromTrans, convexToTrans; convexFromTrans = convexFromWorld; convexToTrans = convexToWorld; btVector3 castShapeAabbMin, castShapeAabbMax; /* Compute AABB that encompasses angular movement */ { btVector3 linVel, angVel; - btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0f, linVel, angVel); + btTransformUtil::calculateVelocity(convexFromTrans, convexToTrans, 1.0f, linVel, angVel); btVector3 zeroLinVel; - zeroLinVel.setValue(0,0,0); + zeroLinVel.setValue(0, 0, 0); btTransform R; - R.setIdentity (); - R.setRotation (convexFromTrans.getRotation()); - castShape->calculateTemporalAabb (R, zeroLinVel, angVel, 1.0f, castShapeAabbMin, castShapeAabbMax); + R.setIdentity(); + R.setRotation(convexFromTrans.getRotation()); + castShape->calculateTemporalAabb(R, zeroLinVel, angVel, 1.0f, castShapeAabbMin, castShapeAabbMax); } #ifndef USE_BRUTEFORCE_RAYBROADPHASE - btSingleSweepCallback convexCB(castShape,convexFromWorld,convexToWorld,this,resultCallback,allowedCcdPenetration); + btSingleSweepCallback convexCB(castShape, convexFromWorld, convexToWorld, this, resultCallback, allowedCcdPenetration); - m_broadphasePairCache->rayTest(convexFromTrans.getOrigin(),convexToTrans.getOrigin(),convexCB,castShapeAabbMin,castShapeAabbMax); + m_broadphasePairCache->rayTest(convexFromTrans.getOrigin(), convexToTrans.getOrigin(), convexCB, castShapeAabbMin, castShapeAabbMax); #else /// go over all objects, and if the ray intersects their aabb + cast shape aabb, // do a ray-shape query using convexCaster (CCD) int i; - for (i=0;igetBroadphaseHandle())) { + if (resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) + { //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); - btVector3 collisionObjectAabbMin,collisionObjectAabbMax; - collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax); - AabbExpand (collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax); - btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing + btVector3 collisionObjectAabbMin, collisionObjectAabbMax; + collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(), collisionObjectAabbMin, collisionObjectAabbMax); + AabbExpand(collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax); + btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing btVector3 hitNormal; - if (btRayAabb(convexFromWorld.getOrigin(),convexToWorld.getOrigin(),collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal)) + if (btRayAabb(convexFromWorld.getOrigin(), convexToWorld.getOrigin(), collisionObjectAabbMin, collisionObjectAabbMax, hitLambda, hitNormal)) { - objectQuerySingle(castShape, convexFromTrans,convexToTrans, - collisionObject, - collisionObject->getCollisionShape(), - collisionObject->getWorldTransform(), - resultCallback, - allowedCcdPenetration); + objectQuerySingle(castShape, convexFromTrans, convexToTrans, + collisionObject, + collisionObject->getCollisionShape(), + collisionObject->getWorldTransform(), + resultCallback, + allowedCcdPenetration); } } } -#endif //USE_BRUTEFORCE_RAYBROADPHASE +#endif //USE_BRUTEFORCE_RAYBROADPHASE } - - struct btBridgedManifoldResult : public btManifoldResult { + btCollisionWorld::ContactResultCallback& m_resultCallback; - btCollisionWorld::ContactResultCallback& m_resultCallback; - - btBridgedManifoldResult( const btCollisionObjectWrapper* obj0Wrap,const btCollisionObjectWrapper* obj1Wrap,btCollisionWorld::ContactResultCallback& resultCallback ) - :btManifoldResult(obj0Wrap,obj1Wrap), - m_resultCallback(resultCallback) + btBridgedManifoldResult(const btCollisionObjectWrapper* obj0Wrap, const btCollisionObjectWrapper* obj1Wrap, btCollisionWorld::ContactResultCallback& resultCallback) + : btManifoldResult(obj0Wrap, obj1Wrap), + m_resultCallback(resultCallback) { } - virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) + virtual void addContactPoint(const btVector3& normalOnBInWorld, const btVector3& pointInWorld, btScalar depth) { bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject(); btVector3 pointA = pointInWorld + normalOnBInWorld * depth; @@ -1209,78 +1135,74 @@ struct btBridgedManifoldResult : public btManifoldResult btVector3 localB; if (isSwapped) { - localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA ); + localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA); localB = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld); - } else + } + else { - localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA ); + localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA); localB = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld); } - - btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth); + + btManifoldPoint newPt(localA, localB, normalOnBInWorld, depth); newPt.m_positionWorldOnA = pointA; newPt.m_positionWorldOnB = pointInWorld; - - //BP mod, store contact triangles. + + //BP mod, store contact triangles. if (isSwapped) { newPt.m_partId0 = m_partId1; newPt.m_partId1 = m_partId0; - newPt.m_index0 = m_index1; - newPt.m_index1 = m_index0; - } else + newPt.m_index0 = m_index1; + newPt.m_index1 = m_index0; + } + else { newPt.m_partId0 = m_partId0; newPt.m_partId1 = m_partId1; - newPt.m_index0 = m_index0; - newPt.m_index1 = m_index1; + newPt.m_index0 = m_index0; + newPt.m_index1 = m_index1; } //experimental feature info, for per-triangle material etc. - const btCollisionObjectWrapper* obj0Wrap = isSwapped? m_body1Wrap : m_body0Wrap; - const btCollisionObjectWrapper* obj1Wrap = isSwapped? m_body0Wrap : m_body1Wrap; - m_resultCallback.addSingleResult(newPt,obj0Wrap,newPt.m_partId0,newPt.m_index0,obj1Wrap,newPt.m_partId1,newPt.m_index1); - + const btCollisionObjectWrapper* obj0Wrap = isSwapped ? m_body1Wrap : m_body0Wrap; + const btCollisionObjectWrapper* obj1Wrap = isSwapped ? m_body0Wrap : m_body1Wrap; + m_resultCallback.addSingleResult(newPt, obj0Wrap, newPt.m_partId0, newPt.m_index0, obj1Wrap, newPt.m_partId1, newPt.m_index1); } - }; - - struct btSingleContactCallback : public btBroadphaseAabbCallback { - btCollisionObject* m_collisionObject; - btCollisionWorld* m_world; - btCollisionWorld::ContactResultCallback& m_resultCallback; - - - btSingleContactCallback(btCollisionObject* collisionObject, btCollisionWorld* world,btCollisionWorld::ContactResultCallback& resultCallback) - :m_collisionObject(collisionObject), - m_world(world), - m_resultCallback(resultCallback) + btCollisionWorld* m_world; + btCollisionWorld::ContactResultCallback& m_resultCallback; + + btSingleContactCallback(btCollisionObject* collisionObject, btCollisionWorld* world, btCollisionWorld::ContactResultCallback& resultCallback) + : m_collisionObject(collisionObject), + m_world(world), + m_resultCallback(resultCallback) { } - virtual bool process(const btBroadphaseProxy* proxy) + virtual bool process(const btBroadphaseProxy* proxy) { - btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject; + btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject; if (collisionObject == m_collisionObject) return true; //only perform raycast if filterMask matches - if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) + if (m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) { - btCollisionObjectWrapper ob0(0,m_collisionObject->getCollisionShape(),m_collisionObject,m_collisionObject->getWorldTransform(),-1,-1); - btCollisionObjectWrapper ob1(0,collisionObject->getCollisionShape(),collisionObject,collisionObject->getWorldTransform(),-1,-1); + btCollisionObjectWrapper ob0(0, m_collisionObject->getCollisionShape(), m_collisionObject, m_collisionObject->getWorldTransform(), -1, -1); + btCollisionObjectWrapper ob1(0, collisionObject->getCollisionShape(), collisionObject, collisionObject->getWorldTransform(), -1, -1); - btCollisionAlgorithm* algorithm = m_world->getDispatcher()->findAlgorithm(&ob0,&ob1,0, BT_CLOSEST_POINT_ALGORITHMS); + btCollisionAlgorithm* algorithm = m_world->getDispatcher()->findAlgorithm(&ob0, &ob1, 0, BT_CLOSEST_POINT_ALGORITHMS); if (algorithm) { - btBridgedManifoldResult contactPointResult(&ob0,&ob1, m_resultCallback); + btBridgedManifoldResult contactPointResult(&ob0, &ob1, m_resultCallback); //discrete collision detection query - - algorithm->processCollision(&ob0,&ob1, m_world->getDispatchInfo(),&contactPointResult); + + algorithm->processCollision(&ob0, &ob1, m_world->getDispatchInfo(), &contactPointResult); algorithm->~btCollisionAlgorithm(); m_world->getDispatcher()->freeCollisionAlgorithm(algorithm); @@ -1290,271 +1212,247 @@ struct btSingleContactCallback : public btBroadphaseAabbCallback } }; - ///contactTest performs a discrete collision test against all objects in the btCollisionWorld, and calls the resultCallback. ///it reports one or more contact points for every overlapping object (including the one with deepest penetration) -void btCollisionWorld::contactTest( btCollisionObject* colObj, ContactResultCallback& resultCallback) +void btCollisionWorld::contactTest(btCollisionObject* colObj, ContactResultCallback& resultCallback) { - btVector3 aabbMin,aabbMax; - colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(),aabbMin,aabbMax); - btSingleContactCallback contactCB(colObj,this,resultCallback); - - m_broadphasePairCache->aabbTest(aabbMin,aabbMax,contactCB); -} + btVector3 aabbMin, aabbMax; + colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), aabbMin, aabbMax); + btSingleContactCallback contactCB(colObj, this, resultCallback); + m_broadphasePairCache->aabbTest(aabbMin, aabbMax, contactCB); +} ///contactTest performs a discrete collision test between two collision objects and calls the resultCallback if overlap if detected. ///it reports one or more contact points (including the one with deepest penetration) -void btCollisionWorld::contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback) +void btCollisionWorld::contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback) { - btCollisionObjectWrapper obA(0,colObjA->getCollisionShape(),colObjA,colObjA->getWorldTransform(),-1,-1); - btCollisionObjectWrapper obB(0,colObjB->getCollisionShape(),colObjB,colObjB->getWorldTransform(),-1,-1); + btCollisionObjectWrapper obA(0, colObjA->getCollisionShape(), colObjA, colObjA->getWorldTransform(), -1, -1); + btCollisionObjectWrapper obB(0, colObjB->getCollisionShape(), colObjB, colObjB->getWorldTransform(), -1, -1); - btCollisionAlgorithm* algorithm = getDispatcher()->findAlgorithm(&obA,&obB, 0, BT_CLOSEST_POINT_ALGORITHMS); + btCollisionAlgorithm* algorithm = getDispatcher()->findAlgorithm(&obA, &obB, 0, BT_CLOSEST_POINT_ALGORITHMS); if (algorithm) { - btBridgedManifoldResult contactPointResult(&obA,&obB, resultCallback); + btBridgedManifoldResult contactPointResult(&obA, &obB, resultCallback); contactPointResult.m_closestPointDistanceThreshold = resultCallback.m_closestDistanceThreshold; //discrete collision detection query - algorithm->processCollision(&obA,&obB, getDispatchInfo(),&contactPointResult); + algorithm->processCollision(&obA, &obB, getDispatchInfo(), &contactPointResult); algorithm->~btCollisionAlgorithm(); getDispatcher()->freeCollisionAlgorithm(algorithm); } - } - - - class DebugDrawcallback : public btTriangleCallback, public btInternalTriangleIndexCallback { - btIDebugDraw* m_debugDrawer; - btVector3 m_color; - btTransform m_worldTrans; + btIDebugDraw* m_debugDrawer; + btVector3 m_color; + btTransform m_worldTrans; public: + DebugDrawcallback(btIDebugDraw* debugDrawer, const btTransform& worldTrans, const btVector3& color) : m_debugDrawer(debugDrawer), + m_color(color), + m_worldTrans(worldTrans) + { + } - DebugDrawcallback(btIDebugDraw* debugDrawer,const btTransform& worldTrans,const btVector3& color) : - m_debugDrawer(debugDrawer), - m_color(color), - m_worldTrans(worldTrans) - { - } + virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex) + { + processTriangle(triangle, partId, triangleIndex); + } - virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) - { - processTriangle(triangle,partId,triangleIndex); - } + virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) + { + (void)partId; + (void)triangleIndex; - virtual void processTriangle(btVector3* triangle,int partId, int triangleIndex) - { - (void)partId; - (void)triangleIndex; + btVector3 wv0, wv1, wv2; + wv0 = m_worldTrans * triangle[0]; + wv1 = m_worldTrans * triangle[1]; + wv2 = m_worldTrans * triangle[2]; + btVector3 center = (wv0 + wv1 + wv2) * btScalar(1. / 3.); - btVector3 wv0,wv1,wv2; - wv0 = m_worldTrans*triangle[0]; - wv1 = m_worldTrans*triangle[1]; - wv2 = m_worldTrans*triangle[2]; - btVector3 center = (wv0+wv1+wv2)*btScalar(1./3.); - - if (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawNormals ) - { - btVector3 normal = (wv1-wv0).cross(wv2-wv0); - normal.normalize(); - btVector3 normalColor(1,1,0); - m_debugDrawer->drawLine(center,center+normal,normalColor); - } - m_debugDrawer->drawLine(wv0,wv1,m_color); - m_debugDrawer->drawLine(wv1,wv2,m_color); - m_debugDrawer->drawLine(wv2,wv0,m_color); - } + if (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawNormals) + { + btVector3 normal = (wv1 - wv0).cross(wv2 - wv0); + normal.normalize(); + btVector3 normalColor(1, 1, 0); + m_debugDrawer->drawLine(center, center + normal, normalColor); + } + m_debugDrawer->drawLine(wv0, wv1, m_color); + m_debugDrawer->drawLine(wv1, wv2, m_color); + m_debugDrawer->drawLine(wv2, wv0, m_color); + } }; - void btCollisionWorld::debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color) { // Draw a small simplex at the center of the object if (getDebugDrawer() && getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawFrames) { - getDebugDrawer()->drawTransform(worldTransform,.1); + getDebugDrawer()->drawTransform(worldTransform, .1); } if (shape->getShapeType() == COMPOUND_SHAPE_PROXYTYPE) { const btCompoundShape* compoundShape = static_cast(shape); - for (int i=compoundShape->getNumChildShapes()-1;i>=0;i--) + for (int i = compoundShape->getNumChildShapes() - 1; i >= 0; i--) { btTransform childTrans = compoundShape->getChildTransform(i); const btCollisionShape* colShape = compoundShape->getChildShape(i); - debugDrawObject(worldTransform*childTrans,colShape,color); + debugDrawObject(worldTransform * childTrans, colShape, color); } - - } else + } + else { + switch (shape->getShapeType()) + { + case BOX_SHAPE_PROXYTYPE: + { + const btBoxShape* boxShape = static_cast(shape); + btVector3 halfExtents = boxShape->getHalfExtentsWithMargin(); + getDebugDrawer()->drawBox(-halfExtents, halfExtents, worldTransform, color); + break; + } - switch (shape->getShapeType()) - { + case SPHERE_SHAPE_PROXYTYPE: + { + const btSphereShape* sphereShape = static_cast(shape); + btScalar radius = sphereShape->getMargin(); //radius doesn't include the margin, so draw with margin - case BOX_SHAPE_PROXYTYPE: - { - const btBoxShape* boxShape = static_cast(shape); - btVector3 halfExtents = boxShape->getHalfExtentsWithMargin(); - getDebugDrawer()->drawBox(-halfExtents,halfExtents,worldTransform,color); - break; - } + getDebugDrawer()->drawSphere(radius, worldTransform, color); + break; + } + case MULTI_SPHERE_SHAPE_PROXYTYPE: + { + const btMultiSphereShape* multiSphereShape = static_cast(shape); - case SPHERE_SHAPE_PROXYTYPE: - { - const btSphereShape* sphereShape = static_cast(shape); - btScalar radius = sphereShape->getMargin();//radius doesn't include the margin, so draw with margin + btTransform childTransform; + childTransform.setIdentity(); - getDebugDrawer()->drawSphere(radius, worldTransform, color); - break; - } - case MULTI_SPHERE_SHAPE_PROXYTYPE: - { - const btMultiSphereShape* multiSphereShape = static_cast(shape); + for (int i = multiSphereShape->getSphereCount() - 1; i >= 0; i--) + { + childTransform.setOrigin(multiSphereShape->getSpherePosition(i)); + getDebugDrawer()->drawSphere(multiSphereShape->getSphereRadius(i), worldTransform * childTransform, color); + } - btTransform childTransform; - childTransform.setIdentity(); + break; + } + case CAPSULE_SHAPE_PROXYTYPE: + { + const btCapsuleShape* capsuleShape = static_cast(shape); - for (int i = multiSphereShape->getSphereCount()-1; i>=0;i--) - { - childTransform.setOrigin(multiSphereShape->getSpherePosition(i)); - getDebugDrawer()->drawSphere(multiSphereShape->getSphereRadius(i), worldTransform*childTransform, color); - } + btScalar radius = capsuleShape->getRadius(); + btScalar halfHeight = capsuleShape->getHalfHeight(); - break; - } - case CAPSULE_SHAPE_PROXYTYPE: - { - const btCapsuleShape* capsuleShape = static_cast(shape); + int upAxis = capsuleShape->getUpAxis(); + getDebugDrawer()->drawCapsule(radius, halfHeight, upAxis, worldTransform, color); + break; + } + case CONE_SHAPE_PROXYTYPE: + { + const btConeShape* coneShape = static_cast(shape); + btScalar radius = coneShape->getRadius(); //+coneShape->getMargin(); + btScalar height = coneShape->getHeight(); //+coneShape->getMargin(); - btScalar radius = capsuleShape->getRadius(); - btScalar halfHeight = capsuleShape->getHalfHeight(); + int upAxis = coneShape->getConeUpIndex(); + getDebugDrawer()->drawCone(radius, height, upAxis, worldTransform, color); + break; + } + case CYLINDER_SHAPE_PROXYTYPE: + { + const btCylinderShape* cylinder = static_cast(shape); + int upAxis = cylinder->getUpAxis(); + btScalar radius = cylinder->getRadius(); + btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis]; + getDebugDrawer()->drawCylinder(radius, halfHeight, upAxis, worldTransform, color); + break; + } - int upAxis = capsuleShape->getUpAxis(); - getDebugDrawer()->drawCapsule(radius, halfHeight, upAxis, worldTransform, color); - break; - } - case CONE_SHAPE_PROXYTYPE: - { - const btConeShape* coneShape = static_cast(shape); - btScalar radius = coneShape->getRadius();//+coneShape->getMargin(); - btScalar height = coneShape->getHeight();//+coneShape->getMargin(); + case STATIC_PLANE_PROXYTYPE: + { + const btStaticPlaneShape* staticPlaneShape = static_cast(shape); + btScalar planeConst = staticPlaneShape->getPlaneConstant(); + const btVector3& planeNormal = staticPlaneShape->getPlaneNormal(); + getDebugDrawer()->drawPlane(planeNormal, planeConst, worldTransform, color); + break; + } + default: + { + /// for polyhedral shapes + if (shape->isPolyhedral()) + { + btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*)shape; - int upAxis= coneShape->getConeUpIndex(); - getDebugDrawer()->drawCone(radius, height, upAxis, worldTransform, color); - break; + int i; + if (polyshape->getConvexPolyhedron()) + { + const btConvexPolyhedron* poly = polyshape->getConvexPolyhedron(); + for (i = 0; i < poly->m_faces.size(); i++) + { + btVector3 centroid(0, 0, 0); + int numVerts = poly->m_faces[i].m_indices.size(); + if (numVerts) + { + int lastV = poly->m_faces[i].m_indices[numVerts - 1]; + for (int v = 0; v < poly->m_faces[i].m_indices.size(); v++) + { + int curVert = poly->m_faces[i].m_indices[v]; + centroid += poly->m_vertices[curVert]; + getDebugDrawer()->drawLine(worldTransform * poly->m_vertices[lastV], worldTransform * poly->m_vertices[curVert], color); + lastV = curVert; + } + } + centroid *= btScalar(1.f) / btScalar(numVerts); + if (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawNormals) + { + btVector3 normalColor(1, 1, 0); + btVector3 faceNormal(poly->m_faces[i].m_plane[0], poly->m_faces[i].m_plane[1], poly->m_faces[i].m_plane[2]); + getDebugDrawer()->drawLine(worldTransform * centroid, worldTransform * (centroid + faceNormal), normalColor); + } + } + } + else + { + for (i = 0; i < polyshape->getNumEdges(); i++) + { + btVector3 a, b; + polyshape->getEdge(i, a, b); + btVector3 wa = worldTransform * a; + btVector3 wb = worldTransform * b; + getDebugDrawer()->drawLine(wa, wb, color); + } + } + } - } - case CYLINDER_SHAPE_PROXYTYPE: - { - const btCylinderShape* cylinder = static_cast(shape); - int upAxis = cylinder->getUpAxis(); - btScalar radius = cylinder->getRadius(); - btScalar halfHeight = cylinder->getHalfExtentsWithMargin()[upAxis]; - getDebugDrawer()->drawCylinder(radius, halfHeight, upAxis, worldTransform, color); - break; - } + if (shape->isConcave()) + { + btConcaveShape* concaveMesh = (btConcaveShape*)shape; - case STATIC_PLANE_PROXYTYPE: - { - const btStaticPlaneShape* staticPlaneShape = static_cast(shape); - btScalar planeConst = staticPlaneShape->getPlaneConstant(); - const btVector3& planeNormal = staticPlaneShape->getPlaneNormal(); - getDebugDrawer()->drawPlane(planeNormal, planeConst,worldTransform, color); - break; + ///@todo pass camera, for some culling? no -> we are not a graphics lib + btVector3 aabbMax(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); + btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT)); - } - default: - { + DebugDrawcallback drawCallback(getDebugDrawer(), worldTransform, color); + concaveMesh->processAllTriangles(&drawCallback, aabbMin, aabbMax); + } - /// for polyhedral shapes - if (shape->isPolyhedral()) - { - btPolyhedralConvexShape* polyshape = (btPolyhedralConvexShape*) shape; - - int i; - if (polyshape->getConvexPolyhedron()) - { - const btConvexPolyhedron* poly = polyshape->getConvexPolyhedron(); - for (i=0;im_faces.size();i++) - { - btVector3 centroid(0,0,0); - int numVerts = poly->m_faces[i].m_indices.size(); - if (numVerts) - { - int lastV = poly->m_faces[i].m_indices[numVerts-1]; - for (int v=0;vm_faces[i].m_indices.size();v++) - { - int curVert = poly->m_faces[i].m_indices[v]; - centroid+=poly->m_vertices[curVert]; - getDebugDrawer()->drawLine(worldTransform*poly->m_vertices[lastV],worldTransform*poly->m_vertices[curVert],color); - lastV = curVert; - } - } - centroid*= btScalar(1.f)/btScalar(numVerts); - if (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawNormals) - { - btVector3 normalColor(1,1,0); - btVector3 faceNormal(poly->m_faces[i].m_plane[0],poly->m_faces[i].m_plane[1],poly->m_faces[i].m_plane[2]); - getDebugDrawer()->drawLine(worldTransform*centroid,worldTransform*(centroid+faceNormal),normalColor); - } - - } - - - } else - { - for (i=0;igetNumEdges();i++) - { - btVector3 a,b; - polyshape->getEdge(i,a,b); - btVector3 wa = worldTransform * a; - btVector3 wb = worldTransform * b; - getDebugDrawer()->drawLine(wa,wb,color); - } - } - - - } - - if (shape->isConcave()) - { - btConcaveShape* concaveMesh = (btConcaveShape*) shape; - - ///@todo pass camera, for some culling? no -> we are not a graphics lib - btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); - btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); - - DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color); - concaveMesh->processAllTriangles(&drawCallback,aabbMin,aabbMax); - - } - - if (shape->getShapeType() == CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE) - { - btConvexTriangleMeshShape* convexMesh = (btConvexTriangleMeshShape*) shape; - //todo: pass camera for some culling - btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); - btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); - //DebugDrawcallback drawCallback; - DebugDrawcallback drawCallback(getDebugDrawer(),worldTransform,color); - convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback,aabbMin,aabbMax); - } - - - - } - + if (shape->getShapeType() == CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE) + { + btConvexTriangleMeshShape* convexMesh = (btConvexTriangleMeshShape*)shape; + //todo: pass camera for some culling + btVector3 aabbMax(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); + btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT)); + //DebugDrawcallback drawCallback; + DebugDrawcallback drawCallback(getDebugDrawer(), worldTransform, color); + convexMesh->getMeshInterface()->InternalProcessAllTriangles(&drawCallback, aabbMin, aabbMax); + } + } } } } - -void btCollisionWorld::debugDrawWorld() +void btCollisionWorld::debugDrawWorld() { if (getDebugDrawer()) { @@ -1562,25 +1460,23 @@ void btCollisionWorld::debugDrawWorld() btIDebugDraw::DefaultColors defaultColors = getDebugDrawer()->getDefaultColors(); - if ( getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints) + if (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawContactPoints) { - - if (getDispatcher()) { int numManifolds = getDispatcher()->getNumManifolds(); - - for (int i=0;igetManifoldByIndexInternal(i); //btCollisionObject* obA = static_cast(contactManifold->getBody0()); //btCollisionObject* obB = static_cast(contactManifold->getBody1()); int numContacts = contactManifold->getNumContacts(); - for (int j=0;jgetContactPoint(j); - getDebugDrawer()->drawContactPoint(cp.m_positionWorldOnB,cp.m_normalWorldOnB,cp.getDistance(),cp.getLifeTime(),defaultColors.m_contactPoint); + getDebugDrawer()->drawContactPoint(cp.m_positionWorldOnB, cp.m_normalWorldOnB, cp.getDistance(), cp.getLifeTime(), defaultColors.m_contactPoint); } } } @@ -1590,58 +1486,63 @@ void btCollisionWorld::debugDrawWorld() { int i; - for ( i=0;igetCollisionFlags() & btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT)==0) + if ((colObj->getCollisionFlags() & btCollisionObject::CF_DISABLE_VISUALIZE_OBJECT) == 0) { if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawWireframe)) { - btVector3 color(btScalar(0.4),btScalar(0.4),btScalar(0.4)); + btVector3 color(btScalar(0.4), btScalar(0.4), btScalar(0.4)); - switch(colObj->getActivationState()) + switch (colObj->getActivationState()) { - case ACTIVE_TAG: - color = defaultColors.m_activeObject; break; - case ISLAND_SLEEPING: - color = defaultColors.m_deactivatedObject;break; - case WANTS_DEACTIVATION: - color = defaultColors.m_wantsDeactivationObject;break; - case DISABLE_DEACTIVATION: - color = defaultColors.m_disabledDeactivationObject;break; - case DISABLE_SIMULATION: - color = defaultColors.m_disabledSimulationObject;break; - default: + case ACTIVE_TAG: + color = defaultColors.m_activeObject; + break; + case ISLAND_SLEEPING: + color = defaultColors.m_deactivatedObject; + break; + case WANTS_DEACTIVATION: + color = defaultColors.m_wantsDeactivationObject; + break; + case DISABLE_DEACTIVATION: + color = defaultColors.m_disabledDeactivationObject; + break; + case DISABLE_SIMULATION: + color = defaultColors.m_disabledSimulationObject; + break; + default: { - color = btVector3(btScalar(.3),btScalar(0.3),btScalar(0.3)); + color = btVector3(btScalar(.3), btScalar(0.3), btScalar(0.3)); } }; colObj->getCustomDebugColor(color); - debugDrawObject(colObj->getWorldTransform(),colObj->getCollisionShape(),color); + debugDrawObject(colObj->getWorldTransform(), colObj->getCollisionShape(), color); } if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb)) { - btVector3 minAabb,maxAabb; + btVector3 minAabb, maxAabb; btVector3 colorvec = defaultColors.m_aabb; - colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb); - btVector3 contactThreshold(gContactBreakingThreshold,gContactBreakingThreshold,gContactBreakingThreshold); + colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb, maxAabb); + btVector3 contactThreshold(gContactBreakingThreshold, gContactBreakingThreshold, gContactBreakingThreshold); minAabb -= contactThreshold; maxAabb += contactThreshold; - btVector3 minAabb2,maxAabb2; + btVector3 minAabb2, maxAabb2; - if(getDispatchInfo().m_useContinuous && colObj->getInternalType()==btCollisionObject::CO_RIGID_BODY && !colObj->isStaticOrKinematicObject()) + if (getDispatchInfo().m_useContinuous && colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY && !colObj->isStaticOrKinematicObject()) { - colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(),minAabb2,maxAabb2); + colObj->getCollisionShape()->getAabb(colObj->getInterpolationWorldTransform(), minAabb2, maxAabb2); minAabb2 -= contactThreshold; maxAabb2 += contactThreshold; minAabb.setMin(minAabb2); maxAabb.setMax(maxAabb2); } - m_debugDrawer->drawAabb(minAabb,maxAabb,colorvec); + m_debugDrawer->drawAabb(minAabb, maxAabb, colorvec); } } } @@ -1649,28 +1550,27 @@ void btCollisionWorld::debugDrawWorld() } } - -void btCollisionWorld::serializeCollisionObjects(btSerializer* serializer) +void btCollisionWorld::serializeCollisionObjects(btSerializer* serializer) { int i; ///keep track of shapes already serialized - btHashMap serializedShapes; + btHashMap serializedShapes; - for (i=0;igetCollisionShape(); if (!serializedShapes.find(shape)) { - serializedShapes.insert(shape,shape); + serializedShapes.insert(shape, shape); shape->serializeSingleShape(serializer); } } //serialize all collision objects - for (i=0;igetInternalType() == btCollisionObject::CO_COLLISION_OBJECT) @@ -1680,8 +1580,6 @@ void btCollisionWorld::serializeCollisionObjects(btSerializer* serializer) } } - - void btCollisionWorld::serializeContactManifolds(btSerializer* serializer) { if (serializer->getSerializationFlags() & BT_SERIALIZE_CONTACT_MANIFOLDS) @@ -1690,7 +1588,7 @@ void btCollisionWorld::serializeContactManifolds(btSerializer* serializer) for (int i = 0; i < numManifolds; i++) { const btPersistentManifold* manifold = getDispatcher()->getInternalManifoldPointer()[i]; - //don't serialize empty manifolds, they just take space + //don't serialize empty manifolds, they just take space //(may have to do it anyway if it destroys determinism) if (manifold->getNumContacts() == 0) continue; @@ -1702,16 +1600,13 @@ void btCollisionWorld::serializeContactManifolds(btSerializer* serializer) } } - -void btCollisionWorld::serialize(btSerializer* serializer) +void btCollisionWorld::serialize(btSerializer* serializer) { - serializer->startSerialization(); - + serializeCollisionObjects(serializer); serializeContactManifolds(serializer); - + serializer->finishSerialization(); } - diff --git a/src/BulletCollision/CollisionDispatch/btCollisionWorld.h b/src/BulletCollision/CollisionDispatch/btCollisionWorld.h index fd1509359..fd0e5b9bb 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionWorld.h +++ b/src/BulletCollision/CollisionDispatch/btCollisionWorld.h @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - /** * @mainpage Bullet Documentation * @@ -66,8 +65,6 @@ subject to the following restrictions: * For up-to-data information and copyright and contributors list check out the Bullet_User_Manual.pdf * */ - - #ifndef BT_COLLISION_WORLD_H #define BT_COLLISION_WORLD_H @@ -87,147 +84,138 @@ class btSerializer; ///CollisionWorld is interface and container for the collision detection class btCollisionWorld { - - protected: + btAlignedObjectArray m_collisionObjects; - btAlignedObjectArray m_collisionObjects; - - btDispatcher* m_dispatcher1; + btDispatcher* m_dispatcher1; - btDispatcherInfo m_dispatchInfo; + btDispatcherInfo m_dispatchInfo; - btBroadphaseInterface* m_broadphasePairCache; + btBroadphaseInterface* m_broadphasePairCache; - btIDebugDraw* m_debugDrawer; + btIDebugDraw* m_debugDrawer; ///m_forceUpdateAllAabbs can be set to false as an optimization to only update active object AABBs ///it is true by default, because it is error-prone (setting the position of static objects wouldn't update their AABB) bool m_forceUpdateAllAabbs; - void serializeCollisionObjects(btSerializer* serializer); + void serializeCollisionObjects(btSerializer* serializer); void serializeContactManifolds(btSerializer* serializer); - public: - //this constructor doesn't own the dispatcher and paircache/broadphase - btCollisionWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphasePairCache, btCollisionConfiguration* collisionConfiguration); + btCollisionWorld(btDispatcher* dispatcher, btBroadphaseInterface* broadphasePairCache, btCollisionConfiguration* collisionConfiguration); virtual ~btCollisionWorld(); - void setBroadphase(btBroadphaseInterface* pairCache) + void setBroadphase(btBroadphaseInterface* pairCache) { m_broadphasePairCache = pairCache; } - const btBroadphaseInterface* getBroadphase() const + const btBroadphaseInterface* getBroadphase() const { return m_broadphasePairCache; } - btBroadphaseInterface* getBroadphase() + btBroadphaseInterface* getBroadphase() { return m_broadphasePairCache; } - btOverlappingPairCache* getPairCache() + btOverlappingPairCache* getPairCache() { return m_broadphasePairCache->getOverlappingPairCache(); } - - btDispatcher* getDispatcher() + btDispatcher* getDispatcher() { return m_dispatcher1; } - const btDispatcher* getDispatcher() const + const btDispatcher* getDispatcher() const { return m_dispatcher1; } - void updateSingleAabb(btCollisionObject* colObj); + void updateSingleAabb(btCollisionObject* colObj); - virtual void updateAabbs(); + virtual void updateAabbs(); ///the computeOverlappingPairs is usually already called by performDiscreteCollisionDetection (or stepSimulation) ///it can be useful to use if you perform ray tests without collision detection/simulation - virtual void computeOverlappingPairs(); + virtual void computeOverlappingPairs(); - - virtual void setDebugDrawer(btIDebugDraw* debugDrawer) + virtual void setDebugDrawer(btIDebugDraw* debugDrawer) { - m_debugDrawer = debugDrawer; + m_debugDrawer = debugDrawer; } - virtual btIDebugDraw* getDebugDrawer() + virtual btIDebugDraw* getDebugDrawer() { return m_debugDrawer; } - virtual void debugDrawWorld(); + virtual void debugDrawWorld(); virtual void debugDrawObject(const btTransform& worldTransform, const btCollisionShape* shape, const btVector3& color); - ///LocalShapeInfo gives extra information for complex shapes ///Currently, only btTriangleMeshShape is available, so it just contains triangleIndex and subpart - struct LocalShapeInfo + struct LocalShapeInfo { - int m_shapePart; - int m_triangleIndex; - + int m_shapePart; + int m_triangleIndex; + //const btCollisionShape* m_shapeTemp; //const btTransform* m_shapeLocalTransform; }; - struct LocalRayResult + struct LocalRayResult { - LocalRayResult(const btCollisionObject* collisionObject, - LocalShapeInfo* localShapeInfo, - const btVector3& hitNormalLocal, - btScalar hitFraction) - :m_collisionObject(collisionObject), - m_localShapeInfo(localShapeInfo), - m_hitNormalLocal(hitNormalLocal), - m_hitFraction(hitFraction) + LocalRayResult(const btCollisionObject* collisionObject, + LocalShapeInfo* localShapeInfo, + const btVector3& hitNormalLocal, + btScalar hitFraction) + : m_collisionObject(collisionObject), + m_localShapeInfo(localShapeInfo), + m_hitNormalLocal(hitNormalLocal), + m_hitFraction(hitFraction) { } - const btCollisionObject* m_collisionObject; - LocalShapeInfo* m_localShapeInfo; - btVector3 m_hitNormalLocal; - btScalar m_hitFraction; - + const btCollisionObject* m_collisionObject; + LocalShapeInfo* m_localShapeInfo; + btVector3 m_hitNormalLocal; + btScalar m_hitFraction; }; ///RayResultCallback is used to report new raycast results - struct RayResultCallback + struct RayResultCallback { - btScalar m_closestHitFraction; - const btCollisionObject* m_collisionObject; - int m_collisionFilterGroup; - int m_collisionFilterMask; + btScalar m_closestHitFraction; + const btCollisionObject* m_collisionObject; + int m_collisionFilterGroup; + int m_collisionFilterMask; //@BP Mod - Custom flags, currently used to enable backface culling on tri-meshes, see btRaycastCallback.h. Apply any of the EFlags defined there on m_flags here to invoke. unsigned int m_flags; virtual ~RayResultCallback() { } - bool hasHit() const + bool hasHit() const { return (m_collisionObject != 0); } RayResultCallback() - :m_closestHitFraction(btScalar(1.)), - m_collisionObject(0), - m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter), - m_collisionFilterMask(btBroadphaseProxy::AllFilter), - //@BP Mod - m_flags(0) + : m_closestHitFraction(btScalar(1.)), + m_collisionObject(0), + m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter), + m_collisionFilterMask(btBroadphaseProxy::AllFilter), + //@BP Mod + m_flags(0) { } @@ -238,62 +226,62 @@ public: return collides; } - - virtual btScalar addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace) = 0; + virtual btScalar addSingleResult(LocalRayResult& rayResult, bool normalInWorldSpace) = 0; }; - struct ClosestRayResultCallback : public RayResultCallback + struct ClosestRayResultCallback : public RayResultCallback { - ClosestRayResultCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld) - :m_rayFromWorld(rayFromWorld), - m_rayToWorld(rayToWorld) + ClosestRayResultCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld) + : m_rayFromWorld(rayFromWorld), + m_rayToWorld(rayToWorld) { } - btVector3 m_rayFromWorld;//used to calculate hitPointWorld from hitFraction - btVector3 m_rayToWorld; + btVector3 m_rayFromWorld; //used to calculate hitPointWorld from hitFraction + btVector3 m_rayToWorld; - btVector3 m_hitNormalWorld; - btVector3 m_hitPointWorld; - - virtual btScalar addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace) + btVector3 m_hitNormalWorld; + btVector3 m_hitPointWorld; + + virtual btScalar addSingleResult(LocalRayResult& rayResult, bool normalInWorldSpace) { //caller already does the filter on the m_closestHitFraction btAssert(rayResult.m_hitFraction <= m_closestHitFraction); - + m_closestHitFraction = rayResult.m_hitFraction; m_collisionObject = rayResult.m_collisionObject; if (normalInWorldSpace) { m_hitNormalWorld = rayResult.m_hitNormalLocal; - } else + } + else { ///need to transform normal into worldspace - m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal; + m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis() * rayResult.m_hitNormalLocal; } - m_hitPointWorld.setInterpolate3(m_rayFromWorld,m_rayToWorld,rayResult.m_hitFraction); + m_hitPointWorld.setInterpolate3(m_rayFromWorld, m_rayToWorld, rayResult.m_hitFraction); return rayResult.m_hitFraction; } }; - struct AllHitsRayResultCallback : public RayResultCallback + struct AllHitsRayResultCallback : public RayResultCallback { - AllHitsRayResultCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld) - :m_rayFromWorld(rayFromWorld), - m_rayToWorld(rayToWorld) + AllHitsRayResultCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld) + : m_rayFromWorld(rayFromWorld), + m_rayToWorld(rayToWorld) { } - btAlignedObjectArray m_collisionObjects; + btAlignedObjectArray m_collisionObjects; - btVector3 m_rayFromWorld;//used to calculate hitPointWorld from hitFraction - btVector3 m_rayToWorld; + btVector3 m_rayFromWorld; //used to calculate hitPointWorld from hitFraction + btVector3 m_rayToWorld; - btAlignedObjectArray m_hitNormalWorld; - btAlignedObjectArray m_hitPointWorld; + btAlignedObjectArray m_hitNormalWorld; + btAlignedObjectArray m_hitPointWorld; btAlignedObjectArray m_hitFractions; - - virtual btScalar addSingleResult(LocalRayResult& rayResult,bool normalInWorldSpace) + + virtual btScalar addSingleResult(LocalRayResult& rayResult, bool normalInWorldSpace) { m_collisionObject = rayResult.m_collisionObject; m_collisionObjects.push_back(rayResult.m_collisionObject); @@ -301,69 +289,66 @@ public: if (normalInWorldSpace) { hitNormalWorld = rayResult.m_hitNormalLocal; - } else + } + else { ///need to transform normal into worldspace - hitNormalWorld = m_collisionObject->getWorldTransform().getBasis()*rayResult.m_hitNormalLocal; + hitNormalWorld = m_collisionObject->getWorldTransform().getBasis() * rayResult.m_hitNormalLocal; } m_hitNormalWorld.push_back(hitNormalWorld); btVector3 hitPointWorld; - hitPointWorld.setInterpolate3(m_rayFromWorld,m_rayToWorld,rayResult.m_hitFraction); + hitPointWorld.setInterpolate3(m_rayFromWorld, m_rayToWorld, rayResult.m_hitFraction); m_hitPointWorld.push_back(hitPointWorld); m_hitFractions.push_back(rayResult.m_hitFraction); return m_closestHitFraction; } }; - struct LocalConvexResult { - LocalConvexResult(const btCollisionObject* hitCollisionObject, - LocalShapeInfo* localShapeInfo, - const btVector3& hitNormalLocal, - const btVector3& hitPointLocal, - btScalar hitFraction - ) - :m_hitCollisionObject(hitCollisionObject), - m_localShapeInfo(localShapeInfo), - m_hitNormalLocal(hitNormalLocal), - m_hitPointLocal(hitPointLocal), - m_hitFraction(hitFraction) + LocalConvexResult(const btCollisionObject* hitCollisionObject, + LocalShapeInfo* localShapeInfo, + const btVector3& hitNormalLocal, + const btVector3& hitPointLocal, + btScalar hitFraction) + : m_hitCollisionObject(hitCollisionObject), + m_localShapeInfo(localShapeInfo), + m_hitNormalLocal(hitNormalLocal), + m_hitPointLocal(hitPointLocal), + m_hitFraction(hitFraction) { } - const btCollisionObject* m_hitCollisionObject; - LocalShapeInfo* m_localShapeInfo; - btVector3 m_hitNormalLocal; - btVector3 m_hitPointLocal; - btScalar m_hitFraction; + const btCollisionObject* m_hitCollisionObject; + LocalShapeInfo* m_localShapeInfo; + btVector3 m_hitNormalLocal; + btVector3 m_hitPointLocal; + btScalar m_hitFraction; }; ///RayResultCallback is used to report new raycast results - struct ConvexResultCallback + struct ConvexResultCallback { - btScalar m_closestHitFraction; - int m_collisionFilterGroup; - int m_collisionFilterMask; - + btScalar m_closestHitFraction; + int m_collisionFilterGroup; + int m_collisionFilterMask; + ConvexResultCallback() - :m_closestHitFraction(btScalar(1.)), - m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter), - m_collisionFilterMask(btBroadphaseProxy::AllFilter) + : m_closestHitFraction(btScalar(1.)), + m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter), + m_collisionFilterMask(btBroadphaseProxy::AllFilter) { } virtual ~ConvexResultCallback() { } - - bool hasHit() const + + bool hasHit() const { return (m_closestHitFraction < btScalar(1.)); } - - virtual bool needsCollision(btBroadphaseProxy* proxy0) const { bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0; @@ -371,39 +356,40 @@ public: return collides; } - virtual btScalar addSingleResult(LocalConvexResult& convexResult,bool normalInWorldSpace) = 0; + virtual btScalar addSingleResult(LocalConvexResult& convexResult, bool normalInWorldSpace) = 0; }; - struct ClosestConvexResultCallback : public ConvexResultCallback + struct ClosestConvexResultCallback : public ConvexResultCallback { - ClosestConvexResultCallback(const btVector3& convexFromWorld,const btVector3& convexToWorld) - :m_convexFromWorld(convexFromWorld), - m_convexToWorld(convexToWorld), - m_hitCollisionObject(0) + ClosestConvexResultCallback(const btVector3& convexFromWorld, const btVector3& convexToWorld) + : m_convexFromWorld(convexFromWorld), + m_convexToWorld(convexToWorld), + m_hitCollisionObject(0) { } - btVector3 m_convexFromWorld;//used to calculate hitPointWorld from hitFraction - btVector3 m_convexToWorld; + btVector3 m_convexFromWorld; //used to calculate hitPointWorld from hitFraction + btVector3 m_convexToWorld; - btVector3 m_hitNormalWorld; - btVector3 m_hitPointWorld; - const btCollisionObject* m_hitCollisionObject; - - virtual btScalar addSingleResult(LocalConvexResult& convexResult,bool normalInWorldSpace) + btVector3 m_hitNormalWorld; + btVector3 m_hitPointWorld; + const btCollisionObject* m_hitCollisionObject; + + virtual btScalar addSingleResult(LocalConvexResult& convexResult, bool normalInWorldSpace) { -//caller already does the filter on the m_closestHitFraction + //caller already does the filter on the m_closestHitFraction btAssert(convexResult.m_hitFraction <= m_closestHitFraction); - + m_closestHitFraction = convexResult.m_hitFraction; m_hitCollisionObject = convexResult.m_hitCollisionObject; if (normalInWorldSpace) { m_hitNormalWorld = convexResult.m_hitNormalLocal; - } else + } + else { ///need to transform normal into worldspace - m_hitNormalWorld = m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal; + m_hitNormalWorld = m_hitCollisionObject->getWorldTransform().getBasis() * convexResult.m_hitNormalLocal; } m_hitPointWorld = convexResult.m_hitPointLocal; return convexResult.m_hitFraction; @@ -411,23 +397,23 @@ public: }; ///ContactResultCallback is used to report contact points - struct ContactResultCallback + struct ContactResultCallback { - int m_collisionFilterGroup; - int m_collisionFilterMask; - btScalar m_closestDistanceThreshold; + int m_collisionFilterGroup; + int m_collisionFilterMask; + btScalar m_closestDistanceThreshold; ContactResultCallback() - :m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter), - m_collisionFilterMask(btBroadphaseProxy::AllFilter), - m_closestDistanceThreshold(0) + : m_collisionFilterGroup(btBroadphaseProxy::DefaultFilter), + m_collisionFilterMask(btBroadphaseProxy::AllFilter), + m_closestDistanceThreshold(0) { } virtual ~ContactResultCallback() { } - + virtual bool needsCollision(btBroadphaseProxy* proxy0) const { bool collides = (proxy0->m_collisionFilterGroup & m_collisionFilterMask) != 0; @@ -435,61 +421,57 @@ public: return collides; } - virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1) = 0; + virtual btScalar addSingleResult(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper* colObj1Wrap, int partId1, int index1) = 0; }; - - - int getNumCollisionObjects() const + int getNumCollisionObjects() const { return int(m_collisionObjects.size()); } /// rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback /// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback. - virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const; + virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const; /// convexTest performs a swept convex cast on all objects in the btCollisionWorld, and calls the resultCallback /// This allows for several queries: first hit, all hits, any hit, dependent on the value return by the callback. - void convexSweepTest (const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration = btScalar(0.)) const; + void convexSweepTest(const btConvexShape* castShape, const btTransform& from, const btTransform& to, ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration = btScalar(0.)) const; ///contactTest performs a discrete collision test between colObj against all objects in the btCollisionWorld, and calls the resultCallback. ///it reports one or more contact points for every overlapping object (including the one with deepest penetration) - void contactTest(btCollisionObject* colObj, ContactResultCallback& resultCallback); + void contactTest(btCollisionObject* colObj, ContactResultCallback& resultCallback); ///contactTest performs a discrete collision test between two collision objects and calls the resultCallback if overlap if detected. ///it reports one or more contact points (including the one with deepest penetration) - void contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback); - + void contactPairTest(btCollisionObject* colObjA, btCollisionObject* colObjB, ContactResultCallback& resultCallback); /// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest. /// In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape. /// This allows more customization. - static void rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans, - btCollisionObject* collisionObject, - const btCollisionShape* collisionShape, - const btTransform& colObjWorldTransform, - RayResultCallback& resultCallback); + static void rayTestSingle(const btTransform& rayFromTrans, const btTransform& rayToTrans, + btCollisionObject* collisionObject, + const btCollisionShape* collisionShape, + const btTransform& colObjWorldTransform, + RayResultCallback& resultCallback); - static void rayTestSingleInternal(const btTransform& rayFromTrans,const btTransform& rayToTrans, - const btCollisionObjectWrapper* collisionObjectWrap, - RayResultCallback& resultCallback); + static void rayTestSingleInternal(const btTransform& rayFromTrans, const btTransform& rayToTrans, + const btCollisionObjectWrapper* collisionObjectWrap, + RayResultCallback& resultCallback); /// objectQuerySingle performs a collision detection query and calls the resultCallback. It is used internally by rayTest. - static void objectQuerySingle(const btConvexShape* castShape, const btTransform& rayFromTrans,const btTransform& rayToTrans, - btCollisionObject* collisionObject, - const btCollisionShape* collisionShape, - const btTransform& colObjWorldTransform, - ConvexResultCallback& resultCallback, btScalar allowedPenetration); + static void objectQuerySingle(const btConvexShape* castShape, const btTransform& rayFromTrans, const btTransform& rayToTrans, + btCollisionObject* collisionObject, + const btCollisionShape* collisionShape, + const btTransform& colObjWorldTransform, + ConvexResultCallback& resultCallback, btScalar allowedPenetration); - static void objectQuerySingleInternal(const btConvexShape* castShape,const btTransform& convexFromTrans,const btTransform& convexToTrans, - const btCollisionObjectWrapper* colObjWrap, - ConvexResultCallback& resultCallback, btScalar allowedPenetration); + static void objectQuerySingleInternal(const btConvexShape* castShape, const btTransform& convexFromTrans, const btTransform& convexToTrans, + const btCollisionObjectWrapper* colObjWrap, + ConvexResultCallback& resultCallback, btScalar allowedPenetration); - virtual void addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup=btBroadphaseProxy::DefaultFilter, int collisionFilterMask=btBroadphaseProxy::AllFilter); - - virtual void refreshBroadphaseProxy(btCollisionObject* collisionObject); + virtual void addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup = btBroadphaseProxy::DefaultFilter, int collisionFilterMask = btBroadphaseProxy::AllFilter); + virtual void refreshBroadphaseProxy(btCollisionObject* collisionObject); btCollisionObjectArray& getCollisionObjectArray() { @@ -501,10 +483,9 @@ public: return m_collisionObjects; } + virtual void removeCollisionObject(btCollisionObject* collisionObject); - virtual void removeCollisionObject(btCollisionObject* collisionObject); - - virtual void performDiscreteCollisionDetection(); + virtual void performDiscreteCollisionDetection(); btDispatcherInfo& getDispatchInfo() { @@ -515,20 +496,18 @@ public: { return m_dispatchInfo; } - - bool getForceUpdateAllAabbs() const + + bool getForceUpdateAllAabbs() const { return m_forceUpdateAllAabbs; } - void setForceUpdateAllAabbs( bool forceUpdateAllAabbs) + void setForceUpdateAllAabbs(bool forceUpdateAllAabbs) { m_forceUpdateAllAabbs = forceUpdateAllAabbs; } ///Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (Bullet/Demos/SerializeDemo) - virtual void serialize(btSerializer* serializer); - + virtual void serialize(btSerializer* serializer); }; - -#endif //BT_COLLISION_WORLD_H +#endif //BT_COLLISION_WORLD_H diff --git a/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.cpp b/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.cpp index f2b083780..9f422dc15 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.cpp +++ b/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.cpp @@ -15,269 +15,251 @@ subject to the following restrictions: #include "btCollisionWorldImporter.h" #include "btBulletCollisionCommon.h" -#include "LinearMath/btSerializer.h" //for btBulletSerializedArrays definition +#include "LinearMath/btSerializer.h" //for btBulletSerializedArrays definition #ifdef SUPPORT_GIMPACT_SHAPE_IMPORT #include "BulletCollision/Gimpact/btGImpactShape.h" -#endif //SUPPORT_GIMPACT_SHAPE_IMPORT +#endif //SUPPORT_GIMPACT_SHAPE_IMPORT btCollisionWorldImporter::btCollisionWorldImporter(btCollisionWorld* world) -:m_collisionWorld(world), -m_verboseMode(0) + : m_collisionWorld(world), + m_verboseMode(0) { - } btCollisionWorldImporter::~btCollisionWorldImporter() { } - - - - -bool btCollisionWorldImporter::convertAllObjects( btBulletSerializedArrays* arrays) +bool btCollisionWorldImporter::convertAllObjects(btBulletSerializedArrays* arrays) { - m_shapeMap.clear(); m_bodyMap.clear(); int i; - for (i=0;im_bvhsDouble.size();i++) + for (i = 0; i < arrays->m_bvhsDouble.size(); i++) { btOptimizedBvh* bvh = createOptimizedBvh(); btQuantizedBvhDoubleData* bvhData = arrays->m_bvhsDouble[i]; bvh->deSerializeDouble(*bvhData); - m_bvhMap.insert(arrays->m_bvhsDouble[i],bvh); + m_bvhMap.insert(arrays->m_bvhsDouble[i], bvh); } - for (i=0;im_bvhsFloat.size();i++) - { - btOptimizedBvh* bvh = createOptimizedBvh(); - btQuantizedBvhFloatData* bvhData = arrays->m_bvhsFloat[i]; + for (i = 0; i < arrays->m_bvhsFloat.size(); i++) + { + btOptimizedBvh* bvh = createOptimizedBvh(); + btQuantizedBvhFloatData* bvhData = arrays->m_bvhsFloat[i]; bvh->deSerializeFloat(*bvhData); - m_bvhMap.insert(arrays->m_bvhsFloat[i],bvh); + m_bvhMap.insert(arrays->m_bvhsFloat[i], bvh); } - - - - - for (i=0;im_colShapeData.size();i++) + for (i = 0; i < arrays->m_colShapeData.size(); i++) { btCollisionShapeData* shapeData = arrays->m_colShapeData[i]; btCollisionShape* shape = convertCollisionShape(shapeData); if (shape) { - // printf("shapeMap.insert(%x,%x)\n",shapeData,shape); - m_shapeMap.insert(shapeData,shape); + // printf("shapeMap.insert(%x,%x)\n",shapeData,shape); + m_shapeMap.insert(shapeData, shape); } - if (shape&& shapeData->m_name) + if (shape && shapeData->m_name) { char* newname = duplicateName(shapeData->m_name); - m_objectNameMap.insert(shape,newname); - m_nameShapeMap.insert(newname,shape); + m_objectNameMap.insert(shape, newname); + m_nameShapeMap.insert(newname, shape); } } - - for (i=0;im_collisionObjectDataDouble.size();i++) + for (i = 0; i < arrays->m_collisionObjectDataDouble.size(); i++) { - btCollisionObjectDoubleData* colObjData = arrays->m_collisionObjectDataDouble[i]; - btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape); - if (shapePtr && *shapePtr) - { - btTransform startTransform; - colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f; - startTransform.deSerializeDouble(colObjData->m_worldTransform); + btCollisionObjectDoubleData* colObjData = arrays->m_collisionObjectDataDouble[i]; + btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape); + if (shapePtr && *shapePtr) + { + btTransform startTransform; + colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f; + startTransform.deSerializeDouble(colObjData->m_worldTransform); - btCollisionShape* shape = (btCollisionShape*)*shapePtr; - btCollisionObject* body = createCollisionObject(startTransform,shape,colObjData->m_name); - body->setFriction(btScalar(colObjData->m_friction)); - body->setRestitution(btScalar(colObjData->m_restitution)); + btCollisionShape* shape = (btCollisionShape*)*shapePtr; + btCollisionObject* body = createCollisionObject(startTransform, shape, colObjData->m_name); + body->setFriction(btScalar(colObjData->m_friction)); + body->setRestitution(btScalar(colObjData->m_restitution)); #ifdef USE_INTERNAL_EDGE_UTILITY - if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) - { - btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape; - if (trimesh->getTriangleInfoMap()) - { - body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); - } - } -#endif //USE_INTERNAL_EDGE_UTILITY - m_bodyMap.insert(colObjData,body); - } else - { - printf("error: no shape found\n"); - } + if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape; + if (trimesh->getTriangleInfoMap()) + { + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + } + } +#endif //USE_INTERNAL_EDGE_UTILITY + m_bodyMap.insert(colObjData, body); + } + else + { + printf("error: no shape found\n"); + } } - for (i=0;im_collisionObjectDataFloat.size();i++) + for (i = 0; i < arrays->m_collisionObjectDataFloat.size(); i++) { - btCollisionObjectFloatData* colObjData = arrays->m_collisionObjectDataFloat[i]; - btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape); - if (shapePtr && *shapePtr) - { - btTransform startTransform; - colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f; - startTransform.deSerializeFloat(colObjData->m_worldTransform); + btCollisionObjectFloatData* colObjData = arrays->m_collisionObjectDataFloat[i]; + btCollisionShape** shapePtr = m_shapeMap.find(colObjData->m_collisionShape); + if (shapePtr && *shapePtr) + { + btTransform startTransform; + colObjData->m_worldTransform.m_origin.m_floats[3] = 0.f; + startTransform.deSerializeFloat(colObjData->m_worldTransform); - btCollisionShape* shape = (btCollisionShape*)*shapePtr; - btCollisionObject* body = createCollisionObject(startTransform,shape,colObjData->m_name); + btCollisionShape* shape = (btCollisionShape*)*shapePtr; + btCollisionObject* body = createCollisionObject(startTransform, shape, colObjData->m_name); #ifdef USE_INTERNAL_EDGE_UTILITY - if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) - { - btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape; - if (trimesh->getTriangleInfoMap()) - { - body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); - } - } -#endif //USE_INTERNAL_EDGE_UTILITY - m_bodyMap.insert(colObjData,body); - } else - { - printf("error: no shape found\n"); - } - } + if (shape->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) + { + btBvhTriangleMeshShape* trimesh = (btBvhTriangleMeshShape*)shape; + if (trimesh->getTriangleInfoMap()) + { + body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK); + } + } +#endif //USE_INTERNAL_EDGE_UTILITY + m_bodyMap.insert(colObjData, body); + } + else + { + printf("error: no shape found\n"); + } + } return true; } - - void btCollisionWorldImporter::deleteAllData() { int i; - for (i=0;iremoveCollisionObject(m_allocatedCollisionObjects[i]); delete m_allocatedCollisionObjects[i]; } m_allocatedCollisionObjects.clear(); - - for (i=0;im_numMeshParts;a++) + for (int a = 0; a < curData->m_numMeshParts; a++) { btMeshPartData* curPart = &curData->m_meshPartsPtr[a]; - if(curPart->m_vertices3f) - delete [] curPart->m_vertices3f; + if (curPart->m_vertices3f) + delete[] curPart->m_vertices3f; - if(curPart->m_vertices3d) - delete [] curPart->m_vertices3d; + if (curPart->m_vertices3d) + delete[] curPart->m_vertices3d; - if(curPart->m_indices32) - delete [] curPart->m_indices32; + if (curPart->m_indices32) + delete[] curPart->m_indices32; - if(curPart->m_3indices16) - delete [] curPart->m_3indices16; + if (curPart->m_3indices16) + delete[] curPart->m_3indices16; - if(curPart->m_indices16) - delete [] curPart->m_indices16; + if (curPart->m_indices16) + delete[] curPart->m_indices16; if (curPart->m_3indices8) - delete [] curPart->m_3indices8; - + delete[] curPart->m_3indices8; } - delete [] curData->m_meshPartsPtr; + delete[] curData->m_meshPartsPtr; delete curData; } m_allocatedbtStridingMeshInterfaceDatas.clear(); - for (i=0;im_shapeType) - { - case STATIC_PLANE_PROXYTYPE: + { + case STATIC_PLANE_PROXYTYPE: { btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*)shapeData; - btVector3 planeNormal,localScaling; + btVector3 planeNormal, localScaling; planeNormal.deSerializeFloat(planeData->m_planeNormal); localScaling.deSerializeFloat(planeData->m_localScaling); - shape = createPlaneShape(planeNormal,planeData->m_planeConstant); + shape = createPlaneShape(planeNormal, planeData->m_planeConstant); shape->setLocalScaling(localScaling); break; } - case SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE: + case SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE: { - btScaledTriangleMeshShapeData* scaledMesh = (btScaledTriangleMeshShapeData*) shapeData; - btCollisionShapeData* colShapeData = (btCollisionShapeData*) &scaledMesh->m_trimeshShapeData; + btScaledTriangleMeshShapeData* scaledMesh = (btScaledTriangleMeshShapeData*)shapeData; + btCollisionShapeData* colShapeData = (btCollisionShapeData*)&scaledMesh->m_trimeshShapeData; colShapeData->m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE; btCollisionShape* childShape = convertCollisionShape(colShapeData); btBvhTriangleMeshShape* meshShape = (btBvhTriangleMeshShape*)childShape; @@ -288,15 +270,14 @@ btCollisionShape* btCollisionWorldImporter::convertCollisionShape( btCollisionS break; } #ifdef SUPPORT_GIMPACT_SHAPE_IMPORT - case GIMPACT_SHAPE_PROXYTYPE: + case GIMPACT_SHAPE_PROXYTYPE: { - btGImpactMeshShapeData* gimpactData = (btGImpactMeshShapeData*) shapeData; + btGImpactMeshShapeData* gimpactData = (btGImpactMeshShapeData*)shapeData; if (gimpactData->m_gimpactSubType == CONST_GIMPACT_TRIMESH_SHAPE) { btStridingMeshInterfaceData* interfaceData = createStridingMeshInterfaceData(&gimpactData->m_meshInterface); btTriangleIndexVertexArray* meshInterface = createMeshInterface(*interfaceData); - btGImpactMeshShape* gimpactShape = createGimpactShape(meshInterface); btVector3 localScaling; localScaling.deSerializeFloat(gimpactData->m_localScaling); @@ -304,47 +285,45 @@ btCollisionShape* btCollisionWorldImporter::convertCollisionShape( btCollisionS gimpactShape->setMargin(btScalar(gimpactData->m_collisionMargin)); gimpactShape->updateBound(); shape = gimpactShape; - } else + } + else { printf("unsupported gimpact sub type\n"); } break; } -#endif //SUPPORT_GIMPACT_SHAPE_IMPORT - //The btCapsuleShape* API has issue passing the margin/scaling/halfextents unmodified through the API - //so deal with this +#endif //SUPPORT_GIMPACT_SHAPE_IMPORT \ + //The btCapsuleShape* API has issue passing the margin/scaling/halfextents unmodified through the API \ + //so deal with this case CAPSULE_SHAPE_PROXYTYPE: { btCapsuleShapeData* capData = (btCapsuleShapeData*)shapeData; - switch (capData->m_upAxis) { - case 0: + case 0: { - shape = createCapsuleShapeX(1,1); + shape = createCapsuleShapeX(1, 1); break; } - case 1: + case 1: { - shape = createCapsuleShapeY(1,1); + shape = createCapsuleShapeY(1, 1); break; } - case 2: + case 2: { - shape = createCapsuleShapeZ(1,1); + shape = createCapsuleShapeZ(1, 1); break; } - default: + default: { printf("error: wrong up axis for btCapsuleShape\n"); } - - }; if (shape) { - btCapsuleShape* cap = (btCapsuleShape*) shape; + btCapsuleShape* cap = (btCapsuleShape*)shape; cap->deSerializeFloat(capData); } break; @@ -355,163 +334,156 @@ btCollisionShape* btCollisionWorldImporter::convertCollisionShape( btCollisionS case SPHERE_SHAPE_PROXYTYPE: case MULTI_SPHERE_SHAPE_PROXYTYPE: case CONVEX_HULL_SHAPE_PROXYTYPE: + { + btConvexInternalShapeData* bsd = (btConvexInternalShapeData*)shapeData; + btVector3 implicitShapeDimensions; + implicitShapeDimensions.deSerializeFloat(bsd->m_implicitShapeDimensions); + btVector3 localScaling; + localScaling.deSerializeFloat(bsd->m_localScaling); + btVector3 margin(bsd->m_collisionMargin, bsd->m_collisionMargin, bsd->m_collisionMargin); + switch (shapeData->m_shapeType) { - btConvexInternalShapeData* bsd = (btConvexInternalShapeData*)shapeData; - btVector3 implicitShapeDimensions; - implicitShapeDimensions.deSerializeFloat(bsd->m_implicitShapeDimensions); + case BOX_SHAPE_PROXYTYPE: + { + btBoxShape* box = (btBoxShape*)createBoxShape(implicitShapeDimensions / localScaling + margin); + //box->initializePolyhedralFeatures(); + shape = box; + + break; + } + case SPHERE_SHAPE_PROXYTYPE: + { + shape = createSphereShape(implicitShapeDimensions.getX()); + break; + } + + case CYLINDER_SHAPE_PROXYTYPE: + { + btCylinderShapeData* cylData = (btCylinderShapeData*)shapeData; + btVector3 halfExtents = implicitShapeDimensions + margin; + switch (cylData->m_upAxis) + { + case 0: + { + shape = createCylinderShapeX(halfExtents.getY(), halfExtents.getX()); + break; + } + case 1: + { + shape = createCylinderShapeY(halfExtents.getX(), halfExtents.getY()); + break; + } + case 2: + { + shape = createCylinderShapeZ(halfExtents.getX(), halfExtents.getZ()); + break; + } + default: + { + printf("unknown Cylinder up axis\n"); + } + }; + + break; + } + case CONE_SHAPE_PROXYTYPE: + { + btConeShapeData* conData = (btConeShapeData*)shapeData; + btVector3 halfExtents = implicitShapeDimensions; //+margin; + switch (conData->m_upIndex) + { + case 0: + { + shape = createConeShapeX(halfExtents.getY(), halfExtents.getX()); + break; + } + case 1: + { + shape = createConeShapeY(halfExtents.getX(), halfExtents.getY()); + break; + } + case 2: + { + shape = createConeShapeZ(halfExtents.getX(), halfExtents.getZ()); + break; + } + default: + { + printf("unknown Cone up axis\n"); + } + }; + + break; + } + case MULTI_SPHERE_SHAPE_PROXYTYPE: + { + btMultiSphereShapeData* mss = (btMultiSphereShapeData*)bsd; + int numSpheres = mss->m_localPositionArraySize; + + btAlignedObjectArray tmpPos; + btAlignedObjectArray radii; + radii.resize(numSpheres); + tmpPos.resize(numSpheres); + int i; + for (i = 0; i < numSpheres; i++) + { + tmpPos[i].deSerializeFloat(mss->m_localPositionArrayPtr[i].m_pos); + radii[i] = mss->m_localPositionArrayPtr[i].m_radius; + } + shape = createMultiSphereShape(&tmpPos[0], &radii[0], numSpheres); + break; + } + case CONVEX_HULL_SHAPE_PROXYTYPE: + { + // int sz = sizeof(btConvexHullShapeData); + // int sz2 = sizeof(btConvexInternalShapeData); + // int sz3 = sizeof(btCollisionShapeData); + btConvexHullShapeData* convexData = (btConvexHullShapeData*)bsd; + int numPoints = convexData->m_numUnscaledPoints; + + btAlignedObjectArray tmpPoints; + tmpPoints.resize(numPoints); + int i; + for (i = 0; i < numPoints; i++) + { +#ifdef BT_USE_DOUBLE_PRECISION + if (convexData->m_unscaledPointsDoublePtr) + tmpPoints[i].deSerialize(convexData->m_unscaledPointsDoublePtr[i]); + if (convexData->m_unscaledPointsFloatPtr) + tmpPoints[i].deSerializeFloat(convexData->m_unscaledPointsFloatPtr[i]); +#else + if (convexData->m_unscaledPointsFloatPtr) + tmpPoints[i].deSerialize(convexData->m_unscaledPointsFloatPtr[i]); + if (convexData->m_unscaledPointsDoublePtr) + tmpPoints[i].deSerializeDouble(convexData->m_unscaledPointsDoublePtr[i]); +#endif //BT_USE_DOUBLE_PRECISION + } + btConvexHullShape* hullShape = createConvexHullShape(); + for (i = 0; i < numPoints; i++) + { + hullShape->addPoint(tmpPoints[i]); + } + hullShape->setMargin(bsd->m_collisionMargin); + //hullShape->initializePolyhedralFeatures(); + shape = hullShape; + break; + } + default: + { + printf("error: cannot create shape type (%d)\n", shapeData->m_shapeType); + } + } + + if (shape) + { + shape->setMargin(bsd->m_collisionMargin); + btVector3 localScaling; localScaling.deSerializeFloat(bsd->m_localScaling); - btVector3 margin(bsd->m_collisionMargin,bsd->m_collisionMargin,bsd->m_collisionMargin); - switch (shapeData->m_shapeType) - { - case BOX_SHAPE_PROXYTYPE: - { - btBoxShape* box= (btBoxShape*)createBoxShape(implicitShapeDimensions/localScaling+margin); - //box->initializePolyhedralFeatures(); - shape = box; - - break; - } - case SPHERE_SHAPE_PROXYTYPE: - { - shape = createSphereShape(implicitShapeDimensions.getX()); - break; - } - - case CYLINDER_SHAPE_PROXYTYPE: - { - btCylinderShapeData* cylData = (btCylinderShapeData*) shapeData; - btVector3 halfExtents = implicitShapeDimensions+margin; - switch (cylData->m_upAxis) - { - case 0: - { - shape = createCylinderShapeX(halfExtents.getY(),halfExtents.getX()); - break; - } - case 1: - { - shape = createCylinderShapeY(halfExtents.getX(),halfExtents.getY()); - break; - } - case 2: - { - shape = createCylinderShapeZ(halfExtents.getX(),halfExtents.getZ()); - break; - } - default: - { - printf("unknown Cylinder up axis\n"); - } - - }; - - - - break; - } - case CONE_SHAPE_PROXYTYPE: - { - btConeShapeData* conData = (btConeShapeData*) shapeData; - btVector3 halfExtents = implicitShapeDimensions;//+margin; - switch (conData->m_upIndex) - { - case 0: - { - shape = createConeShapeX(halfExtents.getY(),halfExtents.getX()); - break; - } - case 1: - { - shape = createConeShapeY(halfExtents.getX(),halfExtents.getY()); - break; - } - case 2: - { - shape = createConeShapeZ(halfExtents.getX(),halfExtents.getZ()); - break; - } - default: - { - printf("unknown Cone up axis\n"); - } - - }; - - - - break; - } - case MULTI_SPHERE_SHAPE_PROXYTYPE: - { - btMultiSphereShapeData* mss = (btMultiSphereShapeData*)bsd; - int numSpheres = mss->m_localPositionArraySize; - - btAlignedObjectArray tmpPos; - btAlignedObjectArray radii; - radii.resize(numSpheres); - tmpPos.resize(numSpheres); - int i; - for ( i=0;im_localPositionArrayPtr[i].m_pos); - radii[i] = mss->m_localPositionArrayPtr[i].m_radius; - } - shape = createMultiSphereShape(&tmpPos[0],&radii[0],numSpheres); - break; - } - case CONVEX_HULL_SHAPE_PROXYTYPE: - { - // int sz = sizeof(btConvexHullShapeData); - // int sz2 = sizeof(btConvexInternalShapeData); - // int sz3 = sizeof(btCollisionShapeData); - btConvexHullShapeData* convexData = (btConvexHullShapeData*)bsd; - int numPoints = convexData->m_numUnscaledPoints; - - btAlignedObjectArray tmpPoints; - tmpPoints.resize(numPoints); - int i; - for ( i=0;im_unscaledPointsDoublePtr) - tmpPoints[i].deSerialize(convexData->m_unscaledPointsDoublePtr[i]); - if (convexData->m_unscaledPointsFloatPtr) - tmpPoints[i].deSerializeFloat(convexData->m_unscaledPointsFloatPtr[i]); -#else - if (convexData->m_unscaledPointsFloatPtr) - tmpPoints[i].deSerialize(convexData->m_unscaledPointsFloatPtr[i]); - if (convexData->m_unscaledPointsDoublePtr) - tmpPoints[i].deSerializeDouble(convexData->m_unscaledPointsDoublePtr[i]); -#endif //BT_USE_DOUBLE_PRECISION - } - btConvexHullShape* hullShape = createConvexHullShape(); - for (i=0;iaddPoint(tmpPoints[i]); - } - hullShape->setMargin(bsd->m_collisionMargin); - //hullShape->initializePolyhedralFeatures(); - shape = hullShape; - break; - } - default: - { - printf("error: cannot create shape type (%d)\n",shapeData->m_shapeType); - } - } - - if (shape) - { - shape->setMargin(bsd->m_collisionMargin); - - btVector3 localScaling; - localScaling.deSerializeFloat(bsd->m_localScaling); - shape->setLocalScaling(localScaling); - - } - break; + shape->setLocalScaling(localScaling); } + break; + } case TRIANGLE_MESH_SHAPE_PROXYTYPE: { btTriangleMeshShapeData* trimesh = (btTriangleMeshShapeData*)shapeData; @@ -522,10 +494,10 @@ btCollisionShape* btCollisionWorldImporter::convertCollisionShape( btCollisionS return 0; } - btVector3 scaling; scaling.deSerializeFloat(trimesh->m_meshInterface.m_scaling); + btVector3 scaling; + scaling.deSerializeFloat(trimesh->m_meshInterface.m_scaling); meshInterface->setScaling(scaling); - btOptimizedBvh* bvh = 0; #if 1 if (trimesh->m_quantizedFloatBvh) @@ -534,7 +506,8 @@ btCollisionShape* btCollisionWorldImporter::convertCollisionShape( btCollisionS if (bvhPtr && *bvhPtr) { bvh = *bvhPtr; - } else + } + else { bvh = createOptimizedBvh(); bvh->deSerializeFloat(*trimesh->m_quantizedFloatBvh); @@ -546,7 +519,8 @@ btCollisionShape* btCollisionWorldImporter::convertCollisionShape( btCollisionS if (bvhPtr && *bvhPtr) { bvh = *bvhPtr; - } else + } + else { bvh = createOptimizedBvh(); bvh->deSerializeDouble(*trimesh->m_quantizedDoubleBvh); @@ -554,8 +528,7 @@ btCollisionShape* btCollisionWorldImporter::convertCollisionShape( btCollisionS } #endif - - btBvhTriangleMeshShape* trimeshShape = createBvhTriangleMeshShape(meshInterface,bvh); + btBvhTriangleMeshShape* trimeshShape = createBvhTriangleMeshShape(meshInterface, bvh); trimeshShape->setMargin(trimesh->m_collisionMargin); shape = trimeshShape; @@ -567,71 +540,66 @@ btCollisionShape* btCollisionWorldImporter::convertCollisionShape( btCollisionS #ifdef USE_INTERNAL_EDGE_UTILITY gContactAddedCallback = btAdjustInternalEdgeContactsCallback; -#endif //USE_INTERNAL_EDGE_UTILITY - +#endif //USE_INTERNAL_EDGE_UTILITY } //printf("trimesh->m_collisionMargin=%f\n",trimesh->m_collisionMargin); break; } case COMPOUND_SHAPE_PROXYTYPE: + { + btCompoundShapeData* compoundData = (btCompoundShapeData*)shapeData; + btCompoundShape* compoundShape = createCompoundShape(); + + //btCompoundShapeChildData* childShapeDataArray = &compoundData->m_childShapePtr[0]; + + btAlignedObjectArray childShapes; + for (int i = 0; i < compoundData->m_numChildShapes; i++) { - btCompoundShapeData* compoundData = (btCompoundShapeData*)shapeData; - btCompoundShape* compoundShape = createCompoundShape(); + //btCompoundShapeChildData* ptr = &compoundData->m_childShapePtr[i]; - //btCompoundShapeChildData* childShapeDataArray = &compoundData->m_childShapePtr[0]; + btCollisionShapeData* cd = compoundData->m_childShapePtr[i].m_childShape; - - btAlignedObjectArray childShapes; - for (int i=0;im_numChildShapes;i++) + btCollisionShape* childShape = convertCollisionShape(cd); + if (childShape) { - //btCompoundShapeChildData* ptr = &compoundData->m_childShapePtr[i]; - - btCollisionShapeData* cd = compoundData->m_childShapePtr[i].m_childShape; - - btCollisionShape* childShape = convertCollisionShape(cd); - if (childShape) - { - btTransform localTransform; - localTransform.deSerializeFloat(compoundData->m_childShapePtr[i].m_transform); - compoundShape->addChildShape(localTransform,childShape); - } else - { -#ifdef _DEBUG - printf("error: couldn't create childShape for compoundShape\n"); -#endif - } - + btTransform localTransform; + localTransform.deSerializeFloat(compoundData->m_childShapePtr[i].m_transform); + compoundShape->addChildShape(localTransform, childShape); } - shape = compoundShape; - - break; - } - case SOFTBODY_SHAPE_PROXYTYPE: - { - return 0; - } - default: - { + else + { #ifdef _DEBUG - printf("unsupported shape type (%d)\n",shapeData->m_shapeType); + printf("error: couldn't create childShape for compoundShape\n"); #endif + } } + shape = compoundShape; + + break; } + case SOFTBODY_SHAPE_PROXYTYPE: + { + return 0; + } + default: + { +#ifdef _DEBUG + printf("unsupported shape type (%d)\n", shapeData->m_shapeType); +#endif + } + } - return shape; - + return shape; } - - char* btCollisionWorldImporter::duplicateName(const char* name) { if (name) { int l = (int)strlen(name); - char* newName = new char[l+1]; - memcpy(newName,name,l); + char* newName = new char[l + 1]; + memcpy(newName, name, l); newName[l] = 0; m_allocatedNames.push_back(newName); return newName; @@ -639,53 +607,43 @@ char* btCollisionWorldImporter::duplicateName(const char* name) return 0; } - - - - - - - - - - -btTriangleIndexVertexArray* btCollisionWorldImporter::createMeshInterface(btStridingMeshInterfaceData& meshData) +btTriangleIndexVertexArray* btCollisionWorldImporter::createMeshInterface(btStridingMeshInterfaceData& meshData) { btTriangleIndexVertexArray* meshInterface = createTriangleMeshContainer(); - for (int i=0;iaddIndexedMesh(meshPart,meshPart.m_indexType); + meshInterface->addIndexedMesh(meshPart, meshPart.m_indexType); } } return meshInterface; } - btStridingMeshInterfaceData* btCollisionWorldImporter::createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData) { //create a new btStridingMeshInterfaceData that is an exact copy of shapedata and store it in the WorldImporter @@ -776,7 +733,7 @@ btStridingMeshInterfaceData* btCollisionWorldImporter::createStridingMeshInterfa newData->m_numMeshParts = interfaceData->m_numMeshParts; newData->m_meshPartsPtr = new btMeshPartData[newData->m_numMeshParts]; - for(int i = 0;i < newData->m_numMeshParts;i++) + for (int i = 0; i < newData->m_numMeshParts; i++) { btMeshPartData* curPart = &interfaceData->m_meshPartsPtr[i]; btMeshPartData* curNewPart = &newData->m_meshPartsPtr[i]; @@ -784,18 +741,18 @@ btStridingMeshInterfaceData* btCollisionWorldImporter::createStridingMeshInterfa curNewPart->m_numTriangles = curPart->m_numTriangles; curNewPart->m_numVertices = curPart->m_numVertices; - if(curPart->m_vertices3f) + if (curPart->m_vertices3f) { curNewPart->m_vertices3f = new btVector3FloatData[curNewPart->m_numVertices]; - memcpy(curNewPart->m_vertices3f,curPart->m_vertices3f,sizeof(btVector3FloatData) * curNewPart->m_numVertices); + memcpy(curNewPart->m_vertices3f, curPart->m_vertices3f, sizeof(btVector3FloatData) * curNewPart->m_numVertices); } else curNewPart->m_vertices3f = NULL; - if(curPart->m_vertices3d) + if (curPart->m_vertices3d) { curNewPart->m_vertices3d = new btVector3DoubleData[curNewPart->m_numVertices]; - memcpy(curNewPart->m_vertices3d,curPart->m_vertices3d,sizeof(btVector3DoubleData) * curNewPart->m_numVertices); + memcpy(curNewPart->m_vertices3d, curPart->m_vertices3d, sizeof(btVector3DoubleData) * curNewPart->m_numVertices); } else curNewPart->m_vertices3d = NULL; @@ -803,63 +760,60 @@ btStridingMeshInterfaceData* btCollisionWorldImporter::createStridingMeshInterfa int numIndices = curNewPart->m_numTriangles * 3; ///the m_3indices8 was not initialized in some Bullet versions, this can cause crashes at loading time ///we catch it by only dealing with m_3indices8 if none of the other indices are initialized - bool uninitialized3indices8Workaround =false; + bool uninitialized3indices8Workaround = false; - if(curPart->m_indices32) + if (curPart->m_indices32) { - uninitialized3indices8Workaround=true; + uninitialized3indices8Workaround = true; curNewPart->m_indices32 = new btIntIndexData[numIndices]; - memcpy(curNewPart->m_indices32,curPart->m_indices32,sizeof(btIntIndexData) * numIndices); + memcpy(curNewPart->m_indices32, curPart->m_indices32, sizeof(btIntIndexData) * numIndices); } else curNewPart->m_indices32 = NULL; - if(curPart->m_3indices16) + if (curPart->m_3indices16) { - uninitialized3indices8Workaround=true; + uninitialized3indices8Workaround = true; curNewPart->m_3indices16 = new btShortIntIndexTripletData[curNewPart->m_numTriangles]; - memcpy(curNewPart->m_3indices16,curPart->m_3indices16,sizeof(btShortIntIndexTripletData) * curNewPart->m_numTriangles); + memcpy(curNewPart->m_3indices16, curPart->m_3indices16, sizeof(btShortIntIndexTripletData) * curNewPart->m_numTriangles); } else curNewPart->m_3indices16 = NULL; - if(curPart->m_indices16) + if (curPart->m_indices16) { - uninitialized3indices8Workaround=true; + uninitialized3indices8Workaround = true; curNewPart->m_indices16 = new btShortIntIndexData[numIndices]; - memcpy(curNewPart->m_indices16,curPart->m_indices16,sizeof(btShortIntIndexData) * numIndices); + memcpy(curNewPart->m_indices16, curPart->m_indices16, sizeof(btShortIntIndexData) * numIndices); } else curNewPart->m_indices16 = NULL; - if(!uninitialized3indices8Workaround && curPart->m_3indices8) + if (!uninitialized3indices8Workaround && curPart->m_3indices8) { curNewPart->m_3indices8 = new btCharIndexTripletData[curNewPart->m_numTriangles]; - memcpy(curNewPart->m_3indices8,curPart->m_3indices8,sizeof(btCharIndexTripletData) * curNewPart->m_numTriangles); + memcpy(curNewPart->m_3indices8, curPart->m_3indices8, sizeof(btCharIndexTripletData) * curNewPart->m_numTriangles); } else curNewPart->m_3indices8 = NULL; - } m_allocatedbtStridingMeshInterfaceDatas.push_back(newData); - return(newData); + return (newData); } #ifdef USE_INTERNAL_EDGE_UTILITY -extern ContactAddedCallback gContactAddedCallback; +extern ContactAddedCallback gContactAddedCallback; -static bool btAdjustInternalEdgeContactsCallback(btManifoldPoint& cp, const btCollisionObject* colObj0,int partId0,int index0,const btCollisionObject* colObj1,int partId1,int index1) +static bool btAdjustInternalEdgeContactsCallback(btManifoldPoint& cp, const btCollisionObject* colObj0, int partId0, int index0, const btCollisionObject* colObj1, int partId1, int index1) { - - btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1); - //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_BACKFACE_MODE); - //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_DOUBLE_SIDED+BT_TRIANGLE_CONCAVE_DOUBLE_SIDED); + btAdjustInternalEdgeContacts(cp, colObj1, colObj0, partId1, index1); + //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_BACKFACE_MODE); + //btAdjustInternalEdgeContacts(cp,colObj1,colObj0, partId1,index1, BT_TRIANGLE_CONVEX_DOUBLE_SIDED+BT_TRIANGLE_CONCAVE_DOUBLE_SIDED); return true; } -#endif //USE_INTERNAL_EDGE_UTILITY - +#endif //USE_INTERNAL_EDGE_UTILITY /* btRigidBody* btWorldImporter::createRigidBody(bool isDynamic, btScalar mass, const btTransform& startTransform,btCollisionShape* shape,const char* bodyName) @@ -898,29 +852,27 @@ btCollisionObject* btCollisionWorldImporter::getCollisionObjectByName(const char return 0; } -btCollisionObject* btCollisionWorldImporter::createCollisionObject(const btTransform& startTransform,btCollisionShape* shape, const char* bodyName) +btCollisionObject* btCollisionWorldImporter::createCollisionObject(const btTransform& startTransform, btCollisionShape* shape, const char* bodyName) { btCollisionObject* colObj = new btCollisionObject(); colObj->setWorldTransform(startTransform); colObj->setCollisionShape(shape); - m_collisionWorld->addCollisionObject(colObj);//todo: flags etc + m_collisionWorld->addCollisionObject(colObj); //todo: flags etc if (bodyName) { char* newname = duplicateName(bodyName); - m_objectNameMap.insert(colObj,newname); - m_nameColObjMap.insert(newname,colObj); + m_objectNameMap.insert(colObj, newname); + m_nameColObjMap.insert(newname, colObj); } m_allocatedCollisionObjects.push_back(colObj); return colObj; } - - -btCollisionShape* btCollisionWorldImporter::createPlaneShape(const btVector3& planeNormal,btScalar planeConstant) +btCollisionShape* btCollisionWorldImporter::createPlaneShape(const btVector3& planeNormal, btScalar planeConstant) { - btStaticPlaneShape* shape = new btStaticPlaneShape(planeNormal,planeConstant); + btStaticPlaneShape* shape = new btStaticPlaneShape(planeNormal, planeConstant); m_allocatedCollisionShapes.push_back(shape); return shape; } @@ -937,85 +889,83 @@ btCollisionShape* btCollisionWorldImporter::createSphereShape(btScalar radius) return shape; } - btCollisionShape* btCollisionWorldImporter::createCapsuleShapeX(btScalar radius, btScalar height) { - btCapsuleShapeX* shape = new btCapsuleShapeX(radius,height); + btCapsuleShapeX* shape = new btCapsuleShapeX(radius, height); m_allocatedCollisionShapes.push_back(shape); return shape; } btCollisionShape* btCollisionWorldImporter::createCapsuleShapeY(btScalar radius, btScalar height) { - btCapsuleShape* shape = new btCapsuleShape(radius,height); + btCapsuleShape* shape = new btCapsuleShape(radius, height); m_allocatedCollisionShapes.push_back(shape); return shape; } btCollisionShape* btCollisionWorldImporter::createCapsuleShapeZ(btScalar radius, btScalar height) { - btCapsuleShapeZ* shape = new btCapsuleShapeZ(radius,height); + btCapsuleShapeZ* shape = new btCapsuleShapeZ(radius, height); m_allocatedCollisionShapes.push_back(shape); return shape; } -btCollisionShape* btCollisionWorldImporter::createCylinderShapeX(btScalar radius,btScalar height) +btCollisionShape* btCollisionWorldImporter::createCylinderShapeX(btScalar radius, btScalar height) { - btCylinderShapeX* shape = new btCylinderShapeX(btVector3(height,radius,radius)); + btCylinderShapeX* shape = new btCylinderShapeX(btVector3(height, radius, radius)); m_allocatedCollisionShapes.push_back(shape); return shape; } -btCollisionShape* btCollisionWorldImporter::createCylinderShapeY(btScalar radius,btScalar height) +btCollisionShape* btCollisionWorldImporter::createCylinderShapeY(btScalar radius, btScalar height) { - btCylinderShape* shape = new btCylinderShape(btVector3(radius,height,radius)); + btCylinderShape* shape = new btCylinderShape(btVector3(radius, height, radius)); m_allocatedCollisionShapes.push_back(shape); return shape; } -btCollisionShape* btCollisionWorldImporter::createCylinderShapeZ(btScalar radius,btScalar height) +btCollisionShape* btCollisionWorldImporter::createCylinderShapeZ(btScalar radius, btScalar height) { - btCylinderShapeZ* shape = new btCylinderShapeZ(btVector3(radius,radius,height)); + btCylinderShapeZ* shape = new btCylinderShapeZ(btVector3(radius, radius, height)); m_allocatedCollisionShapes.push_back(shape); return shape; } -btCollisionShape* btCollisionWorldImporter::createConeShapeX(btScalar radius,btScalar height) +btCollisionShape* btCollisionWorldImporter::createConeShapeX(btScalar radius, btScalar height) { - btConeShapeX* shape = new btConeShapeX(radius,height); + btConeShapeX* shape = new btConeShapeX(radius, height); m_allocatedCollisionShapes.push_back(shape); return shape; } -btCollisionShape* btCollisionWorldImporter::createConeShapeY(btScalar radius,btScalar height) +btCollisionShape* btCollisionWorldImporter::createConeShapeY(btScalar radius, btScalar height) { - btConeShape* shape = new btConeShape(radius,height); + btConeShape* shape = new btConeShape(radius, height); m_allocatedCollisionShapes.push_back(shape); return shape; } -btCollisionShape* btCollisionWorldImporter::createConeShapeZ(btScalar radius,btScalar height) +btCollisionShape* btCollisionWorldImporter::createConeShapeZ(btScalar radius, btScalar height) { - btConeShapeZ* shape = new btConeShapeZ(radius,height); + btConeShapeZ* shape = new btConeShapeZ(radius, height); m_allocatedCollisionShapes.push_back(shape); return shape; } -btTriangleIndexVertexArray* btCollisionWorldImporter::createTriangleMeshContainer() +btTriangleIndexVertexArray* btCollisionWorldImporter::createTriangleMeshContainer() { btTriangleIndexVertexArray* in = new btTriangleIndexVertexArray(); m_allocatedTriangleIndexArrays.push_back(in); return in; } -btOptimizedBvh* btCollisionWorldImporter::createOptimizedBvh() +btOptimizedBvh* btCollisionWorldImporter::createOptimizedBvh() { btOptimizedBvh* bvh = new btOptimizedBvh(); m_allocatedBvhs.push_back(bvh); return bvh; } - btTriangleInfoMap* btCollisionWorldImporter::createTriangleInfoMap() { btTriangleInfoMap* tim = new btTriangleInfoMap(); @@ -1027,16 +977,15 @@ btBvhTriangleMeshShape* btCollisionWorldImporter::createBvhTriangleMeshShape(btS { if (bvh) { - btBvhTriangleMeshShape* bvhTriMesh = new btBvhTriangleMeshShape(trimesh,bvh->isQuantized(), false); + btBvhTriangleMeshShape* bvhTriMesh = new btBvhTriangleMeshShape(trimesh, bvh->isQuantized(), false); bvhTriMesh->setOptimizedBvh(bvh); m_allocatedCollisionShapes.push_back(bvhTriMesh); return bvhTriMesh; } - btBvhTriangleMeshShape* ts = new btBvhTriangleMeshShape(trimesh,true); + btBvhTriangleMeshShape* ts = new btBvhTriangleMeshShape(trimesh, true); m_allocatedCollisionShapes.push_back(ts); return ts; - } btCollisionShape* btCollisionWorldImporter::createConvexTriangleMeshShape(btStridingMeshInterface* trimesh) { @@ -1048,9 +997,8 @@ btGImpactMeshShape* btCollisionWorldImporter::createGimpactShape(btStridingMeshI btGImpactMeshShape* shape = new btGImpactMeshShape(trimesh); m_allocatedCollisionShapes.push_back(shape); return shape; - } -#endif //SUPPORT_GIMPACT_SHAPE_IMPORT +#endif //SUPPORT_GIMPACT_SHAPE_IMPORT btConvexHullShape* btCollisionWorldImporter::createConvexHullShape() { @@ -1066,25 +1014,22 @@ btCompoundShape* btCollisionWorldImporter::createCompoundShape() return shape; } - -btScaledBvhTriangleMeshShape* btCollisionWorldImporter::createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape,const btVector3& localScaling) +btScaledBvhTriangleMeshShape* btCollisionWorldImporter::createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape, const btVector3& localScaling) { - btScaledBvhTriangleMeshShape* shape = new btScaledBvhTriangleMeshShape(meshShape,localScaling); + btScaledBvhTriangleMeshShape* shape = new btScaledBvhTriangleMeshShape(meshShape, localScaling); m_allocatedCollisionShapes.push_back(shape); return shape; } -btMultiSphereShape* btCollisionWorldImporter::createMultiSphereShape(const btVector3* positions,const btScalar* radi,int numSpheres) +btMultiSphereShape* btCollisionWorldImporter::createMultiSphereShape(const btVector3* positions, const btScalar* radi, int numSpheres) { btMultiSphereShape* shape = new btMultiSphereShape(positions, radi, numSpheres); m_allocatedCollisionShapes.push_back(shape); return shape; } - - - // query for data -int btCollisionWorldImporter::getNumCollisionShapes() const +// query for data +int btCollisionWorldImporter::getNumCollisionShapes() const { return m_allocatedCollisionShapes.size(); } @@ -1097,23 +1042,21 @@ btCollisionShape* btCollisionWorldImporter::getCollisionShapeByIndex(int index) btCollisionShape* btCollisionWorldImporter::getCollisionShapeByName(const char* name) { btCollisionShape** shapePtr = m_nameShapeMap.find(name); - if (shapePtr&& *shapePtr) + if (shapePtr && *shapePtr) { return *shapePtr; } return 0; } - -const char* btCollisionWorldImporter::getNameForPointer(const void* ptr) const +const char* btCollisionWorldImporter::getNameForPointer(const void* ptr) const { - const char*const * namePtr = m_objectNameMap.find(ptr); + const char* const* namePtr = m_objectNameMap.find(ptr); if (namePtr && *namePtr) return *namePtr; return 0; } - int btCollisionWorldImporter::getNumRigidBodies() const { return m_allocatedRigidBodies.size(); @@ -1124,12 +1067,11 @@ btCollisionObject* btCollisionWorldImporter::getRigidBodyByIndex(int index) cons return m_allocatedRigidBodies[index]; } - int btCollisionWorldImporter::getNumBvhs() const { return m_allocatedBvhs.size(); } - btOptimizedBvh* btCollisionWorldImporter::getBvhByIndex(int index) const +btOptimizedBvh* btCollisionWorldImporter::getBvhByIndex(int index) const { return m_allocatedBvhs[index]; } @@ -1143,5 +1085,3 @@ btTriangleInfoMap* btCollisionWorldImporter::getTriangleInfoMapByIndex(int index { return m_allocatedTriangleInfoMaps[index]; } - - diff --git a/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.h b/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.h index 81c614272..5e8bc9534 100644 --- a/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.h +++ b/src/BulletCollision/CollisionDispatch/btCollisionWorldImporter.h @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef BT_COLLISION_WORLD_IMPORTER_H #define BT_COLLISION_WORLD_IMPORTER_H @@ -26,7 +25,6 @@ class btCollisionShape; class btCollisionObject; struct btBulletSerializedArrays; - struct ConstraintInput; class btCollisionWorld; struct btCollisionShapeData; @@ -46,9 +44,6 @@ class btSliderConstraint; class btGearConstraint; struct btContactSolverInfo; - - - class btCollisionWorldImporter { protected: @@ -56,60 +51,53 @@ protected: int m_verboseMode; - btAlignedObjectArray m_allocatedCollisionShapes; + btAlignedObjectArray m_allocatedCollisionShapes; btAlignedObjectArray m_allocatedRigidBodies; - btAlignedObjectArray m_allocatedBvhs; + btAlignedObjectArray m_allocatedBvhs; btAlignedObjectArray m_allocatedTriangleInfoMaps; btAlignedObjectArray m_allocatedTriangleIndexArrays; btAlignedObjectArray m_allocatedbtStridingMeshInterfaceDatas; btAlignedObjectArray m_allocatedCollisionObjects; + btAlignedObjectArray m_allocatedNames; - btAlignedObjectArray m_allocatedNames; + btAlignedObjectArray m_indexArrays; + btAlignedObjectArray m_shortIndexArrays; + btAlignedObjectArray m_charIndexArrays; - btAlignedObjectArray m_indexArrays; - btAlignedObjectArray m_shortIndexArrays; - btAlignedObjectArray m_charIndexArrays; + btAlignedObjectArray m_floatVertexArrays; + btAlignedObjectArray m_doubleVertexArrays; - btAlignedObjectArray m_floatVertexArrays; - btAlignedObjectArray m_doubleVertexArrays; + btHashMap m_bvhMap; + btHashMap m_timMap; + btHashMap m_nameShapeMap; + btHashMap m_nameColObjMap; - btHashMap m_bvhMap; - btHashMap m_timMap; - - btHashMap m_nameShapeMap; - btHashMap m_nameColObjMap; - - btHashMap m_objectNameMap; - - btHashMap m_shapeMap; - btHashMap m_bodyMap; + btHashMap m_objectNameMap; + btHashMap m_shapeMap; + btHashMap m_bodyMap; //methods + char* duplicateName(const char* name); - - char* duplicateName(const char* name); - - btCollisionShape* convertCollisionShape( btCollisionShapeData* shapeData ); - + btCollisionShape* convertCollisionShape(btCollisionShapeData* shapeData); public: - btCollisionWorldImporter(btCollisionWorld* world); virtual ~btCollisionWorldImporter(); - bool convertAllObjects( btBulletSerializedArrays* arrays); + bool convertAllObjects(btBulletSerializedArrays* arrays); - ///delete all memory collision shapes, rigid bodies, constraints etc. allocated during the load. + ///delete all memory collision shapes, rigid bodies, constraints etc. allocated during the load. ///make sure you don't use the dynamics world containing objects after you call this method virtual void deleteAllData(); - void setVerboseMode(int verboseMode) + void setVerboseMode(int verboseMode) { m_verboseMode = verboseMode; } @@ -119,14 +107,14 @@ public: return m_verboseMode; } - // query for data - int getNumCollisionShapes() const; + // query for data + int getNumCollisionShapes() const; btCollisionShape* getCollisionShapeByIndex(int index); int getNumRigidBodies() const; btCollisionObject* getRigidBodyByIndex(int index) const; int getNumBvhs() const; - btOptimizedBvh* getBvhByIndex(int index) const; + btOptimizedBvh* getBvhByIndex(int index) const; int getNumTriangleInfoMaps() const; btTriangleInfoMap* getTriangleInfoMapByIndex(int index) const; @@ -134,56 +122,48 @@ public: btCollisionShape* getCollisionShapeByName(const char* name); btCollisionObject* getCollisionObjectByName(const char* name); - - const char* getNameForPointer(const void* ptr) const; + const char* getNameForPointer(const void* ptr) const; ///those virtuals are called by load and can be overridden by the user - - //bodies - virtual btCollisionObject* createCollisionObject( const btTransform& startTransform, btCollisionShape* shape,const char* bodyName); + virtual btCollisionObject* createCollisionObject(const btTransform& startTransform, btCollisionShape* shape, const char* bodyName); ///shapes - virtual btCollisionShape* createPlaneShape(const btVector3& planeNormal,btScalar planeConstant); + virtual btCollisionShape* createPlaneShape(const btVector3& planeNormal, btScalar planeConstant); virtual btCollisionShape* createBoxShape(const btVector3& halfExtents); virtual btCollisionShape* createSphereShape(btScalar radius); virtual btCollisionShape* createCapsuleShapeX(btScalar radius, btScalar height); virtual btCollisionShape* createCapsuleShapeY(btScalar radius, btScalar height); virtual btCollisionShape* createCapsuleShapeZ(btScalar radius, btScalar height); - virtual btCollisionShape* createCylinderShapeX(btScalar radius,btScalar height); - virtual btCollisionShape* createCylinderShapeY(btScalar radius,btScalar height); - virtual btCollisionShape* createCylinderShapeZ(btScalar radius,btScalar height); - virtual btCollisionShape* createConeShapeX(btScalar radius,btScalar height); - virtual btCollisionShape* createConeShapeY(btScalar radius,btScalar height); - virtual btCollisionShape* createConeShapeZ(btScalar radius,btScalar height); - virtual class btTriangleIndexVertexArray* createTriangleMeshContainer(); - virtual btBvhTriangleMeshShape* createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh); + virtual btCollisionShape* createCylinderShapeX(btScalar radius, btScalar height); + virtual btCollisionShape* createCylinderShapeY(btScalar radius, btScalar height); + virtual btCollisionShape* createCylinderShapeZ(btScalar radius, btScalar height); + virtual btCollisionShape* createConeShapeX(btScalar radius, btScalar height); + virtual btCollisionShape* createConeShapeY(btScalar radius, btScalar height); + virtual btCollisionShape* createConeShapeZ(btScalar radius, btScalar height); + virtual class btTriangleIndexVertexArray* createTriangleMeshContainer(); + virtual btBvhTriangleMeshShape* createBvhTriangleMeshShape(btStridingMeshInterface* trimesh, btOptimizedBvh* bvh); virtual btCollisionShape* createConvexTriangleMeshShape(btStridingMeshInterface* trimesh); #ifdef SUPPORT_GIMPACT_SHAPE_IMPORT virtual btGImpactMeshShape* createGimpactShape(btStridingMeshInterface* trimesh); -#endif //SUPPORT_GIMPACT_SHAPE_IMPORT +#endif //SUPPORT_GIMPACT_SHAPE_IMPORT virtual btStridingMeshInterfaceData* createStridingMeshInterfaceData(btStridingMeshInterfaceData* interfaceData); virtual class btConvexHullShape* createConvexHullShape(); virtual class btCompoundShape* createCompoundShape(); - virtual class btScaledBvhTriangleMeshShape* createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape,const btVector3& localScalingbtBvhTriangleMeshShape); + virtual class btScaledBvhTriangleMeshShape* createScaledTrangleMeshShape(btBvhTriangleMeshShape* meshShape, const btVector3& localScalingbtBvhTriangleMeshShape); - virtual class btMultiSphereShape* createMultiSphereShape(const btVector3* positions,const btScalar* radi,int numSpheres); + virtual class btMultiSphereShape* createMultiSphereShape(const btVector3* positions, const btScalar* radi, int numSpheres); virtual btTriangleIndexVertexArray* createMeshInterface(btStridingMeshInterfaceData& meshData); ///acceleration and connectivity structures - virtual btOptimizedBvh* createOptimizedBvh(); + virtual btOptimizedBvh* createOptimizedBvh(); virtual btTriangleInfoMap* createTriangleInfoMap(); - - - - }; - -#endif //BT_WORLD_IMPORTER_H +#endif //BT_WORLD_IMPORTER_H diff --git a/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp index 91b7809c1..e3dda5bfa 100644 --- a/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp +++ b/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.cpp @@ -25,62 +25,58 @@ subject to the following restrictions: btShapePairCallback gCompoundChildShapePairCallback = 0; -btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped) -:btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap), -m_isSwapped(isSwapped), -m_sharedManifold(ci.m_manifold) +btCompoundCollisionAlgorithm::btCompoundCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, bool isSwapped) + : btActivatingCollisionAlgorithm(ci, body0Wrap, body1Wrap), + m_isSwapped(isSwapped), + m_sharedManifold(ci.m_manifold) { m_ownsManifold = false; - const btCollisionObjectWrapper* colObjWrap = m_isSwapped? body1Wrap : body0Wrap; - btAssert (colObjWrap->getCollisionShape()->isCompound()); - + const btCollisionObjectWrapper* colObjWrap = m_isSwapped ? body1Wrap : body0Wrap; + btAssert(colObjWrap->getCollisionShape()->isCompound()); + const btCompoundShape* compoundShape = static_cast(colObjWrap->getCollisionShape()); m_compoundShapeRevision = compoundShape->getUpdateRevision(); - - - preallocateChildAlgorithms(body0Wrap,body1Wrap); + + preallocateChildAlgorithms(body0Wrap, body1Wrap); } -void btCompoundCollisionAlgorithm::preallocateChildAlgorithms(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) +void btCompoundCollisionAlgorithm::preallocateChildAlgorithms(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { - const btCollisionObjectWrapper* colObjWrap = m_isSwapped? body1Wrap : body0Wrap; - const btCollisionObjectWrapper* otherObjWrap = m_isSwapped? body0Wrap : body1Wrap; - btAssert (colObjWrap->getCollisionShape()->isCompound()); - + const btCollisionObjectWrapper* colObjWrap = m_isSwapped ? body1Wrap : body0Wrap; + const btCollisionObjectWrapper* otherObjWrap = m_isSwapped ? body0Wrap : body1Wrap; + btAssert(colObjWrap->getCollisionShape()->isCompound()); + const btCompoundShape* compoundShape = static_cast(colObjWrap->getCollisionShape()); int numChildren = compoundShape->getNumChildShapes(); int i; - + m_childCollisionAlgorithms.resize(numChildren); - for (i=0;igetDynamicAabbTree()) { m_childCollisionAlgorithms[i] = 0; - } else + } + else { - const btCollisionShape* childShape = compoundShape->getChildShape(i); - btCollisionObjectWrapper childWrap(colObjWrap,childShape,colObjWrap->getCollisionObject(),colObjWrap->getWorldTransform(),-1,i);//wrong child trans, but unused (hopefully) - m_childCollisionAlgorithms[i] = m_dispatcher->findAlgorithm(&childWrap,otherObjWrap,m_sharedManifold, BT_CONTACT_POINT_ALGORITHMS); - + btCollisionObjectWrapper childWrap(colObjWrap, childShape, colObjWrap->getCollisionObject(), colObjWrap->getWorldTransform(), -1, i); //wrong child trans, but unused (hopefully) + m_childCollisionAlgorithms[i] = m_dispatcher->findAlgorithm(&childWrap, otherObjWrap, m_sharedManifold, BT_CONTACT_POINT_ALGORITHMS); btAlignedObjectArray m_childCollisionAlgorithmsContact; btAlignedObjectArray m_childCollisionAlgorithmsClosestPoints; - - } } } -void btCompoundCollisionAlgorithm::removeChildAlgorithms() +void btCompoundCollisionAlgorithm::removeChildAlgorithms() { int numChildren = m_childCollisionAlgorithms.size(); int i; - for (i=0;i=0); + btAssert(index >= 0); const btCompoundShape* compoundShape = static_cast(m_compoundColObjWrap->getCollisionShape()); - btAssert(indexgetNumChildShapes()); - + btAssert(index < compoundShape->getNumChildShapes()); //backup - btTransform orgTrans = m_compoundColObjWrap->getWorldTransform(); - + btTransform orgTrans = m_compoundColObjWrap->getWorldTransform(); + const btTransform& childTrans = compoundShape->getChildTransform(index); - btTransform newChildWorldTrans = orgTrans*childTrans ; + btTransform newChildWorldTrans = orgTrans * childTrans; //perform an AABB check first - btVector3 aabbMin0,aabbMax0; - childShape->getAabb(newChildWorldTrans,aabbMin0,aabbMax0); + btVector3 aabbMin0, aabbMax0; + childShape->getAabb(newChildWorldTrans, aabbMin0, aabbMax0); btVector3 extendAabb(m_resultOut->m_closestPointDistanceThreshold, m_resultOut->m_closestPointDistanceThreshold, m_resultOut->m_closestPointDistanceThreshold); aabbMin0 -= extendAabb; aabbMax0 += extendAabb; btVector3 aabbMin1, aabbMax1; - m_otherObjWrap->getCollisionShape()->getAabb(m_otherObjWrap->getWorldTransform(),aabbMin1,aabbMax1); + m_otherObjWrap->getCollisionShape()->getAabb(m_otherObjWrap->getWorldTransform(), aabbMin1, aabbMax1); if (gCompoundChildShapePairCallback) { @@ -150,11 +136,10 @@ public: return; } - if (TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1)) + if (TestAabbAgainstAabb2(aabbMin0, aabbMax0, aabbMin1, aabbMax1)) { + btCollisionObjectWrapper compoundWrap(this->m_compoundColObjWrap, childShape, m_compoundColObjWrap->getCollisionObject(), newChildWorldTrans, -1, index); - btCollisionObjectWrapper compoundWrap(this->m_compoundColObjWrap,childShape,m_compoundColObjWrap->getCollisionObject(),newChildWorldTrans,-1,index); - btCollisionAlgorithm* algo = 0; bool allocatedAlgorithm = false; @@ -172,7 +157,7 @@ public: } algo = m_childCollisionAlgorithms[index]; } - + const btCollisionObjectWrapper* tmpWrap = 0; ///detect swapping case @@ -180,15 +165,16 @@ public: { tmpWrap = m_resultOut->getBody0Wrap(); m_resultOut->setBody0Wrap(&compoundWrap); - m_resultOut->setShapeIdentifiersA(-1,index); - } else + m_resultOut->setShapeIdentifiersA(-1, index); + } + else { tmpWrap = m_resultOut->getBody1Wrap(); m_resultOut->setBody1Wrap(&compoundWrap); - m_resultOut->setShapeIdentifiersB(-1,index); + m_resultOut->setShapeIdentifiersB(-1, index); } - algo->processCollision(&compoundWrap,m_otherObjWrap,m_dispatchInfo,m_resultOut); + algo->processCollision(&compoundWrap, m_otherObjWrap, m_dispatchInfo, m_resultOut); #if 0 if (m_dispatchInfo.m_debugDraw && (m_dispatchInfo.m_debugDraw->getDebugMode() & btIDebugDraw::DBG_DrawAabb)) @@ -202,18 +188,19 @@ public: if (m_resultOut->getBody0Internal() == m_compoundColObjWrap->getCollisionObject()) { m_resultOut->setBody0Wrap(tmpWrap); - } else + } + else { m_resultOut->setBody1Wrap(tmpWrap); } - if(allocatedAlgorithm) + if (allocatedAlgorithm) { algo->~btCollisionAlgorithm(); m_dispatcher->freeCollisionAlgorithm(algo); - } + } } } - void Process(const btDbvtNode* leaf) + void Process(const btDbvtNode* leaf) { int index = leaf->dataAsInt; @@ -230,22 +217,16 @@ public: } #endif - ProcessChildShape(childShape,index); - + ProcessChildShape(childShape, index); } }; - - - - - -void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +void btCompoundCollisionAlgorithm::processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { - const btCollisionObjectWrapper* colObjWrap = m_isSwapped? body1Wrap : body0Wrap; - const btCollisionObjectWrapper* otherObjWrap = m_isSwapped? body0Wrap : body1Wrap; + const btCollisionObjectWrapper* colObjWrap = m_isSwapped ? body1Wrap : body0Wrap; + const btCollisionObjectWrapper* otherObjWrap = m_isSwapped ? body0Wrap : body1Wrap; - btAssert (colObjWrap->getCollisionShape()->isCompound()); + btAssert(colObjWrap->getCollisionShape()->isCompound()); const btCompoundShape* compoundShape = static_cast(colObjWrap->getCollisionShape()); ///btCompoundShape might have changed: @@ -254,17 +235,17 @@ void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrap { ///clear and update all removeChildAlgorithms(); - - preallocateChildAlgorithms(body0Wrap,body1Wrap); + + preallocateChildAlgorithms(body0Wrap, body1Wrap); m_compoundShapeRevision = compoundShape->getUpdateRevision(); } - if (m_childCollisionAlgorithms.size()==0) + if (m_childCollisionAlgorithms.size() == 0) return; const btDbvt* tree = compoundShape->getDynamicAabbTree(); //use a dynamic aabb tree to cull potential child-overlaps - btCompoundLeafCallback callback(colObjWrap,otherObjWrap,m_dispatcher,dispatchInfo,resultOut,&m_childCollisionAlgorithms[0],m_sharedManifold); + btCompoundLeafCallback callback(colObjWrap, otherObjWrap, m_dispatcher, dispatchInfo, resultOut, &m_childCollisionAlgorithms[0], m_sharedManifold); ///we need to refresh all contact manifolds ///note that we should actually recursively traverse all children, btCompoundShape can nested more then 1 level deep @@ -272,18 +253,18 @@ void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrap { int i; manifoldArray.resize(0); - for (i=0;igetAllContactManifolds(manifoldArray); - for (int m=0;mgetNumContacts()) { resultOut->setPersistentManifold(manifoldArray[m]); resultOut->refreshContactPoints(); - resultOut->setPersistentManifold(0);//??necessary? + resultOut->setPersistentManifold(0); //??necessary? } } manifoldArray.resize(0); @@ -293,57 +274,56 @@ void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrap if (tree) { - - btVector3 localAabbMin,localAabbMax; + btVector3 localAabbMin, localAabbMax; btTransform otherInCompoundSpace; otherInCompoundSpace = colObjWrap->getWorldTransform().inverse() * otherObjWrap->getWorldTransform(); - otherObjWrap->getCollisionShape()->getAabb(otherInCompoundSpace,localAabbMin,localAabbMax); + otherObjWrap->getCollisionShape()->getAabb(otherInCompoundSpace, localAabbMin, localAabbMax); btVector3 extraExtends(resultOut->m_closestPointDistanceThreshold, resultOut->m_closestPointDistanceThreshold, resultOut->m_closestPointDistanceThreshold); localAabbMin -= extraExtends; localAabbMax += extraExtends; - const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax); + const ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds = btDbvtVolume::FromMM(localAabbMin, localAabbMax); //process all children, that overlap with the given AABB bounds - tree->collideTVNoStackAlloc(tree->m_root,bounds,stack2,callback); - - } else + tree->collideTVNoStackAlloc(tree->m_root, bounds, stack2, callback); + } + else { //iterate over all children, perform an AABB check inside ProcessChildShape int numChildren = m_childCollisionAlgorithms.size(); int i; - for (i=0;igetChildShape(i),i); + callback.ProcessChildShape(compoundShape->getChildShape(i), i); } } { - //iterate over all children, perform an AABB check inside ProcessChildShape + //iterate over all children, perform an AABB check inside ProcessChildShape int numChildren = m_childCollisionAlgorithms.size(); int i; manifoldArray.resize(0); - const btCollisionShape* childShape = 0; - btTransform orgTrans; - - btTransform newChildWorldTrans; - btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1; - - for (i=0;igetChildShape(i); - //if not longer overlapping, remove the algorithm + //if not longer overlapping, remove the algorithm orgTrans = colObjWrap->getWorldTransform(); - + const btTransform& childTrans = compoundShape->getChildTransform(i); - newChildWorldTrans = orgTrans*childTrans ; + newChildWorldTrans = orgTrans * childTrans; //perform an AABB check first - childShape->getAabb(newChildWorldTrans,aabbMin0,aabbMax0); - otherObjWrap->getCollisionShape()->getAabb(otherObjWrap->getWorldTransform(),aabbMin1,aabbMax1); + childShape->getAabb(newChildWorldTrans, aabbMin0, aabbMax0); + otherObjWrap->getCollisionShape()->getAabb(otherObjWrap->getWorldTransform(), aabbMin1, aabbMax1); - if (!TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1)) + if (!TestAabbAgainstAabb2(aabbMin0, aabbMax0, aabbMin1, aabbMax1)) { m_childCollisionAlgorithms[i]->~btCollisionAlgorithm(); m_dispatcher->freeCollisionAlgorithm(m_childCollisionAlgorithms[i]); @@ -354,15 +334,15 @@ void btCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrap } } -btScalar btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +btScalar btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { btAssert(0); //needs to be fixed, using btCollisionObjectWrapper and NOT modifying internal data structures - btCollisionObject* colObj = m_isSwapped? body1 : body0; - btCollisionObject* otherObj = m_isSwapped? body0 : body1; + btCollisionObject* colObj = m_isSwapped ? body1 : body0; + btCollisionObject* otherObj = m_isSwapped ? body0 : body1; + + btAssert(colObj->getCollisionShape()->isCompound()); - btAssert (colObj->getCollisionShape()->isCompound()); - btCompoundShape* compoundShape = static_cast(colObj->getCollisionShape()); //We will use the OptimizedBVH, AABB tree to cull potential child-overlaps @@ -376,33 +356,29 @@ btScalar btCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* int numChildren = m_childCollisionAlgorithms.size(); int i; - btTransform orgTrans; - btScalar frac; - for (i=0;igetChildShape(i); //backup - orgTrans = colObj->getWorldTransform(); - + orgTrans = colObj->getWorldTransform(); + const btTransform& childTrans = compoundShape->getChildTransform(i); //btTransform newChildWorldTrans = orgTrans*childTrans ; - colObj->setWorldTransform( orgTrans*childTrans ); + colObj->setWorldTransform(orgTrans * childTrans); //btCollisionShape* tmpShape = colObj->getCollisionShape(); //colObj->internalSetTemporaryCollisionShape( childShape ); - frac = m_childCollisionAlgorithms[i]->calculateTimeOfImpact(colObj,otherObj,dispatchInfo,resultOut); - if (fraccalculateTimeOfImpact(colObj, otherObj, dispatchInfo, resultOut); + if (frac < hitFraction) { hitFraction = frac; } //revert back //colObj->internalSetTemporaryCollisionShape( tmpShape); - colObj->setWorldTransform( orgTrans); + colObj->setWorldTransform(orgTrans); } return hitFraction; - } - - - diff --git a/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h index d2086fbc0..4ea5e7718 100644 --- a/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h +++ b/src/BulletCollision/CollisionDispatch/btCompoundCollisionAlgorithm.h @@ -35,7 +35,7 @@ typedef bool (*btShapePairCallback)(const btCollisionShape* pShape0, const btCol extern btShapePairCallback gCompoundChildShapePairCallback; /// btCompoundCollisionAlgorithm supports collision between CompoundCollisionShapes and other collision shapes -class btCompoundCollisionAlgorithm : public btActivatingCollisionAlgorithm +class btCompoundCollisionAlgorithm : public btActivatingCollisionAlgorithm { btNodeStack stack2; btManifoldArray manifoldArray; @@ -44,61 +44,56 @@ protected: btAlignedObjectArray m_childCollisionAlgorithms; bool m_isSwapped; - class btPersistentManifold* m_sharedManifold; - bool m_ownsManifold; + class btPersistentManifold* m_sharedManifold; + bool m_ownsManifold; + int m_compoundShapeRevision; //to keep track of changes, so that childAlgorithm array can be updated - int m_compoundShapeRevision;//to keep track of changes, so that childAlgorithm array can be updated - - void removeChildAlgorithms(); - - void preallocateChildAlgorithms(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap); + void removeChildAlgorithms(); + + void preallocateChildAlgorithms(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap); public: - - btCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped); + btCompoundCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, bool isSwapped); virtual ~btCompoundCollisionAlgorithm(); - btCollisionAlgorithm* getChildAlgorithm (int n) const + btCollisionAlgorithm* getChildAlgorithm(int n) const { return m_childCollisionAlgorithms[n]; } + virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); - - virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) { int i; - for (i=0;igetAllContactManifolds(manifoldArray); } } - - struct CreateFunc :public btCollisionAlgorithmCreateFunc + struct CreateFunc : public btCollisionAlgorithmCreateFunc { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCollisionAlgorithm)); - return new(mem) btCompoundCollisionAlgorithm(ci,body0Wrap,body1Wrap,false); + return new (mem) btCompoundCollisionAlgorithm(ci, body0Wrap, body1Wrap, false); } }; - struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc + struct SwappedCreateFunc : public btCollisionAlgorithmCreateFunc { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCollisionAlgorithm)); - return new(mem) btCompoundCollisionAlgorithm(ci,body0Wrap,body1Wrap,true); + return new (mem) btCompoundCollisionAlgorithm(ci, body0Wrap, body1Wrap, true); } }; - }; -#endif //BT_COMPOUND_COLLISION_ALGORITHM_H +#endif //BT_COMPOUND_COLLISION_ALGORITHM_H diff --git a/src/BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.cpp index 20b542f67..044b60dbb 100644 --- a/src/BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.cpp +++ b/src/BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.cpp @@ -29,29 +29,25 @@ subject to the following restrictions: btShapePairCallback gCompoundCompoundChildShapePairCallback = 0; -btCompoundCompoundCollisionAlgorithm::btCompoundCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped) -:btCompoundCollisionAlgorithm(ci,body0Wrap,body1Wrap,isSwapped) +btCompoundCompoundCollisionAlgorithm::btCompoundCompoundCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, bool isSwapped) + : btCompoundCollisionAlgorithm(ci, body0Wrap, body1Wrap, isSwapped) { - - void* ptr = btAlignedAlloc(sizeof(btHashedSimplePairCache),16); - m_childCollisionAlgorithmCache= new(ptr) btHashedSimplePairCache(); + void* ptr = btAlignedAlloc(sizeof(btHashedSimplePairCache), 16); + m_childCollisionAlgorithmCache = new (ptr) btHashedSimplePairCache(); const btCollisionObjectWrapper* col0ObjWrap = body0Wrap; - btAssert (col0ObjWrap->getCollisionShape()->isCompound()); + btAssert(col0ObjWrap->getCollisionShape()->isCompound()); const btCollisionObjectWrapper* col1ObjWrap = body1Wrap; - btAssert (col1ObjWrap->getCollisionShape()->isCompound()); - + btAssert(col1ObjWrap->getCollisionShape()->isCompound()); + const btCompoundShape* compoundShape0 = static_cast(col0ObjWrap->getCollisionShape()); m_compoundShapeRevision0 = compoundShape0->getUpdateRevision(); const btCompoundShape* compoundShape1 = static_cast(col1ObjWrap->getCollisionShape()); m_compoundShapeRevision1 = compoundShape1->getUpdateRevision(); - - } - btCompoundCompoundCollisionAlgorithm::~btCompoundCompoundCollisionAlgorithm() { removeChildAlgorithms(); @@ -59,32 +55,30 @@ btCompoundCompoundCollisionAlgorithm::~btCompoundCompoundCollisionAlgorithm() btAlignedFree(m_childCollisionAlgorithmCache); } -void btCompoundCompoundCollisionAlgorithm::getAllContactManifolds(btManifoldArray& manifoldArray) +void btCompoundCompoundCollisionAlgorithm::getAllContactManifolds(btManifoldArray& manifoldArray) { int i; btSimplePairArray& pairs = m_childCollisionAlgorithmCache->getOverlappingPairArray(); - for (i=0;igetAllContactManifolds(manifoldArray); } } } - -void btCompoundCompoundCollisionAlgorithm::removeChildAlgorithms() +void btCompoundCompoundCollisionAlgorithm::removeChildAlgorithms() { btSimplePairArray& pairs = m_childCollisionAlgorithmCache->getOverlappingPairArray(); int numChildren = pairs.size(); int i; - for (i=0;i~btCollisionAlgorithm(); m_dispatcher->freeCollisionAlgorithm(algo); } @@ -92,77 +86,65 @@ void btCompoundCompoundCollisionAlgorithm::removeChildAlgorithms() m_childCollisionAlgorithmCache->removeAllPairs(); } -struct btCompoundCompoundLeafCallback : btDbvt::ICollide +struct btCompoundCompoundLeafCallback : btDbvt::ICollide { int m_numOverlapPairs; - const btCollisionObjectWrapper* m_compound0ColObjWrap; const btCollisionObjectWrapper* m_compound1ColObjWrap; btDispatcher* m_dispatcher; const btDispatcherInfo& m_dispatchInfo; - btManifoldResult* m_resultOut; - - - class btHashedSimplePairCache* m_childCollisionAlgorithmCache; - - btPersistentManifold* m_sharedManifold; - - btCompoundCompoundLeafCallback (const btCollisionObjectWrapper* compound1ObjWrap, - const btCollisionObjectWrapper* compound0ObjWrap, - btDispatcher* dispatcher, - const btDispatcherInfo& dispatchInfo, - btManifoldResult* resultOut, - btHashedSimplePairCache* childAlgorithmsCache, - btPersistentManifold* sharedManifold) - :m_numOverlapPairs(0),m_compound0ColObjWrap(compound1ObjWrap),m_compound1ColObjWrap(compound0ObjWrap),m_dispatcher(dispatcher),m_dispatchInfo(dispatchInfo),m_resultOut(resultOut), - m_childCollisionAlgorithmCache(childAlgorithmsCache), - m_sharedManifold(sharedManifold) - { + btManifoldResult* m_resultOut; + class btHashedSimplePairCache* m_childCollisionAlgorithmCache; + + btPersistentManifold* m_sharedManifold; + + btCompoundCompoundLeafCallback(const btCollisionObjectWrapper* compound1ObjWrap, + const btCollisionObjectWrapper* compound0ObjWrap, + btDispatcher* dispatcher, + const btDispatcherInfo& dispatchInfo, + btManifoldResult* resultOut, + btHashedSimplePairCache* childAlgorithmsCache, + btPersistentManifold* sharedManifold) + : m_numOverlapPairs(0), m_compound0ColObjWrap(compound1ObjWrap), m_compound1ColObjWrap(compound0ObjWrap), m_dispatcher(dispatcher), m_dispatchInfo(dispatchInfo), m_resultOut(resultOut), m_childCollisionAlgorithmCache(childAlgorithmsCache), m_sharedManifold(sharedManifold) + { } - - - - void Process(const btDbvtNode* leaf0,const btDbvtNode* leaf1) + void Process(const btDbvtNode* leaf0, const btDbvtNode* leaf1) { BT_PROFILE("btCompoundCompoundLeafCallback::Process"); m_numOverlapPairs++; - int childIndex0 = leaf0->dataAsInt; int childIndex1 = leaf1->dataAsInt; - - - btAssert(childIndex0>=0); - btAssert(childIndex1>=0); + btAssert(childIndex0 >= 0); + btAssert(childIndex1 >= 0); const btCompoundShape* compoundShape0 = static_cast(m_compound0ColObjWrap->getCollisionShape()); - btAssert(childIndex0getNumChildShapes()); + btAssert(childIndex0 < compoundShape0->getNumChildShapes()); const btCompoundShape* compoundShape1 = static_cast(m_compound1ColObjWrap->getCollisionShape()); - btAssert(childIndex1getNumChildShapes()); + btAssert(childIndex1 < compoundShape1->getNumChildShapes()); const btCollisionShape* childShape0 = compoundShape0->getChildShape(childIndex0); const btCollisionShape* childShape1 = compoundShape1->getChildShape(childIndex1); //backup - btTransform orgTrans0 = m_compound0ColObjWrap->getWorldTransform(); + btTransform orgTrans0 = m_compound0ColObjWrap->getWorldTransform(); const btTransform& childTrans0 = compoundShape0->getChildTransform(childIndex0); - btTransform newChildWorldTrans0 = orgTrans0*childTrans0 ; - - btTransform orgTrans1 = m_compound1ColObjWrap->getWorldTransform(); + btTransform newChildWorldTrans0 = orgTrans0 * childTrans0; + + btTransform orgTrans1 = m_compound1ColObjWrap->getWorldTransform(); const btTransform& childTrans1 = compoundShape1->getChildTransform(childIndex1); - btTransform newChildWorldTrans1 = orgTrans1*childTrans1 ; - + btTransform newChildWorldTrans1 = orgTrans1 * childTrans1; //perform an AABB check first - btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1; - childShape0->getAabb(newChildWorldTrans0,aabbMin0,aabbMax0); - childShape1->getAabb(newChildWorldTrans1,aabbMin1,aabbMax1); - + btVector3 aabbMin0, aabbMax0, aabbMin1, aabbMax1; + childShape0->getAabb(newChildWorldTrans0, aabbMin0, aabbMax0); + childShape1->getAabb(newChildWorldTrans1, aabbMin1, aabbMax1); + btVector3 thresholdVec(m_resultOut->m_closestPointDistanceThreshold, m_resultOut->m_closestPointDistanceThreshold, m_resultOut->m_closestPointDistanceThreshold); aabbMin0 -= thresholdVec; @@ -170,17 +152,16 @@ struct btCompoundCompoundLeafCallback : btDbvt::ICollide if (gCompoundCompoundChildShapePairCallback) { - if (!gCompoundCompoundChildShapePairCallback(childShape0,childShape1)) + if (!gCompoundCompoundChildShapePairCallback(childShape0, childShape1)) return; } - if (TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1)) + if (TestAabbAgainstAabb2(aabbMin0, aabbMax0, aabbMin1, aabbMax1)) { - btCollisionObjectWrapper compoundWrap0(this->m_compound0ColObjWrap,childShape0, m_compound0ColObjWrap->getCollisionObject(),newChildWorldTrans0,-1,childIndex0); - btCollisionObjectWrapper compoundWrap1(this->m_compound1ColObjWrap,childShape1,m_compound1ColObjWrap->getCollisionObject(),newChildWorldTrans1,-1,childIndex1); - + btCollisionObjectWrapper compoundWrap0(this->m_compound0ColObjWrap, childShape0, m_compound0ColObjWrap->getCollisionObject(), newChildWorldTrans0, -1, childIndex0); + btCollisionObjectWrapper compoundWrap1(this->m_compound1ColObjWrap, childShape1, m_compound1ColObjWrap->getCollisionObject(), newChildWorldTrans1, -1, childIndex1); - btSimplePair* pair = m_childCollisionAlgorithmCache->findPair(childIndex0,childIndex1); + btSimplePair* pair = m_childCollisionAlgorithmCache->findPair(childIndex0, childIndex1); bool removePair = false; btCollisionAlgorithm* colAlgo = 0; if (m_resultOut->m_closestPointDistanceThreshold > 0) @@ -193,7 +174,6 @@ struct btCompoundCompoundLeafCallback : btDbvt::ICollide if (pair) { colAlgo = (btCollisionAlgorithm*)pair->m_userPointer; - } else { @@ -205,7 +185,7 @@ struct btCompoundCompoundLeafCallback : btDbvt::ICollide } btAssert(colAlgo); - + const btCollisionObjectWrapper* tmpWrap0 = 0; const btCollisionObjectWrapper* tmpWrap1 = 0; @@ -215,105 +195,100 @@ struct btCompoundCompoundLeafCallback : btDbvt::ICollide m_resultOut->setBody0Wrap(&compoundWrap0); m_resultOut->setBody1Wrap(&compoundWrap1); - m_resultOut->setShapeIdentifiersA(-1,childIndex0); - m_resultOut->setShapeIdentifiersB(-1,childIndex1); + m_resultOut->setShapeIdentifiersA(-1, childIndex0); + m_resultOut->setShapeIdentifiersB(-1, childIndex1); + colAlgo->processCollision(&compoundWrap0, &compoundWrap1, m_dispatchInfo, m_resultOut); - colAlgo->processCollision(&compoundWrap0,&compoundWrap1,m_dispatchInfo,m_resultOut); - m_resultOut->setBody0Wrap(tmpWrap0); m_resultOut->setBody1Wrap(tmpWrap1); - + if (removePair) { colAlgo->~btCollisionAlgorithm(); m_dispatcher->freeCollisionAlgorithm(colAlgo); } - } } }; - -static DBVT_INLINE bool MyIntersect( const btDbvtAabbMm& a, - const btDbvtAabbMm& b, const btTransform& xform, btScalar distanceThreshold) +static DBVT_INLINE bool MyIntersect(const btDbvtAabbMm& a, + const btDbvtAabbMm& b, const btTransform& xform, btScalar distanceThreshold) { - btVector3 newmin,newmax; - btTransformAabb(b.Mins(),b.Maxs(),0.f,xform,newmin,newmax); + btVector3 newmin, newmax; + btTransformAabb(b.Mins(), b.Maxs(), 0.f, xform, newmin, newmax); newmin -= btVector3(distanceThreshold, distanceThreshold, distanceThreshold); newmax += btVector3(distanceThreshold, distanceThreshold, distanceThreshold); - btDbvtAabbMm newb = btDbvtAabbMm::FromMM(newmin,newmax); - return Intersect(a,newb); + btDbvtAabbMm newb = btDbvtAabbMm::FromMM(newmin, newmax); + return Intersect(a, newb); } - -static inline void MycollideTT( const btDbvtNode* root0, - const btDbvtNode* root1, - const btTransform& xform, - btCompoundCompoundLeafCallback* callback, btScalar distanceThreshold) +static inline void MycollideTT(const btDbvtNode* root0, + const btDbvtNode* root1, + const btTransform& xform, + btCompoundCompoundLeafCallback* callback, btScalar distanceThreshold) { - - if(root0&&root1) - { - int depth=1; - int treshold=btDbvt::DOUBLE_STACKSIZE-4; - btAlignedObjectArray stkStack; + if (root0 && root1) + { + int depth = 1; + int treshold = btDbvt::DOUBLE_STACKSIZE - 4; + btAlignedObjectArray stkStack; #ifdef USE_LOCAL_STACK - ATTRIBUTE_ALIGNED16(btDbvt::sStkNN localStack[btDbvt::DOUBLE_STACKSIZE]); - stkStack.initializeFromBuffer(&localStack,btDbvt::DOUBLE_STACKSIZE,btDbvt::DOUBLE_STACKSIZE); + ATTRIBUTE_ALIGNED16(btDbvt::sStkNN localStack[btDbvt::DOUBLE_STACKSIZE]); + stkStack.initializeFromBuffer(&localStack, btDbvt::DOUBLE_STACKSIZE, btDbvt::DOUBLE_STACKSIZE); #else - stkStack.resize(btDbvt::DOUBLE_STACKSIZE); + stkStack.resize(btDbvt::DOUBLE_STACKSIZE); #endif - stkStack[0]=btDbvt::sStkNN(root0,root1); - do { - btDbvt::sStkNN p=stkStack[--depth]; - if(MyIntersect(p.a->volume,p.b->volume,xform, distanceThreshold)) + stkStack[0] = btDbvt::sStkNN(root0, root1); + do + { + btDbvt::sStkNN p = stkStack[--depth]; + if (MyIntersect(p.a->volume, p.b->volume, xform, distanceThreshold)) + { + if (depth > treshold) { - if(depth>treshold) + stkStack.resize(stkStack.size() * 2); + treshold = stkStack.size() - 4; + } + if (p.a->isinternal()) + { + if (p.b->isinternal()) { - stkStack.resize(stkStack.size()*2); - treshold=stkStack.size()-4; - } - if(p.a->isinternal()) - { - if(p.b->isinternal()) - { - stkStack[depth++]=btDbvt::sStkNN(p.a->childs[0],p.b->childs[0]); - stkStack[depth++]=btDbvt::sStkNN(p.a->childs[1],p.b->childs[0]); - stkStack[depth++]=btDbvt::sStkNN(p.a->childs[0],p.b->childs[1]); - stkStack[depth++]=btDbvt::sStkNN(p.a->childs[1],p.b->childs[1]); - } - else - { - stkStack[depth++]=btDbvt::sStkNN(p.a->childs[0],p.b); - stkStack[depth++]=btDbvt::sStkNN(p.a->childs[1],p.b); - } + stkStack[depth++] = btDbvt::sStkNN(p.a->childs[0], p.b->childs[0]); + stkStack[depth++] = btDbvt::sStkNN(p.a->childs[1], p.b->childs[0]); + stkStack[depth++] = btDbvt::sStkNN(p.a->childs[0], p.b->childs[1]); + stkStack[depth++] = btDbvt::sStkNN(p.a->childs[1], p.b->childs[1]); } else { - if(p.b->isinternal()) - { - stkStack[depth++]=btDbvt::sStkNN(p.a,p.b->childs[0]); - stkStack[depth++]=btDbvt::sStkNN(p.a,p.b->childs[1]); - } - else - { - callback->Process(p.a,p.b); - } + stkStack[depth++] = btDbvt::sStkNN(p.a->childs[0], p.b); + stkStack[depth++] = btDbvt::sStkNN(p.a->childs[1], p.b); } } - } while(depth); - } + else + { + if (p.b->isinternal()) + { + stkStack[depth++] = btDbvt::sStkNN(p.a, p.b->childs[0]); + stkStack[depth++] = btDbvt::sStkNN(p.a, p.b->childs[1]); + } + else + { + callback->Process(p.a, p.b); + } + } + } + } while (depth); + } } -void btCompoundCompoundCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +void btCompoundCompoundCollisionAlgorithm::processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { - const btCollisionObjectWrapper* col0ObjWrap = body0Wrap; - const btCollisionObjectWrapper* col1ObjWrap= body1Wrap; + const btCollisionObjectWrapper* col1ObjWrap = body1Wrap; - btAssert (col0ObjWrap->getCollisionShape()->isCompound()); - btAssert (col1ObjWrap->getCollisionShape()->isCompound()); + btAssert(col0ObjWrap->getCollisionShape()->isCompound()); + btAssert(col1ObjWrap->getCollisionShape()->isCompound()); const btCompoundShape* compoundShape0 = static_cast(col0ObjWrap->getCollisionShape()); const btCompoundShape* compoundShape1 = static_cast(col1ObjWrap->getCollisionShape()); @@ -321,7 +296,7 @@ void btCompoundCompoundCollisionAlgorithm::processCollision (const btCollisionOb const btDbvt* tree1 = compoundShape1->getDynamicAabbTree(); if (!tree0 || !tree1) { - return btCompoundCollisionAlgorithm::processCollision(body0Wrap,body1Wrap,dispatchInfo,resultOut); + return btCompoundCollisionAlgorithm::processCollision(body0Wrap, body1Wrap, dispatchInfo, resultOut); } ///btCompoundShape might have changed: ////make sure the internal child collision algorithm caches are still valid @@ -331,28 +306,26 @@ void btCompoundCompoundCollisionAlgorithm::processCollision (const btCollisionOb removeChildAlgorithms(); m_compoundShapeRevision0 = compoundShape0->getUpdateRevision(); m_compoundShapeRevision1 = compoundShape1->getUpdateRevision(); - } - ///we need to refresh all contact manifolds ///note that we should actually recursively traverse all children, btCompoundShape can nested more then 1 level deep ///so we should add a 'refreshManifolds' in the btCollisionAlgorithm { int i; btManifoldArray manifoldArray; -#ifdef USE_LOCAL_STACK +#ifdef USE_LOCAL_STACK btPersistentManifold localManifolds[4]; - manifoldArray.initializeFromBuffer(&localManifolds,0,4); + manifoldArray.initializeFromBuffer(&localManifolds, 0, 4); #endif btSimplePairArray& pairs = m_childCollisionAlgorithmCache->getOverlappingPairArray(); - for (i=0;igetAllContactManifolds(manifoldArray); - for (int m=0;mgetNumContacts()) { @@ -366,35 +339,27 @@ void btCompoundCompoundCollisionAlgorithm::processCollision (const btCollisionOb } } + btCompoundCompoundLeafCallback callback(col0ObjWrap, col1ObjWrap, this->m_dispatcher, dispatchInfo, resultOut, this->m_childCollisionAlgorithmCache, m_sharedManifold); - - - btCompoundCompoundLeafCallback callback(col0ObjWrap,col1ObjWrap,this->m_dispatcher,dispatchInfo,resultOut,this->m_childCollisionAlgorithmCache,m_sharedManifold); - - - const btTransform xform=col0ObjWrap->getWorldTransform().inverse()*col1ObjWrap->getWorldTransform(); - MycollideTT(tree0->m_root,tree1->m_root,xform,&callback, resultOut->m_closestPointDistanceThreshold); + const btTransform xform = col0ObjWrap->getWorldTransform().inverse() * col1ObjWrap->getWorldTransform(); + MycollideTT(tree0->m_root, tree1->m_root, xform, &callback, resultOut->m_closestPointDistanceThreshold); //printf("#compound-compound child/leaf overlap =%d \r",callback.m_numOverlapPairs); //remove non-overlapping child pairs { - btAssert(m_removePairs.size()==0); + btAssert(m_removePairs.size() == 0); //iterate over all children, perform an AABB check inside ProcessChildShape btSimplePairArray& pairs = m_childCollisionAlgorithmCache->getOverlappingPairArray(); - - int i; - btManifoldArray manifoldArray; - - - - - btVector3 aabbMin0,aabbMax0,aabbMin1,aabbMax1; - - for (i=0;igetChildShape(pairs[i].m_indexA); const btTransform& childTrans0 = compoundShape0->getChildTransform(pairs[i].m_indexA); - newChildWorldTrans0 = col0ObjWrap->getWorldTransform()*childTrans0 ; - childShape0->getAabb(newChildWorldTrans0,aabbMin0,aabbMax0); + newChildWorldTrans0 = col0ObjWrap->getWorldTransform() * childTrans0; + childShape0->getAabb(newChildWorldTrans0, aabbMin0, aabbMax0); } btVector3 thresholdVec(resultOut->m_closestPointDistanceThreshold, resultOut->m_closestPointDistanceThreshold, resultOut->m_closestPointDistanceThreshold); aabbMin0 -= thresholdVec; aabbMax0 += thresholdVec; { const btCollisionShape* childShape1 = 0; - btTransform newChildWorldTrans1; + btTransform newChildWorldTrans1; childShape1 = compoundShape1->getChildShape(pairs[i].m_indexB); const btTransform& childTrans1 = compoundShape1->getChildTransform(pairs[i].m_indexB); - newChildWorldTrans1 = col1ObjWrap->getWorldTransform()*childTrans1 ; - childShape1->getAabb(newChildWorldTrans1,aabbMin1,aabbMax1); + newChildWorldTrans1 = col1ObjWrap->getWorldTransform() * childTrans1; + childShape1->getAabb(newChildWorldTrans1, aabbMin1, aabbMax1); } - + aabbMin1 -= thresholdVec; aabbMax1 += thresholdVec; - if (!TestAabbAgainstAabb2(aabbMin0,aabbMax0,aabbMin1,aabbMax1)) + if (!TestAabbAgainstAabb2(aabbMin0, aabbMax0, aabbMin1, aabbMax1)) { algo->~btCollisionAlgorithm(); m_dispatcher->freeCollisionAlgorithm(algo); - m_removePairs.push_back(btSimplePair(pairs[i].m_indexA,pairs[i].m_indexB)); + m_removePairs.push_back(btSimplePair(pairs[i].m_indexA, pairs[i].m_indexB)); } } } - for (int i=0;iremoveOverlappingPair(m_removePairs[i].m_indexA,m_removePairs[i].m_indexB); + m_childCollisionAlgorithmCache->removeOverlappingPair(m_removePairs[i].m_indexA, m_removePairs[i].m_indexB); } m_removePairs.clear(); } - } -btScalar btCompoundCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +btScalar btCompoundCompoundCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { btAssert(0); return 0.f; - } - - - diff --git a/src/BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.h index f29f7a709..14e8a7ada 100644 --- a/src/BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.h +++ b/src/BulletCollision/CollisionDispatch/btCompoundCompoundCollisionAlgorithm.h @@ -35,53 +35,46 @@ class btCollisionObject; class btCollisionShape; /// btCompoundCompoundCollisionAlgorithm supports collision between two btCompoundCollisionShape shapes -class btCompoundCompoundCollisionAlgorithm : public btCompoundCollisionAlgorithm +class btCompoundCompoundCollisionAlgorithm : public btCompoundCollisionAlgorithm { - - class btHashedSimplePairCache* m_childCollisionAlgorithmCache; + class btHashedSimplePairCache* m_childCollisionAlgorithmCache; btSimplePairArray m_removePairs; + int m_compoundShapeRevision0; //to keep track of changes, so that childAlgorithm array can be updated + int m_compoundShapeRevision1; - int m_compoundShapeRevision0;//to keep track of changes, so that childAlgorithm array can be updated - int m_compoundShapeRevision1; - - void removeChildAlgorithms(); - -// void preallocateChildAlgorithms(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap); + void removeChildAlgorithms(); + + // void preallocateChildAlgorithms(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap); public: - - btCompoundCompoundCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped); + btCompoundCompoundCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, bool isSwapped); virtual ~btCompoundCompoundCollisionAlgorithm(); - + virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual void getAllContactManifolds(btManifoldArray& manifoldArray); - virtual void getAllContactManifolds(btManifoldArray& manifoldArray); - - - struct CreateFunc :public btCollisionAlgorithmCreateFunc + struct CreateFunc : public btCollisionAlgorithmCreateFunc { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCompoundCollisionAlgorithm)); - return new(mem) btCompoundCompoundCollisionAlgorithm(ci,body0Wrap,body1Wrap,false); + return new (mem) btCompoundCompoundCollisionAlgorithm(ci, body0Wrap, body1Wrap, false); } }; - struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc + struct SwappedCreateFunc : public btCollisionAlgorithmCreateFunc { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btCompoundCompoundCollisionAlgorithm)); - return new(mem) btCompoundCompoundCollisionAlgorithm(ci,body0Wrap,body1Wrap,true); + return new (mem) btCompoundCompoundCollisionAlgorithm(ci, body0Wrap, body1Wrap, true); } }; - }; -#endif //BT_COMPOUND_COMPOUND_COLLISION_ALGORITHM_H +#endif //BT_COMPOUND_COMPOUND_COLLISION_ALGORITHM_H diff --git a/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp index 1cb3d2e7a..9087f8439 100644 --- a/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp +++ b/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.cpp @@ -22,7 +22,6 @@ subject to the following restrictions: #include "BulletCollision/CollisionShapes/btConvexShape.h" #include "BulletCollision/CollisionShapes/btCapsuleShape.h" - #include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" @@ -34,8 +33,6 @@ subject to the following restrictions: #include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" #include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h" - - #include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" #include "BulletCollision/CollisionShapes/btSphereShape.h" @@ -45,31 +42,28 @@ subject to the following restrictions: #include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" #include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" -btConvex2dConvex2dAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver) +btConvex2dConvex2dAlgorithm::CreateFunc::CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver) { m_simplexSolver = simplexSolver; m_pdSolver = pdSolver; } -btConvex2dConvex2dAlgorithm::CreateFunc::~CreateFunc() -{ +btConvex2dConvex2dAlgorithm::CreateFunc::~CreateFunc() +{ } -btConvex2dConvex2dAlgorithm::btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver,int /* numPerturbationIterations */, int /* minimumPointsPerturbationThreshold */) -: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap), -m_simplexSolver(simplexSolver), -m_pdSolver(pdSolver), -m_ownManifold (false), -m_manifoldPtr(mf), -m_lowLevelOfDetail(false) +btConvex2dConvex2dAlgorithm::btConvex2dConvex2dAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int /* numPerturbationIterations */, int /* minimumPointsPerturbationThreshold */) + : btActivatingCollisionAlgorithm(ci, body0Wrap, body1Wrap), + m_simplexSolver(simplexSolver), + m_pdSolver(pdSolver), + m_ownManifold(false), + m_manifoldPtr(mf), + m_lowLevelOfDetail(false) { (void)body0Wrap; (void)body1Wrap; } - - - btConvex2dConvex2dAlgorithm::~btConvex2dConvex2dAlgorithm() { if (m_ownManifold) @@ -79,26 +73,22 @@ btConvex2dConvex2dAlgorithm::~btConvex2dConvex2dAlgorithm() } } -void btConvex2dConvex2dAlgorithm ::setLowLevelOfDetail(bool useLowLevel) +void btConvex2dConvex2dAlgorithm ::setLowLevelOfDetail(bool useLowLevel) { m_lowLevelOfDetail = useLowLevel; } - - extern btScalar gContactBreakingThreshold; - // // Convex-Convex collision algorithm // -void btConvex2dConvex2dAlgorithm ::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +void btConvex2dConvex2dAlgorithm ::processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { - if (!m_manifoldPtr) { //swapped? - m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject()); + m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(), body1Wrap->getCollisionObject()); m_ownManifold = true; } resultOut->setPersistentManifold(m_manifoldPtr); @@ -106,49 +96,41 @@ void btConvex2dConvex2dAlgorithm ::processCollision (const btCollisionObjectWrap //comment-out next line to test multi-contact generation //resultOut->getPersistentManifold()->clearManifold(); - const btConvexShape* min0 = static_cast(body0Wrap->getCollisionShape()); const btConvexShape* min1 = static_cast(body1Wrap->getCollisionShape()); - btVector3 normalOnB; - btVector3 pointOnBWorld; + btVector3 normalOnB; + btVector3 pointOnBWorld; { - - btGjkPairDetector::ClosestPointInput input; - btGjkPairDetector gjkPairDetector(min0,min1,m_simplexSolver,m_pdSolver); + btGjkPairDetector gjkPairDetector(min0, min1, m_simplexSolver, m_pdSolver); //TODO: if (dispatchInfo.m_useContinuous) gjkPairDetector.setMinkowskiA(min0); gjkPairDetector.setMinkowskiB(min1); { input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold(); - input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared; + input.m_maximumDistanceSquared *= input.m_maximumDistanceSquared; } input.m_transformA = body0Wrap->getWorldTransform(); input.m_transformB = body1Wrap->getWorldTransform(); - gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); + gjkPairDetector.getClosestPoints(input, *resultOut, dispatchInfo.m_debugDraw); - btVector3 v0,v1; + btVector3 v0, v1; btVector3 sepNormalWorldSpace; - } if (m_ownManifold) { resultOut->refreshContactPoints(); } - } - - - -btScalar btConvex2dConvex2dAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +btScalar btConvex2dConvex2dAlgorithm::calculateTimeOfImpact(btCollisionObject* col0, btCollisionObject* col1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { (void)resultOut; (void)dispatchInfo; @@ -158,7 +140,6 @@ btScalar btConvex2dConvex2dAlgorithm::calculateTimeOfImpact(btCollisionObject* c ///col0->m_worldTransform, btScalar resultFraction = btScalar(1.); - btScalar squareMot0 = (col0->getInterpolationWorldTransform().getOrigin() - col0->getWorldTransform().getOrigin()).length2(); btScalar squareMot1 = (col1->getInterpolationWorldTransform().getOrigin() - col1->getWorldTransform().getOrigin()).length2(); @@ -166,77 +147,65 @@ btScalar btConvex2dConvex2dAlgorithm::calculateTimeOfImpact(btCollisionObject* c squareMot1 < col1->getCcdSquareMotionThreshold()) return resultFraction; - //An adhoc way of testing the Continuous Collision Detection algorithms //One object is approximated as a sphere, to simplify things //Starting in penetration should report no time of impact //For proper CCD, better accuracy and handling of 'allowed' penetration should be added //also the mainloop of the physics should have a kind of toi queue (something like Brian Mirtich's application of Timewarp for Rigidbodies) - /// Convex0 against sphere for Convex1 { btConvexShape* convex0 = static_cast(col0->getCollisionShape()); - btSphereShape sphere1(col1->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation + btSphereShape sphere1(col1->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation btConvexCast::CastResult result; btVoronoiSimplexSolver voronoiSimplex; //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex); ///Simplification, one object is simplified as a sphere - btGjkConvexCast ccd1( convex0 ,&sphere1,&voronoiSimplex); + btGjkConvexCast ccd1(convex0, &sphere1, &voronoiSimplex); //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0); - if (ccd1.calcTimeOfImpact(col0->getWorldTransform(),col0->getInterpolationWorldTransform(), - col1->getWorldTransform(),col1->getInterpolationWorldTransform(),result)) + if (ccd1.calcTimeOfImpact(col0->getWorldTransform(), col0->getInterpolationWorldTransform(), + col1->getWorldTransform(), col1->getInterpolationWorldTransform(), result)) { - //store result.m_fraction in both bodies - if (col0->getHitFraction()> result.m_fraction) - col0->setHitFraction( result.m_fraction ); + if (col0->getHitFraction() > result.m_fraction) + col0->setHitFraction(result.m_fraction); if (col1->getHitFraction() > result.m_fraction) - col1->setHitFraction( result.m_fraction); + col1->setHitFraction(result.m_fraction); if (resultFraction > result.m_fraction) resultFraction = result.m_fraction; - } - - - - } /// Sphere (for convex0) against Convex1 { btConvexShape* convex1 = static_cast(col1->getCollisionShape()); - btSphereShape sphere0(col0->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation + btSphereShape sphere0(col0->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation btConvexCast::CastResult result; btVoronoiSimplexSolver voronoiSimplex; //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex); ///Simplification, one object is simplified as a sphere - btGjkConvexCast ccd1(&sphere0,convex1,&voronoiSimplex); + btGjkConvexCast ccd1(&sphere0, convex1, &voronoiSimplex); //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0); - if (ccd1.calcTimeOfImpact(col0->getWorldTransform(),col0->getInterpolationWorldTransform(), - col1->getWorldTransform(),col1->getInterpolationWorldTransform(),result)) + if (ccd1.calcTimeOfImpact(col0->getWorldTransform(), col0->getInterpolationWorldTransform(), + col1->getWorldTransform(), col1->getInterpolationWorldTransform(), result)) { - //store result.m_fraction in both bodies - if (col0->getHitFraction() > result.m_fraction) - col0->setHitFraction( result.m_fraction); + if (col0->getHitFraction() > result.m_fraction) + col0->setHitFraction(result.m_fraction); if (col1->getHitFraction() > result.m_fraction) - col1->setHitFraction( result.m_fraction); + col1->setHitFraction(result.m_fraction); if (resultFraction > result.m_fraction) resultFraction = result.m_fraction; - } } return resultFraction; - } - diff --git a/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h b/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h index 24d133677..9fca463fb 100644 --- a/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h +++ b/src/BulletCollision/CollisionDispatch/btConvex2dConvex2dAlgorithm.h @@ -23,70 +23,61 @@ subject to the following restrictions: #include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" #include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h" #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" -#include "LinearMath/btTransformUtil.h" //for btConvexSeparatingDistanceUtil +#include "LinearMath/btTransformUtil.h" //for btConvexSeparatingDistanceUtil class btConvexPenetrationDepthSolver; - ///The convex2dConvex2dAlgorithm collision algorithm support 2d collision detection for btConvex2dShape ///Currently it requires the btMinkowskiPenetrationDepthSolver, it has support for 2d penetration depth computation class btConvex2dConvex2dAlgorithm : public btActivatingCollisionAlgorithm { - btSimplexSolverInterface* m_simplexSolver; + btSimplexSolverInterface* m_simplexSolver; btConvexPenetrationDepthSolver* m_pdSolver; - - bool m_ownManifold; - btPersistentManifold* m_manifoldPtr; - bool m_lowLevelOfDetail; - + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + bool m_lowLevelOfDetail; + public: - - btConvex2dConvex2dAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold); - + btConvex2dConvex2dAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold); virtual ~btConvex2dConvex2dAlgorithm(); - virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) { ///should we use m_ownManifold to avoid adding duplicates? if (m_manifoldPtr && m_ownManifold) manifoldArray.push_back(m_manifoldPtr); } + void setLowLevelOfDetail(bool useLowLevel); - void setLowLevelOfDetail(bool useLowLevel); - - - const btPersistentManifold* getManifold() + const btPersistentManifold* getManifold() { return m_manifoldPtr; } - struct CreateFunc :public btCollisionAlgorithmCreateFunc + struct CreateFunc : public btCollisionAlgorithmCreateFunc { - - btConvexPenetrationDepthSolver* m_pdSolver; - btSimplexSolverInterface* m_simplexSolver; + btConvexPenetrationDepthSolver* m_pdSolver; + btSimplexSolverInterface* m_simplexSolver; int m_numPerturbationIterations; int m_minimumPointsPerturbationThreshold; - CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver); - + CreateFunc(btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* pdSolver); + virtual ~CreateFunc(); - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvex2dConvex2dAlgorithm)); - return new(mem) btConvex2dConvex2dAlgorithm(ci.m_manifold,ci,body0Wrap,body1Wrap,m_simplexSolver,m_pdSolver,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold); + return new (mem) btConvex2dConvex2dAlgorithm(ci.m_manifold, ci, body0Wrap, body1Wrap, m_simplexSolver, m_pdSolver, m_numPerturbationIterations, m_minimumPointsPerturbationThreshold); } }; - - }; -#endif //BT_CONVEX_2D_CONVEX_2D_ALGORITHM_H +#endif //BT_CONVEX_2D_CONVEX_2D_ALGORITHM_H diff --git a/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp index d8cbe9614..e50f85e2b 100644 --- a/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp +++ b/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btConvexConcaveCollisionAlgorithm.h" #include "LinearMath/btQuickprof.h" #include "BulletCollision/CollisionDispatch/btCollisionObject.h" @@ -29,10 +28,10 @@ subject to the following restrictions: #include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" #include "BulletCollision/CollisionShapes/btSdfCollisionShape.h" -btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped) -: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap), -m_btConvexTriangleCallback(ci.m_dispatcher1,body0Wrap,body1Wrap,isSwapped), -m_isSwapped(isSwapped) +btConvexConcaveCollisionAlgorithm::btConvexConcaveCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, bool isSwapped) + : btActivatingCollisionAlgorithm(ci, body0Wrap, body1Wrap), + m_btConvexTriangleCallback(ci.m_dispatcher1, body0Wrap, body1Wrap, isSwapped), + m_isSwapped(isSwapped) { } @@ -40,7 +39,7 @@ btConvexConcaveCollisionAlgorithm::~btConvexConcaveCollisionAlgorithm() { } -void btConvexConcaveCollisionAlgorithm::getAllContactManifolds(btManifoldArray& manifoldArray) +void btConvexConcaveCollisionAlgorithm::getAllContactManifolds(btManifoldArray& manifoldArray) { if (m_btConvexTriangleCallback.m_manifoldPtr) { @@ -48,38 +47,32 @@ void btConvexConcaveCollisionAlgorithm::getAllContactManifolds(btManifoldArray& } } - -btConvexTriangleCallback::btConvexTriangleCallback(btDispatcher* dispatcher,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped): - m_dispatcher(dispatcher), - m_dispatchInfoPtr(0) +btConvexTriangleCallback::btConvexTriangleCallback(btDispatcher* dispatcher, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, bool isSwapped) : m_dispatcher(dispatcher), + m_dispatchInfoPtr(0) { - m_convexBodyWrap = isSwapped? body1Wrap:body0Wrap; - m_triBodyWrap = isSwapped? body0Wrap:body1Wrap; - - // - // create the manifold from the dispatcher 'manifold pool' - // - m_manifoldPtr = m_dispatcher->getNewManifold(m_convexBodyWrap->getCollisionObject(),m_triBodyWrap->getCollisionObject()); + m_convexBodyWrap = isSwapped ? body1Wrap : body0Wrap; + m_triBodyWrap = isSwapped ? body0Wrap : body1Wrap; - clearCache(); + // + // create the manifold from the dispatcher 'manifold pool' + // + m_manifoldPtr = m_dispatcher->getNewManifold(m_convexBodyWrap->getCollisionObject(), m_triBodyWrap->getCollisionObject()); + + clearCache(); } btConvexTriangleCallback::~btConvexTriangleCallback() { clearCache(); - m_dispatcher->releaseManifold( m_manifoldPtr ); - + m_dispatcher->releaseManifold(m_manifoldPtr); } - -void btConvexTriangleCallback::clearCache() +void btConvexTriangleCallback::clearCache() { m_dispatcher->clearManifold(m_manifoldPtr); } - -void btConvexTriangleCallback::processTriangle(btVector3* triangle,int -partId, int triangleIndex) +void btConvexTriangleCallback::processTriangle(btVector3* triangle, int partId, int triangleIndex) { BT_PROFILE("btConvexTriangleCallback::processTriangle"); @@ -88,16 +81,12 @@ partId, int triangleIndex) return; } - //just for debugging purposes - //printf("triangle %d",m_triangleCount++); - - + //just for debugging purposes + //printf("triangle %d",m_triangleCount++); btCollisionAlgorithmConstructionInfo ci; ci.m_dispatcher1 = m_dispatcher; - - #if 0 ///debug drawing of the overlapping triangles @@ -111,16 +100,15 @@ partId, int triangleIndex) m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(triangle[0]),color); } #endif - + if (m_convexBodyWrap->getCollisionShape()->isConvex()) { - btTriangleShape tm(triangle[0],triangle[1],triangle[2]); + btTriangleShape tm(triangle[0], triangle[1], triangle[2]); tm.setMargin(m_collisionMarginTriangle); - - - btCollisionObjectWrapper triObWrap(m_triBodyWrap,&tm,m_triBodyWrap->getCollisionObject(),m_triBodyWrap->getWorldTransform(),partId,triangleIndex);//correct transform? + + btCollisionObjectWrapper triObWrap(m_triBodyWrap, &tm, m_triBodyWrap->getCollisionObject(), m_triBodyWrap->getWorldTransform(), partId, triangleIndex); //correct transform? btCollisionAlgorithm* colAlgo = 0; - + if (m_resultOut->m_closestPointDistanceThreshold > 0) { colAlgo = ci.m_dispatcher1->findAlgorithm(m_convexBodyWrap, &triObWrap, 0, BT_CLOSEST_POINT_ALGORITHMS); @@ -135,36 +123,32 @@ partId, int triangleIndex) { tmpWrap = m_resultOut->getBody0Wrap(); m_resultOut->setBody0Wrap(&triObWrap); - m_resultOut->setShapeIdentifiersA(partId,triangleIndex); + m_resultOut->setShapeIdentifiersA(partId, triangleIndex); } else { tmpWrap = m_resultOut->getBody1Wrap(); m_resultOut->setBody1Wrap(&triObWrap); - m_resultOut->setShapeIdentifiersB(partId,triangleIndex); + m_resultOut->setShapeIdentifiersB(partId, triangleIndex); } - - colAlgo->processCollision(m_convexBodyWrap,&triObWrap,*m_dispatchInfoPtr,m_resultOut); + + colAlgo->processCollision(m_convexBodyWrap, &triObWrap, *m_dispatchInfoPtr, m_resultOut); if (m_resultOut->getBody0Internal() == m_triBodyWrap->getCollisionObject()) { m_resultOut->setBody0Wrap(tmpWrap); - } else + } + else { m_resultOut->setBody1Wrap(tmpWrap); } - - colAlgo->~btCollisionAlgorithm(); ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo); } - } - - -void btConvexTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle, const btDispatcherInfo& dispatchInfo, const btCollisionObjectWrapper* convexBodyWrap, const btCollisionObjectWrapper* triBodyWrap, btManifoldResult* resultOut) +void btConvexTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle, const btDispatcherInfo& dispatchInfo, const btCollisionObjectWrapper* convexBodyWrap, const btCollisionObjectWrapper* triBodyWrap, btManifoldResult* resultOut) { m_convexBodyWrap = convexBodyWrap; m_triBodyWrap = triBodyWrap; @@ -185,16 +169,14 @@ void btConvexTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTr m_aabbMax += extra; m_aabbMin -= extra; - } void btConvexConcaveCollisionAlgorithm::clearCache() { m_btConvexTriangleCallback.clearCache(); - } -void btConvexConcaveCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) +void btConvexConcaveCollisionAlgorithm::processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { BT_PROFILE("btConvexConcaveCollisionAlgorithm::processCollision"); @@ -208,7 +190,6 @@ void btConvexConcaveCollisionAlgorithm::processCollision (const btCollisionObjec btSdfCollisionShape* sdfShape = (btSdfCollisionShape*)triBodyWrap->getCollisionShape(); if (convexBodyWrap->getCollisionShape()->isConvex()) { - btConvexShape* convex = (btConvexShape*)convexBodyWrap->getCollisionShape(); btAlignedObjectArray queryVertices; @@ -229,7 +210,6 @@ void btConvexConcaveCollisionAlgorithm::processCollision (const btCollisionObjec queryVertices.push_back(btVector3(0, 0, 0)); btSphereShape* sphere = (btSphereShape*)convex; maxDist = sphere->getRadius() + SIMD_EPSILON; - } if (queryVertices.size()) { @@ -240,7 +220,7 @@ void btConvexConcaveCollisionAlgorithm::processCollision (const btCollisionObjec for (int v = 0; v < queryVertices.size(); v++) { const btVector3& vtx = queryVertices[v]; - btVector3 vtxWorldSpace = convexBodyWrap->getWorldTransform()*vtx; + btVector3 vtxWorldSpace = convexBodyWrap->getWorldTransform() * vtx; btVector3 vtxInSdf = triBodyWrap->getWorldTransform().invXform(vtxWorldSpace); btVector3 normalLocal; @@ -250,58 +230,52 @@ void btConvexConcaveCollisionAlgorithm::processCollision (const btCollisionObjec if (dist <= maxDist) { normalLocal.safeNormalize(); - btVector3 normal = triBodyWrap->getWorldTransform().getBasis()*normalLocal; + btVector3 normal = triBodyWrap->getWorldTransform().getBasis() * normalLocal; if (convex->getShapeType() == SPHERE_SHAPE_PROXYTYPE) { btSphereShape* sphere = (btSphereShape*)convex; dist -= sphere->getRadius(); - vtxWorldSpace -= sphere->getRadius()*normal; - + vtxWorldSpace -= sphere->getRadius() * normal; } - resultOut->addContactPoint(normal,vtxWorldSpace-normal*dist, dist); + resultOut->addContactPoint(normal, vtxWorldSpace - normal * dist, dist); } } } resultOut->refreshContactPoints(); } - } - } else + } + else { - const btConcaveShape* concaveShape = static_cast( triBodyWrap->getCollisionShape()); - + const btConcaveShape* concaveShape = static_cast(triBodyWrap->getCollisionShape()); + if (convexBodyWrap->getCollisionShape()->isConvex()) { btScalar collisionMarginTriangle = concaveShape->getMargin(); - + resultOut->setPersistentManifold(m_btConvexTriangleCallback.m_manifoldPtr); - m_btConvexTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,dispatchInfo,convexBodyWrap,triBodyWrap,resultOut); + m_btConvexTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle, dispatchInfo, convexBodyWrap, triBodyWrap, resultOut); - m_btConvexTriangleCallback.m_manifoldPtr->setBodies(convexBodyWrap->getCollisionObject(),triBodyWrap->getCollisionObject()); + m_btConvexTriangleCallback.m_manifoldPtr->setBodies(convexBodyWrap->getCollisionObject(), triBodyWrap->getCollisionObject()); + + concaveShape->processAllTriangles(&m_btConvexTriangleCallback, m_btConvexTriangleCallback.getAabbMin(), m_btConvexTriangleCallback.getAabbMax()); - concaveShape->processAllTriangles( &m_btConvexTriangleCallback,m_btConvexTriangleCallback.getAabbMin(),m_btConvexTriangleCallback.getAabbMax()); - resultOut->refreshContactPoints(); m_btConvexTriangleCallback.clearWrapperData(); - } } - } - } - -btScalar btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +btScalar btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { (void)resultOut; (void)dispatchInfo; btCollisionObject* convexbody = m_isSwapped ? body1 : body0; btCollisionObject* triBody = m_isSwapped ? body0 : body1; - //quick approximation using raycast, todo: hook up to the continuous collision detection (one of the btConvexCast) //only perform CCD above a certain threshold, this prevents blocking on the long run @@ -320,25 +294,23 @@ btScalar btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObj btTransform convexFromLocal = triInv * convexbody->getWorldTransform(); btTransform convexToLocal = triInv * convexbody->getInterpolationWorldTransform(); - struct LocalTriangleSphereCastCallback : public btTriangleCallback + struct LocalTriangleSphereCastCallback : public btTriangleCallback { btTransform m_ccdSphereFromTrans; btTransform m_ccdSphereToTrans; - btTransform m_meshTransform; + btTransform m_meshTransform; - btScalar m_ccdSphereRadius; - btScalar m_hitFraction; - + btScalar m_ccdSphereRadius; + btScalar m_hitFraction; - LocalTriangleSphereCastCallback(const btTransform& from,const btTransform& to,btScalar ccdSphereRadius,btScalar hitFraction) - :m_ccdSphereFromTrans(from), - m_ccdSphereToTrans(to), - m_ccdSphereRadius(ccdSphereRadius), - m_hitFraction(hitFraction) - { + LocalTriangleSphereCastCallback(const btTransform& from, const btTransform& to, btScalar ccdSphereRadius, btScalar hitFraction) + : m_ccdSphereFromTrans(from), + m_ccdSphereToTrans(to), + m_ccdSphereRadius(ccdSphereRadius), + m_hitFraction(hitFraction) + { } - - + virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) { BT_PROFILE("processTriangle"); @@ -349,29 +321,23 @@ btScalar btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObj ident.setIdentity(); btConvexCast::CastResult castResult; castResult.m_fraction = m_hitFraction; - btSphereShape pointShape(m_ccdSphereRadius); - btTriangleShape triShape(triangle[0],triangle[1],triangle[2]); - btVoronoiSimplexSolver simplexSolver; - btSubsimplexConvexCast convexCaster(&pointShape,&triShape,&simplexSolver); + btSphereShape pointShape(m_ccdSphereRadius); + btTriangleShape triShape(triangle[0], triangle[1], triangle[2]); + btVoronoiSimplexSolver simplexSolver; + btSubsimplexConvexCast convexCaster(&pointShape, &triShape, &simplexSolver); //GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver); //ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0); //local space? - if (convexCaster.calcTimeOfImpact(m_ccdSphereFromTrans,m_ccdSphereToTrans, - ident,ident,castResult)) + if (convexCaster.calcTimeOfImpact(m_ccdSphereFromTrans, m_ccdSphereToTrans, + ident, ident, castResult)) { if (m_hitFraction > castResult.m_fraction) m_hitFraction = castResult.m_fraction; } - } - }; - - - - if (triBody->getCollisionShape()->isConcave()) { btVector3 rayAabbMin = convexFromLocal.getOrigin(); @@ -379,33 +345,30 @@ btScalar btConvexConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObj btVector3 rayAabbMax = convexFromLocal.getOrigin(); rayAabbMax.setMax(convexToLocal.getOrigin()); btScalar ccdRadius0 = convexbody->getCcdSweptSphereRadius(); - rayAabbMin -= btVector3(ccdRadius0,ccdRadius0,ccdRadius0); - rayAabbMax += btVector3(ccdRadius0,ccdRadius0,ccdRadius0); + rayAabbMin -= btVector3(ccdRadius0, ccdRadius0, ccdRadius0); + rayAabbMax += btVector3(ccdRadius0, ccdRadius0, ccdRadius0); - btScalar curHitFraction = btScalar(1.); //is this available? - LocalTriangleSphereCastCallback raycastCallback(convexFromLocal,convexToLocal, - convexbody->getCcdSweptSphereRadius(),curHitFraction); + btScalar curHitFraction = btScalar(1.); //is this available? + LocalTriangleSphereCastCallback raycastCallback(convexFromLocal, convexToLocal, + convexbody->getCcdSweptSphereRadius(), curHitFraction); raycastCallback.m_hitFraction = convexbody->getHitFraction(); btCollisionObject* concavebody = triBody; - btConcaveShape* triangleMesh = (btConcaveShape*) concavebody->getCollisionShape(); - + btConcaveShape* triangleMesh = (btConcaveShape*)concavebody->getCollisionShape(); + if (triangleMesh) { - triangleMesh->processAllTriangles(&raycastCallback,rayAabbMin,rayAabbMax); + triangleMesh->processAllTriangles(&raycastCallback, rayAabbMin, rayAabbMax); } - - if (raycastCallback.m_hitFraction < convexbody->getHitFraction()) { - convexbody->setHitFraction( raycastCallback.m_hitFraction); + convexbody->setHitFraction(raycastCallback.m_hitFraction); return raycastCallback.m_hitFraction; } } return btScalar(1.); - } diff --git a/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h index 93d842ef5..b72e40298 100644 --- a/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h +++ b/src/BulletCollision/CollisionDispatch/btConvexConcaveCollisionAlgorithm.h @@ -26,42 +26,40 @@ class btDispatcher; #include "btCollisionCreateFunc.h" ///For each triangle in the concave mesh that overlaps with the AABB of a convex (m_convexProxy), processTriangle is called. -ATTRIBUTE_ALIGNED16(class) btConvexTriangleCallback : public btTriangleCallback +ATTRIBUTE_ALIGNED16(class) +btConvexTriangleCallback : public btTriangleCallback { - - btVector3 m_aabbMin; - btVector3 m_aabbMax ; + btVector3 m_aabbMin; + btVector3 m_aabbMax; const btCollisionObjectWrapper* m_convexBodyWrap; const btCollisionObjectWrapper* m_triBodyWrap; - - btManifoldResult* m_resultOut; - btDispatcher* m_dispatcher; + btDispatcher* m_dispatcher; const btDispatcherInfo* m_dispatchInfoPtr; btScalar m_collisionMarginTriangle; - + public: BT_DECLARE_ALIGNED_ALLOCATOR(); - -int m_triangleCount; - - btPersistentManifold* m_manifoldPtr; - btConvexTriangleCallback(btDispatcher* dispatcher,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped); + int m_triangleCount; - void setTimeStepAndCounters(btScalar collisionMarginTriangle,const btDispatcherInfo& dispatchInfo,const btCollisionObjectWrapper* convexBodyWrap, const btCollisionObjectWrapper* triBodyWrap, btManifoldResult* resultOut); + btPersistentManifold* m_manifoldPtr; - void clearWrapperData() + btConvexTriangleCallback(btDispatcher * dispatcher, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, bool isSwapped); + + void setTimeStepAndCounters(btScalar collisionMarginTriangle, const btDispatcherInfo& dispatchInfo, const btCollisionObjectWrapper* convexBodyWrap, const btCollisionObjectWrapper* triBodyWrap, btManifoldResult* resultOut); + + void clearWrapperData() { m_convexBodyWrap = 0; m_triBodyWrap = 0; } virtual ~btConvexTriangleCallback(); - virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex); - + virtual void processTriangle(btVector3 * triangle, int partId, int triangleIndex); + void clearCache(); SIMD_FORCE_INLINE const btVector3& getAabbMin() const @@ -72,56 +70,48 @@ int m_triangleCount; { return m_aabbMax; } - }; - - - /// btConvexConcaveCollisionAlgorithm supports collision between convex shapes and (concave) trianges meshes. -ATTRIBUTE_ALIGNED16(class) btConvexConcaveCollisionAlgorithm : public btActivatingCollisionAlgorithm +ATTRIBUTE_ALIGNED16(class) +btConvexConcaveCollisionAlgorithm : public btActivatingCollisionAlgorithm { - btConvexTriangleCallback m_btConvexTriangleCallback; - bool m_isSwapped; - - + bool m_isSwapped; public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - - btConvexConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped); + + btConvexConcaveCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, bool isSwapped); virtual ~btConvexConcaveCollisionAlgorithm(); - virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + btScalar calculateTimeOfImpact(btCollisionObject * body0, btCollisionObject * body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual void getAllContactManifolds(btManifoldArray& manifoldArray); - - void clearCache(); + virtual void getAllContactManifolds(btManifoldArray & manifoldArray); - struct CreateFunc :public btCollisionAlgorithmCreateFunc + void clearCache(); + + struct CreateFunc : public btCollisionAlgorithmCreateFunc { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConcaveCollisionAlgorithm)); - return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0Wrap,body1Wrap,false); + return new (mem) btConvexConcaveCollisionAlgorithm(ci, body0Wrap, body1Wrap, false); } }; - struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc + struct SwappedCreateFunc : public btCollisionAlgorithmCreateFunc { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConcaveCollisionAlgorithm)); - return new(mem) btConvexConcaveCollisionAlgorithm(ci,body0Wrap,body1Wrap,true); + return new (mem) btConvexConcaveCollisionAlgorithm(ci, body0Wrap, body1Wrap, true); } }; - }; -#endif //BT_CONVEX_CONCAVE_COLLISION_ALGORITHM_H +#endif //BT_CONVEX_CONCAVE_COLLISION_ALGORITHM_H diff --git a/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp index 3e8bc6e42..5f447af2a 100644 --- a/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp +++ b/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.cpp @@ -30,8 +30,6 @@ subject to the following restrictions: #include "BulletCollision/CollisionShapes/btTriangleShape.h" #include "BulletCollision/CollisionShapes/btConvexPolyhedron.h" - - #include "BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h" #include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" @@ -43,8 +41,6 @@ subject to the following restrictions: #include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" #include "BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h" - - #include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" #include "BulletCollision/CollisionShapes/btSphereShape.h" @@ -57,8 +53,6 @@ subject to the following restrictions: /////////// - - static SIMD_FORCE_INLINE void segmentsClosestPoints( btVector3& ptsVector, btVector3& offsetA, @@ -66,43 +60,49 @@ static SIMD_FORCE_INLINE void segmentsClosestPoints( btScalar& tA, btScalar& tB, const btVector3& translation, const btVector3& dirA, btScalar hlenA, - const btVector3& dirB, btScalar hlenB ) + const btVector3& dirB, btScalar hlenB) { // compute the parameters of the closest points on each line segment - btScalar dirA_dot_dirB = btDot(dirA,dirB); - btScalar dirA_dot_trans = btDot(dirA,translation); - btScalar dirB_dot_trans = btDot(dirB,translation); + btScalar dirA_dot_dirB = btDot(dirA, dirB); + btScalar dirA_dot_trans = btDot(dirA, translation); + btScalar dirB_dot_trans = btDot(dirB, translation); btScalar denom = 1.0f - dirA_dot_dirB * dirA_dot_dirB; - if ( denom == 0.0f ) { + if (denom == 0.0f) + { tA = 0.0f; - } else { - tA = ( dirA_dot_trans - dirB_dot_trans * dirA_dot_dirB ) / denom; - if ( tA < -hlenA ) + } + else + { + tA = (dirA_dot_trans - dirB_dot_trans * dirA_dot_dirB) / denom; + if (tA < -hlenA) tA = -hlenA; - else if ( tA > hlenA ) + else if (tA > hlenA) tA = hlenA; } tB = tA * dirA_dot_dirB - dirB_dot_trans; - if ( tB < -hlenB ) { + if (tB < -hlenB) + { tB = -hlenB; tA = tB * dirA_dot_dirB + dirA_dot_trans; - if ( tA < -hlenA ) + if (tA < -hlenA) tA = -hlenA; - else if ( tA > hlenA ) + else if (tA > hlenA) tA = hlenA; - } else if ( tB > hlenB ) { + } + else if (tB > hlenB) + { tB = hlenB; tA = tB * dirA_dot_dirB + dirA_dot_trans; - if ( tA < -hlenA ) + if (tA < -hlenA) tA = -hlenA; - else if ( tA > hlenA ) + else if (tA > hlenA) tA = hlenA; } @@ -114,19 +114,18 @@ static SIMD_FORCE_INLINE void segmentsClosestPoints( ptsVector = translation - offsetA + offsetB; } - static SIMD_FORCE_INLINE btScalar capsuleCapsuleDistance( btVector3& normalOnB, btVector3& pointOnB, btScalar capsuleLengthA, - btScalar capsuleRadiusA, + btScalar capsuleRadiusA, btScalar capsuleLengthB, - btScalar capsuleRadiusB, + btScalar capsuleRadiusB, int capsuleAxisA, int capsuleAxisB, const btTransform& transformA, const btTransform& transformB, - btScalar distanceThreshold ) + btScalar distanceThreshold) { btVector3 directionA = transformA.getBasis().getColumn(capsuleAxisA); btVector3 translationA = transformA.getOrigin(); @@ -139,47 +138,38 @@ static SIMD_FORCE_INLINE btScalar capsuleCapsuleDistance( // compute the closest points of the capsule line segments - btVector3 ptsVector; // the vector between the closest points - - btVector3 offsetA, offsetB; // offsets from segment centers to their closest points - btScalar tA, tB; // parameters on line segment + btVector3 ptsVector; // the vector between the closest points - segmentsClosestPoints( ptsVector, offsetA, offsetB, tA, tB, translation, - directionA, capsuleLengthA, directionB, capsuleLengthB ); + btVector3 offsetA, offsetB; // offsets from segment centers to their closest points + btScalar tA, tB; // parameters on line segment + + segmentsClosestPoints(ptsVector, offsetA, offsetB, tA, tB, translation, + directionA, capsuleLengthA, directionB, capsuleLengthB); btScalar distance = ptsVector.length() - capsuleRadiusA - capsuleRadiusB; - if ( distance > distanceThreshold ) + if (distance > distanceThreshold) return distance; btScalar lenSqr = ptsVector.length2(); - if (lenSqr<= (SIMD_EPSILON*SIMD_EPSILON)) + if (lenSqr <= (SIMD_EPSILON * SIMD_EPSILON)) { //degenerate case where 2 capsules are likely at the same location: take a vector tangential to 'directionA' btVector3 q; - btPlaneSpace1(directionA,normalOnB,q); - } else + btPlaneSpace1(directionA, normalOnB, q); + } + else { // compute the contact normal - normalOnB = ptsVector*-btRecipSqrt(lenSqr); + normalOnB = ptsVector * -btRecipSqrt(lenSqr); } - pointOnB = transformB.getOrigin()+offsetB + normalOnB * capsuleRadiusB; + pointOnB = transformB.getOrigin() + offsetB + normalOnB * capsuleRadiusB; return distance; } - - - - - - ////////// - - - - btConvexConvexAlgorithm::CreateFunc::CreateFunc(btConvexPenetrationDepthSolver* pdSolver) { m_numPerturbationIterations = 0; @@ -187,30 +177,27 @@ btConvexConvexAlgorithm::CreateFunc::CreateFunc(btConvexPenetrationDepthSolver* m_pdSolver = pdSolver; } -btConvexConvexAlgorithm::CreateFunc::~CreateFunc() -{ +btConvexConvexAlgorithm::CreateFunc::~CreateFunc() +{ } -btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,btConvexPenetrationDepthSolver* pdSolver,int numPerturbationIterations, int minimumPointsPerturbationThreshold) -: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap), -m_pdSolver(pdSolver), -m_ownManifold (false), -m_manifoldPtr(mf), -m_lowLevelOfDetail(false), +btConvexConvexAlgorithm::btConvexConvexAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold) + : btActivatingCollisionAlgorithm(ci, body0Wrap, body1Wrap), + m_pdSolver(pdSolver), + m_ownManifold(false), + m_manifoldPtr(mf), + m_lowLevelOfDetail(false), #ifdef USE_SEPDISTANCE_UTIL2 -m_sepDistance((static_cast(body0->getCollisionShape()))->getAngularMotionDisc(), - (static_cast(body1->getCollisionShape()))->getAngularMotionDisc()), + m_sepDistance((static_cast(body0->getCollisionShape()))->getAngularMotionDisc(), + (static_cast(body1->getCollisionShape()))->getAngularMotionDisc()), #endif -m_numPerturbationIterations(numPerturbationIterations), -m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold) + m_numPerturbationIterations(numPerturbationIterations), + m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold) { (void)body0Wrap; (void)body1Wrap; } - - - btConvexConvexAlgorithm::~btConvexConvexAlgorithm() { if (m_ownManifold) @@ -220,112 +207,105 @@ btConvexConvexAlgorithm::~btConvexConvexAlgorithm() } } -void btConvexConvexAlgorithm ::setLowLevelOfDetail(bool useLowLevel) +void btConvexConvexAlgorithm ::setLowLevelOfDetail(bool useLowLevel) { m_lowLevelOfDetail = useLowLevel; } - struct btPerturbedContactResult : public btManifoldResult { btManifoldResult* m_originalManifoldResult; btTransform m_transformA; btTransform m_transformB; - btTransform m_unPerturbedTransform; - bool m_perturbA; - btIDebugDraw* m_debugDrawer; + btTransform m_unPerturbedTransform; + bool m_perturbA; + btIDebugDraw* m_debugDrawer; - - btPerturbedContactResult(btManifoldResult* originalResult,const btTransform& transformA,const btTransform& transformB,const btTransform& unPerturbedTransform,bool perturbA,btIDebugDraw* debugDrawer) - :m_originalManifoldResult(originalResult), - m_transformA(transformA), - m_transformB(transformB), - m_unPerturbedTransform(unPerturbedTransform), - m_perturbA(perturbA), - m_debugDrawer(debugDrawer) + btPerturbedContactResult(btManifoldResult* originalResult, const btTransform& transformA, const btTransform& transformB, const btTransform& unPerturbedTransform, bool perturbA, btIDebugDraw* debugDrawer) + : m_originalManifoldResult(originalResult), + m_transformA(transformA), + m_transformB(transformB), + m_unPerturbedTransform(unPerturbedTransform), + m_perturbA(perturbA), + m_debugDrawer(debugDrawer) { } - virtual ~ btPerturbedContactResult() + virtual ~btPerturbedContactResult() { } - virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar orgDepth) + virtual void addContactPoint(const btVector3& normalOnBInWorld, const btVector3& pointInWorld, btScalar orgDepth) { - btVector3 endPt,startPt; + btVector3 endPt, startPt; btScalar newDepth; btVector3 newNormal; if (m_perturbA) { - btVector3 endPtOrg = pointInWorld + normalOnBInWorld*orgDepth; - endPt = (m_unPerturbedTransform*m_transformA.inverse())(endPtOrg); - newDepth = (endPt - pointInWorld).dot(normalOnBInWorld); - startPt = endPt - normalOnBInWorld*newDepth; - } else + btVector3 endPtOrg = pointInWorld + normalOnBInWorld * orgDepth; + endPt = (m_unPerturbedTransform * m_transformA.inverse())(endPtOrg); + newDepth = (endPt - pointInWorld).dot(normalOnBInWorld); + startPt = endPt - normalOnBInWorld * newDepth; + } + else { - endPt = pointInWorld + normalOnBInWorld*orgDepth; - startPt = (m_unPerturbedTransform*m_transformB.inverse())(pointInWorld); - newDepth = (endPt - startPt).dot(normalOnBInWorld); - + endPt = pointInWorld + normalOnBInWorld * orgDepth; + startPt = (m_unPerturbedTransform * m_transformB.inverse())(pointInWorld); + newDepth = (endPt - startPt).dot(normalOnBInWorld); } //#define DEBUG_CONTACTS 1 #ifdef DEBUG_CONTACTS - m_debugDrawer->drawLine(startPt,endPt,btVector3(1,0,0)); - m_debugDrawer->drawSphere(startPt,0.05,btVector3(0,1,0)); - m_debugDrawer->drawSphere(endPt,0.05,btVector3(0,0,1)); -#endif //DEBUG_CONTACTS + m_debugDrawer->drawLine(startPt, endPt, btVector3(1, 0, 0)); + m_debugDrawer->drawSphere(startPt, 0.05, btVector3(0, 1, 0)); + m_debugDrawer->drawSphere(endPt, 0.05, btVector3(0, 0, 1)); +#endif //DEBUG_CONTACTS - - m_originalManifoldResult->addContactPoint(normalOnBInWorld,startPt,newDepth); + m_originalManifoldResult->addContactPoint(normalOnBInWorld, startPt, newDepth); } - }; extern btScalar gContactBreakingThreshold; - // // Convex-Convex collision algorithm // -void btConvexConvexAlgorithm ::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +void btConvexConvexAlgorithm ::processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { - if (!m_manifoldPtr) { //swapped? - m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject()); + m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(), body1Wrap->getCollisionObject()); m_ownManifold = true; } resultOut->setPersistentManifold(m_manifoldPtr); //comment-out next line to test multi-contact generation //resultOut->getPersistentManifold()->clearManifold(); - const btConvexShape* min0 = static_cast(body0Wrap->getCollisionShape()); const btConvexShape* min1 = static_cast(body1Wrap->getCollisionShape()); - btVector3 normalOnB; - btVector3 pointOnBWorld; + btVector3 normalOnB; + btVector3 pointOnBWorld; #ifndef BT_DISABLE_CAPSULE_CAPSULE_COLLIDER if ((min0->getShapeType() == CAPSULE_SHAPE_PROXYTYPE) && (min1->getShapeType() == CAPSULE_SHAPE_PROXYTYPE)) { //m_manifoldPtr->clearManifold(); - btCapsuleShape* capsuleA = (btCapsuleShape*) min0; - btCapsuleShape* capsuleB = (btCapsuleShape*) min1; - + btCapsuleShape* capsuleA = (btCapsuleShape*)min0; + btCapsuleShape* capsuleB = (btCapsuleShape*)min1; + btScalar threshold = m_manifoldPtr->getContactBreakingThreshold(); - btScalar dist = capsuleCapsuleDistance(normalOnB, pointOnBWorld,capsuleA->getHalfHeight(),capsuleA->getRadius(), - capsuleB->getHalfHeight(),capsuleB->getRadius(),capsuleA->getUpAxis(),capsuleB->getUpAxis(), - body0Wrap->getWorldTransform(),body1Wrap->getWorldTransform(),threshold); + btScalar dist = capsuleCapsuleDistance(normalOnB, pointOnBWorld, capsuleA->getHalfHeight(), capsuleA->getRadius(), + capsuleB->getHalfHeight(), capsuleB->getRadius(), capsuleA->getUpAxis(), capsuleB->getUpAxis(), + body0Wrap->getWorldTransform(), body1Wrap->getWorldTransform(), threshold); - if (dist=(SIMD_EPSILON*SIMD_EPSILON)); - resultOut->addContactPoint(normalOnB,pointOnBWorld,dist); + btAssert(normalOnB.length2() >= (SIMD_EPSILON * SIMD_EPSILON)); + resultOut->addContactPoint(normalOnB, pointOnBWorld, dist); } resultOut->refreshContactPoints(); return; @@ -335,19 +315,19 @@ void btConvexConvexAlgorithm ::processCollision (const btCollisionObjectWrapper* { //m_manifoldPtr->clearManifold(); - btCapsuleShape* capsuleA = (btCapsuleShape*) min0; - btSphereShape* capsuleB = (btSphereShape*) min1; - + btCapsuleShape* capsuleA = (btCapsuleShape*)min0; + btSphereShape* capsuleB = (btSphereShape*)min1; + btScalar threshold = m_manifoldPtr->getContactBreakingThreshold(); - btScalar dist = capsuleCapsuleDistance(normalOnB, pointOnBWorld,capsuleA->getHalfHeight(),capsuleA->getRadius(), - 0.,capsuleB->getRadius(),capsuleA->getUpAxis(),1, - body0Wrap->getWorldTransform(),body1Wrap->getWorldTransform(),threshold); + btScalar dist = capsuleCapsuleDistance(normalOnB, pointOnBWorld, capsuleA->getHalfHeight(), capsuleA->getRadius(), + 0., capsuleB->getRadius(), capsuleA->getUpAxis(), 1, + body0Wrap->getWorldTransform(), body1Wrap->getWorldTransform(), threshold); - if (dist=(SIMD_EPSILON*SIMD_EPSILON)); - resultOut->addContactPoint(normalOnB,pointOnBWorld,dist); + btAssert(normalOnB.length2() >= (SIMD_EPSILON * SIMD_EPSILON)); + resultOut->addContactPoint(normalOnB, pointOnBWorld, dist); } resultOut->refreshContactPoints(); return; @@ -357,252 +337,227 @@ void btConvexConvexAlgorithm ::processCollision (const btCollisionObjectWrapper* { //m_manifoldPtr->clearManifold(); - btSphereShape* capsuleA = (btSphereShape*) min0; - btCapsuleShape* capsuleB = (btCapsuleShape*) min1; - + btSphereShape* capsuleA = (btSphereShape*)min0; + btCapsuleShape* capsuleB = (btCapsuleShape*)min1; + btScalar threshold = m_manifoldPtr->getContactBreakingThreshold(); - btScalar dist = capsuleCapsuleDistance(normalOnB, pointOnBWorld,0.,capsuleA->getRadius(), - capsuleB->getHalfHeight(),capsuleB->getRadius(),1,capsuleB->getUpAxis(), - body0Wrap->getWorldTransform(),body1Wrap->getWorldTransform(),threshold); + btScalar dist = capsuleCapsuleDistance(normalOnB, pointOnBWorld, 0., capsuleA->getRadius(), + capsuleB->getHalfHeight(), capsuleB->getRadius(), 1, capsuleB->getUpAxis(), + body0Wrap->getWorldTransform(), body1Wrap->getWorldTransform(), threshold); - if (dist=(SIMD_EPSILON*SIMD_EPSILON)); - resultOut->addContactPoint(normalOnB,pointOnBWorld,dist); + btAssert(normalOnB.length2() >= (SIMD_EPSILON * SIMD_EPSILON)); + resultOut->addContactPoint(normalOnB, pointOnBWorld, dist); } resultOut->refreshContactPoints(); return; } -#endif //BT_DISABLE_CAPSULE_CAPSULE_COLLIDER - - - +#endif //BT_DISABLE_CAPSULE_CAPSULE_COLLIDER #ifdef USE_SEPDISTANCE_UTIL2 if (dispatchInfo.m_useConvexConservativeDistanceUtil) { - m_sepDistance.updateSeparatingDistance(body0->getWorldTransform(),body1->getWorldTransform()); + m_sepDistance.updateSeparatingDistance(body0->getWorldTransform(), body1->getWorldTransform()); } - if (!dispatchInfo.m_useConvexConservativeDistanceUtil || m_sepDistance.getConservativeSeparatingDistance()<=0.f) -#endif //USE_SEPDISTANCE_UTIL2 + if (!dispatchInfo.m_useConvexConservativeDistanceUtil || m_sepDistance.getConservativeSeparatingDistance() <= 0.f) +#endif //USE_SEPDISTANCE_UTIL2 { - - - btGjkPairDetector::ClosestPointInput input; - btVoronoiSimplexSolver simplexSolver; - btGjkPairDetector gjkPairDetector( min0, min1, &simplexSolver, m_pdSolver ); - //TODO: if (dispatchInfo.m_useContinuous) - gjkPairDetector.setMinkowskiA(min0); - gjkPairDetector.setMinkowskiB(min1); + btGjkPairDetector::ClosestPointInput input; + btVoronoiSimplexSolver simplexSolver; + btGjkPairDetector gjkPairDetector(min0, min1, &simplexSolver, m_pdSolver); + //TODO: if (dispatchInfo.m_useContinuous) + gjkPairDetector.setMinkowskiA(min0); + gjkPairDetector.setMinkowskiB(min1); #ifdef USE_SEPDISTANCE_UTIL2 - if (dispatchInfo.m_useConvexConservativeDistanceUtil) - { - input.m_maximumDistanceSquared = BT_LARGE_FLOAT; - } else -#endif //USE_SEPDISTANCE_UTIL2 - { - //if (dispatchInfo.m_convexMaxDistanceUseCPT) - //{ - // input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactProcessingThreshold(); - //} else - //{ - input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold()+resultOut->m_closestPointDistanceThreshold; -// } - - input.m_maximumDistanceSquared*= input.m_maximumDistanceSquared; - } - - input.m_transformA = body0Wrap->getWorldTransform(); - input.m_transformB = body1Wrap->getWorldTransform(); - - - - - -#ifdef USE_SEPDISTANCE_UTIL2 - btScalar sepDist = 0.f; - if (dispatchInfo.m_useConvexConservativeDistanceUtil) - { - sepDist = gjkPairDetector.getCachedSeparatingDistance(); - if (sepDist>SIMD_EPSILON) + if (dispatchInfo.m_useConvexConservativeDistanceUtil) { - sepDist += dispatchInfo.m_convexConservativeDistanceThreshold; - //now perturbe directions to get multiple contact points - + input.m_maximumDistanceSquared = BT_LARGE_FLOAT; } - } -#endif //USE_SEPDISTANCE_UTIL2 - - if (min0->isPolyhedral() && min1->isPolyhedral()) - { - - - struct btDummyResult : public btDiscreteCollisionDetectorInterface::Result + else +#endif //USE_SEPDISTANCE_UTIL2 { - btVector3 m_normalOnBInWorld; - btVector3 m_pointInWorld; - btScalar m_depth; - bool m_hasContact; - + //if (dispatchInfo.m_convexMaxDistanceUseCPT) + //{ + // input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactProcessingThreshold(); + //} else + //{ + input.m_maximumDistanceSquared = min0->getMargin() + min1->getMargin() + m_manifoldPtr->getContactBreakingThreshold() + resultOut->m_closestPointDistanceThreshold; + // } - btDummyResult() - : m_hasContact(false) - { - } - - - virtual void setShapeIdentifiersA(int partId0,int index0){} - virtual void setShapeIdentifiersB(int partId1,int index1){} - virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) - { - m_hasContact = true; - m_normalOnBInWorld = normalOnBInWorld; - m_pointInWorld = pointInWorld; - m_depth = depth; - } - }; + input.m_maximumDistanceSquared *= input.m_maximumDistanceSquared; + } - - struct btWithoutMarginResult : public btDiscreteCollisionDetectorInterface::Result + input.m_transformA = body0Wrap->getWorldTransform(); + input.m_transformB = body1Wrap->getWorldTransform(); + +#ifdef USE_SEPDISTANCE_UTIL2 + btScalar sepDist = 0.f; + if (dispatchInfo.m_useConvexConservativeDistanceUtil) { - btDiscreteCollisionDetectorInterface::Result* m_originalResult; - btVector3 m_reportedNormalOnWorld; - btScalar m_marginOnA; - btScalar m_marginOnB; - btScalar m_reportedDistance; - - bool m_foundResult; - btWithoutMarginResult(btDiscreteCollisionDetectorInterface::Result* result, btScalar marginOnA, btScalar marginOnB) - :m_originalResult(result), - m_marginOnA(marginOnA), - m_marginOnB(marginOnB), - m_foundResult(false) + sepDist = gjkPairDetector.getCachedSeparatingDistance(); + if (sepDist > SIMD_EPSILON) { + sepDist += dispatchInfo.m_convexConservativeDistanceThreshold; + //now perturbe directions to get multiple contact points } - - virtual void setShapeIdentifiersA(int partId0,int index0){} - virtual void setShapeIdentifiersB(int partId1,int index1){} - virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorldOrg,btScalar depthOrg) + } +#endif //USE_SEPDISTANCE_UTIL2 + + if (min0->isPolyhedral() && min1->isPolyhedral()) + { + struct btDummyResult : public btDiscreteCollisionDetectorInterface::Result { - m_reportedDistance = depthOrg; - m_reportedNormalOnWorld = normalOnBInWorld; - - btVector3 adjustedPointB = pointInWorldOrg - normalOnBInWorld*m_marginOnB; - m_reportedDistance = depthOrg+(m_marginOnA+m_marginOnB); - if (m_reportedDistance<0.f) + btVector3 m_normalOnBInWorld; + btVector3 m_pointInWorld; + btScalar m_depth; + bool m_hasContact; + + btDummyResult() + : m_hasContact(false) { - m_foundResult = true; } - m_originalResult->addContactPoint(normalOnBInWorld,adjustedPointB,m_reportedDistance); - } - }; - - btDummyResult dummy; - -///btBoxShape is an exception: its vertices are created WITH margin so don't subtract it - - btScalar min0Margin = min0->getShapeType()==BOX_SHAPE_PROXYTYPE? 0.f : min0->getMargin(); - btScalar min1Margin = min1->getShapeType()==BOX_SHAPE_PROXYTYPE? 0.f : min1->getMargin(); - - btWithoutMarginResult withoutMargin(resultOut, min0Margin,min1Margin); - - btPolyhedralConvexShape* polyhedronA = (btPolyhedralConvexShape*) min0; - btPolyhedralConvexShape* polyhedronB = (btPolyhedralConvexShape*) min1; - if (polyhedronA->getConvexPolyhedron() && polyhedronB->getConvexPolyhedron()) - { - - - - - btScalar threshold = m_manifoldPtr->getContactBreakingThreshold(); - - btScalar minDist = -1e30f; - btVector3 sepNormalWorldSpace; - bool foundSepAxis = true; - - if (dispatchInfo.m_enableSatConvex) - { - foundSepAxis = btPolyhedralContactClipping::findSeparatingAxis( - *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(), - body0Wrap->getWorldTransform(), - body1Wrap->getWorldTransform(), - sepNormalWorldSpace,*resultOut); - } else - { -#ifdef ZERO_MARGIN - gjkPairDetector.setIgnoreMargin(true); - gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); -#else - - - gjkPairDetector.getClosestPoints(input,withoutMargin,dispatchInfo.m_debugDraw); - //gjkPairDetector.getClosestPoints(input,dummy,dispatchInfo.m_debugDraw); -#endif //ZERO_MARGIN - //btScalar l2 = gjkPairDetector.getCachedSeparatingAxis().length2(); - //if (l2>SIMD_EPSILON) + virtual void setShapeIdentifiersA(int partId0, int index0) {} + virtual void setShapeIdentifiersB(int partId1, int index1) {} + virtual void addContactPoint(const btVector3& normalOnBInWorld, const btVector3& pointInWorld, btScalar depth) { - sepNormalWorldSpace = withoutMargin.m_reportedNormalOnWorld;//gjkPairDetector.getCachedSeparatingAxis()*(1.f/l2); - //minDist = -1e30f;//gjkPairDetector.getCachedSeparatingDistance(); - minDist = withoutMargin.m_reportedDistance;//gjkPairDetector.getCachedSeparatingDistance()+min0->getMargin()+min1->getMargin(); - -#ifdef ZERO_MARGIN - foundSepAxis = true;//gjkPairDetector.getCachedSeparatingDistance()<0.f; -#else - foundSepAxis = withoutMargin.m_foundResult && minDist<0;//-(min0->getMargin()+min1->getMargin()); -#endif + m_hasContact = true; + m_normalOnBInWorld = normalOnBInWorld; + m_pointInWorld = pointInWorld; + m_depth = depth; } - } - if (foundSepAxis) + }; + + struct btWithoutMarginResult : public btDiscreteCollisionDetectorInterface::Result { - -// printf("sepNormalWorldSpace=%f,%f,%f\n",sepNormalWorldSpace.getX(),sepNormalWorldSpace.getY(),sepNormalWorldSpace.getZ()); + btDiscreteCollisionDetectorInterface::Result* m_originalResult; + btVector3 m_reportedNormalOnWorld; + btScalar m_marginOnA; + btScalar m_marginOnB; + btScalar m_reportedDistance; - worldVertsB1.resize(0); - btPolyhedralContactClipping::clipHullAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(), - body0Wrap->getWorldTransform(), - body1Wrap->getWorldTransform(), minDist-threshold, threshold, worldVertsB1,worldVertsB2, - *resultOut); - - } - if (m_ownManifold) + bool m_foundResult; + btWithoutMarginResult(btDiscreteCollisionDetectorInterface::Result* result, btScalar marginOnA, btScalar marginOnB) + : m_originalResult(result), + m_marginOnA(marginOnA), + m_marginOnB(marginOnB), + m_foundResult(false) + { + } + + virtual void setShapeIdentifiersA(int partId0, int index0) {} + virtual void setShapeIdentifiersB(int partId1, int index1) {} + virtual void addContactPoint(const btVector3& normalOnBInWorld, const btVector3& pointInWorldOrg, btScalar depthOrg) + { + m_reportedDistance = depthOrg; + m_reportedNormalOnWorld = normalOnBInWorld; + + btVector3 adjustedPointB = pointInWorldOrg - normalOnBInWorld * m_marginOnB; + m_reportedDistance = depthOrg + (m_marginOnA + m_marginOnB); + if (m_reportedDistance < 0.f) + { + m_foundResult = true; + } + m_originalResult->addContactPoint(normalOnBInWorld, adjustedPointB, m_reportedDistance); + } + }; + + btDummyResult dummy; + + ///btBoxShape is an exception: its vertices are created WITH margin so don't subtract it + + btScalar min0Margin = min0->getShapeType() == BOX_SHAPE_PROXYTYPE ? 0.f : min0->getMargin(); + btScalar min1Margin = min1->getShapeType() == BOX_SHAPE_PROXYTYPE ? 0.f : min1->getMargin(); + + btWithoutMarginResult withoutMargin(resultOut, min0Margin, min1Margin); + + btPolyhedralConvexShape* polyhedronA = (btPolyhedralConvexShape*)min0; + btPolyhedralConvexShape* polyhedronB = (btPolyhedralConvexShape*)min1; + if (polyhedronA->getConvexPolyhedron() && polyhedronB->getConvexPolyhedron()) { - resultOut->refreshContactPoints(); - } - return; - - } else - { - - - //we can also deal with convex versus triangle (without connectivity data) - if (dispatchInfo.m_enableSatConvex && polyhedronA->getConvexPolyhedron() && polyhedronB->getShapeType()==TRIANGLE_SHAPE_PROXYTYPE) - { - - - btVertexArray worldSpaceVertices; - btTriangleShape* tri = (btTriangleShape*)polyhedronB; - worldSpaceVertices.push_back( body1Wrap->getWorldTransform()*tri->m_vertices1[0]); - worldSpaceVertices.push_back( body1Wrap->getWorldTransform()*tri->m_vertices1[1]); - worldSpaceVertices.push_back( body1Wrap->getWorldTransform()*tri->m_vertices1[2]); - - //tri->initializePolyhedralFeatures(); - btScalar threshold = m_manifoldPtr->getContactBreakingThreshold(); + btScalar minDist = -1e30f; btVector3 sepNormalWorldSpace; - btScalar minDist =-1e30f; - btScalar maxDist = threshold; - - bool foundSepAxis = false; - bool useSatSepNormal = true; + bool foundSepAxis = true; - if (useSatSepNormal) + if (dispatchInfo.m_enableSatConvex) { + foundSepAxis = btPolyhedralContactClipping::findSeparatingAxis( + *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(), + body0Wrap->getWorldTransform(), + body1Wrap->getWorldTransform(), + sepNormalWorldSpace, *resultOut); + } + else + { +#ifdef ZERO_MARGIN + gjkPairDetector.setIgnoreMargin(true); + gjkPairDetector.getClosestPoints(input, *resultOut, dispatchInfo.m_debugDraw); +#else + + gjkPairDetector.getClosestPoints(input, withoutMargin, dispatchInfo.m_debugDraw); + //gjkPairDetector.getClosestPoints(input,dummy,dispatchInfo.m_debugDraw); +#endif //ZERO_MARGIN \ + //btScalar l2 = gjkPairDetector.getCachedSeparatingAxis().length2(); \ + //if (l2>SIMD_EPSILON) + { + sepNormalWorldSpace = withoutMargin.m_reportedNormalOnWorld; //gjkPairDetector.getCachedSeparatingAxis()*(1.f/l2); + //minDist = -1e30f;//gjkPairDetector.getCachedSeparatingDistance(); + minDist = withoutMargin.m_reportedDistance; //gjkPairDetector.getCachedSeparatingDistance()+min0->getMargin()+min1->getMargin(); + +#ifdef ZERO_MARGIN + foundSepAxis = true; //gjkPairDetector.getCachedSeparatingDistance()<0.f; +#else + foundSepAxis = withoutMargin.m_foundResult && minDist < 0; //-(min0->getMargin()+min1->getMargin()); +#endif + } + } + if (foundSepAxis) + { + // printf("sepNormalWorldSpace=%f,%f,%f\n",sepNormalWorldSpace.getX(),sepNormalWorldSpace.getY(),sepNormalWorldSpace.getZ()); + + worldVertsB1.resize(0); + btPolyhedralContactClipping::clipHullAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(), + body0Wrap->getWorldTransform(), + body1Wrap->getWorldTransform(), minDist - threshold, threshold, worldVertsB1, worldVertsB2, + *resultOut); + } + if (m_ownManifold) + { + resultOut->refreshContactPoints(); + } + return; + } + else + { + //we can also deal with convex versus triangle (without connectivity data) + if (dispatchInfo.m_enableSatConvex && polyhedronA->getConvexPolyhedron() && polyhedronB->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE) + { + btVertexArray worldSpaceVertices; + btTriangleShape* tri = (btTriangleShape*)polyhedronB; + worldSpaceVertices.push_back(body1Wrap->getWorldTransform() * tri->m_vertices1[0]); + worldSpaceVertices.push_back(body1Wrap->getWorldTransform() * tri->m_vertices1[1]); + worldSpaceVertices.push_back(body1Wrap->getWorldTransform() * tri->m_vertices1[2]); + + //tri->initializePolyhedralFeatures(); + + btScalar threshold = m_manifoldPtr->getContactBreakingThreshold(); + + btVector3 sepNormalWorldSpace; + btScalar minDist = -1e30f; + btScalar maxDist = threshold; + + bool foundSepAxis = false; + bool useSatSepNormal = true; + + if (useSatSepNormal) + { #if 0 if (0) { @@ -610,113 +565,107 @@ void btConvexConvexAlgorithm ::processCollision (const btCollisionObjectWrapper* polyhedronB->initializePolyhedralFeatures(); } else #endif - { - - btVector3 uniqueEdges[3] = {tri->m_vertices1[1]-tri->m_vertices1[0], - tri->m_vertices1[2]-tri->m_vertices1[1], - tri->m_vertices1[0]-tri->m_vertices1[2]}; - - uniqueEdges[0].normalize(); - uniqueEdges[1].normalize(); - uniqueEdges[2].normalize(); - - btConvexPolyhedron polyhedron; - polyhedron.m_vertices.push_back(tri->m_vertices1[2]); - polyhedron.m_vertices.push_back(tri->m_vertices1[0]); - polyhedron.m_vertices.push_back(tri->m_vertices1[1]); - - { - btFace combinedFaceA; - combinedFaceA.m_indices.push_back(0); - combinedFaceA.m_indices.push_back(1); - combinedFaceA.m_indices.push_back(2); - btVector3 faceNormal = uniqueEdges[0].cross(uniqueEdges[1]); - faceNormal.normalize(); - btScalar planeEq=1e30f; - for (int v=0;vm_vertices1[1] - tri->m_vertices1[0], + tri->m_vertices1[2] - tri->m_vertices1[1], + tri->m_vertices1[0] - tri->m_vertices1[2]}; + + uniqueEdges[0].normalize(); + uniqueEdges[1].normalize(); + uniqueEdges[2].normalize(); + + btConvexPolyhedron polyhedron; + polyhedron.m_vertices.push_back(tri->m_vertices1[2]); + polyhedron.m_vertices.push_back(tri->m_vertices1[0]); + polyhedron.m_vertices.push_back(tri->m_vertices1[1]); + { - btScalar eq = tri->m_vertices1[combinedFaceA.m_indices[v]].dot(faceNormal); - if (planeEq>eq) + btFace combinedFaceA; + combinedFaceA.m_indices.push_back(0); + combinedFaceA.m_indices.push_back(1); + combinedFaceA.m_indices.push_back(2); + btVector3 faceNormal = uniqueEdges[0].cross(uniqueEdges[1]); + faceNormal.normalize(); + btScalar planeEq = 1e30f; + for (int v = 0; v < combinedFaceA.m_indices.size(); v++) { - planeEq=eq; + btScalar eq = tri->m_vertices1[combinedFaceA.m_indices[v]].dot(faceNormal); + if (planeEq > eq) + { + planeEq = eq; + } } + combinedFaceA.m_plane[0] = faceNormal[0]; + combinedFaceA.m_plane[1] = faceNormal[1]; + combinedFaceA.m_plane[2] = faceNormal[2]; + combinedFaceA.m_plane[3] = -planeEq; + polyhedron.m_faces.push_back(combinedFaceA); } - combinedFaceA.m_plane[0] = faceNormal[0]; - combinedFaceA.m_plane[1] = faceNormal[1]; - combinedFaceA.m_plane[2] = faceNormal[2]; - combinedFaceA.m_plane[3] = -planeEq; - polyhedron.m_faces.push_back(combinedFaceA); - } - { - btFace combinedFaceB; - combinedFaceB.m_indices.push_back(0); - combinedFaceB.m_indices.push_back(2); - combinedFaceB.m_indices.push_back(1); - btVector3 faceNormal = -uniqueEdges[0].cross(uniqueEdges[1]); - faceNormal.normalize(); - btScalar planeEq=1e30f; - for (int v=0;vm_vertices1[combinedFaceB.m_indices[v]].dot(faceNormal); - if (planeEq>eq) + btFace combinedFaceB; + combinedFaceB.m_indices.push_back(0); + combinedFaceB.m_indices.push_back(2); + combinedFaceB.m_indices.push_back(1); + btVector3 faceNormal = -uniqueEdges[0].cross(uniqueEdges[1]); + faceNormal.normalize(); + btScalar planeEq = 1e30f; + for (int v = 0; v < combinedFaceB.m_indices.size(); v++) { - planeEq=eq; + btScalar eq = tri->m_vertices1[combinedFaceB.m_indices[v]].dot(faceNormal); + if (planeEq > eq) + { + planeEq = eq; + } } + + combinedFaceB.m_plane[0] = faceNormal[0]; + combinedFaceB.m_plane[1] = faceNormal[1]; + combinedFaceB.m_plane[2] = faceNormal[2]; + combinedFaceB.m_plane[3] = -planeEq; + polyhedron.m_faces.push_back(combinedFaceB); } - combinedFaceB.m_plane[0] = faceNormal[0]; - combinedFaceB.m_plane[1] = faceNormal[1]; - combinedFaceB.m_plane[2] = faceNormal[2]; - combinedFaceB.m_plane[3] = -planeEq; - polyhedron.m_faces.push_back(combinedFaceB); + polyhedron.m_uniqueEdges.push_back(uniqueEdges[0]); + polyhedron.m_uniqueEdges.push_back(uniqueEdges[1]); + polyhedron.m_uniqueEdges.push_back(uniqueEdges[2]); + polyhedron.initialize2(); + + polyhedronB->setPolyhedralFeatures(polyhedron); } - - polyhedron.m_uniqueEdges.push_back(uniqueEdges[0]); - polyhedron.m_uniqueEdges.push_back(uniqueEdges[1]); - polyhedron.m_uniqueEdges.push_back(uniqueEdges[2]); - polyhedron.initialize2(); - - polyhedronB->setPolyhedralFeatures(polyhedron); + foundSepAxis = btPolyhedralContactClipping::findSeparatingAxis( + *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(), + body0Wrap->getWorldTransform(), + body1Wrap->getWorldTransform(), + sepNormalWorldSpace, *resultOut); + // printf("sepNormalWorldSpace=%f,%f,%f\n",sepNormalWorldSpace.getX(),sepNormalWorldSpace.getY(),sepNormalWorldSpace.getZ()); } - - - - foundSepAxis = btPolyhedralContactClipping::findSeparatingAxis( - *polyhedronA->getConvexPolyhedron(), *polyhedronB->getConvexPolyhedron(), - body0Wrap->getWorldTransform(), - body1Wrap->getWorldTransform(), - sepNormalWorldSpace,*resultOut); - // printf("sepNormalWorldSpace=%f,%f,%f\n",sepNormalWorldSpace.getX(),sepNormalWorldSpace.getY(),sepNormalWorldSpace.getZ()); - - } - else - { + else + { #ifdef ZERO_MARGIN - gjkPairDetector.setIgnoreMargin(true); - gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); + gjkPairDetector.setIgnoreMargin(true); + gjkPairDetector.getClosestPoints(input, *resultOut, dispatchInfo.m_debugDraw); #else - gjkPairDetector.getClosestPoints(input,dummy,dispatchInfo.m_debugDraw); -#endif//ZERO_MARGIN - - if (dummy.m_hasContact && dummy.m_depth<0) - { - - if (foundSepAxis) + gjkPairDetector.getClosestPoints(input, dummy, dispatchInfo.m_debugDraw); +#endif //ZERO_MARGIN + + if (dummy.m_hasContact && dummy.m_depth < 0) { - if (dummy.m_normalOnBInWorld.dot(sepNormalWorldSpace)<0.99) + if (foundSepAxis) { - printf("?\n"); + if (dummy.m_normalOnBInWorld.dot(sepNormalWorldSpace) < 0.99) + { + printf("?\n"); + } } - } else - { - printf("!\n"); + else + { + printf("!\n"); + } + sepNormalWorldSpace.setValue(0, 0, 1); // = dummy.m_normalOnBInWorld; + //minDist = dummy.m_depth; + foundSepAxis = true; } - sepNormalWorldSpace.setValue(0,0,1);// = dummy.m_normalOnBInWorld; - //minDist = dummy.m_depth; - foundSepAxis = true; - } #if 0 btScalar l2 = gjkPairDetector.getCachedSeparatingAxis().length2(); if (l2>SIMD_EPSILON) @@ -728,145 +677,131 @@ void btConvexConvexAlgorithm ::processCollision (const btCollisionObjectWrapper* foundSepAxis = true; } #endif - } + } - - if (foundSepAxis) - { - worldVertsB2.resize(0); - btPolyhedralContactClipping::clipFaceAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), - body0Wrap->getWorldTransform(), worldSpaceVertices, worldVertsB2,minDist-threshold, maxDist, *resultOut); - } - - - if (m_ownManifold) - { - resultOut->refreshContactPoints(); - } - - return; - } + if (foundSepAxis) + { + worldVertsB2.resize(0); + btPolyhedralContactClipping::clipFaceAgainstHull(sepNormalWorldSpace, *polyhedronA->getConvexPolyhedron(), + body0Wrap->getWorldTransform(), worldSpaceVertices, worldVertsB2, minDist - threshold, maxDist, *resultOut); + } - + if (m_ownManifold) + { + resultOut->refreshContactPoints(); + } + + return; + } + } } + gjkPairDetector.getClosestPoints(input, *resultOut, dispatchInfo.m_debugDraw); - } - - gjkPairDetector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw); + //now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects - //now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects - - //perform perturbation when more then 'm_minimumPointsPerturbationThreshold' points - if (m_numPerturbationIterations && resultOut->getPersistentManifold()->getNumContacts() < m_minimumPointsPerturbationThreshold) - { - - int i; - btVector3 v0,v1; - btVector3 sepNormalWorldSpace; - btScalar l2 = gjkPairDetector.getCachedSeparatingAxis().length2(); - - if (l2>SIMD_EPSILON) + //perform perturbation when more then 'm_minimumPointsPerturbationThreshold' points + if (m_numPerturbationIterations && resultOut->getPersistentManifold()->getNumContacts() < m_minimumPointsPerturbationThreshold) { - sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis()*(1.f/l2); - - btPlaneSpace1(sepNormalWorldSpace,v0,v1); + int i; + btVector3 v0, v1; + btVector3 sepNormalWorldSpace; + btScalar l2 = gjkPairDetector.getCachedSeparatingAxis().length2(); + if (l2 > SIMD_EPSILON) + { + sepNormalWorldSpace = gjkPairDetector.getCachedSeparatingAxis() * (1.f / l2); - bool perturbeA = true; - const btScalar angleLimit = 0.125f * SIMD_PI; - btScalar perturbeAngle; - btScalar radiusA = min0->getAngularMotionDisc(); - btScalar radiusB = min1->getAngularMotionDisc(); - if (radiusA < radiusB) - { - perturbeAngle = gContactBreakingThreshold /radiusA; - perturbeA = true; - } else - { - perturbeAngle = gContactBreakingThreshold / radiusB; - perturbeA = false; - } - if ( perturbeAngle > angleLimit ) + btPlaneSpace1(sepNormalWorldSpace, v0, v1); + + bool perturbeA = true; + const btScalar angleLimit = 0.125f * SIMD_PI; + btScalar perturbeAngle; + btScalar radiusA = min0->getAngularMotionDisc(); + btScalar radiusB = min1->getAngularMotionDisc(); + if (radiusA < radiusB) + { + perturbeAngle = gContactBreakingThreshold / radiusA; + perturbeA = true; + } + else + { + perturbeAngle = gContactBreakingThreshold / radiusB; + perturbeA = false; + } + if (perturbeAngle > angleLimit) perturbeAngle = angleLimit; - btTransform unPerturbedTransform; - if (perturbeA) - { - unPerturbedTransform = input.m_transformA; - } else - { - unPerturbedTransform = input.m_transformB; - } - - for ( i=0;iSIMD_EPSILON) - { - btQuaternion perturbeRot(v0,perturbeAngle); - btScalar iterationAngle = i*(SIMD_2_PI/btScalar(m_numPerturbationIterations)); - btQuaternion rotq(sepNormalWorldSpace,iterationAngle); - - + btTransform unPerturbedTransform; if (perturbeA) { - input.m_transformA.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body0Wrap->getWorldTransform().getBasis()); - input.m_transformB = body1Wrap->getWorldTransform(); - #ifdef DEBUG_CONTACTS - dispatchInfo.m_debugDraw->drawTransform(input.m_transformA,10.0); - #endif //DEBUG_CONTACTS - } else - { - input.m_transformA = body0Wrap->getWorldTransform(); - input.m_transformB.setBasis( btMatrix3x3(rotq.inverse()*perturbeRot*rotq)*body1Wrap->getWorldTransform().getBasis()); - #ifdef DEBUG_CONTACTS - dispatchInfo.m_debugDraw->drawTransform(input.m_transformB,10.0); - #endif + unPerturbedTransform = input.m_transformA; } - - btPerturbedContactResult perturbedResultOut(resultOut,input.m_transformA,input.m_transformB,unPerturbedTransform,perturbeA,dispatchInfo.m_debugDraw); - gjkPairDetector.getClosestPoints(input,perturbedResultOut,dispatchInfo.m_debugDraw); + else + { + unPerturbedTransform = input.m_transformB; + } + + for (i = 0; i < m_numPerturbationIterations; i++) + { + if (v0.length2() > SIMD_EPSILON) + { + btQuaternion perturbeRot(v0, perturbeAngle); + btScalar iterationAngle = i * (SIMD_2_PI / btScalar(m_numPerturbationIterations)); + btQuaternion rotq(sepNormalWorldSpace, iterationAngle); + + if (perturbeA) + { + input.m_transformA.setBasis(btMatrix3x3(rotq.inverse() * perturbeRot * rotq) * body0Wrap->getWorldTransform().getBasis()); + input.m_transformB = body1Wrap->getWorldTransform(); +#ifdef DEBUG_CONTACTS + dispatchInfo.m_debugDraw->drawTransform(input.m_transformA, 10.0); +#endif //DEBUG_CONTACTS + } + else + { + input.m_transformA = body0Wrap->getWorldTransform(); + input.m_transformB.setBasis(btMatrix3x3(rotq.inverse() * perturbeRot * rotq) * body1Wrap->getWorldTransform().getBasis()); +#ifdef DEBUG_CONTACTS + dispatchInfo.m_debugDraw->drawTransform(input.m_transformB, 10.0); +#endif + } + + btPerturbedContactResult perturbedResultOut(resultOut, input.m_transformA, input.m_transformB, unPerturbedTransform, perturbeA, dispatchInfo.m_debugDraw); + gjkPairDetector.getClosestPoints(input, perturbedResultOut, dispatchInfo.m_debugDraw); + } } } } - } - - #ifdef USE_SEPDISTANCE_UTIL2 - if (dispatchInfo.m_useConvexConservativeDistanceUtil && (sepDist>SIMD_EPSILON)) - { - m_sepDistance.initSeparatingDistance(gjkPairDetector.getCachedSeparatingAxis(),sepDist,body0->getWorldTransform(),body1->getWorldTransform()); - } -#endif //USE_SEPDISTANCE_UTIL2 - - + if (dispatchInfo.m_useConvexConservativeDistanceUtil && (sepDist > SIMD_EPSILON)) + { + m_sepDistance.initSeparatingDistance(gjkPairDetector.getCachedSeparatingAxis(), sepDist, body0->getWorldTransform(), body1->getWorldTransform()); + } +#endif //USE_SEPDISTANCE_UTIL2 } if (m_ownManifold) { resultOut->refreshContactPoints(); } - } - - bool disableCcd = false; -btScalar btConvexConvexAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +btScalar btConvexConvexAlgorithm::calculateTimeOfImpact(btCollisionObject* col0, btCollisionObject* col1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { (void)resultOut; (void)dispatchInfo; ///Rather then checking ALL pairs, only calculate TOI when motion exceeds threshold - + ///Linear motion for one of objects needs to exceed m_ccdSquareMotionThreshold ///col0->m_worldTransform, btScalar resultFraction = btScalar(1.); - btScalar squareMot0 = (col0->getInterpolationWorldTransform().getOrigin() - col0->getWorldTransform().getOrigin()).length2(); btScalar squareMot1 = (col1->getInterpolationWorldTransform().getOrigin() - col1->getWorldTransform().getOrigin()).length2(); - + if (squareMot0 < col0->getCcdSquareMotionThreshold() && squareMot1 < col1->getCcdSquareMotionThreshold()) return resultFraction; @@ -874,77 +809,65 @@ btScalar btConvexConvexAlgorithm::calculateTimeOfImpact(btCollisionObject* col0, if (disableCcd) return btScalar(1.); - //An adhoc way of testing the Continuous Collision Detection algorithms //One object is approximated as a sphere, to simplify things //Starting in penetration should report no time of impact //For proper CCD, better accuracy and handling of 'allowed' penetration should be added //also the mainloop of the physics should have a kind of toi queue (something like Brian Mirtich's application of Timewarp for Rigidbodies) - /// Convex0 against sphere for Convex1 { btConvexShape* convex0 = static_cast(col0->getCollisionShape()); - btSphereShape sphere1(col1->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation + btSphereShape sphere1(col1->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation btConvexCast::CastResult result; btVoronoiSimplexSolver voronoiSimplex; //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex); ///Simplification, one object is simplified as a sphere - btGjkConvexCast ccd1( convex0 ,&sphere1,&voronoiSimplex); + btGjkConvexCast ccd1(convex0, &sphere1, &voronoiSimplex); //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0); - if (ccd1.calcTimeOfImpact(col0->getWorldTransform(),col0->getInterpolationWorldTransform(), - col1->getWorldTransform(),col1->getInterpolationWorldTransform(),result)) + if (ccd1.calcTimeOfImpact(col0->getWorldTransform(), col0->getInterpolationWorldTransform(), + col1->getWorldTransform(), col1->getInterpolationWorldTransform(), result)) { - //store result.m_fraction in both bodies - - if (col0->getHitFraction()> result.m_fraction) - col0->setHitFraction( result.m_fraction ); + + if (col0->getHitFraction() > result.m_fraction) + col0->setHitFraction(result.m_fraction); if (col1->getHitFraction() > result.m_fraction) - col1->setHitFraction( result.m_fraction); + col1->setHitFraction(result.m_fraction); if (resultFraction > result.m_fraction) resultFraction = result.m_fraction; - } - - - - } /// Sphere (for convex0) against Convex1 { btConvexShape* convex1 = static_cast(col1->getCollisionShape()); - btSphereShape sphere0(col0->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation + btSphereShape sphere0(col0->getCcdSweptSphereRadius()); //todo: allow non-zero sphere sizes, for better approximation btConvexCast::CastResult result; btVoronoiSimplexSolver voronoiSimplex; //SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex); ///Simplification, one object is simplified as a sphere - btGjkConvexCast ccd1(&sphere0,convex1,&voronoiSimplex); + btGjkConvexCast ccd1(&sphere0, convex1, &voronoiSimplex); //ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0); - if (ccd1.calcTimeOfImpact(col0->getWorldTransform(),col0->getInterpolationWorldTransform(), - col1->getWorldTransform(),col1->getInterpolationWorldTransform(),result)) + if (ccd1.calcTimeOfImpact(col0->getWorldTransform(), col0->getInterpolationWorldTransform(), + col1->getWorldTransform(), col1->getInterpolationWorldTransform(), result)) { - //store result.m_fraction in both bodies - - if (col0->getHitFraction() > result.m_fraction) - col0->setHitFraction( result.m_fraction); + + if (col0->getHitFraction() > result.m_fraction) + col0->setHitFraction(result.m_fraction); if (col1->getHitFraction() > result.m_fraction) - col1->setHitFraction( result.m_fraction); + col1->setHitFraction(result.m_fraction); if (resultFraction > result.m_fraction) resultFraction = result.m_fraction; - } } - + return resultFraction; - } - diff --git a/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h b/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h index cd75ba12d..eac5b4d82 100644 --- a/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h +++ b/src/BulletCollision/CollisionDispatch/btConvexConvexAlgorithm.h @@ -23,7 +23,7 @@ subject to the following restrictions: #include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" #include "btCollisionCreateFunc.h" #include "btCollisionDispatcher.h" -#include "LinearMath/btTransformUtil.h" //for btConvexSeparatingDistanceUtil +#include "LinearMath/btTransformUtil.h" //for btConvexSeparatingDistanceUtil #include "BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h" class btConvexPenetrationDepthSolver; @@ -41,69 +41,61 @@ class btConvexPenetrationDepthSolver; class btConvexConvexAlgorithm : public btActivatingCollisionAlgorithm { #ifdef USE_SEPDISTANCE_UTIL2 - btConvexSeparatingDistanceUtil m_sepDistance; + btConvexSeparatingDistanceUtil m_sepDistance; #endif btConvexPenetrationDepthSolver* m_pdSolver; btVertexArray worldVertsB1; btVertexArray worldVertsB2; - - bool m_ownManifold; - btPersistentManifold* m_manifoldPtr; - bool m_lowLevelOfDetail; - + + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + bool m_lowLevelOfDetail; + int m_numPerturbationIterations; int m_minimumPointsPerturbationThreshold; - ///cache separating vector to speedup collision detection - public: - - btConvexConvexAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold); + btConvexConvexAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, btConvexPenetrationDepthSolver* pdSolver, int numPerturbationIterations, int minimumPointsPerturbationThreshold); virtual ~btConvexConvexAlgorithm(); - virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) { ///should we use m_ownManifold to avoid adding duplicates? if (m_manifoldPtr && m_ownManifold) manifoldArray.push_back(m_manifoldPtr); } + void setLowLevelOfDetail(bool useLowLevel); - void setLowLevelOfDetail(bool useLowLevel); - - - const btPersistentManifold* getManifold() + const btPersistentManifold* getManifold() { return m_manifoldPtr; } - struct CreateFunc :public btCollisionAlgorithmCreateFunc + struct CreateFunc : public btCollisionAlgorithmCreateFunc { - - btConvexPenetrationDepthSolver* m_pdSolver; + btConvexPenetrationDepthSolver* m_pdSolver; int m_numPerturbationIterations; int m_minimumPointsPerturbationThreshold; CreateFunc(btConvexPenetrationDepthSolver* pdSolver); - + virtual ~CreateFunc(); - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btConvexConvexAlgorithm)); - return new(mem) btConvexConvexAlgorithm(ci.m_manifold,ci,body0Wrap,body1Wrap,m_pdSolver,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold); + return new (mem) btConvexConvexAlgorithm(ci.m_manifold, ci, body0Wrap, body1Wrap, m_pdSolver, m_numPerturbationIterations, m_minimumPointsPerturbationThreshold); } }; - - }; -#endif //BT_CONVEX_CONVEX_ALGORITHM_H +#endif //BT_CONVEX_CONVEX_ALGORITHM_H diff --git a/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp index cce2d95bc..994609ab0 100644 --- a/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp +++ b/src/BulletCollision/CollisionDispatch/btConvexPlaneCollisionAlgorithm.cpp @@ -23,25 +23,24 @@ subject to the following restrictions: //#include -btConvexPlaneCollisionAlgorithm::btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap, bool isSwapped, int numPerturbationIterations,int minimumPointsPerturbationThreshold) -: btCollisionAlgorithm(ci), -m_ownManifold(false), -m_manifoldPtr(mf), -m_isSwapped(isSwapped), -m_numPerturbationIterations(numPerturbationIterations), -m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold) +btConvexPlaneCollisionAlgorithm::btConvexPlaneCollisionAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* col0Wrap, const btCollisionObjectWrapper* col1Wrap, bool isSwapped, int numPerturbationIterations, int minimumPointsPerturbationThreshold) + : btCollisionAlgorithm(ci), + m_ownManifold(false), + m_manifoldPtr(mf), + m_isSwapped(isSwapped), + m_numPerturbationIterations(numPerturbationIterations), + m_minimumPointsPerturbationThreshold(minimumPointsPerturbationThreshold) { - const btCollisionObjectWrapper* convexObjWrap = m_isSwapped? col1Wrap : col0Wrap; - const btCollisionObjectWrapper* planeObjWrap = m_isSwapped? col0Wrap : col1Wrap; + const btCollisionObjectWrapper* convexObjWrap = m_isSwapped ? col1Wrap : col0Wrap; + const btCollisionObjectWrapper* planeObjWrap = m_isSwapped ? col0Wrap : col1Wrap; - if (!m_manifoldPtr && m_dispatcher->needsCollision(convexObjWrap->getCollisionObject(),planeObjWrap->getCollisionObject())) + if (!m_manifoldPtr && m_dispatcher->needsCollision(convexObjWrap->getCollisionObject(), planeObjWrap->getCollisionObject())) { - m_manifoldPtr = m_dispatcher->getNewManifold(convexObjWrap->getCollisionObject(),planeObjWrap->getCollisionObject()); + m_manifoldPtr = m_dispatcher->getNewManifold(convexObjWrap->getCollisionObject(), planeObjWrap->getCollisionObject()); m_ownManifold = true; } } - btConvexPlaneCollisionAlgorithm::~btConvexPlaneCollisionAlgorithm() { if (m_ownManifold) @@ -51,32 +50,32 @@ btConvexPlaneCollisionAlgorithm::~btConvexPlaneCollisionAlgorithm() } } -void btConvexPlaneCollisionAlgorithm::collideSingleContact (const btQuaternion& perturbeRot, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +void btConvexPlaneCollisionAlgorithm::collideSingleContact(const btQuaternion& perturbeRot, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { - const btCollisionObjectWrapper* convexObjWrap = m_isSwapped? body1Wrap : body0Wrap; - const btCollisionObjectWrapper* planeObjWrap = m_isSwapped? body0Wrap: body1Wrap; + const btCollisionObjectWrapper* convexObjWrap = m_isSwapped ? body1Wrap : body0Wrap; + const btCollisionObjectWrapper* planeObjWrap = m_isSwapped ? body0Wrap : body1Wrap; - btConvexShape* convexShape = (btConvexShape*) convexObjWrap->getCollisionShape(); - btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObjWrap->getCollisionShape(); + btConvexShape* convexShape = (btConvexShape*)convexObjWrap->getCollisionShape(); + btStaticPlaneShape* planeShape = (btStaticPlaneShape*)planeObjWrap->getCollisionShape(); - bool hasCollision = false; + bool hasCollision = false; const btVector3& planeNormal = planeShape->getPlaneNormal(); const btScalar& planeConstant = planeShape->getPlaneConstant(); - + btTransform convexWorldTransform = convexObjWrap->getWorldTransform(); btTransform convexInPlaneTrans; - convexInPlaneTrans= planeObjWrap->getWorldTransform().inverse() * convexWorldTransform; + convexInPlaneTrans = planeObjWrap->getWorldTransform().inverse() * convexWorldTransform; //now perturbe the convex-world transform - convexWorldTransform.getBasis()*=btMatrix3x3(perturbeRot); + convexWorldTransform.getBasis() *= btMatrix3x3(perturbeRot); btTransform planeInConvex; - planeInConvex= convexWorldTransform.inverse() * planeObjWrap->getWorldTransform(); - - btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal); + planeInConvex = convexWorldTransform.inverse() * planeObjWrap->getWorldTransform(); + + btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis() * -planeNormal); btVector3 vtxInPlane = convexInPlaneTrans(vtx); btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant); - btVector3 vtxInPlaneProjected = vtxInPlane - distance*planeNormal; + btVector3 vtxInPlaneProjected = vtxInPlane - distance * planeNormal; btVector3 vtxInPlaneWorld = planeObjWrap->getWorldTransform() * vtxInPlaneProjected; hasCollision = distance < m_manifoldPtr->getContactBreakingThreshold(); @@ -86,36 +85,35 @@ void btConvexPlaneCollisionAlgorithm::collideSingleContact (const btQuaternion& /// report a contact. internally this will be kept persistent, and contact reduction is done btVector3 normalOnSurfaceB = planeObjWrap->getWorldTransform().getBasis() * planeNormal; btVector3 pOnB = vtxInPlaneWorld; - resultOut->addContactPoint(normalOnSurfaceB,pOnB,distance); + resultOut->addContactPoint(normalOnSurfaceB, pOnB, distance); } } - -void btConvexPlaneCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +void btConvexPlaneCollisionAlgorithm::processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { (void)dispatchInfo; if (!m_manifoldPtr) return; - const btCollisionObjectWrapper* convexObjWrap = m_isSwapped? body1Wrap : body0Wrap; - const btCollisionObjectWrapper* planeObjWrap = m_isSwapped? body0Wrap: body1Wrap; + const btCollisionObjectWrapper* convexObjWrap = m_isSwapped ? body1Wrap : body0Wrap; + const btCollisionObjectWrapper* planeObjWrap = m_isSwapped ? body0Wrap : body1Wrap; - btConvexShape* convexShape = (btConvexShape*) convexObjWrap->getCollisionShape(); - btStaticPlaneShape* planeShape = (btStaticPlaneShape*) planeObjWrap->getCollisionShape(); + btConvexShape* convexShape = (btConvexShape*)convexObjWrap->getCollisionShape(); + btStaticPlaneShape* planeShape = (btStaticPlaneShape*)planeObjWrap->getCollisionShape(); bool hasCollision = false; const btVector3& planeNormal = planeShape->getPlaneNormal(); const btScalar& planeConstant = planeShape->getPlaneConstant(); btTransform planeInConvex; - planeInConvex= convexObjWrap->getWorldTransform().inverse() * planeObjWrap->getWorldTransform(); + planeInConvex = convexObjWrap->getWorldTransform().inverse() * planeObjWrap->getWorldTransform(); btTransform convexInPlaneTrans; - convexInPlaneTrans= planeObjWrap->getWorldTransform().inverse() * convexObjWrap->getWorldTransform(); + convexInPlaneTrans = planeObjWrap->getWorldTransform().inverse() * convexObjWrap->getWorldTransform(); - btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal); + btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis() * -planeNormal); btVector3 vtxInPlane = convexInPlaneTrans(vtx); btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant); - btVector3 vtxInPlaneProjected = vtxInPlane - distance*planeNormal; + btVector3 vtxInPlaneProjected = vtxInPlane - distance * planeNormal; btVector3 vtxInPlaneWorld = planeObjWrap->getWorldTransform() * vtxInPlaneProjected; hasCollision = distance < m_manifoldPtr->getContactBreakingThreshold(); @@ -125,31 +123,31 @@ void btConvexPlaneCollisionAlgorithm::processCollision (const btCollisionObjectW /// report a contact. internally this will be kept persistent, and contact reduction is done btVector3 normalOnSurfaceB = planeObjWrap->getWorldTransform().getBasis() * planeNormal; btVector3 pOnB = vtxInPlaneWorld; - resultOut->addContactPoint(normalOnSurfaceB,pOnB,distance); + resultOut->addContactPoint(normalOnSurfaceB, pOnB, distance); } //the perturbation algorithm doesn't work well with implicit surfaces such as spheres, cylinder and cones: //they keep on rolling forever because of the additional off-center contact points //so only enable the feature for polyhedral shapes (btBoxShape, btConvexHullShape etc) - if (convexShape->isPolyhedral() && resultOut->getPersistentManifold()->getNumContacts()isPolyhedral() && resultOut->getPersistentManifold()->getNumContacts() < m_minimumPointsPerturbationThreshold) { - btVector3 v0,v1; - btPlaneSpace1(planeNormal,v0,v1); + btVector3 v0, v1; + btPlaneSpace1(planeNormal, v0, v1); //now perform 'm_numPerturbationIterations' collision queries with the perturbated collision objects const btScalar angleLimit = 0.125f * SIMD_PI; btScalar perturbeAngle; btScalar radius = convexShape->getAngularMotionDisc(); perturbeAngle = gContactBreakingThreshold / radius; - if ( perturbeAngle > angleLimit ) - perturbeAngle = angleLimit; + if (perturbeAngle > angleLimit) + perturbeAngle = angleLimit; - btQuaternion perturbeRot(v0,perturbeAngle); - for (int i=0;iallocateCollisionAlgorithm(sizeof(btConvexPlaneCollisionAlgorithm)); if (!m_swapped) { - return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,false,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold); - } else + return new (mem) btConvexPlaneCollisionAlgorithm(0, ci, body0Wrap, body1Wrap, false, m_numPerturbationIterations, m_minimumPointsPerturbationThreshold); + } + else { - return new(mem) btConvexPlaneCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,true,m_numPerturbationIterations,m_minimumPointsPerturbationThreshold); + return new (mem) btConvexPlaneCollisionAlgorithm(0, ci, body0Wrap, body1Wrap, true, m_numPerturbationIterations, m_minimumPointsPerturbationThreshold); } } }; - }; -#endif //BT_CONVEX_PLANE_COLLISION_ALGORITHM_H - +#endif //BT_CONVEX_PLANE_COLLISION_ALGORITHM_H diff --git a/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp b/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp index f6e4e57b0..ef3ea9e39 100644 --- a/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp +++ b/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.cpp @@ -26,114 +26,108 @@ subject to the following restrictions: #include "BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h" #ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM #include "BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h" -#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM +#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM #include "BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h" #include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" #include "BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h" #include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" - - #include "LinearMath/btPoolAllocator.h" - - - - btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo) //btDefaultCollisionConfiguration::btDefaultCollisionConfiguration(btStackAlloc* stackAlloc,btPoolAllocator* persistentManifoldPool,btPoolAllocator* collisionAlgorithmPool) { - - void* mem = NULL; + void* mem = NULL; if (constructionInfo.m_useEpaPenetrationAlgorithm) { - mem = btAlignedAlloc(sizeof(btGjkEpaPenetrationDepthSolver),16); - m_pdSolver = new (mem)btGjkEpaPenetrationDepthSolver; - }else - { - mem = btAlignedAlloc(sizeof(btMinkowskiPenetrationDepthSolver),16); - m_pdSolver = new (mem)btMinkowskiPenetrationDepthSolver; + mem = btAlignedAlloc(sizeof(btGjkEpaPenetrationDepthSolver), 16); + m_pdSolver = new (mem) btGjkEpaPenetrationDepthSolver; } - + else + { + mem = btAlignedAlloc(sizeof(btMinkowskiPenetrationDepthSolver), 16); + m_pdSolver = new (mem) btMinkowskiPenetrationDepthSolver; + } + //default CreationFunctions, filling the m_doubleDispatch table - mem = btAlignedAlloc(sizeof(btConvexConvexAlgorithm::CreateFunc),16); - m_convexConvexCreateFunc = new(mem) btConvexConvexAlgorithm::CreateFunc(m_pdSolver); - mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16); - m_convexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::CreateFunc; - mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc),16); - m_swappedConvexConcaveCreateFunc = new (mem)btConvexConcaveCollisionAlgorithm::SwappedCreateFunc; - mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::CreateFunc),16); - m_compoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc(sizeof(btConvexConvexAlgorithm::CreateFunc), 16); + m_convexConvexCreateFunc = new (mem) btConvexConvexAlgorithm::CreateFunc(m_pdSolver); + mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc), 16); + m_convexConcaveCreateFunc = new (mem) btConvexConcaveCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc(sizeof(btConvexConcaveCollisionAlgorithm::CreateFunc), 16); + m_swappedConvexConcaveCreateFunc = new (mem) btConvexConcaveCollisionAlgorithm::SwappedCreateFunc; + mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::CreateFunc), 16); + m_compoundCreateFunc = new (mem) btCompoundCollisionAlgorithm::CreateFunc; - mem = btAlignedAlloc(sizeof(btCompoundCompoundCollisionAlgorithm::CreateFunc),16); - m_compoundCompoundCreateFunc = new (mem)btCompoundCompoundCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc(sizeof(btCompoundCompoundCollisionAlgorithm::CreateFunc), 16); + m_compoundCompoundCreateFunc = new (mem) btCompoundCompoundCollisionAlgorithm::CreateFunc; - mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::SwappedCreateFunc),16); - m_swappedCompoundCreateFunc = new (mem)btCompoundCollisionAlgorithm::SwappedCreateFunc; - mem = btAlignedAlloc(sizeof(btEmptyAlgorithm::CreateFunc),16); - m_emptyCreateFunc = new(mem) btEmptyAlgorithm::CreateFunc; - - mem = btAlignedAlloc(sizeof(btSphereSphereCollisionAlgorithm::CreateFunc),16); - m_sphereSphereCF = new(mem) btSphereSphereCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc(sizeof(btCompoundCollisionAlgorithm::SwappedCreateFunc), 16); + m_swappedCompoundCreateFunc = new (mem) btCompoundCollisionAlgorithm::SwappedCreateFunc; + mem = btAlignedAlloc(sizeof(btEmptyAlgorithm::CreateFunc), 16); + m_emptyCreateFunc = new (mem) btEmptyAlgorithm::CreateFunc; + + mem = btAlignedAlloc(sizeof(btSphereSphereCollisionAlgorithm::CreateFunc), 16); + m_sphereSphereCF = new (mem) btSphereSphereCollisionAlgorithm::CreateFunc; #ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM - mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc),16); - m_sphereBoxCF = new(mem) btSphereBoxCollisionAlgorithm::CreateFunc; - mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc),16); - m_boxSphereCF = new (mem)btSphereBoxCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc), 16); + m_sphereBoxCF = new (mem) btSphereBoxCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc(sizeof(btSphereBoxCollisionAlgorithm::CreateFunc), 16); + m_boxSphereCF = new (mem) btSphereBoxCollisionAlgorithm::CreateFunc; m_boxSphereCF->m_swapped = true; -#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM +#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM - mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc),16); - m_sphereTriangleCF = new (mem)btSphereTriangleCollisionAlgorithm::CreateFunc; - mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc),16); - m_triangleSphereCF = new (mem)btSphereTriangleCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc), 16); + m_sphereTriangleCF = new (mem) btSphereTriangleCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc(sizeof(btSphereTriangleCollisionAlgorithm::CreateFunc), 16); + m_triangleSphereCF = new (mem) btSphereTriangleCollisionAlgorithm::CreateFunc; m_triangleSphereCF->m_swapped = true; - - mem = btAlignedAlloc(sizeof(btBoxBoxCollisionAlgorithm::CreateFunc),16); - m_boxBoxCF = new(mem)btBoxBoxCollisionAlgorithm::CreateFunc; + + mem = btAlignedAlloc(sizeof(btBoxBoxCollisionAlgorithm::CreateFunc), 16); + m_boxBoxCF = new (mem) btBoxBoxCollisionAlgorithm::CreateFunc; //convex versus plane - mem = btAlignedAlloc (sizeof(btConvexPlaneCollisionAlgorithm::CreateFunc),16); + mem = btAlignedAlloc(sizeof(btConvexPlaneCollisionAlgorithm::CreateFunc), 16); m_convexPlaneCF = new (mem) btConvexPlaneCollisionAlgorithm::CreateFunc; - mem = btAlignedAlloc (sizeof(btConvexPlaneCollisionAlgorithm::CreateFunc),16); + mem = btAlignedAlloc(sizeof(btConvexPlaneCollisionAlgorithm::CreateFunc), 16); m_planeConvexCF = new (mem) btConvexPlaneCollisionAlgorithm::CreateFunc; m_planeConvexCF->m_swapped = true; - + ///calculate maximum element size, big enough to fit any collision algorithm in the memory pool int maxSize = sizeof(btConvexConvexAlgorithm); int maxSize2 = sizeof(btConvexConcaveCollisionAlgorithm); int maxSize3 = sizeof(btCompoundCollisionAlgorithm); int maxSize4 = sizeof(btCompoundCompoundCollisionAlgorithm); - int collisionAlgorithmMaxElementSize = btMax(maxSize,constructionInfo.m_customCollisionAlgorithmMaxElementSize); - collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize2); - collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize3); - collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize4); - + int collisionAlgorithmMaxElementSize = btMax(maxSize, constructionInfo.m_customCollisionAlgorithmMaxElementSize); + collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize, maxSize2); + collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize, maxSize3); + collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize, maxSize4); + if (constructionInfo.m_persistentManifoldPool) { m_ownsPersistentManifoldPool = false; m_persistentManifoldPool = constructionInfo.m_persistentManifoldPool; - } else + } + else { m_ownsPersistentManifoldPool = true; - void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16); - m_persistentManifoldPool = new (mem) btPoolAllocator(sizeof(btPersistentManifold),constructionInfo.m_defaultMaxPersistentManifoldPoolSize); + void* mem = btAlignedAlloc(sizeof(btPoolAllocator), 16); + m_persistentManifoldPool = new (mem) btPoolAllocator(sizeof(btPersistentManifold), constructionInfo.m_defaultMaxPersistentManifoldPoolSize); } - - collisionAlgorithmMaxElementSize = (collisionAlgorithmMaxElementSize+16)&0xffffffffffff0; + + collisionAlgorithmMaxElementSize = (collisionAlgorithmMaxElementSize + 16) & 0xffffffffffff0; if (constructionInfo.m_collisionAlgorithmPool) { m_ownsCollisionAlgorithmPool = false; m_collisionAlgorithmPool = constructionInfo.m_collisionAlgorithmPool; - } else + } + else { m_ownsCollisionAlgorithmPool = true; - void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16); - m_collisionAlgorithmPool = new(mem) btPoolAllocator(collisionAlgorithmMaxElementSize,constructionInfo.m_defaultMaxCollisionAlgorithmPoolSize); + void* mem = btAlignedAlloc(sizeof(btPoolAllocator), 16); + m_collisionAlgorithmPool = new (mem) btPoolAllocator(collisionAlgorithmMaxElementSize, constructionInfo.m_defaultMaxCollisionAlgorithmPoolSize); } - - } btDefaultCollisionConfiguration::~btDefaultCollisionConfiguration() @@ -150,83 +144,78 @@ btDefaultCollisionConfiguration::~btDefaultCollisionConfiguration() } m_convexConvexCreateFunc->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_convexConvexCreateFunc); + btAlignedFree(m_convexConvexCreateFunc); m_convexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_convexConcaveCreateFunc); + btAlignedFree(m_convexConcaveCreateFunc); m_swappedConvexConcaveCreateFunc->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_swappedConvexConcaveCreateFunc); + btAlignedFree(m_swappedConvexConcaveCreateFunc); m_compoundCreateFunc->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_compoundCreateFunc); + btAlignedFree(m_compoundCreateFunc); m_compoundCompoundCreateFunc->~btCollisionAlgorithmCreateFunc(); btAlignedFree(m_compoundCompoundCreateFunc); m_swappedCompoundCreateFunc->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_swappedCompoundCreateFunc); + btAlignedFree(m_swappedCompoundCreateFunc); m_emptyCreateFunc->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_emptyCreateFunc); + btAlignedFree(m_emptyCreateFunc); m_sphereSphereCF->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_sphereSphereCF); + btAlignedFree(m_sphereSphereCF); #ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM m_sphereBoxCF->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_sphereBoxCF); + btAlignedFree(m_sphereBoxCF); m_boxSphereCF->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_boxSphereCF); -#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM + btAlignedFree(m_boxSphereCF); +#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM m_sphereTriangleCF->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_sphereTriangleCF); + btAlignedFree(m_sphereTriangleCF); m_triangleSphereCF->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_triangleSphereCF); + btAlignedFree(m_triangleSphereCF); m_boxBoxCF->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_boxBoxCF); + btAlignedFree(m_boxBoxCF); m_convexPlaneCF->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_convexPlaneCF); + btAlignedFree(m_convexPlaneCF); m_planeConvexCF->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_planeConvexCF); + btAlignedFree(m_planeConvexCF); m_pdSolver->~btConvexPenetrationDepthSolver(); - + btAlignedFree(m_pdSolver); - - } btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1) { - - if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1 == SPHERE_SHAPE_PROXYTYPE)) { - return m_sphereSphereCF; + return m_sphereSphereCF; } #ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1 == BOX_SHAPE_PROXYTYPE)) { - return m_sphereBoxCF; + return m_sphereBoxCF; } if ((proxyType0 == BOX_SHAPE_PROXYTYPE) && (proxyType1 == SPHERE_SHAPE_PROXYTYPE)) { - return m_boxSphereCF; + return m_boxSphereCF; } -#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM - +#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1 == TRIANGLE_SHAPE_PROXYTYPE)) { - return m_sphereTriangleCF; + return m_sphereTriangleCF; } if ((proxyType0 == TRIANGLE_SHAPE_PROXYTYPE) && (proxyType1 == SPHERE_SHAPE_PROXYTYPE)) { - return m_triangleSphereCF; + return m_triangleSphereCF; } if (btBroadphaseProxy::isConvex(proxyType0) && (proxyType1 == STATIC_PLANE_PROXYTYPE)) @@ -239,8 +228,6 @@ btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getClosestPoint return m_planeConvexCF; } - - if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConvex(proxyType1)) { return m_convexConvexCreateFunc; @@ -256,7 +243,6 @@ btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getClosestPoint return m_swappedConvexConcaveCreateFunc; } - if (btBroadphaseProxy::isCompound(proxyType0) && btBroadphaseProxy::isCompound(proxyType1)) { return m_compoundCompoundCreateFunc; @@ -276,46 +262,41 @@ btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getClosestPoint //failed to find an algorithm return m_emptyCreateFunc; - } -btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1) +btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1) { - - - - if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1==SPHERE_SHAPE_PROXYTYPE)) + if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1 == SPHERE_SHAPE_PROXYTYPE)) { - return m_sphereSphereCF; + return m_sphereSphereCF; } #ifdef USE_BUGGY_SPHERE_BOX_ALGORITHM - if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1==BOX_SHAPE_PROXYTYPE)) + if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1 == BOX_SHAPE_PROXYTYPE)) { - return m_sphereBoxCF; + return m_sphereBoxCF; } - if ((proxyType0 == BOX_SHAPE_PROXYTYPE ) && (proxyType1==SPHERE_SHAPE_PROXYTYPE)) + if ((proxyType0 == BOX_SHAPE_PROXYTYPE) && (proxyType1 == SPHERE_SHAPE_PROXYTYPE)) { - return m_boxSphereCF; + return m_boxSphereCF; } -#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM +#endif //USE_BUGGY_SPHERE_BOX_ALGORITHM - - if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE ) && (proxyType1==TRIANGLE_SHAPE_PROXYTYPE)) + if ((proxyType0 == SPHERE_SHAPE_PROXYTYPE) && (proxyType1 == TRIANGLE_SHAPE_PROXYTYPE)) { - return m_sphereTriangleCF; + return m_sphereTriangleCF; } - if ((proxyType0 == TRIANGLE_SHAPE_PROXYTYPE ) && (proxyType1==SPHERE_SHAPE_PROXYTYPE)) + if ((proxyType0 == TRIANGLE_SHAPE_PROXYTYPE) && (proxyType1 == SPHERE_SHAPE_PROXYTYPE)) { - return m_triangleSphereCF; - } + return m_triangleSphereCF; + } if ((proxyType0 == BOX_SHAPE_PROXYTYPE) && (proxyType1 == BOX_SHAPE_PROXYTYPE)) { return m_boxBoxCF; } - + if (btBroadphaseProxy::isConvex(proxyType0) && (proxyType1 == STATIC_PLANE_PROXYTYPE)) { return m_convexPlaneCF; @@ -325,8 +306,6 @@ btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlg { return m_planeConvexCF; } - - if (btBroadphaseProxy::isConvex(proxyType0) && btBroadphaseProxy::isConvex(proxyType1)) { @@ -343,7 +322,6 @@ btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlg return m_swappedConvexConcaveCreateFunc; } - if (btBroadphaseProxy::isCompound(proxyType0) && btBroadphaseProxy::isCompound(proxyType1)) { return m_compoundCompoundCreateFunc; @@ -352,7 +330,8 @@ btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlg if (btBroadphaseProxy::isCompound(proxyType0)) { return m_compoundCreateFunc; - } else + } + else { if (btBroadphaseProxy::isCompound(proxyType1)) { @@ -366,17 +345,17 @@ btCollisionAlgorithmCreateFunc* btDefaultCollisionConfiguration::getCollisionAlg void btDefaultCollisionConfiguration::setConvexConvexMultipointIterations(int numPerturbationIterations, int minimumPointsPerturbationThreshold) { - btConvexConvexAlgorithm::CreateFunc* convexConvex = (btConvexConvexAlgorithm::CreateFunc*) m_convexConvexCreateFunc; + btConvexConvexAlgorithm::CreateFunc* convexConvex = (btConvexConvexAlgorithm::CreateFunc*)m_convexConvexCreateFunc; convexConvex->m_numPerturbationIterations = numPerturbationIterations; convexConvex->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold; } -void btDefaultCollisionConfiguration::setPlaneConvexMultipointIterations(int numPerturbationIterations, int minimumPointsPerturbationThreshold) +void btDefaultCollisionConfiguration::setPlaneConvexMultipointIterations(int numPerturbationIterations, int minimumPointsPerturbationThreshold) { btConvexPlaneCollisionAlgorithm::CreateFunc* cpCF = (btConvexPlaneCollisionAlgorithm::CreateFunc*)m_convexPlaneCF; cpCF->m_numPerturbationIterations = numPerturbationIterations; cpCF->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold; - + btConvexPlaneCollisionAlgorithm::CreateFunc* pcCF = (btConvexPlaneCollisionAlgorithm::CreateFunc*)m_planeConvexCF; pcCF->m_numPerturbationIterations = numPerturbationIterations; pcCF->m_minimumPointsPerturbationThreshold = minimumPointsPerturbationThreshold; diff --git a/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h b/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h index 17c7596cf..b39a3f41d 100644 --- a/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h +++ b/src/BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h @@ -20,76 +20,68 @@ subject to the following restrictions: class btVoronoiSimplexSolver; class btConvexPenetrationDepthSolver; -struct btDefaultCollisionConstructionInfo +struct btDefaultCollisionConstructionInfo { - btPoolAllocator* m_persistentManifoldPool; - btPoolAllocator* m_collisionAlgorithmPool; - int m_defaultMaxPersistentManifoldPoolSize; - int m_defaultMaxCollisionAlgorithmPoolSize; - int m_customCollisionAlgorithmMaxElementSize; - int m_useEpaPenetrationAlgorithm; + btPoolAllocator* m_persistentManifoldPool; + btPoolAllocator* m_collisionAlgorithmPool; + int m_defaultMaxPersistentManifoldPoolSize; + int m_defaultMaxCollisionAlgorithmPoolSize; + int m_customCollisionAlgorithmMaxElementSize; + int m_useEpaPenetrationAlgorithm; btDefaultCollisionConstructionInfo() - :m_persistentManifoldPool(0), - m_collisionAlgorithmPool(0), - m_defaultMaxPersistentManifoldPoolSize(4096), - m_defaultMaxCollisionAlgorithmPoolSize(4096), - m_customCollisionAlgorithmMaxElementSize(0), - m_useEpaPenetrationAlgorithm(true) + : m_persistentManifoldPool(0), + m_collisionAlgorithmPool(0), + m_defaultMaxPersistentManifoldPoolSize(4096), + m_defaultMaxCollisionAlgorithmPoolSize(4096), + m_customCollisionAlgorithmMaxElementSize(0), + m_useEpaPenetrationAlgorithm(true) { } }; - - ///btCollisionConfiguration allows to configure Bullet collision detection ///stack allocator, pool memory allocators ///@todo: describe the meaning -class btDefaultCollisionConfiguration : public btCollisionConfiguration +class btDefaultCollisionConfiguration : public btCollisionConfiguration { - protected: + int m_persistentManifoldPoolSize; - int m_persistentManifoldPoolSize; - + btPoolAllocator* m_persistentManifoldPool; + bool m_ownsPersistentManifoldPool; - btPoolAllocator* m_persistentManifoldPool; - bool m_ownsPersistentManifoldPool; - - - btPoolAllocator* m_collisionAlgorithmPool; - bool m_ownsCollisionAlgorithmPool; + btPoolAllocator* m_collisionAlgorithmPool; + bool m_ownsCollisionAlgorithmPool; //default penetration depth solver - btConvexPenetrationDepthSolver* m_pdSolver; - + btConvexPenetrationDepthSolver* m_pdSolver; + //default CreationFunctions, filling the m_doubleDispatch table - btCollisionAlgorithmCreateFunc* m_convexConvexCreateFunc; - btCollisionAlgorithmCreateFunc* m_convexConcaveCreateFunc; - btCollisionAlgorithmCreateFunc* m_swappedConvexConcaveCreateFunc; - btCollisionAlgorithmCreateFunc* m_compoundCreateFunc; - btCollisionAlgorithmCreateFunc* m_compoundCompoundCreateFunc; - - btCollisionAlgorithmCreateFunc* m_swappedCompoundCreateFunc; + btCollisionAlgorithmCreateFunc* m_convexConvexCreateFunc; + btCollisionAlgorithmCreateFunc* m_convexConcaveCreateFunc; + btCollisionAlgorithmCreateFunc* m_swappedConvexConcaveCreateFunc; + btCollisionAlgorithmCreateFunc* m_compoundCreateFunc; + btCollisionAlgorithmCreateFunc* m_compoundCompoundCreateFunc; + + btCollisionAlgorithmCreateFunc* m_swappedCompoundCreateFunc; btCollisionAlgorithmCreateFunc* m_emptyCreateFunc; btCollisionAlgorithmCreateFunc* m_sphereSphereCF; btCollisionAlgorithmCreateFunc* m_sphereBoxCF; btCollisionAlgorithmCreateFunc* m_boxSphereCF; btCollisionAlgorithmCreateFunc* m_boxBoxCF; - btCollisionAlgorithmCreateFunc* m_sphereTriangleCF; - btCollisionAlgorithmCreateFunc* m_triangleSphereCF; - btCollisionAlgorithmCreateFunc* m_planeConvexCF; - btCollisionAlgorithmCreateFunc* m_convexPlaneCF; - + btCollisionAlgorithmCreateFunc* m_sphereTriangleCF; + btCollisionAlgorithmCreateFunc* m_triangleSphereCF; + btCollisionAlgorithmCreateFunc* m_planeConvexCF; + btCollisionAlgorithmCreateFunc* m_convexPlaneCF; + public: - - btDefaultCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo = btDefaultCollisionConstructionInfo()); virtual ~btDefaultCollisionConfiguration(); - ///memory pools + ///memory pools virtual btPoolAllocator* getPersistentManifoldPool() { return m_persistentManifoldPool; @@ -100,8 +92,7 @@ public: return m_collisionAlgorithmPool; } - - virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1); + virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1); virtual btCollisionAlgorithmCreateFunc* getClosestPointsAlgorithmCreateFunc(int proxyType0, int proxyType1); @@ -112,11 +103,9 @@ public: ///3 is a good value for both params, if you want to enable the feature. This is because the default contact cache contains a maximum of 4 points, and one collision query at the unperturbed orientation is performed first. ///See Bullet/Demos/CollisionDemo for an example how this feature gathers multiple points. ///@todo we could add a per-object setting of those parameters, for level-of-detail collision detection. - void setConvexConvexMultipointIterations(int numPerturbationIterations=3, int minimumPointsPerturbationThreshold = 3); - - void setPlaneConvexMultipointIterations(int numPerturbationIterations=3, int minimumPointsPerturbationThreshold = 3); + void setConvexConvexMultipointIterations(int numPerturbationIterations = 3, int minimumPointsPerturbationThreshold = 3); + void setPlaneConvexMultipointIterations(int numPerturbationIterations = 3, int minimumPointsPerturbationThreshold = 3); }; -#endif //BT_DEFAULT_COLLISION_CONFIGURATION - +#endif //BT_DEFAULT_COLLISION_CONFIGURATION diff --git a/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp index 5fa1c8be5..7cd41bdb3 100644 --- a/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp +++ b/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.cpp @@ -15,20 +15,16 @@ subject to the following restrictions: #include "btEmptyCollisionAlgorithm.h" - - btEmptyAlgorithm::btEmptyAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) : btCollisionAlgorithm(ci) { } -void btEmptyAlgorithm::processCollision (const btCollisionObjectWrapper* ,const btCollisionObjectWrapper* ,const btDispatcherInfo& ,btManifoldResult* ) +void btEmptyAlgorithm::processCollision(const btCollisionObjectWrapper*, const btCollisionObjectWrapper*, const btDispatcherInfo&, btManifoldResult*) { } -btScalar btEmptyAlgorithm::calculateTimeOfImpact(btCollisionObject* ,btCollisionObject* ,const btDispatcherInfo& ,btManifoldResult* ) +btScalar btEmptyAlgorithm::calculateTimeOfImpact(btCollisionObject*, btCollisionObject*, const btDispatcherInfo&, btManifoldResult*) { return btScalar(1.); } - - diff --git a/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h index cb0f15218..65ef83e09 100644 --- a/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h +++ b/src/BulletCollision/CollisionDispatch/btEmptyCollisionAlgorithm.h @@ -25,30 +25,28 @@ subject to the following restrictions: ///The dispatcher can dispatch a persistent btEmptyAlgorithm to avoid a search every frame. class btEmptyAlgorithm : public btCollisionAlgorithm { - public: - btEmptyAlgorithm(const btCollisionAlgorithmConstructionInfo& ci); - virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) { } - struct CreateFunc :public btCollisionAlgorithmCreateFunc + struct CreateFunc : public btCollisionAlgorithmCreateFunc { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) - { + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) + { (void)body0Wrap; (void)body1Wrap; void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btEmptyAlgorithm)); - return new(mem) btEmptyAlgorithm(ci); + return new (mem) btEmptyAlgorithm(ci); } }; } ATTRIBUTE_ALIGNED(16); -#endif //BT_EMPTY_ALGORITH +#endif //BT_EMPTY_ALGORITH diff --git a/src/BulletCollision/CollisionDispatch/btGhostObject.cpp b/src/BulletCollision/CollisionDispatch/btGhostObject.cpp index 86141fa68..00f16fd0a 100644 --- a/src/BulletCollision/CollisionDispatch/btGhostObject.cpp +++ b/src/BulletCollision/CollisionDispatch/btGhostObject.cpp @@ -29,60 +29,58 @@ btGhostObject::~btGhostObject() btAssert(!m_overlappingObjects.size()); } - -void btGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btBroadphaseProxy* thisProxy) +void btGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btBroadphaseProxy* thisProxy) { btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject; btAssert(otherObject); ///if this linearSearch becomes too slow (too many overlapping objects) we should add a more appropriate data structure int index = m_overlappingObjects.findLinearSearch(otherObject); - if (index==m_overlappingObjects.size()) + if (index == m_overlappingObjects.size()) { //not found m_overlappingObjects.push_back(otherObject); } } -void btGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy) +void btGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btDispatcher* dispatcher, btBroadphaseProxy* thisProxy) { btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject; btAssert(otherObject); int index = m_overlappingObjects.findLinearSearch(otherObject); - if (index~btHashedOverlappingPairCache(); - btAlignedFree( m_hashPairCache ); + btAlignedFree(m_hashPairCache); } -void btPairCachingGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btBroadphaseProxy* thisProxy) +void btPairCachingGhostObject::addOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btBroadphaseProxy* thisProxy) { - btBroadphaseProxy*actualThisProxy = thisProxy ? thisProxy : getBroadphaseHandle(); + btBroadphaseProxy* actualThisProxy = thisProxy ? thisProxy : getBroadphaseHandle(); btAssert(actualThisProxy); btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject; btAssert(otherObject); int index = m_overlappingObjects.findLinearSearch(otherObject); - if (index==m_overlappingObjects.size()) + if (index == m_overlappingObjects.size()) { m_overlappingObjects.push_back(otherObject); - m_hashPairCache->addOverlappingPair(actualThisProxy,otherProxy); + m_hashPairCache->addOverlappingPair(actualThisProxy, otherProxy); } } -void btPairCachingGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy1) +void btPairCachingGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btDispatcher* dispatcher, btBroadphaseProxy* thisProxy1) { btCollisionObject* otherObject = (btCollisionObject*)otherProxy->m_clientObject; btBroadphaseProxy* actualThisProxy = thisProxy1 ? thisProxy1 : getBroadphaseHandle(); @@ -90,82 +88,79 @@ void btPairCachingGhostObject::removeOverlappingObjectInternal(btBroadphaseProxy btAssert(otherObject); int index = m_overlappingObjects.findLinearSearch(otherObject); - if (indexremoveOverlappingPair(actualThisProxy,otherProxy,dispatcher); + m_hashPairCache->removeOverlappingPair(actualThisProxy, otherProxy, dispatcher); } } - -void btGhostObject::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, btCollisionWorld::ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const +void btGhostObject::convexSweepTest(const btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, btCollisionWorld::ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration) const { - btTransform convexFromTrans,convexToTrans; + btTransform convexFromTrans, convexToTrans; convexFromTrans = convexFromWorld; convexToTrans = convexToWorld; btVector3 castShapeAabbMin, castShapeAabbMax; /* Compute AABB that encompasses angular movement */ { btVector3 linVel, angVel; - btTransformUtil::calculateVelocity (convexFromTrans, convexToTrans, 1.0, linVel, angVel); + btTransformUtil::calculateVelocity(convexFromTrans, convexToTrans, 1.0, linVel, angVel); btTransform R; - R.setIdentity (); - R.setRotation (convexFromTrans.getRotation()); - castShape->calculateTemporalAabb (R, linVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax); + R.setIdentity(); + R.setRotation(convexFromTrans.getRotation()); + castShape->calculateTemporalAabb(R, linVel, angVel, 1.0, castShapeAabbMin, castShapeAabbMax); } /// go over all objects, and if the ray intersects their aabb + cast shape aabb, // do a ray-shape query using convexCaster (CCD) int i; - for (i=0;igetBroadphaseHandle())) { + if (resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) + { //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); - btVector3 collisionObjectAabbMin,collisionObjectAabbMax; - collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(),collisionObjectAabbMin,collisionObjectAabbMax); - AabbExpand (collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax); - btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing + btVector3 collisionObjectAabbMin, collisionObjectAabbMax; + collisionObject->getCollisionShape()->getAabb(collisionObject->getWorldTransform(), collisionObjectAabbMin, collisionObjectAabbMax); + AabbExpand(collisionObjectAabbMin, collisionObjectAabbMax, castShapeAabbMin, castShapeAabbMax); + btScalar hitLambda = btScalar(1.); //could use resultCallback.m_closestHitFraction, but needs testing btVector3 hitNormal; - if (btRayAabb(convexFromWorld.getOrigin(),convexToWorld.getOrigin(),collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,hitNormal)) + if (btRayAabb(convexFromWorld.getOrigin(), convexToWorld.getOrigin(), collisionObjectAabbMin, collisionObjectAabbMax, hitLambda, hitNormal)) { - btCollisionWorld::objectQuerySingle(castShape, convexFromTrans,convexToTrans, - collisionObject, - collisionObject->getCollisionShape(), - collisionObject->getWorldTransform(), - resultCallback, - allowedCcdPenetration); + btCollisionWorld::objectQuerySingle(castShape, convexFromTrans, convexToTrans, + collisionObject, + collisionObject->getCollisionShape(), + collisionObject->getWorldTransform(), + resultCallback, + allowedCcdPenetration); } } } - } -void btGhostObject::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const +void btGhostObject::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const { btTransform rayFromTrans; rayFromTrans.setIdentity(); rayFromTrans.setOrigin(rayFromWorld); - btTransform rayToTrans; + btTransform rayToTrans; rayToTrans.setIdentity(); rayToTrans.setOrigin(rayToWorld); - int i; - for (i=0;igetBroadphaseHandle())) + if (resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) { - btCollisionWorld::rayTestSingle(rayFromTrans,rayToTrans, - collisionObject, - collisionObject->getCollisionShape(), - collisionObject->getWorldTransform(), - resultCallback); + btCollisionWorld::rayTestSingle(rayFromTrans, rayToTrans, + collisionObject, + collisionObject->getCollisionShape(), + collisionObject->getWorldTransform(), + resultCallback); } } } - diff --git a/src/BulletCollision/CollisionDispatch/btGhostObject.h b/src/BulletCollision/CollisionDispatch/btGhostObject.h index 8ec861385..aa7f48d5c 100644 --- a/src/BulletCollision/CollisionDispatch/btGhostObject.h +++ b/src/BulletCollision/CollisionDispatch/btGhostObject.h @@ -16,7 +16,6 @@ subject to the following restrictions: #ifndef BT_GHOST_OBJECT_H #define BT_GHOST_OBJECT_H - #include "btCollisionObject.h" #include "BulletCollision/BroadphaseCollision/btOverlappingPairCallback.h" #include "LinearMath/btAlignedAllocator.h" @@ -31,48 +30,47 @@ class btDispatcher; ///By default, this overlap is based on the AABB ///This is useful for creating a character controller, collision sensors/triggers, explosions etc. ///We plan on adding rayTest and other queries for the btGhostObject -ATTRIBUTE_ALIGNED16(class) btGhostObject : public btCollisionObject +ATTRIBUTE_ALIGNED16(class) +btGhostObject : public btCollisionObject { protected: - btAlignedObjectArray m_overlappingObjects; public: - btGhostObject(); virtual ~btGhostObject(); - void convexSweepTest(const class btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, btCollisionWorld::ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration = 0.f) const; + void convexSweepTest(const class btConvexShape* castShape, const btTransform& convexFromWorld, const btTransform& convexToWorld, btCollisionWorld::ConvexResultCallback& resultCallback, btScalar allowedCcdPenetration = 0.f) const; - void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const; + void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, btCollisionWorld::RayResultCallback& resultCallback) const; ///this method is mainly for expert/internal use only. - virtual void addOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btBroadphaseProxy* thisProxy=0); + virtual void addOverlappingObjectInternal(btBroadphaseProxy * otherProxy, btBroadphaseProxy* thisProxy = 0); ///this method is mainly for expert/internal use only. - virtual void removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy=0); + virtual void removeOverlappingObjectInternal(btBroadphaseProxy * otherProxy, btDispatcher * dispatcher, btBroadphaseProxy* thisProxy = 0); - int getNumOverlappingObjects() const + int getNumOverlappingObjects() const { return m_overlappingObjects.size(); } - btCollisionObject* getOverlappingObject(int index) + btCollisionObject* getOverlappingObject(int index) { return m_overlappingObjects[index]; } - const btCollisionObject* getOverlappingObject(int index) const + const btCollisionObject* getOverlappingObject(int index) const { return m_overlappingObjects[index]; } - btAlignedObjectArray& getOverlappingPairs() + btAlignedObjectArray& getOverlappingPairs() { return m_overlappingObjects; } - const btAlignedObjectArray getOverlappingPairs() const + const btAlignedObjectArray getOverlappingPairs() const { return m_overlappingObjects; } @@ -81,49 +79,43 @@ public: // internal cast // - static const btGhostObject* upcast(const btCollisionObject* colObj) + static const btGhostObject* upcast(const btCollisionObject* colObj) { - if (colObj->getInternalType()==CO_GHOST_OBJECT) + if (colObj->getInternalType() == CO_GHOST_OBJECT) return (const btGhostObject*)colObj; return 0; } - static btGhostObject* upcast(btCollisionObject* colObj) + static btGhostObject* upcast(btCollisionObject * colObj) { - if (colObj->getInternalType()==CO_GHOST_OBJECT) + if (colObj->getInternalType() == CO_GHOST_OBJECT) return (btGhostObject*)colObj; return 0; } - }; -class btPairCachingGhostObject : public btGhostObject +class btPairCachingGhostObject : public btGhostObject { - btHashedOverlappingPairCache* m_hashPairCache; + btHashedOverlappingPairCache* m_hashPairCache; public: - btPairCachingGhostObject(); virtual ~btPairCachingGhostObject(); ///this method is mainly for expert/internal use only. - virtual void addOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btBroadphaseProxy* thisProxy=0); + virtual void addOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btBroadphaseProxy* thisProxy = 0); - virtual void removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy,btDispatcher* dispatcher,btBroadphaseProxy* thisProxy=0); + virtual void removeOverlappingObjectInternal(btBroadphaseProxy* otherProxy, btDispatcher* dispatcher, btBroadphaseProxy* thisProxy = 0); - btHashedOverlappingPairCache* getOverlappingPairCache() + btHashedOverlappingPairCache* getOverlappingPairCache() { return m_hashPairCache; } - }; - - ///The btGhostPairCallback interfaces and forwards adding and removal of overlapping pairs from the btBroadphaseInterface to btGhostObject. class btGhostPairCallback : public btOverlappingPairCallback { - public: btGhostPairCallback() { @@ -131,15 +123,14 @@ public: virtual ~btGhostPairCallback() { - } - virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1) + virtual btBroadphasePair* addOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1) { - btCollisionObject* colObj0 = (btCollisionObject*) proxy0->m_clientObject; - btCollisionObject* colObj1 = (btCollisionObject*) proxy1->m_clientObject; - btGhostObject* ghost0 = btGhostObject::upcast(colObj0); - btGhostObject* ghost1 = btGhostObject::upcast(colObj1); + btCollisionObject* colObj0 = (btCollisionObject*)proxy0->m_clientObject; + btCollisionObject* colObj1 = (btCollisionObject*)proxy1->m_clientObject; + btGhostObject* ghost0 = btGhostObject::upcast(colObj0); + btGhostObject* ghost1 = btGhostObject::upcast(colObj1); if (ghost0) ghost0->addOverlappingObjectInternal(proxy1, proxy0); if (ghost1) @@ -147,29 +138,25 @@ public: return 0; } - virtual void* removeOverlappingPair(btBroadphaseProxy* proxy0,btBroadphaseProxy* proxy1,btDispatcher* dispatcher) + virtual void* removeOverlappingPair(btBroadphaseProxy* proxy0, btBroadphaseProxy* proxy1, btDispatcher* dispatcher) { - btCollisionObject* colObj0 = (btCollisionObject*) proxy0->m_clientObject; - btCollisionObject* colObj1 = (btCollisionObject*) proxy1->m_clientObject; - btGhostObject* ghost0 = btGhostObject::upcast(colObj0); - btGhostObject* ghost1 = btGhostObject::upcast(colObj1); + btCollisionObject* colObj0 = (btCollisionObject*)proxy0->m_clientObject; + btCollisionObject* colObj1 = (btCollisionObject*)proxy1->m_clientObject; + btGhostObject* ghost0 = btGhostObject::upcast(colObj0); + btGhostObject* ghost1 = btGhostObject::upcast(colObj1); if (ghost0) - ghost0->removeOverlappingObjectInternal(proxy1,dispatcher,proxy0); + ghost0->removeOverlappingObjectInternal(proxy1, dispatcher, proxy0); if (ghost1) - ghost1->removeOverlappingObjectInternal(proxy0,dispatcher,proxy1); + ghost1->removeOverlappingObjectInternal(proxy0, dispatcher, proxy1); return 0; } - virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* /*proxy0*/,btDispatcher* /*dispatcher*/) + virtual void removeOverlappingPairsContainingProxy(btBroadphaseProxy* /*proxy0*/, btDispatcher* /*dispatcher*/) { btAssert(0); //need to keep track of all ghost objects and call them here //m_hashPairCache->removeOverlappingPairsContainingProxy(proxy0,dispatcher); } - - - }; #endif - diff --git a/src/BulletCollision/CollisionDispatch/btHashedSimplePairCache.cpp b/src/BulletCollision/CollisionDispatch/btHashedSimplePairCache.cpp index 8271981b2..b686d98d1 100644 --- a/src/BulletCollision/CollisionDispatch/btHashedSimplePairCache.cpp +++ b/src/BulletCollision/CollisionDispatch/btHashedSimplePairCache.cpp @@ -13,64 +13,49 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "btHashedSimplePairCache.h" - #include #ifdef BT_DEBUG_COLLISION_PAIRS -int gOverlappingSimplePairs = 0; -int gRemoveSimplePairs =0; -int gAddedSimplePairs =0; -int gFindSimplePairs =0; -#endif //BT_DEBUG_COLLISION_PAIRS +int gOverlappingSimplePairs = 0; +int gRemoveSimplePairs = 0; +int gAddedSimplePairs = 0; +int gFindSimplePairs = 0; +#endif //BT_DEBUG_COLLISION_PAIRS - - -btHashedSimplePairCache::btHashedSimplePairCache() { - int initialAllocatedSize= 2; +btHashedSimplePairCache::btHashedSimplePairCache() +{ + int initialAllocatedSize = 2; m_overlappingPairArray.reserve(initialAllocatedSize); growTables(); } - - - btHashedSimplePairCache::~btHashedSimplePairCache() { } - - - - - void btHashedSimplePairCache::removeAllPairs() { m_overlappingPairArray.clear(); m_hashTable.clear(); m_next.clear(); - int initialAllocatedSize= 2; + int initialAllocatedSize = 2; m_overlappingPairArray.reserve(initialAllocatedSize); growTables(); } - - btSimplePair* btHashedSimplePairCache::findPair(int indexA, int indexB) { #ifdef BT_DEBUG_COLLISION_PAIRS gFindSimplePairs++; #endif - - + /*if (indexA > indexB) btSwap(indexA, indexB);*/ - int hash = static_cast(getHash(static_cast(indexA), static_cast(indexB)) & (m_overlappingPairArray.capacity()-1)); + int hash = static_cast(getHash(static_cast(indexA), static_cast(indexB)) & (m_overlappingPairArray.capacity() - 1)); if (hash >= m_hashTable.size()) { @@ -95,9 +80,8 @@ btSimplePair* btHashedSimplePairCache::findPair(int indexA, int indexB) //#include -void btHashedSimplePairCache::growTables() +void btHashedSimplePairCache::growTables() { - int newCapacity = m_overlappingPairArray.capacity(); if (m_hashTable.size() < newCapacity) @@ -108,10 +92,9 @@ void btHashedSimplePairCache::growTables() m_hashTable.resize(newCapacity); m_next.resize(newCapacity); - int i; - for (i= 0; i < newCapacity; ++i) + for (i = 0; i < newCapacity; ++i) { m_hashTable[i] = BT_SIMPLE_NULL_PAIR; } @@ -120,27 +103,22 @@ void btHashedSimplePairCache::growTables() m_next[i] = BT_SIMPLE_NULL_PAIR; } - for(i=0;i(getHash(static_cast(indexA),static_cast(indexB)) & (m_overlappingPairArray.capacity()-1)); // New hash value with new mask + + int hashValue = static_cast(getHash(static_cast(indexA), static_cast(indexB)) & (m_overlappingPairArray.capacity() - 1)); // New hash value with new mask m_next[i] = m_hashTable[hashValue]; m_hashTable[hashValue] = i; } - - } } btSimplePair* btHashedSimplePairCache::internalAddPair(int indexA, int indexB) { - - int hash = static_cast(getHash(static_cast(indexA),static_cast(indexB)) & (m_overlappingPairArray.capacity()-1)); // New hash value with new mask - + int hash = static_cast(getHash(static_cast(indexA), static_cast(indexB)) & (m_overlappingPairArray.capacity() - 1)); // New hash value with new mask btSimplePair* pair = internalFindPair(indexA, indexB, hash); if (pair != NULL) @@ -158,32 +136,29 @@ btSimplePair* btHashedSimplePairCache::internalAddPair(int indexA, int indexB) { growTables(); //hash with new capacity - hash = static_cast(getHash(static_cast(indexA),static_cast(indexB)) & (m_overlappingPairArray.capacity()-1)); + hash = static_cast(getHash(static_cast(indexA), static_cast(indexB)) & (m_overlappingPairArray.capacity() - 1)); } - - pair = new (mem) btSimplePair(indexA,indexB); + + pair = new (mem) btSimplePair(indexA, indexB); pair->m_userPointer = 0; - + m_next[count] = m_hashTable[hash]; m_hashTable[hash] = count; return pair; } - - void* btHashedSimplePairCache::removeOverlappingPair(int indexA, int indexB) { #ifdef BT_DEBUG_COLLISION_PAIRS gRemoveSimplePairs++; #endif - /*if (indexA > indexB) btSwap(indexA, indexB);*/ - int hash = static_cast(getHash(static_cast(indexA),static_cast(indexB)) & (m_overlappingPairArray.capacity()-1)); + int hash = static_cast(getHash(static_cast(indexA), static_cast(indexB)) & (m_overlappingPairArray.capacity() - 1)); btSimplePair* pair = internalFindPair(indexA, indexB, hash); if (pair == NULL) @@ -191,10 +166,8 @@ void* btHashedSimplePairCache::removeOverlappingPair(int indexA, int indexB) return 0; } - void* userData = pair->m_userPointer; - int pairIndex = int(pair - &m_overlappingPairArray[0]); btAssert(pairIndex < m_overlappingPairArray.size()); @@ -234,8 +207,8 @@ void* btHashedSimplePairCache::removeOverlappingPair(int indexA, int indexB) // Remove the last pair from the hash table. const btSimplePair* last = &m_overlappingPairArray[lastPairIndex]; - /* missing swap here too, Nat. */ - int lastHash = static_cast(getHash(static_cast(last->m_indexA), static_cast(last->m_indexB)) & (m_overlappingPairArray.capacity()-1)); + /* missing swap here too, Nat. */ + int lastHash = static_cast(getHash(static_cast(last->m_indexA), static_cast(last->m_indexB)) & (m_overlappingPairArray.capacity() - 1)); index = m_hashTable[lastHash]; btAssert(index != BT_SIMPLE_NULL_PAIR); @@ -269,13 +242,3 @@ void* btHashedSimplePairCache::removeOverlappingPair(int indexA, int indexB) return userData; } //#include - - - - - - - - - - diff --git a/src/BulletCollision/CollisionDispatch/btHashedSimplePairCache.h b/src/BulletCollision/CollisionDispatch/btHashedSimplePairCache.h index 318981cda..fd38a4f0e 100644 --- a/src/BulletCollision/CollisionDispatch/btHashedSimplePairCache.h +++ b/src/BulletCollision/CollisionDispatch/btHashedSimplePairCache.h @@ -16,144 +16,126 @@ subject to the following restrictions: #ifndef BT_HASHED_SIMPLE_PAIR_CACHE_H #define BT_HASHED_SIMPLE_PAIR_CACHE_H - - #include "LinearMath/btAlignedObjectArray.h" -const int BT_SIMPLE_NULL_PAIR=0xffffffff; +const int BT_SIMPLE_NULL_PAIR = 0xffffffff; struct btSimplePair { - btSimplePair(int indexA,int indexB) - :m_indexA(indexA), - m_indexB(indexB), - m_userPointer(0) + btSimplePair(int indexA, int indexB) + : m_indexA(indexA), + m_indexB(indexB), + m_userPointer(0) { } int m_indexA; int m_indexB; - union - { - void* m_userPointer; - int m_userValue; + union { + void* m_userPointer; + int m_userValue; }; }; -typedef btAlignedObjectArray btSimplePairArray; - +typedef btAlignedObjectArray btSimplePairArray; #ifdef BT_DEBUG_COLLISION_PAIRS extern int gOverlappingSimplePairs; extern int gRemoveSimplePairs; extern int gAddedSimplePairs; extern int gFindSimplePairs; -#endif //BT_DEBUG_COLLISION_PAIRS - - +#endif //BT_DEBUG_COLLISION_PAIRS class btHashedSimplePairCache { - btSimplePairArray m_overlappingPairArray; - + btSimplePairArray m_overlappingPairArray; protected: - - btAlignedObjectArray m_hashTable; - btAlignedObjectArray m_next; - + btAlignedObjectArray m_hashTable; + btAlignedObjectArray m_next; public: btHashedSimplePairCache(); virtual ~btHashedSimplePairCache(); - + void removeAllPairs(); - virtual void* removeOverlappingPair(int indexA,int indexB); - + virtual void* removeOverlappingPair(int indexA, int indexB); + // Add a pair and return the new pair. If the pair already exists, // no new pair is created and the old one is returned. - virtual btSimplePair* addOverlappingPair(int indexA,int indexB) + virtual btSimplePair* addOverlappingPair(int indexA, int indexB) { #ifdef BT_DEBUG_COLLISION_PAIRS gAddedSimplePairs++; #endif - return internalAddPair(indexA,indexB); + return internalAddPair(indexA, indexB); } - - virtual btSimplePair* getOverlappingPairArrayPtr() + virtual btSimplePair* getOverlappingPairArrayPtr() { return &m_overlappingPairArray[0]; } - const btSimplePair* getOverlappingPairArrayPtr() const + const btSimplePair* getOverlappingPairArrayPtr() const { return &m_overlappingPairArray[0]; } - btSimplePairArray& getOverlappingPairArray() + btSimplePairArray& getOverlappingPairArray() { return m_overlappingPairArray; } - const btSimplePairArray& getOverlappingPairArray() const + const btSimplePairArray& getOverlappingPairArray() const { return m_overlappingPairArray; } - - btSimplePair* findPair(int indexA,int indexB); + btSimplePair* findPair(int indexA, int indexB); int GetCount() const { return m_overlappingPairArray.size(); } - int getNumOverlappingPairs() const + int getNumOverlappingPairs() const { return m_overlappingPairArray.size(); } -private: - - btSimplePair* internalAddPair(int indexA, int indexB); - void growTables(); +private: + btSimplePair* internalAddPair(int indexA, int indexB); + + void growTables(); SIMD_FORCE_INLINE bool equalsPair(const btSimplePair& pair, int indexA, int indexB) - { + { return pair.m_indexA == indexA && pair.m_indexB == indexB; } - - SIMD_FORCE_INLINE unsigned int getHash(unsigned int indexA, unsigned int indexB) { unsigned int key = indexA | (indexB << 16); // Thomas Wang's hash key += ~(key << 15); - key ^= (key >> 10); - key += (key << 3); - key ^= (key >> 6); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); key += ~(key << 11); - key ^= (key >> 16); + key ^= (key >> 16); return key; } - - - - - SIMD_FORCE_INLINE btSimplePair* internalFindPair(int proxyIdA , int proxyIdB, int hash) + SIMD_FORCE_INLINE btSimplePair* internalFindPair(int proxyIdA, int proxyIdB, int hash) { - int index = m_hashTable[hash]; - - while( index != BT_SIMPLE_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyIdA, proxyIdB) == false) + + while (index != BT_SIMPLE_NULL_PAIR && equalsPair(m_overlappingPairArray[index], proxyIdA, proxyIdB) == false) { index = m_next[index]; } - if ( index == BT_SIMPLE_NULL_PAIR ) + if (index == BT_SIMPLE_NULL_PAIR) { return NULL; } @@ -162,13 +144,6 @@ private: return &m_overlappingPairArray[index]; } - - }; - - - -#endif //BT_HASHED_SIMPLE_PAIR_CACHE_H - - +#endif //BT_HASHED_SIMPLE_PAIR_CACHE_H diff --git a/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp b/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp index 898320ee1..e74c83f9f 100644 --- a/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp +++ b/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.cpp @@ -12,50 +12,44 @@ #ifdef DEBUG_INTERNAL_EDGE #include -#endif //DEBUG_INTERNAL_EDGE - +#endif //DEBUG_INTERNAL_EDGE #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW static btIDebugDraw* gDebugDrawer = 0; -void btSetDebugDrawer(btIDebugDraw* debugDrawer) +void btSetDebugDrawer(btIDebugDraw* debugDrawer) { gDebugDrawer = debugDrawer; } -static void btDebugDrawLine(const btVector3& from,const btVector3& to, const btVector3& color) +static void btDebugDrawLine(const btVector3& from, const btVector3& to, const btVector3& color) { if (gDebugDrawer) - gDebugDrawer->drawLine(from,to,color); + gDebugDrawer->drawLine(from, to, color); } -#endif //BT_INTERNAL_EDGE_DEBUG_DRAW +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW - -static int btGetHash(int partId, int triangleIndex) +static int btGetHash(int partId, int triangleIndex) { - int hash = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | triangleIndex; + int hash = (partId << (31 - MAX_NUM_PARTS_IN_BITS)) | triangleIndex; return hash; } - - -static btScalar btGetAngle(const btVector3& edgeA, const btVector3& normalA,const btVector3& normalB) +static btScalar btGetAngle(const btVector3& edgeA, const btVector3& normalA, const btVector3& normalB) { - const btVector3 refAxis0 = edgeA; - const btVector3 refAxis1 = normalA; + const btVector3 refAxis0 = edgeA; + const btVector3 refAxis1 = normalA; const btVector3 swingAxis = normalB; btScalar angle = btAtan2(swingAxis.dot(refAxis0), swingAxis.dot(refAxis1)); - return angle; + return angle; } - struct btConnectivityProcessor : public btTriangleCallback { - int m_partIdA; - int m_triangleIndexA; - btVector3* m_triangleVerticesA; - btTriangleInfoMap* m_triangleInfoMap; - + int m_partIdA; + int m_triangleIndexA; + btVector3* m_triangleVerticesA; + btTriangleInfoMap* m_triangleInfoMap; virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) { @@ -69,18 +63,17 @@ struct btConnectivityProcessor : public btTriangleCallback //search for shared vertices and edges int numshared = 0; - int sharedVertsA[3]={-1,-1,-1}; - int sharedVertsB[3]={-1,-1,-1}; + int sharedVertsA[3] = {-1, -1, -1}; + int sharedVertsB[3] = {-1, -1, -1}; ///skip degenerate triangles - btScalar crossBSqr = ((triangle[1]-triangle[0]).cross(triangle[2]-triangle[0])).length2(); + btScalar crossBSqr = ((triangle[1] - triangle[0]).cross(triangle[2] - triangle[0])).length2(); if (crossBSqr < m_triangleInfoMap->m_equalVertexThreshold) return; - - btScalar crossASqr = ((m_triangleVerticesA[1]-m_triangleVerticesA[0]).cross(m_triangleVerticesA[2]-m_triangleVerticesA[0])).length2(); + btScalar crossASqr = ((m_triangleVerticesA[1] - m_triangleVerticesA[0]).cross(m_triangleVerticesA[2] - m_triangleVerticesA[0])).length2(); ///skip degenerate triangles - if (crossASqr< m_triangleInfoMap->m_equalVertexThreshold) + if (crossASqr < m_triangleInfoMap->m_equalVertexThreshold) return; #if 0 @@ -96,36 +89,36 @@ struct btConnectivityProcessor : public btTriangleCallback triangle[2].getX(),triangle[2].getY(),triangle[2].getZ()); #endif - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) { - for (int j=0;j<3;j++) + for (int j = 0; j < 3; j++) { - if ( (m_triangleVerticesA[i]-triangle[j]).length2() < m_triangleInfoMap->m_equalVertexThreshold) + if ((m_triangleVerticesA[i] - triangle[j]).length2() < m_triangleInfoMap->m_equalVertexThreshold) { sharedVertsA[numshared] = i; sharedVertsB[numshared] = j; numshared++; ///degenerate case - if(numshared >= 3) + if (numshared >= 3) return; } } ///degenerate case - if(numshared >= 3) + if (numshared >= 3) return; } switch (numshared) { - case 0: + case 0: { break; } - case 1: + case 1: { //shared vertex break; } - case 2: + case 2: { //shared edge //we need to make sure the edge is in the order V2V0 and not V0V2 so that the signs are correct @@ -138,26 +131,25 @@ struct btConnectivityProcessor : public btTriangleCallback sharedVertsB[0] = tmp; } - int hash = btGetHash(m_partIdA,m_triangleIndexA); + int hash = btGetHash(m_partIdA, m_triangleIndexA); btTriangleInfo* info = m_triangleInfoMap->find(hash); if (!info) { btTriangleInfo tmp; - m_triangleInfoMap->insert(hash,tmp); + m_triangleInfoMap->insert(hash, tmp); info = m_triangleInfoMap->find(hash); } - int sumvertsA = sharedVertsA[0]+sharedVertsA[1]; - int otherIndexA = 3-sumvertsA; + int sumvertsA = sharedVertsA[0] + sharedVertsA[1]; + int otherIndexA = 3 - sumvertsA; - - btVector3 edge(m_triangleVerticesA[sharedVertsA[1]]-m_triangleVerticesA[sharedVertsA[0]]); + btVector3 edge(m_triangleVerticesA[sharedVertsA[1]] - m_triangleVerticesA[sharedVertsA[0]]); - btTriangleShape tA(m_triangleVerticesA[0],m_triangleVerticesA[1],m_triangleVerticesA[2]); - int otherIndexB = 3-(sharedVertsB[0]+sharedVertsB[1]); + btTriangleShape tA(m_triangleVerticesA[0], m_triangleVerticesA[1], m_triangleVerticesA[2]); + int otherIndexB = 3 - (sharedVertsB[0] + sharedVertsB[1]); - btTriangleShape tB(triangle[sharedVertsB[1]],triangle[sharedVertsB[0]],triangle[otherIndexB]); + btTriangleShape tB(triangle[sharedVertsB[1]], triangle[sharedVertsB[0]], triangle[otherIndexB]); //btTriangleShape tB(triangle[0],triangle[1],triangle[2]); btVector3 normalA; @@ -168,26 +160,25 @@ struct btConnectivityProcessor : public btTriangleCallback btVector3 edgeCrossA = edge.cross(normalA).normalize(); { - btVector3 tmp = m_triangleVerticesA[otherIndexA]-m_triangleVerticesA[sharedVertsA[0]]; + btVector3 tmp = m_triangleVerticesA[otherIndexA] - m_triangleVerticesA[sharedVertsA[0]]; if (edgeCrossA.dot(tmp) < 0) { - edgeCrossA*=-1; + edgeCrossA *= -1; } } btVector3 edgeCrossB = edge.cross(normalB).normalize(); { - btVector3 tmp = triangle[otherIndexB]-triangle[sharedVertsB[0]]; + btVector3 tmp = triangle[otherIndexB] - triangle[sharedVertsB[0]]; if (edgeCrossB.dot(tmp) < 0) { - edgeCrossB*=-1; + edgeCrossB *= -1; } } - btScalar angle2 = 0; - btScalar ang4 = 0.f; - + btScalar angle2 = 0; + btScalar ang4 = 0.f; btVector3 calculatedEdge = edgeCrossA.cross(edgeCrossB); btScalar len2 = calculatedEdge.length2(); @@ -196,52 +187,47 @@ struct btConnectivityProcessor : public btTriangleCallback //btVector3 calculatedNormalB = normalA; bool isConvex = false; - if (len2m_planarEpsilon) + if (len2 < m_triangleInfoMap->m_planarEpsilon) { angle2 = 0.f; ang4 = 0.f; - } else + } + else { - calculatedEdge.normalize(); btVector3 calculatedNormalA = calculatedEdge.cross(edgeCrossA); calculatedNormalA.normalize(); - angle2 = btGetAngle(calculatedNormalA,edgeCrossA,edgeCrossB); - ang4 = SIMD_PI-angle2; + angle2 = btGetAngle(calculatedNormalA, edgeCrossA, edgeCrossB); + ang4 = SIMD_PI - angle2; btScalar dotA = normalA.dot(edgeCrossB); ///@todo: check if we need some epsilon, due to floating point imprecision - isConvex = (dotA<0.); + isConvex = (dotA < 0.); correctedAngle = isConvex ? ang4 : -ang4; } - - - - - //alternatively use + //alternatively use //btVector3 calculatedNormalB2 = quatRotate(orn,normalA); - switch (sumvertsA) { - case 1: + case 1: { - btVector3 edge = m_triangleVerticesA[0]-m_triangleVerticesA[1]; - btQuaternion orn(edge,-correctedAngle); - btVector3 computedNormalB = quatRotate(orn,normalA); + btVector3 edge = m_triangleVerticesA[0] - m_triangleVerticesA[1]; + btQuaternion orn(edge, -correctedAngle); + btVector3 computedNormalB = quatRotate(orn, normalA); btScalar bla = computedNormalB.dot(normalB); - if (bla<0) + if (bla < 0) { - computedNormalB*=-1; + computedNormalB *= -1; info->m_flags |= TRI_INFO_V0V1_SWAP_NORMALB; } #ifdef DEBUG_INTERNAL_EDGE - if ((computedNormalB-normalB).length()>0.0001) + if ((computedNormalB - normalB).length() > 0.0001) { printf("warning: normals not identical\n"); } -#endif//DEBUG_INTERNAL_EDGE +#endif //DEBUG_INTERNAL_EDGE info->m_edgeV0V1Angle = -correctedAngle; @@ -249,44 +235,44 @@ struct btConnectivityProcessor : public btTriangleCallback info->m_flags |= TRI_INFO_V0V1_CONVEX; break; } - case 2: + case 2: { - btVector3 edge = m_triangleVerticesA[2]-m_triangleVerticesA[0]; - btQuaternion orn(edge,-correctedAngle); - btVector3 computedNormalB = quatRotate(orn,normalA); - if (computedNormalB.dot(normalB)<0) + btVector3 edge = m_triangleVerticesA[2] - m_triangleVerticesA[0]; + btQuaternion orn(edge, -correctedAngle); + btVector3 computedNormalB = quatRotate(orn, normalA); + if (computedNormalB.dot(normalB) < 0) { - computedNormalB*=-1; + computedNormalB *= -1; info->m_flags |= TRI_INFO_V2V0_SWAP_NORMALB; } #ifdef DEBUG_INTERNAL_EDGE - if ((computedNormalB-normalB).length()>0.0001) + if ((computedNormalB - normalB).length() > 0.0001) { printf("warning: normals not identical\n"); } -#endif //DEBUG_INTERNAL_EDGE +#endif //DEBUG_INTERNAL_EDGE info->m_edgeV2V0Angle = -correctedAngle; if (isConvex) info->m_flags |= TRI_INFO_V2V0_CONVEX; - break; + break; } - case 3: + case 3: { - btVector3 edge = m_triangleVerticesA[1]-m_triangleVerticesA[2]; - btQuaternion orn(edge,-correctedAngle); - btVector3 computedNormalB = quatRotate(orn,normalA); - if (computedNormalB.dot(normalB)<0) + btVector3 edge = m_triangleVerticesA[1] - m_triangleVerticesA[2]; + btQuaternion orn(edge, -correctedAngle); + btVector3 computedNormalB = quatRotate(orn, normalA); + if (computedNormalB.dot(normalB) < 0) { info->m_flags |= TRI_INFO_V1V2_SWAP_NORMALB; - computedNormalB*=-1; + computedNormalB *= -1; } #ifdef DEBUG_INTERNAL_EDGE - if ((computedNormalB-normalB).length()>0.0001) + if ((computedNormalB - normalB).length() > 0.0001) { printf("warning: normals not identical\n"); } -#endif //DEBUG_INTERNAL_EDGE +#endif //DEBUG_INTERNAL_EDGE info->m_edgeV1V2Angle = -correctedAngle; if (isConvex) @@ -297,18 +283,17 @@ struct btConnectivityProcessor : public btTriangleCallback break; } - default: + default: { // printf("warning: duplicate triangle\n"); } - } } }; ///////////////////////////////////////////////////////// ///////////////////////////////////////////////////////// -void btGenerateInternalEdgeInfo (btBvhTriangleMeshShape*trimeshShape, btTriangleInfoMap* triangleInfoMap) +void btGenerateInternalEdgeInfo(btBvhTriangleMeshShape* trimeshShape, btTriangleInfoMap* triangleInfoMap) { //the user pointer shouldn't already be used for other purposes, we intend to store connectivity info there! if (trimeshShape->getTriangleInfoMap()) @@ -319,46 +304,45 @@ void btGenerateInternalEdgeInfo (btBvhTriangleMeshShape*trimeshShape, btTriangle btStridingMeshInterface* meshInterface = trimeshShape->getMeshInterface(); const btVector3& meshScaling = meshInterface->getScaling(); - for (int partId = 0; partId< meshInterface->getNumSubParts();partId++) + for (int partId = 0; partId < meshInterface->getNumSubParts(); partId++) { - const unsigned char *vertexbase = 0; + const unsigned char* vertexbase = 0; int numverts = 0; PHY_ScalarType type = PHY_INTEGER; int stride = 0; - const unsigned char *indexbase = 0; + const unsigned char* indexbase = 0; int indexstride = 0; int numfaces = 0; PHY_ScalarType indicestype = PHY_INTEGER; //PHY_ScalarType indexType=0; btVector3 triangleVerts[3]; - meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,partId); - btVector3 aabbMin,aabbMax; + meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase, numverts, type, stride, &indexbase, indexstride, numfaces, indicestype, partId); + btVector3 aabbMin, aabbMax; - for (int triangleIndex = 0 ; triangleIndex < numfaces;triangleIndex++) + for (int triangleIndex = 0; triangleIndex < numfaces; triangleIndex++) { - unsigned int* gfxbase = (unsigned int*)(indexbase+triangleIndex*indexstride); + unsigned int* gfxbase = (unsigned int*)(indexbase + triangleIndex * indexstride); - for (int j=2;j>=0;j--) + for (int j = 2; j >= 0; j--) { - - int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; + int graphicsindex = indicestype == PHY_SHORT ? ((unsigned short*)gfxbase)[j] : gfxbase[j]; if (type == PHY_FLOAT) { - float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); + float* graphicsbase = (float*)(vertexbase + graphicsindex * stride); triangleVerts[j] = btVector3( - graphicsbase[0]*meshScaling.getX(), - graphicsbase[1]*meshScaling.getY(), - graphicsbase[2]*meshScaling.getZ()); + graphicsbase[0] * meshScaling.getX(), + graphicsbase[1] * meshScaling.getY(), + graphicsbase[2] * meshScaling.getZ()); } else { - double* graphicsbase = (double*)(vertexbase+graphicsindex*stride); - triangleVerts[j] = btVector3( btScalar(graphicsbase[0]*meshScaling.getX()), btScalar(graphicsbase[1]*meshScaling.getY()), btScalar(graphicsbase[2]*meshScaling.getZ())); + double* graphicsbase = (double*)(vertexbase + graphicsindex * stride); + triangleVerts[j] = btVector3(btScalar(graphicsbase[0] * meshScaling.getX()), btScalar(graphicsbase[1] * meshScaling.getY()), btScalar(graphicsbase[2] * meshScaling.getZ())); } } - aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); - aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); + aabbMin.setValue(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); + aabbMax.setValue(btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT)); aabbMin.setMin(triangleVerts[0]); aabbMax.setMax(triangleVerts[0]); aabbMin.setMin(triangleVerts[1]); @@ -370,140 +354,127 @@ void btGenerateInternalEdgeInfo (btBvhTriangleMeshShape*trimeshShape, btTriangle connectivityProcessor.m_partIdA = partId; connectivityProcessor.m_triangleIndexA = triangleIndex; connectivityProcessor.m_triangleVerticesA = &triangleVerts[0]; - connectivityProcessor.m_triangleInfoMap = triangleInfoMap; + connectivityProcessor.m_triangleInfoMap = triangleInfoMap; - trimeshShape->processAllTriangles(&connectivityProcessor,aabbMin,aabbMax); + trimeshShape->processAllTriangles(&connectivityProcessor, aabbMin, aabbMax); } - } - } - - - // Given a point and a line segment (defined by two points), compute the closest point // in the line. Cap the point at the endpoints of the line segment. -void btNearestPointInLineSegment(const btVector3 &point, const btVector3& line0, const btVector3& line1, btVector3& nearestPoint) +void btNearestPointInLineSegment(const btVector3& point, const btVector3& line0, const btVector3& line1, btVector3& nearestPoint) { - btVector3 lineDelta = line1 - line0; + btVector3 lineDelta = line1 - line0; // Handle degenerate lines - if ( lineDelta.fuzzyZero()) + if (lineDelta.fuzzyZero()) { nearestPoint = line0; } else { - btScalar delta = (point-line0).dot(lineDelta) / (lineDelta).dot(lineDelta); + btScalar delta = (point - line0).dot(lineDelta) / (lineDelta).dot(lineDelta); // Clamp the point to conform to the segment's endpoints - if ( delta < 0 ) + if (delta < 0) delta = 0; - else if ( delta > 1 ) + else if (delta > 1) delta = 1; - nearestPoint = line0 + lineDelta*delta; + nearestPoint = line0 + lineDelta * delta; } } - - - -bool btClampNormal(const btVector3& edge,const btVector3& tri_normal_org,const btVector3& localContactNormalOnB, btScalar correctedEdgeAngle, btVector3 & clampedLocalNormal) +bool btClampNormal(const btVector3& edge, const btVector3& tri_normal_org, const btVector3& localContactNormalOnB, btScalar correctedEdgeAngle, btVector3& clampedLocalNormal) { btVector3 tri_normal = tri_normal_org; //we only have a local triangle normal, not a local contact normal -> only normal in world space... //either compute the current angle all in local space, or all in world space btVector3 edgeCross = edge.cross(tri_normal).normalize(); - btScalar curAngle = btGetAngle(edgeCross,tri_normal,localContactNormalOnB); + btScalar curAngle = btGetAngle(edgeCross, tri_normal, localContactNormalOnB); - if (correctedEdgeAngle<0) + if (correctedEdgeAngle < 0) { if (curAngle < correctedEdgeAngle) { - btScalar diffAngle = correctedEdgeAngle-curAngle; - btQuaternion rotation(edge,diffAngle ); - clampedLocalNormal = btMatrix3x3(rotation)*localContactNormalOnB; + btScalar diffAngle = correctedEdgeAngle - curAngle; + btQuaternion rotation(edge, diffAngle); + clampedLocalNormal = btMatrix3x3(rotation) * localContactNormalOnB; return true; } } - if (correctedEdgeAngle>=0) + if (correctedEdgeAngle >= 0) { if (curAngle > correctedEdgeAngle) { - btScalar diffAngle = correctedEdgeAngle-curAngle; - btQuaternion rotation(edge,diffAngle ); - clampedLocalNormal = btMatrix3x3(rotation)*localContactNormalOnB; + btScalar diffAngle = correctedEdgeAngle - curAngle; + btQuaternion rotation(edge, diffAngle); + clampedLocalNormal = btMatrix3x3(rotation) * localContactNormalOnB; return true; } } return false; } - - /// Changes a btManifoldPoint collision normal to the normal from the mesh. -void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,const btCollisionObjectWrapper* colObj1Wrap, int partId0, int index0, int normalAdjustFlags) +void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap, const btCollisionObjectWrapper* colObj1Wrap, int partId0, int index0, int normalAdjustFlags) { //btAssert(colObj0->getCollisionShape()->getShapeType() == TRIANGLE_SHAPE_PROXYTYPE); if (colObj0Wrap->getCollisionShape()->getShapeType() != TRIANGLE_SHAPE_PROXYTYPE) return; btBvhTriangleMeshShape* trimesh = 0; - - if( colObj0Wrap->getCollisionObject()->getCollisionShape()->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE ) + + if (colObj0Wrap->getCollisionObject()->getCollisionShape()->getShapeType() == SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE) { trimesh = ((btScaledBvhTriangleMeshShape*)colObj0Wrap->getCollisionObject()->getCollisionShape())->getChildShape(); } else { - if (colObj0Wrap->getCollisionObject()->getCollisionShape()->getShapeType()==TRIANGLE_MESH_SHAPE_PROXYTYPE) + if (colObj0Wrap->getCollisionObject()->getCollisionShape()->getShapeType() == TRIANGLE_MESH_SHAPE_PROXYTYPE) { trimesh = (btBvhTriangleMeshShape*)colObj0Wrap->getCollisionObject()->getCollisionShape(); } } - if (trimesh==0) + if (trimesh == 0) return; - btTriangleInfoMap* triangleInfoMapPtr = (btTriangleInfoMap*) trimesh->getTriangleInfoMap(); + btTriangleInfoMap* triangleInfoMapPtr = (btTriangleInfoMap*)trimesh->getTriangleInfoMap(); if (!triangleInfoMapPtr) return; - int hash = btGetHash(partId0,index0); - + int hash = btGetHash(partId0, index0); btTriangleInfo* info = triangleInfoMapPtr->find(hash); if (!info) return; - btScalar frontFacing = (normalAdjustFlags & BT_TRIANGLE_CONVEX_BACKFACE_MODE)==0? 1.f : -1.f; - + btScalar frontFacing = (normalAdjustFlags & BT_TRIANGLE_CONVEX_BACKFACE_MODE) == 0 ? 1.f : -1.f; + const btTriangleShape* tri_shape = static_cast(colObj0Wrap->getCollisionShape()); - btVector3 v0,v1,v2; - tri_shape->getVertex(0,v0); - tri_shape->getVertex(1,v1); - tri_shape->getVertex(2,v2); + btVector3 v0, v1, v2; + tri_shape->getVertex(0, v0); + tri_shape->getVertex(1, v1); + tri_shape->getVertex(2, v2); //btVector3 center = (v0+v1+v2)*btScalar(1./3.); - btVector3 red(1,0,0), green(0,1,0),blue(0,0,1),white(1,1,1),black(0,0,0); + btVector3 red(1, 0, 0), green(0, 1, 0), blue(0, 0, 1), white(1, 1, 1), black(0, 0, 0); btVector3 tri_normal; tri_shape->calcNormal(tri_normal); //btScalar dot = tri_normal.dot(cp.m_normalWorldOnB); btVector3 nearest; - btNearestPointInLineSegment(cp.m_localPointB,v0,v1,nearest); + btNearestPointInLineSegment(cp.m_localPointB, v0, v1, nearest); btVector3 contact = cp.m_localPointB; #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW const btTransform& tr = colObj0->getWorldTransform(); - btDebugDrawLine(tr*nearest,tr*cp.m_localPointB,red); -#endif //BT_INTERNAL_EDGE_DEBUG_DRAW - - + btDebugDrawLine(tr * nearest, tr * cp.m_localPointB, red); +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW bool isNearEdge = false; @@ -511,334 +482,325 @@ void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObjectWr int numConvexEdgeHits = 0; btVector3 localContactNormalOnB = colObj0Wrap->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB; - localContactNormalOnB.normalize();//is this necessary? - + localContactNormalOnB.normalize(); //is this necessary? + // Get closest edge - int bestedge=-1; - btScalar disttobestedge=BT_LARGE_FLOAT; + int bestedge = -1; + btScalar disttobestedge = BT_LARGE_FLOAT; // // Edge 0 -> 1 - if (btFabs(info->m_edgeV0V1Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold) - { - btVector3 nearest; - btNearestPointInLineSegment( cp.m_localPointB, v0, v1, nearest ); - btScalar len=(contact-nearest).length(); - // - if( len < disttobestedge ) - { - bestedge=0; - disttobestedge=len; - } - } + if (btFabs(info->m_edgeV0V1Angle) < triangleInfoMapPtr->m_maxEdgeAngleThreshold) + { + btVector3 nearest; + btNearestPointInLineSegment(cp.m_localPointB, v0, v1, nearest); + btScalar len = (contact - nearest).length(); + // + if (len < disttobestedge) + { + bestedge = 0; + disttobestedge = len; + } + } // Edge 1 -> 2 - if (btFabs(info->m_edgeV1V2Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold) - { - btVector3 nearest; - btNearestPointInLineSegment( cp.m_localPointB, v1, v2, nearest ); - btScalar len=(contact-nearest).length(); - // - if( len < disttobestedge ) - { - bestedge=1; - disttobestedge=len; - } - } + if (btFabs(info->m_edgeV1V2Angle) < triangleInfoMapPtr->m_maxEdgeAngleThreshold) + { + btVector3 nearest; + btNearestPointInLineSegment(cp.m_localPointB, v1, v2, nearest); + btScalar len = (contact - nearest).length(); + // + if (len < disttobestedge) + { + bestedge = 1; + disttobestedge = len; + } + } // Edge 2 -> 0 - if (btFabs(info->m_edgeV2V0Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold) - { - btVector3 nearest; - btNearestPointInLineSegment( cp.m_localPointB, v2, v0, nearest ); - btScalar len=(contact-nearest).length(); - // - if( len < disttobestedge ) - { - bestedge=2; - disttobestedge=len; - } - } - -#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW - btVector3 upfix=tri_normal * btVector3(0.1f,0.1f,0.1f); - btDebugDrawLine(tr * v0 + upfix, tr * v1 + upfix, red ); -#endif - if (btFabs(info->m_edgeV0V1Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold) + if (btFabs(info->m_edgeV2V0Angle) < triangleInfoMapPtr->m_maxEdgeAngleThreshold) { + btVector3 nearest; + btNearestPointInLineSegment(cp.m_localPointB, v2, v0, nearest); + btScalar len = (contact - nearest).length(); + // + if (len < disttobestedge) + { + bestedge = 2; + disttobestedge = len; + } + } + #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW - btDebugDrawLine(tr*contact,tr*(contact+cp.m_normalWorldOnB*10),black); + btVector3 upfix = tri_normal * btVector3(0.1f, 0.1f, 0.1f); + btDebugDrawLine(tr * v0 + upfix, tr * v1 + upfix, red); #endif - btScalar len = (contact-nearest).length(); - if(lenm_edgeDistanceThreshold) - if( bestedge==0 ) - { - btVector3 edge(v0-v1); - isNearEdge = true; - - if (info->m_edgeV0V1Angle==btScalar(0)) - { - numConcaveEdgeHits++; - } else + if (btFabs(info->m_edgeV0V1Angle) < triangleInfoMapPtr->m_maxEdgeAngleThreshold) + { +#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr * contact, tr * (contact + cp.m_normalWorldOnB * 10), black); +#endif + btScalar len = (contact - nearest).length(); + if (len < triangleInfoMapPtr->m_edgeDistanceThreshold) + if (bestedge == 0) { + btVector3 edge(v0 - v1); + isNearEdge = true; - bool isEdgeConvex = (info->m_flags & TRI_INFO_V0V1_CONVEX); - btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1); - #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW - btDebugDrawLine(tr*nearest,tr*(nearest+swapFactor*tri_normal*10),white); - #endif //BT_INTERNAL_EDGE_DEBUG_DRAW - - btVector3 nA = swapFactor * tri_normal; - - btQuaternion orn(edge,info->m_edgeV0V1Angle); - btVector3 computedNormalB = quatRotate(orn,tri_normal); - if (info->m_flags & TRI_INFO_V0V1_SWAP_NORMALB) - computedNormalB*=-1; - btVector3 nB = swapFactor*computedNormalB; - - btScalar NdotA = localContactNormalOnB.dot(nA); - btScalar NdotB = localContactNormalOnB.dot(nB); - bool backFacingNormal = (NdotA< triangleInfoMapPtr->m_convexEpsilon) && (NdotBm_convexEpsilon); - -#ifdef DEBUG_INTERNAL_EDGE - { - - btDebugDrawLine(cp.getPositionWorldOnB(),cp.getPositionWorldOnB()+tr.getBasis()*(nB*20),red); - } -#endif //DEBUG_INTERNAL_EDGE - - - if (backFacingNormal) + if (info->m_edgeV0V1Angle == btScalar(0)) { numConcaveEdgeHits++; } else { - numConvexEdgeHits++; - btVector3 clampedLocalNormal; - bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB, info->m_edgeV0V1Angle,clampedLocalNormal); - if (isClamped) + bool isEdgeConvex = (info->m_flags & TRI_INFO_V0V1_CONVEX); + btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1); +#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr * nearest, tr * (nearest + swapFactor * tri_normal * 10), white); +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW + + btVector3 nA = swapFactor * tri_normal; + + btQuaternion orn(edge, info->m_edgeV0V1Angle); + btVector3 computedNormalB = quatRotate(orn, tri_normal); + if (info->m_flags & TRI_INFO_V0V1_SWAP_NORMALB) + computedNormalB *= -1; + btVector3 nB = swapFactor * computedNormalB; + + btScalar NdotA = localContactNormalOnB.dot(nA); + btScalar NdotB = localContactNormalOnB.dot(nB); + bool backFacingNormal = (NdotA < triangleInfoMapPtr->m_convexEpsilon) && (NdotB < triangleInfoMapPtr->m_convexEpsilon); + +#ifdef DEBUG_INTERNAL_EDGE { - if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED)!=0) || (clampedLocalNormal.dot(frontFacing*tri_normal)>0)) + btDebugDrawLine(cp.getPositionWorldOnB(), cp.getPositionWorldOnB() + tr.getBasis() * (nB * 20), red); + } +#endif //DEBUG_INTERNAL_EDGE + + if (backFacingNormal) + { + numConcaveEdgeHits++; + } + else + { + numConvexEdgeHits++; + btVector3 clampedLocalNormal; + bool isClamped = btClampNormal(edge, swapFactor * tri_normal, localContactNormalOnB, info->m_edgeV0V1Angle, clampedLocalNormal); + if (isClamped) { - btVector3 newNormal = colObj0Wrap->getWorldTransform().getBasis() * clampedLocalNormal; - // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB); - cp.m_normalWorldOnB = newNormal; - // Reproject collision point along normal. (what about cp.m_distance1?) - cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1; - cp.m_localPointB = colObj0Wrap->getWorldTransform().invXform(cp.m_positionWorldOnB); - + if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED) != 0) || (clampedLocalNormal.dot(frontFacing * tri_normal) > 0)) + { + btVector3 newNormal = colObj0Wrap->getWorldTransform().getBasis() * clampedLocalNormal; + // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB); + cp.m_normalWorldOnB = newNormal; + // Reproject collision point along normal. (what about cp.m_distance1?) + cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1; + cp.m_localPointB = colObj0Wrap->getWorldTransform().invXform(cp.m_positionWorldOnB); + } } } } } - } } - btNearestPointInLineSegment(contact,v1,v2,nearest); + btNearestPointInLineSegment(contact, v1, v2, nearest); #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW - btDebugDrawLine(tr*nearest,tr*cp.m_localPointB,green); -#endif //BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr * nearest, tr * cp.m_localPointB, green); +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW - btDebugDrawLine(tr * v1 + upfix, tr * v2 + upfix , green ); -#endif + btDebugDrawLine(tr * v1 + upfix, tr * v2 + upfix, green); +#endif - if (btFabs(info->m_edgeV1V2Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold) + if (btFabs(info->m_edgeV1V2Angle) < triangleInfoMapPtr->m_maxEdgeAngleThreshold) { #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW - btDebugDrawLine(tr*contact,tr*(contact+cp.m_normalWorldOnB*10),black); -#endif //BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr * contact, tr * (contact + cp.m_normalWorldOnB * 10), black); +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW - - - btScalar len = (contact-nearest).length(); - if(lenm_edgeDistanceThreshold) - if( bestedge==1 ) - { - isNearEdge = true; + btScalar len = (contact - nearest).length(); + if (len < triangleInfoMapPtr->m_edgeDistanceThreshold) + if (bestedge == 1) + { + isNearEdge = true; #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW - btDebugDrawLine(tr*nearest,tr*(nearest+tri_normal*10),white); -#endif //BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr * nearest, tr * (nearest + tri_normal * 10), white); +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW - btVector3 edge(v1-v2); + btVector3 edge(v1 - v2); - isNearEdge = true; + isNearEdge = true; - if (info->m_edgeV1V2Angle == btScalar(0)) - { - numConcaveEdgeHits++; - } else - { - bool isEdgeConvex = (info->m_flags & TRI_INFO_V1V2_CONVEX)!=0; - btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1); - #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW - btDebugDrawLine(tr*nearest,tr*(nearest+swapFactor*tri_normal*10),white); - #endif //BT_INTERNAL_EDGE_DEBUG_DRAW - - btVector3 nA = swapFactor * tri_normal; - - btQuaternion orn(edge,info->m_edgeV1V2Angle); - btVector3 computedNormalB = quatRotate(orn,tri_normal); - if (info->m_flags & TRI_INFO_V1V2_SWAP_NORMALB) - computedNormalB*=-1; - btVector3 nB = swapFactor*computedNormalB; - -#ifdef DEBUG_INTERNAL_EDGE - { - btDebugDrawLine(cp.getPositionWorldOnB(),cp.getPositionWorldOnB()+tr.getBasis()*(nB*20),red); - } -#endif //DEBUG_INTERNAL_EDGE - - - btScalar NdotA = localContactNormalOnB.dot(nA); - btScalar NdotB = localContactNormalOnB.dot(nB); - bool backFacingNormal = (NdotA< triangleInfoMapPtr->m_convexEpsilon) && (NdotBm_convexEpsilon); - - if (backFacingNormal) + if (info->m_edgeV1V2Angle == btScalar(0)) { numConcaveEdgeHits++; } else { - numConvexEdgeHits++; - btVector3 localContactNormalOnB = colObj0Wrap->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB; - btVector3 clampedLocalNormal; - bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB, info->m_edgeV1V2Angle,clampedLocalNormal); - if (isClamped) + bool isEdgeConvex = (info->m_flags & TRI_INFO_V1V2_CONVEX) != 0; + btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1); +#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr * nearest, tr * (nearest + swapFactor * tri_normal * 10), white); +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW + + btVector3 nA = swapFactor * tri_normal; + + btQuaternion orn(edge, info->m_edgeV1V2Angle); + btVector3 computedNormalB = quatRotate(orn, tri_normal); + if (info->m_flags & TRI_INFO_V1V2_SWAP_NORMALB) + computedNormalB *= -1; + btVector3 nB = swapFactor * computedNormalB; + +#ifdef DEBUG_INTERNAL_EDGE { - if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED)!=0) || (clampedLocalNormal.dot(frontFacing*tri_normal)>0)) + btDebugDrawLine(cp.getPositionWorldOnB(), cp.getPositionWorldOnB() + tr.getBasis() * (nB * 20), red); + } +#endif //DEBUG_INTERNAL_EDGE + + btScalar NdotA = localContactNormalOnB.dot(nA); + btScalar NdotB = localContactNormalOnB.dot(nB); + bool backFacingNormal = (NdotA < triangleInfoMapPtr->m_convexEpsilon) && (NdotB < triangleInfoMapPtr->m_convexEpsilon); + + if (backFacingNormal) + { + numConcaveEdgeHits++; + } + else + { + numConvexEdgeHits++; + btVector3 localContactNormalOnB = colObj0Wrap->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB; + btVector3 clampedLocalNormal; + bool isClamped = btClampNormal(edge, swapFactor * tri_normal, localContactNormalOnB, info->m_edgeV1V2Angle, clampedLocalNormal); + if (isClamped) { - btVector3 newNormal = colObj0Wrap->getWorldTransform().getBasis() * clampedLocalNormal; - // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB); - cp.m_normalWorldOnB = newNormal; - // Reproject collision point along normal. - cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1; - cp.m_localPointB = colObj0Wrap->getWorldTransform().invXform(cp.m_positionWorldOnB); + if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED) != 0) || (clampedLocalNormal.dot(frontFacing * tri_normal) > 0)) + { + btVector3 newNormal = colObj0Wrap->getWorldTransform().getBasis() * clampedLocalNormal; + // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB); + cp.m_normalWorldOnB = newNormal; + // Reproject collision point along normal. + cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1; + cp.m_localPointB = colObj0Wrap->getWorldTransform().invXform(cp.m_positionWorldOnB); + } } } } } - } } - btNearestPointInLineSegment(contact,v2,v0,nearest); + btNearestPointInLineSegment(contact, v2, v0, nearest); #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW - btDebugDrawLine(tr*nearest,tr*cp.m_localPointB,blue); -#endif //BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr * nearest, tr * cp.m_localPointB, blue); +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW - btDebugDrawLine(tr * v2 + upfix, tr * v0 + upfix , blue ); -#endif + btDebugDrawLine(tr * v2 + upfix, tr * v0 + upfix, blue); +#endif - if (btFabs(info->m_edgeV2V0Angle)< triangleInfoMapPtr->m_maxEdgeAngleThreshold) + if (btFabs(info->m_edgeV2V0Angle) < triangleInfoMapPtr->m_maxEdgeAngleThreshold) { - #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW - btDebugDrawLine(tr*contact,tr*(contact+cp.m_normalWorldOnB*10),black); -#endif //BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr * contact, tr * (contact + cp.m_normalWorldOnB * 10), black); +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW - btScalar len = (contact-nearest).length(); - if(lenm_edgeDistanceThreshold) - if( bestedge==2 ) - { - isNearEdge = true; + btScalar len = (contact - nearest).length(); + if (len < triangleInfoMapPtr->m_edgeDistanceThreshold) + if (bestedge == 2) + { + isNearEdge = true; #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW - btDebugDrawLine(tr*nearest,tr*(nearest+tri_normal*10),white); -#endif //BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr * nearest, tr * (nearest + tri_normal * 10), white); +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW - btVector3 edge(v2-v0); + btVector3 edge(v2 - v0); - if (info->m_edgeV2V0Angle==btScalar(0)) - { - numConcaveEdgeHits++; - } else - { - - bool isEdgeConvex = (info->m_flags & TRI_INFO_V2V0_CONVEX)!=0; - btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1); - #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW - btDebugDrawLine(tr*nearest,tr*(nearest+swapFactor*tri_normal*10),white); - #endif //BT_INTERNAL_EDGE_DEBUG_DRAW - - btVector3 nA = swapFactor * tri_normal; - btQuaternion orn(edge,info->m_edgeV2V0Angle); - btVector3 computedNormalB = quatRotate(orn,tri_normal); - if (info->m_flags & TRI_INFO_V2V0_SWAP_NORMALB) - computedNormalB*=-1; - btVector3 nB = swapFactor*computedNormalB; - -#ifdef DEBUG_INTERNAL_EDGE - { - btDebugDrawLine(cp.getPositionWorldOnB(),cp.getPositionWorldOnB()+tr.getBasis()*(nB*20),red); - } -#endif //DEBUG_INTERNAL_EDGE - - btScalar NdotA = localContactNormalOnB.dot(nA); - btScalar NdotB = localContactNormalOnB.dot(nB); - bool backFacingNormal = (NdotA< triangleInfoMapPtr->m_convexEpsilon) && (NdotBm_convexEpsilon); - - if (backFacingNormal) + if (info->m_edgeV2V0Angle == btScalar(0)) { numConcaveEdgeHits++; } else { - numConvexEdgeHits++; - // printf("hitting convex edge\n"); + bool isEdgeConvex = (info->m_flags & TRI_INFO_V2V0_CONVEX) != 0; + btScalar swapFactor = isEdgeConvex ? btScalar(1) : btScalar(-1); +#ifdef BT_INTERNAL_EDGE_DEBUG_DRAW + btDebugDrawLine(tr * nearest, tr * (nearest + swapFactor * tri_normal * 10), white); +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW + btVector3 nA = swapFactor * tri_normal; + btQuaternion orn(edge, info->m_edgeV2V0Angle); + btVector3 computedNormalB = quatRotate(orn, tri_normal); + if (info->m_flags & TRI_INFO_V2V0_SWAP_NORMALB) + computedNormalB *= -1; + btVector3 nB = swapFactor * computedNormalB; - btVector3 localContactNormalOnB = colObj0Wrap->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB; - btVector3 clampedLocalNormal; - bool isClamped = btClampNormal(edge,swapFactor*tri_normal,localContactNormalOnB,info->m_edgeV2V0Angle,clampedLocalNormal); - if (isClamped) +#ifdef DEBUG_INTERNAL_EDGE { - if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED)!=0) || (clampedLocalNormal.dot(frontFacing*tri_normal)>0)) + btDebugDrawLine(cp.getPositionWorldOnB(), cp.getPositionWorldOnB() + tr.getBasis() * (nB * 20), red); + } +#endif //DEBUG_INTERNAL_EDGE + + btScalar NdotA = localContactNormalOnB.dot(nA); + btScalar NdotB = localContactNormalOnB.dot(nB); + bool backFacingNormal = (NdotA < triangleInfoMapPtr->m_convexEpsilon) && (NdotB < triangleInfoMapPtr->m_convexEpsilon); + + if (backFacingNormal) + { + numConcaveEdgeHits++; + } + else + { + numConvexEdgeHits++; + // printf("hitting convex edge\n"); + + btVector3 localContactNormalOnB = colObj0Wrap->getWorldTransform().getBasis().transpose() * cp.m_normalWorldOnB; + btVector3 clampedLocalNormal; + bool isClamped = btClampNormal(edge, swapFactor * tri_normal, localContactNormalOnB, info->m_edgeV2V0Angle, clampedLocalNormal); + if (isClamped) { - btVector3 newNormal = colObj0Wrap->getWorldTransform().getBasis() * clampedLocalNormal; - // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB); - cp.m_normalWorldOnB = newNormal; - // Reproject collision point along normal. - cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1; - cp.m_localPointB = colObj0Wrap->getWorldTransform().invXform(cp.m_positionWorldOnB); + if (((normalAdjustFlags & BT_TRIANGLE_CONVEX_DOUBLE_SIDED) != 0) || (clampedLocalNormal.dot(frontFacing * tri_normal) > 0)) + { + btVector3 newNormal = colObj0Wrap->getWorldTransform().getBasis() * clampedLocalNormal; + // cp.m_distance1 = cp.m_distance1 * newNormal.dot(cp.m_normalWorldOnB); + cp.m_normalWorldOnB = newNormal; + // Reproject collision point along normal. + cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1; + cp.m_localPointB = colObj0Wrap->getWorldTransform().invXform(cp.m_positionWorldOnB); + } } } - } + } } - - - } } #ifdef DEBUG_INTERNAL_EDGE { - btVector3 color(0,1,1); - btDebugDrawLine(cp.getPositionWorldOnB(),cp.getPositionWorldOnB()+cp.m_normalWorldOnB*10,color); + btVector3 color(0, 1, 1); + btDebugDrawLine(cp.getPositionWorldOnB(), cp.getPositionWorldOnB() + cp.m_normalWorldOnB * 10, color); } -#endif //DEBUG_INTERNAL_EDGE +#endif //DEBUG_INTERNAL_EDGE if (isNearEdge) { - - if (numConcaveEdgeHits>0) + if (numConcaveEdgeHits > 0) { - if ((normalAdjustFlags & BT_TRIANGLE_CONCAVE_DOUBLE_SIDED)!=0) + if ((normalAdjustFlags & BT_TRIANGLE_CONCAVE_DOUBLE_SIDED) != 0) { //fix tri_normal so it pointing the same direction as the current local contact normal if (tri_normal.dot(localContactNormalOnB) < 0) { tri_normal *= -1; } - cp.m_normalWorldOnB = colObj0Wrap->getWorldTransform().getBasis()*tri_normal; - } else + cp.m_normalWorldOnB = colObj0Wrap->getWorldTransform().getBasis() * tri_normal; + } + else { - btVector3 newNormal = tri_normal *frontFacing; + btVector3 newNormal = tri_normal * frontFacing; //if the tri_normal is pointing opposite direction as the current local contact normal, skip it - btScalar d = newNormal.dot(localContactNormalOnB) ; - if (d< 0) + btScalar d = newNormal.dot(localContactNormalOnB); + if (d < 0) { return; } //modify the normal to be the triangle normal (or backfacing normal) - cp.m_normalWorldOnB = colObj0Wrap->getWorldTransform().getBasis() *newNormal; + cp.m_normalWorldOnB = colObj0Wrap->getWorldTransform().getBasis() * newNormal; } - + // Reproject collision point along normal. cp.m_positionWorldOnB = cp.m_positionWorldOnA - cp.m_normalWorldOnB * cp.m_distance1; cp.m_localPointB = colObj0Wrap->getWorldTransform().invXform(cp.m_positionWorldOnB); diff --git a/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h b/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h index 7d9aafeee..9d9cff040 100644 --- a/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h +++ b/src/BulletCollision/CollisionDispatch/btInternalEdgeUtility.h @@ -16,32 +16,26 @@ struct btCollisionObjectWrapper; class btManifoldPoint; class btIDebugDraw; - - enum btInternalEdgeAdjustFlags { BT_TRIANGLE_CONVEX_BACKFACE_MODE = 1, - BT_TRIANGLE_CONCAVE_DOUBLE_SIDED = 2, //double sided options are experimental, single sided is recommended + BT_TRIANGLE_CONCAVE_DOUBLE_SIDED = 2, //double sided options are experimental, single sided is recommended BT_TRIANGLE_CONVEX_DOUBLE_SIDED = 4 }; - ///Call btGenerateInternalEdgeInfo to create triangle info, store in the shape 'userInfo' -void btGenerateInternalEdgeInfo (btBvhTriangleMeshShape*trimeshShape, btTriangleInfoMap* triangleInfoMap); - +void btGenerateInternalEdgeInfo(btBvhTriangleMeshShape* trimeshShape, btTriangleInfoMap* triangleInfoMap); ///Call the btFixMeshNormal to adjust the collision normal, using the triangle info map (generated using btGenerateInternalEdgeInfo) ///If this info map is missing, or the triangle is not store in this map, nothing will be done -void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObjectWrapper* trimeshColObj0Wrap,const btCollisionObjectWrapper* otherColObj1Wrap, int partId0, int index0, int normalAdjustFlags = 0); +void btAdjustInternalEdgeContacts(btManifoldPoint& cp, const btCollisionObjectWrapper* trimeshColObj0Wrap, const btCollisionObjectWrapper* otherColObj1Wrap, int partId0, int index0, int normalAdjustFlags = 0); ///Enable the BT_INTERNAL_EDGE_DEBUG_DRAW define and call btSetDebugDrawer, to get visual info to see if the internal edge utility works properly. ///If the utility doesn't work properly, you might have to adjust the threshold values in btTriangleInfoMap //#define BT_INTERNAL_EDGE_DEBUG_DRAW #ifdef BT_INTERNAL_EDGE_DEBUG_DRAW -void btSetDebugDrawer(btIDebugDraw* debugDrawer); -#endif //BT_INTERNAL_EDGE_DEBUG_DRAW - - -#endif //BT_INTERNAL_EDGE_UTILITY_H +void btSetDebugDrawer(btIDebugDraw* debugDrawer); +#endif //BT_INTERNAL_EDGE_DEBUG_DRAW +#endif //BT_INTERNAL_EDGE_UTILITY_H diff --git a/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp b/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp index 23c73c882..770eb2436 100644 --- a/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp +++ b/src/BulletCollision/CollisionDispatch/btManifoldResult.cpp @@ -13,106 +13,102 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btManifoldResult.h" #include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" #include "BulletCollision/CollisionDispatch/btCollisionObject.h" #include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" ///This is to allow MaterialCombiner/Custom Friction/Restitution values -ContactAddedCallback gContactAddedCallback=0; +ContactAddedCallback gContactAddedCallback = 0; -CalculateCombinedCallback gCalculateCombinedRestitutionCallback = &btManifoldResult::calculateCombinedRestitution; -CalculateCombinedCallback gCalculateCombinedFrictionCallback = &btManifoldResult::calculateCombinedFriction; -CalculateCombinedCallback gCalculateCombinedRollingFrictionCallback = &btManifoldResult::calculateCombinedRollingFriction; -CalculateCombinedCallback gCalculateCombinedSpinningFrictionCallback = &btManifoldResult::calculateCombinedSpinningFriction; -CalculateCombinedCallback gCalculateCombinedContactDampingCallback = &btManifoldResult::calculateCombinedContactDamping; -CalculateCombinedCallback gCalculateCombinedContactStiffnessCallback = &btManifoldResult::calculateCombinedContactStiffness; +CalculateCombinedCallback gCalculateCombinedRestitutionCallback = &btManifoldResult::calculateCombinedRestitution; +CalculateCombinedCallback gCalculateCombinedFrictionCallback = &btManifoldResult::calculateCombinedFriction; +CalculateCombinedCallback gCalculateCombinedRollingFrictionCallback = &btManifoldResult::calculateCombinedRollingFriction; +CalculateCombinedCallback gCalculateCombinedSpinningFrictionCallback = &btManifoldResult::calculateCombinedSpinningFriction; +CalculateCombinedCallback gCalculateCombinedContactDampingCallback = &btManifoldResult::calculateCombinedContactDamping; +CalculateCombinedCallback gCalculateCombinedContactStiffnessCallback = &btManifoldResult::calculateCombinedContactStiffness; -btScalar btManifoldResult::calculateCombinedRollingFriction(const btCollisionObject* body0,const btCollisionObject* body1) +btScalar btManifoldResult::calculateCombinedRollingFriction(const btCollisionObject* body0, const btCollisionObject* body1) { btScalar friction = body0->getRollingFriction() * body1->getFriction() + body1->getRollingFriction() * body0->getFriction(); - const btScalar MAX_FRICTION = btScalar(10.); + const btScalar MAX_FRICTION = btScalar(10.); if (friction < -MAX_FRICTION) friction = -MAX_FRICTION; if (friction > MAX_FRICTION) friction = MAX_FRICTION; return friction; - } -btScalar btManifoldResult::calculateCombinedSpinningFriction(const btCollisionObject* body0,const btCollisionObject* body1) +btScalar btManifoldResult::calculateCombinedSpinningFriction(const btCollisionObject* body0, const btCollisionObject* body1) { - btScalar friction = body0->getSpinningFriction() * body1->getFriction() + body1->getSpinningFriction() * body0->getFriction(); - - const btScalar MAX_FRICTION = btScalar(10.); - if (friction < -MAX_FRICTION) - friction = -MAX_FRICTION; - if (friction > MAX_FRICTION) - friction = MAX_FRICTION; - return friction; + btScalar friction = body0->getSpinningFriction() * body1->getFriction() + body1->getSpinningFriction() * body0->getFriction(); + + const btScalar MAX_FRICTION = btScalar(10.); + if (friction < -MAX_FRICTION) + friction = -MAX_FRICTION; + if (friction > MAX_FRICTION) + friction = MAX_FRICTION; + return friction; } ///User can override this material combiner by implementing gContactAddedCallback and setting body0->m_collisionFlags |= btCollisionObject::customMaterialCallback; -btScalar btManifoldResult::calculateCombinedFriction(const btCollisionObject* body0,const btCollisionObject* body1) +btScalar btManifoldResult::calculateCombinedFriction(const btCollisionObject* body0, const btCollisionObject* body1) { btScalar friction = body0->getFriction() * body1->getFriction(); - const btScalar MAX_FRICTION = btScalar(10.); + const btScalar MAX_FRICTION = btScalar(10.); if (friction < -MAX_FRICTION) friction = -MAX_FRICTION; if (friction > MAX_FRICTION) friction = MAX_FRICTION; return friction; - } -btScalar btManifoldResult::calculateCombinedRestitution(const btCollisionObject* body0,const btCollisionObject* body1) +btScalar btManifoldResult::calculateCombinedRestitution(const btCollisionObject* body0, const btCollisionObject* body1) { return body0->getRestitution() * body1->getRestitution(); } -btScalar btManifoldResult::calculateCombinedContactDamping(const btCollisionObject* body0,const btCollisionObject* body1) +btScalar btManifoldResult::calculateCombinedContactDamping(const btCollisionObject* body0, const btCollisionObject* body1) { - return body0->getContactDamping() + body1->getContactDamping(); + return body0->getContactDamping() + body1->getContactDamping(); } -btScalar btManifoldResult::calculateCombinedContactStiffness(const btCollisionObject* body0,const btCollisionObject* body1) +btScalar btManifoldResult::calculateCombinedContactStiffness(const btCollisionObject* body0, const btCollisionObject* body1) { - - btScalar s0 = body0->getContactStiffness(); - btScalar s1 = body1->getContactStiffness(); - - btScalar tmp0 = btScalar(1)/s0; - btScalar tmp1 = btScalar(1)/s1; - btScalar combinedStiffness = btScalar(1) / (tmp0+tmp1); - return combinedStiffness; + btScalar s0 = body0->getContactStiffness(); + btScalar s1 = body1->getContactStiffness(); + + btScalar tmp0 = btScalar(1) / s0; + btScalar tmp1 = btScalar(1) / s1; + btScalar combinedStiffness = btScalar(1) / (tmp0 + tmp1); + return combinedStiffness; } - -btManifoldResult::btManifoldResult(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) - :m_manifoldPtr(0), - m_body0Wrap(body0Wrap), - m_body1Wrap(body1Wrap) +btManifoldResult::btManifoldResult(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) + : m_manifoldPtr(0), + m_body0Wrap(body0Wrap), + m_body1Wrap(body1Wrap) #ifdef DEBUG_PART_INDEX - ,m_partId0(-1), - m_partId1(-1), - m_index0(-1), - m_index1(-1) -#endif //DEBUG_PART_INDEX - , m_closestPointDistanceThreshold(0) + , + m_partId0(-1), + m_partId1(-1), + m_index0(-1), + m_index1(-1) +#endif //DEBUG_PART_INDEX + , + m_closestPointDistanceThreshold(0) { } - -void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) +void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld, const btVector3& pointInWorld, btScalar depth) { btAssert(m_manifoldPtr); //order in manifold needs to match if (depth > m_manifoldPtr->getContactBreakingThreshold()) -// if (depth > m_manifoldPtr->getContactProcessingThreshold()) + // if (depth > m_manifoldPtr->getContactProcessingThreshold()) return; bool isSwapped = m_manifoldPtr->getBody0() != m_body0Wrap->getCollisionObject(); @@ -122,81 +118,82 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b btVector3 localA; btVector3 localB; - + if (isSwapped) { - localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA ); + localA = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointA); localB = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld); - } else + } + else { - localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA ); + localA = m_body0Wrap->getCollisionObject()->getWorldTransform().invXform(pointA); localB = m_body1Wrap->getCollisionObject()->getWorldTransform().invXform(pointInWorld); } - btManifoldPoint newPt(localA,localB,normalOnBInWorld,depth); + btManifoldPoint newPt(localA, localB, normalOnBInWorld, depth); newPt.m_positionWorldOnA = pointA; newPt.m_positionWorldOnB = pointInWorld; - + int insertIndex = m_manifoldPtr->getCacheEntry(newPt); - newPt.m_combinedFriction = gCalculateCombinedFrictionCallback(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject()); - newPt.m_combinedRestitution = gCalculateCombinedRestitutionCallback(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject()); - newPt.m_combinedRollingFriction = gCalculateCombinedRollingFrictionCallback(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject()); - newPt.m_combinedSpinningFriction = gCalculateCombinedSpinningFrictionCallback(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject()); - - if ( (m_body0Wrap->getCollisionObject()->getCollisionFlags()& btCollisionObject::CF_HAS_CONTACT_STIFFNESS_DAMPING) || - (m_body1Wrap->getCollisionObject()->getCollisionFlags()& btCollisionObject::CF_HAS_CONTACT_STIFFNESS_DAMPING)) - { - newPt.m_combinedContactDamping1 = gCalculateCombinedContactDampingCallback(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject()); - newPt.m_combinedContactStiffness1 = gCalculateCombinedContactStiffnessCallback(m_body0Wrap->getCollisionObject(),m_body1Wrap->getCollisionObject()); - newPt.m_contactPointFlags |= BT_CONTACT_FLAG_CONTACT_STIFFNESS_DAMPING; - } + newPt.m_combinedFriction = gCalculateCombinedFrictionCallback(m_body0Wrap->getCollisionObject(), m_body1Wrap->getCollisionObject()); + newPt.m_combinedRestitution = gCalculateCombinedRestitutionCallback(m_body0Wrap->getCollisionObject(), m_body1Wrap->getCollisionObject()); + newPt.m_combinedRollingFriction = gCalculateCombinedRollingFrictionCallback(m_body0Wrap->getCollisionObject(), m_body1Wrap->getCollisionObject()); + newPt.m_combinedSpinningFriction = gCalculateCombinedSpinningFrictionCallback(m_body0Wrap->getCollisionObject(), m_body1Wrap->getCollisionObject()); - if ( (m_body0Wrap->getCollisionObject()->getCollisionFlags()& btCollisionObject::CF_HAS_FRICTION_ANCHOR) || - (m_body1Wrap->getCollisionObject()->getCollisionFlags()& btCollisionObject::CF_HAS_FRICTION_ANCHOR)) - { - newPt.m_contactPointFlags |= BT_CONTACT_FLAG_FRICTION_ANCHOR; - } + if ((m_body0Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_HAS_CONTACT_STIFFNESS_DAMPING) || + (m_body1Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_HAS_CONTACT_STIFFNESS_DAMPING)) + { + newPt.m_combinedContactDamping1 = gCalculateCombinedContactDampingCallback(m_body0Wrap->getCollisionObject(), m_body1Wrap->getCollisionObject()); + newPt.m_combinedContactStiffness1 = gCalculateCombinedContactStiffnessCallback(m_body0Wrap->getCollisionObject(), m_body1Wrap->getCollisionObject()); + newPt.m_contactPointFlags |= BT_CONTACT_FLAG_CONTACT_STIFFNESS_DAMPING; + } - btPlaneSpace1(newPt.m_normalWorldOnB,newPt.m_lateralFrictionDir1,newPt.m_lateralFrictionDir2); - + if ((m_body0Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_HAS_FRICTION_ANCHOR) || + (m_body1Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_HAS_FRICTION_ANCHOR)) + { + newPt.m_contactPointFlags |= BT_CONTACT_FLAG_FRICTION_ANCHOR; + } - - //BP mod, store contact triangles. + btPlaneSpace1(newPt.m_normalWorldOnB, newPt.m_lateralFrictionDir1, newPt.m_lateralFrictionDir2); + + //BP mod, store contact triangles. if (isSwapped) { newPt.m_partId0 = m_partId1; newPt.m_partId1 = m_partId0; - newPt.m_index0 = m_index1; - newPt.m_index1 = m_index0; - } else + newPt.m_index0 = m_index1; + newPt.m_index1 = m_index0; + } + else { newPt.m_partId0 = m_partId0; newPt.m_partId1 = m_partId1; - newPt.m_index0 = m_index0; - newPt.m_index1 = m_index1; + newPt.m_index0 = m_index0; + newPt.m_index1 = m_index1; } //printf("depth=%f\n",depth); ///@todo, check this for any side effects if (insertIndex >= 0) { //const btManifoldPoint& oldPoint = m_manifoldPtr->getContactPoint(insertIndex); - m_manifoldPtr->replaceContactPoint(newPt,insertIndex); - } else + m_manifoldPtr->replaceContactPoint(newPt, insertIndex); + } + else { insertIndex = m_manifoldPtr->addManifoldPoint(newPt); } - + //User can override friction and/or restitution if (gContactAddedCallback && //and if either of the two bodies requires custom material - ((m_body0Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) || - (m_body1Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK))) + ((m_body0Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK) || + (m_body1Wrap->getCollisionObject()->getCollisionFlags() & btCollisionObject::CF_CUSTOM_MATERIAL_CALLBACK))) { //experimental feature info, for per-triangle material etc. - const btCollisionObjectWrapper* obj0Wrap = isSwapped? m_body1Wrap : m_body0Wrap; - const btCollisionObjectWrapper* obj1Wrap = isSwapped? m_body0Wrap : m_body1Wrap; - (*gContactAddedCallback)(m_manifoldPtr->getContactPoint(insertIndex),obj0Wrap,newPt.m_partId0,newPt.m_index0,obj1Wrap,newPt.m_partId1,newPt.m_index1); + const btCollisionObjectWrapper* obj0Wrap = isSwapped ? m_body1Wrap : m_body0Wrap; + const btCollisionObjectWrapper* obj1Wrap = isSwapped ? m_body0Wrap : m_body1Wrap; + (*gContactAddedCallback)(m_manifoldPtr->getContactPoint(insertIndex), obj0Wrap, newPt.m_partId0, newPt.m_index0, obj1Wrap, newPt.m_partId1, newPt.m_index1); } if (gContactStartedCallback && isNewCollision) @@ -204,4 +201,3 @@ void btManifoldResult::addContactPoint(const btVector3& normalOnBInWorld,const b gContactStartedCallback(m_manifoldPtr); } } - diff --git a/src/BulletCollision/CollisionDispatch/btManifoldResult.h b/src/BulletCollision/CollisionDispatch/btManifoldResult.h index 12cdafd1b..6c0a2d9a4 100644 --- a/src/BulletCollision/CollisionDispatch/btManifoldResult.h +++ b/src/BulletCollision/CollisionDispatch/btManifoldResult.h @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef BT_MANIFOLD_RESULT_H #define BT_MANIFOLD_RESULT_H @@ -29,85 +28,81 @@ class btManifoldPoint; #include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" #include "BulletCollision/CollisionDispatch/btCollisionObject.h" -typedef bool (*ContactAddedCallback)(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap,int partId0,int index0,const btCollisionObjectWrapper* colObj1Wrap,int partId1,int index1); -extern ContactAddedCallback gContactAddedCallback; +typedef bool (*ContactAddedCallback)(btManifoldPoint& cp, const btCollisionObjectWrapper* colObj0Wrap, int partId0, int index0, const btCollisionObjectWrapper* colObj1Wrap, int partId1, int index1); +extern ContactAddedCallback gContactAddedCallback; //#define DEBUG_PART_INDEX 1 /// These callbacks are used to customize the algorith that combine restitution, friction, damping, Stiffness -typedef btScalar (*CalculateCombinedCallback)(const btCollisionObject* body0,const btCollisionObject* body1); +typedef btScalar (*CalculateCombinedCallback)(const btCollisionObject* body0, const btCollisionObject* body1); -extern CalculateCombinedCallback gCalculateCombinedRestitutionCallback; -extern CalculateCombinedCallback gCalculateCombinedFrictionCallback; -extern CalculateCombinedCallback gCalculateCombinedRollingFrictionCallback; -extern CalculateCombinedCallback gCalculateCombinedSpinningFrictionCallback; -extern CalculateCombinedCallback gCalculateCombinedContactDampingCallback; -extern CalculateCombinedCallback gCalculateCombinedContactStiffnessCallback; +extern CalculateCombinedCallback gCalculateCombinedRestitutionCallback; +extern CalculateCombinedCallback gCalculateCombinedFrictionCallback; +extern CalculateCombinedCallback gCalculateCombinedRollingFrictionCallback; +extern CalculateCombinedCallback gCalculateCombinedSpinningFrictionCallback; +extern CalculateCombinedCallback gCalculateCombinedContactDampingCallback; +extern CalculateCombinedCallback gCalculateCombinedContactStiffnessCallback; ///btManifoldResult is a helper class to manage contact results. class btManifoldResult : public btDiscreteCollisionDetectorInterface::Result { protected: - btPersistentManifold* m_manifoldPtr; const btCollisionObjectWrapper* m_body0Wrap; const btCollisionObjectWrapper* m_body1Wrap; - int m_partId0; + int m_partId0; int m_partId1; int m_index0; int m_index1; - - -public: +public: btManifoldResult() : #ifdef DEBUG_PART_INDEX - - m_partId0(-1), - m_partId1(-1), - m_index0(-1), - m_index1(-1) -#endif //DEBUG_PART_INDEX - m_closestPointDistanceThreshold(0) + + m_partId0(-1), + m_partId1(-1), + m_index0(-1), + m_index1(-1) +#endif //DEBUG_PART_INDEX + m_closestPointDistanceThreshold(0) { } - btManifoldResult(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap); + btManifoldResult(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap); - virtual ~btManifoldResult() {}; + virtual ~btManifoldResult(){}; - void setPersistentManifold(btPersistentManifold* manifoldPtr) + void setPersistentManifold(btPersistentManifold* manifoldPtr) { m_manifoldPtr = manifoldPtr; } - const btPersistentManifold* getPersistentManifold() const + const btPersistentManifold* getPersistentManifold() const { return m_manifoldPtr; } - btPersistentManifold* getPersistentManifold() + btPersistentManifold* getPersistentManifold() { return m_manifoldPtr; } - virtual void setShapeIdentifiersA(int partId0,int index0) + virtual void setShapeIdentifiersA(int partId0, int index0) { - m_partId0=partId0; - m_index0=index0; + m_partId0 = partId0; + m_index0 = index0; } - virtual void setShapeIdentifiersB( int partId1,int index1) + virtual void setShapeIdentifiersB(int partId1, int index1) { - m_partId1=partId1; - m_index1=index1; + m_partId1 = partId1; + m_index1 = index1; } + virtual void addContactPoint(const btVector3& normalOnBInWorld, const btVector3& pointInWorld, btScalar depth); - virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth); - - SIMD_FORCE_INLINE void refreshContactPoints() + SIMD_FORCE_INLINE void refreshContactPoints() { btAssert(m_manifoldPtr); if (!m_manifoldPtr->getNumContacts()) @@ -117,10 +112,11 @@ public: if (isSwapped) { - m_manifoldPtr->refreshContactPoints(m_body1Wrap->getCollisionObject()->getWorldTransform(),m_body0Wrap->getCollisionObject()->getWorldTransform()); - } else + m_manifoldPtr->refreshContactPoints(m_body1Wrap->getCollisionObject()->getWorldTransform(), m_body0Wrap->getCollisionObject()->getWorldTransform()); + } + else { - m_manifoldPtr->refreshContactPoints(m_body0Wrap->getCollisionObject()->getWorldTransform(),m_body1Wrap->getCollisionObject()->getWorldTransform()); + m_manifoldPtr->refreshContactPoints(m_body0Wrap->getCollisionObject()->getWorldTransform(), m_body1Wrap->getCollisionObject()->getWorldTransform()); } } @@ -153,15 +149,15 @@ public: return m_body1Wrap->getCollisionObject(); } - btScalar m_closestPointDistanceThreshold; + btScalar m_closestPointDistanceThreshold; /// in the future we can let the user override the methods to combine restitution and friction - static btScalar calculateCombinedRestitution(const btCollisionObject* body0,const btCollisionObject* body1); - static btScalar calculateCombinedFriction(const btCollisionObject* body0,const btCollisionObject* body1); - static btScalar calculateCombinedRollingFriction(const btCollisionObject* body0,const btCollisionObject* body1); - static btScalar calculateCombinedSpinningFriction(const btCollisionObject* body0,const btCollisionObject* body1); - static btScalar calculateCombinedContactDamping(const btCollisionObject* body0,const btCollisionObject* body1); - static btScalar calculateCombinedContactStiffness(const btCollisionObject* body0,const btCollisionObject* body1); + static btScalar calculateCombinedRestitution(const btCollisionObject* body0, const btCollisionObject* body1); + static btScalar calculateCombinedFriction(const btCollisionObject* body0, const btCollisionObject* body1); + static btScalar calculateCombinedRollingFriction(const btCollisionObject* body0, const btCollisionObject* body1); + static btScalar calculateCombinedSpinningFriction(const btCollisionObject* body0, const btCollisionObject* body1); + static btScalar calculateCombinedContactDamping(const btCollisionObject* body0, const btCollisionObject* body1); + static btScalar calculateCombinedContactStiffness(const btCollisionObject* body0, const btCollisionObject* body1); }; -#endif //BT_MANIFOLD_RESULT_H +#endif //BT_MANIFOLD_RESULT_H diff --git a/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp b/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp index 91c76a8da..e5097ccbb 100644 --- a/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp +++ b/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.cpp @@ -14,7 +14,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "LinearMath/btScalar.h" #include "btSimulationIslandManager.h" #include "BulletCollision/BroadphaseCollision/btDispatcher.h" @@ -25,8 +24,7 @@ subject to the following restrictions: //#include #include "LinearMath/btQuickprof.h" -btSimulationIslandManager::btSimulationIslandManager(): -m_splitIslands(true) +btSimulationIslandManager::btSimulationIslandManager() : m_splitIslands(true) { } @@ -34,53 +32,47 @@ btSimulationIslandManager::~btSimulationIslandManager() { } - void btSimulationIslandManager::initUnionFind(int n) { - m_unionFind.reset(n); + m_unionFind.reset(n); } - -void btSimulationIslandManager::findUnions(btDispatcher* /* dispatcher */,btCollisionWorld* colWorld) +void btSimulationIslandManager::findUnions(btDispatcher* /* dispatcher */, btCollisionWorld* colWorld) { - { btOverlappingPairCache* pairCachePtr = colWorld->getPairCache(); const int numOverlappingPairs = pairCachePtr->getNumOverlappingPairs(); if (numOverlappingPairs) { - btBroadphasePair* pairPtr = pairCachePtr->getOverlappingPairArrayPtr(); - - for (int i=0;im_clientObject; - btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject; + btBroadphasePair* pairPtr = pairCachePtr->getOverlappingPairArrayPtr(); - if (((colObj0) && ((colObj0)->mergesSimulationIslands())) && - ((colObj1) && ((colObj1)->mergesSimulationIslands()))) + for (int i = 0; i < numOverlappingPairs; i++) { + const btBroadphasePair& collisionPair = pairPtr[i]; + btCollisionObject* colObj0 = (btCollisionObject*)collisionPair.m_pProxy0->m_clientObject; + btCollisionObject* colObj1 = (btCollisionObject*)collisionPair.m_pProxy1->m_clientObject; - m_unionFind.unite((colObj0)->getIslandTag(), - (colObj1)->getIslandTag()); + if (((colObj0) && ((colObj0)->mergesSimulationIslands())) && + ((colObj1) && ((colObj1)->mergesSimulationIslands()))) + { + m_unionFind.unite((colObj0)->getIslandTag(), + (colObj1)->getIslandTag()); + } } } - } } } #ifdef STATIC_SIMULATION_ISLAND_OPTIMIZATION -void btSimulationIslandManager::updateActivationState(btCollisionWorld* colWorld,btDispatcher* dispatcher) +void btSimulationIslandManager::updateActivationState(btCollisionWorld* colWorld, btDispatcher* dispatcher) { - - // put the index into m_controllers into m_tag + // put the index into m_controllers into m_tag int index = 0; { - int i; - for (i=0;igetCollisionObjectArray().size(); i++) + for (i = 0; i < colWorld->getCollisionObjectArray().size(); i++) { - btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i]; + btCollisionObject* collisionObject = colWorld->getCollisionObjectArray()[i]; //Adding filtering here if (!collisionObject->isStaticOrKinematicObject()) { @@ -92,28 +84,29 @@ void btSimulationIslandManager::updateActivationState(btCollisionWorld* colWor } // do the union find - initUnionFind( index ); + initUnionFind(index); - findUnions(dispatcher,colWorld); + findUnions(dispatcher, colWorld); } -void btSimulationIslandManager::storeIslandActivationState(btCollisionWorld* colWorld) +void btSimulationIslandManager::storeIslandActivationState(btCollisionWorld* colWorld) { - // put the islandId ('find' value) into m_tag + // put the islandId ('find' value) into m_tag { int index = 0; int i; - for (i=0;igetCollisionObjectArray().size();i++) + for (i = 0; i < colWorld->getCollisionObjectArray().size(); i++) { - btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i]; + btCollisionObject* collisionObject = colWorld->getCollisionObjectArray()[i]; if (!collisionObject->isStaticOrKinematicObject()) { - collisionObject->setIslandTag( m_unionFind.find(index) ); + collisionObject->setIslandTag(m_unionFind.find(index)); //Set the correct object offset in Collision Object Array m_unionFind.getElement(index).m_sz = i; collisionObject->setCompanionId(-1); index++; - } else + } + else { collisionObject->setIslandTag(-1); collisionObject->setCompanionId(-2); @@ -122,49 +115,44 @@ void btSimulationIslandManager::storeIslandActivationState(btCollisionWorld* c } } - -#else //STATIC_SIMULATION_ISLAND_OPTIMIZATION -void btSimulationIslandManager::updateActivationState(btCollisionWorld* colWorld,btDispatcher* dispatcher) +#else //STATIC_SIMULATION_ISLAND_OPTIMIZATION +void btSimulationIslandManager::updateActivationState(btCollisionWorld* colWorld, btDispatcher* dispatcher) { + initUnionFind(int(colWorld->getCollisionObjectArray().size())); - initUnionFind( int (colWorld->getCollisionObjectArray().size())); - - // put the index into m_controllers into m_tag + // put the index into m_controllers into m_tag { - int index = 0; int i; - for (i=0;igetCollisionObjectArray().size(); i++) + for (i = 0; i < colWorld->getCollisionObjectArray().size(); i++) { - btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i]; + btCollisionObject* collisionObject = colWorld->getCollisionObjectArray()[i]; collisionObject->setIslandTag(index); collisionObject->setCompanionId(-1); collisionObject->setHitFraction(btScalar(1.)); index++; - } } // do the union find - findUnions(dispatcher,colWorld); + findUnions(dispatcher, colWorld); } -void btSimulationIslandManager::storeIslandActivationState(btCollisionWorld* colWorld) +void btSimulationIslandManager::storeIslandActivationState(btCollisionWorld* colWorld) { - // put the islandId ('find' value) into m_tag + // put the islandId ('find' value) into m_tag { - - int index = 0; int i; - for (i=0;igetCollisionObjectArray().size();i++) + for (i = 0; i < colWorld->getCollisionObjectArray().size(); i++) { - btCollisionObject* collisionObject= colWorld->getCollisionObjectArray()[i]; + btCollisionObject* collisionObject = colWorld->getCollisionObjectArray()[i]; if (!collisionObject->isStaticOrKinematicObject()) { - collisionObject->setIslandTag( m_unionFind.find(index) ); + collisionObject->setIslandTag(m_unionFind.find(index)); collisionObject->setCompanionId(-1); - } else + } + else { collisionObject->setIslandTag(-1); collisionObject->setCompanionId(-2); @@ -174,72 +162,59 @@ void btSimulationIslandManager::storeIslandActivationState(btCollisionWorld* col } } -#endif //STATIC_SIMULATION_ISLAND_OPTIMIZATION +#endif //STATIC_SIMULATION_ISLAND_OPTIMIZATION -inline int getIslandId(const btPersistentManifold* lhs) +inline int getIslandId(const btPersistentManifold* lhs) { int islandId; const btCollisionObject* rcolObj0 = static_cast(lhs->getBody0()); const btCollisionObject* rcolObj1 = static_cast(lhs->getBody1()); - islandId= rcolObj0->getIslandTag()>=0?rcolObj0->getIslandTag():rcolObj1->getIslandTag(); + islandId = rcolObj0->getIslandTag() >= 0 ? rcolObj0->getIslandTag() : rcolObj1->getIslandTag(); return islandId; - } - - /// function object that routes calls to operator< class btPersistentManifoldSortPredicate { - public: - - SIMD_FORCE_INLINE bool operator() ( const btPersistentManifold* lhs, const btPersistentManifold* rhs ) const - { - return getIslandId(lhs) < getIslandId(rhs); - } +public: + SIMD_FORCE_INLINE bool operator()(const btPersistentManifold* lhs, const btPersistentManifold* rhs) const + { + return getIslandId(lhs) < getIslandId(rhs); + } }; class btPersistentManifoldSortPredicateDeterministic { public: - - SIMD_FORCE_INLINE bool operator() (const btPersistentManifold* lhs, const btPersistentManifold* rhs) const + SIMD_FORCE_INLINE bool operator()(const btPersistentManifold* lhs, const btPersistentManifold* rhs) const { return ( - (getIslandId(lhs) < getIslandId(rhs)) - || ((getIslandId(lhs) == getIslandId(rhs)) && lhs->getBody0()->getBroadphaseHandle()->m_uniqueId < rhs->getBody0()->getBroadphaseHandle()->m_uniqueId) - ||((getIslandId(lhs) == getIslandId(rhs)) && (lhs->getBody0()->getBroadphaseHandle()->m_uniqueId == rhs->getBody0()->getBroadphaseHandle()->m_uniqueId) && - (lhs->getBody1()->getBroadphaseHandle()->m_uniqueId < rhs->getBody1()->getBroadphaseHandle()->m_uniqueId)) - ); - + (getIslandId(lhs) < getIslandId(rhs)) || ((getIslandId(lhs) == getIslandId(rhs)) && lhs->getBody0()->getBroadphaseHandle()->m_uniqueId < rhs->getBody0()->getBroadphaseHandle()->m_uniqueId) || ((getIslandId(lhs) == getIslandId(rhs)) && (lhs->getBody0()->getBroadphaseHandle()->m_uniqueId == rhs->getBody0()->getBroadphaseHandle()->m_uniqueId) && (lhs->getBody1()->getBroadphaseHandle()->m_uniqueId < rhs->getBody1()->getBroadphaseHandle()->m_uniqueId))); } }; - -void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld) +void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher, btCollisionWorld* collisionWorld) { - BT_PROFILE("islandUnionFindAndQuickSort"); - + btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray(); m_islandmanifold.resize(0); //we are going to sort the unionfind array, and store the element id in the size //afterwards, we clean unionfind, to make sure no-one uses it anymore - + getUnionFind().sortIslands(); int numElem = getUnionFind().getNumElements(); - int endIslandIndex=1; + int endIslandIndex = 1; int startIslandIndex; - //update the sleeping state for bodies, if all are sleeping - for ( startIslandIndex=0;startIslandIndexgetIslandTag() != islandId) && (colObj0->getIslandTag() != -1)) { -// printf("error in island management\n"); + // printf("error in island management\n"); } btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); if (colObj0->getIslandTag() == islandId) { - if (colObj0->getActivationState()== ACTIVE_TAG || - colObj0->getActivationState()== DISABLE_DEACTIVATION) + if (colObj0->getActivationState() == ACTIVE_TAG || + colObj0->getActivationState() == DISABLE_DEACTIVATION) { allSleeping = false; break; } } } - if (allSleeping) { int idx; - for (idx=startIslandIndex;idxgetIslandTag() != islandId) && (colObj0->getIslandTag() != -1)) { -// printf("error in island management\n"); + // printf("error in island management\n"); } btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); if (colObj0->getIslandTag() == islandId) { - colObj0->setActivationState( ISLAND_SLEEPING ); + colObj0->setActivationState(ISLAND_SLEEPING); } } - } else + } + else { - int idx; - for (idx=startIslandIndex;idxgetIslandTag() != islandId) && (colObj0->getIslandTag() != -1)) { -// printf("error in island management\n"); + // printf("error in island management\n"); } btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); if (colObj0->getIslandTag() == islandId) { - if ( colObj0->getActivationState() == ISLAND_SLEEPING) + if (colObj0->getActivationState() == ISLAND_SLEEPING) { - colObj0->setActivationState( WANTS_DEACTIVATION); + colObj0->setActivationState(WANTS_DEACTIVATION); colObj0->setDeactivationTime(0.f); } } @@ -318,34 +292,30 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisio } } - int i; int maxNumManifolds = dispatcher->getNumManifolds(); -//#define SPLIT_ISLANDS 1 -//#ifdef SPLIT_ISLANDS + //#define SPLIT_ISLANDS 1 + //#ifdef SPLIT_ISLANDS - -//#endif //SPLIT_ISLANDS + //#endif //SPLIT_ISLANDS - - for (i=0;igetManifoldByIndexInternal(i); - if (collisionWorld->getDispatchInfo().m_deterministicOverlappingPairs) - { + btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i); + if (collisionWorld->getDispatchInfo().m_deterministicOverlappingPairs) + { if (manifold->getNumContacts() == 0) continue; - } + } - const btCollisionObject* colObj0 = static_cast(manifold->getBody0()); - const btCollisionObject* colObj1 = static_cast(manifold->getBody1()); - - ///@todo: check sleeping conditions! - if (((colObj0) && colObj0->getActivationState() != ISLAND_SLEEPING) || + const btCollisionObject* colObj0 = static_cast(manifold->getBody0()); + const btCollisionObject* colObj1 = static_cast(manifold->getBody1()); + + ///@todo: check sleeping conditions! + if (((colObj0) && colObj0->getActivationState() != ISLAND_SLEEPING) || ((colObj1) && colObj1->getActivationState() != ISLAND_SLEEPING)) { - //kinematic objects don't merge islands, but wake up all connected objects if (colObj0->isKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING) { @@ -357,36 +327,34 @@ void btSimulationIslandManager::buildIslands(btDispatcher* dispatcher,btCollisio if (colObj1->hasContactResponse()) colObj0->activate(); } - if(m_splitIslands) - { + if (m_splitIslands) + { //filtering for response - if (dispatcher->needsResponse(colObj0,colObj1)) + if (dispatcher->needsResponse(colObj0, colObj1)) m_islandmanifold.push_back(manifold); } } } } - - ///@todo: this is random access, it can be walked 'cache friendly'! -void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld, IslandCallback* callback) +void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher, btCollisionWorld* collisionWorld, IslandCallback* callback) { btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray(); - buildIslands(dispatcher,collisionWorld); + buildIslands(dispatcher, collisionWorld); - int endIslandIndex=1; + int endIslandIndex = 1; int startIslandIndex; int numElem = getUnionFind().getNumElements(); BT_PROFILE("processIslands"); - if(!m_splitIslands) + if (!m_splitIslands) { btPersistentManifold** manifold = dispatcher->getInternalManifoldPointer(); int maxNumManifolds = dispatcher->getNumManifolds(); - callback->processIsland(&collisionObjects[0],collisionObjects.size(),manifold,maxNumManifolds, -1); + callback->processIsland(&collisionObjects[0], collisionObjects.size(), manifold, maxNumManifolds, -1); } else { @@ -394,7 +362,7 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher, // Sort the vector using predicate and std::sort //std::sort(islandmanifold.begin(), islandmanifold.end(), btPersistentManifoldSortPredicate); - int numManifolds = int (m_islandmanifold.size()); + int numManifolds = int(m_islandmanifold.size()); //tried a radix sort, but quicksort/heapsort seems still faster //@todo rewrite island management @@ -403,7 +371,8 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher, if (collisionWorld->getDispatchInfo().m_deterministicOverlappingPairs) { m_islandmanifold.quickSort(btPersistentManifoldSortPredicateDeterministic()); - } else + } + else { m_islandmanifold.quickSort(btPersistentManifoldSortPredicate()); } @@ -417,55 +386,49 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher, //int islandId; - - - // printf("Start Islands\n"); + // printf("Start Islands\n"); //traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated - for ( startIslandIndex=0;startIslandIndexisActive()) - islandSleeping = false; - } - + for (endIslandIndex = startIslandIndex; (endIslandIndex < numElem) && (getUnionFind().getElement(endIslandIndex).m_id == islandId); endIslandIndex++) + { + int i = getUnionFind().getElement(endIslandIndex).m_sz; + btCollisionObject* colObj0 = collisionObjects[i]; + m_islandBodies.push_back(colObj0); + if (colObj0->isActive()) + islandSleeping = false; + } //find the accompanying contact manifold for this islandId int numIslandManifolds = 0; btPersistentManifold** startManifold = 0; - if (startManifoldIndexprocessIsland(&m_islandBodies[0],m_islandBodies.size(),startManifold,numIslandManifolds, islandId); - // printf("Island callback of size:%d bodies, %d manifolds\n",islandBodies.size(),numIslandManifolds); + callback->processIsland(&m_islandBodies[0], m_islandBodies.size(), startManifold, numIslandManifolds, islandId); + // printf("Island callback of size:%d bodies, %d manifolds\n",islandBodies.size(),numIslandManifolds); } - + if (numIslandManifolds) { startManifoldIndex = endManifoldIndex; @@ -473,6 +436,5 @@ void btSimulationIslandManager::buildAndProcessIslands(btDispatcher* dispatcher, m_islandBodies.resize(0); } - } // else if(!splitIslands) - + } // else if(!splitIslands) } diff --git a/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h b/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h index e24c6afec..6c2802141 100644 --- a/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h +++ b/src/BulletCollision/CollisionDispatch/btSimulationIslandManager.h @@ -26,45 +26,39 @@ class btCollisionWorld; class btDispatcher; class btPersistentManifold; - ///SimulationIslandManager creates and handles simulation islands, using btUnionFind class btSimulationIslandManager { btUnionFind m_unionFind; - btAlignedObjectArray m_islandmanifold; - btAlignedObjectArray m_islandBodies; - + btAlignedObjectArray m_islandmanifold; + btAlignedObjectArray m_islandBodies; + bool m_splitIslands; - + public: btSimulationIslandManager(); virtual ~btSimulationIslandManager(); + void initUnionFind(int n); - void initUnionFind(int n); - - - btUnionFind& getUnionFind() { return m_unionFind;} + btUnionFind& getUnionFind() { return m_unionFind; } - virtual void updateActivationState(btCollisionWorld* colWorld,btDispatcher* dispatcher); - virtual void storeIslandActivationState(btCollisionWorld* world); + virtual void updateActivationState(btCollisionWorld* colWorld, btDispatcher* dispatcher); + virtual void storeIslandActivationState(btCollisionWorld* world); + void findUnions(btDispatcher* dispatcher, btCollisionWorld* colWorld); - void findUnions(btDispatcher* dispatcher,btCollisionWorld* colWorld); - - - - struct IslandCallback + struct IslandCallback { - virtual ~IslandCallback() {}; + virtual ~IslandCallback(){}; - virtual void processIsland(btCollisionObject** bodies,int numBodies,class btPersistentManifold** manifolds,int numManifolds, int islandId) = 0; + virtual void processIsland(btCollisionObject** bodies, int numBodies, class btPersistentManifold** manifolds, int numManifolds, int islandId) = 0; }; - void buildAndProcessIslands(btDispatcher* dispatcher,btCollisionWorld* collisionWorld, IslandCallback* callback); + void buildAndProcessIslands(btDispatcher* dispatcher, btCollisionWorld* collisionWorld, IslandCallback* callback); - void buildIslands(btDispatcher* dispatcher,btCollisionWorld* colWorld); + void buildIslands(btDispatcher* dispatcher, btCollisionWorld* colWorld); bool getSplitIslands() { @@ -74,8 +68,6 @@ public: { m_splitIslands = doSplitIslands; } - }; -#endif //BT_SIMULATION_ISLAND_MANAGER_H - +#endif //BT_SIMULATION_ISLAND_MANAGER_H diff --git a/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp index e8b567e0e..bc68b285b 100644 --- a/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp +++ b/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.cpp @@ -21,23 +21,22 @@ subject to the following restrictions: #include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" //#include -btSphereBoxCollisionAlgorithm::btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap, bool isSwapped) -: btActivatingCollisionAlgorithm(ci,col0Wrap,col1Wrap), -m_ownManifold(false), -m_manifoldPtr(mf), -m_isSwapped(isSwapped) +btSphereBoxCollisionAlgorithm::btSphereBoxCollisionAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* col0Wrap, const btCollisionObjectWrapper* col1Wrap, bool isSwapped) + : btActivatingCollisionAlgorithm(ci, col0Wrap, col1Wrap), + m_ownManifold(false), + m_manifoldPtr(mf), + m_isSwapped(isSwapped) { - const btCollisionObjectWrapper* sphereObjWrap = m_isSwapped? col1Wrap : col0Wrap; - const btCollisionObjectWrapper* boxObjWrap = m_isSwapped? col0Wrap : col1Wrap; - - if (!m_manifoldPtr && m_dispatcher->needsCollision(sphereObjWrap->getCollisionObject(),boxObjWrap->getCollisionObject())) + const btCollisionObjectWrapper* sphereObjWrap = m_isSwapped ? col1Wrap : col0Wrap; + const btCollisionObjectWrapper* boxObjWrap = m_isSwapped ? col0Wrap : col1Wrap; + + if (!m_manifoldPtr && m_dispatcher->needsCollision(sphereObjWrap->getCollisionObject(), boxObjWrap->getCollisionObject())) { - m_manifoldPtr = m_dispatcher->getNewManifold(sphereObjWrap->getCollisionObject(),boxObjWrap->getCollisionObject()); + m_manifoldPtr = m_dispatcher->getNewManifold(sphereObjWrap->getCollisionObject(), boxObjWrap->getCollisionObject()); m_ownManifold = true; } } - btSphereBoxCollisionAlgorithm::~btSphereBoxCollisionAlgorithm() { if (m_ownManifold) @@ -47,17 +46,15 @@ btSphereBoxCollisionAlgorithm::~btSphereBoxCollisionAlgorithm() } } - - -void btSphereBoxCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) +void btSphereBoxCollisionAlgorithm::processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { (void)dispatchInfo; (void)resultOut; if (!m_manifoldPtr) return; - const btCollisionObjectWrapper* sphereObjWrap = m_isSwapped? body1Wrap : body0Wrap; - const btCollisionObjectWrapper* boxObjWrap = m_isSwapped? body0Wrap : body1Wrap; + const btCollisionObjectWrapper* sphereObjWrap = m_isSwapped ? body1Wrap : body0Wrap; + const btCollisionObjectWrapper* boxObjWrap = m_isSwapped ? body0Wrap : body1Wrap; btVector3 pOnBox; @@ -83,10 +80,9 @@ void btSphereBoxCollisionAlgorithm::processCollision (const btCollisionObjectWra resultOut->refreshContactPoints(); } } - } -btScalar btSphereBoxCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +btScalar btSphereBoxCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0, btCollisionObject* col1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { (void)resultOut; (void)dispatchInfo; @@ -97,27 +93,26 @@ btScalar btSphereBoxCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* return btScalar(1.); } - -bool btSphereBoxCollisionAlgorithm::getSphereDistance(const btCollisionObjectWrapper* boxObjWrap, btVector3& pointOnBox, btVector3& normal, btScalar& penetrationDepth, const btVector3& sphereCenter, btScalar fRadius, btScalar maxContactDistance ) +bool btSphereBoxCollisionAlgorithm::getSphereDistance(const btCollisionObjectWrapper* boxObjWrap, btVector3& pointOnBox, btVector3& normal, btScalar& penetrationDepth, const btVector3& sphereCenter, btScalar fRadius, btScalar maxContactDistance) { - const btBoxShape* boxShape= (const btBoxShape*)boxObjWrap->getCollisionShape(); - btVector3 const &boxHalfExtent = boxShape->getHalfExtentsWithoutMargin(); + const btBoxShape* boxShape = (const btBoxShape*)boxObjWrap->getCollisionShape(); + btVector3 const& boxHalfExtent = boxShape->getHalfExtentsWithoutMargin(); btScalar boxMargin = boxShape->getMargin(); penetrationDepth = 1.0f; // convert the sphere position to the box's local space - btTransform const &m44T = boxObjWrap->getWorldTransform(); + btTransform const& m44T = boxObjWrap->getWorldTransform(); btVector3 sphereRelPos = m44T.invXform(sphereCenter); // Determine the closest point to the sphere center in the box btVector3 closestPoint = sphereRelPos; - closestPoint.setX( btMin(boxHalfExtent.getX(), closestPoint.getX()) ); - closestPoint.setX( btMax(-boxHalfExtent.getX(), closestPoint.getX()) ); - closestPoint.setY( btMin(boxHalfExtent.getY(), closestPoint.getY()) ); - closestPoint.setY( btMax(-boxHalfExtent.getY(), closestPoint.getY()) ); - closestPoint.setZ( btMin(boxHalfExtent.getZ(), closestPoint.getZ()) ); - closestPoint.setZ( btMax(-boxHalfExtent.getZ(), closestPoint.getZ()) ); - + closestPoint.setX(btMin(boxHalfExtent.getX(), closestPoint.getX())); + closestPoint.setX(btMax(-boxHalfExtent.getX(), closestPoint.getX())); + closestPoint.setY(btMin(boxHalfExtent.getY(), closestPoint.getY())); + closestPoint.setY(btMax(-boxHalfExtent.getY(), closestPoint.getY())); + closestPoint.setZ(btMin(boxHalfExtent.getZ(), closestPoint.getZ())); + closestPoint.setZ(btMax(-boxHalfExtent.getZ(), closestPoint.getZ())); + btScalar intersectionDist = fRadius + boxMargin; btScalar contactDist = intersectionDist + maxContactDistance; normal = sphereRelPos - closestPoint; @@ -136,42 +131,42 @@ bool btSphereBoxCollisionAlgorithm::getSphereDistance(const btCollisionObjectWra { distance = -getSpherePenetration(boxHalfExtent, sphereRelPos, closestPoint, normal); } - else //compute the penetration details + else //compute the penetration details { distance = normal.length(); normal /= distance; } pointOnBox = closestPoint + normal * boxMargin; -// v3PointOnSphere = sphereRelPos - (normal * fRadius); + // v3PointOnSphere = sphereRelPos - (normal * fRadius); penetrationDepth = distance - intersectionDist; // transform back in world space btVector3 tmp = m44T(pointOnBox); pointOnBox = tmp; -// tmp = m44T(v3PointOnSphere); -// v3PointOnSphere = tmp; + // tmp = m44T(v3PointOnSphere); + // v3PointOnSphere = tmp; tmp = m44T.getBasis() * normal; normal = tmp; return true; } -btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btVector3 const &boxHalfExtent, btVector3 const &sphereRelPos, btVector3 &closestPoint, btVector3& normal ) +btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration(btVector3 const& boxHalfExtent, btVector3 const& sphereRelPos, btVector3& closestPoint, btVector3& normal) { //project the center of the sphere on the closest face of the box btScalar faceDist = boxHalfExtent.getX() - sphereRelPos.getX(); btScalar minDist = faceDist; - closestPoint.setX( boxHalfExtent.getX() ); - normal.setValue(btScalar(1.0f), btScalar(0.0f), btScalar(0.0f)); + closestPoint.setX(boxHalfExtent.getX()); + normal.setValue(btScalar(1.0f), btScalar(0.0f), btScalar(0.0f)); faceDist = boxHalfExtent.getX() + sphereRelPos.getX(); if (faceDist < minDist) { minDist = faceDist; closestPoint = sphereRelPos; - closestPoint.setX( -boxHalfExtent.getX() ); - normal.setValue(btScalar(-1.0f), btScalar(0.0f), btScalar(0.0f)); + closestPoint.setX(-boxHalfExtent.getX()); + normal.setValue(btScalar(-1.0f), btScalar(0.0f), btScalar(0.0f)); } faceDist = boxHalfExtent.getY() - sphereRelPos.getY(); @@ -179,8 +174,8 @@ btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btVector3 const &b { minDist = faceDist; closestPoint = sphereRelPos; - closestPoint.setY( boxHalfExtent.getY() ); - normal.setValue(btScalar(0.0f), btScalar(1.0f), btScalar(0.0f)); + closestPoint.setY(boxHalfExtent.getY()); + normal.setValue(btScalar(0.0f), btScalar(1.0f), btScalar(0.0f)); } faceDist = boxHalfExtent.getY() + sphereRelPos.getY(); @@ -188,8 +183,8 @@ btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btVector3 const &b { minDist = faceDist; closestPoint = sphereRelPos; - closestPoint.setY( -boxHalfExtent.getY() ); - normal.setValue(btScalar(0.0f), btScalar(-1.0f), btScalar(0.0f)); + closestPoint.setY(-boxHalfExtent.getY()); + normal.setValue(btScalar(0.0f), btScalar(-1.0f), btScalar(0.0f)); } faceDist = boxHalfExtent.getZ() - sphereRelPos.getZ(); @@ -197,8 +192,8 @@ btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btVector3 const &b { minDist = faceDist; closestPoint = sphereRelPos; - closestPoint.setZ( boxHalfExtent.getZ() ); - normal.setValue(btScalar(0.0f), btScalar(0.0f), btScalar(1.0f)); + closestPoint.setZ(boxHalfExtent.getZ()); + normal.setValue(btScalar(0.0f), btScalar(0.0f), btScalar(1.0f)); } faceDist = boxHalfExtent.getZ() + sphereRelPos.getZ(); @@ -206,8 +201,8 @@ btScalar btSphereBoxCollisionAlgorithm::getSpherePenetration( btVector3 const &b { minDist = faceDist; closestPoint = sphereRelPos; - closestPoint.setZ( -boxHalfExtent.getZ() ); - normal.setValue(btScalar(0.0f), btScalar(0.0f), btScalar(-1.0f)); + closestPoint.setZ(-boxHalfExtent.getZ()); + normal.setValue(btScalar(0.0f), btScalar(0.0f), btScalar(-1.0f)); } return minDist; diff --git a/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h index eefaedc9e..3348bc89a 100644 --- a/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h +++ b/src/BulletCollision/CollisionDispatch/btSphereBoxCollisionAlgorithm.h @@ -28,21 +28,20 @@ class btPersistentManifold; /// Other features are frame-coherency (persistent data) and collision response. class btSphereBoxCollisionAlgorithm : public btActivatingCollisionAlgorithm { - bool m_ownManifold; - btPersistentManifold* m_manifoldPtr; - bool m_isSwapped; - -public: + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + bool m_isSwapped; - btSphereBoxCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap, bool isSwapped); +public: + btSphereBoxCollisionAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, bool isSwapped); virtual ~btSphereBoxCollisionAlgorithm(); - virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) { if (m_manifoldPtr && m_ownManifold) { @@ -50,26 +49,25 @@ public: } } - bool getSphereDistance( const btCollisionObjectWrapper* boxObjWrap, btVector3& v3PointOnBox, btVector3& normal, btScalar& penetrationDepth, const btVector3& v3SphereCenter, btScalar fRadius, btScalar maxContactDistance ); + bool getSphereDistance(const btCollisionObjectWrapper* boxObjWrap, btVector3& v3PointOnBox, btVector3& normal, btScalar& penetrationDepth, const btVector3& v3SphereCenter, btScalar fRadius, btScalar maxContactDistance); - btScalar getSpherePenetration( btVector3 const &boxHalfExtent, btVector3 const &sphereRelPos, btVector3 &closestPoint, btVector3& normal ); - - struct CreateFunc :public btCollisionAlgorithmCreateFunc + btScalar getSpherePenetration(btVector3 const& boxHalfExtent, btVector3 const& sphereRelPos, btVector3& closestPoint, btVector3& normal); + + struct CreateFunc : public btCollisionAlgorithmCreateFunc { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereBoxCollisionAlgorithm)); if (!m_swapped) { - return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,false); - } else + return new (mem) btSphereBoxCollisionAlgorithm(0, ci, body0Wrap, body1Wrap, false); + } + else { - return new(mem) btSphereBoxCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,true); + return new (mem) btSphereBoxCollisionAlgorithm(0, ci, body0Wrap, body1Wrap, true); } } }; - }; -#endif //BT_SPHERE_BOX_COLLISION_ALGORITHM_H - +#endif //BT_SPHERE_BOX_COLLISION_ALGORITHM_H diff --git a/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp index 27eaec305..7fa0559f9 100644 --- a/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp +++ b/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.cpp @@ -20,14 +20,14 @@ subject to the following restrictions: #include "BulletCollision/CollisionDispatch/btCollisionObject.h" #include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" -btSphereSphereCollisionAlgorithm::btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap) -: btActivatingCollisionAlgorithm(ci,col0Wrap,col1Wrap), -m_ownManifold(false), -m_manifoldPtr(mf) +btSphereSphereCollisionAlgorithm::btSphereSphereCollisionAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* col0Wrap, const btCollisionObjectWrapper* col1Wrap) + : btActivatingCollisionAlgorithm(ci, col0Wrap, col1Wrap), + m_ownManifold(false), + m_manifoldPtr(mf) { if (!m_manifoldPtr) { - m_manifoldPtr = m_dispatcher->getNewManifold(col0Wrap->getCollisionObject(),col1Wrap->getCollisionObject()); + m_manifoldPtr = m_dispatcher->getNewManifold(col0Wrap->getCollisionObject(), col1Wrap->getCollisionObject()); m_ownManifold = true; } } @@ -41,7 +41,7 @@ btSphereSphereCollisionAlgorithm::~btSphereSphereCollisionAlgorithm() } } -void btSphereSphereCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +void btSphereSphereCollisionAlgorithm::processCollision(const btCollisionObjectWrapper* col0Wrap, const btCollisionObjectWrapper* col1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { (void)dispatchInfo; @@ -53,27 +53,27 @@ void btSphereSphereCollisionAlgorithm::processCollision (const btCollisionObject btSphereShape* sphere0 = (btSphereShape*)col0Wrap->getCollisionShape(); btSphereShape* sphere1 = (btSphereShape*)col1Wrap->getCollisionShape(); - btVector3 diff = col0Wrap->getWorldTransform().getOrigin()- col1Wrap->getWorldTransform().getOrigin(); + btVector3 diff = col0Wrap->getWorldTransform().getOrigin() - col1Wrap->getWorldTransform().getOrigin(); btScalar len = diff.length(); btScalar radius0 = sphere0->getRadius(); btScalar radius1 = sphere1->getRadius(); #ifdef CLEAR_MANIFOLD - m_manifoldPtr->clearManifold(); //don't do this, it disables warmstarting + m_manifoldPtr->clearManifold(); //don't do this, it disables warmstarting #endif ///iff distance positive, don't generate a new contact - if ( len > (radius0+radius1+resultOut->m_closestPointDistanceThreshold)) + if (len > (radius0 + radius1 + resultOut->m_closestPointDistanceThreshold)) { #ifndef CLEAR_MANIFOLD resultOut->refreshContactPoints(); -#endif //CLEAR_MANIFOLD +#endif //CLEAR_MANIFOLD return; } ///distance (negative means penetration) - btScalar dist = len - (radius0+radius1); + btScalar dist = len - (radius0 + radius1); - btVector3 normalOnSurfaceB(1,0,0); + btVector3 normalOnSurfaceB(1, 0, 0); if (len > SIMD_EPSILON) { normalOnSurfaceB = diff / len; @@ -82,20 +82,18 @@ void btSphereSphereCollisionAlgorithm::processCollision (const btCollisionObject ///point on A (worldspace) ///btVector3 pos0 = col0->getWorldTransform().getOrigin() - radius0 * normalOnSurfaceB; ///point on B (worldspace) - btVector3 pos1 = col1Wrap->getWorldTransform().getOrigin() + radius1* normalOnSurfaceB; + btVector3 pos1 = col1Wrap->getWorldTransform().getOrigin() + radius1 * normalOnSurfaceB; /// report a contact. internally this will be kept persistent, and contact reduction is done - - - resultOut->addContactPoint(normalOnSurfaceB,pos1,dist); + + resultOut->addContactPoint(normalOnSurfaceB, pos1, dist); #ifndef CLEAR_MANIFOLD resultOut->refreshContactPoints(); -#endif //CLEAR_MANIFOLD - +#endif //CLEAR_MANIFOLD } -btScalar btSphereSphereCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +btScalar btSphereSphereCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0, btCollisionObject* col1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { (void)col0; (void)col1; diff --git a/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h index 3517a568a..b08d0df76 100644 --- a/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h +++ b/src/BulletCollision/CollisionDispatch/btSphereSphereCollisionAlgorithm.h @@ -28,39 +28,37 @@ class btPersistentManifold; /// Also provides the most basic sample for custom/user btCollisionAlgorithm class btSphereSphereCollisionAlgorithm : public btActivatingCollisionAlgorithm { - bool m_ownManifold; - btPersistentManifold* m_manifoldPtr; - + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + public: - btSphereSphereCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap); + btSphereSphereCollisionAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* col0Wrap, const btCollisionObjectWrapper* col1Wrap); btSphereSphereCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) : btActivatingCollisionAlgorithm(ci) {} - virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) { if (m_manifoldPtr && m_ownManifold) { manifoldArray.push_back(m_manifoldPtr); } } - + virtual ~btSphereSphereCollisionAlgorithm(); - struct CreateFunc :public btCollisionAlgorithmCreateFunc + struct CreateFunc : public btCollisionAlgorithmCreateFunc { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap) + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* col0Wrap, const btCollisionObjectWrapper* col1Wrap) { void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereSphereCollisionAlgorithm)); - return new(mem) btSphereSphereCollisionAlgorithm(0,ci,col0Wrap,col1Wrap); + return new (mem) btSphereSphereCollisionAlgorithm(0, ci, col0Wrap, col1Wrap); } }; - }; -#endif //BT_SPHERE_SPHERE_COLLISION_ALGORITHM_H - +#endif //BT_SPHERE_SPHERE_COLLISION_ALGORITHM_H diff --git a/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp b/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp index 86d4e7440..1bc3056c0 100644 --- a/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp +++ b/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btSphereTriangleCollisionAlgorithm.h" #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" #include "BulletCollision/CollisionShapes/btSphereShape.h" @@ -21,15 +20,15 @@ subject to the following restrictions: #include "SphereTriangleDetector.h" #include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" -btSphereTriangleCollisionAlgorithm::btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool swapped) -: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap), -m_ownManifold(false), -m_manifoldPtr(mf), -m_swapped(swapped) +btSphereTriangleCollisionAlgorithm::btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, bool swapped) + : btActivatingCollisionAlgorithm(ci, body0Wrap, body1Wrap), + m_ownManifold(false), + m_manifoldPtr(mf), + m_swapped(swapped) { if (!m_manifoldPtr) { - m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject()); + m_manifoldPtr = m_dispatcher->getNewManifold(body0Wrap->getCollisionObject(), body1Wrap->getCollisionObject()); m_ownManifold = true; } } @@ -43,36 +42,35 @@ btSphereTriangleCollisionAlgorithm::~btSphereTriangleCollisionAlgorithm() } } -void btSphereTriangleCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* col0Wrap,const btCollisionObjectWrapper* col1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +void btSphereTriangleCollisionAlgorithm::processCollision(const btCollisionObjectWrapper* col0Wrap, const btCollisionObjectWrapper* col1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { if (!m_manifoldPtr) return; - const btCollisionObjectWrapper* sphereObjWrap = m_swapped? col1Wrap : col0Wrap; - const btCollisionObjectWrapper* triObjWrap = m_swapped? col0Wrap : col1Wrap; + const btCollisionObjectWrapper* sphereObjWrap = m_swapped ? col1Wrap : col0Wrap; + const btCollisionObjectWrapper* triObjWrap = m_swapped ? col0Wrap : col1Wrap; btSphereShape* sphere = (btSphereShape*)sphereObjWrap->getCollisionShape(); btTriangleShape* triangle = (btTriangleShape*)triObjWrap->getCollisionShape(); - + /// report a contact. internally this will be kept persistent, and contact reduction is done resultOut->setPersistentManifold(m_manifoldPtr); - SphereTriangleDetector detector(sphere,triangle, m_manifoldPtr->getContactBreakingThreshold()+ resultOut->m_closestPointDistanceThreshold); - + SphereTriangleDetector detector(sphere, triangle, m_manifoldPtr->getContactBreakingThreshold() + resultOut->m_closestPointDistanceThreshold); + btDiscreteCollisionDetectorInterface::ClosestPointInput input; - input.m_maximumDistanceSquared = btScalar(BT_LARGE_FLOAT);///@todo: tighter bounds + input.m_maximumDistanceSquared = btScalar(BT_LARGE_FLOAT); ///@todo: tighter bounds input.m_transformA = sphereObjWrap->getWorldTransform(); input.m_transformB = triObjWrap->getWorldTransform(); bool swapResults = m_swapped; - detector.getClosestPoints(input,*resultOut,dispatchInfo.m_debugDraw,swapResults); + detector.getClosestPoints(input, *resultOut, dispatchInfo.m_debugDraw, swapResults); if (m_ownManifold) resultOut->refreshContactPoints(); - } -btScalar btSphereTriangleCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +btScalar btSphereTriangleCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0, btCollisionObject* col1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { (void)resultOut; (void)dispatchInfo; diff --git a/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h b/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h index 6b6e39a72..d660222f1 100644 --- a/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h +++ b/src/BulletCollision/CollisionDispatch/btSphereTriangleCollisionAlgorithm.h @@ -27,43 +27,39 @@ class btPersistentManifold; /// Also provides the most basic sample for custom/user btCollisionAlgorithm class btSphereTriangleCollisionAlgorithm : public btActivatingCollisionAlgorithm { - bool m_ownManifold; - btPersistentManifold* m_manifoldPtr; - bool m_swapped; - + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + bool m_swapped; + public: - btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool swapped); + btSphereTriangleCollisionAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, bool swapped); btSphereTriangleCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) : btActivatingCollisionAlgorithm(ci) {} - virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) { if (m_manifoldPtr && m_ownManifold) { manifoldArray.push_back(m_manifoldPtr); } } - + virtual ~btSphereTriangleCollisionAlgorithm(); - struct CreateFunc :public btCollisionAlgorithmCreateFunc + struct CreateFunc : public btCollisionAlgorithmCreateFunc { - - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { - void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSphereTriangleCollisionAlgorithm)); - return new(mem) btSphereTriangleCollisionAlgorithm(ci.m_manifold,ci,body0Wrap,body1Wrap,m_swapped); + return new (mem) btSphereTriangleCollisionAlgorithm(ci.m_manifold, ci, body0Wrap, body1Wrap, m_swapped); } }; - }; -#endif //BT_SPHERE_TRIANGLE_COLLISION_ALGORITHM_H - +#endif //BT_SPHERE_TRIANGLE_COLLISION_ALGORITHM_H diff --git a/src/BulletCollision/CollisionDispatch/btUnionFind.cpp b/src/BulletCollision/CollisionDispatch/btUnionFind.cpp index 522293359..816bf1e6a 100644 --- a/src/BulletCollision/CollisionDispatch/btUnionFind.cpp +++ b/src/BulletCollision/CollisionDispatch/btUnionFind.cpp @@ -15,68 +15,60 @@ subject to the following restrictions: #include "btUnionFind.h" - - btUnionFind::~btUnionFind() { Free(); - } btUnionFind::btUnionFind() -{ - +{ } -void btUnionFind::allocate(int N) +void btUnionFind::allocate(int N) { m_elements.resize(N); } -void btUnionFind::Free() +void btUnionFind::Free() { m_elements.clear(); } - -void btUnionFind::reset(int N) +void btUnionFind::reset(int N) { allocate(N); - for (int i = 0; i < N; i++) - { - m_elements[i].m_id = i; m_elements[i].m_sz = 1; - } + for (int i = 0; i < N; i++) + { + m_elements[i].m_id = i; + m_elements[i].m_sz = 1; + } } - class btUnionFindElementSortPredicate { - public: - - bool operator() ( const btElement& lhs, const btElement& rhs ) const - { - return lhs.m_id < rhs.m_id; - } +public: + bool operator()(const btElement& lhs, const btElement& rhs) const + { + return lhs.m_id < rhs.m_id; + } }; ///this is a special operation, destroying the content of btUnionFind. ///it sorts the elements, based on island id, in order to make it easy to iterate over islands -void btUnionFind::sortIslands() +void btUnionFind::sortIslands() { - //first store the original body index, and islandId int numElements = m_elements.size(); - - for (int i=0;i m_elements; +{ +private: + btAlignedObjectArray m_elements; - public: - - btUnionFind(); - ~btUnionFind(); +public: + btUnionFind(); + ~btUnionFind(); - - //this is a special operation, destroying the content of btUnionFind. - //it sorts the elements, based on island id, in order to make it easy to iterate over islands - void sortIslands(); + //this is a special operation, destroying the content of btUnionFind. + //it sorts the elements, based on island id, in order to make it easy to iterate over islands + void sortIslands(); - void reset(int N); + void reset(int N); - SIMD_FORCE_INLINE int getNumElements() const - { - return int(m_elements.size()); - } - SIMD_FORCE_INLINE bool isRoot(int x) const - { - return (x == m_elements[x].m_id); - } + SIMD_FORCE_INLINE int getNumElements() const + { + return int(m_elements.size()); + } + SIMD_FORCE_INLINE bool isRoot(int x) const + { + return (x == m_elements[x].m_id); + } - btElement& getElement(int index) - { - return m_elements[index]; - } - const btElement& getElement(int index) const - { - return m_elements[index]; - } - - void allocate(int N); - void Free(); + btElement& getElement(int index) + { + return m_elements[index]; + } + const btElement& getElement(int index) const + { + return m_elements[index]; + } + void allocate(int N); + void Free(); + int find(int p, int q) + { + return (find(p) == find(q)); + } - - int find(int p, int q) - { - return (find(p) == find(q)); - } - - void unite(int p, int q) - { - int i = find(p), j = find(q); - if (i == j) - return; + void unite(int p, int q) + { + int i = find(p), j = find(q); + if (i == j) + return; #ifndef USE_PATH_COMPRESSION - //weighted quick union, this keeps the 'trees' balanced, and keeps performance of unite O( log(n) ) - if (m_elements[i].m_sz < m_elements[j].m_sz) - { - m_elements[i].m_id = j; m_elements[j].m_sz += m_elements[i].m_sz; - } - else - { - m_elements[j].m_id = i; m_elements[i].m_sz += m_elements[j].m_sz; - } -#else - m_elements[i].m_id = j; m_elements[j].m_sz += m_elements[i].m_sz; -#endif //USE_PATH_COMPRESSION + //weighted quick union, this keeps the 'trees' balanced, and keeps performance of unite O( log(n) ) + if (m_elements[i].m_sz < m_elements[j].m_sz) + { + m_elements[i].m_id = j; + m_elements[j].m_sz += m_elements[i].m_sz; } + else + { + m_elements[j].m_id = i; + m_elements[i].m_sz += m_elements[j].m_sz; + } +#else + m_elements[i].m_id = j; + m_elements[j].m_sz += m_elements[i].m_sz; +#endif //USE_PATH_COMPRESSION + } - int find(int x) - { + int find(int x) + { + //btAssert(x < m_N); + //btAssert(x >= 0); + + while (x != m_elements[x].m_id) + { + //not really a reason not to use path compression, and it flattens the trees/improves find performance dramatically + +#ifdef USE_PATH_COMPRESSION + const btElement* elementPtr = &m_elements[m_elements[x].m_id]; + m_elements[x].m_id = elementPtr->m_id; + x = elementPtr->m_id; +#else // + x = m_elements[x].m_id; +#endif //btAssert(x < m_N); //btAssert(x >= 0); - - while (x != m_elements[x].m_id) - { - //not really a reason not to use path compression, and it flattens the trees/improves find performance dramatically - - #ifdef USE_PATH_COMPRESSION - const btElement* elementPtr = &m_elements[m_elements[x].m_id]; - m_elements[x].m_id = elementPtr->m_id; - x = elementPtr->m_id; - #else// - x = m_elements[x].m_id; - #endif - //btAssert(x < m_N); - //btAssert(x >= 0); - - } - return x; } + return x; + } +}; - - }; - - -#endif //BT_UNION_FIND_H +#endif //BT_UNION_FIND_H diff --git a/src/BulletCollision/CollisionShapes/btBox2dShape.cpp b/src/BulletCollision/CollisionShapes/btBox2dShape.cpp index ecce028c2..a3d8075da 100644 --- a/src/BulletCollision/CollisionShapes/btBox2dShape.cpp +++ b/src/BulletCollision/CollisionShapes/btBox2dShape.cpp @@ -15,28 +15,23 @@ subject to the following restrictions: #include "btBox2dShape.h" +//{ -//{ - - -void btBox2dShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +void btBox2dShape::getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const { - btTransformAabb(getHalfExtentsWithoutMargin(),getMargin(),t,aabbMin,aabbMax); + btTransformAabb(getHalfExtentsWithoutMargin(), getMargin(), t, aabbMin, aabbMax); } - -void btBox2dShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +void btBox2dShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const { //btScalar margin = btScalar(0.); btVector3 halfExtents = getHalfExtentsWithMargin(); - btScalar lx=btScalar(2.)*(halfExtents.x()); - btScalar ly=btScalar(2.)*(halfExtents.y()); - btScalar lz=btScalar(2.)*(halfExtents.z()); - - inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz), - mass/(btScalar(12.0)) * (lx*lx + lz*lz), - mass/(btScalar(12.0)) * (lx*lx + ly*ly)); + btScalar lx = btScalar(2.) * (halfExtents.x()); + btScalar ly = btScalar(2.) * (halfExtents.y()); + btScalar lz = btScalar(2.) * (halfExtents.z()); + inertia.setValue(mass / (btScalar(12.0)) * (ly * ly + lz * lz), + mass / (btScalar(12.0)) * (lx * lx + lz * lz), + mass / (btScalar(12.0)) * (lx * lx + ly * ly)); } - diff --git a/src/BulletCollision/CollisionShapes/btBox2dShape.h b/src/BulletCollision/CollisionShapes/btBox2dShape.h index 22bee4f2c..7e085f9e2 100644 --- a/src/BulletCollision/CollisionShapes/btBox2dShape.h +++ b/src/BulletCollision/CollisionShapes/btBox2dShape.h @@ -23,9 +23,9 @@ subject to the following restrictions: #include "LinearMath/btMinMax.h" ///The btBox2dShape is a box primitive around the origin, its sides axis aligned with length specified by half extents, in local shape coordinates. When used as part of a btCollisionObject or btRigidBody it will be an oriented box in world space. -ATTRIBUTE_ALIGNED16(class) btBox2dShape: public btPolyhedralConvexShape +ATTRIBUTE_ALIGNED16(class) +btBox2dShape : public btPolyhedralConvexShape { - //btVector3 m_boxHalfExtents1; //use m_implicitShapeDimensions instead btVector3 m_centroid; @@ -33,79 +33,75 @@ ATTRIBUTE_ALIGNED16(class) btBox2dShape: public btPolyhedralConvexShape btVector3 m_normals[4]; public: - BT_DECLARE_ALIGNED_ALLOCATOR(); btVector3 getHalfExtentsWithMargin() const { btVector3 halfExtents = getHalfExtentsWithoutMargin(); - btVector3 margin(getMargin(),getMargin(),getMargin()); + btVector3 margin(getMargin(), getMargin(), getMargin()); halfExtents += margin; return halfExtents; } - + const btVector3& getHalfExtentsWithoutMargin() const { - return m_implicitShapeDimensions;//changed in Bullet 2.63: assume the scaling and margin are included + return m_implicitShapeDimensions; //changed in Bullet 2.63: assume the scaling and margin are included } - - virtual btVector3 localGetSupportingVertex(const btVector3& vec) const + virtual btVector3 localGetSupportingVertex(const btVector3& vec) const { btVector3 halfExtents = getHalfExtentsWithoutMargin(); - btVector3 margin(getMargin(),getMargin(),getMargin()); + btVector3 margin(getMargin(), getMargin(), getMargin()); halfExtents += margin; - + return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()), - btFsels(vec.y(), halfExtents.y(), -halfExtents.y()), - btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); + btFsels(vec.y(), halfExtents.y(), -halfExtents.y()), + btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); } - SIMD_FORCE_INLINE btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const + SIMD_FORCE_INLINE btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const { const btVector3& halfExtents = getHalfExtentsWithoutMargin(); - + return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()), - btFsels(vec.y(), halfExtents.y(), -halfExtents.y()), - btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); + btFsels(vec.y(), halfExtents.y(), -halfExtents.y()), + btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); } - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const { const btVector3& halfExtents = getHalfExtentsWithoutMargin(); - - for (int i=0;iboxHalfExtents.getY()) + if (minDimension > boxHalfExtents.getY()) minDimension = boxHalfExtents.getY(); m_shapeType = BOX_2D_SHAPE_PROXYTYPE; - btVector3 margin(getMargin(),getMargin(),getMargin()); + btVector3 margin(getMargin(), getMargin(), getMargin()); m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin; setSafeMargin(minDimension); @@ -114,42 +110,34 @@ public: virtual void setMargin(btScalar collisionMargin) { //correct the m_implicitShapeDimensions for the margin - btVector3 oldMargin(getMargin(),getMargin(),getMargin()); - btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin; - - btConvexInternalShape::setMargin(collisionMargin); - btVector3 newMargin(getMargin(),getMargin(),getMargin()); - m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin; + btVector3 oldMargin(getMargin(), getMargin(), getMargin()); + btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions + oldMargin; + btConvexInternalShape::setMargin(collisionMargin); + btVector3 newMargin(getMargin(), getMargin(), getMargin()); + m_implicitShapeDimensions = implicitShapeDimensionsWithMargin - newMargin; } - virtual void setLocalScaling(const btVector3& scaling) + virtual void setLocalScaling(const btVector3& scaling) { - btVector3 oldMargin(getMargin(),getMargin(),getMargin()); - btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions+oldMargin; + btVector3 oldMargin(getMargin(), getMargin(), getMargin()); + btVector3 implicitShapeDimensionsWithMargin = m_implicitShapeDimensions + oldMargin; btVector3 unScaledImplicitShapeDimensionsWithMargin = implicitShapeDimensionsWithMargin / m_localScaling; btConvexInternalShape::setLocalScaling(scaling); m_implicitShapeDimensions = (unScaledImplicitShapeDimensionsWithMargin * m_localScaling) - oldMargin; - } - virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const; - + virtual void calculateLocalInertia(btScalar mass, btVector3 & inertia) const; - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; - - - - - - int getVertexCount() const + int getVertexCount() const { return 4; } - virtual int getNumVertices()const + virtual int getNumVertices() const { return 4; } @@ -164,82 +152,70 @@ public: return &m_normals[0]; } - - - - - - - virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const + virtual void getPlane(btVector3 & planeNormal, btVector3 & planeSupport, int i) const { //this plane might not be aligned... - btVector4 plane ; - getPlaneEquation(plane,i); - planeNormal = btVector3(plane.getX(),plane.getY(),plane.getZ()); + btVector4 plane; + getPlaneEquation(plane, i); + planeNormal = btVector3(plane.getX(), plane.getY(), plane.getZ()); planeSupport = localGetSupportingVertex(-planeNormal); } - const btVector3& getCentroid() const { return m_centroid; } - + virtual int getNumPlanes() const { return 6; - } - - + } virtual int getNumEdges() const { return 12; } - - virtual void getVertex(int i,btVector3& vtx) const + virtual void getVertex(int i, btVector3& vtx) const { btVector3 halfExtents = getHalfExtentsWithoutMargin(); vtx = btVector3( - halfExtents.x() * (1-(i&1)) - halfExtents.x() * (i&1), - halfExtents.y() * (1-((i&2)>>1)) - halfExtents.y() * ((i&2)>>1), - halfExtents.z() * (1-((i&4)>>2)) - halfExtents.z() * ((i&4)>>2)); + halfExtents.x() * (1 - (i & 1)) - halfExtents.x() * (i & 1), + halfExtents.y() * (1 - ((i & 2) >> 1)) - halfExtents.y() * ((i & 2) >> 1), + halfExtents.z() * (1 - ((i & 4) >> 2)) - halfExtents.z() * ((i & 4) >> 2)); } - - virtual void getPlaneEquation(btVector4& plane,int i) const + virtual void getPlaneEquation(btVector4 & plane, int i) const { btVector3 halfExtents = getHalfExtentsWithoutMargin(); switch (i) { - case 0: - plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.),-halfExtents.x()); - break; - case 1: - plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.),-halfExtents.x()); - break; - case 2: - plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.),-halfExtents.y()); - break; - case 3: - plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.),-halfExtents.y()); - break; - case 4: - plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.),-halfExtents.z()); - break; - case 5: - plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.),-halfExtents.z()); - break; - default: - btAssert(0); + case 0: + plane.setValue(btScalar(1.), btScalar(0.), btScalar(0.), -halfExtents.x()); + break; + case 1: + plane.setValue(btScalar(-1.), btScalar(0.), btScalar(0.), -halfExtents.x()); + break; + case 2: + plane.setValue(btScalar(0.), btScalar(1.), btScalar(0.), -halfExtents.y()); + break; + case 3: + plane.setValue(btScalar(0.), btScalar(-1.), btScalar(0.), -halfExtents.y()); + break; + case 4: + plane.setValue(btScalar(0.), btScalar(0.), btScalar(1.), -halfExtents.z()); + break; + case 5: + plane.setValue(btScalar(0.), btScalar(0.), btScalar(-1.), -halfExtents.z()); + break; + default: + btAssert(0); } } - - virtual void getEdge(int i,btVector3& pa,btVector3& pb) const + virtual void getEdge(int i, btVector3& pa, btVector3& pb) const //virtual void getEdge(int i,Edge& edge) const { int edgeVert0 = 0; @@ -247,126 +223,117 @@ public: switch (i) { - case 0: + case 0: edgeVert0 = 0; edgeVert1 = 1; - break; - case 1: + break; + case 1: edgeVert0 = 0; edgeVert1 = 2; - break; - case 2: - edgeVert0 = 1; - edgeVert1 = 3; + break; + case 2: + edgeVert0 = 1; + edgeVert1 = 3; - break; - case 3: - edgeVert0 = 2; - edgeVert1 = 3; - break; - case 4: - edgeVert0 = 0; - edgeVert1 = 4; - break; - case 5: - edgeVert0 = 1; - edgeVert1 = 5; - - break; - case 6: - edgeVert0 = 2; - edgeVert1 = 6; - break; - case 7: - edgeVert0 = 3; - edgeVert1 = 7; - break; - case 8: - edgeVert0 = 4; - edgeVert1 = 5; - break; - case 9: - edgeVert0 = 4; - edgeVert1 = 6; - break; - case 10: - edgeVert0 = 5; - edgeVert1 = 7; - break; - case 11: - edgeVert0 = 6; - edgeVert1 = 7; - break; - default: - btAssert(0); + break; + case 3: + edgeVert0 = 2; + edgeVert1 = 3; + break; + case 4: + edgeVert0 = 0; + edgeVert1 = 4; + break; + case 5: + edgeVert0 = 1; + edgeVert1 = 5; + break; + case 6: + edgeVert0 = 2; + edgeVert1 = 6; + break; + case 7: + edgeVert0 = 3; + edgeVert1 = 7; + break; + case 8: + edgeVert0 = 4; + edgeVert1 = 5; + break; + case 9: + edgeVert0 = 4; + edgeVert1 = 6; + break; + case 10: + edgeVert0 = 5; + edgeVert1 = 7; + break; + case 11: + edgeVert0 = 6; + edgeVert1 = 7; + break; + default: + btAssert(0); } - getVertex(edgeVert0,pa ); - getVertex(edgeVert1,pb ); + getVertex(edgeVert0, pa); + getVertex(edgeVert1, pb); } - - - - - virtual bool isInside(const btVector3& pt,btScalar tolerance) const + virtual bool isInside(const btVector3& pt, btScalar tolerance) const { btVector3 halfExtents = getHalfExtentsWithoutMargin(); //btScalar minDist = 2*tolerance; - - bool result = (pt.x() <= (halfExtents.x()+tolerance)) && - (pt.x() >= (-halfExtents.x()-tolerance)) && - (pt.y() <= (halfExtents.y()+tolerance)) && - (pt.y() >= (-halfExtents.y()-tolerance)) && - (pt.z() <= (halfExtents.z()+tolerance)) && - (pt.z() >= (-halfExtents.z()-tolerance)); - + + bool result = (pt.x() <= (halfExtents.x() + tolerance)) && + (pt.x() >= (-halfExtents.x() - tolerance)) && + (pt.y() <= (halfExtents.y() + tolerance)) && + (pt.y() >= (-halfExtents.y() - tolerance)) && + (pt.z() <= (halfExtents.z() + tolerance)) && + (pt.z() >= (-halfExtents.z() - tolerance)); + return result; } - //debugging - virtual const char* getName()const + virtual const char* getName() const { return "Box2d"; } - virtual int getNumPreferredPenetrationDirections() const + virtual int getNumPreferredPenetrationDirections() const { return 6; } - - virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const + + virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const { switch (index) { - case 0: - penetrationVector.setValue(btScalar(1.),btScalar(0.),btScalar(0.)); - break; - case 1: - penetrationVector.setValue(btScalar(-1.),btScalar(0.),btScalar(0.)); - break; - case 2: - penetrationVector.setValue(btScalar(0.),btScalar(1.),btScalar(0.)); - break; - case 3: - penetrationVector.setValue(btScalar(0.),btScalar(-1.),btScalar(0.)); - break; - case 4: - penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(1.)); - break; - case 5: - penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(-1.)); - break; - default: - btAssert(0); + case 0: + penetrationVector.setValue(btScalar(1.), btScalar(0.), btScalar(0.)); + break; + case 1: + penetrationVector.setValue(btScalar(-1.), btScalar(0.), btScalar(0.)); + break; + case 2: + penetrationVector.setValue(btScalar(0.), btScalar(1.), btScalar(0.)); + break; + case 3: + penetrationVector.setValue(btScalar(0.), btScalar(-1.), btScalar(0.)); + break; + case 4: + penetrationVector.setValue(btScalar(0.), btScalar(0.), btScalar(1.)); + break; + case 5: + penetrationVector.setValue(btScalar(0.), btScalar(0.), btScalar(-1.)); + break; + default: + btAssert(0); } } - }; -#endif //BT_OBB_BOX_2D_SHAPE_H - - +#endif //BT_OBB_BOX_2D_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btBoxShape.cpp b/src/BulletCollision/CollisionShapes/btBoxShape.cpp index 72eeb3891..cb91d023e 100644 --- a/src/BulletCollision/CollisionShapes/btBoxShape.cpp +++ b/src/BulletCollision/CollisionShapes/btBoxShape.cpp @@ -14,38 +14,32 @@ subject to the following restrictions: */ #include "btBoxShape.h" -btBoxShape::btBoxShape( const btVector3& boxHalfExtents) -: btPolyhedralConvexShape() +btBoxShape::btBoxShape(const btVector3& boxHalfExtents) + : btPolyhedralConvexShape() { m_shapeType = BOX_SHAPE_PROXYTYPE; - btVector3 margin(getMargin(),getMargin(),getMargin()); + btVector3 margin(getMargin(), getMargin(), getMargin()); m_implicitShapeDimensions = (boxHalfExtents * m_localScaling) - margin; setSafeMargin(boxHalfExtents); }; - - - -void btBoxShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +void btBoxShape::getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const { - btTransformAabb(getHalfExtentsWithoutMargin(),getMargin(),t,aabbMin,aabbMax); + btTransformAabb(getHalfExtentsWithoutMargin(), getMargin(), t, aabbMin, aabbMax); } - -void btBoxShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +void btBoxShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const { //btScalar margin = btScalar(0.); btVector3 halfExtents = getHalfExtentsWithMargin(); - btScalar lx=btScalar(2.)*(halfExtents.x()); - btScalar ly=btScalar(2.)*(halfExtents.y()); - btScalar lz=btScalar(2.)*(halfExtents.z()); - - inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz), - mass/(btScalar(12.0)) * (lx*lx + lz*lz), - mass/(btScalar(12.0)) * (lx*lx + ly*ly)); + btScalar lx = btScalar(2.) * (halfExtents.x()); + btScalar ly = btScalar(2.) * (halfExtents.y()); + btScalar lz = btScalar(2.) * (halfExtents.z()); + inertia.setValue(mass / (btScalar(12.0)) * (ly * ly + lz * lz), + mass / (btScalar(12.0)) * (lx * lx + lz * lz), + mass / (btScalar(12.0)) * (lx * lx + ly * ly)); } - diff --git a/src/BulletCollision/CollisionShapes/btBoxShape.h b/src/BulletCollision/CollisionShapes/btBoxShape.h index 715e3f2ab..3c65505d5 100644 --- a/src/BulletCollision/CollisionShapes/btBoxShape.h +++ b/src/BulletCollision/CollisionShapes/btBoxShape.h @@ -23,112 +23,102 @@ subject to the following restrictions: #include "LinearMath/btMinMax.h" ///The btBoxShape is a box primitive around the origin, its sides axis aligned with length specified by half extents, in local shape coordinates. When used as part of a btCollisionObject or btRigidBody it will be an oriented box in world space. -ATTRIBUTE_ALIGNED16(class) btBoxShape: public btPolyhedralConvexShape +ATTRIBUTE_ALIGNED16(class) +btBoxShape : public btPolyhedralConvexShape { - //btVector3 m_boxHalfExtents1; //use m_implicitShapeDimensions instead - public: - -BT_DECLARE_ALIGNED_ALLOCATOR(); + BT_DECLARE_ALIGNED_ALLOCATOR(); btVector3 getHalfExtentsWithMargin() const { btVector3 halfExtents = getHalfExtentsWithoutMargin(); - btVector3 margin(getMargin(),getMargin(),getMargin()); + btVector3 margin(getMargin(), getMargin(), getMargin()); halfExtents += margin; return halfExtents; } - + const btVector3& getHalfExtentsWithoutMargin() const { - return m_implicitShapeDimensions;//scaling is included, margin is not + return m_implicitShapeDimensions; //scaling is included, margin is not } - - virtual btVector3 localGetSupportingVertex(const btVector3& vec) const + virtual btVector3 localGetSupportingVertex(const btVector3& vec) const { btVector3 halfExtents = getHalfExtentsWithoutMargin(); - btVector3 margin(getMargin(),getMargin(),getMargin()); + btVector3 margin(getMargin(), getMargin(), getMargin()); halfExtents += margin; - + return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()), - btFsels(vec.y(), halfExtents.y(), -halfExtents.y()), - btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); + btFsels(vec.y(), halfExtents.y(), -halfExtents.y()), + btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); } - SIMD_FORCE_INLINE btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const + SIMD_FORCE_INLINE btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const { const btVector3& halfExtents = getHalfExtentsWithoutMargin(); - + return btVector3(btFsels(vec.x(), halfExtents.x(), -halfExtents.x()), - btFsels(vec.y(), halfExtents.y(), -halfExtents.y()), - btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); + btFsels(vec.y(), halfExtents.y(), -halfExtents.y()), + btFsels(vec.z(), halfExtents.z(), -halfExtents.z())); } - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const { const btVector3& halfExtents = getHalfExtentsWithoutMargin(); - - for (int i=0;i>1)) - halfExtents.y() * ((i&2)>>1), - halfExtents.z() * (1-((i&4)>>2)) - halfExtents.z() * ((i&4)>>2)); + halfExtents.x() * (1 - (i & 1)) - halfExtents.x() * (i & 1), + halfExtents.y() * (1 - ((i & 2) >> 1)) - halfExtents.y() * ((i & 2) >> 1), + halfExtents.z() * (1 - ((i & 4) >> 2)) - halfExtents.z() * ((i & 4) >> 2)); } - - virtual void getPlaneEquation(btVector4& plane,int i) const + virtual void getPlaneEquation(btVector4 & plane, int i) const { btVector3 halfExtents = getHalfExtentsWithoutMargin(); switch (i) { - case 0: - plane.setValue(btScalar(1.),btScalar(0.),btScalar(0.),-halfExtents.x()); - break; - case 1: - plane.setValue(btScalar(-1.),btScalar(0.),btScalar(0.),-halfExtents.x()); - break; - case 2: - plane.setValue(btScalar(0.),btScalar(1.),btScalar(0.),-halfExtents.y()); - break; - case 3: - plane.setValue(btScalar(0.),btScalar(-1.),btScalar(0.),-halfExtents.y()); - break; - case 4: - plane.setValue(btScalar(0.),btScalar(0.),btScalar(1.),-halfExtents.z()); - break; - case 5: - plane.setValue(btScalar(0.),btScalar(0.),btScalar(-1.),-halfExtents.z()); - break; - default: - btAssert(0); + case 0: + plane.setValue(btScalar(1.), btScalar(0.), btScalar(0.), -halfExtents.x()); + break; + case 1: + plane.setValue(btScalar(-1.), btScalar(0.), btScalar(0.), -halfExtents.x()); + break; + case 2: + plane.setValue(btScalar(0.), btScalar(1.), btScalar(0.), -halfExtents.y()); + break; + case 3: + plane.setValue(btScalar(0.), btScalar(-1.), btScalar(0.), -halfExtents.y()); + break; + case 4: + plane.setValue(btScalar(0.), btScalar(0.), btScalar(1.), -halfExtents.z()); + break; + case 5: + plane.setValue(btScalar(0.), btScalar(0.), btScalar(-1.), -halfExtents.z()); + break; + default: + btAssert(0); } } - - virtual void getEdge(int i,btVector3& pa,btVector3& pb) const + virtual void getEdge(int i, btVector3& pa, btVector3& pb) const //virtual void getEdge(int i,Edge& edge) const { int edgeVert0 = 0; @@ -188,127 +175,117 @@ BT_DECLARE_ALIGNED_ALLOCATOR(); switch (i) { - case 0: + case 0: edgeVert0 = 0; edgeVert1 = 1; - break; - case 1: + break; + case 1: edgeVert0 = 0; edgeVert1 = 2; - break; - case 2: - edgeVert0 = 1; - edgeVert1 = 3; + break; + case 2: + edgeVert0 = 1; + edgeVert1 = 3; - break; - case 3: - edgeVert0 = 2; - edgeVert1 = 3; - break; - case 4: - edgeVert0 = 0; - edgeVert1 = 4; - break; - case 5: - edgeVert0 = 1; - edgeVert1 = 5; - - break; - case 6: - edgeVert0 = 2; - edgeVert1 = 6; - break; - case 7: - edgeVert0 = 3; - edgeVert1 = 7; - break; - case 8: - edgeVert0 = 4; - edgeVert1 = 5; - break; - case 9: - edgeVert0 = 4; - edgeVert1 = 6; - break; - case 10: - edgeVert0 = 5; - edgeVert1 = 7; - break; - case 11: - edgeVert0 = 6; - edgeVert1 = 7; - break; - default: - btAssert(0); + break; + case 3: + edgeVert0 = 2; + edgeVert1 = 3; + break; + case 4: + edgeVert0 = 0; + edgeVert1 = 4; + break; + case 5: + edgeVert0 = 1; + edgeVert1 = 5; + break; + case 6: + edgeVert0 = 2; + edgeVert1 = 6; + break; + case 7: + edgeVert0 = 3; + edgeVert1 = 7; + break; + case 8: + edgeVert0 = 4; + edgeVert1 = 5; + break; + case 9: + edgeVert0 = 4; + edgeVert1 = 6; + break; + case 10: + edgeVert0 = 5; + edgeVert1 = 7; + break; + case 11: + edgeVert0 = 6; + edgeVert1 = 7; + break; + default: + btAssert(0); } - getVertex(edgeVert0,pa ); - getVertex(edgeVert1,pb ); + getVertex(edgeVert0, pa); + getVertex(edgeVert1, pb); } - - - - - virtual bool isInside(const btVector3& pt,btScalar tolerance) const + virtual bool isInside(const btVector3& pt, btScalar tolerance) const { btVector3 halfExtents = getHalfExtentsWithoutMargin(); //btScalar minDist = 2*tolerance; - - bool result = (pt.x() <= (halfExtents.x()+tolerance)) && - (pt.x() >= (-halfExtents.x()-tolerance)) && - (pt.y() <= (halfExtents.y()+tolerance)) && - (pt.y() >= (-halfExtents.y()-tolerance)) && - (pt.z() <= (halfExtents.z()+tolerance)) && - (pt.z() >= (-halfExtents.z()-tolerance)); - + + bool result = (pt.x() <= (halfExtents.x() + tolerance)) && + (pt.x() >= (-halfExtents.x() - tolerance)) && + (pt.y() <= (halfExtents.y() + tolerance)) && + (pt.y() >= (-halfExtents.y() - tolerance)) && + (pt.z() <= (halfExtents.z() + tolerance)) && + (pt.z() >= (-halfExtents.z() - tolerance)); + return result; } - //debugging - virtual const char* getName()const + virtual const char* getName() const { return "Box"; } - virtual int getNumPreferredPenetrationDirections() const + virtual int getNumPreferredPenetrationDirections() const { return 6; } - - virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const + + virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const { switch (index) { - case 0: - penetrationVector.setValue(btScalar(1.),btScalar(0.),btScalar(0.)); - break; - case 1: - penetrationVector.setValue(btScalar(-1.),btScalar(0.),btScalar(0.)); - break; - case 2: - penetrationVector.setValue(btScalar(0.),btScalar(1.),btScalar(0.)); - break; - case 3: - penetrationVector.setValue(btScalar(0.),btScalar(-1.),btScalar(0.)); - break; - case 4: - penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(1.)); - break; - case 5: - penetrationVector.setValue(btScalar(0.),btScalar(0.),btScalar(-1.)); - break; - default: - btAssert(0); + case 0: + penetrationVector.setValue(btScalar(1.), btScalar(0.), btScalar(0.)); + break; + case 1: + penetrationVector.setValue(btScalar(-1.), btScalar(0.), btScalar(0.)); + break; + case 2: + penetrationVector.setValue(btScalar(0.), btScalar(1.), btScalar(0.)); + break; + case 3: + penetrationVector.setValue(btScalar(0.), btScalar(-1.), btScalar(0.)); + break; + case 4: + penetrationVector.setValue(btScalar(0.), btScalar(0.), btScalar(1.)); + break; + case 5: + penetrationVector.setValue(btScalar(0.), btScalar(0.), btScalar(-1.)); + break; + default: + btAssert(0); } } - }; - -#endif //BT_OBB_BOX_MINKOWSKI_H - - +#endif //BT_OBB_BOX_MINKOWSKI_H diff --git a/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp b/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp index 61f465cb7..d663b3d6d 100644 --- a/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp +++ b/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.cpp @@ -22,11 +22,11 @@ subject to the following restrictions: ///Bvh Concave triangle mesh is a static-triangle mesh shape with Bounding Volume Hierarchy optimization. ///Uses an interface to access the triangles to allow for sharing graphics/physics triangles. btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh) -:btTriangleMeshShape(meshInterface), -m_bvh(0), -m_triangleInfoMap(0), -m_useQuantizedAabbCompression(useQuantizedAabbCompression), -m_ownsBvh(false) + : btTriangleMeshShape(meshInterface), + m_bvh(0), + m_triangleInfoMap(0), + m_useQuantizedAabbCompression(useQuantizedAabbCompression), + m_ownsBvh(false) { m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE; //construct bvh from meshInterface @@ -37,16 +37,15 @@ m_ownsBvh(false) buildOptimizedBvh(); } -#endif //DISABLE_BVH - +#endif //DISABLE_BVH } -btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax,bool buildBvh) -:btTriangleMeshShape(meshInterface), -m_bvh(0), -m_triangleInfoMap(0), -m_useQuantizedAabbCompression(useQuantizedAabbCompression), -m_ownsBvh(false) +btBvhTriangleMeshShape::btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax, bool buildBvh) + : btTriangleMeshShape(meshInterface), + m_bvh(0), + m_triangleInfoMap(0), + m_useQuantizedAabbCompression(useQuantizedAabbCompression), + m_ownsBvh(false) { m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE; //construct bvh from meshInterface @@ -54,30 +53,28 @@ m_ownsBvh(false) if (buildBvh) { - void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16); + void* mem = btAlignedAlloc(sizeof(btOptimizedBvh), 16); m_bvh = new (mem) btOptimizedBvh(); - - m_bvh->build(meshInterface,m_useQuantizedAabbCompression,bvhAabbMin,bvhAabbMax); + + m_bvh->build(meshInterface, m_useQuantizedAabbCompression, bvhAabbMin, bvhAabbMax); m_ownsBvh = true; } -#endif //DISABLE_BVH - +#endif //DISABLE_BVH } -void btBvhTriangleMeshShape::partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax) +void btBvhTriangleMeshShape::partialRefitTree(const btVector3& aabbMin, const btVector3& aabbMax) { - m_bvh->refitPartial( m_meshInterface,aabbMin,aabbMax ); - + m_bvh->refitPartial(m_meshInterface, aabbMin, aabbMax); + m_localAabbMin.setMin(aabbMin); m_localAabbMax.setMax(aabbMax); } - -void btBvhTriangleMeshShape::refitTree(const btVector3& aabbMin,const btVector3& aabbMax) +void btBvhTriangleMeshShape::refitTree(const btVector3& aabbMin, const btVector3& aabbMax) { - m_bvh->refit( m_meshInterface, aabbMin,aabbMax ); - + m_bvh->refit(m_meshInterface, aabbMin, aabbMax); + recalcLocalAabb(); } @@ -90,27 +87,27 @@ btBvhTriangleMeshShape::~btBvhTriangleMeshShape() } } -void btBvhTriangleMeshShape::performRaycast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget) +void btBvhTriangleMeshShape::performRaycast(btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget) { - struct MyNodeOverlapCallback : public btNodeOverlapCallback + struct MyNodeOverlapCallback : public btNodeOverlapCallback { - btStridingMeshInterface* m_meshInterface; + btStridingMeshInterface* m_meshInterface; btTriangleCallback* m_callback; - MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface) - :m_meshInterface(meshInterface), - m_callback(callback) + MyNodeOverlapCallback(btTriangleCallback* callback, btStridingMeshInterface* meshInterface) + : m_meshInterface(meshInterface), + m_callback(callback) { } - + virtual void processNode(int nodeSubPart, int nodeTriangleIndex) { btVector3 m_triangle[3]; - const unsigned char *vertexbase; + const unsigned char* vertexbase; int numverts; PHY_ScalarType type; int stride; - const unsigned char *indexbase; + const unsigned char* indexbase; int indexstride; int numfaces; PHY_ScalarType indicestype; @@ -126,60 +123,60 @@ void btBvhTriangleMeshShape::performRaycast (btTriangleCallback* callback, const indicestype, nodeSubPart); - unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride); - btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT); - + unsigned int* gfxbase = (unsigned int*)(indexbase + nodeTriangleIndex * indexstride); + btAssert(indicestype == PHY_INTEGER || indicestype == PHY_SHORT); + const btVector3& meshScaling = m_meshInterface->getScaling(); - for (int j=2;j>=0;j--) + for (int j = 2; j >= 0; j--) { - int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; - + int graphicsindex = indicestype == PHY_SHORT ? ((unsigned short*)gfxbase)[j] : gfxbase[j]; + if (type == PHY_FLOAT) { - float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); - - m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ()); + float* graphicsbase = (float*)(vertexbase + graphicsindex * stride); + + m_triangle[j] = btVector3(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ()); } else { - double* graphicsbase = (double*)(vertexbase+graphicsindex*stride); - - m_triangle[j] = btVector3(btScalar(graphicsbase[0])*meshScaling.getX(),btScalar(graphicsbase[1])*meshScaling.getY(),btScalar(graphicsbase[2])*meshScaling.getZ()); + double* graphicsbase = (double*)(vertexbase + graphicsindex * stride); + + m_triangle[j] = btVector3(btScalar(graphicsbase[0]) * meshScaling.getX(), btScalar(graphicsbase[1]) * meshScaling.getY(), btScalar(graphicsbase[2]) * meshScaling.getZ()); } } /* Perform ray vs. triangle collision here */ - m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex); + m_callback->processTriangle(m_triangle, nodeSubPart, nodeTriangleIndex); m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart); } }; - MyNodeOverlapCallback myNodeCallback(callback,m_meshInterface); + MyNodeOverlapCallback myNodeCallback(callback, m_meshInterface); - m_bvh->reportRayOverlappingNodex(&myNodeCallback,raySource,rayTarget); + m_bvh->reportRayOverlappingNodex(&myNodeCallback, raySource, rayTarget); } -void btBvhTriangleMeshShape::performConvexcast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax) +void btBvhTriangleMeshShape::performConvexcast(btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget, const btVector3& aabbMin, const btVector3& aabbMax) { - struct MyNodeOverlapCallback : public btNodeOverlapCallback + struct MyNodeOverlapCallback : public btNodeOverlapCallback { - btStridingMeshInterface* m_meshInterface; + btStridingMeshInterface* m_meshInterface; btTriangleCallback* m_callback; - MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface) - :m_meshInterface(meshInterface), - m_callback(callback) + MyNodeOverlapCallback(btTriangleCallback* callback, btStridingMeshInterface* meshInterface) + : m_meshInterface(meshInterface), + m_callback(callback) { } - + virtual void processNode(int nodeSubPart, int nodeTriangleIndex) { btVector3 m_triangle[3]; - const unsigned char *vertexbase; + const unsigned char* vertexbase; int numverts; PHY_ScalarType type; int stride; - const unsigned char *indexbase; + const unsigned char* indexbase; int indexstride; int numfaces; PHY_ScalarType indicestype; @@ -195,77 +192,74 @@ void btBvhTriangleMeshShape::performConvexcast (btTriangleCallback* callback, co indicestype, nodeSubPart); - unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride); - btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT); - + unsigned int* gfxbase = (unsigned int*)(indexbase + nodeTriangleIndex * indexstride); + btAssert(indicestype == PHY_INTEGER || indicestype == PHY_SHORT); + const btVector3& meshScaling = m_meshInterface->getScaling(); - for (int j=2;j>=0;j--) + for (int j = 2; j >= 0; j--) { - int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; + int graphicsindex = indicestype == PHY_SHORT ? ((unsigned short*)gfxbase)[j] : gfxbase[j]; if (type == PHY_FLOAT) { - float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); + float* graphicsbase = (float*)(vertexbase + graphicsindex * stride); - m_triangle[j] = btVector3(graphicsbase[0]*meshScaling.getX(),graphicsbase[1]*meshScaling.getY(),graphicsbase[2]*meshScaling.getZ()); + m_triangle[j] = btVector3(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ()); } else { - double* graphicsbase = (double*)(vertexbase+graphicsindex*stride); - - m_triangle[j] = btVector3(btScalar(graphicsbase[0])*meshScaling.getX(),btScalar(graphicsbase[1])*meshScaling.getY(),btScalar(graphicsbase[2])*meshScaling.getZ()); + double* graphicsbase = (double*)(vertexbase + graphicsindex * stride); + + m_triangle[j] = btVector3(btScalar(graphicsbase[0]) * meshScaling.getX(), btScalar(graphicsbase[1]) * meshScaling.getY(), btScalar(graphicsbase[2]) * meshScaling.getZ()); } } /* Perform ray vs. triangle collision here */ - m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex); + m_callback->processTriangle(m_triangle, nodeSubPart, nodeTriangleIndex); m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart); } }; - MyNodeOverlapCallback myNodeCallback(callback,m_meshInterface); + MyNodeOverlapCallback myNodeCallback(callback, m_meshInterface); - m_bvh->reportBoxCastOverlappingNodex (&myNodeCallback, raySource, rayTarget, aabbMin, aabbMax); + m_bvh->reportBoxCastOverlappingNodex(&myNodeCallback, raySource, rayTarget, aabbMin, aabbMax); } //perform bvh tree traversal and report overlapping triangles to 'callback' -void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const +void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const { - #ifdef DISABLE_BVH //brute force traverse all triangles - btTriangleMeshShape::processAllTriangles(callback,aabbMin,aabbMax); + btTriangleMeshShape::processAllTriangles(callback, aabbMin, aabbMax); #else //first get all the nodes - - struct MyNodeOverlapCallback : public btNodeOverlapCallback + struct MyNodeOverlapCallback : public btNodeOverlapCallback { - btStridingMeshInterface* m_meshInterface; - btTriangleCallback* m_callback; - btVector3 m_triangle[3]; + btStridingMeshInterface* m_meshInterface; + btTriangleCallback* m_callback; + btVector3 m_triangle[3]; int m_numOverlap; - MyNodeOverlapCallback(btTriangleCallback* callback,btStridingMeshInterface* meshInterface) - :m_meshInterface(meshInterface), - m_callback(callback), - m_numOverlap(0) + MyNodeOverlapCallback(btTriangleCallback* callback, btStridingMeshInterface* meshInterface) + : m_meshInterface(meshInterface), + m_callback(callback), + m_numOverlap(0) { } - + virtual void processNode(int nodeSubPart, int nodeTriangleIndex) { m_numOverlap++; - const unsigned char *vertexbase; + const unsigned char* vertexbase; int numverts; PHY_ScalarType type; int stride; - const unsigned char *indexbase; + const unsigned char* indexbase; int indexstride; int numfaces; PHY_ScalarType indicestype; - m_meshInterface->getLockedReadOnlyVertexIndexBase( &vertexbase, @@ -278,67 +272,62 @@ void btBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,co indicestype, nodeSubPart); - unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride); - btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT||indicestype==PHY_UCHAR); - - const btVector3& meshScaling = m_meshInterface->getScaling(); - for (int j=2;j>=0;j--) - { - - int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:indicestype==PHY_INTEGER?gfxbase[j]:((unsigned char*)gfxbase)[j]; + unsigned int* gfxbase = (unsigned int*)(indexbase + nodeTriangleIndex * indexstride); + btAssert(indicestype == PHY_INTEGER || indicestype == PHY_SHORT || indicestype == PHY_UCHAR); + const btVector3& meshScaling = m_meshInterface->getScaling(); + for (int j = 2; j >= 0; j--) + { + int graphicsindex = indicestype == PHY_SHORT ? ((unsigned short*)gfxbase)[j] : indicestype == PHY_INTEGER ? gfxbase[j] : ((unsigned char*)gfxbase)[j]; #ifdef DEBUG_TRIANGLE_MESH - printf("%d ,",graphicsindex); -#endif //DEBUG_TRIANGLE_MESH + printf("%d ,", graphicsindex); +#endif //DEBUG_TRIANGLE_MESH if (type == PHY_FLOAT) { - float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); - + float* graphicsbase = (float*)(vertexbase + graphicsindex * stride); + m_triangle[j] = btVector3( - graphicsbase[0]*meshScaling.getX(), - graphicsbase[1]*meshScaling.getY(), - graphicsbase[2]*meshScaling.getZ()); + graphicsbase[0] * meshScaling.getX(), + graphicsbase[1] * meshScaling.getY(), + graphicsbase[2] * meshScaling.getZ()); } else { - double* graphicsbase = (double*)(vertexbase+graphicsindex*stride); + double* graphicsbase = (double*)(vertexbase + graphicsindex * stride); m_triangle[j] = btVector3( - btScalar(graphicsbase[0])*meshScaling.getX(), - btScalar(graphicsbase[1])*meshScaling.getY(), - btScalar(graphicsbase[2])*meshScaling.getZ()); + btScalar(graphicsbase[0]) * meshScaling.getX(), + btScalar(graphicsbase[1]) * meshScaling.getY(), + btScalar(graphicsbase[2]) * meshScaling.getZ()); } #ifdef DEBUG_TRIANGLE_MESH - printf("triangle vertices:%f,%f,%f\n",triangle[j].x(),triangle[j].y(),triangle[j].z()); -#endif //DEBUG_TRIANGLE_MESH + printf("triangle vertices:%f,%f,%f\n", triangle[j].x(), triangle[j].y(), triangle[j].z()); +#endif //DEBUG_TRIANGLE_MESH } - m_callback->processTriangle(m_triangle,nodeSubPart,nodeTriangleIndex); + m_callback->processTriangle(m_triangle, nodeSubPart, nodeTriangleIndex); m_meshInterface->unLockReadOnlyVertexBase(nodeSubPart); } - }; - MyNodeOverlapCallback myNodeCallback(callback,m_meshInterface); - - m_bvh->reportAabbOverlappingNodex(&myNodeCallback,aabbMin,aabbMax); - -#endif//DISABLE_BVH + MyNodeOverlapCallback myNodeCallback(callback, m_meshInterface); + m_bvh->reportAabbOverlappingNodex(&myNodeCallback, aabbMin, aabbMax); +#endif //DISABLE_BVH } -void btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling) +void btBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling) { - if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON) - { - btTriangleMeshShape::setLocalScaling(scaling); - buildOptimizedBvh(); - } + if ((getLocalScaling() - scaling).length2() > SIMD_EPSILON) + { + btTriangleMeshShape::setLocalScaling(scaling); + buildOptimizedBvh(); + } } -void btBvhTriangleMeshShape::buildOptimizedBvh() +void btBvhTriangleMeshShape::buildOptimizedBvh() { if (m_ownsBvh) { @@ -346,43 +335,39 @@ void btBvhTriangleMeshShape::buildOptimizedBvh() btAlignedFree(m_bvh); } ///m_localAabbMin/m_localAabbMax is already re-calculated in btTriangleMeshShape. We could just scale aabb, but this needs some more work - void* mem = btAlignedAlloc(sizeof(btOptimizedBvh),16); - m_bvh = new(mem) btOptimizedBvh(); + void* mem = btAlignedAlloc(sizeof(btOptimizedBvh), 16); + m_bvh = new (mem) btOptimizedBvh(); //rebuild the bvh... - m_bvh->build(m_meshInterface,m_useQuantizedAabbCompression,m_localAabbMin,m_localAabbMax); + m_bvh->build(m_meshInterface, m_useQuantizedAabbCompression, m_localAabbMin, m_localAabbMax); m_ownsBvh = true; } -void btBvhTriangleMeshShape::setOptimizedBvh(btOptimizedBvh* bvh, const btVector3& scaling) +void btBvhTriangleMeshShape::setOptimizedBvh(btOptimizedBvh* bvh, const btVector3& scaling) { - btAssert(!m_bvh); - btAssert(!m_ownsBvh); + btAssert(!m_bvh); + btAssert(!m_ownsBvh); - m_bvh = bvh; - m_ownsBvh = false; - // update the scaling without rebuilding the bvh - if ((getLocalScaling() -scaling).length2() > SIMD_EPSILON) - { - btTriangleMeshShape::setLocalScaling(scaling); - } + m_bvh = bvh; + m_ownsBvh = false; + // update the scaling without rebuilding the bvh + if ((getLocalScaling() - scaling).length2() > SIMD_EPSILON) + { + btTriangleMeshShape::setLocalScaling(scaling); + } } - - ///fills the dataBuffer and returns the struct name (and 0 on failure) -const char* btBvhTriangleMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const +const char* btBvhTriangleMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const { - btTriangleMeshShapeData* trimeshData = (btTriangleMeshShapeData*) dataBuffer; + btTriangleMeshShapeData* trimeshData = (btTriangleMeshShapeData*)dataBuffer; - btCollisionShape::serialize(&trimeshData->m_collisionShapeData,serializer); + btCollisionShape::serialize(&trimeshData->m_collisionShapeData, serializer); m_meshInterface->serialize(&trimeshData->m_meshInterface, serializer); trimeshData->m_collisionMargin = float(m_collisionMargin); - - - if (m_bvh && !(serializer->getSerializationFlags()&BT_SERIALIZE_NO_BVH)) + if (m_bvh && !(serializer->getSerializationFlags() & BT_SERIALIZE_NO_BVH)) { void* chunk = serializer->findPointer(m_bvh); if (chunk) @@ -391,48 +376,49 @@ const char* btBvhTriangleMeshShape::serialize(void* dataBuffer, btSerializer* se trimeshData->m_quantizedDoubleBvh = (btQuantizedBvhData*)chunk; trimeshData->m_quantizedFloatBvh = 0; #else - trimeshData->m_quantizedFloatBvh = (btQuantizedBvhData*)chunk; - trimeshData->m_quantizedDoubleBvh= 0; -#endif //BT_USE_DOUBLE_PRECISION - } else + trimeshData->m_quantizedFloatBvh = (btQuantizedBvhData*)chunk; + trimeshData->m_quantizedDoubleBvh = 0; +#endif //BT_USE_DOUBLE_PRECISION + } + else { - #ifdef BT_USE_DOUBLE_PRECISION trimeshData->m_quantizedDoubleBvh = (btQuantizedBvhData*)serializer->getUniquePointer(m_bvh); trimeshData->m_quantizedFloatBvh = 0; #else - trimeshData->m_quantizedFloatBvh = (btQuantizedBvhData*)serializer->getUniquePointer(m_bvh); - trimeshData->m_quantizedDoubleBvh= 0; -#endif //BT_USE_DOUBLE_PRECISION - + trimeshData->m_quantizedFloatBvh = (btQuantizedBvhData*)serializer->getUniquePointer(m_bvh); + trimeshData->m_quantizedDoubleBvh = 0; +#endif //BT_USE_DOUBLE_PRECISION + int sz = m_bvh->calculateSerializeBufferSizeNew(); - btChunk* chunk = serializer->allocate(sz,1); + btChunk* chunk = serializer->allocate(sz, 1); const char* structType = m_bvh->serialize(chunk->m_oldPtr, serializer); - serializer->finalizeChunk(chunk,structType,BT_QUANTIZED_BVH_CODE,m_bvh); + serializer->finalizeChunk(chunk, structType, BT_QUANTIZED_BVH_CODE, m_bvh); } - } else + } + else { trimeshData->m_quantizedFloatBvh = 0; trimeshData->m_quantizedDoubleBvh = 0; } - - - if (m_triangleInfoMap && !(serializer->getSerializationFlags()&BT_SERIALIZE_NO_TRIANGLEINFOMAP)) + if (m_triangleInfoMap && !(serializer->getSerializationFlags() & BT_SERIALIZE_NO_TRIANGLEINFOMAP)) { void* chunk = serializer->findPointer(m_triangleInfoMap); if (chunk) { trimeshData->m_triangleInfoMap = (btTriangleInfoMapData*)chunk; - } else + } + else { trimeshData->m_triangleInfoMap = (btTriangleInfoMapData*)serializer->getUniquePointer(m_triangleInfoMap); int sz = m_triangleInfoMap->calculateSerializeBufferSize(); - btChunk* chunk = serializer->allocate(sz,1); + btChunk* chunk = serializer->allocate(sz, 1); const char* structType = m_triangleInfoMap->serialize(chunk->m_oldPtr, serializer); - serializer->finalizeChunk(chunk,structType,BT_TRIANLGE_INFO_MAP,m_triangleInfoMap); + serializer->finalizeChunk(chunk, structType, BT_TRIANLGE_INFO_MAP, m_triangleInfoMap); } - } else + } + else { trimeshData->m_triangleInfoMap = 0; } @@ -443,28 +429,24 @@ const char* btBvhTriangleMeshShape::serialize(void* dataBuffer, btSerializer* se return "btTriangleMeshShapeData"; } -void btBvhTriangleMeshShape::serializeSingleBvh(btSerializer* serializer) const +void btBvhTriangleMeshShape::serializeSingleBvh(btSerializer* serializer) const { if (m_bvh) { - int len = m_bvh->calculateSerializeBufferSizeNew(); //make sure not to use calculateSerializeBufferSize because it is used for in-place - btChunk* chunk = serializer->allocate(len,1); + int len = m_bvh->calculateSerializeBufferSizeNew(); //make sure not to use calculateSerializeBufferSize because it is used for in-place + btChunk* chunk = serializer->allocate(len, 1); const char* structType = m_bvh->serialize(chunk->m_oldPtr, serializer); - serializer->finalizeChunk(chunk,structType,BT_QUANTIZED_BVH_CODE,(void*)m_bvh); + serializer->finalizeChunk(chunk, structType, BT_QUANTIZED_BVH_CODE, (void*)m_bvh); } } -void btBvhTriangleMeshShape::serializeSingleTriangleInfoMap(btSerializer* serializer) const +void btBvhTriangleMeshShape::serializeSingleTriangleInfoMap(btSerializer* serializer) const { if (m_triangleInfoMap) { int len = m_triangleInfoMap->calculateSerializeBufferSize(); - btChunk* chunk = serializer->allocate(len,1); + btChunk* chunk = serializer->allocate(len, 1); const char* structType = m_triangleInfoMap->serialize(chunk->m_oldPtr, serializer); - serializer->finalizeChunk(chunk,structType,BT_TRIANLGE_INFO_MAP,(void*)m_triangleInfoMap); + serializer->finalizeChunk(chunk, structType, BT_TRIANLGE_INFO_MAP, (void*)m_triangleInfoMap); } } - - - - diff --git a/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h b/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h index 1fa4995d1..8b2f2ee85 100644 --- a/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h +++ b/src/BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h @@ -23,103 +23,99 @@ subject to the following restrictions: ///The btBvhTriangleMeshShape is a static-triangle mesh shape, it can only be used for fixed/non-moving objects. ///If you required moving concave triangle meshes, it is recommended to perform convex decomposition -///using HACD, see Bullet/Demos/ConvexDecompositionDemo. +///using HACD, see Bullet/Demos/ConvexDecompositionDemo. ///Alternatively, you can use btGimpactMeshShape for moving concave triangle meshes. -///btBvhTriangleMeshShape has several optimizations, such as bounding volume hierarchy and -///cache friendly traversal for PlayStation 3 Cell SPU. +///btBvhTriangleMeshShape has several optimizations, such as bounding volume hierarchy and +///cache friendly traversal for PlayStation 3 Cell SPU. ///It is recommended to enable useQuantizedAabbCompression for better memory usage. ///It takes a triangle mesh as input, for example a btTriangleMesh or btTriangleIndexVertexArray. The btBvhTriangleMeshShape class allows for triangle mesh deformations by a refit or partialRefit method. ///Instead of building the bounding volume hierarchy acceleration structure, it is also possible to serialize (save) and deserialize (load) the structure from disk. ///See Demos\ConcaveDemo\ConcavePhysicsDemo.cpp for an example. -ATTRIBUTE_ALIGNED16(class) btBvhTriangleMeshShape : public btTriangleMeshShape +ATTRIBUTE_ALIGNED16(class) +btBvhTriangleMeshShape : public btTriangleMeshShape { - - btOptimizedBvh* m_bvh; - btTriangleInfoMap* m_triangleInfoMap; + btOptimizedBvh* m_bvh; + btTriangleInfoMap* m_triangleInfoMap; bool m_useQuantizedAabbCompression; bool m_ownsBvh; #ifdef __clang__ - bool m_pad[11] __attribute__((unused));////need padding due to alignment + bool m_pad[11] __attribute__((unused)); ////need padding due to alignment #else - bool m_pad[11];////need padding due to alignment + bool m_pad[11]; ////need padding due to alignment #endif public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - - btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true); + btBvhTriangleMeshShape(btStridingMeshInterface * meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true); ///optionally pass in a larger bvh aabb, used for quantization. This allows for deformations within this aabb - btBvhTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax, bool buildBvh = true); - + btBvhTriangleMeshShape(btStridingMeshInterface * meshInterface, bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax, bool buildBvh = true); + virtual ~btBvhTriangleMeshShape(); - bool getOwnsBvh () const + bool getOwnsBvh() const { return m_ownsBvh; } + void performRaycast(btTriangleCallback * callback, const btVector3& raySource, const btVector3& rayTarget); + void performConvexcast(btTriangleCallback * callback, const btVector3& boxSource, const btVector3& boxTarget, const btVector3& boxMin, const btVector3& boxMax); - - void performRaycast (btTriangleCallback* callback, const btVector3& raySource, const btVector3& rayTarget); - void performConvexcast (btTriangleCallback* callback, const btVector3& boxSource, const btVector3& boxTarget, const btVector3& boxMin, const btVector3& boxMax); + virtual void processAllTriangles(btTriangleCallback * callback, const btVector3& aabbMin, const btVector3& aabbMax) const; - virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; - - void refitTree(const btVector3& aabbMin,const btVector3& aabbMax); + void refitTree(const btVector3& aabbMin, const btVector3& aabbMax); ///for a fast incremental refit of parts of the tree. Note: the entire AABB of the tree will become more conservative, it never shrinks - void partialRefitTree(const btVector3& aabbMin,const btVector3& aabbMax); + void partialRefitTree(const btVector3& aabbMin, const btVector3& aabbMax); //debugging - virtual const char* getName()const {return "BVHTRIANGLEMESH";} + virtual const char* getName() const { return "BVHTRIANGLEMESH"; } + virtual void setLocalScaling(const btVector3& scaling); - virtual void setLocalScaling(const btVector3& scaling); - - btOptimizedBvh* getOptimizedBvh() + btOptimizedBvh* getOptimizedBvh() { return m_bvh; } - void setOptimizedBvh(btOptimizedBvh* bvh, const btVector3& localScaling=btVector3(1,1,1)); + void setOptimizedBvh(btOptimizedBvh * bvh, const btVector3& localScaling = btVector3(1, 1, 1)); - void buildOptimizedBvh(); + void buildOptimizedBvh(); - bool usesQuantizedAabbCompression() const + bool usesQuantizedAabbCompression() const { - return m_useQuantizedAabbCompression; + return m_useQuantizedAabbCompression; } - void setTriangleInfoMap(btTriangleInfoMap* triangleInfoMap) + void setTriangleInfoMap(btTriangleInfoMap * triangleInfoMap) { m_triangleInfoMap = triangleInfoMap; } - const btTriangleInfoMap* getTriangleInfoMap() const - { - return m_triangleInfoMap; - } - - btTriangleInfoMap* getTriangleInfoMap() + const btTriangleInfoMap* getTriangleInfoMap() const { return m_triangleInfoMap; } - virtual int calculateSerializeBufferSize() const; + btTriangleInfoMap* getTriangleInfoMap() + { + return m_triangleInfoMap; + } + + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; - virtual void serializeSingleBvh(btSerializer* serializer) const; - - virtual void serializeSingleTriangleInfoMap(btSerializer* serializer) const; + virtual void serializeSingleBvh(btSerializer * serializer) const; + virtual void serializeSingleTriangleInfoMap(btSerializer * serializer) const; }; +// clang-format off + ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 struct btTriangleMeshShapeData { @@ -138,12 +134,11 @@ struct btTriangleMeshShapeData }; +// clang-format on -SIMD_FORCE_INLINE int btBvhTriangleMeshShape::calculateSerializeBufferSize() const +SIMD_FORCE_INLINE int btBvhTriangleMeshShape::calculateSerializeBufferSize() const { return sizeof(btTriangleMeshShapeData); } - - -#endif //BT_BVH_TRIANGLE_MESH_SHAPE_H +#endif //BT_BVH_TRIANGLE_MESH_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp b/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp index 0345501ce..7c3377428 100644 --- a/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp +++ b/src/BulletCollision/CollisionShapes/btCapsuleShape.cpp @@ -13,24 +13,21 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btCapsuleShape.h" #include "LinearMath/btQuaternion.h" -btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) : btConvexInternalShape () +btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) : btConvexInternalShape() { m_collisionMargin = radius; m_shapeType = CAPSULE_SHAPE_PROXYTYPE; m_upAxis = 1; - m_implicitShapeDimensions.setValue(radius,0.5f*height,radius); + m_implicitShapeDimensions.setValue(radius, 0.5f * height, radius); } - - btVector3 btCapsuleShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const +btVector3 btCapsuleShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0) const { - - btVector3 supVec(0,0,0); + btVector3 supVec(0, 0, 0); btScalar maxDot(btScalar(-BT_LARGE_FLOAT)); @@ -38,20 +35,19 @@ btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) : btConvexInter btScalar lenSqr = vec.length2(); if (lenSqr < btScalar(0.0001)) { - vec.setValue(1,0,0); - } else + vec.setValue(1, 0, 0); + } + else { - btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); + btScalar rlen = btScalar(1.) / btSqrt(lenSqr); vec *= rlen; } btVector3 vtx; btScalar newDot; - - { - btVector3 pos(0,0,0); + btVector3 pos(0, 0, 0); pos[getUpAxis()] = getHalfHeight(); vtx = pos; @@ -63,7 +59,7 @@ btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) : btConvexInter } } { - btVector3 pos(0,0,0); + btVector3 pos(0, 0, 0); pos[getUpAxis()] = -getHalfHeight(); vtx = pos; @@ -76,15 +72,11 @@ btCapsuleShape::btCapsuleShape(btScalar radius, btScalar height) : btConvexInter } return supVec; - } - void btCapsuleShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +void btCapsuleShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const { - - - - for (int j=0;jm_convexInternalShapeData,serializer); + btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData, serializer); shapeData->m_upAxis = m_upAxis; @@ -179,7 +170,7 @@ SIMD_FORCE_INLINE const char* btCapsuleShape::serialize(void* dataBuffer, btSeri return "btCapsuleShapeData"; } -SIMD_FORCE_INLINE void btCapsuleShape::deSerializeFloat(btCapsuleShapeData* dataBuffer) +SIMD_FORCE_INLINE void btCapsuleShape::deSerializeFloat(btCapsuleShapeData* dataBuffer) { m_implicitShapeDimensions.deSerializeFloat(dataBuffer->m_convexInternalShapeData.m_implicitShapeDimensions); m_collisionMargin = dataBuffer->m_convexInternalShapeData.m_collisionMargin; @@ -188,4 +179,4 @@ SIMD_FORCE_INLINE void btCapsuleShape::deSerializeFloat(btCapsuleShapeData* data m_upAxis = dataBuffer->m_upAxis; } -#endif //BT_CAPSULE_SHAPE_H +#endif //BT_CAPSULE_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btCollisionMargin.h b/src/BulletCollision/CollisionShapes/btCollisionMargin.h index 474bf1fb4..abd8ab3eb 100644 --- a/src/BulletCollision/CollisionShapes/btCollisionMargin.h +++ b/src/BulletCollision/CollisionShapes/btCollisionMargin.h @@ -19,9 +19,6 @@ subject to the following restrictions: ///The CONVEX_DISTANCE_MARGIN is a default collision margin for convex collision shapes derived from btConvexInternalShape. ///This collision margin is used by Gjk and some other algorithms ///Note that when creating small objects, you need to make sure to set a smaller collision margin, using the 'setMargin' API -#define CONVEX_DISTANCE_MARGIN btScalar(0.04)// btScalar(0.1)//;//btScalar(0.01) - - - -#endif //BT_COLLISION_MARGIN_H +#define CONVEX_DISTANCE_MARGIN btScalar(0.04) // btScalar(0.1)//;//btScalar(0.01) +#endif //BT_COLLISION_MARGIN_H diff --git a/src/BulletCollision/CollisionShapes/btCollisionShape.cpp b/src/BulletCollision/CollisionShapes/btCollisionShape.cpp index 823e2788f..0b3640a65 100644 --- a/src/BulletCollision/CollisionShapes/btCollisionShape.cpp +++ b/src/BulletCollision/CollisionShapes/btCollisionShape.cpp @@ -20,47 +20,44 @@ subject to the following restrictions: can be used by probes that are checking whether the library is actually installed. */ -extern "C" +extern "C" { -void btBulletCollisionProbe (); + void btBulletCollisionProbe(); -void btBulletCollisionProbe () {} + void btBulletCollisionProbe() {} } - - -void btCollisionShape::getBoundingSphere(btVector3& center,btScalar& radius) const +void btCollisionShape::getBoundingSphere(btVector3& center, btScalar& radius) const { btTransform tr; tr.setIdentity(); - btVector3 aabbMin,aabbMax; + btVector3 aabbMin, aabbMax; - getAabb(tr,aabbMin,aabbMax); + getAabb(tr, aabbMin, aabbMax); - radius = (aabbMax-aabbMin).length()*btScalar(0.5); - center = (aabbMin+aabbMax)*btScalar(0.5); + radius = (aabbMax - aabbMin).length() * btScalar(0.5); + center = (aabbMin + aabbMax) * btScalar(0.5); } - -btScalar btCollisionShape::getContactBreakingThreshold(btScalar defaultContactThreshold) const +btScalar btCollisionShape::getContactBreakingThreshold(btScalar defaultContactThreshold) const { return getAngularMotionDisc() * defaultContactThreshold; } -btScalar btCollisionShape::getAngularMotionDisc() const +btScalar btCollisionShape::getAngularMotionDisc() const { ///@todo cache this value, to improve performance - btVector3 center; + btVector3 center; btScalar disc; - getBoundingSphere(center,disc); + getBoundingSphere(center, disc); disc += (center).length(); return disc; } -void btCollisionShape::calculateTemporalAabb(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep, btVector3& temporalAabbMin,btVector3& temporalAabbMax) const +void btCollisionShape::calculateTemporalAabb(const btTransform& curTrans, const btVector3& linvel, const btVector3& angvel, btScalar timeStep, btVector3& temporalAabbMin, btVector3& temporalAabbMax) const { //start with static aabb - getAabb(curTrans,temporalAabbMin,temporalAabbMax); + getAabb(curTrans, temporalAabbMin, temporalAabbMax); btScalar temporalAabbMaxx = temporalAabbMax.getX(); btScalar temporalAabbMaxy = temporalAabbMax.getY(); @@ -70,36 +67,36 @@ void btCollisionShape::calculateTemporalAabb(const btTransform& curTrans,const b btScalar temporalAabbMinz = temporalAabbMin.getZ(); // add linear motion - btVector3 linMotion = linvel*timeStep; + btVector3 linMotion = linvel * timeStep; ///@todo: simd would have a vector max/min operation, instead of per-element access if (linMotion.x() > btScalar(0.)) - temporalAabbMaxx += linMotion.x(); + temporalAabbMaxx += linMotion.x(); else temporalAabbMinx += linMotion.x(); if (linMotion.y() > btScalar(0.)) - temporalAabbMaxy += linMotion.y(); + temporalAabbMaxy += linMotion.y(); else temporalAabbMiny += linMotion.y(); if (linMotion.z() > btScalar(0.)) - temporalAabbMaxz += linMotion.z(); + temporalAabbMaxz += linMotion.z(); else temporalAabbMinz += linMotion.z(); //add conservative angular motion btScalar angularMotion = angvel.length() * getAngularMotionDisc() * timeStep; - btVector3 angularMotion3d(angularMotion,angularMotion,angularMotion); - temporalAabbMin = btVector3(temporalAabbMinx,temporalAabbMiny,temporalAabbMinz); - temporalAabbMax = btVector3(temporalAabbMaxx,temporalAabbMaxy,temporalAabbMaxz); + btVector3 angularMotion3d(angularMotion, angularMotion, angularMotion); + temporalAabbMin = btVector3(temporalAabbMinx, temporalAabbMiny, temporalAabbMinz); + temporalAabbMax = btVector3(temporalAabbMaxx, temporalAabbMaxy, temporalAabbMaxz); temporalAabbMin -= angularMotion3d; temporalAabbMax += angularMotion3d; } ///fills the dataBuffer and returns the struct name (and 0 on failure) -const char* btCollisionShape::serialize(void* dataBuffer, btSerializer* serializer) const +const char* btCollisionShape::serialize(void* dataBuffer, btSerializer* serializer) const { - btCollisionShapeData* shapeData = (btCollisionShapeData*) dataBuffer; - char* name = (char*) serializer->findNameForPointer(this); + btCollisionShapeData* shapeData = (btCollisionShapeData*)dataBuffer; + char* name = (char*)serializer->findNameForPointer(this); shapeData->m_name = (char*)serializer->getUniquePointer(name); if (shapeData->m_name) { @@ -113,10 +110,10 @@ const char* btCollisionShape::serialize(void* dataBuffer, btSerializer* serializ return "btCollisionShapeData"; } -void btCollisionShape::serializeSingleShape(btSerializer* serializer) const +void btCollisionShape::serializeSingleShape(btSerializer* serializer) const { int len = calculateSerializeBufferSize(); - btChunk* chunk = serializer->allocate(len,1); + btChunk* chunk = serializer->allocate(len, 1); const char* structType = serialize(chunk->m_oldPtr, serializer); - serializer->finalizeChunk(chunk,structType,BT_SHAPE_CODE,(void*)this); + serializer->finalizeChunk(chunk, structType, BT_SHAPE_CODE, (void*)this); } \ No newline at end of file diff --git a/src/BulletCollision/CollisionShapes/btCollisionShape.h b/src/BulletCollision/CollisionShapes/btCollisionShape.h index 6c4916fbd..c80e105a4 100644 --- a/src/BulletCollision/CollisionShapes/btCollisionShape.h +++ b/src/BulletCollision/CollisionShapes/btCollisionShape.h @@ -19,12 +19,12 @@ subject to the following restrictions: #include "LinearMath/btTransform.h" #include "LinearMath/btVector3.h" #include "LinearMath/btMatrix3x3.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" //for the shape types +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" //for the shape types class btSerializer; - ///The btCollisionShape class provides an interface for collision shapes that can be shared among btCollisionObjects. -ATTRIBUTE_ALIGNED16(class) btCollisionShape +ATTRIBUTE_ALIGNED16(class) +btCollisionShape { protected: int m_shapeType; @@ -32,10 +32,9 @@ protected: int m_userIndex; public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - btCollisionShape() : m_shapeType (INVALID_SHAPE_PROXYTYPE), m_userPointer(0), m_userIndex(-1) + btCollisionShape() : m_shapeType(INVALID_SHAPE_PROXYTYPE), m_userPointer(0), m_userIndex(-1) { } @@ -44,50 +43,47 @@ public: } ///getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t. - virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const =0; + virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const = 0; - virtual void getBoundingSphere(btVector3& center,btScalar& radius) const; + virtual void getBoundingSphere(btVector3 & center, btScalar & radius) const; ///getAngularMotionDisc returns the maximum radius needed for Conservative Advancement to handle time-of-impact with rotations. - virtual btScalar getAngularMotionDisc() const; - - virtual btScalar getContactBreakingThreshold(btScalar defaultContactThresholdFactor) const; + virtual btScalar getAngularMotionDisc() const; + virtual btScalar getContactBreakingThreshold(btScalar defaultContactThresholdFactor) const; ///calculateTemporalAabb calculates the enclosing aabb for the moving object over interval [0..timeStep) ///result is conservative - void calculateTemporalAabb(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep, btVector3& temporalAabbMin,btVector3& temporalAabbMax) const; + void calculateTemporalAabb(const btTransform& curTrans, const btVector3& linvel, const btVector3& angvel, btScalar timeStep, btVector3& temporalAabbMin, btVector3& temporalAabbMax) const; - - - SIMD_FORCE_INLINE bool isPolyhedral() const + SIMD_FORCE_INLINE bool isPolyhedral() const { return btBroadphaseProxy::isPolyhedral(getShapeType()); } - SIMD_FORCE_INLINE bool isConvex2d() const + SIMD_FORCE_INLINE bool isConvex2d() const { return btBroadphaseProxy::isConvex2d(getShapeType()); } - SIMD_FORCE_INLINE bool isConvex() const + SIMD_FORCE_INLINE bool isConvex() const { return btBroadphaseProxy::isConvex(getShapeType()); } - SIMD_FORCE_INLINE bool isNonMoving() const + SIMD_FORCE_INLINE bool isNonMoving() const { return btBroadphaseProxy::isNonMoving(getShapeType()); } - SIMD_FORCE_INLINE bool isConcave() const + SIMD_FORCE_INLINE bool isConcave() const { return btBroadphaseProxy::isConcave(getShapeType()); } - SIMD_FORCE_INLINE bool isCompound() const + SIMD_FORCE_INLINE bool isCompound() const { return btBroadphaseProxy::isCompound(getShapeType()); } - SIMD_FORCE_INLINE bool isSoftBody() const + SIMD_FORCE_INLINE bool isSoftBody() const { return btBroadphaseProxy::isSoftBody(getShapeType()); } @@ -99,35 +95,35 @@ public: } #ifndef __SPU__ - virtual void setLocalScaling(const btVector3& scaling) =0; - virtual const btVector3& getLocalScaling() const =0; - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const = 0; + virtual void setLocalScaling(const btVector3& scaling) = 0; + virtual const btVector3& getLocalScaling() const = 0; + virtual void calculateLocalInertia(btScalar mass, btVector3 & inertia) const = 0; + //debugging support + virtual const char* getName() const = 0; +#endif //__SPU__ -//debugging support - virtual const char* getName()const =0 ; -#endif //__SPU__ - - - int getShapeType() const { return m_shapeType; } + int getShapeType() const + { + return m_shapeType; + } ///the getAnisotropicRollingFrictionDirection can be used in combination with setAnisotropicFriction ///See Bullet/Demos/RollingFrictionDemo for an example - virtual btVector3 getAnisotropicRollingFrictionDirection() const + virtual btVector3 getAnisotropicRollingFrictionDirection() const { - return btVector3(1,1,1); + return btVector3(1, 1, 1); } - virtual void setMargin(btScalar margin) = 0; - virtual btScalar getMargin() const = 0; + virtual void setMargin(btScalar margin) = 0; + virtual btScalar getMargin() const = 0; - ///optional user data pointer - void setUserPointer(void* userPtr) + void setUserPointer(void* userPtr) { m_userPointer = userPtr; } - void* getUserPointer() const + void* getUserPointer() const { return m_userPointer; } @@ -141,16 +137,16 @@ public: return m_userIndex; } - - virtual int calculateSerializeBufferSize() const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; - virtual void serializeSingleShape(btSerializer* serializer) const; - -}; + virtual void serializeSingleShape(btSerializer * serializer) const; +}; +// clang-format off +// parser needs * with the name ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 struct btCollisionShapeData { @@ -158,13 +154,10 @@ struct btCollisionShapeData int m_shapeType; char m_padding[4]; }; - -SIMD_FORCE_INLINE int btCollisionShape::calculateSerializeBufferSize() const +// clang-format on +SIMD_FORCE_INLINE int btCollisionShape::calculateSerializeBufferSize() const { return sizeof(btCollisionShapeData); } - - -#endif //BT_COLLISION_SHAPE_H - +#endif //BT_COLLISION_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btCompoundShape.cpp b/src/BulletCollision/CollisionShapes/btCompoundShape.cpp index 85572da30..fd7828b10 100644 --- a/src/BulletCollision/CollisionShapes/btCompoundShape.cpp +++ b/src/BulletCollision/CollisionShapes/btCompoundShape.cpp @@ -19,26 +19,25 @@ subject to the following restrictions: #include "LinearMath/btSerializer.h" btCompoundShape::btCompoundShape(bool enableDynamicAabbTree, const int initialChildCapacity) -: m_localAabbMin(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)), -m_localAabbMax(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)), -m_dynamicAabbTree(0), -m_updateRevision(1), -m_collisionMargin(btScalar(0.)), -m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)) + : m_localAabbMin(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)), + m_localAabbMax(btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT)), + m_dynamicAabbTree(0), + m_updateRevision(1), + m_collisionMargin(btScalar(0.)), + m_localScaling(btScalar(1.), btScalar(1.), btScalar(1.)) { m_shapeType = COMPOUND_SHAPE_PROXYTYPE; if (enableDynamicAabbTree) { - void* mem = btAlignedAlloc(sizeof(btDbvt),16); - m_dynamicAabbTree = new(mem) btDbvt(); - btAssert(mem==m_dynamicAabbTree); + void* mem = btAlignedAlloc(sizeof(btDbvt), 16); + m_dynamicAabbTree = new (mem) btDbvt(); + btAssert(mem == m_dynamicAabbTree); } m_children.reserve(initialChildCapacity); } - btCompoundShape::~btCompoundShape() { if (m_dynamicAabbTree) @@ -48,7 +47,7 @@ btCompoundShape::~btCompoundShape() } } -void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisionShape* shape) +void btCompoundShape::addChildShape(const btTransform& localTransform, btCollisionShape* shape) { m_updateRevision++; //m_childTransforms.push_back(localTransform); @@ -60,11 +59,10 @@ void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisio child.m_childShapeType = shape->getShapeType(); child.m_childMargin = shape->getMargin(); - //extend the local aabbMin/aabbMax - btVector3 localAabbMin,localAabbMax; - shape->getAabb(localTransform,localAabbMin,localAabbMax); - for (int i=0;i<3;i++) + btVector3 localAabbMin, localAabbMax; + shape->getAabb(localTransform, localAabbMin, localAabbMax); + for (int i = 0; i < 3; i++) { if (m_localAabbMin[i] > localAabbMin[i]) { @@ -74,31 +72,30 @@ void btCompoundShape::addChildShape(const btTransform& localTransform,btCollisio { m_localAabbMax[i] = localAabbMax[i]; } - } if (m_dynamicAabbTree) { - const btDbvtVolume bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax); + const btDbvtVolume bounds = btDbvtVolume::FromMM(localAabbMin, localAabbMax); size_t index = m_children.size(); - child.m_node = m_dynamicAabbTree->insert(bounds,reinterpret_cast(index) ); + child.m_node = m_dynamicAabbTree->insert(bounds, reinterpret_cast(index)); } m_children.push_back(child); - } -void btCompoundShape::updateChildTransform(int childIndex, const btTransform& newChildTransform,bool shouldRecalculateLocalAabb) +void btCompoundShape::updateChildTransform(int childIndex, const btTransform& newChildTransform, bool shouldRecalculateLocalAabb) { m_children[childIndex].m_transform = newChildTransform; if (m_dynamicAabbTree) { ///update the dynamic aabb tree - btVector3 localAabbMin,localAabbMax; - m_children[childIndex].m_childShape->getAabb(newChildTransform,localAabbMin,localAabbMax); - ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax); + btVector3 localAabbMin, localAabbMax; + m_children[childIndex].m_childShape->getAabb(newChildTransform, localAabbMin, localAabbMax); + ATTRIBUTE_ALIGNED16(btDbvtVolume) + bounds = btDbvtVolume::FromMM(localAabbMin, localAabbMax); //int index = m_children.size()-1; - m_dynamicAabbTree->update(m_children[childIndex].m_node,bounds); + m_dynamicAabbTree->update(m_children[childIndex].m_node, bounds); } if (shouldRecalculateLocalAabb) @@ -110,35 +107,30 @@ void btCompoundShape::updateChildTransform(int childIndex, const btTransform& ne void btCompoundShape::removeChildShapeByIndex(int childShapeIndex) { m_updateRevision++; - btAssert(childShapeIndex >=0 && childShapeIndex < m_children.size()); + btAssert(childShapeIndex >= 0 && childShapeIndex < m_children.size()); if (m_dynamicAabbTree) { m_dynamicAabbTree->remove(m_children[childShapeIndex].m_node); } - m_children.swap(childShapeIndex,m_children.size()-1); - if (m_dynamicAabbTree) + m_children.swap(childShapeIndex, m_children.size() - 1); + if (m_dynamicAabbTree) m_children[childShapeIndex].m_node->dataAsInt = childShapeIndex; m_children.pop_back(); - } - - void btCompoundShape::removeChildShape(btCollisionShape* shape) { m_updateRevision++; // Find the children containing the shape specified, and remove those children. //note: there might be multiple children using the same shape! - for(int i = m_children.size()-1; i >= 0 ; i--) + for (int i = m_children.size() - 1; i >= 0; i--) { - if(m_children[i].m_childShape == shape) + if (m_children[i].m_childShape == shape) { removeChildShapeByIndex(i); } } - - recalculateLocalAabb(); } @@ -147,15 +139,15 @@ void btCompoundShape::recalculateLocalAabb() // Recalculate the local aabb // Brute force, it iterates over all the shapes left. - m_localAabbMin = btVector3(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); - m_localAabbMax = btVector3(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); + m_localAabbMin = btVector3(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); + m_localAabbMax = btVector3(btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT)); //extend the local aabbMin/aabbMax for (int j = 0; j < m_children.size(); j++) { - btVector3 localAabbMin,localAabbMax; + btVector3 localAabbMin, localAabbMax; m_children[j].m_childShape->getAabb(m_children[j].m_transform, localAabbMin, localAabbMax); - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) { if (m_localAabbMin[i] > localAabbMin[i]) m_localAabbMin[i] = localAabbMin[i]; @@ -166,53 +158,47 @@ void btCompoundShape::recalculateLocalAabb() } ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version -void btCompoundShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const +void btCompoundShape::getAabb(const btTransform& trans, btVector3& aabbMin, btVector3& aabbMax) const { - btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin); - btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin); - + btVector3 localHalfExtents = btScalar(0.5) * (m_localAabbMax - m_localAabbMin); + btVector3 localCenter = btScalar(0.5) * (m_localAabbMax + m_localAabbMin); + //avoid an illegal AABB when there are no children if (!m_children.size()) { - localHalfExtents.setValue(0,0,0); - localCenter.setValue(0,0,0); + localHalfExtents.setValue(0, 0, 0); + localCenter.setValue(0, 0, 0); } - localHalfExtents += btVector3(getMargin(),getMargin(),getMargin()); - + localHalfExtents += btVector3(getMargin(), getMargin(), getMargin()); - btMatrix3x3 abs_b = trans.getBasis().absolute(); + btMatrix3x3 abs_b = trans.getBasis().absolute(); btVector3 center = trans(localCenter); - btVector3 extent = localHalfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); - aabbMin = center-extent; - aabbMax = center+extent; - + btVector3 extent = localHalfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); + aabbMin = center - extent; + aabbMax = center + extent; } -void btCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +void btCompoundShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const { //approximation: take the inertia from the aabb for now btTransform ident; ident.setIdentity(); - btVector3 aabbMin,aabbMax; - getAabb(ident,aabbMin,aabbMax); + btVector3 aabbMin, aabbMax; + getAabb(ident, aabbMin, aabbMax); - btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5); + btVector3 halfExtents = (aabbMax - aabbMin) * btScalar(0.5); - btScalar lx=btScalar(2.)*(halfExtents.x()); - btScalar ly=btScalar(2.)*(halfExtents.y()); - btScalar lz=btScalar(2.)*(halfExtents.z()); - - inertia[0] = mass/(btScalar(12.0)) * (ly*ly + lz*lz); - inertia[1] = mass/(btScalar(12.0)) * (lx*lx + lz*lz); - inertia[2] = mass/(btScalar(12.0)) * (lx*lx + ly*ly); + btScalar lx = btScalar(2.) * (halfExtents.x()); + btScalar ly = btScalar(2.) * (halfExtents.y()); + btScalar lz = btScalar(2.) * (halfExtents.z()); + inertia[0] = mass / (btScalar(12.0)) * (ly * ly + lz * lz); + inertia[1] = mass / (btScalar(12.0)) * (lx * lx + lz * lz); + inertia[2] = mass / (btScalar(12.0)) * (lx * lx + ly * ly); } - - - void btCompoundShape::calculatePrincipalAxisTransform(const btScalar* masses, btTransform& principal, btVector3& inertia) const { int n = m_children.size(); @@ -223,18 +209,18 @@ void btCompoundShape::calculatePrincipalAxisTransform(const btScalar* masses, bt for (k = 0; k < n; k++) { - btAssert(masses[k]>0); + btAssert(masses[k] > 0); center += m_children[k].m_transform.getOrigin() * masses[k]; totalMass += masses[k]; } - btAssert(totalMass>0); + btAssert(totalMass > 0); center /= totalMass; principal.setOrigin(center); btMatrix3x3 tensor(0, 0, 0, 0, 0, 0, 0, 0, 0); - for ( k = 0; k < n; k++) + for (k = 0; k < n; k++) { btVector3 i; m_children[k].m_childShape->calculateLocalInertia(masses[k], i); @@ -259,8 +245,8 @@ void btCompoundShape::calculatePrincipalAxisTransform(const btScalar* masses, bt j[0].setValue(o2, 0, 0); j[1].setValue(0, o2, 0); j[2].setValue(0, 0, o2); - j[0] += o * -o.x(); - j[1] += o * -o.y(); + j[0] += o * -o.x(); + j[1] += o * -o.y(); j[2] += o * -o.z(); //add inertia tensor of pointmass @@ -273,59 +259,50 @@ void btCompoundShape::calculatePrincipalAxisTransform(const btScalar* masses, bt inertia.setValue(tensor[0][0], tensor[1][1], tensor[2][2]); } - - - - void btCompoundShape::setLocalScaling(const btVector3& scaling) { - - for(int i = 0; i < m_children.size(); i++) + for (int i = 0; i < m_children.size(); i++) { btTransform childTrans = getChildTransform(i); btVector3 childScale = m_children[i].m_childShape->getLocalScaling(); -// childScale = childScale * (childTrans.getBasis() * scaling); + // childScale = childScale * (childTrans.getBasis() * scaling); childScale = childScale * scaling / m_localScaling; m_children[i].m_childShape->setLocalScaling(childScale); childTrans.setOrigin((childTrans.getOrigin()) * scaling / m_localScaling); - updateChildTransform(i, childTrans,false); + updateChildTransform(i, childTrans, false); } - + m_localScaling = scaling; recalculateLocalAabb(); - } - void btCompoundShape::createAabbTreeFromChildren() { - if ( !m_dynamicAabbTree ) - { - void* mem = btAlignedAlloc(sizeof(btDbvt),16); - m_dynamicAabbTree = new(mem) btDbvt(); - btAssert(mem==m_dynamicAabbTree); + if (!m_dynamicAabbTree) + { + void* mem = btAlignedAlloc(sizeof(btDbvt), 16); + m_dynamicAabbTree = new (mem) btDbvt(); + btAssert(mem == m_dynamicAabbTree); - for ( int index = 0; index < m_children.size(); index++ ) - { - btCompoundShapeChild &child = m_children[index]; + for (int index = 0; index < m_children.size(); index++) + { + btCompoundShapeChild& child = m_children[index]; - //extend the local aabbMin/aabbMax - btVector3 localAabbMin,localAabbMax; - child.m_childShape->getAabb(child.m_transform,localAabbMin,localAabbMax); + //extend the local aabbMin/aabbMax + btVector3 localAabbMin, localAabbMax; + child.m_childShape->getAabb(child.m_transform, localAabbMin, localAabbMax); - const btDbvtVolume bounds=btDbvtVolume::FromMM(localAabbMin,localAabbMax); + const btDbvtVolume bounds = btDbvtVolume::FromMM(localAabbMin, localAabbMax); size_t index2 = index; - child.m_node = m_dynamicAabbTree->insert(bounds, reinterpret_cast(index2) ); - } - } + child.m_node = m_dynamicAabbTree->insert(bounds, reinterpret_cast(index2)); + } + } } - ///fills the dataBuffer and returns the struct name (and 0 on failure) -const char* btCompoundShape::serialize(void* dataBuffer, btSerializer* serializer) const +const char* btCompoundShape::serialize(void* dataBuffer, btSerializer* serializer) const { - - btCompoundShapeData* shapeData = (btCompoundShapeData*) dataBuffer; + btCompoundShapeData* shapeData = (btCompoundShapeData*)dataBuffer; btCollisionShape::serialize(&shapeData->m_collisionShapeData, serializer); shapeData->m_collisionMargin = float(m_collisionMargin); @@ -333,27 +310,26 @@ const char* btCompoundShape::serialize(void* dataBuffer, btSerializer* serialize shapeData->m_childShapePtr = 0; if (shapeData->m_numChildShapes) { - btChunk* chunk = serializer->allocate(sizeof(btCompoundShapeChildData),shapeData->m_numChildShapes); + btChunk* chunk = serializer->allocate(sizeof(btCompoundShapeChildData), shapeData->m_numChildShapes); btCompoundShapeChildData* memPtr = (btCompoundShapeChildData*)chunk->m_oldPtr; shapeData->m_childShapePtr = (btCompoundShapeChildData*)serializer->getUniquePointer(memPtr); - for (int i=0;im_numChildShapes;i++,memPtr++) + for (int i = 0; i < shapeData->m_numChildShapes; i++, memPtr++) { memPtr->m_childMargin = float(m_children[i].m_childMargin); memPtr->m_childShape = (btCollisionShapeData*)serializer->getUniquePointer(m_children[i].m_childShape); //don't serialize shapes that already have been serialized if (!serializer->findPointer(m_children[i].m_childShape)) { - btChunk* chunk = serializer->allocate(m_children[i].m_childShape->calculateSerializeBufferSize(),1); - const char* structType = m_children[i].m_childShape->serialize(chunk->m_oldPtr,serializer); - serializer->finalizeChunk(chunk,structType,BT_SHAPE_CODE,m_children[i].m_childShape); - } + btChunk* chunk = serializer->allocate(m_children[i].m_childShape->calculateSerializeBufferSize(), 1); + const char* structType = m_children[i].m_childShape->serialize(chunk->m_oldPtr, serializer); + serializer->finalizeChunk(chunk, structType, BT_SHAPE_CODE, m_children[i].m_childShape); + } memPtr->m_childShapeType = m_children[i].m_childShapeType; m_children[i].m_transform.serializeFloat(memPtr->m_transform); } - serializer->finalizeChunk(chunk,"btCompoundShapeChildData",BT_ARRAY_CODE,chunk->m_oldPtr); + serializer->finalizeChunk(chunk, "btCompoundShapeChildData", BT_ARRAY_CODE, chunk->m_oldPtr); } return "btCompoundShapeData"; } - diff --git a/src/BulletCollision/CollisionShapes/btCompoundShape.h b/src/BulletCollision/CollisionShapes/btCompoundShape.h index 2cbcd1bfc..7e2d0eb81 100644 --- a/src/BulletCollision/CollisionShapes/btCompoundShape.h +++ b/src/BulletCollision/CollisionShapes/btCompoundShape.h @@ -27,45 +27,47 @@ subject to the following restrictions: //class btOptimizedBvh; struct btDbvt; -ATTRIBUTE_ALIGNED16(struct) btCompoundShapeChild +ATTRIBUTE_ALIGNED16(struct) +btCompoundShapeChild { BT_DECLARE_ALIGNED_ALLOCATOR(); - btTransform m_transform; - btCollisionShape* m_childShape; - int m_childShapeType; - btScalar m_childMargin; - struct btDbvtNode* m_node; + btTransform m_transform; + btCollisionShape* m_childShape; + int m_childShapeType; + btScalar m_childMargin; + struct btDbvtNode* m_node; }; SIMD_FORCE_INLINE bool operator==(const btCompoundShapeChild& c1, const btCompoundShapeChild& c2) { - return ( c1.m_transform == c2.m_transform && - c1.m_childShape == c2.m_childShape && - c1.m_childShapeType == c2.m_childShapeType && - c1.m_childMargin == c2.m_childMargin ); + return (c1.m_transform == c2.m_transform && + c1.m_childShape == c2.m_childShape && + c1.m_childShapeType == c2.m_childShapeType && + c1.m_childMargin == c2.m_childMargin); } /// The btCompoundShape allows to store multiple other btCollisionShapes /// This allows for moving concave collision objects. This is more general then the static concave btBvhTriangleMeshShape. -/// It has an (optional) dynamic aabb tree to accelerate early rejection tests. +/// It has an (optional) dynamic aabb tree to accelerate early rejection tests. /// @todo: This aabb tree can also be use to speed up ray tests on btCompoundShape, see http://code.google.com/p/bullet/issues/detail?id=25 /// Currently, removal of child shapes is only supported when disabling the aabb tree (pass 'false' in the constructor of btCompoundShape) -ATTRIBUTE_ALIGNED16(class) btCompoundShape : public btCollisionShape +ATTRIBUTE_ALIGNED16(class) +btCompoundShape : public btCollisionShape { protected: btAlignedObjectArray m_children; - btVector3 m_localAabbMin; - btVector3 m_localAabbMax; + btVector3 m_localAabbMin; + btVector3 m_localAabbMax; - btDbvt* m_dynamicAabbTree; + btDbvt* m_dynamicAabbTree; ///increment m_updateRevision when adding/removing/replacing child shapes, so that some caches can be updated - int m_updateRevision; + int m_updateRevision; - btScalar m_collisionMargin; + btScalar m_collisionMargin; - btVector3 m_localScaling; + btVector3 m_localScaling; public: BT_DECLARE_ALIGNED_ALLOCATOR(); @@ -74,17 +76,16 @@ public: virtual ~btCompoundShape(); - void addChildShape(const btTransform& localTransform,btCollisionShape* shape); + void addChildShape(const btTransform& localTransform, btCollisionShape* shape); /// Remove all children shapes that contain the specified shape - virtual void removeChildShape(btCollisionShape* shape); + virtual void removeChildShape(btCollisionShape * shape); void removeChildShapeByIndex(int childShapeindex); - - int getNumChildShapes() const + int getNumChildShapes() const { - return int (m_children.size()); + return int(m_children.size()); } btCollisionShape* getChildShape(int index) @@ -96,18 +97,17 @@ public: return m_children[index].m_childShape; } - btTransform& getChildTransform(int index) + btTransform& getChildTransform(int index) { return m_children[index].m_transform; } - const btTransform& getChildTransform(int index) const + const btTransform& getChildTransform(int index) const { return m_children[index].m_transform; } ///set a new transform for a child, and update internal data structures (local aabb and dynamic tree) - void updateChildTransform(int childIndex, const btTransform& newChildTransform, bool shouldRecalculateLocalAabb = true); - + void updateChildTransform(int childIndex, const btTransform& newChildTransform, bool shouldRecalculateLocalAabb = true); btCompoundShapeChild* getChildList() { @@ -115,40 +115,40 @@ public: } ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version - virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const; /** Re-calculate the local Aabb. Is called at the end of removeChildShapes. Use this yourself if you modify the children or their transforms. */ - virtual void recalculateLocalAabb(); + virtual void recalculateLocalAabb(); - virtual void setLocalScaling(const btVector3& scaling); + virtual void setLocalScaling(const btVector3& scaling); - virtual const btVector3& getLocalScaling() const + virtual const btVector3& getLocalScaling() const { return m_localScaling; } - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + virtual void calculateLocalInertia(btScalar mass, btVector3 & inertia) const; - virtual void setMargin(btScalar margin) + virtual void setMargin(btScalar margin) { m_collisionMargin = margin; } - virtual btScalar getMargin() const + virtual btScalar getMargin() const { return m_collisionMargin; } - virtual const char* getName()const + virtual const char* getName() const { return "Compound"; } - const btDbvt* getDynamicAabbTree() const + const btDbvt* getDynamicAabbTree() const { return m_dynamicAabbTree; } - - btDbvt* getDynamicAabbTree() + + btDbvt* getDynamicAabbTree() { return m_dynamicAabbTree; } @@ -162,19 +162,19 @@ public: ///of the collision object by the principal transform. void calculatePrincipalAxisTransform(const btScalar* masses, btTransform& principal, btVector3& inertia) const; - int getUpdateRevision() const + int getUpdateRevision() const { return m_updateRevision; } - virtual int calculateSerializeBufferSize() const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; - - + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; }; +// clang-format off + ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 struct btCompoundShapeChildData { @@ -197,16 +197,11 @@ struct btCompoundShapeData }; +// clang-format on -SIMD_FORCE_INLINE int btCompoundShape::calculateSerializeBufferSize() const +SIMD_FORCE_INLINE int btCompoundShape::calculateSerializeBufferSize() const { return sizeof(btCompoundShapeData); } - - - - - - -#endif //BT_COMPOUND_SHAPE_H +#endif //BT_COMPOUND_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btConcaveShape.cpp b/src/BulletCollision/CollisionShapes/btConcaveShape.cpp index 58ff84a5b..5d396844d 100644 --- a/src/BulletCollision/CollisionShapes/btConcaveShape.cpp +++ b/src/BulletCollision/CollisionShapes/btConcaveShape.cpp @@ -13,15 +13,12 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btConcaveShape.h" btConcaveShape::btConcaveShape() : m_collisionMargin(btScalar(0.)) { - } btConcaveShape::~btConcaveShape() { - } diff --git a/src/BulletCollision/CollisionShapes/btConcaveShape.h b/src/BulletCollision/CollisionShapes/btConcaveShape.h index 2917cc5b6..716624e18 100644 --- a/src/BulletCollision/CollisionShapes/btConcaveShape.h +++ b/src/BulletCollision/CollisionShapes/btConcaveShape.h @@ -17,12 +17,13 @@ subject to the following restrictions: #define BT_CONCAVE_SHAPE_H #include "btCollisionShape.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types #include "btTriangleCallback.h" /// PHY_ScalarType enumerates possible scalar types. /// See the btStridingMeshInterface or btHeightfieldTerrainShape for its use -typedef enum PHY_ScalarType { +typedef enum PHY_ScalarType +{ PHY_FLOAT, PHY_DOUBLE, PHY_INTEGER, @@ -33,30 +34,29 @@ typedef enum PHY_ScalarType { ///The btConcaveShape class provides an interface for non-moving (static) concave shapes. ///It has been implemented by the btStaticPlaneShape, btBvhTriangleMeshShape and btHeightfieldTerrainShape. -ATTRIBUTE_ALIGNED16(class) btConcaveShape : public btCollisionShape +ATTRIBUTE_ALIGNED16(class) +btConcaveShape : public btCollisionShape { protected: btScalar m_collisionMargin; public: BT_DECLARE_ALIGNED_ALLOCATOR(); - + btConcaveShape(); virtual ~btConcaveShape(); - virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const = 0; + virtual void processAllTriangles(btTriangleCallback * callback, const btVector3& aabbMin, const btVector3& aabbMax) const = 0; - virtual btScalar getMargin() const { + virtual btScalar getMargin() const + { return m_collisionMargin; } virtual void setMargin(btScalar collisionMargin) { m_collisionMargin = collisionMargin; } - - - }; -#endif //BT_CONCAVE_SHAPE_H +#endif //BT_CONCAVE_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btConeShape.cpp b/src/BulletCollision/CollisionShapes/btConeShape.cpp index 2d83c8bfb..64a6f272c 100644 --- a/src/BulletCollision/CollisionShapes/btConeShape.cpp +++ b/src/BulletCollision/CollisionShapes/btConeShape.cpp @@ -15,11 +15,9 @@ subject to the following restrictions: #include "btConeShape.h" - - -btConeShape::btConeShape (btScalar radius,btScalar height): btConvexInternalShape (), -m_radius (radius), -m_height(height) +btConeShape::btConeShape(btScalar radius, btScalar height) : btConvexInternalShape(), + m_radius(radius), + m_height(height) { m_shapeType = CONE_SHAPE_PROXYTYPE; setConeUpIndex(1); @@ -27,42 +25,40 @@ m_height(height) m_sinAngle = (m_radius / btSqrt(m_radius * m_radius + m_height * m_height)); } -btConeShapeZ::btConeShapeZ (btScalar radius,btScalar height): -btConeShape(radius,height) +btConeShapeZ::btConeShapeZ(btScalar radius, btScalar height) : btConeShape(radius, height) { setConeUpIndex(2); } -btConeShapeX::btConeShapeX (btScalar radius,btScalar height): -btConeShape(radius,height) +btConeShapeX::btConeShapeX(btScalar radius, btScalar height) : btConeShape(radius, height) { setConeUpIndex(0); } ///choose upAxis index -void btConeShape::setConeUpIndex(int upIndex) +void btConeShape::setConeUpIndex(int upIndex) { switch (upIndex) { - case 0: + case 0: m_coneIndices[0] = 1; m_coneIndices[1] = 0; m_coneIndices[2] = 2; - break; - case 1: + break; + case 1: m_coneIndices[0] = 0; m_coneIndices[1] = 1; m_coneIndices[2] = 2; - break; - case 2: + break; + case 2: m_coneIndices[0] = 0; m_coneIndices[1] = 2; m_coneIndices[2] = 1; - break; - default: - btAssert(0); + break; + default: + btAssert(0); }; - + m_implicitShapeDimensions[m_coneIndices[0]] = m_radius; m_implicitShapeDimensions[m_coneIndices[1]] = m_height; m_implicitShapeDimensions[m_coneIndices[2]] = m_radius; @@ -70,72 +66,71 @@ void btConeShape::setConeUpIndex(int upIndex) btVector3 btConeShape::coneLocalSupport(const btVector3& v) const { - btScalar halfHeight = m_height * btScalar(0.5); - if (v[m_coneIndices[1]] > v.length() * m_sinAngle) - { - btVector3 tmp; - - tmp[m_coneIndices[0]] = btScalar(0.); - tmp[m_coneIndices[1]] = halfHeight; - tmp[m_coneIndices[2]] = btScalar(0.); - return tmp; - } - else { - btScalar s = btSqrt(v[m_coneIndices[0]] * v[m_coneIndices[0]] + v[m_coneIndices[2]] * v[m_coneIndices[2]]); - if (s > SIMD_EPSILON) { - btScalar d = m_radius / s; - btVector3 tmp; - tmp[m_coneIndices[0]] = v[m_coneIndices[0]] * d; - tmp[m_coneIndices[1]] = -halfHeight; - tmp[m_coneIndices[2]] = v[m_coneIndices[2]] * d; - return tmp; - } - else { + if (v[m_coneIndices[1]] > v.length() * m_sinAngle) + { btVector3 tmp; + tmp[m_coneIndices[0]] = btScalar(0.); - tmp[m_coneIndices[1]] = -halfHeight; + tmp[m_coneIndices[1]] = halfHeight; tmp[m_coneIndices[2]] = btScalar(0.); return tmp; } - } - + else + { + btScalar s = btSqrt(v[m_coneIndices[0]] * v[m_coneIndices[0]] + v[m_coneIndices[2]] * v[m_coneIndices[2]]); + if (s > SIMD_EPSILON) + { + btScalar d = m_radius / s; + btVector3 tmp; + tmp[m_coneIndices[0]] = v[m_coneIndices[0]] * d; + tmp[m_coneIndices[1]] = -halfHeight; + tmp[m_coneIndices[2]] = v[m_coneIndices[2]] * d; + return tmp; + } + else + { + btVector3 tmp; + tmp[m_coneIndices[0]] = btScalar(0.); + tmp[m_coneIndices[1]] = -halfHeight; + tmp[m_coneIndices[2]] = btScalar(0.); + return tmp; + } + } } -btVector3 btConeShape::localGetSupportingVertexWithoutMargin(const btVector3& vec) const +btVector3 btConeShape::localGetSupportingVertexWithoutMargin(const btVector3& vec) const { - return coneLocalSupport(vec); + return coneLocalSupport(vec); } -void btConeShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +void btConeShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const { - for (int i=0;im_convexInternalShapeData,serializer); + btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData, serializer); shapeData->m_upIndex = m_coneIndices[1]; @@ -182,5 +172,4 @@ SIMD_FORCE_INLINE const char* btConeShape::serialize(void* dataBuffer, btSeriali return "btConeShapeData"; } -#endif //BT_CONE_MINKOWSKI_H - +#endif //BT_CONE_MINKOWSKI_H diff --git a/src/BulletCollision/CollisionShapes/btConvex2dShape.cpp b/src/BulletCollision/CollisionShapes/btConvex2dShape.cpp index 10ea3e981..7d3d1d362 100644 --- a/src/BulletCollision/CollisionShapes/btConvex2dShape.cpp +++ b/src/BulletCollision/CollisionShapes/btConvex2dShape.cpp @@ -15,54 +15,48 @@ subject to the following restrictions: #include "btConvex2dShape.h" -btConvex2dShape::btConvex2dShape( btConvexShape* convexChildShape): -btConvexShape (), m_childConvexShape(convexChildShape) +btConvex2dShape::btConvex2dShape(btConvexShape* convexChildShape) : btConvexShape(), m_childConvexShape(convexChildShape) { m_shapeType = CONVEX_2D_SHAPE_PROXYTYPE; } - + btConvex2dShape::~btConvex2dShape() { } - - -btVector3 btConvex2dShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const +btVector3 btConvex2dShape::localGetSupportingVertexWithoutMargin(const btVector3& vec) const { return m_childConvexShape->localGetSupportingVertexWithoutMargin(vec); } -void btConvex2dShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +void btConvex2dShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const { - m_childConvexShape->batchedUnitVectorGetSupportingVertexWithoutMargin(vectors,supportVerticesOut,numVectors); + m_childConvexShape->batchedUnitVectorGetSupportingVertexWithoutMargin(vectors, supportVerticesOut, numVectors); } - -btVector3 btConvex2dShape::localGetSupportingVertex(const btVector3& vec)const +btVector3 btConvex2dShape::localGetSupportingVertex(const btVector3& vec) const { return m_childConvexShape->localGetSupportingVertex(vec); } - -void btConvex2dShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +void btConvex2dShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const { ///this linear upscaling is not realistic, but we don't deal with large mass ratios... - m_childConvexShape->calculateLocalInertia(mass,inertia); + m_childConvexShape->calculateLocalInertia(mass, inertia); } - - ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version -void btConvex2dShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version +void btConvex2dShape::getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const { - m_childConvexShape->getAabb(t,aabbMin,aabbMax); + m_childConvexShape->getAabb(t, aabbMin, aabbMax); } -void btConvex2dShape::getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +void btConvex2dShape::getAabbSlow(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const { - m_childConvexShape->getAabbSlow(t,aabbMin,aabbMax); + m_childConvexShape->getAabbSlow(t, aabbMin, aabbMax); } -void btConvex2dShape::setLocalScaling(const btVector3& scaling) +void btConvex2dShape::setLocalScaling(const btVector3& scaling) { m_childConvexShape->setLocalScaling(scaling); } @@ -72,21 +66,21 @@ const btVector3& btConvex2dShape::getLocalScaling() const return m_childConvexShape->getLocalScaling(); } -void btConvex2dShape::setMargin(btScalar margin) +void btConvex2dShape::setMargin(btScalar margin) { m_childConvexShape->setMargin(margin); } -btScalar btConvex2dShape::getMargin() const +btScalar btConvex2dShape::getMargin() const { return m_childConvexShape->getMargin(); } -int btConvex2dShape::getNumPreferredPenetrationDirections() const +int btConvex2dShape::getNumPreferredPenetrationDirections() const { return m_childConvexShape->getNumPreferredPenetrationDirections(); } - -void btConvex2dShape::getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const + +void btConvex2dShape::getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const { - m_childConvexShape->getPreferredPenetrationDirection(index,penetrationVector); + m_childConvexShape->getPreferredPenetrationDirection(index, penetrationVector); } diff --git a/src/BulletCollision/CollisionShapes/btConvex2dShape.h b/src/BulletCollision/CollisionShapes/btConvex2dShape.h index bbd1caf42..cd4f1ef7b 100644 --- a/src/BulletCollision/CollisionShapes/btConvex2dShape.h +++ b/src/BulletCollision/CollisionShapes/btConvex2dShape.h @@ -17,66 +17,61 @@ subject to the following restrictions: #define BT_CONVEX_2D_SHAPE_H #include "BulletCollision/CollisionShapes/btConvexShape.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types ///The btConvex2dShape allows to use arbitrary convex shapes as 2d convex shapes, with the Z component assumed to be 0. ///For 2d boxes, the btBox2dShape is recommended. -ATTRIBUTE_ALIGNED16(class) btConvex2dShape : public btConvexShape +ATTRIBUTE_ALIGNED16(class) +btConvex2dShape : public btConvexShape { - btConvexShape* m_childConvexShape; + btConvexShape* m_childConvexShape; - public: - +public: BT_DECLARE_ALIGNED_ALLOCATOR(); - - btConvex2dShape( btConvexShape* convexChildShape); - + + btConvex2dShape(btConvexShape * convexChildShape); + virtual ~btConvex2dShape(); - - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; - virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const; - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; + virtual btVector3 localGetSupportingVertex(const btVector3& vec) const; - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const; - btConvexShape* getChildShape() + virtual void calculateLocalInertia(btScalar mass, btVector3 & inertia) const; + + btConvexShape* getChildShape() { return m_childConvexShape; } - const btConvexShape* getChildShape() const + const btConvexShape* getChildShape() const { return m_childConvexShape; } - virtual const char* getName()const + virtual const char* getName() const { return "Convex2dShape"; } - - /////////////////////////// - ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version - void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const; - virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + virtual void getAabbSlow(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const; - virtual void setLocalScaling(const btVector3& scaling) ; - virtual const btVector3& getLocalScaling() const ; + virtual void setLocalScaling(const btVector3& scaling); + virtual const btVector3& getLocalScaling() const; - virtual void setMargin(btScalar margin); - virtual btScalar getMargin() const; - - virtual int getNumPreferredPenetrationDirections() const; - - virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const; + virtual void setMargin(btScalar margin); + virtual btScalar getMargin() const; + virtual int getNumPreferredPenetrationDirections() const; + virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const; }; -#endif //BT_CONVEX_2D_SHAPE_H +#endif //BT_CONVEX_2D_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp b/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp index a7a959840..703de4592 100644 --- a/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp +++ b/src/BulletCollision/CollisionShapes/btConvexHullShape.cpp @@ -13,7 +13,7 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ -#if defined (_WIN32) || defined (__i386__) +#if defined(_WIN32) || defined(__i386__) #define BT_USE_SSE_IN_API #endif @@ -25,14 +25,14 @@ subject to the following restrictions: #include "btConvexPolyhedron.h" #include "LinearMath/btConvexHullComputer.h" -btConvexHullShape ::btConvexHullShape (const btScalar* points,int numPoints,int stride) : btPolyhedralConvexAabbCachingShape () +btConvexHullShape ::btConvexHullShape(const btScalar* points, int numPoints, int stride) : btPolyhedralConvexAabbCachingShape() { m_shapeType = CONVEX_HULL_SHAPE_PROXYTYPE; m_unscaledPoints.resize(numPoints); unsigned char* pointsAddress = (unsigned char*)points; - for (int i=0;im_convexInternalShapeData, serializer); int numElem = m_unscaledPoints.size(); shapeData->m_numUnscaledPoints = numElem; #ifdef BT_USE_DOUBLE_PRECISION shapeData->m_unscaledPointsFloatPtr = 0; - shapeData->m_unscaledPointsDoublePtr = numElem ? (btVector3Data*)serializer->getUniquePointer((void*)&m_unscaledPoints[0]): 0; + shapeData->m_unscaledPointsDoublePtr = numElem ? (btVector3Data*)serializer->getUniquePointer((void*)&m_unscaledPoints[0]) : 0; #else - shapeData->m_unscaledPointsFloatPtr = numElem ? (btVector3Data*)serializer->getUniquePointer((void*)&m_unscaledPoints[0]): 0; + shapeData->m_unscaledPointsFloatPtr = numElem ? (btVector3Data*)serializer->getUniquePointer((void*)&m_unscaledPoints[0]) : 0; shapeData->m_unscaledPointsDoublePtr = 0; #endif - + if (numElem) { int sz = sizeof(btVector3Data); - // int sz2 = sizeof(btVector3DoubleData); - // int sz3 = sizeof(btVector3FloatData); - btChunk* chunk = serializer->allocate(sz,numElem); + // int sz2 = sizeof(btVector3DoubleData); + // int sz3 = sizeof(btVector3FloatData); + btChunk* chunk = serializer->allocate(sz, numElem); btVector3Data* memPtr = (btVector3Data*)chunk->m_oldPtr; - for (int i=0;ifinalizeChunk(chunk,btVector3DataName,BT_ARRAY_CODE,(void*)&m_unscaledPoints[0]); + serializer->finalizeChunk(chunk, btVector3DataName, BT_ARRAY_CODE, (void*)&m_unscaledPoints[0]); } // Fill padding with zeros to appease msan. @@ -218,45 +204,41 @@ const char* btConvexHullShape::serialize(void* dataBuffer, btSerializer* seriali return "btConvexHullShapeData"; } -void btConvexHullShape::project(const btTransform& trans, const btVector3& dir, btScalar& minProj, btScalar& maxProj, btVector3& witnesPtMin,btVector3& witnesPtMax) const +void btConvexHullShape::project(const btTransform& trans, const btVector3& dir, btScalar& minProj, btScalar& maxProj, btVector3& witnesPtMin, btVector3& witnesPtMax) const { #if 1 minProj = FLT_MAX; maxProj = -FLT_MAX; int numVerts = m_unscaledPoints.size(); - for(int i=0;i maxProj) + if (dp > maxProj) { maxProj = dp; - witnesPtMax=pt; + witnesPtMax = pt; } } #else - btVector3 localAxis = dir*trans.getBasis(); - witnesPtMin = trans(localGetSupportingVertex(localAxis)); + btVector3 localAxis = dir * trans.getBasis(); + witnesPtMin = trans(localGetSupportingVertex(localAxis)); witnesPtMax = trans(localGetSupportingVertex(-localAxis)); minProj = witnesPtMin.dot(dir); maxProj = witnesPtMax.dot(dir); #endif - if(minProj>maxProj) + if (minProj > maxProj) { - btSwap(minProj,maxProj); - btSwap(witnesPtMin,witnesPtMax); + btSwap(minProj, maxProj); + btSwap(witnesPtMin, witnesPtMax); } - - } - - diff --git a/src/BulletCollision/CollisionShapes/btConvexHullShape.h b/src/BulletCollision/CollisionShapes/btConvexHullShape.h index 0c12aeef1..96136d7dd 100644 --- a/src/BulletCollision/CollisionShapes/btConvexHullShape.h +++ b/src/BulletCollision/CollisionShapes/btConvexHullShape.h @@ -17,28 +17,26 @@ subject to the following restrictions: #define BT_CONVEX_HULL_SHAPE_H #include "btPolyhedralConvexShape.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types #include "LinearMath/btAlignedObjectArray.h" - ///The btConvexHullShape implements an implicit convex hull of an array of vertices. ///Bullet provides a general and fast collision detector for convex shapes based on GJK and EPA using localGetSupportingVertex. -ATTRIBUTE_ALIGNED16(class) btConvexHullShape : public btPolyhedralConvexAabbCachingShape +ATTRIBUTE_ALIGNED16(class) +btConvexHullShape : public btPolyhedralConvexAabbCachingShape { - btAlignedObjectArray m_unscaledPoints; + btAlignedObjectArray m_unscaledPoints; public: BT_DECLARE_ALIGNED_ALLOCATOR(); - ///this constructor optionally takes in a pointer to points. Each point is assumed to be 3 consecutive btScalar (x,y,z), the striding defines the number of bytes between each point, in memory. ///It is easier to not pass any points in the constructor, and just add one point at a time, using addPoint. ///btConvexHullShape make an internal copy of the points. - btConvexHullShape(const btScalar* points=0,int numPoints=0, int stride=sizeof(btVector3)); + btConvexHullShape(const btScalar* points = 0, int numPoints = 0, int stride = sizeof(btVector3)); void addPoint(const btVector3& point, bool recalculateLocalAabb = true); - btVector3* getUnscaledPoints() { return &m_unscaledPoints[0]; @@ -55,48 +53,46 @@ public: return getUnscaledPoints(); } - void optimizeConvexHull(); - - SIMD_FORCE_INLINE btVector3 getScaledPoint(int i) const + void optimizeConvexHull(); + + SIMD_FORCE_INLINE btVector3 getScaledPoint(int i) const { return m_unscaledPoints[i] * m_localScaling; } - SIMD_FORCE_INLINE int getNumPoints() const + SIMD_FORCE_INLINE int getNumPoints() const { return m_unscaledPoints.size(); } - virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; - - - virtual void project(const btTransform& trans, const btVector3& dir, btScalar& minProj, btScalar& maxProj, btVector3& witnesPtMin,btVector3& witnesPtMax) const; + virtual btVector3 localGetSupportingVertex(const btVector3& vec) const; + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const; + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const; + virtual void project(const btTransform& trans, const btVector3& dir, btScalar& minProj, btScalar& maxProj, btVector3& witnesPtMin, btVector3& witnesPtMax) const; //debugging - virtual const char* getName()const {return "Convex";} + virtual const char* getName() const { return "Convex"; } - - virtual int getNumVertices() const; + virtual int getNumVertices() const; virtual int getNumEdges() const; - virtual void getEdge(int i,btVector3& pa,btVector3& pb) const; - virtual void getVertex(int i,btVector3& vtx) const; - virtual int getNumPlanes() const; - virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const; - virtual bool isInside(const btVector3& pt,btScalar tolerance) const; + virtual void getEdge(int i, btVector3& pa, btVector3& pb) const; + virtual void getVertex(int i, btVector3& vtx) const; + virtual int getNumPlanes() const; + virtual void getPlane(btVector3 & planeNormal, btVector3 & planeSupport, int i) const; + virtual bool isInside(const btVector3& pt, btScalar tolerance) const; ///in case we receive negative scaling - virtual void setLocalScaling(const btVector3& scaling); + virtual void setLocalScaling(const btVector3& scaling); - virtual int calculateSerializeBufferSize() const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; - + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; }; +// clang-format off + ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 struct btConvexHullShapeData { @@ -110,12 +106,11 @@ struct btConvexHullShapeData }; +// clang-format on -SIMD_FORCE_INLINE int btConvexHullShape::calculateSerializeBufferSize() const +SIMD_FORCE_INLINE int btConvexHullShape::calculateSerializeBufferSize() const { return sizeof(btConvexHullShapeData); } - -#endif //BT_CONVEX_HULL_SHAPE_H - +#endif //BT_CONVEX_HULL_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp b/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp index 083d60b1b..4d598b1aa 100644 --- a/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp +++ b/src/BulletCollision/CollisionShapes/btConvexInternalShape.cpp @@ -13,139 +13,125 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btConvexInternalShape.h" - - btConvexInternalShape::btConvexInternalShape() -: m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)), -m_collisionMargin(CONVEX_DISTANCE_MARGIN) + : m_localScaling(btScalar(1.), btScalar(1.), btScalar(1.)), + m_collisionMargin(CONVEX_DISTANCE_MARGIN) { } - -void btConvexInternalShape::setLocalScaling(const btVector3& scaling) +void btConvexInternalShape::setLocalScaling(const btVector3& scaling) { m_localScaling = scaling.absolute(); } - - -void btConvexInternalShape::getAabbSlow(const btTransform& trans,btVector3&minAabb,btVector3&maxAabb) const +void btConvexInternalShape::getAabbSlow(const btTransform& trans, btVector3& minAabb, btVector3& maxAabb) const { #ifndef __SPU__ //use localGetSupportingVertexWithoutMargin? btScalar margin = getMargin(); - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) { - btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); + btVector3 vec(btScalar(0.), btScalar(0.), btScalar(0.)); vec[i] = btScalar(1.); - btVector3 sv = localGetSupportingVertex(vec*trans.getBasis()); + btVector3 sv = localGetSupportingVertex(vec * trans.getBasis()); btVector3 tmp = trans(sv); - maxAabb[i] = tmp[i]+margin; + maxAabb[i] = tmp[i] + margin; vec[i] = btScalar(-1.); - tmp = trans(localGetSupportingVertex(vec*trans.getBasis())); - minAabb[i] = tmp[i]-margin; + tmp = trans(localGetSupportingVertex(vec * trans.getBasis())); + minAabb[i] = tmp[i] - margin; } #endif } - - -btVector3 btConvexInternalShape::localGetSupportingVertex(const btVector3& vec)const +btVector3 btConvexInternalShape::localGetSupportingVertex(const btVector3& vec) const { #ifndef __SPU__ - btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec); + btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec); - if ( getMargin()!=btScalar(0.) ) + if (getMargin() != btScalar(0.)) { btVector3 vecnorm = vec; - if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON)) + if (vecnorm.length2() < (SIMD_EPSILON * SIMD_EPSILON)) { - vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.)); - } + vecnorm.setValue(btScalar(-1.), btScalar(-1.), btScalar(-1.)); + } vecnorm.normalize(); - supVertex+= getMargin() * vecnorm; + supVertex += getMargin() * vecnorm; } return supVertex; #else btAssert(0); - return btVector3(0,0,0); -#endif //__SPU__ - - } - + return btVector3(0, 0, 0); +#endif //__SPU__ +} btConvexInternalAabbCachingShape::btConvexInternalAabbCachingShape() - : btConvexInternalShape(), -m_localAabbMin(1,1,1), -m_localAabbMax(-1,-1,-1), -m_isLocalAabbValid(false) + : btConvexInternalShape(), + m_localAabbMin(1, 1, 1), + m_localAabbMax(-1, -1, -1), + m_isLocalAabbValid(false) { } - -void btConvexInternalAabbCachingShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const +void btConvexInternalAabbCachingShape::getAabb(const btTransform& trans, btVector3& aabbMin, btVector3& aabbMax) const { - getNonvirtualAabb(trans,aabbMin,aabbMax,getMargin()); + getNonvirtualAabb(trans, aabbMin, aabbMax, getMargin()); } -void btConvexInternalAabbCachingShape::setLocalScaling(const btVector3& scaling) +void btConvexInternalAabbCachingShape::setLocalScaling(const btVector3& scaling) { btConvexInternalShape::setLocalScaling(scaling); recalcLocalAabb(); } - -void btConvexInternalAabbCachingShape::recalcLocalAabb() +void btConvexInternalAabbCachingShape::recalcLocalAabb() { m_isLocalAabbValid = true; - - #if 1 + +#if 1 static const btVector3 _directions[] = - { - btVector3( 1., 0., 0.), - btVector3( 0., 1., 0.), - btVector3( 0., 0., 1.), - btVector3( -1., 0., 0.), - btVector3( 0., -1., 0.), - btVector3( 0., 0., -1.) - }; - + { + btVector3(1., 0., 0.), + btVector3(0., 1., 0.), + btVector3(0., 0., 1.), + btVector3(-1., 0., 0.), + btVector3(0., -1., 0.), + btVector3(0., 0., -1.)}; + btVector3 _supporting[] = - { - btVector3( 0., 0., 0.), - btVector3( 0., 0., 0.), - btVector3( 0., 0., 0.), - btVector3( 0., 0., 0.), - btVector3( 0., 0., 0.), - btVector3( 0., 0., 0.) - }; - + { + btVector3(0., 0., 0.), + btVector3(0., 0., 0.), + btVector3(0., 0., 0.), + btVector3(0., 0., 0.), + btVector3(0., 0., 0.), + btVector3(0., 0., 0.)}; + batchedUnitVectorGetSupportingVertexWithoutMargin(_directions, _supporting, 6); - - for ( int i = 0; i < 3; ++i ) + + for (int i = 0; i < 3; ++i) { m_localAabbMax[i] = _supporting[i][i] + m_collisionMargin; m_localAabbMin[i] = _supporting[i + 3][i] - m_collisionMargin; } - - #else - for (int i=0;i<3;i++) +#else + + for (int i = 0; i < 3; i++) { - btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); + btVector3 vec(btScalar(0.), btScalar(0.), btScalar(0.)); vec[i] = btScalar(1.); btVector3 tmp = localGetSupportingVertex(vec); - m_localAabbMax[i] = tmp[i]+m_collisionMargin; + m_localAabbMax[i] = tmp[i] + m_collisionMargin; vec[i] = btScalar(-1.); tmp = localGetSupportingVertex(vec); - m_localAabbMin[i] = tmp[i]-m_collisionMargin; + m_localAabbMin[i] = tmp[i] - m_collisionMargin; } - #endif +#endif } diff --git a/src/BulletCollision/CollisionShapes/btConvexInternalShape.h b/src/BulletCollision/CollisionShapes/btConvexInternalShape.h index 1213b82fb..a28c57de4 100644 --- a/src/BulletCollision/CollisionShapes/btConvexInternalShape.h +++ b/src/BulletCollision/CollisionShapes/btConvexInternalShape.h @@ -19,39 +19,35 @@ subject to the following restrictions: #include "btConvexShape.h" #include "LinearMath/btAabbUtil2.h" - ///The btConvexInternalShape is an internal base class, shared by most convex shape implementations. ///The btConvexInternalShape uses a default collision margin set to CONVEX_DISTANCE_MARGIN. ///This collision margin used by Gjk and some other algorithms, see also btCollisionMargin.h -///Note that when creating small shapes (derived from btConvexInternalShape), +///Note that when creating small shapes (derived from btConvexInternalShape), ///you need to make sure to set a smaller collision margin, using the 'setMargin' API ///There is a automatic mechanism 'setSafeMargin' used by btBoxShape and btCylinderShape -ATTRIBUTE_ALIGNED16(class) btConvexInternalShape : public btConvexShape +ATTRIBUTE_ALIGNED16(class) +btConvexInternalShape : public btConvexShape { - - protected: - +protected: //local scaling. collisionMargin is not scaled ! - btVector3 m_localScaling; + btVector3 m_localScaling; - btVector3 m_implicitShapeDimensions; - - btScalar m_collisionMargin; + btVector3 m_implicitShapeDimensions; - btScalar m_padding; + btScalar m_collisionMargin; + + btScalar m_padding; btConvexInternalShape(); public: - BT_DECLARE_ALIGNED_ALLOCATOR(); virtual ~btConvexInternalShape() { - } - virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; + virtual btVector3 localGetSupportingVertex(const btVector3& vec) const; const btVector3& getImplicitShapeDimensions() const { @@ -62,110 +58,102 @@ public: ///changing a collision shape while the body is in the world is not recommended, ///it is best to remove the body from the world, then make the change, and re-add it ///alternatively flush the contact points, see documentation for 'cleanProxyFromPairs' - void setImplicitShapeDimensions(const btVector3& dimensions) + void setImplicitShapeDimensions(const btVector3& dimensions) { m_implicitShapeDimensions = dimensions; } - void setSafeMargin(btScalar minDimension, btScalar defaultMarginMultiplier = 0.1f) + void setSafeMargin(btScalar minDimension, btScalar defaultMarginMultiplier = 0.1f) { - btScalar safeMargin = defaultMarginMultiplier*minDimension; + btScalar safeMargin = defaultMarginMultiplier * minDimension; if (safeMargin < getMargin()) { setMargin(safeMargin); } } - void setSafeMargin(const btVector3& halfExtents, btScalar defaultMarginMultiplier = 0.1f) + void setSafeMargin(const btVector3& halfExtents, btScalar defaultMarginMultiplier = 0.1f) { //see http://code.google.com/p/bullet/issues/detail?id=349 //this margin check could could be added to other collision shapes too, //or add some assert/warning somewhere - btScalar minDimension=halfExtents[halfExtents.minAxis()]; + btScalar minDimension = halfExtents[halfExtents.minAxis()]; setSafeMargin(minDimension, defaultMarginMultiplier); } ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version - void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const + void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const { - getAabbSlow(t,aabbMin,aabbMax); + getAabbSlow(t, aabbMin, aabbMax); } + virtual void getAabbSlow(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const; - - virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; - - - virtual void setLocalScaling(const btVector3& scaling); - virtual const btVector3& getLocalScaling() const + virtual void setLocalScaling(const btVector3& scaling); + virtual const btVector3& getLocalScaling() const { return m_localScaling; } - const btVector3& getLocalScalingNV() const + const btVector3& getLocalScalingNV() const { return m_localScaling; } - virtual void setMargin(btScalar margin) + virtual void setMargin(btScalar margin) { m_collisionMargin = margin; } - virtual btScalar getMargin() const + virtual btScalar getMargin() const { return m_collisionMargin; } - btScalar getMarginNV() const + btScalar getMarginNV() const { return m_collisionMargin; } - virtual int getNumPreferredPenetrationDirections() const + virtual int getNumPreferredPenetrationDirections() const { return 0; } - - virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const + + virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const { (void)penetrationVector; (void)index; btAssert(0); } - virtual int calculateSerializeBufferSize() const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; - - + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; }; ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 -struct btConvexInternalShapeData +struct btConvexInternalShapeData { - btCollisionShapeData m_collisionShapeData; + btCollisionShapeData m_collisionShapeData; - btVector3FloatData m_localScaling; + btVector3FloatData m_localScaling; - btVector3FloatData m_implicitShapeDimensions; - - float m_collisionMargin; + btVector3FloatData m_implicitShapeDimensions; - int m_padding; + float m_collisionMargin; + int m_padding; }; - - -SIMD_FORCE_INLINE int btConvexInternalShape::calculateSerializeBufferSize() const +SIMD_FORCE_INLINE int btConvexInternalShape::calculateSerializeBufferSize() const { return sizeof(btConvexInternalShapeData); } ///fills the dataBuffer and returns the struct name (and 0 on failure) -SIMD_FORCE_INLINE const char* btConvexInternalShape::serialize(void* dataBuffer, btSerializer* serializer) const +SIMD_FORCE_INLINE const char* btConvexInternalShape::serialize(void* dataBuffer, btSerializer* serializer) const { - btConvexInternalShapeData* shapeData = (btConvexInternalShapeData*) dataBuffer; + btConvexInternalShapeData* shapeData = (btConvexInternalShapeData*)dataBuffer; btCollisionShape::serialize(&shapeData->m_collisionShapeData, serializer); m_implicitShapeDimensions.serializeFloat(shapeData->m_implicitShapeDimensions); @@ -178,50 +166,43 @@ SIMD_FORCE_INLINE const char* btConvexInternalShape::serialize(void* dataBuffer, return "btConvexInternalShapeData"; } - - - ///btConvexInternalAabbCachingShape adds local aabb caching for convex shapes, to avoid expensive bounding box calculations class btConvexInternalAabbCachingShape : public btConvexInternalShape { - btVector3 m_localAabbMin; - btVector3 m_localAabbMax; - bool m_isLocalAabbValid; - + btVector3 m_localAabbMin; + btVector3 m_localAabbMax; + bool m_isLocalAabbValid; + protected: - btConvexInternalAabbCachingShape(); - - void setCachedLocalAabb (const btVector3& aabbMin, const btVector3& aabbMax) + + void setCachedLocalAabb(const btVector3& aabbMin, const btVector3& aabbMax) { m_isLocalAabbValid = true; m_localAabbMin = aabbMin; m_localAabbMax = aabbMax; } - inline void getCachedLocalAabb (btVector3& aabbMin, btVector3& aabbMax) const + inline void getCachedLocalAabb(btVector3& aabbMin, btVector3& aabbMax) const { btAssert(m_isLocalAabbValid); aabbMin = m_localAabbMin; aabbMax = m_localAabbMax; } - inline void getNonvirtualAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax, btScalar margin) const + inline void getNonvirtualAabb(const btTransform& trans, btVector3& aabbMin, btVector3& aabbMax, btScalar margin) const { - //lazy evaluation of local aabb btAssert(m_isLocalAabbValid); - btTransformAabb(m_localAabbMin,m_localAabbMax,margin,trans,aabbMin,aabbMax); + btTransformAabb(m_localAabbMin, m_localAabbMax, margin, trans, aabbMin, aabbMax); } - + public: - - virtual void setLocalScaling(const btVector3& scaling); + virtual void setLocalScaling(const btVector3& scaling); - virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; - - void recalcLocalAabb(); + virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const; + void recalcLocalAabb(); }; -#endif //BT_CONVEX_INTERNAL_SHAPE_H +#endif //BT_CONVEX_INTERNAL_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp b/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp index ad1d1bf78..f00a440fa 100644 --- a/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp +++ b/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.cpp @@ -25,81 +25,73 @@ void btConvexPointCloudShape::setLocalScaling(const btVector3& scaling) } #ifndef __SPU__ -btVector3 btConvexPointCloudShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const +btVector3 btConvexPointCloudShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0) const { - btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.)); + btVector3 supVec(btScalar(0.), btScalar(0.), btScalar(0.)); btScalar maxDot = btScalar(-BT_LARGE_FLOAT); btVector3 vec = vec0; btScalar lenSqr = vec.length2(); if (lenSqr < btScalar(0.0001)) { - vec.setValue(1,0,0); - } else + vec.setValue(1, 0, 0); + } + else { - btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); + btScalar rlen = btScalar(1.) / btSqrt(lenSqr); vec *= rlen; } - - if( m_numPoints > 0 ) - { - // Here we take advantage of dot(a*b, c) = dot( a, b*c) to do less work. Note this transformation is true mathematically, not numerically. - // btVector3 scaled = vec * m_localScaling; - int index = (int) vec.maxDot( &m_unscaledPoints[0], m_numPoints, maxDot); //FIXME: may violate encapsulation of m_unscaledPoints - return getScaledPoint(index); - } + + if (m_numPoints > 0) + { + // Here we take advantage of dot(a*b, c) = dot( a, b*c) to do less work. Note this transformation is true mathematically, not numerically. + // btVector3 scaled = vec * m_localScaling; + int index = (int)vec.maxDot(&m_unscaledPoints[0], m_numPoints, maxDot); //FIXME: may violate encapsulation of m_unscaledPoints + return getScaledPoint(index); + } return supVec; } -void btConvexPointCloudShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +void btConvexPointCloudShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const { - for( int j = 0; j < numVectors; j++ ) - { - const btVector3& vec = vectors[j] * m_localScaling; // dot( a*c, b) = dot(a, b*c) - btScalar maxDot; - int index = (int) vec.maxDot( &m_unscaledPoints[0], m_numPoints, maxDot); - supportVerticesOut[j][3] = btScalar(-BT_LARGE_FLOAT); - if( 0 <= index ) - { - //WARNING: don't swap next lines, the w component would get overwritten! - supportVerticesOut[j] = getScaledPoint(index); - supportVerticesOut[j][3] = maxDot; - } - } - + for (int j = 0; j < numVectors; j++) + { + const btVector3& vec = vectors[j] * m_localScaling; // dot( a*c, b) = dot(a, b*c) + btScalar maxDot; + int index = (int)vec.maxDot(&m_unscaledPoints[0], m_numPoints, maxDot); + supportVerticesOut[j][3] = btScalar(-BT_LARGE_FLOAT); + if (0 <= index) + { + //WARNING: don't swap next lines, the w component would get overwritten! + supportVerticesOut[j] = getScaledPoint(index); + supportVerticesOut[j][3] = maxDot; + } + } } - - -btVector3 btConvexPointCloudShape::localGetSupportingVertex(const btVector3& vec)const +btVector3 btConvexPointCloudShape::localGetSupportingVertex(const btVector3& vec) const { btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec); - if ( getMargin()!=btScalar(0.) ) + if (getMargin() != btScalar(0.)) { btVector3 vecnorm = vec; - if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON)) + if (vecnorm.length2() < (SIMD_EPSILON * SIMD_EPSILON)) { - vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.)); - } + vecnorm.setValue(btScalar(-1.), btScalar(-1.), btScalar(-1.)); + } vecnorm.normalize(); - supVertex+= getMargin() * vecnorm; + supVertex += getMargin() * vecnorm; } return supVertex; } - #endif - - - - - //currently just for debugging (drawing), perhaps future support for algebraic continuous collision detection //Please note that you can debug-draw btConvexHullShape with the Raytracer Demo -int btConvexPointCloudShape::getNumVertices() const +int btConvexPointCloudShape::getNumVertices() const { return m_numPoints; } @@ -109,31 +101,29 @@ int btConvexPointCloudShape::getNumEdges() const return 0; } -void btConvexPointCloudShape::getEdge(int i,btVector3& pa,btVector3& pb) const +void btConvexPointCloudShape::getEdge(int i, btVector3& pa, btVector3& pb) const { - btAssert (0); + btAssert(0); } -void btConvexPointCloudShape::getVertex(int i,btVector3& vtx) const +void btConvexPointCloudShape::getVertex(int i, btVector3& vtx) const { - vtx = m_unscaledPoints[i]*m_localScaling; + vtx = m_unscaledPoints[i] * m_localScaling; } -int btConvexPointCloudShape::getNumPlanes() const +int btConvexPointCloudShape::getNumPlanes() const { return 0; } -void btConvexPointCloudShape::getPlane(btVector3& ,btVector3& ,int ) const +void btConvexPointCloudShape::getPlane(btVector3&, btVector3&, int) const { - btAssert(0); } //not yet -bool btConvexPointCloudShape::isInside(const btVector3& ,btScalar ) const +bool btConvexPointCloudShape::isInside(const btVector3&, btScalar) const { btAssert(0); return false; } - diff --git a/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.h b/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.h index 54b5afac3..c7d554a4d 100644 --- a/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.h +++ b/src/BulletCollision/CollisionShapes/btConvexPointCloudShape.h @@ -17,11 +17,12 @@ subject to the following restrictions: #define BT_CONVEX_POINT_CLOUD_SHAPE_H #include "btPolyhedralConvexShape.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types #include "LinearMath/btAlignedObjectArray.h" ///The btConvexPointCloudShape implements an implicit convex hull of an array of vertices. -ATTRIBUTE_ALIGNED16(class) btConvexPointCloudShape : public btPolyhedralConvexAabbCachingShape +ATTRIBUTE_ALIGNED16(class) +btConvexPointCloudShape : public btPolyhedralConvexAabbCachingShape { btVector3* m_unscaledPoints; int m_numPoints; @@ -31,13 +32,13 @@ public: btConvexPointCloudShape() { - m_localScaling.setValue(1.f,1.f,1.f); + m_localScaling.setValue(1.f, 1.f, 1.f); m_shapeType = CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE; m_unscaledPoints = 0; m_numPoints = 0; } - btConvexPointCloudShape(btVector3* points,int numPoints, const btVector3& localScaling,bool computeAabb = true) + btConvexPointCloudShape(btVector3 * points, int numPoints, const btVector3& localScaling, bool computeAabb = true) { m_localScaling = localScaling; m_shapeType = CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE; @@ -48,7 +49,7 @@ public: recalcLocalAabb(); } - void setPoints (btVector3* points, int numPoints, bool computeAabb = true,const btVector3& localScaling=btVector3(1.f,1.f,1.f)) + void setPoints(btVector3 * points, int numPoints, bool computeAabb = true, const btVector3& localScaling = btVector3(1.f, 1.f, 1.f)) { m_unscaledPoints = points; m_numPoints = numPoints; @@ -58,48 +59,45 @@ public: recalcLocalAabb(); } - SIMD_FORCE_INLINE btVector3* getUnscaledPoints() + SIMD_FORCE_INLINE btVector3* getUnscaledPoints() { return m_unscaledPoints; } - SIMD_FORCE_INLINE const btVector3* getUnscaledPoints() const + SIMD_FORCE_INLINE const btVector3* getUnscaledPoints() const { return m_unscaledPoints; } - SIMD_FORCE_INLINE int getNumPoints() const + SIMD_FORCE_INLINE int getNumPoints() const { return m_numPoints; } - SIMD_FORCE_INLINE btVector3 getScaledPoint( int index) const + SIMD_FORCE_INLINE btVector3 getScaledPoint(int index) const { return m_unscaledPoints[index] * m_localScaling; } #ifndef __SPU__ - virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; + virtual btVector3 localGetSupportingVertex(const btVector3& vec) const; + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const; + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const; #endif - //debugging - virtual const char* getName()const {return "ConvexPointCloud";} + virtual const char* getName() const { return "ConvexPointCloud"; } - virtual int getNumVertices() const; + virtual int getNumVertices() const; virtual int getNumEdges() const; - virtual void getEdge(int i,btVector3& pa,btVector3& pb) const; - virtual void getVertex(int i,btVector3& vtx) const; - virtual int getNumPlanes() const; - virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const; - virtual bool isInside(const btVector3& pt,btScalar tolerance) const; + virtual void getEdge(int i, btVector3& pa, btVector3& pb) const; + virtual void getVertex(int i, btVector3& vtx) const; + virtual int getNumPlanes() const; + virtual void getPlane(btVector3 & planeNormal, btVector3 & planeSupport, int i) const; + virtual bool isInside(const btVector3& pt, btScalar tolerance) const; ///in case we receive negative scaling - virtual void setLocalScaling(const btVector3& scaling); + virtual void setLocalScaling(const btVector3& scaling); }; - -#endif //BT_CONVEX_POINT_CLOUD_SHAPE_H - +#endif //BT_CONVEX_POINT_CLOUD_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp b/src/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp index 0fea00df5..65b669e1c 100644 --- a/src/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp +++ b/src/BulletCollision/CollisionShapes/btConvexPolyhedron.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - ///This file was written by Erwin Coumans ///Separating axis rest based on work from Pierre Terdiman, see ///And contact clipping based on work from Simon Hobbs @@ -21,49 +20,45 @@ subject to the following restrictions: #include "btConvexPolyhedron.h" #include "LinearMath/btHashMap.h" - btConvexPolyhedron::btConvexPolyhedron() { - } btConvexPolyhedron::~btConvexPolyhedron() { - } - inline bool IsAlmostZero(const btVector3& v) { - if(btFabs(v.x())>1e-6 || btFabs(v.y())>1e-6 || btFabs(v.z())>1e-6) return false; + if (btFabs(v.x()) > 1e-6 || btFabs(v.y()) > 1e-6 || btFabs(v.z()) > 1e-6) return false; return true; } struct btInternalVertexPair { - btInternalVertexPair(short int v0,short int v1) - :m_v0(v0), - m_v1(v1) + btInternalVertexPair(short int v0, short int v1) + : m_v0(v0), + m_v1(v1) { - if (m_v1>m_v0) - btSwap(m_v0,m_v1); + if (m_v1 > m_v0) + btSwap(m_v0, m_v1); } short int m_v0; short int m_v1; int getHash() const { - return m_v0+(m_v1<<16); + return m_v0 + (m_v1 << 16); } bool equals(const btInternalVertexPair& other) const { - return m_v0==other.m_v0 && m_v1==other.m_v1; + return m_v0 == other.m_v0 && m_v1 == other.m_v1; } }; struct btInternalEdge { btInternalEdge() - :m_face0(-1), - m_face1(-1) + : m_face0(-1), + m_face1(-1) { } short int m_face0; @@ -75,23 +70,31 @@ struct btInternalEdge #ifdef TEST_INTERNAL_OBJECTS bool btConvexPolyhedron::testContainment() const { - for(int p=0;p<8;p++) + for (int p = 0; p < 8; p++) { btVector3 LocalPt; - if(p==0) LocalPt = m_localCenter + btVector3(m_extents[0], m_extents[1], m_extents[2]); - else if(p==1) LocalPt = m_localCenter + btVector3(m_extents[0], m_extents[1], -m_extents[2]); - else if(p==2) LocalPt = m_localCenter + btVector3(m_extents[0], -m_extents[1], m_extents[2]); - else if(p==3) LocalPt = m_localCenter + btVector3(m_extents[0], -m_extents[1], -m_extents[2]); - else if(p==4) LocalPt = m_localCenter + btVector3(-m_extents[0], m_extents[1], m_extents[2]); - else if(p==5) LocalPt = m_localCenter + btVector3(-m_extents[0], m_extents[1], -m_extents[2]); - else if(p==6) LocalPt = m_localCenter + btVector3(-m_extents[0], -m_extents[1], m_extents[2]); - else if(p==7) LocalPt = m_localCenter + btVector3(-m_extents[0], -m_extents[1], -m_extents[2]); + if (p == 0) + LocalPt = m_localCenter + btVector3(m_extents[0], m_extents[1], m_extents[2]); + else if (p == 1) + LocalPt = m_localCenter + btVector3(m_extents[0], m_extents[1], -m_extents[2]); + else if (p == 2) + LocalPt = m_localCenter + btVector3(m_extents[0], -m_extents[1], m_extents[2]); + else if (p == 3) + LocalPt = m_localCenter + btVector3(m_extents[0], -m_extents[1], -m_extents[2]); + else if (p == 4) + LocalPt = m_localCenter + btVector3(-m_extents[0], m_extents[1], m_extents[2]); + else if (p == 5) + LocalPt = m_localCenter + btVector3(-m_extents[0], m_extents[1], -m_extents[2]); + else if (p == 6) + LocalPt = m_localCenter + btVector3(-m_extents[0], -m_extents[1], m_extents[2]); + else if (p == 7) + LocalPt = m_localCenter + btVector3(-m_extents[0], -m_extents[1], -m_extents[2]); - for(int i=0;i0.0f) + if (d > 0.0f) return false; } } @@ -99,33 +102,28 @@ bool btConvexPolyhedron::testContainment() const } #endif -void btConvexPolyhedron::initialize() +void btConvexPolyhedron::initialize() { + btHashMap edges; - btHashMap edges; - - - - - for(int i=0;im_face0>=0); - btAssert(edptr->m_face1<0); + btAssert(edptr->m_face0 >= 0); + btAssert(edptr->m_face1 < 0); edptr->m_face1 = i; - } else + } + else { btInternalEdge ed; ed.m_face0 = i; - edges.insert(vp,ed); + edges.insert(vp, ed); } } } #ifdef USE_CONNECTED_FACES - for(int i=0;im_face0>=0); - btAssert(edptr->m_face1>=0); + btAssert(edptr->m_face0 >= 0); + btAssert(edptr->m_face1 >= 0); - int connectedFace = (edptr->m_face0==i)?edptr->m_face1:edptr->m_face0; + int connectedFace = (edptr->m_face0 == i) ? edptr->m_face1 : edptr->m_face0; m_faces[i].m_connectedFaces[j] = connectedFace; } } -#endif//USE_CONNECTED_FACES +#endif //USE_CONNECTED_FACES initialize2(); } -void btConvexPolyhedron::initialize2() +void btConvexPolyhedron::initialize2() { m_localCenter.setValue(0, 0, 0); btScalar TotalArea = 0.0f; - for(int i=0;iMaxX) MaxX = pt.x(); - if(pt.y()MaxY) MaxY = pt.y(); - if(pt.z()MaxZ) MaxZ = pt.z(); + if (pt.x() < MinX) MinX = pt.x(); + if (pt.x() > MaxX) MaxX = pt.x(); + if (pt.y() < MinY) MinY = pt.y(); + if (pt.y() > MaxY) MaxY = pt.y(); + if (pt.z() < MinZ) MinZ = pt.z(); + if (pt.z() > MaxZ) MaxZ = pt.z(); } - mC.setValue(MaxX+MinX, MaxY+MinY, MaxZ+MinZ); - mE.setValue(MaxX-MinX, MaxY-MinY, MaxZ-MinZ); + mC.setValue(MaxX + MinX, MaxY + MinY, MaxZ + MinZ); + mE.setValue(MaxX - MinX, MaxY - MinY, MaxZ - MinZ); - - -// const btScalar r = m_radius / sqrtf(2.0f); + // const btScalar r = m_radius / sqrtf(2.0f); const btScalar r = m_radius / sqrtf(3.0f); const int LargestExtent = mE.maxAxis(); - const btScalar Step = (mE[LargestExtent]*0.5f - r)/1024.0f; + const btScalar Step = (mE[LargestExtent] * 0.5f - r) / 1024.0f; m_extents[0] = m_extents[1] = m_extents[2] = r; - m_extents[LargestExtent] = mE[LargestExtent]*0.5f; + m_extents[LargestExtent] = mE[LargestExtent] * 0.5f; bool FoundBox = false; - for(int j=0;j<1024;j++) + for (int j = 0; j < 1024; j++) { - if(testContainment()) + if (testContainment()) { FoundBox = true; break; @@ -252,25 +245,25 @@ void btConvexPolyhedron::initialize2() m_extents[LargestExtent] -= Step; } - if(!FoundBox) + if (!FoundBox) { m_extents[0] = m_extents[1] = m_extents[2] = r; } else { // Refine the box - const btScalar Step = (m_radius - r)/1024.0f; - const int e0 = (1< maxProj) + if (dp > maxProj) { maxProj = dp; witnesPtMax = pt; } } - if(minProj>maxProj) + if (minProj > maxProj) { - btSwap(minProj,maxProj); - btSwap(witnesPtMin,witnesPtMax); + btSwap(minProj, maxProj); + btSwap(witnesPtMin, witnesPtMax); } } diff --git a/src/BulletCollision/CollisionShapes/btConvexPolyhedron.h b/src/BulletCollision/CollisionShapes/btConvexPolyhedron.h index c5aa20f45..638aa9b3d 100644 --- a/src/BulletCollision/CollisionShapes/btConvexPolyhedron.h +++ b/src/BulletCollision/CollisionShapes/btConvexPolyhedron.h @@ -13,10 +13,8 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - ///This file was written by Erwin Coumans - #ifndef _BT_POLYHEDRAL_FEATURES_H #define _BT_POLYHEDRAL_FEATURES_H @@ -25,42 +23,37 @@ subject to the following restrictions: #define TEST_INTERNAL_OBJECTS 1 - struct btFace { - btAlignedObjectArray m_indices; -// btAlignedObjectArray m_connectedFaces; - btScalar m_plane[4]; + btAlignedObjectArray m_indices; + // btAlignedObjectArray m_connectedFaces; + btScalar m_plane[4]; }; - -ATTRIBUTE_ALIGNED16(class) btConvexPolyhedron +ATTRIBUTE_ALIGNED16(class) +btConvexPolyhedron { - public: - +public: BT_DECLARE_ALIGNED_ALLOCATOR(); - - btConvexPolyhedron(); - virtual ~btConvexPolyhedron(); - btAlignedObjectArray m_vertices; - btAlignedObjectArray m_faces; + btConvexPolyhedron(); + virtual ~btConvexPolyhedron(); + + btAlignedObjectArray m_vertices; + btAlignedObjectArray m_faces; btAlignedObjectArray m_uniqueEdges; - btVector3 m_localCenter; - btVector3 m_extents; - btScalar m_radius; - btVector3 mC; - btVector3 mE; + btVector3 m_localCenter; + btVector3 m_extents; + btScalar m_radius; + btVector3 mC; + btVector3 mE; - void initialize(); - void initialize2(); + void initialize(); + void initialize2(); bool testContainment() const; - void project(const btTransform& trans, const btVector3& dir, btScalar& minProj, btScalar& maxProj, btVector3& witnesPtMin,btVector3& witnesPtMax) const; + void project(const btTransform& trans, const btVector3& dir, btScalar& minProj, btScalar& maxProj, btVector3& witnesPtMin, btVector3& witnesPtMax) const; }; - -#endif //_BT_POLYHEDRAL_FEATURES_H - - +#endif //_BT_POLYHEDRAL_FEATURES_H diff --git a/src/BulletCollision/CollisionShapes/btConvexShape.cpp b/src/BulletCollision/CollisionShapes/btConvexShape.cpp index 2f8485859..f8fb0aa9f 100644 --- a/src/BulletCollision/CollisionShapes/btConvexShape.cpp +++ b/src/BulletCollision/CollisionShapes/btConvexShape.cpp @@ -13,7 +13,7 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ -#if defined (_WIN32) || defined (__i386__) +#if defined(_WIN32) || defined(__i386__) #define BT_USE_SSE_IN_API #endif @@ -27,30 +27,28 @@ subject to the following restrictions: #include "btConvexPointCloudShape.h" ///not supported on IBM SDK, until we fix the alignment of btVector3 -#if defined (__CELLOS_LV2__) && defined (__SPU__) +#if defined(__CELLOS_LV2__) && defined(__SPU__) #include -static inline vec_float4 vec_dot3( vec_float4 vec0, vec_float4 vec1 ) +static inline vec_float4 vec_dot3(vec_float4 vec0, vec_float4 vec1) { - vec_float4 result; - result = spu_mul( vec0, vec1 ); - result = spu_madd( spu_rlqwbyte( vec0, 4 ), spu_rlqwbyte( vec1, 4 ), result ); - return spu_madd( spu_rlqwbyte( vec0, 8 ), spu_rlqwbyte( vec1, 8 ), result ); + vec_float4 result; + result = spu_mul(vec0, vec1); + result = spu_madd(spu_rlqwbyte(vec0, 4), spu_rlqwbyte(vec1, 4), result); + return spu_madd(spu_rlqwbyte(vec0, 8), spu_rlqwbyte(vec1, 8), result); } -#endif //__SPU__ +#endif //__SPU__ -btConvexShape::btConvexShape () +btConvexShape::btConvexShape() { } btConvexShape::~btConvexShape() { - } - -void btConvexShape::project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max, btVector3& witnesPtMin,btVector3& witnesPtMax) const +void btConvexShape::project(const btTransform& trans, const btVector3& dir, btScalar& min, btScalar& max, btVector3& witnesPtMin, btVector3& witnesPtMax) const { - btVector3 localAxis = dir*trans.getBasis(); + btVector3 localAxis = dir * trans.getBasis(); btVector3 vtx1 = trans(localGetSupportingVertex(localAxis)); btVector3 vtx2 = trans(localGetSupportingVertex(-localAxis)); @@ -58,8 +56,8 @@ void btConvexShape::project(const btTransform& trans, const btVector3& dir, btSc max = vtx2.dot(dir); witnesPtMax = vtx2; witnesPtMin = vtx1; - - if(min>max) + + if (min > max) { btScalar tmp = min; min = max; @@ -69,391 +67,392 @@ void btConvexShape::project(const btTransform& trans, const btVector3& dir, btSc } } - -static btVector3 convexHullSupport (const btVector3& localDirOrg, const btVector3* points, int numPoints, const btVector3& localScaling) -{ - +static btVector3 convexHullSupport(const btVector3& localDirOrg, const btVector3* points, int numPoints, const btVector3& localScaling) +{ btVector3 vec = localDirOrg * localScaling; -#if defined (__CELLOS_LV2__) && defined (__SPU__) +#if defined(__CELLOS_LV2__) && defined(__SPU__) btVector3 localDir = vec; - vec_float4 v_distMax = {-FLT_MAX,0,0,0}; - vec_int4 v_idxMax = {-999,0,0,0}; - int v=0; + vec_float4 v_distMax = {-FLT_MAX, 0, 0, 0}; + vec_int4 v_idxMax = {-999, 0, 0, 0}; + int v = 0; int numverts = numPoints; - for(;v<(int)numverts-4;v+=4) { - vec_float4 p0 = vec_dot3(points[v ].get128(),localDir.get128()); - vec_float4 p1 = vec_dot3(points[v+1].get128(),localDir.get128()); - vec_float4 p2 = vec_dot3(points[v+2].get128(),localDir.get128()); - vec_float4 p3 = vec_dot3(points[v+3].get128(),localDir.get128()); - const vec_int4 i0 = {v ,0,0,0}; - const vec_int4 i1 = {v+1,0,0,0}; - const vec_int4 i2 = {v+2,0,0,0}; - const vec_int4 i3 = {v+3,0,0,0}; - vec_uint4 retGt01 = spu_cmpgt(p0,p1); - vec_float4 pmax01 = spu_sel(p1,p0,retGt01); - vec_int4 imax01 = spu_sel(i1,i0,retGt01); - vec_uint4 retGt23 = spu_cmpgt(p2,p3); - vec_float4 pmax23 = spu_sel(p3,p2,retGt23); - vec_int4 imax23 = spu_sel(i3,i2,retGt23); - vec_uint4 retGt0123 = spu_cmpgt(pmax01,pmax23); - vec_float4 pmax0123 = spu_sel(pmax23,pmax01,retGt0123); - vec_int4 imax0123 = spu_sel(imax23,imax01,retGt0123); - vec_uint4 retGtMax = spu_cmpgt(v_distMax,pmax0123); - v_distMax = spu_sel(pmax0123,v_distMax,retGtMax); - v_idxMax = spu_sel(imax0123,v_idxMax,retGtMax); + for (; v < (int)numverts - 4; v += 4) + { + vec_float4 p0 = vec_dot3(points[v].get128(), localDir.get128()); + vec_float4 p1 = vec_dot3(points[v + 1].get128(), localDir.get128()); + vec_float4 p2 = vec_dot3(points[v + 2].get128(), localDir.get128()); + vec_float4 p3 = vec_dot3(points[v + 3].get128(), localDir.get128()); + const vec_int4 i0 = {v, 0, 0, 0}; + const vec_int4 i1 = {v + 1, 0, 0, 0}; + const vec_int4 i2 = {v + 2, 0, 0, 0}; + const vec_int4 i3 = {v + 3, 0, 0, 0}; + vec_uint4 retGt01 = spu_cmpgt(p0, p1); + vec_float4 pmax01 = spu_sel(p1, p0, retGt01); + vec_int4 imax01 = spu_sel(i1, i0, retGt01); + vec_uint4 retGt23 = spu_cmpgt(p2, p3); + vec_float4 pmax23 = spu_sel(p3, p2, retGt23); + vec_int4 imax23 = spu_sel(i3, i2, retGt23); + vec_uint4 retGt0123 = spu_cmpgt(pmax01, pmax23); + vec_float4 pmax0123 = spu_sel(pmax23, pmax01, retGt0123); + vec_int4 imax0123 = spu_sel(imax23, imax01, retGt0123); + vec_uint4 retGtMax = spu_cmpgt(v_distMax, pmax0123); + v_distMax = spu_sel(pmax0123, v_distMax, retGtMax); + v_idxMax = spu_sel(imax0123, v_idxMax, retGtMax); } - for(;v<(int)numverts;v++) { - vec_float4 p = vec_dot3(points[v].get128(),localDir.get128()); - const vec_int4 i = {v,0,0,0}; - vec_uint4 retGtMax = spu_cmpgt(v_distMax,p); - v_distMax = spu_sel(p,v_distMax,retGtMax); - v_idxMax = spu_sel(i,v_idxMax,retGtMax); + for (; v < (int)numverts; v++) + { + vec_float4 p = vec_dot3(points[v].get128(), localDir.get128()); + const vec_int4 i = {v, 0, 0, 0}; + vec_uint4 retGtMax = spu_cmpgt(v_distMax, p); + v_distMax = spu_sel(p, v_distMax, retGtMax); + v_idxMax = spu_sel(i, v_idxMax, retGtMax); } - int ptIndex = spu_extract(v_idxMax,0); - const btVector3& supVec= points[ptIndex] * localScaling; + int ptIndex = spu_extract(v_idxMax, 0); + const btVector3& supVec = points[ptIndex] * localScaling; return supVec; #else btScalar maxDot; - long ptIndex = vec.maxDot( points, numPoints, maxDot); + long ptIndex = vec.maxDot(points, numPoints, maxDot); btAssert(ptIndex >= 0); - if (ptIndex<0) + if (ptIndex < 0) { ptIndex = 0; } btVector3 supVec = points[ptIndex] * localScaling; return supVec; -#endif //__SPU__ +#endif //__SPU__ } -btVector3 btConvexShape::localGetSupportVertexWithoutMarginNonVirtual (const btVector3& localDir) const +btVector3 btConvexShape::localGetSupportVertexWithoutMarginNonVirtual(const btVector3& localDir) const { switch (m_shapeType) { - case SPHERE_SHAPE_PROXYTYPE: - { - return btVector3(0,0,0); - } - case BOX_SHAPE_PROXYTYPE: - { - btBoxShape* convexShape = (btBoxShape*)this; - const btVector3& halfExtents = convexShape->getImplicitShapeDimensions(); + case SPHERE_SHAPE_PROXYTYPE: + { + return btVector3(0, 0, 0); + } + case BOX_SHAPE_PROXYTYPE: + { + btBoxShape* convexShape = (btBoxShape*)this; + const btVector3& halfExtents = convexShape->getImplicitShapeDimensions(); -#if defined( __APPLE__ ) && (defined( BT_USE_SSE )||defined( BT_USE_NEON )) - #if defined( BT_USE_SSE ) - return btVector3( _mm_xor_ps( _mm_and_ps( localDir.mVec128, (__m128){-0.0f, -0.0f, -0.0f, -0.0f }), halfExtents.mVec128 )); - #elif defined( BT_USE_NEON ) - return btVector3( (float32x4_t) (((uint32x4_t) localDir.mVec128 & (uint32x4_t){ 0x80000000, 0x80000000, 0x80000000, 0x80000000}) ^ (uint32x4_t) halfExtents.mVec128 )); - #else - #error unknown vector arch - #endif +#if defined(__APPLE__) && (defined(BT_USE_SSE) || defined(BT_USE_NEON)) +#if defined(BT_USE_SSE) + return btVector3(_mm_xor_ps(_mm_and_ps(localDir.mVec128, (__m128){-0.0f, -0.0f, -0.0f, -0.0f}), halfExtents.mVec128)); +#elif defined(BT_USE_NEON) + return btVector3((float32x4_t)(((uint32x4_t)localDir.mVec128 & (uint32x4_t){0x80000000, 0x80000000, 0x80000000, 0x80000000}) ^ (uint32x4_t)halfExtents.mVec128)); #else - return btVector3(btFsels(localDir.x(), halfExtents.x(), -halfExtents.x()), - btFsels(localDir.y(), halfExtents.y(), -halfExtents.y()), - btFsels(localDir.z(), halfExtents.z(), -halfExtents.z())); +#error unknown vector arch #endif - } - case TRIANGLE_SHAPE_PROXYTYPE: - { - btTriangleShape* triangleShape = (btTriangleShape*)this; - btVector3 dir(localDir.getX(),localDir.getY(),localDir.getZ()); - btVector3* vertices = &triangleShape->m_vertices1[0]; - btVector3 dots = dir.dot3(vertices[0], vertices[1], vertices[2]); - btVector3 sup = vertices[dots.maxAxis()]; - return btVector3(sup.getX(),sup.getY(),sup.getZ()); - } - case CYLINDER_SHAPE_PROXYTYPE: - { - btCylinderShape* cylShape = (btCylinderShape*)this; - //mapping of halfextents/dimension onto radius/height depends on how cylinder local orientation is (upAxis) - - btVector3 halfExtents = cylShape->getImplicitShapeDimensions(); - btVector3 v(localDir.getX(),localDir.getY(),localDir.getZ()); - int cylinderUpAxis = cylShape->getUpAxis(); - int XX(1),YY(0),ZZ(2); - - switch (cylinderUpAxis) - { - case 0: - { - XX = 1; - YY = 0; - ZZ = 2; - } - break; - case 1: - { - XX = 0; - YY = 1; - ZZ = 2; - } - break; - case 2: - { - XX = 0; - YY = 2; - ZZ = 1; - - } - break; - default: - btAssert(0); - break; - }; - - btScalar radius = halfExtents[XX]; - btScalar halfHeight = halfExtents[cylinderUpAxis]; - - btVector3 tmp; - btScalar d ; - - btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); - if (s != btScalar(0.0)) - { - d = radius / s; - tmp[XX] = v[XX] * d; - tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; - tmp[ZZ] = v[ZZ] * d; - return btVector3(tmp.getX(),tmp.getY(),tmp.getZ()); - } else { - tmp[XX] = radius; - tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; - tmp[ZZ] = btScalar(0.0); - return btVector3(tmp.getX(),tmp.getY(),tmp.getZ()); - } - } - case CAPSULE_SHAPE_PROXYTYPE: - { - btVector3 vec0(localDir.getX(),localDir.getY(),localDir.getZ()); - - btCapsuleShape* capsuleShape = (btCapsuleShape*)this; - btScalar halfHeight = capsuleShape->getHalfHeight(); - int capsuleUpAxis = capsuleShape->getUpAxis(); - - btVector3 supVec(0,0,0); - - btScalar maxDot(btScalar(-BT_LARGE_FLOAT)); - - btVector3 vec = vec0; - btScalar lenSqr = vec.length2(); - if (lenSqr < SIMD_EPSILON*SIMD_EPSILON) - { - vec.setValue(1,0,0); - } else - { - btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); - vec *= rlen; - } - btVector3 vtx; - btScalar newDot; - { - btVector3 pos(0,0,0); - pos[capsuleUpAxis] = halfHeight; - - vtx = pos; - newDot = vec.dot(vtx); - - - if (newDot > maxDot) - { - maxDot = newDot; - supVec = vtx; - } - } - { - btVector3 pos(0,0,0); - pos[capsuleUpAxis] = -halfHeight; - - vtx = pos; - newDot = vec.dot(vtx); - if (newDot > maxDot) - { - maxDot = newDot; - supVec = vtx; - } - } - return btVector3(supVec.getX(),supVec.getY(),supVec.getZ()); - } - case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: - { - btConvexPointCloudShape* convexPointCloudShape = (btConvexPointCloudShape*)this; - btVector3* points = convexPointCloudShape->getUnscaledPoints (); - int numPoints = convexPointCloudShape->getNumPoints (); - return convexHullSupport (localDir, points, numPoints,convexPointCloudShape->getLocalScalingNV()); - } - case CONVEX_HULL_SHAPE_PROXYTYPE: - { - btConvexHullShape* convexHullShape = (btConvexHullShape*)this; - btVector3* points = convexHullShape->getUnscaledPoints(); - int numPoints = convexHullShape->getNumPoints (); - return convexHullSupport (localDir, points, numPoints,convexHullShape->getLocalScalingNV()); - } - default: -#ifndef __SPU__ - return this->localGetSupportingVertexWithoutMargin (localDir); #else - btAssert (0); + return btVector3(btFsels(localDir.x(), halfExtents.x(), -halfExtents.x()), + btFsels(localDir.y(), halfExtents.y(), -halfExtents.y()), + btFsels(localDir.z(), halfExtents.z(), -halfExtents.z())); +#endif + } + case TRIANGLE_SHAPE_PROXYTYPE: + { + btTriangleShape* triangleShape = (btTriangleShape*)this; + btVector3 dir(localDir.getX(), localDir.getY(), localDir.getZ()); + btVector3* vertices = &triangleShape->m_vertices1[0]; + btVector3 dots = dir.dot3(vertices[0], vertices[1], vertices[2]); + btVector3 sup = vertices[dots.maxAxis()]; + return btVector3(sup.getX(), sup.getY(), sup.getZ()); + } + case CYLINDER_SHAPE_PROXYTYPE: + { + btCylinderShape* cylShape = (btCylinderShape*)this; + //mapping of halfextents/dimension onto radius/height depends on how cylinder local orientation is (upAxis) + + btVector3 halfExtents = cylShape->getImplicitShapeDimensions(); + btVector3 v(localDir.getX(), localDir.getY(), localDir.getZ()); + int cylinderUpAxis = cylShape->getUpAxis(); + int XX(1), YY(0), ZZ(2); + + switch (cylinderUpAxis) + { + case 0: + { + XX = 1; + YY = 0; + ZZ = 2; + } + break; + case 1: + { + XX = 0; + YY = 1; + ZZ = 2; + } + break; + case 2: + { + XX = 0; + YY = 2; + ZZ = 1; + } + break; + default: + btAssert(0); + break; + }; + + btScalar radius = halfExtents[XX]; + btScalar halfHeight = halfExtents[cylinderUpAxis]; + + btVector3 tmp; + btScalar d; + + btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); + if (s != btScalar(0.0)) + { + d = radius / s; + tmp[XX] = v[XX] * d; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = v[ZZ] * d; + return btVector3(tmp.getX(), tmp.getY(), tmp.getZ()); + } + else + { + tmp[XX] = radius; + tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; + tmp[ZZ] = btScalar(0.0); + return btVector3(tmp.getX(), tmp.getY(), tmp.getZ()); + } + } + case CAPSULE_SHAPE_PROXYTYPE: + { + btVector3 vec0(localDir.getX(), localDir.getY(), localDir.getZ()); + + btCapsuleShape* capsuleShape = (btCapsuleShape*)this; + btScalar halfHeight = capsuleShape->getHalfHeight(); + int capsuleUpAxis = capsuleShape->getUpAxis(); + + btVector3 supVec(0, 0, 0); + + btScalar maxDot(btScalar(-BT_LARGE_FLOAT)); + + btVector3 vec = vec0; + btScalar lenSqr = vec.length2(); + if (lenSqr < SIMD_EPSILON * SIMD_EPSILON) + { + vec.setValue(1, 0, 0); + } + else + { + btScalar rlen = btScalar(1.) / btSqrt(lenSqr); + vec *= rlen; + } + btVector3 vtx; + btScalar newDot; + { + btVector3 pos(0, 0, 0); + pos[capsuleUpAxis] = halfHeight; + + vtx = pos; + newDot = vec.dot(vtx); + + if (newDot > maxDot) + { + maxDot = newDot; + supVec = vtx; + } + } + { + btVector3 pos(0, 0, 0); + pos[capsuleUpAxis] = -halfHeight; + + vtx = pos; + newDot = vec.dot(vtx); + if (newDot > maxDot) + { + maxDot = newDot; + supVec = vtx; + } + } + return btVector3(supVec.getX(), supVec.getY(), supVec.getZ()); + } + case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: + { + btConvexPointCloudShape* convexPointCloudShape = (btConvexPointCloudShape*)this; + btVector3* points = convexPointCloudShape->getUnscaledPoints(); + int numPoints = convexPointCloudShape->getNumPoints(); + return convexHullSupport(localDir, points, numPoints, convexPointCloudShape->getLocalScalingNV()); + } + case CONVEX_HULL_SHAPE_PROXYTYPE: + { + btConvexHullShape* convexHullShape = (btConvexHullShape*)this; + btVector3* points = convexHullShape->getUnscaledPoints(); + int numPoints = convexHullShape->getNumPoints(); + return convexHullSupport(localDir, points, numPoints, convexHullShape->getLocalScalingNV()); + } + default: +#ifndef __SPU__ + return this->localGetSupportingVertexWithoutMargin(localDir); +#else + btAssert(0); #endif } // should never reach here - btAssert (0); - return btVector3 (btScalar(0.0f), btScalar(0.0f), btScalar(0.0f)); + btAssert(0); + return btVector3(btScalar(0.0f), btScalar(0.0f), btScalar(0.0f)); } -btVector3 btConvexShape::localGetSupportVertexNonVirtual (const btVector3& localDir) const +btVector3 btConvexShape::localGetSupportVertexNonVirtual(const btVector3& localDir) const { btVector3 localDirNorm = localDir; - if (localDirNorm .length2() < (SIMD_EPSILON*SIMD_EPSILON)) + if (localDirNorm.length2() < (SIMD_EPSILON * SIMD_EPSILON)) { - localDirNorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.)); + localDirNorm.setValue(btScalar(-1.), btScalar(-1.), btScalar(-1.)); } - localDirNorm.normalize (); + localDirNorm.normalize(); - return localGetSupportVertexWithoutMarginNonVirtual(localDirNorm)+ getMarginNonVirtual() * localDirNorm; + return localGetSupportVertexWithoutMarginNonVirtual(localDirNorm) + getMarginNonVirtual() * localDirNorm; } /* TODO: This should be bumped up to btCollisionShape () */ -btScalar btConvexShape::getMarginNonVirtual () const +btScalar btConvexShape::getMarginNonVirtual() const { switch (m_shapeType) { - case SPHERE_SHAPE_PROXYTYPE: - { - btSphereShape* sphereShape = (btSphereShape*)this; - return sphereShape->getRadius (); - } - case BOX_SHAPE_PROXYTYPE: - { - btBoxShape* convexShape = (btBoxShape*)this; - return convexShape->getMarginNV (); - } - case TRIANGLE_SHAPE_PROXYTYPE: - { - btTriangleShape* triangleShape = (btTriangleShape*)this; - return triangleShape->getMarginNV (); - } - case CYLINDER_SHAPE_PROXYTYPE: - { - btCylinderShape* cylShape = (btCylinderShape*)this; - return cylShape->getMarginNV(); - } - case CONE_SHAPE_PROXYTYPE: - { - btConeShape* conShape = (btConeShape*)this; - return conShape->getMarginNV(); - } - case CAPSULE_SHAPE_PROXYTYPE: - { - btCapsuleShape* capsuleShape = (btCapsuleShape*)this; - return capsuleShape->getMarginNV(); - } - case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: - /* fall through */ - case CONVEX_HULL_SHAPE_PROXYTYPE: - { - btPolyhedralConvexShape* convexHullShape = (btPolyhedralConvexShape*)this; - return convexHullShape->getMarginNV(); - } - default: + case SPHERE_SHAPE_PROXYTYPE: + { + btSphereShape* sphereShape = (btSphereShape*)this; + return sphereShape->getRadius(); + } + case BOX_SHAPE_PROXYTYPE: + { + btBoxShape* convexShape = (btBoxShape*)this; + return convexShape->getMarginNV(); + } + case TRIANGLE_SHAPE_PROXYTYPE: + { + btTriangleShape* triangleShape = (btTriangleShape*)this; + return triangleShape->getMarginNV(); + } + case CYLINDER_SHAPE_PROXYTYPE: + { + btCylinderShape* cylShape = (btCylinderShape*)this; + return cylShape->getMarginNV(); + } + case CONE_SHAPE_PROXYTYPE: + { + btConeShape* conShape = (btConeShape*)this; + return conShape->getMarginNV(); + } + case CAPSULE_SHAPE_PROXYTYPE: + { + btCapsuleShape* capsuleShape = (btCapsuleShape*)this; + return capsuleShape->getMarginNV(); + } + case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: + /* fall through */ + case CONVEX_HULL_SHAPE_PROXYTYPE: + { + btPolyhedralConvexShape* convexHullShape = (btPolyhedralConvexShape*)this; + return convexHullShape->getMarginNV(); + } + default: #ifndef __SPU__ - return this->getMargin (); + return this->getMargin(); #else - btAssert (0); + btAssert(0); #endif } // should never reach here - btAssert (0); + btAssert(0); return btScalar(0.0f); } #ifndef __SPU__ -void btConvexShape::getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const +void btConvexShape::getAabbNonVirtual(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const { switch (m_shapeType) { - case SPHERE_SHAPE_PROXYTYPE: - { - btSphereShape* sphereShape = (btSphereShape*)this; - btScalar radius = sphereShape->getImplicitShapeDimensions().getX();// * convexShape->getLocalScaling().getX(); - btScalar margin = radius + sphereShape->getMarginNonVirtual(); - const btVector3& center = t.getOrigin(); - btVector3 extent(margin,margin,margin); - aabbMin = center - extent; - aabbMax = center + extent; - } - break; - case CYLINDER_SHAPE_PROXYTYPE: - /* fall through */ - case BOX_SHAPE_PROXYTYPE: - { - btBoxShape* convexShape = (btBoxShape*)this; - btScalar margin=convexShape->getMarginNonVirtual(); - btVector3 halfExtents = convexShape->getImplicitShapeDimensions(); - halfExtents += btVector3(margin,margin,margin); - btMatrix3x3 abs_b = t.getBasis().absolute(); - btVector3 center = t.getOrigin(); - btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); - - aabbMin = center - extent; - aabbMax = center + extent; - break; - } - case TRIANGLE_SHAPE_PROXYTYPE: - { - btTriangleShape* triangleShape = (btTriangleShape*)this; - btScalar margin = triangleShape->getMarginNonVirtual(); - for (int i=0;i<3;i++) + case SPHERE_SHAPE_PROXYTYPE: { - btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); - vec[i] = btScalar(1.); + btSphereShape* sphereShape = (btSphereShape*)this; + btScalar radius = sphereShape->getImplicitShapeDimensions().getX(); // * convexShape->getLocalScaling().getX(); + btScalar margin = radius + sphereShape->getMarginNonVirtual(); + const btVector3& center = t.getOrigin(); + btVector3 extent(margin, margin, margin); + aabbMin = center - extent; + aabbMax = center + extent; + } + break; + case CYLINDER_SHAPE_PROXYTYPE: + /* fall through */ + case BOX_SHAPE_PROXYTYPE: + { + btBoxShape* convexShape = (btBoxShape*)this; + btScalar margin = convexShape->getMarginNonVirtual(); + btVector3 halfExtents = convexShape->getImplicitShapeDimensions(); + halfExtents += btVector3(margin, margin, margin); + btMatrix3x3 abs_b = t.getBasis().absolute(); + btVector3 center = t.getOrigin(); + btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); - btVector3 sv = localGetSupportVertexWithoutMarginNonVirtual(vec*t.getBasis()); + aabbMin = center - extent; + aabbMax = center + extent; + break; + } + case TRIANGLE_SHAPE_PROXYTYPE: + { + btTriangleShape* triangleShape = (btTriangleShape*)this; + btScalar margin = triangleShape->getMarginNonVirtual(); + for (int i = 0; i < 3; i++) + { + btVector3 vec(btScalar(0.), btScalar(0.), btScalar(0.)); + vec[i] = btScalar(1.); - btVector3 tmp = t(sv); - aabbMax[i] = tmp[i]+margin; - vec[i] = btScalar(-1.); - tmp = t(localGetSupportVertexWithoutMarginNonVirtual(vec*t.getBasis())); - aabbMin[i] = tmp[i]-margin; - } - } - break; - case CAPSULE_SHAPE_PROXYTYPE: - { - btCapsuleShape* capsuleShape = (btCapsuleShape*)this; - btVector3 halfExtents(capsuleShape->getRadius(),capsuleShape->getRadius(),capsuleShape->getRadius()); - int m_upAxis = capsuleShape->getUpAxis(); - halfExtents[m_upAxis] = capsuleShape->getRadius() + capsuleShape->getHalfHeight(); - btMatrix3x3 abs_b = t.getBasis().absolute(); - btVector3 center = t.getOrigin(); - btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); - aabbMin = center - extent; - aabbMax = center + extent; - } - break; - case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: - case CONVEX_HULL_SHAPE_PROXYTYPE: - { - btPolyhedralConvexAabbCachingShape* convexHullShape = (btPolyhedralConvexAabbCachingShape*)this; - btScalar margin = convexHullShape->getMarginNonVirtual(); - convexHullShape->getNonvirtualAabb (t, aabbMin, aabbMax, margin); - } - break; - default: + btVector3 sv = localGetSupportVertexWithoutMarginNonVirtual(vec * t.getBasis()); + + btVector3 tmp = t(sv); + aabbMax[i] = tmp[i] + margin; + vec[i] = btScalar(-1.); + tmp = t(localGetSupportVertexWithoutMarginNonVirtual(vec * t.getBasis())); + aabbMin[i] = tmp[i] - margin; + } + } + break; + case CAPSULE_SHAPE_PROXYTYPE: + { + btCapsuleShape* capsuleShape = (btCapsuleShape*)this; + btVector3 halfExtents(capsuleShape->getRadius(), capsuleShape->getRadius(), capsuleShape->getRadius()); + int m_upAxis = capsuleShape->getUpAxis(); + halfExtents[m_upAxis] = capsuleShape->getRadius() + capsuleShape->getHalfHeight(); + btMatrix3x3 abs_b = t.getBasis().absolute(); + btVector3 center = t.getOrigin(); + btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); + aabbMin = center - extent; + aabbMax = center + extent; + } + break; + case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: + case CONVEX_HULL_SHAPE_PROXYTYPE: + { + btPolyhedralConvexAabbCachingShape* convexHullShape = (btPolyhedralConvexAabbCachingShape*)this; + btScalar margin = convexHullShape->getMarginNonVirtual(); + convexHullShape->getNonvirtualAabb(t, aabbMin, aabbMax, margin); + } + break; + default: #ifndef __SPU__ - this->getAabb (t, aabbMin, aabbMax); + this->getAabb(t, aabbMin, aabbMax); #else - btAssert (0); + btAssert(0); #endif - break; + break; } // should never reach here - btAssert (0); + btAssert(0); } -#endif //__SPU__ +#endif //__SPU__ diff --git a/src/BulletCollision/CollisionShapes/btConvexShape.h b/src/BulletCollision/CollisionShapes/btConvexShape.h index 875f2ac19..d3b3ed816 100644 --- a/src/BulletCollision/CollisionShapes/btConvexShape.h +++ b/src/BulletCollision/CollisionShapes/btConvexShape.h @@ -28,58 +28,48 @@ subject to the following restrictions: /// The btConvexShape is an abstract shape interface, implemented by all convex shapes such as btBoxShape, btConvexHullShape etc. /// It describes general convex shapes using the localGetSupportingVertex interface, used by collision detectors such as btGjkPairDetector. -ATTRIBUTE_ALIGNED16(class) btConvexShape : public btCollisionShape +ATTRIBUTE_ALIGNED16(class) +btConvexShape : public btCollisionShape { - - public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - btConvexShape (); + btConvexShape(); virtual ~btConvexShape(); - virtual btVector3 localGetSupportingVertex(const btVector3& vec)const = 0; + virtual btVector3 localGetSupportingVertex(const btVector3& vec) const = 0; - //////// - #ifndef __SPU__ - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const=0; - #endif //#ifndef __SPU__ +//////// +#ifndef __SPU__ + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const = 0; +#endif //#ifndef __SPU__ - btVector3 localGetSupportVertexWithoutMarginNonVirtual (const btVector3& vec) const; - btVector3 localGetSupportVertexNonVirtual (const btVector3& vec) const; - btScalar getMarginNonVirtual () const; - void getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const; + btVector3 localGetSupportVertexWithoutMarginNonVirtual(const btVector3& vec) const; + btVector3 localGetSupportVertexNonVirtual(const btVector3& vec) const; + btScalar getMarginNonVirtual() const; + void getAabbNonVirtual(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const; + virtual void project(const btTransform& trans, const btVector3& dir, btScalar& minProj, btScalar& maxProj, btVector3& witnesPtMin, btVector3& witnesPtMax) const; - virtual void project(const btTransform& trans, const btVector3& dir, btScalar& minProj, btScalar& maxProj, btVector3& witnesPtMin,btVector3& witnesPtMax) const; - - //notice that the vectors should be unit length - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const= 0; + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const = 0; ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version - void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const =0; + void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const = 0; - virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const =0; + virtual void getAabbSlow(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const = 0; - virtual void setLocalScaling(const btVector3& scaling) =0; - virtual const btVector3& getLocalScaling() const =0; + virtual void setLocalScaling(const btVector3& scaling) = 0; + virtual const btVector3& getLocalScaling() const = 0; - virtual void setMargin(btScalar margin)=0; + virtual void setMargin(btScalar margin) = 0; - virtual btScalar getMargin() const=0; + virtual btScalar getMargin() const = 0; - virtual int getNumPreferredPenetrationDirections() const=0; - - virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const=0; + virtual int getNumPreferredPenetrationDirections() const = 0; - - - + virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const = 0; }; - - -#endif //BT_CONVEX_SHAPE_INTERFACE1 +#endif //BT_CONVEX_SHAPE_INTERFACE1 diff --git a/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp b/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp index 0f9ced554..f6987cc76 100644 --- a/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp +++ b/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.cpp @@ -19,42 +19,37 @@ subject to the following restrictions: #include "LinearMath/btQuaternion.h" #include "BulletCollision/CollisionShapes/btStridingMeshInterface.h" - -btConvexTriangleMeshShape ::btConvexTriangleMeshShape (btStridingMeshInterface* meshInterface, bool calcAabb) -: btPolyhedralConvexAabbCachingShape(), m_stridingMesh(meshInterface) +btConvexTriangleMeshShape ::btConvexTriangleMeshShape(btStridingMeshInterface* meshInterface, bool calcAabb) + : btPolyhedralConvexAabbCachingShape(), m_stridingMesh(meshInterface) { m_shapeType = CONVEX_TRIANGLEMESH_SHAPE_PROXYTYPE; - if ( calcAabb ) + if (calcAabb) recalcLocalAabb(); } - - - ///It's not nice to have all this virtual function overhead, so perhaps we can also gather the points once ///but then we are duplicating -class LocalSupportVertexCallback: public btInternalTriangleIndexCallback +class LocalSupportVertexCallback : public btInternalTriangleIndexCallback { - btVector3 m_supportVertexLocal; -public: +public: btScalar m_maxDot; btVector3 m_supportVecLocal; LocalSupportVertexCallback(const btVector3& supportVecLocal) - : m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)), - m_maxDot(btScalar(-BT_LARGE_FLOAT)), - m_supportVecLocal(supportVecLocal) + : m_supportVertexLocal(btScalar(0.), btScalar(0.), btScalar(0.)), + m_maxDot(btScalar(-BT_LARGE_FLOAT)), + m_supportVecLocal(supportVecLocal) { } - virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex) { (void)triangleIndex; (void)partId; - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) { btScalar dot = m_supportVecLocal.dot(triangle[i]); if (dot > m_maxDot) @@ -64,99 +59,82 @@ public: } } } - - btVector3 GetSupportVertexLocal() + + btVector3 GetSupportVertexLocal() { return m_supportVertexLocal; } - }; - - - - -btVector3 btConvexTriangleMeshShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const +btVector3 btConvexTriangleMeshShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0) const { - btVector3 supVec(btScalar(0.),btScalar(0.),btScalar(0.)); + btVector3 supVec(btScalar(0.), btScalar(0.), btScalar(0.)); btVector3 vec = vec0; btScalar lenSqr = vec.length2(); if (lenSqr < btScalar(0.0001)) { - vec.setValue(1,0,0); - } else + vec.setValue(1, 0, 0); + } + else { - btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); + btScalar rlen = btScalar(1.) / btSqrt(lenSqr); vec *= rlen; } - LocalSupportVertexCallback supportCallback(vec); - btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); - m_stridingMesh->InternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax); + LocalSupportVertexCallback supportCallback(vec); + btVector3 aabbMax(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); + m_stridingMesh->InternalProcessAllTriangles(&supportCallback, -aabbMax, aabbMax); supVec = supportCallback.GetSupportVertexLocal(); return supVec; } -void btConvexTriangleMeshShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +void btConvexTriangleMeshShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const { //use 'w' component of supportVerticesOut? { - for (int i=0;iInternalProcessAllTriangles(&supportCallback,-aabbMax,aabbMax); + LocalSupportVertexCallback supportCallback(vec); + btVector3 aabbMax(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); + m_stridingMesh->InternalProcessAllTriangles(&supportCallback, -aabbMax, aabbMax); supportVerticesOut[j] = supportCallback.GetSupportVertexLocal(); } - } - - -btVector3 btConvexTriangleMeshShape::localGetSupportingVertex(const btVector3& vec)const +btVector3 btConvexTriangleMeshShape::localGetSupportingVertex(const btVector3& vec) const { btVector3 supVertex = localGetSupportingVertexWithoutMargin(vec); - if ( getMargin()!=btScalar(0.) ) + if (getMargin() != btScalar(0.)) { btVector3 vecnorm = vec; - if (vecnorm .length2() < (SIMD_EPSILON*SIMD_EPSILON)) + if (vecnorm.length2() < (SIMD_EPSILON * SIMD_EPSILON)) { - vecnorm.setValue(btScalar(-1.),btScalar(-1.),btScalar(-1.)); - } + vecnorm.setValue(btScalar(-1.), btScalar(-1.), btScalar(-1.)); + } vecnorm.normalize(); - supVertex+= getMargin() * vecnorm; + supVertex += getMargin() * vecnorm; } return supVertex; } - - - - - - - - //currently just for debugging (drawing), perhaps future support for algebraic continuous collision detection //Please note that you can debug-draw btConvexTriangleMeshShape with the Raytracer Demo -int btConvexTriangleMeshShape::getNumVertices() const +int btConvexTriangleMeshShape::getNumVertices() const { //cache this? return 0; - } int btConvexTriangleMeshShape::getNumEdges() const @@ -164,43 +142,39 @@ int btConvexTriangleMeshShape::getNumEdges() const return 0; } -void btConvexTriangleMeshShape::getEdge(int ,btVector3& ,btVector3& ) const -{ - btAssert(0); -} - -void btConvexTriangleMeshShape::getVertex(int ,btVector3& ) const +void btConvexTriangleMeshShape::getEdge(int, btVector3&, btVector3&) const { btAssert(0); } -int btConvexTriangleMeshShape::getNumPlanes() const +void btConvexTriangleMeshShape::getVertex(int, btVector3&) const +{ + btAssert(0); +} + +int btConvexTriangleMeshShape::getNumPlanes() const { return 0; } -void btConvexTriangleMeshShape::getPlane(btVector3& ,btVector3& ,int ) const +void btConvexTriangleMeshShape::getPlane(btVector3&, btVector3&, int) const { btAssert(0); } //not yet -bool btConvexTriangleMeshShape::isInside(const btVector3& ,btScalar ) const +bool btConvexTriangleMeshShape::isInside(const btVector3&, btScalar) const { btAssert(0); return false; } - - -void btConvexTriangleMeshShape::setLocalScaling(const btVector3& scaling) +void btConvexTriangleMeshShape::setLocalScaling(const btVector3& scaling) { m_stridingMesh->setScaling(scaling); - - recalcLocalAabb(); - -} + recalcLocalAabb(); +} const btVector3& btConvexTriangleMeshShape::getLocalScaling() const { @@ -209,107 +183,101 @@ const btVector3& btConvexTriangleMeshShape::getLocalScaling() const void btConvexTriangleMeshShape::calculatePrincipalAxisTransform(btTransform& principal, btVector3& inertia, btScalar& volume) const { - class CenterCallback: public btInternalTriangleIndexCallback - { - bool first; - btVector3 ref; - btVector3 sum; - btScalar volume; + class CenterCallback : public btInternalTriangleIndexCallback + { + bool first; + btVector3 ref; + btVector3 sum; + btScalar volume; - public: + public: + CenterCallback() : first(true), ref(0, 0, 0), sum(0, 0, 0), volume(0) + { + } - CenterCallback() : first(true), ref(0, 0, 0), sum(0, 0, 0), volume(0) - { - } + virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex) + { + (void)triangleIndex; + (void)partId; + if (first) + { + ref = triangle[0]; + first = false; + } + else + { + btScalar vol = btFabs((triangle[0] - ref).triple(triangle[1] - ref, triangle[2] - ref)); + sum += (btScalar(0.25) * vol) * ((triangle[0] + triangle[1] + triangle[2] + ref)); + volume += vol; + } + } - virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex) - { - (void) triangleIndex; - (void) partId; - if (first) - { - ref = triangle[0]; - first = false; - } - else - { - btScalar vol = btFabs((triangle[0] - ref).triple(triangle[1] - ref, triangle[2] - ref)); - sum += (btScalar(0.25) * vol) * ((triangle[0] + triangle[1] + triangle[2] + ref)); - volume += vol; - } - } - - btVector3 getCenter() - { - return (volume > 0) ? sum / volume : ref; - } + btVector3 getCenter() + { + return (volume > 0) ? sum / volume : ref; + } - btScalar getVolume() - { - return volume * btScalar(1. / 6); - } + btScalar getVolume() + { + return volume * btScalar(1. / 6); + } + }; - }; + class InertiaCallback : public btInternalTriangleIndexCallback + { + btMatrix3x3 sum; + btVector3 center; - class InertiaCallback: public btInternalTriangleIndexCallback - { - btMatrix3x3 sum; - btVector3 center; + public: + InertiaCallback(btVector3& center) : sum(0, 0, 0, 0, 0, 0, 0, 0, 0), center(center) + { + } - public: + virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex) + { + (void)triangleIndex; + (void)partId; + btMatrix3x3 i; + btVector3 a = triangle[0] - center; + btVector3 b = triangle[1] - center; + btVector3 c = triangle[2] - center; + btScalar volNeg = -btFabs(a.triple(b, c)) * btScalar(1. / 6); + for (int j = 0; j < 3; j++) + { + for (int k = 0; k <= j; k++) + { + i[j][k] = i[k][j] = volNeg * (btScalar(0.1) * (a[j] * a[k] + b[j] * b[k] + c[j] * c[k]) + btScalar(0.05) * (a[j] * b[k] + a[k] * b[j] + a[j] * c[k] + a[k] * c[j] + b[j] * c[k] + b[k] * c[j])); + } + } + btScalar i00 = -i[0][0]; + btScalar i11 = -i[1][1]; + btScalar i22 = -i[2][2]; + i[0][0] = i11 + i22; + i[1][1] = i22 + i00; + i[2][2] = i00 + i11; + sum[0] += i[0]; + sum[1] += i[1]; + sum[2] += i[2]; + } - InertiaCallback(btVector3& center) : sum(0, 0, 0, 0, 0, 0, 0, 0, 0), center(center) - { - } + btMatrix3x3& getInertia() + { + return sum; + } + }; - virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex) - { - (void) triangleIndex; - (void) partId; - btMatrix3x3 i; - btVector3 a = triangle[0] - center; - btVector3 b = triangle[1] - center; - btVector3 c = triangle[2] - center; - btScalar volNeg = -btFabs(a.triple(b, c)) * btScalar(1. / 6); - for (int j = 0; j < 3; j++) - { - for (int k = 0; k <= j; k++) - { - i[j][k] = i[k][j] = volNeg * (btScalar(0.1) * (a[j] * a[k] + b[j] * b[k] + c[j] * c[k]) - + btScalar(0.05) * (a[j] * b[k] + a[k] * b[j] + a[j] * c[k] + a[k] * c[j] + b[j] * c[k] + b[k] * c[j])); - } - } - btScalar i00 = -i[0][0]; - btScalar i11 = -i[1][1]; - btScalar i22 = -i[2][2]; - i[0][0] = i11 + i22; - i[1][1] = i22 + i00; - i[2][2] = i00 + i11; - sum[0] += i[0]; - sum[1] += i[1]; - sum[2] += i[2]; - } - - btMatrix3x3& getInertia() - { - return sum; - } + CenterCallback centerCallback; + btVector3 aabbMax(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); + m_stridingMesh->InternalProcessAllTriangles(¢erCallback, -aabbMax, aabbMax); + btVector3 center = centerCallback.getCenter(); + principal.setOrigin(center); + volume = centerCallback.getVolume(); - }; + InertiaCallback inertiaCallback(center); + m_stridingMesh->InternalProcessAllTriangles(&inertiaCallback, -aabbMax, aabbMax); - CenterCallback centerCallback; - btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); - m_stridingMesh->InternalProcessAllTriangles(¢erCallback, -aabbMax, aabbMax); - btVector3 center = centerCallback.getCenter(); - principal.setOrigin(center); - volume = centerCallback.getVolume(); - - InertiaCallback inertiaCallback(center); - m_stridingMesh->InternalProcessAllTriangles(&inertiaCallback, -aabbMax, aabbMax); - - btMatrix3x3& i = inertiaCallback.getInertia(); - i.diagonalize(principal.getBasis(), btScalar(0.00001), 20); - inertia.setValue(i[0][0], i[1][1], i[2][2]); - inertia /= volume; + btMatrix3x3& i = inertiaCallback.getInertia(); + i.diagonalize(principal.getBasis(), btScalar(0.00001), 20); + inertia.setValue(i[0][0], i[1][1], i[2][2]); + inertia /= volume; } - diff --git a/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h b/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h index f338865ca..6dac9fff0 100644 --- a/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h +++ b/src/BulletCollision/CollisionShapes/btConvexTriangleMeshShape.h @@ -15,24 +15,22 @@ subject to the following restrictions: #ifndef BT_CONVEX_TRIANGLEMESH_SHAPE_H #define BT_CONVEX_TRIANGLEMESH_SHAPE_H - #include "btPolyhedralConvexShape.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types - +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types /// The btConvexTriangleMeshShape is a convex hull of a triangle mesh, but the performance is not as good as btConvexHullShape. /// A small benefit of this class is that it uses the btStridingMeshInterface, so you can avoid the duplication of the triangle mesh data. Nevertheless, most users should use the much better performing btConvexHullShape instead. -ATTRIBUTE_ALIGNED16(class) btConvexTriangleMeshShape : public btPolyhedralConvexAabbCachingShape +ATTRIBUTE_ALIGNED16(class) +btConvexTriangleMeshShape : public btPolyhedralConvexAabbCachingShape { - - class btStridingMeshInterface* m_stridingMesh; + class btStridingMeshInterface* m_stridingMesh; public: BT_DECLARE_ALIGNED_ALLOCATOR(); - - btConvexTriangleMeshShape(btStridingMeshInterface* meshInterface, bool calcAabb = true); - class btStridingMeshInterface* getMeshInterface() + btConvexTriangleMeshShape(btStridingMeshInterface * meshInterface, bool calcAabb = true); + + class btStridingMeshInterface* getMeshInterface() { return m_stridingMesh; } @@ -40,24 +38,23 @@ public: { return m_stridingMesh; } - - virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; - - //debugging - virtual const char* getName()const {return "ConvexTrimesh";} - - virtual int getNumVertices() const; - virtual int getNumEdges() const; - virtual void getEdge(int i,btVector3& pa,btVector3& pb) const; - virtual void getVertex(int i,btVector3& vtx) const; - virtual int getNumPlanes() const; - virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const; - virtual bool isInside(const btVector3& pt,btScalar tolerance) const; - - virtual void setLocalScaling(const btVector3& scaling); + virtual btVector3 localGetSupportingVertex(const btVector3& vec) const; + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const; + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const; + + //debugging + virtual const char* getName() const { return "ConvexTrimesh"; } + + virtual int getNumVertices() const; + virtual int getNumEdges() const; + virtual void getEdge(int i, btVector3& pa, btVector3& pb) const; + virtual void getVertex(int i, btVector3& vtx) const; + virtual int getNumPlanes() const; + virtual void getPlane(btVector3 & planeNormal, btVector3 & planeSupport, int i) const; + virtual bool isInside(const btVector3& pt, btScalar tolerance) const; + + virtual void setLocalScaling(const btVector3& scaling); virtual const btVector3& getLocalScaling() const; ///computes the exact moment of inertia and the transform from the coordinate system defined by the principal axes of the moment of inertia @@ -65,13 +62,7 @@ public: ///by the mass. The resulting transform "principal" has to be applied inversely to the mesh in order for the local coordinate system of the ///shape to be centered at the center of mass and to coincide with the principal axes. This also necessitates a correction of the world transform ///of the collision object by the principal transform. This method also computes the volume of the convex mesh. - void calculatePrincipalAxisTransform(btTransform& principal, btVector3& inertia, btScalar& volume) const; - + void calculatePrincipalAxisTransform(btTransform & principal, btVector3 & inertia, btScalar & volume) const; }; - - -#endif //BT_CONVEX_TRIANGLEMESH_SHAPE_H - - - +#endif //BT_CONVEX_TRIANGLEMESH_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btCylinderShape.cpp b/src/BulletCollision/CollisionShapes/btCylinderShape.cpp index 604b3fc77..66dbb8e53 100644 --- a/src/BulletCollision/CollisionShapes/btCylinderShape.cpp +++ b/src/BulletCollision/CollisionShapes/btCylinderShape.cpp @@ -15,11 +15,11 @@ subject to the following restrictions: #include "btCylinderShape.h" -btCylinderShape::btCylinderShape (const btVector3& halfExtents) -:btConvexInternalShape(), -m_upAxis(1) +btCylinderShape::btCylinderShape(const btVector3& halfExtents) + : btConvexInternalShape(), + m_upAxis(1) { - btVector3 margin(getMargin(),getMargin(),getMargin()); + btVector3 margin(getMargin(), getMargin(), getMargin()); m_implicitShapeDimensions = (halfExtents * m_localScaling) - margin; setSafeMargin(halfExtents); @@ -27,30 +27,25 @@ m_upAxis(1) m_shapeType = CYLINDER_SHAPE_PROXYTYPE; } - -btCylinderShapeX::btCylinderShapeX (const btVector3& halfExtents) -:btCylinderShape(halfExtents) +btCylinderShapeX::btCylinderShapeX(const btVector3& halfExtents) + : btCylinderShape(halfExtents) { m_upAxis = 0; - } - -btCylinderShapeZ::btCylinderShapeZ (const btVector3& halfExtents) -:btCylinderShape(halfExtents) +btCylinderShapeZ::btCylinderShapeZ(const btVector3& halfExtents) + : btCylinderShape(halfExtents) { m_upAxis = 2; - } -void btCylinderShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +void btCylinderShape::getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const { - btTransformAabb(getHalfExtentsWithoutMargin(),getMargin(),t,aabbMin,aabbMax); + btTransformAabb(getHalfExtentsWithoutMargin(), getMargin(), t, aabbMin, aabbMax); } -void btCylinderShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +void btCylinderShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const { - //Until Bullet 2.77 a box approximation was used, so uncomment this if you need backwards compatibility //#define USE_BOX_INERTIA_APPROXIMATION 1 #ifndef USE_BOX_INERTIA_APPROXIMATION @@ -64,25 +59,25 @@ void btCylinderShape::calculateLocalInertia(btScalar mass,btVector3& inertia) co * */ - btScalar radius2; // square of cylinder radius - btScalar height2; // square of cylinder height - btVector3 halfExtents = getHalfExtentsWithMargin(); // get cylinder dimension + btScalar radius2; // square of cylinder radius + btScalar height2; // square of cylinder height + btVector3 halfExtents = getHalfExtentsWithMargin(); // get cylinder dimension btScalar div12 = mass / 12.f; btScalar div4 = mass / 4.f; btScalar div2 = mass / 2.f; int idxRadius, idxHeight; - switch (m_upAxis) // get indices of radius and height of cylinder + switch (m_upAxis) // get indices of radius and height of cylinder { - case 0: // cylinder is aligned along x + case 0: // cylinder is aligned along x idxRadius = 1; idxHeight = 0; break; - case 2: // cylinder is aligned along z + case 2: // cylinder is aligned along z idxRadius = 0; idxHeight = 2; break; - default: // cylinder is aligned along y + default: // cylinder is aligned along y idxRadius = 0; idxHeight = 1; } @@ -95,188 +90,164 @@ void btCylinderShape::calculateLocalInertia(btScalar mass,btVector3& inertia) co btScalar t1 = div12 * height2 + div4 * radius2; btScalar t2 = div2 * radius2; - switch (m_upAxis) // set diagonal elements of inertia tensor + switch (m_upAxis) // set diagonal elements of inertia tensor { - case 0: // cylinder is aligned along x - inertia.setValue(t2,t1,t1); + case 0: // cylinder is aligned along x + inertia.setValue(t2, t1, t1); break; - case 2: // cylinder is aligned along z - inertia.setValue(t1,t1,t2); + case 2: // cylinder is aligned along z + inertia.setValue(t1, t1, t2); break; - default: // cylinder is aligned along y - inertia.setValue(t1,t2,t1); + default: // cylinder is aligned along y + inertia.setValue(t1, t2, t1); } -#else //USE_BOX_INERTIA_APPROXIMATION +#else //USE_BOX_INERTIA_APPROXIMATION //approximation of box shape btVector3 halfExtents = getHalfExtentsWithMargin(); - btScalar lx=btScalar(2.)*(halfExtents.x()); - btScalar ly=btScalar(2.)*(halfExtents.y()); - btScalar lz=btScalar(2.)*(halfExtents.z()); + btScalar lx = btScalar(2.) * (halfExtents.x()); + btScalar ly = btScalar(2.) * (halfExtents.y()); + btScalar lz = btScalar(2.) * (halfExtents.z()); - inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz), - mass/(btScalar(12.0)) * (lx*lx + lz*lz), - mass/(btScalar(12.0)) * (lx*lx + ly*ly)); -#endif //USE_BOX_INERTIA_APPROXIMATION + inertia.setValue(mass / (btScalar(12.0)) * (ly * ly + lz * lz), + mass / (btScalar(12.0)) * (lx * lx + lz * lz), + mass / (btScalar(12.0)) * (lx * lx + ly * ly)); +#endif //USE_BOX_INERTIA_APPROXIMATION } - -SIMD_FORCE_INLINE btVector3 CylinderLocalSupportX(const btVector3& halfExtents,const btVector3& v) +SIMD_FORCE_INLINE btVector3 CylinderLocalSupportX(const btVector3& halfExtents, const btVector3& v) { -const int cylinderUpAxis = 0; -const int XX = 1; -const int YY = 0; -const int ZZ = 2; + const int cylinderUpAxis = 0; + const int XX = 1; + const int YY = 0; + const int ZZ = 2; //mapping depends on how cylinder local orientation is // extents of the cylinder is: X,Y is for radius, and Z for height - btScalar radius = halfExtents[XX]; btScalar halfHeight = halfExtents[cylinderUpAxis]; + btVector3 tmp; + btScalar d; - btVector3 tmp; - btScalar d ; - - btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); - if (s != btScalar(0.0)) + btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); + if (s != btScalar(0.0)) { - d = radius / s; + d = radius / s; tmp[XX] = v[XX] * d; tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; tmp[ZZ] = v[ZZ] * d; return tmp; } - else + else { - tmp[XX] = radius; + tmp[XX] = radius; tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; tmp[ZZ] = btScalar(0.0); return tmp; - } - - + } } - - - - - -inline btVector3 CylinderLocalSupportY(const btVector3& halfExtents,const btVector3& v) +inline btVector3 CylinderLocalSupportY(const btVector3& halfExtents, const btVector3& v) { - -const int cylinderUpAxis = 1; -const int XX = 0; -const int YY = 1; -const int ZZ = 2; - + const int cylinderUpAxis = 1; + const int XX = 0; + const int YY = 1; + const int ZZ = 2; btScalar radius = halfExtents[XX]; btScalar halfHeight = halfExtents[cylinderUpAxis]; + btVector3 tmp; + btScalar d; - btVector3 tmp; - btScalar d ; - - btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); - if (s != btScalar(0.0)) + btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); + if (s != btScalar(0.0)) { - d = radius / s; + d = radius / s; tmp[XX] = v[XX] * d; tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; tmp[ZZ] = v[ZZ] * d; return tmp; } - else + else { - tmp[XX] = radius; + tmp[XX] = radius; tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; tmp[ZZ] = btScalar(0.0); return tmp; - } - + } } -inline btVector3 CylinderLocalSupportZ(const btVector3& halfExtents,const btVector3& v) +inline btVector3 CylinderLocalSupportZ(const btVector3& halfExtents, const btVector3& v) { -const int cylinderUpAxis = 2; -const int XX = 0; -const int YY = 2; -const int ZZ = 1; + const int cylinderUpAxis = 2; + const int XX = 0; + const int YY = 2; + const int ZZ = 1; //mapping depends on how cylinder local orientation is // extents of the cylinder is: X,Y is for radius, and Z for height - btScalar radius = halfExtents[XX]; btScalar halfHeight = halfExtents[cylinderUpAxis]; + btVector3 tmp; + btScalar d; - btVector3 tmp; - btScalar d ; - - btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); - if (s != btScalar(0.0)) + btScalar s = btSqrt(v[XX] * v[XX] + v[ZZ] * v[ZZ]); + if (s != btScalar(0.0)) { - d = radius / s; + d = radius / s; tmp[XX] = v[XX] * d; tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; tmp[ZZ] = v[ZZ] * d; return tmp; } - else + else { - tmp[XX] = radius; + tmp[XX] = radius; tmp[YY] = v[YY] < 0.0 ? -halfHeight : halfHeight; tmp[ZZ] = btScalar(0.0); return tmp; - } - - -} - -btVector3 btCylinderShapeX::localGetSupportingVertexWithoutMargin(const btVector3& vec)const -{ - return CylinderLocalSupportX(getHalfExtentsWithoutMargin(),vec); -} - - -btVector3 btCylinderShapeZ::localGetSupportingVertexWithoutMargin(const btVector3& vec)const -{ - return CylinderLocalSupportZ(getHalfExtentsWithoutMargin(),vec); -} -btVector3 btCylinderShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const -{ - return CylinderLocalSupportY(getHalfExtentsWithoutMargin(),vec); -} - -void btCylinderShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const -{ - for (int i=0;im_convexInternalShapeData,serializer); + btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData, serializer); shapeData->m_upAxis = m_upAxis; @@ -213,7 +203,4 @@ SIMD_FORCE_INLINE const char* btCylinderShape::serialize(void* dataBuffer, btSer return "btCylinderShapeData"; } - - -#endif //BT_CYLINDER_MINKOWSKI_H - +#endif //BT_CYLINDER_MINKOWSKI_H diff --git a/src/BulletCollision/CollisionShapes/btEmptyShape.cpp b/src/BulletCollision/CollisionShapes/btEmptyShape.cpp index a9e6df5c5..4699555bd 100644 --- a/src/BulletCollision/CollisionShapes/btEmptyShape.cpp +++ b/src/BulletCollision/CollisionShapes/btEmptyShape.cpp @@ -15,36 +15,28 @@ subject to the following restrictions: #include "btEmptyShape.h" - #include "btCollisionShape.h" - -btEmptyShape::btEmptyShape() : btConcaveShape () +btEmptyShape::btEmptyShape() : btConcaveShape() { m_shapeType = EMPTY_SHAPE_PROXYTYPE; } - btEmptyShape::~btEmptyShape() { } - - ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version -void btEmptyShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version +void btEmptyShape::getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const { - btVector3 margin(getMargin(),getMargin(),getMargin()); + btVector3 margin(getMargin(), getMargin(), getMargin()); aabbMin = t.getOrigin() - margin; aabbMax = t.getOrigin() + margin; - } -void btEmptyShape::calculateLocalInertia(btScalar ,btVector3& ) const +void btEmptyShape::calculateLocalInertia(btScalar, btVector3&) const { btAssert(0); } - - - diff --git a/src/BulletCollision/CollisionShapes/btEmptyShape.h b/src/BulletCollision/CollisionShapes/btEmptyShape.h index 069a79402..d2e21173b 100644 --- a/src/BulletCollision/CollisionShapes/btEmptyShape.h +++ b/src/BulletCollision/CollisionShapes/btEmptyShape.h @@ -23,50 +23,43 @@ subject to the following restrictions: #include "LinearMath/btMatrix3x3.h" #include "btCollisionMargin.h" - - - /// The btEmptyShape is a collision shape without actual collision detection shape, so most users should ignore this class. /// It can be replaced by another shape during runtime, but the inertia tensor should be recomputed. -ATTRIBUTE_ALIGNED16(class) btEmptyShape : public btConcaveShape +ATTRIBUTE_ALIGNED16(class) +btEmptyShape : public btConcaveShape { public: BT_DECLARE_ALIGNED_ALLOCATOR(); - + btEmptyShape(); virtual ~btEmptyShape(); - ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version - void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const; - - virtual void setLocalScaling(const btVector3& scaling) + virtual void setLocalScaling(const btVector3& scaling) { m_localScaling = scaling; } - virtual const btVector3& getLocalScaling() const + virtual const btVector3& getLocalScaling() const { return m_localScaling; } - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; - - virtual const char* getName()const + virtual void calculateLocalInertia(btScalar mass, btVector3 & inertia) const; + + virtual const char* getName() const { return "Empty"; } - virtual void processAllTriangles(btTriangleCallback* ,const btVector3& ,const btVector3& ) const + virtual void processAllTriangles(btTriangleCallback*, const btVector3&, const btVector3&) const { } protected: - btVector3 m_localScaling; - + btVector3 m_localScaling; }; - - -#endif //BT_EMPTY_SHAPE_H +#endif //BT_EMPTY_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp b/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp index 441a89c6b..c85ce2498 100644 --- a/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp +++ b/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.cpp @@ -17,23 +17,17 @@ subject to the following restrictions: #include "LinearMath/btTransformUtil.h" - - -btHeightfieldTerrainShape::btHeightfieldTerrainShape -( -int heightStickWidth, int heightStickLength, const void* heightfieldData, -btScalar heightScale, btScalar minHeight, btScalar maxHeight,int upAxis, -PHY_ScalarType hdt, bool flipQuadEdges -) +btHeightfieldTerrainShape::btHeightfieldTerrainShape( + int heightStickWidth, int heightStickLength, const void* heightfieldData, + btScalar heightScale, btScalar minHeight, btScalar maxHeight, int upAxis, + PHY_ScalarType hdt, bool flipQuadEdges) { initialize(heightStickWidth, heightStickLength, heightfieldData, - heightScale, minHeight, maxHeight, upAxis, hdt, - flipQuadEdges); + heightScale, minHeight, maxHeight, upAxis, hdt, + flipQuadEdges); } - - -btHeightfieldTerrainShape::btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength,const void* heightfieldData,btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges) +btHeightfieldTerrainShape::btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength, const void* heightfieldData, btScalar maxHeight, int upAxis, bool useFloatData, bool flipQuadEdges) { // legacy constructor: support only float or unsigned char, // and min height is zero @@ -45,27 +39,23 @@ btHeightfieldTerrainShape::btHeightfieldTerrainShape(int heightStickWidth, int h btScalar heightScale = maxHeight / 65535; initialize(heightStickWidth, heightStickLength, heightfieldData, - heightScale, minHeight, maxHeight, upAxis, hdt, - flipQuadEdges); + heightScale, minHeight, maxHeight, upAxis, hdt, + flipQuadEdges); } - - -void btHeightfieldTerrainShape::initialize -( -int heightStickWidth, int heightStickLength, const void* heightfieldData, -btScalar heightScale, btScalar minHeight, btScalar maxHeight, int upAxis, -PHY_ScalarType hdt, bool flipQuadEdges -) +void btHeightfieldTerrainShape::initialize( + int heightStickWidth, int heightStickLength, const void* heightfieldData, + btScalar heightScale, btScalar minHeight, btScalar maxHeight, int upAxis, + PHY_ScalarType hdt, bool flipQuadEdges) { // validation - btAssert(heightStickWidth > 1);// && "bad width"); - btAssert(heightStickLength > 1);// && "bad length"); - btAssert(heightfieldData);// && "null heightfield data"); + btAssert(heightStickWidth > 1); // && "bad width"); + btAssert(heightStickLength > 1); // && "bad length"); + btAssert(heightfieldData); // && "null heightfield data"); // btAssert(heightScale) -- do we care? Trust caller here - btAssert(minHeight <= maxHeight);// && "bad min/max height"); - btAssert(upAxis >= 0 && upAxis < 3);// && "bad upAxis--should be in range [0,2]"); - btAssert(hdt != PHY_UCHAR || hdt != PHY_FLOAT || hdt != PHY_SHORT);// && "Bad height data type enum"); + btAssert(minHeight <= maxHeight); // && "bad min/max height"); + btAssert(upAxis >= 0 && upAxis < 3); // && "bad upAxis--should be in range [0,2]"); + btAssert(hdt != PHY_UCHAR || hdt != PHY_FLOAT || hdt != PHY_SHORT); // && "Bad height data type enum"); // initialize member variables m_shapeType = TERRAIN_SHAPE_PROXYTYPE; @@ -73,8 +63,8 @@ PHY_ScalarType hdt, bool flipQuadEdges m_heightStickLength = heightStickLength; m_minHeight = minHeight; m_maxHeight = maxHeight; - m_width = (btScalar) (heightStickWidth - 1); - m_length = (btScalar) (heightStickLength - 1); + m_width = (btScalar)(heightStickWidth - 1); + m_length = (btScalar)(heightStickLength - 1); m_heightScale = heightScale; m_heightfieldDataUnknown = heightfieldData; m_heightDataType = hdt; @@ -87,28 +77,28 @@ PHY_ScalarType hdt, bool flipQuadEdges // determine min/max axis-aligned bounding box (aabb) values switch (m_upAxis) { - case 0: + case 0: { m_localAabbMin.setValue(m_minHeight, 0, 0); m_localAabbMax.setValue(m_maxHeight, m_width, m_length); break; } - case 1: + case 1: { m_localAabbMin.setValue(0, m_minHeight, 0); m_localAabbMax.setValue(m_width, m_maxHeight, m_length); break; }; - case 2: + case 2: { m_localAabbMin.setValue(0, 0, m_minHeight); m_localAabbMax.setValue(m_width, m_length, m_maxHeight); break; } - default: + default: { //need to get valid m_upAxis - btAssert(0);// && "Bad m_upAxis"); + btAssert(0); // && "Bad m_upAxis"); } } @@ -116,62 +106,57 @@ PHY_ScalarType hdt, bool flipQuadEdges m_localOrigin = btScalar(0.5) * (m_localAabbMin + m_localAabbMax); } - - btHeightfieldTerrainShape::~btHeightfieldTerrainShape() { } - - -void btHeightfieldTerrainShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +void btHeightfieldTerrainShape::getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const { - btVector3 halfExtents = (m_localAabbMax-m_localAabbMin)* m_localScaling * btScalar(0.5); + btVector3 halfExtents = (m_localAabbMax - m_localAabbMin) * m_localScaling * btScalar(0.5); btVector3 localOrigin(0, 0, 0); localOrigin[m_upAxis] = (m_minHeight + m_maxHeight) * btScalar(0.5); localOrigin *= m_localScaling; - btMatrix3x3 abs_b = t.getBasis().absolute(); + btMatrix3x3 abs_b = t.getBasis().absolute(); btVector3 center = t.getOrigin(); - btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); - extent += btVector3(getMargin(),getMargin(),getMargin()); + btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); + extent += btVector3(getMargin(), getMargin(), getMargin()); aabbMin = center - extent; aabbMax = center + extent; } - /// This returns the "raw" (user's initial) height, not the actual height. /// The actual height needs to be adjusted to be relative to the center /// of the heightfield's AABB. btScalar -btHeightfieldTerrainShape::getRawHeightFieldValue(int x,int y) const +btHeightfieldTerrainShape::getRawHeightFieldValue(int x, int y) const { btScalar val = 0.f; switch (m_heightDataType) { - case PHY_FLOAT: + case PHY_FLOAT: { - val = m_heightfieldDataFloat[(y*m_heightStickWidth)+x]; + val = m_heightfieldDataFloat[(y * m_heightStickWidth) + x]; break; } - case PHY_UCHAR: + case PHY_UCHAR: { - unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y*m_heightStickWidth)+x]; + unsigned char heightFieldValue = m_heightfieldDataUnsignedChar[(y * m_heightStickWidth) + x]; val = heightFieldValue * m_heightScale; break; } - case PHY_SHORT: + case PHY_SHORT: { short hfValue = m_heightfieldDataShort[(y * m_heightStickWidth) + x]; val = hfValue * m_heightScale; break; } - default: + default: { btAssert(!"Bad m_heightDataType"); } @@ -180,74 +165,63 @@ btHeightfieldTerrainShape::getRawHeightFieldValue(int x,int y) const return val; } - - - /// this returns the vertex in bullet-local coordinates -void btHeightfieldTerrainShape::getVertex(int x,int y,btVector3& vertex) const +void btHeightfieldTerrainShape::getVertex(int x, int y, btVector3& vertex) const { - btAssert(x>=0); - btAssert(y>=0); - btAssert(x= 0); + btAssert(y >= 0); + btAssert(x < m_heightStickWidth); + btAssert(y < m_heightStickLength); - btScalar height = getRawHeightFieldValue(x,y); + btScalar height = getRawHeightFieldValue(x, y); switch (m_upAxis) { - case 0: - { - vertex.setValue( - height - m_localOrigin.getX(), - (-m_width/btScalar(2.0)) + x, - (-m_length/btScalar(2.0) ) + y - ); - break; - } - case 1: + case 0: { vertex.setValue( - (-m_width/btScalar(2.0)) + x, - height - m_localOrigin.getY(), - (-m_length/btScalar(2.0)) + y - ); + height - m_localOrigin.getX(), + (-m_width / btScalar(2.0)) + x, + (-m_length / btScalar(2.0)) + y); + break; + } + case 1: + { + vertex.setValue( + (-m_width / btScalar(2.0)) + x, + height - m_localOrigin.getY(), + (-m_length / btScalar(2.0)) + y); break; }; - case 2: + case 2: { vertex.setValue( - (-m_width/btScalar(2.0)) + x, - (-m_length/btScalar(2.0)) + y, - height - m_localOrigin.getZ() - ); + (-m_width / btScalar(2.0)) + x, + (-m_length / btScalar(2.0)) + y, + height - m_localOrigin.getZ()); break; } - default: + default: { //need to get valid m_upAxis btAssert(0); } } - vertex*=m_localScaling; + vertex *= m_localScaling; } - - static inline int -getQuantized -( -btScalar x -) +getQuantized( + btScalar x) { - if (x < 0.0) { - return (int) (x - 0.5); + if (x < 0.0) + { + return (int)(x - 0.5); } - return (int) (x + 0.5); + return (int)(x + 0.5); } - - /// given input vector, return quantized version /** This routine is basically determining the gridpoint indices for a given @@ -257,7 +231,7 @@ btScalar x "with clamp" means that we restrict the point to be in the heightfield's axis-aligned bounding box. */ -void btHeightfieldTerrainShape::quantizeWithClamp(int* out, const btVector3& point,int /*isMax*/) const +void btHeightfieldTerrainShape::quantizeWithClamp(int* out, const btVector3& point, int /*isMax*/) const { btVector3 clampedPoint(point); clampedPoint.setMax(m_localAabbMin); @@ -266,11 +240,8 @@ void btHeightfieldTerrainShape::quantizeWithClamp(int* out, const btVector3& poi out[0] = getQuantized(clampedPoint.getX()); out[1] = getQuantized(clampedPoint.getY()); out[2] = getQuantized(clampedPoint.getZ()); - } - - /// process all triangles within the provided axis-aligned bounding box /** basic algorithm: @@ -278,128 +249,123 @@ void btHeightfieldTerrainShape::quantizeWithClamp(int* out, const btVector3& poi - convert input aabb to a range of heightfield grid points (quantize) - iterate over all triangles in that subset of the grid */ -void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const +void btHeightfieldTerrainShape::processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const { // scale down the input aabb's so they are in local (non-scaled) coordinates - btVector3 localAabbMin = aabbMin*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]); - btVector3 localAabbMax = aabbMax*btVector3(1.f/m_localScaling[0],1.f/m_localScaling[1],1.f/m_localScaling[2]); + btVector3 localAabbMin = aabbMin * btVector3(1.f / m_localScaling[0], 1.f / m_localScaling[1], 1.f / m_localScaling[2]); + btVector3 localAabbMax = aabbMax * btVector3(1.f / m_localScaling[0], 1.f / m_localScaling[1], 1.f / m_localScaling[2]); // account for local origin localAabbMin += m_localOrigin; localAabbMax += m_localOrigin; //quantize the aabbMin and aabbMax, and adjust the start/end ranges - int quantizedAabbMin[3]; - int quantizedAabbMax[3]; - quantizeWithClamp(quantizedAabbMin, localAabbMin,0); - quantizeWithClamp(quantizedAabbMax, localAabbMax,1); - + int quantizedAabbMin[3]; + int quantizedAabbMax[3]; + quantizeWithClamp(quantizedAabbMin, localAabbMin, 0); + quantizeWithClamp(quantizedAabbMax, localAabbMax, 1); + // expand the min/max quantized values // this is to catch the case where the input aabb falls between grid points! - for (int i = 0; i < 3; ++i) { + for (int i = 0; i < 3; ++i) + { quantizedAabbMin[i]--; quantizedAabbMax[i]++; - } + } - int startX=0; - int endX=m_heightStickWidth-1; - int startJ=0; - int endJ=m_heightStickLength-1; + int startX = 0; + int endX = m_heightStickWidth - 1; + int startJ = 0; + int endJ = m_heightStickLength - 1; switch (m_upAxis) { - case 0: + case 0: { - if (quantizedAabbMin[1]>startX) + if (quantizedAabbMin[1] > startX) startX = quantizedAabbMin[1]; - if (quantizedAabbMax[1]startJ) + if (quantizedAabbMin[2] > startJ) startJ = quantizedAabbMin[2]; - if (quantizedAabbMax[2]startX) + if (quantizedAabbMin[0] > startX) startX = quantizedAabbMin[0]; - if (quantizedAabbMax[0]startJ) + if (quantizedAabbMin[2] > startJ) startJ = quantizedAabbMin[2]; - if (quantizedAabbMax[2]startX) + if (quantizedAabbMin[0] > startX) startX = quantizedAabbMin[0]; - if (quantizedAabbMax[0]startJ) + if (quantizedAabbMin[1] > startJ) startJ = quantizedAabbMin[1]; - if (quantizedAabbMax[1]processTriangle(vertices,x,j); - //second triangle - // getVertex(x,j,vertices[0]);//already got this vertex before, thanks to Danny Chapman - getVertex(x+1,j+1,vertices[1]); - getVertex(x + 1, j, vertices[2]); - callback->processTriangle(vertices, x, j); - - } else + //first triangle + getVertex(x, j, vertices[0]); + getVertex(x, j + 1, vertices[1]); + getVertex(x + 1, j + 1, vertices[2]); + callback->processTriangle(vertices, x, j); + //second triangle + // getVertex(x,j,vertices[0]);//already got this vertex before, thanks to Danny Chapman + getVertex(x + 1, j + 1, vertices[1]); + getVertex(x + 1, j, vertices[2]); + callback->processTriangle(vertices, x, j); + } + else { - //first triangle - getVertex(x,j,vertices[0]); - getVertex(x,j+1,vertices[1]); - getVertex(x+1,j,vertices[2]); - callback->processTriangle(vertices,x,j); - //second triangle - getVertex(x+1,j,vertices[0]); - //getVertex(x,j+1,vertices[1]); - getVertex(x+1,j+1,vertices[2]); - callback->processTriangle(vertices,x,j); + //first triangle + getVertex(x, j, vertices[0]); + getVertex(x, j + 1, vertices[1]); + getVertex(x + 1, j, vertices[2]); + callback->processTriangle(vertices, x, j); + //second triangle + getVertex(x + 1, j, vertices[0]); + //getVertex(x,j+1,vertices[1]); + getVertex(x + 1, j + 1, vertices[2]); + callback->processTriangle(vertices, x, j); } } } - - - } -void btHeightfieldTerrainShape::calculateLocalInertia(btScalar ,btVector3& inertia) const +void btHeightfieldTerrainShape::calculateLocalInertia(btScalar, btVector3& inertia) const { //moving concave objects not supported - - inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); + + inertia.setValue(btScalar(0.), btScalar(0.), btScalar(0.)); } -void btHeightfieldTerrainShape::setLocalScaling(const btVector3& scaling) +void btHeightfieldTerrainShape::setLocalScaling(const btVector3& scaling) { m_localScaling = scaling; } diff --git a/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h b/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h index 4a7a4a4bd..8a50a57e3 100644 --- a/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h +++ b/src/BulletCollision/CollisionShapes/btHeightfieldTerrainShape.h @@ -68,43 +68,41 @@ subject to the following restrictions: For usage and testing see the TerrainDemo. */ -ATTRIBUTE_ALIGNED16(class) btHeightfieldTerrainShape : public btConcaveShape +ATTRIBUTE_ALIGNED16(class) +btHeightfieldTerrainShape : public btConcaveShape { protected: - btVector3 m_localAabbMin; - btVector3 m_localAabbMax; - btVector3 m_localOrigin; + btVector3 m_localAabbMin; + btVector3 m_localAabbMax; + btVector3 m_localOrigin; ///terrain data - int m_heightStickWidth; + int m_heightStickWidth; int m_heightStickLength; - btScalar m_minHeight; - btScalar m_maxHeight; + btScalar m_minHeight; + btScalar m_maxHeight; btScalar m_width; btScalar m_length; btScalar m_heightScale; - union - { - const unsigned char* m_heightfieldDataUnsignedChar; - const short* m_heightfieldDataShort; - const btScalar* m_heightfieldDataFloat; - const void* m_heightfieldDataUnknown; + union { + const unsigned char* m_heightfieldDataUnsignedChar; + const short* m_heightfieldDataShort; + const btScalar* m_heightfieldDataFloat; + const void* m_heightfieldDataUnknown; }; - PHY_ScalarType m_heightDataType; - bool m_flipQuadEdges; - bool m_useDiamondSubdivision; + PHY_ScalarType m_heightDataType; + bool m_flipQuadEdges; + bool m_useDiamondSubdivision; bool m_useZigzagSubdivision; - int m_upAxis; - - btVector3 m_localScaling; - - virtual btScalar getRawHeightFieldValue(int x,int y) const; - void quantizeWithClamp(int* out, const btVector3& point,int isMax) const; - void getVertex(int x,int y,btVector3& vertex) const; + int m_upAxis; + btVector3 m_localScaling; + virtual btScalar getRawHeightFieldValue(int x, int y) const; + void quantizeWithClamp(int* out, const btVector3& point, int isMax) const; + void getVertex(int x, int y, btVector3& vertex) const; /// protected initialization /** @@ -112,25 +110,24 @@ protected: backwards-compatible without a lot of copy/paste. */ void initialize(int heightStickWidth, int heightStickLength, - const void* heightfieldData, btScalar heightScale, - btScalar minHeight, btScalar maxHeight, int upAxis, - PHY_ScalarType heightDataType, bool flipQuadEdges); + const void* heightfieldData, btScalar heightScale, + btScalar minHeight, btScalar maxHeight, int upAxis, + PHY_ScalarType heightDataType, bool flipQuadEdges); public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - + /// preferred constructor /** This constructor supports a range of heightfield data types, and allows for a non-zero minimum height value. heightScale is needed for any integer-based heightfield data types. */ - btHeightfieldTerrainShape(int heightStickWidth,int heightStickLength, - const void* heightfieldData, btScalar heightScale, - btScalar minHeight, btScalar maxHeight, - int upAxis, PHY_ScalarType heightDataType, - bool flipQuadEdges); + btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength, + const void* heightfieldData, btScalar heightScale, + btScalar minHeight, btScalar maxHeight, + int upAxis, PHY_ScalarType heightDataType, + bool flipQuadEdges); /// legacy constructor /** @@ -139,29 +136,27 @@ public: compatibility reasons, heightScale is calculated as maxHeight / 65535 (and is only used when useFloatData = false). */ - btHeightfieldTerrainShape(int heightStickWidth,int heightStickLength,const void* heightfieldData, btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges); + btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength, const void* heightfieldData, btScalar maxHeight, int upAxis, bool useFloatData, bool flipQuadEdges); virtual ~btHeightfieldTerrainShape(); + void setUseDiamondSubdivision(bool useDiamondSubdivision = true) { m_useDiamondSubdivision = useDiamondSubdivision; } - void setUseDiamondSubdivision(bool useDiamondSubdivision=true) { m_useDiamondSubdivision = useDiamondSubdivision;} + ///could help compatibility with Ogre heightfields. See https://code.google.com/p/bullet/issues/detail?id=625 + void setUseZigzagSubdivision(bool useZigzagSubdivision = true) { m_useZigzagSubdivision = useZigzagSubdivision; } - ///could help compatibility with Ogre heightfields. See https://code.google.com/p/bullet/issues/detail?id=625 - void setUseZigzagSubdivision(bool useZigzagSubdivision=true) { m_useZigzagSubdivision = useZigzagSubdivision;} + virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const; - virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + virtual void processAllTriangles(btTriangleCallback * callback, const btVector3& aabbMin, const btVector3& aabbMax) const; - virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + virtual void calculateLocalInertia(btScalar mass, btVector3 & inertia) const; - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + virtual void setLocalScaling(const btVector3& scaling); - virtual void setLocalScaling(const btVector3& scaling); - virtual const btVector3& getLocalScaling() const; - - //debugging - virtual const char* getName()const {return "HEIGHTFIELD";} + //debugging + virtual const char* getName() const { return "HEIGHTFIELD"; } }; -#endif //BT_HEIGHTFIELD_TERRAIN_SHAPE_H +#endif //BT_HEIGHTFIELD_TERRAIN_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btMaterial.h b/src/BulletCollision/CollisionShapes/btMaterial.h index 866f9b4da..c9a436bf2 100644 --- a/src/BulletCollision/CollisionShapes/btMaterial.h +++ b/src/BulletCollision/CollisionShapes/btMaterial.h @@ -21,15 +21,18 @@ subject to the following restrictions: // Material class to be used by btMultimaterialTriangleMeshShape to store triangle properties class btMaterial { - // public members so that materials can change due to world events + // public members so that materials can change due to world events public: - btScalar m_friction; - btScalar m_restitution; - int pad[2]; + btScalar m_friction; + btScalar m_restitution; + int pad[2]; - btMaterial(){} - btMaterial(btScalar fric, btScalar rest) { m_friction = fric; m_restitution = rest; } + btMaterial() {} + btMaterial(btScalar fric, btScalar rest) + { + m_friction = fric; + m_restitution = rest; + } }; -#endif // BT_MATERIAL_H - +#endif // BT_MATERIAL_H diff --git a/src/BulletCollision/CollisionShapes/btMiniSDF.cpp b/src/BulletCollision/CollisionShapes/btMiniSDF.cpp index afe45e1d2..13c0a343f 100644 --- a/src/BulletCollision/CollisionShapes/btMiniSDF.cpp +++ b/src/BulletCollision/CollisionShapes/btMiniSDF.cpp @@ -10,31 +10,31 @@ // #include -#include //memcpy +#include //memcpy struct btSdfDataStream { const char* m_data; int m_size; - + int m_currentOffset; - + btSdfDataStream(const char* data, int size) - :m_data(data), - m_size(size), - m_currentOffset(0) + : m_data(data), + m_size(size), + m_currentOffset(0) { - } - template bool read(T& val) + template + bool read(T& val) { int bytes = sizeof(T); - if (m_currentOffset+bytes<=m_size) + if (m_currentOffset + bytes <= m_size) { char* dest = (char*)&val; - memcpy(dest,&m_data[m_currentOffset],bytes); - m_currentOffset+=bytes; + memcpy(dest, &m_data[m_currentOffset], bytes); + m_currentOffset += bytes; return true; } btAssert(0); @@ -42,137 +42,133 @@ struct btSdfDataStream } }; - bool btMiniSDF::load(const char* data, int size) { - int fileSize = -1; + int fileSize = -1; - btSdfDataStream ds(data,size); - { - double buf[6]; - ds.read(buf); - m_domain.m_min[0] = buf[0]; - m_domain.m_min[1] = buf[1]; - m_domain.m_min[2] = buf[2]; - m_domain.m_min[3] = 0; - m_domain.m_max[0] = buf[3]; - m_domain.m_max[1] = buf[4]; - m_domain.m_max[2] = buf[5]; - m_domain.m_max[3] = 0; - } - { - unsigned int buf2[3]; - ds.read(buf2); - m_resolution[0] = buf2[0]; - m_resolution[1] = buf2[1]; - m_resolution[2] = buf2[2]; - } - { - double buf[3]; - ds.read(buf); - m_cell_size[0] = buf[0]; - m_cell_size[1] = buf[1]; - m_cell_size[2] = buf[2]; - } - { - double buf[3]; - ds.read(buf); - m_inv_cell_size[0] = buf[0]; - m_inv_cell_size[1] = buf[1]; - m_inv_cell_size[2] = buf[2]; - } - { - unsigned long long int cells; - ds.read(cells); - m_n_cells = cells; - } - { - unsigned long long int fields; - ds.read(fields); - m_n_fields = fields; - } + btSdfDataStream ds(data, size); + { + double buf[6]; + ds.read(buf); + m_domain.m_min[0] = buf[0]; + m_domain.m_min[1] = buf[1]; + m_domain.m_min[2] = buf[2]; + m_domain.m_min[3] = 0; + m_domain.m_max[0] = buf[3]; + m_domain.m_max[1] = buf[4]; + m_domain.m_max[2] = buf[5]; + m_domain.m_max[3] = 0; + } + { + unsigned int buf2[3]; + ds.read(buf2); + m_resolution[0] = buf2[0]; + m_resolution[1] = buf2[1]; + m_resolution[2] = buf2[2]; + } + { + double buf[3]; + ds.read(buf); + m_cell_size[0] = buf[0]; + m_cell_size[1] = buf[1]; + m_cell_size[2] = buf[2]; + } + { + double buf[3]; + ds.read(buf); + m_inv_cell_size[0] = buf[0]; + m_inv_cell_size[1] = buf[1]; + m_inv_cell_size[2] = buf[2]; + } + { + unsigned long long int cells; + ds.read(cells); + m_n_cells = cells; + } + { + unsigned long long int fields; + ds.read(fields); + m_n_fields = fields; + } - - unsigned long long int nodes0; - std::size_t n_nodes0; - ds.read(nodes0); - n_nodes0 = nodes0; - if (n_nodes0 > 1024 * 1024 * 1024) - { - return m_isValid; - } - m_nodes.resize(n_nodes0); - for (unsigned int i=0;i& nodes = m_nodes[i]; - nodes.resize(n_nodes1); - for ( int j=0;j& cells = m_cells[i]; - ds.read(n_cells1); - cells.resize(n_cells1); - for (int j=0;j& cell_maps = m_cell_map[i]; - ds.read(n_cell_maps1); - cell_maps.resize(n_cell_maps1); - for (int j=0;j 1024 * 1024 * 1024) + { return m_isValid; + } + m_nodes.resize(n_nodes0); + for (unsigned int i = 0; i < n_nodes0; i++) + { + unsigned long long int n_nodes1; + ds.read(n_nodes1); + btAlignedObjectArray& nodes = m_nodes[i]; + nodes.resize(n_nodes1); + for (int j = 0; j < nodes.size(); j++) + { + double& node = nodes[j]; + ds.read(node); + } + } + + unsigned long long int n_cells0; + ds.read(n_cells0); + m_cells.resize(n_cells0); + for (int i = 0; i < n_cells0; i++) + { + unsigned long long int n_cells1; + btAlignedObjectArray& cells = m_cells[i]; + ds.read(n_cells1); + cells.resize(n_cells1); + for (int j = 0; j < n_cells1; j++) + { + btCell32& cell = cells[j]; + ds.read(cell); + } + } + + { + unsigned long long int n_cell_maps0; + ds.read(n_cell_maps0); + + m_cell_map.resize(n_cell_maps0); + for (int i = 0; i < n_cell_maps0; i++) + { + unsigned long long int n_cell_maps1; + btAlignedObjectArray& cell_maps = m_cell_map[i]; + ds.read(n_cell_maps1); + cell_maps.resize(n_cell_maps1); + for (int j = 0; j < n_cell_maps1; j++) + { + unsigned int& cell_map = cell_maps[j]; + ds.read(cell_map); + } + } + } + + m_isValid = (ds.m_currentOffset == ds.m_size); + return m_isValid; } - -unsigned int btMiniSDF::multiToSingleIndex(btMultiIndex const & ijk) const +unsigned int btMiniSDF::multiToSingleIndex(btMultiIndex const& ijk) const { return m_resolution[1] * m_resolution[0] * ijk.ijk[2] + m_resolution[0] * ijk.ijk[1] + ijk.ijk[0]; } - + btAlignedBox3d btMiniSDF::subdomain(btMultiIndex const& ijk) const { btAssert(m_isValid); btVector3 tmp; - tmp.m_floats[0] = m_cell_size[0]*(double)ijk.ijk[0]; - tmp.m_floats[1] = m_cell_size[1]*(double)ijk.ijk[1]; - tmp.m_floats[2] = m_cell_size[2]*(double)ijk.ijk[2]; - + tmp.m_floats[0] = m_cell_size[0] * (double)ijk.ijk[0]; + tmp.m_floats[1] = m_cell_size[1] * (double)ijk.ijk[1]; + tmp.m_floats[2] = m_cell_size[2] * (double)ijk.ijk[2]; btVector3 origin = m_domain.min() + tmp; - btAlignedBox3d box = btAlignedBox3d (origin, origin + m_cell_size); + btAlignedBox3d box = btAlignedBox3d(origin, origin + m_cell_size); return box; } @@ -181,8 +177,8 @@ btMiniSDF::singleToMultiIndex(unsigned int l) const { btAssert(m_isValid); unsigned int n01 = m_resolution[0] * m_resolution[1]; - unsigned int k = l / n01; - unsigned int temp = l % n01; + unsigned int k = l / n01; + unsigned int temp = l % n01; unsigned int j = temp / m_resolution[0]; unsigned int i = temp % m_resolution[0]; btMultiIndex mi; @@ -199,59 +195,57 @@ btMiniSDF::subdomain(unsigned int l) const return subdomain(singleToMultiIndex(l)); } - btShapeMatrix btMiniSDF::shape_function_(btVector3 const& xi, btShapeGradients* gradient) const { btAssert(m_isValid); btShapeMatrix res; - + btScalar x = xi[0]; btScalar y = xi[1]; btScalar z = xi[2]; - btScalar x2 = x*x; - btScalar y2 = y*y; - btScalar z2 = z*z; + btScalar x2 = x * x; + btScalar y2 = y * y; + btScalar z2 = z * z; - btScalar _1mx = 1.0 - x; - btScalar _1my = 1.0 - y; - btScalar _1mz = 1.0 - z; + btScalar _1mx = 1.0 - x; + btScalar _1my = 1.0 - y; + btScalar _1mz = 1.0 - z; - btScalar _1px = 1.0 + x; - btScalar _1py = 1.0 + y; - btScalar _1pz = 1.0 + z; + btScalar _1px = 1.0 + x; + btScalar _1py = 1.0 + y; + btScalar _1pz = 1.0 + z; - btScalar _1m3x = 1.0 - 3.0 * x; - btScalar _1m3y = 1.0 - 3.0 * y; - btScalar _1m3z = 1.0 - 3.0 * z; + btScalar _1m3x = 1.0 - 3.0 * x; + btScalar _1m3y = 1.0 - 3.0 * y; + btScalar _1m3z = 1.0 - 3.0 * z; - btScalar _1p3x = 1.0 + 3.0 * x; - btScalar _1p3y = 1.0 + 3.0 * y; - btScalar _1p3z = 1.0 + 3.0 * z; + btScalar _1p3x = 1.0 + 3.0 * x; + btScalar _1p3y = 1.0 + 3.0 * y; + btScalar _1p3z = 1.0 + 3.0 * z; - btScalar _1mxt1my = _1mx * _1my; - btScalar _1mxt1py = _1mx * _1py; - btScalar _1pxt1my = _1px * _1my; - btScalar _1pxt1py = _1px * _1py; + btScalar _1mxt1my = _1mx * _1my; + btScalar _1mxt1py = _1mx * _1py; + btScalar _1pxt1my = _1px * _1my; + btScalar _1pxt1py = _1px * _1py; - btScalar _1mxt1mz = _1mx * _1mz; - btScalar _1mxt1pz = _1mx * _1pz; - btScalar _1pxt1mz = _1px * _1mz; - btScalar _1pxt1pz = _1px * _1pz; + btScalar _1mxt1mz = _1mx * _1mz; + btScalar _1mxt1pz = _1mx * _1pz; + btScalar _1pxt1mz = _1px * _1mz; + btScalar _1pxt1pz = _1px * _1pz; - btScalar _1myt1mz = _1my * _1mz; - btScalar _1myt1pz = _1my * _1pz; - btScalar _1pyt1mz = _1py * _1mz; - btScalar _1pyt1pz = _1py * _1pz; - - btScalar _1mx2 = 1.0 - x2; - btScalar _1my2 = 1.0 - y2; - btScalar _1mz2 = 1.0 - z2; + btScalar _1myt1mz = _1my * _1mz; + btScalar _1myt1pz = _1my * _1pz; + btScalar _1pyt1mz = _1py * _1mz; + btScalar _1pyt1pz = _1py * _1pz; + btScalar _1mx2 = 1.0 - x2; + btScalar _1my2 = 1.0 - y2; + btScalar _1mz2 = 1.0 - z2; // Corner nodes. - btScalar fac = 1.0 / 64.0 * (9.0 * (x2 + y2 + z2) - 19.0); + btScalar fac = 1.0 / 64.0 * (9.0 * (x2 + y2 + z2) - 19.0); res[0] = fac * _1mxt1my * _1mz; res[1] = fac * _1pxt1my * _1mz; res[2] = fac * _1mxt1py * _1mz; @@ -264,10 +258,10 @@ btMiniSDF::shape_function_(btVector3 const& xi, btShapeGradients* gradient) cons // Edge nodes. fac = 9.0 / 64.0 * _1mx2; - btScalar fact1m3x = fac * _1m3x; - btScalar fact1p3x = fac * _1p3x; - res[ 8] = fact1m3x * _1myt1mz; - res[ 9] = fact1p3x * _1myt1mz; + btScalar fact1m3x = fac * _1m3x; + btScalar fact1p3x = fac * _1p3x; + res[8] = fact1m3x * _1myt1mz; + res[9] = fact1p3x * _1myt1mz; res[10] = fact1m3x * _1myt1pz; res[11] = fact1p3x * _1myt1pz; res[12] = fact1m3x * _1pyt1mz; @@ -276,8 +270,8 @@ btMiniSDF::shape_function_(btVector3 const& xi, btShapeGradients* gradient) cons res[15] = fact1p3x * _1pyt1pz; fac = 9.0 / 64.0 * _1my2; - btScalar fact1m3y = fac * _1m3y; - btScalar fact1p3y = fac * _1p3y; + btScalar fact1m3y = fac * _1m3y; + btScalar fact1p3y = fac * _1p3y; res[16] = fact1m3y * _1mxt1mz; res[17] = fact1p3y * _1mxt1mz; res[18] = fact1m3y * _1pxt1mz; @@ -288,8 +282,8 @@ btMiniSDF::shape_function_(btVector3 const& xi, btShapeGradients* gradient) cons res[23] = fact1p3y * _1pxt1pz; fac = 9.0 / 64.0 * _1mz2; - btScalar fact1m3z = fac * _1m3z; - btScalar fact1p3z = fac * _1p3z; + btScalar fact1m3z = fac * _1m3z; + btScalar fact1p3z = fac * _1p3z; res[24] = fact1m3z * _1mxt1my; res[25] = fact1p3z * _1mxt1my; res[26] = fact1m3z * _1mxt1py; @@ -309,7 +303,7 @@ btMiniSDF::shape_function_(btVector3 const& xi, btShapeGradients* gradient) cons btScalar _18x = 18.0 * x; btScalar _18y = 18.0 * y; btScalar _18z = 18.0 * z; - + btScalar _3m9x2 = 3.0 - 9.0 * x2; btScalar _3m9y2 = 3.0 - 9.0 * y2; btScalar _3m9z2 = 3.0 - 9.0 * z2; @@ -325,132 +319,128 @@ btMiniSDF::shape_function_(btVector3 const& xi, btShapeGradients* gradient) cons btScalar _18zm9tx2py2p3z2m19 = _18z - _9tx2py2p3z2m19; btScalar _18zp9tx2py2p3z2m19 = _18z + _9tx2py2p3z2m19; - dN(0,0) =_18xm9t3x2py2pz2m19 * _1myt1mz; - dN(0,1) =_1mxt1mz * _18ym9tx2p3y2pz2m19; - dN(0,2) =_1mxt1my * _18zm9tx2py2p3z2m19; - dN(1,0) =_18xp9t3x2py2pz2m19 * _1myt1mz; - dN(1,1) =_1pxt1mz * _18ym9tx2p3y2pz2m19; - dN(1,2) =_1pxt1my * _18zm9tx2py2p3z2m19; - dN(2,0) =_18xm9t3x2py2pz2m19 * _1pyt1mz; - dN(2,1) =_1mxt1mz * _18yp9tx2p3y2pz2m19; - dN(2,2) =_1mxt1py * _18zm9tx2py2p3z2m19; - dN(3,0) =_18xp9t3x2py2pz2m19 * _1pyt1mz; - dN(3,1) =_1pxt1mz * _18yp9tx2p3y2pz2m19; - dN(3,2) =_1pxt1py * _18zm9tx2py2p3z2m19; - dN(4,0) =_18xm9t3x2py2pz2m19 * _1myt1pz; - dN(4,1) =_1mxt1pz * _18ym9tx2p3y2pz2m19; - dN(4,2) =_1mxt1my * _18zp9tx2py2p3z2m19; - dN(5,0) =_18xp9t3x2py2pz2m19 * _1myt1pz; - dN(5,1) =_1pxt1pz * _18ym9tx2p3y2pz2m19; - dN(5,2) =_1pxt1my * _18zp9tx2py2p3z2m19; - dN(6,0) =_18xm9t3x2py2pz2m19 * _1pyt1pz; - dN(6,1) =_1mxt1pz * _18yp9tx2p3y2pz2m19; - dN(6,2) =_1mxt1py * _18zp9tx2py2p3z2m19; - dN(7,0) =_18xp9t3x2py2pz2m19 * _1pyt1pz; - dN(7,1) =_1pxt1pz * _18yp9tx2p3y2pz2m19; - dN(7,2) =_1pxt1py * _18zp9tx2py2p3z2m19; + dN(0, 0) = _18xm9t3x2py2pz2m19 * _1myt1mz; + dN(0, 1) = _1mxt1mz * _18ym9tx2p3y2pz2m19; + dN(0, 2) = _1mxt1my * _18zm9tx2py2p3z2m19; + dN(1, 0) = _18xp9t3x2py2pz2m19 * _1myt1mz; + dN(1, 1) = _1pxt1mz * _18ym9tx2p3y2pz2m19; + dN(1, 2) = _1pxt1my * _18zm9tx2py2p3z2m19; + dN(2, 0) = _18xm9t3x2py2pz2m19 * _1pyt1mz; + dN(2, 1) = _1mxt1mz * _18yp9tx2p3y2pz2m19; + dN(2, 2) = _1mxt1py * _18zm9tx2py2p3z2m19; + dN(3, 0) = _18xp9t3x2py2pz2m19 * _1pyt1mz; + dN(3, 1) = _1pxt1mz * _18yp9tx2p3y2pz2m19; + dN(3, 2) = _1pxt1py * _18zm9tx2py2p3z2m19; + dN(4, 0) = _18xm9t3x2py2pz2m19 * _1myt1pz; + dN(4, 1) = _1mxt1pz * _18ym9tx2p3y2pz2m19; + dN(4, 2) = _1mxt1my * _18zp9tx2py2p3z2m19; + dN(5, 0) = _18xp9t3x2py2pz2m19 * _1myt1pz; + dN(5, 1) = _1pxt1pz * _18ym9tx2p3y2pz2m19; + dN(5, 2) = _1pxt1my * _18zp9tx2py2p3z2m19; + dN(6, 0) = _18xm9t3x2py2pz2m19 * _1pyt1pz; + dN(6, 1) = _1mxt1pz * _18yp9tx2p3y2pz2m19; + dN(6, 2) = _1mxt1py * _18zp9tx2py2p3z2m19; + dN(7, 0) = _18xp9t3x2py2pz2m19 * _1pyt1pz; + dN(7, 1) = _1pxt1pz * _18yp9tx2p3y2pz2m19; + dN(7, 2) = _1pxt1py * _18zp9tx2py2p3z2m19; dN.topRowsDivide(8, 64.0); btScalar _m3m9x2m2x = -_3m9x2 - _2x; - btScalar _p3m9x2m2x = _3m9x2 - _2x; + btScalar _p3m9x2m2x = _3m9x2 - _2x; btScalar _1mx2t1m3x = _1mx2 * _1m3x; btScalar _1mx2t1p3x = _1mx2 * _1p3x; - dN( 8,0) = _m3m9x2m2x * _1myt1mz, - dN( 8,1) = -_1mx2t1m3x * _1mz, - dN( 8,2) = -_1mx2t1m3x * _1my; - dN( 9,0) = _p3m9x2m2x * _1myt1mz, - dN( 9,1) = -_1mx2t1p3x * _1mz, - dN( 9,2) = -_1mx2t1p3x * _1my; - dN(10,0) = _m3m9x2m2x * _1myt1pz, - dN(10,1) = -_1mx2t1m3x * _1pz, - dN(10,2) = _1mx2t1m3x * _1my; - dN(11,0) = _p3m9x2m2x * _1myt1pz, - dN(11,1) = -_1mx2t1p3x * _1pz, - dN(11,2) = _1mx2t1p3x * _1my; - dN(12,0) = _m3m9x2m2x * _1pyt1mz, - dN(12,1) = _1mx2t1m3x * _1mz, - dN(12,2) = -_1mx2t1m3x * _1py; - dN(13,0) = _p3m9x2m2x * _1pyt1mz, - dN(13,1) = _1mx2t1p3x * _1mz, - dN(13,2) = -_1mx2t1p3x * _1py; - dN(14,0) = _m3m9x2m2x * _1pyt1pz, - dN(14,1) = _1mx2t1m3x * _1pz, - dN(14,2) = _1mx2t1m3x * _1py; - dN(15,0) = _p3m9x2m2x * _1pyt1pz, - dN(15,1) = _1mx2t1p3x * _1pz, - dN(15,2) = _1mx2t1p3x * _1py; + dN(8, 0) = _m3m9x2m2x * _1myt1mz, + dN(8, 1) = -_1mx2t1m3x * _1mz, + dN(8, 2) = -_1mx2t1m3x * _1my; + dN(9, 0) = _p3m9x2m2x * _1myt1mz, + dN(9, 1) = -_1mx2t1p3x * _1mz, + dN(9, 2) = -_1mx2t1p3x * _1my; + dN(10, 0) = _m3m9x2m2x * _1myt1pz, + dN(10, 1) = -_1mx2t1m3x * _1pz, + dN(10, 2) = _1mx2t1m3x * _1my; + dN(11, 0) = _p3m9x2m2x * _1myt1pz, + dN(11, 1) = -_1mx2t1p3x * _1pz, + dN(11, 2) = _1mx2t1p3x * _1my; + dN(12, 0) = _m3m9x2m2x * _1pyt1mz, + dN(12, 1) = _1mx2t1m3x * _1mz, + dN(12, 2) = -_1mx2t1m3x * _1py; + dN(13, 0) = _p3m9x2m2x * _1pyt1mz, + dN(13, 1) = _1mx2t1p3x * _1mz, + dN(13, 2) = -_1mx2t1p3x * _1py; + dN(14, 0) = _m3m9x2m2x * _1pyt1pz, + dN(14, 1) = _1mx2t1m3x * _1pz, + dN(14, 2) = _1mx2t1m3x * _1py; + dN(15, 0) = _p3m9x2m2x * _1pyt1pz, + dN(15, 1) = _1mx2t1p3x * _1pz, + dN(15, 2) = _1mx2t1p3x * _1py; btScalar _m3m9y2m2y = -_3m9y2 - _2y; - btScalar _p3m9y2m2y = _3m9y2 - _2y; + btScalar _p3m9y2m2y = _3m9y2 - _2y; btScalar _1my2t1m3y = _1my2 * _1m3y; btScalar _1my2t1p3y = _1my2 * _1p3y; - dN(16,0) = -_1my2t1m3y * _1mz, - dN(16,1) = _m3m9y2m2y * _1mxt1mz, - dN(16,2) = -_1my2t1m3y * _1mx; - dN(17,0) = -_1my2t1p3y * _1mz, - dN(17,1) = _p3m9y2m2y * _1mxt1mz, - dN(17,2) = -_1my2t1p3y * _1mx; - dN(18,0) = _1my2t1m3y * _1mz, - dN(18,1) = _m3m9y2m2y * _1pxt1mz, - dN(18,2) = -_1my2t1m3y * _1px; - dN(19,0) = _1my2t1p3y * _1mz, - dN(19,1) = _p3m9y2m2y * _1pxt1mz, - dN(19,2) = -_1my2t1p3y * _1px; - dN(20,0) = -_1my2t1m3y * _1pz, - dN(20,1) = _m3m9y2m2y * _1mxt1pz, - dN(20,2) = _1my2t1m3y * _1mx; - dN(21,0) = -_1my2t1p3y * _1pz, - dN(21,1) = _p3m9y2m2y * _1mxt1pz, - dN(21,2) = _1my2t1p3y * _1mx; - dN(22,0) = _1my2t1m3y * _1pz, - dN(22,1) = _m3m9y2m2y * _1pxt1pz, - dN(22,2) = _1my2t1m3y * _1px; - dN(23,0) = _1my2t1p3y * _1pz, - dN(23,1) = _p3m9y2m2y * _1pxt1pz, - dN(23,2) = _1my2t1p3y * _1px; - + dN(16, 0) = -_1my2t1m3y * _1mz, + dN(16, 1) = _m3m9y2m2y * _1mxt1mz, + dN(16, 2) = -_1my2t1m3y * _1mx; + dN(17, 0) = -_1my2t1p3y * _1mz, + dN(17, 1) = _p3m9y2m2y * _1mxt1mz, + dN(17, 2) = -_1my2t1p3y * _1mx; + dN(18, 0) = _1my2t1m3y * _1mz, + dN(18, 1) = _m3m9y2m2y * _1pxt1mz, + dN(18, 2) = -_1my2t1m3y * _1px; + dN(19, 0) = _1my2t1p3y * _1mz, + dN(19, 1) = _p3m9y2m2y * _1pxt1mz, + dN(19, 2) = -_1my2t1p3y * _1px; + dN(20, 0) = -_1my2t1m3y * _1pz, + dN(20, 1) = _m3m9y2m2y * _1mxt1pz, + dN(20, 2) = _1my2t1m3y * _1mx; + dN(21, 0) = -_1my2t1p3y * _1pz, + dN(21, 1) = _p3m9y2m2y * _1mxt1pz, + dN(21, 2) = _1my2t1p3y * _1mx; + dN(22, 0) = _1my2t1m3y * _1pz, + dN(22, 1) = _m3m9y2m2y * _1pxt1pz, + dN(22, 2) = _1my2t1m3y * _1px; + dN(23, 0) = _1my2t1p3y * _1pz, + dN(23, 1) = _p3m9y2m2y * _1pxt1pz, + dN(23, 2) = _1my2t1p3y * _1px; btScalar _m3m9z2m2z = -_3m9z2 - _2z; - btScalar _p3m9z2m2z = _3m9z2 - _2z; + btScalar _p3m9z2m2z = _3m9z2 - _2z; btScalar _1mz2t1m3z = _1mz2 * _1m3z; btScalar _1mz2t1p3z = _1mz2 * _1p3z; - dN(24,0) = -_1mz2t1m3z * _1my, - dN(24,1) = -_1mz2t1m3z * _1mx, - dN(24,2) = _m3m9z2m2z * _1mxt1my; - dN(25,0) = -_1mz2t1p3z * _1my, - dN(25,1) = -_1mz2t1p3z * _1mx, - dN(25,2) = _p3m9z2m2z * _1mxt1my; - dN(26,0) = -_1mz2t1m3z * _1py, - dN(26,1) = _1mz2t1m3z * _1mx, - dN(26,2) = _m3m9z2m2z * _1mxt1py; - dN(27,0) = -_1mz2t1p3z * _1py, - dN(27,1) = _1mz2t1p3z * _1mx, - dN(27,2) = _p3m9z2m2z * _1mxt1py; - dN(28,0) = _1mz2t1m3z * _1my, - dN(28,1) = -_1mz2t1m3z * _1px, - dN(28,2) = _m3m9z2m2z * _1pxt1my; - dN(29,0) = _1mz2t1p3z * _1my, - dN(29,1) = -_1mz2t1p3z * _1px, - dN(29,2) = _p3m9z2m2z * _1pxt1my; - dN(30,0) = _1mz2t1m3z * _1py, - dN(30,1) = _1mz2t1m3z * _1px, - dN(30,2) = _m3m9z2m2z * _1pxt1py; - dN(31,0) = _1mz2t1p3z * _1py, - dN(31,1) = _1mz2t1p3z * _1px, - dN(31,2) = _p3m9z2m2z * _1pxt1py; + dN(24, 0) = -_1mz2t1m3z * _1my, + dN(24, 1) = -_1mz2t1m3z * _1mx, + dN(24, 2) = _m3m9z2m2z * _1mxt1my; + dN(25, 0) = -_1mz2t1p3z * _1my, + dN(25, 1) = -_1mz2t1p3z * _1mx, + dN(25, 2) = _p3m9z2m2z * _1mxt1my; + dN(26, 0) = -_1mz2t1m3z * _1py, + dN(26, 1) = _1mz2t1m3z * _1mx, + dN(26, 2) = _m3m9z2m2z * _1mxt1py; + dN(27, 0) = -_1mz2t1p3z * _1py, + dN(27, 1) = _1mz2t1p3z * _1mx, + dN(27, 2) = _p3m9z2m2z * _1mxt1py; + dN(28, 0) = _1mz2t1m3z * _1my, + dN(28, 1) = -_1mz2t1m3z * _1px, + dN(28, 2) = _m3m9z2m2z * _1pxt1my; + dN(29, 0) = _1mz2t1p3z * _1my, + dN(29, 1) = -_1mz2t1p3z * _1px, + dN(29, 2) = _p3m9z2m2z * _1pxt1my; + dN(30, 0) = _1mz2t1m3z * _1py, + dN(30, 1) = _1mz2t1m3z * _1px, + dN(30, 2) = _m3m9z2m2z * _1pxt1py; + dN(31, 0) = _1mz2t1p3z * _1py, + dN(31, 1) = _1mz2t1p3z * _1px, + dN(31, 2) = _p3m9z2m2z * _1pxt1py; dN.bottomRowsMul(32u - 8u, 9.0 / 64.0); - } return res; } - - bool btMiniSDF::interpolate(unsigned int field_id, double& dist, btVector3 const& x, - btVector3* gradient) const + btVector3* gradient) const { btAssert(m_isValid); if (!m_isValid) @@ -459,15 +449,15 @@ bool btMiniSDF::interpolate(unsigned int field_id, double& dist, btVector3 const if (!m_domain.contains(x)) return false; - btVector3 tmpmi = ((x - m_domain.min())*(m_inv_cell_size));//.cast().eval(); - unsigned int mi[3] = {(unsigned int )tmpmi[0],(unsigned int )tmpmi[1],(unsigned int )tmpmi[2]}; + btVector3 tmpmi = ((x - m_domain.min()) * (m_inv_cell_size)); //.cast().eval(); + unsigned int mi[3] = {(unsigned int)tmpmi[0], (unsigned int)tmpmi[1], (unsigned int)tmpmi[2]}; if (mi[0] >= m_resolution[0]) - mi[0] = m_resolution[0]-1; + mi[0] = m_resolution[0] - 1; if (mi[1] >= m_resolution[1]) - mi[1] = m_resolution[1]-1; + mi[1] = m_resolution[1] - 1; if (mi[2] >= m_resolution[2]) - mi[2] = m_resolution[2]-1; - btMultiIndex mui; + mi[2] = m_resolution[2] - 1; + btMultiIndex mui; mui.ijk[0] = mi[0]; mui.ijk[1] = mi[1]; mui.ijk[2] = mi[2]; @@ -478,12 +468,12 @@ bool btMiniSDF::interpolate(unsigned int field_id, double& dist, btVector3 const btAlignedBox3d sd = subdomain(i); i = i_; - btVector3 d = sd.m_max-sd.m_min;//.diagonal().eval(); + btVector3 d = sd.m_max - sd.m_min; //.diagonal().eval(); btVector3 denom = (sd.max() - sd.min()); - btVector3 c0 = btVector3(2.0,2.0,2.0)/denom; - btVector3 c1 = (sd.max() + sd.min())/denom; - btVector3 xi = (c0*x - c1); + btVector3 c0 = btVector3(2.0, 2.0, 2.0) / denom; + btVector3 c1 = (sd.max() + sd.min()) / denom; + btVector3 xi = (c0 * x - c1); btCell32 const& cell = m_cells[field_id][i]; if (!gradient) @@ -497,7 +487,8 @@ bool btMiniSDF::interpolate(unsigned int field_id, double& dist, btVector3 const double c = m_nodes[field_id][v]; if (c == DBL_MAX) { - return false;; + return false; + ; } phi += c * N[j]; } @@ -529,4 +520,3 @@ bool btMiniSDF::interpolate(unsigned int field_id, double& dist, btVector3 const dist = phi; return true; } - diff --git a/src/BulletCollision/CollisionShapes/btMiniSDF.h b/src/BulletCollision/CollisionShapes/btMiniSDF.h index 3de90e4f8..b60fd102f 100644 --- a/src/BulletCollision/CollisionShapes/btMiniSDF.h +++ b/src/BulletCollision/CollisionShapes/btMiniSDF.h @@ -5,7 +5,6 @@ #include "LinearMath/btAabbUtil2.h" #include "LinearMath/btAlignedObjectArray.h" - struct btMultiIndex { unsigned int ijk[3]; @@ -25,7 +24,6 @@ struct btAlignedBox3d { return m_max; } - bool contains(const btVector3& x) const { @@ -33,8 +31,8 @@ struct btAlignedBox3d } btAlignedBox3d(const btVector3& mn, const btVector3& mx) - :m_min(mn), - m_max(mx) + : m_min(mn), + m_max(mx) { } @@ -47,39 +45,38 @@ struct btShapeMatrix { double m_vec[32]; - inline double& operator[](int i) + inline double& operator[](int i) { return m_vec[i]; } - inline const double& operator[](int i) const + inline const double& operator[](int i) const { return m_vec[i]; } - }; struct btShapeGradients { - btVector3 m_vec[32]; + btVector3 m_vec[32]; void topRowsDivide(int row, double denom) { - for (int i=0;i > m_nodes; - btAlignedObjectArray > m_cells; + btAlignedObjectArray > m_cells; btAlignedObjectArray > m_cell_map; btMiniSDF() - :m_isValid(false) + : m_isValid(false) { } bool load(const char* data, int size); @@ -115,20 +110,18 @@ struct btMiniSDF { return m_isValid; } - unsigned int multiToSingleIndex(btMultiIndex const & ijk) const; - + unsigned int multiToSingleIndex(btMultiIndex const& ijk) const; + btAlignedBox3d subdomain(btMultiIndex const& ijk) const; btMultiIndex singleToMultiIndex(unsigned int l) const; btAlignedBox3d subdomain(unsigned int l) const; - btShapeMatrix shape_function_(btVector3 const& xi, btShapeGradients* gradient = 0) const; bool interpolate(unsigned int field_id, double& dist, btVector3 const& x, btVector3* gradient) const; }; - -#endif //MINISDF_H +#endif //MINISDF_H diff --git a/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp b/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp index 899ef5005..d4b6a651d 100644 --- a/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp +++ b/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.cpp @@ -13,65 +13,59 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btMinkowskiSumShape.h" - -btMinkowskiSumShape::btMinkowskiSumShape(const btConvexShape* shapeA,const btConvexShape* shapeB) -: btConvexInternalShape (), -m_shapeA(shapeA), -m_shapeB(shapeB) +btMinkowskiSumShape::btMinkowskiSumShape(const btConvexShape* shapeA, const btConvexShape* shapeB) + : btConvexInternalShape(), + m_shapeA(shapeA), + m_shapeB(shapeB) { m_shapeType = MINKOWSKI_DIFFERENCE_SHAPE_PROXYTYPE; m_transA.setIdentity(); m_transB.setIdentity(); } -btVector3 btMinkowskiSumShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const +btVector3 btMinkowskiSumShape::localGetSupportingVertexWithoutMargin(const btVector3& vec) const { - btVector3 supVertexA = m_transA(m_shapeA->localGetSupportingVertexWithoutMargin(vec*m_transA.getBasis())); - btVector3 supVertexB = m_transB(m_shapeB->localGetSupportingVertexWithoutMargin(-vec*m_transB.getBasis())); - return supVertexA - supVertexB; + btVector3 supVertexA = m_transA(m_shapeA->localGetSupportingVertexWithoutMargin(vec * m_transA.getBasis())); + btVector3 supVertexB = m_transB(m_shapeB->localGetSupportingVertexWithoutMargin(-vec * m_transB.getBasis())); + return supVertexA - supVertexB; } -void btMinkowskiSumShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +void btMinkowskiSumShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const { ///@todo: could make recursive use of batching. probably this shape is not used frequently. - for (int i=0;igetMargin() + m_shapeB->getMargin(); } - -void btMinkowskiSumShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +void btMinkowskiSumShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const { (void)mass; //inertia of the AABB of the Minkowski sum btTransform identity; identity.setIdentity(); - btVector3 aabbMin,aabbMax; - getAabb(identity,aabbMin,aabbMax); + btVector3 aabbMin, aabbMax; + getAabb(identity, aabbMin, aabbMax); - btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5); + btVector3 halfExtents = (aabbMax - aabbMin) * btScalar(0.5); btScalar margin = getMargin(); - btScalar lx=btScalar(2.)*(halfExtents.x()+margin); - btScalar ly=btScalar(2.)*(halfExtents.y()+margin); - btScalar lz=btScalar(2.)*(halfExtents.z()+margin); - const btScalar x2 = lx*lx; - const btScalar y2 = ly*ly; - const btScalar z2 = lz*lz; + btScalar lx = btScalar(2.) * (halfExtents.x() + margin); + btScalar ly = btScalar(2.) * (halfExtents.y() + margin); + btScalar lz = btScalar(2.) * (halfExtents.z() + margin); + const btScalar x2 = lx * lx; + const btScalar y2 = ly * ly; + const btScalar z2 = lz * lz; const btScalar scaledmass = mass * btScalar(0.08333333); - inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2)); + inertia = scaledmass * (btVector3(y2 + z2, x2 + z2, x2 + y2)); } diff --git a/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h b/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h index a3f9a4723..3b5150f6d 100644 --- a/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h +++ b/src/BulletCollision/CollisionShapes/btMinkowskiSumShape.h @@ -17,46 +17,43 @@ subject to the following restrictions: #define BT_MINKOWSKI_SUM_SHAPE_H #include "btConvexInternalShape.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types /// The btMinkowskiSumShape is only for advanced users. This shape represents implicit based minkowski sum of two convex implicit shapes. -ATTRIBUTE_ALIGNED16(class) btMinkowskiSumShape : public btConvexInternalShape +ATTRIBUTE_ALIGNED16(class) +btMinkowskiSumShape : public btConvexInternalShape { - - btTransform m_transA; - btTransform m_transB; - const btConvexShape* m_shapeA; - const btConvexShape* m_shapeB; + btTransform m_transA; + btTransform m_transB; + const btConvexShape* m_shapeA; + const btConvexShape* m_shapeB; public: + BT_DECLARE_ALIGNED_ALLOCATOR(); -BT_DECLARE_ALIGNED_ALLOCATOR(); + btMinkowskiSumShape(const btConvexShape* shapeA, const btConvexShape* shapeB); - btMinkowskiSumShape(const btConvexShape* shapeA,const btConvexShape* shapeB); + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const; - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const; - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; + virtual void calculateLocalInertia(btScalar mass, btVector3 & inertia) const; + void setTransformA(const btTransform& transA) { m_transA = transA; } + void setTransformB(const btTransform& transB) { m_transB = transB; } - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + const btTransform& getTransformA() const { return m_transA; } + const btTransform& GetTransformB() const { return m_transB; } - void setTransformA(const btTransform& transA) { m_transA = transA;} - void setTransformB(const btTransform& transB) { m_transB = transB;} + virtual btScalar getMargin() const; - const btTransform& getTransformA()const { return m_transA;} - const btTransform& GetTransformB()const { return m_transB;} + const btConvexShape* getShapeA() const { return m_shapeA; } + const btConvexShape* getShapeB() const { return m_shapeB; } - - virtual btScalar getMargin() const; - - const btConvexShape* getShapeA() const { return m_shapeA;} - const btConvexShape* getShapeB() const { return m_shapeB;} - - virtual const char* getName()const + virtual const char* getName() const { return "MinkowskiSum"; } }; -#endif //BT_MINKOWSKI_SUM_SHAPE_H +#endif //BT_MINKOWSKI_SUM_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp b/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp index 4195fa313..c0cc55dfb 100644 --- a/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp +++ b/src/BulletCollision/CollisionShapes/btMultiSphereShape.cpp @@ -13,7 +13,7 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ -#if defined (_WIN32) || defined (__i386__) +#if defined(_WIN32) || defined(__i386__) #define BT_USE_SSE_IN_API #endif @@ -22,43 +22,41 @@ subject to the following restrictions: #include "LinearMath/btQuaternion.h" #include "LinearMath/btSerializer.h" -btMultiSphereShape::btMultiSphereShape (const btVector3* positions,const btScalar* radi,int numSpheres) -:btConvexInternalAabbCachingShape () +btMultiSphereShape::btMultiSphereShape(const btVector3* positions, const btScalar* radi, int numSpheres) + : btConvexInternalAabbCachingShape() { m_shapeType = MULTI_SPHERE_SHAPE_PROXYTYPE; //btScalar startMargin = btScalar(BT_LARGE_FLOAT); m_localPositionArray.resize(numSpheres); m_radiArray.resize(numSpheres); - for (int i=0;i maxDot ) + int inner_count = MIN(numSpheres - k, 128); + for (long i = 0; i < inner_count; i++) + { + temp[i] = (*pos) * m_localScaling + vec * m_localScaling * (*rad) - vec * getMargin(); + pos++; + rad++; + } + long i = vec.maxDot(temp, inner_count, newDot); + if (newDot > maxDot) { maxDot = newDot; supVec = temp[i]; } - } + } return supVec; - } - void btMultiSphereShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +void btMultiSphereShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const { - - for (int j=0;j maxDot ) - { - maxDot = newDot; - supportVerticesOut[j] = temp[i]; - } - } - + for (int k = 0; k < numSpheres; k += 128) + { + btVector3 temp[128]; + int inner_count = MIN(numSpheres - k, 128); + for (long i = 0; i < inner_count; i++) + { + temp[i] = (*pos) * m_localScaling + vec * m_localScaling * (*rad) - vec * getMargin(); + pos++; + rad++; + } + long i = vec.maxDot(temp, inner_count, newDot); + if (newDot > maxDot) + { + maxDot = newDot; + supportVerticesOut[j] = temp[i]; + } + } } } - - - - - - - -void btMultiSphereShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +void btMultiSphereShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const { //as an approximation, take the inertia of the box that bounds the spheres - btVector3 localAabbMin,localAabbMax; - getCachedLocalAabb(localAabbMin,localAabbMax); - btVector3 halfExtents = (localAabbMax-localAabbMin)*btScalar(0.5); + btVector3 localAabbMin, localAabbMax; + getCachedLocalAabb(localAabbMin, localAabbMax); + btVector3 halfExtents = (localAabbMax - localAabbMin) * btScalar(0.5); - btScalar lx=btScalar(2.)*(halfExtents.x()); - btScalar ly=btScalar(2.)*(halfExtents.y()); - btScalar lz=btScalar(2.)*(halfExtents.z()); - - inertia.setValue(mass/(btScalar(12.0)) * (ly*ly + lz*lz), - mass/(btScalar(12.0)) * (lx*lx + lz*lz), - mass/(btScalar(12.0)) * (lx*lx + ly*ly)); + btScalar lx = btScalar(2.) * (halfExtents.x()); + btScalar ly = btScalar(2.) * (halfExtents.y()); + btScalar lz = btScalar(2.) * (halfExtents.z()); + inertia.setValue(mass / (btScalar(12.0)) * (ly * ly + lz * lz), + mass / (btScalar(12.0)) * (lx * lx + lz * lz), + mass / (btScalar(12.0)) * (lx * lx + ly * ly)); } - ///fills the dataBuffer and returns the struct name (and 0 on failure) -const char* btMultiSphereShape::serialize(void* dataBuffer, btSerializer* serializer) const +const char* btMultiSphereShape::serialize(void* dataBuffer, btSerializer* serializer) const { - btMultiSphereShapeData* shapeData = (btMultiSphereShapeData*) dataBuffer; + btMultiSphereShapeData* shapeData = (btMultiSphereShapeData*)dataBuffer; btConvexInternalShape::serialize(&shapeData->m_convexInternalShapeData, serializer); int numElem = m_localPositionArray.size(); - shapeData->m_localPositionArrayPtr = numElem ? (btPositionAndRadius*)serializer->getUniquePointer((void*)&m_localPositionArray[0]): 0; - + shapeData->m_localPositionArrayPtr = numElem ? (btPositionAndRadius*)serializer->getUniquePointer((void*)&m_localPositionArray[0]) : 0; + shapeData->m_localPositionArraySize = numElem; if (numElem) { - btChunk* chunk = serializer->allocate(sizeof(btPositionAndRadius),numElem); + btChunk* chunk = serializer->allocate(sizeof(btPositionAndRadius), numElem); btPositionAndRadius* memPtr = (btPositionAndRadius*)chunk->m_oldPtr; - for (int i=0;im_pos); memPtr->m_radius = float(m_radiArray[i]); } - serializer->finalizeChunk(chunk,"btPositionAndRadius",BT_ARRAY_CODE,(void*)&m_localPositionArray[0]); + serializer->finalizeChunk(chunk, "btPositionAndRadius", BT_ARRAY_CODE, (void*)&m_localPositionArray[0]); } // Fill padding with zeros to appease msan. @@ -181,5 +167,3 @@ const char* btMultiSphereShape::serialize(void* dataBuffer, btSerializer* serial return "btMultiSphereShapeData"; } - - diff --git a/src/BulletCollision/CollisionShapes/btMultiSphereShape.h b/src/BulletCollision/CollisionShapes/btMultiSphereShape.h index 5d3b40268..2d79c07ca 100644 --- a/src/BulletCollision/CollisionShapes/btMultiSphereShape.h +++ b/src/BulletCollision/CollisionShapes/btMultiSphereShape.h @@ -17,69 +17,65 @@ subject to the following restrictions: #define BT_MULTI_SPHERE_MINKOWSKI_H #include "btConvexInternalShape.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types #include "LinearMath/btAlignedObjectArray.h" #include "LinearMath/btAabbUtil2.h" - - ///The btMultiSphereShape represents the convex hull of a collection of spheres. You can create special capsules or other smooth volumes. ///It is possible to animate the spheres for deformation, but call 'recalcLocalAabb' after changing any sphere position/radius -ATTRIBUTE_ALIGNED16(class) btMultiSphereShape : public btConvexInternalAabbCachingShape +ATTRIBUTE_ALIGNED16(class) +btMultiSphereShape : public btConvexInternalAabbCachingShape { - btAlignedObjectArray m_localPositionArray; - btAlignedObjectArray m_radiArray; - + btAlignedObjectArray m_radiArray; + public: BT_DECLARE_ALIGNED_ALLOCATOR(); - - btMultiSphereShape (const btVector3* positions,const btScalar* radi,int numSpheres); + + btMultiSphereShape(const btVector3* positions, const btScalar* radi, int numSpheres); ///CollisionShape Interface - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + virtual void calculateLocalInertia(btScalar mass, btVector3 & inertia) const; /// btConvexShape Interface - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const; - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; - - int getSphereCount() const + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const; + + int getSphereCount() const { return m_localPositionArray.size(); } - const btVector3& getSpherePosition(int index) const + const btVector3& getSpherePosition(int index) const { return m_localPositionArray[index]; } - btScalar getSphereRadius(int index) const + btScalar getSphereRadius(int index) const { return m_radiArray[index]; } - - virtual const char* getName()const + virtual const char* getName() const { return "MultiSphere"; } - virtual int calculateSerializeBufferSize() const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; - - + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; }; - -struct btPositionAndRadius +struct btPositionAndRadius { - btVector3FloatData m_pos; - float m_radius; + btVector3FloatData m_pos; + float m_radius; }; +// clang-format off + struct btMultiSphereShapeData { btConvexInternalShapeData m_convexInternalShapeData; @@ -89,13 +85,11 @@ struct btMultiSphereShapeData char m_padding[4]; }; +// clang-format on - -SIMD_FORCE_INLINE int btMultiSphereShape::calculateSerializeBufferSize() const +SIMD_FORCE_INLINE int btMultiSphereShape::calculateSerializeBufferSize() const { return sizeof(btMultiSphereShapeData); } - - -#endif //BT_MULTI_SPHERE_MINKOWSKI_H +#endif //BT_MULTI_SPHERE_MINKOWSKI_H diff --git a/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp b/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp index 58799ac96..30108c9e7 100644 --- a/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp +++ b/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.cpp @@ -19,27 +19,25 @@ subject to the following restrictions: #include "BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h" //#include "BulletCollision/CollisionShapes/btOptimizedBvh.h" - ///Obtains the material for a specific triangle -const btMaterial * btMultimaterialTriangleMeshShape::getMaterialProperties(int partID, int triIndex) +const btMaterial *btMultimaterialTriangleMeshShape::getMaterialProperties(int partID, int triIndex) { - const unsigned char * materialBase = 0; - int numMaterials; - PHY_ScalarType materialType; - int materialStride; - const unsigned char * triangleMaterialBase = 0; - int numTriangles; - int triangleMaterialStride; - PHY_ScalarType triangleType; + const unsigned char *materialBase = 0; + int numMaterials; + PHY_ScalarType materialType; + int materialStride; + const unsigned char *triangleMaterialBase = 0; + int numTriangles; + int triangleMaterialStride; + PHY_ScalarType triangleType; - ((btTriangleIndexVertexMaterialArray*)m_meshInterface)->getLockedReadOnlyMaterialBase(&materialBase, numMaterials, materialType, materialStride, - &triangleMaterialBase, numTriangles, triangleMaterialStride, triangleType, partID); + ((btTriangleIndexVertexMaterialArray *)m_meshInterface)->getLockedReadOnlyMaterialBase(&materialBase, numMaterials, materialType, materialStride, &triangleMaterialBase, numTriangles, triangleMaterialStride, triangleType, partID); - // return the pointer to the place with the friction for the triangle - // TODO: This depends on whether it's a moving mesh or not - // BUG IN GIMPACT - //return (btScalar*)(&materialBase[triangleMaterialBase[(triIndex-1) * triangleMaterialStride] * materialStride]); - int * matInd = (int *)(&(triangleMaterialBase[(triIndex * triangleMaterialStride)])); - btMaterial *matVal = (btMaterial *)(&(materialBase[*matInd * materialStride])); - return (matVal); + // return the pointer to the place with the friction for the triangle + // TODO: This depends on whether it's a moving mesh or not + // BUG IN GIMPACT + //return (btScalar*)(&materialBase[triangleMaterialBase[(triIndex-1) * triangleMaterialStride] * materialStride]); + int *matInd = (int *)(&(triangleMaterialBase[(triIndex * triangleMaterialStride)])); + btMaterial *matVal = (btMaterial *)(&(materialBase[*matInd * materialStride])); + return (matVal); } diff --git a/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h b/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h index 5ebaede4a..d1d42f8e0 100644 --- a/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h +++ b/src/BulletCollision/CollisionShapes/btMultimaterialTriangleMeshShape.h @@ -22,82 +22,80 @@ subject to the following restrictions: #include "btMaterial.h" ///The BvhTriangleMaterialMeshShape extends the btBvhTriangleMeshShape. Its main contribution is the interface into a material array, which allows per-triangle friction and restitution. -ATTRIBUTE_ALIGNED16(class) btMultimaterialTriangleMeshShape : public btBvhTriangleMeshShape +ATTRIBUTE_ALIGNED16(class) +btMultimaterialTriangleMeshShape : public btBvhTriangleMeshShape { - btAlignedObjectArray m_materialList; + btAlignedObjectArray m_materialList; public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - btMultimaterialTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true): - btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression, buildBvh) - { - m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE; + btMultimaterialTriangleMeshShape(btStridingMeshInterface * meshInterface, bool useQuantizedAabbCompression, bool buildBvh = true) : btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression, buildBvh) + { + m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE; - const unsigned char *vertexbase; - int numverts; - PHY_ScalarType type; - int stride; - const unsigned char *indexbase; - int indexstride; - int numfaces; - PHY_ScalarType indicestype; + const unsigned char *vertexbase; + int numverts; + PHY_ScalarType type; + int stride; + const unsigned char *indexbase; + int indexstride; + int numfaces; + PHY_ScalarType indicestype; - //m_materialLookup = (int**)(btAlignedAlloc(sizeof(int*) * meshInterface->getNumSubParts(), 16)); + //m_materialLookup = (int**)(btAlignedAlloc(sizeof(int*) * meshInterface->getNumSubParts(), 16)); - for(int i = 0; i < meshInterface->getNumSubParts(); i++) - { - m_meshInterface->getLockedReadOnlyVertexIndexBase( - &vertexbase, - numverts, - type, - stride, - &indexbase, - indexstride, - numfaces, - indicestype, - i); - //m_materialLookup[i] = (int*)(btAlignedAlloc(sizeof(int) * numfaces, 16)); - } - } + for (int i = 0; i < meshInterface->getNumSubParts(); i++) + { + m_meshInterface->getLockedReadOnlyVertexIndexBase( + &vertexbase, + numverts, + type, + stride, + &indexbase, + indexstride, + numfaces, + indicestype, + i); + //m_materialLookup[i] = (int*)(btAlignedAlloc(sizeof(int) * numfaces, 16)); + } + } ///optionally pass in a larger bvh aabb, used for quantization. This allows for deformations within this aabb - btMultimaterialTriangleMeshShape(btStridingMeshInterface* meshInterface, bool useQuantizedAabbCompression,const btVector3& bvhAabbMin,const btVector3& bvhAabbMax, bool buildBvh = true): - btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression, bvhAabbMin, bvhAabbMax, buildBvh) - { - m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE; + btMultimaterialTriangleMeshShape(btStridingMeshInterface * meshInterface, bool useQuantizedAabbCompression, const btVector3 &bvhAabbMin, const btVector3 &bvhAabbMax, bool buildBvh = true) : btBvhTriangleMeshShape(meshInterface, useQuantizedAabbCompression, bvhAabbMin, bvhAabbMax, buildBvh) + { + m_shapeType = MULTIMATERIAL_TRIANGLE_MESH_PROXYTYPE; - const unsigned char *vertexbase; - int numverts; - PHY_ScalarType type; - int stride; - const unsigned char *indexbase; - int indexstride; - int numfaces; - PHY_ScalarType indicestype; + const unsigned char *vertexbase; + int numverts; + PHY_ScalarType type; + int stride; + const unsigned char *indexbase; + int indexstride; + int numfaces; + PHY_ScalarType indicestype; - //m_materialLookup = (int**)(btAlignedAlloc(sizeof(int*) * meshInterface->getNumSubParts(), 16)); + //m_materialLookup = (int**)(btAlignedAlloc(sizeof(int*) * meshInterface->getNumSubParts(), 16)); - for(int i = 0; i < meshInterface->getNumSubParts(); i++) - { - m_meshInterface->getLockedReadOnlyVertexIndexBase( - &vertexbase, - numverts, - type, - stride, - &indexbase, - indexstride, - numfaces, - indicestype, - i); - //m_materialLookup[i] = (int*)(btAlignedAlloc(sizeof(int) * numfaces * 2, 16)); - } - } - - virtual ~btMultimaterialTriangleMeshShape() - { -/* + for (int i = 0; i < meshInterface->getNumSubParts(); i++) + { + m_meshInterface->getLockedReadOnlyVertexIndexBase( + &vertexbase, + numverts, + type, + stride, + &indexbase, + indexstride, + numfaces, + indicestype, + i); + //m_materialLookup[i] = (int*)(btAlignedAlloc(sizeof(int) * numfaces * 2, 16)); + } + } + + virtual ~btMultimaterialTriangleMeshShape() + { + /* for(int i = 0; i < m_meshInterface->getNumSubParts(); i++) { btAlignedFree(m_materialValues[i]); @@ -106,14 +104,12 @@ public: btAlignedFree(m_materialValues); m_materialLookup = NULL; */ - } + } //debugging - virtual const char* getName()const {return "MULTIMATERIALTRIANGLEMESH";} + virtual const char *getName() const { return "MULTIMATERIALTRIANGLEMESH"; } - ///Obtains the material for a specific triangle - const btMaterial * getMaterialProperties(int partID, int triIndex); + ///Obtains the material for a specific triangle + const btMaterial *getMaterialProperties(int partID, int triIndex); +}; -} -; - -#endif //BT_BVH_TRIANGLE_MATERIAL_MESH_SHAPE_H +#endif //BT_BVH_TRIANGLE_MATERIAL_MESH_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp b/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp index 6f36775f7..687399e0a 100644 --- a/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp +++ b/src/BulletCollision/CollisionShapes/btOptimizedBvh.cpp @@ -13,51 +13,46 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btOptimizedBvh.h" #include "btStridingMeshInterface.h" #include "LinearMath/btAabbUtil2.h" #include "LinearMath/btIDebugDraw.h" - btOptimizedBvh::btOptimizedBvh() -{ +{ } btOptimizedBvh::~btOptimizedBvh() { } - void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax) { m_useQuantization = useQuantizedAabbCompression; - // NodeArray triangleNodes; - struct NodeTriangleCallback : public btInternalTriangleIndexCallback + struct NodeTriangleCallback : public btInternalTriangleIndexCallback { - - NodeArray& m_triangleNodes; + NodeArray& m_triangleNodes; NodeTriangleCallback& operator=(NodeTriangleCallback& other) { m_triangleNodes.copyFromArray(other.m_triangleNodes); return *this; } - - NodeTriangleCallback(NodeArray& triangleNodes) - :m_triangleNodes(triangleNodes) + + NodeTriangleCallback(NodeArray& triangleNodes) + : m_triangleNodes(triangleNodes) { } - virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex) { btOptimizedBvhNode node; - btVector3 aabbMin,aabbMax; - aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); - aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); + btVector3 aabbMin, aabbMax; + aabbMin.setValue(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); + aabbMax.setValue(btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT)); aabbMin.setMin(triangle[0]); aabbMax.setMax(triangle[0]); aabbMin.setMin(triangle[1]); @@ -70,17 +65,17 @@ void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantized node.m_aabbMaxOrg = aabbMax; node.m_escapeIndex = -1; - + //for child nodes node.m_subPart = partId; node.m_triangleIndex = triangleIndex; m_triangleNodes.push_back(node); } }; - struct QuantizedNodeTriangleCallback : public btInternalTriangleIndexCallback + struct QuantizedNodeTriangleCallback : public btInternalTriangleIndexCallback { - QuantizedNodeArray& m_triangleNodes; - const btQuantizedBvh* m_optimizedTree; // for quantization + QuantizedNodeArray& m_triangleNodes; + const btQuantizedBvh* m_optimizedTree; // for quantization QuantizedNodeTriangleCallback& operator=(QuantizedNodeTriangleCallback& other) { @@ -89,23 +84,23 @@ void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantized return *this; } - QuantizedNodeTriangleCallback(QuantizedNodeArray& triangleNodes,const btQuantizedBvh* tree) - :m_triangleNodes(triangleNodes),m_optimizedTree(tree) + QuantizedNodeTriangleCallback(QuantizedNodeArray& triangleNodes, const btQuantizedBvh* tree) + : m_triangleNodes(triangleNodes), m_optimizedTree(tree) { } - virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex) { // The partId and triangle index must fit in the same (positive) integer - btAssert(partId < (1<=0); + btAssert(triangleIndex >= 0); btQuantizedBvhNode node; - btVector3 aabbMin,aabbMax; - aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); - aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); + btVector3 aabbMin, aabbMax; + aabbMin.setValue(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); + aabbMax.setValue(btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT)); aabbMin.setMin(triangle[0]); aabbMax.setMax(triangle[0]); aabbMin.setMin(triangle[1]); @@ -132,59 +127,52 @@ void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantized aabbMin.setZ(aabbMin.z() - MIN_AABB_HALF_DIMENSION); } - m_optimizedTree->quantize(&node.m_quantizedAabbMin[0],aabbMin,0); - m_optimizedTree->quantize(&node.m_quantizedAabbMax[0],aabbMax,1); + m_optimizedTree->quantize(&node.m_quantizedAabbMin[0], aabbMin, 0); + m_optimizedTree->quantize(&node.m_quantizedAabbMax[0], aabbMax, 1); - node.m_escapeIndexOrTriangleIndex = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | triangleIndex; + node.m_escapeIndexOrTriangleIndex = (partId << (31 - MAX_NUM_PARTS_IN_BITS)) | triangleIndex; m_triangleNodes.push_back(node); } }; - - int numLeafNodes = 0; - if (m_useQuantization) { - //initialize quantization values - setQuantizationValues(bvhAabbMin,bvhAabbMax); + setQuantizationValues(bvhAabbMin, bvhAabbMax); - QuantizedNodeTriangleCallback callback(m_quantizedLeafNodes,this); + QuantizedNodeTriangleCallback callback(m_quantizedLeafNodes, this); - - triangles->InternalProcessAllTriangles(&callback,m_bvhAabbMin,m_bvhAabbMax); + triangles->InternalProcessAllTriangles(&callback, m_bvhAabbMin, m_bvhAabbMax); //now we have an array of leafnodes in m_leafNodes numLeafNodes = m_quantizedLeafNodes.size(); - - m_quantizedContiguousNodes.resize(2*numLeafNodes); - - - } else + m_quantizedContiguousNodes.resize(2 * numLeafNodes); + } + else { - NodeTriangleCallback callback(m_leafNodes); + NodeTriangleCallback callback(m_leafNodes); - btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); - btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); + btVector3 aabbMin(btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT)); + btVector3 aabbMax(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); - triangles->InternalProcessAllTriangles(&callback,aabbMin,aabbMax); + triangles->InternalProcessAllTriangles(&callback, aabbMin, aabbMax); //now we have an array of leafnodes in m_leafNodes numLeafNodes = m_leafNodes.size(); - m_contiguousNodes.resize(2*numLeafNodes); + m_contiguousNodes.resize(2 * numLeafNodes); } m_curNodeIndex = 0; - buildTree(0,numLeafNodes); + buildTree(0, numLeafNodes); ///if the entire tree is small then subtree size, we need to create a header info for the tree - if(m_useQuantization && !m_SubtreeHeaders.size()) + if (m_useQuantization && !m_SubtreeHeaders.size()) { btBvhSubtreeInfo& subtree = m_SubtreeHeaders.expand(); subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[0]); @@ -200,37 +188,29 @@ void btOptimizedBvh::build(btStridingMeshInterface* triangles, bool useQuantized m_leafNodes.clear(); } - - - -void btOptimizedBvh::refit(btStridingMeshInterface* meshInterface,const btVector3& aabbMin,const btVector3& aabbMax) +void btOptimizedBvh::refit(btStridingMeshInterface* meshInterface, const btVector3& aabbMin, const btVector3& aabbMax) { if (m_useQuantization) { + setQuantizationValues(aabbMin, aabbMax); - setQuantizationValues(aabbMin,aabbMax); - - updateBvhNodes(meshInterface,0,m_curNodeIndex,0); + updateBvhNodes(meshInterface, 0, m_curNodeIndex, 0); ///now update all subtree headers int i; - for (i=0;im_SubtreeHeaders.size();i++) + for (i = 0; i < this->m_SubtreeHeaders.size(); i++) { btBvhSubtreeInfo& subtree = m_SubtreeHeaders[i]; //PCK: unsigned instead of bool - unsigned overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin,quantizedQueryAabbMax,subtree.m_quantizedAabbMin,subtree.m_quantizedAabbMax); + unsigned overlap = testQuantizedAabbAgainstQuantizedAabb(quantizedQueryAabbMin, quantizedQueryAabbMax, subtree.m_quantizedAabbMin, subtree.m_quantizedAabbMax); if (overlap != 0) { - updateBvhNodes(meshInterface,subtree.m_rootNodeIndex,subtree.m_rootNodeIndex+subtree.m_subtreeSize,i); + updateBvhNodes(meshInterface, subtree.m_rootNodeIndex, subtree.m_rootNodeIndex + subtree.m_subtreeSize, i); subtree.setAabbFromQuantizeNode(m_quantizedContiguousNodes[subtree.m_rootNodeIndex]); } } - } -void btOptimizedBvh::updateBvhNodes(btStridingMeshInterface* meshInterface,int firstNode,int endNode,int index) +void btOptimizedBvh::updateBvhNodes(btStridingMeshInterface* meshInterface, int firstNode, int endNode, int index) { (void)index; btAssert(m_useQuantization); - int curNodeSubPart=-1; + int curNodeSubPart = -1; //get access info to trianglemesh data - const unsigned char *vertexbase = 0; - int numverts = 0; - PHY_ScalarType type = PHY_INTEGER; - int stride = 0; - const unsigned char *indexbase = 0; - int indexstride = 0; - int numfaces = 0; - PHY_ScalarType indicestype = PHY_INTEGER; + const unsigned char* vertexbase = 0; + int numverts = 0; + PHY_ScalarType type = PHY_INTEGER; + int stride = 0; + const unsigned char* indexbase = 0; + int indexstride = 0; + int numfaces = 0; + PHY_ScalarType indicestype = PHY_INTEGER; - btVector3 triangleVerts[3]; - btVector3 aabbMin,aabbMax; - const btVector3& meshScaling = meshInterface->getScaling(); - - int i; - for (i=endNode-1;i>=firstNode;i--) + btVector3 triangleVerts[3]; + btVector3 aabbMin, aabbMax; + const btVector3& meshScaling = meshInterface->getScaling(); + + int i; + for (i = endNode - 1; i >= firstNode; i--) + { + btQuantizedBvhNode& curNode = m_quantizedContiguousNodes[i]; + if (curNode.isLeafNode()) { - - - btQuantizedBvhNode& curNode = m_quantizedContiguousNodes[i]; - if (curNode.isLeafNode()) + //recalc aabb from triangle data + int nodeSubPart = curNode.getPartId(); + int nodeTriangleIndex = curNode.getTriangleIndex(); + if (nodeSubPart != curNodeSubPart) { - //recalc aabb from triangle data - int nodeSubPart = curNode.getPartId(); - int nodeTriangleIndex = curNode.getTriangleIndex(); - if (nodeSubPart != curNodeSubPart) - { - if (curNodeSubPart >= 0) - meshInterface->unLockReadOnlyVertexBase(curNodeSubPart); - meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase,numverts, type,stride,&indexbase,indexstride,numfaces,indicestype,nodeSubPart); + if (curNodeSubPart >= 0) + meshInterface->unLockReadOnlyVertexBase(curNodeSubPart); + meshInterface->getLockedReadOnlyVertexIndexBase(&vertexbase, numverts, type, stride, &indexbase, indexstride, numfaces, indicestype, nodeSubPart); - curNodeSubPart = nodeSubPart; - btAssert(indicestype==PHY_INTEGER||indicestype==PHY_SHORT); - } - //triangles->getLockedReadOnlyVertexIndexBase(vertexBase,numVerts, + curNodeSubPart = nodeSubPart; + btAssert(indicestype == PHY_INTEGER || indicestype == PHY_SHORT); + } + //triangles->getLockedReadOnlyVertexIndexBase(vertexBase,numVerts, - unsigned int* gfxbase = (unsigned int*)(indexbase+nodeTriangleIndex*indexstride); - - - for (int j=2;j>=0;j--) - { - - int graphicsindex = indicestype==PHY_SHORT?((unsigned short*)gfxbase)[j]:gfxbase[j]; - if (type == PHY_FLOAT) - { - float* graphicsbase = (float*)(vertexbase+graphicsindex*stride); - triangleVerts[j] = btVector3( - graphicsbase[0]*meshScaling.getX(), - graphicsbase[1]*meshScaling.getY(), - graphicsbase[2]*meshScaling.getZ()); - } - else - { - double* graphicsbase = (double*)(vertexbase+graphicsindex*stride); - triangleVerts[j] = btVector3( btScalar(graphicsbase[0]*meshScaling.getX()), btScalar(graphicsbase[1]*meshScaling.getY()), btScalar(graphicsbase[2]*meshScaling.getZ())); - } - } + unsigned int* gfxbase = (unsigned int*)(indexbase + nodeTriangleIndex * indexstride); - - - aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); - aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); - aabbMin.setMin(triangleVerts[0]); - aabbMax.setMax(triangleVerts[0]); - aabbMin.setMin(triangleVerts[1]); - aabbMax.setMax(triangleVerts[1]); - aabbMin.setMin(triangleVerts[2]); - aabbMax.setMax(triangleVerts[2]); - - quantize(&curNode.m_quantizedAabbMin[0],aabbMin,0); - quantize(&curNode.m_quantizedAabbMax[0],aabbMax,1); - - } else + for (int j = 2; j >= 0; j--) { - //combine aabb from both children - - btQuantizedBvhNode* leftChildNode = &m_quantizedContiguousNodes[i+1]; - - btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? &m_quantizedContiguousNodes[i+2] : - &m_quantizedContiguousNodes[i+1+leftChildNode->getEscapeIndex()]; - - + int graphicsindex = indicestype == PHY_SHORT ? ((unsigned short*)gfxbase)[j] : gfxbase[j]; + if (type == PHY_FLOAT) { - for (int i=0;i<3;i++) - { - curNode.m_quantizedAabbMin[i] = leftChildNode->m_quantizedAabbMin[i]; - if (curNode.m_quantizedAabbMin[i]>rightChildNode->m_quantizedAabbMin[i]) - curNode.m_quantizedAabbMin[i]=rightChildNode->m_quantizedAabbMin[i]; - - curNode.m_quantizedAabbMax[i] = leftChildNode->m_quantizedAabbMax[i]; - if (curNode.m_quantizedAabbMax[i] < rightChildNode->m_quantizedAabbMax[i]) - curNode.m_quantizedAabbMax[i] = rightChildNode->m_quantizedAabbMax[i]; - } + float* graphicsbase = (float*)(vertexbase + graphicsindex * stride); + triangleVerts[j] = btVector3( + graphicsbase[0] * meshScaling.getX(), + graphicsbase[1] * meshScaling.getY(), + graphicsbase[2] * meshScaling.getZ()); + } + else + { + double* graphicsbase = (double*)(vertexbase + graphicsindex * stride); + triangleVerts[j] = btVector3(btScalar(graphicsbase[0] * meshScaling.getX()), btScalar(graphicsbase[1] * meshScaling.getY()), btScalar(graphicsbase[2] * meshScaling.getZ())); } } + aabbMin.setValue(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); + aabbMax.setValue(btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT)); + aabbMin.setMin(triangleVerts[0]); + aabbMax.setMax(triangleVerts[0]); + aabbMin.setMin(triangleVerts[1]); + aabbMax.setMax(triangleVerts[1]); + aabbMin.setMin(triangleVerts[2]); + aabbMax.setMax(triangleVerts[2]); + + quantize(&curNode.m_quantizedAabbMin[0], aabbMin, 0); + quantize(&curNode.m_quantizedAabbMax[0], aabbMax, 1); } + else + { + //combine aabb from both children - if (curNodeSubPart >= 0) - meshInterface->unLockReadOnlyVertexBase(curNodeSubPart); + btQuantizedBvhNode* leftChildNode = &m_quantizedContiguousNodes[i + 1]; - + btQuantizedBvhNode* rightChildNode = leftChildNode->isLeafNode() ? &m_quantizedContiguousNodes[i + 2] : &m_quantizedContiguousNodes[i + 1 + leftChildNode->getEscapeIndex()]; + + { + for (int i = 0; i < 3; i++) + { + curNode.m_quantizedAabbMin[i] = leftChildNode->m_quantizedAabbMin[i]; + if (curNode.m_quantizedAabbMin[i] > rightChildNode->m_quantizedAabbMin[i]) + curNode.m_quantizedAabbMin[i] = rightChildNode->m_quantizedAabbMin[i]; + + curNode.m_quantizedAabbMax[i] = leftChildNode->m_quantizedAabbMax[i]; + if (curNode.m_quantizedAabbMax[i] < rightChildNode->m_quantizedAabbMax[i]) + curNode.m_quantizedAabbMax[i] = rightChildNode->m_quantizedAabbMax[i]; + } + } + } + } + + if (curNodeSubPart >= 0) + meshInterface->unLockReadOnlyVertexBase(curNodeSubPart); } ///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place' -btOptimizedBvh* btOptimizedBvh::deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian) +btOptimizedBvh* btOptimizedBvh::deSerializeInPlace(void* i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian) { - btQuantizedBvh* bvh = btQuantizedBvh::deSerializeInPlace(i_alignedDataBuffer,i_dataBufferSize,i_swapEndian); - + btQuantizedBvh* bvh = btQuantizedBvh::deSerializeInPlace(i_alignedDataBuffer, i_dataBufferSize, i_swapEndian); + //we don't add additional data so just do a static upcast return static_cast(bvh); } diff --git a/src/BulletCollision/CollisionShapes/btOptimizedBvh.h b/src/BulletCollision/CollisionShapes/btOptimizedBvh.h index 715961f55..22f131c8b 100644 --- a/src/BulletCollision/CollisionShapes/btOptimizedBvh.h +++ b/src/BulletCollision/CollisionShapes/btOptimizedBvh.h @@ -22,44 +22,35 @@ subject to the following restrictions: class btStridingMeshInterface; - ///The btOptimizedBvh extends the btQuantizedBvh to create AABB tree for triangle meshes, through the btStridingMeshInterface. -ATTRIBUTE_ALIGNED16(class) btOptimizedBvh : public btQuantizedBvh +ATTRIBUTE_ALIGNED16(class) +btOptimizedBvh : public btQuantizedBvh { - public: BT_DECLARE_ALIGNED_ALLOCATOR(); protected: - public: - btOptimizedBvh(); virtual ~btOptimizedBvh(); - void build(btStridingMeshInterface* triangles,bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax); + void build(btStridingMeshInterface * triangles, bool useQuantizedAabbCompression, const btVector3& bvhAabbMin, const btVector3& bvhAabbMax); - void refit(btStridingMeshInterface* triangles,const btVector3& aabbMin,const btVector3& aabbMax); + void refit(btStridingMeshInterface * triangles, const btVector3& aabbMin, const btVector3& aabbMax); - void refitPartial(btStridingMeshInterface* triangles,const btVector3& aabbMin, const btVector3& aabbMax); + void refitPartial(btStridingMeshInterface * triangles, const btVector3& aabbMin, const btVector3& aabbMax); - void updateBvhNodes(btStridingMeshInterface* meshInterface,int firstNode,int endNode,int index); + void updateBvhNodes(btStridingMeshInterface * meshInterface, int firstNode, int endNode, int index); /// Data buffer MUST be 16 byte aligned - virtual bool serializeInPlace(void *o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const + virtual bool serializeInPlace(void* o_alignedDataBuffer, unsigned i_dataBufferSize, bool i_swapEndian) const { - return btQuantizedBvh::serialize(o_alignedDataBuffer,i_dataBufferSize,i_swapEndian); - + return btQuantizedBvh::serialize(o_alignedDataBuffer, i_dataBufferSize, i_swapEndian); } ///deSerializeInPlace loads and initializes a BVH from a buffer in memory 'in place' - static btOptimizedBvh *deSerializeInPlace(void *i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian); - - + static btOptimizedBvh* deSerializeInPlace(void* i_alignedDataBuffer, unsigned int i_dataBufferSize, bool i_swapEndian); }; - -#endif //BT_OPTIMIZED_BVH_H - - +#endif //BT_OPTIMIZED_BVH_H diff --git a/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp b/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp index d51b6760f..521ecfc76 100644 --- a/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp +++ b/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.cpp @@ -12,7 +12,7 @@ subject to the following restrictions: 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ -#if defined (_WIN32) || defined (__i386__) +#if defined(_WIN32) || defined(__i386__) #define BT_USE_SSE_IN_API #endif @@ -23,11 +23,9 @@ subject to the following restrictions: #include "LinearMath/btGeometryUtil.h" #include "LinearMath/btGrahamScan2dConvexHull.h" - -btPolyhedralConvexShape::btPolyhedralConvexShape() :btConvexInternalShape(), -m_polyhedron(0) +btPolyhedralConvexShape::btPolyhedralConvexShape() : btConvexInternalShape(), + m_polyhedron(0) { - } btPolyhedralConvexShape::~btPolyhedralConvexShape() @@ -44,65 +42,65 @@ void btPolyhedralConvexShape::setPolyhedralFeatures(btConvexPolyhedron& polyhedr if (m_polyhedron) { *m_polyhedron = polyhedron; - } else + } + else { - void* mem = btAlignedAlloc(sizeof(btConvexPolyhedron),16); + void* mem = btAlignedAlloc(sizeof(btConvexPolyhedron), 16); m_polyhedron = new (mem) btConvexPolyhedron(polyhedron); } } -bool btPolyhedralConvexShape::initializePolyhedralFeatures(int shiftVerticesByMargin) +bool btPolyhedralConvexShape::initializePolyhedralFeatures(int shiftVerticesByMargin) { - if (m_polyhedron) { m_polyhedron->~btConvexPolyhedron(); btAlignedFree(m_polyhedron); } - - void* mem = btAlignedAlloc(sizeof(btConvexPolyhedron),16); + + void* mem = btAlignedAlloc(sizeof(btConvexPolyhedron), 16); m_polyhedron = new (mem) btConvexPolyhedron; btAlignedObjectArray orgVertices; - for (int i=0;i planeEquations; - btGeometryUtil::getPlaneEquationsFromVertices(orgVertices,planeEquations); + btGeometryUtil::getPlaneEquationsFromVertices(orgVertices, planeEquations); btAlignedObjectArray shiftedPlaneEquations; - for (int p=0;p tmpVertices; - btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations,tmpVertices); - - conv.compute(&tmpVertices[0].getX(), sizeof(btVector3),tmpVertices.size(),0.f,0.f); - } else + btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations, tmpVertices); + + conv.compute(&tmpVertices[0].getX(), sizeof(btVector3), tmpVertices.size(), 0.f, 0.f); + } + else { - - conv.compute(&orgVertices[0].getX(), sizeof(btVector3),orgVertices.size(),0.f,0.f); + conv.compute(&orgVertices[0].getX(), sizeof(btVector3), orgVertices.size(), 0.f, 0.f); } #ifndef BT_RECONSTRUCT_FACES - + int numVertices = conv.vertices.size(); m_polyhedron->m_vertices.resize(numVertices); - for (int p=0;pm_vertices[p] = conv.vertices[p]; } @@ -115,78 +113,72 @@ bool btPolyhedralConvexShape::initializePolyhedralFeatures(int shiftVerticesByMa btFace combinedFace; const btConvexHullComputer::Edge* edge = &conv.edges[conv.faces[j]]; v0 = edge->getSourceVertex(); - int prevVertex=v0; + int prevVertex = v0; combinedFace.m_indices.push_back(v0); v1 = edge->getTargetVertex(); while (v1 != v0) { - btVector3 wa = conv.vertices[prevVertex]; btVector3 wb = conv.vertices[v1]; - btVector3 newEdge = wb-wa; + btVector3 newEdge = wb - wa; newEdge.normalize(); - if (numEdges<2) + if (numEdges < 2) edges[numEdges++] = newEdge; - //face->addIndex(v1); combinedFace.m_indices.push_back(v1); edge = edge->getNextEdgeOfFace(); prevVertex = v1; int v01 = edge->getSourceVertex(); v1 = edge->getTargetVertex(); - } - + btAssert(combinedFace.m_indices.size() > 2); btVector3 faceNormal = edges[0].cross(edges[1]); faceNormal.normalize(); - btScalar planeEq=1e30f; + btScalar planeEq = 1e30f; - for (int v=0;vm_vertices[combinedFace.m_indices[v]].dot(faceNormal); - if (planeEq>eq) + if (planeEq > eq) { - planeEq=eq; + planeEq = eq; } } combinedFace.m_plane[0] = faceNormal.getX(); combinedFace.m_plane[1] = faceNormal.getY(); combinedFace.m_plane[2] = faceNormal.getZ(); combinedFace.m_plane[3] = -planeEq; - + m_polyhedron->m_faces.push_back(combinedFace); } - -#else//BT_RECONSTRUCT_FACES +#else //BT_RECONSTRUCT_FACES btAlignedObjectArray faceNormals; int numFaces = conv.faces.size(); faceNormals.resize(numFaces); btConvexHullComputer* convexUtil = &conv; - - btAlignedObjectArray tmpFaces; + btAlignedObjectArray tmpFaces; tmpFaces.resize(numFaces); int numVertices = convexUtil->vertices.size(); m_polyhedron->m_vertices.resize(numVertices); - for (int p=0;pm_vertices[p] = convexUtil->vertices[p]; } - - for (int i=0;ifaces[i]; //printf("face=%d\n",face); - const btConvexHullComputer::Edge* firstEdge = &convexUtil->edges[face]; - const btConvexHullComputer::Edge* edge = firstEdge; + const btConvexHullComputer::Edge* firstEdge = &convexUtil->edges[face]; + const btConvexHullComputer::Edge* edge = firstEdge; btVector3 edges[3]; int numEdges = 0; @@ -194,25 +186,23 @@ bool btPolyhedralConvexShape::initializePolyhedralFeatures(int shiftVerticesByMa do { - int src = edge->getSourceVertex(); tmpFaces[i].m_indices.push_back(src); int targ = edge->getTargetVertex(); btVector3 wa = convexUtil->vertices[src]; btVector3 wb = convexUtil->vertices[targ]; - btVector3 newEdge = wb-wa; + btVector3 newEdge = wb - wa; newEdge.normalize(); - if (numEdges<2) + if (numEdges < 2) edges[numEdges++] = newEdge; edge = edge->getNextEdgeOfFace(); - } while (edge!=firstEdge); + } while (edge != firstEdge); btScalar planeEq = 1e30f; - - if (numEdges==2) + if (numEdges == 2) { faceNormals[i] = edges[0].cross(edges[1]); faceNormals[i].normalize(); @@ -220,20 +210,19 @@ bool btPolyhedralConvexShape::initializePolyhedralFeatures(int shiftVerticesByMa tmpFaces[i].m_plane[1] = faceNormals[i].getY(); tmpFaces[i].m_plane[2] = faceNormals[i].getZ(); tmpFaces[i].m_plane[3] = planeEq; - } else { - btAssert(0);//degenerate? + btAssert(0); //degenerate? faceNormals[i].setZero(); } - for (int v=0;vm_vertices[tmpFaces[i].m_indices[v]].dot(faceNormals[i]); - if (planeEq>eq) + if (planeEq > eq) { - planeEq=eq; + planeEq = eq; } } tmpFaces[i].m_plane[3] = -planeEq; @@ -241,89 +230,86 @@ bool btPolyhedralConvexShape::initializePolyhedralFeatures(int shiftVerticesByMa //merge coplanar faces and copy them to m_polyhedron - btScalar faceWeldThreshold= 0.999f; + btScalar faceWeldThreshold = 0.999f; btAlignedObjectArray todoFaces; - for (int i=0;i coplanarFaceGroup; - int refFace = todoFaces[todoFaces.size()-1]; + int refFace = todoFaces[todoFaces.size() - 1]; coplanarFaceGroup.push_back(refFace); btFace& faceA = tmpFaces[refFace]; todoFaces.pop_back(); - btVector3 faceNormalA(faceA.m_plane[0],faceA.m_plane[1],faceA.m_plane[2]); - for (int j=todoFaces.size()-1;j>=0;j--) + btVector3 faceNormalA(faceA.m_plane[0], faceA.m_plane[1], faceA.m_plane[2]); + for (int j = todoFaces.size() - 1; j >= 0; j--) { int i = todoFaces[j]; btFace& faceB = tmpFaces[i]; - btVector3 faceNormalB(faceB.m_plane[0],faceB.m_plane[1],faceB.m_plane[2]); - if (faceNormalA.dot(faceNormalB)>faceWeldThreshold) + btVector3 faceNormalB(faceB.m_plane[0], faceB.m_plane[1], faceB.m_plane[2]); + if (faceNormalA.dot(faceNormalB) > faceWeldThreshold) { coplanarFaceGroup.push_back(i); todoFaces.remove(i); } } - bool did_merge = false; - if (coplanarFaceGroup.size()>1) + if (coplanarFaceGroup.size() > 1) { //do the merge: use Graham Scan 2d convex hull btAlignedObjectArray orgpoints; - btVector3 averageFaceNormal(0,0,0); + btVector3 averageFaceNormal(0, 0, 0); - for (int i=0;im_faces.push_back(tmpFaces[coplanarFaceGroup[i]]); + // m_polyhedron->m_faces.push_back(tmpFaces[coplanarFaceGroup[i]]); btFace& face = tmpFaces[coplanarFaceGroup[i]]; - btVector3 faceNormal(face.m_plane[0],face.m_plane[1],face.m_plane[2]); - averageFaceNormal+=faceNormal; - for (int f=0;fm_vertices[orgIndex]; - + bool found = false; - for (int i=0;i hull; averageFaceNormal.normalize(); - GrahamScanConvexHull2D(orgpoints,hull,averageFaceNormal); + GrahamScanConvexHull2D(orgpoints, hull, averageFaceNormal); - for (int i=0;im_faces.push_back(combinedFace); } } - if(!did_merge) + if (!did_merge) { - for (int i=0;im_faces.push_back(face); } - - } - - - + } } -#endif //BT_RECONSTRUCT_FACES +#endif //BT_RECONSTRUCT_FACES m_polyhedron->initialize(); @@ -395,14 +380,12 @@ bool btPolyhedralConvexShape::initializePolyhedralFeatures(int shiftVerticesByMa } #ifndef MIN - #define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b)) +#define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b)) #endif -btVector3 btPolyhedralConvexShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0)const +btVector3 btPolyhedralConvexShape::localGetSupportingVertexWithoutMargin(const btVector3& vec0) const { - - - btVector3 supVec(0,0,0); + btVector3 supVec(0, 0, 0); #ifndef __SPU__ int i; btScalar maxDot(btScalar(-BT_LARGE_FLOAT)); @@ -411,37 +394,36 @@ btVector3 btPolyhedralConvexShape::localGetSupportingVertexWithoutMargin(const b btScalar lenSqr = vec.length2(); if (lenSqr < btScalar(0.0001)) { - vec.setValue(1,0,0); - } else + vec.setValue(1, 0, 0); + } + else { - btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); + btScalar rlen = btScalar(1.) / btSqrt(lenSqr); vec *= rlen; } btVector3 vtx; btScalar newDot; - for( int k = 0; k < getNumVertices(); k += 128 ) - { - btVector3 temp[128]; - int inner_count = MIN(getNumVertices() - k, 128); - for( i = 0; i < inner_count; i++ ) - getVertex(i,temp[i]); - i = (int) vec.maxDot( temp, inner_count, newDot); + for (int k = 0; k < getNumVertices(); k += 128) + { + btVector3 temp[128]; + int inner_count = MIN(getNumVertices() - k, 128); + for (i = 0; i < inner_count; i++) + getVertex(i, temp[i]); + i = (int)vec.maxDot(temp, inner_count, newDot); if (newDot > maxDot) { maxDot = newDot; supVec = temp[i]; - } - } - -#endif //__SPU__ + } + } + +#endif //__SPU__ return supVec; } - - -void btPolyhedralConvexShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +void btPolyhedralConvexShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const { #ifndef __SPU__ int i; @@ -449,36 +431,34 @@ void btPolyhedralConvexShape::batchedUnitVectorGetSupportingVertexWithoutMargin( btVector3 vtx; btScalar newDot; - for (i=0;i supportVerticesOut[j][3]) - { + const btVector3& vec = vectors[j]; + + for (int k = 0; k < getNumVertices(); k += 128) + { + btVector3 temp[128]; + int inner_count = MIN(getNumVertices() - k, 128); + for (i = 0; i < inner_count; i++) + getVertex(i, temp[i]); + i = (int)vec.maxDot(temp, inner_count, newDot); + if (newDot > supportVerticesOut[j][3]) + { supportVerticesOut[j] = temp[i]; supportVerticesOut[j][3] = newDot; - } - } - } + } + } + } -#endif //__SPU__ +#endif //__SPU__ } - - -void btPolyhedralConvexShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +void btPolyhedralConvexShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const { #ifndef __SPU__ //not yet, return box inertia @@ -487,81 +467,77 @@ void btPolyhedralConvexShape::calculateLocalInertia(btScalar mass,btVector3& ine btTransform ident; ident.setIdentity(); - btVector3 aabbMin,aabbMax; - getAabb(ident,aabbMin,aabbMax); - btVector3 halfExtents = (aabbMax-aabbMin)*btScalar(0.5); + btVector3 aabbMin, aabbMax; + getAabb(ident, aabbMin, aabbMax); + btVector3 halfExtents = (aabbMax - aabbMin) * btScalar(0.5); - btScalar lx=btScalar(2.)*(halfExtents.x()+margin); - btScalar ly=btScalar(2.)*(halfExtents.y()+margin); - btScalar lz=btScalar(2.)*(halfExtents.z()+margin); - const btScalar x2 = lx*lx; - const btScalar y2 = ly*ly; - const btScalar z2 = lz*lz; + btScalar lx = btScalar(2.) * (halfExtents.x() + margin); + btScalar ly = btScalar(2.) * (halfExtents.y() + margin); + btScalar lz = btScalar(2.) * (halfExtents.z() + margin); + const btScalar x2 = lx * lx; + const btScalar y2 = ly * ly; + const btScalar z2 = lz * lz; const btScalar scaledmass = mass * btScalar(0.08333333); - inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2)); -#endif //__SPU__ + inertia = scaledmass * (btVector3(y2 + z2, x2 + z2, x2 + y2)); +#endif //__SPU__ } - - -void btPolyhedralConvexAabbCachingShape::setLocalScaling(const btVector3& scaling) +void btPolyhedralConvexAabbCachingShape::setLocalScaling(const btVector3& scaling) { btConvexInternalShape::setLocalScaling(scaling); recalcLocalAabb(); } btPolyhedralConvexAabbCachingShape::btPolyhedralConvexAabbCachingShape() -:btPolyhedralConvexShape(), -m_localAabbMin(1,1,1), -m_localAabbMax(-1,-1,-1), -m_isLocalAabbValid(false) + : btPolyhedralConvexShape(), + m_localAabbMin(1, 1, 1), + m_localAabbMax(-1, -1, -1), + m_isLocalAabbValid(false) { } -void btPolyhedralConvexAabbCachingShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const +void btPolyhedralConvexAabbCachingShape::getAabb(const btTransform& trans, btVector3& aabbMin, btVector3& aabbMax) const { - getNonvirtualAabb(trans,aabbMin,aabbMax,getMargin()); + getNonvirtualAabb(trans, aabbMin, aabbMax, getMargin()); } -void btPolyhedralConvexAabbCachingShape::recalcLocalAabb() +void btPolyhedralConvexAabbCachingShape::recalcLocalAabb() { m_isLocalAabbValid = true; - - #if 1 + +#if 1 static const btVector3 _directions[] = - { - btVector3( 1., 0., 0.), - btVector3( 0., 1., 0.), - btVector3( 0., 0., 1.), - btVector3( -1., 0., 0.), - btVector3( 0., -1., 0.), - btVector3( 0., 0., -1.) - }; - + { + btVector3(1., 0., 0.), + btVector3(0., 1., 0.), + btVector3(0., 0., 1.), + btVector3(-1., 0., 0.), + btVector3(0., -1., 0.), + btVector3(0., 0., -1.)}; + btVector3 _supporting[] = - { - btVector3( 0., 0., 0.), - btVector3( 0., 0., 0.), - btVector3( 0., 0., 0.), - btVector3( 0., 0., 0.), - btVector3( 0., 0., 0.), - btVector3( 0., 0., 0.) - }; - + { + btVector3(0., 0., 0.), + btVector3(0., 0., 0.), + btVector3(0., 0., 0.), + btVector3(0., 0., 0.), + btVector3(0., 0., 0.), + btVector3(0., 0., 0.)}; + batchedUnitVectorGetSupportingVertexWithoutMargin(_directions, _supporting, 6); - - for ( int i = 0; i < 3; ++i ) + + for (int i = 0; i < 3; ++i) { m_localAabbMax[i] = _supporting[i][i] + m_collisionMargin; m_localAabbMin[i] = _supporting[i + 3][i] - m_collisionMargin; } - - #else - for (int i=0;i<3;i++) +#else + + for (int i = 0; i < 3; i++) { - btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); + btVector3 vec(btScalar(0.), btScalar(0.), btScalar(0.)); vec[i] = btScalar(1.); btVector3 tmp = localGetSupportingVertex(vec); m_localAabbMax[i] = tmp[i]; @@ -569,9 +545,5 @@ void btPolyhedralConvexAabbCachingShape::recalcLocalAabb() tmp = localGetSupportingVertex(vec); m_localAabbMin[i] = tmp[i]; } - #endif +#endif } - - - - diff --git a/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h b/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h index b7ddb6e06..b3ffab7a2 100644 --- a/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h +++ b/src/BulletCollision/CollisionShapes/btPolyhedralConvexShape.h @@ -20,20 +20,15 @@ subject to the following restrictions: #include "btConvexInternalShape.h" class btConvexPolyhedron; - ///The btPolyhedralConvexShape is an internal interface class for polyhedral convex shapes. -ATTRIBUTE_ALIGNED16(class) btPolyhedralConvexShape : public btConvexInternalShape +ATTRIBUTE_ALIGNED16(class) +btPolyhedralConvexShape : public btConvexInternalShape { - - protected: - btConvexPolyhedron* m_polyhedron; public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - btPolyhedralConvexShape(); @@ -41,55 +36,49 @@ public: ///optional method mainly used to generate multiple contact points by clipping polyhedral features (faces/edges) ///experimental/work-in-progress - virtual bool initializePolyhedralFeatures(int shiftVerticesByMargin=0); + virtual bool initializePolyhedralFeatures(int shiftVerticesByMargin = 0); - virtual void setPolyhedralFeatures(btConvexPolyhedron& polyhedron); - + virtual void setPolyhedralFeatures(btConvexPolyhedron & polyhedron); - const btConvexPolyhedron* getConvexPolyhedron() const + const btConvexPolyhedron* getConvexPolyhedron() const { return m_polyhedron; } //brute force implementations - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; - - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; - - - virtual int getNumVertices() const = 0 ; + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const; + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const; + + virtual void calculateLocalInertia(btScalar mass, btVector3 & inertia) const; + + virtual int getNumVertices() const = 0; virtual int getNumEdges() const = 0; - virtual void getEdge(int i,btVector3& pa,btVector3& pb) const = 0; - virtual void getVertex(int i,btVector3& vtx) const = 0; - virtual int getNumPlanes() const = 0; - virtual void getPlane(btVector3& planeNormal,btVector3& planeSupport,int i ) const = 0; -// virtual int getIndex(int i) const = 0 ; + virtual void getEdge(int i, btVector3& pa, btVector3& pb) const = 0; + virtual void getVertex(int i, btVector3& vtx) const = 0; + virtual int getNumPlanes() const = 0; + virtual void getPlane(btVector3 & planeNormal, btVector3 & planeSupport, int i) const = 0; + // virtual int getIndex(int i) const = 0 ; - virtual bool isInside(const btVector3& pt,btScalar tolerance) const = 0; - + virtual bool isInside(const btVector3& pt, btScalar tolerance) const = 0; }; - ///The btPolyhedralConvexAabbCachingShape adds aabb caching to the btPolyhedralConvexShape class btPolyhedralConvexAabbCachingShape : public btPolyhedralConvexShape { + btVector3 m_localAabbMin; + btVector3 m_localAabbMax; + bool m_isLocalAabbValid; - btVector3 m_localAabbMin; - btVector3 m_localAabbMax; - bool m_isLocalAabbValid; - protected: - - void setCachedLocalAabb (const btVector3& aabbMin, const btVector3& aabbMax) + void setCachedLocalAabb(const btVector3& aabbMin, const btVector3& aabbMax) { m_isLocalAabbValid = true; m_localAabbMin = aabbMin; m_localAabbMax = aabbMax; } - inline void getCachedLocalAabb (btVector3& aabbMin, btVector3& aabbMax) const + inline void getCachedLocalAabb(btVector3& aabbMin, btVector3& aabbMax) const { btAssert(m_isLocalAabbValid); aabbMin = m_localAabbMin; @@ -97,25 +86,21 @@ protected: } protected: - btPolyhedralConvexAabbCachingShape(); - -public: - - inline void getNonvirtualAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax, btScalar margin) const - { +public: + inline void getNonvirtualAabb(const btTransform& trans, btVector3& aabbMin, btVector3& aabbMax, btScalar margin) const + { //lazy evaluation of local aabb btAssert(m_isLocalAabbValid); - btTransformAabb(m_localAabbMin,m_localAabbMax,margin,trans,aabbMin,aabbMax); + btTransformAabb(m_localAabbMin, m_localAabbMax, margin, trans, aabbMin, aabbMax); } - virtual void setLocalScaling(const btVector3& scaling); + virtual void setLocalScaling(const btVector3& scaling); - virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; - - void recalcLocalAabb(); + virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const; + void recalcLocalAabb(); }; -#endif //BT_POLYHEDRAL_CONVEX_SHAPE_H +#endif //BT_POLYHEDRAL_CONVEX_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp b/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp index 6a337c786..f42731997 100644 --- a/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp +++ b/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.cpp @@ -13,11 +13,10 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btScaledBvhTriangleMeshShape.h" -btScaledBvhTriangleMeshShape::btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,const btVector3& localScaling) -:m_localScaling(localScaling),m_bvhTriMeshShape(childShape) +btScaledBvhTriangleMeshShape::btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape, const btVector3& localScaling) + : m_localScaling(localScaling), m_bvhTriMeshShape(childShape) { m_shapeType = SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE; } @@ -26,55 +25,51 @@ btScaledBvhTriangleMeshShape::~btScaledBvhTriangleMeshShape() { } - class btScaledTriangleCallback : public btTriangleCallback { btTriangleCallback* m_originalCallback; - btVector3 m_localScaling; + btVector3 m_localScaling; public: - - btScaledTriangleCallback(btTriangleCallback* originalCallback,const btVector3& localScaling) - :m_originalCallback(originalCallback), - m_localScaling(localScaling) + btScaledTriangleCallback(btTriangleCallback* originalCallback, const btVector3& localScaling) + : m_originalCallback(originalCallback), + m_localScaling(localScaling) { } virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) { btVector3 newTriangle[3]; - newTriangle[0] = triangle[0]*m_localScaling; - newTriangle[1] = triangle[1]*m_localScaling; - newTriangle[2] = triangle[2]*m_localScaling; - m_originalCallback->processTriangle(&newTriangle[0],partId,triangleIndex); + newTriangle[0] = triangle[0] * m_localScaling; + newTriangle[1] = triangle[1] * m_localScaling; + newTriangle[2] = triangle[2] * m_localScaling; + m_originalCallback->processTriangle(&newTriangle[0], partId, triangleIndex); } }; -void btScaledBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const +void btScaledBvhTriangleMeshShape::processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const { - btScaledTriangleCallback scaledCallback(callback,m_localScaling); - - btVector3 invLocalScaling(1.f/m_localScaling.getX(),1.f/m_localScaling.getY(),1.f/m_localScaling.getZ()); - btVector3 scaledAabbMin,scaledAabbMax; + btScaledTriangleCallback scaledCallback(callback, m_localScaling); + + btVector3 invLocalScaling(1.f / m_localScaling.getX(), 1.f / m_localScaling.getY(), 1.f / m_localScaling.getZ()); + btVector3 scaledAabbMin, scaledAabbMax; ///support negative scaling scaledAabbMin[0] = m_localScaling.getX() >= 0. ? aabbMin[0] * invLocalScaling[0] : aabbMax[0] * invLocalScaling[0]; scaledAabbMin[1] = m_localScaling.getY() >= 0. ? aabbMin[1] * invLocalScaling[1] : aabbMax[1] * invLocalScaling[1]; scaledAabbMin[2] = m_localScaling.getZ() >= 0. ? aabbMin[2] * invLocalScaling[2] : aabbMax[2] * invLocalScaling[2]; scaledAabbMin[3] = 0.f; - + scaledAabbMax[0] = m_localScaling.getX() <= 0. ? aabbMin[0] * invLocalScaling[0] : aabbMax[0] * invLocalScaling[0]; scaledAabbMax[1] = m_localScaling.getY() <= 0. ? aabbMin[1] * invLocalScaling[1] : aabbMax[1] * invLocalScaling[1]; scaledAabbMax[2] = m_localScaling.getZ() <= 0. ? aabbMin[2] * invLocalScaling[2] : aabbMax[2] * invLocalScaling[2]; scaledAabbMax[3] = 0.f; - - - m_bvhTriMeshShape->processAllTriangles(&scaledCallback,scaledAabbMin,scaledAabbMax); + + m_bvhTriMeshShape->processAllTriangles(&scaledCallback, scaledAabbMin, scaledAabbMax); } - -void btScaledBvhTriangleMeshShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const +void btScaledBvhTriangleMeshShape::getAabb(const btTransform& trans, btVector3& aabbMin, btVector3& aabbMax) const { btVector3 localAabbMin = m_bvhTriMeshShape->getLocalAabbMin(); btVector3 localAabbMax = m_bvhTriMeshShape->getLocalAabbMax(); @@ -89,22 +84,21 @@ void btScaledBvhTriangleMeshShape::getAabb(const btTransform& trans,btVector3& a localAabbMax[1] = (m_localScaling.getY() <= 0.) ? tmpLocalAabbMin[1] : tmpLocalAabbMax[1]; localAabbMax[2] = (m_localScaling.getZ() <= 0.) ? tmpLocalAabbMin[2] : tmpLocalAabbMax[2]; - btVector3 localHalfExtents = btScalar(0.5)*(localAabbMax-localAabbMin); + btVector3 localHalfExtents = btScalar(0.5) * (localAabbMax - localAabbMin); btScalar margin = m_bvhTriMeshShape->getMargin(); - localHalfExtents += btVector3(margin,margin,margin); - btVector3 localCenter = btScalar(0.5)*(localAabbMax+localAabbMin); - - btMatrix3x3 abs_b = trans.getBasis().absolute(); + localHalfExtents += btVector3(margin, margin, margin); + btVector3 localCenter = btScalar(0.5) * (localAabbMax + localAabbMin); + + btMatrix3x3 abs_b = trans.getBasis().absolute(); btVector3 center = trans(localCenter); - btVector3 extent = localHalfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); + btVector3 extent = localHalfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); aabbMin = center - extent; aabbMax = center + extent; - } -void btScaledBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling) +void btScaledBvhTriangleMeshShape::setLocalScaling(const btVector3& scaling) { m_localScaling = scaling; } @@ -114,8 +108,8 @@ const btVector3& btScaledBvhTriangleMeshShape::getLocalScaling() const return m_localScaling; } -void btScaledBvhTriangleMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +void btScaledBvhTriangleMeshShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const { ///don't make this a movable object! -// btAssert(0); + // btAssert(0); } diff --git a/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h b/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h index 39049eaf0..4d6feb61a 100644 --- a/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h +++ b/src/BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h @@ -18,78 +18,69 @@ subject to the following restrictions: #include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h" - ///The btScaledBvhTriangleMeshShape allows to instance a scaled version of an existing btBvhTriangleMeshShape. ///Note that each btBvhTriangleMeshShape still can have its own local scaling, independent from this btScaledBvhTriangleMeshShape 'localScaling' -ATTRIBUTE_ALIGNED16(class) btScaledBvhTriangleMeshShape : public btConcaveShape +ATTRIBUTE_ALIGNED16(class) +btScaledBvhTriangleMeshShape : public btConcaveShape { - - - btVector3 m_localScaling; + btVector3 m_localScaling; - btBvhTriangleMeshShape* m_bvhTriMeshShape; + btBvhTriangleMeshShape* m_bvhTriMeshShape; public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - - btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape* childShape,const btVector3& localScaling); + btScaledBvhTriangleMeshShape(btBvhTriangleMeshShape * childShape, const btVector3& localScaling); virtual ~btScaledBvhTriangleMeshShape(); - - virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; - virtual void setLocalScaling(const btVector3& scaling); + virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const; + virtual void setLocalScaling(const btVector3& scaling); virtual const btVector3& getLocalScaling() const; - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + virtual void calculateLocalInertia(btScalar mass, btVector3 & inertia) const; - virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + virtual void processAllTriangles(btTriangleCallback * callback, const btVector3& aabbMin, const btVector3& aabbMax) const; - btBvhTriangleMeshShape* getChildShape() + btBvhTriangleMeshShape* getChildShape() { return m_bvhTriMeshShape; } - const btBvhTriangleMeshShape* getChildShape() const + const btBvhTriangleMeshShape* getChildShape() const { return m_bvhTriMeshShape; } //debugging - virtual const char* getName()const {return "SCALEDBVHTRIANGLEMESH";} + virtual const char* getName() const { return "SCALEDBVHTRIANGLEMESH"; } - virtual int calculateSerializeBufferSize() const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; - + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; }; ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 -struct btScaledTriangleMeshShapeData +struct btScaledTriangleMeshShapeData { - btTriangleMeshShapeData m_trimeshShapeData; + btTriangleMeshShapeData m_trimeshShapeData; - btVector3FloatData m_localScaling; + btVector3FloatData m_localScaling; }; - -SIMD_FORCE_INLINE int btScaledBvhTriangleMeshShape::calculateSerializeBufferSize() const +SIMD_FORCE_INLINE int btScaledBvhTriangleMeshShape::calculateSerializeBufferSize() const { return sizeof(btScaledTriangleMeshShapeData); } - ///fills the dataBuffer and returns the struct name (and 0 on failure) -SIMD_FORCE_INLINE const char* btScaledBvhTriangleMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const +SIMD_FORCE_INLINE const char* btScaledBvhTriangleMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const { - btScaledTriangleMeshShapeData* scaledMeshData = (btScaledTriangleMeshShapeData*) dataBuffer; - m_bvhTriMeshShape->serialize(&scaledMeshData->m_trimeshShapeData,serializer); + btScaledTriangleMeshShapeData* scaledMeshData = (btScaledTriangleMeshShapeData*)dataBuffer; + m_bvhTriMeshShape->serialize(&scaledMeshData->m_trimeshShapeData, serializer); scaledMeshData->m_trimeshShapeData.m_collisionShapeData.m_shapeType = SCALED_TRIANGLE_MESH_SHAPE_PROXYTYPE; m_localScaling.serializeFloat(scaledMeshData->m_localScaling); return "btScaledTriangleMeshShapeData"; } - -#endif //BT_SCALED_BVH_TRIANGLE_MESH_SHAPE_H +#endif //BT_SCALED_BVH_TRIANGLE_MESH_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btSdfCollisionShape.cpp b/src/BulletCollision/CollisionShapes/btSdfCollisionShape.cpp index 828acda47..4a95dbea4 100644 --- a/src/BulletCollision/CollisionShapes/btSdfCollisionShape.cpp +++ b/src/BulletCollision/CollisionShapes/btSdfCollisionShape.cpp @@ -9,10 +9,9 @@ struct btSdfCollisionShapeInternalData btMiniSDF m_sdf; btSdfCollisionShapeInternalData() - :m_localScaling(1,1,1), - m_margin(0) + : m_localScaling(1, 1, 1), + m_margin(0) { - } }; @@ -26,8 +25,6 @@ btSdfCollisionShape::btSdfCollisionShape() m_shapeType = SDF_SHAPE_PROXYTYPE; m_data = new btSdfCollisionShapeInternalData(); - - //"E:/develop/bullet3/data/toys/ground_hole64_64_8.cdf");//ground_cube.cdf"); /*unsigned int field_id=0; Eigen::Vector3d x (1,10,1); @@ -35,25 +32,22 @@ btSdfCollisionShape::btSdfCollisionShape() double dist = m_data->m_sdf.interpolate(field_id, x, &gradient); printf("dist=%g\n", dist); */ - } btSdfCollisionShape::~btSdfCollisionShape() { delete m_data; } -void btSdfCollisionShape::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +void btSdfCollisionShape::getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const { btAssert(m_data->m_sdf.isValid()); btVector3 localAabbMin = m_data->m_sdf.m_domain.m_min; btVector3 localAabbMax = m_data->m_sdf.m_domain.m_max; btScalar margin(0); - btTransformAabb(localAabbMin,localAabbMax,margin,t,aabbMin,aabbMax); - + btTransformAabb(localAabbMin, localAabbMax, margin, t, aabbMin, aabbMax); } - -void btSdfCollisionShape::setLocalScaling(const btVector3& scaling) +void btSdfCollisionShape::setLocalScaling(const btVector3& scaling) { m_data->m_localScaling = scaling; } @@ -61,39 +55,38 @@ const btVector3& btSdfCollisionShape::getLocalScaling() const { return m_data->m_localScaling; } -void btSdfCollisionShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +void btSdfCollisionShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const { - inertia.setValue(0,0,0); + inertia.setValue(0, 0, 0); } -const char* btSdfCollisionShape::getName()const +const char* btSdfCollisionShape::getName() const { return "btSdfCollisionShape"; } -void btSdfCollisionShape::setMargin(btScalar margin) +void btSdfCollisionShape::setMargin(btScalar margin) { m_data->m_margin = margin; } -btScalar btSdfCollisionShape::getMargin() const +btScalar btSdfCollisionShape::getMargin() const { return m_data->m_margin; } -void btSdfCollisionShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const +void btSdfCollisionShape::processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const { //not yet } - bool btSdfCollisionShape::queryPoint(const btVector3& ptInSDF, btScalar& distOut, btVector3& normal) { int field = 0; btVector3 grad; double dist; - bool hasResult = m_data->m_sdf.interpolate(field,dist, ptInSDF,&grad); + bool hasResult = m_data->m_sdf.interpolate(field, dist, ptInSDF, &grad); if (hasResult) { - normal.setValue(grad[0],grad[1],grad[2]); - distOut= dist; + normal.setValue(grad[0], grad[1], grad[2]); + distOut = dist; } return hasResult; } diff --git a/src/BulletCollision/CollisionShapes/btSdfCollisionShape.h b/src/BulletCollision/CollisionShapes/btSdfCollisionShape.h index 6e32db9cd..3989d6245 100644 --- a/src/BulletCollision/CollisionShapes/btSdfCollisionShape.h +++ b/src/BulletCollision/CollisionShapes/btSdfCollisionShape.h @@ -8,23 +8,22 @@ class btSdfCollisionShape : public btConcaveShape struct btSdfCollisionShapeInternalData* m_data; public: - btSdfCollisionShape(); virtual ~btSdfCollisionShape(); - + bool initializeSDF(const char* sdfData, int sizeInBytes); - virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; - virtual void setLocalScaling(const btVector3& scaling); + virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const; + virtual void setLocalScaling(const btVector3& scaling); virtual const btVector3& getLocalScaling() const; - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; - virtual const char* getName()const; - virtual void setMargin(btScalar margin); - virtual btScalar getMargin() const; + virtual void calculateLocalInertia(btScalar mass, btVector3& inertia) const; + virtual const char* getName() const; + virtual void setMargin(btScalar margin); + virtual btScalar getMargin() const; - virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + virtual void processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const; bool queryPoint(const btVector3& ptInSDF, btScalar& distOut, btVector3& normal); }; -#endif //BT_SDF_COLLISION_SHAPE_H +#endif //BT_SDF_COLLISION_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btShapeHull.cpp b/src/BulletCollision/CollisionShapes/btShapeHull.cpp index 9f712fe55..8f44e31f1 100644 --- a/src/BulletCollision/CollisionShapes/btShapeHull.cpp +++ b/src/BulletCollision/CollisionShapes/btShapeHull.cpp @@ -15,47 +15,44 @@ subject to the following restrictions: //btShapeHull was implemented by John McCutchan. - #include "btShapeHull.h" #include "LinearMath/btConvexHull.h" #define NUM_UNITSPHERE_POINTS 42 #define NUM_UNITSPHERE_POINTS_HIGHRES 256 - -btShapeHull::btShapeHull (const btConvexShape* shape) +btShapeHull::btShapeHull(const btConvexShape* shape) { m_shape = shape; - m_vertices.clear (); + m_vertices.clear(); m_indices.clear(); m_numIndices = 0; } -btShapeHull::~btShapeHull () +btShapeHull::~btShapeHull() { - m_indices.clear(); - m_vertices.clear (); + m_indices.clear(); + m_vertices.clear(); } -bool -btShapeHull::buildHull (btScalar /*margin*/, int highres) +bool btShapeHull::buildHull(btScalar /*margin*/, int highres) { - int numSampleDirections = highres? NUM_UNITSPHERE_POINTS_HIGHRES:NUM_UNITSPHERE_POINTS; + int numSampleDirections = highres ? NUM_UNITSPHERE_POINTS_HIGHRES : NUM_UNITSPHERE_POINTS; { int numPDA = m_shape->getNumPreferredPenetrationDirections(); if (numPDA) { - for (int i=0;igetPreferredPenetrationDirection(i,norm); + m_shape->getPreferredPenetrationDirection(i, norm); getUnitSpherePoints(highres)[numSampleDirections] = norm; numSampleDirections++; } } } - btVector3 supportPoints[NUM_UNITSPHERE_POINTS_HIGHRES+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; + btVector3 supportPoints[NUM_UNITSPHERE_POINTS_HIGHRES + MAX_PREFERRED_PENETRATION_DIRECTIONS * 2]; int i; for (i = 0; i < numSampleDirections; i++) { @@ -71,18 +68,17 @@ btShapeHull::buildHull (btScalar /*margin*/, int highres) hd.mVertexStride = sizeof(btVector3); #else hd.mVertices = &supportPoints[0]; - hd.mVertexStride = sizeof (btVector3); + hd.mVertexStride = sizeof(btVector3); #endif HullLibrary hl; HullResult hr; - if (hl.CreateConvexHull (hd, hr) == QE_FAIL) + if (hl.CreateConvexHull(hd, hr) == QE_FAIL) { return false; } - m_vertices.resize (static_cast(hr.mNumOutputVertices)); - + m_vertices.resize(static_cast(hr.mNumOutputVertices)); for (i = 0; i < static_cast(hr.mNumOutputVertices); i++) { @@ -96,338 +92,332 @@ btShapeHull::buildHull (btScalar /*margin*/, int highres) } // free temporary hull result that we just copied - hl.ReleaseResult (hr); + hl.ReleaseResult(hr); return true; } -int -btShapeHull::numTriangles () const +int btShapeHull::numTriangles() const { return static_cast(m_numIndices / 3); } -int -btShapeHull::numVertices () const +int btShapeHull::numVertices() const { - return m_vertices.size (); + return m_vertices.size(); } -int -btShapeHull::numIndices () const +int btShapeHull::numIndices() const { return static_cast(m_numIndices); } - btVector3* btShapeHull::getUnitSpherePoints(int highres) { static btVector3 sUnitSpherePointsHighres[NUM_UNITSPHERE_POINTS_HIGHRES + MAX_PREFERRED_PENETRATION_DIRECTIONS * 2] = - { - btVector3(btScalar(0.997604), btScalar(0.067004), btScalar(0.017144)), - btVector3(btScalar(0.984139), btScalar(-0.086784), btScalar(-0.154427)), - btVector3(btScalar(0.971065), btScalar(0.124164), btScalar(-0.203224)), - btVector3(btScalar(0.955844), btScalar(0.291173), btScalar(-0.037704)), - btVector3(btScalar(0.957405), btScalar(0.212238), btScalar(0.195157)), - btVector3(btScalar(0.971650), btScalar(-0.012709), btScalar(0.235561)), - btVector3(btScalar(0.984920), btScalar(-0.161831), btScalar(0.059695)), - btVector3(btScalar(0.946673), btScalar(-0.299288), btScalar(-0.117536)), - btVector3(btScalar(0.922670), btScalar(-0.219186), btScalar(-0.317019)), - btVector3(btScalar(0.928134), btScalar(-0.007265), btScalar(-0.371867)), - btVector3(btScalar(0.875642), btScalar(0.198434), btScalar(-0.439988)), - btVector3(btScalar(0.908035), btScalar(0.325975), btScalar(-0.262562)), - btVector3(btScalar(0.864519), btScalar(0.488706), btScalar(-0.116755)), - btVector3(btScalar(0.893009), btScalar(0.428046), btScalar(0.137185)), - btVector3(btScalar(0.857494), btScalar(0.362137), btScalar(0.364776)), - btVector3(btScalar(0.900815), btScalar(0.132524), btScalar(0.412987)), - btVector3(btScalar(0.934964), btScalar(-0.241739), btScalar(0.259179)), - btVector3(btScalar(0.894570), btScalar(-0.103504), btScalar(0.434263)), - btVector3(btScalar(0.922085), btScalar(-0.376668), btScalar(0.086241)), - btVector3(btScalar(0.862177), btScalar(-0.499154), btScalar(-0.085330)), - btVector3(btScalar(0.861982), btScalar(-0.420218), btScalar(-0.282861)), - btVector3(btScalar(0.818076), btScalar(-0.328256), btScalar(-0.471804)), - btVector3(btScalar(0.762657), btScalar(-0.179329), btScalar(-0.621124)), - btVector3(btScalar(0.826857), btScalar(0.019760), btScalar(-0.561786)), - btVector3(btScalar(0.731434), btScalar(0.206599), btScalar(-0.649817)), - btVector3(btScalar(0.769486), btScalar(0.379052), btScalar(-0.513770)), - btVector3(btScalar(0.796806), btScalar(0.507176), btScalar(-0.328145)), - btVector3(btScalar(0.679722), btScalar(0.684101), btScalar(-0.264123)), - btVector3(btScalar(0.786854), btScalar(0.614886), btScalar(0.050912)), - btVector3(btScalar(0.769486), btScalar(0.571141), btScalar(0.285139)), - btVector3(btScalar(0.707432), btScalar(0.492789), btScalar(0.506288)), - btVector3(btScalar(0.774560), btScalar(0.268037), btScalar(0.572652)), - btVector3(btScalar(0.796220), btScalar(0.031230), btScalar(0.604077)), - btVector3(btScalar(0.837395), btScalar(-0.320285), btScalar(0.442461)), - btVector3(btScalar(0.848127), btScalar(-0.450548), btScalar(0.278307)), - btVector3(btScalar(0.775536), btScalar(-0.206354), btScalar(0.596465)), - btVector3(btScalar(0.816320), btScalar(-0.567007), btScalar(0.109469)), - btVector3(btScalar(0.741191), btScalar(-0.668690), btScalar(-0.056832)), - btVector3(btScalar(0.755632), btScalar(-0.602975), btScalar(-0.254949)), - btVector3(btScalar(0.720311), btScalar(-0.521318), btScalar(-0.457165)), - btVector3(btScalar(0.670746), btScalar(-0.386583), btScalar(-0.632835)), - btVector3(btScalar(0.587031), btScalar(-0.219769), btScalar(-0.778836)), - btVector3(btScalar(0.676015), btScalar(-0.003182), btScalar(-0.736676)), - btVector3(btScalar(0.566932), btScalar(0.186963), btScalar(-0.802064)), - btVector3(btScalar(0.618254), btScalar(0.398105), btScalar(-0.677533)), - btVector3(btScalar(0.653964), btScalar(0.575224), btScalar(-0.490933)), - btVector3(btScalar(0.525367), btScalar(0.743205), btScalar(-0.414028)), - btVector3(btScalar(0.506439), btScalar(0.836528), btScalar(-0.208885)), - btVector3(btScalar(0.651427), btScalar(0.756426), btScalar(-0.056247)), - btVector3(btScalar(0.641670), btScalar(0.745149), btScalar(0.180908)), - btVector3(btScalar(0.602643), btScalar(0.687211), btScalar(0.405180)), - btVector3(btScalar(0.516586), btScalar(0.596999), btScalar(0.613447)), - btVector3(btScalar(0.602252), btScalar(0.387801), btScalar(0.697573)), - btVector3(btScalar(0.646549), btScalar(0.153911), btScalar(0.746956)), - btVector3(btScalar(0.650842), btScalar(-0.087756), btScalar(0.753983)), - btVector3(btScalar(0.740411), btScalar(-0.497404), btScalar(0.451830)), - btVector3(btScalar(0.726946), btScalar(-0.619890), btScalar(0.295093)), - btVector3(btScalar(0.637768), btScalar(-0.313092), btScalar(0.703624)), - btVector3(btScalar(0.678942), btScalar(-0.722934), btScalar(0.126645)), - btVector3(btScalar(0.489072), btScalar(-0.867195), btScalar(-0.092942)), - btVector3(btScalar(0.622742), btScalar(-0.757541), btScalar(-0.194636)), - btVector3(btScalar(0.596788), btScalar(-0.693576), btScalar(-0.403098)), - btVector3(btScalar(0.550150), btScalar(-0.582172), btScalar(-0.598287)), - btVector3(btScalar(0.474436), btScalar(-0.429745), btScalar(-0.768101)), - btVector3(btScalar(0.372574), btScalar(-0.246016), btScalar(-0.894583)), - btVector3(btScalar(0.480095), btScalar(-0.026513), btScalar(-0.876626)), - btVector3(btScalar(0.352474), btScalar(0.177242), btScalar(-0.918787)), - btVector3(btScalar(0.441848), btScalar(0.374386), btScalar(-0.814946)), - btVector3(btScalar(0.492389), btScalar(0.582223), btScalar(-0.646693)), - btVector3(btScalar(0.343498), btScalar(0.866080), btScalar(-0.362693)), - btVector3(btScalar(0.362036), btScalar(0.745149), btScalar(-0.559639)), - btVector3(btScalar(0.334131), btScalar(0.937044), btScalar(-0.099774)), - btVector3(btScalar(0.486925), btScalar(0.871718), btScalar(0.052473)), - btVector3(btScalar(0.452776), btScalar(0.845665), btScalar(0.281820)), - btVector3(btScalar(0.399503), btScalar(0.771785), btScalar(0.494576)), - btVector3(btScalar(0.296469), btScalar(0.673018), btScalar(0.677469)), - btVector3(btScalar(0.392088), btScalar(0.479179), btScalar(0.785213)), - btVector3(btScalar(0.452190), btScalar(0.252094), btScalar(0.855286)), - btVector3(btScalar(0.478339), btScalar(0.013149), btScalar(0.877928)), - btVector3(btScalar(0.481656), btScalar(-0.219380), btScalar(0.848259)), - btVector3(btScalar(0.615327), btScalar(-0.494293), btScalar(0.613837)), - btVector3(btScalar(0.594642), btScalar(-0.650414), btScalar(0.472325)), - btVector3(btScalar(0.562249), btScalar(-0.771345), btScalar(0.297631)), - btVector3(btScalar(0.467411), btScalar(-0.437133), btScalar(0.768231)), - btVector3(btScalar(0.519513), btScalar(-0.847947), btScalar(0.103808)), - btVector3(btScalar(0.297640), btScalar(-0.938159), btScalar(-0.176288)), - btVector3(btScalar(0.446727), btScalar(-0.838615), btScalar(-0.311359)), - btVector3(btScalar(0.331790), btScalar(-0.942437), btScalar(0.040762)), - btVector3(btScalar(0.413358), btScalar(-0.748403), btScalar(-0.518259)), - btVector3(btScalar(0.347596), btScalar(-0.621640), btScalar(-0.701737)), - btVector3(btScalar(0.249831), btScalar(-0.456186), btScalar(-0.853984)), - btVector3(btScalar(0.131772), btScalar(-0.262931), btScalar(-0.955678)), - btVector3(btScalar(0.247099), btScalar(-0.042261), btScalar(-0.967975)), - btVector3(btScalar(0.113624), btScalar(0.165965), btScalar(-0.979491)), - btVector3(btScalar(0.217438), btScalar(0.374580), btScalar(-0.901220)), - btVector3(btScalar(0.307983), btScalar(0.554615), btScalar(-0.772786)), - btVector3(btScalar(0.166702), btScalar(0.953181), btScalar(-0.252021)), - btVector3(btScalar(0.172751), btScalar(0.844499), btScalar(-0.506743)), - btVector3(btScalar(0.177630), btScalar(0.711125), btScalar(-0.679876)), - btVector3(btScalar(0.120064), btScalar(0.992260), btScalar(-0.030482)), - btVector3(btScalar(0.289640), btScalar(0.949098), btScalar(0.122546)), - btVector3(btScalar(0.239879), btScalar(0.909047), btScalar(0.340377)), - btVector3(btScalar(0.181142), btScalar(0.821363), btScalar(0.540641)), - btVector3(btScalar(0.066986), btScalar(0.719097), btScalar(0.691327)), - btVector3(btScalar(0.156750), btScalar(0.545478), btScalar(0.823079)), - btVector3(btScalar(0.236172), btScalar(0.342306), btScalar(0.909353)), - btVector3(btScalar(0.277541), btScalar(0.112693), btScalar(0.953856)), - btVector3(btScalar(0.295299), btScalar(-0.121974), btScalar(0.947415)), - btVector3(btScalar(0.287883), btScalar(-0.349254), btScalar(0.891591)), - btVector3(btScalar(0.437165), btScalar(-0.634666), btScalar(0.636869)), - btVector3(btScalar(0.407113), btScalar(-0.784954), btScalar(0.466664)), - btVector3(btScalar(0.375111), btScalar(-0.888193), btScalar(0.264839)), - btVector3(btScalar(0.275394), btScalar(-0.560591), btScalar(0.780723)), - btVector3(btScalar(0.122015), btScalar(-0.992209), btScalar(-0.024821)), - btVector3(btScalar(0.087866), btScalar(-0.966156), btScalar(-0.241676)), - btVector3(btScalar(0.239489), btScalar(-0.885665), btScalar(-0.397437)), - btVector3(btScalar(0.167287), btScalar(-0.965184), btScalar(0.200817)), - btVector3(btScalar(0.201632), btScalar(-0.776789), btScalar(-0.596335)), - btVector3(btScalar(0.122015), btScalar(-0.637971), btScalar(-0.760098)), - btVector3(btScalar(0.008054), btScalar(-0.464741), btScalar(-0.885214)), - btVector3(btScalar(-0.116054), btScalar(-0.271096), btScalar(-0.955482)), - btVector3(btScalar(-0.000727), btScalar(-0.056065), btScalar(-0.998424)), - btVector3(btScalar(-0.134007), btScalar(0.152939), btScalar(-0.978905)), - btVector3(btScalar(-0.025900), btScalar(0.366026), btScalar(-0.930108)), - btVector3(btScalar(0.081231), btScalar(0.557337), btScalar(-0.826072)), - btVector3(btScalar(-0.002874), btScalar(0.917213), btScalar(-0.398023)), - btVector3(btScalar(-0.050683), btScalar(0.981761), btScalar(-0.182534)), - btVector3(btScalar(-0.040536), btScalar(0.710153), btScalar(-0.702713)), - btVector3(btScalar(-0.139081), btScalar(0.827973), btScalar(-0.543048)), - btVector3(btScalar(-0.101029), btScalar(0.994010), btScalar(0.041152)), - btVector3(btScalar(0.069328), btScalar(0.978067), btScalar(0.196133)), - btVector3(btScalar(0.023860), btScalar(0.911380), btScalar(0.410645)), - btVector3(btScalar(-0.153521), btScalar(0.736789), btScalar(0.658145)), - btVector3(btScalar(-0.070002), btScalar(0.591750), btScalar(0.802780)), - btVector3(btScalar(0.002590), btScalar(0.312948), btScalar(0.949562)), - btVector3(btScalar(0.090988), btScalar(-0.020680), btScalar(0.995627)), - btVector3(btScalar(0.088842), btScalar(-0.250099), btScalar(0.964006)), - btVector3(btScalar(0.083378), btScalar(-0.470185), btScalar(0.878318)), - btVector3(btScalar(0.240074), btScalar(-0.749764), btScalar(0.616374)), - btVector3(btScalar(0.210803), btScalar(-0.885860), btScalar(0.412987)), - btVector3(btScalar(0.077524), btScalar(-0.660524), btScalar(0.746565)), - btVector3(btScalar(-0.096736), btScalar(-0.990070), btScalar(-0.100945)), - btVector3(btScalar(-0.052634), btScalar(-0.990264), btScalar(0.127426)), - btVector3(btScalar(-0.106102), btScalar(-0.938354), btScalar(-0.328340)), - btVector3(btScalar(0.013323), btScalar(-0.863112), btScalar(-0.504596)), - btVector3(btScalar(-0.002093), btScalar(-0.936993), btScalar(0.349161)), - btVector3(btScalar(-0.106297), btScalar(-0.636610), btScalar(-0.763612)), - btVector3(btScalar(-0.229430), btScalar(-0.463769), btScalar(-0.855546)), - btVector3(btScalar(-0.245236), btScalar(-0.066175), btScalar(-0.966999)), - btVector3(btScalar(-0.351587), btScalar(-0.270513), btScalar(-0.896145)), - btVector3(btScalar(-0.370906), btScalar(0.133108), btScalar(-0.918982)), - btVector3(btScalar(-0.264360), btScalar(0.346000), btScalar(-0.900049)), - btVector3(btScalar(-0.151375), btScalar(0.543728), btScalar(-0.825291)), - btVector3(btScalar(-0.218697), btScalar(0.912741), btScalar(-0.344346)), - btVector3(btScalar(-0.274507), btScalar(0.953764), btScalar(-0.121635)), - btVector3(btScalar(-0.259677), btScalar(0.692266), btScalar(-0.673044)), - btVector3(btScalar(-0.350416), btScalar(0.798810), btScalar(-0.488786)), - btVector3(btScalar(-0.320170), btScalar(0.941127), btScalar(0.108297)), - btVector3(btScalar(-0.147667), btScalar(0.952792), btScalar(0.265034)), - btVector3(btScalar(-0.188061), btScalar(0.860636), btScalar(0.472910)), - btVector3(btScalar(-0.370906), btScalar(0.739900), btScalar(0.560941)), - btVector3(btScalar(-0.297143), btScalar(0.585334), btScalar(0.754178)), - btVector3(btScalar(-0.189622), btScalar(0.428241), btScalar(0.883393)), - btVector3(btScalar(-0.091272), btScalar(0.098695), btScalar(0.990747)), - btVector3(btScalar(-0.256945), btScalar(0.228375), btScalar(0.938827)), - btVector3(btScalar(-0.111761), btScalar(-0.133251), btScalar(0.984696)), - btVector3(btScalar(-0.118006), btScalar(-0.356253), btScalar(0.926725)), - btVector3(btScalar(-0.119372), btScalar(-0.563896), btScalar(0.817029)), - btVector3(btScalar(0.041228), btScalar(-0.833949), btScalar(0.550010)), - btVector3(btScalar(-0.121909), btScalar(-0.736543), btScalar(0.665172)), - btVector3(btScalar(-0.307681), btScalar(-0.931160), btScalar(-0.195026)), - btVector3(btScalar(-0.283679), btScalar(-0.957990), btScalar(0.041348)), - btVector3(btScalar(-0.227284), btScalar(-0.935243), btScalar(0.270890)), - btVector3(btScalar(-0.293436), btScalar(-0.858252), btScalar(-0.420860)), - btVector3(btScalar(-0.175767), btScalar(-0.780677), btScalar(-0.599262)), - btVector3(btScalar(-0.170108), btScalar(-0.858835), btScalar(0.482865)), - btVector3(btScalar(-0.332854), btScalar(-0.635055), btScalar(-0.696857)), - btVector3(btScalar(-0.447791), btScalar(-0.445299), btScalar(-0.775128)), - btVector3(btScalar(-0.470622), btScalar(-0.074146), btScalar(-0.879164)), - btVector3(btScalar(-0.639417), btScalar(-0.340505), btScalar(-0.689049)), - btVector3(btScalar(-0.598438), btScalar(0.104722), btScalar(-0.794256)), - btVector3(btScalar(-0.488575), btScalar(0.307699), btScalar(-0.816313)), - btVector3(btScalar(-0.379882), btScalar(0.513592), btScalar(-0.769077)), - btVector3(btScalar(-0.425740), btScalar(0.862775), btScalar(-0.272516)), - btVector3(btScalar(-0.480769), btScalar(0.875412), btScalar(-0.048439)), - btVector3(btScalar(-0.467890), btScalar(0.648716), btScalar(-0.600043)), - btVector3(btScalar(-0.543799), btScalar(0.730956), btScalar(-0.411881)), - btVector3(btScalar(-0.516284), btScalar(0.838277), btScalar(0.174076)), - btVector3(btScalar(-0.353343), btScalar(0.876384), btScalar(0.326519)), - btVector3(btScalar(-0.572875), btScalar(0.614497), btScalar(0.542007)), - btVector3(btScalar(-0.503600), btScalar(0.497261), btScalar(0.706161)), - btVector3(btScalar(-0.530920), btScalar(0.754870), btScalar(0.384685)), - btVector3(btScalar(-0.395884), btScalar(0.366414), btScalar(0.841818)), - btVector3(btScalar(-0.300656), btScalar(0.001678), btScalar(0.953661)), - btVector3(btScalar(-0.461060), btScalar(0.146912), btScalar(0.875000)), - btVector3(btScalar(-0.315486), btScalar(-0.232212), btScalar(0.919893)), - btVector3(btScalar(-0.323682), btScalar(-0.449187), btScalar(0.832644)), - btVector3(btScalar(-0.318999), btScalar(-0.639527), btScalar(0.699134)), - btVector3(btScalar(-0.496771), btScalar(-0.866029), btScalar(-0.055271)), - btVector3(btScalar(-0.496771), btScalar(-0.816257), btScalar(-0.294377)), - btVector3(btScalar(-0.456377), btScalar(-0.869528), btScalar(0.188130)), - btVector3(btScalar(-0.380858), btScalar(-0.827144), btScalar(0.412792)), - btVector3(btScalar(-0.449352), btScalar(-0.727405), btScalar(-0.518259)), - btVector3(btScalar(-0.570533), btScalar(-0.551064), btScalar(-0.608632)), - btVector3(btScalar(-0.656394), btScalar(-0.118280), btScalar(-0.744874)), - btVector3(btScalar(-0.756696), btScalar(-0.438105), btScalar(-0.484882)), - btVector3(btScalar(-0.801773), btScalar(-0.204798), btScalar(-0.561005)), - btVector3(btScalar(-0.785186), btScalar(0.038618), btScalar(-0.617805)), - btVector3(btScalar(-0.709082), btScalar(0.262399), btScalar(-0.654306)), - btVector3(btScalar(-0.583412), btScalar(0.462265), btScalar(-0.667383)), - btVector3(btScalar(-0.616001), btScalar(0.761286), btScalar(-0.201272)), - btVector3(btScalar(-0.660687), btScalar(0.750204), btScalar(0.020072)), - btVector3(btScalar(-0.744987), btScalar(0.435823), btScalar(-0.504791)), - btVector3(btScalar(-0.713765), btScalar(0.605554), btScalar(-0.351373)), - btVector3(btScalar(-0.686251), btScalar(0.687600), btScalar(0.236927)), - btVector3(btScalar(-0.680201), btScalar(0.429407), btScalar(0.593732)), - btVector3(btScalar(-0.733474), btScalar(0.546450), btScalar(0.403814)), - btVector3(btScalar(-0.591023), btScalar(0.292923), btScalar(0.751445)), - btVector3(btScalar(-0.500283), btScalar(-0.080757), btScalar(0.861922)), - btVector3(btScalar(-0.643710), btScalar(0.070115), btScalar(0.761985)), - btVector3(btScalar(-0.506332), btScalar(-0.308425), btScalar(0.805122)), - btVector3(btScalar(-0.503015), btScalar(-0.509847), btScalar(0.697573)), - btVector3(btScalar(-0.482525), btScalar(-0.682105), btScalar(0.549229)), - btVector3(btScalar(-0.680396), btScalar(-0.716323), btScalar(-0.153451)), - btVector3(btScalar(-0.658346), btScalar(-0.746264), btScalar(0.097562)), - btVector3(btScalar(-0.653272), btScalar(-0.646915), btScalar(-0.392948)), - btVector3(btScalar(-0.590828), btScalar(-0.732655), btScalar(0.337645)), - btVector3(btScalar(-0.819140), btScalar(-0.518013), btScalar(-0.246166)), - btVector3(btScalar(-0.900513), btScalar(-0.282178), btScalar(-0.330487)), - btVector3(btScalar(-0.914953), btScalar(-0.028652), btScalar(-0.402122)), - btVector3(btScalar(-0.859924), btScalar(0.220209), btScalar(-0.459898)), - btVector3(btScalar(-0.777185), btScalar(0.613720), btScalar(-0.137836)), - btVector3(btScalar(-0.805285), btScalar(0.586889), btScalar(0.082728)), - btVector3(btScalar(-0.872413), btScalar(0.406077), btScalar(-0.271735)), - btVector3(btScalar(-0.859339), btScalar(0.448072), btScalar(0.246101)), - btVector3(btScalar(-0.757671), btScalar(0.216320), btScalar(0.615594)), - btVector3(btScalar(-0.826165), btScalar(0.348139), btScalar(0.442851)), - btVector3(btScalar(-0.671810), btScalar(-0.162803), btScalar(0.722557)), - btVector3(btScalar(-0.796504), btScalar(-0.004543), btScalar(0.604468)), - btVector3(btScalar(-0.676298), btScalar(-0.378223), btScalar(0.631794)), - btVector3(btScalar(-0.668883), btScalar(-0.558258), btScalar(0.490673)), - btVector3(btScalar(-0.821287), btScalar(-0.570118), btScalar(0.006994)), - btVector3(btScalar(-0.767428), btScalar(-0.587810), btScalar(0.255470)), - btVector3(btScalar(-0.933296), btScalar(-0.349837), btScalar(-0.079865)), - btVector3(btScalar(-0.982667), btScalar(-0.100393), btScalar(-0.155208)), - btVector3(btScalar(-0.961396), btScalar(0.160910), btScalar(-0.222938)), - btVector3(btScalar(-0.934858), btScalar(0.354555), btScalar(-0.006864)), - btVector3(btScalar(-0.941687), btScalar(0.229736), btScalar(0.245711)), - btVector3(btScalar(-0.884317), btScalar(0.131552), btScalar(0.447536)), - btVector3(btScalar(-0.810359), btScalar(-0.219769), btScalar(0.542788)), - btVector3(btScalar(-0.915929), btScalar(-0.210048), btScalar(0.341743)), - btVector3(btScalar(-0.816799), btScalar(-0.407192), btScalar(0.408303)), - btVector3(btScalar(-0.903050), btScalar(-0.392416), btScalar(0.174076)), - btVector3(btScalar(-0.980325), btScalar(-0.170969), btScalar(0.096586)), - btVector3(btScalar(-0.995936), btScalar(0.084891), btScalar(0.029441)), - btVector3(btScalar(-0.960031), btScalar(0.002650), btScalar(0.279283)), - }; + { + btVector3(btScalar(0.997604), btScalar(0.067004), btScalar(0.017144)), + btVector3(btScalar(0.984139), btScalar(-0.086784), btScalar(-0.154427)), + btVector3(btScalar(0.971065), btScalar(0.124164), btScalar(-0.203224)), + btVector3(btScalar(0.955844), btScalar(0.291173), btScalar(-0.037704)), + btVector3(btScalar(0.957405), btScalar(0.212238), btScalar(0.195157)), + btVector3(btScalar(0.971650), btScalar(-0.012709), btScalar(0.235561)), + btVector3(btScalar(0.984920), btScalar(-0.161831), btScalar(0.059695)), + btVector3(btScalar(0.946673), btScalar(-0.299288), btScalar(-0.117536)), + btVector3(btScalar(0.922670), btScalar(-0.219186), btScalar(-0.317019)), + btVector3(btScalar(0.928134), btScalar(-0.007265), btScalar(-0.371867)), + btVector3(btScalar(0.875642), btScalar(0.198434), btScalar(-0.439988)), + btVector3(btScalar(0.908035), btScalar(0.325975), btScalar(-0.262562)), + btVector3(btScalar(0.864519), btScalar(0.488706), btScalar(-0.116755)), + btVector3(btScalar(0.893009), btScalar(0.428046), btScalar(0.137185)), + btVector3(btScalar(0.857494), btScalar(0.362137), btScalar(0.364776)), + btVector3(btScalar(0.900815), btScalar(0.132524), btScalar(0.412987)), + btVector3(btScalar(0.934964), btScalar(-0.241739), btScalar(0.259179)), + btVector3(btScalar(0.894570), btScalar(-0.103504), btScalar(0.434263)), + btVector3(btScalar(0.922085), btScalar(-0.376668), btScalar(0.086241)), + btVector3(btScalar(0.862177), btScalar(-0.499154), btScalar(-0.085330)), + btVector3(btScalar(0.861982), btScalar(-0.420218), btScalar(-0.282861)), + btVector3(btScalar(0.818076), btScalar(-0.328256), btScalar(-0.471804)), + btVector3(btScalar(0.762657), btScalar(-0.179329), btScalar(-0.621124)), + btVector3(btScalar(0.826857), btScalar(0.019760), btScalar(-0.561786)), + btVector3(btScalar(0.731434), btScalar(0.206599), btScalar(-0.649817)), + btVector3(btScalar(0.769486), btScalar(0.379052), btScalar(-0.513770)), + btVector3(btScalar(0.796806), btScalar(0.507176), btScalar(-0.328145)), + btVector3(btScalar(0.679722), btScalar(0.684101), btScalar(-0.264123)), + btVector3(btScalar(0.786854), btScalar(0.614886), btScalar(0.050912)), + btVector3(btScalar(0.769486), btScalar(0.571141), btScalar(0.285139)), + btVector3(btScalar(0.707432), btScalar(0.492789), btScalar(0.506288)), + btVector3(btScalar(0.774560), btScalar(0.268037), btScalar(0.572652)), + btVector3(btScalar(0.796220), btScalar(0.031230), btScalar(0.604077)), + btVector3(btScalar(0.837395), btScalar(-0.320285), btScalar(0.442461)), + btVector3(btScalar(0.848127), btScalar(-0.450548), btScalar(0.278307)), + btVector3(btScalar(0.775536), btScalar(-0.206354), btScalar(0.596465)), + btVector3(btScalar(0.816320), btScalar(-0.567007), btScalar(0.109469)), + btVector3(btScalar(0.741191), btScalar(-0.668690), btScalar(-0.056832)), + btVector3(btScalar(0.755632), btScalar(-0.602975), btScalar(-0.254949)), + btVector3(btScalar(0.720311), btScalar(-0.521318), btScalar(-0.457165)), + btVector3(btScalar(0.670746), btScalar(-0.386583), btScalar(-0.632835)), + btVector3(btScalar(0.587031), btScalar(-0.219769), btScalar(-0.778836)), + btVector3(btScalar(0.676015), btScalar(-0.003182), btScalar(-0.736676)), + btVector3(btScalar(0.566932), btScalar(0.186963), btScalar(-0.802064)), + btVector3(btScalar(0.618254), btScalar(0.398105), btScalar(-0.677533)), + btVector3(btScalar(0.653964), btScalar(0.575224), btScalar(-0.490933)), + btVector3(btScalar(0.525367), btScalar(0.743205), btScalar(-0.414028)), + btVector3(btScalar(0.506439), btScalar(0.836528), btScalar(-0.208885)), + btVector3(btScalar(0.651427), btScalar(0.756426), btScalar(-0.056247)), + btVector3(btScalar(0.641670), btScalar(0.745149), btScalar(0.180908)), + btVector3(btScalar(0.602643), btScalar(0.687211), btScalar(0.405180)), + btVector3(btScalar(0.516586), btScalar(0.596999), btScalar(0.613447)), + btVector3(btScalar(0.602252), btScalar(0.387801), btScalar(0.697573)), + btVector3(btScalar(0.646549), btScalar(0.153911), btScalar(0.746956)), + btVector3(btScalar(0.650842), btScalar(-0.087756), btScalar(0.753983)), + btVector3(btScalar(0.740411), btScalar(-0.497404), btScalar(0.451830)), + btVector3(btScalar(0.726946), btScalar(-0.619890), btScalar(0.295093)), + btVector3(btScalar(0.637768), btScalar(-0.313092), btScalar(0.703624)), + btVector3(btScalar(0.678942), btScalar(-0.722934), btScalar(0.126645)), + btVector3(btScalar(0.489072), btScalar(-0.867195), btScalar(-0.092942)), + btVector3(btScalar(0.622742), btScalar(-0.757541), btScalar(-0.194636)), + btVector3(btScalar(0.596788), btScalar(-0.693576), btScalar(-0.403098)), + btVector3(btScalar(0.550150), btScalar(-0.582172), btScalar(-0.598287)), + btVector3(btScalar(0.474436), btScalar(-0.429745), btScalar(-0.768101)), + btVector3(btScalar(0.372574), btScalar(-0.246016), btScalar(-0.894583)), + btVector3(btScalar(0.480095), btScalar(-0.026513), btScalar(-0.876626)), + btVector3(btScalar(0.352474), btScalar(0.177242), btScalar(-0.918787)), + btVector3(btScalar(0.441848), btScalar(0.374386), btScalar(-0.814946)), + btVector3(btScalar(0.492389), btScalar(0.582223), btScalar(-0.646693)), + btVector3(btScalar(0.343498), btScalar(0.866080), btScalar(-0.362693)), + btVector3(btScalar(0.362036), btScalar(0.745149), btScalar(-0.559639)), + btVector3(btScalar(0.334131), btScalar(0.937044), btScalar(-0.099774)), + btVector3(btScalar(0.486925), btScalar(0.871718), btScalar(0.052473)), + btVector3(btScalar(0.452776), btScalar(0.845665), btScalar(0.281820)), + btVector3(btScalar(0.399503), btScalar(0.771785), btScalar(0.494576)), + btVector3(btScalar(0.296469), btScalar(0.673018), btScalar(0.677469)), + btVector3(btScalar(0.392088), btScalar(0.479179), btScalar(0.785213)), + btVector3(btScalar(0.452190), btScalar(0.252094), btScalar(0.855286)), + btVector3(btScalar(0.478339), btScalar(0.013149), btScalar(0.877928)), + btVector3(btScalar(0.481656), btScalar(-0.219380), btScalar(0.848259)), + btVector3(btScalar(0.615327), btScalar(-0.494293), btScalar(0.613837)), + btVector3(btScalar(0.594642), btScalar(-0.650414), btScalar(0.472325)), + btVector3(btScalar(0.562249), btScalar(-0.771345), btScalar(0.297631)), + btVector3(btScalar(0.467411), btScalar(-0.437133), btScalar(0.768231)), + btVector3(btScalar(0.519513), btScalar(-0.847947), btScalar(0.103808)), + btVector3(btScalar(0.297640), btScalar(-0.938159), btScalar(-0.176288)), + btVector3(btScalar(0.446727), btScalar(-0.838615), btScalar(-0.311359)), + btVector3(btScalar(0.331790), btScalar(-0.942437), btScalar(0.040762)), + btVector3(btScalar(0.413358), btScalar(-0.748403), btScalar(-0.518259)), + btVector3(btScalar(0.347596), btScalar(-0.621640), btScalar(-0.701737)), + btVector3(btScalar(0.249831), btScalar(-0.456186), btScalar(-0.853984)), + btVector3(btScalar(0.131772), btScalar(-0.262931), btScalar(-0.955678)), + btVector3(btScalar(0.247099), btScalar(-0.042261), btScalar(-0.967975)), + btVector3(btScalar(0.113624), btScalar(0.165965), btScalar(-0.979491)), + btVector3(btScalar(0.217438), btScalar(0.374580), btScalar(-0.901220)), + btVector3(btScalar(0.307983), btScalar(0.554615), btScalar(-0.772786)), + btVector3(btScalar(0.166702), btScalar(0.953181), btScalar(-0.252021)), + btVector3(btScalar(0.172751), btScalar(0.844499), btScalar(-0.506743)), + btVector3(btScalar(0.177630), btScalar(0.711125), btScalar(-0.679876)), + btVector3(btScalar(0.120064), btScalar(0.992260), btScalar(-0.030482)), + btVector3(btScalar(0.289640), btScalar(0.949098), btScalar(0.122546)), + btVector3(btScalar(0.239879), btScalar(0.909047), btScalar(0.340377)), + btVector3(btScalar(0.181142), btScalar(0.821363), btScalar(0.540641)), + btVector3(btScalar(0.066986), btScalar(0.719097), btScalar(0.691327)), + btVector3(btScalar(0.156750), btScalar(0.545478), btScalar(0.823079)), + btVector3(btScalar(0.236172), btScalar(0.342306), btScalar(0.909353)), + btVector3(btScalar(0.277541), btScalar(0.112693), btScalar(0.953856)), + btVector3(btScalar(0.295299), btScalar(-0.121974), btScalar(0.947415)), + btVector3(btScalar(0.287883), btScalar(-0.349254), btScalar(0.891591)), + btVector3(btScalar(0.437165), btScalar(-0.634666), btScalar(0.636869)), + btVector3(btScalar(0.407113), btScalar(-0.784954), btScalar(0.466664)), + btVector3(btScalar(0.375111), btScalar(-0.888193), btScalar(0.264839)), + btVector3(btScalar(0.275394), btScalar(-0.560591), btScalar(0.780723)), + btVector3(btScalar(0.122015), btScalar(-0.992209), btScalar(-0.024821)), + btVector3(btScalar(0.087866), btScalar(-0.966156), btScalar(-0.241676)), + btVector3(btScalar(0.239489), btScalar(-0.885665), btScalar(-0.397437)), + btVector3(btScalar(0.167287), btScalar(-0.965184), btScalar(0.200817)), + btVector3(btScalar(0.201632), btScalar(-0.776789), btScalar(-0.596335)), + btVector3(btScalar(0.122015), btScalar(-0.637971), btScalar(-0.760098)), + btVector3(btScalar(0.008054), btScalar(-0.464741), btScalar(-0.885214)), + btVector3(btScalar(-0.116054), btScalar(-0.271096), btScalar(-0.955482)), + btVector3(btScalar(-0.000727), btScalar(-0.056065), btScalar(-0.998424)), + btVector3(btScalar(-0.134007), btScalar(0.152939), btScalar(-0.978905)), + btVector3(btScalar(-0.025900), btScalar(0.366026), btScalar(-0.930108)), + btVector3(btScalar(0.081231), btScalar(0.557337), btScalar(-0.826072)), + btVector3(btScalar(-0.002874), btScalar(0.917213), btScalar(-0.398023)), + btVector3(btScalar(-0.050683), btScalar(0.981761), btScalar(-0.182534)), + btVector3(btScalar(-0.040536), btScalar(0.710153), btScalar(-0.702713)), + btVector3(btScalar(-0.139081), btScalar(0.827973), btScalar(-0.543048)), + btVector3(btScalar(-0.101029), btScalar(0.994010), btScalar(0.041152)), + btVector3(btScalar(0.069328), btScalar(0.978067), btScalar(0.196133)), + btVector3(btScalar(0.023860), btScalar(0.911380), btScalar(0.410645)), + btVector3(btScalar(-0.153521), btScalar(0.736789), btScalar(0.658145)), + btVector3(btScalar(-0.070002), btScalar(0.591750), btScalar(0.802780)), + btVector3(btScalar(0.002590), btScalar(0.312948), btScalar(0.949562)), + btVector3(btScalar(0.090988), btScalar(-0.020680), btScalar(0.995627)), + btVector3(btScalar(0.088842), btScalar(-0.250099), btScalar(0.964006)), + btVector3(btScalar(0.083378), btScalar(-0.470185), btScalar(0.878318)), + btVector3(btScalar(0.240074), btScalar(-0.749764), btScalar(0.616374)), + btVector3(btScalar(0.210803), btScalar(-0.885860), btScalar(0.412987)), + btVector3(btScalar(0.077524), btScalar(-0.660524), btScalar(0.746565)), + btVector3(btScalar(-0.096736), btScalar(-0.990070), btScalar(-0.100945)), + btVector3(btScalar(-0.052634), btScalar(-0.990264), btScalar(0.127426)), + btVector3(btScalar(-0.106102), btScalar(-0.938354), btScalar(-0.328340)), + btVector3(btScalar(0.013323), btScalar(-0.863112), btScalar(-0.504596)), + btVector3(btScalar(-0.002093), btScalar(-0.936993), btScalar(0.349161)), + btVector3(btScalar(-0.106297), btScalar(-0.636610), btScalar(-0.763612)), + btVector3(btScalar(-0.229430), btScalar(-0.463769), btScalar(-0.855546)), + btVector3(btScalar(-0.245236), btScalar(-0.066175), btScalar(-0.966999)), + btVector3(btScalar(-0.351587), btScalar(-0.270513), btScalar(-0.896145)), + btVector3(btScalar(-0.370906), btScalar(0.133108), btScalar(-0.918982)), + btVector3(btScalar(-0.264360), btScalar(0.346000), btScalar(-0.900049)), + btVector3(btScalar(-0.151375), btScalar(0.543728), btScalar(-0.825291)), + btVector3(btScalar(-0.218697), btScalar(0.912741), btScalar(-0.344346)), + btVector3(btScalar(-0.274507), btScalar(0.953764), btScalar(-0.121635)), + btVector3(btScalar(-0.259677), btScalar(0.692266), btScalar(-0.673044)), + btVector3(btScalar(-0.350416), btScalar(0.798810), btScalar(-0.488786)), + btVector3(btScalar(-0.320170), btScalar(0.941127), btScalar(0.108297)), + btVector3(btScalar(-0.147667), btScalar(0.952792), btScalar(0.265034)), + btVector3(btScalar(-0.188061), btScalar(0.860636), btScalar(0.472910)), + btVector3(btScalar(-0.370906), btScalar(0.739900), btScalar(0.560941)), + btVector3(btScalar(-0.297143), btScalar(0.585334), btScalar(0.754178)), + btVector3(btScalar(-0.189622), btScalar(0.428241), btScalar(0.883393)), + btVector3(btScalar(-0.091272), btScalar(0.098695), btScalar(0.990747)), + btVector3(btScalar(-0.256945), btScalar(0.228375), btScalar(0.938827)), + btVector3(btScalar(-0.111761), btScalar(-0.133251), btScalar(0.984696)), + btVector3(btScalar(-0.118006), btScalar(-0.356253), btScalar(0.926725)), + btVector3(btScalar(-0.119372), btScalar(-0.563896), btScalar(0.817029)), + btVector3(btScalar(0.041228), btScalar(-0.833949), btScalar(0.550010)), + btVector3(btScalar(-0.121909), btScalar(-0.736543), btScalar(0.665172)), + btVector3(btScalar(-0.307681), btScalar(-0.931160), btScalar(-0.195026)), + btVector3(btScalar(-0.283679), btScalar(-0.957990), btScalar(0.041348)), + btVector3(btScalar(-0.227284), btScalar(-0.935243), btScalar(0.270890)), + btVector3(btScalar(-0.293436), btScalar(-0.858252), btScalar(-0.420860)), + btVector3(btScalar(-0.175767), btScalar(-0.780677), btScalar(-0.599262)), + btVector3(btScalar(-0.170108), btScalar(-0.858835), btScalar(0.482865)), + btVector3(btScalar(-0.332854), btScalar(-0.635055), btScalar(-0.696857)), + btVector3(btScalar(-0.447791), btScalar(-0.445299), btScalar(-0.775128)), + btVector3(btScalar(-0.470622), btScalar(-0.074146), btScalar(-0.879164)), + btVector3(btScalar(-0.639417), btScalar(-0.340505), btScalar(-0.689049)), + btVector3(btScalar(-0.598438), btScalar(0.104722), btScalar(-0.794256)), + btVector3(btScalar(-0.488575), btScalar(0.307699), btScalar(-0.816313)), + btVector3(btScalar(-0.379882), btScalar(0.513592), btScalar(-0.769077)), + btVector3(btScalar(-0.425740), btScalar(0.862775), btScalar(-0.272516)), + btVector3(btScalar(-0.480769), btScalar(0.875412), btScalar(-0.048439)), + btVector3(btScalar(-0.467890), btScalar(0.648716), btScalar(-0.600043)), + btVector3(btScalar(-0.543799), btScalar(0.730956), btScalar(-0.411881)), + btVector3(btScalar(-0.516284), btScalar(0.838277), btScalar(0.174076)), + btVector3(btScalar(-0.353343), btScalar(0.876384), btScalar(0.326519)), + btVector3(btScalar(-0.572875), btScalar(0.614497), btScalar(0.542007)), + btVector3(btScalar(-0.503600), btScalar(0.497261), btScalar(0.706161)), + btVector3(btScalar(-0.530920), btScalar(0.754870), btScalar(0.384685)), + btVector3(btScalar(-0.395884), btScalar(0.366414), btScalar(0.841818)), + btVector3(btScalar(-0.300656), btScalar(0.001678), btScalar(0.953661)), + btVector3(btScalar(-0.461060), btScalar(0.146912), btScalar(0.875000)), + btVector3(btScalar(-0.315486), btScalar(-0.232212), btScalar(0.919893)), + btVector3(btScalar(-0.323682), btScalar(-0.449187), btScalar(0.832644)), + btVector3(btScalar(-0.318999), btScalar(-0.639527), btScalar(0.699134)), + btVector3(btScalar(-0.496771), btScalar(-0.866029), btScalar(-0.055271)), + btVector3(btScalar(-0.496771), btScalar(-0.816257), btScalar(-0.294377)), + btVector3(btScalar(-0.456377), btScalar(-0.869528), btScalar(0.188130)), + btVector3(btScalar(-0.380858), btScalar(-0.827144), btScalar(0.412792)), + btVector3(btScalar(-0.449352), btScalar(-0.727405), btScalar(-0.518259)), + btVector3(btScalar(-0.570533), btScalar(-0.551064), btScalar(-0.608632)), + btVector3(btScalar(-0.656394), btScalar(-0.118280), btScalar(-0.744874)), + btVector3(btScalar(-0.756696), btScalar(-0.438105), btScalar(-0.484882)), + btVector3(btScalar(-0.801773), btScalar(-0.204798), btScalar(-0.561005)), + btVector3(btScalar(-0.785186), btScalar(0.038618), btScalar(-0.617805)), + btVector3(btScalar(-0.709082), btScalar(0.262399), btScalar(-0.654306)), + btVector3(btScalar(-0.583412), btScalar(0.462265), btScalar(-0.667383)), + btVector3(btScalar(-0.616001), btScalar(0.761286), btScalar(-0.201272)), + btVector3(btScalar(-0.660687), btScalar(0.750204), btScalar(0.020072)), + btVector3(btScalar(-0.744987), btScalar(0.435823), btScalar(-0.504791)), + btVector3(btScalar(-0.713765), btScalar(0.605554), btScalar(-0.351373)), + btVector3(btScalar(-0.686251), btScalar(0.687600), btScalar(0.236927)), + btVector3(btScalar(-0.680201), btScalar(0.429407), btScalar(0.593732)), + btVector3(btScalar(-0.733474), btScalar(0.546450), btScalar(0.403814)), + btVector3(btScalar(-0.591023), btScalar(0.292923), btScalar(0.751445)), + btVector3(btScalar(-0.500283), btScalar(-0.080757), btScalar(0.861922)), + btVector3(btScalar(-0.643710), btScalar(0.070115), btScalar(0.761985)), + btVector3(btScalar(-0.506332), btScalar(-0.308425), btScalar(0.805122)), + btVector3(btScalar(-0.503015), btScalar(-0.509847), btScalar(0.697573)), + btVector3(btScalar(-0.482525), btScalar(-0.682105), btScalar(0.549229)), + btVector3(btScalar(-0.680396), btScalar(-0.716323), btScalar(-0.153451)), + btVector3(btScalar(-0.658346), btScalar(-0.746264), btScalar(0.097562)), + btVector3(btScalar(-0.653272), btScalar(-0.646915), btScalar(-0.392948)), + btVector3(btScalar(-0.590828), btScalar(-0.732655), btScalar(0.337645)), + btVector3(btScalar(-0.819140), btScalar(-0.518013), btScalar(-0.246166)), + btVector3(btScalar(-0.900513), btScalar(-0.282178), btScalar(-0.330487)), + btVector3(btScalar(-0.914953), btScalar(-0.028652), btScalar(-0.402122)), + btVector3(btScalar(-0.859924), btScalar(0.220209), btScalar(-0.459898)), + btVector3(btScalar(-0.777185), btScalar(0.613720), btScalar(-0.137836)), + btVector3(btScalar(-0.805285), btScalar(0.586889), btScalar(0.082728)), + btVector3(btScalar(-0.872413), btScalar(0.406077), btScalar(-0.271735)), + btVector3(btScalar(-0.859339), btScalar(0.448072), btScalar(0.246101)), + btVector3(btScalar(-0.757671), btScalar(0.216320), btScalar(0.615594)), + btVector3(btScalar(-0.826165), btScalar(0.348139), btScalar(0.442851)), + btVector3(btScalar(-0.671810), btScalar(-0.162803), btScalar(0.722557)), + btVector3(btScalar(-0.796504), btScalar(-0.004543), btScalar(0.604468)), + btVector3(btScalar(-0.676298), btScalar(-0.378223), btScalar(0.631794)), + btVector3(btScalar(-0.668883), btScalar(-0.558258), btScalar(0.490673)), + btVector3(btScalar(-0.821287), btScalar(-0.570118), btScalar(0.006994)), + btVector3(btScalar(-0.767428), btScalar(-0.587810), btScalar(0.255470)), + btVector3(btScalar(-0.933296), btScalar(-0.349837), btScalar(-0.079865)), + btVector3(btScalar(-0.982667), btScalar(-0.100393), btScalar(-0.155208)), + btVector3(btScalar(-0.961396), btScalar(0.160910), btScalar(-0.222938)), + btVector3(btScalar(-0.934858), btScalar(0.354555), btScalar(-0.006864)), + btVector3(btScalar(-0.941687), btScalar(0.229736), btScalar(0.245711)), + btVector3(btScalar(-0.884317), btScalar(0.131552), btScalar(0.447536)), + btVector3(btScalar(-0.810359), btScalar(-0.219769), btScalar(0.542788)), + btVector3(btScalar(-0.915929), btScalar(-0.210048), btScalar(0.341743)), + btVector3(btScalar(-0.816799), btScalar(-0.407192), btScalar(0.408303)), + btVector3(btScalar(-0.903050), btScalar(-0.392416), btScalar(0.174076)), + btVector3(btScalar(-0.980325), btScalar(-0.170969), btScalar(0.096586)), + btVector3(btScalar(-0.995936), btScalar(0.084891), btScalar(0.029441)), + btVector3(btScalar(-0.960031), btScalar(0.002650), btScalar(0.279283)), + }; static btVector3 sUnitSpherePoints[NUM_UNITSPHERE_POINTS + MAX_PREFERRED_PENETRATION_DIRECTIONS * 2] = - { - btVector3(btScalar(0.000000) , btScalar(-0.000000),btScalar(-1.000000)), - btVector3(btScalar(0.723608) , btScalar(-0.525725),btScalar(-0.447219)), - btVector3(btScalar(-0.276388) , btScalar(-0.850649),btScalar(-0.447219)), - btVector3(btScalar(-0.894426) , btScalar(-0.000000),btScalar(-0.447216)), - btVector3(btScalar(-0.276388) , btScalar(0.850649),btScalar(-0.447220)), - btVector3(btScalar(0.723608) , btScalar(0.525725),btScalar(-0.447219)), - btVector3(btScalar(0.276388) , btScalar(-0.850649),btScalar(0.447220)), - btVector3(btScalar(-0.723608) , btScalar(-0.525725),btScalar(0.447219)), - btVector3(btScalar(-0.723608) , btScalar(0.525725),btScalar(0.447219)), - btVector3(btScalar(0.276388) , btScalar(0.850649),btScalar(0.447219)), - btVector3(btScalar(0.894426) , btScalar(0.000000),btScalar(0.447216)), - btVector3(btScalar(-0.000000) , btScalar(0.000000),btScalar(1.000000)), - btVector3(btScalar(0.425323) , btScalar(-0.309011),btScalar(-0.850654)), - btVector3(btScalar(-0.162456) , btScalar(-0.499995),btScalar(-0.850654)), - btVector3(btScalar(0.262869) , btScalar(-0.809012),btScalar(-0.525738)), - btVector3(btScalar(0.425323) , btScalar(0.309011),btScalar(-0.850654)), - btVector3(btScalar(0.850648) , btScalar(-0.000000),btScalar(-0.525736)), - btVector3(btScalar(-0.525730) , btScalar(-0.000000),btScalar(-0.850652)), - btVector3(btScalar(-0.688190) , btScalar(-0.499997),btScalar(-0.525736)), - btVector3(btScalar(-0.162456) , btScalar(0.499995),btScalar(-0.850654)), - btVector3(btScalar(-0.688190) , btScalar(0.499997),btScalar(-0.525736)), - btVector3(btScalar(0.262869) , btScalar(0.809012),btScalar(-0.525738)), - btVector3(btScalar(0.951058) , btScalar(0.309013),btScalar(0.000000)), - btVector3(btScalar(0.951058) , btScalar(-0.309013),btScalar(0.000000)), - btVector3(btScalar(0.587786) , btScalar(-0.809017),btScalar(0.000000)), - btVector3(btScalar(0.000000) , btScalar(-1.000000),btScalar(0.000000)), - btVector3(btScalar(-0.587786) , btScalar(-0.809017),btScalar(0.000000)), - btVector3(btScalar(-0.951058) , btScalar(-0.309013),btScalar(-0.000000)), - btVector3(btScalar(-0.951058) , btScalar(0.309013),btScalar(-0.000000)), - btVector3(btScalar(-0.587786) , btScalar(0.809017),btScalar(-0.000000)), - btVector3(btScalar(-0.000000) , btScalar(1.000000),btScalar(-0.000000)), - btVector3(btScalar(0.587786) , btScalar(0.809017),btScalar(-0.000000)), - btVector3(btScalar(0.688190) , btScalar(-0.499997),btScalar(0.525736)), - btVector3(btScalar(-0.262869) , btScalar(-0.809012),btScalar(0.525738)), - btVector3(btScalar(-0.850648) , btScalar(0.000000),btScalar(0.525736)), - btVector3(btScalar(-0.262869) , btScalar(0.809012),btScalar(0.525738)), - btVector3(btScalar(0.688190) , btScalar(0.499997),btScalar(0.525736)), - btVector3(btScalar(0.525730) , btScalar(0.000000),btScalar(0.850652)), - btVector3(btScalar(0.162456) , btScalar(-0.499995),btScalar(0.850654)), - btVector3(btScalar(-0.425323) , btScalar(-0.309011),btScalar(0.850654)), - btVector3(btScalar(-0.425323) , btScalar(0.309011),btScalar(0.850654)), - btVector3(btScalar(0.162456) , btScalar(0.499995),btScalar(0.850654)) - }; + { + btVector3(btScalar(0.000000), btScalar(-0.000000), btScalar(-1.000000)), + btVector3(btScalar(0.723608), btScalar(-0.525725), btScalar(-0.447219)), + btVector3(btScalar(-0.276388), btScalar(-0.850649), btScalar(-0.447219)), + btVector3(btScalar(-0.894426), btScalar(-0.000000), btScalar(-0.447216)), + btVector3(btScalar(-0.276388), btScalar(0.850649), btScalar(-0.447220)), + btVector3(btScalar(0.723608), btScalar(0.525725), btScalar(-0.447219)), + btVector3(btScalar(0.276388), btScalar(-0.850649), btScalar(0.447220)), + btVector3(btScalar(-0.723608), btScalar(-0.525725), btScalar(0.447219)), + btVector3(btScalar(-0.723608), btScalar(0.525725), btScalar(0.447219)), + btVector3(btScalar(0.276388), btScalar(0.850649), btScalar(0.447219)), + btVector3(btScalar(0.894426), btScalar(0.000000), btScalar(0.447216)), + btVector3(btScalar(-0.000000), btScalar(0.000000), btScalar(1.000000)), + btVector3(btScalar(0.425323), btScalar(-0.309011), btScalar(-0.850654)), + btVector3(btScalar(-0.162456), btScalar(-0.499995), btScalar(-0.850654)), + btVector3(btScalar(0.262869), btScalar(-0.809012), btScalar(-0.525738)), + btVector3(btScalar(0.425323), btScalar(0.309011), btScalar(-0.850654)), + btVector3(btScalar(0.850648), btScalar(-0.000000), btScalar(-0.525736)), + btVector3(btScalar(-0.525730), btScalar(-0.000000), btScalar(-0.850652)), + btVector3(btScalar(-0.688190), btScalar(-0.499997), btScalar(-0.525736)), + btVector3(btScalar(-0.162456), btScalar(0.499995), btScalar(-0.850654)), + btVector3(btScalar(-0.688190), btScalar(0.499997), btScalar(-0.525736)), + btVector3(btScalar(0.262869), btScalar(0.809012), btScalar(-0.525738)), + btVector3(btScalar(0.951058), btScalar(0.309013), btScalar(0.000000)), + btVector3(btScalar(0.951058), btScalar(-0.309013), btScalar(0.000000)), + btVector3(btScalar(0.587786), btScalar(-0.809017), btScalar(0.000000)), + btVector3(btScalar(0.000000), btScalar(-1.000000), btScalar(0.000000)), + btVector3(btScalar(-0.587786), btScalar(-0.809017), btScalar(0.000000)), + btVector3(btScalar(-0.951058), btScalar(-0.309013), btScalar(-0.000000)), + btVector3(btScalar(-0.951058), btScalar(0.309013), btScalar(-0.000000)), + btVector3(btScalar(-0.587786), btScalar(0.809017), btScalar(-0.000000)), + btVector3(btScalar(-0.000000), btScalar(1.000000), btScalar(-0.000000)), + btVector3(btScalar(0.587786), btScalar(0.809017), btScalar(-0.000000)), + btVector3(btScalar(0.688190), btScalar(-0.499997), btScalar(0.525736)), + btVector3(btScalar(-0.262869), btScalar(-0.809012), btScalar(0.525738)), + btVector3(btScalar(-0.850648), btScalar(0.000000), btScalar(0.525736)), + btVector3(btScalar(-0.262869), btScalar(0.809012), btScalar(0.525738)), + btVector3(btScalar(0.688190), btScalar(0.499997), btScalar(0.525736)), + btVector3(btScalar(0.525730), btScalar(0.000000), btScalar(0.850652)), + btVector3(btScalar(0.162456), btScalar(-0.499995), btScalar(0.850654)), + btVector3(btScalar(-0.425323), btScalar(-0.309011), btScalar(0.850654)), + btVector3(btScalar(-0.425323), btScalar(0.309011), btScalar(0.850654)), + btVector3(btScalar(0.162456), btScalar(0.499995), btScalar(0.850654))}; if (highres) return sUnitSpherePointsHighres; return sUnitSpherePoints; } - diff --git a/src/BulletCollision/CollisionShapes/btShapeHull.h b/src/BulletCollision/CollisionShapes/btShapeHull.h index 78ea4b650..54439f9ca 100644 --- a/src/BulletCollision/CollisionShapes/btShapeHull.h +++ b/src/BulletCollision/CollisionShapes/btShapeHull.h @@ -21,32 +21,31 @@ subject to the following restrictions: #include "LinearMath/btAlignedObjectArray.h" #include "BulletCollision/CollisionShapes/btConvexShape.h" - ///The btShapeHull class takes a btConvexShape, builds a simplified convex hull using btConvexHull and provides triangle indices and vertices. ///It can be useful for to simplify a complex convex object and for visualization of a non-polyhedral convex object. ///It approximates the convex hull using the supporting vertex of 42 directions. -ATTRIBUTE_ALIGNED16(class) btShapeHull +ATTRIBUTE_ALIGNED16(class) +btShapeHull { protected: - btAlignedObjectArray m_vertices; btAlignedObjectArray m_indices; unsigned int m_numIndices; const btConvexShape* m_shape; - static btVector3* getUnitSpherePoints(int highres=0); + static btVector3* getUnitSpherePoints(int highres = 0); public: BT_DECLARE_ALIGNED_ALLOCATOR(); - - btShapeHull (const btConvexShape* shape); - ~btShapeHull (); - bool buildHull (btScalar margin, int highres=0); + btShapeHull(const btConvexShape* shape); + ~btShapeHull(); - int numTriangles () const; - int numVertices () const; - int numIndices () const; + bool buildHull(btScalar margin, int highres = 0); + + int numTriangles() const; + int numVertices() const; + int numIndices() const; const btVector3* getVertexPointer() const { @@ -58,4 +57,4 @@ public: } }; -#endif //BT_SHAPE_HULL_H +#endif //BT_SHAPE_HULL_H diff --git a/src/BulletCollision/CollisionShapes/btSphereShape.cpp b/src/BulletCollision/CollisionShapes/btSphereShape.cpp index b9a736c0f..027db2e10 100644 --- a/src/BulletCollision/CollisionShapes/btSphereShape.cpp +++ b/src/BulletCollision/CollisionShapes/btSphereShape.cpp @@ -18,54 +18,48 @@ subject to the following restrictions: #include "LinearMath/btQuaternion.h" -btVector3 btSphereShape::localGetSupportingVertexWithoutMargin(const btVector3& vec)const +btVector3 btSphereShape::localGetSupportingVertexWithoutMargin(const btVector3& vec) const { (void)vec; - return btVector3(btScalar(0.),btScalar(0.),btScalar(0.)); + return btVector3(btScalar(0.), btScalar(0.), btScalar(0.)); } -void btSphereShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +void btSphereShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const { (void)vectors; - for (int i=0;iprocessTriangle(triangle,0,0); + callback->processTriangle(triangle, 0, 0); - triangle[0] = projectedCenter - tangentDir0*radius - tangentDir1*radius; - triangle[1] = projectedCenter - tangentDir0*radius + tangentDir1*radius; - triangle[2] = projectedCenter + tangentDir0*radius + tangentDir1*radius; - - callback->processTriangle(triangle,0,1); + triangle[0] = projectedCenter - tangentDir0 * radius - tangentDir1 * radius; + triangle[1] = projectedCenter - tangentDir0 * radius + tangentDir1 * radius; + triangle[2] = projectedCenter + tangentDir0 * radius + tangentDir1 * radius; + callback->processTriangle(triangle, 0, 1); } -void btStaticPlaneShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +void btStaticPlaneShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const { (void)mass; //moving concave objects not supported - - inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); + + inertia.setValue(btScalar(0.), btScalar(0.), btScalar(0.)); } -void btStaticPlaneShape::setLocalScaling(const btVector3& scaling) +void btStaticPlaneShape::setLocalScaling(const btVector3& scaling) { m_localScaling = scaling; } diff --git a/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h b/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h index 5e9eccc77..1cda8bbc7 100644 --- a/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h +++ b/src/BulletCollision/CollisionShapes/btStaticPlaneShape.h @@ -18,78 +18,74 @@ subject to the following restrictions: #include "btConcaveShape.h" - ///The btStaticPlaneShape simulates an infinite non-moving (static) collision plane. -ATTRIBUTE_ALIGNED16(class) btStaticPlaneShape : public btConcaveShape +ATTRIBUTE_ALIGNED16(class) +btStaticPlaneShape : public btConcaveShape { protected: - btVector3 m_localAabbMin; - btVector3 m_localAabbMax; - - btVector3 m_planeNormal; - btScalar m_planeConstant; - btVector3 m_localScaling; + btVector3 m_localAabbMin; + btVector3 m_localAabbMax; + + btVector3 m_planeNormal; + btScalar m_planeConstant; + btVector3 m_localScaling; public: BT_DECLARE_ALIGNED_ALLOCATOR(); - btStaticPlaneShape(const btVector3& planeNormal,btScalar planeConstant); + btStaticPlaneShape(const btVector3& planeNormal, btScalar planeConstant); virtual ~btStaticPlaneShape(); + virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const; - virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + virtual void processAllTriangles(btTriangleCallback * callback, const btVector3& aabbMin, const btVector3& aabbMax) const; - virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + virtual void calculateLocalInertia(btScalar mass, btVector3 & inertia) const; - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; - - virtual void setLocalScaling(const btVector3& scaling); + virtual void setLocalScaling(const btVector3& scaling); virtual const btVector3& getLocalScaling() const; - - const btVector3& getPlaneNormal() const + + const btVector3& getPlaneNormal() const { - return m_planeNormal; + return m_planeNormal; } - const btScalar& getPlaneConstant() const + const btScalar& getPlaneConstant() const { - return m_planeConstant; + return m_planeConstant; } //debugging - virtual const char* getName()const {return "STATICPLANE";} + virtual const char* getName() const { return "STATICPLANE"; } - virtual int calculateSerializeBufferSize() const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; - - + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; }; ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 -struct btStaticPlaneShapeData +struct btStaticPlaneShapeData { - btCollisionShapeData m_collisionShapeData; + btCollisionShapeData m_collisionShapeData; - btVector3FloatData m_localScaling; - btVector3FloatData m_planeNormal; - float m_planeConstant; - char m_pad[4]; + btVector3FloatData m_localScaling; + btVector3FloatData m_planeNormal; + float m_planeConstant; + char m_pad[4]; }; - -SIMD_FORCE_INLINE int btStaticPlaneShape::calculateSerializeBufferSize() const +SIMD_FORCE_INLINE int btStaticPlaneShape::calculateSerializeBufferSize() const { return sizeof(btStaticPlaneShapeData); } ///fills the dataBuffer and returns the struct name (and 0 on failure) -SIMD_FORCE_INLINE const char* btStaticPlaneShape::serialize(void* dataBuffer, btSerializer* serializer) const +SIMD_FORCE_INLINE const char* btStaticPlaneShape::serialize(void* dataBuffer, btSerializer* serializer) const { - btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*) dataBuffer; - btCollisionShape::serialize(&planeData->m_collisionShapeData,serializer); + btStaticPlaneShapeData* planeData = (btStaticPlaneShapeData*)dataBuffer; + btCollisionShape::serialize(&planeData->m_collisionShapeData, serializer); m_localScaling.serializeFloat(planeData->m_localScaling); m_planeNormal.serializeFloat(planeData->m_planeNormal); @@ -104,8 +100,4 @@ SIMD_FORCE_INLINE const char* btStaticPlaneShape::serialize(void* dataBuffer, bt return "btStaticPlaneShapeData"; } - -#endif //BT_STATIC_PLANE_SHAPE_H - - - +#endif //BT_STATIC_PLANE_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp b/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp index 78ddeb370..eb288e99c 100644 --- a/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp +++ b/src/BulletCollision/CollisionShapes/btStridingMeshInterface.cpp @@ -18,32 +18,30 @@ subject to the following restrictions: btStridingMeshInterface::~btStridingMeshInterface() { - } - -void btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const +void btStridingMeshInterface::InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const { (void)aabbMin; (void)aabbMax; int numtotalphysicsverts = 0; - int part,graphicssubparts = getNumSubParts(); - const unsigned char * vertexbase; - const unsigned char * indexbase; + int part, graphicssubparts = getNumSubParts(); + const unsigned char* vertexbase; + const unsigned char* indexbase; int indexstride; PHY_ScalarType type; PHY_ScalarType gfxindextype; - int stride,numverts,numtriangles; + int stride, numverts, numtriangles; int gfxindex; btVector3 triangle[3]; btVector3 meshScaling = getScaling(); ///if the number of parts is big, the performance might drop due to the innerloop switch on indextype - for (part=0;partinternalProcessTriangleIndex(triangle, part, gfxindex); + } + break; + } + case PHY_SHORT: + { + for (gfxindex = 0; gfxindex < numtriangles; gfxindex++) + { + unsigned short int* tri_indices = (unsigned short int*)(indexbase + gfxindex * indexstride); + graphicsbase = (float*)(vertexbase + tri_indices[0] * stride); + triangle[0].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ()); + graphicsbase = (float*)(vertexbase + tri_indices[1] * stride); + triangle[1].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ()); + graphicsbase = (float*)(vertexbase + tri_indices[2] * stride); + triangle[2].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ()); + callback->internalProcessTriangleIndex(triangle, part, gfxindex); + } + break; + } + case PHY_UCHAR: + { + for (gfxindex = 0; gfxindex < numtriangles; gfxindex++) + { + unsigned char* tri_indices = (unsigned char*)(indexbase + gfxindex * indexstride); + graphicsbase = (float*)(vertexbase + tri_indices[0] * stride); + triangle[0].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ()); + graphicsbase = (float*)(vertexbase + tri_indices[1] * stride); + triangle[1].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ()); + graphicsbase = (float*)(vertexbase + tri_indices[2] * stride); + triangle[2].setValue(graphicsbase[0] * meshScaling.getX(), graphicsbase[1] * meshScaling.getY(), graphicsbase[2] * meshScaling.getZ()); + callback->internalProcessTriangleIndex(triangle, part, gfxindex); + } + break; + } + default: + btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT)); + } + break; + } - switch (gfxindextype) - { - case PHY_INTEGER: - { - for (gfxindex=0;gfxindexinternalProcessTriangleIndex(triangle,part,gfxindex); - } - break; - } - case PHY_SHORT: - { - for (gfxindex=0;gfxindexinternalProcessTriangleIndex(triangle,part,gfxindex); - } - break; - } - case PHY_UCHAR: - { - for (gfxindex=0;gfxindexinternalProcessTriangleIndex(triangle,part,gfxindex); - } - break; - } - default: - btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT)); - } - break; - } - - case PHY_DOUBLE: + case PHY_DOUBLE: { double* graphicsbase; switch (gfxindextype) { - case PHY_INTEGER: + case PHY_INTEGER: { - for (gfxindex=0;gfxindexinternalProcessTriangleIndex(triangle,part,gfxindex); + unsigned int* tri_indices = (unsigned int*)(indexbase + gfxindex * indexstride); + graphicsbase = (double*)(vertexbase + tri_indices[0] * stride); + triangle[0].setValue((btScalar)graphicsbase[0] * meshScaling.getX(), (btScalar)graphicsbase[1] * meshScaling.getY(), (btScalar)graphicsbase[2] * meshScaling.getZ()); + graphicsbase = (double*)(vertexbase + tri_indices[1] * stride); + triangle[1].setValue((btScalar)graphicsbase[0] * meshScaling.getX(), (btScalar)graphicsbase[1] * meshScaling.getY(), (btScalar)graphicsbase[2] * meshScaling.getZ()); + graphicsbase = (double*)(vertexbase + tri_indices[2] * stride); + triangle[2].setValue((btScalar)graphicsbase[0] * meshScaling.getX(), (btScalar)graphicsbase[1] * meshScaling.getY(), (btScalar)graphicsbase[2] * meshScaling.getZ()); + callback->internalProcessTriangleIndex(triangle, part, gfxindex); } break; } - case PHY_SHORT: + case PHY_SHORT: { - for (gfxindex=0;gfxindexinternalProcessTriangleIndex(triangle,part,gfxindex); + unsigned short int* tri_indices = (unsigned short int*)(indexbase + gfxindex * indexstride); + graphicsbase = (double*)(vertexbase + tri_indices[0] * stride); + triangle[0].setValue((btScalar)graphicsbase[0] * meshScaling.getX(), (btScalar)graphicsbase[1] * meshScaling.getY(), (btScalar)graphicsbase[2] * meshScaling.getZ()); + graphicsbase = (double*)(vertexbase + tri_indices[1] * stride); + triangle[1].setValue((btScalar)graphicsbase[0] * meshScaling.getX(), (btScalar)graphicsbase[1] * meshScaling.getY(), (btScalar)graphicsbase[2] * meshScaling.getZ()); + graphicsbase = (double*)(vertexbase + tri_indices[2] * stride); + triangle[2].setValue((btScalar)graphicsbase[0] * meshScaling.getX(), (btScalar)graphicsbase[1] * meshScaling.getY(), (btScalar)graphicsbase[2] * meshScaling.getZ()); + callback->internalProcessTriangleIndex(triangle, part, gfxindex); } break; } - case PHY_UCHAR: + case PHY_UCHAR: { - for (gfxindex=0;gfxindexinternalProcessTriangleIndex(triangle,part,gfxindex); + unsigned char* tri_indices = (unsigned char*)(indexbase + gfxindex * indexstride); + graphicsbase = (double*)(vertexbase + tri_indices[0] * stride); + triangle[0].setValue((btScalar)graphicsbase[0] * meshScaling.getX(), (btScalar)graphicsbase[1] * meshScaling.getY(), (btScalar)graphicsbase[2] * meshScaling.getZ()); + graphicsbase = (double*)(vertexbase + tri_indices[1] * stride); + triangle[1].setValue((btScalar)graphicsbase[0] * meshScaling.getX(), (btScalar)graphicsbase[1] * meshScaling.getY(), (btScalar)graphicsbase[2] * meshScaling.getZ()); + graphicsbase = (double*)(vertexbase + tri_indices[2] * stride); + triangle[2].setValue((btScalar)graphicsbase[0] * meshScaling.getX(), (btScalar)graphicsbase[1] * meshScaling.getY(), (btScalar)graphicsbase[2] * meshScaling.getZ()); + callback->internalProcessTriangleIndex(triangle, part, gfxindex); } break; } - default: - btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT)); + default: + btAssert((gfxindextype == PHY_INTEGER) || (gfxindextype == PHY_SHORT)); } break; } - default: - btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE)); + default: + btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE)); } unLockReadOnlyVertexBase(part); } } -void btStridingMeshInterface::calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax) +void btStridingMeshInterface::calculateAabbBruteForce(btVector3& aabbMin, btVector3& aabbMax) { - - struct AabbCalculationCallback : public btInternalTriangleIndexCallback + struct AabbCalculationCallback : public btInternalTriangleIndexCallback { - btVector3 m_aabbMin; - btVector3 m_aabbMax; + btVector3 m_aabbMin; + btVector3 m_aabbMax; AabbCalculationCallback() { - m_aabbMin.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); - m_aabbMax.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); + m_aabbMin.setValue(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); + m_aabbMax.setValue(btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT)); } - virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex) { (void)partId; (void)triangleIndex; @@ -202,21 +198,19 @@ void btStridingMeshInterface::calculateAabbBruteForce(btVector3& aabbMin,btVecto }; //first calculate the total aabb for all triangles - AabbCalculationCallback aabbCallback; - aabbMin.setValue(btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT),btScalar(-BT_LARGE_FLOAT)); - aabbMax.setValue(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); - InternalProcessAllTriangles(&aabbCallback,aabbMin,aabbMax); + AabbCalculationCallback aabbCallback; + aabbMin.setValue(btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT), btScalar(-BT_LARGE_FLOAT)); + aabbMax.setValue(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); + InternalProcessAllTriangles(&aabbCallback, aabbMin, aabbMax); aabbMin = aabbCallback.m_aabbMin; aabbMax = aabbCallback.m_aabbMax; } - - ///fills the dataBuffer and returns the struct name (and 0 on failure) -const char* btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* serializer) const +const char* btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* serializer) const { - btStridingMeshInterfaceData* trimeshData = (btStridingMeshInterfaceData*) dataBuffer; + btStridingMeshInterfaceData* trimeshData = (btStridingMeshInterfaceData*)dataBuffer; trimeshData->m_numMeshParts = getNumSubParts(); @@ -226,29 +220,28 @@ const char* btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* s if (trimeshData->m_numMeshParts) { - btChunk* chunk = serializer->allocate(sizeof(btMeshPartData),trimeshData->m_numMeshParts); + btChunk* chunk = serializer->allocate(sizeof(btMeshPartData), trimeshData->m_numMeshParts); btMeshPartData* memPtr = (btMeshPartData*)chunk->m_oldPtr; - trimeshData->m_meshPartsPtr = (btMeshPartData *)serializer->getUniquePointer(memPtr); + trimeshData->m_meshPartsPtr = (btMeshPartData*)serializer->getUniquePointer(memPtr); - - // int numtotalphysicsverts = 0; - int part,graphicssubparts = getNumSubParts(); - const unsigned char * vertexbase; - const unsigned char * indexbase; + // int numtotalphysicsverts = 0; + int part, graphicssubparts = getNumSubParts(); + const unsigned char* vertexbase; + const unsigned char* indexbase; int indexstride; PHY_ScalarType type; PHY_ScalarType gfxindextype; - int stride,numverts,numtriangles; + int stride, numverts, numtriangles; int gfxindex; - // btVector3 triangle[3]; + // btVector3 triangle[3]; - // btVector3 meshScaling = getScaling(); + // btVector3 meshScaling = getScaling(); ///if the number of parts is big, the performance might drop due to the innerloop switch on indextype - for (part=0;partm_numTriangles = numtriangles;//indices = 3*numtriangles + getLockedReadOnlyVertexIndexBase(&vertexbase, numverts, type, stride, &indexbase, indexstride, numtriangles, gfxindextype, part); + memPtr->m_numTriangles = numtriangles; //indices = 3*numtriangles memPtr->m_numVertices = numverts; memPtr->m_indices16 = 0; memPtr->m_indices32 = 0; @@ -257,39 +250,38 @@ const char* btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* s memPtr->m_vertices3f = 0; memPtr->m_vertices3d = 0; - switch (gfxindextype) { - case PHY_INTEGER: + case PHY_INTEGER: { - int numindices = numtriangles*3; - + int numindices = numtriangles * 3; + if (numindices) { - btChunk* chunk = serializer->allocate(sizeof(btIntIndexData),numindices); + btChunk* chunk = serializer->allocate(sizeof(btIntIndexData), numindices); btIntIndexData* tmpIndices = (btIntIndexData*)chunk->m_oldPtr; memPtr->m_indices32 = (btIntIndexData*)serializer->getUniquePointer(tmpIndices); - for (gfxindex=0;gfxindexfinalizeChunk(chunk,"btIntIndexData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr); + serializer->finalizeChunk(chunk, "btIntIndexData", BT_ARRAY_CODE, (void*)chunk->m_oldPtr); } break; } - case PHY_SHORT: + case PHY_SHORT: { if (numtriangles) { - btChunk* chunk = serializer->allocate(sizeof(btShortIntIndexTripletData),numtriangles); + btChunk* chunk = serializer->allocate(sizeof(btShortIntIndexTripletData), numtriangles); btShortIntIndexTripletData* tmpIndices = (btShortIntIndexTripletData*)chunk->m_oldPtr; - memPtr->m_3indices16 = (btShortIntIndexTripletData*) serializer->getUniquePointer(tmpIndices); - for (gfxindex=0;gfxindexm_3indices16 = (btShortIntIndexTripletData*)serializer->getUniquePointer(tmpIndices); + for (gfxindex = 0; gfxindex < numtriangles; gfxindex++) { - unsigned short int* tri_indices= (unsigned short int*)(indexbase+gfxindex*indexstride); + unsigned short int* tri_indices = (unsigned short int*)(indexbase + gfxindex * indexstride); tmpIndices[gfxindex].m_values[0] = tri_indices[0]; tmpIndices[gfxindex].m_values[1] = tri_indices[1]; tmpIndices[gfxindex].m_values[2] = tri_indices[2]; @@ -297,7 +289,7 @@ const char* btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* s tmpIndices[gfxindex].m_pad[0] = 0; tmpIndices[gfxindex].m_pad[1] = 0; } - serializer->finalizeChunk(chunk,"btShortIntIndexTripletData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr); + serializer->finalizeChunk(chunk, "btShortIntIndexTripletData", BT_ARRAY_CODE, (void*)chunk->m_oldPtr); } break; } @@ -305,23 +297,23 @@ const char* btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* s { if (numtriangles) { - btChunk* chunk = serializer->allocate(sizeof(btCharIndexTripletData),numtriangles); + btChunk* chunk = serializer->allocate(sizeof(btCharIndexTripletData), numtriangles); btCharIndexTripletData* tmpIndices = (btCharIndexTripletData*)chunk->m_oldPtr; - memPtr->m_3indices8 = (btCharIndexTripletData*) serializer->getUniquePointer(tmpIndices); - for (gfxindex=0;gfxindexm_3indices8 = (btCharIndexTripletData*)serializer->getUniquePointer(tmpIndices); + for (gfxindex = 0; gfxindex < numtriangles; gfxindex++) { - unsigned char* tri_indices= (unsigned char*)(indexbase+gfxindex*indexstride); + unsigned char* tri_indices = (unsigned char*)(indexbase + gfxindex * indexstride); tmpIndices[gfxindex].m_values[0] = tri_indices[0]; tmpIndices[gfxindex].m_values[1] = tri_indices[1]; tmpIndices[gfxindex].m_values[2] = tri_indices[2]; // Fill padding with zeros to appease msan. tmpIndices[gfxindex].m_pad = 0; } - serializer->finalizeChunk(chunk,"btCharIndexTripletData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr); + serializer->finalizeChunk(chunk, "btCharIndexTripletData", BT_ARRAY_CODE, (void*)chunk->m_oldPtr); } break; } - default: + default: { btAssert(0); //unknown index type @@ -330,54 +322,54 @@ const char* btStridingMeshInterface::serialize(void* dataBuffer, btSerializer* s switch (type) { - case PHY_FLOAT: - { - float* graphicsbase; - - if (numverts) - { - btChunk* chunk = serializer->allocate(sizeof(btVector3FloatData),numverts); - btVector3FloatData* tmpVertices = (btVector3FloatData*) chunk->m_oldPtr; - memPtr->m_vertices3f = (btVector3FloatData *)serializer->getUniquePointer(tmpVertices); - for (int i=0;ifinalizeChunk(chunk,"btVector3FloatData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr); - } - break; - } - - case PHY_DOUBLE: + case PHY_FLOAT: { + float* graphicsbase; + if (numverts) { - btChunk* chunk = serializer->allocate(sizeof(btVector3DoubleData),numverts); - btVector3DoubleData* tmpVertices = (btVector3DoubleData*) chunk->m_oldPtr; - memPtr->m_vertices3d = (btVector3DoubleData *) serializer->getUniquePointer(tmpVertices); - for (int i=0;ifinalizeChunk(chunk,"btVector3DoubleData",BT_ARRAY_CODE,(void*)chunk->m_oldPtr); + btChunk* chunk = serializer->allocate(sizeof(btVector3FloatData), numverts); + btVector3FloatData* tmpVertices = (btVector3FloatData*)chunk->m_oldPtr; + memPtr->m_vertices3f = (btVector3FloatData*)serializer->getUniquePointer(tmpVertices); + for (int i = 0; i < numverts; i++) + { + graphicsbase = (float*)(vertexbase + i * stride); + tmpVertices[i].m_floats[0] = graphicsbase[0]; + tmpVertices[i].m_floats[1] = graphicsbase[1]; + tmpVertices[i].m_floats[2] = graphicsbase[2]; + } + serializer->finalizeChunk(chunk, "btVector3FloatData", BT_ARRAY_CODE, (void*)chunk->m_oldPtr); } break; } - default: - btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE)); + case PHY_DOUBLE: + { + if (numverts) + { + btChunk* chunk = serializer->allocate(sizeof(btVector3DoubleData), numverts); + btVector3DoubleData* tmpVertices = (btVector3DoubleData*)chunk->m_oldPtr; + memPtr->m_vertices3d = (btVector3DoubleData*)serializer->getUniquePointer(tmpVertices); + for (int i = 0; i < numverts; i++) + { + double* graphicsbase = (double*)(vertexbase + i * stride); //for now convert to float, might leave it at double + tmpVertices[i].m_floats[0] = graphicsbase[0]; + tmpVertices[i].m_floats[1] = graphicsbase[1]; + tmpVertices[i].m_floats[2] = graphicsbase[2]; + } + serializer->finalizeChunk(chunk, "btVector3DoubleData", BT_ARRAY_CODE, (void*)chunk->m_oldPtr); + } + break; + } + + default: + btAssert((type == PHY_FLOAT) || (type == PHY_DOUBLE)); } unLockReadOnlyVertexBase(part); } - serializer->finalizeChunk(chunk,"btMeshPartData",BT_ARRAY_CODE,chunk->m_oldPtr); + serializer->finalizeChunk(chunk, "btMeshPartData", BT_ARRAY_CODE, chunk->m_oldPtr); } // Fill padding with zeros to appease msan. diff --git a/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h b/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h index 9fbe13976..7d729ee0d 100644 --- a/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h +++ b/src/BulletCollision/CollisionShapes/btStridingMeshInterface.h @@ -20,110 +20,102 @@ subject to the following restrictions: #include "btTriangleCallback.h" #include "btConcaveShape.h" - - - - /// The btStridingMeshInterface is the interface class for high performance generic access to triangle meshes, used in combination with btBvhTriangleMeshShape and some other collision shapes. /// Using index striding of 3*sizeof(integer) it can use triangle arrays, using index striding of 1*sizeof(integer) it can handle triangle strips. /// It allows for sharing graphics and collision meshes. Also it provides locking/unlocking of graphics meshes that are in gpu memory. -ATTRIBUTE_ALIGNED16(class ) btStridingMeshInterface +ATTRIBUTE_ALIGNED16(class) +btStridingMeshInterface { - protected: - - btVector3 m_scaling; +protected: + btVector3 m_scaling; - public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - - btStridingMeshInterface() :m_scaling(btScalar(1.),btScalar(1.),btScalar(1.)) - { +public: + BT_DECLARE_ALIGNED_ALLOCATOR(); - } + btStridingMeshInterface() : m_scaling(btScalar(1.), btScalar(1.), btScalar(1.)) + { + } - virtual ~btStridingMeshInterface(); + virtual ~btStridingMeshInterface(); + virtual void InternalProcessAllTriangles(btInternalTriangleIndexCallback * callback, const btVector3& aabbMin, const btVector3& aabbMax) const; + ///brute force method to calculate aabb + void calculateAabbBruteForce(btVector3 & aabbMin, btVector3 & aabbMax); - virtual void InternalProcessAllTriangles(btInternalTriangleIndexCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + /// get read and write access to a subpart of a triangle mesh + /// this subpart has a continuous array of vertices and indices + /// in this way the mesh can be handled as chunks of memory with striding + /// very similar to OpenGL vertexarray support + /// make a call to unLockVertexBase when the read and write access is finished + virtual void getLockedVertexIndexBase(unsigned char** vertexbase, int& numverts, PHY_ScalarType& type, int& stride, unsigned char** indexbase, int& indexstride, int& numfaces, PHY_ScalarType& indicestype, int subpart = 0) = 0; - ///brute force method to calculate aabb - void calculateAabbBruteForce(btVector3& aabbMin,btVector3& aabbMax); + virtual void getLockedReadOnlyVertexIndexBase(const unsigned char** vertexbase, int& numverts, PHY_ScalarType& type, int& stride, const unsigned char** indexbase, int& indexstride, int& numfaces, PHY_ScalarType& indicestype, int subpart = 0) const = 0; - /// get read and write access to a subpart of a triangle mesh - /// this subpart has a continuous array of vertices and indices - /// in this way the mesh can be handled as chunks of memory with striding - /// very similar to OpenGL vertexarray support - /// make a call to unLockVertexBase when the read and write access is finished - virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0)=0; - - virtual void getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& stride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0) const=0; - - /// unLockVertexBase finishes the access to a subpart of the triangle mesh - /// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished - virtual void unLockVertexBase(int subpart)=0; + /// unLockVertexBase finishes the access to a subpart of the triangle mesh + /// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished + virtual void unLockVertexBase(int subpart) = 0; - virtual void unLockReadOnlyVertexBase(int subpart) const=0; + virtual void unLockReadOnlyVertexBase(int subpart) const = 0; + /// getNumSubParts returns the number of seperate subparts + /// each subpart has a continuous array of vertices and indices + virtual int getNumSubParts() const = 0; - /// getNumSubParts returns the number of seperate subparts - /// each subpart has a continuous array of vertices and indices - virtual int getNumSubParts() const=0; + virtual void preallocateVertices(int numverts) = 0; + virtual void preallocateIndices(int numindices) = 0; - virtual void preallocateVertices(int numverts)=0; - virtual void preallocateIndices(int numindices)=0; + virtual bool hasPremadeAabb() const { return false; } + virtual void setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax) const + { + (void)aabbMin; + (void)aabbMax; + } + virtual void getPremadeAabb(btVector3 * aabbMin, btVector3 * aabbMax) const + { + (void)aabbMin; + (void)aabbMax; + } - virtual bool hasPremadeAabb() const { return false; } - virtual void setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const - { - (void) aabbMin; - (void) aabbMax; - } - virtual void getPremadeAabb(btVector3* aabbMin, btVector3* aabbMax ) const - { - (void) aabbMin; - (void) aabbMax; - } - - const btVector3& getScaling() const { - return m_scaling; - } - void setScaling(const btVector3& scaling) - { - m_scaling = scaling; - } - - virtual int calculateSerializeBufferSize() const; - - ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + const btVector3& getScaling() const + { + return m_scaling; + } + void setScaling(const btVector3& scaling) + { + m_scaling = scaling; + } + virtual int calculateSerializeBufferSize() const; + ///fills the dataBuffer and returns the struct name (and 0 on failure) + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; }; -struct btIntIndexData +struct btIntIndexData { - int m_value; + int m_value; }; -struct btShortIntIndexData +struct btShortIntIndexData { short m_value; char m_pad[2]; }; -struct btShortIntIndexTripletData +struct btShortIntIndexTripletData { - short m_values[3]; - char m_pad[2]; + short m_values[3]; + char m_pad[2]; }; -struct btCharIndexTripletData +struct btCharIndexTripletData { unsigned char m_values[3]; - char m_pad; + char m_pad; }; +// clang-format off ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 struct btMeshPartData @@ -151,14 +143,11 @@ struct btStridingMeshInterfaceData char m_padding[4]; }; +// clang-format on - - -SIMD_FORCE_INLINE int btStridingMeshInterface::calculateSerializeBufferSize() const +SIMD_FORCE_INLINE int btStridingMeshInterface::calculateSerializeBufferSize() const { return sizeof(btStridingMeshInterfaceData); } - - -#endif //BT_STRIDING_MESHINTERFACE_H +#endif //BT_STRIDING_MESHINTERFACE_H diff --git a/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp b/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp index 52f346bf7..c4d33c429 100644 --- a/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp +++ b/src/BulletCollision/CollisionShapes/btTetrahedronShape.cpp @@ -16,29 +16,29 @@ subject to the following restrictions: #include "btTetrahedronShape.h" #include "LinearMath/btMatrix3x3.h" -btBU_Simplex1to4::btBU_Simplex1to4() : btPolyhedralConvexAabbCachingShape (), -m_numVertices(0) +btBU_Simplex1to4::btBU_Simplex1to4() : btPolyhedralConvexAabbCachingShape(), + m_numVertices(0) { m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE; } -btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0) : btPolyhedralConvexAabbCachingShape (), -m_numVertices(0) +btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0) : btPolyhedralConvexAabbCachingShape(), + m_numVertices(0) { m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE; addVertex(pt0); } -btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1) : btPolyhedralConvexAabbCachingShape (), -m_numVertices(0) +btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0, const btVector3& pt1) : btPolyhedralConvexAabbCachingShape(), + m_numVertices(0) { m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE; addVertex(pt0); addVertex(pt1); } -btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2) : btPolyhedralConvexAabbCachingShape (), -m_numVertices(0) +btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0, const btVector3& pt1, const btVector3& pt2) : btPolyhedralConvexAabbCachingShape(), + m_numVertices(0) { m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE; addVertex(pt0); @@ -46,8 +46,8 @@ m_numVertices(0) addVertex(pt2); } -btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0,const btVector3& pt1,const btVector3& pt2,const btVector3& pt3) : btPolyhedralConvexAabbCachingShape (), -m_numVertices(0) +btBU_Simplex1to4::btBU_Simplex1to4(const btVector3& pt0, const btVector3& pt1, const btVector3& pt2, const btVector3& pt3) : btPolyhedralConvexAabbCachingShape(), + m_numVertices(0) { m_shapeType = TETRAHEDRAL_SHAPE_PROXYTYPE; addVertex(pt0); @@ -56,17 +56,16 @@ m_numVertices(0) addVertex(pt3); } - -void btBU_Simplex1to4::getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +void btBU_Simplex1to4::getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const { #if 1 - btPolyhedralConvexAabbCachingShape::getAabb(t,aabbMin,aabbMax); + btPolyhedralConvexAabbCachingShape::getAabb(t, aabbMin, aabbMax); #else - aabbMin.setValue(BT_LARGE_FLOAT,BT_LARGE_FLOAT,BT_LARGE_FLOAT); - aabbMax.setValue(-BT_LARGE_FLOAT,-BT_LARGE_FLOAT,-BT_LARGE_FLOAT); + aabbMin.setValue(BT_LARGE_FLOAT, BT_LARGE_FLOAT, BT_LARGE_FLOAT); + aabbMax.setValue(-BT_LARGE_FLOAT, -BT_LARGE_FLOAT, -BT_LARGE_FLOAT); //just transform the vertices in worldspace, and take their AABB - for (int i=0;i m_triangleBuffer; - btAlignedObjectArray m_triangleBuffer; - public: - - virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex); - - int getNumTriangles() const + + int getNumTriangles() const { return int(m_triangleBuffer.size()); } - - const btTriangle& getTriangle(int index) const + + const btTriangle& getTriangle(int index) const { return m_triangleBuffer[index]; } - void clearBuffer() + void clearBuffer() { m_triangleBuffer.clear(); } - }; - -#endif //BT_TRIANGLE_BUFFER_H - +#endif //BT_TRIANGLE_BUFFER_H diff --git a/src/BulletCollision/CollisionShapes/btTriangleCallback.cpp b/src/BulletCollision/CollisionShapes/btTriangleCallback.cpp index f558bf6d2..5bd2c595f 100644 --- a/src/BulletCollision/CollisionShapes/btTriangleCallback.cpp +++ b/src/BulletCollision/CollisionShapes/btTriangleCallback.cpp @@ -17,12 +17,8 @@ subject to the following restrictions: btTriangleCallback::~btTriangleCallback() { - } - btInternalTriangleIndexCallback::~btInternalTriangleIndexCallback() { - } - diff --git a/src/BulletCollision/CollisionShapes/btTriangleCallback.h b/src/BulletCollision/CollisionShapes/btTriangleCallback.h index 461c57f87..d3644891e 100644 --- a/src/BulletCollision/CollisionShapes/btTriangleCallback.h +++ b/src/BulletCollision/CollisionShapes/btTriangleCallback.h @@ -18,13 +18,11 @@ subject to the following restrictions: #include "LinearMath/btVector3.h" - ///The btTriangleCallback provides a callback for each overlapping triangle when calling processAllTriangles. ///This callback is called by processAllTriangles for all btConcaveShape derived class, such as btBvhTriangleMeshShape, btStaticPlaneShape and btHeightfieldTerrainShape. class btTriangleCallback { public: - virtual ~btTriangleCallback(); virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) = 0; }; @@ -32,11 +30,8 @@ public: class btInternalTriangleIndexCallback { public: - virtual ~btInternalTriangleIndexCallback(); - virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) = 0; + virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex) = 0; }; - - -#endif //BT_TRIANGLE_CALLBACK_H +#endif //BT_TRIANGLE_CALLBACK_H diff --git a/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp index a665024cb..dae425519 100644 --- a/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp +++ b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.cpp @@ -15,81 +15,76 @@ subject to the following restrictions: #include "btTriangleIndexVertexArray.h" -btTriangleIndexVertexArray::btTriangleIndexVertexArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride,int numVertices,btScalar* vertexBase,int vertexStride) -: m_hasAabb(0) +btTriangleIndexVertexArray::btTriangleIndexVertexArray(int numTriangles, int* triangleIndexBase, int triangleIndexStride, int numVertices, btScalar* vertexBase, int vertexStride) + : m_hasAabb(0) { btIndexedMesh mesh; mesh.m_numTriangles = numTriangles; - mesh.m_triangleIndexBase = (const unsigned char *)triangleIndexBase; + mesh.m_triangleIndexBase = (const unsigned char*)triangleIndexBase; mesh.m_triangleIndexStride = triangleIndexStride; mesh.m_numVertices = numVertices; - mesh.m_vertexBase = (const unsigned char *)vertexBase; + mesh.m_vertexBase = (const unsigned char*)vertexBase; mesh.m_vertexStride = vertexStride; addIndexedMesh(mesh); - } btTriangleIndexVertexArray::~btTriangleIndexVertexArray() { - } -void btTriangleIndexVertexArray::getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) +void btTriangleIndexVertexArray::getLockedVertexIndexBase(unsigned char** vertexbase, int& numverts, PHY_ScalarType& type, int& vertexStride, unsigned char** indexbase, int& indexstride, int& numfaces, PHY_ScalarType& indicestype, int subpart) { - btAssert(subpart< getNumSubParts() ); + btAssert(subpart < getNumSubParts()); btIndexedMesh& mesh = m_indexedMeshes[subpart]; numverts = mesh.m_numVertices; - (*vertexbase) = (unsigned char *) mesh.m_vertexBase; + (*vertexbase) = (unsigned char*)mesh.m_vertexBase; - type = mesh.m_vertexType; + type = mesh.m_vertexType; vertexStride = mesh.m_vertexStride; numfaces = mesh.m_numTriangles; - (*indexbase) = (unsigned char *)mesh.m_triangleIndexBase; + (*indexbase) = (unsigned char*)mesh.m_triangleIndexBase; indexstride = mesh.m_triangleIndexStride; indicestype = mesh.m_indexType; } -void btTriangleIndexVertexArray::getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart) const +void btTriangleIndexVertexArray::getLockedReadOnlyVertexIndexBase(const unsigned char** vertexbase, int& numverts, PHY_ScalarType& type, int& vertexStride, const unsigned char** indexbase, int& indexstride, int& numfaces, PHY_ScalarType& indicestype, int subpart) const { const btIndexedMesh& mesh = m_indexedMeshes[subpart]; numverts = mesh.m_numVertices; - (*vertexbase) = (const unsigned char *)mesh.m_vertexBase; + (*vertexbase) = (const unsigned char*)mesh.m_vertexBase; + + type = mesh.m_vertexType; - type = mesh.m_vertexType; - vertexStride = mesh.m_vertexStride; numfaces = mesh.m_numTriangles; - (*indexbase) = (const unsigned char *)mesh.m_triangleIndexBase; + (*indexbase) = (const unsigned char*)mesh.m_triangleIndexBase; indexstride = mesh.m_triangleIndexStride; indicestype = mesh.m_indexType; } -bool btTriangleIndexVertexArray::hasPremadeAabb() const +bool btTriangleIndexVertexArray::hasPremadeAabb() const { return (m_hasAabb == 1); } - -void btTriangleIndexVertexArray::setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const +void btTriangleIndexVertexArray::setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax) const { m_aabbMin = aabbMin; m_aabbMax = aabbMax; - m_hasAabb = 1; // this is intentionally an int see notes in header + m_hasAabb = 1; // this is intentionally an int see notes in header } -void btTriangleIndexVertexArray::getPremadeAabb(btVector3* aabbMin, btVector3* aabbMax ) const +void btTriangleIndexVertexArray::getPremadeAabb(btVector3* aabbMin, btVector3* aabbMax) const { *aabbMin = m_aabbMin; *aabbMax = m_aabbMax; } - - diff --git a/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h index b7a6f7436..8ebb22baa 100644 --- a/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h +++ b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h @@ -20,62 +20,59 @@ subject to the following restrictions: #include "LinearMath/btAlignedObjectArray.h" #include "LinearMath/btScalar.h" - ///The btIndexedMesh indexes a single vertex and index array. Multiple btIndexedMesh objects can be passed into a btTriangleIndexVertexArray using addIndexedMesh. ///Instead of the number of indices, we pass the number of triangles. -ATTRIBUTE_ALIGNED16( struct) btIndexedMesh +ATTRIBUTE_ALIGNED16(struct) +btIndexedMesh { BT_DECLARE_ALIGNED_ALLOCATOR(); - int m_numTriangles; - const unsigned char * m_triangleIndexBase; - // Size in byte of the indices for one triangle (3*sizeof(index_type) if the indices are tightly packed) - int m_triangleIndexStride; - int m_numVertices; - const unsigned char * m_vertexBase; - // Size of a vertex, in bytes - int m_vertexStride; + int m_numTriangles; + const unsigned char* m_triangleIndexBase; + // Size in byte of the indices for one triangle (3*sizeof(index_type) if the indices are tightly packed) + int m_triangleIndexStride; + int m_numVertices; + const unsigned char* m_vertexBase; + // Size of a vertex, in bytes + int m_vertexStride; - // The index type is set when adding an indexed mesh to the - // btTriangleIndexVertexArray, do not set it manually - PHY_ScalarType m_indexType; + // The index type is set when adding an indexed mesh to the + // btTriangleIndexVertexArray, do not set it manually + PHY_ScalarType m_indexType; - // The vertex type has a default type similar to Bullet's precision mode (float or double) - // but can be set manually if you for example run Bullet with double precision but have - // mesh data in single precision.. - PHY_ScalarType m_vertexType; + // The vertex type has a default type similar to Bullet's precision mode (float or double) + // but can be set manually if you for example run Bullet with double precision but have + // mesh data in single precision.. + PHY_ScalarType m_vertexType; - - btIndexedMesh() - :m_indexType(PHY_INTEGER), + btIndexedMesh() + : m_indexType(PHY_INTEGER), #ifdef BT_USE_DOUBLE_PRECISION - m_vertexType(PHY_DOUBLE) -#else // BT_USE_DOUBLE_PRECISION - m_vertexType(PHY_FLOAT) -#endif // BT_USE_DOUBLE_PRECISION - { - } -} -; + m_vertexType(PHY_DOUBLE) +#else // BT_USE_DOUBLE_PRECISION + m_vertexType(PHY_FLOAT) +#endif // BT_USE_DOUBLE_PRECISION + { + } +}; - -typedef btAlignedObjectArray IndexedMeshArray; +typedef btAlignedObjectArray IndexedMeshArray; ///The btTriangleIndexVertexArray allows to access multiple triangle meshes, by indexing into existing triangle/index arrays. ///Additional meshes can be added using addIndexedMesh ///No duplicate is made of the vertex/index data, it only indexes into external vertex/index arrays. ///So keep those arrays around during the lifetime of this btTriangleIndexVertexArray. -ATTRIBUTE_ALIGNED16( class) btTriangleIndexVertexArray : public btStridingMeshInterface +ATTRIBUTE_ALIGNED16(class) +btTriangleIndexVertexArray : public btStridingMeshInterface { protected: - IndexedMeshArray m_indexedMeshes; + IndexedMeshArray m_indexedMeshes; int m_pad[2]; - mutable int m_hasAabb; // using int instead of bool to maintain alignment + mutable int m_hasAabb; // using int instead of bool to maintain alignment mutable btVector3 m_aabbMin; mutable btVector3 m_aabbMax; public: - BT_DECLARE_ALIGNED_ALLOCATOR(); btTriangleIndexVertexArray() : m_hasAabb(0) @@ -85,49 +82,47 @@ public: virtual ~btTriangleIndexVertexArray(); //just to be backwards compatible - btTriangleIndexVertexArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride,int numVertices,btScalar* vertexBase,int vertexStride); - - void addIndexedMesh(const btIndexedMesh& mesh, PHY_ScalarType indexType = PHY_INTEGER) + btTriangleIndexVertexArray(int numTriangles, int* triangleIndexBase, int triangleIndexStride, int numVertices, btScalar* vertexBase, int vertexStride); + + void addIndexedMesh(const btIndexedMesh& mesh, PHY_ScalarType indexType = PHY_INTEGER) { m_indexedMeshes.push_back(mesh); - m_indexedMeshes[m_indexedMeshes.size()-1].m_indexType = indexType; + m_indexedMeshes[m_indexedMeshes.size() - 1].m_indexType = indexType; } - - - virtual void getLockedVertexIndexBase(unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0); - virtual void getLockedReadOnlyVertexIndexBase(const unsigned char **vertexbase, int& numverts,PHY_ScalarType& type, int& vertexStride,const unsigned char **indexbase,int & indexstride,int& numfaces,PHY_ScalarType& indicestype,int subpart=0) const; + virtual void getLockedVertexIndexBase(unsigned char** vertexbase, int& numverts, PHY_ScalarType& type, int& vertexStride, unsigned char** indexbase, int& indexstride, int& numfaces, PHY_ScalarType& indicestype, int subpart = 0); + + virtual void getLockedReadOnlyVertexIndexBase(const unsigned char** vertexbase, int& numverts, PHY_ScalarType& type, int& vertexStride, const unsigned char** indexbase, int& indexstride, int& numfaces, PHY_ScalarType& indicestype, int subpart = 0) const; /// unLockVertexBase finishes the access to a subpart of the triangle mesh /// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished - virtual void unLockVertexBase(int subpart) {(void)subpart;} + virtual void unLockVertexBase(int subpart) { (void)subpart; } - virtual void unLockReadOnlyVertexBase(int subpart) const {(void)subpart;} + virtual void unLockReadOnlyVertexBase(int subpart) const { (void)subpart; } /// getNumSubParts returns the number of seperate subparts /// each subpart has a continuous array of vertices and indices - virtual int getNumSubParts() const { + virtual int getNumSubParts() const + { return (int)m_indexedMeshes.size(); } - IndexedMeshArray& getIndexedMeshArray() + IndexedMeshArray& getIndexedMeshArray() { return m_indexedMeshes; } - const IndexedMeshArray& getIndexedMeshArray() const + const IndexedMeshArray& getIndexedMeshArray() const { return m_indexedMeshes; } - virtual void preallocateVertices(int numverts){(void) numverts;} - virtual void preallocateIndices(int numindices){(void) numindices;} + virtual void preallocateVertices(int numverts) { (void)numverts; } + virtual void preallocateIndices(int numindices) { (void)numindices; } - virtual bool hasPremadeAabb() const; - virtual void setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax ) const; - virtual void getPremadeAabb(btVector3* aabbMin, btVector3* aabbMax ) const; + virtual bool hasPremadeAabb() const; + virtual void setPremadeAabb(const btVector3& aabbMin, const btVector3& aabbMax) const; + virtual void getPremadeAabb(btVector3 * aabbMin, btVector3 * aabbMax) const; +}; -} -; - -#endif //BT_TRIANGLE_INDEX_VERTEX_ARRAY_H +#endif //BT_TRIANGLE_INDEX_VERTEX_ARRAY_H diff --git a/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp index dc562941a..4bf133d7a 100644 --- a/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp +++ b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.cpp @@ -17,70 +17,68 @@ subject to the following restrictions: #include "btTriangleIndexVertexMaterialArray.h" -btTriangleIndexVertexMaterialArray::btTriangleIndexVertexMaterialArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride, - int numVertices,btScalar* vertexBase,int vertexStride, - int numMaterials, unsigned char* materialBase, int materialStride, - int* triangleMaterialsBase, int materialIndexStride) : -btTriangleIndexVertexArray(numTriangles, triangleIndexBase, triangleIndexStride, numVertices, vertexBase, vertexStride) +btTriangleIndexVertexMaterialArray::btTriangleIndexVertexMaterialArray(int numTriangles, int* triangleIndexBase, int triangleIndexStride, + int numVertices, btScalar* vertexBase, int vertexStride, + int numMaterials, unsigned char* materialBase, int materialStride, + int* triangleMaterialsBase, int materialIndexStride) : btTriangleIndexVertexArray(numTriangles, triangleIndexBase, triangleIndexStride, numVertices, vertexBase, vertexStride) { - btMaterialProperties mat; + btMaterialProperties mat; - mat.m_numMaterials = numMaterials; - mat.m_materialBase = materialBase; - mat.m_materialStride = materialStride; + mat.m_numMaterials = numMaterials; + mat.m_materialBase = materialBase; + mat.m_materialStride = materialStride; #ifdef BT_USE_DOUBLE_PRECISION - mat.m_materialType = PHY_DOUBLE; + mat.m_materialType = PHY_DOUBLE; #else - mat.m_materialType = PHY_FLOAT; + mat.m_materialType = PHY_FLOAT; #endif - mat.m_numTriangles = numTriangles; - mat.m_triangleMaterialsBase = (unsigned char *)triangleMaterialsBase; - mat.m_triangleMaterialStride = materialIndexStride; - mat.m_triangleType = PHY_INTEGER; + mat.m_numTriangles = numTriangles; + mat.m_triangleMaterialsBase = (unsigned char*)triangleMaterialsBase; + mat.m_triangleMaterialStride = materialIndexStride; + mat.m_triangleType = PHY_INTEGER; - addMaterialProperties(mat); + addMaterialProperties(mat); } - -void btTriangleIndexVertexMaterialArray::getLockedMaterialBase(unsigned char **materialBase, int& numMaterials, PHY_ScalarType& materialType, int& materialStride, - unsigned char ** triangleMaterialBase, int& numTriangles, int& triangleMaterialStride, PHY_ScalarType& triangleType, int subpart) +void btTriangleIndexVertexMaterialArray::getLockedMaterialBase(unsigned char** materialBase, int& numMaterials, PHY_ScalarType& materialType, int& materialStride, + unsigned char** triangleMaterialBase, int& numTriangles, int& triangleMaterialStride, PHY_ScalarType& triangleType, int subpart) { - btAssert(subpart< getNumSubParts() ); + btAssert(subpart < getNumSubParts()); - btMaterialProperties& mats = m_materials[subpart]; + btMaterialProperties& mats = m_materials[subpart]; - numMaterials = mats.m_numMaterials; - (*materialBase) = (unsigned char *) mats.m_materialBase; + numMaterials = mats.m_numMaterials; + (*materialBase) = (unsigned char*)mats.m_materialBase; #ifdef BT_USE_DOUBLE_PRECISION - materialType = PHY_DOUBLE; + materialType = PHY_DOUBLE; #else - materialType = PHY_FLOAT; + materialType = PHY_FLOAT; #endif - materialStride = mats.m_materialStride; + materialStride = mats.m_materialStride; - numTriangles = mats.m_numTriangles; - (*triangleMaterialBase) = (unsigned char *)mats.m_triangleMaterialsBase; - triangleMaterialStride = mats.m_triangleMaterialStride; - triangleType = mats.m_triangleType; + numTriangles = mats.m_numTriangles; + (*triangleMaterialBase) = (unsigned char*)mats.m_triangleMaterialsBase; + triangleMaterialStride = mats.m_triangleMaterialStride; + triangleType = mats.m_triangleType; } -void btTriangleIndexVertexMaterialArray::getLockedReadOnlyMaterialBase(const unsigned char **materialBase, int& numMaterials, PHY_ScalarType& materialType, int& materialStride, - const unsigned char ** triangleMaterialBase, int& numTriangles, int& triangleMaterialStride, PHY_ScalarType& triangleType, int subpart) +void btTriangleIndexVertexMaterialArray::getLockedReadOnlyMaterialBase(const unsigned char** materialBase, int& numMaterials, PHY_ScalarType& materialType, int& materialStride, + const unsigned char** triangleMaterialBase, int& numTriangles, int& triangleMaterialStride, PHY_ScalarType& triangleType, int subpart) { - btMaterialProperties& mats = m_materials[subpart]; + btMaterialProperties& mats = m_materials[subpart]; - numMaterials = mats.m_numMaterials; - (*materialBase) = (const unsigned char *) mats.m_materialBase; + numMaterials = mats.m_numMaterials; + (*materialBase) = (const unsigned char*)mats.m_materialBase; #ifdef BT_USE_DOUBLE_PRECISION - materialType = PHY_DOUBLE; + materialType = PHY_DOUBLE; #else - materialType = PHY_FLOAT; + materialType = PHY_FLOAT; #endif - materialStride = mats.m_materialStride; + materialStride = mats.m_materialStride; - numTriangles = mats.m_numTriangles; - (*triangleMaterialBase) = (const unsigned char *)mats.m_triangleMaterialsBase; - triangleMaterialStride = mats.m_triangleMaterialStride; - triangleType = mats.m_triangleType; + numTriangles = mats.m_numTriangles; + (*triangleMaterialBase) = (const unsigned char*)mats.m_triangleMaterialsBase; + triangleMaterialStride = mats.m_triangleMaterialStride; + triangleType = mats.m_triangleType; } diff --git a/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h index ba4f7b460..315b1e21f 100644 --- a/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h +++ b/src/BulletCollision/CollisionShapes/btTriangleIndexVertexMaterialArray.h @@ -20,26 +20,26 @@ subject to the following restrictions: #include "btTriangleIndexVertexArray.h" - -ATTRIBUTE_ALIGNED16( struct) btMaterialProperties +ATTRIBUTE_ALIGNED16(struct) +btMaterialProperties { - ///m_materialBase ==========> 2 btScalar values make up one material, friction then restitution - int m_numMaterials; - const unsigned char * m_materialBase; - int m_materialStride; - PHY_ScalarType m_materialType; - ///m_numTriangles <=========== This exists in the btIndexedMesh object for the same subpart, but since we're - /// padding the structure, it can be reproduced at no real cost - ///m_triangleMaterials =====> 1 integer value makes up one entry - /// eg: m_triangleMaterials[1] = 5; // This will set triangle 2 to use material 5 - int m_numTriangles; - const unsigned char * m_triangleMaterialsBase; - int m_triangleMaterialStride; - ///m_triangleType <========== Automatically set in addMaterialProperties - PHY_ScalarType m_triangleType; + ///m_materialBase ==========> 2 btScalar values make up one material, friction then restitution + int m_numMaterials; + const unsigned char* m_materialBase; + int m_materialStride; + PHY_ScalarType m_materialType; + ///m_numTriangles <=========== This exists in the btIndexedMesh object for the same subpart, but since we're + /// padding the structure, it can be reproduced at no real cost + ///m_triangleMaterials =====> 1 integer value makes up one entry + /// eg: m_triangleMaterials[1] = 5; // This will set triangle 2 to use material 5 + int m_numTriangles; + const unsigned char* m_triangleMaterialsBase; + int m_triangleMaterialStride; + ///m_triangleType <========== Automatically set in addMaterialProperties + PHY_ScalarType m_triangleType; }; -typedef btAlignedObjectArray MaterialArray; +typedef btAlignedObjectArray MaterialArray; ///Teh btTriangleIndexVertexMaterialArray is built on TriangleIndexVertexArray ///The addition of a material array allows for the utilization of the partID and @@ -47,38 +47,37 @@ typedef btAlignedObjectArray MaterialArray; ///TriangleIndexVertexArray, no duplicate is made of the material data, so it ///is the users responsibility to maintain the array during the lifetime of the ///TriangleIndexVertexMaterialArray. -ATTRIBUTE_ALIGNED16(class) btTriangleIndexVertexMaterialArray : public btTriangleIndexVertexArray +ATTRIBUTE_ALIGNED16(class) +btTriangleIndexVertexMaterialArray : public btTriangleIndexVertexArray { protected: - MaterialArray m_materials; - + MaterialArray m_materials; + public: BT_DECLARE_ALIGNED_ALLOCATOR(); - btTriangleIndexVertexMaterialArray() + btTriangleIndexVertexMaterialArray() { } - btTriangleIndexVertexMaterialArray(int numTriangles,int* triangleIndexBase,int triangleIndexStride, - int numVertices,btScalar* vertexBase,int vertexStride, - int numMaterials, unsigned char* materialBase, int materialStride, - int* triangleMaterialsBase, int materialIndexStride); + btTriangleIndexVertexMaterialArray(int numTriangles, int* triangleIndexBase, int triangleIndexStride, + int numVertices, btScalar* vertexBase, int vertexStride, + int numMaterials, unsigned char* materialBase, int materialStride, + int* triangleMaterialsBase, int materialIndexStride); - virtual ~btTriangleIndexVertexMaterialArray() {} + virtual ~btTriangleIndexVertexMaterialArray() {} - void addMaterialProperties(const btMaterialProperties& mat, PHY_ScalarType triangleType = PHY_INTEGER) - { - m_materials.push_back(mat); - m_materials[m_materials.size()-1].m_triangleType = triangleType; - } + void addMaterialProperties(const btMaterialProperties& mat, PHY_ScalarType triangleType = PHY_INTEGER) + { + m_materials.push_back(mat); + m_materials[m_materials.size() - 1].m_triangleType = triangleType; + } - virtual void getLockedMaterialBase(unsigned char **materialBase, int& numMaterials, PHY_ScalarType& materialType, int& materialStride, - unsigned char ** triangleMaterialBase, int& numTriangles, int& triangleMaterialStride, PHY_ScalarType& triangleType ,int subpart = 0); + virtual void getLockedMaterialBase(unsigned char** materialBase, int& numMaterials, PHY_ScalarType& materialType, int& materialStride, + unsigned char** triangleMaterialBase, int& numTriangles, int& triangleMaterialStride, PHY_ScalarType& triangleType, int subpart = 0); - virtual void getLockedReadOnlyMaterialBase(const unsigned char **materialBase, int& numMaterials, PHY_ScalarType& materialType, int& materialStride, - const unsigned char ** triangleMaterialBase, int& numTriangles, int& triangleMaterialStride, PHY_ScalarType& triangleType, int subpart = 0); + virtual void getLockedReadOnlyMaterialBase(const unsigned char** materialBase, int& numMaterials, PHY_ScalarType& materialType, int& materialStride, + const unsigned char** triangleMaterialBase, int& numTriangles, int& triangleMaterialStride, PHY_ScalarType& triangleType, int subpart = 0); +}; -} -; - -#endif //BT_MULTIMATERIAL_TRIANGLE_INDEX_VERTEX_ARRAY_H +#endif //BT_MULTIMATERIAL_TRIANGLE_INDEX_VERTEX_ARRAY_H diff --git a/src/BulletCollision/CollisionShapes/btTriangleInfoMap.h b/src/BulletCollision/CollisionShapes/btTriangleInfoMap.h index 642758959..8ee35ef5f 100644 --- a/src/BulletCollision/CollisionShapes/btTriangleInfoMap.h +++ b/src/BulletCollision/CollisionShapes/btTriangleInfoMap.h @@ -16,11 +16,9 @@ subject to the following restrictions: #ifndef _BT_TRIANGLE_INFO_MAP_H #define _BT_TRIANGLE_INFO_MAP_H - #include "LinearMath/btHashMap.h" #include "LinearMath/btSerializer.h" - ///for btTriangleInfo m_flags #define TRI_INFO_V0V1_CONVEX 1 #define TRI_INFO_V1V2_CONVEX 2 @@ -30,61 +28,58 @@ subject to the following restrictions: #define TRI_INFO_V1V2_SWAP_NORMALB 16 #define TRI_INFO_V2V0_SWAP_NORMALB 32 - ///The btTriangleInfo structure stores information to adjust collision normals to avoid collisions against internal edges -///it can be generated using -struct btTriangleInfo +///it can be generated using +struct btTriangleInfo { btTriangleInfo() { m_edgeV0V1Angle = SIMD_2_PI; m_edgeV1V2Angle = SIMD_2_PI; m_edgeV2V0Angle = SIMD_2_PI; - m_flags=0; + m_flags = 0; } - int m_flags; - - btScalar m_edgeV0V1Angle; - btScalar m_edgeV1V2Angle; - btScalar m_edgeV2V0Angle; + int m_flags; + btScalar m_edgeV0V1Angle; + btScalar m_edgeV1V2Angle; + btScalar m_edgeV2V0Angle; }; -typedef btHashMap btInternalTriangleInfoMap; - +typedef btHashMap btInternalTriangleInfoMap; ///The btTriangleInfoMap stores edge angle information for some triangles. You can compute this information yourself or using btGenerateInternalEdgeInfo. -struct btTriangleInfoMap : public btInternalTriangleInfoMap +struct btTriangleInfoMap : public btInternalTriangleInfoMap { - btScalar m_convexEpsilon;///used to determine if an edge or contact normal is convex, using the dot product - btScalar m_planarEpsilon; ///used to determine if a triangle edge is planar with zero angle - btScalar m_equalVertexThreshold; ///used to compute connectivity: if the distance between two vertices is smaller than m_equalVertexThreshold, they are considered to be 'shared' - btScalar m_edgeDistanceThreshold; ///used to determine edge contacts: if the closest distance between a contact point and an edge is smaller than this distance threshold it is considered to "hit the edge" - btScalar m_maxEdgeAngleThreshold; //ignore edges that connect triangles at an angle larger than this m_maxEdgeAngleThreshold - btScalar m_zeroAreaThreshold; ///used to determine if a triangle is degenerate (length squared of cross product of 2 triangle edges < threshold) - - + btScalar m_convexEpsilon; ///used to determine if an edge or contact normal is convex, using the dot product + btScalar m_planarEpsilon; ///used to determine if a triangle edge is planar with zero angle + btScalar m_equalVertexThreshold; ///used to compute connectivity: if the distance between two vertices is smaller than m_equalVertexThreshold, they are considered to be 'shared' + btScalar m_edgeDistanceThreshold; ///used to determine edge contacts: if the closest distance between a contact point and an edge is smaller than this distance threshold it is considered to "hit the edge" + btScalar m_maxEdgeAngleThreshold; //ignore edges that connect triangles at an angle larger than this m_maxEdgeAngleThreshold + btScalar m_zeroAreaThreshold; ///used to determine if a triangle is degenerate (length squared of cross product of 2 triangle edges < threshold) + btTriangleInfoMap() { m_convexEpsilon = 0.00f; m_planarEpsilon = 0.0001f; - m_equalVertexThreshold = btScalar(0.0001)*btScalar(0.0001); + m_equalVertexThreshold = btScalar(0.0001) * btScalar(0.0001); m_edgeDistanceThreshold = btScalar(0.1); - m_zeroAreaThreshold = btScalar(0.0001)*btScalar(0.0001); + m_zeroAreaThreshold = btScalar(0.0001) * btScalar(0.0001); m_maxEdgeAngleThreshold = SIMD_2_PI; } virtual ~btTriangleInfoMap() {} - virtual int calculateSerializeBufferSize() const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; - - void deSerialize(struct btTriangleInfoMapData& data); + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + void deSerialize(struct btTriangleInfoMapData& data); }; +// clang-format off + ///those fields have to be float and not btScalar for the serialization to work properly struct btTriangleInfoData { @@ -114,86 +109,86 @@ struct btTriangleInfoMapData char m_padding[4]; }; -SIMD_FORCE_INLINE int btTriangleInfoMap::calculateSerializeBufferSize() const +// clang-format on + +SIMD_FORCE_INLINE int btTriangleInfoMap::calculateSerializeBufferSize() const { return sizeof(btTriangleInfoMapData); } ///fills the dataBuffer and returns the struct name (and 0 on failure) -SIMD_FORCE_INLINE const char* btTriangleInfoMap::serialize(void* dataBuffer, btSerializer* serializer) const +SIMD_FORCE_INLINE const char* btTriangleInfoMap::serialize(void* dataBuffer, btSerializer* serializer) const { - btTriangleInfoMapData* tmapData = (btTriangleInfoMapData*) dataBuffer; + btTriangleInfoMapData* tmapData = (btTriangleInfoMapData*)dataBuffer; tmapData->m_convexEpsilon = (float)m_convexEpsilon; tmapData->m_planarEpsilon = (float)m_planarEpsilon; - tmapData->m_equalVertexThreshold =(float) m_equalVertexThreshold; + tmapData->m_equalVertexThreshold = (float)m_equalVertexThreshold; tmapData->m_edgeDistanceThreshold = (float)m_edgeDistanceThreshold; tmapData->m_zeroAreaThreshold = (float)m_zeroAreaThreshold; - + tmapData->m_hashTableSize = m_hashTable.size(); tmapData->m_hashTablePtr = tmapData->m_hashTableSize ? (int*)serializer->getUniquePointer((void*)&m_hashTable[0]) : 0; if (tmapData->m_hashTablePtr) - { + { //serialize an int buffer int sz = sizeof(int); int numElem = tmapData->m_hashTableSize; - btChunk* chunk = serializer->allocate(sz,numElem); + btChunk* chunk = serializer->allocate(sz, numElem); int* memPtr = (int*)chunk->m_oldPtr; - for (int i=0;ifinalizeChunk(chunk,"int",BT_ARRAY_CODE,(void*)&m_hashTable[0]); - + serializer->finalizeChunk(chunk, "int", BT_ARRAY_CODE, (void*)&m_hashTable[0]); } tmapData->m_nextSize = m_next.size(); - tmapData->m_nextPtr = tmapData->m_nextSize? (int*)serializer->getUniquePointer((void*)&m_next[0]): 0; + tmapData->m_nextPtr = tmapData->m_nextSize ? (int*)serializer->getUniquePointer((void*)&m_next[0]) : 0; if (tmapData->m_nextPtr) { int sz = sizeof(int); int numElem = tmapData->m_nextSize; - btChunk* chunk = serializer->allocate(sz,numElem); + btChunk* chunk = serializer->allocate(sz, numElem); int* memPtr = (int*)chunk->m_oldPtr; - for (int i=0;ifinalizeChunk(chunk,"int",BT_ARRAY_CODE,(void*)&m_next[0]); + serializer->finalizeChunk(chunk, "int", BT_ARRAY_CODE, (void*)&m_next[0]); } - + tmapData->m_numValues = m_valueArray.size(); - tmapData->m_valueArrayPtr = tmapData->m_numValues ? (btTriangleInfoData*)serializer->getUniquePointer((void*)&m_valueArray[0]): 0; + tmapData->m_valueArrayPtr = tmapData->m_numValues ? (btTriangleInfoData*)serializer->getUniquePointer((void*)&m_valueArray[0]) : 0; if (tmapData->m_valueArrayPtr) { int sz = sizeof(btTriangleInfoData); int numElem = tmapData->m_numValues; - btChunk* chunk = serializer->allocate(sz,numElem); + btChunk* chunk = serializer->allocate(sz, numElem); btTriangleInfoData* memPtr = (btTriangleInfoData*)chunk->m_oldPtr; - for (int i=0;im_edgeV0V1Angle = (float)m_valueArray[i].m_edgeV0V1Angle; memPtr->m_edgeV1V2Angle = (float)m_valueArray[i].m_edgeV1V2Angle; memPtr->m_edgeV2V0Angle = (float)m_valueArray[i].m_edgeV2V0Angle; memPtr->m_flags = m_valueArray[i].m_flags; } - serializer->finalizeChunk(chunk,"btTriangleInfoData",BT_ARRAY_CODE,(void*) &m_valueArray[0]); + serializer->finalizeChunk(chunk, "btTriangleInfoData", BT_ARRAY_CODE, (void*)&m_valueArray[0]); } - + tmapData->m_numKeys = m_keyArray.size(); tmapData->m_keyArrayPtr = tmapData->m_numKeys ? (int*)serializer->getUniquePointer((void*)&m_keyArray[0]) : 0; if (tmapData->m_keyArrayPtr) { int sz = sizeof(int); int numElem = tmapData->m_numValues; - btChunk* chunk = serializer->allocate(sz,numElem); + btChunk* chunk = serializer->allocate(sz, numElem); int* memPtr = (int*)chunk->m_oldPtr; - for (int i=0;ifinalizeChunk(chunk,"int",BT_ARRAY_CODE,(void*) &m_keyArray[0]); - + serializer->finalizeChunk(chunk, "int", BT_ARRAY_CODE, (void*)&m_keyArray[0]); } // Fill padding with zeros to appease msan. @@ -205,44 +200,39 @@ SIMD_FORCE_INLINE const char* btTriangleInfoMap::serialize(void* dataBuffer, btS return "btTriangleInfoMapData"; } - - ///fills the dataBuffer and returns the struct name (and 0 on failure) -SIMD_FORCE_INLINE void btTriangleInfoMap::deSerialize(btTriangleInfoMapData& tmapData ) +SIMD_FORCE_INLINE void btTriangleInfoMap::deSerialize(btTriangleInfoMapData& tmapData) { - - m_convexEpsilon = tmapData.m_convexEpsilon; m_planarEpsilon = tmapData.m_planarEpsilon; m_equalVertexThreshold = tmapData.m_equalVertexThreshold; m_edgeDistanceThreshold = tmapData.m_edgeDistanceThreshold; m_zeroAreaThreshold = tmapData.m_zeroAreaThreshold; m_hashTable.resize(tmapData.m_hashTableSize); - int i =0; - for (i=0;i m_4componentVertices; - btAlignedObjectArray m_3componentVertices; + btAlignedObjectArray m_4componentVertices; + btAlignedObjectArray m_3componentVertices; - btAlignedObjectArray m_32bitIndices; - btAlignedObjectArray m_16bitIndices; - bool m_use32bitIndices; - bool m_use4componentVertices; - + btAlignedObjectArray m_32bitIndices; + btAlignedObjectArray m_16bitIndices; + bool m_use32bitIndices; + bool m_use4componentVertices; - public: - btScalar m_weldingThreshold; +public: + btScalar m_weldingThreshold; - btTriangleMesh (bool use32bitIndices=true,bool use4componentVertices=true); + btTriangleMesh(bool use32bitIndices = true, bool use4componentVertices = true); - bool getUse32bitIndices() const - { - return m_use32bitIndices; - } + bool getUse32bitIndices() const + { + return m_use32bitIndices; + } - bool getUse4componentVertices() const - { - return m_use4componentVertices; - } - ///By default addTriangle won't search for duplicate vertices, because the search is very slow for large triangle meshes. - ///In general it is better to directly use btTriangleIndexVertexArray instead. - void addTriangle(const btVector3& vertex0,const btVector3& vertex1,const btVector3& vertex2, bool removeDuplicateVertices=false); + bool getUse4componentVertices() const + { + return m_use4componentVertices; + } + ///By default addTriangle won't search for duplicate vertices, because the search is very slow for large triangle meshes. + ///In general it is better to directly use btTriangleIndexVertexArray instead. + void addTriangle(const btVector3& vertex0, const btVector3& vertex1, const btVector3& vertex2, bool removeDuplicateVertices = false); - ///Add a triangle using its indices. Make sure the indices are pointing within the vertices array, so add the vertices first (and to be sure, avoid removal of duplicate vertices) - void addTriangleIndices(int index1, int index2, int index3 ); - - int getNumTriangles() const; + ///Add a triangle using its indices. Make sure the indices are pointing within the vertices array, so add the vertices first (and to be sure, avoid removal of duplicate vertices) + void addTriangleIndices(int index1, int index2, int index3); - virtual void preallocateVertices(int numverts); - virtual void preallocateIndices(int numindices); + int getNumTriangles() const; - ///findOrAddVertex is an internal method, use addTriangle instead - int findOrAddVertex(const btVector3& vertex, bool removeDuplicateVertices); - ///addIndex is an internal method, use addTriangle instead - void addIndex(int index); - + virtual void preallocateVertices(int numverts); + virtual void preallocateIndices(int numindices); + + ///findOrAddVertex is an internal method, use addTriangle instead + int findOrAddVertex(const btVector3& vertex, bool removeDuplicateVertices); + ///addIndex is an internal method, use addTriangle instead + void addIndex(int index); }; -#endif //BT_TRIANGLE_MESH_H - +#endif //BT_TRIANGLE_MESH_H diff --git a/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp b/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp index 0e1795140..aec239063 100644 --- a/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp +++ b/src/BulletCollision/CollisionShapes/btTriangleMeshShape.cpp @@ -20,12 +20,11 @@ subject to the following restrictions: #include "LinearMath/btAabbUtil2.h" #include "BulletCollision/CollisionShapes/btCollisionMargin.h" - btTriangleMeshShape::btTriangleMeshShape(btStridingMeshInterface* meshInterface) -: btConcaveShape (), m_meshInterface(meshInterface) + : btConcaveShape(), m_meshInterface(meshInterface) { m_shapeType = TRIANGLE_MESH_SHAPE_PROXYTYPE; - if(meshInterface->hasPremadeAabb()) + if (meshInterface->hasPremadeAabb()) { meshInterface->getPremadeAabb(&m_localAabbMin, &m_localAabbMax); } @@ -35,69 +34,60 @@ btTriangleMeshShape::btTriangleMeshShape(btStridingMeshInterface* meshInterface) } } - btTriangleMeshShape::~btTriangleMeshShape() { - } - - - -void btTriangleMeshShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const +void btTriangleMeshShape::getAabb(const btTransform& trans, btVector3& aabbMin, btVector3& aabbMax) const { + btVector3 localHalfExtents = btScalar(0.5) * (m_localAabbMax - m_localAabbMin); + localHalfExtents += btVector3(getMargin(), getMargin(), getMargin()); + btVector3 localCenter = btScalar(0.5) * (m_localAabbMax + m_localAabbMin); - btVector3 localHalfExtents = btScalar(0.5)*(m_localAabbMax-m_localAabbMin); - localHalfExtents += btVector3(getMargin(),getMargin(),getMargin()); - btVector3 localCenter = btScalar(0.5)*(m_localAabbMax+m_localAabbMin); - - btMatrix3x3 abs_b = trans.getBasis().absolute(); + btMatrix3x3 abs_b = trans.getBasis().absolute(); btVector3 center = trans(localCenter); - btVector3 extent = localHalfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); + btVector3 extent = localHalfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); aabbMin = center - extent; aabbMax = center + extent; } -void btTriangleMeshShape::recalcLocalAabb() +void btTriangleMeshShape::recalcLocalAabb() { - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) { - btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); + btVector3 vec(btScalar(0.), btScalar(0.), btScalar(0.)); vec[i] = btScalar(1.); btVector3 tmp = localGetSupportingVertex(vec); - m_localAabbMax[i] = tmp[i]+m_collisionMargin; + m_localAabbMax[i] = tmp[i] + m_collisionMargin; vec[i] = btScalar(-1.); tmp = localGetSupportingVertex(vec); - m_localAabbMin[i] = tmp[i]-m_collisionMargin; + m_localAabbMin[i] = tmp[i] - m_collisionMargin; } } - - class SupportVertexCallback : public btTriangleCallback { - btVector3 m_supportVertexLocal; -public: - btTransform m_worldTrans; +public: + btTransform m_worldTrans; btScalar m_maxDot; btVector3 m_supportVecLocal; - SupportVertexCallback(const btVector3& supportVecWorld,const btTransform& trans) - : m_supportVertexLocal(btScalar(0.),btScalar(0.),btScalar(0.)), m_worldTrans(trans) ,m_maxDot(btScalar(-BT_LARGE_FLOAT)) - + SupportVertexCallback(const btVector3& supportVecWorld, const btTransform& trans) + : m_supportVertexLocal(btScalar(0.), btScalar(0.), btScalar(0.)), m_worldTrans(trans), m_maxDot(btScalar(-BT_LARGE_FLOAT)) + { m_supportVecLocal = supportVecWorld * m_worldTrans.getBasis(); } - virtual void processTriangle( btVector3* triangle,int partId, int triangleIndex) + virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) { (void)partId; (void)triangleIndex; - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) { btScalar dot = m_supportVecLocal.dot(triangle[i]); if (dot > m_maxDot) @@ -113,14 +103,12 @@ public: return m_worldTrans(m_supportVertexLocal); } - btVector3 GetSupportVertexLocal() + btVector3 GetSupportVertexLocal() { return m_supportVertexLocal; } - }; - void btTriangleMeshShape::setLocalScaling(const btVector3& scaling) { m_meshInterface->setScaling(scaling); @@ -132,60 +120,46 @@ const btVector3& btTriangleMeshShape::getLocalScaling() const return m_meshInterface->getScaling(); } - - - - - //#define DEBUG_TRIANGLE_MESH - - -void btTriangleMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const +void btTriangleMeshShape::processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const { - struct FilteredCallback : public btInternalTriangleIndexCallback + struct FilteredCallback : public btInternalTriangleIndexCallback { btTriangleCallback* m_callback; btVector3 m_aabbMin; btVector3 m_aabbMax; - FilteredCallback(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) - :m_callback(callback), - m_aabbMin(aabbMin), - m_aabbMax(aabbMax) + FilteredCallback(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) + : m_callback(callback), + m_aabbMin(aabbMin), + m_aabbMax(aabbMax) { } - virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) + virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex) { - if (TestTriangleAgainstAabb2(&triangle[0],m_aabbMin,m_aabbMax)) + if (TestTriangleAgainstAabb2(&triangle[0], m_aabbMin, m_aabbMax)) { //check aabb in triangle-space, before doing this - m_callback->processTriangle(triangle,partId,triangleIndex); + m_callback->processTriangle(triangle, partId, triangleIndex); } - } - }; - FilteredCallback filterCallback(callback,aabbMin,aabbMax); + FilteredCallback filterCallback(callback, aabbMin, aabbMax); - m_meshInterface->InternalProcessAllTriangles(&filterCallback,aabbMin,aabbMax); + m_meshInterface->InternalProcessAllTriangles(&filterCallback, aabbMin, aabbMax); } - - - - -void btTriangleMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +void btTriangleMeshShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const { (void)mass; //moving concave objects not supported btAssert(0); - inertia.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); + inertia.setValue(btScalar(0.), btScalar(0.), btScalar(0.)); } - btVector3 btTriangleMeshShape::localGetSupportingVertex(const btVector3& vec) const { btVector3 supportVertex; @@ -193,15 +167,13 @@ btVector3 btTriangleMeshShape::localGetSupportingVertex(const btVector3& vec) co btTransform ident; ident.setIdentity(); - SupportVertexCallback supportCallback(vec,ident); + SupportVertexCallback supportCallback(vec, ident); + + btVector3 aabbMax(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); + + processAllTriangles(&supportCallback, -aabbMax, aabbMax); - btVector3 aabbMax(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); - - processAllTriangles(&supportCallback,-aabbMax,aabbMax); - supportVertex = supportCallback.GetSupportVertexLocal(); return supportVertex; } - - diff --git a/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h b/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h index 453e58005..4a70e283f 100644 --- a/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h +++ b/src/BulletCollision/CollisionShapes/btTriangleMeshShape.h @@ -19,18 +19,18 @@ subject to the following restrictions: #include "btConcaveShape.h" #include "btStridingMeshInterface.h" - ///The btTriangleMeshShape is an internal concave triangle mesh interface. Don't use this class directly, use btBvhTriangleMeshShape instead. -ATTRIBUTE_ALIGNED16(class) btTriangleMeshShape : public btConcaveShape +ATTRIBUTE_ALIGNED16(class) +btTriangleMeshShape : public btConcaveShape { protected: - btVector3 m_localAabbMin; - btVector3 m_localAabbMax; + btVector3 m_localAabbMin; + btVector3 m_localAabbMax; btStridingMeshInterface* m_meshInterface; ///btTriangleMeshShape constructor has been disabled/protected, so that users will not mistakenly use this class. ///Don't use btTriangleMeshShape but use btBvhTriangleMeshShape instead! - btTriangleMeshShape(btStridingMeshInterface* meshInterface); + btTriangleMeshShape(btStridingMeshInterface * meshInterface); public: BT_DECLARE_ALIGNED_ALLOCATOR(); @@ -39,23 +39,23 @@ public: virtual btVector3 localGetSupportingVertex(const btVector3& vec) const; - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const { btAssert(0); return localGetSupportingVertex(vec); } - void recalcLocalAabb(); + void recalcLocalAabb(); - virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const; - virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + virtual void processAllTriangles(btTriangleCallback * callback, const btVector3& aabbMin, const btVector3& aabbMax) const; - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + virtual void calculateLocalInertia(btScalar mass, btVector3 & inertia) const; - virtual void setLocalScaling(const btVector3& scaling); + virtual void setLocalScaling(const btVector3& scaling); virtual const btVector3& getLocalScaling() const; - + btStridingMeshInterface* getMeshInterface() { return m_meshInterface; @@ -75,16 +75,8 @@ public: return m_localAabbMax; } - - //debugging - virtual const char* getName()const {return "TRIANGLEMESH";} - - - + virtual const char* getName() const { return "TRIANGLEMESH"; } }; - - - -#endif //BT_TRIANGLE_MESH_SHAPE_H +#endif //BT_TRIANGLE_MESH_SHAPE_H diff --git a/src/BulletCollision/CollisionShapes/btTriangleShape.h b/src/BulletCollision/CollisionShapes/btTriangleShape.h index a8a80f82f..190cbdae6 100644 --- a/src/BulletCollision/CollisionShapes/btTriangleShape.h +++ b/src/BulletCollision/CollisionShapes/btTriangleShape.h @@ -19,15 +19,13 @@ subject to the following restrictions: #include "btConvexShape.h" #include "btBoxShape.h" -ATTRIBUTE_ALIGNED16(class) btTriangleShape : public btPolyhedralConvexShape +ATTRIBUTE_ALIGNED16(class) +btTriangleShape : public btPolyhedralConvexShape { - - public: + BT_DECLARE_ALIGNED_ALLOCATOR(); -BT_DECLARE_ALIGNED_ALLOCATOR(); - - btVector3 m_vertices1[3]; + btVector3 m_vertices1[3]; virtual int getNumVertices() const { @@ -43,7 +41,7 @@ BT_DECLARE_ALIGNED_ALLOCATOR(); { return m_vertices1[index]; } - virtual void getVertex(int index,btVector3& vert) const + virtual void getVertex(int index, btVector3& vert) const { vert = m_vertices1[index]; } @@ -52,83 +50,79 @@ BT_DECLARE_ALIGNED_ALLOCATOR(); { return 3; } - - virtual void getEdge(int i,btVector3& pa,btVector3& pb) const + + virtual void getEdge(int i, btVector3& pa, btVector3& pb) const { - getVertex(i,pa); - getVertex((i+1)%3,pb); + getVertex(i, pa); + getVertex((i + 1) % 3, pb); } - - virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax)const + virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const { -// btAssert(0); - getAabbSlow(t,aabbMin,aabbMax); + // btAssert(0); + getAabbSlow(t, aabbMin, aabbMax); } - btVector3 localGetSupportingVertexWithoutMargin(const btVector3& dir)const + btVector3 localGetSupportingVertexWithoutMargin(const btVector3& dir) const { - btVector3 dots = dir.dot3(m_vertices1[0], m_vertices1[1], m_vertices1[2]); - return m_vertices1[dots.maxAxis()]; - + btVector3 dots = dir.dot3(m_vertices1[0], m_vertices1[1], m_vertices1[2]); + return m_vertices1[dots.maxAxis()]; } - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const { - for (int i=0;ilocalGetSupportingVertexWithoutMargin(vec); - return tmpVertex*m_uniformScalingFactor; + return tmpVertex * m_uniformScalingFactor; } -void btUniformScalingShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const +void btUniformScalingShape::batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const { - m_childConvexShape->batchedUnitVectorGetSupportingVertexWithoutMargin(vectors,supportVerticesOut,numVectors); + m_childConvexShape->batchedUnitVectorGetSupportingVertexWithoutMargin(vectors, supportVerticesOut, numVectors); int i; - for (i=0;ilocalGetSupportingVertex(vec); - return tmpVertex*m_uniformScalingFactor; + return tmpVertex * m_uniformScalingFactor; } - -void btUniformScalingShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +void btUniformScalingShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const { - ///this linear upscaling is not realistic, but we don't deal with large mass ratios... btVector3 tmpInertia; - m_childConvexShape->calculateLocalInertia(mass,tmpInertia); + m_childConvexShape->calculateLocalInertia(mass, tmpInertia); inertia = tmpInertia * m_uniformScalingFactor; } - - ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version -void btUniformScalingShape::getAabb(const btTransform& trans,btVector3& aabbMin,btVector3& aabbMax) const +///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version +void btUniformScalingShape::getAabb(const btTransform& trans, btVector3& aabbMin, btVector3& aabbMax) const { - getAabbSlow(trans,aabbMin,aabbMax); - + getAabbSlow(trans, aabbMin, aabbMax); } -void btUniformScalingShape::getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const +void btUniformScalingShape::getAabbSlow(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const { #if 1 btVector3 _directions[] = - { - btVector3( 1., 0., 0.), - btVector3( 0., 1., 0.), - btVector3( 0., 0., 1.), - btVector3( -1., 0., 0.), - btVector3( 0., -1., 0.), - btVector3( 0., 0., -1.) - }; - + { + btVector3(1., 0., 0.), + btVector3(0., 1., 0.), + btVector3(0., 0., 1.), + btVector3(-1., 0., 0.), + btVector3(0., -1., 0.), + btVector3(0., 0., -1.)}; + btVector3 _supporting[] = - { - btVector3( 0., 0., 0.), - btVector3( 0., 0., 0.), - btVector3( 0., 0., 0.), - btVector3( 0., 0., 0.), - btVector3( 0., 0., 0.), - btVector3( 0., 0., 0.) - }; + { + btVector3(0., 0., 0.), + btVector3(0., 0., 0.), + btVector3(0., 0., 0.), + btVector3(0., 0., 0.), + btVector3(0., 0., 0.), + btVector3(0., 0., 0.)}; - for (int i=0;i<6;i++) + for (int i = 0; i < 6; i++) { - _directions[i] = _directions[i]*t.getBasis(); + _directions[i] = _directions[i] * t.getBasis(); } - - batchedUnitVectorGetSupportingVertexWithoutMargin(_directions, _supporting, 6); - - btVector3 aabbMin1(0,0,0),aabbMax1(0,0,0); - for ( int i = 0; i < 3; ++i ) + batchedUnitVectorGetSupportingVertexWithoutMargin(_directions, _supporting, 6); + + btVector3 aabbMin1(0, 0, 0), aabbMax1(0, 0, 0); + + for (int i = 0; i < 3; ++i) { aabbMax1[i] = t(_supporting[i])[i]; aabbMin1[i] = t(_supporting[i + 3])[i]; } - btVector3 marginVec(getMargin(),getMargin(),getMargin()); - aabbMin = aabbMin1-marginVec; - aabbMax = aabbMax1+marginVec; - + btVector3 marginVec(getMargin(), getMargin(), getMargin()); + aabbMin = aabbMin1 - marginVec; + aabbMax = aabbMax1 + marginVec; + #else btScalar margin = getMargin(); - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) { - btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); + btVector3 vec(btScalar(0.), btScalar(0.), btScalar(0.)); vec[i] = btScalar(1.); - btVector3 sv = localGetSupportingVertex(vec*t.getBasis()); + btVector3 sv = localGetSupportingVertex(vec * t.getBasis()); btVector3 tmp = t(sv); - aabbMax[i] = tmp[i]+margin; + aabbMax[i] = tmp[i] + margin; vec[i] = btScalar(-1.); - sv = localGetSupportingVertex(vec*t.getBasis()); + sv = localGetSupportingVertex(vec * t.getBasis()); tmp = t(sv); - aabbMin[i] = tmp[i]-margin; + aabbMin[i] = tmp[i] - margin; } #endif } -void btUniformScalingShape::setLocalScaling(const btVector3& scaling) +void btUniformScalingShape::setLocalScaling(const btVector3& scaling) { m_childConvexShape->setLocalScaling(scaling); } @@ -140,21 +130,21 @@ const btVector3& btUniformScalingShape::getLocalScaling() const return m_childConvexShape->getLocalScaling(); } -void btUniformScalingShape::setMargin(btScalar margin) +void btUniformScalingShape::setMargin(btScalar margin) { m_childConvexShape->setMargin(margin); } -btScalar btUniformScalingShape::getMargin() const +btScalar btUniformScalingShape::getMargin() const { return m_childConvexShape->getMargin() * m_uniformScalingFactor; } -int btUniformScalingShape::getNumPreferredPenetrationDirections() const +int btUniformScalingShape::getNumPreferredPenetrationDirections() const { return m_childConvexShape->getNumPreferredPenetrationDirections(); } - -void btUniformScalingShape::getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const + +void btUniformScalingShape::getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const { - m_childConvexShape->getPreferredPenetrationDirection(index,penetrationVector); + m_childConvexShape->getPreferredPenetrationDirection(index, penetrationVector); } diff --git a/src/BulletCollision/CollisionShapes/btUniformScalingShape.h b/src/BulletCollision/CollisionShapes/btUniformScalingShape.h index a10f58d24..4dfe34efb 100644 --- a/src/BulletCollision/CollisionShapes/btUniformScalingShape.h +++ b/src/BulletCollision/CollisionShapes/btUniformScalingShape.h @@ -17,73 +17,68 @@ subject to the following restrictions: #define BT_UNIFORM_SCALING_SHAPE_H #include "btConvexShape.h" -#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types +#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h" // for the types ///The btUniformScalingShape allows to re-use uniform scaled instances of btConvexShape in a memory efficient way. ///Istead of using btUniformScalingShape, it is better to use the non-uniform setLocalScaling method on convex shapes that implement it. -ATTRIBUTE_ALIGNED16(class) btUniformScalingShape : public btConvexShape +ATTRIBUTE_ALIGNED16(class) +btUniformScalingShape : public btConvexShape { - btConvexShape* m_childConvexShape; + btConvexShape* m_childConvexShape; - btScalar m_uniformScalingFactor; - - public: - + btScalar m_uniformScalingFactor; + +public: BT_DECLARE_ALIGNED_ALLOCATOR(); - - btUniformScalingShape( btConvexShape* convexChildShape, btScalar uniformScalingFactor); - + + btUniformScalingShape(btConvexShape * convexChildShape, btScalar uniformScalingFactor); + virtual ~btUniformScalingShape(); - - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const; - virtual btVector3 localGetSupportingVertex(const btVector3& vec)const; + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const; - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const; + virtual btVector3 localGetSupportingVertex(const btVector3& vec) const; - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const; - btScalar getUniformScalingFactor() const + virtual void calculateLocalInertia(btScalar mass, btVector3 & inertia) const; + + btScalar getUniformScalingFactor() const { return m_uniformScalingFactor; } - btConvexShape* getChildShape() + btConvexShape* getChildShape() { return m_childConvexShape; } - const btConvexShape* getChildShape() const + const btConvexShape* getChildShape() const { return m_childConvexShape; } - virtual const char* getName()const + virtual const char* getName() const { return "UniformScalingShape"; } - - /////////////////////////// - ///getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version - void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const; - virtual void getAabbSlow(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const; + virtual void getAabbSlow(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const; - virtual void setLocalScaling(const btVector3& scaling) ; - virtual const btVector3& getLocalScaling() const ; + virtual void setLocalScaling(const btVector3& scaling); + virtual const btVector3& getLocalScaling() const; - virtual void setMargin(btScalar margin); - virtual btScalar getMargin() const; - - virtual int getNumPreferredPenetrationDirections() const; - - virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const; + virtual void setMargin(btScalar margin); + virtual btScalar getMargin() const; + virtual int getNumPreferredPenetrationDirections() const; + virtual void getPreferredPenetrationDirection(int index, btVector3& penetrationVector) const; }; -#endif //BT_UNIFORM_SCALING_SHAPE_H +#endif //BT_UNIFORM_SCALING_SHAPE_H diff --git a/src/BulletCollision/Gimpact/btBoxCollision.h b/src/BulletCollision/Gimpact/btBoxCollision.h index 0a0357e5a..182835c3b 100644 --- a/src/BulletCollision/Gimpact/btBoxCollision.h +++ b/src/BulletCollision/Gimpact/btBoxCollision.h @@ -26,27 +26,21 @@ subject to the following restrictions: #include "LinearMath/btTransform.h" - ///Swap numbers -#define BT_SWAP_NUMBERS(a,b){ \ - a = a+b; \ - b = a-b; \ - a = a-b; \ -}\ - - -#define BT_MAX(a,b) (ab?b:a) - -#define BT_GREATER(x, y) btFabs(x) > (y) - -#define BT_MAX3(a,b,c) BT_MAX(a,BT_MAX(b,c)) -#define BT_MIN3(a,b,c) BT_MIN(a,BT_MIN(b,c)) - - +#define BT_SWAP_NUMBERS(a, b) \ + { \ + a = a + b; \ + b = a - b; \ + a = a - b; \ + } +#define BT_MAX(a, b) (a < b ? b : a) +#define BT_MIN(a, b) (a > b ? b : a) +#define BT_GREATER(x, y) btFabs(x) > (y) +#define BT_MAX3(a, b, c) BT_MAX(a, BT_MAX(b, c)) +#define BT_MIN3(a, b, c) BT_MIN(a, BT_MIN(b, c)) enum eBT_PLANE_INTERSECTION_TYPE { @@ -115,152 +109,144 @@ enum eBT_PLANE_INTERSECTION_TYPE // return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,1,0,0,1); //} +#define TEST_CROSS_EDGE_BOX_MCR(edge, absolute_edge, pointa, pointb, _extend, i_dir_0, i_dir_1, i_comp_0, i_comp_1) \ + { \ + const btScalar dir0 = -edge[i_dir_0]; \ + const btScalar dir1 = edge[i_dir_1]; \ + btScalar pmin = pointa[i_comp_0] * dir0 + pointa[i_comp_1] * dir1; \ + btScalar pmax = pointb[i_comp_0] * dir0 + pointb[i_comp_1] * dir1; \ + if (pmin > pmax) \ + { \ + BT_SWAP_NUMBERS(pmin, pmax); \ + } \ + const btScalar abs_dir0 = absolute_edge[i_dir_0]; \ + const btScalar abs_dir1 = absolute_edge[i_dir_1]; \ + const btScalar rad = _extend[i_comp_0] * abs_dir0 + _extend[i_comp_1] * abs_dir1; \ + if (pmin > rad || -rad > pmax) return false; \ + } -#define TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,i_dir_0,i_dir_1,i_comp_0,i_comp_1)\ -{\ - const btScalar dir0 = -edge[i_dir_0];\ - const btScalar dir1 = edge[i_dir_1];\ - btScalar pmin = pointa[i_comp_0]*dir0 + pointa[i_comp_1]*dir1;\ - btScalar pmax = pointb[i_comp_0]*dir0 + pointb[i_comp_1]*dir1;\ - if(pmin>pmax)\ - {\ - BT_SWAP_NUMBERS(pmin,pmax); \ - }\ - const btScalar abs_dir0 = absolute_edge[i_dir_0];\ - const btScalar abs_dir1 = absolute_edge[i_dir_1];\ - const btScalar rad = _extend[i_comp_0] * abs_dir0 + _extend[i_comp_1] * abs_dir1;\ - if(pmin>rad || -rad>pmax) return false;\ -}\ +#define TEST_CROSS_EDGE_BOX_X_AXIS_MCR(edge, absolute_edge, pointa, pointb, _extend) \ + { \ + TEST_CROSS_EDGE_BOX_MCR(edge, absolute_edge, pointa, pointb, _extend, 2, 1, 1, 2); \ + } +#define TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(edge, absolute_edge, pointa, pointb, _extend) \ + { \ + TEST_CROSS_EDGE_BOX_MCR(edge, absolute_edge, pointa, pointb, _extend, 0, 2, 2, 0); \ + } -#define TEST_CROSS_EDGE_BOX_X_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\ -{\ - TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,2,1,1,2);\ -}\ - -#define TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\ -{\ - TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,0,2,2,0);\ -}\ - -#define TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\ -{\ - TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,1,0,0,1);\ -}\ - +#define TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(edge, absolute_edge, pointa, pointb, _extend) \ + { \ + TEST_CROSS_EDGE_BOX_MCR(edge, absolute_edge, pointa, pointb, _extend, 1, 0, 0, 1); \ + } //! Returns the dot product between a vec3f and the col of a matrix SIMD_FORCE_INLINE btScalar bt_mat3_dot_col( -const btMatrix3x3 & mat, const btVector3 & vec3, int colindex) + const btMatrix3x3 &mat, const btVector3 &vec3, int colindex) { - return vec3[0]*mat[0][colindex] + vec3[1]*mat[1][colindex] + vec3[2]*mat[2][colindex]; + return vec3[0] * mat[0][colindex] + vec3[1] * mat[1][colindex] + vec3[2] * mat[2][colindex]; } - //! Class for transforming a model1 to the space of model0 -ATTRIBUTE_ALIGNED16 (class) BT_BOX_BOX_TRANSFORM_CACHE +ATTRIBUTE_ALIGNED16(class) +BT_BOX_BOX_TRANSFORM_CACHE { public: - btVector3 m_T1to0;//!< Transforms translation of model1 to model 0 - btMatrix3x3 m_R1to0;//!< Transforms Rotation of model1 to model 0, equal to R0' * R1 - btMatrix3x3 m_AR;//!< Absolute value of m_R1to0 + btVector3 m_T1to0; //!< Transforms translation of model1 to model 0 + btMatrix3x3 m_R1to0; //!< Transforms Rotation of model1 to model 0, equal to R0' * R1 + btMatrix3x3 m_AR; //!< Absolute value of m_R1to0 SIMD_FORCE_INLINE void calc_absolute_matrix() { -// static const btVector3 vepsi(1e-6f,1e-6f,1e-6f); -// m_AR[0] = vepsi + m_R1to0[0].absolute(); -// m_AR[1] = vepsi + m_R1to0[1].absolute(); -// m_AR[2] = vepsi + m_R1to0[2].absolute(); + // static const btVector3 vepsi(1e-6f,1e-6f,1e-6f); + // m_AR[0] = vepsi + m_R1to0[0].absolute(); + // m_AR[1] = vepsi + m_R1to0[1].absolute(); + // m_AR[2] = vepsi + m_R1to0[2].absolute(); - int i,j; - - for(i=0;i<3;i++) - { - for(j=0;j<3;j++ ) - { - m_AR[i][j] = 1e-6f + btFabs(m_R1to0[i][j]); - } - } + int i, j; + for (i = 0; i < 3; i++) + { + for (j = 0; j < 3; j++) + { + m_AR[i][j] = 1e-6f + btFabs(m_R1to0[i][j]); + } + } } BT_BOX_BOX_TRANSFORM_CACHE() { } - - //! Calc the transformation relative 1 to 0. Inverts matrics by transposing - SIMD_FORCE_INLINE void calc_from_homogenic(const btTransform & trans0,const btTransform & trans1) + SIMD_FORCE_INLINE void calc_from_homogenic(const btTransform &trans0, const btTransform &trans1) { - btTransform temp_trans = trans0.inverse(); temp_trans = temp_trans * trans1; m_T1to0 = temp_trans.getOrigin(); m_R1to0 = temp_trans.getBasis(); - calc_absolute_matrix(); } //! Calcs the full invertion of the matrices. Useful for scaling matrices - SIMD_FORCE_INLINE void calc_from_full_invert(const btTransform & trans0,const btTransform & trans1) + SIMD_FORCE_INLINE void calc_from_full_invert(const btTransform &trans0, const btTransform &trans1) { m_R1to0 = trans0.getBasis().inverse(); m_T1to0 = m_R1to0 * (-trans0.getOrigin()); - m_T1to0 += m_R1to0*trans1.getOrigin(); + m_T1to0 += m_R1to0 * trans1.getOrigin(); m_R1to0 *= trans1.getBasis(); calc_absolute_matrix(); } - SIMD_FORCE_INLINE btVector3 transform(const btVector3 & point) const + SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) const { - return point.dot3( m_R1to0[0], m_R1to0[1], m_R1to0[2] ) + m_T1to0; + return point.dot3(m_R1to0[0], m_R1to0[1], m_R1to0[2]) + m_T1to0; } }; - #define BOX_PLANE_EPSILON 0.000001f //! Axis aligned box -ATTRIBUTE_ALIGNED16 (class) btAABB +ATTRIBUTE_ALIGNED16(class) +btAABB { public: btVector3 m_min; btVector3 m_max; btAABB() - {} - - - btAABB(const btVector3 & V1, - const btVector3 & V2, - const btVector3 & V3) { - m_min[0] = BT_MIN3(V1[0],V2[0],V3[0]); - m_min[1] = BT_MIN3(V1[1],V2[1],V3[1]); - m_min[2] = BT_MIN3(V1[2],V2[2],V3[2]); - - m_max[0] = BT_MAX3(V1[0],V2[0],V3[0]); - m_max[1] = BT_MAX3(V1[1],V2[1],V3[1]); - m_max[2] = BT_MAX3(V1[2],V2[2],V3[2]); } - btAABB(const btVector3 & V1, - const btVector3 & V2, - const btVector3 & V3, - btScalar margin) + btAABB(const btVector3 &V1, + const btVector3 &V2, + const btVector3 &V3) { - m_min[0] = BT_MIN3(V1[0],V2[0],V3[0]); - m_min[1] = BT_MIN3(V1[1],V2[1],V3[1]); - m_min[2] = BT_MIN3(V1[2],V2[2],V3[2]); + m_min[0] = BT_MIN3(V1[0], V2[0], V3[0]); + m_min[1] = BT_MIN3(V1[1], V2[1], V3[1]); + m_min[2] = BT_MIN3(V1[2], V2[2], V3[2]); - m_max[0] = BT_MAX3(V1[0],V2[0],V3[0]); - m_max[1] = BT_MAX3(V1[1],V2[1],V3[1]); - m_max[2] = BT_MAX3(V1[2],V2[2],V3[2]); + m_max[0] = BT_MAX3(V1[0], V2[0], V3[0]); + m_max[1] = BT_MAX3(V1[1], V2[1], V3[1]); + m_max[2] = BT_MAX3(V1[2], V2[2], V3[2]); + } + + btAABB(const btVector3 &V1, + const btVector3 &V2, + const btVector3 &V3, + btScalar margin) + { + m_min[0] = BT_MIN3(V1[0], V2[0], V3[0]); + m_min[1] = BT_MIN3(V1[1], V2[1], V3[1]); + m_min[2] = BT_MIN3(V1[2], V2[2], V3[2]); + + m_max[0] = BT_MAX3(V1[0], V2[0], V3[0]); + m_max[1] = BT_MAX3(V1[1], V2[1], V3[1]); + m_max[2] = BT_MAX3(V1[2], V2[2], V3[2]); m_min[0] -= margin; m_min[1] -= margin; @@ -270,13 +256,11 @@ public: m_max[2] += margin; } - btAABB(const btAABB &other): - m_min(other.m_min),m_max(other.m_max) + btAABB(const btAABB &other) : m_min(other.m_min), m_max(other.m_max) { } - btAABB(const btAABB &other,btScalar margin ): - m_min(other.m_min),m_max(other.m_max) + btAABB(const btAABB &other, btScalar margin) : m_min(other.m_min), m_max(other.m_max) { m_min[0] -= margin; m_min[1] -= margin; @@ -317,34 +301,34 @@ public: m_max[2] = other.m_max[2] + margin; } - template + template SIMD_FORCE_INLINE void calc_from_triangle( - const CLASS_POINT & V1, - const CLASS_POINT & V2, - const CLASS_POINT & V3) + const CLASS_POINT &V1, + const CLASS_POINT &V2, + const CLASS_POINT &V3) { - m_min[0] = BT_MIN3(V1[0],V2[0],V3[0]); - m_min[1] = BT_MIN3(V1[1],V2[1],V3[1]); - m_min[2] = BT_MIN3(V1[2],V2[2],V3[2]); + m_min[0] = BT_MIN3(V1[0], V2[0], V3[0]); + m_min[1] = BT_MIN3(V1[1], V2[1], V3[1]); + m_min[2] = BT_MIN3(V1[2], V2[2], V3[2]); - m_max[0] = BT_MAX3(V1[0],V2[0],V3[0]); - m_max[1] = BT_MAX3(V1[1],V2[1],V3[1]); - m_max[2] = BT_MAX3(V1[2],V2[2],V3[2]); + m_max[0] = BT_MAX3(V1[0], V2[0], V3[0]); + m_max[1] = BT_MAX3(V1[1], V2[1], V3[1]); + m_max[2] = BT_MAX3(V1[2], V2[2], V3[2]); } - template + template SIMD_FORCE_INLINE void calc_from_triangle_margin( - const CLASS_POINT & V1, - const CLASS_POINT & V2, - const CLASS_POINT & V3, btScalar margin) + const CLASS_POINT &V1, + const CLASS_POINT &V2, + const CLASS_POINT &V3, btScalar margin) { - m_min[0] = BT_MIN3(V1[0],V2[0],V3[0]); - m_min[1] = BT_MIN3(V1[1],V2[1],V3[1]); - m_min[2] = BT_MIN3(V1[2],V2[2],V3[2]); + m_min[0] = BT_MIN3(V1[0], V2[0], V3[0]); + m_min[1] = BT_MIN3(V1[1], V2[1], V3[1]); + m_min[2] = BT_MIN3(V1[2], V2[2], V3[2]); - m_max[0] = BT_MAX3(V1[0],V2[0],V3[0]); - m_max[1] = BT_MAX3(V1[1],V2[1],V3[1]); - m_max[2] = BT_MAX3(V1[2],V2[2],V3[2]); + m_max[0] = BT_MAX3(V1[0], V2[0], V3[0]); + m_max[1] = BT_MAX3(V1[1], V2[1], V3[1]); + m_max[2] = BT_MAX3(V1[2], V2[2], V3[2]); m_min[0] -= margin; m_min[1] -= margin; @@ -355,91 +339,89 @@ public: } //! Apply a transform to an AABB - SIMD_FORCE_INLINE void appy_transform(const btTransform & trans) + SIMD_FORCE_INLINE void appy_transform(const btTransform &trans) { - btVector3 center = (m_max+m_min)*0.5f; + btVector3 center = (m_max + m_min) * 0.5f; btVector3 extends = m_max - center; // Compute new center center = trans(center); - btVector3 textends = extends.dot3(trans.getBasis().getRow(0).absolute(), - trans.getBasis().getRow(1).absolute(), - trans.getBasis().getRow(2).absolute()); + btVector3 textends = extends.dot3(trans.getBasis().getRow(0).absolute(), + trans.getBasis().getRow(1).absolute(), + trans.getBasis().getRow(2).absolute()); m_min = center - textends; m_max = center + textends; } - //! Apply a transform to an AABB - SIMD_FORCE_INLINE void appy_transform_trans_cache(const BT_BOX_BOX_TRANSFORM_CACHE & trans) + SIMD_FORCE_INLINE void appy_transform_trans_cache(const BT_BOX_BOX_TRANSFORM_CACHE &trans) { - btVector3 center = (m_max+m_min)*0.5f; + btVector3 center = (m_max + m_min) * 0.5f; btVector3 extends = m_max - center; // Compute new center center = trans.transform(center); - btVector3 textends = extends.dot3(trans.m_R1to0.getRow(0).absolute(), - trans.m_R1to0.getRow(1).absolute(), - trans.m_R1to0.getRow(2).absolute()); - + btVector3 textends = extends.dot3(trans.m_R1to0.getRow(0).absolute(), + trans.m_R1to0.getRow(1).absolute(), + trans.m_R1to0.getRow(2).absolute()); + m_min = center - textends; m_max = center + textends; } //! Merges a Box - SIMD_FORCE_INLINE void merge(const btAABB & box) + SIMD_FORCE_INLINE void merge(const btAABB &box) { - m_min[0] = BT_MIN(m_min[0],box.m_min[0]); - m_min[1] = BT_MIN(m_min[1],box.m_min[1]); - m_min[2] = BT_MIN(m_min[2],box.m_min[2]); + m_min[0] = BT_MIN(m_min[0], box.m_min[0]); + m_min[1] = BT_MIN(m_min[1], box.m_min[1]); + m_min[2] = BT_MIN(m_min[2], box.m_min[2]); - m_max[0] = BT_MAX(m_max[0],box.m_max[0]); - m_max[1] = BT_MAX(m_max[1],box.m_max[1]); - m_max[2] = BT_MAX(m_max[2],box.m_max[2]); + m_max[0] = BT_MAX(m_max[0], box.m_max[0]); + m_max[1] = BT_MAX(m_max[1], box.m_max[1]); + m_max[2] = BT_MAX(m_max[2], box.m_max[2]); } //! Merges a point - template - SIMD_FORCE_INLINE void merge_point(const CLASS_POINT & point) + template + SIMD_FORCE_INLINE void merge_point(const CLASS_POINT &point) { - m_min[0] = BT_MIN(m_min[0],point[0]); - m_min[1] = BT_MIN(m_min[1],point[1]); - m_min[2] = BT_MIN(m_min[2],point[2]); + m_min[0] = BT_MIN(m_min[0], point[0]); + m_min[1] = BT_MIN(m_min[1], point[1]); + m_min[2] = BT_MIN(m_min[2], point[2]); - m_max[0] = BT_MAX(m_max[0],point[0]); - m_max[1] = BT_MAX(m_max[1],point[1]); - m_max[2] = BT_MAX(m_max[2],point[2]); + m_max[0] = BT_MAX(m_max[0], point[0]); + m_max[1] = BT_MAX(m_max[1], point[1]); + m_max[2] = BT_MAX(m_max[2], point[2]); } //! Gets the extend and center - SIMD_FORCE_INLINE void get_center_extend(btVector3 & center,btVector3 & extend) const + SIMD_FORCE_INLINE void get_center_extend(btVector3 & center, btVector3 & extend) const { - center = (m_max+m_min)*0.5f; + center = (m_max + m_min) * 0.5f; extend = m_max - center; } //! Finds the intersecting box between this box and the other. - SIMD_FORCE_INLINE void find_intersection(const btAABB & other, btAABB & intersection) const + SIMD_FORCE_INLINE void find_intersection(const btAABB &other, btAABB &intersection) const { - intersection.m_min[0] = BT_MAX(other.m_min[0],m_min[0]); - intersection.m_min[1] = BT_MAX(other.m_min[1],m_min[1]); - intersection.m_min[2] = BT_MAX(other.m_min[2],m_min[2]); + intersection.m_min[0] = BT_MAX(other.m_min[0], m_min[0]); + intersection.m_min[1] = BT_MAX(other.m_min[1], m_min[1]); + intersection.m_min[2] = BT_MAX(other.m_min[2], m_min[2]); - intersection.m_max[0] = BT_MIN(other.m_max[0],m_max[0]); - intersection.m_max[1] = BT_MIN(other.m_max[1],m_max[1]); - intersection.m_max[2] = BT_MIN(other.m_max[2],m_max[2]); + intersection.m_max[0] = BT_MIN(other.m_max[0], m_max[0]); + intersection.m_max[1] = BT_MIN(other.m_max[1], m_max[1]); + intersection.m_max[2] = BT_MIN(other.m_max[2], m_max[2]); } - - SIMD_FORCE_INLINE bool has_collision(const btAABB & other) const + SIMD_FORCE_INLINE bool has_collision(const btAABB &other) const { - if(m_min[0] > other.m_max[0] || - m_max[0] < other.m_min[0] || - m_min[1] > other.m_max[1] || - m_max[1] < other.m_min[1] || - m_min[2] > other.m_max[2] || - m_max[2] < other.m_min[2]) + if (m_min[0] > other.m_max[0] || + m_max[0] < other.m_min[0] || + m_min[1] > other.m_max[1] || + m_max[1] < other.m_min[1] || + m_min[2] > other.m_max[2] || + m_max[2] < other.m_min[2]) { return false; } @@ -451,35 +433,34 @@ public: \param vorigin A vec3f with the origin of the ray \param vdir A vec3f with the direction of the ray */ - SIMD_FORCE_INLINE bool collide_ray(const btVector3 & vorigin,const btVector3 & vdir) const + SIMD_FORCE_INLINE bool collide_ray(const btVector3 &vorigin, const btVector3 &vdir) const { - btVector3 extents,center; - this->get_center_extend(center,extents);; + btVector3 extents, center; + this->get_center_extend(center, extents); + ; btScalar Dx = vorigin[0] - center[0]; - if(BT_GREATER(Dx, extents[0]) && Dx*vdir[0]>=0.0f) return false; + if (BT_GREATER(Dx, extents[0]) && Dx * vdir[0] >= 0.0f) return false; btScalar Dy = vorigin[1] - center[1]; - if(BT_GREATER(Dy, extents[1]) && Dy*vdir[1]>=0.0f) return false; + if (BT_GREATER(Dy, extents[1]) && Dy * vdir[1] >= 0.0f) return false; btScalar Dz = vorigin[2] - center[2]; - if(BT_GREATER(Dz, extents[2]) && Dz*vdir[2]>=0.0f) return false; - + if (BT_GREATER(Dz, extents[2]) && Dz * vdir[2] >= 0.0f) return false; btScalar f = vdir[1] * Dz - vdir[2] * Dy; - if(btFabs(f) > extents[1]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[1])) return false; + if (btFabs(f) > extents[1] * btFabs(vdir[2]) + extents[2] * btFabs(vdir[1])) return false; f = vdir[2] * Dx - vdir[0] * Dz; - if(btFabs(f) > extents[0]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[0]))return false; + if (btFabs(f) > extents[0] * btFabs(vdir[2]) + extents[2] * btFabs(vdir[0])) return false; f = vdir[0] * Dy - vdir[1] * Dx; - if(btFabs(f) > extents[0]*btFabs(vdir[1]) + extents[1]*btFabs(vdir[0]))return false; + if (btFabs(f) > extents[0] * btFabs(vdir[1]) + extents[1] * btFabs(vdir[0])) return false; return true; } - - SIMD_FORCE_INLINE void projection_interval(const btVector3 & direction, btScalar &vmin, btScalar &vmax) const + SIMD_FORCE_INLINE void projection_interval(const btVector3 &direction, btScalar &vmin, btScalar &vmax) const { - btVector3 center = (m_max+m_min)*0.5f; - btVector3 extend = m_max-center; + btVector3 center = (m_max + m_min) * 0.5f; + btVector3 extend = m_max - center; - btScalar _fOrigin = direction.dot(center); + btScalar _fOrigin = direction.dot(center); btScalar _fMaximumExtent = extend.dot(direction.absolute()); vmin = _fOrigin - _fMaximumExtent; vmax = _fOrigin + _fMaximumExtent; @@ -487,30 +468,30 @@ public: SIMD_FORCE_INLINE eBT_PLANE_INTERSECTION_TYPE plane_classify(const btVector4 &plane) const { - btScalar _fmin,_fmax; - this->projection_interval(plane,_fmin,_fmax); + btScalar _fmin, _fmax; + this->projection_interval(plane, _fmin, _fmax); - if(plane[3] > _fmax + BOX_PLANE_EPSILON) + if (plane[3] > _fmax + BOX_PLANE_EPSILON) { - return BT_CONST_BACK_PLANE; // 0 + return BT_CONST_BACK_PLANE; // 0 } - if(plane[3]+BOX_PLANE_EPSILON >=_fmin) + if (plane[3] + BOX_PLANE_EPSILON >= _fmin) { - return BT_CONST_COLLIDE_PLANE; //1 + return BT_CONST_COLLIDE_PLANE; //1 } - return BT_CONST_FRONT_PLANE;//2 + return BT_CONST_FRONT_PLANE; //2 } - SIMD_FORCE_INLINE bool overlapping_trans_conservative(const btAABB & box, btTransform & trans1_to_0) const + SIMD_FORCE_INLINE bool overlapping_trans_conservative(const btAABB &box, btTransform &trans1_to_0) const { btAABB tbox = box; tbox.appy_transform(trans1_to_0); return has_collision(tbox); } - SIMD_FORCE_INLINE bool overlapping_trans_conservative2(const btAABB & box, - const BT_BOX_BOX_TRANSFORM_CACHE & trans1_to_0) const + SIMD_FORCE_INLINE bool overlapping_trans_conservative2(const btAABB &box, + const BT_BOX_BOX_TRANSFORM_CACHE &trans1_to_0) const { btAABB tbox = box; tbox.appy_transform_trans_cache(trans1_to_0); @@ -519,52 +500,50 @@ public: //! transcache is the transformation cache from box to this AABB SIMD_FORCE_INLINE bool overlapping_trans_cache( - const btAABB & box,const BT_BOX_BOX_TRANSFORM_CACHE & transcache, bool fulltest) const + const btAABB &box, const BT_BOX_BOX_TRANSFORM_CACHE &transcache, bool fulltest) const { - //Taken from OPCODE - btVector3 ea,eb;//extends - btVector3 ca,cb;//extends - get_center_extend(ca,ea); - box.get_center_extend(cb,eb); - + btVector3 ea, eb; //extends + btVector3 ca, cb; //extends + get_center_extend(ca, ea); + box.get_center_extend(cb, eb); btVector3 T; - btScalar t,t2; + btScalar t, t2; int i; // Class I : A's basis vectors - for(i=0;i<3;i++) + for (i = 0; i < 3; i++) { - T[i] = transcache.m_R1to0[i].dot(cb) + transcache.m_T1to0[i] - ca[i]; + T[i] = transcache.m_R1to0[i].dot(cb) + transcache.m_T1to0[i] - ca[i]; t = transcache.m_AR[i].dot(eb) + ea[i]; - if(BT_GREATER(T[i], t)) return false; + if (BT_GREATER(T[i], t)) return false; } // Class II : B's basis vectors - for(i=0;i<3;i++) + for (i = 0; i < 3; i++) { - t = bt_mat3_dot_col(transcache.m_R1to0,T,i); - t2 = bt_mat3_dot_col(transcache.m_AR,ea,i) + eb[i]; - if(BT_GREATER(t,t2)) return false; + t = bt_mat3_dot_col(transcache.m_R1to0, T, i); + t2 = bt_mat3_dot_col(transcache.m_AR, ea, i) + eb[i]; + if (BT_GREATER(t, t2)) return false; } // Class III : 9 cross products - if(fulltest) + if (fulltest) { - int j,m,n,o,p,q,r; - for(i=0;i<3;i++) + int j, m, n, o, p, q, r; + for (i = 0; i < 3; i++) { - m = (i+1)%3; - n = (i+2)%3; - o = i==0?1:0; - p = i==2?1:2; - for(j=0;j<3;j++) + m = (i + 1) % 3; + n = (i + 2) % 3; + o = i == 0 ? 1 : 0; + p = i == 2 ? 1 : 2; + for (j = 0; j < 3; j++) { - q = j==2?1:2; - r = j==0?1:0; - t = T[n]*transcache.m_R1to0[m][j] - T[m]*transcache.m_R1to0[n][j]; - t2 = ea[o]*transcache.m_AR[p][j] + ea[p]*transcache.m_AR[o][j] + - eb[r]*transcache.m_AR[i][q] + eb[q]*transcache.m_AR[i][r]; - if(BT_GREATER(t,t2)) return false; + q = j == 2 ? 1 : 2; + r = j == 0 ? 1 : 0; + t = T[n] * transcache.m_R1to0[m][j] - T[m] * transcache.m_R1to0[n][j]; + t2 = ea[o] * transcache.m_AR[p][j] + ea[p] * transcache.m_AR[o][j] + + eb[r] * transcache.m_AR[i][q] + eb[q] * transcache.m_AR[i][r]; + if (BT_GREATER(t, t2)) return false; } } } @@ -573,7 +552,7 @@ public: //! Simple test for planes. SIMD_FORCE_INLINE bool collide_plane( - const btVector4 & plane) const + const btVector4 &plane) const { eBT_PLANE_INTERSECTION_TYPE classify = plane_classify(plane); return (classify == BT_CONST_COLLIDE_PLANE); @@ -581,15 +560,15 @@ public: //! test for a triangle, with edges SIMD_FORCE_INLINE bool collide_triangle_exact( - const btVector3 & p1, - const btVector3 & p2, - const btVector3 & p3, - const btVector4 & triangle_plane) const + const btVector3 &p1, + const btVector3 &p2, + const btVector3 &p3, + const btVector4 &triangle_plane) const { - if(!collide_plane(triangle_plane)) return false; + if (!collide_plane(triangle_plane)) return false; - btVector3 center,extends; - this->get_center_extend(center,extends); + btVector3 center, extends; + this->get_center_extend(center, extends); const btVector3 v1(p1 - center); const btVector3 v2(p2 - center); @@ -599,47 +578,43 @@ public: btVector3 diff(v2 - v1); btVector3 abs_diff = diff.absolute(); //Test With X axis - TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v1,v3,extends); + TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff, abs_diff, v1, v3, extends); //Test With Y axis - TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v1,v3,extends); + TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff, abs_diff, v1, v3, extends); //Test With Z axis - TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v1,v3,extends); - + TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff, abs_diff, v1, v3, extends); diff = v3 - v2; abs_diff = diff.absolute(); //Test With X axis - TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v2,v1,extends); + TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff, abs_diff, v2, v1, extends); //Test With Y axis - TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v2,v1,extends); + TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff, abs_diff, v2, v1, extends); //Test With Z axis - TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v2,v1,extends); + TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff, abs_diff, v2, v1, extends); diff = v1 - v3; abs_diff = diff.absolute(); //Test With X axis - TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v3,v2,extends); + TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff, abs_diff, v3, v2, extends); //Test With Y axis - TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v3,v2,extends); + TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff, abs_diff, v3, v2, extends); //Test With Z axis - TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v3,v2,extends); + TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff, abs_diff, v3, v2, extends); return true; } }; - //! Compairison of transformation objects -SIMD_FORCE_INLINE bool btCompareTransformsEqual(const btTransform & t1,const btTransform & t2) +SIMD_FORCE_INLINE bool btCompareTransformsEqual(const btTransform &t1, const btTransform &t2) { - if(!(t1.getOrigin() == t2.getOrigin()) ) return false; + if (!(t1.getOrigin() == t2.getOrigin())) return false; - if(!(t1.getBasis().getRow(0) == t2.getBasis().getRow(0)) ) return false; - if(!(t1.getBasis().getRow(1) == t2.getBasis().getRow(1)) ) return false; - if(!(t1.getBasis().getRow(2) == t2.getBasis().getRow(2)) ) return false; + if (!(t1.getBasis().getRow(0) == t2.getBasis().getRow(0))) return false; + if (!(t1.getBasis().getRow(1) == t2.getBasis().getRow(1))) return false; + if (!(t1.getBasis().getRow(2) == t2.getBasis().getRow(2))) return false; return true; } - - -#endif // GIM_BOX_COLLISION_H_INCLUDED +#endif // GIM_BOX_COLLISION_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/btClipPolygon.h b/src/BulletCollision/Gimpact/btClipPolygon.h index de0a5231b..38c23e222 100644 --- a/src/BulletCollision/Gimpact/btClipPolygon.h +++ b/src/BulletCollision/Gimpact/btClipPolygon.h @@ -27,77 +27,74 @@ subject to the following restrictions: #include "LinearMath/btTransform.h" #include "LinearMath/btGeometryUtil.h" - -SIMD_FORCE_INLINE btScalar bt_distance_point_plane(const btVector4 & plane,const btVector3 &point) +SIMD_FORCE_INLINE btScalar bt_distance_point_plane(const btVector4 &plane, const btVector3 &point) { return point.dot(plane) - plane[3]; } /*! Vector blending Takes two vectors a, b, blends them together*/ -SIMD_FORCE_INLINE void bt_vec_blend(btVector3 &vr, const btVector3 &va,const btVector3 &vb, btScalar blend_factor) +SIMD_FORCE_INLINE void bt_vec_blend(btVector3 &vr, const btVector3 &va, const btVector3 &vb, btScalar blend_factor) { - vr = (1-blend_factor)*va + blend_factor*vb; + vr = (1 - blend_factor) * va + blend_factor * vb; } //! This function calcs the distance from a 3D plane SIMD_FORCE_INLINE void bt_plane_clip_polygon_collect( - const btVector3 & point0, - const btVector3 & point1, - btScalar dist0, - btScalar dist1, - btVector3 * clipped, - int & clipped_count) + const btVector3 &point0, + const btVector3 &point1, + btScalar dist0, + btScalar dist1, + btVector3 *clipped, + int &clipped_count) { - bool _prevclassif = (dist0>SIMD_EPSILON); - bool _classif = (dist1>SIMD_EPSILON); - if(_classif!=_prevclassif) + bool _prevclassif = (dist0 > SIMD_EPSILON); + bool _classif = (dist1 > SIMD_EPSILON); + if (_classif != _prevclassif) { - btScalar blendfactor = -dist0/(dist1-dist0); - bt_vec_blend(clipped[clipped_count],point0,point1,blendfactor); + btScalar blendfactor = -dist0 / (dist1 - dist0); + bt_vec_blend(clipped[clipped_count], point0, point1, blendfactor); clipped_count++; } - if(!_classif) + if (!_classif) { clipped[clipped_count] = point1; clipped_count++; } } - //! Clips a polygon by a plane /*! *\return The count of the clipped counts */ SIMD_FORCE_INLINE int bt_plane_clip_polygon( - const btVector4 & plane, - const btVector3 * polygon_points, - int polygon_point_count, - btVector3 * clipped) + const btVector4 &plane, + const btVector3 *polygon_points, + int polygon_point_count, + btVector3 *clipped) { - int clipped_count = 0; + int clipped_count = 0; - - //clip first point - btScalar firstdist = bt_distance_point_plane(plane,polygon_points[0]);; - if(!(firstdist>SIMD_EPSILON)) + //clip first point + btScalar firstdist = bt_distance_point_plane(plane, polygon_points[0]); + ; + if (!(firstdist > SIMD_EPSILON)) { clipped[clipped_count] = polygon_points[0]; clipped_count++; } btScalar olddist = firstdist; - for(int i=1;iSIMD_EPSILON)) + //clip first point0 + btScalar firstdist = bt_distance_point_plane(plane, point0); + ; + if (!(firstdist > SIMD_EPSILON)) { clipped[clipped_count] = point0; clipped_count++; @@ -139,44 +137,37 @@ SIMD_FORCE_INLINE int bt_plane_clip_triangle( // point 1 btScalar olddist = firstdist; - btScalar dist = bt_distance_point_plane(plane,point1); + btScalar dist = bt_distance_point_plane(plane, point1); bt_plane_clip_polygon_collect( - point0,point1, - olddist, - dist, - clipped, - clipped_count); + point0, point1, + olddist, + dist, + clipped, + clipped_count); olddist = dist; - // point 2 - dist = bt_distance_point_plane(plane,point2); + dist = bt_distance_point_plane(plane, point2); bt_plane_clip_polygon_collect( - point1,point2, - olddist, - dist, - clipped, - clipped_count); + point1, point2, + olddist, + dist, + clipped, + clipped_count); olddist = dist; - - //RETURN TO FIRST point0 bt_plane_clip_polygon_collect( - point2,point0, - olddist, - firstdist, - clipped, - clipped_count); + point2, point0, + olddist, + firstdist, + clipped, + clipped_count); return clipped_count; } - - - - -#endif // GIM_TRI_COLLISION_H_INCLUDED +#endif // GIM_TRI_COLLISION_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/btCompoundFromGimpact.h b/src/BulletCollision/Gimpact/btCompoundFromGimpact.h index 19f7ecddd..ede59e8a5 100644 --- a/src/BulletCollision/Gimpact/btCompoundFromGimpact.h +++ b/src/BulletCollision/Gimpact/btCompoundFromGimpact.h @@ -5,7 +5,8 @@ #include "btGImpactShape.h" #include "BulletCollision/NarrowPhaseCollision/btRaycastCallback.h" -ATTRIBUTE_ALIGNED16(class) btCompoundFromGimpactShape : public btCompoundShape +ATTRIBUTE_ALIGNED16(class) +btCompoundFromGimpactShape : public btCompoundShape { public: BT_DECLARE_ALIGNED_ALLOCATOR(); @@ -18,92 +19,87 @@ public: delete m_children[i].m_childShape; } } - }; struct MyCallback : public btTriangleRaycastCallback +{ + int m_ignorePart; + int m_ignoreTriangleIndex; + + MyCallback(const btVector3& from, const btVector3& to, int ignorePart, int ignoreTriangleIndex) + : btTriangleRaycastCallback(from, to), + m_ignorePart(ignorePart), + m_ignoreTriangleIndex(ignoreTriangleIndex) + { + } + virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex) + { + if (partId != m_ignorePart || triangleIndex != m_ignoreTriangleIndex) { - int m_ignorePart; - int m_ignoreTriangleIndex; - + if (hitFraction < m_hitFraction) + return hitFraction; + } - MyCallback(const btVector3& from, const btVector3& to, int ignorePart, int ignoreTriangleIndex) - :btTriangleRaycastCallback(from,to), - m_ignorePart(ignorePart), - m_ignoreTriangleIndex(ignoreTriangleIndex) - { - - } - virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex) - { - if (partId!=m_ignorePart || triangleIndex!=m_ignoreTriangleIndex) - { - if (hitFraction < m_hitFraction) - return hitFraction; - } + return m_hitFraction; + } +}; +struct MyInternalTriangleIndexCallback : public btInternalTriangleIndexCallback +{ + const btGImpactMeshShape* m_gimpactShape; + btCompoundShape* m_colShape; + btScalar m_depth; - return m_hitFraction; - } - }; - struct MyInternalTriangleIndexCallback :public btInternalTriangleIndexCallback + MyInternalTriangleIndexCallback(btCompoundShape* colShape, const btGImpactMeshShape* meshShape, btScalar depth) + : m_colShape(colShape), + m_gimpactShape(meshShape), + m_depth(depth) + { + } + + virtual void internalProcessTriangleIndex(btVector3* triangle, int partId, int triangleIndex) + { + btVector3 scale = m_gimpactShape->getLocalScaling(); + btVector3 v0 = triangle[0] * scale; + btVector3 v1 = triangle[1] * scale; + btVector3 v2 = triangle[2] * scale; + + btVector3 centroid = (v0 + v1 + v2) / 3; + btVector3 normal = (v1 - v0).cross(v2 - v0); + normal.normalize(); + btVector3 rayFrom = centroid; + btVector3 rayTo = centroid - normal * m_depth; + + MyCallback cb(rayFrom, rayTo, partId, triangleIndex); + + m_gimpactShape->processAllTrianglesRay(&cb, rayFrom, rayTo); + if (cb.m_hitFraction < 1) { - const btGImpactMeshShape* m_gimpactShape; - btCompoundShape* m_colShape; - btScalar m_depth; + rayTo.setInterpolate3(cb.m_from, cb.m_to, cb.m_hitFraction); + //rayTo = cb.m_from; + //rayTo = rayTo.lerp(cb.m_to,cb.m_hitFraction); + //gDebugDraw.drawLine(tr(centroid),tr(centroid+normal),btVector3(1,0,0)); + } - MyInternalTriangleIndexCallback (btCompoundShape* colShape, const btGImpactMeshShape* meshShape, btScalar depth) - :m_colShape(colShape), - m_gimpactShape(meshShape), - m_depth(depth) - { - } - - virtual void internalProcessTriangleIndex(btVector3* triangle,int partId,int triangleIndex) - { - btVector3 scale = m_gimpactShape->getLocalScaling(); - btVector3 v0=triangle[0]*scale; - btVector3 v1=triangle[1]*scale; - btVector3 v2=triangle[2]*scale; - - btVector3 centroid = (v0+v1+v2)/3; - btVector3 normal = (v1-v0).cross(v2-v0); - normal.normalize(); - btVector3 rayFrom = centroid; - btVector3 rayTo = centroid-normal*m_depth; - - MyCallback cb(rayFrom,rayTo,partId,triangleIndex); - - m_gimpactShape->processAllTrianglesRay(&cb,rayFrom, rayTo); - if (cb.m_hitFraction<1) - { - rayTo.setInterpolate3(cb.m_from,cb.m_to,cb.m_hitFraction); - //rayTo = cb.m_from; - //rayTo = rayTo.lerp(cb.m_to,cb.m_hitFraction); - //gDebugDraw.drawLine(tr(centroid),tr(centroid+normal),btVector3(1,0,0)); - } - + btBU_Simplex1to4* tet = new btBU_Simplex1to4(v0, v1, v2, rayTo); + btTransform ident; + ident.setIdentity(); + m_colShape->addChildShape(ident, tet); + } +}; - - btBU_Simplex1to4* tet = new btBU_Simplex1to4(v0,v1,v2,rayTo); - btTransform ident; - ident.setIdentity(); - m_colShape->addChildShape(ident,tet); - } - }; - -btCompoundShape* btCreateCompoundFromGimpactShape(const btGImpactMeshShape* gimpactMesh, btScalar depth) +btCompoundShape* btCreateCompoundFromGimpactShape(const btGImpactMeshShape* gimpactMesh, btScalar depth) { btCompoundShape* colShape = new btCompoundFromGimpactShape(); - - btTransform tr; - tr.setIdentity(); - - MyInternalTriangleIndexCallback cb(colShape,gimpactMesh, depth); - btVector3 aabbMin,aabbMax; - gimpactMesh->getAabb(tr,aabbMin,aabbMax); - gimpactMesh->getMeshInterface()->InternalProcessAllTriangles(&cb,aabbMin,aabbMax); - return colShape; -} + btTransform tr; + tr.setIdentity(); -#endif //BT_COMPOUND_FROM_GIMPACT + MyInternalTriangleIndexCallback cb(colShape, gimpactMesh, depth); + btVector3 aabbMin, aabbMax; + gimpactMesh->getAabb(tr, aabbMin, aabbMax); + gimpactMesh->getMeshInterface()->InternalProcessAllTriangles(&cb, aabbMin, aabbMax); + + return colShape; +} + +#endif //BT_COMPOUND_FROM_GIMPACT diff --git a/src/BulletCollision/Gimpact/btContactProcessing.cpp b/src/BulletCollision/Gimpact/btContactProcessing.cpp index eed31d839..f2e3e18d6 100644 --- a/src/BulletCollision/Gimpact/btContactProcessing.cpp +++ b/src/BulletCollision/Gimpact/btContactProcessing.cpp @@ -27,54 +27,50 @@ struct CONTACT_KEY_TOKEN unsigned int m_key; int m_value; CONTACT_KEY_TOKEN() - { - } + { + } - CONTACT_KEY_TOKEN(unsigned int key,int token) - { - m_key = key; - m_value = token; - } + CONTACT_KEY_TOKEN(unsigned int key, int token) + { + m_key = key; + m_value = token; + } - CONTACT_KEY_TOKEN(const CONTACT_KEY_TOKEN& rtoken) - { - m_key = rtoken.m_key; - m_value = rtoken.m_value; - } + CONTACT_KEY_TOKEN(const CONTACT_KEY_TOKEN& rtoken) + { + m_key = rtoken.m_key; + m_value = rtoken.m_value; + } - inline bool operator <(const CONTACT_KEY_TOKEN& other) const + inline bool operator<(const CONTACT_KEY_TOKEN& other) const { return (m_key < other.m_key); } - inline bool operator >(const CONTACT_KEY_TOKEN& other) const + inline bool operator>(const CONTACT_KEY_TOKEN& other) const { return (m_key > other.m_key); } - }; class CONTACT_KEY_TOKEN_COMP { - public: - - bool operator() ( const CONTACT_KEY_TOKEN& a, const CONTACT_KEY_TOKEN& b ) const - { - return ( a < b ); - } +public: + bool operator()(const CONTACT_KEY_TOKEN& a, const CONTACT_KEY_TOKEN& b) const + { + return (a < b); + } }; - void btContactArray::merge_contacts( - const btContactArray & contacts, bool normal_contact_average) + const btContactArray& contacts, bool normal_contact_average) { clear(); int i; - if(contacts.size()==0) return; + if (contacts.size() == 0) return; - - if(contacts.size()==1) + if (contacts.size() == 1) { push_back(contacts[0]); return; @@ -86,16 +82,16 @@ void btContactArray::merge_contacts( //fill key contacts - for ( i = 0;im_depth - CONTACT_DIFF_EPSILON > scontact->m_depth)//) + if (pcontact->m_depth - CONTACT_DIFF_EPSILON > scontact->m_depth) //) { *pcontact = *scontact; - coincident_count = 0; + coincident_count = 0; } - else if(normal_contact_average) + else if (normal_contact_average) { - if(btFabs(pcontact->m_depth - scontact->m_depth)m_normal; - coincident_count++; - } - } + if (btFabs(pcontact->m_depth - scontact->m_depth) < CONTACT_DIFF_EPSILON) + { + if (coincident_count < MAX_COINCIDENT) + { + coincident_normals[coincident_count] = scontact->m_normal; + coincident_count++; + } + } } } else - {//add new contact + { //add new contact - if(normal_contact_average && coincident_count>0) - { - pcontact->interpolate_normals(coincident_normals,coincident_count); - coincident_count = 0; - } + if (normal_contact_average && coincident_count > 0) + { + pcontact->interpolate_normals(coincident_normals, coincident_count); + coincident_count = 0; + } - push_back(*scontact); - pcontact = &(*this)[this->size()-1]; - } + push_back(*scontact); + pcontact = &(*this)[this->size() - 1]; + } last_key = key; } } -void btContactArray::merge_contacts_unique(const btContactArray & contacts) +void btContactArray::merge_contacts_unique(const btContactArray& contacts) { clear(); - if(contacts.size()==0) return; + if (contacts.size() == 0) return; - if(contacts.size()==1) + if (contacts.size() == 1) { push_back(contacts[0]); return; @@ -160,14 +156,14 @@ void btContactArray::merge_contacts_unique(const btContactArray & contacts) GIM_CONTACT average_contact = contacts[0]; - for (int i=1;i +class btContactArray : public btAlignedObjectArray { public: btContactArray() @@ -38,28 +38,28 @@ public: } SIMD_FORCE_INLINE void push_contact( - const btVector3 &point,const btVector3 & normal, + const btVector3 &point, const btVector3 &normal, btScalar depth, int feature1, int feature2) { - push_back( GIM_CONTACT(point,normal,depth,feature1,feature2) ); + push_back(GIM_CONTACT(point, normal, depth, feature1, feature2)); } SIMD_FORCE_INLINE void push_triangle_contacts( - const GIM_TRIANGLE_CONTACT & tricontact, - int feature1,int feature2) + const GIM_TRIANGLE_CONTACT &tricontact, + int feature1, int feature2) { - for(int i = 0;i splitValue) { //swap - primitive_boxes.swap(i,splitIndex); + primitive_boxes.swap(i, splitIndex); //swapLeafNodes(i,splitIndex); splitIndex++; } @@ -142,32 +137,30 @@ int btBvhTree::_sort_and_calc_splitting_index( //bool unbalanced2 = true; //this should be safe too: - int rangeBalancedIndices = numIndices/3; - bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices))); + int rangeBalancedIndices = numIndices / 3; + bool unbalanced = ((splitIndex <= (startIndex + rangeBalancedIndices)) || (splitIndex >= (endIndex - 1 - rangeBalancedIndices))); if (unbalanced) { - splitIndex = startIndex+ (numIndices>>1); + splitIndex = startIndex + (numIndices >> 1); } - btAssert(!((splitIndex==startIndex) || (splitIndex == (endIndex)))); + btAssert(!((splitIndex == startIndex) || (splitIndex == (endIndex)))); return splitIndex; - } - -void btBvhTree::_build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex) +void btBvhTree::_build_sub_tree(GIM_BVH_DATA_ARRAY& primitive_boxes, int startIndex, int endIndex) { int curIndex = m_num_nodes; m_num_nodes++; - btAssert((endIndex-startIndex)>0); + btAssert((endIndex - startIndex) > 0); - if ((endIndex-startIndex)==1) + if ((endIndex - startIndex) == 1) { - //We have a leaf node - setNodeBound(curIndex,primitive_boxes[startIndex].m_bound); + //We have a leaf node + setNodeBound(curIndex, primitive_boxes[startIndex].m_bound); m_node_array[curIndex].setDataIndex(primitive_boxes[startIndex].m_data); return; @@ -175,47 +168,42 @@ void btBvhTree::_build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startI //calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'. //split axis - int splitIndex = _calc_splitting_axis(primitive_boxes,startIndex,endIndex); + int splitIndex = _calc_splitting_axis(primitive_boxes, startIndex, endIndex); splitIndex = _sort_and_calc_splitting_index( - primitive_boxes,startIndex,endIndex, - splitIndex//split axis - ); - + primitive_boxes, startIndex, endIndex, + splitIndex //split axis + ); //calc this node bounding box btAABB node_bound; node_bound.invalidate(); - for (int i=startIndex;iget_primitive_box(getNodeData(nodecount),leafbox); - setNodeBound(nodecount,leafbox); + m_primitive_manager->get_primitive_box(getNodeData(nodecount), leafbox); + setNodeBound(nodecount, leafbox); } else { @@ -243,20 +231,20 @@ void btGImpactBvh::refit() btAABB temp_box; int child_node = getLeftNode(nodecount); - if(child_node) + if (child_node) { - getNodeBound(child_node,temp_box); + getNodeBound(child_node, temp_box); bound.merge(temp_box); } child_node = getRightNode(nodecount); - if(child_node) + if (child_node) { - getNodeBound(child_node,temp_box); + getNodeBound(child_node, temp_box); bound.merge(temp_box); } - setNodeBound(nodecount,bound); + setNodeBound(nodecount, bound); } } } @@ -268,17 +256,17 @@ void btGImpactBvh::buildSet() GIM_BVH_DATA_ARRAY primitive_boxes; primitive_boxes.resize(m_primitive_manager->get_primitive_count()); - for (int i = 0;iget_primitive_box(i,primitive_boxes[i].m_bound); - primitive_boxes[i].m_data = i; + m_primitive_manager->get_primitive_box(i, primitive_boxes[i].m_bound); + primitive_boxes[i].m_data = i; } m_box_tree.build_tree(primitive_boxes); } //! returns the indices of the primitives in the m_primitive_manager -bool btGImpactBvh::boxQuery(const btAABB & box, btAlignedObjectArray & collided_results) const +bool btGImpactBvh::boxQuery(const btAABB& box, btAlignedObjectArray& collided_results) const { int curIndex = 0; int numNodes = getNodeCount(); @@ -286,7 +274,7 @@ bool btGImpactBvh::boxQuery(const btAABB & box, btAlignedObjectArray & coll while (curIndex < numNodes) { btAABB bound; - getNodeBound(curIndex,bound); + getNodeBound(curIndex, bound); //catch bugs in tree data @@ -306,19 +294,17 @@ bool btGImpactBvh::boxQuery(const btAABB & box, btAlignedObjectArray & coll else { //skip node - curIndex+= getEscapeNodeIndex(curIndex); + curIndex += getEscapeNodeIndex(curIndex); } } - if(collided_results.size()>0) return true; + if (collided_results.size() > 0) return true; return false; } - - //! returns the indices of the primitives in the m_primitive_manager bool btGImpactBvh::rayQuery( - const btVector3 & ray_dir,const btVector3 & ray_origin , - btAlignedObjectArray & collided_results) const + const btVector3& ray_dir, const btVector3& ray_origin, + btAlignedObjectArray& collided_results) const { int curIndex = 0; int numNodes = getNodeCount(); @@ -326,16 +312,16 @@ bool btGImpactBvh::rayQuery( while (curIndex < numNodes) { btAABB bound; - getNodeBound(curIndex,bound); + getNodeBound(curIndex, bound); //catch bugs in tree data - bool aabbOverlap = bound.collide_ray(ray_origin,ray_dir); + bool aabbOverlap = bound.collide_ray(ray_origin, ray_dir); bool isleafnode = isLeafNode(curIndex); if (isleafnode && aabbOverlap) { - collided_results.push_back(getNodeData( curIndex)); + collided_results.push_back(getNodeData(curIndex)); } if (aabbOverlap || isleafnode) @@ -346,153 +332,133 @@ bool btGImpactBvh::rayQuery( else { //skip node - curIndex+= getEscapeNodeIndex(curIndex); + curIndex += getEscapeNodeIndex(curIndex); } } - if(collided_results.size()>0) return true; + if (collided_results.size() > 0) return true; return false; } - SIMD_FORCE_INLINE bool _node_collision( - btGImpactBvh * boxset0, btGImpactBvh * boxset1, - const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0, - int node0 ,int node1, bool complete_primitive_tests) + btGImpactBvh* boxset0, btGImpactBvh* boxset1, + const BT_BOX_BOX_TRANSFORM_CACHE& trans_cache_1to0, + int node0, int node1, bool complete_primitive_tests) { btAABB box0; - boxset0->getNodeBound(node0,box0); + boxset0->getNodeBound(node0, box0); btAABB box1; - boxset1->getNodeBound(node1,box1); - - return box0.overlapping_trans_cache(box1,trans_cache_1to0,complete_primitive_tests ); -// box1.appy_transform_trans_cache(trans_cache_1to0); -// return box0.has_collision(box1); + boxset1->getNodeBound(node1, box1); + return box0.overlapping_trans_cache(box1, trans_cache_1to0, complete_primitive_tests); + // box1.appy_transform_trans_cache(trans_cache_1to0); + // return box0.has_collision(box1); } - //stackless recursive collision routine static void _find_collision_pairs_recursive( - btGImpactBvh * boxset0, btGImpactBvh * boxset1, - btPairSet * collision_pairs, - const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0, + btGImpactBvh* boxset0, btGImpactBvh* boxset1, + btPairSet* collision_pairs, + const BT_BOX_BOX_TRANSFORM_CACHE& trans_cache_1to0, int node0, int node1, bool complete_primitive_tests) { + if (_node_collision( + boxset0, boxset1, trans_cache_1to0, + node0, node1, complete_primitive_tests) == false) return; //avoid colliding internal nodes - - - if( _node_collision( - boxset0,boxset1,trans_cache_1to0, - node0,node1,complete_primitive_tests) ==false) return;//avoid colliding internal nodes - - if(boxset0->isLeafNode(node0)) + if (boxset0->isLeafNode(node0)) { - if(boxset1->isLeafNode(node1)) + if (boxset1->isLeafNode(node1)) { // collision result collision_pairs->push_pair( - boxset0->getNodeData(node0),boxset1->getNodeData(node1)); + boxset0->getNodeData(node0), boxset1->getNodeData(node1)); return; } else { - //collide left recursive _find_collision_pairs_recursive( - boxset0,boxset1, - collision_pairs,trans_cache_1to0, - node0,boxset1->getLeftNode(node1),false); + boxset0, boxset1, + collision_pairs, trans_cache_1to0, + node0, boxset1->getLeftNode(node1), false); //collide right recursive _find_collision_pairs_recursive( - boxset0,boxset1, - collision_pairs,trans_cache_1to0, - node0,boxset1->getRightNode(node1),false); - - + boxset0, boxset1, + collision_pairs, trans_cache_1to0, + node0, boxset1->getRightNode(node1), false); } } else { - if(boxset1->isLeafNode(node1)) + if (boxset1->isLeafNode(node1)) { - //collide left recursive _find_collision_pairs_recursive( - boxset0,boxset1, - collision_pairs,trans_cache_1to0, - boxset0->getLeftNode(node0),node1,false); - + boxset0, boxset1, + collision_pairs, trans_cache_1to0, + boxset0->getLeftNode(node0), node1, false); //collide right recursive _find_collision_pairs_recursive( - boxset0,boxset1, - collision_pairs,trans_cache_1to0, - boxset0->getRightNode(node0),node1,false); - - + boxset0, boxset1, + collision_pairs, trans_cache_1to0, + boxset0->getRightNode(node0), node1, false); } else { //collide left0 left1 - - _find_collision_pairs_recursive( - boxset0,boxset1, - collision_pairs,trans_cache_1to0, - boxset0->getLeftNode(node0),boxset1->getLeftNode(node1),false); + boxset0, boxset1, + collision_pairs, trans_cache_1to0, + boxset0->getLeftNode(node0), boxset1->getLeftNode(node1), false); //collide left0 right1 _find_collision_pairs_recursive( - boxset0,boxset1, - collision_pairs,trans_cache_1to0, - boxset0->getLeftNode(node0),boxset1->getRightNode(node1),false); - + boxset0, boxset1, + collision_pairs, trans_cache_1to0, + boxset0->getLeftNode(node0), boxset1->getRightNode(node1), false); //collide right0 left1 _find_collision_pairs_recursive( - boxset0,boxset1, - collision_pairs,trans_cache_1to0, - boxset0->getRightNode(node0),boxset1->getLeftNode(node1),false); + boxset0, boxset1, + collision_pairs, trans_cache_1to0, + boxset0->getRightNode(node0), boxset1->getLeftNode(node1), false); //collide right0 right1 _find_collision_pairs_recursive( - boxset0,boxset1, - collision_pairs,trans_cache_1to0, - boxset0->getRightNode(node0),boxset1->getRightNode(node1),false); + boxset0, boxset1, + collision_pairs, trans_cache_1to0, + boxset0->getRightNode(node0), boxset1->getRightNode(node1), false); - }// else if node1 is not a leaf - }// else if node0 is not a leaf + } // else if node1 is not a leaf + } // else if node0 is not a leaf } - -void btGImpactBvh::find_collision(btGImpactBvh * boxset0, const btTransform & trans0, - btGImpactBvh * boxset1, const btTransform & trans1, - btPairSet & collision_pairs) +void btGImpactBvh::find_collision(btGImpactBvh* boxset0, const btTransform& trans0, + btGImpactBvh* boxset1, const btTransform& trans1, + btPairSet& collision_pairs) { - - if(boxset0->getNodeCount()==0 || boxset1->getNodeCount()==0 ) return; + if (boxset0->getNodeCount() == 0 || boxset1->getNodeCount() == 0) return; BT_BOX_BOX_TRANSFORM_CACHE trans_cache_1to0; - trans_cache_1to0.calc_from_homogenic(trans0,trans1); + trans_cache_1to0.calc_from_homogenic(trans0, trans1); #ifdef TRI_COLLISION_PROFILING bt_begin_gim02_tree_time(); -#endif //TRI_COLLISION_PROFILING +#endif //TRI_COLLISION_PROFILING _find_collision_pairs_recursive( - boxset0,boxset1, - &collision_pairs,trans_cache_1to0,0,0,true); + boxset0, boxset1, + &collision_pairs, trans_cache_1to0, 0, 0, true); #ifdef TRI_COLLISION_PROFILING bt_end_gim02_tree_time(); -#endif //TRI_COLLISION_PROFILING - +#endif //TRI_COLLISION_PROFILING } - diff --git a/src/BulletCollision/Gimpact/btGImpactBvh.h b/src/BulletCollision/Gimpact/btGImpactBvh.h index e20e03cc1..79dcda957 100644 --- a/src/BulletCollision/Gimpact/btGImpactBvh.h +++ b/src/BulletCollision/Gimpact/btGImpactBvh.h @@ -24,7 +24,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "LinearMath/btAlignedObjectArray.h" #include "btBoxCollision.h" @@ -32,50 +31,48 @@ subject to the following restrictions: #include "btGImpactBvhStructs.h" //! A pairset array -class btPairSet: public btAlignedObjectArray +class btPairSet : public btAlignedObjectArray { public: btPairSet() { reserve(32); } - inline void push_pair(int index1,int index2) + inline void push_pair(int index1, int index2) { - push_back(GIM_PAIR(index1,index2)); + push_back(GIM_PAIR(index1, index2)); } - inline void push_pair_inv(int index1,int index2) + inline void push_pair_inv(int index1, int index2) { - push_back(GIM_PAIR(index2,index1)); + push_back(GIM_PAIR(index2, index1)); } }; -class GIM_BVH_DATA_ARRAY:public btAlignedObjectArray +class GIM_BVH_DATA_ARRAY : public btAlignedObjectArray { }; - -class GIM_BVH_TREE_NODE_ARRAY:public btAlignedObjectArray +class GIM_BVH_TREE_NODE_ARRAY : public btAlignedObjectArray { }; - - - //! Basic Box tree structure class btBvhTree { protected: int m_num_nodes; GIM_BVH_TREE_NODE_ARRAY m_node_array; + protected: int _sort_and_calc_splitting_index( - GIM_BVH_DATA_ARRAY & primitive_boxes, - int startIndex, int endIndex, int splitAxis); + GIM_BVH_DATA_ARRAY& primitive_boxes, + int startIndex, int endIndex, int splitAxis); - int _calc_splitting_axis(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex); + int _calc_splitting_axis(GIM_BVH_DATA_ARRAY& primitive_boxes, int startIndex, int endIndex); + + void _build_sub_tree(GIM_BVH_DATA_ARRAY& primitive_boxes, int startIndex, int endIndex); - void _build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex); public: btBvhTree() { @@ -84,7 +81,7 @@ public: //! prototype functions for box tree management //!@{ - void build_tree(GIM_BVH_DATA_ARRAY & primitive_boxes); + void build_tree(GIM_BVH_DATA_ARRAY& primitive_boxes); SIMD_FORCE_INLINE void clearNodes() { @@ -109,25 +106,25 @@ public: return m_node_array[nodeindex].getDataIndex(); } - SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const + SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB& bound) const { bound = m_node_array[nodeindex].m_bound; } - SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound) + SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB& bound) { m_node_array[nodeindex].m_bound = bound; } SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const { - return nodeindex+1; + return nodeindex + 1; } SIMD_FORCE_INLINE int getRightNode(int nodeindex) const { - if(m_node_array[nodeindex+1].isLeafNode()) return nodeindex+2; - return nodeindex+1 + m_node_array[nodeindex+1].getEscapeIndex(); + if (m_node_array[nodeindex + 1].isLeafNode()) return nodeindex + 2; + return nodeindex + 1 + m_node_array[nodeindex + 1].getEscapeIndex(); } SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const @@ -135,7 +132,7 @@ public: return m_node_array[nodeindex].getEscapeIndex(); } - SIMD_FORCE_INLINE const GIM_BVH_TREE_NODE * get_node_pointer(int index = 0) const + SIMD_FORCE_INLINE const GIM_BVH_TREE_NODE* get_node_pointer(int index = 0) const { return &m_node_array[index]; } @@ -143,7 +140,6 @@ public: //!@} }; - //! Prototype Base class for primitive classification /*! This class is a wrapper for primitive collections. @@ -153,18 +149,16 @@ This class can manage Compound shapes and trimeshes, and if it is managing trime class btPrimitiveManagerBase { public: - virtual ~btPrimitiveManagerBase() {} //! determines if this manager consist on only triangles, which special case will be optimized virtual bool is_trimesh() const = 0; virtual int get_primitive_count() const = 0; - virtual void get_primitive_box(int prim_index ,btAABB & primbox) const = 0; + virtual void get_primitive_box(int prim_index, btAABB& primbox) const = 0; //! retrieves only the points of the triangle, and the collision margin - virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const= 0; + virtual void get_primitive_triangle(int prim_index, btPrimitiveTriangle& triangle) const = 0; }; - //! Structure for containing Boxes /*! This class offers an structure for managing a box tree of primitives. @@ -174,13 +168,13 @@ class btGImpactBvh { protected: btBvhTree m_box_tree; - btPrimitiveManagerBase * m_primitive_manager; + btPrimitiveManagerBase* m_primitive_manager; protected: //stackless refit void refit(); -public: +public: //! this constructor doesn't build the tree. you must call buildSet btGImpactBvh() { @@ -188,31 +182,30 @@ public: } //! this constructor doesn't build the tree. you must call buildSet - btGImpactBvh(btPrimitiveManagerBase * primitive_manager) + btGImpactBvh(btPrimitiveManagerBase* primitive_manager) { m_primitive_manager = primitive_manager; } - SIMD_FORCE_INLINE btAABB getGlobalBox() const + SIMD_FORCE_INLINE btAABB getGlobalBox() const { btAABB totalbox; getNodeBound(0, totalbox); return totalbox; } - SIMD_FORCE_INLINE void setPrimitiveManager(btPrimitiveManagerBase * primitive_manager) + SIMD_FORCE_INLINE void setPrimitiveManager(btPrimitiveManagerBase* primitive_manager) { m_primitive_manager = primitive_manager; } - SIMD_FORCE_INLINE btPrimitiveManagerBase * getPrimitiveManager() const + SIMD_FORCE_INLINE btPrimitiveManagerBase* getPrimitiveManager() const { return m_primitive_manager; } - -//! node manager prototype functions -///@{ + //! node manager prototype functions + ///@{ //! this attemps to refit the box set. SIMD_FORCE_INLINE void update() @@ -224,21 +217,21 @@ public: void buildSet(); //! returns the indices of the primitives in the m_primitive_manager - bool boxQuery(const btAABB & box, btAlignedObjectArray & collided_results) const; + bool boxQuery(const btAABB& box, btAlignedObjectArray& collided_results) const; //! returns the indices of the primitives in the m_primitive_manager - SIMD_FORCE_INLINE bool boxQueryTrans(const btAABB & box, - const btTransform & transform, btAlignedObjectArray & collided_results) const + SIMD_FORCE_INLINE bool boxQueryTrans(const btAABB& box, + const btTransform& transform, btAlignedObjectArray& collided_results) const { - btAABB transbox=box; + btAABB transbox = box; transbox.appy_transform(transform); - return boxQuery(transbox,collided_results); + return boxQuery(transbox, collided_results); } //! returns the indices of the primitives in the m_primitive_manager bool rayQuery( - const btVector3 & ray_dir,const btVector3 & ray_origin , - btAlignedObjectArray & collided_results) const; + const btVector3& ray_dir, const btVector3& ray_origin, + btAlignedObjectArray& collided_results) const; //! tells if this set has hierarcht SIMD_FORCE_INLINE bool hasHierarchy() const @@ -247,7 +240,7 @@ public: } //! tells if this set is a trimesh - SIMD_FORCE_INLINE bool isTrimesh() const + SIMD_FORCE_INLINE bool isTrimesh() const { return m_primitive_manager->is_trimesh(); } @@ -269,17 +262,16 @@ public: return m_box_tree.getNodeData(nodeindex); } - SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const + SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB& bound) const { m_box_tree.getNodeBound(nodeindex, bound); } - SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound) + SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB& bound) { m_box_tree.setNodeBound(nodeindex, bound); } - SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const { return m_box_tree.getLeftNode(nodeindex); @@ -295,24 +287,23 @@ public: return m_box_tree.getEscapeNodeIndex(nodeindex); } - SIMD_FORCE_INLINE void getNodeTriangle(int nodeindex,btPrimitiveTriangle & triangle) const + SIMD_FORCE_INLINE void getNodeTriangle(int nodeindex, btPrimitiveTriangle& triangle) const { - m_primitive_manager->get_primitive_triangle(getNodeData(nodeindex),triangle); + m_primitive_manager->get_primitive_triangle(getNodeData(nodeindex), triangle); } - - SIMD_FORCE_INLINE const GIM_BVH_TREE_NODE * get_node_pointer(int index = 0) const + SIMD_FORCE_INLINE const GIM_BVH_TREE_NODE* get_node_pointer(int index = 0) const { return m_box_tree.get_node_pointer(index); } #ifdef TRI_COLLISION_PROFILING static float getAverageTreeCollisionTime(); -#endif //TRI_COLLISION_PROFILING +#endif //TRI_COLLISION_PROFILING - static void find_collision(btGImpactBvh * boxset1, const btTransform & trans1, - btGImpactBvh * boxset2, const btTransform & trans2, - btPairSet & collision_pairs); + static void find_collision(btGImpactBvh* boxset1, const btTransform& trans1, + btGImpactBvh* boxset2, const btTransform& trans2, + btPairSet& collision_pairs); }; -#endif // GIM_BOXPRUNING_H_INCLUDED +#endif // GIM_BOXPRUNING_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/btGImpactBvhStructs.h b/src/BulletCollision/Gimpact/btGImpactBvhStructs.h index 9342a572d..54888c675 100644 --- a/src/BulletCollision/Gimpact/btGImpactBvhStructs.h +++ b/src/BulletCollision/Gimpact/btGImpactBvhStructs.h @@ -24,7 +24,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "LinearMath/btAlignedObjectArray.h" #include "btBoxCollision.h" @@ -33,21 +32,22 @@ subject to the following restrictions: //! Overlapping pair struct GIM_PAIR { - int m_index1; - int m_index2; - GIM_PAIR() - {} + int m_index1; + int m_index2; + GIM_PAIR() + { + } - GIM_PAIR(const GIM_PAIR & p) - { - m_index1 = p.m_index1; - m_index2 = p.m_index2; + GIM_PAIR(const GIM_PAIR& p) + { + m_index1 = p.m_index1; + m_index2 = p.m_index2; } GIM_PAIR(int index1, int index2) - { - m_index1 = index1; - m_index2 = index2; + { + m_index1 = index1; + m_index2 = index2; } }; @@ -63,8 +63,10 @@ class GIM_BVH_TREE_NODE { public: btAABB m_bound; + protected: - int m_escapeIndexOrDataIndex; + int m_escapeIndexOrDataIndex; + public: GIM_BVH_TREE_NODE() { @@ -74,7 +76,7 @@ public: SIMD_FORCE_INLINE bool isLeafNode() const { //skipindex is negative (internal node), triangleindex >=0 (leafnode) - return (m_escapeIndexOrDataIndex>=0); + return (m_escapeIndexOrDataIndex >= 0); } SIMD_FORCE_INLINE int getEscapeIndex() const @@ -99,7 +101,6 @@ public: { m_escapeIndexOrDataIndex = index; } - }; -#endif // GIM_BOXPRUNING_H_INCLUDED +#endif // GIM_BOXPRUNING_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp b/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp index 2e87475e3..4a1835d0d 100644 --- a/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp +++ b/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.cpp @@ -31,18 +31,16 @@ Concave-Concave Collision #include "btContactProcessing.h" #include "LinearMath/btQuickprof.h" - //! Class for accessing the plane equation class btPlaneShape : public btStaticPlaneShape { public: - btPlaneShape(const btVector3& v, float f) - :btStaticPlaneShape(v,f) + : btStaticPlaneShape(v, f) { } - void get_plane_equation(btVector4 &equation) + void get_plane_equation(btVector4& equation) { equation[0] = m_planeNormal[0]; equation[1] = m_planeNormal[1]; @@ -50,8 +48,7 @@ public: equation[3] = m_planeConstant; } - - void get_plane_equation_transformed(const btTransform & trans,btVector4 &equation) const + void get_plane_equation_transformed(const btTransform& trans, btVector4& equation) const { equation[0] = trans.getBasis().getRow(0).dot(m_planeNormal); equation[1] = trans.getBasis().getRow(1).dot(m_planeNormal); @@ -60,8 +57,6 @@ public: } }; - - ////////////////////////////////////////////////////////////////////////////////////////////// #ifdef TRI_COLLISION_PROFILING @@ -80,7 +75,7 @@ void bt_end_gim02_tri_time() g_accum_triangle_collision_time += g_triangle_clock.getTimeMicroseconds(); g_count_triangle_collision++; } -#endif //TRI_COLLISION_PROFILING +#endif //TRI_COLLISION_PROFILING //! Retrieving shapes shapes /*! Declared here due of insuficent space on Pool allocators @@ -89,7 +84,7 @@ Declared here due of insuficent space on Pool allocators class GIM_ShapeRetriever { public: - const btGImpactShapeInterface * m_gim_shape; + const btGImpactShapeInterface* m_gim_shape; btTriangleShapeEx m_trishape; btTetrahedronShapeEx m_tetrashape; @@ -97,51 +92,50 @@ public: class ChildShapeRetriever { public: - GIM_ShapeRetriever * m_parent; - virtual const btCollisionShape * getChildShape(int index) + GIM_ShapeRetriever* m_parent; + virtual const btCollisionShape* getChildShape(int index) { return m_parent->m_gim_shape->getChildShape(index); } virtual ~ChildShapeRetriever() {} }; - class TriangleShapeRetriever:public ChildShapeRetriever + class TriangleShapeRetriever : public ChildShapeRetriever { public: - - virtual btCollisionShape * getChildShape(int index) + virtual btCollisionShape* getChildShape(int index) { - m_parent->m_gim_shape->getBulletTriangle(index,m_parent->m_trishape); + m_parent->m_gim_shape->getBulletTriangle(index, m_parent->m_trishape); return &m_parent->m_trishape; } virtual ~TriangleShapeRetriever() {} }; - class TetraShapeRetriever:public ChildShapeRetriever + class TetraShapeRetriever : public ChildShapeRetriever { public: - - virtual btCollisionShape * getChildShape(int index) + virtual btCollisionShape* getChildShape(int index) { - m_parent->m_gim_shape->getBulletTetrahedron(index,m_parent->m_tetrashape); + m_parent->m_gim_shape->getBulletTetrahedron(index, m_parent->m_tetrashape); return &m_parent->m_tetrashape; } }; + public: ChildShapeRetriever m_child_retriever; TriangleShapeRetriever m_tri_retriever; - TetraShapeRetriever m_tetra_retriever; - ChildShapeRetriever * m_current_retriever; + TetraShapeRetriever m_tetra_retriever; + ChildShapeRetriever* m_current_retriever; - GIM_ShapeRetriever(const btGImpactShapeInterface * gim_shape) + GIM_ShapeRetriever(const btGImpactShapeInterface* gim_shape) { m_gim_shape = gim_shape; //select retriever - if(m_gim_shape->needsRetrieveTriangles()) + if (m_gim_shape->needsRetrieveTriangles()) { m_current_retriever = &m_tri_retriever; } - else if(m_gim_shape->needsRetrieveTetrahedrons()) + else if (m_gim_shape->needsRetrieveTetrahedrons()) { m_current_retriever = &m_tetra_retriever; } @@ -153,32 +147,26 @@ public: m_current_retriever->m_parent = this; } - const btCollisionShape * getChildShape(int index) + const btCollisionShape* getChildShape(int index) { return m_current_retriever->getChildShape(index); } - - }; - - //!@} - #ifdef TRI_COLLISION_PROFILING //! Gets the average time in miliseconds of tree collisions float btGImpactCollisionAlgorithm::getAverageTreeCollisionTime() { return btGImpactBoxSet::getAverageTreeCollisionTime(); - } //! Gets the average time in miliseconds of triangle collisions float btGImpactCollisionAlgorithm::getAverageTriangleCollisionTime() { - if(g_count_triangle_collision == 0) return 0; + if (g_count_triangle_collision == 0) return 0; float avgtime = g_accum_triangle_collision_time; avgtime /= (float)g_count_triangle_collision; @@ -189,12 +177,10 @@ float btGImpactCollisionAlgorithm::getAverageTriangleCollisionTime() return avgtime; } -#endif //TRI_COLLISION_PROFILING +#endif //TRI_COLLISION_PROFILING - - -btGImpactCollisionAlgorithm::btGImpactCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) -: btActivatingCollisionAlgorithm(ci,body0Wrap,body1Wrap) +btGImpactCollisionAlgorithm::btGImpactCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) + : btActivatingCollisionAlgorithm(ci, body0Wrap, body1Wrap) { m_manifoldPtr = NULL; m_convex_algorithm = NULL; @@ -205,77 +191,62 @@ btGImpactCollisionAlgorithm::~btGImpactCollisionAlgorithm() clearCache(); } - - - - -void btGImpactCollisionAlgorithm::addContactPoint(const btCollisionObjectWrapper * body0Wrap, - const btCollisionObjectWrapper * body1Wrap, - const btVector3 & point, - const btVector3 & normal, - btScalar distance) +void btGImpactCollisionAlgorithm::addContactPoint(const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper* body1Wrap, + const btVector3& point, + const btVector3& normal, + btScalar distance) { - m_resultOut->setShapeIdentifiersA(m_part0,m_triface0); - m_resultOut->setShapeIdentifiersB(m_part1,m_triface1); - checkManifold(body0Wrap,body1Wrap); - m_resultOut->addContactPoint(normal,point,distance); + m_resultOut->setShapeIdentifiersA(m_part0, m_triface0); + m_resultOut->setShapeIdentifiersB(m_part1, m_triface1); + checkManifold(body0Wrap, body1Wrap); + m_resultOut->addContactPoint(normal, point, distance); } - void btGImpactCollisionAlgorithm::shape_vs_shape_collision( - const btCollisionObjectWrapper * body0Wrap, - const btCollisionObjectWrapper* body1Wrap, - const btCollisionShape * shape0, - const btCollisionShape * shape1) + const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper* body1Wrap, + const btCollisionShape* shape0, + const btCollisionShape* shape1) { - - { - - btCollisionAlgorithm* algor = newAlgorithm(body0Wrap,body1Wrap); + btCollisionAlgorithm* algor = newAlgorithm(body0Wrap, body1Wrap); // post : checkManifold is called - m_resultOut->setShapeIdentifiersA(m_part0,m_triface0); - m_resultOut->setShapeIdentifiersB(m_part1,m_triface1); - - algor->processCollision(body0Wrap,body1Wrap,*m_dispatchInfo,m_resultOut); - + m_resultOut->setShapeIdentifiersA(m_part0, m_triface0); + m_resultOut->setShapeIdentifiersB(m_part1, m_triface1); + + algor->processCollision(body0Wrap, body1Wrap, *m_dispatchInfo, m_resultOut); + algor->~btCollisionAlgorithm(); m_dispatcher->freeCollisionAlgorithm(algor); } - } void btGImpactCollisionAlgorithm::convex_vs_convex_collision( - const btCollisionObjectWrapper* body0Wrap, - const btCollisionObjectWrapper* body1Wrap, - const btCollisionShape* shape0, - const btCollisionShape* shape1) + const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper* body1Wrap, + const btCollisionShape* shape0, + const btCollisionShape* shape1) { + m_resultOut->setShapeIdentifiersA(m_part0, m_triface0); + m_resultOut->setShapeIdentifiersB(m_part1, m_triface1); - m_resultOut->setShapeIdentifiersA(m_part0,m_triface0); - m_resultOut->setShapeIdentifiersB(m_part1,m_triface1); - - btCollisionObjectWrapper ob0(body0Wrap,shape0,body0Wrap->getCollisionObject(),body0Wrap->getWorldTransform(),m_part0,m_triface0); - btCollisionObjectWrapper ob1(body1Wrap,shape1,body1Wrap->getCollisionObject(),body1Wrap->getWorldTransform(),m_part1,m_triface1); - checkConvexAlgorithm(&ob0,&ob1); - m_convex_algorithm->processCollision(&ob0,&ob1,*m_dispatchInfo,m_resultOut); - - + btCollisionObjectWrapper ob0(body0Wrap, shape0, body0Wrap->getCollisionObject(), body0Wrap->getWorldTransform(), m_part0, m_triface0); + btCollisionObjectWrapper ob1(body1Wrap, shape1, body1Wrap->getCollisionObject(), body1Wrap->getWorldTransform(), m_part1, m_triface1); + checkConvexAlgorithm(&ob0, &ob1); + m_convex_algorithm->processCollision(&ob0, &ob1, *m_dispatchInfo, m_resultOut); } - - - void btGImpactCollisionAlgorithm::gimpact_vs_gimpact_find_pairs( - const btTransform & trans0, - const btTransform & trans1, - const btGImpactShapeInterface * shape0, - const btGImpactShapeInterface * shape1,btPairSet & pairset) + const btTransform& trans0, + const btTransform& trans1, + const btGImpactShapeInterface* shape0, + const btGImpactShapeInterface* shape1, btPairSet& pairset) { - if(shape0->hasBoxSet() && shape1->hasBoxSet()) + if (shape0->hasBoxSet() && shape1->hasBoxSet()) { - btGImpactBoxSet::find_collision(shape0->getBoxSet(),trans0,shape1->getBoxSet(),trans1,pairset); + btGImpactBoxSet::find_collision(shape0->getBoxSet(), trans0, shape1->getBoxSet(), trans1, pairset); } else { @@ -283,74 +254,66 @@ void btGImpactCollisionAlgorithm::gimpact_vs_gimpact_find_pairs( btAABB boxshape1; int i = shape0->getNumChildShapes(); - while(i--) + while (i--) { - shape0->getChildAabb(i,trans0,boxshape0.m_min,boxshape0.m_max); + shape0->getChildAabb(i, trans0, boxshape0.m_min, boxshape0.m_max); int j = shape1->getNumChildShapes(); - while(j--) + while (j--) { - shape1->getChildAabb(i,trans1,boxshape1.m_min,boxshape1.m_max); + shape1->getChildAabb(i, trans1, boxshape1.m_min, boxshape1.m_max); - if(boxshape1.has_collision(boxshape0)) + if (boxshape1.has_collision(boxshape0)) { - pairset.push_pair(i,j); + pairset.push_pair(i, j); } } } } - - } - void btGImpactCollisionAlgorithm::gimpact_vs_shape_find_pairs( - const btTransform & trans0, - const btTransform & trans1, - const btGImpactShapeInterface * shape0, - const btCollisionShape * shape1, - btAlignedObjectArray & collided_primitives) + const btTransform& trans0, + const btTransform& trans1, + const btGImpactShapeInterface* shape0, + const btCollisionShape* shape1, + btAlignedObjectArray& collided_primitives) { - btAABB boxshape; - - if(shape0->hasBoxSet()) + if (shape0->hasBoxSet()) { btTransform trans1to0 = trans0.inverse(); trans1to0 *= trans1; - shape1->getAabb(trans1to0,boxshape.m_min,boxshape.m_max); + shape1->getAabb(trans1to0, boxshape.m_min, boxshape.m_max); shape0->getBoxSet()->boxQuery(boxshape, collided_primitives); } else { - shape1->getAabb(trans1,boxshape.m_min,boxshape.m_max); + shape1->getAabb(trans1, boxshape.m_min, boxshape.m_max); btAABB boxshape0; int i = shape0->getNumChildShapes(); - while(i--) + while (i--) { - shape0->getChildAabb(i,trans0,boxshape0.m_min,boxshape0.m_max); + shape0->getChildAabb(i, trans0, boxshape0.m_min, boxshape0.m_max); - if(boxshape.has_collision(boxshape0)) + if (boxshape.has_collision(boxshape0)) { collided_primitives.push_back(i); } } - } - } - -void btGImpactCollisionAlgorithm::collide_gjk_triangles(const btCollisionObjectWrapper * body0Wrap, - const btCollisionObjectWrapper * body1Wrap, - const btGImpactMeshShapePart * shape0, - const btGImpactMeshShapePart * shape1, - const int * pairs, int pair_count) +void btGImpactCollisionAlgorithm::collide_gjk_triangles(const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper* body1Wrap, + const btGImpactMeshShapePart* shape0, + const btGImpactMeshShapePart* shape1, + const int* pairs, int pair_count) { btTriangleShapeEx tri0; btTriangleShapeEx tri1; @@ -358,27 +321,22 @@ void btGImpactCollisionAlgorithm::collide_gjk_triangles(const btCollisionObjectW shape0->lockChildShapes(); shape1->lockChildShapes(); - const int * pair_pointer = pairs; + const int* pair_pointer = pairs; - while(pair_count--) + while (pair_count--) { - m_triface0 = *(pair_pointer); - m_triface1 = *(pair_pointer+1); - pair_pointer+=2; - - - - shape0->getBulletTriangle(m_triface0,tri0); - shape1->getBulletTriangle(m_triface1,tri1); + m_triface1 = *(pair_pointer + 1); + pair_pointer += 2; + shape0->getBulletTriangle(m_triface0, tri0); + shape1->getBulletTriangle(m_triface1, tri1); //collide two convex shapes - if(tri0.overlap_test_conservative(tri1)) + if (tri0.overlap_test_conservative(tri1)) { - convex_vs_convex_collision(body0Wrap,body1Wrap,&tri0,&tri1); + convex_vs_convex_collision(body0Wrap, body1Wrap, &tri0, &tri1); } - } shape0->unlockChildShapes(); @@ -386,10 +344,10 @@ void btGImpactCollisionAlgorithm::collide_gjk_triangles(const btCollisionObjectW } void btGImpactCollisionAlgorithm::collide_sat_triangles(const btCollisionObjectWrapper* body0Wrap, - const btCollisionObjectWrapper* body1Wrap, - const btGImpactMeshShapePart * shape0, - const btGImpactMeshShapePart * shape1, - const int * pairs, int pair_count) + const btCollisionObjectWrapper* body1Wrap, + const btGImpactMeshShapePart* shape0, + const btGImpactMeshShapePart* shape1, + const int* pairs, int pair_count) { btTransform orgtrans0 = body0Wrap->getWorldTransform(); btTransform orgtrans1 = body1Wrap->getWorldTransform(); @@ -401,119 +359,105 @@ void btGImpactCollisionAlgorithm::collide_sat_triangles(const btCollisionObjectW shape0->lockChildShapes(); shape1->lockChildShapes(); - const int * pair_pointer = pairs; + const int* pair_pointer = pairs; - while(pair_count--) + while (pair_count--) { - m_triface0 = *(pair_pointer); - m_triface1 = *(pair_pointer+1); - pair_pointer+=2; + m_triface1 = *(pair_pointer + 1); + pair_pointer += 2; + shape0->getPrimitiveTriangle(m_triface0, ptri0); + shape1->getPrimitiveTriangle(m_triface1, ptri1); - shape0->getPrimitiveTriangle(m_triface0,ptri0); - shape1->getPrimitiveTriangle(m_triface1,ptri1); - - #ifdef TRI_COLLISION_PROFILING +#ifdef TRI_COLLISION_PROFILING bt_begin_gim02_tri_time(); - #endif +#endif ptri0.applyTransform(orgtrans0); ptri1.applyTransform(orgtrans1); - //build planes ptri0.buildTriPlane(); ptri1.buildTriPlane(); // test conservative - - - if(ptri0.overlap_test_conservative(ptri1)) + if (ptri0.overlap_test_conservative(ptri1)) { - if(ptri0.find_triangle_collision_clip_method(ptri1,contact_data)) + if (ptri0.find_triangle_collision_clip_method(ptri1, contact_data)) { - int j = contact_data.m_point_count; - while(j--) + while (j--) { - addContactPoint(body0Wrap, body1Wrap, - contact_data.m_points[j], - contact_data.m_separating_normal, - -contact_data.m_penetration_depth); + contact_data.m_points[j], + contact_data.m_separating_normal, + -contact_data.m_penetration_depth); } } } - #ifdef TRI_COLLISION_PROFILING +#ifdef TRI_COLLISION_PROFILING bt_end_gim02_tri_time(); - #endif - +#endif } shape0->unlockChildShapes(); shape1->unlockChildShapes(); - } - void btGImpactCollisionAlgorithm::gimpact_vs_gimpact( - const btCollisionObjectWrapper* body0Wrap, - const btCollisionObjectWrapper * body1Wrap, - const btGImpactShapeInterface * shape0, - const btGImpactShapeInterface * shape1) + const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper* body1Wrap, + const btGImpactShapeInterface* shape0, + const btGImpactShapeInterface* shape1) { - - if(shape0->getGImpactShapeType()==CONST_GIMPACT_TRIMESH_SHAPE) + if (shape0->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE) { - const btGImpactMeshShape * meshshape0 = static_cast(shape0); + const btGImpactMeshShape* meshshape0 = static_cast(shape0); m_part0 = meshshape0->getMeshPartCount(); - while(m_part0--) + while (m_part0--) { - gimpact_vs_gimpact(body0Wrap,body1Wrap,meshshape0->getMeshPart(m_part0),shape1); + gimpact_vs_gimpact(body0Wrap, body1Wrap, meshshape0->getMeshPart(m_part0), shape1); } return; } - if(shape1->getGImpactShapeType()==CONST_GIMPACT_TRIMESH_SHAPE) + if (shape1->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE) { - const btGImpactMeshShape * meshshape1 = static_cast(shape1); + const btGImpactMeshShape* meshshape1 = static_cast(shape1); m_part1 = meshshape1->getMeshPartCount(); - while(m_part1--) + while (m_part1--) { - - gimpact_vs_gimpact(body0Wrap,body1Wrap,shape0,meshshape1->getMeshPart(m_part1)); - + gimpact_vs_gimpact(body0Wrap, body1Wrap, shape0, meshshape1->getMeshPart(m_part1)); } return; } - btTransform orgtrans0 = body0Wrap->getWorldTransform(); btTransform orgtrans1 = body1Wrap->getWorldTransform(); btPairSet pairset; - gimpact_vs_gimpact_find_pairs(orgtrans0,orgtrans1,shape0,shape1,pairset); + gimpact_vs_gimpact_find_pairs(orgtrans0, orgtrans1, shape0, shape1, pairset); - if(pairset.size()== 0) return; + if (pairset.size() == 0) return; - if(shape0->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART && + if (shape0->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART && shape1->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART) { - const btGImpactMeshShapePart * shapepart0 = static_cast(shape0); - const btGImpactMeshShapePart * shapepart1 = static_cast(shape1); - //specialized function - #ifdef BULLET_TRIANGLE_COLLISION - collide_gjk_triangles(body0Wrap,body1Wrap,shapepart0,shapepart1,&pairset[0].m_index1,pairset.size()); - #else - collide_sat_triangles(body0Wrap,body1Wrap,shapepart0,shapepart1,&pairset[0].m_index1,pairset.size()); - #endif + const btGImpactMeshShapePart* shapepart0 = static_cast(shape0); + const btGImpactMeshShapePart* shapepart1 = static_cast(shape1); +//specialized function +#ifdef BULLET_TRIANGLE_COLLISION + collide_gjk_triangles(body0Wrap, body1Wrap, shapepart0, shapepart1, &pairset[0].m_index1, pairset.size()); +#else + collide_sat_triangles(body0Wrap, body1Wrap, shapepart0, shapepart1, &pairset[0].m_index1, pairset.size()); +#endif return; } @@ -530,32 +474,32 @@ void btGImpactCollisionAlgorithm::gimpact_vs_gimpact( bool child_has_transform1 = shape1->childrenHasTransform(); int i = pairset.size(); - while(i--) + while (i--) { - GIM_PAIR * pair = &pairset[i]; + GIM_PAIR* pair = &pairset[i]; m_triface0 = pair->m_index1; m_triface1 = pair->m_index2; - const btCollisionShape * colshape0 = retriever0.getChildShape(m_triface0); - const btCollisionShape * colshape1 = retriever1.getChildShape(m_triface1); + const btCollisionShape* colshape0 = retriever0.getChildShape(m_triface0); + const btCollisionShape* colshape1 = retriever1.getChildShape(m_triface1); btTransform tr0 = body0Wrap->getWorldTransform(); btTransform tr1 = body1Wrap->getWorldTransform(); - if(child_has_transform0) + if (child_has_transform0) { - tr0 = orgtrans0*shape0->getChildTransform(m_triface0); + tr0 = orgtrans0 * shape0->getChildTransform(m_triface0); } - if(child_has_transform1) + if (child_has_transform1) { - tr1 = orgtrans1*shape1->getChildTransform(m_triface1); + tr1 = orgtrans1 * shape1->getChildTransform(m_triface1); } - btCollisionObjectWrapper ob0(body0Wrap,colshape0,body0Wrap->getCollisionObject(),tr0,m_part0,m_triface0); - btCollisionObjectWrapper ob1(body1Wrap,colshape1,body1Wrap->getCollisionObject(),tr1,m_part1,m_triface1); + btCollisionObjectWrapper ob0(body0Wrap, colshape0, body0Wrap->getCollisionObject(), tr0, m_part0, m_triface0); + btCollisionObjectWrapper ob1(body1Wrap, colshape1, body1Wrap->getCollisionObject(), tr1, m_part1, m_triface1); //collide two convex shapes - convex_vs_convex_collision(&ob0,&ob1,colshape0,colshape1); + convex_vs_convex_collision(&ob0, &ob1, colshape0, colshape1); } shape0->unlockChildShapes(); @@ -563,159 +507,149 @@ void btGImpactCollisionAlgorithm::gimpact_vs_gimpact( } void btGImpactCollisionAlgorithm::gimpact_vs_shape(const btCollisionObjectWrapper* body0Wrap, - const btCollisionObjectWrapper * body1Wrap, - const btGImpactShapeInterface * shape0, - const btCollisionShape * shape1,bool swapped) + const btCollisionObjectWrapper* body1Wrap, + const btGImpactShapeInterface* shape0, + const btCollisionShape* shape1, bool swapped) { - if(shape0->getGImpactShapeType()==CONST_GIMPACT_TRIMESH_SHAPE) + if (shape0->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE) { - const btGImpactMeshShape * meshshape0 = static_cast(shape0); + const btGImpactMeshShape* meshshape0 = static_cast(shape0); int& part = swapped ? m_part1 : m_part0; part = meshshape0->getMeshPartCount(); - while(part--) + while (part--) { - gimpact_vs_shape(body0Wrap, - body1Wrap, - meshshape0->getMeshPart(part), - shape1,swapped); - + body1Wrap, + meshshape0->getMeshPart(part), + shape1, swapped); } return; } - #ifdef GIMPACT_VS_PLANE_COLLISION - if(shape0->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART && +#ifdef GIMPACT_VS_PLANE_COLLISION + if (shape0->getGImpactShapeType() == CONST_GIMPACT_TRIMESH_SHAPE_PART && shape1->getShapeType() == STATIC_PLANE_PROXYTYPE) { - const btGImpactMeshShapePart * shapepart = static_cast(shape0); - const btStaticPlaneShape * planeshape = static_cast(shape1); - gimpacttrimeshpart_vs_plane_collision(body0Wrap,body1Wrap,shapepart,planeshape,swapped); + const btGImpactMeshShapePart* shapepart = static_cast(shape0); + const btStaticPlaneShape* planeshape = static_cast(shape1); + gimpacttrimeshpart_vs_plane_collision(body0Wrap, body1Wrap, shapepart, planeshape, swapped); return; } - #endif +#endif - - - if(shape1->isCompound()) + if (shape1->isCompound()) { - const btCompoundShape * compoundshape = static_cast(shape1); - gimpact_vs_compoundshape(body0Wrap,body1Wrap,shape0,compoundshape,swapped); + const btCompoundShape* compoundshape = static_cast(shape1); + gimpact_vs_compoundshape(body0Wrap, body1Wrap, shape0, compoundshape, swapped); return; } - else if(shape1->isConcave()) + else if (shape1->isConcave()) { - const btConcaveShape * concaveshape = static_cast(shape1); - gimpact_vs_concave(body0Wrap,body1Wrap,shape0,concaveshape,swapped); + const btConcaveShape* concaveshape = static_cast(shape1); + gimpact_vs_concave(body0Wrap, body1Wrap, shape0, concaveshape, swapped); return; } - btTransform orgtrans0 = body0Wrap->getWorldTransform(); btTransform orgtrans1 = body1Wrap->getWorldTransform(); btAlignedObjectArray collided_results; - gimpact_vs_shape_find_pairs(orgtrans0,orgtrans1,shape0,shape1,collided_results); - - if(collided_results.size() == 0) return; + gimpact_vs_shape_find_pairs(orgtrans0, orgtrans1, shape0, shape1, collided_results); + if (collided_results.size() == 0) return; shape0->lockChildShapes(); GIM_ShapeRetriever retriever0(shape0); - bool child_has_transform0 = shape0->childrenHasTransform(); - int i = collided_results.size(); - while(i--) + while (i--) { int child_index = collided_results[i]; - if(swapped) - m_triface1 = child_index; - else - m_triface0 = child_index; + if (swapped) + m_triface1 = child_index; + else + m_triface0 = child_index; - const btCollisionShape * colshape0 = retriever0.getChildShape(child_index); + const btCollisionShape* colshape0 = retriever0.getChildShape(child_index); btTransform tr0 = body0Wrap->getWorldTransform(); - if(child_has_transform0) + if (child_has_transform0) { - tr0 = orgtrans0*shape0->getChildTransform(child_index); + tr0 = orgtrans0 * shape0->getChildTransform(child_index); } - btCollisionObjectWrapper ob0(body0Wrap,colshape0,body0Wrap->getCollisionObject(),body0Wrap->getWorldTransform(),m_part0,m_triface0); + btCollisionObjectWrapper ob0(body0Wrap, colshape0, body0Wrap->getCollisionObject(), body0Wrap->getWorldTransform(), m_part0, m_triface0); const btCollisionObjectWrapper* prevObj0 = m_resultOut->getBody0Wrap(); - - if (m_resultOut->getBody0Wrap()->getCollisionObject()==ob0.getCollisionObject()) + + if (m_resultOut->getBody0Wrap()->getCollisionObject() == ob0.getCollisionObject()) { m_resultOut->setBody0Wrap(&ob0); - } else + } + else { m_resultOut->setBody1Wrap(&ob0); } //collide two shapes - if(swapped) + if (swapped) { - - shape_vs_shape_collision(body1Wrap,&ob0,shape1,colshape0); + shape_vs_shape_collision(body1Wrap, &ob0, shape1, colshape0); } else { - - shape_vs_shape_collision(&ob0,body1Wrap,colshape0,shape1); + shape_vs_shape_collision(&ob0, body1Wrap, colshape0, shape1); } m_resultOut->setBody0Wrap(prevObj0); - } shape0->unlockChildShapes(); - } void btGImpactCollisionAlgorithm::gimpact_vs_compoundshape(const btCollisionObjectWrapper* body0Wrap, - const btCollisionObjectWrapper* body1Wrap, - const btGImpactShapeInterface * shape0, - const btCompoundShape * shape1,bool swapped) + const btCollisionObjectWrapper* body1Wrap, + const btGImpactShapeInterface* shape0, + const btCompoundShape* shape1, bool swapped) { btTransform orgtrans1 = body1Wrap->getWorldTransform(); int i = shape1->getNumChildShapes(); - while(i--) + while (i--) { + const btCollisionShape* colshape1 = shape1->getChildShape(i); + btTransform childtrans1 = orgtrans1 * shape1->getChildTransform(i); - const btCollisionShape * colshape1 = shape1->getChildShape(i); - btTransform childtrans1 = orgtrans1*shape1->getChildTransform(i); + btCollisionObjectWrapper ob1(body1Wrap, colshape1, body1Wrap->getCollisionObject(), childtrans1, -1, i); - btCollisionObjectWrapper ob1(body1Wrap,colshape1,body1Wrap->getCollisionObject(),childtrans1,-1,i); - const btCollisionObjectWrapper* tmp = 0; - if (m_resultOut->getBody0Wrap()->getCollisionObject()==ob1.getCollisionObject()) + if (m_resultOut->getBody0Wrap()->getCollisionObject() == ob1.getCollisionObject()) { tmp = m_resultOut->getBody0Wrap(); m_resultOut->setBody0Wrap(&ob1); - } else + } + else { tmp = m_resultOut->getBody1Wrap(); m_resultOut->setBody1Wrap(&ob1); } //collide child shape gimpact_vs_shape(body0Wrap, &ob1, - shape0,colshape1,swapped); + shape0, colshape1, swapped); - if (m_resultOut->getBody0Wrap()->getCollisionObject()==ob1.getCollisionObject()) + if (m_resultOut->getBody0Wrap()->getCollisionObject() == ob1.getCollisionObject()) { m_resultOut->setBody0Wrap(tmp); - } else + } + else { m_resultOut->setBody1Wrap(tmp); } @@ -723,27 +657,25 @@ void btGImpactCollisionAlgorithm::gimpact_vs_compoundshape(const btCollisionObje } void btGImpactCollisionAlgorithm::gimpacttrimeshpart_vs_plane_collision( - const btCollisionObjectWrapper * body0Wrap, - const btCollisionObjectWrapper * body1Wrap, - const btGImpactMeshShapePart * shape0, - const btStaticPlaneShape * shape1,bool swapped) + const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper* body1Wrap, + const btGImpactMeshShapePart* shape0, + const btStaticPlaneShape* shape1, bool swapped) { - - btTransform orgtrans0 = body0Wrap->getWorldTransform(); btTransform orgtrans1 = body1Wrap->getWorldTransform(); - const btPlaneShape * planeshape = static_cast(shape1); + const btPlaneShape* planeshape = static_cast(shape1); btVector4 plane; - planeshape->get_plane_equation_transformed(orgtrans1,plane); + planeshape->get_plane_equation_transformed(orgtrans1, plane); //test box against plane btAABB tribox; - shape0->getAabb(orgtrans0,tribox.m_min,tribox.m_max); + shape0->getAabb(orgtrans0, tribox.m_min, tribox.m_max); tribox.increment_margin(planeshape->getMargin()); - if( tribox.plane_classify(plane)!= BT_CONST_COLLIDE_PLANE) return; + if (tribox.plane_classify(plane) != BT_CONST_COLLIDE_PLANE) return; shape0->lockChildShapes(); @@ -751,28 +683,28 @@ void btGImpactCollisionAlgorithm::gimpacttrimeshpart_vs_plane_collision( btVector3 vertex; int vi = shape0->getVertexCount(); - while(vi--) + while (vi--) { - shape0->getVertex(vi,vertex); + shape0->getVertex(vi, vertex); vertex = orgtrans0(vertex); btScalar distance = vertex.dot(plane) - plane[3] - margin; - if(distance<0.0)//add contact + if (distance < 0.0) //add contact { - if(swapped) + if (swapped) { addContactPoint(body1Wrap, body0Wrap, - vertex, - -plane, - distance); + vertex, + -plane, + distance); } else { addContactPoint(body0Wrap, body1Wrap, - vertex, - plane, - distance); + vertex, + plane, + distance); } } } @@ -780,69 +712,64 @@ void btGImpactCollisionAlgorithm::gimpacttrimeshpart_vs_plane_collision( shape0->unlockChildShapes(); } - - - -class btGImpactTriangleCallback: public btTriangleCallback +class btGImpactTriangleCallback : public btTriangleCallback { public: - btGImpactCollisionAlgorithm * algorithm; - const btCollisionObjectWrapper * body0Wrap; - const btCollisionObjectWrapper * body1Wrap; - const btGImpactShapeInterface * gimpactshape0; + btGImpactCollisionAlgorithm* algorithm; + const btCollisionObjectWrapper* body0Wrap; + const btCollisionObjectWrapper* body1Wrap; + const btGImpactShapeInterface* gimpactshape0; bool swapped; btScalar margin; virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) { - btTriangleShapeEx tri1(triangle[0],triangle[1],triangle[2]); + btTriangleShapeEx tri1(triangle[0], triangle[1], triangle[2]); tri1.setMargin(margin); - if(swapped) - { - algorithm->setPart0(partId); - algorithm->setFace0(triangleIndex); - } - else - { - algorithm->setPart1(partId); - algorithm->setFace1(triangleIndex); - } + if (swapped) + { + algorithm->setPart0(partId); + algorithm->setFace0(triangleIndex); + } + else + { + algorithm->setPart1(partId); + algorithm->setFace1(triangleIndex); + } - btCollisionObjectWrapper ob1Wrap(body1Wrap,&tri1,body1Wrap->getCollisionObject(),body1Wrap->getWorldTransform(),partId,triangleIndex); - const btCollisionObjectWrapper * tmp = 0; + btCollisionObjectWrapper ob1Wrap(body1Wrap, &tri1, body1Wrap->getCollisionObject(), body1Wrap->getWorldTransform(), partId, triangleIndex); + const btCollisionObjectWrapper* tmp = 0; - if (algorithm->internalGetResultOut()->getBody0Wrap()->getCollisionObject()==ob1Wrap.getCollisionObject()) + if (algorithm->internalGetResultOut()->getBody0Wrap()->getCollisionObject() == ob1Wrap.getCollisionObject()) { tmp = algorithm->internalGetResultOut()->getBody0Wrap(); algorithm->internalGetResultOut()->setBody0Wrap(&ob1Wrap); - } else + } + else { tmp = algorithm->internalGetResultOut()->getBody1Wrap(); algorithm->internalGetResultOut()->setBody1Wrap(&ob1Wrap); } - - algorithm->gimpact_vs_shape( - body0Wrap,&ob1Wrap,gimpactshape0,&tri1,swapped); - if (algorithm->internalGetResultOut()->getBody0Wrap()->getCollisionObject()==ob1Wrap.getCollisionObject()) + algorithm->gimpact_vs_shape( + body0Wrap, &ob1Wrap, gimpactshape0, &tri1, swapped); + + if (algorithm->internalGetResultOut()->getBody0Wrap()->getCollisionObject() == ob1Wrap.getCollisionObject()) { algorithm->internalGetResultOut()->setBody0Wrap(tmp); - } else + } + else { algorithm->internalGetResultOut()->setBody1Wrap(tmp); } - } }; - - - void btGImpactCollisionAlgorithm::gimpact_vs_concave( - const btCollisionObjectWrapper* body0Wrap, - const btCollisionObjectWrapper * body1Wrap, - const btGImpactShapeInterface * shape0, - const btConcaveShape * shape1,bool swapped) + const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper* body1Wrap, + const btGImpactShapeInterface* shape0, + const btConcaveShape* shape1, bool swapped) { //create the callback btGImpactTriangleCallback tricallback; @@ -858,75 +785,65 @@ void btGImpactCollisionAlgorithm::gimpact_vs_concave( gimpactInConcaveSpace = body1Wrap->getWorldTransform().inverse() * body0Wrap->getWorldTransform(); - btVector3 minAABB,maxAABB; - shape0->getAabb(gimpactInConcaveSpace,minAABB,maxAABB); - - shape1->processAllTriangles(&tricallback,minAABB,maxAABB); + btVector3 minAABB, maxAABB; + shape0->getAabb(gimpactInConcaveSpace, minAABB, maxAABB); + shape1->processAllTriangles(&tricallback, minAABB, maxAABB); } - - -void btGImpactCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +void btGImpactCollisionAlgorithm::processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { - clearCache(); + clearCache(); - m_resultOut = resultOut; + m_resultOut = resultOut; m_dispatchInfo = &dispatchInfo; - const btGImpactShapeInterface * gimpactshape0; - const btGImpactShapeInterface * gimpactshape1; + const btGImpactShapeInterface* gimpactshape0; + const btGImpactShapeInterface* gimpactshape1; - if (body0Wrap->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE) + if (body0Wrap->getCollisionShape()->getShapeType() == GIMPACT_SHAPE_PROXYTYPE) { - gimpactshape0 = static_cast(body0Wrap->getCollisionShape()); + gimpactshape0 = static_cast(body0Wrap->getCollisionShape()); - if( body1Wrap->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE ) + if (body1Wrap->getCollisionShape()->getShapeType() == GIMPACT_SHAPE_PROXYTYPE) { - gimpactshape1 = static_cast(body1Wrap->getCollisionShape()); + gimpactshape1 = static_cast(body1Wrap->getCollisionShape()); - gimpact_vs_gimpact(body0Wrap,body1Wrap,gimpactshape0,gimpactshape1); + gimpact_vs_gimpact(body0Wrap, body1Wrap, gimpactshape0, gimpactshape1); } else { - gimpact_vs_shape(body0Wrap,body1Wrap,gimpactshape0,body1Wrap->getCollisionShape(),false); + gimpact_vs_shape(body0Wrap, body1Wrap, gimpactshape0, body1Wrap->getCollisionShape(), false); } - } - else if (body1Wrap->getCollisionShape()->getShapeType()==GIMPACT_SHAPE_PROXYTYPE ) + else if (body1Wrap->getCollisionShape()->getShapeType() == GIMPACT_SHAPE_PROXYTYPE) { - gimpactshape1 = static_cast(body1Wrap->getCollisionShape()); + gimpactshape1 = static_cast(body1Wrap->getCollisionShape()); - gimpact_vs_shape(body1Wrap,body0Wrap,gimpactshape1,body0Wrap->getCollisionShape(),true); + gimpact_vs_shape(body1Wrap, body0Wrap, gimpactshape1, body0Wrap->getCollisionShape(), true); } } - -btScalar btGImpactCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +btScalar btGImpactCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { return 1.f; - } ///////////////////////////////////// REGISTERING ALGORITHM ////////////////////////////////////////////// - - //! Use this function for register the algorithm externally -void btGImpactCollisionAlgorithm::registerAlgorithm(btCollisionDispatcher * dispatcher) +void btGImpactCollisionAlgorithm::registerAlgorithm(btCollisionDispatcher* dispatcher) { - static btGImpactCollisionAlgorithm::CreateFunc s_gimpact_cf; int i; - for ( i = 0;i < MAX_BROADPHASE_COLLISION_TYPES ;i++ ) + for (i = 0; i < MAX_BROADPHASE_COLLISION_TYPES; i++) { - dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE,i ,&s_gimpact_cf); + dispatcher->registerCollisionCreateFunc(GIMPACT_SHAPE_PROXYTYPE, i, &s_gimpact_cf); } - for ( i = 0;i < MAX_BROADPHASE_COLLISION_TYPES ;i++ ) + for (i = 0; i < MAX_BROADPHASE_COLLISION_TYPES; i++) { - dispatcher->registerCollisionCreateFunc(i,GIMPACT_SHAPE_PROXYTYPE ,&s_gimpact_cf); + dispatcher->registerCollisionCreateFunc(i, GIMPACT_SHAPE_PROXYTYPE, &s_gimpact_cf); } - } diff --git a/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h b/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h index 3e5675f72..a368c8a0c 100644 --- a/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h +++ b/src/BulletCollision/Gimpact/btGImpactCollisionAlgorithm.h @@ -42,7 +42,6 @@ class btDispatcher; #include "LinearMath/btIDebugDraw.h" #include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" - //! Collision Algorithm for GImpact Shapes /*! For register this algorithm in Bullet, proceed as following: @@ -54,36 +53,35 @@ btGImpactCollisionAlgorithm::registerAlgorithm(dispatcher); class btGImpactCollisionAlgorithm : public btActivatingCollisionAlgorithm { protected: - btCollisionAlgorithm * m_convex_algorithm; - btPersistentManifold * m_manifoldPtr; + btCollisionAlgorithm* m_convex_algorithm; + btPersistentManifold* m_manifoldPtr; btManifoldResult* m_resultOut; - const btDispatcherInfo * m_dispatchInfo; + const btDispatcherInfo* m_dispatchInfo; int m_triface0; int m_part0; int m_triface1; int m_part1; - //! Creates a new contact point - SIMD_FORCE_INLINE btPersistentManifold* newContactManifold(const btCollisionObject* body0,const btCollisionObject* body1) + SIMD_FORCE_INLINE btPersistentManifold* newContactManifold(const btCollisionObject* body0, const btCollisionObject* body1) { - m_manifoldPtr = m_dispatcher->getNewManifold(body0,body1); + m_manifoldPtr = m_dispatcher->getNewManifold(body0, body1); return m_manifoldPtr; } SIMD_FORCE_INLINE void destroyConvexAlgorithm() { - if(m_convex_algorithm) + if (m_convex_algorithm) { m_convex_algorithm->~btCollisionAlgorithm(); - m_dispatcher->freeCollisionAlgorithm( m_convex_algorithm); + m_dispatcher->freeCollisionAlgorithm(m_convex_algorithm); m_convex_algorithm = NULL; } } SIMD_FORCE_INLINE void destroyContactManifolds() { - if(m_manifoldPtr == NULL) return; + if (m_manifoldPtr == NULL) return; m_dispatcher->releaseManifold(m_manifoldPtr); m_manifoldPtr = NULL; } @@ -104,207 +102,187 @@ protected: return m_manifoldPtr; } - // Call before process collision - SIMD_FORCE_INLINE void checkManifold(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + SIMD_FORCE_INLINE void checkManifold(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { - if(getLastManifold() == 0) + if (getLastManifold() == 0) { - newContactManifold(body0Wrap->getCollisionObject(),body1Wrap->getCollisionObject()); + newContactManifold(body0Wrap->getCollisionObject(), body1Wrap->getCollisionObject()); } m_resultOut->setPersistentManifold(getLastManifold()); } // Call before process collision - SIMD_FORCE_INLINE btCollisionAlgorithm * newAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + SIMD_FORCE_INLINE btCollisionAlgorithm* newAlgorithm(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { - checkManifold(body0Wrap,body1Wrap); + checkManifold(body0Wrap, body1Wrap); - btCollisionAlgorithm * convex_algorithm = m_dispatcher->findAlgorithm( - body0Wrap,body1Wrap,getLastManifold(), BT_CONTACT_POINT_ALGORITHMS); - return convex_algorithm ; + btCollisionAlgorithm* convex_algorithm = m_dispatcher->findAlgorithm( + body0Wrap, body1Wrap, getLastManifold(), BT_CONTACT_POINT_ALGORITHMS); + return convex_algorithm; } // Call before process collision - SIMD_FORCE_INLINE void checkConvexAlgorithm(const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + SIMD_FORCE_INLINE void checkConvexAlgorithm(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { - if(m_convex_algorithm) return; - m_convex_algorithm = newAlgorithm(body0Wrap,body1Wrap); + if (m_convex_algorithm) return; + m_convex_algorithm = newAlgorithm(body0Wrap, body1Wrap); } + void addContactPoint(const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper* body1Wrap, + const btVector3& point, + const btVector3& normal, + btScalar distance); - - - void addContactPoint(const btCollisionObjectWrapper * body0Wrap, - const btCollisionObjectWrapper * body1Wrap, - const btVector3 & point, - const btVector3 & normal, - btScalar distance); - -//! Collision routines -//!@{ + //! Collision routines + //!@{ void collide_gjk_triangles(const btCollisionObjectWrapper* body0Wrap, - const btCollisionObjectWrapper* body1Wrap, - const btGImpactMeshShapePart * shape0, - const btGImpactMeshShapePart * shape1, - const int * pairs, int pair_count); + const btCollisionObjectWrapper* body1Wrap, + const btGImpactMeshShapePart* shape0, + const btGImpactMeshShapePart* shape1, + const int* pairs, int pair_count); void collide_sat_triangles(const btCollisionObjectWrapper* body0Wrap, - const btCollisionObjectWrapper* body1Wrap, - const btGImpactMeshShapePart * shape0, - const btGImpactMeshShapePart * shape1, - const int * pairs, int pair_count); - - - + const btCollisionObjectWrapper* body1Wrap, + const btGImpactMeshShapePart* shape0, + const btGImpactMeshShapePart* shape1, + const int* pairs, int pair_count); void shape_vs_shape_collision( - const btCollisionObjectWrapper* body0, - const btCollisionObjectWrapper* body1, - const btCollisionShape * shape0, - const btCollisionShape * shape1); + const btCollisionObjectWrapper* body0, + const btCollisionObjectWrapper* body1, + const btCollisionShape* shape0, + const btCollisionShape* shape1); void convex_vs_convex_collision(const btCollisionObjectWrapper* body0Wrap, - const btCollisionObjectWrapper* body1Wrap, - const btCollisionShape* shape0, - const btCollisionShape* shape1); - - + const btCollisionObjectWrapper* body1Wrap, + const btCollisionShape* shape0, + const btCollisionShape* shape1); void gimpact_vs_gimpact_find_pairs( - const btTransform & trans0, - const btTransform & trans1, - const btGImpactShapeInterface * shape0, - const btGImpactShapeInterface * shape1,btPairSet & pairset); + const btTransform& trans0, + const btTransform& trans1, + const btGImpactShapeInterface* shape0, + const btGImpactShapeInterface* shape1, btPairSet& pairset); void gimpact_vs_shape_find_pairs( - const btTransform & trans0, - const btTransform & trans1, - const btGImpactShapeInterface * shape0, - const btCollisionShape * shape1, - btAlignedObjectArray & collided_primitives); - + const btTransform& trans0, + const btTransform& trans1, + const btGImpactShapeInterface* shape0, + const btCollisionShape* shape1, + btAlignedObjectArray& collided_primitives); void gimpacttrimeshpart_vs_plane_collision( - const btCollisionObjectWrapper * body0Wrap, - const btCollisionObjectWrapper * body1Wrap, - const btGImpactMeshShapePart * shape0, - const btStaticPlaneShape * shape1,bool swapped); - + const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper* body1Wrap, + const btGImpactMeshShapePart* shape0, + const btStaticPlaneShape* shape1, bool swapped); public: - - btGImpactCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap); + btGImpactCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap); virtual ~btGImpactCollisionAlgorithm(); - virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) { if (m_manifoldPtr) manifoldArray.push_back(m_manifoldPtr); } - btManifoldResult* internalGetResultOut() + btManifoldResult* internalGetResultOut() { return m_resultOut; } - struct CreateFunc :public btCollisionAlgorithmCreateFunc + struct CreateFunc : public btCollisionAlgorithmCreateFunc { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btGImpactCollisionAlgorithm)); - return new(mem) btGImpactCollisionAlgorithm(ci,body0Wrap,body1Wrap); + return new (mem) btGImpactCollisionAlgorithm(ci, body0Wrap, body1Wrap); } }; //! Use this function for register the algorithm externally - static void registerAlgorithm(btCollisionDispatcher * dispatcher); + static void registerAlgorithm(btCollisionDispatcher* dispatcher); #ifdef TRI_COLLISION_PROFILING //! Gets the average time in miliseconds of tree collisions static float getAverageTreeCollisionTime(); //! Gets the average time in miliseconds of triangle collisions static float getAverageTriangleCollisionTime(); -#endif //TRI_COLLISION_PROFILING +#endif //TRI_COLLISION_PROFILING //! Collides two gimpact shapes /*! \pre shape0 and shape1 couldn't be btGImpactMeshShape objects */ - void gimpact_vs_gimpact(const btCollisionObjectWrapper* body0Wrap, - const btCollisionObjectWrapper * body1Wrap, - const btGImpactShapeInterface * shape0, - const btGImpactShapeInterface * shape1); + const btCollisionObjectWrapper* body1Wrap, + const btGImpactShapeInterface* shape0, + const btGImpactShapeInterface* shape1); void gimpact_vs_shape(const btCollisionObjectWrapper* body0Wrap, - const btCollisionObjectWrapper* body1Wrap, - const btGImpactShapeInterface * shape0, - const btCollisionShape * shape1,bool swapped); + const btCollisionObjectWrapper* body1Wrap, + const btGImpactShapeInterface* shape0, + const btCollisionShape* shape1, bool swapped); - void gimpact_vs_compoundshape(const btCollisionObjectWrapper * body0Wrap, - const btCollisionObjectWrapper * body1Wrap, - const btGImpactShapeInterface * shape0, - const btCompoundShape * shape1,bool swapped); + void gimpact_vs_compoundshape(const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper* body1Wrap, + const btGImpactShapeInterface* shape0, + const btCompoundShape* shape1, bool swapped); void gimpact_vs_concave( - const btCollisionObjectWrapper * body0Wrap, - const btCollisionObjectWrapper * body1Wrap, - const btGImpactShapeInterface * shape0, - const btConcaveShape * shape1,bool swapped); - - - - - /// Accessor/Mutator pairs for Part and triangleID - void setFace0(int value) - { - m_triface0 = value; - } - int getFace0() - { - return m_triface0; - } - void setFace1(int value) - { - m_triface1 = value; - } - int getFace1() - { - return m_triface1; - } - void setPart0(int value) - { - m_part0 = value; - } - int getPart0() - { - return m_part0; - } - void setPart1(int value) - { - m_part1 = value; - } - int getPart1() - { - return m_part1; - } + const btCollisionObjectWrapper* body0Wrap, + const btCollisionObjectWrapper* body1Wrap, + const btGImpactShapeInterface* shape0, + const btConcaveShape* shape1, bool swapped); + /// Accessor/Mutator pairs for Part and triangleID + void setFace0(int value) + { + m_triface0 = value; + } + int getFace0() + { + return m_triface0; + } + void setFace1(int value) + { + m_triface1 = value; + } + int getFace1() + { + return m_triface1; + } + void setPart0(int value) + { + m_part0 = value; + } + int getPart0() + { + return m_part0; + } + void setPart1(int value) + { + m_part1 = value; + } + int getPart1() + { + return m_part1; + } }; - //algorithm details //#define BULLET_TRIANGLE_COLLISION 1 #define GIMPACT_VS_PLANE_COLLISION 1 - - -#endif //BT_GIMPACT_BVH_CONCAVE_COLLISION_ALGORITHM_H +#endif //BT_GIMPACT_BVH_CONCAVE_COLLISION_ALGORITHM_H diff --git a/src/BulletCollision/Gimpact/btGImpactMassUtil.h b/src/BulletCollision/Gimpact/btGImpactMassUtil.h index 2543aefcf..1cde46ed8 100644 --- a/src/BulletCollision/Gimpact/btGImpactMassUtil.h +++ b/src/BulletCollision/Gimpact/btGImpactMassUtil.h @@ -21,40 +21,36 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef GIMPACT_MASS_UTIL_H #define GIMPACT_MASS_UTIL_H #include "LinearMath/btTransform.h" - - SIMD_FORCE_INLINE btVector3 gim_inertia_add_transformed( - const btVector3 & source_inertia, const btVector3 & added_inertia, const btTransform & transform) + const btVector3& source_inertia, const btVector3& added_inertia, const btTransform& transform) { - btMatrix3x3 rotatedTensor = transform.getBasis().scaled(added_inertia) * transform.getBasis().transpose(); + btMatrix3x3 rotatedTensor = transform.getBasis().scaled(added_inertia) * transform.getBasis().transpose(); btScalar x2 = transform.getOrigin()[0]; - x2*= x2; + x2 *= x2; btScalar y2 = transform.getOrigin()[1]; - y2*= y2; + y2 *= y2; btScalar z2 = transform.getOrigin()[2]; - z2*= z2; + z2 *= z2; - btScalar ix = rotatedTensor[0][0]*(y2+z2); - btScalar iy = rotatedTensor[1][1]*(x2+z2); - btScalar iz = rotatedTensor[2][2]*(x2+y2); + btScalar ix = rotatedTensor[0][0] * (y2 + z2); + btScalar iy = rotatedTensor[1][1] * (x2 + z2); + btScalar iz = rotatedTensor[2][2] * (x2 + y2); - return btVector3(source_inertia[0]+ix,source_inertia[1]+iy,source_inertia[2] + iz); + return btVector3(source_inertia[0] + ix, source_inertia[1] + iy, source_inertia[2] + iz); } -SIMD_FORCE_INLINE btVector3 gim_get_point_inertia(const btVector3 & point, btScalar mass) +SIMD_FORCE_INLINE btVector3 gim_get_point_inertia(const btVector3& point, btScalar mass) { - btScalar x2 = point[0]*point[0]; - btScalar y2 = point[1]*point[1]; - btScalar z2 = point[2]*point[2]; - return btVector3(mass*(y2+z2),mass*(x2+z2),mass*(x2+y2)); + btScalar x2 = point[0] * point[0]; + btScalar y2 = point[1] * point[1]; + btScalar z2 = point[2] * point[2]; + return btVector3(mass * (y2 + z2), mass * (x2 + z2), mass * (x2 + y2)); } - -#endif //GIMPACT_MESH_SHAPE_H +#endif //GIMPACT_MESH_SHAPE_H diff --git a/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp b/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp index 4528758c3..b81fc9704 100644 --- a/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp +++ b/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.cpp @@ -27,11 +27,9 @@ subject to the following restrictions: #ifdef TRI_COLLISION_PROFILING btClock g_q_tree_clock; - float g_q_accum_tree_collision_time = 0; int g_q_count_traversing = 0; - void bt_begin_gim02_q_tree_time() { g_q_tree_clock.reset(); @@ -43,11 +41,10 @@ void bt_end_gim02_q_tree_time() g_q_count_traversing++; } - //! Gets the average time in miliseconds of tree collisions float btGImpactQuantizedBvh::getAverageTreeCollisionTime() { - if(g_q_count_traversing == 0) return 0; + if (g_q_count_traversing == 0) return 0; float avgtime = g_q_accum_tree_collision_time; avgtime /= (float)g_q_count_traversing; @@ -56,99 +53,92 @@ float btGImpactQuantizedBvh::getAverageTreeCollisionTime() g_q_count_traversing = 0; return avgtime; -// float avgtime = g_q_count_traversing; -// g_q_count_traversing = 0; -// return avgtime; - + // float avgtime = g_q_count_traversing; + // g_q_count_traversing = 0; + // return avgtime; } -#endif //TRI_COLLISION_PROFILING +#endif //TRI_COLLISION_PROFILING /////////////////////// btQuantizedBvhTree ///////////////////////////////// void btQuantizedBvhTree::calc_quantization( - GIM_BVH_DATA_ARRAY & primitive_boxes, btScalar boundMargin) + GIM_BVH_DATA_ARRAY& primitive_boxes, btScalar boundMargin) { //calc globa box btAABB global_bound; global_bound.invalidate(); - for (int i=0;i splitValue) { //swap - primitive_boxes.swap(i,splitIndex); + primitive_boxes.swap(i, splitIndex); //swapLeafNodes(i,splitIndex); splitIndex++; } @@ -163,32 +153,30 @@ int btQuantizedBvhTree::_sort_and_calc_splitting_index( //bool unbalanced2 = true; //this should be safe too: - int rangeBalancedIndices = numIndices/3; - bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices))); + int rangeBalancedIndices = numIndices / 3; + bool unbalanced = ((splitIndex <= (startIndex + rangeBalancedIndices)) || (splitIndex >= (endIndex - 1 - rangeBalancedIndices))); if (unbalanced) { - splitIndex = startIndex+ (numIndices>>1); + splitIndex = startIndex + (numIndices >> 1); } - btAssert(!((splitIndex==startIndex) || (splitIndex == (endIndex)))); + btAssert(!((splitIndex == startIndex) || (splitIndex == (endIndex)))); return splitIndex; - } - -void btQuantizedBvhTree::_build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex) +void btQuantizedBvhTree::_build_sub_tree(GIM_BVH_DATA_ARRAY& primitive_boxes, int startIndex, int endIndex) { int curIndex = m_num_nodes; m_num_nodes++; - btAssert((endIndex-startIndex)>0); + btAssert((endIndex - startIndex) > 0); - if ((endIndex-startIndex)==1) + if ((endIndex - startIndex) == 1) { - //We have a leaf node - setNodeBound(curIndex,primitive_boxes[startIndex].m_bound); + //We have a leaf node + setNodeBound(curIndex, primitive_boxes[startIndex].m_bound); m_node_array[curIndex].setDataIndex(primitive_boxes[startIndex].m_data); return; @@ -196,48 +184,43 @@ void btQuantizedBvhTree::_build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, i //calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'. //split axis - int splitIndex = _calc_splitting_axis(primitive_boxes,startIndex,endIndex); + int splitIndex = _calc_splitting_axis(primitive_boxes, startIndex, endIndex); splitIndex = _sort_and_calc_splitting_index( - primitive_boxes,startIndex,endIndex, - splitIndex//split axis - ); - + primitive_boxes, startIndex, endIndex, + splitIndex //split axis + ); //calc this node bounding box btAABB node_bound; node_bound.invalidate(); - for (int i=startIndex;iget_primitive_box(getNodeData(nodecount),leafbox); - setNodeBound(nodecount,leafbox); + m_primitive_manager->get_primitive_box(getNodeData(nodecount), leafbox); + setNodeBound(nodecount, leafbox); } else { @@ -265,20 +248,20 @@ void btGImpactQuantizedBvh::refit() btAABB temp_box; int child_node = getLeftNode(nodecount); - if(child_node) + if (child_node) { - getNodeBound(child_node,temp_box); + getNodeBound(child_node, temp_box); bound.merge(temp_box); } child_node = getRightNode(nodecount); - if(child_node) + if (child_node) { - getNodeBound(child_node,temp_box); + getNodeBound(child_node, temp_box); bound.merge(temp_box); } - setNodeBound(nodecount,bound); + setNodeBound(nodecount, bound); } } } @@ -290,17 +273,17 @@ void btGImpactQuantizedBvh::buildSet() GIM_BVH_DATA_ARRAY primitive_boxes; primitive_boxes.resize(m_primitive_manager->get_primitive_count()); - for (int i = 0;iget_primitive_box(i,primitive_boxes[i].m_bound); - primitive_boxes[i].m_data = i; + m_primitive_manager->get_primitive_box(i, primitive_boxes[i].m_bound); + primitive_boxes[i].m_data = i; } m_box_tree.build_tree(primitive_boxes); } //! returns the indices of the primitives in the m_primitive_manager -bool btGImpactQuantizedBvh::boxQuery(const btAABB & box, btAlignedObjectArray & collided_results) const +bool btGImpactQuantizedBvh::boxQuery(const btAABB& box, btAlignedObjectArray& collided_results) const { int curIndex = 0; int numNodes = getNodeCount(); @@ -310,16 +293,14 @@ bool btGImpactQuantizedBvh::boxQuery(const btAABB & box, btAlignedObjectArray0) return true; + if (collided_results.size() > 0) return true; return false; } - - //! returns the indices of the primitives in the m_primitive_manager bool btGImpactQuantizedBvh::rayQuery( - const btVector3 & ray_dir,const btVector3 & ray_origin , - btAlignedObjectArray & collided_results) const + const btVector3& ray_dir, const btVector3& ray_origin, + btAlignedObjectArray& collided_results) const { int curIndex = 0; int numNodes = getNodeCount(); @@ -355,16 +334,16 @@ bool btGImpactQuantizedBvh::rayQuery( while (curIndex < numNodes) { btAABB bound; - getNodeBound(curIndex,bound); + getNodeBound(curIndex, bound); //catch bugs in tree data - bool aabbOverlap = bound.collide_ray(ray_origin,ray_dir); + bool aabbOverlap = bound.collide_ray(ray_origin, ray_dir); bool isleafnode = isLeafNode(curIndex); if (isleafnode && aabbOverlap) { - collided_results.push_back(getNodeData( curIndex)); + collided_results.push_back(getNodeData(curIndex)); } if (aabbOverlap || isleafnode) @@ -375,154 +354,133 @@ bool btGImpactQuantizedBvh::rayQuery( else { //skip node - curIndex+= getEscapeNodeIndex(curIndex); + curIndex += getEscapeNodeIndex(curIndex); } } - if(collided_results.size()>0) return true; + if (collided_results.size() > 0) return true; return false; } - SIMD_FORCE_INLINE bool _quantized_node_collision( - const btGImpactQuantizedBvh * boxset0, const btGImpactQuantizedBvh * boxset1, - const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0, - int node0 ,int node1, bool complete_primitive_tests) + const btGImpactQuantizedBvh* boxset0, const btGImpactQuantizedBvh* boxset1, + const BT_BOX_BOX_TRANSFORM_CACHE& trans_cache_1to0, + int node0, int node1, bool complete_primitive_tests) { btAABB box0; - boxset0->getNodeBound(node0,box0); + boxset0->getNodeBound(node0, box0); btAABB box1; - boxset1->getNodeBound(node1,box1); - - return box0.overlapping_trans_cache(box1,trans_cache_1to0,complete_primitive_tests ); -// box1.appy_transform_trans_cache(trans_cache_1to0); -// return box0.has_collision(box1); + boxset1->getNodeBound(node1, box1); + return box0.overlapping_trans_cache(box1, trans_cache_1to0, complete_primitive_tests); + // box1.appy_transform_trans_cache(trans_cache_1to0); + // return box0.has_collision(box1); } - //stackless recursive collision routine static void _find_quantized_collision_pairs_recursive( - const btGImpactQuantizedBvh * boxset0, const btGImpactQuantizedBvh * boxset1, - btPairSet * collision_pairs, - const BT_BOX_BOX_TRANSFORM_CACHE & trans_cache_1to0, + const btGImpactQuantizedBvh* boxset0, const btGImpactQuantizedBvh* boxset1, + btPairSet* collision_pairs, + const BT_BOX_BOX_TRANSFORM_CACHE& trans_cache_1to0, int node0, int node1, bool complete_primitive_tests) { + if (_quantized_node_collision( + boxset0, boxset1, trans_cache_1to0, + node0, node1, complete_primitive_tests) == false) return; //avoid colliding internal nodes - - - if( _quantized_node_collision( - boxset0,boxset1,trans_cache_1to0, - node0,node1,complete_primitive_tests) ==false) return;//avoid colliding internal nodes - - if(boxset0->isLeafNode(node0)) + if (boxset0->isLeafNode(node0)) { - if(boxset1->isLeafNode(node1)) + if (boxset1->isLeafNode(node1)) { // collision result collision_pairs->push_pair( - boxset0->getNodeData(node0),boxset1->getNodeData(node1)); + boxset0->getNodeData(node0), boxset1->getNodeData(node1)); return; } else { - //collide left recursive _find_quantized_collision_pairs_recursive( - boxset0,boxset1, - collision_pairs,trans_cache_1to0, - node0,boxset1->getLeftNode(node1),false); + boxset0, boxset1, + collision_pairs, trans_cache_1to0, + node0, boxset1->getLeftNode(node1), false); //collide right recursive _find_quantized_collision_pairs_recursive( - boxset0,boxset1, - collision_pairs,trans_cache_1to0, - node0,boxset1->getRightNode(node1),false); - - + boxset0, boxset1, + collision_pairs, trans_cache_1to0, + node0, boxset1->getRightNode(node1), false); } } else { - if(boxset1->isLeafNode(node1)) + if (boxset1->isLeafNode(node1)) { - //collide left recursive _find_quantized_collision_pairs_recursive( - boxset0,boxset1, - collision_pairs,trans_cache_1to0, - boxset0->getLeftNode(node0),node1,false); - + boxset0, boxset1, + collision_pairs, trans_cache_1to0, + boxset0->getLeftNode(node0), node1, false); //collide right recursive _find_quantized_collision_pairs_recursive( - boxset0,boxset1, - collision_pairs,trans_cache_1to0, - boxset0->getRightNode(node0),node1,false); - - + boxset0, boxset1, + collision_pairs, trans_cache_1to0, + boxset0->getRightNode(node0), node1, false); } else { //collide left0 left1 - - _find_quantized_collision_pairs_recursive( - boxset0,boxset1, - collision_pairs,trans_cache_1to0, - boxset0->getLeftNode(node0),boxset1->getLeftNode(node1),false); + boxset0, boxset1, + collision_pairs, trans_cache_1to0, + boxset0->getLeftNode(node0), boxset1->getLeftNode(node1), false); //collide left0 right1 _find_quantized_collision_pairs_recursive( - boxset0,boxset1, - collision_pairs,trans_cache_1to0, - boxset0->getLeftNode(node0),boxset1->getRightNode(node1),false); - + boxset0, boxset1, + collision_pairs, trans_cache_1to0, + boxset0->getLeftNode(node0), boxset1->getRightNode(node1), false); //collide right0 left1 _find_quantized_collision_pairs_recursive( - boxset0,boxset1, - collision_pairs,trans_cache_1to0, - boxset0->getRightNode(node0),boxset1->getLeftNode(node1),false); + boxset0, boxset1, + collision_pairs, trans_cache_1to0, + boxset0->getRightNode(node0), boxset1->getLeftNode(node1), false); //collide right0 right1 _find_quantized_collision_pairs_recursive( - boxset0,boxset1, - collision_pairs,trans_cache_1to0, - boxset0->getRightNode(node0),boxset1->getRightNode(node1),false); + boxset0, boxset1, + collision_pairs, trans_cache_1to0, + boxset0->getRightNode(node0), boxset1->getRightNode(node1), false); - }// else if node1 is not a leaf - }// else if node0 is not a leaf + } // else if node1 is not a leaf + } // else if node0 is not a leaf } - -void btGImpactQuantizedBvh::find_collision(const btGImpactQuantizedBvh * boxset0, const btTransform & trans0, - const btGImpactQuantizedBvh * boxset1, const btTransform & trans1, - btPairSet & collision_pairs) +void btGImpactQuantizedBvh::find_collision(const btGImpactQuantizedBvh* boxset0, const btTransform& trans0, + const btGImpactQuantizedBvh* boxset1, const btTransform& trans1, + btPairSet& collision_pairs) { - - if(boxset0->getNodeCount()==0 || boxset1->getNodeCount()==0 ) return; + if (boxset0->getNodeCount() == 0 || boxset1->getNodeCount() == 0) return; BT_BOX_BOX_TRANSFORM_CACHE trans_cache_1to0; - trans_cache_1to0.calc_from_homogenic(trans0,trans1); + trans_cache_1to0.calc_from_homogenic(trans0, trans1); #ifdef TRI_COLLISION_PROFILING bt_begin_gim02_q_tree_time(); -#endif //TRI_COLLISION_PROFILING +#endif //TRI_COLLISION_PROFILING _find_quantized_collision_pairs_recursive( - boxset0,boxset1, - &collision_pairs,trans_cache_1to0,0,0,true); + boxset0, boxset1, + &collision_pairs, trans_cache_1to0, 0, 0, true); #ifdef TRI_COLLISION_PROFILING bt_end_gim02_q_tree_time(); -#endif //TRI_COLLISION_PROFILING - +#endif //TRI_COLLISION_PROFILING } - - diff --git a/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h b/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h index 42e5520fc..b231c1e83 100644 --- a/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h +++ b/src/BulletCollision/Gimpact/btGImpactQuantizedBvh.h @@ -28,13 +28,10 @@ subject to the following restrictions: #include "btQuantization.h" #include "btGImpactQuantizedBvhStructs.h" -class GIM_QUANTIZED_BVH_NODE_ARRAY:public btAlignedObjectArray +class GIM_QUANTIZED_BVH_NODE_ARRAY : public btAlignedObjectArray { }; - - - //! Basic Box tree structure class btQuantizedBvhTree { @@ -43,16 +40,18 @@ protected: GIM_QUANTIZED_BVH_NODE_ARRAY m_node_array; btAABB m_global_bound; btVector3 m_bvhQuantization; + protected: - void calc_quantization(GIM_BVH_DATA_ARRAY & primitive_boxes, btScalar boundMargin = btScalar(1.0) ); + void calc_quantization(GIM_BVH_DATA_ARRAY& primitive_boxes, btScalar boundMargin = btScalar(1.0)); int _sort_and_calc_splitting_index( - GIM_BVH_DATA_ARRAY & primitive_boxes, - int startIndex, int endIndex, int splitAxis); + GIM_BVH_DATA_ARRAY& primitive_boxes, + int startIndex, int endIndex, int splitAxis); - int _calc_splitting_axis(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex); + int _calc_splitting_axis(GIM_BVH_DATA_ARRAY& primitive_boxes, int startIndex, int endIndex); + + void _build_sub_tree(GIM_BVH_DATA_ARRAY& primitive_boxes, int startIndex, int endIndex); - void _build_sub_tree(GIM_BVH_DATA_ARRAY & primitive_boxes, int startIndex, int endIndex); public: btQuantizedBvhTree() { @@ -61,20 +60,19 @@ public: //! prototype functions for box tree management //!@{ - void build_tree(GIM_BVH_DATA_ARRAY & primitive_boxes); + void build_tree(GIM_BVH_DATA_ARRAY& primitive_boxes); SIMD_FORCE_INLINE void quantizePoint( - unsigned short * quantizedpoint, const btVector3 & point) const + unsigned short* quantizedpoint, const btVector3& point) const { - bt_quantize_clamp(quantizedpoint,point,m_global_bound.m_min,m_global_bound.m_max,m_bvhQuantization); + bt_quantize_clamp(quantizedpoint, point, m_global_bound.m_min, m_global_bound.m_max, m_bvhQuantization); } - SIMD_FORCE_INLINE bool testQuantizedBoxOverlapp( int node_index, - unsigned short * quantizedMin,unsigned short * quantizedMax) const + unsigned short* quantizedMin, unsigned short* quantizedMax) const { - return m_node_array[node_index].testQuantizedBoxOverlapp(quantizedMin,quantizedMax); + return m_node_array[node_index].testQuantizedBoxOverlapp(quantizedMin, quantizedMax); } SIMD_FORCE_INLINE void clearNodes() @@ -100,41 +98,41 @@ public: return m_node_array[nodeindex].getDataIndex(); } - SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const + SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB& bound) const { bound.m_min = bt_unquantize( m_node_array[nodeindex].m_quantizedAabbMin, - m_global_bound.m_min,m_bvhQuantization); + m_global_bound.m_min, m_bvhQuantization); bound.m_max = bt_unquantize( m_node_array[nodeindex].m_quantizedAabbMax, - m_global_bound.m_min,m_bvhQuantization); + m_global_bound.m_min, m_bvhQuantization); } - SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound) + SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB& bound) { - bt_quantize_clamp( m_node_array[nodeindex].m_quantizedAabbMin, - bound.m_min, - m_global_bound.m_min, - m_global_bound.m_max, - m_bvhQuantization); + bt_quantize_clamp(m_node_array[nodeindex].m_quantizedAabbMin, + bound.m_min, + m_global_bound.m_min, + m_global_bound.m_max, + m_bvhQuantization); - bt_quantize_clamp( m_node_array[nodeindex].m_quantizedAabbMax, - bound.m_max, - m_global_bound.m_min, - m_global_bound.m_max, - m_bvhQuantization); + bt_quantize_clamp(m_node_array[nodeindex].m_quantizedAabbMax, + bound.m_max, + m_global_bound.m_min, + m_global_bound.m_max, + m_bvhQuantization); } SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const { - return nodeindex+1; + return nodeindex + 1; } SIMD_FORCE_INLINE int getRightNode(int nodeindex) const { - if(m_node_array[nodeindex+1].isLeafNode()) return nodeindex+2; - return nodeindex+1 + m_node_array[nodeindex+1].getEscapeIndex(); + if (m_node_array[nodeindex + 1].isLeafNode()) return nodeindex + 2; + return nodeindex + 1 + m_node_array[nodeindex + 1].getEscapeIndex(); } SIMD_FORCE_INLINE int getEscapeNodeIndex(int nodeindex) const @@ -142,7 +140,7 @@ public: return m_node_array[nodeindex].getEscapeIndex(); } - SIMD_FORCE_INLINE const BT_QUANTIZED_BVH_NODE * get_node_pointer(int index = 0) const + SIMD_FORCE_INLINE const BT_QUANTIZED_BVH_NODE* get_node_pointer(int index = 0) const { return &m_node_array[index]; } @@ -150,8 +148,6 @@ public: //!@} }; - - //! Structure for containing Boxes /*! This class offers an structure for managing a box tree of primitives. @@ -161,13 +157,13 @@ class btGImpactQuantizedBvh { protected: btQuantizedBvhTree m_box_tree; - btPrimitiveManagerBase * m_primitive_manager; + btPrimitiveManagerBase* m_primitive_manager; protected: //stackless refit void refit(); -public: +public: //! this constructor doesn't build the tree. you must call buildSet btGImpactQuantizedBvh() { @@ -175,31 +171,30 @@ public: } //! this constructor doesn't build the tree. you must call buildSet - btGImpactQuantizedBvh(btPrimitiveManagerBase * primitive_manager) + btGImpactQuantizedBvh(btPrimitiveManagerBase* primitive_manager) { m_primitive_manager = primitive_manager; } - SIMD_FORCE_INLINE btAABB getGlobalBox() const + SIMD_FORCE_INLINE btAABB getGlobalBox() const { btAABB totalbox; getNodeBound(0, totalbox); return totalbox; } - SIMD_FORCE_INLINE void setPrimitiveManager(btPrimitiveManagerBase * primitive_manager) + SIMD_FORCE_INLINE void setPrimitiveManager(btPrimitiveManagerBase* primitive_manager) { m_primitive_manager = primitive_manager; } - SIMD_FORCE_INLINE btPrimitiveManagerBase * getPrimitiveManager() const + SIMD_FORCE_INLINE btPrimitiveManagerBase* getPrimitiveManager() const { return m_primitive_manager; } - -//! node manager prototype functions -///@{ + //! node manager prototype functions + ///@{ //! this attemps to refit the box set. SIMD_FORCE_INLINE void update() @@ -211,21 +206,21 @@ public: void buildSet(); //! returns the indices of the primitives in the m_primitive_manager - bool boxQuery(const btAABB & box, btAlignedObjectArray & collided_results) const; + bool boxQuery(const btAABB& box, btAlignedObjectArray& collided_results) const; //! returns the indices of the primitives in the m_primitive_manager - SIMD_FORCE_INLINE bool boxQueryTrans(const btAABB & box, - const btTransform & transform, btAlignedObjectArray & collided_results) const + SIMD_FORCE_INLINE bool boxQueryTrans(const btAABB& box, + const btTransform& transform, btAlignedObjectArray& collided_results) const { - btAABB transbox=box; + btAABB transbox = box; transbox.appy_transform(transform); - return boxQuery(transbox,collided_results); + return boxQuery(transbox, collided_results); } //! returns the indices of the primitives in the m_primitive_manager bool rayQuery( - const btVector3 & ray_dir,const btVector3 & ray_origin , - btAlignedObjectArray & collided_results) const; + const btVector3& ray_dir, const btVector3& ray_origin, + btAlignedObjectArray& collided_results) const; //! tells if this set has hierarcht SIMD_FORCE_INLINE bool hasHierarchy() const @@ -234,7 +229,7 @@ public: } //! tells if this set is a trimesh - SIMD_FORCE_INLINE bool isTrimesh() const + SIMD_FORCE_INLINE bool isTrimesh() const { return m_primitive_manager->is_trimesh(); } @@ -256,17 +251,16 @@ public: return m_box_tree.getNodeData(nodeindex); } - SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB & bound) const + SIMD_FORCE_INLINE void getNodeBound(int nodeindex, btAABB& bound) const { m_box_tree.getNodeBound(nodeindex, bound); } - SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB & bound) + SIMD_FORCE_INLINE void setNodeBound(int nodeindex, const btAABB& bound) { m_box_tree.setNodeBound(nodeindex, bound); } - SIMD_FORCE_INLINE int getLeftNode(int nodeindex) const { return m_box_tree.getLeftNode(nodeindex); @@ -282,24 +276,23 @@ public: return m_box_tree.getEscapeNodeIndex(nodeindex); } - SIMD_FORCE_INLINE void getNodeTriangle(int nodeindex,btPrimitiveTriangle & triangle) const + SIMD_FORCE_INLINE void getNodeTriangle(int nodeindex, btPrimitiveTriangle& triangle) const { - m_primitive_manager->get_primitive_triangle(getNodeData(nodeindex),triangle); + m_primitive_manager->get_primitive_triangle(getNodeData(nodeindex), triangle); } - - SIMD_FORCE_INLINE const BT_QUANTIZED_BVH_NODE * get_node_pointer(int index = 0) const + SIMD_FORCE_INLINE const BT_QUANTIZED_BVH_NODE* get_node_pointer(int index = 0) const { return m_box_tree.get_node_pointer(index); } #ifdef TRI_COLLISION_PROFILING static float getAverageTreeCollisionTime(); -#endif //TRI_COLLISION_PROFILING +#endif //TRI_COLLISION_PROFILING - static void find_collision(const btGImpactQuantizedBvh * boxset1, const btTransform & trans1, - const btGImpactQuantizedBvh * boxset2, const btTransform & trans2, - btPairSet & collision_pairs); + static void find_collision(const btGImpactQuantizedBvh* boxset1, const btTransform& trans1, + const btGImpactQuantizedBvh* boxset2, const btTransform& trans2, + btPairSet& collision_pairs); }; -#endif // GIM_BOXPRUNING_H_INCLUDED +#endif // GIM_BOXPRUNING_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/btGImpactQuantizedBvhStructs.h b/src/BulletCollision/Gimpact/btGImpactQuantizedBvhStructs.h index 7dd5a1b9d..bd50cb5b8 100644 --- a/src/BulletCollision/Gimpact/btGImpactQuantizedBvhStructs.h +++ b/src/BulletCollision/Gimpact/btGImpactQuantizedBvhStructs.h @@ -29,13 +29,14 @@ subject to the following restrictions: ///btQuantizedBvhNode is a compressed aabb node, 16 bytes. ///Node can be used for leafnode or internal node. Leafnodes can point to 32-bit triangle index (non-negative range). -ATTRIBUTE_ALIGNED16 (struct) BT_QUANTIZED_BVH_NODE +ATTRIBUTE_ALIGNED16(struct) +BT_QUANTIZED_BVH_NODE { //12 bytes - unsigned short int m_quantizedAabbMin[3]; - unsigned short int m_quantizedAabbMax[3]; + unsigned short int m_quantizedAabbMin[3]; + unsigned short int m_quantizedAabbMax[3]; //4 bytes - int m_escapeIndexOrDataIndex; + int m_escapeIndexOrDataIndex; BT_QUANTIZED_BVH_NODE() { @@ -45,7 +46,7 @@ ATTRIBUTE_ALIGNED16 (struct) BT_QUANTIZED_BVH_NODE SIMD_FORCE_INLINE bool isLeafNode() const { //skipindex is negative (internal node), triangleindex >=0 (leafnode) - return (m_escapeIndexOrDataIndex>=0); + return (m_escapeIndexOrDataIndex >= 0); } SIMD_FORCE_INLINE int getEscapeIndex() const @@ -72,20 +73,19 @@ ATTRIBUTE_ALIGNED16 (struct) BT_QUANTIZED_BVH_NODE } SIMD_FORCE_INLINE bool testQuantizedBoxOverlapp( - unsigned short * quantizedMin,unsigned short * quantizedMax) const + unsigned short* quantizedMin, unsigned short* quantizedMax) const { - if(m_quantizedAabbMin[0] > quantizedMax[0] || - m_quantizedAabbMax[0] < quantizedMin[0] || - m_quantizedAabbMin[1] > quantizedMax[1] || - m_quantizedAabbMax[1] < quantizedMin[1] || - m_quantizedAabbMin[2] > quantizedMax[2] || - m_quantizedAabbMax[2] < quantizedMin[2]) + if (m_quantizedAabbMin[0] > quantizedMax[0] || + m_quantizedAabbMax[0] < quantizedMin[0] || + m_quantizedAabbMin[1] > quantizedMax[1] || + m_quantizedAabbMax[1] < quantizedMin[1] || + m_quantizedAabbMin[2] > quantizedMax[2] || + m_quantizedAabbMax[2] < quantizedMin[2]) { return false; } return true; } - }; -#endif // GIM_QUANTIZED_SET_STRUCTS_H_INCLUDED +#endif // GIM_QUANTIZED_SET_STRUCTS_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/btGImpactShape.cpp b/src/BulletCollision/Gimpact/btGImpactShape.cpp index 30c85e3ff..34c229a3a 100644 --- a/src/BulletCollision/Gimpact/btGImpactShape.cpp +++ b/src/BulletCollision/Gimpact/btGImpactShape.cpp @@ -18,178 +18,169 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btGImpactShape.h" #include "btGImpactMassUtil.h" - -btGImpactMeshShapePart::btGImpactMeshShapePart( btStridingMeshInterface * meshInterface, int part ) +btGImpactMeshShapePart::btGImpactMeshShapePart(btStridingMeshInterface* meshInterface, int part) { - // moved from .h to .cpp because of conditional compilation - // (The setting of BT_THREADSAFE may differ between various cpp files, so it is best to - // avoid using it in h files) - m_primitive_manager.m_meshInterface = meshInterface; - m_primitive_manager.m_part = part; - m_box_set.setPrimitiveManager( &m_primitive_manager ); + // moved from .h to .cpp because of conditional compilation + // (The setting of BT_THREADSAFE may differ between various cpp files, so it is best to + // avoid using it in h files) + m_primitive_manager.m_meshInterface = meshInterface; + m_primitive_manager.m_part = part; + m_box_set.setPrimitiveManager(&m_primitive_manager); #if BT_THREADSAFE - // If threadsafe is requested, this object uses a different lock/unlock - // model with the btStridingMeshInterface -- lock once when the object is constructed - // and unlock once in the destructor. - // The other way of locking and unlocking for each collision check in the narrowphase - // is not threadsafe. Note these are not thread-locks, they are calls to the meshInterface's - // getLockedReadOnlyVertexIndexBase virtual function, which by default just returns a couple of - // pointers. In theory a client could override the lock function to do all sorts of - // things like reading data from GPU memory, or decompressing data on the fly, but such things - // do not seem all that likely or useful, given the performance cost. - m_primitive_manager.lock(); + // If threadsafe is requested, this object uses a different lock/unlock + // model with the btStridingMeshInterface -- lock once when the object is constructed + // and unlock once in the destructor. + // The other way of locking and unlocking for each collision check in the narrowphase + // is not threadsafe. Note these are not thread-locks, they are calls to the meshInterface's + // getLockedReadOnlyVertexIndexBase virtual function, which by default just returns a couple of + // pointers. In theory a client could override the lock function to do all sorts of + // things like reading data from GPU memory, or decompressing data on the fly, but such things + // do not seem all that likely or useful, given the performance cost. + m_primitive_manager.lock(); #endif } btGImpactMeshShapePart::~btGImpactMeshShapePart() { - // moved from .h to .cpp because of conditional compilation + // moved from .h to .cpp because of conditional compilation #if BT_THREADSAFE - m_primitive_manager.unlock(); + m_primitive_manager.unlock(); #endif } void btGImpactMeshShapePart::lockChildShapes() const { - // moved from .h to .cpp because of conditional compilation -#if ! BT_THREADSAFE - // called in the narrowphase -- not threadsafe! - void * dummy = (void*) ( m_box_set.getPrimitiveManager() ); - TrimeshPrimitiveManager * dummymanager = static_cast( dummy ); - dummymanager->lock(); + // moved from .h to .cpp because of conditional compilation +#if !BT_THREADSAFE + // called in the narrowphase -- not threadsafe! + void* dummy = (void*)(m_box_set.getPrimitiveManager()); + TrimeshPrimitiveManager* dummymanager = static_cast(dummy); + dummymanager->lock(); #endif } -void btGImpactMeshShapePart::unlockChildShapes() const +void btGImpactMeshShapePart::unlockChildShapes() const { - // moved from .h to .cpp because of conditional compilation -#if ! BT_THREADSAFE - // called in the narrowphase -- not threadsafe! - void * dummy = (void*) ( m_box_set.getPrimitiveManager() ); - TrimeshPrimitiveManager * dummymanager = static_cast( dummy ); - dummymanager->unlock(); + // moved from .h to .cpp because of conditional compilation +#if !BT_THREADSAFE + // called in the narrowphase -- not threadsafe! + void* dummy = (void*)(m_box_set.getPrimitiveManager()); + TrimeshPrimitiveManager* dummymanager = static_cast(dummy); + dummymanager->unlock(); #endif } - #define CALC_EXACT_INERTIA 1 - -void btGImpactCompoundShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +void btGImpactCompoundShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const { lockChildShapes(); #ifdef CALC_EXACT_INERTIA - inertia.setValue(0.f,0.f,0.f); + inertia.setValue(0.f, 0.f, 0.f); int i = this->getNumChildShapes(); - btScalar shapemass = mass/btScalar(i); + btScalar shapemass = mass / btScalar(i); - while(i--) + while (i--) { btVector3 temp_inertia; - m_childShapes[i]->calculateLocalInertia(shapemass,temp_inertia); - if(childrenHasTransform()) + m_childShapes[i]->calculateLocalInertia(shapemass, temp_inertia); + if (childrenHasTransform()) { - inertia = gim_inertia_add_transformed( inertia,temp_inertia,m_childTransforms[i]); + inertia = gim_inertia_add_transformed(inertia, temp_inertia, m_childTransforms[i]); } else { - inertia = gim_inertia_add_transformed( inertia,temp_inertia,btTransform::getIdentity()); + inertia = gim_inertia_add_transformed(inertia, temp_inertia, btTransform::getIdentity()); } - } #else // Calc box inertia - btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0]; - btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1]; - btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2]; - const btScalar x2 = lx*lx; - const btScalar y2 = ly*ly; - const btScalar z2 = lz*lz; + btScalar lx = m_localAABB.m_max[0] - m_localAABB.m_min[0]; + btScalar ly = m_localAABB.m_max[1] - m_localAABB.m_min[1]; + btScalar lz = m_localAABB.m_max[2] - m_localAABB.m_min[2]; + const btScalar x2 = lx * lx; + const btScalar y2 = ly * ly; + const btScalar z2 = lz * lz; const btScalar scaledmass = mass * btScalar(0.08333333); - inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2)); + inertia = scaledmass * (btVector3(y2 + z2, x2 + z2, x2 + y2)); #endif unlockChildShapes(); } - - -void btGImpactMeshShapePart::calculateLocalInertia(btScalar mass,btVector3& inertia) const +void btGImpactMeshShapePart::calculateLocalInertia(btScalar mass, btVector3& inertia) const { lockChildShapes(); - #ifdef CALC_EXACT_INERTIA - inertia.setValue(0.f,0.f,0.f); + inertia.setValue(0.f, 0.f, 0.f); int i = this->getVertexCount(); - btScalar pointmass = mass/btScalar(i); + btScalar pointmass = mass / btScalar(i); - while(i--) + while (i--) { btVector3 pointintertia; - this->getVertex(i,pointintertia); - pointintertia = gim_get_point_inertia(pointintertia,pointmass); - inertia+=pointintertia; + this->getVertex(i, pointintertia); + pointintertia = gim_get_point_inertia(pointintertia, pointmass); + inertia += pointintertia; } #else // Calc box inertia - btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0]; - btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1]; - btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2]; - const btScalar x2 = lx*lx; - const btScalar y2 = ly*ly; - const btScalar z2 = lz*lz; + btScalar lx = m_localAABB.m_max[0] - m_localAABB.m_min[0]; + btScalar ly = m_localAABB.m_max[1] - m_localAABB.m_min[1]; + btScalar lz = m_localAABB.m_max[2] - m_localAABB.m_min[2]; + const btScalar x2 = lx * lx; + const btScalar y2 = ly * ly; + const btScalar z2 = lz * lz; const btScalar scaledmass = mass * btScalar(0.08333333); - inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2)); + inertia = scaledmass * (btVector3(y2 + z2, x2 + z2, x2 + y2)); #endif unlockChildShapes(); } -void btGImpactMeshShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const +void btGImpactMeshShape::calculateLocalInertia(btScalar mass, btVector3& inertia) const { - #ifdef CALC_EXACT_INERTIA - inertia.setValue(0.f,0.f,0.f); + inertia.setValue(0.f, 0.f, 0.f); int i = this->getMeshPartCount(); - btScalar partmass = mass/btScalar(i); + btScalar partmass = mass / btScalar(i); - while(i--) + while (i--) { btVector3 partinertia; - getMeshPart(i)->calculateLocalInertia(partmass,partinertia); - inertia+=partinertia; + getMeshPart(i)->calculateLocalInertia(partmass, partinertia); + inertia += partinertia; } #else // Calc box inertia - btScalar lx= m_localAABB.m_max[0] - m_localAABB.m_min[0]; - btScalar ly= m_localAABB.m_max[1] - m_localAABB.m_min[1]; - btScalar lz= m_localAABB.m_max[2] - m_localAABB.m_min[2]; - const btScalar x2 = lx*lx; - const btScalar y2 = ly*ly; - const btScalar z2 = lz*lz; + btScalar lx = m_localAABB.m_max[0] - m_localAABB.m_min[0]; + btScalar ly = m_localAABB.m_max[1] - m_localAABB.m_min[1]; + btScalar lz = m_localAABB.m_max[2] - m_localAABB.m_min[2]; + const btScalar x2 = lx * lx; + const btScalar y2 = ly * ly; + const btScalar z2 = lz * lz; const btScalar scaledmass = mass * btScalar(0.08333333); - inertia = scaledmass * (btVector3(y2+z2,x2+z2,x2+y2)); + inertia = scaledmass * (btVector3(y2 + z2, x2 + z2, x2 + y2)); #endif } @@ -198,7 +189,7 @@ void btGImpactMeshShape::rayTest(const btVector3& rayFrom, const btVector3& rayT { } -void btGImpactMeshShapePart::processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom, const btVector3& rayTo) const +void btGImpactMeshShapePart::processAllTrianglesRay(btTriangleCallback* callback, const btVector3& rayFrom, const btVector3& rayTo) const { lockChildShapes(); @@ -207,7 +198,7 @@ void btGImpactMeshShapePart::processAllTrianglesRay(btTriangleCallback* callback rayDir.normalize(); m_box_set.rayQuery(rayDir, rayFrom, collided); - if(collided.size()==0) + if (collided.size() == 0) { unlockChildShapes(); return; @@ -216,15 +207,15 @@ void btGImpactMeshShapePart::processAllTrianglesRay(btTriangleCallback* callback int part = (int)getPart(); btPrimitiveTriangle triangle; int i = collided.size(); - while(i--) + while (i--) { - getPrimitiveTriangle(collided[i],triangle); - callback->processTriangle(triangle.m_vertices,part,collided[i]); + getPrimitiveTriangle(collided[i], triangle); + callback->processTriangle(triangle.m_vertices, part, collided[i]); } unlockChildShapes(); } -void btGImpactMeshShapePart::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const +void btGImpactMeshShapePart::processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const { lockChildShapes(); btAABB box; @@ -232,9 +223,9 @@ void btGImpactMeshShapePart::processAllTriangles(btTriangleCallback* callback,co box.m_max = aabbMax; btAlignedObjectArray collided; - m_box_set.boxQuery(box,collided); + m_box_set.boxQuery(box, collided); - if(collided.size()==0) + if (collided.size() == 0) { unlockChildShapes(); return; @@ -243,40 +234,38 @@ void btGImpactMeshShapePart::processAllTriangles(btTriangleCallback* callback,co int part = (int)getPart(); btPrimitiveTriangle triangle; int i = collided.size(); - while(i--) + while (i--) { - this->getPrimitiveTriangle(collided[i],triangle); - callback->processTriangle(triangle.m_vertices,part,collided[i]); + this->getPrimitiveTriangle(collided[i], triangle); + callback->processTriangle(triangle.m_vertices, part, collided[i]); } unlockChildShapes(); - } -void btGImpactMeshShape::processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const +void btGImpactMeshShape::processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const { int i = m_mesh_parts.size(); - while(i--) + while (i--) { - m_mesh_parts[i]->processAllTriangles(callback,aabbMin,aabbMax); + m_mesh_parts[i]->processAllTriangles(callback, aabbMin, aabbMax); } } -void btGImpactMeshShape::processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom, const btVector3& rayTo) const +void btGImpactMeshShape::processAllTrianglesRay(btTriangleCallback* callback, const btVector3& rayFrom, const btVector3& rayTo) const { int i = m_mesh_parts.size(); - while(i--) + while (i--) { m_mesh_parts[i]->processAllTrianglesRay(callback, rayFrom, rayTo); } } - ///fills the dataBuffer and returns the struct name (and 0 on failure) -const char* btGImpactMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const +const char* btGImpactMeshShape::serialize(void* dataBuffer, btSerializer* serializer) const { - btGImpactMeshShapeData* trimeshData = (btGImpactMeshShapeData*) dataBuffer; + btGImpactMeshShapeData* trimeshData = (btGImpactMeshShapeData*)dataBuffer; - btCollisionShape::serialize(&trimeshData->m_collisionShapeData,serializer); + btCollisionShape::serialize(&trimeshData->m_collisionShapeData, serializer); m_meshInterface->serialize(&trimeshData->m_meshInterface, serializer); @@ -288,4 +277,3 @@ const char* btGImpactMeshShape::serialize(void* dataBuffer, btSerializer* serial return "btGImpactMeshShapeData"; } - diff --git a/src/BulletCollision/Gimpact/btGImpactShape.h b/src/BulletCollision/Gimpact/btGImpactShape.h index 9d7e40562..5b85e8704 100644 --- a/src/BulletCollision/Gimpact/btGImpactShape.h +++ b/src/BulletCollision/Gimpact/btGImpactShape.h @@ -21,7 +21,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef GIMPACT_SHAPE_H #define GIMPACT_SHAPE_H @@ -37,8 +36,7 @@ subject to the following restrictions: #include "LinearMath/btMatrix3x3.h" #include "LinearMath/btAlignedObjectArray.h" -#include "btGImpactQuantizedBvh.h" // box tree class - +#include "btGImpactQuantizedBvh.h" // box tree class //! declare Quantized trees, (you can change to float based trees) typedef btGImpactQuantizedBvh btGImpactBoxSet; @@ -50,10 +48,8 @@ enum eGIMPACT_SHAPE_TYPE CONST_GIMPACT_TRIMESH_SHAPE }; - - //! Helper class for tetrahedrons -class btTetrahedronShapeEx:public btBU_Simplex1to4 +class btTetrahedronShapeEx : public btBU_Simplex1to4 { public: btTetrahedronShapeEx() @@ -61,10 +57,9 @@ public: m_numVertices = 4; } - SIMD_FORCE_INLINE void setVertices( - const btVector3 & v0,const btVector3 & v1, - const btVector3 & v2,const btVector3 & v3) + const btVector3& v0, const btVector3& v1, + const btVector3& v2, const btVector3& v3) { m_vertices[0] = v0; m_vertices[1] = v1; @@ -74,45 +69,42 @@ public: } }; - //! Base class for gimpact shapes class btGImpactShapeInterface : public btConcaveShape { protected: - btAABB m_localAABB; - bool m_needs_update; - btVector3 localScaling; - btGImpactBoxSet m_box_set;// optionally boxset + btAABB m_localAABB; + bool m_needs_update; + btVector3 localScaling; + btGImpactBoxSet m_box_set; // optionally boxset //! use this function for perfofm refit in bounding boxes - //! use this function for perfofm refit in bounding boxes - virtual void calcLocalAABB() - { + //! use this function for perfofm refit in bounding boxes + virtual void calcLocalAABB() + { lockChildShapes(); - if(m_box_set.getNodeCount() == 0) - { - m_box_set.buildSet(); - } - else - { - m_box_set.update(); - } - unlockChildShapes(); - - m_localAABB = m_box_set.getGlobalBox(); - } + if (m_box_set.getNodeCount() == 0) + { + m_box_set.buildSet(); + } + else + { + m_box_set.update(); + } + unlockChildShapes(); + m_localAABB = m_box_set.getGlobalBox(); + } public: btGImpactShapeInterface() { - m_shapeType=GIMPACT_SHAPE_PROXYTYPE; + m_shapeType = GIMPACT_SHAPE_PROXYTYPE; m_localAABB.invalidate(); m_needs_update = true; - localScaling.setValue(1.f,1.f,1.f); + localScaling.setValue(1.f, 1.f, 1.f); } - //! performs refit operation /*! Updates the entire Box set of this shape. @@ -120,47 +112,46 @@ public: will does nothing. \post if m_needs_update == true, then it calls calcLocalAABB(); */ - SIMD_FORCE_INLINE void updateBound() - { - if(!m_needs_update) return; - calcLocalAABB(); - m_needs_update = false; - } + SIMD_FORCE_INLINE void updateBound() + { + if (!m_needs_update) return; + calcLocalAABB(); + m_needs_update = false; + } - //! If the Bounding box is not updated, then this class attemps to calculate it. - /*! + //! If the Bounding box is not updated, then this class attemps to calculate it. + /*! \post Calls updateBound() for update the box set. */ - void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const - { - btAABB transformedbox = m_localAABB; - transformedbox.appy_transform(t); - aabbMin = transformedbox.m_min; - aabbMax = transformedbox.m_max; - } + void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const + { + btAABB transformedbox = m_localAABB; + transformedbox.appy_transform(t); + aabbMin = transformedbox.m_min; + aabbMax = transformedbox.m_max; + } - //! Tells to this object that is needed to refit the box set - virtual void postUpdate() - { - m_needs_update = true; - } + //! Tells to this object that is needed to refit the box set + virtual void postUpdate() + { + m_needs_update = true; + } //! Obtains the local box, which is the global calculated box of the total of subshapes - SIMD_FORCE_INLINE const btAABB & getLocalBox() + SIMD_FORCE_INLINE const btAABB& getLocalBox() { return m_localAABB; } + virtual int getShapeType() const + { + return GIMPACT_SHAPE_PROXYTYPE; + } - virtual int getShapeType() const - { - return GIMPACT_SHAPE_PROXYTYPE; - } - - /*! + /*! \post You must call updateBound() for update the box set. */ - virtual void setLocalScaling(const btVector3& scaling) + virtual void setLocalScaling(const btVector3& scaling) { localScaling = scaling; postUpdate(); @@ -171,46 +162,43 @@ public: return localScaling; } - virtual void setMargin(btScalar margin) - { - m_collisionMargin = margin; - int i = getNumChildShapes(); - while(i--) - { + { + m_collisionMargin = margin; + int i = getNumChildShapes(); + while (i--) + { btCollisionShape* child = getChildShape(i); child->setMargin(margin); - } + } m_needs_update = true; - } - + } //! Subshape member functions //!@{ //! Base method for determinig which kind of GIMPACT shape we get - virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const = 0 ; + virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const = 0; //! gets boxset - SIMD_FORCE_INLINE const btGImpactBoxSet * getBoxSet() const + SIMD_FORCE_INLINE const btGImpactBoxSet* getBoxSet() const { return &m_box_set; } //! Determines if this class has a hierarchy structure for sorting its primitives - SIMD_FORCE_INLINE bool hasBoxSet() const + SIMD_FORCE_INLINE bool hasBoxSet() const { - if(m_box_set.getNodeCount() == 0) return false; + if (m_box_set.getNodeCount() == 0) return false; return true; } //! Obtains the primitive manager - virtual const btPrimitiveManagerBase * getPrimitiveManager() const = 0; - + virtual const btPrimitiveManagerBase* getPrimitiveManager() const = 0; //! Gets the number of children - virtual int getNumChildShapes() const = 0; + virtual int getNumChildShapes() const = 0; //! if true, then its children must get transforms. virtual bool childrenHasTransform() const = 0; @@ -221,11 +209,9 @@ public: //! Determines if this shape has tetrahedrons virtual bool needsRetrieveTetrahedrons() const = 0; - virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const = 0; - - virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const = 0; - + virtual void getBulletTriangle(int prim_index, btTriangleShapeEx& triangle) const = 0; + virtual void getBulletTetrahedron(int prim_index, btTetrahedronShapeEx& tetrahedron) const = 0; //! call when reading child shapes virtual void lockChildShapes() const @@ -237,94 +223,91 @@ public: } //! if this trimesh - SIMD_FORCE_INLINE void getPrimitiveTriangle(int index,btPrimitiveTriangle & triangle) const + SIMD_FORCE_INLINE void getPrimitiveTriangle(int index, btPrimitiveTriangle& triangle) const { - getPrimitiveManager()->get_primitive_triangle(index,triangle); + getPrimitiveManager()->get_primitive_triangle(index, triangle); } - //! Retrieves the bound from a child - /*! + /*! */ - virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const - { - btAABB child_aabb; - getPrimitiveManager()->get_primitive_box(child_index,child_aabb); - child_aabb.appy_transform(t); - aabbMin = child_aabb.m_min; - aabbMax = child_aabb.m_max; - } + virtual void getChildAabb(int child_index, const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const + { + btAABB child_aabb; + getPrimitiveManager()->get_primitive_box(child_index, child_aabb); + child_aabb.appy_transform(t); + aabbMin = child_aabb.m_min; + aabbMax = child_aabb.m_max; + } //! Gets the children virtual btCollisionShape* getChildShape(int index) = 0; - //! Gets the child virtual const btCollisionShape* getChildShape(int index) const = 0; //! Gets the children transform - virtual btTransform getChildTransform(int index) const = 0; + virtual btTransform getChildTransform(int index) const = 0; //! Sets the children transform /*! \post You must call updateBound() for update the box set. */ - virtual void setChildTransform(int index, const btTransform & transform) = 0; + virtual void setChildTransform(int index, const btTransform& transform) = 0; //!@} - //! virtual method for ray collision - virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const + virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const { - (void) rayFrom; (void) rayTo; (void) resultCallback; + (void)rayFrom; + (void)rayTo; + (void)resultCallback; } //! Function for retrieve triangles. /*! It gives the triangles in local space */ - virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const + virtual void processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const { - (void) callback; (void) aabbMin; (void) aabbMax; + (void)callback; + (void)aabbMin; + (void)aabbMax; } //! Function for retrieve triangles. /*! It gives the triangles in local space */ - virtual void processAllTrianglesRay(btTriangleCallback* /*callback*/,const btVector3& /*rayFrom*/, const btVector3& /*rayTo*/) const + virtual void processAllTrianglesRay(btTriangleCallback* /*callback*/, const btVector3& /*rayFrom*/, const btVector3& /*rayTo*/) const { - } //!@} - }; - //! btGImpactCompoundShape allows to handle multiple btCollisionShape objects at once /*! This class only can manage Convex subshapes */ -class btGImpactCompoundShape : public btGImpactShapeInterface +class btGImpactCompoundShape : public btGImpactShapeInterface { public: //! compound primitive manager - class CompoundPrimitiveManager:public btPrimitiveManagerBase + class CompoundPrimitiveManager : public btPrimitiveManagerBase { public: virtual ~CompoundPrimitiveManager() {} - btGImpactCompoundShape * m_compoundShape; - + btGImpactCompoundShape* m_compoundShape; CompoundPrimitiveManager(const CompoundPrimitiveManager& compound) - : btPrimitiveManagerBase() + : btPrimitiveManagerBase() { m_compoundShape = compound.m_compoundShape; } - CompoundPrimitiveManager(btGImpactCompoundShape * compoundShape) + CompoundPrimitiveManager(btGImpactCompoundShape* compoundShape) { m_compoundShape = compoundShape; } @@ -341,13 +324,13 @@ public: virtual int get_primitive_count() const { - return (int )m_compoundShape->getNumChildShapes(); + return (int)m_compoundShape->getNumChildShapes(); } - virtual void get_primitive_box(int prim_index ,btAABB & primbox) const + virtual void get_primitive_box(int prim_index, btAABB& primbox) const { btTransform prim_trans; - if(m_compoundShape->childrenHasTransform()) + if (m_compoundShape->childrenHasTransform()) { prim_trans = m_compoundShape->getChildTransform(prim_index); } @@ -356,30 +339,26 @@ public: prim_trans.setIdentity(); } const btCollisionShape* shape = m_compoundShape->getChildShape(prim_index); - shape->getAabb(prim_trans,primbox.m_min,primbox.m_max); + shape->getAabb(prim_trans, primbox.m_min, primbox.m_max); } - virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const + virtual void get_primitive_triangle(int prim_index, btPrimitiveTriangle& triangle) const { btAssert(0); - (void) prim_index; (void) triangle; + (void)prim_index; + (void)triangle; } - }; - - protected: CompoundPrimitiveManager m_primitive_manager; - btAlignedObjectArray m_childTransforms; - btAlignedObjectArray m_childShapes; - + btAlignedObjectArray m_childTransforms; + btAlignedObjectArray m_childShapes; public: - btGImpactCompoundShape(bool children_has_transform = true) { - (void) children_has_transform; + (void)children_has_transform; m_primitive_manager.m_compoundShape = this; m_box_set.setPrimitiveManager(&m_primitive_manager); } @@ -388,36 +367,33 @@ public: { } - //! if true, then its children must get transforms. virtual bool childrenHasTransform() const { - if(m_childTransforms.size()==0) return false; + if (m_childTransforms.size() == 0) return false; return true; } - //! Obtains the primitive manager - virtual const btPrimitiveManagerBase * getPrimitiveManager() const + virtual const btPrimitiveManagerBase* getPrimitiveManager() const { return &m_primitive_manager; } //! Obtains the compopund primitive manager - SIMD_FORCE_INLINE CompoundPrimitiveManager * getCompoundPrimitiveManager() + SIMD_FORCE_INLINE CompoundPrimitiveManager* getCompoundPrimitiveManager() { return &m_primitive_manager; } //! Gets the number of children - virtual int getNumChildShapes() const + virtual int getNumChildShapes() const { return m_childShapes.size(); } - //! Use this method for adding children. Only Convex shapes are allowed. - void addChildShape(const btTransform& localTransform,btCollisionShape* shape) + void addChildShape(const btTransform& localTransform, btCollisionShape* shape) { btAssert(shape->isConvex()); m_childTransforms.push_back(localTransform); @@ -444,24 +420,22 @@ public: } //! Retrieves the bound from a child - /*! + /*! */ - virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const - { - - if(childrenHasTransform()) - { - m_childShapes[child_index]->getAabb(t*m_childTransforms[child_index],aabbMin,aabbMax); - } - else - { - m_childShapes[child_index]->getAabb(t,aabbMin,aabbMax); - } - } - + virtual void getChildAabb(int child_index, const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const + { + if (childrenHasTransform()) + { + m_childShapes[child_index]->getAabb(t * m_childTransforms[child_index], aabbMin, aabbMax); + } + else + { + m_childShapes[child_index]->getAabb(t, aabbMin, aabbMax); + } + } //! Gets the children transform - virtual btTransform getChildTransform(int index) const + virtual btTransform getChildTransform(int index) const { btAssert(m_childTransforms.size() == m_childShapes.size()); return m_childTransforms[index]; @@ -471,7 +445,7 @@ public: /*! \post You must call updateBound() for update the box set. */ - virtual void setChildTransform(int index, const btTransform & transform) + virtual void setChildTransform(int index, const btTransform& transform) { btAssert(m_childTransforms.size() == m_childShapes.size()); m_childTransforms[index] = transform; @@ -490,24 +464,24 @@ public: return false; } - - virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const + virtual void getBulletTriangle(int prim_index, btTriangleShapeEx& triangle) const { - (void) prim_index; (void) triangle; + (void)prim_index; + (void)triangle; btAssert(0); } - virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const + virtual void getBulletTetrahedron(int prim_index, btTetrahedronShapeEx& tetrahedron) const { - (void) prim_index; (void) tetrahedron; + (void)prim_index; + (void)tetrahedron; btAssert(0); } - //! Calculates the exact inertia tensor for this shape - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + virtual void calculateLocalInertia(btScalar mass, btVector3& inertia) const; - virtual const char* getName()const + virtual const char* getName() const { return "GImpactCompound"; } @@ -516,11 +490,8 @@ public: { return CONST_GIMPACT_COMPOUND_SHAPE; } - }; - - //! This class manages a sub part of a mesh supplied by the btStridingMeshInterface interface. /*! - Simply create this shape by passing the btStridingMeshInterface to the constructor btGImpactMeshShapePart, then you must call updateBound() after creating the mesh @@ -535,21 +506,21 @@ public: /*! Manages the info from btStridingMeshInterface object and controls the Lock/Unlock mechanism */ - class TrimeshPrimitiveManager:public btPrimitiveManagerBase + class TrimeshPrimitiveManager : public btPrimitiveManagerBase { public: btScalar m_margin; - btStridingMeshInterface * m_meshInterface; + btStridingMeshInterface* m_meshInterface; btVector3 m_scale; int m_part; int m_lock_count; - const unsigned char *vertexbase; + const unsigned char* vertexbase; int numverts; PHY_ScalarType type; int stride; - const unsigned char *indexbase; + const unsigned char* indexbase; int indexstride; - int numfaces; + int numfaces; PHY_ScalarType indicestype; TrimeshPrimitiveManager() @@ -557,7 +528,7 @@ public: m_meshInterface = NULL; m_part = 0; m_margin = 0.01f; - m_scale = btVector3(1.f,1.f,1.f); + m_scale = btVector3(1.f, 1.f, 1.f); m_lock_count = 0; vertexbase = 0; numverts = 0; @@ -567,8 +538,8 @@ public: numfaces = 0; } - TrimeshPrimitiveManager(const TrimeshPrimitiveManager & manager) - : btPrimitiveManagerBase() + TrimeshPrimitiveManager(const TrimeshPrimitiveManager& manager) + : btPrimitiveManagerBase() { m_meshInterface = manager.m_meshInterface; m_part = manager.m_part; @@ -581,11 +552,10 @@ public: indexbase = 0; indexstride = 0; numfaces = 0; - } TrimeshPrimitiveManager( - btStridingMeshInterface * meshInterface, int part) + btStridingMeshInterface* meshInterface, int part) { m_meshInterface = meshInterface; m_part = part; @@ -598,29 +568,28 @@ public: indexbase = 0; indexstride = 0; numfaces = 0; - } virtual ~TrimeshPrimitiveManager() {} void lock() { - if(m_lock_count>0) + if (m_lock_count > 0) { m_lock_count++; return; } m_meshInterface->getLockedReadOnlyVertexIndexBase( - &vertexbase,numverts, - type, stride,&indexbase, indexstride, numfaces,indicestype,m_part); + &vertexbase, numverts, + type, stride, &indexbase, indexstride, numfaces, indicestype, m_part); m_lock_count = 1; } void unlock() { - if(m_lock_count == 0) return; - if(m_lock_count>1) + if (m_lock_count == 0) return; + if (m_lock_count > 1) { --m_lock_count; return; @@ -637,93 +606,91 @@ public: virtual int get_primitive_count() const { - return (int )numfaces; + return (int)numfaces; } SIMD_FORCE_INLINE int get_vertex_count() const { - return (int )numverts; + return (int)numverts; } - SIMD_FORCE_INLINE void get_indices(int face_index,unsigned int &i0,unsigned int &i1,unsigned int &i2) const + SIMD_FORCE_INLINE void get_indices(int face_index, unsigned int& i0, unsigned int& i1, unsigned int& i2) const { - if(indicestype == PHY_SHORT) + if (indicestype == PHY_SHORT) { - unsigned short* s_indices = (unsigned short *)(indexbase + face_index * indexstride); + unsigned short* s_indices = (unsigned short*)(indexbase + face_index * indexstride); i0 = s_indices[0]; i1 = s_indices[1]; i2 = s_indices[2]; } else { - unsigned int * i_indices = (unsigned int *)(indexbase + face_index*indexstride); + unsigned int* i_indices = (unsigned int*)(indexbase + face_index * indexstride); i0 = i_indices[0]; i1 = i_indices[1]; i2 = i_indices[2]; } } - SIMD_FORCE_INLINE void get_vertex(unsigned int vertex_index, btVector3 & vertex) const + SIMD_FORCE_INLINE void get_vertex(unsigned int vertex_index, btVector3& vertex) const { - if(type == PHY_DOUBLE) + if (type == PHY_DOUBLE) { - double * dvertices = (double *)(vertexbase + vertex_index*stride); - vertex[0] = btScalar(dvertices[0]*m_scale[0]); - vertex[1] = btScalar(dvertices[1]*m_scale[1]); - vertex[2] = btScalar(dvertices[2]*m_scale[2]); + double* dvertices = (double*)(vertexbase + vertex_index * stride); + vertex[0] = btScalar(dvertices[0] * m_scale[0]); + vertex[1] = btScalar(dvertices[1] * m_scale[1]); + vertex[2] = btScalar(dvertices[2] * m_scale[2]); } else { - float * svertices = (float *)(vertexbase + vertex_index*stride); - vertex[0] = svertices[0]*m_scale[0]; - vertex[1] = svertices[1]*m_scale[1]; - vertex[2] = svertices[2]*m_scale[2]; + float* svertices = (float*)(vertexbase + vertex_index * stride); + vertex[0] = svertices[0] * m_scale[0]; + vertex[1] = svertices[1] * m_scale[1]; + vertex[2] = svertices[2] * m_scale[2]; } } - virtual void get_primitive_box(int prim_index ,btAABB & primbox) const + virtual void get_primitive_box(int prim_index, btAABB& primbox) const { - btPrimitiveTriangle triangle; - get_primitive_triangle(prim_index,triangle); + btPrimitiveTriangle triangle; + get_primitive_triangle(prim_index, triangle); primbox.calc_from_triangle_margin( triangle.m_vertices[0], - triangle.m_vertices[1],triangle.m_vertices[2],triangle.m_margin); + triangle.m_vertices[1], triangle.m_vertices[2], triangle.m_margin); } - virtual void get_primitive_triangle(int prim_index,btPrimitiveTriangle & triangle) const + virtual void get_primitive_triangle(int prim_index, btPrimitiveTriangle& triangle) const { unsigned int indices[3]; - get_indices(prim_index,indices[0],indices[1],indices[2]); - get_vertex(indices[0],triangle.m_vertices[0]); - get_vertex(indices[1],triangle.m_vertices[1]); - get_vertex(indices[2],triangle.m_vertices[2]); + get_indices(prim_index, indices[0], indices[1], indices[2]); + get_vertex(indices[0], triangle.m_vertices[0]); + get_vertex(indices[1], triangle.m_vertices[1]); + get_vertex(indices[2], triangle.m_vertices[2]); triangle.m_margin = m_margin; } - SIMD_FORCE_INLINE void get_bullet_triangle(int prim_index,btTriangleShapeEx & triangle) const + SIMD_FORCE_INLINE void get_bullet_triangle(int prim_index, btTriangleShapeEx& triangle) const { unsigned int indices[3]; - get_indices(prim_index,indices[0],indices[1],indices[2]); - get_vertex(indices[0],triangle.m_vertices1[0]); - get_vertex(indices[1],triangle.m_vertices1[1]); - get_vertex(indices[2],triangle.m_vertices1[2]); + get_indices(prim_index, indices[0], indices[1], indices[2]); + get_vertex(indices[0], triangle.m_vertices1[0]); + get_vertex(indices[1], triangle.m_vertices1[1]); + get_vertex(indices[2], triangle.m_vertices1[2]); triangle.setMargin(m_margin); } - }; - protected: TrimeshPrimitiveManager m_primitive_manager; -public: +public: btGImpactMeshShapePart() { m_box_set.setPrimitiveManager(&m_primitive_manager); } - btGImpactMeshShapePart( btStridingMeshInterface * meshInterface, int part ); - virtual ~btGImpactMeshShapePart(); + btGImpactMeshShapePart(btStridingMeshInterface* meshInterface, int part); + virtual ~btGImpactMeshShapePart(); //! if true, then its children must get transforms. virtual bool childrenHasTransform() const @@ -731,40 +698,36 @@ public: return false; } - //! call when reading child shapes - virtual void lockChildShapes() const; - virtual void unlockChildShapes() const; + virtual void lockChildShapes() const; + virtual void unlockChildShapes() const; //! Gets the number of children - virtual int getNumChildShapes() const + virtual int getNumChildShapes() const { return m_primitive_manager.get_primitive_count(); } - //! Gets the children virtual btCollisionShape* getChildShape(int index) { - (void) index; + (void)index; btAssert(0); return NULL; } - - //! Gets the child virtual const btCollisionShape* getChildShape(int index) const { - (void) index; + (void)index; btAssert(0); return NULL; } //! Gets the children transform - virtual btTransform getChildTransform(int index) const + virtual btTransform getChildTransform(int index) const { - (void) index; + (void)index; btAssert(0); return btTransform(); } @@ -773,35 +736,27 @@ public: /*! \post You must call updateBound() for update the box set. */ - virtual void setChildTransform(int index, const btTransform & transform) + virtual void setChildTransform(int index, const btTransform& transform) { - (void) index; - (void) transform; + (void)index; + (void)transform; btAssert(0); } - //! Obtains the primitive manager - virtual const btPrimitiveManagerBase * getPrimitiveManager() const + virtual const btPrimitiveManagerBase* getPrimitiveManager() const { return &m_primitive_manager; } - SIMD_FORCE_INLINE TrimeshPrimitiveManager * getTrimeshPrimitiveManager() + SIMD_FORCE_INLINE TrimeshPrimitiveManager* getTrimeshPrimitiveManager() { return &m_primitive_manager; } + virtual void calculateLocalInertia(btScalar mass, btVector3& inertia) const; - - - - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; - - - - - virtual const char* getName()const + virtual const char* getName() const { return "GImpactMeshShapePart"; } @@ -823,62 +778,59 @@ public: return false; } - virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const + virtual void getBulletTriangle(int prim_index, btTriangleShapeEx& triangle) const { - m_primitive_manager.get_bullet_triangle(prim_index,triangle); + m_primitive_manager.get_bullet_triangle(prim_index, triangle); } - virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const + virtual void getBulletTetrahedron(int prim_index, btTetrahedronShapeEx& tetrahedron) const { - (void) prim_index; - (void) tetrahedron; + (void)prim_index; + (void)tetrahedron; btAssert(0); } - - SIMD_FORCE_INLINE int getVertexCount() const { return m_primitive_manager.get_vertex_count(); } - SIMD_FORCE_INLINE void getVertex(int vertex_index, btVector3 & vertex) const + SIMD_FORCE_INLINE void getVertex(int vertex_index, btVector3& vertex) const { - m_primitive_manager.get_vertex(vertex_index,vertex); + m_primitive_manager.get_vertex(vertex_index, vertex); } SIMD_FORCE_INLINE void setMargin(btScalar margin) - { - m_primitive_manager.m_margin = margin; - postUpdate(); - } + { + m_primitive_manager.m_margin = margin; + postUpdate(); + } - SIMD_FORCE_INLINE btScalar getMargin() const - { - return m_primitive_manager.m_margin; - } + SIMD_FORCE_INLINE btScalar getMargin() const + { + return m_primitive_manager.m_margin; + } - virtual void setLocalScaling(const btVector3& scaling) - { - m_primitive_manager.m_scale = scaling; - postUpdate(); - } + virtual void setLocalScaling(const btVector3& scaling) + { + m_primitive_manager.m_scale = scaling; + postUpdate(); + } - virtual const btVector3& getLocalScaling() const - { - return m_primitive_manager.m_scale; - } + virtual const btVector3& getLocalScaling() const + { + return m_primitive_manager.m_scale; + } - SIMD_FORCE_INLINE int getPart() const - { - return (int)m_primitive_manager.m_part; - } + SIMD_FORCE_INLINE int getPart() const + { + return (int)m_primitive_manager.m_part; + } - virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; - virtual void processAllTrianglesRay(btTriangleCallback* callback,const btVector3& rayFrom,const btVector3& rayTo) const; + virtual void processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const; + virtual void processAllTrianglesRay(btTriangleCallback* callback, const btVector3& rayFrom, const btVector3& rayTo) const; }; - //! This class manages a mesh supplied by the btStridingMeshInterface interface. /*! Set of btGImpactMeshShapePart parts @@ -893,29 +845,29 @@ class btGImpactMeshShape : public btGImpactShapeInterface protected: btAlignedObjectArray m_mesh_parts; - void buildMeshParts(btStridingMeshInterface * meshInterface) + void buildMeshParts(btStridingMeshInterface* meshInterface) { - for (int i=0;igetNumSubParts() ;++i ) + for (int i = 0; i < meshInterface->getNumSubParts(); ++i) { - btGImpactMeshShapePart * newpart = new btGImpactMeshShapePart(meshInterface,i); + btGImpactMeshShapePart* newpart = new btGImpactMeshShapePart(meshInterface, i); m_mesh_parts.push_back(newpart); } } //! use this function for perfofm refit in bounding boxes - virtual void calcLocalAABB() - { - m_localAABB.invalidate(); - int i = m_mesh_parts.size(); - while(i--) - { - m_mesh_parts[i]->updateBound(); - m_localAABB.merge(m_mesh_parts[i]->getLocalBox()); - } - } + virtual void calcLocalAABB() + { + m_localAABB.invalidate(); + int i = m_mesh_parts.size(); + while (i--) + { + m_mesh_parts[i]->updateBound(); + m_localAABB.merge(m_mesh_parts[i]->getLocalBox()); + } + } public: - btGImpactMeshShape(btStridingMeshInterface * meshInterface) + btGImpactMeshShape(btStridingMeshInterface* meshInterface) { m_meshInterface = meshInterface; buildMeshParts(meshInterface); @@ -924,15 +876,14 @@ public: virtual ~btGImpactMeshShape() { int i = m_mesh_parts.size(); - while(i--) - { - btGImpactMeshShapePart * part = m_mesh_parts[i]; + while (i--) + { + btGImpactMeshShapePart* part = m_mesh_parts[i]; delete part; - } + } m_mesh_parts.clear(); } - btStridingMeshInterface* getMeshInterface() { return m_meshInterface; @@ -948,79 +899,73 @@ public: return m_mesh_parts.size(); } - btGImpactMeshShapePart * getMeshPart(int index) + btGImpactMeshShapePart* getMeshPart(int index) { return m_mesh_parts[index]; } - - - const btGImpactMeshShapePart * getMeshPart(int index) const + const btGImpactMeshShapePart* getMeshPart(int index) const { return m_mesh_parts[index]; } - - virtual void setLocalScaling(const btVector3& scaling) + virtual void setLocalScaling(const btVector3& scaling) { localScaling = scaling; int i = m_mesh_parts.size(); - while(i--) - { - btGImpactMeshShapePart * part = m_mesh_parts[i]; + while (i--) + { + btGImpactMeshShapePart* part = m_mesh_parts[i]; part->setLocalScaling(scaling); - } + } m_needs_update = true; } virtual void setMargin(btScalar margin) - { - m_collisionMargin = margin; + { + m_collisionMargin = margin; int i = m_mesh_parts.size(); - while(i--) - { - btGImpactMeshShapePart * part = m_mesh_parts[i]; + while (i--) + { + btGImpactMeshShapePart* part = m_mesh_parts[i]; part->setMargin(margin); - } + } m_needs_update = true; - } + } //! Tells to this object that is needed to refit all the meshes - virtual void postUpdate() - { + virtual void postUpdate() + { int i = m_mesh_parts.size(); - while(i--) - { - btGImpactMeshShapePart * part = m_mesh_parts[i]; + while (i--) + { + btGImpactMeshShapePart* part = m_mesh_parts[i]; part->postUpdate(); - } + } - m_needs_update = true; - } - - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const; + m_needs_update = true; + } + virtual void calculateLocalInertia(btScalar mass, btVector3& inertia) const; //! Obtains the primitive manager - virtual const btPrimitiveManagerBase * getPrimitiveManager() const + virtual const btPrimitiveManagerBase* getPrimitiveManager() const { btAssert(0); return NULL; } - //! Gets the number of children - virtual int getNumChildShapes() const + virtual int getNumChildShapes() const { btAssert(0); return 0; } - //! if true, then its children must get transforms. virtual bool childrenHasTransform() const { @@ -1042,15 +987,17 @@ public: return false; } - virtual void getBulletTriangle(int prim_index,btTriangleShapeEx & triangle) const + virtual void getBulletTriangle(int prim_index, btTriangleShapeEx& triangle) const { - (void) prim_index; (void) triangle; + (void)prim_index; + (void)triangle; btAssert(0); } - virtual void getBulletTetrahedron(int prim_index,btTetrahedronShapeEx & tetrahedron) const + virtual void getBulletTetrahedron(int prim_index, btTetrahedronShapeEx& tetrahedron) const { - (void) prim_index; (void) tetrahedron; + (void)prim_index; + (void)tetrahedron; btAssert(0); } @@ -1065,39 +1012,38 @@ public: btAssert(0); } - - - //! Retrieves the bound from a child - /*! + /*! */ - virtual void getChildAabb(int child_index,const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const - { - (void) child_index; (void) t; (void) aabbMin; (void) aabbMax; - btAssert(0); - } + virtual void getChildAabb(int child_index, const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const + { + (void)child_index; + (void)t; + (void)aabbMin; + (void)aabbMax; + btAssert(0); + } //! Gets the children virtual btCollisionShape* getChildShape(int index) { - (void) index; + (void)index; btAssert(0); return NULL; } - //! Gets the child virtual const btCollisionShape* getChildShape(int index) const { - (void) index; + (void)index; btAssert(0); return NULL; } //! Gets the children transform - virtual btTransform getChildTransform(int index) const + virtual btTransform getChildTransform(int index) const { - (void) index; + (void)index; btAssert(0); return btTransform(); } @@ -1106,59 +1052,56 @@ public: /*! \post You must call updateBound() for update the box set. */ - virtual void setChildTransform(int index, const btTransform & transform) + virtual void setChildTransform(int index, const btTransform& transform) { - (void) index; (void) transform; + (void)index; + (void)transform; btAssert(0); } - virtual eGIMPACT_SHAPE_TYPE getGImpactShapeType() const { return CONST_GIMPACT_TRIMESH_SHAPE; } - - virtual const char* getName()const + virtual const char* getName() const { return "GImpactMesh"; } - virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const; + virtual void rayTest(const btVector3& rayFrom, const btVector3& rayTo, btCollisionWorld::RayResultCallback& resultCallback) const; //! Function for retrieve triangles. /*! It gives the triangles in local space */ - virtual void processAllTriangles(btTriangleCallback* callback,const btVector3& aabbMin,const btVector3& aabbMax) const; + virtual void processAllTriangles(btTriangleCallback* callback, const btVector3& aabbMin, const btVector3& aabbMax) const; - virtual void processAllTrianglesRay (btTriangleCallback* callback,const btVector3& rayFrom,const btVector3& rayTo) const; + virtual void processAllTrianglesRay(btTriangleCallback* callback, const btVector3& rayFrom, const btVector3& rayTo) const; - virtual int calculateSerializeBufferSize() const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; - + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; }; ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 -struct btGImpactMeshShapeData +struct btGImpactMeshShapeData { - btCollisionShapeData m_collisionShapeData; + btCollisionShapeData m_collisionShapeData; btStridingMeshInterfaceData m_meshInterface; - btVector3FloatData m_localScaling; + btVector3FloatData m_localScaling; - float m_collisionMargin; + float m_collisionMargin; - int m_gimpactSubType; + int m_gimpactSubType; }; -SIMD_FORCE_INLINE int btGImpactMeshShape::calculateSerializeBufferSize() const +SIMD_FORCE_INLINE int btGImpactMeshShape::calculateSerializeBufferSize() const { return sizeof(btGImpactMeshShapeData); } - -#endif //GIMPACT_MESH_SHAPE_H +#endif //GIMPACT_MESH_SHAPE_H diff --git a/src/BulletCollision/Gimpact/btGenericPoolAllocator.cpp b/src/BulletCollision/Gimpact/btGenericPoolAllocator.cpp index 5d07d1adb..bfdb3db5d 100644 --- a/src/BulletCollision/Gimpact/btGenericPoolAllocator.cpp +++ b/src/BulletCollision/Gimpact/btGenericPoolAllocator.cpp @@ -20,48 +20,45 @@ subject to the following restrictions: #include "btGenericPoolAllocator.h" - - /// *************** btGenericMemoryPool ******************/////////// size_t btGenericMemoryPool::allocate_from_free_nodes(size_t num_elements) { size_t ptr = BT_UINT_MAX; - if(m_free_nodes_count == 0) return BT_UINT_MAX; + if (m_free_nodes_count == 0) return BT_UINT_MAX; // find an avaliable free node with the correct size size_t revindex = m_free_nodes_count; - while(revindex-- && ptr == BT_UINT_MAX) + while (revindex-- && ptr == BT_UINT_MAX) { - if(m_allocated_sizes[m_free_nodes[revindex]]>=num_elements) + if (m_allocated_sizes[m_free_nodes[revindex]] >= num_elements) { ptr = revindex; } } - if(ptr == BT_UINT_MAX) return BT_UINT_MAX; // not found - + if (ptr == BT_UINT_MAX) return BT_UINT_MAX; // not found revindex = ptr; ptr = m_free_nodes[revindex]; // post: ptr contains the node index, and revindex the index in m_free_nodes - size_t finalsize = m_allocated_sizes[ptr]; + size_t finalsize = m_allocated_sizes[ptr]; finalsize -= num_elements; m_allocated_sizes[ptr] = num_elements; // post: finalsize>=0, m_allocated_sizes[ptr] has the requested size - if(finalsize>0) // preserve free node, there are some free memory + if (finalsize > 0) // preserve free node, there are some free memory { m_free_nodes[revindex] = ptr + num_elements; m_allocated_sizes[ptr + num_elements] = finalsize; } - else // delete free node + else // delete free node { // swap with end - m_free_nodes[revindex] = m_free_nodes[m_free_nodes_count-1]; + m_free_nodes[revindex] = m_free_nodes[m_free_nodes_count - 1]; m_free_nodes_count--; } @@ -70,17 +67,16 @@ size_t btGenericMemoryPool::allocate_from_free_nodes(size_t num_elements) size_t btGenericMemoryPool::allocate_from_pool(size_t num_elements) { - if(m_allocated_count+num_elements>m_max_element_count) return BT_UINT_MAX; + if (m_allocated_count + num_elements > m_max_element_count) return BT_UINT_MAX; size_t ptr = m_allocated_count; m_allocated_sizes[m_allocated_count] = num_elements; - m_allocated_count+=num_elements; + m_allocated_count += num_elements; return ptr; } - void btGenericMemoryPool::init_pool(size_t element_size, size_t element_count) { m_allocated_count = 0; @@ -89,14 +85,11 @@ void btGenericMemoryPool::init_pool(size_t element_size, size_t element_count) m_element_size = element_size; m_max_element_count = element_count; + m_pool = (unsigned char *)btAlignedAlloc(m_element_size * m_max_element_count, 16); + m_free_nodes = (size_t *)btAlignedAlloc(sizeof(size_t) * m_max_element_count, 16); + m_allocated_sizes = (size_t *)btAlignedAlloc(sizeof(size_t) * m_max_element_count, 16); - - - m_pool = (unsigned char *) btAlignedAlloc(m_element_size*m_max_element_count,16); - m_free_nodes = (size_t *) btAlignedAlloc(sizeof(size_t)*m_max_element_count,16); - m_allocated_sizes = (size_t *) btAlignedAlloc(sizeof(size_t)*m_max_element_count,16); - - for (size_t i = 0;i< m_max_element_count;i++ ) + for (size_t i = 0; i < m_max_element_count; i++) { m_allocated_sizes[i] = 0; } @@ -111,150 +104,141 @@ void btGenericMemoryPool::end_pool() m_free_nodes_count = 0; } - //! Allocates memory in pool /*! \param size_bytes size in bytes of the buffer */ -void * btGenericMemoryPool::allocate(size_t size_bytes) +void *btGenericMemoryPool::allocate(size_t size_bytes) { - - size_t module = size_bytes%m_element_size; - size_t element_count = size_bytes/m_element_size; - if(module>0) element_count++; + size_t module = size_bytes % m_element_size; + size_t element_count = size_bytes / m_element_size; + if (module > 0) element_count++; size_t alloc_pos = allocate_from_free_nodes(element_count); // a free node is found - if(alloc_pos != BT_UINT_MAX) + if (alloc_pos != BT_UINT_MAX) { return get_element_data(alloc_pos); } // allocate directly on pool alloc_pos = allocate_from_pool(element_count); - if(alloc_pos == BT_UINT_MAX) return NULL; // not space + if (alloc_pos == BT_UINT_MAX) return NULL; // not space return get_element_data(alloc_pos); } -bool btGenericMemoryPool::freeMemory(void * pointer) +bool btGenericMemoryPool::freeMemory(void *pointer) { - unsigned char * pointer_pos = (unsigned char *)pointer; - unsigned char * pool_pos = (unsigned char *)m_pool; + unsigned char *pointer_pos = (unsigned char *)pointer; + unsigned char *pool_pos = (unsigned char *)m_pool; // calc offset - if(pointer_pos=get_pool_capacity()) return false;// far away + if (offset >= get_pool_capacity()) return false; // far away // find free position - m_free_nodes[m_free_nodes_count] = offset/m_element_size; + m_free_nodes[m_free_nodes_count] = offset / m_element_size; m_free_nodes_count++; return true; } - /// *******************! btGenericPoolAllocator *******************!/// - btGenericPoolAllocator::~btGenericPoolAllocator() { // destroy pools size_t i; - for (i=0;iend_pool(); btAlignedFree(m_pools[i]); } } - // creates a pool -btGenericMemoryPool * btGenericPoolAllocator::push_new_pool() +btGenericMemoryPool *btGenericPoolAllocator::push_new_pool() { - if(m_pool_count >= BT_DEFAULT_MAX_POOLS) return NULL; + if (m_pool_count >= BT_DEFAULT_MAX_POOLS) return NULL; - btGenericMemoryPool * newptr = (btGenericMemoryPool *)btAlignedAlloc(sizeof(btGenericMemoryPool),16); + btGenericMemoryPool *newptr = (btGenericMemoryPool *)btAlignedAlloc(sizeof(btGenericMemoryPool), 16); m_pools[m_pool_count] = newptr; - m_pools[m_pool_count]->init_pool(m_pool_element_size,m_pool_element_count); + m_pools[m_pool_count]->init_pool(m_pool_element_size, m_pool_element_count); m_pool_count++; return newptr; } -void * btGenericPoolAllocator::failback_alloc(size_t size_bytes) +void *btGenericPoolAllocator::failback_alloc(size_t size_bytes) { + btGenericMemoryPool *pool = NULL; - btGenericMemoryPool * pool = NULL; - - - if(size_bytes<=get_pool_capacity()) + if (size_bytes <= get_pool_capacity()) { - pool = push_new_pool(); + pool = push_new_pool(); } - if(pool==NULL) // failback + if (pool == NULL) // failback { - return btAlignedAlloc(size_bytes,16); + return btAlignedAlloc(size_bytes, 16); } return pool->allocate(size_bytes); } -bool btGenericPoolAllocator::failback_free(void * pointer) +bool btGenericPoolAllocator::failback_free(void *pointer) { btAlignedFree(pointer); return true; } - //! Allocates memory in pool /*! \param size_bytes size in bytes of the buffer */ -void * btGenericPoolAllocator::allocate(size_t size_bytes) +void *btGenericPoolAllocator::allocate(size_t size_bytes) { - void * ptr = NULL; + void *ptr = NULL; size_t i = 0; - while(iallocate(size_bytes); ++i; } - if(ptr) return ptr; + if (ptr) return ptr; return failback_alloc(size_bytes); } -bool btGenericPoolAllocator::freeMemory(void * pointer) +bool btGenericPoolAllocator::freeMemory(void *pointer) { bool result = false; size_t i = 0; - while(ifreeMemory(pointer); ++i; } - if(result) return true; + if (result) return true; return failback_free(pointer); } /// ************** STANDARD ALLOCATOR ***************************/// - #define BT_DEFAULT_POOL_SIZE 32768 #define BT_DEFAULT_POOL_ELEMENT_SIZE 8 // main allocator -class GIM_STANDARD_ALLOCATOR: public btGenericPoolAllocator +class GIM_STANDARD_ALLOCATOR : public btGenericPoolAllocator { public: - GIM_STANDARD_ALLOCATOR():btGenericPoolAllocator(BT_DEFAULT_POOL_ELEMENT_SIZE,BT_DEFAULT_POOL_SIZE) + GIM_STANDARD_ALLOCATOR() : btGenericPoolAllocator(BT_DEFAULT_POOL_ELEMENT_SIZE, BT_DEFAULT_POOL_SIZE) { } }; @@ -262,19 +246,18 @@ public: // global allocator GIM_STANDARD_ALLOCATOR g_main_allocator; - -void * btPoolAlloc(size_t size) +void *btPoolAlloc(size_t size) { return g_main_allocator.allocate(size); } -void * btPoolRealloc(void *ptr, size_t oldsize, size_t newsize) +void *btPoolRealloc(void *ptr, size_t oldsize, size_t newsize) { - void * newptr = btPoolAlloc(newsize); - size_t copysize = oldsizemaxval?maxval:number)) +#define BT_CLAMP(number, minval, maxval) (number < minval ? minval : (number > maxval ? maxval : number)) /// Calc a plane from a triangle edge an a normal. plane is a vec4f -SIMD_FORCE_INLINE void bt_edge_plane(const btVector3 & e1,const btVector3 & e2, const btVector3 & normal,btVector4 & plane) +SIMD_FORCE_INLINE void bt_edge_plane(const btVector3 &e1, const btVector3 &e2, const btVector3 &normal, btVector4 &plane) { - btVector3 planenormal = (e2-e1).cross(normal); + btVector3 planenormal = (e2 - e1).cross(normal); planenormal.normalize(); - plane.setValue(planenormal[0],planenormal[1],planenormal[2],e2.dot(planenormal)); + plane.setValue(planenormal[0], planenormal[1], planenormal[2], e2.dot(planenormal)); } - - //***************** SEGMENT and LINE FUNCTIONS **********************************/// /*! Finds the closest point(cp) to (v) on a segment (e1,e2) */ SIMD_FORCE_INLINE void bt_closest_point_on_segment( - btVector3 & cp, const btVector3 & v, - const btVector3 &e1,const btVector3 &e2) + btVector3 &cp, const btVector3 &v, + const btVector3 &e1, const btVector3 &e2) { - btVector3 n = e2-e1; - cp = v - e1; - btScalar _scalar = cp.dot(n)/n.dot(n); - if(_scalar <0.0f) + btVector3 n = e2 - e1; + cp = v - e1; + btScalar _scalar = cp.dot(n) / n.dot(n); + if (_scalar < 0.0f) { - cp = e1; + cp = e1; } - else if(_scalar >1.0f) + else if (_scalar > 1.0f) { - cp = e2; + cp = e2; } else { - cp = _scalar*n + e1; + cp = _scalar * n + e1; } } - //! line plane collision /*! *\return @@ -82,131 +74,125 @@ SIMD_FORCE_INLINE void bt_closest_point_on_segment( */ SIMD_FORCE_INLINE int bt_line_plane_collision( - const btVector4 & plane, - const btVector3 & vDir, - const btVector3 & vPoint, - btVector3 & pout, + const btVector4 &plane, + const btVector3 &vDir, + const btVector3 &vPoint, + btVector3 &pout, btScalar &tparam, btScalar tmin, btScalar tmax) { - btScalar _dotdir = vDir.dot(plane); - if(btFabs(_dotdir)tmax) + else if (tparam > tmax) { returnvalue = 0; tparam = tmax; } - pout = tparam*vDir + vPoint; + pout = tparam * vDir + vPoint; return returnvalue; } - //! Find closest points on segments SIMD_FORCE_INLINE void bt_segment_collision( - const btVector3 & vA1, - const btVector3 & vA2, - const btVector3 & vB1, - const btVector3 & vB2, - btVector3 & vPointA, - btVector3 & vPointB) + const btVector3 &vA1, + const btVector3 &vA2, + const btVector3 &vB1, + const btVector3 &vB2, + btVector3 &vPointA, + btVector3 &vPointB) { - btVector3 AD = vA2 - vA1; - btVector3 BD = vB2 - vB1; - btVector3 N = AD.cross(BD); - btScalar tp = N.length2(); + btVector3 AD = vA2 - vA1; + btVector3 BD = vB2 - vB1; + btVector3 N = AD.cross(BD); + btScalar tp = N.length2(); - btVector4 _M;//plane + btVector4 _M; //plane - if(tp_M[1]) - { - invert_b_order = true; - BT_SWAP_NUMBERS(_M[0],_M[1]); - } - _M[2] = vA1.dot(AD); - _M[3] = vA2.dot(AD); - //mid points - N[0] = (_M[0]+_M[1])*0.5f; - N[1] = (_M[2]+_M[3])*0.5f; + if (_M[0] > _M[1]) + { + invert_b_order = true; + BT_SWAP_NUMBERS(_M[0], _M[1]); + } + _M[2] = vA1.dot(AD); + _M[3] = vA2.dot(AD); + //mid points + N[0] = (_M[0] + _M[1]) * 0.5f; + N[1] = (_M[2] + _M[3]) * 0.5f; - if(N[0]=0.0f) - { - if (_dist>m_penetration_depth) - { - m_penetration_depth = _dist; - point_indices[0] = _k; - m_point_count=1; - } - else if ((_dist+SIMD_EPSILON)>=m_penetration_depth) - { - point_indices[m_point_count] = _k; - m_point_count++; - } - } - } + if (_dist >= 0.0f) + { + if (_dist > m_penetration_depth) + { + m_penetration_depth = _dist; + point_indices[0] = _k; + m_point_count = 1; + } + else if ((_dist + SIMD_EPSILON) >= m_penetration_depth) + { + point_indices[m_point_count] = _k; + m_point_count++; + } + } + } - for ( _k=0;_k0.0f&&dis1>0.0f&&dis2>0.0f) return false; + if (dis0 > 0.0f && dis1 > 0.0f && dis2 > 0.0f) return false; - // classify points on this triangle - dis0 = bt_distance_point_plane(other.m_plane,m_vertices[0]) - total_margin; + // classify points on this triangle + dis0 = bt_distance_point_plane(other.m_plane, m_vertices[0]) - total_margin; - dis1 = bt_distance_point_plane(other.m_plane,m_vertices[1]) - total_margin; + dis1 = bt_distance_point_plane(other.m_plane, m_vertices[1]) - total_margin; - dis2 = bt_distance_point_plane(other.m_plane,m_vertices[2]) - total_margin; + dis2 = bt_distance_point_plane(other.m_plane, m_vertices[2]) - total_margin; - if (dis0>0.0f&&dis1>0.0f&&dis2>0.0f) return false; + if (dis0 > 0.0f && dis1 > 0.0f && dis2 > 0.0f) return false; - return true; + return true; } -int btPrimitiveTriangle::clip_triangle(btPrimitiveTriangle & other, btVector3 * clipped_points ) +int btPrimitiveTriangle::clip_triangle(btPrimitiveTriangle& other, btVector3* clipped_points) { - // edge 0 + // edge 0 - btVector3 temp_points[MAX_TRI_CLIPPING]; + btVector3 temp_points[MAX_TRI_CLIPPING]; + btVector4 edgeplane; - btVector4 edgeplane; + get_edge_plane(0, edgeplane); - get_edge_plane(0,edgeplane); + int clipped_count = bt_plane_clip_triangle( + edgeplane, other.m_vertices[0], other.m_vertices[1], other.m_vertices[2], temp_points); + if (clipped_count == 0) return 0; - int clipped_count = bt_plane_clip_triangle( - edgeplane,other.m_vertices[0],other.m_vertices[1],other.m_vertices[2],temp_points); + btVector3 temp_points1[MAX_TRI_CLIPPING]; - if (clipped_count == 0) return 0; + // edge 1 + get_edge_plane(1, edgeplane); - btVector3 temp_points1[MAX_TRI_CLIPPING]; + clipped_count = bt_plane_clip_polygon(edgeplane, temp_points, clipped_count, temp_points1); + if (clipped_count == 0) return 0; - // edge 1 - get_edge_plane(1,edgeplane); + // edge 2 + get_edge_plane(2, edgeplane); + clipped_count = bt_plane_clip_polygon( + edgeplane, temp_points1, clipped_count, clipped_points); - clipped_count = bt_plane_clip_polygon(edgeplane,temp_points,clipped_count,temp_points1); - - if (clipped_count == 0) return 0; - - // edge 2 - get_edge_plane(2,edgeplane); - - clipped_count = bt_plane_clip_polygon( - edgeplane,temp_points1,clipped_count,clipped_points); - - return clipped_count; + return clipped_count; } -bool btPrimitiveTriangle::find_triangle_collision_clip_method(btPrimitiveTriangle & other, GIM_TRIANGLE_CONTACT & contacts) +bool btPrimitiveTriangle::find_triangle_collision_clip_method(btPrimitiveTriangle& other, GIM_TRIANGLE_CONTACT& contacts) { - btScalar margin = m_margin + other.m_margin; + btScalar margin = m_margin + other.m_margin; - btVector3 clipped_points[MAX_TRI_CLIPPING]; - int clipped_count; - //create planes - // plane v vs U points + btVector3 clipped_points[MAX_TRI_CLIPPING]; + int clipped_count; + //create planes + // plane v vs U points - GIM_TRIANGLE_CONTACT contacts1; + GIM_TRIANGLE_CONTACT contacts1; - contacts1.m_separating_normal = m_plane; + contacts1.m_separating_normal = m_plane; + clipped_count = clip_triangle(other, clipped_points); - clipped_count = clip_triangle(other,clipped_points); + if (clipped_count == 0) + { + return false; //Reject + } - if (clipped_count == 0 ) - { - return false;//Reject - } + //find most deep interval face1 + contacts1.merge_points(contacts1.m_separating_normal, margin, clipped_points, clipped_count); + if (contacts1.m_point_count == 0) return false; // too far + //Normal pointing to this triangle + contacts1.m_separating_normal *= -1.f; - //find most deep interval face1 - contacts1.merge_points(contacts1.m_separating_normal,margin,clipped_points,clipped_count); - if (contacts1.m_point_count == 0) return false; // too far - //Normal pointing to this triangle - contacts1.m_separating_normal *= -1.f; + //Clip tri1 by tri2 edges + GIM_TRIANGLE_CONTACT contacts2; + contacts2.m_separating_normal = other.m_plane; + clipped_count = other.clip_triangle(*this, clipped_points); - //Clip tri1 by tri2 edges - GIM_TRIANGLE_CONTACT contacts2; - contacts2.m_separating_normal = other.m_plane; + if (clipped_count == 0) + { + return false; //Reject + } - clipped_count = other.clip_triangle(*this,clipped_points); + //find most deep interval face1 + contacts2.merge_points(contacts2.m_separating_normal, margin, clipped_points, clipped_count); + if (contacts2.m_point_count == 0) return false; // too far - if (clipped_count == 0 ) - { - return false;//Reject - } - - //find most deep interval face1 - contacts2.merge_points(contacts2.m_separating_normal,margin,clipped_points,clipped_count); - if (contacts2.m_point_count == 0) return false; // too far - - - - - ////check most dir for contacts - if (contacts2.m_penetration_depth0.0f&&dis1>0.0f&&dis2>0.0f) return false; + if (dis0 > 0.0f && dis1 > 0.0f && dis2 > 0.0f) return false; - // classify points on this triangle - dis0 = bt_distance_point_plane(plane1,m_vertices1[0]) - total_margin; + // classify points on this triangle + dis0 = bt_distance_point_plane(plane1, m_vertices1[0]) - total_margin; - dis1 = bt_distance_point_plane(plane1,m_vertices1[1]) - total_margin; + dis1 = bt_distance_point_plane(plane1, m_vertices1[1]) - total_margin; - dis2 = bt_distance_point_plane(plane1,m_vertices1[2]) - total_margin; + dis2 = bt_distance_point_plane(plane1, m_vertices1[2]) - total_margin; - if (dis0>0.0f&&dis1>0.0f&&dis2>0.0f) return false; + if (dis0 > 0.0f && dis1 > 0.0f && dis2 > 0.0f) return false; - return true; + return true; } - - diff --git a/src/BulletCollision/Gimpact/btTriangleShapeEx.h b/src/BulletCollision/Gimpact/btTriangleShapeEx.h index 973c2ed12..568a1ce81 100644 --- a/src/BulletCollision/Gimpact/btTriangleShapeEx.h +++ b/src/BulletCollision/Gimpact/btTriangleShapeEx.h @@ -21,7 +21,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef GIMPACT_TRIANGLE_SHAPE_EX_H #define GIMPACT_TRIANGLE_SHAPE_EX_H @@ -31,16 +30,15 @@ subject to the following restrictions: #include "btClipPolygon.h" #include "btGeometryOperations.h" - #define MAX_TRI_CLIPPING 16 //! Structure for collision struct GIM_TRIANGLE_CONTACT { - btScalar m_penetration_depth; - int m_point_count; - btVector4 m_separating_normal; - btVector3 m_points[MAX_TRI_CLIPPING]; + btScalar m_penetration_depth; + int m_point_count; + btVector4 m_separating_normal; + btVector3 m_points[MAX_TRI_CLIPPING]; SIMD_FORCE_INLINE void copy_from(const GIM_TRIANGLE_CONTACT& other) { @@ -48,7 +46,7 @@ struct GIM_TRIANGLE_CONTACT m_separating_normal = other.m_separating_normal; m_point_count = other.m_point_count; int i = m_point_count; - while(i--) + while (i--) { m_points[i] = other.m_points[i]; } @@ -63,14 +61,11 @@ struct GIM_TRIANGLE_CONTACT copy_from(other); } - //! classify points that are closer - void merge_points(const btVector4 & plane, - btScalar margin, const btVector3 * points, int point_count); - + //! classify points that are closer + void merge_points(const btVector4& plane, + btScalar margin, const btVector3* points, int point_count); }; - - class btPrimitiveTriangle { public: @@ -78,17 +73,15 @@ public: btVector4 m_plane; btScalar m_margin; btScalar m_dummy; - btPrimitiveTriangle():m_margin(0.01f) + btPrimitiveTriangle() : m_margin(0.01f) { - } - SIMD_FORCE_INLINE void buildTriPlane() { - btVector3 normal = (m_vertices[1]-m_vertices[0]).cross(m_vertices[2]-m_vertices[0]); + btVector3 normal = (m_vertices[1] - m_vertices[0]).cross(m_vertices[2] - m_vertices[0]); normal.normalize(); - m_plane.setValue(normal[0],normal[1],normal[2],m_vertices[0].dot(normal)); + m_plane.setValue(normal[0], normal[1], normal[2], m_vertices[0].dot(normal)); } //! Test if triangles could collide @@ -98,14 +91,14 @@ public: /*! \pre this triangle must have its plane calculated. */ - SIMD_FORCE_INLINE void get_edge_plane(int edge_index, btVector4 &plane) const - { - const btVector3 & e0 = m_vertices[edge_index]; - const btVector3 & e1 = m_vertices[(edge_index+1)%3]; - bt_edge_plane(e0,e1,m_plane,plane); - } + SIMD_FORCE_INLINE void get_edge_plane(int edge_index, btVector4& plane) const + { + const btVector3& e0 = m_vertices[edge_index]; + const btVector3& e1 = m_vertices[(edge_index + 1) % 3]; + bt_edge_plane(e0, e1, m_plane, plane); + } - void applyTransform(const btTransform& t) + void applyTransform(const btTransform& t) { m_vertices[0] = t(m_vertices[0]); m_vertices[1] = t(m_vertices[1]); @@ -117,44 +110,41 @@ public: \pre clipped_points must have MAX_TRI_CLIPPING size, and this triangle must have its plane calculated. \return the number of clipped points */ - int clip_triangle(btPrimitiveTriangle & other, btVector3 * clipped_points ); + int clip_triangle(btPrimitiveTriangle& other, btVector3* clipped_points); //! Find collision using the clipping method /*! \pre this triangle and other must have their triangles calculated */ - bool find_triangle_collision_clip_method(btPrimitiveTriangle & other, GIM_TRIANGLE_CONTACT & contacts); + bool find_triangle_collision_clip_method(btPrimitiveTriangle& other, GIM_TRIANGLE_CONTACT& contacts); }; - - //! Helper class for colliding Bullet Triangle Shapes /*! This class implements a better getAabb method than the previous btTriangleShape class */ -class btTriangleShapeEx: public btTriangleShape +class btTriangleShapeEx : public btTriangleShape { public: - - btTriangleShapeEx():btTriangleShape(btVector3(0,0,0),btVector3(0,0,0),btVector3(0,0,0)) + btTriangleShapeEx() : btTriangleShape(btVector3(0, 0, 0), btVector3(0, 0, 0), btVector3(0, 0, 0)) { } - btTriangleShapeEx(const btVector3& p0,const btVector3& p1,const btVector3& p2): btTriangleShape(p0,p1,p2) + btTriangleShapeEx(const btVector3& p0, const btVector3& p1, const btVector3& p2) : btTriangleShape(p0, p1, p2) { } - btTriangleShapeEx(const btTriangleShapeEx & other): btTriangleShape(other.m_vertices1[0],other.m_vertices1[1],other.m_vertices1[2]) + btTriangleShapeEx(const btTriangleShapeEx& other) : btTriangleShape(other.m_vertices1[0], other.m_vertices1[1], other.m_vertices1[2]) { } - virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax)const + virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const { btVector3 tv0 = t(m_vertices1[0]); btVector3 tv1 = t(m_vertices1[1]); btVector3 tv2 = t(m_vertices1[2]); - btAABB trianglebox(tv0,tv1,tv2,m_collisionMargin); + btAABB trianglebox(tv0, tv1, tv2, m_collisionMargin); aabbMin = trianglebox.m_min; aabbMax = trianglebox.m_max; } @@ -166,15 +156,14 @@ public: m_vertices1[2] = t(m_vertices1[2]); } - SIMD_FORCE_INLINE void buildTriPlane(btVector4 & plane) const + SIMD_FORCE_INLINE void buildTriPlane(btVector4& plane) const { - btVector3 normal = (m_vertices1[1]-m_vertices1[0]).cross(m_vertices1[2]-m_vertices1[0]); + btVector3 normal = (m_vertices1[1] - m_vertices1[0]).cross(m_vertices1[2] - m_vertices1[0]); normal.normalize(); - plane.setValue(normal[0],normal[1],normal[2],m_vertices1[0].dot(normal)); + plane.setValue(normal[0], normal[1], normal[2], m_vertices1[0].dot(normal)); } bool overlap_test_conservative(const btTriangleShapeEx& other); }; - -#endif //GIMPACT_TRIANGLE_MESH_SHAPE_H +#endif //GIMPACT_TRIANGLE_MESH_SHAPE_H diff --git a/src/BulletCollision/Gimpact/gim_array.h b/src/BulletCollision/Gimpact/gim_array.h index cda51a5fc..fc2dc38a3 100644 --- a/src/BulletCollision/Gimpact/gim_array.h +++ b/src/BulletCollision/Gimpact/gim_array.h @@ -34,47 +34,46 @@ email: projectileman@yahoo.com #include "gim_memory.h" - #define GIM_ARRAY_GROW_INCREMENT 2 #define GIM_ARRAY_GROW_FACTOR 2 //! Very simple array container with fast access and simd memory -template +template class gim_array { public: -//! properties -//!@{ - T *m_data; - GUINT m_size; - GUINT m_allocated_size; -//!@} -//! protected operations -//!@{ + //! properties + //!@{ + T* m_data; + GUINT m_size; + GUINT m_allocated_size; + //!@} + //! protected operations + //!@{ - inline void destroyData() + inline void destroyData() { - m_allocated_size = 0; - if(m_data==NULL) return; + m_allocated_size = 0; + if (m_data == NULL) return; gim_free(m_data); m_data = NULL; } inline bool resizeData(GUINT newsize) { - if(newsize==0) + if (newsize == 0) { destroyData(); return true; } - if(m_size>0) + if (m_size > 0) { - m_data = (T*)gim_realloc(m_data,m_size*sizeof(T),newsize*sizeof(T)); + m_data = (T*)gim_realloc(m_data, m_size * sizeof(T), newsize * sizeof(T)); } else { - m_data = (T*)gim_alloc(newsize*sizeof(T)); + m_data = (T*)gim_alloc(newsize * sizeof(T)); } m_allocated_size = newsize; return true; @@ -82,243 +81,238 @@ public: inline bool growingCheck() { - if(m_allocated_size<=m_size) + if (m_allocated_size <= m_size) { - GUINT requestsize = m_size; - m_size = m_allocated_size; - if(resizeData((requestsize+GIM_ARRAY_GROW_INCREMENT)*GIM_ARRAY_GROW_FACTOR)==false) return false; + GUINT requestsize = m_size; + m_size = m_allocated_size; + if (resizeData((requestsize + GIM_ARRAY_GROW_INCREMENT) * GIM_ARRAY_GROW_FACTOR) == false) return false; } return true; } -//!@} -//! public operations -//!@{ - inline bool reserve(GUINT size) - { - if(m_allocated_size>=size) return false; - return resizeData(size); - } + //!@} + //! public operations + //!@{ + inline bool reserve(GUINT size) + { + if (m_allocated_size >= size) return false; + return resizeData(size); + } - inline void clear_range(GUINT start_range) - { - while(m_size>start_range) - { - m_data[--m_size].~T(); - } - } + inline void clear_range(GUINT start_range) + { + while (m_size > start_range) + { + m_data[--m_size].~T(); + } + } - inline void clear() - { - if(m_size==0)return; - clear_range(0); - } + inline void clear() + { + if (m_size == 0) return; + clear_range(0); + } - inline void clear_memory() - { - clear(); - destroyData(); - } + inline void clear_memory() + { + clear(); + destroyData(); + } - gim_array() - { - m_data = 0; - m_size = 0; - m_allocated_size = 0; - } + gim_array() + { + m_data = 0; + m_size = 0; + m_allocated_size = 0; + } - gim_array(GUINT reservesize) - { - m_data = 0; - m_size = 0; + gim_array(GUINT reservesize) + { + m_data = 0; + m_size = 0; - m_allocated_size = 0; - reserve(reservesize); - } + m_allocated_size = 0; + reserve(reservesize); + } - ~gim_array() - { - clear_memory(); - } + ~gim_array() + { + clear_memory(); + } - inline GUINT size() const - { - return m_size; - } + inline GUINT size() const + { + return m_size; + } - inline GUINT max_size() const - { - return m_allocated_size; - } + inline GUINT max_size() const + { + return m_allocated_size; + } - inline T & operator[](size_t i) + inline T& operator[](size_t i) { return m_data[i]; } - inline const T & operator[](size_t i) const + inline const T& operator[](size_t i) const { return m_data[i]; } - inline T * pointer(){ return m_data;} - inline const T * pointer() const - { return m_data;} + inline T* pointer() { return m_data; } + inline const T* pointer() const + { + return m_data; + } - - inline T * get_pointer_at(GUINT i) + inline T* get_pointer_at(GUINT i) { return m_data + i; } - inline const T * get_pointer_at(GUINT i) const + inline const T* get_pointer_at(GUINT i) const { return m_data + i; } - inline T & at(GUINT i) + inline T& at(GUINT i) { return m_data[i]; } - inline const T & at(GUINT i) const + inline const T& at(GUINT i) const { return m_data[i]; } - inline T & front() + inline T& front() { return *m_data; } - inline const T & front() const + inline const T& front() const { return *m_data; } - inline T & back() + inline T& back() { - return m_data[m_size-1]; + return m_data[m_size - 1]; } - inline const T & back() const + inline const T& back() const { - return m_data[m_size-1]; + return m_data[m_size - 1]; } - inline void swap(GUINT i, GUINT j) { - gim_swap_elements(m_data,i,j); + gim_swap_elements(m_data, i, j); } - inline void push_back(const T & obj) + inline void push_back(const T& obj) { - this->growingCheck(); - m_data[m_size] = obj; - m_size++; + this->growingCheck(); + m_data[m_size] = obj; + m_size++; } //!Simply increase the m_size, doesn't call the new element constructor inline void push_back_mem() { - this->growingCheck(); - m_size++; + this->growingCheck(); + m_size++; } - inline void push_back_memcpy(const T & obj) + inline void push_back_memcpy(const T& obj) { - this->growingCheck(); - gim_simd_memcpy(&m_data[m_size],&obj,sizeof(T)); - m_size++; + this->growingCheck(); + gim_simd_memcpy(&m_data[m_size], &obj, sizeof(T)); + m_size++; } inline void pop_back() { - m_size--; - m_data[m_size].~T(); + m_size--; + m_data[m_size].~T(); } //!Simply decrease the m_size, doesn't call the deleted element destructor inline void pop_back_mem() { - m_size--; + m_size--; } - //! fast erase + //! fast erase inline void erase(GUINT index) { - if(indexgrowingCheck(); - for(GUINT i = m_size;i>index;i--) - { - gim_simd_memcpy(m_data+i,m_data+i-1,sizeof(T)); - } - m_size++; + this->growingCheck(); + for (GUINT i = m_size; i > index; i--) + { + gim_simd_memcpy(m_data + i, m_data + i - 1, sizeof(T)); + } + m_size++; } - inline void insert(const T & obj,GUINT index) + inline void insert(const T& obj, GUINT index) { - insert_mem(index); - m_data[index] = obj; + insert_mem(index); + m_data[index] = obj; } - inline void resize(GUINT size, bool call_constructor = true, const T& fillData=T()) + inline void resize(GUINT size, bool call_constructor = true, const T& fillData = T()) { - if(size>m_size) - { - reserve(size); - if(call_constructor) - { - while(m_size m_size) + { + reserve(size); + if (call_constructor) + { + while (m_size < size) + { + m_data[m_size] = fillData; + m_size++; + } + } + else + { + m_size = size; + } + } + else if (size < m_size) + { + if (call_constructor) clear_range(size); + m_size = size; + } } inline void refit() { - resizeData(m_size); + resizeData(m_size); } - }; - - - - -#endif // GIM_CONTAINERS_H_INCLUDED +#endif // GIM_CONTAINERS_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/gim_basic_geometry_operations.h b/src/BulletCollision/Gimpact/gim_basic_geometry_operations.h index 0c48cb60f..7ab783672 100644 --- a/src/BulletCollision/Gimpact/gim_basic_geometry_operations.h +++ b/src/BulletCollision/Gimpact/gim_basic_geometry_operations.h @@ -35,12 +35,8 @@ email: projectileman@yahoo.com ----------------------------------------------------------------------------- */ - #include "gim_linear_math.h" - - - #ifndef PLANEDIREPSILON #define PLANEDIREPSILON 0.0000001f #endif @@ -49,77 +45,82 @@ email: projectileman@yahoo.com #define PARALELENORMALS 0.000001f #endif -#define TRIANGLE_NORMAL(v1,v2,v3,n)\ -{\ - vec3f _dif1,_dif2;\ - VEC_DIFF(_dif1,v2,v1);\ - VEC_DIFF(_dif2,v3,v1);\ - VEC_CROSS(n,_dif1,_dif2);\ - VEC_NORMALIZE(n);\ -}\ +#define TRIANGLE_NORMAL(v1, v2, v3, n) \ + { \ + vec3f _dif1, _dif2; \ + VEC_DIFF(_dif1, v2, v1); \ + VEC_DIFF(_dif2, v3, v1); \ + VEC_CROSS(n, _dif1, _dif2); \ + VEC_NORMALIZE(n); \ + } -#define TRIANGLE_NORMAL_FAST(v1,v2,v3,n){\ - vec3f _dif1,_dif2; \ - VEC_DIFF(_dif1,v2,v1); \ - VEC_DIFF(_dif2,v3,v1); \ - VEC_CROSS(n,_dif1,_dif2); \ -}\ +#define TRIANGLE_NORMAL_FAST(v1, v2, v3, n) \ + { \ + vec3f _dif1, _dif2; \ + VEC_DIFF(_dif1, v2, v1); \ + VEC_DIFF(_dif2, v3, v1); \ + VEC_CROSS(n, _dif1, _dif2); \ + } /// plane is a vec4f -#define TRIANGLE_PLANE(v1,v2,v3,plane) {\ - TRIANGLE_NORMAL(v1,v2,v3,plane);\ - plane[3] = VEC_DOT(v1,plane);\ -}\ +#define TRIANGLE_PLANE(v1, v2, v3, plane) \ + { \ + TRIANGLE_NORMAL(v1, v2, v3, plane); \ + plane[3] = VEC_DOT(v1, plane); \ + } /// plane is a vec4f -#define TRIANGLE_PLANE_FAST(v1,v2,v3,plane) {\ - TRIANGLE_NORMAL_FAST(v1,v2,v3,plane);\ - plane[3] = VEC_DOT(v1,plane);\ -}\ +#define TRIANGLE_PLANE_FAST(v1, v2, v3, plane) \ + { \ + TRIANGLE_NORMAL_FAST(v1, v2, v3, plane); \ + plane[3] = VEC_DOT(v1, plane); \ + } /// Calc a plane from an edge an a normal. plane is a vec4f -#define EDGE_PLANE(e1,e2,n,plane) {\ - vec3f _dif; \ - VEC_DIFF(_dif,e2,e1); \ - VEC_CROSS(plane,_dif,n); \ - VEC_NORMALIZE(plane); \ - plane[3] = VEC_DOT(e1,plane);\ -}\ +#define EDGE_PLANE(e1, e2, n, plane) \ + { \ + vec3f _dif; \ + VEC_DIFF(_dif, e2, e1); \ + VEC_CROSS(plane, _dif, n); \ + VEC_NORMALIZE(plane); \ + plane[3] = VEC_DOT(e1, plane); \ + } -#define DISTANCE_PLANE_POINT(plane,point) (VEC_DOT(plane,point) - plane[3]) +#define DISTANCE_PLANE_POINT(plane, point) (VEC_DOT(plane, point) - plane[3]) -#define PROJECT_POINT_PLANE(point,plane,projected) {\ - GREAL _dis;\ - _dis = DISTANCE_PLANE_POINT(plane,point);\ - VEC_SCALE(projected,-_dis,plane);\ - VEC_SUM(projected,projected,point); \ -}\ +#define PROJECT_POINT_PLANE(point, plane, projected) \ + { \ + GREAL _dis; \ + _dis = DISTANCE_PLANE_POINT(plane, point); \ + VEC_SCALE(projected, -_dis, plane); \ + VEC_SUM(projected, projected, point); \ + } //! Verifies if a point is in the plane hull -template +template SIMD_FORCE_INLINE bool POINT_IN_HULL( - const CLASS_POINT& point,const CLASS_PLANE * planes,GUINT plane_count) + const CLASS_POINT &point, const CLASS_PLANE *planes, GUINT plane_count) { GREAL _dis; - for (GUINT _i = 0;_i< plane_count;++_i) + for (GUINT _i = 0; _i < plane_count; ++_i) { - _dis = DISTANCE_PLANE_POINT(planes[_i],point); - if(_dis>0.0f) return false; + _dis = DISTANCE_PLANE_POINT(planes[_i], point); + if (_dis > 0.0f) return false; } return true; } -template +template SIMD_FORCE_INLINE void PLANE_CLIP_SEGMENT( - const CLASS_POINT& s1, - const CLASS_POINT &s2,const CLASS_PLANE &plane,CLASS_POINT &clipped) + const CLASS_POINT &s1, + const CLASS_POINT &s2, const CLASS_PLANE &plane, CLASS_POINT &clipped) { - GREAL _dis1,_dis2; - _dis1 = DISTANCE_PLANE_POINT(plane,s1); - VEC_DIFF(clipped,s2,s1); - _dis2 = VEC_DOT(clipped,plane); - VEC_SCALE(clipped,-_dis1/_dis2,clipped); - VEC_SUM(clipped,clipped,s1); + GREAL _dis1, _dis2; + _dis1 = DISTANCE_PLANE_POINT(plane, s1); + VEC_DIFF(clipped, s2, s1); + _dis2 = VEC_DOT(clipped, plane); + VEC_SCALE(clipped, -_dis1 / _dis2, clipped); + VEC_SUM(clipped, clipped, s1); } enum ePLANE_INTERSECTION_TYPE @@ -152,30 +153,30 @@ intersection type must have the following values */ -template +template SIMD_FORCE_INLINE eLINE_PLANE_INTERSECTION_TYPE PLANE_CLIP_SEGMENT2( - const CLASS_POINT& s1, + const CLASS_POINT &s1, const CLASS_POINT &s2, - const CLASS_PLANE &plane,CLASS_POINT &clipped) + const CLASS_PLANE &plane, CLASS_POINT &clipped) { - GREAL _dis1 = DISTANCE_PLANE_POINT(plane,s1); - GREAL _dis2 = DISTANCE_PLANE_POINT(plane,s2); - if(_dis1 >-G_EPSILON && _dis2 >-G_EPSILON) + GREAL _dis1 = DISTANCE_PLANE_POINT(plane, s1); + GREAL _dis2 = DISTANCE_PLANE_POINT(plane, s2); + if (_dis1 > -G_EPSILON && _dis2 > -G_EPSILON) { - if(_dis1<_dis2) return G_FRONT_PLANE_S1; - return G_FRONT_PLANE_S2; + if (_dis1 < _dis2) return G_FRONT_PLANE_S1; + return G_FRONT_PLANE_S2; } - else if(_dis1 _dis2) return G_BACK_PLANE_S1; - return G_BACK_PLANE_S2; + if (_dis1 > _dis2) return G_BACK_PLANE_S1; + return G_BACK_PLANE_S2; } - VEC_DIFF(clipped,s2,s1); - _dis2 = VEC_DOT(clipped,plane); - VEC_SCALE(clipped,-_dis1/_dis2,clipped); - VEC_SUM(clipped,clipped,s1); - if(_dis1<_dis2) return G_COLLIDE_PLANE_S1; + VEC_DIFF(clipped, s2, s1); + _dis2 = VEC_DOT(clipped, plane); + VEC_SCALE(clipped, -_dis1 / _dis2, clipped); + VEC_SUM(clipped, clipped, s1); + if (_dis1 < _dis2) return G_COLLIDE_PLANE_S1; return G_COLLIDE_PLANE_S2; } @@ -194,43 +195,42 @@ intersection_type must have the following values
  • 5 : Segment collides plane, s2 in back */ -template +template SIMD_FORCE_INLINE eLINE_PLANE_INTERSECTION_TYPE PLANE_CLIP_SEGMENT_CLOSEST( - const CLASS_POINT& s1, + const CLASS_POINT &s1, const CLASS_POINT &s2, const CLASS_PLANE &plane, - CLASS_POINT &clipped1,CLASS_POINT &clipped2) + CLASS_POINT &clipped1, CLASS_POINT &clipped2) { - eLINE_PLANE_INTERSECTION_TYPE intersection_type = PLANE_CLIP_SEGMENT2(s1,s2,plane,clipped1); - switch(intersection_type) + eLINE_PLANE_INTERSECTION_TYPE intersection_type = PLANE_CLIP_SEGMENT2(s1, s2, plane, clipped1); + switch (intersection_type) { - case G_FRONT_PLANE_S1: - VEC_COPY(clipped1,s1); - VEC_COPY(clipped2,s2); - break; - case G_FRONT_PLANE_S2: - VEC_COPY(clipped1,s2); - VEC_COPY(clipped2,s1); - break; - case G_BACK_PLANE_S1: - VEC_COPY(clipped1,s1); - VEC_COPY(clipped2,s2); - break; - case G_BACK_PLANE_S2: - VEC_COPY(clipped1,s2); - VEC_COPY(clipped2,s1); - break; - case G_COLLIDE_PLANE_S1: - VEC_COPY(clipped2,s1); - break; - case G_COLLIDE_PLANE_S2: - VEC_COPY(clipped2,s2); - break; + case G_FRONT_PLANE_S1: + VEC_COPY(clipped1, s1); + VEC_COPY(clipped2, s2); + break; + case G_FRONT_PLANE_S2: + VEC_COPY(clipped1, s2); + VEC_COPY(clipped2, s1); + break; + case G_BACK_PLANE_S1: + VEC_COPY(clipped1, s1); + VEC_COPY(clipped2, s2); + break; + case G_BACK_PLANE_S2: + VEC_COPY(clipped1, s2); + VEC_COPY(clipped2, s1); + break; + case G_COLLIDE_PLANE_S1: + VEC_COPY(clipped2, s1); + break; + case G_COLLIDE_PLANE_S2: + VEC_COPY(clipped2, s2); + break; } return intersection_type; } - //! Finds the 2 smallest cartesian coordinates of a plane normal #define PLANE_MINOR_AXES(plane, i0, i1) VEC_MINOR_AXES(plane, i0, i1) @@ -239,23 +239,23 @@ SIMD_FORCE_INLINE eLINE_PLANE_INTERSECTION_TYPE PLANE_CLIP_SEGMENT_CLOSEST( Intersects plane in one way only. The ray must face the plane (normals must be in opossite directions).
    It uses the PLANEDIREPSILON constant. */ -template +template SIMD_FORCE_INLINE bool RAY_PLANE_COLLISION( - const CLASS_PLANE & plane, - const CLASS_POINT & vDir, - const CLASS_POINT & vPoint, - CLASS_POINT & pout,T &tparam) + const CLASS_PLANE &plane, + const CLASS_POINT &vDir, + const CLASS_POINT &vPoint, + CLASS_POINT &pout, T &tparam) { - GREAL _dis,_dotdir; - _dotdir = VEC_DOT(plane,vDir); - if(_dotdir +template SIMD_FORCE_INLINE GUINT LINE_PLANE_COLLISION( - const CLASS_PLANE & plane, - const CLASS_POINT & vDir, - const CLASS_POINT & vPoint, - CLASS_POINT & pout, + const CLASS_PLANE &plane, + const CLASS_POINT &vDir, + const CLASS_POINT &vPoint, + CLASS_POINT &pout, T &tparam, T tmin, T tmax) { - GREAL _dis,_dotdir; - _dotdir = VEC_DOT(plane,vDir); - if(btFabs(_dotdir)tmax) + else if (tparam > tmax) { returnvalue = 0; tparam = tmax; } - VEC_SCALE(pout,tparam,vDir); - VEC_SUM(pout,vPoint,pout); + VEC_SCALE(pout, tparam, vDir); + VEC_SUM(pout, vPoint, pout); return returnvalue; } @@ -312,24 +312,24 @@ SIMD_FORCE_INLINE GUINT LINE_PLANE_COLLISION( \return true if the planes intersect, 0 if paralell. */ -template +template SIMD_FORCE_INLINE bool INTERSECT_PLANES( - const CLASS_PLANE &p1, - const CLASS_PLANE &p2, - CLASS_POINT &p, - CLASS_POINT &d) + const CLASS_PLANE &p1, + const CLASS_PLANE &p2, + CLASS_POINT &p, + CLASS_POINT &d) { - VEC_CROSS(d,p1,p2); - GREAL denom = VEC_DOT(d, d); - if(GIM_IS_ZERO(denom)) return false; + VEC_CROSS(d, p1, p2); + GREAL denom = VEC_DOT(d, d); + if (GIM_IS_ZERO(denom)) return false; vec3f _n; - _n[0]=p1[3]*p2[0] - p2[3]*p1[0]; - _n[1]=p1[3]*p2[1] - p2[3]*p1[1]; - _n[2]=p1[3]*p2[2] - p2[3]*p1[2]; - VEC_CROSS(p,_n,d); - p[0]/=denom; - p[1]/=denom; - p[2]/=denom; + _n[0] = p1[3] * p2[0] - p2[3] * p1[0]; + _n[1] = p1[3] * p2[1] - p2[3] * p1[1]; + _n[2] = p1[3] * p2[2] - p2[3] * p1[2]; + VEC_CROSS(p, _n, d); + p[0] /= denom; + p[1] /= denom; + p[2] /= denom; return true; } @@ -337,32 +337,31 @@ SIMD_FORCE_INLINE bool INTERSECT_PLANES( /*! Finds the closest point(cp) to (v) on a segment (e1,e2) */ -template +template SIMD_FORCE_INLINE void CLOSEST_POINT_ON_SEGMENT( - CLASS_POINT & cp, const CLASS_POINT & v, - const CLASS_POINT &e1,const CLASS_POINT &e2) + CLASS_POINT &cp, const CLASS_POINT &v, + const CLASS_POINT &e1, const CLASS_POINT &e2) { - vec3f _n; - VEC_DIFF(_n,e2,e1); - VEC_DIFF(cp,v,e1); + vec3f _n; + VEC_DIFF(_n, e2, e1); + VEC_DIFF(cp, v, e1); GREAL _scalar = VEC_DOT(cp, _n); - _scalar/= VEC_DOT(_n, _n); - if(_scalar <0.0f) + _scalar /= VEC_DOT(_n, _n); + if (_scalar < 0.0f) { - VEC_COPY(cp,e1); + VEC_COPY(cp, e1); } - else if(_scalar >1.0f) + else if (_scalar > 1.0f) { - VEC_COPY(cp,e2); + VEC_COPY(cp, e2); } else { - VEC_SCALE(cp,_scalar,_n); - VEC_SUM(cp,cp,e1); + VEC_SCALE(cp, _scalar, _n); + VEC_SUM(cp, cp, e1); } } - /*! \brief Finds the line params where these lines intersect. \param dir1 Direction of line 1 @@ -374,118 +373,114 @@ SIMD_FORCE_INLINE void CLOSEST_POINT_ON_SEGMENT( \param dointersect 0 if the lines won't intersect, else 1 */ -template +template SIMD_FORCE_INLINE bool LINE_INTERSECTION_PARAMS( - const CLASS_POINT & dir1, - CLASS_POINT & point1, - const CLASS_POINT & dir2, - CLASS_POINT & point2, - T& t1,T& t2) + const CLASS_POINT &dir1, + CLASS_POINT &point1, + const CLASS_POINT &dir2, + CLASS_POINT &point2, + T &t1, T &t2) { - GREAL det; - GREAL e1e1 = VEC_DOT(dir1,dir1); - GREAL e1e2 = VEC_DOT(dir1,dir2); - GREAL e2e2 = VEC_DOT(dir2,dir2); + GREAL det; + GREAL e1e1 = VEC_DOT(dir1, dir1); + GREAL e1e2 = VEC_DOT(dir1, dir2); + GREAL e2e2 = VEC_DOT(dir2, dir2); vec3f p1p2; - VEC_DIFF(p1p2,point1,point2); - GREAL p1p2e1 = VEC_DOT(p1p2,dir1); - GREAL p1p2e2 = VEC_DOT(p1p2,dir2); - det = e1e2*e1e2 - e1e1*e2e2; - if(GIM_IS_ZERO(det)) return false; - t1 = (e1e2*p1p2e2 - e2e2*p1p2e1)/det; - t2 = (e1e1*p1p2e2 - e1e2*p1p2e1)/det; + VEC_DIFF(p1p2, point1, point2); + GREAL p1p2e1 = VEC_DOT(p1p2, dir1); + GREAL p1p2e2 = VEC_DOT(p1p2, dir2); + det = e1e2 * e1e2 - e1e1 * e2e2; + if (GIM_IS_ZERO(det)) return false; + t1 = (e1e2 * p1p2e2 - e2e2 * p1p2e1) / det; + t2 = (e1e1 * p1p2e2 - e1e2 * p1p2e1) / det; return true; } //! Find closest points on segments -template +template SIMD_FORCE_INLINE void SEGMENT_COLLISION( - const CLASS_POINT & vA1, - const CLASS_POINT & vA2, - const CLASS_POINT & vB1, - const CLASS_POINT & vB2, - CLASS_POINT & vPointA, - CLASS_POINT & vPointB) + const CLASS_POINT &vA1, + const CLASS_POINT &vA2, + const CLASS_POINT &vB1, + const CLASS_POINT &vB2, + CLASS_POINT &vPointA, + CLASS_POINT &vPointB) { - CLASS_POINT _AD,_BD,n; - vec4f _M;//plane - VEC_DIFF(_AD,vA2,vA1); - VEC_DIFF(_BD,vB2,vB1); - VEC_CROSS(n,_AD,_BD); - GREAL _tp = VEC_DOT(n,n); - if(_tp_M[1]) - { - invert_b_order = true; - GIM_SWAP_NUMBERS(_M[0],_M[1]); - } - _M[2] = VEC_DOT(vA1,_AD); - _M[3] = VEC_DOT(vA2,_AD); - //mid points - n[0] = (_M[0]+_M[1])*0.5f; - n[1] = (_M[2]+_M[3])*0.5f; + CLASS_POINT _AD, _BD, n; + vec4f _M; //plane + VEC_DIFF(_AD, vA2, vA1); + VEC_DIFF(_BD, vB2, vB1); + VEC_CROSS(n, _AD, _BD); + GREAL _tp = VEC_DOT(n, n); + if (_tp < G_EPSILON) //ARE PARALELE + { + //project B over A + bool invert_b_order = false; + _M[0] = VEC_DOT(vB1, _AD); + _M[1] = VEC_DOT(vB2, _AD); + if (_M[0] > _M[1]) + { + invert_b_order = true; + GIM_SWAP_NUMBERS(_M[0], _M[1]); + } + _M[2] = VEC_DOT(vA1, _AD); + _M[3] = VEC_DOT(vA2, _AD); + //mid points + n[0] = (_M[0] + _M[1]) * 0.5f; + n[1] = (_M[2] + _M[3]) * 0.5f; - if(n[0] -SIMD_FORCE_INLINE bool BOX_AXIS_INTERSECT(T pos, T dir,T bmin, T bmax, T & tfirst, T & tlast) +template +SIMD_FORCE_INLINE bool BOX_AXIS_INTERSECT(T pos, T dir, T bmin, T bmax, T &tfirst, T &tlast) { - if(GIM_IS_ZERO(dir)) + if (GIM_IS_ZERO(dir)) { - return !(pos < bmin || pos > bmax); + return !(pos < bmin || pos > bmax); } GREAL a0 = (bmin - pos) / dir; GREAL a1 = (bmax - pos) / dir; - if(a0 > a1) GIM_SWAP_NUMBERS(a0, a1); + if (a0 > a1) GIM_SWAP_NUMBERS(a0, a1); tfirst = GIM_MAX(a0, tfirst); tlast = GIM_MIN(a1, tlast); if (tlast < tfirst) return false; return true; } - //! Sorts 3 componets -template +template SIMD_FORCE_INLINE void SORT_3_INDICES( - const T * values, - GUINT * order_indices) + const T *values, + GUINT *order_indices) { //get minimum order_indices[0] = values[0] < values[1] ? (values[0] < values[2] ? 0 : 2) : (values[1] < values[2] ? 1 : 2); //get second and third - GUINT i0 = (order_indices[0] + 1)%3; - GUINT i1 = (i0 + 1)%3; + GUINT i0 = (order_indices[0] + 1) % 3; + GUINT i1 = (i0 + 1) % 3; - if(values[i0] < values[i1]) + if (values[i0] < values[i1]) { order_indices[1] = i0; order_indices[2] = i1; @@ -539,8 +533,4 @@ SIMD_FORCE_INLINE void SORT_3_INDICES( } } - - - - -#endif // GIM_VECTOR_H_INCLUDED +#endif // GIM_VECTOR_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/gim_bitset.h b/src/BulletCollision/Gimpact/gim_bitset.h index 7dee48a4c..c1fb41a5c 100644 --- a/src/BulletCollision/Gimpact/gim_bitset.h +++ b/src/BulletCollision/Gimpact/gim_bitset.h @@ -34,34 +34,32 @@ email: projectileman@yahoo.com #include "gim_array.h" - #define GUINT_BIT_COUNT 32 #define GUINT_EXPONENT 5 class gim_bitset { public: - gim_array m_container; + gim_array m_container; - gim_bitset() - { + gim_bitset() + { + } - } + gim_bitset(GUINT bits_count) + { + resize(bits_count); + } - gim_bitset(GUINT bits_count) - { - resize(bits_count); - } - - ~gim_bitset() - { - } + ~gim_bitset() + { + } inline bool resize(GUINT newsize) { GUINT oldsize = m_container.size(); - m_container.resize(newsize/GUINT_BIT_COUNT + 1,false); - while(oldsize=size()) + if (bit_index >= size()) { resize(bit_index); } - m_container[bit_index >> GUINT_EXPONENT] |= (1 << (bit_index & (GUINT_BIT_COUNT-1))); + m_container[bit_index >> GUINT_EXPONENT] |= (1 << (bit_index & (GUINT_BIT_COUNT - 1))); } ///Return 0 or 1 inline char get(GUINT bit_index) { - if(bit_index>=size()) + if (bit_index >= size()) { return 0; } char value = m_container[bit_index >> GUINT_EXPONENT] & - (1 << (bit_index & (GUINT_BIT_COUNT-1))); + (1 << (bit_index & (GUINT_BIT_COUNT - 1))); return value; } inline void clear(GUINT bit_index) { - m_container[bit_index >> GUINT_EXPONENT] &= ~(1 << (bit_index & (GUINT_BIT_COUNT-1))); + m_container[bit_index >> GUINT_EXPONENT] &= ~(1 << (bit_index & (GUINT_BIT_COUNT - 1))); } }; - - - - -#endif // GIM_CONTAINERS_H_INCLUDED +#endif // GIM_CONTAINERS_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/gim_box_collision.h b/src/BulletCollision/Gimpact/gim_box_collision.h index a051b4fdb..9f7cbe732 100644 --- a/src/BulletCollision/Gimpact/gim_box_collision.h +++ b/src/BulletCollision/Gimpact/gim_box_collision.h @@ -35,8 +35,6 @@ email: projectileman@yahoo.com #include "gim_basic_geometry_operations.h" #include "LinearMath/btTransform.h" - - //SIMD_FORCE_INLINE bool test_cross_edge_box( // const btVector3 & edge, // const btVector3 & absolute_edge, @@ -99,52 +97,50 @@ email: projectileman@yahoo.com #ifndef TEST_CROSS_EDGE_BOX_MCR -#define TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,i_dir_0,i_dir_1,i_comp_0,i_comp_1)\ -{\ - const btScalar dir0 = -edge[i_dir_0];\ - const btScalar dir1 = edge[i_dir_1];\ - btScalar pmin = pointa[i_comp_0]*dir0 + pointa[i_comp_1]*dir1;\ - btScalar pmax = pointb[i_comp_0]*dir0 + pointb[i_comp_1]*dir1;\ - if(pmin>pmax)\ - {\ - GIM_SWAP_NUMBERS(pmin,pmax); \ - }\ - const btScalar abs_dir0 = absolute_edge[i_dir_0];\ - const btScalar abs_dir1 = absolute_edge[i_dir_1];\ - const btScalar rad = _extend[i_comp_0] * abs_dir0 + _extend[i_comp_1] * abs_dir1;\ - if(pmin>rad || -rad>pmax) return false;\ -}\ +#define TEST_CROSS_EDGE_BOX_MCR(edge, absolute_edge, pointa, pointb, _extend, i_dir_0, i_dir_1, i_comp_0, i_comp_1) \ + { \ + const btScalar dir0 = -edge[i_dir_0]; \ + const btScalar dir1 = edge[i_dir_1]; \ + btScalar pmin = pointa[i_comp_0] * dir0 + pointa[i_comp_1] * dir1; \ + btScalar pmax = pointb[i_comp_0] * dir0 + pointb[i_comp_1] * dir1; \ + if (pmin > pmax) \ + { \ + GIM_SWAP_NUMBERS(pmin, pmax); \ + } \ + const btScalar abs_dir0 = absolute_edge[i_dir_0]; \ + const btScalar abs_dir1 = absolute_edge[i_dir_1]; \ + const btScalar rad = _extend[i_comp_0] * abs_dir0 + _extend[i_comp_1] * abs_dir1; \ + if (pmin > rad || -rad > pmax) return false; \ + } #endif -#define TEST_CROSS_EDGE_BOX_X_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\ -{\ - TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,2,1,1,2);\ -}\ - -#define TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\ -{\ - TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,0,2,2,0);\ -}\ - -#define TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\ -{\ - TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,1,0,0,1);\ -}\ +#define TEST_CROSS_EDGE_BOX_X_AXIS_MCR(edge, absolute_edge, pointa, pointb, _extend) \ + { \ + TEST_CROSS_EDGE_BOX_MCR(edge, absolute_edge, pointa, pointb, _extend, 2, 1, 1, 2); \ + } +#define TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(edge, absolute_edge, pointa, pointb, _extend) \ + { \ + TEST_CROSS_EDGE_BOX_MCR(edge, absolute_edge, pointa, pointb, _extend, 0, 2, 2, 0); \ + } +#define TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(edge, absolute_edge, pointa, pointb, _extend) \ + { \ + TEST_CROSS_EDGE_BOX_MCR(edge, absolute_edge, pointa, pointb, _extend, 1, 0, 0, 1); \ + } //! Class for transforming a model1 to the space of model0 class GIM_BOX_BOX_TRANSFORM_CACHE { public: - btVector3 m_T1to0;//!< Transforms translation of model1 to model 0 - btMatrix3x3 m_R1to0;//!< Transforms Rotation of model1 to model 0, equal to R0' * R1 - btMatrix3x3 m_AR;//!< Absolute value of m_R1to0 + btVector3 m_T1to0; //!< Transforms translation of model1 to model 0 + btMatrix3x3 m_R1to0; //!< Transforms Rotation of model1 to model 0, equal to R0' * R1 + btMatrix3x3 m_AR; //!< Absolute value of m_R1to0 SIMD_FORCE_INLINE void calc_absolute_matrix() { - static const btVector3 vepsi(1e-6f,1e-6f,1e-6f); + static const btVector3 vepsi(1e-6f, 1e-6f, 1e-6f); m_AR[0] = vepsi + m_R1to0[0].absolute(); m_AR[1] = vepsi + m_R1to0[1].absolute(); m_AR[2] = vepsi + m_R1to0[2].absolute(); @@ -154,42 +150,40 @@ public: { } - - GIM_BOX_BOX_TRANSFORM_CACHE(mat4f trans1_to_0) + GIM_BOX_BOX_TRANSFORM_CACHE(mat4f trans1_to_0) { - COPY_MATRIX_3X3(m_R1to0,trans1_to_0) - MAT_GET_TRANSLATION(trans1_to_0,m_T1to0) + COPY_MATRIX_3X3(m_R1to0, trans1_to_0) + MAT_GET_TRANSLATION(trans1_to_0, m_T1to0) calc_absolute_matrix(); } //! Calc the transformation relative 1 to 0. Inverts matrics by transposing - SIMD_FORCE_INLINE void calc_from_homogenic(const btTransform & trans0,const btTransform & trans1) + SIMD_FORCE_INLINE void calc_from_homogenic(const btTransform &trans0, const btTransform &trans1) { - m_R1to0 = trans0.getBasis().transpose(); m_T1to0 = m_R1to0 * (-trans0.getOrigin()); - m_T1to0 += m_R1to0*trans1.getOrigin(); + m_T1to0 += m_R1to0 * trans1.getOrigin(); m_R1to0 *= trans1.getBasis(); calc_absolute_matrix(); } //! Calcs the full invertion of the matrices. Useful for scaling matrices - SIMD_FORCE_INLINE void calc_from_full_invert(const btTransform & trans0,const btTransform & trans1) + SIMD_FORCE_INLINE void calc_from_full_invert(const btTransform &trans0, const btTransform &trans1) { m_R1to0 = trans0.getBasis().inverse(); m_T1to0 = m_R1to0 * (-trans0.getOrigin()); - m_T1to0 += m_R1to0*trans1.getOrigin(); + m_T1to0 += m_R1to0 * trans1.getOrigin(); m_R1to0 *= trans1.getBasis(); calc_absolute_matrix(); } - SIMD_FORCE_INLINE btVector3 transform(const btVector3 & point) + SIMD_FORCE_INLINE btVector3 transform(const btVector3 &point) { - return point.dot3(m_R1to0[0], m_R1to0[1], m_R1to0[2]) + m_T1to0; + return point.dot3(m_R1to0[0], m_R1to0[1], m_R1to0[2]) + m_T1to0; } }; @@ -205,34 +199,34 @@ public: btVector3 m_max; GIM_AABB() - {} - - - GIM_AABB(const btVector3 & V1, - const btVector3 & V2, - const btVector3 & V3) { - m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]); - m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]); - m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]); - - m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]); - m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]); - m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]); } - GIM_AABB(const btVector3 & V1, - const btVector3 & V2, - const btVector3 & V3, + GIM_AABB(const btVector3 &V1, + const btVector3 &V2, + const btVector3 &V3) + { + m_min[0] = GIM_MIN3(V1[0], V2[0], V3[0]); + m_min[1] = GIM_MIN3(V1[1], V2[1], V3[1]); + m_min[2] = GIM_MIN3(V1[2], V2[2], V3[2]); + + m_max[0] = GIM_MAX3(V1[0], V2[0], V3[0]); + m_max[1] = GIM_MAX3(V1[1], V2[1], V3[1]); + m_max[2] = GIM_MAX3(V1[2], V2[2], V3[2]); + } + + GIM_AABB(const btVector3 &V1, + const btVector3 &V2, + const btVector3 &V3, GREAL margin) { - m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]); - m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]); - m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]); + m_min[0] = GIM_MIN3(V1[0], V2[0], V3[0]); + m_min[1] = GIM_MIN3(V1[1], V2[1], V3[1]); + m_min[2] = GIM_MIN3(V1[2], V2[2], V3[2]); - m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]); - m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]); - m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]); + m_max[0] = GIM_MAX3(V1[0], V2[0], V3[0]); + m_max[1] = GIM_MAX3(V1[1], V2[1], V3[1]); + m_max[2] = GIM_MAX3(V1[2], V2[2], V3[2]); m_min[0] -= margin; m_min[1] -= margin; @@ -242,13 +236,11 @@ public: m_max[2] += margin; } - GIM_AABB(const GIM_AABB &other): - m_min(other.m_min),m_max(other.m_max) + GIM_AABB(const GIM_AABB &other) : m_min(other.m_min), m_max(other.m_max) { } - GIM_AABB(const GIM_AABB &other,btScalar margin ): - m_min(other.m_min),m_max(other.m_max) + GIM_AABB(const GIM_AABB &other, btScalar margin) : m_min(other.m_min), m_max(other.m_max) { m_min[0] -= margin; m_min[1] -= margin; @@ -289,34 +281,34 @@ public: m_max[2] = other.m_max[2] + margin; } - template + template SIMD_FORCE_INLINE void calc_from_triangle( - const CLASS_POINT & V1, - const CLASS_POINT & V2, - const CLASS_POINT & V3) + const CLASS_POINT &V1, + const CLASS_POINT &V2, + const CLASS_POINT &V3) { - m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]); - m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]); - m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]); + m_min[0] = GIM_MIN3(V1[0], V2[0], V3[0]); + m_min[1] = GIM_MIN3(V1[1], V2[1], V3[1]); + m_min[2] = GIM_MIN3(V1[2], V2[2], V3[2]); - m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]); - m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]); - m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]); + m_max[0] = GIM_MAX3(V1[0], V2[0], V3[0]); + m_max[1] = GIM_MAX3(V1[1], V2[1], V3[1]); + m_max[2] = GIM_MAX3(V1[2], V2[2], V3[2]); } - template + template SIMD_FORCE_INLINE void calc_from_triangle_margin( - const CLASS_POINT & V1, - const CLASS_POINT & V2, - const CLASS_POINT & V3, btScalar margin) + const CLASS_POINT &V1, + const CLASS_POINT &V2, + const CLASS_POINT &V3, btScalar margin) { - m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]); - m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]); - m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]); + m_min[0] = GIM_MIN3(V1[0], V2[0], V3[0]); + m_min[1] = GIM_MIN3(V1[1], V2[1], V3[1]); + m_min[2] = GIM_MIN3(V1[2], V2[2], V3[2]); - m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]); - m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]); - m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]); + m_max[0] = GIM_MAX3(V1[0], V2[0], V3[0]); + m_max[1] = GIM_MAX3(V1[1], V2[1], V3[1]); + m_max[2] = GIM_MAX3(V1[2], V2[2], V3[2]); m_min[0] -= margin; m_min[1] -= margin; @@ -327,74 +319,73 @@ public: } //! Apply a transform to an AABB - SIMD_FORCE_INLINE void appy_transform(const btTransform & trans) + SIMD_FORCE_INLINE void appy_transform(const btTransform &trans) { - btVector3 center = (m_max+m_min)*0.5f; + btVector3 center = (m_max + m_min) * 0.5f; btVector3 extends = m_max - center; // Compute new center center = trans(center); - btVector3 textends = extends.dot3(trans.getBasis().getRow(0).absolute(), - trans.getBasis().getRow(1).absolute(), - trans.getBasis().getRow(2).absolute()); - + btVector3 textends = extends.dot3(trans.getBasis().getRow(0).absolute(), + trans.getBasis().getRow(1).absolute(), + trans.getBasis().getRow(2).absolute()); + m_min = center - textends; m_max = center + textends; } //! Merges a Box - SIMD_FORCE_INLINE void merge(const GIM_AABB & box) + SIMD_FORCE_INLINE void merge(const GIM_AABB &box) { - m_min[0] = GIM_MIN(m_min[0],box.m_min[0]); - m_min[1] = GIM_MIN(m_min[1],box.m_min[1]); - m_min[2] = GIM_MIN(m_min[2],box.m_min[2]); + m_min[0] = GIM_MIN(m_min[0], box.m_min[0]); + m_min[1] = GIM_MIN(m_min[1], box.m_min[1]); + m_min[2] = GIM_MIN(m_min[2], box.m_min[2]); - m_max[0] = GIM_MAX(m_max[0],box.m_max[0]); - m_max[1] = GIM_MAX(m_max[1],box.m_max[1]); - m_max[2] = GIM_MAX(m_max[2],box.m_max[2]); + m_max[0] = GIM_MAX(m_max[0], box.m_max[0]); + m_max[1] = GIM_MAX(m_max[1], box.m_max[1]); + m_max[2] = GIM_MAX(m_max[2], box.m_max[2]); } //! Merges a point - template - SIMD_FORCE_INLINE void merge_point(const CLASS_POINT & point) + template + SIMD_FORCE_INLINE void merge_point(const CLASS_POINT &point) { - m_min[0] = GIM_MIN(m_min[0],point[0]); - m_min[1] = GIM_MIN(m_min[1],point[1]); - m_min[2] = GIM_MIN(m_min[2],point[2]); + m_min[0] = GIM_MIN(m_min[0], point[0]); + m_min[1] = GIM_MIN(m_min[1], point[1]); + m_min[2] = GIM_MIN(m_min[2], point[2]); - m_max[0] = GIM_MAX(m_max[0],point[0]); - m_max[1] = GIM_MAX(m_max[1],point[1]); - m_max[2] = GIM_MAX(m_max[2],point[2]); + m_max[0] = GIM_MAX(m_max[0], point[0]); + m_max[1] = GIM_MAX(m_max[1], point[1]); + m_max[2] = GIM_MAX(m_max[2], point[2]); } //! Gets the extend and center - SIMD_FORCE_INLINE void get_center_extend(btVector3 & center,btVector3 & extend) const + SIMD_FORCE_INLINE void get_center_extend(btVector3 ¢er, btVector3 &extend) const { - center = (m_max+m_min)*0.5f; + center = (m_max + m_min) * 0.5f; extend = m_max - center; } //! Finds the intersecting box between this box and the other. - SIMD_FORCE_INLINE void find_intersection(const GIM_AABB & other, GIM_AABB & intersection) const + SIMD_FORCE_INLINE void find_intersection(const GIM_AABB &other, GIM_AABB &intersection) const { - intersection.m_min[0] = GIM_MAX(other.m_min[0],m_min[0]); - intersection.m_min[1] = GIM_MAX(other.m_min[1],m_min[1]); - intersection.m_min[2] = GIM_MAX(other.m_min[2],m_min[2]); + intersection.m_min[0] = GIM_MAX(other.m_min[0], m_min[0]); + intersection.m_min[1] = GIM_MAX(other.m_min[1], m_min[1]); + intersection.m_min[2] = GIM_MAX(other.m_min[2], m_min[2]); - intersection.m_max[0] = GIM_MIN(other.m_max[0],m_max[0]); - intersection.m_max[1] = GIM_MIN(other.m_max[1],m_max[1]); - intersection.m_max[2] = GIM_MIN(other.m_max[2],m_max[2]); + intersection.m_max[0] = GIM_MIN(other.m_max[0], m_max[0]); + intersection.m_max[1] = GIM_MIN(other.m_max[1], m_max[1]); + intersection.m_max[2] = GIM_MIN(other.m_max[2], m_max[2]); } - - SIMD_FORCE_INLINE bool has_collision(const GIM_AABB & other) const + SIMD_FORCE_INLINE bool has_collision(const GIM_AABB &other) const { - if(m_min[0] > other.m_max[0] || - m_max[0] < other.m_min[0] || - m_min[1] > other.m_max[1] || - m_max[1] < other.m_min[1] || - m_min[2] > other.m_max[2] || - m_max[2] < other.m_min[2]) + if (m_min[0] > other.m_max[0] || + m_max[0] < other.m_min[0] || + m_min[1] > other.m_max[1] || + m_max[1] < other.m_min[1] || + m_min[2] > other.m_max[2] || + m_max[2] < other.m_min[2]) { return false; } @@ -406,35 +397,34 @@ public: \param vorigin A vec3f with the origin of the ray \param vdir A vec3f with the direction of the ray */ - SIMD_FORCE_INLINE bool collide_ray(const btVector3 & vorigin,const btVector3 & vdir) + SIMD_FORCE_INLINE bool collide_ray(const btVector3 &vorigin, const btVector3 &vdir) { - btVector3 extents,center; - this->get_center_extend(center,extents);; + btVector3 extents, center; + this->get_center_extend(center, extents); + ; btScalar Dx = vorigin[0] - center[0]; - if(GIM_GREATER(Dx, extents[0]) && Dx*vdir[0]>=0.0f) return false; + if (GIM_GREATER(Dx, extents[0]) && Dx * vdir[0] >= 0.0f) return false; btScalar Dy = vorigin[1] - center[1]; - if(GIM_GREATER(Dy, extents[1]) && Dy*vdir[1]>=0.0f) return false; + if (GIM_GREATER(Dy, extents[1]) && Dy * vdir[1] >= 0.0f) return false; btScalar Dz = vorigin[2] - center[2]; - if(GIM_GREATER(Dz, extents[2]) && Dz*vdir[2]>=0.0f) return false; - + if (GIM_GREATER(Dz, extents[2]) && Dz * vdir[2] >= 0.0f) return false; btScalar f = vdir[1] * Dz - vdir[2] * Dy; - if(btFabs(f) > extents[1]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[1])) return false; + if (btFabs(f) > extents[1] * btFabs(vdir[2]) + extents[2] * btFabs(vdir[1])) return false; f = vdir[2] * Dx - vdir[0] * Dz; - if(btFabs(f) > extents[0]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[0]))return false; + if (btFabs(f) > extents[0] * btFabs(vdir[2]) + extents[2] * btFabs(vdir[0])) return false; f = vdir[0] * Dy - vdir[1] * Dx; - if(btFabs(f) > extents[0]*btFabs(vdir[1]) + extents[1]*btFabs(vdir[0]))return false; + if (btFabs(f) > extents[0] * btFabs(vdir[1]) + extents[1] * btFabs(vdir[0])) return false; return true; } - - SIMD_FORCE_INLINE void projection_interval(const btVector3 & direction, btScalar &vmin, btScalar &vmax) const + SIMD_FORCE_INLINE void projection_interval(const btVector3 &direction, btScalar &vmin, btScalar &vmax) const { - btVector3 center = (m_max+m_min)*0.5f; - btVector3 extend = m_max-center; + btVector3 center = (m_max + m_min) * 0.5f; + btVector3 extend = m_max - center; - btScalar _fOrigin = direction.dot(center); + btScalar _fOrigin = direction.dot(center); btScalar _fMaximumExtent = extend.dot(direction.absolute()); vmin = _fOrigin - _fMaximumExtent; vmax = _fOrigin + _fMaximumExtent; @@ -442,22 +432,22 @@ public: SIMD_FORCE_INLINE ePLANE_INTERSECTION_TYPE plane_classify(const btVector4 &plane) const { - btScalar _fmin,_fmax; - this->projection_interval(plane,_fmin,_fmax); + btScalar _fmin, _fmax; + this->projection_interval(plane, _fmin, _fmax); - if(plane[3] > _fmax + BOX_PLANE_EPSILON) + if (plane[3] > _fmax + BOX_PLANE_EPSILON) { - return G_BACK_PLANE; // 0 + return G_BACK_PLANE; // 0 } - if(plane[3]+BOX_PLANE_EPSILON >=_fmin) + if (plane[3] + BOX_PLANE_EPSILON >= _fmin) { - return G_COLLIDE_PLANE; //1 + return G_COLLIDE_PLANE; //1 } - return G_FRONT_PLANE;//2 + return G_FRONT_PLANE; //2 } - SIMD_FORCE_INLINE bool overlapping_trans_conservative(const GIM_AABB & box, btTransform & trans1_to_0) + SIMD_FORCE_INLINE bool overlapping_trans_conservative(const GIM_AABB &box, btTransform &trans1_to_0) { GIM_AABB tbox = box; tbox.appy_transform(trans1_to_0); @@ -466,52 +456,50 @@ public: //! transcache is the transformation cache from box to this AABB SIMD_FORCE_INLINE bool overlapping_trans_cache( - const GIM_AABB & box,const GIM_BOX_BOX_TRANSFORM_CACHE & transcache, bool fulltest) + const GIM_AABB &box, const GIM_BOX_BOX_TRANSFORM_CACHE &transcache, bool fulltest) { - //Taken from OPCODE - btVector3 ea,eb;//extends - btVector3 ca,cb;//extends - get_center_extend(ca,ea); - box.get_center_extend(cb,eb); - + btVector3 ea, eb; //extends + btVector3 ca, cb; //extends + get_center_extend(ca, ea); + box.get_center_extend(cb, eb); btVector3 T; - btScalar t,t2; + btScalar t, t2; int i; // Class I : A's basis vectors - for(i=0;i<3;i++) + for (i = 0; i < 3; i++) { - T[i] = transcache.m_R1to0[i].dot(cb) + transcache.m_T1to0[i] - ca[i]; + T[i] = transcache.m_R1to0[i].dot(cb) + transcache.m_T1to0[i] - ca[i]; t = transcache.m_AR[i].dot(eb) + ea[i]; - if(GIM_GREATER(T[i], t)) return false; + if (GIM_GREATER(T[i], t)) return false; } // Class II : B's basis vectors - for(i=0;i<3;i++) + for (i = 0; i < 3; i++) { - t = MAT_DOT_COL(transcache.m_R1to0,T,i); - t2 = MAT_DOT_COL(transcache.m_AR,ea,i) + eb[i]; - if(GIM_GREATER(t,t2)) return false; + t = MAT_DOT_COL(transcache.m_R1to0, T, i); + t2 = MAT_DOT_COL(transcache.m_AR, ea, i) + eb[i]; + if (GIM_GREATER(t, t2)) return false; } // Class III : 9 cross products - if(fulltest) + if (fulltest) { - int j,m,n,o,p,q,r; - for(i=0;i<3;i++) + int j, m, n, o, p, q, r; + for (i = 0; i < 3; i++) { - m = (i+1)%3; - n = (i+2)%3; - o = i==0?1:0; - p = i==2?1:2; - for(j=0;j<3;j++) + m = (i + 1) % 3; + n = (i + 2) % 3; + o = i == 0 ? 1 : 0; + p = i == 2 ? 1 : 2; + for (j = 0; j < 3; j++) { - q = j==2?1:2; - r = j==0?1:0; - t = T[n]*transcache.m_R1to0[m][j] - T[m]*transcache.m_R1to0[n][j]; - t2 = ea[o]*transcache.m_AR[p][j] + ea[p]*transcache.m_AR[o][j] + - eb[r]*transcache.m_AR[i][q] + eb[q]*transcache.m_AR[i][r]; - if(GIM_GREATER(t,t2)) return false; + q = j == 2 ? 1 : 2; + r = j == 0 ? 1 : 0; + t = T[n] * transcache.m_R1to0[m][j] - T[m] * transcache.m_R1to0[n][j]; + t2 = ea[o] * transcache.m_AR[p][j] + ea[p] * transcache.m_AR[o][j] + + eb[r] * transcache.m_AR[i][q] + eb[q] * transcache.m_AR[i][r]; + if (GIM_GREATER(t, t2)) return false; } } } @@ -520,7 +508,7 @@ public: //! Simple test for planes. SIMD_FORCE_INLINE bool collide_plane( - const btVector4 & plane) + const btVector4 &plane) { ePLANE_INTERSECTION_TYPE classify = plane_classify(plane); return (classify == G_COLLIDE_PLANE); @@ -528,15 +516,15 @@ public: //! test for a triangle, with edges SIMD_FORCE_INLINE bool collide_triangle_exact( - const btVector3 & p1, - const btVector3 & p2, - const btVector3 & p3, - const btVector4 & triangle_plane) + const btVector3 &p1, + const btVector3 &p2, + const btVector3 &p3, + const btVector4 &triangle_plane) { - if(!collide_plane(triangle_plane)) return false; + if (!collide_plane(triangle_plane)) return false; - btVector3 center,extends; - this->get_center_extend(center,extends); + btVector3 center, extends; + this->get_center_extend(center, extends); const btVector3 v1(p1 - center); const btVector3 v2(p2 - center); @@ -546,30 +534,29 @@ public: btVector3 diff(v2 - v1); btVector3 abs_diff = diff.absolute(); //Test With X axis - TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v1,v3,extends); + TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff, abs_diff, v1, v3, extends); //Test With Y axis - TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v1,v3,extends); + TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff, abs_diff, v1, v3, extends); //Test With Z axis - TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v1,v3,extends); - + TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff, abs_diff, v1, v3, extends); diff = v3 - v2; abs_diff = diff.absolute(); //Test With X axis - TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v2,v1,extends); + TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff, abs_diff, v2, v1, extends); //Test With Y axis - TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v2,v1,extends); + TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff, abs_diff, v2, v1, extends); //Test With Z axis - TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v2,v1,extends); + TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff, abs_diff, v2, v1, extends); diff = v1 - v3; abs_diff = diff.absolute(); //Test With X axis - TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v3,v2,extends); + TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff, abs_diff, v3, v2, extends); //Test With Y axis - TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v3,v2,extends); + TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff, abs_diff, v3, v2, extends); //Test With Z axis - TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v3,v2,extends); + TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff, abs_diff, v3, v2, extends); return true; } @@ -577,17 +564,15 @@ public: #ifndef BT_BOX_COLLISION_H_INCLUDED //! Compairison of transformation objects -SIMD_FORCE_INLINE bool btCompareTransformsEqual(const btTransform & t1,const btTransform & t2) +SIMD_FORCE_INLINE bool btCompareTransformsEqual(const btTransform &t1, const btTransform &t2) { - if(!(t1.getOrigin() == t2.getOrigin()) ) return false; + if (!(t1.getOrigin() == t2.getOrigin())) return false; - if(!(t1.getBasis().getRow(0) == t2.getBasis().getRow(0)) ) return false; - if(!(t1.getBasis().getRow(1) == t2.getBasis().getRow(1)) ) return false; - if(!(t1.getBasis().getRow(2) == t2.getBasis().getRow(2)) ) return false; + if (!(t1.getBasis().getRow(0) == t2.getBasis().getRow(0))) return false; + if (!(t1.getBasis().getRow(1) == t2.getBasis().getRow(1))) return false; + if (!(t1.getBasis().getRow(2) == t2.getBasis().getRow(2))) return false; return true; } #endif - - -#endif // GIM_BOX_COLLISION_H_INCLUDED +#endif // GIM_BOX_COLLISION_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/gim_box_set.cpp b/src/BulletCollision/Gimpact/gim_box_set.cpp index 0c3d7ba8d..0c7a6b7fc 100644 --- a/src/BulletCollision/Gimpact/gim_box_set.cpp +++ b/src/BulletCollision/Gimpact/gim_box_set.cpp @@ -28,67 +28,64 @@ email: projectileman@yahoo.com ----------------------------------------------------------------------------- */ - #include "gim_box_set.h" - GUINT GIM_BOX_TREE::_calc_splitting_axis( - gim_array & primitive_boxes, GUINT startIndex, GUINT endIndex) + gim_array& primitive_boxes, GUINT startIndex, GUINT endIndex) { GUINT i; - btVector3 means(btScalar(0.),btScalar(0.),btScalar(0.)); - btVector3 variance(btScalar(0.),btScalar(0.),btScalar(0.)); - GUINT numIndices = endIndex-startIndex; + btVector3 means(btScalar(0.), btScalar(0.), btScalar(0.)); + btVector3 variance(btScalar(0.), btScalar(0.), btScalar(0.)); + GUINT numIndices = endIndex - startIndex; - for (i=startIndex;i & primitive_boxes, GUINT startIndex, + gim_array& primitive_boxes, GUINT startIndex, GUINT endIndex, GUINT splitAxis) { GUINT i; - GUINT splitIndex =startIndex; + GUINT splitIndex = startIndex; GUINT numIndices = endIndex - startIndex; // average of centers btScalar splitValue = 0.0f; - for (i=startIndex;i splitValue) { //swap - primitive_boxes.swap(i,splitIndex); + primitive_boxes.swap(i, splitIndex); splitIndex++; } } @@ -102,28 +99,27 @@ GUINT GIM_BOX_TREE::_sort_and_calc_splitting_index( //bool unbalanced2 = true; //this should be safe too: - GUINT rangeBalancedIndices = numIndices/3; - bool unbalanced = ((splitIndex<=(startIndex+rangeBalancedIndices)) || (splitIndex >=(endIndex-1-rangeBalancedIndices))); + GUINT rangeBalancedIndices = numIndices / 3; + bool unbalanced = ((splitIndex <= (startIndex + rangeBalancedIndices)) || (splitIndex >= (endIndex - 1 - rangeBalancedIndices))); if (unbalanced) { - splitIndex = startIndex+ (numIndices>>1); + splitIndex = startIndex + (numIndices >> 1); } - btAssert(!((splitIndex==startIndex) || (splitIndex == (endIndex)))); + btAssert(!((splitIndex == startIndex) || (splitIndex == (endIndex)))); return splitIndex; } - -void GIM_BOX_TREE::_build_sub_tree(gim_array & primitive_boxes, GUINT startIndex, GUINT endIndex) +void GIM_BOX_TREE::_build_sub_tree(gim_array& primitive_boxes, GUINT startIndex, GUINT endIndex) { GUINT current_index = m_num_nodes++; - btAssert((endIndex-startIndex)>0); + btAssert((endIndex - startIndex) > 0); - if((endIndex-startIndex) == 1) //we got a leaf - { + if ((endIndex - startIndex) == 1) //we got a leaf + { m_node_array[current_index].m_left = 0; m_node_array[current_index].m_right = 0; m_node_array[current_index].m_escapeIndex = 0; @@ -138,8 +134,8 @@ void GIM_BOX_TREE::_build_sub_tree(gim_array & primitive_boxes, G GUINT splitIndex; //calc this node bounding box - m_node_array[current_index].m_bound.invalidate(); - for (splitIndex=startIndex;splitIndex & primitive_boxes, G //calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'. //split axis - splitIndex = _calc_splitting_axis(primitive_boxes,startIndex,endIndex); + splitIndex = _calc_splitting_axis(primitive_boxes, startIndex, endIndex); splitIndex = _sort_and_calc_splitting_index( - primitive_boxes,startIndex,endIndex,splitIndex); + primitive_boxes, startIndex, endIndex, splitIndex); //configure this inner node : the left node index m_node_array[current_index].m_left = m_num_nodes; //build left child tree - _build_sub_tree(primitive_boxes, startIndex, splitIndex ); + _build_sub_tree(primitive_boxes, startIndex, splitIndex); //configure this inner node : the right node index m_node_array[current_index].m_right = m_num_nodes; //build right child tree - _build_sub_tree(primitive_boxes, splitIndex ,endIndex); + _build_sub_tree(primitive_boxes, splitIndex, endIndex); //configure this inner node : the escape index - m_node_array[current_index].m_escapeIndex = m_num_nodes - current_index; + m_node_array[current_index].m_escapeIndex = m_num_nodes - current_index; } //! stackless build tree void GIM_BOX_TREE::build_tree( - gim_array & primitive_boxes) + gim_array& primitive_boxes) { // initialize node count to 0 m_num_nodes = 0; // allocate nodes - m_node_array.resize(primitive_boxes.size()*2); - + m_node_array.resize(primitive_boxes.size() * 2); + _build_sub_tree(primitive_boxes, 0, primitive_boxes.size()); } - - diff --git a/src/BulletCollision/Gimpact/gim_box_set.h b/src/BulletCollision/Gimpact/gim_box_set.h index 61d190a7d..0522007e4 100644 --- a/src/BulletCollision/Gimpact/gim_box_set.h +++ b/src/BulletCollision/Gimpact/gim_box_set.h @@ -33,54 +33,51 @@ email: projectileman@yahoo.com ----------------------------------------------------------------------------- */ - #include "gim_array.h" #include "gim_radixsort.h" #include "gim_box_collision.h" #include "gim_tri_collision.h" - - //! Overlapping pair struct GIM_PAIR { - GUINT m_index1; - GUINT m_index2; - GIM_PAIR() - {} + GUINT m_index1; + GUINT m_index2; + GIM_PAIR() + { + } - GIM_PAIR(const GIM_PAIR & p) - { - m_index1 = p.m_index1; - m_index2 = p.m_index2; + GIM_PAIR(const GIM_PAIR& p) + { + m_index1 = p.m_index1; + m_index2 = p.m_index2; } GIM_PAIR(GUINT index1, GUINT index2) - { - m_index1 = index1; - m_index2 = index2; + { + m_index1 = index1; + m_index2 = index2; } }; //! A pairset array -class gim_pair_set: public gim_array +class gim_pair_set : public gim_array { public: - gim_pair_set():gim_array(32) + gim_pair_set() : gim_array(32) { } - inline void push_pair(GUINT index1,GUINT index2) + inline void push_pair(GUINT index1, GUINT index2) { - push_back(GIM_PAIR(index1,index2)); + push_back(GIM_PAIR(index1, index2)); } - inline void push_pair_inv(GUINT index1,GUINT index2) + inline void push_pair_inv(GUINT index1, GUINT index2) { - push_back(GIM_PAIR(index2,index1)); + push_back(GIM_PAIR(index2, index1)); } }; - //! Prototype Base class for primitive classification /*! This class is a wrapper for primitive collections. @@ -90,16 +87,14 @@ This class can manage Compound shapes and trimeshes, and if it is managing trime class GIM_PRIMITIVE_MANAGER_PROTOTYPE { public: - virtual ~GIM_PRIMITIVE_MANAGER_PROTOTYPE() {} //! determines if this manager consist on only triangles, which special case will be optimized virtual bool is_trimesh() = 0; virtual GUINT get_primitive_count() = 0; - virtual void get_primitive_box(GUINT prim_index ,GIM_AABB & primbox) = 0; - virtual void get_primitive_triangle(GUINT prim_index,GIM_TRIANGLE & triangle) = 0; + virtual void get_primitive_box(GUINT prim_index, GIM_AABB& primbox) = 0; + virtual void get_primitive_triangle(GUINT prim_index, GIM_TRIANGLE& triangle) = 0; }; - struct GIM_AABB_DATA { GIM_AABB m_bound; @@ -110,22 +105,22 @@ struct GIM_AABB_DATA struct GIM_BOX_TREE_NODE { GIM_AABB m_bound; - GUINT m_left;//!< Left subtree - GUINT m_right;//!< Right subtree - GUINT m_escapeIndex;//!< Scape index for traversing - GUINT m_data;//!< primitive index if apply + GUINT m_left; //!< Left subtree + GUINT m_right; //!< Right subtree + GUINT m_escapeIndex; //!< Scape index for traversing + GUINT m_data; //!< primitive index if apply GIM_BOX_TREE_NODE() { - m_left = 0; - m_right = 0; - m_escapeIndex = 0; - m_data = 0; + m_left = 0; + m_right = 0; + m_escapeIndex = 0; + m_data = 0; } SIMD_FORCE_INLINE bool is_leaf_node() const { - return (!m_left && !m_right); + return (!m_left && !m_right); } }; @@ -135,14 +130,16 @@ class GIM_BOX_TREE protected: GUINT m_num_nodes; gim_array m_node_array; + protected: GUINT _sort_and_calc_splitting_index( - gim_array & primitive_boxes, - GUINT startIndex, GUINT endIndex, GUINT splitAxis); + gim_array& primitive_boxes, + GUINT startIndex, GUINT endIndex, GUINT splitAxis); - GUINT _calc_splitting_axis(gim_array & primitive_boxes, GUINT startIndex, GUINT endIndex); + GUINT _calc_splitting_axis(gim_array& primitive_boxes, GUINT startIndex, GUINT endIndex); + + void _build_sub_tree(gim_array& primitive_boxes, GUINT startIndex, GUINT endIndex); - void _build_sub_tree(gim_array & primitive_boxes, GUINT startIndex, GUINT endIndex); public: GIM_BOX_TREE() { @@ -151,7 +148,7 @@ public: //! prototype functions for box tree management //!@{ - void build_tree(gim_array & primitive_boxes); + void build_tree(gim_array& primitive_boxes); SIMD_FORCE_INLINE void clearNodes() { @@ -176,22 +173,22 @@ public: return m_node_array[nodeindex].m_data; } - SIMD_FORCE_INLINE void getNodeBound(GUINT nodeindex, GIM_AABB & bound) const + SIMD_FORCE_INLINE void getNodeBound(GUINT nodeindex, GIM_AABB& bound) const { bound = m_node_array[nodeindex].m_bound; } - SIMD_FORCE_INLINE void setNodeBound(GUINT nodeindex, const GIM_AABB & bound) + SIMD_FORCE_INLINE void setNodeBound(GUINT nodeindex, const GIM_AABB& bound) { m_node_array[nodeindex].m_bound = bound; } - SIMD_FORCE_INLINE GUINT getLeftNodeIndex(GUINT nodeindex) const + SIMD_FORCE_INLINE GUINT getLeftNodeIndex(GUINT nodeindex) const { return m_node_array[nodeindex].m_left; } - SIMD_FORCE_INLINE GUINT getRightNodeIndex(GUINT nodeindex) const + SIMD_FORCE_INLINE GUINT getRightNodeIndex(GUINT nodeindex) const { return m_node_array[nodeindex].m_right; } @@ -204,78 +201,78 @@ public: //!@} }; - //! Generic Box Tree Template /*! This class offers an structure for managing a box tree of primitives. Requires a Primitive prototype (like GIM_PRIMITIVE_MANAGER_PROTOTYPE ) and a Box tree structure ( like GIM_BOX_TREE). */ -template +template class GIM_BOX_TREE_TEMPLATE_SET { protected: _GIM_PRIMITIVE_MANAGER_PROTOTYPE m_primitive_manager; _GIM_BOX_TREE_PROTOTYPE m_box_tree; + protected: //stackless refit SIMD_FORCE_INLINE void refit() { GUINT nodecount = getNodeCount(); - while(nodecount--) + while (nodecount--) { - if(isLeafNode(nodecount)) + if (isLeafNode(nodecount)) { GIM_AABB leafbox; - m_primitive_manager.get_primitive_box(getNodeData(nodecount),leafbox); - setNodeBound(nodecount,leafbox); + m_primitive_manager.get_primitive_box(getNodeData(nodecount), leafbox); + setNodeBound(nodecount, leafbox); } else { //get left bound GUINT childindex = getLeftNodeIndex(nodecount); GIM_AABB bound; - getNodeBound(childindex,bound); + getNodeBound(childindex, bound); //get right bound childindex = getRightNodeIndex(nodecount); GIM_AABB bound2; - getNodeBound(childindex,bound2); + getNodeBound(childindex, bound2); bound.merge(bound2); - setNodeBound(nodecount,bound); + setNodeBound(nodecount, bound); } } } -public: +public: GIM_BOX_TREE_TEMPLATE_SET() { } - SIMD_FORCE_INLINE GIM_AABB getGlobalBox() const + SIMD_FORCE_INLINE GIM_AABB getGlobalBox() const { GIM_AABB totalbox; getNodeBound(0, totalbox); return totalbox; } - SIMD_FORCE_INLINE void setPrimitiveManager(const _GIM_PRIMITIVE_MANAGER_PROTOTYPE & primitive_manager) + SIMD_FORCE_INLINE void setPrimitiveManager(const _GIM_PRIMITIVE_MANAGER_PROTOTYPE& primitive_manager) { m_primitive_manager = primitive_manager; } - const _GIM_PRIMITIVE_MANAGER_PROTOTYPE & getPrimitiveManager() const + const _GIM_PRIMITIVE_MANAGER_PROTOTYPE& getPrimitiveManager() const { return m_primitive_manager; } - _GIM_PRIMITIVE_MANAGER_PROTOTYPE & getPrimitiveManager() + _GIM_PRIMITIVE_MANAGER_PROTOTYPE& getPrimitiveManager() { return m_primitive_manager; } -//! node manager prototype functions -///@{ + //! node manager prototype functions + ///@{ //! this attemps to refit the box set. SIMD_FORCE_INLINE void update() @@ -288,19 +285,19 @@ public: { //obtain primitive boxes gim_array primitive_boxes; - primitive_boxes.resize(m_primitive_manager.get_primitive_count(),false); + primitive_boxes.resize(m_primitive_manager.get_primitive_count(), false); - for (GUINT i = 0;i & collided_results) const + SIMD_FORCE_INLINE bool boxQuery(const GIM_AABB& box, gim_array& collided_results) const { GUINT curIndex = 0; GUINT numNodes = getNodeCount(); @@ -308,7 +305,7 @@ public: while (curIndex < numNodes) { GIM_AABB bound; - getNodeBound(curIndex,bound); + getNodeBound(curIndex, bound); //catch bugs in tree data @@ -328,26 +325,26 @@ public: else { //skip node - curIndex+= getScapeNodeIndex(curIndex); + curIndex += getScapeNodeIndex(curIndex); } } - if(collided_results.size()>0) return true; + if (collided_results.size() > 0) return true; return false; } //! returns the indices of the primitives in the m_primitive_manager - SIMD_FORCE_INLINE bool boxQueryTrans(const GIM_AABB & box, - const btTransform & transform, gim_array & collided_results) const + SIMD_FORCE_INLINE bool boxQueryTrans(const GIM_AABB& box, + const btTransform& transform, gim_array& collided_results) const { - GIM_AABB transbox=box; + GIM_AABB transbox = box; transbox.appy_transform(transform); - return boxQuery(transbox,collided_results); + return boxQuery(transbox, collided_results); } //! returns the indices of the primitives in the m_primitive_manager SIMD_FORCE_INLINE bool rayQuery( - const btVector3 & ray_dir,const btVector3 & ray_origin , - gim_array & collided_results) const + const btVector3& ray_dir, const btVector3& ray_origin, + gim_array& collided_results) const { GUINT curIndex = 0; GUINT numNodes = getNodeCount(); @@ -355,16 +352,16 @@ public: while (curIndex < numNodes) { GIM_AABB bound; - getNodeBound(curIndex,bound); + getNodeBound(curIndex, bound); //catch bugs in tree data - bool aabbOverlap = bound.collide_ray(ray_origin,ray_dir); + bool aabbOverlap = bound.collide_ray(ray_origin, ray_dir); bool isleafnode = isLeafNode(curIndex); if (isleafnode && aabbOverlap) { - collided_results.push_back(getNodeData( curIndex)); + collided_results.push_back(getNodeData(curIndex)); } if (aabbOverlap || isleafnode) @@ -375,10 +372,10 @@ public: else { //skip node - curIndex+= getScapeNodeIndex(curIndex); + curIndex += getScapeNodeIndex(curIndex); } } - if(collided_results.size()>0) return true; + if (collided_results.size() > 0) return true; return false; } @@ -389,7 +386,7 @@ public: } //! tells if this set is a trimesh - SIMD_FORCE_INLINE bool isTrimesh() const + SIMD_FORCE_INLINE bool isTrimesh() const { return m_primitive_manager.is_trimesh(); } @@ -411,12 +408,12 @@ public: return m_box_tree.getNodeData(nodeindex); } - SIMD_FORCE_INLINE void getNodeBound(GUINT nodeindex, GIM_AABB & bound) const + SIMD_FORCE_INLINE void getNodeBound(GUINT nodeindex, GIM_AABB& bound) const { m_box_tree.getNodeBound(nodeindex, bound); } - SIMD_FORCE_INLINE void setNodeBound(GUINT nodeindex, const GIM_AABB & bound) + SIMD_FORCE_INLINE void setNodeBound(GUINT nodeindex, const GIM_AABB& bound) { m_box_tree.setNodeBound(nodeindex, bound); } @@ -436,36 +433,30 @@ public: return m_box_tree.getScapeNodeIndex(nodeindex); } - SIMD_FORCE_INLINE void getNodeTriangle(GUINT nodeindex,GIM_TRIANGLE & triangle) const + SIMD_FORCE_INLINE void getNodeTriangle(GUINT nodeindex, GIM_TRIANGLE& triangle) const { - m_primitive_manager.get_primitive_triangle(getNodeData(nodeindex),triangle); + m_primitive_manager.get_primitive_triangle(getNodeData(nodeindex), triangle); } - }; //! Class for Box Tree Sets /*! this has the GIM_BOX_TREE implementation for bounding boxes. */ -template -class GIM_BOX_TREE_SET: public GIM_BOX_TREE_TEMPLATE_SET< _GIM_PRIMITIVE_MANAGER_PROTOTYPE, GIM_BOX_TREE> +template +class GIM_BOX_TREE_SET : public GIM_BOX_TREE_TEMPLATE_SET<_GIM_PRIMITIVE_MANAGER_PROTOTYPE, GIM_BOX_TREE> { public: - }; - - - - /// GIM_BOX_SET collision methods -template +template class GIM_TREE_TREE_COLLIDER { public: - gim_pair_set * m_collision_pairs; - BOX_SET_CLASS0 * m_boxset0; - BOX_SET_CLASS1 * m_boxset1; + gim_pair_set* m_collision_pairs; + BOX_SET_CLASS0* m_boxset0; + BOX_SET_CLASS1* m_boxset1; GUINT current_node0; GUINT current_node1; bool node0_is_leaf; @@ -483,18 +474,18 @@ public: GIM_TRIANGLE m_tri1; btVector4 m_tri1_plane; - public: GIM_TREE_TREE_COLLIDER() { current_node0 = G_UINT_INFINITY; current_node1 = G_UINT_INFINITY; } + protected: SIMD_FORCE_INLINE void retrieve_node0_triangle(GUINT node0) { - if(node0_has_triangle) return; - m_boxset0->getNodeTriangle(node0,m_tri0); + if (node0_has_triangle) return; + m_boxset0->getNodeTriangle(node0, m_tri0); //transform triangle m_tri0.m_vertices[0] = trans_cache_0to1(m_tri0.m_vertices[0]); m_tri0.m_vertices[1] = trans_cache_0to1(m_tri0.m_vertices[1]); @@ -506,8 +497,8 @@ protected: SIMD_FORCE_INLINE void retrieve_node1_triangle(GUINT node1) { - if(node1_has_triangle) return; - m_boxset1->getNodeTriangle(node1,m_tri1); + if (node1_has_triangle) return; + m_boxset1->getNodeTriangle(node1, m_tri1); //transform triangle m_tri1.m_vertices[0] = trans_cache_1to0.transform(m_tri1.m_vertices[0]); m_tri1.m_vertices[1] = trans_cache_1to0.transform(m_tri1.m_vertices[1]); @@ -519,8 +510,8 @@ protected: SIMD_FORCE_INLINE void retrieve_node0_info(GUINT node0) { - if(node0 == current_node0) return; - m_boxset0->getNodeBound(node0,m_box0); + if (node0 == current_node0) return; + m_boxset0->getNodeBound(node0, m_box0); node0_is_leaf = m_boxset0->isLeafNode(node0); node0_has_triangle = false; current_node0 = node0; @@ -528,21 +519,21 @@ protected: SIMD_FORCE_INLINE void retrieve_node1_info(GUINT node1) { - if(node1 == current_node1) return; - m_boxset1->getNodeBound(node1,m_box1); + if (node1 == current_node1) return; + m_boxset1->getNodeBound(node1, m_box1); node1_is_leaf = m_boxset1->isLeafNode(node1); node1_has_triangle = false; current_node1 = node1; } - SIMD_FORCE_INLINE bool node_collision(GUINT node0 ,GUINT node1) + SIMD_FORCE_INLINE bool node_collision(GUINT node0, GUINT node1) { retrieve_node0_info(node0); retrieve_node1_info(node1); - bool result = m_box0.overlapping_trans_cache(m_box1,trans_cache_1to0,true); - if(!result) return false; + bool result = m_box0.overlapping_trans_cache(m_box1, trans_cache_1to0, true); + if (!result) return false; - if(t0_is_trimesh && node0_is_leaf) + if (t0_is_trimesh && node0_is_leaf) { //perform primitive vs box collision retrieve_node0_triangle(node0); @@ -550,14 +541,14 @@ protected: m_box1.increment_margin(m_tri0.m_margin); result = m_box1.collide_triangle_exact( - m_tri0.m_vertices[0],m_tri0.m_vertices[1],m_tri0.m_vertices[2],m_tri0_plane); + m_tri0.m_vertices[0], m_tri0.m_vertices[1], m_tri0.m_vertices[2], m_tri0_plane); m_box1.increment_margin(-m_tri0.m_margin); - if(!result) return false; + if (!result) return false; return true; } - else if(t1_is_trimesh && node1_is_leaf) + else if (t1_is_trimesh && node1_is_leaf) { //perform primitive vs box collision retrieve_node1_triangle(node1); @@ -565,11 +556,11 @@ protected: m_box0.increment_margin(m_tri1.m_margin); result = m_box0.collide_triangle_exact( - m_tri1.m_vertices[0],m_tri1.m_vertices[1],m_tri1.m_vertices[2],m_tri1_plane); + m_tri1.m_vertices[0], m_tri1.m_vertices[1], m_tri1.m_vertices[2], m_tri1_plane); m_box0.increment_margin(-m_tri1.m_margin); - if(!result) return false; + if (!result) return false; return true; } return true; @@ -582,40 +573,39 @@ protected: stack_collisions.reserve(32); //add the first pair - stack_collisions.push_pair(0,0); + stack_collisions.push_pair(0, 0); - - while(stack_collisions.size()) + while (stack_collisions.size()) { //retrieve the last pair and pop GUINT node0 = stack_collisions.back().m_index1; GUINT node1 = stack_collisions.back().m_index2; stack_collisions.pop_back(); - if(node_collision(node0,node1)) // a collision is found + if (node_collision(node0, node1)) // a collision is found { - if(node0_is_leaf) + if (node0_is_leaf) { - if(node1_is_leaf) + if (node1_is_leaf) { - m_collision_pairs->push_pair(m_boxset0->getNodeData(node0),m_boxset1->getNodeData(node1)); + m_collision_pairs->push_pair(m_boxset0->getNodeData(node0), m_boxset1->getNodeData(node1)); } else { //collide left - stack_collisions.push_pair(node0,m_boxset1->getLeftNodeIndex(node1)); + stack_collisions.push_pair(node0, m_boxset1->getLeftNodeIndex(node1)); //collide right - stack_collisions.push_pair(node0,m_boxset1->getRightNodeIndex(node1)); + stack_collisions.push_pair(node0, m_boxset1->getRightNodeIndex(node1)); } } else { - if(node1_is_leaf) + if (node1_is_leaf) { //collide left - stack_collisions.push_pair(m_boxset0->getLeftNodeIndex(node0),node1); + stack_collisions.push_pair(m_boxset0->getLeftNodeIndex(node0), node1); //collide right - stack_collisions.push_pair(m_boxset0->getRightNodeIndex(node0),node1); + stack_collisions.push_pair(m_boxset0->getRightNodeIndex(node0), node1); } else { @@ -624,36 +614,36 @@ protected: GUINT left1 = m_boxset1->getLeftNodeIndex(node1); GUINT right1 = m_boxset1->getRightNodeIndex(node1); //collide left - stack_collisions.push_pair(left0,left1); + stack_collisions.push_pair(left0, left1); //collide right - stack_collisions.push_pair(left0,right1); + stack_collisions.push_pair(left0, right1); //collide left - stack_collisions.push_pair(right0,left1); + stack_collisions.push_pair(right0, left1); //collide right - stack_collisions.push_pair(right0,right1); + stack_collisions.push_pair(right0, right1); - }// else if node1 is not a leaf - }// else if node0 is not a leaf + } // else if node1 is not a leaf + } // else if node0 is not a leaf - }// if(node_collision(node0,node1)) - }//while(stack_collisions.size()) + } // if(node_collision(node0,node1)) + } //while(stack_collisions.size()) } + public: - void find_collision(BOX_SET_CLASS0 * boxset1, const btTransform & trans1, - BOX_SET_CLASS1 * boxset2, const btTransform & trans2, - gim_pair_set & collision_pairs, bool complete_primitive_tests = true) + void find_collision(BOX_SET_CLASS0* boxset1, const btTransform& trans1, + BOX_SET_CLASS1* boxset2, const btTransform& trans2, + gim_pair_set& collision_pairs, bool complete_primitive_tests = true) { m_collision_pairs = &collision_pairs; m_boxset0 = boxset1; m_boxset1 = boxset2; - trans_cache_1to0.calc_from_homogenic(trans1,trans2); + trans_cache_1to0.calc_from_homogenic(trans1, trans2); - trans_cache_0to1 = trans2.inverse(); + trans_cache_0to1 = trans2.inverse(); trans_cache_0to1 *= trans1; - - if(complete_primitive_tests) + if (complete_primitive_tests) { t0_is_trimesh = boxset1->getPrimitiveManager().is_trimesh(); t1_is_trimesh = boxset2->getPrimitiveManager().is_trimesh(); @@ -668,7 +658,4 @@ public: } }; - -#endif // GIM_BOXPRUNING_H_INCLUDED - - +#endif // GIM_BOXPRUNING_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/gim_clip_polygon.h b/src/BulletCollision/Gimpact/gim_clip_polygon.h index e342459ce..57b9c5c91 100644 --- a/src/BulletCollision/Gimpact/gim_clip_polygon.h +++ b/src/BulletCollision/Gimpact/gim_clip_polygon.h @@ -33,91 +33,86 @@ email: projectileman@yahoo.com ----------------------------------------------------------------------------- */ - //! This function calcs the distance from a 3D plane class DISTANCE_PLANE_3D_FUNC { public: - template - inline GREAL operator()(const CLASS_PLANE & plane, const CLASS_POINT & point) + template + inline GREAL operator()(const CLASS_PLANE& plane, const CLASS_POINT& point) { return DISTANCE_PLANE_POINT(plane, point); } }; - - -template +template SIMD_FORCE_INLINE void PLANE_CLIP_POLYGON_COLLECT( - const CLASS_POINT & point0, - const CLASS_POINT & point1, - GREAL dist0, - GREAL dist1, - CLASS_POINT * clipped, - GUINT & clipped_count) + const CLASS_POINT& point0, + const CLASS_POINT& point1, + GREAL dist0, + GREAL dist1, + CLASS_POINT* clipped, + GUINT& clipped_count) { - GUINT _prevclassif = (dist0>G_EPSILON); - GUINT _classif = (dist1>G_EPSILON); - if(_classif!=_prevclassif) + GUINT _prevclassif = (dist0 > G_EPSILON); + GUINT _classif = (dist1 > G_EPSILON); + if (_classif != _prevclassif) { - GREAL blendfactor = -dist0/(dist1-dist0); - VEC_BLEND(clipped[clipped_count],point0,point1,blendfactor); + GREAL blendfactor = -dist0 / (dist1 - dist0); + VEC_BLEND(clipped[clipped_count], point0, point1, blendfactor); clipped_count++; } - if(!_classif) + if (!_classif) { - VEC_COPY(clipped[clipped_count],point1); + VEC_COPY(clipped[clipped_count], point1); clipped_count++; } } - //! Clips a polygon by a plane /*! *\return The count of the clipped counts */ -template +template SIMD_FORCE_INLINE GUINT PLANE_CLIP_POLYGON_GENERIC( - const CLASS_PLANE & plane, - const CLASS_POINT * polygon_points, - GUINT polygon_point_count, - CLASS_POINT * clipped,DISTANCE_PLANE_FUNC distance_func) + const CLASS_PLANE& plane, + const CLASS_POINT* polygon_points, + GUINT polygon_point_count, + CLASS_POINT* clipped, DISTANCE_PLANE_FUNC distance_func) { - GUINT clipped_count = 0; + GUINT clipped_count = 0; - - //clip first point - GREAL firstdist = distance_func(plane,polygon_points[0]);; - if(!(firstdist>G_EPSILON)) + //clip first point + GREAL firstdist = distance_func(plane, polygon_points[0]); + ; + if (!(firstdist > G_EPSILON)) { - VEC_COPY(clipped[clipped_count],polygon_points[0]); + VEC_COPY(clipped[clipped_count], polygon_points[0]); clipped_count++; } GREAL olddist = firstdist; - for(GUINT _i=1;_i +template SIMD_FORCE_INLINE GUINT PLANE_CLIP_TRIANGLE_GENERIC( - const CLASS_PLANE & plane, - const CLASS_POINT & point0, - const CLASS_POINT & point1, - const CLASS_POINT & point2, - CLASS_POINT * clipped,DISTANCE_PLANE_FUNC distance_func) + const CLASS_PLANE& plane, + const CLASS_POINT& point0, + const CLASS_POINT& point1, + const CLASS_POINT& point2, + CLASS_POINT* clipped, DISTANCE_PLANE_FUNC distance_func) { - GUINT clipped_count = 0; + GUINT clipped_count = 0; - //clip first point - GREAL firstdist = distance_func(plane,point0);; - if(!(firstdist>G_EPSILON)) + //clip first point + GREAL firstdist = distance_func(plane, point0); + ; + if (!(firstdist > G_EPSILON)) { - VEC_COPY(clipped[clipped_count],point0); + VEC_COPY(clipped[clipped_count], point0); clipped_count++; } // point 1 GREAL olddist = firstdist; - GREAL dist = distance_func(plane,point1); + GREAL dist = distance_func(plane, point1); PLANE_CLIP_POLYGON_COLLECT( - point0,point1, - olddist, - dist, - clipped, - clipped_count); + point0, point1, + olddist, + dist, + clipped, + clipped_count); olddist = dist; - // point 2 - dist = distance_func(plane,point2); + dist = distance_func(plane, point2); PLANE_CLIP_POLYGON_COLLECT( - point1,point2, - olddist, - dist, - clipped, - clipped_count); + point1, point2, + olddist, + dist, + clipped, + clipped_count); olddist = dist; - - //RETURN TO FIRST point PLANE_CLIP_POLYGON_COLLECT( - point2,point0, - olddist, - firstdist, - clipped, - clipped_count); + point2, point0, + olddist, + firstdist, + clipped, + clipped_count); return clipped_count; } - -template +template SIMD_FORCE_INLINE GUINT PLANE_CLIP_POLYGON3D( - const CLASS_PLANE & plane, - const CLASS_POINT * polygon_points, - GUINT polygon_point_count, - CLASS_POINT * clipped) + const CLASS_PLANE& plane, + const CLASS_POINT* polygon_points, + GUINT polygon_point_count, + CLASS_POINT* clipped) { - return PLANE_CLIP_POLYGON_GENERIC(plane,polygon_points,polygon_point_count,clipped,DISTANCE_PLANE_3D_FUNC()); + return PLANE_CLIP_POLYGON_GENERIC(plane, polygon_points, polygon_point_count, clipped, DISTANCE_PLANE_3D_FUNC()); } - -template +template SIMD_FORCE_INLINE GUINT PLANE_CLIP_TRIANGLE3D( - const CLASS_PLANE & plane, - const CLASS_POINT & point0, - const CLASS_POINT & point1, - const CLASS_POINT & point2, - CLASS_POINT * clipped) + const CLASS_PLANE& plane, + const CLASS_POINT& point0, + const CLASS_POINT& point1, + const CLASS_POINT& point2, + CLASS_POINT* clipped) { - return PLANE_CLIP_TRIANGLE_GENERIC(plane,point0,point1,point2,clipped,DISTANCE_PLANE_3D_FUNC()); + return PLANE_CLIP_TRIANGLE_GENERIC(plane, point0, point1, point2, clipped, DISTANCE_PLANE_3D_FUNC()); } - - -#endif // GIM_TRI_COLLISION_H_INCLUDED +#endif // GIM_TRI_COLLISION_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/gim_contact.cpp b/src/BulletCollision/Gimpact/gim_contact.cpp index 20e41de08..390225709 100644 --- a/src/BulletCollision/Gimpact/gim_contact.cpp +++ b/src/BulletCollision/Gimpact/gim_contact.cpp @@ -33,91 +33,89 @@ email: projectileman@yahoo.com #define MAX_COINCIDENT 8 void gim_contact_array::merge_contacts( - const gim_contact_array & contacts, bool normal_contact_average) + const gim_contact_array& contacts, bool normal_contact_average) { clear(); - if(contacts.size()==1) + if (contacts.size() == 1) { push_back(contacts.back()); return; } gim_array keycontacts(contacts.size()); - keycontacts.resize(contacts.size(),false); + keycontacts.resize(contacts.size(), false); //fill key contacts GUINT i; - for (i = 0;im_depth - CONTACT_DIFF_EPSILON > scontact->m_depth)//) + if (pcontact->m_depth - CONTACT_DIFF_EPSILON > scontact->m_depth) //) { *pcontact = *scontact; - coincident_count = 0; + coincident_count = 0; } - else if(normal_contact_average) + else if (normal_contact_average) { - if(btFabs(pcontact->m_depth - scontact->m_depth)m_normal; - coincident_count++; - } - } + if (btFabs(pcontact->m_depth - scontact->m_depth) < CONTACT_DIFF_EPSILON) + { + if (coincident_count < MAX_COINCIDENT) + { + coincident_normals[coincident_count] = scontact->m_normal; + coincident_count++; + } + } } } else - {//add new contact + { //add new contact - if(normal_contact_average && coincident_count>0) - { - pcontact->interpolate_normals(coincident_normals,coincident_count); - coincident_count = 0; - } + if (normal_contact_average && coincident_count > 0) + { + pcontact->interpolate_normals(coincident_normals, coincident_count); + coincident_count = 0; + } - push_back(*scontact); - pcontact = &back(); - } + push_back(*scontact); + pcontact = &back(); + } last_key = key; } } -void gim_contact_array::merge_contacts_unique(const gim_contact_array & contacts) +void gim_contact_array::merge_contacts_unique(const gim_contact_array& contacts) { clear(); - if(contacts.size()==1) + if (contacts.size() == 1) { push_back(contacts.back()); return; @@ -125,14 +123,14 @@ void gim_contact_array::merge_contacts_unique(const gim_contact_array & contacts GIM_CONTACT average_contact = contacts.back(); - for (GUINT i=1;i +class gim_contact_array : public gim_array { public: - gim_contact_array():gim_array(64) + gim_contact_array() : gim_array(64) { } - SIMD_FORCE_INLINE void push_contact(const btVector3 &point,const btVector3 & normal, - GREAL depth, GUINT feature1, GUINT feature2) + SIMD_FORCE_INLINE void push_contact(const btVector3 &point, const btVector3 &normal, + GREAL depth, GUINT feature1, GUINT feature2) { push_back_mem(); - GIM_CONTACT & newele = back(); + GIM_CONTACT &newele = back(); newele.m_point = point; newele.m_normal = normal; newele.m_depth = depth; @@ -150,13 +146,13 @@ public: } SIMD_FORCE_INLINE void push_triangle_contacts( - const GIM_TRIANGLE_CONTACT_DATA & tricontact, - GUINT feature1,GUINT feature2) + const GIM_TRIANGLE_CONTACT_DATA &tricontact, + GUINT feature1, GUINT feature2) { - for(GUINT i = 0;i +template struct GIM_HASH_TABLE_NODE { - GUINT m_key; - T m_data; - GIM_HASH_TABLE_NODE() - { - } + GUINT m_key; + T m_data; + GIM_HASH_TABLE_NODE() + { + } - GIM_HASH_TABLE_NODE(const GIM_HASH_TABLE_NODE & value) - { - m_key = value.m_key; - m_data = value.m_data; - } + GIM_HASH_TABLE_NODE(const GIM_HASH_TABLE_NODE& value) + { + m_key = value.m_key; + m_data = value.m_data; + } - GIM_HASH_TABLE_NODE(GUINT key, const T & data) - { - m_key = key; - m_data = data; - } + GIM_HASH_TABLE_NODE(GUINT key, const T& data) + { + m_key = key; + m_data = data; + } - bool operator <(const GIM_HASH_TABLE_NODE & other) const + bool operator<(const GIM_HASH_TABLE_NODE& other) const { ///inverse order, further objects are first - if(m_key < other.m_key) return true; + if (m_key < other.m_key) return true; return false; } - bool operator >(const GIM_HASH_TABLE_NODE & other) const + bool operator>(const GIM_HASH_TABLE_NODE& other) const { ///inverse order, further objects are first - if(m_key > other.m_key) return true; + if (m_key > other.m_key) return true; return false; } - bool operator ==(const GIM_HASH_TABLE_NODE & other) const + bool operator==(const GIM_HASH_TABLE_NODE& other) const { ///inverse order, further objects are first - if(m_key == other.m_key) return true; + if (m_key == other.m_key) return true; return false; } }; @@ -89,21 +88,19 @@ struct GIM_HASH_TABLE_NODE class GIM_HASH_NODE_GET_KEY { public: - template - inline GUINT operator()( const T& a) + template + inline GUINT operator()(const T& a) { return a.m_key; } }; - - ///Macro for comparing the key and the element class GIM_HASH_NODE_CMP_KEY_MACRO { public: - template - inline int operator() ( const T& a, GUINT key) + template + inline int operator()(const T& a, GUINT key) { return ((int)(a.m_key - key)); } @@ -113,65 +110,53 @@ public: class GIM_HASH_NODE_CMP_MACRO { public: - template - inline int operator() ( const T& a, const T& b ) + template + inline int operator()(const T& a, const T& b) { return ((int)(a.m_key - b.m_key)); } }; - - - - //! Sorting for hash table /*! switch automatically between quicksort and radixsort */ -template -void gim_sort_hash_node_array(T * array, GUINT array_count) +template +void gim_sort_hash_node_array(T* array, GUINT array_count) { - if(array_count */ -template +template class gim_hash_table { protected: - typedef GIM_HASH_TABLE_NODE _node_type; + typedef GIM_HASH_TABLE_NODE _node_type; - //!The nodes - //array< _node_type, SuperAllocator<_node_type> > m_nodes; - gim_array< _node_type > m_nodes; - //SuperBufferedArray< _node_type > m_nodes; - bool m_sorted; + //!The nodes + //array< _node_type, SuperAllocator<_node_type> > m_nodes; + gim_array<_node_type> m_nodes; + //SuperBufferedArray< _node_type > m_nodes; + bool m_sorted; - ///Hash table data management. The hash table has the indices to the corresponding m_nodes array - GUINT * m_hash_table;//!< - GUINT m_table_size;//!< - GUINT m_node_size;//!< - GUINT m_min_hash_table_size; + ///Hash table data management. The hash table has the indices to the corresponding m_nodes array + GUINT* m_hash_table; //!< + GUINT m_table_size; //!< + GUINT m_node_size; //!< + GUINT m_min_hash_table_size; + //! Returns the cell index + inline GUINT _find_cell(GUINT hashkey) + { + _node_type* nodesptr = m_nodes.pointer(); + GUINT start_index = (hashkey % m_table_size) * m_node_size; + GUINT end_index = start_index + m_node_size; + while (start_index < end_index) + { + GUINT value = m_hash_table[start_index]; + if (value != GIM_INVALID_HASH) + { + if (nodesptr[value].m_key == hashkey) return start_index; + } + start_index++; + } + return GIM_INVALID_HASH; + } - //! Returns the cell index - inline GUINT _find_cell(GUINT hashkey) - { - _node_type * nodesptr = m_nodes.pointer(); - GUINT start_index = (hashkey%m_table_size)*m_node_size; - GUINT end_index = start_index + m_node_size; + //! Find the avaliable cell for the hashkey, and return an existing cell if it has the same hash key + inline GUINT _find_avaliable_cell(GUINT hashkey) + { + _node_type* nodesptr = m_nodes.pointer(); + GUINT avaliable_index = GIM_INVALID_HASH; + GUINT start_index = (hashkey % m_table_size) * m_node_size; + GUINT end_index = start_index + m_node_size; - while(start_index= m_nodes.size()) return false; - if(m_nodes[index].m_key != GIM_INVALID_HASH) - { - //Search for the avaliable cell in buffer - GUINT cell_index = _find_cell(m_nodes[index].m_key); + //! erase by index in hash table + inline bool _erase_by_index_hash_table(GUINT index) + { + if (index >= m_nodes.size()) return false; + if (m_nodes[index].m_key != GIM_INVALID_HASH) + { + //Search for the avaliable cell in buffer + GUINT cell_index = _find_cell(m_nodes[index].m_key); - btAssert(cell_index!=GIM_INVALID_HASH); - btAssert(m_hash_table[cell_index]==index); + btAssert(cell_index != GIM_INVALID_HASH); + btAssert(m_hash_table[cell_index] == index); - m_hash_table[cell_index] = GIM_INVALID_HASH; - } + m_hash_table[cell_index] = GIM_INVALID_HASH; + } - return this->_erase_unsorted(index); - } + return this->_erase_unsorted(index); + } - //! erase by key in hash table - inline bool _erase_hash_table(GUINT hashkey) - { - if(hashkey == GIM_INVALID_HASH) return false; + //! erase by key in hash table + inline bool _erase_hash_table(GUINT hashkey) + { + if (hashkey == GIM_INVALID_HASH) return false; - //Search for the avaliable cell in buffer - GUINT cell_index = _find_cell(hashkey); - if(cell_index ==GIM_INVALID_HASH) return false; + //Search for the avaliable cell in buffer + GUINT cell_index = _find_cell(hashkey); + if (cell_index == GIM_INVALID_HASH) return false; - GUINT index = m_hash_table[cell_index]; - m_hash_table[cell_index] = GIM_INVALID_HASH; + GUINT index = m_hash_table[cell_index]; + m_hash_table[cell_index] = GIM_INVALID_HASH; - return this->_erase_unsorted(index); - } + return this->_erase_unsorted(index); + } - - - //! insert an element in hash table - /*! + //! insert an element in hash table + /*! If the element exists, this won't insert the element \return the index in the array of the existing element,or GIM_INVALID_HASH if the element has been inserted If so, the element has been inserted at the last position of the array. */ - inline GUINT _insert_hash_table(GUINT hashkey, const T & value) - { - if(hashkey==GIM_INVALID_HASH) - { - //Insert anyway - _insert_unsorted(hashkey,value); - return GIM_INVALID_HASH; - } + inline GUINT _insert_hash_table(GUINT hashkey, const T& value) + { + if (hashkey == GIM_INVALID_HASH) + { + //Insert anyway + _insert_unsorted(hashkey, value); + return GIM_INVALID_HASH; + } - GUINT cell_index = _assign_hash_table_cell(hashkey); + GUINT cell_index = _assign_hash_table_cell(hashkey); - GUINT value_key = m_hash_table[cell_index]; + GUINT value_key = m_hash_table[cell_index]; - if(value_key!= GIM_INVALID_HASH) return value_key;// Not overrited + if (value_key != GIM_INVALID_HASH) return value_key; // Not overrited - m_hash_table[cell_index] = m_nodes.size(); + m_hash_table[cell_index] = m_nodes.size(); - _insert_unsorted(hashkey,value); - return GIM_INVALID_HASH; - } + _insert_unsorted(hashkey, value); + return GIM_INVALID_HASH; + } - //! insert an element in hash table. - /*! + //! insert an element in hash table. + /*! If the element exists, this replaces the element. \return the index in the array of the existing element,or GIM_INVALID_HASH if the element has been inserted If so, the element has been inserted at the last position of the array. */ - inline GUINT _insert_hash_table_replace(GUINT hashkey, const T & value) - { - if(hashkey==GIM_INVALID_HASH) - { - //Insert anyway - _insert_unsorted(hashkey,value); - return GIM_INVALID_HASH; - } + inline GUINT _insert_hash_table_replace(GUINT hashkey, const T& value) + { + if (hashkey == GIM_INVALID_HASH) + { + //Insert anyway + _insert_unsorted(hashkey, value); + return GIM_INVALID_HASH; + } - GUINT cell_index = _assign_hash_table_cell(hashkey); + GUINT cell_index = _assign_hash_table_cell(hashkey); - GUINT value_key = m_hash_table[cell_index]; + GUINT value_key = m_hash_table[cell_index]; - if(value_key!= GIM_INVALID_HASH) - {//replaces the existing - m_nodes[value_key] = _node_type(hashkey,value); - return value_key;// index of the replaced element - } + if (value_key != GIM_INVALID_HASH) + { //replaces the existing + m_nodes[value_key] = _node_type(hashkey, value); + return value_key; // index of the replaced element + } - m_hash_table[cell_index] = m_nodes.size(); + m_hash_table[cell_index] = m_nodes.size(); - _insert_unsorted(hashkey,value); - return GIM_INVALID_HASH; + _insert_unsorted(hashkey, value); + return GIM_INVALID_HASH; + } - } + ///Sorted array data management. The hash table has the indices to the corresponding m_nodes array + inline bool _erase_sorted(GUINT index) + { + if (index >= (GUINT)m_nodes.size()) return false; + m_nodes.erase_sorted(index); + if (m_nodes.size() < 2) m_sorted = false; + return true; + } - - ///Sorted array data management. The hash table has the indices to the corresponding m_nodes array - inline bool _erase_sorted(GUINT index) - { - if(index>=(GUINT)m_nodes.size()) return false; - m_nodes.erase_sorted(index); - if(m_nodes.size()<2) m_sorted = false; - return true; - } + //! faster, but unsorted + inline bool _erase_unsorted(GUINT index) + { + if (index >= m_nodes.size()) return false; - //! faster, but unsorted - inline bool _erase_unsorted(GUINT index) - { - if(index>=m_nodes.size()) return false; - - GUINT lastindex = m_nodes.size()-1; - if(indexcheck_for_switching_to_hashtable(); - } + inline void _insert_in_pos(GUINT hashkey, const T& value, GUINT pos) + { + m_nodes.insert(_node_type(hashkey, value), pos); + this->check_for_switching_to_hashtable(); + } - //! Insert an element in an ordered array - inline GUINT _insert_sorted(GUINT hashkey, const T & value) - { - if(hashkey==GIM_INVALID_HASH || size()==0) - { - m_nodes.push_back(_node_type(hashkey,value)); - return GIM_INVALID_HASH; - } - //Insert at last position - //Sort element + //! Insert an element in an ordered array + inline GUINT _insert_sorted(GUINT hashkey, const T& value) + { + if (hashkey == GIM_INVALID_HASH || size() == 0) + { + m_nodes.push_back(_node_type(hashkey, value)); + return GIM_INVALID_HASH; + } + //Insert at last position + //Sort element + GUINT result_ind = 0; + GUINT last_index = m_nodes.size() - 1; + _node_type* ptr = m_nodes.pointer(); - GUINT result_ind=0; - GUINT last_index = m_nodes.size()-1; - _node_type * ptr = m_nodes.pointer(); + bool found = gim_binary_search_ex( + ptr, 0, last_index, result_ind, hashkey, GIM_HASH_NODE_CMP_KEY_MACRO()); - bool found = gim_binary_search_ex( - ptr,0,last_index,result_ind,hashkey,GIM_HASH_NODE_CMP_KEY_MACRO()); + //Insert before found index + if (found) + { + return result_ind; + } + else + { + _insert_in_pos(hashkey, value, result_ind); + } + return GIM_INVALID_HASH; + } + inline GUINT _insert_sorted_replace(GUINT hashkey, const T& value) + { + if (hashkey == GIM_INVALID_HASH || size() == 0) + { + m_nodes.push_back(_node_type(hashkey, value)); + return GIM_INVALID_HASH; + } + //Insert at last position + //Sort element + GUINT result_ind; + GUINT last_index = m_nodes.size() - 1; + _node_type* ptr = m_nodes.pointer(); - //Insert before found index - if(found) - { - return result_ind; - } - else - { - _insert_in_pos(hashkey, value, result_ind); - } - return GIM_INVALID_HASH; - } + bool found = gim_binary_search_ex( + ptr, 0, last_index, result_ind, hashkey, GIM_HASH_NODE_CMP_KEY_MACRO()); - inline GUINT _insert_sorted_replace(GUINT hashkey, const T & value) - { - if(hashkey==GIM_INVALID_HASH || size()==0) - { - m_nodes.push_back(_node_type(hashkey,value)); - return GIM_INVALID_HASH; - } - //Insert at last position - //Sort element - GUINT result_ind; - GUINT last_index = m_nodes.size()-1; - _node_type * ptr = m_nodes.pointer(); + //Insert before found index + if (found) + { + m_nodes[result_ind] = _node_type(hashkey, value); + } + else + { + _insert_in_pos(hashkey, value, result_ind); + } + return result_ind; + } - bool found = gim_binary_search_ex( - ptr,0,last_index,result_ind,hashkey,GIM_HASH_NODE_CMP_KEY_MACRO()); - - //Insert before found index - if(found) - { - m_nodes[result_ind] = _node_type(hashkey,value); - } - else - { - _insert_in_pos(hashkey, value, result_ind); - } - return result_ind; - } - - //! Fast insertion in m_nodes array - inline GUINT _insert_unsorted(GUINT hashkey, const T & value) - { - m_nodes.push_back(_node_type(hashkey,value)); - m_sorted = false; - return GIM_INVALID_HASH; - } - - + //! Fast insertion in m_nodes array + inline GUINT _insert_unsorted(GUINT hashkey, const T& value) + { + m_nodes.push_back(_node_type(hashkey, value)); + m_sorted = false; + return GIM_INVALID_HASH; + } public: - - /*! + /*!
  • if node_size = 0, then this container becomes a simple sorted array allocator. reserve_size is used for reserve memory in m_nodes. When the array size reaches the size equivalent to 'min_hash_table_size', then it becomes a hash table by calling check_for_switching_to_hashtable.
  • If node_size != 0, then this container becomes a hash table for ever */ - gim_hash_table(GUINT reserve_size = GIM_DEFAULT_HASH_TABLE_SIZE, - GUINT node_size = GIM_DEFAULT_HASH_TABLE_NODE_SIZE, - GUINT min_hash_table_size = GIM_INVALID_HASH) - { - m_hash_table = NULL; - m_table_size = 0; - m_sorted = false; - m_node_size = node_size; - m_min_hash_table_size = min_hash_table_size; + gim_hash_table(GUINT reserve_size = GIM_DEFAULT_HASH_TABLE_SIZE, + GUINT node_size = GIM_DEFAULT_HASH_TABLE_NODE_SIZE, + GUINT min_hash_table_size = GIM_INVALID_HASH) + { + m_hash_table = NULL; + m_table_size = 0; + m_sorted = false; + m_node_size = node_size; + m_min_hash_table_size = min_hash_table_size; - if(m_node_size!=0) - { - if(reserve_size!=0) - { - m_nodes.reserve(reserve_size); - _reserve_table_memory(reserve_size); - _invalidate_keys(); - } - else - { - m_nodes.reserve(GIM_DEFAULT_HASH_TABLE_SIZE); - _reserve_table_memory(GIM_DEFAULT_HASH_TABLE_SIZE); - _invalidate_keys(); - } - } - else if(reserve_size!=0) - { - m_nodes.reserve(reserve_size); - } + if (m_node_size != 0) + { + if (reserve_size != 0) + { + m_nodes.reserve(reserve_size); + _reserve_table_memory(reserve_size); + _invalidate_keys(); + } + else + { + m_nodes.reserve(GIM_DEFAULT_HASH_TABLE_SIZE); + _reserve_table_memory(GIM_DEFAULT_HASH_TABLE_SIZE); + _invalidate_keys(); + } + } + else if (reserve_size != 0) + { + m_nodes.reserve(reserve_size); + } + } - } + ~gim_hash_table() + { + _destroy(); + } - ~gim_hash_table() - { - _destroy(); - } + inline bool is_hash_table() + { + if (m_hash_table) return true; + return false; + } - inline bool is_hash_table() - { - if(m_hash_table) return true; - return false; - } + inline bool is_sorted() + { + if (size() < 2) return true; + return m_sorted; + } - inline bool is_sorted() - { - if(size()<2) return true; - return m_sorted; - } + bool sort() + { + if (is_sorted()) return true; + if (m_nodes.size() < 2) return false; - bool sort() - { - if(is_sorted()) return true; - if(m_nodes.size()<2) return false; + _node_type* ptr = m_nodes.pointer(); + GUINT siz = m_nodes.size(); + gim_sort_hash_node_array(ptr, siz); + m_sorted = true; + if (m_hash_table) + { + _rehash(); + } + return true; + } - _node_type * ptr = m_nodes.pointer(); - GUINT siz = m_nodes.size(); - gim_sort_hash_node_array(ptr,siz); - m_sorted=true; + bool switch_to_hashtable() + { + if (m_hash_table) return false; + if (m_node_size == 0) m_node_size = GIM_DEFAULT_HASH_TABLE_NODE_SIZE; + if (m_nodes.size() < GIM_DEFAULT_HASH_TABLE_SIZE) + { + _resize_table(GIM_DEFAULT_HASH_TABLE_SIZE); + } + else + { + _resize_table(m_nodes.size() + 1); + } + return true; + } + bool switch_to_sorted_array() + { + if (m_hash_table == NULL) return true; + _clear_table_memory(); + return sort(); + } - if(m_hash_table) - { - _rehash(); - } - return true; - } + //!If the container reaches the + bool check_for_switching_to_hashtable() + { + if (this->m_hash_table) return true; - bool switch_to_hashtable() - { - if(m_hash_table) return false; - if(m_node_size==0) m_node_size = GIM_DEFAULT_HASH_TABLE_NODE_SIZE; - if(m_nodes.size()m_hash_table) return true; + //! Retrieves the amount of keys. + inline GUINT size() const + { + return m_nodes.size(); + } - if(!(m_nodes.size()< m_min_hash_table_size)) - { - if(m_node_size == 0) - { - m_node_size = GIM_DEFAULT_HASH_TABLE_NODE_SIZE; - } + //! Retrieves the hash key. + inline GUINT get_key(GUINT index) const + { + return m_nodes[index].m_key; + } - _resize_table(m_nodes.size()+1); - return true; - } - return false; - } - - inline void set_sorted(bool value) - { - m_sorted = value; - } - - //! Retrieves the amount of keys. - inline GUINT size() const - { - return m_nodes.size(); - } - - //! Retrieves the hash key. - inline GUINT get_key(GUINT index) const - { - return m_nodes[index].m_key; - } - - //! Retrieves the value by index - /*! + //! Retrieves the value by index + /*! */ - inline T * get_value_by_index(GUINT index) - { - return &m_nodes[index].m_data; - } + inline T* get_value_by_index(GUINT index) + { + return &m_nodes[index].m_data; + } - inline const T& operator[](GUINT index) const - { - return m_nodes[index].m_data; - } + inline const T& operator[](GUINT index) const + { + return m_nodes[index].m_data; + } - inline T& operator[](GUINT index) - { - return m_nodes[index].m_data; - } + inline T& operator[](GUINT index) + { + return m_nodes[index].m_data; + } - //! Finds the index of the element with the key - /*! + //! Finds the index of the element with the key + /*! \return the index in the array of the existing element,or GIM_INVALID_HASH if the element has been inserted If so, the element has been inserted at the last position of the array. */ - inline GUINT find(GUINT hashkey) - { - if(m_hash_table) - { - GUINT cell_index = _find_cell(hashkey); - if(cell_index==GIM_INVALID_HASH) return GIM_INVALID_HASH; - return m_hash_table[cell_index]; - } + inline GUINT find(GUINT hashkey) + { + if (m_hash_table) + { + GUINT cell_index = _find_cell(hashkey); + if (cell_index == GIM_INVALID_HASH) return GIM_INVALID_HASH; + return m_hash_table[cell_index]; + } GUINT last_index = m_nodes.size(); - if(last_index<2) - { - if(last_index==0) return GIM_INVALID_HASH; - if(m_nodes[0].m_key == hashkey) return 0; - return GIM_INVALID_HASH; - } - else if(m_sorted) - { - //Binary search - GUINT result_ind = 0; + if (last_index < 2) + { + if (last_index == 0) return GIM_INVALID_HASH; + if (m_nodes[0].m_key == hashkey) return 0; + return GIM_INVALID_HASH; + } + else if (m_sorted) + { + //Binary search + GUINT result_ind = 0; last_index--; - _node_type * ptr = m_nodes.pointer(); + _node_type* ptr = m_nodes.pointer(); - bool found = gim_binary_search_ex(ptr,0,last_index,result_ind,hashkey,GIM_HASH_NODE_CMP_KEY_MACRO()); + bool found = gim_binary_search_ex(ptr, 0, last_index, result_ind, hashkey, GIM_HASH_NODE_CMP_KEY_MACRO()); + if (found) return result_ind; + } + return GIM_INVALID_HASH; + } - if(found) return result_ind; - } - return GIM_INVALID_HASH; - } - - //! Retrieves the value associated with the index - /*! + //! Retrieves the value associated with the index + /*! \return the found element, or null */ - inline T * get_value(GUINT hashkey) - { - GUINT index = find(hashkey); - if(index == GIM_INVALID_HASH) return NULL; - return &m_nodes[index].m_data; - } + inline T* get_value(GUINT hashkey) + { + GUINT index = find(hashkey); + if (index == GIM_INVALID_HASH) return NULL; + return &m_nodes[index].m_data; + } - - /*! + /*! */ - inline bool erase_by_index(GUINT index) - { - if(index > m_nodes.size()) return false; + inline bool erase_by_index(GUINT index) + { + if (index > m_nodes.size()) return false; - if(m_hash_table == NULL) - { - if(is_sorted()) - { - return this->_erase_sorted(index); - } - else - { - return this->_erase_unsorted(index); - } - } - else - { - return this->_erase_by_index_hash_table(index); - } - return false; - } + if (m_hash_table == NULL) + { + if (is_sorted()) + { + return this->_erase_sorted(index); + } + else + { + return this->_erase_unsorted(index); + } + } + else + { + return this->_erase_by_index_hash_table(index); + } + return false; + } + inline bool erase_by_index_unsorted(GUINT index) + { + if (index > m_nodes.size()) return false; + if (m_hash_table == NULL) + { + return this->_erase_unsorted(index); + } + else + { + return this->_erase_by_index_hash_table(index); + } + return false; + } - inline bool erase_by_index_unsorted(GUINT index) - { - if(index > m_nodes.size()) return false; - - if(m_hash_table == NULL) - { - return this->_erase_unsorted(index); - } - else - { - return this->_erase_by_index_hash_table(index); - } - return false; - } - - - - /*! + /*! */ - inline bool erase_by_key(GUINT hashkey) - { - if(size()==0) return false; + inline bool erase_by_key(GUINT hashkey) + { + if (size() == 0) return false; - if(m_hash_table) - { - return this->_erase_hash_table(hashkey); - } - //Binary search + if (m_hash_table) + { + return this->_erase_hash_table(hashkey); + } + //Binary search - if(is_sorted()==false) return false; + if (is_sorted() == false) return false; - GUINT result_ind = find(hashkey); - if(result_ind!= GIM_INVALID_HASH) - { - return this->_erase_sorted(result_ind); - } - return false; - } + GUINT result_ind = find(hashkey); + if (result_ind != GIM_INVALID_HASH) + { + return this->_erase_sorted(result_ind); + } + return false; + } - void clear() - { - m_nodes.clear(); + void clear() + { + m_nodes.clear(); - if(m_hash_table==NULL) return; - GUINT datasize = m_table_size*m_node_size; - //Initialize the hashkeys. - GUINT i; - for(i=0;i_insert_hash_table(hashkey,element); - } - if(this->is_sorted()) - { - return this->_insert_sorted(hashkey,element); - } - return this->_insert_unsorted(hashkey,element); - } + inline GUINT insert(GUINT hashkey, const T& element) + { + if (m_hash_table) + { + return this->_insert_hash_table(hashkey, element); + } + if (this->is_sorted()) + { + return this->_insert_sorted(hashkey, element); + } + return this->_insert_unsorted(hashkey, element); + } - //! Insert an element into the hash, and could overrite an existing object with the same hash. - /*! + //! Insert an element into the hash, and could overrite an existing object with the same hash. + /*! \return If GIM_INVALID_HASH, the object has been inserted succesfully. Else it returns the position of the replaced element. */ - inline GUINT insert_override(GUINT hashkey, const T & element) - { - if(m_hash_table) - { - return this->_insert_hash_table_replace(hashkey,element); - } - if(this->is_sorted()) - { - return this->_insert_sorted_replace(hashkey,element); - } - this->_insert_unsorted(hashkey,element); - return m_nodes.size(); - } + inline GUINT insert_override(GUINT hashkey, const T& element) + { + if (m_hash_table) + { + return this->_insert_hash_table_replace(hashkey, element); + } + if (this->is_sorted()) + { + return this->_insert_sorted_replace(hashkey, element); + } + this->_insert_unsorted(hashkey, element); + return m_nodes.size(); + } - - - //! Insert an element into the hash,But if this container is a sorted array, this inserts it unsorted - /*! + //! Insert an element into the hash,But if this container is a sorted array, this inserts it unsorted + /*! */ - inline GUINT insert_unsorted(GUINT hashkey,const T & element) - { - if(m_hash_table) - { - return this->_insert_hash_table(hashkey,element); - } - return this->_insert_unsorted(hashkey,element); - } - - + inline GUINT insert_unsorted(GUINT hashkey, const T& element) + { + if (m_hash_table) + { + return this->_insert_hash_table(hashkey, element); + } + return this->_insert_unsorted(hashkey, element); + } }; - - -#endif // GIM_CONTAINERS_H_INCLUDED +#endif // GIM_CONTAINERS_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/gim_linear_math.h b/src/BulletCollision/Gimpact/gim_linear_math.h index 64f11b495..70a1b508f 100644 --- a/src/BulletCollision/Gimpact/gim_linear_math.h +++ b/src/BulletCollision/Gimpact/gim_linear_math.h @@ -34,962 +34,900 @@ email: projectileman@yahoo.com ----------------------------------------------------------------------------- */ - #include "gim_math.h" #include "gim_geom_types.h" - - - //! Zero out a 2D vector -#define VEC_ZERO_2(a) \ -{ \ - (a)[0] = (a)[1] = 0.0f; \ -}\ - +#define VEC_ZERO_2(a) \ + { \ + (a)[0] = (a)[1] = 0.0f; \ + } //! Zero out a 3D vector -#define VEC_ZERO(a) \ -{ \ - (a)[0] = (a)[1] = (a)[2] = 0.0f; \ -}\ - +#define VEC_ZERO(a) \ + { \ + (a)[0] = (a)[1] = (a)[2] = 0.0f; \ + } /// Zero out a 4D vector -#define VEC_ZERO_4(a) \ -{ \ - (a)[0] = (a)[1] = (a)[2] = (a)[3] = 0.0f; \ -}\ - +#define VEC_ZERO_4(a) \ + { \ + (a)[0] = (a)[1] = (a)[2] = (a)[3] = 0.0f; \ + } /// Vector copy -#define VEC_COPY_2(b,a) \ -{ \ - (b)[0] = (a)[0]; \ - (b)[1] = (a)[1]; \ -}\ - +#define VEC_COPY_2(b, a) \ + { \ + (b)[0] = (a)[0]; \ + (b)[1] = (a)[1]; \ + } /// Copy 3D vector -#define VEC_COPY(b,a) \ -{ \ - (b)[0] = (a)[0]; \ - (b)[1] = (a)[1]; \ - (b)[2] = (a)[2]; \ -}\ - +#define VEC_COPY(b, a) \ + { \ + (b)[0] = (a)[0]; \ + (b)[1] = (a)[1]; \ + (b)[2] = (a)[2]; \ + } /// Copy 4D vector -#define VEC_COPY_4(b,a) \ -{ \ - (b)[0] = (a)[0]; \ - (b)[1] = (a)[1]; \ - (b)[2] = (a)[2]; \ - (b)[3] = (a)[3]; \ -}\ +#define VEC_COPY_4(b, a) \ + { \ + (b)[0] = (a)[0]; \ + (b)[1] = (a)[1]; \ + (b)[2] = (a)[2]; \ + (b)[3] = (a)[3]; \ + } /// VECTOR SWAP -#define VEC_SWAP(b,a) \ -{ \ - GIM_SWAP_NUMBERS((b)[0],(a)[0]);\ - GIM_SWAP_NUMBERS((b)[1],(a)[1]);\ - GIM_SWAP_NUMBERS((b)[2],(a)[2]);\ -}\ +#define VEC_SWAP(b, a) \ + { \ + GIM_SWAP_NUMBERS((b)[0], (a)[0]); \ + GIM_SWAP_NUMBERS((b)[1], (a)[1]); \ + GIM_SWAP_NUMBERS((b)[2], (a)[2]); \ + } /// Vector difference -#define VEC_DIFF_2(v21,v2,v1) \ -{ \ - (v21)[0] = (v2)[0] - (v1)[0]; \ - (v21)[1] = (v2)[1] - (v1)[1]; \ -}\ - +#define VEC_DIFF_2(v21, v2, v1) \ + { \ + (v21)[0] = (v2)[0] - (v1)[0]; \ + (v21)[1] = (v2)[1] - (v1)[1]; \ + } /// Vector difference -#define VEC_DIFF(v21,v2,v1) \ -{ \ - (v21)[0] = (v2)[0] - (v1)[0]; \ - (v21)[1] = (v2)[1] - (v1)[1]; \ - (v21)[2] = (v2)[2] - (v1)[2]; \ -}\ - +#define VEC_DIFF(v21, v2, v1) \ + { \ + (v21)[0] = (v2)[0] - (v1)[0]; \ + (v21)[1] = (v2)[1] - (v1)[1]; \ + (v21)[2] = (v2)[2] - (v1)[2]; \ + } /// Vector difference -#define VEC_DIFF_4(v21,v2,v1) \ -{ \ - (v21)[0] = (v2)[0] - (v1)[0]; \ - (v21)[1] = (v2)[1] - (v1)[1]; \ - (v21)[2] = (v2)[2] - (v1)[2]; \ - (v21)[3] = (v2)[3] - (v1)[3]; \ -}\ - +#define VEC_DIFF_4(v21, v2, v1) \ + { \ + (v21)[0] = (v2)[0] - (v1)[0]; \ + (v21)[1] = (v2)[1] - (v1)[1]; \ + (v21)[2] = (v2)[2] - (v1)[2]; \ + (v21)[3] = (v2)[3] - (v1)[3]; \ + } /// Vector sum -#define VEC_SUM_2(v21,v2,v1) \ -{ \ - (v21)[0] = (v2)[0] + (v1)[0]; \ - (v21)[1] = (v2)[1] + (v1)[1]; \ -}\ - +#define VEC_SUM_2(v21, v2, v1) \ + { \ + (v21)[0] = (v2)[0] + (v1)[0]; \ + (v21)[1] = (v2)[1] + (v1)[1]; \ + } /// Vector sum -#define VEC_SUM(v21,v2,v1) \ -{ \ - (v21)[0] = (v2)[0] + (v1)[0]; \ - (v21)[1] = (v2)[1] + (v1)[1]; \ - (v21)[2] = (v2)[2] + (v1)[2]; \ -}\ - +#define VEC_SUM(v21, v2, v1) \ + { \ + (v21)[0] = (v2)[0] + (v1)[0]; \ + (v21)[1] = (v2)[1] + (v1)[1]; \ + (v21)[2] = (v2)[2] + (v1)[2]; \ + } /// Vector sum -#define VEC_SUM_4(v21,v2,v1) \ -{ \ - (v21)[0] = (v2)[0] + (v1)[0]; \ - (v21)[1] = (v2)[1] + (v1)[1]; \ - (v21)[2] = (v2)[2] + (v1)[2]; \ - (v21)[3] = (v2)[3] + (v1)[3]; \ -}\ - +#define VEC_SUM_4(v21, v2, v1) \ + { \ + (v21)[0] = (v2)[0] + (v1)[0]; \ + (v21)[1] = (v2)[1] + (v1)[1]; \ + (v21)[2] = (v2)[2] + (v1)[2]; \ + (v21)[3] = (v2)[3] + (v1)[3]; \ + } /// scalar times vector -#define VEC_SCALE_2(c,a,b) \ -{ \ - (c)[0] = (a)*(b)[0]; \ - (c)[1] = (a)*(b)[1]; \ -}\ - +#define VEC_SCALE_2(c, a, b) \ + { \ + (c)[0] = (a) * (b)[0]; \ + (c)[1] = (a) * (b)[1]; \ + } /// scalar times vector -#define VEC_SCALE(c,a,b) \ -{ \ - (c)[0] = (a)*(b)[0]; \ - (c)[1] = (a)*(b)[1]; \ - (c)[2] = (a)*(b)[2]; \ -}\ - +#define VEC_SCALE(c, a, b) \ + { \ + (c)[0] = (a) * (b)[0]; \ + (c)[1] = (a) * (b)[1]; \ + (c)[2] = (a) * (b)[2]; \ + } /// scalar times vector -#define VEC_SCALE_4(c,a,b) \ -{ \ - (c)[0] = (a)*(b)[0]; \ - (c)[1] = (a)*(b)[1]; \ - (c)[2] = (a)*(b)[2]; \ - (c)[3] = (a)*(b)[3]; \ -}\ - +#define VEC_SCALE_4(c, a, b) \ + { \ + (c)[0] = (a) * (b)[0]; \ + (c)[1] = (a) * (b)[1]; \ + (c)[2] = (a) * (b)[2]; \ + (c)[3] = (a) * (b)[3]; \ + } /// accumulate scaled vector -#define VEC_ACCUM_2(c,a,b) \ -{ \ - (c)[0] += (a)*(b)[0]; \ - (c)[1] += (a)*(b)[1]; \ -}\ - +#define VEC_ACCUM_2(c, a, b) \ + { \ + (c)[0] += (a) * (b)[0]; \ + (c)[1] += (a) * (b)[1]; \ + } /// accumulate scaled vector -#define VEC_ACCUM(c,a,b) \ -{ \ - (c)[0] += (a)*(b)[0]; \ - (c)[1] += (a)*(b)[1]; \ - (c)[2] += (a)*(b)[2]; \ -}\ - +#define VEC_ACCUM(c, a, b) \ + { \ + (c)[0] += (a) * (b)[0]; \ + (c)[1] += (a) * (b)[1]; \ + (c)[2] += (a) * (b)[2]; \ + } /// accumulate scaled vector -#define VEC_ACCUM_4(c,a,b) \ -{ \ - (c)[0] += (a)*(b)[0]; \ - (c)[1] += (a)*(b)[1]; \ - (c)[2] += (a)*(b)[2]; \ - (c)[3] += (a)*(b)[3]; \ -}\ - +#define VEC_ACCUM_4(c, a, b) \ + { \ + (c)[0] += (a) * (b)[0]; \ + (c)[1] += (a) * (b)[1]; \ + (c)[2] += (a) * (b)[2]; \ + (c)[3] += (a) * (b)[3]; \ + } /// Vector dot product -#define VEC_DOT_2(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1]) - +#define VEC_DOT_2(a, b) ((a)[0] * (b)[0] + (a)[1] * (b)[1]) /// Vector dot product -#define VEC_DOT(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2]) +#define VEC_DOT(a, b) ((a)[0] * (b)[0] + (a)[1] * (b)[1] + (a)[2] * (b)[2]) /// Vector dot product -#define VEC_DOT_4(a,b) ((a)[0]*(b)[0] + (a)[1]*(b)[1] + (a)[2]*(b)[2] + (a)[3]*(b)[3]) +#define VEC_DOT_4(a, b) ((a)[0] * (b)[0] + (a)[1] * (b)[1] + (a)[2] * (b)[2] + (a)[3] * (b)[3]) /// vector impact parameter (squared) -#define VEC_IMPACT_SQ(bsq,direction,position) {\ - GREAL _llel_ = VEC_DOT(direction, position);\ - bsq = VEC_DOT(position, position) - _llel_*_llel_;\ -}\ - +#define VEC_IMPACT_SQ(bsq, direction, position) \ + { \ + GREAL _llel_ = VEC_DOT(direction, position); \ + bsq = VEC_DOT(position, position) - _llel_ * _llel_; \ + } /// vector impact parameter -#define VEC_IMPACT(bsq,direction,position) {\ - VEC_IMPACT_SQ(bsq,direction,position); \ - GIM_SQRT(bsq,bsq); \ -}\ +#define VEC_IMPACT(bsq, direction, position) \ + { \ + VEC_IMPACT_SQ(bsq, direction, position); \ + GIM_SQRT(bsq, bsq); \ + } /// Vector length -#define VEC_LENGTH_2(a,l)\ -{\ - GREAL _pp = VEC_DOT_2(a,a);\ - GIM_SQRT(_pp,l);\ -}\ - +#define VEC_LENGTH_2(a, l) \ + { \ + GREAL _pp = VEC_DOT_2(a, a); \ + GIM_SQRT(_pp, l); \ + } /// Vector length -#define VEC_LENGTH(a,l)\ -{\ - GREAL _pp = VEC_DOT(a,a);\ - GIM_SQRT(_pp,l);\ -}\ - +#define VEC_LENGTH(a, l) \ + { \ + GREAL _pp = VEC_DOT(a, a); \ + GIM_SQRT(_pp, l); \ + } /// Vector length -#define VEC_LENGTH_4(a,l)\ -{\ - GREAL _pp = VEC_DOT_4(a,a);\ - GIM_SQRT(_pp,l);\ -}\ +#define VEC_LENGTH_4(a, l) \ + { \ + GREAL _pp = VEC_DOT_4(a, a); \ + GIM_SQRT(_pp, l); \ + } /// Vector inv length -#define VEC_INV_LENGTH_2(a,l)\ -{\ - GREAL _pp = VEC_DOT_2(a,a);\ - GIM_INV_SQRT(_pp,l);\ -}\ - +#define VEC_INV_LENGTH_2(a, l) \ + { \ + GREAL _pp = VEC_DOT_2(a, a); \ + GIM_INV_SQRT(_pp, l); \ + } /// Vector inv length -#define VEC_INV_LENGTH(a,l)\ -{\ - GREAL _pp = VEC_DOT(a,a);\ - GIM_INV_SQRT(_pp,l);\ -}\ - +#define VEC_INV_LENGTH(a, l) \ + { \ + GREAL _pp = VEC_DOT(a, a); \ + GIM_INV_SQRT(_pp, l); \ + } /// Vector inv length -#define VEC_INV_LENGTH_4(a,l)\ -{\ - GREAL _pp = VEC_DOT_4(a,a);\ - GIM_INV_SQRT(_pp,l);\ -}\ - - +#define VEC_INV_LENGTH_4(a, l) \ + { \ + GREAL _pp = VEC_DOT_4(a, a); \ + GIM_INV_SQRT(_pp, l); \ + } /// distance between two points -#define VEC_DISTANCE(_len,_va,_vb) {\ - vec3f _tmp_; \ - VEC_DIFF(_tmp_, _vb, _va); \ - VEC_LENGTH(_tmp_,_len); \ -}\ - +#define VEC_DISTANCE(_len, _va, _vb) \ + { \ + vec3f _tmp_; \ + VEC_DIFF(_tmp_, _vb, _va); \ + VEC_LENGTH(_tmp_, _len); \ + } /// Vector length -#define VEC_CONJUGATE_LENGTH(a,l)\ -{\ - GREAL _pp = 1.0 - a[0]*a[0] - a[1]*a[1] - a[2]*a[2];\ - GIM_SQRT(_pp,l);\ -}\ - +#define VEC_CONJUGATE_LENGTH(a, l) \ + { \ + GREAL _pp = 1.0 - a[0] * a[0] - a[1] * a[1] - a[2] * a[2]; \ + GIM_SQRT(_pp, l); \ + } /// Vector length -#define VEC_NORMALIZE(a) { \ - GREAL len;\ - VEC_INV_LENGTH(a,len); \ - if(lenA[1]?(A[0]>A[2]?0:2):(A[1]>A[2]?1:2);\ -}\ +#define VEC_MAYOR_COORD(vec, maxc) \ + { \ + GREAL A[] = {fabs(vec[0]), fabs(vec[1]), fabs(vec[2])}; \ + maxc = A[0] > A[1] ? (A[0] > A[2] ? 0 : 2) : (A[1] > A[2] ? 1 : 2); \ + } //! Finds the 2 smallest cartesian coordinates from a vector -#define VEC_MINOR_AXES(vec, i0, i1)\ -{\ - VEC_MAYOR_COORD(vec,i0);\ - i0 = (i0+1)%3;\ - i1 = (i0+1)%3;\ -}\ +#define VEC_MINOR_AXES(vec, i0, i1) \ + { \ + VEC_MAYOR_COORD(vec, i0); \ + i0 = (i0 + 1) % 3; \ + i1 = (i0 + 1) % 3; \ + } +#define VEC_EQUAL(v1, v2) (v1[0] == v2[0] && v1[1] == v2[1] && v1[2] == v2[2]) - - -#define VEC_EQUAL(v1,v2) (v1[0]==v2[0]&&v1[1]==v2[1]&&v1[2]==v2[2]) - -#define VEC_NEAR_EQUAL(v1,v2) (GIM_NEAR_EQUAL(v1[0],v2[0])&&GIM_NEAR_EQUAL(v1[1],v2[1])&&GIM_NEAR_EQUAL(v1[2],v2[2])) - +#define VEC_NEAR_EQUAL(v1, v2) (GIM_NEAR_EQUAL(v1[0], v2[0]) && GIM_NEAR_EQUAL(v1[1], v2[1]) && GIM_NEAR_EQUAL(v1[2], v2[2])) /// Vector cross -#define X_AXIS_CROSS_VEC(dst,src)\ -{ \ - dst[0] = 0.0f; \ - dst[1] = -src[2]; \ - dst[2] = src[1]; \ -}\ - -#define Y_AXIS_CROSS_VEC(dst,src)\ -{ \ - dst[0] = src[2]; \ - dst[1] = 0.0f; \ - dst[2] = -src[0]; \ -}\ - -#define Z_AXIS_CROSS_VEC(dst,src)\ -{ \ - dst[0] = -src[1]; \ - dst[1] = src[0]; \ - dst[2] = 0.0f; \ -}\ - - - +#define X_AXIS_CROSS_VEC(dst, src) \ + { \ + dst[0] = 0.0f; \ + dst[1] = -src[2]; \ + dst[2] = src[1]; \ + } +#define Y_AXIS_CROSS_VEC(dst, src) \ + { \ + dst[0] = src[2]; \ + dst[1] = 0.0f; \ + dst[2] = -src[0]; \ + } +#define Z_AXIS_CROSS_VEC(dst, src) \ + { \ + dst[0] = -src[1]; \ + dst[1] = src[0]; \ + dst[2] = 0.0f; \ + } /// initialize matrix -#define IDENTIFY_MATRIX_3X3(m) \ -{ \ - m[0][0] = 1.0; \ - m[0][1] = 0.0; \ - m[0][2] = 0.0; \ - \ - m[1][0] = 0.0; \ - m[1][1] = 1.0; \ - m[1][2] = 0.0; \ - \ - m[2][0] = 0.0; \ - m[2][1] = 0.0; \ - m[2][2] = 1.0; \ -}\ +#define IDENTIFY_MATRIX_3X3(m) \ + { \ + m[0][0] = 1.0; \ + m[0][1] = 0.0; \ + m[0][2] = 0.0; \ + \ + m[1][0] = 0.0; \ + m[1][1] = 1.0; \ + m[1][2] = 0.0; \ + \ + m[2][0] = 0.0; \ + m[2][1] = 0.0; \ + m[2][2] = 1.0; \ + } /*! initialize matrix */ -#define IDENTIFY_MATRIX_4X4(m) \ -{ \ - m[0][0] = 1.0; \ - m[0][1] = 0.0; \ - m[0][2] = 0.0; \ - m[0][3] = 0.0; \ - \ - m[1][0] = 0.0; \ - m[1][1] = 1.0; \ - m[1][2] = 0.0; \ - m[1][3] = 0.0; \ - \ - m[2][0] = 0.0; \ - m[2][1] = 0.0; \ - m[2][2] = 1.0; \ - m[2][3] = 0.0; \ - \ - m[3][0] = 0.0; \ - m[3][1] = 0.0; \ - m[3][2] = 0.0; \ - m[3][3] = 1.0; \ -}\ +#define IDENTIFY_MATRIX_4X4(m) \ + { \ + m[0][0] = 1.0; \ + m[0][1] = 0.0; \ + m[0][2] = 0.0; \ + m[0][3] = 0.0; \ + \ + m[1][0] = 0.0; \ + m[1][1] = 1.0; \ + m[1][2] = 0.0; \ + m[1][3] = 0.0; \ + \ + m[2][0] = 0.0; \ + m[2][1] = 0.0; \ + m[2][2] = 1.0; \ + m[2][3] = 0.0; \ + \ + m[3][0] = 0.0; \ + m[3][1] = 0.0; \ + m[3][2] = 0.0; \ + m[3][3] = 1.0; \ + } /*! initialize matrix */ -#define ZERO_MATRIX_4X4(m) \ -{ \ - m[0][0] = 0.0; \ - m[0][1] = 0.0; \ - m[0][2] = 0.0; \ - m[0][3] = 0.0; \ - \ - m[1][0] = 0.0; \ - m[1][1] = 0.0; \ - m[1][2] = 0.0; \ - m[1][3] = 0.0; \ - \ - m[2][0] = 0.0; \ - m[2][1] = 0.0; \ - m[2][2] = 0.0; \ - m[2][3] = 0.0; \ - \ - m[3][0] = 0.0; \ - m[3][1] = 0.0; \ - m[3][2] = 0.0; \ - m[3][3] = 0.0; \ -}\ +#define ZERO_MATRIX_4X4(m) \ + { \ + m[0][0] = 0.0; \ + m[0][1] = 0.0; \ + m[0][2] = 0.0; \ + m[0][3] = 0.0; \ + \ + m[1][0] = 0.0; \ + m[1][1] = 0.0; \ + m[1][2] = 0.0; \ + m[1][3] = 0.0; \ + \ + m[2][0] = 0.0; \ + m[2][1] = 0.0; \ + m[2][2] = 0.0; \ + m[2][3] = 0.0; \ + \ + m[3][0] = 0.0; \ + m[3][1] = 0.0; \ + m[3][2] = 0.0; \ + m[3][3] = 0.0; \ + } /*! matrix rotation X */ -#define ROTX_CS(m,cosine,sine) \ -{ \ - /* rotation about the x-axis */ \ - \ - m[0][0] = 1.0; \ - m[0][1] = 0.0; \ - m[0][2] = 0.0; \ - m[0][3] = 0.0; \ - \ - m[1][0] = 0.0; \ - m[1][1] = (cosine); \ - m[1][2] = (sine); \ - m[1][3] = 0.0; \ - \ - m[2][0] = 0.0; \ - m[2][1] = -(sine); \ - m[2][2] = (cosine); \ - m[2][3] = 0.0; \ - \ - m[3][0] = 0.0; \ - m[3][1] = 0.0; \ - m[3][2] = 0.0; \ - m[3][3] = 1.0; \ -}\ +#define ROTX_CS(m, cosine, sine) \ + { \ + /* rotation about the x-axis */ \ + \ + m[0][0] = 1.0; \ + m[0][1] = 0.0; \ + m[0][2] = 0.0; \ + m[0][3] = 0.0; \ + \ + m[1][0] = 0.0; \ + m[1][1] = (cosine); \ + m[1][2] = (sine); \ + m[1][3] = 0.0; \ + \ + m[2][0] = 0.0; \ + m[2][1] = -(sine); \ + m[2][2] = (cosine); \ + m[2][3] = 0.0; \ + \ + m[3][0] = 0.0; \ + m[3][1] = 0.0; \ + m[3][2] = 0.0; \ + m[3][3] = 1.0; \ + } /*! matrix rotation Y */ -#define ROTY_CS(m,cosine,sine) \ -{ \ - /* rotation about the y-axis */ \ - \ - m[0][0] = (cosine); \ - m[0][1] = 0.0; \ - m[0][2] = -(sine); \ - m[0][3] = 0.0; \ - \ - m[1][0] = 0.0; \ - m[1][1] = 1.0; \ - m[1][2] = 0.0; \ - m[1][3] = 0.0; \ - \ - m[2][0] = (sine); \ - m[2][1] = 0.0; \ - m[2][2] = (cosine); \ - m[2][3] = 0.0; \ - \ - m[3][0] = 0.0; \ - m[3][1] = 0.0; \ - m[3][2] = 0.0; \ - m[3][3] = 1.0; \ -}\ +#define ROTY_CS(m, cosine, sine) \ + { \ + /* rotation about the y-axis */ \ + \ + m[0][0] = (cosine); \ + m[0][1] = 0.0; \ + m[0][2] = -(sine); \ + m[0][3] = 0.0; \ + \ + m[1][0] = 0.0; \ + m[1][1] = 1.0; \ + m[1][2] = 0.0; \ + m[1][3] = 0.0; \ + \ + m[2][0] = (sine); \ + m[2][1] = 0.0; \ + m[2][2] = (cosine); \ + m[2][3] = 0.0; \ + \ + m[3][0] = 0.0; \ + m[3][1] = 0.0; \ + m[3][2] = 0.0; \ + m[3][3] = 1.0; \ + } /*! matrix rotation Z */ -#define ROTZ_CS(m,cosine,sine) \ -{ \ - /* rotation about the z-axis */ \ - \ - m[0][0] = (cosine); \ - m[0][1] = (sine); \ - m[0][2] = 0.0; \ - m[0][3] = 0.0; \ - \ - m[1][0] = -(sine); \ - m[1][1] = (cosine); \ - m[1][2] = 0.0; \ - m[1][3] = 0.0; \ - \ - m[2][0] = 0.0; \ - m[2][1] = 0.0; \ - m[2][2] = 1.0; \ - m[2][3] = 0.0; \ - \ - m[3][0] = 0.0; \ - m[3][1] = 0.0; \ - m[3][2] = 0.0; \ - m[3][3] = 1.0; \ -}\ +#define ROTZ_CS(m, cosine, sine) \ + { \ + /* rotation about the z-axis */ \ + \ + m[0][0] = (cosine); \ + m[0][1] = (sine); \ + m[0][2] = 0.0; \ + m[0][3] = 0.0; \ + \ + m[1][0] = -(sine); \ + m[1][1] = (cosine); \ + m[1][2] = 0.0; \ + m[1][3] = 0.0; \ + \ + m[2][0] = 0.0; \ + m[2][1] = 0.0; \ + m[2][2] = 1.0; \ + m[2][3] = 0.0; \ + \ + m[3][0] = 0.0; \ + m[3][1] = 0.0; \ + m[3][2] = 0.0; \ + m[3][3] = 1.0; \ + } /*! matrix copy */ -#define COPY_MATRIX_2X2(b,a) \ -{ \ - b[0][0] = a[0][0]; \ - b[0][1] = a[0][1]; \ - \ - b[1][0] = a[1][0]; \ - b[1][1] = a[1][1]; \ - \ -}\ - +#define COPY_MATRIX_2X2(b, a) \ + { \ + b[0][0] = a[0][0]; \ + b[0][1] = a[0][1]; \ + \ + b[1][0] = a[1][0]; \ + b[1][1] = a[1][1]; \ + } /*! matrix copy */ -#define COPY_MATRIX_2X3(b,a) \ -{ \ - b[0][0] = a[0][0]; \ - b[0][1] = a[0][1]; \ - b[0][2] = a[0][2]; \ - \ - b[1][0] = a[1][0]; \ - b[1][1] = a[1][1]; \ - b[1][2] = a[1][2]; \ -}\ - +#define COPY_MATRIX_2X3(b, a) \ + { \ + b[0][0] = a[0][0]; \ + b[0][1] = a[0][1]; \ + b[0][2] = a[0][2]; \ + \ + b[1][0] = a[1][0]; \ + b[1][1] = a[1][1]; \ + b[1][2] = a[1][2]; \ + } /*! matrix copy */ -#define COPY_MATRIX_3X3(b,a) \ -{ \ - b[0][0] = a[0][0]; \ - b[0][1] = a[0][1]; \ - b[0][2] = a[0][2]; \ - \ - b[1][0] = a[1][0]; \ - b[1][1] = a[1][1]; \ - b[1][2] = a[1][2]; \ - \ - b[2][0] = a[2][0]; \ - b[2][1] = a[2][1]; \ - b[2][2] = a[2][2]; \ -}\ - +#define COPY_MATRIX_3X3(b, a) \ + { \ + b[0][0] = a[0][0]; \ + b[0][1] = a[0][1]; \ + b[0][2] = a[0][2]; \ + \ + b[1][0] = a[1][0]; \ + b[1][1] = a[1][1]; \ + b[1][2] = a[1][2]; \ + \ + b[2][0] = a[2][0]; \ + b[2][1] = a[2][1]; \ + b[2][2] = a[2][2]; \ + } /*! matrix copy */ -#define COPY_MATRIX_4X4(b,a) \ -{ \ - b[0][0] = a[0][0]; \ - b[0][1] = a[0][1]; \ - b[0][2] = a[0][2]; \ - b[0][3] = a[0][3]; \ - \ - b[1][0] = a[1][0]; \ - b[1][1] = a[1][1]; \ - b[1][2] = a[1][2]; \ - b[1][3] = a[1][3]; \ - \ - b[2][0] = a[2][0]; \ - b[2][1] = a[2][1]; \ - b[2][2] = a[2][2]; \ - b[2][3] = a[2][3]; \ - \ - b[3][0] = a[3][0]; \ - b[3][1] = a[3][1]; \ - b[3][2] = a[3][2]; \ - b[3][3] = a[3][3]; \ -}\ - +#define COPY_MATRIX_4X4(b, a) \ + { \ + b[0][0] = a[0][0]; \ + b[0][1] = a[0][1]; \ + b[0][2] = a[0][2]; \ + b[0][3] = a[0][3]; \ + \ + b[1][0] = a[1][0]; \ + b[1][1] = a[1][1]; \ + b[1][2] = a[1][2]; \ + b[1][3] = a[1][3]; \ + \ + b[2][0] = a[2][0]; \ + b[2][1] = a[2][1]; \ + b[2][2] = a[2][2]; \ + b[2][3] = a[2][3]; \ + \ + b[3][0] = a[3][0]; \ + b[3][1] = a[3][1]; \ + b[3][2] = a[3][2]; \ + b[3][3] = a[3][3]; \ + } /*! matrix transpose */ -#define TRANSPOSE_MATRIX_2X2(b,a) \ -{ \ - b[0][0] = a[0][0]; \ - b[0][1] = a[1][0]; \ - \ - b[1][0] = a[0][1]; \ - b[1][1] = a[1][1]; \ -}\ - +#define TRANSPOSE_MATRIX_2X2(b, a) \ + { \ + b[0][0] = a[0][0]; \ + b[0][1] = a[1][0]; \ + \ + b[1][0] = a[0][1]; \ + b[1][1] = a[1][1]; \ + } /*! matrix transpose */ -#define TRANSPOSE_MATRIX_3X3(b,a) \ -{ \ - b[0][0] = a[0][0]; \ - b[0][1] = a[1][0]; \ - b[0][2] = a[2][0]; \ - \ - b[1][0] = a[0][1]; \ - b[1][1] = a[1][1]; \ - b[1][2] = a[2][1]; \ - \ - b[2][0] = a[0][2]; \ - b[2][1] = a[1][2]; \ - b[2][2] = a[2][2]; \ -}\ - +#define TRANSPOSE_MATRIX_3X3(b, a) \ + { \ + b[0][0] = a[0][0]; \ + b[0][1] = a[1][0]; \ + b[0][2] = a[2][0]; \ + \ + b[1][0] = a[0][1]; \ + b[1][1] = a[1][1]; \ + b[1][2] = a[2][1]; \ + \ + b[2][0] = a[0][2]; \ + b[2][1] = a[1][2]; \ + b[2][2] = a[2][2]; \ + } /*! matrix transpose */ -#define TRANSPOSE_MATRIX_4X4(b,a) \ -{ \ - b[0][0] = a[0][0]; \ - b[0][1] = a[1][0]; \ - b[0][2] = a[2][0]; \ - b[0][3] = a[3][0]; \ - \ - b[1][0] = a[0][1]; \ - b[1][1] = a[1][1]; \ - b[1][2] = a[2][1]; \ - b[1][3] = a[3][1]; \ - \ - b[2][0] = a[0][2]; \ - b[2][1] = a[1][2]; \ - b[2][2] = a[2][2]; \ - b[2][3] = a[3][2]; \ - \ - b[3][0] = a[0][3]; \ - b[3][1] = a[1][3]; \ - b[3][2] = a[2][3]; \ - b[3][3] = a[3][3]; \ -}\ - +#define TRANSPOSE_MATRIX_4X4(b, a) \ + { \ + b[0][0] = a[0][0]; \ + b[0][1] = a[1][0]; \ + b[0][2] = a[2][0]; \ + b[0][3] = a[3][0]; \ + \ + b[1][0] = a[0][1]; \ + b[1][1] = a[1][1]; \ + b[1][2] = a[2][1]; \ + b[1][3] = a[3][1]; \ + \ + b[2][0] = a[0][2]; \ + b[2][1] = a[1][2]; \ + b[2][2] = a[2][2]; \ + b[2][3] = a[3][2]; \ + \ + b[3][0] = a[0][3]; \ + b[3][1] = a[1][3]; \ + b[3][2] = a[2][3]; \ + b[3][3] = a[3][3]; \ + } /*! multiply matrix by scalar */ -#define SCALE_MATRIX_2X2(b,s,a) \ -{ \ - b[0][0] = (s) * a[0][0]; \ - b[0][1] = (s) * a[0][1]; \ - \ - b[1][0] = (s) * a[1][0]; \ - b[1][1] = (s) * a[1][1]; \ -}\ - +#define SCALE_MATRIX_2X2(b, s, a) \ + { \ + b[0][0] = (s)*a[0][0]; \ + b[0][1] = (s)*a[0][1]; \ + \ + b[1][0] = (s)*a[1][0]; \ + b[1][1] = (s)*a[1][1]; \ + } /*! multiply matrix by scalar */ -#define SCALE_MATRIX_3X3(b,s,a) \ -{ \ - b[0][0] = (s) * a[0][0]; \ - b[0][1] = (s) * a[0][1]; \ - b[0][2] = (s) * a[0][2]; \ - \ - b[1][0] = (s) * a[1][0]; \ - b[1][1] = (s) * a[1][1]; \ - b[1][2] = (s) * a[1][2]; \ - \ - b[2][0] = (s) * a[2][0]; \ - b[2][1] = (s) * a[2][1]; \ - b[2][2] = (s) * a[2][2]; \ -}\ - +#define SCALE_MATRIX_3X3(b, s, a) \ + { \ + b[0][0] = (s)*a[0][0]; \ + b[0][1] = (s)*a[0][1]; \ + b[0][2] = (s)*a[0][2]; \ + \ + b[1][0] = (s)*a[1][0]; \ + b[1][1] = (s)*a[1][1]; \ + b[1][2] = (s)*a[1][2]; \ + \ + b[2][0] = (s)*a[2][0]; \ + b[2][1] = (s)*a[2][1]; \ + b[2][2] = (s)*a[2][2]; \ + } /*! multiply matrix by scalar */ -#define SCALE_MATRIX_4X4(b,s,a) \ -{ \ - b[0][0] = (s) * a[0][0]; \ - b[0][1] = (s) * a[0][1]; \ - b[0][2] = (s) * a[0][2]; \ - b[0][3] = (s) * a[0][3]; \ - \ - b[1][0] = (s) * a[1][0]; \ - b[1][1] = (s) * a[1][1]; \ - b[1][2] = (s) * a[1][2]; \ - b[1][3] = (s) * a[1][3]; \ - \ - b[2][0] = (s) * a[2][0]; \ - b[2][1] = (s) * a[2][1]; \ - b[2][2] = (s) * a[2][2]; \ - b[2][3] = (s) * a[2][3]; \ - \ - b[3][0] = s * a[3][0]; \ - b[3][1] = s * a[3][1]; \ - b[3][2] = s * a[3][2]; \ - b[3][3] = s * a[3][3]; \ -}\ - +#define SCALE_MATRIX_4X4(b, s, a) \ + { \ + b[0][0] = (s)*a[0][0]; \ + b[0][1] = (s)*a[0][1]; \ + b[0][2] = (s)*a[0][2]; \ + b[0][3] = (s)*a[0][3]; \ + \ + b[1][0] = (s)*a[1][0]; \ + b[1][1] = (s)*a[1][1]; \ + b[1][2] = (s)*a[1][2]; \ + b[1][3] = (s)*a[1][3]; \ + \ + b[2][0] = (s)*a[2][0]; \ + b[2][1] = (s)*a[2][1]; \ + b[2][2] = (s)*a[2][2]; \ + b[2][3] = (s)*a[2][3]; \ + \ + b[3][0] = s * a[3][0]; \ + b[3][1] = s * a[3][1]; \ + b[3][2] = s * a[3][2]; \ + b[3][3] = s * a[3][3]; \ + } /*! multiply matrix by scalar */ -#define SCALE_VEC_MATRIX_2X2(b,svec,a) \ -{ \ - b[0][0] = svec[0] * a[0][0]; \ - b[1][0] = svec[0] * a[1][0]; \ - \ - b[0][1] = svec[1] * a[0][1]; \ - b[1][1] = svec[1] * a[1][1]; \ -}\ - +#define SCALE_VEC_MATRIX_2X2(b, svec, a) \ + { \ + b[0][0] = svec[0] * a[0][0]; \ + b[1][0] = svec[0] * a[1][0]; \ + \ + b[0][1] = svec[1] * a[0][1]; \ + b[1][1] = svec[1] * a[1][1]; \ + } /*! multiply matrix by scalar. Each columns is scaled by each scalar vector component */ -#define SCALE_VEC_MATRIX_3X3(b,svec,a) \ -{ \ - b[0][0] = svec[0] * a[0][0]; \ - b[1][0] = svec[0] * a[1][0]; \ - b[2][0] = svec[0] * a[2][0]; \ - \ - b[0][1] = svec[1] * a[0][1]; \ - b[1][1] = svec[1] * a[1][1]; \ - b[2][1] = svec[1] * a[2][1]; \ - \ - b[0][2] = svec[2] * a[0][2]; \ - b[1][2] = svec[2] * a[1][2]; \ - b[2][2] = svec[2] * a[2][2]; \ -}\ - +#define SCALE_VEC_MATRIX_3X3(b, svec, a) \ + { \ + b[0][0] = svec[0] * a[0][0]; \ + b[1][0] = svec[0] * a[1][0]; \ + b[2][0] = svec[0] * a[2][0]; \ + \ + b[0][1] = svec[1] * a[0][1]; \ + b[1][1] = svec[1] * a[1][1]; \ + b[2][1] = svec[1] * a[2][1]; \ + \ + b[0][2] = svec[2] * a[0][2]; \ + b[1][2] = svec[2] * a[1][2]; \ + b[2][2] = svec[2] * a[2][2]; \ + } /*! multiply matrix by scalar */ -#define SCALE_VEC_MATRIX_4X4(b,svec,a) \ -{ \ - b[0][0] = svec[0] * a[0][0]; \ - b[1][0] = svec[0] * a[1][0]; \ - b[2][0] = svec[0] * a[2][0]; \ - b[3][0] = svec[0] * a[3][0]; \ - \ - b[0][1] = svec[1] * a[0][1]; \ - b[1][1] = svec[1] * a[1][1]; \ - b[2][1] = svec[1] * a[2][1]; \ - b[3][1] = svec[1] * a[3][1]; \ - \ - b[0][2] = svec[2] * a[0][2]; \ - b[1][2] = svec[2] * a[1][2]; \ - b[2][2] = svec[2] * a[2][2]; \ - b[3][2] = svec[2] * a[3][2]; \ - \ - b[0][3] = svec[3] * a[0][3]; \ - b[1][3] = svec[3] * a[1][3]; \ - b[2][3] = svec[3] * a[2][3]; \ - b[3][3] = svec[3] * a[3][3]; \ -}\ - +#define SCALE_VEC_MATRIX_4X4(b, svec, a) \ + { \ + b[0][0] = svec[0] * a[0][0]; \ + b[1][0] = svec[0] * a[1][0]; \ + b[2][0] = svec[0] * a[2][0]; \ + b[3][0] = svec[0] * a[3][0]; \ + \ + b[0][1] = svec[1] * a[0][1]; \ + b[1][1] = svec[1] * a[1][1]; \ + b[2][1] = svec[1] * a[2][1]; \ + b[3][1] = svec[1] * a[3][1]; \ + \ + b[0][2] = svec[2] * a[0][2]; \ + b[1][2] = svec[2] * a[1][2]; \ + b[2][2] = svec[2] * a[2][2]; \ + b[3][2] = svec[2] * a[3][2]; \ + \ + b[0][3] = svec[3] * a[0][3]; \ + b[1][3] = svec[3] * a[1][3]; \ + b[2][3] = svec[3] * a[2][3]; \ + b[3][3] = svec[3] * a[3][3]; \ + } /*! multiply matrix by scalar */ -#define ACCUM_SCALE_MATRIX_2X2(b,s,a) \ -{ \ - b[0][0] += (s) * a[0][0]; \ - b[0][1] += (s) * a[0][1]; \ - \ - b[1][0] += (s) * a[1][0]; \ - b[1][1] += (s) * a[1][1]; \ -}\ - +#define ACCUM_SCALE_MATRIX_2X2(b, s, a) \ + { \ + b[0][0] += (s)*a[0][0]; \ + b[0][1] += (s)*a[0][1]; \ + \ + b[1][0] += (s)*a[1][0]; \ + b[1][1] += (s)*a[1][1]; \ + } /*! multiply matrix by scalar */ -#define ACCUM_SCALE_MATRIX_3X3(b,s,a) \ -{ \ - b[0][0] += (s) * a[0][0]; \ - b[0][1] += (s) * a[0][1]; \ - b[0][2] += (s) * a[0][2]; \ - \ - b[1][0] += (s) * a[1][0]; \ - b[1][1] += (s) * a[1][1]; \ - b[1][2] += (s) * a[1][2]; \ - \ - b[2][0] += (s) * a[2][0]; \ - b[2][1] += (s) * a[2][1]; \ - b[2][2] += (s) * a[2][2]; \ -}\ - +#define ACCUM_SCALE_MATRIX_3X3(b, s, a) \ + { \ + b[0][0] += (s)*a[0][0]; \ + b[0][1] += (s)*a[0][1]; \ + b[0][2] += (s)*a[0][2]; \ + \ + b[1][0] += (s)*a[1][0]; \ + b[1][1] += (s)*a[1][1]; \ + b[1][2] += (s)*a[1][2]; \ + \ + b[2][0] += (s)*a[2][0]; \ + b[2][1] += (s)*a[2][1]; \ + b[2][2] += (s)*a[2][2]; \ + } /*! multiply matrix by scalar */ -#define ACCUM_SCALE_MATRIX_4X4(b,s,a) \ -{ \ - b[0][0] += (s) * a[0][0]; \ - b[0][1] += (s) * a[0][1]; \ - b[0][2] += (s) * a[0][2]; \ - b[0][3] += (s) * a[0][3]; \ - \ - b[1][0] += (s) * a[1][0]; \ - b[1][1] += (s) * a[1][1]; \ - b[1][2] += (s) * a[1][2]; \ - b[1][3] += (s) * a[1][3]; \ - \ - b[2][0] += (s) * a[2][0]; \ - b[2][1] += (s) * a[2][1]; \ - b[2][2] += (s) * a[2][2]; \ - b[2][3] += (s) * a[2][3]; \ - \ - b[3][0] += (s) * a[3][0]; \ - b[3][1] += (s) * a[3][1]; \ - b[3][2] += (s) * a[3][2]; \ - b[3][3] += (s) * a[3][3]; \ -}\ +#define ACCUM_SCALE_MATRIX_4X4(b, s, a) \ + { \ + b[0][0] += (s)*a[0][0]; \ + b[0][1] += (s)*a[0][1]; \ + b[0][2] += (s)*a[0][2]; \ + b[0][3] += (s)*a[0][3]; \ + \ + b[1][0] += (s)*a[1][0]; \ + b[1][1] += (s)*a[1][1]; \ + b[1][2] += (s)*a[1][2]; \ + b[1][3] += (s)*a[1][3]; \ + \ + b[2][0] += (s)*a[2][0]; \ + b[2][1] += (s)*a[2][1]; \ + b[2][2] += (s)*a[2][2]; \ + b[2][3] += (s)*a[2][3]; \ + \ + b[3][0] += (s)*a[3][0]; \ + b[3][1] += (s)*a[3][1]; \ + b[3][2] += (s)*a[3][2]; \ + b[3][3] += (s)*a[3][3]; \ + } /*! matrix product */ /*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/ -#define MATRIX_PRODUCT_2X2(c,a,b) \ -{ \ - c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]; \ - c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]; \ - \ - c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]; \ - c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]; \ - \ -}\ +#define MATRIX_PRODUCT_2X2(c, a, b) \ + { \ + c[0][0] = a[0][0] * b[0][0] + a[0][1] * b[1][0]; \ + c[0][1] = a[0][0] * b[0][1] + a[0][1] * b[1][1]; \ + \ + c[1][0] = a[1][0] * b[0][0] + a[1][1] * b[1][0]; \ + c[1][1] = a[1][0] * b[0][1] + a[1][1] * b[1][1]; \ + } /*! matrix product */ /*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/ -#define MATRIX_PRODUCT_3X3(c,a,b) \ -{ \ - c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0]; \ - c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1]; \ - c[0][2] = a[0][0]*b[0][2]+a[0][1]*b[1][2]+a[0][2]*b[2][2]; \ - \ - c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]+a[1][2]*b[2][0]; \ - c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]+a[1][2]*b[2][1]; \ - c[1][2] = a[1][0]*b[0][2]+a[1][1]*b[1][2]+a[1][2]*b[2][2]; \ - \ - c[2][0] = a[2][0]*b[0][0]+a[2][1]*b[1][0]+a[2][2]*b[2][0]; \ - c[2][1] = a[2][0]*b[0][1]+a[2][1]*b[1][1]+a[2][2]*b[2][1]; \ - c[2][2] = a[2][0]*b[0][2]+a[2][1]*b[1][2]+a[2][2]*b[2][2]; \ -}\ - +#define MATRIX_PRODUCT_3X3(c, a, b) \ + { \ + c[0][0] = a[0][0] * b[0][0] + a[0][1] * b[1][0] + a[0][2] * b[2][0]; \ + c[0][1] = a[0][0] * b[0][1] + a[0][1] * b[1][1] + a[0][2] * b[2][1]; \ + c[0][2] = a[0][0] * b[0][2] + a[0][1] * b[1][2] + a[0][2] * b[2][2]; \ + \ + c[1][0] = a[1][0] * b[0][0] + a[1][1] * b[1][0] + a[1][2] * b[2][0]; \ + c[1][1] = a[1][0] * b[0][1] + a[1][1] * b[1][1] + a[1][2] * b[2][1]; \ + c[1][2] = a[1][0] * b[0][2] + a[1][1] * b[1][2] + a[1][2] * b[2][2]; \ + \ + c[2][0] = a[2][0] * b[0][0] + a[2][1] * b[1][0] + a[2][2] * b[2][0]; \ + c[2][1] = a[2][0] * b[0][1] + a[2][1] * b[1][1] + a[2][2] * b[2][1]; \ + c[2][2] = a[2][0] * b[0][2] + a[2][1] * b[1][2] + a[2][2] * b[2][2]; \ + } /*! matrix product */ /*! c[x][y] = a[x][0]*b[0][y]+a[x][1]*b[1][y]+a[x][2]*b[2][y]+a[x][3]*b[3][y];*/ -#define MATRIX_PRODUCT_4X4(c,a,b) \ -{ \ - c[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0]+a[0][2]*b[2][0]+a[0][3]*b[3][0];\ - c[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1]+a[0][2]*b[2][1]+a[0][3]*b[3][1];\ - c[0][2] = a[0][0]*b[0][2]+a[0][1]*b[1][2]+a[0][2]*b[2][2]+a[0][3]*b[3][2];\ - c[0][3] = a[0][0]*b[0][3]+a[0][1]*b[1][3]+a[0][2]*b[2][3]+a[0][3]*b[3][3];\ - \ - c[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0]+a[1][2]*b[2][0]+a[1][3]*b[3][0];\ - c[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1]+a[1][2]*b[2][1]+a[1][3]*b[3][1];\ - c[1][2] = a[1][0]*b[0][2]+a[1][1]*b[1][2]+a[1][2]*b[2][2]+a[1][3]*b[3][2];\ - c[1][3] = a[1][0]*b[0][3]+a[1][1]*b[1][3]+a[1][2]*b[2][3]+a[1][3]*b[3][3];\ - \ - c[2][0] = a[2][0]*b[0][0]+a[2][1]*b[1][0]+a[2][2]*b[2][0]+a[2][3]*b[3][0];\ - c[2][1] = a[2][0]*b[0][1]+a[2][1]*b[1][1]+a[2][2]*b[2][1]+a[2][3]*b[3][1];\ - c[2][2] = a[2][0]*b[0][2]+a[2][1]*b[1][2]+a[2][2]*b[2][2]+a[2][3]*b[3][2];\ - c[2][3] = a[2][0]*b[0][3]+a[2][1]*b[1][3]+a[2][2]*b[2][3]+a[2][3]*b[3][3];\ - \ - c[3][0] = a[3][0]*b[0][0]+a[3][1]*b[1][0]+a[3][2]*b[2][0]+a[3][3]*b[3][0];\ - c[3][1] = a[3][0]*b[0][1]+a[3][1]*b[1][1]+a[3][2]*b[2][1]+a[3][3]*b[3][1];\ - c[3][2] = a[3][0]*b[0][2]+a[3][1]*b[1][2]+a[3][2]*b[2][2]+a[3][3]*b[3][2];\ - c[3][3] = a[3][0]*b[0][3]+a[3][1]*b[1][3]+a[3][2]*b[2][3]+a[3][3]*b[3][3];\ -}\ - +#define MATRIX_PRODUCT_4X4(c, a, b) \ + { \ + c[0][0] = a[0][0] * b[0][0] + a[0][1] * b[1][0] + a[0][2] * b[2][0] + a[0][3] * b[3][0]; \ + c[0][1] = a[0][0] * b[0][1] + a[0][1] * b[1][1] + a[0][2] * b[2][1] + a[0][3] * b[3][1]; \ + c[0][2] = a[0][0] * b[0][2] + a[0][1] * b[1][2] + a[0][2] * b[2][2] + a[0][3] * b[3][2]; \ + c[0][3] = a[0][0] * b[0][3] + a[0][1] * b[1][3] + a[0][2] * b[2][3] + a[0][3] * b[3][3]; \ + \ + c[1][0] = a[1][0] * b[0][0] + a[1][1] * b[1][0] + a[1][2] * b[2][0] + a[1][3] * b[3][0]; \ + c[1][1] = a[1][0] * b[0][1] + a[1][1] * b[1][1] + a[1][2] * b[2][1] + a[1][3] * b[3][1]; \ + c[1][2] = a[1][0] * b[0][2] + a[1][1] * b[1][2] + a[1][2] * b[2][2] + a[1][3] * b[3][2]; \ + c[1][3] = a[1][0] * b[0][3] + a[1][1] * b[1][3] + a[1][2] * b[2][3] + a[1][3] * b[3][3]; \ + \ + c[2][0] = a[2][0] * b[0][0] + a[2][1] * b[1][0] + a[2][2] * b[2][0] + a[2][3] * b[3][0]; \ + c[2][1] = a[2][0] * b[0][1] + a[2][1] * b[1][1] + a[2][2] * b[2][1] + a[2][3] * b[3][1]; \ + c[2][2] = a[2][0] * b[0][2] + a[2][1] * b[1][2] + a[2][2] * b[2][2] + a[2][3] * b[3][2]; \ + c[2][3] = a[2][0] * b[0][3] + a[2][1] * b[1][3] + a[2][2] * b[2][3] + a[2][3] * b[3][3]; \ + \ + c[3][0] = a[3][0] * b[0][0] + a[3][1] * b[1][0] + a[3][2] * b[2][0] + a[3][3] * b[3][0]; \ + c[3][1] = a[3][0] * b[0][1] + a[3][1] * b[1][1] + a[3][2] * b[2][1] + a[3][3] * b[3][1]; \ + c[3][2] = a[3][0] * b[0][2] + a[3][1] * b[1][2] + a[3][2] * b[2][2] + a[3][3] * b[3][2]; \ + c[3][3] = a[3][0] * b[0][3] + a[3][1] * b[1][3] + a[3][2] * b[2][3] + a[3][3] * b[3][3]; \ + } /*! matrix times vector */ -#define MAT_DOT_VEC_2X2(p,m,v) \ -{ \ - p[0] = m[0][0]*v[0] + m[0][1]*v[1]; \ - p[1] = m[1][0]*v[0] + m[1][1]*v[1]; \ -}\ - +#define MAT_DOT_VEC_2X2(p, m, v) \ + { \ + p[0] = m[0][0] * v[0] + m[0][1] * v[1]; \ + p[1] = m[1][0] * v[0] + m[1][1] * v[1]; \ + } /*! matrix times vector */ -#define MAT_DOT_VEC_3X3(p,m,v) \ -{ \ - p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2]; \ - p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2]; \ - p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2]; \ -}\ - +#define MAT_DOT_VEC_3X3(p, m, v) \ + { \ + p[0] = m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2]; \ + p[1] = m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2]; \ + p[2] = m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2]; \ + } /*! matrix times vector v is a vec4f */ -#define MAT_DOT_VEC_4X4(p,m,v) \ -{ \ - p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2] + m[0][3]*v[3]; \ - p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2] + m[1][3]*v[3]; \ - p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2] + m[2][3]*v[3]; \ - p[3] = m[3][0]*v[0] + m[3][1]*v[1] + m[3][2]*v[2] + m[3][3]*v[3]; \ -}\ +#define MAT_DOT_VEC_4X4(p, m, v) \ + { \ + p[0] = m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2] + m[0][3] * v[3]; \ + p[1] = m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2] + m[1][3] * v[3]; \ + p[2] = m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2] + m[2][3] * v[3]; \ + p[3] = m[3][0] * v[0] + m[3][1] * v[1] + m[3][2] * v[2] + m[3][3] * v[3]; \ + } /*! matrix times vector v is a vec3f and m is a mat4f
    Last column is added as the position */ -#define MAT_DOT_VEC_3X4(p,m,v) \ -{ \ - p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]*v[2] + m[0][3]; \ - p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]*v[2] + m[1][3]; \ - p[2] = m[2][0]*v[0] + m[2][1]*v[1] + m[2][2]*v[2] + m[2][3]; \ -}\ - +#define MAT_DOT_VEC_3X4(p, m, v) \ + { \ + p[0] = m[0][0] * v[0] + m[0][1] * v[1] + m[0][2] * v[2] + m[0][3]; \ + p[1] = m[1][0] * v[0] + m[1][1] * v[1] + m[1][2] * v[2] + m[1][3]; \ + p[2] = m[2][0] * v[0] + m[2][1] * v[1] + m[2][2] * v[2] + m[2][3]; \ + } /*! vector transpose times matrix */ /*! p[j] = v[0]*m[0][j] + v[1]*m[1][j] + v[2]*m[2][j]; */ -#define VEC_DOT_MAT_3X3(p,v,m) \ -{ \ - p[0] = v[0]*m[0][0] + v[1]*m[1][0] + v[2]*m[2][0]; \ - p[1] = v[0]*m[0][1] + v[1]*m[1][1] + v[2]*m[2][1]; \ - p[2] = v[0]*m[0][2] + v[1]*m[1][2] + v[2]*m[2][2]; \ -}\ - +#define VEC_DOT_MAT_3X3(p, v, m) \ + { \ + p[0] = v[0] * m[0][0] + v[1] * m[1][0] + v[2] * m[2][0]; \ + p[1] = v[0] * m[0][1] + v[1] * m[1][1] + v[2] * m[2][1]; \ + p[2] = v[0] * m[0][2] + v[1] * m[1][2] + v[2] * m[2][2]; \ + } /*! affine matrix times vector */ /** The matrix is assumed to be an affine matrix, with last two * entries representing a translation */ -#define MAT_DOT_VEC_2X3(p,m,v) \ -{ \ - p[0] = m[0][0]*v[0] + m[0][1]*v[1] + m[0][2]; \ - p[1] = m[1][0]*v[0] + m[1][1]*v[1] + m[1][2]; \ -}\ +#define MAT_DOT_VEC_2X3(p, m, v) \ + { \ + p[0] = m[0][0] * v[0] + m[0][1] * v[1] + m[0][2]; \ + p[1] = m[1][0] * v[0] + m[1][1] * v[1] + m[1][2]; \ + } //! Transform a plane -#define MAT_TRANSFORM_PLANE_4X4(pout,m,plane)\ -{ \ - pout[0] = m[0][0]*plane[0] + m[0][1]*plane[1] + m[0][2]*plane[2];\ - pout[1] = m[1][0]*plane[0] + m[1][1]*plane[1] + m[1][2]*plane[2];\ - pout[2] = m[2][0]*plane[0] + m[2][1]*plane[1] + m[2][2]*plane[2];\ - pout[3] = m[0][3]*pout[0] + m[1][3]*pout[1] + m[2][3]*pout[2] + plane[3];\ -}\ - - +#define MAT_TRANSFORM_PLANE_4X4(pout, m, plane) \ + { \ + pout[0] = m[0][0] * plane[0] + m[0][1] * plane[1] + m[0][2] * plane[2]; \ + pout[1] = m[1][0] * plane[0] + m[1][1] * plane[1] + m[1][2] * plane[2]; \ + pout[2] = m[2][0] * plane[0] + m[2][1] * plane[1] + m[2][2] * plane[2]; \ + pout[3] = m[0][3] * pout[0] + m[1][3] * pout[1] + m[2][3] * pout[2] + plane[3]; \ + } /** inverse transpose of matrix times vector * @@ -1000,22 +938,22 @@ Last column is added as the position * It will leave normals the wrong length !!! * See macro below for use on normals. */ -#define INV_TRANSP_MAT_DOT_VEC_2X2(p,m,v) \ -{ \ - GREAL det; \ - \ - det = m[0][0]*m[1][1] - m[0][1]*m[1][0]; \ - p[0] = m[1][1]*v[0] - m[1][0]*v[1]; \ - p[1] = - m[0][1]*v[0] + m[0][0]*v[1]; \ - \ - /* if matrix not singular, and not orthonormal, then renormalize */ \ - if ((det!=1.0f) && (det != 0.0f)) { \ - det = 1.0f / det; \ - p[0] *= det; \ - p[1] *= det; \ - } \ -}\ - +#define INV_TRANSP_MAT_DOT_VEC_2X2(p, m, v) \ + { \ + GREAL det; \ + \ + det = m[0][0] * m[1][1] - m[0][1] * m[1][0]; \ + p[0] = m[1][1] * v[0] - m[1][0] * v[1]; \ + p[1] = -m[0][1] * v[0] + m[0][0] * v[1]; \ + \ + /* if matrix not singular, and not orthonormal, then renormalize */ \ + if ((det != 1.0f) && (det != 0.0f)) \ + { \ + det = 1.0f / det; \ + p[0] *= det; \ + p[1] *= det; \ + } \ + } /** transform normal vector by inverse transpose of matrix * and then renormalize the vector @@ -1024,550 +962,527 @@ Last column is added as the position * and multiplies vector v into it, to yeild vector p * Vector p is then normalized. */ -#define NORM_XFORM_2X2(p,m,v) \ -{ \ - GREAL len; \ - \ - /* do nothing if off-diagonals are zero and diagonals are \ - * equal */ \ - if ((m[0][1] != 0.0) || (m[1][0] != 0.0) || (m[0][0] != m[1][1])) { \ - p[0] = m[1][1]*v[0] - m[1][0]*v[1]; \ - p[1] = - m[0][1]*v[0] + m[0][0]*v[1]; \ - \ - len = p[0]*p[0] + p[1]*p[1]; \ - GIM_INV_SQRT(len,len); \ - p[0] *= len; \ - p[1] *= len; \ - } else { \ - VEC_COPY_2 (p, v); \ - } \ -}\ - +#define NORM_XFORM_2X2(p, m, v) \ + { \ + GREAL len; \ + \ + /* do nothing if off-diagonals are zero and diagonals are \ + * equal */ \ + if ((m[0][1] != 0.0) || (m[1][0] != 0.0) || (m[0][0] != m[1][1])) \ + { \ + p[0] = m[1][1] * v[0] - m[1][0] * v[1]; \ + p[1] = -m[0][1] * v[0] + m[0][0] * v[1]; \ + \ + len = p[0] * p[0] + p[1] * p[1]; \ + GIM_INV_SQRT(len, len); \ + p[0] *= len; \ + p[1] *= len; \ + } \ + else \ + { \ + VEC_COPY_2(p, v); \ + } \ + } /** outer product of vector times vector transpose * * The outer product of vector v and vector transpose t yeilds * dyadic matrix m. */ -#define OUTER_PRODUCT_2X2(m,v,t) \ -{ \ - m[0][0] = v[0] * t[0]; \ - m[0][1] = v[0] * t[1]; \ - \ - m[1][0] = v[1] * t[0]; \ - m[1][1] = v[1] * t[1]; \ -}\ - +#define OUTER_PRODUCT_2X2(m, v, t) \ + { \ + m[0][0] = v[0] * t[0]; \ + m[0][1] = v[0] * t[1]; \ + \ + m[1][0] = v[1] * t[0]; \ + m[1][1] = v[1] * t[1]; \ + } /** outer product of vector times vector transpose * * The outer product of vector v and vector transpose t yeilds * dyadic matrix m. */ -#define OUTER_PRODUCT_3X3(m,v,t) \ -{ \ - m[0][0] = v[0] * t[0]; \ - m[0][1] = v[0] * t[1]; \ - m[0][2] = v[0] * t[2]; \ - \ - m[1][0] = v[1] * t[0]; \ - m[1][1] = v[1] * t[1]; \ - m[1][2] = v[1] * t[2]; \ - \ - m[2][0] = v[2] * t[0]; \ - m[2][1] = v[2] * t[1]; \ - m[2][2] = v[2] * t[2]; \ -}\ - +#define OUTER_PRODUCT_3X3(m, v, t) \ + { \ + m[0][0] = v[0] * t[0]; \ + m[0][1] = v[0] * t[1]; \ + m[0][2] = v[0] * t[2]; \ + \ + m[1][0] = v[1] * t[0]; \ + m[1][1] = v[1] * t[1]; \ + m[1][2] = v[1] * t[2]; \ + \ + m[2][0] = v[2] * t[0]; \ + m[2][1] = v[2] * t[1]; \ + m[2][2] = v[2] * t[2]; \ + } /** outer product of vector times vector transpose * * The outer product of vector v and vector transpose t yeilds * dyadic matrix m. */ -#define OUTER_PRODUCT_4X4(m,v,t) \ -{ \ - m[0][0] = v[0] * t[0]; \ - m[0][1] = v[0] * t[1]; \ - m[0][2] = v[0] * t[2]; \ - m[0][3] = v[0] * t[3]; \ - \ - m[1][0] = v[1] * t[0]; \ - m[1][1] = v[1] * t[1]; \ - m[1][2] = v[1] * t[2]; \ - m[1][3] = v[1] * t[3]; \ - \ - m[2][0] = v[2] * t[0]; \ - m[2][1] = v[2] * t[1]; \ - m[2][2] = v[2] * t[2]; \ - m[2][3] = v[2] * t[3]; \ - \ - m[3][0] = v[3] * t[0]; \ - m[3][1] = v[3] * t[1]; \ - m[3][2] = v[3] * t[2]; \ - m[3][3] = v[3] * t[3]; \ -}\ - +#define OUTER_PRODUCT_4X4(m, v, t) \ + { \ + m[0][0] = v[0] * t[0]; \ + m[0][1] = v[0] * t[1]; \ + m[0][2] = v[0] * t[2]; \ + m[0][3] = v[0] * t[3]; \ + \ + m[1][0] = v[1] * t[0]; \ + m[1][1] = v[1] * t[1]; \ + m[1][2] = v[1] * t[2]; \ + m[1][3] = v[1] * t[3]; \ + \ + m[2][0] = v[2] * t[0]; \ + m[2][1] = v[2] * t[1]; \ + m[2][2] = v[2] * t[2]; \ + m[2][3] = v[2] * t[3]; \ + \ + m[3][0] = v[3] * t[0]; \ + m[3][1] = v[3] * t[1]; \ + m[3][2] = v[3] * t[2]; \ + m[3][3] = v[3] * t[3]; \ + } /** outer product of vector times vector transpose * * The outer product of vector v and vector transpose t yeilds * dyadic matrix m. */ -#define ACCUM_OUTER_PRODUCT_2X2(m,v,t) \ -{ \ - m[0][0] += v[0] * t[0]; \ - m[0][1] += v[0] * t[1]; \ - \ - m[1][0] += v[1] * t[0]; \ - m[1][1] += v[1] * t[1]; \ -}\ - +#define ACCUM_OUTER_PRODUCT_2X2(m, v, t) \ + { \ + m[0][0] += v[0] * t[0]; \ + m[0][1] += v[0] * t[1]; \ + \ + m[1][0] += v[1] * t[0]; \ + m[1][1] += v[1] * t[1]; \ + } /** outer product of vector times vector transpose * * The outer product of vector v and vector transpose t yeilds * dyadic matrix m. */ -#define ACCUM_OUTER_PRODUCT_3X3(m,v,t) \ -{ \ - m[0][0] += v[0] * t[0]; \ - m[0][1] += v[0] * t[1]; \ - m[0][2] += v[0] * t[2]; \ - \ - m[1][0] += v[1] * t[0]; \ - m[1][1] += v[1] * t[1]; \ - m[1][2] += v[1] * t[2]; \ - \ - m[2][0] += v[2] * t[0]; \ - m[2][1] += v[2] * t[1]; \ - m[2][2] += v[2] * t[2]; \ -}\ - +#define ACCUM_OUTER_PRODUCT_3X3(m, v, t) \ + { \ + m[0][0] += v[0] * t[0]; \ + m[0][1] += v[0] * t[1]; \ + m[0][2] += v[0] * t[2]; \ + \ + m[1][0] += v[1] * t[0]; \ + m[1][1] += v[1] * t[1]; \ + m[1][2] += v[1] * t[2]; \ + \ + m[2][0] += v[2] * t[0]; \ + m[2][1] += v[2] * t[1]; \ + m[2][2] += v[2] * t[2]; \ + } /** outer product of vector times vector transpose * * The outer product of vector v and vector transpose t yeilds * dyadic matrix m. */ -#define ACCUM_OUTER_PRODUCT_4X4(m,v,t) \ -{ \ - m[0][0] += v[0] * t[0]; \ - m[0][1] += v[0] * t[1]; \ - m[0][2] += v[0] * t[2]; \ - m[0][3] += v[0] * t[3]; \ - \ - m[1][0] += v[1] * t[0]; \ - m[1][1] += v[1] * t[1]; \ - m[1][2] += v[1] * t[2]; \ - m[1][3] += v[1] * t[3]; \ - \ - m[2][0] += v[2] * t[0]; \ - m[2][1] += v[2] * t[1]; \ - m[2][2] += v[2] * t[2]; \ - m[2][3] += v[2] * t[3]; \ - \ - m[3][0] += v[3] * t[0]; \ - m[3][1] += v[3] * t[1]; \ - m[3][2] += v[3] * t[2]; \ - m[3][3] += v[3] * t[3]; \ -}\ - +#define ACCUM_OUTER_PRODUCT_4X4(m, v, t) \ + { \ + m[0][0] += v[0] * t[0]; \ + m[0][1] += v[0] * t[1]; \ + m[0][2] += v[0] * t[2]; \ + m[0][3] += v[0] * t[3]; \ + \ + m[1][0] += v[1] * t[0]; \ + m[1][1] += v[1] * t[1]; \ + m[1][2] += v[1] * t[2]; \ + m[1][3] += v[1] * t[3]; \ + \ + m[2][0] += v[2] * t[0]; \ + m[2][1] += v[2] * t[1]; \ + m[2][2] += v[2] * t[2]; \ + m[2][3] += v[2] * t[3]; \ + \ + m[3][0] += v[3] * t[0]; \ + m[3][1] += v[3] * t[1]; \ + m[3][2] += v[3] * t[2]; \ + m[3][3] += v[3] * t[3]; \ + } /** determinant of matrix * * Computes determinant of matrix m, returning d */ -#define DETERMINANT_2X2(d,m) \ -{ \ - d = m[0][0] * m[1][1] - m[0][1] * m[1][0]; \ -}\ - +#define DETERMINANT_2X2(d, m) \ + { \ + d = m[0][0] * m[1][1] - m[0][1] * m[1][0]; \ + } /** determinant of matrix * * Computes determinant of matrix m, returning d */ -#define DETERMINANT_3X3(d,m) \ -{ \ - d = m[0][0] * (m[1][1]*m[2][2] - m[1][2] * m[2][1]); \ - d -= m[0][1] * (m[1][0]*m[2][2] - m[1][2] * m[2][0]); \ - d += m[0][2] * (m[1][0]*m[2][1] - m[1][1] * m[2][0]); \ -}\ - +#define DETERMINANT_3X3(d, m) \ + { \ + d = m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]); \ + d -= m[0][1] * (m[1][0] * m[2][2] - m[1][2] * m[2][0]); \ + d += m[0][2] * (m[1][0] * m[2][1] - m[1][1] * m[2][0]); \ + } /** i,j,th cofactor of a 4x4 matrix * */ -#define COFACTOR_4X4_IJ(fac,m,i,j) \ -{ \ - GUINT __ii[4], __jj[4], __k; \ - \ - for (__k=0; __k */ -#define INV_MAT_DOT_VEC_3X3(p,m,v) \ -{ \ - p[0] = MAT_DOT_COL(m,v,0); \ - p[1] = MAT_DOT_COL(m,v,1); \ - p[2] = MAT_DOT_COL(m,v,2); \ -}\ +#define INV_MAT_DOT_VEC_3X3(p, m, v) \ + { \ + p[0] = MAT_DOT_COL(m, v, 0); \ + p[1] = MAT_DOT_COL(m, v, 1); \ + p[2] = MAT_DOT_COL(m, v, 2); \ + } - - -#endif // GIM_VECTOR_H_INCLUDED +#endif // GIM_VECTOR_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/gim_math.h b/src/BulletCollision/Gimpact/gim_math.h index 939079e10..3c4f821a7 100644 --- a/src/BulletCollision/Gimpact/gim_math.h +++ b/src/BulletCollision/Gimpact/gim_math.h @@ -34,8 +34,6 @@ email: projectileman@yahoo.com #include "LinearMath/btScalar.h" - - #define GREAL btScalar #define GREAL2 double #define GINT int @@ -45,8 +43,6 @@ email: projectileman@yahoo.com #define GINT64 long long #define GUINT64 unsigned long long - - #define G_PI 3.14159265358979f #define G_HALF_PI 1.5707963f //267948966 @@ -54,16 +50,14 @@ email: projectileman@yahoo.com //71795864 #define G_ROOT3 1.73205f #define G_ROOT2 1.41421f -#define G_UINT_INFINITY 0xffffffff //!< A very very high value +#define G_UINT_INFINITY 0xffffffff //!< A very very high value #define G_REAL_INFINITY FLT_MAX -#define G_SIGN_BITMASK 0x80000000 +#define G_SIGN_BITMASK 0x80000000 #define G_EPSILON SIMD_EPSILON - - enum GIM_SCALAR_TYPES { - G_STYPE_REAL =0, + G_STYPE_REAL = 0, G_STYPE_REAL2, G_STYPE_SHORT, G_STYPE_USHORT, @@ -73,85 +67,82 @@ enum GIM_SCALAR_TYPES G_STYPE_UINT64 }; - - -#define G_DEGTORAD(X) ((X)*3.1415926f/180.0f) -#define G_RADTODEG(X) ((X)*180.0f/3.1415926f) +#define G_DEGTORAD(X) ((X)*3.1415926f / 180.0f) +#define G_RADTODEG(X) ((X)*180.0f / 3.1415926f) //! Integer representation of a floating-point value. -#define GIM_IR(x) ((GUINT&)(x)) +#define GIM_IR(x) ((GUINT&)(x)) //! Signed integer representation of a floating-point value. -#define GIM_SIR(x) ((GINT&)(x)) +#define GIM_SIR(x) ((GINT&)(x)) //! Absolute integer representation of a floating-point value -#define GIM_AIR(x) (GIM_IR(x)&0x7fffffff) +#define GIM_AIR(x) (GIM_IR(x) & 0x7fffffff) //! Floating-point representation of an integer value. -#define GIM_FR(x) ((GREAL&)(x)) +#define GIM_FR(x) ((GREAL&)(x)) -#define GIM_MAX(a,b) (ab?b:a) +#define GIM_MAX(a, b) (a < b ? b : a) +#define GIM_MIN(a, b) (a > b ? b : a) -#define GIM_MAX3(a,b,c) GIM_MAX(a,GIM_MAX(b,c)) -#define GIM_MIN3(a,b,c) GIM_MIN(a,GIM_MIN(b,c)) +#define GIM_MAX3(a, b, c) GIM_MAX(a, GIM_MAX(b, c)) +#define GIM_MIN3(a, b, c) GIM_MIN(a, GIM_MIN(b, c)) -#define GIM_IS_ZERO(value) (value < G_EPSILON && value > -G_EPSILON) +#define GIM_IS_ZERO(value) (value < G_EPSILON && value > -G_EPSILON) #define GIM_IS_NEGATIVE(value) (value <= -G_EPSILON) #define GIM_IS_POSISITVE(value) (value >= G_EPSILON) -#define GIM_NEAR_EQUAL(v1,v2) GIM_IS_ZERO((v1-v2)) +#define GIM_NEAR_EQUAL(v1, v2) GIM_IS_ZERO((v1 - v2)) ///returns a clamped number -#define GIM_CLAMP(number,minval,maxval) (numbermaxval?maxval:number)) +#define GIM_CLAMP(number, minval, maxval) (number < minval ? minval : (number > maxval ? maxval : number)) -#define GIM_GREATER(x, y) btFabs(x) > (y) +#define GIM_GREATER(x, y) btFabs(x) > (y) ///Swap numbers -#define GIM_SWAP_NUMBERS(a,b){ \ - a = a+b; \ - b = a-b; \ - a = a-b; \ -}\ +#define GIM_SWAP_NUMBERS(a, b) \ + { \ + a = a + b; \ + b = a - b; \ + a = a - b; \ + } -#define GIM_INV_SQRT(va,isva)\ -{\ - if(va<=0.0000001f)\ - {\ - isva = G_REAL_INFINITY;\ - }\ - else\ - {\ - GREAL _x = va * 0.5f;\ - GUINT _y = 0x5f3759df - ( GIM_IR(va) >> 1);\ - isva = GIM_FR(_y);\ - isva = isva * ( 1.5f - ( _x * isva * isva ) );\ - }\ -}\ +#define GIM_INV_SQRT(va, isva) \ + { \ + if (va <= 0.0000001f) \ + { \ + isva = G_REAL_INFINITY; \ + } \ + else \ + { \ + GREAL _x = va * 0.5f; \ + GUINT _y = 0x5f3759df - (GIM_IR(va) >> 1); \ + isva = GIM_FR(_y); \ + isva = isva * (1.5f - (_x * isva * isva)); \ + } \ + } -#define GIM_SQRT(va,sva)\ -{\ - GIM_INV_SQRT(va,sva);\ - sva = 1.0f/sva;\ -}\ +#define GIM_SQRT(va, sva) \ + { \ + GIM_INV_SQRT(va, sva); \ + sva = 1.0f / sva; \ + } //! Computes 1.0f / sqrtf(x). Comes from Quake3. See http://www.magic-software.com/3DGEDInvSqrt.html inline GREAL gim_inv_sqrt(GREAL f) { - GREAL r; - GIM_INV_SQRT(f,r); - return r; + GREAL r; + GIM_INV_SQRT(f, r); + return r; } inline GREAL gim_sqrt(GREAL f) { - GREAL r; - GIM_SQRT(f,r); - return r; + GREAL r; + GIM_SQRT(f, r); + return r; } - - -#endif // GIM_MATH_H_INCLUDED +#endif // GIM_MATH_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/gim_memory.cpp b/src/BulletCollision/Gimpact/gim_memory.cpp index 1636eb786..9e29ab91d 100644 --- a/src/BulletCollision/Gimpact/gim_memory.cpp +++ b/src/BulletCollision/Gimpact/gim_memory.cpp @@ -27,7 +27,6 @@ email: projectileman@yahoo.com ----------------------------------------------------------------------------- */ - #include "gim_memory.h" #include "stdlib.h" @@ -40,52 +39,49 @@ static gim_alloca_function *g_allocafn = 0; static gim_realloc_function *g_reallocfn = 0; static gim_free_function *g_freefn = 0; -void gim_set_alloc_handler (gim_alloc_function *fn) +void gim_set_alloc_handler(gim_alloc_function *fn) { - g_allocfn = fn; + g_allocfn = fn; } -void gim_set_alloca_handler (gim_alloca_function *fn) +void gim_set_alloca_handler(gim_alloca_function *fn) { - g_allocafn = fn; + g_allocafn = fn; } -void gim_set_realloc_handler (gim_realloc_function *fn) +void gim_set_realloc_handler(gim_realloc_function *fn) { - g_reallocfn = fn; + g_reallocfn = fn; } -void gim_set_free_handler (gim_free_function *fn) +void gim_set_free_handler(gim_free_function *fn) { - g_freefn = fn; + g_freefn = fn; } gim_alloc_function *gim_get_alloc_handler() { - return g_allocfn; + return g_allocfn; } gim_alloca_function *gim_get_alloca_handler() { - return g_allocafn; + return g_allocafn; } - -gim_realloc_function *gim_get_realloc_handler () +gim_realloc_function *gim_get_realloc_handler() { - return g_reallocfn; + return g_reallocfn; } - -gim_free_function *gim_get_free_handler () +gim_free_function *gim_get_free_handler() { - return g_freefn; + return g_freefn; } - -void * gim_alloc(size_t size) +void *gim_alloc(size_t size) { - void * ptr; + void *ptr; if (g_allocfn) { ptr = g_allocfn(size); @@ -93,27 +89,29 @@ void * gim_alloc(size_t size) else { #ifdef GIM_SIMD_MEMORY - ptr = btAlignedAlloc(size,16); + ptr = btAlignedAlloc(size, 16); #else ptr = malloc(size); #endif } - return ptr; + return ptr; } -void * gim_alloca(size_t size) +void *gim_alloca(size_t size) { - if (g_allocafn) return g_allocafn(size); else return gim_alloc(size); + if (g_allocafn) + return g_allocafn(size); + else + return gim_alloc(size); } - -void * gim_realloc(void *ptr, size_t oldsize, size_t newsize) +void *gim_realloc(void *ptr, size_t oldsize, size_t newsize) { - void * newptr = gim_alloc(newsize); - size_t copysize = oldsize #ifdef PREFETCH -#include // for prefetch -#define pfval 64 -#define pfval2 128 +#include // for prefetch +#define pfval 64 +#define pfval2 128 //! Prefetch 64 -#define pf(_x,_i) _mm_prefetch((void *)(_x + _i + pfval), 0) +#define pf(_x, _i) _mm_prefetch((void *)(_x + _i + pfval), 0) //! Prefetch 128 -#define pf2(_x,_i) _mm_prefetch((void *)(_x + _i + pfval2), 0) +#define pf2(_x, _i) _mm_prefetch((void *)(_x + _i + pfval2), 0) #else //! Prefetch 64 -#define pf(_x,_i) +#define pf(_x, _i) //! Prefetch 128 -#define pf2(_x,_i) +#define pf2(_x, _i) #endif - ///Functions for manip packed arrays of numbers -#define GIM_COPY_ARRAYS(dest_array,source_array,element_count)\ -{\ - for (GUINT _i_=0;_i_0) - { - *(c_dst_ptr++) = *(c_src_ptr++); - copysize--; - } - return; + char *c_src_ptr = (char *)src; + char *c_dst_ptr = (char *)dst; + while (copysize > 0) + { + *(c_dst_ptr++) = *(c_src_ptr++); + copysize--; + } + return; #else - memcpy(dst,src,copysize); + memcpy(dst, src, copysize); #endif } - - -template -inline void gim_swap_elements(T* _array,size_t _i,size_t _j) +template +inline void gim_swap_elements(T *_array, size_t _i, size_t _j) { T _e_tmp_ = _array[_i]; _array[_i] = _array[_j]; _array[_j] = _e_tmp_; } - -template -inline void gim_swap_elements_memcpy(T* _array,size_t _i,size_t _j) +template +inline void gim_swap_elements_memcpy(T *_array, size_t _i, size_t _j) { char _e_tmp_[sizeof(T)]; - gim_simd_memcpy(_e_tmp_,&_array[_i],sizeof(T)); - gim_simd_memcpy(&_array[_i],&_array[_j],sizeof(T)); - gim_simd_memcpy(&_array[_j],_e_tmp_,sizeof(T)); + gim_simd_memcpy(_e_tmp_, &_array[_i], sizeof(T)); + gim_simd_memcpy(&_array[_i], &_array[_j], sizeof(T)); + gim_simd_memcpy(&_array[_j], _e_tmp_, sizeof(T)); } template -inline void gim_swap_elements_ptr(char * _array,size_t _i,size_t _j) +inline void gim_swap_elements_ptr(char *_array, size_t _i, size_t _j) { char _e_tmp_[SIZE]; - _i*=SIZE; - _j*=SIZE; - gim_simd_memcpy(_e_tmp_,_array+_i,SIZE); - gim_simd_memcpy(_array+_i,_array+_j,SIZE); - gim_simd_memcpy(_array+_j,_e_tmp_,SIZE); + _i *= SIZE; + _j *= SIZE; + gim_simd_memcpy(_e_tmp_, _array + _i, SIZE); + gim_simd_memcpy(_array + _i, _array + _j, SIZE); + gim_simd_memcpy(_array + _j, _e_tmp_, SIZE); } -#endif // GIM_MEMORY_H_INCLUDED +#endif // GIM_MEMORY_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/gim_radixsort.h b/src/BulletCollision/Gimpact/gim_radixsort.h index c246ef125..ff7907adc 100644 --- a/src/BulletCollision/Gimpact/gim_radixsort.h +++ b/src/BulletCollision/Gimpact/gim_radixsort.h @@ -40,24 +40,22 @@ email: projectileman@yahoo.com //! Prototype for comparators class less_comparator { - public: - - template - inline int operator() ( const T& a, const Z& b ) +public: + template + inline int operator()(const T& a, const Z& b) { - return ( ab?1:0)); + return (a < b ? -1 : (a > b ? 1 : 0)); } }; //! Prototype for comparators class integer_comparator { - public: - - template - inline int operator() ( const T& a, const T& b ) +public: + template + inline int operator()(const T& a, const T& b) { - return (int)(a-b); + return (int)(a - b); } }; @@ -65,20 +63,19 @@ class integer_comparator class uint_key_func { public: - template - inline GUINT operator()( const T& a) + template + inline GUINT operator()(const T& a) { return (GUINT)a; } }; - //!Prototype for copying elements class copy_elements_func { public: - template - inline void operator()(T& a,T& b) + template + inline void operator()(T& a, T& b) { a = b; } @@ -88,34 +85,33 @@ public: class memcopy_elements_func { public: - template - inline void operator()(T& a,T& b) + template + inline void operator()(T& a, T& b) { - gim_simd_memcpy(&a,&b,sizeof(T)); + gim_simd_memcpy(&a, &b, sizeof(T)); } }; - //! @{ struct GIM_RSORT_TOKEN { - GUINT m_key; - GUINT m_value; - GIM_RSORT_TOKEN() - { - } - GIM_RSORT_TOKEN(const GIM_RSORT_TOKEN& rtoken) - { - m_key = rtoken.m_key; - m_value = rtoken.m_value; - } + GUINT m_key; + GUINT m_value; + GIM_RSORT_TOKEN() + { + } + GIM_RSORT_TOKEN(const GIM_RSORT_TOKEN& rtoken) + { + m_key = rtoken.m_key; + m_value = rtoken.m_value; + } - inline bool operator <(const GIM_RSORT_TOKEN& other) const + inline bool operator<(const GIM_RSORT_TOKEN& other) const { return (m_key < other.m_key); } - inline bool operator >(const GIM_RSORT_TOKEN& other) const + inline bool operator>(const GIM_RSORT_TOKEN& other) const { return (m_key > other.m_key); } @@ -124,33 +120,28 @@ struct GIM_RSORT_TOKEN //! Prototype for comparators class GIM_RSORT_TOKEN_COMPARATOR { - public: - - inline int operator()( const GIM_RSORT_TOKEN& a, const GIM_RSORT_TOKEN& b ) +public: + inline int operator()(const GIM_RSORT_TOKEN& a, const GIM_RSORT_TOKEN& b) { return (int)((a.m_key) - (b.m_key)); } }; - - #define kHist 2048 // ---- utils for accessing 11-bit quantities -#define D11_0(x) (x & 0x7FF) -#define D11_1(x) (x >> 11 & 0x7FF) -#define D11_2(x) (x >> 22 ) - - +#define D11_0(x) (x & 0x7FF) +#define D11_1(x) (x >> 11 & 0x7FF) +#define D11_2(x) (x >> 22) ///Radix sort for unsigned integer keys inline void gim_radix_sort_rtokens( - GIM_RSORT_TOKEN * array, - GIM_RSORT_TOKEN * sorted, GUINT element_count) + GIM_RSORT_TOKEN* array, + GIM_RSORT_TOKEN* sorted, GUINT element_count) { GUINT i; GUINT b0[kHist * 3]; - GUINT *b1 = b0 + kHist; - GUINT *b2 = b1 + kHist; + GUINT* b1 = b0 + kHist; + GUINT* b2 = b1 + kHist; for (i = 0; i < kHist * 3; ++i) { b0[i] = 0; @@ -159,10 +150,10 @@ inline void gim_radix_sort_rtokens( GUINT pos; for (i = 0; i < element_count; ++i) { - fi = array[i].m_key; - b0[D11_0(fi)] ++; - b1[D11_1(fi)] ++; - b2[D11_2(fi)] ++; + fi = array[i].m_key; + b0[D11_0(fi)]++; + b1[D11_1(fi)]++; + b2[D11_2(fi)]++; } { GUINT sum0 = 0, sum1 = 0, sum2 = 0; @@ -182,7 +173,7 @@ inline void gim_radix_sort_rtokens( } for (i = 0; i < element_count; ++i) { - fi = array[i].m_key; + fi = array[i].m_key; pos = D11_0(fi); pos = ++b0[pos]; sorted[pos].m_key = array[i].m_key; @@ -190,7 +181,7 @@ inline void gim_radix_sort_rtokens( } for (i = 0; i < element_count; ++i) { - fi = sorted[i].m_key; + fi = sorted[i].m_key; pos = D11_1(fi); pos = ++b1[pos]; array[pos].m_key = sorted[i].m_key; @@ -198,7 +189,7 @@ inline void gim_radix_sort_rtokens( } for (i = 0; i < element_count; ++i) { - fi = array[i].m_key; + fi = array[i].m_key; pos = D11_2(fi); pos = ++b2[pos]; sorted[pos].m_key = array[i].m_key; @@ -206,9 +197,6 @@ inline void gim_radix_sort_rtokens( } } - - - /// Get the sorted tokens from an array. For generic use. Tokens are IRR_RSORT_TOKEN /*! *\param array Array of elements to sort @@ -216,21 +204,21 @@ inline void gim_radix_sort_rtokens( *\param element_count element count *\param uintkey_macro Functor which retrieves the integer representation of an array element */ -template +template void gim_radix_sort_array_tokens( - T* array , - GIM_RSORT_TOKEN * sorted_tokens, - GUINT element_count,GETKEY_CLASS uintkey_macro) + T* array, + GIM_RSORT_TOKEN* sorted_tokens, + GUINT element_count, GETKEY_CLASS uintkey_macro) { - GIM_RSORT_TOKEN * _unsorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*element_count); - for (GUINT _i=0;_i +template void gim_radix_sort( - T * array, GUINT element_count, + T* array, GUINT element_count, GETKEY_CLASS get_uintkey_macro, COPY_CLASS copy_elements_macro) { - GIM_RSORT_TOKEN * _sorted = (GIM_RSORT_TOKEN *) gim_alloc(sizeof(GIM_RSORT_TOKEN)*element_count); - gim_radix_sort_array_tokens(array,_sorted,element_count,get_uintkey_macro); - T * _original_array = (T *) gim_alloc(sizeof(T)*element_count); - gim_simd_memcpy(_original_array,array,sizeof(T)*element_count); - for (GUINT _i=0;_i -bool gim_binary_search_ex( - const T* _array, GUINT _start_i, - GUINT _end_i,GUINT & _result_index, - const KEYCLASS & _search_key, - COMP_CLASS _comp_macro) +template +bool gim_binary_search_ex( + const T* _array, GUINT _start_i, + GUINT _end_i, GUINT& _result_index, + const KEYCLASS& _search_key, + COMP_CLASS _comp_macro) { GUINT _k; int _comp_result; GUINT _i = _start_i; - GUINT _j = _end_i+1; + GUINT _j = _end_i + 1; while (_i < _j) { - _k = (_j+_i-1)/2; + _k = (_j + _i - 1) / 2; _comp_result = _comp_macro(_array[_k], _search_key); if (_comp_result == 0) { @@ -291,7 +279,7 @@ bool gim_binary_search_ex( } else if (_comp_result < 0) { - _i = _k+1; + _i = _k + 1; } else { @@ -302,8 +290,6 @@ bool gim_binary_search_ex( return false; } - - //! Failsafe Iterative binary search,Template version /*! If the element is not found, it returns the nearest upper element position, may be the further position after the last element. @@ -314,26 +300,26 @@ If the element is not found, it returns the nearest upper element position, may \param _result_index the index of the found element, or if not found then it will get the index of the closest bigger value \return true if found, else false */ -template +template bool gim_binary_search( - const T*_array,GUINT _start_i, - GUINT _end_i,const T & _search_key, - GUINT & _result_index) + const T* _array, GUINT _start_i, + GUINT _end_i, const T& _search_key, + GUINT& _result_index) { GUINT _i = _start_i; - GUINT _j = _end_i+1; + GUINT _j = _end_i + 1; GUINT _k; - while(_i < _j) + while (_i < _j) { - _k = (_j+_i-1)/2; - if(_array[_k]==_search_key) + _k = (_j + _i - 1) / 2; + if (_array[_k] == _search_key) { _result_index = _k; return true; } - else if (_array[_k]<_search_key) + else if (_array[_k] < _search_key) { - _i = _k+1; + _i = _k + 1; } else { @@ -344,27 +330,25 @@ bool gim_binary_search( return false; } - - ///heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/ template -void gim_down_heap(T *pArr, GUINT k, GUINT n,COMP_CLASS CompareFunc) +void gim_down_heap(T* pArr, GUINT k, GUINT n, COMP_CLASS CompareFunc) { /* PRE: a[k+1..N] is a heap */ /* POST: a[k..N] is a heap */ T temp = pArr[k - 1]; /* k has child(s) */ - while (k <= n/2) + while (k <= n / 2) { - int child = 2*k; + int child = 2 * k; - if ((child < (int)n) && CompareFunc(pArr[child - 1] , pArr[child])<0) + if ((child < (int)n) && CompareFunc(pArr[child - 1], pArr[child]) < 0) { child++; } /* pick larger child */ - if (CompareFunc(temp , pArr[child - 1])<0) + if (CompareFunc(temp, pArr[child - 1]) < 0) { /* move child up */ pArr[k - 1] = pArr[child - 1]; @@ -378,29 +362,25 @@ void gim_down_heap(T *pArr, GUINT k, GUINT n,COMP_CLASS CompareFunc) pArr[k - 1] = temp; } /*downHeap*/ - template -void gim_heap_sort(T *pArr, GUINT element_count, COMP_CLASS CompareFunc) +void gim_heap_sort(T* pArr, GUINT element_count, COMP_CLASS CompareFunc) { /* sort a[0..N-1], N.B. 0 to N-1 */ GUINT k; GUINT n = element_count; - for (k = n/2; k > 0; k--) + for (k = n / 2; k > 0; k--) { gim_down_heap(pArr, k, n, CompareFunc); } /* a[1..N] is now a heap */ - while ( n>=2 ) + while (n >= 2) { - gim_swap_elements(pArr,0,n-1); /* largest of a[0..n-1] */ + gim_swap_elements(pArr, 0, n - 1); /* largest of a[0..n-1] */ --n; /* restore a[1..i-1] heap */ gim_down_heap(pArr, 1, n, CompareFunc); } } - - - -#endif // GIM_RADIXSORT_H_INCLUDED +#endif // GIM_RADIXSORT_H_INCLUDED diff --git a/src/BulletCollision/Gimpact/gim_tri_collision.cpp b/src/BulletCollision/Gimpact/gim_tri_collision.cpp index f9727e1d5..8d83e95da 100644 --- a/src/BulletCollision/Gimpact/gim_tri_collision.cpp +++ b/src/BulletCollision/Gimpact/gim_tri_collision.cpp @@ -33,15 +33,13 @@ email: projectileman@yahoo.com #include "gim_tri_collision.h" - #define TRI_LOCAL_EPSILON 0.000001f #define MIN_EDGE_EDGE_DIS 0.00001f - class GIM_TRIANGLE_CALCULATION_CACHE { public: - GREAL margin; + GREAL margin; btVector3 tu_vertices[3]; btVector3 tv_vertices[3]; btVector4 tu_plane; @@ -55,46 +53,47 @@ public: GREAL du0du2; GREAL dv[4]; GREAL dv0dv1; - GREAL dv0dv2; + GREAL dv0dv2; btVector3 temp_points[MAX_TRI_CLIPPING]; btVector3 temp_points1[MAX_TRI_CLIPPING]; btVector3 contact_points[MAX_TRI_CLIPPING]; - - //! if returns false, the faces are paralele SIMD_FORCE_INLINE bool compute_intervals( - const GREAL &D0, - const GREAL &D1, - const GREAL &D2, - const GREAL &D0D1, - const GREAL &D0D2, - GREAL & scale_edge0, - GREAL & scale_edge1, - GUINT &edge_index0, - GUINT &edge_index1) + const GREAL &D0, + const GREAL &D1, + const GREAL &D2, + const GREAL &D0D1, + const GREAL &D0D2, + GREAL &scale_edge0, + GREAL &scale_edge1, + GUINT &edge_index0, + GUINT &edge_index1) { - if(D0D1>0.0f) + if (D0D1 > 0.0f) { /* here we know that D0D2<=0.0 */ /* that is D0, D1 are on the same side, D2 on the other or on the plane */ - scale_edge0 = -D2/(D0-D2); - scale_edge1 = -D1/(D2-D1); - edge_index0 = 2;edge_index1 = 1; + scale_edge0 = -D2 / (D0 - D2); + scale_edge1 = -D1 / (D2 - D1); + edge_index0 = 2; + edge_index1 = 1; } - else if(D0D2>0.0f) + else if (D0D2 > 0.0f) { /* here we know that d0d1<=0.0 */ - scale_edge0 = -D0/(D1-D0); - scale_edge1 = -D1/(D2-D1); - edge_index0 = 0;edge_index1 = 1; + scale_edge0 = -D0 / (D1 - D0); + scale_edge1 = -D1 / (D2 - D1); + edge_index0 = 0; + edge_index1 = 1; } - else if(D1*D2>0.0f || D0!=0.0f) + else if (D1 * D2 > 0.0f || D0 != 0.0f) { /* here we know that d0d1<=0.0 or that D0!=0.0 */ - scale_edge0 = -D0/(D1-D0); - scale_edge1 = -D2/(D0-D2); - edge_index0 = 0 ;edge_index1 = 2; + scale_edge0 = -D0 / (D1 - D0); + scale_edge1 = -D2 / (D0 - D2); + edge_index0 = 0; + edge_index1 = 2; } else { @@ -103,46 +102,44 @@ public: return true; } - //! clip triangle /*! */ SIMD_FORCE_INLINE GUINT clip_triangle( - const btVector4 & tri_plane, - const btVector3 * tripoints, - const btVector3 * srcpoints, - btVector3 * clip_points) + const btVector4 &tri_plane, + const btVector3 *tripoints, + const btVector3 *srcpoints, + btVector3 *clip_points) { // edge 0 btVector4 edgeplane; - EDGE_PLANE(tripoints[0],tripoints[1],tri_plane,edgeplane); + EDGE_PLANE(tripoints[0], tripoints[1], tri_plane, edgeplane); GUINT clipped_count = PLANE_CLIP_TRIANGLE3D( - edgeplane,srcpoints[0],srcpoints[1],srcpoints[2],temp_points); + edgeplane, srcpoints[0], srcpoints[1], srcpoints[2], temp_points); - if(clipped_count == 0) return 0; + if (clipped_count == 0) return 0; // edge 1 - EDGE_PLANE(tripoints[1],tripoints[2],tri_plane,edgeplane); + EDGE_PLANE(tripoints[1], tripoints[2], tri_plane, edgeplane); clipped_count = PLANE_CLIP_POLYGON3D( - edgeplane,temp_points,clipped_count,temp_points1); + edgeplane, temp_points, clipped_count, temp_points1); - if(clipped_count == 0) return 0; + if (clipped_count == 0) return 0; // edge 2 - EDGE_PLANE(tripoints[2],tripoints[0],tri_plane,edgeplane); + EDGE_PLANE(tripoints[2], tripoints[0], tri_plane, edgeplane); clipped_count = PLANE_CLIP_POLYGON3D( - edgeplane,temp_points1,clipped_count,clip_points); + edgeplane, temp_points1, clipped_count, clip_points); return clipped_count; - /*GUINT i0 = (tri_plane.closestAxis()+1)%3; GUINT i1 = (i0+1)%3; // edge 0 @@ -172,13 +169,13 @@ public: } SIMD_FORCE_INLINE void sort_isect( - GREAL & isect0,GREAL & isect1,GUINT &e0,GUINT &e1,btVector3 & vec0,btVector3 & vec1) + GREAL &isect0, GREAL &isect1, GUINT &e0, GUINT &e1, btVector3 &vec0, btVector3 &vec1) { - if(isect1=isect_v[1]) // face U casts face V + if (isect_u[1] >= isect_v[1]) // face U casts face V { return 1; } - else if(isect_v[0]<=isect_u[0]) // face V casts face U + else if (isect_v[0] <= isect_u[0]) // face V casts face U { return 2; } @@ -257,32 +253,31 @@ public: closest_point_v = vp_e0; // calc edges and separation - if(isect_u[1]+ MIN_EDGE_EDGE_DIS=isect_u[1]) // face V casts face U + if (isect_v[1] >= isect_u[1]) // face V casts face U { return 2; } - else if(isect_u[0]<=isect_v[0]) // face U casts face V + else if (isect_u[0] <= isect_v[0]) // face U casts face V { return 1; } @@ -291,41 +286,39 @@ public: closest_point_v = vp_e1; // calc edges and separation - if(isect_v[1]+MIN_EDGE_EDGE_DIS0.0f && du0du2>0.0f) // same sign on all of them + not equal 0 ? + if (du0du1 > 0.0f && du0du2 > 0.0f) // same sign on all of them + not equal 0 ? { - if(du[0]<0) //we need test behind the triangle plane + if (du[0] < 0) //we need test behind the triangle plane { - distances[0] = GIM_MAX3(du[0],du[1],du[2]); + distances[0] = GIM_MAX3(du[0], du[1], du[2]); distances[0] = -distances[0]; - if(distances[0]>margin) return false; //never intersect + if (distances[0] > margin) return false; //never intersect //reorder triangle v - VEC_SWAP(tv_vertices[0],tv_vertices[1]); - VEC_SCALE_4(tv_plane,-1.0f,tv_plane); + VEC_SWAP(tv_vertices[0], tv_vertices[1]); + VEC_SCALE_4(tv_plane, -1.0f, tv_plane); } else { - distances[0] = GIM_MIN3(du[0],du[1],du[2]); - if(distances[0]>margin) return false; //never intersect + distances[0] = GIM_MIN3(du[0], du[1], du[2]); + if (distances[0] > margin) return false; //never intersect } } else { //Look if we need to invert the triangle - distances[0] = (du[0]+du[1]+du[2])/3.0f; //centroid + distances[0] = (du[0] + du[1] + du[2]) / 3.0f; //centroid - if(distances[0]<0.0f) + if (distances[0] < 0.0f) { //reorder triangle v - VEC_SWAP(tv_vertices[0],tv_vertices[1]); - VEC_SCALE_4(tv_plane,-1.0f,tv_plane); + VEC_SWAP(tv_vertices[0], tv_vertices[1]); + VEC_SCALE_4(tv_plane, -1.0f, tv_plane); - distances[0] = GIM_MAX3(du[0],du[1],du[2]); + distances[0] = GIM_MAX3(du[0], du[1], du[2]); distances[0] = -distances[0]; } else { - distances[0] = GIM_MIN3(du[0],du[1],du[2]); + distances[0] = GIM_MIN3(du[0], du[1], du[2]); } } - // plane U vs V points - TRIANGLE_PLANE(tu_vertices[0],tu_vertices[1],tu_vertices[2],tu_plane); + TRIANGLE_PLANE(tu_vertices[0], tu_vertices[1], tu_vertices[2], tu_plane); - dv[0] = DISTANCE_PLANE_POINT(tu_plane,tv_vertices[0]); - dv[1] = DISTANCE_PLANE_POINT(tu_plane,tv_vertices[1]); - dv[2] = DISTANCE_PLANE_POINT(tu_plane,tv_vertices[2]); + dv[0] = DISTANCE_PLANE_POINT(tu_plane, tv_vertices[0]); + dv[1] = DISTANCE_PLANE_POINT(tu_plane, tv_vertices[1]); + dv[2] = DISTANCE_PLANE_POINT(tu_plane, tv_vertices[2]); dv0dv1 = dv[0] * dv[1]; dv0dv2 = dv[0] * dv[2]; - - if(dv0dv1>0.0f && dv0dv2>0.0f) // same sign on all of them + not equal 0 ? + if (dv0dv1 > 0.0f && dv0dv2 > 0.0f) // same sign on all of them + not equal 0 ? { - if(dv[0]<0) //we need test behind the triangle plane + if (dv[0] < 0) //we need test behind the triangle plane { - distances[1] = GIM_MAX3(dv[0],dv[1],dv[2]); + distances[1] = GIM_MAX3(dv[0], dv[1], dv[2]); distances[1] = -distances[1]; - if(distances[1]>margin) return false; //never intersect + if (distances[1] > margin) return false; //never intersect //reorder triangle u - VEC_SWAP(tu_vertices[0],tu_vertices[1]); - VEC_SCALE_4(tu_plane,-1.0f,tu_plane); + VEC_SWAP(tu_vertices[0], tu_vertices[1]); + VEC_SCALE_4(tu_plane, -1.0f, tu_plane); } else { - distances[1] = GIM_MIN3(dv[0],dv[1],dv[2]); - if(distances[1]>margin) return false; //never intersect + distances[1] = GIM_MIN3(dv[0], dv[1], dv[2]); + if (distances[1] > margin) return false; //never intersect } } else { //Look if we need to invert the triangle - distances[1] = (dv[0]+dv[1]+dv[2])/3.0f; //centroid + distances[1] = (dv[0] + dv[1] + dv[2]) / 3.0f; //centroid - if(distances[1]<0.0f) + if (distances[1] < 0.0f) { //reorder triangle v - VEC_SWAP(tu_vertices[0],tu_vertices[1]); - VEC_SCALE_4(tu_plane,-1.0f,tu_plane); + VEC_SWAP(tu_vertices[0], tu_vertices[1]); + VEC_SCALE_4(tu_plane, -1.0f, tu_plane); - distances[1] = GIM_MAX3(dv[0],dv[1],dv[2]); + distances[1] = GIM_MAX3(dv[0], dv[1], dv[2]); distances[1] = -distances[1]; } else { - distances[1] = GIM_MIN3(dv[0],dv[1],dv[2]); + distances[1] = GIM_MIN3(dv[0], dv[1], dv[2]); } } @@ -448,47 +437,44 @@ public: } else {*/ - bl = 0; - if(distances[0]margin) return false; + if (distances[2] > margin) return false; contacts.m_penetration_depth = -distances[2] + margin; contacts.m_points[0] = closest_point_v; contacts.m_point_count = 1; - VEC_COPY(contacts.m_separating_normal,edge_edge_dir); + VEC_COPY(contacts.m_separating_normal, edge_edge_dir); return true; } //clip face against other - GUINT point_count; //TODO - if(bl == 0) //clip U points against V + if (bl == 0) //clip U points against V { - point_count = clip_triangle(tv_plane,tv_vertices,tu_vertices,contact_points); - if(point_count == 0) return false; - contacts.merge_points(tv_plane,margin,contact_points,point_count); + point_count = clip_triangle(tv_plane, tv_vertices, tu_vertices, contact_points); + if (point_count == 0) return false; + contacts.merge_points(tv_plane, margin, contact_points, point_count); } - else //clip V points against U + else //clip V points against U { - point_count = clip_triangle(tu_plane,tu_vertices,tv_vertices,contact_points); - if(point_count == 0) return false; - contacts.merge_points(tu_plane,margin,contact_points,point_count); + point_count = clip_triangle(tu_plane, tu_vertices, tv_vertices, contact_points); + if (point_count == 0) return false; + contacts.merge_points(tu_plane, margin, contact_points, point_count); contacts.m_separating_normal *= -1.f; } - if(contacts.m_point_count == 0) return false; + if (contacts.m_point_count == 0) return false; return true; } - }; - /*class GIM_TRIANGLE_CALCULATION_CACHE { public: @@ -621,20 +607,13 @@ public: };*/ - - bool GIM_TRIANGLE::collide_triangle_hard_test( - const GIM_TRIANGLE & other, - GIM_TRIANGLE_CONTACT_DATA & contact_data) const + const GIM_TRIANGLE &other, + GIM_TRIANGLE_CONTACT_DATA &contact_data) const { - GIM_TRIANGLE_CALCULATION_CACHE calc_cache; + GIM_TRIANGLE_CALCULATION_CACHE calc_cache; return calc_cache.triangle_collision( - m_vertices[0],m_vertices[1],m_vertices[2],m_margin, - other.m_vertices[0],other.m_vertices[1],other.m_vertices[2],other.m_margin, - contact_data); - + m_vertices[0], m_vertices[1], m_vertices[2], m_margin, + other.m_vertices[0], other.m_vertices[1], other.m_vertices[2], other.m_margin, + contact_data); } - - - - diff --git a/src/BulletCollision/Gimpact/gim_tri_collision.h b/src/BulletCollision/Gimpact/gim_tri_collision.h index 267f806e7..e6d4bf547 100644 --- a/src/BulletCollision/Gimpact/gim_tri_collision.h +++ b/src/BulletCollision/Gimpact/gim_tri_collision.h @@ -36,8 +36,6 @@ email: projectileman@yahoo.com #include "gim_box_collision.h" #include "gim_clip_polygon.h" - - #ifndef MAX_TRI_CLIPPING #define MAX_TRI_CLIPPING 16 #endif @@ -45,18 +43,18 @@ email: projectileman@yahoo.com //! Structure for collision struct GIM_TRIANGLE_CONTACT_DATA { - GREAL m_penetration_depth; - GUINT m_point_count; - btVector4 m_separating_normal; - btVector3 m_points[MAX_TRI_CLIPPING]; + GREAL m_penetration_depth; + GUINT m_point_count; + btVector4 m_separating_normal; + btVector3 m_points[MAX_TRI_CLIPPING]; - SIMD_FORCE_INLINE void copy_from(const GIM_TRIANGLE_CONTACT_DATA& other) + SIMD_FORCE_INLINE void copy_from(const GIM_TRIANGLE_CONTACT_DATA &other) { m_penetration_depth = other.m_penetration_depth; m_separating_normal = other.m_separating_normal; m_point_count = other.m_point_count; GUINT i = m_point_count; - while(i--) + while (i--) { m_points[i] = other.m_points[i]; } @@ -66,39 +64,36 @@ struct GIM_TRIANGLE_CONTACT_DATA { } - GIM_TRIANGLE_CONTACT_DATA(const GIM_TRIANGLE_CONTACT_DATA& other) + GIM_TRIANGLE_CONTACT_DATA(const GIM_TRIANGLE_CONTACT_DATA &other) { copy_from(other); } - - - - //! classify points that are closer - template - SIMD_FORCE_INLINE void mergepoints_generic(const CLASS_PLANE & plane, - GREAL margin, const btVector3 * points, GUINT point_count, DISTANCE_FUNC distance_func) - { - m_point_count = 0; - m_penetration_depth= -1000.0f; + //! classify points that are closer + template + SIMD_FORCE_INLINE void mergepoints_generic(const CLASS_PLANE &plane, + GREAL margin, const btVector3 *points, GUINT point_count, DISTANCE_FUNC distance_func) + { + m_point_count = 0; + m_penetration_depth = -1000.0f; GUINT point_indices[MAX_TRI_CLIPPING]; GUINT _k; - for(_k=0;_k=0.0f) + if (_dist >= 0.0f) { - if(_dist>m_penetration_depth) + if (_dist > m_penetration_depth) { m_penetration_depth = _dist; point_indices[0] = _k; - m_point_count=1; + m_point_count = 1; } - else if((_dist+G_EPSILON)>=m_penetration_depth) + else if ((_dist + G_EPSILON) >= m_penetration_depth) { point_indices[m_point_count] = _k; m_point_count++; @@ -106,88 +101,87 @@ struct GIM_TRIANGLE_CONTACT_DATA } } - for( _k=0;_kG_EPSILON) + else if (sumuv - 1.0f > G_EPSILON) { return false; } @@ -294,50 +288,49 @@ if 0.0<= u+v <=1.0 then they are inside of triangle /*! Test if point is in triangle, with m_margin tolerance */ - SIMD_FORCE_INLINE bool is_point_inside(const btVector3 & point, const btVector3 & tri_normal) const + SIMD_FORCE_INLINE bool is_point_inside(const btVector3 &point, const btVector3 &tri_normal) const { //Test with edge 0 btVector4 edge_plane; - this->get_edge_plane(0,tri_normal,edge_plane); - GREAL dist = DISTANCE_PLANE_POINT(edge_plane,point); - if(dist-m_margin>0.0f) return false; // outside plane + this->get_edge_plane(0, tri_normal, edge_plane); + GREAL dist = DISTANCE_PLANE_POINT(edge_plane, point); + if (dist - m_margin > 0.0f) return false; // outside plane - this->get_edge_plane(1,tri_normal,edge_plane); - dist = DISTANCE_PLANE_POINT(edge_plane,point); - if(dist-m_margin>0.0f) return false; // outside plane + this->get_edge_plane(1, tri_normal, edge_plane); + dist = DISTANCE_PLANE_POINT(edge_plane, point); + if (dist - m_margin > 0.0f) return false; // outside plane - this->get_edge_plane(2,tri_normal,edge_plane); - dist = DISTANCE_PLANE_POINT(edge_plane,point); - if(dist-m_margin>0.0f) return false; // outside plane + this->get_edge_plane(2, tri_normal, edge_plane); + dist = DISTANCE_PLANE_POINT(edge_plane, point); + if (dist - m_margin > 0.0f) return false; // outside plane return true; } - //! Bidireccional ray collision SIMD_FORCE_INLINE bool ray_collision( - const btVector3 & vPoint, - const btVector3 & vDir, btVector3 & pout, btVector3 & triangle_normal, - GREAL & tparam, GREAL tmax = G_REAL_INFINITY) + const btVector3 &vPoint, + const btVector3 &vDir, btVector3 &pout, btVector3 &triangle_normal, + GREAL &tparam, GREAL tmax = G_REAL_INFINITY) { btVector4 faceplane; { btVector3 dif1 = m_vertices[1] - m_vertices[0]; btVector3 dif2 = m_vertices[2] - m_vertices[0]; - VEC_CROSS(faceplane,dif1,dif2); - faceplane[3] = m_vertices[0].dot(faceplane); + VEC_CROSS(faceplane, dif1, dif2); + faceplane[3] = m_vertices[0].dot(faceplane); } - GUINT res = LINE_PLANE_COLLISION(faceplane,vDir,vPoint,pout,tparam, btScalar(0), tmax); - if(res == 0) return false; - if(! is_point_inside(pout,faceplane)) return false; + GUINT res = LINE_PLANE_COLLISION(faceplane, vDir, vPoint, pout, tparam, btScalar(0), tmax); + if (res == 0) return false; + if (!is_point_inside(pout, faceplane)) return false; - if(res==2) //invert normal + if (res == 2) //invert normal { - triangle_normal.setValue(-faceplane[0],-faceplane[1],-faceplane[2]); + triangle_normal.setValue(-faceplane[0], -faceplane[1], -faceplane[2]); } else { - triangle_normal.setValue(faceplane[0],faceplane[1],faceplane[2]); + triangle_normal.setValue(faceplane[0], faceplane[1], faceplane[2]); } VEC_NORMALIZE(triangle_normal); @@ -345,36 +338,31 @@ if 0.0<= u+v <=1.0 then they are inside of triangle return true; } - //! one direccion ray collision SIMD_FORCE_INLINE bool ray_collision_front_side( - const btVector3 & vPoint, - const btVector3 & vDir, btVector3 & pout, btVector3 & triangle_normal, - GREAL & tparam, GREAL tmax = G_REAL_INFINITY) + const btVector3 &vPoint, + const btVector3 &vDir, btVector3 &pout, btVector3 &triangle_normal, + GREAL &tparam, GREAL tmax = G_REAL_INFINITY) { btVector4 faceplane; { btVector3 dif1 = m_vertices[1] - m_vertices[0]; btVector3 dif2 = m_vertices[2] - m_vertices[0]; - VEC_CROSS(faceplane,dif1,dif2); - faceplane[3] = m_vertices[0].dot(faceplane); + VEC_CROSS(faceplane, dif1, dif2); + faceplane[3] = m_vertices[0].dot(faceplane); } - GUINT res = LINE_PLANE_COLLISION(faceplane,vDir,vPoint,pout,tparam, btScalar(0), tmax); - if(res != 1) return false; + GUINT res = LINE_PLANE_COLLISION(faceplane, vDir, vPoint, pout, tparam, btScalar(0), tmax); + if (res != 1) return false; - if(!is_point_inside(pout,faceplane)) return false; + if (!is_point_inside(pout, faceplane)) return false; - triangle_normal.setValue(faceplane[0],faceplane[1],faceplane[2]); + triangle_normal.setValue(faceplane[0], faceplane[1], faceplane[2]); VEC_NORMALIZE(triangle_normal); return true; } - }; - - - -#endif // GIM_TRI_COLLISION_H_INCLUDED +#endif // GIM_TRI_COLLISION_H_INCLUDED diff --git a/src/BulletCollision/NarrowPhaseCollision/btComputeGjkEpaPenetration.h b/src/BulletCollision/NarrowPhaseCollision/btComputeGjkEpaPenetration.h index bb8d8b872..2446c88cd 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btComputeGjkEpaPenetration.h +++ b/src/BulletCollision/NarrowPhaseCollision/btComputeGjkEpaPenetration.h @@ -16,163 +16,153 @@ subject to the following restrictions: #ifndef BT_GJK_EPA_PENETATION_CONVEX_COLLISION_H #define BT_GJK_EPA_PENETATION_CONVEX_COLLISION_H -#include "LinearMath/btTransform.h" // Note that btVector3 might be double precision... +#include "LinearMath/btTransform.h" // Note that btVector3 might be double precision... #include "btGjkEpa3.h" #include "btGjkCollisionDescription.h" #include "BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h" - - - - - template bool btGjkEpaCalcPenDepth(const btConvexTemplate& a, const btConvexTemplate& b, - const btGjkCollisionDescription& colDesc, - btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB) + const btGjkCollisionDescription& colDesc, + btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB) { - (void)v; - - // const btScalar radialmargin(btScalar(0.)); - - btVector3 guessVector(b.getWorldTransform().getOrigin()-a.getWorldTransform().getOrigin());//?? why not use the GJK input? - - btGjkEpaSolver3::sResults results; + (void)v; - - if(btGjkEpaSolver3_Penetration(a,b,guessVector,results)) - - { - // debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0)); - //resultOut->addContactPoint(results.normal,results.witnesses[1],-results.depth); - wWitnessOnA = results.witnesses[0]; - wWitnessOnB = results.witnesses[1]; - v = results.normal; - return true; - } else - { - if(btGjkEpaSolver3_Distance(a,b,guessVector,results)) - { - wWitnessOnA = results.witnesses[0]; - wWitnessOnB = results.witnesses[1]; - v = results.normal; - return false; - } - } - return false; + // const btScalar radialmargin(btScalar(0.)); + + btVector3 guessVector(b.getWorldTransform().getOrigin() - a.getWorldTransform().getOrigin()); //?? why not use the GJK input? + + btGjkEpaSolver3::sResults results; + + if (btGjkEpaSolver3_Penetration(a, b, guessVector, results)) + + { + // debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0)); + //resultOut->addContactPoint(results.normal,results.witnesses[1],-results.depth); + wWitnessOnA = results.witnesses[0]; + wWitnessOnB = results.witnesses[1]; + v = results.normal; + return true; + } + else + { + if (btGjkEpaSolver3_Distance(a, b, guessVector, results)) + { + wWitnessOnA = results.witnesses[0]; + wWitnessOnB = results.witnesses[1]; + v = results.normal; + return false; + } + } + return false; } template -int btComputeGjkEpaPenetration(const btConvexTemplate& a, const btConvexTemplate& b, const btGjkCollisionDescription& colDesc, btVoronoiSimplexSolver& simplexSolver, btGjkDistanceTemplate* distInfo) +int btComputeGjkEpaPenetration(const btConvexTemplate& a, const btConvexTemplate& b, const btGjkCollisionDescription& colDesc, btVoronoiSimplexSolver& simplexSolver, btGjkDistanceTemplate* distInfo) { - - bool m_catchDegeneracies = true; - btScalar m_cachedSeparatingDistance = 0.f; - - btScalar distance=btScalar(0.); - btVector3 normalInB(btScalar(0.),btScalar(0.),btScalar(0.)); - - btVector3 pointOnA,pointOnB; - btTransform localTransA = a.getWorldTransform(); - btTransform localTransB = b.getWorldTransform(); - - btScalar marginA = a.getMargin(); - btScalar marginB = b.getMargin(); - - int m_curIter = 0; - int gGjkMaxIter = colDesc.m_maxGjkIterations;//this is to catch invalid input, perhaps check for #NaN? - btVector3 m_cachedSeparatingAxis = colDesc.m_firstDir; - - bool isValid = false; - bool checkSimplex = false; - bool checkPenetration = true; - int m_degenerateSimplex = 0; - - int m_lastUsedMethod = -1; - - { - btScalar squaredDistance = BT_LARGE_FLOAT; - btScalar delta = btScalar(0.); - - btScalar margin = marginA + marginB; - - - - simplexSolver.reset(); - - for ( ; ; ) - //while (true) - { - - btVector3 seperatingAxisInA = (-m_cachedSeparatingAxis)* localTransA.getBasis(); - btVector3 seperatingAxisInB = m_cachedSeparatingAxis* localTransB.getBasis(); - - btVector3 pInA = a.getLocalSupportWithoutMargin(seperatingAxisInA); - btVector3 qInB = b.getLocalSupportWithoutMargin(seperatingAxisInB); - - btVector3 pWorld = localTransA(pInA); - btVector3 qWorld = localTransB(qInB); - - - - btVector3 w = pWorld - qWorld; - delta = m_cachedSeparatingAxis.dot(w); - - // potential exit, they don't overlap - if ((delta > btScalar(0.0)) && (delta * delta > squaredDistance * colDesc.m_maximumDistanceSquared)) - { - m_degenerateSimplex = 10; - checkSimplex=true; - //checkPenetration = false; - break; - } - - //exit 0: the new point is already in the simplex, or we didn't come any closer - if (simplexSolver.inSimplex(w)) - { - m_degenerateSimplex = 1; - checkSimplex = true; - break; - } - // are we getting any closer ? - btScalar f0 = squaredDistance - delta; - btScalar f1 = squaredDistance * colDesc.m_gjkRelError2; - - if (f0 <= f1) - { - if (f0 <= btScalar(0.)) - { - m_degenerateSimplex = 2; - } else - { - m_degenerateSimplex = 11; - } - checkSimplex = true; - break; - } - - //add current vertex to simplex - simplexSolver.addVertex(w, pWorld, qWorld); - btVector3 newCachedSeparatingAxis; - - //calculate the closest point to the origin (update vector v) - if (!simplexSolver.closest(newCachedSeparatingAxis)) - { - m_degenerateSimplex = 3; - checkSimplex = true; - break; - } - - if(newCachedSeparatingAxis.length2() btScalar(0.0)) && (delta * delta > squaredDistance * colDesc.m_maximumDistanceSquared)) + { + m_degenerateSimplex = 10; + checkSimplex = true; + //checkPenetration = false; + break; + } + + //exit 0: the new point is already in the simplex, or we didn't come any closer + if (simplexSolver.inSimplex(w)) + { + m_degenerateSimplex = 1; + checkSimplex = true; + break; + } + // are we getting any closer ? + btScalar f0 = squaredDistance - delta; + btScalar f1 = squaredDistance * colDesc.m_gjkRelError2; + + if (f0 <= f1) + { + if (f0 <= btScalar(0.)) + { + m_degenerateSimplex = 2; + } + else + { + m_degenerateSimplex = 11; + } + checkSimplex = true; + break; + } + + //add current vertex to simplex + simplexSolver.addVertex(w, pWorld, qWorld); + btVector3 newCachedSeparatingAxis; + + //calculate the closest point to the origin (update vector v) + if (!simplexSolver.closest(newCachedSeparatingAxis)) + { + m_degenerateSimplex = 3; + checkSimplex = true; + break; + } + + if (newCachedSeparatingAxis.length2() < colDesc.m_gjkRelError2) + { + m_cachedSeparatingAxis = newCachedSeparatingAxis; + m_degenerateSimplex = 6; + checkSimplex = true; + break; + } + + btScalar previousSquaredDistance = squaredDistance; + squaredDistance = newCachedSeparatingAxis.length2(); #if 0 ///warning: this termination condition leads to some problems in 2d test case see Bullet/Demos/Box2dDemo if (squaredDistance>previousSquaredDistance) @@ -182,188 +172,183 @@ int btComputeGjkEpaPenetration(const btConvexTemplate& a, const btConvexTemplate checkSimplex = false; break; } -#endif // - - - //redundant m_simplexSolver->compute_points(pointOnA, pointOnB); - - //are we getting any closer ? - if (previousSquaredDistance - squaredDistance <= SIMD_EPSILON * previousSquaredDistance) - { - // m_simplexSolver->backup_closest(m_cachedSeparatingAxis); - checkSimplex = true; - m_degenerateSimplex = 12; - - break; - } - - m_cachedSeparatingAxis = newCachedSeparatingAxis; - - //degeneracy, this is typically due to invalid/uninitialized worldtransforms for a btCollisionObject - if (m_curIter++ > gGjkMaxIter) - { -#if defined(DEBUG) || defined (_DEBUG) - - printf("btGjkPairDetector maxIter exceeded:%i\n",m_curIter); - printf("sepAxis=(%f,%f,%f), squaredDistance = %f\n", - m_cachedSeparatingAxis.getX(), - m_cachedSeparatingAxis.getY(), - m_cachedSeparatingAxis.getZ(), - squaredDistance); +#endif // + + //redundant m_simplexSolver->compute_points(pointOnA, pointOnB); + + //are we getting any closer ? + if (previousSquaredDistance - squaredDistance <= SIMD_EPSILON * previousSquaredDistance) + { + // m_simplexSolver->backup_closest(m_cachedSeparatingAxis); + checkSimplex = true; + m_degenerateSimplex = 12; + + break; + } + + m_cachedSeparatingAxis = newCachedSeparatingAxis; + + //degeneracy, this is typically due to invalid/uninitialized worldtransforms for a btCollisionObject + if (m_curIter++ > gGjkMaxIter) + { +#if defined(DEBUG) || defined(_DEBUG) + + printf("btGjkPairDetector maxIter exceeded:%i\n", m_curIter); + printf("sepAxis=(%f,%f,%f), squaredDistance = %f\n", + m_cachedSeparatingAxis.getX(), + m_cachedSeparatingAxis.getY(), + m_cachedSeparatingAxis.getZ(), + squaredDistance); #endif - - break; - - } - - - bool check = (!simplexSolver.fullSimplex()); - //bool check = (!m_simplexSolver->fullSimplex() && squaredDistance > SIMD_EPSILON * m_simplexSolver->maxVertex()); - - if (!check) - { - //do we need this backup_closest here ? - // m_simplexSolver->backup_closest(m_cachedSeparatingAxis); - m_degenerateSimplex = 13; - break; - } - } - - if (checkSimplex) - { - simplexSolver.compute_points(pointOnA, pointOnB); - normalInB = m_cachedSeparatingAxis; - - btScalar lenSqr =m_cachedSeparatingAxis.length2(); - - //valid normal - if (lenSqr < 0.0001) - { - m_degenerateSimplex = 5; - } - if (lenSqr > SIMD_EPSILON*SIMD_EPSILON) - { - btScalar rlen = btScalar(1.) / btSqrt(lenSqr ); - normalInB *= rlen; //normalize - - btScalar s = btSqrt(squaredDistance); - - btAssert(s > btScalar(0.0)); - pointOnA -= m_cachedSeparatingAxis * (marginA / s); - pointOnB += m_cachedSeparatingAxis * (marginB / s); - distance = ((btScalar(1.)/rlen) - margin); - isValid = true; - - m_lastUsedMethod = 1; - } else - { - m_lastUsedMethod = 2; - } - } - - bool catchDegeneratePenetrationCase = - (m_catchDegeneracies && m_degenerateSimplex && ((distance+margin) < 0.01)); - - //if (checkPenetration && !isValid) - if (checkPenetration && (!isValid || catchDegeneratePenetrationCase )) - { - //penetration case - - //if there is no way to handle penetrations, bail out - - // Penetration depth case. - btVector3 tmpPointOnA,tmpPointOnB; - - m_cachedSeparatingAxis.setZero(); - - bool isValid2 = btGjkEpaCalcPenDepth(a,b, - colDesc, - m_cachedSeparatingAxis, tmpPointOnA, tmpPointOnB); - - if (isValid2) - { - btVector3 tmpNormalInB = tmpPointOnB-tmpPointOnA; - btScalar lenSqr = tmpNormalInB.length2(); - if (lenSqr <= (SIMD_EPSILON*SIMD_EPSILON)) - { - tmpNormalInB = m_cachedSeparatingAxis; - lenSqr = m_cachedSeparatingAxis.length2(); - } - - if (lenSqr > (SIMD_EPSILON*SIMD_EPSILON)) - { - tmpNormalInB /= btSqrt(lenSqr); - btScalar distance2 = -(tmpPointOnA-tmpPointOnB).length(); - //only replace valid penetrations when the result is deeper (check) - if (!isValid || (distance2 < distance)) - { - distance = distance2; - pointOnA = tmpPointOnA; - pointOnB = tmpPointOnB; - normalInB = tmpNormalInB; - - isValid = true; - m_lastUsedMethod = 3; - } else - { - m_lastUsedMethod = 8; - } - } else - { - m_lastUsedMethod = 9; - } - } else - - { - ///this is another degenerate case, where the initial GJK calculation reports a degenerate case - ///EPA reports no penetration, and the second GJK (using the supporting vector without margin) - ///reports a valid positive distance. Use the results of the second GJK instead of failing. - ///thanks to Jacob.Langford for the reproduction case - ///http://code.google.com/p/bullet/issues/detail?id=250 - - - if (m_cachedSeparatingAxis.length2() > btScalar(0.)) - { - btScalar distance2 = (tmpPointOnA-tmpPointOnB).length()-margin; - //only replace valid distances when the distance is less - if (!isValid || (distance2 < distance)) - { - distance = distance2; - pointOnA = tmpPointOnA; - pointOnB = tmpPointOnB; - pointOnA -= m_cachedSeparatingAxis * marginA ; - pointOnB += m_cachedSeparatingAxis * marginB ; - normalInB = m_cachedSeparatingAxis; - normalInB.normalize(); - - isValid = true; - m_lastUsedMethod = 6; - } else - { - m_lastUsedMethod = 5; - } - } - } - } - } - - - - if (isValid && ((distance < 0) || (distance*distance < colDesc.m_maximumDistanceSquared))) - { - - m_cachedSeparatingAxis = normalInB; - m_cachedSeparatingDistance = distance; - distInfo->m_distance = distance; - distInfo->m_normalBtoA = normalInB; - distInfo->m_pointOnB = pointOnB; - distInfo->m_pointOnA = pointOnB+normalInB*distance; - return 0; - } - return -m_lastUsedMethod; + + break; + } + + bool check = (!simplexSolver.fullSimplex()); + //bool check = (!m_simplexSolver->fullSimplex() && squaredDistance > SIMD_EPSILON * m_simplexSolver->maxVertex()); + + if (!check) + { + //do we need this backup_closest here ? + // m_simplexSolver->backup_closest(m_cachedSeparatingAxis); + m_degenerateSimplex = 13; + break; + } + } + + if (checkSimplex) + { + simplexSolver.compute_points(pointOnA, pointOnB); + normalInB = m_cachedSeparatingAxis; + + btScalar lenSqr = m_cachedSeparatingAxis.length2(); + + //valid normal + if (lenSqr < 0.0001) + { + m_degenerateSimplex = 5; + } + if (lenSqr > SIMD_EPSILON * SIMD_EPSILON) + { + btScalar rlen = btScalar(1.) / btSqrt(lenSqr); + normalInB *= rlen; //normalize + + btScalar s = btSqrt(squaredDistance); + + btAssert(s > btScalar(0.0)); + pointOnA -= m_cachedSeparatingAxis * (marginA / s); + pointOnB += m_cachedSeparatingAxis * (marginB / s); + distance = ((btScalar(1.) / rlen) - margin); + isValid = true; + + m_lastUsedMethod = 1; + } + else + { + m_lastUsedMethod = 2; + } + } + + bool catchDegeneratePenetrationCase = + (m_catchDegeneracies && m_degenerateSimplex && ((distance + margin) < 0.01)); + + //if (checkPenetration && !isValid) + if (checkPenetration && (!isValid || catchDegeneratePenetrationCase)) + { + //penetration case + + //if there is no way to handle penetrations, bail out + + // Penetration depth case. + btVector3 tmpPointOnA, tmpPointOnB; + + m_cachedSeparatingAxis.setZero(); + + bool isValid2 = btGjkEpaCalcPenDepth(a, b, + colDesc, + m_cachedSeparatingAxis, tmpPointOnA, tmpPointOnB); + + if (isValid2) + { + btVector3 tmpNormalInB = tmpPointOnB - tmpPointOnA; + btScalar lenSqr = tmpNormalInB.length2(); + if (lenSqr <= (SIMD_EPSILON * SIMD_EPSILON)) + { + tmpNormalInB = m_cachedSeparatingAxis; + lenSqr = m_cachedSeparatingAxis.length2(); + } + + if (lenSqr > (SIMD_EPSILON * SIMD_EPSILON)) + { + tmpNormalInB /= btSqrt(lenSqr); + btScalar distance2 = -(tmpPointOnA - tmpPointOnB).length(); + //only replace valid penetrations when the result is deeper (check) + if (!isValid || (distance2 < distance)) + { + distance = distance2; + pointOnA = tmpPointOnA; + pointOnB = tmpPointOnB; + normalInB = tmpNormalInB; + + isValid = true; + m_lastUsedMethod = 3; + } + else + { + m_lastUsedMethod = 8; + } + } + else + { + m_lastUsedMethod = 9; + } + } + else + + { + ///this is another degenerate case, where the initial GJK calculation reports a degenerate case + ///EPA reports no penetration, and the second GJK (using the supporting vector without margin) + ///reports a valid positive distance. Use the results of the second GJK instead of failing. + ///thanks to Jacob.Langford for the reproduction case + ///http://code.google.com/p/bullet/issues/detail?id=250 + + if (m_cachedSeparatingAxis.length2() > btScalar(0.)) + { + btScalar distance2 = (tmpPointOnA - tmpPointOnB).length() - margin; + //only replace valid distances when the distance is less + if (!isValid || (distance2 < distance)) + { + distance = distance2; + pointOnA = tmpPointOnA; + pointOnB = tmpPointOnB; + pointOnA -= m_cachedSeparatingAxis * marginA; + pointOnB += m_cachedSeparatingAxis * marginB; + normalInB = m_cachedSeparatingAxis; + normalInB.normalize(); + + isValid = true; + m_lastUsedMethod = 6; + } + else + { + m_lastUsedMethod = 5; + } + } + } + } + } + + if (isValid && ((distance < 0) || (distance * distance < colDesc.m_maximumDistanceSquared))) + { + m_cachedSeparatingAxis = normalInB; + m_cachedSeparatingDistance = distance; + distInfo->m_distance = distance; + distInfo->m_normalBtoA = normalInB; + distInfo->m_pointOnB = pointOnB; + distInfo->m_pointOnA = pointOnB + normalInB * distance; + return 0; + } + return -m_lastUsedMethod; } - - - -#endif //BT_GJK_EPA_PENETATION_CONVEX_COLLISION_H +#endif //BT_GJK_EPA_PENETATION_CONVEX_COLLISION_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp b/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp index 3481fec85..38df8d480 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp +++ b/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btContinuousConvexCollision.h" #include "BulletCollision/CollisionShapes/btConvexShape.h" #include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" @@ -24,59 +23,60 @@ subject to the following restrictions: #include "btPointCollector.h" #include "BulletCollision/CollisionShapes/btStaticPlaneShape.h" - - -btContinuousConvexCollision::btContinuousConvexCollision ( const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* penetrationDepthSolver) -:m_simplexSolver(simplexSolver), -m_penetrationDepthSolver(penetrationDepthSolver), -m_convexA(convexA),m_convexB1(convexB),m_planeShape(0) +btContinuousConvexCollision::btContinuousConvexCollision(const btConvexShape* convexA, const btConvexShape* convexB, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* penetrationDepthSolver) + : m_simplexSolver(simplexSolver), + m_penetrationDepthSolver(penetrationDepthSolver), + m_convexA(convexA), + m_convexB1(convexB), + m_planeShape(0) { } - -btContinuousConvexCollision::btContinuousConvexCollision( const btConvexShape* convexA,const btStaticPlaneShape* plane) -:m_simplexSolver(0), -m_penetrationDepthSolver(0), -m_convexA(convexA),m_convexB1(0),m_planeShape(plane) +btContinuousConvexCollision::btContinuousConvexCollision(const btConvexShape* convexA, const btStaticPlaneShape* plane) + : m_simplexSolver(0), + m_penetrationDepthSolver(0), + m_convexA(convexA), + m_convexB1(0), + m_planeShape(plane) { } - /// This maximum should not be necessary. It allows for untested/degenerate cases in production code. /// You don't want your game ever to lock-up. #define MAX_ITERATIONS 64 -void btContinuousConvexCollision::computeClosestPoints( const btTransform& transA, const btTransform& transB,btPointCollector& pointCollector) +void btContinuousConvexCollision::computeClosestPoints(const btTransform& transA, const btTransform& transB, btPointCollector& pointCollector) { if (m_convexB1) { m_simplexSolver->reset(); - btGjkPairDetector gjk(m_convexA,m_convexB1,m_convexA->getShapeType(),m_convexB1->getShapeType(),m_convexA->getMargin(),m_convexB1->getMargin(),m_simplexSolver,m_penetrationDepthSolver); + btGjkPairDetector gjk(m_convexA, m_convexB1, m_convexA->getShapeType(), m_convexB1->getShapeType(), m_convexA->getMargin(), m_convexB1->getMargin(), m_simplexSolver, m_penetrationDepthSolver); btGjkPairDetector::ClosestPointInput input; input.m_transformA = transA; input.m_transformB = transB; - gjk.getClosestPoints(input,pointCollector,0); - } else + gjk.getClosestPoints(input, pointCollector, 0); + } + else { //convex versus plane const btConvexShape* convexShape = m_convexA; const btStaticPlaneShape* planeShape = m_planeShape; - + const btVector3& planeNormal = planeShape->getPlaneNormal(); const btScalar& planeConstant = planeShape->getPlaneConstant(); - + btTransform convexWorldTransform = transA; btTransform convexInPlaneTrans; - convexInPlaneTrans= transB.inverse() * convexWorldTransform; + convexInPlaneTrans = transB.inverse() * convexWorldTransform; btTransform planeInConvex; - planeInConvex= convexWorldTransform.inverse() * transB; - - btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis()*-planeNormal); + planeInConvex = convexWorldTransform.inverse() * transB; + + btVector3 vtx = convexShape->localGetSupportingVertex(planeInConvex.getBasis() * -planeNormal); btVector3 vtxInPlane = convexInPlaneTrans(vtx); btScalar distance = (planeNormal.dot(vtxInPlane) - planeConstant); - btVector3 vtxInPlaneProjected = vtxInPlane - distance*planeNormal; + btVector3 vtxInPlaneProjected = vtxInPlane - distance * planeNormal; btVector3 vtxInPlaneWorld = transB * vtxInPlaneProjected; btVector3 normalOnSurfaceB = transB.getBasis() * planeNormal; @@ -87,36 +87,33 @@ void btContinuousConvexCollision::computeClosestPoints( const btTransform& trans } } -bool btContinuousConvexCollision::calcTimeOfImpact( - const btTransform& fromA, - const btTransform& toA, - const btTransform& fromB, - const btTransform& toB, - CastResult& result) +bool btContinuousConvexCollision::calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result) { - - /// compute linear and angular velocity for this interval, to interpolate - btVector3 linVelA,angVelA,linVelB,angVelB; - btTransformUtil::calculateVelocity(fromA,toA,btScalar(1.),linVelA,angVelA); - btTransformUtil::calculateVelocity(fromB,toB,btScalar(1.),linVelB,angVelB); - + btVector3 linVelA, angVelA, linVelB, angVelB; + btTransformUtil::calculateVelocity(fromA, toA, btScalar(1.), linVelA, angVelA); + btTransformUtil::calculateVelocity(fromB, toB, btScalar(1.), linVelB, angVelB); btScalar boundingRadiusA = m_convexA->getAngularMotionDisc(); - btScalar boundingRadiusB = m_convexB1?m_convexB1->getAngularMotionDisc():0.f; + btScalar boundingRadiusB = m_convexB1 ? m_convexB1->getAngularMotionDisc() : 0.f; btScalar maxAngularProjectedVelocity = angVelA.length() * boundingRadiusA + angVelB.length() * boundingRadiusB; - btVector3 relLinVel = (linVelB-linVelA); + btVector3 relLinVel = (linVelB - linVelA); - btScalar relLinVelocLength = (linVelB-linVelA).length(); - - if ((relLinVelocLength+maxAngularProjectedVelocity) == 0.f) + btScalar relLinVelocLength = (linVelB - linVelA).length(); + + if ((relLinVelocLength + maxAngularProjectedVelocity) == 0.f) return false; btScalar lambda = btScalar(0.); btVector3 n; - n.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); + n.setValue(btScalar(0.), btScalar(0.), btScalar(0.)); bool hasResult = false; btVector3 c; @@ -126,14 +123,13 @@ bool btContinuousConvexCollision::calcTimeOfImpact( int numIter = 0; //first solution, using GJK - btScalar radius = 0.001f; -// result.drawCoordSystem(sphereTr); + // result.drawCoordSystem(sphereTr); - btPointCollector pointCollector1; + btPointCollector pointCollector1; - { - computeClosestPoints(fromA,fromB,pointCollector1); + { + computeClosestPoints(fromA, fromB, pointCollector1); hasResult = pointCollector1.m_hasResult; c = pointCollector1.m_pointInWorld; @@ -145,7 +141,7 @@ bool btContinuousConvexCollision::calcTimeOfImpact( dist = pointCollector1.m_distance + result.m_allowedPenetration; n = pointCollector1.m_normalOnBInWorld; btScalar projectedLinearVelocity = relLinVel.dot(n); - if ((projectedLinearVelocity+ maxAngularProjectedVelocity)<=SIMD_EPSILON) + if ((projectedLinearVelocity + maxAngularProjectedVelocity) <= SIMD_EPSILON) return false; //not close enough @@ -153,18 +149,17 @@ bool btContinuousConvexCollision::calcTimeOfImpact( { if (result.m_debugDrawer) { - result.m_debugDrawer->drawSphere(c,0.2f,btVector3(1,1,1)); + result.m_debugDrawer->drawSphere(c, 0.2f, btVector3(1, 1, 1)); } btScalar dLambda = btScalar(0.); projectedLinearVelocity = relLinVel.dot(n); - //don't report time of impact for motion away from the contact normal (or causes minor penetration) - if ((projectedLinearVelocity+ maxAngularProjectedVelocity)<=SIMD_EPSILON) + if ((projectedLinearVelocity + maxAngularProjectedVelocity) <= SIMD_EPSILON) return false; - - dLambda = dist / (projectedLinearVelocity+ maxAngularProjectedVelocity); + + dLambda = dist / (projectedLinearVelocity + maxAngularProjectedVelocity); lambda += dLambda; @@ -181,28 +176,29 @@ bool btContinuousConvexCollision::calcTimeOfImpact( lastLambda = lambda; //interpolate to next lambda - btTransform interpolatedTransA,interpolatedTransB,relativeTrans; + btTransform interpolatedTransA, interpolatedTransB, relativeTrans; - btTransformUtil::integrateTransform(fromA,linVelA,angVelA,lambda,interpolatedTransA); - btTransformUtil::integrateTransform(fromB,linVelB,angVelB,lambda,interpolatedTransB); + btTransformUtil::integrateTransform(fromA, linVelA, angVelA, lambda, interpolatedTransA); + btTransformUtil::integrateTransform(fromB, linVelB, angVelB, lambda, interpolatedTransB); relativeTrans = interpolatedTransB.inverseTimes(interpolatedTransA); if (result.m_debugDrawer) { - result.m_debugDrawer->drawSphere(interpolatedTransA.getOrigin(),0.2f,btVector3(1,0,0)); + result.m_debugDrawer->drawSphere(interpolatedTransA.getOrigin(), 0.2f, btVector3(1, 0, 0)); } - result.DebugDraw( lambda ); + result.DebugDraw(lambda); - btPointCollector pointCollector; - computeClosestPoints(interpolatedTransA,interpolatedTransB,pointCollector); + btPointCollector pointCollector; + computeClosestPoints(interpolatedTransA, interpolatedTransB, pointCollector); if (pointCollector.m_hasResult) { - dist = pointCollector.m_distance+result.m_allowedPenetration; - c = pointCollector.m_pointInWorld; + dist = pointCollector.m_distance + result.m_allowedPenetration; + c = pointCollector.m_pointInWorld; n = pointCollector.m_normalOnBInWorld; - } else + } + else { result.reportFailure(-1, numIter); return false; @@ -215,7 +211,7 @@ bool btContinuousConvexCollision::calcTimeOfImpact( return false; } } - + result.m_fraction = lambda; result.m_normal = n; result.m_hitPoint = c; @@ -224,4 +220,3 @@ bool btContinuousConvexCollision::calcTimeOfImpact( return false; } - diff --git a/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h b/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h index 528b5e010..67b2205c3 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h +++ b/src/BulletCollision/NarrowPhaseCollision/btContinuousConvexCollision.h @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef BT_CONTINUOUS_COLLISION_CONVEX_CAST_H #define BT_CONTINUOUS_COLLISION_CONVEX_CAST_H @@ -30,30 +29,25 @@ class btStaticPlaneShape; class btContinuousConvexCollision : public btConvexCast { btSimplexSolverInterface* m_simplexSolver; - btConvexPenetrationDepthSolver* m_penetrationDepthSolver; - const btConvexShape* m_convexA; + btConvexPenetrationDepthSolver* m_penetrationDepthSolver; + const btConvexShape* m_convexA; //second object is either a convex or a plane (code sharing) - const btConvexShape* m_convexB1; - const btStaticPlaneShape* m_planeShape; + const btConvexShape* m_convexB1; + const btStaticPlaneShape* m_planeShape; - void computeClosestPoints( const btTransform& transA, const btTransform& transB,struct btPointCollector& pointCollector); + void computeClosestPoints(const btTransform& transA, const btTransform& transB, struct btPointCollector& pointCollector); public: + btContinuousConvexCollision(const btConvexShape* shapeA, const btConvexShape* shapeB, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* penetrationDepthSolver); - btContinuousConvexCollision (const btConvexShape* shapeA,const btConvexShape* shapeB ,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver); - - btContinuousConvexCollision(const btConvexShape* shapeA,const btStaticPlaneShape* plane ); - - virtual bool calcTimeOfImpact( - const btTransform& fromA, - const btTransform& toA, - const btTransform& fromB, - const btTransform& toB, - CastResult& result); - + btContinuousConvexCollision(const btConvexShape* shapeA, const btStaticPlaneShape* plane); + virtual bool calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result); }; - -#endif //BT_CONTINUOUS_COLLISION_CONVEX_CAST_H - +#endif //BT_CONTINUOUS_COLLISION_CONVEX_CAST_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h b/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h index bfd79d03b..98b0d5084 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h +++ b/src/BulletCollision/NarrowPhaseCollision/btConvexCast.h @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef BT_CONVEX_CAST_H #define BT_CONVEX_CAST_H @@ -27,47 +26,46 @@ class btMinkowskiSumShape; class btConvexCast { public: - - virtual ~btConvexCast(); ///RayResult stores the closest result /// alternatively, add a callback method to decide about closest/all results - struct CastResult + struct CastResult { //virtual bool addRayResult(const btVector3& normal,btScalar fraction) = 0; - - virtual void DebugDraw(btScalar fraction) {(void)fraction;} - virtual void drawCoordSystem(const btTransform& trans) {(void)trans;} - virtual void reportFailure(int errNo, int numIterations) {(void)errNo;(void)numIterations;} + + virtual void DebugDraw(btScalar fraction) { (void)fraction; } + virtual void drawCoordSystem(const btTransform& trans) { (void)trans; } + virtual void reportFailure(int errNo, int numIterations) + { + (void)errNo; + (void)numIterations; + } CastResult() - :m_fraction(btScalar(BT_LARGE_FLOAT)), - m_debugDrawer(0), - m_allowedPenetration(btScalar(0)) + : m_fraction(btScalar(BT_LARGE_FLOAT)), + m_debugDrawer(0), + m_allowedPenetration(btScalar(0)) { } + virtual ~CastResult(){}; - virtual ~CastResult() {}; - - btTransform m_hitTransformA; - btTransform m_hitTransformB; - btVector3 m_normal; - btVector3 m_hitPoint; - btScalar m_fraction; //input and output + btTransform m_hitTransformA; + btTransform m_hitTransformB; + btVector3 m_normal; + btVector3 m_hitPoint; + btScalar m_fraction; //input and output btIDebugDraw* m_debugDrawer; - btScalar m_allowedPenetration; - + btScalar m_allowedPenetration; }; - /// cast a convex against another convex object - virtual bool calcTimeOfImpact( - const btTransform& fromA, - const btTransform& toA, - const btTransform& fromB, - const btTransform& toB, - CastResult& result) = 0; + virtual bool calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result) = 0; }; -#endif //BT_CONVEX_CAST_H +#endif //BT_CONVEX_CAST_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h b/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h index 29620abff..65c9df934 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h +++ b/src/BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef BT_CONVEX_PENETRATION_DEPTH_H #define BT_CONVEX_PENETRATION_DEPTH_H @@ -25,16 +24,12 @@ class btTransform; ///ConvexPenetrationDepthSolver provides an interface for penetration depth calculation. class btConvexPenetrationDepthSolver { -public: - - virtual ~btConvexPenetrationDepthSolver() {}; - virtual bool calcPenDepth( btSimplexSolverInterface& simplexSolver, - const btConvexShape* convexA,const btConvexShape* convexB, - const btTransform& transA,const btTransform& transB, - btVector3& v, btVector3& pa, btVector3& pb, - class btIDebugDraw* debugDraw) = 0; - - +public: + virtual ~btConvexPenetrationDepthSolver(){}; + virtual bool calcPenDepth(btSimplexSolverInterface& simplexSolver, + const btConvexShape* convexA, const btConvexShape* convexB, + const btTransform& transA, const btTransform& transB, + btVector3& v, btVector3& pa, btVector3& pb, + class btIDebugDraw* debugDraw) = 0; }; -#endif //BT_CONVEX_PENETRATION_DEPTH_H - +#endif //BT_CONVEX_PENETRATION_DEPTH_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h b/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h index 0ea7b483c..d1bbb1a46 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h +++ b/src/BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef BT_DISCRETE_COLLISION_DETECTOR1_INTERFACE_H #define BT_DISCRETE_COLLISION_DETECTOR1_INTERFACE_H @@ -27,64 +26,60 @@ subject to the following restrictions: /// by taking closestPointInA = closestPointInB + m_distance * m_normalOnSurfaceB struct btDiscreteCollisionDetectorInterface { - struct Result { - - virtual ~Result(){} + virtual ~Result() {} ///setShapeIdentifiersA/B provides experimental support for per-triangle material / custom material combiner - virtual void setShapeIdentifiersA(int partId0,int index0)=0; - virtual void setShapeIdentifiersB(int partId1,int index1)=0; - virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth)=0; + virtual void setShapeIdentifiersA(int partId0, int index0) = 0; + virtual void setShapeIdentifiersB(int partId1, int index1) = 0; + virtual void addContactPoint(const btVector3& normalOnBInWorld, const btVector3& pointInWorld, btScalar depth) = 0; }; struct ClosestPointInput { ClosestPointInput() - :m_maximumDistanceSquared(btScalar(BT_LARGE_FLOAT)) + : m_maximumDistanceSquared(btScalar(BT_LARGE_FLOAT)) { } btTransform m_transformA; btTransform m_transformB; - btScalar m_maximumDistanceSquared; + btScalar m_maximumDistanceSquared; }; - virtual ~btDiscreteCollisionDetectorInterface() {}; + virtual ~btDiscreteCollisionDetectorInterface(){}; // // give either closest points (distance > 0) or penetration (distance) // the normal always points from B towards A // - virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false) = 0; - + virtual void getClosestPoints(const ClosestPointInput& input, Result& output, class btIDebugDraw* debugDraw, bool swapResults = false) = 0; }; struct btStorageResult : public btDiscreteCollisionDetectorInterface::Result { - btVector3 m_normalOnSurfaceB; - btVector3 m_closestPointInB; - btScalar m_distance; //negative means penetration ! + btVector3 m_normalOnSurfaceB; + btVector3 m_closestPointInB; + btScalar m_distance; //negative means penetration ! - protected: - btStorageResult() : m_distance(btScalar(BT_LARGE_FLOAT)) - { - } - - public: - virtual ~btStorageResult() {}; +protected: + btStorageResult() : m_distance(btScalar(BT_LARGE_FLOAT)) + { + } - virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) +public: + virtual ~btStorageResult(){}; + + virtual void addContactPoint(const btVector3& normalOnBInWorld, const btVector3& pointInWorld, btScalar depth) + { + if (depth < m_distance) { - if (depth < m_distance) - { - m_normalOnSurfaceB = normalOnBInWorld; - m_closestPointInB = pointInWorld; - m_distance = depth; - } + m_normalOnSurfaceB = normalOnBInWorld; + m_closestPointInB = pointInWorld; + m_distance = depth; } + } }; -#endif //BT_DISCRETE_COLLISION_DETECTOR1_INTERFACE_H - +#endif //BT_DISCRETE_COLLISION_DETECTOR1_INTERFACE_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btGjkCollisionDescription.h b/src/BulletCollision/NarrowPhaseCollision/btGjkCollisionDescription.h index 0b49b0ecc..c9fd84beb 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btGjkCollisionDescription.h +++ b/src/BulletCollision/NarrowPhaseCollision/btGjkCollisionDescription.h @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef GJK_COLLISION_DESCRIPTION_H #define GJK_COLLISION_DESCRIPTION_H @@ -21,21 +20,20 @@ subject to the following restrictions: struct btGjkCollisionDescription { - btVector3 m_firstDir; - int m_maxGjkIterations; - btScalar m_maximumDistanceSquared; - btScalar m_gjkRelError2; - btGjkCollisionDescription() - :m_firstDir(0,1,0), - m_maxGjkIterations(1000), - m_maximumDistanceSquared(1e30f), - m_gjkRelError2(1.0e-6) - { - } - virtual ~btGjkCollisionDescription() - { - } + btVector3 m_firstDir; + int m_maxGjkIterations; + btScalar m_maximumDistanceSquared; + btScalar m_gjkRelError2; + btGjkCollisionDescription() + : m_firstDir(0, 1, 0), + m_maxGjkIterations(1000), + m_maximumDistanceSquared(1e30f), + m_gjkRelError2(1.0e-6) + { + } + virtual ~btGjkCollisionDescription() + { + } }; -#endif //GJK_COLLISION_DESCRIPTION_H - +#endif //GJK_COLLISION_DESCRIPTION_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp b/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp index bef697a0a..9d61e75da 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp +++ b/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.cpp @@ -13,8 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "btGjkConvexCast.h" #include "BulletCollision/CollisionShapes/btSphereShape.h" #include "btGjkPairDetector.h" @@ -27,41 +25,39 @@ subject to the following restrictions: #define MAX_ITERATIONS 32 #endif -btGjkConvexCast::btGjkConvexCast(const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver) -:m_simplexSolver(simplexSolver), -m_convexA(convexA), -m_convexB(convexB) +btGjkConvexCast::btGjkConvexCast(const btConvexShape* convexA, const btConvexShape* convexB, btSimplexSolverInterface* simplexSolver) + : m_simplexSolver(simplexSolver), + m_convexA(convexA), + m_convexB(convexB) { } -bool btGjkConvexCast::calcTimeOfImpact( - const btTransform& fromA, - const btTransform& toA, - const btTransform& fromB, - const btTransform& toB, - CastResult& result) +bool btGjkConvexCast::calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result) { - - m_simplexSolver->reset(); /// compute linear velocity for this interval, to interpolate //assume no rotation/angular velocity, assert here? - btVector3 linVelA,linVelB; - linVelA = toA.getOrigin()-fromA.getOrigin(); - linVelB = toB.getOrigin()-fromB.getOrigin(); + btVector3 linVelA, linVelB; + linVelA = toA.getOrigin() - fromA.getOrigin(); + linVelB = toB.getOrigin() - fromB.getOrigin(); btScalar radius = btScalar(0.001); btScalar lambda = btScalar(0.); - btVector3 v(1,0,0); + btVector3 v(1, 0, 0); int maxIter = MAX_ITERATIONS; btVector3 n; - n.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); + n.setValue(btScalar(0.), btScalar(0.), btScalar(0.)); bool hasResult = false; btVector3 c; - btVector3 r = (linVelA-linVelB); + btVector3 r = (linVelA - linVelB); btScalar lastLambda = lambda; //btScalar epsilon = btScalar(0.001); @@ -69,17 +65,14 @@ bool btGjkConvexCast::calcTimeOfImpact( int numIter = 0; //first solution, using GJK - btTransform identityTrans; identityTrans.setIdentity(); + // result.drawCoordSystem(sphereTr); -// result.drawCoordSystem(sphereTr); + btPointCollector pointCollector; - btPointCollector pointCollector; - - - btGjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,0);//m_penetrationDepthSolver); + btGjkPairDetector gjk(m_convexA, m_convexB, m_simplexSolver, 0); //m_penetrationDepthSolver); btGjkPairDetector::ClosestPointInput input; //we don't use margins during CCD @@ -87,7 +80,7 @@ bool btGjkConvexCast::calcTimeOfImpact( input.m_transformA = fromA; input.m_transformB = fromB; - gjk.getClosestPoints(input,pointCollector,0); + gjk.getClosestPoints(input, pointCollector, 0); hasResult = pointCollector.m_hasResult; c = pointCollector.m_pointInWorld; @@ -98,20 +91,18 @@ bool btGjkConvexCast::calcTimeOfImpact( dist = pointCollector.m_distance; n = pointCollector.m_normalOnBInWorld; - - //not close enough while (dist > radius) { numIter++; if (numIter > maxIter) { - return false; //todo: report a failure + return false; //todo: report a failure } btScalar dLambda = btScalar(0.); btScalar projectedLinearVelocity = r.dot(n); - + dLambda = dist / (projectedLinearVelocity); lambda = lambda - dLambda; @@ -132,35 +123,35 @@ bool btGjkConvexCast::calcTimeOfImpact( lastLambda = lambda; //interpolate to next lambda - result.DebugDraw( lambda ); - input.m_transformA.getOrigin().setInterpolate3(fromA.getOrigin(),toA.getOrigin(),lambda); - input.m_transformB.getOrigin().setInterpolate3(fromB.getOrigin(),toB.getOrigin(),lambda); - - gjk.getClosestPoints(input,pointCollector,0); + result.DebugDraw(lambda); + input.m_transformA.getOrigin().setInterpolate3(fromA.getOrigin(), toA.getOrigin(), lambda); + input.m_transformB.getOrigin().setInterpolate3(fromB.getOrigin(), toB.getOrigin(), lambda); + + gjk.getClosestPoints(input, pointCollector, 0); if (pointCollector.m_hasResult) { if (pointCollector.m_distance < btScalar(0.)) { result.m_fraction = lastLambda; n = pointCollector.m_normalOnBInWorld; - result.m_normal=n; + result.m_normal = n; result.m_hitPoint = pointCollector.m_pointInWorld; return true; } - c = pointCollector.m_pointInWorld; + c = pointCollector.m_pointInWorld; n = pointCollector.m_normalOnBInWorld; dist = pointCollector.m_distance; - } else + } + else { //?? return false; } - } //is n normalized? //don't report time of impact for motion away from the contact normal (or causes minor penetration) - if (n.dot(r)>=-result.m_allowedPenetration) + if (n.dot(r) >= -result.m_allowedPenetration) return false; result.m_fraction = lambda; @@ -170,7 +161,4 @@ bool btGjkConvexCast::calcTimeOfImpact( } return false; - - } - diff --git a/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h b/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h index 6a42ee63b..ef5979173 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h +++ b/src/BulletCollision/NarrowPhaseCollision/btGjkConvexCast.h @@ -13,8 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #ifndef BT_GJK_CONVEX_CAST_H #define BT_GJK_CONVEX_CAST_H @@ -29,22 +27,20 @@ class btMinkowskiSumShape; ///GjkConvexCast performs a raycast on a convex object using support mapping. class btGjkConvexCast : public btConvexCast { - btSimplexSolverInterface* m_simplexSolver; - const btConvexShape* m_convexA; - const btConvexShape* m_convexB; + btSimplexSolverInterface* m_simplexSolver; + const btConvexShape* m_convexA; + const btConvexShape* m_convexB; public: - - btGjkConvexCast(const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver); + btGjkConvexCast(const btConvexShape* convexA, const btConvexShape* convexB, btSimplexSolverInterface* simplexSolver); /// cast a convex against another convex object - virtual bool calcTimeOfImpact( - const btTransform& fromA, - const btTransform& toA, - const btTransform& fromB, - const btTransform& toB, - CastResult& result); - + virtual bool calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result); }; -#endif //BT_GJK_CONVEX_CAST_H +#endif //BT_GJK_CONVEX_CAST_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp b/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp index eefb974bb..45d181713 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp +++ b/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.cpp @@ -26,1010 +26,1065 @@ GJK-EPA collision solver by Nathanael Presson, 2008 #include "BulletCollision/CollisionShapes/btSphereShape.h" #include "btGjkEpa2.h" -#if defined(DEBUG) || defined (_DEBUG) -#include //for debug printf +#if defined(DEBUG) || defined(_DEBUG) +#include //for debug printf #ifdef __SPU__ #include #define printf spu_printf -#endif //__SPU__ +#endif //__SPU__ #endif namespace gjkepa2_impl { +// Config - // Config - - /* GJK */ -#define GJK_MAX_ITERATIONS 128 +/* GJK */ +#define GJK_MAX_ITERATIONS 128 #ifdef BT_USE_DOUBLE_PRECISION - #define GJK_ACCURACY ((btScalar)1e-12) - #define GJK_MIN_DISTANCE ((btScalar)1e-12) - #define GJK_DUPLICATED_EPS ((btScalar)1e-12) +#define GJK_ACCURACY ((btScalar)1e-12) +#define GJK_MIN_DISTANCE ((btScalar)1e-12) +#define GJK_DUPLICATED_EPS ((btScalar)1e-12) #else - #define GJK_ACCURACY ((btScalar)0.0001) - #define GJK_MIN_DISTANCE ((btScalar)0.0001) - #define GJK_DUPLICATED_EPS ((btScalar)0.0001) -#endif //BT_USE_DOUBLE_PRECISION +#define GJK_ACCURACY ((btScalar)0.0001) +#define GJK_MIN_DISTANCE ((btScalar)0.0001) +#define GJK_DUPLICATED_EPS ((btScalar)0.0001) +#endif //BT_USE_DOUBLE_PRECISION +#define GJK_SIMPLEX2_EPS ((btScalar)0.0) +#define GJK_SIMPLEX3_EPS ((btScalar)0.0) +#define GJK_SIMPLEX4_EPS ((btScalar)0.0) -#define GJK_SIMPLEX2_EPS ((btScalar)0.0) -#define GJK_SIMPLEX3_EPS ((btScalar)0.0) -#define GJK_SIMPLEX4_EPS ((btScalar)0.0) - - /* EPA */ -#define EPA_MAX_VERTICES 128 -#define EPA_MAX_ITERATIONS 255 +/* EPA */ +#define EPA_MAX_VERTICES 128 +#define EPA_MAX_ITERATIONS 255 #ifdef BT_USE_DOUBLE_PRECISION - #define EPA_ACCURACY ((btScalar)1e-12) - #define EPA_PLANE_EPS ((btScalar)1e-14) - #define EPA_INSIDE_EPS ((btScalar)1e-9) +#define EPA_ACCURACY ((btScalar)1e-12) +#define EPA_PLANE_EPS ((btScalar)1e-14) +#define EPA_INSIDE_EPS ((btScalar)1e-9) #else - #define EPA_ACCURACY ((btScalar)0.0001) - #define EPA_PLANE_EPS ((btScalar)0.00001) - #define EPA_INSIDE_EPS ((btScalar)0.01) +#define EPA_ACCURACY ((btScalar)0.0001) +#define EPA_PLANE_EPS ((btScalar)0.00001) +#define EPA_INSIDE_EPS ((btScalar)0.01) #endif -#define EPA_FALLBACK (10*EPA_ACCURACY) -#define EPA_MAX_FACES (EPA_MAX_VERTICES*2) +#define EPA_FALLBACK (10 * EPA_ACCURACY) +#define EPA_MAX_FACES (EPA_MAX_VERTICES * 2) +// Shorthands +typedef unsigned int U; +typedef unsigned char U1; - // Shorthands - typedef unsigned int U; - typedef unsigned char U1; +// MinkowskiDiff +struct MinkowskiDiff +{ + const btConvexShape* m_shapes[2]; + btMatrix3x3 m_toshape1; + btTransform m_toshape0; +#ifdef __SPU__ + bool m_enableMargin; +#else + btVector3 (btConvexShape::*Ls)(const btVector3&) const; +#endif //__SPU__ - // MinkowskiDiff - struct MinkowskiDiff + MinkowskiDiff() { - const btConvexShape* m_shapes[2]; - btMatrix3x3 m_toshape1; - btTransform m_toshape0; + } #ifdef __SPU__ - bool m_enableMargin; + void EnableMargin(bool enable) + { + m_enableMargin = enable; + } + inline btVector3 Support0(const btVector3& d) const + { + if (m_enableMargin) + { + return m_shapes[0]->localGetSupportVertexNonVirtual(d); + } + else + { + return m_shapes[0]->localGetSupportVertexWithoutMarginNonVirtual(d); + } + } + inline btVector3 Support1(const btVector3& d) const + { + if (m_enableMargin) + { + return m_toshape0 * (m_shapes[1]->localGetSupportVertexNonVirtual(m_toshape1 * d)); + } + else + { + return m_toshape0 * (m_shapes[1]->localGetSupportVertexWithoutMarginNonVirtual(m_toshape1 * d)); + } + } #else - btVector3 (btConvexShape::*Ls)(const btVector3&) const; -#endif//__SPU__ - + void EnableMargin(bool enable) + { + if (enable) + Ls = &btConvexShape::localGetSupportVertexNonVirtual; + else + Ls = &btConvexShape::localGetSupportVertexWithoutMarginNonVirtual; + } + inline btVector3 Support0(const btVector3& d) const + { + return (((m_shapes[0])->*(Ls))(d)); + } + inline btVector3 Support1(const btVector3& d) const + { + return (m_toshape0 * ((m_shapes[1])->*(Ls))(m_toshape1 * d)); + } +#endif //__SPU__ - MinkowskiDiff() - { + inline btVector3 Support(const btVector3& d) const + { + return (Support0(d) - Support1(-d)); + } + btVector3 Support(const btVector3& d, U index) const + { + if (index) + return (Support1(d)); + else + return (Support0(d)); + } +}; - } -#ifdef __SPU__ - void EnableMargin(bool enable) - { - m_enableMargin = enable; - } - inline btVector3 Support0(const btVector3& d) const - { - if (m_enableMargin) - { - return m_shapes[0]->localGetSupportVertexNonVirtual(d); - } else - { - return m_shapes[0]->localGetSupportVertexWithoutMarginNonVirtual(d); - } - } - inline btVector3 Support1(const btVector3& d) const - { - if (m_enableMargin) - { - return m_toshape0*(m_shapes[1]->localGetSupportVertexNonVirtual(m_toshape1*d)); - } else - { - return m_toshape0*(m_shapes[1]->localGetSupportVertexWithoutMarginNonVirtual(m_toshape1*d)); - } - } -#else - void EnableMargin(bool enable) - { - if(enable) - Ls=&btConvexShape::localGetSupportVertexNonVirtual; - else - Ls=&btConvexShape::localGetSupportVertexWithoutMarginNonVirtual; - } - inline btVector3 Support0(const btVector3& d) const - { - return(((m_shapes[0])->*(Ls))(d)); - } - inline btVector3 Support1(const btVector3& d) const - { - return(m_toshape0*((m_shapes[1])->*(Ls))(m_toshape1*d)); - } -#endif //__SPU__ +typedef MinkowskiDiff tShape; - inline btVector3 Support(const btVector3& d) const - { - return(Support0(d)-Support1(-d)); - } - btVector3 Support(const btVector3& d,U index) const - { - if(index) - return(Support1(d)); - else - return(Support0(d)); - } +// GJK +struct GJK +{ + /* Types */ + struct sSV + { + btVector3 d, w; }; - - typedef MinkowskiDiff tShape; - - - // GJK - struct GJK + struct sSimplex { - /* Types */ - struct sSV + sSV* c[4]; + btScalar p[4]; + U rank; + }; + struct eStatus + { + enum _ { - btVector3 d,w; - }; - struct sSimplex - { - sSV* c[4]; - btScalar p[4]; - U rank; - }; - struct eStatus { enum _ { Valid, Inside, - Failed };}; - /* Fields */ - tShape m_shape; - btVector3 m_ray; - btScalar m_distance; - sSimplex m_simplices[2]; - sSV m_store[4]; - sSV* m_free[4]; - U m_nfree; - U m_current; - sSimplex* m_simplex; - eStatus::_ m_status; - /* Methods */ - GJK() - { - Initialize(); - } - void Initialize() - { - m_ray = btVector3(0,0,0); - m_nfree = 0; - m_status = eStatus::Failed; - m_current = 0; - m_distance = 0; - } - eStatus::_ Evaluate(const tShape& shapearg,const btVector3& guess) - { - U iterations=0; - btScalar sqdist=0; - btScalar alpha=0; - btVector3 lastw[4]; - U clastw=0; - /* Initialize solver */ - m_free[0] = &m_store[0]; - m_free[1] = &m_store[1]; - m_free[2] = &m_store[2]; - m_free[3] = &m_store[3]; - m_nfree = 4; - m_current = 0; - m_status = eStatus::Valid; - m_shape = shapearg; - m_distance = 0; - /* Initialize simplex */ - m_simplices[0].rank = 0; - m_ray = guess; - const btScalar sqrl= m_ray.length2(); - appendvertice(m_simplices[0],sqrl>0?-m_ray:btVector3(1,0,0)); - m_simplices[0].p[0] = 1; - m_ray = m_simplices[0].c[0]->w; - sqdist = sqrl; - lastw[0] = - lastw[1] = - lastw[2] = - lastw[3] = m_ray; - /* Loop */ - do { - const U next=1-m_current; - sSimplex& cs=m_simplices[m_current]; - sSimplex& ns=m_simplices[next]; - /* Check zero */ - const btScalar rl=m_ray.length(); - if(rlw; - bool found=false; - for(U i=0;i<4;++i) - { - if((w-lastw[i]).length2()w, - cs.c[1]->w, - weights,mask);break; - case 3: sqdist=projectorigin( cs.c[0]->w, - cs.c[1]->w, - cs.c[2]->w, - weights,mask);break; - case 4: sqdist=projectorigin( cs.c[0]->w, - cs.c[1]->w, - cs.c[2]->w, - cs.c[3]->w, - weights,mask);break; - } - if(sqdist>=0) - {/* Valid */ - ns.rank = 0; - m_ray = btVector3(0,0,0); - m_current = next; - for(U i=0,ni=cs.rank;iw*weights[i]; - } - else - { - m_free[m_nfree++] = cs.c[i]; - } - } - if(mask==15) m_status=eStatus::Inside; - } - else - {/* Return old simplex */ - removevertice(m_simplices[m_current]); - break; - } - m_status=((++iterations)rank) - { - case 1: - { - for(U i=0;i<3;++i) - { - btVector3 axis=btVector3(0,0,0); - axis[i]=1; - appendvertice(*m_simplex, axis); - if(EncloseOrigin()) return(true); - removevertice(*m_simplex); - appendvertice(*m_simplex,-axis); - if(EncloseOrigin()) return(true); - removevertice(*m_simplex); - } - } - break; - case 2: - { - const btVector3 d=m_simplex->c[1]->w-m_simplex->c[0]->w; - for(U i=0;i<3;++i) - { - btVector3 axis=btVector3(0,0,0); - axis[i]=1; - const btVector3 p=btCross(d,axis); - if(p.length2()>0) - { - appendvertice(*m_simplex, p); - if(EncloseOrigin()) return(true); - removevertice(*m_simplex); - appendvertice(*m_simplex,-p); - if(EncloseOrigin()) return(true); - removevertice(*m_simplex); - } - } - } - break; - case 3: - { - const btVector3 n=btCross(m_simplex->c[1]->w-m_simplex->c[0]->w, - m_simplex->c[2]->w-m_simplex->c[0]->w); - if(n.length2()>0) - { - appendvertice(*m_simplex,n); - if(EncloseOrigin()) return(true); - removevertice(*m_simplex); - appendvertice(*m_simplex,-n); - if(EncloseOrigin()) return(true); - removevertice(*m_simplex); - } - } - break; - case 4: - { - if(btFabs(det( m_simplex->c[0]->w-m_simplex->c[3]->w, - m_simplex->c[1]->w-m_simplex->c[3]->w, - m_simplex->c[2]->w-m_simplex->c[3]->w))>0) - return(true); - } - break; - } - return(false); - } - /* Internals */ - void getsupport(const btVector3& d,sSV& sv) const - { - sv.d = d/d.length(); - sv.w = m_shape.Support(sv.d); - } - void removevertice(sSimplex& simplex) - { - m_free[m_nfree++]=simplex.c[--simplex.rank]; - } - void appendvertice(sSimplex& simplex,const btVector3& v) - { - simplex.p[simplex.rank]=0; - simplex.c[simplex.rank]=m_free[--m_nfree]; - getsupport(v,*simplex.c[simplex.rank++]); - } - static btScalar det(const btVector3& a,const btVector3& b,const btVector3& c) - { - return( a.y()*b.z()*c.x()+a.z()*b.x()*c.y()- - a.x()*b.z()*c.y()-a.y()*b.x()*c.z()+ - a.x()*b.y()*c.z()-a.z()*b.y()*c.x()); - } - static btScalar projectorigin( const btVector3& a, - const btVector3& b, - btScalar* w,U& m) - { - const btVector3 d=b-a; - const btScalar l=d.length2(); - if(l>GJK_SIMPLEX2_EPS) - { - const btScalar t(l>0?-btDot(a,d)/l:0); - if(t>=1) { w[0]=0;w[1]=1;m=2;return(b.length2()); } - else if(t<=0) { w[0]=1;w[1]=0;m=1;return(a.length2()); } - else { w[0]=1-(w[1]=t);m=3;return((a+d*t).length2()); } - } - return(-1); - } - static btScalar projectorigin( const btVector3& a, - const btVector3& b, - const btVector3& c, - btScalar* w,U& m) - { - static const U imd3[]={1,2,0}; - const btVector3* vt[]={&a,&b,&c}; - const btVector3 dl[]={a-b,b-c,c-a}; - const btVector3 n=btCross(dl[0],dl[1]); - const btScalar l=n.length2(); - if(l>GJK_SIMPLEX3_EPS) - { - btScalar mindist=-1; - btScalar subw[2]={0.f,0.f}; - U subm(0); - for(U i=0;i<3;++i) - { - if(btDot(*vt[i],btCross(dl[i],n))>0) - { - const U j=imd3[i]; - const btScalar subd(projectorigin(*vt[i],*vt[j],subw,subm)); - if((mindist<0)||(subd(((subm&1)?1<GJK_SIMPLEX4_EPS)) - { - btScalar mindist=-1; - btScalar subw[3]={0.f,0.f,0.f}; - U subm(0); - for(U i=0;i<3;++i) - { - const U j=imd3[i]; - const btScalar s=vl*btDot(d,btCross(dl[i],dl[j])); - if(s>0) - { - const btScalar subd=projectorigin(*vt[i],*vt[j],d,subw,subm); - if((mindist<0)||(subd((subm&1?1< 0 ? -m_ray : btVector3(1, 0, 0)); + m_simplices[0].p[0] = 1; + m_ray = m_simplices[0].c[0]->w; + sqdist = sqrl; + lastw[0] = + lastw[1] = + lastw[2] = + lastw[3] = m_ray; + /* Loop */ + do { - btVector3 n; - btScalar d; - sSV* c[3]; - sFace* f[3]; - sFace* l[2]; - U1 e[3]; - U1 pass; - }; - struct sList + const U next = 1 - m_current; + sSimplex& cs = m_simplices[m_current]; + sSimplex& ns = m_simplices[next]; + /* Check zero */ + const btScalar rl = m_ray.length(); + if (rl < GJK_MIN_DISTANCE) + { /* Touching or inside */ + m_status = eStatus::Inside; + break; + } + /* Append new vertice in -'v' direction */ + appendvertice(cs, -m_ray); + const btVector3& w = cs.c[cs.rank - 1]->w; + bool found = false; + for (U i = 0; i < 4; ++i) + { + if ((w - lastw[i]).length2() < GJK_DUPLICATED_EPS) + { + found = true; + break; + } + } + if (found) + { /* Return old simplex */ + removevertice(m_simplices[m_current]); + break; + } + else + { /* Update lastw */ + lastw[clastw = (clastw + 1) & 3] = w; + } + /* Check for termination */ + const btScalar omega = btDot(m_ray, w) / rl; + alpha = btMax(omega, alpha); + if (((rl - alpha) - (GJK_ACCURACY * rl)) <= 0) + { /* Return old simplex */ + removevertice(m_simplices[m_current]); + break; + } + /* Reduce simplex */ + btScalar weights[4]; + U mask = 0; + switch (cs.rank) + { + case 2: + sqdist = projectorigin(cs.c[0]->w, + cs.c[1]->w, + weights, mask); + break; + case 3: + sqdist = projectorigin(cs.c[0]->w, + cs.c[1]->w, + cs.c[2]->w, + weights, mask); + break; + case 4: + sqdist = projectorigin(cs.c[0]->w, + cs.c[1]->w, + cs.c[2]->w, + cs.c[3]->w, + weights, mask); + break; + } + if (sqdist >= 0) + { /* Valid */ + ns.rank = 0; + m_ray = btVector3(0, 0, 0); + m_current = next; + for (U i = 0, ni = cs.rank; i < ni; ++i) + { + if (mask & (1 << i)) + { + ns.c[ns.rank] = cs.c[i]; + ns.p[ns.rank++] = weights[i]; + m_ray += cs.c[i]->w * weights[i]; + } + else + { + m_free[m_nfree++] = cs.c[i]; + } + } + if (mask == 15) m_status = eStatus::Inside; + } + else + { /* Return old simplex */ + removevertice(m_simplices[m_current]); + break; + } + m_status = ((++iterations) < GJK_MAX_ITERATIONS) ? m_status : eStatus::Failed; + } while (m_status == eStatus::Valid); + m_simplex = &m_simplices[m_current]; + switch (m_status) { - sFace* root; - U count; - sList() : root(0),count(0) {} - }; - struct sHorizon + case eStatus::Valid: + m_distance = m_ray.length(); + break; + case eStatus::Inside: + m_distance = 0; + break; + default: + { + } + } + return (m_status); + } + bool EncloseOrigin() + { + switch (m_simplex->rank) + { + case 1: + { + for (U i = 0; i < 3; ++i) + { + btVector3 axis = btVector3(0, 0, 0); + axis[i] = 1; + appendvertice(*m_simplex, axis); + if (EncloseOrigin()) return (true); + removevertice(*m_simplex); + appendvertice(*m_simplex, -axis); + if (EncloseOrigin()) return (true); + removevertice(*m_simplex); + } + } + break; + case 2: + { + const btVector3 d = m_simplex->c[1]->w - m_simplex->c[0]->w; + for (U i = 0; i < 3; ++i) + { + btVector3 axis = btVector3(0, 0, 0); + axis[i] = 1; + const btVector3 p = btCross(d, axis); + if (p.length2() > 0) + { + appendvertice(*m_simplex, p); + if (EncloseOrigin()) return (true); + removevertice(*m_simplex); + appendvertice(*m_simplex, -p); + if (EncloseOrigin()) return (true); + removevertice(*m_simplex); + } + } + } + break; + case 3: + { + const btVector3 n = btCross(m_simplex->c[1]->w - m_simplex->c[0]->w, + m_simplex->c[2]->w - m_simplex->c[0]->w); + if (n.length2() > 0) + { + appendvertice(*m_simplex, n); + if (EncloseOrigin()) return (true); + removevertice(*m_simplex); + appendvertice(*m_simplex, -n); + if (EncloseOrigin()) return (true); + removevertice(*m_simplex); + } + } + break; + case 4: + { + if (btFabs(det(m_simplex->c[0]->w - m_simplex->c[3]->w, + m_simplex->c[1]->w - m_simplex->c[3]->w, + m_simplex->c[2]->w - m_simplex->c[3]->w)) > 0) + return (true); + } + break; + } + return (false); + } + /* Internals */ + void getsupport(const btVector3& d, sSV& sv) const + { + sv.d = d / d.length(); + sv.w = m_shape.Support(sv.d); + } + void removevertice(sSimplex& simplex) + { + m_free[m_nfree++] = simplex.c[--simplex.rank]; + } + void appendvertice(sSimplex& simplex, const btVector3& v) + { + simplex.p[simplex.rank] = 0; + simplex.c[simplex.rank] = m_free[--m_nfree]; + getsupport(v, *simplex.c[simplex.rank++]); + } + static btScalar det(const btVector3& a, const btVector3& b, const btVector3& c) + { + return (a.y() * b.z() * c.x() + a.z() * b.x() * c.y() - + a.x() * b.z() * c.y() - a.y() * b.x() * c.z() + + a.x() * b.y() * c.z() - a.z() * b.y() * c.x()); + } + static btScalar projectorigin(const btVector3& a, + const btVector3& b, + btScalar* w, U& m) + { + const btVector3 d = b - a; + const btScalar l = d.length2(); + if (l > GJK_SIMPLEX2_EPS) + { + const btScalar t(l > 0 ? -btDot(a, d) / l : 0); + if (t >= 1) + { + w[0] = 0; + w[1] = 1; + m = 2; + return (b.length2()); + } + else if (t <= 0) + { + w[0] = 1; + w[1] = 0; + m = 1; + return (a.length2()); + } + else + { + w[0] = 1 - (w[1] = t); + m = 3; + return ((a + d * t).length2()); + } + } + return (-1); + } + static btScalar projectorigin(const btVector3& a, + const btVector3& b, + const btVector3& c, + btScalar* w, U& m) + { + static const U imd3[] = {1, 2, 0}; + const btVector3* vt[] = {&a, &b, &c}; + const btVector3 dl[] = {a - b, b - c, c - a}; + const btVector3 n = btCross(dl[0], dl[1]); + const btScalar l = n.length2(); + if (l > GJK_SIMPLEX3_EPS) + { + btScalar mindist = -1; + btScalar subw[2] = {0.f, 0.f}; + U subm(0); + for (U i = 0; i < 3; ++i) + { + if (btDot(*vt[i], btCross(dl[i], n)) > 0) + { + const U j = imd3[i]; + const btScalar subd(projectorigin(*vt[i], *vt[j], subw, subm)); + if ((mindist < 0) || (subd < mindist)) + { + mindist = subd; + m = static_cast(((subm & 1) ? 1 << i : 0) + ((subm & 2) ? 1 << j : 0)); + w[i] = subw[0]; + w[j] = subw[1]; + w[imd3[j]] = 0; + } + } + } + if (mindist < 0) + { + const btScalar d = btDot(a, n); + const btScalar s = btSqrt(l); + const btVector3 p = n * (d / l); + mindist = p.length2(); + m = 7; + w[0] = (btCross(dl[1], b - p)).length() / s; + w[1] = (btCross(dl[2], c - p)).length() / s; + w[2] = 1 - (w[0] + w[1]); + } + return (mindist); + } + return (-1); + } + static btScalar projectorigin(const btVector3& a, + const btVector3& b, + const btVector3& c, + const btVector3& d, + btScalar* w, U& m) + { + static const U imd3[] = {1, 2, 0}; + const btVector3* vt[] = {&a, &b, &c, &d}; + const btVector3 dl[] = {a - d, b - d, c - d}; + const btScalar vl = det(dl[0], dl[1], dl[2]); + const bool ng = (vl * btDot(a, btCross(b - c, a - b))) <= 0; + if (ng && (btFabs(vl) > GJK_SIMPLEX4_EPS)) + { + btScalar mindist = -1; + btScalar subw[3] = {0.f, 0.f, 0.f}; + U subm(0); + for (U i = 0; i < 3; ++i) + { + const U j = imd3[i]; + const btScalar s = vl * btDot(d, btCross(dl[i], dl[j])); + if (s > 0) + { + const btScalar subd = projectorigin(*vt[i], *vt[j], d, subw, subm); + if ((mindist < 0) || (subd < mindist)) + { + mindist = subd; + m = static_cast((subm & 1 ? 1 << i : 0) + + (subm & 2 ? 1 << j : 0) + + (subm & 4 ? 8 : 0)); + w[i] = subw[0]; + w[j] = subw[1]; + w[imd3[j]] = 0; + w[3] = subw[2]; + } + } + } + if (mindist < 0) + { + mindist = 0; + m = 15; + w[0] = det(c, b, d) / vl; + w[1] = det(a, c, d) / vl; + w[2] = det(b, a, d) / vl; + w[3] = 1 - (w[0] + w[1] + w[2]); + } + return (mindist); + } + return (-1); + } +}; + +// EPA +struct EPA +{ + /* Types */ + typedef GJK::sSV sSV; + struct sFace + { + btVector3 n; + btScalar d; + sSV* c[3]; + sFace* f[3]; + sFace* l[2]; + U1 e[3]; + U1 pass; + }; + struct sList + { + sFace* root; + U count; + sList() : root(0), count(0) {} + }; + struct sHorizon + { + sFace* cf; + sFace* ff; + U nf; + sHorizon() : cf(0), ff(0), nf(0) {} + }; + struct eStatus + { + enum _ { - sFace* cf; - sFace* ff; - U nf; - sHorizon() : cf(0),ff(0),nf(0) {} - }; - struct eStatus { enum _ { Valid, Touching, Degenerated, NonConvex, - InvalidHull, + InvalidHull, OutOfFaces, OutOfVertices, AccuraryReached, FallBack, - Failed };}; - /* Fields */ - eStatus::_ m_status; - GJK::sSimplex m_result; - btVector3 m_normal; - btScalar m_depth; - sSV m_sv_store[EPA_MAX_VERTICES]; - sFace m_fc_store[EPA_MAX_FACES]; - U m_nextsv; - sList m_hull; - sList m_stock; - /* Methods */ - EPA() - { - Initialize(); - } - - - static inline void bind(sFace* fa,U ea,sFace* fb,U eb) - { - fa->e[ea]=(U1)eb;fa->f[ea]=fb; - fb->e[eb]=(U1)ea;fb->f[eb]=fa; - } - static inline void append(sList& list,sFace* face) - { - face->l[0] = 0; - face->l[1] = list.root; - if(list.root) list.root->l[0]=face; - list.root = face; - ++list.count; - } - static inline void remove(sList& list,sFace* face) - { - if(face->l[1]) face->l[1]->l[0]=face->l[0]; - if(face->l[0]) face->l[0]->l[1]=face->l[1]; - if(face==list.root) list.root=face->l[1]; - --list.count; - } - - - void Initialize() - { - m_status = eStatus::Failed; - m_normal = btVector3(0,0,0); - m_depth = 0; - m_nextsv = 0; - for(U i=0;i1)&&gjk.EncloseOrigin()) - { - - /* Clean up */ - while(m_hull.root) - { - sFace* f = m_hull.root; - remove(m_hull,f); - append(m_stock,f); - } - m_status = eStatus::Valid; - m_nextsv = 0; - /* Orient simplex */ - if(gjk.det( simplex.c[0]->w-simplex.c[3]->w, - simplex.c[1]->w-simplex.c[3]->w, - simplex.c[2]->w-simplex.c[3]->w)<0) - { - btSwap(simplex.c[0],simplex.c[1]); - btSwap(simplex.p[0],simplex.p[1]); - } - /* Build initial hull */ - sFace* tetra[]={newface(simplex.c[0],simplex.c[1],simplex.c[2],true), - newface(simplex.c[1],simplex.c[0],simplex.c[3],true), - newface(simplex.c[2],simplex.c[1],simplex.c[3],true), - newface(simplex.c[0],simplex.c[2],simplex.c[3],true)}; - if(m_hull.count==4) - { - sFace* best=findbest(); - sFace outer=*best; - U pass=0; - U iterations=0; - bind(tetra[0],0,tetra[1],0); - bind(tetra[0],1,tetra[2],0); - bind(tetra[0],2,tetra[3],0); - bind(tetra[1],1,tetra[3],2); - bind(tetra[1],2,tetra[2],1); - bind(tetra[2],2,tetra[3],1); - m_status=eStatus::Valid; - for(;iterationspass = (U1)(++pass); - gjk.getsupport(best->n,*w); - const btScalar wdist=btDot(best->n,w->w)-best->d; - if(wdist>EPA_ACCURACY) - { - for(U j=0;(j<3)&&valid;++j) - { - valid&=expand( pass,w, - best->f[j],best->e[j], - horizon); - } - if(valid&&(horizon.nf>=3)) - { - bind(horizon.cf,1,horizon.ff,2); - remove(m_hull,best); - append(m_stock,best); - best=findbest(); - outer=*best; - } else { m_status=eStatus::InvalidHull;break; } - } else { m_status=eStatus::AccuraryReached;break; } - } else { m_status=eStatus::OutOfVertices;break; } - } - const btVector3 projection=outer.n*outer.d; - m_normal = outer.n; - m_depth = outer.d; - m_result.rank = 3; - m_result.c[0] = outer.c[0]; - m_result.c[1] = outer.c[1]; - m_result.c[2] = outer.c[2]; - m_result.p[0] = btCross( outer.c[1]->w-projection, - outer.c[2]->w-projection).length(); - m_result.p[1] = btCross( outer.c[2]->w-projection, - outer.c[0]->w-projection).length(); - m_result.p[2] = btCross( outer.c[0]->w-projection, - outer.c[1]->w-projection).length(); - const btScalar sum=m_result.p[0]+m_result.p[1]+m_result.p[2]; - m_result.p[0] /= sum; - m_result.p[1] /= sum; - m_result.p[2] /= sum; - return(m_status); - } - } - /* Fallback */ - m_status = eStatus::FallBack; - m_normal = -guess; - const btScalar nl=m_normal.length(); - if(nl>0) - m_normal = m_normal/nl; - else - m_normal = btVector3(1,0,0); - m_depth = 0; - m_result.rank=1; - m_result.c[0]=simplex.c[0]; - m_result.p[0]=1; - return(m_status); - } - bool getedgedist(sFace* face, sSV* a, sSV* b, btScalar& dist) - { - const btVector3 ba = b->w - a->w; - const btVector3 n_ab = btCross(ba, face->n); // Outward facing edge normal direction, on triangle plane - const btScalar a_dot_nab = btDot(a->w, n_ab); // Only care about the sign to determine inside/outside, so not normalization required - - if(a_dot_nab < 0) - { - // Outside of edge a->b - - const btScalar ba_l2 = ba.length2(); - const btScalar a_dot_ba = btDot(a->w, ba); - const btScalar b_dot_ba = btDot(b->w, ba); - - if(a_dot_ba > 0) - { - // Pick distance vertex a - dist = a->w.length(); - } - else if(b_dot_ba < 0) - { - // Pick distance vertex b - dist = b->w.length(); - } - else - { - // Pick distance to edge a->b - const btScalar a_dot_b = btDot(a->w, b->w); - dist = btSqrt(btMax((a->w.length2() * b->w.length2() - a_dot_b * a_dot_b) / ba_l2, (btScalar)0)); - } - - return true; - } - - return false; - } - sFace* newface(sSV* a,sSV* b,sSV* c,bool forced) - { - if(m_stock.root) - { - sFace* face=m_stock.root; - remove(m_stock,face); - append(m_hull,face); - face->pass = 0; - face->c[0] = a; - face->c[1] = b; - face->c[2] = c; - face->n = btCross(b->w-a->w,c->w-a->w); - const btScalar l=face->n.length(); - const bool v=l>EPA_ACCURACY; - - if(v) - { - if(!(getedgedist(face, a, b, face->d) || - getedgedist(face, b, c, face->d) || - getedgedist(face, c, a, face->d))) - { - // Origin projects to the interior of the triangle - // Use distance to triangle plane - face->d = btDot(a->w, face->n) / l; - } - - face->n /= l; - if(forced || (face->d >= -EPA_PLANE_EPS)) - { - return face; - } - else - m_status=eStatus::NonConvex; - } - else - m_status=eStatus::Degenerated; - - remove(m_hull, face); - append(m_stock, face); - return 0; - - } - m_status = m_stock.root ? eStatus::OutOfVertices : eStatus::OutOfFaces; - return 0; - } - sFace* findbest() - { - sFace* minf=m_hull.root; - btScalar mind=minf->d*minf->d; - for(sFace* f=minf->l[1];f;f=f->l[1]) - { - const btScalar sqd=f->d*f->d; - if(sqdpass!=pass) - { - const U e1=i1m3[e]; - if((btDot(f->n,w->w)-f->d)<-EPA_PLANE_EPS) - { - sFace* nf=newface(f->c[e1],f->c[e],w,false); - if(nf) - { - bind(nf,0,f,e); - if(horizon.cf) bind(horizon.cf,1,nf,2); else horizon.ff=nf; - horizon.cf=nf; - ++horizon.nf; - return(true); - } - } - else - { - const U e2=i2m3[e]; - f->pass = (U1)pass; - if( expand(pass,w,f->f[e1],f->e[e1],horizon)&& - expand(pass,w,f->f[e2],f->e[e2],horizon)) - { - remove(m_hull,f); - append(m_stock,f); - return(true); - } - } - } - return(false); - } - + Failed + }; }; - - // - static void Initialize( const btConvexShape* shape0,const btTransform& wtrs0, - const btConvexShape* shape1,const btTransform& wtrs1, - btGjkEpaSolver2::sResults& results, - tShape& shape, - bool withmargins) + /* Fields */ + eStatus::_ m_status; + GJK::sSimplex m_result; + btVector3 m_normal; + btScalar m_depth; + sSV m_sv_store[EPA_MAX_VERTICES]; + sFace m_fc_store[EPA_MAX_FACES]; + U m_nextsv; + sList m_hull; + sList m_stock; + /* Methods */ + EPA() { - /* Results */ - results.witnesses[0] = - results.witnesses[1] = btVector3(0,0,0); - results.status = btGjkEpaSolver2::sResults::Separated; - /* Shape */ - shape.m_shapes[0] = shape0; - shape.m_shapes[1] = shape1; - shape.m_toshape1 = wtrs1.getBasis().transposeTimes(wtrs0.getBasis()); - shape.m_toshape0 = wtrs0.inverseTimes(wtrs1); - shape.EnableMargin(withmargins); + Initialize(); } + static inline void bind(sFace* fa, U ea, sFace* fb, U eb) + { + fa->e[ea] = (U1)eb; + fa->f[ea] = fb; + fb->e[eb] = (U1)ea; + fb->f[eb] = fa; + } + static inline void append(sList& list, sFace* face) + { + face->l[0] = 0; + face->l[1] = list.root; + if (list.root) list.root->l[0] = face; + list.root = face; + ++list.count; + } + static inline void remove(sList& list, sFace* face) + { + if (face->l[1]) face->l[1]->l[0] = face->l[0]; + if (face->l[0]) face->l[0]->l[1] = face->l[1]; + if (face == list.root) list.root = face->l[1]; + --list.count; + } + + void Initialize() + { + m_status = eStatus::Failed; + m_normal = btVector3(0, 0, 0); + m_depth = 0; + m_nextsv = 0; + for (U i = 0; i < EPA_MAX_FACES; ++i) + { + append(m_stock, &m_fc_store[EPA_MAX_FACES - i - 1]); + } + } + eStatus::_ Evaluate(GJK& gjk, const btVector3& guess) + { + GJK::sSimplex& simplex = *gjk.m_simplex; + if ((simplex.rank > 1) && gjk.EncloseOrigin()) + { + /* Clean up */ + while (m_hull.root) + { + sFace* f = m_hull.root; + remove(m_hull, f); + append(m_stock, f); + } + m_status = eStatus::Valid; + m_nextsv = 0; + /* Orient simplex */ + if (gjk.det(simplex.c[0]->w - simplex.c[3]->w, + simplex.c[1]->w - simplex.c[3]->w, + simplex.c[2]->w - simplex.c[3]->w) < 0) + { + btSwap(simplex.c[0], simplex.c[1]); + btSwap(simplex.p[0], simplex.p[1]); + } + /* Build initial hull */ + sFace* tetra[] = {newface(simplex.c[0], simplex.c[1], simplex.c[2], true), + newface(simplex.c[1], simplex.c[0], simplex.c[3], true), + newface(simplex.c[2], simplex.c[1], simplex.c[3], true), + newface(simplex.c[0], simplex.c[2], simplex.c[3], true)}; + if (m_hull.count == 4) + { + sFace* best = findbest(); + sFace outer = *best; + U pass = 0; + U iterations = 0; + bind(tetra[0], 0, tetra[1], 0); + bind(tetra[0], 1, tetra[2], 0); + bind(tetra[0], 2, tetra[3], 0); + bind(tetra[1], 1, tetra[3], 2); + bind(tetra[1], 2, tetra[2], 1); + bind(tetra[2], 2, tetra[3], 1); + m_status = eStatus::Valid; + for (; iterations < EPA_MAX_ITERATIONS; ++iterations) + { + if (m_nextsv < EPA_MAX_VERTICES) + { + sHorizon horizon; + sSV* w = &m_sv_store[m_nextsv++]; + bool valid = true; + best->pass = (U1)(++pass); + gjk.getsupport(best->n, *w); + const btScalar wdist = btDot(best->n, w->w) - best->d; + if (wdist > EPA_ACCURACY) + { + for (U j = 0; (j < 3) && valid; ++j) + { + valid &= expand(pass, w, + best->f[j], best->e[j], + horizon); + } + if (valid && (horizon.nf >= 3)) + { + bind(horizon.cf, 1, horizon.ff, 2); + remove(m_hull, best); + append(m_stock, best); + best = findbest(); + outer = *best; + } + else + { + m_status = eStatus::InvalidHull; + break; + } + } + else + { + m_status = eStatus::AccuraryReached; + break; + } + } + else + { + m_status = eStatus::OutOfVertices; + break; + } + } + const btVector3 projection = outer.n * outer.d; + m_normal = outer.n; + m_depth = outer.d; + m_result.rank = 3; + m_result.c[0] = outer.c[0]; + m_result.c[1] = outer.c[1]; + m_result.c[2] = outer.c[2]; + m_result.p[0] = btCross(outer.c[1]->w - projection, + outer.c[2]->w - projection) + .length(); + m_result.p[1] = btCross(outer.c[2]->w - projection, + outer.c[0]->w - projection) + .length(); + m_result.p[2] = btCross(outer.c[0]->w - projection, + outer.c[1]->w - projection) + .length(); + const btScalar sum = m_result.p[0] + m_result.p[1] + m_result.p[2]; + m_result.p[0] /= sum; + m_result.p[1] /= sum; + m_result.p[2] /= sum; + return (m_status); + } + } + /* Fallback */ + m_status = eStatus::FallBack; + m_normal = -guess; + const btScalar nl = m_normal.length(); + if (nl > 0) + m_normal = m_normal / nl; + else + m_normal = btVector3(1, 0, 0); + m_depth = 0; + m_result.rank = 1; + m_result.c[0] = simplex.c[0]; + m_result.p[0] = 1; + return (m_status); + } + bool getedgedist(sFace* face, sSV* a, sSV* b, btScalar& dist) + { + const btVector3 ba = b->w - a->w; + const btVector3 n_ab = btCross(ba, face->n); // Outward facing edge normal direction, on triangle plane + const btScalar a_dot_nab = btDot(a->w, n_ab); // Only care about the sign to determine inside/outside, so not normalization required + + if (a_dot_nab < 0) + { + // Outside of edge a->b + + const btScalar ba_l2 = ba.length2(); + const btScalar a_dot_ba = btDot(a->w, ba); + const btScalar b_dot_ba = btDot(b->w, ba); + + if (a_dot_ba > 0) + { + // Pick distance vertex a + dist = a->w.length(); + } + else if (b_dot_ba < 0) + { + // Pick distance vertex b + dist = b->w.length(); + } + else + { + // Pick distance to edge a->b + const btScalar a_dot_b = btDot(a->w, b->w); + dist = btSqrt(btMax((a->w.length2() * b->w.length2() - a_dot_b * a_dot_b) / ba_l2, (btScalar)0)); + } + + return true; + } + + return false; + } + sFace* newface(sSV* a, sSV* b, sSV* c, bool forced) + { + if (m_stock.root) + { + sFace* face = m_stock.root; + remove(m_stock, face); + append(m_hull, face); + face->pass = 0; + face->c[0] = a; + face->c[1] = b; + face->c[2] = c; + face->n = btCross(b->w - a->w, c->w - a->w); + const btScalar l = face->n.length(); + const bool v = l > EPA_ACCURACY; + + if (v) + { + if (!(getedgedist(face, a, b, face->d) || + getedgedist(face, b, c, face->d) || + getedgedist(face, c, a, face->d))) + { + // Origin projects to the interior of the triangle + // Use distance to triangle plane + face->d = btDot(a->w, face->n) / l; + } + + face->n /= l; + if (forced || (face->d >= -EPA_PLANE_EPS)) + { + return face; + } + else + m_status = eStatus::NonConvex; + } + else + m_status = eStatus::Degenerated; + + remove(m_hull, face); + append(m_stock, face); + return 0; + } + m_status = m_stock.root ? eStatus::OutOfVertices : eStatus::OutOfFaces; + return 0; + } + sFace* findbest() + { + sFace* minf = m_hull.root; + btScalar mind = minf->d * minf->d; + for (sFace* f = minf->l[1]; f; f = f->l[1]) + { + const btScalar sqd = f->d * f->d; + if (sqd < mind) + { + minf = f; + mind = sqd; + } + } + return (minf); + } + bool expand(U pass, sSV* w, sFace* f, U e, sHorizon& horizon) + { + static const U i1m3[] = {1, 2, 0}; + static const U i2m3[] = {2, 0, 1}; + if (f->pass != pass) + { + const U e1 = i1m3[e]; + if ((btDot(f->n, w->w) - f->d) < -EPA_PLANE_EPS) + { + sFace* nf = newface(f->c[e1], f->c[e], w, false); + if (nf) + { + bind(nf, 0, f, e); + if (horizon.cf) + bind(horizon.cf, 1, nf, 2); + else + horizon.ff = nf; + horizon.cf = nf; + ++horizon.nf; + return (true); + } + } + else + { + const U e2 = i2m3[e]; + f->pass = (U1)pass; + if (expand(pass, w, f->f[e1], f->e[e1], horizon) && + expand(pass, w, f->f[e2], f->e[e2], horizon)) + { + remove(m_hull, f); + append(m_stock, f); + return (true); + } + } + } + return (false); + } +}; + +// +static void Initialize(const btConvexShape* shape0, const btTransform& wtrs0, + const btConvexShape* shape1, const btTransform& wtrs1, + btGjkEpaSolver2::sResults& results, + tShape& shape, + bool withmargins) +{ + /* Results */ + results.witnesses[0] = + results.witnesses[1] = btVector3(0, 0, 0); + results.status = btGjkEpaSolver2::sResults::Separated; + /* Shape */ + shape.m_shapes[0] = shape0; + shape.m_shapes[1] = shape1; + shape.m_toshape1 = wtrs1.getBasis().transposeTimes(wtrs0.getBasis()); + shape.m_toshape0 = wtrs0.inverseTimes(wtrs1); + shape.EnableMargin(withmargins); } +} // namespace gjkepa2_impl + // // Api // -using namespace gjkepa2_impl; +using namespace gjkepa2_impl; // -int btGjkEpaSolver2::StackSizeRequirement() +int btGjkEpaSolver2::StackSizeRequirement() { - return(sizeof(GJK)+sizeof(EPA)); + return (sizeof(GJK) + sizeof(EPA)); } // -bool btGjkEpaSolver2::Distance( const btConvexShape* shape0, - const btTransform& wtrs0, - const btConvexShape* shape1, - const btTransform& wtrs1, - const btVector3& guess, - sResults& results) +bool btGjkEpaSolver2::Distance(const btConvexShape* shape0, + const btTransform& wtrs0, + const btConvexShape* shape1, + const btTransform& wtrs1, + const btVector3& guess, + sResults& results) { - tShape shape; - Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,false); - GJK gjk; - GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,guess); - if(gjk_status==GJK::eStatus::Valid) + tShape shape; + Initialize(shape0, wtrs0, shape1, wtrs1, results, shape, false); + GJK gjk; + GJK::eStatus::_ gjk_status = gjk.Evaluate(shape, guess); + if (gjk_status == GJK::eStatus::Valid) { - btVector3 w0=btVector3(0,0,0); - btVector3 w1=btVector3(0,0,0); - for(U i=0;irank;++i) + btVector3 w0 = btVector3(0, 0, 0); + btVector3 w1 = btVector3(0, 0, 0); + for (U i = 0; i < gjk.m_simplex->rank; ++i) { - const btScalar p=gjk.m_simplex->p[i]; - w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p; - w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p; + const btScalar p = gjk.m_simplex->p[i]; + w0 += shape.Support(gjk.m_simplex->c[i]->d, 0) * p; + w1 += shape.Support(-gjk.m_simplex->c[i]->d, 1) * p; } - results.witnesses[0] = wtrs0*w0; - results.witnesses[1] = wtrs0*w1; - results.normal = w0-w1; - results.distance = results.normal.length(); - results.normal /= results.distance>GJK_MIN_DISTANCE?results.distance:1; - return(true); + results.witnesses[0] = wtrs0 * w0; + results.witnesses[1] = wtrs0 * w1; + results.normal = w0 - w1; + results.distance = results.normal.length(); + results.normal /= results.distance > GJK_MIN_DISTANCE ? results.distance : 1; + return (true); } else { - results.status = gjk_status==GJK::eStatus::Inside? - sResults::Penetrating : - sResults::GJK_Failed ; - return(false); + results.status = gjk_status == GJK::eStatus::Inside ? sResults::Penetrating : sResults::GJK_Failed; + return (false); } } // -bool btGjkEpaSolver2::Penetration( const btConvexShape* shape0, - const btTransform& wtrs0, - const btConvexShape* shape1, - const btTransform& wtrs1, - const btVector3& guess, - sResults& results, - bool usemargins) +bool btGjkEpaSolver2::Penetration(const btConvexShape* shape0, + const btTransform& wtrs0, + const btConvexShape* shape1, + const btTransform& wtrs1, + const btVector3& guess, + sResults& results, + bool usemargins) { - tShape shape; - Initialize(shape0,wtrs0,shape1,wtrs1,results,shape,usemargins); - GJK gjk; - GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,-guess); - switch(gjk_status) + tShape shape; + Initialize(shape0, wtrs0, shape1, wtrs1, results, shape, usemargins); + GJK gjk; + GJK::eStatus::_ gjk_status = gjk.Evaluate(shape, -guess); + switch (gjk_status) { - case GJK::eStatus::Inside: + case GJK::eStatus::Inside: { - EPA epa; - EPA::eStatus::_ epa_status=epa.Evaluate(gjk,-guess); - if(epa_status!=EPA::eStatus::Failed) + EPA epa; + EPA::eStatus::_ epa_status = epa.Evaluate(gjk, -guess); + if (epa_status != EPA::eStatus::Failed) { - btVector3 w0=btVector3(0,0,0); - for(U i=0;id,0)*epa.m_result.p[i]; + w0 += shape.Support(epa.m_result.c[i]->d, 0) * epa.m_result.p[i]; } - results.status = sResults::Penetrating; - results.witnesses[0] = wtrs0*w0; - results.witnesses[1] = wtrs0*(w0-epa.m_normal*epa.m_depth); - results.normal = -epa.m_normal; - results.distance = -epa.m_depth; - return(true); - } else results.status=sResults::EPA_Failed; + results.status = sResults::Penetrating; + results.witnesses[0] = wtrs0 * w0; + results.witnesses[1] = wtrs0 * (w0 - epa.m_normal * epa.m_depth); + results.normal = -epa.m_normal; + results.distance = -epa.m_depth; + return (true); + } + else + results.status = sResults::EPA_Failed; } break; - case GJK::eStatus::Failed: - results.status=sResults::GJK_Failed; - break; + case GJK::eStatus::Failed: + results.status = sResults::GJK_Failed; + break; default: - { - } + { + } } - return(false); + return (false); } #ifndef __SPU__ // -btScalar btGjkEpaSolver2::SignedDistance(const btVector3& position, - btScalar margin, - const btConvexShape* shape0, - const btTransform& wtrs0, - sResults& results) +btScalar btGjkEpaSolver2::SignedDistance(const btVector3& position, + btScalar margin, + const btConvexShape* shape0, + const btTransform& wtrs0, + sResults& results) { - tShape shape; - btSphereShape shape1(margin); - btTransform wtrs1(btQuaternion(0,0,0,1),position); - Initialize(shape0,wtrs0,&shape1,wtrs1,results,shape,false); - GJK gjk; - GJK::eStatus::_ gjk_status=gjk.Evaluate(shape,btVector3(1,1,1)); - if(gjk_status==GJK::eStatus::Valid) + tShape shape; + btSphereShape shape1(margin); + btTransform wtrs1(btQuaternion(0, 0, 0, 1), position); + Initialize(shape0, wtrs0, &shape1, wtrs1, results, shape, false); + GJK gjk; + GJK::eStatus::_ gjk_status = gjk.Evaluate(shape, btVector3(1, 1, 1)); + if (gjk_status == GJK::eStatus::Valid) { - btVector3 w0=btVector3(0,0,0); - btVector3 w1=btVector3(0,0,0); - for(U i=0;irank;++i) + btVector3 w0 = btVector3(0, 0, 0); + btVector3 w1 = btVector3(0, 0, 0); + for (U i = 0; i < gjk.m_simplex->rank; ++i) { - const btScalar p=gjk.m_simplex->p[i]; - w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p; - w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p; + const btScalar p = gjk.m_simplex->p[i]; + w0 += shape.Support(gjk.m_simplex->c[i]->d, 0) * p; + w1 += shape.Support(-gjk.m_simplex->c[i]->d, 1) * p; } - results.witnesses[0] = wtrs0*w0; - results.witnesses[1] = wtrs0*w1; - const btVector3 delta= results.witnesses[1]- - results.witnesses[0]; - const btScalar margin= shape0->getMarginNonVirtual()+ - shape1.getMarginNonVirtual(); - const btScalar length= delta.length(); - results.normal = delta/length; - results.witnesses[0] += results.normal*margin; - return(length-margin); + results.witnesses[0] = wtrs0 * w0; + results.witnesses[1] = wtrs0 * w1; + const btVector3 delta = results.witnesses[1] - + results.witnesses[0]; + const btScalar margin = shape0->getMarginNonVirtual() + + shape1.getMarginNonVirtual(); + const btScalar length = delta.length(); + results.normal = delta / length; + results.witnesses[0] += results.normal * margin; + return (length - margin); } else { - if(gjk_status==GJK::eStatus::Inside) + if (gjk_status == GJK::eStatus::Inside) { - if(Penetration(shape0,wtrs0,&shape1,wtrs1,gjk.m_ray,results)) + if (Penetration(shape0, wtrs0, &shape1, wtrs1, gjk.m_ray, results)) { - const btVector3 delta= results.witnesses[0]- - results.witnesses[1]; - const btScalar length= delta.length(); + const btVector3 delta = results.witnesses[0] - + results.witnesses[1]; + const btScalar length = delta.length(); if (length >= SIMD_EPSILON) - results.normal = delta/length; - return(-length); + results.normal = delta / length; + return (-length); } - } + } } - return(SIMD_INFINITY); + return (SIMD_INFINITY); } // -bool btGjkEpaSolver2::SignedDistance(const btConvexShape* shape0, - const btTransform& wtrs0, - const btConvexShape* shape1, - const btTransform& wtrs1, - const btVector3& guess, - sResults& results) +bool btGjkEpaSolver2::SignedDistance(const btConvexShape* shape0, + const btTransform& wtrs0, + const btConvexShape* shape1, + const btTransform& wtrs1, + const btVector3& guess, + sResults& results) { - if(!Distance(shape0,wtrs0,shape1,wtrs1,guess,results)) - return(Penetration(shape0,wtrs0,shape1,wtrs1,guess,results,false)); + if (!Distance(shape0, wtrs0, shape1, wtrs1, guess, results)) + return (Penetration(shape0, wtrs0, shape1, wtrs1, guess, results, false)); else - return(true); + return (true); } -#endif //__SPU__ +#endif //__SPU__ -/* Symbols cleanup */ +/* Symbols cleanup */ #undef GJK_MAX_ITERATIONS #undef GJK_ACCURACY diff --git a/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.h b/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.h index ac501d5ec..893daea3f 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.h +++ b/src/BulletCollision/NarrowPhaseCollision/btGjkEpa2.h @@ -28,48 +28,46 @@ GJK-EPA collision solver by Nathanael Presson, 2008 #include "BulletCollision/CollisionShapes/btConvexShape.h" ///btGjkEpaSolver contributed under zlib by Nathanael Presson -struct btGjkEpaSolver2 +struct btGjkEpaSolver2 { -struct sResults + struct sResults { - enum eStatus + enum eStatus { - Separated, /* Shapes doesnt penetrate */ - Penetrating, /* Shapes are penetrating */ - GJK_Failed, /* GJK phase fail, no big issue, shapes are probably just 'touching' */ - EPA_Failed /* EPA phase fail, bigger problem, need to save parameters, and debug */ - } status; - btVector3 witnesses[2]; - btVector3 normal; - btScalar distance; + Separated, /* Shapes doesnt penetrate */ + Penetrating, /* Shapes are penetrating */ + GJK_Failed, /* GJK phase fail, no big issue, shapes are probably just 'touching' */ + EPA_Failed /* EPA phase fail, bigger problem, need to save parameters, and debug */ + } status; + btVector3 witnesses[2]; + btVector3 normal; + btScalar distance; }; -static int StackSizeRequirement(); + static int StackSizeRequirement(); -static bool Distance( const btConvexShape* shape0,const btTransform& wtrs0, - const btConvexShape* shape1,const btTransform& wtrs1, - const btVector3& guess, - sResults& results); + static bool Distance(const btConvexShape* shape0, const btTransform& wtrs0, + const btConvexShape* shape1, const btTransform& wtrs1, + const btVector3& guess, + sResults& results); -static bool Penetration(const btConvexShape* shape0,const btTransform& wtrs0, - const btConvexShape* shape1,const btTransform& wtrs1, + static bool Penetration(const btConvexShape* shape0, const btTransform& wtrs0, + const btConvexShape* shape1, const btTransform& wtrs1, const btVector3& guess, sResults& results, - bool usemargins=true); + bool usemargins = true); #ifndef __SPU__ -static btScalar SignedDistance( const btVector3& position, - btScalar margin, - const btConvexShape* shape, - const btTransform& wtrs, - sResults& results); - -static bool SignedDistance( const btConvexShape* shape0,const btTransform& wtrs0, - const btConvexShape* shape1,const btTransform& wtrs1, - const btVector3& guess, - sResults& results); -#endif //__SPU__ + static btScalar SignedDistance(const btVector3& position, + btScalar margin, + const btConvexShape* shape, + const btTransform& wtrs, + sResults& results); + static bool SignedDistance(const btConvexShape* shape0, const btTransform& wtrs0, + const btConvexShape* shape1, const btTransform& wtrs1, + const btVector3& guess, + sResults& results); +#endif //__SPU__ }; -#endif //BT_GJK_EPA2_H - +#endif //BT_GJK_EPA2_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btGjkEpa3.h b/src/BulletCollision/NarrowPhaseCollision/btGjkEpa3.h index 878949af9..5389d05f5 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btGjkEpa3.h +++ b/src/BulletCollision/NarrowPhaseCollision/btGjkEpa3.h @@ -29,915 +29,946 @@ Improvements and refactoring by Erwin Coumans, 2008-2014 #include "LinearMath/btTransform.h" #include "btGjkCollisionDescription.h" - - -struct btGjkEpaSolver3 +struct btGjkEpaSolver3 { -struct sResults + struct sResults { - enum eStatus + enum eStatus { - Separated, /* Shapes doesnt penetrate */ - Penetrating, /* Shapes are penetrating */ - GJK_Failed, /* GJK phase fail, no big issue, shapes are probably just 'touching' */ - EPA_Failed /* EPA phase fail, bigger problem, need to save parameters, and debug */ - } status; - btVector3 witnesses[2]; - btVector3 normal; - btScalar distance; + Separated, /* Shapes doesnt penetrate */ + Penetrating, /* Shapes are penetrating */ + GJK_Failed, /* GJK phase fail, no big issue, shapes are probably just 'touching' */ + EPA_Failed /* EPA phase fail, bigger problem, need to save parameters, and debug */ + } status; + btVector3 witnesses[2]; + btVector3 normal; + btScalar distance; }; - - }; - - -#if defined(DEBUG) || defined (_DEBUG) -#include //for debug printf +#if defined(DEBUG) || defined(_DEBUG) +#include //for debug printf #ifdef __SPU__ #include #define printf spu_printf -#endif //__SPU__ +#endif //__SPU__ #endif +// Config - - // Config - - /* GJK */ -#define GJK_MAX_ITERATIONS 128 -#define GJK_ACCURARY ((btScalar)0.0001) -#define GJK_MIN_DISTANCE ((btScalar)0.0001) -#define GJK_DUPLICATED_EPS ((btScalar)0.0001) -#define GJK_SIMPLEX2_EPS ((btScalar)0.0) -#define GJK_SIMPLEX3_EPS ((btScalar)0.0) -#define GJK_SIMPLEX4_EPS ((btScalar)0.0) - - /* EPA */ -#define EPA_MAX_VERTICES 64 -#define EPA_MAX_FACES (EPA_MAX_VERTICES*2) -#define EPA_MAX_ITERATIONS 255 -#define EPA_ACCURACY ((btScalar)0.0001) -#define EPA_FALLBACK (10*EPA_ACCURACY) -#define EPA_PLANE_EPS ((btScalar)0.00001) -#define EPA_INSIDE_EPS ((btScalar)0.01) - - - // Shorthands - typedef unsigned int U; - typedef unsigned char U1; - - // MinkowskiDiff - template - struct MinkowskiDiff - { - const btConvexTemplate* m_convexAPtr; - const btConvexTemplate* m_convexBPtr; - - btMatrix3x3 m_toshape1; - btTransform m_toshape0; - - bool m_enableMargin; - - - MinkowskiDiff(const btConvexTemplate& a, const btConvexTemplate& b) - :m_convexAPtr(&a), - m_convexBPtr(&b) - { - } - - void EnableMargin(bool enable) - { - m_enableMargin = enable; - } - inline btVector3 Support0(const btVector3& d) const - { - return m_convexAPtr->getLocalSupportWithMargin(d); - } - inline btVector3 Support1(const btVector3& d) const - { - return m_toshape0*m_convexBPtr->getLocalSupportWithMargin(m_toshape1*d); - } - - - inline btVector3 Support(const btVector3& d) const - { - return(Support0(d)-Support1(-d)); - } - btVector3 Support(const btVector3& d,U index) const - { - if(index) - return(Support1(d)); - else - return(Support0(d)); - } - }; - -enum eGjkStatus -{ - eGjkValid, - eGjkInside, - eGjkFailed -}; +/* GJK */ +#define GJK_MAX_ITERATIONS 128 +#define GJK_ACCURARY ((btScalar)0.0001) +#define GJK_MIN_DISTANCE ((btScalar)0.0001) +#define GJK_DUPLICATED_EPS ((btScalar)0.0001) +#define GJK_SIMPLEX2_EPS ((btScalar)0.0) +#define GJK_SIMPLEX3_EPS ((btScalar)0.0) +#define GJK_SIMPLEX4_EPS ((btScalar)0.0) - // GJK - template - struct GJK - { - /* Types */ - struct sSV - { - btVector3 d,w; - }; - struct sSimplex - { - sSV* c[4]; - btScalar p[4]; - U rank; - }; - - /* Fields */ - - MinkowskiDiff m_shape; - btVector3 m_ray; - btScalar m_distance; - sSimplex m_simplices[2]; - sSV m_store[4]; - sSV* m_free[4]; - U m_nfree; - U m_current; - sSimplex* m_simplex; - eGjkStatus m_status; - /* Methods */ - - GJK(const btConvexTemplate& a, const btConvexTemplate& b) - :m_shape(a,b) - { - Initialize(); - } - void Initialize() - { - m_ray = btVector3(0,0,0); - m_nfree = 0; - m_status = eGjkFailed; - m_current = 0; - m_distance = 0; - } - eGjkStatus Evaluate(const MinkowskiDiff& shapearg,const btVector3& guess) - { - U iterations=0; - btScalar sqdist=0; - btScalar alpha=0; - btVector3 lastw[4]; - U clastw=0; - /* Initialize solver */ - m_free[0] = &m_store[0]; - m_free[1] = &m_store[1]; - m_free[2] = &m_store[2]; - m_free[3] = &m_store[3]; - m_nfree = 4; - m_current = 0; - m_status = eGjkValid; - m_shape = shapearg; - m_distance = 0; - /* Initialize simplex */ - m_simplices[0].rank = 0; - m_ray = guess; - const btScalar sqrl= m_ray.length2(); - appendvertice(m_simplices[0],sqrl>0?-m_ray:btVector3(1,0,0)); - m_simplices[0].p[0] = 1; - m_ray = m_simplices[0].c[0]->w; - sqdist = sqrl; - lastw[0] = - lastw[1] = - lastw[2] = - lastw[3] = m_ray; - /* Loop */ - do { - const U next=1-m_current; - sSimplex& cs=m_simplices[m_current]; - sSimplex& ns=m_simplices[next]; - /* Check zero */ - const btScalar rl=m_ray.length(); - if(rlw; - bool found=false; - for(U i=0;i<4;++i) - { - if((w-lastw[i]).length2()w, - cs.c[1]->w, - weights,mask);break; - case 3: sqdist=projectorigin( cs.c[0]->w, - cs.c[1]->w, - cs.c[2]->w, - weights,mask);break; - case 4: sqdist=projectorigin( cs.c[0]->w, - cs.c[1]->w, - cs.c[2]->w, - cs.c[3]->w, - weights,mask);break; - } - if(sqdist>=0) - {/* Valid */ - ns.rank = 0; - m_ray = btVector3(0,0,0); - m_current = next; - for(U i=0,ni=cs.rank;iw*weights[i]; - } - else - { - m_free[m_nfree++] = cs.c[i]; - } - } - if(mask==15) m_status=eGjkInside; - } - else - {/* Return old simplex */ - removevertice(m_simplices[m_current]); - break; - } - m_status=((++iterations)rank) - { - case 1: - { - for(U i=0;i<3;++i) - { - btVector3 axis=btVector3(0,0,0); - axis[i]=1; - appendvertice(*m_simplex, axis); - if(EncloseOrigin()) return(true); - removevertice(*m_simplex); - appendvertice(*m_simplex,-axis); - if(EncloseOrigin()) return(true); - removevertice(*m_simplex); - } - } - break; - case 2: - { - const btVector3 d=m_simplex->c[1]->w-m_simplex->c[0]->w; - for(U i=0;i<3;++i) - { - btVector3 axis=btVector3(0,0,0); - axis[i]=1; - const btVector3 p=btCross(d,axis); - if(p.length2()>0) - { - appendvertice(*m_simplex, p); - if(EncloseOrigin()) return(true); - removevertice(*m_simplex); - appendvertice(*m_simplex,-p); - if(EncloseOrigin()) return(true); - removevertice(*m_simplex); - } - } - } - break; - case 3: - { - const btVector3 n=btCross(m_simplex->c[1]->w-m_simplex->c[0]->w, - m_simplex->c[2]->w-m_simplex->c[0]->w); - if(n.length2()>0) - { - appendvertice(*m_simplex,n); - if(EncloseOrigin()) return(true); - removevertice(*m_simplex); - appendvertice(*m_simplex,-n); - if(EncloseOrigin()) return(true); - removevertice(*m_simplex); - } - } - break; - case 4: - { - if(btFabs(det( m_simplex->c[0]->w-m_simplex->c[3]->w, - m_simplex->c[1]->w-m_simplex->c[3]->w, - m_simplex->c[2]->w-m_simplex->c[3]->w))>0) - return(true); - } - break; - } - return(false); - } - /* Internals */ - void getsupport(const btVector3& d,sSV& sv) const - { - sv.d = d/d.length(); - sv.w = m_shape.Support(sv.d); - } - void removevertice(sSimplex& simplex) - { - m_free[m_nfree++]=simplex.c[--simplex.rank]; - } - void appendvertice(sSimplex& simplex,const btVector3& v) - { - simplex.p[simplex.rank]=0; - simplex.c[simplex.rank]=m_free[--m_nfree]; - getsupport(v,*simplex.c[simplex.rank++]); - } - static btScalar det(const btVector3& a,const btVector3& b,const btVector3& c) - { - return( a.y()*b.z()*c.x()+a.z()*b.x()*c.y()- - a.x()*b.z()*c.y()-a.y()*b.x()*c.z()+ - a.x()*b.y()*c.z()-a.z()*b.y()*c.x()); - } - static btScalar projectorigin( const btVector3& a, - const btVector3& b, - btScalar* w,U& m) - { - const btVector3 d=b-a; - const btScalar l=d.length2(); - if(l>GJK_SIMPLEX2_EPS) - { - const btScalar t(l>0?-btDot(a,d)/l:0); - if(t>=1) { w[0]=0;w[1]=1;m=2;return(b.length2()); } - else if(t<=0) { w[0]=1;w[1]=0;m=1;return(a.length2()); } - else { w[0]=1-(w[1]=t);m=3;return((a+d*t).length2()); } - } - return(-1); - } - static btScalar projectorigin( const btVector3& a, - const btVector3& b, - const btVector3& c, - btScalar* w,U& m) - { - static const U imd3[]={1,2,0}; - const btVector3* vt[]={&a,&b,&c}; - const btVector3 dl[]={a-b,b-c,c-a}; - const btVector3 n=btCross(dl[0],dl[1]); - const btScalar l=n.length2(); - if(l>GJK_SIMPLEX3_EPS) - { - btScalar mindist=-1; - btScalar subw[2]={0.f,0.f}; - U subm(0); - for(U i=0;i<3;++i) - { - if(btDot(*vt[i],btCross(dl[i],n))>0) - { - const U j=imd3[i]; - const btScalar subd(projectorigin(*vt[i],*vt[j],subw,subm)); - if((mindist<0)||(subd(((subm&1)?1<GJK_SIMPLEX4_EPS)) - { - btScalar mindist=-1; - btScalar subw[3]={0.f,0.f,0.f}; - U subm(0); - for(U i=0;i<3;++i) - { - const U j=imd3[i]; - const btScalar s=vl*btDot(d,btCross(dl[i],dl[j])); - if(s>0) - { - const btScalar subd=projectorigin(*vt[i],*vt[j],d,subw,subm); - if((mindist<0)||(subd((subm&1?1< - struct EPA - { - /* Types */ - - struct sFace - { - btVector3 n; - btScalar d; - typename GJK::sSV* c[3]; - sFace* f[3]; - sFace* l[2]; - U1 e[3]; - U1 pass; - }; - struct sList - { - sFace* root; - U count; - sList() : root(0),count(0) {} - }; - struct sHorizon - { - sFace* cf; - sFace* ff; - U nf; - sHorizon() : cf(0),ff(0),nf(0) {} - }; - - /* Fields */ - eEpaStatus m_status; - typename GJK::sSimplex m_result; - btVector3 m_normal; - btScalar m_depth; - typename GJK::sSV m_sv_store[EPA_MAX_VERTICES]; - sFace m_fc_store[EPA_MAX_FACES]; - U m_nextsv; - sList m_hull; - sList m_stock; - /* Methods */ - EPA() - { - Initialize(); - } - - - static inline void bind(sFace* fa,U ea,sFace* fb,U eb) - { - fa->e[ea]=(U1)eb;fa->f[ea]=fb; - fb->e[eb]=(U1)ea;fb->f[eb]=fa; - } - static inline void append(sList& list,sFace* face) - { - face->l[0] = 0; - face->l[1] = list.root; - if(list.root) list.root->l[0]=face; - list.root = face; - ++list.count; - } - static inline void remove(sList& list,sFace* face) - { - if(face->l[1]) face->l[1]->l[0]=face->l[0]; - if(face->l[0]) face->l[0]->l[1]=face->l[1]; - if(face==list.root) list.root=face->l[1]; - --list.count; - } - - - void Initialize() - { - m_status = eEpaFailed; - m_normal = btVector3(0,0,0); - m_depth = 0; - m_nextsv = 0; - for(U i=0;i& gjk,const btVector3& guess) - { - typename GJK::sSimplex& simplex=*gjk.m_simplex; - if((simplex.rank>1)&&gjk.EncloseOrigin()) - { - - /* Clean up */ - while(m_hull.root) - { - sFace* f = m_hull.root; - remove(m_hull,f); - append(m_stock,f); - } - m_status = eEpaValid; - m_nextsv = 0; - /* Orient simplex */ - if(gjk.det( simplex.c[0]->w-simplex.c[3]->w, - simplex.c[1]->w-simplex.c[3]->w, - simplex.c[2]->w-simplex.c[3]->w)<0) - { - btSwap(simplex.c[0],simplex.c[1]); - btSwap(simplex.p[0],simplex.p[1]); - } - /* Build initial hull */ - sFace* tetra[]={newface(simplex.c[0],simplex.c[1],simplex.c[2],true), - newface(simplex.c[1],simplex.c[0],simplex.c[3],true), - newface(simplex.c[2],simplex.c[1],simplex.c[3],true), - newface(simplex.c[0],simplex.c[2],simplex.c[3],true)}; - if(m_hull.count==4) - { - sFace* best=findbest(); - sFace outer=*best; - U pass=0; - U iterations=0; - bind(tetra[0],0,tetra[1],0); - bind(tetra[0],1,tetra[2],0); - bind(tetra[0],2,tetra[3],0); - bind(tetra[1],1,tetra[3],2); - bind(tetra[1],2,tetra[2],1); - bind(tetra[2],2,tetra[3],1); - m_status=eEpaValid; - for(;iterations::sSV* w=&m_sv_store[m_nextsv++]; - bool valid=true; - best->pass = (U1)(++pass); - gjk.getsupport(best->n,*w); - const btScalar wdist=btDot(best->n,w->w)-best->d; - if(wdist>EPA_ACCURACY) - { - for(U j=0;(j<3)&&valid;++j) - { - valid&=expand( pass,w, - best->f[j],best->e[j], - horizon); - } - if(valid&&(horizon.nf>=3)) - { - bind(horizon.cf,1,horizon.ff,2); - remove(m_hull,best); - append(m_stock,best); - best=findbest(); - outer=*best; - } else { m_status=eEpaInvalidHull;break; } - } else { m_status=eEpaAccuraryReached;break; } - } else { m_status=eEpaOutOfVertices;break; } - } - const btVector3 projection=outer.n*outer.d; - m_normal = outer.n; - m_depth = outer.d; - m_result.rank = 3; - m_result.c[0] = outer.c[0]; - m_result.c[1] = outer.c[1]; - m_result.c[2] = outer.c[2]; - m_result.p[0] = btCross( outer.c[1]->w-projection, - outer.c[2]->w-projection).length(); - m_result.p[1] = btCross( outer.c[2]->w-projection, - outer.c[0]->w-projection).length(); - m_result.p[2] = btCross( outer.c[0]->w-projection, - outer.c[1]->w-projection).length(); - const btScalar sum=m_result.p[0]+m_result.p[1]+m_result.p[2]; - m_result.p[0] /= sum; - m_result.p[1] /= sum; - m_result.p[2] /= sum; - return(m_status); - } - } - /* Fallback */ - m_status = eEpaFallBack; - m_normal = -guess; - const btScalar nl=m_normal.length(); - if(nl>0) - m_normal = m_normal/nl; - else - m_normal = btVector3(1,0,0); - m_depth = 0; - m_result.rank=1; - m_result.c[0]=simplex.c[0]; - m_result.p[0]=1; - return(m_status); - } - bool getedgedist(sFace* face, typename GJK::sSV* a, typename GJK::sSV* b, btScalar& dist) - { - const btVector3 ba = b->w - a->w; - const btVector3 n_ab = btCross(ba, face->n); // Outward facing edge normal direction, on triangle plane - const btScalar a_dot_nab = btDot(a->w, n_ab); // Only care about the sign to determine inside/outside, so not normalization required - - if(a_dot_nab < 0) - { - // Outside of edge a->b - - const btScalar ba_l2 = ba.length2(); - const btScalar a_dot_ba = btDot(a->w, ba); - const btScalar b_dot_ba = btDot(b->w, ba); - - if(a_dot_ba > 0) - { - // Pick distance vertex a - dist = a->w.length(); - } - else if(b_dot_ba < 0) - { - // Pick distance vertex b - dist = b->w.length(); - } - else - { - // Pick distance to edge a->b - const btScalar a_dot_b = btDot(a->w, b->w); - dist = btSqrt(btMax((a->w.length2() * b->w.length2() - a_dot_b * a_dot_b) / ba_l2, (btScalar)0)); - } - - return true; - } - - return false; - } - sFace* newface(typename GJK::sSV* a,typename GJK::sSV* b,typename GJK::sSV* c,bool forced) - { - if(m_stock.root) - { - sFace* face=m_stock.root; - remove(m_stock,face); - append(m_hull,face); - face->pass = 0; - face->c[0] = a; - face->c[1] = b; - face->c[2] = c; - face->n = btCross(b->w-a->w,c->w-a->w); - const btScalar l=face->n.length(); - const bool v=l>EPA_ACCURACY; - - if(v) - { - if(!(getedgedist(face, a, b, face->d) || - getedgedist(face, b, c, face->d) || - getedgedist(face, c, a, face->d))) - { - // Origin projects to the interior of the triangle - // Use distance to triangle plane - face->d = btDot(a->w, face->n) / l; - } - - face->n /= l; - if(forced || (face->d >= -EPA_PLANE_EPS)) - { - return face; - } - else - m_status=eEpaNonConvex; - } - else - m_status=eEpaDegenerated; - - remove(m_hull, face); - append(m_stock, face); - return 0; - - } - m_status = m_stock.root ? eEpaOutOfVertices : eEpaOutOfFaces; - return 0; - } - sFace* findbest() - { - sFace* minf=m_hull.root; - btScalar mind=minf->d*minf->d; - for(sFace* f=minf->l[1];f;f=f->l[1]) - { - const btScalar sqd=f->d*f->d; - if(sqd::sSV* w,sFace* f,U e,sHorizon& horizon) - { - static const U i1m3[]={1,2,0}; - static const U i2m3[]={2,0,1}; - if(f->pass!=pass) - { - const U e1=i1m3[e]; - if((btDot(f->n,w->w)-f->d)<-EPA_PLANE_EPS) - { - sFace* nf=newface(f->c[e1],f->c[e],w,false); - if(nf) - { - bind(nf,0,f,e); - if(horizon.cf) bind(horizon.cf,1,nf,2); else horizon.ff=nf; - horizon.cf=nf; - ++horizon.nf; - return(true); - } - } - else - { - const U e2=i2m3[e]; - f->pass = (U1)pass; - if( expand(pass,w,f->f[e1],f->e[e1],horizon)&& - expand(pass,w,f->f[e2],f->e[e2],horizon)) - { - remove(m_hull,f); - append(m_stock,f); - return(true); - } - } - } - return(false); - } - - }; - - template - static void Initialize( const btConvexTemplate& a, const btConvexTemplate& b, - btGjkEpaSolver3::sResults& results, - MinkowskiDiff& shape) - { - /* Results */ - results.witnesses[0] = - results.witnesses[1] = btVector3(0,0,0); - results.status = btGjkEpaSolver3::sResults::Separated; - /* Shape */ - - shape.m_toshape1 = b.getWorldTransform().getBasis().transposeTimes(a.getWorldTransform().getBasis()); - shape.m_toshape0 = a.getWorldTransform().inverseTimes(b.getWorldTransform()); - - } - +struct MinkowskiDiff +{ + const btConvexTemplate* m_convexAPtr; + const btConvexTemplate* m_convexBPtr; + + btMatrix3x3 m_toshape1; + btTransform m_toshape0; + + bool m_enableMargin; + + MinkowskiDiff(const btConvexTemplate& a, const btConvexTemplate& b) + : m_convexAPtr(&a), + m_convexBPtr(&b) + { + } + + void EnableMargin(bool enable) + { + m_enableMargin = enable; + } + inline btVector3 Support0(const btVector3& d) const + { + return m_convexAPtr->getLocalSupportWithMargin(d); + } + inline btVector3 Support1(const btVector3& d) const + { + return m_toshape0 * m_convexBPtr->getLocalSupportWithMargin(m_toshape1 * d); + } + + inline btVector3 Support(const btVector3& d) const + { + return (Support0(d) - Support1(-d)); + } + btVector3 Support(const btVector3& d, U index) const + { + if (index) + return (Support1(d)); + else + return (Support0(d)); + } +}; + +enum eGjkStatus +{ + eGjkValid, + eGjkInside, + eGjkFailed +}; + +// GJK +template +struct GJK +{ + /* Types */ + struct sSV + { + btVector3 d, w; + }; + struct sSimplex + { + sSV* c[4]; + btScalar p[4]; + U rank; + }; + + /* Fields */ + + MinkowskiDiff m_shape; + btVector3 m_ray; + btScalar m_distance; + sSimplex m_simplices[2]; + sSV m_store[4]; + sSV* m_free[4]; + U m_nfree; + U m_current; + sSimplex* m_simplex; + eGjkStatus m_status; + /* Methods */ + + GJK(const btConvexTemplate& a, const btConvexTemplate& b) + : m_shape(a, b) + { + Initialize(); + } + void Initialize() + { + m_ray = btVector3(0, 0, 0); + m_nfree = 0; + m_status = eGjkFailed; + m_current = 0; + m_distance = 0; + } + eGjkStatus Evaluate(const MinkowskiDiff& shapearg, const btVector3& guess) + { + U iterations = 0; + btScalar sqdist = 0; + btScalar alpha = 0; + btVector3 lastw[4]; + U clastw = 0; + /* Initialize solver */ + m_free[0] = &m_store[0]; + m_free[1] = &m_store[1]; + m_free[2] = &m_store[2]; + m_free[3] = &m_store[3]; + m_nfree = 4; + m_current = 0; + m_status = eGjkValid; + m_shape = shapearg; + m_distance = 0; + /* Initialize simplex */ + m_simplices[0].rank = 0; + m_ray = guess; + const btScalar sqrl = m_ray.length2(); + appendvertice(m_simplices[0], sqrl > 0 ? -m_ray : btVector3(1, 0, 0)); + m_simplices[0].p[0] = 1; + m_ray = m_simplices[0].c[0]->w; + sqdist = sqrl; + lastw[0] = + lastw[1] = + lastw[2] = + lastw[3] = m_ray; + /* Loop */ + do + { + const U next = 1 - m_current; + sSimplex& cs = m_simplices[m_current]; + sSimplex& ns = m_simplices[next]; + /* Check zero */ + const btScalar rl = m_ray.length(); + if (rl < GJK_MIN_DISTANCE) + { /* Touching or inside */ + m_status = eGjkInside; + break; + } + /* Append new vertice in -'v' direction */ + appendvertice(cs, -m_ray); + const btVector3& w = cs.c[cs.rank - 1]->w; + bool found = false; + for (U i = 0; i < 4; ++i) + { + if ((w - lastw[i]).length2() < GJK_DUPLICATED_EPS) + { + found = true; + break; + } + } + if (found) + { /* Return old simplex */ + removevertice(m_simplices[m_current]); + break; + } + else + { /* Update lastw */ + lastw[clastw = (clastw + 1) & 3] = w; + } + /* Check for termination */ + const btScalar omega = btDot(m_ray, w) / rl; + alpha = btMax(omega, alpha); + if (((rl - alpha) - (GJK_ACCURARY * rl)) <= 0) + { /* Return old simplex */ + removevertice(m_simplices[m_current]); + break; + } + /* Reduce simplex */ + btScalar weights[4]; + U mask = 0; + switch (cs.rank) + { + case 2: + sqdist = projectorigin(cs.c[0]->w, + cs.c[1]->w, + weights, mask); + break; + case 3: + sqdist = projectorigin(cs.c[0]->w, + cs.c[1]->w, + cs.c[2]->w, + weights, mask); + break; + case 4: + sqdist = projectorigin(cs.c[0]->w, + cs.c[1]->w, + cs.c[2]->w, + cs.c[3]->w, + weights, mask); + break; + } + if (sqdist >= 0) + { /* Valid */ + ns.rank = 0; + m_ray = btVector3(0, 0, 0); + m_current = next; + for (U i = 0, ni = cs.rank; i < ni; ++i) + { + if (mask & (1 << i)) + { + ns.c[ns.rank] = cs.c[i]; + ns.p[ns.rank++] = weights[i]; + m_ray += cs.c[i]->w * weights[i]; + } + else + { + m_free[m_nfree++] = cs.c[i]; + } + } + if (mask == 15) m_status = eGjkInside; + } + else + { /* Return old simplex */ + removevertice(m_simplices[m_current]); + break; + } + m_status = ((++iterations) < GJK_MAX_ITERATIONS) ? m_status : eGjkFailed; + } while (m_status == eGjkValid); + m_simplex = &m_simplices[m_current]; + switch (m_status) + { + case eGjkValid: + m_distance = m_ray.length(); + break; + case eGjkInside: + m_distance = 0; + break; + default: + { + } + } + return (m_status); + } + bool EncloseOrigin() + { + switch (m_simplex->rank) + { + case 1: + { + for (U i = 0; i < 3; ++i) + { + btVector3 axis = btVector3(0, 0, 0); + axis[i] = 1; + appendvertice(*m_simplex, axis); + if (EncloseOrigin()) return (true); + removevertice(*m_simplex); + appendvertice(*m_simplex, -axis); + if (EncloseOrigin()) return (true); + removevertice(*m_simplex); + } + } + break; + case 2: + { + const btVector3 d = m_simplex->c[1]->w - m_simplex->c[0]->w; + for (U i = 0; i < 3; ++i) + { + btVector3 axis = btVector3(0, 0, 0); + axis[i] = 1; + const btVector3 p = btCross(d, axis); + if (p.length2() > 0) + { + appendvertice(*m_simplex, p); + if (EncloseOrigin()) return (true); + removevertice(*m_simplex); + appendvertice(*m_simplex, -p); + if (EncloseOrigin()) return (true); + removevertice(*m_simplex); + } + } + } + break; + case 3: + { + const btVector3 n = btCross(m_simplex->c[1]->w - m_simplex->c[0]->w, + m_simplex->c[2]->w - m_simplex->c[0]->w); + if (n.length2() > 0) + { + appendvertice(*m_simplex, n); + if (EncloseOrigin()) return (true); + removevertice(*m_simplex); + appendvertice(*m_simplex, -n); + if (EncloseOrigin()) return (true); + removevertice(*m_simplex); + } + } + break; + case 4: + { + if (btFabs(det(m_simplex->c[0]->w - m_simplex->c[3]->w, + m_simplex->c[1]->w - m_simplex->c[3]->w, + m_simplex->c[2]->w - m_simplex->c[3]->w)) > 0) + return (true); + } + break; + } + return (false); + } + /* Internals */ + void getsupport(const btVector3& d, sSV& sv) const + { + sv.d = d / d.length(); + sv.w = m_shape.Support(sv.d); + } + void removevertice(sSimplex& simplex) + { + m_free[m_nfree++] = simplex.c[--simplex.rank]; + } + void appendvertice(sSimplex& simplex, const btVector3& v) + { + simplex.p[simplex.rank] = 0; + simplex.c[simplex.rank] = m_free[--m_nfree]; + getsupport(v, *simplex.c[simplex.rank++]); + } + static btScalar det(const btVector3& a, const btVector3& b, const btVector3& c) + { + return (a.y() * b.z() * c.x() + a.z() * b.x() * c.y() - + a.x() * b.z() * c.y() - a.y() * b.x() * c.z() + + a.x() * b.y() * c.z() - a.z() * b.y() * c.x()); + } + static btScalar projectorigin(const btVector3& a, + const btVector3& b, + btScalar* w, U& m) + { + const btVector3 d = b - a; + const btScalar l = d.length2(); + if (l > GJK_SIMPLEX2_EPS) + { + const btScalar t(l > 0 ? -btDot(a, d) / l : 0); + if (t >= 1) + { + w[0] = 0; + w[1] = 1; + m = 2; + return (b.length2()); + } + else if (t <= 0) + { + w[0] = 1; + w[1] = 0; + m = 1; + return (a.length2()); + } + else + { + w[0] = 1 - (w[1] = t); + m = 3; + return ((a + d * t).length2()); + } + } + return (-1); + } + static btScalar projectorigin(const btVector3& a, + const btVector3& b, + const btVector3& c, + btScalar* w, U& m) + { + static const U imd3[] = {1, 2, 0}; + const btVector3* vt[] = {&a, &b, &c}; + const btVector3 dl[] = {a - b, b - c, c - a}; + const btVector3 n = btCross(dl[0], dl[1]); + const btScalar l = n.length2(); + if (l > GJK_SIMPLEX3_EPS) + { + btScalar mindist = -1; + btScalar subw[2] = {0.f, 0.f}; + U subm(0); + for (U i = 0; i < 3; ++i) + { + if (btDot(*vt[i], btCross(dl[i], n)) > 0) + { + const U j = imd3[i]; + const btScalar subd(projectorigin(*vt[i], *vt[j], subw, subm)); + if ((mindist < 0) || (subd < mindist)) + { + mindist = subd; + m = static_cast(((subm & 1) ? 1 << i : 0) + ((subm & 2) ? 1 << j : 0)); + w[i] = subw[0]; + w[j] = subw[1]; + w[imd3[j]] = 0; + } + } + } + if (mindist < 0) + { + const btScalar d = btDot(a, n); + const btScalar s = btSqrt(l); + const btVector3 p = n * (d / l); + mindist = p.length2(); + m = 7; + w[0] = (btCross(dl[1], b - p)).length() / s; + w[1] = (btCross(dl[2], c - p)).length() / s; + w[2] = 1 - (w[0] + w[1]); + } + return (mindist); + } + return (-1); + } + static btScalar projectorigin(const btVector3& a, + const btVector3& b, + const btVector3& c, + const btVector3& d, + btScalar* w, U& m) + { + static const U imd3[] = {1, 2, 0}; + const btVector3* vt[] = {&a, &b, &c, &d}; + const btVector3 dl[] = {a - d, b - d, c - d}; + const btScalar vl = det(dl[0], dl[1], dl[2]); + const bool ng = (vl * btDot(a, btCross(b - c, a - b))) <= 0; + if (ng && (btFabs(vl) > GJK_SIMPLEX4_EPS)) + { + btScalar mindist = -1; + btScalar subw[3] = {0.f, 0.f, 0.f}; + U subm(0); + for (U i = 0; i < 3; ++i) + { + const U j = imd3[i]; + const btScalar s = vl * btDot(d, btCross(dl[i], dl[j])); + if (s > 0) + { + const btScalar subd = projectorigin(*vt[i], *vt[j], d, subw, subm); + if ((mindist < 0) || (subd < mindist)) + { + mindist = subd; + m = static_cast((subm & 1 ? 1 << i : 0) + + (subm & 2 ? 1 << j : 0) + + (subm & 4 ? 8 : 0)); + w[i] = subw[0]; + w[j] = subw[1]; + w[imd3[j]] = 0; + w[3] = subw[2]; + } + } + } + if (mindist < 0) + { + mindist = 0; + m = 15; + w[0] = det(c, b, d) / vl; + w[1] = det(a, c, d) / vl; + w[2] = det(b, a, d) / vl; + w[3] = 1 - (w[0] + w[1] + w[2]); + } + return (mindist); + } + return (-1); + } +}; + +enum eEpaStatus +{ + eEpaValid, + eEpaTouching, + eEpaDegenerated, + eEpaNonConvex, + eEpaInvalidHull, + eEpaOutOfFaces, + eEpaOutOfVertices, + eEpaAccuraryReached, + eEpaFallBack, + eEpaFailed +}; + +// EPA +template +struct EPA +{ + /* Types */ + + struct sFace + { + btVector3 n; + btScalar d; + typename GJK::sSV* c[3]; + sFace* f[3]; + sFace* l[2]; + U1 e[3]; + U1 pass; + }; + struct sList + { + sFace* root; + U count; + sList() : root(0), count(0) {} + }; + struct sHorizon + { + sFace* cf; + sFace* ff; + U nf; + sHorizon() : cf(0), ff(0), nf(0) {} + }; + + /* Fields */ + eEpaStatus m_status; + typename GJK::sSimplex m_result; + btVector3 m_normal; + btScalar m_depth; + typename GJK::sSV m_sv_store[EPA_MAX_VERTICES]; + sFace m_fc_store[EPA_MAX_FACES]; + U m_nextsv; + sList m_hull; + sList m_stock; + /* Methods */ + EPA() + { + Initialize(); + } + + static inline void bind(sFace* fa, U ea, sFace* fb, U eb) + { + fa->e[ea] = (U1)eb; + fa->f[ea] = fb; + fb->e[eb] = (U1)ea; + fb->f[eb] = fa; + } + static inline void append(sList& list, sFace* face) + { + face->l[0] = 0; + face->l[1] = list.root; + if (list.root) list.root->l[0] = face; + list.root = face; + ++list.count; + } + static inline void remove(sList& list, sFace* face) + { + if (face->l[1]) face->l[1]->l[0] = face->l[0]; + if (face->l[0]) face->l[0]->l[1] = face->l[1]; + if (face == list.root) list.root = face->l[1]; + --list.count; + } + + void Initialize() + { + m_status = eEpaFailed; + m_normal = btVector3(0, 0, 0); + m_depth = 0; + m_nextsv = 0; + for (U i = 0; i < EPA_MAX_FACES; ++i) + { + append(m_stock, &m_fc_store[EPA_MAX_FACES - i - 1]); + } + } + eEpaStatus Evaluate(GJK& gjk, const btVector3& guess) + { + typename GJK::sSimplex& simplex = *gjk.m_simplex; + if ((simplex.rank > 1) && gjk.EncloseOrigin()) + { + /* Clean up */ + while (m_hull.root) + { + sFace* f = m_hull.root; + remove(m_hull, f); + append(m_stock, f); + } + m_status = eEpaValid; + m_nextsv = 0; + /* Orient simplex */ + if (gjk.det(simplex.c[0]->w - simplex.c[3]->w, + simplex.c[1]->w - simplex.c[3]->w, + simplex.c[2]->w - simplex.c[3]->w) < 0) + { + btSwap(simplex.c[0], simplex.c[1]); + btSwap(simplex.p[0], simplex.p[1]); + } + /* Build initial hull */ + sFace* tetra[] = {newface(simplex.c[0], simplex.c[1], simplex.c[2], true), + newface(simplex.c[1], simplex.c[0], simplex.c[3], true), + newface(simplex.c[2], simplex.c[1], simplex.c[3], true), + newface(simplex.c[0], simplex.c[2], simplex.c[3], true)}; + if (m_hull.count == 4) + { + sFace* best = findbest(); + sFace outer = *best; + U pass = 0; + U iterations = 0; + bind(tetra[0], 0, tetra[1], 0); + bind(tetra[0], 1, tetra[2], 0); + bind(tetra[0], 2, tetra[3], 0); + bind(tetra[1], 1, tetra[3], 2); + bind(tetra[1], 2, tetra[2], 1); + bind(tetra[2], 2, tetra[3], 1); + m_status = eEpaValid; + for (; iterations < EPA_MAX_ITERATIONS; ++iterations) + { + if (m_nextsv < EPA_MAX_VERTICES) + { + sHorizon horizon; + typename GJK::sSV* w = &m_sv_store[m_nextsv++]; + bool valid = true; + best->pass = (U1)(++pass); + gjk.getsupport(best->n, *w); + const btScalar wdist = btDot(best->n, w->w) - best->d; + if (wdist > EPA_ACCURACY) + { + for (U j = 0; (j < 3) && valid; ++j) + { + valid &= expand(pass, w, + best->f[j], best->e[j], + horizon); + } + if (valid && (horizon.nf >= 3)) + { + bind(horizon.cf, 1, horizon.ff, 2); + remove(m_hull, best); + append(m_stock, best); + best = findbest(); + outer = *best; + } + else + { + m_status = eEpaInvalidHull; + break; + } + } + else + { + m_status = eEpaAccuraryReached; + break; + } + } + else + { + m_status = eEpaOutOfVertices; + break; + } + } + const btVector3 projection = outer.n * outer.d; + m_normal = outer.n; + m_depth = outer.d; + m_result.rank = 3; + m_result.c[0] = outer.c[0]; + m_result.c[1] = outer.c[1]; + m_result.c[2] = outer.c[2]; + m_result.p[0] = btCross(outer.c[1]->w - projection, + outer.c[2]->w - projection) + .length(); + m_result.p[1] = btCross(outer.c[2]->w - projection, + outer.c[0]->w - projection) + .length(); + m_result.p[2] = btCross(outer.c[0]->w - projection, + outer.c[1]->w - projection) + .length(); + const btScalar sum = m_result.p[0] + m_result.p[1] + m_result.p[2]; + m_result.p[0] /= sum; + m_result.p[1] /= sum; + m_result.p[2] /= sum; + return (m_status); + } + } + /* Fallback */ + m_status = eEpaFallBack; + m_normal = -guess; + const btScalar nl = m_normal.length(); + if (nl > 0) + m_normal = m_normal / nl; + else + m_normal = btVector3(1, 0, 0); + m_depth = 0; + m_result.rank = 1; + m_result.c[0] = simplex.c[0]; + m_result.p[0] = 1; + return (m_status); + } + bool getedgedist(sFace* face, typename GJK::sSV* a, typename GJK::sSV* b, btScalar& dist) + { + const btVector3 ba = b->w - a->w; + const btVector3 n_ab = btCross(ba, face->n); // Outward facing edge normal direction, on triangle plane + const btScalar a_dot_nab = btDot(a->w, n_ab); // Only care about the sign to determine inside/outside, so not normalization required + + if (a_dot_nab < 0) + { + // Outside of edge a->b + + const btScalar ba_l2 = ba.length2(); + const btScalar a_dot_ba = btDot(a->w, ba); + const btScalar b_dot_ba = btDot(b->w, ba); + + if (a_dot_ba > 0) + { + // Pick distance vertex a + dist = a->w.length(); + } + else if (b_dot_ba < 0) + { + // Pick distance vertex b + dist = b->w.length(); + } + else + { + // Pick distance to edge a->b + const btScalar a_dot_b = btDot(a->w, b->w); + dist = btSqrt(btMax((a->w.length2() * b->w.length2() - a_dot_b * a_dot_b) / ba_l2, (btScalar)0)); + } + + return true; + } + + return false; + } + sFace* newface(typename GJK::sSV* a, typename GJK::sSV* b, typename GJK::sSV* c, bool forced) + { + if (m_stock.root) + { + sFace* face = m_stock.root; + remove(m_stock, face); + append(m_hull, face); + face->pass = 0; + face->c[0] = a; + face->c[1] = b; + face->c[2] = c; + face->n = btCross(b->w - a->w, c->w - a->w); + const btScalar l = face->n.length(); + const bool v = l > EPA_ACCURACY; + + if (v) + { + if (!(getedgedist(face, a, b, face->d) || + getedgedist(face, b, c, face->d) || + getedgedist(face, c, a, face->d))) + { + // Origin projects to the interior of the triangle + // Use distance to triangle plane + face->d = btDot(a->w, face->n) / l; + } + + face->n /= l; + if (forced || (face->d >= -EPA_PLANE_EPS)) + { + return face; + } + else + m_status = eEpaNonConvex; + } + else + m_status = eEpaDegenerated; + + remove(m_hull, face); + append(m_stock, face); + return 0; + } + m_status = m_stock.root ? eEpaOutOfVertices : eEpaOutOfFaces; + return 0; + } + sFace* findbest() + { + sFace* minf = m_hull.root; + btScalar mind = minf->d * minf->d; + for (sFace* f = minf->l[1]; f; f = f->l[1]) + { + const btScalar sqd = f->d * f->d; + if (sqd < mind) + { + minf = f; + mind = sqd; + } + } + return (minf); + } + bool expand(U pass, typename GJK::sSV* w, sFace* f, U e, sHorizon& horizon) + { + static const U i1m3[] = {1, 2, 0}; + static const U i2m3[] = {2, 0, 1}; + if (f->pass != pass) + { + const U e1 = i1m3[e]; + if ((btDot(f->n, w->w) - f->d) < -EPA_PLANE_EPS) + { + sFace* nf = newface(f->c[e1], f->c[e], w, false); + if (nf) + { + bind(nf, 0, f, e); + if (horizon.cf) + bind(horizon.cf, 1, nf, 2); + else + horizon.ff = nf; + horizon.cf = nf; + ++horizon.nf; + return (true); + } + } + else + { + const U e2 = i2m3[e]; + f->pass = (U1)pass; + if (expand(pass, w, f->f[e1], f->e[e1], horizon) && + expand(pass, w, f->f[e2], f->e[e2], horizon)) + { + remove(m_hull, f); + append(m_stock, f); + return (true); + } + } + } + return (false); + } +}; + +template +static void Initialize(const btConvexTemplate& a, const btConvexTemplate& b, + btGjkEpaSolver3::sResults& results, + MinkowskiDiff& shape) +{ + /* Results */ + results.witnesses[0] = + results.witnesses[1] = btVector3(0, 0, 0); + results.status = btGjkEpaSolver3::sResults::Separated; + /* Shape */ + + shape.m_toshape1 = b.getWorldTransform().getBasis().transposeTimes(a.getWorldTransform().getBasis()); + shape.m_toshape0 = a.getWorldTransform().inverseTimes(b.getWorldTransform()); +} // // Api // - - // template -bool btGjkEpaSolver3_Distance(const btConvexTemplate& a, const btConvexTemplate& b, - const btVector3& guess, - btGjkEpaSolver3::sResults& results) +bool btGjkEpaSolver3_Distance(const btConvexTemplate& a, const btConvexTemplate& b, + const btVector3& guess, + btGjkEpaSolver3::sResults& results) { - MinkowskiDiff shape(a,b); - Initialize(a,b,results,shape); - GJK gjk(a,b); - eGjkStatus gjk_status=gjk.Evaluate(shape,guess); - if(gjk_status==eGjkValid) - { - btVector3 w0=btVector3(0,0,0); - btVector3 w1=btVector3(0,0,0); - for(U i=0;irank;++i) - { - const btScalar p=gjk.m_simplex->p[i]; - w0+=shape.Support( gjk.m_simplex->c[i]->d,0)*p; - w1+=shape.Support(-gjk.m_simplex->c[i]->d,1)*p; - } - results.witnesses[0] = a.getWorldTransform()*w0; - results.witnesses[1] = a.getWorldTransform()*w1; - results.normal = w0-w1; - results.distance = results.normal.length(); - results.normal /= results.distance>GJK_MIN_DISTANCE?results.distance:1; - return(true); - } - else - { - results.status = gjk_status==eGjkInside? - btGjkEpaSolver3::sResults::Penetrating : - btGjkEpaSolver3::sResults::GJK_Failed ; - return(false); - } + MinkowskiDiff shape(a, b); + Initialize(a, b, results, shape); + GJK gjk(a, b); + eGjkStatus gjk_status = gjk.Evaluate(shape, guess); + if (gjk_status == eGjkValid) + { + btVector3 w0 = btVector3(0, 0, 0); + btVector3 w1 = btVector3(0, 0, 0); + for (U i = 0; i < gjk.m_simplex->rank; ++i) + { + const btScalar p = gjk.m_simplex->p[i]; + w0 += shape.Support(gjk.m_simplex->c[i]->d, 0) * p; + w1 += shape.Support(-gjk.m_simplex->c[i]->d, 1) * p; + } + results.witnesses[0] = a.getWorldTransform() * w0; + results.witnesses[1] = a.getWorldTransform() * w1; + results.normal = w0 - w1; + results.distance = results.normal.length(); + results.normal /= results.distance > GJK_MIN_DISTANCE ? results.distance : 1; + return (true); + } + else + { + results.status = gjk_status == eGjkInside ? btGjkEpaSolver3::sResults::Penetrating : btGjkEpaSolver3::sResults::GJK_Failed; + return (false); + } } - template -bool btGjkEpaSolver3_Penetration(const btConvexTemplate& a, - const btConvexTemplate& b, - const btVector3& guess, - btGjkEpaSolver3::sResults& results) +bool btGjkEpaSolver3_Penetration(const btConvexTemplate& a, + const btConvexTemplate& b, + const btVector3& guess, + btGjkEpaSolver3::sResults& results) { - MinkowskiDiff shape(a,b); - Initialize(a,b,results,shape); - GJK gjk(a,b); - eGjkStatus gjk_status=gjk.Evaluate(shape,-guess); - switch(gjk_status) - { - case eGjkInside: - { - EPA epa; - eEpaStatus epa_status=epa.Evaluate(gjk,-guess); - if(epa_status!=eEpaFailed) - { - btVector3 w0=btVector3(0,0,0); - for(U i=0;id,0)*epa.m_result.p[i]; - } - results.status = btGjkEpaSolver3::sResults::Penetrating; - results.witnesses[0] = a.getWorldTransform()*w0; - results.witnesses[1] = a.getWorldTransform()*(w0-epa.m_normal*epa.m_depth); - results.normal = -epa.m_normal; - results.distance = -epa.m_depth; - return(true); - } else results.status=btGjkEpaSolver3::sResults::EPA_Failed; - } - break; - case eGjkFailed: - results.status=btGjkEpaSolver3::sResults::GJK_Failed; - break; - default: - { - } - } - return(false); + MinkowskiDiff shape(a, b); + Initialize(a, b, results, shape); + GJK gjk(a, b); + eGjkStatus gjk_status = gjk.Evaluate(shape, -guess); + switch (gjk_status) + { + case eGjkInside: + { + EPA epa; + eEpaStatus epa_status = epa.Evaluate(gjk, -guess); + if (epa_status != eEpaFailed) + { + btVector3 w0 = btVector3(0, 0, 0); + for (U i = 0; i < epa.m_result.rank; ++i) + { + w0 += shape.Support(epa.m_result.c[i]->d, 0) * epa.m_result.p[i]; + } + results.status = btGjkEpaSolver3::sResults::Penetrating; + results.witnesses[0] = a.getWorldTransform() * w0; + results.witnesses[1] = a.getWorldTransform() * (w0 - epa.m_normal * epa.m_depth); + results.normal = -epa.m_normal; + results.distance = -epa.m_depth; + return (true); + } + else + results.status = btGjkEpaSolver3::sResults::EPA_Failed; + } + break; + case eGjkFailed: + results.status = btGjkEpaSolver3::sResults::GJK_Failed; + break; + default: + { + } + } + return (false); } #if 0 @@ -990,28 +1021,28 @@ int btComputeGjkEpaPenetration2(const btCollisionDescription& colDesc, btDistanc #endif template -int btComputeGjkDistance(const btConvexTemplate& a, const btConvexTemplate& b, - const btGjkCollisionDescription& colDesc, btDistanceInfoTemplate* distInfo) +int btComputeGjkDistance(const btConvexTemplate& a, const btConvexTemplate& b, + const btGjkCollisionDescription& colDesc, btDistanceInfoTemplate* distInfo) { - btGjkEpaSolver3::sResults results; - btVector3 guess = colDesc.m_firstDir; - - bool isSeparated = btGjkEpaSolver3_Distance( a,b, - guess, - results); - if (isSeparated) - { - distInfo->m_distance = results.distance; - distInfo->m_pointOnA= results.witnesses[0]; - distInfo->m_pointOnB= results.witnesses[1]; - distInfo->m_normalBtoA= results.normal; - return 0; - } - - return -1; + btGjkEpaSolver3::sResults results; + btVector3 guess = colDesc.m_firstDir; + + bool isSeparated = btGjkEpaSolver3_Distance(a, b, + guess, + results); + if (isSeparated) + { + distInfo->m_distance = results.distance; + distInfo->m_pointOnA = results.witnesses[0]; + distInfo->m_pointOnB = results.witnesses[1]; + distInfo->m_normalBtoA = results.normal; + return 0; + } + + return -1; } -/* Symbols cleanup */ +/* Symbols cleanup */ #undef GJK_MAX_ITERATIONS #undef GJK_ACCURARY @@ -1029,7 +1060,4 @@ int btComputeGjkDistance(const btConvexTemplate& a, const btConvexTemplate& b, #undef EPA_PLANE_EPS #undef EPA_INSIDE_EPS - - -#endif //BT_GJK_EPA3_H - +#endif //BT_GJK_EPA3_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp b/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp index b79f49d61..b44fab5d8 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp +++ b/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.cpp @@ -18,16 +18,14 @@ subject to the following restrictions: #include "BulletCollision/CollisionShapes/btConvexShape.h" #include "btGjkEpaPenetrationDepthSolver.h" - #include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h" bool btGjkEpaPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& simplexSolver, - const btConvexShape* pConvexA, const btConvexShape* pConvexB, - const btTransform& transformA, const btTransform& transformB, - btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB, - class btIDebugDraw* debugDraw) + const btConvexShape* pConvexA, const btConvexShape* pConvexB, + const btTransform& transformA, const btTransform& transformB, + btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB, + class btIDebugDraw* debugDraw) { - (void)debugDraw; (void)v; (void)simplexSolver; @@ -49,13 +47,13 @@ bool btGjkEpaPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& simp for (int i = 0; i < numVectors; i++) { simplexSolver.reset(); - btVector3 guessVector = guessVectors[i]; + btVector3 guessVector = guessVectors[i]; - btGjkEpaSolver2::sResults results; + btGjkEpaSolver2::sResults results; if (btGjkEpaSolver2::Penetration(pConvexA, transformA, - pConvexB, transformB, - guessVector, results)) + pConvexB, transformB, + guessVector, results)) { wWitnessOnA = results.witnesses[0]; @@ -81,4 +79,3 @@ bool btGjkEpaPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& simp v.setValue(0, 0, 0); return false; } - diff --git a/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h b/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h index 1ed6340af..92d6df172 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h +++ b/src/BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h @@ -23,21 +23,18 @@ subject to the following restrictions: ///calculate the penetration depth between two convex shapes. class btGjkEpaPenetrationDepthSolver : public btConvexPenetrationDepthSolver { - public : +public: + btGjkEpaPenetrationDepthSolver() + { + } - btGjkEpaPenetrationDepthSolver() - { - } - - bool calcPenDepth( btSimplexSolverInterface& simplexSolver, - const btConvexShape* pConvexA, const btConvexShape* pConvexB, - const btTransform& transformA, const btTransform& transformB, - btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB, - class btIDebugDraw* debugDraw); - - private : + bool calcPenDepth(btSimplexSolverInterface& simplexSolver, + const btConvexShape* pConvexA, const btConvexShape* pConvexB, + const btTransform& transformA, const btTransform& transformB, + btVector3& v, btVector3& wWitnessOnA, btVector3& wWitnessOnB, + class btIDebugDraw* debugDraw); +private: }; -#endif // BT_GJP_EPA_PENETRATION_DEPTH_H - +#endif // BT_GJP_EPA_PENETRATION_DEPTH_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp b/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp index a0b825f0e..936130753 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp +++ b/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.cpp @@ -18,75 +18,72 @@ subject to the following restrictions: #include "BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h" #include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h" - - -#if defined(DEBUG) || defined (_DEBUG) +#if defined(DEBUG) || defined(_DEBUG) //#define TEST_NON_VIRTUAL 1 -#include //for debug printf +#include //for debug printf #ifdef __SPU__ #include #define printf spu_printf -#endif //__SPU__ +#endif //__SPU__ #endif //must be above the machine epsilon -#ifdef BT_USE_DOUBLE_PRECISION - #define REL_ERROR2 btScalar(1.0e-12) - btScalar gGjkEpaPenetrationTolerance = 1.0e-12; +#ifdef BT_USE_DOUBLE_PRECISION +#define REL_ERROR2 btScalar(1.0e-12) +btScalar gGjkEpaPenetrationTolerance = 1.0e-12; #else - #define REL_ERROR2 btScalar(1.0e-6) - btScalar gGjkEpaPenetrationTolerance = 0.001; +#define REL_ERROR2 btScalar(1.0e-6) +btScalar gGjkEpaPenetrationTolerance = 0.001; #endif //temp globals, to improve GJK/EPA/penetration calculations int gNumDeepPenetrationChecks = 0; int gNumGjkChecks = 0; - -btGjkPairDetector::btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver) -:m_cachedSeparatingAxis(btScalar(0.),btScalar(1.),btScalar(0.)), -m_penetrationDepthSolver(penetrationDepthSolver), -m_simplexSolver(simplexSolver), -m_minkowskiA(objectA), -m_minkowskiB(objectB), -m_shapeTypeA(objectA->getShapeType()), -m_shapeTypeB(objectB->getShapeType()), -m_marginA(objectA->getMargin()), -m_marginB(objectB->getMargin()), -m_ignoreMargin(false), -m_lastUsedMethod(-1), -m_catchDegeneracies(1), -m_fixContactNormalDirection(1) +btGjkPairDetector::btGjkPairDetector(const btConvexShape *objectA, const btConvexShape *objectB, btSimplexSolverInterface *simplexSolver, btConvexPenetrationDepthSolver *penetrationDepthSolver) + : m_cachedSeparatingAxis(btScalar(0.), btScalar(1.), btScalar(0.)), + m_penetrationDepthSolver(penetrationDepthSolver), + m_simplexSolver(simplexSolver), + m_minkowskiA(objectA), + m_minkowskiB(objectB), + m_shapeTypeA(objectA->getShapeType()), + m_shapeTypeB(objectB->getShapeType()), + m_marginA(objectA->getMargin()), + m_marginB(objectB->getMargin()), + m_ignoreMargin(false), + m_lastUsedMethod(-1), + m_catchDegeneracies(1), + m_fixContactNormalDirection(1) { } -btGjkPairDetector::btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,int shapeTypeA,int shapeTypeB,btScalar marginA, btScalar marginB, btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver) -:m_cachedSeparatingAxis(btScalar(0.),btScalar(1.),btScalar(0.)), -m_penetrationDepthSolver(penetrationDepthSolver), -m_simplexSolver(simplexSolver), -m_minkowskiA(objectA), -m_minkowskiB(objectB), -m_shapeTypeA(shapeTypeA), -m_shapeTypeB(shapeTypeB), -m_marginA(marginA), -m_marginB(marginB), -m_ignoreMargin(false), -m_lastUsedMethod(-1), -m_catchDegeneracies(1), -m_fixContactNormalDirection(1) +btGjkPairDetector::btGjkPairDetector(const btConvexShape *objectA, const btConvexShape *objectB, int shapeTypeA, int shapeTypeB, btScalar marginA, btScalar marginB, btSimplexSolverInterface *simplexSolver, btConvexPenetrationDepthSolver *penetrationDepthSolver) + : m_cachedSeparatingAxis(btScalar(0.), btScalar(1.), btScalar(0.)), + m_penetrationDepthSolver(penetrationDepthSolver), + m_simplexSolver(simplexSolver), + m_minkowskiA(objectA), + m_minkowskiB(objectB), + m_shapeTypeA(shapeTypeA), + m_shapeTypeB(shapeTypeB), + m_marginA(marginA), + m_marginB(marginB), + m_ignoreMargin(false), + m_lastUsedMethod(-1), + m_catchDegeneracies(1), + m_fixContactNormalDirection(1) { } -void btGjkPairDetector::getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults) +void btGjkPairDetector::getClosestPoints(const ClosestPointInput &input, Result &output, class btIDebugDraw *debugDraw, bool swapResults) { (void)swapResults; - getClosestPointsNonVirtual(input,output,debugDraw); + getClosestPointsNonVirtual(input, output, debugDraw); } -static void btComputeSupport(const btConvexShape* convexA, const btTransform& localTransA, const btConvexShape* convexB, const btTransform& localTransB, const btVector3& dir, bool check2d, btVector3& supAworld, btVector3& supBworld, btVector3& aMinb) +static void btComputeSupport(const btConvexShape *convexA, const btTransform &localTransA, const btConvexShape *convexB, const btTransform &localTransB, const btVector3 &dir, bool check2d, btVector3 &supAworld, btVector3 &supBworld, btVector3 &aMinb) { - btVector3 seperatingAxisInA = (dir)* localTransA.getBasis(); - btVector3 seperatingAxisInB = (-dir)* localTransB.getBasis(); + btVector3 seperatingAxisInA = (dir)*localTransA.getBasis(); + btVector3 seperatingAxisInB = (-dir) * localTransB.getBasis(); btVector3 pInANoMargin = convexA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA); btVector3 qInBNoMargin = convexB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB); @@ -106,22 +103,21 @@ static void btComputeSupport(const btConvexShape* convexA, const btTransform& lo aMinb = supAworld - supBworld; } -struct btSupportVector +struct btSupportVector { - btVector3 v; //!< Support point in minkowski sum - btVector3 v1; //!< Support point in obj1 - btVector3 v2; //!< Support point in obj2 + btVector3 v; //!< Support point in minkowski sum + btVector3 v1; //!< Support point in obj1 + btVector3 v2; //!< Support point in obj2 }; -struct btSimplex +struct btSimplex { btSupportVector ps[4]; - int last; //!< index of last added point + int last; //!< index of last added point }; static btVector3 ccd_vec3_origin(0, 0, 0); - inline void btSimplexInit(btSimplex *s) { s->last = -1; @@ -142,19 +138,18 @@ inline void btSupportCopy(btSupportVector *d, const btSupportVector *s) *d = *s; } -inline void btVec3Copy(btVector3 *v, const btVector3* w) +inline void btVec3Copy(btVector3 *v, const btVector3 *w) { *v = *w; } -inline void ccdVec3Add(btVector3*v, const btVector3*w) +inline void ccdVec3Add(btVector3 *v, const btVector3 *w) { v->m_floats[0] += w->m_floats[0]; v->m_floats[1] += w->m_floats[1]; v->m_floats[2] += w->m_floats[2]; } - inline void ccdVec3Sub(btVector3 *v, const btVector3 *w) { *v -= *w; @@ -162,24 +157,22 @@ inline void ccdVec3Sub(btVector3 *v, const btVector3 *w) inline void btVec3Sub2(btVector3 *d, const btVector3 *v, const btVector3 *w) { *d = (*v) - (*w); - } -inline btScalar btVec3Dot(const btVector3 *a, const btVector3 *b) +inline btScalar btVec3Dot(const btVector3 *a, const btVector3 *b) { btScalar dot; dot = a->dot(*b); - + return dot; } -inline btScalar ccdVec3Dist2(const btVector3 *a, const btVector3*b) +inline btScalar ccdVec3Dist2(const btVector3 *a, const btVector3 *b) { btVector3 ab; btVec3Sub2(&ab, a, b); return btVec3Dot(&ab, &ab); } - inline void btVec3Scale(btVector3 *d, btScalar k) { d->m_floats[0] *= k; @@ -195,7 +188,7 @@ inline void btVec3Cross(btVector3 *d, const btVector3 *a, const btVector3 *b) } inline void btTripleCross(const btVector3 *a, const btVector3 *b, - const btVector3 *c, btVector3 *d) + const btVector3 *c, btVector3 *d) { btVector3 e; btVec3Cross(&e, a, b); @@ -213,36 +206,35 @@ inline int ccdEq(btScalar _a, btScalar _b) a = btFabs(_a); b = btFabs(_b); - if (b > a) { + if (b > a) + { return ab < SIMD_EPSILON * b; } - else { + else + { return ab < SIMD_EPSILON * a; } } -btScalar ccdVec3X(const btVector3* v) +btScalar ccdVec3X(const btVector3 *v) { return v->x(); } -btScalar ccdVec3Y(const btVector3* v) +btScalar ccdVec3Y(const btVector3 *v) { return v->y(); } -btScalar ccdVec3Z(const btVector3* v) +btScalar ccdVec3Z(const btVector3 *v) { return v->z(); } inline int btVec3Eq(const btVector3 *a, const btVector3 *b) { - return ccdEq(ccdVec3X(a), ccdVec3X(b)) - && ccdEq(ccdVec3Y(a), ccdVec3Y(b)) - && ccdEq(ccdVec3Z(a), ccdVec3Z(b)); + return ccdEq(ccdVec3X(a), ccdVec3X(b)) && ccdEq(ccdVec3Y(a), ccdVec3Y(b)) && ccdEq(ccdVec3Z(a), ccdVec3Z(b)); } - inline void btSimplexAdd(btSimplex *s, const btSupportVector *v) { // here is no check on boundaries in sake of speed @@ -250,7 +242,6 @@ inline void btSimplexAdd(btSimplex *s, const btSupportVector *v) btSupportCopy(s->ps + s->last, v); } - inline void btSimplexSet(btSimplex *s, size_t pos, const btSupportVector *a) { btSupportCopy(s->ps + pos, a); @@ -268,27 +259,28 @@ inline const btSupportVector *ccdSimplexLast(const btSimplex *s) inline int ccdSign(btScalar val) { - if (btFuzzyZero(val)) { + if (btFuzzyZero(val)) + { return 0; } - else if (val < btScalar(0)) { + else if (val < btScalar(0)) + { return -1; } return 1; } - inline btScalar btVec3PointSegmentDist2(const btVector3 *P, - const btVector3 *x0, - const btVector3 *b, - btVector3 *witness) + const btVector3 *x0, + const btVector3 *b, + btVector3 *witness) { // The computation comes from solving equation of segment: // S(t) = x0 + t.d // where - x0 is initial point of segment // - d is direction of segment from x0 (|d| > 0) // - t belongs to <0, 1> interval - // + // // Than, distance from a segment to some point P can be expressed: // D(t) = |x0 + t.d - P|^2 // which is distance from any point on segment. Minimization @@ -310,24 +302,29 @@ inline btScalar btVec3PointSegmentDist2(const btVector3 *P, t = -btScalar(1.) * btVec3Dot(&a, &d); t /= btVec3Dot(&d, &d); - if (t < btScalar(0) || btFuzzyZero(t)) { + if (t < btScalar(0) || btFuzzyZero(t)) + { dist = ccdVec3Dist2(x0, P); if (witness) btVec3Copy(witness, x0); } - else if (t > btScalar(1) || ccdEq(t, btScalar(1))) { + else if (t > btScalar(1) || ccdEq(t, btScalar(1))) + { dist = ccdVec3Dist2(b, P); if (witness) btVec3Copy(witness, b); } - else { - if (witness) { + else + { + if (witness) + { btVec3Copy(witness, &d); btVec3Scale(witness, t); ccdVec3Add(witness, x0); dist = ccdVec3Dist2(witness, P); } - else { + else + { // recycling variables btVec3Scale(&d, t); ccdVec3Add(&d, &a); @@ -338,11 +335,10 @@ inline btScalar btVec3PointSegmentDist2(const btVector3 *P, return dist; } - btScalar btVec3PointTriDist2(const btVector3 *P, - const btVector3 *x0, const btVector3 *B, - const btVector3 *C, - btVector3 *witness) + const btVector3 *x0, const btVector3 *B, + const btVector3 *C, + btVector3 *witness) { // Computation comes from analytic expression for triangle (x0, B, C) // T(s, t) = x0 + s.d1 + t.d2, where d1 = B - x0 and d2 = C - x0 and @@ -372,13 +368,9 @@ btScalar btVec3PointTriDist2(const btVector3 *P, s = (q * r - w * p) / (w * v - r * r); t = (-s * r - q) / w; - if ((btFuzzyZero(s) || s > btScalar(0)) - && (ccdEq(s, btScalar(1)) || s < btScalar(1)) - && (btFuzzyZero(t) || t > btScalar(0)) - && (ccdEq(t, btScalar(1)) || t < btScalar(1)) - && (ccdEq(t + s, btScalar(1)) || t + s < btScalar(1))) { - - if (witness) + if ((btFuzzyZero(s) || s > btScalar(0)) && (ccdEq(s, btScalar(1)) || s < btScalar(1)) && (btFuzzyZero(t) || t > btScalar(0)) && (ccdEq(t, btScalar(1)) || t < btScalar(1)) && (ccdEq(t + s, btScalar(1)) || t + s < btScalar(1))) + { + if (witness) { btVec3Scale(&d1, s); btVec3Scale(&d2, t); @@ -388,7 +380,7 @@ btScalar btVec3PointTriDist2(const btVector3 *P, dist = ccdVec3Dist2(witness, P); } - else + else { dist = s * s * v; dist += t * t * w; @@ -398,18 +390,21 @@ btScalar btVec3PointTriDist2(const btVector3 *P, dist += u; } } - else { + else + { dist = btVec3PointSegmentDist2(P, x0, B, witness); dist2 = btVec3PointSegmentDist2(P, x0, C, &witness2); - if (dist2 < dist) { + if (dist2 < dist) + { dist = dist2; if (witness) btVec3Copy(witness, &witness2); } dist2 = btVec3PointSegmentDist2(P, B, C, &witness2); - if (dist2 < dist) { + if (dist2 < dist) + { dist = dist2; if (witness) btVec3Copy(witness, &witness2); @@ -419,7 +414,6 @@ btScalar btVec3PointTriDist2(const btVector3 *P, return dist; } - static int btDoSimplex2(btSimplex *simplex, btVector3 *dir) { const btSupportVector *A, *B; @@ -441,18 +435,21 @@ static int btDoSimplex2(btSimplex *simplex, btVector3 *dir) // check if origin doesn't lie on AB segment btVec3Cross(&tmp, &AB, &AO); - if (btFuzzyZero(btVec3Dot(&tmp, &tmp)) && dot > btScalar(0)) { + if (btFuzzyZero(btVec3Dot(&tmp, &tmp)) && dot > btScalar(0)) + { return 1; } // check if origin is in area where AB segment is - if (btFuzzyZero(dot) || dot < btScalar(0)) { + if (btFuzzyZero(dot) || dot < btScalar(0)) + { // origin is in outside are of A btSimplexSet(simplex, 0, A); btSimplexSetSize(simplex, 1); btVec3Copy(dir, &AO); } - else { + else + { // origin is in area where AB segment is // keep simplex untouched and set direction to @@ -463,8 +460,6 @@ static int btDoSimplex2(btSimplex *simplex, btVector3 *dir) return 0; } - - static int btDoSimplex3(btSimplex *simplex, btVector3 *dir) { const btSupportVector *A, *B, *C; @@ -479,13 +474,15 @@ static int btDoSimplex3(btSimplex *simplex, btVector3 *dir) // check touching contact dist = btVec3PointTriDist2(&ccd_vec3_origin, &A->v, &B->v, &C->v, 0); - if (btFuzzyZero(dist)) { + if (btFuzzyZero(dist)) + { return 1; } // check if triangle is really triangle (has area > 0) // if not simplex can't be expanded and thus no itersection is found - if (btVec3Eq(&A->v, &B->v) || btVec3Eq(&A->v, &C->v)) { + if (btVec3Eq(&A->v, &B->v) || btVec3Eq(&A->v, &C->v)) + { return -1; } @@ -500,54 +497,64 @@ static int btDoSimplex3(btSimplex *simplex, btVector3 *dir) btVec3Cross(&tmp, &ABC, &AC); dot = btVec3Dot(&tmp, &AO); - if (btFuzzyZero(dot) || dot > btScalar(0)) { + if (btFuzzyZero(dot) || dot > btScalar(0)) + { dot = btVec3Dot(&AC, &AO); - if (btFuzzyZero(dot) || dot > btScalar(0)) { + if (btFuzzyZero(dot) || dot > btScalar(0)) + { // C is already in place btSimplexSet(simplex, 1, A); btSimplexSetSize(simplex, 2); btTripleCross(&AC, &AO, &AC, dir); } - else { - + else + { dot = btVec3Dot(&AB, &AO); - if (btFuzzyZero(dot) || dot > btScalar(0)) { + if (btFuzzyZero(dot) || dot > btScalar(0)) + { btSimplexSet(simplex, 0, B); btSimplexSet(simplex, 1, A); btSimplexSetSize(simplex, 2); btTripleCross(&AB, &AO, &AB, dir); } - else { + else + { btSimplexSet(simplex, 0, A); btSimplexSetSize(simplex, 1); btVec3Copy(dir, &AO); } } } - else { + else + { btVec3Cross(&tmp, &AB, &ABC); dot = btVec3Dot(&tmp, &AO); - if (btFuzzyZero(dot) || dot > btScalar(0)) + if (btFuzzyZero(dot) || dot > btScalar(0)) { dot = btVec3Dot(&AB, &AO); - if (btFuzzyZero(dot) || dot > btScalar(0)) { + if (btFuzzyZero(dot) || dot > btScalar(0)) + { btSimplexSet(simplex, 0, B); btSimplexSet(simplex, 1, A); btSimplexSetSize(simplex, 2); btTripleCross(&AB, &AO, &AB, dir); } - else { + else + { btSimplexSet(simplex, 0, A); btSimplexSetSize(simplex, 1); btVec3Copy(dir, &AO); } } - else { + else + { dot = btVec3Dot(&ABC, &AO); - if (btFuzzyZero(dot) || dot > btScalar(0)) { + if (btFuzzyZero(dot) || dot > btScalar(0)) + { btVec3Copy(dir, &ABC); } - else { + else + { btSupportVector tmp; btSupportCopy(&tmp, C); btSimplexSet(simplex, 0, B); @@ -581,7 +588,8 @@ static int btDoSimplex4(btSimplex *simplex, btVector3 *dir) // if it is not simplex can't be expanded and thus no intersection is // found dist = btVec3PointTriDist2(&A->v, &B->v, &C->v, &D->v, 0); - if (btFuzzyZero(dist)) { + if (btFuzzyZero(dist)) + { return -1; } @@ -622,12 +630,14 @@ static int btDoSimplex4(btSimplex *simplex, btVector3 *dir) AC_O = ccdSign(btVec3Dot(&ADB, &AO)) == C_on_ADB; AD_O = ccdSign(btVec3Dot(&ABC, &AO)) == D_on_ABC; - if (AB_O && AC_O && AD_O) { + if (AB_O && AC_O && AD_O) + { // origin is in tetrahedron return 1; // rearrange simplex to triangle and call btDoSimplex3() } - else if (!AB_O) { + else if (!AB_O) + { // B is farthest from the origin among all of the tetrahedron's // points, so remove it from the list and go on with the triangle // case @@ -636,14 +646,16 @@ static int btDoSimplex4(btSimplex *simplex, btVector3 *dir) btSimplexSet(simplex, 2, A); btSimplexSetSize(simplex, 3); } - else if (!AC_O) { + else if (!AC_O) + { // C is farthest btSimplexSet(simplex, 1, D); btSimplexSet(simplex, 0, B); btSimplexSet(simplex, 2, A); btSimplexSetSize(simplex, 3); } - else { // (!AD_O) + else + { // (!AD_O) btSimplexSet(simplex, 0, C); btSimplexSet(simplex, 1, B); btSimplexSet(simplex, 2, A); @@ -655,36 +667,39 @@ static int btDoSimplex4(btSimplex *simplex, btVector3 *dir) static int btDoSimplex(btSimplex *simplex, btVector3 *dir) { - if (btSimplexSize(simplex) == 2) { + if (btSimplexSize(simplex) == 2) + { // simplex contains segment only one segment return btDoSimplex2(simplex, dir); } - else if (btSimplexSize(simplex) == 3) { + else if (btSimplexSize(simplex) == 3) + { // simplex contains triangle return btDoSimplex3(simplex, dir); } - else { // btSimplexSize(simplex) == 4 - // tetrahedron - this is the only shape which can encapsule origin - // so btDoSimplex4() also contains test on it + else + { // btSimplexSize(simplex) == 4 + // tetrahedron - this is the only shape which can encapsule origin + // so btDoSimplex4() also contains test on it return btDoSimplex4(simplex, dir); } } #ifdef __SPU__ -void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw) +void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput &input, Result &output, class btIDebugDraw *debugDraw) #else -void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& input, Result& output, class btIDebugDraw* debugDraw) +void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput &input, Result &output, class btIDebugDraw *debugDraw) #endif { m_cachedSeparatingDistance = 0.f; - btScalar distance=btScalar(0.); - btVector3 normalInB(btScalar(0.),btScalar(0.),btScalar(0.)); + btScalar distance = btScalar(0.); + btVector3 normalInB(btScalar(0.), btScalar(0.), btScalar(0.)); - btVector3 pointOnA,pointOnB; - btTransform localTransA = input.m_transformA; + btVector3 pointOnA, pointOnB; + btTransform localTransA = input.m_transformA; btTransform localTransB = input.m_transformB; - btVector3 positionOffset=(localTransA.getOrigin() + localTransB.getOrigin()) * btScalar(0.5); + btVector3 positionOffset = (localTransA.getOrigin() + localTransB.getOrigin()) * btScalar(0.5); localTransA.getOrigin() -= positionOffset; localTransB.getOrigin() -= positionOffset; @@ -703,19 +718,19 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu } m_curIter = 0; - int gGjkMaxIter = 1000;//this is to catch invalid input, perhaps check for #NaN? - m_cachedSeparatingAxis.setValue(0,1,0); + int gGjkMaxIter = 1000; //this is to catch invalid input, perhaps check for #NaN? + m_cachedSeparatingAxis.setValue(0, 1, 0); bool isValid = false; bool checkSimplex = false; bool checkPenetration = true; m_degenerateSimplex = 0; - + m_lastUsedMethod = -1; int status = -2; btVector3 orgNormalInB(0, 0, 0); btScalar margin = marginA + marginB; - + //we add a separate implementation to check if the convex shapes intersect //See also "Real-time Collision Detection with Implicit Objects" by Leif Olvang //Todo: integrate the simplex penetration check directly inside the Bullet btVoronoiSimplexSolver @@ -726,22 +741,18 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu btScalar squaredDistance = BT_LARGE_FLOAT; btScalar delta = btScalar(0.); - - - btSimplex simplex1; - btSimplex* simplex = &simplex1; + btSimplex *simplex = &simplex1; btSimplexInit(simplex); btVector3 dir(1, 0, 0); { - btVector3 lastSupV; btVector3 supAworld; btVector3 supBworld; btComputeSupport(m_minkowskiA, localTransA, m_minkowskiB, localTransB, dir, check2d, supAworld, supBworld, lastSupV); - + btSupportVector last; last.v = lastSupV; last.v1 = supAworld; @@ -751,10 +762,8 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu dir = -lastSupV; - - // start iterations - for (int iterations = 0; iterations reset(); @@ -825,27 +833,24 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu //printf("Intersect!\n"); } - if (status==-1) + if (status == -1) { //printf("not intersect\n"); } //printf("dir=%f,%f,%f\n",dir[0],dir[1],dir[2]); if (1) { - for (; ; ) - //while (true) + for (;;) + //while (true) { - - btVector3 seperatingAxisInA = (-m_cachedSeparatingAxis)* localTransA.getBasis(); - btVector3 seperatingAxisInB = m_cachedSeparatingAxis* localTransB.getBasis(); - + btVector3 seperatingAxisInA = (-m_cachedSeparatingAxis) * localTransA.getBasis(); + btVector3 seperatingAxisInB = m_cachedSeparatingAxis * localTransB.getBasis(); btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA); btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB); - btVector3 pWorld = localTransA(pInA); - btVector3 qWorld = localTransB(qInB); - + btVector3 pWorld = localTransA(pInA); + btVector3 qWorld = localTransB(qInB); if (check2d) { @@ -921,8 +926,7 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu checkSimplex = false; break; } -#endif // - +#endif // //redundant m_simplexSolver->compute_points(pointOnA, pointOnB); @@ -938,33 +942,31 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu m_cachedSeparatingAxis = newCachedSeparatingAxis; - //degeneracy, this is typically due to invalid/uninitialized worldtransforms for a btCollisionObject + //degeneracy, this is typically due to invalid/uninitialized worldtransforms for a btCollisionObject if (m_curIter++ > gGjkMaxIter) { -#if defined(DEBUG) || defined (_DEBUG) +#if defined(DEBUG) || defined(_DEBUG) printf("btGjkPairDetector maxIter exceeded:%i\n", m_curIter); printf("sepAxis=(%f,%f,%f), squaredDistance = %f, shapeTypeA=%i,shapeTypeB=%i\n", - m_cachedSeparatingAxis.getX(), - m_cachedSeparatingAxis.getY(), - m_cachedSeparatingAxis.getZ(), - squaredDistance, - m_minkowskiA->getShapeType(), - m_minkowskiB->getShapeType()); + m_cachedSeparatingAxis.getX(), + m_cachedSeparatingAxis.getY(), + m_cachedSeparatingAxis.getZ(), + squaredDistance, + m_minkowskiA->getShapeType(), + m_minkowskiB->getShapeType()); -#endif +#endif break; - } - bool check = (!m_simplexSolver->fullSimplex()); //bool check = (!m_simplexSolver->fullSimplex() && squaredDistance > SIMD_EPSILON * m_simplexSolver->maxVertex()); if (!check) { //do we need this backup_closest here ? - // m_simplexSolver->backup_closest(m_cachedSeparatingAxis); + // m_simplexSolver->backup_closest(m_cachedSeparatingAxis); m_degenerateSimplex = 13; break; } @@ -972,20 +974,20 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu if (checkSimplex) { - m_simplexSolver->compute_points(pointOnA, pointOnB); - normalInB = m_cachedSeparatingAxis; + m_simplexSolver->compute_points(pointOnA, pointOnB); + normalInB = m_cachedSeparatingAxis; + + btScalar lenSqr = m_cachedSeparatingAxis.length2(); - btScalar lenSqr =m_cachedSeparatingAxis.length2(); - //valid normal if (lenSqr < REL_ERROR2) { m_degenerateSimplex = 5; } - if (lenSqr > SIMD_EPSILON*SIMD_EPSILON) + if (lenSqr > SIMD_EPSILON * SIMD_EPSILON) { btScalar rlen = btScalar(1.) / btSqrt(lenSqr); - normalInB *= rlen; //normalize + normalInB *= rlen; //normalize btScalar s = btSqrt(squaredDistance); @@ -1005,13 +1007,11 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu } } - - - bool catchDegeneratePenetrationCase = - (m_catchDegeneracies && m_penetrationDepthSolver && m_degenerateSimplex && ((distance+margin) < gGjkEpaPenetrationTolerance)); + bool catchDegeneratePenetrationCase = + (m_catchDegeneracies && m_penetrationDepthSolver && m_degenerateSimplex && ((distance + margin) < gGjkEpaPenetrationTolerance)); //if (checkPenetration && !isValid) - if ((checkPenetration && (!isValid || catchDegeneratePenetrationCase )) || (status == 0)) + if ((checkPenetration && (!isValid || catchDegeneratePenetrationCase)) || (status == 0)) { //penetration case @@ -1019,19 +1019,17 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu if (m_penetrationDepthSolver) { // Penetration depth case. - btVector3 tmpPointOnA,tmpPointOnB; - + btVector3 tmpPointOnA, tmpPointOnB; + gNumDeepPenetrationChecks++; m_cachedSeparatingAxis.setZero(); - bool isValid2 = m_penetrationDepthSolver->calcPenDepth( - *m_simplexSolver, - m_minkowskiA,m_minkowskiB, - localTransA,localTransB, + bool isValid2 = m_penetrationDepthSolver->calcPenDepth( + *m_simplexSolver, + m_minkowskiA, m_minkowskiB, + localTransA, localTransB, m_cachedSeparatingAxis, tmpPointOnA, tmpPointOnB, - debugDraw - ); - + debugDraw); if (m_cachedSeparatingAxis.length2()) { @@ -1039,13 +1037,13 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu { btVector3 tmpNormalInB = tmpPointOnB - tmpPointOnA; btScalar lenSqr = tmpNormalInB.length2(); - if (lenSqr <= (SIMD_EPSILON*SIMD_EPSILON)) + if (lenSqr <= (SIMD_EPSILON * SIMD_EPSILON)) { tmpNormalInB = m_cachedSeparatingAxis; lenSqr = m_cachedSeparatingAxis.length2(); } - if (lenSqr > (SIMD_EPSILON*SIMD_EPSILON)) + if (lenSqr > (SIMD_EPSILON * SIMD_EPSILON)) { tmpNormalInB /= btSqrt(lenSqr); btScalar distance2 = -(tmpPointOnA - tmpPointOnB).length(); @@ -1058,7 +1056,6 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu pointOnB = tmpPointOnB; normalInB = tmpNormalInB; isValid = true; - } else { @@ -1079,7 +1076,6 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu ///thanks to Jacob.Langford for the reproduction case ///http://code.google.com/p/bullet/issues/detail?id=250 - if (m_cachedSeparatingAxis.length2() > btScalar(0.)) { btScalar distance2 = (tmpPointOnA - tmpPointOnB).length() - margin; @@ -1103,109 +1099,90 @@ void btGjkPairDetector::getClosestPointsNonVirtual(const ClosestPointInput& inpu } } } - } else + } + else { //printf("EPA didn't return a valid value\n"); } - } - } } - - - if (isValid && ((distance < 0) || (distance*distance < input.m_maximumDistanceSquared))) + if (isValid && ((distance < 0) || (distance * distance < input.m_maximumDistanceSquared))) { - m_cachedSeparatingAxis = normalInB; m_cachedSeparatingDistance = distance; if (1) { - ///todo: need to track down this EPA penetration solver degeneracy - ///the penetration solver reports penetration but the contact normal - ///connecting the contact points is pointing in the opposite direction - ///until then, detect the issue and revert the normal + ///todo: need to track down this EPA penetration solver degeneracy + ///the penetration solver reports penetration but the contact normal + ///connecting the contact points is pointing in the opposite direction + ///until then, detect the issue and revert the normal btScalar d2 = 0.f; { - btVector3 seperatingAxisInA = (-orgNormalInB)* localTransA.getBasis(); - btVector3 seperatingAxisInB = orgNormalInB* localTransB.getBasis(); - + btVector3 seperatingAxisInA = (-orgNormalInB) * localTransA.getBasis(); + btVector3 seperatingAxisInB = orgNormalInB * localTransB.getBasis(); btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA); btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB); - btVector3 pWorld = localTransA(pInA); - btVector3 qWorld = localTransB(qInB); + btVector3 pWorld = localTransA(pInA); + btVector3 qWorld = localTransB(qInB); btVector3 w = pWorld - qWorld; - d2 = orgNormalInB.dot(w)- margin; + d2 = orgNormalInB.dot(w) - margin; } - - btScalar d1=0; + + btScalar d1 = 0; { - - btVector3 seperatingAxisInA = (normalInB)* localTransA.getBasis(); - btVector3 seperatingAxisInB = -normalInB* localTransB.getBasis(); - + btVector3 seperatingAxisInA = (normalInB)*localTransA.getBasis(); + btVector3 seperatingAxisInB = -normalInB * localTransB.getBasis(); btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA); btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB); - btVector3 pWorld = localTransA(pInA); - btVector3 qWorld = localTransB(qInB); - btVector3 w = pWorld - qWorld; - d1 = (-normalInB).dot(w)- margin; - + btVector3 pWorld = localTransA(pInA); + btVector3 qWorld = localTransB(qInB); + btVector3 w = pWorld - qWorld; + d1 = (-normalInB).dot(w) - margin; } btScalar d0 = 0.f; { - btVector3 seperatingAxisInA = (-normalInB)* input.m_transformA.getBasis(); - btVector3 seperatingAxisInB = normalInB* input.m_transformB.getBasis(); - + btVector3 seperatingAxisInA = (-normalInB) * input.m_transformA.getBasis(); + btVector3 seperatingAxisInB = normalInB * input.m_transformB.getBasis(); btVector3 pInA = m_minkowskiA->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA); btVector3 qInB = m_minkowskiB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB); - btVector3 pWorld = localTransA(pInA); - btVector3 qWorld = localTransB(qInB); - btVector3 w = pWorld - qWorld; - d0 = normalInB.dot(w)-margin; + btVector3 pWorld = localTransA(pInA); + btVector3 qWorld = localTransB(qInB); + btVector3 w = pWorld - qWorld; + d0 = normalInB.dot(w) - margin; } - - if (d1>d0) + + if (d1 > d0) { m_lastUsedMethod = 10; - normalInB*=-1; - } + normalInB *= -1; + } if (orgNormalInB.length2()) { if (d2 > d0 && d2 > d1 && d2 > distance) { - normalInB = orgNormalInB; distance = d2; } } } - output.addContactPoint( normalInB, - pointOnB+positionOffset, + pointOnB + positionOffset, distance); - } else { //printf("invalid gjk query\n"); } - - } - - - - - diff --git a/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h b/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h index feeae6862..659b63551 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h +++ b/src/BulletCollision/NarrowPhaseCollision/btGjkPairDetector.h @@ -13,9 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - - #ifndef BT_GJK_PAIR_DETECTOR_H #define BT_GJK_PAIR_DETECTOR_H @@ -29,39 +26,34 @@ class btConvexPenetrationDepthSolver; /// btGjkPairDetector uses GJK to implement the btDiscreteCollisionDetectorInterface class btGjkPairDetector : public btDiscreteCollisionDetectorInterface { - - - btVector3 m_cachedSeparatingAxis; - btConvexPenetrationDepthSolver* m_penetrationDepthSolver; + btVector3 m_cachedSeparatingAxis; + btConvexPenetrationDepthSolver* m_penetrationDepthSolver; btSimplexSolverInterface* m_simplexSolver; const btConvexShape* m_minkowskiA; const btConvexShape* m_minkowskiB; - int m_shapeTypeA; + int m_shapeTypeA; int m_shapeTypeB; - btScalar m_marginA; - btScalar m_marginB; + btScalar m_marginA; + btScalar m_marginB; - bool m_ignoreMargin; - btScalar m_cachedSeparatingDistance; - + bool m_ignoreMargin; + btScalar m_cachedSeparatingDistance; public: - //some debugging to fix degeneracy problems - int m_lastUsedMethod; - int m_curIter; - int m_degenerateSimplex; - int m_catchDegeneracies; - int m_fixContactNormalDirection; + int m_lastUsedMethod; + int m_curIter; + int m_degenerateSimplex; + int m_catchDegeneracies; + int m_fixContactNormalDirection; - btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver); - btGjkPairDetector(const btConvexShape* objectA,const btConvexShape* objectB,int shapeTypeA,int shapeTypeB,btScalar marginA, btScalar marginB, btSimplexSolverInterface* simplexSolver,btConvexPenetrationDepthSolver* penetrationDepthSolver); - virtual ~btGjkPairDetector() {}; + btGjkPairDetector(const btConvexShape* objectA, const btConvexShape* objectB, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* penetrationDepthSolver); + btGjkPairDetector(const btConvexShape* objectA, const btConvexShape* objectB, int shapeTypeA, int shapeTypeB, btScalar marginA, btScalar marginB, btSimplexSolverInterface* simplexSolver, btConvexPenetrationDepthSolver* penetrationDepthSolver); + virtual ~btGjkPairDetector(){}; - virtual void getClosestPoints(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw,bool swapResults=false); + virtual void getClosestPoints(const ClosestPointInput& input, Result& output, class btIDebugDraw* debugDraw, bool swapResults = false); - void getClosestPointsNonVirtual(const ClosestPointInput& input,Result& output,class btIDebugDraw* debugDraw); - + void getClosestPointsNonVirtual(const ClosestPointInput& input, Result& output, class btIDebugDraw* debugDraw); void setMinkowskiA(const btConvexShape* minkA) { @@ -81,23 +73,21 @@ public: { return m_cachedSeparatingAxis; } - btScalar getCachedSeparatingDistance() const + btScalar getCachedSeparatingDistance() const { return m_cachedSeparatingDistance; } - void setPenetrationDepthSolver(btConvexPenetrationDepthSolver* penetrationDepthSolver) + void setPenetrationDepthSolver(btConvexPenetrationDepthSolver* penetrationDepthSolver) { m_penetrationDepthSolver = penetrationDepthSolver; } ///don't use setIgnoreMargin, it's for Bullet's internal use - void setIgnoreMargin(bool ignoreMargin) + void setIgnoreMargin(bool ignoreMargin) { m_ignoreMargin = ignoreMargin; } - - }; -#endif //BT_GJK_PAIR_DETECTOR_H +#endif //BT_GJK_PAIR_DETECTOR_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h b/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h index 571ad2c5f..6d21f6620 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h +++ b/src/BulletCollision/NarrowPhaseCollision/btManifoldPoint.h @@ -20,161 +20,152 @@ subject to the following restrictions: #include "LinearMath/btTransformUtil.h" #ifdef PFX_USE_FREE_VECTORMATH - #include "physics_effects/base_level/solver/pfx_constraint_row.h" +#include "physics_effects/base_level/solver/pfx_constraint_row.h" typedef sce::PhysicsEffects::PfxConstraintRow btConstraintRow; #else - // Don't change following order of parameters - ATTRIBUTE_ALIGNED16(struct) btConstraintRow { - btScalar m_normal[3]; - btScalar m_rhs; - btScalar m_jacDiagInv; - btScalar m_lowerLimit; - btScalar m_upperLimit; - btScalar m_accumImpulse; - }; - typedef btConstraintRow PfxConstraintRow; -#endif //PFX_USE_FREE_VECTORMATH +// Don't change following order of parameters +ATTRIBUTE_ALIGNED16(struct) +btConstraintRow +{ + btScalar m_normal[3]; + btScalar m_rhs; + btScalar m_jacDiagInv; + btScalar m_lowerLimit; + btScalar m_upperLimit; + btScalar m_accumImpulse; +}; +typedef btConstraintRow PfxConstraintRow; +#endif //PFX_USE_FREE_VECTORMATH enum btContactPointFlags { - BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED=1, - BT_CONTACT_FLAG_HAS_CONTACT_CFM=2, - BT_CONTACT_FLAG_HAS_CONTACT_ERP=4, - BT_CONTACT_FLAG_CONTACT_STIFFNESS_DAMPING = 8, + BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED = 1, + BT_CONTACT_FLAG_HAS_CONTACT_CFM = 2, + BT_CONTACT_FLAG_HAS_CONTACT_ERP = 4, + BT_CONTACT_FLAG_CONTACT_STIFFNESS_DAMPING = 8, BT_CONTACT_FLAG_FRICTION_ANCHOR = 16, }; /// ManifoldContactPoint collects and maintains persistent contactpoints. /// used to improve stability and performance of rigidbody dynamics response. class btManifoldPoint +{ +public: + btManifoldPoint() + : m_userPersistentData(0), + m_contactPointFlags(0), + m_appliedImpulse(0.f), + m_appliedImpulseLateral1(0.f), + m_appliedImpulseLateral2(0.f), + m_contactMotion1(0.f), + m_contactMotion2(0.f), + m_contactCFM(0.f), + m_contactERP(0.f), + m_frictionCFM(0.f), + m_lifeTime(0) { - public: - btManifoldPoint() - :m_userPersistentData(0), - m_contactPointFlags(0), - m_appliedImpulse(0.f), - m_appliedImpulseLateral1(0.f), - m_appliedImpulseLateral2(0.f), - m_contactMotion1(0.f), - m_contactMotion2(0.f), - m_contactCFM(0.f), - m_contactERP(0.f), - m_frictionCFM(0.f), - m_lifeTime(0) - { - } + } - btManifoldPoint( const btVector3 &pointA, const btVector3 &pointB, - const btVector3 &normal, - btScalar distance ) : - m_localPointA( pointA ), - m_localPointB( pointB ), - m_normalWorldOnB( normal ), - m_distance1( distance ), - m_combinedFriction(btScalar(0.)), - m_combinedRollingFriction(btScalar(0.)), - m_combinedSpinningFriction(btScalar(0.)), - m_combinedRestitution(btScalar(0.)), - m_userPersistentData(0), - m_contactPointFlags(0), - m_appliedImpulse(0.f), - m_appliedImpulseLateral1(0.f), - m_appliedImpulseLateral2(0.f), - m_contactMotion1(0.f), - m_contactMotion2(0.f), - m_contactCFM(0.f), - m_contactERP(0.f), - m_frictionCFM(0.f), - m_lifeTime(0) - { - - } + btManifoldPoint(const btVector3& pointA, const btVector3& pointB, + const btVector3& normal, + btScalar distance) : m_localPointA(pointA), + m_localPointB(pointB), + m_normalWorldOnB(normal), + m_distance1(distance), + m_combinedFriction(btScalar(0.)), + m_combinedRollingFriction(btScalar(0.)), + m_combinedSpinningFriction(btScalar(0.)), + m_combinedRestitution(btScalar(0.)), + m_userPersistentData(0), + m_contactPointFlags(0), + m_appliedImpulse(0.f), + m_appliedImpulseLateral1(0.f), + m_appliedImpulseLateral2(0.f), + m_contactMotion1(0.f), + m_contactMotion2(0.f), + m_contactCFM(0.f), + m_contactERP(0.f), + m_frictionCFM(0.f), + m_lifeTime(0) + { + } - + btVector3 m_localPointA; + btVector3 m_localPointB; + btVector3 m_positionWorldOnB; + ///m_positionWorldOnA is redundant information, see getPositionWorldOnA(), but for clarity + btVector3 m_positionWorldOnA; + btVector3 m_normalWorldOnB; - btVector3 m_localPointA; - btVector3 m_localPointB; - btVector3 m_positionWorldOnB; - ///m_positionWorldOnA is redundant information, see getPositionWorldOnA(), but for clarity - btVector3 m_positionWorldOnA; - btVector3 m_normalWorldOnB; - - btScalar m_distance1; - btScalar m_combinedFriction; - btScalar m_combinedRollingFriction;//torsional friction orthogonal to contact normal, useful to make spheres stop rolling forever - btScalar m_combinedSpinningFriction;//torsional friction around contact normal, useful for grasping objects - btScalar m_combinedRestitution; + btScalar m_distance1; + btScalar m_combinedFriction; + btScalar m_combinedRollingFriction; //torsional friction orthogonal to contact normal, useful to make spheres stop rolling forever + btScalar m_combinedSpinningFriction; //torsional friction around contact normal, useful for grasping objects + btScalar m_combinedRestitution; - //BP mod, store contact triangles. - int m_partId0; - int m_partId1; - int m_index0; - int m_index1; - - mutable void* m_userPersistentData; - //bool m_lateralFrictionInitialized; - int m_contactPointFlags; - - btScalar m_appliedImpulse; - btScalar m_appliedImpulseLateral1; - btScalar m_appliedImpulseLateral2; - btScalar m_contactMotion1; - btScalar m_contactMotion2; - - union - { - btScalar m_contactCFM; - btScalar m_combinedContactStiffness1; - }; - - union - { - btScalar m_contactERP; - btScalar m_combinedContactDamping1; - }; + //BP mod, store contact triangles. + int m_partId0; + int m_partId1; + int m_index0; + int m_index1; - btScalar m_frictionCFM; + mutable void* m_userPersistentData; + //bool m_lateralFrictionInitialized; + int m_contactPointFlags; - int m_lifeTime;//lifetime of the contactpoint in frames - - btVector3 m_lateralFrictionDir1; - btVector3 m_lateralFrictionDir2; - - - - - btScalar getDistance() const - { - return m_distance1; - } - int getLifeTime() const - { - return m_lifeTime; - } - - const btVector3& getPositionWorldOnA() const { - return m_positionWorldOnA; -// return m_positionWorldOnB + m_normalWorldOnB * m_distance1; - } - - const btVector3& getPositionWorldOnB() const - { - return m_positionWorldOnB; - } - - void setDistance(btScalar dist) - { - m_distance1 = dist; - } - - ///this returns the most recent applied impulse, to satisfy contact constraints by the constraint solver - btScalar getAppliedImpulse() const - { - return m_appliedImpulse; - } - - + btScalar m_appliedImpulse; + btScalar m_appliedImpulseLateral1; + btScalar m_appliedImpulseLateral2; + btScalar m_contactMotion1; + btScalar m_contactMotion2; + union { + btScalar m_contactCFM; + btScalar m_combinedContactStiffness1; }; -#endif //BT_MANIFOLD_CONTACT_POINT_H + union { + btScalar m_contactERP; + btScalar m_combinedContactDamping1; + }; + + btScalar m_frictionCFM; + + int m_lifeTime; //lifetime of the contactpoint in frames + + btVector3 m_lateralFrictionDir1; + btVector3 m_lateralFrictionDir2; + + btScalar getDistance() const + { + return m_distance1; + } + int getLifeTime() const + { + return m_lifeTime; + } + + const btVector3& getPositionWorldOnA() const + { + return m_positionWorldOnA; + // return m_positionWorldOnB + m_normalWorldOnB * m_distance1; + } + + const btVector3& getPositionWorldOnB() const + { + return m_positionWorldOnB; + } + + void setDistance(btScalar dist) + { + m_distance1 = dist; + } + + ///this returns the most recent applied impulse, to satisfy contact constraints by the constraint solver + btScalar getAppliedImpulse() const + { + return m_appliedImpulse; + } +}; + +#endif //BT_MANIFOLD_CONTACT_POINT_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp b/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp index fa45f4903..a77449812 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp +++ b/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.cpp @@ -21,42 +21,38 @@ subject to the following restrictions: #define NUM_UNITSPHERE_POINTS 42 - bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& simplexSolver, - const btConvexShape* convexA,const btConvexShape* convexB, - const btTransform& transA,const btTransform& transB, - btVector3& v, btVector3& pa, btVector3& pb, - class btIDebugDraw* debugDraw - ) + const btConvexShape* convexA, const btConvexShape* convexB, + const btTransform& transA, const btTransform& transB, + btVector3& v, btVector3& pa, btVector3& pb, + class btIDebugDraw* debugDraw) { - (void)v; - - bool check2d= convexA->isConvex2d() && convexB->isConvex2d(); + + bool check2d = convexA->isConvex2d() && convexB->isConvex2d(); struct btIntermediateResult : public btDiscreteCollisionDetectorInterface::Result { - - btIntermediateResult():m_hasResult(false) + btIntermediateResult() : m_hasResult(false) { } - + btVector3 m_normalOnBInWorld; btVector3 m_pointInWorld; btScalar m_depth; - bool m_hasResult; + bool m_hasResult; - virtual void setShapeIdentifiersA(int partId0,int index0) + virtual void setShapeIdentifiersA(int partId0, int index0) { (void)partId0; (void)index0; } - virtual void setShapeIdentifiersB(int partId1,int index1) + virtual void setShapeIdentifiersB(int partId1, int index1) { (void)partId1; (void)index1; } - void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth) + void addContactPoint(const btVector3& normalOnBInWorld, const btVector3& pointInWorld, btScalar depth) { m_normalOnBInWorld = normalOnBInWorld; m_pointInWorld = pointInWorld; @@ -68,39 +64,39 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s //just take fixed number of orientation, and sample the penetration depth in that direction btScalar minProj = btScalar(BT_LARGE_FLOAT); btVector3 minNorm(btScalar(0.), btScalar(0.), btScalar(0.)); - btVector3 minA,minB; - btVector3 seperatingAxisInA,seperatingAxisInB; - btVector3 pInA,qInB,pWorld,qWorld,w; + btVector3 minA, minB; + btVector3 seperatingAxisInA, seperatingAxisInB; + btVector3 pInA, qInB, pWorld, qWorld, w; #ifndef __SPU__ #define USE_BATCHED_SUPPORT 1 #endif #ifdef USE_BATCHED_SUPPORT - btVector3 supportVerticesABatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; - btVector3 supportVerticesBBatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; - btVector3 seperatingAxisInABatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; - btVector3 seperatingAxisInBBatch[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2]; + btVector3 supportVerticesABatch[NUM_UNITSPHERE_POINTS + MAX_PREFERRED_PENETRATION_DIRECTIONS * 2]; + btVector3 supportVerticesBBatch[NUM_UNITSPHERE_POINTS + MAX_PREFERRED_PENETRATION_DIRECTIONS * 2]; + btVector3 seperatingAxisInABatch[NUM_UNITSPHERE_POINTS + MAX_PREFERRED_PENETRATION_DIRECTIONS * 2]; + btVector3 seperatingAxisInBBatch[NUM_UNITSPHERE_POINTS + MAX_PREFERRED_PENETRATION_DIRECTIONS * 2]; int i; int numSampleDirections = NUM_UNITSPHERE_POINTS; - for (i=0;igetNumPreferredPenetrationDirections(); if (numPDA) { - for (int i=0;igetPreferredPenetrationDirection(i,norm); - norm = transA.getBasis() * norm; + convexA->getPreferredPenetrationDirection(i, norm); + norm = transA.getBasis() * norm; getPenetrationDirections()[numSampleDirections] = norm; seperatingAxisInABatch[numSampleDirections] = (-norm) * transA.getBasis(); seperatingAxisInBBatch[numSampleDirections] = norm * transB.getBasis(); @@ -113,11 +109,11 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s int numPDB = convexB->getNumPreferredPenetrationDirections(); if (numPDB) { - for (int i=0;igetPreferredPenetrationDirection(i,norm); - norm = transB.getBasis() * norm; + convexB->getPreferredPenetrationDirection(i, norm); + norm = transB.getBasis() * norm; getPenetrationDirections()[numSampleDirections] = norm; seperatingAxisInABatch[numSampleDirections] = (-norm) * transA.getBasis(); seperatingAxisInBBatch[numSampleDirections] = norm * transB.getBasis(); @@ -126,29 +122,25 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s } } + convexA->batchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInABatch, supportVerticesABatch, numSampleDirections); + convexB->batchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInBBatch, supportVerticesBBatch, numSampleDirections); - - - convexA->batchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInABatch,supportVerticesABatch,numSampleDirections); - convexB->batchedUnitVectorGetSupportingVertexWithoutMargin(seperatingAxisInBBatch,supportVerticesBBatch,numSampleDirections); - - for (i=0;i0.01) + if (norm.length2() > 0.01) { - seperatingAxisInA = seperatingAxisInABatch[i]; seperatingAxisInB = seperatingAxisInBBatch[i]; pInA = supportVerticesABatch[i]; qInB = supportVerticesBBatch[i]; - pWorld = transA(pInA); + pWorld = transA(pInA); qWorld = transB(qInB); if (check2d) { @@ -156,7 +148,7 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s qWorld[2] = 0.f; } - w = qWorld - pWorld; + w = qWorld - pWorld; btScalar delta = norm.dot(w); //find smallest delta if (delta < minProj) @@ -167,7 +159,7 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s minB = qWorld; } } - } + } #else int numSampleDirections = NUM_UNITSPHERE_POINTS; @@ -177,11 +169,11 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s int numPDA = convexA->getNumPreferredPenetrationDirections(); if (numPDA) { - for (int i=0;igetPreferredPenetrationDirection(i,norm); - norm = transA.getBasis() * norm; + convexA->getPreferredPenetrationDirection(i, norm); + norm = transA.getBasis() * norm; getPenetrationDirections()[numSampleDirections] = norm; numSampleDirections++; } @@ -192,28 +184,28 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s int numPDB = convexB->getNumPreferredPenetrationDirections(); if (numPDB) { - for (int i=0;igetPreferredPenetrationDirection(i,norm); - norm = transB.getBasis() * norm; + convexB->getPreferredPenetrationDirection(i, norm); + norm = transB.getBasis() * norm; getPenetrationDirections()[numSampleDirections] = norm; numSampleDirections++; } } } -#endif // __SPU__ +#endif // __SPU__ - for (int i=0;ilocalGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInA); qInB = convexB->localGetSupportVertexWithoutMarginNonVirtual(seperatingAxisInB); - pWorld = transA(pInA); + pWorld = transA(pInA); qWorld = transB(qInB); - w = qWorld - pWorld; + w = qWorld - pWorld; btScalar delta = norm.dot(w); //find smallest delta if (delta < minProj) @@ -224,48 +216,39 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s minB = qWorld; } } -#endif //USE_BATCHED_SUPPORT +#endif //USE_BATCHED_SUPPORT //add the margins - minA += minNorm*convexA->getMarginNonVirtual(); - minB -= minNorm*convexB->getMarginNonVirtual(); + minA += minNorm * convexA->getMarginNonVirtual(); + minB -= minNorm * convexB->getMarginNonVirtual(); //no penetration if (minProj < btScalar(0.)) return false; - btScalar extraSeparation = 0.5f;///scale dependent - minProj += extraSeparation+(convexA->getMarginNonVirtual() + convexB->getMarginNonVirtual()); - - - - + btScalar extraSeparation = 0.5f; ///scale dependent + minProj += extraSeparation + (convexA->getMarginNonVirtual() + convexB->getMarginNonVirtual()); //#define DEBUG_DRAW 1 #ifdef DEBUG_DRAW if (debugDraw) { - btVector3 color(0,1,0); - debugDraw->drawLine(minA,minB,color); - color = btVector3 (1,1,1); - btVector3 vec = minB-minA; + btVector3 color(0, 1, 0); + debugDraw->drawLine(minA, minB, color); + color = btVector3(1, 1, 1); + btVector3 vec = minB - minA; btScalar prj2 = minNorm.dot(vec); - debugDraw->drawLine(minA,minA+(minNorm*minProj),color); - + debugDraw->drawLine(minA, minA + (minNorm * minProj), color); } -#endif //DEBUG_DRAW +#endif //DEBUG_DRAW - - - btGjkPairDetector gjkdet(convexA,convexB,&simplexSolver,0); + btGjkPairDetector gjkdet(convexA, convexB, &simplexSolver, 0); btScalar offsetDist = minProj; btVector3 offset = minNorm * offsetDist; - - btGjkPairDetector::ClosestPointInput input; - + btVector3 newOrg = transA.getOrigin() + offset; btTransform displacedTrans = transA; @@ -273,89 +256,81 @@ bool btMinkowskiPenetrationDepthSolver::calcPenDepth(btSimplexSolverInterface& s input.m_transformA = displacedTrans; input.m_transformB = transB; - input.m_maximumDistanceSquared = btScalar(BT_LARGE_FLOAT);//minProj; - + input.m_maximumDistanceSquared = btScalar(BT_LARGE_FLOAT); //minProj; + btIntermediateResult res; gjkdet.setCachedSeperatingAxis(-minNorm); - gjkdet.getClosestPoints(input,res,debugDraw); + gjkdet.getClosestPoints(input, res, debugDraw); btScalar correctedMinNorm = minProj - res.m_depth; - //the penetration depth is over-estimated, relax it - btScalar penetration_relaxation= btScalar(1.); - minNorm*=penetration_relaxation; - + btScalar penetration_relaxation = btScalar(1.); + minNorm *= penetration_relaxation; if (res.m_hasResult) { - pa = res.m_pointInWorld - minNorm * correctedMinNorm; pb = res.m_pointInWorld; v = minNorm; - + #ifdef DEBUG_DRAW if (debugDraw) { - btVector3 color(1,0,0); - debugDraw->drawLine(pa,pb,color); + btVector3 color(1, 0, 0); + debugDraw->drawLine(pa, pb, color); } -#endif//DEBUG_DRAW - - +#endif //DEBUG_DRAW } return res.m_hasResult; } -btVector3* btMinkowskiPenetrationDepthSolver::getPenetrationDirections() +btVector3* btMinkowskiPenetrationDepthSolver::getPenetrationDirections() { - static btVector3 sPenetrationDirections[NUM_UNITSPHERE_POINTS+MAX_PREFERRED_PENETRATION_DIRECTIONS*2] = - { - btVector3(btScalar(0.000000) , btScalar(-0.000000),btScalar(-1.000000)), - btVector3(btScalar(0.723608) , btScalar(-0.525725),btScalar(-0.447219)), - btVector3(btScalar(-0.276388) , btScalar(-0.850649),btScalar(-0.447219)), - btVector3(btScalar(-0.894426) , btScalar(-0.000000),btScalar(-0.447216)), - btVector3(btScalar(-0.276388) , btScalar(0.850649),btScalar(-0.447220)), - btVector3(btScalar(0.723608) , btScalar(0.525725),btScalar(-0.447219)), - btVector3(btScalar(0.276388) , btScalar(-0.850649),btScalar(0.447220)), - btVector3(btScalar(-0.723608) , btScalar(-0.525725),btScalar(0.447219)), - btVector3(btScalar(-0.723608) , btScalar(0.525725),btScalar(0.447219)), - btVector3(btScalar(0.276388) , btScalar(0.850649),btScalar(0.447219)), - btVector3(btScalar(0.894426) , btScalar(0.000000),btScalar(0.447216)), - btVector3(btScalar(-0.000000) , btScalar(0.000000),btScalar(1.000000)), - btVector3(btScalar(0.425323) , btScalar(-0.309011),btScalar(-0.850654)), - btVector3(btScalar(-0.162456) , btScalar(-0.499995),btScalar(-0.850654)), - btVector3(btScalar(0.262869) , btScalar(-0.809012),btScalar(-0.525738)), - btVector3(btScalar(0.425323) , btScalar(0.309011),btScalar(-0.850654)), - btVector3(btScalar(0.850648) , btScalar(-0.000000),btScalar(-0.525736)), - btVector3(btScalar(-0.525730) , btScalar(-0.000000),btScalar(-0.850652)), - btVector3(btScalar(-0.688190) , btScalar(-0.499997),btScalar(-0.525736)), - btVector3(btScalar(-0.162456) , btScalar(0.499995),btScalar(-0.850654)), - btVector3(btScalar(-0.688190) , btScalar(0.499997),btScalar(-0.525736)), - btVector3(btScalar(0.262869) , btScalar(0.809012),btScalar(-0.525738)), - btVector3(btScalar(0.951058) , btScalar(0.309013),btScalar(0.000000)), - btVector3(btScalar(0.951058) , btScalar(-0.309013),btScalar(0.000000)), - btVector3(btScalar(0.587786) , btScalar(-0.809017),btScalar(0.000000)), - btVector3(btScalar(0.000000) , btScalar(-1.000000),btScalar(0.000000)), - btVector3(btScalar(-0.587786) , btScalar(-0.809017),btScalar(0.000000)), - btVector3(btScalar(-0.951058) , btScalar(-0.309013),btScalar(-0.000000)), - btVector3(btScalar(-0.951058) , btScalar(0.309013),btScalar(-0.000000)), - btVector3(btScalar(-0.587786) , btScalar(0.809017),btScalar(-0.000000)), - btVector3(btScalar(-0.000000) , btScalar(1.000000),btScalar(-0.000000)), - btVector3(btScalar(0.587786) , btScalar(0.809017),btScalar(-0.000000)), - btVector3(btScalar(0.688190) , btScalar(-0.499997),btScalar(0.525736)), - btVector3(btScalar(-0.262869) , btScalar(-0.809012),btScalar(0.525738)), - btVector3(btScalar(-0.850648) , btScalar(0.000000),btScalar(0.525736)), - btVector3(btScalar(-0.262869) , btScalar(0.809012),btScalar(0.525738)), - btVector3(btScalar(0.688190) , btScalar(0.499997),btScalar(0.525736)), - btVector3(btScalar(0.525730) , btScalar(0.000000),btScalar(0.850652)), - btVector3(btScalar(0.162456) , btScalar(-0.499995),btScalar(0.850654)), - btVector3(btScalar(-0.425323) , btScalar(-0.309011),btScalar(0.850654)), - btVector3(btScalar(-0.425323) , btScalar(0.309011),btScalar(0.850654)), - btVector3(btScalar(0.162456) , btScalar(0.499995),btScalar(0.850654)) - }; + static btVector3 sPenetrationDirections[NUM_UNITSPHERE_POINTS + MAX_PREFERRED_PENETRATION_DIRECTIONS * 2] = + { + btVector3(btScalar(0.000000), btScalar(-0.000000), btScalar(-1.000000)), + btVector3(btScalar(0.723608), btScalar(-0.525725), btScalar(-0.447219)), + btVector3(btScalar(-0.276388), btScalar(-0.850649), btScalar(-0.447219)), + btVector3(btScalar(-0.894426), btScalar(-0.000000), btScalar(-0.447216)), + btVector3(btScalar(-0.276388), btScalar(0.850649), btScalar(-0.447220)), + btVector3(btScalar(0.723608), btScalar(0.525725), btScalar(-0.447219)), + btVector3(btScalar(0.276388), btScalar(-0.850649), btScalar(0.447220)), + btVector3(btScalar(-0.723608), btScalar(-0.525725), btScalar(0.447219)), + btVector3(btScalar(-0.723608), btScalar(0.525725), btScalar(0.447219)), + btVector3(btScalar(0.276388), btScalar(0.850649), btScalar(0.447219)), + btVector3(btScalar(0.894426), btScalar(0.000000), btScalar(0.447216)), + btVector3(btScalar(-0.000000), btScalar(0.000000), btScalar(1.000000)), + btVector3(btScalar(0.425323), btScalar(-0.309011), btScalar(-0.850654)), + btVector3(btScalar(-0.162456), btScalar(-0.499995), btScalar(-0.850654)), + btVector3(btScalar(0.262869), btScalar(-0.809012), btScalar(-0.525738)), + btVector3(btScalar(0.425323), btScalar(0.309011), btScalar(-0.850654)), + btVector3(btScalar(0.850648), btScalar(-0.000000), btScalar(-0.525736)), + btVector3(btScalar(-0.525730), btScalar(-0.000000), btScalar(-0.850652)), + btVector3(btScalar(-0.688190), btScalar(-0.499997), btScalar(-0.525736)), + btVector3(btScalar(-0.162456), btScalar(0.499995), btScalar(-0.850654)), + btVector3(btScalar(-0.688190), btScalar(0.499997), btScalar(-0.525736)), + btVector3(btScalar(0.262869), btScalar(0.809012), btScalar(-0.525738)), + btVector3(btScalar(0.951058), btScalar(0.309013), btScalar(0.000000)), + btVector3(btScalar(0.951058), btScalar(-0.309013), btScalar(0.000000)), + btVector3(btScalar(0.587786), btScalar(-0.809017), btScalar(0.000000)), + btVector3(btScalar(0.000000), btScalar(-1.000000), btScalar(0.000000)), + btVector3(btScalar(-0.587786), btScalar(-0.809017), btScalar(0.000000)), + btVector3(btScalar(-0.951058), btScalar(-0.309013), btScalar(-0.000000)), + btVector3(btScalar(-0.951058), btScalar(0.309013), btScalar(-0.000000)), + btVector3(btScalar(-0.587786), btScalar(0.809017), btScalar(-0.000000)), + btVector3(btScalar(-0.000000), btScalar(1.000000), btScalar(-0.000000)), + btVector3(btScalar(0.587786), btScalar(0.809017), btScalar(-0.000000)), + btVector3(btScalar(0.688190), btScalar(-0.499997), btScalar(0.525736)), + btVector3(btScalar(-0.262869), btScalar(-0.809012), btScalar(0.525738)), + btVector3(btScalar(-0.850648), btScalar(0.000000), btScalar(0.525736)), + btVector3(btScalar(-0.262869), btScalar(0.809012), btScalar(0.525738)), + btVector3(btScalar(0.688190), btScalar(0.499997), btScalar(0.525736)), + btVector3(btScalar(0.525730), btScalar(0.000000), btScalar(0.850652)), + btVector3(btScalar(0.162456), btScalar(-0.499995), btScalar(0.850654)), + btVector3(btScalar(-0.425323), btScalar(-0.309011), btScalar(0.850654)), + btVector3(btScalar(-0.425323), btScalar(0.309011), btScalar(0.850654)), + btVector3(btScalar(0.162456), btScalar(0.499995), btScalar(0.850654))}; return sPenetrationDirections; } - - diff --git a/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h b/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h index fd533b4fc..8e3e39325 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h +++ b/src/BulletCollision/NarrowPhaseCollision/btMinkowskiPenetrationDepthSolver.h @@ -23,18 +23,14 @@ subject to the following restrictions: class btMinkowskiPenetrationDepthSolver : public btConvexPenetrationDepthSolver { protected: - - static btVector3* getPenetrationDirections(); + static btVector3* getPenetrationDirections(); public: - - virtual bool calcPenDepth( btSimplexSolverInterface& simplexSolver, - const btConvexShape* convexA,const btConvexShape* convexB, - const btTransform& transA,const btTransform& transB, - btVector3& v, btVector3& pa, btVector3& pb, - class btIDebugDraw* debugDraw - ); + virtual bool calcPenDepth(btSimplexSolverInterface& simplexSolver, + const btConvexShape* convexA, const btConvexShape* convexB, + const btTransform& transA, const btTransform& transB, + btVector3& v, btVector3& pa, btVector3& pb, + class btIDebugDraw* debugDraw); }; -#endif //BT_MINKOWSKI_PENETRATION_DEPTH_SOLVER_H - +#endif //BT_MINKOWSKI_PENETRATION_DEPTH_SOLVER_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btMprPenetration.h b/src/BulletCollision/NarrowPhaseCollision/btMprPenetration.h index 052f48b8c..ea946e2da 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btMprPenetration.h +++ b/src/BulletCollision/NarrowPhaseCollision/btMprPenetration.h @@ -28,32 +28,31 @@ //#define MPR_AVERAGE_CONTACT_POSITIONS - struct btMprCollisionDescription { - btVector3 m_firstDir; - int m_maxGjkIterations; - btScalar m_maximumDistanceSquared; - btScalar m_gjkRelError2; - - btMprCollisionDescription() - : m_firstDir(0,1,0), - m_maxGjkIterations(1000), - m_maximumDistanceSquared(1e30f), - m_gjkRelError2(1.0e-6) - { - } - virtual ~btMprCollisionDescription() - { - } + btVector3 m_firstDir; + int m_maxGjkIterations; + btScalar m_maximumDistanceSquared; + btScalar m_gjkRelError2; + + btMprCollisionDescription() + : m_firstDir(0, 1, 0), + m_maxGjkIterations(1000), + m_maximumDistanceSquared(1e30f), + m_gjkRelError2(1.0e-6) + { + } + virtual ~btMprCollisionDescription() + { + } }; struct btMprDistanceInfo { - btVector3 m_pointOnA; - btVector3 m_pointOnB; - btVector3 m_normalBtoA; - btScalar m_distance; + btVector3 m_pointOnA; + btVector3 m_pointOnB; + btVector3 m_normalBtoA; + btScalar m_distance; }; #ifdef __cplusplus @@ -67,131 +66,112 @@ struct btMprDistanceInfo #define BT_MPR_TOLERANCE 1E-6f #define BT_MPR_MAX_ITERATIONS 1000 -struct _btMprSupport_t +struct _btMprSupport_t { - btVector3 v; //!< Support point in minkowski sum - btVector3 v1; //!< Support point in obj1 - btVector3 v2; //!< Support point in obj2 + btVector3 v; //!< Support point in minkowski sum + btVector3 v1; //!< Support point in obj1 + btVector3 v2; //!< Support point in obj2 }; typedef struct _btMprSupport_t btMprSupport_t; -struct _btMprSimplex_t +struct _btMprSimplex_t { - btMprSupport_t ps[4]; - int last; //!< index of last added point + btMprSupport_t ps[4]; + int last; //!< index of last added point }; typedef struct _btMprSimplex_t btMprSimplex_t; -inline btMprSupport_t* btMprSimplexPointW(btMprSimplex_t *s, int idx) +inline btMprSupport_t *btMprSimplexPointW(btMprSimplex_t *s, int idx) { - return &s->ps[idx]; + return &s->ps[idx]; } inline void btMprSimplexSetSize(btMprSimplex_t *s, int size) { - s->last = size - 1; + s->last = size - 1; } #ifdef DEBUG_MPR -inline void btPrintPortalVertex(_btMprSimplex_t* portal, int index) +inline void btPrintPortalVertex(_btMprSimplex_t *portal, int index) { - printf("portal[%d].v = %f,%f,%f, v1=%f,%f,%f, v2=%f,%f,%f\n", index, portal->ps[index].v.x(),portal->ps[index].v.y(),portal->ps[index].v.z(), - portal->ps[index].v1.x(),portal->ps[index].v1.y(),portal->ps[index].v1.z(), - portal->ps[index].v2.x(),portal->ps[index].v2.y(),portal->ps[index].v2.z()); + printf("portal[%d].v = %f,%f,%f, v1=%f,%f,%f, v2=%f,%f,%f\n", index, portal->ps[index].v.x(), portal->ps[index].v.y(), portal->ps[index].v.z(), + portal->ps[index].v1.x(), portal->ps[index].v1.y(), portal->ps[index].v1.z(), + portal->ps[index].v2.x(), portal->ps[index].v2.y(), portal->ps[index].v2.z()); } -#endif //DEBUG_MPR - - - +#endif //DEBUG_MPR inline int btMprSimplexSize(const btMprSimplex_t *s) { - return s->last + 1; + return s->last + 1; } - -inline const btMprSupport_t* btMprSimplexPoint(const btMprSimplex_t* s, int idx) +inline const btMprSupport_t *btMprSimplexPoint(const btMprSimplex_t *s, int idx) { - // here is no check on boundaries - return &s->ps[idx]; + // here is no check on boundaries + return &s->ps[idx]; } inline void btMprSupportCopy(btMprSupport_t *d, const btMprSupport_t *s) { - *d = *s; + *d = *s; } inline void btMprSimplexSet(btMprSimplex_t *s, size_t pos, const btMprSupport_t *a) { - btMprSupportCopy(s->ps + pos, a); + btMprSupportCopy(s->ps + pos, a); } - inline void btMprSimplexSwap(btMprSimplex_t *s, size_t pos1, size_t pos2) { - btMprSupport_t supp; + btMprSupport_t supp; - btMprSupportCopy(&supp, &s->ps[pos1]); - btMprSupportCopy(&s->ps[pos1], &s->ps[pos2]); - btMprSupportCopy(&s->ps[pos2], &supp); + btMprSupportCopy(&supp, &s->ps[pos1]); + btMprSupportCopy(&s->ps[pos1], &s->ps[pos2]); + btMprSupportCopy(&s->ps[pos2], &supp); } - inline int btMprIsZero(float val) { - return BT_MPR_FABS(val) < FLT_EPSILON; + return BT_MPR_FABS(val) < FLT_EPSILON; } - - inline int btMprEq(float _a, float _b) { - float ab; - float a, b; + float ab; + float a, b; - ab = BT_MPR_FABS(_a - _b); - if (BT_MPR_FABS(ab) < FLT_EPSILON) - return 1; + ab = BT_MPR_FABS(_a - _b); + if (BT_MPR_FABS(ab) < FLT_EPSILON) + return 1; - a = BT_MPR_FABS(_a); - b = BT_MPR_FABS(_b); - if (b > a){ - return ab < FLT_EPSILON * b; - }else{ - return ab < FLT_EPSILON * a; - } + a = BT_MPR_FABS(_a); + b = BT_MPR_FABS(_b); + if (b > a) + { + return ab < FLT_EPSILON * b; + } + else + { + return ab < FLT_EPSILON * a; + } } - -inline int btMprVec3Eq(const btVector3* a, const btVector3 *b) +inline int btMprVec3Eq(const btVector3 *a, const btVector3 *b) { - return btMprEq((*a).x(), (*b).x()) - && btMprEq((*a).y(), (*b).y()) - && btMprEq((*a).z(), (*b).z()); + return btMprEq((*a).x(), (*b).x()) && btMprEq((*a).y(), (*b).y()) && btMprEq((*a).z(), (*b).z()); } - - - - - - - - - - template -inline void btFindOrigin(const btConvexTemplate& a, const btConvexTemplate& b, const btMprCollisionDescription& colDesc,btMprSupport_t *center) +inline void btFindOrigin(const btConvexTemplate &a, const btConvexTemplate &b, const btMprCollisionDescription &colDesc, btMprSupport_t *center) { - center->v1 = a.getObjectCenterInWorld(); - center->v2 = b.getObjectCenterInWorld(); - center->v = center->v1 - center->v2; + center->v2 = b.getObjectCenterInWorld(); + center->v = center->v1 - center->v2; } inline void btMprVec3Set(btVector3 *v, float x, float y, float z) { - v->setValue(x,y,z); + v->setValue(x, y, z); } inline void btMprVec3Add(btVector3 *v, const btVector3 *w) @@ -201,41 +181,38 @@ inline void btMprVec3Add(btVector3 *v, const btVector3 *w) inline void btMprVec3Copy(btVector3 *v, const btVector3 *w) { - *v = *w; + *v = *w; } inline void btMprVec3Scale(btVector3 *d, float k) { - *d *= k; + *d *= k; } inline float btMprVec3Dot(const btVector3 *a, const btVector3 *b) { - float dot; + float dot; - dot = btDot(*a,*b); - return dot; + dot = btDot(*a, *b); + return dot; } - inline float btMprVec3Len2(const btVector3 *v) { - return btMprVec3Dot(v, v); + return btMprVec3Dot(v, v); } inline void btMprVec3Normalize(btVector3 *d) { - float k = 1.f / BT_MPR_SQRT(btMprVec3Len2(d)); - btMprVec3Scale(d, k); + float k = 1.f / BT_MPR_SQRT(btMprVec3Len2(d)); + btMprVec3Scale(d, k); } inline void btMprVec3Cross(btVector3 *d, const btVector3 *a, const btVector3 *b) { - *d = btCross(*a,*b); - + *d = btCross(*a, *b); } - inline void btMprVec3Sub2(btVector3 *d, const btVector3 *v, const btVector3 *w) { *d = *v - *w; @@ -243,89 +220,97 @@ inline void btMprVec3Sub2(btVector3 *d, const btVector3 *v, const btVector3 *w) inline void btPortalDir(const btMprSimplex_t *portal, btVector3 *dir) { - btVector3 v2v1, v3v1; + btVector3 v2v1, v3v1; - btMprVec3Sub2(&v2v1, &btMprSimplexPoint(portal, 2)->v, - &btMprSimplexPoint(portal, 1)->v); - btMprVec3Sub2(&v3v1, &btMprSimplexPoint(portal, 3)->v, - &btMprSimplexPoint(portal, 1)->v); - btMprVec3Cross(dir, &v2v1, &v3v1); - btMprVec3Normalize(dir); + btMprVec3Sub2(&v2v1, &btMprSimplexPoint(portal, 2)->v, + &btMprSimplexPoint(portal, 1)->v); + btMprVec3Sub2(&v3v1, &btMprSimplexPoint(portal, 3)->v, + &btMprSimplexPoint(portal, 1)->v); + btMprVec3Cross(dir, &v2v1, &v3v1); + btMprVec3Normalize(dir); } - inline int portalEncapsulesOrigin(const btMprSimplex_t *portal, - const btVector3 *dir) + const btVector3 *dir) { - float dot; - dot = btMprVec3Dot(dir, &btMprSimplexPoint(portal, 1)->v); - return btMprIsZero(dot) || dot > 0.f; + float dot; + dot = btMprVec3Dot(dir, &btMprSimplexPoint(portal, 1)->v); + return btMprIsZero(dot) || dot > 0.f; } inline int portalReachTolerance(const btMprSimplex_t *portal, - const btMprSupport_t *v4, - const btVector3 *dir) + const btMprSupport_t *v4, + const btVector3 *dir) { - float dv1, dv2, dv3, dv4; - float dot1, dot2, dot3; + float dv1, dv2, dv3, dv4; + float dot1, dot2, dot3; - // find the smallest dot product of dir and {v1-v4, v2-v4, v3-v4} + // find the smallest dot product of dir and {v1-v4, v2-v4, v3-v4} - dv1 = btMprVec3Dot(&btMprSimplexPoint(portal, 1)->v, dir); - dv2 = btMprVec3Dot(&btMprSimplexPoint(portal, 2)->v, dir); - dv3 = btMprVec3Dot(&btMprSimplexPoint(portal, 3)->v, dir); - dv4 = btMprVec3Dot(&v4->v, dir); + dv1 = btMprVec3Dot(&btMprSimplexPoint(portal, 1)->v, dir); + dv2 = btMprVec3Dot(&btMprSimplexPoint(portal, 2)->v, dir); + dv3 = btMprVec3Dot(&btMprSimplexPoint(portal, 3)->v, dir); + dv4 = btMprVec3Dot(&v4->v, dir); - dot1 = dv4 - dv1; - dot2 = dv4 - dv2; - dot3 = dv4 - dv3; + dot1 = dv4 - dv1; + dot2 = dv4 - dv2; + dot3 = dv4 - dv3; - dot1 = BT_MPR_FMIN(dot1, dot2); - dot1 = BT_MPR_FMIN(dot1, dot3); + dot1 = BT_MPR_FMIN(dot1, dot2); + dot1 = BT_MPR_FMIN(dot1, dot3); - return btMprEq(dot1, BT_MPR_TOLERANCE) || dot1 < BT_MPR_TOLERANCE; + return btMprEq(dot1, BT_MPR_TOLERANCE) || dot1 < BT_MPR_TOLERANCE; } inline int portalCanEncapsuleOrigin(const btMprSimplex_t *portal, - const btMprSupport_t *v4, - const btVector3 *dir) + const btMprSupport_t *v4, + const btVector3 *dir) { - float dot; - dot = btMprVec3Dot(&v4->v, dir); - return btMprIsZero(dot) || dot > 0.f; + float dot; + dot = btMprVec3Dot(&v4->v, dir); + return btMprIsZero(dot) || dot > 0.f; } inline void btExpandPortal(btMprSimplex_t *portal, - const btMprSupport_t *v4) + const btMprSupport_t *v4) { - float dot; - btVector3 v4v0; + float dot; + btVector3 v4v0; - btMprVec3Cross(&v4v0, &v4->v, &btMprSimplexPoint(portal, 0)->v); - dot = btMprVec3Dot(&btMprSimplexPoint(portal, 1)->v, &v4v0); - if (dot > 0.f){ - dot = btMprVec3Dot(&btMprSimplexPoint(portal, 2)->v, &v4v0); - if (dot > 0.f){ - btMprSimplexSet(portal, 1, v4); - }else{ - btMprSimplexSet(portal, 3, v4); - } - }else{ - dot = btMprVec3Dot(&btMprSimplexPoint(portal, 3)->v, &v4v0); - if (dot > 0.f){ - btMprSimplexSet(portal, 2, v4); - }else{ - btMprSimplexSet(portal, 1, v4); - } - } + btMprVec3Cross(&v4v0, &v4->v, &btMprSimplexPoint(portal, 0)->v); + dot = btMprVec3Dot(&btMprSimplexPoint(portal, 1)->v, &v4v0); + if (dot > 0.f) + { + dot = btMprVec3Dot(&btMprSimplexPoint(portal, 2)->v, &v4v0); + if (dot > 0.f) + { + btMprSimplexSet(portal, 1, v4); + } + else + { + btMprSimplexSet(portal, 3, v4); + } + } + else + { + dot = btMprVec3Dot(&btMprSimplexPoint(portal, 3)->v, &v4v0); + if (dot > 0.f) + { + btMprSimplexSet(portal, 2, v4); + } + else + { + btMprSimplexSet(portal, 1, v4); + } + } } template -inline void btMprSupport(const btConvexTemplate& a, const btConvexTemplate& b, - const btMprCollisionDescription& colDesc, - const btVector3& dir, btMprSupport_t *supp) +inline void btMprSupport(const btConvexTemplate &a, const btConvexTemplate &b, + const btMprCollisionDescription &colDesc, + const btVector3 &dir, btMprSupport_t *supp) { - btVector3 seperatingAxisInA = dir* a.getWorldTransform().getBasis(); - btVector3 seperatingAxisInB = -dir* b.getWorldTransform().getBasis(); + btVector3 seperatingAxisInA = dir * a.getWorldTransform().getBasis(); + btVector3 seperatingAxisInB = -dir * b.getWorldTransform().getBasis(); btVector3 pInA = a.getLocalSupportWithMargin(seperatingAxisInA); btVector3 qInB = b.getLocalSupportWithMargin(seperatingAxisInB); @@ -335,574 +320,565 @@ inline void btMprSupport(const btConvexTemplate& a, const btConvexTemplate& b, supp->v = supp->v1 - supp->v2; } - template -static int btDiscoverPortal(const btConvexTemplate& a, const btConvexTemplate& b, - const btMprCollisionDescription& colDesc, - btMprSimplex_t *portal) +static int btDiscoverPortal(const btConvexTemplate &a, const btConvexTemplate &b, + const btMprCollisionDescription &colDesc, + btMprSimplex_t *portal) { - btVector3 dir, va, vb; - float dot; - int cont; - - + btVector3 dir, va, vb; + float dot; + int cont; - // vertex 0 is center of portal - btFindOrigin(a,b,colDesc, btMprSimplexPointW(portal, 0)); - - - // vertex 0 is center of portal - btMprSimplexSetSize(portal, 1); - + // vertex 0 is center of portal + btFindOrigin(a, b, colDesc, btMprSimplexPointW(portal, 0)); + // vertex 0 is center of portal + btMprSimplexSetSize(portal, 1); - btVector3 zero = btVector3(0,0,0); - btVector3* org = &zero; + btVector3 zero = btVector3(0, 0, 0); + btVector3 *org = &zero; - if (btMprVec3Eq(&btMprSimplexPoint(portal, 0)->v, org)){ - // Portal's center lies on origin (0,0,0) => we know that objects - // intersect but we would need to know penetration info. - // So move center little bit... - btMprVec3Set(&va, FLT_EPSILON * 10.f, 0.f, 0.f); - btMprVec3Add(&btMprSimplexPointW(portal, 0)->v, &va); - } + if (btMprVec3Eq(&btMprSimplexPoint(portal, 0)->v, org)) + { + // Portal's center lies on origin (0,0,0) => we know that objects + // intersect but we would need to know penetration info. + // So move center little bit... + btMprVec3Set(&va, FLT_EPSILON * 10.f, 0.f, 0.f); + btMprVec3Add(&btMprSimplexPointW(portal, 0)->v, &va); + } + // vertex 1 = support in direction of origin + btMprVec3Copy(&dir, &btMprSimplexPoint(portal, 0)->v); + btMprVec3Scale(&dir, -1.f); + btMprVec3Normalize(&dir); - // vertex 1 = support in direction of origin - btMprVec3Copy(&dir, &btMprSimplexPoint(portal, 0)->v); - btMprVec3Scale(&dir, -1.f); - btMprVec3Normalize(&dir); + btMprSupport(a, b, colDesc, dir, btMprSimplexPointW(portal, 1)); + btMprSimplexSetSize(portal, 2); - btMprSupport(a,b,colDesc, dir, btMprSimplexPointW(portal, 1)); - - btMprSimplexSetSize(portal, 2); + // test if origin isn't outside of v1 + dot = btMprVec3Dot(&btMprSimplexPoint(portal, 1)->v, &dir); - // test if origin isn't outside of v1 - dot = btMprVec3Dot(&btMprSimplexPoint(portal, 1)->v, &dir); - + if (btMprIsZero(dot) || dot < 0.f) + return -1; - if (btMprIsZero(dot) || dot < 0.f) - return -1; + // vertex 2 + btMprVec3Cross(&dir, &btMprSimplexPoint(portal, 0)->v, + &btMprSimplexPoint(portal, 1)->v); + if (btMprIsZero(btMprVec3Len2(&dir))) + { + if (btMprVec3Eq(&btMprSimplexPoint(portal, 1)->v, org)) + { + // origin lies on v1 + return 1; + } + else + { + // origin lies on v0-v1 segment + return 2; + } + } + btMprVec3Normalize(&dir); + btMprSupport(a, b, colDesc, dir, btMprSimplexPointW(portal, 2)); - // vertex 2 - btMprVec3Cross(&dir, &btMprSimplexPoint(portal, 0)->v, - &btMprSimplexPoint(portal, 1)->v); - if (btMprIsZero(btMprVec3Len2(&dir))){ - if (btMprVec3Eq(&btMprSimplexPoint(portal, 1)->v, org)){ - // origin lies on v1 - return 1; - }else{ - // origin lies on v0-v1 segment - return 2; - } - } + dot = btMprVec3Dot(&btMprSimplexPoint(portal, 2)->v, &dir); + if (btMprIsZero(dot) || dot < 0.f) + return -1; - btMprVec3Normalize(&dir); - btMprSupport(a,b,colDesc, dir, btMprSimplexPointW(portal, 2)); - - - - dot = btMprVec3Dot(&btMprSimplexPoint(portal, 2)->v, &dir); - if (btMprIsZero(dot) || dot < 0.f) - return -1; + btMprSimplexSetSize(portal, 3); - btMprSimplexSetSize(portal, 3); + // vertex 3 direction + btMprVec3Sub2(&va, &btMprSimplexPoint(portal, 1)->v, + &btMprSimplexPoint(portal, 0)->v); + btMprVec3Sub2(&vb, &btMprSimplexPoint(portal, 2)->v, + &btMprSimplexPoint(portal, 0)->v); + btMprVec3Cross(&dir, &va, &vb); + btMprVec3Normalize(&dir); - // vertex 3 direction - btMprVec3Sub2(&va, &btMprSimplexPoint(portal, 1)->v, - &btMprSimplexPoint(portal, 0)->v); - btMprVec3Sub2(&vb, &btMprSimplexPoint(portal, 2)->v, - &btMprSimplexPoint(portal, 0)->v); - btMprVec3Cross(&dir, &va, &vb); - btMprVec3Normalize(&dir); + // it is better to form portal faces to be oriented "outside" origin + dot = btMprVec3Dot(&dir, &btMprSimplexPoint(portal, 0)->v); + if (dot > 0.f) + { + btMprSimplexSwap(portal, 1, 2); + btMprVec3Scale(&dir, -1.f); + } - // it is better to form portal faces to be oriented "outside" origin - dot = btMprVec3Dot(&dir, &btMprSimplexPoint(portal, 0)->v); - if (dot > 0.f){ - btMprSimplexSwap(portal, 1, 2); - btMprVec3Scale(&dir, -1.f); - } + while (btMprSimplexSize(portal) < 4) + { + btMprSupport(a, b, colDesc, dir, btMprSimplexPointW(portal, 3)); - while (btMprSimplexSize(portal) < 4){ - btMprSupport(a,b,colDesc, dir, btMprSimplexPointW(portal, 3)); - - dot = btMprVec3Dot(&btMprSimplexPoint(portal, 3)->v, &dir); - if (btMprIsZero(dot) || dot < 0.f) - return -1; + dot = btMprVec3Dot(&btMprSimplexPoint(portal, 3)->v, &dir); + if (btMprIsZero(dot) || dot < 0.f) + return -1; - cont = 0; + cont = 0; - // test if origin is outside (v1, v0, v3) - set v2 as v3 and - // continue - btMprVec3Cross(&va, &btMprSimplexPoint(portal, 1)->v, - &btMprSimplexPoint(portal, 3)->v); - dot = btMprVec3Dot(&va, &btMprSimplexPoint(portal, 0)->v); - if (dot < 0.f && !btMprIsZero(dot)){ - btMprSimplexSet(portal, 2, btMprSimplexPoint(portal, 3)); - cont = 1; - } + // test if origin is outside (v1, v0, v3) - set v2 as v3 and + // continue + btMprVec3Cross(&va, &btMprSimplexPoint(portal, 1)->v, + &btMprSimplexPoint(portal, 3)->v); + dot = btMprVec3Dot(&va, &btMprSimplexPoint(portal, 0)->v); + if (dot < 0.f && !btMprIsZero(dot)) + { + btMprSimplexSet(portal, 2, btMprSimplexPoint(portal, 3)); + cont = 1; + } - if (!cont){ - // test if origin is outside (v3, v0, v2) - set v1 as v3 and - // continue - btMprVec3Cross(&va, &btMprSimplexPoint(portal, 3)->v, - &btMprSimplexPoint(portal, 2)->v); - dot = btMprVec3Dot(&va, &btMprSimplexPoint(portal, 0)->v); - if (dot < 0.f && !btMprIsZero(dot)){ - btMprSimplexSet(portal, 1, btMprSimplexPoint(portal, 3)); - cont = 1; - } - } + if (!cont) + { + // test if origin is outside (v3, v0, v2) - set v1 as v3 and + // continue + btMprVec3Cross(&va, &btMprSimplexPoint(portal, 3)->v, + &btMprSimplexPoint(portal, 2)->v); + dot = btMprVec3Dot(&va, &btMprSimplexPoint(portal, 0)->v); + if (dot < 0.f && !btMprIsZero(dot)) + { + btMprSimplexSet(portal, 1, btMprSimplexPoint(portal, 3)); + cont = 1; + } + } - if (cont){ - btMprVec3Sub2(&va, &btMprSimplexPoint(portal, 1)->v, - &btMprSimplexPoint(portal, 0)->v); - btMprVec3Sub2(&vb, &btMprSimplexPoint(portal, 2)->v, - &btMprSimplexPoint(portal, 0)->v); - btMprVec3Cross(&dir, &va, &vb); - btMprVec3Normalize(&dir); - }else{ - btMprSimplexSetSize(portal, 4); - } - } + if (cont) + { + btMprVec3Sub2(&va, &btMprSimplexPoint(portal, 1)->v, + &btMprSimplexPoint(portal, 0)->v); + btMprVec3Sub2(&vb, &btMprSimplexPoint(portal, 2)->v, + &btMprSimplexPoint(portal, 0)->v); + btMprVec3Cross(&dir, &va, &vb); + btMprVec3Normalize(&dir); + } + else + { + btMprSimplexSetSize(portal, 4); + } + } - return 0; + return 0; } template -static int btRefinePortal(const btConvexTemplate& a, const btConvexTemplate& b,const btMprCollisionDescription& colDesc, - btMprSimplex_t *portal) +static int btRefinePortal(const btConvexTemplate &a, const btConvexTemplate &b, const btMprCollisionDescription &colDesc, + btMprSimplex_t *portal) { - btVector3 dir; - btMprSupport_t v4; + btVector3 dir; + btMprSupport_t v4; - for (int i=0;iv, + &btMprSimplexPoint(portal, 2)->v); + b[0] = btMprVec3Dot(&vec, &btMprSimplexPoint(portal, 3)->v); - // use barycentric coordinates of tetrahedron to find origin - btMprVec3Cross(&vec, &btMprSimplexPoint(portal, 1)->v, - &btMprSimplexPoint(portal, 2)->v); - b[0] = btMprVec3Dot(&vec, &btMprSimplexPoint(portal, 3)->v); + btMprVec3Cross(&vec, &btMprSimplexPoint(portal, 3)->v, + &btMprSimplexPoint(portal, 2)->v); + b[1] = btMprVec3Dot(&vec, &btMprSimplexPoint(portal, 0)->v); - btMprVec3Cross(&vec, &btMprSimplexPoint(portal, 3)->v, - &btMprSimplexPoint(portal, 2)->v); - b[1] = btMprVec3Dot(&vec, &btMprSimplexPoint(portal, 0)->v); + btMprVec3Cross(&vec, &btMprSimplexPoint(portal, 0)->v, + &btMprSimplexPoint(portal, 1)->v); + b[2] = btMprVec3Dot(&vec, &btMprSimplexPoint(portal, 3)->v); - btMprVec3Cross(&vec, &btMprSimplexPoint(portal, 0)->v, - &btMprSimplexPoint(portal, 1)->v); - b[2] = btMprVec3Dot(&vec, &btMprSimplexPoint(portal, 3)->v); - - btMprVec3Cross(&vec, &btMprSimplexPoint(portal, 2)->v, - &btMprSimplexPoint(portal, 1)->v); - b[3] = btMprVec3Dot(&vec, &btMprSimplexPoint(portal, 0)->v); + btMprVec3Cross(&vec, &btMprSimplexPoint(portal, 2)->v, + &btMprSimplexPoint(portal, 1)->v); + b[3] = btMprVec3Dot(&vec, &btMprSimplexPoint(portal, 0)->v); sum = b[0] + b[1] + b[2] + b[3]; - if (btMprIsZero(sum) || sum < 0.f){ + if (btMprIsZero(sum) || sum < 0.f) + { b[0] = 0.f; - btMprVec3Cross(&vec, &btMprSimplexPoint(portal, 2)->v, - &btMprSimplexPoint(portal, 3)->v); - b[1] = btMprVec3Dot(&vec, &dir); - btMprVec3Cross(&vec, &btMprSimplexPoint(portal, 3)->v, - &btMprSimplexPoint(portal, 1)->v); - b[2] = btMprVec3Dot(&vec, &dir); - btMprVec3Cross(&vec, &btMprSimplexPoint(portal, 1)->v, - &btMprSimplexPoint(portal, 2)->v); - b[3] = btMprVec3Dot(&vec, &dir); + btMprVec3Cross(&vec, &btMprSimplexPoint(portal, 2)->v, + &btMprSimplexPoint(portal, 3)->v); + b[1] = btMprVec3Dot(&vec, &dir); + btMprVec3Cross(&vec, &btMprSimplexPoint(portal, 3)->v, + &btMprSimplexPoint(portal, 1)->v); + b[2] = btMprVec3Dot(&vec, &dir); + btMprVec3Cross(&vec, &btMprSimplexPoint(portal, 1)->v, + &btMprSimplexPoint(portal, 2)->v); + b[3] = btMprVec3Dot(&vec, &dir); sum = b[1] + b[2] + b[3]; } inv = 1.f / sum; - btMprVec3Copy(&p1, origin); - btMprVec3Copy(&p2, origin); - for (i = 0; i < 4; i++){ - btMprVec3Copy(&vec, &btMprSimplexPoint(portal, i)->v1); - btMprVec3Scale(&vec, b[i]); - btMprVec3Add(&p1, &vec); + btMprVec3Copy(&p1, origin); + btMprVec3Copy(&p2, origin); + for (i = 0; i < 4; i++) + { + btMprVec3Copy(&vec, &btMprSimplexPoint(portal, i)->v1); + btMprVec3Scale(&vec, b[i]); + btMprVec3Add(&p1, &vec); - btMprVec3Copy(&vec, &btMprSimplexPoint(portal, i)->v2); - btMprVec3Scale(&vec, b[i]); - btMprVec3Add(&p2, &vec); - } - btMprVec3Scale(&p1, inv); - btMprVec3Scale(&p2, inv); + btMprVec3Copy(&vec, &btMprSimplexPoint(portal, i)->v2); + btMprVec3Scale(&vec, b[i]); + btMprVec3Add(&p2, &vec); + } + btMprVec3Scale(&p1, inv); + btMprVec3Scale(&p2, inv); #ifdef MPR_AVERAGE_CONTACT_POSITIONS - btMprVec3Copy(pos, &p1); - btMprVec3Add(pos, &p2); - btMprVec3Scale(pos, 0.5); + btMprVec3Copy(pos, &p1); + btMprVec3Add(pos, &p2); + btMprVec3Scale(pos, 0.5); #else - btMprVec3Copy(pos, &p2); -#endif//MPR_AVERAGE_CONTACT_POSITIONS + btMprVec3Copy(pos, &p2); +#endif //MPR_AVERAGE_CONTACT_POSITIONS } inline float btMprVec3Dist2(const btVector3 *a, const btVector3 *b) { - btVector3 ab; - btMprVec3Sub2(&ab, a, b); - return btMprVec3Len2(&ab); + btVector3 ab; + btMprVec3Sub2(&ab, a, b); + return btMprVec3Len2(&ab); } inline float _btMprVec3PointSegmentDist2(const btVector3 *P, - const btVector3 *x0, - const btVector3 *b, - btVector3 *witness) + const btVector3 *x0, + const btVector3 *b, + btVector3 *witness) { - // The computation comes from solving equation of segment: - // S(t) = x0 + t.d - // where - x0 is initial point of segment - // - d is direction of segment from x0 (|d| > 0) - // - t belongs to <0, 1> interval - // - // Than, distance from a segment to some point P can be expressed: - // D(t) = |x0 + t.d - P|^2 - // which is distance from any point on segment. Minimization - // of this function brings distance from P to segment. - // Minimization of D(t) leads to simple quadratic equation that's - // solving is straightforward. - // - // Bonus of this method is witness point for free. + // The computation comes from solving equation of segment: + // S(t) = x0 + t.d + // where - x0 is initial point of segment + // - d is direction of segment from x0 (|d| > 0) + // - t belongs to <0, 1> interval + // + // Than, distance from a segment to some point P can be expressed: + // D(t) = |x0 + t.d - P|^2 + // which is distance from any point on segment. Minimization + // of this function brings distance from P to segment. + // Minimization of D(t) leads to simple quadratic equation that's + // solving is straightforward. + // + // Bonus of this method is witness point for free. - float dist, t; - btVector3 d, a; + float dist, t; + btVector3 d, a; - // direction of segment - btMprVec3Sub2(&d, b, x0); + // direction of segment + btMprVec3Sub2(&d, b, x0); - // precompute vector from P to x0 - btMprVec3Sub2(&a, x0, P); + // precompute vector from P to x0 + btMprVec3Sub2(&a, x0, P); - t = -1.f * btMprVec3Dot(&a, &d); - t /= btMprVec3Len2(&d); + t = -1.f * btMprVec3Dot(&a, &d); + t /= btMprVec3Len2(&d); - if (t < 0.f || btMprIsZero(t)){ - dist = btMprVec3Dist2(x0, P); - if (witness) - btMprVec3Copy(witness, x0); - }else if (t > 1.f || btMprEq(t, 1.f)){ - dist = btMprVec3Dist2(b, P); - if (witness) - btMprVec3Copy(witness, b); - }else{ - if (witness){ - btMprVec3Copy(witness, &d); - btMprVec3Scale(witness, t); - btMprVec3Add(witness, x0); - dist = btMprVec3Dist2(witness, P); - }else{ - // recycling variables - btMprVec3Scale(&d, t); - btMprVec3Add(&d, &a); - dist = btMprVec3Len2(&d); - } - } + if (t < 0.f || btMprIsZero(t)) + { + dist = btMprVec3Dist2(x0, P); + if (witness) + btMprVec3Copy(witness, x0); + } + else if (t > 1.f || btMprEq(t, 1.f)) + { + dist = btMprVec3Dist2(b, P); + if (witness) + btMprVec3Copy(witness, b); + } + else + { + if (witness) + { + btMprVec3Copy(witness, &d); + btMprVec3Scale(witness, t); + btMprVec3Add(witness, x0); + dist = btMprVec3Dist2(witness, P); + } + else + { + // recycling variables + btMprVec3Scale(&d, t); + btMprVec3Add(&d, &a); + dist = btMprVec3Len2(&d); + } + } - return dist; + return dist; } - - inline float btMprVec3PointTriDist2(const btVector3 *P, - const btVector3 *x0, const btVector3 *B, - const btVector3 *C, - btVector3 *witness) + const btVector3 *x0, const btVector3 *B, + const btVector3 *C, + btVector3 *witness) { - // Computation comes from analytic expression for triangle (x0, B, C) - // T(s, t) = x0 + s.d1 + t.d2, where d1 = B - x0 and d2 = C - x0 and - // Then equation for distance is: - // D(s, t) = | T(s, t) - P |^2 - // This leads to minimization of quadratic function of two variables. - // The solution from is taken only if s is between 0 and 1, t is - // between 0 and 1 and t + s < 1, otherwise distance from segment is - // computed. + // Computation comes from analytic expression for triangle (x0, B, C) + // T(s, t) = x0 + s.d1 + t.d2, where d1 = B - x0 and d2 = C - x0 and + // Then equation for distance is: + // D(s, t) = | T(s, t) - P |^2 + // This leads to minimization of quadratic function of two variables. + // The solution from is taken only if s is between 0 and 1, t is + // between 0 and 1 and t + s < 1, otherwise distance from segment is + // computed. - btVector3 d1, d2, a; - float u, v, w, p, q, r; - float s, t, dist, dist2; - btVector3 witness2; + btVector3 d1, d2, a; + float u, v, w, p, q, r; + float s, t, dist, dist2; + btVector3 witness2; - btMprVec3Sub2(&d1, B, x0); - btMprVec3Sub2(&d2, C, x0); - btMprVec3Sub2(&a, x0, P); + btMprVec3Sub2(&d1, B, x0); + btMprVec3Sub2(&d2, C, x0); + btMprVec3Sub2(&a, x0, P); - u = btMprVec3Dot(&a, &a); - v = btMprVec3Dot(&d1, &d1); - w = btMprVec3Dot(&d2, &d2); - p = btMprVec3Dot(&a, &d1); - q = btMprVec3Dot(&a, &d2); - r = btMprVec3Dot(&d1, &d2); + u = btMprVec3Dot(&a, &a); + v = btMprVec3Dot(&d1, &d1); + w = btMprVec3Dot(&d2, &d2); + p = btMprVec3Dot(&a, &d1); + q = btMprVec3Dot(&a, &d2); + r = btMprVec3Dot(&d1, &d2); btScalar div = (w * v - r * r); if (btMprIsZero(div)) { - s=-1; - } else + s = -1; + } + else { s = (q * r - w * p) / div; t = (-s * r - q) / w; } - if ((btMprIsZero(s) || s > 0.f) - && (btMprEq(s, 1.f) || s < 1.f) - && (btMprIsZero(t) || t > 0.f) - && (btMprEq(t, 1.f) || t < 1.f) - && (btMprEq(t + s, 1.f) || t + s < 1.f)){ + if ((btMprIsZero(s) || s > 0.f) && (btMprEq(s, 1.f) || s < 1.f) && (btMprIsZero(t) || t > 0.f) && (btMprEq(t, 1.f) || t < 1.f) && (btMprEq(t + s, 1.f) || t + s < 1.f)) + { + if (witness) + { + btMprVec3Scale(&d1, s); + btMprVec3Scale(&d2, t); + btMprVec3Copy(witness, x0); + btMprVec3Add(witness, &d1); + btMprVec3Add(witness, &d2); - if (witness){ - btMprVec3Scale(&d1, s); - btMprVec3Scale(&d2, t); - btMprVec3Copy(witness, x0); - btMprVec3Add(witness, &d1); - btMprVec3Add(witness, &d2); + dist = btMprVec3Dist2(witness, P); + } + else + { + dist = s * s * v; + dist += t * t * w; + dist += 2.f * s * t * r; + dist += 2.f * s * p; + dist += 2.f * t * q; + dist += u; + } + } + else + { + dist = _btMprVec3PointSegmentDist2(P, x0, B, witness); - dist = btMprVec3Dist2(witness, P); - }else{ - dist = s * s * v; - dist += t * t * w; - dist += 2.f * s * t * r; - dist += 2.f * s * p; - dist += 2.f * t * q; - dist += u; - } - }else{ - dist = _btMprVec3PointSegmentDist2(P, x0, B, witness); + dist2 = _btMprVec3PointSegmentDist2(P, x0, C, &witness2); + if (dist2 < dist) + { + dist = dist2; + if (witness) + btMprVec3Copy(witness, &witness2); + } - dist2 = _btMprVec3PointSegmentDist2(P, x0, C, &witness2); - if (dist2 < dist){ - dist = dist2; - if (witness) - btMprVec3Copy(witness, &witness2); - } + dist2 = _btMprVec3PointSegmentDist2(P, B, C, &witness2); + if (dist2 < dist) + { + dist = dist2; + if (witness) + btMprVec3Copy(witness, &witness2); + } + } - dist2 = _btMprVec3PointSegmentDist2(P, B, C, &witness2); - if (dist2 < dist){ - dist = dist2; - if (witness) - btMprVec3Copy(witness, &witness2); - } - } - - return dist; + return dist; } template -static void btFindPenetr(const btConvexTemplate& a, const btConvexTemplate& b, - const btMprCollisionDescription& colDesc, - btMprSimplex_t *portal, - float *depth, btVector3 *pdir, btVector3 *pos) +static void btFindPenetr(const btConvexTemplate &a, const btConvexTemplate &b, + const btMprCollisionDescription &colDesc, + btMprSimplex_t *portal, + float *depth, btVector3 *pdir, btVector3 *pos) { - btVector3 dir; - btMprSupport_t v4; - unsigned long iterations; + btVector3 dir; + btMprSupport_t v4; + unsigned long iterations; - btVector3 zero = btVector3(0,0,0); - btVector3* origin = &zero; + btVector3 zero = btVector3(0, 0, 0); + btVector3 *origin = &zero; - - iterations = 1UL; - for (int i=0;i find penetration info - if (portalReachTolerance(portal, &v4, &dir) - || iterations ==BT_MPR_MAX_ITERATIONS) + // reached tolerance -> find penetration info + if (portalReachTolerance(portal, &v4, &dir) || iterations == BT_MPR_MAX_ITERATIONS) { - *depth = btMprVec3PointTriDist2(origin,&btMprSimplexPoint(portal, 1)->v,&btMprSimplexPoint(portal, 2)->v,&btMprSimplexPoint(portal, 3)->v,pdir); - *depth = BT_MPR_SQRT(*depth); - + *depth = btMprVec3PointTriDist2(origin, &btMprSimplexPoint(portal, 1)->v, &btMprSimplexPoint(portal, 2)->v, &btMprSimplexPoint(portal, 3)->v, pdir); + *depth = BT_MPR_SQRT(*depth); + if (btMprIsZero((*pdir).x()) && btMprIsZero((*pdir).y()) && btMprIsZero((*pdir).z())) { - *pdir = dir; - } + } btMprVec3Normalize(pdir); - - // barycentric coordinates: - btFindPos(portal, pos); + // barycentric coordinates: + btFindPos(portal, pos); - return; - } + return; + } - btExpandPortal(portal, &v4); + btExpandPortal(portal, &v4); - iterations++; - } + iterations++; + } } -static void btFindPenetrTouch(btMprSimplex_t *portal,float *depth, btVector3 *dir, btVector3 *pos) +static void btFindPenetrTouch(btMprSimplex_t *portal, float *depth, btVector3 *dir, btVector3 *pos) { - // Touching contact on portal's v1 - so depth is zero and direction - // is unimportant and pos can be guessed - *depth = 0.f; - btVector3 zero = btVector3(0,0,0); - btVector3* origin = &zero; - + // Touching contact on portal's v1 - so depth is zero and direction + // is unimportant and pos can be guessed + *depth = 0.f; + btVector3 zero = btVector3(0, 0, 0); + btVector3 *origin = &zero; btMprVec3Copy(dir, origin); #ifdef MPR_AVERAGE_CONTACT_POSITIONS - btMprVec3Copy(pos, &btMprSimplexPoint(portal, 1)->v1); - btMprVec3Add(pos, &btMprSimplexPoint(portal, 1)->v2); - btMprVec3Scale(pos, 0.5); + btMprVec3Copy(pos, &btMprSimplexPoint(portal, 1)->v1); + btMprVec3Add(pos, &btMprSimplexPoint(portal, 1)->v2); + btMprVec3Scale(pos, 0.5); #else - btMprVec3Copy(pos, &btMprSimplexPoint(portal, 1)->v2); + btMprVec3Copy(pos, &btMprSimplexPoint(portal, 1)->v2); #endif } static void btFindPenetrSegment(btMprSimplex_t *portal, - float *depth, btVector3 *dir, btVector3 *pos) + float *depth, btVector3 *dir, btVector3 *pos) { - - // Origin lies on v0-v1 segment. - // Depth is distance to v1, direction also and position must be - // computed + // Origin lies on v0-v1 segment. + // Depth is distance to v1, direction also and position must be + // computed #ifdef MPR_AVERAGE_CONTACT_POSITIONS - btMprVec3Copy(pos, &btMprSimplexPoint(portal, 1)->v1); - btMprVec3Add(pos, &btMprSimplexPoint(portal, 1)->v2); - btMprVec3Scale(pos, 0.5f); + btMprVec3Copy(pos, &btMprSimplexPoint(portal, 1)->v1); + btMprVec3Add(pos, &btMprSimplexPoint(portal, 1)->v2); + btMprVec3Scale(pos, 0.5f); #else - btMprVec3Copy(pos, &btMprSimplexPoint(portal, 1)->v2); -#endif//MPR_AVERAGE_CONTACT_POSITIONS + btMprVec3Copy(pos, &btMprSimplexPoint(portal, 1)->v2); +#endif //MPR_AVERAGE_CONTACT_POSITIONS - btMprVec3Copy(dir, &btMprSimplexPoint(portal, 1)->v); - *depth = BT_MPR_SQRT(btMprVec3Len2(dir)); - btMprVec3Normalize(dir); - - + btMprVec3Copy(dir, &btMprSimplexPoint(portal, 1)->v); + *depth = BT_MPR_SQRT(btMprVec3Len2(dir)); + btMprVec3Normalize(dir); } - template -inline int btMprPenetration( const btConvexTemplate& a, const btConvexTemplate& b, - const btMprCollisionDescription& colDesc, - float *depthOut, btVector3* dirOut, btVector3* posOut) +inline int btMprPenetration(const btConvexTemplate &a, const btConvexTemplate &b, + const btMprCollisionDescription &colDesc, + float *depthOut, btVector3 *dirOut, btVector3 *posOut) { - - btMprSimplex_t portal; + btMprSimplex_t portal; + // Phase 1: Portal discovery + int result = btDiscoverPortal(a, b, colDesc, &portal); - // Phase 1: Portal discovery - int result = btDiscoverPortal(a,b,colDesc, &portal); - - //sepAxis[pairIndex] = *pdir;//or -dir? switch (result) { - case 0: + case 0: { // Phase 2: Portal refinement - - result = btRefinePortal(a,b,colDesc, &portal); + + result = btRefinePortal(a, b, colDesc, &portal); if (result < 0) return -1; // Phase 3. Penetration info - btFindPenetr(a,b,colDesc, &portal, depthOut, dirOut, posOut); - - + btFindPenetr(a, b, colDesc, &portal, depthOut, dirOut, posOut); + break; } - case 1: + case 1: { - // Touching contact on portal's v1. + // Touching contact on portal's v1. btFindPenetrTouch(&portal, depthOut, dirOut, posOut); - result=0; + result = 0; break; } - case 2: + case 2: { - - btFindPenetrSegment( &portal, depthOut, dirOut, posOut); - result=0; + btFindPenetrSegment(&portal, depthOut, dirOut, posOut); + result = 0; break; } - default: + default: { //if (res < 0) //{ - // Origin isn't inside portal - no collision. - result = -1; + // Origin isn't inside portal - no collision. + result = -1; //} } }; - + return result; }; - -template -inline int btComputeMprPenetration( const btConvexTemplate& a, const btConvexTemplate& b, const - btMprCollisionDescription& colDesc, btMprDistanceTemplate* distInfo) +template +inline int btComputeMprPenetration(const btConvexTemplate &a, const btConvexTemplate &b, const btMprCollisionDescription &colDesc, btMprDistanceTemplate *distInfo) { - btVector3 dir,pos; + btVector3 dir, pos; float depth; - int res = btMprPenetration(a,b,colDesc,&depth, &dir, &pos); - if (res==0) + int res = btMprPenetration(a, b, colDesc, &depth, &dir, &pos); + if (res == 0) { distInfo->m_distance = -depth; distInfo->m_pointOnB = pos; distInfo->m_normalBtoA = -dir; - distInfo->m_pointOnA = pos-distInfo->m_distance*dir; + distInfo->m_pointOnA = pos - distInfo->m_distance * dir; return 0; } return -1; } - - -#endif //BT_MPR_PENETRATION_H +#endif //BT_MPR_PENETRATION_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp b/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp index 9603a8bbd..f1422cad4 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp +++ b/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btPersistentManifold.h" #include "LinearMath/btTransform.h" #include "LinearMath/btSerializer.h" @@ -24,83 +23,76 @@ subject to the following restrictions: #define btCollisionObjectData btCollisionObjectFloatData #endif -btScalar gContactBreakingThreshold = btScalar(0.02); -ContactDestroyedCallback gContactDestroyedCallback = 0; -ContactProcessedCallback gContactProcessedCallback = 0; -ContactStartedCallback gContactStartedCallback = 0; -ContactEndedCallback gContactEndedCallback = 0; +btScalar gContactBreakingThreshold = btScalar(0.02); +ContactDestroyedCallback gContactDestroyedCallback = 0; +ContactProcessedCallback gContactProcessedCallback = 0; +ContactStartedCallback gContactStartedCallback = 0; +ContactEndedCallback gContactEndedCallback = 0; ///gContactCalcArea3Points will approximate the convex hull area using 3 points ///when setting it to false, it will use 4 points to compute the area: it is more accurate but slower -bool gContactCalcArea3Points = true; - +bool gContactCalcArea3Points = true; btPersistentManifold::btPersistentManifold() -:btTypedObject(BT_PERSISTENT_MANIFOLD_TYPE), -m_body0(0), -m_body1(0), -m_cachedPoints (0), -m_companionIdA(0), -m_companionIdB(0), -m_index1a(0) + : btTypedObject(BT_PERSISTENT_MANIFOLD_TYPE), + m_body0(0), + m_body1(0), + m_cachedPoints(0), + m_companionIdA(0), + m_companionIdB(0), + m_index1a(0) { } - - - #ifdef DEBUG_PERSISTENCY #include -void btPersistentManifold::DebugPersistency() +void btPersistentManifold::DebugPersistency() { int i; - printf("DebugPersistency : numPoints %d\n",m_cachedPoints); - for (i=0;i1) + if (occurance > 1) printf("error in clearUserCache\n"); } } - btAssert(occurance<=0); -#endif //DEBUG_PERSISTENCY + btAssert(occurance <= 0); +#endif //DEBUG_PERSISTENCY if (pt.m_userPersistentData && gContactDestroyedCallback) { (*gContactDestroyedCallback)(pt.m_userPersistentData); pt.m_userPersistentData = 0; } - + #ifdef DEBUG_PERSISTENCY DebugPersistency(); #endif } - - } -static inline btScalar calcArea4Points(const btVector3 &p0,const btVector3 &p1,const btVector3 &p2,const btVector3 &p3) +static inline btScalar calcArea4Points(const btVector3& p0, const btVector3& p1, const btVector3& p2, const btVector3& p3) { // It calculates possible 3 area constructed from random 4 points and returns the biggest one. - btVector3 a[3],b[3]; + btVector3 a[3], b[3]; a[0] = p0 - p1; a[1] = p0 - p2; a[2] = p0 - p3; @@ -113,100 +105,102 @@ static inline btScalar calcArea4Points(const btVector3 &p0,const btVector3 &p1,c btVector3 tmp1 = a[1].cross(b[1]); btVector3 tmp2 = a[2].cross(b[2]); - return btMax(btMax(tmp0.length2(),tmp1.length2()),tmp2.length2()); + return btMax(btMax(tmp0.length2(), tmp1.length2()), tmp2.length2()); } -int btPersistentManifold::sortCachedPoints(const btManifoldPoint& pt) +int btPersistentManifold::sortCachedPoints(const btManifoldPoint& pt) { - //calculate 4 possible cases areas, and take biggest area - //also need to keep 'deepest' - - int maxPenetrationIndex = -1; + //calculate 4 possible cases areas, and take biggest area + //also need to keep 'deepest' + + int maxPenetrationIndex = -1; #define KEEP_DEEPEST_POINT 1 #ifdef KEEP_DEEPEST_POINT - btScalar maxPenetration = pt.getDistance(); - for (int i=0;i<4;i++) + btScalar maxPenetration = pt.getDistance(); + for (int i = 0; i < 4; i++) + { + if (m_pointCache[i].getDistance() < maxPenetration) { - if (m_pointCache[i].getDistance() < maxPenetration) - { - maxPenetrationIndex = i; - maxPenetration = m_pointCache[i].getDistance(); - } + maxPenetrationIndex = i; + maxPenetration = m_pointCache[i].getDistance(); } -#endif //KEEP_DEEPEST_POINT - - btScalar res0(btScalar(0.)),res1(btScalar(0.)),res2(btScalar(0.)),res3(btScalar(0.)); + } +#endif //KEEP_DEEPEST_POINT + + btScalar res0(btScalar(0.)), res1(btScalar(0.)), res2(btScalar(0.)), res3(btScalar(0.)); if (gContactCalcArea3Points) { if (maxPenetrationIndex != 0) { - btVector3 a0 = pt.m_localPointA-m_pointCache[1].m_localPointA; - btVector3 b0 = m_pointCache[3].m_localPointA-m_pointCache[2].m_localPointA; + btVector3 a0 = pt.m_localPointA - m_pointCache[1].m_localPointA; + btVector3 b0 = m_pointCache[3].m_localPointA - m_pointCache[2].m_localPointA; btVector3 cross = a0.cross(b0); res0 = cross.length2(); } if (maxPenetrationIndex != 1) { - btVector3 a1 = pt.m_localPointA-m_pointCache[0].m_localPointA; - btVector3 b1 = m_pointCache[3].m_localPointA-m_pointCache[2].m_localPointA; + btVector3 a1 = pt.m_localPointA - m_pointCache[0].m_localPointA; + btVector3 b1 = m_pointCache[3].m_localPointA - m_pointCache[2].m_localPointA; btVector3 cross = a1.cross(b1); res1 = cross.length2(); } if (maxPenetrationIndex != 2) { - btVector3 a2 = pt.m_localPointA-m_pointCache[0].m_localPointA; - btVector3 b2 = m_pointCache[3].m_localPointA-m_pointCache[1].m_localPointA; + btVector3 a2 = pt.m_localPointA - m_pointCache[0].m_localPointA; + btVector3 b2 = m_pointCache[3].m_localPointA - m_pointCache[1].m_localPointA; btVector3 cross = a2.cross(b2); res2 = cross.length2(); } if (maxPenetrationIndex != 3) { - btVector3 a3 = pt.m_localPointA-m_pointCache[0].m_localPointA; - btVector3 b3 = m_pointCache[2].m_localPointA-m_pointCache[1].m_localPointA; + btVector3 a3 = pt.m_localPointA - m_pointCache[0].m_localPointA; + btVector3 b3 = m_pointCache[2].m_localPointA - m_pointCache[1].m_localPointA; btVector3 cross = a3.cross(b3); res3 = cross.length2(); } - } + } else { - if(maxPenetrationIndex != 0) { - res0 = calcArea4Points(pt.m_localPointA,m_pointCache[1].m_localPointA,m_pointCache[2].m_localPointA,m_pointCache[3].m_localPointA); + if (maxPenetrationIndex != 0) + { + res0 = calcArea4Points(pt.m_localPointA, m_pointCache[1].m_localPointA, m_pointCache[2].m_localPointA, m_pointCache[3].m_localPointA); } - if(maxPenetrationIndex != 1) { - res1 = calcArea4Points(pt.m_localPointA,m_pointCache[0].m_localPointA,m_pointCache[2].m_localPointA,m_pointCache[3].m_localPointA); + if (maxPenetrationIndex != 1) + { + res1 = calcArea4Points(pt.m_localPointA, m_pointCache[0].m_localPointA, m_pointCache[2].m_localPointA, m_pointCache[3].m_localPointA); } - if(maxPenetrationIndex != 2) { - res2 = calcArea4Points(pt.m_localPointA,m_pointCache[0].m_localPointA,m_pointCache[1].m_localPointA,m_pointCache[3].m_localPointA); + if (maxPenetrationIndex != 2) + { + res2 = calcArea4Points(pt.m_localPointA, m_pointCache[0].m_localPointA, m_pointCache[1].m_localPointA, m_pointCache[3].m_localPointA); } - if(maxPenetrationIndex != 3) { - res3 = calcArea4Points(pt.m_localPointA,m_pointCache[0].m_localPointA,m_pointCache[1].m_localPointA,m_pointCache[2].m_localPointA); + if (maxPenetrationIndex != 3) + { + res3 = calcArea4Points(pt.m_localPointA, m_pointCache[0].m_localPointA, m_pointCache[1].m_localPointA, m_pointCache[2].m_localPointA); } } - btVector4 maxvec(res0,res1,res2,res3); + btVector4 maxvec(res0, res1, res2, res3); int biggestarea = maxvec.closestAxis4(); return biggestarea; - } - int btPersistentManifold::getCacheEntry(const btManifoldPoint& newPoint) const { - btScalar shortestDist = getContactBreakingThreshold() * getContactBreakingThreshold(); + btScalar shortestDist = getContactBreakingThreshold() * getContactBreakingThreshold(); int size = getNumContacts(); int nearestPoint = -1; - for( int i = 0; i < size; i++ ) + for (int i = 0; i < size; i++) { - const btManifoldPoint &mp = m_pointCache[i]; + const btManifoldPoint& mp = m_pointCache[i]; - btVector3 diffA = mp.m_localPointA- newPoint.m_localPointA; + btVector3 diffA = mp.m_localPointA - newPoint.m_localPointA; const btScalar distToManiPoint = diffA.dot(diffA); - if( distToManiPoint < shortestDist ) + if (distToManiPoint < shortestDist) { shortestDist = distToManiPoint; nearestPoint = i; @@ -221,7 +215,7 @@ int btPersistentManifold::addManifoldPoint(const btManifoldPoint& newPoint, bool { btAssert(validContactDistance(newPoint)); } - + int insertIndex = getNumContacts(); if (insertIndex == MANIFOLD_CACHE_SIZE) { @@ -232,91 +226,87 @@ int btPersistentManifold::addManifoldPoint(const btManifoldPoint& newPoint, bool insertIndex = 0; #endif clearUserCache(m_pointCache[insertIndex]); - - } else + } + else { m_cachedPoints++; - - } - if (insertIndex<0) - insertIndex=0; + if (insertIndex < 0) + insertIndex = 0; - btAssert(m_pointCache[insertIndex].m_userPersistentData==0); + btAssert(m_pointCache[insertIndex].m_userPersistentData == 0); m_pointCache[insertIndex] = newPoint; return insertIndex; } -btScalar btPersistentManifold::getContactBreakingThreshold() const +btScalar btPersistentManifold::getContactBreakingThreshold() const { return m_contactBreakingThreshold; } - - -void btPersistentManifold::refreshContactPoints(const btTransform& trA,const btTransform& trB) +void btPersistentManifold::refreshContactPoints(const btTransform& trA, const btTransform& trB) { int i; #ifdef DEBUG_PERSISTENCY printf("refreshContactPoints posA = (%f,%f,%f) posB = (%f,%f,%f)\n", - trA.getOrigin().getX(), - trA.getOrigin().getY(), - trA.getOrigin().getZ(), - trB.getOrigin().getX(), - trB.getOrigin().getY(), - trB.getOrigin().getZ()); -#endif //DEBUG_PERSISTENCY + trA.getOrigin().getX(), + trA.getOrigin().getY(), + trA.getOrigin().getZ(), + trB.getOrigin().getX(), + trB.getOrigin().getY(), + trB.getOrigin().getZ()); +#endif //DEBUG_PERSISTENCY /// first refresh worldspace positions and distance - for (i=getNumContacts()-1;i>=0;i--) + for (i = getNumContacts() - 1; i >= 0; i--) { - btManifoldPoint &manifoldPoint = m_pointCache[i]; - manifoldPoint.m_positionWorldOnA = trA( manifoldPoint.m_localPointA ); - manifoldPoint.m_positionWorldOnB = trB( manifoldPoint.m_localPointB ); - manifoldPoint.m_distance1 = (manifoldPoint.m_positionWorldOnA - manifoldPoint.m_positionWorldOnB).dot(manifoldPoint.m_normalWorldOnB); + btManifoldPoint& manifoldPoint = m_pointCache[i]; + manifoldPoint.m_positionWorldOnA = trA(manifoldPoint.m_localPointA); + manifoldPoint.m_positionWorldOnB = trB(manifoldPoint.m_localPointB); + manifoldPoint.m_distance1 = (manifoldPoint.m_positionWorldOnA - manifoldPoint.m_positionWorldOnB).dot(manifoldPoint.m_normalWorldOnB); manifoldPoint.m_lifeTime++; } - /// then + /// then btScalar distance2d; - btVector3 projectedDifference,projectedPoint; - for (i=getNumContacts()-1;i>=0;i--) + btVector3 projectedDifference, projectedPoint; + for (i = getNumContacts() - 1; i >= 0; i--) { - - btManifoldPoint &manifoldPoint = m_pointCache[i]; + btManifoldPoint& manifoldPoint = m_pointCache[i]; //contact becomes invalid when signed distance exceeds margin (projected on contactnormal direction) if (!validContactDistance(manifoldPoint)) { removeContactPoint(i); - } else + } + else { - //todo: friction anchor may require the contact to be around a bit longer + //todo: friction anchor may require the contact to be around a bit longer //contact also becomes invalid when relative movement orthogonal to normal exceeds margin projectedPoint = manifoldPoint.m_positionWorldOnA - manifoldPoint.m_normalWorldOnB * manifoldPoint.m_distance1; projectedDifference = manifoldPoint.m_positionWorldOnB - projectedPoint; distance2d = projectedDifference.dot(projectedDifference); - if (distance2d > getContactBreakingThreshold()*getContactBreakingThreshold() ) + if (distance2d > getContactBreakingThreshold() * getContactBreakingThreshold()) { removeContactPoint(i); - } else + } + else { //contact point processed callback if (gContactProcessedCallback) - (*gContactProcessedCallback)(manifoldPoint,(void*)m_body0,(void*)m_body1); + (*gContactProcessedCallback)(manifoldPoint, (void*)m_body0, (void*)m_body1); } } } #ifdef DEBUG_PERSISTENCY DebugPersistency(); -#endif // +#endif // } - -int btPersistentManifold::calculateSerializeBufferSize() const +int btPersistentManifold::calculateSerializeBufferSize() const { return sizeof(btPersistentManifoldData); } -const char* btPersistentManifold::serialize(const class btPersistentManifold* manifold, void* dataBuffer, class btSerializer* serializer) const +const char* btPersistentManifold::serialize(const class btPersistentManifold* manifold, void* dataBuffer, class btSerializer* serializer) const { btPersistentManifoldData* dataOut = (btPersistentManifoldData*)dataBuffer; memset(dataOut, 0, sizeof(btPersistentManifoldData)); @@ -379,7 +369,7 @@ void btPersistentManifold::deSerialize(const struct btPersistentManifoldDoubleDa for (int i = 0; i < this->getNumContacts(); i++) { btManifoldPoint& pt = m_pointCache[i]; - + pt.m_appliedImpulse = manifoldDataPtr->m_pointCacheAppliedImpulse[i]; pt.m_appliedImpulseLateral1 = manifoldDataPtr->m_pointCacheAppliedImpulseLateral1[i]; pt.m_appliedImpulseLateral2 = manifoldDataPtr->m_pointCacheAppliedImpulseLateral2[i]; @@ -409,7 +399,6 @@ void btPersistentManifold::deSerialize(const struct btPersistentManifoldDoubleDa pt.m_contactMotion1 = manifoldDataPtr->m_pointCacheContactMotion1[i]; pt.m_contactMotion2 = manifoldDataPtr->m_pointCacheContactMotion2[i]; } - } void btPersistentManifold::deSerialize(const struct btPersistentManifoldFloatData* manifoldDataPtr) @@ -455,5 +444,4 @@ void btPersistentManifold::deSerialize(const struct btPersistentManifoldFloatDat pt.m_contactMotion1 = manifoldDataPtr->m_pointCacheContactMotion1[i]; pt.m_contactMotion2 = manifoldDataPtr->m_pointCacheContactMotion2[i]; } - } \ No newline at end of file diff --git a/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h b/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h index 67be0c48e..8a9134c95 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h +++ b/src/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h @@ -16,7 +16,6 @@ subject to the following restrictions: #ifndef BT_PERSISTENT_MANIFOLD_H #define BT_PERSISTENT_MANIFOLD_H - #include "LinearMath/btVector3.h" #include "LinearMath/btTransform.h" #include "btManifoldPoint.h" @@ -34,14 +33,14 @@ extern btScalar gContactBreakingThreshold; class btPersistentManifold; typedef bool (*ContactDestroyedCallback)(void* userPersistentData); -typedef bool (*ContactProcessedCallback)(btManifoldPoint& cp,void* body0,void* body1); -typedef void (*ContactStartedCallback)(btPersistentManifold* const &manifold); -typedef void (*ContactEndedCallback)(btPersistentManifold* const &manifold); -extern ContactDestroyedCallback gContactDestroyedCallback; +typedef bool (*ContactProcessedCallback)(btManifoldPoint& cp, void* body0, void* body1); +typedef void (*ContactStartedCallback)(btPersistentManifold* const& manifold); +typedef void (*ContactEndedCallback)(btPersistentManifold* const& manifold); +extern ContactDestroyedCallback gContactDestroyedCallback; extern ContactProcessedCallback gContactProcessedCallback; extern ContactStartedCallback gContactStartedCallback; extern ContactEndedCallback gContactEndedCallback; -#endif //SWIG +#endif //SWIG //the enum starts at 1024 to avoid type conflicts with btTypedConstraint enum btContactManifoldTypes @@ -60,73 +59,74 @@ enum btContactManifoldTypes ///the contact point with deepest penetration is always kept, and it tries to maximuze the area covered by the points ///note that some pairs of objects might have more then one contact manifold. - //ATTRIBUTE_ALIGNED128( class) btPersistentManifold : public btTypedObject -ATTRIBUTE_ALIGNED16( class) btPersistentManifold : public btTypedObject +ATTRIBUTE_ALIGNED16(class) +btPersistentManifold : public btTypedObject { - btManifoldPoint m_pointCache[MANIFOLD_CACHE_SIZE]; /// this two body pointers can point to the physics rigidbody class. const btCollisionObject* m_body0; const btCollisionObject* m_body1; - int m_cachedPoints; + int m_cachedPoints; - btScalar m_contactBreakingThreshold; - btScalar m_contactProcessingThreshold; + btScalar m_contactBreakingThreshold; + btScalar m_contactProcessingThreshold; - /// sort cached points so most isolated points come first - int sortCachedPoints(const btManifoldPoint& pt); + int sortCachedPoints(const btManifoldPoint& pt); - int findContactPoint(const btManifoldPoint* unUsed, int numUnused,const btManifoldPoint& pt); + int findContactPoint(const btManifoldPoint* unUsed, int numUnused, const btManifoldPoint& pt); public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - int m_companionIdA; - int m_companionIdB; + int m_companionIdA; + int m_companionIdB; int m_index1a; btPersistentManifold(); - btPersistentManifold(const btCollisionObject* body0,const btCollisionObject* body1,int , btScalar contactBreakingThreshold,btScalar contactProcessingThreshold) + btPersistentManifold(const btCollisionObject* body0, const btCollisionObject* body1, int, btScalar contactBreakingThreshold, btScalar contactProcessingThreshold) : btTypedObject(BT_PERSISTENT_MANIFOLD_TYPE), - m_body0(body0),m_body1(body1),m_cachedPoints(0), - m_contactBreakingThreshold(contactBreakingThreshold), - m_contactProcessingThreshold(contactProcessingThreshold), - m_companionIdA(0), - m_companionIdB(0), - m_index1a(0) + m_body0(body0), + m_body1(body1), + m_cachedPoints(0), + m_contactBreakingThreshold(contactBreakingThreshold), + m_contactProcessingThreshold(contactProcessingThreshold), + m_companionIdA(0), + m_companionIdB(0), + m_index1a(0) { } - SIMD_FORCE_INLINE const btCollisionObject* getBody0() const { return m_body0;} - SIMD_FORCE_INLINE const btCollisionObject* getBody1() const { return m_body1;} + SIMD_FORCE_INLINE const btCollisionObject* getBody0() const { return m_body0; } + SIMD_FORCE_INLINE const btCollisionObject* getBody1() const { return m_body1; } - void setBodies(const btCollisionObject* body0,const btCollisionObject* body1) + void setBodies(const btCollisionObject* body0, const btCollisionObject* body1) { m_body0 = body0; m_body1 = body1; } - void clearUserCache(btManifoldPoint& pt); + void clearUserCache(btManifoldPoint & pt); #ifdef DEBUG_PERSISTENCY - void DebugPersistency(); -#endif // - - SIMD_FORCE_INLINE int getNumContacts() const { return m_cachedPoints;} + void DebugPersistency(); +#endif // + + SIMD_FORCE_INLINE int getNumContacts() const + { + return m_cachedPoints; + } /// the setNumContacts API is usually not used, except when you gather/fill all contacts manually void setNumContacts(int cachedPoints) { m_cachedPoints = cachedPoints; } - SIMD_FORCE_INLINE const btManifoldPoint& getContactPoint(int index) const { btAssert(index < m_cachedPoints); @@ -140,39 +140,36 @@ public: } ///@todo: get this margin from the current physics / collision environment - btScalar getContactBreakingThreshold() const; + btScalar getContactBreakingThreshold() const; - btScalar getContactProcessingThreshold() const + btScalar getContactProcessingThreshold() const { return m_contactProcessingThreshold; } - + void setContactBreakingThreshold(btScalar contactBreakingThreshold) { m_contactBreakingThreshold = contactBreakingThreshold; } - void setContactProcessingThreshold(btScalar contactProcessingThreshold) + void setContactProcessingThreshold(btScalar contactProcessingThreshold) { m_contactProcessingThreshold = contactProcessingThreshold; } - - - int getCacheEntry(const btManifoldPoint& newPoint) const; - int addManifoldPoint( const btManifoldPoint& newPoint, bool isPredictive=false); + int addManifoldPoint(const btManifoldPoint& newPoint, bool isPredictive = false); - void removeContactPoint (int index) + void removeContactPoint(int index) { clearUserCache(m_pointCache[index]); int lastUsedIndex = getNumContacts() - 1; -// m_pointCache[index] = m_pointCache[lastUsedIndex]; - if(index != lastUsedIndex) + // m_pointCache[index] = m_pointCache[lastUsedIndex]; + if (index != lastUsedIndex) { - m_pointCache[index] = m_pointCache[lastUsedIndex]; + m_pointCache[index] = m_pointCache[lastUsedIndex]; //get rid of duplicated userPersistentData pointer m_pointCache[lastUsedIndex].m_userPersistentData = 0; m_pointCache[lastUsedIndex].m_appliedImpulse = 0.f; @@ -182,7 +179,7 @@ public: m_pointCache[lastUsedIndex].m_lifeTime = 0; } - btAssert(m_pointCache[lastUsedIndex].m_userPersistentData==0); + btAssert(m_pointCache[lastUsedIndex].m_userPersistentData == 0); m_cachedPoints--; if (gContactEndedCallback && m_cachedPoints == 0) @@ -243,13 +240,12 @@ public: return pt.m_distance1 <= getContactBreakingThreshold(); } /// calculated new worldspace coordinates and depth, and reject points that exceed the collision margin - void refreshContactPoints( const btTransform& trA,const btTransform& trB); + void refreshContactPoints(const btTransform& trA, const btTransform& trB); - - SIMD_FORCE_INLINE void clearManifold() + SIMD_FORCE_INLINE void clearManifold() { int i; - for (i=0;i //for FLT_MAX +#include //for FLT_MAX -int gExpectedNbTests=0; +int gExpectedNbTests = 0; int gActualNbTests = 0; bool gUseInternalObject = true; // Clips a face to the back of a plane -void btPolyhedralContactClipping::clipFace(const btVertexArray& pVtxIn, btVertexArray& ppVtxOut, const btVector3& planeNormalWS,btScalar planeEqWS) +void btPolyhedralContactClipping::clipFace(const btVertexArray& pVtxIn, btVertexArray& ppVtxOut, const btVector3& planeNormalWS, btScalar planeEqWS) { - int ve; btScalar ds, de; int numVerts = pVtxIn.size(); if (numVerts < 2) return; - btVector3 firstVertex=pVtxIn[pVtxIn.size()-1]; + btVector3 firstVertex = pVtxIn[pVtxIn.size() - 1]; btVector3 endVertex = pVtxIn[0]; - - ds = planeNormalWS.dot(firstVertex)+planeEqWS; + + ds = planeNormalWS.dot(firstVertex) + planeEqWS; for (ve = 0; ve < numVerts; ve++) { - endVertex=pVtxIn[ve]; + endVertex = pVtxIn[ve]; - de = planeNormalWS.dot(endVertex)+planeEqWS; + de = planeNormalWS.dot(endVertex) + planeEqWS; - if (ds<0) + if (ds < 0) { - if (de<0) + if (de < 0) { // Start < 0, end < 0, so output endVertex ppVtxOut.push_back(endVertex); @@ -59,15 +56,15 @@ void btPolyhedralContactClipping::clipFace(const btVertexArray& pVtxIn, btVertex else { // Start < 0, end >= 0, so output intersection - ppVtxOut.push_back( firstVertex.lerp(endVertex,btScalar(ds * 1.f/(ds - de)))); + ppVtxOut.push_back(firstVertex.lerp(endVertex, btScalar(ds * 1.f / (ds - de)))); } } else { - if (de<0) + if (de < 0) { // Start >= 0, end < 0 so output intersection and end - ppVtxOut.push_back(firstVertex.lerp(endVertex,btScalar(ds * 1.f/(ds - de)))); + ppVtxOut.push_back(firstVertex.lerp(endVertex, btScalar(ds * 1.f / (ds - de)))); ppVtxOut.push_back(endVertex); } } @@ -76,47 +73,44 @@ void btPolyhedralContactClipping::clipFace(const btVertexArray& pVtxIn, btVertex } } - -static bool TestSepAxis(const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btVector3& sep_axis, btScalar& depth, btVector3& witnessPointA, btVector3& witnessPointB) +static bool TestSepAxis(const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA, const btTransform& transB, const btVector3& sep_axis, btScalar& depth, btVector3& witnessPointA, btVector3& witnessPointB) { - btScalar Min0,Max0; - btScalar Min1,Max1; - btVector3 witnesPtMinA,witnesPtMaxA; - btVector3 witnesPtMinB,witnesPtMaxB; + btScalar Min0, Max0; + btScalar Min1, Max1; + btVector3 witnesPtMinA, witnesPtMaxA; + btVector3 witnesPtMinB, witnesPtMaxB; - hullA.project(transA,sep_axis, Min0, Max0,witnesPtMinA,witnesPtMaxA); - hullB.project(transB, sep_axis, Min1, Max1,witnesPtMinB,witnesPtMaxB); + hullA.project(transA, sep_axis, Min0, Max0, witnesPtMinA, witnesPtMaxA); + hullB.project(transB, sep_axis, Min1, Max1, witnesPtMinB, witnesPtMaxB); - if(Max0=0.0f); + btAssert(d0 >= 0.0f); btScalar d1 = Max1 - Min0; - btAssert(d1>=0.0f); - if (d0= 0.0f); + if (d0 < d1) { depth = d0; witnessPointA = witnesPtMaxA; witnessPointB = witnesPtMinB; - - } else + } + else { depth = d1; witnessPointA = witnesPtMinA; witnessPointB = witnesPtMaxB; } - + return true; } - - -static int gActualSATPairTests=0; +static int gActualSATPairTests = 0; inline bool IsAlmostZero(const btVector3& v) { - if(btFabs(v.x())>1e-6 || btFabs(v.y())>1e-6 || btFabs(v.z())>1e-6) return false; + if (btFabs(v.x()) > 1e-6 || btFabs(v.y()) > 1e-6 || btFabs(v.z()) > 1e-6) return false; return true; } @@ -125,9 +119,9 @@ inline bool IsAlmostZero(const btVector3& v) inline void BoxSupport(const btScalar extents[3], const btScalar sv[3], btScalar p[3]) { // This version is ~11.000 cycles (4%) faster overall in one of the tests. -// IR(p[0]) = IR(extents[0])|(IR(sv[0])&SIGN_BITMASK); -// IR(p[1]) = IR(extents[1])|(IR(sv[1])&SIGN_BITMASK); -// IR(p[2]) = IR(extents[2])|(IR(sv[2])&SIGN_BITMASK); + // IR(p[0]) = IR(extents[0])|(IR(sv[0])&SIGN_BITMASK); + // IR(p[1]) = IR(extents[1])|(IR(sv[1])&SIGN_BITMASK); + // IR(p[2]) = IR(extents[2])|(IR(sv[2])&SIGN_BITMASK); p[0] = sv[0] < 0.0f ? -extents[0] : extents[0]; p[1] = sv[1] < 0.0f ? -extents[1] : extents[1]; p[2] = sv[2] < 0.0f ? -extents[2] : extents[2]; @@ -140,90 +134,94 @@ void InverseTransformPoint3x3(btVector3& out, const btVector3& in, const btTrans const btVector3& r1 = rot[1]; const btVector3& r2 = rot[2]; - const btScalar x = r0.x()*in.x() + r1.x()*in.y() + r2.x()*in.z(); - const btScalar y = r0.y()*in.x() + r1.y()*in.y() + r2.y()*in.z(); - const btScalar z = r0.z()*in.x() + r1.z()*in.y() + r2.z()*in.z(); + const btScalar x = r0.x() * in.x() + r1.x() * in.y() + r2.x() * in.z(); + const btScalar y = r0.y() * in.x() + r1.y() * in.y() + r2.y() * in.z(); + const btScalar z = r0.z() * in.x() + r1.z() * in.y() + r2.z() * in.z(); out.setValue(x, y, z); } - bool TestInternalObjects( const btTransform& trans0, const btTransform& trans1, const btVector3& delta_c, const btVector3& axis, const btConvexPolyhedron& convex0, const btConvexPolyhedron& convex1, btScalar dmin) +bool TestInternalObjects(const btTransform& trans0, const btTransform& trans1, const btVector3& delta_c, const btVector3& axis, const btConvexPolyhedron& convex0, const btConvexPolyhedron& convex1, btScalar dmin) { const btScalar dp = delta_c.dot(axis); btVector3 localAxis0; - InverseTransformPoint3x3(localAxis0, axis,trans0); + InverseTransformPoint3x3(localAxis0, axis, trans0); btVector3 localAxis1; - InverseTransformPoint3x3(localAxis1, axis,trans1); + InverseTransformPoint3x3(localAxis1, axis, trans1); btScalar p0[3]; BoxSupport(convex0.m_extents, localAxis0, p0); btScalar p1[3]; BoxSupport(convex1.m_extents, localAxis1, p1); - const btScalar Radius0 = p0[0]*localAxis0.x() + p0[1]*localAxis0.y() + p0[2]*localAxis0.z(); - const btScalar Radius1 = p1[0]*localAxis1.x() + p1[1]*localAxis1.y() + p1[2]*localAxis1.z(); + const btScalar Radius0 = p0[0] * localAxis0.x() + p0[1] * localAxis0.y() + p0[2] * localAxis0.z(); + const btScalar Radius1 = p1[0] * localAxis1.x() + p1[1] * localAxis1.y() + p1[2] * localAxis1.z(); - const btScalar MinRadius = Radius0>convex0.m_radius ? Radius0 : convex0.m_radius; - const btScalar MaxRadius = Radius1>convex1.m_radius ? Radius1 : convex1.m_radius; + const btScalar MinRadius = Radius0 > convex0.m_radius ? Radius0 : convex0.m_radius; + const btScalar MaxRadius = Radius1 > convex1.m_radius ? Radius1 : convex1.m_radius; const btScalar MinMaxRadius = MaxRadius + MinRadius; const btScalar d0 = MinMaxRadius + dp; const btScalar d1 = MinMaxRadius - dp; - const btScalar depth = d0dmin) + const btScalar depth = d0 < d1 ? d0 : d1; + if (depth > dmin) return false; return true; } -#endif //TEST_INTERNAL_OBJECTS +#endif //TEST_INTERNAL_OBJECTS - - - SIMD_FORCE_INLINE void btSegmentsClosestPoints( +SIMD_FORCE_INLINE void btSegmentsClosestPoints( btVector3& ptsVector, btVector3& offsetA, btVector3& offsetB, btScalar& tA, btScalar& tB, const btVector3& translation, const btVector3& dirA, btScalar hlenA, - const btVector3& dirB, btScalar hlenB ) + const btVector3& dirB, btScalar hlenB) { // compute the parameters of the closest points on each line segment - btScalar dirA_dot_dirB = btDot(dirA,dirB); - btScalar dirA_dot_trans = btDot(dirA,translation); - btScalar dirB_dot_trans = btDot(dirB,translation); + btScalar dirA_dot_dirB = btDot(dirA, dirB); + btScalar dirA_dot_trans = btDot(dirA, translation); + btScalar dirB_dot_trans = btDot(dirB, translation); btScalar denom = 1.0f - dirA_dot_dirB * dirA_dot_dirB; - if ( denom == 0.0f ) { + if (denom == 0.0f) + { tA = 0.0f; - } else { - tA = ( dirA_dot_trans - dirB_dot_trans * dirA_dot_dirB ) / denom; - if ( tA < -hlenA ) + } + else + { + tA = (dirA_dot_trans - dirB_dot_trans * dirA_dot_dirB) / denom; + if (tA < -hlenA) tA = -hlenA; - else if ( tA > hlenA ) + else if (tA > hlenA) tA = hlenA; } tB = tA * dirA_dot_dirB - dirB_dot_trans; - if ( tB < -hlenB ) { + if (tB < -hlenB) + { tB = -hlenB; tA = tB * dirA_dot_dirB + dirA_dot_trans; - if ( tA < -hlenA ) + if (tA < -hlenA) tA = -hlenA; - else if ( tA > hlenA ) + else if (tA > hlenA) tA = hlenA; - } else if ( tB > hlenB ) { + } + else if (tB > hlenB) + { tB = hlenB; tA = tB * dirA_dot_dirB + dirA_dot_trans; - if ( tA < -hlenA ) + if (tA < -hlenA) tA = -hlenA; - else if ( tA > hlenA ) + else if (tA > hlenA) tA = hlenA; } @@ -235,44 +233,42 @@ void InverseTransformPoint3x3(btVector3& out, const btVector3& in, const btTrans ptsVector = translation - offsetA + offsetB; } - - -bool btPolyhedralContactClipping::findSeparatingAxis( const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, btVector3& sep, btDiscreteCollisionDetectorInterface::Result& resultOut) +bool btPolyhedralContactClipping::findSeparatingAxis(const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA, const btTransform& transB, btVector3& sep, btDiscreteCollisionDetectorInterface::Result& resultOut) { gActualSATPairTests++; -//#ifdef TEST_INTERNAL_OBJECTS + //#ifdef TEST_INTERNAL_OBJECTS const btVector3 c0 = transA * hullA.m_localCenter; const btVector3 c1 = transB * hullB.m_localCenter; const btVector3 DeltaC2 = c0 - c1; -//#endif + //#endif btScalar dmin = FLT_MAX; - int curPlaneTests=0; + int curPlaneTests = 0; int numFacesA = hullA.m_faces.size(); // Test normals from hullA - for(int i=0;i=0&&edgeB>=0) + if (edgeA >= 0 && edgeB >= 0) { -// printf("edge-edge\n"); + // printf("edge-edge\n"); //add an edge-edge contact btVector3 ptsVector; @@ -375,57 +368,55 @@ bool btPolyhedralContactClipping::findSeparatingAxis( const btConvexPolyhedron& btScalar tA; btScalar tB; - btVector3 translation = witnessPointB-witnessPointA; + btVector3 translation = witnessPointB - witnessPointA; btVector3 dirA = worldEdgeA; btVector3 dirB = worldEdgeB; - + btScalar hlenB = 1e30f; btScalar hlenA = 1e30f; - btSegmentsClosestPoints(ptsVector,offsetA,offsetB,tA,tB, - translation, - dirA, hlenA, - dirB,hlenB); + btSegmentsClosestPoints(ptsVector, offsetA, offsetB, tA, tB, + translation, + dirA, hlenA, + dirB, hlenB); btScalar nlSqrt = ptsVector.length2(); - if (nlSqrt>SIMD_EPSILON) + if (nlSqrt > SIMD_EPSILON) { btScalar nl = btSqrt(nlSqrt); - ptsVector *= 1.f/nl; - if (ptsVector.dot(DeltaC2)<0.f) + ptsVector *= 1.f / nl; + if (ptsVector.dot(DeltaC2) < 0.f) { - ptsVector*=-1.f; + ptsVector *= -1.f; } btVector3 ptOnB = witnessPointB + offsetB; btScalar distance = nl; - resultOut.addContactPoint(ptsVector, ptOnB,-distance); + resultOut.addContactPoint(ptsVector, ptOnB, -distance); } - } - - if((DeltaC2.dot(sep))<0.0f) + if ((DeltaC2.dot(sep)) < 0.0f) sep = -sep; return true; } -void btPolyhedralContactClipping::clipFaceAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btTransform& transA, btVertexArray& worldVertsB1,btVertexArray& worldVertsB2, const btScalar minDist, btScalar maxDist,btDiscreteCollisionDetectorInterface::Result& resultOut) +void btPolyhedralContactClipping::clipFaceAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btTransform& transA, btVertexArray& worldVertsB1, btVertexArray& worldVertsB2, const btScalar minDist, btScalar maxDist, btDiscreteCollisionDetectorInterface::Result& resultOut) { worldVertsB2.resize(0); btVertexArray* pVtxIn = &worldVertsB1; btVertexArray* pVtxOut = &worldVertsB2; pVtxOut->reserve(pVtxIn->size()); - int closestFaceA=-1; + int closestFaceA = -1; { btScalar dmin = FLT_MAX; - for(int face=0;faceresize(0); } - - -//#define ONLY_REPORT_DEEPEST_POINT + //#define ONLY_REPORT_DEEPEST_POINT btVector3 point; - // only keep points that are behind the witness face { - btVector3 localPlaneNormal (polyA.m_plane[0],polyA.m_plane[1],polyA.m_plane[2]); + btVector3 localPlaneNormal(polyA.m_plane[0], polyA.m_plane[1], polyA.m_plane[2]); btScalar localPlaneEq = polyA.m_plane[3]; - btVector3 planeNormalWS = transA.getBasis()*localPlaneNormal; - btScalar planeEqWS=localPlaneEq-planeNormalWS.dot(transA.getOrigin()); - for (int i=0;isize();i++) + btVector3 planeNormalWS = transA.getBasis() * localPlaneNormal; + btScalar planeEqWS = localPlaneEq - planeNormalWS.dot(transA.getOrigin()); + for (int i = 0; i < pVtxIn->size(); i++) { btVector3 vtx = pVtxIn->at(i); - btScalar depth = planeNormalWS.dot(vtx)+planeEqWS; - if (depth <=minDist) + btScalar depth = planeNormalWS.dot(vtx) + planeEqWS; + if (depth <= minDist) { -// printf("clamped: depth=%f to minDist=%f\n",depth,minDist); + // printf("clamped: depth=%f to minDist=%f\n",depth,minDist); depth = minDist; } - if (depth <=maxDist) + if (depth <= maxDist) { btVector3 point = pVtxIn->at(i); #ifdef ONLY_REPORT_DEEPEST_POINT @@ -507,40 +495,32 @@ void btPolyhedralContactClipping::clipFaceAgainstHull(const btVector3& separatin { printf("error in btPolyhedralContactClipping depth = %f\n", depth); printf("likely wrong separatingNormal passed in\n"); - } -#endif - resultOut.addContactPoint(separatingNormal,point,depth); + } +#endif + resultOut.addContactPoint(separatingNormal, point, depth); #endif } } } #ifdef ONLY_REPORT_DEEPEST_POINT - if (curMaxDist=0) - clipFaceAgainstHull(separatingNormal, hullA, transA,worldVertsB1, worldVertsB2,minDist, maxDist,resultOut); + { + const btFace& polyB = hullB.m_faces[closestFaceB]; + const int numVertices = polyB.m_indices.size(); + for (int e0 = 0; e0 < numVertices; e0++) + { + const btVector3& b = hullB.m_vertices[polyB.m_indices[e0]]; + worldVertsB1.push_back(transB * b); + } + } + if (closestFaceB >= 0) + clipFaceAgainstHull(separatingNormal, hullA, transA, worldVertsB1, worldVertsB2, minDist, maxDist, resultOut); } diff --git a/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h b/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h index 30e3db687..328f6424b 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h +++ b/src/BulletCollision/NarrowPhaseCollision/btPolyhedralContactClipping.h @@ -13,14 +13,11 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - ///This file was written by Erwin Coumans - #ifndef BT_POLYHEDRAL_CONTACT_CLIPPING_H #define BT_POLYHEDRAL_CONTACT_CLIPPING_H - #include "LinearMath/btAlignedObjectArray.h" #include "LinearMath/btTransform.h" #include "btDiscreteCollisionDetectorInterface.h" @@ -32,18 +29,14 @@ typedef btAlignedObjectArray btVertexArray; // Clips a face to the back of a plane struct btPolyhedralContactClipping { + static void clipHullAgainstHull(const btVector3& separatingNormal1, const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA, const btTransform& transB, const btScalar minDist, btScalar maxDist, btVertexArray& worldVertsB1, btVertexArray& worldVertsB2, btDiscreteCollisionDetectorInterface::Result& resultOut); - static void clipHullAgainstHull(const btVector3& separatingNormal1, const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, const btScalar minDist, btScalar maxDist,btVertexArray& worldVertsB1,btVertexArray& worldVertsB2,btDiscreteCollisionDetectorInterface::Result& resultOut); + static void clipFaceAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btTransform& transA, btVertexArray& worldVertsB1, btVertexArray& worldVertsB2, const btScalar minDist, btScalar maxDist, btDiscreteCollisionDetectorInterface::Result& resultOut); - static void clipFaceAgainstHull(const btVector3& separatingNormal, const btConvexPolyhedron& hullA, const btTransform& transA, btVertexArray& worldVertsB1,btVertexArray& worldVertsB2, const btScalar minDist, btScalar maxDist,btDiscreteCollisionDetectorInterface::Result& resultOut); - - - static bool findSeparatingAxis( const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA,const btTransform& transB, btVector3& sep, btDiscreteCollisionDetectorInterface::Result& resultOut); + static bool findSeparatingAxis(const btConvexPolyhedron& hullA, const btConvexPolyhedron& hullB, const btTransform& transA, const btTransform& transB, btVector3& sep, btDiscreteCollisionDetectorInterface::Result& resultOut); ///the clipFace method is used internally - static void clipFace(const btVertexArray& pVtxIn, btVertexArray& ppVtxOut, const btVector3& planeNormalWS,btScalar planeEqWS); - + static void clipFace(const btVertexArray& pVtxIn, btVertexArray& ppVtxOut, const btVector3& planeNormalWS, btScalar planeEqWS); }; -#endif // BT_POLYHEDRAL_CONTACT_CLIPPING_H - +#endif // BT_POLYHEDRAL_CONTACT_CLIPPING_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp b/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp index 786efd182..3d11e5bce 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp +++ b/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.cpp @@ -23,39 +23,38 @@ subject to the following restrictions: #include "BulletCollision/NarrowPhaseCollision/btGjkEpaPenetrationDepthSolver.h" #include "btRaycastCallback.h" -btTriangleRaycastCallback::btTriangleRaycastCallback(const btVector3& from,const btVector3& to, unsigned int flags) - : - m_from(from), - m_to(to), - //@BP Mod - m_flags(flags), - m_hitFraction(btScalar(1.)) +btTriangleRaycastCallback::btTriangleRaycastCallback(const btVector3& from, const btVector3& to, unsigned int flags) + : m_from(from), + m_to(to), + //@BP Mod + m_flags(flags), + m_hitFraction(btScalar(1.)) { - } - - -void btTriangleRaycastCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex) +void btTriangleRaycastCallback::processTriangle(btVector3* triangle, int partId, int triangleIndex) { - const btVector3 &vert0=triangle[0]; - const btVector3 &vert1=triangle[1]; - const btVector3 &vert2=triangle[2]; + const btVector3& vert0 = triangle[0]; + const btVector3& vert1 = triangle[1]; + const btVector3& vert2 = triangle[2]; - btVector3 v10; v10 = vert1 - vert0 ; - btVector3 v20; v20 = vert2 - vert0 ; + btVector3 v10; + v10 = vert1 - vert0; + btVector3 v20; + v20 = vert2 - vert0; + + btVector3 triangleNormal; + triangleNormal = v10.cross(v20); - btVector3 triangleNormal; triangleNormal = v10.cross( v20 ); - const btScalar dist = vert0.dot(triangleNormal); - btScalar dist_a = triangleNormal.dot(m_from) ; - dist_a-= dist; + btScalar dist_a = triangleNormal.dot(m_from); + dist_a -= dist; btScalar dist_b = triangleNormal.dot(m_to); dist_b -= dist; - if ( dist_a * dist_b >= btScalar(0.0) ) + if (dist_a * dist_b >= btScalar(0.0)) { - return ; // same sign + return; // same sign } if (((m_flags & kF_FilterBackfaces) != 0) && (dist_a <= btScalar(0.0))) @@ -64,52 +63,52 @@ void btTriangleRaycastCallback::processTriangle(btVector3* triangle,int partId, return; } - - const btScalar proj_length=dist_a-dist_b; - const btScalar distance = (dist_a)/(proj_length); + const btScalar proj_length = dist_a - dist_b; + const btScalar distance = (dist_a) / (proj_length); // Now we have the intersection point on the plane, we'll see if it's inside the triangle // Add an epsilon as a tolerance for the raycast, // in case the ray hits exacly on the edge of the triangle. // It must be scaled for the triangle size. - - if(distance < m_hitFraction) + + if (distance < m_hitFraction) { - - - btScalar edge_tolerance =triangleNormal.length2(); + btScalar edge_tolerance = triangleNormal.length2(); edge_tolerance *= btScalar(-0.0001); - btVector3 point; point.setInterpolate3( m_from, m_to, distance); + btVector3 point; + point.setInterpolate3(m_from, m_to, distance); { - btVector3 v0p; v0p = vert0 - point; - btVector3 v1p; v1p = vert1 - point; - btVector3 cp0; cp0 = v0p.cross( v1p ); + btVector3 v0p; + v0p = vert0 - point; + btVector3 v1p; + v1p = vert1 - point; + btVector3 cp0; + cp0 = v0p.cross(v1p); - if ( (btScalar)(cp0.dot(triangleNormal)) >=edge_tolerance) + if ((btScalar)(cp0.dot(triangleNormal)) >= edge_tolerance) { - - - btVector3 v2p; v2p = vert2 - point; + btVector3 v2p; + v2p = vert2 - point; btVector3 cp1; - cp1 = v1p.cross( v2p); - if ( (btScalar)(cp1.dot(triangleNormal)) >=edge_tolerance) + cp1 = v1p.cross(v2p); + if ((btScalar)(cp1.dot(triangleNormal)) >= edge_tolerance) { btVector3 cp2; cp2 = v2p.cross(v0p); - - if ( (btScalar)(cp2.dot(triangleNormal)) >=edge_tolerance) - { - //@BP Mod - // Triangle normal isn't normalized - triangleNormal.normalize(); - //@BP Mod - Allow for unflipped normal when raycasting against backfaces + if ((btScalar)(cp2.dot(triangleNormal)) >= edge_tolerance) + { + //@BP Mod + // Triangle normal isn't normalized + triangleNormal.normalize(); + + //@BP Mod - Allow for unflipped normal when raycasting against backfaces if (((m_flags & kF_KeepUnflippedNormal) == 0) && (dist_a <= btScalar(0.0))) { - m_hitFraction = reportHit(-triangleNormal,distance,partId,triangleIndex); + m_hitFraction = reportHit(-triangleNormal, distance, partId, triangleIndex); } else { - m_hitFraction = reportHit(triangleNormal,distance,partId,triangleIndex); + m_hitFraction = reportHit(triangleNormal, distance, partId, triangleIndex); } } } @@ -118,8 +117,7 @@ void btTriangleRaycastCallback::processTriangle(btVector3* triangle,int partId, } } - -btTriangleConvexcastCallback::btTriangleConvexcastCallback (const btConvexShape* convexShape, const btTransform& convexShapeFrom, const btTransform& convexShapeTo, const btTransform& triangleToWorld, const btScalar triangleCollisionMargin) +btTriangleConvexcastCallback::btTriangleConvexcastCallback(const btConvexShape* convexShape, const btTransform& convexShapeFrom, const btTransform& convexShapeTo, const btTransform& triangleToWorld, const btScalar triangleCollisionMargin) { m_convexShape = convexShape; m_convexShapeFrom = convexShapeFrom; @@ -130,14 +128,13 @@ btTriangleConvexcastCallback::btTriangleConvexcastCallback (const btConvexShape* m_allowedPenetration = 0.f; } -void -btTriangleConvexcastCallback::processTriangle (btVector3* triangle, int partId, int triangleIndex) +void btTriangleConvexcastCallback::processTriangle(btVector3* triangle, int partId, int triangleIndex) { - btTriangleShape triangleShape (triangle[0], triangle[1], triangle[2]); - triangleShape.setMargin(m_triangleCollisionMargin); + btTriangleShape triangleShape(triangle[0], triangle[1], triangle[2]); + triangleShape.setMargin(m_triangleCollisionMargin); - btVoronoiSimplexSolver simplexSolver; - btGjkEpaPenetrationDepthSolver gjkEpaPenetrationSolver; + btVoronoiSimplexSolver simplexSolver; + btGjkEpaPenetrationDepthSolver gjkEpaPenetrationSolver; //#define USE_SUBSIMPLEX_CONVEX_CAST 1 //if you reenable USE_SUBSIMPLEX_CONVEX_CAST see commented out code below @@ -145,21 +142,21 @@ btTriangleConvexcastCallback::processTriangle (btVector3* triangle, int partId, btSubsimplexConvexCast convexCaster(m_convexShape, &triangleShape, &simplexSolver); #else //btGjkConvexCast convexCaster(m_convexShape,&triangleShape,&simplexSolver); - btContinuousConvexCollision convexCaster(m_convexShape,&triangleShape,&simplexSolver,&gjkEpaPenetrationSolver); -#endif //#USE_SUBSIMPLEX_CONVEX_CAST - + btContinuousConvexCollision convexCaster(m_convexShape, &triangleShape, &simplexSolver, &gjkEpaPenetrationSolver); +#endif //#USE_SUBSIMPLEX_CONVEX_CAST + btConvexCast::CastResult castResult; castResult.m_fraction = btScalar(1.); castResult.m_allowedPenetration = m_allowedPenetration; - if (convexCaster.calcTimeOfImpact(m_convexShapeFrom,m_convexShapeTo,m_triangleToWorld, m_triangleToWorld, castResult)) + if (convexCaster.calcTimeOfImpact(m_convexShapeFrom, m_convexShapeTo, m_triangleToWorld, m_triangleToWorld, castResult)) { //add hit if (castResult.m_normal.length2() > btScalar(0.0001)) - { + { if (castResult.m_fraction < m_hitFraction) { -/* btContinuousConvexCast's normal is already in world space */ -/* + /* btContinuousConvexCast's normal is already in world space */ + /* #ifdef USE_SUBSIMPLEX_CONVEX_CAST //rotate normal into worldspace castResult.m_normal = m_convexShapeFrom.getBasis() * castResult.m_normal; @@ -167,11 +164,11 @@ btTriangleConvexcastCallback::processTriangle (btVector3* triangle, int partId, */ castResult.m_normal.normalize(); - reportHit (castResult.m_normal, - castResult.m_hitPoint, - castResult.m_fraction, - partId, - triangleIndex); + reportHit(castResult.m_normal, + castResult.m_hitPoint, + castResult.m_fraction, + partId, + triangleIndex); } } } diff --git a/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h b/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h index f2ed0cd39..2b2dfabec 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h +++ b/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h @@ -21,35 +21,33 @@ subject to the following restrictions: struct btBroadphaseProxy; class btConvexShape; -class btTriangleRaycastCallback: public btTriangleCallback +class btTriangleRaycastCallback : public btTriangleCallback { public: - //input btVector3 m_from; btVector3 m_to; - //@BP Mod - allow backface filtering and unflipped normals - enum EFlags - { - kF_None = 0, - kF_FilterBackfaces = 1 << 0, - kF_KeepUnflippedNormal = 1 << 1, // Prevents returned face normal getting flipped when a ray hits a back-facing triangle - ///SubSimplexConvexCastRaytest is the default, even if kF_None is set. - kF_UseSubSimplexConvexCastRaytest = 1 << 2, // Uses an approximate but faster ray versus convex intersection algorithm - kF_UseGjkConvexCastRaytest = 1 << 3, - kF_Terminator = 0xFFFFFFFF - }; - unsigned int m_flags; + //@BP Mod - allow backface filtering and unflipped normals + enum EFlags + { + kF_None = 0, + kF_FilterBackfaces = 1 << 0, + kF_KeepUnflippedNormal = 1 << 1, // Prevents returned face normal getting flipped when a ray hits a back-facing triangle + ///SubSimplexConvexCastRaytest is the default, even if kF_None is set. + kF_UseSubSimplexConvexCastRaytest = 1 << 2, // Uses an approximate but faster ray versus convex intersection algorithm + kF_UseGjkConvexCastRaytest = 1 << 3, + kF_Terminator = 0xFFFFFFFF + }; + unsigned int m_flags; - btScalar m_hitFraction; + btScalar m_hitFraction; + + btTriangleRaycastCallback(const btVector3& from, const btVector3& to, unsigned int flags = 0); - btTriangleRaycastCallback(const btVector3& from,const btVector3& to, unsigned int flags=0); - virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex); - virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex ) = 0; - + virtual btScalar reportHit(const btVector3& hitNormalLocal, btScalar hitFraction, int partId, int triangleIndex) = 0; }; class btTriangleConvexcastCallback : public btTriangleCallback @@ -63,12 +61,11 @@ public: btScalar m_triangleCollisionMargin; btScalar m_allowedPenetration; - btTriangleConvexcastCallback (const btConvexShape* convexShape, const btTransform& convexShapeFrom, const btTransform& convexShapeTo, const btTransform& triangleToWorld, const btScalar triangleCollisionMargin); + btTriangleConvexcastCallback(const btConvexShape* convexShape, const btTransform& convexShapeFrom, const btTransform& convexShapeTo, const btTransform& triangleToWorld, const btScalar triangleCollisionMargin); - virtual void processTriangle (btVector3* triangle, int partId, int triangleIndex); + virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex); - virtual btScalar reportHit (const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex) = 0; + virtual btScalar reportHit(const btVector3& hitNormalLocal, const btVector3& hitPointLocal, btScalar hitFraction, int partId, int triangleIndex) = 0; }; -#endif //BT_RAYCAST_TRI_CALLBACK_H - +#endif //BT_RAYCAST_TRI_CALLBACK_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h b/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h index da8a13914..ccd227109 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h +++ b/src/BulletCollision/NarrowPhaseCollision/btSimplexSolverInterface.h @@ -13,8 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #ifndef BT_SIMPLEX_SOLVER_INTERFACE_H #define BT_SIMPLEX_SOLVER_INTERFACE_H @@ -31,33 +29,30 @@ subject to the following restrictions: /// voronoi regions or barycentric coordinates class btSimplexSolverInterface { - public: - virtual ~btSimplexSolverInterface() {}; +public: + virtual ~btSimplexSolverInterface(){}; virtual void reset() = 0; virtual void addVertex(const btVector3& w, const btVector3& p, const btVector3& q) = 0; - + virtual bool closest(btVector3& v) = 0; virtual btScalar maxVertex() = 0; virtual bool fullSimplex() const = 0; - virtual int getSimplex(btVector3 *pBuf, btVector3 *qBuf, btVector3 *yBuf) const = 0; + virtual int getSimplex(btVector3* pBuf, btVector3* qBuf, btVector3* yBuf) const = 0; virtual bool inSimplex(const btVector3& w) = 0; - + virtual void backup_closest(btVector3& v) = 0; virtual bool emptySimplex() const = 0; virtual void compute_points(btVector3& p1, btVector3& p2) = 0; - virtual int numVertices() const =0; - - + virtual int numVertices() const = 0; }; #endif -#endif //BT_SIMPLEX_SOLVER_INTERFACE_H - +#endif //BT_SIMPLEX_SOLVER_INTERFACE_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp b/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp index 08d6e6de8..a2af32fdd 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp +++ b/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btSubSimplexConvexCast.h" #include "BulletCollision/CollisionShapes/btConvexShape.h" @@ -22,9 +21,10 @@ subject to the following restrictions: #include "btPointCollector.h" #include "LinearMath/btTransformUtil.h" -btSubsimplexConvexCast::btSubsimplexConvexCast (const btConvexShape* convexA,const btConvexShape* convexB,btSimplexSolverInterface* simplexSolver) -:m_simplexSolver(simplexSolver), -m_convexA(convexA),m_convexB(convexB) +btSubsimplexConvexCast::btSubsimplexConvexCast(const btConvexShape* convexA, const btConvexShape* convexB, btSimplexSolverInterface* simplexSolver) + : m_simplexSolver(simplexSolver), + m_convexA(convexA), + m_convexB(convexB) { } @@ -35,19 +35,18 @@ m_convexA(convexA),m_convexB(convexB) #else #define MAX_ITERATIONS 32 #endif -bool btSubsimplexConvexCast::calcTimeOfImpact( - const btTransform& fromA, - const btTransform& toA, - const btTransform& fromB, - const btTransform& toB, - CastResult& result) +bool btSubsimplexConvexCast::calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result) { - m_simplexSolver->reset(); - btVector3 linVelA,linVelB; - linVelA = toA.getOrigin()-fromA.getOrigin(); - linVelB = toB.getOrigin()-fromB.getOrigin(); + btVector3 linVelA, linVelB; + linVelA = toA.getOrigin() - fromA.getOrigin(); + linVelB = toB.getOrigin() - fromB.getOrigin(); btScalar lambda = btScalar(0.); @@ -55,43 +54,39 @@ bool btSubsimplexConvexCast::calcTimeOfImpact( btTransform interpolatedTransB = fromB; ///take relative motion - btVector3 r = (linVelA-linVelB); + btVector3 r = (linVelA - linVelB); btVector3 v; - - btVector3 supVertexA = fromA(m_convexA->localGetSupportingVertex(-r*fromA.getBasis())); - btVector3 supVertexB = fromB(m_convexB->localGetSupportingVertex(r*fromB.getBasis())); - v = supVertexA-supVertexB; + + btVector3 supVertexA = fromA(m_convexA->localGetSupportingVertex(-r * fromA.getBasis())); + btVector3 supVertexB = fromB(m_convexB->localGetSupportingVertex(r * fromB.getBasis())); + v = supVertexA - supVertexB; int maxIter = MAX_ITERATIONS; btVector3 n; - n.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); - + n.setValue(btScalar(0.), btScalar(0.), btScalar(0.)); + btVector3 c; - - - btScalar dist2 = v.length2(); #ifdef BT_USE_DOUBLE_PRECISION btScalar epsilon = SIMD_EPSILON * 10; #else -//todo: epsilon kept for backward compatibility of unit tests. -//will need to digg deeper to make the algorithm more robust -//since, a large epsilon can cause an early termination with false -//positive results (ray intersections that shouldn't be there) + //todo: epsilon kept for backward compatibility of unit tests. + //will need to digg deeper to make the algorithm more robust + //since, a large epsilon can cause an early termination with false + //positive results (ray intersections that shouldn't be there) btScalar epsilon = btScalar(0.0001); -#endif //BT_USE_DOUBLE_PRECISION +#endif //BT_USE_DOUBLE_PRECISION - - btVector3 w,p; + btVector3 w, p; btScalar VdotR; - - while ( (dist2 > epsilon) && maxIter--) + + while ((dist2 > epsilon) && maxIter--) { - supVertexA = interpolatedTransA(m_convexA->localGetSupportingVertex(-v*interpolatedTransA.getBasis())); - supVertexB = interpolatedTransB(m_convexB->localGetSupportingVertex(v*interpolatedTransB.getBasis())); - w = supVertexA-supVertexB; + supVertexA = interpolatedTransA(m_convexA->localGetSupportingVertex(-v * interpolatedTransA.getBasis())); + supVertexB = interpolatedTransB(m_convexB->localGetSupportingVertex(v * interpolatedTransB.getBasis())); + w = supVertexA - supVertexB; btScalar VdotW = v.dot(w); @@ -100,68 +95,63 @@ bool btSubsimplexConvexCast::calcTimeOfImpact( return false; } - if ( VdotW > btScalar(0.)) + if (VdotW > btScalar(0.)) { VdotR = v.dot(r); - if (VdotR >= -(SIMD_EPSILON*SIMD_EPSILON)) + if (VdotR >= -(SIMD_EPSILON * SIMD_EPSILON)) return false; else { lambda = lambda - VdotW / VdotR; //interpolate to next lambda // x = s + lambda * r; - interpolatedTransA.getOrigin().setInterpolate3(fromA.getOrigin(),toA.getOrigin(),lambda); - interpolatedTransB.getOrigin().setInterpolate3(fromB.getOrigin(),toB.getOrigin(),lambda); + interpolatedTransA.getOrigin().setInterpolate3(fromA.getOrigin(), toA.getOrigin(), lambda); + interpolatedTransB.getOrigin().setInterpolate3(fromB.getOrigin(), toB.getOrigin(), lambda); //m_simplexSolver->reset(); //check next line - w = supVertexA-supVertexB; - + w = supVertexA - supVertexB; + n = v; - } - } + } ///Just like regular GJK only add the vertex if it isn't already (close) to current vertex, it would lead to divisions by zero and NaN etc. if (!m_simplexSolver->inSimplex(w)) - m_simplexSolver->addVertex( w, supVertexA , supVertexB); + m_simplexSolver->addVertex(w, supVertexA, supVertexB); if (m_simplexSolver->closest(v)) { dist2 = v.length2(); - + //todo: check this normal for validity //n=v; //printf("V=%f , %f, %f\n",v[0],v[1],v[2]); //printf("DIST2=%f\n",dist2); //printf("numverts = %i\n",m_simplexSolver->numVertices()); - } else + } + else { dist2 = btScalar(0.); - } + } } //int numiter = MAX_ITERATIONS - maxIter; -// printf("number of iterations: %d", numiter); - + // printf("number of iterations: %d", numiter); + //don't report a time of impact when moving 'away' from the hitnormal - result.m_fraction = lambda; - if (n.length2() >= (SIMD_EPSILON*SIMD_EPSILON)) + if (n.length2() >= (SIMD_EPSILON * SIMD_EPSILON)) result.m_normal = n.normalized(); else result.m_normal = btVector3(btScalar(0.0), btScalar(0.0), btScalar(0.0)); //don't report time of impact for motion away from the contact normal (or causes minor penetration) - if (result.m_normal.dot(r)>=-result.m_allowedPenetration) + if (result.m_normal.dot(r) >= -result.m_allowedPenetration) return false; - btVector3 hitA,hitB; - m_simplexSolver->compute_points(hitA,hitB); - result.m_hitPoint=hitB; + btVector3 hitA, hitB; + m_simplexSolver->compute_points(hitA, hitB); + result.m_hitPoint = hitB; return true; } - - - - diff --git a/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h b/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h index 6c8127983..0638a30eb 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h +++ b/src/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef BT_SUBSIMPLEX_CONVEX_CAST_H #define BT_SUBSIMPLEX_CONVEX_CAST_H @@ -28,23 +27,21 @@ class btConvexShape; class btSubsimplexConvexCast : public btConvexCast { btSimplexSolverInterface* m_simplexSolver; - const btConvexShape* m_convexA; - const btConvexShape* m_convexB; + const btConvexShape* m_convexA; + const btConvexShape* m_convexB; public: - - btSubsimplexConvexCast (const btConvexShape* shapeA,const btConvexShape* shapeB,btSimplexSolverInterface* simplexSolver); + btSubsimplexConvexCast(const btConvexShape* shapeA, const btConvexShape* shapeB, btSimplexSolverInterface* simplexSolver); //virtual ~btSubsimplexConvexCast(); ///SimsimplexConvexCast calculateTimeOfImpact calculates the time of impact+normal for the linear cast (sweep) between two moving objects. ///Precondition is that objects should not penetration/overlap at the start from the interval. Overlap can be tested using btGjkPairDetector. - virtual bool calcTimeOfImpact( - const btTransform& fromA, - const btTransform& toA, - const btTransform& fromB, - const btTransform& toB, - CastResult& result); - + virtual bool calcTimeOfImpact( + const btTransform& fromA, + const btTransform& toA, + const btTransform& fromB, + const btTransform& toB, + CastResult& result); }; -#endif //BT_SUBSIMPLEX_CONVEX_CAST_H +#endif //BT_SUBSIMPLEX_CONVEX_CAST_H diff --git a/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp b/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp index 756373c9b..8fda94d2a 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp +++ b/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.cpp @@ -23,26 +23,24 @@ subject to the following restrictions: */ - #include "btVoronoiSimplexSolver.h" -#define VERTA 0 -#define VERTB 1 -#define VERTC 2 -#define VERTD 3 +#define VERTA 0 +#define VERTB 1 +#define VERTC 2 +#define VERTD 3 #define CATCH_DEGENERATE_TETRAHEDRON 1 -void btVoronoiSimplexSolver::removeVertex(int index) +void btVoronoiSimplexSolver::removeVertex(int index) { - - btAssert(m_numVertices>0); + btAssert(m_numVertices > 0); m_numVertices--; m_simplexVectorW[index] = m_simplexVectorW[m_numVertices]; m_simplexPointsP[index] = m_simplexPointsP[m_numVertices]; m_simplexPointsQ[index] = m_simplexPointsQ[m_numVertices]; } -void btVoronoiSimplexSolver::reduceVertices (const btUsageBitfield& usedVerts) +void btVoronoiSimplexSolver::reduceVertices(const btUsageBitfield& usedVerts) { if ((numVertices() >= 4) && (!usedVerts.usedVertexD)) removeVertex(3); @@ -52,29 +50,22 @@ void btVoronoiSimplexSolver::reduceVertices (const btUsageBitfield& usedVerts) if ((numVertices() >= 2) && (!usedVerts.usedVertexB)) removeVertex(1); - + if ((numVertices() >= 1) && (!usedVerts.usedVertexA)) removeVertex(0); - } - - - - //clear the simplex, remove all the vertices void btVoronoiSimplexSolver::reset() { m_cachedValidClosest = false; m_numVertices = 0; m_needsUpdate = true; - m_lastW = btVector3(btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT),btScalar(BT_LARGE_FLOAT)); + m_lastW = btVector3(btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT), btScalar(BT_LARGE_FLOAT)); m_cachedBC.reset(); } - - - //add a vertex +//add a vertex void btVoronoiSimplexSolver::addVertex(const btVector3& w, const btVector3& p, const btVector3& q) { m_lastW = w; @@ -87,9 +78,8 @@ void btVoronoiSimplexSolver::addVertex(const btVector3& w, const btVector3& p, c m_numVertices++; } -bool btVoronoiSimplexSolver::updateClosestVectorAndPoints() +bool btVoronoiSimplexSolver::updateClosestVectorAndPoints() { - if (m_needsUpdate) { m_cachedBC.reset(); @@ -98,127 +88,131 @@ bool btVoronoiSimplexSolver::updateClosestVectorAndPoints() switch (numVertices()) { - case 0: + case 0: m_cachedValidClosest = false; break; - case 1: + case 1: { m_cachedP1 = m_simplexPointsP[0]; m_cachedP2 = m_simplexPointsQ[0]; - m_cachedV = m_cachedP1-m_cachedP2; //== m_simplexVectorW[0] + m_cachedV = m_cachedP1 - m_cachedP2; //== m_simplexVectorW[0] m_cachedBC.reset(); - m_cachedBC.setBarycentricCoordinates(btScalar(1.),btScalar(0.),btScalar(0.),btScalar(0.)); + m_cachedBC.setBarycentricCoordinates(btScalar(1.), btScalar(0.), btScalar(0.), btScalar(0.)); m_cachedValidClosest = m_cachedBC.isValid(); break; }; - case 2: + case 2: { - //closest point origin from line segment - const btVector3& from = m_simplexVectorW[0]; - const btVector3& to = m_simplexVectorW[1]; - btVector3 nearest; + //closest point origin from line segment + const btVector3& from = m_simplexVectorW[0]; + const btVector3& to = m_simplexVectorW[1]; + btVector3 nearest; - btVector3 p (btScalar(0.),btScalar(0.),btScalar(0.)); - btVector3 diff = p - from; - btVector3 v = to - from; - btScalar t = v.dot(diff); - - if (t > 0) { - btScalar dotVV = v.dot(v); - if (t < dotVV) { - t /= dotVV; - diff -= t*v; - m_cachedBC.m_usedVertices.usedVertexA = true; - m_cachedBC.m_usedVertices.usedVertexB = true; - } else { - t = 1; - diff -= v; - //reduce to 1 point - m_cachedBC.m_usedVertices.usedVertexB = true; - } - } else + btVector3 p(btScalar(0.), btScalar(0.), btScalar(0.)); + btVector3 diff = p - from; + btVector3 v = to - from; + btScalar t = v.dot(diff); + + if (t > 0) + { + btScalar dotVV = v.dot(v); + if (t < dotVV) { - t = 0; - //reduce to 1 point + t /= dotVV; + diff -= t * v; m_cachedBC.m_usedVertices.usedVertexA = true; + m_cachedBC.m_usedVertices.usedVertexB = true; } - m_cachedBC.setBarycentricCoordinates(1-t,t); - nearest = from + t*v; + else + { + t = 1; + diff -= v; + //reduce to 1 point + m_cachedBC.m_usedVertices.usedVertexB = true; + } + } + else + { + t = 0; + //reduce to 1 point + m_cachedBC.m_usedVertices.usedVertexA = true; + } + m_cachedBC.setBarycentricCoordinates(1 - t, t); + nearest = from + t * v; - m_cachedP1 = m_simplexPointsP[0] + t * (m_simplexPointsP[1] - m_simplexPointsP[0]); - m_cachedP2 = m_simplexPointsQ[0] + t * (m_simplexPointsQ[1] - m_simplexPointsQ[0]); - m_cachedV = m_cachedP1 - m_cachedP2; - - reduceVertices(m_cachedBC.m_usedVertices); + m_cachedP1 = m_simplexPointsP[0] + t * (m_simplexPointsP[1] - m_simplexPointsP[0]); + m_cachedP2 = m_simplexPointsQ[0] + t * (m_simplexPointsQ[1] - m_simplexPointsQ[0]); + m_cachedV = m_cachedP1 - m_cachedP2; - m_cachedValidClosest = m_cachedBC.isValid(); - break; + reduceVertices(m_cachedBC.m_usedVertices); + + m_cachedValidClosest = m_cachedBC.isValid(); + break; } - case 3: - { - //closest point origin from triangle - btVector3 p (btScalar(0.),btScalar(0.),btScalar(0.)); - - const btVector3& a = m_simplexVectorW[0]; - const btVector3& b = m_simplexVectorW[1]; - const btVector3& c = m_simplexVectorW[2]; - - closestPtPointTriangle(p,a,b,c,m_cachedBC); - m_cachedP1 = m_simplexPointsP[0] * m_cachedBC.m_barycentricCoords[0] + - m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] + - m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2]; - - m_cachedP2 = m_simplexPointsQ[0] * m_cachedBC.m_barycentricCoords[0] + - m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] + - m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2]; - - m_cachedV = m_cachedP1-m_cachedP2; - - reduceVertices (m_cachedBC.m_usedVertices); - m_cachedValidClosest = m_cachedBC.isValid(); - - break; - } - case 4: + case 3: { + //closest point origin from triangle + btVector3 p(btScalar(0.), btScalar(0.), btScalar(0.)); + + const btVector3& a = m_simplexVectorW[0]; + const btVector3& b = m_simplexVectorW[1]; + const btVector3& c = m_simplexVectorW[2]; + + closestPtPointTriangle(p, a, b, c, m_cachedBC); + m_cachedP1 = m_simplexPointsP[0] * m_cachedBC.m_barycentricCoords[0] + + m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] + + m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2]; + + m_cachedP2 = m_simplexPointsQ[0] * m_cachedBC.m_barycentricCoords[0] + + m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] + + m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2]; + + m_cachedV = m_cachedP1 - m_cachedP2; + + reduceVertices(m_cachedBC.m_usedVertices); + m_cachedValidClosest = m_cachedBC.isValid(); + + break; + } + case 4: + { + btVector3 p(btScalar(0.), btScalar(0.), btScalar(0.)); - - btVector3 p (btScalar(0.),btScalar(0.),btScalar(0.)); - const btVector3& a = m_simplexVectorW[0]; const btVector3& b = m_simplexVectorW[1]; const btVector3& c = m_simplexVectorW[2]; const btVector3& d = m_simplexVectorW[3]; - bool hasSeparation = closestPtPointTetrahedron(p,a,b,c,d,m_cachedBC); + bool hasSeparation = closestPtPointTetrahedron(p, a, b, c, d, m_cachedBC); if (hasSeparation) { - m_cachedP1 = m_simplexPointsP[0] * m_cachedBC.m_barycentricCoords[0] + - m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] + - m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2] + - m_simplexPointsP[3] * m_cachedBC.m_barycentricCoords[3]; + m_simplexPointsP[1] * m_cachedBC.m_barycentricCoords[1] + + m_simplexPointsP[2] * m_cachedBC.m_barycentricCoords[2] + + m_simplexPointsP[3] * m_cachedBC.m_barycentricCoords[3]; m_cachedP2 = m_simplexPointsQ[0] * m_cachedBC.m_barycentricCoords[0] + - m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] + - m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2] + - m_simplexPointsQ[3] * m_cachedBC.m_barycentricCoords[3]; + m_simplexPointsQ[1] * m_cachedBC.m_barycentricCoords[1] + + m_simplexPointsQ[2] * m_cachedBC.m_barycentricCoords[2] + + m_simplexPointsQ[3] * m_cachedBC.m_barycentricCoords[3]; - m_cachedV = m_cachedP1-m_cachedP2; - reduceVertices (m_cachedBC.m_usedVertices); - } else + m_cachedV = m_cachedP1 - m_cachedP2; + reduceVertices(m_cachedBC.m_usedVertices); + } + else { -// printf("sub distance got penetration\n"); + // printf("sub distance got penetration\n"); if (m_cachedBC.m_degenerate) { m_cachedValidClosest = false; - } else + } + else { m_cachedValidClosest = true; //degenerate case == false, penetration = true + zero - m_cachedV.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); + m_cachedV.setValue(btScalar(0.), btScalar(0.), btScalar(0.)); } break; } @@ -228,7 +222,7 @@ bool btVoronoiSimplexSolver::updateClosestVectorAndPoints() //closest point origin from tetrahedron break; } - default: + default: { m_cachedValidClosest = false; } @@ -236,7 +230,6 @@ bool btVoronoiSimplexSolver::updateClosestVectorAndPoints() } return m_cachedValidClosest; - } //return/calculate the closest vertex @@ -247,13 +240,11 @@ bool btVoronoiSimplexSolver::closest(btVector3& v) return succes; } - - btScalar btVoronoiSimplexSolver::maxVertex() { int i, numverts = numVertices(); btScalar maxV = btScalar(0.); - for (i=0;i= btScalar(0.0) && d4 <= d3) + // Check if P in vertex region outside B + btVector3 bp = p - b; + btScalar d3 = ab.dot(bp); + btScalar d4 = ac.dot(bp); + if (d3 >= btScalar(0.0) && d4 <= d3) { result.m_closestPointOnSimplex = b; result.m_usedVertices.usedVertexB = true; - result.setBarycentricCoordinates(0,1,0); + result.setBarycentricCoordinates(0, 1, 0); - return true; // b; // barycentric coordinates (0,1,0) + return true; // b; // barycentric coordinates (0,1,0) } - // Check if P in edge region of AB, if so return projection of P onto AB - btScalar vc = d1*d4 - d3*d2; - if (vc <= btScalar(0.0) && d1 >= btScalar(0.0) && d3 <= btScalar(0.0)) { - btScalar v = d1 / (d1 - d3); + // Check if P in edge region of AB, if so return projection of P onto AB + btScalar vc = d1 * d4 - d3 * d2; + if (vc <= btScalar(0.0) && d1 >= btScalar(0.0) && d3 <= btScalar(0.0)) + { + btScalar v = d1 / (d1 - d3); result.m_closestPointOnSimplex = a + v * ab; result.m_usedVertices.usedVertexA = true; result.m_usedVertices.usedVertexB = true; - result.setBarycentricCoordinates(1-v,v,0); + result.setBarycentricCoordinates(1 - v, v, 0); return true; - //return a + v * ab; // barycentric coordinates (1-v,v,0) - } + //return a + v * ab; // barycentric coordinates (1-v,v,0) + } - // Check if P in vertex region outside C - btVector3 cp = p - c; - btScalar d5 = ab.dot(cp); - btScalar d6 = ac.dot(cp); - if (d6 >= btScalar(0.0) && d5 <= d6) + // Check if P in vertex region outside C + btVector3 cp = p - c; + btScalar d5 = ab.dot(cp); + btScalar d6 = ac.dot(cp); + if (d6 >= btScalar(0.0) && d5 <= d6) { result.m_closestPointOnSimplex = c; result.m_usedVertices.usedVertexC = true; - result.setBarycentricCoordinates(0,0,1); - return true;//c; // barycentric coordinates (0,0,1) + result.setBarycentricCoordinates(0, 0, 1); + return true; //c; // barycentric coordinates (0,0,1) } - // Check if P in edge region of AC, if so return projection of P onto AC - btScalar vb = d5*d2 - d1*d6; - if (vb <= btScalar(0.0) && d2 >= btScalar(0.0) && d6 <= btScalar(0.0)) { - btScalar w = d2 / (d2 - d6); + // Check if P in edge region of AC, if so return projection of P onto AC + btScalar vb = d5 * d2 - d1 * d6; + if (vb <= btScalar(0.0) && d2 >= btScalar(0.0) && d6 <= btScalar(0.0)) + { + btScalar w = d2 / (d2 - d6); result.m_closestPointOnSimplex = a + w * ac; result.m_usedVertices.usedVertexA = true; result.m_usedVertices.usedVertexC = true; - result.setBarycentricCoordinates(1-w,0,w); + result.setBarycentricCoordinates(1 - w, 0, w); return true; - //return a + w * ac; // barycentric coordinates (1-w,0,w) - } + //return a + w * ac; // barycentric coordinates (1-w,0,w) + } + + // Check if P in edge region of BC, if so return projection of P onto BC + btScalar va = d3 * d6 - d5 * d4; + if (va <= btScalar(0.0) && (d4 - d3) >= btScalar(0.0) && (d5 - d6) >= btScalar(0.0)) + { + btScalar w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); - // Check if P in edge region of BC, if so return projection of P onto BC - btScalar va = d3*d6 - d5*d4; - if (va <= btScalar(0.0) && (d4 - d3) >= btScalar(0.0) && (d5 - d6) >= btScalar(0.0)) { - btScalar w = (d4 - d3) / ((d4 - d3) + (d5 - d6)); - result.m_closestPointOnSimplex = b + w * (c - b); result.m_usedVertices.usedVertexB = true; result.m_usedVertices.usedVertexC = true; - result.setBarycentricCoordinates(0,1-w,w); - return true; - // return b + w * (c - b); // barycentric coordinates (0,1-w,w) - } + result.setBarycentricCoordinates(0, 1 - w, w); + return true; + // return b + w * (c - b); // barycentric coordinates (0,1-w,w) + } + + // P inside face region. Compute Q through its barycentric coordinates (u,v,w) + btScalar denom = btScalar(1.0) / (va + vb + vc); + btScalar v = vb * denom; + btScalar w = vc * denom; - // P inside face region. Compute Q through its barycentric coordinates (u,v,w) - btScalar denom = btScalar(1.0) / (va + vb + vc); - btScalar v = vb * denom; - btScalar w = vc * denom; - result.m_closestPointOnSimplex = a + ab * v + ac * w; result.m_usedVertices.usedVertexA = true; result.m_usedVertices.usedVertexB = true; result.m_usedVertices.usedVertexC = true; - result.setBarycentricCoordinates(1-v-w,v,w); - + result.setBarycentricCoordinates(1 - v - w, v, w); + return true; -// return a + ab * v + ac * w; // = u*a + v*b + w*c, u = va * denom = btScalar(1.0) - v - w - + // return a + ab * v + ac * w; // = u*a + v*b + w*c, u = va * denom = btScalar(1.0) - v - w } - - - - /// Test if point p and d lie on opposite sides of plane through abc int btVoronoiSimplexSolver::pointOutsideOfPlane(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d) { - btVector3 normal = (b-a).cross(c-a); + btVector3 normal = (b - a).cross(c - a); - btScalar signp = (p - a).dot(normal); // [AP AB AC] - btScalar signd = (d - a).dot( normal); // [AD AB AC] + btScalar signp = (p - a).dot(normal); // [AP AB AC] + btScalar signd = (d - a).dot(normal); // [AD AB AC] #ifdef CATCH_DEGENERATE_TETRAHEDRON #ifdef BT_USE_DOUBLE_PRECISION -if (signd * signd < (btScalar(1e-8) * btScalar(1e-8))) + if (signd * signd < (btScalar(1e-8) * btScalar(1e-8))) { return -1; } #else if (signd * signd < (btScalar(1e-4) * btScalar(1e-4))) { -// printf("affine dependent/degenerate\n");// + // printf("affine dependent/degenerate\n");// return -1; } #endif #endif // Points on opposite sides if expression signs are opposite - return signp * signd < btScalar(0.); + return signp * signd < btScalar(0.); } - -bool btVoronoiSimplexSolver::closestPtPointTetrahedron(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d, btSubSimplexClosestResult& finalResult) +bool btVoronoiSimplexSolver::closestPtPointTetrahedron(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d, btSubSimplexClosestResult& finalResult) { btSubSimplexClosestResult tempResult; - // Start out assuming point inside all halfspaces, so closest to itself + // Start out assuming point inside all halfspaces, so closest to itself finalResult.m_closestPointOnSimplex = p; finalResult.m_usedVertices.reset(); - finalResult.m_usedVertices.usedVertexA = true; + finalResult.m_usedVertices.usedVertexA = true; finalResult.m_usedVertices.usedVertexB = true; finalResult.m_usedVertices.usedVertexC = true; finalResult.m_usedVertices.usedVertexD = true; - int pointOutsideABC = pointOutsideOfPlane(p, a, b, c, d); + int pointOutsideABC = pointOutsideOfPlane(p, a, b, c, d); int pointOutsideACD = pointOutsideOfPlane(p, a, c, d, b); - int pointOutsideADB = pointOutsideOfPlane(p, a, d, b, c); - int pointOutsideBDC = pointOutsideOfPlane(p, b, d, c, a); + int pointOutsideADB = pointOutsideOfPlane(p, a, d, b, c); + int pointOutsideBDC = pointOutsideOfPlane(p, b, d, c, a); - if (pointOutsideABC < 0 || pointOutsideACD < 0 || pointOutsideADB < 0 || pointOutsideBDC < 0) - { - finalResult.m_degenerate = true; - return false; - } - - if (!pointOutsideABC && !pointOutsideACD && !pointOutsideADB && !pointOutsideBDC) - { - return false; - } - - - btScalar bestSqDist = FLT_MAX; - // If point outside face abc then compute closest point on abc - if (pointOutsideABC) + if (pointOutsideABC < 0 || pointOutsideACD < 0 || pointOutsideADB < 0 || pointOutsideBDC < 0) { - closestPtPointTriangle(p, a, b, c,tempResult); + finalResult.m_degenerate = true; + return false; + } + + if (!pointOutsideABC && !pointOutsideACD && !pointOutsideADB && !pointOutsideBDC) + { + return false; + } + + btScalar bestSqDist = FLT_MAX; + // If point outside face abc then compute closest point on abc + if (pointOutsideABC) + { + closestPtPointTriangle(p, a, b, c, tempResult); btVector3 q = tempResult.m_closestPointOnSimplex; - - btScalar sqDist = (q - p).dot( q - p); - // Update best closest point if (squared) distance is less than current best - if (sqDist < bestSqDist) { + + btScalar sqDist = (q - p).dot(q - p); + // Update best closest point if (squared) distance is less than current best + if (sqDist < bestSqDist) + { bestSqDist = sqDist; finalResult.m_closestPointOnSimplex = q; //convert result bitmask! @@ -504,25 +481,22 @@ bool btVoronoiSimplexSolver::closestPtPointTetrahedron(const btVector3& p, const finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexB; finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexC; finalResult.setBarycentricCoordinates( - tempResult.m_barycentricCoords[VERTA], - tempResult.m_barycentricCoords[VERTB], - tempResult.m_barycentricCoords[VERTC], - 0 - ); - + tempResult.m_barycentricCoords[VERTA], + tempResult.m_barycentricCoords[VERTB], + tempResult.m_barycentricCoords[VERTC], + 0); } - } - + } // Repeat test for face acd - if (pointOutsideACD) + if (pointOutsideACD) { - closestPtPointTriangle(p, a, c, d,tempResult); + closestPtPointTriangle(p, a, c, d, tempResult); btVector3 q = tempResult.m_closestPointOnSimplex; //convert result bitmask! - btScalar sqDist = (q - p).dot( q - p); - if (sqDist < bestSqDist) + btScalar sqDist = (q - p).dot(q - p); + if (sqDist < bestSqDist) { bestSqDist = sqDist; finalResult.m_closestPointOnSimplex = q; @@ -532,52 +506,46 @@ bool btVoronoiSimplexSolver::closestPtPointTetrahedron(const btVector3& p, const finalResult.m_usedVertices.usedVertexC = tempResult.m_usedVertices.usedVertexB; finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexC; finalResult.setBarycentricCoordinates( - tempResult.m_barycentricCoords[VERTA], - 0, - tempResult.m_barycentricCoords[VERTB], - tempResult.m_barycentricCoords[VERTC] - ); - + tempResult.m_barycentricCoords[VERTA], + 0, + tempResult.m_barycentricCoords[VERTB], + tempResult.m_barycentricCoords[VERTC]); } - } - // Repeat test for face adb + } + // Repeat test for face adb - if (pointOutsideADB) { - closestPtPointTriangle(p, a, d, b,tempResult); + closestPtPointTriangle(p, a, d, b, tempResult); btVector3 q = tempResult.m_closestPointOnSimplex; //convert result bitmask! - btScalar sqDist = (q - p).dot( q - p); - if (sqDist < bestSqDist) + btScalar sqDist = (q - p).dot(q - p); + if (sqDist < bestSqDist) { bestSqDist = sqDist; finalResult.m_closestPointOnSimplex = q; finalResult.m_usedVertices.reset(); finalResult.m_usedVertices.usedVertexA = tempResult.m_usedVertices.usedVertexA; finalResult.m_usedVertices.usedVertexB = tempResult.m_usedVertices.usedVertexC; - + finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexB; finalResult.setBarycentricCoordinates( - tempResult.m_barycentricCoords[VERTA], - tempResult.m_barycentricCoords[VERTC], - 0, - tempResult.m_barycentricCoords[VERTB] - ); - + tempResult.m_barycentricCoords[VERTA], + tempResult.m_barycentricCoords[VERTC], + 0, + tempResult.m_barycentricCoords[VERTB]); } - } - // Repeat test for face bdc - + } + // Repeat test for face bdc if (pointOutsideBDC) { - closestPtPointTriangle(p, b, d, c,tempResult); + closestPtPointTriangle(p, b, d, c, tempResult); btVector3 q = tempResult.m_closestPointOnSimplex; //convert result bitmask! - btScalar sqDist = (q - p).dot( q - p); - if (sqDist < bestSqDist) + btScalar sqDist = (q - p).dot(q - p); + if (sqDist < bestSqDist) { bestSqDist = sqDist; finalResult.m_closestPointOnSimplex = q; @@ -588,25 +556,22 @@ bool btVoronoiSimplexSolver::closestPtPointTetrahedron(const btVector3& p, const finalResult.m_usedVertices.usedVertexD = tempResult.m_usedVertices.usedVertexB; finalResult.setBarycentricCoordinates( - 0, - tempResult.m_barycentricCoords[VERTA], - tempResult.m_barycentricCoords[VERTC], - tempResult.m_barycentricCoords[VERTB] - ); - + 0, + tempResult.m_barycentricCoords[VERTA], + tempResult.m_barycentricCoords[VERTC], + tempResult.m_barycentricCoords[VERTB]); } - } + } //help! we ended up full ! - + if (finalResult.m_usedVertices.usedVertexA && finalResult.m_usedVertices.usedVertexB && finalResult.m_usedVertices.usedVertexC && - finalResult.m_usedVertices.usedVertexD) + finalResult.m_usedVertices.usedVertexD) { return true; } - return true; + return true; } - diff --git a/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h b/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h index 80fd490f4..24a0a8f2d 100644 --- a/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h +++ b/src/BulletCollision/NarrowPhaseCollision/btVoronoiSimplexSolver.h @@ -13,15 +13,11 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #ifndef BT_VORONOI_SIMPLEX_SOLVER_H #define BT_VORONOI_SIMPLEX_SOLVER_H #include "btSimplexSolverInterface.h" - - #define VORONOI_SIMPLEX_MAX_VERTS 5 ///disable next define, or use defaultCollisionConfiguration->getSimplexSolver()->setEqualVertexThreshold(0.f) to disable/configure @@ -31,9 +27,10 @@ subject to the following restrictions: #define VORONOI_DEFAULT_EQUAL_VERTEX_THRESHOLD 1e-12f #else #define VORONOI_DEFAULT_EQUAL_VERTEX_THRESHOLD 0.0001f -#endif//BT_USE_DOUBLE_PRECISION +#endif //BT_USE_DOUBLE_PRECISION -struct btUsageBitfield{ +struct btUsageBitfield +{ btUsageBitfield() { reset(); @@ -46,140 +43,131 @@ struct btUsageBitfield{ usedVertexC = false; usedVertexD = false; } - unsigned short usedVertexA : 1; - unsigned short usedVertexB : 1; - unsigned short usedVertexC : 1; - unsigned short usedVertexD : 1; - unsigned short unused1 : 1; - unsigned short unused2 : 1; - unsigned short unused3 : 1; - unsigned short unused4 : 1; + unsigned short usedVertexA : 1; + unsigned short usedVertexB : 1; + unsigned short usedVertexC : 1; + unsigned short usedVertexD : 1; + unsigned short unused1 : 1; + unsigned short unused2 : 1; + unsigned short unused3 : 1; + unsigned short unused4 : 1; }; - -struct btSubSimplexClosestResult +struct btSubSimplexClosestResult { - btVector3 m_closestPointOnSimplex; + btVector3 m_closestPointOnSimplex; //MASK for m_usedVertices - //stores the simplex vertex-usage, using the MASK, + //stores the simplex vertex-usage, using the MASK, // if m_usedVertices & MASK then the related vertex is used - btUsageBitfield m_usedVertices; - btScalar m_barycentricCoords[4]; + btUsageBitfield m_usedVertices; + btScalar m_barycentricCoords[4]; bool m_degenerate; - void reset() + void reset() { m_degenerate = false; setBarycentricCoordinates(); m_usedVertices.reset(); } - bool isValid() + bool isValid() { bool valid = (m_barycentricCoords[0] >= btScalar(0.)) && - (m_barycentricCoords[1] >= btScalar(0.)) && - (m_barycentricCoords[2] >= btScalar(0.)) && - (m_barycentricCoords[3] >= btScalar(0.)); - + (m_barycentricCoords[1] >= btScalar(0.)) && + (m_barycentricCoords[2] >= btScalar(0.)) && + (m_barycentricCoords[3] >= btScalar(0.)); return valid; } - void setBarycentricCoordinates(btScalar a=btScalar(0.),btScalar b=btScalar(0.),btScalar c=btScalar(0.),btScalar d=btScalar(0.)) + void setBarycentricCoordinates(btScalar a = btScalar(0.), btScalar b = btScalar(0.), btScalar c = btScalar(0.), btScalar d = btScalar(0.)) { m_barycentricCoords[0] = a; m_barycentricCoords[1] = b; m_barycentricCoords[2] = c; m_barycentricCoords[3] = d; } - }; /// btVoronoiSimplexSolver is an implementation of the closest point distance algorithm from a 1-4 points simplex to the origin. /// Can be used with GJK, as an alternative to Johnson distance algorithm. #ifdef NO_VIRTUAL_INTERFACE -ATTRIBUTE_ALIGNED16(class) btVoronoiSimplexSolver +ATTRIBUTE_ALIGNED16(class) +btVoronoiSimplexSolver #else -ATTRIBUTE_ALIGNED16(class) btVoronoiSimplexSolver : public btSimplexSolverInterface +ATTRIBUTE_ALIGNED16(class) +btVoronoiSimplexSolver : public btSimplexSolverInterface #endif { public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - int m_numVertices; + int m_numVertices; - btVector3 m_simplexVectorW[VORONOI_SIMPLEX_MAX_VERTS]; - btVector3 m_simplexPointsP[VORONOI_SIMPLEX_MAX_VERTS]; - btVector3 m_simplexPointsQ[VORONOI_SIMPLEX_MAX_VERTS]; + btVector3 m_simplexVectorW[VORONOI_SIMPLEX_MAX_VERTS]; + btVector3 m_simplexPointsP[VORONOI_SIMPLEX_MAX_VERTS]; + btVector3 m_simplexPointsQ[VORONOI_SIMPLEX_MAX_VERTS]; - - - btVector3 m_cachedP1; - btVector3 m_cachedP2; - btVector3 m_cachedV; - btVector3 m_lastW; - - btScalar m_equalVertexThreshold; - bool m_cachedValidClosest; + btVector3 m_cachedP1; + btVector3 m_cachedP2; + btVector3 m_cachedV; + btVector3 m_lastW; + btScalar m_equalVertexThreshold; + bool m_cachedValidClosest; btSubSimplexClosestResult m_cachedBC; - bool m_needsUpdate; - - void removeVertex(int index); - void reduceVertices (const btUsageBitfield& usedVerts); - bool updateClosestVectorAndPoints(); + bool m_needsUpdate; - bool closestPtPointTetrahedron(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d, btSubSimplexClosestResult& finalResult); - int pointOutsideOfPlane(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d); - bool closestPtPointTriangle(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c,btSubSimplexClosestResult& result); + void removeVertex(int index); + void reduceVertices(const btUsageBitfield& usedVerts); + bool updateClosestVectorAndPoints(); + + bool closestPtPointTetrahedron(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d, btSubSimplexClosestResult& finalResult); + int pointOutsideOfPlane(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, const btVector3& d); + bool closestPtPointTriangle(const btVector3& p, const btVector3& a, const btVector3& b, const btVector3& c, btSubSimplexClosestResult& result); public: - btVoronoiSimplexSolver() - : m_equalVertexThreshold(VORONOI_DEFAULT_EQUAL_VERTEX_THRESHOLD) + : m_equalVertexThreshold(VORONOI_DEFAULT_EQUAL_VERTEX_THRESHOLD) { } - void reset(); + void reset(); - void addVertex(const btVector3& w, const btVector3& p, const btVector3& q); + void addVertex(const btVector3& w, const btVector3& p, const btVector3& q); - void setEqualVertexThreshold(btScalar threshold) - { - m_equalVertexThreshold = threshold; - } + void setEqualVertexThreshold(btScalar threshold) + { + m_equalVertexThreshold = threshold; + } - btScalar getEqualVertexThreshold() const - { - return m_equalVertexThreshold; - } + btScalar getEqualVertexThreshold() const + { + return m_equalVertexThreshold; + } - bool closest(btVector3& v); + bool closest(btVector3 & v); - btScalar maxVertex(); + btScalar maxVertex(); - bool fullSimplex() const - { - return (m_numVertices == 4); - } + bool fullSimplex() const + { + return (m_numVertices == 4); + } - int getSimplex(btVector3 *pBuf, btVector3 *qBuf, btVector3 *yBuf) const; + int getSimplex(btVector3 * pBuf, btVector3 * qBuf, btVector3 * yBuf) const; - bool inSimplex(const btVector3& w); - - void backup_closest(btVector3& v) ; + bool inSimplex(const btVector3& w); - bool emptySimplex() const ; + void backup_closest(btVector3 & v); - void compute_points(btVector3& p1, btVector3& p2) ; - - int numVertices() const - { - return m_numVertices; - } + bool emptySimplex() const; + void compute_points(btVector3 & p1, btVector3 & p2); + int numVertices() const + { + return m_numVertices; + } }; -#endif //BT_VORONOI_SIMPLEX_SOLVER_H - +#endif //BT_VORONOI_SIMPLEX_SOLVER_H diff --git a/src/BulletDynamics/Character/btCharacterControllerInterface.h b/src/BulletDynamics/Character/btCharacterControllerInterface.h index abe24b5ca..2ccf317b9 100644 --- a/src/BulletDynamics/Character/btCharacterControllerInterface.h +++ b/src/BulletDynamics/Character/btCharacterControllerInterface.h @@ -26,22 +26,21 @@ class btCollisionWorld; class btCharacterControllerInterface : public btActionInterface { public: - btCharacterControllerInterface () {}; - virtual ~btCharacterControllerInterface () {}; - - virtual void setWalkDirection(const btVector3& walkDirection) = 0; - virtual void setVelocityForTimeInterval(const btVector3& velocity, btScalar timeInterval) = 0; - virtual void reset ( btCollisionWorld* collisionWorld ) = 0; - virtual void warp (const btVector3& origin) = 0; + btCharacterControllerInterface(){}; + virtual ~btCharacterControllerInterface(){}; - virtual void preStep ( btCollisionWorld* collisionWorld) = 0; - virtual void playerStep (btCollisionWorld* collisionWorld, btScalar dt) = 0; - virtual bool canJump () const = 0; - virtual void jump(const btVector3& dir = btVector3(0, 0, 0)) = 0; + virtual void setWalkDirection(const btVector3& walkDirection) = 0; + virtual void setVelocityForTimeInterval(const btVector3& velocity, btScalar timeInterval) = 0; + virtual void reset(btCollisionWorld* collisionWorld) = 0; + virtual void warp(const btVector3& origin) = 0; - virtual bool onGround () const = 0; - virtual void setUpInterpolate (bool value) = 0; + virtual void preStep(btCollisionWorld* collisionWorld) = 0; + virtual void playerStep(btCollisionWorld* collisionWorld, btScalar dt) = 0; + virtual bool canJump() const = 0; + virtual void jump(const btVector3& dir = btVector3(0, 0, 0)) = 0; + + virtual bool onGround() const = 0; + virtual void setUpInterpolate(bool value) = 0; }; -#endif //BT_CHARACTER_CONTROLLER_INTERFACE_H - +#endif //BT_CHARACTER_CONTROLLER_INTERFACE_H diff --git a/src/BulletDynamics/Character/btKinematicCharacterController.cpp b/src/BulletDynamics/Character/btKinematicCharacterController.cpp index cb1aa71a1..c2642b580 100644 --- a/src/BulletDynamics/Character/btKinematicCharacterController.cpp +++ b/src/BulletDynamics/Character/btKinematicCharacterController.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include #include "LinearMath/btIDebugDraw.h" #include "BulletCollision/CollisionDispatch/btGhostObject.h" @@ -24,20 +23,19 @@ subject to the following restrictions: #include "LinearMath/btDefaultMotionState.h" #include "btKinematicCharacterController.h" - // static helper method static btVector3 getNormalizedVector(const btVector3& v) { btVector3 n(0, 0, 0); - if (v.length() > SIMD_EPSILON) { + if (v.length() > SIMD_EPSILON) + { n = v.normalized(); } return n; } - ///@todo Interact with dynamic objects, ///Ride kinematicly animated platforms properly ///More realistic (or maybe just a config option) falling @@ -47,18 +45,19 @@ getNormalizedVector(const btVector3& v) class btKinematicClosestNotMeRayResultCallback : public btCollisionWorld::ClosestRayResultCallback { public: - btKinematicClosestNotMeRayResultCallback (btCollisionObject* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) + btKinematicClosestNotMeRayResultCallback(btCollisionObject* me) : btCollisionWorld::ClosestRayResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) { m_me = me; } - virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,bool normalInWorldSpace) + virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) { if (rayResult.m_collisionObject == m_me) return 1.0; - return ClosestRayResultCallback::addSingleResult (rayResult, normalInWorldSpace); + return ClosestRayResultCallback::addSingleResult(rayResult, normalInWorldSpace); } + protected: btCollisionObject* m_me; }; @@ -66,15 +65,12 @@ protected: class btKinematicClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback { public: - btKinematicClosestNotMeConvexResultCallback (btCollisionObject* me, const btVector3& up, btScalar minSlopeDot) - : btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)) - , m_me(me) - , m_up(up) - , m_minSlopeDot(minSlopeDot) + btKinematicClosestNotMeConvexResultCallback(btCollisionObject* me, const btVector3& up, btScalar minSlopeDot) + : btCollisionWorld::ClosestConvexResultCallback(btVector3(0.0, 0.0, 0.0), btVector3(0.0, 0.0, 0.0)), m_me(me), m_up(up), m_minSlopeDot(minSlopeDot) { } - virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace) + virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult, bool normalInWorldSpace) { if (convexResult.m_hitCollisionObject == m_me) return btScalar(1.0); @@ -86,19 +82,22 @@ public: if (normalInWorldSpace) { hitNormalWorld = convexResult.m_hitNormalLocal; - } else + } + else { ///need to transform normal into worldspace - hitNormalWorld = convexResult.m_hitCollisionObject->getWorldTransform().getBasis()*convexResult.m_hitNormalLocal; + hitNormalWorld = convexResult.m_hitCollisionObject->getWorldTransform().getBasis() * convexResult.m_hitNormalLocal; } btScalar dotUp = m_up.dot(hitNormalWorld); - if (dotUp < m_minSlopeDot) { + if (dotUp < m_minSlopeDot) + { return btScalar(1.0); } - return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace); + return ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace); } + protected: btCollisionObject* m_me; const btVector3 m_up; @@ -110,7 +109,7 @@ protected: * * from: http://www-cs-students.stanford.edu/~adityagp/final/node3.html */ -btVector3 btKinematicCharacterController::computeReflectionDirection (const btVector3& direction, const btVector3& normal) +btVector3 btKinematicCharacterController::computeReflectionDirection(const btVector3& direction, const btVector3& normal) { return direction - (btScalar(2.0) * direction.dot(normal)) * normal; } @@ -118,7 +117,7 @@ btVector3 btKinematicCharacterController::computeReflectionDirection (const btVe /* * Returns the portion of 'direction' that is parallel to 'normal' */ -btVector3 btKinematicCharacterController::parallelComponent (const btVector3& direction, const btVector3& normal) +btVector3 btKinematicCharacterController::parallelComponent(const btVector3& direction, const btVector3& normal) { btScalar magnitude = direction.dot(normal); return normal * magnitude; @@ -127,29 +126,29 @@ btVector3 btKinematicCharacterController::parallelComponent (const btVector3& di /* * Returns the portion of 'direction' that is perpindicular to 'normal' */ -btVector3 btKinematicCharacterController::perpindicularComponent (const btVector3& direction, const btVector3& normal) +btVector3 btKinematicCharacterController::perpindicularComponent(const btVector3& direction, const btVector3& normal) { return direction - parallelComponent(direction, normal); } -btKinematicCharacterController::btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight, const btVector3& up) +btKinematicCharacterController::btKinematicCharacterController(btPairCachingGhostObject* ghostObject, btConvexShape* convexShape, btScalar stepHeight, const btVector3& up) { m_ghostObject = ghostObject; m_up.setValue(0.0f, 0.0f, 1.0f); m_jumpAxis.setValue(0.0f, 0.0f, 1.0f); m_addedMargin = 0.02; - m_walkDirection.setValue(0.0,0.0,0.0); + m_walkDirection.setValue(0.0, 0.0, 0.0); m_AngVel.setValue(0.0, 0.0, 0.0); - m_useGhostObjectSweepTest = true; + m_useGhostObjectSweepTest = true; m_turnAngle = btScalar(0.0); - m_convexShape=convexShape; - m_useWalkDirection = true; // use walk direction by default, legacy behavior + m_convexShape = convexShape; + m_useWalkDirection = true; // use walk direction by default, legacy behavior m_velocityTimeInterval = 0.0; m_verticalVelocity = 0.0; m_verticalOffset = 0.0; - m_gravity = 9.8 * 3.0 ; // 3G acceleration. - m_fallSpeed = 55.0; // Terminal velocity of a sky diver in m/s. - m_jumpSpeed = 10.0; // ? + m_gravity = 9.8 * 3.0; // 3G acceleration. + m_fallSpeed = 55.0; // Terminal velocity of a sky diver in m/s. + m_jumpSpeed = 10.0; // ? m_SetjumpSpeed = m_jumpSpeed; m_wasOnGround = false; m_wasJumping = false; @@ -166,7 +165,7 @@ btKinematicCharacterController::btKinematicCharacterController (btPairCachingGho setMaxSlope(btRadians(45.0)); } -btKinematicCharacterController::~btKinematicCharacterController () +btKinematicCharacterController::~btKinematicCharacterController() { } @@ -175,7 +174,7 @@ btPairCachingGhostObject* btKinematicCharacterController::getGhostObject() return m_ghostObject; } -bool btKinematicCharacterController::recoverFromPenetration ( btCollisionWorld* collisionWorld) +bool btKinematicCharacterController::recoverFromPenetration(btCollisionWorld* collisionWorld) { // Here we must refresh the overlapping paircache as the penetrating movement itself or the // previous recovery iteration might have used setWorldTransform and pushed us into an object @@ -186,19 +185,19 @@ bool btKinematicCharacterController::recoverFromPenetration ( btCollisionWorld* // paircache and the ghostobject's internal paircache at the same time. /BW btVector3 minAabb, maxAabb; - m_convexShape->getAabb(m_ghostObject->getWorldTransform(), minAabb,maxAabb); - collisionWorld->getBroadphase()->setAabb(m_ghostObject->getBroadphaseHandle(), - minAabb, - maxAabb, - collisionWorld->getDispatcher()); - + m_convexShape->getAabb(m_ghostObject->getWorldTransform(), minAabb, maxAabb); + collisionWorld->getBroadphase()->setAabb(m_ghostObject->getBroadphaseHandle(), + minAabb, + maxAabb, + collisionWorld->getDispatcher()); + bool penetration = false; collisionWorld->getDispatcher()->dispatchAllCollisionPairs(m_ghostObject->getOverlappingPairCache(), collisionWorld->getDispatchInfo(), collisionWorld->getDispatcher()); m_currentPosition = m_ghostObject->getWorldTransform().getOrigin(); - -// btScalar maxPen = btScalar(0.0); + + // btScalar maxPen = btScalar(0.0); for (int i = 0; i < m_ghostObject->getOverlappingPairCache()->getNumOverlappingPairs(); i++) { m_manifoldArray.resize(0); @@ -206,25 +205,24 @@ bool btKinematicCharacterController::recoverFromPenetration ( btCollisionWorld* btBroadphasePair* collisionPair = &m_ghostObject->getOverlappingPairCache()->getOverlappingPairArray()[i]; btCollisionObject* obj0 = static_cast(collisionPair->m_pProxy0->m_clientObject); - btCollisionObject* obj1 = static_cast(collisionPair->m_pProxy1->m_clientObject); + btCollisionObject* obj1 = static_cast(collisionPair->m_pProxy1->m_clientObject); if ((obj0 && !obj0->hasContactResponse()) || (obj1 && !obj1->hasContactResponse())) continue; if (!needsCollision(obj0, obj1)) continue; - + if (collisionPair->m_algorithm) collisionPair->m_algorithm->getAllContactManifolds(m_manifoldArray); - - for (int j=0;jgetBody0() == m_ghostObject ? btScalar(-1.0) : btScalar(1.0); - for (int p=0;pgetNumContacts();p++) + for (int p = 0; p < manifold->getNumContacts(); p++) { - const btManifoldPoint&pt = manifold->getContactPoint(p); + const btManifoldPoint& pt = manifold->getContactPoint(p); btScalar dist = pt.getDistance(); @@ -239,22 +237,24 @@ bool btKinematicCharacterController::recoverFromPenetration ( btCollisionWorld* //} m_currentPosition += pt.m_normalWorldOnB * directionSign * dist * btScalar(0.2); penetration = true; - } else { + } + else + { //printf("touching %f\n", dist); } } - + //manifold->clearManifold(); } } btTransform newTrans = m_ghostObject->getWorldTransform(); newTrans.setOrigin(m_currentPosition); m_ghostObject->setWorldTransform(newTrans); -// printf("m_touchingNormal = %f,%f,%f\n",m_touchingNormal[0],m_touchingNormal[1],m_touchingNormal[2]); + // printf("m_touchingNormal = %f,%f,%f\n",m_touchingNormal[0],m_touchingNormal[1],m_touchingNormal[2]); return penetration; } -void btKinematicCharacterController::stepUp ( btCollisionWorld* world) +void btKinematicCharacterController::stepUp(btCollisionWorld* world) { btScalar stepHeight = 0.0f; if (m_verticalVelocity < 0.0) @@ -263,8 +263,8 @@ void btKinematicCharacterController::stepUp ( btCollisionWorld* world) // phase 1: up btTransform start, end; - start.setIdentity (); - end.setIdentity (); + start.setIdentity(); + end.setIdentity(); /* FIXME: Handle penetration properly */ start.setOrigin(m_currentPosition); @@ -272,7 +272,7 @@ void btKinematicCharacterController::stepUp ( btCollisionWorld* world) m_targetPosition = m_currentPosition + m_up * (stepHeight) + m_jumpAxis * ((m_verticalOffset > 0.f ? m_verticalOffset : 0.f)); m_currentPosition = m_targetPosition; - end.setOrigin (m_targetPosition); + end.setOrigin(m_targetPosition); start.setRotation(m_currentOrientation); end.setRotation(m_targetOrientation); @@ -280,10 +280,10 @@ void btKinematicCharacterController::stepUp ( btCollisionWorld* world) btKinematicClosestNotMeConvexResultCallback callback(m_ghostObject, -m_up, m_maxSlopeCosine); callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; - + if (m_useGhostObjectSweepTest) { - m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, world->getDispatchInfo().m_allowedCcdPenetration); + m_ghostObject->convexSweepTest(m_convexShape, start, end, callback, world->getDispatchInfo().m_allowedCcdPenetration); } else { @@ -298,7 +298,7 @@ void btKinematicCharacterController::stepUp ( btCollisionWorld* world) // we moved up only a fraction of the step height m_currentStepOffset = stepHeight * callback.m_closestHitFraction; if (m_interpolateUp == true) - m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction); + m_currentPosition.setInterpolate3(m_currentPosition, m_targetPosition, callback.m_closestHitFraction); else m_currentPosition = m_targetPosition; } @@ -329,7 +329,9 @@ void btKinematicCharacterController::stepUp ( btCollisionWorld* world) m_verticalVelocity = 0.0; m_currentStepOffset = m_stepHeight; } - } else { + } + else + { m_currentStepOffset = stepHeight; m_currentPosition = m_targetPosition; } @@ -342,43 +344,44 @@ bool btKinematicCharacterController::needsCollision(const btCollisionObject* bod return collides; } -void btKinematicCharacterController::updateTargetPositionBasedOnCollision (const btVector3& hitNormal, btScalar tangentMag, btScalar normalMag) +void btKinematicCharacterController::updateTargetPositionBasedOnCollision(const btVector3& hitNormal, btScalar tangentMag, btScalar normalMag) { btVector3 movementDirection = m_targetPosition - m_currentPosition; btScalar movementLength = movementDirection.length(); - if (movementLength>SIMD_EPSILON) + if (movementLength > SIMD_EPSILON) { movementDirection.normalize(); - btVector3 reflectDir = computeReflectionDirection (movementDirection, hitNormal); + btVector3 reflectDir = computeReflectionDirection(movementDirection, hitNormal); reflectDir.normalize(); btVector3 parallelDir, perpindicularDir; - parallelDir = parallelComponent (reflectDir, hitNormal); - perpindicularDir = perpindicularComponent (reflectDir, hitNormal); + parallelDir = parallelComponent(reflectDir, hitNormal); + perpindicularDir = perpindicularComponent(reflectDir, hitNormal); m_targetPosition = m_currentPosition; - if (0)//tangentMag != 0.0) + if (0) //tangentMag != 0.0) { - btVector3 parComponent = parallelDir * btScalar (tangentMag*movementLength); -// printf("parComponent=%f,%f,%f\n",parComponent[0],parComponent[1],parComponent[2]); - m_targetPosition += parComponent; + btVector3 parComponent = parallelDir * btScalar(tangentMag * movementLength); + // printf("parComponent=%f,%f,%f\n",parComponent[0],parComponent[1],parComponent[2]); + m_targetPosition += parComponent; } if (normalMag != 0.0) { - btVector3 perpComponent = perpindicularDir * btScalar (normalMag*movementLength); -// printf("perpComponent=%f,%f,%f\n",perpComponent[0],perpComponent[1],perpComponent[2]); + btVector3 perpComponent = perpindicularDir * btScalar(normalMag * movementLength); + // printf("perpComponent=%f,%f,%f\n",perpComponent[0],perpComponent[1],perpComponent[2]); m_targetPosition += perpComponent; } - } else + } + else { -// printf("movementLength don't normalize a zero vector\n"); + // printf("movementLength don't normalize a zero vector\n"); } } -void btKinematicCharacterController::stepForwardAndStrafe ( btCollisionWorld* collisionWorld, const btVector3& walkMove) +void btKinematicCharacterController::stepForwardAndStrafe(btCollisionWorld* collisionWorld, const btVector3& walkMove) { // printf("m_normalizedDirection=%f,%f,%f\n", // m_normalizedDirection[0],m_normalizedDirection[1],m_normalizedDirection[2]); @@ -387,29 +390,28 @@ void btKinematicCharacterController::stepForwardAndStrafe ( btCollisionWorld* co m_targetPosition = m_currentPosition + walkMove; - start.setIdentity (); - end.setIdentity (); - + start.setIdentity(); + end.setIdentity(); + btScalar fraction = 1.0; - btScalar distance2 = (m_currentPosition-m_targetPosition).length2(); -// printf("distance2=%f\n",distance2); + btScalar distance2 = (m_currentPosition - m_targetPosition).length2(); + // printf("distance2=%f\n",distance2); int maxIter = 10; while (fraction > btScalar(0.01) && maxIter-- > 0) { - start.setOrigin (m_currentPosition); - end.setOrigin (m_targetPosition); + start.setOrigin(m_currentPosition); + end.setOrigin(m_targetPosition); btVector3 sweepDirNegative(m_currentPosition - m_targetPosition); start.setRotation(m_currentOrientation); end.setRotation(m_targetOrientation); - btKinematicClosestNotMeConvexResultCallback callback (m_ghostObject, sweepDirNegative, btScalar(0.0)); + btKinematicClosestNotMeConvexResultCallback callback(m_ghostObject, sweepDirNegative, btScalar(0.0)); callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; - btScalar margin = m_convexShape->getMargin(); m_convexShape->setMargin(margin + m_addedMargin); @@ -426,18 +428,17 @@ void btKinematicCharacterController::stepForwardAndStrafe ( btCollisionWorld* co } m_convexShape->setMargin(margin); - fraction -= callback.m_closestHitFraction; if (callback.hasHit() && m_ghostObject->hasContactResponse() && needsCollision(m_ghostObject, callback.m_hitCollisionObject)) - { + { // we moved only a fraction //btScalar hitDistance; //hitDistance = (callback.m_hitPointWorld - m_currentPosition).length(); -// m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction); + // m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction); - updateTargetPositionBasedOnCollision (callback.m_hitNormalWorld); + updateTargetPositionBasedOnCollision(callback.m_hitNormalWorld); btVector3 currentDir = m_targetPosition - m_currentPosition; distance2 = currentDir.length2(); if (distance2 > SIMD_EPSILON) @@ -448,21 +449,21 @@ void btKinematicCharacterController::stepForwardAndStrafe ( btCollisionWorld* co { break; } - } else + } + else { -// printf("currentDir: don't normalize a zero vector\n"); + // printf("currentDir: don't normalize a zero vector\n"); break; } - } - else - { - m_currentPosition = m_targetPosition; + else + { + m_currentPosition = m_targetPosition; } } } -void btKinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld, btScalar dt) +void btKinematicCharacterController::stepDown(btCollisionWorld* collisionWorld, btScalar dt) { btTransform start, end, end_double; bool runonce = false; @@ -475,64 +476,64 @@ void btKinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld m_targetPosition -= (step_drop + gravity_drop);*/ btVector3 orig_position = m_targetPosition; - - btScalar downVelocity = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt; + + btScalar downVelocity = (m_verticalVelocity < 0.f ? -m_verticalVelocity : 0.f) * dt; if (m_verticalVelocity > 0.0) return; - if(downVelocity > 0.0 && downVelocity > m_fallSpeed - && (m_wasOnGround || !m_wasJumping)) + if (downVelocity > 0.0 && downVelocity > m_fallSpeed && (m_wasOnGround || !m_wasJumping)) downVelocity = m_fallSpeed; btVector3 step_drop = m_up * (m_currentStepOffset + downVelocity); m_targetPosition -= step_drop; btKinematicClosestNotMeConvexResultCallback callback(m_ghostObject, m_up, m_maxSlopeCosine); - callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; - callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; + callback.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; + callback.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; btKinematicClosestNotMeConvexResultCallback callback2(m_ghostObject, m_up, m_maxSlopeCosine); - callback2.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; - callback2.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; + callback2.m_collisionFilterGroup = getGhostObject()->getBroadphaseHandle()->m_collisionFilterGroup; + callback2.m_collisionFilterMask = getGhostObject()->getBroadphaseHandle()->m_collisionFilterMask; while (1) { - start.setIdentity (); - end.setIdentity (); + start.setIdentity(); + end.setIdentity(); - end_double.setIdentity (); + end_double.setIdentity(); - start.setOrigin (m_currentPosition); - end.setOrigin (m_targetPosition); + start.setOrigin(m_currentPosition); + end.setOrigin(m_targetPosition); start.setRotation(m_currentOrientation); end.setRotation(m_targetOrientation); //set double test for 2x the step drop, to check for a large drop vs small drop - end_double.setOrigin (m_targetPosition - step_drop); + end_double.setOrigin(m_targetPosition - step_drop); if (m_useGhostObjectSweepTest) { - m_ghostObject->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); + m_ghostObject->convexSweepTest(m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); if (!callback.hasHit() && m_ghostObject->hasContactResponse()) { //test a double fall height, to see if the character should interpolate it's fall (full) or not (partial) - m_ghostObject->convexSweepTest (m_convexShape, start, end_double, callback2, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); + m_ghostObject->convexSweepTest(m_convexShape, start, end_double, callback2, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); } - } else + } + else { - collisionWorld->convexSweepTest (m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); + collisionWorld->convexSweepTest(m_convexShape, start, end, callback, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); if (!callback.hasHit() && m_ghostObject->hasContactResponse()) { //test a double fall height, to see if the character should interpolate it's fall (large) or not (small) - collisionWorld->convexSweepTest (m_convexShape, start, end_double, callback2, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); + collisionWorld->convexSweepTest(m_convexShape, start, end_double, callback2, collisionWorld->getDispatchInfo().m_allowedCcdPenetration); } } - - btScalar downVelocity2 = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt; + + btScalar downVelocity2 = (m_verticalVelocity < 0.f ? -m_verticalVelocity : 0.f) * dt; bool has_hit; if (bounce_fix == true) has_hit = (callback.hasHit() || callback2.hasHit()) && m_ghostObject->hasContactResponse() && needsCollision(m_ghostObject, callback.m_hitCollisionObject); @@ -543,8 +544,7 @@ void btKinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld if (m_verticalVelocity < 0.0) stepHeight = m_stepHeight; - if (downVelocity2 > 0.0 && downVelocity2 < stepHeight && has_hit == true && runonce == false - && (m_wasOnGround || !m_wasJumping)) + if (downVelocity2 > 0.0 && downVelocity2 < stepHeight && has_hit == true && runonce == false && (m_wasOnGround || !m_wasJumping)) { //redo the velocity calculation when falling a small amount, for fast stairs motion //for larger falls, use the smoother/slower interpolated movement by not touching the target position @@ -555,7 +555,7 @@ void btKinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld step_drop = m_up * (m_currentStepOffset + downVelocity); m_targetPosition -= step_drop; runonce = true; - continue; //re-run previous tests + continue; //re-run previous tests } break; } @@ -570,30 +570,32 @@ void btKinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld if (bounce_fix == true) { if (full_drop == true) - m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction); - else + m_currentPosition.setInterpolate3(m_currentPosition, m_targetPosition, callback.m_closestHitFraction); + else //due to errors in the closestHitFraction variable when used with large polygons, calculate the hit fraction manually - m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, fraction); + m_currentPosition.setInterpolate3(m_currentPosition, m_targetPosition, fraction); } else - m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction); + m_currentPosition.setInterpolate3(m_currentPosition, m_targetPosition, callback.m_closestHitFraction); full_drop = false; m_verticalVelocity = 0.0; m_verticalOffset = 0.0; m_wasJumping = false; - } else { + } + else + { // we dropped the full height full_drop = true; if (bounce_fix == true) { - downVelocity = (m_verticalVelocity<0.f?-m_verticalVelocity:0.f) * dt; + downVelocity = (m_verticalVelocity < 0.f ? -m_verticalVelocity : 0.f) * dt; if (downVelocity > m_fallSpeed && (m_wasOnGround || !m_wasJumping)) { - m_targetPosition += step_drop; //undo previous target change + m_targetPosition += step_drop; //undo previous target change downVelocity = m_fallSpeed; step_drop = m_up * (m_currentStepOffset + downVelocity); m_targetPosition -= step_drop; @@ -605,30 +607,22 @@ void btKinematicCharacterController::stepDown ( btCollisionWorld* collisionWorld } } - - -void btKinematicCharacterController::setWalkDirection -( -const btVector3& walkDirection -) +void btKinematicCharacterController::setWalkDirection( + const btVector3& walkDirection) { m_useWalkDirection = true; m_walkDirection = walkDirection; m_normalizedDirection = getNormalizedVector(m_walkDirection); } - - -void btKinematicCharacterController::setVelocityForTimeInterval -( -const btVector3& velocity, -btScalar timeInterval -) +void btKinematicCharacterController::setVelocityForTimeInterval( + const btVector3& velocity, + btScalar timeInterval) { -// printf("setVelocity!\n"); -// printf(" interval: %f\n", timeInterval); -// printf(" velocity: (%f, %f, %f)\n", -// velocity.x(), velocity.y(), velocity.z()); + // printf("setVelocity!\n"); + // printf(" interval: %f\n", timeInterval); + // printf(" velocity: (%f, %f, %f)\n", + // velocity.x(), velocity.y(), velocity.z()); m_useWalkDirection = false; m_walkDirection = velocity; @@ -661,7 +655,7 @@ void btKinematicCharacterController::setLinearVelocity(const btVector3& velocity btVector3 upComponent = m_up * (btSin(SIMD_HALF_PI - btAcos(c)) * m_walkDirection.length()); m_walkDirection -= upComponent; m_verticalVelocity = (c < 0.0f ? -1 : 1) * upComponent.length(); - + if (c > 0.0f) { m_wasJumping = true; @@ -678,46 +672,45 @@ btVector3 btKinematicCharacterController::getLinearVelocity() const return m_walkDirection + (m_verticalVelocity * m_up); } -void btKinematicCharacterController::reset ( btCollisionWorld* collisionWorld ) +void btKinematicCharacterController::reset(btCollisionWorld* collisionWorld) { - m_verticalVelocity = 0.0; - m_verticalOffset = 0.0; - m_wasOnGround = false; - m_wasJumping = false; - m_walkDirection.setValue(0,0,0); - m_velocityTimeInterval = 0.0; + m_verticalVelocity = 0.0; + m_verticalOffset = 0.0; + m_wasOnGround = false; + m_wasJumping = false; + m_walkDirection.setValue(0, 0, 0); + m_velocityTimeInterval = 0.0; - //clear pair cache - btHashedOverlappingPairCache *cache = m_ghostObject->getOverlappingPairCache(); - while (cache->getOverlappingPairArray().size() > 0) - { - cache->removeOverlappingPair(cache->getOverlappingPairArray()[0].m_pProxy0, cache->getOverlappingPairArray()[0].m_pProxy1, collisionWorld->getDispatcher()); - } + //clear pair cache + btHashedOverlappingPairCache* cache = m_ghostObject->getOverlappingPairCache(); + while (cache->getOverlappingPairArray().size() > 0) + { + cache->removeOverlappingPair(cache->getOverlappingPairArray()[0].m_pProxy0, cache->getOverlappingPairArray()[0].m_pProxy1, collisionWorld->getDispatcher()); + } } -void btKinematicCharacterController::warp (const btVector3& origin) +void btKinematicCharacterController::warp(const btVector3& origin) { btTransform xform; xform.setIdentity(); - xform.setOrigin (origin); - m_ghostObject->setWorldTransform (xform); + xform.setOrigin(origin); + m_ghostObject->setWorldTransform(xform); } - -void btKinematicCharacterController::preStep ( btCollisionWorld* collisionWorld) +void btKinematicCharacterController::preStep(btCollisionWorld* collisionWorld) { m_currentPosition = m_ghostObject->getWorldTransform().getOrigin(); m_targetPosition = m_currentPosition; m_currentOrientation = m_ghostObject->getWorldTransform().getRotation(); m_targetOrientation = m_currentOrientation; -// printf("m_targetPosition=%f,%f,%f\n",m_targetPosition[0],m_targetPosition[1],m_targetPosition[2]); + // printf("m_targetPosition=%f,%f,%f\n",m_targetPosition[0],m_targetPosition[1],m_targetPosition[2]); } -void btKinematicCharacterController::playerStep ( btCollisionWorld* collisionWorld, btScalar dt) +void btKinematicCharacterController::playerStep(btCollisionWorld* collisionWorld, btScalar dt) { -// printf("playerStep(): "); -// printf(" dt = %f", dt); + // printf("playerStep(): "); + // printf(" dt = %f", dt); if (m_AngVel.length2() > 0.0f) { @@ -744,16 +737,17 @@ void btKinematicCharacterController::playerStep ( btCollisionWorld* collisionWo } // quick check... - if (!m_useWalkDirection && (m_velocityTimeInterval <= 0.0)) { -// printf("\n"); - return; // no motion + if (!m_useWalkDirection && (m_velocityTimeInterval <= 0.0)) + { + // printf("\n"); + return; // no motion } m_wasOnGround = onGround(); //btVector3 lvel = m_walkDirection; //btScalar c = 0.0f; - + if (m_walkDirection.length2() > 0) { // apply damping @@ -761,7 +755,7 @@ void btKinematicCharacterController::playerStep ( btCollisionWorld* collisionWo } m_verticalVelocity *= btPow(btScalar(1) - m_linearDamping, dt); - + // Update fall velocity. m_verticalVelocity -= m_gravity * dt; if (m_verticalVelocity > 0.0 && m_verticalVelocity > m_jumpSpeed) @@ -777,12 +771,12 @@ void btKinematicCharacterController::playerStep ( btCollisionWorld* collisionWo btTransform xform; xform = m_ghostObject->getWorldTransform(); -// printf("walkDirection(%f,%f,%f)\n",walkDirection[0],walkDirection[1],walkDirection[2]); -// printf("walkSpeed=%f\n",walkSpeed); + // printf("walkDirection(%f,%f,%f)\n",walkDirection[0],walkDirection[1],walkDirection[2]); + // printf("walkSpeed=%f\n",walkSpeed); stepUp(collisionWorld); //todo: Experimenting with behavior of controller when it hits a ceiling.. - //bool hitUp = stepUp (collisionWorld); + //bool hitUp = stepUp (collisionWorld); //if (hitUp) //{ // m_verticalVelocity -= m_gravity * dt; @@ -799,9 +793,12 @@ void btKinematicCharacterController::playerStep ( btCollisionWorld* collisionWo // xform = m_ghostObject->getWorldTransform(); //} - if (m_useWalkDirection) { - stepForwardAndStrafe (collisionWorld, m_walkDirection); - } else { + if (m_useWalkDirection) + { + stepForwardAndStrafe(collisionWorld, m_walkDirection); + } + else + { //printf(" time: %f", m_velocityTimeInterval); // still have some time left for moving! btScalar dtMoving = @@ -816,7 +813,7 @@ void btKinematicCharacterController::playerStep ( btCollisionWorld* collisionWo // okay, step stepForwardAndStrafe(collisionWorld, move); } - stepDown (collisionWorld, dt); + stepDown(collisionWorld, dt); //todo: Experimenting with max jump height //if (m_wasJumping) @@ -827,7 +824,7 @@ void btKinematicCharacterController::playerStep ( btCollisionWorld* collisionWo // // substract the overshoot // m_currentPosition[m_upAxis] -= ds - m_maxJumpHeight; - // // max height was reached, so potential energy is at max + // // max height was reached, so potential energy is at max // // and kinematic energy is 0, thus velocity is 0. // if (m_verticalVelocity > 0.0) // m_verticalVelocity = 0.0; @@ -835,8 +832,8 @@ void btKinematicCharacterController::playerStep ( btCollisionWorld* collisionWo //} // printf("\n"); - xform.setOrigin (m_currentPosition); - m_ghostObject->setWorldTransform (xform); + xform.setOrigin(m_currentPosition); + m_ghostObject->setWorldTransform(xform); int numPenetrationLoops = 0; m_touchingContact = false; @@ -852,23 +849,23 @@ void btKinematicCharacterController::playerStep ( btCollisionWorld* collisionWo } } -void btKinematicCharacterController::setFallSpeed (btScalar fallSpeed) +void btKinematicCharacterController::setFallSpeed(btScalar fallSpeed) { m_fallSpeed = fallSpeed; } -void btKinematicCharacterController::setJumpSpeed (btScalar jumpSpeed) +void btKinematicCharacterController::setJumpSpeed(btScalar jumpSpeed) { m_jumpSpeed = jumpSpeed; m_SetjumpSpeed = m_jumpSpeed; } -void btKinematicCharacterController::setMaxJumpHeight (btScalar maxJumpHeight) +void btKinematicCharacterController::setMaxJumpHeight(btScalar maxJumpHeight) { m_maxJumpHeight = maxJumpHeight; } -bool btKinematicCharacterController::canJump () const +bool btKinematicCharacterController::canJump() const { return onGround(); } @@ -927,20 +924,20 @@ btScalar btKinematicCharacterController::getMaxPenetrationDepth() const return m_maxPenetrationDepth; } -bool btKinematicCharacterController::onGround () const +bool btKinematicCharacterController::onGround() const { return (fabs(m_verticalVelocity) < SIMD_EPSILON) && (fabs(m_verticalOffset) < SIMD_EPSILON); } -void btKinematicCharacterController::setStepHeight(btScalar h) +void btKinematicCharacterController::setStepHeight(btScalar h) { m_stepHeight = h; } btVector3* btKinematicCharacterController::getUpAxisDirections() { - static btVector3 sUpAxisDirection[3] = { btVector3(1.0f, 0.0f, 0.0f), btVector3(0.0f, 1.0f, 0.0f), btVector3(0.0f, 0.0f, 1.0f) }; - + static btVector3 sUpAxisDirection[3] = {btVector3(1.0f, 0.0f, 0.0f), btVector3(0.0f, 1.0f, 0.0f), btVector3(0.0f, 0.0f, 1.0f)}; + return sUpAxisDirection; } @@ -997,4 +994,3 @@ btQuaternion btKinematicCharacterController::getRotation(btVector3& v0, btVector return shortestArcQuatNormalize2(v0, v1); } - diff --git a/src/BulletDynamics/Character/btKinematicCharacterController.h b/src/BulletDynamics/Character/btKinematicCharacterController.h index 00c59c024..ff34fc871 100644 --- a/src/BulletDynamics/Character/btKinematicCharacterController.h +++ b/src/BulletDynamics/Character/btKinematicCharacterController.h @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef BT_KINEMATIC_CHARACTER_CONTROLLER_H #define BT_KINEMATIC_CHARACTER_CONTROLLER_H @@ -23,7 +22,6 @@ subject to the following restrictions: #include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h" - class btCollisionShape; class btConvexShape; class btRigidBody; @@ -34,15 +32,15 @@ class btPairCachingGhostObject; ///btKinematicCharacterController is an object that supports a sliding motion in a world. ///It uses a ghost object and convex sweep test to test for upcoming collisions. This is combined with discrete collision detection to recover from penetrations. ///Interaction between btKinematicCharacterController and dynamic rigid bodies needs to be explicity implemented by the user. -ATTRIBUTE_ALIGNED16(class) btKinematicCharacterController : public btCharacterControllerInterface +ATTRIBUTE_ALIGNED16(class) +btKinematicCharacterController : public btCharacterControllerInterface { protected: - btScalar m_halfHeight; - + btPairCachingGhostObject* m_ghostObject; - btConvexShape* m_convexShape;//is also in m_ghostObject, but it needs to be convex, so we store it here to avoid upcast - + btConvexShape* m_convexShape; //is also in m_ghostObject, but it needs to be convex, so we store it here to avoid upcast + btScalar m_maxPenetrationDepth; btScalar m_verticalVelocity; btScalar m_verticalOffset; @@ -50,33 +48,33 @@ protected: btScalar m_jumpSpeed; btScalar m_SetjumpSpeed; btScalar m_maxJumpHeight; - btScalar m_maxSlopeRadians; // Slope angle that is set (used for returning the exact value) - btScalar m_maxSlopeCosine; // Cosine equivalent of m_maxSlopeRadians (calculated once when set, for optimization) + btScalar m_maxSlopeRadians; // Slope angle that is set (used for returning the exact value) + btScalar m_maxSlopeCosine; // Cosine equivalent of m_maxSlopeRadians (calculated once when set, for optimization) btScalar m_gravity; btScalar m_turnAngle; - + btScalar m_stepHeight; - btScalar m_addedMargin;//@todo: remove this and fix the code + btScalar m_addedMargin; //@todo: remove this and fix the code ///this is the desired walk direction, set by the user - btVector3 m_walkDirection; - btVector3 m_normalizedDirection; - btVector3 m_AngVel; + btVector3 m_walkDirection; + btVector3 m_normalizedDirection; + btVector3 m_AngVel; - btVector3 m_jumpPosition; + btVector3 m_jumpPosition; //some internal variables btVector3 m_currentPosition; - btScalar m_currentStepOffset; + btScalar m_currentStepOffset; btVector3 m_targetPosition; btQuaternion m_currentOrientation; btQuaternion m_targetOrientation; ///keep track of the contact manifolds - btManifoldArray m_manifoldArray; + btManifoldArray m_manifoldArray; bool m_touchingContact; btVector3 m_touchingNormal; @@ -84,52 +82,50 @@ protected: btScalar m_linearDamping; btScalar m_angularDamping; - bool m_wasOnGround; - bool m_wasJumping; - bool m_useGhostObjectSweepTest; - bool m_useWalkDirection; - btScalar m_velocityTimeInterval; + bool m_wasOnGround; + bool m_wasJumping; + bool m_useGhostObjectSweepTest; + bool m_useWalkDirection; + btScalar m_velocityTimeInterval; btVector3 m_up; btVector3 m_jumpAxis; static btVector3* getUpAxisDirections(); - bool m_interpolateUp; - bool full_drop; - bool bounce_fix; + bool m_interpolateUp; + bool full_drop; + bool bounce_fix; - btVector3 computeReflectionDirection (const btVector3& direction, const btVector3& normal); - btVector3 parallelComponent (const btVector3& direction, const btVector3& normal); - btVector3 perpindicularComponent (const btVector3& direction, const btVector3& normal); + btVector3 computeReflectionDirection(const btVector3& direction, const btVector3& normal); + btVector3 parallelComponent(const btVector3& direction, const btVector3& normal); + btVector3 perpindicularComponent(const btVector3& direction, const btVector3& normal); - bool recoverFromPenetration ( btCollisionWorld* collisionWorld); - void stepUp (btCollisionWorld* collisionWorld); - void updateTargetPositionBasedOnCollision (const btVector3& hit_normal, btScalar tangentMag = btScalar(0.0), btScalar normalMag = btScalar(1.0)); - void stepForwardAndStrafe (btCollisionWorld* collisionWorld, const btVector3& walkMove); - void stepDown (btCollisionWorld* collisionWorld, btScalar dt); + bool recoverFromPenetration(btCollisionWorld * collisionWorld); + void stepUp(btCollisionWorld * collisionWorld); + void updateTargetPositionBasedOnCollision(const btVector3& hit_normal, btScalar tangentMag = btScalar(0.0), btScalar normalMag = btScalar(1.0)); + void stepForwardAndStrafe(btCollisionWorld * collisionWorld, const btVector3& walkMove); + void stepDown(btCollisionWorld * collisionWorld, btScalar dt); virtual bool needsCollision(const btCollisionObject* body0, const btCollisionObject* body1); void setUpVector(const btVector3& up); - btQuaternion getRotation(btVector3& v0, btVector3& v1) const; + btQuaternion getRotation(btVector3 & v0, btVector3 & v1) const; public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - btKinematicCharacterController (btPairCachingGhostObject* ghostObject,btConvexShape* convexShape,btScalar stepHeight, const btVector3& up = btVector3(1.0,0.0,0.0)); - ~btKinematicCharacterController (); - + btKinematicCharacterController(btPairCachingGhostObject * ghostObject, btConvexShape * convexShape, btScalar stepHeight, const btVector3& up = btVector3(1.0, 0.0, 0.0)); + ~btKinematicCharacterController(); ///btActionInterface interface - virtual void updateAction( btCollisionWorld* collisionWorld,btScalar deltaTime) + virtual void updateAction(btCollisionWorld * collisionWorld, btScalar deltaTime) { - preStep ( collisionWorld); - playerStep (collisionWorld, deltaTime); + preStep(collisionWorld); + playerStep(collisionWorld, deltaTime); } - + ///btActionInterface interface - void debugDraw(btIDebugDraw* debugDrawer); + void debugDraw(btIDebugDraw * debugDrawer); void setUp(const btVector3& up); @@ -140,7 +136,7 @@ public: /// increment the position each simulation iteration, regardless /// of dt. /// This call will reset any velocity set by setVelocityForTimeInterval(). - virtual void setWalkDirection(const btVector3& walkDirection); + virtual void setWalkDirection(const btVector3& walkDirection); /// Caller provides a velocity with which the character should move for /// the given time period. After the time period, velocity is reset @@ -148,7 +144,7 @@ public: /// This call will reset any walk direction set by setWalkDirection(). /// Negative time intervals will result in no motion. virtual void setVelocityForTimeInterval(const btVector3& velocity, - btScalar timeInterval); + btScalar timeInterval); virtual void setAngularVelocity(const btVector3& velocity); virtual const btVector3& getAngularVelocity() const; @@ -157,24 +153,24 @@ public: virtual btVector3 getLinearVelocity() const; void setLinearDamping(btScalar d) { m_linearDamping = btClamped(d, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); } - btScalar getLinearDamping() const { return m_linearDamping; } + btScalar getLinearDamping() const { return m_linearDamping; } void setAngularDamping(btScalar d) { m_angularDamping = btClamped(d, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); } - btScalar getAngularDamping() const { return m_angularDamping; } + btScalar getAngularDamping() const { return m_angularDamping; } - void reset ( btCollisionWorld* collisionWorld ); - void warp (const btVector3& origin); + void reset(btCollisionWorld * collisionWorld); + void warp(const btVector3& origin); - void preStep ( btCollisionWorld* collisionWorld); - void playerStep ( btCollisionWorld* collisionWorld, btScalar dt); + void preStep(btCollisionWorld * collisionWorld); + void playerStep(btCollisionWorld * collisionWorld, btScalar dt); void setStepHeight(btScalar h); btScalar getStepHeight() const { return m_stepHeight; } - void setFallSpeed (btScalar fallSpeed); + void setFallSpeed(btScalar fallSpeed); btScalar getFallSpeed() const { return m_fallSpeed; } - void setJumpSpeed (btScalar jumpSpeed); + void setJumpSpeed(btScalar jumpSpeed); btScalar getJumpSpeed() const { return m_jumpSpeed; } - void setMaxJumpHeight (btScalar maxJumpHeight); - bool canJump () const; + void setMaxJumpHeight(btScalar maxJumpHeight); + bool canJump() const; void jump(const btVector3& v = btVector3(0, 0, 0)); @@ -192,13 +188,13 @@ public: btScalar getMaxPenetrationDepth() const; btPairCachingGhostObject* getGhostObject(); - void setUseGhostSweepTest(bool useGhostObjectSweepTest) + void setUseGhostSweepTest(bool useGhostObjectSweepTest) { m_useGhostObjectSweepTest = useGhostObjectSweepTest; } - bool onGround () const; - void setUpInterpolate (bool value); + bool onGround() const; + void setUpInterpolate(bool value); }; -#endif // BT_KINEMATIC_CHARACTER_CONTROLLER_H +#endif // BT_KINEMATIC_CHARACTER_CONTROLLER_H diff --git a/src/BulletDynamics/ConstraintSolver/btBatchedConstraints.cpp b/src/BulletDynamics/ConstraintSolver/btBatchedConstraints.cpp index c82ba87f9..b51dfaad3 100644 --- a/src/BulletDynamics/ConstraintSolver/btBatchedConstraints.cpp +++ b/src/BulletDynamics/ConstraintSolver/btBatchedConstraints.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btBatchedConstraints.h" #include "LinearMath/btIDebugDraw.h" @@ -21,606 +20,573 @@ subject to the following restrictions: #include "LinearMath/btStackAlloc.h" #include "LinearMath/btQuickprof.h" -#include //for memset +#include //for memset const int kNoMerge = -1; bool btBatchedConstraints::s_debugDrawBatches = false; - struct btBatchedConstraintInfo { - int constraintIndex; - int numConstraintRows; - int bodyIds[2]; + int constraintIndex; + int numConstraintRows; + int bodyIds[2]; }; - struct btBatchInfo { - int numConstraints; - int mergeIndex; + int numConstraints; + int mergeIndex; - btBatchInfo() : numConstraints(0), mergeIndex(kNoMerge) {} + btBatchInfo() : numConstraints(0), mergeIndex(kNoMerge) {} }; - bool btBatchedConstraints::validate(btConstraintArray* constraints, const btAlignedObjectArray& bodies) const { - // - // validate: for debugging only. Verify coloring of bodies, that no body is touched by more than one batch in any given phase - // - int errors = 0; - const int kUnassignedBatch = -1; + // + // validate: for debugging only. Verify coloring of bodies, that no body is touched by more than one batch in any given phase + // + int errors = 0; + const int kUnassignedBatch = -1; - btAlignedObjectArray bodyBatchId; - for (int iPhase = 0; iPhase < m_phases.size(); ++iPhase) - { - bodyBatchId.resizeNoInitialize(0); - bodyBatchId.resize( bodies.size(), kUnassignedBatch ); - const Range& phase = m_phases[iPhase]; - for (int iBatch = phase.begin; iBatch < phase.end; ++iBatch) - { - const Range& batch = m_batches[iBatch]; - for (int iiCons = batch.begin; iiCons < batch.end; ++iiCons) - { - int iCons = m_constraintIndices[iiCons]; - const btSolverConstraint& cons = constraints->at(iCons); - const btSolverBody& bodyA = bodies[cons.m_solverBodyIdA]; - const btSolverBody& bodyB = bodies[cons.m_solverBodyIdB]; - if (! bodyA.internalGetInvMass().isZero()) - { - int thisBodyBatchId = bodyBatchId[cons.m_solverBodyIdA]; - if (thisBodyBatchId == kUnassignedBatch) - { - bodyBatchId[cons.m_solverBodyIdA] = iBatch; - } - else if (thisBodyBatchId != iBatch) - { - btAssert( !"dynamic body is used in 2 different batches in the same phase" ); - errors++; - } - } - if (! bodyB.internalGetInvMass().isZero()) - { - int thisBodyBatchId = bodyBatchId[cons.m_solverBodyIdB]; - if (thisBodyBatchId == kUnassignedBatch) - { - bodyBatchId[cons.m_solverBodyIdB] = iBatch; - } - else if (thisBodyBatchId != iBatch) - { - btAssert( !"dynamic body is used in 2 different batches in the same phase" ); - errors++; - } - } - } - } - } - return errors == 0; + btAlignedObjectArray bodyBatchId; + for (int iPhase = 0; iPhase < m_phases.size(); ++iPhase) + { + bodyBatchId.resizeNoInitialize(0); + bodyBatchId.resize(bodies.size(), kUnassignedBatch); + const Range& phase = m_phases[iPhase]; + for (int iBatch = phase.begin; iBatch < phase.end; ++iBatch) + { + const Range& batch = m_batches[iBatch]; + for (int iiCons = batch.begin; iiCons < batch.end; ++iiCons) + { + int iCons = m_constraintIndices[iiCons]; + const btSolverConstraint& cons = constraints->at(iCons); + const btSolverBody& bodyA = bodies[cons.m_solverBodyIdA]; + const btSolverBody& bodyB = bodies[cons.m_solverBodyIdB]; + if (!bodyA.internalGetInvMass().isZero()) + { + int thisBodyBatchId = bodyBatchId[cons.m_solverBodyIdA]; + if (thisBodyBatchId == kUnassignedBatch) + { + bodyBatchId[cons.m_solverBodyIdA] = iBatch; + } + else if (thisBodyBatchId != iBatch) + { + btAssert(!"dynamic body is used in 2 different batches in the same phase"); + errors++; + } + } + if (!bodyB.internalGetInvMass().isZero()) + { + int thisBodyBatchId = bodyBatchId[cons.m_solverBodyIdB]; + if (thisBodyBatchId == kUnassignedBatch) + { + bodyBatchId[cons.m_solverBodyIdB] = iBatch; + } + else if (thisBodyBatchId != iBatch) + { + btAssert(!"dynamic body is used in 2 different batches in the same phase"); + errors++; + } + } + } + } + } + return errors == 0; } - -static void debugDrawSingleBatch( const btBatchedConstraints* bc, - btConstraintArray* constraints, - const btAlignedObjectArray& bodies, - int iBatch, - const btVector3& color, - const btVector3& offset - ) +static void debugDrawSingleBatch(const btBatchedConstraints* bc, + btConstraintArray* constraints, + const btAlignedObjectArray& bodies, + int iBatch, + const btVector3& color, + const btVector3& offset) { - if (bc && bc->m_debugDrawer && iBatch < bc->m_batches.size()) - { - const btBatchedConstraints::Range& b = bc->m_batches[iBatch]; - for (int iiCon = b.begin; iiCon < b.end; ++iiCon) - { - int iCon = bc->m_constraintIndices[iiCon]; - const btSolverConstraint& con = constraints->at(iCon); - int iBody0 = con.m_solverBodyIdA; - int iBody1 = con.m_solverBodyIdB; - btVector3 pos0 = bodies[iBody0].getWorldTransform().getOrigin() + offset; - btVector3 pos1 = bodies[iBody1].getWorldTransform().getOrigin() + offset; - bc->m_debugDrawer->drawLine(pos0, pos1, color); - } - } + if (bc && bc->m_debugDrawer && iBatch < bc->m_batches.size()) + { + const btBatchedConstraints::Range& b = bc->m_batches[iBatch]; + for (int iiCon = b.begin; iiCon < b.end; ++iiCon) + { + int iCon = bc->m_constraintIndices[iiCon]; + const btSolverConstraint& con = constraints->at(iCon); + int iBody0 = con.m_solverBodyIdA; + int iBody1 = con.m_solverBodyIdB; + btVector3 pos0 = bodies[iBody0].getWorldTransform().getOrigin() + offset; + btVector3 pos1 = bodies[iBody1].getWorldTransform().getOrigin() + offset; + bc->m_debugDrawer->drawLine(pos0, pos1, color); + } + } } - -static void debugDrawPhase( const btBatchedConstraints* bc, - btConstraintArray* constraints, - const btAlignedObjectArray& bodies, - int iPhase, - const btVector3& color0, - const btVector3& color1, - const btVector3& offset - ) +static void debugDrawPhase(const btBatchedConstraints* bc, + btConstraintArray* constraints, + const btAlignedObjectArray& bodies, + int iPhase, + const btVector3& color0, + const btVector3& color1, + const btVector3& offset) { - BT_PROFILE( "debugDrawPhase" ); - if ( bc && bc->m_debugDrawer && iPhase < bc->m_phases.size() ) - { - const btBatchedConstraints::Range& phase = bc->m_phases[iPhase]; - for (int iBatch = phase.begin; iBatch < phase.end; ++iBatch) - { - float tt = float(iBatch - phase.begin) / float(btMax(1, phase.end - phase.begin - 1)); - btVector3 col = lerp(color0, color1, tt); - debugDrawSingleBatch(bc, constraints, bodies, iBatch, col, offset); - } - } + BT_PROFILE("debugDrawPhase"); + if (bc && bc->m_debugDrawer && iPhase < bc->m_phases.size()) + { + const btBatchedConstraints::Range& phase = bc->m_phases[iPhase]; + for (int iBatch = phase.begin; iBatch < phase.end; ++iBatch) + { + float tt = float(iBatch - phase.begin) / float(btMax(1, phase.end - phase.begin - 1)); + btVector3 col = lerp(color0, color1, tt); + debugDrawSingleBatch(bc, constraints, bodies, iBatch, col, offset); + } + } } - -static void debugDrawAllBatches( const btBatchedConstraints* bc, - btConstraintArray* constraints, - const btAlignedObjectArray& bodies - ) +static void debugDrawAllBatches(const btBatchedConstraints* bc, + btConstraintArray* constraints, + const btAlignedObjectArray& bodies) { - BT_PROFILE( "debugDrawAllBatches" ); - if ( bc && bc->m_debugDrawer && bc->m_phases.size() > 0 ) - { - btVector3 bboxMin(BT_LARGE_FLOAT, BT_LARGE_FLOAT, BT_LARGE_FLOAT); - btVector3 bboxMax = -bboxMin; - for (int iBody = 0; iBody < bodies.size(); ++iBody) - { - const btVector3& pos = bodies[iBody].getWorldTransform().getOrigin(); - bboxMin.setMin(pos); - bboxMax.setMax(pos); - } - btVector3 bboxExtent = bboxMax - bboxMin; - btVector3 offsetBase = btVector3( 0, bboxExtent.y()*1.1f, 0 ); - btVector3 offsetStep = btVector3( 0, 0, bboxExtent.z()*1.1f ); - int numPhases = bc->m_phases.size(); - for (int iPhase = 0; iPhase < numPhases; ++iPhase) - { - float b = float(iPhase)/float(numPhases-1); - btVector3 color0 = btVector3(1,0,b); - btVector3 color1 = btVector3(0,1,b); - btVector3 offset = offsetBase + offsetStep*(float(iPhase) - float(numPhases-1)*0.5); - debugDrawPhase(bc, constraints, bodies, iPhase, color0, color1, offset); - } - } + BT_PROFILE("debugDrawAllBatches"); + if (bc && bc->m_debugDrawer && bc->m_phases.size() > 0) + { + btVector3 bboxMin(BT_LARGE_FLOAT, BT_LARGE_FLOAT, BT_LARGE_FLOAT); + btVector3 bboxMax = -bboxMin; + for (int iBody = 0; iBody < bodies.size(); ++iBody) + { + const btVector3& pos = bodies[iBody].getWorldTransform().getOrigin(); + bboxMin.setMin(pos); + bboxMax.setMax(pos); + } + btVector3 bboxExtent = bboxMax - bboxMin; + btVector3 offsetBase = btVector3(0, bboxExtent.y() * 1.1f, 0); + btVector3 offsetStep = btVector3(0, 0, bboxExtent.z() * 1.1f); + int numPhases = bc->m_phases.size(); + for (int iPhase = 0; iPhase < numPhases; ++iPhase) + { + float b = float(iPhase) / float(numPhases - 1); + btVector3 color0 = btVector3(1, 0, b); + btVector3 color1 = btVector3(0, 1, b); + btVector3 offset = offsetBase + offsetStep * (float(iPhase) - float(numPhases - 1) * 0.5); + debugDrawPhase(bc, constraints, bodies, iPhase, color0, color1, offset); + } + } } - static void initBatchedBodyDynamicFlags(btAlignedObjectArray* outBodyDynamicFlags, const btAlignedObjectArray& bodies) { - BT_PROFILE("initBatchedBodyDynamicFlags"); - btAlignedObjectArray& bodyDynamicFlags = *outBodyDynamicFlags; - bodyDynamicFlags.resizeNoInitialize(bodies.size()); - for (int i = 0; i < bodies.size(); ++i) - { - const btSolverBody& body = bodies[ i ]; - bodyDynamicFlags[i] = ( body.internalGetInvMass().x() > btScalar( 0 ) ); - } + BT_PROFILE("initBatchedBodyDynamicFlags"); + btAlignedObjectArray& bodyDynamicFlags = *outBodyDynamicFlags; + bodyDynamicFlags.resizeNoInitialize(bodies.size()); + for (int i = 0; i < bodies.size(); ++i) + { + const btSolverBody& body = bodies[i]; + bodyDynamicFlags[i] = (body.internalGetInvMass().x() > btScalar(0)); + } } - static int runLengthEncodeConstraintInfo(btBatchedConstraintInfo* outConInfos, int numConstraints) { - BT_PROFILE("runLengthEncodeConstraintInfo"); - // detect and run-length encode constraint rows that repeat the same bodies - int iDest = 0; - int iSrc = 0; - while (iSrc < numConstraints) - { - const btBatchedConstraintInfo& srcConInfo = outConInfos[iSrc]; - btBatchedConstraintInfo& conInfo = outConInfos[iDest]; - conInfo.constraintIndex = iSrc; - conInfo.bodyIds[0] = srcConInfo.bodyIds[0]; - conInfo.bodyIds[1] = srcConInfo.bodyIds[1]; - while (iSrc < numConstraints && outConInfos[iSrc].bodyIds[0] == srcConInfo.bodyIds[0] && outConInfos[iSrc].bodyIds[1] == srcConInfo.bodyIds[1]) - { - ++iSrc; - } - conInfo.numConstraintRows = iSrc - conInfo.constraintIndex; - ++iDest; - } - return iDest; + BT_PROFILE("runLengthEncodeConstraintInfo"); + // detect and run-length encode constraint rows that repeat the same bodies + int iDest = 0; + int iSrc = 0; + while (iSrc < numConstraints) + { + const btBatchedConstraintInfo& srcConInfo = outConInfos[iSrc]; + btBatchedConstraintInfo& conInfo = outConInfos[iDest]; + conInfo.constraintIndex = iSrc; + conInfo.bodyIds[0] = srcConInfo.bodyIds[0]; + conInfo.bodyIds[1] = srcConInfo.bodyIds[1]; + while (iSrc < numConstraints && outConInfos[iSrc].bodyIds[0] == srcConInfo.bodyIds[0] && outConInfos[iSrc].bodyIds[1] == srcConInfo.bodyIds[1]) + { + ++iSrc; + } + conInfo.numConstraintRows = iSrc - conInfo.constraintIndex; + ++iDest; + } + return iDest; } - struct ReadSolverConstraintsLoop : public btIParallelForBody { - btBatchedConstraintInfo* m_outConInfos; - btConstraintArray* m_constraints; + btBatchedConstraintInfo* m_outConInfos; + btConstraintArray* m_constraints; - ReadSolverConstraintsLoop( btBatchedConstraintInfo* outConInfos, btConstraintArray* constraints ) - { - m_outConInfos = outConInfos; - m_constraints = constraints; - } - void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - for (int i = iBegin; i < iEnd; ++i) - { - btBatchedConstraintInfo& conInfo = m_outConInfos[i]; - const btSolverConstraint& con = m_constraints->at( i ); - conInfo.bodyIds[0] = con.m_solverBodyIdA; - conInfo.bodyIds[1] = con.m_solverBodyIdB; - conInfo.constraintIndex = i; - conInfo.numConstraintRows = 1; - } - } + ReadSolverConstraintsLoop(btBatchedConstraintInfo* outConInfos, btConstraintArray* constraints) + { + m_outConInfos = outConInfos; + m_constraints = constraints; + } + void forLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + for (int i = iBegin; i < iEnd; ++i) + { + btBatchedConstraintInfo& conInfo = m_outConInfos[i]; + const btSolverConstraint& con = m_constraints->at(i); + conInfo.bodyIds[0] = con.m_solverBodyIdA; + conInfo.bodyIds[1] = con.m_solverBodyIdB; + conInfo.constraintIndex = i; + conInfo.numConstraintRows = 1; + } + } }; - static int initBatchedConstraintInfo(btBatchedConstraintInfo* outConInfos, btConstraintArray* constraints) { - BT_PROFILE("initBatchedConstraintInfo"); - int numConstraints = constraints->size(); - bool inParallel = true; - if (inParallel) - { - ReadSolverConstraintsLoop loop(outConInfos, constraints); - int grainSize = 1200; - btParallelFor(0, numConstraints, grainSize, loop); - } - else - { - for (int i = 0; i < numConstraints; ++i) - { - btBatchedConstraintInfo& conInfo = outConInfos[i]; - const btSolverConstraint& con = constraints->at( i ); - conInfo.bodyIds[0] = con.m_solverBodyIdA; - conInfo.bodyIds[1] = con.m_solverBodyIdB; - conInfo.constraintIndex = i; - conInfo.numConstraintRows = 1; - } - } - bool useRunLengthEncoding = true; - if (useRunLengthEncoding) - { - numConstraints = runLengthEncodeConstraintInfo(outConInfos, numConstraints); - } - return numConstraints; + BT_PROFILE("initBatchedConstraintInfo"); + int numConstraints = constraints->size(); + bool inParallel = true; + if (inParallel) + { + ReadSolverConstraintsLoop loop(outConInfos, constraints); + int grainSize = 1200; + btParallelFor(0, numConstraints, grainSize, loop); + } + else + { + for (int i = 0; i < numConstraints; ++i) + { + btBatchedConstraintInfo& conInfo = outConInfos[i]; + const btSolverConstraint& con = constraints->at(i); + conInfo.bodyIds[0] = con.m_solverBodyIdA; + conInfo.bodyIds[1] = con.m_solverBodyIdB; + conInfo.constraintIndex = i; + conInfo.numConstraintRows = 1; + } + } + bool useRunLengthEncoding = true; + if (useRunLengthEncoding) + { + numConstraints = runLengthEncodeConstraintInfo(outConInfos, numConstraints); + } + return numConstraints; } - static void expandConstraintRowsInPlace(int* constraintBatchIds, const btBatchedConstraintInfo* conInfos, int numConstraints, int numConstraintRows) { - BT_PROFILE("expandConstraintRowsInPlace"); - if (numConstraintRows > numConstraints) - { - // we walk the array in reverse to avoid overwriteing - for (int iCon = numConstraints - 1; iCon >= 0; --iCon) - { - const btBatchedConstraintInfo& conInfo = conInfos[iCon]; - int iBatch = constraintBatchIds[iCon]; - for (int i = conInfo.numConstraintRows - 1; i >= 0; --i) - { - int iDest = conInfo.constraintIndex + i; - btAssert(iDest >= iCon); - btAssert(iDest >= 0 && iDest < numConstraintRows); - constraintBatchIds[iDest] = iBatch; - } - } - } + BT_PROFILE("expandConstraintRowsInPlace"); + if (numConstraintRows > numConstraints) + { + // we walk the array in reverse to avoid overwriteing + for (int iCon = numConstraints - 1; iCon >= 0; --iCon) + { + const btBatchedConstraintInfo& conInfo = conInfos[iCon]; + int iBatch = constraintBatchIds[iCon]; + for (int i = conInfo.numConstraintRows - 1; i >= 0; --i) + { + int iDest = conInfo.constraintIndex + i; + btAssert(iDest >= iCon); + btAssert(iDest >= 0 && iDest < numConstraintRows); + constraintBatchIds[iDest] = iBatch; + } + } + } } - static void expandConstraintRows(int* destConstraintBatchIds, const int* srcConstraintBatchIds, const btBatchedConstraintInfo* conInfos, int numConstraints, int numConstraintRows) { - BT_PROFILE("expandConstraintRows"); - for ( int iCon = 0; iCon < numConstraints; ++iCon ) - { - const btBatchedConstraintInfo& conInfo = conInfos[ iCon ]; - int iBatch = srcConstraintBatchIds[ iCon ]; - for ( int i = 0; i < conInfo.numConstraintRows; ++i ) - { - int iDest = conInfo.constraintIndex + i; - btAssert( iDest >= iCon ); - btAssert( iDest >= 0 && iDest < numConstraintRows ); - destConstraintBatchIds[ iDest ] = iBatch; - } - } + BT_PROFILE("expandConstraintRows"); + for (int iCon = 0; iCon < numConstraints; ++iCon) + { + const btBatchedConstraintInfo& conInfo = conInfos[iCon]; + int iBatch = srcConstraintBatchIds[iCon]; + for (int i = 0; i < conInfo.numConstraintRows; ++i) + { + int iDest = conInfo.constraintIndex + i; + btAssert(iDest >= iCon); + btAssert(iDest >= 0 && iDest < numConstraintRows); + destConstraintBatchIds[iDest] = iBatch; + } + } } - struct ExpandConstraintRowsLoop : public btIParallelForBody { - int* m_destConstraintBatchIds; - const int* m_srcConstraintBatchIds; - const btBatchedConstraintInfo* m_conInfos; - int m_numConstraintRows; + int* m_destConstraintBatchIds; + const int* m_srcConstraintBatchIds; + const btBatchedConstraintInfo* m_conInfos; + int m_numConstraintRows; - ExpandConstraintRowsLoop( int* destConstraintBatchIds, const int* srcConstraintBatchIds, const btBatchedConstraintInfo* conInfos, int numConstraintRows) - { - m_destConstraintBatchIds = destConstraintBatchIds; - m_srcConstraintBatchIds = srcConstraintBatchIds; - m_conInfos = conInfos; - m_numConstraintRows = numConstraintRows; - } - void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - expandConstraintRows(m_destConstraintBatchIds, m_srcConstraintBatchIds + iBegin, m_conInfos + iBegin, iEnd - iBegin, m_numConstraintRows); - } + ExpandConstraintRowsLoop(int* destConstraintBatchIds, const int* srcConstraintBatchIds, const btBatchedConstraintInfo* conInfos, int numConstraintRows) + { + m_destConstraintBatchIds = destConstraintBatchIds; + m_srcConstraintBatchIds = srcConstraintBatchIds; + m_conInfos = conInfos; + m_numConstraintRows = numConstraintRows; + } + void forLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + expandConstraintRows(m_destConstraintBatchIds, m_srcConstraintBatchIds + iBegin, m_conInfos + iBegin, iEnd - iBegin, m_numConstraintRows); + } }; - static void expandConstraintRowsMt(int* destConstraintBatchIds, const int* srcConstraintBatchIds, const btBatchedConstraintInfo* conInfos, int numConstraints, int numConstraintRows) { - BT_PROFILE("expandConstraintRowsMt"); - ExpandConstraintRowsLoop loop(destConstraintBatchIds, srcConstraintBatchIds, conInfos, numConstraintRows); - int grainSize = 600; - btParallelFor(0, numConstraints, grainSize, loop); + BT_PROFILE("expandConstraintRowsMt"); + ExpandConstraintRowsLoop loop(destConstraintBatchIds, srcConstraintBatchIds, conInfos, numConstraintRows); + int grainSize = 600; + btParallelFor(0, numConstraints, grainSize, loop); } - static void initBatchedConstraintInfoArray(btAlignedObjectArray* outConInfos, btConstraintArray* constraints) { - BT_PROFILE("initBatchedConstraintInfoArray"); - btAlignedObjectArray& conInfos = *outConInfos; - int numConstraints = constraints->size(); - conInfos.resizeNoInitialize(numConstraints); + BT_PROFILE("initBatchedConstraintInfoArray"); + btAlignedObjectArray& conInfos = *outConInfos; + int numConstraints = constraints->size(); + conInfos.resizeNoInitialize(numConstraints); - int newSize = initBatchedConstraintInfo(&outConInfos->at(0), constraints); - conInfos.resizeNoInitialize(newSize); + int newSize = initBatchedConstraintInfo(&outConInfos->at(0), constraints); + conInfos.resizeNoInitialize(newSize); } - static void mergeSmallBatches(btBatchInfo* batches, int iBeginBatch, int iEndBatch, int minBatchSize, int maxBatchSize) { - BT_PROFILE("mergeSmallBatches"); - for ( int iBatch = iEndBatch - 1; iBatch >= iBeginBatch; --iBatch ) - { - btBatchInfo& batch = batches[ iBatch ]; - if ( batch.mergeIndex == kNoMerge && batch.numConstraints > 0 && batch.numConstraints < minBatchSize ) - { - for ( int iDestBatch = iBatch - 1; iDestBatch >= iBeginBatch; --iDestBatch ) - { - btBatchInfo& destBatch = batches[ iDestBatch ]; - if ( destBatch.mergeIndex == kNoMerge && ( destBatch.numConstraints + batch.numConstraints ) < maxBatchSize ) - { - destBatch.numConstraints += batch.numConstraints; - batch.numConstraints = 0; - batch.mergeIndex = iDestBatch; - break; - } - } - } - } - // flatten mergeIndexes - // e.g. in case where A was merged into B and then B was merged into C, we need A to point to C instead of B - // Note: loop goes forward through batches because batches always merge from higher indexes to lower, - // so by going from low to high it reduces the amount of trail-following - for ( int iBatch = iBeginBatch; iBatch < iEndBatch; ++iBatch ) - { - btBatchInfo& batch = batches[ iBatch ]; - if ( batch.mergeIndex != kNoMerge ) - { - int iMergeDest = batches[ batch.mergeIndex ].mergeIndex; - // follow trail of merges to the end - while ( iMergeDest != kNoMerge ) - { - int iNext = batches[ iMergeDest ].mergeIndex; - if ( iNext == kNoMerge ) - { - batch.mergeIndex = iMergeDest; - break; - } - iMergeDest = iNext; - } - } - } + BT_PROFILE("mergeSmallBatches"); + for (int iBatch = iEndBatch - 1; iBatch >= iBeginBatch; --iBatch) + { + btBatchInfo& batch = batches[iBatch]; + if (batch.mergeIndex == kNoMerge && batch.numConstraints > 0 && batch.numConstraints < minBatchSize) + { + for (int iDestBatch = iBatch - 1; iDestBatch >= iBeginBatch; --iDestBatch) + { + btBatchInfo& destBatch = batches[iDestBatch]; + if (destBatch.mergeIndex == kNoMerge && (destBatch.numConstraints + batch.numConstraints) < maxBatchSize) + { + destBatch.numConstraints += batch.numConstraints; + batch.numConstraints = 0; + batch.mergeIndex = iDestBatch; + break; + } + } + } + } + // flatten mergeIndexes + // e.g. in case where A was merged into B and then B was merged into C, we need A to point to C instead of B + // Note: loop goes forward through batches because batches always merge from higher indexes to lower, + // so by going from low to high it reduces the amount of trail-following + for (int iBatch = iBeginBatch; iBatch < iEndBatch; ++iBatch) + { + btBatchInfo& batch = batches[iBatch]; + if (batch.mergeIndex != kNoMerge) + { + int iMergeDest = batches[batch.mergeIndex].mergeIndex; + // follow trail of merges to the end + while (iMergeDest != kNoMerge) + { + int iNext = batches[iMergeDest].mergeIndex; + if (iNext == kNoMerge) + { + batch.mergeIndex = iMergeDest; + break; + } + iMergeDest = iNext; + } + } + } } - static void updateConstraintBatchIdsForMerges(int* constraintBatchIds, int numConstraints, const btBatchInfo* batches, int numBatches) { - BT_PROFILE("updateConstraintBatchIdsForMerges"); - // update batchIds to account for merges - for (int i = 0; i < numConstraints; ++i) - { - int iBatch = constraintBatchIds[i]; - btAssert(iBatch < numBatches); - // if this constraint references a batch that was merged into another batch - if (batches[iBatch].mergeIndex != kNoMerge) - { - // update batchId - constraintBatchIds[i] = batches[iBatch].mergeIndex; - } - } + BT_PROFILE("updateConstraintBatchIdsForMerges"); + // update batchIds to account for merges + for (int i = 0; i < numConstraints; ++i) + { + int iBatch = constraintBatchIds[i]; + btAssert(iBatch < numBatches); + // if this constraint references a batch that was merged into another batch + if (batches[iBatch].mergeIndex != kNoMerge) + { + // update batchId + constraintBatchIds[i] = batches[iBatch].mergeIndex; + } + } } - struct UpdateConstraintBatchIdsForMergesLoop : public btIParallelForBody { - int* m_constraintBatchIds; - const btBatchInfo* m_batches; - int m_numBatches; + int* m_constraintBatchIds; + const btBatchInfo* m_batches; + int m_numBatches; - UpdateConstraintBatchIdsForMergesLoop( int* constraintBatchIds, const btBatchInfo* batches, int numBatches ) - { - m_constraintBatchIds = constraintBatchIds; - m_batches = batches; - m_numBatches = numBatches; - } - void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - BT_PROFILE( "UpdateConstraintBatchIdsForMergesLoop" ); - updateConstraintBatchIdsForMerges( m_constraintBatchIds + iBegin, iEnd - iBegin, m_batches, m_numBatches ); - } + UpdateConstraintBatchIdsForMergesLoop(int* constraintBatchIds, const btBatchInfo* batches, int numBatches) + { + m_constraintBatchIds = constraintBatchIds; + m_batches = batches; + m_numBatches = numBatches; + } + void forLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + BT_PROFILE("UpdateConstraintBatchIdsForMergesLoop"); + updateConstraintBatchIdsForMerges(m_constraintBatchIds + iBegin, iEnd - iBegin, m_batches, m_numBatches); + } }; - static void updateConstraintBatchIdsForMergesMt(int* constraintBatchIds, int numConstraints, const btBatchInfo* batches, int numBatches) { - BT_PROFILE( "updateConstraintBatchIdsForMergesMt" ); - UpdateConstraintBatchIdsForMergesLoop loop(constraintBatchIds, batches, numBatches); - int grainSize = 800; - btParallelFor(0, numConstraints, grainSize, loop); + BT_PROFILE("updateConstraintBatchIdsForMergesMt"); + UpdateConstraintBatchIdsForMergesLoop loop(constraintBatchIds, batches, numBatches); + int grainSize = 800; + btParallelFor(0, numConstraints, grainSize, loop); } - inline bool BatchCompare(const btBatchedConstraints::Range& a, const btBatchedConstraints::Range& b) { - int lenA = a.end - a.begin; - int lenB = b.end - b.begin; - return lenA > lenB; + int lenA = a.end - a.begin; + int lenB = b.end - b.begin; + return lenA > lenB; } - static void writeOutConstraintIndicesForRangeOfBatches(btBatchedConstraints* bc, - const int* constraintBatchIds, - int numConstraints, - int* constraintIdPerBatch, - int batchBegin, - int batchEnd - ) + const int* constraintBatchIds, + int numConstraints, + int* constraintIdPerBatch, + int batchBegin, + int batchEnd) { - BT_PROFILE("writeOutConstraintIndicesForRangeOfBatches"); - for ( int iCon = 0; iCon < numConstraints; ++iCon ) - { - int iBatch = constraintBatchIds[ iCon ]; - if (iBatch >= batchBegin && iBatch < batchEnd) - { - int iDestCon = constraintIdPerBatch[ iBatch ]; - constraintIdPerBatch[ iBatch ] = iDestCon + 1; - bc->m_constraintIndices[ iDestCon ] = iCon; - } - } + BT_PROFILE("writeOutConstraintIndicesForRangeOfBatches"); + for (int iCon = 0; iCon < numConstraints; ++iCon) + { + int iBatch = constraintBatchIds[iCon]; + if (iBatch >= batchBegin && iBatch < batchEnd) + { + int iDestCon = constraintIdPerBatch[iBatch]; + constraintIdPerBatch[iBatch] = iDestCon + 1; + bc->m_constraintIndices[iDestCon] = iCon; + } + } } - struct WriteOutConstraintIndicesLoop : public btIParallelForBody { - btBatchedConstraints* m_batchedConstraints; - const int* m_constraintBatchIds; - int m_numConstraints; - int* m_constraintIdPerBatch; - int m_maxNumBatchesPerPhase; + btBatchedConstraints* m_batchedConstraints; + const int* m_constraintBatchIds; + int m_numConstraints; + int* m_constraintIdPerBatch; + int m_maxNumBatchesPerPhase; - WriteOutConstraintIndicesLoop( btBatchedConstraints* bc, const int* constraintBatchIds, int numConstraints, int* constraintIdPerBatch, int maxNumBatchesPerPhase ) - { - m_batchedConstraints = bc; - m_constraintBatchIds = constraintBatchIds; - m_numConstraints = numConstraints; - m_constraintIdPerBatch = constraintIdPerBatch; - m_maxNumBatchesPerPhase = maxNumBatchesPerPhase; - } - void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - BT_PROFILE( "WriteOutConstraintIndicesLoop" ); - int batchBegin = iBegin * m_maxNumBatchesPerPhase; - int batchEnd = iEnd * m_maxNumBatchesPerPhase; - writeOutConstraintIndicesForRangeOfBatches(m_batchedConstraints, - m_constraintBatchIds, - m_numConstraints, - m_constraintIdPerBatch, - batchBegin, - batchEnd - ); - } + WriteOutConstraintIndicesLoop(btBatchedConstraints* bc, const int* constraintBatchIds, int numConstraints, int* constraintIdPerBatch, int maxNumBatchesPerPhase) + { + m_batchedConstraints = bc; + m_constraintBatchIds = constraintBatchIds; + m_numConstraints = numConstraints; + m_constraintIdPerBatch = constraintIdPerBatch; + m_maxNumBatchesPerPhase = maxNumBatchesPerPhase; + } + void forLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + BT_PROFILE("WriteOutConstraintIndicesLoop"); + int batchBegin = iBegin * m_maxNumBatchesPerPhase; + int batchEnd = iEnd * m_maxNumBatchesPerPhase; + writeOutConstraintIndicesForRangeOfBatches(m_batchedConstraints, + m_constraintBatchIds, + m_numConstraints, + m_constraintIdPerBatch, + batchBegin, + batchEnd); + } }; - static void writeOutConstraintIndicesMt(btBatchedConstraints* bc, - const int* constraintBatchIds, - int numConstraints, - int* constraintIdPerBatch, - int maxNumBatchesPerPhase, - int numPhases - ) + const int* constraintBatchIds, + int numConstraints, + int* constraintIdPerBatch, + int maxNumBatchesPerPhase, + int numPhases) { - BT_PROFILE("writeOutConstraintIndicesMt"); - bool inParallel = true; - if (inParallel) - { - WriteOutConstraintIndicesLoop loop( bc, constraintBatchIds, numConstraints, constraintIdPerBatch, maxNumBatchesPerPhase ); - btParallelFor( 0, numPhases, 1, loop ); - } - else - { - for ( int iCon = 0; iCon < numConstraints; ++iCon ) - { - int iBatch = constraintBatchIds[ iCon ]; - int iDestCon = constraintIdPerBatch[ iBatch ]; - constraintIdPerBatch[ iBatch ] = iDestCon + 1; - bc->m_constraintIndices[ iDestCon ] = iCon; - } - } + BT_PROFILE("writeOutConstraintIndicesMt"); + bool inParallel = true; + if (inParallel) + { + WriteOutConstraintIndicesLoop loop(bc, constraintBatchIds, numConstraints, constraintIdPerBatch, maxNumBatchesPerPhase); + btParallelFor(0, numPhases, 1, loop); + } + else + { + for (int iCon = 0; iCon < numConstraints; ++iCon) + { + int iBatch = constraintBatchIds[iCon]; + int iDestCon = constraintIdPerBatch[iBatch]; + constraintIdPerBatch[iBatch] = iDestCon + 1; + bc->m_constraintIndices[iDestCon] = iCon; + } + } } - static void writeGrainSizes(btBatchedConstraints* bc) { - typedef btBatchedConstraints::Range Range; - int numPhases = bc->m_phases.size(); - bc->m_phaseGrainSize.resizeNoInitialize(numPhases); - int numThreads = btGetTaskScheduler()->getNumThreads(); - for (int iPhase = 0; iPhase < numPhases; ++iPhase) - { - const Range& phase = bc->m_phases[ iPhase ]; - int numBatches = phase.end - phase.begin; - float grainSize = floor((0.25f*numBatches / float(numThreads)) + 0.0f); - bc->m_phaseGrainSize[ iPhase ] = btMax(1, int(grainSize)); - } + typedef btBatchedConstraints::Range Range; + int numPhases = bc->m_phases.size(); + bc->m_phaseGrainSize.resizeNoInitialize(numPhases); + int numThreads = btGetTaskScheduler()->getNumThreads(); + for (int iPhase = 0; iPhase < numPhases; ++iPhase) + { + const Range& phase = bc->m_phases[iPhase]; + int numBatches = phase.end - phase.begin; + float grainSize = floor((0.25f * numBatches / float(numThreads)) + 0.0f); + bc->m_phaseGrainSize[iPhase] = btMax(1, int(grainSize)); + } } - static void writeOutBatches(btBatchedConstraints* bc, - const int* constraintBatchIds, - int numConstraints, - const btBatchInfo* batches, - int* batchWork, - int maxNumBatchesPerPhase, - int numPhases -) + const int* constraintBatchIds, + int numConstraints, + const btBatchInfo* batches, + int* batchWork, + int maxNumBatchesPerPhase, + int numPhases) { - BT_PROFILE("writeOutBatches"); - typedef btBatchedConstraints::Range Range; - bc->m_constraintIndices.reserve( numConstraints ); - bc->m_batches.resizeNoInitialize( 0 ); - bc->m_phases.resizeNoInitialize( 0 ); + BT_PROFILE("writeOutBatches"); + typedef btBatchedConstraints::Range Range; + bc->m_constraintIndices.reserve(numConstraints); + bc->m_batches.resizeNoInitialize(0); + bc->m_phases.resizeNoInitialize(0); - //int maxNumBatches = numPhases * maxNumBatchesPerPhase; - { - int* constraintIdPerBatch = batchWork; // for each batch, keep an index into the next available slot in the m_constraintIndices array - int iConstraint = 0; - for (int iPhase = 0; iPhase < numPhases; ++iPhase) - { - int curPhaseBegin = bc->m_batches.size(); - int iBegin = iPhase * maxNumBatchesPerPhase; - int iEnd = iBegin + maxNumBatchesPerPhase; - for ( int i = iBegin; i < iEnd; ++i ) - { - const btBatchInfo& batch = batches[ i ]; - int curBatchBegin = iConstraint; - constraintIdPerBatch[ i ] = curBatchBegin; // record the start of each batch in m_constraintIndices array - int numConstraints = batch.numConstraints; - iConstraint += numConstraints; - if ( numConstraints > 0 ) - { - bc->m_batches.push_back( Range( curBatchBegin, iConstraint ) ); - } - } - // if any batches were emitted this phase, - if ( bc->m_batches.size() > curPhaseBegin ) - { - // output phase - bc->m_phases.push_back( Range( curPhaseBegin, bc->m_batches.size() ) ); - } - } + //int maxNumBatches = numPhases * maxNumBatchesPerPhase; + { + int* constraintIdPerBatch = batchWork; // for each batch, keep an index into the next available slot in the m_constraintIndices array + int iConstraint = 0; + for (int iPhase = 0; iPhase < numPhases; ++iPhase) + { + int curPhaseBegin = bc->m_batches.size(); + int iBegin = iPhase * maxNumBatchesPerPhase; + int iEnd = iBegin + maxNumBatchesPerPhase; + for (int i = iBegin; i < iEnd; ++i) + { + const btBatchInfo& batch = batches[i]; + int curBatchBegin = iConstraint; + constraintIdPerBatch[i] = curBatchBegin; // record the start of each batch in m_constraintIndices array + int numConstraints = batch.numConstraints; + iConstraint += numConstraints; + if (numConstraints > 0) + { + bc->m_batches.push_back(Range(curBatchBegin, iConstraint)); + } + } + // if any batches were emitted this phase, + if (bc->m_batches.size() > curPhaseBegin) + { + // output phase + bc->m_phases.push_back(Range(curPhaseBegin, bc->m_batches.size())); + } + } - btAssert(iConstraint == numConstraints); - bc->m_constraintIndices.resizeNoInitialize( numConstraints ); - writeOutConstraintIndicesMt( bc, constraintBatchIds, numConstraints, constraintIdPerBatch, maxNumBatchesPerPhase, numPhases ); - } - // for each phase - for (int iPhase = 0; iPhase < bc->m_phases.size(); ++iPhase) - { - // sort the batches from largest to smallest (can be helpful to some task schedulers) - const Range& curBatches = bc->m_phases[iPhase]; - bc->m_batches.quickSortInternal(BatchCompare, curBatches.begin, curBatches.end-1); - } - bc->m_phaseOrder.resize(bc->m_phases.size()); - for (int i = 0; i < bc->m_phases.size(); ++i) - { - bc->m_phaseOrder[i] = i; - } - writeGrainSizes(bc); + btAssert(iConstraint == numConstraints); + bc->m_constraintIndices.resizeNoInitialize(numConstraints); + writeOutConstraintIndicesMt(bc, constraintBatchIds, numConstraints, constraintIdPerBatch, maxNumBatchesPerPhase, numPhases); + } + // for each phase + for (int iPhase = 0; iPhase < bc->m_phases.size(); ++iPhase) + { + // sort the batches from largest to smallest (can be helpful to some task schedulers) + const Range& curBatches = bc->m_phases[iPhase]; + bc->m_batches.quickSortInternal(BatchCompare, curBatches.begin, curBatches.end - 1); + } + bc->m_phaseOrder.resize(bc->m_phases.size()); + for (int i = 0; i < bc->m_phases.size(); ++i) + { + bc->m_phaseOrder[i] = i; + } + writeGrainSizes(bc); } - // // PreallocatedMemoryHelper -- helper object for allocating a number of chunks of memory in a single contiguous block. // It is generally more efficient to do a single larger allocation than many smaller allocations. @@ -639,191 +605,184 @@ static void writeOutBatches(btBatchedConstraints* bc, template class PreallocatedMemoryHelper { - struct Chunk - { - void** ptr; - size_t size; - }; - Chunk m_chunks[N]; - int m_numChunks; + struct Chunk + { + void** ptr; + size_t size; + }; + Chunk m_chunks[N]; + int m_numChunks; + public: - PreallocatedMemoryHelper() {m_numChunks=0;} - void addChunk( void** ptr, size_t sz ) - { - btAssert( m_numChunks < N ); - if ( m_numChunks < N ) - { - Chunk& chunk = m_chunks[ m_numChunks ]; - chunk.ptr = ptr; - chunk.size = sz; - m_numChunks++; - } - } - size_t getSizeToAllocate() const - { - size_t totalSize = 0; - for (int i = 0; i < m_numChunks; ++i) - { - totalSize += m_chunks[i].size; - } - return totalSize; - } - void setChunkPointers(void* mem) const - { - size_t totalSize = 0; - for (int i = 0; i < m_numChunks; ++i) - { - const Chunk& chunk = m_chunks[ i ]; - char* chunkPtr = static_cast(mem) + totalSize; - *chunk.ptr = chunkPtr; - totalSize += chunk.size; - } - } + PreallocatedMemoryHelper() { m_numChunks = 0; } + void addChunk(void** ptr, size_t sz) + { + btAssert(m_numChunks < N); + if (m_numChunks < N) + { + Chunk& chunk = m_chunks[m_numChunks]; + chunk.ptr = ptr; + chunk.size = sz; + m_numChunks++; + } + } + size_t getSizeToAllocate() const + { + size_t totalSize = 0; + for (int i = 0; i < m_numChunks; ++i) + { + totalSize += m_chunks[i].size; + } + return totalSize; + } + void setChunkPointers(void* mem) const + { + size_t totalSize = 0; + for (int i = 0; i < m_numChunks; ++i) + { + const Chunk& chunk = m_chunks[i]; + char* chunkPtr = static_cast(mem) + totalSize; + *chunk.ptr = chunkPtr; + totalSize += chunk.size; + } + } }; - - static btVector3 findMaxDynamicConstraintExtent( - btVector3* bodyPositions, - bool* bodyDynamicFlags, - btBatchedConstraintInfo* conInfos, - int numConstraints, - int numBodies - ) + btVector3* bodyPositions, + bool* bodyDynamicFlags, + btBatchedConstraintInfo* conInfos, + int numConstraints, + int numBodies) { - BT_PROFILE("findMaxDynamicConstraintExtent"); - btVector3 consExtent = btVector3(1,1,1) * 0.001; - for (int iCon = 0; iCon < numConstraints; ++iCon) - { - const btBatchedConstraintInfo& con = conInfos[ iCon ]; - int iBody0 = con.bodyIds[0]; - int iBody1 = con.bodyIds[1]; - btAssert(iBody0 >= 0 && iBody0 < numBodies); - btAssert(iBody1 >= 0 && iBody1 < numBodies); - // is it a dynamic constraint? - if (bodyDynamicFlags[iBody0] && bodyDynamicFlags[iBody1]) - { - btVector3 delta = bodyPositions[iBody1] - bodyPositions[iBody0]; - consExtent.setMax(delta.absolute()); - } - } - return consExtent; + BT_PROFILE("findMaxDynamicConstraintExtent"); + btVector3 consExtent = btVector3(1, 1, 1) * 0.001; + for (int iCon = 0; iCon < numConstraints; ++iCon) + { + const btBatchedConstraintInfo& con = conInfos[iCon]; + int iBody0 = con.bodyIds[0]; + int iBody1 = con.bodyIds[1]; + btAssert(iBody0 >= 0 && iBody0 < numBodies); + btAssert(iBody1 >= 0 && iBody1 < numBodies); + // is it a dynamic constraint? + if (bodyDynamicFlags[iBody0] && bodyDynamicFlags[iBody1]) + { + btVector3 delta = bodyPositions[iBody1] - bodyPositions[iBody0]; + consExtent.setMax(delta.absolute()); + } + } + return consExtent; } - struct btIntVec3 { - int m_ints[ 3 ]; + int m_ints[3]; - SIMD_FORCE_INLINE const int& operator[](int i) const {return m_ints[i];} - SIMD_FORCE_INLINE int& operator[](int i) {return m_ints[i];} + SIMD_FORCE_INLINE const int& operator[](int i) const { return m_ints[i]; } + SIMD_FORCE_INLINE int& operator[](int i) { return m_ints[i]; } }; - struct AssignConstraintsToGridBatchesParams { - bool* bodyDynamicFlags; - btIntVec3* bodyGridCoords; - int numBodies; - btBatchedConstraintInfo* conInfos; - int* constraintBatchIds; - btIntVec3 gridChunkDim; - int maxNumBatchesPerPhase; - int numPhases; - int phaseMask; + bool* bodyDynamicFlags; + btIntVec3* bodyGridCoords; + int numBodies; + btBatchedConstraintInfo* conInfos; + int* constraintBatchIds; + btIntVec3 gridChunkDim; + int maxNumBatchesPerPhase; + int numPhases; + int phaseMask; - AssignConstraintsToGridBatchesParams() - { - memset(this, 0, sizeof(*this)); - } + AssignConstraintsToGridBatchesParams() + { + memset(this, 0, sizeof(*this)); + } }; - static void assignConstraintsToGridBatches(const AssignConstraintsToGridBatchesParams& params, int iConBegin, int iConEnd) { - BT_PROFILE("assignConstraintsToGridBatches"); - // (can be done in parallel) - for ( int iCon = iConBegin; iCon < iConEnd; ++iCon ) - { - const btBatchedConstraintInfo& con = params.conInfos[ iCon ]; - int iBody0 = con.bodyIds[ 0 ]; - int iBody1 = con.bodyIds[ 1 ]; - int iPhase = iCon; //iBody0; // pseudorandom choice to distribute evenly amongst phases - iPhase &= params.phaseMask; - int gridCoord[ 3 ]; - // is it a dynamic constraint? - if ( params.bodyDynamicFlags[ iBody0 ] && params.bodyDynamicFlags[ iBody1 ] ) - { - const btIntVec3& body0Coords = params.bodyGridCoords[iBody0]; - const btIntVec3& body1Coords = params.bodyGridCoords[iBody1]; - // for each dimension x,y,z, - for (int i = 0; i < 3; ++i) - { - int coordMin = btMin(body0Coords.m_ints[i], body1Coords.m_ints[i]); - int coordMax = btMax(body0Coords.m_ints[i], body1Coords.m_ints[i]); - if (coordMin != coordMax) - { - btAssert( coordMax == coordMin + 1 ); - if ((coordMin&1) == 0) - { - iPhase &= ~(1 << i); // force bit off - } - else - { - iPhase |= (1 << i); // force bit on - iPhase &= params.phaseMask; - } - } - gridCoord[ i ] = coordMin; - } - } - else - { - if ( !params.bodyDynamicFlags[ iBody0 ] ) - { - iBody0 = con.bodyIds[ 1 ]; - } - btAssert(params.bodyDynamicFlags[ iBody0 ]); - const btIntVec3& body0Coords = params.bodyGridCoords[iBody0]; - // for each dimension x,y,z, - for ( int i = 0; i < 3; ++i ) - { - gridCoord[ i ] = body0Coords.m_ints[ i ]; - } - } - // calculate chunk coordinates - int chunkCoord[ 3 ]; - btIntVec3 gridChunkDim = params.gridChunkDim; - // for each dimension x,y,z, - for ( int i = 0; i < 3; ++i ) - { - int coordOffset = ( iPhase >> i ) & 1; - chunkCoord[ i ] = (gridCoord[ i ] - coordOffset)/2; - btClamp( chunkCoord[ i ], 0, gridChunkDim[ i ] - 1); - btAssert( chunkCoord[ i ] < gridChunkDim[ i ] ); - } - int iBatch = iPhase * params.maxNumBatchesPerPhase + chunkCoord[ 0 ] + chunkCoord[ 1 ] * gridChunkDim[ 0 ] + chunkCoord[ 2 ] * gridChunkDim[ 0 ] * gridChunkDim[ 1 ]; - btAssert(iBatch >= 0 && iBatch < params.maxNumBatchesPerPhase*params.numPhases); - params.constraintBatchIds[ iCon ] = iBatch; - } + BT_PROFILE("assignConstraintsToGridBatches"); + // (can be done in parallel) + for (int iCon = iConBegin; iCon < iConEnd; ++iCon) + { + const btBatchedConstraintInfo& con = params.conInfos[iCon]; + int iBody0 = con.bodyIds[0]; + int iBody1 = con.bodyIds[1]; + int iPhase = iCon; //iBody0; // pseudorandom choice to distribute evenly amongst phases + iPhase &= params.phaseMask; + int gridCoord[3]; + // is it a dynamic constraint? + if (params.bodyDynamicFlags[iBody0] && params.bodyDynamicFlags[iBody1]) + { + const btIntVec3& body0Coords = params.bodyGridCoords[iBody0]; + const btIntVec3& body1Coords = params.bodyGridCoords[iBody1]; + // for each dimension x,y,z, + for (int i = 0; i < 3; ++i) + { + int coordMin = btMin(body0Coords.m_ints[i], body1Coords.m_ints[i]); + int coordMax = btMax(body0Coords.m_ints[i], body1Coords.m_ints[i]); + if (coordMin != coordMax) + { + btAssert(coordMax == coordMin + 1); + if ((coordMin & 1) == 0) + { + iPhase &= ~(1 << i); // force bit off + } + else + { + iPhase |= (1 << i); // force bit on + iPhase &= params.phaseMask; + } + } + gridCoord[i] = coordMin; + } + } + else + { + if (!params.bodyDynamicFlags[iBody0]) + { + iBody0 = con.bodyIds[1]; + } + btAssert(params.bodyDynamicFlags[iBody0]); + const btIntVec3& body0Coords = params.bodyGridCoords[iBody0]; + // for each dimension x,y,z, + for (int i = 0; i < 3; ++i) + { + gridCoord[i] = body0Coords.m_ints[i]; + } + } + // calculate chunk coordinates + int chunkCoord[3]; + btIntVec3 gridChunkDim = params.gridChunkDim; + // for each dimension x,y,z, + for (int i = 0; i < 3; ++i) + { + int coordOffset = (iPhase >> i) & 1; + chunkCoord[i] = (gridCoord[i] - coordOffset) / 2; + btClamp(chunkCoord[i], 0, gridChunkDim[i] - 1); + btAssert(chunkCoord[i] < gridChunkDim[i]); + } + int iBatch = iPhase * params.maxNumBatchesPerPhase + chunkCoord[0] + chunkCoord[1] * gridChunkDim[0] + chunkCoord[2] * gridChunkDim[0] * gridChunkDim[1]; + btAssert(iBatch >= 0 && iBatch < params.maxNumBatchesPerPhase * params.numPhases); + params.constraintBatchIds[iCon] = iBatch; + } } - struct AssignConstraintsToGridBatchesLoop : public btIParallelForBody { - const AssignConstraintsToGridBatchesParams* m_params; + const AssignConstraintsToGridBatchesParams* m_params; - AssignConstraintsToGridBatchesLoop( const AssignConstraintsToGridBatchesParams& params ) - { - m_params = ¶ms; - } - void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - assignConstraintsToGridBatches(*m_params, iBegin, iEnd); - } + AssignConstraintsToGridBatchesLoop(const AssignConstraintsToGridBatchesParams& params) + { + m_params = ¶ms; + } + void forLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + assignConstraintsToGridBatches(*m_params, iBegin, iEnd); + } }; - // // setupSpatialGridBatchesMt -- generate batches using a uniform 3D grid // @@ -853,276 +812,269 @@ to 4. With fewer phases, there are more constraints per phase and this makes it */ // static void setupSpatialGridBatchesMt( - btBatchedConstraints* batchedConstraints, - btAlignedObjectArray* scratchMemory, - btConstraintArray* constraints, - const btAlignedObjectArray& bodies, - int minBatchSize, - int maxBatchSize, - bool use2DGrid -) + btBatchedConstraints* batchedConstraints, + btAlignedObjectArray* scratchMemory, + btConstraintArray* constraints, + const btAlignedObjectArray& bodies, + int minBatchSize, + int maxBatchSize, + bool use2DGrid) { - BT_PROFILE("setupSpatialGridBatchesMt"); - const int numPhases = 8; - int numConstraints = constraints->size(); - int numConstraintRows = constraints->size(); + BT_PROFILE("setupSpatialGridBatchesMt"); + const int numPhases = 8; + int numConstraints = constraints->size(); + int numConstraintRows = constraints->size(); - const int maxGridChunkCount = 128; - int allocNumBatchesPerPhase = maxGridChunkCount; - int minNumBatchesPerPhase = 16; - int allocNumBatches = allocNumBatchesPerPhase * numPhases; + const int maxGridChunkCount = 128; + int allocNumBatchesPerPhase = maxGridChunkCount; + int minNumBatchesPerPhase = 16; + int allocNumBatches = allocNumBatchesPerPhase * numPhases; - btVector3* bodyPositions = NULL; - bool* bodyDynamicFlags = NULL; - btIntVec3* bodyGridCoords = NULL; - btBatchInfo* batches = NULL; - int* batchWork = NULL; - btBatchedConstraintInfo* conInfos = NULL; - int* constraintBatchIds = NULL; - int* constraintRowBatchIds = NULL; - { - PreallocatedMemoryHelper<10> memHelper; - memHelper.addChunk( (void**) &bodyPositions, sizeof( btVector3 ) * bodies.size() ); - memHelper.addChunk( (void**) &bodyDynamicFlags, sizeof( bool ) * bodies.size() ); - memHelper.addChunk( (void**) &bodyGridCoords, sizeof( btIntVec3 ) * bodies.size() ); - memHelper.addChunk( (void**) &batches, sizeof( btBatchInfo )* allocNumBatches ); - memHelper.addChunk( (void**) &batchWork, sizeof( int )* allocNumBatches ); - memHelper.addChunk( (void**) &conInfos, sizeof( btBatchedConstraintInfo ) * numConstraints ); - memHelper.addChunk( (void**) &constraintBatchIds, sizeof( int ) * numConstraints ); - memHelper.addChunk( (void**) &constraintRowBatchIds, sizeof( int ) * numConstraintRows ); - size_t scratchSize = memHelper.getSizeToAllocate(); - // if we need to reallocate - if (scratchMemory->capacity() < scratchSize) - { - // allocate 6.25% extra to avoid repeated reallocs - scratchMemory->reserve( scratchSize + scratchSize/16 ); - } - scratchMemory->resizeNoInitialize( scratchSize ); - char* memPtr = &scratchMemory->at(0); - memHelper.setChunkPointers( memPtr ); - } + btVector3* bodyPositions = NULL; + bool* bodyDynamicFlags = NULL; + btIntVec3* bodyGridCoords = NULL; + btBatchInfo* batches = NULL; + int* batchWork = NULL; + btBatchedConstraintInfo* conInfos = NULL; + int* constraintBatchIds = NULL; + int* constraintRowBatchIds = NULL; + { + PreallocatedMemoryHelper<10> memHelper; + memHelper.addChunk((void**)&bodyPositions, sizeof(btVector3) * bodies.size()); + memHelper.addChunk((void**)&bodyDynamicFlags, sizeof(bool) * bodies.size()); + memHelper.addChunk((void**)&bodyGridCoords, sizeof(btIntVec3) * bodies.size()); + memHelper.addChunk((void**)&batches, sizeof(btBatchInfo) * allocNumBatches); + memHelper.addChunk((void**)&batchWork, sizeof(int) * allocNumBatches); + memHelper.addChunk((void**)&conInfos, sizeof(btBatchedConstraintInfo) * numConstraints); + memHelper.addChunk((void**)&constraintBatchIds, sizeof(int) * numConstraints); + memHelper.addChunk((void**)&constraintRowBatchIds, sizeof(int) * numConstraintRows); + size_t scratchSize = memHelper.getSizeToAllocate(); + // if we need to reallocate + if (scratchMemory->capacity() < scratchSize) + { + // allocate 6.25% extra to avoid repeated reallocs + scratchMemory->reserve(scratchSize + scratchSize / 16); + } + scratchMemory->resizeNoInitialize(scratchSize); + char* memPtr = &scratchMemory->at(0); + memHelper.setChunkPointers(memPtr); + } - numConstraints = initBatchedConstraintInfo(conInfos, constraints); + numConstraints = initBatchedConstraintInfo(conInfos, constraints); - // compute bounding box around all dynamic bodies - // (could be done in parallel) - btVector3 bboxMin(BT_LARGE_FLOAT, BT_LARGE_FLOAT, BT_LARGE_FLOAT); - btVector3 bboxMax = -bboxMin; - //int dynamicBodyCount = 0; - for (int i = 0; i < bodies.size(); ++i) - { - const btSolverBody& body = bodies[i]; - btVector3 bodyPos = body.getWorldTransform().getOrigin(); - bool isDynamic = ( body.internalGetInvMass().x() > btScalar( 0 ) ); - bodyPositions[i] = bodyPos; - bodyDynamicFlags[i] = isDynamic; - if (isDynamic) - { - //dynamicBodyCount++; - bboxMin.setMin(bodyPos); - bboxMax.setMax(bodyPos); - } - } + // compute bounding box around all dynamic bodies + // (could be done in parallel) + btVector3 bboxMin(BT_LARGE_FLOAT, BT_LARGE_FLOAT, BT_LARGE_FLOAT); + btVector3 bboxMax = -bboxMin; + //int dynamicBodyCount = 0; + for (int i = 0; i < bodies.size(); ++i) + { + const btSolverBody& body = bodies[i]; + btVector3 bodyPos = body.getWorldTransform().getOrigin(); + bool isDynamic = (body.internalGetInvMass().x() > btScalar(0)); + bodyPositions[i] = bodyPos; + bodyDynamicFlags[i] = isDynamic; + if (isDynamic) + { + //dynamicBodyCount++; + bboxMin.setMin(bodyPos); + bboxMax.setMax(bodyPos); + } + } - // find max extent of all dynamic constraints - // (could be done in parallel) - btVector3 consExtent = findMaxDynamicConstraintExtent(bodyPositions, bodyDynamicFlags, conInfos, numConstraints, bodies.size()); + // find max extent of all dynamic constraints + // (could be done in parallel) + btVector3 consExtent = findMaxDynamicConstraintExtent(bodyPositions, bodyDynamicFlags, conInfos, numConstraints, bodies.size()); - btVector3 gridExtent = bboxMax - bboxMin; + btVector3 gridExtent = bboxMax - bboxMin; - btVector3 gridCellSize = consExtent; - int gridDim[3]; - gridDim[ 0 ] = int( 1.0 + gridExtent.x() / gridCellSize.x() ); - gridDim[ 1 ] = int( 1.0 + gridExtent.y() / gridCellSize.y() ); - gridDim[ 2 ] = int( 1.0 + gridExtent.z() / gridCellSize.z() ); + btVector3 gridCellSize = consExtent; + int gridDim[3]; + gridDim[0] = int(1.0 + gridExtent.x() / gridCellSize.x()); + gridDim[1] = int(1.0 + gridExtent.y() / gridCellSize.y()); + gridDim[2] = int(1.0 + gridExtent.z() / gridCellSize.z()); - // if we can collapse an axis, it will cut our number of phases in half which could be more efficient - int phaseMask = 7; - bool collapseAxis = use2DGrid; - if ( collapseAxis ) - { - // pick the smallest axis to collapse, leaving us with the greatest number of cells in our grid - int iAxisToCollapse = 0; - int axisDim = gridDim[iAxisToCollapse]; - //for each dimension - for ( int i = 0; i < 3; ++i ) - { - if (gridDim[i] < axisDim) - { - iAxisToCollapse = i; - axisDim = gridDim[i]; - } - } - // collapse it - gridCellSize[iAxisToCollapse] = gridExtent[iAxisToCollapse] * 2.0f; - phaseMask &= ~(1 << iAxisToCollapse); - } + // if we can collapse an axis, it will cut our number of phases in half which could be more efficient + int phaseMask = 7; + bool collapseAxis = use2DGrid; + if (collapseAxis) + { + // pick the smallest axis to collapse, leaving us with the greatest number of cells in our grid + int iAxisToCollapse = 0; + int axisDim = gridDim[iAxisToCollapse]; + //for each dimension + for (int i = 0; i < 3; ++i) + { + if (gridDim[i] < axisDim) + { + iAxisToCollapse = i; + axisDim = gridDim[i]; + } + } + // collapse it + gridCellSize[iAxisToCollapse] = gridExtent[iAxisToCollapse] * 2.0f; + phaseMask &= ~(1 << iAxisToCollapse); + } - int numGridChunks = 0; - btIntVec3 gridChunkDim; // each chunk is 2x2x2 group of cells - while (true) - { - gridDim[0] = int( 1.0 + gridExtent.x() / gridCellSize.x() ); - gridDim[1] = int( 1.0 + gridExtent.y() / gridCellSize.y() ); - gridDim[2] = int( 1.0 + gridExtent.z() / gridCellSize.z() ); - gridChunkDim[ 0 ] = btMax( 1, ( gridDim[ 0 ] + 0 ) / 2 ); - gridChunkDim[ 1 ] = btMax( 1, ( gridDim[ 1 ] + 0 ) / 2 ); - gridChunkDim[ 2 ] = btMax( 1, ( gridDim[ 2 ] + 0 ) / 2 ); - numGridChunks = gridChunkDim[ 0 ] * gridChunkDim[ 1 ] * gridChunkDim[ 2 ]; - float nChunks = float(gridChunkDim[0]) * float(gridChunkDim[1]) * float(gridChunkDim[2]); // suceptible to integer overflow - if ( numGridChunks <= maxGridChunkCount && nChunks <= maxGridChunkCount ) - { - break; - } - gridCellSize *= 1.25; // should roughly cut numCells in half - } - btAssert(numGridChunks <= maxGridChunkCount ); - int maxNumBatchesPerPhase = numGridChunks; + int numGridChunks = 0; + btIntVec3 gridChunkDim; // each chunk is 2x2x2 group of cells + while (true) + { + gridDim[0] = int(1.0 + gridExtent.x() / gridCellSize.x()); + gridDim[1] = int(1.0 + gridExtent.y() / gridCellSize.y()); + gridDim[2] = int(1.0 + gridExtent.z() / gridCellSize.z()); + gridChunkDim[0] = btMax(1, (gridDim[0] + 0) / 2); + gridChunkDim[1] = btMax(1, (gridDim[1] + 0) / 2); + gridChunkDim[2] = btMax(1, (gridDim[2] + 0) / 2); + numGridChunks = gridChunkDim[0] * gridChunkDim[1] * gridChunkDim[2]; + float nChunks = float(gridChunkDim[0]) * float(gridChunkDim[1]) * float(gridChunkDim[2]); // suceptible to integer overflow + if (numGridChunks <= maxGridChunkCount && nChunks <= maxGridChunkCount) + { + break; + } + gridCellSize *= 1.25; // should roughly cut numCells in half + } + btAssert(numGridChunks <= maxGridChunkCount); + int maxNumBatchesPerPhase = numGridChunks; - // for each dynamic body, compute grid coords - btVector3 invGridCellSize = btVector3(1,1,1)/gridCellSize; - // (can be done in parallel) - for (int iBody = 0; iBody < bodies.size(); ++iBody) - { - btIntVec3& coords = bodyGridCoords[iBody]; - if (bodyDynamicFlags[iBody]) - { - btVector3 v = ( bodyPositions[ iBody ] - bboxMin )*invGridCellSize; - coords.m_ints[0] = int(v.x()); - coords.m_ints[1] = int(v.y()); - coords.m_ints[2] = int(v.z()); - btAssert(coords.m_ints[0] >= 0 && coords.m_ints[0] < gridDim[0]); - btAssert(coords.m_ints[1] >= 0 && coords.m_ints[1] < gridDim[1]); - btAssert(coords.m_ints[2] >= 0 && coords.m_ints[2] < gridDim[2]); - } - else - { - coords.m_ints[0] = -1; - coords.m_ints[1] = -1; - coords.m_ints[2] = -1; - } - } + // for each dynamic body, compute grid coords + btVector3 invGridCellSize = btVector3(1, 1, 1) / gridCellSize; + // (can be done in parallel) + for (int iBody = 0; iBody < bodies.size(); ++iBody) + { + btIntVec3& coords = bodyGridCoords[iBody]; + if (bodyDynamicFlags[iBody]) + { + btVector3 v = (bodyPositions[iBody] - bboxMin) * invGridCellSize; + coords.m_ints[0] = int(v.x()); + coords.m_ints[1] = int(v.y()); + coords.m_ints[2] = int(v.z()); + btAssert(coords.m_ints[0] >= 0 && coords.m_ints[0] < gridDim[0]); + btAssert(coords.m_ints[1] >= 0 && coords.m_ints[1] < gridDim[1]); + btAssert(coords.m_ints[2] >= 0 && coords.m_ints[2] < gridDim[2]); + } + else + { + coords.m_ints[0] = -1; + coords.m_ints[1] = -1; + coords.m_ints[2] = -1; + } + } - for (int iPhase = 0; iPhase < numPhases; ++iPhase) - { - int batchBegin = iPhase * maxNumBatchesPerPhase; - int batchEnd = batchBegin + maxNumBatchesPerPhase; - for ( int iBatch = batchBegin; iBatch < batchEnd; ++iBatch ) - { - btBatchInfo& batch = batches[ iBatch ]; - batch = btBatchInfo(); - } - } + for (int iPhase = 0; iPhase < numPhases; ++iPhase) + { + int batchBegin = iPhase * maxNumBatchesPerPhase; + int batchEnd = batchBegin + maxNumBatchesPerPhase; + for (int iBatch = batchBegin; iBatch < batchEnd; ++iBatch) + { + btBatchInfo& batch = batches[iBatch]; + batch = btBatchInfo(); + } + } - { - AssignConstraintsToGridBatchesParams params; - params.bodyDynamicFlags = bodyDynamicFlags; - params.bodyGridCoords = bodyGridCoords; - params.numBodies = bodies.size(); - params.conInfos = conInfos; - params.constraintBatchIds = constraintBatchIds; - params.gridChunkDim = gridChunkDim; - params.maxNumBatchesPerPhase = maxNumBatchesPerPhase; - params.numPhases = numPhases; - params.phaseMask = phaseMask; - bool inParallel = true; - if (inParallel) - { - AssignConstraintsToGridBatchesLoop loop(params); - int grainSize = 250; - btParallelFor(0, numConstraints, grainSize, loop); - } - else - { - assignConstraintsToGridBatches( params, 0, numConstraints ); - } - } - for ( int iCon = 0; iCon < numConstraints; ++iCon ) - { - const btBatchedConstraintInfo& con = conInfos[ iCon ]; - int iBatch = constraintBatchIds[ iCon ]; - btBatchInfo& batch = batches[iBatch]; - batch.numConstraints += con.numConstraintRows; - } + { + AssignConstraintsToGridBatchesParams params; + params.bodyDynamicFlags = bodyDynamicFlags; + params.bodyGridCoords = bodyGridCoords; + params.numBodies = bodies.size(); + params.conInfos = conInfos; + params.constraintBatchIds = constraintBatchIds; + params.gridChunkDim = gridChunkDim; + params.maxNumBatchesPerPhase = maxNumBatchesPerPhase; + params.numPhases = numPhases; + params.phaseMask = phaseMask; + bool inParallel = true; + if (inParallel) + { + AssignConstraintsToGridBatchesLoop loop(params); + int grainSize = 250; + btParallelFor(0, numConstraints, grainSize, loop); + } + else + { + assignConstraintsToGridBatches(params, 0, numConstraints); + } + } + for (int iCon = 0; iCon < numConstraints; ++iCon) + { + const btBatchedConstraintInfo& con = conInfos[iCon]; + int iBatch = constraintBatchIds[iCon]; + btBatchInfo& batch = batches[iBatch]; + batch.numConstraints += con.numConstraintRows; + } - for (int iPhase = 0; iPhase < numPhases; ++iPhase) - { - // if phase is legit, - if (iPhase == (iPhase&phaseMask)) - { - int iBeginBatch = iPhase * maxNumBatchesPerPhase; - int iEndBatch = iBeginBatch + maxNumBatchesPerPhase; - mergeSmallBatches( batches, iBeginBatch, iEndBatch, minBatchSize, maxBatchSize ); - } - } - // all constraints have been assigned a batchId - updateConstraintBatchIdsForMergesMt(constraintBatchIds, numConstraints, batches, maxNumBatchesPerPhase*numPhases); + for (int iPhase = 0; iPhase < numPhases; ++iPhase) + { + // if phase is legit, + if (iPhase == (iPhase & phaseMask)) + { + int iBeginBatch = iPhase * maxNumBatchesPerPhase; + int iEndBatch = iBeginBatch + maxNumBatchesPerPhase; + mergeSmallBatches(batches, iBeginBatch, iEndBatch, minBatchSize, maxBatchSize); + } + } + // all constraints have been assigned a batchId + updateConstraintBatchIdsForMergesMt(constraintBatchIds, numConstraints, batches, maxNumBatchesPerPhase * numPhases); - if (numConstraintRows > numConstraints) - { - expandConstraintRowsMt(&constraintRowBatchIds[0], &constraintBatchIds[0], &conInfos[0], numConstraints, numConstraintRows); - } - else - { - constraintRowBatchIds = constraintBatchIds; - } + if (numConstraintRows > numConstraints) + { + expandConstraintRowsMt(&constraintRowBatchIds[0], &constraintBatchIds[0], &conInfos[0], numConstraints, numConstraintRows); + } + else + { + constraintRowBatchIds = constraintBatchIds; + } - writeOutBatches(batchedConstraints, constraintRowBatchIds, numConstraintRows, batches, batchWork, maxNumBatchesPerPhase, numPhases); - btAssert(batchedConstraints->validate(constraints, bodies)); + writeOutBatches(batchedConstraints, constraintRowBatchIds, numConstraintRows, batches, batchWork, maxNumBatchesPerPhase, numPhases); + btAssert(batchedConstraints->validate(constraints, bodies)); } - static void setupSingleBatch( - btBatchedConstraints* bc, - int numConstraints -) + btBatchedConstraints* bc, + int numConstraints) { - BT_PROFILE("setupSingleBatch"); - typedef btBatchedConstraints::Range Range; + BT_PROFILE("setupSingleBatch"); + typedef btBatchedConstraints::Range Range; - bc->m_constraintIndices.resize( numConstraints ); - for ( int i = 0; i < numConstraints; ++i ) - { - bc->m_constraintIndices[ i ] = i; - } + bc->m_constraintIndices.resize(numConstraints); + for (int i = 0; i < numConstraints; ++i) + { + bc->m_constraintIndices[i] = i; + } - bc->m_batches.resizeNoInitialize( 0 ); - bc->m_phases.resizeNoInitialize( 0 ); - bc->m_phaseOrder.resizeNoInitialize( 0 ); - bc->m_phaseGrainSize.resizeNoInitialize( 0 ); + bc->m_batches.resizeNoInitialize(0); + bc->m_phases.resizeNoInitialize(0); + bc->m_phaseOrder.resizeNoInitialize(0); + bc->m_phaseGrainSize.resizeNoInitialize(0); - if (numConstraints > 0) - { - bc->m_batches.push_back( Range( 0, numConstraints ) ); - bc->m_phases.push_back( Range( 0, 1 ) ); - bc->m_phaseOrder.push_back(0); - bc->m_phaseGrainSize.push_back(1); - } + if (numConstraints > 0) + { + bc->m_batches.push_back(Range(0, numConstraints)); + bc->m_phases.push_back(Range(0, 1)); + bc->m_phaseOrder.push_back(0); + bc->m_phaseGrainSize.push_back(1); + } } - void btBatchedConstraints::setup( - btConstraintArray* constraints, - const btAlignedObjectArray& bodies, - BatchingMethod batchingMethod, - int minBatchSize, - int maxBatchSize, - btAlignedObjectArray* scratchMemory - ) + btConstraintArray* constraints, + const btAlignedObjectArray& bodies, + BatchingMethod batchingMethod, + int minBatchSize, + int maxBatchSize, + btAlignedObjectArray* scratchMemory) { - if (constraints->size() >= minBatchSize*4) - { - bool use2DGrid = batchingMethod == BATCHING_METHOD_SPATIAL_GRID_2D; - setupSpatialGridBatchesMt( this, scratchMemory, constraints, bodies, minBatchSize, maxBatchSize, use2DGrid ); - if (s_debugDrawBatches) - { - debugDrawAllBatches( this, constraints, bodies ); - } - } - else - { - setupSingleBatch( this, constraints->size() ); - } + if (constraints->size() >= minBatchSize * 4) + { + bool use2DGrid = batchingMethod == BATCHING_METHOD_SPATIAL_GRID_2D; + setupSpatialGridBatchesMt(this, scratchMemory, constraints, bodies, minBatchSize, maxBatchSize, use2DGrid); + if (s_debugDrawBatches) + { + debugDrawAllBatches(this, constraints, bodies); + } + } + else + { + setupSingleBatch(this, constraints->size()); + } } - - diff --git a/src/BulletDynamics/ConstraintSolver/btBatchedConstraints.h b/src/BulletDynamics/ConstraintSolver/btBatchedConstraints.h index 0fd8f31dd..5d982ca37 100644 --- a/src/BulletDynamics/ConstraintSolver/btBatchedConstraints.h +++ b/src/BulletDynamics/ConstraintSolver/btBatchedConstraints.h @@ -21,46 +21,42 @@ subject to the following restrictions: #include "BulletDynamics/ConstraintSolver/btSolverBody.h" #include "BulletDynamics/ConstraintSolver/btSolverConstraint.h" - class btIDebugDraw; struct btBatchedConstraints { - enum BatchingMethod - { - BATCHING_METHOD_SPATIAL_GRID_2D, - BATCHING_METHOD_SPATIAL_GRID_3D, - BATCHING_METHOD_COUNT - }; - struct Range - { - int begin; - int end; + enum BatchingMethod + { + BATCHING_METHOD_SPATIAL_GRID_2D, + BATCHING_METHOD_SPATIAL_GRID_3D, + BATCHING_METHOD_COUNT + }; + struct Range + { + int begin; + int end; - Range() : begin( 0 ), end( 0 ) {} - Range( int _beg, int _end ) : begin( _beg ), end( _end ) {} - }; + Range() : begin(0), end(0) {} + Range(int _beg, int _end) : begin(_beg), end(_end) {} + }; - btAlignedObjectArray m_constraintIndices; - btAlignedObjectArray m_batches; // each batch is a range of indices in the m_constraintIndices array - btAlignedObjectArray m_phases; // each phase is range of indices in the m_batches array - btAlignedObjectArray m_phaseGrainSize; // max grain size for each phase - btAlignedObjectArray m_phaseOrder; // phases can be done in any order, so we can randomize the order here - btIDebugDraw* m_debugDrawer; + btAlignedObjectArray m_constraintIndices; + btAlignedObjectArray m_batches; // each batch is a range of indices in the m_constraintIndices array + btAlignedObjectArray m_phases; // each phase is range of indices in the m_batches array + btAlignedObjectArray m_phaseGrainSize; // max grain size for each phase + btAlignedObjectArray m_phaseOrder; // phases can be done in any order, so we can randomize the order here + btIDebugDraw* m_debugDrawer; - static bool s_debugDrawBatches; + static bool s_debugDrawBatches; - btBatchedConstraints() {m_debugDrawer=NULL;} - void setup( btConstraintArray* constraints, - const btAlignedObjectArray& bodies, - BatchingMethod batchingMethod, - int minBatchSize, - int maxBatchSize, - btAlignedObjectArray* scratchMemory - ); - bool validate( btConstraintArray* constraints, const btAlignedObjectArray& bodies ) const; + btBatchedConstraints() { m_debugDrawer = NULL; } + void setup(btConstraintArray* constraints, + const btAlignedObjectArray& bodies, + BatchingMethod batchingMethod, + int minBatchSize, + int maxBatchSize, + btAlignedObjectArray* scratchMemory); + bool validate(btConstraintArray* constraints, const btAlignedObjectArray& bodies) const; }; - -#endif // BT_BATCHED_CONSTRAINTS_H - +#endif // BT_BATCHED_CONSTRAINTS_H diff --git a/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp index 0572256f7..10678b2a6 100644 --- a/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp +++ b/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.cpp @@ -15,49 +15,37 @@ subject to the following restrictions: Written by: Marcus Hennix */ - #include "btConeTwistConstraint.h" #include "BulletDynamics/Dynamics/btRigidBody.h" #include "LinearMath/btTransformUtil.h" #include "LinearMath/btMinMax.h" #include - - //#define CONETWIST_USE_OBSOLETE_SOLVER true #define CONETWIST_USE_OBSOLETE_SOLVER false #define CONETWIST_DEF_FIX_THRESH btScalar(.05f) - SIMD_FORCE_INLINE btScalar computeAngularImpulseDenominator(const btVector3& axis, const btMatrix3x3& invInertiaWorld) { btVector3 vec = axis * invInertiaWorld; return axis.dot(vec); } - - - -btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB, - const btTransform& rbAFrame,const btTransform& rbBFrame) - :btTypedConstraint(CONETWIST_CONSTRAINT_TYPE, rbA,rbB),m_rbAFrame(rbAFrame),m_rbBFrame(rbBFrame), - m_angularOnly(false), - m_useSolveConstraintObsolete(CONETWIST_USE_OBSOLETE_SOLVER) +btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA, btRigidBody& rbB, + const btTransform& rbAFrame, const btTransform& rbBFrame) + : btTypedConstraint(CONETWIST_CONSTRAINT_TYPE, rbA, rbB), m_rbAFrame(rbAFrame), m_rbBFrame(rbBFrame), m_angularOnly(false), m_useSolveConstraintObsolete(CONETWIST_USE_OBSOLETE_SOLVER) { init(); } -btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame) - :btTypedConstraint(CONETWIST_CONSTRAINT_TYPE,rbA),m_rbAFrame(rbAFrame), - m_angularOnly(false), - m_useSolveConstraintObsolete(CONETWIST_USE_OBSOLETE_SOLVER) +btConeTwistConstraint::btConeTwistConstraint(btRigidBody& rbA, const btTransform& rbAFrame) + : btTypedConstraint(CONETWIST_CONSTRAINT_TYPE, rbA), m_rbAFrame(rbAFrame), m_angularOnly(false), m_useSolveConstraintObsolete(CONETWIST_USE_OBSOLETE_SOLVER) { m_rbBFrame = m_rbAFrame; m_rbBFrame.setOrigin(btVector3(0., 0., 0.)); - init(); + init(); } - void btConeTwistConstraint::init() { m_angularOnly = false; @@ -75,30 +63,29 @@ void btConeTwistConstraint::init() m_angCFM = btScalar(0.f); } - -void btConeTwistConstraint::getInfo1 (btConstraintInfo1* info) +void btConeTwistConstraint::getInfo1(btConstraintInfo1* info) { if (m_useSolveConstraintObsolete) { info->m_numConstraintRows = 0; info->nub = 0; - } + } else { info->m_numConstraintRows = 3; info->nub = 3; - calcAngleInfo2(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform(),m_rbA.getInvInertiaTensorWorld(),m_rbB.getInvInertiaTensorWorld()); - if(m_solveSwingLimit) + calcAngleInfo2(m_rbA.getCenterOfMassTransform(), m_rbB.getCenterOfMassTransform(), m_rbA.getInvInertiaTensorWorld(), m_rbB.getInvInertiaTensorWorld()); + if (m_solveSwingLimit) { info->m_numConstraintRows++; info->nub--; - if((m_swingSpan1 < m_fixThresh) && (m_swingSpan2 < m_fixThresh)) + if ((m_swingSpan1 < m_fixThresh) && (m_swingSpan2 < m_fixThresh)) { info->m_numConstraintRows++; info->nub--; } } - if(m_solveTwistLimit) + if (m_solveTwistLimit) { info->m_numConstraintRows++; info->nub--; @@ -106,90 +93,88 @@ void btConeTwistConstraint::getInfo1 (btConstraintInfo1* info) } } -void btConeTwistConstraint::getInfo1NonVirtual (btConstraintInfo1* info) +void btConeTwistConstraint::getInfo1NonVirtual(btConstraintInfo1* info) { //always reserve 6 rows: object transform is not available on SPU info->m_numConstraintRows = 6; info->nub = 0; - -} - - -void btConeTwistConstraint::getInfo2 (btConstraintInfo2* info) -{ - getInfo2NonVirtual(info,m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform(),m_rbA.getInvInertiaTensorWorld(),m_rbB.getInvInertiaTensorWorld()); } -void btConeTwistConstraint::getInfo2NonVirtual (btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btMatrix3x3& invInertiaWorldA,const btMatrix3x3& invInertiaWorldB) +void btConeTwistConstraint::getInfo2(btConstraintInfo2* info) { - calcAngleInfo2(transA,transB,invInertiaWorldA,invInertiaWorldB); - + getInfo2NonVirtual(info, m_rbA.getCenterOfMassTransform(), m_rbB.getCenterOfMassTransform(), m_rbA.getInvInertiaTensorWorld(), m_rbB.getInvInertiaTensorWorld()); +} + +void btConeTwistConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTransform& transA, const btTransform& transB, const btMatrix3x3& invInertiaWorldA, const btMatrix3x3& invInertiaWorldB) +{ + calcAngleInfo2(transA, transB, invInertiaWorldA, invInertiaWorldB); + btAssert(!m_useSolveConstraintObsolete); - // set jacobian - info->m_J1linearAxis[0] = 1; - info->m_J1linearAxis[info->rowskip+1] = 1; - info->m_J1linearAxis[2*info->rowskip+2] = 1; + // set jacobian + info->m_J1linearAxis[0] = 1; + info->m_J1linearAxis[info->rowskip + 1] = 1; + info->m_J1linearAxis[2 * info->rowskip + 2] = 1; btVector3 a1 = transA.getBasis() * m_rbAFrame.getOrigin(); { btVector3* angular0 = (btVector3*)(info->m_J1angularAxis); - btVector3* angular1 = (btVector3*)(info->m_J1angularAxis+info->rowskip); - btVector3* angular2 = (btVector3*)(info->m_J1angularAxis+2*info->rowskip); + btVector3* angular1 = (btVector3*)(info->m_J1angularAxis + info->rowskip); + btVector3* angular2 = (btVector3*)(info->m_J1angularAxis + 2 * info->rowskip); btVector3 a1neg = -a1; - a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2); + a1neg.getSkewSymmetricMatrix(angular0, angular1, angular2); } - info->m_J2linearAxis[0] = -1; - info->m_J2linearAxis[info->rowskip+1] = -1; - info->m_J2linearAxis[2*info->rowskip+2] = -1; + info->m_J2linearAxis[0] = -1; + info->m_J2linearAxis[info->rowskip + 1] = -1; + info->m_J2linearAxis[2 * info->rowskip + 2] = -1; btVector3 a2 = transB.getBasis() * m_rbBFrame.getOrigin(); { btVector3* angular0 = (btVector3*)(info->m_J2angularAxis); - btVector3* angular1 = (btVector3*)(info->m_J2angularAxis+info->rowskip); - btVector3* angular2 = (btVector3*)(info->m_J2angularAxis+2*info->rowskip); - a2.getSkewSymmetricMatrix(angular0,angular1,angular2); + btVector3* angular1 = (btVector3*)(info->m_J2angularAxis + info->rowskip); + btVector3* angular2 = (btVector3*)(info->m_J2angularAxis + 2 * info->rowskip); + a2.getSkewSymmetricMatrix(angular0, angular1, angular2); } - // set right hand side + // set right hand side btScalar linERP = (m_flags & BT_CONETWIST_FLAGS_LIN_ERP) ? m_linERP : info->erp; - btScalar k = info->fps * linERP; - int j; - for (j=0; j<3; j++) - { - info->m_constraintError[j*info->rowskip] = k * (a2[j] + transB.getOrigin()[j] - a1[j] - transA.getOrigin()[j]); - info->m_lowerLimit[j*info->rowskip] = -SIMD_INFINITY; - info->m_upperLimit[j*info->rowskip] = SIMD_INFINITY; - if(m_flags & BT_CONETWIST_FLAGS_LIN_CFM) + btScalar k = info->fps * linERP; + int j; + for (j = 0; j < 3; j++) + { + info->m_constraintError[j * info->rowskip] = k * (a2[j] + transB.getOrigin()[j] - a1[j] - transA.getOrigin()[j]); + info->m_lowerLimit[j * info->rowskip] = -SIMD_INFINITY; + info->m_upperLimit[j * info->rowskip] = SIMD_INFINITY; + if (m_flags & BT_CONETWIST_FLAGS_LIN_CFM) { - info->cfm[j*info->rowskip] = m_linCFM; + info->cfm[j * info->rowskip] = m_linCFM; } - } + } int row = 3; - int srow = row * info->rowskip; + int srow = row * info->rowskip; btVector3 ax1; // angular limits - if(m_solveSwingLimit) + if (m_solveSwingLimit) { - btScalar *J1 = info->m_J1angularAxis; - btScalar *J2 = info->m_J2angularAxis; - if((m_swingSpan1 < m_fixThresh) && (m_swingSpan2 < m_fixThresh)) + btScalar* J1 = info->m_J1angularAxis; + btScalar* J2 = info->m_J2angularAxis; + if ((m_swingSpan1 < m_fixThresh) && (m_swingSpan2 < m_fixThresh)) { - btTransform trA = transA*m_rbAFrame; + btTransform trA = transA * m_rbAFrame; btVector3 p = trA.getBasis().getColumn(1); btVector3 q = trA.getBasis().getColumn(2); int srow1 = srow + info->rowskip; - J1[srow+0] = p[0]; - J1[srow+1] = p[1]; - J1[srow+2] = p[2]; - J1[srow1+0] = q[0]; - J1[srow1+1] = q[1]; - J1[srow1+2] = q[2]; - J2[srow+0] = -p[0]; - J2[srow+1] = -p[1]; - J2[srow+2] = -p[2]; - J2[srow1+0] = -q[0]; - J2[srow1+1] = -q[1]; - J2[srow1+2] = -q[2]; + J1[srow + 0] = p[0]; + J1[srow + 1] = p[1]; + J1[srow + 2] = p[2]; + J1[srow1 + 0] = q[0]; + J1[srow1 + 1] = q[1]; + J1[srow1 + 2] = q[2]; + J2[srow + 0] = -p[0]; + J2[srow + 1] = -p[1]; + J2[srow + 2] = -p[2]; + J2[srow1 + 0] = -q[0]; + J2[srow1 + 1] = -q[1]; + J2[srow1 + 2] = -q[2]; btScalar fact = info->fps * m_relaxationFactor; - info->m_constraintError[srow] = fact * m_swingAxis.dot(p); - info->m_constraintError[srow1] = fact * m_swingAxis.dot(q); + info->m_constraintError[srow] = fact * m_swingAxis.dot(p); + info->m_constraintError[srow1] = fact * m_swingAxis.dot(q); info->m_lowerLimit[srow] = -SIMD_INFINITY; info->m_upperLimit[srow] = SIMD_INFINITY; info->m_lowerLimit[srow1] = -SIMD_INFINITY; @@ -199,16 +184,16 @@ void btConeTwistConstraint::getInfo2NonVirtual (btConstraintInfo2* info,const bt else { ax1 = m_swingAxis * m_relaxationFactor * m_relaxationFactor; - J1[srow+0] = ax1[0]; - J1[srow+1] = ax1[1]; - J1[srow+2] = ax1[2]; - J2[srow+0] = -ax1[0]; - J2[srow+1] = -ax1[1]; - J2[srow+2] = -ax1[2]; + J1[srow + 0] = ax1[0]; + J1[srow + 1] = ax1[1]; + J1[srow + 2] = ax1[2]; + J2[srow + 0] = -ax1[0]; + J2[srow + 1] = -ax1[1]; + J2[srow + 2] = -ax1[2]; btScalar k = info->fps * m_biasFactor; info->m_constraintError[srow] = k * m_swingCorrection; - if(m_flags & BT_CONETWIST_FLAGS_ANG_CFM) + if (m_flags & BT_CONETWIST_FLAGS_ANG_CFM) { info->cfm[srow] = m_angCFM; } @@ -218,36 +203,35 @@ void btConeTwistConstraint::getInfo2NonVirtual (btConstraintInfo2* info,const bt srow += info->rowskip; } } - if(m_solveTwistLimit) + if (m_solveTwistLimit) { ax1 = m_twistAxis * m_relaxationFactor * m_relaxationFactor; - btScalar *J1 = info->m_J1angularAxis; - btScalar *J2 = info->m_J2angularAxis; - J1[srow+0] = ax1[0]; - J1[srow+1] = ax1[1]; - J1[srow+2] = ax1[2]; - J2[srow+0] = -ax1[0]; - J2[srow+1] = -ax1[1]; - J2[srow+2] = -ax1[2]; + btScalar* J1 = info->m_J1angularAxis; + btScalar* J2 = info->m_J2angularAxis; + J1[srow + 0] = ax1[0]; + J1[srow + 1] = ax1[1]; + J1[srow + 2] = ax1[2]; + J2[srow + 0] = -ax1[0]; + J2[srow + 1] = -ax1[1]; + J2[srow + 2] = -ax1[2]; btScalar k = info->fps * m_biasFactor; info->m_constraintError[srow] = k * m_twistCorrection; - if(m_flags & BT_CONETWIST_FLAGS_ANG_CFM) + if (m_flags & BT_CONETWIST_FLAGS_ANG_CFM) { info->cfm[srow] = m_angCFM; } - if(m_twistSpan > 0.0f) + if (m_twistSpan > 0.0f) { - - if(m_twistCorrection > 0.0f) + if (m_twistCorrection > 0.0f) { info->m_lowerLimit[srow] = 0; info->m_upperLimit[srow] = SIMD_INFINITY; - } + } else { info->m_lowerLimit[srow] = -SIMD_INFINITY; info->m_upperLimit[srow] = 0; - } + } } else { @@ -257,22 +241,20 @@ void btConeTwistConstraint::getInfo2NonVirtual (btConstraintInfo2* info,const bt srow += info->rowskip; } } - - -void btConeTwistConstraint::buildJacobian() +void btConeTwistConstraint::buildJacobian() { if (m_useSolveConstraintObsolete) { m_appliedImpulse = btScalar(0.); m_accTwistLimitImpulse = btScalar(0.); m_accSwingLimitImpulse = btScalar(0.); - m_accMotorImpulse = btVector3(0.,0.,0.); + m_accMotorImpulse = btVector3(0., 0., 0.); if (!m_angularOnly) { - btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); - btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); + btVector3 pivotAInW = m_rbA.getCenterOfMassTransform() * m_rbAFrame.getOrigin(); + btVector3 pivotBInW = m_rbB.getCenterOfMassTransform() * m_rbBFrame.getOrigin(); btVector3 relPos = pivotBInW - pivotAInW; btVector3 normal[3]; @@ -282,71 +264,68 @@ void btConeTwistConstraint::buildJacobian() } else { - normal[0].setValue(btScalar(1.0),0,0); + normal[0].setValue(btScalar(1.0), 0, 0); } btPlaneSpace1(normal[0], normal[1], normal[2]); - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) { new (&m_jac[i]) btJacobianEntry( - m_rbA.getCenterOfMassTransform().getBasis().transpose(), - m_rbB.getCenterOfMassTransform().getBasis().transpose(), - pivotAInW - m_rbA.getCenterOfMassPosition(), - pivotBInW - m_rbB.getCenterOfMassPosition(), - normal[i], - m_rbA.getInvInertiaDiagLocal(), - m_rbA.getInvMass(), - m_rbB.getInvInertiaDiagLocal(), - m_rbB.getInvMass()); + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + pivotAInW - m_rbA.getCenterOfMassPosition(), + pivotBInW - m_rbB.getCenterOfMassPosition(), + normal[i], + m_rbA.getInvInertiaDiagLocal(), + m_rbA.getInvMass(), + m_rbB.getInvInertiaDiagLocal(), + m_rbB.getInvMass()); } } - calcAngleInfo2(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform(),m_rbA.getInvInertiaTensorWorld(),m_rbB.getInvInertiaTensorWorld()); + calcAngleInfo2(m_rbA.getCenterOfMassTransform(), m_rbB.getCenterOfMassTransform(), m_rbA.getInvInertiaTensorWorld(), m_rbB.getInvInertiaTensorWorld()); } } - - -void btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep) +void btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA, btSolverBody& bodyB, btScalar timeStep) { - #ifndef __SPU__ +#ifndef __SPU__ if (m_useSolveConstraintObsolete) { - btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); - btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); + btVector3 pivotAInW = m_rbA.getCenterOfMassTransform() * m_rbAFrame.getOrigin(); + btVector3 pivotBInW = m_rbB.getCenterOfMassTransform() * m_rbBFrame.getOrigin(); btScalar tau = btScalar(0.3); //linear part if (!m_angularOnly) { - btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); + btVector3 rel_pos1 = pivotAInW - m_rbA.getCenterOfMassPosition(); btVector3 rel_pos2 = pivotBInW - m_rbB.getCenterOfMassPosition(); btVector3 vel1; - bodyA.internalGetVelocityInLocalPointObsolete(rel_pos1,vel1); + bodyA.internalGetVelocityInLocalPointObsolete(rel_pos1, vel1); btVector3 vel2; - bodyB.internalGetVelocityInLocalPointObsolete(rel_pos2,vel2); + bodyB.internalGetVelocityInLocalPointObsolete(rel_pos2, vel2); btVector3 vel = vel1 - vel2; - for (int i=0;i<3;i++) - { + for (int i = 0; i < 3; i++) + { const btVector3& normal = m_jac[i].m_linearJointAxis; btScalar jacDiagABInv = btScalar(1.) / m_jac[i].getDiagonal(); btScalar rel_vel; rel_vel = normal.dot(vel); //positional error (zeroth order error) - btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal - btScalar impulse = depth*tau/timeStep * jacDiagABInv - rel_vel * jacDiagABInv; + btScalar depth = -(pivotAInW - pivotBInW).dot(normal); //this is the error projected on the normal + btScalar impulse = depth * tau / timeStep * jacDiagABInv - rel_vel * jacDiagABInv; m_appliedImpulse += impulse; - + btVector3 ftorqueAxis1 = rel_pos1.cross(normal); btVector3 ftorqueAxis2 = rel_pos2.cross(normal); - bodyA.internalApplyImpulse(normal*m_rbA.getInvMass(), m_rbA.getInvInertiaTensorWorld()*ftorqueAxis1,impulse); - bodyB.internalApplyImpulse(normal*m_rbB.getInvMass(), m_rbB.getInvInertiaTensorWorld()*ftorqueAxis2,-impulse); - + bodyA.internalApplyImpulse(normal * m_rbA.getInvMass(), m_rbA.getInvInertiaTensorWorld() * ftorqueAxis1, impulse); + bodyB.internalApplyImpulse(normal * m_rbB.getInvMass(), m_rbB.getInvInertiaTensorWorld() * ftorqueAxis2, -impulse); } } @@ -356,13 +335,17 @@ void btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolver // compute current and predicted transforms btTransform trACur = m_rbA.getCenterOfMassTransform(); btTransform trBCur = m_rbB.getCenterOfMassTransform(); - btVector3 omegaA; bodyA.internalGetAngularVelocity(omegaA); - btVector3 omegaB; bodyB.internalGetAngularVelocity(omegaB); - btTransform trAPred; trAPred.setIdentity(); - btVector3 zerovec(0,0,0); + btVector3 omegaA; + bodyA.internalGetAngularVelocity(omegaA); + btVector3 omegaB; + bodyB.internalGetAngularVelocity(omegaB); + btTransform trAPred; + trAPred.setIdentity(); + btVector3 zerovec(0, 0, 0); btTransformUtil::integrateTransform( trACur, zerovec, omegaA, timeStep, trAPred); - btTransform trBPred; trBPred.setIdentity(); + btTransform trBPred; + trBPred.setIdentity(); btTransformUtil::integrateTransform( trBCur, zerovec, omegaB, timeStep, trBPred); @@ -374,7 +357,7 @@ void btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolver // compute desired omegas in world btVector3 omegaADes, omegaBDes; - + btTransformUtil::calculateVelocity(trACur, trADes, timeStep, zerovec, omegaADes); btTransformUtil::calculateVelocity(trBCur, trBDes, timeStep, zerovec, omegaBDes); @@ -415,10 +398,10 @@ void btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolver { btScalar fMaxImpulse = m_maxMotorImpulse; if (m_bNormalizedMotorStrength) - fMaxImpulse = fMaxImpulse/kAxisAInv; + fMaxImpulse = fMaxImpulse / kAxisAInv; btVector3 newUnclampedAccImpulse = m_accMotorImpulse + impulse; - btScalar newUnclampedMag = newUnclampedAccImpulse.length(); + btScalar newUnclampedMag = newUnclampedAccImpulse.length(); if (newUnclampedMag > fMaxImpulse) { newUnclampedAccImpulse.normalize(); @@ -428,31 +411,32 @@ void btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolver m_accMotorImpulse += impulse; } - btScalar impulseMag = impulse.length(); - btVector3 impulseAxis = impulse / impulseMag; - - bodyA.internalApplyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*impulseAxis, impulseMag); - bodyB.internalApplyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*impulseAxis, -impulseMag); + btScalar impulseMag = impulse.length(); + btVector3 impulseAxis = impulse / impulseMag; + bodyA.internalApplyImpulse(btVector3(0, 0, 0), m_rbA.getInvInertiaTensorWorld() * impulseAxis, impulseMag); + bodyB.internalApplyImpulse(btVector3(0, 0, 0), m_rbB.getInvInertiaTensorWorld() * impulseAxis, -impulseMag); } } - else if (m_damping > SIMD_EPSILON) // no motor: do a little damping + else if (m_damping > SIMD_EPSILON) // no motor: do a little damping { - btVector3 angVelA; bodyA.internalGetAngularVelocity(angVelA); - btVector3 angVelB; bodyB.internalGetAngularVelocity(angVelB); + btVector3 angVelA; + bodyA.internalGetAngularVelocity(angVelA); + btVector3 angVelB; + bodyB.internalGetAngularVelocity(angVelB); btVector3 relVel = angVelB - angVelA; if (relVel.length2() > SIMD_EPSILON) { btVector3 relVelAxis = relVel.normalized(); - btScalar m_kDamping = btScalar(1.) / - (getRigidBodyA().computeAngularImpulseDenominator(relVelAxis) + - getRigidBodyB().computeAngularImpulseDenominator(relVelAxis)); + btScalar m_kDamping = btScalar(1.) / + (getRigidBodyA().computeAngularImpulseDenominator(relVelAxis) + + getRigidBodyB().computeAngularImpulseDenominator(relVelAxis)); btVector3 impulse = m_damping * m_kDamping * relVel; - btScalar impulseMag = impulse.length(); + btScalar impulseMag = impulse.length(); btVector3 impulseAxis = impulse / impulseMag; - bodyA.internalApplyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*impulseAxis, impulseMag); - bodyB.internalApplyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*impulseAxis, -impulseMag); + bodyA.internalApplyImpulse(btVector3(0, 0, 0), m_rbA.getInvInertiaTensorWorld() * impulseAxis, impulseMag); + bodyB.internalApplyImpulse(btVector3(0, 0, 0), m_rbB.getInvInertiaTensorWorld() * impulseAxis, -impulseMag); } } @@ -467,7 +451,7 @@ void btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolver // solve swing limit if (m_solveSwingLimit) { - btScalar amplitude = m_swingLimitRatio * m_swingCorrection*m_biasFactor/timeStep; + btScalar amplitude = m_swingLimitRatio * m_swingCorrection * m_biasFactor / timeStep; btScalar relSwingVel = (angVelB - angVelA).dot(m_swingAxis); if (relSwingVel > 0) amplitude += m_swingLimitRatio * relSwingVel * m_relaxationFactor; @@ -475,7 +459,7 @@ void btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolver // Clamp the accumulated impulse btScalar temp = m_accSwingLimitImpulse; - m_accSwingLimitImpulse = btMax(m_accSwingLimitImpulse + impulseMag, btScalar(0.0) ); + m_accSwingLimitImpulse = btMax(m_accSwingLimitImpulse + impulseMag, btScalar(0.0)); impulseMag = m_accSwingLimitImpulse - temp; btVector3 impulse = m_swingAxis * impulseMag; @@ -491,47 +475,41 @@ void btConeTwistConstraint::solveConstraintObsolete(btSolverBody& bodyA,btSolver impulseMag = impulse.length(); btVector3 noTwistSwingAxis = impulse / impulseMag; - bodyA.internalApplyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*noTwistSwingAxis, impulseMag); - bodyB.internalApplyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*noTwistSwingAxis, -impulseMag); + bodyA.internalApplyImpulse(btVector3(0, 0, 0), m_rbA.getInvInertiaTensorWorld() * noTwistSwingAxis, impulseMag); + bodyB.internalApplyImpulse(btVector3(0, 0, 0), m_rbB.getInvInertiaTensorWorld() * noTwistSwingAxis, -impulseMag); } - // solve twist limit if (m_solveTwistLimit) { - btScalar amplitude = m_twistLimitRatio * m_twistCorrection*m_biasFactor/timeStep; - btScalar relTwistVel = (angVelB - angVelA).dot( m_twistAxis ); - if (relTwistVel > 0) // only damp when moving towards limit (m_twistAxis flipping is important) + btScalar amplitude = m_twistLimitRatio * m_twistCorrection * m_biasFactor / timeStep; + btScalar relTwistVel = (angVelB - angVelA).dot(m_twistAxis); + if (relTwistVel > 0) // only damp when moving towards limit (m_twistAxis flipping is important) amplitude += m_twistLimitRatio * relTwistVel * m_relaxationFactor; btScalar impulseMag = amplitude * m_kTwist; // Clamp the accumulated impulse btScalar temp = m_accTwistLimitImpulse; - m_accTwistLimitImpulse = btMax(m_accTwistLimitImpulse + impulseMag, btScalar(0.0) ); + m_accTwistLimitImpulse = btMax(m_accTwistLimitImpulse + impulseMag, btScalar(0.0)); impulseMag = m_accTwistLimitImpulse - temp; - // btVector3 impulse = m_twistAxis * impulseMag; + // btVector3 impulse = m_twistAxis * impulseMag; - bodyA.internalApplyImpulse(btVector3(0,0,0), m_rbA.getInvInertiaTensorWorld()*m_twistAxis,impulseMag); - bodyB.internalApplyImpulse(btVector3(0,0,0), m_rbB.getInvInertiaTensorWorld()*m_twistAxis,-impulseMag); - } + bodyA.internalApplyImpulse(btVector3(0, 0, 0), m_rbA.getInvInertiaTensorWorld() * m_twistAxis, impulseMag); + bodyB.internalApplyImpulse(btVector3(0, 0, 0), m_rbB.getInvInertiaTensorWorld() * m_twistAxis, -impulseMag); + } } } #else -btAssert(0); -#endif //__SPU__ + btAssert(0); +#endif //__SPU__ } - - - -void btConeTwistConstraint::updateRHS(btScalar timeStep) +void btConeTwistConstraint::updateRHS(btScalar timeStep) { (void)timeStep; - } - #ifndef __SPU__ void btConeTwistConstraint::calcAngleInfo() { @@ -540,15 +518,15 @@ void btConeTwistConstraint::calcAngleInfo() m_solveTwistLimit = false; m_solveSwingLimit = false; - btVector3 b1Axis1(0,0,0),b1Axis2(0,0,0),b1Axis3(0,0,0); - btVector3 b2Axis1(0,0,0),b2Axis2(0,0,0); + btVector3 b1Axis1(0, 0, 0), b1Axis2(0, 0, 0), b1Axis3(0, 0, 0); + btVector3 b2Axis1(0, 0, 0), b2Axis2(0, 0, 0); b1Axis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(0); b2Axis1 = getRigidBodyB().getCenterOfMassTransform().getBasis() * this->m_rbBFrame.getBasis().getColumn(0); - btScalar swing1=btScalar(0.),swing2 = btScalar(0.); + btScalar swing1 = btScalar(0.), swing2 = btScalar(0.); - btScalar swx=btScalar(0.),swy = btScalar(0.); + btScalar swx = btScalar(0.), swy = btScalar(0.); btScalar thresh = btScalar(10.); btScalar fact; @@ -558,33 +536,33 @@ void btConeTwistConstraint::calcAngleInfo() b1Axis2 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(1); swx = b2Axis1.dot(b1Axis1); swy = b2Axis1.dot(b1Axis2); - swing1 = btAtan2Fast(swy, swx); - fact = (swy*swy + swx*swx) * thresh * thresh; + swing1 = btAtan2Fast(swy, swx); + fact = (swy * swy + swx * swx) * thresh * thresh; fact = fact / (fact + btScalar(1.0)); - swing1 *= fact; + swing1 *= fact; } if (m_swingSpan2 >= btScalar(0.05f)) { - b1Axis3 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(2); + b1Axis3 = getRigidBodyA().getCenterOfMassTransform().getBasis() * this->m_rbAFrame.getBasis().getColumn(2); swx = b2Axis1.dot(b1Axis1); swy = b2Axis1.dot(b1Axis3); - swing2 = btAtan2Fast(swy, swx); - fact = (swy*swy + swx*swx) * thresh * thresh; + swing2 = btAtan2Fast(swy, swx); + fact = (swy * swy + swx * swx) * thresh * thresh; fact = fact / (fact + btScalar(1.0)); - swing2 *= fact; + swing2 *= fact; } - btScalar RMaxAngle1Sq = 1.0f / (m_swingSpan1*m_swingSpan1); - btScalar RMaxAngle2Sq = 1.0f / (m_swingSpan2*m_swingSpan2); - btScalar EllipseAngle = btFabs(swing1*swing1)* RMaxAngle1Sq + btFabs(swing2*swing2) * RMaxAngle2Sq; + btScalar RMaxAngle1Sq = 1.0f / (m_swingSpan1 * m_swingSpan1); + btScalar RMaxAngle2Sq = 1.0f / (m_swingSpan2 * m_swingSpan2); + btScalar EllipseAngle = btFabs(swing1 * swing1) * RMaxAngle1Sq + btFabs(swing2 * swing2) * RMaxAngle2Sq; if (EllipseAngle > 1.0f) { - m_swingCorrection = EllipseAngle-1.0f; + m_swingCorrection = EllipseAngle - 1.0f; m_solveSwingLimit = true; // Calculate necessary axis & factors - m_swingAxis = b2Axis1.cross(b1Axis2* b2Axis1.dot(b1Axis2) + b1Axis3* b2Axis1.dot(b1Axis3)); + m_swingAxis = b2Axis1.cross(b1Axis2 * b2Axis1.dot(b1Axis2) + b1Axis3 * b2Axis1.dot(b1Axis3)); m_swingAxis.normalize(); btScalar swingAxisSign = (b2Axis1.dot(b1Axis1) >= 0.0f) ? 1.0f : -1.0f; m_swingAxis *= swingAxisSign; @@ -594,14 +572,14 @@ void btConeTwistConstraint::calcAngleInfo() if (m_twistSpan >= btScalar(0.)) { btVector3 b2Axis2 = getRigidBodyB().getCenterOfMassTransform().getBasis() * this->m_rbBFrame.getBasis().getColumn(1); - btQuaternion rotationArc = shortestArcQuat(b2Axis1,b1Axis1); - btVector3 TwistRef = quatRotate(rotationArc,b2Axis2); - btScalar twist = btAtan2Fast( TwistRef.dot(b1Axis3), TwistRef.dot(b1Axis2) ); + btQuaternion rotationArc = shortestArcQuat(b2Axis1, b1Axis1); + btVector3 TwistRef = quatRotate(rotationArc, b2Axis2); + btScalar twist = btAtan2Fast(TwistRef.dot(b1Axis3), TwistRef.dot(b1Axis2)); m_twistAngle = twist; -// btScalar lockedFreeFactor = (m_twistSpan > btScalar(0.05f)) ? m_limitSoftness : btScalar(0.); + // btScalar lockedFreeFactor = (m_twistSpan > btScalar(0.05f)) ? m_limitSoftness : btScalar(0.); btScalar lockedFreeFactor = (m_twistSpan > btScalar(0.05f)) ? btScalar(1.0f) : btScalar(0.); - if (twist <= -m_twistSpan*lockedFreeFactor) + if (twist <= -m_twistSpan * lockedFreeFactor) { m_twistCorrection = -(twist + m_twistSpan); m_solveTwistLimit = true; @@ -609,7 +587,7 @@ void btConeTwistConstraint::calcAngleInfo() m_twistAxis.normalize(); m_twistAxis *= -1.0f; } - else if (twist > m_twistSpan*lockedFreeFactor) + else if (twist > m_twistSpan * lockedFreeFactor) { m_twistCorrection = (twist - m_twistSpan); m_solveTwistLimit = true; @@ -618,13 +596,11 @@ void btConeTwistConstraint::calcAngleInfo() } } } -#endif //__SPU__ +#endif //__SPU__ -static btVector3 vTwist(1,0,0); // twist axis in constraint's space +static btVector3 vTwist(1, 0, 0); // twist axis in constraint's space - - -void btConeTwistConstraint::calcAngleInfo2(const btTransform& transA, const btTransform& transB, const btMatrix3x3& invInertiaWorldA,const btMatrix3x3& invInertiaWorldB) +void btConeTwistConstraint::calcAngleInfo2(const btTransform& transA, const btTransform& transB, const btMatrix3x3& invInertiaWorldA, const btMatrix3x3& invInertiaWorldB) { m_swingCorrection = btScalar(0.); m_twistLimitSign = btScalar(0.); @@ -632,7 +608,7 @@ void btConeTwistConstraint::calcAngleInfo2(const btTransform& transA, const btTr m_solveSwingLimit = false; // compute rotation of A wrt B (in constraint space) if (m_bMotorEnabled && (!m_useSolveConstraintObsolete)) - { // it is assumed that setMotorTarget() was alredy called + { // it is assumed that setMotorTarget() was alredy called // and motor target m_qTarget is within constraint limits // TODO : split rotation to pure swing and pure twist // compute desired transforms in world @@ -641,23 +617,22 @@ void btConeTwistConstraint::calcAngleInfo2(const btTransform& transA, const btTr btTransform trB = transB * m_rbBFrame; btTransform trDeltaAB = trB * trPose * trA.inverse(); btQuaternion qDeltaAB = trDeltaAB.getRotation(); - btVector3 swingAxis = btVector3(qDeltaAB.x(), qDeltaAB.y(), qDeltaAB.z()); + btVector3 swingAxis = btVector3(qDeltaAB.x(), qDeltaAB.y(), qDeltaAB.z()); btScalar swingAxisLen2 = swingAxis.length2(); - if(btFuzzyZero(swingAxisLen2)) + if (btFuzzyZero(swingAxisLen2)) { - return; + return; } m_swingAxis = swingAxis; m_swingAxis.normalize(); m_swingCorrection = qDeltaAB.getAngle(); - if(!btFuzzyZero(m_swingCorrection)) + if (!btFuzzyZero(m_swingCorrection)) { m_solveSwingLimit = true; } return; } - { // compute rotation of A wrt B (in constraint space) btQuaternion qA = transA.getRotation() * m_rbAFrame.getRotation(); @@ -665,13 +640,17 @@ void btConeTwistConstraint::calcAngleInfo2(const btTransform& transA, const btTr btQuaternion qAB = qB.inverse() * qA; // split rotation into cone and twist // (all this is done from B's perspective. Maybe I should be averaging axes...) - btVector3 vConeNoTwist = quatRotate(qAB, vTwist); vConeNoTwist.normalize(); - btQuaternion qABCone = shortestArcQuat(vTwist, vConeNoTwist); qABCone.normalize(); - btQuaternion qABTwist = qABCone.inverse() * qAB; qABTwist.normalize(); + btVector3 vConeNoTwist = quatRotate(qAB, vTwist); + vConeNoTwist.normalize(); + btQuaternion qABCone = shortestArcQuat(vTwist, vConeNoTwist); + qABCone.normalize(); + btQuaternion qABTwist = qABCone.inverse() * qAB; + qABTwist.normalize(); if (m_swingSpan1 >= m_fixThresh && m_swingSpan2 >= m_fixThresh) { - btScalar swingAngle, swingLimit = 0; btVector3 swingAxis; + btScalar swingAngle, swingLimit = 0; + btVector3 swingAxis; computeConeLimitInfo(qABCone, swingAngle, swingAxis, swingLimit); if (swingAngle > swingLimit * m_limitSoftness) @@ -684,9 +663,9 @@ void btConeTwistConstraint::calcAngleInfo2(const btTransform& transA, const btTr m_swingLimitRatio = 1.f; if (swingAngle < swingLimit && m_limitSoftness < 1.f - SIMD_EPSILON) { - m_swingLimitRatio = (swingAngle - swingLimit * m_limitSoftness)/ + m_swingLimitRatio = (swingAngle - swingLimit * m_limitSoftness) / (swingLimit - swingLimit * m_limitSoftness); - } + } // swing correction tries to get back to soft limit m_swingCorrection = swingAngle - (swingLimit * m_limitSoftness); @@ -694,14 +673,14 @@ void btConeTwistConstraint::calcAngleInfo2(const btTransform& transA, const btTr // adjustment of swing axis (based on ellipse normal) adjustSwingAxisToUseEllipseNormal(swingAxis); - // Calculate necessary axis & factors + // Calculate necessary axis & factors m_swingAxis = quatRotate(qB, -swingAxis); - m_twistAxisA.setValue(0,0,0); + m_twistAxisA.setValue(0, 0, 0); - m_kSwing = btScalar(1.) / - (computeAngularImpulseDenominator(m_swingAxis,invInertiaWorldA) + - computeAngularImpulseDenominator(m_swingAxis,invInertiaWorldB)); + m_kSwing = btScalar(1.) / + (computeAngularImpulseDenominator(m_swingAxis, invInertiaWorldA) + + computeAngularImpulseDenominator(m_swingAxis, invInertiaWorldB)); } } else @@ -717,9 +696,9 @@ void btConeTwistConstraint::calcAngleInfo2(const btTransform& transA, const btTr btScalar x = ivB.dot(ivA); btScalar y = ivB.dot(jvA); btScalar z = ivB.dot(kvA); - if((m_swingSpan1 < m_fixThresh) && (m_swingSpan2 < m_fixThresh)) - { // fixed. We'll need to add one more row to constraint - if((!btFuzzyZero(y)) || (!(btFuzzyZero(z)))) + if ((m_swingSpan1 < m_fixThresh) && (m_swingSpan2 < m_fixThresh)) + { // fixed. We'll need to add one more row to constraint + if ((!btFuzzyZero(y)) || (!(btFuzzyZero(z)))) { m_solveSwingLimit = true; m_swingAxis = -ivB.cross(ivA); @@ -727,47 +706,47 @@ void btConeTwistConstraint::calcAngleInfo2(const btTransform& transA, const btTr } else { - if(m_swingSpan1 < m_fixThresh) - { // hinge around Y axis -// if(!(btFuzzyZero(y))) - if((!(btFuzzyZero(x))) || (!(btFuzzyZero(z)))) + if (m_swingSpan1 < m_fixThresh) + { // hinge around Y axis + // if(!(btFuzzyZero(y))) + if ((!(btFuzzyZero(x))) || (!(btFuzzyZero(z)))) { m_solveSwingLimit = true; - if(m_swingSpan2 >= m_fixThresh) + if (m_swingSpan2 >= m_fixThresh) { y = btScalar(0.f); btScalar span2 = btAtan2(z, x); - if(span2 > m_swingSpan2) + if (span2 > m_swingSpan2) { x = btCos(m_swingSpan2); z = btSin(m_swingSpan2); } - else if(span2 < -m_swingSpan2) + else if (span2 < -m_swingSpan2) { - x = btCos(m_swingSpan2); + x = btCos(m_swingSpan2); z = -btSin(m_swingSpan2); } } } } else - { // hinge around Z axis -// if(!btFuzzyZero(z)) - if((!(btFuzzyZero(x))) || (!(btFuzzyZero(y)))) + { // hinge around Z axis + // if(!btFuzzyZero(z)) + if ((!(btFuzzyZero(x))) || (!(btFuzzyZero(y)))) { m_solveSwingLimit = true; - if(m_swingSpan1 >= m_fixThresh) + if (m_swingSpan1 >= m_fixThresh) { z = btScalar(0.f); btScalar span1 = btAtan2(y, x); - if(span1 > m_swingSpan1) + if (span1 > m_swingSpan1) { x = btCos(m_swingSpan1); y = btSin(m_swingSpan1); } - else if(span1 < -m_swingSpan1) + else if (span1 < -m_swingSpan1) { - x = btCos(m_swingSpan1); + x = btCos(m_swingSpan1); y = -btSin(m_swingSpan1); } } @@ -778,10 +757,10 @@ void btConeTwistConstraint::calcAngleInfo2(const btTransform& transA, const btTr target[2] = x * ivA[2] + y * jvA[2] + z * kvA[2]; target.normalize(); m_swingAxis = -ivB.cross(target); - m_swingCorrection = m_swingAxis.length(); + m_swingCorrection = m_swingAxis.length(); - if (!btFuzzyZero(m_swingCorrection)) - m_swingAxis.normalize(); + if (!btFuzzyZero(m_swingCorrection)) + m_swingAxis.normalize(); } } @@ -790,15 +769,15 @@ void btConeTwistConstraint::calcAngleInfo2(const btTransform& transA, const btTr btVector3 twistAxis; computeTwistLimitInfo(qABTwist, m_twistAngle, twistAxis); - if (m_twistAngle > m_twistSpan*m_limitSoftness) + if (m_twistAngle > m_twistSpan * m_limitSoftness) { m_solveTwistLimit = true; m_twistLimitRatio = 1.f; if (m_twistAngle < m_twistSpan && m_limitSoftness < 1.f - SIMD_EPSILON) { - m_twistLimitRatio = (m_twistAngle - m_twistSpan * m_limitSoftness)/ - (m_twistSpan - m_twistSpan * m_limitSoftness); + m_twistLimitRatio = (m_twistAngle - m_twistSpan * m_limitSoftness) / + (m_twistSpan - m_twistSpan * m_limitSoftness); } // twist correction tries to get back to soft limit @@ -807,8 +786,8 @@ void btConeTwistConstraint::calcAngleInfo2(const btTransform& transA, const btTr m_twistAxis = quatRotate(qB, -twistAxis); m_kTwist = btScalar(1.) / - (computeAngularImpulseDenominator(m_twistAxis,invInertiaWorldA) + - computeAngularImpulseDenominator(m_twistAxis,invInertiaWorldB)); + (computeAngularImpulseDenominator(m_twistAxis, invInertiaWorldA) + + computeAngularImpulseDenominator(m_twistAxis, invInertiaWorldB)); } if (m_solveSwingLimit) @@ -821,15 +800,13 @@ void btConeTwistConstraint::calcAngleInfo2(const btTransform& transA, const btTr } } - - // given a cone rotation in constraint space, (pre: twist must already be removed) // this method computes its corresponding swing angle and axis. // more interestingly, it computes the cone/swing limit (angle) for this cone "pose". void btConeTwistConstraint::computeConeLimitInfo(const btQuaternion& qCone, - btScalar& swingAngle, // out - btVector3& vSwingAxis, // out - btScalar& swingLimit) // out + btScalar& swingAngle, // out + btVector3& vSwingAxis, // out + btScalar& swingLimit) // out { swingAngle = qCone.getAngle(); if (swingAngle > SIMD_EPSILON) @@ -840,7 +817,7 @@ void btConeTwistConstraint::computeConeLimitInfo(const btQuaternion& qCone, // non-zero twist?! this should never happen. btAssert(fabs(vSwingAxis.x()) <= SIMD_EPSILON)); #endif - + // Compute limit for given swing. tricky: // Given a swing axis, we're looking for the intersection with the bounding cone ellipse. // (Since we're dealing with angles, this ellipse is embedded on the surface of a sphere.) @@ -848,7 +825,7 @@ void btConeTwistConstraint::computeConeLimitInfo(const btQuaternion& qCone, // For starters, compute the direction from center to surface of ellipse. // This is just the perpendicular (ie. rotate 2D vector by PI/2) of the swing axis. // (vSwingAxis is the cone rotation (in z,y); change vars and rotate to (x,y) coords.) - btScalar xEllipse = vSwingAxis.y(); + btScalar xEllipse = vSwingAxis.y(); btScalar yEllipse = -vSwingAxis.z(); // Now, we use the slope of the vector (using x/yEllipse) and find the length @@ -858,10 +835,10 @@ void btConeTwistConstraint::computeConeLimitInfo(const btQuaternion& qCone, // a^2 b^2 // Do the math and it should be clear. - swingLimit = m_swingSpan1; // if xEllipse == 0, we have a pure vSwingAxis.z rotation: just use swingspan1 + swingLimit = m_swingSpan1; // if xEllipse == 0, we have a pure vSwingAxis.z rotation: just use swingspan1 if (fabs(xEllipse) > SIMD_EPSILON) { - btScalar surfaceSlope2 = (yEllipse*yEllipse)/(xEllipse*xEllipse); + btScalar surfaceSlope2 = (yEllipse * yEllipse) / (xEllipse * xEllipse); btScalar norm = 1 / (m_swingSpan2 * m_swingSpan2); norm += surfaceSlope2 / (m_swingSpan1 * m_swingSpan1); btScalar swingLimit2 = (1 + surfaceSlope2) / norm; @@ -887,7 +864,7 @@ void btConeTwistConstraint::computeConeLimitInfo(const btQuaternion& qCone, #if 0 btAssert(0); #endif - } + } } btVector3 btConeTwistConstraint::GetPointForAngle(btScalar fAngleInRadians, btScalar fLength) const @@ -903,10 +880,10 @@ btVector3 btConeTwistConstraint::GetPointForAngle(btScalar fAngleInRadians, btSc // a^2 b^2 // Do the math and it should be clear. - btScalar swingLimit = m_swingSpan1; // if xEllipse == 0, just use axis b (1) + btScalar swingLimit = m_swingSpan1; // if xEllipse == 0, just use axis b (1) if (fabs(xEllipse) > SIMD_EPSILON) { - btScalar surfaceSlope2 = (yEllipse*yEllipse)/(xEllipse*xEllipse); + btScalar surfaceSlope2 = (yEllipse * yEllipse) / (xEllipse * xEllipse); btScalar norm = 1 / (m_swingSpan2 * m_swingSpan2); norm += surfaceSlope2 / (m_swingSpan1 * m_swingSpan1); btScalar swingLimit2 = (1 + surfaceSlope2) / norm; @@ -917,20 +894,20 @@ btVector3 btConeTwistConstraint::GetPointForAngle(btScalar fAngleInRadians, btSc // note: twist is x-axis, swing 1 and 2 are along the z and y axes respectively btVector3 vSwingAxis(0, xEllipse, -yEllipse); btQuaternion qSwing(vSwingAxis, swingLimit); - btVector3 vPointInConstraintSpace(fLength,0,0); + btVector3 vPointInConstraintSpace(fLength, 0, 0); return quatRotate(qSwing, vPointInConstraintSpace); } // given a twist rotation in constraint space, (pre: cone must already be removed) // this method computes its corresponding angle and axis. void btConeTwistConstraint::computeTwistLimitInfo(const btQuaternion& qTwist, - btScalar& twistAngle, // out - btVector3& vTwistAxis) // out + btScalar& twistAngle, // out + btVector3& vTwistAxis) // out { btQuaternion qMinTwist = qTwist; twistAngle = qTwist.getAngle(); - if (twistAngle > SIMD_PI) // long way around. flip quat and recalculate. + if (twistAngle > SIMD_PI) // long way around. flip quat and recalculate. { qMinTwist = -(qTwist); twistAngle = qMinTwist.getAngle(); @@ -948,80 +925,79 @@ void btConeTwistConstraint::computeTwistLimitInfo(const btQuaternion& qTwist, vTwistAxis.normalize(); } - void btConeTwistConstraint::adjustSwingAxisToUseEllipseNormal(btVector3& vSwingAxis) const { // the swing axis is computed as the "twist-free" cone rotation, // but the cone limit is not circular, but elliptical (if swingspan1 != swingspan2). - // so, if we're outside the limits, the closest way back inside the cone isn't + // so, if we're outside the limits, the closest way back inside the cone isn't // along the vector back to the center. better (and more stable) to use the ellipse normal. // convert swing axis to direction from center to surface of ellipse // (ie. rotate 2D vector by PI/2) btScalar y = -vSwingAxis.z(); - btScalar z = vSwingAxis.y(); + btScalar z = vSwingAxis.y(); // do the math... - if (fabs(z) > SIMD_EPSILON) // avoid division by 0. and we don't need an update if z == 0. + if (fabs(z) > SIMD_EPSILON) // avoid division by 0. and we don't need an update if z == 0. { // compute gradient/normal of ellipse surface at current "point" - btScalar grad = y/z; + btScalar grad = y / z; grad *= m_swingSpan2 / m_swingSpan1; // adjust y/z to represent normal at point (instead of vector to point) if (y > 0) - y = fabs(grad * z); + y = fabs(grad * z); else y = -fabs(grad * z); // convert ellipse direction back to swing axis vSwingAxis.setZ(-y); - vSwingAxis.setY( z); + vSwingAxis.setY(z); vSwingAxis.normalize(); } } - - -void btConeTwistConstraint::setMotorTarget(const btQuaternion &q) +void btConeTwistConstraint::setMotorTarget(const btQuaternion& q) { //btTransform trACur = m_rbA.getCenterOfMassTransform(); //btTransform trBCur = m_rbB.getCenterOfMassTransform(); -// btTransform trABCur = trBCur.inverse() * trACur; -// btQuaternion qABCur = trABCur.getRotation(); -// btTransform trConstraintCur = (trBCur * m_rbBFrame).inverse() * (trACur * m_rbAFrame); + // btTransform trABCur = trBCur.inverse() * trACur; + // btQuaternion qABCur = trABCur.getRotation(); + // btTransform trConstraintCur = (trBCur * m_rbBFrame).inverse() * (trACur * m_rbAFrame); //btQuaternion qConstraintCur = trConstraintCur.getRotation(); btQuaternion qConstraint = m_rbBFrame.getRotation().inverse() * q * m_rbAFrame.getRotation(); setMotorTargetInConstraintSpace(qConstraint); } - -void btConeTwistConstraint::setMotorTargetInConstraintSpace(const btQuaternion &q) +void btConeTwistConstraint::setMotorTargetInConstraintSpace(const btQuaternion& q) { m_qTarget = q; // clamp motor target to within limits { - btScalar softness = 1.f;//m_limitSoftness; + btScalar softness = 1.f; //m_limitSoftness; // split into twist and cone btVector3 vTwisted = quatRotate(m_qTarget, vTwist); - btQuaternion qTargetCone = shortestArcQuat(vTwist, vTwisted); qTargetCone.normalize(); - btQuaternion qTargetTwist = qTargetCone.inverse() * m_qTarget; qTargetTwist.normalize(); + btQuaternion qTargetCone = shortestArcQuat(vTwist, vTwisted); + qTargetCone.normalize(); + btQuaternion qTargetTwist = qTargetCone.inverse() * m_qTarget; + qTargetTwist.normalize(); // clamp cone if (m_swingSpan1 >= btScalar(0.05f) && m_swingSpan2 >= btScalar(0.05f)) { - btScalar swingAngle, swingLimit; btVector3 swingAxis; + btScalar swingAngle, swingLimit; + btVector3 swingAxis; computeConeLimitInfo(qTargetCone, swingAngle, swingAxis, swingLimit); if (fabs(swingAngle) > SIMD_EPSILON) { - if (swingAngle > swingLimit*softness) - swingAngle = swingLimit*softness; - else if (swingAngle < -swingLimit*softness) - swingAngle = -swingLimit*softness; + if (swingAngle > swingLimit * softness) + swingAngle = swingLimit * softness; + else if (swingAngle < -swingLimit * softness) + swingAngle = -swingLimit * softness; qTargetCone = btQuaternion(swingAxis, swingAngle); } } @@ -1029,16 +1005,17 @@ void btConeTwistConstraint::setMotorTargetInConstraintSpace(const btQuaternion & // clamp twist if (m_twistSpan >= btScalar(0.05f)) { - btScalar twistAngle; btVector3 twistAxis; + btScalar twistAngle; + btVector3 twistAxis; computeTwistLimitInfo(qTargetTwist, twistAngle, twistAxis); if (fabs(twistAngle) > SIMD_EPSILON) { // eddy todo: limitSoftness used here??? - if (twistAngle > m_twistSpan*softness) - twistAngle = m_twistSpan*softness; - else if (twistAngle < -m_twistSpan*softness) - twistAngle = -m_twistSpan*softness; + if (twistAngle > m_twistSpan * softness) + twistAngle = m_twistSpan * softness; + else if (twistAngle < -m_twistSpan * softness) + twistAngle = -m_twistSpan * softness; qTargetTwist = btQuaternion(twistAxis, twistAngle); } } @@ -1047,15 +1024,15 @@ void btConeTwistConstraint::setMotorTargetInConstraintSpace(const btQuaternion & } } -///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). +///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). ///If no axis is provided, it uses the default axis for this constraint. void btConeTwistConstraint::setParam(int num, btScalar value, int axis) { - switch(num) + switch (num) { - case BT_CONSTRAINT_ERP : - case BT_CONSTRAINT_STOP_ERP : - if((axis >= 0) && (axis < 3)) + case BT_CONSTRAINT_ERP: + case BT_CONSTRAINT_STOP_ERP: + if ((axis >= 0) && (axis < 3)) { m_linERP = value; m_flags |= BT_CONETWIST_FLAGS_LIN_ERP; @@ -1065,9 +1042,9 @@ void btConeTwistConstraint::setParam(int num, btScalar value, int axis) m_biasFactor = value; } break; - case BT_CONSTRAINT_CFM : - case BT_CONSTRAINT_STOP_CFM : - if((axis >= 0) && (axis < 3)) + case BT_CONSTRAINT_CFM: + case BT_CONSTRAINT_STOP_CFM: + if ((axis >= 0) && (axis < 3)) { m_linCFM = value; m_flags |= BT_CONETWIST_FLAGS_LIN_CFM; @@ -1085,19 +1062,19 @@ void btConeTwistConstraint::setParam(int num, btScalar value, int axis) } ///return the local value of parameter -btScalar btConeTwistConstraint::getParam(int num, int axis) const +btScalar btConeTwistConstraint::getParam(int num, int axis) const { btScalar retVal = 0; - switch(num) + switch (num) { - case BT_CONSTRAINT_ERP : - case BT_CONSTRAINT_STOP_ERP : - if((axis >= 0) && (axis < 3)) + case BT_CONSTRAINT_ERP: + case BT_CONSTRAINT_STOP_ERP: + if ((axis >= 0) && (axis < 3)) { btAssertConstrParams(m_flags & BT_CONETWIST_FLAGS_LIN_ERP); retVal = m_linERP; } - else if((axis >= 3) && (axis < 6)) + else if ((axis >= 3) && (axis < 6)) { retVal = m_biasFactor; } @@ -1106,14 +1083,14 @@ btScalar btConeTwistConstraint::getParam(int num, int axis) const btAssertConstrParams(0); } break; - case BT_CONSTRAINT_CFM : - case BT_CONSTRAINT_STOP_CFM : - if((axis >= 0) && (axis < 3)) + case BT_CONSTRAINT_CFM: + case BT_CONSTRAINT_STOP_CFM: + if ((axis >= 0) && (axis < 3)) { btAssertConstrParams(m_flags & BT_CONETWIST_FLAGS_LIN_CFM); retVal = m_linCFM; } - else if((axis >= 3) && (axis < 6)) + else if ((axis >= 3) && (axis < 6)) { btAssertConstrParams(m_flags & BT_CONETWIST_FLAGS_ANG_CFM); retVal = m_angCFM; @@ -1123,21 +1100,16 @@ btScalar btConeTwistConstraint::getParam(int num, int axis) const btAssertConstrParams(0); } break; - default : + default: btAssertConstrParams(0); } return retVal; } - -void btConeTwistConstraint::setFrames(const btTransform & frameA, const btTransform & frameB) +void btConeTwistConstraint::setFrames(const btTransform& frameA, const btTransform& frameB) { m_rbAFrame = frameA; m_rbBFrame = frameB; buildJacobian(); //calculateTransforms(); } - - - - diff --git a/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h b/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h index 7a33d01d1..64f44df1c 100644 --- a/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h +++ b/src/BulletDynamics/ConstraintSolver/btConeTwistConstraint.h @@ -15,8 +15,6 @@ subject to the following restrictions: Written by: Marcus Hennix */ - - /* Overview: @@ -31,8 +29,6 @@ twist is along the x-axis, and swing 1 and 2 are along the z and y axes respectively. */ - - #ifndef BT_CONETWISTCONSTRAINT_H #define BT_CONETWISTCONSTRAINT_H @@ -41,13 +37,12 @@ and swing 1 and 2 are along the z and y axes respectively. #include "btTypedConstraint.h" #ifdef BT_USE_DOUBLE_PRECISION -#define btConeTwistConstraintData2 btConeTwistConstraintDoubleData -#define btConeTwistConstraintDataName "btConeTwistConstraintDoubleData" +#define btConeTwistConstraintData2 btConeTwistConstraintDoubleData +#define btConeTwistConstraintDataName "btConeTwistConstraintDoubleData" #else -#define btConeTwistConstraintData2 btConeTwistConstraintData -#define btConeTwistConstraintDataName "btConeTwistConstraintData" -#endif //BT_USE_DOUBLE_PRECISION - +#define btConeTwistConstraintData2 btConeTwistConstraintData +#define btConeTwistConstraintDataName "btConeTwistConstraintData" +#endif //BT_USE_DOUBLE_PRECISION class btRigidBody; @@ -59,103 +54,99 @@ enum btConeTwistFlags }; ///btConeTwistConstraint can be used to simulate ragdoll joints (upper arm, leg etc) -ATTRIBUTE_ALIGNED16(class) btConeTwistConstraint : public btTypedConstraint +ATTRIBUTE_ALIGNED16(class) +btConeTwistConstraint : public btTypedConstraint { #ifdef IN_PARALLELL_SOLVER public: #endif - btJacobianEntry m_jac[3]; //3 orthogonal linear constraints + btJacobianEntry m_jac[3]; //3 orthogonal linear constraints - btTransform m_rbAFrame; + btTransform m_rbAFrame; btTransform m_rbBFrame; - btScalar m_limitSoftness; - btScalar m_biasFactor; - btScalar m_relaxationFactor; + btScalar m_limitSoftness; + btScalar m_biasFactor; + btScalar m_relaxationFactor; - btScalar m_damping; + btScalar m_damping; - btScalar m_swingSpan1; - btScalar m_swingSpan2; - btScalar m_twistSpan; + btScalar m_swingSpan1; + btScalar m_swingSpan2; + btScalar m_twistSpan; - btScalar m_fixThresh; + btScalar m_fixThresh; - btVector3 m_swingAxis; - btVector3 m_twistAxis; + btVector3 m_swingAxis; + btVector3 m_twistAxis; - btScalar m_kSwing; - btScalar m_kTwist; + btScalar m_kSwing; + btScalar m_kTwist; - btScalar m_twistLimitSign; - btScalar m_swingCorrection; - btScalar m_twistCorrection; + btScalar m_twistLimitSign; + btScalar m_swingCorrection; + btScalar m_twistCorrection; - btScalar m_twistAngle; + btScalar m_twistAngle; - btScalar m_accSwingLimitImpulse; - btScalar m_accTwistLimitImpulse; + btScalar m_accSwingLimitImpulse; + btScalar m_accTwistLimitImpulse; - bool m_angularOnly; - bool m_solveTwistLimit; - bool m_solveSwingLimit; + bool m_angularOnly; + bool m_solveTwistLimit; + bool m_solveSwingLimit; - bool m_useSolveConstraintObsolete; + bool m_useSolveConstraintObsolete; // not yet used... - btScalar m_swingLimitRatio; - btScalar m_twistLimitRatio; - btVector3 m_twistAxisA; + btScalar m_swingLimitRatio; + btScalar m_twistLimitRatio; + btVector3 m_twistAxisA; // motor - bool m_bMotorEnabled; - bool m_bNormalizedMotorStrength; + bool m_bMotorEnabled; + bool m_bNormalizedMotorStrength; btQuaternion m_qTarget; - btScalar m_maxMotorImpulse; - btVector3 m_accMotorImpulse; - - // parameters - int m_flags; - btScalar m_linCFM; - btScalar m_linERP; - btScalar m_angCFM; - -protected: + btScalar m_maxMotorImpulse; + btVector3 m_accMotorImpulse; + // parameters + int m_flags; + btScalar m_linCFM; + btScalar m_linERP; + btScalar m_angCFM; + +protected: void init(); - void computeConeLimitInfo(const btQuaternion& qCone, // in - btScalar& swingAngle, btVector3& vSwingAxis, btScalar& swingLimit); // all outs + void computeConeLimitInfo(const btQuaternion& qCone, // in + btScalar& swingAngle, btVector3& vSwingAxis, btScalar& swingLimit); // all outs - void computeTwistLimitInfo(const btQuaternion& qTwist, // in - btScalar& twistAngle, btVector3& vTwistAxis); // all outs - - void adjustSwingAxisToUseEllipseNormal(btVector3& vSwingAxis) const; + void computeTwistLimitInfo(const btQuaternion& qTwist, // in + btScalar& twistAngle, btVector3& vTwistAxis); // all outs + void adjustSwingAxisToUseEllipseNormal(btVector3 & vSwingAxis) const; public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - btConeTwistConstraint(btRigidBody& rbA,btRigidBody& rbB,const btTransform& rbAFrame, const btTransform& rbBFrame); - - btConeTwistConstraint(btRigidBody& rbA,const btTransform& rbAFrame); + btConeTwistConstraint(btRigidBody & rbA, btRigidBody & rbB, const btTransform& rbAFrame, const btTransform& rbBFrame); - virtual void buildJacobian(); + btConeTwistConstraint(btRigidBody & rbA, const btTransform& rbAFrame); - virtual void getInfo1 (btConstraintInfo1* info); + virtual void buildJacobian(); - void getInfo1NonVirtual(btConstraintInfo1* info); - - virtual void getInfo2 (btConstraintInfo2* info); - - void getInfo2NonVirtual(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btMatrix3x3& invInertiaWorldA,const btMatrix3x3& invInertiaWorldB); + virtual void getInfo1(btConstraintInfo1 * info); - virtual void solveConstraintObsolete(btSolverBody& bodyA,btSolverBody& bodyB,btScalar timeStep); + void getInfo1NonVirtual(btConstraintInfo1 * info); - - void updateRHS(btScalar timeStep); + virtual void getInfo2(btConstraintInfo2 * info); + void getInfo2NonVirtual(btConstraintInfo2 * info, const btTransform& transA, const btTransform& transB, const btMatrix3x3& invInertiaWorldA, const btMatrix3x3& invInertiaWorldB); + + virtual void solveConstraintObsolete(btSolverBody & bodyA, btSolverBody & bodyB, btScalar timeStep); + + void updateRHS(btScalar timeStep); const btRigidBody& getRigidBodyA() const { @@ -166,64 +157,64 @@ public: return m_rbB; } - void setAngularOnly(bool angularOnly) + void setAngularOnly(bool angularOnly) { m_angularOnly = angularOnly; } - - bool getAngularOnly() const + + bool getAngularOnly() const { - return m_angularOnly; + return m_angularOnly; } - void setLimit(int limitIndex,btScalar limitValue) + void setLimit(int limitIndex, btScalar limitValue) { switch (limitIndex) { - case 3: + case 3: { m_twistSpan = limitValue; break; } - case 4: + case 4: { m_swingSpan2 = limitValue; break; } - case 5: + case 5: { m_swingSpan1 = limitValue; break; } - default: + default: { } }; } - btScalar getLimit(int limitIndex) const + btScalar getLimit(int limitIndex) const { switch (limitIndex) { - case 3: + case 3: { return m_twistSpan; break; } - case 4: + case 4: { return m_swingSpan2; break; } - case 5: + case 5: { return m_swingSpan1; break; } - default: + default: { - btAssert(0 && "Invalid limitIndex specified for btConeTwistConstraint"); - return 0.0; + btAssert(0 && "Invalid limitIndex specified for btConeTwistConstraint"); + return 0.0; } }; } @@ -239,18 +230,18 @@ public: // __relaxationFactor: // 0->1, recommend to stay near 1. // the lower the value, the less the constraint will fight velocities which violate the angular limits. - void setLimit(btScalar _swingSpan1,btScalar _swingSpan2,btScalar _twistSpan, btScalar _softness = 1.f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f) + void setLimit(btScalar _swingSpan1, btScalar _swingSpan2, btScalar _twistSpan, btScalar _softness = 1.f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f) { m_swingSpan1 = _swingSpan1; m_swingSpan2 = _swingSpan2; - m_twistSpan = _twistSpan; + m_twistSpan = _twistSpan; - m_limitSoftness = _softness; + m_limitSoftness = _softness; m_biasFactor = _biasFactor; m_relaxationFactor = _relaxationFactor; } - const btTransform& getAFrame() const { return m_rbAFrame; }; + const btTransform& getAFrame() const { return m_rbAFrame; }; const btTransform& getBFrame() const { return m_rbBFrame; }; inline int getSolveTwistLimit() @@ -269,7 +260,7 @@ public: } void calcAngleInfo(); - void calcAngleInfo2(const btTransform& transA, const btTransform& transB,const btMatrix3x3& invInertiaWorldA,const btMatrix3x3& invInertiaWorldB); + void calcAngleInfo2(const btTransform& transA, const btTransform& transB, const btMatrix3x3& invInertiaWorldA, const btMatrix3x3& invInertiaWorldB); inline btScalar getSwingSpan1() const { @@ -308,8 +299,16 @@ public: bool isMotorEnabled() const { return m_bMotorEnabled; } btScalar getMaxMotorImpulse() const { return m_maxMotorImpulse; } bool isMaxMotorImpulseNormalized() const { return m_bNormalizedMotorStrength; } - void setMaxMotorImpulse(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; m_bNormalizedMotorStrength = false; } - void setMaxMotorImpulseNormalized(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; m_bNormalizedMotorStrength = true; } + void setMaxMotorImpulse(btScalar maxMotorImpulse) + { + m_maxMotorImpulse = maxMotorImpulse; + m_bNormalizedMotorStrength = false; + } + void setMaxMotorImpulseNormalized(btScalar maxMotorImpulse) + { + m_maxMotorImpulse = maxMotorImpulse; + m_bNormalizedMotorStrength = true; + } btScalar getFixThresh() { return m_fixThresh; } void setFixThresh(btScalar fixThresh) { m_fixThresh = fixThresh; } @@ -318,17 +317,17 @@ public: // q: the desired rotation of bodyA wrt bodyB. // note: if q violates the joint limits, the internal target is clamped to avoid conflicting impulses (very bad for stability) // note: don't forget to enableMotor() - void setMotorTarget(const btQuaternion &q); + void setMotorTarget(const btQuaternion& q); const btQuaternion& getMotorTarget() const { return m_qTarget; } // same as above, but q is the desired rotation of frameA wrt frameB in constraint space - void setMotorTargetInConstraintSpace(const btQuaternion &q); + void setMotorTargetInConstraintSpace(const btQuaternion& q); btVector3 GetPointForAngle(btScalar fAngleInRadians, btScalar fLength) const; - ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). + ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). ///If no axis is provided, it uses the default axis for this constraint. - virtual void setParam(int num, btScalar value, int axis = -1); + virtual void setParam(int num, btScalar value, int axis = -1); virtual void setFrames(const btTransform& frameA, const btTransform& frameB); @@ -342,84 +341,74 @@ public: return m_rbBFrame; } - ///return the local value of parameter - virtual btScalar getParam(int num, int axis = -1) const; + virtual btScalar getParam(int num, int axis = -1) const; int getFlags() const { return m_flags; } - virtual int calculateSerializeBufferSize() const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; - + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; }; - - -struct btConeTwistConstraintDoubleData +struct btConeTwistConstraintDoubleData { - btTypedConstraintDoubleData m_typeConstraintData; + btTypedConstraintDoubleData m_typeConstraintData; btTransformDoubleData m_rbAFrame; btTransformDoubleData m_rbBFrame; //limits - double m_swingSpan1; - double m_swingSpan2; - double m_twistSpan; - double m_limitSoftness; - double m_biasFactor; - double m_relaxationFactor; - - double m_damping; - - + double m_swingSpan1; + double m_swingSpan2; + double m_twistSpan; + double m_limitSoftness; + double m_biasFactor; + double m_relaxationFactor; + double m_damping; }; #ifdef BT_BACKWARDS_COMPATIBLE_SERIALIZATION ///this structure is not used, except for loading pre-2.82 .bullet files -struct btConeTwistConstraintData +struct btConeTwistConstraintData { - btTypedConstraintData m_typeConstraintData; + btTypedConstraintData m_typeConstraintData; btTransformFloatData m_rbAFrame; btTransformFloatData m_rbBFrame; //limits - float m_swingSpan1; - float m_swingSpan2; - float m_twistSpan; - float m_limitSoftness; - float m_biasFactor; - float m_relaxationFactor; + float m_swingSpan1; + float m_swingSpan2; + float m_twistSpan; + float m_limitSoftness; + float m_biasFactor; + float m_relaxationFactor; + + float m_damping; - float m_damping; - char m_pad[4]; - }; -#endif //BT_BACKWARDS_COMPATIBLE_SERIALIZATION +#endif //BT_BACKWARDS_COMPATIBLE_SERIALIZATION // -SIMD_FORCE_INLINE int btConeTwistConstraint::calculateSerializeBufferSize() const +SIMD_FORCE_INLINE int btConeTwistConstraint::calculateSerializeBufferSize() const { return sizeof(btConeTwistConstraintData2); - } - - ///fills the dataBuffer and returns the struct name (and 0 on failure) -SIMD_FORCE_INLINE const char* btConeTwistConstraint::serialize(void* dataBuffer, btSerializer* serializer) const +///fills the dataBuffer and returns the struct name (and 0 on failure) +SIMD_FORCE_INLINE const char* btConeTwistConstraint::serialize(void* dataBuffer, btSerializer* serializer) const { - btConeTwistConstraintData2* cone = (btConeTwistConstraintData2*) dataBuffer; - btTypedConstraint::serialize(&cone->m_typeConstraintData,serializer); + btConeTwistConstraintData2* cone = (btConeTwistConstraintData2*)dataBuffer; + btTypedConstraint::serialize(&cone->m_typeConstraintData, serializer); m_rbAFrame.serialize(cone->m_rbAFrame); m_rbBFrame.serialize(cone->m_rbBFrame); - + cone->m_swingSpan1 = m_swingSpan1; cone->m_swingSpan2 = m_swingSpan2; cone->m_twistSpan = m_twistSpan; @@ -431,5 +420,4 @@ SIMD_FORCE_INLINE const char* btConeTwistConstraint::serialize(void* dataBuffer, return btConeTwistConstraintDataName; } - -#endif //BT_CONETWISTCONSTRAINT_H +#endif //BT_CONETWISTCONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h b/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h index 0491639f7..808433477 100644 --- a/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h +++ b/src/BulletDynamics/ConstraintSolver/btConstraintSolver.h @@ -26,41 +26,33 @@ struct btContactSolverInfo; struct btBroadphaseProxy; class btIDebugDraw; class btStackAlloc; -class btDispatcher; +class btDispatcher; /// btConstraintSolver provides solver interface - enum btConstraintSolverType { - BT_SEQUENTIAL_IMPULSE_SOLVER=1, - BT_MLCP_SOLVER=2, - BT_NNCG_SOLVER=4, - BT_MULTIBODY_SOLVER=8, + BT_SEQUENTIAL_IMPULSE_SOLVER = 1, + BT_MLCP_SOLVER = 2, + BT_NNCG_SOLVER = 4, + BT_MULTIBODY_SOLVER = 8, }; class btConstraintSolver { - public: - virtual ~btConstraintSolver() {} - - virtual void prepareSolve (int /* numBodies */, int /* numManifolds */) {;} + + virtual void prepareSolve(int /* numBodies */, int /* numManifolds */) { ; } ///solve a group of constraints - virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints, const btContactSolverInfo& info,class btIDebugDraw* debugDrawer,btDispatcher* dispatcher) = 0; + virtual btScalar solveGroup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifold, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& info, class btIDebugDraw* debugDrawer, btDispatcher* dispatcher) = 0; - virtual void allSolved (const btContactSolverInfo& /* info */,class btIDebugDraw* /* debugDrawer */) {;} + virtual void allSolved(const btContactSolverInfo& /* info */, class btIDebugDraw* /* debugDrawer */) { ; } ///clear internal cached data and reset random seed - virtual void reset() = 0; - - virtual btConstraintSolverType getSolverType() const=0; - + virtual void reset() = 0; + virtual btConstraintSolverType getSolverType() const = 0; }; - - - -#endif //BT_CONSTRAINT_SOLVER_H +#endif //BT_CONSTRAINT_SOLVER_H diff --git a/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp index 1098d0c96..4b22b2fff 100644 --- a/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp +++ b/src/BulletDynamics/ConstraintSolver/btContactConstraint.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btContactConstraint.h" #include "BulletDynamics/Dynamics/btRigidBody.h" #include "LinearMath/btVector3.h" @@ -22,44 +21,33 @@ subject to the following restrictions: #include "LinearMath/btMinMax.h" #include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h" - - -btContactConstraint::btContactConstraint(btPersistentManifold* contactManifold,btRigidBody& rbA,btRigidBody& rbB) -:btTypedConstraint(CONTACT_CONSTRAINT_TYPE,rbA,rbB), - m_contactManifold(*contactManifold) +btContactConstraint::btContactConstraint(btPersistentManifold* contactManifold, btRigidBody& rbA, btRigidBody& rbB) + : btTypedConstraint(CONTACT_CONSTRAINT_TYPE, rbA, rbB), + m_contactManifold(*contactManifold) { - } btContactConstraint::~btContactConstraint() { - } -void btContactConstraint::setContactManifold(btPersistentManifold* contactManifold) +void btContactConstraint::setContactManifold(btPersistentManifold* contactManifold) { m_contactManifold = *contactManifold; } -void btContactConstraint::getInfo1 (btConstraintInfo1* info) +void btContactConstraint::getInfo1(btConstraintInfo1* info) { - } -void btContactConstraint::getInfo2 (btConstraintInfo2* info) +void btContactConstraint::getInfo2(btConstraintInfo2* info) { - } -void btContactConstraint::buildJacobian() +void btContactConstraint::buildJacobian() { - } - - - - #include "btContactConstraint.h" #include "BulletDynamics/Dynamics/btRigidBody.h" #include "LinearMath/btVector3.h" @@ -68,64 +56,59 @@ void btContactConstraint::buildJacobian() #include "LinearMath/btMinMax.h" #include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h" - - //response between two dynamic objects without friction and no restitution, assuming 0 penetration depth btScalar resolveSingleCollision( - btRigidBody* body1, - btCollisionObject* colObj2, - const btVector3& contactPositionWorld, - const btVector3& contactNormalOnB, - const btContactSolverInfo& solverInfo, - btScalar distance) + btRigidBody* body1, + btCollisionObject* colObj2, + const btVector3& contactPositionWorld, + const btVector3& contactNormalOnB, + const btContactSolverInfo& solverInfo, + btScalar distance) { btRigidBody* body2 = btRigidBody::upcast(colObj2); - - - const btVector3& normal = contactNormalOnB; - btVector3 rel_pos1 = contactPositionWorld - body1->getWorldTransform().getOrigin(); - btVector3 rel_pos2 = contactPositionWorld - colObj2->getWorldTransform().getOrigin(); - - btVector3 vel1 = body1->getVelocityInLocalPoint(rel_pos1); - btVector3 vel2 = body2? body2->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0); - btVector3 vel = vel1 - vel2; - btScalar rel_vel; - rel_vel = normal.dot(vel); - - btScalar combinedRestitution = 0.f; - btScalar restitution = combinedRestitution* -rel_vel; + const btVector3& normal = contactNormalOnB; - btScalar positionalError = solverInfo.m_erp *-distance /solverInfo.m_timeStep ; - btScalar velocityError = -(1.0f + restitution) * rel_vel;// * damping; - btScalar denom0 = body1->computeImpulseDenominator(contactPositionWorld,normal); - btScalar denom1 = body2? body2->computeImpulseDenominator(contactPositionWorld,normal) : 0.f; + btVector3 rel_pos1 = contactPositionWorld - body1->getWorldTransform().getOrigin(); + btVector3 rel_pos2 = contactPositionWorld - colObj2->getWorldTransform().getOrigin(); + + btVector3 vel1 = body1->getVelocityInLocalPoint(rel_pos1); + btVector3 vel2 = body2 ? body2->getVelocityInLocalPoint(rel_pos2) : btVector3(0, 0, 0); + btVector3 vel = vel1 - vel2; + btScalar rel_vel; + rel_vel = normal.dot(vel); + + btScalar combinedRestitution = 0.f; + btScalar restitution = combinedRestitution * -rel_vel; + + btScalar positionalError = solverInfo.m_erp * -distance / solverInfo.m_timeStep; + btScalar velocityError = -(1.0f + restitution) * rel_vel; // * damping; + btScalar denom0 = body1->computeImpulseDenominator(contactPositionWorld, normal); + btScalar denom1 = body2 ? body2->computeImpulseDenominator(contactPositionWorld, normal) : 0.f; btScalar relaxation = 1.f; - btScalar jacDiagABInv = relaxation/(denom0+denom1); + btScalar jacDiagABInv = relaxation / (denom0 + denom1); - btScalar penetrationImpulse = positionalError * jacDiagABInv; - btScalar velocityImpulse = velocityError * jacDiagABInv; + btScalar penetrationImpulse = positionalError * jacDiagABInv; + btScalar velocityImpulse = velocityError * jacDiagABInv; - btScalar normalImpulse = penetrationImpulse+velocityImpulse; - normalImpulse = 0.f > normalImpulse ? 0.f: normalImpulse; + btScalar normalImpulse = penetrationImpulse + velocityImpulse; + normalImpulse = 0.f > normalImpulse ? 0.f : normalImpulse; - body1->applyImpulse(normal*(normalImpulse), rel_pos1); - if (body2) - body2->applyImpulse(-normal*(normalImpulse), rel_pos2); - - return normalImpulse; + body1->applyImpulse(normal * (normalImpulse), rel_pos1); + if (body2) + body2->applyImpulse(-normal * (normalImpulse), rel_pos2); + + return normalImpulse; } - //bilateral constraint between two dynamic objects void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1, - btRigidBody& body2, const btVector3& pos2, - btScalar distance, const btVector3& normal,btScalar& impulse ,btScalar timeStep) + btRigidBody& body2, const btVector3& pos2, + btScalar distance, const btVector3& normal, btScalar& impulse, btScalar timeStep) { (void)timeStep; (void)distance; - btScalar normalLenSqr = normal.length2(); btAssert(btFabs(normalLenSqr) < btScalar(1.1)); if (normalLenSqr > btScalar(1.1)) @@ -133,45 +116,38 @@ void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1, impulse = btScalar(0.); return; } - btVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition(); + btVector3 rel_pos1 = pos1 - body1.getCenterOfMassPosition(); btVector3 rel_pos2 = pos2 - body2.getCenterOfMassPosition(); //this jacobian entry could be re-used for all iterations - + btVector3 vel1 = body1.getVelocityInLocalPoint(rel_pos1); btVector3 vel2 = body2.getVelocityInLocalPoint(rel_pos2); btVector3 vel = vel1 - vel2; - - btJacobianEntry jac(body1.getCenterOfMassTransform().getBasis().transpose(), - body2.getCenterOfMassTransform().getBasis().transpose(), - rel_pos1,rel_pos2,normal,body1.getInvInertiaDiagLocal(),body1.getInvMass(), - body2.getInvInertiaDiagLocal(),body2.getInvMass()); + btJacobianEntry jac(body1.getCenterOfMassTransform().getBasis().transpose(), + body2.getCenterOfMassTransform().getBasis().transpose(), + rel_pos1, rel_pos2, normal, body1.getInvInertiaDiagLocal(), body1.getInvMass(), + body2.getInvInertiaDiagLocal(), body2.getInvMass()); btScalar jacDiagAB = jac.getDiagonal(); btScalar jacDiagABInv = btScalar(1.) / jacDiagAB; - - btScalar rel_vel = jac.getRelativeVelocity( + + btScalar rel_vel = jac.getRelativeVelocity( body1.getLinearVelocity(), body1.getCenterOfMassTransform().getBasis().transpose() * body1.getAngularVelocity(), body2.getLinearVelocity(), - body2.getCenterOfMassTransform().getBasis().transpose() * body2.getAngularVelocity()); - - + body2.getCenterOfMassTransform().getBasis().transpose() * body2.getAngularVelocity()); rel_vel = normal.dot(vel); - + //todo: move this into proper structure btScalar contactDamping = btScalar(0.2); #ifdef ONLY_USE_LINEAR_MASS btScalar massTerm = btScalar(1.) / (body1.getInvMass() + body2.getInvMass()); - impulse = - contactDamping * rel_vel * massTerm; -#else + impulse = -contactDamping * rel_vel * massTerm; +#else btScalar velocityImpulse = -contactDamping * rel_vel * jacDiagABInv; impulse = velocityImpulse; #endif } - - - - diff --git a/src/BulletDynamics/ConstraintSolver/btContactConstraint.h b/src/BulletDynamics/ConstraintSolver/btContactConstraint.h index adb226835..255489be9 100644 --- a/src/BulletDynamics/ConstraintSolver/btContactConstraint.h +++ b/src/BulletDynamics/ConstraintSolver/btContactConstraint.h @@ -22,20 +22,17 @@ subject to the following restrictions: #include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" ///btContactConstraint can be automatically created to solve contact constraints using the unified btTypedConstraint interface -ATTRIBUTE_ALIGNED16(class) btContactConstraint : public btTypedConstraint +ATTRIBUTE_ALIGNED16(class) +btContactConstraint : public btTypedConstraint { protected: - btPersistentManifold m_contactManifold; protected: - - - btContactConstraint(btPersistentManifold* contactManifold,btRigidBody& rbA,btRigidBody& rbB); + btContactConstraint(btPersistentManifold * contactManifold, btRigidBody & rbA, btRigidBody & rbB); public: - - void setContactManifold(btPersistentManifold* contactManifold); + void setContactManifold(btPersistentManifold * contactManifold); btPersistentManifold* getContactManifold() { @@ -49,25 +46,20 @@ public: virtual ~btContactConstraint(); - virtual void getInfo1 (btConstraintInfo1* info); + virtual void getInfo1(btConstraintInfo1 * info); - virtual void getInfo2 (btConstraintInfo2* info); + virtual void getInfo2(btConstraintInfo2 * info); ///obsolete methods - virtual void buildJacobian(); - - + virtual void buildJacobian(); }; ///very basic collision resolution without friction -btScalar resolveSingleCollision(btRigidBody* body1, class btCollisionObject* colObj2, const btVector3& contactPositionWorld,const btVector3& contactNormalOnB, const struct btContactSolverInfo& solverInfo,btScalar distance); - +btScalar resolveSingleCollision(btRigidBody* body1, class btCollisionObject* colObj2, const btVector3& contactPositionWorld, const btVector3& contactNormalOnB, const struct btContactSolverInfo& solverInfo, btScalar distance); ///resolveSingleBilateral is an obsolete methods used for vehicle friction between two dynamic objects void resolveSingleBilateral(btRigidBody& body1, const btVector3& pos1, - btRigidBody& body2, const btVector3& pos2, - btScalar distance, const btVector3& normal,btScalar& impulse ,btScalar timeStep); + btRigidBody& body2, const btVector3& pos2, + btScalar distance, const btVector3& normal, btScalar& impulse, btScalar timeStep); - - -#endif //BT_CONTACT_CONSTRAINT_H +#endif //BT_CONTACT_CONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h b/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h index 93865cbc5..439cc4428 100644 --- a/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h +++ b/src/BulletDynamics/ConstraintSolver/btContactSolverInfo.h @@ -18,7 +18,7 @@ subject to the following restrictions: #include "LinearMath/btScalar.h" -enum btSolverMode +enum btSolverMode { SOLVER_RANDMIZE_ORDER = 1, SOLVER_FRICTION_SEPARATE = 2, @@ -35,134 +35,125 @@ enum btSolverMode struct btContactSolverInfoData { - + btScalar m_tau; + btScalar m_damping; //global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'. + btScalar m_friction; + btScalar m_timeStep; + btScalar m_restitution; + int m_numIterations; + btScalar m_maxErrorReduction; + btScalar m_sor; //successive over-relaxation term + btScalar m_erp; //error reduction for non-contact constraints + btScalar m_erp2; //error reduction for contact constraints + btScalar m_globalCfm; //constraint force mixing for contacts and non-contacts + btScalar m_frictionERP; //error reduction for friction constraints + btScalar m_frictionCFM; //constraint force mixing for friction constraints - btScalar m_tau; - btScalar m_damping;//global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'. - btScalar m_friction; - btScalar m_timeStep; - btScalar m_restitution; - int m_numIterations; - btScalar m_maxErrorReduction; - btScalar m_sor;//successive over-relaxation term - btScalar m_erp;//error reduction for non-contact constraints - btScalar m_erp2;//error reduction for contact constraints - btScalar m_globalCfm;//constraint force mixing for contacts and non-contacts - btScalar m_frictionERP;//error reduction for friction constraints - btScalar m_frictionCFM;//constraint force mixing for friction constraints - - int m_splitImpulse; - btScalar m_splitImpulsePenetrationThreshold; - btScalar m_splitImpulseTurnErp; - btScalar m_linearSlop; - btScalar m_warmstartingFactor; - - int m_solverMode; - int m_restingContactRestitutionThreshold; - int m_minimumSolverBatchSize; - btScalar m_maxGyroscopicForce; - btScalar m_singleAxisRollingFrictionThreshold; - btScalar m_leastSquaresResidualThreshold; - btScalar m_restitutionVelocityThreshold; + int m_splitImpulse; + btScalar m_splitImpulsePenetrationThreshold; + btScalar m_splitImpulseTurnErp; + btScalar m_linearSlop; + btScalar m_warmstartingFactor; + int m_solverMode; + int m_restingContactRestitutionThreshold; + int m_minimumSolverBatchSize; + btScalar m_maxGyroscopicForce; + btScalar m_singleAxisRollingFrictionThreshold; + btScalar m_leastSquaresResidualThreshold; + btScalar m_restitutionVelocityThreshold; }; struct btContactSolverInfo : public btContactSolverInfoData { - - - inline btContactSolverInfo() { m_tau = btScalar(0.6); m_damping = btScalar(1.0); m_friction = btScalar(0.3); - m_timeStep = btScalar(1.f/60.f); + m_timeStep = btScalar(1.f / 60.f); m_restitution = btScalar(0.); m_maxErrorReduction = btScalar(20.); m_numIterations = 10; m_erp = btScalar(0.2); m_erp2 = btScalar(0.2); m_globalCfm = btScalar(0.); - m_frictionERP = btScalar(0.2);//positional friction 'anchors' are disabled by default + m_frictionERP = btScalar(0.2); //positional friction 'anchors' are disabled by default m_frictionCFM = btScalar(0.); m_sor = btScalar(1.); m_splitImpulse = true; m_splitImpulsePenetrationThreshold = -.04f; m_splitImpulseTurnErp = 0.1f; m_linearSlop = btScalar(0.0); - m_warmstartingFactor=btScalar(0.85); + m_warmstartingFactor = btScalar(0.85); //m_solverMode = SOLVER_USE_WARMSTARTING | SOLVER_SIMD | SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION|SOLVER_USE_2_FRICTION_DIRECTIONS|SOLVER_ENABLE_FRICTION_DIRECTION_CACHING;// | SOLVER_RANDMIZE_ORDER; - m_solverMode = SOLVER_USE_WARMSTARTING | SOLVER_SIMD;// | SOLVER_RANDMIZE_ORDER; - m_restingContactRestitutionThreshold = 2;//unused as of 2.81 - m_minimumSolverBatchSize = 128; //try to combine islands until the amount of constraints reaches this limit - m_maxGyroscopicForce = 100.f; ///it is only used for 'explicit' version of gyroscopic force - m_singleAxisRollingFrictionThreshold = 1e30f;///if the velocity is above this threshold, it will use a single constraint row (axis), otherwise 3 rows. + m_solverMode = SOLVER_USE_WARMSTARTING | SOLVER_SIMD; // | SOLVER_RANDMIZE_ORDER; + m_restingContactRestitutionThreshold = 2; //unused as of 2.81 + m_minimumSolverBatchSize = 128; //try to combine islands until the amount of constraints reaches this limit + m_maxGyroscopicForce = 100.f; ///it is only used for 'explicit' version of gyroscopic force + m_singleAxisRollingFrictionThreshold = 1e30f; ///if the velocity is above this threshold, it will use a single constraint row (axis), otherwise 3 rows. m_leastSquaresResidualThreshold = 0.f; - m_restitutionVelocityThreshold = 0.2f;//if the relative velocity is below this threshold, there is zero restitution + m_restitutionVelocityThreshold = 0.2f; //if the relative velocity is below this threshold, there is zero restitution } }; ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 struct btContactSolverInfoDoubleData { - double m_tau; - double m_damping;//global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'. - double m_friction; - double m_timeStep; - double m_restitution; - double m_maxErrorReduction; - double m_sor; - double m_erp;//used as Baumgarte factor - double m_erp2;//used in Split Impulse - double m_globalCfm;//constraint force mixing - double m_splitImpulsePenetrationThreshold; - double m_splitImpulseTurnErp; - double m_linearSlop; - double m_warmstartingFactor; - double m_maxGyroscopicForce;///it is only used for 'explicit' version of gyroscopic force - double m_singleAxisRollingFrictionThreshold; - - int m_numIterations; - int m_solverMode; - int m_restingContactRestitutionThreshold; - int m_minimumSolverBatchSize; - int m_splitImpulse; - char m_padding[4]; + double m_tau; + double m_damping; //global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'. + double m_friction; + double m_timeStep; + double m_restitution; + double m_maxErrorReduction; + double m_sor; + double m_erp; //used as Baumgarte factor + double m_erp2; //used in Split Impulse + double m_globalCfm; //constraint force mixing + double m_splitImpulsePenetrationThreshold; + double m_splitImpulseTurnErp; + double m_linearSlop; + double m_warmstartingFactor; + double m_maxGyroscopicForce; ///it is only used for 'explicit' version of gyroscopic force + double m_singleAxisRollingFrictionThreshold; + int m_numIterations; + int m_solverMode; + int m_restingContactRestitutionThreshold; + int m_minimumSolverBatchSize; + int m_splitImpulse; + char m_padding[4]; }; ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 struct btContactSolverInfoFloatData { - float m_tau; - float m_damping;//global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'. - float m_friction; - float m_timeStep; + float m_tau; + float m_damping; //global non-contact constraint damping, can be locally overridden by constraints during 'getInfo2'. + float m_friction; + float m_timeStep; - float m_restitution; - float m_maxErrorReduction; - float m_sor; - float m_erp;//used as Baumgarte factor + float m_restitution; + float m_maxErrorReduction; + float m_sor; + float m_erp; //used as Baumgarte factor - float m_erp2;//used in Split Impulse - float m_globalCfm;//constraint force mixing - float m_splitImpulsePenetrationThreshold; - float m_splitImpulseTurnErp; + float m_erp2; //used in Split Impulse + float m_globalCfm; //constraint force mixing + float m_splitImpulsePenetrationThreshold; + float m_splitImpulseTurnErp; - float m_linearSlop; - float m_warmstartingFactor; - float m_maxGyroscopicForce; - float m_singleAxisRollingFrictionThreshold; + float m_linearSlop; + float m_warmstartingFactor; + float m_maxGyroscopicForce; + float m_singleAxisRollingFrictionThreshold; - int m_numIterations; - int m_solverMode; - int m_restingContactRestitutionThreshold; - int m_minimumSolverBatchSize; + int m_numIterations; + int m_solverMode; + int m_restingContactRestitutionThreshold; + int m_minimumSolverBatchSize; - int m_splitImpulse; - char m_padding[4]; + int m_splitImpulse; + char m_padding[4]; }; - - -#endif //BT_CONTACT_SOLVER_INFO +#endif //BT_CONTACT_SOLVER_INFO diff --git a/src/BulletDynamics/ConstraintSolver/btFixedConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btFixedConstraint.cpp index 75d81cc08..bba102d90 100644 --- a/src/BulletDynamics/ConstraintSolver/btFixedConstraint.cpp +++ b/src/BulletDynamics/ConstraintSolver/btFixedConstraint.cpp @@ -13,25 +13,20 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btFixedConstraint.h" #include "BulletDynamics/Dynamics/btRigidBody.h" #include "LinearMath/btTransformUtil.h" #include - -btFixedConstraint::btFixedConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& frameInA,const btTransform& frameInB) -:btGeneric6DofSpring2Constraint(rbA,rbB,frameInA,frameInB) +btFixedConstraint::btFixedConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB) + : btGeneric6DofSpring2Constraint(rbA, rbB, frameInA, frameInB) { - setAngularLowerLimit(btVector3(0,0,0)); - setAngularUpperLimit(btVector3(0,0,0)); - setLinearLowerLimit(btVector3(0,0,0)); - setLinearUpperLimit(btVector3(0,0,0)); + setAngularLowerLimit(btVector3(0, 0, 0)); + setAngularUpperLimit(btVector3(0, 0, 0)); + setLinearLowerLimit(btVector3(0, 0, 0)); + setLinearUpperLimit(btVector3(0, 0, 0)); } - - - -btFixedConstraint::~btFixedConstraint () +btFixedConstraint::~btFixedConstraint() { } diff --git a/src/BulletDynamics/ConstraintSolver/btFixedConstraint.h b/src/BulletDynamics/ConstraintSolver/btFixedConstraint.h index bff2008b2..6d474ea81 100644 --- a/src/BulletDynamics/ConstraintSolver/btFixedConstraint.h +++ b/src/BulletDynamics/ConstraintSolver/btFixedConstraint.h @@ -18,16 +18,13 @@ subject to the following restrictions: #include "btGeneric6DofSpring2Constraint.h" - -ATTRIBUTE_ALIGNED16(class) btFixedConstraint : public btGeneric6DofSpring2Constraint +ATTRIBUTE_ALIGNED16(class) +btFixedConstraint : public btGeneric6DofSpring2Constraint { - public: - btFixedConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& frameInA,const btTransform& frameInB); + btFixedConstraint(btRigidBody & rbA, btRigidBody & rbB, const btTransform& frameInA, const btTransform& frameInB); - virtual ~btFixedConstraint(); - }; -#endif //BT_FIXED_CONSTRAINT_H +#endif //BT_FIXED_CONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btGearConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btGearConstraint.cpp index bcd457b67..7535c52c0 100644 --- a/src/BulletDynamics/ConstraintSolver/btGearConstraint.cpp +++ b/src/BulletDynamics/ConstraintSolver/btGearConstraint.cpp @@ -17,38 +17,36 @@ subject to the following restrictions: #include "btGearConstraint.h" -btGearConstraint::btGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA,const btVector3& axisInB, btScalar ratio) -:btTypedConstraint(GEAR_CONSTRAINT_TYPE,rbA,rbB), -m_axisInA(axisInA), -m_axisInB(axisInB), -m_ratio(ratio) +btGearConstraint::btGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA, const btVector3& axisInB, btScalar ratio) + : btTypedConstraint(GEAR_CONSTRAINT_TYPE, rbA, rbB), + m_axisInA(axisInA), + m_axisInB(axisInB), + m_ratio(ratio) { } -btGearConstraint::~btGearConstraint () +btGearConstraint::~btGearConstraint() { } -void btGearConstraint::getInfo1 (btConstraintInfo1* info) +void btGearConstraint::getInfo1(btConstraintInfo1* info) { info->m_numConstraintRows = 1; info->nub = 1; } -void btGearConstraint::getInfo2 (btConstraintInfo2* info) +void btGearConstraint::getInfo2(btConstraintInfo2* info) { btVector3 globalAxisA, globalAxisB; - globalAxisA = m_rbA.getWorldTransform().getBasis()*this->m_axisInA; - globalAxisB = m_rbB.getWorldTransform().getBasis()*this->m_axisInB; + globalAxisA = m_rbA.getWorldTransform().getBasis() * this->m_axisInA; + globalAxisB = m_rbB.getWorldTransform().getBasis() * this->m_axisInB; info->m_J1angularAxis[0] = globalAxisA[0]; info->m_J1angularAxis[1] = globalAxisA[1]; info->m_J1angularAxis[2] = globalAxisA[2]; - info->m_J2angularAxis[0] = m_ratio*globalAxisB[0]; - info->m_J2angularAxis[1] = m_ratio*globalAxisB[1]; - info->m_J2angularAxis[2] = m_ratio*globalAxisB[2]; - + info->m_J2angularAxis[0] = m_ratio * globalAxisB[0]; + info->m_J2angularAxis[1] = m_ratio * globalAxisB[1]; + info->m_J2angularAxis[2] = m_ratio * globalAxisB[2]; } - diff --git a/src/BulletDynamics/ConstraintSolver/btGearConstraint.h b/src/BulletDynamics/ConstraintSolver/btGearConstraint.h index e4613455a..64b15dfbc 100644 --- a/src/BulletDynamics/ConstraintSolver/btGearConstraint.h +++ b/src/BulletDynamics/ConstraintSolver/btGearConstraint.h @@ -13,45 +13,40 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #ifndef BT_GEAR_CONSTRAINT_H #define BT_GEAR_CONSTRAINT_H #include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" - #ifdef BT_USE_DOUBLE_PRECISION -#define btGearConstraintData btGearConstraintDoubleData -#define btGearConstraintDataName "btGearConstraintDoubleData" +#define btGearConstraintData btGearConstraintDoubleData +#define btGearConstraintDataName "btGearConstraintDoubleData" #else -#define btGearConstraintData btGearConstraintFloatData -#define btGearConstraintDataName "btGearConstraintFloatData" -#endif //BT_USE_DOUBLE_PRECISION - - +#define btGearConstraintData btGearConstraintFloatData +#define btGearConstraintDataName "btGearConstraintFloatData" +#endif //BT_USE_DOUBLE_PRECISION ///The btGeatConstraint will couple the angular velocity for two bodies around given local axis and ratio. ///See Bullet/Demos/ConstraintDemo for an example use. class btGearConstraint : public btTypedConstraint { protected: - btVector3 m_axisInA; - btVector3 m_axisInB; - bool m_useFrameA; - btScalar m_ratio; + btVector3 m_axisInA; + btVector3 m_axisInB; + bool m_useFrameA; + btScalar m_ratio; public: - btGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA,const btVector3& axisInB, btScalar ratio=1.f); - virtual ~btGearConstraint (); + btGearConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& axisInA, const btVector3& axisInB, btScalar ratio = 1.f); + virtual ~btGearConstraint(); ///internal method used by the constraint solver, don't use them directly - virtual void getInfo1 (btConstraintInfo1* info); + virtual void getInfo1(btConstraintInfo1* info); ///internal method used by the constraint solver, don't use them directly - virtual void getInfo2 (btConstraintInfo2* info); + virtual void getInfo2(btConstraintInfo2* info); - void setAxisA(btVector3& axisA) + void setAxisA(btVector3& axisA) { m_axisInA = axisA; } @@ -76,68 +71,64 @@ public: return m_ratio; } - - virtual void setParam(int num, btScalar value, int axis = -1) + virtual void setParam(int num, btScalar value, int axis = -1) { - (void) num; - (void) value; - (void) axis; + (void)num; + (void)value; + (void)axis; btAssert(0); } ///return the local value of parameter - virtual btScalar getParam(int num, int axis = -1) const - { - (void) num; - (void) axis; + virtual btScalar getParam(int num, int axis = -1) const + { + (void)num; + (void)axis; btAssert(0); return 0.f; } - virtual int calculateSerializeBufferSize() const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; }; - - - ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 struct btGearConstraintFloatData { - btTypedConstraintFloatData m_typeConstraintData; + btTypedConstraintFloatData m_typeConstraintData; - btVector3FloatData m_axisInA; - btVector3FloatData m_axisInB; + btVector3FloatData m_axisInA; + btVector3FloatData m_axisInB; - float m_ratio; - char m_padding[4]; + float m_ratio; + char m_padding[4]; }; struct btGearConstraintDoubleData { - btTypedConstraintDoubleData m_typeConstraintData; + btTypedConstraintDoubleData m_typeConstraintData; - btVector3DoubleData m_axisInA; - btVector3DoubleData m_axisInB; + btVector3DoubleData m_axisInA; + btVector3DoubleData m_axisInB; - double m_ratio; + double m_ratio; }; -SIMD_FORCE_INLINE int btGearConstraint::calculateSerializeBufferSize() const +SIMD_FORCE_INLINE int btGearConstraint::calculateSerializeBufferSize() const { return sizeof(btGearConstraintData); } - ///fills the dataBuffer and returns the struct name (and 0 on failure) -SIMD_FORCE_INLINE const char* btGearConstraint::serialize(void* dataBuffer, btSerializer* serializer) const +///fills the dataBuffer and returns the struct name (and 0 on failure) +SIMD_FORCE_INLINE const char* btGearConstraint::serialize(void* dataBuffer, btSerializer* serializer) const { btGearConstraintData* gear = (btGearConstraintData*)dataBuffer; - btTypedConstraint::serialize(&gear->m_typeConstraintData,serializer); + btTypedConstraint::serialize(&gear->m_typeConstraintData, serializer); - m_axisInA.serialize( gear->m_axisInA ); - m_axisInB.serialize( gear->m_axisInB ); + m_axisInA.serialize(gear->m_axisInA); + m_axisInB.serialize(gear->m_axisInB); gear->m_ratio = m_ratio; @@ -152,9 +143,4 @@ SIMD_FORCE_INLINE const char* btGearConstraint::serialize(void* dataBuffer, btSe return btGearConstraintDataName; } - - - - - -#endif //BT_GEAR_CONSTRAINT_H +#endif //BT_GEAR_CONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp index c38b8353f..1f5420353 100644 --- a/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp +++ b/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.cpp @@ -25,83 +25,61 @@ http://gimpact.sf.net #include "LinearMath/btTransformUtil.h" #include - - #define D6_USE_OBSOLETE_METHOD false #define D6_USE_FRAME_OFFSET true - - - - - btGeneric6DofConstraint::btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA) -: btTypedConstraint(D6_CONSTRAINT_TYPE, rbA, rbB) -, m_frameInA(frameInA) -, m_frameInB(frameInB), -m_useLinearReferenceFrameA(useLinearReferenceFrameA), -m_useOffsetForConstraintFrame(D6_USE_FRAME_OFFSET), -m_flags(0), -m_useSolveConstraintObsolete(D6_USE_OBSOLETE_METHOD) + : btTypedConstraint(D6_CONSTRAINT_TYPE, rbA, rbB), m_frameInA(frameInA), m_frameInB(frameInB), m_useLinearReferenceFrameA(useLinearReferenceFrameA), m_useOffsetForConstraintFrame(D6_USE_FRAME_OFFSET), m_flags(0), m_useSolveConstraintObsolete(D6_USE_OBSOLETE_METHOD) { calculateTransforms(); } - - btGeneric6DofConstraint::btGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB) - : btTypedConstraint(D6_CONSTRAINT_TYPE, getFixedBody(), rbB), - m_frameInB(frameInB), - m_useLinearReferenceFrameA(useLinearReferenceFrameB), - m_useOffsetForConstraintFrame(D6_USE_FRAME_OFFSET), - m_flags(0), - m_useSolveConstraintObsolete(false) + : btTypedConstraint(D6_CONSTRAINT_TYPE, getFixedBody(), rbB), + m_frameInB(frameInB), + m_useLinearReferenceFrameA(useLinearReferenceFrameB), + m_useOffsetForConstraintFrame(D6_USE_FRAME_OFFSET), + m_flags(0), + m_useSolveConstraintObsolete(false) { ///not providing rigidbody A means implicitly using worldspace for body A m_frameInA = rbB.getCenterOfMassTransform() * m_frameInB; calculateTransforms(); } - - - #define GENERIC_D6_DISABLE_WARMSTARTING 1 - - btScalar btGetMatrixElem(const btMatrix3x3& mat, int index); btScalar btGetMatrixElem(const btMatrix3x3& mat, int index) { - int i = index%3; - int j = index/3; + int i = index % 3; + int j = index / 3; return mat[i][j]; } - - ///MatrixToEulerXYZ from http://www.geometrictools.com/LibFoundation/Mathematics/Wm4Matrix3.inl.html -bool matrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz); -bool matrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz) +bool matrixToEulerXYZ(const btMatrix3x3& mat, btVector3& xyz); +bool matrixToEulerXYZ(const btMatrix3x3& mat, btVector3& xyz) { // // rot = cy*cz -cy*sz sy // // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx // // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy // - btScalar fi = btGetMatrixElem(mat,2); + btScalar fi = btGetMatrixElem(mat, 2); if (fi < btScalar(1.0f)) { if (fi > btScalar(-1.0f)) { - xyz[0] = btAtan2(-btGetMatrixElem(mat,5),btGetMatrixElem(mat,8)); - xyz[1] = btAsin(btGetMatrixElem(mat,2)); - xyz[2] = btAtan2(-btGetMatrixElem(mat,1),btGetMatrixElem(mat,0)); + xyz[0] = btAtan2(-btGetMatrixElem(mat, 5), btGetMatrixElem(mat, 8)); + xyz[1] = btAsin(btGetMatrixElem(mat, 2)); + xyz[2] = btAtan2(-btGetMatrixElem(mat, 1), btGetMatrixElem(mat, 0)); return true; } else { // WARNING. Not unique. XA - ZA = -atan2(r10,r11) - xyz[0] = -btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4)); + xyz[0] = -btAtan2(btGetMatrixElem(mat, 3), btGetMatrixElem(mat, 4)); xyz[1] = -SIMD_HALF_PI; xyz[2] = btScalar(0.0); return false; @@ -110,7 +88,7 @@ bool matrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz) else { // WARNING. Not unique. XAngle + ZAngle = atan2(r10,r11) - xyz[0] = btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4)); + xyz[0] = btAtan2(btGetMatrixElem(mat, 3), btGetMatrixElem(mat, 4)); xyz[1] = SIMD_HALF_PI; xyz[2] = 0.0; } @@ -121,52 +99,49 @@ bool matrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz) int btRotationalLimitMotor::testLimitValue(btScalar test_value) { - if(m_loLimit>m_hiLimit) + if (m_loLimit > m_hiLimit) { - m_currentLimit = 0;//Free from violation + m_currentLimit = 0; //Free from violation return 0; } if (test_value < m_loLimit) { - m_currentLimit = 1;//low limit violation - m_currentLimitError = test_value - m_loLimit; - if(m_currentLimitError>SIMD_PI) - m_currentLimitError-=SIMD_2_PI; - else if(m_currentLimitError<-SIMD_PI) - m_currentLimitError+=SIMD_2_PI; + m_currentLimit = 1; //low limit violation + m_currentLimitError = test_value - m_loLimit; + if (m_currentLimitError > SIMD_PI) + m_currentLimitError -= SIMD_2_PI; + else if (m_currentLimitError < -SIMD_PI) + m_currentLimitError += SIMD_2_PI; return 1; } - else if (test_value> m_hiLimit) + else if (test_value > m_hiLimit) { - m_currentLimit = 2;//High limit violation + m_currentLimit = 2; //High limit violation m_currentLimitError = test_value - m_hiLimit; - if(m_currentLimitError>SIMD_PI) - m_currentLimitError-=SIMD_2_PI; - else if(m_currentLimitError<-SIMD_PI) - m_currentLimitError+=SIMD_2_PI; + if (m_currentLimitError > SIMD_PI) + m_currentLimitError -= SIMD_2_PI; + else if (m_currentLimitError < -SIMD_PI) + m_currentLimitError += SIMD_2_PI; return 2; }; - m_currentLimit = 0;//Free from violation + m_currentLimit = 0; //Free from violation return 0; - } - - btScalar btRotationalLimitMotor::solveAngularLimits( - btScalar timeStep,btVector3& axis,btScalar jacDiagABInv, - btRigidBody * body0, btRigidBody * body1 ) + btScalar timeStep, btVector3& axis, btScalar jacDiagABInv, + btRigidBody* body0, btRigidBody* body1) { - if (needApplyTorques()==false) return 0.0f; + if (needApplyTorques() == false) return 0.0f; btScalar target_velocity = m_targetVelocity; btScalar maxMotorForce = m_maxMotorForce; //current error correction - if (m_currentLimit!=0) + if (m_currentLimit != 0) { - target_velocity = -m_stopERP*m_currentLimitError/(timeStep); + target_velocity = -m_stopERP * m_currentLimitError / (timeStep); maxMotorForce = m_maxLimitForce; } @@ -178,42 +153,37 @@ btScalar btRotationalLimitMotor::solveAngularLimits( btVector3 angVelB = body1->getAngularVelocity(); btVector3 vel_diff; - vel_diff = angVelA-angVelB; - - + vel_diff = angVelA - angVelB; btScalar rel_vel = axis.dot(vel_diff); // correction velocity - btScalar motor_relvel = m_limitSoftness*(target_velocity - m_damping*rel_vel); + btScalar motor_relvel = m_limitSoftness * (target_velocity - m_damping * rel_vel); - - if ( motor_relvel < SIMD_EPSILON && motor_relvel > -SIMD_EPSILON ) + if (motor_relvel < SIMD_EPSILON && motor_relvel > -SIMD_EPSILON) { - return 0.0f;//no need for applying force + return 0.0f; //no need for applying force } - // correction impulse - btScalar unclippedMotorImpulse = (1+m_bounce)*motor_relvel*jacDiagABInv; + btScalar unclippedMotorImpulse = (1 + m_bounce) * motor_relvel * jacDiagABInv; // clip correction impulse btScalar clippedMotorImpulse; ///@todo: should clip against accumulated impulse - if (unclippedMotorImpulse>0.0f) + if (unclippedMotorImpulse > 0.0f) { - clippedMotorImpulse = unclippedMotorImpulse > maxMotorForce? maxMotorForce: unclippedMotorImpulse; + clippedMotorImpulse = unclippedMotorImpulse > maxMotorForce ? maxMotorForce : unclippedMotorImpulse; } else { - clippedMotorImpulse = unclippedMotorImpulse < -maxMotorForce ? -maxMotorForce: unclippedMotorImpulse; + clippedMotorImpulse = unclippedMotorImpulse < -maxMotorForce ? -maxMotorForce : unclippedMotorImpulse; } - // sort with accumulated impulses - btScalar lo = btScalar(-BT_LARGE_FLOAT); - btScalar hi = btScalar(BT_LARGE_FLOAT); + btScalar lo = btScalar(-BT_LARGE_FLOAT); + btScalar hi = btScalar(BT_LARGE_FLOAT); btScalar oldaccumImpulse = m_accumulatedImpulse; btScalar sum = oldaccumImpulse + clippedMotorImpulse; @@ -227,59 +197,50 @@ btScalar btRotationalLimitMotor::solveAngularLimits( body1->applyTorqueImpulse(-motorImp); return clippedMotorImpulse; - - } //////////////////////////// End btRotationalLimitMotor //////////////////////////////////// - - - //////////////////////////// btTranslationalLimitMotor //////////////////////////////////// - int btTranslationalLimitMotor::testLimitValue(int limitIndex, btScalar test_value) { btScalar loLimit = m_lowerLimit[limitIndex]; btScalar hiLimit = m_upperLimit[limitIndex]; - if(loLimit > hiLimit) + if (loLimit > hiLimit) { - m_currentLimit[limitIndex] = 0;//Free from violation + m_currentLimit[limitIndex] = 0; //Free from violation m_currentLimitError[limitIndex] = btScalar(0.f); return 0; } if (test_value < loLimit) { - m_currentLimit[limitIndex] = 2;//low limit violation - m_currentLimitError[limitIndex] = test_value - loLimit; + m_currentLimit[limitIndex] = 2; //low limit violation + m_currentLimitError[limitIndex] = test_value - loLimit; return 2; } - else if (test_value> hiLimit) + else if (test_value > hiLimit) { - m_currentLimit[limitIndex] = 1;//High limit violation + m_currentLimit[limitIndex] = 1; //High limit violation m_currentLimitError[limitIndex] = test_value - hiLimit; return 1; }; - m_currentLimit[limitIndex] = 0;//Free from violation + m_currentLimit[limitIndex] = 0; //Free from violation m_currentLimitError[limitIndex] = btScalar(0.f); return 0; } - - btScalar btTranslationalLimitMotor::solveLinearAxis( btScalar timeStep, btScalar jacDiagABInv, - btRigidBody& body1,const btVector3 &pointInA, - btRigidBody& body2,const btVector3 &pointInB, + btRigidBody& body1, const btVector3& pointInA, + btRigidBody& body2, const btVector3& pointInB, int limit_index, - const btVector3 & axis_normal_on_a, - const btVector3 & anchorPos) + const btVector3& axis_normal_on_a, + const btVector3& anchorPos) { - ///find relative velocity // btVector3 rel_pos1 = pointInA - body1.getCenterOfMassPosition(); // btVector3 rel_pos2 = pointInB - body2.getCenterOfMassPosition(); @@ -292,14 +253,12 @@ btScalar btTranslationalLimitMotor::solveLinearAxis( btScalar rel_vel = axis_normal_on_a.dot(vel); - - /// apply displacement correction //positional error (zeroth order error) btScalar depth = -(pointInA - pointInB).dot(axis_normal_on_a); - btScalar lo = btScalar(-BT_LARGE_FLOAT); - btScalar hi = btScalar(BT_LARGE_FLOAT); + btScalar lo = btScalar(-BT_LARGE_FLOAT); + btScalar hi = btScalar(BT_LARGE_FLOAT); btScalar minLimit = m_lowerLimit[limit_index]; btScalar maxLimit = m_upperLimit[limit_index]; @@ -312,7 +271,6 @@ btScalar btTranslationalLimitMotor::solveLinearAxis( { depth -= maxLimit; lo = btScalar(0.); - } else { @@ -329,10 +287,7 @@ btScalar btTranslationalLimitMotor::solveLinearAxis( } } - btScalar normalImpulse= m_limitSoftness*(m_restitution*depth/timeStep - m_damping*rel_vel) * jacDiagABInv; - - - + btScalar normalImpulse = m_limitSoftness * (m_restitution * depth / timeStep - m_damping * rel_vel) * jacDiagABInv; btScalar oldNormalImpulse = m_accumulatedImpulse[limit_index]; btScalar sum = oldNormalImpulse + normalImpulse; @@ -340,11 +295,9 @@ btScalar btTranslationalLimitMotor::solveLinearAxis( normalImpulse = m_accumulatedImpulse[limit_index] - oldNormalImpulse; btVector3 impulse_vector = axis_normal_on_a * normalImpulse; - body1.applyImpulse( impulse_vector, rel_pos1); + body1.applyImpulse(impulse_vector, rel_pos1); body2.applyImpulse(-impulse_vector, rel_pos2); - - return normalImpulse; } @@ -352,8 +305,8 @@ btScalar btTranslationalLimitMotor::solveLinearAxis( void btGeneric6DofConstraint::calculateAngleInfo() { - btMatrix3x3 relative_frame = m_calculatedTransformA.getBasis().inverse()*m_calculatedTransformB.getBasis(); - matrixToEulerXYZ(relative_frame,m_calculatedAxisAngleDiff); + btMatrix3x3 relative_frame = m_calculatedTransformA.getBasis().inverse() * m_calculatedTransformB.getBasis(); + matrixToEulerXYZ(relative_frame, m_calculatedAxisAngleDiff); // in euler angle mode we do not actually constrain the angular velocity // along the axes axis[0] and axis[2] (although we do use axis[1]) : // @@ -378,31 +331,30 @@ void btGeneric6DofConstraint::calculateAngleInfo() m_calculatedAxis[0].normalize(); m_calculatedAxis[1].normalize(); m_calculatedAxis[2].normalize(); - } void btGeneric6DofConstraint::calculateTransforms() { - calculateTransforms(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); + calculateTransforms(m_rbA.getCenterOfMassTransform(), m_rbB.getCenterOfMassTransform()); } -void btGeneric6DofConstraint::calculateTransforms(const btTransform& transA,const btTransform& transB) +void btGeneric6DofConstraint::calculateTransforms(const btTransform& transA, const btTransform& transB) { m_calculatedTransformA = transA * m_frameInA; m_calculatedTransformB = transB * m_frameInB; calculateLinearInfo(); calculateAngleInfo(); - if(m_useOffsetForConstraintFrame) - { // get weight factors depending on masses + if (m_useOffsetForConstraintFrame) + { // get weight factors depending on masses btScalar miA = getRigidBodyA().getInvMass(); btScalar miB = getRigidBodyB().getInvMass(); m_hasStaticBody = (miA < SIMD_EPSILON) || (miB < SIMD_EPSILON); btScalar miS = miA + miB; - if(miS > btScalar(0.f)) + if (miS > btScalar(0.f)) { m_factA = miB / miS; } - else + else { m_factA = btScalar(0.5f); } @@ -410,39 +362,32 @@ void btGeneric6DofConstraint::calculateTransforms(const btTransform& transA,cons } } - - void btGeneric6DofConstraint::buildLinearJacobian( - btJacobianEntry & jacLinear,const btVector3 & normalWorld, - const btVector3 & pivotAInW,const btVector3 & pivotBInW) + btJacobianEntry& jacLinear, const btVector3& normalWorld, + const btVector3& pivotAInW, const btVector3& pivotBInW) { new (&jacLinear) btJacobianEntry( - m_rbA.getCenterOfMassTransform().getBasis().transpose(), - m_rbB.getCenterOfMassTransform().getBasis().transpose(), - pivotAInW - m_rbA.getCenterOfMassPosition(), - pivotBInW - m_rbB.getCenterOfMassPosition(), - normalWorld, - m_rbA.getInvInertiaDiagLocal(), - m_rbA.getInvMass(), - m_rbB.getInvInertiaDiagLocal(), - m_rbB.getInvMass()); + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + pivotAInW - m_rbA.getCenterOfMassPosition(), + pivotBInW - m_rbB.getCenterOfMassPosition(), + normalWorld, + m_rbA.getInvInertiaDiagLocal(), + m_rbA.getInvMass(), + m_rbB.getInvInertiaDiagLocal(), + m_rbB.getInvMass()); } - - void btGeneric6DofConstraint::buildAngularJacobian( - btJacobianEntry & jacAngular,const btVector3 & jointAxisW) + btJacobianEntry& jacAngular, const btVector3& jointAxisW) { - new (&jacAngular) btJacobianEntry(jointAxisW, - m_rbA.getCenterOfMassTransform().getBasis().transpose(), - m_rbB.getCenterOfMassTransform().getBasis().transpose(), - m_rbA.getInvInertiaDiagLocal(), - m_rbB.getInvInertiaDiagLocal()); - + new (&jacAngular) btJacobianEntry(jointAxisW, + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + m_rbA.getInvInertiaDiagLocal(), + m_rbB.getInvInertiaDiagLocal()); } - - bool btGeneric6DofConstraint::testAngularLimitMotor(int axis_index) { btScalar angle = m_calculatedAxisAngleDiff[axis_index]; @@ -453,23 +398,20 @@ bool btGeneric6DofConstraint::testAngularLimitMotor(int axis_index) return m_angularLimits[axis_index].needApplyTorques(); } - - void btGeneric6DofConstraint::buildJacobian() { #ifndef __SPU__ if (m_useSolveConstraintObsolete) { - // Clear accumulated impulses for the next simulation step m_linearLimits.m_accumulatedImpulse.setValue(btScalar(0.), btScalar(0.), btScalar(0.)); int i; - for(i = 0; i < 3; i++) + for (i = 0; i < 3; i++) { m_angularLimits[i].m_accumulatedImpulse = btScalar(0.); } //calculates transform - calculateTransforms(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); + calculateTransforms(m_rbA.getCenterOfMassTransform(), m_rbB.getCenterOfMassTransform()); // const btVector3& pivotAInW = m_calculatedTransformA.getOrigin(); // const btVector3& pivotBInW = m_calculatedTransformB.getOrigin(); @@ -483,7 +425,7 @@ void btGeneric6DofConstraint::buildJacobian() btVector3 normalWorld; //linear part - for (i=0;i<3;i++) + for (i = 0; i < 3; i++) { if (m_linearLimits.isLimited(i)) { @@ -493,56 +435,53 @@ void btGeneric6DofConstraint::buildJacobian() normalWorld = m_calculatedTransformB.getBasis().getColumn(i); buildLinearJacobian( - m_jacLinear[i],normalWorld , - pivotAInW,pivotBInW); - + m_jacLinear[i], normalWorld, + pivotAInW, pivotBInW); } } // angular part - for (i=0;i<3;i++) + for (i = 0; i < 3; i++) { //calculates error angle if (testAngularLimitMotor(i)) { normalWorld = this->getAxis(i); // Create angular atom - buildAngularJacobian(m_jacAng[i],normalWorld); + buildAngularJacobian(m_jacAng[i], normalWorld); } } - } -#endif //__SPU__ - +#endif //__SPU__ } - -void btGeneric6DofConstraint::getInfo1 (btConstraintInfo1* info) +void btGeneric6DofConstraint::getInfo1(btConstraintInfo1* info) { if (m_useSolveConstraintObsolete) { info->m_numConstraintRows = 0; info->nub = 0; - } else + } + else { //prepare constraint - calculateTransforms(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); + calculateTransforms(m_rbA.getCenterOfMassTransform(), m_rbB.getCenterOfMassTransform()); info->m_numConstraintRows = 0; info->nub = 6; int i; //test linear limits - for(i = 0; i < 3; i++) + for (i = 0; i < 3; i++) { - if(m_linearLimits.needApplyForce(i)) + if (m_linearLimits.needApplyForce(i)) { info->m_numConstraintRows++; info->nub--; } } //test angular limits - for (i=0;i<3 ;i++ ) + for (i = 0; i < 3; i++) { - if(testAngularLimitMotor(i)) + if (testAngularLimitMotor(i)) { info->m_numConstraintRows++; info->nub--; @@ -551,13 +490,14 @@ void btGeneric6DofConstraint::getInfo1 (btConstraintInfo1* info) } } -void btGeneric6DofConstraint::getInfo1NonVirtual (btConstraintInfo1* info) +void btGeneric6DofConstraint::getInfo1NonVirtual(btConstraintInfo1* info) { if (m_useSolveConstraintObsolete) { info->m_numConstraintRows = 0; info->nub = 0; - } else + } + else { //pre-allocate all 6 info->m_numConstraintRows = 6; @@ -565,8 +505,7 @@ void btGeneric6DofConstraint::getInfo1NonVirtual (btConstraintInfo1* info) } } - -void btGeneric6DofConstraint::getInfo2 (btConstraintInfo2* info) +void btGeneric6DofConstraint::getInfo2(btConstraintInfo2* info) { btAssert(!m_useSolveConstraintObsolete); @@ -577,136 +516,124 @@ void btGeneric6DofConstraint::getInfo2 (btConstraintInfo2* info) const btVector3& angVelA = m_rbA.getAngularVelocity(); const btVector3& angVelB = m_rbB.getAngularVelocity(); - if(m_useOffsetForConstraintFrame) - { // for stability better to solve angular limits first - int row = setAngularLimits(info, 0,transA,transB,linVelA,linVelB,angVelA,angVelB); - setLinearLimits(info, row, transA,transB,linVelA,linVelB,angVelA,angVelB); + if (m_useOffsetForConstraintFrame) + { // for stability better to solve angular limits first + int row = setAngularLimits(info, 0, transA, transB, linVelA, linVelB, angVelA, angVelB); + setLinearLimits(info, row, transA, transB, linVelA, linVelB, angVelA, angVelB); } else - { // leave old version for compatibility - int row = setLinearLimits(info, 0, transA,transB,linVelA,linVelB,angVelA,angVelB); - setAngularLimits(info, row,transA,transB,linVelA,linVelB,angVelA,angVelB); + { // leave old version for compatibility + int row = setLinearLimits(info, 0, transA, transB, linVelA, linVelB, angVelA, angVelB); + setAngularLimits(info, row, transA, transB, linVelA, linVelB, angVelA, angVelB); } - } - -void btGeneric6DofConstraint::getInfo2NonVirtual (btConstraintInfo2* info, const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB) +void btGeneric6DofConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB) { - btAssert(!m_useSolveConstraintObsolete); //prepare constraint - calculateTransforms(transA,transB); + calculateTransforms(transA, transB); int i; - for (i=0;i<3 ;i++ ) + for (i = 0; i < 3; i++) { testAngularLimitMotor(i); } - if(m_useOffsetForConstraintFrame) - { // for stability better to solve angular limits first - int row = setAngularLimits(info, 0,transA,transB,linVelA,linVelB,angVelA,angVelB); - setLinearLimits(info, row, transA,transB,linVelA,linVelB,angVelA,angVelB); + if (m_useOffsetForConstraintFrame) + { // for stability better to solve angular limits first + int row = setAngularLimits(info, 0, transA, transB, linVelA, linVelB, angVelA, angVelB); + setLinearLimits(info, row, transA, transB, linVelA, linVelB, angVelA, angVelB); } else - { // leave old version for compatibility - int row = setLinearLimits(info, 0, transA,transB,linVelA,linVelB,angVelA,angVelB); - setAngularLimits(info, row,transA,transB,linVelA,linVelB,angVelA,angVelB); + { // leave old version for compatibility + int row = setLinearLimits(info, 0, transA, transB, linVelA, linVelB, angVelA, angVelB); + setAngularLimits(info, row, transA, transB, linVelA, linVelB, angVelA, angVelB); } } - - -int btGeneric6DofConstraint::setLinearLimits(btConstraintInfo2* info, int row, const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB) +int btGeneric6DofConstraint::setLinearLimits(btConstraintInfo2* info, int row, const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB) { -// int row = 0; + // int row = 0; //solve linear limits btRotationalLimitMotor limot; - for (int i=0;i<3 ;i++ ) + for (int i = 0; i < 3; i++) { - if(m_linearLimits.needApplyForce(i)) - { // re-use rotational motor code + if (m_linearLimits.needApplyForce(i)) + { // re-use rotational motor code limot.m_bounce = btScalar(0.f); limot.m_currentLimit = m_linearLimits.m_currentLimit[i]; limot.m_currentPosition = m_linearLimits.m_currentLinearDiff[i]; - limot.m_currentLimitError = m_linearLimits.m_currentLimitError[i]; - limot.m_damping = m_linearLimits.m_damping; - limot.m_enableMotor = m_linearLimits.m_enableMotor[i]; - limot.m_hiLimit = m_linearLimits.m_upperLimit[i]; - limot.m_limitSoftness = m_linearLimits.m_limitSoftness; - limot.m_loLimit = m_linearLimits.m_lowerLimit[i]; - limot.m_maxLimitForce = btScalar(0.f); - limot.m_maxMotorForce = m_linearLimits.m_maxMotorForce[i]; - limot.m_targetVelocity = m_linearLimits.m_targetVelocity[i]; + limot.m_currentLimitError = m_linearLimits.m_currentLimitError[i]; + limot.m_damping = m_linearLimits.m_damping; + limot.m_enableMotor = m_linearLimits.m_enableMotor[i]; + limot.m_hiLimit = m_linearLimits.m_upperLimit[i]; + limot.m_limitSoftness = m_linearLimits.m_limitSoftness; + limot.m_loLimit = m_linearLimits.m_lowerLimit[i]; + limot.m_maxLimitForce = btScalar(0.f); + limot.m_maxMotorForce = m_linearLimits.m_maxMotorForce[i]; + limot.m_targetVelocity = m_linearLimits.m_targetVelocity[i]; btVector3 axis = m_calculatedTransformA.getBasis().getColumn(i); int flags = m_flags >> (i * BT_6DOF_FLAGS_AXIS_SHIFT); - limot.m_normalCFM = (flags & BT_6DOF_FLAGS_CFM_NORM) ? m_linearLimits.m_normalCFM[i] : info->cfm[0]; - limot.m_stopCFM = (flags & BT_6DOF_FLAGS_CFM_STOP) ? m_linearLimits.m_stopCFM[i] : info->cfm[0]; - limot.m_stopERP = (flags & BT_6DOF_FLAGS_ERP_STOP) ? m_linearLimits.m_stopERP[i] : info->erp; - if(m_useOffsetForConstraintFrame) + limot.m_normalCFM = (flags & BT_6DOF_FLAGS_CFM_NORM) ? m_linearLimits.m_normalCFM[i] : info->cfm[0]; + limot.m_stopCFM = (flags & BT_6DOF_FLAGS_CFM_STOP) ? m_linearLimits.m_stopCFM[i] : info->cfm[0]; + limot.m_stopERP = (flags & BT_6DOF_FLAGS_ERP_STOP) ? m_linearLimits.m_stopERP[i] : info->erp; + if (m_useOffsetForConstraintFrame) { int indx1 = (i + 1) % 3; int indx2 = (i + 2) % 3; - int rotAllowed = 1; // rotations around orthos to current axis - if(m_angularLimits[indx1].m_currentLimit && m_angularLimits[indx2].m_currentLimit) + int rotAllowed = 1; // rotations around orthos to current axis + if (m_angularLimits[indx1].m_currentLimit && m_angularLimits[indx2].m_currentLimit) { rotAllowed = 0; } - row += get_limit_motor_info2(&limot, transA,transB,linVelA,linVelB,angVelA,angVelB, info, row, axis, 0, rotAllowed); + row += get_limit_motor_info2(&limot, transA, transB, linVelA, linVelB, angVelA, angVelB, info, row, axis, 0, rotAllowed); } else { - row += get_limit_motor_info2(&limot, transA,transB,linVelA,linVelB,angVelA,angVelB, info, row, axis, 0); + row += get_limit_motor_info2(&limot, transA, transB, linVelA, linVelB, angVelA, angVelB, info, row, axis, 0); } } } return row; } - - -int btGeneric6DofConstraint::setAngularLimits(btConstraintInfo2 *info, int row_offset, const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB) +int btGeneric6DofConstraint::setAngularLimits(btConstraintInfo2* info, int row_offset, const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB) { - btGeneric6DofConstraint * d6constraint = this; + btGeneric6DofConstraint* d6constraint = this; int row = row_offset; //solve angular limits - for (int i=0;i<3 ;i++ ) + for (int i = 0; i < 3; i++) { - if(d6constraint->getRotationalLimitMotor(i)->needApplyTorques()) + if (d6constraint->getRotationalLimitMotor(i)->needApplyTorques()) { btVector3 axis = d6constraint->getAxis(i); int flags = m_flags >> ((i + 3) * BT_6DOF_FLAGS_AXIS_SHIFT); - if(!(flags & BT_6DOF_FLAGS_CFM_NORM)) + if (!(flags & BT_6DOF_FLAGS_CFM_NORM)) { m_angularLimits[i].m_normalCFM = info->cfm[0]; } - if(!(flags & BT_6DOF_FLAGS_CFM_STOP)) + if (!(flags & BT_6DOF_FLAGS_CFM_STOP)) { m_angularLimits[i].m_stopCFM = info->cfm[0]; } - if(!(flags & BT_6DOF_FLAGS_ERP_STOP)) + if (!(flags & BT_6DOF_FLAGS_ERP_STOP)) { m_angularLimits[i].m_stopERP = info->erp; } row += get_limit_motor_info2(d6constraint->getRotationalLimitMotor(i), - transA,transB,linVelA,linVelB,angVelA,angVelB, info,row,axis,1); + transA, transB, linVelA, linVelB, angVelA, angVelB, info, row, axis, 1); } } return row; } - - - -void btGeneric6DofConstraint::updateRHS(btScalar timeStep) +void btGeneric6DofConstraint::updateRHS(btScalar timeStep) { (void)timeStep; - } - void btGeneric6DofConstraint::setFrames(const btTransform& frameA, const btTransform& frameB) { m_frameInA = frameA; @@ -715,33 +642,27 @@ void btGeneric6DofConstraint::setFrames(const btTransform& frameA, const btTrans calculateTransforms(); } - - btVector3 btGeneric6DofConstraint::getAxis(int axis_index) const { return m_calculatedAxis[axis_index]; } - -btScalar btGeneric6DofConstraint::getRelativePivotPosition(int axisIndex) const +btScalar btGeneric6DofConstraint::getRelativePivotPosition(int axisIndex) const { return m_calculatedLinearDiff[axisIndex]; } - btScalar btGeneric6DofConstraint::getAngle(int axisIndex) const { return m_calculatedAxisAngleDiff[axisIndex]; } - - void btGeneric6DofConstraint::calcAnchorPos(void) { btScalar imA = m_rbA.getInvMass(); btScalar imB = m_rbB.getInvMass(); btScalar weight; - if(imB == btScalar(0.0)) + if (imB == btScalar(0.0)) { weight = btScalar(1.0); } @@ -755,43 +676,39 @@ void btGeneric6DofConstraint::calcAnchorPos(void) return; } - - void btGeneric6DofConstraint::calculateLinearInfo() { m_calculatedLinearDiff = m_calculatedTransformB.getOrigin() - m_calculatedTransformA.getOrigin(); m_calculatedLinearDiff = m_calculatedTransformA.getBasis().inverse() * m_calculatedLinearDiff; - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { m_linearLimits.m_currentLinearDiff[i] = m_calculatedLinearDiff[i]; m_linearLimits.testLimitValue(i, m_calculatedLinearDiff[i]); } } - - int btGeneric6DofConstraint::get_limit_motor_info2( - btRotationalLimitMotor * limot, - const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB, - btConstraintInfo2 *info, int row, btVector3& ax1, int rotational,int rotAllowed) + btRotationalLimitMotor* limot, + const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB, + btConstraintInfo2* info, int row, btVector3& ax1, int rotational, int rotAllowed) { - int srow = row * info->rowskip; - bool powered = limot->m_enableMotor; - int limit = limot->m_currentLimit; - if (powered || limit) - { // if the joint is powered, or has joint limits, add in the extra row - btScalar *J1 = rotational ? info->m_J1angularAxis : info->m_J1linearAxis; - btScalar *J2 = rotational ? info->m_J2angularAxis : info->m_J2linearAxis; - J1[srow+0] = ax1[0]; - J1[srow+1] = ax1[1]; - J1[srow+2] = ax1[2]; + int srow = row * info->rowskip; + bool powered = limot->m_enableMotor; + int limit = limot->m_currentLimit; + if (powered || limit) + { // if the joint is powered, or has joint limits, add in the extra row + btScalar* J1 = rotational ? info->m_J1angularAxis : info->m_J1linearAxis; + btScalar* J2 = rotational ? info->m_J2angularAxis : info->m_J2linearAxis; + J1[srow + 0] = ax1[0]; + J1[srow + 1] = ax1[1]; + J1[srow + 2] = ax1[2]; - J2[srow+0] = -ax1[0]; - J2[srow+1] = -ax1[1]; - J2[srow+2] = -ax1[2]; + J2[srow + 0] = -ax1[0]; + J2[srow + 1] = -ax1[1]; + J2[srow + 2] = -ax1[2]; - if((!rotational)) - { + if ((!rotational)) + { if (m_useOffsetForConstraintFrame) { btVector3 tmpA, tmpB, relA, relB; @@ -814,55 +731,56 @@ int btGeneric6DofConstraint::get_limit_motor_info2( relB = orthoB - totalDist * m_factB; tmpA = relA.cross(ax1); tmpB = relB.cross(ax1); - if(m_hasStaticBody && (!rotAllowed)) + if (m_hasStaticBody && (!rotAllowed)) { tmpA *= m_factA; tmpB *= m_factB; } int i; - for (i=0; i<3; i++) info->m_J1angularAxis[srow+i] = tmpA[i]; - for (i=0; i<3; i++) info->m_J2angularAxis[srow+i] = -tmpB[i]; - } else + for (i = 0; i < 3; i++) info->m_J1angularAxis[srow + i] = tmpA[i]; + for (i = 0; i < 3; i++) info->m_J2angularAxis[srow + i] = -tmpB[i]; + } + else { - btVector3 ltd; // Linear Torque Decoupling vector + btVector3 ltd; // Linear Torque Decoupling vector btVector3 c = m_calculatedTransformB.getOrigin() - transA.getOrigin(); ltd = c.cross(ax1); - info->m_J1angularAxis[srow+0] = ltd[0]; - info->m_J1angularAxis[srow+1] = ltd[1]; - info->m_J1angularAxis[srow+2] = ltd[2]; + info->m_J1angularAxis[srow + 0] = ltd[0]; + info->m_J1angularAxis[srow + 1] = ltd[1]; + info->m_J1angularAxis[srow + 2] = ltd[2]; c = m_calculatedTransformB.getOrigin() - transB.getOrigin(); ltd = -c.cross(ax1); - info->m_J2angularAxis[srow+0] = ltd[0]; - info->m_J2angularAxis[srow+1] = ltd[1]; - info->m_J2angularAxis[srow+2] = ltd[2]; + info->m_J2angularAxis[srow + 0] = ltd[0]; + info->m_J2angularAxis[srow + 1] = ltd[1]; + info->m_J2angularAxis[srow + 2] = ltd[2]; } - } - // if we're limited low and high simultaneously, the joint motor is - // ineffective - if (limit && (limot->m_loLimit == limot->m_hiLimit)) powered = false; - info->m_constraintError[srow] = btScalar(0.f); - if (powered) - { + } + // if we're limited low and high simultaneously, the joint motor is + // ineffective + if (limit && (limot->m_loLimit == limot->m_hiLimit)) powered = false; + info->m_constraintError[srow] = btScalar(0.f); + if (powered) + { info->cfm[srow] = limot->m_normalCFM; - if(!limit) - { + if (!limit) + { btScalar tag_vel = rotational ? limot->m_targetVelocity : -limot->m_targetVelocity; - btScalar mot_fact = getMotorFactor( limot->m_currentPosition, - limot->m_loLimit, - limot->m_hiLimit, - tag_vel, - info->fps * limot->m_stopERP); + btScalar mot_fact = getMotorFactor(limot->m_currentPosition, + limot->m_loLimit, + limot->m_hiLimit, + tag_vel, + info->fps * limot->m_stopERP); info->m_constraintError[srow] += mot_fact * limot->m_targetVelocity; - info->m_lowerLimit[srow] = -limot->m_maxMotorForce / info->fps; - info->m_upperLimit[srow] = limot->m_maxMotorForce / info->fps; - } - } - if(limit) - { - btScalar k = info->fps * limot->m_stopERP; - if(!rotational) + info->m_lowerLimit[srow] = -limot->m_maxMotorForce / info->fps; + info->m_upperLimit[srow] = limot->m_maxMotorForce / info->fps; + } + } + if (limit) + { + btScalar k = info->fps * limot->m_stopERP; + if (!rotational) { info->m_constraintError[srow] += k * limot->m_currentLimitError; } @@ -871,116 +789,112 @@ int btGeneric6DofConstraint::get_limit_motor_info2( info->m_constraintError[srow] += -k * limot->m_currentLimitError; } info->cfm[srow] = limot->m_stopCFM; - if (limot->m_loLimit == limot->m_hiLimit) - { // limited low and high simultaneously - info->m_lowerLimit[srow] = -SIMD_INFINITY; - info->m_upperLimit[srow] = SIMD_INFINITY; - } - else - { - if (limit == 1) - { - info->m_lowerLimit[srow] = 0; - info->m_upperLimit[srow] = SIMD_INFINITY; - } - else - { - info->m_lowerLimit[srow] = -SIMD_INFINITY; - info->m_upperLimit[srow] = 0; - } - // deal with bounce - if (limot->m_bounce > 0) - { - // calculate joint velocity - btScalar vel; - if (rotational) - { - vel = angVelA.dot(ax1); -//make sure that if no body -> angVelB == zero vec -// if (body1) - vel -= angVelB.dot(ax1); - } - else - { - vel = linVelA.dot(ax1); -//make sure that if no body -> angVelB == zero vec -// if (body1) - vel -= linVelB.dot(ax1); - } - // only apply bounce if the velocity is incoming, and if the - // resulting c[] exceeds what we already have. - if (limit == 1) - { - if (vel < 0) - { - btScalar newc = -limot->m_bounce* vel; - if (newc > info->m_constraintError[srow]) + if (limot->m_loLimit == limot->m_hiLimit) + { // limited low and high simultaneously + info->m_lowerLimit[srow] = -SIMD_INFINITY; + info->m_upperLimit[srow] = SIMD_INFINITY; + } + else + { + if (limit == 1) + { + info->m_lowerLimit[srow] = 0; + info->m_upperLimit[srow] = SIMD_INFINITY; + } + else + { + info->m_lowerLimit[srow] = -SIMD_INFINITY; + info->m_upperLimit[srow] = 0; + } + // deal with bounce + if (limot->m_bounce > 0) + { + // calculate joint velocity + btScalar vel; + if (rotational) + { + vel = angVelA.dot(ax1); + //make sure that if no body -> angVelB == zero vec + // if (body1) + vel -= angVelB.dot(ax1); + } + else + { + vel = linVelA.dot(ax1); + //make sure that if no body -> angVelB == zero vec + // if (body1) + vel -= linVelB.dot(ax1); + } + // only apply bounce if the velocity is incoming, and if the + // resulting c[] exceeds what we already have. + if (limit == 1) + { + if (vel < 0) + { + btScalar newc = -limot->m_bounce * vel; + if (newc > info->m_constraintError[srow]) info->m_constraintError[srow] = newc; - } - } - else - { - if (vel > 0) - { - btScalar newc = -limot->m_bounce * vel; - if (newc < info->m_constraintError[srow]) + } + } + else + { + if (vel > 0) + { + btScalar newc = -limot->m_bounce * vel; + if (newc < info->m_constraintError[srow]) info->m_constraintError[srow] = newc; - } - } - } - } - } - return 1; - } - else return 0; + } + } + } + } + } + return 1; + } + else + return 0; } - - - - - - ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). - ///If no axis is provided, it uses the default axis for this constraint. +///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). +///If no axis is provided, it uses the default axis for this constraint. void btGeneric6DofConstraint::setParam(int num, btScalar value, int axis) { - if((axis >= 0) && (axis < 3)) + if ((axis >= 0) && (axis < 3)) { - switch(num) + switch (num) { - case BT_CONSTRAINT_STOP_ERP : + case BT_CONSTRAINT_STOP_ERP: m_linearLimits.m_stopERP[axis] = value; m_flags |= BT_6DOF_FLAGS_ERP_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT); break; - case BT_CONSTRAINT_STOP_CFM : + case BT_CONSTRAINT_STOP_CFM: m_linearLimits.m_stopCFM[axis] = value; m_flags |= BT_6DOF_FLAGS_CFM_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT); break; - case BT_CONSTRAINT_CFM : + case BT_CONSTRAINT_CFM: m_linearLimits.m_normalCFM[axis] = value; m_flags |= BT_6DOF_FLAGS_CFM_NORM << (axis * BT_6DOF_FLAGS_AXIS_SHIFT); break; - default : + default: btAssertConstrParams(0); } } - else if((axis >=3) && (axis < 6)) + else if ((axis >= 3) && (axis < 6)) { - switch(num) + switch (num) { - case BT_CONSTRAINT_STOP_ERP : + case BT_CONSTRAINT_STOP_ERP: m_angularLimits[axis - 3].m_stopERP = value; m_flags |= BT_6DOF_FLAGS_ERP_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT); break; - case BT_CONSTRAINT_STOP_CFM : + case BT_CONSTRAINT_STOP_CFM: m_angularLimits[axis - 3].m_stopCFM = value; m_flags |= BT_6DOF_FLAGS_CFM_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT); break; - case BT_CONSTRAINT_CFM : + case BT_CONSTRAINT_CFM: m_angularLimits[axis - 3].m_normalCFM = value; m_flags |= BT_6DOF_FLAGS_CFM_NORM << (axis * BT_6DOF_FLAGS_AXIS_SHIFT); break; - default : + default: btAssertConstrParams(0); } } @@ -990,47 +904,47 @@ void btGeneric6DofConstraint::setParam(int num, btScalar value, int axis) } } - ///return the local value of parameter -btScalar btGeneric6DofConstraint::getParam(int num, int axis) const +///return the local value of parameter +btScalar btGeneric6DofConstraint::getParam(int num, int axis) const { btScalar retVal = 0; - if((axis >= 0) && (axis < 3)) + if ((axis >= 0) && (axis < 3)) { - switch(num) + switch (num) { - case BT_CONSTRAINT_STOP_ERP : + case BT_CONSTRAINT_STOP_ERP: btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_ERP_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT))); retVal = m_linearLimits.m_stopERP[axis]; break; - case BT_CONSTRAINT_STOP_CFM : + case BT_CONSTRAINT_STOP_CFM: btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_CFM_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT))); retVal = m_linearLimits.m_stopCFM[axis]; break; - case BT_CONSTRAINT_CFM : + case BT_CONSTRAINT_CFM: btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_CFM_NORM << (axis * BT_6DOF_FLAGS_AXIS_SHIFT))); retVal = m_linearLimits.m_normalCFM[axis]; break; - default : + default: btAssertConstrParams(0); } } - else if((axis >=3) && (axis < 6)) + else if ((axis >= 3) && (axis < 6)) { - switch(num) + switch (num) { - case BT_CONSTRAINT_STOP_ERP : + case BT_CONSTRAINT_STOP_ERP: btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_ERP_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT))); retVal = m_angularLimits[axis - 3].m_stopERP; break; - case BT_CONSTRAINT_STOP_CFM : + case BT_CONSTRAINT_STOP_CFM: btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_CFM_STOP << (axis * BT_6DOF_FLAGS_AXIS_SHIFT))); retVal = m_angularLimits[axis - 3].m_stopCFM; break; - case BT_CONSTRAINT_CFM : + case BT_CONSTRAINT_CFM: btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_CFM_NORM << (axis * BT_6DOF_FLAGS_AXIS_SHIFT))); retVal = m_angularLimits[axis - 3].m_normalCFM; break; - default : + default: btAssertConstrParams(0); } } @@ -1041,23 +955,21 @@ btScalar btGeneric6DofConstraint::getParam(int num, int axis) const return retVal; } - - -void btGeneric6DofConstraint::setAxis(const btVector3& axis1,const btVector3& axis2) +void btGeneric6DofConstraint::setAxis(const btVector3& axis1, const btVector3& axis2) { btVector3 zAxis = axis1.normalized(); btVector3 yAxis = axis2.normalized(); - btVector3 xAxis = yAxis.cross(zAxis); // we want right coordinate system - + btVector3 xAxis = yAxis.cross(zAxis); // we want right coordinate system + btTransform frameInW; frameInW.setIdentity(); - frameInW.getBasis().setValue( xAxis[0], yAxis[0], zAxis[0], - xAxis[1], yAxis[1], zAxis[1], - xAxis[2], yAxis[2], zAxis[2]); - + frameInW.getBasis().setValue(xAxis[0], yAxis[0], zAxis[0], + xAxis[1], yAxis[1], zAxis[1], + xAxis[2], yAxis[2], zAxis[2]); + // now get constraint frame in local coordinate systems m_frameInA = m_rbA.getCenterOfMassTransform().inverse() * frameInW; m_frameInB = m_rbB.getCenterOfMassTransform().inverse() * frameInW; - + calculateTransforms(); } diff --git a/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h b/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h index b2ad45f74..b9e762e17 100644 --- a/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h +++ b/src/BulletDynamics/ConstraintSolver/btGeneric6DofConstraint.h @@ -23,7 +23,6 @@ email: projectileman@yahoo.com http://gimpact.sf.net */ - #ifndef BT_GENERIC_6DOF_CONSTRAINT_H #define BT_GENERIC_6DOF_CONSTRAINT_H @@ -33,96 +32,91 @@ http://gimpact.sf.net class btRigidBody; - - #ifdef BT_USE_DOUBLE_PRECISION -#define btGeneric6DofConstraintData2 btGeneric6DofConstraintDoubleData2 -#define btGeneric6DofConstraintDataName "btGeneric6DofConstraintDoubleData2" +#define btGeneric6DofConstraintData2 btGeneric6DofConstraintDoubleData2 +#define btGeneric6DofConstraintDataName "btGeneric6DofConstraintDoubleData2" #else -#define btGeneric6DofConstraintData2 btGeneric6DofConstraintData -#define btGeneric6DofConstraintDataName "btGeneric6DofConstraintData" -#endif //BT_USE_DOUBLE_PRECISION - +#define btGeneric6DofConstraintData2 btGeneric6DofConstraintData +#define btGeneric6DofConstraintDataName "btGeneric6DofConstraintData" +#endif //BT_USE_DOUBLE_PRECISION //! Rotation Limit structure for generic joints class btRotationalLimitMotor { public: - //! limit_parameters - //!@{ - btScalar m_loLimit;//!< joint limit - btScalar m_hiLimit;//!< joint limit - btScalar m_targetVelocity;//!< target motor velocity - btScalar m_maxMotorForce;//!< max force on motor - btScalar m_maxLimitForce;//!< max force on limit - btScalar m_damping;//!< Damping. - btScalar m_limitSoftness;//! Relaxation factor - btScalar m_normalCFM;//!< Constraint force mixing factor - btScalar m_stopERP;//!< Error tolerance factor when joint is at limit - btScalar m_stopCFM;//!< Constraint force mixing factor when joint is at limit - btScalar m_bounce;//!< restitution factor - bool m_enableMotor; + //! limit_parameters + //!@{ + btScalar m_loLimit; //!< joint limit + btScalar m_hiLimit; //!< joint limit + btScalar m_targetVelocity; //!< target motor velocity + btScalar m_maxMotorForce; //!< max force on motor + btScalar m_maxLimitForce; //!< max force on limit + btScalar m_damping; //!< Damping. + btScalar m_limitSoftness; //! Relaxation factor + btScalar m_normalCFM; //!< Constraint force mixing factor + btScalar m_stopERP; //!< Error tolerance factor when joint is at limit + btScalar m_stopCFM; //!< Constraint force mixing factor when joint is at limit + btScalar m_bounce; //!< restitution factor + bool m_enableMotor; - //!@} + //!@} - //! temp_variables - //!@{ - btScalar m_currentLimitError;//! How much is violated this limit - btScalar m_currentPosition; //! current value of angle - int m_currentLimit;//!< 0=free, 1=at lo limit, 2=at hi limit - btScalar m_accumulatedImpulse; - //!@} + //! temp_variables + //!@{ + btScalar m_currentLimitError; //! How much is violated this limit + btScalar m_currentPosition; //! current value of angle + int m_currentLimit; //!< 0=free, 1=at lo limit, 2=at hi limit + btScalar m_accumulatedImpulse; + //!@} - btRotationalLimitMotor() - { - m_accumulatedImpulse = 0.f; - m_targetVelocity = 0; - m_maxMotorForce = 6.0f; - m_maxLimitForce = 300.0f; - m_loLimit = 1.0f; - m_hiLimit = -1.0f; + btRotationalLimitMotor() + { + m_accumulatedImpulse = 0.f; + m_targetVelocity = 0; + m_maxMotorForce = 6.0f; + m_maxLimitForce = 300.0f; + m_loLimit = 1.0f; + m_hiLimit = -1.0f; m_normalCFM = 0.f; m_stopERP = 0.2f; m_stopCFM = 0.f; - m_bounce = 0.0f; - m_damping = 1.0f; - m_limitSoftness = 0.5f; - m_currentLimit = 0; - m_currentLimitError = 0; - m_enableMotor = false; - } + m_bounce = 0.0f; + m_damping = 1.0f; + m_limitSoftness = 0.5f; + m_currentLimit = 0; + m_currentLimitError = 0; + m_enableMotor = false; + } - btRotationalLimitMotor(const btRotationalLimitMotor & limot) - { - m_targetVelocity = limot.m_targetVelocity; - m_maxMotorForce = limot.m_maxMotorForce; - m_limitSoftness = limot.m_limitSoftness; - m_loLimit = limot.m_loLimit; - m_hiLimit = limot.m_hiLimit; + btRotationalLimitMotor(const btRotationalLimitMotor& limot) + { + m_targetVelocity = limot.m_targetVelocity; + m_maxMotorForce = limot.m_maxMotorForce; + m_limitSoftness = limot.m_limitSoftness; + m_loLimit = limot.m_loLimit; + m_hiLimit = limot.m_hiLimit; m_normalCFM = limot.m_normalCFM; m_stopERP = limot.m_stopERP; - m_stopCFM = limot.m_stopCFM; - m_bounce = limot.m_bounce; - m_currentLimit = limot.m_currentLimit; - m_currentLimitError = limot.m_currentLimitError; - m_enableMotor = limot.m_enableMotor; - } - - + m_stopCFM = limot.m_stopCFM; + m_bounce = limot.m_bounce; + m_currentLimit = limot.m_currentLimit; + m_currentLimitError = limot.m_currentLimitError; + m_enableMotor = limot.m_enableMotor; + } //! Is limited - bool isLimited() const - { - if(m_loLimit > m_hiLimit) return false; - return true; - } + bool isLimited() const + { + if (m_loLimit > m_hiLimit) return false; + return true; + } //! Need apply correction - bool needApplyTorques() const - { - if(m_currentLimit == 0 && m_enableMotor == false) return false; - return true; - } + bool needApplyTorques() const + { + if (m_currentLimit == 0 && m_enableMotor == false) return false; + return true; + } //! calculates error /*! @@ -131,104 +125,98 @@ public: int testLimitValue(btScalar test_value); //! apply the correction impulses for two bodies - btScalar solveAngularLimits(btScalar timeStep,btVector3& axis, btScalar jacDiagABInv,btRigidBody * body0, btRigidBody * body1); - + btScalar solveAngularLimits(btScalar timeStep, btVector3& axis, btScalar jacDiagABInv, btRigidBody* body0, btRigidBody* body1); }; - - class btTranslationalLimitMotor { public: - btVector3 m_lowerLimit;//!< the constraint lower limits - btVector3 m_upperLimit;//!< the constraint upper limits - btVector3 m_accumulatedImpulse; - //! Linear_Limit_parameters - //!@{ - btScalar m_limitSoftness;//!< Softness for linear limit - btScalar m_damping;//!< Damping for linear limit - btScalar m_restitution;//! Bounce parameter for linear limit - btVector3 m_normalCFM;//!< Constraint force mixing factor - btVector3 m_stopERP;//!< Error tolerance factor when joint is at limit - btVector3 m_stopCFM;//!< Constraint force mixing factor when joint is at limit - //!@} - bool m_enableMotor[3]; - btVector3 m_targetVelocity;//!< target motor velocity - btVector3 m_maxMotorForce;//!< max force on motor - btVector3 m_currentLimitError;//! How much is violated this limit - btVector3 m_currentLinearDiff;//! Current relative offset of constraint frames - int m_currentLimit[3];//!< 0=free, 1=at lower limit, 2=at upper limit + btVector3 m_lowerLimit; //!< the constraint lower limits + btVector3 m_upperLimit; //!< the constraint upper limits + btVector3 m_accumulatedImpulse; + //! Linear_Limit_parameters + //!@{ + btScalar m_limitSoftness; //!< Softness for linear limit + btScalar m_damping; //!< Damping for linear limit + btScalar m_restitution; //! Bounce parameter for linear limit + btVector3 m_normalCFM; //!< Constraint force mixing factor + btVector3 m_stopERP; //!< Error tolerance factor when joint is at limit + btVector3 m_stopCFM; //!< Constraint force mixing factor when joint is at limit + //!@} + bool m_enableMotor[3]; + btVector3 m_targetVelocity; //!< target motor velocity + btVector3 m_maxMotorForce; //!< max force on motor + btVector3 m_currentLimitError; //! How much is violated this limit + btVector3 m_currentLinearDiff; //! Current relative offset of constraint frames + int m_currentLimit[3]; //!< 0=free, 1=at lower limit, 2=at upper limit - btTranslationalLimitMotor() - { - m_lowerLimit.setValue(0.f,0.f,0.f); - m_upperLimit.setValue(0.f,0.f,0.f); - m_accumulatedImpulse.setValue(0.f,0.f,0.f); + btTranslationalLimitMotor() + { + m_lowerLimit.setValue(0.f, 0.f, 0.f); + m_upperLimit.setValue(0.f, 0.f, 0.f); + m_accumulatedImpulse.setValue(0.f, 0.f, 0.f); m_normalCFM.setValue(0.f, 0.f, 0.f); m_stopERP.setValue(0.2f, 0.2f, 0.2f); m_stopCFM.setValue(0.f, 0.f, 0.f); - m_limitSoftness = 0.7f; - m_damping = btScalar(1.0f); - m_restitution = btScalar(0.5f); - for(int i=0; i < 3; i++) + m_limitSoftness = 0.7f; + m_damping = btScalar(1.0f); + m_restitution = btScalar(0.5f); + for (int i = 0; i < 3; i++) { m_enableMotor[i] = false; m_targetVelocity[i] = btScalar(0.f); m_maxMotorForce[i] = btScalar(0.f); } - } + } - btTranslationalLimitMotor(const btTranslationalLimitMotor & other ) - { - m_lowerLimit = other.m_lowerLimit; - m_upperLimit = other.m_upperLimit; - m_accumulatedImpulse = other.m_accumulatedImpulse; + btTranslationalLimitMotor(const btTranslationalLimitMotor& other) + { + m_lowerLimit = other.m_lowerLimit; + m_upperLimit = other.m_upperLimit; + m_accumulatedImpulse = other.m_accumulatedImpulse; - m_limitSoftness = other.m_limitSoftness ; - m_damping = other.m_damping; - m_restitution = other.m_restitution; + m_limitSoftness = other.m_limitSoftness; + m_damping = other.m_damping; + m_restitution = other.m_restitution; m_normalCFM = other.m_normalCFM; m_stopERP = other.m_stopERP; m_stopCFM = other.m_stopCFM; - for(int i=0; i < 3; i++) + for (int i = 0; i < 3; i++) { m_enableMotor[i] = other.m_enableMotor[i]; m_targetVelocity[i] = other.m_targetVelocity[i]; m_maxMotorForce[i] = other.m_maxMotorForce[i]; } - } + } - //! Test limit + //! Test limit /*! - free means upper < lower, - locked means upper == lower - limited means upper > lower - limitIndex: first 3 are linear, next 3 are angular */ - inline bool isLimited(int limitIndex) const - { - return (m_upperLimit[limitIndex] >= m_lowerLimit[limitIndex]); - } - inline bool needApplyForce(int limitIndex) const - { - if(m_currentLimit[limitIndex] == 0 && m_enableMotor[limitIndex] == false) return false; - return true; - } + inline bool isLimited(int limitIndex) const + { + return (m_upperLimit[limitIndex] >= m_lowerLimit[limitIndex]); + } + inline bool needApplyForce(int limitIndex) const + { + if (m_currentLimit[limitIndex] == 0 && m_enableMotor[limitIndex] == false) return false; + return true; + } int testLimitValue(int limitIndex, btScalar test_value); - - btScalar solveLinearAxis( - btScalar timeStep, - btScalar jacDiagABInv, - btRigidBody& body1,const btVector3 &pointInA, - btRigidBody& body2,const btVector3 &pointInB, - int limit_index, - const btVector3 & axis_normal_on_a, - const btVector3 & anchorPos); - - + btScalar solveLinearAxis( + btScalar timeStep, + btScalar jacDiagABInv, + btRigidBody& body1, const btVector3& pointInA, + btRigidBody& body2, const btVector3& pointInB, + int limit_index, + const btVector3& axis_normal_on_a, + const btVector3& anchorPos); }; enum bt6DofFlags @@ -237,8 +225,7 @@ enum bt6DofFlags BT_6DOF_FLAGS_CFM_STOP = 2, BT_6DOF_FLAGS_ERP_STOP = 4 }; -#define BT_6DOF_FLAGS_AXIS_SHIFT 3 // bits per axis - +#define BT_6DOF_FLAGS_AXIS_SHIFT 3 // bits per axis /// btGeneric6DofConstraint between two rigidbodies each with a pivotpoint that descibes the axis location in local space /*! @@ -276,254 +263,245 @@ This brings support for limit parameters and motors.
  • */ -ATTRIBUTE_ALIGNED16(class) btGeneric6DofConstraint : public btTypedConstraint +ATTRIBUTE_ALIGNED16(class) +btGeneric6DofConstraint : public btTypedConstraint { protected: - //! relative_frames - //!@{ - btTransform m_frameInA;//!< the constraint space w.r.t body A - btTransform m_frameInB;//!< the constraint space w.r.t body B - //!@} - - //! Jacobians - //!@{ - btJacobianEntry m_jacLinear[3];//!< 3 orthogonal linear constraints - btJacobianEntry m_jacAng[3];//!< 3 orthogonal angular constraints - //!@} - - //! Linear_Limit_parameters - //!@{ - btTranslationalLimitMotor m_linearLimits; - //!@} - - - //! hinge_parameters - //!@{ - btRotationalLimitMotor m_angularLimits[3]; + //!@{ + btTransform m_frameInA; //!< the constraint space w.r.t body A + btTransform m_frameInB; //!< the constraint space w.r.t body B //!@} + //! Jacobians + //!@{ + btJacobianEntry m_jacLinear[3]; //!< 3 orthogonal linear constraints + btJacobianEntry m_jacAng[3]; //!< 3 orthogonal angular constraints + //!@} + + //! Linear_Limit_parameters + //!@{ + btTranslationalLimitMotor m_linearLimits; + //!@} + + //! hinge_parameters + //!@{ + btRotationalLimitMotor m_angularLimits[3]; + //!@} protected: - //! temporal variables - //!@{ - btScalar m_timeStep; - btTransform m_calculatedTransformA; - btTransform m_calculatedTransformB; - btVector3 m_calculatedAxisAngleDiff; - btVector3 m_calculatedAxis[3]; - btVector3 m_calculatedLinearDiff; - btScalar m_factA; - btScalar m_factB; - bool m_hasStaticBody; - - btVector3 m_AnchorPos; // point betwen pivots of bodies A and B to solve linear axes + //! temporal variables + //!@{ + btScalar m_timeStep; + btTransform m_calculatedTransformA; + btTransform m_calculatedTransformB; + btVector3 m_calculatedAxisAngleDiff; + btVector3 m_calculatedAxis[3]; + btVector3 m_calculatedLinearDiff; + btScalar m_factA; + btScalar m_factB; + bool m_hasStaticBody; - bool m_useLinearReferenceFrameA; - bool m_useOffsetForConstraintFrame; - - int m_flags; + btVector3 m_AnchorPos; // point betwen pivots of bodies A and B to solve linear axes - //!@} + bool m_useLinearReferenceFrameA; + bool m_useOffsetForConstraintFrame; - btGeneric6DofConstraint& operator=(btGeneric6DofConstraint& other) - { - btAssert(0); - (void) other; - return *this; - } + int m_flags; + //!@} - int setAngularLimits(btConstraintInfo2 *info, int row_offset,const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB); + btGeneric6DofConstraint& operator=(btGeneric6DofConstraint& other) + { + btAssert(0); + (void)other; + return *this; + } - int setLinearLimits(btConstraintInfo2 *info, int row, const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB); + int setAngularLimits(btConstraintInfo2 * info, int row_offset, const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB); - void buildLinearJacobian( - btJacobianEntry & jacLinear,const btVector3 & normalWorld, - const btVector3 & pivotAInW,const btVector3 & pivotBInW); + int setLinearLimits(btConstraintInfo2 * info, int row, const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB); - void buildAngularJacobian(btJacobianEntry & jacAngular,const btVector3 & jointAxisW); + void buildLinearJacobian( + btJacobianEntry & jacLinear, const btVector3& normalWorld, + const btVector3& pivotAInW, const btVector3& pivotBInW); + + void buildAngularJacobian(btJacobianEntry & jacAngular, const btVector3& jointAxisW); // tests linear limits void calculateLinearInfo(); //! calcs the euler angles between the two bodies. - void calculateAngleInfo(); - - + void calculateAngleInfo(); public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - - ///for backwards compatibility during the transition to 'getInfo/getInfo2' - bool m_useSolveConstraintObsolete; - btGeneric6DofConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA); - btGeneric6DofConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB); - + ///for backwards compatibility during the transition to 'getInfo/getInfo2' + bool m_useSolveConstraintObsolete; + + btGeneric6DofConstraint(btRigidBody & rbA, btRigidBody & rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA); + btGeneric6DofConstraint(btRigidBody & rbB, const btTransform& frameInB, bool useLinearReferenceFrameB); + //! Calcs global transform of the offsets /*! Calcs the global transform for the joint offset for body A an B, and also calcs the agle differences between the bodies. \sa btGeneric6DofConstraint.getCalculatedTransformA , btGeneric6DofConstraint.getCalculatedTransformB, btGeneric6DofConstraint.calculateAngleInfo */ - void calculateTransforms(const btTransform& transA,const btTransform& transB); + void calculateTransforms(const btTransform& transA, const btTransform& transB); void calculateTransforms(); //! Gets the global transform of the offset for body A - /*! + /*! \sa btGeneric6DofConstraint.getFrameOffsetA, btGeneric6DofConstraint.getFrameOffsetB, btGeneric6DofConstraint.calculateAngleInfo. */ - const btTransform & getCalculatedTransformA() const - { - return m_calculatedTransformA; - } + const btTransform& getCalculatedTransformA() const + { + return m_calculatedTransformA; + } - //! Gets the global transform of the offset for body B - /*! + //! Gets the global transform of the offset for body B + /*! \sa btGeneric6DofConstraint.getFrameOffsetA, btGeneric6DofConstraint.getFrameOffsetB, btGeneric6DofConstraint.calculateAngleInfo. */ - const btTransform & getCalculatedTransformB() const - { - return m_calculatedTransformB; - } + const btTransform& getCalculatedTransformB() const + { + return m_calculatedTransformB; + } - const btTransform & getFrameOffsetA() const - { - return m_frameInA; - } + const btTransform& getFrameOffsetA() const + { + return m_frameInA; + } - const btTransform & getFrameOffsetB() const - { - return m_frameInB; - } + const btTransform& getFrameOffsetB() const + { + return m_frameInB; + } + btTransform& getFrameOffsetA() + { + return m_frameInA; + } - btTransform & getFrameOffsetA() - { - return m_frameInA; - } - - btTransform & getFrameOffsetB() - { - return m_frameInB; - } - + btTransform& getFrameOffsetB() + { + return m_frameInB; + } //! performs Jacobian calculation, and also calculates angle differences and axis - virtual void buildJacobian(); + virtual void buildJacobian(); - virtual void getInfo1 (btConstraintInfo1* info); + virtual void getInfo1(btConstraintInfo1 * info); - void getInfo1NonVirtual (btConstraintInfo1* info); + void getInfo1NonVirtual(btConstraintInfo1 * info); - virtual void getInfo2 (btConstraintInfo2* info); + virtual void getInfo2(btConstraintInfo2 * info); - void getInfo2NonVirtual (btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB); + void getInfo2NonVirtual(btConstraintInfo2 * info, const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB); - - void updateRHS(btScalar timeStep); + void updateRHS(btScalar timeStep); //! Get the rotation axis in global coordinates /*! \pre btGeneric6DofConstraint.buildJacobian must be called previously. */ - btVector3 getAxis(int axis_index) const; + btVector3 getAxis(int axis_index) const; - //! Get the relative Euler angle - /*! + //! Get the relative Euler angle + /*! \pre btGeneric6DofConstraint::calculateTransforms() must be called previously. */ - btScalar getAngle(int axis_index) const; + btScalar getAngle(int axis_index) const; //! Get the relative position of the constraint pivot - /*! + /*! \pre btGeneric6DofConstraint::calculateTransforms() must be called previously. */ btScalar getRelativePivotPosition(int axis_index) const; - void setFrames(const btTransform & frameA, const btTransform & frameB); + void setFrames(const btTransform& frameA, const btTransform& frameB); //! Test angular limit. /*! Calculates angular correction and returns true if limit needs to be corrected. \pre btGeneric6DofConstraint::calculateTransforms() must be called previously. */ - bool testAngularLimitMotor(int axis_index); + bool testAngularLimitMotor(int axis_index); - void setLinearLowerLimit(const btVector3& linearLower) - { - m_linearLimits.m_lowerLimit = linearLower; - } + void setLinearLowerLimit(const btVector3& linearLower) + { + m_linearLimits.m_lowerLimit = linearLower; + } - void getLinearLowerLimit(btVector3& linearLower) const + void getLinearLowerLimit(btVector3 & linearLower) const { linearLower = m_linearLimits.m_lowerLimit; } - void setLinearUpperLimit(const btVector3& linearUpper) + void setLinearUpperLimit(const btVector3& linearUpper) { m_linearLimits.m_upperLimit = linearUpper; } - void getLinearUpperLimit(btVector3& linearUpper) const + void getLinearUpperLimit(btVector3 & linearUpper) const { linearUpper = m_linearLimits.m_upperLimit; } - void setAngularLowerLimit(const btVector3& angularLower) - { - for(int i = 0; i < 3; i++) - m_angularLimits[i].m_loLimit = btNormalizeAngle(angularLower[i]); - } - - void getAngularLowerLimit(btVector3& angularLower) const + void setAngularLowerLimit(const btVector3& angularLower) { - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) + m_angularLimits[i].m_loLimit = btNormalizeAngle(angularLower[i]); + } + + void getAngularLowerLimit(btVector3 & angularLower) const + { + for (int i = 0; i < 3; i++) angularLower[i] = m_angularLimits[i].m_loLimit; } - void setAngularUpperLimit(const btVector3& angularUpper) - { - for(int i = 0; i < 3; i++) - m_angularLimits[i].m_hiLimit = btNormalizeAngle(angularUpper[i]); - } - - void getAngularUpperLimit(btVector3& angularUpper) const + void setAngularUpperLimit(const btVector3& angularUpper) { - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) + m_angularLimits[i].m_hiLimit = btNormalizeAngle(angularUpper[i]); + } + + void getAngularUpperLimit(btVector3 & angularUpper) const + { + for (int i = 0; i < 3; i++) angularUpper[i] = m_angularLimits[i].m_hiLimit; } //! Retrieves the angular limit informacion - btRotationalLimitMotor * getRotationalLimitMotor(int index) - { - return &m_angularLimits[index]; - } + btRotationalLimitMotor* getRotationalLimitMotor(int index) + { + return &m_angularLimits[index]; + } - //! Retrieves the limit informacion - btTranslationalLimitMotor * getTranslationalLimitMotor() - { - return &m_linearLimits; - } + //! Retrieves the limit informacion + btTranslationalLimitMotor* getTranslationalLimitMotor() + { + return &m_linearLimits; + } - //first 3 are linear, next 3 are angular - void setLimit(int axis, btScalar lo, btScalar hi) - { - if(axis<3) - { - m_linearLimits.m_lowerLimit[axis] = lo; - m_linearLimits.m_upperLimit[axis] = hi; - } - else - { + //first 3 are linear, next 3 are angular + void setLimit(int axis, btScalar lo, btScalar hi) + { + if (axis < 3) + { + m_linearLimits.m_lowerLimit[axis] = lo; + m_linearLimits.m_upperLimit[axis] = hi; + } + else + { lo = btNormalizeAngle(lo); hi = btNormalizeAngle(hi); - m_angularLimits[axis-3].m_loLimit = lo; - m_angularLimits[axis-3].m_hiLimit = hi; - } - } + m_angularLimits[axis - 3].m_loLimit = lo; + m_angularLimits[axis - 3].m_hiLimit = hi; + } + } //! Test limit /*! @@ -532,116 +510,106 @@ public: - limited means upper > lower - limitIndex: first 3 are linear, next 3 are angular */ - bool isLimited(int limitIndex) const - { - if(limitIndex<3) - { + bool isLimited(int limitIndex) const + { + if (limitIndex < 3) + { return m_linearLimits.isLimited(limitIndex); + } + return m_angularLimits[limitIndex - 3].isLimited(); + } - } - return m_angularLimits[limitIndex-3].isLimited(); - } + virtual void calcAnchorPos(void); // overridable - virtual void calcAnchorPos(void); // overridable - - int get_limit_motor_info2( btRotationalLimitMotor * limot, - const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB, - btConstraintInfo2 *info, int row, btVector3& ax1, int rotational, int rotAllowed = false); + int get_limit_motor_info2(btRotationalLimitMotor * limot, + const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB, + btConstraintInfo2* info, int row, btVector3& ax1, int rotational, int rotAllowed = false); // access for UseFrameOffset bool getUseFrameOffset() const { return m_useOffsetForConstraintFrame; } void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; } - + bool getUseLinearReferenceFrameA() const { return m_useLinearReferenceFrameA; } void setUseLinearReferenceFrameA(bool linearReferenceFrameA) { m_useLinearReferenceFrameA = linearReferenceFrameA; } - ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). + ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). ///If no axis is provided, it uses the default axis for this constraint. - virtual void setParam(int num, btScalar value, int axis = -1); + virtual void setParam(int num, btScalar value, int axis = -1); ///return the local value of parameter - virtual btScalar getParam(int num, int axis = -1) const; + virtual btScalar getParam(int num, int axis = -1) const; - void setAxis( const btVector3& axis1, const btVector3& axis2); + void setAxis(const btVector3& axis1, const btVector3& axis2); - virtual int getFlags() const - { - return m_flags; + virtual int getFlags() const + { + return m_flags; } - virtual int calculateSerializeBufferSize() const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; - - + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; }; - struct btGeneric6DofConstraintData { - btTypedConstraintData m_typeConstraintData; - btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis. + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis. btTransformFloatData m_rbBFrame; - - btVector3FloatData m_linearUpperLimit; - btVector3FloatData m_linearLowerLimit; - btVector3FloatData m_angularUpperLimit; - btVector3FloatData m_angularLowerLimit; - - int m_useLinearReferenceFrameA; + btVector3FloatData m_linearUpperLimit; + btVector3FloatData m_linearLowerLimit; + + btVector3FloatData m_angularUpperLimit; + btVector3FloatData m_angularLowerLimit; + + int m_useLinearReferenceFrameA; int m_useOffsetForConstraintFrame; }; struct btGeneric6DofConstraintDoubleData2 { - btTypedConstraintDoubleData m_typeConstraintData; - btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis. + btTypedConstraintDoubleData m_typeConstraintData; + btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis. btTransformDoubleData m_rbBFrame; - - btVector3DoubleData m_linearUpperLimit; - btVector3DoubleData m_linearLowerLimit; - btVector3DoubleData m_angularUpperLimit; - btVector3DoubleData m_angularLowerLimit; - - int m_useLinearReferenceFrameA; + btVector3DoubleData m_linearUpperLimit; + btVector3DoubleData m_linearLowerLimit; + + btVector3DoubleData m_angularUpperLimit; + btVector3DoubleData m_angularLowerLimit; + + int m_useLinearReferenceFrameA; int m_useOffsetForConstraintFrame; }; -SIMD_FORCE_INLINE int btGeneric6DofConstraint::calculateSerializeBufferSize() const +SIMD_FORCE_INLINE int btGeneric6DofConstraint::calculateSerializeBufferSize() const { return sizeof(btGeneric6DofConstraintData2); } - ///fills the dataBuffer and returns the struct name (and 0 on failure) -SIMD_FORCE_INLINE const char* btGeneric6DofConstraint::serialize(void* dataBuffer, btSerializer* serializer) const +///fills the dataBuffer and returns the struct name (and 0 on failure) +SIMD_FORCE_INLINE const char* btGeneric6DofConstraint::serialize(void* dataBuffer, btSerializer* serializer) const { - btGeneric6DofConstraintData2* dof = (btGeneric6DofConstraintData2*)dataBuffer; - btTypedConstraint::serialize(&dof->m_typeConstraintData,serializer); + btTypedConstraint::serialize(&dof->m_typeConstraintData, serializer); m_frameInA.serialize(dof->m_rbAFrame); m_frameInB.serialize(dof->m_rbBFrame); - int i; - for (i=0;i<3;i++) + for (i = 0; i < 3; i++) { - dof->m_angularLowerLimit.m_floats[i] = m_angularLimits[i].m_loLimit; - dof->m_angularUpperLimit.m_floats[i] = m_angularLimits[i].m_hiLimit; + dof->m_angularLowerLimit.m_floats[i] = m_angularLimits[i].m_loLimit; + dof->m_angularUpperLimit.m_floats[i] = m_angularLimits[i].m_hiLimit; dof->m_linearLowerLimit.m_floats[i] = m_linearLimits.m_lowerLimit[i]; dof->m_linearUpperLimit.m_floats[i] = m_linearLimits.m_upperLimit[i]; } - - dof->m_useLinearReferenceFrameA = m_useLinearReferenceFrameA? 1 : 0; + + dof->m_useLinearReferenceFrameA = m_useLinearReferenceFrameA ? 1 : 0; dof->m_useOffsetForConstraintFrame = m_useOffsetForConstraintFrame ? 1 : 0; return btGeneric6DofConstraintDataName; } - - - - -#endif //BT_GENERIC_6DOF_CONSTRAINT_H +#endif //BT_GENERIC_6DOF_CONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp b/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp index 611b30342..7d972ca2b 100644 --- a/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp +++ b/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.cpp @@ -37,67 +37,54 @@ email: projectileman@yahoo.com http://gimpact.sf.net */ - - #include "btGeneric6DofSpring2Constraint.h" #include "BulletDynamics/Dynamics/btRigidBody.h" #include "LinearMath/btTransformUtil.h" #include - - btGeneric6DofSpring2Constraint::btGeneric6DofSpring2Constraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, RotateOrder rotOrder) - : btTypedConstraint(D6_SPRING_2_CONSTRAINT_TYPE, rbA, rbB) - , m_frameInA(frameInA) - , m_frameInB(frameInB) - , m_rotateOrder(rotOrder) - , m_flags(0) + : btTypedConstraint(D6_SPRING_2_CONSTRAINT_TYPE, rbA, rbB), m_frameInA(frameInA), m_frameInB(frameInB), m_rotateOrder(rotOrder), m_flags(0) { calculateTransforms(); } - btGeneric6DofSpring2Constraint::btGeneric6DofSpring2Constraint(btRigidBody& rbB, const btTransform& frameInB, RotateOrder rotOrder) - : btTypedConstraint(D6_SPRING_2_CONSTRAINT_TYPE, getFixedBody(), rbB) - , m_frameInB(frameInB) - , m_rotateOrder(rotOrder) - , m_flags(0) + : btTypedConstraint(D6_SPRING_2_CONSTRAINT_TYPE, getFixedBody(), rbB), m_frameInB(frameInB), m_rotateOrder(rotOrder), m_flags(0) { ///not providing rigidbody A means implicitly using worldspace for body A m_frameInA = rbB.getCenterOfMassTransform() * m_frameInB; calculateTransforms(); } - btScalar btGeneric6DofSpring2Constraint::btGetMatrixElem(const btMatrix3x3& mat, int index) { - int i = index%3; - int j = index/3; + int i = index % 3; + int j = index / 3; return mat[i][j]; } // MatrixToEulerXYZ from http://www.geometrictools.com/LibFoundation/Mathematics/Wm4Matrix3.inl.html -bool btGeneric6DofSpring2Constraint::matrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz) +bool btGeneric6DofSpring2Constraint::matrixToEulerXYZ(const btMatrix3x3& mat, btVector3& xyz) { // rot = cy*cz -cy*sz sy // cz*sx*sy+cx*sz cx*cz-sx*sy*sz -cy*sx // -cx*cz*sy+sx*sz cz*sx+cx*sy*sz cx*cy - btScalar fi = btGetMatrixElem(mat,2); + btScalar fi = btGetMatrixElem(mat, 2); if (fi < btScalar(1.0f)) { if (fi > btScalar(-1.0f)) { - xyz[0] = btAtan2(-btGetMatrixElem(mat,5),btGetMatrixElem(mat,8)); - xyz[1] = btAsin(btGetMatrixElem(mat,2)); - xyz[2] = btAtan2(-btGetMatrixElem(mat,1),btGetMatrixElem(mat,0)); + xyz[0] = btAtan2(-btGetMatrixElem(mat, 5), btGetMatrixElem(mat, 8)); + xyz[1] = btAsin(btGetMatrixElem(mat, 2)); + xyz[2] = btAtan2(-btGetMatrixElem(mat, 1), btGetMatrixElem(mat, 0)); return true; } else { // WARNING. Not unique. XA - ZA = -atan2(r10,r11) - xyz[0] = -btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4)); + xyz[0] = -btAtan2(btGetMatrixElem(mat, 3), btGetMatrixElem(mat, 4)); xyz[1] = -SIMD_HALF_PI; xyz[2] = btScalar(0.0); return false; @@ -106,32 +93,32 @@ bool btGeneric6DofSpring2Constraint::matrixToEulerXYZ(const btMatrix3x3& mat,btV else { // WARNING. Not unique. XAngle + ZAngle = atan2(r10,r11) - xyz[0] = btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4)); + xyz[0] = btAtan2(btGetMatrixElem(mat, 3), btGetMatrixElem(mat, 4)); xyz[1] = SIMD_HALF_PI; xyz[2] = 0.0; } return false; } -bool btGeneric6DofSpring2Constraint::matrixToEulerXZY(const btMatrix3x3& mat,btVector3& xyz) +bool btGeneric6DofSpring2Constraint::matrixToEulerXZY(const btMatrix3x3& mat, btVector3& xyz) { // rot = cy*cz -sz sy*cz // cy*cx*sz+sx*sy cx*cz sy*cx*sz-cy*sx // cy*sx*sz-cx*sy sx*cz sy*sx*sz+cx*cy - btScalar fi = btGetMatrixElem(mat,1); + btScalar fi = btGetMatrixElem(mat, 1); if (fi < btScalar(1.0f)) { if (fi > btScalar(-1.0f)) { - xyz[0] = btAtan2(btGetMatrixElem(mat,7),btGetMatrixElem(mat,4)); - xyz[1] = btAtan2(btGetMatrixElem(mat,2),btGetMatrixElem(mat,0)); - xyz[2] = btAsin(-btGetMatrixElem(mat,1)); + xyz[0] = btAtan2(btGetMatrixElem(mat, 7), btGetMatrixElem(mat, 4)); + xyz[1] = btAtan2(btGetMatrixElem(mat, 2), btGetMatrixElem(mat, 0)); + xyz[2] = btAsin(-btGetMatrixElem(mat, 1)); return true; } else { - xyz[0] = -btAtan2(-btGetMatrixElem(mat,6),btGetMatrixElem(mat,8)); + xyz[0] = -btAtan2(-btGetMatrixElem(mat, 6), btGetMatrixElem(mat, 8)); xyz[1] = btScalar(0.0); xyz[2] = SIMD_HALF_PI; return false; @@ -139,33 +126,33 @@ bool btGeneric6DofSpring2Constraint::matrixToEulerXZY(const btMatrix3x3& mat,btV } else { - xyz[0] = btAtan2(-btGetMatrixElem(mat,6),btGetMatrixElem(mat,8)); + xyz[0] = btAtan2(-btGetMatrixElem(mat, 6), btGetMatrixElem(mat, 8)); xyz[1] = 0.0; xyz[2] = -SIMD_HALF_PI; } return false; } -bool btGeneric6DofSpring2Constraint::matrixToEulerYXZ(const btMatrix3x3& mat,btVector3& xyz) +bool btGeneric6DofSpring2Constraint::matrixToEulerYXZ(const btMatrix3x3& mat, btVector3& xyz) { // rot = cy*cz+sy*sx*sz cz*sy*sx-cy*sz cx*sy // cx*sz cx*cz -sx // cy*sx*sz-cz*sy sy*sz+cy*cz*sx cy*cx - btScalar fi = btGetMatrixElem(mat,5); + btScalar fi = btGetMatrixElem(mat, 5); if (fi < btScalar(1.0f)) { if (fi > btScalar(-1.0f)) { - xyz[0] = btAsin(-btGetMatrixElem(mat,5)); - xyz[1] = btAtan2(btGetMatrixElem(mat,2),btGetMatrixElem(mat,8)); - xyz[2] = btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,4)); + xyz[0] = btAsin(-btGetMatrixElem(mat, 5)); + xyz[1] = btAtan2(btGetMatrixElem(mat, 2), btGetMatrixElem(mat, 8)); + xyz[2] = btAtan2(btGetMatrixElem(mat, 3), btGetMatrixElem(mat, 4)); return true; } else { xyz[0] = SIMD_HALF_PI; - xyz[1] = -btAtan2(-btGetMatrixElem(mat,1),btGetMatrixElem(mat,0)); + xyz[1] = -btAtan2(-btGetMatrixElem(mat, 1), btGetMatrixElem(mat, 0)); xyz[2] = btScalar(0.0); return false; } @@ -173,32 +160,32 @@ bool btGeneric6DofSpring2Constraint::matrixToEulerYXZ(const btMatrix3x3& mat,btV else { xyz[0] = -SIMD_HALF_PI; - xyz[1] = btAtan2(-btGetMatrixElem(mat,1),btGetMatrixElem(mat,0)); + xyz[1] = btAtan2(-btGetMatrixElem(mat, 1), btGetMatrixElem(mat, 0)); xyz[2] = 0.0; } return false; } -bool btGeneric6DofSpring2Constraint::matrixToEulerYZX(const btMatrix3x3& mat,btVector3& xyz) +bool btGeneric6DofSpring2Constraint::matrixToEulerYZX(const btMatrix3x3& mat, btVector3& xyz) { // rot = cy*cz sy*sx-cy*cx*sz cx*sy+cy*sz*sx // sz cz*cx -cz*sx // -cz*sy cy*sx+cx*sy*sz cy*cx-sy*sz*sx - btScalar fi = btGetMatrixElem(mat,3); + btScalar fi = btGetMatrixElem(mat, 3); if (fi < btScalar(1.0f)) { if (fi > btScalar(-1.0f)) { - xyz[0] = btAtan2(-btGetMatrixElem(mat,5),btGetMatrixElem(mat,4)); - xyz[1] = btAtan2(-btGetMatrixElem(mat,6),btGetMatrixElem(mat,0)); - xyz[2] = btAsin(btGetMatrixElem(mat,3)); + xyz[0] = btAtan2(-btGetMatrixElem(mat, 5), btGetMatrixElem(mat, 4)); + xyz[1] = btAtan2(-btGetMatrixElem(mat, 6), btGetMatrixElem(mat, 0)); + xyz[2] = btAsin(btGetMatrixElem(mat, 3)); return true; } else { xyz[0] = btScalar(0.0); - xyz[1] = -btAtan2(btGetMatrixElem(mat,7),btGetMatrixElem(mat,8)); + xyz[1] = -btAtan2(btGetMatrixElem(mat, 7), btGetMatrixElem(mat, 8)); xyz[2] = -SIMD_HALF_PI; return false; } @@ -206,33 +193,33 @@ bool btGeneric6DofSpring2Constraint::matrixToEulerYZX(const btMatrix3x3& mat,btV else { xyz[0] = btScalar(0.0); - xyz[1] = btAtan2(btGetMatrixElem(mat,7),btGetMatrixElem(mat,8)); + xyz[1] = btAtan2(btGetMatrixElem(mat, 7), btGetMatrixElem(mat, 8)); xyz[2] = SIMD_HALF_PI; } return false; } -bool btGeneric6DofSpring2Constraint::matrixToEulerZXY(const btMatrix3x3& mat,btVector3& xyz) +bool btGeneric6DofSpring2Constraint::matrixToEulerZXY(const btMatrix3x3& mat, btVector3& xyz) { // rot = cz*cy-sz*sx*sy -cx*sz cz*sy+cy*sz*sx // cy*sz+cz*sx*sy cz*cx sz*sy-cz*xy*sx // -cx*sy sx cx*cy - btScalar fi = btGetMatrixElem(mat,7); + btScalar fi = btGetMatrixElem(mat, 7); if (fi < btScalar(1.0f)) { if (fi > btScalar(-1.0f)) { - xyz[0] = btAsin(btGetMatrixElem(mat,7)); - xyz[1] = btAtan2(-btGetMatrixElem(mat,6),btGetMatrixElem(mat,8)); - xyz[2] = btAtan2(-btGetMatrixElem(mat,1),btGetMatrixElem(mat,4)); + xyz[0] = btAsin(btGetMatrixElem(mat, 7)); + xyz[1] = btAtan2(-btGetMatrixElem(mat, 6), btGetMatrixElem(mat, 8)); + xyz[2] = btAtan2(-btGetMatrixElem(mat, 1), btGetMatrixElem(mat, 4)); return true; } else { xyz[0] = -SIMD_HALF_PI; xyz[1] = btScalar(0.0); - xyz[2] = -btAtan2(btGetMatrixElem(mat,2),btGetMatrixElem(mat,0)); + xyz[2] = -btAtan2(btGetMatrixElem(mat, 2), btGetMatrixElem(mat, 0)); return false; } } @@ -240,32 +227,32 @@ bool btGeneric6DofSpring2Constraint::matrixToEulerZXY(const btMatrix3x3& mat,btV { xyz[0] = SIMD_HALF_PI; xyz[1] = btScalar(0.0); - xyz[2] = btAtan2(btGetMatrixElem(mat,2),btGetMatrixElem(mat,0)); + xyz[2] = btAtan2(btGetMatrixElem(mat, 2), btGetMatrixElem(mat, 0)); } return false; } -bool btGeneric6DofSpring2Constraint::matrixToEulerZYX(const btMatrix3x3& mat,btVector3& xyz) +bool btGeneric6DofSpring2Constraint::matrixToEulerZYX(const btMatrix3x3& mat, btVector3& xyz) { // rot = cz*cy cz*sy*sx-cx*sz sz*sx+cz*cx*sy // cy*sz cz*cx+sz*sy*sx cx*sz*sy-cz*sx // -sy cy*sx cy*cx - btScalar fi = btGetMatrixElem(mat,6); + btScalar fi = btGetMatrixElem(mat, 6); if (fi < btScalar(1.0f)) { if (fi > btScalar(-1.0f)) { - xyz[0] = btAtan2(btGetMatrixElem(mat,7), btGetMatrixElem(mat,8)); - xyz[1] = btAsin(-btGetMatrixElem(mat,6)); - xyz[2] = btAtan2(btGetMatrixElem(mat,3),btGetMatrixElem(mat,0)); + xyz[0] = btAtan2(btGetMatrixElem(mat, 7), btGetMatrixElem(mat, 8)); + xyz[1] = btAsin(-btGetMatrixElem(mat, 6)); + xyz[2] = btAtan2(btGetMatrixElem(mat, 3), btGetMatrixElem(mat, 0)); return true; } else { xyz[0] = btScalar(0.0); xyz[1] = SIMD_HALF_PI; - xyz[2] = -btAtan2(btGetMatrixElem(mat,1),btGetMatrixElem(mat,2)); + xyz[2] = -btAtan2(btGetMatrixElem(mat, 1), btGetMatrixElem(mat, 2)); return false; } } @@ -273,23 +260,36 @@ bool btGeneric6DofSpring2Constraint::matrixToEulerZYX(const btMatrix3x3& mat,btV { xyz[0] = btScalar(0.0); xyz[1] = -SIMD_HALF_PI; - xyz[2] = btAtan2(-btGetMatrixElem(mat,1),-btGetMatrixElem(mat,2)); + xyz[2] = btAtan2(-btGetMatrixElem(mat, 1), -btGetMatrixElem(mat, 2)); } return false; } void btGeneric6DofSpring2Constraint::calculateAngleInfo() { - btMatrix3x3 relative_frame = m_calculatedTransformA.getBasis().inverse()*m_calculatedTransformB.getBasis(); + btMatrix3x3 relative_frame = m_calculatedTransformA.getBasis().inverse() * m_calculatedTransformB.getBasis(); switch (m_rotateOrder) { - case RO_XYZ : matrixToEulerXYZ(relative_frame,m_calculatedAxisAngleDiff); break; - case RO_XZY : matrixToEulerXZY(relative_frame,m_calculatedAxisAngleDiff); break; - case RO_YXZ : matrixToEulerYXZ(relative_frame,m_calculatedAxisAngleDiff); break; - case RO_YZX : matrixToEulerYZX(relative_frame,m_calculatedAxisAngleDiff); break; - case RO_ZXY : matrixToEulerZXY(relative_frame,m_calculatedAxisAngleDiff); break; - case RO_ZYX : matrixToEulerZYX(relative_frame,m_calculatedAxisAngleDiff); break; - default : btAssert(false); + case RO_XYZ: + matrixToEulerXYZ(relative_frame, m_calculatedAxisAngleDiff); + break; + case RO_XZY: + matrixToEulerXZY(relative_frame, m_calculatedAxisAngleDiff); + break; + case RO_YXZ: + matrixToEulerYXZ(relative_frame, m_calculatedAxisAngleDiff); + break; + case RO_YZX: + matrixToEulerYZX(relative_frame, m_calculatedAxisAngleDiff); + break; + case RO_ZXY: + matrixToEulerZXY(relative_frame, m_calculatedAxisAngleDiff); + break; + case RO_ZYX: + matrixToEulerZYX(relative_frame, m_calculatedAxisAngleDiff); + break; + default: + btAssert(false); } // in euler angle mode we do not actually constrain the angular velocity // along the axes axis[0] and axis[2] (although we do use axis[1]) : @@ -307,14 +307,14 @@ void btGeneric6DofSpring2Constraint::calculateAngleInfo() // to the components of w and set that to 0. switch (m_rotateOrder) { - case RO_XYZ : + case RO_XYZ: { //Is this the "line of nodes" calculation choosing planes YZ (B coordinate system) and xy (A coordinate system)? (http://en.wikipedia.org/wiki/Euler_angles) //The two planes are non-homologous, so this is a Tait–Bryan angle formalism and not a proper Euler //Extrinsic rotations are equal to the reversed order intrinsic rotations so the above xyz extrinsic rotations (axes are fixed) are the same as the zy'x" intrinsic rotations (axes are refreshed after each rotation) //that is why xy and YZ planes are chosen (this will describe a zy'x" intrinsic rotation) (see the figure on the left at http://en.wikipedia.org/wiki/Euler_angles under Tait–Bryan angles) // x' = Nperp = N.cross(axis2) - // y' = N = axis2.cross(axis0) + // y' = N = axis2.cross(axis0) // z' = z // // x" = X @@ -324,7 +324,7 @@ void btGeneric6DofSpring2Constraint::calculateAngleInfo() //first rotate around z //second rotate around y'= z.cross(X) //third rotate around x" = X - //Original XYZ extrinsic rotation order. + //Original XYZ extrinsic rotation order. //Planes: xy and YZ normals: z, X. Plane intersection (N) is z.cross(X) btVector3 axis0 = m_calculatedTransformB.getBasis().getColumn(0); btVector3 axis2 = m_calculatedTransformA.getBasis().getColumn(2); @@ -333,7 +333,7 @@ void btGeneric6DofSpring2Constraint::calculateAngleInfo() m_calculatedAxis[2] = axis0.cross(m_calculatedAxis[1]); break; } - case RO_XZY : + case RO_XZY: { //planes: xz,ZY normals: y, X //first rotate around y @@ -346,7 +346,7 @@ void btGeneric6DofSpring2Constraint::calculateAngleInfo() m_calculatedAxis[1] = m_calculatedAxis[2].cross(axis0); break; } - case RO_YXZ : + case RO_YXZ: { //planes: yx,XZ normals: z, Y //first rotate around z @@ -359,7 +359,7 @@ void btGeneric6DofSpring2Constraint::calculateAngleInfo() m_calculatedAxis[2] = m_calculatedAxis[0].cross(axis1); break; } - case RO_YZX : + case RO_YZX: { //planes: yz,ZX normals: x, Y //first rotate around x @@ -372,7 +372,7 @@ void btGeneric6DofSpring2Constraint::calculateAngleInfo() m_calculatedAxis[1] = m_calculatedAxis[2].cross(axis0); break; } - case RO_ZXY : + case RO_ZXY: { //planes: zx,XY normals: y, Z //first rotate around y @@ -385,7 +385,7 @@ void btGeneric6DofSpring2Constraint::calculateAngleInfo() m_calculatedAxis[2] = m_calculatedAxis[0].cross(axis1); break; } - case RO_ZYX : + case RO_ZYX: { //planes: zy,YX normals: x, Z //first rotate around x @@ -398,22 +398,21 @@ void btGeneric6DofSpring2Constraint::calculateAngleInfo() m_calculatedAxis[2] = axis0.cross(m_calculatedAxis[1]); break; } - default: - btAssert(false); + default: + btAssert(false); } m_calculatedAxis[0].normalize(); m_calculatedAxis[1].normalize(); m_calculatedAxis[2].normalize(); - } void btGeneric6DofSpring2Constraint::calculateTransforms() { - calculateTransforms(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); + calculateTransforms(m_rbA.getCenterOfMassTransform(), m_rbB.getCenterOfMassTransform()); } -void btGeneric6DofSpring2Constraint::calculateTransforms(const btTransform& transA,const btTransform& transB) +void btGeneric6DofSpring2Constraint::calculateTransforms(const btTransform& transA, const btTransform& transB) { m_calculatedTransformA = transA * m_frameInA; m_calculatedTransformB = transB * m_frameInB; @@ -424,18 +423,17 @@ void btGeneric6DofSpring2Constraint::calculateTransforms(const btTransform& tran btScalar miB = getRigidBodyB().getInvMass(); m_hasStaticBody = (miA < SIMD_EPSILON) || (miB < SIMD_EPSILON); btScalar miS = miA + miB; - if(miS > btScalar(0.f)) + if (miS > btScalar(0.f)) { m_factA = miB / miS; } - else + else { m_factA = btScalar(0.5f); } m_factB = btScalar(1.0f) - m_factA; } - void btGeneric6DofSpring2Constraint::testAngularLimitMotor(int axis_index) { btScalar angle = m_calculatedAxisAngleDiff[axis_index]; @@ -444,35 +442,37 @@ void btGeneric6DofSpring2Constraint::testAngularLimitMotor(int axis_index) m_angularLimits[axis_index].testLimitValue(angle); } - -void btGeneric6DofSpring2Constraint::getInfo1 (btConstraintInfo1* info) +void btGeneric6DofSpring2Constraint::getInfo1(btConstraintInfo1* info) { //prepare constraint - calculateTransforms(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); + calculateTransforms(m_rbA.getCenterOfMassTransform(), m_rbB.getCenterOfMassTransform()); info->m_numConstraintRows = 0; info->nub = 0; int i; //test linear limits - for(i = 0; i < 3; i++) + for (i = 0; i < 3; i++) { - if (m_linearLimits.m_currentLimit[i]==4) info->m_numConstraintRows += 2; - else if (m_linearLimits.m_currentLimit[i]!=0) info->m_numConstraintRows += 1; - if (m_linearLimits.m_enableMotor[i] ) info->m_numConstraintRows += 1; + if (m_linearLimits.m_currentLimit[i] == 4) + info->m_numConstraintRows += 2; + else if (m_linearLimits.m_currentLimit[i] != 0) + info->m_numConstraintRows += 1; + if (m_linearLimits.m_enableMotor[i]) info->m_numConstraintRows += 1; if (m_linearLimits.m_enableSpring[i]) info->m_numConstraintRows += 1; } //test angular limits - for (i=0;i<3 ;i++ ) + for (i = 0; i < 3; i++) { testAngularLimitMotor(i); - if (m_angularLimits[i].m_currentLimit==4) info->m_numConstraintRows += 2; - else if (m_angularLimits[i].m_currentLimit!=0) info->m_numConstraintRows += 1; - if (m_angularLimits[i].m_enableMotor ) info->m_numConstraintRows += 1; + if (m_angularLimits[i].m_currentLimit == 4) + info->m_numConstraintRows += 2; + else if (m_angularLimits[i].m_currentLimit != 0) + info->m_numConstraintRows += 1; + if (m_angularLimits[i].m_enableMotor) info->m_numConstraintRows += 1; if (m_angularLimits[i].m_enableSpring) info->m_numConstraintRows += 1; } } - -void btGeneric6DofSpring2Constraint::getInfo2 (btConstraintInfo2* info) +void btGeneric6DofSpring2Constraint::getInfo2(btConstraintInfo2* info) { const btTransform& transA = m_rbA.getCenterOfMassTransform(); const btTransform& transB = m_rbB.getCenterOfMassTransform(); @@ -482,118 +482,138 @@ void btGeneric6DofSpring2Constraint::getInfo2 (btConstraintInfo2* info) const btVector3& angVelB = m_rbB.getAngularVelocity(); // for stability better to solve angular limits first - int row = setAngularLimits(info, 0,transA,transB,linVelA,linVelB,angVelA,angVelB); - setLinearLimits(info, row, transA,transB,linVelA,linVelB,angVelA,angVelB); + int row = setAngularLimits(info, 0, transA, transB, linVelA, linVelB, angVelA, angVelB); + setLinearLimits(info, row, transA, transB, linVelA, linVelB, angVelA, angVelB); } - -int btGeneric6DofSpring2Constraint::setLinearLimits(btConstraintInfo2* info, int row, const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB) +int btGeneric6DofSpring2Constraint::setLinearLimits(btConstraintInfo2* info, int row, const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB) { //solve linear limits btRotationalLimitMotor2 limot; - for (int i=0;i<3 ;i++ ) + for (int i = 0; i < 3; i++) { - if(m_linearLimits.m_currentLimit[i] || m_linearLimits.m_enableMotor[i] || m_linearLimits.m_enableSpring[i]) - { // re-use rotational motor code - limot.m_bounce = m_linearLimits.m_bounce[i]; - limot.m_currentLimit = m_linearLimits.m_currentLimit[i]; - limot.m_currentPosition = m_linearLimits.m_currentLinearDiff[i]; - limot.m_currentLimitError = m_linearLimits.m_currentLimitError[i]; - limot.m_currentLimitErrorHi = m_linearLimits.m_currentLimitErrorHi[i]; - limot.m_enableMotor = m_linearLimits.m_enableMotor[i]; - limot.m_servoMotor = m_linearLimits.m_servoMotor[i]; - limot.m_servoTarget = m_linearLimits.m_servoTarget[i]; - limot.m_enableSpring = m_linearLimits.m_enableSpring[i]; - limot.m_springStiffness = m_linearLimits.m_springStiffness[i]; + if (m_linearLimits.m_currentLimit[i] || m_linearLimits.m_enableMotor[i] || m_linearLimits.m_enableSpring[i]) + { // re-use rotational motor code + limot.m_bounce = m_linearLimits.m_bounce[i]; + limot.m_currentLimit = m_linearLimits.m_currentLimit[i]; + limot.m_currentPosition = m_linearLimits.m_currentLinearDiff[i]; + limot.m_currentLimitError = m_linearLimits.m_currentLimitError[i]; + limot.m_currentLimitErrorHi = m_linearLimits.m_currentLimitErrorHi[i]; + limot.m_enableMotor = m_linearLimits.m_enableMotor[i]; + limot.m_servoMotor = m_linearLimits.m_servoMotor[i]; + limot.m_servoTarget = m_linearLimits.m_servoTarget[i]; + limot.m_enableSpring = m_linearLimits.m_enableSpring[i]; + limot.m_springStiffness = m_linearLimits.m_springStiffness[i]; limot.m_springStiffnessLimited = m_linearLimits.m_springStiffnessLimited[i]; - limot.m_springDamping = m_linearLimits.m_springDamping[i]; - limot.m_springDampingLimited = m_linearLimits.m_springDampingLimited[i]; - limot.m_equilibriumPoint = m_linearLimits.m_equilibriumPoint[i]; - limot.m_hiLimit = m_linearLimits.m_upperLimit[i]; - limot.m_loLimit = m_linearLimits.m_lowerLimit[i]; - limot.m_maxMotorForce = m_linearLimits.m_maxMotorForce[i]; - limot.m_targetVelocity = m_linearLimits.m_targetVelocity[i]; + limot.m_springDamping = m_linearLimits.m_springDamping[i]; + limot.m_springDampingLimited = m_linearLimits.m_springDampingLimited[i]; + limot.m_equilibriumPoint = m_linearLimits.m_equilibriumPoint[i]; + limot.m_hiLimit = m_linearLimits.m_upperLimit[i]; + limot.m_loLimit = m_linearLimits.m_lowerLimit[i]; + limot.m_maxMotorForce = m_linearLimits.m_maxMotorForce[i]; + limot.m_targetVelocity = m_linearLimits.m_targetVelocity[i]; btVector3 axis = m_calculatedTransformA.getBasis().getColumn(i); int flags = m_flags >> (i * BT_6DOF_FLAGS_AXIS_SHIFT2); - limot.m_stopCFM = (flags & BT_6DOF_FLAGS_CFM_STOP2) ? m_linearLimits.m_stopCFM[i] : info->cfm[0]; - limot.m_stopERP = (flags & BT_6DOF_FLAGS_ERP_STOP2) ? m_linearLimits.m_stopERP[i] : info->erp; + limot.m_stopCFM = (flags & BT_6DOF_FLAGS_CFM_STOP2) ? m_linearLimits.m_stopCFM[i] : info->cfm[0]; + limot.m_stopERP = (flags & BT_6DOF_FLAGS_ERP_STOP2) ? m_linearLimits.m_stopERP[i] : info->erp; limot.m_motorCFM = (flags & BT_6DOF_FLAGS_CFM_MOTO2) ? m_linearLimits.m_motorCFM[i] : info->cfm[0]; limot.m_motorERP = (flags & BT_6DOF_FLAGS_ERP_MOTO2) ? m_linearLimits.m_motorERP[i] : info->erp; //rotAllowed is a bit of a magic from the original 6dof. The calculation of it here is something that imitates the original behavior as much as possible. int indx1 = (i + 1) % 3; int indx2 = (i + 2) % 3; - int rotAllowed = 1; // rotations around orthos to current axis (it is used only when one of the body is static) - #define D6_LIMIT_ERROR_THRESHOLD_FOR_ROTATION 1.0e-3 + int rotAllowed = 1; // rotations around orthos to current axis (it is used only when one of the body is static) +#define D6_LIMIT_ERROR_THRESHOLD_FOR_ROTATION 1.0e-3 bool indx1Violated = m_angularLimits[indx1].m_currentLimit == 1 || - m_angularLimits[indx1].m_currentLimit == 2 || - ( m_angularLimits[indx1].m_currentLimit == 3 && ( m_angularLimits[indx1].m_currentLimitError < -D6_LIMIT_ERROR_THRESHOLD_FOR_ROTATION || m_angularLimits[indx1].m_currentLimitError > D6_LIMIT_ERROR_THRESHOLD_FOR_ROTATION ) ) || - ( m_angularLimits[indx1].m_currentLimit == 4 && ( m_angularLimits[indx1].m_currentLimitError < -D6_LIMIT_ERROR_THRESHOLD_FOR_ROTATION || m_angularLimits[indx1].m_currentLimitErrorHi > D6_LIMIT_ERROR_THRESHOLD_FOR_ROTATION ) ); + m_angularLimits[indx1].m_currentLimit == 2 || + (m_angularLimits[indx1].m_currentLimit == 3 && (m_angularLimits[indx1].m_currentLimitError < -D6_LIMIT_ERROR_THRESHOLD_FOR_ROTATION || m_angularLimits[indx1].m_currentLimitError > D6_LIMIT_ERROR_THRESHOLD_FOR_ROTATION)) || + (m_angularLimits[indx1].m_currentLimit == 4 && (m_angularLimits[indx1].m_currentLimitError < -D6_LIMIT_ERROR_THRESHOLD_FOR_ROTATION || m_angularLimits[indx1].m_currentLimitErrorHi > D6_LIMIT_ERROR_THRESHOLD_FOR_ROTATION)); bool indx2Violated = m_angularLimits[indx2].m_currentLimit == 1 || - m_angularLimits[indx2].m_currentLimit == 2 || - ( m_angularLimits[indx2].m_currentLimit == 3 && ( m_angularLimits[indx2].m_currentLimitError < -D6_LIMIT_ERROR_THRESHOLD_FOR_ROTATION || m_angularLimits[indx2].m_currentLimitError > D6_LIMIT_ERROR_THRESHOLD_FOR_ROTATION ) ) || - ( m_angularLimits[indx2].m_currentLimit == 4 && ( m_angularLimits[indx2].m_currentLimitError < -D6_LIMIT_ERROR_THRESHOLD_FOR_ROTATION || m_angularLimits[indx2].m_currentLimitErrorHi > D6_LIMIT_ERROR_THRESHOLD_FOR_ROTATION ) ); - if( indx1Violated && indx2Violated ) + m_angularLimits[indx2].m_currentLimit == 2 || + (m_angularLimits[indx2].m_currentLimit == 3 && (m_angularLimits[indx2].m_currentLimitError < -D6_LIMIT_ERROR_THRESHOLD_FOR_ROTATION || m_angularLimits[indx2].m_currentLimitError > D6_LIMIT_ERROR_THRESHOLD_FOR_ROTATION)) || + (m_angularLimits[indx2].m_currentLimit == 4 && (m_angularLimits[indx2].m_currentLimitError < -D6_LIMIT_ERROR_THRESHOLD_FOR_ROTATION || m_angularLimits[indx2].m_currentLimitErrorHi > D6_LIMIT_ERROR_THRESHOLD_FOR_ROTATION)); + if (indx1Violated && indx2Violated) { rotAllowed = 0; } - row += get_limit_motor_info2(&limot, transA,transB,linVelA,linVelB,angVelA,angVelB, info, row, axis, 0, rotAllowed); - + row += get_limit_motor_info2(&limot, transA, transB, linVelA, linVelB, angVelA, angVelB, info, row, axis, 0, rotAllowed); } } return row; } - - -int btGeneric6DofSpring2Constraint::setAngularLimits(btConstraintInfo2 *info, int row_offset, const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB) +int btGeneric6DofSpring2Constraint::setAngularLimits(btConstraintInfo2* info, int row_offset, const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB) { int row = row_offset; //order of rotational constraint rows int cIdx[] = {0, 1, 2}; - switch(m_rotateOrder) + switch (m_rotateOrder) { - case RO_XYZ : cIdx[0] = 0; cIdx[1] = 1; cIdx[2] = 2; break; - case RO_XZY : cIdx[0] = 0; cIdx[1] = 2; cIdx[2] = 1; break; - case RO_YXZ : cIdx[0] = 1; cIdx[1] = 0; cIdx[2] = 2; break; - case RO_YZX : cIdx[0] = 1; cIdx[1] = 2; cIdx[2] = 0; break; - case RO_ZXY : cIdx[0] = 2; cIdx[1] = 0; cIdx[2] = 1; break; - case RO_ZYX : cIdx[0] = 2; cIdx[1] = 1; cIdx[2] = 0; break; - default : btAssert(false); + case RO_XYZ: + cIdx[0] = 0; + cIdx[1] = 1; + cIdx[2] = 2; + break; + case RO_XZY: + cIdx[0] = 0; + cIdx[1] = 2; + cIdx[2] = 1; + break; + case RO_YXZ: + cIdx[0] = 1; + cIdx[1] = 0; + cIdx[2] = 2; + break; + case RO_YZX: + cIdx[0] = 1; + cIdx[1] = 2; + cIdx[2] = 0; + break; + case RO_ZXY: + cIdx[0] = 2; + cIdx[1] = 0; + cIdx[2] = 1; + break; + case RO_ZYX: + cIdx[0] = 2; + cIdx[1] = 1; + cIdx[2] = 0; + break; + default: + btAssert(false); } - for (int ii = 0; ii < 3 ; ii++ ) + for (int ii = 0; ii < 3; ii++) { int i = cIdx[ii]; - if(m_angularLimits[i].m_currentLimit || m_angularLimits[i].m_enableMotor || m_angularLimits[i].m_enableSpring) + if (m_angularLimits[i].m_currentLimit || m_angularLimits[i].m_enableMotor || m_angularLimits[i].m_enableSpring) { btVector3 axis = getAxis(i); int flags = m_flags >> ((i + 3) * BT_6DOF_FLAGS_AXIS_SHIFT2); - if(!(flags & BT_6DOF_FLAGS_CFM_STOP2)) + if (!(flags & BT_6DOF_FLAGS_CFM_STOP2)) { m_angularLimits[i].m_stopCFM = info->cfm[0]; } - if(!(flags & BT_6DOF_FLAGS_ERP_STOP2)) + if (!(flags & BT_6DOF_FLAGS_ERP_STOP2)) { m_angularLimits[i].m_stopERP = info->erp; } - if(!(flags & BT_6DOF_FLAGS_CFM_MOTO2)) + if (!(flags & BT_6DOF_FLAGS_CFM_MOTO2)) { m_angularLimits[i].m_motorCFM = info->cfm[0]; } - if(!(flags & BT_6DOF_FLAGS_ERP_MOTO2)) + if (!(flags & BT_6DOF_FLAGS_ERP_MOTO2)) { m_angularLimits[i].m_motorERP = info->erp; } - row += get_limit_motor_info2(&m_angularLimits[i],transA,transB,linVelA,linVelB,angVelA,angVelB, info,row,axis,1); + row += get_limit_motor_info2(&m_angularLimits[i], transA, transB, linVelA, linVelB, angVelA, angVelB, info, row, axis, 1); } } return row; } - void btGeneric6DofSpring2Constraint::setFrames(const btTransform& frameA, const btTransform& frameB) { m_frameInA = frameA; @@ -602,32 +622,31 @@ void btGeneric6DofSpring2Constraint::setFrames(const btTransform& frameA, const calculateTransforms(); } - void btGeneric6DofSpring2Constraint::calculateLinearInfo() { m_calculatedLinearDiff = m_calculatedTransformB.getOrigin() - m_calculatedTransformA.getOrigin(); m_calculatedLinearDiff = m_calculatedTransformA.getBasis().inverse() * m_calculatedLinearDiff; - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) { m_linearLimits.m_currentLinearDiff[i] = m_calculatedLinearDiff[i]; m_linearLimits.testLimitValue(i, m_calculatedLinearDiff[i]); } } -void btGeneric6DofSpring2Constraint::calculateJacobi(btRotationalLimitMotor2 * limot, const btTransform& transA,const btTransform& transB, btConstraintInfo2 *info, int srow, btVector3& ax1, int rotational, int rotAllowed) +void btGeneric6DofSpring2Constraint::calculateJacobi(btRotationalLimitMotor2* limot, const btTransform& transA, const btTransform& transB, btConstraintInfo2* info, int srow, btVector3& ax1, int rotational, int rotAllowed) { - btScalar *J1 = rotational ? info->m_J1angularAxis : info->m_J1linearAxis; - btScalar *J2 = rotational ? info->m_J2angularAxis : info->m_J2linearAxis; + btScalar* J1 = rotational ? info->m_J1angularAxis : info->m_J1linearAxis; + btScalar* J2 = rotational ? info->m_J2angularAxis : info->m_J2linearAxis; - J1[srow+0] = ax1[0]; - J1[srow+1] = ax1[1]; - J1[srow+2] = ax1[2]; + J1[srow + 0] = ax1[0]; + J1[srow + 1] = ax1[1]; + J1[srow + 2] = ax1[2]; - J2[srow+0] = -ax1[0]; - J2[srow+1] = -ax1[1]; - J2[srow+2] = -ax1[2]; + J2[srow + 0] = -ax1[0]; + J2[srow + 1] = -ax1[1]; + J2[srow + 2] = -ax1[2]; - if(!rotational) + if (!rotational) { btVector3 tmpA, tmpB, relA, relB; // get vector from bodyB to frameB in WCS @@ -636,40 +655,44 @@ void btGeneric6DofSpring2Constraint::calculateJacobi(btRotationalLimitMotor2 * l relA = m_calculatedTransformA.getOrigin() - transA.getOrigin(); tmpA = relA.cross(ax1); tmpB = relB.cross(ax1); - if(m_hasStaticBody && (!rotAllowed)) + if (m_hasStaticBody && (!rotAllowed)) { tmpA *= m_factA; tmpB *= m_factB; } int i; - for (i=0; i<3; i++) info->m_J1angularAxis[srow+i] = tmpA[i]; - for (i=0; i<3; i++) info->m_J2angularAxis[srow+i] = -tmpB[i]; + for (i = 0; i < 3; i++) info->m_J1angularAxis[srow + i] = tmpA[i]; + for (i = 0; i < 3; i++) info->m_J2angularAxis[srow + i] = -tmpB[i]; } } - int btGeneric6DofSpring2Constraint::get_limit_motor_info2( - btRotationalLimitMotor2 * limot, - const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB, - btConstraintInfo2 *info, int row, btVector3& ax1, int rotational,int rotAllowed) + btRotationalLimitMotor2* limot, + const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB, + btConstraintInfo2* info, int row, btVector3& ax1, int rotational, int rotAllowed) { int count = 0; int srow = row * info->rowskip; - if (limot->m_currentLimit==4) + if (limot->m_currentLimit == 4) { btScalar vel = rotational ? angVelA.dot(ax1) - angVelB.dot(ax1) : linVelA.dot(ax1) - linVelB.dot(ax1); - calculateJacobi(limot,transA,transB,info,srow,ax1,rotational,rotAllowed); + calculateJacobi(limot, transA, transB, info, srow, ax1, rotational, rotAllowed); info->m_constraintError[srow] = info->fps * limot->m_stopERP * limot->m_currentLimitError * (rotational ? -1 : 1); - if (rotational) { - if (info->m_constraintError[srow]-vel*limot->m_stopERP > 0) { - btScalar bounceerror = -limot->m_bounce* vel; + if (rotational) + { + if (info->m_constraintError[srow] - vel * limot->m_stopERP > 0) + { + btScalar bounceerror = -limot->m_bounce * vel; if (bounceerror > info->m_constraintError[srow]) info->m_constraintError[srow] = bounceerror; } - } else { - if (info->m_constraintError[srow]-vel*limot->m_stopERP < 0) { - btScalar bounceerror = -limot->m_bounce* vel; + } + else + { + if (info->m_constraintError[srow] - vel * limot->m_stopERP < 0) + { + btScalar bounceerror = -limot->m_bounce * vel; if (bounceerror < info->m_constraintError[srow]) info->m_constraintError[srow] = bounceerror; } } @@ -679,16 +702,21 @@ int btGeneric6DofSpring2Constraint::get_limit_motor_info2( srow += info->rowskip; ++count; - calculateJacobi(limot,transA,transB,info,srow,ax1,rotational,rotAllowed); + calculateJacobi(limot, transA, transB, info, srow, ax1, rotational, rotAllowed); info->m_constraintError[srow] = info->fps * limot->m_stopERP * limot->m_currentLimitErrorHi * (rotational ? -1 : 1); - if (rotational) { - if (info->m_constraintError[srow]-vel*limot->m_stopERP < 0) { - btScalar bounceerror = -limot->m_bounce* vel; + if (rotational) + { + if (info->m_constraintError[srow] - vel * limot->m_stopERP < 0) + { + btScalar bounceerror = -limot->m_bounce * vel; if (bounceerror < info->m_constraintError[srow]) info->m_constraintError[srow] = bounceerror; } - } else { - if (info->m_constraintError[srow]-vel*limot->m_stopERP > 0) { - btScalar bounceerror = -limot->m_bounce* vel; + } + else + { + if (info->m_constraintError[srow] - vel * limot->m_stopERP > 0) + { + btScalar bounceerror = -limot->m_bounce * vel; if (bounceerror > info->m_constraintError[srow]) info->m_constraintError[srow] = bounceerror; } } @@ -697,10 +725,10 @@ int btGeneric6DofSpring2Constraint::get_limit_motor_info2( info->cfm[srow] = limot->m_stopCFM; srow += info->rowskip; ++count; - } else - if (limot->m_currentLimit==3) + } + else if (limot->m_currentLimit == 3) { - calculateJacobi(limot,transA,transB,info,srow,ax1,rotational,rotAllowed); + calculateJacobi(limot, transA, transB, info, srow, ax1, rotational, rotAllowed); info->m_constraintError[srow] = info->fps * limot->m_stopERP * limot->m_currentLimitError * (rotational ? -1 : 1); info->m_lowerLimit[srow] = -SIMD_INFINITY; info->m_upperLimit[srow] = SIMD_INFINITY; @@ -711,13 +739,13 @@ int btGeneric6DofSpring2Constraint::get_limit_motor_info2( if (limot->m_enableMotor && !limot->m_servoMotor) { - calculateJacobi(limot,transA,transB,info,srow,ax1,rotational,rotAllowed); + calculateJacobi(limot, transA, transB, info, srow, ax1, rotational, rotAllowed); btScalar tag_vel = rotational ? limot->m_targetVelocity : -limot->m_targetVelocity; - btScalar mot_fact = getMotorFactor(limot->m_currentPosition, - limot->m_loLimit, - limot->m_hiLimit, - tag_vel, - info->fps * limot->m_motorERP); + btScalar mot_fact = getMotorFactor(limot->m_currentPosition, + limot->m_loLimit, + limot->m_hiLimit, + tag_vel, + info->fps * limot->m_motorERP); info->m_constraintError[srow] = mot_fact * limot->m_targetVelocity; info->m_lowerLimit[srow] = -limot->m_maxMotorForce / info->fps; info->m_upperLimit[srow] = limot->m_maxMotorForce / info->fps; @@ -735,36 +763,36 @@ int btGeneric6DofSpring2Constraint::get_limit_motor_info2( if (error > SIMD_PI) { error -= SIMD_2_PI; - curServoTarget +=SIMD_2_PI; + curServoTarget += SIMD_2_PI; } if (error < -SIMD_PI) { error += SIMD_2_PI; - curServoTarget -=SIMD_2_PI; + curServoTarget -= SIMD_2_PI; } } - calculateJacobi(limot,transA,transB,info,srow,ax1,rotational,rotAllowed); - btScalar targetvelocity = error<0 ? -limot->m_targetVelocity : limot->m_targetVelocity; + calculateJacobi(limot, transA, transB, info, srow, ax1, rotational, rotAllowed); + btScalar targetvelocity = error < 0 ? -limot->m_targetVelocity : limot->m_targetVelocity; btScalar tag_vel = -targetvelocity; btScalar mot_fact; - if(error != 0) + if (error != 0) { btScalar lowLimit; btScalar hiLimit; - if(limot->m_loLimit > limot->m_hiLimit) + if (limot->m_loLimit > limot->m_hiLimit) { lowLimit = error > 0 ? curServoTarget : -SIMD_INFINITY; - hiLimit = error < 0 ? curServoTarget : SIMD_INFINITY; + hiLimit = error < 0 ? curServoTarget : SIMD_INFINITY; } else { - lowLimit = error > 0 && curServoTarget>limot->m_loLimit ? curServoTarget : limot->m_loLimit; - hiLimit = error < 0 && curServoTargetm_hiLimit ? curServoTarget : limot->m_hiLimit; + lowLimit = error > 0 && curServoTarget > limot->m_loLimit ? curServoTarget : limot->m_loLimit; + hiLimit = error < 0 && curServoTarget < limot->m_hiLimit ? curServoTarget : limot->m_hiLimit; } mot_fact = getMotorFactor(limot->m_currentPosition, lowLimit, hiLimit, tag_vel, info->fps * limot->m_motorERP); - } - else + } + else { mot_fact = 0; } @@ -779,7 +807,7 @@ int btGeneric6DofSpring2Constraint::get_limit_motor_info2( if (limot->m_enableSpring) { btScalar error = limot->m_currentPosition - limot->m_equilibriumPoint; - calculateJacobi(limot,transA,transB,info,srow,ax1,rotational,rotAllowed); + calculateJacobi(limot, transA, transB, info, srow, ax1, rotational, rotAllowed); //btScalar cfm = 1.0 / ((1.0/info->fps)*limot->m_springStiffness+ limot->m_springDamping); //if(cfm > 0.99999) @@ -793,11 +821,12 @@ int btGeneric6DofSpring2Constraint::get_limit_motor_info2( btScalar kd = limot->m_springDamping; btScalar ks = limot->m_springStiffness; btScalar vel = rotational ? angVelA.dot(ax1) - angVelB.dot(ax1) : linVelA.dot(ax1) - linVelB.dot(ax1); -// btScalar erp = 0.1; + // btScalar erp = 0.1; btScalar cfm = BT_ZERO; btScalar mA = BT_ONE / m_rbA.getInvMass(); btScalar mB = BT_ONE / m_rbB.getInvMass(); - if (rotational) { + if (rotational) + { btScalar rrA = (m_calculatedTransformA.getOrigin() - transA.getOrigin()).length2(); btScalar rrB = (m_calculatedTransformB.getOrigin() - transB.getOrigin()).length2(); if (m_rbA.getInvMass()) mA = mA * rrA + 1 / (m_rbA.getInvInertiaTensorWorld() * ax1).length(); @@ -806,20 +835,19 @@ int btGeneric6DofSpring2Constraint::get_limit_motor_info2( btScalar m = mA > mB ? mB : mA; btScalar angularfreq = sqrt(ks / m); - //limit stiffness (the spring should not be sampled faster that the quarter of its angular frequency) - if(limot->m_springStiffnessLimited && 0.25 < angularfreq * dt) + if (limot->m_springStiffnessLimited && 0.25 < angularfreq * dt) { ks = BT_ONE / dt / dt / btScalar(16.0) * m; } //avoid damping that would blow up the spring - if(limot->m_springDampingLimited && kd * dt > m) + if (limot->m_springDampingLimited && kd * dt > m) { kd = m / dt; } btScalar fs = ks * error * dt; btScalar fd = -kd * (vel) * (rotational ? -1 : 1) * dt; - btScalar f = (fs+fd); + btScalar f = (fs + fd); // after the spring force affecting the body(es) the new velocity will be // vel + f / m * (rotational ? -1 : 1) @@ -836,7 +864,7 @@ int btGeneric6DofSpring2Constraint::get_limit_motor_info2( btScalar minf = f < fd ? f : fd; btScalar maxf = f < fd ? fd : f; - if(!rotational) + if (!rotational) { info->m_lowerLimit[srow] = minf > 0 ? 0 : minf; info->m_upperLimit[srow] = maxf < 0 ? 0 : maxf; @@ -855,56 +883,55 @@ int btGeneric6DofSpring2Constraint::get_limit_motor_info2( return count; } - -//override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). +//override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). //If no axis is provided, it uses the default axis for this constraint. void btGeneric6DofSpring2Constraint::setParam(int num, btScalar value, int axis) { - if((axis >= 0) && (axis < 3)) + if ((axis >= 0) && (axis < 3)) { - switch(num) + switch (num) { - case BT_CONSTRAINT_STOP_ERP : + case BT_CONSTRAINT_STOP_ERP: m_linearLimits.m_stopERP[axis] = value; m_flags |= BT_6DOF_FLAGS_ERP_STOP2 << (axis * BT_6DOF_FLAGS_AXIS_SHIFT2); break; - case BT_CONSTRAINT_STOP_CFM : + case BT_CONSTRAINT_STOP_CFM: m_linearLimits.m_stopCFM[axis] = value; m_flags |= BT_6DOF_FLAGS_CFM_STOP2 << (axis * BT_6DOF_FLAGS_AXIS_SHIFT2); break; - case BT_CONSTRAINT_ERP : + case BT_CONSTRAINT_ERP: m_linearLimits.m_motorERP[axis] = value; m_flags |= BT_6DOF_FLAGS_ERP_MOTO2 << (axis * BT_6DOF_FLAGS_AXIS_SHIFT2); break; - case BT_CONSTRAINT_CFM : + case BT_CONSTRAINT_CFM: m_linearLimits.m_motorCFM[axis] = value; m_flags |= BT_6DOF_FLAGS_CFM_MOTO2 << (axis * BT_6DOF_FLAGS_AXIS_SHIFT2); break; - default : + default: btAssertConstrParams(0); } } - else if((axis >=3) && (axis < 6)) + else if ((axis >= 3) && (axis < 6)) { - switch(num) + switch (num) { - case BT_CONSTRAINT_STOP_ERP : + case BT_CONSTRAINT_STOP_ERP: m_angularLimits[axis - 3].m_stopERP = value; m_flags |= BT_6DOF_FLAGS_ERP_STOP2 << (axis * BT_6DOF_FLAGS_AXIS_SHIFT2); break; - case BT_CONSTRAINT_STOP_CFM : + case BT_CONSTRAINT_STOP_CFM: m_angularLimits[axis - 3].m_stopCFM = value; m_flags |= BT_6DOF_FLAGS_CFM_STOP2 << (axis * BT_6DOF_FLAGS_AXIS_SHIFT2); break; - case BT_CONSTRAINT_ERP : + case BT_CONSTRAINT_ERP: m_angularLimits[axis - 3].m_motorERP = value; m_flags |= BT_6DOF_FLAGS_ERP_MOTO2 << (axis * BT_6DOF_FLAGS_AXIS_SHIFT2); break; - case BT_CONSTRAINT_CFM : + case BT_CONSTRAINT_CFM: m_angularLimits[axis - 3].m_motorCFM = value; m_flags |= BT_6DOF_FLAGS_CFM_MOTO2 << (axis * BT_6DOF_FLAGS_AXIS_SHIFT2); break; - default : + default: btAssertConstrParams(0); } } @@ -915,54 +942,54 @@ void btGeneric6DofSpring2Constraint::setParam(int num, btScalar value, int axis) } //return the local value of parameter -btScalar btGeneric6DofSpring2Constraint::getParam(int num, int axis) const +btScalar btGeneric6DofSpring2Constraint::getParam(int num, int axis) const { btScalar retVal = 0; - if((axis >= 0) && (axis < 3)) + if ((axis >= 0) && (axis < 3)) { - switch(num) + switch (num) { - case BT_CONSTRAINT_STOP_ERP : + case BT_CONSTRAINT_STOP_ERP: btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_ERP_STOP2 << (axis * BT_6DOF_FLAGS_AXIS_SHIFT2))); retVal = m_linearLimits.m_stopERP[axis]; break; - case BT_CONSTRAINT_STOP_CFM : + case BT_CONSTRAINT_STOP_CFM: btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_CFM_STOP2 << (axis * BT_6DOF_FLAGS_AXIS_SHIFT2))); retVal = m_linearLimits.m_stopCFM[axis]; break; - case BT_CONSTRAINT_ERP : + case BT_CONSTRAINT_ERP: btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_ERP_MOTO2 << (axis * BT_6DOF_FLAGS_AXIS_SHIFT2))); retVal = m_linearLimits.m_motorERP[axis]; break; - case BT_CONSTRAINT_CFM : + case BT_CONSTRAINT_CFM: btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_CFM_MOTO2 << (axis * BT_6DOF_FLAGS_AXIS_SHIFT2))); retVal = m_linearLimits.m_motorCFM[axis]; break; - default : + default: btAssertConstrParams(0); } } - else if((axis >=3) && (axis < 6)) + else if ((axis >= 3) && (axis < 6)) { - switch(num) + switch (num) { - case BT_CONSTRAINT_STOP_ERP : + case BT_CONSTRAINT_STOP_ERP: btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_ERP_STOP2 << (axis * BT_6DOF_FLAGS_AXIS_SHIFT2))); retVal = m_angularLimits[axis - 3].m_stopERP; break; - case BT_CONSTRAINT_STOP_CFM : + case BT_CONSTRAINT_STOP_CFM: btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_CFM_STOP2 << (axis * BT_6DOF_FLAGS_AXIS_SHIFT2))); retVal = m_angularLimits[axis - 3].m_stopCFM; break; - case BT_CONSTRAINT_ERP : + case BT_CONSTRAINT_ERP: btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_ERP_MOTO2 << (axis * BT_6DOF_FLAGS_AXIS_SHIFT2))); retVal = m_angularLimits[axis - 3].m_motorERP; break; - case BT_CONSTRAINT_CFM : + case BT_CONSTRAINT_CFM: btAssertConstrParams(m_flags & (BT_6DOF_FLAGS_CFM_MOTO2 << (axis * BT_6DOF_FLAGS_AXIS_SHIFT2))); retVal = m_angularLimits[axis - 3].m_motorCFM; break; - default : + default: btAssertConstrParams(0); } } @@ -973,31 +1000,29 @@ btScalar btGeneric6DofSpring2Constraint::getParam(int num, int axis) const return retVal; } - - -void btGeneric6DofSpring2Constraint::setAxis(const btVector3& axis1,const btVector3& axis2) +void btGeneric6DofSpring2Constraint::setAxis(const btVector3& axis1, const btVector3& axis2) { btVector3 zAxis = axis1.normalized(); btVector3 yAxis = axis2.normalized(); - btVector3 xAxis = yAxis.cross(zAxis); // we want right coordinate system - + btVector3 xAxis = yAxis.cross(zAxis); // we want right coordinate system + btTransform frameInW; frameInW.setIdentity(); - frameInW.getBasis().setValue( xAxis[0], yAxis[0], zAxis[0], - xAxis[1], yAxis[1], zAxis[1], - xAxis[2], yAxis[2], zAxis[2]); - + frameInW.getBasis().setValue(xAxis[0], yAxis[0], zAxis[0], + xAxis[1], yAxis[1], zAxis[1], + xAxis[2], yAxis[2], zAxis[2]); + // now get constraint frame in local coordinate systems m_frameInA = m_rbA.getCenterOfMassTransform().inverse() * frameInW; m_frameInB = m_rbB.getCenterOfMassTransform().inverse() * frameInW; - + calculateTransforms(); } void btGeneric6DofSpring2Constraint::setBounce(int index, btScalar bounce) { btAssert((index >= 0) && (index < 6)); - if (index<3) + if (index < 3) m_linearLimits.m_bounce[index] = bounce; else m_angularLimits[index - 3].m_bounce = bounce; @@ -1006,7 +1031,7 @@ void btGeneric6DofSpring2Constraint::setBounce(int index, btScalar bounce) void btGeneric6DofSpring2Constraint::enableMotor(int index, bool onOff) { btAssert((index >= 0) && (index < 6)); - if (index<3) + if (index < 3) m_linearLimits.m_enableMotor[index] = onOff; else m_angularLimits[index - 3].m_enableMotor = onOff; @@ -1015,7 +1040,7 @@ void btGeneric6DofSpring2Constraint::enableMotor(int index, bool onOff) void btGeneric6DofSpring2Constraint::setServo(int index, bool onOff) { btAssert((index >= 0) && (index < 6)); - if (index<3) + if (index < 3) m_linearLimits.m_servoMotor[index] = onOff; else m_angularLimits[index - 3].m_servoMotor = onOff; @@ -1024,18 +1049,16 @@ void btGeneric6DofSpring2Constraint::setServo(int index, bool onOff) void btGeneric6DofSpring2Constraint::setTargetVelocity(int index, btScalar velocity) { btAssert((index >= 0) && (index < 6)); - if (index<3) + if (index < 3) m_linearLimits.m_targetVelocity[index] = velocity; else m_angularLimits[index - 3].m_targetVelocity = velocity; } - - void btGeneric6DofSpring2Constraint::setServoTarget(int index, btScalar targetOrg) { btAssert((index >= 0) && (index < 6)); - if (index<3) + if (index < 3) { m_linearLimits.m_servoTarget[index] = targetOrg; } @@ -1044,23 +1067,24 @@ void btGeneric6DofSpring2Constraint::setServoTarget(int index, btScalar targetOr //wrap between -PI and PI, see also //https://stackoverflow.com/questions/4633177/c-how-to-wrap-a-float-to-the-interval-pi-pi - btScalar target = targetOrg+SIMD_PI; + btScalar target = targetOrg + SIMD_PI; if (1) { - btScalar m = target - SIMD_2_PI * floor(target/SIMD_2_PI); + btScalar m = target - SIMD_2_PI * floor(target / SIMD_2_PI); // handle boundary cases resulted from floating-point cut off: { - if (m>=SIMD_2_PI) + if (m >= SIMD_2_PI) { target = 0; - } else + } + else { - if (m<0 ) + if (m < 0) { - if (SIMD_2_PI+m == SIMD_2_PI) + if (SIMD_2_PI + m == SIMD_2_PI) target = 0; else - target = SIMD_2_PI+m; + target = SIMD_2_PI + m; } else { @@ -1070,7 +1094,7 @@ void btGeneric6DofSpring2Constraint::setServoTarget(int index, btScalar targetOr } target -= SIMD_PI; } - + m_angularLimits[index - 3].m_servoTarget = target; } } @@ -1078,7 +1102,7 @@ void btGeneric6DofSpring2Constraint::setServoTarget(int index, btScalar targetOr void btGeneric6DofSpring2Constraint::setMaxMotorForce(int index, btScalar force) { btAssert((index >= 0) && (index < 6)); - if (index<3) + if (index < 3) m_linearLimits.m_maxMotorForce[index] = force; else m_angularLimits[index - 3].m_maxMotorForce = force; @@ -1087,19 +1111,22 @@ void btGeneric6DofSpring2Constraint::setMaxMotorForce(int index, btScalar force) void btGeneric6DofSpring2Constraint::enableSpring(int index, bool onOff) { btAssert((index >= 0) && (index < 6)); - if (index<3) + if (index < 3) m_linearLimits.m_enableSpring[index] = onOff; else - m_angularLimits[index - 3] .m_enableSpring = onOff; + m_angularLimits[index - 3].m_enableSpring = onOff; } void btGeneric6DofSpring2Constraint::setStiffness(int index, btScalar stiffness, bool limitIfNeeded) { btAssert((index >= 0) && (index < 6)); - if (index<3) { + if (index < 3) + { m_linearLimits.m_springStiffness[index] = stiffness; m_linearLimits.m_springStiffnessLimited[index] = limitIfNeeded; - } else { + } + else + { m_angularLimits[index - 3].m_springStiffness = stiffness; m_angularLimits[index - 3].m_springStiffnessLimited = limitIfNeeded; } @@ -1108,10 +1135,13 @@ void btGeneric6DofSpring2Constraint::setStiffness(int index, btScalar stiffness, void btGeneric6DofSpring2Constraint::setDamping(int index, btScalar damping, bool limitIfNeeded) { btAssert((index >= 0) && (index < 6)); - if (index<3) { + if (index < 3) + { m_linearLimits.m_springDamping[index] = damping; m_linearLimits.m_springDampingLimited[index] = limitIfNeeded; - } else { + } + else + { m_angularLimits[index - 3].m_springDamping = damping; m_angularLimits[index - 3].m_springDampingLimited = limitIfNeeded; } @@ -1121,9 +1151,9 @@ void btGeneric6DofSpring2Constraint::setEquilibriumPoint() { calculateTransforms(); int i; - for( i = 0; i < 3; i++) + for (i = 0; i < 3; i++) m_linearLimits.m_equilibriumPoint[i] = m_calculatedLinearDiff[i]; - for(i = 0; i < 3; i++) + for (i = 0; i < 3; i++) m_angularLimits[i].m_equilibriumPoint = m_calculatedAxisAngleDiff[i]; } @@ -1131,35 +1161,38 @@ void btGeneric6DofSpring2Constraint::setEquilibriumPoint(int index) { btAssert((index >= 0) && (index < 6)); calculateTransforms(); - if (index<3) + if (index < 3) m_linearLimits.m_equilibriumPoint[index] = m_calculatedLinearDiff[index]; else - m_angularLimits[index - 3] .m_equilibriumPoint = m_calculatedAxisAngleDiff[index - 3]; + m_angularLimits[index - 3].m_equilibriumPoint = m_calculatedAxisAngleDiff[index - 3]; } void btGeneric6DofSpring2Constraint::setEquilibriumPoint(int index, btScalar val) { btAssert((index >= 0) && (index < 6)); - if (index<3) + if (index < 3) m_linearLimits.m_equilibriumPoint[index] = val; else - m_angularLimits[index - 3] .m_equilibriumPoint = val; + m_angularLimits[index - 3].m_equilibriumPoint = val; } - //////////////////////////// btRotationalLimitMotor2 //////////////////////////////////// void btRotationalLimitMotor2::testLimitValue(btScalar test_value) { //we can't normalize the angles here because we would lost the sign that we use later, but it doesn't seem to be a problem - if(m_loLimit > m_hiLimit) { + if (m_loLimit > m_hiLimit) + { m_currentLimit = 0; m_currentLimitError = btScalar(0.f); } - else if(m_loLimit == m_hiLimit) { + else if (m_loLimit == m_hiLimit) + { m_currentLimitError = test_value - m_loLimit; m_currentLimit = 3; - } else { + } + else + { m_currentLimitError = test_value - m_loLimit; m_currentLimitErrorHi = test_value - m_hiLimit; m_currentLimit = 4; @@ -1172,18 +1205,20 @@ void btTranslationalLimitMotor2::testLimitValue(int limitIndex, btScalar test_va { btScalar loLimit = m_lowerLimit[limitIndex]; btScalar hiLimit = m_upperLimit[limitIndex]; - if(loLimit > hiLimit) { + if (loLimit > hiLimit) + { m_currentLimitError[limitIndex] = 0; m_currentLimit[limitIndex] = 0; } - else if(loLimit == hiLimit) { + else if (loLimit == hiLimit) + { m_currentLimitError[limitIndex] = test_value - loLimit; m_currentLimit[limitIndex] = 3; - } else { + } + else + { m_currentLimitError[limitIndex] = test_value - loLimit; m_currentLimitErrorHi[limitIndex] = test_value - hiLimit; m_currentLimit[limitIndex] = 4; } } - - diff --git a/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h b/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h index fc2ed4f7a..55c1363ed 100644 --- a/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h +++ b/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpring2Constraint.h @@ -37,7 +37,6 @@ email: projectileman@yahoo.com http://gimpact.sf.net */ - #ifndef BT_GENERIC_6DOF_CONSTRAINT2_H #define BT_GENERIC_6DOF_CONSTRAINT2_H @@ -47,18 +46,17 @@ http://gimpact.sf.net class btRigidBody; - #ifdef BT_USE_DOUBLE_PRECISION -#define btGeneric6DofSpring2ConstraintData2 btGeneric6DofSpring2ConstraintDoubleData2 -#define btGeneric6DofSpring2ConstraintDataName "btGeneric6DofSpring2ConstraintDoubleData2" +#define btGeneric6DofSpring2ConstraintData2 btGeneric6DofSpring2ConstraintDoubleData2 +#define btGeneric6DofSpring2ConstraintDataName "btGeneric6DofSpring2ConstraintDoubleData2" #else -#define btGeneric6DofSpring2ConstraintData2 btGeneric6DofSpring2ConstraintData -#define btGeneric6DofSpring2ConstraintDataName "btGeneric6DofSpring2ConstraintData" -#endif //BT_USE_DOUBLE_PRECISION +#define btGeneric6DofSpring2ConstraintData2 btGeneric6DofSpring2ConstraintData +#define btGeneric6DofSpring2ConstraintDataName "btGeneric6DofSpring2ConstraintData" +#endif //BT_USE_DOUBLE_PRECISION enum RotateOrder { - RO_XYZ=0, + RO_XYZ = 0, RO_XZY, RO_YXZ, RO_YZX, @@ -69,9 +67,9 @@ enum RotateOrder class btRotationalLimitMotor2 { public: -// upper < lower means free -// upper == lower means locked -// upper > lower means limited + // upper < lower means free + // upper == lower means locked + // upper > lower means limited btScalar m_loLimit; btScalar m_hiLimit; btScalar m_bounce; @@ -79,95 +77,92 @@ public: btScalar m_stopCFM; btScalar m_motorERP; btScalar m_motorCFM; - bool m_enableMotor; + bool m_enableMotor; btScalar m_targetVelocity; btScalar m_maxMotorForce; - bool m_servoMotor; + bool m_servoMotor; btScalar m_servoTarget; - bool m_enableSpring; + bool m_enableSpring; btScalar m_springStiffness; - bool m_springStiffnessLimited; + bool m_springStiffnessLimited; btScalar m_springDamping; - bool m_springDampingLimited; + bool m_springDampingLimited; btScalar m_equilibriumPoint; btScalar m_currentLimitError; btScalar m_currentLimitErrorHi; btScalar m_currentPosition; - int m_currentLimit; + int m_currentLimit; btRotationalLimitMotor2() { - m_loLimit = 1.0f; - m_hiLimit = -1.0f; - m_bounce = 0.0f; - m_stopERP = 0.2f; - m_stopCFM = 0.f; - m_motorERP = 0.9f; - m_motorCFM = 0.f; - m_enableMotor = false; - m_targetVelocity = 0; - m_maxMotorForce = 6.0f; - m_servoMotor = false; - m_servoTarget = 0; - m_enableSpring = false; - m_springStiffness = 0; + m_loLimit = 1.0f; + m_hiLimit = -1.0f; + m_bounce = 0.0f; + m_stopERP = 0.2f; + m_stopCFM = 0.f; + m_motorERP = 0.9f; + m_motorCFM = 0.f; + m_enableMotor = false; + m_targetVelocity = 0; + m_maxMotorForce = 6.0f; + m_servoMotor = false; + m_servoTarget = 0; + m_enableSpring = false; + m_springStiffness = 0; m_springStiffnessLimited = false; - m_springDamping = 0; - m_springDampingLimited = false; - m_equilibriumPoint = 0; + m_springDamping = 0; + m_springDampingLimited = false; + m_equilibriumPoint = 0; - m_currentLimitError = 0; + m_currentLimitError = 0; m_currentLimitErrorHi = 0; - m_currentPosition = 0; - m_currentLimit = 0; + m_currentPosition = 0; + m_currentLimit = 0; } - btRotationalLimitMotor2(const btRotationalLimitMotor2 & limot) + btRotationalLimitMotor2(const btRotationalLimitMotor2& limot) { - m_loLimit = limot.m_loLimit; - m_hiLimit = limot.m_hiLimit; - m_bounce = limot.m_bounce; - m_stopERP = limot.m_stopERP; - m_stopCFM = limot.m_stopCFM; - m_motorERP = limot.m_motorERP; - m_motorCFM = limot.m_motorCFM; - m_enableMotor = limot.m_enableMotor; - m_targetVelocity = limot.m_targetVelocity; - m_maxMotorForce = limot.m_maxMotorForce; - m_servoMotor = limot.m_servoMotor; - m_servoTarget = limot.m_servoTarget; - m_enableSpring = limot.m_enableSpring; - m_springStiffness = limot.m_springStiffness; + m_loLimit = limot.m_loLimit; + m_hiLimit = limot.m_hiLimit; + m_bounce = limot.m_bounce; + m_stopERP = limot.m_stopERP; + m_stopCFM = limot.m_stopCFM; + m_motorERP = limot.m_motorERP; + m_motorCFM = limot.m_motorCFM; + m_enableMotor = limot.m_enableMotor; + m_targetVelocity = limot.m_targetVelocity; + m_maxMotorForce = limot.m_maxMotorForce; + m_servoMotor = limot.m_servoMotor; + m_servoTarget = limot.m_servoTarget; + m_enableSpring = limot.m_enableSpring; + m_springStiffness = limot.m_springStiffness; m_springStiffnessLimited = limot.m_springStiffnessLimited; - m_springDamping = limot.m_springDamping; - m_springDampingLimited = limot.m_springDampingLimited; - m_equilibriumPoint = limot.m_equilibriumPoint; + m_springDamping = limot.m_springDamping; + m_springDampingLimited = limot.m_springDampingLimited; + m_equilibriumPoint = limot.m_equilibriumPoint; - m_currentLimitError = limot.m_currentLimitError; + m_currentLimitError = limot.m_currentLimitError; m_currentLimitErrorHi = limot.m_currentLimitErrorHi; - m_currentPosition = limot.m_currentPosition; - m_currentLimit = limot.m_currentLimit; + m_currentPosition = limot.m_currentPosition; + m_currentLimit = limot.m_currentLimit; } - bool isLimited() { - if(m_loLimit > m_hiLimit) return false; + if (m_loLimit > m_hiLimit) return false; return true; } void testLimitValue(btScalar test_value); }; - - class btTranslationalLimitMotor2 { public: -// upper < lower means free -// upper == lower means locked -// upper > lower means limited + // upper < lower means free + // upper == lower means locked + // upper > lower means limited btVector3 m_lowerLimit; btVector3 m_upperLimit; btVector3 m_bounce; @@ -175,14 +170,14 @@ public: btVector3 m_stopCFM; btVector3 m_motorERP; btVector3 m_motorCFM; - bool m_enableMotor[3]; - bool m_servoMotor[3]; - bool m_enableSpring[3]; + bool m_enableMotor[3]; + bool m_servoMotor[3]; + bool m_enableSpring[3]; btVector3 m_servoTarget; btVector3 m_springStiffness; - bool m_springStiffnessLimited[3]; + bool m_springStiffnessLimited[3]; btVector3 m_springDamping; - bool m_springDampingLimited[3]; + bool m_springDampingLimited[3]; btVector3 m_equilibriumPoint; btVector3 m_targetVelocity; btVector3 m_maxMotorForce; @@ -190,69 +185,69 @@ public: btVector3 m_currentLimitError; btVector3 m_currentLimitErrorHi; btVector3 m_currentLinearDiff; - int m_currentLimit[3]; + int m_currentLimit[3]; btTranslationalLimitMotor2() { - m_lowerLimit .setValue(0.f , 0.f , 0.f ); - m_upperLimit .setValue(0.f , 0.f , 0.f ); - m_bounce .setValue(0.f , 0.f , 0.f ); - m_stopERP .setValue(0.2f, 0.2f, 0.2f); - m_stopCFM .setValue(0.f , 0.f , 0.f ); - m_motorERP .setValue(0.9f, 0.9f, 0.9f); - m_motorCFM .setValue(0.f , 0.f , 0.f ); + m_lowerLimit.setValue(0.f, 0.f, 0.f); + m_upperLimit.setValue(0.f, 0.f, 0.f); + m_bounce.setValue(0.f, 0.f, 0.f); + m_stopERP.setValue(0.2f, 0.2f, 0.2f); + m_stopCFM.setValue(0.f, 0.f, 0.f); + m_motorERP.setValue(0.9f, 0.9f, 0.9f); + m_motorCFM.setValue(0.f, 0.f, 0.f); - m_currentLimitError .setValue(0.f , 0.f , 0.f ); - m_currentLimitErrorHi.setValue(0.f , 0.f , 0.f ); - m_currentLinearDiff .setValue(0.f , 0.f , 0.f ); + m_currentLimitError.setValue(0.f, 0.f, 0.f); + m_currentLimitErrorHi.setValue(0.f, 0.f, 0.f); + m_currentLinearDiff.setValue(0.f, 0.f, 0.f); - for(int i=0; i < 3; i++) + for (int i = 0; i < 3; i++) { - m_enableMotor[i] = false; - m_servoMotor[i] = false; - m_enableSpring[i] = false; - m_servoTarget[i] = btScalar(0.f); - m_springStiffness[i] = btScalar(0.f); + m_enableMotor[i] = false; + m_servoMotor[i] = false; + m_enableSpring[i] = false; + m_servoTarget[i] = btScalar(0.f); + m_springStiffness[i] = btScalar(0.f); m_springStiffnessLimited[i] = false; - m_springDamping[i] = btScalar(0.f); - m_springDampingLimited[i] = false; - m_equilibriumPoint[i] = btScalar(0.f); - m_targetVelocity[i] = btScalar(0.f); - m_maxMotorForce[i] = btScalar(0.f); - - m_currentLimit[i] = 0; + m_springDamping[i] = btScalar(0.f); + m_springDampingLimited[i] = false; + m_equilibriumPoint[i] = btScalar(0.f); + m_targetVelocity[i] = btScalar(0.f); + m_maxMotorForce[i] = btScalar(0.f); + + m_currentLimit[i] = 0; } } - btTranslationalLimitMotor2(const btTranslationalLimitMotor2 & other ) + btTranslationalLimitMotor2(const btTranslationalLimitMotor2& other) { - m_lowerLimit = other.m_lowerLimit; - m_upperLimit = other.m_upperLimit; - m_bounce = other.m_bounce; - m_stopERP = other.m_stopERP; - m_stopCFM = other.m_stopCFM; - m_motorERP = other.m_motorERP; - m_motorCFM = other.m_motorCFM; - - m_currentLimitError = other.m_currentLimitError; + m_lowerLimit = other.m_lowerLimit; + m_upperLimit = other.m_upperLimit; + m_bounce = other.m_bounce; + m_stopERP = other.m_stopERP; + m_stopCFM = other.m_stopCFM; + m_motorERP = other.m_motorERP; + m_motorCFM = other.m_motorCFM; + + m_currentLimitError = other.m_currentLimitError; m_currentLimitErrorHi = other.m_currentLimitErrorHi; - m_currentLinearDiff = other.m_currentLinearDiff; + m_currentLinearDiff = other.m_currentLinearDiff; - for(int i=0; i < 3; i++) + for (int i = 0; i < 3; i++) { - m_enableMotor[i] = other.m_enableMotor[i]; - m_servoMotor[i] = other.m_servoMotor[i]; - m_enableSpring[i] = other.m_enableSpring[i]; - m_servoTarget[i] = other.m_servoTarget[i]; - m_springStiffness[i] = other.m_springStiffness[i]; + m_enableMotor[i] = other.m_enableMotor[i]; + m_servoMotor[i] = other.m_servoMotor[i]; + m_enableSpring[i] = other.m_enableSpring[i]; + m_servoTarget[i] = other.m_servoTarget[i]; + m_springStiffness[i] = other.m_springStiffness[i]; m_springStiffnessLimited[i] = other.m_springStiffnessLimited[i]; - m_springDamping[i] = other.m_springDamping[i]; - m_springDampingLimited[i] = other.m_springDampingLimited[i]; - m_equilibriumPoint[i] = other.m_equilibriumPoint[i]; - m_targetVelocity[i] = other.m_targetVelocity[i]; - m_maxMotorForce[i] = other.m_maxMotorForce[i]; + m_springDamping[i] = other.m_springDamping[i]; + m_springDampingLimited[i] = other.m_springDampingLimited[i]; + m_equilibriumPoint[i] = other.m_equilibriumPoint[i]; + m_targetVelocity[i] = other.m_targetVelocity[i]; + m_maxMotorForce[i] = other.m_maxMotorForce[i]; - m_currentLimit[i] = other.m_currentLimit[i]; + m_currentLimit[i] = other.m_currentLimit[i]; } } @@ -271,13 +266,12 @@ enum bt6DofFlags2 BT_6DOF_FLAGS_CFM_MOTO2 = 4, BT_6DOF_FLAGS_ERP_MOTO2 = 8 }; -#define BT_6DOF_FLAGS_AXIS_SHIFT2 4 // bits per axis +#define BT_6DOF_FLAGS_AXIS_SHIFT2 4 // bits per axis - -ATTRIBUTE_ALIGNED16(class) btGeneric6DofSpring2Constraint : public btTypedConstraint +ATTRIBUTE_ALIGNED16(class) +btGeneric6DofSpring2Constraint : public btTypedConstraint { protected: - btTransform m_frameInA; btTransform m_frameInB; @@ -290,45 +284,43 @@ protected: RotateOrder m_rotateOrder; protected: + btTransform m_calculatedTransformA; + btTransform m_calculatedTransformB; + btVector3 m_calculatedAxisAngleDiff; + btVector3 m_calculatedAxis[3]; + btVector3 m_calculatedLinearDiff; + btScalar m_factA; + btScalar m_factB; + bool m_hasStaticBody; + int m_flags; - btTransform m_calculatedTransformA; - btTransform m_calculatedTransformB; - btVector3 m_calculatedAxisAngleDiff; - btVector3 m_calculatedAxis[3]; - btVector3 m_calculatedLinearDiff; - btScalar m_factA; - btScalar m_factB; - bool m_hasStaticBody; - int m_flags; - - btGeneric6DofSpring2Constraint& operator=(btGeneric6DofSpring2Constraint&) + btGeneric6DofSpring2Constraint& operator=(btGeneric6DofSpring2Constraint&) { btAssert(0); return *this; } - int setAngularLimits(btConstraintInfo2 *info, int row_offset,const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB); - int setLinearLimits(btConstraintInfo2 *info, int row, const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB); + int setAngularLimits(btConstraintInfo2 * info, int row_offset, const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB); + int setLinearLimits(btConstraintInfo2 * info, int row, const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB); void calculateLinearInfo(); void calculateAngleInfo(); void testAngularLimitMotor(int axis_index); - void calculateJacobi(btRotationalLimitMotor2* limot, const btTransform& transA,const btTransform& transB, btConstraintInfo2* info, int srow, btVector3& ax1, int rotational, int rotAllowed); - int get_limit_motor_info2(btRotationalLimitMotor2* limot, - const btTransform& transA,const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB,const btVector3& angVelA,const btVector3& angVelB, - btConstraintInfo2* info, int row, btVector3& ax1, int rotational, int rotAllowed = false); + void calculateJacobi(btRotationalLimitMotor2 * limot, const btTransform& transA, const btTransform& transB, btConstraintInfo2* info, int srow, btVector3& ax1, int rotational, int rotAllowed); + int get_limit_motor_info2(btRotationalLimitMotor2 * limot, + const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, const btVector3& angVelA, const btVector3& angVelB, + btConstraintInfo2* info, int row, btVector3& ax1, int rotational, int rotAllowed = false); public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - btGeneric6DofSpring2Constraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, RotateOrder rotOrder = RO_XYZ); - btGeneric6DofSpring2Constraint(btRigidBody& rbB, const btTransform& frameInB, RotateOrder rotOrder = RO_XYZ); + btGeneric6DofSpring2Constraint(btRigidBody & rbA, btRigidBody & rbB, const btTransform& frameInA, const btTransform& frameInB, RotateOrder rotOrder = RO_XYZ); + btGeneric6DofSpring2Constraint(btRigidBody & rbB, const btTransform& frameInB, RotateOrder rotOrder = RO_XYZ); virtual void buildJacobian() {} - virtual void getInfo1 (btConstraintInfo1* info); - virtual void getInfo2 (btConstraintInfo2* info); + virtual void getInfo1(btConstraintInfo1 * info); + virtual void getInfo2(btConstraintInfo2 * info); virtual int calculateSerializeBufferSize() const; virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; @@ -336,19 +328,19 @@ public: btTranslationalLimitMotor2* getTranslationalLimitMotor() { return &m_linearLimits; } // Calculates the global transform for the joint offset for body A an B, and also calculates the angle differences between the bodies. - void calculateTransforms(const btTransform& transA,const btTransform& transB); + void calculateTransforms(const btTransform& transA, const btTransform& transB); void calculateTransforms(); // Gets the global transform of the offset for body A - const btTransform & getCalculatedTransformA() const { return m_calculatedTransformA; } + const btTransform& getCalculatedTransformA() const { return m_calculatedTransformA; } // Gets the global transform of the offset for body B - const btTransform & getCalculatedTransformB() const { return m_calculatedTransformB; } + const btTransform& getCalculatedTransformB() const { return m_calculatedTransformB; } - const btTransform & getFrameOffsetA() const { return m_frameInA; } - const btTransform & getFrameOffsetB() const { return m_frameInB; } + const btTransform& getFrameOffsetA() const { return m_frameInA; } + const btTransform& getFrameOffsetB() const { return m_frameInB; } - btTransform & getFrameOffsetA() { return m_frameInA; } - btTransform & getFrameOffsetB() { return m_frameInB; } + btTransform& getFrameOffsetA() { return m_frameInA; } + btTransform& getFrameOffsetB() { return m_frameInB; } // Get the rotation axis in global coordinates ( btGeneric6DofSpring2Constraint::calculateTransforms() must be called previously ) btVector3 getAxis(int axis_index) const { return m_calculatedAxis[axis_index]; } @@ -359,58 +351,58 @@ public: // Get the relative position of the constraint pivot ( btGeneric6DofSpring2Constraint::calculateTransforms() must be called previously ) btScalar getRelativePivotPosition(int axis_index) const { return m_calculatedLinearDiff[axis_index]; } - void setFrames(const btTransform & frameA, const btTransform & frameB); + void setFrames(const btTransform& frameA, const btTransform& frameB); void setLinearLowerLimit(const btVector3& linearLower) { m_linearLimits.m_lowerLimit = linearLower; } - void getLinearLowerLimit(btVector3& linearLower) { linearLower = m_linearLimits.m_lowerLimit; } + void getLinearLowerLimit(btVector3 & linearLower) { linearLower = m_linearLimits.m_lowerLimit; } void setLinearUpperLimit(const btVector3& linearUpper) { m_linearLimits.m_upperLimit = linearUpper; } - void getLinearUpperLimit(btVector3& linearUpper) { linearUpper = m_linearLimits.m_upperLimit; } + void getLinearUpperLimit(btVector3 & linearUpper) { linearUpper = m_linearLimits.m_upperLimit; } void setAngularLowerLimit(const btVector3& angularLower) { - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) m_angularLimits[i].m_loLimit = btNormalizeAngle(angularLower[i]); } void setAngularLowerLimitReversed(const btVector3& angularLower) { - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) m_angularLimits[i].m_hiLimit = btNormalizeAngle(-angularLower[i]); } - void getAngularLowerLimit(btVector3& angularLower) + void getAngularLowerLimit(btVector3 & angularLower) { - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) angularLower[i] = m_angularLimits[i].m_loLimit; } - void getAngularLowerLimitReversed(btVector3& angularLower) + void getAngularLowerLimitReversed(btVector3 & angularLower) { - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) angularLower[i] = -m_angularLimits[i].m_hiLimit; } void setAngularUpperLimit(const btVector3& angularUpper) { - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) m_angularLimits[i].m_hiLimit = btNormalizeAngle(angularUpper[i]); } void setAngularUpperLimitReversed(const btVector3& angularUpper) { - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) m_angularLimits[i].m_loLimit = btNormalizeAngle(-angularUpper[i]); } - void getAngularUpperLimit(btVector3& angularUpper) + void getAngularUpperLimit(btVector3 & angularUpper) { - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) angularUpper[i] = m_angularLimits[i].m_hiLimit; } - void getAngularUpperLimitReversed(btVector3& angularUpper) + void getAngularUpperLimitReversed(btVector3 & angularUpper) { - for(int i = 0; i < 3; i++) + for (int i = 0; i < 3; i++) angularUpper[i] = -m_angularLimits[i].m_loLimit; } @@ -418,7 +410,7 @@ public: void setLimit(int axis, btScalar lo, btScalar hi) { - if(axis<3) + if (axis < 3) { m_linearLimits.m_lowerLimit[axis] = lo; m_linearLimits.m_upperLimit[axis] = hi; @@ -427,14 +419,14 @@ public: { lo = btNormalizeAngle(lo); hi = btNormalizeAngle(hi); - m_angularLimits[axis-3].m_loLimit = lo; - m_angularLimits[axis-3].m_hiLimit = hi; + m_angularLimits[axis - 3].m_loLimit = lo; + m_angularLimits[axis - 3].m_hiLimit = hi; } } void setLimitReversed(int axis, btScalar lo, btScalar hi) { - if(axis<3) + if (axis < 3) { m_linearLimits.m_lowerLimit[axis] = lo; m_linearLimits.m_upperLimit[axis] = hi; @@ -443,54 +435,53 @@ public: { lo = btNormalizeAngle(lo); hi = btNormalizeAngle(hi); - m_angularLimits[axis-3].m_hiLimit = -lo; - m_angularLimits[axis-3].m_loLimit = -hi; + m_angularLimits[axis - 3].m_hiLimit = -lo; + m_angularLimits[axis - 3].m_loLimit = -hi; } } bool isLimited(int limitIndex) { - if(limitIndex<3) + if (limitIndex < 3) { return m_linearLimits.isLimited(limitIndex); } - return m_angularLimits[limitIndex-3].isLimited(); + return m_angularLimits[limitIndex - 3].isLimited(); } void setRotationOrder(RotateOrder order) { m_rotateOrder = order; } RotateOrder getRotationOrder() { return m_rotateOrder; } - void setAxis( const btVector3& axis1, const btVector3& axis2); + void setAxis(const btVector3& axis1, const btVector3& axis2); void setBounce(int index, btScalar bounce); void enableMotor(int index, bool onOff); - void setServo(int index, bool onOff); // set the type of the motor (servo or not) (the motor has to be turned on for servo also) + void setServo(int index, bool onOff); // set the type of the motor (servo or not) (the motor has to be turned on for servo also) void setTargetVelocity(int index, btScalar velocity); void setServoTarget(int index, btScalar target); void setMaxMotorForce(int index, btScalar force); void enableSpring(int index, bool onOff); - void setStiffness(int index, btScalar stiffness, bool limitIfNeeded = true); // if limitIfNeeded is true the system will automatically limit the stiffness in necessary situations where otherwise the spring would move unrealistically too widely - void setDamping(int index, btScalar damping, bool limitIfNeeded = true); // if limitIfNeeded is true the system will automatically limit the damping in necessary situations where otherwise the spring would blow up - void setEquilibriumPoint(); // set the current constraint position/orientation as an equilibrium point for all DOF - void setEquilibriumPoint(int index); // set the current constraint position/orientation as an equilibrium point for given DOF + void setStiffness(int index, btScalar stiffness, bool limitIfNeeded = true); // if limitIfNeeded is true the system will automatically limit the stiffness in necessary situations where otherwise the spring would move unrealistically too widely + void setDamping(int index, btScalar damping, bool limitIfNeeded = true); // if limitIfNeeded is true the system will automatically limit the damping in necessary situations where otherwise the spring would blow up + void setEquilibriumPoint(); // set the current constraint position/orientation as an equilibrium point for all DOF + void setEquilibriumPoint(int index); // set the current constraint position/orientation as an equilibrium point for given DOF void setEquilibriumPoint(int index, btScalar val); - //override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). + //override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). //If no axis is provided, it uses the default axis for this constraint. virtual void setParam(int num, btScalar value, int axis = -1); virtual btScalar getParam(int num, int axis = -1) const; - - static btScalar btGetMatrixElem(const btMatrix3x3& mat, int index); - static bool matrixToEulerXYZ(const btMatrix3x3& mat,btVector3& xyz); - static bool matrixToEulerXZY(const btMatrix3x3& mat,btVector3& xyz); - static bool matrixToEulerYXZ(const btMatrix3x3& mat,btVector3& xyz); - static bool matrixToEulerYZX(const btMatrix3x3& mat,btVector3& xyz); - static bool matrixToEulerZXY(const btMatrix3x3& mat,btVector3& xyz); - static bool matrixToEulerZYX(const btMatrix3x3& mat,btVector3& xyz); -}; + static btScalar btGetMatrixElem(const btMatrix3x3& mat, int index); + static bool matrixToEulerXYZ(const btMatrix3x3& mat, btVector3& xyz); + static bool matrixToEulerXZY(const btMatrix3x3& mat, btVector3& xyz); + static bool matrixToEulerYXZ(const btMatrix3x3& mat, btVector3& xyz); + static bool matrixToEulerYZX(const btMatrix3x3& mat, btVector3& xyz); + static bool matrixToEulerZXY(const btMatrix3x3& mat, btVector3& xyz); + static bool matrixToEulerZYX(const btMatrix3x3& mat, btVector3& xyz); +}; struct btGeneric6DofSpring2ConstraintData { @@ -511,12 +502,12 @@ struct btGeneric6DofSpring2ConstraintData btVector3FloatData m_linearSpringStiffness; btVector3FloatData m_linearSpringDamping; btVector3FloatData m_linearEquilibriumPoint; - char m_linearEnableMotor[4]; - char m_linearServoMotor[4]; - char m_linearEnableSpring[4]; - char m_linearSpringStiffnessLimited[4]; - char m_linearSpringDampingLimited[4]; - char m_padding1[4]; + char m_linearEnableMotor[4]; + char m_linearServoMotor[4]; + char m_linearEnableSpring[4]; + char m_linearSpringStiffnessLimited[4]; + char m_linearSpringDampingLimited[4]; + char m_padding1[4]; btVector3FloatData m_angularUpperLimit; btVector3FloatData m_angularLowerLimit; @@ -531,13 +522,13 @@ struct btGeneric6DofSpring2ConstraintData btVector3FloatData m_angularSpringStiffness; btVector3FloatData m_angularSpringDamping; btVector3FloatData m_angularEquilibriumPoint; - char m_angularEnableMotor[4]; - char m_angularServoMotor[4]; - char m_angularEnableSpring[4]; - char m_angularSpringStiffnessLimited[4]; - char m_angularSpringDampingLimited[4]; + char m_angularEnableMotor[4]; + char m_angularServoMotor[4]; + char m_angularEnableSpring[4]; + char m_angularSpringStiffnessLimited[4]; + char m_angularSpringDampingLimited[4]; - int m_rotateOrder; + int m_rotateOrder; }; struct btGeneric6DofSpring2ConstraintDoubleData2 @@ -559,12 +550,12 @@ struct btGeneric6DofSpring2ConstraintDoubleData2 btVector3DoubleData m_linearSpringStiffness; btVector3DoubleData m_linearSpringDamping; btVector3DoubleData m_linearEquilibriumPoint; - char m_linearEnableMotor[4]; - char m_linearServoMotor[4]; - char m_linearEnableSpring[4]; - char m_linearSpringStiffnessLimited[4]; - char m_linearSpringDampingLimited[4]; - char m_padding1[4]; + char m_linearEnableMotor[4]; + char m_linearServoMotor[4]; + char m_linearEnableSpring[4]; + char m_linearSpringStiffnessLimited[4]; + char m_linearSpringDampingLimited[4]; + char m_padding1[4]; btVector3DoubleData m_angularUpperLimit; btVector3DoubleData m_angularLowerLimit; @@ -579,13 +570,13 @@ struct btGeneric6DofSpring2ConstraintDoubleData2 btVector3DoubleData m_angularSpringStiffness; btVector3DoubleData m_angularSpringDamping; btVector3DoubleData m_angularEquilibriumPoint; - char m_angularEnableMotor[4]; - char m_angularServoMotor[4]; - char m_angularEnableSpring[4]; - char m_angularSpringStiffnessLimited[4]; - char m_angularSpringDampingLimited[4]; + char m_angularEnableMotor[4]; + char m_angularServoMotor[4]; + char m_angularEnableSpring[4]; + char m_angularSpringStiffnessLimited[4]; + char m_angularSpringDampingLimited[4]; - int m_rotateOrder; + int m_rotateOrder; }; SIMD_FORCE_INLINE int btGeneric6DofSpring2Constraint::calculateSerializeBufferSize() const @@ -596,84 +587,80 @@ SIMD_FORCE_INLINE int btGeneric6DofSpring2Constraint::calculateSerializeBufferSi SIMD_FORCE_INLINE const char* btGeneric6DofSpring2Constraint::serialize(void* dataBuffer, btSerializer* serializer) const { btGeneric6DofSpring2ConstraintData2* dof = (btGeneric6DofSpring2ConstraintData2*)dataBuffer; - btTypedConstraint::serialize(&dof->m_typeConstraintData,serializer); + btTypedConstraint::serialize(&dof->m_typeConstraintData, serializer); m_frameInA.serialize(dof->m_rbAFrame); m_frameInB.serialize(dof->m_rbBFrame); int i; - for (i=0;i<3;i++) + for (i = 0; i < 3; i++) { - dof->m_angularLowerLimit.m_floats[i] = m_angularLimits[i].m_loLimit; - dof->m_angularUpperLimit.m_floats[i] = m_angularLimits[i].m_hiLimit; - dof->m_angularBounce.m_floats[i] = m_angularLimits[i].m_bounce; - dof->m_angularStopERP.m_floats[i] = m_angularLimits[i].m_stopERP; - dof->m_angularStopCFM.m_floats[i] = m_angularLimits[i].m_stopCFM; - dof->m_angularMotorERP.m_floats[i] = m_angularLimits[i].m_motorERP; - dof->m_angularMotorCFM.m_floats[i] = m_angularLimits[i].m_motorCFM; - dof->m_angularTargetVelocity.m_floats[i] = m_angularLimits[i].m_targetVelocity; - dof->m_angularMaxMotorForce.m_floats[i] = m_angularLimits[i].m_maxMotorForce; - dof->m_angularServoTarget.m_floats[i] = m_angularLimits[i].m_servoTarget; - dof->m_angularSpringStiffness.m_floats[i] = m_angularLimits[i].m_springStiffness; - dof->m_angularSpringDamping.m_floats[i] = m_angularLimits[i].m_springDamping; + dof->m_angularLowerLimit.m_floats[i] = m_angularLimits[i].m_loLimit; + dof->m_angularUpperLimit.m_floats[i] = m_angularLimits[i].m_hiLimit; + dof->m_angularBounce.m_floats[i] = m_angularLimits[i].m_bounce; + dof->m_angularStopERP.m_floats[i] = m_angularLimits[i].m_stopERP; + dof->m_angularStopCFM.m_floats[i] = m_angularLimits[i].m_stopCFM; + dof->m_angularMotorERP.m_floats[i] = m_angularLimits[i].m_motorERP; + dof->m_angularMotorCFM.m_floats[i] = m_angularLimits[i].m_motorCFM; + dof->m_angularTargetVelocity.m_floats[i] = m_angularLimits[i].m_targetVelocity; + dof->m_angularMaxMotorForce.m_floats[i] = m_angularLimits[i].m_maxMotorForce; + dof->m_angularServoTarget.m_floats[i] = m_angularLimits[i].m_servoTarget; + dof->m_angularSpringStiffness.m_floats[i] = m_angularLimits[i].m_springStiffness; + dof->m_angularSpringDamping.m_floats[i] = m_angularLimits[i].m_springDamping; dof->m_angularEquilibriumPoint.m_floats[i] = m_angularLimits[i].m_equilibriumPoint; } - dof->m_angularLowerLimit.m_floats[3] = 0; - dof->m_angularUpperLimit.m_floats[3] = 0; - dof->m_angularBounce.m_floats[3] = 0; - dof->m_angularStopERP.m_floats[3] = 0; - dof->m_angularStopCFM.m_floats[3] = 0; - dof->m_angularMotorERP.m_floats[3] = 0; - dof->m_angularMotorCFM.m_floats[3] = 0; - dof->m_angularTargetVelocity.m_floats[3] = 0; - dof->m_angularMaxMotorForce.m_floats[3] = 0; - dof->m_angularServoTarget.m_floats[3] = 0; - dof->m_angularSpringStiffness.m_floats[3] = 0; - dof->m_angularSpringDamping.m_floats[3] = 0; + dof->m_angularLowerLimit.m_floats[3] = 0; + dof->m_angularUpperLimit.m_floats[3] = 0; + dof->m_angularBounce.m_floats[3] = 0; + dof->m_angularStopERP.m_floats[3] = 0; + dof->m_angularStopCFM.m_floats[3] = 0; + dof->m_angularMotorERP.m_floats[3] = 0; + dof->m_angularMotorCFM.m_floats[3] = 0; + dof->m_angularTargetVelocity.m_floats[3] = 0; + dof->m_angularMaxMotorForce.m_floats[3] = 0; + dof->m_angularServoTarget.m_floats[3] = 0; + dof->m_angularSpringStiffness.m_floats[3] = 0; + dof->m_angularSpringDamping.m_floats[3] = 0; dof->m_angularEquilibriumPoint.m_floats[3] = 0; - for (i=0;i<4;i++) + for (i = 0; i < 4; i++) { - dof->m_angularEnableMotor[i] = i < 3 ? ( m_angularLimits[i].m_enableMotor ? 1 : 0 ) : 0; - dof->m_angularServoMotor[i] = i < 3 ? ( m_angularLimits[i].m_servoMotor ? 1 : 0 ) : 0; - dof->m_angularEnableSpring[i] = i < 3 ? ( m_angularLimits[i].m_enableSpring ? 1 : 0 ) : 0; - dof->m_angularSpringStiffnessLimited[i] = i < 3 ? ( m_angularLimits[i].m_springStiffnessLimited ? 1 : 0 ) : 0; - dof->m_angularSpringDampingLimited[i] = i < 3 ? ( m_angularLimits[i].m_springDampingLimited ? 1 : 0 ) : 0; + dof->m_angularEnableMotor[i] = i < 3 ? (m_angularLimits[i].m_enableMotor ? 1 : 0) : 0; + dof->m_angularServoMotor[i] = i < 3 ? (m_angularLimits[i].m_servoMotor ? 1 : 0) : 0; + dof->m_angularEnableSpring[i] = i < 3 ? (m_angularLimits[i].m_enableSpring ? 1 : 0) : 0; + dof->m_angularSpringStiffnessLimited[i] = i < 3 ? (m_angularLimits[i].m_springStiffnessLimited ? 1 : 0) : 0; + dof->m_angularSpringDampingLimited[i] = i < 3 ? (m_angularLimits[i].m_springDampingLimited ? 1 : 0) : 0; } - m_linearLimits.m_lowerLimit.serialize( dof->m_linearLowerLimit ); - m_linearLimits.m_upperLimit.serialize( dof->m_linearUpperLimit ); - m_linearLimits.m_bounce.serialize( dof->m_linearBounce ); - m_linearLimits.m_stopERP.serialize( dof->m_linearStopERP ); - m_linearLimits.m_stopCFM.serialize( dof->m_linearStopCFM ); - m_linearLimits.m_motorERP.serialize( dof->m_linearMotorERP ); - m_linearLimits.m_motorCFM.serialize( dof->m_linearMotorCFM ); - m_linearLimits.m_targetVelocity.serialize( dof->m_linearTargetVelocity ); - m_linearLimits.m_maxMotorForce.serialize( dof->m_linearMaxMotorForce ); - m_linearLimits.m_servoTarget.serialize( dof->m_linearServoTarget ); - m_linearLimits.m_springStiffness.serialize( dof->m_linearSpringStiffness ); - m_linearLimits.m_springDamping.serialize( dof->m_linearSpringDamping ); - m_linearLimits.m_equilibriumPoint.serialize( dof->m_linearEquilibriumPoint ); - for (i=0;i<4;i++) + m_linearLimits.m_lowerLimit.serialize(dof->m_linearLowerLimit); + m_linearLimits.m_upperLimit.serialize(dof->m_linearUpperLimit); + m_linearLimits.m_bounce.serialize(dof->m_linearBounce); + m_linearLimits.m_stopERP.serialize(dof->m_linearStopERP); + m_linearLimits.m_stopCFM.serialize(dof->m_linearStopCFM); + m_linearLimits.m_motorERP.serialize(dof->m_linearMotorERP); + m_linearLimits.m_motorCFM.serialize(dof->m_linearMotorCFM); + m_linearLimits.m_targetVelocity.serialize(dof->m_linearTargetVelocity); + m_linearLimits.m_maxMotorForce.serialize(dof->m_linearMaxMotorForce); + m_linearLimits.m_servoTarget.serialize(dof->m_linearServoTarget); + m_linearLimits.m_springStiffness.serialize(dof->m_linearSpringStiffness); + m_linearLimits.m_springDamping.serialize(dof->m_linearSpringDamping); + m_linearLimits.m_equilibriumPoint.serialize(dof->m_linearEquilibriumPoint); + for (i = 0; i < 4; i++) { - dof->m_linearEnableMotor[i] = i < 3 ? ( m_linearLimits.m_enableMotor[i] ? 1 : 0 ) : 0; - dof->m_linearServoMotor[i] = i < 3 ? ( m_linearLimits.m_servoMotor[i] ? 1 : 0 ) : 0; - dof->m_linearEnableSpring[i] = i < 3 ? ( m_linearLimits.m_enableSpring[i] ? 1 : 0 ) : 0; - dof->m_linearSpringStiffnessLimited[i] = i < 3 ? ( m_linearLimits.m_springStiffnessLimited[i] ? 1 : 0 ) : 0; - dof->m_linearSpringDampingLimited[i] = i < 3 ? ( m_linearLimits.m_springDampingLimited[i] ? 1 : 0 ) : 0; + dof->m_linearEnableMotor[i] = i < 3 ? (m_linearLimits.m_enableMotor[i] ? 1 : 0) : 0; + dof->m_linearServoMotor[i] = i < 3 ? (m_linearLimits.m_servoMotor[i] ? 1 : 0) : 0; + dof->m_linearEnableSpring[i] = i < 3 ? (m_linearLimits.m_enableSpring[i] ? 1 : 0) : 0; + dof->m_linearSpringStiffnessLimited[i] = i < 3 ? (m_linearLimits.m_springStiffnessLimited[i] ? 1 : 0) : 0; + dof->m_linearSpringDampingLimited[i] = i < 3 ? (m_linearLimits.m_springDampingLimited[i] ? 1 : 0) : 0; } dof->m_rotateOrder = m_rotateOrder; - dof->m_padding1[0] = 0; - dof->m_padding1[1] = 0; - dof->m_padding1[2] = 0; - dof->m_padding1[3] = 0; - + dof->m_padding1[0] = 0; + dof->m_padding1[1] = 0; + dof->m_padding1[2] = 0; + dof->m_padding1[3] = 0; + return btGeneric6DofSpring2ConstraintDataName; } - - - - -#endif //BT_GENERIC_6DOF_CONSTRAINT_H +#endif //BT_GENERIC_6DOF_CONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp index 3f875989e..8baf52bcd 100644 --- a/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp +++ b/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.cpp @@ -17,26 +17,23 @@ subject to the following restrictions: #include "BulletDynamics/Dynamics/btRigidBody.h" #include "LinearMath/btTransformUtil.h" - -btGeneric6DofSpringConstraint::btGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA) +btGeneric6DofSpringConstraint::btGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA) : btGeneric6DofConstraint(rbA, rbB, frameInA, frameInB, useLinearReferenceFrameA) { - init(); + init(); } - btGeneric6DofSpringConstraint::btGeneric6DofSpringConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB) - : btGeneric6DofConstraint(rbB, frameInB, useLinearReferenceFrameB) + : btGeneric6DofConstraint(rbB, frameInB, useLinearReferenceFrameB) { - init(); + init(); } - void btGeneric6DofSpringConstraint::init() { m_objectType = D6_SPRING_CONSTRAINT_TYPE; - for(int i = 0; i < 6; i++) + for (int i = 0; i < 6; i++) { m_springEnabled[i] = false; m_equilibriumPoint[i] = btScalar(0.f); @@ -45,12 +42,11 @@ void btGeneric6DofSpringConstraint::init() } } - void btGeneric6DofSpringConstraint::enableSpring(int index, bool onOff) { btAssert((index >= 0) && (index < 6)); m_springEnabled[index] = onOff; - if(index < 3) + if (index < 3) { m_linearLimits.m_enableMotor[index] = onOff; } @@ -60,44 +56,38 @@ void btGeneric6DofSpringConstraint::enableSpring(int index, bool onOff) } } - - void btGeneric6DofSpringConstraint::setStiffness(int index, btScalar stiffness) { btAssert((index >= 0) && (index < 6)); m_springStiffness[index] = stiffness; } - void btGeneric6DofSpringConstraint::setDamping(int index, btScalar damping) { btAssert((index >= 0) && (index < 6)); m_springDamping[index] = damping; } - void btGeneric6DofSpringConstraint::setEquilibriumPoint() { calculateTransforms(); int i; - for( i = 0; i < 3; i++) + for (i = 0; i < 3; i++) { m_equilibriumPoint[i] = m_calculatedLinearDiff[i]; } - for(i = 0; i < 3; i++) + for (i = 0; i < 3; i++) { m_equilibriumPoint[i + 3] = m_calculatedAxisAngleDiff[i]; } } - - void btGeneric6DofSpringConstraint::setEquilibriumPoint(int index) { btAssert((index >= 0) && (index < 6)); calculateTransforms(); - if(index < 3) + if (index < 3) { m_equilibriumPoint[index] = m_calculatedLinearDiff[index]; } @@ -113,15 +103,14 @@ void btGeneric6DofSpringConstraint::setEquilibriumPoint(int index, btScalar val) m_equilibriumPoint[index] = val; } - void btGeneric6DofSpringConstraint::internalUpdateSprings(btConstraintInfo2* info) { // it is assumed that calculateTransforms() have been called before this call int i; //btVector3 relVel = m_rbB.getLinearVelocity() - m_rbA.getLinearVelocity(); - for(i = 0; i < 3; i++) + for (i = 0; i < 3; i++) { - if(m_springEnabled[i]) + if (m_springEnabled[i]) { // get current position of constraint btScalar currPos = m_calculatedLinearDiff[i]; @@ -130,28 +119,27 @@ void btGeneric6DofSpringConstraint::internalUpdateSprings(btConstraintInfo2* inf // spring force is (delta * m_stiffness) according to Hooke's Law btScalar force = delta * m_springStiffness[i]; btScalar velFactor = info->fps * m_springDamping[i] / btScalar(info->m_numIterations); - m_linearLimits.m_targetVelocity[i] = velFactor * force; - m_linearLimits.m_maxMotorForce[i] = btFabs(force); + m_linearLimits.m_targetVelocity[i] = velFactor * force; + m_linearLimits.m_maxMotorForce[i] = btFabs(force); } } - for(i = 0; i < 3; i++) + for (i = 0; i < 3; i++) { - if(m_springEnabled[i + 3]) + if (m_springEnabled[i + 3]) { // get current position of constraint btScalar currPos = m_calculatedAxisAngleDiff[i]; // calculate difference - btScalar delta = currPos - m_equilibriumPoint[i+3]; + btScalar delta = currPos - m_equilibriumPoint[i + 3]; // spring force is (-delta * m_stiffness) according to Hooke's Law - btScalar force = -delta * m_springStiffness[i+3]; - btScalar velFactor = info->fps * m_springDamping[i+3] / btScalar(info->m_numIterations); + btScalar force = -delta * m_springStiffness[i + 3]; + btScalar velFactor = info->fps * m_springDamping[i + 3] / btScalar(info->m_numIterations); m_angularLimits[i].m_targetVelocity = velFactor * force; m_angularLimits[i].m_maxMotorForce = btFabs(force); } } } - void btGeneric6DofSpringConstraint::getInfo2(btConstraintInfo2* info) { // this will be called by constraint solver at the constraint setup stage @@ -161,25 +149,21 @@ void btGeneric6DofSpringConstraint::getInfo2(btConstraintInfo2* info) btGeneric6DofConstraint::getInfo2(info); } - -void btGeneric6DofSpringConstraint::setAxis(const btVector3& axis1,const btVector3& axis2) +void btGeneric6DofSpringConstraint::setAxis(const btVector3& axis1, const btVector3& axis2) { btVector3 zAxis = axis1.normalized(); btVector3 yAxis = axis2.normalized(); - btVector3 xAxis = yAxis.cross(zAxis); // we want right coordinate system + btVector3 xAxis = yAxis.cross(zAxis); // we want right coordinate system btTransform frameInW; frameInW.setIdentity(); - frameInW.getBasis().setValue( xAxis[0], yAxis[0], zAxis[0], - xAxis[1], yAxis[1], zAxis[1], - xAxis[2], yAxis[2], zAxis[2]); + frameInW.getBasis().setValue(xAxis[0], yAxis[0], zAxis[0], + xAxis[1], yAxis[1], zAxis[1], + xAxis[2], yAxis[2], zAxis[2]); // now get constraint frame in local coordinate systems m_frameInA = m_rbA.getCenterOfMassTransform().inverse() * frameInW; m_frameInB = m_rbB.getCenterOfMassTransform().inverse() * frameInW; - calculateTransforms(); + calculateTransforms(); } - - - diff --git a/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h b/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h index dac59c688..02b9d4d05 100644 --- a/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h +++ b/src/BulletDynamics/ConstraintSolver/btGeneric6DofSpringConstraint.h @@ -16,20 +16,17 @@ subject to the following restrictions: #ifndef BT_GENERIC_6DOF_SPRING_CONSTRAINT_H #define BT_GENERIC_6DOF_SPRING_CONSTRAINT_H - #include "LinearMath/btVector3.h" #include "btTypedConstraint.h" #include "btGeneric6DofConstraint.h" #ifdef BT_USE_DOUBLE_PRECISION -#define btGeneric6DofSpringConstraintData2 btGeneric6DofSpringConstraintDoubleData2 -#define btGeneric6DofSpringConstraintDataName "btGeneric6DofSpringConstraintDoubleData2" +#define btGeneric6DofSpringConstraintData2 btGeneric6DofSpringConstraintDoubleData2 +#define btGeneric6DofSpringConstraintDataName "btGeneric6DofSpringConstraintDoubleData2" #else -#define btGeneric6DofSpringConstraintData2 btGeneric6DofSpringConstraintData -#define btGeneric6DofSpringConstraintDataName "btGeneric6DofSpringConstraintData" -#endif //BT_USE_DOUBLE_PRECISION - - +#define btGeneric6DofSpringConstraintData2 btGeneric6DofSpringConstraintData +#define btGeneric6DofSpringConstraintDataName "btGeneric6DofSpringConstraintData" +#endif //BT_USE_DOUBLE_PRECISION /// Generic 6 DOF constraint that allows to set spring motors to any translational and rotational DOF @@ -41,101 +38,98 @@ subject to the following restrictions: /// 4 : rotation Y (2nd Euler rotational around new position of Y axis, range [-PI/2+epsilon, PI/2-epsilon] ) /// 5 : rotation Z (1st Euler rotational around Z axis, range [-PI+epsilon, PI-epsilon] ) -ATTRIBUTE_ALIGNED16(class) btGeneric6DofSpringConstraint : public btGeneric6DofConstraint +ATTRIBUTE_ALIGNED16(class) +btGeneric6DofSpringConstraint : public btGeneric6DofConstraint { protected: - bool m_springEnabled[6]; - btScalar m_equilibriumPoint[6]; - btScalar m_springStiffness[6]; - btScalar m_springDamping[6]; // between 0 and 1 (1 == no damping) + bool m_springEnabled[6]; + btScalar m_equilibriumPoint[6]; + btScalar m_springStiffness[6]; + btScalar m_springDamping[6]; // between 0 and 1 (1 == no damping) void init(); - void internalUpdateSprings(btConstraintInfo2* info); -public: - + void internalUpdateSprings(btConstraintInfo2 * info); + +public: BT_DECLARE_ALIGNED_ALLOCATOR(); - - btGeneric6DofSpringConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA); - btGeneric6DofSpringConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameB); + + btGeneric6DofSpringConstraint(btRigidBody & rbA, btRigidBody & rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA); + btGeneric6DofSpringConstraint(btRigidBody & rbB, const btTransform& frameInB, bool useLinearReferenceFrameB); void enableSpring(int index, bool onOff); void setStiffness(int index, btScalar stiffness); void setDamping(int index, btScalar damping); - void setEquilibriumPoint(); // set the current constraint position/orientation as an equilibrium point for all DOF + void setEquilibriumPoint(); // set the current constraint position/orientation as an equilibrium point for all DOF void setEquilibriumPoint(int index); // set the current constraint position/orientation as an equilibrium point for given DOF void setEquilibriumPoint(int index, btScalar val); bool isSpringEnabled(int index) const { - return m_springEnabled[index]; + return m_springEnabled[index]; } btScalar getStiffness(int index) const { - return m_springStiffness[index]; + return m_springStiffness[index]; } btScalar getDamping(int index) const { - return m_springDamping[index]; + return m_springDamping[index]; } btScalar getEquilibriumPoint(int index) const { - return m_equilibriumPoint[index]; + return m_equilibriumPoint[index]; } - virtual void setAxis( const btVector3& axis1, const btVector3& axis2); + virtual void setAxis(const btVector3& axis1, const btVector3& axis2); - virtual void getInfo2 (btConstraintInfo2* info); + virtual void getInfo2(btConstraintInfo2 * info); - virtual int calculateSerializeBufferSize() const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; - + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; }; - struct btGeneric6DofSpringConstraintData { - btGeneric6DofConstraintData m_6dofData; - - int m_springEnabled[6]; - float m_equilibriumPoint[6]; - float m_springStiffness[6]; - float m_springDamping[6]; + btGeneric6DofConstraintData m_6dofData; + + int m_springEnabled[6]; + float m_equilibriumPoint[6]; + float m_springStiffness[6]; + float m_springDamping[6]; }; struct btGeneric6DofSpringConstraintDoubleData2 { - btGeneric6DofConstraintDoubleData2 m_6dofData; - - int m_springEnabled[6]; - double m_equilibriumPoint[6]; - double m_springStiffness[6]; - double m_springDamping[6]; + btGeneric6DofConstraintDoubleData2 m_6dofData; + + int m_springEnabled[6]; + double m_equilibriumPoint[6]; + double m_springStiffness[6]; + double m_springDamping[6]; }; - -SIMD_FORCE_INLINE int btGeneric6DofSpringConstraint::calculateSerializeBufferSize() const +SIMD_FORCE_INLINE int btGeneric6DofSpringConstraint::calculateSerializeBufferSize() const { return sizeof(btGeneric6DofSpringConstraintData2); } - ///fills the dataBuffer and returns the struct name (and 0 on failure) -SIMD_FORCE_INLINE const char* btGeneric6DofSpringConstraint::serialize(void* dataBuffer, btSerializer* serializer) const +///fills the dataBuffer and returns the struct name (and 0 on failure) +SIMD_FORCE_INLINE const char* btGeneric6DofSpringConstraint::serialize(void* dataBuffer, btSerializer* serializer) const { btGeneric6DofSpringConstraintData2* dof = (btGeneric6DofSpringConstraintData2*)dataBuffer; - btGeneric6DofConstraint::serialize(&dof->m_6dofData,serializer); + btGeneric6DofConstraint::serialize(&dof->m_6dofData, serializer); int i; - for (i=0;i<6;i++) + for (i = 0; i < 6; i++) { dof->m_equilibriumPoint[i] = m_equilibriumPoint[i]; dof->m_springDamping[i] = m_springDamping[i]; - dof->m_springEnabled[i] = m_springEnabled[i]? 1 : 0; + dof->m_springEnabled[i] = m_springEnabled[i] ? 1 : 0; dof->m_springStiffness[i] = m_springStiffness[i]; } return btGeneric6DofSpringConstraintDataName; } -#endif // BT_GENERIC_6DOF_SPRING_CONSTRAINT_H - +#endif // BT_GENERIC_6DOF_SPRING_CONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp b/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp index 4be2aabe4..6507e1a0a 100644 --- a/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp +++ b/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.cpp @@ -13,54 +13,49 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "btHinge2Constraint.h" #include "BulletDynamics/Dynamics/btRigidBody.h" #include "LinearMath/btTransformUtil.h" - - // constructor // anchor, axis1 and axis2 are in world coordinate system // axis1 must be orthogonal to axis2 btHinge2Constraint::btHinge2Constraint(btRigidBody& rbA, btRigidBody& rbB, btVector3& anchor, btVector3& axis1, btVector3& axis2) -: btGeneric6DofSpring2Constraint(rbA, rbB, btTransform::getIdentity(), btTransform::getIdentity(),RO_XYZ), - m_anchor(anchor), - m_axis1(axis1), - m_axis2(axis2) + : btGeneric6DofSpring2Constraint(rbA, rbB, btTransform::getIdentity(), btTransform::getIdentity(), RO_XYZ), + m_anchor(anchor), + m_axis1(axis1), + m_axis2(axis2) { // build frame basis // 6DOF constraint uses Euler angles and to define limits // it is assumed that rotational order is : // Z - first, allowed limits are (-PI,PI); - // new position of Y - second (allowed limits are (-PI/2 + epsilon, PI/2 - epsilon), where epsilon is a small positive number + // new position of Y - second (allowed limits are (-PI/2 + epsilon, PI/2 - epsilon), where epsilon is a small positive number // used to prevent constraint from instability on poles; // new position of X, allowed limits are (-PI,PI); // So to simulate ODE Universal joint we should use parent axis as Z, child axis as Y and limit all other DOFs // Build the frame in world coordinate system first btVector3 zAxis = axis1.normalize(); btVector3 xAxis = axis2.normalize(); - btVector3 yAxis = zAxis.cross(xAxis); // we want right coordinate system + btVector3 yAxis = zAxis.cross(xAxis); // we want right coordinate system btTransform frameInW; frameInW.setIdentity(); - frameInW.getBasis().setValue( xAxis[0], yAxis[0], zAxis[0], - xAxis[1], yAxis[1], zAxis[1], - xAxis[2], yAxis[2], zAxis[2]); + frameInW.getBasis().setValue(xAxis[0], yAxis[0], zAxis[0], + xAxis[1], yAxis[1], zAxis[1], + xAxis[2], yAxis[2], zAxis[2]); frameInW.setOrigin(anchor); // now get constraint frame in local coordinate systems m_frameInA = rbA.getCenterOfMassTransform().inverse() * frameInW; m_frameInB = rbB.getCenterOfMassTransform().inverse() * frameInW; // sei limits setLinearLowerLimit(btVector3(0.f, 0.f, -1.f)); - setLinearUpperLimit(btVector3(0.f, 0.f, 1.f)); + setLinearUpperLimit(btVector3(0.f, 0.f, 1.f)); // like front wheels of a car - setAngularLowerLimit(btVector3(1.f, 0.f, -SIMD_HALF_PI * 0.5f)); - setAngularUpperLimit(btVector3(-1.f, 0.f, SIMD_HALF_PI * 0.5f)); + setAngularLowerLimit(btVector3(1.f, 0.f, -SIMD_HALF_PI * 0.5f)); + setAngularUpperLimit(btVector3(-1.f, 0.f, SIMD_HALF_PI * 0.5f)); // enable suspension enableSpring(2, true); setStiffness(2, SIMD_PI * SIMD_PI * 4.f); setDamping(2, 0.01f); setEquilibriumPoint(); } - diff --git a/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.h b/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.h index 06a8e3ecd..95f604a89 100644 --- a/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.h +++ b/src/BulletDynamics/ConstraintSolver/btHinge2Constraint.h @@ -16,32 +16,30 @@ subject to the following restrictions: #ifndef BT_HINGE2_CONSTRAINT_H #define BT_HINGE2_CONSTRAINT_H - - #include "LinearMath/btVector3.h" #include "btTypedConstraint.h" #include "btGeneric6DofSpring2Constraint.h" - - // Constraint similar to ODE Hinge2 Joint // has 3 degrees of frredom: // 2 rotational degrees of freedom, similar to Euler rotations around Z (axis 1) and X (axis 2) // 1 translational (along axis Z) with suspension spring -ATTRIBUTE_ALIGNED16(class) btHinge2Constraint : public btGeneric6DofSpring2Constraint +ATTRIBUTE_ALIGNED16(class) +btHinge2Constraint : public btGeneric6DofSpring2Constraint { protected: - btVector3 m_anchor; - btVector3 m_axis1; - btVector3 m_axis2; + btVector3 m_anchor; + btVector3 m_axis1; + btVector3 m_axis2; + public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - + BT_DECLARE_ALIGNED_ALLOCATOR(); + // constructor // anchor, axis1 and axis2 are in world coordinate system // axis1 must be orthogonal to axis2 - btHinge2Constraint(btRigidBody& rbA, btRigidBody& rbB, btVector3& anchor, btVector3& axis1, btVector3& axis2); + btHinge2Constraint(btRigidBody & rbA, btRigidBody & rbB, btVector3 & anchor, btVector3 & axis1, btVector3 & axis2); // access const btVector3& getAnchor() { return m_calculatedTransformA.getOrigin(); } const btVector3& getAnchor2() { return m_calculatedTransformB.getOrigin(); } @@ -51,10 +49,7 @@ public: btScalar getAngle2() { return getAngle(0); } // limits void setUpperLimit(btScalar ang1max) { setAngularUpperLimit(btVector3(-1.f, 0.f, ang1max)); } - void setLowerLimit(btScalar ang1min) { setAngularLowerLimit(btVector3( 1.f, 0.f, ang1min)); } + void setLowerLimit(btScalar ang1min) { setAngularLowerLimit(btVector3(1.f, 0.f, ang1min)); } }; - - -#endif // BT_HINGE2_CONSTRAINT_H - +#endif // BT_HINGE2_CONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp index 7e5e6f9e5..121290d0d 100644 --- a/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp +++ b/src/BulletDynamics/ConstraintSolver/btHingeConstraint.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btHingeConstraint.h" #include "BulletDynamics/Dynamics/btRigidBody.h" #include "LinearMath/btTransformUtil.h" @@ -21,8 +20,6 @@ subject to the following restrictions: #include #include "btSolverBody.h" - - //#define HINGE_USE_OBSOLETE_SOLVER false #define HINGE_USE_OBSOLETE_SOLVER false @@ -30,59 +27,60 @@ subject to the following restrictions: #ifndef __SPU__ - - - - -btHingeConstraint::btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, - const btVector3& axisInA,const btVector3& axisInB, bool useReferenceFrameA) - :btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA,rbB), +btHingeConstraint::btHingeConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& pivotInA, const btVector3& pivotInB, + const btVector3& axisInA, const btVector3& axisInB, bool useReferenceFrameA) + : btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA, rbB), #ifdef _BT_USE_CENTER_LIMIT_ - m_limit(), + m_limit(), #endif - m_angularOnly(false), - m_enableAngularMotor(false), - m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER), - m_useOffsetForConstraintFrame(HINGE_USE_FRAME_OFFSET), - m_useReferenceFrameA(useReferenceFrameA), - m_flags(0), - m_normalCFM(0), - m_normalERP(0), - m_stopCFM(0), - m_stopERP(0) + m_angularOnly(false), + m_enableAngularMotor(false), + m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER), + m_useOffsetForConstraintFrame(HINGE_USE_FRAME_OFFSET), + m_useReferenceFrameA(useReferenceFrameA), + m_flags(0), + m_normalCFM(0), + m_normalERP(0), + m_stopCFM(0), + m_stopERP(0) { m_rbAFrame.getOrigin() = pivotInA; - + // since no frame is given, assume this to be zero angle and just pick rb transform axis btVector3 rbAxisA1 = rbA.getCenterOfMassTransform().getBasis().getColumn(0); btVector3 rbAxisA2; btScalar projection = axisInA.dot(rbAxisA1); - if (projection >= 1.0f - SIMD_EPSILON) { + if (projection >= 1.0f - SIMD_EPSILON) + { rbAxisA1 = -rbA.getCenterOfMassTransform().getBasis().getColumn(2); rbAxisA2 = rbA.getCenterOfMassTransform().getBasis().getColumn(1); - } else if (projection <= -1.0f + SIMD_EPSILON) { + } + else if (projection <= -1.0f + SIMD_EPSILON) + { rbAxisA1 = rbA.getCenterOfMassTransform().getBasis().getColumn(2); - rbAxisA2 = rbA.getCenterOfMassTransform().getBasis().getColumn(1); - } else { + rbAxisA2 = rbA.getCenterOfMassTransform().getBasis().getColumn(1); + } + else + { rbAxisA2 = axisInA.cross(rbAxisA1); rbAxisA1 = rbAxisA2.cross(axisInA); } - m_rbAFrame.getBasis().setValue( rbAxisA1.getX(),rbAxisA2.getX(),axisInA.getX(), - rbAxisA1.getY(),rbAxisA2.getY(),axisInA.getY(), - rbAxisA1.getZ(),rbAxisA2.getZ(),axisInA.getZ() ); + m_rbAFrame.getBasis().setValue(rbAxisA1.getX(), rbAxisA2.getX(), axisInA.getX(), + rbAxisA1.getY(), rbAxisA2.getY(), axisInA.getY(), + rbAxisA1.getZ(), rbAxisA2.getZ(), axisInA.getZ()); + + btQuaternion rotationArc = shortestArcQuat(axisInA, axisInB); + btVector3 rbAxisB1 = quatRotate(rotationArc, rbAxisA1); + btVector3 rbAxisB2 = axisInB.cross(rbAxisB1); - btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB); - btVector3 rbAxisB1 = quatRotate(rotationArc,rbAxisA1); - btVector3 rbAxisB2 = axisInB.cross(rbAxisB1); - m_rbBFrame.getOrigin() = pivotInB; - m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),axisInB.getX(), - rbAxisB1.getY(),rbAxisB2.getY(),axisInB.getY(), - rbAxisB1.getZ(),rbAxisB2.getZ(),axisInB.getZ() ); - -#ifndef _BT_USE_CENTER_LIMIT_ + m_rbBFrame.getBasis().setValue(rbAxisB1.getX(), rbAxisB2.getX(), axisInB.getX(), + rbAxisB1.getY(), rbAxisB2.getY(), axisInB.getY(), + rbAxisB1.getZ(), rbAxisB2.getZ(), axisInB.getZ()); + +#ifndef _BT_USE_CENTER_LIMIT_ //start with free m_lowerLimit = btScalar(1.0f); m_upperLimit = btScalar(-1.0f); @@ -94,47 +92,44 @@ btHingeConstraint::btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const bt m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f); } - - -btHingeConstraint::btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,const btVector3& axisInA, bool useReferenceFrameA) -:btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA), +btHingeConstraint::btHingeConstraint(btRigidBody& rbA, const btVector3& pivotInA, const btVector3& axisInA, bool useReferenceFrameA) + : btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA), #ifdef _BT_USE_CENTER_LIMIT_ -m_limit(), + m_limit(), #endif -m_angularOnly(false), m_enableAngularMotor(false), -m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER), -m_useOffsetForConstraintFrame(HINGE_USE_FRAME_OFFSET), -m_useReferenceFrameA(useReferenceFrameA), -m_flags(0), -m_normalCFM(0), -m_normalERP(0), -m_stopCFM(0), -m_stopERP(0) + m_angularOnly(false), + m_enableAngularMotor(false), + m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER), + m_useOffsetForConstraintFrame(HINGE_USE_FRAME_OFFSET), + m_useReferenceFrameA(useReferenceFrameA), + m_flags(0), + m_normalCFM(0), + m_normalERP(0), + m_stopCFM(0), + m_stopERP(0) { - // since no frame is given, assume this to be zero angle and just pick rb transform axis // fixed axis in worldspace btVector3 rbAxisA1, rbAxisA2; btPlaneSpace1(axisInA, rbAxisA1, rbAxisA2); m_rbAFrame.getOrigin() = pivotInA; - m_rbAFrame.getBasis().setValue( rbAxisA1.getX(),rbAxisA2.getX(),axisInA.getX(), - rbAxisA1.getY(),rbAxisA2.getY(),axisInA.getY(), - rbAxisA1.getZ(),rbAxisA2.getZ(),axisInA.getZ() ); + m_rbAFrame.getBasis().setValue(rbAxisA1.getX(), rbAxisA2.getX(), axisInA.getX(), + rbAxisA1.getY(), rbAxisA2.getY(), axisInA.getY(), + rbAxisA1.getZ(), rbAxisA2.getZ(), axisInA.getZ()); btVector3 axisInB = rbA.getCenterOfMassTransform().getBasis() * axisInA; - btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB); - btVector3 rbAxisB1 = quatRotate(rotationArc,rbAxisA1); + btQuaternion rotationArc = shortestArcQuat(axisInA, axisInB); + btVector3 rbAxisB1 = quatRotate(rotationArc, rbAxisA1); btVector3 rbAxisB2 = axisInB.cross(rbAxisB1); - m_rbBFrame.getOrigin() = rbA.getCenterOfMassTransform()(pivotInA); - m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),axisInB.getX(), - rbAxisB1.getY(),rbAxisB2.getY(),axisInB.getY(), - rbAxisB1.getZ(),rbAxisB2.getZ(),axisInB.getZ() ); - -#ifndef _BT_USE_CENTER_LIMIT_ + m_rbBFrame.getBasis().setValue(rbAxisB1.getX(), rbAxisB2.getX(), axisInB.getX(), + rbAxisB1.getY(), rbAxisB2.getY(), axisInB.getY(), + rbAxisB1.getZ(), rbAxisB2.getZ(), axisInB.getZ()); + +#ifndef _BT_USE_CENTER_LIMIT_ //start with free m_lowerLimit = btScalar(1.0f); m_upperLimit = btScalar(-1.0f); @@ -146,26 +141,24 @@ m_stopERP(0) m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f); } - - -btHingeConstraint::btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, - const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA) -:btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA,rbB),m_rbAFrame(rbAFrame),m_rbBFrame(rbBFrame), +btHingeConstraint::btHingeConstraint(btRigidBody& rbA, btRigidBody& rbB, + const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA) + : btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA, rbB), m_rbAFrame(rbAFrame), m_rbBFrame(rbBFrame), #ifdef _BT_USE_CENTER_LIMIT_ -m_limit(), + m_limit(), #endif -m_angularOnly(false), -m_enableAngularMotor(false), -m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER), -m_useOffsetForConstraintFrame(HINGE_USE_FRAME_OFFSET), -m_useReferenceFrameA(useReferenceFrameA), -m_flags(0), -m_normalCFM(0), -m_normalERP(0), -m_stopCFM(0), -m_stopERP(0) + m_angularOnly(false), + m_enableAngularMotor(false), + m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER), + m_useOffsetForConstraintFrame(HINGE_USE_FRAME_OFFSET), + m_useReferenceFrameA(useReferenceFrameA), + m_flags(0), + m_normalCFM(0), + m_normalERP(0), + m_stopCFM(0), + m_stopERP(0) { -#ifndef _BT_USE_CENTER_LIMIT_ +#ifndef _BT_USE_CENTER_LIMIT_ //start with free m_lowerLimit = btScalar(1.0f); m_upperLimit = btScalar(-1.0f); @@ -175,30 +168,28 @@ m_stopERP(0) m_solveLimit = false; #endif m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f); -} - - +} btHingeConstraint::btHingeConstraint(btRigidBody& rbA, const btTransform& rbAFrame, bool useReferenceFrameA) -:btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA),m_rbAFrame(rbAFrame),m_rbBFrame(rbAFrame), + : btTypedConstraint(HINGE_CONSTRAINT_TYPE, rbA), m_rbAFrame(rbAFrame), m_rbBFrame(rbAFrame), #ifdef _BT_USE_CENTER_LIMIT_ -m_limit(), + m_limit(), #endif -m_angularOnly(false), -m_enableAngularMotor(false), -m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER), -m_useOffsetForConstraintFrame(HINGE_USE_FRAME_OFFSET), -m_useReferenceFrameA(useReferenceFrameA), -m_flags(0), -m_normalCFM(0), -m_normalERP(0), -m_stopCFM(0), -m_stopERP(0) + m_angularOnly(false), + m_enableAngularMotor(false), + m_useSolveConstraintObsolete(HINGE_USE_OBSOLETE_SOLVER), + m_useOffsetForConstraintFrame(HINGE_USE_FRAME_OFFSET), + m_useReferenceFrameA(useReferenceFrameA), + m_flags(0), + m_normalCFM(0), + m_normalERP(0), + m_stopCFM(0), + m_stopERP(0) { ///not providing rigidbody B means implicitly using worldspace for body B m_rbBFrame.getOrigin() = m_rbA.getCenterOfMassTransform()(m_rbAFrame.getOrigin()); -#ifndef _BT_USE_CENTER_LIMIT_ +#ifndef _BT_USE_CENTER_LIMIT_ //start with free m_lowerLimit = btScalar(1.0f); m_upperLimit = btScalar(-1.0f); @@ -210,9 +201,7 @@ m_stopERP(0) m_referenceSign = m_useReferenceFrameA ? btScalar(-1.f) : btScalar(1.f); } - - -void btHingeConstraint::buildJacobian() +void btHingeConstraint::buildJacobian() { if (m_useSolveConstraintObsolete) { @@ -221,8 +210,8 @@ void btHingeConstraint::buildJacobian() if (!m_angularOnly) { - btVector3 pivotAInW = m_rbA.getCenterOfMassTransform()*m_rbAFrame.getOrigin(); - btVector3 pivotBInW = m_rbB.getCenterOfMassTransform()*m_rbBFrame.getOrigin(); + btVector3 pivotAInW = m_rbA.getCenterOfMassTransform() * m_rbAFrame.getOrigin(); + btVector3 pivotBInW = m_rbB.getCenterOfMassTransform() * m_rbBFrame.getOrigin(); btVector3 relPos = pivotBInW - pivotAInW; btVector3 normal[3]; @@ -232,23 +221,23 @@ void btHingeConstraint::buildJacobian() } else { - normal[0].setValue(btScalar(1.0),0,0); + normal[0].setValue(btScalar(1.0), 0, 0); } btPlaneSpace1(normal[0], normal[1], normal[2]); - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) { new (&m_jac[i]) btJacobianEntry( - m_rbA.getCenterOfMassTransform().getBasis().transpose(), - m_rbB.getCenterOfMassTransform().getBasis().transpose(), - pivotAInW - m_rbA.getCenterOfMassPosition(), - pivotBInW - m_rbB.getCenterOfMassPosition(), - normal[i], - m_rbA.getInvInertiaDiagLocal(), - m_rbA.getInvMass(), - m_rbB.getInvInertiaDiagLocal(), - m_rbB.getInvMass()); + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + pivotAInW - m_rbA.getCenterOfMassPosition(), + pivotBInW - m_rbB.getCenterOfMassPosition(), + normal[i], + m_rbA.getInvInertiaDiagLocal(), + m_rbA.getInvMass(), + m_rbB.getInvInertiaDiagLocal(), + m_rbB.getInvMass()); } } @@ -258,60 +247,55 @@ void btHingeConstraint::buildJacobian() //this is unused for now, it's a todo btVector3 jointAxis0local; btVector3 jointAxis1local; - - btPlaneSpace1(m_rbAFrame.getBasis().getColumn(2),jointAxis0local,jointAxis1local); + + btPlaneSpace1(m_rbAFrame.getBasis().getColumn(2), jointAxis0local, jointAxis1local); btVector3 jointAxis0 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis0local; btVector3 jointAxis1 = getRigidBodyA().getCenterOfMassTransform().getBasis() * jointAxis1local; btVector3 hingeAxisWorld = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); - - new (&m_jacAng[0]) btJacobianEntry(jointAxis0, - m_rbA.getCenterOfMassTransform().getBasis().transpose(), - m_rbB.getCenterOfMassTransform().getBasis().transpose(), - m_rbA.getInvInertiaDiagLocal(), - m_rbB.getInvInertiaDiagLocal()); - new (&m_jacAng[1]) btJacobianEntry(jointAxis1, - m_rbA.getCenterOfMassTransform().getBasis().transpose(), - m_rbB.getCenterOfMassTransform().getBasis().transpose(), - m_rbA.getInvInertiaDiagLocal(), - m_rbB.getInvInertiaDiagLocal()); + new (&m_jacAng[0]) btJacobianEntry(jointAxis0, + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + m_rbA.getInvInertiaDiagLocal(), + m_rbB.getInvInertiaDiagLocal()); - new (&m_jacAng[2]) btJacobianEntry(hingeAxisWorld, - m_rbA.getCenterOfMassTransform().getBasis().transpose(), - m_rbB.getCenterOfMassTransform().getBasis().transpose(), - m_rbA.getInvInertiaDiagLocal(), - m_rbB.getInvInertiaDiagLocal()); + new (&m_jacAng[1]) btJacobianEntry(jointAxis1, + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + m_rbA.getInvInertiaDiagLocal(), + m_rbB.getInvInertiaDiagLocal()); - // clear accumulator - m_accLimitImpulse = btScalar(0.); + new (&m_jacAng[2]) btJacobianEntry(hingeAxisWorld, + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + m_rbA.getInvInertiaDiagLocal(), + m_rbB.getInvInertiaDiagLocal()); - // test angular limit - testLimit(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); + // clear accumulator + m_accLimitImpulse = btScalar(0.); + + // test angular limit + testLimit(m_rbA.getCenterOfMassTransform(), m_rbB.getCenterOfMassTransform()); //Compute K = J*W*J' for hinge axis - btVector3 axisA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); - m_kHinge = 1.0f / (getRigidBodyA().computeAngularImpulseDenominator(axisA) + - getRigidBodyB().computeAngularImpulseDenominator(axisA)); - + btVector3 axisA = getRigidBodyA().getCenterOfMassTransform().getBasis() * m_rbAFrame.getBasis().getColumn(2); + m_kHinge = 1.0f / (getRigidBodyA().computeAngularImpulseDenominator(axisA) + + getRigidBodyB().computeAngularImpulseDenominator(axisA)); } } - -#endif //__SPU__ - +#endif //__SPU__ static inline btScalar btNormalizeAnglePositive(btScalar angle) { - return btFmod(btFmod(angle, btScalar(2.0*SIMD_PI)) + btScalar(2.0*SIMD_PI), btScalar(2.0*SIMD_PI)); + return btFmod(btFmod(angle, btScalar(2.0 * SIMD_PI)) + btScalar(2.0 * SIMD_PI), btScalar(2.0 * SIMD_PI)); } - - static btScalar btShortestAngularDistance(btScalar accAngle, btScalar curAngle) { btScalar result = btNormalizeAngle(btNormalizeAnglePositive(btNormalizeAnglePositive(curAngle) - - btNormalizeAnglePositive(accAngle))); + btNormalizeAnglePositive(accAngle))); return result; } @@ -320,41 +304,36 @@ static btScalar btShortestAngleUpdate(btScalar accAngle, btScalar curAngle) btScalar tol(0.3); btScalar result = btShortestAngularDistance(accAngle, curAngle); - if (btFabs(result) > tol) + if (btFabs(result) > tol) return curAngle; - else + else return accAngle + result; return curAngle; } - btScalar btHingeAccumulatedAngleConstraint::getAccumulatedHingeAngle() { btScalar hingeAngle = getHingeAngle(); - m_accumulatedAngle = btShortestAngleUpdate(m_accumulatedAngle,hingeAngle); + m_accumulatedAngle = btShortestAngleUpdate(m_accumulatedAngle, hingeAngle); return m_accumulatedAngle; } -void btHingeAccumulatedAngleConstraint::setAccumulatedHingeAngle(btScalar accAngle) +void btHingeAccumulatedAngleConstraint::setAccumulatedHingeAngle(btScalar accAngle) { - m_accumulatedAngle = accAngle; + m_accumulatedAngle = accAngle; } void btHingeAccumulatedAngleConstraint::getInfo1(btConstraintInfo1* info) { //update m_accumulatedAngle btScalar curHingeAngle = getHingeAngle(); - m_accumulatedAngle = btShortestAngleUpdate(m_accumulatedAngle,curHingeAngle); + m_accumulatedAngle = btShortestAngleUpdate(m_accumulatedAngle, curHingeAngle); btHingeConstraint::getInfo1(info); - } - void btHingeConstraint::getInfo1(btConstraintInfo1* info) { - - if (m_useSolveConstraintObsolete) { info->m_numConstraintRows = 0; @@ -362,17 +341,16 @@ void btHingeConstraint::getInfo1(btConstraintInfo1* info) } else { - info->m_numConstraintRows = 5; // Fixed 3 linear + 2 angular - info->nub = 1; + info->m_numConstraintRows = 5; // Fixed 3 linear + 2 angular + info->nub = 1; //always add the row, to avoid computation (data is not available yet) //prepare constraint - testLimit(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); - if(getSolveLimit() || getEnableAngularMotor()) + testLimit(m_rbA.getCenterOfMassTransform(), m_rbB.getCenterOfMassTransform()); + if (getSolveLimit() || getEnableAngularMotor()) { - info->m_numConstraintRows++; // limit 3rd anguar as well - info->nub--; + info->m_numConstraintRows++; // limit 3rd anguar as well + info->nub--; } - } } @@ -386,41 +364,38 @@ void btHingeConstraint::getInfo1NonVirtual(btConstraintInfo1* info) else { //always add the 'limit' row, to avoid computation (data is not available yet) - info->m_numConstraintRows = 6; // Fixed 3 linear + 2 angular - info->nub = 0; + info->m_numConstraintRows = 6; // Fixed 3 linear + 2 angular + info->nub = 0; } } -void btHingeConstraint::getInfo2 (btConstraintInfo2* info) +void btHingeConstraint::getInfo2(btConstraintInfo2* info) { - if(m_useOffsetForConstraintFrame) + if (m_useOffsetForConstraintFrame) { - getInfo2InternalUsingFrameOffset(info, m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform(),m_rbA.getAngularVelocity(),m_rbB.getAngularVelocity()); + getInfo2InternalUsingFrameOffset(info, m_rbA.getCenterOfMassTransform(), m_rbB.getCenterOfMassTransform(), m_rbA.getAngularVelocity(), m_rbB.getAngularVelocity()); } else { - getInfo2Internal(info, m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform(),m_rbA.getAngularVelocity(),m_rbB.getAngularVelocity()); + getInfo2Internal(info, m_rbA.getCenterOfMassTransform(), m_rbB.getCenterOfMassTransform(), m_rbA.getAngularVelocity(), m_rbB.getAngularVelocity()); } } - -void btHingeConstraint::getInfo2NonVirtual (btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB) +void btHingeConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTransform& transA, const btTransform& transB, const btVector3& angVelA, const btVector3& angVelB) { ///the regular (virtual) implementation getInfo2 already performs 'testLimit' during getInfo1, so we need to do it now - testLimit(transA,transB); + testLimit(transA, transB); - getInfo2Internal(info,transA,transB,angVelA,angVelB); + getInfo2Internal(info, transA, transB, angVelA, angVelB); } - -void btHingeConstraint::getInfo2Internal(btConstraintInfo2* info, const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB) +void btHingeConstraint::getInfo2Internal(btConstraintInfo2* info, const btTransform& transA, const btTransform& transB, const btVector3& angVelA, const btVector3& angVelB) { - btAssert(!m_useSolveConstraintObsolete); int i, skip = info->rowskip; // transforms in world space - btTransform trA = transA*m_rbAFrame; - btTransform trB = transB*m_rbBFrame; + btTransform trA = transA * m_rbAFrame; + btTransform trB = transB * m_rbBFrame; // pivot point btVector3 pivotAInW = trA.getOrigin(); btVector3 pivotBInW = trB.getOrigin(); @@ -448,7 +423,7 @@ void btHingeConstraint::getInfo2Internal(btConstraintInfo2* info, const btTransf info->m_constraintError[i*skip]=0.f; } } -#endif //#if 0 +#endif //#if 0 // linear (all fixed) if (!m_angularOnly) @@ -460,10 +435,7 @@ void btHingeConstraint::getInfo2Internal(btConstraintInfo2* info, const btTransf info->m_J2linearAxis[0] = -1; info->m_J2linearAxis[skip + 1] = -1; info->m_J2linearAxis[2 * skip + 2] = -1; - } - - - + } btVector3 a1 = pivotAInW - transA.getOrigin(); { @@ -471,22 +443,22 @@ void btHingeConstraint::getInfo2Internal(btConstraintInfo2* info, const btTransf btVector3* angular1 = (btVector3*)(info->m_J1angularAxis + skip); btVector3* angular2 = (btVector3*)(info->m_J1angularAxis + 2 * skip); btVector3 a1neg = -a1; - a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2); + a1neg.getSkewSymmetricMatrix(angular0, angular1, angular2); } btVector3 a2 = pivotBInW - transB.getOrigin(); { btVector3* angular0 = (btVector3*)(info->m_J2angularAxis); btVector3* angular1 = (btVector3*)(info->m_J2angularAxis + skip); btVector3* angular2 = (btVector3*)(info->m_J2angularAxis + 2 * skip); - a2.getSkewSymmetricMatrix(angular0,angular1,angular2); + a2.getSkewSymmetricMatrix(angular0, angular1, angular2); } // linear RHS btScalar normalErp = (m_flags & BT_HINGE_FLAGS_ERP_NORM) ? m_normalERP : info->erp; - btScalar k = info->fps * normalErp; + btScalar k = info->fps * normalErp; if (!m_angularOnly) { - for(i = 0; i < 3; i++) + for (i = 0; i < 3; i++) { info->m_constraintError[i * skip] = k * (pivotBInW[i] - pivotAInW[i]); } @@ -504,9 +476,9 @@ void btHingeConstraint::getInfo2Internal(btConstraintInfo2* info, const btTransf // get 2 orthos to hinge axis (X, Y) btVector3 p = trA.getBasis().getColumn(0); btVector3 q = trA.getBasis().getColumn(1); - // set the two hinge angular rows - int s3 = 3 * info->rowskip; - int s4 = 4 * info->rowskip; + // set the two hinge angular rows + int s3 = 3 * info->rowskip; + int s4 = 4 * info->rowskip; info->m_J1angularAxis[s3 + 0] = p[0]; info->m_J1angularAxis[s3 + 1] = p[1]; @@ -521,181 +493,172 @@ void btHingeConstraint::getInfo2Internal(btConstraintInfo2* info, const btTransf info->m_J2angularAxis[s4 + 0] = -q[0]; info->m_J2angularAxis[s4 + 1] = -q[1]; info->m_J2angularAxis[s4 + 2] = -q[2]; - // compute the right hand side of the constraint equation. set relative - // body velocities along p and q to bring the hinge back into alignment. - // if ax1,ax2 are the unit length hinge axes as computed from body1 and - // body2, we need to rotate both bodies along the axis u = (ax1 x ax2). - // if `theta' is the angle between ax1 and ax2, we need an angular velocity - // along u to cover angle erp*theta in one step : - // |angular_velocity| = angle/time = erp*theta / stepsize - // = (erp*fps) * theta - // angular_velocity = |angular_velocity| * (ax1 x ax2) / |ax1 x ax2| - // = (erp*fps) * theta * (ax1 x ax2) / sin(theta) - // ...as ax1 and ax2 are unit length. if theta is smallish, - // theta ~= sin(theta), so - // angular_velocity = (erp*fps) * (ax1 x ax2) - // ax1 x ax2 is in the plane space of ax1, so we project the angular - // velocity to p and q to find the right hand side. - btVector3 ax2 = trB.getBasis().getColumn(2); + // compute the right hand side of the constraint equation. set relative + // body velocities along p and q to bring the hinge back into alignment. + // if ax1,ax2 are the unit length hinge axes as computed from body1 and + // body2, we need to rotate both bodies along the axis u = (ax1 x ax2). + // if `theta' is the angle between ax1 and ax2, we need an angular velocity + // along u to cover angle erp*theta in one step : + // |angular_velocity| = angle/time = erp*theta / stepsize + // = (erp*fps) * theta + // angular_velocity = |angular_velocity| * (ax1 x ax2) / |ax1 x ax2| + // = (erp*fps) * theta * (ax1 x ax2) / sin(theta) + // ...as ax1 and ax2 are unit length. if theta is smallish, + // theta ~= sin(theta), so + // angular_velocity = (erp*fps) * (ax1 x ax2) + // ax1 x ax2 is in the plane space of ax1, so we project the angular + // velocity to p and q to find the right hand side. + btVector3 ax2 = trB.getBasis().getColumn(2); btVector3 u = ax1.cross(ax2); info->m_constraintError[s3] = k * u.dot(p); info->m_constraintError[s4] = k * u.dot(q); // check angular limits - int nrow = 4; // last filled row + int nrow = 4; // last filled row int srow; btScalar limit_err = btScalar(0.0); int limit = 0; - if(getSolveLimit()) + if (getSolveLimit()) { -#ifdef _BT_USE_CENTER_LIMIT_ - limit_err = m_limit.getCorrection() * m_referenceSign; +#ifdef _BT_USE_CENTER_LIMIT_ + limit_err = m_limit.getCorrection() * m_referenceSign; #else - limit_err = m_correction * m_referenceSign; + limit_err = m_correction * m_referenceSign; #endif - limit = (limit_err > btScalar(0.0)) ? 1 : 2; - + limit = (limit_err > btScalar(0.0)) ? 1 : 2; } // if the hinge has joint limits or motor, add in the extra row bool powered = getEnableAngularMotor(); - if(limit || powered) + if (limit || powered) { nrow++; srow = nrow * info->rowskip; - info->m_J1angularAxis[srow+0] = ax1[0]; - info->m_J1angularAxis[srow+1] = ax1[1]; - info->m_J1angularAxis[srow+2] = ax1[2]; + info->m_J1angularAxis[srow + 0] = ax1[0]; + info->m_J1angularAxis[srow + 1] = ax1[1]; + info->m_J1angularAxis[srow + 2] = ax1[2]; - info->m_J2angularAxis[srow+0] = -ax1[0]; - info->m_J2angularAxis[srow+1] = -ax1[1]; - info->m_J2angularAxis[srow+2] = -ax1[2]; + info->m_J2angularAxis[srow + 0] = -ax1[0]; + info->m_J2angularAxis[srow + 1] = -ax1[1]; + info->m_J2angularAxis[srow + 2] = -ax1[2]; btScalar lostop = getLowerLimit(); btScalar histop = getUpperLimit(); - if(limit && (lostop == histop)) + if (limit && (lostop == histop)) { // the joint motor is ineffective powered = false; } info->m_constraintError[srow] = btScalar(0.0f); btScalar currERP = (m_flags & BT_HINGE_FLAGS_ERP_STOP) ? m_stopERP : normalErp; - if(powered) + if (powered) { - if(m_flags & BT_HINGE_FLAGS_CFM_NORM) + if (m_flags & BT_HINGE_FLAGS_CFM_NORM) { info->cfm[srow] = m_normalCFM; } btScalar mot_fact = getMotorFactor(m_hingeAngle, lostop, histop, m_motorTargetVelocity, info->fps * currERP); info->m_constraintError[srow] += mot_fact * m_motorTargetVelocity * m_referenceSign; - info->m_lowerLimit[srow] = - m_maxMotorImpulse; - info->m_upperLimit[srow] = m_maxMotorImpulse; + info->m_lowerLimit[srow] = -m_maxMotorImpulse; + info->m_upperLimit[srow] = m_maxMotorImpulse; } - if(limit) + if (limit) { k = info->fps * currERP; info->m_constraintError[srow] += k * limit_err; - if(m_flags & BT_HINGE_FLAGS_CFM_STOP) + if (m_flags & BT_HINGE_FLAGS_CFM_STOP) { info->cfm[srow] = m_stopCFM; } - if(lostop == histop) + if (lostop == histop) { // limited low and high simultaneously info->m_lowerLimit[srow] = -SIMD_INFINITY; info->m_upperLimit[srow] = SIMD_INFINITY; } - else if(limit == 1) - { // low limit + else if (limit == 1) + { // low limit info->m_lowerLimit[srow] = 0; info->m_upperLimit[srow] = SIMD_INFINITY; } - else - { // high limit + else + { // high limit info->m_lowerLimit[srow] = -SIMD_INFINITY; info->m_upperLimit[srow] = 0; } // bounce (we'll use slider parameter abs(1.0 - m_dampingLimAng) for that) -#ifdef _BT_USE_CENTER_LIMIT_ +#ifdef _BT_USE_CENTER_LIMIT_ btScalar bounce = m_limit.getRelaxationFactor(); #else btScalar bounce = m_relaxationFactor; #endif - if(bounce > btScalar(0.0)) + if (bounce > btScalar(0.0)) { btScalar vel = angVelA.dot(ax1); vel -= angVelB.dot(ax1); // only apply bounce if the velocity is incoming, and if the // resulting c[] exceeds what we already have. - if(limit == 1) - { // low limit - if(vel < 0) + if (limit == 1) + { // low limit + if (vel < 0) { btScalar newc = -bounce * vel; - if(newc > info->m_constraintError[srow]) + if (newc > info->m_constraintError[srow]) { info->m_constraintError[srow] = newc; } } } else - { // high limit - all those computations are reversed - if(vel > 0) + { // high limit - all those computations are reversed + if (vel > 0) { btScalar newc = -bounce * vel; - if(newc < info->m_constraintError[srow]) + if (newc < info->m_constraintError[srow]) { info->m_constraintError[srow] = newc; } } } } -#ifdef _BT_USE_CENTER_LIMIT_ +#ifdef _BT_USE_CENTER_LIMIT_ info->m_constraintError[srow] *= m_limit.getBiasFactor(); #else info->m_constraintError[srow] *= m_biasFactor; #endif - } // if(limit) - } // if angular limit or powered + } // if(limit) + } // if angular limit or powered } - -void btHingeConstraint::setFrames(const btTransform & frameA, const btTransform & frameB) +void btHingeConstraint::setFrames(const btTransform& frameA, const btTransform& frameB) { m_rbAFrame = frameA; m_rbBFrame = frameB; buildJacobian(); } - -void btHingeConstraint::updateRHS(btScalar timeStep) +void btHingeConstraint::updateRHS(btScalar timeStep) { (void)timeStep; - } - - - btScalar btHingeConstraint::getHingeAngle() { - return getHingeAngle(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); + return getHingeAngle(m_rbA.getCenterOfMassTransform(), m_rbB.getCenterOfMassTransform()); } -btScalar btHingeConstraint::getHingeAngle(const btTransform& transA,const btTransform& transB) +btScalar btHingeConstraint::getHingeAngle(const btTransform& transA, const btTransform& transB) { - const btVector3 refAxis0 = transA.getBasis() * m_rbAFrame.getBasis().getColumn(0); - const btVector3 refAxis1 = transA.getBasis() * m_rbAFrame.getBasis().getColumn(1); + const btVector3 refAxis0 = transA.getBasis() * m_rbAFrame.getBasis().getColumn(0); + const btVector3 refAxis1 = transA.getBasis() * m_rbAFrame.getBasis().getColumn(1); const btVector3 swingAxis = transB.getBasis() * m_rbBFrame.getBasis().getColumn(1); -// btScalar angle = btAtan2Fast(swingAxis.dot(refAxis0), swingAxis.dot(refAxis1)); + // btScalar angle = btAtan2Fast(swingAxis.dot(refAxis0), swingAxis.dot(refAxis1)); btScalar angle = btAtan2(swingAxis.dot(refAxis0), swingAxis.dot(refAxis1)); return m_referenceSign * angle; } - - -void btHingeConstraint::testLimit(const btTransform& transA,const btTransform& transB) +void btHingeConstraint::testLimit(const btTransform& transA, const btTransform& transB) { // Compute limit information - m_hingeAngle = getHingeAngle(transA,transB); -#ifdef _BT_USE_CENTER_LIMIT_ + m_hingeAngle = getHingeAngle(transA, transB); +#ifdef _BT_USE_CENTER_LIMIT_ m_limit.test(m_hingeAngle); #else m_correction = btScalar(0.); @@ -709,7 +672,7 @@ void btHingeConstraint::testLimit(const btTransform& transA,const btTransform& t m_correction = (m_lowerLimit - m_hingeAngle); m_limitSign = 1.0f; m_solveLimit = true; - } + } else if (m_hingeAngle >= m_upperLimit) { m_correction = m_upperLimit - m_hingeAngle; @@ -721,7 +684,6 @@ void btHingeConstraint::testLimit(const btTransform& transA,const btTransform& t return; } - static btVector3 vHinge(0, 0, btScalar(1)); void btHingeConstraint::setMotorTarget(const btQuaternion& qAinB, btScalar dt) @@ -731,14 +693,15 @@ void btHingeConstraint::setMotorTarget(const btQuaternion& qAinB, btScalar dt) qConstraint.normalize(); // extract "pure" hinge component - btVector3 vNoHinge = quatRotate(qConstraint, vHinge); vNoHinge.normalize(); + btVector3 vNoHinge = quatRotate(qConstraint, vHinge); + vNoHinge.normalize(); btQuaternion qNoHinge = shortestArcQuat(vHinge, vNoHinge); btQuaternion qHinge = qNoHinge.inverse() * qConstraint; qHinge.normalize(); // compute angular target, clamped to limits btScalar targetAngle = qHinge.getAngle(); - if (targetAngle > SIMD_PI) // long way around. flip quat and recalculate. + if (targetAngle > SIMD_PI) // long way around. flip quat and recalculate. { qHinge = -(qHinge); targetAngle = qHinge.getAngle(); @@ -751,7 +714,7 @@ void btHingeConstraint::setMotorTarget(const btQuaternion& qAinB, btScalar dt) void btHingeConstraint::setMotorTarget(btScalar targetAngle, btScalar dt) { -#ifdef _BT_USE_CENTER_LIMIT_ +#ifdef _BT_USE_CENTER_LIMIT_ m_limit.fit(targetAngle); #else if (m_lowerLimit < m_upperLimit) @@ -763,20 +726,18 @@ void btHingeConstraint::setMotorTarget(btScalar targetAngle, btScalar dt) } #endif // compute angular velocity - btScalar curAngle = getHingeAngle(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); + btScalar curAngle = getHingeAngle(m_rbA.getCenterOfMassTransform(), m_rbB.getCenterOfMassTransform()); btScalar dAngle = targetAngle - curAngle; m_motorTargetVelocity = dAngle / dt; } - - -void btHingeConstraint::getInfo2InternalUsingFrameOffset(btConstraintInfo2* info, const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB) +void btHingeConstraint::getInfo2InternalUsingFrameOffset(btConstraintInfo2* info, const btTransform& transA, const btTransform& transB, const btVector3& angVelA, const btVector3& angVelB) { btAssert(!m_useSolveConstraintObsolete); int i, s = info->rowskip; // transforms in world space - btTransform trA = transA*m_rbAFrame; - btTransform trB = transB*m_rbBFrame; + btTransform trA = transA * m_rbAFrame; + btTransform trB = transB * m_rbBFrame; // pivot point // btVector3 pivotAInW = trA.getOrigin(); // btVector3 pivotBInW = trB.getOrigin(); @@ -789,11 +750,11 @@ void btHingeConstraint::getInfo2InternalUsingFrameOffset(btConstraintInfo2* info bool hasStaticBody = (miA < SIMD_EPSILON) || (miB < SIMD_EPSILON); btScalar miS = miA + miB; btScalar factA, factB; - if(miS > btScalar(0.f)) + if (miS > btScalar(0.f)) { factA = miB / miS; } - else + else { factA = btScalar(0.5f); } @@ -804,14 +765,14 @@ void btHingeConstraint::getInfo2InternalUsingFrameOffset(btConstraintInfo2* info btVector3 ax1B = trB.getBasis().getColumn(2); btVector3 ax1 = ax1A * factA + ax1B * factB; ax1.normalize(); - // fill first 3 rows + // fill first 3 rows // we want: velA + wA x relA == velB + wB x relB btTransform bodyA_trans = transA; btTransform bodyB_trans = transB; int s0 = 0; int s1 = s; int s2 = s * 2; - int nrow = 2; // last filled row + int nrow = 2; // last filled row btVector3 tmpA, tmpB, relA, relB, p, q; // get vector from bodyB to frameB in WCS relB = trB.getOrigin() - bodyB_trans.getOrigin(); @@ -830,7 +791,7 @@ void btHingeConstraint::getInfo2InternalUsingFrameOffset(btConstraintInfo2* info // now choose average ortho to hinge axis p = orthoB * factA + orthoA * factB; btScalar len2 = p.length2(); - if(len2 > SIMD_EPSILON) + if (len2 > SIMD_EPSILON) { p /= btSqrt(len2); } @@ -843,44 +804,44 @@ void btHingeConstraint::getInfo2InternalUsingFrameOffset(btConstraintInfo2* info // fill three rows tmpA = relA.cross(p); tmpB = relB.cross(p); - for (i=0; i<3; i++) info->m_J1angularAxis[s0+i] = tmpA[i]; - for (i=0; i<3; i++) info->m_J2angularAxis[s0+i] = -tmpB[i]; + for (i = 0; i < 3; i++) info->m_J1angularAxis[s0 + i] = tmpA[i]; + for (i = 0; i < 3; i++) info->m_J2angularAxis[s0 + i] = -tmpB[i]; tmpA = relA.cross(q); tmpB = relB.cross(q); - if(hasStaticBody && getSolveLimit()) - { // to make constraint between static and dynamic objects more rigid + if (hasStaticBody && getSolveLimit()) + { // to make constraint between static and dynamic objects more rigid // remove wA (or wB) from equation if angular limit is hit tmpB *= factB; tmpA *= factA; } - for (i=0; i<3; i++) info->m_J1angularAxis[s1+i] = tmpA[i]; - for (i=0; i<3; i++) info->m_J2angularAxis[s1+i] = -tmpB[i]; + for (i = 0; i < 3; i++) info->m_J1angularAxis[s1 + i] = tmpA[i]; + for (i = 0; i < 3; i++) info->m_J2angularAxis[s1 + i] = -tmpB[i]; tmpA = relA.cross(ax1); tmpB = relB.cross(ax1); - if(hasStaticBody) - { // to make constraint between static and dynamic objects more rigid + if (hasStaticBody) + { // to make constraint between static and dynamic objects more rigid // remove wA (or wB) from equation tmpB *= factB; tmpA *= factA; } - for (i=0; i<3; i++) info->m_J1angularAxis[s2+i] = tmpA[i]; - for (i=0; i<3; i++) info->m_J2angularAxis[s2+i] = -tmpB[i]; + for (i = 0; i < 3; i++) info->m_J1angularAxis[s2 + i] = tmpA[i]; + for (i = 0; i < 3; i++) info->m_J2angularAxis[s2 + i] = -tmpB[i]; - btScalar normalErp = (m_flags & BT_HINGE_FLAGS_ERP_NORM)? m_normalERP : info->erp; + btScalar normalErp = (m_flags & BT_HINGE_FLAGS_ERP_NORM) ? m_normalERP : info->erp; btScalar k = info->fps * normalErp; if (!m_angularOnly) { - for (i=0; i<3; i++) info->m_J1linearAxis[s0+i] = p[i]; - for (i=0; i<3; i++) info->m_J1linearAxis[s1+i] = q[i]; - for (i=0; i<3; i++) info->m_J1linearAxis[s2+i] = ax1[i]; + for (i = 0; i < 3; i++) info->m_J1linearAxis[s0 + i] = p[i]; + for (i = 0; i < 3; i++) info->m_J1linearAxis[s1 + i] = q[i]; + for (i = 0; i < 3; i++) info->m_J1linearAxis[s2 + i] = ax1[i]; - for (i=0; i<3; i++) info->m_J2linearAxis[s0+i] = -p[i]; - for (i=0; i<3; i++) info->m_J2linearAxis[s1+i] = -q[i]; - for (i=0; i<3; i++) info->m_J2linearAxis[s2+i] = -ax1[i]; + for (i = 0; i < 3; i++) info->m_J2linearAxis[s0 + i] = -p[i]; + for (i = 0; i < 3; i++) info->m_J2linearAxis[s1 + i] = -q[i]; + for (i = 0; i < 3; i++) info->m_J2linearAxis[s2 + i] = -ax1[i]; + + // compute three elements of right hand side - // compute three elements of right hand side - btScalar rhs = k * p.dot(ofs); info->m_constraintError[s0] = rhs; rhs = k * q.dot(ofs); @@ -925,146 +886,144 @@ void btHingeConstraint::getInfo2InternalUsingFrameOffset(btConstraintInfo2* info // angular_velocity = (erp*fps) * (ax1 x ax2) // ax1 x ax2 is in the plane space of ax1, so we project the angular // velocity to p and q to find the right hand side. - k = info->fps * normalErp;//?? + k = info->fps * normalErp; //?? btVector3 u = ax1A.cross(ax1B); info->m_constraintError[s3] = k * u.dot(p); info->m_constraintError[s4] = k * u.dot(q); #endif // check angular limits - nrow = 4; // last filled row + nrow = 4; // last filled row int srow; btScalar limit_err = btScalar(0.0); int limit = 0; - if(getSolveLimit()) + if (getSolveLimit()) { -#ifdef _BT_USE_CENTER_LIMIT_ - limit_err = m_limit.getCorrection() * m_referenceSign; +#ifdef _BT_USE_CENTER_LIMIT_ + limit_err = m_limit.getCorrection() * m_referenceSign; #else - limit_err = m_correction * m_referenceSign; + limit_err = m_correction * m_referenceSign; #endif - limit = (limit_err > btScalar(0.0)) ? 1 : 2; - + limit = (limit_err > btScalar(0.0)) ? 1 : 2; } // if the hinge has joint limits or motor, add in the extra row bool powered = getEnableAngularMotor(); - if(limit || powered) + if (limit || powered) { nrow++; srow = nrow * info->rowskip; - info->m_J1angularAxis[srow+0] = ax1[0]; - info->m_J1angularAxis[srow+1] = ax1[1]; - info->m_J1angularAxis[srow+2] = ax1[2]; + info->m_J1angularAxis[srow + 0] = ax1[0]; + info->m_J1angularAxis[srow + 1] = ax1[1]; + info->m_J1angularAxis[srow + 2] = ax1[2]; - info->m_J2angularAxis[srow+0] = -ax1[0]; - info->m_J2angularAxis[srow+1] = -ax1[1]; - info->m_J2angularAxis[srow+2] = -ax1[2]; + info->m_J2angularAxis[srow + 0] = -ax1[0]; + info->m_J2angularAxis[srow + 1] = -ax1[1]; + info->m_J2angularAxis[srow + 2] = -ax1[2]; btScalar lostop = getLowerLimit(); btScalar histop = getUpperLimit(); - if(limit && (lostop == histop)) + if (limit && (lostop == histop)) { // the joint motor is ineffective powered = false; } info->m_constraintError[srow] = btScalar(0.0f); btScalar currERP = (m_flags & BT_HINGE_FLAGS_ERP_STOP) ? m_stopERP : normalErp; - if(powered) + if (powered) { - if(m_flags & BT_HINGE_FLAGS_CFM_NORM) + if (m_flags & BT_HINGE_FLAGS_CFM_NORM) { info->cfm[srow] = m_normalCFM; } btScalar mot_fact = getMotorFactor(m_hingeAngle, lostop, histop, m_motorTargetVelocity, info->fps * currERP); info->m_constraintError[srow] += mot_fact * m_motorTargetVelocity * m_referenceSign; - info->m_lowerLimit[srow] = - m_maxMotorImpulse; - info->m_upperLimit[srow] = m_maxMotorImpulse; + info->m_lowerLimit[srow] = -m_maxMotorImpulse; + info->m_upperLimit[srow] = m_maxMotorImpulse; } - if(limit) + if (limit) { k = info->fps * currERP; info->m_constraintError[srow] += k * limit_err; - if(m_flags & BT_HINGE_FLAGS_CFM_STOP) + if (m_flags & BT_HINGE_FLAGS_CFM_STOP) { info->cfm[srow] = m_stopCFM; } - if(lostop == histop) + if (lostop == histop) { // limited low and high simultaneously info->m_lowerLimit[srow] = -SIMD_INFINITY; info->m_upperLimit[srow] = SIMD_INFINITY; } - else if(limit == 1) - { // low limit + else if (limit == 1) + { // low limit info->m_lowerLimit[srow] = 0; info->m_upperLimit[srow] = SIMD_INFINITY; } - else - { // high limit + else + { // high limit info->m_lowerLimit[srow] = -SIMD_INFINITY; info->m_upperLimit[srow] = 0; } // bounce (we'll use slider parameter abs(1.0 - m_dampingLimAng) for that) -#ifdef _BT_USE_CENTER_LIMIT_ +#ifdef _BT_USE_CENTER_LIMIT_ btScalar bounce = m_limit.getRelaxationFactor(); #else btScalar bounce = m_relaxationFactor; #endif - if(bounce > btScalar(0.0)) + if (bounce > btScalar(0.0)) { btScalar vel = angVelA.dot(ax1); vel -= angVelB.dot(ax1); // only apply bounce if the velocity is incoming, and if the // resulting c[] exceeds what we already have. - if(limit == 1) - { // low limit - if(vel < 0) + if (limit == 1) + { // low limit + if (vel < 0) { btScalar newc = -bounce * vel; - if(newc > info->m_constraintError[srow]) + if (newc > info->m_constraintError[srow]) { info->m_constraintError[srow] = newc; } } } else - { // high limit - all those computations are reversed - if(vel > 0) + { // high limit - all those computations are reversed + if (vel > 0) { btScalar newc = -bounce * vel; - if(newc < info->m_constraintError[srow]) + if (newc < info->m_constraintError[srow]) { info->m_constraintError[srow] = newc; } } } } -#ifdef _BT_USE_CENTER_LIMIT_ +#ifdef _BT_USE_CENTER_LIMIT_ info->m_constraintError[srow] *= m_limit.getBiasFactor(); #else info->m_constraintError[srow] *= m_biasFactor; #endif - } // if(limit) - } // if angular limit or powered + } // if(limit) + } // if angular limit or powered } - -///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). +///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). ///If no axis is provided, it uses the default axis for this constraint. void btHingeConstraint::setParam(int num, btScalar value, int axis) { - if((axis == -1) || (axis == 5)) + if ((axis == -1) || (axis == 5)) { - switch(num) - { - case BT_CONSTRAINT_STOP_ERP : + switch (num) + { + case BT_CONSTRAINT_STOP_ERP: m_stopERP = value; m_flags |= BT_HINGE_FLAGS_ERP_STOP; break; - case BT_CONSTRAINT_STOP_CFM : + case BT_CONSTRAINT_STOP_CFM: m_stopCFM = value; m_flags |= BT_HINGE_FLAGS_CFM_STOP; break; - case BT_CONSTRAINT_CFM : + case BT_CONSTRAINT_CFM: m_normalCFM = value; m_flags |= BT_HINGE_FLAGS_CFM_NORM; break; @@ -1072,7 +1031,7 @@ void btHingeConstraint::setParam(int num, btScalar value, int axis) m_normalERP = value; m_flags |= BT_HINGE_FLAGS_ERP_NORM; break; - default : + default: btAssertConstrParams(0); } } @@ -1083,22 +1042,22 @@ void btHingeConstraint::setParam(int num, btScalar value, int axis) } ///return the local value of parameter -btScalar btHingeConstraint::getParam(int num, int axis) const +btScalar btHingeConstraint::getParam(int num, int axis) const { btScalar retVal = 0; - if((axis == -1) || (axis == 5)) + if ((axis == -1) || (axis == 5)) { - switch(num) - { - case BT_CONSTRAINT_STOP_ERP : + switch (num) + { + case BT_CONSTRAINT_STOP_ERP: btAssertConstrParams(m_flags & BT_HINGE_FLAGS_ERP_STOP); retVal = m_stopERP; break; - case BT_CONSTRAINT_STOP_CFM : + case BT_CONSTRAINT_STOP_CFM: btAssertConstrParams(m_flags & BT_HINGE_FLAGS_CFM_STOP); retVal = m_stopCFM; break; - case BT_CONSTRAINT_CFM : + case BT_CONSTRAINT_CFM: btAssertConstrParams(m_flags & BT_HINGE_FLAGS_CFM_NORM); retVal = m_normalCFM; break; @@ -1106,7 +1065,7 @@ btScalar btHingeConstraint::getParam(int num, int axis) const btAssertConstrParams(m_flags & BT_HINGE_FLAGS_ERP_NORM); retVal = m_normalERP; break; - default : + default: btAssertConstrParams(0); } } @@ -1116,5 +1075,3 @@ btScalar btHingeConstraint::getParam(int num, int axis) const } return retVal; } - - diff --git a/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h b/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h index 3c3df24db..c7509e30a 100644 --- a/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h +++ b/src/BulletDynamics/ConstraintSolver/btHingeConstraint.h @@ -20,7 +20,6 @@ subject to the following restrictions: #define _BT_USE_CENTER_LIMIT_ 1 - #include "LinearMath/btVector3.h" #include "btJacobianEntry.h" #include "btTypedConstraint.h" @@ -28,14 +27,12 @@ subject to the following restrictions: class btRigidBody; #ifdef BT_USE_DOUBLE_PRECISION -#define btHingeConstraintData btHingeConstraintDoubleData2 //rename to 2 for backwards compatibility, so we can still load the 'btHingeConstraintDoubleData' version -#define btHingeConstraintDataName "btHingeConstraintDoubleData2" +#define btHingeConstraintData btHingeConstraintDoubleData2 //rename to 2 for backwards compatibility, so we can still load the 'btHingeConstraintDoubleData' version +#define btHingeConstraintDataName "btHingeConstraintDoubleData2" #else -#define btHingeConstraintData btHingeConstraintFloatData -#define btHingeConstraintDataName "btHingeConstraintFloatData" -#endif //BT_USE_DOUBLE_PRECISION - - +#define btHingeConstraintData btHingeConstraintFloatData +#define btHingeConstraintDataName "btHingeConstraintFloatData" +#endif //BT_USE_DOUBLE_PRECISION enum btHingeFlags { @@ -45,89 +42,83 @@ enum btHingeFlags BT_HINGE_FLAGS_ERP_NORM = 8 }; - /// hinge constraint between two rigidbodies each with a pivotpoint that descibes the axis location in local space /// axis defines the orientation of the hinge axis -ATTRIBUTE_ALIGNED16(class) btHingeConstraint : public btTypedConstraint +ATTRIBUTE_ALIGNED16(class) +btHingeConstraint : public btTypedConstraint { #ifdef IN_PARALLELL_SOLVER public: #endif - btJacobianEntry m_jac[3]; //3 orthogonal linear constraints - btJacobianEntry m_jacAng[3]; //2 orthogonal angular constraints+ 1 for limit/motor + btJacobianEntry m_jac[3]; //3 orthogonal linear constraints + btJacobianEntry m_jacAng[3]; //2 orthogonal angular constraints+ 1 for limit/motor - btTransform m_rbAFrame; // constraint axii. Assumes z is hinge axis. + btTransform m_rbAFrame; // constraint axii. Assumes z is hinge axis. btTransform m_rbBFrame; - btScalar m_motorTargetVelocity; - btScalar m_maxMotorImpulse; + btScalar m_motorTargetVelocity; + btScalar m_maxMotorImpulse; - -#ifdef _BT_USE_CENTER_LIMIT_ - btAngularLimit m_limit; +#ifdef _BT_USE_CENTER_LIMIT_ + btAngularLimit m_limit; #else - btScalar m_lowerLimit; - btScalar m_upperLimit; - btScalar m_limitSign; - btScalar m_correction; + btScalar m_lowerLimit; + btScalar m_upperLimit; + btScalar m_limitSign; + btScalar m_correction; - btScalar m_limitSoftness; - btScalar m_biasFactor; - btScalar m_relaxationFactor; + btScalar m_limitSoftness; + btScalar m_biasFactor; + btScalar m_relaxationFactor; - bool m_solveLimit; + bool m_solveLimit; #endif - btScalar m_kHinge; + btScalar m_kHinge; + btScalar m_accLimitImpulse; + btScalar m_hingeAngle; + btScalar m_referenceSign; - btScalar m_accLimitImpulse; - btScalar m_hingeAngle; - btScalar m_referenceSign; + bool m_angularOnly; + bool m_enableAngularMotor; + bool m_useSolveConstraintObsolete; + bool m_useOffsetForConstraintFrame; + bool m_useReferenceFrameA; - bool m_angularOnly; - bool m_enableAngularMotor; - bool m_useSolveConstraintObsolete; - bool m_useOffsetForConstraintFrame; - bool m_useReferenceFrameA; + btScalar m_accMotorImpulse; - btScalar m_accMotorImpulse; + int m_flags; + btScalar m_normalCFM; + btScalar m_normalERP; + btScalar m_stopCFM; + btScalar m_stopERP; - int m_flags; - btScalar m_normalCFM; - btScalar m_normalERP; - btScalar m_stopCFM; - btScalar m_stopERP; - - public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - - btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, const btVector3& axisInA,const btVector3& axisInB, bool useReferenceFrameA = false); - btHingeConstraint(btRigidBody& rbA,const btVector3& pivotInA,const btVector3& axisInA, bool useReferenceFrameA = false); - - btHingeConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false); + btHingeConstraint(btRigidBody & rbA, btRigidBody & rbB, const btVector3& pivotInA, const btVector3& pivotInB, const btVector3& axisInA, const btVector3& axisInB, bool useReferenceFrameA = false); - btHingeConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA = false); + btHingeConstraint(btRigidBody & rbA, const btVector3& pivotInA, const btVector3& axisInA, bool useReferenceFrameA = false); + btHingeConstraint(btRigidBody & rbA, btRigidBody & rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false); - virtual void buildJacobian(); + btHingeConstraint(btRigidBody & rbA, const btTransform& rbAFrame, bool useReferenceFrameA = false); - virtual void getInfo1 (btConstraintInfo1* info); + virtual void buildJacobian(); - void getInfo1NonVirtual(btConstraintInfo1* info); + virtual void getInfo1(btConstraintInfo1 * info); - virtual void getInfo2 (btConstraintInfo2* info); + void getInfo1NonVirtual(btConstraintInfo1 * info); - void getInfo2NonVirtual(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB); + virtual void getInfo2(btConstraintInfo2 * info); - void getInfo2Internal(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB); - void getInfo2InternalUsingFrameOffset(btConstraintInfo2* info,const btTransform& transA,const btTransform& transB,const btVector3& angVelA,const btVector3& angVelB); - + void getInfo2NonVirtual(btConstraintInfo2 * info, const btTransform& transA, const btTransform& transB, const btVector3& angVelA, const btVector3& angVelB); - void updateRHS(btScalar timeStep); + void getInfo2Internal(btConstraintInfo2 * info, const btTransform& transA, const btTransform& transB, const btVector3& angVelA, const btVector3& angVelB); + void getInfo2InternalUsingFrameOffset(btConstraintInfo2 * info, const btTransform& transA, const btTransform& transB, const btVector3& angVelA, const btVector3& angVelB); + + void updateRHS(btScalar timeStep); const btRigidBody& getRigidBodyA() const { @@ -138,19 +129,19 @@ public: return m_rbB; } - btRigidBody& getRigidBodyA() - { - return m_rbA; - } + btRigidBody& getRigidBodyA() + { + return m_rbA; + } - btRigidBody& getRigidBodyB() - { - return m_rbB; + btRigidBody& getRigidBodyB() + { + return m_rbB; } btTransform& getFrameOffsetA() { - return m_rbAFrame; + return m_rbAFrame; } btTransform& getFrameOffsetB() @@ -159,15 +150,15 @@ public: } void setFrames(const btTransform& frameA, const btTransform& frameB); - - void setAngularOnly(bool angularOnly) + + void setAngularOnly(bool angularOnly) { m_angularOnly = angularOnly; } - void enableAngularMotor(bool enableMotor,btScalar targetVelocity,btScalar maxMotorImpulse) + void enableAngularMotor(bool enableMotor, btScalar targetVelocity, btScalar maxMotorImpulse) { - m_enableAngularMotor = enableMotor; + m_enableAngularMotor = enableMotor; m_motorTargetVelocity = targetVelocity; m_maxMotorImpulse = maxMotorImpulse; } @@ -175,29 +166,28 @@ public: // extra motor API, including ability to set a target rotation (as opposed to angular velocity) // note: setMotorTarget sets angular velocity under the hood, so you must call it every tick to // maintain a given angular target. - void enableMotor(bool enableMotor) { m_enableAngularMotor = enableMotor; } + void enableMotor(bool enableMotor) { m_enableAngularMotor = enableMotor; } void setMaxMotorImpulse(btScalar maxMotorImpulse) { m_maxMotorImpulse = maxMotorImpulse; } void setMotorTargetVelocity(btScalar motorTargetVelocity) { m_motorTargetVelocity = motorTargetVelocity; } - void setMotorTarget(const btQuaternion& qAinB, btScalar dt); // qAinB is rotation of body A wrt body B. + void setMotorTarget(const btQuaternion& qAinB, btScalar dt); // qAinB is rotation of body A wrt body B. void setMotorTarget(btScalar targetAngle, btScalar dt); - - void setLimit(btScalar low,btScalar high,btScalar _softness = 0.9f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f) + void setLimit(btScalar low, btScalar high, btScalar _softness = 0.9f, btScalar _biasFactor = 0.3f, btScalar _relaxationFactor = 1.0f) { -#ifdef _BT_USE_CENTER_LIMIT_ +#ifdef _BT_USE_CENTER_LIMIT_ m_limit.set(low, high, _softness, _biasFactor, _relaxationFactor); #else m_lowerLimit = btNormalizeAngle(low); m_upperLimit = btNormalizeAngle(high); - m_limitSoftness = _softness; + m_limitSoftness = _softness; m_biasFactor = _biasFactor; m_relaxationFactor = _relaxationFactor; #endif } - + btScalar getLimitSoftness() const { -#ifdef _BT_USE_CENTER_LIMIT_ +#ifdef _BT_USE_CENTER_LIMIT_ return m_limit.getSoftness(); #else return m_limitSoftness; @@ -206,7 +196,7 @@ public: btScalar getLimitBiasFactor() const { -#ifdef _BT_USE_CENTER_LIMIT_ +#ifdef _BT_USE_CENTER_LIMIT_ return m_limit.getBiasFactor(); #else return m_biasFactor; @@ -215,112 +205,110 @@ public: btScalar getLimitRelaxationFactor() const { -#ifdef _BT_USE_CENTER_LIMIT_ +#ifdef _BT_USE_CENTER_LIMIT_ return m_limit.getRelaxationFactor(); #else return m_relaxationFactor; #endif } - void setAxis(btVector3& axisInA) + void setAxis(btVector3 & axisInA) { btVector3 rbAxisA1, rbAxisA2; btPlaneSpace1(axisInA, rbAxisA1, rbAxisA2); btVector3 pivotInA = m_rbAFrame.getOrigin(); -// m_rbAFrame.getOrigin() = pivotInA; - m_rbAFrame.getBasis().setValue( rbAxisA1.getX(),rbAxisA2.getX(),axisInA.getX(), - rbAxisA1.getY(),rbAxisA2.getY(),axisInA.getY(), - rbAxisA1.getZ(),rbAxisA2.getZ(),axisInA.getZ() ); + // m_rbAFrame.getOrigin() = pivotInA; + m_rbAFrame.getBasis().setValue(rbAxisA1.getX(), rbAxisA2.getX(), axisInA.getX(), + rbAxisA1.getY(), rbAxisA2.getY(), axisInA.getY(), + rbAxisA1.getZ(), rbAxisA2.getZ(), axisInA.getZ()); btVector3 axisInB = m_rbA.getCenterOfMassTransform().getBasis() * axisInA; - btQuaternion rotationArc = shortestArcQuat(axisInA,axisInB); - btVector3 rbAxisB1 = quatRotate(rotationArc,rbAxisA1); + btQuaternion rotationArc = shortestArcQuat(axisInA, axisInB); + btVector3 rbAxisB1 = quatRotate(rotationArc, rbAxisA1); btVector3 rbAxisB2 = axisInB.cross(rbAxisB1); m_rbBFrame.getOrigin() = m_rbB.getCenterOfMassTransform().inverse()(m_rbA.getCenterOfMassTransform()(pivotInA)); - m_rbBFrame.getBasis().setValue( rbAxisB1.getX(),rbAxisB2.getX(),axisInB.getX(), - rbAxisB1.getY(),rbAxisB2.getY(),axisInB.getY(), - rbAxisB1.getZ(),rbAxisB2.getZ(),axisInB.getZ() ); + m_rbBFrame.getBasis().setValue(rbAxisB1.getX(), rbAxisB2.getX(), axisInB.getX(), + rbAxisB1.getY(), rbAxisB2.getY(), axisInB.getY(), + rbAxisB1.getZ(), rbAxisB2.getZ(), axisInB.getZ()); m_rbBFrame.getBasis() = m_rbB.getCenterOfMassTransform().getBasis().inverse() * m_rbBFrame.getBasis(); - } - bool hasLimit() const { -#ifdef _BT_USE_CENTER_LIMIT_ - return m_limit.getHalfRange() > 0; -#else - return m_lowerLimit <= m_upperLimit; -#endif - } - - btScalar getLowerLimit() const + bool hasLimit() const { -#ifdef _BT_USE_CENTER_LIMIT_ - return m_limit.getLow(); +#ifdef _BT_USE_CENTER_LIMIT_ + return m_limit.getHalfRange() > 0; #else - return m_lowerLimit; + return m_lowerLimit <= m_upperLimit; #endif } - btScalar getUpperLimit() const + btScalar getLowerLimit() const { -#ifdef _BT_USE_CENTER_LIMIT_ - return m_limit.getHigh(); -#else - return m_upperLimit; +#ifdef _BT_USE_CENTER_LIMIT_ + return m_limit.getLow(); +#else + return m_lowerLimit; #endif } + btScalar getUpperLimit() const + { +#ifdef _BT_USE_CENTER_LIMIT_ + return m_limit.getHigh(); +#else + return m_upperLimit; +#endif + } ///The getHingeAngle gives the hinge angle in range [-PI,PI] btScalar getHingeAngle(); - btScalar getHingeAngle(const btTransform& transA,const btTransform& transB); + btScalar getHingeAngle(const btTransform& transA, const btTransform& transB); - void testLimit(const btTransform& transA,const btTransform& transB); + void testLimit(const btTransform& transA, const btTransform& transB); - - const btTransform& getAFrame() const { return m_rbAFrame; }; + const btTransform& getAFrame() const { return m_rbAFrame; }; const btTransform& getBFrame() const { return m_rbBFrame; }; - btTransform& getAFrame() { return m_rbAFrame; }; + btTransform& getAFrame() { return m_rbAFrame; }; btTransform& getBFrame() { return m_rbBFrame; }; inline int getSolveLimit() { -#ifdef _BT_USE_CENTER_LIMIT_ - return m_limit.isLimit(); +#ifdef _BT_USE_CENTER_LIMIT_ + return m_limit.isLimit(); #else - return m_solveLimit; + return m_solveLimit; #endif } inline btScalar getLimitSign() { -#ifdef _BT_USE_CENTER_LIMIT_ - return m_limit.getSign(); +#ifdef _BT_USE_CENTER_LIMIT_ + return m_limit.getSign(); #else return m_limitSign; #endif } - inline bool getAngularOnly() - { - return m_angularOnly; + inline bool getAngularOnly() + { + return m_angularOnly; } - inline bool getEnableAngularMotor() - { - return m_enableAngularMotor; + inline bool getEnableAngularMotor() + { + return m_enableAngularMotor; } - inline btScalar getMotorTargetVelocity() - { - return m_motorTargetVelocity; + inline btScalar getMotorTargetVelocity() + { + return m_motorTargetVelocity; } - inline btScalar getMaxMotorImpulse() - { - return m_maxMotorImpulse; + inline btScalar getMaxMotorImpulse() + { + return m_maxMotorImpulse; } // access for UseFrameOffset bool getUseFrameOffset() { return m_useOffsetForConstraintFrame; } @@ -329,143 +317,132 @@ public: bool getUseReferenceFrameA() const { return m_useReferenceFrameA; } void setUseReferenceFrameA(bool useReferenceFrameA) { m_useReferenceFrameA = useReferenceFrameA; } - ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). + ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). ///If no axis is provided, it uses the default axis for this constraint. - virtual void setParam(int num, btScalar value, int axis = -1); + virtual void setParam(int num, btScalar value, int axis = -1); ///return the local value of parameter - virtual btScalar getParam(int num, int axis = -1) const; - - virtual int getFlags() const + virtual btScalar getParam(int num, int axis = -1) const; + + virtual int getFlags() const { - return m_flags; + return m_flags; } - virtual int calculateSerializeBufferSize() const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; - - + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; }; - //only for backward compatibility #ifdef BT_BACKWARDS_COMPATIBLE_SERIALIZATION ///this structure is not used, except for loading pre-2.82 .bullet files -struct btHingeConstraintDoubleData +struct btHingeConstraintDoubleData { - btTypedConstraintData m_typeConstraintData; - btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis. + btTypedConstraintData m_typeConstraintData; + btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis. btTransformDoubleData m_rbBFrame; - int m_useReferenceFrameA; - int m_angularOnly; - int m_enableAngularMotor; - float m_motorTargetVelocity; - float m_maxMotorImpulse; - - float m_lowerLimit; - float m_upperLimit; - float m_limitSoftness; - float m_biasFactor; - float m_relaxationFactor; + int m_useReferenceFrameA; + int m_angularOnly; + int m_enableAngularMotor; + float m_motorTargetVelocity; + float m_maxMotorImpulse; + float m_lowerLimit; + float m_upperLimit; + float m_limitSoftness; + float m_biasFactor; + float m_relaxationFactor; }; -#endif //BT_BACKWARDS_COMPATIBLE_SERIALIZATION +#endif //BT_BACKWARDS_COMPATIBLE_SERIALIZATION ///The getAccumulatedHingeAngle returns the accumulated hinge angle, taking rotation across the -PI/PI boundary into account -ATTRIBUTE_ALIGNED16(class) btHingeAccumulatedAngleConstraint : public btHingeConstraint +ATTRIBUTE_ALIGNED16(class) +btHingeAccumulatedAngleConstraint : public btHingeConstraint { protected: - btScalar m_accumulatedAngle; + btScalar m_accumulatedAngle; + public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - - btHingeAccumulatedAngleConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB, const btVector3& axisInA,const btVector3& axisInB, bool useReferenceFrameA = false) - :btHingeConstraint(rbA,rbB,pivotInA,pivotInB, axisInA,axisInB, useReferenceFrameA ) + + btHingeAccumulatedAngleConstraint(btRigidBody & rbA, btRigidBody & rbB, const btVector3& pivotInA, const btVector3& pivotInB, const btVector3& axisInA, const btVector3& axisInB, bool useReferenceFrameA = false) + : btHingeConstraint(rbA, rbB, pivotInA, pivotInB, axisInA, axisInB, useReferenceFrameA) { - m_accumulatedAngle=getHingeAngle(); + m_accumulatedAngle = getHingeAngle(); } - btHingeAccumulatedAngleConstraint(btRigidBody& rbA,const btVector3& pivotInA,const btVector3& axisInA, bool useReferenceFrameA = false) - :btHingeConstraint(rbA,pivotInA,axisInA, useReferenceFrameA) + btHingeAccumulatedAngleConstraint(btRigidBody & rbA, const btVector3& pivotInA, const btVector3& axisInA, bool useReferenceFrameA = false) + : btHingeConstraint(rbA, pivotInA, axisInA, useReferenceFrameA) { - m_accumulatedAngle=getHingeAngle(); - } - - btHingeAccumulatedAngleConstraint(btRigidBody& rbA,btRigidBody& rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false) - :btHingeConstraint(rbA,rbB, rbAFrame, rbBFrame, useReferenceFrameA ) - { - m_accumulatedAngle=getHingeAngle(); + m_accumulatedAngle = getHingeAngle(); } - btHingeAccumulatedAngleConstraint(btRigidBody& rbA,const btTransform& rbAFrame, bool useReferenceFrameA = false) - :btHingeConstraint(rbA,rbAFrame, useReferenceFrameA ) + btHingeAccumulatedAngleConstraint(btRigidBody & rbA, btRigidBody & rbB, const btTransform& rbAFrame, const btTransform& rbBFrame, bool useReferenceFrameA = false) + : btHingeConstraint(rbA, rbB, rbAFrame, rbBFrame, useReferenceFrameA) { - m_accumulatedAngle=getHingeAngle(); + m_accumulatedAngle = getHingeAngle(); + } + + btHingeAccumulatedAngleConstraint(btRigidBody & rbA, const btTransform& rbAFrame, bool useReferenceFrameA = false) + : btHingeConstraint(rbA, rbAFrame, useReferenceFrameA) + { + m_accumulatedAngle = getHingeAngle(); } btScalar getAccumulatedHingeAngle(); - void setAccumulatedHingeAngle(btScalar accAngle); - virtual void getInfo1 (btConstraintInfo1* info); - + void setAccumulatedHingeAngle(btScalar accAngle); + virtual void getInfo1(btConstraintInfo1 * info); }; -struct btHingeConstraintFloatData +struct btHingeConstraintFloatData { - btTypedConstraintData m_typeConstraintData; - btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis. + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis. btTransformFloatData m_rbBFrame; - int m_useReferenceFrameA; - int m_angularOnly; - - int m_enableAngularMotor; - float m_motorTargetVelocity; - float m_maxMotorImpulse; + int m_useReferenceFrameA; + int m_angularOnly; - float m_lowerLimit; - float m_upperLimit; - float m_limitSoftness; - float m_biasFactor; - float m_relaxationFactor; + int m_enableAngularMotor; + float m_motorTargetVelocity; + float m_maxMotorImpulse; + float m_lowerLimit; + float m_upperLimit; + float m_limitSoftness; + float m_biasFactor; + float m_relaxationFactor; }; - - ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 -struct btHingeConstraintDoubleData2 +struct btHingeConstraintDoubleData2 { - btTypedConstraintDoubleData m_typeConstraintData; - btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis. + btTypedConstraintDoubleData m_typeConstraintData; + btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis. btTransformDoubleData m_rbBFrame; - int m_useReferenceFrameA; - int m_angularOnly; - int m_enableAngularMotor; - double m_motorTargetVelocity; - double m_maxMotorImpulse; - - double m_lowerLimit; - double m_upperLimit; - double m_limitSoftness; - double m_biasFactor; - double m_relaxationFactor; - char m_padding1[4]; + int m_useReferenceFrameA; + int m_angularOnly; + int m_enableAngularMotor; + double m_motorTargetVelocity; + double m_maxMotorImpulse; + double m_lowerLimit; + double m_upperLimit; + double m_limitSoftness; + double m_biasFactor; + double m_relaxationFactor; + char m_padding1[4]; }; - - - -SIMD_FORCE_INLINE int btHingeConstraint::calculateSerializeBufferSize() const +SIMD_FORCE_INLINE int btHingeConstraint::calculateSerializeBufferSize() const { return sizeof(btHingeConstraintData); } - ///fills the dataBuffer and returns the struct name (and 0 on failure) -SIMD_FORCE_INLINE const char* btHingeConstraint::serialize(void* dataBuffer, btSerializer* serializer) const +///fills the dataBuffer and returns the struct name (and 0 on failure) +SIMD_FORCE_INLINE const char* btHingeConstraint::serialize(void* dataBuffer, btSerializer* serializer) const { btHingeConstraintData* hingeData = (btHingeConstraintData*)dataBuffer; - btTypedConstraint::serialize(&hingeData->m_typeConstraintData,serializer); + btTypedConstraint::serialize(&hingeData->m_typeConstraintData, serializer); m_rbAFrame.serialize(hingeData->m_rbAFrame); m_rbBFrame.serialize(hingeData->m_rbBFrame); @@ -475,7 +452,7 @@ SIMD_FORCE_INLINE const char* btHingeConstraint::serialize(void* dataBuffer, btS hingeData->m_maxMotorImpulse = float(m_maxMotorImpulse); hingeData->m_motorTargetVelocity = float(m_motorTargetVelocity); hingeData->m_useReferenceFrameA = m_useReferenceFrameA; -#ifdef _BT_USE_CENTER_LIMIT_ +#ifdef _BT_USE_CENTER_LIMIT_ hingeData->m_lowerLimit = float(m_limit.getLow()); hingeData->m_upperLimit = float(m_limit.getHigh()); hingeData->m_limitSoftness = float(m_limit.getSoftness()); @@ -500,4 +477,4 @@ SIMD_FORCE_INLINE const char* btHingeConstraint::serialize(void* dataBuffer, btS return btHingeConstraintDataName; } -#endif //BT_HINGECONSTRAINT_H +#endif //BT_HINGECONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h b/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h index 125580d19..438456fe5 100644 --- a/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h +++ b/src/BulletDynamics/ConstraintSolver/btJacobianEntry.h @@ -18,7 +18,6 @@ subject to the following restrictions: #include "LinearMath/btMatrix3x3.h" - //notes: // Another memory optimization would be to store m_1MinvJt in the remaining 3 w components // which makes the btJacobianEntry memory layout 16 bytes @@ -27,25 +26,26 @@ subject to the following restrictions: /// Jacobian entry is an abstraction that allows to describe constraints /// it can be used in combination with a constraint solver /// Can be used to relate the effect of an impulse to the constraint error -ATTRIBUTE_ALIGNED16(class) btJacobianEntry +ATTRIBUTE_ALIGNED16(class) +btJacobianEntry { public: - btJacobianEntry() {}; + btJacobianEntry(){}; //constraint between two different rigidbodies btJacobianEntry( const btMatrix3x3& world2A, const btMatrix3x3& world2B, - const btVector3& rel_pos1,const btVector3& rel_pos2, + const btVector3& rel_pos1, const btVector3& rel_pos2, const btVector3& jointAxis, - const btVector3& inertiaInvA, + const btVector3& inertiaInvA, const btScalar massInvA, const btVector3& inertiaInvB, const btScalar massInvB) - :m_linearJointAxis(jointAxis) + : m_linearJointAxis(jointAxis) { - m_aJ = world2A*(rel_pos1.cross(m_linearJointAxis)); - m_bJ = world2B*(rel_pos2.cross(-m_linearJointAxis)); - m_0MinvJt = inertiaInvA * m_aJ; + m_aJ = world2A * (rel_pos1.cross(m_linearJointAxis)); + m_bJ = world2B * (rel_pos2.cross(-m_linearJointAxis)); + m_0MinvJt = inertiaInvA * m_aJ; m_1MinvJt = inertiaInvB * m_bJ; m_Adiag = massInvA + m_0MinvJt.dot(m_aJ) + massInvB + m_1MinvJt.dot(m_bJ); @@ -54,33 +54,31 @@ public: //angular constraint between two different rigidbodies btJacobianEntry(const btVector3& jointAxis, - const btMatrix3x3& world2A, - const btMatrix3x3& world2B, - const btVector3& inertiaInvA, - const btVector3& inertiaInvB) - :m_linearJointAxis(btVector3(btScalar(0.),btScalar(0.),btScalar(0.))) + const btMatrix3x3& world2A, + const btMatrix3x3& world2B, + const btVector3& inertiaInvA, + const btVector3& inertiaInvB) + : m_linearJointAxis(btVector3(btScalar(0.), btScalar(0.), btScalar(0.))) { - m_aJ= world2A*jointAxis; - m_bJ = world2B*-jointAxis; - m_0MinvJt = inertiaInvA * m_aJ; + m_aJ = world2A * jointAxis; + m_bJ = world2B * -jointAxis; + m_0MinvJt = inertiaInvA * m_aJ; m_1MinvJt = inertiaInvB * m_bJ; - m_Adiag = m_0MinvJt.dot(m_aJ) + m_1MinvJt.dot(m_bJ); + m_Adiag = m_0MinvJt.dot(m_aJ) + m_1MinvJt.dot(m_bJ); btAssert(m_Adiag > btScalar(0.0)); } //angular constraint between two different rigidbodies btJacobianEntry(const btVector3& axisInA, - const btVector3& axisInB, - const btVector3& inertiaInvA, - const btVector3& inertiaInvB) - : m_linearJointAxis(btVector3(btScalar(0.),btScalar(0.),btScalar(0.))) - , m_aJ(axisInA) - , m_bJ(-axisInB) + const btVector3& axisInB, + const btVector3& inertiaInvA, + const btVector3& inertiaInvB) + : m_linearJointAxis(btVector3(btScalar(0.), btScalar(0.), btScalar(0.))), m_aJ(axisInA), m_bJ(-axisInB) { - m_0MinvJt = inertiaInvA * m_aJ; + m_0MinvJt = inertiaInvA * m_aJ; m_1MinvJt = inertiaInvB * m_bJ; - m_Adiag = m_0MinvJt.dot(m_aJ) + m_1MinvJt.dot(m_bJ); + m_Adiag = m_0MinvJt.dot(m_aJ) + m_1MinvJt.dot(m_bJ); btAssert(m_Adiag > btScalar(0.0)); } @@ -88,25 +86,25 @@ public: //constraint on one rigidbody btJacobianEntry( const btMatrix3x3& world2A, - const btVector3& rel_pos1,const btVector3& rel_pos2, + const btVector3& rel_pos1, const btVector3& rel_pos2, const btVector3& jointAxis, - const btVector3& inertiaInvA, + const btVector3& inertiaInvA, const btScalar massInvA) - :m_linearJointAxis(jointAxis) + : m_linearJointAxis(jointAxis) { - m_aJ= world2A*(rel_pos1.cross(jointAxis)); - m_bJ = world2A*(rel_pos2.cross(-jointAxis)); - m_0MinvJt = inertiaInvA * m_aJ; - m_1MinvJt = btVector3(btScalar(0.),btScalar(0.),btScalar(0.)); + m_aJ = world2A * (rel_pos1.cross(jointAxis)); + m_bJ = world2A * (rel_pos2.cross(-jointAxis)); + m_0MinvJt = inertiaInvA * m_aJ; + m_1MinvJt = btVector3(btScalar(0.), btScalar(0.), btScalar(0.)); m_Adiag = massInvA + m_0MinvJt.dot(m_aJ); btAssert(m_Adiag > btScalar(0.0)); } - btScalar getDiagonal() const { return m_Adiag; } + btScalar getDiagonal() const { return m_Adiag; } // for two constraints on the same rigidbody (for example vehicle friction) - btScalar getNonDiagonal(const btJacobianEntry& jacB, const btScalar massInvA) const + btScalar getNonDiagonal(const btJacobianEntry& jacB, const btScalar massInvA) const { const btJacobianEntry& jacA = *this; btScalar lin = massInvA * jacA.m_linearJointAxis.dot(jacB.m_linearJointAxis); @@ -114,42 +112,39 @@ public: return lin + ang; } - - // for two constraints on sharing two same rigidbodies (for example two contact points between two rigidbodies) - btScalar getNonDiagonal(const btJacobianEntry& jacB,const btScalar massInvA,const btScalar massInvB) const + btScalar getNonDiagonal(const btJacobianEntry& jacB, const btScalar massInvA, const btScalar massInvB) const { const btJacobianEntry& jacA = *this; btVector3 lin = jacA.m_linearJointAxis * jacB.m_linearJointAxis; btVector3 ang0 = jacA.m_0MinvJt * jacB.m_aJ; btVector3 ang1 = jacA.m_1MinvJt * jacB.m_bJ; - btVector3 lin0 = massInvA * lin ; + btVector3 lin0 = massInvA * lin; btVector3 lin1 = massInvB * lin; - btVector3 sum = ang0+ang1+lin0+lin1; - return sum[0]+sum[1]+sum[2]; + btVector3 sum = ang0 + ang1 + lin0 + lin1; + return sum[0] + sum[1] + sum[2]; } - btScalar getRelativeVelocity(const btVector3& linvelA,const btVector3& angvelA,const btVector3& linvelB,const btVector3& angvelB) + btScalar getRelativeVelocity(const btVector3& linvelA, const btVector3& angvelA, const btVector3& linvelB, const btVector3& angvelB) { btVector3 linrel = linvelA - linvelB; - btVector3 angvela = angvelA * m_aJ; - btVector3 angvelb = angvelB * m_bJ; + btVector3 angvela = angvelA * m_aJ; + btVector3 angvelb = angvelB * m_bJ; linrel *= m_linearJointAxis; angvela += angvelb; angvela += linrel; - btScalar rel_vel2 = angvela[0]+angvela[1]+angvela[2]; + btScalar rel_vel2 = angvela[0] + angvela[1] + angvela[2]; return rel_vel2 + SIMD_EPSILON; } -//private: + //private: - btVector3 m_linearJointAxis; - btVector3 m_aJ; - btVector3 m_bJ; - btVector3 m_0MinvJt; - btVector3 m_1MinvJt; + btVector3 m_linearJointAxis; + btVector3 m_aJ; + btVector3 m_bJ; + btVector3 m_0MinvJt; + btVector3 m_1MinvJt; //Optimization: can be stored in the w/last component of one of the vectors - btScalar m_Adiag; - + btScalar m_Adiag; }; -#endif //BT_JACOBIAN_ENTRY_H +#endif //BT_JACOBIAN_ENTRY_H diff --git a/src/BulletDynamics/ConstraintSolver/btNNCGConstraintSolver.cpp b/src/BulletDynamics/ConstraintSolver/btNNCGConstraintSolver.cpp index f3979be35..ccf891604 100644 --- a/src/BulletDynamics/ConstraintSolver/btNNCGConstraintSolver.cpp +++ b/src/BulletDynamics/ConstraintSolver/btNNCGConstraintSolver.cpp @@ -15,14 +15,9 @@ subject to the following restrictions: #include "btNNCGConstraintSolver.h" - - - - - -btScalar btNNCGConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer) +btScalar btNNCGConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer) { - btScalar val = btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup( bodies,numBodies,manifoldPtr, numManifolds, constraints,numConstraints,infoGlobal,debugDrawer); + btScalar val = btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(bodies, numBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal, debugDrawer); m_pNC.resizeNoInitialize(m_tmpSolverNonContactConstraintPool.size()); m_pC.resizeNoInitialize(m_tmpSolverContactConstraintPool.size()); @@ -37,38 +32,39 @@ btScalar btNNCGConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject* return val; } -btScalar btNNCGConstraintSolver::solveSingleIteration(int iteration, btCollisionObject** /*bodies */,int /*numBodies*/,btPersistentManifold** /*manifoldPtr*/, int /*numManifolds*/,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* /*debugDrawer*/) +btScalar btNNCGConstraintSolver::solveSingleIteration(int iteration, btCollisionObject** /*bodies */, int /*numBodies*/, btPersistentManifold** /*manifoldPtr*/, int /*numManifolds*/, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* /*debugDrawer*/) { - int numNonContactPool = m_tmpSolverNonContactConstraintPool.size(); int numConstraintPool = m_tmpSolverContactConstraintPool.size(); int numFrictionPool = m_tmpSolverContactFrictionConstraintPool.size(); if (infoGlobal.m_solverMode & SOLVER_RANDMIZE_ORDER) { - if (1) // uncomment this for a bit less random ((iteration & 7) == 0) + if (1) // uncomment this for a bit less random ((iteration & 7) == 0) { - - for (int j=0; j0 ? deltaflengthsqr / m_deltafLengthSqrPrev : 2; - if (beta>1) + btScalar beta = m_deltafLengthSqrPrev > 0 ? deltaflengthsqr / m_deltafLengthSqrPrev : 2; + if (beta > 1) { - for (int j=0;jisEnabled()) { - int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA(),infoGlobal.m_timeStep); - int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB(),infoGlobal.m_timeStep); + int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA(), infoGlobal.m_timeStep); + int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB(), infoGlobal.m_timeStep); btSolverBody& bodyA = m_tmpSolverBodyPool[bodyAid]; btSolverBody& bodyB = m_tmpSolverBodyPool[bodyBid]; - constraints[j]->solveConstraintObsolete(bodyA,bodyB,infoGlobal.m_timeStep); + constraints[j]->solveConstraintObsolete(bodyA, bodyB, infoGlobal.m_timeStep); } } @@ -147,203 +141,206 @@ btScalar btNNCGConstraintSolver::solveSingleIteration(int iteration, btCollision if (infoGlobal.m_solverMode & SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS) { int numPoolConstraints = m_tmpSolverContactConstraintPool.size(); - int multiplier = (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)? 2 : 1; + int multiplier = (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) ? 2 : 1; - for (int c=0;cbtScalar(0)) + if (totalImpulse > btScalar(0)) { - solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse); - solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse; - btScalar deltaf = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold); - m_deltafCF[c*multiplier] = deltaf; - deltaflengthsqr += deltaf*deltaf; - } else { - m_deltafCF[c*multiplier] = 0; + solveManifold.m_lowerLimit = -(solveManifold.m_friction * totalImpulse); + solveManifold.m_upperLimit = solveManifold.m_friction * totalImpulse; + btScalar deltaf = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold); + m_deltafCF[c * multiplier] = deltaf; + deltaflengthsqr += deltaf * deltaf; + } + else + { + m_deltafCF[c * multiplier] = 0; } } if (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) { + btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[c * multiplier + 1]]; - btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[c*multiplier+1]]; - - if (totalImpulse>btScalar(0)) + if (totalImpulse > btScalar(0)) { - solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse); - solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse; - btScalar deltaf = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold); - m_deltafCF[c*multiplier+1] = deltaf; - deltaflengthsqr += deltaf*deltaf; - } else { - m_deltafCF[c*multiplier+1] = 0; + solveManifold.m_lowerLimit = -(solveManifold.m_friction * totalImpulse); + solveManifold.m_upperLimit = solveManifold.m_friction * totalImpulse; + btScalar deltaf = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold); + m_deltafCF[c * multiplier + 1] = deltaf; + deltaflengthsqr += deltaf * deltaf; + } + else + { + m_deltafCF[c * multiplier + 1] = 0; } } } } - } - else//SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS + else //SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS { //solve the friction constraints after all contact constraints, don't interleave them int numPoolConstraints = m_tmpSolverContactConstraintPool.size(); int j; - for (j=0;jbtScalar(0)) + if (totalImpulse > btScalar(0)) { - solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse); - solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse; + solveManifold.m_lowerLimit = -(solveManifold.m_friction * totalImpulse); + solveManifold.m_upperLimit = solveManifold.m_friction * totalImpulse; - btScalar deltaf = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold); + btScalar deltaf = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold); m_deltafCF[j] = deltaf; - deltaflengthsqr += deltaf*deltaf; - } else { + deltaflengthsqr += deltaf * deltaf; + } + else + { m_deltafCF[j] = 0; } } } - { + { int numRollingFrictionPoolConstraints = m_tmpSolverContactRollingFrictionConstraintPool.size(); - for (int j=0;jbtScalar(0)) + if (totalImpulse > btScalar(0)) { - btScalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction*totalImpulse; - if (rollingFrictionMagnitude>rollingFrictionConstraint.m_friction) + btScalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction * totalImpulse; + if (rollingFrictionMagnitude > rollingFrictionConstraint.m_friction) rollingFrictionMagnitude = rollingFrictionConstraint.m_friction; rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude; rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude; - btScalar deltaf = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA],m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB],rollingFrictionConstraint); + btScalar deltaf = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA], m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB], rollingFrictionConstraint); m_deltafCRF[j] = deltaf; - deltaflengthsqr += deltaf*deltaf; - } else { + deltaflengthsqr += deltaf * deltaf; + } + else + { m_deltafCRF[j] = 0; } } - } - + } } - - - } - - - - if (!m_onlyForNoneContact) + if (!m_onlyForNoneContact) { - if (iteration==0) + if (iteration == 0) { - for (int j=0;j0 ? deltaflengthsqr / m_deltafLengthSqrPrev : 2; - if (beta>1) { - for (int j=0;j 0 ? deltaflengthsqr / m_deltafLengthSqrPrev : 2; + if (beta > 1) + { + for (int j = 0; j < m_tmpSolverNonContactConstraintPool.size(); j++) m_pNC[j] = 0; + for (int j = 0; j < m_tmpSolverContactConstraintPool.size(); j++) m_pC[j] = 0; + for (int j = 0; j < m_tmpSolverContactFrictionConstraintPool.size(); j++) m_pCF[j] = 0; + for (int j = 0; j < m_tmpSolverContactRollingFrictionConstraintPool.size(); j++) m_pCRF[j] = 0; + } + else + { + for (int j = 0; j < m_tmpSolverNonContactConstraintPool.size(); j++) { btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[m_orderNonContactConstraintPool[j]]; - if (iteration < constraint.m_overrideNumSolverIterations) { + if (iteration < constraint.m_overrideNumSolverIterations) + { btScalar additionaldeltaimpulse = beta * m_pNC[j]; constraint.m_appliedImpulse = btScalar(constraint.m_appliedImpulse) + additionaldeltaimpulse; m_pNC[j] = beta * m_pNC[j] + m_deltafNC[j]; btSolverBody& body1 = m_tmpSolverBodyPool[constraint.m_solverBodyIdA]; btSolverBody& body2 = m_tmpSolverBodyPool[constraint.m_solverBodyIdB]; const btSolverConstraint& c = constraint; - body1.internalApplyImpulse(c.m_contactNormal1*body1.internalGetInvMass(),c.m_angularComponentA,additionaldeltaimpulse); - body2.internalApplyImpulse(c.m_contactNormal2*body2.internalGetInvMass(),c.m_angularComponentB,additionaldeltaimpulse); + body1.internalApplyImpulse(c.m_contactNormal1 * body1.internalGetInvMass(), c.m_angularComponentA, additionaldeltaimpulse); + body2.internalApplyImpulse(c.m_contactNormal2 * body2.internalGetInvMass(), c.m_angularComponentB, additionaldeltaimpulse); } } - for (int j=0;j m_pNC; // p for None Contact constraints - btAlignedObjectArray m_pC; // p for Contact constraints - btAlignedObjectArray m_pCF; // p for ContactFriction constraints - btAlignedObjectArray m_pCRF; // p for ContactRollingFriction constraints + btAlignedObjectArray m_pNC; // p for None Contact constraints + btAlignedObjectArray m_pC; // p for Contact constraints + btAlignedObjectArray m_pCF; // p for ContactFriction constraints + btAlignedObjectArray m_pCRF; // p for ContactRollingFriction constraints //These are recalculated in every iterations. We just keep these to prevent reallocation in each iteration. - btAlignedObjectArray m_deltafNC; // deltaf for NoneContact constraints - btAlignedObjectArray m_deltafC; // deltaf for Contact constraints - btAlignedObjectArray m_deltafCF; // deltaf for ContactFriction constraints - btAlignedObjectArray m_deltafCRF; // deltaf for ContactRollingFriction constraints + btAlignedObjectArray m_deltafNC; // deltaf for NoneContact constraints + btAlignedObjectArray m_deltafC; // deltaf for Contact constraints + btAlignedObjectArray m_deltafCF; // deltaf for ContactFriction constraints + btAlignedObjectArray m_deltafCRF; // deltaf for ContactRollingFriction constraints - protected: + virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject * *bodies, int numBodies, const btContactSolverInfo& infoGlobal); + virtual btScalar solveSingleIteration(int iteration, btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer); - virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject** bodies,int numBodies,const btContactSolverInfo& infoGlobal); - virtual btScalar solveSingleIteration(int iteration, btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer); - - virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer); + virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer); public: - BT_DECLARE_ALIGNED_ALLOCATOR(); btNNCGConstraintSolver() : btSequentialImpulseConstraintSolver(), m_onlyForNoneContact(false) {} @@ -57,8 +54,4 @@ public: bool m_onlyForNoneContact; }; - - - -#endif //BT_NNCG_CONSTRAINT_SOLVER_H - +#endif //BT_NNCG_CONSTRAINT_SOLVER_H diff --git a/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp index 3c0430b90..ad399dc57 100644 --- a/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp +++ b/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.cpp @@ -13,217 +13,193 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btPoint2PointConstraint.h" #include "BulletDynamics/Dynamics/btRigidBody.h" #include - - - - -btPoint2PointConstraint::btPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB) -:btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE,rbA,rbB),m_pivotInA(pivotInA),m_pivotInB(pivotInB), -m_flags(0), -m_useSolveConstraintObsolete(false) +btPoint2PointConstraint::btPoint2PointConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& pivotInA, const btVector3& pivotInB) + : btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE, rbA, rbB), m_pivotInA(pivotInA), m_pivotInB(pivotInB), m_flags(0), m_useSolveConstraintObsolete(false) { - } - -btPoint2PointConstraint::btPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA) -:btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE,rbA),m_pivotInA(pivotInA),m_pivotInB(rbA.getCenterOfMassTransform()(pivotInA)), -m_flags(0), -m_useSolveConstraintObsolete(false) +btPoint2PointConstraint::btPoint2PointConstraint(btRigidBody& rbA, const btVector3& pivotInA) + : btTypedConstraint(POINT2POINT_CONSTRAINT_TYPE, rbA), m_pivotInA(pivotInA), m_pivotInB(rbA.getCenterOfMassTransform()(pivotInA)), m_flags(0), m_useSolveConstraintObsolete(false) { - } -void btPoint2PointConstraint::buildJacobian() +void btPoint2PointConstraint::buildJacobian() { - ///we need it for both methods { m_appliedImpulse = btScalar(0.); - btVector3 normal(0,0,0); + btVector3 normal(0, 0, 0); - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) { normal[i] = 1; new (&m_jac[i]) btJacobianEntry( - m_rbA.getCenterOfMassTransform().getBasis().transpose(), - m_rbB.getCenterOfMassTransform().getBasis().transpose(), - m_rbA.getCenterOfMassTransform()*m_pivotInA - m_rbA.getCenterOfMassPosition(), - m_rbB.getCenterOfMassTransform()*m_pivotInB - m_rbB.getCenterOfMassPosition(), - normal, - m_rbA.getInvInertiaDiagLocal(), - m_rbA.getInvMass(), - m_rbB.getInvInertiaDiagLocal(), - m_rbB.getInvMass()); - normal[i] = 0; + m_rbA.getCenterOfMassTransform().getBasis().transpose(), + m_rbB.getCenterOfMassTransform().getBasis().transpose(), + m_rbA.getCenterOfMassTransform() * m_pivotInA - m_rbA.getCenterOfMassPosition(), + m_rbB.getCenterOfMassTransform() * m_pivotInB - m_rbB.getCenterOfMassPosition(), + normal, + m_rbA.getInvInertiaDiagLocal(), + m_rbA.getInvMass(), + m_rbB.getInvInertiaDiagLocal(), + m_rbB.getInvMass()); + normal[i] = 0; } } - - } -void btPoint2PointConstraint::getInfo1 (btConstraintInfo1* info) +void btPoint2PointConstraint::getInfo1(btConstraintInfo1* info) { getInfo1NonVirtual(info); } -void btPoint2PointConstraint::getInfo1NonVirtual (btConstraintInfo1* info) +void btPoint2PointConstraint::getInfo1NonVirtual(btConstraintInfo1* info) { if (m_useSolveConstraintObsolete) { info->m_numConstraintRows = 0; info->nub = 0; - } else + } + else { info->m_numConstraintRows = 3; info->nub = 3; } } - - - -void btPoint2PointConstraint::getInfo2 (btConstraintInfo2* info) +void btPoint2PointConstraint::getInfo2(btConstraintInfo2* info) { - getInfo2NonVirtual(info, m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); + getInfo2NonVirtual(info, m_rbA.getCenterOfMassTransform(), m_rbB.getCenterOfMassTransform()); } -void btPoint2PointConstraint::getInfo2NonVirtual (btConstraintInfo2* info, const btTransform& body0_trans, const btTransform& body1_trans) +void btPoint2PointConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTransform& body0_trans, const btTransform& body1_trans) { btAssert(!m_useSolveConstraintObsolete); - //retrieve matrices + //retrieve matrices // anchor points in global coordinates with respect to body PORs. - - // set jacobian - info->m_J1linearAxis[0] = 1; - info->m_J1linearAxis[info->rowskip+1] = 1; - info->m_J1linearAxis[2*info->rowskip+2] = 1; - btVector3 a1 = body0_trans.getBasis()*getPivotInA(); + // set jacobian + info->m_J1linearAxis[0] = 1; + info->m_J1linearAxis[info->rowskip + 1] = 1; + info->m_J1linearAxis[2 * info->rowskip + 2] = 1; + + btVector3 a1 = body0_trans.getBasis() * getPivotInA(); { btVector3* angular0 = (btVector3*)(info->m_J1angularAxis); - btVector3* angular1 = (btVector3*)(info->m_J1angularAxis+info->rowskip); - btVector3* angular2 = (btVector3*)(info->m_J1angularAxis+2*info->rowskip); + btVector3* angular1 = (btVector3*)(info->m_J1angularAxis + info->rowskip); + btVector3* angular2 = (btVector3*)(info->m_J1angularAxis + 2 * info->rowskip); btVector3 a1neg = -a1; - a1neg.getSkewSymmetricMatrix(angular0,angular1,angular2); + a1neg.getSkewSymmetricMatrix(angular0, angular1, angular2); } - + info->m_J2linearAxis[0] = -1; - info->m_J2linearAxis[info->rowskip+1] = -1; - info->m_J2linearAxis[2*info->rowskip+2] = -1; - - btVector3 a2 = body1_trans.getBasis()*getPivotInB(); - + info->m_J2linearAxis[info->rowskip + 1] = -1; + info->m_J2linearAxis[2 * info->rowskip + 2] = -1; + + btVector3 a2 = body1_trans.getBasis() * getPivotInB(); + { - // btVector3 a2n = -a2; + // btVector3 a2n = -a2; btVector3* angular0 = (btVector3*)(info->m_J2angularAxis); - btVector3* angular1 = (btVector3*)(info->m_J2angularAxis+info->rowskip); - btVector3* angular2 = (btVector3*)(info->m_J2angularAxis+2*info->rowskip); - a2.getSkewSymmetricMatrix(angular0,angular1,angular2); + btVector3* angular1 = (btVector3*)(info->m_J2angularAxis + info->rowskip); + btVector3* angular2 = (btVector3*)(info->m_J2angularAxis + 2 * info->rowskip); + a2.getSkewSymmetricMatrix(angular0, angular1, angular2); } - - - // set right hand side + // set right hand side btScalar currERP = (m_flags & BT_P2P_FLAGS_ERP) ? m_erp : info->erp; - btScalar k = info->fps * currERP; - int j; - for (j=0; j<3; j++) - { - info->m_constraintError[j*info->rowskip] = k * (a2[j] + body1_trans.getOrigin()[j] - a1[j] - body0_trans.getOrigin()[j]); - //printf("info->m_constraintError[%d]=%f\n",j,info->m_constraintError[j]); - } - if(m_flags & BT_P2P_FLAGS_CFM) + btScalar k = info->fps * currERP; + int j; + for (j = 0; j < 3; j++) { - for (j=0; j<3; j++) + info->m_constraintError[j * info->rowskip] = k * (a2[j] + body1_trans.getOrigin()[j] - a1[j] - body0_trans.getOrigin()[j]); + //printf("info->m_constraintError[%d]=%f\n",j,info->m_constraintError[j]); + } + if (m_flags & BT_P2P_FLAGS_CFM) + { + for (j = 0; j < 3; j++) { - info->cfm[j*info->rowskip] = m_cfm; + info->cfm[j * info->rowskip] = m_cfm; } } - btScalar impulseClamp = m_setting.m_impulseClamp;// - for (j=0; j<3; j++) - { + btScalar impulseClamp = m_setting.m_impulseClamp; // + for (j = 0; j < 3; j++) + { if (m_setting.m_impulseClamp > 0) { - info->m_lowerLimit[j*info->rowskip] = -impulseClamp; - info->m_upperLimit[j*info->rowskip] = impulseClamp; + info->m_lowerLimit[j * info->rowskip] = -impulseClamp; + info->m_upperLimit[j * info->rowskip] = impulseClamp; } } info->m_damping = m_setting.m_damping; - } - - -void btPoint2PointConstraint::updateRHS(btScalar timeStep) +void btPoint2PointConstraint::updateRHS(btScalar timeStep) { (void)timeStep; - } -///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). +///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). ///If no axis is provided, it uses the default axis for this constraint. void btPoint2PointConstraint::setParam(int num, btScalar value, int axis) { - if(axis != -1) + if (axis != -1) { btAssertConstrParams(0); } else { - switch(num) + switch (num) { - case BT_CONSTRAINT_ERP : - case BT_CONSTRAINT_STOP_ERP : - m_erp = value; + case BT_CONSTRAINT_ERP: + case BT_CONSTRAINT_STOP_ERP: + m_erp = value; m_flags |= BT_P2P_FLAGS_ERP; break; - case BT_CONSTRAINT_CFM : - case BT_CONSTRAINT_STOP_CFM : - m_cfm = value; + case BT_CONSTRAINT_CFM: + case BT_CONSTRAINT_STOP_CFM: + m_cfm = value; m_flags |= BT_P2P_FLAGS_CFM; break; - default: + default: btAssertConstrParams(0); } } } ///return the local value of parameter -btScalar btPoint2PointConstraint::getParam(int num, int axis) const +btScalar btPoint2PointConstraint::getParam(int num, int axis) const { btScalar retVal(SIMD_INFINITY); - if(axis != -1) + if (axis != -1) { btAssertConstrParams(0); } else { - switch(num) + switch (num) { - case BT_CONSTRAINT_ERP : - case BT_CONSTRAINT_STOP_ERP : + case BT_CONSTRAINT_ERP: + case BT_CONSTRAINT_STOP_ERP: btAssertConstrParams(m_flags & BT_P2P_FLAGS_ERP); - retVal = m_erp; + retVal = m_erp; break; - case BT_CONSTRAINT_CFM : - case BT_CONSTRAINT_STOP_CFM : + case BT_CONSTRAINT_CFM: + case BT_CONSTRAINT_STOP_CFM: btAssertConstrParams(m_flags & BT_P2P_FLAGS_CFM); - retVal = m_cfm; + retVal = m_cfm; break; - default: + default: btAssertConstrParams(0); } } return retVal; } - diff --git a/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h b/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h index 8fa03d719..4717e1980 100644 --- a/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h +++ b/src/BulletDynamics/ConstraintSolver/btPoint2PointConstraint.h @@ -22,26 +22,24 @@ subject to the following restrictions: class btRigidBody; - #ifdef BT_USE_DOUBLE_PRECISION -#define btPoint2PointConstraintData2 btPoint2PointConstraintDoubleData2 -#define btPoint2PointConstraintDataName "btPoint2PointConstraintDoubleData2" +#define btPoint2PointConstraintData2 btPoint2PointConstraintDoubleData2 +#define btPoint2PointConstraintDataName "btPoint2PointConstraintDoubleData2" #else -#define btPoint2PointConstraintData2 btPoint2PointConstraintFloatData -#define btPoint2PointConstraintDataName "btPoint2PointConstraintFloatData" -#endif //BT_USE_DOUBLE_PRECISION +#define btPoint2PointConstraintData2 btPoint2PointConstraintFloatData +#define btPoint2PointConstraintDataName "btPoint2PointConstraintFloatData" +#endif //BT_USE_DOUBLE_PRECISION -struct btConstraintSetting +struct btConstraintSetting { - btConstraintSetting() : - m_tau(btScalar(0.3)), - m_damping(btScalar(1.)), - m_impulseClamp(btScalar(0.)) + btConstraintSetting() : m_tau(btScalar(0.3)), + m_damping(btScalar(1.)), + m_impulseClamp(btScalar(0.)) { } - btScalar m_tau; - btScalar m_damping; - btScalar m_impulseClamp; + btScalar m_tau; + btScalar m_damping; + btScalar m_impulseClamp; }; enum btPoint2PointFlags @@ -51,52 +49,51 @@ enum btPoint2PointFlags }; /// point to point constraint between two rigidbodies each with a pivotpoint that descibes the 'ballsocket' location in local space -ATTRIBUTE_ALIGNED16(class) btPoint2PointConstraint : public btTypedConstraint +ATTRIBUTE_ALIGNED16(class) +btPoint2PointConstraint : public btTypedConstraint { #ifdef IN_PARALLELL_SOLVER public: #endif - btJacobianEntry m_jac[3]; //3 orthogonal linear constraints - - btVector3 m_pivotInA; - btVector3 m_pivotInB; - - int m_flags; - btScalar m_erp; - btScalar m_cfm; - -public: + btJacobianEntry m_jac[3]; //3 orthogonal linear constraints + btVector3 m_pivotInA; + btVector3 m_pivotInB; + + int m_flags; + btScalar m_erp; + btScalar m_cfm; + +public: BT_DECLARE_ALIGNED_ALLOCATOR(); ///for backwards compatibility during the transition to 'getInfo/getInfo2' - bool m_useSolveConstraintObsolete; + bool m_useSolveConstraintObsolete; - btConstraintSetting m_setting; + btConstraintSetting m_setting; - btPoint2PointConstraint(btRigidBody& rbA,btRigidBody& rbB, const btVector3& pivotInA,const btVector3& pivotInB); + btPoint2PointConstraint(btRigidBody & rbA, btRigidBody & rbB, const btVector3& pivotInA, const btVector3& pivotInB); - btPoint2PointConstraint(btRigidBody& rbA,const btVector3& pivotInA); + btPoint2PointConstraint(btRigidBody & rbA, const btVector3& pivotInA); + virtual void buildJacobian(); - virtual void buildJacobian(); + virtual void getInfo1(btConstraintInfo1 * info); - virtual void getInfo1 (btConstraintInfo1* info); + void getInfo1NonVirtual(btConstraintInfo1 * info); - void getInfo1NonVirtual (btConstraintInfo1* info); + virtual void getInfo2(btConstraintInfo2 * info); - virtual void getInfo2 (btConstraintInfo2* info); + void getInfo2NonVirtual(btConstraintInfo2 * info, const btTransform& body0_trans, const btTransform& body1_trans); - void getInfo2NonVirtual (btConstraintInfo2* info, const btTransform& body0_trans, const btTransform& body1_trans); + void updateRHS(btScalar timeStep); - void updateRHS(btScalar timeStep); - - void setPivotA(const btVector3& pivotA) + void setPivotA(const btVector3& pivotA) { m_pivotInA = pivotA; } - void setPivotB(const btVector3& pivotB) + void setPivotB(const btVector3& pivotB) { m_pivotInB = pivotB; } @@ -111,70 +108,66 @@ public: return m_pivotInB; } - ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). + ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). ///If no axis is provided, it uses the default axis for this constraint. - virtual void setParam(int num, btScalar value, int axis = -1); + virtual void setParam(int num, btScalar value, int axis = -1); ///return the local value of parameter - virtual btScalar getParam(int num, int axis = -1) const; - - virtual int getFlags() const - { - return m_flags; - } + virtual btScalar getParam(int num, int axis = -1) const; - virtual int calculateSerializeBufferSize() const; + virtual int getFlags() const + { + return m_flags; + } + + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; - - + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; }; ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 -struct btPoint2PointConstraintFloatData +struct btPoint2PointConstraintFloatData { - btTypedConstraintData m_typeConstraintData; - btVector3FloatData m_pivotInA; - btVector3FloatData m_pivotInB; + btTypedConstraintData m_typeConstraintData; + btVector3FloatData m_pivotInA; + btVector3FloatData m_pivotInB; }; ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 -struct btPoint2PointConstraintDoubleData2 +struct btPoint2PointConstraintDoubleData2 { - btTypedConstraintDoubleData m_typeConstraintData; - btVector3DoubleData m_pivotInA; - btVector3DoubleData m_pivotInB; + btTypedConstraintDoubleData m_typeConstraintData; + btVector3DoubleData m_pivotInA; + btVector3DoubleData m_pivotInB; }; #ifdef BT_BACKWARDS_COMPATIBLE_SERIALIZATION ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 ///this structure is not used, except for loading pre-2.82 .bullet files ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 -struct btPoint2PointConstraintDoubleData +struct btPoint2PointConstraintDoubleData { - btTypedConstraintData m_typeConstraintData; - btVector3DoubleData m_pivotInA; - btVector3DoubleData m_pivotInB; + btTypedConstraintData m_typeConstraintData; + btVector3DoubleData m_pivotInA; + btVector3DoubleData m_pivotInB; }; -#endif //BT_BACKWARDS_COMPATIBLE_SERIALIZATION +#endif //BT_BACKWARDS_COMPATIBLE_SERIALIZATION - -SIMD_FORCE_INLINE int btPoint2PointConstraint::calculateSerializeBufferSize() const +SIMD_FORCE_INLINE int btPoint2PointConstraint::calculateSerializeBufferSize() const { return sizeof(btPoint2PointConstraintData2); - } - ///fills the dataBuffer and returns the struct name (and 0 on failure) -SIMD_FORCE_INLINE const char* btPoint2PointConstraint::serialize(void* dataBuffer, btSerializer* serializer) const +///fills the dataBuffer and returns the struct name (and 0 on failure) +SIMD_FORCE_INLINE const char* btPoint2PointConstraint::serialize(void* dataBuffer, btSerializer* serializer) const { btPoint2PointConstraintData2* p2pData = (btPoint2PointConstraintData2*)dataBuffer; - btTypedConstraint::serialize(&p2pData->m_typeConstraintData,serializer); + btTypedConstraint::serialize(&p2pData->m_typeConstraintData, serializer); m_pivotInA.serialize(p2pData->m_pivotInA); m_pivotInB.serialize(p2pData->m_pivotInB); return btPoint2PointConstraintDataName; } -#endif //BT_POINT2POINTCONSTRAINT_H +#endif //BT_POINT2POINTCONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp b/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp index 63174a6ec..e8a766ecc 100644 --- a/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp +++ b/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.cpp @@ -21,7 +21,6 @@ subject to the following restrictions: #include "btSequentialImpulseConstraintSolver.h" #include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" - #include "LinearMath/btIDebugDraw.h" #include "LinearMath/btCpuFeatureUtility.h" @@ -34,9 +33,9 @@ subject to the following restrictions: //#include "btSolverBody.h" //#include "btSolverConstraint.h" #include "LinearMath/btAlignedObjectArray.h" -#include //for memset +#include //for memset -int gNumSplitImpulseRecoveries = 0; +int gNumSplitImpulseRecoveries = 0; #include "BulletDynamics/Dynamics/btRigidBody.h" @@ -45,13 +44,13 @@ int gNumSplitImpulseRecoveries = 0; ///Below are optional SSE2 and SSE4/FMA3 versions. We assume most hardware has SSE2. For SSE4/FMA3 we perform a CPU feature check. static btScalar gResolveSingleConstraintRowGeneric_scalar_reference(btSolverBody& bodyA, btSolverBody& bodyB, const btSolverConstraint& c) { - btScalar deltaImpulse = c.m_rhs - btScalar(c.m_appliedImpulse)*c.m_cfm; + btScalar deltaImpulse = c.m_rhs - btScalar(c.m_appliedImpulse) * c.m_cfm; const btScalar deltaVel1Dotn = c.m_contactNormal1.dot(bodyA.internalGetDeltaLinearVelocity()) + c.m_relpos1CrossNormal.dot(bodyA.internalGetDeltaAngularVelocity()); const btScalar deltaVel2Dotn = c.m_contactNormal2.dot(bodyB.internalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(bodyB.internalGetDeltaAngularVelocity()); // const btScalar delta_rel_vel = deltaVel1Dotn-deltaVel2Dotn; - deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv; - deltaImpulse -= deltaVel2Dotn*c.m_jacDiagABInv; + deltaImpulse -= deltaVel1Dotn * c.m_jacDiagABInv; + deltaImpulse -= deltaVel2Dotn * c.m_jacDiagABInv; const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse; if (sum < c.m_lowerLimit) @@ -69,21 +68,20 @@ static btScalar gResolveSingleConstraintRowGeneric_scalar_reference(btSolverBody c.m_appliedImpulse = sum; } - bodyA.internalApplyImpulse(c.m_contactNormal1*bodyA.internalGetInvMass(), c.m_angularComponentA, deltaImpulse); - bodyB.internalApplyImpulse(c.m_contactNormal2*bodyB.internalGetInvMass(), c.m_angularComponentB, deltaImpulse); + bodyA.internalApplyImpulse(c.m_contactNormal1 * bodyA.internalGetInvMass(), c.m_angularComponentA, deltaImpulse); + bodyB.internalApplyImpulse(c.m_contactNormal2 * bodyB.internalGetInvMass(), c.m_angularComponentB, deltaImpulse); - return deltaImpulse*(1./c.m_jacDiagABInv); + return deltaImpulse * (1. / c.m_jacDiagABInv); } - static btScalar gResolveSingleConstraintRowLowerLimit_scalar_reference(btSolverBody& bodyA, btSolverBody& bodyB, const btSolverConstraint& c) { - btScalar deltaImpulse = c.m_rhs - btScalar(c.m_appliedImpulse)*c.m_cfm; + btScalar deltaImpulse = c.m_rhs - btScalar(c.m_appliedImpulse) * c.m_cfm; const btScalar deltaVel1Dotn = c.m_contactNormal1.dot(bodyA.internalGetDeltaLinearVelocity()) + c.m_relpos1CrossNormal.dot(bodyA.internalGetDeltaAngularVelocity()); const btScalar deltaVel2Dotn = c.m_contactNormal2.dot(bodyB.internalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(bodyB.internalGetDeltaAngularVelocity()); - deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv; - deltaImpulse -= deltaVel2Dotn*c.m_jacDiagABInv; + deltaImpulse -= deltaVel1Dotn * c.m_jacDiagABInv; + deltaImpulse -= deltaVel2Dotn * c.m_jacDiagABInv; const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse; if (sum < c.m_lowerLimit) { @@ -94,58 +92,55 @@ static btScalar gResolveSingleConstraintRowLowerLimit_scalar_reference(btSolverB { c.m_appliedImpulse = sum; } - bodyA.internalApplyImpulse(c.m_contactNormal1*bodyA.internalGetInvMass(), c.m_angularComponentA, deltaImpulse); - bodyB.internalApplyImpulse(c.m_contactNormal2*bodyB.internalGetInvMass(), c.m_angularComponentB, deltaImpulse); + bodyA.internalApplyImpulse(c.m_contactNormal1 * bodyA.internalGetInvMass(), c.m_angularComponentA, deltaImpulse); + bodyB.internalApplyImpulse(c.m_contactNormal2 * bodyB.internalGetInvMass(), c.m_angularComponentB, deltaImpulse); - return deltaImpulse*(1./c.m_jacDiagABInv); + return deltaImpulse * (1. / c.m_jacDiagABInv); } - - #ifdef USE_SIMD #include - -#define btVecSplat(x, e) _mm_shuffle_ps(x, x, _MM_SHUFFLE(e,e,e,e)) -static inline __m128 btSimdDot3( __m128 vec0, __m128 vec1 ) +#define btVecSplat(x, e) _mm_shuffle_ps(x, x, _MM_SHUFFLE(e, e, e, e)) +static inline __m128 btSimdDot3(__m128 vec0, __m128 vec1) { - __m128 result = _mm_mul_ps( vec0, vec1); - return _mm_add_ps( btVecSplat( result, 0 ), _mm_add_ps( btVecSplat( result, 1 ), btVecSplat( result, 2 ) ) ); + __m128 result = _mm_mul_ps(vec0, vec1); + return _mm_add_ps(btVecSplat(result, 0), _mm_add_ps(btVecSplat(result, 1), btVecSplat(result, 2))); } -#if defined (BT_ALLOW_SSE4) +#if defined(BT_ALLOW_SSE4) #include -#define USE_FMA 1 -#define USE_FMA3_INSTEAD_FMA4 1 -#define USE_SSE4_DOT 1 +#define USE_FMA 1 +#define USE_FMA3_INSTEAD_FMA4 1 +#define USE_SSE4_DOT 1 -#define SSE4_DP(a, b) _mm_dp_ps(a, b, 0x7f) -#define SSE4_DP_FP(a, b) _mm_cvtss_f32(_mm_dp_ps(a, b, 0x7f)) +#define SSE4_DP(a, b) _mm_dp_ps(a, b, 0x7f) +#define SSE4_DP_FP(a, b) _mm_cvtss_f32(_mm_dp_ps(a, b, 0x7f)) #if USE_SSE4_DOT -#define DOT_PRODUCT(a, b) SSE4_DP(a, b) +#define DOT_PRODUCT(a, b) SSE4_DP(a, b) #else -#define DOT_PRODUCT(a, b) btSimdDot3(a, b) +#define DOT_PRODUCT(a, b) btSimdDot3(a, b) #endif #if USE_FMA #if USE_FMA3_INSTEAD_FMA4 // a*b + c -#define FMADD(a, b, c) _mm_fmadd_ps(a, b, c) +#define FMADD(a, b, c) _mm_fmadd_ps(a, b, c) // -(a*b) + c -#define FMNADD(a, b, c) _mm_fnmadd_ps(a, b, c) -#else // USE_FMA3 +#define FMNADD(a, b, c) _mm_fnmadd_ps(a, b, c) +#else // USE_FMA3 // a*b + c -#define FMADD(a, b, c) _mm_macc_ps(a, b, c) +#define FMADD(a, b, c) _mm_macc_ps(a, b, c) // -(a*b) + c -#define FMNADD(a, b, c) _mm_nmacc_ps(a, b, c) +#define FMNADD(a, b, c) _mm_nmacc_ps(a, b, c) #endif -#else // USE_FMA +#else // USE_FMA // c + a*b -#define FMADD(a, b, c) _mm_add_ps(c, _mm_mul_ps(a, b)) +#define FMADD(a, b, c) _mm_add_ps(c, _mm_mul_ps(a, b)) // c - a*b -#define FMNADD(a, b, c) _mm_sub_ps(c, _mm_mul_ps(a, b)) +#define FMNADD(a, b, c) _mm_sub_ps(c, _mm_mul_ps(a, b)) #endif #endif @@ -153,8 +148,8 @@ static inline __m128 btSimdDot3( __m128 vec0, __m128 vec1 ) static btScalar gResolveSingleConstraintRowGeneric_sse2(btSolverBody& bodyA, btSolverBody& bodyB, const btSolverConstraint& c) { __m128 cpAppliedImp = _mm_set1_ps(c.m_appliedImpulse); - __m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit); - __m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit); + __m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit); + __m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit); btSimdScalar deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhs), _mm_mul_ps(_mm_set1_ps(c.m_appliedImpulse), _mm_set1_ps(c.m_cfm))); __m128 deltaVel1Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal1.mVec128, bodyA.internalGetDeltaLinearVelocity().mVec128), btSimdDot3(c.m_relpos1CrossNormal.mVec128, bodyA.internalGetDeltaAngularVelocity().mVec128)); __m128 deltaVel2Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal2.mVec128, bodyB.internalGetDeltaLinearVelocity().mVec128), btSimdDot3(c.m_relpos2CrossNormal.mVec128, bodyB.internalGetDeltaAngularVelocity().mVec128)); @@ -170,52 +165,49 @@ static btScalar gResolveSingleConstraintRowGeneric_sse2(btSolverBody& bodyA, btS __m128 upperMinApplied = _mm_sub_ps(upperLimit1, cpAppliedImp); deltaImpulse = _mm_or_ps(_mm_and_ps(resultUpperLess, deltaImpulse), _mm_andnot_ps(resultUpperLess, upperMinApplied)); c.m_appliedImpulse = _mm_or_ps(_mm_and_ps(resultUpperLess, c.m_appliedImpulse), _mm_andnot_ps(resultUpperLess, upperLimit1)); - __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal1.mVec128, bodyA.internalGetInvMass().mVec128); - __m128 linearComponentB = _mm_mul_ps((c.m_contactNormal2).mVec128, bodyB.internalGetInvMass().mVec128); + __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal1.mVec128, bodyA.internalGetInvMass().mVec128); + __m128 linearComponentB = _mm_mul_ps((c.m_contactNormal2).mVec128, bodyB.internalGetInvMass().mVec128); __m128 impulseMagnitude = deltaImpulse; bodyA.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(bodyA.internalGetDeltaLinearVelocity().mVec128, _mm_mul_ps(linearComponentA, impulseMagnitude)); bodyA.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(bodyA.internalGetDeltaAngularVelocity().mVec128, _mm_mul_ps(c.m_angularComponentA.mVec128, impulseMagnitude)); bodyB.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(bodyB.internalGetDeltaLinearVelocity().mVec128, _mm_mul_ps(linearComponentB, impulseMagnitude)); bodyB.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(bodyB.internalGetDeltaAngularVelocity().mVec128, _mm_mul_ps(c.m_angularComponentB.mVec128, impulseMagnitude)); - return deltaImpulse.m_floats[0]/c.m_jacDiagABInv; + return deltaImpulse.m_floats[0] / c.m_jacDiagABInv; } - // Enhanced version of gResolveSingleConstraintRowGeneric_sse2 with SSE4.1 and FMA3 static btScalar gResolveSingleConstraintRowGeneric_sse4_1_fma3(btSolverBody& bodyA, btSolverBody& bodyB, const btSolverConstraint& c) { -#if defined (BT_ALLOW_SSE4) - __m128 tmp = _mm_set_ps1(c.m_jacDiagABInv); - __m128 deltaImpulse = _mm_set_ps1(c.m_rhs - btScalar(c.m_appliedImpulse)*c.m_cfm); - const __m128 lowerLimit = _mm_set_ps1(c.m_lowerLimit); - const __m128 upperLimit = _mm_set_ps1(c.m_upperLimit); - const __m128 deltaVel1Dotn = _mm_add_ps(DOT_PRODUCT(c.m_contactNormal1.mVec128, bodyA.internalGetDeltaLinearVelocity().mVec128), DOT_PRODUCT(c.m_relpos1CrossNormal.mVec128, bodyA.internalGetDeltaAngularVelocity().mVec128)); - const __m128 deltaVel2Dotn = _mm_add_ps(DOT_PRODUCT(c.m_contactNormal2.mVec128, bodyB.internalGetDeltaLinearVelocity().mVec128), DOT_PRODUCT(c.m_relpos2CrossNormal.mVec128, bodyB.internalGetDeltaAngularVelocity().mVec128)); - deltaImpulse = FMNADD(deltaVel1Dotn, tmp, deltaImpulse); - deltaImpulse = FMNADD(deltaVel2Dotn, tmp, deltaImpulse); - tmp = _mm_add_ps(c.m_appliedImpulse, deltaImpulse); // sum - const __m128 maskLower = _mm_cmpgt_ps(tmp, lowerLimit); - const __m128 maskUpper = _mm_cmpgt_ps(upperLimit, tmp); - deltaImpulse = _mm_blendv_ps(_mm_sub_ps(lowerLimit, c.m_appliedImpulse), _mm_blendv_ps(_mm_sub_ps(upperLimit, c.m_appliedImpulse), deltaImpulse, maskUpper), maskLower); - c.m_appliedImpulse = _mm_blendv_ps(lowerLimit, _mm_blendv_ps(upperLimit, tmp, maskUpper), maskLower); - bodyA.internalGetDeltaLinearVelocity().mVec128 = FMADD(_mm_mul_ps(c.m_contactNormal1.mVec128, bodyA.internalGetInvMass().mVec128), deltaImpulse, bodyA.internalGetDeltaLinearVelocity().mVec128); +#if defined(BT_ALLOW_SSE4) + __m128 tmp = _mm_set_ps1(c.m_jacDiagABInv); + __m128 deltaImpulse = _mm_set_ps1(c.m_rhs - btScalar(c.m_appliedImpulse) * c.m_cfm); + const __m128 lowerLimit = _mm_set_ps1(c.m_lowerLimit); + const __m128 upperLimit = _mm_set_ps1(c.m_upperLimit); + const __m128 deltaVel1Dotn = _mm_add_ps(DOT_PRODUCT(c.m_contactNormal1.mVec128, bodyA.internalGetDeltaLinearVelocity().mVec128), DOT_PRODUCT(c.m_relpos1CrossNormal.mVec128, bodyA.internalGetDeltaAngularVelocity().mVec128)); + const __m128 deltaVel2Dotn = _mm_add_ps(DOT_PRODUCT(c.m_contactNormal2.mVec128, bodyB.internalGetDeltaLinearVelocity().mVec128), DOT_PRODUCT(c.m_relpos2CrossNormal.mVec128, bodyB.internalGetDeltaAngularVelocity().mVec128)); + deltaImpulse = FMNADD(deltaVel1Dotn, tmp, deltaImpulse); + deltaImpulse = FMNADD(deltaVel2Dotn, tmp, deltaImpulse); + tmp = _mm_add_ps(c.m_appliedImpulse, deltaImpulse); // sum + const __m128 maskLower = _mm_cmpgt_ps(tmp, lowerLimit); + const __m128 maskUpper = _mm_cmpgt_ps(upperLimit, tmp); + deltaImpulse = _mm_blendv_ps(_mm_sub_ps(lowerLimit, c.m_appliedImpulse), _mm_blendv_ps(_mm_sub_ps(upperLimit, c.m_appliedImpulse), deltaImpulse, maskUpper), maskLower); + c.m_appliedImpulse = _mm_blendv_ps(lowerLimit, _mm_blendv_ps(upperLimit, tmp, maskUpper), maskLower); + bodyA.internalGetDeltaLinearVelocity().mVec128 = FMADD(_mm_mul_ps(c.m_contactNormal1.mVec128, bodyA.internalGetInvMass().mVec128), deltaImpulse, bodyA.internalGetDeltaLinearVelocity().mVec128); bodyA.internalGetDeltaAngularVelocity().mVec128 = FMADD(c.m_angularComponentA.mVec128, deltaImpulse, bodyA.internalGetDeltaAngularVelocity().mVec128); - bodyB.internalGetDeltaLinearVelocity().mVec128 = FMADD(_mm_mul_ps(c.m_contactNormal2.mVec128, bodyB.internalGetInvMass().mVec128), deltaImpulse, bodyB.internalGetDeltaLinearVelocity().mVec128); + bodyB.internalGetDeltaLinearVelocity().mVec128 = FMADD(_mm_mul_ps(c.m_contactNormal2.mVec128, bodyB.internalGetInvMass().mVec128), deltaImpulse, bodyB.internalGetDeltaLinearVelocity().mVec128); bodyB.internalGetDeltaAngularVelocity().mVec128 = FMADD(c.m_angularComponentB.mVec128, deltaImpulse, bodyB.internalGetDeltaAngularVelocity().mVec128); btSimdScalar deltaImp = deltaImpulse; - return deltaImp.m_floats[0]*(1./c.m_jacDiagABInv); + return deltaImp.m_floats[0] * (1. / c.m_jacDiagABInv); #else - return gResolveSingleConstraintRowGeneric_sse2(bodyA,bodyB,c); + return gResolveSingleConstraintRowGeneric_sse2(bodyA, bodyB, c); #endif } - - static btScalar gResolveSingleConstraintRowLowerLimit_sse2(btSolverBody& bodyA, btSolverBody& bodyB, const btSolverConstraint& c) { __m128 cpAppliedImp = _mm_set1_ps(c.m_appliedImpulse); - __m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit); - __m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit); + __m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit); + __m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit); btSimdScalar deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhs), _mm_mul_ps(_mm_set1_ps(c.m_appliedImpulse), _mm_set1_ps(c.m_cfm))); __m128 deltaVel1Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal1.mVec128, bodyA.internalGetDeltaLinearVelocity().mVec128), btSimdDot3(c.m_relpos1CrossNormal.mVec128, bodyA.internalGetDeltaAngularVelocity().mVec128)); __m128 deltaVel2Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal2.mVec128, bodyB.internalGetDeltaLinearVelocity().mVec128), btSimdDot3(c.m_relpos2CrossNormal.mVec128, bodyB.internalGetDeltaAngularVelocity().mVec128)); @@ -228,104 +220,98 @@ static btScalar gResolveSingleConstraintRowLowerLimit_sse2(btSolverBody& bodyA, __m128 lowMinApplied = _mm_sub_ps(lowerLimit1, cpAppliedImp); deltaImpulse = _mm_or_ps(_mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse)); c.m_appliedImpulse = _mm_or_ps(_mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum)); - __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal1.mVec128, bodyA.internalGetInvMass().mVec128); - __m128 linearComponentB = _mm_mul_ps(c.m_contactNormal2.mVec128, bodyB.internalGetInvMass().mVec128); + __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal1.mVec128, bodyA.internalGetInvMass().mVec128); + __m128 linearComponentB = _mm_mul_ps(c.m_contactNormal2.mVec128, bodyB.internalGetInvMass().mVec128); __m128 impulseMagnitude = deltaImpulse; bodyA.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(bodyA.internalGetDeltaLinearVelocity().mVec128, _mm_mul_ps(linearComponentA, impulseMagnitude)); bodyA.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(bodyA.internalGetDeltaAngularVelocity().mVec128, _mm_mul_ps(c.m_angularComponentA.mVec128, impulseMagnitude)); bodyB.internalGetDeltaLinearVelocity().mVec128 = _mm_add_ps(bodyB.internalGetDeltaLinearVelocity().mVec128, _mm_mul_ps(linearComponentB, impulseMagnitude)); bodyB.internalGetDeltaAngularVelocity().mVec128 = _mm_add_ps(bodyB.internalGetDeltaAngularVelocity().mVec128, _mm_mul_ps(c.m_angularComponentB.mVec128, impulseMagnitude)); - return deltaImpulse.m_floats[0]/c.m_jacDiagABInv; + return deltaImpulse.m_floats[0] / c.m_jacDiagABInv; } - // Enhanced version of gResolveSingleConstraintRowGeneric_sse2 with SSE4.1 and FMA3 static btScalar gResolveSingleConstraintRowLowerLimit_sse4_1_fma3(btSolverBody& bodyA, btSolverBody& bodyB, const btSolverConstraint& c) { #ifdef BT_ALLOW_SSE4 - __m128 tmp = _mm_set_ps1(c.m_jacDiagABInv); - __m128 deltaImpulse = _mm_set_ps1(c.m_rhs - btScalar(c.m_appliedImpulse)*c.m_cfm); - const __m128 lowerLimit = _mm_set_ps1(c.m_lowerLimit); - const __m128 deltaVel1Dotn = _mm_add_ps(DOT_PRODUCT(c.m_contactNormal1.mVec128, bodyA.internalGetDeltaLinearVelocity().mVec128), DOT_PRODUCT(c.m_relpos1CrossNormal.mVec128, bodyA.internalGetDeltaAngularVelocity().mVec128)); - const __m128 deltaVel2Dotn = _mm_add_ps(DOT_PRODUCT(c.m_contactNormal2.mVec128, bodyB.internalGetDeltaLinearVelocity().mVec128), DOT_PRODUCT(c.m_relpos2CrossNormal.mVec128, bodyB.internalGetDeltaAngularVelocity().mVec128)); - deltaImpulse = FMNADD(deltaVel1Dotn, tmp, deltaImpulse); - deltaImpulse = FMNADD(deltaVel2Dotn, tmp, deltaImpulse); - tmp = _mm_add_ps(c.m_appliedImpulse, deltaImpulse); - const __m128 mask = _mm_cmpgt_ps(tmp, lowerLimit); - deltaImpulse = _mm_blendv_ps(_mm_sub_ps(lowerLimit, c.m_appliedImpulse), deltaImpulse, mask); - c.m_appliedImpulse = _mm_blendv_ps(lowerLimit, tmp, mask); - bodyA.internalGetDeltaLinearVelocity().mVec128 = FMADD(_mm_mul_ps(c.m_contactNormal1.mVec128, bodyA.internalGetInvMass().mVec128), deltaImpulse, bodyA.internalGetDeltaLinearVelocity().mVec128); + __m128 tmp = _mm_set_ps1(c.m_jacDiagABInv); + __m128 deltaImpulse = _mm_set_ps1(c.m_rhs - btScalar(c.m_appliedImpulse) * c.m_cfm); + const __m128 lowerLimit = _mm_set_ps1(c.m_lowerLimit); + const __m128 deltaVel1Dotn = _mm_add_ps(DOT_PRODUCT(c.m_contactNormal1.mVec128, bodyA.internalGetDeltaLinearVelocity().mVec128), DOT_PRODUCT(c.m_relpos1CrossNormal.mVec128, bodyA.internalGetDeltaAngularVelocity().mVec128)); + const __m128 deltaVel2Dotn = _mm_add_ps(DOT_PRODUCT(c.m_contactNormal2.mVec128, bodyB.internalGetDeltaLinearVelocity().mVec128), DOT_PRODUCT(c.m_relpos2CrossNormal.mVec128, bodyB.internalGetDeltaAngularVelocity().mVec128)); + deltaImpulse = FMNADD(deltaVel1Dotn, tmp, deltaImpulse); + deltaImpulse = FMNADD(deltaVel2Dotn, tmp, deltaImpulse); + tmp = _mm_add_ps(c.m_appliedImpulse, deltaImpulse); + const __m128 mask = _mm_cmpgt_ps(tmp, lowerLimit); + deltaImpulse = _mm_blendv_ps(_mm_sub_ps(lowerLimit, c.m_appliedImpulse), deltaImpulse, mask); + c.m_appliedImpulse = _mm_blendv_ps(lowerLimit, tmp, mask); + bodyA.internalGetDeltaLinearVelocity().mVec128 = FMADD(_mm_mul_ps(c.m_contactNormal1.mVec128, bodyA.internalGetInvMass().mVec128), deltaImpulse, bodyA.internalGetDeltaLinearVelocity().mVec128); bodyA.internalGetDeltaAngularVelocity().mVec128 = FMADD(c.m_angularComponentA.mVec128, deltaImpulse, bodyA.internalGetDeltaAngularVelocity().mVec128); - bodyB.internalGetDeltaLinearVelocity().mVec128 = FMADD(_mm_mul_ps(c.m_contactNormal2.mVec128, bodyB.internalGetInvMass().mVec128), deltaImpulse, bodyB.internalGetDeltaLinearVelocity().mVec128); + bodyB.internalGetDeltaLinearVelocity().mVec128 = FMADD(_mm_mul_ps(c.m_contactNormal2.mVec128, bodyB.internalGetInvMass().mVec128), deltaImpulse, bodyB.internalGetDeltaLinearVelocity().mVec128); bodyB.internalGetDeltaAngularVelocity().mVec128 = FMADD(c.m_angularComponentB.mVec128, deltaImpulse, bodyB.internalGetDeltaAngularVelocity().mVec128); btSimdScalar deltaImp = deltaImpulse; - return deltaImp.m_floats[0]*(1./c.m_jacDiagABInv); + return deltaImp.m_floats[0] * (1. / c.m_jacDiagABInv); #else - return gResolveSingleConstraintRowLowerLimit_sse2(bodyA,bodyB,c); -#endif //BT_ALLOW_SSE4 + return gResolveSingleConstraintRowLowerLimit_sse2(bodyA, bodyB, c); +#endif //BT_ALLOW_SSE4 } +#endif //USE_SIMD -#endif //USE_SIMD - - - -btScalar btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGenericSIMD(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& c) +btScalar btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGenericSIMD(btSolverBody& bodyA, btSolverBody& bodyB, const btSolverConstraint& c) { return m_resolveSingleConstraintRowGeneric(bodyA, bodyB, c); } // Project Gauss Seidel or the equivalent Sequential Impulse -btScalar btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGeneric(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& c) +btScalar btSequentialImpulseConstraintSolver::resolveSingleConstraintRowGeneric(btSolverBody& bodyA, btSolverBody& bodyB, const btSolverConstraint& c) { return m_resolveSingleConstraintRowGeneric(bodyA, bodyB, c); } -btScalar btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimitSIMD(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& c) +btScalar btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimitSIMD(btSolverBody& bodyA, btSolverBody& bodyB, const btSolverConstraint& c) { return m_resolveSingleConstraintRowLowerLimit(bodyA, bodyB, c); } - -btScalar btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimit(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& c) +btScalar btSequentialImpulseConstraintSolver::resolveSingleConstraintRowLowerLimit(btSolverBody& bodyA, btSolverBody& bodyB, const btSolverConstraint& c) { return m_resolveSingleConstraintRowLowerLimit(bodyA, bodyB, c); } - static btScalar gResolveSplitPenetrationImpulse_scalar_reference( - btSolverBody& bodyA, - btSolverBody& bodyB, - const btSolverConstraint& c) + btSolverBody& bodyA, + btSolverBody& bodyB, + const btSolverConstraint& c) { btScalar deltaImpulse = 0.f; - if (c.m_rhsPenetration) - { - gNumSplitImpulseRecoveries++; - deltaImpulse = c.m_rhsPenetration-btScalar(c.m_appliedPushImpulse)*c.m_cfm; - const btScalar deltaVel1Dotn = c.m_contactNormal1.dot(bodyA.internalGetPushVelocity()) + c.m_relpos1CrossNormal.dot(bodyA.internalGetTurnVelocity()); - const btScalar deltaVel2Dotn = c.m_contactNormal2.dot(bodyB.internalGetPushVelocity()) + c.m_relpos2CrossNormal.dot(bodyB.internalGetTurnVelocity()); + if (c.m_rhsPenetration) + { + gNumSplitImpulseRecoveries++; + deltaImpulse = c.m_rhsPenetration - btScalar(c.m_appliedPushImpulse) * c.m_cfm; + const btScalar deltaVel1Dotn = c.m_contactNormal1.dot(bodyA.internalGetPushVelocity()) + c.m_relpos1CrossNormal.dot(bodyA.internalGetTurnVelocity()); + const btScalar deltaVel2Dotn = c.m_contactNormal2.dot(bodyB.internalGetPushVelocity()) + c.m_relpos2CrossNormal.dot(bodyB.internalGetTurnVelocity()); - deltaImpulse -= deltaVel1Dotn*c.m_jacDiagABInv; - deltaImpulse -= deltaVel2Dotn*c.m_jacDiagABInv; - const btScalar sum = btScalar(c.m_appliedPushImpulse) + deltaImpulse; - if (sum < c.m_lowerLimit) - { - deltaImpulse = c.m_lowerLimit-c.m_appliedPushImpulse; - c.m_appliedPushImpulse = c.m_lowerLimit; - } - else - { - c.m_appliedPushImpulse = sum; - } - bodyA.internalApplyPushImpulse(c.m_contactNormal1*bodyA.internalGetInvMass(),c.m_angularComponentA,deltaImpulse); - bodyB.internalApplyPushImpulse(c.m_contactNormal2*bodyB.internalGetInvMass(),c.m_angularComponentB,deltaImpulse); - } - return deltaImpulse*(1./c.m_jacDiagABInv); + deltaImpulse -= deltaVel1Dotn * c.m_jacDiagABInv; + deltaImpulse -= deltaVel2Dotn * c.m_jacDiagABInv; + const btScalar sum = btScalar(c.m_appliedPushImpulse) + deltaImpulse; + if (sum < c.m_lowerLimit) + { + deltaImpulse = c.m_lowerLimit - c.m_appliedPushImpulse; + c.m_appliedPushImpulse = c.m_lowerLimit; + } + else + { + c.m_appliedPushImpulse = sum; + } + bodyA.internalApplyPushImpulse(c.m_contactNormal1 * bodyA.internalGetInvMass(), c.m_angularComponentA, deltaImpulse); + bodyB.internalApplyPushImpulse(c.m_contactNormal2 * bodyB.internalGetInvMass(), c.m_angularComponentB, deltaImpulse); + } + return deltaImpulse * (1. / c.m_jacDiagABInv); } -static btScalar gResolveSplitPenetrationImpulse_sse2(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& c) +static btScalar gResolveSplitPenetrationImpulse_sse2(btSolverBody& bodyA, btSolverBody& bodyB, const btSolverConstraint& c) { #ifdef USE_SIMD if (!c.m_rhsPenetration) @@ -334,113 +320,109 @@ static btScalar gResolveSplitPenetrationImpulse_sse2(btSolverBody& bodyA,btSolve gNumSplitImpulseRecoveries++; __m128 cpAppliedImp = _mm_set1_ps(c.m_appliedPushImpulse); - __m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit); - __m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit); - __m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhsPenetration), _mm_mul_ps(_mm_set1_ps(c.m_appliedPushImpulse),_mm_set1_ps(c.m_cfm))); - __m128 deltaVel1Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal1.mVec128,bodyA.internalGetPushVelocity().mVec128), btSimdDot3(c.m_relpos1CrossNormal.mVec128,bodyA.internalGetTurnVelocity().mVec128)); - __m128 deltaVel2Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal2.mVec128,bodyB.internalGetPushVelocity().mVec128), btSimdDot3(c.m_relpos2CrossNormal.mVec128,bodyB.internalGetTurnVelocity().mVec128)); - deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel1Dotn,_mm_set1_ps(c.m_jacDiagABInv))); - deltaImpulse = _mm_sub_ps(deltaImpulse,_mm_mul_ps(deltaVel2Dotn,_mm_set1_ps(c.m_jacDiagABInv))); - btSimdScalar sum = _mm_add_ps(cpAppliedImp,deltaImpulse); - btSimdScalar resultLowerLess,resultUpperLess; - resultLowerLess = _mm_cmplt_ps(sum,lowerLimit1); - resultUpperLess = _mm_cmplt_ps(sum,upperLimit1); - __m128 lowMinApplied = _mm_sub_ps(lowerLimit1,cpAppliedImp); - deltaImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse) ); - c.m_appliedPushImpulse = _mm_or_ps( _mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum) ); - __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal1.mVec128,bodyA.internalGetInvMass().mVec128); - __m128 linearComponentB = _mm_mul_ps(c.m_contactNormal2.mVec128,bodyB.internalGetInvMass().mVec128); + __m128 lowerLimit1 = _mm_set1_ps(c.m_lowerLimit); + __m128 upperLimit1 = _mm_set1_ps(c.m_upperLimit); + __m128 deltaImpulse = _mm_sub_ps(_mm_set1_ps(c.m_rhsPenetration), _mm_mul_ps(_mm_set1_ps(c.m_appliedPushImpulse), _mm_set1_ps(c.m_cfm))); + __m128 deltaVel1Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal1.mVec128, bodyA.internalGetPushVelocity().mVec128), btSimdDot3(c.m_relpos1CrossNormal.mVec128, bodyA.internalGetTurnVelocity().mVec128)); + __m128 deltaVel2Dotn = _mm_add_ps(btSimdDot3(c.m_contactNormal2.mVec128, bodyB.internalGetPushVelocity().mVec128), btSimdDot3(c.m_relpos2CrossNormal.mVec128, bodyB.internalGetTurnVelocity().mVec128)); + deltaImpulse = _mm_sub_ps(deltaImpulse, _mm_mul_ps(deltaVel1Dotn, _mm_set1_ps(c.m_jacDiagABInv))); + deltaImpulse = _mm_sub_ps(deltaImpulse, _mm_mul_ps(deltaVel2Dotn, _mm_set1_ps(c.m_jacDiagABInv))); + btSimdScalar sum = _mm_add_ps(cpAppliedImp, deltaImpulse); + btSimdScalar resultLowerLess, resultUpperLess; + resultLowerLess = _mm_cmplt_ps(sum, lowerLimit1); + resultUpperLess = _mm_cmplt_ps(sum, upperLimit1); + __m128 lowMinApplied = _mm_sub_ps(lowerLimit1, cpAppliedImp); + deltaImpulse = _mm_or_ps(_mm_and_ps(resultLowerLess, lowMinApplied), _mm_andnot_ps(resultLowerLess, deltaImpulse)); + c.m_appliedPushImpulse = _mm_or_ps(_mm_and_ps(resultLowerLess, lowerLimit1), _mm_andnot_ps(resultLowerLess, sum)); + __m128 linearComponentA = _mm_mul_ps(c.m_contactNormal1.mVec128, bodyA.internalGetInvMass().mVec128); + __m128 linearComponentB = _mm_mul_ps(c.m_contactNormal2.mVec128, bodyB.internalGetInvMass().mVec128); __m128 impulseMagnitude = deltaImpulse; - bodyA.internalGetPushVelocity().mVec128 = _mm_add_ps(bodyA.internalGetPushVelocity().mVec128,_mm_mul_ps(linearComponentA,impulseMagnitude)); - bodyA.internalGetTurnVelocity().mVec128 = _mm_add_ps(bodyA.internalGetTurnVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentA.mVec128,impulseMagnitude)); - bodyB.internalGetPushVelocity().mVec128 = _mm_add_ps(bodyB.internalGetPushVelocity().mVec128,_mm_mul_ps(linearComponentB,impulseMagnitude)); - bodyB.internalGetTurnVelocity().mVec128 = _mm_add_ps(bodyB.internalGetTurnVelocity().mVec128 ,_mm_mul_ps(c.m_angularComponentB.mVec128,impulseMagnitude)); + bodyA.internalGetPushVelocity().mVec128 = _mm_add_ps(bodyA.internalGetPushVelocity().mVec128, _mm_mul_ps(linearComponentA, impulseMagnitude)); + bodyA.internalGetTurnVelocity().mVec128 = _mm_add_ps(bodyA.internalGetTurnVelocity().mVec128, _mm_mul_ps(c.m_angularComponentA.mVec128, impulseMagnitude)); + bodyB.internalGetPushVelocity().mVec128 = _mm_add_ps(bodyB.internalGetPushVelocity().mVec128, _mm_mul_ps(linearComponentB, impulseMagnitude)); + bodyB.internalGetTurnVelocity().mVec128 = _mm_add_ps(bodyB.internalGetTurnVelocity().mVec128, _mm_mul_ps(c.m_angularComponentB.mVec128, impulseMagnitude)); btSimdScalar deltaImp = deltaImpulse; return deltaImp.m_floats[0] * (1. / c.m_jacDiagABInv); #else - return gResolveSplitPenetrationImpulse_scalar_reference(bodyA,bodyB,c); + return gResolveSplitPenetrationImpulse_scalar_reference(bodyA, bodyB, c); #endif } - btSequentialImpulseConstraintSolver::btSequentialImpulseConstraintSolver() { - m_btSeed2 = 0; - m_cachedSolverMode = 0; - setupSolverFunctions( false ); + m_btSeed2 = 0; + m_cachedSolverMode = 0; + setupSolverFunctions(false); } -void btSequentialImpulseConstraintSolver::setupSolverFunctions( bool useSimd ) +void btSequentialImpulseConstraintSolver::setupSolverFunctions(bool useSimd) { - m_resolveSingleConstraintRowGeneric = gResolveSingleConstraintRowGeneric_scalar_reference; - m_resolveSingleConstraintRowLowerLimit = gResolveSingleConstraintRowLowerLimit_scalar_reference; - m_resolveSplitPenetrationImpulse = gResolveSplitPenetrationImpulse_scalar_reference; + m_resolveSingleConstraintRowGeneric = gResolveSingleConstraintRowGeneric_scalar_reference; + m_resolveSingleConstraintRowLowerLimit = gResolveSingleConstraintRowLowerLimit_scalar_reference; + m_resolveSplitPenetrationImpulse = gResolveSplitPenetrationImpulse_scalar_reference; - if ( useSimd ) - { + if (useSimd) + { #ifdef USE_SIMD - m_resolveSingleConstraintRowGeneric = gResolveSingleConstraintRowGeneric_sse2; - m_resolveSingleConstraintRowLowerLimit = gResolveSingleConstraintRowLowerLimit_sse2; - m_resolveSplitPenetrationImpulse = gResolveSplitPenetrationImpulse_sse2; + m_resolveSingleConstraintRowGeneric = gResolveSingleConstraintRowGeneric_sse2; + m_resolveSingleConstraintRowLowerLimit = gResolveSingleConstraintRowLowerLimit_sse2; + m_resolveSplitPenetrationImpulse = gResolveSplitPenetrationImpulse_sse2; #ifdef BT_ALLOW_SSE4 - int cpuFeatures = btCpuFeatureUtility::getCpuFeatures(); - if ((cpuFeatures & btCpuFeatureUtility::CPU_FEATURE_FMA3) && (cpuFeatures & btCpuFeatureUtility::CPU_FEATURE_SSE4_1)) - { - m_resolveSingleConstraintRowGeneric = gResolveSingleConstraintRowGeneric_sse4_1_fma3; - m_resolveSingleConstraintRowLowerLimit = gResolveSingleConstraintRowLowerLimit_sse4_1_fma3; - } -#endif//BT_ALLOW_SSE4 -#endif //USE_SIMD - } + int cpuFeatures = btCpuFeatureUtility::getCpuFeatures(); + if ((cpuFeatures & btCpuFeatureUtility::CPU_FEATURE_FMA3) && (cpuFeatures & btCpuFeatureUtility::CPU_FEATURE_SSE4_1)) + { + m_resolveSingleConstraintRowGeneric = gResolveSingleConstraintRowGeneric_sse4_1_fma3; + m_resolveSingleConstraintRowLowerLimit = gResolveSingleConstraintRowLowerLimit_sse4_1_fma3; + } +#endif //BT_ALLOW_SSE4 +#endif //USE_SIMD + } } - btSequentialImpulseConstraintSolver::~btSequentialImpulseConstraintSolver() - { - } +btSequentialImpulseConstraintSolver::~btSequentialImpulseConstraintSolver() +{ +} - btSingleConstraintRowSolver btSequentialImpulseConstraintSolver::getScalarConstraintRowSolverGeneric() - { - return gResolveSingleConstraintRowGeneric_scalar_reference; - } - - btSingleConstraintRowSolver btSequentialImpulseConstraintSolver::getScalarConstraintRowSolverLowerLimit() - { - return gResolveSingleConstraintRowLowerLimit_scalar_reference; - } +btSingleConstraintRowSolver btSequentialImpulseConstraintSolver::getScalarConstraintRowSolverGeneric() +{ + return gResolveSingleConstraintRowGeneric_scalar_reference; +} +btSingleConstraintRowSolver btSequentialImpulseConstraintSolver::getScalarConstraintRowSolverLowerLimit() +{ + return gResolveSingleConstraintRowLowerLimit_scalar_reference; +} #ifdef USE_SIMD - btSingleConstraintRowSolver btSequentialImpulseConstraintSolver::getSSE2ConstraintRowSolverGeneric() - { - return gResolveSingleConstraintRowGeneric_sse2; - } - btSingleConstraintRowSolver btSequentialImpulseConstraintSolver::getSSE2ConstraintRowSolverLowerLimit() - { - return gResolveSingleConstraintRowLowerLimit_sse2; - } +btSingleConstraintRowSolver btSequentialImpulseConstraintSolver::getSSE2ConstraintRowSolverGeneric() +{ + return gResolveSingleConstraintRowGeneric_sse2; +} +btSingleConstraintRowSolver btSequentialImpulseConstraintSolver::getSSE2ConstraintRowSolverLowerLimit() +{ + return gResolveSingleConstraintRowLowerLimit_sse2; +} #ifdef BT_ALLOW_SSE4 - btSingleConstraintRowSolver btSequentialImpulseConstraintSolver::getSSE4_1ConstraintRowSolverGeneric() - { - return gResolveSingleConstraintRowGeneric_sse4_1_fma3; - } - btSingleConstraintRowSolver btSequentialImpulseConstraintSolver::getSSE4_1ConstraintRowSolverLowerLimit() - { - return gResolveSingleConstraintRowLowerLimit_sse4_1_fma3; - } -#endif //BT_ALLOW_SSE4 -#endif //USE_SIMD +btSingleConstraintRowSolver btSequentialImpulseConstraintSolver::getSSE4_1ConstraintRowSolverGeneric() +{ + return gResolveSingleConstraintRowGeneric_sse4_1_fma3; +} +btSingleConstraintRowSolver btSequentialImpulseConstraintSolver::getSSE4_1ConstraintRowSolverLowerLimit() +{ + return gResolveSingleConstraintRowLowerLimit_sse4_1_fma3; +} +#endif //BT_ALLOW_SSE4 +#endif //USE_SIMD unsigned long btSequentialImpulseConstraintSolver::btRand2() { - m_btSeed2 = (1664525L*m_btSeed2 + 1013904223L) & 0xffffffff; + m_btSeed2 = (1664525L * m_btSeed2 + 1013904223L) & 0xffffffff; return m_btSeed2; } - - //See ODE: adam's all-int straightforward(?) dRandInt (0..n-1) -int btSequentialImpulseConstraintSolver::btRandInt2 (int n) +int btSequentialImpulseConstraintSolver::btRandInt2(int n) { // seems good; xor-fold and modulus const unsigned long un = static_cast(n); @@ -448,15 +430,20 @@ int btSequentialImpulseConstraintSolver::btRandInt2 (int n) // note: probably more aggressive than it needs to be -- might be // able to get away without one or two of the innermost branches. - if (un <= 0x00010000UL) { + if (un <= 0x00010000UL) + { r ^= (r >> 16); - if (un <= 0x00000100UL) { + if (un <= 0x00000100UL) + { r ^= (r >> 8); - if (un <= 0x00000010UL) { + if (un <= 0x00000010UL) + { r ^= (r >> 4); - if (un <= 0x00000004UL) { + if (un <= 0x00000004UL) + { r ^= (r >> 2); - if (un <= 0x00000002UL) { + if (un <= 0x00000002UL) + { r ^= (r >> 1); } } @@ -464,70 +451,56 @@ int btSequentialImpulseConstraintSolver::btRandInt2 (int n) } } - return (int) (r % un); + return (int)(r % un); } - - -void btSequentialImpulseConstraintSolver::initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject, btScalar timeStep) +void btSequentialImpulseConstraintSolver::initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject, btScalar timeStep) { + btRigidBody* rb = collisionObject ? btRigidBody::upcast(collisionObject) : 0; - btRigidBody* rb = collisionObject? btRigidBody::upcast(collisionObject) : 0; - - solverBody->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f); - solverBody->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f); - solverBody->internalGetPushVelocity().setValue(0.f,0.f,0.f); - solverBody->internalGetTurnVelocity().setValue(0.f,0.f,0.f); + solverBody->internalGetDeltaLinearVelocity().setValue(0.f, 0.f, 0.f); + solverBody->internalGetDeltaAngularVelocity().setValue(0.f, 0.f, 0.f); + solverBody->internalGetPushVelocity().setValue(0.f, 0.f, 0.f); + solverBody->internalGetTurnVelocity().setValue(0.f, 0.f, 0.f); if (rb) { solverBody->m_worldTransform = rb->getWorldTransform(); - solverBody->internalSetInvMass(btVector3(rb->getInvMass(),rb->getInvMass(),rb->getInvMass())*rb->getLinearFactor()); + solverBody->internalSetInvMass(btVector3(rb->getInvMass(), rb->getInvMass(), rb->getInvMass()) * rb->getLinearFactor()); solverBody->m_originalBody = rb; solverBody->m_angularFactor = rb->getAngularFactor(); solverBody->m_linearFactor = rb->getLinearFactor(); solverBody->m_linearVelocity = rb->getLinearVelocity(); solverBody->m_angularVelocity = rb->getAngularVelocity(); - solverBody->m_externalForceImpulse = rb->getTotalForce()*rb->getInvMass()*timeStep; - solverBody->m_externalTorqueImpulse = rb->getTotalTorque()*rb->getInvInertiaTensorWorld()*timeStep ; - - } else + solverBody->m_externalForceImpulse = rb->getTotalForce() * rb->getInvMass() * timeStep; + solverBody->m_externalTorqueImpulse = rb->getTotalTorque() * rb->getInvInertiaTensorWorld() * timeStep; + } + else { solverBody->m_worldTransform.setIdentity(); - solverBody->internalSetInvMass(btVector3(0,0,0)); + solverBody->internalSetInvMass(btVector3(0, 0, 0)); solverBody->m_originalBody = 0; - solverBody->m_angularFactor.setValue(1,1,1); - solverBody->m_linearFactor.setValue(1,1,1); - solverBody->m_linearVelocity.setValue(0,0,0); - solverBody->m_angularVelocity.setValue(0,0,0); - solverBody->m_externalForceImpulse.setValue(0,0,0); - solverBody->m_externalTorqueImpulse.setValue(0,0,0); + solverBody->m_angularFactor.setValue(1, 1, 1); + solverBody->m_linearFactor.setValue(1, 1, 1); + solverBody->m_linearVelocity.setValue(0, 0, 0); + solverBody->m_angularVelocity.setValue(0, 0, 0); + solverBody->m_externalForceImpulse.setValue(0, 0, 0); + solverBody->m_externalTorqueImpulse.setValue(0, 0, 0); } - - } - - - - - btScalar btSequentialImpulseConstraintSolver::restitutionCurve(btScalar rel_vel, btScalar restitution, btScalar velocityThreshold) { //printf("rel_vel =%f\n", rel_vel); - if (btFabs(rel_vel)hasAnisotropicFriction(frictionMode)) { // transform to local coordinates @@ -538,16 +511,10 @@ void btSequentialImpulseConstraintSolver::applyAnisotropicFriction(btCollisionOb // ... and transform it back to global coordinates frictionDirection = colObj->getWorldTransform().getBasis() * loc_lateral; } - } - - - -void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstraint& solverConstraint, const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity, btScalar cfmSlip) +void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstraint& solverConstraint, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity, btScalar cfmSlip) { - - btSolverBody& solverBodyA = m_tmpSolverBodyPool[solverBodyIdA]; btSolverBody& solverBodyB = m_tmpSolverBodyPool[solverBodyIdB]; @@ -568,12 +535,13 @@ void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstr solverConstraint.m_contactNormal1 = normalAxis; btVector3 ftorqueAxis1 = rel_pos1.cross(solverConstraint.m_contactNormal1); solverConstraint.m_relpos1CrossNormal = ftorqueAxis1; - solverConstraint.m_angularComponentA = body0->getInvInertiaTensorWorld()*ftorqueAxis1*body0->getAngularFactor(); - }else + solverConstraint.m_angularComponentA = body0->getInvInertiaTensorWorld() * ftorqueAxis1 * body0->getAngularFactor(); + } + else { solverConstraint.m_contactNormal1.setZero(); solverConstraint.m_relpos1CrossNormal.setZero(); - solverConstraint.m_angularComponentA .setZero(); + solverConstraint.m_angularComponentA.setZero(); } if (bodyA) @@ -581,8 +549,9 @@ void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstr solverConstraint.m_contactNormal2 = -normalAxis; btVector3 ftorqueAxis1 = rel_pos2.cross(solverConstraint.m_contactNormal2); solverConstraint.m_relpos2CrossNormal = ftorqueAxis1; - solverConstraint.m_angularComponentB = bodyA->getInvInertiaTensorWorld()*ftorqueAxis1*bodyA->getAngularFactor(); - } else + solverConstraint.m_angularComponentB = bodyA->getInvInertiaTensorWorld() * ftorqueAxis1 * bodyA->getAngularFactor(); + } + else { solverConstraint.m_contactNormal2.setZero(); solverConstraint.m_relpos2CrossNormal.setZero(); @@ -595,32 +564,28 @@ void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstr btScalar denom1 = 0.f; if (body0) { - vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1); + vec = (solverConstraint.m_angularComponentA).cross(rel_pos1); denom0 = body0->getInvMass() + normalAxis.dot(vec); } if (bodyA) { - vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2); + vec = (-solverConstraint.m_angularComponentB).cross(rel_pos2); denom1 = bodyA->getInvMass() + normalAxis.dot(vec); } - btScalar denom = relaxation/(denom0+denom1); + btScalar denom = relaxation / (denom0 + denom1); solverConstraint.m_jacDiagABInv = denom; } { - - btScalar rel_vel; - btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(body0?solverBodyA.m_linearVelocity+solverBodyA.m_externalForceImpulse:btVector3(0,0,0)) - + solverConstraint.m_relpos1CrossNormal.dot(body0?solverBodyA.m_angularVelocity:btVector3(0,0,0)); - btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(bodyA?solverBodyB.m_linearVelocity+solverBodyB.m_externalForceImpulse:btVector3(0,0,0)) - + solverConstraint.m_relpos2CrossNormal.dot(bodyA?solverBodyB.m_angularVelocity:btVector3(0,0,0)); + btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(body0 ? solverBodyA.m_linearVelocity + solverBodyA.m_externalForceImpulse : btVector3(0, 0, 0)) + solverConstraint.m_relpos1CrossNormal.dot(body0 ? solverBodyA.m_angularVelocity : btVector3(0, 0, 0)); + btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(bodyA ? solverBodyB.m_linearVelocity + solverBodyB.m_externalForceImpulse : btVector3(0, 0, 0)) + solverConstraint.m_relpos2CrossNormal.dot(bodyA ? solverBodyB.m_angularVelocity : btVector3(0, 0, 0)); - rel_vel = vel1Dotn+vel2Dotn; + rel_vel = vel1Dotn + vel2Dotn; -// btScalar positionalError = 0.f; + // btScalar positionalError = 0.f; - btScalar velocityError = desiredVelocity - rel_vel; + btScalar velocityError = desiredVelocity - rel_vel; btScalar velocityImpulse = velocityError * solverConstraint.m_jacDiagABInv; btScalar penetrationImpulse = btScalar(0); @@ -628,8 +593,8 @@ void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstr if (cp.m_contactPointFlags & BT_CONTACT_FLAG_FRICTION_ANCHOR) { btScalar distance = (cp.getPositionWorldOnA() - cp.getPositionWorldOnB()).dot(normalAxis); - btScalar positionalError = -distance * infoGlobal.m_frictionERP/infoGlobal.m_timeStep; - penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv; + btScalar positionalError = -distance * infoGlobal.m_frictionERP / infoGlobal.m_timeStep; + penetrationImpulse = positionalError * solverConstraint.m_jacDiagABInv; } solverConstraint.m_rhs = penetrationImpulse + velocityImpulse; @@ -637,11 +602,10 @@ void btSequentialImpulseConstraintSolver::setupFrictionConstraint(btSolverConstr solverConstraint.m_cfm = cfmSlip; solverConstraint.m_lowerLimit = -solverConstraint.m_friction; solverConstraint.m_upperLimit = solverConstraint.m_friction; - } } -btSolverConstraint& btSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity, btScalar cfmSlip) +btSolverConstraint& btSequentialImpulseConstraintSolver::addFrictionConstraint(const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity, btScalar cfmSlip) { btSolverConstraint& solverConstraint = m_tmpSolverContactFrictionConstraintPool.expandNonInitializing(); solverConstraint.m_frictionIndex = frictionIndex; @@ -650,15 +614,13 @@ btSolverConstraint& btSequentialImpulseConstraintSolver::addFrictionConstraint(c return solverConstraint; } - -void btSequentialImpulseConstraintSolver::setupTorsionalFrictionConstraint( btSolverConstraint& solverConstraint, const btVector3& normalAxis1,int solverBodyIdA,int solverBodyIdB, - btManifoldPoint& cp,btScalar combinedTorsionalFriction, const btVector3& rel_pos1,const btVector3& rel_pos2, - btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, - btScalar desiredVelocity, btScalar cfmSlip) +void btSequentialImpulseConstraintSolver::setupTorsionalFrictionConstraint(btSolverConstraint& solverConstraint, const btVector3& normalAxis1, int solverBodyIdA, int solverBodyIdB, + btManifoldPoint& cp, btScalar combinedTorsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2, + btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, + btScalar desiredVelocity, btScalar cfmSlip) { - btVector3 normalAxis(0,0,0); - + btVector3 normalAxis(0, 0, 0); solverConstraint.m_contactNormal1 = normalAxis; solverConstraint.m_contactNormal2 = -normalAxis; @@ -671,8 +633,8 @@ void btSequentialImpulseConstraintSolver::setupTorsionalFrictionConstraint( btSo solverConstraint.m_solverBodyIdA = solverBodyIdA; solverConstraint.m_solverBodyIdB = solverBodyIdB; - solverConstraint.m_friction = combinedTorsionalFriction; - solverConstraint.m_originalContactPoint = 0; + solverConstraint.m_friction = combinedTorsionalFriction; + solverConstraint.m_originalContactPoint = 0; solverConstraint.m_appliedImpulse = 0.f; solverConstraint.m_appliedPushImpulse = 0.f; @@ -680,138 +642,125 @@ void btSequentialImpulseConstraintSolver::setupTorsionalFrictionConstraint( btSo { btVector3 ftorqueAxis1 = -normalAxis1; solverConstraint.m_relpos1CrossNormal = ftorqueAxis1; - solverConstraint.m_angularComponentA = body0 ? body0->getInvInertiaTensorWorld()*ftorqueAxis1*body0->getAngularFactor() : btVector3(0,0,0); + solverConstraint.m_angularComponentA = body0 ? body0->getInvInertiaTensorWorld() * ftorqueAxis1 * body0->getAngularFactor() : btVector3(0, 0, 0); } { btVector3 ftorqueAxis1 = normalAxis1; solverConstraint.m_relpos2CrossNormal = ftorqueAxis1; - solverConstraint.m_angularComponentB = bodyA ? bodyA->getInvInertiaTensorWorld()*ftorqueAxis1*bodyA->getAngularFactor() : btVector3(0,0,0); + solverConstraint.m_angularComponentB = bodyA ? bodyA->getInvInertiaTensorWorld() * ftorqueAxis1 * bodyA->getAngularFactor() : btVector3(0, 0, 0); } - { - btVector3 iMJaA = body0?body0->getInvInertiaTensorWorld()*solverConstraint.m_relpos1CrossNormal:btVector3(0,0,0); - btVector3 iMJaB = bodyA?bodyA->getInvInertiaTensorWorld()*solverConstraint.m_relpos2CrossNormal:btVector3(0,0,0); + btVector3 iMJaA = body0 ? body0->getInvInertiaTensorWorld() * solverConstraint.m_relpos1CrossNormal : btVector3(0, 0, 0); + btVector3 iMJaB = bodyA ? bodyA->getInvInertiaTensorWorld() * solverConstraint.m_relpos2CrossNormal : btVector3(0, 0, 0); btScalar sum = 0; sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal); sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal); - solverConstraint.m_jacDiagABInv = btScalar(1.)/sum; + solverConstraint.m_jacDiagABInv = btScalar(1.) / sum; } { - - btScalar rel_vel; - btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(body0?solverBodyA.m_linearVelocity+solverBodyA.m_externalForceImpulse:btVector3(0,0,0)) - + solverConstraint.m_relpos1CrossNormal.dot(body0?solverBodyA.m_angularVelocity:btVector3(0,0,0)); - btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(bodyA?solverBodyB.m_linearVelocity+solverBodyB.m_externalForceImpulse:btVector3(0,0,0)) - + solverConstraint.m_relpos2CrossNormal.dot(bodyA?solverBodyB.m_angularVelocity:btVector3(0,0,0)); + btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(body0 ? solverBodyA.m_linearVelocity + solverBodyA.m_externalForceImpulse : btVector3(0, 0, 0)) + solverConstraint.m_relpos1CrossNormal.dot(body0 ? solverBodyA.m_angularVelocity : btVector3(0, 0, 0)); + btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(bodyA ? solverBodyB.m_linearVelocity + solverBodyB.m_externalForceImpulse : btVector3(0, 0, 0)) + solverConstraint.m_relpos2CrossNormal.dot(bodyA ? solverBodyB.m_angularVelocity : btVector3(0, 0, 0)); - rel_vel = vel1Dotn+vel2Dotn; + rel_vel = vel1Dotn + vel2Dotn; -// btScalar positionalError = 0.f; + // btScalar positionalError = 0.f; - btSimdScalar velocityError = desiredVelocity - rel_vel; - btSimdScalar velocityImpulse = velocityError * btSimdScalar(solverConstraint.m_jacDiagABInv); + btSimdScalar velocityError = desiredVelocity - rel_vel; + btSimdScalar velocityImpulse = velocityError * btSimdScalar(solverConstraint.m_jacDiagABInv); solverConstraint.m_rhs = velocityImpulse; solverConstraint.m_cfm = cfmSlip; solverConstraint.m_lowerLimit = -solverConstraint.m_friction; solverConstraint.m_upperLimit = solverConstraint.m_friction; - } } - - - - - - - -btSolverConstraint& btSequentialImpulseConstraintSolver::addTorsionalFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,btScalar combinedTorsionalFriction, const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity, btScalar cfmSlip) +btSolverConstraint& btSequentialImpulseConstraintSolver::addTorsionalFrictionConstraint(const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint& cp, btScalar combinedTorsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity, btScalar cfmSlip) { btSolverConstraint& solverConstraint = m_tmpSolverContactRollingFrictionConstraintPool.expandNonInitializing(); solverConstraint.m_frictionIndex = frictionIndex; - setupTorsionalFrictionConstraint(solverConstraint, normalAxis, solverBodyIdA, solverBodyIdB, cp, combinedTorsionalFriction,rel_pos1, rel_pos2, - colObj0, colObj1, relaxation, desiredVelocity, cfmSlip); + setupTorsionalFrictionConstraint(solverConstraint, normalAxis, solverBodyIdA, solverBodyIdB, cp, combinedTorsionalFriction, rel_pos1, rel_pos2, + colObj0, colObj1, relaxation, desiredVelocity, cfmSlip); return solverConstraint; } - -int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject& body,btScalar timeStep) +int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject& body, btScalar timeStep) { #if BT_THREADSAFE - int solverBodyId = -1; - bool isRigidBodyType = btRigidBody::upcast( &body ) != NULL; - if ( isRigidBodyType && !body.isStaticOrKinematicObject() ) - { - // dynamic body - // Dynamic bodies can only be in one island, so it's safe to write to the companionId - solverBodyId = body.getCompanionId(); - if ( solverBodyId < 0 ) - { - solverBodyId = m_tmpSolverBodyPool.size(); - btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); - initSolverBody( &solverBody, &body, timeStep ); - body.setCompanionId( solverBodyId ); - } - } - else if (isRigidBodyType && body.isKinematicObject()) - { - // - // NOTE: must test for kinematic before static because some kinematic objects also - // identify as "static" - // - // Kinematic bodies can be in multiple islands at once, so it is a - // race condition to write to them, so we use an alternate method - // to record the solverBodyId - int uniqueId = body.getWorldArrayIndex(); - const int INVALID_SOLVER_BODY_ID = -1; - if (uniqueId >= m_kinematicBodyUniqueIdToSolverBodyTable.size()) - { - m_kinematicBodyUniqueIdToSolverBodyTable.resize(uniqueId + 1, INVALID_SOLVER_BODY_ID); - } - solverBodyId = m_kinematicBodyUniqueIdToSolverBodyTable[ uniqueId ]; - // if no table entry yet, - if ( solverBodyId == INVALID_SOLVER_BODY_ID ) - { - // create a table entry for this body - solverBodyId = m_tmpSolverBodyPool.size(); - btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); - initSolverBody( &solverBody, &body, timeStep ); - m_kinematicBodyUniqueIdToSolverBodyTable[ uniqueId ] = solverBodyId; - } - } - else - { - bool isMultiBodyType = (body.getInternalType()&btCollisionObject::CO_FEATHERSTONE_LINK); - // Incorrectly set collision object flags can degrade performance in various ways. + int solverBodyId = -1; + bool isRigidBodyType = btRigidBody::upcast(&body) != NULL; + if (isRigidBodyType && !body.isStaticOrKinematicObject()) + { + // dynamic body + // Dynamic bodies can only be in one island, so it's safe to write to the companionId + solverBodyId = body.getCompanionId(); + if (solverBodyId < 0) + { + solverBodyId = m_tmpSolverBodyPool.size(); + btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); + initSolverBody(&solverBody, &body, timeStep); + body.setCompanionId(solverBodyId); + } + } + else if (isRigidBodyType && body.isKinematicObject()) + { + // + // NOTE: must test for kinematic before static because some kinematic objects also + // identify as "static" + // + // Kinematic bodies can be in multiple islands at once, so it is a + // race condition to write to them, so we use an alternate method + // to record the solverBodyId + int uniqueId = body.getWorldArrayIndex(); + const int INVALID_SOLVER_BODY_ID = -1; + if (uniqueId >= m_kinematicBodyUniqueIdToSolverBodyTable.size()) + { + m_kinematicBodyUniqueIdToSolverBodyTable.resize(uniqueId + 1, INVALID_SOLVER_BODY_ID); + } + solverBodyId = m_kinematicBodyUniqueIdToSolverBodyTable[uniqueId]; + // if no table entry yet, + if (solverBodyId == INVALID_SOLVER_BODY_ID) + { + // create a table entry for this body + solverBodyId = m_tmpSolverBodyPool.size(); + btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); + initSolverBody(&solverBody, &body, timeStep); + m_kinematicBodyUniqueIdToSolverBodyTable[uniqueId] = solverBodyId; + } + } + else + { + bool isMultiBodyType = (body.getInternalType() & btCollisionObject::CO_FEATHERSTONE_LINK); + // Incorrectly set collision object flags can degrade performance in various ways. if (!isMultiBodyType) { - btAssert( body.isStaticOrKinematicObject() ); + btAssert(body.isStaticOrKinematicObject()); } - //it could be a multibody link collider - // all fixed bodies (inf mass) get mapped to a single solver id - if ( m_fixedBodyId < 0 ) - { - m_fixedBodyId = m_tmpSolverBodyPool.size(); - btSolverBody& fixedBody = m_tmpSolverBodyPool.expand(); - initSolverBody( &fixedBody, 0, timeStep ); - } - solverBodyId = m_fixedBodyId; - } - btAssert( solverBodyId >= 0 && solverBodyId < m_tmpSolverBodyPool.size() ); + //it could be a multibody link collider + // all fixed bodies (inf mass) get mapped to a single solver id + if (m_fixedBodyId < 0) + { + m_fixedBodyId = m_tmpSolverBodyPool.size(); + btSolverBody& fixedBody = m_tmpSolverBodyPool.expand(); + initSolverBody(&fixedBody, 0, timeStep); + } + solverBodyId = m_fixedBodyId; + } + btAssert(solverBodyId >= 0 && solverBodyId < m_tmpSolverBodyPool.size()); return solverBodyId; -#else // BT_THREADSAFE +#else // BT_THREADSAFE - int solverBodyIdA = -1; + int solverBodyIdA = -1; if (body.getCompanionId() >= 0) { //body has already been converted solverBodyIdA = body.getCompanionId(); - btAssert(solverBodyIdA < m_tmpSolverBodyPool.size()); - } else + btAssert(solverBodyIdA < m_tmpSolverBodyPool.size()); + } + else { btRigidBody* rb = btRigidBody::upcast(&body); //convert both active and kinematic objects (for their velocity) @@ -819,233 +768,216 @@ int btSequentialImpulseConstraintSolver::getOrInitSolverBody(btCollisionObject& { solverBodyIdA = m_tmpSolverBodyPool.size(); btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); - initSolverBody(&solverBody,&body,timeStep); + initSolverBody(&solverBody, &body, timeStep); body.setCompanionId(solverBodyIdA); - } else + } + else { - - if (m_fixedBodyId<0) + if (m_fixedBodyId < 0) { m_fixedBodyId = m_tmpSolverBodyPool.size(); btSolverBody& fixedBody = m_tmpSolverBodyPool.expand(); - initSolverBody(&fixedBody,0,timeStep); + initSolverBody(&fixedBody, 0, timeStep); } return m_fixedBodyId; -// return 0;//assume first one is a fixed solver body + // return 0;//assume first one is a fixed solver body } } return solverBodyIdA; -#endif // BT_THREADSAFE - +#endif // BT_THREADSAFE } #include - void btSequentialImpulseConstraintSolver::setupContactConstraint(btSolverConstraint& solverConstraint, int solverBodyIdA, int solverBodyIdB, btManifoldPoint& cp, const btContactSolverInfo& infoGlobal, btScalar& relaxation, const btVector3& rel_pos1, const btVector3& rel_pos2) { + // const btVector3& pos1 = cp.getPositionWorldOnA(); + // const btVector3& pos2 = cp.getPositionWorldOnB(); - // const btVector3& pos1 = cp.getPositionWorldOnA(); - // const btVector3& pos2 = cp.getPositionWorldOnB(); + btSolverBody* bodyA = &m_tmpSolverBodyPool[solverBodyIdA]; + btSolverBody* bodyB = &m_tmpSolverBodyPool[solverBodyIdB]; - btSolverBody* bodyA = &m_tmpSolverBodyPool[solverBodyIdA]; - btSolverBody* bodyB = &m_tmpSolverBodyPool[solverBodyIdB]; + btRigidBody* rb0 = bodyA->m_originalBody; + btRigidBody* rb1 = bodyB->m_originalBody; - btRigidBody* rb0 = bodyA->m_originalBody; - btRigidBody* rb1 = bodyB->m_originalBody; + // btVector3 rel_pos1 = pos1 - colObj0->getWorldTransform().getOrigin(); + // btVector3 rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin(); + //rel_pos1 = pos1 - bodyA->getWorldTransform().getOrigin(); + //rel_pos2 = pos2 - bodyB->getWorldTransform().getOrigin(); -// btVector3 rel_pos1 = pos1 - colObj0->getWorldTransform().getOrigin(); -// btVector3 rel_pos2 = pos2 - colObj1->getWorldTransform().getOrigin(); - //rel_pos1 = pos1 - bodyA->getWorldTransform().getOrigin(); - //rel_pos2 = pos2 - bodyB->getWorldTransform().getOrigin(); + relaxation = infoGlobal.m_sor; + btScalar invTimeStep = btScalar(1) / infoGlobal.m_timeStep; - relaxation = infoGlobal.m_sor; - btScalar invTimeStep = btScalar(1)/infoGlobal.m_timeStep; + //cfm = 1 / ( dt * kp + kd ) + //erp = dt * kp / ( dt * kp + kd ) - //cfm = 1 / ( dt * kp + kd ) - //erp = dt * kp / ( dt * kp + kd ) - - btScalar cfm = infoGlobal.m_globalCfm; - btScalar erp = infoGlobal.m_erp2; + btScalar cfm = infoGlobal.m_globalCfm; + btScalar erp = infoGlobal.m_erp2; - if ((cp.m_contactPointFlags&BT_CONTACT_FLAG_HAS_CONTACT_CFM) || (cp.m_contactPointFlags&BT_CONTACT_FLAG_HAS_CONTACT_ERP)) - { - if (cp.m_contactPointFlags&BT_CONTACT_FLAG_HAS_CONTACT_CFM) - cfm = cp.m_contactCFM; - if (cp.m_contactPointFlags&BT_CONTACT_FLAG_HAS_CONTACT_ERP) - erp = cp.m_contactERP; - } else - { - if (cp.m_contactPointFlags & BT_CONTACT_FLAG_CONTACT_STIFFNESS_DAMPING) - { - btScalar denom = ( infoGlobal.m_timeStep * cp.m_combinedContactStiffness1 + cp.m_combinedContactDamping1 ); - if (denom < SIMD_EPSILON) - { - denom = SIMD_EPSILON; - } - cfm = btScalar(1) / denom; - erp = (infoGlobal.m_timeStep * cp.m_combinedContactStiffness1) / denom; - } - } - - cfm *= invTimeStep; - + if ((cp.m_contactPointFlags & BT_CONTACT_FLAG_HAS_CONTACT_CFM) || (cp.m_contactPointFlags & BT_CONTACT_FLAG_HAS_CONTACT_ERP)) + { + if (cp.m_contactPointFlags & BT_CONTACT_FLAG_HAS_CONTACT_CFM) + cfm = cp.m_contactCFM; + if (cp.m_contactPointFlags & BT_CONTACT_FLAG_HAS_CONTACT_ERP) + erp = cp.m_contactERP; + } + else + { + if (cp.m_contactPointFlags & BT_CONTACT_FLAG_CONTACT_STIFFNESS_DAMPING) + { + btScalar denom = (infoGlobal.m_timeStep * cp.m_combinedContactStiffness1 + cp.m_combinedContactDamping1); + if (denom < SIMD_EPSILON) + { + denom = SIMD_EPSILON; + } + cfm = btScalar(1) / denom; + erp = (infoGlobal.m_timeStep * cp.m_combinedContactStiffness1) / denom; + } + } - btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB); - solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld()*torqueAxis0*rb0->getAngularFactor() : btVector3(0,0,0); - btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB); - solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld()*-torqueAxis1*rb1->getAngularFactor() : btVector3(0,0,0); + cfm *= invTimeStep; - { + btVector3 torqueAxis0 = rel_pos1.cross(cp.m_normalWorldOnB); + solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld() * torqueAxis0 * rb0->getAngularFactor() : btVector3(0, 0, 0); + btVector3 torqueAxis1 = rel_pos2.cross(cp.m_normalWorldOnB); + solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld() * -torqueAxis1 * rb1->getAngularFactor() : btVector3(0, 0, 0); + + { #ifdef COMPUTE_IMPULSE_DENOM - btScalar denom0 = rb0->computeImpulseDenominator(pos1,cp.m_normalWorldOnB); - btScalar denom1 = rb1->computeImpulseDenominator(pos2,cp.m_normalWorldOnB); + btScalar denom0 = rb0->computeImpulseDenominator(pos1, cp.m_normalWorldOnB); + btScalar denom1 = rb1->computeImpulseDenominator(pos2, cp.m_normalWorldOnB); #else - btVector3 vec; - btScalar denom0 = 0.f; - btScalar denom1 = 0.f; - if (rb0) - { - vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1); - denom0 = rb0->getInvMass() + cp.m_normalWorldOnB.dot(vec); - } - if (rb1) - { - vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2); - denom1 = rb1->getInvMass() + cp.m_normalWorldOnB.dot(vec); - } -#endif //COMPUTE_IMPULSE_DENOM + btVector3 vec; + btScalar denom0 = 0.f; + btScalar denom1 = 0.f; + if (rb0) + { + vec = (solverConstraint.m_angularComponentA).cross(rel_pos1); + denom0 = rb0->getInvMass() + cp.m_normalWorldOnB.dot(vec); + } + if (rb1) + { + vec = (-solverConstraint.m_angularComponentB).cross(rel_pos2); + denom1 = rb1->getInvMass() + cp.m_normalWorldOnB.dot(vec); + } +#endif //COMPUTE_IMPULSE_DENOM - btScalar denom = relaxation/(denom0+denom1+cfm); - solverConstraint.m_jacDiagABInv = denom; - } + btScalar denom = relaxation / (denom0 + denom1 + cfm); + solverConstraint.m_jacDiagABInv = denom; + } - if (rb0) - { - solverConstraint.m_contactNormal1 = cp.m_normalWorldOnB; - solverConstraint.m_relpos1CrossNormal = torqueAxis0; - } else - { - solverConstraint.m_contactNormal1.setZero(); - solverConstraint.m_relpos1CrossNormal.setZero(); - } - if (rb1) - { - solverConstraint.m_contactNormal2 = -cp.m_normalWorldOnB; - solverConstraint.m_relpos2CrossNormal = -torqueAxis1; - }else - { - solverConstraint.m_contactNormal2.setZero(); - solverConstraint.m_relpos2CrossNormal.setZero(); - } + if (rb0) + { + solverConstraint.m_contactNormal1 = cp.m_normalWorldOnB; + solverConstraint.m_relpos1CrossNormal = torqueAxis0; + } + else + { + solverConstraint.m_contactNormal1.setZero(); + solverConstraint.m_relpos1CrossNormal.setZero(); + } + if (rb1) + { + solverConstraint.m_contactNormal2 = -cp.m_normalWorldOnB; + solverConstraint.m_relpos2CrossNormal = -torqueAxis1; + } + else + { + solverConstraint.m_contactNormal2.setZero(); + solverConstraint.m_relpos2CrossNormal.setZero(); + } - btScalar restitution = 0.f; - btScalar penetration = cp.getDistance()+infoGlobal.m_linearSlop; + btScalar restitution = 0.f; + btScalar penetration = cp.getDistance() + infoGlobal.m_linearSlop; - { - btVector3 vel1,vel2; + { + btVector3 vel1, vel2; - vel1 = rb0? rb0->getVelocityInLocalPoint(rel_pos1) : btVector3(0,0,0); - vel2 = rb1? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0); + vel1 = rb0 ? rb0->getVelocityInLocalPoint(rel_pos1) : btVector3(0, 0, 0); + vel2 = rb1 ? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0, 0, 0); - // btVector3 vel2 = rb1 ? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0); - btVector3 vel = vel1 - vel2; - btScalar rel_vel = cp.m_normalWorldOnB.dot(vel); + // btVector3 vel2 = rb1 ? rb1->getVelocityInLocalPoint(rel_pos2) : btVector3(0,0,0); + btVector3 vel = vel1 - vel2; + btScalar rel_vel = cp.m_normalWorldOnB.dot(vel); + solverConstraint.m_friction = cp.m_combinedFriction; + restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution, infoGlobal.m_restitutionVelocityThreshold); + if (restitution <= btScalar(0.)) + { + restitution = 0.f; + }; + } - solverConstraint.m_friction = cp.m_combinedFriction; + ///warm starting (or zero if disabled) + if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) + { + solverConstraint.m_appliedImpulse = cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor; + if (rb0) + bodyA->internalApplyImpulse(solverConstraint.m_contactNormal1 * bodyA->internalGetInvMass() * rb0->getLinearFactor(), solverConstraint.m_angularComponentA, solverConstraint.m_appliedImpulse); + if (rb1) + bodyB->internalApplyImpulse(-solverConstraint.m_contactNormal2 * bodyB->internalGetInvMass() * rb1->getLinearFactor(), -solverConstraint.m_angularComponentB, -(btScalar)solverConstraint.m_appliedImpulse); + } + else + { + solverConstraint.m_appliedImpulse = 0.f; + } + solverConstraint.m_appliedPushImpulse = 0.f; - restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution, infoGlobal.m_restitutionVelocityThreshold); - if (restitution <= btScalar(0.)) - { - restitution = 0.f; - }; - } + { + btVector3 externalForceImpulseA = bodyA->m_originalBody ? bodyA->m_externalForceImpulse : btVector3(0, 0, 0); + btVector3 externalTorqueImpulseA = bodyA->m_originalBody ? bodyA->m_externalTorqueImpulse : btVector3(0, 0, 0); + btVector3 externalForceImpulseB = bodyB->m_originalBody ? bodyB->m_externalForceImpulse : btVector3(0, 0, 0); + btVector3 externalTorqueImpulseB = bodyB->m_originalBody ? bodyB->m_externalTorqueImpulse : btVector3(0, 0, 0); + btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(bodyA->m_linearVelocity + externalForceImpulseA) + solverConstraint.m_relpos1CrossNormal.dot(bodyA->m_angularVelocity + externalTorqueImpulseA); + btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(bodyB->m_linearVelocity + externalForceImpulseB) + solverConstraint.m_relpos2CrossNormal.dot(bodyB->m_angularVelocity + externalTorqueImpulseB); + btScalar rel_vel = vel1Dotn + vel2Dotn; - ///warm starting (or zero if disabled) - if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) - { - solverConstraint.m_appliedImpulse = cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor; - if (rb0) - bodyA->internalApplyImpulse(solverConstraint.m_contactNormal1*bodyA->internalGetInvMass()*rb0->getLinearFactor(),solverConstraint.m_angularComponentA,solverConstraint.m_appliedImpulse); - if (rb1) - bodyB->internalApplyImpulse(-solverConstraint.m_contactNormal2*bodyB->internalGetInvMass()*rb1->getLinearFactor(),-solverConstraint.m_angularComponentB,-(btScalar)solverConstraint.m_appliedImpulse); - } else - { - solverConstraint.m_appliedImpulse = 0.f; - } - - solverConstraint.m_appliedPushImpulse = 0.f; - - { - - btVector3 externalForceImpulseA = bodyA->m_originalBody ? bodyA->m_externalForceImpulse: btVector3(0,0,0); - btVector3 externalTorqueImpulseA = bodyA->m_originalBody ? bodyA->m_externalTorqueImpulse: btVector3(0,0,0); - btVector3 externalForceImpulseB = bodyB->m_originalBody ? bodyB->m_externalForceImpulse: btVector3(0,0,0); - btVector3 externalTorqueImpulseB = bodyB->m_originalBody ?bodyB->m_externalTorqueImpulse : btVector3(0,0,0); - - - btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(bodyA->m_linearVelocity+externalForceImpulseA) - + solverConstraint.m_relpos1CrossNormal.dot(bodyA->m_angularVelocity+externalTorqueImpulseA); - btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(bodyB->m_linearVelocity+externalForceImpulseB) - + solverConstraint.m_relpos2CrossNormal.dot(bodyB->m_angularVelocity+externalTorqueImpulseB); - btScalar rel_vel = vel1Dotn+vel2Dotn; - - btScalar positionalError = 0.f; - btScalar velocityError = restitution - rel_vel;// * damping; - - - - if (penetration>0) - { - positionalError = 0; - - velocityError -= penetration *invTimeStep; - } else - { - positionalError = -penetration * erp*invTimeStep; - - } - - btScalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv; - btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv; - - if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold)) - { - //combine position and velocity into rhs - solverConstraint.m_rhs = penetrationImpulse+velocityImpulse;//-solverConstraint.m_contactNormal1.dot(bodyA->m_externalForce*bodyA->m_invMass-bodyB->m_externalForce/bodyB->m_invMass)*solverConstraint.m_jacDiagABInv; - solverConstraint.m_rhsPenetration = 0.f; - - } else - { - //split position and velocity into rhs and m_rhsPenetration - solverConstraint.m_rhs = velocityImpulse; - solverConstraint.m_rhsPenetration = penetrationImpulse; - } - solverConstraint.m_cfm = cfm*solverConstraint.m_jacDiagABInv; - solverConstraint.m_lowerLimit = 0; - solverConstraint.m_upperLimit = 1e10f; - } + btScalar positionalError = 0.f; + btScalar velocityError = restitution - rel_vel; // * damping; + if (penetration > 0) + { + positionalError = 0; + velocityError -= penetration * invTimeStep; + } + else + { + positionalError = -penetration * erp * invTimeStep; + } + btScalar penetrationImpulse = positionalError * solverConstraint.m_jacDiagABInv; + btScalar velocityImpulse = velocityError * solverConstraint.m_jacDiagABInv; + if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold)) + { + //combine position and velocity into rhs + solverConstraint.m_rhs = penetrationImpulse + velocityImpulse; //-solverConstraint.m_contactNormal1.dot(bodyA->m_externalForce*bodyA->m_invMass-bodyB->m_externalForce/bodyB->m_invMass)*solverConstraint.m_jacDiagABInv; + solverConstraint.m_rhsPenetration = 0.f; + } + else + { + //split position and velocity into rhs and m_rhsPenetration + solverConstraint.m_rhs = velocityImpulse; + solverConstraint.m_rhsPenetration = penetrationImpulse; + } + solverConstraint.m_cfm = cfm * solverConstraint.m_jacDiagABInv; + solverConstraint.m_lowerLimit = 0; + solverConstraint.m_upperLimit = 1e10f; + } } - - -void btSequentialImpulseConstraintSolver::setFrictionConstraintImpulse( btSolverConstraint& solverConstraint, - int solverBodyIdA, int solverBodyIdB, - btManifoldPoint& cp, const btContactSolverInfo& infoGlobal) +void btSequentialImpulseConstraintSolver::setFrictionConstraintImpulse(btSolverConstraint& solverConstraint, + int solverBodyIdA, int solverBodyIdB, + btManifoldPoint& cp, const btContactSolverInfo& infoGlobal) { - btSolverBody* bodyA = &m_tmpSolverBodyPool[solverBodyIdA]; btSolverBody* bodyB = &m_tmpSolverBodyPool[solverBodyIdB]; @@ -1058,10 +990,11 @@ void btSequentialImpulseConstraintSolver::setFrictionConstraintImpulse( btSolver { frictionConstraint1.m_appliedImpulse = cp.m_appliedImpulseLateral1 * infoGlobal.m_warmstartingFactor; if (rb0) - bodyA->internalApplyImpulse(frictionConstraint1.m_contactNormal1*rb0->getInvMass()*rb0->getLinearFactor(),frictionConstraint1.m_angularComponentA,frictionConstraint1.m_appliedImpulse); + bodyA->internalApplyImpulse(frictionConstraint1.m_contactNormal1 * rb0->getInvMass() * rb0->getLinearFactor(), frictionConstraint1.m_angularComponentA, frictionConstraint1.m_appliedImpulse); if (rb1) - bodyB->internalApplyImpulse(-frictionConstraint1.m_contactNormal2*rb1->getInvMass()*rb1->getLinearFactor(),-frictionConstraint1.m_angularComponentB,-(btScalar)frictionConstraint1.m_appliedImpulse); - } else + bodyB->internalApplyImpulse(-frictionConstraint1.m_contactNormal2 * rb1->getInvMass() * rb1->getLinearFactor(), -frictionConstraint1.m_angularComponentB, -(btScalar)frictionConstraint1.m_appliedImpulse); + } + else { frictionConstraint1.m_appliedImpulse = 0.f; } @@ -1069,50 +1002,45 @@ void btSequentialImpulseConstraintSolver::setFrictionConstraintImpulse( btSolver if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) { - btSolverConstraint& frictionConstraint2 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex+1]; + btSolverConstraint& frictionConstraint2 = m_tmpSolverContactFrictionConstraintPool[solverConstraint.m_frictionIndex + 1]; if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) { - frictionConstraint2.m_appliedImpulse = cp.m_appliedImpulseLateral2 * infoGlobal.m_warmstartingFactor; + frictionConstraint2.m_appliedImpulse = cp.m_appliedImpulseLateral2 * infoGlobal.m_warmstartingFactor; if (rb0) - bodyA->internalApplyImpulse(frictionConstraint2.m_contactNormal1*rb0->getInvMass(),frictionConstraint2.m_angularComponentA,frictionConstraint2.m_appliedImpulse); + bodyA->internalApplyImpulse(frictionConstraint2.m_contactNormal1 * rb0->getInvMass(), frictionConstraint2.m_angularComponentA, frictionConstraint2.m_appliedImpulse); if (rb1) - bodyB->internalApplyImpulse(-frictionConstraint2.m_contactNormal2*rb1->getInvMass(),-frictionConstraint2.m_angularComponentB,-(btScalar)frictionConstraint2.m_appliedImpulse); - } else + bodyB->internalApplyImpulse(-frictionConstraint2.m_contactNormal2 * rb1->getInvMass(), -frictionConstraint2.m_angularComponentB, -(btScalar)frictionConstraint2.m_appliedImpulse); + } + else { frictionConstraint2.m_appliedImpulse = 0.f; } } } - - - -void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal) +void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* manifold, const btContactSolverInfo& infoGlobal) { - btCollisionObject* colObj0=0,*colObj1=0; + btCollisionObject *colObj0 = 0, *colObj1 = 0; colObj0 = (btCollisionObject*)manifold->getBody0(); colObj1 = (btCollisionObject*)manifold->getBody1(); - int solverBodyIdA = getOrInitSolverBody(*colObj0,infoGlobal.m_timeStep); - int solverBodyIdB = getOrInitSolverBody(*colObj1,infoGlobal.m_timeStep); + int solverBodyIdA = getOrInitSolverBody(*colObj0, infoGlobal.m_timeStep); + int solverBodyIdB = getOrInitSolverBody(*colObj1, infoGlobal.m_timeStep); -// btRigidBody* bodyA = btRigidBody::upcast(colObj0); -// btRigidBody* bodyB = btRigidBody::upcast(colObj1); + // btRigidBody* bodyA = btRigidBody::upcast(colObj0); + // btRigidBody* bodyB = btRigidBody::upcast(colObj1); btSolverBody* solverBodyA = &m_tmpSolverBodyPool[solverBodyIdA]; btSolverBody* solverBodyB = &m_tmpSolverBodyPool[solverBodyIdB]; - - ///avoid collision response between two static objects if (!solverBodyA || (solverBodyA->m_invMass.fuzzyZero() && (!solverBodyB || solverBodyB->m_invMass.fuzzyZero()))) return; - int rollingFriction=1; - for (int j=0;jgetNumContacts();j++) + int rollingFriction = 1; + for (int j = 0; j < manifold->getNumContacts(); j++) { - btManifoldPoint& cp = manifold->getContactPoint(j); if (cp.getDistance() <= manifold->getContactProcessingThreshold()) @@ -1121,7 +1049,6 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m btVector3 rel_pos2; btScalar relaxation; - int frictionIndex = m_tmpSolverContactConstraintPool.size(); btSolverConstraint& solverConstraint = m_tmpSolverContactConstraintPool.expandNonInitializing(); solverConstraint.m_solverBodyIdA = solverBodyIdA; @@ -1137,43 +1064,38 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m btVector3 vel1; btVector3 vel2; - - solverBodyA->getVelocityInLocalPointNoDelta(rel_pos1,vel1); - solverBodyB->getVelocityInLocalPointNoDelta(rel_pos2,vel2 ); - btVector3 vel = vel1 - vel2; + solverBodyA->getVelocityInLocalPointNoDelta(rel_pos1, vel1); + solverBodyB->getVelocityInLocalPointNoDelta(rel_pos2, vel2); + + btVector3 vel = vel1 - vel2; btScalar rel_vel = cp.m_normalWorldOnB.dot(vel); setupContactConstraint(solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal, relaxation, rel_pos1, rel_pos2); - - - /////setup the friction constraints solverConstraint.m_frictionIndex = m_tmpSolverContactFrictionConstraintPool.size(); - if ((cp.m_combinedRollingFriction>0.f) && (rollingFriction>0)) + if ((cp.m_combinedRollingFriction > 0.f) && (rollingFriction > 0)) { - { - addTorsionalFrictionConstraint(cp.m_normalWorldOnB,solverBodyIdA,solverBodyIdB,frictionIndex,cp,cp.m_combinedSpinningFriction, rel_pos1,rel_pos2,colObj0,colObj1, relaxation); - btVector3 axis0,axis1; - btPlaneSpace1(cp.m_normalWorldOnB,axis0,axis1); + addTorsionalFrictionConstraint(cp.m_normalWorldOnB, solverBodyIdA, solverBodyIdB, frictionIndex, cp, cp.m_combinedSpinningFriction, rel_pos1, rel_pos2, colObj0, colObj1, relaxation); + btVector3 axis0, axis1; + btPlaneSpace1(cp.m_normalWorldOnB, axis0, axis1); axis0.normalize(); axis1.normalize(); - - applyAnisotropicFriction(colObj0,axis0,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); - applyAnisotropicFriction(colObj1,axis0,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); - applyAnisotropicFriction(colObj0,axis1,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); - applyAnisotropicFriction(colObj1,axis1,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); - if (axis0.length()>0.001) - addTorsionalFrictionConstraint(axis0,solverBodyIdA,solverBodyIdB,frictionIndex,cp, - cp.m_combinedRollingFriction, rel_pos1,rel_pos2,colObj0,colObj1, relaxation); - if (axis1.length()>0.001) - addTorsionalFrictionConstraint(axis1,solverBodyIdA,solverBodyIdB,frictionIndex,cp, - cp.m_combinedRollingFriction, rel_pos1,rel_pos2,colObj0,colObj1, relaxation); + applyAnisotropicFriction(colObj0, axis0, btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); + applyAnisotropicFriction(colObj1, axis0, btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); + applyAnisotropicFriction(colObj0, axis1, btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); + applyAnisotropicFriction(colObj1, axis1, btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); + if (axis0.length() > 0.001) + addTorsionalFrictionConstraint(axis0, solverBodyIdA, solverBodyIdB, frictionIndex, cp, + cp.m_combinedRollingFriction, rel_pos1, rel_pos2, colObj0, colObj1, relaxation); + if (axis1.length() > 0.001) + addTorsionalFrictionConstraint(axis1, solverBodyIdA, solverBodyIdB, frictionIndex, cp, + cp.m_combinedRollingFriction, rel_pos1, rel_pos2, colObj0, colObj1, relaxation); } } @@ -1192,102 +1114,93 @@ void btSequentialImpulseConstraintSolver::convertContact(btPersistentManifold* m ///In that case, you can set the target relative motion in each friction direction (cp.m_contactMotion1 and cp.m_contactMotion2) ///this will give a conveyor belt effect /// - - if (!(infoGlobal.m_solverMode & SOLVER_ENABLE_FRICTION_DIRECTION_CACHING) || !(cp.m_contactPointFlags&BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED)) + + if (!(infoGlobal.m_solverMode & SOLVER_ENABLE_FRICTION_DIRECTION_CACHING) || !(cp.m_contactPointFlags & BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED)) { cp.m_lateralFrictionDir1 = vel - cp.m_normalWorldOnB * rel_vel; btScalar lat_rel_vel = cp.m_lateralFrictionDir1.length2(); if (!(infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION) && lat_rel_vel > SIMD_EPSILON) { - cp.m_lateralFrictionDir1 *= 1.f/btSqrt(lat_rel_vel); - applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION); - applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION); - addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation,infoGlobal); - - if((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) - { - cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB); - cp.m_lateralFrictionDir2.normalize();//?? - applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION); - applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION); - addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation, infoGlobal); - } - - } else - { - btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2); - - applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION); - applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION); - addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation, infoGlobal); + cp.m_lateralFrictionDir1 *= 1.f / btSqrt(lat_rel_vel); + applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION); + applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION); + addFrictionConstraint(cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal); if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) { - applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION); - applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION); - addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation, infoGlobal); + cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB); + cp.m_lateralFrictionDir2.normalize(); //?? + applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION); + applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION); + addFrictionConstraint(cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal); } + } + else + { + btPlaneSpace1(cp.m_normalWorldOnB, cp.m_lateralFrictionDir1, cp.m_lateralFrictionDir2); + applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION); + applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION); + addFrictionConstraint(cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal); + + if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) + { + applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION); + applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION); + addFrictionConstraint(cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal); + } if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) && (infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION)) { - cp.m_contactPointFlags|=BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED; + cp.m_contactPointFlags |= BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED; } } - - } else + } + else { - addFrictionConstraint(cp.m_lateralFrictionDir1,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation, infoGlobal, cp.m_contactMotion1, cp.m_frictionCFM); + addFrictionConstraint(cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal, cp.m_contactMotion1, cp.m_frictionCFM); if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) - addFrictionConstraint(cp.m_lateralFrictionDir2,solverBodyIdA,solverBodyIdB,frictionIndex,cp,rel_pos1,rel_pos2,colObj0,colObj1, relaxation, infoGlobal, cp.m_contactMotion2, cp.m_frictionCFM); - + addFrictionConstraint(cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, frictionIndex, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal, cp.m_contactMotion2, cp.m_frictionCFM); } - setFrictionConstraintImpulse( solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal); - - - - + setFrictionConstraintImpulse(solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal); } } } -void btSequentialImpulseConstraintSolver::convertContacts(btPersistentManifold** manifoldPtr,int numManifolds, const btContactSolverInfo& infoGlobal) +void btSequentialImpulseConstraintSolver::convertContacts(btPersistentManifold** manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal) { int i; btPersistentManifold* manifold = 0; -// btCollisionObject* colObj0=0,*colObj1=0; + // btCollisionObject* colObj0=0,*colObj1=0; - - for (i=0;igetRigidBodyA(); const btRigidBody& rbB = constraint->getRigidBodyB(); - const btSolverBody* bodyAPtr = &m_tmpSolverBodyPool[solverBodyIdA]; - const btSolverBody* bodyBPtr = &m_tmpSolverBodyPool[solverBodyIdB]; + const btSolverBody* bodyAPtr = &m_tmpSolverBodyPool[solverBodyIdA]; + const btSolverBody* bodyBPtr = &m_tmpSolverBodyPool[solverBodyIdB]; int overrideNumSolverIterations = constraint->getOverrideNumSolverIterations() > 0 ? constraint->getOverrideNumSolverIterations() : infoGlobal.m_numIterations; - if (overrideNumSolverIterations>m_maxOverrideNumSolverIterations) + if (overrideNumSolverIterations > m_maxOverrideNumSolverIterations) m_maxOverrideNumSolverIterations = overrideNumSolverIterations; - for (int j=0;jgetDeltaLinearVelocity().isZero()); - btAssert(bodyAPtr->getDeltaAngularVelocity().isZero()); - btAssert(bodyAPtr->getPushVelocity().isZero()); - btAssert(bodyAPtr->getTurnVelocity().isZero()); - btAssert(bodyBPtr->getDeltaLinearVelocity().isZero()); - btAssert(bodyBPtr->getDeltaAngularVelocity().isZero()); - btAssert(bodyBPtr->getPushVelocity().isZero()); - btAssert(bodyBPtr->getTurnVelocity().isZero()); + // these vectors are already cleared in initSolverBody, no need to redundantly clear again + btAssert(bodyAPtr->getDeltaLinearVelocity().isZero()); + btAssert(bodyAPtr->getDeltaAngularVelocity().isZero()); + btAssert(bodyAPtr->getPushVelocity().isZero()); + btAssert(bodyAPtr->getTurnVelocity().isZero()); + btAssert(bodyBPtr->getDeltaLinearVelocity().isZero()); + btAssert(bodyBPtr->getDeltaAngularVelocity().isZero()); + btAssert(bodyBPtr->getPushVelocity().isZero()); + btAssert(bodyBPtr->getTurnVelocity().isZero()); //bodyAPtr->internalGetDeltaLinearVelocity().setValue(0.f,0.f,0.f); //bodyAPtr->internalGetDeltaAngularVelocity().setValue(0.f,0.f,0.f); //bodyAPtr->internalGetPushVelocity().setValue(0.f,0.f,0.f); @@ -1315,17 +1228,16 @@ void btSequentialImpulseConstraintSolver::convertJoint(btSolverConstraint* curre //bodyBPtr->internalGetPushVelocity().setValue(0.f,0.f,0.f); //bodyBPtr->internalGetTurnVelocity().setValue(0.f,0.f,0.f); - btTypedConstraint::btConstraintInfo2 info2; - info2.fps = 1.f/infoGlobal.m_timeStep; + info2.fps = 1.f / infoGlobal.m_timeStep; info2.erp = infoGlobal.m_erp; info2.m_J1linearAxis = currentConstraintRow->m_contactNormal1; info2.m_J1angularAxis = currentConstraintRow->m_relpos1CrossNormal; info2.m_J2linearAxis = currentConstraintRow->m_contactNormal2; info2.m_J2angularAxis = currentConstraintRow->m_relpos2CrossNormal; - info2.rowskip = sizeof(btSolverConstraint)/sizeof(btScalar);//check this + info2.rowskip = sizeof(btSolverConstraint) / sizeof(btScalar); //check this ///the size of btSolverConstraint needs be a multiple of btScalar - btAssert(info2.rowskip*sizeof(btScalar)== sizeof(btSolverConstraint)); + btAssert(info2.rowskip * sizeof(btScalar) == sizeof(btSolverConstraint)); info2.m_constraintError = ¤tConstraintRow->m_rhs; currentConstraintRow->m_cfm = infoGlobal.m_globalCfm; info2.m_damping = infoGlobal.m_damping; @@ -1336,16 +1248,16 @@ void btSequentialImpulseConstraintSolver::convertJoint(btSolverConstraint* curre constraint->getInfo2(&info2); ///finalize the constraint setup - for (int j=0;j=constraint->getBreakingImpulseThreshold()) + if (solverConstraint.m_upperLimit >= constraint->getBreakingImpulseThreshold()) { solverConstraint.m_upperLimit = constraint->getBreakingImpulseThreshold(); } - if (solverConstraint.m_lowerLimit<=-constraint->getBreakingImpulseThreshold()) + if (solverConstraint.m_lowerLimit <= -constraint->getBreakingImpulseThreshold()) { solverConstraint.m_lowerLimit = -constraint->getBreakingImpulseThreshold(); } @@ -1354,18 +1266,18 @@ void btSequentialImpulseConstraintSolver::convertJoint(btSolverConstraint* curre { const btVector3& ftorqueAxis1 = solverConstraint.m_relpos1CrossNormal; - solverConstraint.m_angularComponentA = constraint->getRigidBodyA().getInvInertiaTensorWorld()*ftorqueAxis1*constraint->getRigidBodyA().getAngularFactor(); + solverConstraint.m_angularComponentA = constraint->getRigidBodyA().getInvInertiaTensorWorld() * ftorqueAxis1 * constraint->getRigidBodyA().getAngularFactor(); } { const btVector3& ftorqueAxis2 = solverConstraint.m_relpos2CrossNormal; - solverConstraint.m_angularComponentB = constraint->getRigidBodyB().getInvInertiaTensorWorld()*ftorqueAxis2*constraint->getRigidBodyB().getAngularFactor(); + solverConstraint.m_angularComponentB = constraint->getRigidBodyB().getInvInertiaTensorWorld() * ftorqueAxis2 * constraint->getRigidBodyB().getAngularFactor(); } { - btVector3 iMJlA = solverConstraint.m_contactNormal1*rbA.getInvMass(); - btVector3 iMJaA = rbA.getInvInertiaTensorWorld()*solverConstraint.m_relpos1CrossNormal; - btVector3 iMJlB = solverConstraint.m_contactNormal2*rbB.getInvMass();//sign of normal? - btVector3 iMJaB = rbB.getInvInertiaTensorWorld()*solverConstraint.m_relpos2CrossNormal; + btVector3 iMJlA = solverConstraint.m_contactNormal1 * rbA.getInvMass(); + btVector3 iMJaA = rbA.getInvInertiaTensorWorld() * solverConstraint.m_relpos1CrossNormal; + btVector3 iMJlB = solverConstraint.m_contactNormal2 * rbB.getInvMass(); //sign of normal? + btVector3 iMJaB = rbB.getInvInertiaTensorWorld() * solverConstraint.m_relpos2CrossNormal; btScalar sum = iMJlA.dot(solverConstraint.m_contactNormal1); sum += iMJaA.dot(solverConstraint.m_relpos1CrossNormal); @@ -1373,41 +1285,38 @@ void btSequentialImpulseConstraintSolver::convertJoint(btSolverConstraint* curre sum += iMJaB.dot(solverConstraint.m_relpos2CrossNormal); btScalar fsum = btFabs(sum); btAssert(fsum > SIMD_EPSILON); - btScalar sorRelaxation = 1.f;//todo: get from globalInfo? - solverConstraint.m_jacDiagABInv = fsum>SIMD_EPSILON?sorRelaxation/sum : 0.f; + btScalar sorRelaxation = 1.f; //todo: get from globalInfo? + solverConstraint.m_jacDiagABInv = fsum > SIMD_EPSILON ? sorRelaxation / sum : 0.f; } { btScalar rel_vel; - btVector3 externalForceImpulseA = bodyAPtr->m_originalBody ? bodyAPtr->m_externalForceImpulse : btVector3(0,0,0); - btVector3 externalTorqueImpulseA = bodyAPtr->m_originalBody ? bodyAPtr->m_externalTorqueImpulse : btVector3(0,0,0); + btVector3 externalForceImpulseA = bodyAPtr->m_originalBody ? bodyAPtr->m_externalForceImpulse : btVector3(0, 0, 0); + btVector3 externalTorqueImpulseA = bodyAPtr->m_originalBody ? bodyAPtr->m_externalTorqueImpulse : btVector3(0, 0, 0); - btVector3 externalForceImpulseB = bodyBPtr->m_originalBody ? bodyBPtr->m_externalForceImpulse : btVector3(0,0,0); - btVector3 externalTorqueImpulseB = bodyBPtr->m_originalBody ?bodyBPtr->m_externalTorqueImpulse : btVector3(0,0,0); + btVector3 externalForceImpulseB = bodyBPtr->m_originalBody ? bodyBPtr->m_externalForceImpulse : btVector3(0, 0, 0); + btVector3 externalTorqueImpulseB = bodyBPtr->m_originalBody ? bodyBPtr->m_externalTorqueImpulse : btVector3(0, 0, 0); - btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(rbA.getLinearVelocity()+externalForceImpulseA) - + solverConstraint.m_relpos1CrossNormal.dot(rbA.getAngularVelocity()+externalTorqueImpulseA); + btScalar vel1Dotn = solverConstraint.m_contactNormal1.dot(rbA.getLinearVelocity() + externalForceImpulseA) + solverConstraint.m_relpos1CrossNormal.dot(rbA.getAngularVelocity() + externalTorqueImpulseA); - btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(rbB.getLinearVelocity()+externalForceImpulseB) - + solverConstraint.m_relpos2CrossNormal.dot(rbB.getAngularVelocity()+externalTorqueImpulseB); + btScalar vel2Dotn = solverConstraint.m_contactNormal2.dot(rbB.getLinearVelocity() + externalForceImpulseB) + solverConstraint.m_relpos2CrossNormal.dot(rbB.getAngularVelocity() + externalTorqueImpulseB); - rel_vel = vel1Dotn+vel2Dotn; + rel_vel = vel1Dotn + vel2Dotn; btScalar restitution = 0.f; - btScalar positionalError = solverConstraint.m_rhs;//already filled in by getConstraintInfo2 - btScalar velocityError = restitution - rel_vel * info2.m_damping; - btScalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv; - btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv; - solverConstraint.m_rhs = penetrationImpulse+velocityImpulse; + btScalar positionalError = solverConstraint.m_rhs; //already filled in by getConstraintInfo2 + btScalar velocityError = restitution - rel_vel * info2.m_damping; + btScalar penetrationImpulse = positionalError * solverConstraint.m_jacDiagABInv; + btScalar velocityImpulse = velocityError * solverConstraint.m_jacDiagABInv; + solverConstraint.m_rhs = penetrationImpulse + velocityImpulse; solverConstraint.m_appliedImpulse = 0.f; } } } - -void btSequentialImpulseConstraintSolver::convertJoints(btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal) +void btSequentialImpulseConstraintSolver::convertJoints(btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal) { - BT_PROFILE("convertJoints"); - for (int j=0;jbuildJacobian(); @@ -1418,7 +1327,7 @@ void btSequentialImpulseConstraintSolver::convertJoints(btTypedConstraint** cons m_tmpConstraintSizesPool.resizeNoInitialize(numConstraints); //calculate the total number of contraint rows - for (int i=0;igetJointFeedback(); @@ -1433,7 +1342,8 @@ void btSequentialImpulseConstraintSolver::convertJoints(btTypedConstraint** cons if (constraints[i]->isEnabled()) { constraints[i]->getInfo1(&info1); - } else + } + else { info1.m_numConstraintRows = 0; info1.nub = 0; @@ -1442,110 +1352,105 @@ void btSequentialImpulseConstraintSolver::convertJoints(btTypedConstraint** cons } m_tmpSolverNonContactConstraintPool.resizeNoInitialize(totalNumRows); - ///setup the btSolverConstraints int currentRow = 0; - for (int i=0;igetRigidBodyA(); btRigidBody& rbB = constraint->getRigidBodyB(); - int solverBodyIdA = getOrInitSolverBody(rbA,infoGlobal.m_timeStep); - int solverBodyIdB = getOrInitSolverBody(rbB,infoGlobal.m_timeStep); + int solverBodyIdA = getOrInitSolverBody(rbA, infoGlobal.m_timeStep); + int solverBodyIdB = getOrInitSolverBody(rbB, infoGlobal.m_timeStep); - convertJoint(currentConstraintRow, constraint, info1, solverBodyIdA, solverBodyIdB, infoGlobal); - } - currentRow+=info1.m_numConstraintRows; + convertJoint(currentConstraintRow, constraint, info1, solverBodyIdA, solverBodyIdB, infoGlobal); + } + currentRow += info1.m_numConstraintRows; } } - void btSequentialImpulseConstraintSolver::convertBodies(btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal) { - BT_PROFILE("convertBodies"); + BT_PROFILE("convertBodies"); for (int i = 0; i < numBodies; i++) { bodies[i]->setCompanionId(-1); } #if BT_THREADSAFE - m_kinematicBodyUniqueIdToSolverBodyTable.resize( 0 ); -#endif // BT_THREADSAFE + m_kinematicBodyUniqueIdToSolverBodyTable.resize(0); +#endif // BT_THREADSAFE - m_tmpSolverBodyPool.reserve(numBodies+1); + m_tmpSolverBodyPool.reserve(numBodies + 1); m_tmpSolverBodyPool.resize(0); //btSolverBody& fixedBody = m_tmpSolverBodyPool.expand(); - //initSolverBody(&fixedBody,0); + //initSolverBody(&fixedBody,0); - for (int i=0;igetInvMass()) { btSolverBody& solverBody = m_tmpSolverBodyPool[bodyId]; - btVector3 gyroForce (0,0,0); - if (body->getFlags()&BT_ENABLE_GYROSCOPIC_FORCE_EXPLICIT) + btVector3 gyroForce(0, 0, 0); + if (body->getFlags() & BT_ENABLE_GYROSCOPIC_FORCE_EXPLICIT) { gyroForce = body->computeGyroscopicForceExplicit(infoGlobal.m_maxGyroscopicForce); - solverBody.m_externalTorqueImpulse -= gyroForce*body->getInvInertiaTensorWorld()*infoGlobal.m_timeStep; + solverBody.m_externalTorqueImpulse -= gyroForce * body->getInvInertiaTensorWorld() * infoGlobal.m_timeStep; } - if (body->getFlags()&BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD) + if (body->getFlags() & BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD) { gyroForce = body->computeGyroscopicImpulseImplicit_World(infoGlobal.m_timeStep); solverBody.m_externalTorqueImpulse += gyroForce; } - if (body->getFlags()&BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY) + if (body->getFlags() & BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY) { gyroForce = body->computeGyroscopicImpulseImplicit_Body(infoGlobal.m_timeStep); solverBody.m_externalTorqueImpulse += gyroForce; - } } } } - -btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer) +btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer) { m_fixedBodyId = -1; BT_PROFILE("solveGroupCacheFriendlySetup"); (void)debugDrawer; - // if solver mode has changed, - if ( infoGlobal.m_solverMode != m_cachedSolverMode ) - { - // update solver functions to use SIMD or non-SIMD - bool useSimd = !!( infoGlobal.m_solverMode & SOLVER_SIMD ); - setupSolverFunctions( useSimd ); - m_cachedSolverMode = infoGlobal.m_solverMode; - } + // if solver mode has changed, + if (infoGlobal.m_solverMode != m_cachedSolverMode) + { + // update solver functions to use SIMD or non-SIMD + bool useSimd = !!(infoGlobal.m_solverMode & SOLVER_SIMD); + setupSolverFunctions(useSimd); + m_cachedSolverMode = infoGlobal.m_solverMode; + } m_maxOverrideNumSolverIterations = 0; #ifdef BT_ADDITIONAL_DEBUG - //make sure that dynamic bodies exist for all (enabled) constraints - for (int i=0;iisEnabled()) { if (!constraint->getRigidBodyA().isStaticOrKinematicObject()) { - bool found=false; - for (int b=0;bgetRigidBodyA()==bodies[b]) + if (&constraint->getRigidBodyA() == bodies[b]) { found = true; break; @@ -1555,10 +1460,10 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol } if (!constraint->getRigidBodyB().isStaticOrKinematicObject()) { - bool found=false; - for (int b=0;bgetRigidBodyB()==bodies[b]) + if (&constraint->getRigidBodyB() == bodies[b]) { found = true; break; @@ -1568,50 +1473,46 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol } } } - //make sure that dynamic bodies exist for all contact manifolds - for (int i=0;igetBody0()->isStaticOrKinematicObject()) - { - bool found=false; - for (int b=0;bgetBody0()==bodies[b]) - { - found = true; - break; - } - } - btAssert(found); - } - if (!manifoldPtr[i]->getBody1()->isStaticOrKinematicObject()) - { - bool found=false; - for (int b=0;bgetBody1()==bodies[b]) - { - found = true; - break; - } - } - btAssert(found); - } - } -#endif //BT_ADDITIONAL_DEBUG - + //make sure that dynamic bodies exist for all contact manifolds + for (int i = 0; i < numManifolds; i++) + { + if (!manifoldPtr[i]->getBody0()->isStaticOrKinematicObject()) + { + bool found = false; + for (int b = 0; b < numBodies; b++) + { + if (manifoldPtr[i]->getBody0() == bodies[b]) + { + found = true; + break; + } + } + btAssert(found); + } + if (!manifoldPtr[i]->getBody1()->isStaticOrKinematicObject()) + { + bool found = false; + for (int b = 0; b < numBodies; b++) + { + if (manifoldPtr[i]->getBody1() == bodies[b]) + { + found = true; + break; + } + } + btAssert(found); + } + } +#endif //BT_ADDITIONAL_DEBUG //convert all bodies - convertBodies(bodies, numBodies, infoGlobal); + convertBodies(bodies, numBodies, infoGlobal); - convertJoints(constraints, numConstraints, infoGlobal); + convertJoints(constraints, numConstraints, infoGlobal); - convertContacts(manifoldPtr,numManifolds,infoGlobal); - - -// btContactSolverInfo info = infoGlobal; + convertContacts(manifoldPtr, numManifolds, infoGlobal); + // btContactSolverInfo info = infoGlobal; int numNonContactPool = m_tmpSolverNonContactConstraintPool.size(); int numConstraintPool = m_tmpSolverContactConstraintPool.size(); @@ -1620,35 +1521,33 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(btCol ///@todo: use stack allocator for such temporarily memory, same for solver bodies/constraints m_orderNonContactConstraintPool.resizeNoInitialize(numNonContactPool); if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) - m_orderTmpConstraintPool.resizeNoInitialize(numConstraintPool*2); + m_orderTmpConstraintPool.resizeNoInitialize(numConstraintPool * 2); else m_orderTmpConstraintPool.resizeNoInitialize(numConstraintPool); m_orderFrictionConstraintPool.resizeNoInitialize(numFrictionPool); { int i; - for (i=0;iisEnabled()) { - btScalar residual = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[constraint.m_solverBodyIdA],m_tmpSolverBodyPool[constraint.m_solverBodyIdB],constraint); - leastSquaresResidual = btMax(leastSquaresResidual, residual*residual); + int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA(), infoGlobal.m_timeStep); + int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB(), infoGlobal.m_timeStep); + btSolverBody& bodyA = m_tmpSolverBodyPool[bodyAid]; + btSolverBody& bodyB = m_tmpSolverBodyPool[bodyBid]; + constraints[j]->solveConstraintObsolete(bodyA, bodyB, infoGlobal.m_timeStep); } } - if (iteration< infoGlobal.m_numIterations) + ///solve all contact constraints + if (infoGlobal.m_solverMode & SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS) { - for (int j=0;jisEnabled()) + btScalar totalImpulse = 0; + { - int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA(),infoGlobal.m_timeStep); - int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB(),infoGlobal.m_timeStep); - btSolverBody& bodyA = m_tmpSolverBodyPool[bodyAid]; - btSolverBody& bodyB = m_tmpSolverBodyPool[bodyBid]; - constraints[j]->solveConstraintObsolete(bodyA,bodyB,infoGlobal.m_timeStep); + const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[c]]; + btScalar residual = resolveSingleConstraintRowLowerLimit(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold); + leastSquaresResidual = btMax(leastSquaresResidual, residual * residual); + + totalImpulse = solveManifold.m_appliedImpulse; } - } - - ///solve all contact constraints - if (infoGlobal.m_solverMode & SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS) - { - int numPoolConstraints = m_tmpSolverContactConstraintPool.size(); - int multiplier = (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)? 2 : 1; - - for (int c=0;c btScalar(0)) { + solveManifold.m_lowerLimit = -(solveManifold.m_friction * totalImpulse); + solveManifold.m_upperLimit = solveManifold.m_friction * totalImpulse; - btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[c*multiplier]]; - - if (totalImpulse>btScalar(0)) - { - solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse); - solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse; - - btScalar residual = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold); - leastSquaresResidual = btMax(leastSquaresResidual, residual*residual); - } + btScalar residual = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold); + leastSquaresResidual = btMax(leastSquaresResidual, residual * residual); } + } - if (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) + if (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) + { + btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[c * multiplier + 1]]; + + if (totalImpulse > btScalar(0)) { + solveManifold.m_lowerLimit = -(solveManifold.m_friction * totalImpulse); + solveManifold.m_upperLimit = solveManifold.m_friction * totalImpulse; - btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[c*multiplier+1]]; - - if (totalImpulse>btScalar(0)) - { - solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse); - solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse; - - btScalar residual = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold); - leastSquaresResidual = btMax(leastSquaresResidual, residual*residual); - } + btScalar residual = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold); + leastSquaresResidual = btMax(leastSquaresResidual, residual * residual); } } } - } - else//SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS - { - //solve the friction constraints after all contact constraints, don't interleave them - int numPoolConstraints = m_tmpSolverContactConstraintPool.size(); - int j; - - for (j=0;jbtScalar(0)) - { - solveManifold.m_lowerLimit = -(solveManifold.m_friction*totalImpulse); - solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse; - - btScalar residual = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA],m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB],solveManifold); - leastSquaresResidual = btMax(leastSquaresResidual, residual*residual); - } - } - } - - - int numRollingFrictionPoolConstraints = m_tmpSolverContactRollingFrictionConstraintPool.size(); - for (int j=0;jbtScalar(0)) - { - btScalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction*totalImpulse; - if (rollingFrictionMagnitude>rollingFrictionConstraint.m_friction) - rollingFrictionMagnitude = rollingFrictionConstraint.m_friction; - - rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude; - rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude; - - btScalar residual = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA],m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB],rollingFrictionConstraint); - leastSquaresResidual = btMax(leastSquaresResidual, residual*residual); - } - } - - } + else //SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS + { + //solve the friction constraints after all contact constraints, don't interleave them + int numPoolConstraints = m_tmpSolverContactConstraintPool.size(); + int j; + + for (j = 0; j < numPoolConstraints; j++) + { + const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[m_orderTmpConstraintPool[j]]; + btScalar residual = resolveSingleConstraintRowLowerLimit(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold); + leastSquaresResidual = btMax(leastSquaresResidual, residual * residual); + } + + ///solve all friction constraints + + int numFrictionPoolConstraints = m_tmpSolverContactFrictionConstraintPool.size(); + for (j = 0; j < numFrictionPoolConstraints; j++) + { + btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[m_orderFrictionConstraintPool[j]]; + btScalar totalImpulse = m_tmpSolverContactConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse; + + if (totalImpulse > btScalar(0)) + { + solveManifold.m_lowerLimit = -(solveManifold.m_friction * totalImpulse); + solveManifold.m_upperLimit = solveManifold.m_friction * totalImpulse; + + btScalar residual = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold); + leastSquaresResidual = btMax(leastSquaresResidual, residual * residual); + } + } + } + + int numRollingFrictionPoolConstraints = m_tmpSolverContactRollingFrictionConstraintPool.size(); + for (int j = 0; j < numRollingFrictionPoolConstraints; j++) + { + btSolverConstraint& rollingFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[j]; + btScalar totalImpulse = m_tmpSolverContactConstraintPool[rollingFrictionConstraint.m_frictionIndex].m_appliedImpulse; + if (totalImpulse > btScalar(0)) + { + btScalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction * totalImpulse; + if (rollingFrictionMagnitude > rollingFrictionConstraint.m_friction) + rollingFrictionMagnitude = rollingFrictionConstraint.m_friction; + + rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude; + rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude; + + btScalar residual = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA], m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB], rollingFrictionConstraint); + leastSquaresResidual = btMax(leastSquaresResidual, residual * residual); + } + } + } return leastSquaresResidual; } - -void btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer) +void btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer) { BT_PROFILE("solveGroupCacheFriendlySplitImpulseIterations"); int iteration; if (infoGlobal.m_splitImpulse) { { - for ( iteration = 0;iteration=(infoGlobal.m_numIterations-1)) + if (leastSquaresResidual <= infoGlobal.m_leastSquaresResidualThreshold || iteration >= (infoGlobal.m_numIterations - 1)) { #ifdef VERBOSE_RESIDUAL_PRINTF - printf("residual = %f at iteration #%d\n",leastSquaresResidual,iteration); + printf("residual = %f at iteration #%d\n", leastSquaresResidual, iteration); #endif break; } } - } + } } } -btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer) +btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyIterations(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer) { BT_PROFILE("solveGroupCacheFriendlyIterations"); { ///this is a special step to resolve penetrations (just for contacts) - solveGroupCacheFriendlySplitImpulseIterations(bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer); + solveGroupCacheFriendlySplitImpulseIterations(bodies, numBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal, debugDrawer); - int maxIterations = m_maxOverrideNumSolverIterations > infoGlobal.m_numIterations? m_maxOverrideNumSolverIterations : infoGlobal.m_numIterations; + int maxIterations = m_maxOverrideNumSolverIterations > infoGlobal.m_numIterations ? m_maxOverrideNumSolverIterations : infoGlobal.m_numIterations; - for ( int iteration = 0 ; iteration< maxIterations ; iteration++) + for (int iteration = 0; iteration < maxIterations; iteration++) //for ( int iteration = maxIterations-1 ; iteration >= 0;iteration--) { - m_leastSquaresResidual = solveSingleIteration(iteration, bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer); + m_leastSquaresResidual = solveSingleIteration(iteration, bodies, numBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal, debugDrawer); - if (m_leastSquaresResidual <= infoGlobal.m_leastSquaresResidualThreshold || (iteration>= (maxIterations-1))) + if (m_leastSquaresResidual <= infoGlobal.m_leastSquaresResidualThreshold || (iteration >= (maxIterations - 1))) { #ifdef VERBOSE_RESIDUAL_PRINTF - printf("residual = %f at iteration #%d\n",m_leastSquaresResidual,iteration); + printf("residual = %f at iteration #%d\n", m_leastSquaresResidual, iteration); #endif break; } } - } return 0.f; } void btSequentialImpulseConstraintSolver::writeBackContacts(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal) { - for (int j=iBegin; jm_appliedImpulse = solveManifold.m_appliedImpulse; + for (int j = iBegin; j < iEnd; j++) + { + const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[j]; + btManifoldPoint* pt = (btManifoldPoint*)solveManifold.m_originalContactPoint; + btAssert(pt); + pt->m_appliedImpulse = solveManifold.m_appliedImpulse; // float f = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse; - // printf("pt->m_appliedImpulseLateral1 = %f\n", f); - pt->m_appliedImpulseLateral1 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse; - //printf("pt->m_appliedImpulseLateral1 = %f\n", pt->m_appliedImpulseLateral1); - if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) - { - pt->m_appliedImpulseLateral2 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex+1].m_appliedImpulse; - } - //do a callback here? + // printf("pt->m_appliedImpulseLateral1 = %f\n", f); + pt->m_appliedImpulseLateral1 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex].m_appliedImpulse; + //printf("pt->m_appliedImpulseLateral1 = %f\n", pt->m_appliedImpulseLateral1); + if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) + { + pt->m_appliedImpulseLateral2 = m_tmpSolverContactFrictionConstraintPool[solveManifold.m_frictionIndex + 1].m_appliedImpulse; } + //do a callback here? + } } void btSequentialImpulseConstraintSolver::writeBackJoints(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal) { - for (int j=iBegin; jgetJointFeedback(); if (fb) { - fb->m_appliedForceBodyA += solverConstr.m_contactNormal1*solverConstr.m_appliedImpulse*constr->getRigidBodyA().getLinearFactor()/infoGlobal.m_timeStep; - fb->m_appliedForceBodyB += solverConstr.m_contactNormal2*solverConstr.m_appliedImpulse*constr->getRigidBodyB().getLinearFactor()/infoGlobal.m_timeStep; - fb->m_appliedTorqueBodyA += solverConstr.m_relpos1CrossNormal* constr->getRigidBodyA().getAngularFactor()*solverConstr.m_appliedImpulse/infoGlobal.m_timeStep; - fb->m_appliedTorqueBodyB += solverConstr.m_relpos2CrossNormal* constr->getRigidBodyB().getAngularFactor()*solverConstr.m_appliedImpulse/infoGlobal.m_timeStep; /*RGM ???? */ - + fb->m_appliedForceBodyA += solverConstr.m_contactNormal1 * solverConstr.m_appliedImpulse * constr->getRigidBodyA().getLinearFactor() / infoGlobal.m_timeStep; + fb->m_appliedForceBodyB += solverConstr.m_contactNormal2 * solverConstr.m_appliedImpulse * constr->getRigidBodyB().getLinearFactor() / infoGlobal.m_timeStep; + fb->m_appliedTorqueBodyA += solverConstr.m_relpos1CrossNormal * constr->getRigidBodyA().getAngularFactor() * solverConstr.m_appliedImpulse / infoGlobal.m_timeStep; + fb->m_appliedTorqueBodyB += solverConstr.m_relpos2CrossNormal * constr->getRigidBodyB().getAngularFactor() * solverConstr.m_appliedImpulse / infoGlobal.m_timeStep; /*RGM ???? */ } constr->internalSetAppliedImpulse(solverConstr.m_appliedImpulse); - if (btFabs(solverConstr.m_appliedImpulse)>=constr->getBreakingImpulseThreshold()) + if (btFabs(solverConstr.m_appliedImpulse) >= constr->getBreakingImpulseThreshold()) { constr->setEnabled(false); } } } - void btSequentialImpulseConstraintSolver::writeBackBodies(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal) { - for (int i=iBegin; isetLinearVelocity( - m_tmpSolverBodyPool[i].m_linearVelocity+ + m_tmpSolverBodyPool[i].m_linearVelocity + m_tmpSolverBodyPool[i].m_externalForceImpulse); m_tmpSolverBodyPool[i].m_originalBody->setAngularVelocity( - m_tmpSolverBodyPool[i].m_angularVelocity+ + m_tmpSolverBodyPool[i].m_angularVelocity + m_tmpSolverBodyPool[i].m_externalTorqueImpulse); if (infoGlobal.m_splitImpulse) @@ -1959,17 +1847,17 @@ void btSequentialImpulseConstraintSolver::writeBackBodies(int iBegin, int iEnd, } } -btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinish(btCollisionObject** bodies,int numBodies,const btContactSolverInfo& infoGlobal) +btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinish(btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal) { BT_PROFILE("solveGroupCacheFriendlyFinish"); if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) { - writeBackContacts(0, m_tmpSolverContactConstraintPool.size(), infoGlobal); + writeBackContacts(0, m_tmpSolverContactConstraintPool.size(), infoGlobal); } - writeBackJoints(0, m_tmpSolverNonContactConstraintPool.size(), infoGlobal); - writeBackBodies(0, m_tmpSolverBodyPool.size(), infoGlobal); + writeBackJoints(0, m_tmpSolverNonContactConstraintPool.size(), infoGlobal); + writeBackBodies(0, m_tmpSolverBodyPool.size(), infoGlobal); m_tmpSolverContactConstraintPool.resizeNoInitialize(0); m_tmpSolverNonContactConstraintPool.resizeNoInitialize(0); @@ -1980,25 +1868,22 @@ btScalar btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinish(btCo return 0.f; } - - /// btSequentialImpulseConstraintSolver Sequentially applies impulses -btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer,btDispatcher* /*dispatcher*/) +btScalar btSequentialImpulseConstraintSolver::solveGroup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer, btDispatcher* /*dispatcher*/) { - BT_PROFILE("solveGroup"); //you need to provide at least some bodies - solveGroupCacheFriendlySetup( bodies, numBodies, manifoldPtr, numManifolds,constraints, numConstraints,infoGlobal,debugDrawer); + solveGroupCacheFriendlySetup(bodies, numBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal, debugDrawer); - solveGroupCacheFriendlyIterations(bodies, numBodies, manifoldPtr, numManifolds,constraints, numConstraints,infoGlobal,debugDrawer); + solveGroupCacheFriendlyIterations(bodies, numBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal, debugDrawer); solveGroupCacheFriendlyFinish(bodies, numBodies, infoGlobal); return 0.f; } -void btSequentialImpulseConstraintSolver::reset() +void btSequentialImpulseConstraintSolver::reset() { m_btSeed2 = 0; } diff --git a/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h b/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h index b834c3dac..70db83b06 100644 --- a/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h +++ b/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h @@ -27,147 +27,142 @@ class btCollisionObject; #include "BulletCollision/NarrowPhaseCollision/btManifoldPoint.h" #include "BulletDynamics/ConstraintSolver/btConstraintSolver.h" -typedef btScalar(*btSingleConstraintRowSolver)(btSolverBody&, btSolverBody&, const btSolverConstraint&); +typedef btScalar (*btSingleConstraintRowSolver)(btSolverBody&, btSolverBody&, const btSolverConstraint&); ///The btSequentialImpulseConstraintSolver is a fast SIMD implementation of the Projected Gauss Seidel (iterative LCP) method. -ATTRIBUTE_ALIGNED16(class) btSequentialImpulseConstraintSolver : public btConstraintSolver +ATTRIBUTE_ALIGNED16(class) +btSequentialImpulseConstraintSolver : public btConstraintSolver { protected: - btAlignedObjectArray m_tmpSolverBodyPool; - btConstraintArray m_tmpSolverContactConstraintPool; - btConstraintArray m_tmpSolverNonContactConstraintPool; - btConstraintArray m_tmpSolverContactFrictionConstraintPool; - btConstraintArray m_tmpSolverContactRollingFrictionConstraintPool; + btAlignedObjectArray m_tmpSolverBodyPool; + btConstraintArray m_tmpSolverContactConstraintPool; + btConstraintArray m_tmpSolverNonContactConstraintPool; + btConstraintArray m_tmpSolverContactFrictionConstraintPool; + btConstraintArray m_tmpSolverContactRollingFrictionConstraintPool; - btAlignedObjectArray m_orderTmpConstraintPool; - btAlignedObjectArray m_orderNonContactConstraintPool; - btAlignedObjectArray m_orderFrictionConstraintPool; + btAlignedObjectArray m_orderTmpConstraintPool; + btAlignedObjectArray m_orderNonContactConstraintPool; + btAlignedObjectArray m_orderFrictionConstraintPool; btAlignedObjectArray m_tmpConstraintSizesPool; - int m_maxOverrideNumSolverIterations; + int m_maxOverrideNumSolverIterations; int m_fixedBodyId; - // When running solvers on multiple threads, a race condition exists for Kinematic objects that - // participate in more than one solver. - // The getOrInitSolverBody() function writes the companionId of each body (storing the index of the solver body - // for the current solver). For normal dynamic bodies it isn't an issue because they can only be in one island - // (and therefore one thread) at a time. But kinematic bodies can be in multiple islands at once. - // To avoid this race condition, this solver does not write the companionId, instead it stores the solver body - // index in this solver-local table, indexed by the uniqueId of the body. - btAlignedObjectArray m_kinematicBodyUniqueIdToSolverBodyTable; // only used for multithreading + // When running solvers on multiple threads, a race condition exists for Kinematic objects that + // participate in more than one solver. + // The getOrInitSolverBody() function writes the companionId of each body (storing the index of the solver body + // for the current solver). For normal dynamic bodies it isn't an issue because they can only be in one island + // (and therefore one thread) at a time. But kinematic bodies can be in multiple islands at once. + // To avoid this race condition, this solver does not write the companionId, instead it stores the solver body + // index in this solver-local table, indexed by the uniqueId of the body. + btAlignedObjectArray m_kinematicBodyUniqueIdToSolverBodyTable; // only used for multithreading btSingleConstraintRowSolver m_resolveSingleConstraintRowGeneric; btSingleConstraintRowSolver m_resolveSingleConstraintRowLowerLimit; - btSingleConstraintRowSolver m_resolveSplitPenetrationImpulse; - int m_cachedSolverMode; // used to check if SOLVER_SIMD flag has been changed - void setupSolverFunctions( bool useSimd ); + btSingleConstraintRowSolver m_resolveSplitPenetrationImpulse; + int m_cachedSolverMode; // used to check if SOLVER_SIMD flag has been changed + void setupSolverFunctions(bool useSimd); - btScalar m_leastSquaresResidual; + btScalar m_leastSquaresResidual; - void setupFrictionConstraint( btSolverConstraint& solverConstraint, const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB, - btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2, - btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, - const btContactSolverInfo& infoGlobal, - btScalar desiredVelocity=0., btScalar cfmSlip=0.); + void setupFrictionConstraint(btSolverConstraint & solverConstraint, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, + btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2, + btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, + const btContactSolverInfo& infoGlobal, + btScalar desiredVelocity = 0., btScalar cfmSlip = 0.); - void setupTorsionalFrictionConstraint( btSolverConstraint& solverConstraint, const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB, - btManifoldPoint& cp,btScalar combinedTorsionalFriction, const btVector3& rel_pos1,const btVector3& rel_pos2, - btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, - btScalar desiredVelocity=0., btScalar cfmSlip=0.); + void setupTorsionalFrictionConstraint(btSolverConstraint & solverConstraint, const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, + btManifoldPoint& cp, btScalar combinedTorsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2, + btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, + btScalar desiredVelocity = 0., btScalar cfmSlip = 0.); - btSolverConstraint& addFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity=0., btScalar cfmSlip=0.); - btSolverConstraint& addTorsionalFrictionConstraint(const btVector3& normalAxis,int solverBodyIdA,int solverBodyIdB,int frictionIndex,btManifoldPoint& cp,btScalar torsionalFriction, const btVector3& rel_pos1,const btVector3& rel_pos2,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity=0, btScalar cfmSlip=0.f); + btSolverConstraint& addFrictionConstraint(const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint& cp, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity = 0., btScalar cfmSlip = 0.); + btSolverConstraint& addTorsionalFrictionConstraint(const btVector3& normalAxis, int solverBodyIdA, int solverBodyIdB, int frictionIndex, btManifoldPoint& cp, btScalar torsionalFriction, const btVector3& rel_pos1, const btVector3& rel_pos2, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, btScalar desiredVelocity = 0, btScalar cfmSlip = 0.f); + void setupContactConstraint(btSolverConstraint & solverConstraint, int solverBodyIdA, int solverBodyIdB, btManifoldPoint& cp, + const btContactSolverInfo& infoGlobal, btScalar& relaxation, const btVector3& rel_pos1, const btVector3& rel_pos2); - void setupContactConstraint(btSolverConstraint& solverConstraint, int solverBodyIdA, int solverBodyIdB, btManifoldPoint& cp, - const btContactSolverInfo& infoGlobal,btScalar& relaxation, const btVector3& rel_pos1, const btVector3& rel_pos2); + static void applyAnisotropicFriction(btCollisionObject * colObj, btVector3 & frictionDirection, int frictionMode); - static void applyAnisotropicFriction(btCollisionObject* colObj,btVector3& frictionDirection, int frictionMode); - - void setFrictionConstraintImpulse( btSolverConstraint& solverConstraint, int solverBodyIdA,int solverBodyIdB, - btManifoldPoint& cp, const btContactSolverInfo& infoGlobal); + void setFrictionConstraintImpulse(btSolverConstraint & solverConstraint, int solverBodyIdA, int solverBodyIdB, + btManifoldPoint& cp, const btContactSolverInfo& infoGlobal); ///m_btSeed2 is used for re-arranging the constraint rows. improves convergence/quality of friction - unsigned long m_btSeed2; - + unsigned long m_btSeed2; btScalar restitutionCurve(btScalar rel_vel, btScalar restitution, btScalar velocityThreshold); - virtual void convertContacts(btPersistentManifold** manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal); + virtual void convertContacts(btPersistentManifold * *manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal); - void convertContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal); + void convertContact(btPersistentManifold * manifold, const btContactSolverInfo& infoGlobal); - virtual void convertJoints(btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal); - void convertJoint(btSolverConstraint* currentConstraintRow, btTypedConstraint* constraint, const btTypedConstraint::btConstraintInfo1& info1, int solverBodyIdA, int solverBodyIdB, const btContactSolverInfo& infoGlobal); + virtual void convertJoints(btTypedConstraint * *constraints, int numConstraints, const btContactSolverInfo& infoGlobal); + void convertJoint(btSolverConstraint * currentConstraintRow, btTypedConstraint * constraint, const btTypedConstraint::btConstraintInfo1& info1, int solverBodyIdA, int solverBodyIdB, const btContactSolverInfo& infoGlobal); - virtual void convertBodies(btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal); + virtual void convertBodies(btCollisionObject * *bodies, int numBodies, const btContactSolverInfo& infoGlobal); - btScalar resolveSplitPenetrationSIMD(btSolverBody& bodyA,btSolverBody& bodyB, const btSolverConstraint& contactConstraint) - { - return m_resolveSplitPenetrationImpulse( bodyA, bodyB, contactConstraint ); - } + btScalar resolveSplitPenetrationSIMD(btSolverBody & bodyA, btSolverBody & bodyB, const btSolverConstraint& contactConstraint) + { + return m_resolveSplitPenetrationImpulse(bodyA, bodyB, contactConstraint); + } - btScalar resolveSplitPenetrationImpulseCacheFriendly(btSolverBody& bodyA,btSolverBody& bodyB, const btSolverConstraint& contactConstraint) - { - return m_resolveSplitPenetrationImpulse( bodyA, bodyB, contactConstraint ); - } + btScalar resolveSplitPenetrationImpulseCacheFriendly(btSolverBody & bodyA, btSolverBody & bodyB, const btSolverConstraint& contactConstraint) + { + return m_resolveSplitPenetrationImpulse(bodyA, bodyB, contactConstraint); + } //internal method - int getOrInitSolverBody(btCollisionObject& body,btScalar timeStep); - void initSolverBody(btSolverBody* solverBody, btCollisionObject* collisionObject, btScalar timeStep); + int getOrInitSolverBody(btCollisionObject & body, btScalar timeStep); + void initSolverBody(btSolverBody * solverBody, btCollisionObject * collisionObject, btScalar timeStep); - btScalar resolveSingleConstraintRowGeneric(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& contactConstraint); - btScalar resolveSingleConstraintRowGenericSIMD(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& contactConstraint); - btScalar resolveSingleConstraintRowLowerLimit(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& contactConstraint); - btScalar resolveSingleConstraintRowLowerLimitSIMD(btSolverBody& bodyA,btSolverBody& bodyB,const btSolverConstraint& contactConstraint); - btScalar resolveSplitPenetrationImpulse(btSolverBody& bodyA,btSolverBody& bodyB, const btSolverConstraint& contactConstraint) - { - return m_resolveSplitPenetrationImpulse( bodyA, bodyB, contactConstraint ); - } + btScalar resolveSingleConstraintRowGeneric(btSolverBody & bodyA, btSolverBody & bodyB, const btSolverConstraint& contactConstraint); + btScalar resolveSingleConstraintRowGenericSIMD(btSolverBody & bodyA, btSolverBody & bodyB, const btSolverConstraint& contactConstraint); + btScalar resolveSingleConstraintRowLowerLimit(btSolverBody & bodyA, btSolverBody & bodyB, const btSolverConstraint& contactConstraint); + btScalar resolveSingleConstraintRowLowerLimitSIMD(btSolverBody & bodyA, btSolverBody & bodyB, const btSolverConstraint& contactConstraint); + btScalar resolveSplitPenetrationImpulse(btSolverBody & bodyA, btSolverBody & bodyB, const btSolverConstraint& contactConstraint) + { + return m_resolveSplitPenetrationImpulse(bodyA, bodyB, contactConstraint); + } protected: + void writeBackContacts(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal); + void writeBackJoints(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal); + void writeBackBodies(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal); + virtual void solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer); + virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject * *bodies, int numBodies, const btContactSolverInfo& infoGlobal); + virtual btScalar solveSingleIteration(int iteration, btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer); - void writeBackContacts(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal); - void writeBackJoints(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal); - void writeBackBodies(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal); - virtual void solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer); - virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject** bodies,int numBodies,const btContactSolverInfo& infoGlobal); - virtual btScalar solveSingleIteration(int iteration, btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer); - - virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer); - virtual btScalar solveGroupCacheFriendlyIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer); - + virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer); + virtual btScalar solveGroupCacheFriendlyIterations(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer); public: - BT_DECLARE_ALIGNED_ALLOCATOR(); btSequentialImpulseConstraintSolver(); virtual ~btSequentialImpulseConstraintSolver(); - virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer,btDispatcher* dispatcher); + virtual btScalar solveGroup(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifold, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btDispatcher* dispatcher); ///clear internal cached data and reset random seed - virtual void reset(); + virtual void reset(); unsigned long btRand2(); - int btRandInt2 (int n); + int btRandInt2(int n); - void setRandSeed(unsigned long seed) + void setRandSeed(unsigned long seed) { m_btSeed2 = seed; } - unsigned long getRandSeed() const + unsigned long getRandSeed() const { return m_btSeed2; } - - virtual btConstraintSolverType getSolverType() const + virtual btConstraintSolverType getSolverType() const { return BT_SEQUENTIAL_IMPULSE_SOLVER; } - btSingleConstraintRowSolver getActiveConstraintRowSolverGeneric() + btSingleConstraintRowSolver getActiveConstraintRowSolverGeneric() { return m_resolveSingleConstraintRowGeneric; } @@ -175,7 +170,7 @@ public: { m_resolveSingleConstraintRowGeneric = rowSolver; } - btSingleConstraintRowSolver getActiveConstraintRowSolverLowerLimit() + btSingleConstraintRowSolver getActiveConstraintRowSolverLowerLimit() { return m_resolveSingleConstraintRowLowerLimit; } @@ -185,18 +180,14 @@ public: } ///Various implementations of solving a single constraint row using a generic equality constraint, using scalar reference, SSE2 or SSE4 - btSingleConstraintRowSolver getScalarConstraintRowSolverGeneric(); - btSingleConstraintRowSolver getSSE2ConstraintRowSolverGeneric(); - btSingleConstraintRowSolver getSSE4_1ConstraintRowSolverGeneric(); + btSingleConstraintRowSolver getScalarConstraintRowSolverGeneric(); + btSingleConstraintRowSolver getSSE2ConstraintRowSolverGeneric(); + btSingleConstraintRowSolver getSSE4_1ConstraintRowSolverGeneric(); ///Various implementations of solving a single constraint row using an inequality (lower limit) constraint, using scalar reference, SSE2 or SSE4 - btSingleConstraintRowSolver getScalarConstraintRowSolverLowerLimit(); - btSingleConstraintRowSolver getSSE2ConstraintRowSolverLowerLimit(); - btSingleConstraintRowSolver getSSE4_1ConstraintRowSolverLowerLimit(); + btSingleConstraintRowSolver getScalarConstraintRowSolverLowerLimit(); + btSingleConstraintRowSolver getSSE2ConstraintRowSolverLowerLimit(); + btSingleConstraintRowSolver getSSE4_1ConstraintRowSolverLowerLimit(); }; - - - -#endif //BT_SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H - +#endif //BT_SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_H diff --git a/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolverMt.cpp b/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolverMt.cpp index 4306c37e4..2718da4a5 100644 --- a/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolverMt.cpp +++ b/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolverMt.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btSequentialImpulseConstraintSolverMt.h" #include "LinearMath/btQuickprof.h" @@ -23,8 +22,6 @@ subject to the following restrictions: #include "BulletDynamics/ConstraintSolver/btTypedConstraint.h" #include "BulletDynamics/Dynamics/btRigidBody.h" - - bool btSequentialImpulseConstraintSolverMt::s_allowNestedParallelForLoops = false; // some task schedulers don't like nested loops int btSequentialImpulseConstraintSolverMt::s_minimumContactManifoldsForBatching = 250; int btSequentialImpulseConstraintSolverMt::s_minBatchSize = 50; @@ -32,613 +29,594 @@ int btSequentialImpulseConstraintSolverMt::s_maxBatchSize = 100; btBatchedConstraints::BatchingMethod btSequentialImpulseConstraintSolverMt::s_contactBatchingMethod = btBatchedConstraints::BATCHING_METHOD_SPATIAL_GRID_2D; btBatchedConstraints::BatchingMethod btSequentialImpulseConstraintSolverMt::s_jointBatchingMethod = btBatchedConstraints::BATCHING_METHOD_SPATIAL_GRID_2D; - btSequentialImpulseConstraintSolverMt::btSequentialImpulseConstraintSolverMt() { - m_numFrictionDirections = 1; - m_useBatching = false; - m_useObsoleteJointConstraints = false; + m_numFrictionDirections = 1; + m_useBatching = false; + m_useObsoleteJointConstraints = false; } - btSequentialImpulseConstraintSolverMt::~btSequentialImpulseConstraintSolverMt() { } - void btSequentialImpulseConstraintSolverMt::setupBatchedContactConstraints() { - BT_PROFILE("setupBatchedContactConstraints"); - m_batchedContactConstraints.setup( &m_tmpSolverContactConstraintPool, - m_tmpSolverBodyPool, - s_contactBatchingMethod, - s_minBatchSize, - s_maxBatchSize, - &m_scratchMemory - ); + BT_PROFILE("setupBatchedContactConstraints"); + m_batchedContactConstraints.setup(&m_tmpSolverContactConstraintPool, + m_tmpSolverBodyPool, + s_contactBatchingMethod, + s_minBatchSize, + s_maxBatchSize, + &m_scratchMemory); } - void btSequentialImpulseConstraintSolverMt::setupBatchedJointConstraints() { - BT_PROFILE("setupBatchedJointConstraints"); - m_batchedJointConstraints.setup( &m_tmpSolverNonContactConstraintPool, - m_tmpSolverBodyPool, - s_jointBatchingMethod, - s_minBatchSize, - s_maxBatchSize, - &m_scratchMemory - ); + BT_PROFILE("setupBatchedJointConstraints"); + m_batchedJointConstraints.setup(&m_tmpSolverNonContactConstraintPool, + m_tmpSolverBodyPool, + s_jointBatchingMethod, + s_minBatchSize, + s_maxBatchSize, + &m_scratchMemory); } - void btSequentialImpulseConstraintSolverMt::internalSetupContactConstraints(int iContactConstraint, const btContactSolverInfo& infoGlobal) { - btSolverConstraint& contactConstraint = m_tmpSolverContactConstraintPool[iContactConstraint]; + btSolverConstraint& contactConstraint = m_tmpSolverContactConstraintPool[iContactConstraint]; - btVector3 rel_pos1; - btVector3 rel_pos2; - btScalar relaxation; + btVector3 rel_pos1; + btVector3 rel_pos2; + btScalar relaxation; - int solverBodyIdA = contactConstraint.m_solverBodyIdA; - int solverBodyIdB = contactConstraint.m_solverBodyIdB; + int solverBodyIdA = contactConstraint.m_solverBodyIdA; + int solverBodyIdB = contactConstraint.m_solverBodyIdB; - btSolverBody* solverBodyA = &m_tmpSolverBodyPool[ solverBodyIdA ]; - btSolverBody* solverBodyB = &m_tmpSolverBodyPool[ solverBodyIdB ]; + btSolverBody* solverBodyA = &m_tmpSolverBodyPool[solverBodyIdA]; + btSolverBody* solverBodyB = &m_tmpSolverBodyPool[solverBodyIdB]; - btRigidBody* colObj0 = solverBodyA->m_originalBody; - btRigidBody* colObj1 = solverBodyB->m_originalBody; + btRigidBody* colObj0 = solverBodyA->m_originalBody; + btRigidBody* colObj1 = solverBodyB->m_originalBody; - btManifoldPoint& cp = *static_cast( contactConstraint.m_originalContactPoint ); + btManifoldPoint& cp = *static_cast(contactConstraint.m_originalContactPoint); - const btVector3& pos1 = cp.getPositionWorldOnA(); - const btVector3& pos2 = cp.getPositionWorldOnB(); + const btVector3& pos1 = cp.getPositionWorldOnA(); + const btVector3& pos2 = cp.getPositionWorldOnB(); - rel_pos1 = pos1 - solverBodyA->getWorldTransform().getOrigin(); - rel_pos2 = pos2 - solverBodyB->getWorldTransform().getOrigin(); + rel_pos1 = pos1 - solverBodyA->getWorldTransform().getOrigin(); + rel_pos2 = pos2 - solverBodyB->getWorldTransform().getOrigin(); - btVector3 vel1; - btVector3 vel2; + btVector3 vel1; + btVector3 vel2; - solverBodyA->getVelocityInLocalPointNoDelta( rel_pos1, vel1 ); - solverBodyB->getVelocityInLocalPointNoDelta( rel_pos2, vel2 ); + solverBodyA->getVelocityInLocalPointNoDelta(rel_pos1, vel1); + solverBodyB->getVelocityInLocalPointNoDelta(rel_pos2, vel2); - btVector3 vel = vel1 - vel2; - btScalar rel_vel = cp.m_normalWorldOnB.dot( vel ); + btVector3 vel = vel1 - vel2; + btScalar rel_vel = cp.m_normalWorldOnB.dot(vel); - setupContactConstraint( contactConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal, relaxation, rel_pos1, rel_pos2 ); + setupContactConstraint(contactConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal, relaxation, rel_pos1, rel_pos2); - // setup rolling friction constraints - int rollingFrictionIndex = m_rollingFrictionIndexTable[iContactConstraint]; - if (rollingFrictionIndex >= 0) - { - btSolverConstraint& spinningFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[ rollingFrictionIndex ]; - btAssert( spinningFrictionConstraint.m_frictionIndex == iContactConstraint ); - setupTorsionalFrictionConstraint( spinningFrictionConstraint, - cp.m_normalWorldOnB, - solverBodyIdA, - solverBodyIdB, - cp, - cp.m_combinedSpinningFriction, - rel_pos1, - rel_pos2, - colObj0, - colObj1, - relaxation, - 0.0f, - 0.0f - ); - btVector3 axis[2]; - btPlaneSpace1( cp.m_normalWorldOnB, axis[0], axis[1] ); - axis[0].normalize(); - axis[1].normalize(); + // setup rolling friction constraints + int rollingFrictionIndex = m_rollingFrictionIndexTable[iContactConstraint]; + if (rollingFrictionIndex >= 0) + { + btSolverConstraint& spinningFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[rollingFrictionIndex]; + btAssert(spinningFrictionConstraint.m_frictionIndex == iContactConstraint); + setupTorsionalFrictionConstraint(spinningFrictionConstraint, + cp.m_normalWorldOnB, + solverBodyIdA, + solverBodyIdB, + cp, + cp.m_combinedSpinningFriction, + rel_pos1, + rel_pos2, + colObj0, + colObj1, + relaxation, + 0.0f, + 0.0f); + btVector3 axis[2]; + btPlaneSpace1(cp.m_normalWorldOnB, axis[0], axis[1]); + axis[0].normalize(); + axis[1].normalize(); - applyAnisotropicFriction( colObj0, axis[0], btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION ); - applyAnisotropicFriction( colObj1, axis[0], btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION ); - applyAnisotropicFriction( colObj0, axis[1], btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION ); - applyAnisotropicFriction( colObj1, axis[1], btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION ); - // put the largest axis first - if (axis[1].length2() > axis[0].length2()) - { - btSwap(axis[0], axis[1]); - } - const btScalar kRollingFrictionThreshold = 0.001f; - for (int i = 0; i < 2; ++i) - { - int iRollingFric = rollingFrictionIndex + 1 + i; - btSolverConstraint& rollingFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[ iRollingFric ]; - btAssert(rollingFrictionConstraint.m_frictionIndex == iContactConstraint); - btVector3 dir = axis[i]; - if ( dir.length() > kRollingFrictionThreshold ) - { - setupTorsionalFrictionConstraint( rollingFrictionConstraint, - dir, - solverBodyIdA, - solverBodyIdB, - cp, - cp.m_combinedRollingFriction, - rel_pos1, - rel_pos2, - colObj0, - colObj1, - relaxation, - 0.0f, - 0.0f - ); - } - else - { - rollingFrictionConstraint.m_frictionIndex = -1; // disable constraint - } - } - } + applyAnisotropicFriction(colObj0, axis[0], btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); + applyAnisotropicFriction(colObj1, axis[0], btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); + applyAnisotropicFriction(colObj0, axis[1], btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); + applyAnisotropicFriction(colObj1, axis[1], btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); + // put the largest axis first + if (axis[1].length2() > axis[0].length2()) + { + btSwap(axis[0], axis[1]); + } + const btScalar kRollingFrictionThreshold = 0.001f; + for (int i = 0; i < 2; ++i) + { + int iRollingFric = rollingFrictionIndex + 1 + i; + btSolverConstraint& rollingFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[iRollingFric]; + btAssert(rollingFrictionConstraint.m_frictionIndex == iContactConstraint); + btVector3 dir = axis[i]; + if (dir.length() > kRollingFrictionThreshold) + { + setupTorsionalFrictionConstraint(rollingFrictionConstraint, + dir, + solverBodyIdA, + solverBodyIdB, + cp, + cp.m_combinedRollingFriction, + rel_pos1, + rel_pos2, + colObj0, + colObj1, + relaxation, + 0.0f, + 0.0f); + } + else + { + rollingFrictionConstraint.m_frictionIndex = -1; // disable constraint + } + } + } - // setup friction constraints - // setupFrictionConstraint(solverConstraint, normalAxis, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal, desiredVelocity, cfmSlip); - { - ///Bullet has several options to set the friction directions - ///By default, each contact has only a single friction direction that is recomputed automatically very frame - ///based on the relative linear velocity. - ///If the relative velocity it zero, it will automatically compute a friction direction. + // setup friction constraints + // setupFrictionConstraint(solverConstraint, normalAxis, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal, desiredVelocity, cfmSlip); + { + ///Bullet has several options to set the friction directions + ///By default, each contact has only a single friction direction that is recomputed automatically very frame + ///based on the relative linear velocity. + ///If the relative velocity it zero, it will automatically compute a friction direction. - ///You can also enable two friction directions, using the SOLVER_USE_2_FRICTION_DIRECTIONS. - ///In that case, the second friction direction will be orthogonal to both contact normal and first friction direction. - /// - ///If you choose SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION, then the friction will be independent from the relative projected velocity. - /// - ///The user can manually override the friction directions for certain contacts using a contact callback, - ///and set the cp.m_lateralFrictionInitialized to true - ///In that case, you can set the target relative motion in each friction direction (cp.m_contactMotion1 and cp.m_contactMotion2) - ///this will give a conveyor belt effect - /// - btSolverConstraint* frictionConstraint1 = &m_tmpSolverContactFrictionConstraintPool[contactConstraint.m_frictionIndex]; - btAssert(frictionConstraint1->m_frictionIndex == iContactConstraint); + ///You can also enable two friction directions, using the SOLVER_USE_2_FRICTION_DIRECTIONS. + ///In that case, the second friction direction will be orthogonal to both contact normal and first friction direction. + /// + ///If you choose SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION, then the friction will be independent from the relative projected velocity. + /// + ///The user can manually override the friction directions for certain contacts using a contact callback, + ///and set the cp.m_lateralFrictionInitialized to true + ///In that case, you can set the target relative motion in each friction direction (cp.m_contactMotion1 and cp.m_contactMotion2) + ///this will give a conveyor belt effect + /// + btSolverConstraint* frictionConstraint1 = &m_tmpSolverContactFrictionConstraintPool[contactConstraint.m_frictionIndex]; + btAssert(frictionConstraint1->m_frictionIndex == iContactConstraint); - btSolverConstraint* frictionConstraint2 = NULL; - if ( infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS ) - { - frictionConstraint2 = &m_tmpSolverContactFrictionConstraintPool[contactConstraint.m_frictionIndex + 1]; - btAssert( frictionConstraint2->m_frictionIndex == iContactConstraint ); - } + btSolverConstraint* frictionConstraint2 = NULL; + if (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) + { + frictionConstraint2 = &m_tmpSolverContactFrictionConstraintPool[contactConstraint.m_frictionIndex + 1]; + btAssert(frictionConstraint2->m_frictionIndex == iContactConstraint); + } - if ( !( infoGlobal.m_solverMode & SOLVER_ENABLE_FRICTION_DIRECTION_CACHING ) || !( cp.m_contactPointFlags&BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED ) ) - { - cp.m_lateralFrictionDir1 = vel - cp.m_normalWorldOnB * rel_vel; - btScalar lat_rel_vel = cp.m_lateralFrictionDir1.length2(); - if ( !( infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION ) && lat_rel_vel > SIMD_EPSILON ) - { - cp.m_lateralFrictionDir1 *= 1.f / btSqrt( lat_rel_vel ); - applyAnisotropicFriction( colObj0, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION ); - applyAnisotropicFriction( colObj1, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION ); - setupFrictionConstraint( *frictionConstraint1, cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal ); + if (!(infoGlobal.m_solverMode & SOLVER_ENABLE_FRICTION_DIRECTION_CACHING) || !(cp.m_contactPointFlags & BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED)) + { + cp.m_lateralFrictionDir1 = vel - cp.m_normalWorldOnB * rel_vel; + btScalar lat_rel_vel = cp.m_lateralFrictionDir1.length2(); + if (!(infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION) && lat_rel_vel > SIMD_EPSILON) + { + cp.m_lateralFrictionDir1 *= 1.f / btSqrt(lat_rel_vel); + applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION); + applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION); + setupFrictionConstraint(*frictionConstraint1, cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal); - if ( frictionConstraint2 ) - { - cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross( cp.m_normalWorldOnB ); - cp.m_lateralFrictionDir2.normalize();//?? - applyAnisotropicFriction( colObj0, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION ); - applyAnisotropicFriction( colObj1, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION ); - setupFrictionConstraint( *frictionConstraint2, cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal ); - } - } - else - { - btPlaneSpace1( cp.m_normalWorldOnB, cp.m_lateralFrictionDir1, cp.m_lateralFrictionDir2 ); + if (frictionConstraint2) + { + cp.m_lateralFrictionDir2 = cp.m_lateralFrictionDir1.cross(cp.m_normalWorldOnB); + cp.m_lateralFrictionDir2.normalize(); //?? + applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION); + applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION); + setupFrictionConstraint(*frictionConstraint2, cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal); + } + } + else + { + btPlaneSpace1(cp.m_normalWorldOnB, cp.m_lateralFrictionDir1, cp.m_lateralFrictionDir2); - applyAnisotropicFriction( colObj0, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION ); - applyAnisotropicFriction( colObj1, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION ); - setupFrictionConstraint( *frictionConstraint1, cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal ); + applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION); + applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION); + setupFrictionConstraint(*frictionConstraint1, cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal); - if ( frictionConstraint2 ) - { - applyAnisotropicFriction( colObj0, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION ); - applyAnisotropicFriction( colObj1, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION ); - setupFrictionConstraint( *frictionConstraint2, cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal ); - } + if (frictionConstraint2) + { + applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION); + applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION); + setupFrictionConstraint(*frictionConstraint2, cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal); + } - if ( ( infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS ) && ( infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION ) ) - { - cp.m_contactPointFlags |= BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED; - } - } - } - else - { - setupFrictionConstraint( *frictionConstraint1, cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal, cp.m_contactMotion1, cp.m_frictionCFM ); - if ( frictionConstraint2 ) - { - setupFrictionConstraint( *frictionConstraint2, cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal, cp.m_contactMotion2, cp.m_frictionCFM ); - } - } - } + if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) && (infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION)) + { + cp.m_contactPointFlags |= BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED; + } + } + } + else + { + setupFrictionConstraint(*frictionConstraint1, cp.m_lateralFrictionDir1, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal, cp.m_contactMotion1, cp.m_frictionCFM); + if (frictionConstraint2) + { + setupFrictionConstraint(*frictionConstraint2, cp.m_lateralFrictionDir2, solverBodyIdA, solverBodyIdB, cp, rel_pos1, rel_pos2, colObj0, colObj1, relaxation, infoGlobal, cp.m_contactMotion2, cp.m_frictionCFM); + } + } + } - setFrictionConstraintImpulse( contactConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal ); + setFrictionConstraintImpulse(contactConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal); } - struct SetupContactConstraintsLoop : public btIParallelForBody { - btSequentialImpulseConstraintSolverMt* m_solver; - const btBatchedConstraints* m_bc; - const btContactSolverInfo* m_infoGlobal; + btSequentialImpulseConstraintSolverMt* m_solver; + const btBatchedConstraints* m_bc; + const btContactSolverInfo* m_infoGlobal; - SetupContactConstraintsLoop( btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc, const btContactSolverInfo& infoGlobal ) - { - m_solver = solver; - m_bc = bc; - m_infoGlobal = &infoGlobal; - } - void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - BT_PROFILE( "SetupContactConstraintsLoop" ); - for ( int iBatch = iBegin; iBatch < iEnd; ++iBatch ) - { - const btBatchedConstraints::Range& batch = m_bc->m_batches[ iBatch ]; - for (int i = batch.begin; i < batch.end; ++i) - { - int iContact = m_bc->m_constraintIndices[i]; - m_solver->internalSetupContactConstraints( iContact, *m_infoGlobal ); - } - } - } + SetupContactConstraintsLoop(btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc, const btContactSolverInfo& infoGlobal) + { + m_solver = solver; + m_bc = bc; + m_infoGlobal = &infoGlobal; + } + void forLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + BT_PROFILE("SetupContactConstraintsLoop"); + for (int iBatch = iBegin; iBatch < iEnd; ++iBatch) + { + const btBatchedConstraints::Range& batch = m_bc->m_batches[iBatch]; + for (int i = batch.begin; i < batch.end; ++i) + { + int iContact = m_bc->m_constraintIndices[i]; + m_solver->internalSetupContactConstraints(iContact, *m_infoGlobal); + } + } + } }; - void btSequentialImpulseConstraintSolverMt::setupAllContactConstraints(const btContactSolverInfo& infoGlobal) { - BT_PROFILE( "setupAllContactConstraints" ); - if ( m_useBatching ) - { - const btBatchedConstraints& batchedCons = m_batchedContactConstraints; - SetupContactConstraintsLoop loop( this, &batchedCons, infoGlobal ); - for ( int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase ) - { - int iPhase = batchedCons.m_phaseOrder[ iiPhase ]; - const btBatchedConstraints::Range& phase = batchedCons.m_phases[ iPhase ]; - int grainSize = 1; - btParallelFor( phase.begin, phase.end, grainSize, loop ); - } - } - else - { - for ( int i = 0; i < m_tmpSolverContactConstraintPool.size(); ++i ) - { - internalSetupContactConstraints( i, infoGlobal ); - } - } + BT_PROFILE("setupAllContactConstraints"); + if (m_useBatching) + { + const btBatchedConstraints& batchedCons = m_batchedContactConstraints; + SetupContactConstraintsLoop loop(this, &batchedCons, infoGlobal); + for (int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase) + { + int iPhase = batchedCons.m_phaseOrder[iiPhase]; + const btBatchedConstraints::Range& phase = batchedCons.m_phases[iPhase]; + int grainSize = 1; + btParallelFor(phase.begin, phase.end, grainSize, loop); + } + } + else + { + for (int i = 0; i < m_tmpSolverContactConstraintPool.size(); ++i) + { + internalSetupContactConstraints(i, infoGlobal); + } + } } - -int btSequentialImpulseConstraintSolverMt::getOrInitSolverBodyThreadsafe(btCollisionObject& body,btScalar timeStep) +int btSequentialImpulseConstraintSolverMt::getOrInitSolverBodyThreadsafe(btCollisionObject& body, btScalar timeStep) { - // - // getOrInitSolverBody is threadsafe only for a single thread per solver (with potentially multiple solvers) - // - // getOrInitSolverBodyThreadsafe -- attempts to be fully threadsafe (however may affect determinism) - // - int solverBodyId = -1; - bool isRigidBodyType = btRigidBody::upcast( &body ) != NULL; - if ( isRigidBodyType && !body.isStaticOrKinematicObject() ) - { - // dynamic body - // Dynamic bodies can only be in one island, so it's safe to write to the companionId - solverBodyId = body.getCompanionId(); - if ( solverBodyId < 0 ) - { - m_bodySolverArrayMutex.lock(); - // now that we have the lock, check again - solverBodyId = body.getCompanionId(); - if ( solverBodyId < 0 ) - { - solverBodyId = m_tmpSolverBodyPool.size(); - btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); - initSolverBody( &solverBody, &body, timeStep ); - body.setCompanionId( solverBodyId ); - } - m_bodySolverArrayMutex.unlock(); - } - } - else if (isRigidBodyType && body.isKinematicObject()) - { - // - // NOTE: must test for kinematic before static because some kinematic objects also - // identify as "static" - // - // Kinematic bodies can be in multiple islands at once, so it is a - // race condition to write to them, so we use an alternate method - // to record the solverBodyId - int uniqueId = body.getWorldArrayIndex(); - const int INVALID_SOLVER_BODY_ID = -1; - if (m_kinematicBodyUniqueIdToSolverBodyTable.size() <= uniqueId ) - { - m_kinematicBodyUniqueIdToSolverBodyTableMutex.lock(); - // now that we have the lock, check again - if ( m_kinematicBodyUniqueIdToSolverBodyTable.size() <= uniqueId ) - { - m_kinematicBodyUniqueIdToSolverBodyTable.resize( uniqueId + 1, INVALID_SOLVER_BODY_ID ); - } - m_kinematicBodyUniqueIdToSolverBodyTableMutex.unlock(); - } - solverBodyId = m_kinematicBodyUniqueIdToSolverBodyTable[ uniqueId ]; - // if no table entry yet, - if ( INVALID_SOLVER_BODY_ID == solverBodyId ) - { - // need to acquire both locks - m_kinematicBodyUniqueIdToSolverBodyTableMutex.lock(); - m_bodySolverArrayMutex.lock(); - // now that we have the lock, check again - solverBodyId = m_kinematicBodyUniqueIdToSolverBodyTable[ uniqueId ]; - if ( INVALID_SOLVER_BODY_ID == solverBodyId ) - { - // create a table entry for this body - solverBodyId = m_tmpSolverBodyPool.size(); - btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); - initSolverBody( &solverBody, &body, timeStep ); - m_kinematicBodyUniqueIdToSolverBodyTable[ uniqueId ] = solverBodyId; - } - m_bodySolverArrayMutex.unlock(); - m_kinematicBodyUniqueIdToSolverBodyTableMutex.unlock(); - } - } - else - { - // all fixed bodies (inf mass) get mapped to a single solver id - if ( m_fixedBodyId < 0 ) - { - m_bodySolverArrayMutex.lock(); - // now that we have the lock, check again - if ( m_fixedBodyId < 0 ) - { - m_fixedBodyId = m_tmpSolverBodyPool.size(); - btSolverBody& fixedBody = m_tmpSolverBodyPool.expand(); - initSolverBody( &fixedBody, 0, timeStep ); - } - m_bodySolverArrayMutex.unlock(); - } - solverBodyId = m_fixedBodyId; - } - btAssert( solverBodyId >= 0 && solverBodyId < m_tmpSolverBodyPool.size() ); + // + // getOrInitSolverBody is threadsafe only for a single thread per solver (with potentially multiple solvers) + // + // getOrInitSolverBodyThreadsafe -- attempts to be fully threadsafe (however may affect determinism) + // + int solverBodyId = -1; + bool isRigidBodyType = btRigidBody::upcast(&body) != NULL; + if (isRigidBodyType && !body.isStaticOrKinematicObject()) + { + // dynamic body + // Dynamic bodies can only be in one island, so it's safe to write to the companionId + solverBodyId = body.getCompanionId(); + if (solverBodyId < 0) + { + m_bodySolverArrayMutex.lock(); + // now that we have the lock, check again + solverBodyId = body.getCompanionId(); + if (solverBodyId < 0) + { + solverBodyId = m_tmpSolverBodyPool.size(); + btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); + initSolverBody(&solverBody, &body, timeStep); + body.setCompanionId(solverBodyId); + } + m_bodySolverArrayMutex.unlock(); + } + } + else if (isRigidBodyType && body.isKinematicObject()) + { + // + // NOTE: must test for kinematic before static because some kinematic objects also + // identify as "static" + // + // Kinematic bodies can be in multiple islands at once, so it is a + // race condition to write to them, so we use an alternate method + // to record the solverBodyId + int uniqueId = body.getWorldArrayIndex(); + const int INVALID_SOLVER_BODY_ID = -1; + if (m_kinematicBodyUniqueIdToSolverBodyTable.size() <= uniqueId) + { + m_kinematicBodyUniqueIdToSolverBodyTableMutex.lock(); + // now that we have the lock, check again + if (m_kinematicBodyUniqueIdToSolverBodyTable.size() <= uniqueId) + { + m_kinematicBodyUniqueIdToSolverBodyTable.resize(uniqueId + 1, INVALID_SOLVER_BODY_ID); + } + m_kinematicBodyUniqueIdToSolverBodyTableMutex.unlock(); + } + solverBodyId = m_kinematicBodyUniqueIdToSolverBodyTable[uniqueId]; + // if no table entry yet, + if (INVALID_SOLVER_BODY_ID == solverBodyId) + { + // need to acquire both locks + m_kinematicBodyUniqueIdToSolverBodyTableMutex.lock(); + m_bodySolverArrayMutex.lock(); + // now that we have the lock, check again + solverBodyId = m_kinematicBodyUniqueIdToSolverBodyTable[uniqueId]; + if (INVALID_SOLVER_BODY_ID == solverBodyId) + { + // create a table entry for this body + solverBodyId = m_tmpSolverBodyPool.size(); + btSolverBody& solverBody = m_tmpSolverBodyPool.expand(); + initSolverBody(&solverBody, &body, timeStep); + m_kinematicBodyUniqueIdToSolverBodyTable[uniqueId] = solverBodyId; + } + m_bodySolverArrayMutex.unlock(); + m_kinematicBodyUniqueIdToSolverBodyTableMutex.unlock(); + } + } + else + { + // all fixed bodies (inf mass) get mapped to a single solver id + if (m_fixedBodyId < 0) + { + m_bodySolverArrayMutex.lock(); + // now that we have the lock, check again + if (m_fixedBodyId < 0) + { + m_fixedBodyId = m_tmpSolverBodyPool.size(); + btSolverBody& fixedBody = m_tmpSolverBodyPool.expand(); + initSolverBody(&fixedBody, 0, timeStep); + } + m_bodySolverArrayMutex.unlock(); + } + solverBodyId = m_fixedBodyId; + } + btAssert(solverBodyId >= 0 && solverBodyId < m_tmpSolverBodyPool.size()); return solverBodyId; } - void btSequentialImpulseConstraintSolverMt::internalCollectContactManifoldCachedInfo(btContactManifoldCachedInfo* cachedInfoArray, btPersistentManifold** manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal) { - BT_PROFILE("internalCollectContactManifoldCachedInfo"); - for (int i = 0; i < numManifolds; ++i) - { - btContactManifoldCachedInfo* cachedInfo = &cachedInfoArray[i]; - btPersistentManifold* manifold = manifoldPtr[i]; - btCollisionObject* colObj0 = (btCollisionObject*) manifold->getBody0(); - btCollisionObject* colObj1 = (btCollisionObject*) manifold->getBody1(); + BT_PROFILE("internalCollectContactManifoldCachedInfo"); + for (int i = 0; i < numManifolds; ++i) + { + btContactManifoldCachedInfo* cachedInfo = &cachedInfoArray[i]; + btPersistentManifold* manifold = manifoldPtr[i]; + btCollisionObject* colObj0 = (btCollisionObject*)manifold->getBody0(); + btCollisionObject* colObj1 = (btCollisionObject*)manifold->getBody1(); - int solverBodyIdA = getOrInitSolverBodyThreadsafe( *colObj0, infoGlobal.m_timeStep ); - int solverBodyIdB = getOrInitSolverBodyThreadsafe( *colObj1, infoGlobal.m_timeStep ); + int solverBodyIdA = getOrInitSolverBodyThreadsafe(*colObj0, infoGlobal.m_timeStep); + int solverBodyIdB = getOrInitSolverBodyThreadsafe(*colObj1, infoGlobal.m_timeStep); - cachedInfo->solverBodyIds[ 0 ] = solverBodyIdA; - cachedInfo->solverBodyIds[ 1 ] = solverBodyIdB; - cachedInfo->numTouchingContacts = 0; + cachedInfo->solverBodyIds[0] = solverBodyIdA; + cachedInfo->solverBodyIds[1] = solverBodyIdB; + cachedInfo->numTouchingContacts = 0; - btSolverBody* solverBodyA = &m_tmpSolverBodyPool[ solverBodyIdA ]; - btSolverBody* solverBodyB = &m_tmpSolverBodyPool[ solverBodyIdB ]; + btSolverBody* solverBodyA = &m_tmpSolverBodyPool[solverBodyIdA]; + btSolverBody* solverBodyB = &m_tmpSolverBodyPool[solverBodyIdB]; - // A contact manifold between 2 static object should not exist! - // check the collision flags of your objects if this assert fires. - // Incorrectly set collision object flags can degrade performance in various ways. - btAssert( !m_tmpSolverBodyPool[ solverBodyIdA ].m_invMass.isZero() || !m_tmpSolverBodyPool[ solverBodyIdB ].m_invMass.isZero() ); + // A contact manifold between 2 static object should not exist! + // check the collision flags of your objects if this assert fires. + // Incorrectly set collision object flags can degrade performance in various ways. + btAssert(!m_tmpSolverBodyPool[solverBodyIdA].m_invMass.isZero() || !m_tmpSolverBodyPool[solverBodyIdB].m_invMass.isZero()); - int iContact = 0; - for ( int j = 0; j < manifold->getNumContacts(); j++ ) - { - btManifoldPoint& cp = manifold->getContactPoint( j ); + int iContact = 0; + for (int j = 0; j < manifold->getNumContacts(); j++) + { + btManifoldPoint& cp = manifold->getContactPoint(j); - if ( cp.getDistance() <= manifold->getContactProcessingThreshold() ) - { - cachedInfo->contactPoints[ iContact ] = &cp; - cachedInfo->contactHasRollingFriction[ iContact ] = ( cp.m_combinedRollingFriction > 0.f ); - iContact++; - } - } - cachedInfo->numTouchingContacts = iContact; - } + if (cp.getDistance() <= manifold->getContactProcessingThreshold()) + { + cachedInfo->contactPoints[iContact] = &cp; + cachedInfo->contactHasRollingFriction[iContact] = (cp.m_combinedRollingFriction > 0.f); + iContact++; + } + } + cachedInfo->numTouchingContacts = iContact; + } } - struct CollectContactManifoldCachedInfoLoop : public btIParallelForBody { - btSequentialImpulseConstraintSolverMt* m_solver; - btSequentialImpulseConstraintSolverMt::btContactManifoldCachedInfo* m_cachedInfoArray; - btPersistentManifold** m_manifoldPtr; - const btContactSolverInfo* m_infoGlobal; + btSequentialImpulseConstraintSolverMt* m_solver; + btSequentialImpulseConstraintSolverMt::btContactManifoldCachedInfo* m_cachedInfoArray; + btPersistentManifold** m_manifoldPtr; + const btContactSolverInfo* m_infoGlobal; - CollectContactManifoldCachedInfoLoop( btSequentialImpulseConstraintSolverMt* solver, btSequentialImpulseConstraintSolverMt::btContactManifoldCachedInfo* cachedInfoArray, btPersistentManifold** manifoldPtr, const btContactSolverInfo& infoGlobal ) - { - m_solver = solver; - m_cachedInfoArray = cachedInfoArray; - m_manifoldPtr = manifoldPtr; - m_infoGlobal = &infoGlobal; - } - void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - m_solver->internalCollectContactManifoldCachedInfo( m_cachedInfoArray + iBegin, m_manifoldPtr + iBegin, iEnd - iBegin, *m_infoGlobal ); - } + CollectContactManifoldCachedInfoLoop(btSequentialImpulseConstraintSolverMt* solver, btSequentialImpulseConstraintSolverMt::btContactManifoldCachedInfo* cachedInfoArray, btPersistentManifold** manifoldPtr, const btContactSolverInfo& infoGlobal) + { + m_solver = solver; + m_cachedInfoArray = cachedInfoArray; + m_manifoldPtr = manifoldPtr; + m_infoGlobal = &infoGlobal; + } + void forLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + m_solver->internalCollectContactManifoldCachedInfo(m_cachedInfoArray + iBegin, m_manifoldPtr + iBegin, iEnd - iBegin, *m_infoGlobal); + } }; - void btSequentialImpulseConstraintSolverMt::internalAllocContactConstraints(const btContactManifoldCachedInfo* cachedInfoArray, int numManifolds) { - BT_PROFILE("internalAllocContactConstraints"); - // possibly parallel part - for ( int iManifold = 0; iManifold < numManifolds; ++iManifold ) - { - const btContactManifoldCachedInfo& cachedInfo = cachedInfoArray[ iManifold ]; - int contactIndex = cachedInfo.contactIndex; - int frictionIndex = contactIndex * m_numFrictionDirections; - int rollingFrictionIndex = cachedInfo.rollingFrictionIndex; - for ( int i = 0; i < cachedInfo.numTouchingContacts; i++ ) - { - btSolverConstraint& contactConstraint = m_tmpSolverContactConstraintPool[contactIndex]; - contactConstraint.m_solverBodyIdA = cachedInfo.solverBodyIds[ 0 ]; - contactConstraint.m_solverBodyIdB = cachedInfo.solverBodyIds[ 1 ]; - contactConstraint.m_originalContactPoint = cachedInfo.contactPoints[ i ]; + BT_PROFILE("internalAllocContactConstraints"); + // possibly parallel part + for (int iManifold = 0; iManifold < numManifolds; ++iManifold) + { + const btContactManifoldCachedInfo& cachedInfo = cachedInfoArray[iManifold]; + int contactIndex = cachedInfo.contactIndex; + int frictionIndex = contactIndex * m_numFrictionDirections; + int rollingFrictionIndex = cachedInfo.rollingFrictionIndex; + for (int i = 0; i < cachedInfo.numTouchingContacts; i++) + { + btSolverConstraint& contactConstraint = m_tmpSolverContactConstraintPool[contactIndex]; + contactConstraint.m_solverBodyIdA = cachedInfo.solverBodyIds[0]; + contactConstraint.m_solverBodyIdB = cachedInfo.solverBodyIds[1]; + contactConstraint.m_originalContactPoint = cachedInfo.contactPoints[i]; - // allocate the friction constraints - contactConstraint.m_frictionIndex = frictionIndex; - for ( int iDir = 0; iDir < m_numFrictionDirections; ++iDir ) - { - btSolverConstraint& frictionConstraint = m_tmpSolverContactFrictionConstraintPool[frictionIndex]; - frictionConstraint.m_frictionIndex = contactIndex; - frictionIndex++; - } + // allocate the friction constraints + contactConstraint.m_frictionIndex = frictionIndex; + for (int iDir = 0; iDir < m_numFrictionDirections; ++iDir) + { + btSolverConstraint& frictionConstraint = m_tmpSolverContactFrictionConstraintPool[frictionIndex]; + frictionConstraint.m_frictionIndex = contactIndex; + frictionIndex++; + } - // allocate rolling friction constraints - if ( cachedInfo.contactHasRollingFriction[ i ] ) - { - m_rollingFrictionIndexTable[ contactIndex ] = rollingFrictionIndex; - // allocate 3 (although we may use only 2 sometimes) - for ( int i = 0; i < 3; i++ ) - { - m_tmpSolverContactRollingFrictionConstraintPool[ rollingFrictionIndex ].m_frictionIndex = contactIndex; - rollingFrictionIndex++; - } - } - else - { - // indicate there is no rolling friction for this contact point - m_rollingFrictionIndexTable[ contactIndex ] = -1; - } - contactIndex++; - } - } + // allocate rolling friction constraints + if (cachedInfo.contactHasRollingFriction[i]) + { + m_rollingFrictionIndexTable[contactIndex] = rollingFrictionIndex; + // allocate 3 (although we may use only 2 sometimes) + for (int i = 0; i < 3; i++) + { + m_tmpSolverContactRollingFrictionConstraintPool[rollingFrictionIndex].m_frictionIndex = contactIndex; + rollingFrictionIndex++; + } + } + else + { + // indicate there is no rolling friction for this contact point + m_rollingFrictionIndexTable[contactIndex] = -1; + } + contactIndex++; + } + } } - struct AllocContactConstraintsLoop : public btIParallelForBody { - btSequentialImpulseConstraintSolverMt* m_solver; - const btSequentialImpulseConstraintSolverMt::btContactManifoldCachedInfo* m_cachedInfoArray; + btSequentialImpulseConstraintSolverMt* m_solver; + const btSequentialImpulseConstraintSolverMt::btContactManifoldCachedInfo* m_cachedInfoArray; - AllocContactConstraintsLoop( btSequentialImpulseConstraintSolverMt* solver, btSequentialImpulseConstraintSolverMt::btContactManifoldCachedInfo* cachedInfoArray ) - { - m_solver = solver; - m_cachedInfoArray = cachedInfoArray; - } - void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - m_solver->internalAllocContactConstraints( m_cachedInfoArray + iBegin, iEnd - iBegin ); - } + AllocContactConstraintsLoop(btSequentialImpulseConstraintSolverMt* solver, btSequentialImpulseConstraintSolverMt::btContactManifoldCachedInfo* cachedInfoArray) + { + m_solver = solver; + m_cachedInfoArray = cachedInfoArray; + } + void forLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + m_solver->internalAllocContactConstraints(m_cachedInfoArray + iBegin, iEnd - iBegin); + } }; - void btSequentialImpulseConstraintSolverMt::allocAllContactConstraints(btPersistentManifold** manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal) { - BT_PROFILE( "allocAllContactConstraints" ); - btAlignedObjectArray cachedInfoArray; // = m_manifoldCachedInfoArray; - cachedInfoArray.resizeNoInitialize( numManifolds ); - if (/* DISABLES CODE */ (false)) - { - // sequential - internalCollectContactManifoldCachedInfo(&cachedInfoArray[ 0 ], manifoldPtr, numManifolds, infoGlobal); - } - else - { - // may alter ordering of bodies which affects determinism - CollectContactManifoldCachedInfoLoop loop( this, &cachedInfoArray[ 0 ], manifoldPtr, infoGlobal ); - int grainSize = 200; - btParallelFor( 0, numManifolds, grainSize, loop ); - } + BT_PROFILE("allocAllContactConstraints"); + btAlignedObjectArray cachedInfoArray; // = m_manifoldCachedInfoArray; + cachedInfoArray.resizeNoInitialize(numManifolds); + if (/* DISABLES CODE */ (false)) + { + // sequential + internalCollectContactManifoldCachedInfo(&cachedInfoArray[0], manifoldPtr, numManifolds, infoGlobal); + } + else + { + // may alter ordering of bodies which affects determinism + CollectContactManifoldCachedInfoLoop loop(this, &cachedInfoArray[0], manifoldPtr, infoGlobal); + int grainSize = 200; + btParallelFor(0, numManifolds, grainSize, loop); + } - { - // serial part - int numContacts = 0; - int numRollingFrictionConstraints = 0; - for ( int iManifold = 0; iManifold < numManifolds; ++iManifold ) - { - btContactManifoldCachedInfo& cachedInfo = cachedInfoArray[ iManifold ]; - cachedInfo.contactIndex = numContacts; - cachedInfo.rollingFrictionIndex = numRollingFrictionConstraints; - numContacts += cachedInfo.numTouchingContacts; - for (int i = 0; i < cachedInfo.numTouchingContacts; ++i) - { - if (cachedInfo.contactHasRollingFriction[i]) - { - numRollingFrictionConstraints += 3; - } - } - } - { - BT_PROFILE( "allocPools" ); - if ( m_tmpSolverContactConstraintPool.capacity() < numContacts ) - { - // if we need to reallocate, reserve some extra so we don't have to reallocate again next frame - int extraReserve = numContacts / 16; - m_tmpSolverContactConstraintPool.reserve( numContacts + extraReserve ); - m_rollingFrictionIndexTable.reserve( numContacts + extraReserve ); - m_tmpSolverContactFrictionConstraintPool.reserve( ( numContacts + extraReserve )*m_numFrictionDirections ); - m_tmpSolverContactRollingFrictionConstraintPool.reserve( numRollingFrictionConstraints + extraReserve ); - } - m_tmpSolverContactConstraintPool.resizeNoInitialize( numContacts ); - m_rollingFrictionIndexTable.resizeNoInitialize( numContacts ); - m_tmpSolverContactFrictionConstraintPool.resizeNoInitialize( numContacts*m_numFrictionDirections ); - m_tmpSolverContactRollingFrictionConstraintPool.resizeNoInitialize( numRollingFrictionConstraints ); - } - } - { - AllocContactConstraintsLoop loop(this, &cachedInfoArray[0]); - int grainSize = 200; - btParallelFor( 0, numManifolds, grainSize, loop ); - } + { + // serial part + int numContacts = 0; + int numRollingFrictionConstraints = 0; + for (int iManifold = 0; iManifold < numManifolds; ++iManifold) + { + btContactManifoldCachedInfo& cachedInfo = cachedInfoArray[iManifold]; + cachedInfo.contactIndex = numContacts; + cachedInfo.rollingFrictionIndex = numRollingFrictionConstraints; + numContacts += cachedInfo.numTouchingContacts; + for (int i = 0; i < cachedInfo.numTouchingContacts; ++i) + { + if (cachedInfo.contactHasRollingFriction[i]) + { + numRollingFrictionConstraints += 3; + } + } + } + { + BT_PROFILE("allocPools"); + if (m_tmpSolverContactConstraintPool.capacity() < numContacts) + { + // if we need to reallocate, reserve some extra so we don't have to reallocate again next frame + int extraReserve = numContacts / 16; + m_tmpSolverContactConstraintPool.reserve(numContacts + extraReserve); + m_rollingFrictionIndexTable.reserve(numContacts + extraReserve); + m_tmpSolverContactFrictionConstraintPool.reserve((numContacts + extraReserve) * m_numFrictionDirections); + m_tmpSolverContactRollingFrictionConstraintPool.reserve(numRollingFrictionConstraints + extraReserve); + } + m_tmpSolverContactConstraintPool.resizeNoInitialize(numContacts); + m_rollingFrictionIndexTable.resizeNoInitialize(numContacts); + m_tmpSolverContactFrictionConstraintPool.resizeNoInitialize(numContacts * m_numFrictionDirections); + m_tmpSolverContactRollingFrictionConstraintPool.resizeNoInitialize(numRollingFrictionConstraints); + } + } + { + AllocContactConstraintsLoop loop(this, &cachedInfoArray[0]); + int grainSize = 200; + btParallelFor(0, numManifolds, grainSize, loop); + } } - void btSequentialImpulseConstraintSolverMt::convertContacts(btPersistentManifold** manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal) { - if (!m_useBatching) - { - btSequentialImpulseConstraintSolver::convertContacts(manifoldPtr, numManifolds, infoGlobal); - return; - } - BT_PROFILE( "convertContacts" ); - if (numManifolds > 0) - { - if ( m_fixedBodyId < 0 ) - { - m_fixedBodyId = m_tmpSolverBodyPool.size(); - btSolverBody& fixedBody = m_tmpSolverBodyPool.expand(); - initSolverBody( &fixedBody, 0, infoGlobal.m_timeStep ); - } - allocAllContactConstraints( manifoldPtr, numManifolds, infoGlobal ); - if ( m_useBatching ) - { - setupBatchedContactConstraints(); - } - setupAllContactConstraints( infoGlobal ); - } + if (!m_useBatching) + { + btSequentialImpulseConstraintSolver::convertContacts(manifoldPtr, numManifolds, infoGlobal); + return; + } + BT_PROFILE("convertContacts"); + if (numManifolds > 0) + { + if (m_fixedBodyId < 0) + { + m_fixedBodyId = m_tmpSolverBodyPool.size(); + btSolverBody& fixedBody = m_tmpSolverBodyPool.expand(); + initSolverBody(&fixedBody, 0, infoGlobal.m_timeStep); + } + allocAllContactConstraints(manifoldPtr, numManifolds, infoGlobal); + if (m_useBatching) + { + setupBatchedContactConstraints(); + } + setupAllContactConstraints(infoGlobal); + } } - -void btSequentialImpulseConstraintSolverMt::internalInitMultipleJoints( btTypedConstraint** constraints, int iBegin, int iEnd ) +void btSequentialImpulseConstraintSolverMt::internalInitMultipleJoints(btTypedConstraint** constraints, int iBegin, int iEnd) { - BT_PROFILE("internalInitMultipleJoints"); - for ( int i = iBegin; i < iEnd; i++ ) + BT_PROFILE("internalInitMultipleJoints"); + for (int i = iBegin; i < iEnd; i++) { btTypedConstraint* constraint = constraints[i]; btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i]; if (constraint->isEnabled()) - { - constraint->buildJacobian(); - constraint->internalSetAppliedImpulse( 0.0f ); - btJointFeedback* fb = constraint->getJointFeedback(); - if ( fb ) - { - fb->m_appliedForceBodyA.setZero(); - fb->m_appliedTorqueBodyA.setZero(); - fb->m_appliedForceBodyB.setZero(); - fb->m_appliedTorqueBodyB.setZero(); - } - constraint->getInfo1( &info1 ); - } - else + { + constraint->buildJacobian(); + constraint->internalSetAppliedImpulse(0.0f); + btJointFeedback* fb = constraint->getJointFeedback(); + if (fb) + { + fb->m_appliedForceBodyA.setZero(); + fb->m_appliedTorqueBodyA.setZero(); + fb->m_appliedForceBodyB.setZero(); + fb->m_appliedTorqueBodyB.setZero(); + } + constraint->getInfo1(&info1); + } + else { info1.m_numConstraintRows = 0; info1.nub = 0; @@ -646,158 +624,151 @@ void btSequentialImpulseConstraintSolverMt::internalInitMultipleJoints( btTypedC } } - struct InitJointsLoop : public btIParallelForBody { - btSequentialImpulseConstraintSolverMt* m_solver; - btTypedConstraint** m_constraints; + btSequentialImpulseConstraintSolverMt* m_solver; + btTypedConstraint** m_constraints; - InitJointsLoop( btSequentialImpulseConstraintSolverMt* solver, btTypedConstraint** constraints ) - { - m_solver = solver; - m_constraints = constraints; - } - void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - m_solver->internalInitMultipleJoints( m_constraints, iBegin, iEnd ); - } + InitJointsLoop(btSequentialImpulseConstraintSolverMt* solver, btTypedConstraint** constraints) + { + m_solver = solver; + m_constraints = constraints; + } + void forLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + m_solver->internalInitMultipleJoints(m_constraints, iBegin, iEnd); + } }; - -void btSequentialImpulseConstraintSolverMt::internalConvertMultipleJoints( const btAlignedObjectArray& jointParamsArray, btTypedConstraint** constraints, int iBegin, int iEnd, const btContactSolverInfo& infoGlobal ) +void btSequentialImpulseConstraintSolverMt::internalConvertMultipleJoints(const btAlignedObjectArray& jointParamsArray, btTypedConstraint** constraints, int iBegin, int iEnd, const btContactSolverInfo& infoGlobal) { - BT_PROFILE("internalConvertMultipleJoints"); - for ( int i = iBegin; i < iEnd; ++i ) - { - const JointParams& jointParams = jointParamsArray[ i ]; - int currentRow = jointParams.m_solverConstraint; - if ( currentRow != -1 ) - { - const btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[ i ]; - btAssert( currentRow < m_tmpSolverNonContactConstraintPool.size() ); - btAssert( info1.m_numConstraintRows > 0 ); + BT_PROFILE("internalConvertMultipleJoints"); + for (int i = iBegin; i < iEnd; ++i) + { + const JointParams& jointParams = jointParamsArray[i]; + int currentRow = jointParams.m_solverConstraint; + if (currentRow != -1) + { + const btTypedConstraint::btConstraintInfo1& info1 = m_tmpConstraintSizesPool[i]; + btAssert(currentRow < m_tmpSolverNonContactConstraintPool.size()); + btAssert(info1.m_numConstraintRows > 0); - btSolverConstraint* currentConstraintRow = &m_tmpSolverNonContactConstraintPool[ currentRow ]; - btTypedConstraint* constraint = constraints[ i ]; + btSolverConstraint* currentConstraintRow = &m_tmpSolverNonContactConstraintPool[currentRow]; + btTypedConstraint* constraint = constraints[i]; - convertJoint( currentConstraintRow, constraint, info1, jointParams.m_solverBodyA, jointParams.m_solverBodyB, infoGlobal ); - } - } + convertJoint(currentConstraintRow, constraint, info1, jointParams.m_solverBodyA, jointParams.m_solverBodyB, infoGlobal); + } + } } - struct ConvertJointsLoop : public btIParallelForBody { - btSequentialImpulseConstraintSolverMt* m_solver; - const btAlignedObjectArray& m_jointParamsArray; - btTypedConstraint** m_srcConstraints; - const btContactSolverInfo& m_infoGlobal; + btSequentialImpulseConstraintSolverMt* m_solver; + const btAlignedObjectArray& m_jointParamsArray; + btTypedConstraint** m_srcConstraints; + const btContactSolverInfo& m_infoGlobal; - ConvertJointsLoop( btSequentialImpulseConstraintSolverMt* solver, - const btAlignedObjectArray& jointParamsArray, - btTypedConstraint** srcConstraints, - const btContactSolverInfo& infoGlobal - ) : - m_jointParamsArray(jointParamsArray), - m_infoGlobal(infoGlobal) - { - m_solver = solver; - m_srcConstraints = srcConstraints; - } - void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - m_solver->internalConvertMultipleJoints( m_jointParamsArray, m_srcConstraints, iBegin, iEnd, m_infoGlobal ); - } + ConvertJointsLoop(btSequentialImpulseConstraintSolverMt* solver, + const btAlignedObjectArray& jointParamsArray, + btTypedConstraint** srcConstraints, + const btContactSolverInfo& infoGlobal) : m_jointParamsArray(jointParamsArray), + m_infoGlobal(infoGlobal) + { + m_solver = solver; + m_srcConstraints = srcConstraints; + } + void forLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + m_solver->internalConvertMultipleJoints(m_jointParamsArray, m_srcConstraints, iBegin, iEnd, m_infoGlobal); + } }; - void btSequentialImpulseConstraintSolverMt::convertJoints(btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal) { - if ( !m_useBatching ) - { - btSequentialImpulseConstraintSolver::convertJoints(constraints, numConstraints, infoGlobal); - return; - } - BT_PROFILE("convertJoints"); - bool parallelJointSetup = true; + if (!m_useBatching) + { + btSequentialImpulseConstraintSolver::convertJoints(constraints, numConstraints, infoGlobal); + return; + } + BT_PROFILE("convertJoints"); + bool parallelJointSetup = true; m_tmpConstraintSizesPool.resizeNoInitialize(numConstraints); - if (parallelJointSetup) - { - InitJointsLoop loop(this, constraints); - int grainSize = 40; - btParallelFor(0, numConstraints, grainSize, loop); - } - else - { - internalInitMultipleJoints( constraints, 0, numConstraints ); - } + if (parallelJointSetup) + { + InitJointsLoop loop(this, constraints); + int grainSize = 40; + btParallelFor(0, numConstraints, grainSize, loop); + } + else + { + internalInitMultipleJoints(constraints, 0, numConstraints); + } int totalNumRows = 0; - btAlignedObjectArray jointParamsArray; - jointParamsArray.resizeNoInitialize(numConstraints); + btAlignedObjectArray jointParamsArray; + jointParamsArray.resizeNoInitialize(numConstraints); //calculate the total number of contraint rows - for (int i=0;igetRigidBodyA(), infoGlobal.m_timeStep ); - params.m_solverBodyB = getOrInitSolverBody( constraint->getRigidBodyB(), infoGlobal.m_timeStep ); + params.m_solverConstraint = totalNumRows; + params.m_solverBodyA = getOrInitSolverBody(constraint->getRigidBodyA(), infoGlobal.m_timeStep); + params.m_solverBodyB = getOrInitSolverBody(constraint->getRigidBodyB(), infoGlobal.m_timeStep); } - else + else { - params.m_solverConstraint = -1; + params.m_solverConstraint = -1; } totalNumRows += info1.m_numConstraintRows; } m_tmpSolverNonContactConstraintPool.resizeNoInitialize(totalNumRows); ///setup the btSolverConstraints - if ( parallelJointSetup ) - { - ConvertJointsLoop loop(this, jointParamsArray, constraints, infoGlobal); - int grainSize = 20; - btParallelFor(0, numConstraints, grainSize, loop); - } - else - { - internalConvertMultipleJoints( jointParamsArray, constraints, 0, numConstraints, infoGlobal ); - } - setupBatchedJointConstraints(); + if (parallelJointSetup) + { + ConvertJointsLoop loop(this, jointParamsArray, constraints, infoGlobal); + int grainSize = 20; + btParallelFor(0, numConstraints, grainSize, loop); + } + else + { + internalConvertMultipleJoints(jointParamsArray, constraints, 0, numConstraints, infoGlobal); + } + setupBatchedJointConstraints(); } - void btSequentialImpulseConstraintSolverMt::internalConvertBodies(btCollisionObject** bodies, int iBegin, int iEnd, const btContactSolverInfo& infoGlobal) { - BT_PROFILE("internalConvertBodies"); - for (int i=iBegin; i < iEnd; i++) + BT_PROFILE("internalConvertBodies"); + for (int i = iBegin; i < iEnd; i++) { - btCollisionObject* obj = bodies[i]; + btCollisionObject* obj = bodies[i]; obj->setCompanionId(i); btSolverBody& solverBody = m_tmpSolverBodyPool[i]; - initSolverBody(&solverBody, obj, infoGlobal.m_timeStep); + initSolverBody(&solverBody, obj, infoGlobal.m_timeStep); btRigidBody* body = btRigidBody::upcast(obj); if (body && body->getInvMass()) { - btVector3 gyroForce (0,0,0); - if (body->getFlags()&BT_ENABLE_GYROSCOPIC_FORCE_EXPLICIT) + btVector3 gyroForce(0, 0, 0); + if (body->getFlags() & BT_ENABLE_GYROSCOPIC_FORCE_EXPLICIT) { gyroForce = body->computeGyroscopicForceExplicit(infoGlobal.m_maxGyroscopicForce); - solverBody.m_externalTorqueImpulse -= gyroForce*body->getInvInertiaTensorWorld()*infoGlobal.m_timeStep; + solverBody.m_externalTorqueImpulse -= gyroForce * body->getInvInertiaTensorWorld() * infoGlobal.m_timeStep; } - if (body->getFlags()&BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD) + if (body->getFlags() & BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD) { gyroForce = body->computeGyroscopicImpulseImplicit_World(infoGlobal.m_timeStep); solverBody.m_externalTorqueImpulse += gyroForce; } - if (body->getFlags()&BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY) + if (body->getFlags() & BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY) { gyroForce = body->computeGyroscopicImpulseImplicit_Body(infoGlobal.m_timeStep); solverBody.m_externalTorqueImpulse += gyroForce; @@ -806,809 +777,772 @@ void btSequentialImpulseConstraintSolverMt::internalConvertBodies(btCollisionObj } } - struct ConvertBodiesLoop : public btIParallelForBody { - btSequentialImpulseConstraintSolverMt* m_solver; - btCollisionObject** m_bodies; - int m_numBodies; - const btContactSolverInfo& m_infoGlobal; + btSequentialImpulseConstraintSolverMt* m_solver; + btCollisionObject** m_bodies; + int m_numBodies; + const btContactSolverInfo& m_infoGlobal; - ConvertBodiesLoop( btSequentialImpulseConstraintSolverMt* solver, - btCollisionObject** bodies, - int numBodies, - const btContactSolverInfo& infoGlobal - ) : - m_infoGlobal(infoGlobal) - { - m_solver = solver; - m_bodies = bodies; - m_numBodies = numBodies; - } - void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - m_solver->internalConvertBodies( m_bodies, iBegin, iEnd, m_infoGlobal ); - } + ConvertBodiesLoop(btSequentialImpulseConstraintSolverMt* solver, + btCollisionObject** bodies, + int numBodies, + const btContactSolverInfo& infoGlobal) : m_infoGlobal(infoGlobal) + { + m_solver = solver; + m_bodies = bodies; + m_numBodies = numBodies; + } + void forLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + m_solver->internalConvertBodies(m_bodies, iBegin, iEnd, m_infoGlobal); + } }; - void btSequentialImpulseConstraintSolverMt::convertBodies(btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal) { - BT_PROFILE("convertBodies"); - m_kinematicBodyUniqueIdToSolverBodyTable.resize( 0 ); + BT_PROFILE("convertBodies"); + m_kinematicBodyUniqueIdToSolverBodyTable.resize(0); - m_tmpSolverBodyPool.resizeNoInitialize(numBodies+1); + m_tmpSolverBodyPool.resizeNoInitialize(numBodies + 1); - m_fixedBodyId = numBodies; - { - btSolverBody& fixedBody = m_tmpSolverBodyPool[ m_fixedBodyId ]; - initSolverBody( &fixedBody, NULL, infoGlobal.m_timeStep ); - } + m_fixedBodyId = numBodies; + { + btSolverBody& fixedBody = m_tmpSolverBodyPool[m_fixedBodyId]; + initSolverBody(&fixedBody, NULL, infoGlobal.m_timeStep); + } - bool parallelBodySetup = true; - if (parallelBodySetup) - { - ConvertBodiesLoop loop(this, bodies, numBodies, infoGlobal); - int grainSize = 40; - btParallelFor(0, numBodies, grainSize, loop); - } - else - { - internalConvertBodies( bodies, 0, numBodies, infoGlobal ); - } + bool parallelBodySetup = true; + if (parallelBodySetup) + { + ConvertBodiesLoop loop(this, bodies, numBodies, infoGlobal); + int grainSize = 40; + btParallelFor(0, numBodies, grainSize, loop); + } + else + { + internalConvertBodies(bodies, 0, numBodies, infoGlobal); + } } - btScalar btSequentialImpulseConstraintSolverMt::solveGroupCacheFriendlySetup( - btCollisionObject** bodies, - int numBodies, - btPersistentManifold** manifoldPtr, - int numManifolds, - btTypedConstraint** constraints, - int numConstraints, - const btContactSolverInfo& infoGlobal, - btIDebugDraw* debugDrawer - ) + btCollisionObject** bodies, + int numBodies, + btPersistentManifold** manifoldPtr, + int numManifolds, + btTypedConstraint** constraints, + int numConstraints, + const btContactSolverInfo& infoGlobal, + btIDebugDraw* debugDrawer) { - m_numFrictionDirections = (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) ? 2 : 1; - m_useBatching = false; - if ( numManifolds >= s_minimumContactManifoldsForBatching && - (s_allowNestedParallelForLoops || !btThreadsAreRunning()) - ) - { - m_useBatching = true; - m_batchedContactConstraints.m_debugDrawer = debugDrawer; - m_batchedJointConstraints.m_debugDrawer = debugDrawer; - } - btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup( bodies, - numBodies, - manifoldPtr, - numManifolds, - constraints, - numConstraints, - infoGlobal, - debugDrawer - ); - return 0.0f; + m_numFrictionDirections = (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) ? 2 : 1; + m_useBatching = false; + if (numManifolds >= s_minimumContactManifoldsForBatching && + (s_allowNestedParallelForLoops || !btThreadsAreRunning())) + { + m_useBatching = true; + m_batchedContactConstraints.m_debugDrawer = debugDrawer; + m_batchedJointConstraints.m_debugDrawer = debugDrawer; + } + btSequentialImpulseConstraintSolver::solveGroupCacheFriendlySetup(bodies, + numBodies, + manifoldPtr, + numManifolds, + constraints, + numConstraints, + infoGlobal, + debugDrawer); + return 0.0f; } - -btScalar btSequentialImpulseConstraintSolverMt::resolveMultipleContactSplitPenetrationImpulseConstraints( const btAlignedObjectArray& consIndices, int batchBegin, int batchEnd ) +btScalar btSequentialImpulseConstraintSolverMt::resolveMultipleContactSplitPenetrationImpulseConstraints(const btAlignedObjectArray& consIndices, int batchBegin, int batchEnd) { - btScalar leastSquaresResidual = 0.f; - for ( int iiCons = batchBegin; iiCons < batchEnd; ++iiCons ) - { - int iCons = consIndices[ iiCons ]; - const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[ iCons ]; - btSolverBody& bodyA = m_tmpSolverBodyPool[ solveManifold.m_solverBodyIdA ]; - btSolverBody& bodyB = m_tmpSolverBodyPool[ solveManifold.m_solverBodyIdB ]; - btScalar residual = resolveSplitPenetrationImpulse( bodyA, bodyB, solveManifold ); - leastSquaresResidual += residual*residual; - } - return leastSquaresResidual; + btScalar leastSquaresResidual = 0.f; + for (int iiCons = batchBegin; iiCons < batchEnd; ++iiCons) + { + int iCons = consIndices[iiCons]; + const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[iCons]; + btSolverBody& bodyA = m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA]; + btSolverBody& bodyB = m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB]; + btScalar residual = resolveSplitPenetrationImpulse(bodyA, bodyB, solveManifold); + leastSquaresResidual += residual * residual; + } + return leastSquaresResidual; } - struct ContactSplitPenetrationImpulseSolverLoop : public btIParallelSumBody { - btSequentialImpulseConstraintSolverMt* m_solver; - const btBatchedConstraints* m_bc; + btSequentialImpulseConstraintSolverMt* m_solver; + const btBatchedConstraints* m_bc; - ContactSplitPenetrationImpulseSolverLoop( btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc ) - { - m_solver = solver; - m_bc = bc; - } - btScalar sumLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - BT_PROFILE( "ContactSplitPenetrationImpulseSolverLoop" ); - btScalar sum = 0; - for ( int iBatch = iBegin; iBatch < iEnd; ++iBatch ) - { - const btBatchedConstraints::Range& batch = m_bc->m_batches[ iBatch ]; - sum += m_solver->resolveMultipleContactSplitPenetrationImpulseConstraints( m_bc->m_constraintIndices, batch.begin, batch.end ); - } - return sum; - } + ContactSplitPenetrationImpulseSolverLoop(btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc) + { + m_solver = solver; + m_bc = bc; + } + btScalar sumLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + BT_PROFILE("ContactSplitPenetrationImpulseSolverLoop"); + btScalar sum = 0; + for (int iBatch = iBegin; iBatch < iEnd; ++iBatch) + { + const btBatchedConstraints::Range& batch = m_bc->m_batches[iBatch]; + sum += m_solver->resolveMultipleContactSplitPenetrationImpulseConstraints(m_bc->m_constraintIndices, batch.begin, batch.end); + } + return sum; + } }; - -void btSequentialImpulseConstraintSolverMt::solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer) +void btSequentialImpulseConstraintSolverMt::solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer) { BT_PROFILE("solveGroupCacheFriendlySplitImpulseIterations"); if (infoGlobal.m_splitImpulse) { - for ( int iteration = 0; iteration < infoGlobal.m_numIterations; iteration++ ) - { - btScalar leastSquaresResidual = 0.f; - if (m_useBatching) - { - const btBatchedConstraints& batchedCons = m_batchedContactConstraints; - ContactSplitPenetrationImpulseSolverLoop loop( this, &batchedCons ); - btScalar leastSquaresResidual = 0.f; - for ( int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase ) - { - int iPhase = batchedCons.m_phaseOrder[ iiPhase ]; - const btBatchedConstraints::Range& phase = batchedCons.m_phases[ iPhase ]; - int grainSize = batchedCons.m_phaseGrainSize[iPhase]; - leastSquaresResidual += btParallelSum( phase.begin, phase.end, grainSize, loop ); - } - } - else - { - // non-batched - leastSquaresResidual = resolveMultipleContactSplitPenetrationImpulseConstraints(m_orderTmpConstraintPool, 0, m_tmpSolverContactConstraintPool.size()); - } - if ( leastSquaresResidual <= infoGlobal.m_leastSquaresResidualThreshold || iteration >= ( infoGlobal.m_numIterations - 1 ) ) - { + for (int iteration = 0; iteration < infoGlobal.m_numIterations; iteration++) + { + btScalar leastSquaresResidual = 0.f; + if (m_useBatching) + { + const btBatchedConstraints& batchedCons = m_batchedContactConstraints; + ContactSplitPenetrationImpulseSolverLoop loop(this, &batchedCons); + btScalar leastSquaresResidual = 0.f; + for (int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase) + { + int iPhase = batchedCons.m_phaseOrder[iiPhase]; + const btBatchedConstraints::Range& phase = batchedCons.m_phases[iPhase]; + int grainSize = batchedCons.m_phaseGrainSize[iPhase]; + leastSquaresResidual += btParallelSum(phase.begin, phase.end, grainSize, loop); + } + } + else + { + // non-batched + leastSquaresResidual = resolveMultipleContactSplitPenetrationImpulseConstraints(m_orderTmpConstraintPool, 0, m_tmpSolverContactConstraintPool.size()); + } + if (leastSquaresResidual <= infoGlobal.m_leastSquaresResidualThreshold || iteration >= (infoGlobal.m_numIterations - 1)) + { #ifdef VERBOSE_RESIDUAL_PRINTF - printf( "residual = %f at iteration #%d\n", leastSquaresResidual, iteration ); + printf("residual = %f at iteration #%d\n", leastSquaresResidual, iteration); #endif - break; - } - } + break; + } + } } } - -btScalar btSequentialImpulseConstraintSolverMt::solveSingleIteration(int iteration, btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer) +btScalar btSequentialImpulseConstraintSolverMt::solveSingleIteration(int iteration, btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer) { - if ( !m_useBatching ) - { - return btSequentialImpulseConstraintSolver::solveSingleIteration( iteration, bodies, numBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal, debugDrawer ); - } - BT_PROFILE( "solveSingleIterationMt" ); - btScalar leastSquaresResidual = 0.f; + if (!m_useBatching) + { + return btSequentialImpulseConstraintSolver::solveSingleIteration(iteration, bodies, numBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal, debugDrawer); + } + BT_PROFILE("solveSingleIterationMt"); + btScalar leastSquaresResidual = 0.f; if (infoGlobal.m_solverMode & SOLVER_RANDMIZE_ORDER) { - if (1) // uncomment this for a bit less random ((iteration & 7) == 0) + if (1) // uncomment this for a bit less random ((iteration & 7) == 0) { - randomizeConstraintOrdering(iteration, infoGlobal.m_numIterations); + randomizeConstraintOrdering(iteration, infoGlobal.m_numIterations); } } { ///solve all joint constraints - leastSquaresResidual += resolveAllJointConstraints(iteration); + leastSquaresResidual += resolveAllJointConstraints(iteration); - if (iteration< infoGlobal.m_numIterations) + if (iteration < infoGlobal.m_numIterations) { - // this loop is only used for cone-twist constraints, - // it would be nice to skip this loop if none of the constraints need it - if ( m_useObsoleteJointConstraints ) - { - for ( int j = 0; jisEnabled() ) - { - int bodyAid = getOrInitSolverBody( constraints[ j ]->getRigidBodyA(), infoGlobal.m_timeStep ); - int bodyBid = getOrInitSolverBody( constraints[ j ]->getRigidBodyB(), infoGlobal.m_timeStep ); - btSolverBody& bodyA = m_tmpSolverBodyPool[ bodyAid ]; - btSolverBody& bodyB = m_tmpSolverBodyPool[ bodyBid ]; - constraints[ j ]->solveConstraintObsolete( bodyA, bodyB, infoGlobal.m_timeStep ); - } - } - } + // this loop is only used for cone-twist constraints, + // it would be nice to skip this loop if none of the constraints need it + if (m_useObsoleteJointConstraints) + { + for (int j = 0; j < numConstraints; j++) + { + if (constraints[j]->isEnabled()) + { + int bodyAid = getOrInitSolverBody(constraints[j]->getRigidBodyA(), infoGlobal.m_timeStep); + int bodyBid = getOrInitSolverBody(constraints[j]->getRigidBodyB(), infoGlobal.m_timeStep); + btSolverBody& bodyA = m_tmpSolverBodyPool[bodyAid]; + btSolverBody& bodyB = m_tmpSolverBodyPool[bodyBid]; + constraints[j]->solveConstraintObsolete(bodyA, bodyB, infoGlobal.m_timeStep); + } + } + } if (infoGlobal.m_solverMode & SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS) { - // solve all contact, contact-friction, and rolling friction constraints interleaved - leastSquaresResidual += resolveAllContactConstraintsInterleaved(); + // solve all contact, contact-friction, and rolling friction constraints interleaved + leastSquaresResidual += resolveAllContactConstraintsInterleaved(); } - else//SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS + else //SOLVER_INTERLEAVE_CONTACT_AND_FRICTION_CONSTRAINTS { - // don't interleave them + // don't interleave them // solve all contact constraints - leastSquaresResidual += resolveAllContactConstraints(); + leastSquaresResidual += resolveAllContactConstraints(); // solve all contact friction constraints - leastSquaresResidual += resolveAllContactFrictionConstraints(); + leastSquaresResidual += resolveAllContactFrictionConstraints(); - // solve all rolling friction constraints - leastSquaresResidual += resolveAllRollingFrictionConstraints(); + // solve all rolling friction constraints + leastSquaresResidual += resolveAllRollingFrictionConstraints(); } } } - return leastSquaresResidual; + return leastSquaresResidual; } - -btScalar btSequentialImpulseConstraintSolverMt::resolveMultipleJointConstraints( const btAlignedObjectArray& consIndices, int batchBegin, int batchEnd, int iteration ) +btScalar btSequentialImpulseConstraintSolverMt::resolveMultipleJointConstraints(const btAlignedObjectArray& consIndices, int batchBegin, int batchEnd, int iteration) { - btScalar leastSquaresResidual = 0.f; - for ( int iiCons = batchBegin; iiCons < batchEnd; ++iiCons ) - { - int iCons = consIndices[ iiCons ]; - const btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[ iCons ]; - if ( iteration < constraint.m_overrideNumSolverIterations ) - { - btSolverBody& bodyA = m_tmpSolverBodyPool[ constraint.m_solverBodyIdA ]; - btSolverBody& bodyB = m_tmpSolverBodyPool[ constraint.m_solverBodyIdB ]; - btScalar residual = resolveSingleConstraintRowGeneric( bodyA, bodyB, constraint ); - leastSquaresResidual += residual*residual; - } - } - return leastSquaresResidual; + btScalar leastSquaresResidual = 0.f; + for (int iiCons = batchBegin; iiCons < batchEnd; ++iiCons) + { + int iCons = consIndices[iiCons]; + const btSolverConstraint& constraint = m_tmpSolverNonContactConstraintPool[iCons]; + if (iteration < constraint.m_overrideNumSolverIterations) + { + btSolverBody& bodyA = m_tmpSolverBodyPool[constraint.m_solverBodyIdA]; + btSolverBody& bodyB = m_tmpSolverBodyPool[constraint.m_solverBodyIdB]; + btScalar residual = resolveSingleConstraintRowGeneric(bodyA, bodyB, constraint); + leastSquaresResidual += residual * residual; + } + } + return leastSquaresResidual; } - -btScalar btSequentialImpulseConstraintSolverMt::resolveMultipleContactConstraints( const btAlignedObjectArray& consIndices, int batchBegin, int batchEnd ) +btScalar btSequentialImpulseConstraintSolverMt::resolveMultipleContactConstraints(const btAlignedObjectArray& consIndices, int batchBegin, int batchEnd) { - btScalar leastSquaresResidual = 0.f; - for ( int iiCons = batchBegin; iiCons < batchEnd; ++iiCons ) - { - int iCons = consIndices[ iiCons ]; - const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[ iCons ]; - btSolverBody& bodyA = m_tmpSolverBodyPool[ solveManifold.m_solverBodyIdA ]; - btSolverBody& bodyB = m_tmpSolverBodyPool[ solveManifold.m_solverBodyIdB ]; - btScalar residual = resolveSingleConstraintRowLowerLimit( bodyA, bodyB, solveManifold ); - leastSquaresResidual += residual*residual; - } - return leastSquaresResidual; + btScalar leastSquaresResidual = 0.f; + for (int iiCons = batchBegin; iiCons < batchEnd; ++iiCons) + { + int iCons = consIndices[iiCons]; + const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[iCons]; + btSolverBody& bodyA = m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA]; + btSolverBody& bodyB = m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB]; + btScalar residual = resolveSingleConstraintRowLowerLimit(bodyA, bodyB, solveManifold); + leastSquaresResidual += residual * residual; + } + return leastSquaresResidual; } - -btScalar btSequentialImpulseConstraintSolverMt::resolveMultipleContactFrictionConstraints( const btAlignedObjectArray& consIndices, int batchBegin, int batchEnd ) +btScalar btSequentialImpulseConstraintSolverMt::resolveMultipleContactFrictionConstraints(const btAlignedObjectArray& consIndices, int batchBegin, int batchEnd) { - btScalar leastSquaresResidual = 0.f; - for ( int iiCons = batchBegin; iiCons < batchEnd; ++iiCons ) - { - int iContact = consIndices[ iiCons ]; - btScalar totalImpulse = m_tmpSolverContactConstraintPool[ iContact ].m_appliedImpulse; + btScalar leastSquaresResidual = 0.f; + for (int iiCons = batchBegin; iiCons < batchEnd; ++iiCons) + { + int iContact = consIndices[iiCons]; + btScalar totalImpulse = m_tmpSolverContactConstraintPool[iContact].m_appliedImpulse; - // apply sliding friction - if ( totalImpulse > 0.0f ) - { - int iBegin = iContact * m_numFrictionDirections; - int iEnd = iBegin + m_numFrictionDirections; - for ( int iFriction = iBegin; iFriction < iEnd; ++iFriction ) - { - btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[ iFriction++ ]; - btAssert( solveManifold.m_frictionIndex == iContact ); + // apply sliding friction + if (totalImpulse > 0.0f) + { + int iBegin = iContact * m_numFrictionDirections; + int iEnd = iBegin + m_numFrictionDirections; + for (int iFriction = iBegin; iFriction < iEnd; ++iFriction) + { + btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[iFriction++]; + btAssert(solveManifold.m_frictionIndex == iContact); - solveManifold.m_lowerLimit = -( solveManifold.m_friction*totalImpulse ); - solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse; + solveManifold.m_lowerLimit = -(solveManifold.m_friction * totalImpulse); + solveManifold.m_upperLimit = solveManifold.m_friction * totalImpulse; - btSolverBody& bodyA = m_tmpSolverBodyPool[ solveManifold.m_solverBodyIdA ]; - btSolverBody& bodyB = m_tmpSolverBodyPool[ solveManifold.m_solverBodyIdB ]; - btScalar residual = resolveSingleConstraintRowGeneric( bodyA, bodyB, solveManifold ); - leastSquaresResidual += residual*residual; - } - } - } - return leastSquaresResidual; + btSolverBody& bodyA = m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA]; + btSolverBody& bodyB = m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB]; + btScalar residual = resolveSingleConstraintRowGeneric(bodyA, bodyB, solveManifold); + leastSquaresResidual += residual * residual; + } + } + } + return leastSquaresResidual; } - -btScalar btSequentialImpulseConstraintSolverMt::resolveMultipleContactRollingFrictionConstraints( const btAlignedObjectArray& consIndices, int batchBegin, int batchEnd ) +btScalar btSequentialImpulseConstraintSolverMt::resolveMultipleContactRollingFrictionConstraints(const btAlignedObjectArray& consIndices, int batchBegin, int batchEnd) { - btScalar leastSquaresResidual = 0.f; - for ( int iiCons = batchBegin; iiCons < batchEnd; ++iiCons ) - { - int iContact = consIndices[ iiCons ]; - int iFirstRollingFriction = m_rollingFrictionIndexTable[ iContact ]; - if ( iFirstRollingFriction >= 0 ) - { - btScalar totalImpulse = m_tmpSolverContactConstraintPool[ iContact ].m_appliedImpulse; - // apply rolling friction - if ( totalImpulse > 0.0f ) - { - int iBegin = iFirstRollingFriction; - int iEnd = iBegin + 3; - for ( int iRollingFric = iBegin; iRollingFric < iEnd; ++iRollingFric ) - { - btSolverConstraint& rollingFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[ iRollingFric ]; - if ( rollingFrictionConstraint.m_frictionIndex != iContact ) - { - break; - } - btScalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction*totalImpulse; - if ( rollingFrictionMagnitude > rollingFrictionConstraint.m_friction ) - { - rollingFrictionMagnitude = rollingFrictionConstraint.m_friction; - } + btScalar leastSquaresResidual = 0.f; + for (int iiCons = batchBegin; iiCons < batchEnd; ++iiCons) + { + int iContact = consIndices[iiCons]; + int iFirstRollingFriction = m_rollingFrictionIndexTable[iContact]; + if (iFirstRollingFriction >= 0) + { + btScalar totalImpulse = m_tmpSolverContactConstraintPool[iContact].m_appliedImpulse; + // apply rolling friction + if (totalImpulse > 0.0f) + { + int iBegin = iFirstRollingFriction; + int iEnd = iBegin + 3; + for (int iRollingFric = iBegin; iRollingFric < iEnd; ++iRollingFric) + { + btSolverConstraint& rollingFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[iRollingFric]; + if (rollingFrictionConstraint.m_frictionIndex != iContact) + { + break; + } + btScalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction * totalImpulse; + if (rollingFrictionMagnitude > rollingFrictionConstraint.m_friction) + { + rollingFrictionMagnitude = rollingFrictionConstraint.m_friction; + } - rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude; - rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude; + rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude; + rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude; - btScalar residual = resolveSingleConstraintRowGeneric( m_tmpSolverBodyPool[ rollingFrictionConstraint.m_solverBodyIdA ], m_tmpSolverBodyPool[ rollingFrictionConstraint.m_solverBodyIdB ], rollingFrictionConstraint ); - leastSquaresResidual += residual*residual; - } - } - } - } - return leastSquaresResidual; + btScalar residual = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA], m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB], rollingFrictionConstraint); + leastSquaresResidual += residual * residual; + } + } + } + } + return leastSquaresResidual; } - -btScalar btSequentialImpulseConstraintSolverMt::resolveMultipleContactConstraintsInterleaved( const btAlignedObjectArray& contactIndices, - int batchBegin, - int batchEnd - ) +btScalar btSequentialImpulseConstraintSolverMt::resolveMultipleContactConstraintsInterleaved(const btAlignedObjectArray& contactIndices, + int batchBegin, + int batchEnd) { - btScalar leastSquaresResidual = 0.f; - int numPoolConstraints = m_tmpSolverContactConstraintPool.size(); + btScalar leastSquaresResidual = 0.f; + int numPoolConstraints = m_tmpSolverContactConstraintPool.size(); - for ( int iiCons = batchBegin; iiCons < batchEnd; iiCons++ ) - { - btScalar totalImpulse = 0; - int iContact = contactIndices[ iiCons ]; - // apply penetration constraint - { - const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[ iContact ]; - btScalar residual = resolveSingleConstraintRowLowerLimit( m_tmpSolverBodyPool[ solveManifold.m_solverBodyIdA ], m_tmpSolverBodyPool[ solveManifold.m_solverBodyIdB ], solveManifold ); - leastSquaresResidual += residual*residual; - totalImpulse = solveManifold.m_appliedImpulse; - } + for (int iiCons = batchBegin; iiCons < batchEnd; iiCons++) + { + btScalar totalImpulse = 0; + int iContact = contactIndices[iiCons]; + // apply penetration constraint + { + const btSolverConstraint& solveManifold = m_tmpSolverContactConstraintPool[iContact]; + btScalar residual = resolveSingleConstraintRowLowerLimit(m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA], m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB], solveManifold); + leastSquaresResidual += residual * residual; + totalImpulse = solveManifold.m_appliedImpulse; + } - // apply sliding friction - if ( totalImpulse > 0.0f ) - { - int iBegin = iContact * m_numFrictionDirections; - int iEnd = iBegin + m_numFrictionDirections; - for ( int iFriction = iBegin; iFriction < iEnd; ++iFriction ) - { - btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[ iFriction ]; - btAssert( solveManifold.m_frictionIndex == iContact ); + // apply sliding friction + if (totalImpulse > 0.0f) + { + int iBegin = iContact * m_numFrictionDirections; + int iEnd = iBegin + m_numFrictionDirections; + for (int iFriction = iBegin; iFriction < iEnd; ++iFriction) + { + btSolverConstraint& solveManifold = m_tmpSolverContactFrictionConstraintPool[iFriction]; + btAssert(solveManifold.m_frictionIndex == iContact); - solveManifold.m_lowerLimit = -( solveManifold.m_friction*totalImpulse ); - solveManifold.m_upperLimit = solveManifold.m_friction*totalImpulse; + solveManifold.m_lowerLimit = -(solveManifold.m_friction * totalImpulse); + solveManifold.m_upperLimit = solveManifold.m_friction * totalImpulse; - btSolverBody& bodyA = m_tmpSolverBodyPool[ solveManifold.m_solverBodyIdA ]; - btSolverBody& bodyB = m_tmpSolverBodyPool[ solveManifold.m_solverBodyIdB ]; - btScalar residual = resolveSingleConstraintRowGeneric( bodyA, bodyB, solveManifold ); - leastSquaresResidual += residual*residual; - } - } + btSolverBody& bodyA = m_tmpSolverBodyPool[solveManifold.m_solverBodyIdA]; + btSolverBody& bodyB = m_tmpSolverBodyPool[solveManifold.m_solverBodyIdB]; + btScalar residual = resolveSingleConstraintRowGeneric(bodyA, bodyB, solveManifold); + leastSquaresResidual += residual * residual; + } + } - // apply rolling friction - int iFirstRollingFriction = m_rollingFrictionIndexTable[ iContact ]; - if ( totalImpulse > 0.0f && iFirstRollingFriction >= 0) - { - int iBegin = iFirstRollingFriction; - int iEnd = iBegin + 3; - for ( int iRollingFric = iBegin; iRollingFric < iEnd; ++iRollingFric ) - { - btSolverConstraint& rollingFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[ iRollingFric ]; - if ( rollingFrictionConstraint.m_frictionIndex != iContact ) - { - break; - } - btScalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction*totalImpulse; - if ( rollingFrictionMagnitude > rollingFrictionConstraint.m_friction ) - { - rollingFrictionMagnitude = rollingFrictionConstraint.m_friction; - } + // apply rolling friction + int iFirstRollingFriction = m_rollingFrictionIndexTable[iContact]; + if (totalImpulse > 0.0f && iFirstRollingFriction >= 0) + { + int iBegin = iFirstRollingFriction; + int iEnd = iBegin + 3; + for (int iRollingFric = iBegin; iRollingFric < iEnd; ++iRollingFric) + { + btSolverConstraint& rollingFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[iRollingFric]; + if (rollingFrictionConstraint.m_frictionIndex != iContact) + { + break; + } + btScalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction * totalImpulse; + if (rollingFrictionMagnitude > rollingFrictionConstraint.m_friction) + { + rollingFrictionMagnitude = rollingFrictionConstraint.m_friction; + } - rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude; - rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude; + rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude; + rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude; - btScalar residual = resolveSingleConstraintRowGeneric( m_tmpSolverBodyPool[ rollingFrictionConstraint.m_solverBodyIdA ], m_tmpSolverBodyPool[ rollingFrictionConstraint.m_solverBodyIdB ], rollingFrictionConstraint ); - leastSquaresResidual += residual*residual; - } - } - } - return leastSquaresResidual; + btScalar residual = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA], m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB], rollingFrictionConstraint); + leastSquaresResidual += residual * residual; + } + } + } + return leastSquaresResidual; } - -void btSequentialImpulseConstraintSolverMt::randomizeBatchedConstraintOrdering( btBatchedConstraints* batchedConstraints ) +void btSequentialImpulseConstraintSolverMt::randomizeBatchedConstraintOrdering(btBatchedConstraints* batchedConstraints) { - btBatchedConstraints& bc = *batchedConstraints; - // randomize ordering of phases - for ( int ii = 1; ii < bc.m_phaseOrder.size(); ++ii ) - { - int iSwap = btRandInt2( ii + 1 ); - bc.m_phaseOrder.swap( ii, iSwap ); - } + btBatchedConstraints& bc = *batchedConstraints; + // randomize ordering of phases + for (int ii = 1; ii < bc.m_phaseOrder.size(); ++ii) + { + int iSwap = btRandInt2(ii + 1); + bc.m_phaseOrder.swap(ii, iSwap); + } - // for each batch, - for ( int iBatch = 0; iBatch < bc.m_batches.size(); ++iBatch ) - { - // randomize ordering of constraints within the batch - const btBatchedConstraints::Range& batch = bc.m_batches[ iBatch ]; - for ( int iiCons = batch.begin; iiCons < batch.end; ++iiCons ) - { - int iSwap = batch.begin + btRandInt2( iiCons - batch.begin + 1 ); - btAssert(iSwap >= batch.begin && iSwap < batch.end); - bc.m_constraintIndices.swap( iiCons, iSwap ); - } - } + // for each batch, + for (int iBatch = 0; iBatch < bc.m_batches.size(); ++iBatch) + { + // randomize ordering of constraints within the batch + const btBatchedConstraints::Range& batch = bc.m_batches[iBatch]; + for (int iiCons = batch.begin; iiCons < batch.end; ++iiCons) + { + int iSwap = batch.begin + btRandInt2(iiCons - batch.begin + 1); + btAssert(iSwap >= batch.begin && iSwap < batch.end); + bc.m_constraintIndices.swap(iiCons, iSwap); + } + } } - void btSequentialImpulseConstraintSolverMt::randomizeConstraintOrdering(int iteration, int numIterations) { - // randomize ordering of joint constraints - randomizeBatchedConstraintOrdering( &m_batchedJointConstraints ); + // randomize ordering of joint constraints + randomizeBatchedConstraintOrdering(&m_batchedJointConstraints); - //contact/friction constraints are not solved more than numIterations - if ( iteration < numIterations ) - { - randomizeBatchedConstraintOrdering( &m_batchedContactConstraints ); - } + //contact/friction constraints are not solved more than numIterations + if (iteration < numIterations) + { + randomizeBatchedConstraintOrdering(&m_batchedContactConstraints); + } } - struct JointSolverLoop : public btIParallelSumBody { - btSequentialImpulseConstraintSolverMt* m_solver; - const btBatchedConstraints* m_bc; - int m_iteration; + btSequentialImpulseConstraintSolverMt* m_solver; + const btBatchedConstraints* m_bc; + int m_iteration; - JointSolverLoop( btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc, int iteration ) - { - m_solver = solver; - m_bc = bc; - m_iteration = iteration; - } - btScalar sumLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - BT_PROFILE( "JointSolverLoop" ); - btScalar sum = 0; - for ( int iBatch = iBegin; iBatch < iEnd; ++iBatch ) - { - const btBatchedConstraints::Range& batch = m_bc->m_batches[ iBatch ]; - sum += m_solver->resolveMultipleJointConstraints( m_bc->m_constraintIndices, batch.begin, batch.end, m_iteration ); - } - return sum; - } + JointSolverLoop(btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc, int iteration) + { + m_solver = solver; + m_bc = bc; + m_iteration = iteration; + } + btScalar sumLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + BT_PROFILE("JointSolverLoop"); + btScalar sum = 0; + for (int iBatch = iBegin; iBatch < iEnd; ++iBatch) + { + const btBatchedConstraints::Range& batch = m_bc->m_batches[iBatch]; + sum += m_solver->resolveMultipleJointConstraints(m_bc->m_constraintIndices, batch.begin, batch.end, m_iteration); + } + return sum; + } }; - btScalar btSequentialImpulseConstraintSolverMt::resolveAllJointConstraints(int iteration) { - BT_PROFILE( "resolveAllJointConstraints" ); - const btBatchedConstraints& batchedCons = m_batchedJointConstraints; - JointSolverLoop loop( this, &batchedCons, iteration ); - btScalar leastSquaresResidual = 0.f; - for ( int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase ) - { - int iPhase = batchedCons.m_phaseOrder[ iiPhase ]; - const btBatchedConstraints::Range& phase = batchedCons.m_phases[ iPhase ]; - int grainSize = 1; - leastSquaresResidual += btParallelSum( phase.begin, phase.end, grainSize, loop ); - } - return leastSquaresResidual; + BT_PROFILE("resolveAllJointConstraints"); + const btBatchedConstraints& batchedCons = m_batchedJointConstraints; + JointSolverLoop loop(this, &batchedCons, iteration); + btScalar leastSquaresResidual = 0.f; + for (int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase) + { + int iPhase = batchedCons.m_phaseOrder[iiPhase]; + const btBatchedConstraints::Range& phase = batchedCons.m_phases[iPhase]; + int grainSize = 1; + leastSquaresResidual += btParallelSum(phase.begin, phase.end, grainSize, loop); + } + return leastSquaresResidual; } - struct ContactSolverLoop : public btIParallelSumBody { - btSequentialImpulseConstraintSolverMt* m_solver; - const btBatchedConstraints* m_bc; + btSequentialImpulseConstraintSolverMt* m_solver; + const btBatchedConstraints* m_bc; - ContactSolverLoop( btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc ) - { - m_solver = solver; - m_bc = bc; - } - btScalar sumLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - BT_PROFILE( "ContactSolverLoop" ); - btScalar sum = 0; - for ( int iBatch = iBegin; iBatch < iEnd; ++iBatch ) - { - const btBatchedConstraints::Range& batch = m_bc->m_batches[ iBatch ]; - sum += m_solver->resolveMultipleContactConstraints( m_bc->m_constraintIndices, batch.begin, batch.end ); - } - return sum; - } + ContactSolverLoop(btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc) + { + m_solver = solver; + m_bc = bc; + } + btScalar sumLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + BT_PROFILE("ContactSolverLoop"); + btScalar sum = 0; + for (int iBatch = iBegin; iBatch < iEnd; ++iBatch) + { + const btBatchedConstraints::Range& batch = m_bc->m_batches[iBatch]; + sum += m_solver->resolveMultipleContactConstraints(m_bc->m_constraintIndices, batch.begin, batch.end); + } + return sum; + } }; - btScalar btSequentialImpulseConstraintSolverMt::resolveAllContactConstraints() { - BT_PROFILE( "resolveAllContactConstraints" ); - const btBatchedConstraints& batchedCons = m_batchedContactConstraints; - ContactSolverLoop loop( this, &batchedCons ); - btScalar leastSquaresResidual = 0.f; - for ( int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase ) - { - int iPhase = batchedCons.m_phaseOrder[ iiPhase ]; - const btBatchedConstraints::Range& phase = batchedCons.m_phases[ iPhase ]; - int grainSize = batchedCons.m_phaseGrainSize[iPhase]; - leastSquaresResidual += btParallelSum( phase.begin, phase.end, grainSize, loop ); - } - return leastSquaresResidual; + BT_PROFILE("resolveAllContactConstraints"); + const btBatchedConstraints& batchedCons = m_batchedContactConstraints; + ContactSolverLoop loop(this, &batchedCons); + btScalar leastSquaresResidual = 0.f; + for (int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase) + { + int iPhase = batchedCons.m_phaseOrder[iiPhase]; + const btBatchedConstraints::Range& phase = batchedCons.m_phases[iPhase]; + int grainSize = batchedCons.m_phaseGrainSize[iPhase]; + leastSquaresResidual += btParallelSum(phase.begin, phase.end, grainSize, loop); + } + return leastSquaresResidual; } - struct ContactFrictionSolverLoop : public btIParallelSumBody { - btSequentialImpulseConstraintSolverMt* m_solver; - const btBatchedConstraints* m_bc; + btSequentialImpulseConstraintSolverMt* m_solver; + const btBatchedConstraints* m_bc; - ContactFrictionSolverLoop( btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc ) - { - m_solver = solver; - m_bc = bc; - } - btScalar sumLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - BT_PROFILE( "ContactFrictionSolverLoop" ); - btScalar sum = 0; - for ( int iBatch = iBegin; iBatch < iEnd; ++iBatch ) - { - const btBatchedConstraints::Range& batch = m_bc->m_batches[ iBatch ]; - sum += m_solver->resolveMultipleContactFrictionConstraints( m_bc->m_constraintIndices, batch.begin, batch.end ); - } - return sum; - } + ContactFrictionSolverLoop(btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc) + { + m_solver = solver; + m_bc = bc; + } + btScalar sumLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + BT_PROFILE("ContactFrictionSolverLoop"); + btScalar sum = 0; + for (int iBatch = iBegin; iBatch < iEnd; ++iBatch) + { + const btBatchedConstraints::Range& batch = m_bc->m_batches[iBatch]; + sum += m_solver->resolveMultipleContactFrictionConstraints(m_bc->m_constraintIndices, batch.begin, batch.end); + } + return sum; + } }; - btScalar btSequentialImpulseConstraintSolverMt::resolveAllContactFrictionConstraints() { - BT_PROFILE( "resolveAllContactFrictionConstraints" ); - const btBatchedConstraints& batchedCons = m_batchedContactConstraints; - ContactFrictionSolverLoop loop( this, &batchedCons ); - btScalar leastSquaresResidual = 0.f; - for ( int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase ) - { - int iPhase = batchedCons.m_phaseOrder[ iiPhase ]; - const btBatchedConstraints::Range& phase = batchedCons.m_phases[ iPhase ]; - int grainSize = batchedCons.m_phaseGrainSize[iPhase]; - leastSquaresResidual += btParallelSum( phase.begin, phase.end, grainSize, loop ); - } - return leastSquaresResidual; + BT_PROFILE("resolveAllContactFrictionConstraints"); + const btBatchedConstraints& batchedCons = m_batchedContactConstraints; + ContactFrictionSolverLoop loop(this, &batchedCons); + btScalar leastSquaresResidual = 0.f; + for (int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase) + { + int iPhase = batchedCons.m_phaseOrder[iiPhase]; + const btBatchedConstraints::Range& phase = batchedCons.m_phases[iPhase]; + int grainSize = batchedCons.m_phaseGrainSize[iPhase]; + leastSquaresResidual += btParallelSum(phase.begin, phase.end, grainSize, loop); + } + return leastSquaresResidual; } - struct InterleavedContactSolverLoop : public btIParallelSumBody { - btSequentialImpulseConstraintSolverMt* m_solver; - const btBatchedConstraints* m_bc; + btSequentialImpulseConstraintSolverMt* m_solver; + const btBatchedConstraints* m_bc; - InterleavedContactSolverLoop( btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc ) - { - m_solver = solver; - m_bc = bc; - } - btScalar sumLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - BT_PROFILE( "InterleavedContactSolverLoop" ); - btScalar sum = 0; - for ( int iBatch = iBegin; iBatch < iEnd; ++iBatch ) - { - const btBatchedConstraints::Range& batch = m_bc->m_batches[ iBatch ]; - sum += m_solver->resolveMultipleContactConstraintsInterleaved( m_bc->m_constraintIndices, batch.begin, batch.end ); - } - return sum; - } + InterleavedContactSolverLoop(btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc) + { + m_solver = solver; + m_bc = bc; + } + btScalar sumLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + BT_PROFILE("InterleavedContactSolverLoop"); + btScalar sum = 0; + for (int iBatch = iBegin; iBatch < iEnd; ++iBatch) + { + const btBatchedConstraints::Range& batch = m_bc->m_batches[iBatch]; + sum += m_solver->resolveMultipleContactConstraintsInterleaved(m_bc->m_constraintIndices, batch.begin, batch.end); + } + return sum; + } }; - btScalar btSequentialImpulseConstraintSolverMt::resolveAllContactConstraintsInterleaved() { - BT_PROFILE( "resolveAllContactConstraintsInterleaved" ); - const btBatchedConstraints& batchedCons = m_batchedContactConstraints; - InterleavedContactSolverLoop loop( this, &batchedCons ); - btScalar leastSquaresResidual = 0.f; - for ( int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase ) - { - int iPhase = batchedCons.m_phaseOrder[ iiPhase ]; - const btBatchedConstraints::Range& phase = batchedCons.m_phases[ iPhase ]; - int grainSize = 1; - leastSquaresResidual += btParallelSum( phase.begin, phase.end, grainSize, loop ); - } - return leastSquaresResidual; + BT_PROFILE("resolveAllContactConstraintsInterleaved"); + const btBatchedConstraints& batchedCons = m_batchedContactConstraints; + InterleavedContactSolverLoop loop(this, &batchedCons); + btScalar leastSquaresResidual = 0.f; + for (int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase) + { + int iPhase = batchedCons.m_phaseOrder[iiPhase]; + const btBatchedConstraints::Range& phase = batchedCons.m_phases[iPhase]; + int grainSize = 1; + leastSquaresResidual += btParallelSum(phase.begin, phase.end, grainSize, loop); + } + return leastSquaresResidual; } - struct ContactRollingFrictionSolverLoop : public btIParallelSumBody { - btSequentialImpulseConstraintSolverMt* m_solver; - const btBatchedConstraints* m_bc; + btSequentialImpulseConstraintSolverMt* m_solver; + const btBatchedConstraints* m_bc; - ContactRollingFrictionSolverLoop( btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc ) - { - m_solver = solver; - m_bc = bc; - } - btScalar sumLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - BT_PROFILE( "ContactFrictionSolverLoop" ); - btScalar sum = 0; - for ( int iBatch = iBegin; iBatch < iEnd; ++iBatch ) - { - const btBatchedConstraints::Range& batch = m_bc->m_batches[ iBatch ]; - sum += m_solver->resolveMultipleContactRollingFrictionConstraints( m_bc->m_constraintIndices, batch.begin, batch.end ); - } - return sum; - } + ContactRollingFrictionSolverLoop(btSequentialImpulseConstraintSolverMt* solver, const btBatchedConstraints* bc) + { + m_solver = solver; + m_bc = bc; + } + btScalar sumLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + BT_PROFILE("ContactFrictionSolverLoop"); + btScalar sum = 0; + for (int iBatch = iBegin; iBatch < iEnd; ++iBatch) + { + const btBatchedConstraints::Range& batch = m_bc->m_batches[iBatch]; + sum += m_solver->resolveMultipleContactRollingFrictionConstraints(m_bc->m_constraintIndices, batch.begin, batch.end); + } + return sum; + } }; - btScalar btSequentialImpulseConstraintSolverMt::resolveAllRollingFrictionConstraints() { - BT_PROFILE( "resolveAllRollingFrictionConstraints" ); - btScalar leastSquaresResidual = 0.f; - // - // We do not generate batches for rolling friction constraints. We assume that - // one of two cases is true: - // - // 1. either most bodies in the simulation have rolling friction, in which case we can use the - // batches for contacts and use a lookup table to translate contact indices to rolling friction - // (ignoring any contact indices that don't map to a rolling friction constraint). As long as - // most contacts have a corresponding rolling friction constraint, this should parallelize well. - // - // -OR- - // - // 2. few bodies in the simulation have rolling friction, so it is not worth trying to use the - // batches from contacts as most of the contacts won't have corresponding rolling friction - // constraints and most threads would end up doing very little work. Most of the time would - // go to threading overhead, so we don't bother with threading. - // - int numRollingFrictionPoolConstraints = m_tmpSolverContactRollingFrictionConstraintPool.size(); - if (numRollingFrictionPoolConstraints >= m_tmpSolverContactConstraintPool.size()) - { - // use batching if there are many rolling friction constraints - const btBatchedConstraints& batchedCons = m_batchedContactConstraints; - ContactRollingFrictionSolverLoop loop( this, &batchedCons ); - btScalar leastSquaresResidual = 0.f; - for ( int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase ) - { - int iPhase = batchedCons.m_phaseOrder[ iiPhase ]; - const btBatchedConstraints::Range& phase = batchedCons.m_phases[ iPhase ]; - int grainSize = 1; - leastSquaresResidual += btParallelSum( phase.begin, phase.end, grainSize, loop ); - } - } - else - { - // no batching, also ignores SOLVER_RANDMIZE_ORDER - for ( int j = 0; j < numRollingFrictionPoolConstraints; j++ ) - { - btSolverConstraint& rollingFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[ j ]; - if ( rollingFrictionConstraint.m_frictionIndex >= 0 ) - { - btScalar totalImpulse = m_tmpSolverContactConstraintPool[ rollingFrictionConstraint.m_frictionIndex ].m_appliedImpulse; - if ( totalImpulse > 0.0f ) - { - btScalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction*totalImpulse; - if ( rollingFrictionMagnitude > rollingFrictionConstraint.m_friction ) - rollingFrictionMagnitude = rollingFrictionConstraint.m_friction; + BT_PROFILE("resolveAllRollingFrictionConstraints"); + btScalar leastSquaresResidual = 0.f; + // + // We do not generate batches for rolling friction constraints. We assume that + // one of two cases is true: + // + // 1. either most bodies in the simulation have rolling friction, in which case we can use the + // batches for contacts and use a lookup table to translate contact indices to rolling friction + // (ignoring any contact indices that don't map to a rolling friction constraint). As long as + // most contacts have a corresponding rolling friction constraint, this should parallelize well. + // + // -OR- + // + // 2. few bodies in the simulation have rolling friction, so it is not worth trying to use the + // batches from contacts as most of the contacts won't have corresponding rolling friction + // constraints and most threads would end up doing very little work. Most of the time would + // go to threading overhead, so we don't bother with threading. + // + int numRollingFrictionPoolConstraints = m_tmpSolverContactRollingFrictionConstraintPool.size(); + if (numRollingFrictionPoolConstraints >= m_tmpSolverContactConstraintPool.size()) + { + // use batching if there are many rolling friction constraints + const btBatchedConstraints& batchedCons = m_batchedContactConstraints; + ContactRollingFrictionSolverLoop loop(this, &batchedCons); + btScalar leastSquaresResidual = 0.f; + for (int iiPhase = 0; iiPhase < batchedCons.m_phases.size(); ++iiPhase) + { + int iPhase = batchedCons.m_phaseOrder[iiPhase]; + const btBatchedConstraints::Range& phase = batchedCons.m_phases[iPhase]; + int grainSize = 1; + leastSquaresResidual += btParallelSum(phase.begin, phase.end, grainSize, loop); + } + } + else + { + // no batching, also ignores SOLVER_RANDMIZE_ORDER + for (int j = 0; j < numRollingFrictionPoolConstraints; j++) + { + btSolverConstraint& rollingFrictionConstraint = m_tmpSolverContactRollingFrictionConstraintPool[j]; + if (rollingFrictionConstraint.m_frictionIndex >= 0) + { + btScalar totalImpulse = m_tmpSolverContactConstraintPool[rollingFrictionConstraint.m_frictionIndex].m_appliedImpulse; + if (totalImpulse > 0.0f) + { + btScalar rollingFrictionMagnitude = rollingFrictionConstraint.m_friction * totalImpulse; + if (rollingFrictionMagnitude > rollingFrictionConstraint.m_friction) + rollingFrictionMagnitude = rollingFrictionConstraint.m_friction; - rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude; - rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude; + rollingFrictionConstraint.m_lowerLimit = -rollingFrictionMagnitude; + rollingFrictionConstraint.m_upperLimit = rollingFrictionMagnitude; - btScalar residual = resolveSingleConstraintRowGeneric( m_tmpSolverBodyPool[ rollingFrictionConstraint.m_solverBodyIdA ], m_tmpSolverBodyPool[ rollingFrictionConstraint.m_solverBodyIdB ], rollingFrictionConstraint ); - leastSquaresResidual += residual*residual; - } - } - } - } - return leastSquaresResidual; + btScalar residual = resolveSingleConstraintRowGeneric(m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdA], m_tmpSolverBodyPool[rollingFrictionConstraint.m_solverBodyIdB], rollingFrictionConstraint); + leastSquaresResidual += residual * residual; + } + } + } + } + return leastSquaresResidual; } - -void btSequentialImpulseConstraintSolverMt::internalWriteBackContacts( int iBegin, int iEnd, const btContactSolverInfo& infoGlobal ) +void btSequentialImpulseConstraintSolverMt::internalWriteBackContacts(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal) { - BT_PROFILE("internalWriteBackContacts"); - writeBackContacts(iBegin, iEnd, infoGlobal); - //for ( int iContact = iBegin; iContact < iEnd; ++iContact) - //{ - // const btSolverConstraint& contactConstraint = m_tmpSolverContactConstraintPool[ iContact ]; - // btManifoldPoint* pt = (btManifoldPoint*) contactConstraint.m_originalContactPoint; - // btAssert( pt ); - // pt->m_appliedImpulse = contactConstraint.m_appliedImpulse; - // pt->m_appliedImpulseLateral1 = m_tmpSolverContactFrictionConstraintPool[ contactConstraint.m_frictionIndex ].m_appliedImpulse; - // if ( m_numFrictionDirections == 2 ) - // { - // pt->m_appliedImpulseLateral2 = m_tmpSolverContactFrictionConstraintPool[ contactConstraint.m_frictionIndex + 1 ].m_appliedImpulse; - // } - //} + BT_PROFILE("internalWriteBackContacts"); + writeBackContacts(iBegin, iEnd, infoGlobal); + //for ( int iContact = iBegin; iContact < iEnd; ++iContact) + //{ + // const btSolverConstraint& contactConstraint = m_tmpSolverContactConstraintPool[ iContact ]; + // btManifoldPoint* pt = (btManifoldPoint*) contactConstraint.m_originalContactPoint; + // btAssert( pt ); + // pt->m_appliedImpulse = contactConstraint.m_appliedImpulse; + // pt->m_appliedImpulseLateral1 = m_tmpSolverContactFrictionConstraintPool[ contactConstraint.m_frictionIndex ].m_appliedImpulse; + // if ( m_numFrictionDirections == 2 ) + // { + // pt->m_appliedImpulseLateral2 = m_tmpSolverContactFrictionConstraintPool[ contactConstraint.m_frictionIndex + 1 ].m_appliedImpulse; + // } + //} } - -void btSequentialImpulseConstraintSolverMt::internalWriteBackJoints( int iBegin, int iEnd, const btContactSolverInfo& infoGlobal ) +void btSequentialImpulseConstraintSolverMt::internalWriteBackJoints(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal) { BT_PROFILE("internalWriteBackJoints"); - writeBackJoints(iBegin, iEnd, infoGlobal); + writeBackJoints(iBegin, iEnd, infoGlobal); } - -void btSequentialImpulseConstraintSolverMt::internalWriteBackBodies( int iBegin, int iEnd, const btContactSolverInfo& infoGlobal ) +void btSequentialImpulseConstraintSolverMt::internalWriteBackBodies(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal) { BT_PROFILE("internalWriteBackBodies"); - writeBackBodies( iBegin, iEnd, infoGlobal ); + writeBackBodies(iBegin, iEnd, infoGlobal); } - struct WriteContactPointsLoop : public btIParallelForBody { - btSequentialImpulseConstraintSolverMt* m_solver; - const btContactSolverInfo* m_infoGlobal; + btSequentialImpulseConstraintSolverMt* m_solver; + const btContactSolverInfo* m_infoGlobal; - WriteContactPointsLoop( btSequentialImpulseConstraintSolverMt* solver, const btContactSolverInfo& infoGlobal ) - { - m_solver = solver; - m_infoGlobal = &infoGlobal; - } - void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - m_solver->internalWriteBackContacts( iBegin, iEnd, *m_infoGlobal ); - } + WriteContactPointsLoop(btSequentialImpulseConstraintSolverMt* solver, const btContactSolverInfo& infoGlobal) + { + m_solver = solver; + m_infoGlobal = &infoGlobal; + } + void forLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + m_solver->internalWriteBackContacts(iBegin, iEnd, *m_infoGlobal); + } }; - struct WriteJointsLoop : public btIParallelForBody { - btSequentialImpulseConstraintSolverMt* m_solver; - const btContactSolverInfo* m_infoGlobal; + btSequentialImpulseConstraintSolverMt* m_solver; + const btContactSolverInfo* m_infoGlobal; - WriteJointsLoop( btSequentialImpulseConstraintSolverMt* solver, const btContactSolverInfo& infoGlobal ) - { - m_solver = solver; - m_infoGlobal = &infoGlobal; - } - void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - m_solver->internalWriteBackJoints( iBegin, iEnd, *m_infoGlobal ); - } + WriteJointsLoop(btSequentialImpulseConstraintSolverMt* solver, const btContactSolverInfo& infoGlobal) + { + m_solver = solver; + m_infoGlobal = &infoGlobal; + } + void forLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + m_solver->internalWriteBackJoints(iBegin, iEnd, *m_infoGlobal); + } }; - struct WriteBodiesLoop : public btIParallelForBody { - btSequentialImpulseConstraintSolverMt* m_solver; - const btContactSolverInfo* m_infoGlobal; + btSequentialImpulseConstraintSolverMt* m_solver; + const btContactSolverInfo* m_infoGlobal; - WriteBodiesLoop( btSequentialImpulseConstraintSolverMt* solver, const btContactSolverInfo& infoGlobal ) - { - m_solver = solver; - m_infoGlobal = &infoGlobal; - } - void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - m_solver->internalWriteBackBodies( iBegin, iEnd, *m_infoGlobal ); - } + WriteBodiesLoop(btSequentialImpulseConstraintSolverMt* solver, const btContactSolverInfo& infoGlobal) + { + m_solver = solver; + m_infoGlobal = &infoGlobal; + } + void forLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + m_solver->internalWriteBackBodies(iBegin, iEnd, *m_infoGlobal); + } }; - btScalar btSequentialImpulseConstraintSolverMt::solveGroupCacheFriendlyFinish(btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal) { BT_PROFILE("solveGroupCacheFriendlyFinish"); if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) - { - WriteContactPointsLoop loop( this, infoGlobal ); - int grainSize = 500; - btParallelFor( 0, m_tmpSolverContactConstraintPool.size(), grainSize, loop ); - } + { + WriteContactPointsLoop loop(this, infoGlobal); + int grainSize = 500; + btParallelFor(0, m_tmpSolverContactConstraintPool.size(), grainSize, loop); + } - { - WriteJointsLoop loop( this, infoGlobal ); - int grainSize = 400; - btParallelFor( 0, m_tmpSolverNonContactConstraintPool.size(), grainSize, loop ); - } - { - WriteBodiesLoop loop( this, infoGlobal ); - int grainSize = 100; - btParallelFor( 0, m_tmpSolverBodyPool.size(), grainSize, loop ); - } + { + WriteJointsLoop loop(this, infoGlobal); + int grainSize = 400; + btParallelFor(0, m_tmpSolverNonContactConstraintPool.size(), grainSize, loop); + } + { + WriteBodiesLoop loop(this, infoGlobal); + int grainSize = 100; + btParallelFor(0, m_tmpSolverBodyPool.size(), grainSize, loop); + } m_tmpSolverContactConstraintPool.resizeNoInitialize(0); m_tmpSolverNonContactConstraintPool.resizeNoInitialize(0); @@ -1618,4 +1552,3 @@ btScalar btSequentialImpulseConstraintSolverMt::solveGroupCacheFriendlyFinish(bt m_tmpSolverBodyPool.resizeNoInitialize(0); return 0.f; } - diff --git a/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolverMt.h b/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolverMt.h index 55d53474c..1861ddd7d 100644 --- a/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolverMt.h +++ b/src/BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolverMt.h @@ -53,102 +53,98 @@ subject to the following restrictions: /// because floating point addition is not associative due to rounding errors. /// The task scheduler can and should ensure that the result of any parallelSum operation is deterministic. /// -ATTRIBUTE_ALIGNED16(class) btSequentialImpulseConstraintSolverMt : public btSequentialImpulseConstraintSolver +ATTRIBUTE_ALIGNED16(class) +btSequentialImpulseConstraintSolverMt : public btSequentialImpulseConstraintSolver { public: - virtual void solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer) BT_OVERRIDE; - virtual btScalar solveSingleIteration(int iteration, btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer) BT_OVERRIDE; - virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer) BT_OVERRIDE; - virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal) BT_OVERRIDE; + virtual void solveGroupCacheFriendlySplitImpulseIterations(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer) BT_OVERRIDE; + virtual btScalar solveSingleIteration(int iteration, btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer) BT_OVERRIDE; + virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer) BT_OVERRIDE; + virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject * *bodies, int numBodies, const btContactSolverInfo& infoGlobal) BT_OVERRIDE; - // temp struct used to collect info from persistent manifolds into a cache-friendly struct using multiple threads - struct btContactManifoldCachedInfo - { - static const int MAX_NUM_CONTACT_POINTS = 4; + // temp struct used to collect info from persistent manifolds into a cache-friendly struct using multiple threads + struct btContactManifoldCachedInfo + { + static const int MAX_NUM_CONTACT_POINTS = 4; - int numTouchingContacts; - int solverBodyIds[ 2 ]; - int contactIndex; - int rollingFrictionIndex; - bool contactHasRollingFriction[ MAX_NUM_CONTACT_POINTS ]; - btManifoldPoint* contactPoints[ MAX_NUM_CONTACT_POINTS ]; - }; - // temp struct used for setting up joint constraints in parallel - struct JointParams - { - int m_solverConstraint; - int m_solverBodyA; - int m_solverBodyB; - }; - void internalInitMultipleJoints(btTypedConstraint** constraints, int iBegin, int iEnd); - void internalConvertMultipleJoints( const btAlignedObjectArray& jointParamsArray, btTypedConstraint** constraints, int iBegin, int iEnd, const btContactSolverInfo& infoGlobal ); + int numTouchingContacts; + int solverBodyIds[2]; + int contactIndex; + int rollingFrictionIndex; + bool contactHasRollingFriction[MAX_NUM_CONTACT_POINTS]; + btManifoldPoint* contactPoints[MAX_NUM_CONTACT_POINTS]; + }; + // temp struct used for setting up joint constraints in parallel + struct JointParams + { + int m_solverConstraint; + int m_solverBodyA; + int m_solverBodyB; + }; + void internalInitMultipleJoints(btTypedConstraint * *constraints, int iBegin, int iEnd); + void internalConvertMultipleJoints(const btAlignedObjectArray& jointParamsArray, btTypedConstraint** constraints, int iBegin, int iEnd, const btContactSolverInfo& infoGlobal); - // parameters to control batching - static bool s_allowNestedParallelForLoops; // whether to allow nested parallel operations - static int s_minimumContactManifoldsForBatching; // don't even try to batch if fewer manifolds than this - static btBatchedConstraints::BatchingMethod s_contactBatchingMethod; - static btBatchedConstraints::BatchingMethod s_jointBatchingMethod; - static int s_minBatchSize; // desired number of constraints per batch - static int s_maxBatchSize; + // parameters to control batching + static bool s_allowNestedParallelForLoops; // whether to allow nested parallel operations + static int s_minimumContactManifoldsForBatching; // don't even try to batch if fewer manifolds than this + static btBatchedConstraints::BatchingMethod s_contactBatchingMethod; + static btBatchedConstraints::BatchingMethod s_jointBatchingMethod; + static int s_minBatchSize; // desired number of constraints per batch + static int s_maxBatchSize; protected: - static const int CACHE_LINE_SIZE = 64; + static const int CACHE_LINE_SIZE = 64; - btBatchedConstraints m_batchedContactConstraints; - btBatchedConstraints m_batchedJointConstraints; - int m_numFrictionDirections; - bool m_useBatching; - bool m_useObsoleteJointConstraints; - btAlignedObjectArray m_manifoldCachedInfoArray; - btAlignedObjectArray m_rollingFrictionIndexTable; // lookup table mapping contact index to rolling friction index - btSpinMutex m_bodySolverArrayMutex; - char m_antiFalseSharingPadding[CACHE_LINE_SIZE]; // padding to keep mutexes in separate cachelines - btSpinMutex m_kinematicBodyUniqueIdToSolverBodyTableMutex; - btAlignedObjectArray m_scratchMemory; + btBatchedConstraints m_batchedContactConstraints; + btBatchedConstraints m_batchedJointConstraints; + int m_numFrictionDirections; + bool m_useBatching; + bool m_useObsoleteJointConstraints; + btAlignedObjectArray m_manifoldCachedInfoArray; + btAlignedObjectArray m_rollingFrictionIndexTable; // lookup table mapping contact index to rolling friction index + btSpinMutex m_bodySolverArrayMutex; + char m_antiFalseSharingPadding[CACHE_LINE_SIZE]; // padding to keep mutexes in separate cachelines + btSpinMutex m_kinematicBodyUniqueIdToSolverBodyTableMutex; + btAlignedObjectArray m_scratchMemory; - virtual void randomizeConstraintOrdering( int iteration, int numIterations ); - virtual btScalar resolveAllJointConstraints( int iteration ); - virtual btScalar resolveAllContactConstraints(); - virtual btScalar resolveAllContactFrictionConstraints(); - virtual btScalar resolveAllContactConstraintsInterleaved(); - virtual btScalar resolveAllRollingFrictionConstraints(); + virtual void randomizeConstraintOrdering(int iteration, int numIterations); + virtual btScalar resolveAllJointConstraints(int iteration); + virtual btScalar resolveAllContactConstraints(); + virtual btScalar resolveAllContactFrictionConstraints(); + virtual btScalar resolveAllContactConstraintsInterleaved(); + virtual btScalar resolveAllRollingFrictionConstraints(); - virtual void setupBatchedContactConstraints(); - virtual void setupBatchedJointConstraints(); - virtual void convertJoints(btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal) BT_OVERRIDE; - virtual void convertContacts(btPersistentManifold** manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal) BT_OVERRIDE; - virtual void convertBodies(btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal) BT_OVERRIDE; + virtual void setupBatchedContactConstraints(); + virtual void setupBatchedJointConstraints(); + virtual void convertJoints(btTypedConstraint * *constraints, int numConstraints, const btContactSolverInfo& infoGlobal) BT_OVERRIDE; + virtual void convertContacts(btPersistentManifold * *manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal) BT_OVERRIDE; + virtual void convertBodies(btCollisionObject * *bodies, int numBodies, const btContactSolverInfo& infoGlobal) BT_OVERRIDE; - int getOrInitSolverBodyThreadsafe(btCollisionObject& body, btScalar timeStep); - void allocAllContactConstraints(btPersistentManifold** manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal); - void setupAllContactConstraints(const btContactSolverInfo& infoGlobal); - void randomizeBatchedConstraintOrdering( btBatchedConstraints* batchedConstraints ); + int getOrInitSolverBodyThreadsafe(btCollisionObject & body, btScalar timeStep); + void allocAllContactConstraints(btPersistentManifold * *manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal); + void setupAllContactConstraints(const btContactSolverInfo& infoGlobal); + void randomizeBatchedConstraintOrdering(btBatchedConstraints * batchedConstraints); public: - BT_DECLARE_ALIGNED_ALLOCATOR(); btSequentialImpulseConstraintSolverMt(); virtual ~btSequentialImpulseConstraintSolverMt(); - btScalar resolveMultipleJointConstraints( const btAlignedObjectArray& consIndices, int batchBegin, int batchEnd, int iteration ); - btScalar resolveMultipleContactConstraints( const btAlignedObjectArray& consIndices, int batchBegin, int batchEnd ); - btScalar resolveMultipleContactSplitPenetrationImpulseConstraints( const btAlignedObjectArray& consIndices, int batchBegin, int batchEnd ); - btScalar resolveMultipleContactFrictionConstraints( const btAlignedObjectArray& consIndices, int batchBegin, int batchEnd ); - btScalar resolveMultipleContactRollingFrictionConstraints( const btAlignedObjectArray& consIndices, int batchBegin, int batchEnd ); - btScalar resolveMultipleContactConstraintsInterleaved( const btAlignedObjectArray& contactIndices, int batchBegin, int batchEnd ); + btScalar resolveMultipleJointConstraints(const btAlignedObjectArray& consIndices, int batchBegin, int batchEnd, int iteration); + btScalar resolveMultipleContactConstraints(const btAlignedObjectArray& consIndices, int batchBegin, int batchEnd); + btScalar resolveMultipleContactSplitPenetrationImpulseConstraints(const btAlignedObjectArray& consIndices, int batchBegin, int batchEnd); + btScalar resolveMultipleContactFrictionConstraints(const btAlignedObjectArray& consIndices, int batchBegin, int batchEnd); + btScalar resolveMultipleContactRollingFrictionConstraints(const btAlignedObjectArray& consIndices, int batchBegin, int batchEnd); + btScalar resolveMultipleContactConstraintsInterleaved(const btAlignedObjectArray& contactIndices, int batchBegin, int batchEnd); - void internalCollectContactManifoldCachedInfo(btContactManifoldCachedInfo* cachedInfoArray, btPersistentManifold** manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal); - void internalAllocContactConstraints(const btContactManifoldCachedInfo* cachedInfoArray, int numManifolds); - void internalSetupContactConstraints(int iContactConstraint, const btContactSolverInfo& infoGlobal); - void internalConvertBodies(btCollisionObject** bodies, int iBegin, int iEnd, const btContactSolverInfo& infoGlobal); - void internalWriteBackContacts(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal); - void internalWriteBackJoints(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal); - void internalWriteBackBodies(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal); + void internalCollectContactManifoldCachedInfo(btContactManifoldCachedInfo * cachedInfoArray, btPersistentManifold * *manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal); + void internalAllocContactConstraints(const btContactManifoldCachedInfo* cachedInfoArray, int numManifolds); + void internalSetupContactConstraints(int iContactConstraint, const btContactSolverInfo& infoGlobal); + void internalConvertBodies(btCollisionObject * *bodies, int iBegin, int iEnd, const btContactSolverInfo& infoGlobal); + void internalWriteBackContacts(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal); + void internalWriteBackJoints(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal); + void internalWriteBackBodies(int iBegin, int iEnd, const btContactSolverInfo& infoGlobal); }; - - - -#endif //BT_SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_MT_H - +#endif //BT_SEQUENTIAL_IMPULSE_CONSTRAINT_SOLVER_MT_H diff --git a/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp index d63cef031..cac5302a7 100755 --- a/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp +++ b/src/BulletDynamics/ConstraintSolver/btSliderConstraint.cpp @@ -18,8 +18,6 @@ Added by Roman Ponomarev (rponom@gmail.com) April 04, 2008 */ - - #include "btSliderConstraint.h" #include "BulletDynamics/Dynamics/btRigidBody.h" #include "LinearMath/btTransformUtil.h" @@ -29,10 +27,10 @@ April 04, 2008 void btSliderConstraint::initParams() { - m_lowerLinLimit = btScalar(1.0); - m_upperLinLimit = btScalar(-1.0); - m_lowerAngLimit = btScalar(0.); - m_upperAngLimit = btScalar(0.); + m_lowerLinLimit = btScalar(1.0); + m_upperLinLimit = btScalar(-1.0); + m_lowerAngLimit = btScalar(0.); + m_upperAngLimit = btScalar(0.); m_softnessDirLin = SLIDER_CONSTRAINT_DEF_SOFTNESS; m_restitutionDirLin = SLIDER_CONSTRAINT_DEF_RESTITUTION; m_dampingDirLin = btScalar(0.); @@ -59,13 +57,13 @@ void btSliderConstraint::initParams() m_cfmLimAng = SLIDER_CONSTRAINT_DEF_CFM; m_poweredLinMotor = false; - m_targetLinMotorVelocity = btScalar(0.); - m_maxLinMotorForce = btScalar(0.); + m_targetLinMotorVelocity = btScalar(0.); + m_maxLinMotorForce = btScalar(0.); m_accumulatedLinMotorImpulse = btScalar(0.0); m_poweredAngMotor = false; - m_targetAngMotorVelocity = btScalar(0.); - m_maxAngMotorForce = btScalar(0.); + m_targetAngMotorVelocity = btScalar(0.); + m_maxAngMotorForce = btScalar(0.); m_accumulatedAngMotorImpulse = btScalar(0.0); m_flags = 0; @@ -73,43 +71,32 @@ void btSliderConstraint::initParams() m_useOffsetForConstraintFrame = USE_OFFSET_FOR_CONSTANT_FRAME; - calculateTransforms(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); + calculateTransforms(m_rbA.getCenterOfMassTransform(), m_rbB.getCenterOfMassTransform()); } - - - - btSliderConstraint::btSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA) - : btTypedConstraint(SLIDER_CONSTRAINT_TYPE, rbA, rbB), - m_useSolveConstraintObsolete(false), - m_frameInA(frameInA), - m_frameInB(frameInB), - m_useLinearReferenceFrameA(useLinearReferenceFrameA) + : btTypedConstraint(SLIDER_CONSTRAINT_TYPE, rbA, rbB), + m_useSolveConstraintObsolete(false), + m_frameInA(frameInA), + m_frameInB(frameInB), + m_useLinearReferenceFrameA(useLinearReferenceFrameA) { initParams(); } - - btSliderConstraint::btSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA) - : btTypedConstraint(SLIDER_CONSTRAINT_TYPE, getFixedBody(), rbB), - m_useSolveConstraintObsolete(false), - m_frameInB(frameInB), - m_useLinearReferenceFrameA(useLinearReferenceFrameA) + : btTypedConstraint(SLIDER_CONSTRAINT_TYPE, getFixedBody(), rbB), + m_useSolveConstraintObsolete(false), + m_frameInB(frameInB), + m_useLinearReferenceFrameA(useLinearReferenceFrameA) { ///not providing rigidbody A means implicitly using worldspace for body A m_frameInA = rbB.getCenterOfMassTransform() * m_frameInB; -// m_frameInA.getOrigin() = m_rbA.getCenterOfMassTransform()(m_frameInA.getOrigin()); + // m_frameInA.getOrigin() = m_rbA.getCenterOfMassTransform()(m_frameInA.getOrigin()); initParams(); } - - - - - void btSliderConstraint::getInfo1(btConstraintInfo1* info) { if (m_useSolveConstraintObsolete) @@ -119,46 +106,39 @@ void btSliderConstraint::getInfo1(btConstraintInfo1* info) } else { - info->m_numConstraintRows = 4; // Fixed 2 linear + 2 angular - info->nub = 2; + info->m_numConstraintRows = 4; // Fixed 2 linear + 2 angular + info->nub = 2; //prepare constraint - calculateTransforms(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); + calculateTransforms(m_rbA.getCenterOfMassTransform(), m_rbB.getCenterOfMassTransform()); testAngLimits(); testLinLimits(); - if(getSolveLinLimit() || getPoweredLinMotor()) + if (getSolveLinLimit() || getPoweredLinMotor()) { - info->m_numConstraintRows++; // limit 3rd linear as well - info->nub--; + info->m_numConstraintRows++; // limit 3rd linear as well + info->nub--; } - if(getSolveAngLimit() || getPoweredAngMotor()) + if (getSolveAngLimit() || getPoweredAngMotor()) { - info->m_numConstraintRows++; // limit 3rd angular as well - info->nub--; + info->m_numConstraintRows++; // limit 3rd angular as well + info->nub--; } } } void btSliderConstraint::getInfo1NonVirtual(btConstraintInfo1* info) { - - info->m_numConstraintRows = 6; // Fixed 2 linear + 2 angular + 1 limit (even if not used) - info->nub = 0; + info->m_numConstraintRows = 6; // Fixed 2 linear + 2 angular + 1 limit (even if not used) + info->nub = 0; } void btSliderConstraint::getInfo2(btConstraintInfo2* info) { - getInfo2NonVirtual(info,m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform(), m_rbA.getLinearVelocity(),m_rbB.getLinearVelocity(), m_rbA.getInvMass(),m_rbB.getInvMass()); + getInfo2NonVirtual(info, m_rbA.getCenterOfMassTransform(), m_rbB.getCenterOfMassTransform(), m_rbA.getLinearVelocity(), m_rbB.getLinearVelocity(), m_rbA.getInvMass(), m_rbB.getInvMass()); } - - - - - - -void btSliderConstraint::calculateTransforms(const btTransform& transA,const btTransform& transB) +void btSliderConstraint::calculateTransforms(const btTransform& transA, const btTransform& transB) { - if(m_useLinearReferenceFrameA || (!m_useSolveConstraintObsolete)) + if (m_useLinearReferenceFrameA || (!m_useSolveConstraintObsolete)) { m_calculatedTransformA = transA * m_frameInA; m_calculatedTransformB = transB * m_frameInB; @@ -170,8 +150,8 @@ void btSliderConstraint::calculateTransforms(const btTransform& transA,const btT } m_realPivotAInW = m_calculatedTransformA.getOrigin(); m_realPivotBInW = m_calculatedTransformB.getOrigin(); - m_sliderAxis = m_calculatedTransformA.getBasis().getColumn(0); // along X - if(m_useLinearReferenceFrameA || m_useSolveConstraintObsolete) + m_sliderAxis = m_calculatedTransformA.getBasis().getColumn(0); // along X + if (m_useLinearReferenceFrameA || m_useSolveConstraintObsolete) { m_delta = m_realPivotBInW - m_realPivotAInW; } @@ -180,30 +160,28 @@ void btSliderConstraint::calculateTransforms(const btTransform& transA,const btT m_delta = m_realPivotAInW - m_realPivotBInW; } m_projPivotInW = m_realPivotAInW + m_sliderAxis.dot(m_delta) * m_sliderAxis; - btVector3 normalWorld; - int i; - //linear part - for(i = 0; i < 3; i++) - { + btVector3 normalWorld; + int i; + //linear part + for (i = 0; i < 3; i++) + { normalWorld = m_calculatedTransformA.getBasis().getColumn(i); m_depth[i] = m_delta.dot(normalWorld); - } + } } - - void btSliderConstraint::testLinLimits(void) { m_solveLinLim = false; m_linPos = m_depth[0]; - if(m_lowerLinLimit <= m_upperLinLimit) + if (m_lowerLinLimit <= m_upperLinLimit) { - if(m_depth[0] > m_upperLinLimit) + if (m_depth[0] > m_upperLinLimit) { m_depth[0] -= m_upperLinLimit; m_solveLinLim = true; } - else if(m_depth[0] < m_lowerLinLimit) + else if (m_depth[0] < m_lowerLinLimit) { m_depth[0] -= m_lowerLinLimit; m_solveLinLim = true; @@ -219,27 +197,25 @@ void btSliderConstraint::testLinLimits(void) } } - - void btSliderConstraint::testAngLimits(void) { m_angDepth = btScalar(0.); m_solveAngLim = false; - if(m_lowerAngLimit <= m_upperAngLimit) + if (m_lowerAngLimit <= m_upperAngLimit) { const btVector3 axisA0 = m_calculatedTransformA.getBasis().getColumn(1); const btVector3 axisA1 = m_calculatedTransformA.getBasis().getColumn(2); const btVector3 axisB0 = m_calculatedTransformB.getBasis().getColumn(1); -// btScalar rot = btAtan2Fast(axisB0.dot(axisA1), axisB0.dot(axisA0)); - btScalar rot = btAtan2(axisB0.dot(axisA1), axisB0.dot(axisA0)); + // btScalar rot = btAtan2Fast(axisB0.dot(axisA1), axisB0.dot(axisA0)); + btScalar rot = btAtan2(axisB0.dot(axisA1), axisB0.dot(axisA0)); rot = btAdjustAngleToLimits(rot, m_lowerAngLimit, m_upperAngLimit); m_angPos = rot; - if(rot < m_lowerAngLimit) + if (rot < m_lowerAngLimit) { m_angDepth = rot - m_lowerAngLimit; m_solveAngLim = true; - } - else if(rot > m_upperAngLimit) + } + else if (rot > m_upperAngLimit) { m_angDepth = rot - m_upperAngLimit; m_solveAngLim = true; @@ -255,8 +231,6 @@ btVector3 btSliderConstraint::getAncorInA(void) return ancorInA; } - - btVector3 btSliderConstraint::getAncorInB(void) { btVector3 ancorInB; @@ -264,17 +238,16 @@ btVector3 btSliderConstraint::getAncorInB(void) return ancorInB; } - -void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTransform& transA,const btTransform& transB, const btVector3& linVelA,const btVector3& linVelB, btScalar rbAinvMass,btScalar rbBinvMass ) +void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, btScalar rbAinvMass, btScalar rbBinvMass) { const btTransform& trA = getCalculatedTransformA(); const btTransform& trB = getCalculatedTransformB(); - + btAssert(!m_useSolveConstraintObsolete); int i, s = info->rowskip; - + btScalar signFact = m_useLinearReferenceFrameA ? btScalar(1.0f) : btScalar(-1.0f); - + // difference between frames in WCS btVector3 ofs = trB.getOrigin() - trA.getOrigin(); // now get weight factors depending on masses @@ -283,11 +256,11 @@ void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTra bool hasStaticBody = (miA < SIMD_EPSILON) || (miB < SIMD_EPSILON); btScalar miS = miA + miB; btScalar factA, factB; - if(miS > btScalar(0.f)) + if (miS > btScalar(0.f)) { factA = miB / miS; } - else + else { factA = btScalar(0.5f); } @@ -295,17 +268,17 @@ void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTra btVector3 ax1, p, q; btVector3 ax1A = trA.getBasis().getColumn(0); btVector3 ax1B = trB.getBasis().getColumn(0); - if(m_useOffsetForConstraintFrame) + if (m_useOffsetForConstraintFrame) { // get the desired direction of slider axis // as weighted sum of X-orthos of frameA and frameB in WCS ax1 = ax1A * factA + ax1B * factB; ax1.normalize(); // construct two orthos to slider axis - btPlaneSpace1 (ax1, p, q); + btPlaneSpace1(ax1, p, q); } else - { // old way - use frameA + { // old way - use frameA ax1 = trA.getBasis().getColumn(0); // get 2 orthos to slider axis (Y, Z) p = trA.getBasis().getColumn(1); @@ -322,16 +295,16 @@ void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTra info->m_J1angularAxis[0] = p[0]; info->m_J1angularAxis[1] = p[1]; info->m_J1angularAxis[2] = p[2]; - info->m_J1angularAxis[s+0] = q[0]; - info->m_J1angularAxis[s+1] = q[1]; - info->m_J1angularAxis[s+2] = q[2]; + info->m_J1angularAxis[s + 0] = q[0]; + info->m_J1angularAxis[s + 1] = q[1]; + info->m_J1angularAxis[s + 2] = q[2]; info->m_J2angularAxis[0] = -p[0]; info->m_J2angularAxis[1] = -p[1]; info->m_J2angularAxis[2] = -p[2]; - info->m_J2angularAxis[s+0] = -q[0]; - info->m_J2angularAxis[s+1] = -q[1]; - info->m_J2angularAxis[s+2] = -q[2]; + info->m_J2angularAxis[s + 0] = -q[0]; + info->m_J2angularAxis[s + 1] = -q[1]; + info->m_J2angularAxis[s + 2] = -q[2]; // compute the right hand side of the constraint equation. set relative // body velocities along p and q to bring the slider back into alignment. // if ax1A,ax1B are the unit length slider axes as computed from bodyA and @@ -347,25 +320,25 @@ void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTra // angular_velocity = (erp*fps) * (ax1 x ax2) // ax1 x ax2 is in the plane space of ax1, so we project the angular // velocity to p and q to find the right hand side. -// btScalar k = info->fps * info->erp * getSoftnessOrthoAng(); + // btScalar k = info->fps * info->erp * getSoftnessOrthoAng(); btScalar currERP = (m_flags & BT_SLIDER_FLAGS_ERP_ORTANG) ? m_softnessOrthoAng : m_softnessOrthoAng * info->erp; btScalar k = info->fps * currERP; btVector3 u = ax1A.cross(ax1B); info->m_constraintError[0] = k * u.dot(p); info->m_constraintError[s] = k * u.dot(q); - if(m_flags & BT_SLIDER_FLAGS_CFM_ORTANG) + if (m_flags & BT_SLIDER_FLAGS_CFM_ORTANG) { info->cfm[0] = m_cfmOrthoAng; info->cfm[s] = m_cfmOrthoAng; } - int nrow = 1; // last filled row + int nrow = 1; // last filled row int srow; btScalar limit_err; int limit; - // next two rows. + // next two rows. // we want: velA + wA x relA == velB + wB x relB ... but this would // result in three equations, so we project along two orthos to the slider axis @@ -375,8 +348,8 @@ void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTra int s2 = nrow * s; nrow++; int s3 = nrow * s; - btVector3 tmpA(0,0,0), tmpB(0,0,0), relA(0,0,0), relB(0,0,0), c(0,0,0); - if(m_useOffsetForConstraintFrame) + btVector3 tmpA(0, 0, 0), tmpB(0, 0, 0), relA(0, 0, 0), relB(0, 0, 0), c(0, 0, 0); + if (m_useOffsetForConstraintFrame) { // get vector from bodyB to frameB in WCS relB = trB.getOrigin() - bodyB_trans.getOrigin(); @@ -398,7 +371,7 @@ void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTra // now choose average ortho to slider axis p = orthoB * factA + orthoA * factB; btScalar len2 = p.length2(); - if(len2 > SIMD_EPSILON) + if (len2 > SIMD_EPSILON) { p /= btSqrt(len2); } @@ -411,38 +384,38 @@ void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTra // fill two rows tmpA = relA.cross(p); tmpB = relB.cross(p); - for (i=0; i<3; i++) info->m_J1angularAxis[s2+i] = tmpA[i]; - for (i=0; i<3; i++) info->m_J2angularAxis[s2+i] = -tmpB[i]; + for (i = 0; i < 3; i++) info->m_J1angularAxis[s2 + i] = tmpA[i]; + for (i = 0; i < 3; i++) info->m_J2angularAxis[s2 + i] = -tmpB[i]; tmpA = relA.cross(q); tmpB = relB.cross(q); - if(hasStaticBody && getSolveAngLimit()) - { // to make constraint between static and dynamic objects more rigid + if (hasStaticBody && getSolveAngLimit()) + { // to make constraint between static and dynamic objects more rigid // remove wA (or wB) from equation if angular limit is hit tmpB *= factB; tmpA *= factA; } - for (i=0; i<3; i++) info->m_J1angularAxis[s3+i] = tmpA[i]; - for (i=0; i<3; i++) info->m_J2angularAxis[s3+i] = -tmpB[i]; - for (i=0; i<3; i++) info->m_J1linearAxis[s2+i] = p[i]; - for (i=0; i<3; i++) info->m_J1linearAxis[s3+i] = q[i]; - for (i=0; i<3; i++) info->m_J2linearAxis[s2+i] = -p[i]; - for (i=0; i<3; i++) info->m_J2linearAxis[s3+i] = -q[i]; + for (i = 0; i < 3; i++) info->m_J1angularAxis[s3 + i] = tmpA[i]; + for (i = 0; i < 3; i++) info->m_J2angularAxis[s3 + i] = -tmpB[i]; + for (i = 0; i < 3; i++) info->m_J1linearAxis[s2 + i] = p[i]; + for (i = 0; i < 3; i++) info->m_J1linearAxis[s3 + i] = q[i]; + for (i = 0; i < 3; i++) info->m_J2linearAxis[s2 + i] = -p[i]; + for (i = 0; i < 3; i++) info->m_J2linearAxis[s3 + i] = -q[i]; } else - { // old way - maybe incorrect if bodies are not on the slider axis + { // old way - maybe incorrect if bodies are not on the slider axis // see discussion "Bug in slider constraint" http://bulletphysics.org/Bullet/phpBB3/viewtopic.php?f=9&t=4024&start=0 c = bodyB_trans.getOrigin() - bodyA_trans.getOrigin(); btVector3 tmp = c.cross(p); - for (i=0; i<3; i++) info->m_J1angularAxis[s2+i] = factA*tmp[i]; - for (i=0; i<3; i++) info->m_J2angularAxis[s2+i] = factB*tmp[i]; + for (i = 0; i < 3; i++) info->m_J1angularAxis[s2 + i] = factA * tmp[i]; + for (i = 0; i < 3; i++) info->m_J2angularAxis[s2 + i] = factB * tmp[i]; tmp = c.cross(q); - for (i=0; i<3; i++) info->m_J1angularAxis[s3+i] = factA*tmp[i]; - for (i=0; i<3; i++) info->m_J2angularAxis[s3+i] = factB*tmp[i]; + for (i = 0; i < 3; i++) info->m_J1angularAxis[s3 + i] = factA * tmp[i]; + for (i = 0; i < 3; i++) info->m_J2angularAxis[s3 + i] = factB * tmp[i]; - for (i=0; i<3; i++) info->m_J1linearAxis[s2+i] = p[i]; - for (i=0; i<3; i++) info->m_J1linearAxis[s3+i] = q[i]; - for (i=0; i<3; i++) info->m_J2linearAxis[s2+i] = -p[i]; - for (i=0; i<3; i++) info->m_J2linearAxis[s3+i] = -q[i]; + for (i = 0; i < 3; i++) info->m_J1linearAxis[s2 + i] = p[i]; + for (i = 0; i < 3; i++) info->m_J1linearAxis[s3 + i] = q[i]; + for (i = 0; i < 3; i++) info->m_J2linearAxis[s2 + i] = -p[i]; + for (i = 0; i < 3; i++) info->m_J2linearAxis[s3 + i] = -q[i]; } // compute two elements of right hand side @@ -454,19 +427,18 @@ void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTra info->m_constraintError[s2] = rhs; rhs = k * q.dot(ofs); info->m_constraintError[s3] = rhs; - if(m_flags & BT_SLIDER_FLAGS_CFM_ORTLIN) + if (m_flags & BT_SLIDER_FLAGS_CFM_ORTLIN) { info->cfm[s2] = m_cfmOrthoLin; info->cfm[s3] = m_cfmOrthoLin; } - // check linear limits limit_err = btScalar(0.0); limit = 0; - if(getSolveLinLimit()) + if (getSolveLinLimit()) { - limit_err = getLinDepth() * signFact; + limit_err = getLinDepth() * signFact; limit = (limit_err > btScalar(0.0)) ? 2 : 1; } bool powered = getPoweredLinMotor(); @@ -475,12 +447,12 @@ void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTra { nrow++; srow = nrow * info->rowskip; - info->m_J1linearAxis[srow+0] = ax1[0]; - info->m_J1linearAxis[srow+1] = ax1[1]; - info->m_J1linearAxis[srow+2] = ax1[2]; - info->m_J2linearAxis[srow+0] = -ax1[0]; - info->m_J2linearAxis[srow+1] = -ax1[1]; - info->m_J2linearAxis[srow+2] = -ax1[2]; + info->m_J1linearAxis[srow + 0] = ax1[0]; + info->m_J1linearAxis[srow + 1] = ax1[1]; + info->m_J1linearAxis[srow + 2] = ax1[2]; + info->m_J2linearAxis[srow + 0] = -ax1[0]; + info->m_J2linearAxis[srow + 1] = -ax1[1]; + info->m_J2linearAxis[srow + 2] = -ax1[2]; // linear torque decoupling step: // // we have to be careful that the linear constraint forces (+/- ax1) applied to the two bodies @@ -488,36 +460,36 @@ void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTra // constraint force is applied at must lie along the same ax1 axis. // a torque couple will result in limited slider-jointed free // bodies from gaining angular momentum. - if(m_useOffsetForConstraintFrame) + if (m_useOffsetForConstraintFrame) { // this is needed only when bodyA and bodyB are both dynamic. - if(!hasStaticBody) + if (!hasStaticBody) { tmpA = relA.cross(ax1); tmpB = relB.cross(ax1); - info->m_J1angularAxis[srow+0] = tmpA[0]; - info->m_J1angularAxis[srow+1] = tmpA[1]; - info->m_J1angularAxis[srow+2] = tmpA[2]; - info->m_J2angularAxis[srow+0] = -tmpB[0]; - info->m_J2angularAxis[srow+1] = -tmpB[1]; - info->m_J2angularAxis[srow+2] = -tmpB[2]; + info->m_J1angularAxis[srow + 0] = tmpA[0]; + info->m_J1angularAxis[srow + 1] = tmpA[1]; + info->m_J1angularAxis[srow + 2] = tmpA[2]; + info->m_J2angularAxis[srow + 0] = -tmpB[0]; + info->m_J2angularAxis[srow + 1] = -tmpB[1]; + info->m_J2angularAxis[srow + 2] = -tmpB[2]; } } else - { // The old way. May be incorrect if bodies are not on the slider axis - btVector3 ltd; // Linear Torque Decoupling vector (a torque) + { // The old way. May be incorrect if bodies are not on the slider axis + btVector3 ltd; // Linear Torque Decoupling vector (a torque) ltd = c.cross(ax1); - info->m_J1angularAxis[srow+0] = factA*ltd[0]; - info->m_J1angularAxis[srow+1] = factA*ltd[1]; - info->m_J1angularAxis[srow+2] = factA*ltd[2]; - info->m_J2angularAxis[srow+0] = factB*ltd[0]; - info->m_J2angularAxis[srow+1] = factB*ltd[1]; - info->m_J2angularAxis[srow+2] = factB*ltd[2]; + info->m_J1angularAxis[srow + 0] = factA * ltd[0]; + info->m_J1angularAxis[srow + 1] = factA * ltd[1]; + info->m_J1angularAxis[srow + 2] = factA * ltd[2]; + info->m_J2angularAxis[srow + 0] = factB * ltd[0]; + info->m_J2angularAxis[srow + 1] = factB * ltd[1]; + info->m_J2angularAxis[srow + 2] = factB * ltd[2]; } // right-hand part btScalar lostop = getLowerLinLimit(); btScalar histop = getUpperLinLimit(); - if(limit && (lostop == histop)) + if (limit && (lostop == histop)) { // the joint motor is ineffective powered = false; } @@ -525,9 +497,9 @@ void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTra info->m_lowerLimit[srow] = 0.; info->m_upperLimit[srow] = 0.; currERP = (m_flags & BT_SLIDER_FLAGS_ERP_LIMLIN) ? m_softnessLimLin : info->erp; - if(powered) + if (powered) { - if(m_flags & BT_SLIDER_FLAGS_CFM_DIRLIN) + if (m_flags & BT_SLIDER_FLAGS_CFM_DIRLIN) { info->cfm[srow] = m_cfmDirLin; } @@ -537,41 +509,41 @@ void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTra info->m_lowerLimit[srow] += -getMaxLinMotorForce() / info->fps; info->m_upperLimit[srow] += getMaxLinMotorForce() / info->fps; } - if(limit) + if (limit) { k = info->fps * currERP; info->m_constraintError[srow] += k * limit_err; - if(m_flags & BT_SLIDER_FLAGS_CFM_LIMLIN) + if (m_flags & BT_SLIDER_FLAGS_CFM_LIMLIN) { info->cfm[srow] = m_cfmLimLin; } - if(lostop == histop) - { // limited low and high simultaneously + if (lostop == histop) + { // limited low and high simultaneously info->m_lowerLimit[srow] = -SIMD_INFINITY; info->m_upperLimit[srow] = SIMD_INFINITY; } - else if(limit == 1) - { // low limit + else if (limit == 1) + { // low limit info->m_lowerLimit[srow] = -SIMD_INFINITY; info->m_upperLimit[srow] = 0; } - else - { // high limit + else + { // high limit info->m_lowerLimit[srow] = 0; info->m_upperLimit[srow] = SIMD_INFINITY; } // bounce (we'll use slider parameter abs(1.0 - m_dampingLimLin) for that) btScalar bounce = btFabs(btScalar(1.0) - getDampingLimLin()); - if(bounce > btScalar(0.0)) + if (bounce > btScalar(0.0)) { btScalar vel = linVelA.dot(ax1); vel -= linVelB.dot(ax1); vel *= signFact; // only apply bounce if the velocity is incoming, and if the // resulting c[] exceeds what we already have. - if(limit == 1) - { // low limit - if(vel < 0) + if (limit == 1) + { // low limit + if (vel < 0) { btScalar newc = -bounce * vel; if (newc > info->m_constraintError[srow]) @@ -581,11 +553,11 @@ void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTra } } else - { // high limit - all those computations are reversed - if(vel > 0) + { // high limit - all those computations are reversed + if (vel > 0) { btScalar newc = -bounce * vel; - if(newc < info->m_constraintError[srow]) + if (newc < info->m_constraintError[srow]) { info->m_constraintError[srow] = newc; } @@ -593,40 +565,40 @@ void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTra } } info->m_constraintError[srow] *= getSoftnessLimLin(); - } // if(limit) - } // if linear limit + } // if(limit) + } // if linear limit // check angular limits limit_err = btScalar(0.0); limit = 0; - if(getSolveAngLimit()) + if (getSolveAngLimit()) { limit_err = getAngDepth(); limit = (limit_err > btScalar(0.0)) ? 1 : 2; } // if the slider has joint limits, add in the extra row powered = getPoweredAngMotor(); - if(limit || powered) + if (limit || powered) { nrow++; srow = nrow * info->rowskip; - info->m_J1angularAxis[srow+0] = ax1[0]; - info->m_J1angularAxis[srow+1] = ax1[1]; - info->m_J1angularAxis[srow+2] = ax1[2]; + info->m_J1angularAxis[srow + 0] = ax1[0]; + info->m_J1angularAxis[srow + 1] = ax1[1]; + info->m_J1angularAxis[srow + 2] = ax1[2]; - info->m_J2angularAxis[srow+0] = -ax1[0]; - info->m_J2angularAxis[srow+1] = -ax1[1]; - info->m_J2angularAxis[srow+2] = -ax1[2]; + info->m_J2angularAxis[srow + 0] = -ax1[0]; + info->m_J2angularAxis[srow + 1] = -ax1[1]; + info->m_J2angularAxis[srow + 2] = -ax1[2]; btScalar lostop = getLowerAngLimit(); btScalar histop = getUpperAngLimit(); - if(limit && (lostop == histop)) + if (limit && (lostop == histop)) { // the joint motor is ineffective powered = false; } currERP = (m_flags & BT_SLIDER_FLAGS_ERP_LIMANG) ? m_softnessLimAng : info->erp; - if(powered) + if (powered) { - if(m_flags & BT_SLIDER_FLAGS_CFM_DIRANG) + if (m_flags & BT_SLIDER_FLAGS_CFM_DIRANG) { info->cfm[srow] = m_cfmDirAng; } @@ -635,55 +607,55 @@ void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTra info->m_lowerLimit[srow] = -getMaxAngMotorForce() / info->fps; info->m_upperLimit[srow] = getMaxAngMotorForce() / info->fps; } - if(limit) + if (limit) { k = info->fps * currERP; info->m_constraintError[srow] += k * limit_err; - if(m_flags & BT_SLIDER_FLAGS_CFM_LIMANG) + if (m_flags & BT_SLIDER_FLAGS_CFM_LIMANG) { info->cfm[srow] = m_cfmLimAng; } - if(lostop == histop) + if (lostop == histop) { // limited low and high simultaneously info->m_lowerLimit[srow] = -SIMD_INFINITY; info->m_upperLimit[srow] = SIMD_INFINITY; } - else if(limit == 1) - { // low limit + else if (limit == 1) + { // low limit info->m_lowerLimit[srow] = 0; info->m_upperLimit[srow] = SIMD_INFINITY; } - else - { // high limit + else + { // high limit info->m_lowerLimit[srow] = -SIMD_INFINITY; info->m_upperLimit[srow] = 0; } // bounce (we'll use slider parameter abs(1.0 - m_dampingLimAng) for that) btScalar bounce = btFabs(btScalar(1.0) - getDampingLimAng()); - if(bounce > btScalar(0.0)) + if (bounce > btScalar(0.0)) { btScalar vel = m_rbA.getAngularVelocity().dot(ax1); vel -= m_rbB.getAngularVelocity().dot(ax1); // only apply bounce if the velocity is incoming, and if the // resulting c[] exceeds what we already have. - if(limit == 1) - { // low limit - if(vel < 0) + if (limit == 1) + { // low limit + if (vel < 0) { btScalar newc = -bounce * vel; - if(newc > info->m_constraintError[srow]) + if (newc > info->m_constraintError[srow]) { info->m_constraintError[srow] = newc; } } } else - { // high limit - all those computations are reversed - if(vel > 0) + { // high limit - all those computations are reversed + if (vel > 0) { btScalar newc = -bounce * vel; - if(newc < info->m_constraintError[srow]) + if (newc < info->m_constraintError[srow]) { info->m_constraintError[srow] = newc; } @@ -691,165 +663,161 @@ void btSliderConstraint::getInfo2NonVirtual(btConstraintInfo2* info, const btTra } } info->m_constraintError[srow] *= getSoftnessLimAng(); - } // if(limit) - } // if angular limit or powered + } // if(limit) + } // if angular limit or powered } - -///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). +///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). ///If no axis is provided, it uses the default axis for this constraint. void btSliderConstraint::setParam(int num, btScalar value, int axis) { - switch(num) + switch (num) { - case BT_CONSTRAINT_STOP_ERP : - if(axis < 1) - { - m_softnessLimLin = value; - m_flags |= BT_SLIDER_FLAGS_ERP_LIMLIN; - } - else if(axis < 3) - { - m_softnessOrthoLin = value; - m_flags |= BT_SLIDER_FLAGS_ERP_ORTLIN; - } - else if(axis == 3) - { - m_softnessLimAng = value; - m_flags |= BT_SLIDER_FLAGS_ERP_LIMANG; - } - else if(axis < 6) - { - m_softnessOrthoAng = value; - m_flags |= BT_SLIDER_FLAGS_ERP_ORTANG; - } - else - { - btAssertConstrParams(0); - } - break; - case BT_CONSTRAINT_CFM : - if(axis < 1) - { - m_cfmDirLin = value; - m_flags |= BT_SLIDER_FLAGS_CFM_DIRLIN; - } - else if(axis == 3) - { - m_cfmDirAng = value; - m_flags |= BT_SLIDER_FLAGS_CFM_DIRANG; - } - else - { - btAssertConstrParams(0); - } - break; - case BT_CONSTRAINT_STOP_CFM : - if(axis < 1) - { - m_cfmLimLin = value; - m_flags |= BT_SLIDER_FLAGS_CFM_LIMLIN; - } - else if(axis < 3) - { - m_cfmOrthoLin = value; - m_flags |= BT_SLIDER_FLAGS_CFM_ORTLIN; - } - else if(axis == 3) - { - m_cfmLimAng = value; - m_flags |= BT_SLIDER_FLAGS_CFM_LIMANG; - } - else if(axis < 6) - { - m_cfmOrthoAng = value; - m_flags |= BT_SLIDER_FLAGS_CFM_ORTANG; - } - else - { - btAssertConstrParams(0); - } - break; + case BT_CONSTRAINT_STOP_ERP: + if (axis < 1) + { + m_softnessLimLin = value; + m_flags |= BT_SLIDER_FLAGS_ERP_LIMLIN; + } + else if (axis < 3) + { + m_softnessOrthoLin = value; + m_flags |= BT_SLIDER_FLAGS_ERP_ORTLIN; + } + else if (axis == 3) + { + m_softnessLimAng = value; + m_flags |= BT_SLIDER_FLAGS_ERP_LIMANG; + } + else if (axis < 6) + { + m_softnessOrthoAng = value; + m_flags |= BT_SLIDER_FLAGS_ERP_ORTANG; + } + else + { + btAssertConstrParams(0); + } + break; + case BT_CONSTRAINT_CFM: + if (axis < 1) + { + m_cfmDirLin = value; + m_flags |= BT_SLIDER_FLAGS_CFM_DIRLIN; + } + else if (axis == 3) + { + m_cfmDirAng = value; + m_flags |= BT_SLIDER_FLAGS_CFM_DIRANG; + } + else + { + btAssertConstrParams(0); + } + break; + case BT_CONSTRAINT_STOP_CFM: + if (axis < 1) + { + m_cfmLimLin = value; + m_flags |= BT_SLIDER_FLAGS_CFM_LIMLIN; + } + else if (axis < 3) + { + m_cfmOrthoLin = value; + m_flags |= BT_SLIDER_FLAGS_CFM_ORTLIN; + } + else if (axis == 3) + { + m_cfmLimAng = value; + m_flags |= BT_SLIDER_FLAGS_CFM_LIMANG; + } + else if (axis < 6) + { + m_cfmOrthoAng = value; + m_flags |= BT_SLIDER_FLAGS_CFM_ORTANG; + } + else + { + btAssertConstrParams(0); + } + break; } } ///return the local value of parameter -btScalar btSliderConstraint::getParam(int num, int axis) const +btScalar btSliderConstraint::getParam(int num, int axis) const { btScalar retVal(SIMD_INFINITY); - switch(num) + switch (num) { - case BT_CONSTRAINT_STOP_ERP : - if(axis < 1) - { - btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_ERP_LIMLIN); - retVal = m_softnessLimLin; - } - else if(axis < 3) - { - btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_ERP_ORTLIN); - retVal = m_softnessOrthoLin; - } - else if(axis == 3) - { - btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_ERP_LIMANG); - retVal = m_softnessLimAng; - } - else if(axis < 6) - { - btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_ERP_ORTANG); - retVal = m_softnessOrthoAng; - } - else - { - btAssertConstrParams(0); - } - break; - case BT_CONSTRAINT_CFM : - if(axis < 1) - { - btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_DIRLIN); - retVal = m_cfmDirLin; - } - else if(axis == 3) - { - btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_DIRANG); - retVal = m_cfmDirAng; - } - else - { - btAssertConstrParams(0); - } - break; - case BT_CONSTRAINT_STOP_CFM : - if(axis < 1) - { - btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_LIMLIN); - retVal = m_cfmLimLin; - } - else if(axis < 3) - { - btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_ORTLIN); - retVal = m_cfmOrthoLin; - } - else if(axis == 3) - { - btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_LIMANG); - retVal = m_cfmLimAng; - } - else if(axis < 6) - { - btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_ORTANG); - retVal = m_cfmOrthoAng; - } - else - { - btAssertConstrParams(0); - } - break; + case BT_CONSTRAINT_STOP_ERP: + if (axis < 1) + { + btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_ERP_LIMLIN); + retVal = m_softnessLimLin; + } + else if (axis < 3) + { + btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_ERP_ORTLIN); + retVal = m_softnessOrthoLin; + } + else if (axis == 3) + { + btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_ERP_LIMANG); + retVal = m_softnessLimAng; + } + else if (axis < 6) + { + btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_ERP_ORTANG); + retVal = m_softnessOrthoAng; + } + else + { + btAssertConstrParams(0); + } + break; + case BT_CONSTRAINT_CFM: + if (axis < 1) + { + btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_DIRLIN); + retVal = m_cfmDirLin; + } + else if (axis == 3) + { + btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_DIRANG); + retVal = m_cfmDirAng; + } + else + { + btAssertConstrParams(0); + } + break; + case BT_CONSTRAINT_STOP_CFM: + if (axis < 1) + { + btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_LIMLIN); + retVal = m_cfmLimLin; + } + else if (axis < 3) + { + btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_ORTLIN); + retVal = m_cfmOrthoLin; + } + else if (axis == 3) + { + btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_LIMANG); + retVal = m_cfmLimAng; + } + else if (axis < 6) + { + btAssertConstrParams(m_flags & BT_SLIDER_FLAGS_CFM_ORTANG); + retVal = m_cfmOrthoAng; + } + else + { + btAssertConstrParams(0); + } + break; } return retVal; } - - - diff --git a/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h b/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h index 1957f08a9..75ca34e97 100755 --- a/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h +++ b/src/BulletDynamics/ConstraintSolver/btSliderConstraint.h @@ -25,31 +25,26 @@ TODO: #ifndef BT_SLIDER_CONSTRAINT_H #define BT_SLIDER_CONSTRAINT_H -#include "LinearMath/btScalar.h"//for BT_USE_DOUBLE_PRECISION +#include "LinearMath/btScalar.h" //for BT_USE_DOUBLE_PRECISION #ifdef BT_USE_DOUBLE_PRECISION -#define btSliderConstraintData2 btSliderConstraintDoubleData -#define btSliderConstraintDataName "btSliderConstraintDoubleData" +#define btSliderConstraintData2 btSliderConstraintDoubleData +#define btSliderConstraintDataName "btSliderConstraintDoubleData" #else -#define btSliderConstraintData2 btSliderConstraintData -#define btSliderConstraintDataName "btSliderConstraintData" -#endif //BT_USE_DOUBLE_PRECISION +#define btSliderConstraintData2 btSliderConstraintData +#define btSliderConstraintDataName "btSliderConstraintData" +#endif //BT_USE_DOUBLE_PRECISION #include "LinearMath/btVector3.h" #include "btJacobianEntry.h" #include "btTypedConstraint.h" - - class btRigidBody; - - -#define SLIDER_CONSTRAINT_DEF_SOFTNESS (btScalar(1.0)) -#define SLIDER_CONSTRAINT_DEF_DAMPING (btScalar(1.0)) -#define SLIDER_CONSTRAINT_DEF_RESTITUTION (btScalar(0.7)) -#define SLIDER_CONSTRAINT_DEF_CFM (btScalar(0.f)) - +#define SLIDER_CONSTRAINT_DEF_SOFTNESS (btScalar(1.0)) +#define SLIDER_CONSTRAINT_DEF_DAMPING (btScalar(1.0)) +#define SLIDER_CONSTRAINT_DEF_RESTITUTION (btScalar(0.7)) +#define SLIDER_CONSTRAINT_DEF_CFM (btScalar(0.f)) enum btSliderFlags { @@ -67,15 +62,15 @@ enum btSliderFlags BT_SLIDER_FLAGS_ERP_LIMANG = (1 << 11) }; - -ATTRIBUTE_ALIGNED16(class) btSliderConstraint : public btTypedConstraint +ATTRIBUTE_ALIGNED16(class) +btSliderConstraint : public btTypedConstraint { protected: ///for backwards compatibility during the transition to 'getInfo/getInfo2' - bool m_useSolveConstraintObsolete; - bool m_useOffsetForConstraintFrame; - btTransform m_frameInA; - btTransform m_frameInB; + bool m_useSolveConstraintObsolete; + bool m_useOffsetForConstraintFrame; + btTransform m_frameInA; + btTransform m_frameInB; // use frameA fo define limits, if true bool m_useLinearReferenceFrameA; // linear limits @@ -119,21 +114,21 @@ protected: btScalar m_restitutionOrthoAng; btScalar m_dampingOrthoAng; btScalar m_cfmOrthoAng; - + // for interlal use bool m_solveLinLim; bool m_solveAngLim; int m_flags; - btJacobianEntry m_jacLin[3]; - btScalar m_jacLinDiagABInv[3]; + btJacobianEntry m_jacLin[3]; + btScalar m_jacLinDiagABInv[3]; - btJacobianEntry m_jacAng[3]; + btJacobianEntry m_jacAng[3]; btScalar m_timeStep; - btTransform m_calculatedTransformA; - btTransform m_calculatedTransformB; + btTransform m_calculatedTransformA; + btTransform m_calculatedTransformB; btVector3 m_sliderAxis; btVector3 m_realPivotAInW; @@ -150,57 +145,57 @@ protected: btScalar m_angDepth; btScalar m_kAngle; - bool m_poweredLinMotor; - btScalar m_targetLinMotorVelocity; - btScalar m_maxLinMotorForce; - btScalar m_accumulatedLinMotorImpulse; - - bool m_poweredAngMotor; - btScalar m_targetAngMotorVelocity; - btScalar m_maxAngMotorForce; - btScalar m_accumulatedAngMotorImpulse; + bool m_poweredLinMotor; + btScalar m_targetLinMotorVelocity; + btScalar m_maxLinMotorForce; + btScalar m_accumulatedLinMotorImpulse; - //------------------------ + bool m_poweredAngMotor; + btScalar m_targetAngMotorVelocity; + btScalar m_maxAngMotorForce; + btScalar m_accumulatedAngMotorImpulse; + + //------------------------ void initParams(); + public: BT_DECLARE_ALIGNED_ALLOCATOR(); - + // constructors - btSliderConstraint(btRigidBody& rbA, btRigidBody& rbB, const btTransform& frameInA, const btTransform& frameInB ,bool useLinearReferenceFrameA); - btSliderConstraint(btRigidBody& rbB, const btTransform& frameInB, bool useLinearReferenceFrameA); + btSliderConstraint(btRigidBody & rbA, btRigidBody & rbB, const btTransform& frameInA, const btTransform& frameInB, bool useLinearReferenceFrameA); + btSliderConstraint(btRigidBody & rbB, const btTransform& frameInB, bool useLinearReferenceFrameA); // overrides - virtual void getInfo1 (btConstraintInfo1* info); + virtual void getInfo1(btConstraintInfo1 * info); - void getInfo1NonVirtual(btConstraintInfo1* info); - - virtual void getInfo2 (btConstraintInfo2* info); + void getInfo1NonVirtual(btConstraintInfo1 * info); - void getInfo2NonVirtual(btConstraintInfo2* info, const btTransform& transA, const btTransform& transB,const btVector3& linVelA,const btVector3& linVelB, btScalar rbAinvMass,btScalar rbBinvMass); + virtual void getInfo2(btConstraintInfo2 * info); + void getInfo2NonVirtual(btConstraintInfo2 * info, const btTransform& transA, const btTransform& transB, const btVector3& linVelA, const btVector3& linVelB, btScalar rbAinvMass, btScalar rbBinvMass); // access - const btRigidBody& getRigidBodyA() const { return m_rbA; } - const btRigidBody& getRigidBodyB() const { return m_rbB; } - const btTransform & getCalculatedTransformA() const { return m_calculatedTransformA; } - const btTransform & getCalculatedTransformB() const { return m_calculatedTransformB; } - const btTransform & getFrameOffsetA() const { return m_frameInA; } - const btTransform & getFrameOffsetB() const { return m_frameInB; } - btTransform & getFrameOffsetA() { return m_frameInA; } - btTransform & getFrameOffsetB() { return m_frameInB; } - btScalar getLowerLinLimit() { return m_lowerLinLimit; } - void setLowerLinLimit(btScalar lowerLimit) { m_lowerLinLimit = lowerLimit; } - btScalar getUpperLinLimit() { return m_upperLinLimit; } - void setUpperLinLimit(btScalar upperLimit) { m_upperLinLimit = upperLimit; } - btScalar getLowerAngLimit() { return m_lowerAngLimit; } - void setLowerAngLimit(btScalar lowerLimit) { m_lowerAngLimit = btNormalizeAngle(lowerLimit); } - btScalar getUpperAngLimit() { return m_upperAngLimit; } - void setUpperAngLimit(btScalar upperLimit) { m_upperAngLimit = btNormalizeAngle(upperLimit); } + const btRigidBody& getRigidBodyA() const { return m_rbA; } + const btRigidBody& getRigidBodyB() const { return m_rbB; } + const btTransform& getCalculatedTransformA() const { return m_calculatedTransformA; } + const btTransform& getCalculatedTransformB() const { return m_calculatedTransformB; } + const btTransform& getFrameOffsetA() const { return m_frameInA; } + const btTransform& getFrameOffsetB() const { return m_frameInB; } + btTransform& getFrameOffsetA() { return m_frameInA; } + btTransform& getFrameOffsetB() { return m_frameInB; } + btScalar getLowerLinLimit() { return m_lowerLinLimit; } + void setLowerLinLimit(btScalar lowerLimit) { m_lowerLinLimit = lowerLimit; } + btScalar getUpperLinLimit() { return m_upperLinLimit; } + void setUpperLinLimit(btScalar upperLimit) { m_upperLinLimit = upperLimit; } + btScalar getLowerAngLimit() { return m_lowerAngLimit; } + void setLowerAngLimit(btScalar lowerLimit) { m_lowerAngLimit = btNormalizeAngle(lowerLimit); } + btScalar getUpperAngLimit() { return m_upperAngLimit; } + void setUpperAngLimit(btScalar upperLimit) { m_upperAngLimit = btNormalizeAngle(upperLimit); } bool getUseLinearReferenceFrameA() { return m_useLinearReferenceFrameA; } btScalar getSoftnessDirLin() { return m_softnessDirLin; } btScalar getRestitutionDirLin() { return m_restitutionDirLin; } - btScalar getDampingDirLin() { return m_dampingDirLin ; } + btScalar getDampingDirLin() { return m_dampingDirLin; } btScalar getSoftnessDirAng() { return m_softnessDirAng; } btScalar getRestitutionDirAng() { return m_restitutionDirAng; } btScalar getDampingDirAng() { return m_dampingDirAng; } @@ -249,8 +244,6 @@ public: btScalar getLinearPos() const { return m_linPos; } btScalar getAngularPos() const { return m_angPos; } - - // access for ODE solver bool getSolveLinLimit() { return m_solveLinLim; } @@ -258,9 +251,9 @@ public: bool getSolveAngLimit() { return m_solveAngLim; } btScalar getAngDepth() { return m_angDepth; } // shared code used by ODE solver - void calculateTransforms(const btTransform& transA,const btTransform& transB); - void testLinLimits(); - void testAngLimits(); + void calculateTransforms(const btTransform& transA, const btTransform& transB); + void testLinLimits(); + void testAngLimits(); // access for PE Solver btVector3 getAncorInA(); btVector3 getAncorInB(); @@ -268,84 +261,75 @@ public: bool getUseFrameOffset() { return m_useOffsetForConstraintFrame; } void setUseFrameOffset(bool frameOffsetOnOff) { m_useOffsetForConstraintFrame = frameOffsetOnOff; } - void setFrames(const btTransform& frameA, const btTransform& frameB) - { - m_frameInA=frameA; - m_frameInB=frameB; - calculateTransforms(m_rbA.getCenterOfMassTransform(),m_rbB.getCenterOfMassTransform()); + void setFrames(const btTransform& frameA, const btTransform& frameB) + { + m_frameInA = frameA; + m_frameInB = frameB; + calculateTransforms(m_rbA.getCenterOfMassTransform(), m_rbB.getCenterOfMassTransform()); buildJacobian(); - } + } - - ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). + ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). ///If no axis is provided, it uses the default axis for this constraint. - virtual void setParam(int num, btScalar value, int axis = -1); + virtual void setParam(int num, btScalar value, int axis = -1); ///return the local value of parameter - virtual btScalar getParam(int num, int axis = -1) const; - - virtual int getFlags() const - { + virtual btScalar getParam(int num, int axis = -1) const; + + virtual int getFlags() const + { return m_flags; } - virtual int calculateSerializeBufferSize() const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; - - + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; }; - ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 - struct btSliderConstraintData { - btTypedConstraintData m_typeConstraintData; - btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis. + btTypedConstraintData m_typeConstraintData; + btTransformFloatData m_rbAFrame; // constraint axii. Assumes z is hinge axis. btTransformFloatData m_rbBFrame; - - float m_linearUpperLimit; - float m_linearLowerLimit; - float m_angularUpperLimit; - float m_angularLowerLimit; + float m_linearUpperLimit; + float m_linearLowerLimit; - int m_useLinearReferenceFrameA; + float m_angularUpperLimit; + float m_angularLowerLimit; + + int m_useLinearReferenceFrameA; int m_useOffsetForConstraintFrame; - }; - struct btSliderConstraintDoubleData { - btTypedConstraintDoubleData m_typeConstraintData; - btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis. + btTypedConstraintDoubleData m_typeConstraintData; + btTransformDoubleData m_rbAFrame; // constraint axii. Assumes z is hinge axis. btTransformDoubleData m_rbBFrame; - - double m_linearUpperLimit; - double m_linearLowerLimit; - double m_angularUpperLimit; - double m_angularLowerLimit; + double m_linearUpperLimit; + double m_linearLowerLimit; - int m_useLinearReferenceFrameA; + double m_angularUpperLimit; + double m_angularLowerLimit; + + int m_useLinearReferenceFrameA; int m_useOffsetForConstraintFrame; - }; -SIMD_FORCE_INLINE int btSliderConstraint::calculateSerializeBufferSize() const +SIMD_FORCE_INLINE int btSliderConstraint::calculateSerializeBufferSize() const { return sizeof(btSliderConstraintData2); } - ///fills the dataBuffer and returns the struct name (and 0 on failure) -SIMD_FORCE_INLINE const char* btSliderConstraint::serialize(void* dataBuffer, btSerializer* serializer) const +///fills the dataBuffer and returns the struct name (and 0 on failure) +SIMD_FORCE_INLINE const char* btSliderConstraint::serialize(void* dataBuffer, btSerializer* serializer) const { - - btSliderConstraintData2* sliderData = (btSliderConstraintData2*) dataBuffer; - btTypedConstraint::serialize(&sliderData->m_typeConstraintData,serializer); + btSliderConstraintData2* sliderData = (btSliderConstraintData2*)dataBuffer; + btTypedConstraint::serialize(&sliderData->m_typeConstraintData, serializer); m_frameInA.serialize(sliderData->m_rbAFrame); m_frameInB.serialize(sliderData->m_rbBFrame); @@ -362,7 +346,4 @@ SIMD_FORCE_INLINE const char* btSliderConstraint::serialize(void* dataBuffer, bt return btSliderConstraintDataName; } - - -#endif //BT_SLIDER_CONSTRAINT_H - +#endif //BT_SLIDER_CONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp index 0c7dbd668..1ea20edcb 100644 --- a/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp +++ b/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.cpp @@ -13,43 +13,38 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "btSolve2LinearConstraint.h" #include "BulletDynamics/Dynamics/btRigidBody.h" #include "LinearMath/btVector3.h" #include "btJacobianEntry.h" - void btSolve2LinearConstraint::resolveUnilateralPairConstraint( - btRigidBody* body1, - btRigidBody* body2, + btRigidBody* body1, + btRigidBody* body2, - const btMatrix3x3& world2A, - const btMatrix3x3& world2B, - - const btVector3& invInertiaADiag, - const btScalar invMassA, - const btVector3& linvelA,const btVector3& angvelA, - const btVector3& rel_posA1, - const btVector3& invInertiaBDiag, - const btScalar invMassB, - const btVector3& linvelB,const btVector3& angvelB, - const btVector3& rel_posA2, + const btMatrix3x3& world2A, + const btMatrix3x3& world2B, - btScalar depthA, const btVector3& normalA, - const btVector3& rel_posB1,const btVector3& rel_posB2, - btScalar depthB, const btVector3& normalB, - btScalar& imp0,btScalar& imp1) + const btVector3& invInertiaADiag, + const btScalar invMassA, + const btVector3& linvelA, const btVector3& angvelA, + const btVector3& rel_posA1, + const btVector3& invInertiaBDiag, + const btScalar invMassB, + const btVector3& linvelB, const btVector3& angvelB, + const btVector3& rel_posA2, + + btScalar depthA, const btVector3& normalA, + const btVector3& rel_posB1, const btVector3& rel_posB2, + btScalar depthB, const btVector3& normalB, + btScalar& imp0, btScalar& imp1) { (void)linvelA; (void)linvelB; (void)angvelB; (void)angvelA; - - imp0 = btScalar(0.); imp1 = btScalar(0.); @@ -59,86 +54,76 @@ void btSolve2LinearConstraint::resolveUnilateralPairConstraint( btAssert(len < SIMD_EPSILON); - //this jacobian entry could be re-used for all iterations - btJacobianEntry jacA(world2A,world2B,rel_posA1,rel_posA2,normalA,invInertiaADiag,invMassA, - invInertiaBDiag,invMassB); - btJacobianEntry jacB(world2A,world2B,rel_posB1,rel_posB2,normalB,invInertiaADiag,invMassA, - invInertiaBDiag,invMassB); - + btJacobianEntry jacA(world2A, world2B, rel_posA1, rel_posA2, normalA, invInertiaADiag, invMassA, + invInertiaBDiag, invMassB); + btJacobianEntry jacB(world2A, world2B, rel_posB1, rel_posB2, normalB, invInertiaADiag, invMassA, + invInertiaBDiag, invMassB); + //const btScalar vel0 = jacA.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB); //const btScalar vel1 = jacB.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB); - const btScalar vel0 = normalA.dot(body1->getVelocityInLocalPoint(rel_posA1)-body2->getVelocityInLocalPoint(rel_posA1)); - const btScalar vel1 = normalB.dot(body1->getVelocityInLocalPoint(rel_posB1)-body2->getVelocityInLocalPoint(rel_posB1)); + const btScalar vel0 = normalA.dot(body1->getVelocityInLocalPoint(rel_posA1) - body2->getVelocityInLocalPoint(rel_posA1)); + const btScalar vel1 = normalB.dot(body1->getVelocityInLocalPoint(rel_posB1) - body2->getVelocityInLocalPoint(rel_posB1)); -// btScalar penetrationImpulse = (depth*contactTau*timeCorrection) * massTerm;//jacDiagABInv + // btScalar penetrationImpulse = (depth*contactTau*timeCorrection) * massTerm;//jacDiagABInv btScalar massTerm = btScalar(1.) / (invMassA + invMassB); - // calculate rhs (or error) terms - const btScalar dv0 = depthA * m_tau * massTerm - vel0 * m_damping; - const btScalar dv1 = depthB * m_tau * massTerm - vel1 * m_damping; - + const btScalar dv0 = depthA * m_tau * massTerm - vel0 * m_damping; + const btScalar dv1 = depthB * m_tau * massTerm - vel1 * m_damping; // dC/dv * dv = -C - + // jacobian * impulse = -error // //impulse = jacobianInverse * -error // inverting 2x2 symmetric system (offdiagonal are equal!) - // + // + btScalar nonDiag = jacA.getNonDiagonal(jacB, invMassA, invMassB); + btScalar invDet = btScalar(1.0) / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag); - btScalar nonDiag = jacA.getNonDiagonal(jacB,invMassA,invMassB); - btScalar invDet = btScalar(1.0) / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag ); - //imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet; //imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet; imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet; - imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet; + imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * -nonDiag * invDet; //[a b] [d -c] //[c d] inverse = (1 / determinant) * [-b a] where determinant is (ad - bc) //[jA nD] * [imp0] = [dv0] //[nD jB] [imp1] [dv1] - } - - void btSolve2LinearConstraint::resolveBilateralPairConstraint( - btRigidBody* body1, - btRigidBody* body2, - const btMatrix3x3& world2A, - const btMatrix3x3& world2B, - - const btVector3& invInertiaADiag, - const btScalar invMassA, - const btVector3& linvelA,const btVector3& angvelA, - const btVector3& rel_posA1, - const btVector3& invInertiaBDiag, - const btScalar invMassB, - const btVector3& linvelB,const btVector3& angvelB, - const btVector3& rel_posA2, + btRigidBody* body1, + btRigidBody* body2, + const btMatrix3x3& world2A, + const btMatrix3x3& world2B, - btScalar depthA, const btVector3& normalA, - const btVector3& rel_posB1,const btVector3& rel_posB2, - btScalar depthB, const btVector3& normalB, - btScalar& imp0,btScalar& imp1) + const btVector3& invInertiaADiag, + const btScalar invMassA, + const btVector3& linvelA, const btVector3& angvelA, + const btVector3& rel_posA1, + const btVector3& invInertiaBDiag, + const btScalar invMassB, + const btVector3& linvelB, const btVector3& angvelB, + const btVector3& rel_posA2, + + btScalar depthA, const btVector3& normalA, + const btVector3& rel_posB1, const btVector3& rel_posB2, + btScalar depthB, const btVector3& normalB, + btScalar& imp0, btScalar& imp1) { - (void)linvelA; (void)linvelB; (void)angvelA; (void)angvelB; - - imp0 = btScalar(0.); imp1 = btScalar(0.); @@ -148,42 +133,40 @@ void btSolve2LinearConstraint::resolveBilateralPairConstraint( btAssert(len < SIMD_EPSILON); - //this jacobian entry could be re-used for all iterations - btJacobianEntry jacA(world2A,world2B,rel_posA1,rel_posA2,normalA,invInertiaADiag,invMassA, - invInertiaBDiag,invMassB); - btJacobianEntry jacB(world2A,world2B,rel_posB1,rel_posB2,normalB,invInertiaADiag,invMassA, - invInertiaBDiag,invMassB); - + btJacobianEntry jacA(world2A, world2B, rel_posA1, rel_posA2, normalA, invInertiaADiag, invMassA, + invInertiaBDiag, invMassB); + btJacobianEntry jacB(world2A, world2B, rel_posB1, rel_posB2, normalB, invInertiaADiag, invMassA, + invInertiaBDiag, invMassB); + //const btScalar vel0 = jacA.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB); //const btScalar vel1 = jacB.getRelativeVelocity(linvelA,angvelA,linvelB,angvelB); - const btScalar vel0 = normalA.dot(body1->getVelocityInLocalPoint(rel_posA1)-body2->getVelocityInLocalPoint(rel_posA1)); - const btScalar vel1 = normalB.dot(body1->getVelocityInLocalPoint(rel_posB1)-body2->getVelocityInLocalPoint(rel_posB1)); + const btScalar vel0 = normalA.dot(body1->getVelocityInLocalPoint(rel_posA1) - body2->getVelocityInLocalPoint(rel_posA1)); + const btScalar vel1 = normalB.dot(body1->getVelocityInLocalPoint(rel_posB1) - body2->getVelocityInLocalPoint(rel_posB1)); // calculate rhs (or error) terms - const btScalar dv0 = depthA * m_tau - vel0 * m_damping; - const btScalar dv1 = depthB * m_tau - vel1 * m_damping; + const btScalar dv0 = depthA * m_tau - vel0 * m_damping; + const btScalar dv1 = depthB * m_tau - vel1 * m_damping; // dC/dv * dv = -C - + // jacobian * impulse = -error // //impulse = jacobianInverse * -error // inverting 2x2 symmetric system (offdiagonal are equal!) - // + // + btScalar nonDiag = jacA.getNonDiagonal(jacB, invMassA, invMassB); + btScalar invDet = btScalar(1.0) / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag); - btScalar nonDiag = jacA.getNonDiagonal(jacB,invMassA,invMassB); - btScalar invDet = btScalar(1.0) / (jacA.getDiagonal() * jacB.getDiagonal() - nonDiag * nonDiag ); - //imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet; //imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet; imp0 = dv0 * jacA.getDiagonal() * invDet + dv1 * -nonDiag * invDet; - imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * - nonDiag * invDet; + imp1 = dv1 * jacB.getDiagonal() * invDet + dv0 * -nonDiag * invDet; //[a b] [d -c] //[c d] inverse = (1 / determinant) * [-b a] where determinant is (ad - bc) @@ -191,9 +174,9 @@ void btSolve2LinearConstraint::resolveBilateralPairConstraint( //[jA nD] * [imp0] = [dv0] //[nD jB] [imp1] [dv1] - if ( imp0 > btScalar(0.0)) + if (imp0 > btScalar(0.0)) { - if ( imp1 > btScalar(0.0) ) + if (imp1 > btScalar(0.0)) { //both positive } @@ -203,9 +186,10 @@ void btSolve2LinearConstraint::resolveBilateralPairConstraint( // now imp0>0 imp1<0 imp0 = dv0 / jacA.getDiagonal(); - if ( imp0 > btScalar(0.0) ) + if (imp0 > btScalar(0.0)) { - } else + } + else { imp0 = btScalar(0.); } @@ -216,24 +200,25 @@ void btSolve2LinearConstraint::resolveBilateralPairConstraint( imp0 = btScalar(0.); imp1 = dv1 / jacB.getDiagonal(); - if ( imp1 <= btScalar(0.0) ) + if (imp1 <= btScalar(0.0)) { imp1 = btScalar(0.); // now imp0>0 imp1<0 imp0 = dv0 / jacA.getDiagonal(); - if ( imp0 > btScalar(0.0) ) + if (imp0 > btScalar(0.0)) { - } else + } + else { imp0 = btScalar(0.); } - } else + } + else { } } } - /* void btSolve2LinearConstraint::resolveAngularConstraint( const btMatrix3x3& invInertiaAWS, const btScalar invMassA, @@ -252,4 +237,3 @@ void btSolve2LinearConstraint::resolveAngularConstraint( const btMatrix3x3& invI } */ - diff --git a/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h b/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h index e8bfabf86..fca8ecec8 100644 --- a/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h +++ b/src/BulletDynamics/ConstraintSolver/btSolve2LinearConstraint.h @@ -19,20 +19,16 @@ subject to the following restrictions: #include "LinearMath/btMatrix3x3.h" #include "LinearMath/btVector3.h" - class btRigidBody; - - /// constraint class used for lateral tyre friction. -class btSolve2LinearConstraint +class btSolve2LinearConstraint { - btScalar m_tau; - btScalar m_damping; + btScalar m_tau; + btScalar m_damping; public: - - btSolve2LinearConstraint(btScalar tau,btScalar damping) + btSolve2LinearConstraint(btScalar tau, btScalar damping) { m_tau = tau; m_damping = damping; @@ -40,52 +36,51 @@ public: // // solve unilateral constraint (equality, direct method) // - void resolveUnilateralPairConstraint( - btRigidBody* body0, + void resolveUnilateralPairConstraint( + btRigidBody* body0, btRigidBody* body1, const btMatrix3x3& world2A, - const btMatrix3x3& world2B, - - const btVector3& invInertiaADiag, - const btScalar invMassA, - const btVector3& linvelA,const btVector3& angvelA, - const btVector3& rel_posA1, - const btVector3& invInertiaBDiag, - const btScalar invMassB, - const btVector3& linvelB,const btVector3& angvelB, - const btVector3& rel_posA2, + const btMatrix3x3& world2B, - btScalar depthA, const btVector3& normalA, - const btVector3& rel_posB1,const btVector3& rel_posB2, - btScalar depthB, const btVector3& normalB, - btScalar& imp0,btScalar& imp1); + const btVector3& invInertiaADiag, + const btScalar invMassA, + const btVector3& linvelA, const btVector3& angvelA, + const btVector3& rel_posA1, + const btVector3& invInertiaBDiag, + const btScalar invMassB, + const btVector3& linvelB, const btVector3& angvelB, + const btVector3& rel_posA2, + btScalar depthA, const btVector3& normalA, + const btVector3& rel_posB1, const btVector3& rel_posB2, + btScalar depthB, const btVector3& normalB, + btScalar& imp0, btScalar& imp1); // // solving 2x2 lcp problem (inequality, direct solution ) // void resolveBilateralPairConstraint( - btRigidBody* body0, - btRigidBody* body1, + btRigidBody* body0, + btRigidBody* body1, const btMatrix3x3& world2A, - const btMatrix3x3& world2B, - - const btVector3& invInertiaADiag, - const btScalar invMassA, - const btVector3& linvelA,const btVector3& angvelA, - const btVector3& rel_posA1, - const btVector3& invInertiaBDiag, - const btScalar invMassB, - const btVector3& linvelB,const btVector3& angvelB, - const btVector3& rel_posA2, + const btMatrix3x3& world2B, - btScalar depthA, const btVector3& normalA, - const btVector3& rel_posB1,const btVector3& rel_posB2, - btScalar depthB, const btVector3& normalB, - btScalar& imp0,btScalar& imp1); + const btVector3& invInertiaADiag, + const btScalar invMassA, + const btVector3& linvelA, const btVector3& angvelA, + const btVector3& rel_posA1, + const btVector3& invInertiaBDiag, + const btScalar invMassB, + const btVector3& linvelB, const btVector3& angvelB, + const btVector3& rel_posA2, -/* + btScalar depthA, const btVector3& normalA, + const btVector3& rel_posB1, const btVector3& rel_posB2, + btScalar depthB, const btVector3& normalB, + btScalar& imp0, btScalar& imp1); + + /* void resolveAngularConstraint( const btMatrix3x3& invInertiaAWS, const btScalar invMassA, const btVector3& linvelA,const btVector3& angvelA, @@ -101,7 +96,6 @@ public: btScalar& imp0,btScalar& imp1); */ - }; -#endif //BT_SOLVE_2LINEAR_CONSTRAINT_H +#endif //BT_SOLVE_2LINEAR_CONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btSolverBody.h b/src/BulletDynamics/ConstraintSolver/btSolverBody.h index 27ccefe41..409aa8a08 100644 --- a/src/BulletDynamics/ConstraintSolver/btSolverBody.h +++ b/src/BulletDynamics/ConstraintSolver/btSolverBody.h @@ -16,7 +16,7 @@ subject to the following restrictions: #ifndef BT_SOLVER_BODY_H #define BT_SOLVER_BODY_H -class btRigidBody; +class btRigidBody; #include "LinearMath/btVector3.h" #include "LinearMath/btMatrix3x3.h" @@ -26,103 +26,99 @@ class btRigidBody; ///Until we get other contributions, only use SIMD on Windows, when using Visual Studio 2008 or later, and not double precision #ifdef BT_USE_SSE #define USE_SIMD 1 -#endif // - +#endif // #ifdef USE_SIMD -struct btSimdScalar +struct btSimdScalar { - SIMD_FORCE_INLINE btSimdScalar() - { - - } - - SIMD_FORCE_INLINE btSimdScalar(float fl) - :m_vec128 (_mm_set1_ps(fl)) + SIMD_FORCE_INLINE btSimdScalar() { } - SIMD_FORCE_INLINE btSimdScalar(__m128 v128) - :m_vec128(v128) + SIMD_FORCE_INLINE btSimdScalar(float fl) + : m_vec128(_mm_set1_ps(fl)) { } - union + + SIMD_FORCE_INLINE btSimdScalar(__m128 v128) + : m_vec128(v128) { - __m128 m_vec128; - float m_floats[4]; - int m_ints[4]; - btScalar m_unusedPadding; + } + union { + __m128 m_vec128; + float m_floats[4]; + int m_ints[4]; + btScalar m_unusedPadding; }; - SIMD_FORCE_INLINE __m128 get128() + SIMD_FORCE_INLINE __m128 get128() { return m_vec128; } - SIMD_FORCE_INLINE const __m128 get128() const + SIMD_FORCE_INLINE const __m128 get128() const { return m_vec128; } - SIMD_FORCE_INLINE void set128(__m128 v128) + SIMD_FORCE_INLINE void set128(__m128 v128) { m_vec128 = v128; } - SIMD_FORCE_INLINE operator __m128() - { - return m_vec128; + SIMD_FORCE_INLINE operator __m128() + { + return m_vec128; } - SIMD_FORCE_INLINE operator const __m128() const - { - return m_vec128; - } - - SIMD_FORCE_INLINE operator float() const - { - return m_floats[0]; + SIMD_FORCE_INLINE operator const __m128() const + { + return m_vec128; } + SIMD_FORCE_INLINE operator float() const + { + return m_floats[0]; + } }; ///@brief Return the elementwise product of two btSimdScalar -SIMD_FORCE_INLINE btSimdScalar -operator*(const btSimdScalar& v1, const btSimdScalar& v2) +SIMD_FORCE_INLINE btSimdScalar +operator*(const btSimdScalar& v1, const btSimdScalar& v2) { - return btSimdScalar(_mm_mul_ps(v1.get128(),v2.get128())); + return btSimdScalar(_mm_mul_ps(v1.get128(), v2.get128())); } ///@brief Return the elementwise product of two btSimdScalar -SIMD_FORCE_INLINE btSimdScalar -operator+(const btSimdScalar& v1, const btSimdScalar& v2) +SIMD_FORCE_INLINE btSimdScalar +operator+(const btSimdScalar& v1, const btSimdScalar& v2) { - return btSimdScalar(_mm_add_ps(v1.get128(),v2.get128())); + return btSimdScalar(_mm_add_ps(v1.get128(), v2.get128())); } - #else #define btSimdScalar btScalar #endif ///The btSolverBody is an internal datastructure for the constraint solver. Only necessary data is packed to increase cache coherence/performance. -ATTRIBUTE_ALIGNED16 (struct) btSolverBody +ATTRIBUTE_ALIGNED16(struct) +btSolverBody { BT_DECLARE_ALIGNED_ALLOCATOR(); - btTransform m_worldTransform; - btVector3 m_deltaLinearVelocity; - btVector3 m_deltaAngularVelocity; - btVector3 m_angularFactor; - btVector3 m_linearFactor; - btVector3 m_invMass; - btVector3 m_pushVelocity; - btVector3 m_turnVelocity; - btVector3 m_linearVelocity; - btVector3 m_angularVelocity; - btVector3 m_externalForceImpulse; - btVector3 m_externalTorqueImpulse; + btTransform m_worldTransform; + btVector3 m_deltaLinearVelocity; + btVector3 m_deltaAngularVelocity; + btVector3 m_angularFactor; + btVector3 m_linearFactor; + btVector3 m_invMass; + btVector3 m_pushVelocity; + btVector3 m_turnVelocity; + btVector3 m_linearVelocity; + btVector3 m_angularVelocity; + btVector3 m_externalForceImpulse; + btVector3 m_externalTorqueImpulse; - btRigidBody* m_originalBody; - void setWorldTransform(const btTransform& worldTransform) + btRigidBody* m_originalBody; + void setWorldTransform(const btTransform& worldTransform) { m_worldTransform = worldTransform; } @@ -131,56 +127,50 @@ ATTRIBUTE_ALIGNED16 (struct) btSolverBody { return m_worldTransform; } - - - SIMD_FORCE_INLINE void getVelocityInLocalPointNoDelta(const btVector3& rel_pos, btVector3& velocity ) const + SIMD_FORCE_INLINE void getVelocityInLocalPointNoDelta(const btVector3& rel_pos, btVector3& velocity) const { if (m_originalBody) - velocity = m_linearVelocity + m_externalForceImpulse + (m_angularVelocity+m_externalTorqueImpulse).cross(rel_pos); + velocity = m_linearVelocity + m_externalForceImpulse + (m_angularVelocity + m_externalTorqueImpulse).cross(rel_pos); else - velocity.setValue(0,0,0); + velocity.setValue(0, 0, 0); } - - SIMD_FORCE_INLINE void getVelocityInLocalPointObsolete(const btVector3& rel_pos, btVector3& velocity ) const + SIMD_FORCE_INLINE void getVelocityInLocalPointObsolete(const btVector3& rel_pos, btVector3& velocity) const { if (m_originalBody) - velocity = m_linearVelocity+m_deltaLinearVelocity + (m_angularVelocity+m_deltaAngularVelocity).cross(rel_pos); + velocity = m_linearVelocity + m_deltaLinearVelocity + (m_angularVelocity + m_deltaAngularVelocity).cross(rel_pos); else - velocity.setValue(0,0,0); + velocity.setValue(0, 0, 0); } - SIMD_FORCE_INLINE void getAngularVelocity(btVector3& angVel) const + SIMD_FORCE_INLINE void getAngularVelocity(btVector3 & angVel) const { if (m_originalBody) - angVel =m_angularVelocity+m_deltaAngularVelocity; + angVel = m_angularVelocity + m_deltaAngularVelocity; else - angVel.setValue(0,0,0); + angVel.setValue(0, 0, 0); } - //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position - SIMD_FORCE_INLINE void applyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,const btScalar impulseMagnitude) + SIMD_FORCE_INLINE void applyImpulse(const btVector3& linearComponent, const btVector3& angularComponent, const btScalar impulseMagnitude) { if (m_originalBody) { - m_deltaLinearVelocity += linearComponent*impulseMagnitude*m_linearFactor; - m_deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor); + m_deltaLinearVelocity += linearComponent * impulseMagnitude * m_linearFactor; + m_deltaAngularVelocity += angularComponent * (impulseMagnitude * m_angularFactor); } } - SIMD_FORCE_INLINE void internalApplyPushImpulse(const btVector3& linearComponent, const btVector3& angularComponent,btScalar impulseMagnitude) + SIMD_FORCE_INLINE void internalApplyPushImpulse(const btVector3& linearComponent, const btVector3& angularComponent, btScalar impulseMagnitude) { if (m_originalBody) { - m_pushVelocity += linearComponent*impulseMagnitude*m_linearFactor; - m_turnVelocity += angularComponent*(impulseMagnitude*m_angularFactor); + m_pushVelocity += linearComponent * impulseMagnitude * m_linearFactor; + m_turnVelocity += angularComponent * (impulseMagnitude * m_angularFactor); } } - - const btVector3& getDeltaLinearVelocity() const { return m_deltaLinearVelocity; @@ -191,20 +181,19 @@ ATTRIBUTE_ALIGNED16 (struct) btSolverBody return m_deltaAngularVelocity; } - const btVector3& getPushVelocity() const + const btVector3& getPushVelocity() const { return m_pushVelocity; } - const btVector3& getTurnVelocity() const + const btVector3& getTurnVelocity() const { return m_turnVelocity; } - //////////////////////////////////////////////// ///some internal methods, don't use them - + btVector3& internalGetDeltaLinearVelocity() { return m_deltaLinearVelocity; @@ -229,7 +218,7 @@ ATTRIBUTE_ALIGNED16 (struct) btSolverBody { m_invMass = invMass; } - + btVector3& internalGetPushVelocity() { return m_pushVelocity; @@ -240,67 +229,57 @@ ATTRIBUTE_ALIGNED16 (struct) btSolverBody return m_turnVelocity; } - SIMD_FORCE_INLINE void internalGetVelocityInLocalPointObsolete(const btVector3& rel_pos, btVector3& velocity ) const + SIMD_FORCE_INLINE void internalGetVelocityInLocalPointObsolete(const btVector3& rel_pos, btVector3& velocity) const { - velocity = m_linearVelocity+m_deltaLinearVelocity + (m_angularVelocity+m_deltaAngularVelocity).cross(rel_pos); + velocity = m_linearVelocity + m_deltaLinearVelocity + (m_angularVelocity + m_deltaAngularVelocity).cross(rel_pos); } - SIMD_FORCE_INLINE void internalGetAngularVelocity(btVector3& angVel) const + SIMD_FORCE_INLINE void internalGetAngularVelocity(btVector3 & angVel) const { - angVel = m_angularVelocity+m_deltaAngularVelocity; + angVel = m_angularVelocity + m_deltaAngularVelocity; } - //Optimization for the iterative solver: avoid calculating constant terms involving inertia, normal, relative position - SIMD_FORCE_INLINE void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent,const btScalar impulseMagnitude) + SIMD_FORCE_INLINE void internalApplyImpulse(const btVector3& linearComponent, const btVector3& angularComponent, const btScalar impulseMagnitude) { if (m_originalBody) { - m_deltaLinearVelocity += linearComponent*impulseMagnitude*m_linearFactor; - m_deltaAngularVelocity += angularComponent*(impulseMagnitude*m_angularFactor); - } - } - - - - - void writebackVelocity() - { - if (m_originalBody) - { - m_linearVelocity +=m_deltaLinearVelocity; - m_angularVelocity += m_deltaAngularVelocity; - - //m_originalBody->setCompanionId(-1); + m_deltaLinearVelocity += linearComponent * impulseMagnitude * m_linearFactor; + m_deltaAngularVelocity += angularComponent * (impulseMagnitude * m_angularFactor); } } - - void writebackVelocityAndTransform(btScalar timeStep, btScalar splitImpulseTurnErp) + void writebackVelocity() { - (void) timeStep; if (m_originalBody) { m_linearVelocity += m_deltaLinearVelocity; m_angularVelocity += m_deltaAngularVelocity; - + + //m_originalBody->setCompanionId(-1); + } + } + + void writebackVelocityAndTransform(btScalar timeStep, btScalar splitImpulseTurnErp) + { + (void)timeStep; + if (m_originalBody) + { + m_linearVelocity += m_deltaLinearVelocity; + m_angularVelocity += m_deltaAngularVelocity; + //correct the position/orientation based on push/turn recovery btTransform newTransform; - if (m_pushVelocity[0]!=0.f || m_pushVelocity[1]!=0 || m_pushVelocity[2]!=0 || m_turnVelocity[0]!=0.f || m_turnVelocity[1]!=0 || m_turnVelocity[2]!=0) + if (m_pushVelocity[0] != 0.f || m_pushVelocity[1] != 0 || m_pushVelocity[2] != 0 || m_turnVelocity[0] != 0.f || m_turnVelocity[1] != 0 || m_turnVelocity[2] != 0) { - // btQuaternion orn = m_worldTransform.getRotation(); - btTransformUtil::integrateTransform(m_worldTransform,m_pushVelocity,m_turnVelocity*splitImpulseTurnErp,timeStep,newTransform); + // btQuaternion orn = m_worldTransform.getRotation(); + btTransformUtil::integrateTransform(m_worldTransform, m_pushVelocity, m_turnVelocity * splitImpulseTurnErp, timeStep, newTransform); m_worldTransform = newTransform; } //m_worldTransform.setRotation(orn); //m_originalBody->setCompanionId(-1); } } - - - }; -#endif //BT_SOLVER_BODY_H - - +#endif //BT_SOLVER_BODY_H diff --git a/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h b/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h index 5515e6b31..c7938df86 100644 --- a/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h +++ b/src/BulletDynamics/ConstraintSolver/btSolverConstraint.h @@ -16,7 +16,7 @@ subject to the following restrictions: #ifndef BT_SOLVER_CONSTRAINT_H #define BT_SOLVER_CONSTRAINT_H -class btRigidBody; +class btRigidBody; #include "LinearMath/btVector3.h" #include "LinearMath/btMatrix3x3.h" #include "btJacobianEntry.h" @@ -25,56 +25,50 @@ class btRigidBody; //#define NO_FRICTION_TANGENTIALS 1 #include "btSolverBody.h" - ///1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and friction constraints. -ATTRIBUTE_ALIGNED16 (struct) btSolverConstraint +ATTRIBUTE_ALIGNED16(struct) +btSolverConstraint { BT_DECLARE_ALIGNED_ALLOCATOR(); - btVector3 m_relpos1CrossNormal; - btVector3 m_contactNormal1; + btVector3 m_relpos1CrossNormal; + btVector3 m_contactNormal1; - btVector3 m_relpos2CrossNormal; - btVector3 m_contactNormal2; //usually m_contactNormal2 == -m_contactNormal1, but not always + btVector3 m_relpos2CrossNormal; + btVector3 m_contactNormal2; //usually m_contactNormal2 == -m_contactNormal1, but not always - btVector3 m_angularComponentA; - btVector3 m_angularComponentB; - - mutable btSimdScalar m_appliedPushImpulse; - mutable btSimdScalar m_appliedImpulse; + btVector3 m_angularComponentA; + btVector3 m_angularComponentB; - btScalar m_friction; - btScalar m_jacDiagABInv; - btScalar m_rhs; - btScalar m_cfm; - - btScalar m_lowerLimit; - btScalar m_upperLimit; - btScalar m_rhsPenetration; - union - { - void* m_originalContactPoint; - btScalar m_unusedPadding4; - int m_numRowsForNonContactConstraint; + mutable btSimdScalar m_appliedPushImpulse; + mutable btSimdScalar m_appliedImpulse; + + btScalar m_friction; + btScalar m_jacDiagABInv; + btScalar m_rhs; + btScalar m_cfm; + + btScalar m_lowerLimit; + btScalar m_upperLimit; + btScalar m_rhsPenetration; + union { + void* m_originalContactPoint; + btScalar m_unusedPadding4; + int m_numRowsForNonContactConstraint; }; - int m_overrideNumSolverIterations; - int m_frictionIndex; + int m_overrideNumSolverIterations; + int m_frictionIndex; int m_solverBodyIdA; int m_solverBodyIdB; - - enum btSolverConstraintType + enum btSolverConstraintType { BT_SOLVER_CONTACT_1D = 0, BT_SOLVER_FRICTION_1D }; }; -typedef btAlignedObjectArray btConstraintArray; - - -#endif //BT_SOLVER_CONSTRAINT_H - - +typedef btAlignedObjectArray btConstraintArray; +#endif //BT_SOLVER_CONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp index 9f04f2805..ebe679c44 100644 --- a/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp +++ b/src/BulletDynamics/ConstraintSolver/btTypedConstraint.cpp @@ -13,69 +13,63 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btTypedConstraint.h" #include "BulletDynamics/Dynamics/btRigidBody.h" #include "LinearMath/btSerializer.h" - #define DEFAULT_DEBUGDRAW_SIZE btScalar(0.05f) btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA) -:btTypedObject(type), -m_userConstraintType(-1), -m_userConstraintPtr((void*)-1), -m_breakingImpulseThreshold(SIMD_INFINITY), -m_isEnabled(true), -m_needsFeedback(false), -m_overrideNumSolverIterations(-1), -m_rbA(rbA), -m_rbB(getFixedBody()), -m_appliedImpulse(btScalar(0.)), -m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE), -m_jointFeedback(0) + : btTypedObject(type), + m_userConstraintType(-1), + m_userConstraintPtr((void*)-1), + m_breakingImpulseThreshold(SIMD_INFINITY), + m_isEnabled(true), + m_needsFeedback(false), + m_overrideNumSolverIterations(-1), + m_rbA(rbA), + m_rbB(getFixedBody()), + m_appliedImpulse(btScalar(0.)), + m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE), + m_jointFeedback(0) { } - -btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB) -:btTypedObject(type), -m_userConstraintType(-1), -m_userConstraintPtr((void*)-1), -m_breakingImpulseThreshold(SIMD_INFINITY), -m_isEnabled(true), -m_needsFeedback(false), -m_overrideNumSolverIterations(-1), -m_rbA(rbA), -m_rbB(rbB), -m_appliedImpulse(btScalar(0.)), -m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE), -m_jointFeedback(0) +btTypedConstraint::btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA, btRigidBody& rbB) + : btTypedObject(type), + m_userConstraintType(-1), + m_userConstraintPtr((void*)-1), + m_breakingImpulseThreshold(SIMD_INFINITY), + m_isEnabled(true), + m_needsFeedback(false), + m_overrideNumSolverIterations(-1), + m_rbA(rbA), + m_rbB(rbB), + m_appliedImpulse(btScalar(0.)), + m_dbgDrawSize(DEFAULT_DEBUGDRAW_SIZE), + m_jointFeedback(0) { } - - - btScalar btTypedConstraint::getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact) { - if(lowLim > uppLim) + if (lowLim > uppLim) { return btScalar(1.0f); } - else if(lowLim == uppLim) + else if (lowLim == uppLim) { return btScalar(0.0f); } btScalar lim_fact = btScalar(1.0f); btScalar delta_max = vel / timeFact; - if(delta_max < btScalar(0.0f)) + if (delta_max < btScalar(0.0f)) { - if((pos >= lowLim) && (pos < (lowLim - delta_max))) + if ((pos >= lowLim) && (pos < (lowLim - delta_max))) { lim_fact = (lowLim - pos) / delta_max; } - else if(pos < lowLim) + else if (pos < lowLim) { lim_fact = btScalar(0.0f); } @@ -84,13 +78,13 @@ btScalar btTypedConstraint::getMotorFactor(btScalar pos, btScalar lowLim, btScal lim_fact = btScalar(1.0f); } } - else if(delta_max > btScalar(0.0f)) + else if (delta_max > btScalar(0.0f)) { - if((pos <= uppLim) && (pos > (uppLim - delta_max))) + if ((pos <= uppLim) && (pos > (uppLim - delta_max))) { lim_fact = (uppLim - pos) / delta_max; } - else if(pos > uppLim) + else if (pos > uppLim) { lim_fact = btScalar(0.0f); } @@ -101,19 +95,19 @@ btScalar btTypedConstraint::getMotorFactor(btScalar pos, btScalar lowLim, btScal } else { - lim_fact = btScalar(0.0f); + lim_fact = btScalar(0.0f); } return lim_fact; } ///fills the dataBuffer and returns the struct name (and 0 on failure) -const char* btTypedConstraint::serialize(void* dataBuffer, btSerializer* serializer) const +const char* btTypedConstraint::serialize(void* dataBuffer, btSerializer* serializer) const { - btTypedConstraintData2* tcd = (btTypedConstraintData2*) dataBuffer; + btTypedConstraintData2* tcd = (btTypedConstraintData2*)dataBuffer; tcd->m_rbA = (btRigidBodyData*)serializer->getUniquePointer(&m_rbA); tcd->m_rbB = (btRigidBodyData*)serializer->getUniquePointer(&m_rbB); - char* name = (char*) serializer->findNameForPointer(this); + char* name = (char*)serializer->findNameForPointer(this); tcd->m_name = (char*)serializer->getUniquePointer(name); if (tcd->m_name) { @@ -124,10 +118,10 @@ const char* btTypedConstraint::serialize(void* dataBuffer, btSerializer* seriali tcd->m_needsFeedback = m_needsFeedback; tcd->m_overrideNumSolverIterations = m_overrideNumSolverIterations; tcd->m_breakingImpulseThreshold = m_breakingImpulseThreshold; - tcd->m_isEnabled = m_isEnabled? 1: 0; - - tcd->m_userConstraintId =m_userConstraintId; - tcd->m_userConstraintType =m_userConstraintType; + tcd->m_isEnabled = m_isEnabled ? 1 : 0; + + tcd->m_userConstraintId = m_userConstraintId; + tcd->m_userConstraintType = m_userConstraintType; tcd->m_appliedImpulse = m_appliedImpulse; tcd->m_dbgDrawSize = m_dbgDrawSize; @@ -135,10 +129,10 @@ const char* btTypedConstraint::serialize(void* dataBuffer, btSerializer* seriali tcd->m_disableCollisionsBetweenLinkedBodies = false; int i; - for (i=0;im_disableCollisionsBetweenLinkedBodies = true; - for (i=0;im_disableCollisionsBetweenLinkedBodies = true; @@ -147,17 +141,16 @@ const char* btTypedConstraint::serialize(void* dataBuffer, btSerializer* seriali btRigidBody& btTypedConstraint::getFixedBody() { - static btRigidBody s_fixed(0, 0,0); - s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.))); + static btRigidBody s_fixed(0, 0, 0); + s_fixed.setMassProps(btScalar(0.), btVector3(btScalar(0.), btScalar(0.), btScalar(0.))); return s_fixed; } - void btAngularLimit::set(btScalar low, btScalar high, btScalar _softness, btScalar _biasFactor, btScalar _relaxationFactor) { m_halfRange = (high - low) / 2.0f; m_center = btNormalizeAngle(low + m_halfRange); - m_softness = _softness; + m_softness = _softness; m_biasFactor = _biasFactor; m_relaxationFactor = _relaxationFactor; } @@ -174,7 +167,7 @@ void btAngularLimit::test(const btScalar angle) if (deviation < -m_halfRange) { m_solveLimit = true; - m_correction = - (deviation + m_halfRange); + m_correction = -(deviation + m_halfRange); m_sign = +1.0f; } else if (deviation > m_halfRange) @@ -186,7 +179,6 @@ void btAngularLimit::test(const btScalar angle) } } - btScalar btAngularLimit::getError() const { return m_correction * m_sign; diff --git a/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h b/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h index 8a2a2d1ae..d30f3dee5 100644 --- a/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h +++ b/src/BulletDynamics/ConstraintSolver/btTypedConstraint.h @@ -16,26 +16,24 @@ subject to the following restrictions: #ifndef BT_TYPED_CONSTRAINT_H #define BT_TYPED_CONSTRAINT_H - #include "LinearMath/btScalar.h" #include "btSolverConstraint.h" #include "BulletDynamics/Dynamics/btRigidBody.h" #ifdef BT_USE_DOUBLE_PRECISION -#define btTypedConstraintData2 btTypedConstraintDoubleData -#define btTypedConstraintDataName "btTypedConstraintDoubleData" +#define btTypedConstraintData2 btTypedConstraintDoubleData +#define btTypedConstraintDataName "btTypedConstraintDoubleData" #else -#define btTypedConstraintData2 btTypedConstraintFloatData -#define btTypedConstraintDataName "btTypedConstraintFloatData" -#endif //BT_USE_DOUBLE_PRECISION - +#define btTypedConstraintData2 btTypedConstraintFloatData +#define btTypedConstraintDataName "btTypedConstraintFloatData" +#endif //BT_USE_DOUBLE_PRECISION class btSerializer; //Don't change any of the existing enum values, so add enum types at the end for serialization compatibility enum btTypedConstraintType { - POINT2POINT_CONSTRAINT_TYPE=3, + POINT2POINT_CONSTRAINT_TYPE = 3, HINGE_CONSTRAINT_TYPE, CONETWIST_CONSTRAINT_TYPE, D6_CONSTRAINT_TYPE, @@ -48,91 +46,88 @@ enum btTypedConstraintType MAX_CONSTRAINT_TYPE }; - enum btConstraintParams { - BT_CONSTRAINT_ERP=1, + BT_CONSTRAINT_ERP = 1, BT_CONSTRAINT_STOP_ERP, BT_CONSTRAINT_CFM, BT_CONSTRAINT_STOP_CFM }; #if 1 - #define btAssertConstrParams(_par) btAssert(_par) +#define btAssertConstrParams(_par) btAssert(_par) #else - #define btAssertConstrParams(_par) +#define btAssertConstrParams(_par) #endif - -ATTRIBUTE_ALIGNED16(struct) btJointFeedback +ATTRIBUTE_ALIGNED16(struct) +btJointFeedback { BT_DECLARE_ALIGNED_ALLOCATOR(); - btVector3 m_appliedForceBodyA; - btVector3 m_appliedTorqueBodyA; - btVector3 m_appliedForceBodyB; - btVector3 m_appliedTorqueBodyB; + btVector3 m_appliedForceBodyA; + btVector3 m_appliedTorqueBodyA; + btVector3 m_appliedForceBodyB; + btVector3 m_appliedTorqueBodyB; }; - ///TypedConstraint is the baseclass for Bullet constraints and vehicles -ATTRIBUTE_ALIGNED16(class) btTypedConstraint : public btTypedObject +ATTRIBUTE_ALIGNED16(class) +btTypedConstraint : public btTypedObject { - int m_userConstraintType; + int m_userConstraintType; - union - { - int m_userConstraintId; + union { + int m_userConstraintId; void* m_userConstraintPtr; }; - btScalar m_breakingImpulseThreshold; - bool m_isEnabled; - bool m_needsFeedback; - int m_overrideNumSolverIterations; + btScalar m_breakingImpulseThreshold; + bool m_isEnabled; + bool m_needsFeedback; + int m_overrideNumSolverIterations; - - btTypedConstraint& operator=(btTypedConstraint& other) + btTypedConstraint& operator=(btTypedConstraint& other) { btAssert(0); - (void) other; + (void)other; return *this; } protected: - btRigidBody& m_rbA; - btRigidBody& m_rbB; - btScalar m_appliedImpulse; - btScalar m_dbgDrawSize; - btJointFeedback* m_jointFeedback; + btRigidBody& m_rbA; + btRigidBody& m_rbB; + btScalar m_appliedImpulse; + btScalar m_dbgDrawSize; + btJointFeedback* m_jointFeedback; ///internal method used by the constraint solver, don't use them directly btScalar getMotorFactor(btScalar pos, btScalar lowLim, btScalar uppLim, btScalar vel, btScalar timeFact); - public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - virtual ~btTypedConstraint() {}; - btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA); - btTypedConstraint(btTypedConstraintType type, btRigidBody& rbA,btRigidBody& rbB); + virtual ~btTypedConstraint(){}; + btTypedConstraint(btTypedConstraintType type, btRigidBody & rbA); + btTypedConstraint(btTypedConstraintType type, btRigidBody & rbA, btRigidBody & rbB); - struct btConstraintInfo1 { - int m_numConstraintRows,nub; + struct btConstraintInfo1 + { + int m_numConstraintRows, nub; }; static btRigidBody& getFixedBody(); - struct btConstraintInfo2 { + struct btConstraintInfo2 + { // integrator parameters: frames per second (1/stepsize), default error // reduction parameter (0..1). - btScalar fps,erp; + btScalar fps, erp; // for the first and second body, pointers to two (linear and angular) // n*3 jacobian sub matrices, stored by rows. these matrices will have // been initialized to 0 on entry. if the second body is zero then the // J2xx pointers may be 0. - btScalar *m_J1linearAxis,*m_J1angularAxis,*m_J2linearAxis,*m_J2angularAxis; + btScalar *m_J1linearAxis, *m_J1angularAxis, *m_J2linearAxis, *m_J2angularAxis; // elements to jump from one row to the next in J's int rowskip; @@ -140,19 +135,19 @@ public: // right hand sides of the equation J*v = c + cfm * lambda. cfm is the // "constraint force mixing" vector. c is set to zero on entry, cfm is // set to a constant value (typically very small or zero) value on entry. - btScalar *m_constraintError,*cfm; + btScalar *m_constraintError, *cfm; // lo and hi limits for variables (set to -/+ infinity on entry). - btScalar *m_lowerLimit,*m_upperLimit; + btScalar *m_lowerLimit, *m_upperLimit; // number of solver iterations int m_numIterations; //damping of the velocity - btScalar m_damping; + btScalar m_damping; }; - int getOverrideNumSolverIterations() const + int getOverrideNumSolverIterations() const { return m_overrideNumSolverIterations; } @@ -165,60 +160,57 @@ public: } ///internal method used by the constraint solver, don't use them directly - virtual void buildJacobian() {}; + virtual void buildJacobian(){}; ///internal method used by the constraint solver, don't use them directly - virtual void setupSolverConstraint(btConstraintArray& ca, int solverBodyA,int solverBodyB, btScalar timeStep) + virtual void setupSolverConstraint(btConstraintArray & ca, int solverBodyA, int solverBodyB, btScalar timeStep) { - (void)ca; - (void)solverBodyA; - (void)solverBodyB; - (void)timeStep; + (void)ca; + (void)solverBodyA; + (void)solverBodyB; + (void)timeStep; } - - ///internal method used by the constraint solver, don't use them directly - virtual void getInfo1 (btConstraintInfo1* info)=0; ///internal method used by the constraint solver, don't use them directly - virtual void getInfo2 (btConstraintInfo2* info)=0; + virtual void getInfo1(btConstraintInfo1 * info) = 0; ///internal method used by the constraint solver, don't use them directly - void internalSetAppliedImpulse(btScalar appliedImpulse) + virtual void getInfo2(btConstraintInfo2 * info) = 0; + + ///internal method used by the constraint solver, don't use them directly + void internalSetAppliedImpulse(btScalar appliedImpulse) { m_appliedImpulse = appliedImpulse; } ///internal method used by the constraint solver, don't use them directly - btScalar internalGetAppliedImpulse() + btScalar internalGetAppliedImpulse() { return m_appliedImpulse; } - - btScalar getBreakingImpulseThreshold() const + btScalar getBreakingImpulseThreshold() const { - return m_breakingImpulseThreshold; + return m_breakingImpulseThreshold; } - void setBreakingImpulseThreshold(btScalar threshold) + void setBreakingImpulseThreshold(btScalar threshold) { m_breakingImpulseThreshold = threshold; } - bool isEnabled() const + bool isEnabled() const { return m_isEnabled; } - void setEnabled(bool enabled) + void setEnabled(bool enabled) { - m_isEnabled=enabled; + m_isEnabled = enabled; } - ///internal method used by the constraint solver, don't use them directly - virtual void solveConstraintObsolete(btSolverBody& /*bodyA*/,btSolverBody& /*bodyB*/,btScalar /*timeStep*/) {}; + virtual void solveConstraintObsolete(btSolverBody& /*bodyA*/, btSolverBody& /*bodyB*/, btScalar /*timeStep*/){}; - const btRigidBody& getRigidBodyA() const { return m_rbA; @@ -228,7 +220,7 @@ public: return m_rbB; } - btRigidBody& getRigidBodyA() + btRigidBody& getRigidBodyA() { return m_rbA; } @@ -239,15 +231,15 @@ public: int getUserConstraintType() const { - return m_userConstraintType ; + return m_userConstraintType; } - void setUserConstraintType(int userConstraintType) + void setUserConstraintType(int userConstraintType) { m_userConstraintType = userConstraintType; }; - void setUserConstraintId(int uid) + void setUserConstraintId(int uid) { m_userConstraintId = uid; } @@ -257,17 +249,17 @@ public: return m_userConstraintId; } - void setUserConstraintPtr(void* ptr) + void setUserConstraintPtr(void* ptr) { m_userConstraintPtr = ptr; } - void* getUserConstraintPtr() + void* getUserConstraintPtr() { return m_userConstraintPtr; } - void setJointFeedback(btJointFeedback* jointFeedback) + void setJointFeedback(btJointFeedback * jointFeedback) { m_jointFeedback = jointFeedback; } @@ -282,37 +274,36 @@ public: return m_jointFeedback; } - int getUid() const { - return m_userConstraintId; - } + return m_userConstraintId; + } - bool needsFeedback() const + bool needsFeedback() const { return m_needsFeedback; } ///enableFeedback will allow to read the applied linear and angular impulse ///use getAppliedImpulse, getAppliedLinearImpulse and getAppliedAngularImpulse to read feedback information - void enableFeedback(bool needsFeedback) + void enableFeedback(bool needsFeedback) { m_needsFeedback = needsFeedback; } - ///getAppliedImpulse is an estimated total applied impulse. + ///getAppliedImpulse is an estimated total applied impulse. ///This feedback could be used to determine breaking constraints or playing sounds. - btScalar getAppliedImpulse() const + btScalar getAppliedImpulse() const { btAssert(m_needsFeedback); return m_appliedImpulse; } - btTypedConstraintType getConstraintType () const + btTypedConstraintType getConstraintType() const { return btTypedConstraintType(m_objectType); } - + void setDbgDrawSize(btScalar dbgDrawSize) { m_dbgDrawSize = dbgDrawSize; @@ -322,35 +313,34 @@ public: return m_dbgDrawSize; } - ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). + ///override the default global value of a parameter (such as ERP or CFM), optionally provide the axis (0..5). ///If no axis is provided, it uses the default axis for this constraint. - virtual void setParam(int num, btScalar value, int axis = -1) = 0; + virtual void setParam(int num, btScalar value, int axis = -1) = 0; ///return the local value of parameter - virtual btScalar getParam(int num, int axis = -1) const = 0; - - virtual int calculateSerializeBufferSize() const; + virtual btScalar getParam(int num, int axis = -1) const = 0; + + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; - + virtual const char* serialize(void* dataBuffer, btSerializer* serializer) const; }; -// returns angle in range [-SIMD_2_PI, SIMD_2_PI], closest to one of the limits +// returns angle in range [-SIMD_2_PI, SIMD_2_PI], closest to one of the limits // all arguments should be normalized angles (i.e. in range [-SIMD_PI, SIMD_PI]) SIMD_FORCE_INLINE btScalar btAdjustAngleToLimits(btScalar angleInRadians, btScalar angleLowerLimitInRadians, btScalar angleUpperLimitInRadians) { - if(angleLowerLimitInRadians >= angleUpperLimitInRadians) + if (angleLowerLimitInRadians >= angleUpperLimitInRadians) { return angleInRadians; } - else if(angleInRadians < angleLowerLimitInRadians) + else if (angleInRadians < angleLowerLimitInRadians) { btScalar diffLo = btFabs(btNormalizeAngle(angleLowerLimitInRadians - angleInRadians)); btScalar diffHi = btFabs(btNormalizeAngle(angleUpperLimitInRadians - angleInRadians)); return (diffLo < diffHi) ? angleInRadians : (angleInRadians + SIMD_2_PI); } - else if(angleInRadians > angleUpperLimitInRadians) + else if (angleInRadians > angleUpperLimitInRadians) { btScalar diffHi = btFabs(btNormalizeAngle(angleInRadians - angleUpperLimitInRadians)); btScalar diffLo = btFabs(btNormalizeAngle(angleInRadians - angleLowerLimitInRadians)); @@ -362,6 +352,8 @@ SIMD_FORCE_INLINE btScalar btAdjustAngleToLimits(btScalar angleInRadians, btScal } } +// clang-format off + ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 struct btTypedConstraintFloatData { @@ -385,6 +377,8 @@ struct btTypedConstraintFloatData }; + + ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 #define BT_BACKWARDS_COMPATIBLE_SERIALIZATION @@ -436,18 +430,17 @@ struct btTypedConstraintDoubleData }; +// clang-format on -SIMD_FORCE_INLINE int btTypedConstraint::calculateSerializeBufferSize() const +SIMD_FORCE_INLINE int btTypedConstraint::calculateSerializeBufferSize() const { return sizeof(btTypedConstraintData2); } - - class btAngularLimit { private: - btScalar + btScalar m_center, m_halfRange, m_softness, @@ -462,15 +455,16 @@ private: public: /// Default constructor initializes limit as inactive, allowing free constraint movement btAngularLimit() - :m_center(0.0f), - m_halfRange(-1.0f), - m_softness(0.9f), - m_biasFactor(0.3f), - m_relaxationFactor(1.0f), - m_correction(0.0f), - m_sign(0.0f), - m_solveLimit(false) - {} + : m_center(0.0f), + m_halfRange(-1.0f), + m_softness(0.9f), + m_biasFactor(0.3f), + m_relaxationFactor(1.0f), + m_correction(0.0f), + m_sign(0.0f), + m_solveLimit(false) + { + } /// Sets all limit's parameters. /// When low > high limit becomes inactive. @@ -499,13 +493,13 @@ public: return m_relaxationFactor; } - /// Returns correction value evaluated when test() was invoked + /// Returns correction value evaluated when test() was invoked inline btScalar getCorrection() const { return m_correction; } - /// Returns sign value evaluated when test() was invoked + /// Returns sign value evaluated when test() was invoked inline btScalar getSign() const { return m_sign; @@ -533,9 +527,6 @@ public: btScalar getLow() const; btScalar getHigh() const; - }; - - -#endif //BT_TYPED_CONSTRAINT_H +#endif //BT_TYPED_CONSTRAINT_H diff --git a/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp b/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp index b009f41ae..42ed1fbb8 100644 --- a/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp +++ b/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.cpp @@ -13,43 +13,38 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "btUniversalConstraint.h" #include "BulletDynamics/Dynamics/btRigidBody.h" #include "LinearMath/btTransformUtil.h" - - #define UNIV_EPS btScalar(0.01f) - // constructor // anchor, axis1 and axis2 are in world coordinate system // axis1 must be orthogonal to axis2 btUniversalConstraint::btUniversalConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& anchor, const btVector3& axis1, const btVector3& axis2) -: btGeneric6DofConstraint(rbA, rbB, btTransform::getIdentity(), btTransform::getIdentity(), true), - m_anchor(anchor), - m_axis1(axis1), - m_axis2(axis2) + : btGeneric6DofConstraint(rbA, rbB, btTransform::getIdentity(), btTransform::getIdentity(), true), + m_anchor(anchor), + m_axis1(axis1), + m_axis2(axis2) { // build frame basis // 6DOF constraint uses Euler angles and to define limits // it is assumed that rotational order is : // Z - first, allowed limits are (-PI,PI); - // new position of Y - second (allowed limits are (-PI/2 + epsilon, PI/2 - epsilon), where epsilon is a small positive number + // new position of Y - second (allowed limits are (-PI/2 + epsilon, PI/2 - epsilon), where epsilon is a small positive number // used to prevent constraint from instability on poles; // new position of X, allowed limits are (-PI,PI); // So to simulate ODE Universal joint we should use parent axis as Z, child axis as Y and limit all other DOFs // Build the frame in world coordinate system first btVector3 zAxis = m_axis1.normalize(); btVector3 yAxis = m_axis2.normalize(); - btVector3 xAxis = yAxis.cross(zAxis); // we want right coordinate system + btVector3 xAxis = yAxis.cross(zAxis); // we want right coordinate system btTransform frameInW; frameInW.setIdentity(); - frameInW.getBasis().setValue( xAxis[0], yAxis[0], zAxis[0], - xAxis[1], yAxis[1], zAxis[1], - xAxis[2], yAxis[2], zAxis[2]); + frameInW.getBasis().setValue(xAxis[0], yAxis[0], zAxis[0], + xAxis[1], yAxis[1], zAxis[1], + xAxis[2], yAxis[2], zAxis[2]); frameInW.setOrigin(anchor); // now get constraint frame in local coordinate systems m_frameInA = rbA.getCenterOfMassTransform().inverse() * frameInW; @@ -58,30 +53,28 @@ btUniversalConstraint::btUniversalConstraint(btRigidBody& rbA, btRigidBody& rbB, setLinearLowerLimit(btVector3(0., 0., 0.)); setLinearUpperLimit(btVector3(0., 0., 0.)); setAngularLowerLimit(btVector3(0.f, -SIMD_HALF_PI + UNIV_EPS, -SIMD_PI + UNIV_EPS)); - setAngularUpperLimit(btVector3(0.f, SIMD_HALF_PI - UNIV_EPS, SIMD_PI - UNIV_EPS)); + setAngularUpperLimit(btVector3(0.f, SIMD_HALF_PI - UNIV_EPS, SIMD_PI - UNIV_EPS)); } -void btUniversalConstraint::setAxis(const btVector3& axis1,const btVector3& axis2) +void btUniversalConstraint::setAxis(const btVector3& axis1, const btVector3& axis2) { - m_axis1 = axis1; - m_axis2 = axis2; + m_axis1 = axis1; + m_axis2 = axis2; btVector3 zAxis = axis1.normalized(); btVector3 yAxis = axis2.normalized(); - btVector3 xAxis = yAxis.cross(zAxis); // we want right coordinate system + btVector3 xAxis = yAxis.cross(zAxis); // we want right coordinate system btTransform frameInW; frameInW.setIdentity(); - frameInW.getBasis().setValue( xAxis[0], yAxis[0], zAxis[0], - xAxis[1], yAxis[1], zAxis[1], - xAxis[2], yAxis[2], zAxis[2]); + frameInW.getBasis().setValue(xAxis[0], yAxis[0], zAxis[0], + xAxis[1], yAxis[1], zAxis[1], + xAxis[2], yAxis[2], zAxis[2]); frameInW.setOrigin(m_anchor); // now get constraint frame in local coordinate systems m_frameInA = m_rbA.getCenterOfMassTransform().inverse() * frameInW; m_frameInB = m_rbB.getCenterOfMassTransform().inverse() * frameInW; - calculateTransforms(); + calculateTransforms(); } - - diff --git a/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.h b/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.h index 9e7084104..8c24d93a6 100644 --- a/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.h +++ b/src/BulletDynamics/ConstraintSolver/btUniversalConstraint.h @@ -16,35 +16,32 @@ subject to the following restrictions: #ifndef BT_UNIVERSAL_CONSTRAINT_H #define BT_UNIVERSAL_CONSTRAINT_H - - #include "LinearMath/btVector3.h" #include "btTypedConstraint.h" #include "btGeneric6DofConstraint.h" - - /// Constraint similar to ODE Universal Joint /// has 2 rotatioonal degrees of freedom, similar to Euler rotations around Z (axis 1) /// and Y (axis 2) -/// Description from ODE manual : -/// "Given axis 1 on body 1, and axis 2 on body 2 that is perpendicular to axis 1, it keeps them perpendicular. +/// Description from ODE manual : +/// "Given axis 1 on body 1, and axis 2 on body 2 that is perpendicular to axis 1, it keeps them perpendicular. /// In other words, rotation of the two bodies about the direction perpendicular to the two axes will be equal." -ATTRIBUTE_ALIGNED16(class) btUniversalConstraint : public btGeneric6DofConstraint +ATTRIBUTE_ALIGNED16(class) +btUniversalConstraint : public btGeneric6DofConstraint { protected: - btVector3 m_anchor; - btVector3 m_axis1; - btVector3 m_axis2; + btVector3 m_anchor; + btVector3 m_axis1; + btVector3 m_axis2; + public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - + // constructor // anchor, axis1 and axis2 are in world coordinate system // axis1 must be orthogonal to axis2 - btUniversalConstraint(btRigidBody& rbA, btRigidBody& rbB, const btVector3& anchor, const btVector3& axis1, const btVector3& axis2); + btUniversalConstraint(btRigidBody & rbA, btRigidBody & rbB, const btVector3& anchor, const btVector3& axis1, const btVector3& axis2); // access const btVector3& getAnchor() { return m_calculatedTransformA.getOrigin(); } const btVector3& getAnchor2() { return m_calculatedTransformB.getOrigin(); } @@ -56,10 +53,7 @@ public: void setUpperLimit(btScalar ang1max, btScalar ang2max) { setAngularUpperLimit(btVector3(0.f, ang1max, ang2max)); } void setLowerLimit(btScalar ang1min, btScalar ang2min) { setAngularLowerLimit(btVector3(0.f, ang1min, ang2min)); } - void setAxis( const btVector3& axis1, const btVector3& axis2); + void setAxis(const btVector3& axis1, const btVector3& axis2); }; - - -#endif // BT_UNIVERSAL_CONSTRAINT_H - +#endif // BT_UNIVERSAL_CONSTRAINT_H diff --git a/src/BulletDynamics/Dynamics/btActionInterface.h b/src/BulletDynamics/Dynamics/btActionInterface.h index e1fea3a49..b5cac56cd 100644 --- a/src/BulletDynamics/Dynamics/btActionInterface.h +++ b/src/BulletDynamics/Dynamics/btActionInterface.h @@ -26,21 +26,16 @@ class btCollisionWorld; class btActionInterface { protected: - static btRigidBody& getFixedBody(); - - -public: +public: virtual ~btActionInterface() { } - virtual void updateAction( btCollisionWorld* collisionWorld, btScalar deltaTimeStep)=0; + virtual void updateAction(btCollisionWorld* collisionWorld, btScalar deltaTimeStep) = 0; virtual void debugDraw(btIDebugDraw* debugDrawer) = 0; - }; -#endif //_BT_ACTION_INTERFACE_H - +#endif //_BT_ACTION_INTERFACE_H diff --git a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp index b9944c138..dfbbdb154 100644 --- a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp +++ b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btDiscreteDynamicsWorld.h" //collision detection @@ -38,11 +37,9 @@ subject to the following restrictions: #include "BulletDynamics/ConstraintSolver/btSliderConstraint.h" #include "BulletDynamics/ConstraintSolver/btContactConstraint.h" - #include "LinearMath/btIDebugDraw.h" #include "BulletCollision/CollisionShapes/btSphereShape.h" - #include "BulletDynamics/Dynamics/btActionInterface.h" #include "LinearMath/btQuickprof.h" #include "LinearMath/btMotionState.h" @@ -56,57 +53,52 @@ int startHit=2; int firstHit=startHit; #endif -SIMD_FORCE_INLINE int btGetConstraintIslandId(const btTypedConstraint* lhs) +SIMD_FORCE_INLINE int btGetConstraintIslandId(const btTypedConstraint* lhs) { int islandId; const btCollisionObject& rcolObj0 = lhs->getRigidBodyA(); const btCollisionObject& rcolObj1 = lhs->getRigidBodyB(); - islandId= rcolObj0.getIslandTag()>=0?rcolObj0.getIslandTag():rcolObj1.getIslandTag(); + islandId = rcolObj0.getIslandTag() >= 0 ? rcolObj0.getIslandTag() : rcolObj1.getIslandTag(); return islandId; - } - class btSortConstraintOnIslandPredicate { - public: - - bool operator() ( const btTypedConstraint* lhs, const btTypedConstraint* rhs ) const - { - int rIslandId0,lIslandId0; - rIslandId0 = btGetConstraintIslandId(rhs); - lIslandId0 = btGetConstraintIslandId(lhs); - return lIslandId0 < rIslandId0; - } +public: + bool operator()(const btTypedConstraint* lhs, const btTypedConstraint* rhs) const + { + int rIslandId0, lIslandId0; + rIslandId0 = btGetConstraintIslandId(rhs); + lIslandId0 = btGetConstraintIslandId(lhs); + return lIslandId0 < rIslandId0; + } }; struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCallback { - btContactSolverInfo* m_solverInfo; - btConstraintSolver* m_solver; - btTypedConstraint** m_sortedConstraints; - int m_numConstraints; - btIDebugDraw* m_debugDrawer; - btDispatcher* m_dispatcher; + btContactSolverInfo* m_solverInfo; + btConstraintSolver* m_solver; + btTypedConstraint** m_sortedConstraints; + int m_numConstraints; + btIDebugDraw* m_debugDrawer; + btDispatcher* m_dispatcher; btAlignedObjectArray m_bodies; btAlignedObjectArray m_manifolds; btAlignedObjectArray m_constraints; - InplaceSolverIslandCallback( - btConstraintSolver* solver, + btConstraintSolver* solver, btStackAlloc* stackAlloc, btDispatcher* dispatcher) - :m_solverInfo(NULL), - m_solver(solver), - m_sortedConstraints(NULL), - m_numConstraints(0), - m_debugDrawer(NULL), - m_dispatcher(dispatcher) + : m_solverInfo(NULL), + m_solver(solver), + m_sortedConstraints(NULL), + m_numConstraints(0), + m_debugDrawer(NULL), + m_dispatcher(dispatcher) { - } InplaceSolverIslandCallback& operator=(InplaceSolverIslandCallback& other) @@ -116,34 +108,34 @@ struct InplaceSolverIslandCallback : public btSimulationIslandManager::IslandCal return *this; } - SIMD_FORCE_INLINE void setup ( btContactSolverInfo* solverInfo, btTypedConstraint** sortedConstraints, int numConstraints, btIDebugDraw* debugDrawer) + SIMD_FORCE_INLINE void setup(btContactSolverInfo* solverInfo, btTypedConstraint** sortedConstraints, int numConstraints, btIDebugDraw* debugDrawer) { btAssert(solverInfo); m_solverInfo = solverInfo; m_sortedConstraints = sortedConstraints; m_numConstraints = numConstraints; m_debugDrawer = debugDrawer; - m_bodies.resize (0); - m_manifolds.resize (0); - m_constraints.resize (0); + m_bodies.resize(0); + m_manifolds.resize(0); + m_constraints.resize(0); } - - virtual void processIsland(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifolds,int numManifolds, int islandId) + virtual void processIsland(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifolds, int numManifolds, int islandId) { - if (islandId<0) + if (islandId < 0) { ///we don't split islands, so all constraints/contact manifolds/bodies are passed into the solver regardless the island id - m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,&m_sortedConstraints[0],m_numConstraints,*m_solverInfo,m_debugDrawer,m_dispatcher); - } else + m_solver->solveGroup(bodies, numBodies, manifolds, numManifolds, &m_sortedConstraints[0], m_numConstraints, *m_solverInfo, m_debugDrawer, m_dispatcher); + } + else { - //also add all non-contact constraints/joints for this island + //also add all non-contact constraints/joints for this island btTypedConstraint** startConstraint = 0; int numCurConstraints = 0; int i; //find the first constraint for this island - for (i=0;im_minimumSolverBatchSize<=1) + if (m_solverInfo->m_minimumSolverBatchSize <= 1) { - m_solver->solveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,*m_solverInfo,m_debugDrawer,m_dispatcher); - } else + m_solver->solveGroup(bodies, numBodies, manifolds, numManifolds, startConstraint, numCurConstraints, *m_solverInfo, m_debugDrawer, m_dispatcher); + } + else { - - for (i=0;im_solverInfo->m_minimumSolverBatchSize) + if ((m_constraints.size() + m_manifolds.size()) > m_solverInfo->m_minimumSolverBatchSize) { processConstraints(); - } else + } + else { //printf("deferred\n"); } } } } - void processConstraints() + void processConstraints() { + btCollisionObject** bodies = m_bodies.size() ? &m_bodies[0] : 0; + btPersistentManifold** manifold = m_manifolds.size() ? &m_manifolds[0] : 0; + btTypedConstraint** constraints = m_constraints.size() ? &m_constraints[0] : 0; - btCollisionObject** bodies = m_bodies.size()? &m_bodies[0]:0; - btPersistentManifold** manifold = m_manifolds.size()?&m_manifolds[0]:0; - btTypedConstraint** constraints = m_constraints.size()?&m_constraints[0]:0; - - m_solver->solveGroup( bodies,m_bodies.size(),manifold, m_manifolds.size(),constraints, m_constraints.size() ,*m_solverInfo,m_debugDrawer,m_dispatcher); + m_solver->solveGroup(bodies, m_bodies.size(), manifold, m_manifolds.size(), constraints, m_constraints.size(), *m_solverInfo, m_debugDrawer, m_dispatcher); m_bodies.resize(0); m_manifolds.resize(0); m_constraints.resize(0); - } - }; - - -btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration) -:btDynamicsWorld(dispatcher,pairCache,collisionConfiguration), -m_sortedConstraints (), -m_solverIslandCallback ( NULL ), -m_constraintSolver(constraintSolver), -m_gravity(0,-10,0), -m_localTime(0), -m_fixedTimeStep(0), -m_synchronizeAllMotionStates(false), -m_applySpeculativeContactRestitution(false), -m_profileTimings(0), -m_latencyMotionStateInterpolation(true) +btDiscreteDynamicsWorld::btDiscreteDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration) + : btDynamicsWorld(dispatcher, pairCache, collisionConfiguration), + m_sortedConstraints(), + m_solverIslandCallback(NULL), + m_constraintSolver(constraintSolver), + m_gravity(0, -10, 0), + m_localTime(0), + m_fixedTimeStep(0), + m_synchronizeAllMotionStates(false), + m_applySpeculativeContactRestitution(false), + m_profileTimings(0), + m_latencyMotionStateInterpolation(true) { if (!m_constraintSolver) { - void* mem = btAlignedAlloc(sizeof(btSequentialImpulseConstraintSolver),16); + void* mem = btAlignedAlloc(sizeof(btSequentialImpulseConstraintSolver), 16); m_constraintSolver = new (mem) btSequentialImpulseConstraintSolver; m_ownsConstraintSolver = true; - } else + } + else { m_ownsConstraintSolver = false; } { - void* mem = btAlignedAlloc(sizeof(btSimulationIslandManager),16); + void* mem = btAlignedAlloc(sizeof(btSimulationIslandManager), 16); m_islandManager = new (mem) btSimulationIslandManager(); } m_ownsIslandManager = true; { - void* mem = btAlignedAlloc(sizeof(InplaceSolverIslandCallback),16); - m_solverIslandCallback = new (mem) InplaceSolverIslandCallback (m_constraintSolver, 0, dispatcher); + void* mem = btAlignedAlloc(sizeof(InplaceSolverIslandCallback), 16); + m_solverIslandCallback = new (mem) InplaceSolverIslandCallback(m_constraintSolver, 0, dispatcher); } } - btDiscreteDynamicsWorld::~btDiscreteDynamicsWorld() { //only delete it when we created it if (m_ownsIslandManager) { m_islandManager->~btSimulationIslandManager(); - btAlignedFree( m_islandManager); + btAlignedFree(m_islandManager); } if (m_solverIslandCallback) { @@ -253,18 +241,17 @@ btDiscreteDynamicsWorld::~btDiscreteDynamicsWorld() } if (m_ownsConstraintSolver) { - m_constraintSolver->~btConstraintSolver(); btAlignedFree(m_constraintSolver); } } -void btDiscreteDynamicsWorld::saveKinematicState(btScalar timeStep) +void btDiscreteDynamicsWorld::saveKinematicState(btScalar timeStep) { -///would like to iterate over m_nonStaticRigidBodies, but unfortunately old API allows -///to switch status _after_ adding kinematic objects to the world -///fix it for Bullet 3.x release - for (int i=0;igetDebugMode(); - if(mode & (btIDebugDraw::DBG_DrawConstraints | btIDebugDraw::DBG_DrawConstraintLimits)) + if (mode & (btIDebugDraw::DBG_DrawConstraints | btIDebugDraw::DBG_DrawConstraintLimits)) { drawConstraints = true; } } - if(drawConstraints) + if (drawConstraints) { - for(int i = getNumConstraints()-1; i>=0 ;i--) + for (int i = getNumConstraints() - 1; i >= 0; i--) { btTypedConstraint* constraint = getConstraint(i); debugDrawConstraint(constraint); } } - - - if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb | btIDebugDraw::DBG_DrawNormals))) + if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe | btIDebugDraw::DBG_DrawAabb | btIDebugDraw::DBG_DrawNormals))) { int i; if (getDebugDrawer() && getDebugDrawer()->getDebugMode()) { - for (i=0;idebugDraw(m_debugDrawer); } } } - if (getDebugDrawer()) - getDebugDrawer()->flushLines(); - + if (getDebugDrawer()) + getDebugDrawer()->flushLines(); } -void btDiscreteDynamicsWorld::clearForces() +void btDiscreteDynamicsWorld::clearForces() { ///@todo: iterate over awake simulation islands! - for ( int i=0;iisActive()) @@ -349,8 +332,7 @@ void btDiscreteDynamicsWorld::applyGravity() } } - -void btDiscreteDynamicsWorld::synchronizeSingleMotionState(btRigidBody* body) +void btDiscreteDynamicsWorld::synchronizeSingleMotionState(btRigidBody* body) { btAssert(body); @@ -363,32 +345,32 @@ void btDiscreteDynamicsWorld::synchronizeSingleMotionState(btRigidBody* body) { btTransform interpolatedTransform; btTransformUtil::integrateTransform(body->getInterpolationWorldTransform(), - body->getInterpolationLinearVelocity(),body->getInterpolationAngularVelocity(), - (m_latencyMotionStateInterpolation && m_fixedTimeStep) ? m_localTime - m_fixedTimeStep : m_localTime*body->getHitFraction(), - interpolatedTransform); + body->getInterpolationLinearVelocity(), body->getInterpolationAngularVelocity(), + (m_latencyMotionStateInterpolation && m_fixedTimeStep) ? m_localTime - m_fixedTimeStep : m_localTime * body->getHitFraction(), + interpolatedTransform); body->getMotionState()->setWorldTransform(interpolatedTransform); } } } - -void btDiscreteDynamicsWorld::synchronizeMotionStates() +void btDiscreteDynamicsWorld::synchronizeMotionStates() { -// BT_PROFILE("synchronizeMotionStates"); + // BT_PROFILE("synchronizeMotionStates"); if (m_synchronizeAllMotionStates) { //iterate over all collision objects - for ( int i=0;iisActive()) @@ -397,12 +379,10 @@ void btDiscreteDynamicsWorld::synchronizeMotionStates() } } - -int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep) +int btDiscreteDynamicsWorld::stepSimulation(btScalar timeStep, int maxSubSteps, btScalar fixedTimeStep) { startProfiling(timeStep); - int numSimulationSubSteps = 0; if (maxSubSteps) @@ -412,10 +392,11 @@ int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, m_localTime += timeStep; if (m_localTime >= fixedTimeStep) { - numSimulationSubSteps = int( m_localTime / fixedTimeStep); + numSimulationSubSteps = int(m_localTime / fixedTimeStep); m_localTime -= numSimulationSubSteps * fixedTimeStep; } - } else + } + else { //variable timestep fixedTimeStep = timeStep; @@ -425,7 +406,8 @@ int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, { numSimulationSubSteps = 0; maxSubSteps = 0; - } else + } + else { numSimulationSubSteps = 1; maxSubSteps = 1; @@ -435,28 +417,25 @@ int btDiscreteDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, //process some debugging flags if (getDebugDrawer()) { - btIDebugDraw* debugDrawer = getDebugDrawer (); + btIDebugDraw* debugDrawer = getDebugDrawer(); gDisableDeactivation = (debugDrawer->getDebugMode() & btIDebugDraw::DBG_NoDeactivation) != 0; } if (numSimulationSubSteps) { - //clamp the number of substeps, to prevent simulation grinding spiralling down to a halt - int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps)? maxSubSteps : numSimulationSubSteps; + int clampedSimulationSteps = (numSimulationSubSteps > maxSubSteps) ? maxSubSteps : numSimulationSubSteps; - saveKinematicState(fixedTimeStep*clampedSimulationSteps); + saveKinematicState(fixedTimeStep * clampedSimulationSteps); applyGravity(); - - - for (int i=0;iisActive() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY)) + if (body->isActive() && !(body->getFlags() & BT_DISABLE_WORLD_GRAVITY)) { body->setGravity(gravity); } } } -btVector3 btDiscreteDynamicsWorld::getGravity () const +btVector3 btDiscreteDynamicsWorld::getGravity() const { return m_gravity; } -void btDiscreteDynamicsWorld::addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask) +void btDiscreteDynamicsWorld::addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup, int collisionFilterMask) { - btCollisionWorld::addCollisionObject(collisionObject,collisionFilterGroup,collisionFilterMask); + btCollisionWorld::addCollisionObject(collisionObject, collisionFilterGroup, collisionFilterMask); } -void btDiscreteDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject) +void btDiscreteDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject) { btRigidBody* body = btRigidBody::upcast(collisionObject); if (body) @@ -552,16 +528,15 @@ void btDiscreteDynamicsWorld::removeCollisionObject(btCollisionObject* collision btCollisionWorld::removeCollisionObject(collisionObject); } -void btDiscreteDynamicsWorld::removeRigidBody(btRigidBody* body) +void btDiscreteDynamicsWorld::removeRigidBody(btRigidBody* body) { m_nonStaticRigidBodies.remove(body); btCollisionWorld::removeCollisionObject(body); } - -void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body) +void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body) { - if (!body->isStaticOrKinematicObject() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY)) + if (!body->isStaticOrKinematicObject() && !(body->getFlags() & BT_DISABLE_WORLD_GRAVITY)) { body->setGravity(m_gravity); } @@ -571,22 +546,23 @@ void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body) if (!body->isStaticObject()) { m_nonStaticRigidBodies.push_back(body); - } else + } + else { body->setActivationState(ISLAND_SLEEPING); } bool isDynamic = !(body->isStaticObject() || body->isKinematicObject()); - int collisionFilterGroup = isDynamic? int(btBroadphaseProxy::DefaultFilter) : int(btBroadphaseProxy::StaticFilter); - int collisionFilterMask = isDynamic? int(btBroadphaseProxy::AllFilter) : int(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter); + int collisionFilterGroup = isDynamic ? int(btBroadphaseProxy::DefaultFilter) : int(btBroadphaseProxy::StaticFilter); + int collisionFilterMask = isDynamic ? int(btBroadphaseProxy::AllFilter) : int(btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter); - addCollisionObject(body,collisionFilterGroup,collisionFilterMask); + addCollisionObject(body, collisionFilterGroup, collisionFilterMask); } } -void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body, int group, int mask) +void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body, int group, int mask) { - if (!body->isStaticOrKinematicObject() && !(body->getFlags() &BT_DISABLE_WORLD_GRAVITY)) + if (!body->isStaticOrKinematicObject() && !(body->getFlags() & BT_DISABLE_WORLD_GRAVITY)) { body->setGravity(m_gravity); } @@ -597,31 +573,29 @@ void btDiscreteDynamicsWorld::addRigidBody(btRigidBody* body, int group, int mas { m_nonStaticRigidBodies.push_back(body); } - else + else { body->setActivationState(ISLAND_SLEEPING); } - addCollisionObject(body,group,mask); + addCollisionObject(body, group, mask); } } - -void btDiscreteDynamicsWorld::updateActions(btScalar timeStep) +void btDiscreteDynamicsWorld::updateActions(btScalar timeStep) { BT_PROFILE("updateActions"); - for ( int i=0;iupdateAction( this, timeStep); + m_actions[i]->updateAction(this, timeStep); } } - -void btDiscreteDynamicsWorld::updateActivationState(btScalar timeStep) +void btDiscreteDynamicsWorld::updateActivationState(btScalar timeStep) { BT_PROFILE("updateActivationState"); - for ( int i=0;iisStaticOrKinematicObject()) { body->setActivationState(ISLAND_SLEEPING); - } else + } + else { if (body->getActivationState() == ACTIVE_TAG) - body->setActivationState( WANTS_DEACTIVATION ); + body->setActivationState(WANTS_DEACTIVATION); if (body->getActivationState() == ISLAND_SLEEPING) { - body->setAngularVelocity(btVector3(0,0,0)); - body->setLinearVelocity(btVector3(0,0,0)); + body->setAngularVelocity(btVector3(0, 0, 0)); + body->setLinearVelocity(btVector3(0, 0, 0)); } - } - } else + } + else { if (body->getActivationState() != DISABLE_DEACTIVATION) - body->setActivationState( ACTIVE_TAG ); + body->setActivationState(ACTIVE_TAG); } } } } -void btDiscreteDynamicsWorld::addConstraint(btTypedConstraint* constraint,bool disableCollisionsBetweenLinkedBodies) +void btDiscreteDynamicsWorld::addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies) { m_constraints.push_back(constraint); - //Make sure the two bodies of a type constraint are different (possibly add this to the btTypedConstraint constructor?) - btAssert(&constraint->getRigidBodyA()!=&constraint->getRigidBodyB()); - + //Make sure the two bodies of a type constraint are different (possibly add this to the btTypedConstraint constructor?) + btAssert(&constraint->getRigidBodyA() != &constraint->getRigidBodyB()); + if (disableCollisionsBetweenLinkedBodies) { constraint->getRigidBodyA().addConstraintRef(constraint); @@ -666,105 +641,98 @@ void btDiscreteDynamicsWorld::addConstraint(btTypedConstraint* constraint,bool d } } -void btDiscreteDynamicsWorld::removeConstraint(btTypedConstraint* constraint) +void btDiscreteDynamicsWorld::removeConstraint(btTypedConstraint* constraint) { m_constraints.remove(constraint); constraint->getRigidBodyA().removeConstraintRef(constraint); constraint->getRigidBodyB().removeConstraintRef(constraint); } -void btDiscreteDynamicsWorld::addAction(btActionInterface* action) +void btDiscreteDynamicsWorld::addAction(btActionInterface* action) { m_actions.push_back(action); } -void btDiscreteDynamicsWorld::removeAction(btActionInterface* action) +void btDiscreteDynamicsWorld::removeAction(btActionInterface* action) { m_actions.remove(action); } - -void btDiscreteDynamicsWorld::addVehicle(btActionInterface* vehicle) +void btDiscreteDynamicsWorld::addVehicle(btActionInterface* vehicle) { addAction(vehicle); } -void btDiscreteDynamicsWorld::removeVehicle(btActionInterface* vehicle) +void btDiscreteDynamicsWorld::removeVehicle(btActionInterface* vehicle) { removeAction(vehicle); } -void btDiscreteDynamicsWorld::addCharacter(btActionInterface* character) +void btDiscreteDynamicsWorld::addCharacter(btActionInterface* character) { addAction(character); } -void btDiscreteDynamicsWorld::removeCharacter(btActionInterface* character) +void btDiscreteDynamicsWorld::removeCharacter(btActionInterface* character) { removeAction(character); } - - - -void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) +void btDiscreteDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) { BT_PROFILE("solveConstraints"); - m_sortedConstraints.resize( m_constraints.size()); + m_sortedConstraints.resize(m_constraints.size()); int i; - for (i=0;isetup(&solverInfo,constraintsPtr,m_sortedConstraints.size(),getDebugDrawer()); + m_solverIslandCallback->setup(&solverInfo, constraintsPtr, m_sortedConstraints.size(), getDebugDrawer()); m_constraintSolver->prepareSolve(getCollisionWorld()->getNumCollisionObjects(), getCollisionWorld()->getDispatcher()->getNumManifolds()); /// solve all the constraints for this island - m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(),getCollisionWorld(),m_solverIslandCallback); + m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(), getCollisionWorld(), m_solverIslandCallback); m_solverIslandCallback->processConstraints(); m_constraintSolver->allSolved(solverInfo, m_debugDrawer); } - -void btDiscreteDynamicsWorld::calculateSimulationIslands() +void btDiscreteDynamicsWorld::calculateSimulationIslands() { BT_PROFILE("calculateSimulationIslands"); - getSimulationIslandManager()->updateActivationState(getCollisionWorld(),getCollisionWorld()->getDispatcher()); + getSimulationIslandManager()->updateActivationState(getCollisionWorld(), getCollisionWorld()->getDispatcher()); - { - //merge islands based on speculative contact manifolds too - for (int i=0;im_predictiveManifolds.size();i++) - { - btPersistentManifold* manifold = m_predictiveManifolds[i]; + { + //merge islands based on speculative contact manifolds too + for (int i = 0; i < this->m_predictiveManifolds.size(); i++) + { + btPersistentManifold* manifold = m_predictiveManifolds[i]; - const btCollisionObject* colObj0 = manifold->getBody0(); - const btCollisionObject* colObj1 = manifold->getBody1(); + const btCollisionObject* colObj0 = manifold->getBody0(); + const btCollisionObject* colObj1 = manifold->getBody1(); - if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) && - ((colObj1) && (!(colObj1)->isStaticOrKinematicObject()))) - { - getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag()); - } - } - } + if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) && + ((colObj1) && (!(colObj1)->isStaticOrKinematicObject()))) + { + getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(), (colObj1)->getIslandTag()); + } + } + } { int i; int numConstraints = int(m_constraints.size()); - for (i=0;i< numConstraints ; i++ ) + for (i = 0; i < numConstraints; i++) { btTypedConstraint* constraint = m_constraints[i]; if (constraint->isEnabled()) @@ -775,7 +743,7 @@ void btDiscreteDynamicsWorld::calculateSimulationIslands() if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) && ((colObj1) && (!(colObj1)->isStaticOrKinematicObject()))) { - getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag()); + getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(), (colObj1)->getIslandTag()); } } } @@ -783,51 +751,44 @@ void btDiscreteDynamicsWorld::calculateSimulationIslands() //Store the island id in each body getSimulationIslandManager()->storeIslandActivationState(getCollisionWorld()); - - } - - - class btClosestNotMeConvexResultCallback : public btCollisionWorld::ClosestConvexResultCallback { public: - btCollisionObject* m_me; btScalar m_allowedPenetration; btOverlappingPairCache* m_pairCache; btDispatcher* m_dispatcher; public: - btClosestNotMeConvexResultCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) : - btCollisionWorld::ClosestConvexResultCallback(fromA,toA), - m_me(me), - m_allowedPenetration(0.0f), - m_pairCache(pairCache), - m_dispatcher(dispatcher) + btClosestNotMeConvexResultCallback(btCollisionObject* me, const btVector3& fromA, const btVector3& toA, btOverlappingPairCache* pairCache, btDispatcher* dispatcher) : btCollisionWorld::ClosestConvexResultCallback(fromA, toA), + m_me(me), + m_allowedPenetration(0.0f), + m_pairCache(pairCache), + m_dispatcher(dispatcher) { } - virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult,bool normalInWorldSpace) + virtual btScalar addSingleResult(btCollisionWorld::LocalConvexResult& convexResult, bool normalInWorldSpace) { if (convexResult.m_hitCollisionObject == m_me) return 1.0f; //ignore result if there is no contact response - if(!convexResult.m_hitCollisionObject->hasContactResponse()) + if (!convexResult.m_hitCollisionObject->hasContactResponse()) return 1.0f; - btVector3 linVelA,linVelB; - linVelA = m_convexToWorld-m_convexFromWorld; - linVelB = btVector3(0,0,0);//toB.getOrigin()-fromB.getOrigin(); + btVector3 linVelA, linVelB; + linVelA = m_convexToWorld - m_convexFromWorld; + linVelB = btVector3(0, 0, 0); //toB.getOrigin()-fromB.getOrigin(); - btVector3 relativeVelocity = (linVelA-linVelB); + btVector3 relativeVelocity = (linVelA - linVelB); //don't report time of impact for motion away from the contact normal (or causes minor penetration) - if (convexResult.m_hitNormalLocal.dot(relativeVelocity)>=-m_allowedPenetration) + if (convexResult.m_hitNormalLocal.dot(relativeVelocity) >= -m_allowedPenetration) return 1.f; - return ClosestConvexResultCallback::addSingleResult (convexResult, normalInWorldSpace); + return ClosestConvexResultCallback::addSingleResult(convexResult, normalInWorldSpace); } virtual bool needsCollision(btBroadphaseProxy* proxy0) const @@ -840,13 +801,13 @@ public: if (!ClosestConvexResultCallback::needsCollision(proxy0)) return false; - btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject; + btCollisionObject* otherObj = (btCollisionObject*)proxy0->m_clientObject; - if(!m_dispatcher->needsCollision(m_me, otherObj)) + if (!m_dispatcher->needsCollision(m_me, otherObj)) return false; //call needsResponse, see http://code.google.com/p/bullet/issues/detail?id=179 - if (m_dispatcher->needsResponse(m_me,otherObj)) + if (m_dispatcher->needsResponse(m_me, otherObj)) { #if 0 ///don't do CCD when there are already contact points (touching contact/penetration) @@ -872,28 +833,24 @@ public: return false; } - - }; ///internal debugging variable. this value shouldn't be too high -int gNumClampedCcdMotions=0; +int gNumClampedCcdMotions = 0; - -void btDiscreteDynamicsWorld::createPredictiveContactsInternal( btRigidBody** bodies, int numBodies, btScalar timeStep) +void btDiscreteDynamicsWorld::createPredictiveContactsInternal(btRigidBody** bodies, int numBodies, btScalar timeStep) { btTransform predictedTrans; - for ( int i=0;isetHitFraction(1.f); if (body->isActive() && (!body->isStaticOrKinematicObject())) { - body->predictIntegratedTransform(timeStep, predictedTrans); - btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2(); + btScalar squareMotion = (predictedTrans.getOrigin() - body->getWorldTransform().getOrigin()).length2(); if (getDispatchInfo().m_useContinuous && body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion) { @@ -905,60 +862,55 @@ void btDiscreteDynamicsWorld::createPredictiveContactsInternal( btRigidBody** bo class StaticOnlyCallback : public btClosestNotMeConvexResultCallback { public: - - StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) : - btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher) + StaticOnlyCallback(btCollisionObject* me, const btVector3& fromA, const btVector3& toA, btOverlappingPairCache* pairCache, btDispatcher* dispatcher) : btClosestNotMeConvexResultCallback(me, fromA, toA, pairCache, dispatcher) { } - virtual bool needsCollision(btBroadphaseProxy* proxy0) const + virtual bool needsCollision(btBroadphaseProxy* proxy0) const { - btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject; + btCollisionObject* otherObj = (btCollisionObject*)proxy0->m_clientObject; if (!otherObj->isStaticOrKinematicObject()) return false; return btClosestNotMeConvexResultCallback::needsCollision(proxy0); } }; - StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher()); + StaticOnlyCallback sweepResults(body, body->getWorldTransform().getOrigin(), predictedTrans.getOrigin(), getBroadphase()->getOverlappingPairCache(), getDispatcher()); #else - btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher()); + btClosestNotMeConvexResultCallback sweepResults(body, body->getWorldTransform().getOrigin(), predictedTrans.getOrigin(), getBroadphase()->getOverlappingPairCache(), getDispatcher()); #endif //btConvexShape* convexShape = static_cast(body->getCollisionShape()); - btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast(body->getCollisionShape()); - sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration; + btSphereShape tmpSphere(body->getCcdSweptSphereRadius()); //btConvexShape* convexShape = static_cast(body->getCollisionShape()); + sweepResults.m_allowedPenetration = getDispatchInfo().m_allowedCcdPenetration; sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup; - sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask; + sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask; btTransform modifiedPredictedTrans = predictedTrans; modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis()); - convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults); + convexSweepTest(&tmpSphere, body->getWorldTransform(), modifiedPredictedTrans, sweepResults); if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f)) { - - btVector3 distVec = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin())*sweepResults.m_closestHitFraction; + btVector3 distVec = (predictedTrans.getOrigin() - body->getWorldTransform().getOrigin()) * sweepResults.m_closestHitFraction; btScalar distance = distVec.dot(-sweepResults.m_hitNormalWorld); - - btPersistentManifold* manifold = m_dispatcher1->getNewManifold(body,sweepResults.m_hitCollisionObject); - btMutexLock( &m_predictiveManifoldsMutex ); + btPersistentManifold* manifold = m_dispatcher1->getNewManifold(body, sweepResults.m_hitCollisionObject); + btMutexLock(&m_predictiveManifoldsMutex); m_predictiveManifolds.push_back(manifold); - btMutexUnlock( &m_predictiveManifoldsMutex ); + btMutexUnlock(&m_predictiveManifoldsMutex); - btVector3 worldPointB = body->getWorldTransform().getOrigin()+distVec; - btVector3 localPointB = sweepResults.m_hitCollisionObject->getWorldTransform().inverse()*worldPointB; + btVector3 worldPointB = body->getWorldTransform().getOrigin() + distVec; + btVector3 localPointB = sweepResults.m_hitCollisionObject->getWorldTransform().inverse() * worldPointB; - btManifoldPoint newPoint(btVector3(0,0,0), localPointB,sweepResults.m_hitNormalWorld,distance); + btManifoldPoint newPoint(btVector3(0, 0, 0), localPointB, sweepResults.m_hitNormalWorld, distance); bool isPredictive = true; int index = manifold->addManifoldPoint(newPoint, isPredictive); btManifoldPoint& pt = manifold->getContactPoint(index); pt.m_combinedRestitution = 0; - pt.m_combinedFriction = gCalculateCombinedFrictionCallback(body,sweepResults.m_hitCollisionObject); + pt.m_combinedFriction = gCalculateCombinedFrictionCallback(body, sweepResults.m_hitCollisionObject); pt.m_positionWorldOnA = body->getWorldTransform().getOrigin(); pt.m_positionWorldOnB = worldPointB; - } } } @@ -968,42 +920,39 @@ void btDiscreteDynamicsWorld::createPredictiveContactsInternal( btRigidBody** bo void btDiscreteDynamicsWorld::releasePredictiveContacts() { - BT_PROFILE( "release predictive contact manifolds" ); + BT_PROFILE("release predictive contact manifolds"); - for ( int i = 0; i < m_predictiveManifolds.size(); i++ ) - { - btPersistentManifold* manifold = m_predictiveManifolds[ i ]; - this->m_dispatcher1->releaseManifold( manifold ); - } - m_predictiveManifolds.clear(); + for (int i = 0; i < m_predictiveManifolds.size(); i++) + { + btPersistentManifold* manifold = m_predictiveManifolds[i]; + this->m_dispatcher1->releaseManifold(manifold); + } + m_predictiveManifolds.clear(); } void btDiscreteDynamicsWorld::createPredictiveContacts(btScalar timeStep) { BT_PROFILE("createPredictiveContacts"); - releasePredictiveContacts(); - if (m_nonStaticRigidBodies.size() > 0) - { - createPredictiveContactsInternal( &m_nonStaticRigidBodies[ 0 ], m_nonStaticRigidBodies.size(), timeStep ); - } + releasePredictiveContacts(); + if (m_nonStaticRigidBodies.size() > 0) + { + createPredictiveContactsInternal(&m_nonStaticRigidBodies[0], m_nonStaticRigidBodies.size(), timeStep); + } } -void btDiscreteDynamicsWorld::integrateTransformsInternal( btRigidBody** bodies, int numBodies, btScalar timeStep ) +void btDiscreteDynamicsWorld::integrateTransformsInternal(btRigidBody** bodies, int numBodies, btScalar timeStep) { btTransform predictedTrans; - for (int i=0;isetHitFraction(1.f); if (body->isActive() && (!body->isStaticOrKinematicObject())) { - body->predictIntegratedTransform(timeStep, predictedTrans); - btScalar squareMotion = (predictedTrans.getOrigin()-body->getWorldTransform().getOrigin()).length2(); - - + btScalar squareMotion = (predictedTrans.getOrigin() - body->getWorldTransform().getOrigin()).length2(); if (getDispatchInfo().m_useContinuous && body->getCcdSquareMotionThreshold() && body->getCcdSquareMotionThreshold() < squareMotion) { @@ -1015,43 +964,40 @@ void btDiscreteDynamicsWorld::integrateTransformsInternal( btRigidBody** bodies, class StaticOnlyCallback : public btClosestNotMeConvexResultCallback { public: - - StaticOnlyCallback (btCollisionObject* me,const btVector3& fromA,const btVector3& toA,btOverlappingPairCache* pairCache,btDispatcher* dispatcher) : - btClosestNotMeConvexResultCallback(me,fromA,toA,pairCache,dispatcher) + StaticOnlyCallback(btCollisionObject* me, const btVector3& fromA, const btVector3& toA, btOverlappingPairCache* pairCache, btDispatcher* dispatcher) : btClosestNotMeConvexResultCallback(me, fromA, toA, pairCache, dispatcher) { } - virtual bool needsCollision(btBroadphaseProxy* proxy0) const + virtual bool needsCollision(btBroadphaseProxy* proxy0) const { - btCollisionObject* otherObj = (btCollisionObject*) proxy0->m_clientObject; + btCollisionObject* otherObj = (btCollisionObject*)proxy0->m_clientObject; if (!otherObj->isStaticOrKinematicObject()) return false; return btClosestNotMeConvexResultCallback::needsCollision(proxy0); } }; - StaticOnlyCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher()); + StaticOnlyCallback sweepResults(body, body->getWorldTransform().getOrigin(), predictedTrans.getOrigin(), getBroadphase()->getOverlappingPairCache(), getDispatcher()); #else - btClosestNotMeConvexResultCallback sweepResults(body,body->getWorldTransform().getOrigin(),predictedTrans.getOrigin(),getBroadphase()->getOverlappingPairCache(),getDispatcher()); + btClosestNotMeConvexResultCallback sweepResults(body, body->getWorldTransform().getOrigin(), predictedTrans.getOrigin(), getBroadphase()->getOverlappingPairCache(), getDispatcher()); #endif //btConvexShape* convexShape = static_cast(body->getCollisionShape()); - btSphereShape tmpSphere(body->getCcdSweptSphereRadius());//btConvexShape* convexShape = static_cast(body->getCollisionShape()); - sweepResults.m_allowedPenetration=getDispatchInfo().m_allowedCcdPenetration; + btSphereShape tmpSphere(body->getCcdSweptSphereRadius()); //btConvexShape* convexShape = static_cast(body->getCollisionShape()); + sweepResults.m_allowedPenetration = getDispatchInfo().m_allowedCcdPenetration; sweepResults.m_collisionFilterGroup = body->getBroadphaseProxy()->m_collisionFilterGroup; - sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask; + sweepResults.m_collisionFilterMask = body->getBroadphaseProxy()->m_collisionFilterMask; btTransform modifiedPredictedTrans = predictedTrans; modifiedPredictedTrans.setBasis(body->getWorldTransform().getBasis()); - convexSweepTest(&tmpSphere,body->getWorldTransform(),modifiedPredictedTrans,sweepResults); + convexSweepTest(&tmpSphere, body->getWorldTransform(), modifiedPredictedTrans, sweepResults); if (sweepResults.hasHit() && (sweepResults.m_closestHitFraction < 1.f)) { - //printf("clamped integration to hit fraction = %f\n",fraction); body->setHitFraction(sweepResults.m_closestHitFraction); - body->predictIntegratedTransform(timeStep*body->getHitFraction(), predictedTrans); + body->predictIntegratedTransform(timeStep * body->getHitFraction(), predictedTrans); body->setHitFraction(0.f); - body->proceedToTransform( predictedTrans); + body->proceedToTransform(predictedTrans); #if 0 btVector3 linVel = body->getLinearVelocity(); @@ -1078,50 +1024,45 @@ void btDiscreteDynamicsWorld::integrateTransformsInternal( btRigidBody** bodies, //btScalar depth = 0.f; //appliedImpulse = resolveSingleCollision(body,(btCollisionObject*)sweepResults.m_hitCollisionObject,sweepResults.m_hitPointWorld,sweepResults.m_hitNormalWorld,getSolverInfo(), depth); - #endif - continue; + continue; } } } - - body->proceedToTransform( predictedTrans); - + body->proceedToTransform(predictedTrans); } - } - } void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep) { BT_PROFILE("integrateTransforms"); - if (m_nonStaticRigidBodies.size() > 0) - { - integrateTransformsInternal(&m_nonStaticRigidBodies[0], m_nonStaticRigidBodies.size(), timeStep); - } + if (m_nonStaticRigidBodies.size() > 0) + { + integrateTransformsInternal(&m_nonStaticRigidBodies[0], m_nonStaticRigidBodies.size(), timeStep); + } - ///this should probably be switched on by default, but it is not well tested yet + ///this should probably be switched on by default, but it is not well tested yet if (m_applySpeculativeContactRestitution) { BT_PROFILE("apply speculative contact restitution"); - for (int i=0;igetBody0()); btRigidBody* body1 = btRigidBody::upcast((btCollisionObject*)manifold->getBody1()); - for (int p=0;pgetNumContacts();p++) + for (int p = 0; p < manifold->getNumContacts(); p++) { const btManifoldPoint& pt = manifold->getContactPoint(p); btScalar combinedRestitution = gCalculateCombinedRestitutionCallback(body0, body1); - if (combinedRestitution>0 && pt.m_appliedImpulse != 0.f) + if (combinedRestitution > 0 && pt.m_appliedImpulse != 0.f) //if (pt.getDistance()>0 && combinedRestitution>0 && pt.m_appliedImpulse != 0.f) { - btVector3 imp = -pt.m_normalWorldOnB * pt.m_appliedImpulse* combinedRestitution; + btVector3 imp = -pt.m_normalWorldOnB * pt.m_appliedImpulse * combinedRestitution; const btVector3& pos1 = pt.getPositionWorldOnA(); const btVector3& pos2 = pt.getPositionWorldOnB(); @@ -1130,23 +1071,19 @@ void btDiscreteDynamicsWorld::integrateTransforms(btScalar timeStep) btVector3 rel_pos1 = pos2 - body1->getWorldTransform().getOrigin(); if (body0) - body0->applyImpulse(imp,rel_pos0); + body0->applyImpulse(imp, rel_pos0); if (body1) - body1->applyImpulse(-imp,rel_pos1); + body1->applyImpulse(-imp, rel_pos1); } } } } } - - - - -void btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) +void btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) { BT_PROFILE("predictUnconstraintMotion"); - for ( int i=0;iisStaticOrKinematicObject()) @@ -1155,179 +1092,171 @@ void btDiscreteDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) body->applyDamping(timeStep); - body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform()); + body->predictIntegratedTransform(timeStep, body->getInterpolationWorldTransform()); } } } - -void btDiscreteDynamicsWorld::startProfiling(btScalar timeStep) +void btDiscreteDynamicsWorld::startProfiling(btScalar timeStep) { (void)timeStep; #ifndef BT_NO_PROFILE CProfileManager::Reset(); -#endif //BT_NO_PROFILE - +#endif //BT_NO_PROFILE } - - - - - void btDiscreteDynamicsWorld::debugDrawConstraint(btTypedConstraint* constraint) { bool drawFrames = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraints) != 0; bool drawLimits = (getDebugDrawer()->getDebugMode() & btIDebugDraw::DBG_DrawConstraintLimits) != 0; btScalar dbgDrawSize = constraint->getDbgDrawSize(); - if(dbgDrawSize <= btScalar(0.f)) + if (dbgDrawSize <= btScalar(0.f)) { return; } - switch(constraint->getConstraintType()) + switch (constraint->getConstraintType()) { case POINT2POINT_CONSTRAINT_TYPE: - { - btPoint2PointConstraint* p2pC = (btPoint2PointConstraint*)constraint; - btTransform tr; - tr.setIdentity(); - btVector3 pivot = p2pC->getPivotInA(); - pivot = p2pC->getRigidBodyA().getCenterOfMassTransform() * pivot; - tr.setOrigin(pivot); - getDebugDrawer()->drawTransform(tr, dbgDrawSize); - // that ideally should draw the same frame - pivot = p2pC->getPivotInB(); - pivot = p2pC->getRigidBodyB().getCenterOfMassTransform() * pivot; - tr.setOrigin(pivot); - if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); - } - break; + { + btPoint2PointConstraint* p2pC = (btPoint2PointConstraint*)constraint; + btTransform tr; + tr.setIdentity(); + btVector3 pivot = p2pC->getPivotInA(); + pivot = p2pC->getRigidBodyA().getCenterOfMassTransform() * pivot; + tr.setOrigin(pivot); + getDebugDrawer()->drawTransform(tr, dbgDrawSize); + // that ideally should draw the same frame + pivot = p2pC->getPivotInB(); + pivot = p2pC->getRigidBodyB().getCenterOfMassTransform() * pivot; + tr.setOrigin(pivot); + if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); + } + break; case HINGE_CONSTRAINT_TYPE: + { + btHingeConstraint* pHinge = (btHingeConstraint*)constraint; + btTransform tr = pHinge->getRigidBodyA().getCenterOfMassTransform() * pHinge->getAFrame(); + if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); + tr = pHinge->getRigidBodyB().getCenterOfMassTransform() * pHinge->getBFrame(); + if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); + btScalar minAng = pHinge->getLowerLimit(); + btScalar maxAng = pHinge->getUpperLimit(); + if (minAng == maxAng) { - btHingeConstraint* pHinge = (btHingeConstraint*)constraint; - btTransform tr = pHinge->getRigidBodyA().getCenterOfMassTransform() * pHinge->getAFrame(); - if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); - tr = pHinge->getRigidBodyB().getCenterOfMassTransform() * pHinge->getBFrame(); - if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); - btScalar minAng = pHinge->getLowerLimit(); - btScalar maxAng = pHinge->getUpperLimit(); - if(minAng == maxAng) - { - break; - } - bool drawSect = true; - if(!pHinge->hasLimit()) - { - minAng = btScalar(0.f); - maxAng = SIMD_2_PI; - drawSect = false; - } - if(drawLimits) - { - btVector3& center = tr.getOrigin(); - btVector3 normal = tr.getBasis().getColumn(2); - btVector3 axis = tr.getBasis().getColumn(0); - getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, minAng, maxAng, btVector3(0,0,0), drawSect); - } + break; } - break; + bool drawSect = true; + if (!pHinge->hasLimit()) + { + minAng = btScalar(0.f); + maxAng = SIMD_2_PI; + drawSect = false; + } + if (drawLimits) + { + btVector3& center = tr.getOrigin(); + btVector3 normal = tr.getBasis().getColumn(2); + btVector3 axis = tr.getBasis().getColumn(0); + getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, minAng, maxAng, btVector3(0, 0, 0), drawSect); + } + } + break; case CONETWIST_CONSTRAINT_TYPE: + { + btConeTwistConstraint* pCT = (btConeTwistConstraint*)constraint; + btTransform tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame(); + if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); + tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame(); + if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); + if (drawLimits) { - btConeTwistConstraint* pCT = (btConeTwistConstraint*)constraint; - btTransform tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame(); - if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); - tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame(); - if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); - if(drawLimits) + //const btScalar length = btScalar(5); + const btScalar length = dbgDrawSize; + static int nSegments = 8 * 4; + btScalar fAngleInRadians = btScalar(2. * 3.1415926) * (btScalar)(nSegments - 1) / btScalar(nSegments); + btVector3 pPrev = pCT->GetPointForAngle(fAngleInRadians, length); + pPrev = tr * pPrev; + for (int i = 0; i < nSegments; i++) { - //const btScalar length = btScalar(5); - const btScalar length = dbgDrawSize; - static int nSegments = 8*4; - btScalar fAngleInRadians = btScalar(2.*3.1415926) * (btScalar)(nSegments-1)/btScalar(nSegments); - btVector3 pPrev = pCT->GetPointForAngle(fAngleInRadians, length); - pPrev = tr * pPrev; - for (int i=0; iGetPointForAngle(fAngleInRadians, length); - pCur = tr * pCur; - getDebugDrawer()->drawLine(pPrev, pCur, btVector3(0,0,0)); + fAngleInRadians = btScalar(2. * 3.1415926) * (btScalar)i / btScalar(nSegments); + btVector3 pCur = pCT->GetPointForAngle(fAngleInRadians, length); + pCur = tr * pCur; + getDebugDrawer()->drawLine(pPrev, pCur, btVector3(0, 0, 0)); - if (i%(nSegments/8) == 0) - getDebugDrawer()->drawLine(tr.getOrigin(), pCur, btVector3(0,0,0)); - - pPrev = pCur; - } - btScalar tws = pCT->getTwistSpan(); - btScalar twa = pCT->getTwistAngle(); - bool useFrameB = (pCT->getRigidBodyB().getInvMass() > btScalar(0.f)); - if(useFrameB) - { - tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame(); - } - else - { - tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame(); - } - btVector3 pivot = tr.getOrigin(); - btVector3 normal = tr.getBasis().getColumn(0); - btVector3 axis1 = tr.getBasis().getColumn(1); - getDebugDrawer()->drawArc(pivot, normal, axis1, dbgDrawSize, dbgDrawSize, -twa-tws, -twa+tws, btVector3(0,0,0), true); + if (i % (nSegments / 8) == 0) + getDebugDrawer()->drawLine(tr.getOrigin(), pCur, btVector3(0, 0, 0)); + pPrev = pCur; } + btScalar tws = pCT->getTwistSpan(); + btScalar twa = pCT->getTwistAngle(); + bool useFrameB = (pCT->getRigidBodyB().getInvMass() > btScalar(0.f)); + if (useFrameB) + { + tr = pCT->getRigidBodyB().getCenterOfMassTransform() * pCT->getBFrame(); + } + else + { + tr = pCT->getRigidBodyA().getCenterOfMassTransform() * pCT->getAFrame(); + } + btVector3 pivot = tr.getOrigin(); + btVector3 normal = tr.getBasis().getColumn(0); + btVector3 axis1 = tr.getBasis().getColumn(1); + getDebugDrawer()->drawArc(pivot, normal, axis1, dbgDrawSize, dbgDrawSize, -twa - tws, -twa + tws, btVector3(0, 0, 0), true); } - break; + } + break; case D6_SPRING_CONSTRAINT_TYPE: case D6_CONSTRAINT_TYPE: + { + btGeneric6DofConstraint* p6DOF = (btGeneric6DofConstraint*)constraint; + btTransform tr = p6DOF->getCalculatedTransformA(); + if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); + tr = p6DOF->getCalculatedTransformB(); + if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); + if (drawLimits) { - btGeneric6DofConstraint* p6DOF = (btGeneric6DofConstraint*)constraint; - btTransform tr = p6DOF->getCalculatedTransformA(); - if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); + tr = p6DOF->getCalculatedTransformA(); + const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin(); + btVector3 up = tr.getBasis().getColumn(2); + btVector3 axis = tr.getBasis().getColumn(0); + btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit; + btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit; + btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit; + btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit; + getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0, 0, 0)); + axis = tr.getBasis().getColumn(1); + btScalar ay = p6DOF->getAngle(1); + btScalar az = p6DOF->getAngle(2); + btScalar cy = btCos(ay); + btScalar sy = btSin(ay); + btScalar cz = btCos(az); + btScalar sz = btSin(az); + btVector3 ref; + ref[0] = cy * cz * axis[0] + cy * sz * axis[1] - sy * axis[2]; + ref[1] = -sz * axis[0] + cz * axis[1]; + ref[2] = cz * sy * axis[0] + sz * sy * axis[1] + cy * axis[2]; tr = p6DOF->getCalculatedTransformB(); - if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); - if(drawLimits) + btVector3 normal = -tr.getBasis().getColumn(0); + btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit; + btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit; + if (minFi > maxFi) { - tr = p6DOF->getCalculatedTransformA(); - const btVector3& center = p6DOF->getCalculatedTransformB().getOrigin(); - btVector3 up = tr.getBasis().getColumn(2); - btVector3 axis = tr.getBasis().getColumn(0); - btScalar minTh = p6DOF->getRotationalLimitMotor(1)->m_loLimit; - btScalar maxTh = p6DOF->getRotationalLimitMotor(1)->m_hiLimit; - btScalar minPs = p6DOF->getRotationalLimitMotor(2)->m_loLimit; - btScalar maxPs = p6DOF->getRotationalLimitMotor(2)->m_hiLimit; - getDebugDrawer()->drawSpherePatch(center, up, axis, dbgDrawSize * btScalar(.9f), minTh, maxTh, minPs, maxPs, btVector3(0,0,0)); - axis = tr.getBasis().getColumn(1); - btScalar ay = p6DOF->getAngle(1); - btScalar az = p6DOF->getAngle(2); - btScalar cy = btCos(ay); - btScalar sy = btSin(ay); - btScalar cz = btCos(az); - btScalar sz = btSin(az); - btVector3 ref; - ref[0] = cy*cz*axis[0] + cy*sz*axis[1] - sy*axis[2]; - ref[1] = -sz*axis[0] + cz*axis[1]; - ref[2] = cz*sy*axis[0] + sz*sy*axis[1] + cy*axis[2]; - tr = p6DOF->getCalculatedTransformB(); - btVector3 normal = -tr.getBasis().getColumn(0); - btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit; - btScalar maxFi = p6DOF->getRotationalLimitMotor(0)->m_hiLimit; - if(minFi > maxFi) - { - getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0,0,0), false); - } - else if(minFi < maxFi) - { - getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0,0,0), true); - } - tr = p6DOF->getCalculatedTransformA(); - btVector3 bbMin = p6DOF->getTranslationalLimitMotor()->m_lowerLimit; - btVector3 bbMax = p6DOF->getTranslationalLimitMotor()->m_upperLimit; - getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0,0,0)); + getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, -SIMD_PI, SIMD_PI, btVector3(0, 0, 0), false); } + else if (minFi < maxFi) + { + getDebugDrawer()->drawArc(center, normal, ref, dbgDrawSize, dbgDrawSize, minFi, maxFi, btVector3(0, 0, 0), true); + } + tr = p6DOF->getCalculatedTransformA(); + btVector3 bbMin = p6DOF->getTranslationalLimitMotor()->m_lowerLimit; + btVector3 bbMax = p6DOF->getTranslationalLimitMotor()->m_upperLimit; + getDebugDrawer()->drawBox(bbMin, bbMax, tr, btVector3(0, 0, 0)); } - break; + } + break; ///note: the code for D6_SPRING_2_CONSTRAINT_TYPE is identical to D6_CONSTRAINT_TYPE, the D6_CONSTRAINT_TYPE+D6_SPRING_CONSTRAINT_TYPE will likely become obsolete/deprecated at some stage case D6_SPRING_2_CONSTRAINT_TYPE: { @@ -1359,9 +1288,9 @@ void btDiscreteDynamicsWorld::debugDrawConstraint(btTypedConstraint* constraint) btScalar cz = btCos(az); btScalar sz = btSin(az); btVector3 ref; - ref[0] = cy*cz*axis[0] + cy*sz*axis[1] - sy*axis[2]; - ref[1] = -sz*axis[0] + cz*axis[1]; - ref[2] = cz*sy*axis[0] + sz*sy*axis[1] + cy*axis[2]; + ref[0] = cy * cz * axis[0] + cy * sz * axis[1] - sy * axis[2]; + ref[1] = -sz * axis[0] + cz * axis[1]; + ref[2] = cz * sy * axis[0] + sz * sy * axis[1] + cy * axis[2]; tr = p6DOF->getCalculatedTransformB(); btVector3 normal = -tr.getBasis().getColumn(0); btScalar minFi = p6DOF->getRotationalLimitMotor(0)->m_loLimit; @@ -1383,42 +1312,38 @@ void btDiscreteDynamicsWorld::debugDrawConstraint(btTypedConstraint* constraint) break; } case SLIDER_CONSTRAINT_TYPE: + { + btSliderConstraint* pSlider = (btSliderConstraint*)constraint; + btTransform tr = pSlider->getCalculatedTransformA(); + if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); + tr = pSlider->getCalculatedTransformB(); + if (drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); + if (drawLimits) { - btSliderConstraint* pSlider = (btSliderConstraint*)constraint; - btTransform tr = pSlider->getCalculatedTransformA(); - if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); - tr = pSlider->getCalculatedTransformB(); - if(drawFrames) getDebugDrawer()->drawTransform(tr, dbgDrawSize); - if(drawLimits) - { - btTransform tr = pSlider->getUseLinearReferenceFrameA() ? pSlider->getCalculatedTransformA() : pSlider->getCalculatedTransformB(); - btVector3 li_min = tr * btVector3(pSlider->getLowerLinLimit(), 0.f, 0.f); - btVector3 li_max = tr * btVector3(pSlider->getUpperLinLimit(), 0.f, 0.f); - getDebugDrawer()->drawLine(li_min, li_max, btVector3(0, 0, 0)); - btVector3 normal = tr.getBasis().getColumn(0); - btVector3 axis = tr.getBasis().getColumn(1); - btScalar a_min = pSlider->getLowerAngLimit(); - btScalar a_max = pSlider->getUpperAngLimit(); - const btVector3& center = pSlider->getCalculatedTransformB().getOrigin(); - getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, a_min, a_max, btVector3(0,0,0), true); - } + btTransform tr = pSlider->getUseLinearReferenceFrameA() ? pSlider->getCalculatedTransformA() : pSlider->getCalculatedTransformB(); + btVector3 li_min = tr * btVector3(pSlider->getLowerLinLimit(), 0.f, 0.f); + btVector3 li_max = tr * btVector3(pSlider->getUpperLinLimit(), 0.f, 0.f); + getDebugDrawer()->drawLine(li_min, li_max, btVector3(0, 0, 0)); + btVector3 normal = tr.getBasis().getColumn(0); + btVector3 axis = tr.getBasis().getColumn(1); + btScalar a_min = pSlider->getLowerAngLimit(); + btScalar a_max = pSlider->getUpperAngLimit(); + const btVector3& center = pSlider->getCalculatedTransformB().getOrigin(); + getDebugDrawer()->drawArc(center, normal, axis, dbgDrawSize, dbgDrawSize, a_min, a_max, btVector3(0, 0, 0), true); } - break; - default : + } + break; + default: break; } return; } - - - - -void btDiscreteDynamicsWorld::setConstraintSolver(btConstraintSolver* solver) +void btDiscreteDynamicsWorld::setConstraintSolver(btConstraintSolver* solver) { if (m_ownsConstraintSolver) { - btAlignedFree( m_constraintSolver); + btAlignedFree(m_constraintSolver); } m_ownsConstraintSolver = false; m_constraintSolver = solver; @@ -1430,8 +1355,7 @@ btConstraintSolver* btDiscreteDynamicsWorld::getConstraintSolver() return m_constraintSolver; } - -int btDiscreteDynamicsWorld::getNumConstraints() const +int btDiscreteDynamicsWorld::getNumConstraints() const { return int(m_constraints.size()); } @@ -1444,93 +1368,87 @@ const btTypedConstraint* btDiscreteDynamicsWorld::getConstraint(int index) const return m_constraints[index]; } - - -void btDiscreteDynamicsWorld::serializeRigidBodies(btSerializer* serializer) +void btDiscreteDynamicsWorld::serializeRigidBodies(btSerializer* serializer) { int i; //serialize all collision objects - for (i=0;igetInternalType() & btCollisionObject::CO_RIGID_BODY) { int len = colObj->calculateSerializeBufferSize(); - btChunk* chunk = serializer->allocate(len,1); + btChunk* chunk = serializer->allocate(len, 1); const char* structType = colObj->serialize(chunk->m_oldPtr, serializer); - serializer->finalizeChunk(chunk,structType,BT_RIGIDBODY_CODE,colObj); + serializer->finalizeChunk(chunk, structType, BT_RIGIDBODY_CODE, colObj); } } - for (i=0;icalculateSerializeBufferSize(); - btChunk* chunk = serializer->allocate(size,1); - const char* structType = constraint->serialize(chunk->m_oldPtr,serializer); - serializer->finalizeChunk(chunk,structType,BT_CONSTRAINT_CODE,constraint); + btChunk* chunk = serializer->allocate(size, 1); + const char* structType = constraint->serialize(chunk->m_oldPtr, serializer); + serializer->finalizeChunk(chunk, structType, BT_CONSTRAINT_CODE, constraint); } } - - - -void btDiscreteDynamicsWorld::serializeDynamicsWorldInfo(btSerializer* serializer) +void btDiscreteDynamicsWorld::serializeDynamicsWorldInfo(btSerializer* serializer) { #ifdef BT_USE_DOUBLE_PRECISION - int len = sizeof(btDynamicsWorldDoubleData); - btChunk* chunk = serializer->allocate(len,1); - btDynamicsWorldDoubleData* worldInfo = (btDynamicsWorldDoubleData*)chunk->m_oldPtr; -#else//BT_USE_DOUBLE_PRECISION - int len = sizeof(btDynamicsWorldFloatData); - btChunk* chunk = serializer->allocate(len,1); - btDynamicsWorldFloatData* worldInfo = (btDynamicsWorldFloatData*)chunk->m_oldPtr; -#endif//BT_USE_DOUBLE_PRECISION + int len = sizeof(btDynamicsWorldDoubleData); + btChunk* chunk = serializer->allocate(len, 1); + btDynamicsWorldDoubleData* worldInfo = (btDynamicsWorldDoubleData*)chunk->m_oldPtr; +#else //BT_USE_DOUBLE_PRECISION + int len = sizeof(btDynamicsWorldFloatData); + btChunk* chunk = serializer->allocate(len, 1); + btDynamicsWorldFloatData* worldInfo = (btDynamicsWorldFloatData*)chunk->m_oldPtr; +#endif //BT_USE_DOUBLE_PRECISION - memset(worldInfo ,0x00,len); + memset(worldInfo, 0x00, len); - m_gravity.serialize(worldInfo->m_gravity); - worldInfo->m_solverInfo.m_tau = getSolverInfo().m_tau; - worldInfo->m_solverInfo.m_damping = getSolverInfo().m_damping; - worldInfo->m_solverInfo.m_friction = getSolverInfo().m_friction; - worldInfo->m_solverInfo.m_timeStep = getSolverInfo().m_timeStep; + m_gravity.serialize(worldInfo->m_gravity); + worldInfo->m_solverInfo.m_tau = getSolverInfo().m_tau; + worldInfo->m_solverInfo.m_damping = getSolverInfo().m_damping; + worldInfo->m_solverInfo.m_friction = getSolverInfo().m_friction; + worldInfo->m_solverInfo.m_timeStep = getSolverInfo().m_timeStep; - worldInfo->m_solverInfo.m_restitution = getSolverInfo().m_restitution; - worldInfo->m_solverInfo.m_maxErrorReduction = getSolverInfo().m_maxErrorReduction; - worldInfo->m_solverInfo.m_sor = getSolverInfo().m_sor; - worldInfo->m_solverInfo.m_erp = getSolverInfo().m_erp; + worldInfo->m_solverInfo.m_restitution = getSolverInfo().m_restitution; + worldInfo->m_solverInfo.m_maxErrorReduction = getSolverInfo().m_maxErrorReduction; + worldInfo->m_solverInfo.m_sor = getSolverInfo().m_sor; + worldInfo->m_solverInfo.m_erp = getSolverInfo().m_erp; - worldInfo->m_solverInfo.m_erp2 = getSolverInfo().m_erp2; - worldInfo->m_solverInfo.m_globalCfm = getSolverInfo().m_globalCfm; - worldInfo->m_solverInfo.m_splitImpulsePenetrationThreshold = getSolverInfo().m_splitImpulsePenetrationThreshold; - worldInfo->m_solverInfo.m_splitImpulseTurnErp = getSolverInfo().m_splitImpulseTurnErp; + worldInfo->m_solverInfo.m_erp2 = getSolverInfo().m_erp2; + worldInfo->m_solverInfo.m_globalCfm = getSolverInfo().m_globalCfm; + worldInfo->m_solverInfo.m_splitImpulsePenetrationThreshold = getSolverInfo().m_splitImpulsePenetrationThreshold; + worldInfo->m_solverInfo.m_splitImpulseTurnErp = getSolverInfo().m_splitImpulseTurnErp; - worldInfo->m_solverInfo.m_linearSlop = getSolverInfo().m_linearSlop; - worldInfo->m_solverInfo.m_warmstartingFactor = getSolverInfo().m_warmstartingFactor; - worldInfo->m_solverInfo.m_maxGyroscopicForce = getSolverInfo().m_maxGyroscopicForce; - worldInfo->m_solverInfo.m_singleAxisRollingFrictionThreshold = getSolverInfo().m_singleAxisRollingFrictionThreshold; + worldInfo->m_solverInfo.m_linearSlop = getSolverInfo().m_linearSlop; + worldInfo->m_solverInfo.m_warmstartingFactor = getSolverInfo().m_warmstartingFactor; + worldInfo->m_solverInfo.m_maxGyroscopicForce = getSolverInfo().m_maxGyroscopicForce; + worldInfo->m_solverInfo.m_singleAxisRollingFrictionThreshold = getSolverInfo().m_singleAxisRollingFrictionThreshold; - worldInfo->m_solverInfo.m_numIterations = getSolverInfo().m_numIterations; - worldInfo->m_solverInfo.m_solverMode = getSolverInfo().m_solverMode; - worldInfo->m_solverInfo.m_restingContactRestitutionThreshold = getSolverInfo().m_restingContactRestitutionThreshold; - worldInfo->m_solverInfo.m_minimumSolverBatchSize = getSolverInfo().m_minimumSolverBatchSize; + worldInfo->m_solverInfo.m_numIterations = getSolverInfo().m_numIterations; + worldInfo->m_solverInfo.m_solverMode = getSolverInfo().m_solverMode; + worldInfo->m_solverInfo.m_restingContactRestitutionThreshold = getSolverInfo().m_restingContactRestitutionThreshold; + worldInfo->m_solverInfo.m_minimumSolverBatchSize = getSolverInfo().m_minimumSolverBatchSize; - worldInfo->m_solverInfo.m_splitImpulse = getSolverInfo().m_splitImpulse; + worldInfo->m_solverInfo.m_splitImpulse = getSolverInfo().m_splitImpulse; - // Fill padding with zeros to appease msan. - memset(worldInfo->m_solverInfo.m_padding, 0, sizeof(worldInfo->m_solverInfo.m_padding)); + // Fill padding with zeros to appease msan. + memset(worldInfo->m_solverInfo.m_padding, 0, sizeof(worldInfo->m_solverInfo.m_padding)); #ifdef BT_USE_DOUBLE_PRECISION - const char* structType = "btDynamicsWorldDoubleData"; -#else//BT_USE_DOUBLE_PRECISION - const char* structType = "btDynamicsWorldFloatData"; -#endif//BT_USE_DOUBLE_PRECISION - serializer->finalizeChunk(chunk,structType,BT_DYNAMICSWORLD_CODE,worldInfo); + const char* structType = "btDynamicsWorldDoubleData"; +#else //BT_USE_DOUBLE_PRECISION + const char* structType = "btDynamicsWorldFloatData"; +#endif //BT_USE_DOUBLE_PRECISION + serializer->finalizeChunk(chunk, structType, BT_DYNAMICSWORLD_CODE, worldInfo); } -void btDiscreteDynamicsWorld::serialize(btSerializer* serializer) +void btDiscreteDynamicsWorld::serialize(btSerializer* serializer) { - serializer->startSerialization(); serializeDynamicsWorldInfo(serializer); @@ -1543,4 +1461,3 @@ void btDiscreteDynamicsWorld::serialize(btSerializer* serializer) serializer->finishSerialization(); } - diff --git a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h index b0d19f48a..7fe961921 100644 --- a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h +++ b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef BT_DISCRETE_DYNAMICS_WORLD_H #define BT_DISCRETE_DYNAMICS_WORLD_H @@ -32,159 +31,153 @@ struct InplaceSolverIslandCallback; #include "LinearMath/btAlignedObjectArray.h" #include "LinearMath/btThreads.h" - ///btDiscreteDynamicsWorld provides discrete rigid body simulation ///those classes replace the obsolete CcdPhysicsEnvironment/CcdPhysicsController -ATTRIBUTE_ALIGNED16(class) btDiscreteDynamicsWorld : public btDynamicsWorld +ATTRIBUTE_ALIGNED16(class) +btDiscreteDynamicsWorld : public btDynamicsWorld { protected: - - btAlignedObjectArray m_sortedConstraints; - InplaceSolverIslandCallback* m_solverIslandCallback; + btAlignedObjectArray m_sortedConstraints; + InplaceSolverIslandCallback* m_solverIslandCallback; - btConstraintSolver* m_constraintSolver; + btConstraintSolver* m_constraintSolver; - btSimulationIslandManager* m_islandManager; + btSimulationIslandManager* m_islandManager; btAlignedObjectArray m_constraints; btAlignedObjectArray m_nonStaticRigidBodies; - btVector3 m_gravity; + btVector3 m_gravity; //for variable timesteps - btScalar m_localTime; - btScalar m_fixedTimeStep; + btScalar m_localTime; + btScalar m_fixedTimeStep; //for variable timesteps - bool m_ownsIslandManager; - bool m_ownsConstraintSolver; - bool m_synchronizeAllMotionStates; - bool m_applySpeculativeContactRestitution; + bool m_ownsIslandManager; + bool m_ownsConstraintSolver; + bool m_synchronizeAllMotionStates; + bool m_applySpeculativeContactRestitution; - btAlignedObjectArray m_actions; - - int m_profileTimings; + btAlignedObjectArray m_actions; - bool m_latencyMotionStateInterpolation; + int m_profileTimings; - btAlignedObjectArray m_predictiveManifolds; - btSpinMutex m_predictiveManifoldsMutex; // used to synchronize threads creating predictive contacts + bool m_latencyMotionStateInterpolation; - virtual void predictUnconstraintMotion(btScalar timeStep); - - void integrateTransformsInternal( btRigidBody** bodies, int numBodies, btScalar timeStep ); // can be called in parallel - virtual void integrateTransforms(btScalar timeStep); - - virtual void calculateSimulationIslands(); + btAlignedObjectArray m_predictiveManifolds; + btSpinMutex m_predictiveManifoldsMutex; // used to synchronize threads creating predictive contacts - virtual void solveConstraints(btContactSolverInfo& solverInfo); - - virtual void updateActivationState(btScalar timeStep); + virtual void predictUnconstraintMotion(btScalar timeStep); - void updateActions(btScalar timeStep); + void integrateTransformsInternal(btRigidBody * *bodies, int numBodies, btScalar timeStep); // can be called in parallel + virtual void integrateTransforms(btScalar timeStep); - void startProfiling(btScalar timeStep); + virtual void calculateSimulationIslands(); - virtual void internalSingleStepSimulation( btScalar timeStep); + virtual void solveConstraints(btContactSolverInfo & solverInfo); - void releasePredictiveContacts(); - void createPredictiveContactsInternal( btRigidBody** bodies, int numBodies, btScalar timeStep ); // can be called in parallel - virtual void createPredictiveContacts(btScalar timeStep); + virtual void updateActivationState(btScalar timeStep); - virtual void saveKinematicState(btScalar timeStep); + void updateActions(btScalar timeStep); - void serializeRigidBodies(btSerializer* serializer); + void startProfiling(btScalar timeStep); - void serializeDynamicsWorldInfo(btSerializer* serializer); + virtual void internalSingleStepSimulation(btScalar timeStep); + + void releasePredictiveContacts(); + void createPredictiveContactsInternal(btRigidBody * *bodies, int numBodies, btScalar timeStep); // can be called in parallel + virtual void createPredictiveContacts(btScalar timeStep); + + virtual void saveKinematicState(btScalar timeStep); + + void serializeRigidBodies(btSerializer * serializer); + + void serializeDynamicsWorldInfo(btSerializer * serializer); public: - - BT_DECLARE_ALIGNED_ALLOCATOR(); ///this btDiscreteDynamicsWorld constructor gets created objects from the user, and will not delete those - btDiscreteDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration); + btDiscreteDynamicsWorld(btDispatcher * dispatcher, btBroadphaseInterface * pairCache, btConstraintSolver * constraintSolver, btCollisionConfiguration * collisionConfiguration); virtual ~btDiscreteDynamicsWorld(); ///if maxSubSteps > 0, it will interpolate motion between fixedTimeStep's - virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.)); + virtual int stepSimulation(btScalar timeStep, int maxSubSteps = 1, btScalar fixedTimeStep = btScalar(1.) / btScalar(60.)); - - virtual void synchronizeMotionStates(); + virtual void synchronizeMotionStates(); ///this can be useful to synchronize a single rigid body -> graphics object - void synchronizeSingleMotionState(btRigidBody* body); + void synchronizeSingleMotionState(btRigidBody * body); - virtual void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false); + virtual void addConstraint(btTypedConstraint * constraint, bool disableCollisionsBetweenLinkedBodies = false); - virtual void removeConstraint(btTypedConstraint* constraint); + virtual void removeConstraint(btTypedConstraint * constraint); - virtual void addAction(btActionInterface*); + virtual void addAction(btActionInterface*); - virtual void removeAction(btActionInterface*); - - btSimulationIslandManager* getSimulationIslandManager() + virtual void removeAction(btActionInterface*); + + btSimulationIslandManager* getSimulationIslandManager() { return m_islandManager; } - const btSimulationIslandManager* getSimulationIslandManager() const + const btSimulationIslandManager* getSimulationIslandManager() const { return m_islandManager; } - btCollisionWorld* getCollisionWorld() + btCollisionWorld* getCollisionWorld() { return this; } - virtual void setGravity(const btVector3& gravity); + virtual void setGravity(const btVector3& gravity); - virtual btVector3 getGravity () const; + virtual btVector3 getGravity() const; - virtual void addCollisionObject(btCollisionObject* collisionObject, int collisionFilterGroup=btBroadphaseProxy::StaticFilter, int collisionFilterMask=btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter); + virtual void addCollisionObject(btCollisionObject * collisionObject, int collisionFilterGroup = btBroadphaseProxy::StaticFilter, int collisionFilterMask = btBroadphaseProxy::AllFilter ^ btBroadphaseProxy::StaticFilter); - virtual void addRigidBody(btRigidBody* body); + virtual void addRigidBody(btRigidBody * body); - virtual void addRigidBody(btRigidBody* body, int group, int mask); + virtual void addRigidBody(btRigidBody * body, int group, int mask); - virtual void removeRigidBody(btRigidBody* body); + virtual void removeRigidBody(btRigidBody * body); ///removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise call btCollisionWorld::removeCollisionObject - virtual void removeCollisionObject(btCollisionObject* collisionObject); + virtual void removeCollisionObject(btCollisionObject * collisionObject); + virtual void debugDrawConstraint(btTypedConstraint * constraint); - virtual void debugDrawConstraint(btTypedConstraint* constraint); + virtual void debugDrawWorld(); - virtual void debugDrawWorld(); - - virtual void setConstraintSolver(btConstraintSolver* solver); + virtual void setConstraintSolver(btConstraintSolver * solver); virtual btConstraintSolver* getConstraintSolver(); - - virtual int getNumConstraints() const; - virtual btTypedConstraint* getConstraint(int index) ; + virtual int getNumConstraints() const; + + virtual btTypedConstraint* getConstraint(int index); virtual const btTypedConstraint* getConstraint(int index) const; - - virtual btDynamicsWorldType getWorldType() const + virtual btDynamicsWorldType getWorldType() const { return BT_DISCRETE_DYNAMICS_WORLD; } - + ///the forces on each rigidbody is accumulating together with gravity. clear this after each timestep. - virtual void clearForces(); + virtual void clearForces(); ///apply gravity, call this once per timestep - virtual void applyGravity(); + virtual void applyGravity(); - virtual void setNumTasks(int numTasks) + virtual void setNumTasks(int numTasks) { - (void) numTasks; + (void)numTasks; } ///obsolete, use updateActions instead @@ -194,15 +187,15 @@ public: } ///obsolete, use addAction instead - virtual void addVehicle(btActionInterface* vehicle); + virtual void addVehicle(btActionInterface * vehicle); ///obsolete, use removeAction instead - virtual void removeVehicle(btActionInterface* vehicle); + virtual void removeVehicle(btActionInterface * vehicle); ///obsolete, use addAction instead - virtual void addCharacter(btActionInterface* character); + virtual void addCharacter(btActionInterface * character); ///obsolete, use removeAction instead - virtual void removeCharacter(btActionInterface* character); + virtual void removeCharacter(btActionInterface * character); - void setSynchronizeAllMotionStates(bool synchronizeAll) + void setSynchronizeAllMotionStates(bool synchronizeAll) { m_synchronizeAllMotionStates = synchronizeAll; } @@ -215,18 +208,18 @@ public: { m_applySpeculativeContactRestitution = enable; } - + bool getApplySpeculativeContactRestitution() const { return m_applySpeculativeContactRestitution; } ///Preliminary serialization test for Bullet 2.76. Loading those files requires a separate parser (see Bullet/Demos/SerializeDemo) - virtual void serialize(btSerializer* serializer); + virtual void serialize(btSerializer * serializer); ///Interpolate motion state between previous and current transform, instead of current and next transform. ///This can relieve discontinuities in the rendering, due to penetrations - void setLatencyMotionStateInterpolation(bool latencyInterpolation ) + void setLatencyMotionStateInterpolation(bool latencyInterpolation) { m_latencyMotionStateInterpolation = latencyInterpolation; } @@ -236,4 +229,4 @@ public: } }; -#endif //BT_DISCRETE_DYNAMICS_WORLD_H +#endif //BT_DISCRETE_DYNAMICS_WORLD_H diff --git a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorldMt.cpp b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorldMt.cpp index d705bf238..d5805ad9b 100644 --- a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorldMt.cpp +++ b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorldMt.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btDiscreteDynamicsWorldMt.h" //collision detection @@ -38,148 +37,139 @@ subject to the following restrictions: #include "BulletDynamics/ConstraintSolver/btSliderConstraint.h" #include "BulletDynamics/ConstraintSolver/btContactConstraint.h" - #include "LinearMath/btIDebugDraw.h" #include "BulletCollision/CollisionShapes/btSphereShape.h" - #include "BulletDynamics/Dynamics/btActionInterface.h" #include "LinearMath/btQuickprof.h" #include "LinearMath/btMotionState.h" #include "LinearMath/btSerializer.h" - - /// /// btConstraintSolverPoolMt /// btConstraintSolverPoolMt::ThreadSolver* btConstraintSolverPoolMt::getAndLockThreadSolver() { - int i = 0; + int i = 0; #if BT_THREADSAFE - i = btGetCurrentThreadIndex() % m_solvers.size(); -#endif // #if BT_THREADSAFE - while ( true ) - { - ThreadSolver& solver = m_solvers[ i ]; - if ( solver.mutex.tryLock() ) - { - return &solver; - } - // failed, try the next one - i = ( i + 1 ) % m_solvers.size(); - } - return NULL; + i = btGetCurrentThreadIndex() % m_solvers.size(); +#endif // #if BT_THREADSAFE + while (true) + { + ThreadSolver& solver = m_solvers[i]; + if (solver.mutex.tryLock()) + { + return &solver; + } + // failed, try the next one + i = (i + 1) % m_solvers.size(); + } + return NULL; } -void btConstraintSolverPoolMt::init( btConstraintSolver** solvers, int numSolvers ) +void btConstraintSolverPoolMt::init(btConstraintSolver** solvers, int numSolvers) { - m_solverType = BT_SEQUENTIAL_IMPULSE_SOLVER; - m_solvers.resize( numSolvers ); - for ( int i = 0; i < numSolvers; ++i ) - { - m_solvers[ i ].solver = solvers[ i ]; - } - if ( numSolvers > 0 ) - { - m_solverType = solvers[ 0 ]->getSolverType(); - } + m_solverType = BT_SEQUENTIAL_IMPULSE_SOLVER; + m_solvers.resize(numSolvers); + for (int i = 0; i < numSolvers; ++i) + { + m_solvers[i].solver = solvers[i]; + } + if (numSolvers > 0) + { + m_solverType = solvers[0]->getSolverType(); + } } // create the solvers for me -btConstraintSolverPoolMt::btConstraintSolverPoolMt( int numSolvers ) +btConstraintSolverPoolMt::btConstraintSolverPoolMt(int numSolvers) { - btAlignedObjectArray solvers; - solvers.reserve( numSolvers ); - for ( int i = 0; i < numSolvers; ++i ) - { - btConstraintSolver* solver = new btSequentialImpulseConstraintSolver(); - solvers.push_back( solver ); - } - init( &solvers[ 0 ], numSolvers ); + btAlignedObjectArray solvers; + solvers.reserve(numSolvers); + for (int i = 0; i < numSolvers; ++i) + { + btConstraintSolver* solver = new btSequentialImpulseConstraintSolver(); + solvers.push_back(solver); + } + init(&solvers[0], numSolvers); } // pass in fully constructed solvers (destructor will delete them) -btConstraintSolverPoolMt::btConstraintSolverPoolMt( btConstraintSolver** solvers, int numSolvers ) +btConstraintSolverPoolMt::btConstraintSolverPoolMt(btConstraintSolver** solvers, int numSolvers) { - init( solvers, numSolvers ); + init(solvers, numSolvers); } btConstraintSolverPoolMt::~btConstraintSolverPoolMt() { - // delete all solvers - for ( int i = 0; i < m_solvers.size(); ++i ) - { - ThreadSolver& solver = m_solvers[ i ]; - delete solver.solver; - solver.solver = NULL; - } + // delete all solvers + for (int i = 0; i < m_solvers.size(); ++i) + { + ThreadSolver& solver = m_solvers[i]; + delete solver.solver; + solver.solver = NULL; + } } ///solve a group of constraints -btScalar btConstraintSolverPoolMt::solveGroup( btCollisionObject** bodies, - int numBodies, - btPersistentManifold** manifolds, - int numManifolds, - btTypedConstraint** constraints, - int numConstraints, - const btContactSolverInfo& info, - btIDebugDraw* debugDrawer, - btDispatcher* dispatcher -) +btScalar btConstraintSolverPoolMt::solveGroup(btCollisionObject** bodies, + int numBodies, + btPersistentManifold** manifolds, + int numManifolds, + btTypedConstraint** constraints, + int numConstraints, + const btContactSolverInfo& info, + btIDebugDraw* debugDrawer, + btDispatcher* dispatcher) { - ThreadSolver* ts = getAndLockThreadSolver(); - ts->solver->solveGroup( bodies, numBodies, manifolds, numManifolds, constraints, numConstraints, info, debugDrawer, dispatcher ); - ts->mutex.unlock(); - return 0.0f; + ThreadSolver* ts = getAndLockThreadSolver(); + ts->solver->solveGroup(bodies, numBodies, manifolds, numManifolds, constraints, numConstraints, info, debugDrawer, dispatcher); + ts->mutex.unlock(); + return 0.0f; } void btConstraintSolverPoolMt::reset() { - for ( int i = 0; i < m_solvers.size(); ++i ) - { - ThreadSolver& solver = m_solvers[ i ]; - solver.mutex.lock(); - solver.solver->reset(); - solver.mutex.unlock(); - } + for (int i = 0; i < m_solvers.size(); ++i) + { + ThreadSolver& solver = m_solvers[i]; + solver.mutex.lock(); + solver.solver->reset(); + solver.mutex.unlock(); + } } - /// /// btDiscreteDynamicsWorldMt /// btDiscreteDynamicsWorldMt::btDiscreteDynamicsWorldMt(btDispatcher* dispatcher, - btBroadphaseInterface* pairCache, - btConstraintSolverPoolMt* constraintSolver, - btConstraintSolver* constraintSolverMt, - btCollisionConfiguration* collisionConfiguration -) -: btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration) + btBroadphaseInterface* pairCache, + btConstraintSolverPoolMt* constraintSolver, + btConstraintSolver* constraintSolverMt, + btCollisionConfiguration* collisionConfiguration) + : btDiscreteDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration) { if (m_ownsIslandManager) { m_islandManager->~btSimulationIslandManager(); - btAlignedFree( m_islandManager); + btAlignedFree(m_islandManager); } { - void* mem = btAlignedAlloc(sizeof(btSimulationIslandManagerMt),16); + void* mem = btAlignedAlloc(sizeof(btSimulationIslandManagerMt), 16); btSimulationIslandManagerMt* im = new (mem) btSimulationIslandManagerMt(); - im->setMinimumSolverBatchSize( m_solverInfo.m_minimumSolverBatchSize ); - m_islandManager = im; + im->setMinimumSolverBatchSize(m_solverInfo.m_minimumSolverBatchSize); + m_islandManager = im; } - m_constraintSolverMt = constraintSolverMt; + m_constraintSolverMt = constraintSolverMt; } - btDiscreteDynamicsWorldMt::~btDiscreteDynamicsWorldMt() { } - void btDiscreteDynamicsWorldMt::solveConstraints(btContactSolverInfo& solverInfo) { BT_PROFILE("solveConstraints"); @@ -187,92 +177,87 @@ void btDiscreteDynamicsWorldMt::solveConstraints(btContactSolverInfo& solverInfo m_constraintSolver->prepareSolve(getCollisionWorld()->getNumCollisionObjects(), getCollisionWorld()->getDispatcher()->getNumManifolds()); /// solve all the constraints for this island - btSimulationIslandManagerMt* im = static_cast(m_islandManager); - btSimulationIslandManagerMt::SolverParams solverParams; - solverParams.m_solverPool = m_constraintSolver; - solverParams.m_solverMt = m_constraintSolverMt; - solverParams.m_solverInfo = &solverInfo; - solverParams.m_debugDrawer = m_debugDrawer; - solverParams.m_dispatcher = getCollisionWorld()->getDispatcher(); - im->buildAndProcessIslands( getCollisionWorld()->getDispatcher(), getCollisionWorld(), m_constraints, solverParams ); + btSimulationIslandManagerMt* im = static_cast(m_islandManager); + btSimulationIslandManagerMt::SolverParams solverParams; + solverParams.m_solverPool = m_constraintSolver; + solverParams.m_solverMt = m_constraintSolverMt; + solverParams.m_solverInfo = &solverInfo; + solverParams.m_debugDrawer = m_debugDrawer; + solverParams.m_dispatcher = getCollisionWorld()->getDispatcher(); + im->buildAndProcessIslands(getCollisionWorld()->getDispatcher(), getCollisionWorld(), m_constraints, solverParams); m_constraintSolver->allSolved(solverInfo, m_debugDrawer); } - struct UpdaterUnconstrainedMotion : public btIParallelForBody { - btScalar timeStep; - btRigidBody** rigidBodies; + btScalar timeStep; + btRigidBody** rigidBodies; - void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - for ( int i = iBegin; i < iEnd; ++i ) - { - btRigidBody* body = rigidBodies[ i ]; - if ( !body->isStaticOrKinematicObject() ) - { - //don't integrate/update velocities here, it happens in the constraint solver - body->applyDamping( timeStep ); - body->predictIntegratedTransform( timeStep, body->getInterpolationWorldTransform() ); - } - } - } + void forLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + for (int i = iBegin; i < iEnd; ++i) + { + btRigidBody* body = rigidBodies[i]; + if (!body->isStaticOrKinematicObject()) + { + //don't integrate/update velocities here, it happens in the constraint solver + body->applyDamping(timeStep); + body->predictIntegratedTransform(timeStep, body->getInterpolationWorldTransform()); + } + } + } }; - -void btDiscreteDynamicsWorldMt::predictUnconstraintMotion( btScalar timeStep ) +void btDiscreteDynamicsWorldMt::predictUnconstraintMotion(btScalar timeStep) { - BT_PROFILE( "predictUnconstraintMotion" ); - if ( m_nonStaticRigidBodies.size() > 0 ) - { - UpdaterUnconstrainedMotion update; - update.timeStep = timeStep; - update.rigidBodies = &m_nonStaticRigidBodies[ 0 ]; - int grainSize = 50; // num of iterations per task for task scheduler - btParallelFor( 0, m_nonStaticRigidBodies.size(), grainSize, update ); - } + BT_PROFILE("predictUnconstraintMotion"); + if (m_nonStaticRigidBodies.size() > 0) + { + UpdaterUnconstrainedMotion update; + update.timeStep = timeStep; + update.rigidBodies = &m_nonStaticRigidBodies[0]; + int grainSize = 50; // num of iterations per task for task scheduler + btParallelFor(0, m_nonStaticRigidBodies.size(), grainSize, update); + } } - -void btDiscreteDynamicsWorldMt::createPredictiveContacts( btScalar timeStep ) +void btDiscreteDynamicsWorldMt::createPredictiveContacts(btScalar timeStep) { - BT_PROFILE( "createPredictiveContacts" ); - releasePredictiveContacts(); - if ( m_nonStaticRigidBodies.size() > 0 ) - { - UpdaterCreatePredictiveContacts update; - update.world = this; - update.timeStep = timeStep; - update.rigidBodies = &m_nonStaticRigidBodies[ 0 ]; - int grainSize = 50; // num of iterations per task for task scheduler - btParallelFor( 0, m_nonStaticRigidBodies.size(), grainSize, update ); - } + BT_PROFILE("createPredictiveContacts"); + releasePredictiveContacts(); + if (m_nonStaticRigidBodies.size() > 0) + { + UpdaterCreatePredictiveContacts update; + update.world = this; + update.timeStep = timeStep; + update.rigidBodies = &m_nonStaticRigidBodies[0]; + int grainSize = 50; // num of iterations per task for task scheduler + btParallelFor(0, m_nonStaticRigidBodies.size(), grainSize, update); + } } - -void btDiscreteDynamicsWorldMt::integrateTransforms( btScalar timeStep ) +void btDiscreteDynamicsWorldMt::integrateTransforms(btScalar timeStep) { - BT_PROFILE( "integrateTransforms" ); - if ( m_nonStaticRigidBodies.size() > 0 ) - { - UpdaterIntegrateTransforms update; - update.world = this; - update.timeStep = timeStep; - update.rigidBodies = &m_nonStaticRigidBodies[ 0 ]; - int grainSize = 50; // num of iterations per task for task scheduler - btParallelFor( 0, m_nonStaticRigidBodies.size(), grainSize, update ); - } + BT_PROFILE("integrateTransforms"); + if (m_nonStaticRigidBodies.size() > 0) + { + UpdaterIntegrateTransforms update; + update.world = this; + update.timeStep = timeStep; + update.rigidBodies = &m_nonStaticRigidBodies[0]; + int grainSize = 50; // num of iterations per task for task scheduler + btParallelFor(0, m_nonStaticRigidBodies.size(), grainSize, update); + } } - -int btDiscreteDynamicsWorldMt::stepSimulation( btScalar timeStep, int maxSubSteps, btScalar fixedTimeStep ) +int btDiscreteDynamicsWorldMt::stepSimulation(btScalar timeStep, int maxSubSteps, btScalar fixedTimeStep) { - int numSubSteps = btDiscreteDynamicsWorld::stepSimulation(timeStep, maxSubSteps, fixedTimeStep); - if (btITaskScheduler* scheduler = btGetTaskScheduler()) - { - // tell Bullet's threads to sleep, so other threads can run - scheduler->sleepWorkerThreadsHint(); - } - return numSubSteps; + int numSubSteps = btDiscreteDynamicsWorld::stepSimulation(timeStep, maxSubSteps, fixedTimeStep); + if (btITaskScheduler* scheduler = btGetTaskScheduler()) + { + // tell Bullet's threads to sleep, so other threads can run + scheduler->sleepWorkerThreadsHint(); + } + return numSubSteps; } diff --git a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorldMt.h b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorldMt.h index 667fe5800..58d808923 100644 --- a/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorldMt.h +++ b/src/BulletDynamics/Dynamics/btDiscreteDynamicsWorldMt.h @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef BT_DISCRETE_DYNAMICS_WORLD_MT_H #define BT_DISCRETE_DYNAMICS_WORLD_MT_H @@ -21,7 +20,6 @@ subject to the following restrictions: #include "btSimulationIslandManagerMt.h" #include "BulletDynamics/ConstraintSolver/btConstraintSolver.h" - /// /// btConstraintSolverPoolMt - masquerades as a constraint solver, but really it is a threadsafe pool of them. /// @@ -34,46 +32,43 @@ subject to the following restrictions: class btConstraintSolverPoolMt : public btConstraintSolver { public: - // create the solvers for me - explicit btConstraintSolverPoolMt( int numSolvers ); + // create the solvers for me + explicit btConstraintSolverPoolMt(int numSolvers); - // pass in fully constructed solvers (destructor will delete them) - btConstraintSolverPoolMt( btConstraintSolver** solvers, int numSolvers ); + // pass in fully constructed solvers (destructor will delete them) + btConstraintSolverPoolMt(btConstraintSolver** solvers, int numSolvers); - virtual ~btConstraintSolverPoolMt(); + virtual ~btConstraintSolverPoolMt(); - ///solve a group of constraints - virtual btScalar solveGroup( btCollisionObject** bodies, - int numBodies, - btPersistentManifold** manifolds, - int numManifolds, - btTypedConstraint** constraints, - int numConstraints, - const btContactSolverInfo& info, - btIDebugDraw* debugDrawer, - btDispatcher* dispatcher - ) BT_OVERRIDE; + ///solve a group of constraints + virtual btScalar solveGroup(btCollisionObject** bodies, + int numBodies, + btPersistentManifold** manifolds, + int numManifolds, + btTypedConstraint** constraints, + int numConstraints, + const btContactSolverInfo& info, + btIDebugDraw* debugDrawer, + btDispatcher* dispatcher) BT_OVERRIDE; - virtual void reset() BT_OVERRIDE; - virtual btConstraintSolverType getSolverType() const BT_OVERRIDE { return m_solverType; } + virtual void reset() BT_OVERRIDE; + virtual btConstraintSolverType getSolverType() const BT_OVERRIDE { return m_solverType; } private: - const static size_t kCacheLineSize = 128; - struct ThreadSolver - { - btConstraintSolver* solver; - btSpinMutex mutex; - char _cachelinePadding[ kCacheLineSize - sizeof( btSpinMutex ) - sizeof( void* ) ]; // keep mutexes from sharing a cache line - }; - btAlignedObjectArray m_solvers; - btConstraintSolverType m_solverType; + const static size_t kCacheLineSize = 128; + struct ThreadSolver + { + btConstraintSolver* solver; + btSpinMutex mutex; + char _cachelinePadding[kCacheLineSize - sizeof(btSpinMutex) - sizeof(void*)]; // keep mutexes from sharing a cache line + }; + btAlignedObjectArray m_solvers; + btConstraintSolverType m_solverType; - ThreadSolver* getAndLockThreadSolver(); - void init( btConstraintSolver** solvers, int numSolvers ); + ThreadSolver* getAndLockThreadSolver(); + void init(btConstraintSolver** solvers, int numSolvers); }; - - /// /// btDiscreteDynamicsWorldMt -- a version of DiscreteDynamicsWorld with some minor changes to support /// solving simulation islands on multiple threads. @@ -84,53 +79,53 @@ private: /// - integrateTransforms /// - createPredictiveContacts /// -ATTRIBUTE_ALIGNED16(class) btDiscreteDynamicsWorldMt : public btDiscreteDynamicsWorld +ATTRIBUTE_ALIGNED16(class) +btDiscreteDynamicsWorldMt : public btDiscreteDynamicsWorld { protected: - btConstraintSolver* m_constraintSolverMt; + btConstraintSolver* m_constraintSolverMt; - virtual void solveConstraints(btContactSolverInfo& solverInfo) BT_OVERRIDE; + virtual void solveConstraints(btContactSolverInfo & solverInfo) BT_OVERRIDE; - virtual void predictUnconstraintMotion( btScalar timeStep ) BT_OVERRIDE; + virtual void predictUnconstraintMotion(btScalar timeStep) BT_OVERRIDE; - struct UpdaterCreatePredictiveContacts : public btIParallelForBody - { - btScalar timeStep; - btRigidBody** rigidBodies; - btDiscreteDynamicsWorldMt* world; + struct UpdaterCreatePredictiveContacts : public btIParallelForBody + { + btScalar timeStep; + btRigidBody** rigidBodies; + btDiscreteDynamicsWorldMt* world; - void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - world->createPredictiveContactsInternal( &rigidBodies[ iBegin ], iEnd - iBegin, timeStep ); - } - }; - virtual void createPredictiveContacts( btScalar timeStep ) BT_OVERRIDE; + void forLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + world->createPredictiveContactsInternal(&rigidBodies[iBegin], iEnd - iBegin, timeStep); + } + }; + virtual void createPredictiveContacts(btScalar timeStep) BT_OVERRIDE; - struct UpdaterIntegrateTransforms : public btIParallelForBody - { - btScalar timeStep; - btRigidBody** rigidBodies; - btDiscreteDynamicsWorldMt* world; + struct UpdaterIntegrateTransforms : public btIParallelForBody + { + btScalar timeStep; + btRigidBody** rigidBodies; + btDiscreteDynamicsWorldMt* world; - void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - world->integrateTransformsInternal( &rigidBodies[ iBegin ], iEnd - iBegin, timeStep ); - } - }; - virtual void integrateTransforms( btScalar timeStep ) BT_OVERRIDE; + void forLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + world->integrateTransformsInternal(&rigidBodies[iBegin], iEnd - iBegin, timeStep); + } + }; + virtual void integrateTransforms(btScalar timeStep) BT_OVERRIDE; public: BT_DECLARE_ALIGNED_ALLOCATOR(); - btDiscreteDynamicsWorldMt(btDispatcher* dispatcher, - btBroadphaseInterface* pairCache, - btConstraintSolverPoolMt* constraintSolver, // Note this should be a solver-pool for multi-threading - btConstraintSolver* constraintSolverMt, // single multi-threaded solver for large islands (or NULL) - btCollisionConfiguration* collisionConfiguration - ); + btDiscreteDynamicsWorldMt(btDispatcher * dispatcher, + btBroadphaseInterface * pairCache, + btConstraintSolverPoolMt * constraintSolver, // Note this should be a solver-pool for multi-threading + btConstraintSolver * constraintSolverMt, // single multi-threaded solver for large islands (or NULL) + btCollisionConfiguration * collisionConfiguration); virtual ~btDiscreteDynamicsWorldMt(); - virtual int stepSimulation( btScalar timeStep, int maxSubSteps, btScalar fixedTimeStep ) BT_OVERRIDE; + virtual int stepSimulation(btScalar timeStep, int maxSubSteps, btScalar fixedTimeStep) BT_OVERRIDE; }; -#endif //BT_DISCRETE_DYNAMICS_WORLD_H +#endif //BT_DISCRETE_DYNAMICS_WORLD_H diff --git a/src/BulletDynamics/Dynamics/btDynamicsWorld.h b/src/BulletDynamics/Dynamics/btDynamicsWorld.h index 42d8fc0de..eadd8c12e 100644 --- a/src/BulletDynamics/Dynamics/btDynamicsWorld.h +++ b/src/BulletDynamics/Dynamics/btDynamicsWorld.h @@ -24,150 +24,150 @@ class btActionInterface; class btConstraintSolver; class btDynamicsWorld; - /// Type for the callback for each tick -typedef void (*btInternalTickCallback)(btDynamicsWorld *world, btScalar timeStep); +typedef void (*btInternalTickCallback)(btDynamicsWorld* world, btScalar timeStep); enum btDynamicsWorldType { - BT_SIMPLE_DYNAMICS_WORLD=1, - BT_DISCRETE_DYNAMICS_WORLD=2, - BT_CONTINUOUS_DYNAMICS_WORLD=3, - BT_SOFT_RIGID_DYNAMICS_WORLD=4, - BT_GPU_DYNAMICS_WORLD=5, - BT_SOFT_MULTIBODY_DYNAMICS_WORLD=6 + BT_SIMPLE_DYNAMICS_WORLD = 1, + BT_DISCRETE_DYNAMICS_WORLD = 2, + BT_CONTINUOUS_DYNAMICS_WORLD = 3, + BT_SOFT_RIGID_DYNAMICS_WORLD = 4, + BT_GPU_DYNAMICS_WORLD = 5, + BT_SOFT_MULTIBODY_DYNAMICS_WORLD = 6 }; ///The btDynamicsWorld is the interface class for several dynamics implementation, basic, discrete, parallel, and continuous etc. class btDynamicsWorld : public btCollisionWorld { - protected: - btInternalTickCallback m_internalTickCallback; - btInternalTickCallback m_internalPreTickCallback; - void* m_worldUserInfo; + btInternalTickCallback m_internalTickCallback; + btInternalTickCallback m_internalPreTickCallback; + void* m_worldUserInfo; - btContactSolverInfo m_solverInfo; + btContactSolverInfo m_solverInfo; public: - + btDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* broadphase, btCollisionConfiguration* collisionConfiguration) + : btCollisionWorld(dispatcher, broadphase, collisionConfiguration), m_internalTickCallback(0), m_internalPreTickCallback(0), m_worldUserInfo(0) + { + } - btDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* broadphase,btCollisionConfiguration* collisionConfiguration) - :btCollisionWorld(dispatcher,broadphase,collisionConfiguration), m_internalTickCallback(0),m_internalPreTickCallback(0), m_worldUserInfo(0) + virtual ~btDynamicsWorld() + { + } + + ///stepSimulation proceeds the simulation over 'timeStep', units in preferably in seconds. + ///By default, Bullet will subdivide the timestep in constant substeps of each 'fixedTimeStep'. + ///in order to keep the simulation real-time, the maximum number of substeps can be clamped to 'maxSubSteps'. + ///You can disable subdividing the timestep/substepping by passing maxSubSteps=0 as second argument to stepSimulation, but in that case you have to keep the timeStep constant. + virtual int stepSimulation(btScalar timeStep, int maxSubSteps = 1, btScalar fixedTimeStep = btScalar(1.) / btScalar(60.)) = 0; + + virtual void debugDrawWorld() = 0; + + virtual void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies = false) + { + (void)constraint; + (void)disableCollisionsBetweenLinkedBodies; + } + + virtual void removeConstraint(btTypedConstraint* constraint) { (void)constraint; } + + virtual void addAction(btActionInterface* action) = 0; + + virtual void removeAction(btActionInterface* action) = 0; + + //once a rigidbody is added to the dynamics world, it will get this gravity assigned + //existing rigidbodies in the world get gravity assigned too, during this method + virtual void setGravity(const btVector3& gravity) = 0; + virtual btVector3 getGravity() const = 0; + + virtual void synchronizeMotionStates() = 0; + + virtual void addRigidBody(btRigidBody* body) = 0; + + virtual void addRigidBody(btRigidBody* body, int group, int mask) = 0; + + virtual void removeRigidBody(btRigidBody* body) = 0; + + virtual void setConstraintSolver(btConstraintSolver* solver) = 0; + + virtual btConstraintSolver* getConstraintSolver() = 0; + + virtual int getNumConstraints() const { return 0; } + + virtual btTypedConstraint* getConstraint(int index) + { + (void)index; + return 0; + } + + virtual const btTypedConstraint* getConstraint(int index) const + { + (void)index; + return 0; + } + + virtual btDynamicsWorldType getWorldType() const = 0; + + virtual void clearForces() = 0; + + /// Set the callback for when an internal tick (simulation substep) happens, optional user info + void setInternalTickCallback(btInternalTickCallback cb, void* worldUserInfo = 0, bool isPreTick = false) + { + if (isPreTick) { + m_internalPreTickCallback = cb; } - - virtual ~btDynamicsWorld() + else { + m_internalTickCallback = cb; } - - ///stepSimulation proceeds the simulation over 'timeStep', units in preferably in seconds. - ///By default, Bullet will subdivide the timestep in constant substeps of each 'fixedTimeStep'. - ///in order to keep the simulation real-time, the maximum number of substeps can be clamped to 'maxSubSteps'. - ///You can disable subdividing the timestep/substepping by passing maxSubSteps=0 as second argument to stepSimulation, but in that case you have to keep the timeStep constant. - virtual int stepSimulation( btScalar timeStep,int maxSubSteps=1, btScalar fixedTimeStep=btScalar(1.)/btScalar(60.))=0; - - virtual void debugDrawWorld() = 0; - - virtual void addConstraint(btTypedConstraint* constraint, bool disableCollisionsBetweenLinkedBodies=false) - { - (void)constraint; (void)disableCollisionsBetweenLinkedBodies; - } + m_worldUserInfo = worldUserInfo; + } - virtual void removeConstraint(btTypedConstraint* constraint) {(void)constraint;} + void setWorldUserInfo(void* worldUserInfo) + { + m_worldUserInfo = worldUserInfo; + } - virtual void addAction(btActionInterface* action) = 0; + void* getWorldUserInfo() const + { + return m_worldUserInfo; + } - virtual void removeAction(btActionInterface* action) = 0; - - //once a rigidbody is added to the dynamics world, it will get this gravity assigned - //existing rigidbodies in the world get gravity assigned too, during this method - virtual void setGravity(const btVector3& gravity) = 0; - virtual btVector3 getGravity () const = 0; - - virtual void synchronizeMotionStates() = 0; - - virtual void addRigidBody(btRigidBody* body) = 0; - - virtual void addRigidBody(btRigidBody* body, int group, int mask) = 0; - - virtual void removeRigidBody(btRigidBody* body) = 0; - - virtual void setConstraintSolver(btConstraintSolver* solver) = 0; - - virtual btConstraintSolver* getConstraintSolver() = 0; - - virtual int getNumConstraints() const { return 0; } - - virtual btTypedConstraint* getConstraint(int index) { (void)index; return 0; } - - virtual const btTypedConstraint* getConstraint(int index) const { (void)index; return 0; } - - virtual btDynamicsWorldType getWorldType() const=0; - - virtual void clearForces() = 0; - - /// Set the callback for when an internal tick (simulation substep) happens, optional user info - void setInternalTickCallback(btInternalTickCallback cb, void* worldUserInfo=0,bool isPreTick=false) - { - if (isPreTick) - { - m_internalPreTickCallback = cb; - } else - { - m_internalTickCallback = cb; - } - m_worldUserInfo = worldUserInfo; - } - - void setWorldUserInfo(void* worldUserInfo) - { - m_worldUserInfo = worldUserInfo; - } - - void* getWorldUserInfo() const - { - return m_worldUserInfo; - } - - btContactSolverInfo& getSolverInfo() - { - return m_solverInfo; - } - - const btContactSolverInfo& getSolverInfo() const - { - return m_solverInfo; - } - - - ///obsolete, use addAction instead. - virtual void addVehicle(btActionInterface* vehicle) {(void)vehicle;} - ///obsolete, use removeAction instead - virtual void removeVehicle(btActionInterface* vehicle) {(void)vehicle;} - ///obsolete, use addAction instead. - virtual void addCharacter(btActionInterface* character) {(void)character;} - ///obsolete, use removeAction instead - virtual void removeCharacter(btActionInterface* character) {(void)character;} + btContactSolverInfo& getSolverInfo() + { + return m_solverInfo; + } + const btContactSolverInfo& getSolverInfo() const + { + return m_solverInfo; + } + ///obsolete, use addAction instead. + virtual void addVehicle(btActionInterface* vehicle) { (void)vehicle; } + ///obsolete, use removeAction instead + virtual void removeVehicle(btActionInterface* vehicle) { (void)vehicle; } + ///obsolete, use addAction instead. + virtual void addCharacter(btActionInterface* character) { (void)character; } + ///obsolete, use removeAction instead + virtual void removeCharacter(btActionInterface* character) { (void)character; } }; ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 struct btDynamicsWorldDoubleData { - btContactSolverInfoDoubleData m_solverInfo; - btVector3DoubleData m_gravity; + btContactSolverInfoDoubleData m_solverInfo; + btVector3DoubleData m_gravity; }; ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 struct btDynamicsWorldFloatData { - btContactSolverInfoFloatData m_solverInfo; - btVector3FloatData m_gravity; + btContactSolverInfoFloatData m_solverInfo; + btVector3FloatData m_gravity; }; - -#endif //BT_DYNAMICS_WORLD_H - - +#endif //BT_DYNAMICS_WORLD_H diff --git a/src/BulletDynamics/Dynamics/btRigidBody.cpp b/src/BulletDynamics/Dynamics/btRigidBody.cpp index ca0714fcf..f4bcabada 100644 --- a/src/BulletDynamics/Dynamics/btRigidBody.cpp +++ b/src/BulletDynamics/Dynamics/btRigidBody.cpp @@ -22,36 +22,34 @@ subject to the following restrictions: #include "LinearMath/btSerializer.h" //'temporarily' global variables -btScalar gDeactivationTime = btScalar(2.); -bool gDisableDeactivation = false; +btScalar gDeactivationTime = btScalar(2.); +bool gDisableDeactivation = false; static int uniqueId = 0; - btRigidBody::btRigidBody(const btRigidBody::btRigidBodyConstructionInfo& constructionInfo) { setupRigidBody(constructionInfo); } -btRigidBody::btRigidBody(btScalar mass, btMotionState *motionState, btCollisionShape *collisionShape, const btVector3 &localInertia) +btRigidBody::btRigidBody(btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia) { - btRigidBodyConstructionInfo cinfo(mass,motionState,collisionShape,localInertia); + btRigidBodyConstructionInfo cinfo(mass, motionState, collisionShape, localInertia); setupRigidBody(cinfo); } -void btRigidBody::setupRigidBody(const btRigidBody::btRigidBodyConstructionInfo& constructionInfo) +void btRigidBody::setupRigidBody(const btRigidBody::btRigidBodyConstructionInfo& constructionInfo) { - - m_internalType=CO_RIGID_BODY; + m_internalType = CO_RIGID_BODY; m_linearVelocity.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); - m_angularVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); - m_angularFactor.setValue(1,1,1); - m_linearFactor.setValue(1,1,1); + m_angularVelocity.setValue(btScalar(0.), btScalar(0.), btScalar(0.)); + m_angularFactor.setValue(1, 1, 1); + m_linearFactor.setValue(1, 1, 1); m_gravity.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); m_gravity_acceleration.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)), - setDamping(constructionInfo.m_linearDamping, constructionInfo.m_angularDamping); + setDamping(constructionInfo.m_linearDamping, constructionInfo.m_angularDamping); m_linearSleepingThreshold = constructionInfo.m_linearSleepingThreshold; m_angularSleepingThreshold = constructionInfo.m_angularSleepingThreshold; @@ -67,48 +65,44 @@ void btRigidBody::setupRigidBody(const btRigidBody::btRigidBodyConstructionInfo& if (m_optionalMotionState) { m_optionalMotionState->getWorldTransform(m_worldTransform); - } else + } + else { m_worldTransform = constructionInfo.m_startWorldTransform; } m_interpolationWorldTransform = m_worldTransform; - m_interpolationLinearVelocity.setValue(0,0,0); - m_interpolationAngularVelocity.setValue(0,0,0); - + m_interpolationLinearVelocity.setValue(0, 0, 0); + m_interpolationAngularVelocity.setValue(0, 0, 0); + //moved to btCollisionObject m_friction = constructionInfo.m_friction; m_rollingFriction = constructionInfo.m_rollingFriction; - m_spinningFriction = constructionInfo.m_spinningFriction; - + m_spinningFriction = constructionInfo.m_spinningFriction; + m_restitution = constructionInfo.m_restitution; - setCollisionShape( constructionInfo.m_collisionShape ); + setCollisionShape(constructionInfo.m_collisionShape); m_debugBodyId = uniqueId++; - + setMassProps(constructionInfo.m_mass, constructionInfo.m_localInertia); updateInertiaTensor(); m_rigidbodyFlags = BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY; - m_deltaLinearVelocity.setZero(); m_deltaAngularVelocity.setZero(); - m_invMass = m_inverseMass*m_linearFactor; + m_invMass = m_inverseMass * m_linearFactor; m_pushVelocity.setZero(); m_turnVelocity.setZero(); - - - } - -void btRigidBody::predictIntegratedTransform(btScalar timeStep,btTransform& predictedTransform) +void btRigidBody::predictIntegratedTransform(btScalar timeStep, btTransform& predictedTransform) { - btTransformUtil::integrateTransform(m_worldTransform,m_linearVelocity,m_angularVelocity,timeStep,predictedTransform); + btTransformUtil::integrateTransform(m_worldTransform, m_linearVelocity, m_angularVelocity, timeStep, predictedTransform); } -void btRigidBody::saveKinematicState(btScalar timeStep) +void btRigidBody::saveKinematicState(btScalar timeStep) { //todo: clamp to some (user definable) safe minimum timestep, to limit maximum angular/linear velocities if (timeStep != btScalar(0.)) @@ -116,25 +110,22 @@ void btRigidBody::saveKinematicState(btScalar timeStep) //if we use motionstate to synchronize world transforms, get the new kinematic/animated world transform if (getMotionState()) getMotionState()->getWorldTransform(m_worldTransform); - btVector3 linVel,angVel; - - btTransformUtil::calculateVelocity(m_interpolationWorldTransform,m_worldTransform,timeStep,m_linearVelocity,m_angularVelocity); + btVector3 linVel, angVel; + + btTransformUtil::calculateVelocity(m_interpolationWorldTransform, m_worldTransform, timeStep, m_linearVelocity, m_angularVelocity); m_interpolationLinearVelocity = m_linearVelocity; m_interpolationAngularVelocity = m_angularVelocity; m_interpolationWorldTransform = m_worldTransform; //printf("angular = %f %f %f\n",m_angularVelocity.getX(),m_angularVelocity.getY(),m_angularVelocity.getZ()); } } - -void btRigidBody::getAabb(btVector3& aabbMin,btVector3& aabbMax) const + +void btRigidBody::getAabb(btVector3& aabbMin, btVector3& aabbMax) const { - getCollisionShape()->getAabb(m_worldTransform,aabbMin,aabbMax); + getCollisionShape()->getAabb(m_worldTransform, aabbMin, aabbMax); } - - - -void btRigidBody::setGravity(const btVector3& acceleration) +void btRigidBody::setGravity(const btVector3& acceleration) { if (m_inverseMass != btScalar(0.0)) { @@ -143,22 +134,14 @@ void btRigidBody::setGravity(const btVector3& acceleration) m_gravity_acceleration = acceleration; } - - - - - void btRigidBody::setDamping(btScalar lin_damping, btScalar ang_damping) { m_linearDamping = btClamped(lin_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); m_angularDamping = btClamped(ang_damping, (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); } - - - ///applyDamping damps the velocity, using the given m_linearDamping and m_angularDamping -void btRigidBody::applyDamping(btScalar timeStep) +void btRigidBody::applyDamping(btScalar timeStep) { //On new damping: see discussion/issue report here: http://code.google.com/p/bullet/issues/detail?id=74 //todo: do some performance comparisons (but other parts of the engine are probably bottleneck anyway @@ -168,8 +151,8 @@ void btRigidBody::applyDamping(btScalar timeStep) m_linearVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_linearDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); m_angularVelocity *= GEN_clamped((btScalar(1.) - timeStep * m_angularDamping), (btScalar)btScalar(0.0), (btScalar)btScalar(1.0)); #else - m_linearVelocity *= btPow(btScalar(1)-m_linearDamping, timeStep); - m_angularVelocity *= btPow(btScalar(1)-m_angularDamping, timeStep); + m_linearVelocity *= btPow(btScalar(1) - m_linearDamping, timeStep); + m_angularVelocity *= btPow(btScalar(1) - m_angularDamping, timeStep); #endif if (m_additionalDamping) @@ -182,7 +165,6 @@ void btRigidBody::applyDamping(btScalar timeStep) m_angularVelocity *= m_additionalDampingFactor; m_linearVelocity *= m_additionalDampingFactor; } - btScalar speed = m_linearVelocity.length(); if (speed < m_linearDamping) @@ -191,10 +173,11 @@ void btRigidBody::applyDamping(btScalar timeStep) if (speed > dampVel) { btVector3 dir = m_linearVelocity.normalized(); - m_linearVelocity -= dir * dampVel; - } else + m_linearVelocity -= dir * dampVel; + } + else { - m_linearVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); + m_linearVelocity.setValue(btScalar(0.), btScalar(0.), btScalar(0.)); } } @@ -205,30 +188,28 @@ void btRigidBody::applyDamping(btScalar timeStep) if (angSpeed > angDampVel) { btVector3 dir = m_angularVelocity.normalized(); - m_angularVelocity -= dir * angDampVel; - } else + m_angularVelocity -= dir * angDampVel; + } + else { - m_angularVelocity.setValue(btScalar(0.),btScalar(0.),btScalar(0.)); + m_angularVelocity.setValue(btScalar(0.), btScalar(0.), btScalar(0.)); } } } } - void btRigidBody::applyGravity() { if (isStaticOrKinematicObject()) return; - - applyCentralForce(m_gravity); + applyCentralForce(m_gravity); } void btRigidBody::proceedToTransform(const btTransform& newTrans) { - setCenterOfMassTransform( newTrans ); + setCenterOfMassTransform(newTrans); } - void btRigidBody::setMassProps(btScalar mass, const btVector3& inertia) { @@ -236,7 +217,8 @@ void btRigidBody::setMassProps(btScalar mass, const btVector3& inertia) { m_collisionFlags |= btCollisionObject::CF_STATIC_OBJECT; m_inverseMass = btScalar(0.); - } else + } + else { m_collisionFlags &= (~btCollisionObject::CF_STATIC_OBJECT); m_inverseMass = btScalar(1.0) / mass; @@ -244,50 +226,45 @@ void btRigidBody::setMassProps(btScalar mass, const btVector3& inertia) //Fg = m * a m_gravity = mass * m_gravity_acceleration; - - m_invInertiaLocal.setValue(inertia.x() != btScalar(0.0) ? btScalar(1.0) / inertia.x(): btScalar(0.0), - inertia.y() != btScalar(0.0) ? btScalar(1.0) / inertia.y(): btScalar(0.0), - inertia.z() != btScalar(0.0) ? btScalar(1.0) / inertia.z(): btScalar(0.0)); - m_invMass = m_linearFactor*m_inverseMass; + m_invInertiaLocal.setValue(inertia.x() != btScalar(0.0) ? btScalar(1.0) / inertia.x() : btScalar(0.0), + inertia.y() != btScalar(0.0) ? btScalar(1.0) / inertia.y() : btScalar(0.0), + inertia.z() != btScalar(0.0) ? btScalar(1.0) / inertia.z() : btScalar(0.0)); + + m_invMass = m_linearFactor * m_inverseMass; } - -void btRigidBody::updateInertiaTensor() +void btRigidBody::updateInertiaTensor() { m_invInertiaTensorWorld = m_worldTransform.getBasis().scaled(m_invInertiaLocal) * m_worldTransform.getBasis().transpose(); } - - btVector3 btRigidBody::getLocalInertia() const { - btVector3 inertiaLocal; const btVector3 inertia = m_invInertiaLocal; inertiaLocal.setValue(inertia.x() != btScalar(0.0) ? btScalar(1.0) / inertia.x() : btScalar(0.0), - inertia.y() != btScalar(0.0) ? btScalar(1.0) / inertia.y() : btScalar(0.0), - inertia.z() != btScalar(0.0) ? btScalar(1.0) / inertia.z() : btScalar(0.0)); + inertia.y() != btScalar(0.0) ? btScalar(1.0) / inertia.y() : btScalar(0.0), + inertia.z() != btScalar(0.0) ? btScalar(1.0) / inertia.z() : btScalar(0.0)); return inertiaLocal; } inline btVector3 evalEulerEqn(const btVector3& w1, const btVector3& w0, const btVector3& T, const btScalar dt, - const btMatrix3x3 &I) + const btMatrix3x3& I) { - const btVector3 w2 = I*w1 + w1.cross(I*w1)*dt - (T*dt + I*w0); + const btVector3 w2 = I * w1 + w1.cross(I * w1) * dt - (T * dt + I * w0); return w2; } inline btMatrix3x3 evalEulerEqnDeriv(const btVector3& w1, const btVector3& w0, const btScalar dt, - const btMatrix3x3 &I) + const btMatrix3x3& I) { - btMatrix3x3 w1x, Iw1x; - const btVector3 Iwi = (I*w1); + const btVector3 Iwi = (I * w1); w1.getSkewSymmetricMatrix(&w1x[0], &w1x[1], &w1x[2]); Iwi.getSkewSymmetricMatrix(&Iw1x[0], &Iw1x[1], &Iw1x[2]); - const btMatrix3x3 dfw1 = I + (w1x*I - Iw1x)*dt; + const btMatrix3x3 dfw1 = I + (w1x * I - Iw1x) * dt; return dfw1; } @@ -295,58 +272,55 @@ btVector3 btRigidBody::computeGyroscopicForceExplicit(btScalar maxGyroscopicForc { btVector3 inertiaLocal = getLocalInertia(); btMatrix3x3 inertiaTensorWorld = getWorldTransform().getBasis().scaled(inertiaLocal) * getWorldTransform().getBasis().transpose(); - btVector3 tmp = inertiaTensorWorld*getAngularVelocity(); + btVector3 tmp = inertiaTensorWorld * getAngularVelocity(); btVector3 gf = getAngularVelocity().cross(tmp); btScalar l2 = gf.length2(); - if (l2>maxGyroscopicForce*maxGyroscopicForce) + if (l2 > maxGyroscopicForce * maxGyroscopicForce) { - gf *= btScalar(1.)/btSqrt(l2)*maxGyroscopicForce; + gf *= btScalar(1.) / btSqrt(l2) * maxGyroscopicForce; } return gf; } - btVector3 btRigidBody::computeGyroscopicImpulseImplicit_Body(btScalar step) const -{ +{ btVector3 idl = getLocalInertia(); btVector3 omega1 = getAngularVelocity(); btQuaternion q = getWorldTransform().getRotation(); - + // Convert to body coordinates btVector3 omegab = quatRotate(q.inverse(), omega1); btMatrix3x3 Ib; - Ib.setValue(idl.x(),0,0, - 0,idl.y(),0, - 0,0,idl.z()); - - btVector3 ibo = Ib*omegab; + Ib.setValue(idl.x(), 0, 0, + 0, idl.y(), 0, + 0, 0, idl.z()); + + btVector3 ibo = Ib * omegab; // Residual vector btVector3 f = step * omegab.cross(ibo); - + btMatrix3x3 skew0; omegab.getSkewSymmetricMatrix(&skew0[0], &skew0[1], &skew0[2]); - btVector3 om = Ib*omegab; + btVector3 om = Ib * omegab; btMatrix3x3 skew1; - om.getSkewSymmetricMatrix(&skew1[0],&skew1[1],&skew1[2]); - + om.getSkewSymmetricMatrix(&skew1[0], &skew1[1], &skew1[2]); + // Jacobian - btMatrix3x3 J = Ib + (skew0*Ib - skew1)*step; - -// btMatrix3x3 Jinv = J.inverse(); -// btVector3 omega_div = Jinv*f; + btMatrix3x3 J = Ib + (skew0 * Ib - skew1) * step; + + // btMatrix3x3 Jinv = J.inverse(); + // btVector3 omega_div = Jinv*f; btVector3 omega_div = J.solve33(f); - + // Single Newton-Raphson update - omegab = omegab - omega_div;//Solve33(J, f); + omegab = omegab - omega_div; //Solve33(J, f); // Back to world coordinates - btVector3 omega2 = quatRotate(q,omegab); - btVector3 gf = omega2-omega1; + btVector3 omega2 = quatRotate(q, omegab); + btVector3 gf = omega2 - omega1; return gf; } - - btVector3 btRigidBody::computeGyroscopicImpulseImplicit_World(btScalar step) const { // use full newton-euler equations. common practice to drop the wxIw term. want it for better tumbling behavior. @@ -361,7 +335,7 @@ btVector3 btRigidBody::computeGyroscopicImpulseImplicit_World(btScalar step) con m_worldTransform.getBasis().transpose(); // use newtons method to find implicit solution for new angular velocity (w') - // f(w') = -(T*step + Iw) + Iw' + w' + w'xIw'*step = 0 + // f(w') = -(T*step + Iw) + Iw' + w' + w'xIw'*step = 0 // df/dw' = I + 1xIw'*step + w'xI*step btVector3 w1 = w0; @@ -383,8 +357,7 @@ btVector3 btRigidBody::computeGyroscopicImpulseImplicit_World(btScalar step) con return gf; } - -void btRigidBody::integrateVelocities(btScalar step) +void btRigidBody::integrateVelocities(btScalar step) { if (isStaticOrKinematicObject()) return; @@ -393,30 +366,28 @@ void btRigidBody::integrateVelocities(btScalar step) m_angularVelocity += m_invInertiaTensorWorld * m_totalTorque * step; #define MAX_ANGVEL SIMD_HALF_PI - /// clamp angular velocity. collision calculations will fail on higher angular velocities + /// clamp angular velocity. collision calculations will fail on higher angular velocities btScalar angvel = m_angularVelocity.length(); - if (angvel*step > MAX_ANGVEL) + if (angvel * step > MAX_ANGVEL) { - m_angularVelocity *= (MAX_ANGVEL/step) /angvel; + m_angularVelocity *= (MAX_ANGVEL / step) / angvel; } - } btQuaternion btRigidBody::getOrientation() const { - btQuaternion orn; - m_worldTransform.getBasis().getRotation(orn); - return orn; + btQuaternion orn; + m_worldTransform.getBasis().getRotation(orn); + return orn; } - - + void btRigidBody::setCenterOfMassTransform(const btTransform& xform) { - if (isKinematicObject()) { m_interpolationWorldTransform = m_worldTransform; - } else + } + else { m_interpolationWorldTransform = xform; } @@ -426,10 +397,6 @@ void btRigidBody::setCenterOfMassTransform(const btTransform& xform) updateInertiaTensor(); } - - - - void btRigidBody::addConstraintRef(btTypedConstraint* c) { ///disable collision with the 'other' body @@ -450,39 +417,39 @@ void btRigidBody::addConstraintRef(btTypedConstraint* c) { colObjB->setIgnoreCollisionCheck(colObjA, true); } - } + } } void btRigidBody::removeConstraintRef(btTypedConstraint* c) { int index = m_constraintRefs.findLinearSearch(c); //don't remove constraints that are not referenced - if(index < m_constraintRefs.size()) - { - m_constraintRefs.remove(c); - btCollisionObject* colObjA = &c->getRigidBodyA(); - btCollisionObject* colObjB = &c->getRigidBodyB(); - if (colObjA == this) - { - colObjA->setIgnoreCollisionCheck(colObjB, false); - } - else - { - colObjB->setIgnoreCollisionCheck(colObjA, false); - } - } + if (index < m_constraintRefs.size()) + { + m_constraintRefs.remove(c); + btCollisionObject* colObjA = &c->getRigidBodyA(); + btCollisionObject* colObjB = &c->getRigidBodyB(); + if (colObjA == this) + { + colObjA->setIgnoreCollisionCheck(colObjB, false); + } + else + { + colObjB->setIgnoreCollisionCheck(colObjA, false); + } + } } -int btRigidBody::calculateSerializeBufferSize() const +int btRigidBody::calculateSerializeBufferSize() const { int sz = sizeof(btRigidBodyData); return sz; } - ///fills the dataBuffer and returns the struct name (and 0 on failure) -const char* btRigidBody::serialize(void* dataBuffer, class btSerializer* serializer) const +///fills the dataBuffer and returns the struct name (and 0 on failure) +const char* btRigidBody::serialize(void* dataBuffer, class btSerializer* serializer) const { - btRigidBodyData* rbd = (btRigidBodyData*) dataBuffer; + btRigidBodyData* rbd = (btRigidBodyData*)dataBuffer; btCollisionObject::serialize(&rbd->m_collisionObjectData, serializer); @@ -504,7 +471,7 @@ const char* btRigidBody::serialize(void* dataBuffer, class btSerializer* seriali rbd->m_additionalLinearDampingThresholdSqr = m_additionalLinearDampingThresholdSqr; rbd->m_additionalAngularDampingThresholdSqr = m_additionalAngularDampingThresholdSqr; rbd->m_additionalAngularDampingFactor = m_additionalAngularDampingFactor; - rbd->m_linearSleepingThreshold=m_linearSleepingThreshold; + rbd->m_linearSleepingThreshold = m_linearSleepingThreshold; rbd->m_angularSleepingThreshold = m_angularSleepingThreshold; // Fill padding with zeros to appease msan. @@ -515,13 +482,9 @@ const char* btRigidBody::serialize(void* dataBuffer, class btSerializer* seriali return btRigidBodyDataName; } - - void btRigidBody::serializeSingleObject(class btSerializer* serializer) const { - btChunk* chunk = serializer->allocate(calculateSerializeBufferSize(),1); + btChunk* chunk = serializer->allocate(calculateSerializeBufferSize(), 1); const char* structType = serialize(chunk->m_oldPtr, serializer); - serializer->finalizeChunk(chunk,structType,BT_RIGIDBODY_CODE,(void*)this); + serializer->finalizeChunk(chunk, structType, BT_RIGIDBODY_CODE, (void*)this); } - - diff --git a/src/BulletDynamics/Dynamics/btRigidBody.h b/src/BulletDynamics/Dynamics/btRigidBody.h index 372245031..4bb5a0f91 100644 --- a/src/BulletDynamics/Dynamics/btRigidBody.h +++ b/src/BulletDynamics/Dynamics/btRigidBody.h @@ -25,209 +25,195 @@ class btCollisionShape; class btMotionState; class btTypedConstraint; - extern btScalar gDeactivationTime; extern bool gDisableDeactivation; #ifdef BT_USE_DOUBLE_PRECISION -#define btRigidBodyData btRigidBodyDoubleData -#define btRigidBodyDataName "btRigidBodyDoubleData" +#define btRigidBodyData btRigidBodyDoubleData +#define btRigidBodyDataName "btRigidBodyDoubleData" #else -#define btRigidBodyData btRigidBodyFloatData -#define btRigidBodyDataName "btRigidBodyFloatData" -#endif //BT_USE_DOUBLE_PRECISION +#define btRigidBodyData btRigidBodyFloatData +#define btRigidBodyDataName "btRigidBodyFloatData" +#endif //BT_USE_DOUBLE_PRECISION - -enum btRigidBodyFlags +enum btRigidBodyFlags { BT_DISABLE_WORLD_GRAVITY = 1, ///BT_ENABLE_GYROPSCOPIC_FORCE flags is enabled by default in Bullet 2.83 and onwards. ///and it BT_ENABLE_GYROPSCOPIC_FORCE becomes equivalent to BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY ///See Demos/GyroscopicDemo and computeGyroscopicImpulseImplicit BT_ENABLE_GYROSCOPIC_FORCE_EXPLICIT = 2, - BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD=4, - BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY=8, + BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD = 4, + BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY = 8, BT_ENABLE_GYROPSCOPIC_FORCE = BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY, }; - ///The btRigidBody is the main class for rigid body objects. It is derived from btCollisionObject, so it keeps a pointer to a btCollisionShape. ///It is recommended for performance and memory use to share btCollisionShape objects whenever possible. -///There are 3 types of rigid bodies: +///There are 3 types of rigid bodies: ///- A) Dynamic rigid bodies, with positive mass. Motion is controlled by rigid body dynamics. ///- B) Fixed objects with zero mass. They are not moving (basically collision objects) ///- C) Kinematic objects, which are objects without mass, but the user can move them. There is on-way interaction, and Bullet calculates a velocity based on the timestep and previous and current world transform. ///Bullet automatically deactivates dynamic rigid bodies, when the velocity is below a threshold for a given time. ///Deactivated (sleeping) rigid bodies don't take any processing time, except a minor broadphase collision detection impact (to allow active objects to activate/wake up sleeping objects) -class btRigidBody : public btCollisionObject +class btRigidBody : public btCollisionObject { + btMatrix3x3 m_invInertiaTensorWorld; + btVector3 m_linearVelocity; + btVector3 m_angularVelocity; + btScalar m_inverseMass; + btVector3 m_linearFactor; - btMatrix3x3 m_invInertiaTensorWorld; - btVector3 m_linearVelocity; - btVector3 m_angularVelocity; - btScalar m_inverseMass; - btVector3 m_linearFactor; + btVector3 m_gravity; + btVector3 m_gravity_acceleration; + btVector3 m_invInertiaLocal; + btVector3 m_totalForce; + btVector3 m_totalTorque; - btVector3 m_gravity; - btVector3 m_gravity_acceleration; - btVector3 m_invInertiaLocal; - btVector3 m_totalForce; - btVector3 m_totalTorque; - - btScalar m_linearDamping; - btScalar m_angularDamping; + btScalar m_linearDamping; + btScalar m_angularDamping; - bool m_additionalDamping; - btScalar m_additionalDampingFactor; - btScalar m_additionalLinearDampingThresholdSqr; - btScalar m_additionalAngularDampingThresholdSqr; - btScalar m_additionalAngularDampingFactor; + bool m_additionalDamping; + btScalar m_additionalDampingFactor; + btScalar m_additionalLinearDampingThresholdSqr; + btScalar m_additionalAngularDampingThresholdSqr; + btScalar m_additionalAngularDampingFactor; - - btScalar m_linearSleepingThreshold; - btScalar m_angularSleepingThreshold; + btScalar m_linearSleepingThreshold; + btScalar m_angularSleepingThreshold; //m_optionalMotionState allows to automatic synchronize the world transform for active objects - btMotionState* m_optionalMotionState; + btMotionState* m_optionalMotionState; //keep track of typed constraints referencing this rigid body, to disable collision between linked bodies btAlignedObjectArray m_constraintRefs; - int m_rigidbodyFlags; - - int m_debugBodyId; - + int m_rigidbodyFlags; + + int m_debugBodyId; protected: - - ATTRIBUTE_ALIGNED16(btVector3 m_deltaLinearVelocity); - btVector3 m_deltaAngularVelocity; - btVector3 m_angularFactor; - btVector3 m_invMass; - btVector3 m_pushVelocity; - btVector3 m_turnVelocity; - + ATTRIBUTE_ALIGNED16(btVector3 m_deltaLinearVelocity); + btVector3 m_deltaAngularVelocity; + btVector3 m_angularFactor; + btVector3 m_invMass; + btVector3 m_pushVelocity; + btVector3 m_turnVelocity; public: - - ///The btRigidBodyConstructionInfo structure provides information to create a rigid body. Setting mass to zero creates a fixed (non-dynamic) rigid body. ///For dynamic objects, you can use the collision shape to approximate the local inertia tensor, otherwise use the zero vector (default argument) - ///You can use the motion state to synchronize the world transform between physics and graphics objects. + ///You can use the motion state to synchronize the world transform between physics and graphics objects. ///And if the motion state is provided, the rigid body will initialize its initial world transform from the motion state, ///m_startWorldTransform is only used when you don't provide a motion state. - struct btRigidBodyConstructionInfo + struct btRigidBodyConstructionInfo { - btScalar m_mass; + btScalar m_mass; ///When a motionState is provided, the rigid body will initialize its world transform from the motion state ///In this case, m_startWorldTransform is ignored. - btMotionState* m_motionState; - btTransform m_startWorldTransform; + btMotionState* m_motionState; + btTransform m_startWorldTransform; - btCollisionShape* m_collisionShape; - btVector3 m_localInertia; - btScalar m_linearDamping; - btScalar m_angularDamping; + btCollisionShape* m_collisionShape; + btVector3 m_localInertia; + btScalar m_linearDamping; + btScalar m_angularDamping; ///best simulation results when friction is non-zero - btScalar m_friction; + btScalar m_friction; ///the m_rollingFriction prevents rounded shapes, such as spheres, cylinders and capsules from rolling forever. ///See Bullet/Demos/RollingFrictionDemo for usage - btScalar m_rollingFriction; - btScalar m_spinningFriction;//torsional friction around contact normal - - ///best simulation results using zero restitution. - btScalar m_restitution; + btScalar m_rollingFriction; + btScalar m_spinningFriction; //torsional friction around contact normal - btScalar m_linearSleepingThreshold; - btScalar m_angularSleepingThreshold; + ///best simulation results using zero restitution. + btScalar m_restitution; + + btScalar m_linearSleepingThreshold; + btScalar m_angularSleepingThreshold; //Additional damping can help avoiding lowpass jitter motion, help stability for ragdolls etc. //Such damping is undesirable, so once the overall simulation quality of the rigid body dynamics system has improved, this should become obsolete - bool m_additionalDamping; - btScalar m_additionalDampingFactor; - btScalar m_additionalLinearDampingThresholdSqr; - btScalar m_additionalAngularDampingThresholdSqr; - btScalar m_additionalAngularDampingFactor; + bool m_additionalDamping; + btScalar m_additionalDampingFactor; + btScalar m_additionalLinearDampingThresholdSqr; + btScalar m_additionalAngularDampingThresholdSqr; + btScalar m_additionalAngularDampingFactor; - btRigidBodyConstructionInfo( btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0)): - m_mass(mass), - m_motionState(motionState), - m_collisionShape(collisionShape), - m_localInertia(localInertia), - m_linearDamping(btScalar(0.)), - m_angularDamping(btScalar(0.)), - m_friction(btScalar(0.5)), - m_rollingFriction(btScalar(0)), - m_spinningFriction(btScalar(0)), - m_restitution(btScalar(0.)), - m_linearSleepingThreshold(btScalar(0.8)), - m_angularSleepingThreshold(btScalar(1.f)), - m_additionalDamping(false), - m_additionalDampingFactor(btScalar(0.005)), - m_additionalLinearDampingThresholdSqr(btScalar(0.01)), - m_additionalAngularDampingThresholdSqr(btScalar(0.01)), - m_additionalAngularDampingFactor(btScalar(0.01)) + btRigidBodyConstructionInfo(btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia = btVector3(0, 0, 0)) : m_mass(mass), + m_motionState(motionState), + m_collisionShape(collisionShape), + m_localInertia(localInertia), + m_linearDamping(btScalar(0.)), + m_angularDamping(btScalar(0.)), + m_friction(btScalar(0.5)), + m_rollingFriction(btScalar(0)), + m_spinningFriction(btScalar(0)), + m_restitution(btScalar(0.)), + m_linearSleepingThreshold(btScalar(0.8)), + m_angularSleepingThreshold(btScalar(1.f)), + m_additionalDamping(false), + m_additionalDampingFactor(btScalar(0.005)), + m_additionalLinearDampingThresholdSqr(btScalar(0.01)), + m_additionalAngularDampingThresholdSqr(btScalar(0.01)), + m_additionalAngularDampingFactor(btScalar(0.01)) { m_startWorldTransform.setIdentity(); } }; ///btRigidBody constructor using construction info - btRigidBody( const btRigidBodyConstructionInfo& constructionInfo); + btRigidBody(const btRigidBodyConstructionInfo& constructionInfo); - ///btRigidBody constructor for backwards compatibility. + ///btRigidBody constructor for backwards compatibility. ///To specify friction (etc) during rigid body construction, please use the other constructor (using btRigidBodyConstructionInfo) - btRigidBody( btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia=btVector3(0,0,0)); - + btRigidBody(btScalar mass, btMotionState* motionState, btCollisionShape* collisionShape, const btVector3& localInertia = btVector3(0, 0, 0)); virtual ~btRigidBody() - { - //No constraints should point to this rigidbody - //Remove constraints from the dynamics world before you delete the related rigidbodies. - btAssert(m_constraintRefs.size()==0); - } + { + //No constraints should point to this rigidbody + //Remove constraints from the dynamics world before you delete the related rigidbodies. + btAssert(m_constraintRefs.size() == 0); + } protected: - ///setupRigidBody is only used internally by the constructor - void setupRigidBody(const btRigidBodyConstructionInfo& constructionInfo); + void setupRigidBody(const btRigidBodyConstructionInfo& constructionInfo); public: + void proceedToTransform(const btTransform& newTrans); - void proceedToTransform(const btTransform& newTrans); - ///to keep collision detection and dynamics separate we don't store a rigidbody pointer ///but a rigidbody is derived from btCollisionObject, so we can safely perform an upcast - static const btRigidBody* upcast(const btCollisionObject* colObj) + static const btRigidBody* upcast(const btCollisionObject* colObj) { - if (colObj->getInternalType()&btCollisionObject::CO_RIGID_BODY) + if (colObj->getInternalType() & btCollisionObject::CO_RIGID_BODY) return (const btRigidBody*)colObj; return 0; } - static btRigidBody* upcast(btCollisionObject* colObj) + static btRigidBody* upcast(btCollisionObject* colObj) { - if (colObj->getInternalType()&btCollisionObject::CO_RIGID_BODY) + if (colObj->getInternalType() & btCollisionObject::CO_RIGID_BODY) return (btRigidBody*)colObj; return 0; } - - /// continuous collision detection needs prediction - void predictIntegratedTransform(btScalar step, btTransform& predictedTransform) ; - - void saveKinematicState(btScalar step); - - void applyGravity(); - - void setGravity(const btVector3& acceleration); - const btVector3& getGravity() const + /// continuous collision detection needs prediction + void predictIntegratedTransform(btScalar step, btTransform& predictedTransform); + + void saveKinematicState(btScalar step); + + void applyGravity(); + + void setGravity(const btVector3& acceleration); + + const btVector3& getGravity() const { return m_gravity_acceleration; } - void setDamping(btScalar lin_damping, btScalar ang_damping); + void setDamping(btScalar lin_damping, btScalar ang_damping); btScalar getLinearDamping() const { @@ -249,18 +235,20 @@ public: return m_angularSleepingThreshold; } - void applyDamping(btScalar timeStep); + void applyDamping(btScalar timeStep); - SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const { + SIMD_FORCE_INLINE const btCollisionShape* getCollisionShape() const + { return m_collisionShape; } - SIMD_FORCE_INLINE btCollisionShape* getCollisionShape() { - return m_collisionShape; + SIMD_FORCE_INLINE btCollisionShape* getCollisionShape() + { + return m_collisionShape; } - - void setMassProps(btScalar mass, const btVector3& inertia); - + + void setMassProps(btScalar mass, const btVector3& inertia); + const btVector3& getLinearFactor() const { return m_linearFactor; @@ -268,20 +256,21 @@ public: void setLinearFactor(const btVector3& linearFactor) { m_linearFactor = linearFactor; - m_invMass = m_linearFactor*m_inverseMass; + m_invMass = m_linearFactor * m_inverseMass; } - btScalar getInvMass() const { return m_inverseMass; } - const btMatrix3x3& getInvInertiaTensorWorld() const { - return m_invInertiaTensorWorld; - } - - void integrateVelocities(btScalar step); - - void setCenterOfMassTransform(const btTransform& xform); - - void applyCentralForce(const btVector3& force) + btScalar getInvMass() const { return m_inverseMass; } + const btMatrix3x3& getInvInertiaTensorWorld() const { - m_totalForce += force*m_linearFactor; + return m_invInertiaTensorWorld; + } + + void integrateVelocities(btScalar step); + + void setCenterOfMassTransform(const btTransform& xform); + + void applyCentralForce(const btVector3& force) + { + m_totalForce += force * m_linearFactor; } const btVector3& getTotalForce() const @@ -293,90 +282,93 @@ public: { return m_totalTorque; }; - + const btVector3& getInvInertiaDiagLocal() const { return m_invInertiaLocal; }; - void setInvInertiaDiagLocal(const btVector3& diagInvInertia) + void setInvInertiaDiagLocal(const btVector3& diagInvInertia) { m_invInertiaLocal = diagInvInertia; } - void setSleepingThresholds(btScalar linear,btScalar angular) + void setSleepingThresholds(btScalar linear, btScalar angular) { m_linearSleepingThreshold = linear; m_angularSleepingThreshold = angular; } - void applyTorque(const btVector3& torque) + void applyTorque(const btVector3& torque) { - m_totalTorque += torque*m_angularFactor; + m_totalTorque += torque * m_angularFactor; } - - void applyForce(const btVector3& force, const btVector3& rel_pos) + + void applyForce(const btVector3& force, const btVector3& rel_pos) { applyCentralForce(force); - applyTorque(rel_pos.cross(force*m_linearFactor)); + applyTorque(rel_pos.cross(force * m_linearFactor)); } - + void applyCentralImpulse(const btVector3& impulse) { - m_linearVelocity += impulse *m_linearFactor * m_inverseMass; + m_linearVelocity += impulse * m_linearFactor * m_inverseMass; } - - void applyTorqueImpulse(const btVector3& torque) + + void applyTorqueImpulse(const btVector3& torque) { - m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor; + m_angularVelocity += m_invInertiaTensorWorld * torque * m_angularFactor; } - - void applyImpulse(const btVector3& impulse, const btVector3& rel_pos) + + void applyImpulse(const btVector3& impulse, const btVector3& rel_pos) { if (m_inverseMass != btScalar(0.)) { applyCentralImpulse(impulse); if (m_angularFactor) { - applyTorqueImpulse(rel_pos.cross(impulse*m_linearFactor)); + applyTorqueImpulse(rel_pos.cross(impulse * m_linearFactor)); } } } - void clearForces() + void clearForces() { m_totalForce.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); m_totalTorque.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); } - - void updateInertiaTensor(); - - const btVector3& getCenterOfMassPosition() const { - return m_worldTransform.getOrigin(); + + void updateInertiaTensor(); + + const btVector3& getCenterOfMassPosition() const + { + return m_worldTransform.getOrigin(); } btQuaternion getOrientation() const; - - const btTransform& getCenterOfMassTransform() const { - return m_worldTransform; + + const btTransform& getCenterOfMassTransform() const + { + return m_worldTransform; } - const btVector3& getLinearVelocity() const { - return m_linearVelocity; + const btVector3& getLinearVelocity() const + { + return m_linearVelocity; } - const btVector3& getAngularVelocity() const { - return m_angularVelocity; + const btVector3& getAngularVelocity() const + { + return m_angularVelocity; } - inline void setLinearVelocity(const btVector3& lin_vel) - { + { m_updateRevision++; - m_linearVelocity = lin_vel; + m_linearVelocity = lin_vel; } - inline void setAngularVelocity(const btVector3& ang_vel) - { + inline void setAngularVelocity(const btVector3& ang_vel) + { m_updateRevision++; - m_angularVelocity = ang_vel; + m_angularVelocity = ang_vel; } btVector3 getVelocityInLocalPoint(const btVector3& rel_pos) const @@ -388,18 +380,13 @@ public: // return (m_worldTransform(rel_pos) - m_interpolationWorldTransform(rel_pos)) / m_kinematicTimeStep; } - void translate(const btVector3& v) + void translate(const btVector3& v) { - m_worldTransform.getOrigin() += v; + m_worldTransform.getOrigin() += v; } - - void getAabb(btVector3& aabbMin,btVector3& aabbMax) const; + void getAabb(btVector3& aabbMin, btVector3& aabbMax) const; - - - - SIMD_FORCE_INLINE btScalar computeImpulseDenominator(const btVector3& pos, const btVector3& normal) const { btVector3 r0 = pos - getCenterOfMassPosition(); @@ -409,7 +396,6 @@ public: btVector3 vec = (c0 * getInvInertiaTensorWorld()).cross(r0); return m_inverseMass + normal.dot(vec); - } SIMD_FORCE_INLINE btScalar computeAngularImpulseDenominator(const btVector3& axis) const @@ -418,26 +404,25 @@ public: return axis.dot(vec); } - SIMD_FORCE_INLINE void updateDeactivation(btScalar timeStep) + SIMD_FORCE_INLINE void updateDeactivation(btScalar timeStep) { - if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == DISABLE_DEACTIVATION)) + if ((getActivationState() == ISLAND_SLEEPING) || (getActivationState() == DISABLE_DEACTIVATION)) return; - if ((getLinearVelocity().length2() < m_linearSleepingThreshold*m_linearSleepingThreshold) && - (getAngularVelocity().length2() < m_angularSleepingThreshold*m_angularSleepingThreshold)) + if ((getLinearVelocity().length2() < m_linearSleepingThreshold * m_linearSleepingThreshold) && + (getAngularVelocity().length2() < m_angularSleepingThreshold * m_angularSleepingThreshold)) { m_deactivationTime += timeStep; - } else + } + else { - m_deactivationTime=btScalar(0.); + m_deactivationTime = btScalar(0.); setActivationState(0); } - } - SIMD_FORCE_INLINE bool wantsSleeping() + SIMD_FORCE_INLINE bool wantsSleeping() { - if (getActivationState() == DISABLE_DEACTIVATION) return false; @@ -445,41 +430,39 @@ public: if (gDisableDeactivation || (gDeactivationTime == btScalar(0.))) return false; - if ( (getActivationState() == ISLAND_SLEEPING) || (getActivationState() == WANTS_DEACTIVATION)) + if ((getActivationState() == ISLAND_SLEEPING) || (getActivationState() == WANTS_DEACTIVATION)) return true; - if (m_deactivationTime> gDeactivationTime) + if (m_deactivationTime > gDeactivationTime) { return true; } return false; } - - - const btBroadphaseProxy* getBroadphaseProxy() const + const btBroadphaseProxy* getBroadphaseProxy() const { return m_broadphaseHandle; } - btBroadphaseProxy* getBroadphaseProxy() + btBroadphaseProxy* getBroadphaseProxy() { return m_broadphaseHandle; } - void setNewBroadphaseProxy(btBroadphaseProxy* broadphaseProxy) + void setNewBroadphaseProxy(btBroadphaseProxy* broadphaseProxy) { m_broadphaseHandle = broadphaseProxy; } //btMotionState allows to automatic synchronize the world transform for active objects - btMotionState* getMotionState() + btMotionState* getMotionState() { return m_optionalMotionState; } - const btMotionState* getMotionState() const + const btMotionState* getMotionState() const { return m_optionalMotionState; } - void setMotionState(btMotionState* motionState) + void setMotionState(btMotionState* motionState) { m_optionalMotionState = motionState; if (m_optionalMotionState) @@ -487,27 +470,27 @@ public: } //for experimental overriding of friction/contact solver func - int m_contactSolverType; - int m_frictionSolverType; + int m_contactSolverType; + int m_frictionSolverType; - void setAngularFactor(const btVector3& angFac) + void setAngularFactor(const btVector3& angFac) { m_updateRevision++; m_angularFactor = angFac; } - void setAngularFactor(btScalar angFac) + void setAngularFactor(btScalar angFac) { m_updateRevision++; - m_angularFactor.setValue(angFac,angFac,angFac); + m_angularFactor.setValue(angFac, angFac, angFac); } - const btVector3& getAngularFactor() const + const btVector3& getAngularFactor() const { return m_angularFactor; } //is this rigidbody added to a btCollisionWorld/btDynamicsWorld/btBroadphase? - bool isInWorld() const + bool isInWorld() const { return (getBroadphaseProxy() != 0); } @@ -525,7 +508,7 @@ public: return m_constraintRefs.size(); } - void setFlags(int flags) + void setFlags(int flags) { m_rigidbodyFlags = flags; } @@ -535,12 +518,9 @@ public: return m_rigidbodyFlags; } - - - ///perform implicit force computation in world space btVector3 computeGyroscopicImpulseImplicit_World(btScalar dt) const; - + ///perform implicit force computation in body space (inertial frame) btVector3 computeGyroscopicImpulseImplicit_Body(btScalar step) const; @@ -550,70 +530,66 @@ public: /////////////////////////////////////////////// - virtual int calculateSerializeBufferSize() const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const; + virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const; virtual void serializeSingleObject(class btSerializer* serializer) const; - }; //@todo add m_optionalMotionState and m_constraintRefs to btRigidBodyData ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 -struct btRigidBodyFloatData +struct btRigidBodyFloatData { - btCollisionObjectFloatData m_collisionObjectData; - btMatrix3x3FloatData m_invInertiaTensorWorld; - btVector3FloatData m_linearVelocity; - btVector3FloatData m_angularVelocity; - btVector3FloatData m_angularFactor; - btVector3FloatData m_linearFactor; - btVector3FloatData m_gravity; - btVector3FloatData m_gravity_acceleration; - btVector3FloatData m_invInertiaLocal; - btVector3FloatData m_totalForce; - btVector3FloatData m_totalTorque; - float m_inverseMass; - float m_linearDamping; - float m_angularDamping; - float m_additionalDampingFactor; - float m_additionalLinearDampingThresholdSqr; - float m_additionalAngularDampingThresholdSqr; - float m_additionalAngularDampingFactor; - float m_linearSleepingThreshold; - float m_angularSleepingThreshold; - int m_additionalDamping; + btCollisionObjectFloatData m_collisionObjectData; + btMatrix3x3FloatData m_invInertiaTensorWorld; + btVector3FloatData m_linearVelocity; + btVector3FloatData m_angularVelocity; + btVector3FloatData m_angularFactor; + btVector3FloatData m_linearFactor; + btVector3FloatData m_gravity; + btVector3FloatData m_gravity_acceleration; + btVector3FloatData m_invInertiaLocal; + btVector3FloatData m_totalForce; + btVector3FloatData m_totalTorque; + float m_inverseMass; + float m_linearDamping; + float m_angularDamping; + float m_additionalDampingFactor; + float m_additionalLinearDampingThresholdSqr; + float m_additionalAngularDampingThresholdSqr; + float m_additionalAngularDampingFactor; + float m_linearSleepingThreshold; + float m_angularSleepingThreshold; + int m_additionalDamping; }; ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 -struct btRigidBodyDoubleData +struct btRigidBodyDoubleData { - btCollisionObjectDoubleData m_collisionObjectData; - btMatrix3x3DoubleData m_invInertiaTensorWorld; - btVector3DoubleData m_linearVelocity; - btVector3DoubleData m_angularVelocity; - btVector3DoubleData m_angularFactor; - btVector3DoubleData m_linearFactor; - btVector3DoubleData m_gravity; - btVector3DoubleData m_gravity_acceleration; - btVector3DoubleData m_invInertiaLocal; - btVector3DoubleData m_totalForce; - btVector3DoubleData m_totalTorque; - double m_inverseMass; - double m_linearDamping; - double m_angularDamping; - double m_additionalDampingFactor; - double m_additionalLinearDampingThresholdSqr; - double m_additionalAngularDampingThresholdSqr; - double m_additionalAngularDampingFactor; - double m_linearSleepingThreshold; - double m_angularSleepingThreshold; - int m_additionalDamping; - char m_padding[4]; + btCollisionObjectDoubleData m_collisionObjectData; + btMatrix3x3DoubleData m_invInertiaTensorWorld; + btVector3DoubleData m_linearVelocity; + btVector3DoubleData m_angularVelocity; + btVector3DoubleData m_angularFactor; + btVector3DoubleData m_linearFactor; + btVector3DoubleData m_gravity; + btVector3DoubleData m_gravity_acceleration; + btVector3DoubleData m_invInertiaLocal; + btVector3DoubleData m_totalForce; + btVector3DoubleData m_totalTorque; + double m_inverseMass; + double m_linearDamping; + double m_angularDamping; + double m_additionalDampingFactor; + double m_additionalLinearDampingThresholdSqr; + double m_additionalAngularDampingThresholdSqr; + double m_additionalAngularDampingFactor; + double m_linearSleepingThreshold; + double m_angularSleepingThreshold; + int m_additionalDamping; + char m_padding[4]; }; - - -#endif //BT_RIGIDBODY_H - +#endif //BT_RIGIDBODY_H diff --git a/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp b/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp index 6f63b87c8..8103390fb 100644 --- a/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp +++ b/src/BulletDynamics/Dynamics/btSimpleDynamicsWorld.cpp @@ -21,47 +21,40 @@ subject to the following restrictions: #include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" #include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" - /* Make sure this dummy function never changes so that it can be used by probes that are checking whether the library is actually installed. */ -extern "C" +extern "C" { - void btBulletDynamicsProbe (); - void btBulletDynamicsProbe () {} + void btBulletDynamicsProbe(); + void btBulletDynamicsProbe() {} } - - - -btSimpleDynamicsWorld::btSimpleDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration) -:btDynamicsWorld(dispatcher,pairCache,collisionConfiguration), -m_constraintSolver(constraintSolver), -m_ownsConstraintSolver(false), -m_gravity(0,0,-10) +btSimpleDynamicsWorld::btSimpleDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration) + : btDynamicsWorld(dispatcher, pairCache, collisionConfiguration), + m_constraintSolver(constraintSolver), + m_ownsConstraintSolver(false), + m_gravity(0, 0, -10) { - } - btSimpleDynamicsWorld::~btSimpleDynamicsWorld() { if (m_ownsConstraintSolver) - btAlignedFree( m_constraintSolver); + btAlignedFree(m_constraintSolver); } -int btSimpleDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, btScalar fixedTimeStep) +int btSimpleDynamicsWorld::stepSimulation(btScalar timeStep, int maxSubSteps, btScalar fixedTimeStep) { (void)fixedTimeStep; (void)maxSubSteps; - ///apply gravity, predict motion predictUnconstraintMotion(timeStep); - btDispatcherInfo& dispatchInfo = getDispatchInfo(); + btDispatcherInfo& dispatchInfo = getDispatchInfo(); dispatchInfo.m_timeStep = timeStep; dispatchInfo.m_stepCount = 0; dispatchInfo.m_debugDraw = getDebugDrawer(); @@ -74,17 +67,17 @@ int btSimpleDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, b if (numManifolds) { btPersistentManifold** manifoldPtr = ((btCollisionDispatcher*)m_dispatcher1)->getInternalManifoldPointer(); - + btContactSolverInfo infoGlobal; infoGlobal.m_timeStep = timeStep; - m_constraintSolver->prepareSolve(0,numManifolds); - m_constraintSolver->solveGroup(&getCollisionObjectArray()[0],getNumCollisionObjects(),manifoldPtr, numManifolds,0,0,infoGlobal,m_debugDrawer, m_dispatcher1); - m_constraintSolver->allSolved(infoGlobal,m_debugDrawer); + m_constraintSolver->prepareSolve(0, numManifolds); + m_constraintSolver->solveGroup(&getCollisionObjectArray()[0], getNumCollisionObjects(), manifoldPtr, numManifolds, 0, 0, infoGlobal, m_debugDrawer, m_dispatcher1); + m_constraintSolver->allSolved(infoGlobal, m_debugDrawer); } ///integrate transforms integrateTransforms(timeStep); - + updateAabbs(); synchronizeMotionStates(); @@ -92,29 +85,27 @@ int btSimpleDynamicsWorld::stepSimulation( btScalar timeStep,int maxSubSteps, b clearForces(); return 1; - } -void btSimpleDynamicsWorld::clearForces() +void btSimpleDynamicsWorld::clearForces() { ///@todo: iterate over awake simulation islands! - for ( int i=0;iclearForces(); } } -} +} - -void btSimpleDynamicsWorld::setGravity(const btVector3& gravity) +void btSimpleDynamicsWorld::setGravity(const btVector3& gravity) { m_gravity = gravity; - for ( int i=0;isetGravity(m_gravity); @@ -155,37 +145,32 @@ void btSimpleDynamicsWorld::addRigidBody(btRigidBody* body) } } -void btSimpleDynamicsWorld::addRigidBody(btRigidBody* body, int group, int mask) +void btSimpleDynamicsWorld::addRigidBody(btRigidBody* body, int group, int mask) { body->setGravity(m_gravity); if (body->getCollisionShape()) { - addCollisionObject(body,group,mask); + addCollisionObject(body, group, mask); } } - -void btSimpleDynamicsWorld::debugDrawWorld() +void btSimpleDynamicsWorld::debugDrawWorld() { - -} - -void btSimpleDynamicsWorld::addAction(btActionInterface* action) -{ - } -void btSimpleDynamicsWorld::removeAction(btActionInterface* action) +void btSimpleDynamicsWorld::addAction(btActionInterface* action) { - } +void btSimpleDynamicsWorld::removeAction(btActionInterface* action) +{ +} -void btSimpleDynamicsWorld::updateAabbs() +void btSimpleDynamicsWorld::updateAabbs() { btTransform predictedTrans; - for ( int i=0;iisActive() && (!body->isStaticObject())) { - btVector3 minAabb,maxAabb; - colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb,maxAabb); + btVector3 minAabb, maxAabb; + colObj->getCollisionShape()->getAabb(colObj->getWorldTransform(), minAabb, maxAabb); btBroadphaseInterface* bp = getBroadphase(); - bp->setAabb(body->getBroadphaseHandle(),minAabb,maxAabb, m_dispatcher1); + bp->setAabb(body->getBroadphaseHandle(), minAabb, maxAabb, m_dispatcher1); } } } } -void btSimpleDynamicsWorld::integrateTransforms(btScalar timeStep) +void btSimpleDynamicsWorld::integrateTransforms(btScalar timeStep) { btTransform predictedTrans; - for ( int i=0;iisActive() && (!body->isStaticObject())) { body->predictIntegratedTransform(timeStep, predictedTrans); - body->proceedToTransform( predictedTrans); + body->proceedToTransform(predictedTrans); } } } } - - -void btSimpleDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) +void btSimpleDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) { - for ( int i=0;iisActive()) { body->applyGravity(); - body->integrateVelocities( timeStep); + body->integrateVelocities(timeStep); body->applyDamping(timeStep); - body->predictIntegratedTransform(timeStep,body->getInterpolationWorldTransform()); + body->predictIntegratedTransform(timeStep, body->getInterpolationWorldTransform()); } } } } } - -void btSimpleDynamicsWorld::synchronizeMotionStates() +void btSimpleDynamicsWorld::synchronizeMotionStates() { ///@todo: iterate over awake simulation islands! - for ( int i=0;i #include "LinearMath/btQuickprof.h" - -SIMD_FORCE_INLINE int calcBatchCost( int bodies, int manifolds, int constraints ) +SIMD_FORCE_INLINE int calcBatchCost(int bodies, int manifolds, int constraints) { - // rough estimate of the cost of a batch, used for merging - int batchCost = bodies + 8 * manifolds + 4 * constraints; - return batchCost; + // rough estimate of the cost of a batch, used for merging + int batchCost = bodies + 8 * manifolds + 4 * constraints; + return batchCost; } - -SIMD_FORCE_INLINE int calcBatchCost( const btSimulationIslandManagerMt::Island* island ) +SIMD_FORCE_INLINE int calcBatchCost(const btSimulationIslandManagerMt::Island* island) { - return calcBatchCost( island->bodyArray.size(), island->manifoldArray.size(), island->constraintArray.size() ); + return calcBatchCost(island->bodyArray.size(), island->manifoldArray.size(), island->constraintArray.size()); } - btSimulationIslandManagerMt::btSimulationIslandManagerMt() { - m_minimumSolverBatchSize = calcBatchCost(0, 128, 0); - m_batchIslandMinBodyCount = 32; - m_islandDispatch = parallelIslandDispatch; - m_batchIsland = NULL; + m_minimumSolverBatchSize = calcBatchCost(0, 128, 0); + m_batchIslandMinBodyCount = 32; + m_islandDispatch = parallelIslandDispatch; + m_batchIsland = NULL; } - btSimulationIslandManagerMt::~btSimulationIslandManagerMt() { - for ( int i = 0; i < m_allocatedIslands.size(); ++i ) - { - delete m_allocatedIslands[ i ]; - } - m_allocatedIslands.resize( 0 ); - m_activeIslands.resize( 0 ); - m_freeIslands.resize( 0 ); + for (int i = 0; i < m_allocatedIslands.size(); ++i) + { + delete m_allocatedIslands[i]; + } + m_allocatedIslands.resize(0); + m_activeIslands.resize(0); + m_freeIslands.resize(0); } - -inline int getIslandId(const btPersistentManifold* lhs) +inline int getIslandId(const btPersistentManifold* lhs) { const btCollisionObject* rcolObj0 = static_cast(lhs->getBody0()); const btCollisionObject* rcolObj1 = static_cast(lhs->getBody1()); - int islandId = rcolObj0->getIslandTag() >= 0 ? rcolObj0->getIslandTag() : rcolObj1->getIslandTag(); + int islandId = rcolObj0->getIslandTag() >= 0 ? rcolObj0->getIslandTag() : rcolObj1->getIslandTag(); return islandId; } - -SIMD_FORCE_INLINE int btGetConstraintIslandId( const btTypedConstraint* lhs ) +SIMD_FORCE_INLINE int btGetConstraintIslandId(const btTypedConstraint* lhs) { - const btCollisionObject& rcolObj0 = lhs->getRigidBodyA(); - const btCollisionObject& rcolObj1 = lhs->getRigidBodyB(); - int islandId = rcolObj0.getIslandTag() >= 0 ? rcolObj0.getIslandTag() : rcolObj1.getIslandTag(); - return islandId; + const btCollisionObject& rcolObj0 = lhs->getRigidBodyA(); + const btCollisionObject& rcolObj1 = lhs->getRigidBodyB(); + int islandId = rcolObj0.getIslandTag() >= 0 ? rcolObj0.getIslandTag() : rcolObj1.getIslandTag(); + return islandId; } /// function object that routes calls to operator< class IslandBatchSizeSortPredicate { public: - bool operator() ( const btSimulationIslandManagerMt::Island* lhs, const btSimulationIslandManagerMt::Island* rhs ) const - { - int lCost = calcBatchCost( lhs ); - int rCost = calcBatchCost( rhs ); - return lCost > rCost; - } + bool operator()(const btSimulationIslandManagerMt::Island* lhs, const btSimulationIslandManagerMt::Island* rhs) const + { + int lCost = calcBatchCost(lhs); + int rCost = calcBatchCost(rhs); + return lCost > rCost; + } }; - class IslandBodyCapacitySortPredicate { public: - bool operator() ( const btSimulationIslandManagerMt::Island* lhs, const btSimulationIslandManagerMt::Island* rhs ) const - { - return lhs->bodyArray.capacity() > rhs->bodyArray.capacity(); - } + bool operator()(const btSimulationIslandManagerMt::Island* lhs, const btSimulationIslandManagerMt::Island* rhs) const + { + return lhs->bodyArray.capacity() > rhs->bodyArray.capacity(); + } }; - -void btSimulationIslandManagerMt::Island::append( const Island& other ) +void btSimulationIslandManagerMt::Island::append(const Island& other) { - // append bodies - for ( int i = 0; i < other.bodyArray.size(); ++i ) - { - bodyArray.push_back( other.bodyArray[ i ] ); - } - // append manifolds - for ( int i = 0; i < other.manifoldArray.size(); ++i ) - { - manifoldArray.push_back( other.manifoldArray[ i ] ); - } - // append constraints - for ( int i = 0; i < other.constraintArray.size(); ++i ) - { - constraintArray.push_back( other.constraintArray[ i ] ); - } + // append bodies + for (int i = 0; i < other.bodyArray.size(); ++i) + { + bodyArray.push_back(other.bodyArray[i]); + } + // append manifolds + for (int i = 0; i < other.manifoldArray.size(); ++i) + { + manifoldArray.push_back(other.manifoldArray[i]); + } + // append constraints + for (int i = 0; i < other.constraintArray.size(); ++i) + { + constraintArray.push_back(other.constraintArray[i]); + } } - -bool btIsBodyInIsland( const btSimulationIslandManagerMt::Island& island, const btCollisionObject* obj ) +bool btIsBodyInIsland(const btSimulationIslandManagerMt::Island& island, const btCollisionObject* obj) { - for ( int i = 0; i < island.bodyArray.size(); ++i ) - { - if ( island.bodyArray[ i ] == obj ) - { - return true; - } - } - return false; + for (int i = 0; i < island.bodyArray.size(); ++i) + { + if (island.bodyArray[i] == obj) + { + return true; + } + } + return false; } - void btSimulationIslandManagerMt::initIslandPools() { - // reset island pools - int numElem = getUnionFind().getNumElements(); - m_lookupIslandFromId.resize( numElem ); - for ( int i = 0; i < m_lookupIslandFromId.size(); ++i ) - { - m_lookupIslandFromId[ i ] = NULL; - } - m_activeIslands.resize( 0 ); - m_freeIslands.resize( 0 ); - // check whether allocated islands are sorted by body capacity (largest to smallest) - int lastCapacity = 0; - bool isSorted = true; - for ( int i = 0; i < m_allocatedIslands.size(); ++i ) - { - Island* island = m_allocatedIslands[ i ]; - int cap = island->bodyArray.capacity(); - if ( cap > lastCapacity ) - { - isSorted = false; - break; - } - lastCapacity = cap; - } - if ( !isSorted ) - { - m_allocatedIslands.quickSort( IslandBodyCapacitySortPredicate() ); - } + // reset island pools + int numElem = getUnionFind().getNumElements(); + m_lookupIslandFromId.resize(numElem); + for (int i = 0; i < m_lookupIslandFromId.size(); ++i) + { + m_lookupIslandFromId[i] = NULL; + } + m_activeIslands.resize(0); + m_freeIslands.resize(0); + // check whether allocated islands are sorted by body capacity (largest to smallest) + int lastCapacity = 0; + bool isSorted = true; + for (int i = 0; i < m_allocatedIslands.size(); ++i) + { + Island* island = m_allocatedIslands[i]; + int cap = island->bodyArray.capacity(); + if (cap > lastCapacity) + { + isSorted = false; + break; + } + lastCapacity = cap; + } + if (!isSorted) + { + m_allocatedIslands.quickSort(IslandBodyCapacitySortPredicate()); + } - m_batchIsland = NULL; - // mark all islands free (but avoid deallocation) - for ( int i = 0; i < m_allocatedIslands.size(); ++i ) - { - Island* island = m_allocatedIslands[ i ]; - island->bodyArray.resize( 0 ); - island->manifoldArray.resize( 0 ); - island->constraintArray.resize( 0 ); - island->id = -1; - island->isSleeping = true; - m_freeIslands.push_back( island ); - } + m_batchIsland = NULL; + // mark all islands free (but avoid deallocation) + for (int i = 0; i < m_allocatedIslands.size(); ++i) + { + Island* island = m_allocatedIslands[i]; + island->bodyArray.resize(0); + island->manifoldArray.resize(0); + island->constraintArray.resize(0); + island->id = -1; + island->isSleeping = true; + m_freeIslands.push_back(island); + } } - -btSimulationIslandManagerMt::Island* btSimulationIslandManagerMt::getIsland( int id ) +btSimulationIslandManagerMt::Island* btSimulationIslandManagerMt::getIsland(int id) { - Island* island = m_lookupIslandFromId[ id ]; - if ( island == NULL ) - { - // search for existing island - for ( int i = 0; i < m_activeIslands.size(); ++i ) - { - if ( m_activeIslands[ i ]->id == id ) - { - island = m_activeIslands[ i ]; - break; - } - } - m_lookupIslandFromId[ id ] = island; - } - return island; + Island* island = m_lookupIslandFromId[id]; + if (island == NULL) + { + // search for existing island + for (int i = 0; i < m_activeIslands.size(); ++i) + { + if (m_activeIslands[i]->id == id) + { + island = m_activeIslands[i]; + break; + } + } + m_lookupIslandFromId[id] = island; + } + return island; } - -btSimulationIslandManagerMt::Island* btSimulationIslandManagerMt::allocateIsland( int id, int numBodies ) +btSimulationIslandManagerMt::Island* btSimulationIslandManagerMt::allocateIsland(int id, int numBodies) { - Island* island = NULL; - int allocSize = numBodies; - if ( numBodies < m_batchIslandMinBodyCount ) - { - if ( m_batchIsland ) - { - island = m_batchIsland; - m_lookupIslandFromId[ id ] = island; - // if we've made a large enough batch, - if ( island->bodyArray.size() + numBodies >= m_batchIslandMinBodyCount ) - { - // next time start a new batch - m_batchIsland = NULL; - } - return island; - } - else - { - // need to allocate a batch island - allocSize = m_batchIslandMinBodyCount * 2; - } - } - btAlignedObjectArray& freeIslands = m_freeIslands; + Island* island = NULL; + int allocSize = numBodies; + if (numBodies < m_batchIslandMinBodyCount) + { + if (m_batchIsland) + { + island = m_batchIsland; + m_lookupIslandFromId[id] = island; + // if we've made a large enough batch, + if (island->bodyArray.size() + numBodies >= m_batchIslandMinBodyCount) + { + // next time start a new batch + m_batchIsland = NULL; + } + return island; + } + else + { + // need to allocate a batch island + allocSize = m_batchIslandMinBodyCount * 2; + } + } + btAlignedObjectArray& freeIslands = m_freeIslands; - // search for free island - if ( freeIslands.size() > 0 ) - { - // try to reuse a previously allocated island - int iFound = freeIslands.size(); - // linear search for smallest island that can hold our bodies - for ( int i = freeIslands.size() - 1; i >= 0; --i ) - { - if ( freeIslands[ i ]->bodyArray.capacity() >= allocSize ) - { - iFound = i; - island = freeIslands[ i ]; - island->id = id; - break; - } - } - // if found, shrink array while maintaining ordering - if ( island ) - { - int iDest = iFound; - int iSrc = iDest + 1; - while ( iSrc < freeIslands.size() ) - { - freeIslands[ iDest++ ] = freeIslands[ iSrc++ ]; - } - freeIslands.pop_back(); - } - } - if ( island == NULL ) - { - // no free island found, allocate - island = new Island(); // TODO: change this to use the pool allocator - island->id = id; - island->bodyArray.reserve( allocSize ); - m_allocatedIslands.push_back( island ); - } - m_lookupIslandFromId[ id ] = island; - if ( numBodies < m_batchIslandMinBodyCount ) - { - m_batchIsland = island; - } - m_activeIslands.push_back( island ); - return island; + // search for free island + if (freeIslands.size() > 0) + { + // try to reuse a previously allocated island + int iFound = freeIslands.size(); + // linear search for smallest island that can hold our bodies + for (int i = freeIslands.size() - 1; i >= 0; --i) + { + if (freeIslands[i]->bodyArray.capacity() >= allocSize) + { + iFound = i; + island = freeIslands[i]; + island->id = id; + break; + } + } + // if found, shrink array while maintaining ordering + if (island) + { + int iDest = iFound; + int iSrc = iDest + 1; + while (iSrc < freeIslands.size()) + { + freeIslands[iDest++] = freeIslands[iSrc++]; + } + freeIslands.pop_back(); + } + } + if (island == NULL) + { + // no free island found, allocate + island = new Island(); // TODO: change this to use the pool allocator + island->id = id; + island->bodyArray.reserve(allocSize); + m_allocatedIslands.push_back(island); + } + m_lookupIslandFromId[id] = island; + if (numBodies < m_batchIslandMinBodyCount) + { + m_batchIsland = island; + } + m_activeIslands.push_back(island); + return island; } - -void btSimulationIslandManagerMt::buildIslands( btDispatcher* dispatcher, btCollisionWorld* collisionWorld ) +void btSimulationIslandManagerMt::buildIslands(btDispatcher* dispatcher, btCollisionWorld* collisionWorld) { - BT_PROFILE("buildIslands"); - + btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray(); //we are going to sort the unionfind array, and store the element id in the size //afterwards, we clean unionfind, to make sure no-one uses it anymore - + getUnionFind().sortIslands(); int numElem = getUnionFind().getNumElements(); - int endIslandIndex=1; + int endIslandIndex = 1; int startIslandIndex; //update the sleeping state for bodies, if all are sleeping - for ( startIslandIndex=0;startIslandIndexgetIslandTag() != islandId) && (colObj0->getIslandTag() != -1)) { -// printf("error in island management\n"); + // printf("error in island management\n"); } btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); if (colObj0->getIslandTag() == islandId) { - if (colObj0->getActivationState()== ACTIVE_TAG || - colObj0->getActivationState()== DISABLE_DEACTIVATION) + if (colObj0->getActivationState() == ACTIVE_TAG || + colObj0->getActivationState() == DISABLE_DEACTIVATION) { allSleeping = false; break; @@ -327,43 +312,43 @@ void btSimulationIslandManagerMt::buildIslands( btDispatcher* dispatcher, btColl if (allSleeping) { int idx; - for (idx=startIslandIndex;idxgetIslandTag() != islandId) && (colObj0->getIslandTag() != -1)) { -// printf("error in island management\n"); + // printf("error in island management\n"); } btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); if (colObj0->getIslandTag() == islandId) { - colObj0->setActivationState( ISLAND_SLEEPING ); + colObj0->setActivationState(ISLAND_SLEEPING); } } - } else + } + else { - int idx; - for (idx=startIslandIndex;idxgetIslandTag() != islandId) && (colObj0->getIslandTag() != -1)) { -// printf("error in island management\n"); + // printf("error in island management\n"); } btAssert((colObj0->getIslandTag() == islandId) || (colObj0->getIslandTag() == -1)); if (colObj0->getIslandTag() == islandId) { - if ( colObj0->getActivationState() == ISLAND_SLEEPING) + if (colObj0->getActivationState() == ISLAND_SLEEPING) { - colObj0->setActivationState( WANTS_DEACTIVATION); + colObj0->setActivationState(WANTS_DEACTIVATION); colObj0->setDeactivationTime(0.f); } } @@ -372,352 +357,338 @@ void btSimulationIslandManagerMt::buildIslands( btDispatcher* dispatcher, btColl } } - -void btSimulationIslandManagerMt::addBodiesToIslands( btCollisionWorld* collisionWorld ) +void btSimulationIslandManagerMt::addBodiesToIslands(btCollisionWorld* collisionWorld) { - btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray(); - int endIslandIndex = 1; - int startIslandIndex; - int numElem = getUnionFind().getNumElements(); + btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray(); + int endIslandIndex = 1; + int startIslandIndex; + int numElem = getUnionFind().getNumElements(); - // create explicit islands and add bodies to each - for ( startIslandIndex = 0; startIslandIndex < numElem; startIslandIndex = endIslandIndex ) - { - int islandId = getUnionFind().getElement( startIslandIndex ).m_id; + // create explicit islands and add bodies to each + for (startIslandIndex = 0; startIslandIndex < numElem; startIslandIndex = endIslandIndex) + { + int islandId = getUnionFind().getElement(startIslandIndex).m_id; - // find end index - for ( endIslandIndex = startIslandIndex; ( endIslandIndex < numElem ) && ( getUnionFind().getElement( endIslandIndex ).m_id == islandId ); endIslandIndex++ ) - { - } - // check if island is sleeping - bool islandSleeping = true; - for ( int iElem = startIslandIndex; iElem < endIslandIndex; iElem++ ) - { - int i = getUnionFind().getElement( iElem ).m_sz; - btCollisionObject* colObj = collisionObjects[ i ]; - if ( colObj->isActive() ) - { - islandSleeping = false; - } - } - if ( !islandSleeping ) - { - // want to count the number of bodies before allocating the island to optimize memory usage of the Island structures - int numBodies = endIslandIndex - startIslandIndex; - Island* island = allocateIsland( islandId, numBodies ); - island->isSleeping = false; - - // add bodies to island - for ( int iElem = startIslandIndex; iElem < endIslandIndex; iElem++ ) - { - int i = getUnionFind().getElement( iElem ).m_sz; - btCollisionObject* colObj = collisionObjects[ i ]; - island->bodyArray.push_back( colObj ); - } - } - } + // find end index + for (endIslandIndex = startIslandIndex; (endIslandIndex < numElem) && (getUnionFind().getElement(endIslandIndex).m_id == islandId); endIslandIndex++) + { + } + // check if island is sleeping + bool islandSleeping = true; + for (int iElem = startIslandIndex; iElem < endIslandIndex; iElem++) + { + int i = getUnionFind().getElement(iElem).m_sz; + btCollisionObject* colObj = collisionObjects[i]; + if (colObj->isActive()) + { + islandSleeping = false; + } + } + if (!islandSleeping) + { + // want to count the number of bodies before allocating the island to optimize memory usage of the Island structures + int numBodies = endIslandIndex - startIslandIndex; + Island* island = allocateIsland(islandId, numBodies); + island->isSleeping = false; + // add bodies to island + for (int iElem = startIslandIndex; iElem < endIslandIndex; iElem++) + { + int i = getUnionFind().getElement(iElem).m_sz; + btCollisionObject* colObj = collisionObjects[i]; + island->bodyArray.push_back(colObj); + } + } + } } - -void btSimulationIslandManagerMt::addManifoldsToIslands( btDispatcher* dispatcher ) +void btSimulationIslandManagerMt::addManifoldsToIslands(btDispatcher* dispatcher) { - // walk all the manifolds, activating bodies touched by kinematic objects, and add each manifold to its Island - int maxNumManifolds = dispatcher->getNumManifolds(); - for ( int i = 0; i < maxNumManifolds; i++ ) - { - btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal( i ); + // walk all the manifolds, activating bodies touched by kinematic objects, and add each manifold to its Island + int maxNumManifolds = dispatcher->getNumManifolds(); + for (int i = 0; i < maxNumManifolds; i++) + { + btPersistentManifold* manifold = dispatcher->getManifoldByIndexInternal(i); - const btCollisionObject* colObj0 = static_cast( manifold->getBody0() ); - const btCollisionObject* colObj1 = static_cast( manifold->getBody1() ); + const btCollisionObject* colObj0 = static_cast(manifold->getBody0()); + const btCollisionObject* colObj1 = static_cast(manifold->getBody1()); - ///@todo: check sleeping conditions! - if ( ( ( colObj0 ) && colObj0->getActivationState() != ISLAND_SLEEPING ) || - ( ( colObj1 ) && colObj1->getActivationState() != ISLAND_SLEEPING ) ) - { - - //kinematic objects don't merge islands, but wake up all connected objects - if ( colObj0->isKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING ) - { - if ( colObj0->hasContactResponse() ) - colObj1->activate(); - } - if ( colObj1->isKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING ) - { - if ( colObj1->hasContactResponse() ) - colObj0->activate(); - } - //filtering for response - if ( dispatcher->needsResponse( colObj0, colObj1 ) ) - { - // scatter manifolds into various islands - int islandId = getIslandId( manifold ); - // if island not sleeping, - if ( Island* island = getIsland( islandId ) ) - { - island->manifoldArray.push_back( manifold ); - } - } - } - } + ///@todo: check sleeping conditions! + if (((colObj0) && colObj0->getActivationState() != ISLAND_SLEEPING) || + ((colObj1) && colObj1->getActivationState() != ISLAND_SLEEPING)) + { + //kinematic objects don't merge islands, but wake up all connected objects + if (colObj0->isKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING) + { + if (colObj0->hasContactResponse()) + colObj1->activate(); + } + if (colObj1->isKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING) + { + if (colObj1->hasContactResponse()) + colObj0->activate(); + } + //filtering for response + if (dispatcher->needsResponse(colObj0, colObj1)) + { + // scatter manifolds into various islands + int islandId = getIslandId(manifold); + // if island not sleeping, + if (Island* island = getIsland(islandId)) + { + island->manifoldArray.push_back(manifold); + } + } + } + } } - -void btSimulationIslandManagerMt::addConstraintsToIslands( btAlignedObjectArray& constraints ) +void btSimulationIslandManagerMt::addConstraintsToIslands(btAlignedObjectArray& constraints) { - // walk constraints - for ( int i = 0; i < constraints.size(); i++ ) - { - // scatter constraints into various islands - btTypedConstraint* constraint = constraints[ i ]; - if ( constraint->isEnabled() ) - { - int islandId = btGetConstraintIslandId( constraint ); - // if island is not sleeping, - if ( Island* island = getIsland( islandId ) ) - { - island->constraintArray.push_back( constraint ); - } - } - } + // walk constraints + for (int i = 0; i < constraints.size(); i++) + { + // scatter constraints into various islands + btTypedConstraint* constraint = constraints[i]; + if (constraint->isEnabled()) + { + int islandId = btGetConstraintIslandId(constraint); + // if island is not sleeping, + if (Island* island = getIsland(islandId)) + { + island->constraintArray.push_back(constraint); + } + } + } } - void btSimulationIslandManagerMt::mergeIslands() { - // sort islands in order of decreasing batch size - m_activeIslands.quickSort( IslandBatchSizeSortPredicate() ); + // sort islands in order of decreasing batch size + m_activeIslands.quickSort(IslandBatchSizeSortPredicate()); - // merge small islands to satisfy minimum batch size - // find first small batch island - int destIslandIndex = m_activeIslands.size(); - for ( int i = 0; i < m_activeIslands.size(); ++i ) - { - Island* island = m_activeIslands[ i ]; - int batchSize = calcBatchCost( island ); - if ( batchSize < m_minimumSolverBatchSize ) - { - destIslandIndex = i; - break; - } - } - int lastIndex = m_activeIslands.size() - 1; - while ( destIslandIndex < lastIndex ) - { - // merge islands from the back of the list - Island* island = m_activeIslands[ destIslandIndex ]; - int numBodies = island->bodyArray.size(); - int numManifolds = island->manifoldArray.size(); - int numConstraints = island->constraintArray.size(); - int firstIndex = lastIndex; - // figure out how many islands we want to merge and find out how many bodies, manifolds and constraints we will have - while ( true ) - { - Island* src = m_activeIslands[ firstIndex ]; - numBodies += src->bodyArray.size(); - numManifolds += src->manifoldArray.size(); - numConstraints += src->constraintArray.size(); - int batchCost = calcBatchCost( numBodies, numManifolds, numConstraints ); - if ( batchCost >= m_minimumSolverBatchSize ) - { - break; - } - if ( firstIndex - 1 == destIslandIndex ) - { - break; - } - firstIndex--; - } - // reserve space for these pointers to minimize reallocation - island->bodyArray.reserve( numBodies ); - island->manifoldArray.reserve( numManifolds ); - island->constraintArray.reserve( numConstraints ); - // merge islands - for ( int i = firstIndex; i <= lastIndex; ++i ) - { - island->append( *m_activeIslands[ i ] ); - } - // shrink array to exclude the islands that were merged from - m_activeIslands.resize( firstIndex ); - lastIndex = firstIndex - 1; - destIslandIndex++; - } + // merge small islands to satisfy minimum batch size + // find first small batch island + int destIslandIndex = m_activeIslands.size(); + for (int i = 0; i < m_activeIslands.size(); ++i) + { + Island* island = m_activeIslands[i]; + int batchSize = calcBatchCost(island); + if (batchSize < m_minimumSolverBatchSize) + { + destIslandIndex = i; + break; + } + } + int lastIndex = m_activeIslands.size() - 1; + while (destIslandIndex < lastIndex) + { + // merge islands from the back of the list + Island* island = m_activeIslands[destIslandIndex]; + int numBodies = island->bodyArray.size(); + int numManifolds = island->manifoldArray.size(); + int numConstraints = island->constraintArray.size(); + int firstIndex = lastIndex; + // figure out how many islands we want to merge and find out how many bodies, manifolds and constraints we will have + while (true) + { + Island* src = m_activeIslands[firstIndex]; + numBodies += src->bodyArray.size(); + numManifolds += src->manifoldArray.size(); + numConstraints += src->constraintArray.size(); + int batchCost = calcBatchCost(numBodies, numManifolds, numConstraints); + if (batchCost >= m_minimumSolverBatchSize) + { + break; + } + if (firstIndex - 1 == destIslandIndex) + { + break; + } + firstIndex--; + } + // reserve space for these pointers to minimize reallocation + island->bodyArray.reserve(numBodies); + island->manifoldArray.reserve(numManifolds); + island->constraintArray.reserve(numConstraints); + // merge islands + for (int i = firstIndex; i <= lastIndex; ++i) + { + island->append(*m_activeIslands[i]); + } + // shrink array to exclude the islands that were merged from + m_activeIslands.resize(firstIndex); + lastIndex = firstIndex - 1; + destIslandIndex++; + } } - void btSimulationIslandManagerMt::solveIsland(btConstraintSolver* solver, Island& island, const SolverParams& solverParams) { - btPersistentManifold** manifolds = island.manifoldArray.size() ? &island.manifoldArray[ 0 ] : NULL; - btTypedConstraint** constraintsPtr = island.constraintArray.size() ? &island.constraintArray[ 0 ] : NULL; - solver->solveGroup( &island.bodyArray[ 0 ], - island.bodyArray.size(), - manifolds, - island.manifoldArray.size(), - constraintsPtr, - island.constraintArray.size(), - *solverParams.m_solverInfo, - solverParams.m_debugDrawer, - solverParams.m_dispatcher - ); + btPersistentManifold** manifolds = island.manifoldArray.size() ? &island.manifoldArray[0] : NULL; + btTypedConstraint** constraintsPtr = island.constraintArray.size() ? &island.constraintArray[0] : NULL; + solver->solveGroup(&island.bodyArray[0], + island.bodyArray.size(), + manifolds, + island.manifoldArray.size(), + constraintsPtr, + island.constraintArray.size(), + *solverParams.m_solverInfo, + solverParams.m_debugDrawer, + solverParams.m_dispatcher); } - -void btSimulationIslandManagerMt::serialIslandDispatch( btAlignedObjectArray* islandsPtr, const SolverParams& solverParams ) +void btSimulationIslandManagerMt::serialIslandDispatch(btAlignedObjectArray* islandsPtr, const SolverParams& solverParams) { - BT_PROFILE( "serialIslandDispatch" ); - // serial dispatch - btAlignedObjectArray& islands = *islandsPtr; - btConstraintSolver* solver = solverParams.m_solverMt ? solverParams.m_solverMt : solverParams.m_solverPool; - for ( int i = 0; i < islands.size(); ++i ) - { - solveIsland(solver, *islands[ i ], solverParams); - } + BT_PROFILE("serialIslandDispatch"); + // serial dispatch + btAlignedObjectArray& islands = *islandsPtr; + btConstraintSolver* solver = solverParams.m_solverMt ? solverParams.m_solverMt : solverParams.m_solverPool; + for (int i = 0; i < islands.size(); ++i) + { + solveIsland(solver, *islands[i], solverParams); + } } - struct UpdateIslandDispatcher : public btIParallelForBody { - btAlignedObjectArray& m_islandsPtr; - const btSimulationIslandManagerMt::SolverParams& m_solverParams; + btAlignedObjectArray& m_islandsPtr; + const btSimulationIslandManagerMt::SolverParams& m_solverParams; - UpdateIslandDispatcher(btAlignedObjectArray& islandsPtr, const btSimulationIslandManagerMt::SolverParams& solverParams) - : m_islandsPtr(islandsPtr), m_solverParams(solverParams) - {} + UpdateIslandDispatcher(btAlignedObjectArray& islandsPtr, const btSimulationIslandManagerMt::SolverParams& solverParams) + : m_islandsPtr(islandsPtr), m_solverParams(solverParams) + { + } - void forLoop( int iBegin, int iEnd ) const BT_OVERRIDE - { - btConstraintSolver* solver = m_solverParams.m_solverPool; - for ( int i = iBegin; i < iEnd; ++i ) - { - btSimulationIslandManagerMt::Island* island = m_islandsPtr[ i ]; - btSimulationIslandManagerMt::solveIsland( solver, *island, m_solverParams ); - } - } + void forLoop(int iBegin, int iEnd) const BT_OVERRIDE + { + btConstraintSolver* solver = m_solverParams.m_solverPool; + for (int i = iBegin; i < iEnd; ++i) + { + btSimulationIslandManagerMt::Island* island = m_islandsPtr[i]; + btSimulationIslandManagerMt::solveIsland(solver, *island, m_solverParams); + } + } }; - -void btSimulationIslandManagerMt::parallelIslandDispatch( btAlignedObjectArray* islandsPtr, const SolverParams& solverParams ) +void btSimulationIslandManagerMt::parallelIslandDispatch(btAlignedObjectArray* islandsPtr, const SolverParams& solverParams) { - BT_PROFILE( "parallelIslandDispatch" ); - // - // if there are islands with many contacts, it may be faster to submit these - // large islands *serially* to a single parallel constraint solver, and then later - // submit the remaining smaller islands in parallel to multiple sequential solvers. - // - // Some task schedulers do not deal well with nested parallelFor loops. One implementation - // of OpenMP was actually slower than doing everything single-threaded. Intel TBB - // on the other hand, seems to do a pretty respectable job with it. - // - // When solving islands in parallel, the worst case performance happens when there - // is one very large island and then perhaps a smattering of very small - // islands -- one worker thread takes the large island and the remaining workers - // tear through the smaller islands and then sit idle waiting for the first worker - // to finish. Solving islands in parallel works best when there are numerous small - // islands, roughly equal in size. - // - // By contrast, the other approach -- the parallel constraint solver -- is only - // able to deliver a worthwhile speedup when the island is large. For smaller islands, - // it is difficult to extract a useful amount of parallelism -- the overhead of grouping - // the constraints into batches and sending the batches to worker threads can nullify - // any gains from parallelism. - // + BT_PROFILE("parallelIslandDispatch"); + // + // if there are islands with many contacts, it may be faster to submit these + // large islands *serially* to a single parallel constraint solver, and then later + // submit the remaining smaller islands in parallel to multiple sequential solvers. + // + // Some task schedulers do not deal well with nested parallelFor loops. One implementation + // of OpenMP was actually slower than doing everything single-threaded. Intel TBB + // on the other hand, seems to do a pretty respectable job with it. + // + // When solving islands in parallel, the worst case performance happens when there + // is one very large island and then perhaps a smattering of very small + // islands -- one worker thread takes the large island and the remaining workers + // tear through the smaller islands and then sit idle waiting for the first worker + // to finish. Solving islands in parallel works best when there are numerous small + // islands, roughly equal in size. + // + // By contrast, the other approach -- the parallel constraint solver -- is only + // able to deliver a worthwhile speedup when the island is large. For smaller islands, + // it is difficult to extract a useful amount of parallelism -- the overhead of grouping + // the constraints into batches and sending the batches to worker threads can nullify + // any gains from parallelism. + // - UpdateIslandDispatcher dispatcher(*islandsPtr, solverParams); - // We take advantage of the fact the islands are sorted in order of decreasing size - int iBegin = 0; - if (solverParams.m_solverMt) - { - while ( iBegin < islandsPtr->size() ) - { - btSimulationIslandManagerMt::Island* island = ( *islandsPtr )[ iBegin ]; - if ( island->manifoldArray.size() < btSequentialImpulseConstraintSolverMt::s_minimumContactManifoldsForBatching ) - { - // OK to submit the rest of the array in parallel - break; - } - // serial dispatch to parallel solver for large islands (if any) - solveIsland(solverParams.m_solverMt, *island, solverParams); - ++iBegin; - } - } - // parallel dispatch to sequential solvers for rest - btParallelFor( iBegin, islandsPtr->size(), 1, dispatcher ); + UpdateIslandDispatcher dispatcher(*islandsPtr, solverParams); + // We take advantage of the fact the islands are sorted in order of decreasing size + int iBegin = 0; + if (solverParams.m_solverMt) + { + while (iBegin < islandsPtr->size()) + { + btSimulationIslandManagerMt::Island* island = (*islandsPtr)[iBegin]; + if (island->manifoldArray.size() < btSequentialImpulseConstraintSolverMt::s_minimumContactManifoldsForBatching) + { + // OK to submit the rest of the array in parallel + break; + } + // serial dispatch to parallel solver for large islands (if any) + solveIsland(solverParams.m_solverMt, *island, solverParams); + ++iBegin; + } + } + // parallel dispatch to sequential solvers for rest + btParallelFor(iBegin, islandsPtr->size(), 1, dispatcher); } - ///@todo: this is random access, it can be walked 'cache friendly'! -void btSimulationIslandManagerMt::buildAndProcessIslands( btDispatcher* dispatcher, - btCollisionWorld* collisionWorld, - btAlignedObjectArray& constraints, - const SolverParams& solverParams - ) +void btSimulationIslandManagerMt::buildAndProcessIslands(btDispatcher* dispatcher, + btCollisionWorld* collisionWorld, + btAlignedObjectArray& constraints, + const SolverParams& solverParams) { BT_PROFILE("buildAndProcessIslands"); btCollisionObjectArray& collisionObjects = collisionWorld->getCollisionObjectArray(); - buildIslands(dispatcher,collisionWorld); + buildIslands(dispatcher, collisionWorld); - if(!getSplitIslands()) + if (!getSplitIslands()) { - btPersistentManifold** manifolds = dispatcher->getInternalManifoldPointer(); - int maxNumManifolds = dispatcher->getNumManifolds(); + btPersistentManifold** manifolds = dispatcher->getInternalManifoldPointer(); + int maxNumManifolds = dispatcher->getNumManifolds(); - for ( int i = 0; i < maxNumManifolds; i++ ) - { - btPersistentManifold* manifold = manifolds[ i ]; + for (int i = 0; i < maxNumManifolds; i++) + { + btPersistentManifold* manifold = manifolds[i]; - const btCollisionObject* colObj0 = static_cast( manifold->getBody0() ); - const btCollisionObject* colObj1 = static_cast( manifold->getBody1() ); + const btCollisionObject* colObj0 = static_cast(manifold->getBody0()); + const btCollisionObject* colObj1 = static_cast(manifold->getBody1()); - ///@todo: check sleeping conditions! - if ( ( ( colObj0 ) && colObj0->getActivationState() != ISLAND_SLEEPING ) || - ( ( colObj1 ) && colObj1->getActivationState() != ISLAND_SLEEPING ) ) - { - - //kinematic objects don't merge islands, but wake up all connected objects - if ( colObj0->isKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING ) - { - if ( colObj0->hasContactResponse() ) - colObj1->activate(); - } - if ( colObj1->isKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING ) - { - if ( colObj1->hasContactResponse() ) - colObj0->activate(); - } - } - } - btTypedConstraint** constraintsPtr = constraints.size() ? &constraints[ 0 ] : NULL; - btConstraintSolver* solver = solverParams.m_solverMt ? solverParams.m_solverMt : solverParams.m_solverPool; - solver->solveGroup(&collisionObjects[0], - collisionObjects.size(), - manifolds, - maxNumManifolds, - constraintsPtr, - constraints.size(), - *solverParams.m_solverInfo, - solverParams.m_debugDrawer, - solverParams.m_dispatcher - ); + ///@todo: check sleeping conditions! + if (((colObj0) && colObj0->getActivationState() != ISLAND_SLEEPING) || + ((colObj1) && colObj1->getActivationState() != ISLAND_SLEEPING)) + { + //kinematic objects don't merge islands, but wake up all connected objects + if (colObj0->isKinematicObject() && colObj0->getActivationState() != ISLAND_SLEEPING) + { + if (colObj0->hasContactResponse()) + colObj1->activate(); + } + if (colObj1->isKinematicObject() && colObj1->getActivationState() != ISLAND_SLEEPING) + { + if (colObj1->hasContactResponse()) + colObj0->activate(); + } + } + } + btTypedConstraint** constraintsPtr = constraints.size() ? &constraints[0] : NULL; + btConstraintSolver* solver = solverParams.m_solverMt ? solverParams.m_solverMt : solverParams.m_solverPool; + solver->solveGroup(&collisionObjects[0], + collisionObjects.size(), + manifolds, + maxNumManifolds, + constraintsPtr, + constraints.size(), + *solverParams.m_solverInfo, + solverParams.m_debugDrawer, + solverParams.m_dispatcher); } else { - initIslandPools(); + initIslandPools(); - //traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated - addBodiesToIslands( collisionWorld ); - addManifoldsToIslands( dispatcher ); - addConstraintsToIslands( constraints ); + //traverse the simulation islands, and call the solver, unless all objects are sleeping/deactivated + addBodiesToIslands(collisionWorld); + addManifoldsToIslands(dispatcher); + addConstraintsToIslands(constraints); - // m_activeIslands array should now contain all non-sleeping Islands, and each Island should - // have all the necessary bodies, manifolds and constraints. + // m_activeIslands array should now contain all non-sleeping Islands, and each Island should + // have all the necessary bodies, manifolds and constraints. - // if we want to merge islands with small batch counts, - if ( m_minimumSolverBatchSize > 1 ) - { - mergeIslands(); - } - // dispatch islands to solver - m_islandDispatch( &m_activeIslands, solverParams ); + // if we want to merge islands with small batch counts, + if (m_minimumSolverBatchSize > 1) + { + mergeIslands(); + } + // dispatch islands to solver + m_islandDispatch(&m_activeIslands, solverParams); } } diff --git a/src/BulletDynamics/Dynamics/btSimulationIslandManagerMt.h b/src/BulletDynamics/Dynamics/btSimulationIslandManagerMt.h index 563577a6f..ab73a899f 100644 --- a/src/BulletDynamics/Dynamics/btSimulationIslandManagerMt.h +++ b/src/BulletDynamics/Dynamics/btSimulationIslandManagerMt.h @@ -35,80 +35,78 @@ class btIDebugDraw; class btSimulationIslandManagerMt : public btSimulationIslandManager { public: - struct Island - { - // a simulation island consisting of bodies, manifolds and constraints, - // to be passed into a constraint solver. - btAlignedObjectArray bodyArray; - btAlignedObjectArray manifoldArray; - btAlignedObjectArray constraintArray; - int id; // island id - bool isSleeping; + struct Island + { + // a simulation island consisting of bodies, manifolds and constraints, + // to be passed into a constraint solver. + btAlignedObjectArray bodyArray; + btAlignedObjectArray manifoldArray; + btAlignedObjectArray constraintArray; + int id; // island id + bool isSleeping; - void append( const Island& other ); // add bodies, manifolds, constraints to my own - }; - struct SolverParams - { - btConstraintSolver* m_solverPool; - btConstraintSolver* m_solverMt; - btContactSolverInfo* m_solverInfo; - btIDebugDraw* m_debugDrawer; - btDispatcher* m_dispatcher; - }; - static void solveIsland(btConstraintSolver* solver, Island& island, const SolverParams& solverParams); + void append(const Island& other); // add bodies, manifolds, constraints to my own + }; + struct SolverParams + { + btConstraintSolver* m_solverPool; + btConstraintSolver* m_solverMt; + btContactSolverInfo* m_solverInfo; + btIDebugDraw* m_debugDrawer; + btDispatcher* m_dispatcher; + }; + static void solveIsland(btConstraintSolver* solver, Island& island, const SolverParams& solverParams); + + typedef void (*IslandDispatchFunc)(btAlignedObjectArray* islands, const SolverParams& solverParams); + static void serialIslandDispatch(btAlignedObjectArray* islandsPtr, const SolverParams& solverParams); + static void parallelIslandDispatch(btAlignedObjectArray* islandsPtr, const SolverParams& solverParams); - typedef void( *IslandDispatchFunc ) ( btAlignedObjectArray* islands, const SolverParams& solverParams ); - static void serialIslandDispatch( btAlignedObjectArray* islandsPtr, const SolverParams& solverParams ); - static void parallelIslandDispatch( btAlignedObjectArray* islandsPtr, const SolverParams& solverParams ); protected: - btAlignedObjectArray m_allocatedIslands; // owner of all Islands - btAlignedObjectArray m_activeIslands; // islands actively in use - btAlignedObjectArray m_freeIslands; // islands ready to be reused - btAlignedObjectArray m_lookupIslandFromId; // big lookup table to map islandId to Island pointer - Island* m_batchIsland; - int m_minimumSolverBatchSize; - int m_batchIslandMinBodyCount; - IslandDispatchFunc m_islandDispatch; + btAlignedObjectArray m_allocatedIslands; // owner of all Islands + btAlignedObjectArray m_activeIslands; // islands actively in use + btAlignedObjectArray m_freeIslands; // islands ready to be reused + btAlignedObjectArray m_lookupIslandFromId; // big lookup table to map islandId to Island pointer + Island* m_batchIsland; + int m_minimumSolverBatchSize; + int m_batchIslandMinBodyCount; + IslandDispatchFunc m_islandDispatch; + + Island* getIsland(int id); + virtual Island* allocateIsland(int id, int numBodies); + virtual void initIslandPools(); + virtual void addBodiesToIslands(btCollisionWorld* collisionWorld); + virtual void addManifoldsToIslands(btDispatcher* dispatcher); + virtual void addConstraintsToIslands(btAlignedObjectArray& constraints); + virtual void mergeIslands(); - Island* getIsland( int id ); - virtual Island* allocateIsland( int id, int numBodies ); - virtual void initIslandPools(); - virtual void addBodiesToIslands( btCollisionWorld* collisionWorld ); - virtual void addManifoldsToIslands( btDispatcher* dispatcher ); - virtual void addConstraintsToIslands( btAlignedObjectArray& constraints ); - virtual void mergeIslands(); - public: btSimulationIslandManagerMt(); virtual ~btSimulationIslandManagerMt(); - virtual void buildAndProcessIslands( btDispatcher* dispatcher, - btCollisionWorld* collisionWorld, - btAlignedObjectArray& constraints, - const SolverParams& solverParams - ); + virtual void buildAndProcessIslands(btDispatcher* dispatcher, + btCollisionWorld* collisionWorld, + btAlignedObjectArray& constraints, + const SolverParams& solverParams); - virtual void buildIslands(btDispatcher* dispatcher,btCollisionWorld* colWorld); + virtual void buildIslands(btDispatcher* dispatcher, btCollisionWorld* colWorld); - int getMinimumSolverBatchSize() const - { - return m_minimumSolverBatchSize; - } - void setMinimumSolverBatchSize( int sz ) - { - m_minimumSolverBatchSize = sz; - } - IslandDispatchFunc getIslandDispatchFunction() const - { - return m_islandDispatch; - } - // allow users to set their own dispatch function for multithreaded dispatch - void setIslandDispatchFunction( IslandDispatchFunc func ) - { - m_islandDispatch = func; - } + int getMinimumSolverBatchSize() const + { + return m_minimumSolverBatchSize; + } + void setMinimumSolverBatchSize(int sz) + { + m_minimumSolverBatchSize = sz; + } + IslandDispatchFunc getIslandDispatchFunction() const + { + return m_islandDispatch; + } + // allow users to set their own dispatch function for multithreaded dispatch + void setIslandDispatchFunction(IslandDispatchFunc func) + { + m_islandDispatch = func; + } }; - -#endif //BT_SIMULATION_ISLAND_MANAGER_H - +#endif //BT_SIMULATION_ISLAND_MANAGER_H diff --git a/src/BulletDynamics/Featherstone/btMultiBody.cpp b/src/BulletDynamics/Featherstone/btMultiBody.cpp index 34fe4b8de..60ebfc9ee 100644 --- a/src/BulletDynamics/Featherstone/btMultiBody.cpp +++ b/src/BulletDynamics/Featherstone/btMultiBody.cpp @@ -21,7 +21,6 @@ */ - #include "btMultiBody.h" #include "btMultiBodyLink.h" #include "btMultiBodyLinkCollider.h" @@ -29,28 +28,30 @@ #include "LinearMath/btTransformUtil.h" #include "LinearMath/btSerializer.h" //#include "Bullet3Common/b3Logging.h" -// #define INCLUDE_GYRO_TERM +// #define INCLUDE_GYRO_TERM ///todo: determine if we need these options. If so, make a proper API, otherwise delete those globals bool gJointFeedbackInWorldSpace = false; bool gJointFeedbackInJointFrame = false; -namespace { - const btScalar SLEEP_EPSILON = btScalar(0.05); // this is a squared velocity (m^2 s^-2) - const btScalar SLEEP_TIMEOUT = btScalar(2); // in seconds -} +namespace +{ +const btScalar SLEEP_EPSILON = btScalar(0.05); // this is a squared velocity (m^2 s^-2) +const btScalar SLEEP_TIMEOUT = btScalar(2); // in seconds +} // namespace -namespace { - void SpatialTransform(const btMatrix3x3 &rotation_matrix, // rotates vectors in 'from' frame to vectors in 'to' frame - const btVector3 &displacement, // vector from origin of 'from' frame to origin of 'to' frame, in 'to' coordinates - const btVector3 &top_in, // top part of input vector - const btVector3 &bottom_in, // bottom part of input vector - btVector3 &top_out, // top part of output vector - btVector3 &bottom_out) // bottom part of output vector - { - top_out = rotation_matrix * top_in; - bottom_out = -displacement.cross(top_out) + rotation_matrix * bottom_in; - } +namespace +{ +void SpatialTransform(const btMatrix3x3 &rotation_matrix, // rotates vectors in 'from' frame to vectors in 'to' frame + const btVector3 &displacement, // vector from origin of 'from' frame to origin of 'to' frame, in 'to' coordinates + const btVector3 &top_in, // top part of input vector + const btVector3 &bottom_in, // bottom part of input vector + btVector3 &top_out, // top part of output vector + btVector3 &bottom_out) // bottom part of output vector +{ + top_out = rotation_matrix * top_in; + bottom_out = -displacement.cross(top_out) + rotation_matrix * bottom_in; +} #if 0 void InverseSpatialTransform(const btMatrix3x3 &rotation_matrix, @@ -83,60 +84,58 @@ namespace { bottom_out = a_bottom.cross(b_top) + a_top.cross(b_bottom); } #endif - -} +} // namespace // // Implementation of class btMultiBody // btMultiBody::btMultiBody(int n_links, - btScalar mass, - const btVector3 &inertia, - bool fixedBase, - bool canSleep, - bool /*deprecatedUseMultiDof*/) - : - m_baseCollider(0), - m_baseName(0), - m_basePos(0,0,0), - m_baseQuat(0, 0, 0, 1), - m_baseMass(mass), - m_baseInertia(inertia), - - m_fixedBase(fixedBase), - m_awake(true), - m_canSleep(canSleep), - m_sleepTimer(0), - m_userObjectPointer(0), - m_userIndex2(-1), - m_userIndex(-1), - m_companionId(-1), - m_linearDamping(0.04f), - m_angularDamping(0.04f), - m_useGyroTerm(true), - m_maxAppliedImpulse(1000.f), - m_maxCoordinateVelocity(100.f), - m_hasSelfCollision(true), - __posUpdated(false), - m_dofCount(0), - m_posVarCnt(0), - m_useRK4(false), - m_useGlobalVelocities(false), - m_internalNeedsJointFeedback(false) + btScalar mass, + const btVector3 &inertia, + bool fixedBase, + bool canSleep, + bool /*deprecatedUseMultiDof*/) + : m_baseCollider(0), + m_baseName(0), + m_basePos(0, 0, 0), + m_baseQuat(0, 0, 0, 1), + m_baseMass(mass), + m_baseInertia(inertia), + + m_fixedBase(fixedBase), + m_awake(true), + m_canSleep(canSleep), + m_sleepTimer(0), + m_userObjectPointer(0), + m_userIndex2(-1), + m_userIndex(-1), + m_companionId(-1), + m_linearDamping(0.04f), + m_angularDamping(0.04f), + m_useGyroTerm(true), + m_maxAppliedImpulse(1000.f), + m_maxCoordinateVelocity(100.f), + m_hasSelfCollision(true), + __posUpdated(false), + m_dofCount(0), + m_posVarCnt(0), + m_useRK4(false), + m_useGlobalVelocities(false), + m_internalNeedsJointFeedback(false) { - m_cachedInertiaTopLeft.setValue(0,0,0,0,0,0,0,0,0); - m_cachedInertiaTopRight.setValue(0,0,0,0,0,0,0,0,0); - m_cachedInertiaLowerLeft.setValue(0,0,0,0,0,0,0,0,0); - m_cachedInertiaLowerRight.setValue(0,0,0,0,0,0,0,0,0); - m_cachedInertiaValid=false; + m_cachedInertiaTopLeft.setValue(0, 0, 0, 0, 0, 0, 0, 0, 0); + m_cachedInertiaTopRight.setValue(0, 0, 0, 0, 0, 0, 0, 0, 0); + m_cachedInertiaLowerLeft.setValue(0, 0, 0, 0, 0, 0, 0, 0, 0); + m_cachedInertiaLowerRight.setValue(0, 0, 0, 0, 0, 0, 0, 0, 0); + m_cachedInertiaValid = false; m_links.resize(n_links); m_matrixBuf.resize(n_links + 1); - m_baseForce.setValue(0, 0, 0); - m_baseTorque.setValue(0, 0, 0); + m_baseForce.setValue(0, 0, 0); + m_baseTorque.setValue(0, 0, 0); clearConstraintForces(); clearForcesAndTorques(); @@ -147,131 +146,125 @@ btMultiBody::~btMultiBody() } void btMultiBody::setupFixed(int i, - btScalar mass, - const btVector3 &inertia, - int parent, - const btQuaternion &rotParentToThis, - const btVector3 &parentComToThisPivotOffset, - const btVector3 &thisPivotToThisComOffset, bool /*deprecatedDisableParentCollision*/) + btScalar mass, + const btVector3 &inertia, + int parent, + const btQuaternion &rotParentToThis, + const btVector3 &parentComToThisPivotOffset, + const btVector3 &thisPivotToThisComOffset, bool /*deprecatedDisableParentCollision*/) { - m_links[i].m_mass = mass; - m_links[i].m_inertiaLocal = inertia; - m_links[i].m_parent = parent; - m_links[i].setAxisTop(0, 0., 0., 0.); - m_links[i].setAxisBottom(0, btVector3(0,0,0)); - m_links[i].m_zeroRotParentToThis = rotParentToThis; + m_links[i].m_inertiaLocal = inertia; + m_links[i].m_parent = parent; + m_links[i].setAxisTop(0, 0., 0., 0.); + m_links[i].setAxisBottom(0, btVector3(0, 0, 0)); + m_links[i].m_zeroRotParentToThis = rotParentToThis; m_links[i].m_dVector = thisPivotToThisComOffset; - m_links[i].m_eVector = parentComToThisPivotOffset; + m_links[i].m_eVector = parentComToThisPivotOffset; m_links[i].m_jointType = btMultibodyLink::eFixed; m_links[i].m_dofCount = 0; m_links[i].m_posVarCount = 0; - m_links[i].m_flags |=BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION; - + m_links[i].m_flags |= BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION; + m_links[i].updateCacheMultiDof(); updateLinksDofOffsets(); - } - void btMultiBody::setupPrismatic(int i, - btScalar mass, - const btVector3 &inertia, - int parent, - const btQuaternion &rotParentToThis, - const btVector3 &jointAxis, - const btVector3 &parentComToThisPivotOffset, - const btVector3 &thisPivotToThisComOffset, - bool disableParentCollision) + btScalar mass, + const btVector3 &inertia, + int parent, + const btQuaternion &rotParentToThis, + const btVector3 &jointAxis, + const btVector3 &parentComToThisPivotOffset, + const btVector3 &thisPivotToThisComOffset, + bool disableParentCollision) { m_dofCount += 1; m_posVarCnt += 1; - - m_links[i].m_mass = mass; - m_links[i].m_inertiaLocal = inertia; - m_links[i].m_parent = parent; - m_links[i].m_zeroRotParentToThis = rotParentToThis; - m_links[i].setAxisTop(0, 0., 0., 0.); - m_links[i].setAxisBottom(0, jointAxis); - m_links[i].m_eVector = parentComToThisPivotOffset; + + m_links[i].m_mass = mass; + m_links[i].m_inertiaLocal = inertia; + m_links[i].m_parent = parent; + m_links[i].m_zeroRotParentToThis = rotParentToThis; + m_links[i].setAxisTop(0, 0., 0., 0.); + m_links[i].setAxisBottom(0, jointAxis); + m_links[i].m_eVector = parentComToThisPivotOffset; m_links[i].m_dVector = thisPivotToThisComOffset; - m_links[i].m_cachedRotParentToThis = rotParentToThis; + m_links[i].m_cachedRotParentToThis = rotParentToThis; m_links[i].m_jointType = btMultibodyLink::ePrismatic; m_links[i].m_dofCount = 1; - m_links[i].m_posVarCount = 1; + m_links[i].m_posVarCount = 1; m_links[i].m_jointPos[0] = 0.f; m_links[i].m_jointTorque[0] = 0.f; if (disableParentCollision) - m_links[i].m_flags |=BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION; + m_links[i].m_flags |= BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION; // - + m_links[i].updateCacheMultiDof(); - + updateLinksDofOffsets(); } void btMultiBody::setupRevolute(int i, - btScalar mass, - const btVector3 &inertia, - int parent, - const btQuaternion &rotParentToThis, - const btVector3 &jointAxis, - const btVector3 &parentComToThisPivotOffset, - const btVector3 &thisPivotToThisComOffset, - bool disableParentCollision) + btScalar mass, + const btVector3 &inertia, + int parent, + const btQuaternion &rotParentToThis, + const btVector3 &jointAxis, + const btVector3 &parentComToThisPivotOffset, + const btVector3 &thisPivotToThisComOffset, + bool disableParentCollision) { m_dofCount += 1; m_posVarCnt += 1; - - m_links[i].m_mass = mass; - m_links[i].m_inertiaLocal = inertia; - m_links[i].m_parent = parent; - m_links[i].m_zeroRotParentToThis = rotParentToThis; - m_links[i].setAxisTop(0, jointAxis); - m_links[i].setAxisBottom(0, jointAxis.cross(thisPivotToThisComOffset)); - m_links[i].m_dVector = thisPivotToThisComOffset; - m_links[i].m_eVector = parentComToThisPivotOffset; + + m_links[i].m_mass = mass; + m_links[i].m_inertiaLocal = inertia; + m_links[i].m_parent = parent; + m_links[i].m_zeroRotParentToThis = rotParentToThis; + m_links[i].setAxisTop(0, jointAxis); + m_links[i].setAxisBottom(0, jointAxis.cross(thisPivotToThisComOffset)); + m_links[i].m_dVector = thisPivotToThisComOffset; + m_links[i].m_eVector = parentComToThisPivotOffset; m_links[i].m_jointType = btMultibodyLink::eRevolute; m_links[i].m_dofCount = 1; - m_links[i].m_posVarCount = 1; + m_links[i].m_posVarCount = 1; m_links[i].m_jointPos[0] = 0.f; m_links[i].m_jointTorque[0] = 0.f; if (disableParentCollision) - m_links[i].m_flags |=BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION; - // + m_links[i].m_flags |= BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION; + // m_links[i].updateCacheMultiDof(); // updateLinksDofOffsets(); } - - void btMultiBody::setupSpherical(int i, - btScalar mass, - const btVector3 &inertia, - int parent, - const btQuaternion &rotParentToThis, - const btVector3 &parentComToThisPivotOffset, - const btVector3 &thisPivotToThisComOffset, - bool disableParentCollision) + btScalar mass, + const btVector3 &inertia, + int parent, + const btQuaternion &rotParentToThis, + const btVector3 &parentComToThisPivotOffset, + const btVector3 &thisPivotToThisComOffset, + bool disableParentCollision) { - m_dofCount += 3; m_posVarCnt += 4; m_links[i].m_mass = mass; - m_links[i].m_inertiaLocal = inertia; - m_links[i].m_parent = parent; - m_links[i].m_zeroRotParentToThis = rotParentToThis; - m_links[i].m_dVector = thisPivotToThisComOffset; - m_links[i].m_eVector = parentComToThisPivotOffset; + m_links[i].m_inertiaLocal = inertia; + m_links[i].m_parent = parent; + m_links[i].m_zeroRotParentToThis = rotParentToThis; + m_links[i].m_dVector = thisPivotToThisComOffset; + m_links[i].m_eVector = parentComToThisPivotOffset; m_links[i].m_jointType = btMultibodyLink::eSpherical; m_links[i].m_dofCount = 3; @@ -282,62 +275,61 @@ void btMultiBody::setupSpherical(int i, m_links[i].setAxisBottom(0, m_links[i].getAxisTop(0).cross(thisPivotToThisComOffset)); m_links[i].setAxisBottom(1, m_links[i].getAxisTop(1).cross(thisPivotToThisComOffset)); m_links[i].setAxisBottom(2, m_links[i].getAxisTop(2).cross(thisPivotToThisComOffset)); - m_links[i].m_jointPos[0] = m_links[i].m_jointPos[1] = m_links[i].m_jointPos[2] = 0.f; m_links[i].m_jointPos[3] = 1.f; + m_links[i].m_jointPos[0] = m_links[i].m_jointPos[1] = m_links[i].m_jointPos[2] = 0.f; + m_links[i].m_jointPos[3] = 1.f; m_links[i].m_jointTorque[0] = m_links[i].m_jointTorque[1] = m_links[i].m_jointTorque[2] = 0.f; - if (disableParentCollision) - m_links[i].m_flags |=BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION; + m_links[i].m_flags |= BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION; // - m_links[i].updateCacheMultiDof(); + m_links[i].updateCacheMultiDof(); // updateLinksDofOffsets(); } void btMultiBody::setupPlanar(int i, - btScalar mass, - const btVector3 &inertia, - int parent, - const btQuaternion &rotParentToThis, - const btVector3 &rotationAxis, - const btVector3 &parentComToThisComOffset, - bool disableParentCollision) + btScalar mass, + const btVector3 &inertia, + int parent, + const btQuaternion &rotParentToThis, + const btVector3 &rotationAxis, + const btVector3 &parentComToThisComOffset, + bool disableParentCollision) { - m_dofCount += 3; m_posVarCnt += 3; m_links[i].m_mass = mass; - m_links[i].m_inertiaLocal = inertia; - m_links[i].m_parent = parent; - m_links[i].m_zeroRotParentToThis = rotParentToThis; + m_links[i].m_inertiaLocal = inertia; + m_links[i].m_parent = parent; + m_links[i].m_zeroRotParentToThis = rotParentToThis; m_links[i].m_dVector.setZero(); - m_links[i].m_eVector = parentComToThisComOffset; + m_links[i].m_eVector = parentComToThisComOffset; // btVector3 vecNonParallelToRotAxis(1, 0, 0); - if(rotationAxis.normalized().dot(vecNonParallelToRotAxis) > 0.999) + if (rotationAxis.normalized().dot(vecNonParallelToRotAxis) > 0.999) vecNonParallelToRotAxis.setValue(0, 1, 0); // m_links[i].m_jointType = btMultibodyLink::ePlanar; m_links[i].m_dofCount = 3; m_links[i].m_posVarCount = 3; - btVector3 n=rotationAxis.normalized(); - m_links[i].setAxisTop(0, n[0],n[1],n[2]); - m_links[i].setAxisTop(1,0,0,0); - m_links[i].setAxisTop(2,0,0,0); - m_links[i].setAxisBottom(0,0,0,0); + btVector3 n = rotationAxis.normalized(); + m_links[i].setAxisTop(0, n[0], n[1], n[2]); + m_links[i].setAxisTop(1, 0, 0, 0); + m_links[i].setAxisTop(2, 0, 0, 0); + m_links[i].setAxisBottom(0, 0, 0, 0); btVector3 cr = m_links[i].getAxisTop(0).cross(vecNonParallelToRotAxis); - m_links[i].setAxisBottom(1,cr[0],cr[1],cr[2]); + m_links[i].setAxisBottom(1, cr[0], cr[1], cr[2]); cr = m_links[i].getAxisBottom(1).cross(m_links[i].getAxisTop(0)); - m_links[i].setAxisBottom(2,cr[0],cr[1],cr[2]); + m_links[i].setAxisBottom(2, cr[0], cr[1], cr[2]); m_links[i].m_jointPos[0] = m_links[i].m_jointPos[1] = m_links[i].m_jointPos[2] = 0.f; m_links[i].m_jointTorque[0] = m_links[i].m_jointTorque[1] = m_links[i].m_jointTorque[2] = 0.f; if (disableParentCollision) - m_links[i].m_flags |=BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION; - // + m_links[i].m_flags |= BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION; + // m_links[i].updateCacheMultiDof(); // updateLinksDofOffsets(); @@ -347,202 +339,208 @@ void btMultiBody::finalizeMultiDof() { m_deltaV.resize(0); m_deltaV.resize(6 + m_dofCount); - m_realBuf.resize(6 + m_dofCount + m_dofCount*m_dofCount + 6 + m_dofCount); //m_dofCount for joint-space vels + m_dofCount^2 for "D" matrices + delta-pos vector (6 base "vels" + joint "vels") - m_vectorBuf.resize(2 * m_dofCount); //two 3-vectors (i.e. one six-vector) for each system dof ("h" matrices) - for (int i=0;i=-1); - btAssert(i=m_links.size())) + btAssert(i >= -1); + btAssert(i < m_links.size()); + if ((i < -1) || (i >= m_links.size())) { - return btVector3(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY); + return btVector3(SIMD_INFINITY, SIMD_INFINITY, SIMD_INFINITY); } - btVector3 result = local_pos; - while (i != -1) { - // 'result' is in frame i. transform it to frame parent(i) - result += getRVector(i); - result = quatRotate(getParentToLocalRot(i).inverse(),result); - i = getParent(i); - } + btVector3 result = local_pos; + while (i != -1) + { + // 'result' is in frame i. transform it to frame parent(i) + result += getRVector(i); + result = quatRotate(getParentToLocalRot(i).inverse(), result); + i = getParent(i); + } - // 'result' is now in the base frame. transform it to world frame - result = quatRotate(getWorldToBaseRot().inverse() ,result); - result += getBasePos(); + // 'result' is now in the base frame. transform it to world frame + result = quatRotate(getWorldToBaseRot().inverse(), result); + result += getBasePos(); - return result; + return result; } btVector3 btMultiBody::worldPosToLocal(int i, const btVector3 &world_pos) const { - btAssert(i>=-1); - btAssert(i=m_links.size())) + btAssert(i >= -1); + btAssert(i < m_links.size()); + if ((i < -1) || (i >= m_links.size())) { - return btVector3(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY); + return btVector3(SIMD_INFINITY, SIMD_INFINITY, SIMD_INFINITY); } - if (i == -1) { - // world to base - return quatRotate(getWorldToBaseRot(),(world_pos - getBasePos())); - } else { - // find position in parent frame, then transform to current frame - return quatRotate(getParentToLocalRot(i),worldPosToLocal(getParent(i), world_pos)) - getRVector(i); - } + if (i == -1) + { + // world to base + return quatRotate(getWorldToBaseRot(), (world_pos - getBasePos())); + } + else + { + // find position in parent frame, then transform to current frame + return quatRotate(getParentToLocalRot(i), worldPosToLocal(getParent(i), world_pos)) - getRVector(i); + } } btVector3 btMultiBody::localDirToWorld(int i, const btVector3 &local_dir) const { - btAssert(i>=-1); - btAssert(i=m_links.size())) + btAssert(i >= -1); + btAssert(i < m_links.size()); + if ((i < -1) || (i >= m_links.size())) { - return btVector3(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY); + return btVector3(SIMD_INFINITY, SIMD_INFINITY, SIMD_INFINITY); } - - btVector3 result = local_dir; - while (i != -1) { - result = quatRotate(getParentToLocalRot(i).inverse() , result); - i = getParent(i); - } - result = quatRotate(getWorldToBaseRot().inverse() , result); - return result; + btVector3 result = local_dir; + while (i != -1) + { + result = quatRotate(getParentToLocalRot(i).inverse(), result); + i = getParent(i); + } + result = quatRotate(getWorldToBaseRot().inverse(), result); + return result; } btVector3 btMultiBody::worldDirToLocal(int i, const btVector3 &world_dir) const { - btAssert(i>=-1); - btAssert(i=m_links.size())) + btAssert(i >= -1); + btAssert(i < m_links.size()); + if ((i < -1) || (i >= m_links.size())) { - return btVector3(SIMD_INFINITY,SIMD_INFINITY,SIMD_INFINITY); + return btVector3(SIMD_INFINITY, SIMD_INFINITY, SIMD_INFINITY); } - if (i == -1) { - return quatRotate(getWorldToBaseRot(), world_dir); - } else { - return quatRotate(getParentToLocalRot(i) ,worldDirToLocal(getParent(i), world_dir)); - } + if (i == -1) + { + return quatRotate(getWorldToBaseRot(), world_dir); + } + else + { + return quatRotate(getParentToLocalRot(i), worldDirToLocal(getParent(i), world_dir)); + } } btMatrix3x3 btMultiBody::localFrameToWorld(int i, const btMatrix3x3 &local_frame) const { - btMatrix3x3 result = local_frame; - btVector3 frameInWorld0 = localDirToWorld(i, local_frame.getColumn(0)); - btVector3 frameInWorld1 = localDirToWorld(i, local_frame.getColumn(1)); - btVector3 frameInWorld2 = localDirToWorld(i, local_frame.getColumn(2)); - result.setValue(frameInWorld0[0], frameInWorld1[0], frameInWorld2[0], frameInWorld0[1], frameInWorld1[1], frameInWorld2[1], frameInWorld0[2], frameInWorld1[2], frameInWorld2[2]); - return result; + btMatrix3x3 result = local_frame; + btVector3 frameInWorld0 = localDirToWorld(i, local_frame.getColumn(0)); + btVector3 frameInWorld1 = localDirToWorld(i, local_frame.getColumn(1)); + btVector3 frameInWorld2 = localDirToWorld(i, local_frame.getColumn(2)); + result.setValue(frameInWorld0[0], frameInWorld1[0], frameInWorld2[0], frameInWorld0[1], frameInWorld1[1], frameInWorld2[1], frameInWorld0[2], frameInWorld1[2], frameInWorld2[2]); + return result; } void btMultiBody::compTreeLinkVelocities(btVector3 *omega, btVector3 *vel) const { int num_links = getNumLinks(); - // Calculates the velocities of each link (and the base) in its local frame - omega[0] = quatRotate(m_baseQuat ,getBaseOmega()); - vel[0] = quatRotate(m_baseQuat ,getBaseVel()); - - for (int i = 0; i < num_links; ++i) + // Calculates the velocities of each link (and the base) in its local frame + omega[0] = quatRotate(m_baseQuat, getBaseOmega()); + vel[0] = quatRotate(m_baseQuat, getBaseVel()); + + for (int i = 0; i < num_links; ++i) { - const int parent = m_links[i].m_parent; + const int parent = m_links[i].m_parent; - // transform parent vel into this frame, store in omega[i+1], vel[i+1] - SpatialTransform(btMatrix3x3(m_links[i].m_cachedRotParentToThis), m_links[i].m_cachedRVector, - omega[parent+1], vel[parent+1], - omega[i+1], vel[i+1]); + // transform parent vel into this frame, store in omega[i+1], vel[i+1] + SpatialTransform(btMatrix3x3(m_links[i].m_cachedRotParentToThis), m_links[i].m_cachedRVector, + omega[parent + 1], vel[parent + 1], + omega[i + 1], vel[i + 1]); - // now add qidot * shat_i + // now add qidot * shat_i //only supported for revolute/prismatic joints, todo: spherical and planar joints - switch(m_links[i].m_jointType) + switch (m_links[i].m_jointType) { case btMultibodyLink::ePrismatic: case btMultibodyLink::eRevolute: @@ -550,8 +548,8 @@ void btMultiBody::compTreeLinkVelocities(btVector3 *omega, btVector3 *vel) const btVector3 axisTop = m_links[i].getAxisTop(0); btVector3 axisBottom = m_links[i].getAxisBottom(0); btScalar jointVel = getJointVel(i); - omega[i+1] += jointVel * axisTop; - vel[i+1] += jointVel * axisBottom; + omega[i + 1] += jointVel * axisTop; + vel[i + 1] += jointVel * axisBottom; break; } default: @@ -564,41 +562,48 @@ void btMultiBody::compTreeLinkVelocities(btVector3 *omega, btVector3 *vel) const btScalar btMultiBody::getKineticEnergy() const { int num_links = getNumLinks(); - // TODO: would be better not to allocate memory here - btAlignedObjectArray omega;omega.resize(num_links+1); - btAlignedObjectArray vel;vel.resize(num_links+1); - compTreeLinkVelocities(&omega[0], &vel[0]); + // TODO: would be better not to allocate memory here + btAlignedObjectArray omega; + omega.resize(num_links + 1); + btAlignedObjectArray vel; + vel.resize(num_links + 1); + compTreeLinkVelocities(&omega[0], &vel[0]); - // we will do the factor of 0.5 at the end - btScalar result = m_baseMass * vel[0].dot(vel[0]); - result += omega[0].dot(m_baseInertia * omega[0]); - - for (int i = 0; i < num_links; ++i) { - result += m_links[i].m_mass * vel[i+1].dot(vel[i+1]); - result += omega[i+1].dot(m_links[i].m_inertiaLocal * omega[i+1]); - } + // we will do the factor of 0.5 at the end + btScalar result = m_baseMass * vel[0].dot(vel[0]); + result += omega[0].dot(m_baseInertia * omega[0]); - return 0.5f * result; + for (int i = 0; i < num_links; ++i) + { + result += m_links[i].m_mass * vel[i + 1].dot(vel[i + 1]); + result += omega[i + 1].dot(m_links[i].m_inertiaLocal * omega[i + 1]); + } + + return 0.5f * result; } btVector3 btMultiBody::getAngularMomentum() const { int num_links = getNumLinks(); - // TODO: would be better not to allocate memory here - btAlignedObjectArray omega;omega.resize(num_links+1); - btAlignedObjectArray vel;vel.resize(num_links+1); - btAlignedObjectArray rot_from_world;rot_from_world.resize(num_links+1); - compTreeLinkVelocities(&omega[0], &vel[0]); + // TODO: would be better not to allocate memory here + btAlignedObjectArray omega; + omega.resize(num_links + 1); + btAlignedObjectArray vel; + vel.resize(num_links + 1); + btAlignedObjectArray rot_from_world; + rot_from_world.resize(num_links + 1); + compTreeLinkVelocities(&omega[0], &vel[0]); - rot_from_world[0] = m_baseQuat; - btVector3 result = quatRotate(rot_from_world[0].inverse() , (m_baseInertia * omega[0])); + rot_from_world[0] = m_baseQuat; + btVector3 result = quatRotate(rot_from_world[0].inverse(), (m_baseInertia * omega[0])); - for (int i = 0; i < num_links; ++i) { - rot_from_world[i+1] = m_links[i].m_cachedRotParentToThis * rot_from_world[m_links[i].m_parent+1]; - result += (quatRotate(rot_from_world[i+1].inverse() , (m_links[i].m_inertiaLocal * omega[i+1]))); - } + for (int i = 0; i < num_links; ++i) + { + rot_from_world[i + 1] = m_links[i].m_cachedRotParentToThis * rot_from_world[m_links[i].m_parent + 1]; + result += (quatRotate(rot_from_world[i + 1].inverse(), (m_links[i].m_inertiaLocal * omega[i + 1]))); + } - return result; + return result; } void btMultiBody::clearConstraintForces() @@ -606,57 +611,55 @@ void btMultiBody::clearConstraintForces() m_baseConstraintForce.setValue(0, 0, 0); m_baseConstraintTorque.setValue(0, 0, 0); - - for (int i = 0; i < getNumLinks(); ++i) { - m_links[i].m_appliedConstraintForce.setValue(0, 0, 0); - m_links[i].m_appliedConstraintTorque.setValue(0, 0, 0); - } + for (int i = 0; i < getNumLinks(); ++i) + { + m_links[i].m_appliedConstraintForce.setValue(0, 0, 0); + m_links[i].m_appliedConstraintTorque.setValue(0, 0, 0); + } } void btMultiBody::clearForcesAndTorques() { - m_baseForce.setValue(0, 0, 0); - m_baseTorque.setValue(0, 0, 0); + m_baseForce.setValue(0, 0, 0); + m_baseTorque.setValue(0, 0, 0); - - for (int i = 0; i < getNumLinks(); ++i) { - m_links[i].m_appliedForce.setValue(0, 0, 0); - m_links[i].m_appliedTorque.setValue(0, 0, 0); + for (int i = 0; i < getNumLinks(); ++i) + { + m_links[i].m_appliedForce.setValue(0, 0, 0); + m_links[i].m_appliedTorque.setValue(0, 0, 0); m_links[i].m_jointTorque[0] = m_links[i].m_jointTorque[1] = m_links[i].m_jointTorque[2] = m_links[i].m_jointTorque[3] = m_links[i].m_jointTorque[4] = m_links[i].m_jointTorque[5] = 0.f; - } + } } void btMultiBody::clearVelocities() { - for (int i = 0; i < 6 + getNumDofs(); ++i) + for (int i = 0; i < 6 + getNumDofs(); ++i) { m_realBuf[i] = 0.f; } } void btMultiBody::addLinkForce(int i, const btVector3 &f) { - m_links[i].m_appliedForce += f; + m_links[i].m_appliedForce += f; } void btMultiBody::addLinkTorque(int i, const btVector3 &t) { - m_links[i].m_appliedTorque += t; + m_links[i].m_appliedTorque += t; } void btMultiBody::addLinkConstraintForce(int i, const btVector3 &f) { - m_links[i].m_appliedConstraintForce += f; + m_links[i].m_appliedConstraintForce += f; } void btMultiBody::addLinkConstraintTorque(int i, const btVector3 &t) { - m_links[i].m_appliedConstraintTorque += t; + m_links[i].m_appliedConstraintTorque += t; } - - void btMultiBody::addJointTorque(int i, btScalar Q) { - m_links[i].m_jointTorque[0] += Q; + m_links[i].m_jointTorque[0] += Q; } void btMultiBody::addJointTorqueMultiDof(int i, int dof, btScalar Q) @@ -666,70 +669,70 @@ void btMultiBody::addJointTorqueMultiDof(int i, int dof, btScalar Q) void btMultiBody::addJointTorqueMultiDof(int i, const btScalar *Q) { - for(int dof = 0; dof < m_links[i].m_dofCount; ++dof) + for (int dof = 0; dof < m_links[i].m_dofCount; ++dof) m_links[i].m_jointTorque[dof] = Q[dof]; } -const btVector3 & btMultiBody::getLinkForce(int i) const +const btVector3 &btMultiBody::getLinkForce(int i) const { - return m_links[i].m_appliedForce; + return m_links[i].m_appliedForce; } -const btVector3 & btMultiBody::getLinkTorque(int i) const +const btVector3 &btMultiBody::getLinkTorque(int i) const { - return m_links[i].m_appliedTorque; + return m_links[i].m_appliedTorque; } btScalar btMultiBody::getJointTorque(int i) const { - return m_links[i].m_jointTorque[0]; + return m_links[i].m_jointTorque[0]; } -btScalar * btMultiBody::getJointTorqueMultiDof(int i) +btScalar *btMultiBody::getJointTorqueMultiDof(int i) { - return &m_links[i].m_jointTorque[0]; + return &m_links[i].m_jointTorque[0]; } -inline btMatrix3x3 outerProduct(const btVector3& v0, const btVector3& v1) //renamed it from vecMulVecTranspose (http://en.wikipedia.org/wiki/Outer_product); maybe it should be moved to btVector3 like dot and cross? +inline btMatrix3x3 outerProduct(const btVector3 &v0, const btVector3 &v1) //renamed it from vecMulVecTranspose (http://en.wikipedia.org/wiki/Outer_product); maybe it should be moved to btVector3 like dot and cross? { - btVector3 row0 = btVector3( - v0.x() * v1.x(), - v0.x() * v1.y(), - v0.x() * v1.z()); - btVector3 row1 = btVector3( - v0.y() * v1.x(), - v0.y() * v1.y(), - v0.y() * v1.z()); - btVector3 row2 = btVector3( - v0.z() * v1.x(), - v0.z() * v1.y(), - v0.z() * v1.z()); + btVector3 row0 = btVector3( + v0.x() * v1.x(), + v0.x() * v1.y(), + v0.x() * v1.z()); + btVector3 row1 = btVector3( + v0.y() * v1.x(), + v0.y() * v1.y(), + v0.y() * v1.z()); + btVector3 row2 = btVector3( + v0.z() * v1.x(), + v0.z() * v1.y(), + v0.z() * v1.z()); - btMatrix3x3 m(row0[0],row0[1],row0[2], - row1[0],row1[1],row1[2], - row2[0],row2[1],row2[2]); - return m; + btMatrix3x3 m(row0[0], row0[1], row0[2], + row1[0], row1[1], row1[2], + row2[0], row2[1], row2[2]); + return m; } #define vecMulVecTranspose(v0, v1Transposed) outerProduct(v0, v1Transposed) // void btMultiBody::computeAccelerationsArticulatedBodyAlgorithmMultiDof(btScalar dt, - btAlignedObjectArray &scratch_r, - btAlignedObjectArray &scratch_v, - btAlignedObjectArray &scratch_m, - bool isConstraintPass) + btAlignedObjectArray &scratch_r, + btAlignedObjectArray &scratch_v, + btAlignedObjectArray &scratch_m, + bool isConstraintPass) { - // Implement Featherstone's algorithm to calculate joint accelerations (q_double_dot) - // and the base linear & angular accelerations. + // Implement Featherstone's algorithm to calculate joint accelerations (q_double_dot) + // and the base linear & angular accelerations. - // We apply damping forces in this routine as well as any external forces specified by the - // caller (via addBaseForce etc). + // We apply damping forces in this routine as well as any external forces specified by the + // caller (via addBaseForce etc). + + // output should point to an array of 6 + num_links reals. + // Format is: 3 angular accelerations (in world frame), 3 linear accelerations (in world frame), + // num_links joint acceleration values. - // output should point to an array of 6 + num_links reals. - // Format is: 3 angular accelerations (in world frame), 3 linear accelerations (in world frame), - // num_links joint acceleration values. - // We added support for multi degree of freedom (multi dof) joints. // In addition we also can compute the joint reaction forces. This is performed in a second pass, // so that we can include the effect of the constraint solver forces (computed in the PGS LCP solver) @@ -738,96 +741,96 @@ void btMultiBody::computeAccelerationsArticulatedBodyAlgorithmMultiDof(btScalar int num_links = getNumLinks(); - const btScalar DAMPING_K1_LINEAR = m_linearDamping; + const btScalar DAMPING_K1_LINEAR = m_linearDamping; const btScalar DAMPING_K2_LINEAR = m_linearDamping; const btScalar DAMPING_K1_ANGULAR = m_angularDamping; - const btScalar DAMPING_K2_ANGULAR= m_angularDamping; + const btScalar DAMPING_K2_ANGULAR = m_angularDamping; const btVector3 base_vel = getBaseVel(); const btVector3 base_omega = getBaseOmega(); - // Temporary matrices/vectors -- use scratch space from caller - // so that we don't have to keep reallocating every frame + // Temporary matrices/vectors -- use scratch space from caller + // so that we don't have to keep reallocating every frame - scratch_r.resize(2*m_dofCount + 7); //multidof? ("Y"s use it and it is used to store qdd) => 2 x m_dofCount - scratch_v.resize(8*num_links + 6); - scratch_m.resize(4*num_links + 4); + scratch_r.resize(2 * m_dofCount + 7); //multidof? ("Y"s use it and it is used to store qdd) => 2 x m_dofCount + scratch_v.resize(8 * num_links + 6); + scratch_m.resize(4 * num_links + 4); //btScalar * r_ptr = &scratch_r[0]; - btScalar * output = &scratch_r[m_dofCount]; // "output" holds the q_double_dot results - btVector3 * v_ptr = &scratch_v[0]; - - // vhat_i (top = angular, bottom = linear part) + btScalar *output = &scratch_r[m_dofCount]; // "output" holds the q_double_dot results + btVector3 *v_ptr = &scratch_v[0]; + + // vhat_i (top = angular, bottom = linear part) btSpatialMotionVector *spatVel = (btSpatialMotionVector *)v_ptr; v_ptr += num_links * 2 + 2; // - // zhat_i^A - btSpatialForceVector * zeroAccSpatFrc = (btSpatialForceVector *)v_ptr; + // zhat_i^A + btSpatialForceVector *zeroAccSpatFrc = (btSpatialForceVector *)v_ptr; v_ptr += num_links * 2 + 2; // - // chat_i (note NOT defined for the base) - btSpatialMotionVector * spatCoriolisAcc = (btSpatialMotionVector *)v_ptr; + // chat_i (note NOT defined for the base) + btSpatialMotionVector *spatCoriolisAcc = (btSpatialMotionVector *)v_ptr; v_ptr += num_links * 2; // - // Ihat_i^A. - btSymmetricSpatialDyad * spatInertia = (btSymmetricSpatialDyad *)&scratch_m[num_links + 1]; + // Ihat_i^A. + btSymmetricSpatialDyad *spatInertia = (btSymmetricSpatialDyad *)&scratch_m[num_links + 1]; - // Cached 3x3 rotation matrices from parent frame to this frame. - btMatrix3x3 * rot_from_parent = &m_matrixBuf[0]; - btMatrix3x3 * rot_from_world = &scratch_m[0]; + // Cached 3x3 rotation matrices from parent frame to this frame. + btMatrix3x3 *rot_from_parent = &m_matrixBuf[0]; + btMatrix3x3 *rot_from_world = &scratch_m[0]; - // hhat_i, ahat_i - // hhat is NOT stored for the base (but ahat is) - btSpatialForceVector * h = (btSpatialForceVector *)(m_dofCount > 0 ? &m_vectorBuf[0] : 0); - btSpatialMotionVector * spatAcc = (btSpatialMotionVector *)v_ptr; - v_ptr += num_links * 2 + 2; + // hhat_i, ahat_i + // hhat is NOT stored for the base (but ahat is) + btSpatialForceVector *h = (btSpatialForceVector *)(m_dofCount > 0 ? &m_vectorBuf[0] : 0); + btSpatialMotionVector *spatAcc = (btSpatialMotionVector *)v_ptr; + v_ptr += num_links * 2 + 2; // - // Y_i, invD_i - btScalar * invD = m_dofCount > 0 ? &m_realBuf[6 + m_dofCount] : 0; - btScalar * Y = &scratch_r[0]; + // Y_i, invD_i + btScalar *invD = m_dofCount > 0 ? &m_realBuf[6 + m_dofCount] : 0; + btScalar *Y = &scratch_r[0]; // - //aux variables - btSpatialMotionVector spatJointVel; //spatial velocity due to the joint motion (i.e. without predecessors' influence) - btScalar D[36]; //"D" matrix; it's dofxdof for each body so asingle 6x6 D matrix will do - btScalar invD_times_Y[6]; //D^{-1} * Y [dofxdof x dofx1 = dofx1] <=> D^{-1} * u; better moved to buffers since it is recalced in calcAccelerationDeltasMultiDof; num_dof of btScalar would cover all bodies - btSpatialMotionVector result; //holds results of the SolveImatrix op; it is a spatial motion vector (accel) - btScalar Y_minus_hT_a[6]; //Y - h^{T} * a; it's dofx1 for each body so a single 6x1 temp is enough - btSpatialForceVector spatForceVecTemps[6]; //6 temporary spatial force vectors - btSpatialTransformationMatrix fromParent; //spatial transform from parent to child - btSymmetricSpatialDyad dyadTemp; //inertia matrix temp + //aux variables + btSpatialMotionVector spatJointVel; //spatial velocity due to the joint motion (i.e. without predecessors' influence) + btScalar D[36]; //"D" matrix; it's dofxdof for each body so asingle 6x6 D matrix will do + btScalar invD_times_Y[6]; //D^{-1} * Y [dofxdof x dofx1 = dofx1] <=> D^{-1} * u; better moved to buffers since it is recalced in calcAccelerationDeltasMultiDof; num_dof of btScalar would cover all bodies + btSpatialMotionVector result; //holds results of the SolveImatrix op; it is a spatial motion vector (accel) + btScalar Y_minus_hT_a[6]; //Y - h^{T} * a; it's dofx1 for each body so a single 6x1 temp is enough + btSpatialForceVector spatForceVecTemps[6]; //6 temporary spatial force vectors + btSpatialTransformationMatrix fromParent; //spatial transform from parent to child + btSymmetricSpatialDyad dyadTemp; //inertia matrix temp btSpatialTransformationMatrix fromWorld; fromWorld.m_trnVec.setZero(); ///////////////// - // ptr to the joint accel part of the output - btScalar * joint_accel = output + 6; + // ptr to the joint accel part of the output + btScalar *joint_accel = output + 6; - // Start of the algorithm proper. - - // First 'upward' loop. - // Combines CompTreeLinkVelocities and InitTreeLinks from Mirtich. + // Start of the algorithm proper. - rot_from_parent[0] = btMatrix3x3(m_baseQuat); //m_baseQuat assumed to be alias!? + // First 'upward' loop. + // Combines CompTreeLinkVelocities and InitTreeLinks from Mirtich. + + rot_from_parent[0] = btMatrix3x3(m_baseQuat); //m_baseQuat assumed to be alias!? //create the vector of spatial velocity of the base by transforming global-coor linear and angular velocities into base-local coordinates spatVel[0].setVector(rot_from_parent[0] * base_omega, rot_from_parent[0] * base_vel); - if (m_fixedBase) - { - zeroAccSpatFrc[0].setZero(); - } - else + if (m_fixedBase) { - const btVector3& baseForce = isConstraintPass? m_baseConstraintForce : m_baseForce; - const btVector3& baseTorque = isConstraintPass? m_baseConstraintTorque : m_baseTorque; - //external forces - zeroAccSpatFrc[0].setVector(-(rot_from_parent[0] * baseTorque), -(rot_from_parent[0] * baseForce)); + zeroAccSpatFrc[0].setZero(); + } + else + { + const btVector3 &baseForce = isConstraintPass ? m_baseConstraintForce : m_baseForce; + const btVector3 &baseTorque = isConstraintPass ? m_baseConstraintTorque : m_baseTorque; + //external forces + zeroAccSpatFrc[0].setVector(-(rot_from_parent[0] * baseTorque), -(rot_from_parent[0] * baseForce)); //adding damping terms (only) const btScalar linDampMult = 1., angDampMult = 1.; zeroAccSpatFrc[0].addVector(angDampMult * m_baseInertia * spatVel[0].getAngular() * (DAMPING_K1_ANGULAR + DAMPING_K2_ANGULAR * spatVel[0].getAngular().safeNorm()), - linDampMult * m_baseMass * spatVel[0].getLinear() * (DAMPING_K1_LINEAR + DAMPING_K2_LINEAR * spatVel[0].getLinear().safeNorm())); + linDampMult * m_baseMass * spatVel[0].getLinear() * (DAMPING_K1_LINEAR + DAMPING_K2_LINEAR * spatVel[0].getLinear().safeNorm())); // //p += vhat x Ihat vhat - done in a simpler way @@ -835,67 +838,66 @@ void btMultiBody::computeAccelerationsArticulatedBodyAlgorithmMultiDof(btScalar zeroAccSpatFrc[0].addAngular(spatVel[0].getAngular().cross(m_baseInertia * spatVel[0].getAngular())); // zeroAccSpatFrc[0].addLinear(m_baseMass * spatVel[0].getAngular().cross(spatVel[0].getLinear())); - } - + } //init the spatial AB inertia (it has the simple form thanks to choosing local body frames origins at their COMs) - spatInertia[0].setMatrix( btMatrix3x3(0,0,0,0,0,0,0,0,0), - // - btMatrix3x3(m_baseMass, 0, 0, - 0, m_baseMass, 0, - 0, 0, m_baseMass), - // - btMatrix3x3(m_baseInertia[0], 0, 0, - 0, m_baseInertia[1], 0, - 0, 0, m_baseInertia[2]) - ); + spatInertia[0].setMatrix(btMatrix3x3(0, 0, 0, 0, 0, 0, 0, 0, 0), + // + btMatrix3x3(m_baseMass, 0, 0, + 0, m_baseMass, 0, + 0, 0, m_baseMass), + // + btMatrix3x3(m_baseInertia[0], 0, 0, + 0, m_baseInertia[1], 0, + 0, 0, m_baseInertia[2])); - rot_from_world[0] = rot_from_parent[0]; + rot_from_world[0] = rot_from_parent[0]; // - for (int i = 0; i < num_links; ++i) { - const int parent = m_links[i].m_parent; - rot_from_parent[i+1] = btMatrix3x3(m_links[i].m_cachedRotParentToThis); - rot_from_world[i+1] = rot_from_parent[i+1] * rot_from_world[parent+1]; + for (int i = 0; i < num_links; ++i) + { + const int parent = m_links[i].m_parent; + rot_from_parent[i + 1] = btMatrix3x3(m_links[i].m_cachedRotParentToThis); + rot_from_world[i + 1] = rot_from_parent[i + 1] * rot_from_world[parent + 1]; - fromParent.m_rotMat = rot_from_parent[i+1]; fromParent.m_trnVec = m_links[i].m_cachedRVector; - fromWorld.m_rotMat = rot_from_world[i+1]; - fromParent.transform(spatVel[parent+1], spatVel[i+1]); + fromParent.m_rotMat = rot_from_parent[i + 1]; + fromParent.m_trnVec = m_links[i].m_cachedRVector; + fromWorld.m_rotMat = rot_from_world[i + 1]; + fromParent.transform(spatVel[parent + 1], spatVel[i + 1]); // now set vhat_i to its true value by doing - // vhat_i += qidot * shat_i - if(!m_useGlobalVelocities) + // vhat_i += qidot * shat_i + if (!m_useGlobalVelocities) { spatJointVel.setZero(); - for(int dof = 0; dof < m_links[i].m_dofCount; ++dof) + for (int dof = 0; dof < m_links[i].m_dofCount; ++dof) spatJointVel += m_links[i].m_axes[dof] * getJointVelMultiDof(i)[dof]; // remember vhat_i is really vhat_p(i) (but in current frame) at this point => we need to add velocity across the inboard joint - spatVel[i+1] += spatJointVel; + spatVel[i + 1] += spatJointVel; // // vhat_i is vhat_p(i) transformed to local coors + the velocity across the i-th inboard joint //spatVel[i+1] = fromParent * spatVel[parent+1] + spatJointVel; - } else { - fromWorld.transformRotationOnly(m_links[i].m_absFrameTotVelocity, spatVel[i+1]); + fromWorld.transformRotationOnly(m_links[i].m_absFrameTotVelocity, spatVel[i + 1]); fromWorld.transformRotationOnly(m_links[i].m_absFrameLocVelocity, spatJointVel); } - // we can now calculate chat_i - spatVel[i+1].cross(spatJointVel, spatCoriolisAcc[i]); + // we can now calculate chat_i + spatVel[i + 1].cross(spatJointVel, spatCoriolisAcc[i]); - // calculate zhat_i^A + // calculate zhat_i^A // - //external forces - btVector3 linkAppliedForce = isConstraintPass? m_links[i].m_appliedConstraintForce : m_links[i].m_appliedForce; - btVector3 linkAppliedTorque =isConstraintPass ? m_links[i].m_appliedConstraintTorque : m_links[i].m_appliedTorque; - - zeroAccSpatFrc[i+1].setVector(-(rot_from_world[i+1] * linkAppliedTorque), -(rot_from_world[i+1] * linkAppliedForce )); - + //external forces + btVector3 linkAppliedForce = isConstraintPass ? m_links[i].m_appliedConstraintForce : m_links[i].m_appliedForce; + btVector3 linkAppliedTorque = isConstraintPass ? m_links[i].m_appliedConstraintTorque : m_links[i].m_appliedTorque; + + zeroAccSpatFrc[i + 1].setVector(-(rot_from_world[i + 1] * linkAppliedTorque), -(rot_from_world[i + 1] * linkAppliedForce)); + #if 0 { @@ -913,27 +915,26 @@ void btMultiBody::computeAccelerationsArticulatedBodyAlgorithmMultiDof(btScalar // //adding damping terms (only) btScalar linDampMult = 1., angDampMult = 1.; - zeroAccSpatFrc[i+1].addVector(angDampMult * m_links[i].m_inertiaLocal * spatVel[i+1].getAngular() * (DAMPING_K1_ANGULAR + DAMPING_K2_ANGULAR * spatVel[i+1].getAngular().safeNorm()), - linDampMult * m_links[i].m_mass * spatVel[i+1].getLinear() * (DAMPING_K1_LINEAR + DAMPING_K2_LINEAR * spatVel[i+1].getLinear().safeNorm())); - - // calculate Ihat_i^A + zeroAccSpatFrc[i + 1].addVector(angDampMult * m_links[i].m_inertiaLocal * spatVel[i + 1].getAngular() * (DAMPING_K1_ANGULAR + DAMPING_K2_ANGULAR * spatVel[i + 1].getAngular().safeNorm()), + linDampMult * m_links[i].m_mass * spatVel[i + 1].getLinear() * (DAMPING_K1_LINEAR + DAMPING_K2_LINEAR * spatVel[i + 1].getLinear().safeNorm())); + + // calculate Ihat_i^A //init the spatial AB inertia (it has the simple form thanks to choosing local body frames origins at their COMs) - spatInertia[i+1].setMatrix( btMatrix3x3(0,0,0,0,0,0,0,0,0), - // - btMatrix3x3(m_links[i].m_mass, 0, 0, - 0, m_links[i].m_mass, 0, - 0, 0, m_links[i].m_mass), - // - btMatrix3x3(m_links[i].m_inertiaLocal[0], 0, 0, - 0, m_links[i].m_inertiaLocal[1], 0, - 0, 0, m_links[i].m_inertiaLocal[2]) - ); + spatInertia[i + 1].setMatrix(btMatrix3x3(0, 0, 0, 0, 0, 0, 0, 0, 0), + // + btMatrix3x3(m_links[i].m_mass, 0, 0, + 0, m_links[i].m_mass, 0, + 0, 0, m_links[i].m_mass), + // + btMatrix3x3(m_links[i].m_inertiaLocal[0], 0, 0, + 0, m_links[i].m_inertiaLocal[1], 0, + 0, 0, m_links[i].m_inertiaLocal[2])); // //p += vhat x Ihat vhat - done in a simpler way - if(m_useGyroTerm) - zeroAccSpatFrc[i+1].addAngular(spatVel[i+1].getAngular().cross(m_links[i].m_inertiaLocal * spatVel[i+1].getAngular())); - // - zeroAccSpatFrc[i+1].addLinear(m_links[i].m_mass * spatVel[i+1].getAngular().cross(spatVel[i+1].getLinear())); + if (m_useGyroTerm) + zeroAccSpatFrc[i + 1].addAngular(spatVel[i + 1].getAngular().cross(m_links[i].m_inertiaLocal * spatVel[i + 1].getAngular())); + // + zeroAccSpatFrc[i + 1].addLinear(m_links[i].m_mass * spatVel[i + 1].getAngular().cross(spatVel[i + 1].getLinear())); //btVector3 temp = m_links[i].m_mass * spatVel[i+1].getAngular().cross(spatVel[i+1].getLinear()); ////clamp parent's omega //btScalar parOmegaMod = temp.length(); @@ -944,52 +945,49 @@ void btMultiBody::computeAccelerationsArticulatedBodyAlgorithmMultiDof(btScalar //printf("|zeroAccSpatFrc[%d]| = %.4f\n", i+1, temp.length()); //temp = spatCoriolisAcc[i].getLinear(); //printf("|spatCoriolisAcc[%d]| = %.4f\n", i+1, temp.length()); - - //printf("w[%d] = [%.4f %.4f %.4f]\n", i, vel_top_angular[i+1].x(), vel_top_angular[i+1].y(), vel_top_angular[i+1].z()); - //printf("v[%d] = [%.4f %.4f %.4f]\n", i, vel_bottom_linear[i+1].x(), vel_bottom_linear[i+1].y(), vel_bottom_linear[i+1].z()); + //printf("v[%d] = [%.4f %.4f %.4f]\n", i, vel_bottom_linear[i+1].x(), vel_bottom_linear[i+1].y(), vel_bottom_linear[i+1].z()); //printf("c[%d] = [%.4f %.4f %.4f]\n", i, coriolis_bottom_linear[i].x(), coriolis_bottom_linear[i].y(), coriolis_bottom_linear[i].z()); - } - - // 'Downward' loop. - // (part of TreeForwardDynamics in Mirtich.) - for (int i = num_links - 1; i >= 0; --i) + } + + // 'Downward' loop. + // (part of TreeForwardDynamics in Mirtich.) + for (int i = num_links - 1; i >= 0; --i) { const int parent = m_links[i].m_parent; - fromParent.m_rotMat = rot_from_parent[i+1]; fromParent.m_trnVec = m_links[i].m_cachedRVector; + fromParent.m_rotMat = rot_from_parent[i + 1]; + fromParent.m_trnVec = m_links[i].m_cachedRVector; - for(int dof = 0; dof < m_links[i].m_dofCount; ++dof) + for (int dof = 0; dof < m_links[i].m_dofCount; ++dof) { btSpatialForceVector &hDof = h[m_links[i].m_dofOffset + dof]; // - hDof = spatInertia[i+1] * m_links[i].m_axes[dof]; + hDof = spatInertia[i + 1] * m_links[i].m_axes[dof]; // - Y[m_links[i].m_dofOffset + dof] = m_links[i].m_jointTorque[dof] - - m_links[i].m_axes[dof].dot(zeroAccSpatFrc[i+1]) - - spatCoriolisAcc[i].dot(hDof); - + Y[m_links[i].m_dofOffset + dof] = m_links[i].m_jointTorque[dof] - m_links[i].m_axes[dof].dot(zeroAccSpatFrc[i + 1]) - spatCoriolisAcc[i].dot(hDof); } - for(int dof = 0; dof < m_links[i].m_dofCount; ++dof) - { + for (int dof = 0; dof < m_links[i].m_dofCount; ++dof) + { btScalar *D_row = &D[dof * m_links[i].m_dofCount]; - for(int dof2 = 0; dof2 < m_links[i].m_dofCount; ++dof2) + for (int dof2 = 0; dof2 < m_links[i].m_dofCount; ++dof2) { const btSpatialForceVector &hDof2 = h[m_links[i].m_dofOffset + dof2]; D_row[dof2] = m_links[i].m_axes[dof].dot(hDof2); } } - btScalar *invDi = &invD[m_links[i].m_dofOffset*m_links[i].m_dofOffset]; - switch(m_links[i].m_jointType) + btScalar *invDi = &invD[m_links[i].m_dofOffset * m_links[i].m_dofOffset]; + switch (m_links[i].m_jointType) { case btMultibodyLink::ePrismatic: case btMultibodyLink::eRevolute: { - if (D[0]>=SIMD_EPSILON) + if (D[0] >= SIMD_EPSILON) { invDi[0] = 1.0f / D[0]; - } else + } + else { invDi[0] = 0; } @@ -1002,10 +1000,10 @@ void btMultiBody::computeAccelerationsArticulatedBodyAlgorithmMultiDof(btScalar const btMatrix3x3 invD3x3(D3x3.inverse()); //unroll the loop? - for(int row = 0; row < 3; ++row) + for (int row = 0; row < 3; ++row) { - for(int col = 0; col < 3; ++col) - { + for (int col = 0; col < 3; ++col) + { invDi[row * 3 + col] = invD3x3[row][col]; } } @@ -1014,86 +1012,82 @@ void btMultiBody::computeAccelerationsArticulatedBodyAlgorithmMultiDof(btScalar } default: { - } } //determine h*D^{-1} - for(int dof = 0; dof < m_links[i].m_dofCount; ++dof) + for (int dof = 0; dof < m_links[i].m_dofCount; ++dof) { spatForceVecTemps[dof].setZero(); - for(int dof2 = 0; dof2 < m_links[i].m_dofCount; ++dof2) - { + for (int dof2 = 0; dof2 < m_links[i].m_dofCount; ++dof2) + { const btSpatialForceVector &hDof2 = h[m_links[i].m_dofOffset + dof2]; - // + // spatForceVecTemps[dof] += hDof2 * invDi[dof2 * m_links[i].m_dofCount + dof]; } } - dyadTemp = spatInertia[i+1]; + dyadTemp = spatInertia[i + 1]; //determine (h*D^{-1}) * h^{T} - for(int dof = 0; dof < m_links[i].m_dofCount; ++dof) - { + for (int dof = 0; dof < m_links[i].m_dofCount; ++dof) + { const btSpatialForceVector &hDof = h[m_links[i].m_dofOffset + dof]; // dyadTemp -= symmetricSpatialOuterProduct(hDof, spatForceVecTemps[dof]); } - fromParent.transformInverse(dyadTemp, spatInertia[parent+1], btSpatialTransformationMatrix::Add); - - for(int dof = 0; dof < m_links[i].m_dofCount; ++dof) + fromParent.transformInverse(dyadTemp, spatInertia[parent + 1], btSpatialTransformationMatrix::Add); + + for (int dof = 0; dof < m_links[i].m_dofCount; ++dof) { invD_times_Y[dof] = 0.f; - for(int dof2 = 0; dof2 < m_links[i].m_dofCount; ++dof2) + for (int dof2 = 0; dof2 < m_links[i].m_dofCount; ++dof2) { - invD_times_Y[dof] += invDi[dof * m_links[i].m_dofCount + dof2] * Y[m_links[i].m_dofOffset + dof2]; - } + invD_times_Y[dof] += invDi[dof * m_links[i].m_dofCount + dof2] * Y[m_links[i].m_dofOffset + dof2]; + } } - - spatForceVecTemps[0] = zeroAccSpatFrc[i+1] + spatInertia[i+1] * spatCoriolisAcc[i]; - for(int dof = 0; dof < m_links[i].m_dofCount; ++dof) - { + spatForceVecTemps[0] = zeroAccSpatFrc[i + 1] + spatInertia[i + 1] * spatCoriolisAcc[i]; + + for (int dof = 0; dof < m_links[i].m_dofCount; ++dof) + { const btSpatialForceVector &hDof = h[m_links[i].m_dofOffset + dof]; // - spatForceVecTemps[0] += hDof * invD_times_Y[dof]; + spatForceVecTemps[0] += hDof * invD_times_Y[dof]; } - + fromParent.transformInverse(spatForceVecTemps[0], spatForceVecTemps[1]); - - zeroAccSpatFrc[parent+1] += spatForceVecTemps[1]; - } + zeroAccSpatFrc[parent + 1] += spatForceVecTemps[1]; + } - // Second 'upward' loop - // (part of TreeForwardDynamics in Mirtich) + // Second 'upward' loop + // (part of TreeForwardDynamics in Mirtich) - if (m_fixedBase) + if (m_fixedBase) { - spatAcc[0].setZero(); - } - else + spatAcc[0].setZero(); + } + else { - if (num_links > 0) + if (num_links > 0) { m_cachedInertiaValid = true; m_cachedInertiaTopLeft = spatInertia[0].m_topLeftMat; m_cachedInertiaTopRight = spatInertia[0].m_topRightMat; m_cachedInertiaLowerLeft = spatInertia[0].m_bottomLeftMat; - m_cachedInertiaLowerRight= spatInertia[0].m_topLeftMat.transpose(); + m_cachedInertiaLowerRight = spatInertia[0].m_topLeftMat.transpose(); + } - } - solveImatrix(zeroAccSpatFrc[0], result); spatAcc[0] = -result; - } - - - // now do the loop over the m_links - for (int i = 0; i < num_links; ++i) + } + + // now do the loop over the m_links + for (int i = 0; i < num_links; ++i) { // qdd = D^{-1} * (Y - h^{T}*apar) = (S^{T}*I*S)^{-1} * (tau - S^{T}*I*cor - S^{T}*zeroAccFrc - S^{T}*I*apar) // a = apar + cor + Sqdd @@ -1101,73 +1095,73 @@ void btMultiBody::computeAccelerationsArticulatedBodyAlgorithmMultiDof(btScalar // qdd = D^{-1} * (Y - h^{T}*(apar+cor)) // a = apar + Sqdd - const int parent = m_links[i].m_parent; - fromParent.m_rotMat = rot_from_parent[i+1]; fromParent.m_trnVec = m_links[i].m_cachedRVector; + const int parent = m_links[i].m_parent; + fromParent.m_rotMat = rot_from_parent[i + 1]; + fromParent.m_trnVec = m_links[i].m_cachedRVector; - fromParent.transform(spatAcc[parent+1], spatAcc[i+1]); - - for(int dof = 0; dof < m_links[i].m_dofCount; ++dof) + fromParent.transform(spatAcc[parent + 1], spatAcc[i + 1]); + + for (int dof = 0; dof < m_links[i].m_dofCount; ++dof) { const btSpatialForceVector &hDof = h[m_links[i].m_dofOffset + dof]; - // - Y_minus_hT_a[dof] = Y[m_links[i].m_dofOffset + dof] - spatAcc[i+1].dot(hDof); + // + Y_minus_hT_a[dof] = Y[m_links[i].m_dofOffset + dof] - spatAcc[i + 1].dot(hDof); } - btScalar *invDi = &invD[m_links[i].m_dofOffset*m_links[i].m_dofOffset]; + btScalar *invDi = &invD[m_links[i].m_dofOffset * m_links[i].m_dofOffset]; //D^{-1} * (Y - h^{T}*apar) mulMatrix(invDi, Y_minus_hT_a, m_links[i].m_dofCount, m_links[i].m_dofCount, m_links[i].m_dofCount, 1, &joint_accel[m_links[i].m_dofOffset]); - spatAcc[i+1] += spatCoriolisAcc[i]; + spatAcc[i + 1] += spatCoriolisAcc[i]; - for(int dof = 0; dof < m_links[i].m_dofCount; ++dof) - spatAcc[i+1] += m_links[i].m_axes[dof] * joint_accel[m_links[i].m_dofOffset + dof]; + for (int dof = 0; dof < m_links[i].m_dofCount; ++dof) + spatAcc[i + 1] += m_links[i].m_axes[dof] * joint_accel[m_links[i].m_dofOffset + dof]; if (m_links[i].m_jointFeedback) { m_internalNeedsJointFeedback = true; - btVector3 angularBotVec = (spatInertia[i+1]*spatAcc[i+1]+zeroAccSpatFrc[i+1]).m_bottomVec; - btVector3 linearTopVec = (spatInertia[i+1]*spatAcc[i+1]+zeroAccSpatFrc[i+1]).m_topVec; + btVector3 angularBotVec = (spatInertia[i + 1] * spatAcc[i + 1] + zeroAccSpatFrc[i + 1]).m_bottomVec; + btVector3 linearTopVec = (spatInertia[i + 1] * spatAcc[i + 1] + zeroAccSpatFrc[i + 1]).m_topVec; if (gJointFeedbackInJointFrame) { //shift the reaction forces to the joint frame //linear (force) component is the same //shift the angular (torque, moment) component using the relative position, m_links[i].m_dVector - angularBotVec = angularBotVec - linearTopVec.cross(m_links[i].m_dVector); + angularBotVec = angularBotVec - linearTopVec.cross(m_links[i].m_dVector); } - if (gJointFeedbackInWorldSpace) { if (isConstraintPass) { - m_links[i].m_jointFeedback->m_reactionForces.m_bottomVec += m_links[i].m_cachedWorldTransform.getBasis()*angularBotVec; - m_links[i].m_jointFeedback->m_reactionForces.m_topVec += m_links[i].m_cachedWorldTransform.getBasis()*linearTopVec; - } else - { - m_links[i].m_jointFeedback->m_reactionForces.m_bottomVec = m_links[i].m_cachedWorldTransform.getBasis()*angularBotVec; - m_links[i].m_jointFeedback->m_reactionForces.m_topVec = m_links[i].m_cachedWorldTransform.getBasis()*linearTopVec; - } - } else - { - if (isConstraintPass) - { - m_links[i].m_jointFeedback->m_reactionForces.m_bottomVec += angularBotVec; - m_links[i].m_jointFeedback->m_reactionForces.m_topVec += linearTopVec; - + m_links[i].m_jointFeedback->m_reactionForces.m_bottomVec += m_links[i].m_cachedWorldTransform.getBasis() * angularBotVec; + m_links[i].m_jointFeedback->m_reactionForces.m_topVec += m_links[i].m_cachedWorldTransform.getBasis() * linearTopVec; } else { - m_links[i].m_jointFeedback->m_reactionForces.m_bottomVec = angularBotVec; - m_links[i].m_jointFeedback->m_reactionForces.m_topVec = linearTopVec; - } - } + m_links[i].m_jointFeedback->m_reactionForces.m_bottomVec = m_links[i].m_cachedWorldTransform.getBasis() * angularBotVec; + m_links[i].m_jointFeedback->m_reactionForces.m_topVec = m_links[i].m_cachedWorldTransform.getBasis() * linearTopVec; + } + } + else + { + if (isConstraintPass) + { + m_links[i].m_jointFeedback->m_reactionForces.m_bottomVec += angularBotVec; + m_links[i].m_jointFeedback->m_reactionForces.m_topVec += linearTopVec; + } + else + { + m_links[i].m_jointFeedback->m_reactionForces.m_bottomVec = angularBotVec; + m_links[i].m_jointFeedback->m_reactionForces.m_topVec = linearTopVec; + } + } + } } - } - - // transform base accelerations back to the world frame. + // transform base accelerations back to the world frame. const btVector3 omegadot_out = rot_from_parent[0].transpose() * spatAcc[0].getAngular(); output[0] = omegadot_out[0]; output[1] = omegadot_out[1]; @@ -1196,26 +1190,25 @@ void btMultiBody::computeAccelerationsArticulatedBodyAlgorithmMultiDof(btScalar //printf("]\n"); ///////////////// - // Final step: add the accelerations (times dt) to the velocities. + // Final step: add the accelerations (times dt) to the velocities. if (!isConstraintPass) { - if(dt > 0.) - applyDeltaVeeMultiDof(output, dt); - + if (dt > 0.) + applyDeltaVeeMultiDof(output, dt); } ///// //btScalar angularThres = 1; - //btScalar maxAngVel = 0.; + //btScalar maxAngVel = 0.; //bool scaleDown = 1.; //for(int link = 0; link < m_links.size(); ++link) - //{ + //{ // if(spatVel[link+1].getAngular().length() > maxAngVel) // { // maxAngVel = spatVel[link+1].getAngular().length(); // scaleDown = angularThres / spatVel[link+1].getAngular().length(); // break; - // } + // } //} //if(scaleDown != 1.) @@ -1232,77 +1225,77 @@ void btMultiBody::computeAccelerationsArticulatedBodyAlgorithmMultiDof(btScalar ///// ///////////////////// - if(m_useGlobalVelocities) + if (m_useGlobalVelocities) { - for (int i = 0; i < num_links; ++i) + for (int i = 0; i < num_links; ++i) { const int parent = m_links[i].m_parent; //rot_from_parent[i+1] = btMatrix3x3(m_links[i].m_cachedRotParentToThis); /// <- done //rot_from_world[i+1] = rot_from_parent[i+1] * rot_from_world[parent+1]; /// <- done - - fromParent.m_rotMat = rot_from_parent[i+1]; fromParent.m_trnVec = m_links[i].m_cachedRVector; - fromWorld.m_rotMat = rot_from_world[i+1]; - - // vhat_i = i_xhat_p(i) * vhat_p(i) - fromParent.transform(spatVel[parent+1], spatVel[i+1]); + + fromParent.m_rotMat = rot_from_parent[i + 1]; + fromParent.m_trnVec = m_links[i].m_cachedRVector; + fromWorld.m_rotMat = rot_from_world[i + 1]; + + // vhat_i = i_xhat_p(i) * vhat_p(i) + fromParent.transform(spatVel[parent + 1], spatVel[i + 1]); //nice alternative below (using operator *) but it generates temps ///////////////////////////////////////////////////////////// // now set vhat_i to its true value by doing - // vhat_i += qidot * shat_i + // vhat_i += qidot * shat_i spatJointVel.setZero(); - for(int dof = 0; dof < m_links[i].m_dofCount; ++dof) + for (int dof = 0; dof < m_links[i].m_dofCount; ++dof) spatJointVel += m_links[i].m_axes[dof] * getJointVelMultiDof(i)[dof]; - + // remember vhat_i is really vhat_p(i) (but in current frame) at this point => we need to add velocity across the inboard joint - spatVel[i+1] += spatJointVel; + spatVel[i + 1] += spatJointVel; - - fromWorld.transformInverseRotationOnly(spatVel[i+1], m_links[i].m_absFrameTotVelocity); + fromWorld.transformInverseRotationOnly(spatVel[i + 1], m_links[i].m_absFrameTotVelocity); fromWorld.transformInverseRotationOnly(spatJointVel, m_links[i].m_absFrameLocVelocity); } } - } - - -void btMultiBody::solveImatrix(const btVector3& rhs_top, const btVector3& rhs_bot, btScalar result[6]) const +void btMultiBody::solveImatrix(const btVector3 &rhs_top, const btVector3 &rhs_bot, btScalar result[6]) const { int num_links = getNumLinks(); ///solve I * x = rhs, so the result = invI * rhs - if (num_links == 0) + if (num_links == 0) { // in the case of 0 m_links (i.e. a plain rigid body, not a multibody) rhs * invI is easier - - if ((m_baseInertia[0] >= SIMD_EPSILON) && (m_baseInertia[1] >= SIMD_EPSILON) && (m_baseInertia[2] >= SIMD_EPSILON)) - { - result[0] = rhs_bot[0] / m_baseInertia[0]; - result[1] = rhs_bot[1] / m_baseInertia[1]; - result[2] = rhs_bot[2] / m_baseInertia[2]; - } else - { - result[0] = 0; - result[1] = 0; - result[2] = 0; + + if ((m_baseInertia[0] >= SIMD_EPSILON) && (m_baseInertia[1] >= SIMD_EPSILON) && (m_baseInertia[2] >= SIMD_EPSILON)) + { + result[0] = rhs_bot[0] / m_baseInertia[0]; + result[1] = rhs_bot[1] / m_baseInertia[1]; + result[2] = rhs_bot[2] / m_baseInertia[2]; + } + else + { + result[0] = 0; + result[1] = 0; + result[2] = 0; + } + if (m_baseMass >= SIMD_EPSILON) + { + result[3] = rhs_top[0] / m_baseMass; + result[4] = rhs_top[1] / m_baseMass; + result[5] = rhs_top[2] / m_baseMass; + } + else + { + result[3] = 0; + result[4] = 0; + result[5] = 0; + } } - if (m_baseMass>=SIMD_EPSILON) - { - result[3] = rhs_top[0] / m_baseMass; - result[4] = rhs_top[1] / m_baseMass; - result[5] = rhs_top[2] / m_baseMass; - } else - { - result[3] = 0; - result[4] = 0; - result[5] = 0; - } - } else + else { if (!m_cachedInertiaValid) { - for (int i=0;i<6;i++) + for (int i = 0; i < 6; i++) { result[i] = 0.f; } @@ -1310,94 +1303,95 @@ void btMultiBody::solveImatrix(const btVector3& rhs_top, const btVector3& rhs_bo } /// Special routine for calculating the inverse of a spatial inertia matrix ///the 6x6 matrix is stored as 4 blocks of 3x3 matrices - btMatrix3x3 Binv = m_cachedInertiaTopRight.inverse()*-1.f; + btMatrix3x3 Binv = m_cachedInertiaTopRight.inverse() * -1.f; btMatrix3x3 tmp = m_cachedInertiaLowerRight * Binv; btMatrix3x3 invIupper_right = (tmp * m_cachedInertiaTopLeft + m_cachedInertiaLowerLeft).inverse(); tmp = invIupper_right * m_cachedInertiaLowerRight; btMatrix3x3 invI_upper_left = (tmp * Binv); btMatrix3x3 invI_lower_right = (invI_upper_left).transpose(); - tmp = m_cachedInertiaTopLeft * invI_upper_left; - tmp[0][0]-= 1.0; - tmp[1][1]-= 1.0; - tmp[2][2]-= 1.0; + tmp = m_cachedInertiaTopLeft * invI_upper_left; + tmp[0][0] -= 1.0; + tmp[1][1] -= 1.0; + tmp[2][2] -= 1.0; btMatrix3x3 invI_lower_left = (Binv * tmp); //multiply result = invI * rhs { - btVector3 vtop = invI_upper_left*rhs_top; - btVector3 tmp; - tmp = invIupper_right * rhs_bot; - vtop += tmp; - btVector3 vbot = invI_lower_left*rhs_top; - tmp = invI_lower_right * rhs_bot; - vbot += tmp; - result[0] = vtop[0]; - result[1] = vtop[1]; - result[2] = vtop[2]; - result[3] = vbot[0]; - result[4] = vbot[1]; - result[5] = vbot[2]; + btVector3 vtop = invI_upper_left * rhs_top; + btVector3 tmp; + tmp = invIupper_right * rhs_bot; + vtop += tmp; + btVector3 vbot = invI_lower_left * rhs_top; + tmp = invI_lower_right * rhs_bot; + vbot += tmp; + result[0] = vtop[0]; + result[1] = vtop[1]; + result[2] = vtop[2]; + result[3] = vbot[0]; + result[4] = vbot[1]; + result[5] = vbot[2]; } - - } + } } void btMultiBody::solveImatrix(const btSpatialForceVector &rhs, btSpatialMotionVector &result) const { int num_links = getNumLinks(); ///solve I * x = rhs, so the result = invI * rhs - if (num_links == 0) + if (num_links == 0) { // in the case of 0 m_links (i.e. a plain rigid body, not a multibody) rhs * invI is easier if ((m_baseInertia[0] >= SIMD_EPSILON) && (m_baseInertia[1] >= SIMD_EPSILON) && (m_baseInertia[2] >= SIMD_EPSILON)) - { - result.setAngular(rhs.getAngular() / m_baseInertia); - } else - { - result.setAngular(btVector3(0,0,0)); - } - if (m_baseMass>=SIMD_EPSILON) - { - result.setLinear(rhs.getLinear() / m_baseMass); - } else - { - result.setLinear(btVector3(0,0,0)); - } - } else + { + result.setAngular(rhs.getAngular() / m_baseInertia); + } + else + { + result.setAngular(btVector3(0, 0, 0)); + } + if (m_baseMass >= SIMD_EPSILON) + { + result.setLinear(rhs.getLinear() / m_baseMass); + } + else + { + result.setLinear(btVector3(0, 0, 0)); + } + } + else { /// Special routine for calculating the inverse of a spatial inertia matrix ///the 6x6 matrix is stored as 4 blocks of 3x3 matrices if (!m_cachedInertiaValid) { - result.setLinear(btVector3(0,0,0)); - result.setAngular(btVector3(0,0,0)); - result.setVector(btVector3(0,0,0),btVector3(0,0,0)); + result.setLinear(btVector3(0, 0, 0)); + result.setAngular(btVector3(0, 0, 0)); + result.setVector(btVector3(0, 0, 0), btVector3(0, 0, 0)); return; } - btMatrix3x3 Binv = m_cachedInertiaTopRight.inverse()*-1.f; + btMatrix3x3 Binv = m_cachedInertiaTopRight.inverse() * -1.f; btMatrix3x3 tmp = m_cachedInertiaLowerRight * Binv; btMatrix3x3 invIupper_right = (tmp * m_cachedInertiaTopLeft + m_cachedInertiaLowerLeft).inverse(); tmp = invIupper_right * m_cachedInertiaLowerRight; btMatrix3x3 invI_upper_left = (tmp * Binv); btMatrix3x3 invI_lower_right = (invI_upper_left).transpose(); - tmp = m_cachedInertiaTopLeft * invI_upper_left; - tmp[0][0]-= 1.0; - tmp[1][1]-= 1.0; - tmp[2][2]-= 1.0; + tmp = m_cachedInertiaTopLeft * invI_upper_left; + tmp[0][0] -= 1.0; + tmp[1][1] -= 1.0; + tmp[2][2] -= 1.0; btMatrix3x3 invI_lower_left = (Binv * tmp); //multiply result = invI * rhs { - btVector3 vtop = invI_upper_left*rhs.getLinear(); - btVector3 tmp; - tmp = invIupper_right * rhs.getAngular(); - vtop += tmp; - btVector3 vbot = invI_lower_left*rhs.getLinear(); - tmp = invI_lower_right * rhs.getAngular(); - vbot += tmp; - result.setVector(vtop, vbot); + btVector3 vtop = invI_upper_left * rhs.getLinear(); + btVector3 tmp; + tmp = invIupper_right * rhs.getAngular(); + vtop += tmp; + btVector3 vbot = invI_lower_left * rhs.getLinear(); + tmp = invI_lower_right * rhs.getAngular(); + vbot += tmp; + result.setVector(vtop, vbot); } - - } + } } void btMultiBody::mulMatrix(btScalar *pA, btScalar *pB, int rowsA, int colsA, int rowsB, int colsB, btScalar *pC) const @@ -1416,155 +1410,152 @@ void btMultiBody::mulMatrix(btScalar *pA, btScalar *pB, int rowsA, int colsA, in } void btMultiBody::calcAccelerationDeltasMultiDof(const btScalar *force, btScalar *output, - btAlignedObjectArray &scratch_r, btAlignedObjectArray &scratch_v) const + btAlignedObjectArray &scratch_r, btAlignedObjectArray &scratch_v) const { - // Temporary matrices/vectors -- use scratch space from caller - // so that we don't have to keep reallocating every frame + // Temporary matrices/vectors -- use scratch space from caller + // so that we don't have to keep reallocating every frame - - int num_links = getNumLinks(); - scratch_r.resize(m_dofCount); - scratch_v.resize(4*num_links + 4); + int num_links = getNumLinks(); + scratch_r.resize(m_dofCount); + scratch_v.resize(4 * num_links + 4); - btScalar * r_ptr = m_dofCount ? &scratch_r[0] : 0; - btVector3 * v_ptr = &scratch_v[0]; + btScalar *r_ptr = m_dofCount ? &scratch_r[0] : 0; + btVector3 *v_ptr = &scratch_v[0]; - // zhat_i^A (scratch space) - btSpatialForceVector * zeroAccSpatFrc = (btSpatialForceVector *)v_ptr; + // zhat_i^A (scratch space) + btSpatialForceVector *zeroAccSpatFrc = (btSpatialForceVector *)v_ptr; v_ptr += num_links * 2 + 2; - // rot_from_parent (cached from calcAccelerations) - const btMatrix3x3 * rot_from_parent = &m_matrixBuf[0]; + // rot_from_parent (cached from calcAccelerations) + const btMatrix3x3 *rot_from_parent = &m_matrixBuf[0]; - // hhat (cached), accel (scratch) - // hhat is NOT stored for the base (but ahat is) - const btSpatialForceVector * h = (btSpatialForceVector *)(m_dofCount > 0 ? &m_vectorBuf[0] : 0); - btSpatialMotionVector * spatAcc = (btSpatialMotionVector *)v_ptr; + // hhat (cached), accel (scratch) + // hhat is NOT stored for the base (but ahat is) + const btSpatialForceVector *h = (btSpatialForceVector *)(m_dofCount > 0 ? &m_vectorBuf[0] : 0); + btSpatialMotionVector *spatAcc = (btSpatialMotionVector *)v_ptr; v_ptr += num_links * 2 + 2; - // Y_i (scratch), invD_i (cached) - const btScalar * invD = m_dofCount > 0 ? &m_realBuf[6 + m_dofCount] : 0; - btScalar * Y = r_ptr; + // Y_i (scratch), invD_i (cached) + const btScalar *invD = m_dofCount > 0 ? &m_realBuf[6 + m_dofCount] : 0; + btScalar *Y = r_ptr; //////////////// //aux variables - btScalar invD_times_Y[6]; //D^{-1} * Y [dofxdof x dofx1 = dofx1] <=> D^{-1} * u; better moved to buffers since it is recalced in calcAccelerationDeltasMultiDof; num_dof of btScalar would cover all bodies - btSpatialMotionVector result; //holds results of the SolveImatrix op; it is a spatial motion vector (accel) - btScalar Y_minus_hT_a[6]; //Y - h^{T} * a; it's dofx1 for each body so a single 6x1 temp is enough - btSpatialForceVector spatForceVecTemps[6]; //6 temporary spatial force vectors - btSpatialTransformationMatrix fromParent; + btScalar invD_times_Y[6]; //D^{-1} * Y [dofxdof x dofx1 = dofx1] <=> D^{-1} * u; better moved to buffers since it is recalced in calcAccelerationDeltasMultiDof; num_dof of btScalar would cover all bodies + btSpatialMotionVector result; //holds results of the SolveImatrix op; it is a spatial motion vector (accel) + btScalar Y_minus_hT_a[6]; //Y - h^{T} * a; it's dofx1 for each body so a single 6x1 temp is enough + btSpatialForceVector spatForceVecTemps[6]; //6 temporary spatial force vectors + btSpatialTransformationMatrix fromParent; ///////////////// - // First 'upward' loop. - // Combines CompTreeLinkVelocities and InitTreeLinks from Mirtich. - + // First 'upward' loop. + // Combines CompTreeLinkVelocities and InitTreeLinks from Mirtich. + // Fill in zero_acc - // -- set to force/torque on the base, zero otherwise - if (m_fixedBase) + // -- set to force/torque on the base, zero otherwise + if (m_fixedBase) + { + zeroAccSpatFrc[0].setZero(); + } + else { - zeroAccSpatFrc[0].setZero(); - } else - { //test forces fromParent.m_rotMat = rot_from_parent[0]; - fromParent.transformRotationOnly(btSpatialForceVector(-force[0],-force[1],-force[2], -force[3],-force[4],-force[5]), zeroAccSpatFrc[0]); - } - for (int i = 0; i < num_links; ++i) + fromParent.transformRotationOnly(btSpatialForceVector(-force[0], -force[1], -force[2], -force[3], -force[4], -force[5]), zeroAccSpatFrc[0]); + } + for (int i = 0; i < num_links; ++i) { - zeroAccSpatFrc[i+1].setZero(); - } + zeroAccSpatFrc[i + 1].setZero(); + } // 'Downward' loop. - // (part of TreeForwardDynamics in Mirtich.) - for (int i = num_links - 1; i >= 0; --i) + // (part of TreeForwardDynamics in Mirtich.) + for (int i = num_links - 1; i >= 0; --i) { const int parent = m_links[i].m_parent; - fromParent.m_rotMat = rot_from_parent[i+1]; fromParent.m_trnVec = m_links[i].m_cachedRVector; + fromParent.m_rotMat = rot_from_parent[i + 1]; + fromParent.m_trnVec = m_links[i].m_cachedRVector; - for(int dof = 0; dof < m_links[i].m_dofCount; ++dof) + for (int dof = 0; dof < m_links[i].m_dofCount; ++dof) { - Y[m_links[i].m_dofOffset + dof] = force[6 + m_links[i].m_dofOffset + dof] - - m_links[i].m_axes[dof].dot(zeroAccSpatFrc[i+1]) - ; + Y[m_links[i].m_dofOffset + dof] = force[6 + m_links[i].m_dofOffset + dof] - m_links[i].m_axes[dof].dot(zeroAccSpatFrc[i + 1]); } btVector3 in_top, in_bottom, out_top, out_bottom; - const btScalar *invDi = &invD[m_links[i].m_dofOffset*m_links[i].m_dofOffset]; - - for(int dof = 0; dof < m_links[i].m_dofCount; ++dof) + const btScalar *invDi = &invD[m_links[i].m_dofOffset * m_links[i].m_dofOffset]; + + for (int dof = 0; dof < m_links[i].m_dofCount; ++dof) { invD_times_Y[dof] = 0.f; - for(int dof2 = 0; dof2 < m_links[i].m_dofCount; ++dof2) + for (int dof2 = 0; dof2 < m_links[i].m_dofCount; ++dof2) { - invD_times_Y[dof] += invDi[dof * m_links[i].m_dofCount + dof2] * Y[m_links[i].m_dofOffset + dof2]; - } + invD_times_Y[dof] += invDi[dof * m_links[i].m_dofCount + dof2] * Y[m_links[i].m_dofOffset + dof2]; + } } - - // Zp += pXi * (Zi + hi*Yi/Di) - spatForceVecTemps[0] = zeroAccSpatFrc[i+1]; - for(int dof = 0; dof < m_links[i].m_dofCount; ++dof) + // Zp += pXi * (Zi + hi*Yi/Di) + spatForceVecTemps[0] = zeroAccSpatFrc[i + 1]; + + for (int dof = 0; dof < m_links[i].m_dofCount; ++dof) { const btSpatialForceVector &hDof = h[m_links[i].m_dofOffset + dof]; // - spatForceVecTemps[0] += hDof * invD_times_Y[dof]; + spatForceVecTemps[0] += hDof * invD_times_Y[dof]; } - fromParent.transformInverse(spatForceVecTemps[0], spatForceVecTemps[1]); - - zeroAccSpatFrc[parent+1] += spatForceVecTemps[1]; - } - + + zeroAccSpatFrc[parent + 1] += spatForceVecTemps[1]; + } + // ptr to the joint accel part of the output - btScalar * joint_accel = output + 6; + btScalar *joint_accel = output + 6; + // Second 'upward' loop + // (part of TreeForwardDynamics in Mirtich) - // Second 'upward' loop - // (part of TreeForwardDynamics in Mirtich) - - if (m_fixedBase) + if (m_fixedBase) { - spatAcc[0].setZero(); - } - else + spatAcc[0].setZero(); + } + else { solveImatrix(zeroAccSpatFrc[0], result); spatAcc[0] = -result; + } - } - - // now do the loop over the m_links - for (int i = 0; i < num_links; ++i) + // now do the loop over the m_links + for (int i = 0; i < num_links; ++i) { - const int parent = m_links[i].m_parent; - fromParent.m_rotMat = rot_from_parent[i+1]; fromParent.m_trnVec = m_links[i].m_cachedRVector; + const int parent = m_links[i].m_parent; + fromParent.m_rotMat = rot_from_parent[i + 1]; + fromParent.m_trnVec = m_links[i].m_cachedRVector; - fromParent.transform(spatAcc[parent+1], spatAcc[i+1]); - - for(int dof = 0; dof < m_links[i].m_dofCount; ++dof) + fromParent.transform(spatAcc[parent + 1], spatAcc[i + 1]); + + for (int dof = 0; dof < m_links[i].m_dofCount; ++dof) { const btSpatialForceVector &hDof = h[m_links[i].m_dofOffset + dof]; - // - Y_minus_hT_a[dof] = Y[m_links[i].m_dofOffset + dof] - spatAcc[i+1].dot(hDof); + // + Y_minus_hT_a[dof] = Y[m_links[i].m_dofOffset + dof] - spatAcc[i + 1].dot(hDof); } - const btScalar *invDi = &invD[m_links[i].m_dofOffset*m_links[i].m_dofOffset]; - mulMatrix(const_cast(invDi), Y_minus_hT_a, m_links[i].m_dofCount, m_links[i].m_dofCount, m_links[i].m_dofCount, 1, &joint_accel[m_links[i].m_dofOffset]); + const btScalar *invDi = &invD[m_links[i].m_dofOffset * m_links[i].m_dofOffset]; + mulMatrix(const_cast(invDi), Y_minus_hT_a, m_links[i].m_dofCount, m_links[i].m_dofCount, m_links[i].m_dofCount, 1, &joint_accel[m_links[i].m_dofOffset]); - for(int dof = 0; dof < m_links[i].m_dofCount; ++dof) - spatAcc[i+1] += m_links[i].m_axes[dof] * joint_accel[m_links[i].m_dofOffset + dof]; - } + for (int dof = 0; dof < m_links[i].m_dofCount; ++dof) + spatAcc[i + 1] += m_links[i].m_axes[dof] * joint_accel[m_links[i].m_dofOffset + dof]; + } - // transform base accelerations back to the world frame. - btVector3 omegadot_out; - omegadot_out = rot_from_parent[0].transpose() * spatAcc[0].getAngular(); + // transform base accelerations back to the world frame. + btVector3 omegadot_out; + omegadot_out = rot_from_parent[0].transpose() * spatAcc[0].getAngular(); output[0] = omegadot_out[0]; output[1] = omegadot_out[1]; output[2] = omegadot_out[2]; - btVector3 vdot_out; - vdot_out = rot_from_parent[0].transpose() * spatAcc[0].getLinear(); + btVector3 vdot_out; + vdot_out = rot_from_parent[0].transpose() * spatAcc[0].getLinear(); output[3] = vdot_out[0]; output[4] = vdot_out[1]; output[5] = vdot_out[2]; @@ -1577,19 +1568,16 @@ void btMultiBody::calcAccelerationDeltasMultiDof(const btScalar *force, btScalar ///////////////// } - - - void btMultiBody::stepPositionsMultiDof(btScalar dt, btScalar *pq, btScalar *pqd) -{ +{ int num_links = getNumLinks(); - // step position by adding dt * velocity - //btVector3 v = getBaseVel(); - //m_basePos += dt * v; + // step position by adding dt * velocity + //btVector3 v = getBaseVel(); + //m_basePos += dt * v; // btScalar *pBasePos = (pq ? &pq[4] : m_basePos); - btScalar *pBaseVel = (pqd ? &pqd[3] : &m_realBuf[3]); //note: the !pqd case assumes m_realBuf holds with base velocity at 3,4,5 (should be wrapped for safety) - // + btScalar *pBaseVel = (pqd ? &pqd[3] : &m_realBuf[3]); //note: the !pqd case assumes m_realBuf holds with base velocity at 3,4,5 (should be wrapped for safety) + // pBasePos[0] += dt * pBaseVel[0]; pBasePos[1] += dt * pBaseVel[1]; pBasePos[2] += dt * pBaseVel[2]; @@ -1599,92 +1587,98 @@ void btMultiBody::stepPositionsMultiDof(btScalar dt, btScalar *pq, btScalar *pqd struct { //"exponential map" based on btTransformUtil::integrateTransform(..) - void operator() (const btVector3 &omega, btQuaternion &quat, bool baseBody, btScalar dt) + void operator()(const btVector3 &omega, btQuaternion &quat, bool baseBody, btScalar dt) { //baseBody => quat is alias and omega is global coor - //!baseBody => quat is alibi and omega is local coor - + //!baseBody => quat is alibi and omega is local coor + btVector3 axis; btVector3 angvel; - if(!baseBody) - angvel = quatRotate(quat, omega); //if quat is not m_baseQuat, it is alibi => ok + if (!baseBody) + angvel = quatRotate(quat, omega); //if quat is not m_baseQuat, it is alibi => ok else angvel = omega; - - btScalar fAngle = angvel.length(); + + btScalar fAngle = angvel.length(); //limit the angular motion if (fAngle * dt > ANGULAR_MOTION_THRESHOLD) { - fAngle = btScalar(0.5)*SIMD_HALF_PI / dt; + fAngle = btScalar(0.5) * SIMD_HALF_PI / dt; } - if ( fAngle < btScalar(0.001) ) + if (fAngle < btScalar(0.001)) { // use Taylor's expansions of sync function - axis = angvel*( btScalar(0.5)*dt-(dt*dt*dt)*(btScalar(0.020833333333))*fAngle*fAngle ); + axis = angvel * (btScalar(0.5) * dt - (dt * dt * dt) * (btScalar(0.020833333333)) * fAngle * fAngle); } else { // sync(fAngle) = sin(c*fAngle)/t - axis = angvel*( btSin(btScalar(0.5)*fAngle*dt)/fAngle ); + axis = angvel * (btSin(btScalar(0.5) * fAngle * dt) / fAngle); } - - if(!baseBody) - quat = btQuaternion(axis.x(),axis.y(),axis.z(),btCos( fAngle*dt*btScalar(0.5) )) * quat; - else - quat = quat * btQuaternion(-axis.x(),-axis.y(),-axis.z(),btCos( fAngle*dt*btScalar(0.5) )); - //equivalent to: quat = (btQuaternion(axis.x(),axis.y(),axis.z(),btCos( fAngle*dt*btScalar(0.5) )) * quat.inverse()).inverse(); - + + if (!baseBody) + quat = btQuaternion(axis.x(), axis.y(), axis.z(), btCos(fAngle * dt * btScalar(0.5))) * quat; + else + quat = quat * btQuaternion(-axis.x(), -axis.y(), -axis.z(), btCos(fAngle * dt * btScalar(0.5))); + //equivalent to: quat = (btQuaternion(axis.x(),axis.y(),axis.z(),btCos( fAngle*dt*btScalar(0.5) )) * quat.inverse()).inverse(); + quat.normalize(); } } pQuatUpdateFun; /////////////////////////////// //pQuatUpdateFun(getBaseOmega(), m_baseQuat, true, dt); - // - btScalar *pBaseQuat = pq ? pq : m_baseQuat; - btScalar *pBaseOmega = pqd ? pqd : &m_realBuf[0]; //note: the !pqd case assumes m_realBuf starts with base omega (should be wrapped for safety) // - btQuaternion baseQuat; baseQuat.setValue(pBaseQuat[0], pBaseQuat[1], pBaseQuat[2], pBaseQuat[3]); - btVector3 baseOmega; baseOmega.setValue(pBaseOmega[0], pBaseOmega[1], pBaseOmega[2]); + btScalar *pBaseQuat = pq ? pq : m_baseQuat; + btScalar *pBaseOmega = pqd ? pqd : &m_realBuf[0]; //note: the !pqd case assumes m_realBuf starts with base omega (should be wrapped for safety) + // + btQuaternion baseQuat; + baseQuat.setValue(pBaseQuat[0], pBaseQuat[1], pBaseQuat[2], pBaseQuat[3]); + btVector3 baseOmega; + baseOmega.setValue(pBaseOmega[0], pBaseOmega[1], pBaseOmega[2]); pQuatUpdateFun(baseOmega, baseQuat, true, dt); pBaseQuat[0] = baseQuat.x(); pBaseQuat[1] = baseQuat.y(); pBaseQuat[2] = baseQuat.z(); pBaseQuat[3] = baseQuat.w(); - //printf("pBaseOmega = %.4f %.4f %.4f\n", pBaseOmega->x(), pBaseOmega->y(), pBaseOmega->z()); //printf("pBaseVel = %.4f %.4f %.4f\n", pBaseVel->x(), pBaseVel->y(), pBaseVel->z()); //printf("baseQuat = %.4f %.4f %.4f %.4f\n", pBaseQuat->x(), pBaseQuat->y(), pBaseQuat->z(), pBaseQuat->w()); - if(pq) + if (pq) pq += 7; - if(pqd) + if (pqd) pqd += 6; // Finally we can update m_jointPos for each of the m_links - for (int i = 0; i < num_links; ++i) + for (int i = 0; i < num_links; ++i) { - btScalar *pJointPos = (pq ? pq : &m_links[i].m_jointPos[0]); + btScalar *pJointPos = (pq ? pq : &m_links[i].m_jointPos[0]); btScalar *pJointVel = (pqd ? pqd : getJointVelMultiDof(i)); - switch(m_links[i].m_jointType) + switch (m_links[i].m_jointType) { case btMultibodyLink::ePrismatic: case btMultibodyLink::eRevolute: { - btScalar jointVel = pJointVel[0]; + btScalar jointVel = pJointVel[0]; pJointPos[0] += dt * jointVel; break; } case btMultibodyLink::eSpherical: { - btVector3 jointVel; jointVel.setValue(pJointVel[0], pJointVel[1], pJointVel[2]); - btQuaternion jointOri; jointOri.setValue(pJointPos[0], pJointPos[1], pJointPos[2], pJointPos[3]); + btVector3 jointVel; + jointVel.setValue(pJointVel[0], pJointVel[1], pJointVel[2]); + btQuaternion jointOri; + jointOri.setValue(pJointPos[0], pJointPos[1], pJointPos[2], pJointPos[3]); pQuatUpdateFun(jointVel, jointOri, false, dt); - pJointPos[0] = jointOri.x(); pJointPos[1] = jointOri.y(); pJointPos[2] = jointOri.z(); pJointPos[3] = jointOri.w(); + pJointPos[0] = jointOri.x(); + pJointPos[1] = jointOri.y(); + pJointPos[2] = jointOri.z(); + pJointPos[3] = jointOri.w(); break; } case btMultibodyLink::ePlanar: @@ -1701,122 +1695,124 @@ void btMultiBody::stepPositionsMultiDof(btScalar dt, btScalar *pq, btScalar *pqd default: { } - } m_links[i].updateCacheMultiDof(pq); - if(pq) + if (pq) pq += m_links[i].m_posVarCount; - if(pqd) + if (pqd) pqd += m_links[i].m_dofCount; - } + } } void btMultiBody::fillConstraintJacobianMultiDof(int link, - const btVector3 &contact_point, - const btVector3 &normal_ang, - const btVector3 &normal_lin, - btScalar *jac, - btAlignedObjectArray &scratch_r, - btAlignedObjectArray &scratch_v, - btAlignedObjectArray &scratch_m) const + const btVector3 &contact_point, + const btVector3 &normal_ang, + const btVector3 &normal_lin, + btScalar *jac, + btAlignedObjectArray &scratch_r, + btAlignedObjectArray &scratch_v, + btAlignedObjectArray &scratch_m) const { - // temporary space + // temporary space int num_links = getNumLinks(); int m_dofCount = getNumDofs(); - scratch_v.resize(3*num_links + 3); //(num_links + base) offsets + (num_links + base) normals_lin + (num_links + base) normals_ang - scratch_m.resize(num_links + 1); + scratch_v.resize(3 * num_links + 3); //(num_links + base) offsets + (num_links + base) normals_lin + (num_links + base) normals_ang + scratch_m.resize(num_links + 1); - btVector3 * v_ptr = &scratch_v[0]; - btVector3 * p_minus_com_local = v_ptr; v_ptr += num_links + 1; - btVector3 * n_local_lin = v_ptr; v_ptr += num_links + 1; - btVector3 * n_local_ang = v_ptr; v_ptr += num_links + 1; - btAssert(v_ptr - &scratch_v[0] == scratch_v.size()); + btVector3 *v_ptr = &scratch_v[0]; + btVector3 *p_minus_com_local = v_ptr; + v_ptr += num_links + 1; + btVector3 *n_local_lin = v_ptr; + v_ptr += num_links + 1; + btVector3 *n_local_ang = v_ptr; + v_ptr += num_links + 1; + btAssert(v_ptr - &scratch_v[0] == scratch_v.size()); - scratch_r.resize(m_dofCount); - btScalar * results = m_dofCount > 0 ? &scratch_r[0] : 0; + scratch_r.resize(m_dofCount); + btScalar *results = m_dofCount > 0 ? &scratch_r[0] : 0; - btMatrix3x3 * rot_from_world = &scratch_m[0]; + btMatrix3x3 *rot_from_world = &scratch_m[0]; - const btVector3 p_minus_com_world = contact_point - m_basePos; - const btVector3 &normal_lin_world = normal_lin; //convenience + const btVector3 p_minus_com_world = contact_point - m_basePos; + const btVector3 &normal_lin_world = normal_lin; //convenience const btVector3 &normal_ang_world = normal_ang; - rot_from_world[0] = btMatrix3x3(m_baseQuat); - - // omega coeffients first. - btVector3 omega_coeffs_world; - omega_coeffs_world = p_minus_com_world.cross(normal_lin_world); + rot_from_world[0] = btMatrix3x3(m_baseQuat); + + // omega coeffients first. + btVector3 omega_coeffs_world; + omega_coeffs_world = p_minus_com_world.cross(normal_lin_world); jac[0] = omega_coeffs_world[0] + normal_ang_world[0]; jac[1] = omega_coeffs_world[1] + normal_ang_world[1]; jac[2] = omega_coeffs_world[2] + normal_ang_world[2]; - // then v coefficients - jac[3] = normal_lin_world[0]; - jac[4] = normal_lin_world[1]; - jac[5] = normal_lin_world[2]; + // then v coefficients + jac[3] = normal_lin_world[0]; + jac[4] = normal_lin_world[1]; + jac[5] = normal_lin_world[2]; //create link-local versions of p_minus_com and normal p_minus_com_local[0] = rot_from_world[0] * p_minus_com_world; - n_local_lin[0] = rot_from_world[0] * normal_lin_world; + n_local_lin[0] = rot_from_world[0] * normal_lin_world; n_local_ang[0] = rot_from_world[0] * normal_ang_world; - // Set remaining jac values to zero for now. - for (int i = 6; i < 6 + m_dofCount; ++i) + // Set remaining jac values to zero for now. + for (int i = 6; i < 6 + m_dofCount; ++i) { - jac[i] = 0; - } + jac[i] = 0; + } - // Qdot coefficients, if necessary. - if (num_links > 0 && link > -1) { + // Qdot coefficients, if necessary. + if (num_links > 0 && link > -1) + { + // TODO: speed this up -- don't calculate for m_links we don't need. + // (Also, we are making 3 separate calls to this function, for the normal & the 2 friction directions, + // which is resulting in repeated work being done...) - // TODO: speed this up -- don't calculate for m_links we don't need. - // (Also, we are making 3 separate calls to this function, for the normal & the 2 friction directions, - // which is resulting in repeated work being done...) + // calculate required normals & positions in the local frames. + for (int i = 0; i < num_links; ++i) + { + // transform to local frame + const int parent = m_links[i].m_parent; + const btMatrix3x3 mtx(m_links[i].m_cachedRotParentToThis); + rot_from_world[i + 1] = mtx * rot_from_world[parent + 1]; - // calculate required normals & positions in the local frames. - for (int i = 0; i < num_links; ++i) { - - // transform to local frame - const int parent = m_links[i].m_parent; - const btMatrix3x3 mtx(m_links[i].m_cachedRotParentToThis); - rot_from_world[i+1] = mtx * rot_from_world[parent+1]; - - n_local_lin[i+1] = mtx * n_local_lin[parent+1]; - n_local_ang[i+1] = mtx * n_local_ang[parent+1]; - p_minus_com_local[i+1] = mtx * p_minus_com_local[parent+1] - m_links[i].m_cachedRVector; + n_local_lin[i + 1] = mtx * n_local_lin[parent + 1]; + n_local_ang[i + 1] = mtx * n_local_ang[parent + 1]; + p_minus_com_local[i + 1] = mtx * p_minus_com_local[parent + 1] - m_links[i].m_cachedRVector; // calculate the jacobian entry - switch(m_links[i].m_jointType) + switch (m_links[i].m_jointType) { case btMultibodyLink::eRevolute: { - results[m_links[i].m_dofOffset] = n_local_lin[i+1].dot(m_links[i].getAxisTop(0).cross(p_minus_com_local[i+1]) + m_links[i].getAxisBottom(0)); - results[m_links[i].m_dofOffset] += n_local_ang[i+1].dot(m_links[i].getAxisTop(0)); + results[m_links[i].m_dofOffset] = n_local_lin[i + 1].dot(m_links[i].getAxisTop(0).cross(p_minus_com_local[i + 1]) + m_links[i].getAxisBottom(0)); + results[m_links[i].m_dofOffset] += n_local_ang[i + 1].dot(m_links[i].getAxisTop(0)); break; } case btMultibodyLink::ePrismatic: { - results[m_links[i].m_dofOffset] = n_local_lin[i+1].dot(m_links[i].getAxisBottom(0)); + results[m_links[i].m_dofOffset] = n_local_lin[i + 1].dot(m_links[i].getAxisBottom(0)); break; } case btMultibodyLink::eSpherical: { - results[m_links[i].m_dofOffset + 0] = n_local_lin[i+1].dot(m_links[i].getAxisTop(0).cross(p_minus_com_local[i+1]) + m_links[i].getAxisBottom(0)); - results[m_links[i].m_dofOffset + 1] = n_local_lin[i+1].dot(m_links[i].getAxisTop(1).cross(p_minus_com_local[i+1]) + m_links[i].getAxisBottom(1)); - results[m_links[i].m_dofOffset + 2] = n_local_lin[i+1].dot(m_links[i].getAxisTop(2).cross(p_minus_com_local[i+1]) + m_links[i].getAxisBottom(2)); - - results[m_links[i].m_dofOffset + 0] += n_local_ang[i+1].dot(m_links[i].getAxisTop(0)); - results[m_links[i].m_dofOffset + 1] += n_local_ang[i+1].dot(m_links[i].getAxisTop(1)); - results[m_links[i].m_dofOffset + 2] += n_local_ang[i+1].dot(m_links[i].getAxisTop(2)); + results[m_links[i].m_dofOffset + 0] = n_local_lin[i + 1].dot(m_links[i].getAxisTop(0).cross(p_minus_com_local[i + 1]) + m_links[i].getAxisBottom(0)); + results[m_links[i].m_dofOffset + 1] = n_local_lin[i + 1].dot(m_links[i].getAxisTop(1).cross(p_minus_com_local[i + 1]) + m_links[i].getAxisBottom(1)); + results[m_links[i].m_dofOffset + 2] = n_local_lin[i + 1].dot(m_links[i].getAxisTop(2).cross(p_minus_com_local[i + 1]) + m_links[i].getAxisBottom(2)); + + results[m_links[i].m_dofOffset + 0] += n_local_ang[i + 1].dot(m_links[i].getAxisTop(0)); + results[m_links[i].m_dofOffset + 1] += n_local_ang[i + 1].dot(m_links[i].getAxisTop(1)); + results[m_links[i].m_dofOffset + 2] += n_local_ang[i + 1].dot(m_links[i].getAxisTop(2)); break; } case btMultibodyLink::ePlanar: { - results[m_links[i].m_dofOffset + 0] = n_local_lin[i+1].dot(m_links[i].getAxisTop(0).cross(p_minus_com_local[i+1]));// + m_links[i].getAxisBottom(0)); - results[m_links[i].m_dofOffset + 1] = n_local_lin[i+1].dot(m_links[i].getAxisBottom(1)); - results[m_links[i].m_dofOffset + 2] = n_local_lin[i+1].dot(m_links[i].getAxisBottom(2)); + results[m_links[i].m_dofOffset + 0] = n_local_lin[i + 1].dot(m_links[i].getAxisTop(0).cross(p_minus_com_local[i + 1])); // + m_links[i].getAxisBottom(0)); + results[m_links[i].m_dofOffset + 1] = n_local_lin[i + 1].dot(m_links[i].getAxisBottom(1)); + results[m_links[i].m_dofOffset + 2] = n_local_lin[i + 1].dot(m_links[i].getAxisBottom(2)); break; } @@ -1824,269 +1820,260 @@ void btMultiBody::fillConstraintJacobianMultiDof(int link, { } } - - } + } - // Now copy through to output. + // Now copy through to output. //printf("jac[%d] = ", link); - while (link != -1) + while (link != -1) { - for(int dof = 0; dof < m_links[link].m_dofCount; ++dof) + for (int dof = 0; dof < m_links[link].m_dofCount; ++dof) { jac[6 + m_links[link].m_dofOffset + dof] = results[m_links[link].m_dofOffset + dof]; //printf("%.2f\t", jac[6 + m_links[link].m_dofOffset + dof]); } - - link = m_links[link].m_parent; - } - //printf("]\n"); - } -} + link = m_links[link].m_parent; + } + //printf("]\n"); + } +} void btMultiBody::wakeUp() { m_sleepTimer = 0; - m_awake = true; + m_awake = true; } void btMultiBody::goToSleep() { - m_awake = false; + m_awake = false; } void btMultiBody::checkMotionAndSleepIfRequired(btScalar timestep) { extern bool gDisableDeactivation; - if (!m_canSleep || gDisableDeactivation) + if (!m_canSleep || gDisableDeactivation) { m_awake = true; m_sleepTimer = 0; return; } - // motion is computed as omega^2 + v^2 + (sum of squares of joint velocities) - btScalar motion = 0; + // motion is computed as omega^2 + v^2 + (sum of squares of joint velocities) + btScalar motion = 0; { - for (int i = 0; i < 6 + m_dofCount; ++i) + for (int i = 0; i < 6 + m_dofCount; ++i) motion += m_realBuf[i] * m_realBuf[i]; } - - if (motion < SLEEP_EPSILON) { - m_sleepTimer += timestep; - if (m_sleepTimer > SLEEP_TIMEOUT) { - goToSleep(); - } - } else { - m_sleepTimer = 0; + if (motion < SLEEP_EPSILON) + { + m_sleepTimer += timestep; + if (m_sleepTimer > SLEEP_TIMEOUT) + { + goToSleep(); + } + } + else + { + m_sleepTimer = 0; if (!m_awake) wakeUp(); - } + } } - -void btMultiBody::forwardKinematics(btAlignedObjectArray& world_to_local,btAlignedObjectArray& local_origin) +void btMultiBody::forwardKinematics(btAlignedObjectArray &world_to_local, btAlignedObjectArray &local_origin) { - int num_links = getNumLinks(); // Cached 3x3 rotation matrices from parent frame to this frame. - btMatrix3x3* rot_from_parent =(btMatrix3x3 *) &m_matrixBuf[0]; + btMatrix3x3 *rot_from_parent = (btMatrix3x3 *)&m_matrixBuf[0]; - rot_from_parent[0] = btMatrix3x3(m_baseQuat); //m_baseQuat assumed to be alias!? - - for (int i = 0; i < num_links; ++i) + rot_from_parent[0] = btMatrix3x3(m_baseQuat); //m_baseQuat assumed to be alias!? + + for (int i = 0; i < num_links; ++i) { - rot_from_parent[i+1] = btMatrix3x3(m_links[i].m_cachedRotParentToThis); + rot_from_parent[i + 1] = btMatrix3x3(m_links[i].m_cachedRotParentToThis); } - + int nLinks = getNumLinks(); ///base + num m_links - world_to_local.resize(nLinks+1); - local_origin.resize(nLinks+1); + world_to_local.resize(nLinks + 1); + local_origin.resize(nLinks + 1); world_to_local[0] = getWorldToBaseRot(); local_origin[0] = getBasePos(); - - for (int k=0;k& world_to_local,btAlignedObjectArray& local_origin) +void btMultiBody::updateCollisionObjectWorldTransforms(btAlignedObjectArray &world_to_local, btAlignedObjectArray &local_origin) { - world_to_local.resize(getNumLinks()+1); - local_origin.resize(getNumLinks()+1); - + world_to_local.resize(getNumLinks() + 1); + local_origin.resize(getNumLinks() + 1); + world_to_local[0] = getWorldToBaseRot(); local_origin[0] = getBasePos(); - + if (getBaseCollider()) { btVector3 posr = local_origin[0]; // float pos[4]={posr.x(),posr.y(),posr.z(),1}; - btScalar quat[4]={-world_to_local[0].x(),-world_to_local[0].y(),-world_to_local[0].z(),world_to_local[0].w()}; + btScalar quat[4] = {-world_to_local[0].x(), -world_to_local[0].y(), -world_to_local[0].z(), world_to_local[0].w()}; btTransform tr; tr.setIdentity(); tr.setOrigin(posr); - tr.setRotation(btQuaternion(quat[0],quat[1],quat[2],quat[3])); - + tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3])); + getBaseCollider()->setWorldTransform(tr); - } - - for (int k=0;km_link; btAssert(link == m); - - int index = link+1; - + + int index = link + 1; + btVector3 posr = local_origin[index]; // float pos[4]={posr.x(),posr.y(),posr.z(),1}; - btScalar quat[4]={-world_to_local[index].x(),-world_to_local[index].y(),-world_to_local[index].z(),world_to_local[index].w()}; + btScalar quat[4] = {-world_to_local[index].x(), -world_to_local[index].y(), -world_to_local[index].z(), world_to_local[index].w()}; btTransform tr; tr.setIdentity(); tr.setOrigin(posr); - tr.setRotation(btQuaternion(quat[0],quat[1],quat[2],quat[3])); - + tr.setRotation(btQuaternion(quat[0], quat[1], quat[2], quat[3])); + col->setWorldTransform(tr); } } } -int btMultiBody::calculateSerializeBufferSize() const +int btMultiBody::calculateSerializeBufferSize() const { int sz = sizeof(btMultiBodyData); return sz; } - ///fills the dataBuffer and returns the struct name (and 0 on failure) -const char* btMultiBody::serialize(void* dataBuffer, class btSerializer* serializer) const +///fills the dataBuffer and returns the struct name (and 0 on failure) +const char *btMultiBody::serialize(void *dataBuffer, class btSerializer *serializer) const { - btMultiBodyData* mbd = (btMultiBodyData*) dataBuffer; - getBasePos().serialize(mbd->m_baseWorldPosition); - getWorldToBaseRot().inverse().serialize(mbd->m_baseWorldOrientation); - getBaseVel().serialize(mbd->m_baseLinearVelocity); - getBaseOmega().serialize(mbd->m_baseAngularVelocity); + btMultiBodyData *mbd = (btMultiBodyData *)dataBuffer; + getBasePos().serialize(mbd->m_baseWorldPosition); + getWorldToBaseRot().inverse().serialize(mbd->m_baseWorldOrientation); + getBaseVel().serialize(mbd->m_baseLinearVelocity); + getBaseOmega().serialize(mbd->m_baseAngularVelocity); - mbd->m_baseMass = this->getBaseMass(); - getBaseInertia().serialize(mbd->m_baseInertia); + mbd->m_baseMass = this->getBaseMass(); + getBaseInertia().serialize(mbd->m_baseInertia); + { + char *name = (char *)serializer->findNameForPointer(m_baseName); + mbd->m_baseName = (char *)serializer->getUniquePointer(name); + if (mbd->m_baseName) { - char* name = (char*) serializer->findNameForPointer(m_baseName); - mbd->m_baseName = (char*)serializer->getUniquePointer(name); - if (mbd->m_baseName) - { - serializer->serializeName(name); - } + serializer->serializeName(name); } - mbd->m_numLinks = this->getNumLinks(); - if (mbd->m_numLinks) + } + mbd->m_numLinks = this->getNumLinks(); + if (mbd->m_numLinks) + { + int sz = sizeof(btMultiBodyLinkData); + int numElem = mbd->m_numLinks; + btChunk *chunk = serializer->allocate(sz, numElem); + btMultiBodyLinkData *memPtr = (btMultiBodyLinkData *)chunk->m_oldPtr; + for (int i = 0; i < numElem; i++, memPtr++) { - int sz = sizeof(btMultiBodyLinkData); - int numElem = mbd->m_numLinks; - btChunk* chunk = serializer->allocate(sz,numElem); - btMultiBodyLinkData* memPtr = (btMultiBodyLinkData*)chunk->m_oldPtr; - for (int i=0;im_jointType = getLink(i).m_jointType; + memPtr->m_dofCount = getLink(i).m_dofCount; + memPtr->m_posVarCount = getLink(i).m_posVarCount; + + getLink(i).m_inertiaLocal.serialize(memPtr->m_linkInertia); + + getLink(i).m_absFrameTotVelocity.m_topVec.serialize(memPtr->m_absFrameTotVelocityTop); + getLink(i).m_absFrameTotVelocity.m_bottomVec.serialize(memPtr->m_absFrameTotVelocityBottom); + getLink(i).m_absFrameLocVelocity.m_topVec.serialize(memPtr->m_absFrameLocVelocityTop); + getLink(i).m_absFrameLocVelocity.m_bottomVec.serialize(memPtr->m_absFrameLocVelocityBottom); + + memPtr->m_linkMass = getLink(i).m_mass; + memPtr->m_parentIndex = getLink(i).m_parent; + memPtr->m_jointDamping = getLink(i).m_jointDamping; + memPtr->m_jointFriction = getLink(i).m_jointFriction; + memPtr->m_jointLowerLimit = getLink(i).m_jointLowerLimit; + memPtr->m_jointUpperLimit = getLink(i).m_jointUpperLimit; + memPtr->m_jointMaxForce = getLink(i).m_jointMaxForce; + memPtr->m_jointMaxVelocity = getLink(i).m_jointMaxVelocity; + + getLink(i).m_eVector.serialize(memPtr->m_parentComToThisPivotOffset); + getLink(i).m_dVector.serialize(memPtr->m_thisPivotToThisComOffset); + getLink(i).m_zeroRotParentToThis.serialize(memPtr->m_zeroRotParentToThis); + btAssert(memPtr->m_dofCount <= 3); + for (int dof = 0; dof < getLink(i).m_dofCount; dof++) { + getLink(i).getAxisBottom(dof).serialize(memPtr->m_jointAxisBottom[dof]); + getLink(i).getAxisTop(dof).serialize(memPtr->m_jointAxisTop[dof]); - memPtr->m_jointType = getLink(i).m_jointType; - memPtr->m_dofCount = getLink(i).m_dofCount; - memPtr->m_posVarCount = getLink(i).m_posVarCount; - - getLink(i).m_inertiaLocal.serialize(memPtr->m_linkInertia); - - getLink(i).m_absFrameTotVelocity.m_topVec.serialize(memPtr->m_absFrameTotVelocityTop); - getLink(i).m_absFrameTotVelocity.m_bottomVec.serialize(memPtr->m_absFrameTotVelocityBottom); - getLink(i).m_absFrameLocVelocity.m_topVec.serialize(memPtr->m_absFrameLocVelocityTop); - getLink(i).m_absFrameLocVelocity.m_bottomVec.serialize(memPtr->m_absFrameLocVelocityBottom); - - memPtr->m_linkMass = getLink(i).m_mass; - memPtr->m_parentIndex = getLink(i).m_parent; - memPtr->m_jointDamping = getLink(i).m_jointDamping; - memPtr->m_jointFriction = getLink(i).m_jointFriction; - memPtr->m_jointLowerLimit = getLink(i).m_jointLowerLimit; - memPtr->m_jointUpperLimit = getLink(i).m_jointUpperLimit; - memPtr->m_jointMaxForce = getLink(i).m_jointMaxForce; - memPtr->m_jointMaxVelocity = getLink(i).m_jointMaxVelocity; - - getLink(i).m_eVector.serialize(memPtr->m_parentComToThisPivotOffset); - getLink(i).m_dVector.serialize(memPtr->m_thisPivotToThisComOffset); - getLink(i).m_zeroRotParentToThis.serialize(memPtr->m_zeroRotParentToThis); - btAssert(memPtr->m_dofCount<=3); - for (int dof = 0;dofm_jointAxisBottom[dof]); - getLink(i).getAxisTop(dof).serialize(memPtr->m_jointAxisTop[dof]); - - memPtr->m_jointTorque[dof] = getLink(i).m_jointTorque[dof]; - memPtr->m_jointVel[dof] = getJointVelMultiDof(i)[dof]; - - } - int numPosVar = getLink(i).m_posVarCount; - for (int posvar = 0; posvar < numPosVar;posvar++) - { - memPtr->m_jointPos[posvar] = getLink(i).m_jointPos[posvar]; - } - - - { - char* name = (char*) serializer->findNameForPointer(m_links[i].m_linkName); - memPtr->m_linkName = (char*)serializer->getUniquePointer(name); - if (memPtr->m_linkName) - { - serializer->serializeName(name); - } - } - { - char* name = (char*) serializer->findNameForPointer(m_links[i].m_jointName); - memPtr->m_jointName = (char*)serializer->getUniquePointer(name); - if (memPtr->m_jointName) - { - serializer->serializeName(name); - } - } - memPtr->m_linkCollider = (btCollisionObjectData*)serializer->getUniquePointer(getLink(i).m_collider); - + memPtr->m_jointTorque[dof] = getLink(i).m_jointTorque[dof]; + memPtr->m_jointVel[dof] = getJointVelMultiDof(i)[dof]; + } + int numPosVar = getLink(i).m_posVarCount; + for (int posvar = 0; posvar < numPosVar; posvar++) + { + memPtr->m_jointPos[posvar] = getLink(i).m_jointPos[posvar]; } - serializer->finalizeChunk(chunk,btMultiBodyLinkDataName,BT_ARRAY_CODE,(void*) &m_links[0]); - } - mbd->m_links = mbd->m_numLinks? (btMultiBodyLinkData*) serializer->getUniquePointer((void*)&m_links[0]):0; - // Fill padding with zeros to appease msan. + { + char *name = (char *)serializer->findNameForPointer(m_links[i].m_linkName); + memPtr->m_linkName = (char *)serializer->getUniquePointer(name); + if (memPtr->m_linkName) + { + serializer->serializeName(name); + } + } + { + char *name = (char *)serializer->findNameForPointer(m_links[i].m_jointName); + memPtr->m_jointName = (char *)serializer->getUniquePointer(name); + if (memPtr->m_jointName) + { + serializer->serializeName(name); + } + } + memPtr->m_linkCollider = (btCollisionObjectData *)serializer->getUniquePointer(getLink(i).m_collider); + } + serializer->finalizeChunk(chunk, btMultiBodyLinkDataName, BT_ARRAY_CODE, (void *)&m_links[0]); + } + mbd->m_links = mbd->m_numLinks ? (btMultiBodyLinkData *)serializer->getUniquePointer((void *)&m_links[0]) : 0; + + // Fill padding with zeros to appease msan. #ifdef BT_USE_DOUBLE_PRECISION - memset(mbd->m_padding, 0, sizeof(mbd->m_padding)); + memset(mbd->m_padding, 0, sizeof(mbd->m_padding)); #endif - return btMultiBodyDataName; + return btMultiBodyDataName; } diff --git a/src/BulletDynamics/Featherstone/btMultiBody.h b/src/BulletDynamics/Featherstone/btMultiBody.h index 23ea5533f..145ed4677 100644 --- a/src/BulletDynamics/Featherstone/btMultiBody.h +++ b/src/BulletDynamics/Featherstone/btMultiBody.h @@ -21,7 +21,6 @@ */ - #ifndef BT_MULTIBODY_H #define BT_MULTIBODY_H @@ -31,116 +30,111 @@ #include "LinearMath/btMatrix3x3.h" #include "LinearMath/btAlignedObjectArray.h" - ///serialization data, don't change them if you are not familiar with the details of the serialization mechanisms #ifdef BT_USE_DOUBLE_PRECISION - #define btMultiBodyData btMultiBodyDoubleData - #define btMultiBodyDataName "btMultiBodyDoubleData" - #define btMultiBodyLinkData btMultiBodyLinkDoubleData - #define btMultiBodyLinkDataName "btMultiBodyLinkDoubleData" +#define btMultiBodyData btMultiBodyDoubleData +#define btMultiBodyDataName "btMultiBodyDoubleData" +#define btMultiBodyLinkData btMultiBodyLinkDoubleData +#define btMultiBodyLinkDataName "btMultiBodyLinkDoubleData" #else - #define btMultiBodyData btMultiBodyFloatData - #define btMultiBodyDataName "btMultiBodyFloatData" - #define btMultiBodyLinkData btMultiBodyLinkFloatData - #define btMultiBodyLinkDataName "btMultiBodyLinkFloatData" -#endif //BT_USE_DOUBLE_PRECISION +#define btMultiBodyData btMultiBodyFloatData +#define btMultiBodyDataName "btMultiBodyFloatData" +#define btMultiBodyLinkData btMultiBodyLinkFloatData +#define btMultiBodyLinkDataName "btMultiBodyLinkFloatData" +#endif //BT_USE_DOUBLE_PRECISION #include "btMultiBodyLink.h" class btMultiBodyLinkCollider; -ATTRIBUTE_ALIGNED16(class) btMultiBody +ATTRIBUTE_ALIGNED16(class) +btMultiBody { public: - - BT_DECLARE_ALIGNED_ALLOCATOR(); - // - // initialization - // - - btMultiBody(int n_links, // NOT including the base - btScalar mass, // mass of base - const btVector3 &inertia, // inertia of base, in base frame; assumed diagonal - bool fixedBase, // whether the base is fixed (true) or can move (false) - bool canSleep, bool deprecatedMultiDof=true); + // + // initialization + // + btMultiBody(int n_links, // NOT including the base + btScalar mass, // mass of base + const btVector3 &inertia, // inertia of base, in base frame; assumed diagonal + bool fixedBase, // whether the base is fixed (true) or can move (false) + bool canSleep, bool deprecatedMultiDof = true); virtual ~btMultiBody(); - + //note: fixed link collision with parent is always disabled void setupFixed(int linkIndex, - btScalar mass, - const btVector3 &inertia, - int parent, - const btQuaternion &rotParentToThis, - const btVector3 &parentComToThisPivotOffset, - const btVector3 &thisPivotToThisComOffset, bool deprecatedDisableParentCollision=true); + btScalar mass, + const btVector3 &inertia, + int parent, + const btQuaternion &rotParentToThis, + const btVector3 &parentComToThisPivotOffset, + const btVector3 &thisPivotToThisComOffset, bool deprecatedDisableParentCollision = true); - void setupPrismatic(int i, - btScalar mass, - const btVector3 &inertia, - int parent, - const btQuaternion &rotParentToThis, - const btVector3 &jointAxis, - const btVector3 &parentComToThisPivotOffset, - const btVector3 &thisPivotToThisComOffset, - bool disableParentCollision); + btScalar mass, + const btVector3 &inertia, + int parent, + const btQuaternion &rotParentToThis, + const btVector3 &jointAxis, + const btVector3 &parentComToThisPivotOffset, + const btVector3 &thisPivotToThisComOffset, + bool disableParentCollision); - void setupRevolute(int linkIndex, // 0 to num_links-1 - btScalar mass, - const btVector3 &inertia, - int parentIndex, - const btQuaternion &rotParentToThis, // rotate points in parent frame to this frame, when q = 0 - const btVector3 &jointAxis, // in my frame - const btVector3 &parentComToThisPivotOffset, // vector from parent COM to joint axis, in PARENT frame - const btVector3 &thisPivotToThisComOffset, // vector from joint axis to my COM, in MY frame - bool disableParentCollision=false); + void setupRevolute(int linkIndex, // 0 to num_links-1 + btScalar mass, + const btVector3 &inertia, + int parentIndex, + const btQuaternion &rotParentToThis, // rotate points in parent frame to this frame, when q = 0 + const btVector3 &jointAxis, // in my frame + const btVector3 &parentComToThisPivotOffset, // vector from parent COM to joint axis, in PARENT frame + const btVector3 &thisPivotToThisComOffset, // vector from joint axis to my COM, in MY frame + bool disableParentCollision = false); - void setupSpherical(int linkIndex, // 0 to num_links-1 - btScalar mass, - const btVector3 &inertia, - int parent, - const btQuaternion &rotParentToThis, // rotate points in parent frame to this frame, when q = 0 - const btVector3 &parentComToThisPivotOffset, // vector from parent COM to joint axis, in PARENT frame - const btVector3 &thisPivotToThisComOffset, // vector from joint axis to my COM, in MY frame - bool disableParentCollision=false); + void setupSpherical(int linkIndex, // 0 to num_links-1 + btScalar mass, + const btVector3 &inertia, + int parent, + const btQuaternion &rotParentToThis, // rotate points in parent frame to this frame, when q = 0 + const btVector3 &parentComToThisPivotOffset, // vector from parent COM to joint axis, in PARENT frame + const btVector3 &thisPivotToThisComOffset, // vector from joint axis to my COM, in MY frame + bool disableParentCollision = false); - void setupPlanar(int i, // 0 to num_links-1 - btScalar mass, - const btVector3 &inertia, - int parent, - const btQuaternion &rotParentToThis, // rotate points in parent frame to this frame, when q = 0 - const btVector3 &rotationAxis, - const btVector3 &parentComToThisComOffset, // vector from parent COM to this COM, in PARENT frame - bool disableParentCollision=false); - - const btMultibodyLink& getLink(int index) const + void setupPlanar(int i, // 0 to num_links-1 + btScalar mass, + const btVector3 &inertia, + int parent, + const btQuaternion &rotParentToThis, // rotate points in parent frame to this frame, when q = 0 + const btVector3 &rotationAxis, + const btVector3 &parentComToThisComOffset, // vector from parent COM to this COM, in PARENT frame + bool disableParentCollision = false); + + const btMultibodyLink &getLink(int index) const { return m_links[index]; } - btMultibodyLink& getLink(int index) + btMultibodyLink &getLink(int index) { return m_links[index]; } - - void setBaseCollider(btMultiBodyLinkCollider* collider)//collider can be NULL to disable collision for the base + void setBaseCollider(btMultiBodyLinkCollider * collider) //collider can be NULL to disable collision for the base { m_baseCollider = collider; } - const btMultiBodyLinkCollider* getBaseCollider() const + const btMultiBodyLinkCollider *getBaseCollider() const { return m_baseCollider; } - btMultiBodyLinkCollider* getBaseCollider() + btMultiBodyLinkCollider *getBaseCollider() { return m_baseCollider; } - btMultiBodyLinkCollider* getLinkCollider(int index) + btMultiBodyLinkCollider *getLinkCollider(int index) { if (index >= 0 && index < getNumLinks()) { @@ -149,61 +143,56 @@ public: return 0; } - // - // get parent - // input: link num from 0 to num_links-1 - // output: link num from 0 to num_links-1, OR -1 to mean the base. - // - int getParent(int link_num) const; - - - // - // get number of m_links, masses, moments of inertia - // + // + // get parent + // input: link num from 0 to num_links-1 + // output: link num from 0 to num_links-1, OR -1 to mean the base. + // + int getParent(int link_num) const; - int getNumLinks() const { return m_links.size(); } + // + // get number of m_links, masses, moments of inertia + // + + int getNumLinks() const { return m_links.size(); } int getNumDofs() const { return m_dofCount; } int getNumPosVars() const { return m_posVarCnt; } - btScalar getBaseMass() const { return m_baseMass; } - const btVector3 & getBaseInertia() const { return m_baseInertia; } - btScalar getLinkMass(int i) const; - const btVector3 & getLinkInertia(int i) const; - - + btScalar getBaseMass() const { return m_baseMass; } + const btVector3 &getBaseInertia() const { return m_baseInertia; } + btScalar getLinkMass(int i) const; + const btVector3 &getLinkInertia(int i) const; - // - // change mass (incomplete: can only change base mass and inertia at present) - // + // + // change mass (incomplete: can only change base mass and inertia at present) + // - void setBaseMass(btScalar mass) { m_baseMass = mass; } - void setBaseInertia(const btVector3 &inertia) { m_baseInertia = inertia; } + void setBaseMass(btScalar mass) { m_baseMass = mass; } + void setBaseInertia(const btVector3 &inertia) { m_baseInertia = inertia; } + // + // get/set pos/vel/rot/omega for the base link + // - // - // get/set pos/vel/rot/omega for the base link - // + const btVector3 &getBasePos() const { return m_basePos; } // in world frame + const btVector3 getBaseVel() const + { + return btVector3(m_realBuf[3], m_realBuf[4], m_realBuf[5]); + } // in world frame + const btQuaternion &getWorldToBaseRot() const + { + return m_baseQuat; + } // rotates world vectors into base frame + btVector3 getBaseOmega() const { return btVector3(m_realBuf[0], m_realBuf[1], m_realBuf[2]); } // in world frame - const btVector3 & getBasePos() const { return m_basePos; } // in world frame - const btVector3 getBaseVel() const - { - return btVector3(m_realBuf[3],m_realBuf[4],m_realBuf[5]); - } // in world frame - const btQuaternion & getWorldToBaseRot() const - { - return m_baseQuat; - } // rotates world vectors into base frame - btVector3 getBaseOmega() const { return btVector3(m_realBuf[0],m_realBuf[1],m_realBuf[2]); } // in world frame - - void setBasePos(const btVector3 &pos) - { - m_basePos = pos; + void setBasePos(const btVector3 &pos) + { + m_basePos = pos; } - void setBaseWorldTransform(const btTransform& tr) + void setBaseWorldTransform(const btTransform &tr) { setBasePos(tr.getOrigin()); setWorldToBaseRot(tr.getRotation().inverse()); - } btTransform getBaseWorldTransform() const @@ -214,190 +203,181 @@ public: return tr; } - void setBaseVel(const btVector3 &vel) - { - - m_realBuf[3]=vel[0]; m_realBuf[4]=vel[1]; m_realBuf[5]=vel[2]; + void setBaseVel(const btVector3 &vel) + { + m_realBuf[3] = vel[0]; + m_realBuf[4] = vel[1]; + m_realBuf[5] = vel[2]; } - void setWorldToBaseRot(const btQuaternion &rot) - { - m_baseQuat = rot; //m_baseQuat asumed to ba alias!? + void setWorldToBaseRot(const btQuaternion &rot) + { + m_baseQuat = rot; //m_baseQuat asumed to ba alias!? } - void setBaseOmega(const btVector3 &omega) - { - m_realBuf[0]=omega[0]; - m_realBuf[1]=omega[1]; - m_realBuf[2]=omega[2]; + void setBaseOmega(const btVector3 &omega) + { + m_realBuf[0] = omega[0]; + m_realBuf[1] = omega[1]; + m_realBuf[2] = omega[2]; } + // + // get/set pos/vel for child m_links (i = 0 to num_links-1) + // - // - // get/set pos/vel for child m_links (i = 0 to num_links-1) - // + btScalar getJointPos(int i) const; + btScalar getJointVel(int i) const; - btScalar getJointPos(int i) const; - btScalar getJointVel(int i) const; + btScalar *getJointVelMultiDof(int i); + btScalar *getJointPosMultiDof(int i); - btScalar * getJointVelMultiDof(int i); - btScalar * getJointPosMultiDof(int i); + const btScalar *getJointVelMultiDof(int i) const; + const btScalar *getJointPosMultiDof(int i) const; - const btScalar * getJointVelMultiDof(int i) const ; - const btScalar * getJointPosMultiDof(int i) const ; - - void setJointPos(int i, btScalar q); - void setJointVel(int i, btScalar qdot); + void setJointPos(int i, btScalar q); + void setJointVel(int i, btScalar qdot); void setJointPosMultiDof(int i, btScalar *q); - void setJointVelMultiDof(int i, btScalar *qdot); + void setJointVelMultiDof(int i, btScalar *qdot); - - - // - // direct access to velocities as a vector of 6 + num_links elements. - // (omega first, then v, then joint velocities.) - // - const btScalar * getVelocityVector() const - { - return &m_realBuf[0]; + // + // direct access to velocities as a vector of 6 + num_links elements. + // (omega first, then v, then joint velocities.) + // + const btScalar *getVelocityVector() const + { + return &m_realBuf[0]; } -/* btScalar * getVelocityVector() + /* btScalar * getVelocityVector() { return &real_buf[0]; } - */ + */ - // - // get the frames of reference (positions and orientations) of the child m_links - // (i = 0 to num_links-1) - // + // + // get the frames of reference (positions and orientations) of the child m_links + // (i = 0 to num_links-1) + // - const btVector3 & getRVector(int i) const; // vector from COM(parent(i)) to COM(i), in frame i's coords - const btQuaternion & getParentToLocalRot(int i) const; // rotates vectors in frame parent(i) to vectors in frame i. + const btVector3 &getRVector(int i) const; // vector from COM(parent(i)) to COM(i), in frame i's coords + const btQuaternion &getParentToLocalRot(int i) const; // rotates vectors in frame parent(i) to vectors in frame i. + // + // transform vectors in local frame of link i to world frame (or vice versa) + // + btVector3 localPosToWorld(int i, const btVector3 &vec) const; + btVector3 localDirToWorld(int i, const btVector3 &vec) const; + btVector3 worldPosToLocal(int i, const btVector3 &vec) const; + btVector3 worldDirToLocal(int i, const btVector3 &vec) const; - // - // transform vectors in local frame of link i to world frame (or vice versa) - // - btVector3 localPosToWorld(int i, const btVector3 &vec) const; - btVector3 localDirToWorld(int i, const btVector3 &vec) const; - btVector3 worldPosToLocal(int i, const btVector3 &vec) const; - btVector3 worldDirToLocal(int i, const btVector3 &vec) const; + // + // transform a frame in local coordinate to a frame in world coordinate + // + btMatrix3x3 localFrameToWorld(int i, const btMatrix3x3 &mat) const; - // - // transform a frame in local coordinate to a frame in world coordinate - // - btMatrix3x3 localFrameToWorld(int i, const btMatrix3x3 &mat) const; + // + // calculate kinetic energy and angular momentum + // useful for debugging. + // - // - // calculate kinetic energy and angular momentum - // useful for debugging. - // + btScalar getKineticEnergy() const; + btVector3 getAngularMomentum() const; - btScalar getKineticEnergy() const; - btVector3 getAngularMomentum() const; - + // + // set external forces and torques. Note all external forces/torques are given in the WORLD frame. + // - // - // set external forces and torques. Note all external forces/torques are given in the WORLD frame. - // - - void clearForcesAndTorques(); - void clearConstraintForces(); + void clearForcesAndTorques(); + void clearConstraintForces(); void clearVelocities(); - void addBaseForce(const btVector3 &f) - { - m_baseForce += f; + void addBaseForce(const btVector3 &f) + { + m_baseForce += f; } - void addBaseTorque(const btVector3 &t) { m_baseTorque += t; } - void addLinkForce(int i, const btVector3 &f); - void addLinkTorque(int i, const btVector3 &t); + void addBaseTorque(const btVector3 &t) { m_baseTorque += t; } + void addLinkForce(int i, const btVector3 &f); + void addLinkTorque(int i, const btVector3 &t); - void addBaseConstraintForce(const btVector3 &f) - { - m_baseConstraintForce += f; - } - void addBaseConstraintTorque(const btVector3 &t) { m_baseConstraintTorque += t; } - void addLinkConstraintForce(int i, const btVector3 &f); - void addLinkConstraintTorque(int i, const btVector3 &t); - + void addBaseConstraintForce(const btVector3 &f) + { + m_baseConstraintForce += f; + } + void addBaseConstraintTorque(const btVector3 &t) { m_baseConstraintTorque += t; } + void addLinkConstraintForce(int i, const btVector3 &f); + void addLinkConstraintTorque(int i, const btVector3 &t); -void addJointTorque(int i, btScalar Q); + void addJointTorque(int i, btScalar Q); void addJointTorqueMultiDof(int i, int dof, btScalar Q); void addJointTorqueMultiDof(int i, const btScalar *Q); - const btVector3 & getBaseForce() const { return m_baseForce; } - const btVector3 & getBaseTorque() const { return m_baseTorque; } - const btVector3 & getLinkForce(int i) const; - const btVector3 & getLinkTorque(int i) const; - btScalar getJointTorque(int i) const; - btScalar * getJointTorqueMultiDof(int i); + const btVector3 &getBaseForce() const { return m_baseForce; } + const btVector3 &getBaseTorque() const { return m_baseTorque; } + const btVector3 &getLinkForce(int i) const; + const btVector3 &getLinkTorque(int i) const; + btScalar getJointTorque(int i) const; + btScalar *getJointTorqueMultiDof(int i); + // + // dynamics routines. + // - // - // dynamics routines. - // + // timestep the velocities (given the external forces/torques set using addBaseForce etc). + // also sets up caches for calcAccelerationDeltas. + // + // Note: the caller must provide three vectors which are used as + // temporary scratch space. The idea here is to reduce dynamic + // memory allocation: the same scratch vectors can be re-used + // again and again for different Multibodies, instead of each + // btMultiBody allocating (and then deallocating) their own + // individual scratch buffers. This gives a considerable speed + // improvement, at least on Windows (where dynamic memory + // allocation appears to be fairly slow). + // - // timestep the velocities (given the external forces/torques set using addBaseForce etc). - // also sets up caches for calcAccelerationDeltas. - // - // Note: the caller must provide three vectors which are used as - // temporary scratch space. The idea here is to reduce dynamic - // memory allocation: the same scratch vectors can be re-used - // again and again for different Multibodies, instead of each - // btMultiBody allocating (and then deallocating) their own - // individual scratch buffers. This gives a considerable speed - // improvement, at least on Windows (where dynamic memory - // allocation appears to be fairly slow). - // - - void computeAccelerationsArticulatedBodyAlgorithmMultiDof(btScalar dt, - btAlignedObjectArray &scratch_r, - btAlignedObjectArray &scratch_v, - btAlignedObjectArray &scratch_m, - bool isConstraintPass=false - ); + btAlignedObjectArray & scratch_r, + btAlignedObjectArray & scratch_v, + btAlignedObjectArray & scratch_m, + bool isConstraintPass = false); -///stepVelocitiesMultiDof is deprecated, use computeAccelerationsArticulatedBodyAlgorithmMultiDof instead - void stepVelocitiesMultiDof(btScalar dt, - btAlignedObjectArray &scratch_r, - btAlignedObjectArray &scratch_v, - btAlignedObjectArray &scratch_m, - bool isConstraintPass=false) + ///stepVelocitiesMultiDof is deprecated, use computeAccelerationsArticulatedBodyAlgorithmMultiDof instead + void stepVelocitiesMultiDof(btScalar dt, + btAlignedObjectArray & scratch_r, + btAlignedObjectArray & scratch_v, + btAlignedObjectArray & scratch_m, + bool isConstraintPass = false) { - computeAccelerationsArticulatedBodyAlgorithmMultiDof(dt,scratch_r,scratch_v,scratch_m,isConstraintPass); - } + computeAccelerationsArticulatedBodyAlgorithmMultiDof(dt, scratch_r, scratch_v, scratch_m, isConstraintPass); + } - // calcAccelerationDeltasMultiDof - // input: force vector (in same format as jacobian, i.e.: - // 3 torque values, 3 force values, num_links joint torque values) - // output: 3 omegadot values, 3 vdot values, num_links q_double_dot values - // (existing contents of output array are replaced) - // calcAccelerationDeltasMultiDof must have been called first. + // calcAccelerationDeltasMultiDof + // input: force vector (in same format as jacobian, i.e.: + // 3 torque values, 3 force values, num_links joint torque values) + // output: 3 omegadot values, 3 vdot values, num_links q_double_dot values + // (existing contents of output array are replaced) + // calcAccelerationDeltasMultiDof must have been called first. void calcAccelerationDeltasMultiDof(const btScalar *force, btScalar *output, - btAlignedObjectArray &scratch_r, - btAlignedObjectArray &scratch_v) const; - - - void applyDeltaVeeMultiDof2(const btScalar * delta_vee, btScalar multiplier) + btAlignedObjectArray &scratch_r, + btAlignedObjectArray &scratch_v) const; + + void applyDeltaVeeMultiDof2(const btScalar *delta_vee, btScalar multiplier) { for (int dof = 0; dof < 6 + getNumDofs(); ++dof) - { - m_deltaV[dof] += delta_vee[dof] * multiplier; - } + { + m_deltaV[dof] += delta_vee[dof] * multiplier; + } } void processDeltaVeeMultiDof2() { - applyDeltaVeeMultiDof(&m_deltaV[0],1); + applyDeltaVeeMultiDof(&m_deltaV[0], 1); for (int dof = 0; dof < 6 + getNumDofs(); ++dof) - { + { m_deltaV[dof] = 0.f; } } - void applyDeltaVeeMultiDof(const btScalar * delta_vee, btScalar multiplier) + void applyDeltaVeeMultiDof(const btScalar *delta_vee, btScalar multiplier) { //for (int dof = 0; dof < 6 + getNumDofs(); ++dof) // printf("%.4f ", delta_vee[dof]*multiplier); @@ -418,65 +398,61 @@ void addJointTorque(int i, btScalar Q); for (int dof = 0; dof < 6 + getNumDofs(); ++dof) { m_realBuf[dof] += delta_vee[dof] * multiplier; - btClamp(m_realBuf[dof],-m_maxCoordinateVelocity,m_maxCoordinateVelocity); + btClamp(m_realBuf[dof], -m_maxCoordinateVelocity, m_maxCoordinateVelocity); } - } + } - - - // timestep the positions (given current velocities). + // timestep the positions (given current velocities). void stepPositionsMultiDof(btScalar dt, btScalar *pq = 0, btScalar *pqd = 0); + // + // contacts + // - // - // contacts - // + // This routine fills out a contact constraint jacobian for this body. + // the 'normal' supplied must be -n for body1 or +n for body2 of the contact. + // 'normal' & 'contact_point' are both given in world coordinates. - // This routine fills out a contact constraint jacobian for this body. - // the 'normal' supplied must be -n for body1 or +n for body2 of the contact. - // 'normal' & 'contact_point' are both given in world coordinates. - void fillContactJacobianMultiDof(int link, - const btVector3 &contact_point, - const btVector3 &normal, - btScalar *jac, - btAlignedObjectArray &scratch_r, - btAlignedObjectArray &scratch_v, - btAlignedObjectArray &scratch_m) const { fillConstraintJacobianMultiDof(link, contact_point, btVector3(0, 0, 0), normal, jac, scratch_r, scratch_v, scratch_m); } + const btVector3 &contact_point, + const btVector3 &normal, + btScalar *jac, + btAlignedObjectArray &scratch_r, + btAlignedObjectArray &scratch_v, + btAlignedObjectArray &scratch_m) const { fillConstraintJacobianMultiDof(link, contact_point, btVector3(0, 0, 0), normal, jac, scratch_r, scratch_v, scratch_m); } //a more general version of fillContactJacobianMultiDof which does not assume.. //.. that the constraint in question is contact or, to be more precise, constrains linear velocity only void fillConstraintJacobianMultiDof(int link, - const btVector3 &contact_point, - const btVector3 &normal_ang, - const btVector3 &normal_lin, - btScalar *jac, - btAlignedObjectArray &scratch_r, - btAlignedObjectArray &scratch_v, - btAlignedObjectArray &scratch_m) const; + const btVector3 &contact_point, + const btVector3 &normal_ang, + const btVector3 &normal_lin, + btScalar *jac, + btAlignedObjectArray &scratch_r, + btAlignedObjectArray &scratch_v, + btAlignedObjectArray &scratch_m) const; - - // - // sleeping - // - void setCanSleep(bool canSleep) + // + // sleeping + // + void setCanSleep(bool canSleep) { m_canSleep = canSleep; } - bool getCanSleep()const + bool getCanSleep() const { return m_canSleep; } - bool isAwake() const { return m_awake; } - void wakeUp(); - void goToSleep(); - void checkMotionAndSleepIfRequired(btScalar timestep); - + bool isAwake() const { return m_awake; } + void wakeUp(); + void goToSleep(); + void checkMotionAndSleepIfRequired(btScalar timestep); + bool hasFixedBase() const { - return m_fixedBase; + return m_fixedBase; } int getCompanionId() const @@ -489,16 +465,16 @@ void addJointTorque(int i, btScalar Q); m_companionId = id; } - void setNumLinks(int numLinks)//careful: when changing the number of m_links, make sure to re-initialize or update existing m_links + void setNumLinks(int numLinks) //careful: when changing the number of m_links, make sure to re-initialize or update existing m_links { m_links.resize(numLinks); } btScalar getLinearDamping() const { - return m_linearDamping; + return m_linearDamping; } - void setLinearDamping( btScalar damp) + void setLinearDamping(btScalar damp) { m_linearDamping = damp; } @@ -506,11 +482,11 @@ void addJointTorque(int i, btScalar Q); { return m_angularDamping; } - void setAngularDamping( btScalar damp) + void setAngularDamping(btScalar damp) { m_angularDamping = damp; } - + bool getUseGyroTerm() const { return m_useGyroTerm; @@ -519,24 +495,24 @@ void addJointTorque(int i, btScalar Q); { m_useGyroTerm = useGyro; } - btScalar getMaxCoordinateVelocity() const + btScalar getMaxCoordinateVelocity() const { - return m_maxCoordinateVelocity ; + return m_maxCoordinateVelocity; } - void setMaxCoordinateVelocity(btScalar maxVel) + void setMaxCoordinateVelocity(btScalar maxVel) { m_maxCoordinateVelocity = maxVel; } - btScalar getMaxAppliedImpulse() const + btScalar getMaxAppliedImpulse() const { return m_maxAppliedImpulse; } - void setMaxAppliedImpulse(btScalar maxImp) + void setMaxAppliedImpulse(btScalar maxImp) { m_maxAppliedImpulse = maxImp; } - void setHasSelfCollision(bool hasSelfCollision) + void setHasSelfCollision(bool hasSelfCollision) { m_hasSelfCollision = hasSelfCollision; } @@ -545,7 +521,6 @@ void addJointTorque(int i, btScalar Q); return m_hasSelfCollision; } - void finalizeMultiDof(); void useRK4Integration(bool use) { m_useRK4 = use; } @@ -561,126 +536,123 @@ void addJointTorque(int i, btScalar Q); { __posUpdated = updated; } - + //internalNeedsJointFeedback is for internal use only bool internalNeedsJointFeedback() const { return m_internalNeedsJointFeedback; } - void forwardKinematics(btAlignedObjectArray& scratch_q,btAlignedObjectArray& scratch_m); + void forwardKinematics(btAlignedObjectArray & scratch_q, btAlignedObjectArray & scratch_m); - void compTreeLinkVelocities(btVector3 *omega, btVector3 *vel) const; + void compTreeLinkVelocities(btVector3 * omega, btVector3 * vel) const; - void updateCollisionObjectWorldTransforms(btAlignedObjectArray& scratch_q,btAlignedObjectArray& scratch_m); - - virtual int calculateSerializeBufferSize() const; + void updateCollisionObjectWorldTransforms(btAlignedObjectArray & scratch_q, btAlignedObjectArray & scratch_m); + + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const; + virtual const char *serialize(void *dataBuffer, class btSerializer *serializer) const; - const char* getBaseName() const + const char *getBaseName() const { return m_baseName; } ///memory of setBaseName needs to be manager by user - void setBaseName(const char* name) + void setBaseName(const char *name) { m_baseName = name; } ///users can point to their objects, userPointer is not used by Bullet - void* getUserPointer() const + void *getUserPointer() const { return m_userObjectPointer; } - int getUserIndex() const + int getUserIndex() const { return m_userIndex; } - int getUserIndex2() const + int getUserIndex2() const { return m_userIndex2; } ///users can point to their objects, userPointer is not used by Bullet - void setUserPointer(void* userPointer) + void setUserPointer(void *userPointer) { m_userObjectPointer = userPointer; } ///users can point to their objects, userPointer is not used by Bullet - void setUserIndex(int index) + void setUserIndex(int index) { m_userIndex = index; } - void setUserIndex2(int index) + void setUserIndex2(int index) { m_userIndex2 = index; } private: - btMultiBody(const btMultiBody &); // not implemented - void operator=(const btMultiBody &); // not implemented + btMultiBody(const btMultiBody &); // not implemented + void operator=(const btMultiBody &); // not implemented - - void solveImatrix(const btVector3& rhs_top, const btVector3& rhs_bot, btScalar result[6]) const; + void solveImatrix(const btVector3 &rhs_top, const btVector3 &rhs_bot, btScalar result[6]) const; void solveImatrix(const btSpatialForceVector &rhs, btSpatialMotionVector &result) const; - + void updateLinksDofOffsets() { int dofOffset = 0, cfgOffset = 0; - for(int bidx = 0; bidx < m_links.size(); ++bidx) + for (int bidx = 0; bidx < m_links.size(); ++bidx) { - m_links[bidx].m_dofOffset = dofOffset; m_links[bidx].m_cfgOffset = cfgOffset; - dofOffset += m_links[bidx].m_dofCount; cfgOffset += m_links[bidx].m_posVarCount; + m_links[bidx].m_dofOffset = dofOffset; + m_links[bidx].m_cfgOffset = cfgOffset; + dofOffset += m_links[bidx].m_dofCount; + cfgOffset += m_links[bidx].m_posVarCount; } } - void mulMatrix(btScalar *pA, btScalar *pB, int rowsA, int colsA, int rowsB, int colsB, btScalar *pC) const; - - + void mulMatrix(btScalar * pA, btScalar * pB, int rowsA, int colsA, int rowsB, int colsB, btScalar *pC) const; + private: + btMultiBodyLinkCollider *m_baseCollider; //can be NULL + const char *m_baseName; //memory needs to be manager by user! - btMultiBodyLinkCollider* m_baseCollider;//can be NULL - const char* m_baseName;//memory needs to be manager by user! + btVector3 m_basePos; // position of COM of base (world frame) + btQuaternion m_baseQuat; // rotates world points into base frame - btVector3 m_basePos; // position of COM of base (world frame) - btQuaternion m_baseQuat; // rotates world points into base frame + btScalar m_baseMass; // mass of the base + btVector3 m_baseInertia; // inertia of the base (in local frame; diagonal) - btScalar m_baseMass; // mass of the base - btVector3 m_baseInertia; // inertia of the base (in local frame; diagonal) + btVector3 m_baseForce; // external force applied to base. World frame. + btVector3 m_baseTorque; // external torque applied to base. World frame. - btVector3 m_baseForce; // external force applied to base. World frame. - btVector3 m_baseTorque; // external torque applied to base. World frame. - - btVector3 m_baseConstraintForce; // external force applied to base. World frame. - btVector3 m_baseConstraintTorque; // external torque applied to base. World frame. - - btAlignedObjectArray m_links; // array of m_links, excluding the base. index from 0 to num_links-1. + btVector3 m_baseConstraintForce; // external force applied to base. World frame. + btVector3 m_baseConstraintTorque; // external torque applied to base. World frame. - - // - // realBuf: - // offset size array - // 0 6 + num_links v (base_omega; base_vel; joint_vels) MULTIDOF [sysdof x sysdof for D matrices (TOO MUCH!) + pos_delta which is sys-cfg sized] - // 6+num_links num_links D - // - // vectorBuf: - // offset size array - // 0 num_links h_top - // num_links num_links h_bottom - // - // matrixBuf: - // offset size array - // 0 num_links+1 rot_from_parent - // - btAlignedObjectArray m_deltaV; - btAlignedObjectArray m_realBuf; - btAlignedObjectArray m_vectorBuf; - btAlignedObjectArray m_matrixBuf; + btAlignedObjectArray m_links; // array of m_links, excluding the base. index from 0 to num_links-1. + // + // realBuf: + // offset size array + // 0 6 + num_links v (base_omega; base_vel; joint_vels) MULTIDOF [sysdof x sysdof for D matrices (TOO MUCH!) + pos_delta which is sys-cfg sized] + // 6+num_links num_links D + // + // vectorBuf: + // offset size array + // 0 num_links h_top + // num_links num_links h_bottom + // + // matrixBuf: + // offset size array + // 0 num_links+1 rot_from_parent + // + btAlignedObjectArray m_deltaV; + btAlignedObjectArray m_realBuf; + btAlignedObjectArray m_vectorBuf; + btAlignedObjectArray m_matrixBuf; btMatrix3x3 m_cachedInertiaTopLeft; btMatrix3x3 m_cachedInertiaTopRight; @@ -688,25 +660,25 @@ private: btMatrix3x3 m_cachedInertiaLowerRight; bool m_cachedInertiaValid; - bool m_fixedBase; + bool m_fixedBase; - // Sleep parameters. - bool m_awake; - bool m_canSleep; - btScalar m_sleepTimer; + // Sleep parameters. + bool m_awake; + bool m_canSleep; + btScalar m_sleepTimer; - void* m_userObjectPointer; + void *m_userObjectPointer; int m_userIndex2; int m_userIndex; - int m_companionId; - btScalar m_linearDamping; - btScalar m_angularDamping; - bool m_useGyroTerm; - btScalar m_maxAppliedImpulse; - btScalar m_maxCoordinateVelocity; - bool m_hasSelfCollision; - + int m_companionId; + btScalar m_linearDamping; + btScalar m_angularDamping; + bool m_useGyroTerm; + btScalar m_maxAppliedImpulse; + btScalar m_maxCoordinateVelocity; + bool m_hasSelfCollision; + bool __posUpdated; int m_dofCount, m_posVarCnt; @@ -720,117 +692,108 @@ private: struct btMultiBodyLinkDoubleData { - btQuaternionDoubleData m_zeroRotParentToThis; - btVector3DoubleData m_parentComToThisPivotOffset; - btVector3DoubleData m_thisPivotToThisComOffset; - btVector3DoubleData m_jointAxisTop[6]; - btVector3DoubleData m_jointAxisBottom[6]; + btQuaternionDoubleData m_zeroRotParentToThis; + btVector3DoubleData m_parentComToThisPivotOffset; + btVector3DoubleData m_thisPivotToThisComOffset; + btVector3DoubleData m_jointAxisTop[6]; + btVector3DoubleData m_jointAxisBottom[6]; - btVector3DoubleData m_linkInertia; // inertia of the base (in local frame; diagonal) - btVector3DoubleData m_absFrameTotVelocityTop; - btVector3DoubleData m_absFrameTotVelocityBottom; - btVector3DoubleData m_absFrameLocVelocityTop; - btVector3DoubleData m_absFrameLocVelocityBottom; + btVector3DoubleData m_linkInertia; // inertia of the base (in local frame; diagonal) + btVector3DoubleData m_absFrameTotVelocityTop; + btVector3DoubleData m_absFrameTotVelocityBottom; + btVector3DoubleData m_absFrameLocVelocityTop; + btVector3DoubleData m_absFrameLocVelocityBottom; - double m_linkMass; - int m_parentIndex; - int m_jointType; + double m_linkMass; + int m_parentIndex; + int m_jointType; - int m_dofCount; - int m_posVarCount; - double m_jointPos[7]; - double m_jointVel[6]; - double m_jointTorque[6]; + int m_dofCount; + int m_posVarCount; + double m_jointPos[7]; + double m_jointVel[6]; + double m_jointTorque[6]; - double m_jointDamping; - double m_jointFriction; - double m_jointLowerLimit; - double m_jointUpperLimit; - double m_jointMaxForce; - double m_jointMaxVelocity; - - char *m_linkName; - char *m_jointName; - btCollisionObjectDoubleData *m_linkCollider; - char *m_paddingPtr; + double m_jointDamping; + double m_jointFriction; + double m_jointLowerLimit; + double m_jointUpperLimit; + double m_jointMaxForce; + double m_jointMaxVelocity; + char *m_linkName; + char *m_jointName; + btCollisionObjectDoubleData *m_linkCollider; + char *m_paddingPtr; }; struct btMultiBodyLinkFloatData { - btQuaternionFloatData m_zeroRotParentToThis; - btVector3FloatData m_parentComToThisPivotOffset; - btVector3FloatData m_thisPivotToThisComOffset; - btVector3FloatData m_jointAxisTop[6]; - btVector3FloatData m_jointAxisBottom[6]; - btVector3FloatData m_linkInertia; // inertia of the base (in local frame; diagonal) - btVector3FloatData m_absFrameTotVelocityTop; - btVector3FloatData m_absFrameTotVelocityBottom; - btVector3FloatData m_absFrameLocVelocityTop; - btVector3FloatData m_absFrameLocVelocityBottom; + btQuaternionFloatData m_zeroRotParentToThis; + btVector3FloatData m_parentComToThisPivotOffset; + btVector3FloatData m_thisPivotToThisComOffset; + btVector3FloatData m_jointAxisTop[6]; + btVector3FloatData m_jointAxisBottom[6]; + btVector3FloatData m_linkInertia; // inertia of the base (in local frame; diagonal) + btVector3FloatData m_absFrameTotVelocityTop; + btVector3FloatData m_absFrameTotVelocityBottom; + btVector3FloatData m_absFrameLocVelocityTop; + btVector3FloatData m_absFrameLocVelocityBottom; - int m_dofCount; - float m_linkMass; - int m_parentIndex; - int m_jointType; - + int m_dofCount; + float m_linkMass; + int m_parentIndex; + int m_jointType; - - float m_jointPos[7]; - float m_jointVel[6]; - float m_jointTorque[6]; - int m_posVarCount; - float m_jointDamping; - float m_jointFriction; - float m_jointLowerLimit; - float m_jointUpperLimit; - float m_jointMaxForce; - float m_jointMaxVelocity; - - char *m_linkName; - char *m_jointName; - btCollisionObjectFloatData *m_linkCollider; - char *m_paddingPtr; + float m_jointPos[7]; + float m_jointVel[6]; + float m_jointTorque[6]; + int m_posVarCount; + float m_jointDamping; + float m_jointFriction; + float m_jointLowerLimit; + float m_jointUpperLimit; + float m_jointMaxForce; + float m_jointMaxVelocity; + char *m_linkName; + char *m_jointName; + btCollisionObjectFloatData *m_linkCollider; + char *m_paddingPtr; }; ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 -struct btMultiBodyDoubleData +struct btMultiBodyDoubleData { btVector3DoubleData m_baseWorldPosition; btQuaternionDoubleData m_baseWorldOrientation; btVector3DoubleData m_baseLinearVelocity; btVector3DoubleData m_baseAngularVelocity; - btVector3DoubleData m_baseInertia; // inertia of the base (in local frame; diagonal) - double m_baseMass; - int m_numLinks; - char m_padding[4]; + btVector3DoubleData m_baseInertia; // inertia of the base (in local frame; diagonal) + double m_baseMass; + int m_numLinks; + char m_padding[4]; - char *m_baseName; - btMultiBodyLinkDoubleData *m_links; - btCollisionObjectDoubleData *m_baseCollider; - - + char *m_baseName; + btMultiBodyLinkDoubleData *m_links; + btCollisionObjectDoubleData *m_baseCollider; }; ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 -struct btMultiBodyFloatData +struct btMultiBodyFloatData { btVector3FloatData m_baseWorldPosition; btQuaternionFloatData m_baseWorldOrientation; btVector3FloatData m_baseLinearVelocity; btVector3FloatData m_baseAngularVelocity; - btVector3FloatData m_baseInertia; // inertia of the base (in local frame; diagonal) - float m_baseMass; - int m_numLinks; - - char *m_baseName; - btMultiBodyLinkFloatData *m_links; - btCollisionObjectFloatData *m_baseCollider; + btVector3FloatData m_baseInertia; // inertia of the base (in local frame; diagonal) + float m_baseMass; + int m_numLinks; + char *m_baseName; + btMultiBodyLinkFloatData *m_links; + btCollisionObjectFloatData *m_baseCollider; }; - - #endif diff --git a/src/BulletDynamics/Featherstone/btMultiBodyConstraint.cpp b/src/BulletDynamics/Featherstone/btMultiBodyConstraint.cpp index 9f61874b8..e17ab94d9 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyConstraint.cpp +++ b/src/BulletDynamics/Featherstone/btMultiBodyConstraint.cpp @@ -1,32 +1,29 @@ #include "btMultiBodyConstraint.h" #include "BulletDynamics/Dynamics/btRigidBody.h" -#include "btMultiBodyPoint2Point.h" //for testing (BTMBP2PCONSTRAINT_BLOCK_ANGULAR_MOTION_TEST macro) +#include "btMultiBodyPoint2Point.h" //for testing (BTMBP2PCONSTRAINT_BLOCK_ANGULAR_MOTION_TEST macro) - - -btMultiBodyConstraint::btMultiBodyConstraint(btMultiBody* bodyA,btMultiBody* bodyB,int linkA, int linkB, int numRows, bool isUnilateral) - :m_bodyA(bodyA), - m_bodyB(bodyB), - m_linkA(linkA), - m_linkB(linkB), - m_numRows(numRows), - m_jacSizeA(0), - m_jacSizeBoth(0), - m_isUnilateral(isUnilateral), - m_numDofsFinalized(-1), - m_maxAppliedImpulse(100) +btMultiBodyConstraint::btMultiBodyConstraint(btMultiBody* bodyA, btMultiBody* bodyB, int linkA, int linkB, int numRows, bool isUnilateral) + : m_bodyA(bodyA), + m_bodyB(bodyB), + m_linkA(linkA), + m_linkB(linkB), + m_numRows(numRows), + m_jacSizeA(0), + m_jacSizeBoth(0), + m_isUnilateral(isUnilateral), + m_numDofsFinalized(-1), + m_maxAppliedImpulse(100) { - } void btMultiBodyConstraint::updateJacobianSizes() { - if(m_bodyA) + if (m_bodyA) { m_jacSizeA = (6 + m_bodyA->getNumDofs()); } - if(m_bodyB) + if (m_bodyB) { m_jacSizeBoth = m_jacSizeA + 6 + m_bodyB->getNumDofs(); } @@ -38,7 +35,7 @@ void btMultiBodyConstraint::allocateJacobiansMultiDof() { updateJacobianSizes(); - m_posOffset = ((1 + m_jacSizeBoth)*m_numRows); + m_posOffset = ((1 + m_jacSizeBoth) * m_numRows); m_data.resize((2 + m_jacSizeBoth) * m_numRows); } @@ -46,298 +43,307 @@ btMultiBodyConstraint::~btMultiBodyConstraint() { } -void btMultiBodyConstraint::applyDeltaVee(btMultiBodyJacobianData& data, btScalar* delta_vee, btScalar impulse, int velocityIndex, int ndof) +void btMultiBodyConstraint::applyDeltaVee(btMultiBodyJacobianData& data, btScalar* delta_vee, btScalar impulse, int velocityIndex, int ndof) { for (int i = 0; i < ndof; ++i) - data.m_deltaVelocities[velocityIndex+i] += delta_vee[i] * impulse; + data.m_deltaVelocities[velocityIndex + i] += delta_vee[i] * impulse; } -btScalar btMultiBodyConstraint::fillMultiBodyConstraint( btMultiBodySolverConstraint& solverConstraint, - btMultiBodyJacobianData& data, - btScalar* jacOrgA, btScalar* jacOrgB, - const btVector3& constraintNormalAng, - const btVector3& constraintNormalLin, - const btVector3& posAworld, const btVector3& posBworld, - btScalar posError, - const btContactSolverInfo& infoGlobal, - btScalar lowerLimit, btScalar upperLimit, - bool angConstraint, - btScalar relaxation, - bool isFriction, btScalar desiredVelocity, btScalar cfmSlip) +btScalar btMultiBodyConstraint::fillMultiBodyConstraint(btMultiBodySolverConstraint& solverConstraint, + btMultiBodyJacobianData& data, + btScalar* jacOrgA, btScalar* jacOrgB, + const btVector3& constraintNormalAng, + const btVector3& constraintNormalLin, + const btVector3& posAworld, const btVector3& posBworld, + btScalar posError, + const btContactSolverInfo& infoGlobal, + btScalar lowerLimit, btScalar upperLimit, + bool angConstraint, + btScalar relaxation, + bool isFriction, btScalar desiredVelocity, btScalar cfmSlip) { - solverConstraint.m_multiBodyA = m_bodyA; - solverConstraint.m_multiBodyB = m_bodyB; - solverConstraint.m_linkA = m_linkA; - solverConstraint.m_linkB = m_linkB; - - btMultiBody* multiBodyA = solverConstraint.m_multiBodyA; - btMultiBody* multiBodyB = solverConstraint.m_multiBodyB; - - btSolverBody* bodyA = multiBodyA ? 0 : &data.m_solverBodyPool->at(solverConstraint.m_solverBodyIdA); - btSolverBody* bodyB = multiBodyB ? 0 : &data.m_solverBodyPool->at(solverConstraint.m_solverBodyIdB); - - btRigidBody* rb0 = multiBodyA ? 0 : bodyA->m_originalBody; - btRigidBody* rb1 = multiBodyB ? 0 : bodyB->m_originalBody; - - btVector3 rel_pos1, rel_pos2; //these two used to be inited to posAworld and posBworld (respectively) but it does not seem necessary - if (bodyA) - rel_pos1 = posAworld - bodyA->getWorldTransform().getOrigin(); - if (bodyB) - rel_pos2 = posBworld - bodyB->getWorldTransform().getOrigin(); - - if (multiBodyA) - { - if (solverConstraint.m_linkA<0) - { - rel_pos1 = posAworld - multiBodyA->getBasePos(); - } else - { - rel_pos1 = posAworld - multiBodyA->getLink(solverConstraint.m_linkA).m_cachedWorldTransform.getOrigin(); - } - - const int ndofA = multiBodyA->getNumDofs() + 6; - - solverConstraint.m_deltaVelAindex = multiBodyA->getCompanionId(); - - if (solverConstraint.m_deltaVelAindex <0) - { - solverConstraint.m_deltaVelAindex = data.m_deltaVelocities.size(); - multiBodyA->setCompanionId(solverConstraint.m_deltaVelAindex); - data.m_deltaVelocities.resize(data.m_deltaVelocities.size()+ndofA); - } else - { - btAssert(data.m_deltaVelocities.size() >= solverConstraint.m_deltaVelAindex+ndofA); - } - - //determine jacobian of this 1D constraint in terms of multibodyA's degrees of freedom - //resize.. - solverConstraint.m_jacAindex = data.m_jacobians.size(); - data.m_jacobians.resize(data.m_jacobians.size()+ndofA); - //copy/determine - if(jacOrgA) - { - for (int i=0;ifillContactJacobianMultiDof(solverConstraint.m_linkA, posAworld, constraintNormalLin, jac1, data.scratch_r, data.scratch_v, data.scratch_m); - multiBodyA->fillConstraintJacobianMultiDof(solverConstraint.m_linkA, posAworld, constraintNormalAng, constraintNormalLin, jac1, data.scratch_r, data.scratch_v, data.scratch_m); - } - - //determine the velocity response of multibodyA to reaction impulses of this constraint (i.e. A[i,i] for i=1,...n_con: multibody's inverse inertia with respect to this 1D constraint) - //resize.. - data.m_deltaVelocitiesUnitImpulse.resize(data.m_deltaVelocitiesUnitImpulse.size()+ndofA); //=> each constraint row has the constrained tree dofs allocated in m_deltaVelocitiesUnitImpulse - btAssert(data.m_jacobians.size() == data.m_deltaVelocitiesUnitImpulse.size()); - btScalar* delta = &data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacAindex]; - //determine.. - multiBodyA->calcAccelerationDeltasMultiDof(&data.m_jacobians[solverConstraint.m_jacAindex],delta,data.scratch_r, data.scratch_v); - - btVector3 torqueAxis0; - if (angConstraint) { - torqueAxis0 = constraintNormalAng; - } - else { - torqueAxis0 = rel_pos1.cross(constraintNormalLin); - - } - solverConstraint.m_relpos1CrossNormal = torqueAxis0; - solverConstraint.m_contactNormal1 = constraintNormalLin; - } - else //if(rb0) - { - btVector3 torqueAxis0; - if (angConstraint) { - torqueAxis0 = constraintNormalAng; - } - else { - torqueAxis0 = rel_pos1.cross(constraintNormalLin); - } - solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld()*torqueAxis0*rb0->getAngularFactor() : btVector3(0,0,0); - solverConstraint.m_relpos1CrossNormal = torqueAxis0; - solverConstraint.m_contactNormal1 = constraintNormalLin; - } - - if (multiBodyB) - { - if (solverConstraint.m_linkB<0) - { - rel_pos2 = posBworld - multiBodyB->getBasePos(); - } else - { - rel_pos2 = posBworld - multiBodyB->getLink(solverConstraint.m_linkB).m_cachedWorldTransform.getOrigin(); - } - - const int ndofB = multiBodyB->getNumDofs() + 6; - - solverConstraint.m_deltaVelBindex = multiBodyB->getCompanionId(); - if (solverConstraint.m_deltaVelBindex <0) - { - solverConstraint.m_deltaVelBindex = data.m_deltaVelocities.size(); - multiBodyB->setCompanionId(solverConstraint.m_deltaVelBindex); - data.m_deltaVelocities.resize(data.m_deltaVelocities.size()+ndofB); - } - - //determine jacobian of this 1D constraint in terms of multibodyB's degrees of freedom - //resize.. - solverConstraint.m_jacBindex = data.m_jacobians.size(); - data.m_jacobians.resize(data.m_jacobians.size()+ndofB); - //copy/determine.. - if(jacOrgB) - { - for (int i=0;ifillContactJacobianMultiDof(solverConstraint.m_linkB, posBworld, -constraintNormalLin, &data.m_jacobians[solverConstraint.m_jacBindex], data.scratch_r, data.scratch_v, data.scratch_m); - multiBodyB->fillConstraintJacobianMultiDof(solverConstraint.m_linkB, posBworld, -constraintNormalAng, -constraintNormalLin, &data.m_jacobians[solverConstraint.m_jacBindex], data.scratch_r, data.scratch_v, data.scratch_m); - } - - //determine velocity response of multibodyB to reaction impulses of this constraint (i.e. A[i,i] for i=1,...n_con: multibody's inverse inertia with respect to this 1D constraint) - //resize.. - data.m_deltaVelocitiesUnitImpulse.resize(data.m_deltaVelocitiesUnitImpulse.size()+ndofB); - btAssert(data.m_jacobians.size() == data.m_deltaVelocitiesUnitImpulse.size()); - btScalar* delta = &data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex]; - //determine.. - multiBodyB->calcAccelerationDeltasMultiDof(&data.m_jacobians[solverConstraint.m_jacBindex],delta,data.scratch_r, data.scratch_v); - - btVector3 torqueAxis1; - if (angConstraint) { - torqueAxis1 = constraintNormalAng; - } - else { - torqueAxis1 = rel_pos2.cross(constraintNormalLin); - } - solverConstraint.m_relpos2CrossNormal = -torqueAxis1; - solverConstraint.m_contactNormal2 = -constraintNormalLin; - } - else //if(rb1) - { - btVector3 torqueAxis1; - if (angConstraint) { - torqueAxis1 = constraintNormalAng; - } - else { - torqueAxis1 = rel_pos2.cross(constraintNormalLin); - } - solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld()*-torqueAxis1*rb1->getAngularFactor() : btVector3(0,0,0); - solverConstraint.m_relpos2CrossNormal = -torqueAxis1; - solverConstraint.m_contactNormal2 = -constraintNormalLin; - } - { - - btVector3 vec; - btScalar denom0 = 0.f; - btScalar denom1 = 0.f; - btScalar* jacB = 0; - btScalar* jacA = 0; - btScalar* deltaVelA = 0; - btScalar* deltaVelB = 0; - int ndofA = 0; - //determine the "effective mass" of the constrained multibodyA with respect to this 1D constraint (i.e. 1/A[i,i]) - if (multiBodyA) - { - ndofA = multiBodyA->getNumDofs() + 6; - jacA = &data.m_jacobians[solverConstraint.m_jacAindex]; - deltaVelA = &data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacAindex]; - for (int i = 0; i < ndofA; ++i) - { - btScalar j = jacA[i] ; - btScalar l = deltaVelA[i]; - denom0 += j*l; - } - } - else if(rb0) - { - vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1); - if (angConstraint) { + solverConstraint.m_multiBodyA = m_bodyA; + solverConstraint.m_multiBodyB = m_bodyB; + solverConstraint.m_linkA = m_linkA; + solverConstraint.m_linkB = m_linkB; + + btMultiBody* multiBodyA = solverConstraint.m_multiBodyA; + btMultiBody* multiBodyB = solverConstraint.m_multiBodyB; + + btSolverBody* bodyA = multiBodyA ? 0 : &data.m_solverBodyPool->at(solverConstraint.m_solverBodyIdA); + btSolverBody* bodyB = multiBodyB ? 0 : &data.m_solverBodyPool->at(solverConstraint.m_solverBodyIdB); + + btRigidBody* rb0 = multiBodyA ? 0 : bodyA->m_originalBody; + btRigidBody* rb1 = multiBodyB ? 0 : bodyB->m_originalBody; + + btVector3 rel_pos1, rel_pos2; //these two used to be inited to posAworld and posBworld (respectively) but it does not seem necessary + if (bodyA) + rel_pos1 = posAworld - bodyA->getWorldTransform().getOrigin(); + if (bodyB) + rel_pos2 = posBworld - bodyB->getWorldTransform().getOrigin(); + + if (multiBodyA) + { + if (solverConstraint.m_linkA < 0) + { + rel_pos1 = posAworld - multiBodyA->getBasePos(); + } + else + { + rel_pos1 = posAworld - multiBodyA->getLink(solverConstraint.m_linkA).m_cachedWorldTransform.getOrigin(); + } + + const int ndofA = multiBodyA->getNumDofs() + 6; + + solverConstraint.m_deltaVelAindex = multiBodyA->getCompanionId(); + + if (solverConstraint.m_deltaVelAindex < 0) + { + solverConstraint.m_deltaVelAindex = data.m_deltaVelocities.size(); + multiBodyA->setCompanionId(solverConstraint.m_deltaVelAindex); + data.m_deltaVelocities.resize(data.m_deltaVelocities.size() + ndofA); + } + else + { + btAssert(data.m_deltaVelocities.size() >= solverConstraint.m_deltaVelAindex + ndofA); + } + + //determine jacobian of this 1D constraint in terms of multibodyA's degrees of freedom + //resize.. + solverConstraint.m_jacAindex = data.m_jacobians.size(); + data.m_jacobians.resize(data.m_jacobians.size() + ndofA); + //copy/determine + if (jacOrgA) + { + for (int i = 0; i < ndofA; i++) + data.m_jacobians[solverConstraint.m_jacAindex + i] = jacOrgA[i]; + } + else + { + btScalar* jac1 = &data.m_jacobians[solverConstraint.m_jacAindex]; + //multiBodyA->fillContactJacobianMultiDof(solverConstraint.m_linkA, posAworld, constraintNormalLin, jac1, data.scratch_r, data.scratch_v, data.scratch_m); + multiBodyA->fillConstraintJacobianMultiDof(solverConstraint.m_linkA, posAworld, constraintNormalAng, constraintNormalLin, jac1, data.scratch_r, data.scratch_v, data.scratch_m); + } + + //determine the velocity response of multibodyA to reaction impulses of this constraint (i.e. A[i,i] for i=1,...n_con: multibody's inverse inertia with respect to this 1D constraint) + //resize.. + data.m_deltaVelocitiesUnitImpulse.resize(data.m_deltaVelocitiesUnitImpulse.size() + ndofA); //=> each constraint row has the constrained tree dofs allocated in m_deltaVelocitiesUnitImpulse + btAssert(data.m_jacobians.size() == data.m_deltaVelocitiesUnitImpulse.size()); + btScalar* delta = &data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacAindex]; + //determine.. + multiBodyA->calcAccelerationDeltasMultiDof(&data.m_jacobians[solverConstraint.m_jacAindex], delta, data.scratch_r, data.scratch_v); + + btVector3 torqueAxis0; + if (angConstraint) + { + torqueAxis0 = constraintNormalAng; + } + else + { + torqueAxis0 = rel_pos1.cross(constraintNormalLin); + } + solverConstraint.m_relpos1CrossNormal = torqueAxis0; + solverConstraint.m_contactNormal1 = constraintNormalLin; + } + else //if(rb0) + { + btVector3 torqueAxis0; + if (angConstraint) + { + torqueAxis0 = constraintNormalAng; + } + else + { + torqueAxis0 = rel_pos1.cross(constraintNormalLin); + } + solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld() * torqueAxis0 * rb0->getAngularFactor() : btVector3(0, 0, 0); + solverConstraint.m_relpos1CrossNormal = torqueAxis0; + solverConstraint.m_contactNormal1 = constraintNormalLin; + } + + if (multiBodyB) + { + if (solverConstraint.m_linkB < 0) + { + rel_pos2 = posBworld - multiBodyB->getBasePos(); + } + else + { + rel_pos2 = posBworld - multiBodyB->getLink(solverConstraint.m_linkB).m_cachedWorldTransform.getOrigin(); + } + + const int ndofB = multiBodyB->getNumDofs() + 6; + + solverConstraint.m_deltaVelBindex = multiBodyB->getCompanionId(); + if (solverConstraint.m_deltaVelBindex < 0) + { + solverConstraint.m_deltaVelBindex = data.m_deltaVelocities.size(); + multiBodyB->setCompanionId(solverConstraint.m_deltaVelBindex); + data.m_deltaVelocities.resize(data.m_deltaVelocities.size() + ndofB); + } + + //determine jacobian of this 1D constraint in terms of multibodyB's degrees of freedom + //resize.. + solverConstraint.m_jacBindex = data.m_jacobians.size(); + data.m_jacobians.resize(data.m_jacobians.size() + ndofB); + //copy/determine.. + if (jacOrgB) + { + for (int i = 0; i < ndofB; i++) + data.m_jacobians[solverConstraint.m_jacBindex + i] = jacOrgB[i]; + } + else + { + //multiBodyB->fillContactJacobianMultiDof(solverConstraint.m_linkB, posBworld, -constraintNormalLin, &data.m_jacobians[solverConstraint.m_jacBindex], data.scratch_r, data.scratch_v, data.scratch_m); + multiBodyB->fillConstraintJacobianMultiDof(solverConstraint.m_linkB, posBworld, -constraintNormalAng, -constraintNormalLin, &data.m_jacobians[solverConstraint.m_jacBindex], data.scratch_r, data.scratch_v, data.scratch_m); + } + + //determine velocity response of multibodyB to reaction impulses of this constraint (i.e. A[i,i] for i=1,...n_con: multibody's inverse inertia with respect to this 1D constraint) + //resize.. + data.m_deltaVelocitiesUnitImpulse.resize(data.m_deltaVelocitiesUnitImpulse.size() + ndofB); + btAssert(data.m_jacobians.size() == data.m_deltaVelocitiesUnitImpulse.size()); + btScalar* delta = &data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex]; + //determine.. + multiBodyB->calcAccelerationDeltasMultiDof(&data.m_jacobians[solverConstraint.m_jacBindex], delta, data.scratch_r, data.scratch_v); + + btVector3 torqueAxis1; + if (angConstraint) + { + torqueAxis1 = constraintNormalAng; + } + else + { + torqueAxis1 = rel_pos2.cross(constraintNormalLin); + } + solverConstraint.m_relpos2CrossNormal = -torqueAxis1; + solverConstraint.m_contactNormal2 = -constraintNormalLin; + } + else //if(rb1) + { + btVector3 torqueAxis1; + if (angConstraint) + { + torqueAxis1 = constraintNormalAng; + } + else + { + torqueAxis1 = rel_pos2.cross(constraintNormalLin); + } + solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld() * -torqueAxis1 * rb1->getAngularFactor() : btVector3(0, 0, 0); + solverConstraint.m_relpos2CrossNormal = -torqueAxis1; + solverConstraint.m_contactNormal2 = -constraintNormalLin; + } + { + btVector3 vec; + btScalar denom0 = 0.f; + btScalar denom1 = 0.f; + btScalar* jacB = 0; + btScalar* jacA = 0; + btScalar* deltaVelA = 0; + btScalar* deltaVelB = 0; + int ndofA = 0; + //determine the "effective mass" of the constrained multibodyA with respect to this 1D constraint (i.e. 1/A[i,i]) + if (multiBodyA) + { + ndofA = multiBodyA->getNumDofs() + 6; + jacA = &data.m_jacobians[solverConstraint.m_jacAindex]; + deltaVelA = &data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacAindex]; + for (int i = 0; i < ndofA; ++i) + { + btScalar j = jacA[i]; + btScalar l = deltaVelA[i]; + denom0 += j * l; + } + } + else if (rb0) + { + vec = (solverConstraint.m_angularComponentA).cross(rel_pos1); + if (angConstraint) + { denom0 = constraintNormalAng.dot(solverConstraint.m_angularComponentA); - } - else { - denom0 = rb0->getInvMass() + constraintNormalLin.dot(vec); - } - } - // - if (multiBodyB) - { - const int ndofB = multiBodyB->getNumDofs() + 6; - jacB = &data.m_jacobians[solverConstraint.m_jacBindex]; - deltaVelB = &data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex]; - for (int i = 0; i < ndofB; ++i) - { - btScalar j = jacB[i] ; - btScalar l = deltaVelB[i]; - denom1 += j*l; - } - - } - else if(rb1) - { - vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2); - if (angConstraint) { + } + else + { + denom0 = rb0->getInvMass() + constraintNormalLin.dot(vec); + } + } + // + if (multiBodyB) + { + const int ndofB = multiBodyB->getNumDofs() + 6; + jacB = &data.m_jacobians[solverConstraint.m_jacBindex]; + deltaVelB = &data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex]; + for (int i = 0; i < ndofB; ++i) + { + btScalar j = jacB[i]; + btScalar l = deltaVelB[i]; + denom1 += j * l; + } + } + else if (rb1) + { + vec = (-solverConstraint.m_angularComponentB).cross(rel_pos2); + if (angConstraint) + { denom1 = constraintNormalAng.dot(-solverConstraint.m_angularComponentB); - } - else { - denom1 = rb1->getInvMass() + constraintNormalLin.dot(vec); - } - } - - // - btScalar d = denom0+denom1; - if (d>SIMD_EPSILON) - { - solverConstraint.m_jacDiagABInv = relaxation/(d); - } - else - { - //disable the constraint row to handle singularity/redundant constraint - solverConstraint.m_jacDiagABInv = 0.f; - } - } - - - //compute rhs and remaining solverConstraint fields - btScalar penetration = isFriction? 0 : posError; - - btScalar rel_vel = 0.f; - int ndofA = 0; - int ndofB = 0; - { - btVector3 vel1,vel2; - if (multiBodyA) - { - ndofA = multiBodyA->getNumDofs() + 6; - btScalar* jacA = &data.m_jacobians[solverConstraint.m_jacAindex]; - for (int i = 0; i < ndofA ; ++i) - rel_vel += multiBodyA->getVelocityVector()[i] * jacA[i]; - } - else if(rb0) - { + } + else + { + denom1 = rb1->getInvMass() + constraintNormalLin.dot(vec); + } + } + + // + btScalar d = denom0 + denom1; + if (d > SIMD_EPSILON) + { + solverConstraint.m_jacDiagABInv = relaxation / (d); + } + else + { + //disable the constraint row to handle singularity/redundant constraint + solverConstraint.m_jacDiagABInv = 0.f; + } + } + + //compute rhs and remaining solverConstraint fields + btScalar penetration = isFriction ? 0 : posError; + + btScalar rel_vel = 0.f; + int ndofA = 0; + int ndofB = 0; + { + btVector3 vel1, vel2; + if (multiBodyA) + { + ndofA = multiBodyA->getNumDofs() + 6; + btScalar* jacA = &data.m_jacobians[solverConstraint.m_jacAindex]; + for (int i = 0; i < ndofA; ++i) + rel_vel += multiBodyA->getVelocityVector()[i] * jacA[i]; + } + else if (rb0) + { rel_vel += rb0->getLinearVelocity().dot(solverConstraint.m_contactNormal1); rel_vel += rb0->getAngularVelocity().dot(solverConstraint.m_relpos1CrossNormal); - } - if (multiBodyB) - { - ndofB = multiBodyB->getNumDofs() + 6; - btScalar* jacB = &data.m_jacobians[solverConstraint.m_jacBindex]; - for (int i = 0; i < ndofB ; ++i) - rel_vel += multiBodyB->getVelocityVector()[i] * jacB[i]; - - } - else if(rb1) - { + } + if (multiBodyB) + { + ndofB = multiBodyB->getNumDofs() + 6; + btScalar* jacB = &data.m_jacobians[solverConstraint.m_jacBindex]; + for (int i = 0; i < ndofB; ++i) + rel_vel += multiBodyB->getVelocityVector()[i] * jacB[i]; + } + else if (rb1) + { rel_vel += rb1->getLinearVelocity().dot(solverConstraint.m_contactNormal2); rel_vel += rb1->getAngularVelocity().dot(solverConstraint.m_relpos2CrossNormal); - } - - solverConstraint.m_friction = 0.f;//cp.m_combinedFriction; - } - - - ///warm starting (or zero if disabled) - /* + } + + solverConstraint.m_friction = 0.f; //cp.m_combinedFriction; + } + + ///warm starting (or zero if disabled) + /* if (infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) { solverConstraint.m_appliedImpulse = isFriction ? 0 : cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor; @@ -369,38 +375,35 @@ btScalar btMultiBodyConstraint::fillMultiBodyConstraint( btMultiBodySolverConstr } } else */ - - solverConstraint.m_appliedImpulse = 0.f; - solverConstraint.m_appliedPushImpulse = 0.f; - - { - - btScalar positionalError = 0.f; - btScalar velocityError = desiredVelocity - rel_vel;// * damping; - - - btScalar erp = infoGlobal.m_erp2; - + + solverConstraint.m_appliedImpulse = 0.f; + solverConstraint.m_appliedPushImpulse = 0.f; + + { + btScalar positionalError = 0.f; + btScalar velocityError = desiredVelocity - rel_vel; // * damping; + + btScalar erp = infoGlobal.m_erp2; + //split impulse is not implemented yet for btMultiBody* //if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold)) - { - erp = infoGlobal.m_erp; - } - - positionalError = -penetration * erp/infoGlobal.m_timeStep; - - btScalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv; - btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv; - + { + erp = infoGlobal.m_erp; + } + + positionalError = -penetration * erp / infoGlobal.m_timeStep; + + btScalar penetrationImpulse = positionalError * solverConstraint.m_jacDiagABInv; + btScalar velocityImpulse = velocityError * solverConstraint.m_jacDiagABInv; + //split impulse is not implemented yet for btMultiBody* - // if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold)) - { - //combine position and velocity into rhs - solverConstraint.m_rhs = penetrationImpulse+velocityImpulse; - solverConstraint.m_rhsPenetration = 0.f; - - } + // if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold)) + { + //combine position and velocity into rhs + solverConstraint.m_rhs = penetrationImpulse + velocityImpulse; + solverConstraint.m_rhsPenetration = 0.f; + } /*else { //split position and velocity into rhs and m_rhsPenetration @@ -409,11 +412,10 @@ btScalar btMultiBodyConstraint::fillMultiBodyConstraint( btMultiBodySolverConstr } */ - solverConstraint.m_cfm = 0.f; - solverConstraint.m_lowerLimit = lowerLimit; - solverConstraint.m_upperLimit = upperLimit; - } - - return rel_vel; - + solverConstraint.m_cfm = 0.f; + solverConstraint.m_lowerLimit = lowerLimit; + solverConstraint.m_upperLimit = upperLimit; + } + + return rel_vel; } diff --git a/src/BulletDynamics/Featherstone/btMultiBodyConstraint.h b/src/BulletDynamics/Featherstone/btMultiBodyConstraint.h index a2ae57127..5c15f3e85 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyConstraint.h +++ b/src/BulletDynamics/Featherstone/btMultiBodyConstraint.h @@ -27,66 +27,62 @@ struct btSolverInfo; struct btMultiBodyJacobianData { - btAlignedObjectArray m_jacobians; - btAlignedObjectArray m_deltaVelocitiesUnitImpulse; //holds the joint-space response of the corresp. tree to the test impulse in each constraint space dimension - btAlignedObjectArray m_deltaVelocities; //holds joint-space vectors of all the constrained trees accumulating the effect of corrective impulses applied in SI - btAlignedObjectArray scratch_r; - btAlignedObjectArray scratch_v; - btAlignedObjectArray scratch_m; - btAlignedObjectArray* m_solverBodyPool; - int m_fixedBodyId; - + btAlignedObjectArray m_jacobians; + btAlignedObjectArray m_deltaVelocitiesUnitImpulse; //holds the joint-space response of the corresp. tree to the test impulse in each constraint space dimension + btAlignedObjectArray m_deltaVelocities; //holds joint-space vectors of all the constrained trees accumulating the effect of corrective impulses applied in SI + btAlignedObjectArray scratch_r; + btAlignedObjectArray scratch_v; + btAlignedObjectArray scratch_m; + btAlignedObjectArray* m_solverBodyPool; + int m_fixedBodyId; }; - -ATTRIBUTE_ALIGNED16(class) btMultiBodyConstraint +ATTRIBUTE_ALIGNED16(class) +btMultiBodyConstraint { protected: + btMultiBody* m_bodyA; + btMultiBody* m_bodyB; + int m_linkA; + int m_linkB; - btMultiBody* m_bodyA; - btMultiBody* m_bodyB; - int m_linkA; - int m_linkB; + int m_numRows; + int m_jacSizeA; + int m_jacSizeBoth; + int m_posOffset; - int m_numRows; - int m_jacSizeA; - int m_jacSizeBoth; - int m_posOffset; + bool m_isUnilateral; + int m_numDofsFinalized; + btScalar m_maxAppliedImpulse; - bool m_isUnilateral; - int m_numDofsFinalized; - btScalar m_maxAppliedImpulse; + // warning: the data block lay out is not consistent for all constraints + // data block laid out as follows: + // cached impulses. (one per row.) + // jacobians. (interleaved, row1 body1 then row1 body2 then row2 body 1 etc) + // positions. (one per row.) + btAlignedObjectArray m_data; + void applyDeltaVee(btMultiBodyJacobianData & data, btScalar * delta_vee, btScalar impulse, int velocityIndex, int ndof); - // warning: the data block lay out is not consistent for all constraints - // data block laid out as follows: - // cached impulses. (one per row.) - // jacobians. (interleaved, row1 body1 then row1 body2 then row2 body 1 etc) - // positions. (one per row.) - btAlignedObjectArray m_data; + btScalar fillMultiBodyConstraint(btMultiBodySolverConstraint & solverConstraint, + btMultiBodyJacobianData & data, + btScalar * jacOrgA, btScalar * jacOrgB, + const btVector3& constraintNormalAng, - void applyDeltaVee(btMultiBodyJacobianData& data, btScalar* delta_vee, btScalar impulse, int velocityIndex, int ndof); - - btScalar fillMultiBodyConstraint(btMultiBodySolverConstraint& solverConstraint, - btMultiBodyJacobianData& data, - btScalar* jacOrgA, btScalar* jacOrgB, - const btVector3& constraintNormalAng, - - const btVector3& constraintNormalLin, - const btVector3& posAworld, const btVector3& posBworld, - btScalar posError, - const btContactSolverInfo& infoGlobal, - btScalar lowerLimit, btScalar upperLimit, - bool angConstraint = false, - - btScalar relaxation = 1.f, - bool isFriction = false, btScalar desiredVelocity=0, btScalar cfmSlip=0); + const btVector3& constraintNormalLin, + const btVector3& posAworld, const btVector3& posBworld, + btScalar posError, + const btContactSolverInfo& infoGlobal, + btScalar lowerLimit, btScalar upperLimit, + bool angConstraint = false, + + btScalar relaxation = 1.f, + bool isFriction = false, btScalar desiredVelocity = 0, btScalar cfmSlip = 0); public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - btMultiBodyConstraint(btMultiBody* bodyA,btMultiBody* bodyB,int linkA, int linkB, int numRows, bool isUnilateral); + btMultiBodyConstraint(btMultiBody * bodyA, btMultiBody * bodyB, int linkA, int linkB, int numRows, bool isUnilateral); virtual ~btMultiBodyConstraint(); void updateJacobianSizes(); @@ -94,27 +90,27 @@ public: //many constraints have setFrameInB/setPivotInB. Will use 'getConstraintType' later. virtual void setFrameInB(const btMatrix3x3& frameInB) {} - virtual void setPivotInB(const btVector3& pivotInB){} + virtual void setPivotInB(const btVector3& pivotInB) {} - virtual void finalizeMultiDof()=0; + virtual void finalizeMultiDof() = 0; - virtual int getIslandIdA() const =0; - virtual int getIslandIdB() const =0; + virtual int getIslandIdA() const = 0; + virtual int getIslandIdB() const = 0; - virtual void createConstraintRows(btMultiBodyConstraintArray& constraintRows, - btMultiBodyJacobianData& data, - const btContactSolverInfo& infoGlobal)=0; + virtual void createConstraintRows(btMultiBodyConstraintArray & constraintRows, + btMultiBodyJacobianData & data, + const btContactSolverInfo& infoGlobal) = 0; - int getNumRows() const + int getNumRows() const { return m_numRows; } - btMultiBody* getMultiBodyA() + btMultiBody* getMultiBodyA() { return m_bodyA; } - btMultiBody* getMultiBodyB() + btMultiBody* getMultiBodyB() { return m_bodyB; } @@ -127,77 +123,72 @@ public: { return m_linkB; } - void internalSetAppliedImpulse(int dof, btScalar appliedImpulse) + void internalSetAppliedImpulse(int dof, btScalar appliedImpulse) { - btAssert(dof>=0); + btAssert(dof >= 0); btAssert(dof < getNumRows()); m_data[dof] = appliedImpulse; - } - - btScalar getAppliedImpulse(int dof) + + btScalar getAppliedImpulse(int dof) { - btAssert(dof>=0); + btAssert(dof >= 0); btAssert(dof < getNumRows()); return m_data[dof]; } // current constraint position - // constraint is pos >= 0 for unilateral, or pos = 0 for bilateral - // NOTE: ignored position for friction rows. - btScalar getPosition(int row) const + // constraint is pos >= 0 for unilateral, or pos = 0 for bilateral + // NOTE: ignored position for friction rows. + btScalar getPosition(int row) const { return m_data[m_posOffset + row]; } - void setPosition(int row, btScalar pos) + void setPosition(int row, btScalar pos) { m_data[m_posOffset + row] = pos; } - bool isUnilateral() const { return m_isUnilateral; } // jacobian blocks. - // each of size 6 + num_links. (jacobian2 is null if no body2.) - // format: 3 'omega' coefficients, 3 'v' coefficients, then the 'qdot' coefficients. - btScalar* jacobianA(int row) + // each of size 6 + num_links. (jacobian2 is null if no body2.) + // format: 3 'omega' coefficients, 3 'v' coefficients, then the 'qdot' coefficients. + btScalar* jacobianA(int row) { return &m_data[m_numRows + row * m_jacSizeBoth]; } - const btScalar* jacobianA(int row) const + const btScalar* jacobianA(int row) const { return &m_data[m_numRows + (row * m_jacSizeBoth)]; } - btScalar* jacobianB(int row) + btScalar* jacobianB(int row) { return &m_data[m_numRows + (row * m_jacSizeBoth) + m_jacSizeA]; } - const btScalar* jacobianB(int row) const + const btScalar* jacobianB(int row) const { return &m_data[m_numRows + (row * m_jacSizeBoth) + m_jacSizeA]; } - btScalar getMaxAppliedImpulse() const + btScalar getMaxAppliedImpulse() const { return m_maxAppliedImpulse; } - void setMaxAppliedImpulse(btScalar maxImp) + void setMaxAppliedImpulse(btScalar maxImp) { m_maxAppliedImpulse = maxImp; } - virtual void debugDraw(class btIDebugDraw* drawer)=0; + virtual void debugDraw(class btIDebugDraw * drawer) = 0; virtual void setGearRatio(btScalar ratio) {} virtual void setGearAuxLink(int gearAuxLink) {} - virtual void setRelativePositionTarget(btScalar relPosTarget){} - virtual void setErp(btScalar erp){} - - + virtual void setRelativePositionTarget(btScalar relPosTarget) {} + virtual void setErp(btScalar erp) {} }; -#endif //BT_MULTIBODY_CONSTRAINT_H - +#endif //BT_MULTIBODY_CONSTRAINT_H diff --git a/src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp b/src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp index cd84826e1..60e2e5de3 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp +++ b/src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btMultiBodyConstraintSolver.h" #include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h" #include "btMultiBodyLinkCollider.h" @@ -24,33 +23,33 @@ subject to the following restrictions: #include "LinearMath/btQuickprof.h" -btScalar btMultiBodyConstraintSolver::solveSingleIteration(int iteration, btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer) +btScalar btMultiBodyConstraintSolver::solveSingleIteration(int iteration, btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer) { - btScalar leastSquaredResidual = btSequentialImpulseConstraintSolver::solveSingleIteration(iteration, bodies ,numBodies,manifoldPtr, numManifolds,constraints,numConstraints,infoGlobal,debugDrawer); - + btScalar leastSquaredResidual = btSequentialImpulseConstraintSolver::solveSingleIteration(iteration, bodies, numBodies, manifoldPtr, numManifolds, constraints, numConstraints, infoGlobal, debugDrawer); + //solve featherstone non-contact constraints //printf("m_multiBodyNonContactConstraints = %d\n",m_multiBodyNonContactConstraints.size()); - for (int j=0;jsetPosUpdated(false); - if(constraint.m_multiBodyB) + if (constraint.m_multiBodyB) constraint.m_multiBodyB->setPosUpdated(false); } //solve featherstone normal contact - for (int j0=0;j0setPosUpdated(false); - if(constraint.m_multiBodyB) + if (constraint.m_multiBodyB) constraint.m_multiBodyB->setPosUpdated(false); } //solve featherstone frictional contact - if (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS && ((infoGlobal.m_solverMode&SOLVER_DISABLE_IMPLICIT_CONE_FRICTION) == 0)) + if (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS && ((infoGlobal.m_solverMode & SOLVER_DISABLE_IMPLICIT_CONE_FRICTION) == 0)) { - for (int j1 = 0; j1m_multiBodyTorsionalFrictionContactConstraints.size(); j1++) + for (int j1 = 0; j1 < this->m_multiBodyTorsionalFrictionContactConstraints.size(); j1++) { if (iteration < infoGlobal.m_numIterations) { - int index = j1;//iteration&1? j1 : m_multiBodyTorsionalFrictionContactConstraints.size()-1-j1; + int index = j1; //iteration&1? j1 : m_multiBodyTorsionalFrictionContactConstraints.size()-1-j1; btMultiBodySolverConstraint& frictionConstraint = m_multiBodyTorsionalFrictionContactConstraints[index]; btScalar totalImpulse = m_multiBodyNormalContactConstraints[frictionConstraint.m_frictionIndex].m_appliedImpulse; //adjust friction limits here - if (totalImpulse>btScalar(0)) + if (totalImpulse > btScalar(0)) { - frictionConstraint.m_lowerLimit = -(frictionConstraint.m_friction*totalImpulse); - frictionConstraint.m_upperLimit = frictionConstraint.m_friction*totalImpulse; + frictionConstraint.m_lowerLimit = -(frictionConstraint.m_friction * totalImpulse); + frictionConstraint.m_upperLimit = frictionConstraint.m_friction * totalImpulse; btScalar residual = resolveSingleConstraintRowGeneric(frictionConstraint); - leastSquaredResidual = btMax(leastSquaredResidual , residual*residual); + leastSquaredResidual = btMax(leastSquaredResidual, residual * residual); if (frictionConstraint.m_multiBodyA) frictionConstraint.m_multiBodyA->setPosUpdated(false); @@ -99,29 +98,29 @@ btScalar btMultiBodyConstraintSolver::solveSingleIteration(int iteration, btColl { if (iteration < infoGlobal.m_numIterations) { - int index = j1;//iteration&1? j1 : m_multiBodyFrictionContactConstraints.size()-1-j1; + int index = j1; //iteration&1? j1 : m_multiBodyFrictionContactConstraints.size()-1-j1; btMultiBodySolverConstraint& frictionConstraint = m_multiBodyFrictionContactConstraints[index]; btScalar totalImpulse = m_multiBodyNormalContactConstraints[frictionConstraint.m_frictionIndex].m_appliedImpulse; j1++; - int index2 = j1;//iteration&1? j1 : m_multiBodyFrictionContactConstraints.size()-1-j1; + int index2 = j1; //iteration&1? j1 : m_multiBodyFrictionContactConstraints.size()-1-j1; btMultiBodySolverConstraint& frictionConstraintB = m_multiBodyFrictionContactConstraints[index2]; btAssert(frictionConstraint.m_frictionIndex == frictionConstraintB.m_frictionIndex); if (frictionConstraint.m_frictionIndex == frictionConstraintB.m_frictionIndex) { - frictionConstraint.m_lowerLimit = -(frictionConstraint.m_friction*totalImpulse); - frictionConstraint.m_upperLimit = frictionConstraint.m_friction*totalImpulse; - frictionConstraintB.m_lowerLimit = -(frictionConstraintB.m_friction*totalImpulse); - frictionConstraintB.m_upperLimit = frictionConstraintB.m_friction*totalImpulse; + frictionConstraint.m_lowerLimit = -(frictionConstraint.m_friction * totalImpulse); + frictionConstraint.m_upperLimit = frictionConstraint.m_friction * totalImpulse; + frictionConstraintB.m_lowerLimit = -(frictionConstraintB.m_friction * totalImpulse); + frictionConstraintB.m_upperLimit = frictionConstraintB.m_friction * totalImpulse; btScalar residual = resolveConeFrictionConstraintRows(frictionConstraint, frictionConstraintB); - leastSquaredResidual = btMax(leastSquaredResidual, residual*residual); - + leastSquaredResidual = btMax(leastSquaredResidual, residual * residual); + if (frictionConstraintB.m_multiBodyA) frictionConstraintB.m_multiBodyA->setPosUpdated(false); if (frictionConstraintB.m_multiBodyB) frictionConstraintB.m_multiBodyB->setPosUpdated(false); - + if (frictionConstraint.m_multiBodyA) frictionConstraint.m_multiBodyA->setPosUpdated(false); if (frictionConstraint.m_multiBodyB) @@ -129,26 +128,24 @@ btScalar btMultiBodyConstraintSolver::solveSingleIteration(int iteration, btColl } } } - - } else { - for (int j1 = 0; j1m_multiBodyFrictionContactConstraints.size(); j1++) + for (int j1 = 0; j1 < this->m_multiBodyFrictionContactConstraints.size(); j1++) { if (iteration < infoGlobal.m_numIterations) { - int index = j1;//iteration&1? j1 : m_multiBodyFrictionContactConstraints.size()-1-j1; + int index = j1; //iteration&1? j1 : m_multiBodyFrictionContactConstraints.size()-1-j1; btMultiBodySolverConstraint& frictionConstraint = m_multiBodyFrictionContactConstraints[index]; btScalar totalImpulse = m_multiBodyNormalContactConstraints[frictionConstraint.m_frictionIndex].m_appliedImpulse; //adjust friction limits here - if (totalImpulse>btScalar(0)) + if (totalImpulse > btScalar(0)) { - frictionConstraint.m_lowerLimit = -(frictionConstraint.m_friction*totalImpulse); - frictionConstraint.m_upperLimit = frictionConstraint.m_friction*totalImpulse; + frictionConstraint.m_lowerLimit = -(frictionConstraint.m_friction * totalImpulse); + frictionConstraint.m_upperLimit = frictionConstraint.m_friction * totalImpulse; btScalar residual = resolveSingleConstraintRowGeneric(frictionConstraint); - leastSquaredResidual = btMax(leastSquaredResidual, residual*residual); + leastSquaredResidual = btMax(leastSquaredResidual, residual * residual); if (frictionConstraint.m_multiBodyA) frictionConstraint.m_multiBodyA->setPosUpdated(false); @@ -161,18 +158,18 @@ btScalar btMultiBodyConstraintSolver::solveSingleIteration(int iteration, btColl return leastSquaredResidual; } -btScalar btMultiBodyConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer) +btScalar btMultiBodyConstraintSolver::solveGroupCacheFriendlySetup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer) { m_multiBodyNonContactConstraints.resize(0); m_multiBodyNormalContactConstraints.resize(0); m_multiBodyFrictionContactConstraints.resize(0); m_multiBodyTorsionalFrictionContactConstraints.resize(0); - + m_data.m_jacobians.resize(0); m_data.m_deltaVelocitiesUnitImpulse.resize(0); m_data.m_deltaVelocities.resize(0); - for (int i=0;iinternalGetDeltaLinearVelocity()) + c.m_relpos2CrossNormal.dot(bodyB->internalGetDeltaAngularVelocity()); } - - deltaImpulse -= deltaVelADotn*c.m_jacDiagABInv;//m_jacDiagABInv = 1./denom - deltaImpulse -= deltaVelBDotn*c.m_jacDiagABInv; + deltaImpulse -= deltaVelADotn * c.m_jacDiagABInv; //m_jacDiagABInv = 1./denom + deltaImpulse -= deltaVelBDotn * c.m_jacDiagABInv; const btScalar sum = btScalar(c.m_appliedImpulse) + deltaImpulse; if (sum < c.m_lowerLimit) @@ -246,7 +241,7 @@ btScalar btMultiBodyConstraintSolver::resolveSingleConstraintRowGeneric(const bt { c.m_appliedImpulse = sum; } - + if (c.m_multiBodyA) { applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacAindex], deltaImpulse, c.m_deltaVelAindex, ndofA); @@ -254,12 +249,11 @@ btScalar btMultiBodyConstraintSolver::resolveSingleConstraintRowGeneric(const bt //note: update of the actual velocities (below) in the multibody does not have to happen now since m_deltaVelocities can be applied after all iterations //it would make the multibody solver more like the regular one with m_deltaVelocities being equivalent to btSolverBody::m_deltaLinearVelocity/m_deltaAngularVelocity c.m_multiBodyA->applyDeltaVeeMultiDof2(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacAindex], deltaImpulse); -#endif //DIRECTLY_UPDATE_VELOCITY_DURING_SOLVER_ITERATIONS +#endif //DIRECTLY_UPDATE_VELOCITY_DURING_SOLVER_ITERATIONS } else if (c.m_solverBodyIdA >= 0) { - bodyA->internalApplyImpulse(c.m_contactNormal1*bodyA->internalGetInvMass(), c.m_angularComponentA, deltaImpulse); - + bodyA->internalApplyImpulse(c.m_contactNormal1 * bodyA->internalGetInvMass(), c.m_angularComponentA, deltaImpulse); } if (c.m_multiBodyB) { @@ -268,54 +262,54 @@ btScalar btMultiBodyConstraintSolver::resolveSingleConstraintRowGeneric(const bt //note: update of the actual velocities (below) in the multibody does not have to happen now since m_deltaVelocities can be applied after all iterations //it would make the multibody solver more like the regular one with m_deltaVelocities being equivalent to btSolverBody::m_deltaLinearVelocity/m_deltaAngularVelocity c.m_multiBodyB->applyDeltaVeeMultiDof2(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacBindex], deltaImpulse); -#endif //DIRECTLY_UPDATE_VELOCITY_DURING_SOLVER_ITERATIONS +#endif //DIRECTLY_UPDATE_VELOCITY_DURING_SOLVER_ITERATIONS } else if (c.m_solverBodyIdB >= 0) { - bodyB->internalApplyImpulse(c.m_contactNormal2*bodyB->internalGetInvMass(), c.m_angularComponentB, deltaImpulse); + bodyB->internalApplyImpulse(c.m_contactNormal2 * bodyB->internalGetInvMass(), c.m_angularComponentB, deltaImpulse); } - btScalar deltaVel =deltaImpulse/c.m_jacDiagABInv; + btScalar deltaVel = deltaImpulse / c.m_jacDiagABInv; return deltaVel; } - -btScalar btMultiBodyConstraintSolver::resolveConeFrictionConstraintRows(const btMultiBodySolverConstraint& cA1,const btMultiBodySolverConstraint& cB) +btScalar btMultiBodyConstraintSolver::resolveConeFrictionConstraintRows(const btMultiBodySolverConstraint& cA1, const btMultiBodySolverConstraint& cB) { - int ndofA=0; - int ndofB=0; + int ndofA = 0; + int ndofB = 0; btSolverBody* bodyA = 0; btSolverBody* bodyB = 0; btScalar deltaImpulseB = 0.f; btScalar sumB = 0.f; { - deltaImpulseB = cB.m_rhs-btScalar(cB.m_appliedImpulse)*cB.m_cfm; - btScalar deltaVelADotn=0; - btScalar deltaVelBDotn=0; + deltaImpulseB = cB.m_rhs - btScalar(cB.m_appliedImpulse) * cB.m_cfm; + btScalar deltaVelADotn = 0; + btScalar deltaVelBDotn = 0; if (cB.m_multiBodyA) { - ndofA = cB.m_multiBodyA->getNumDofs() + 6; - for (int i = 0; i < ndofA; ++i) - deltaVelADotn += m_data.m_jacobians[cB.m_jacAindex+i] * m_data.m_deltaVelocities[cB.m_deltaVelAindex+i]; - } else if(cB.m_solverBodyIdA >= 0) + ndofA = cB.m_multiBodyA->getNumDofs() + 6; + for (int i = 0; i < ndofA; ++i) + deltaVelADotn += m_data.m_jacobians[cB.m_jacAindex + i] * m_data.m_deltaVelocities[cB.m_deltaVelAindex + i]; + } + else if (cB.m_solverBodyIdA >= 0) { bodyA = &m_tmpSolverBodyPool[cB.m_solverBodyIdA]; - deltaVelADotn += cB.m_contactNormal1.dot(bodyA->internalGetDeltaLinearVelocity()) + cB.m_relpos1CrossNormal.dot(bodyA->internalGetDeltaAngularVelocity()); + deltaVelADotn += cB.m_contactNormal1.dot(bodyA->internalGetDeltaLinearVelocity()) + cB.m_relpos1CrossNormal.dot(bodyA->internalGetDeltaAngularVelocity()); } if (cB.m_multiBodyB) { - ndofB = cB.m_multiBodyB->getNumDofs() + 6; - for (int i = 0; i < ndofB; ++i) - deltaVelBDotn += m_data.m_jacobians[cB.m_jacBindex+i] * m_data.m_deltaVelocities[cB.m_deltaVelBindex+i]; - } else if(cB.m_solverBodyIdB >= 0) + ndofB = cB.m_multiBodyB->getNumDofs() + 6; + for (int i = 0; i < ndofB; ++i) + deltaVelBDotn += m_data.m_jacobians[cB.m_jacBindex + i] * m_data.m_deltaVelocities[cB.m_deltaVelBindex + i]; + } + else if (cB.m_solverBodyIdB >= 0) { bodyB = &m_tmpSolverBodyPool[cB.m_solverBodyIdB]; - deltaVelBDotn += cB.m_contactNormal2.dot(bodyB->internalGetDeltaLinearVelocity()) + cB.m_relpos2CrossNormal.dot(bodyB->internalGetDeltaAngularVelocity()); + deltaVelBDotn += cB.m_contactNormal2.dot(bodyB->internalGetDeltaLinearVelocity()) + cB.m_relpos2CrossNormal.dot(bodyB->internalGetDeltaAngularVelocity()); } - - deltaImpulseB -= deltaVelADotn*cB.m_jacDiagABInv;//m_jacDiagABInv = 1./denom - deltaImpulseB -= deltaVelBDotn*cB.m_jacDiagABInv; + deltaImpulseB -= deltaVelADotn * cB.m_jacDiagABInv; //m_jacDiagABInv = 1./denom + deltaImpulseB -= deltaVelBDotn * cB.m_jacDiagABInv; sumB = btScalar(cB.m_appliedImpulse) + deltaImpulseB; } @@ -324,45 +318,45 @@ btScalar btMultiBodyConstraintSolver::resolveConeFrictionConstraintRows(const bt const btMultiBodySolverConstraint& cA = cA1; { { - deltaImpulseA = cA.m_rhs-btScalar(cA.m_appliedImpulse)*cA.m_cfm; - btScalar deltaVelADotn=0; - btScalar deltaVelBDotn=0; + deltaImpulseA = cA.m_rhs - btScalar(cA.m_appliedImpulse) * cA.m_cfm; + btScalar deltaVelADotn = 0; + btScalar deltaVelBDotn = 0; if (cA.m_multiBodyA) { - ndofA = cA.m_multiBodyA->getNumDofs() + 6; - for (int i = 0; i < ndofA; ++i) - deltaVelADotn += m_data.m_jacobians[cA.m_jacAindex+i] * m_data.m_deltaVelocities[cA.m_deltaVelAindex+i]; - } else if(cA.m_solverBodyIdA >= 0) + ndofA = cA.m_multiBodyA->getNumDofs() + 6; + for (int i = 0; i < ndofA; ++i) + deltaVelADotn += m_data.m_jacobians[cA.m_jacAindex + i] * m_data.m_deltaVelocities[cA.m_deltaVelAindex + i]; + } + else if (cA.m_solverBodyIdA >= 0) { bodyA = &m_tmpSolverBodyPool[cA.m_solverBodyIdA]; - deltaVelADotn += cA.m_contactNormal1.dot(bodyA->internalGetDeltaLinearVelocity()) + cA.m_relpos1CrossNormal.dot(bodyA->internalGetDeltaAngularVelocity()); + deltaVelADotn += cA.m_contactNormal1.dot(bodyA->internalGetDeltaLinearVelocity()) + cA.m_relpos1CrossNormal.dot(bodyA->internalGetDeltaAngularVelocity()); } if (cA.m_multiBodyB) { - ndofB = cA.m_multiBodyB->getNumDofs() + 6; - for (int i = 0; i < ndofB; ++i) - deltaVelBDotn += m_data.m_jacobians[cA.m_jacBindex+i] * m_data.m_deltaVelocities[cA.m_deltaVelBindex+i]; - } else if(cA.m_solverBodyIdB >= 0) + ndofB = cA.m_multiBodyB->getNumDofs() + 6; + for (int i = 0; i < ndofB; ++i) + deltaVelBDotn += m_data.m_jacobians[cA.m_jacBindex + i] * m_data.m_deltaVelocities[cA.m_deltaVelBindex + i]; + } + else if (cA.m_solverBodyIdB >= 0) { bodyB = &m_tmpSolverBodyPool[cA.m_solverBodyIdB]; - deltaVelBDotn += cA.m_contactNormal2.dot(bodyB->internalGetDeltaLinearVelocity()) + cA.m_relpos2CrossNormal.dot(bodyB->internalGetDeltaAngularVelocity()); + deltaVelBDotn += cA.m_contactNormal2.dot(bodyB->internalGetDeltaLinearVelocity()) + cA.m_relpos2CrossNormal.dot(bodyB->internalGetDeltaAngularVelocity()); } - - deltaImpulseA -= deltaVelADotn*cA.m_jacDiagABInv;//m_jacDiagABInv = 1./denom - deltaImpulseA -= deltaVelBDotn*cA.m_jacDiagABInv; + deltaImpulseA -= deltaVelADotn * cA.m_jacDiagABInv; //m_jacDiagABInv = 1./denom + deltaImpulseA -= deltaVelBDotn * cA.m_jacDiagABInv; sumA = btScalar(cA.m_appliedImpulse) + deltaImpulseA; } } - if (sumA*sumA+sumB*sumB>=cA.m_lowerLimit*cB.m_lowerLimit) + if (sumA * sumA + sumB * sumB >= cA.m_lowerLimit * cB.m_lowerLimit) { - btScalar angle = btAtan2(sumA,sumB); - btScalar sumAclipped = btFabs(cA.m_lowerLimit*btSin(angle)); - btScalar sumBclipped = btFabs(cB.m_lowerLimit*btCos(angle)); + btScalar angle = btAtan2(sumA, sumB); + btScalar sumAclipped = btFabs(cA.m_lowerLimit * btSin(angle)); + btScalar sumBclipped = btFabs(cB.m_lowerLimit * btCos(angle)); - if (sumA < -sumAclipped) { deltaImpulseA = -sumAclipped - cA.m_appliedImpulse; @@ -396,78 +390,77 @@ btScalar btMultiBodyConstraintSolver::resolveConeFrictionConstraintRows(const bt //cA.m_appliedImpulse = sumAclipped; //deltaImpulseB = sumBclipped-cB.m_appliedImpulse; //cB.m_appliedImpulse = sumBclipped; - } + } else { cA.m_appliedImpulse = sumA; cB.m_appliedImpulse = sumB; } - + if (cA.m_multiBodyA) { - applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[cA.m_jacAindex],deltaImpulseA,cA.m_deltaVelAindex,ndofA); + applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[cA.m_jacAindex], deltaImpulseA, cA.m_deltaVelAindex, ndofA); #ifdef DIRECTLY_UPDATE_VELOCITY_DURING_SOLVER_ITERATIONS //note: update of the actual velocities (below) in the multibody does not have to happen now since m_deltaVelocities can be applied after all iterations //it would make the multibody solver more like the regular one with m_deltaVelocities being equivalent to btSolverBody::m_deltaLinearVelocity/m_deltaAngularVelocity - cA.m_multiBodyA->applyDeltaVeeMultiDof2(&m_data.m_deltaVelocitiesUnitImpulse[cA.m_jacAindex],deltaImpulseA); -#endif //DIRECTLY_UPDATE_VELOCITY_DURING_SOLVER_ITERATIONS - } else if(cA.m_solverBodyIdA >= 0) + cA.m_multiBodyA->applyDeltaVeeMultiDof2(&m_data.m_deltaVelocitiesUnitImpulse[cA.m_jacAindex], deltaImpulseA); +#endif //DIRECTLY_UPDATE_VELOCITY_DURING_SOLVER_ITERATIONS + } + else if (cA.m_solverBodyIdA >= 0) { - bodyA->internalApplyImpulse(cA.m_contactNormal1*bodyA->internalGetInvMass(),cA.m_angularComponentA,deltaImpulseA); - + bodyA->internalApplyImpulse(cA.m_contactNormal1 * bodyA->internalGetInvMass(), cA.m_angularComponentA, deltaImpulseA); } if (cA.m_multiBodyB) { - applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[cA.m_jacBindex],deltaImpulseA,cA.m_deltaVelBindex,ndofB); + applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[cA.m_jacBindex], deltaImpulseA, cA.m_deltaVelBindex, ndofB); #ifdef DIRECTLY_UPDATE_VELOCITY_DURING_SOLVER_ITERATIONS //note: update of the actual velocities (below) in the multibody does not have to happen now since m_deltaVelocities can be applied after all iterations //it would make the multibody solver more like the regular one with m_deltaVelocities being equivalent to btSolverBody::m_deltaLinearVelocity/m_deltaAngularVelocity - cA.m_multiBodyB->applyDeltaVeeMultiDof2(&m_data.m_deltaVelocitiesUnitImpulse[cA.m_jacBindex],deltaImpulseA); -#endif //DIRECTLY_UPDATE_VELOCITY_DURING_SOLVER_ITERATIONS - } else if(cA.m_solverBodyIdB >= 0) + cA.m_multiBodyB->applyDeltaVeeMultiDof2(&m_data.m_deltaVelocitiesUnitImpulse[cA.m_jacBindex], deltaImpulseA); +#endif //DIRECTLY_UPDATE_VELOCITY_DURING_SOLVER_ITERATIONS + } + else if (cA.m_solverBodyIdB >= 0) { - bodyB->internalApplyImpulse(cA.m_contactNormal2*bodyB->internalGetInvMass(),cA.m_angularComponentB,deltaImpulseA); + bodyB->internalApplyImpulse(cA.m_contactNormal2 * bodyB->internalGetInvMass(), cA.m_angularComponentB, deltaImpulseA); } if (cB.m_multiBodyA) { - applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[cB.m_jacAindex],deltaImpulseB,cB.m_deltaVelAindex,ndofA); + applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[cB.m_jacAindex], deltaImpulseB, cB.m_deltaVelAindex, ndofA); #ifdef DIRECTLY_UPDATE_VELOCITY_DURING_SOLVER_ITERATIONS //note: update of the actual velocities (below) in the multibody does not have to happen now since m_deltaVelocities can be applied after all iterations //it would make the multibody solver more like the regular one with m_deltaVelocities being equivalent to btSolverBody::m_deltaLinearVelocity/m_deltaAngularVelocity - cB.m_multiBodyA->applyDeltaVeeMultiDof2(&m_data.m_deltaVelocitiesUnitImpulse[cB.m_jacAindex],deltaImpulseB); -#endif //DIRECTLY_UPDATE_VELOCITY_DURING_SOLVER_ITERATIONS - } else if(cB.m_solverBodyIdA >= 0) + cB.m_multiBodyA->applyDeltaVeeMultiDof2(&m_data.m_deltaVelocitiesUnitImpulse[cB.m_jacAindex], deltaImpulseB); +#endif //DIRECTLY_UPDATE_VELOCITY_DURING_SOLVER_ITERATIONS + } + else if (cB.m_solverBodyIdA >= 0) { - bodyA->internalApplyImpulse(cB.m_contactNormal1*bodyA->internalGetInvMass(),cB.m_angularComponentA,deltaImpulseB); + bodyA->internalApplyImpulse(cB.m_contactNormal1 * bodyA->internalGetInvMass(), cB.m_angularComponentA, deltaImpulseB); } if (cB.m_multiBodyB) { - applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[cB.m_jacBindex],deltaImpulseB,cB.m_deltaVelBindex,ndofB); + applyDeltaVee(&m_data.m_deltaVelocitiesUnitImpulse[cB.m_jacBindex], deltaImpulseB, cB.m_deltaVelBindex, ndofB); #ifdef DIRECTLY_UPDATE_VELOCITY_DURING_SOLVER_ITERATIONS //note: update of the actual velocities (below) in the multibody does not have to happen now since m_deltaVelocities can be applied after all iterations //it would make the multibody solver more like the regular one with m_deltaVelocities being equivalent to btSolverBody::m_deltaLinearVelocity/m_deltaAngularVelocity - cB.m_multiBodyB->applyDeltaVeeMultiDof2(&m_data.m_deltaVelocitiesUnitImpulse[cB.m_jacBindex],deltaImpulseB); -#endif //DIRECTLY_UPDATE_VELOCITY_DURING_SOLVER_ITERATIONS - } else if(cB.m_solverBodyIdB >= 0) + cB.m_multiBodyB->applyDeltaVeeMultiDof2(&m_data.m_deltaVelocitiesUnitImpulse[cB.m_jacBindex], deltaImpulseB); +#endif //DIRECTLY_UPDATE_VELOCITY_DURING_SOLVER_ITERATIONS + } + else if (cB.m_solverBodyIdB >= 0) { - bodyB->internalApplyImpulse(cB.m_contactNormal2*bodyB->internalGetInvMass(),cB.m_angularComponentB,deltaImpulseB); + bodyB->internalApplyImpulse(cB.m_contactNormal2 * bodyB->internalGetInvMass(), cB.m_angularComponentB, deltaImpulseB); } - btScalar deltaVel =deltaImpulseA/cA.m_jacDiagABInv+deltaImpulseB/cB.m_jacDiagABInv; - return deltaVel; + btScalar deltaVel = deltaImpulseA / cA.m_jacDiagABInv + deltaImpulseB / cB.m_jacDiagABInv; + return deltaVel; } - - - -void btMultiBodyConstraintSolver::setupMultiBodyContactConstraint(btMultiBodySolverConstraint& solverConstraint, - const btVector3& contactNormal, - btManifoldPoint& cp, const btContactSolverInfo& infoGlobal, - btScalar& relaxation, - bool isFriction, btScalar desiredVelocity, btScalar cfmSlip) +void btMultiBodyConstraintSolver::setupMultiBodyContactConstraint(btMultiBodySolverConstraint& solverConstraint, + const btVector3& contactNormal, + btManifoldPoint& cp, const btContactSolverInfo& infoGlobal, + btScalar& relaxation, + bool isFriction, btScalar desiredVelocity, btScalar cfmSlip) { - BT_PROFILE("setupMultiBodyContactConstraint"); btVector3 rel_pos1; btVector3 rel_pos2; @@ -485,44 +478,46 @@ void btMultiBodyConstraintSolver::setupMultiBodyContactConstraint(btMultiBodySol btRigidBody* rb1 = multiBodyB ? 0 : bodyB->m_originalBody; if (bodyA) - rel_pos1 = pos1 - bodyA->getWorldTransform().getOrigin(); + rel_pos1 = pos1 - bodyA->getWorldTransform().getOrigin(); if (bodyB) rel_pos2 = pos2 - bodyB->getWorldTransform().getOrigin(); relaxation = infoGlobal.m_sor; - - btScalar invTimeStep = btScalar(1)/infoGlobal.m_timeStep; - - //cfm = 1 / ( dt * kp + kd ) - //erp = dt * kp / ( dt * kp + kd ) - - btScalar cfm; + + btScalar invTimeStep = btScalar(1) / infoGlobal.m_timeStep; + + //cfm = 1 / ( dt * kp + kd ) + //erp = dt * kp / ( dt * kp + kd ) + + btScalar cfm; btScalar erp; if (isFriction) { cfm = infoGlobal.m_frictionCFM; erp = infoGlobal.m_frictionERP; - } else + } + else { cfm = infoGlobal.m_globalCfm; erp = infoGlobal.m_erp2; - if ((cp.m_contactPointFlags&BT_CONTACT_FLAG_HAS_CONTACT_CFM) || (cp.m_contactPointFlags&BT_CONTACT_FLAG_HAS_CONTACT_ERP)) + if ((cp.m_contactPointFlags & BT_CONTACT_FLAG_HAS_CONTACT_CFM) || (cp.m_contactPointFlags & BT_CONTACT_FLAG_HAS_CONTACT_ERP)) { - if (cp.m_contactPointFlags&BT_CONTACT_FLAG_HAS_CONTACT_CFM) - cfm = cp.m_contactCFM; - if (cp.m_contactPointFlags&BT_CONTACT_FLAG_HAS_CONTACT_ERP) - erp = cp.m_contactERP; - } else + if (cp.m_contactPointFlags & BT_CONTACT_FLAG_HAS_CONTACT_CFM) + cfm = cp.m_contactCFM; + if (cp.m_contactPointFlags & BT_CONTACT_FLAG_HAS_CONTACT_ERP) + erp = cp.m_contactERP; + } + else { if (cp.m_contactPointFlags & BT_CONTACT_FLAG_CONTACT_STIFFNESS_DAMPING) { - btScalar denom = ( infoGlobal.m_timeStep * cp.m_combinedContactStiffness1 + cp.m_combinedContactDamping1 ); + btScalar denom = (infoGlobal.m_timeStep * cp.m_combinedContactStiffness1 + cp.m_combinedContactDamping1); if (denom < SIMD_EPSILON) { denom = SIMD_EPSILON; } - cfm = btScalar(1) / denom; + cfm = btScalar(1) / denom; erp = (infoGlobal.m_timeStep * cp.m_combinedContactStiffness1) / denom; } } @@ -532,218 +527,217 @@ void btMultiBodyConstraintSolver::setupMultiBodyContactConstraint(btMultiBodySol if (multiBodyA) { - if (solverConstraint.m_linkA<0) + if (solverConstraint.m_linkA < 0) { rel_pos1 = pos1 - multiBodyA->getBasePos(); - } else + } + else { rel_pos1 = pos1 - multiBodyA->getLink(solverConstraint.m_linkA).m_cachedWorldTransform.getOrigin(); } - const int ndofA = multiBodyA->getNumDofs() + 6; + const int ndofA = multiBodyA->getNumDofs() + 6; solverConstraint.m_deltaVelAindex = multiBodyA->getCompanionId(); - if (solverConstraint.m_deltaVelAindex <0) + if (solverConstraint.m_deltaVelAindex < 0) { solverConstraint.m_deltaVelAindex = m_data.m_deltaVelocities.size(); multiBodyA->setCompanionId(solverConstraint.m_deltaVelAindex); - m_data.m_deltaVelocities.resize(m_data.m_deltaVelocities.size()+ndofA); - } else + m_data.m_deltaVelocities.resize(m_data.m_deltaVelocities.size() + ndofA); + } + else { - btAssert(m_data.m_deltaVelocities.size() >= solverConstraint.m_deltaVelAindex+ndofA); + btAssert(m_data.m_deltaVelocities.size() >= solverConstraint.m_deltaVelAindex + ndofA); } solverConstraint.m_jacAindex = m_data.m_jacobians.size(); - m_data.m_jacobians.resize(m_data.m_jacobians.size()+ndofA); - m_data.m_deltaVelocitiesUnitImpulse.resize(m_data.m_deltaVelocitiesUnitImpulse.size()+ndofA); + m_data.m_jacobians.resize(m_data.m_jacobians.size() + ndofA); + m_data.m_deltaVelocitiesUnitImpulse.resize(m_data.m_deltaVelocitiesUnitImpulse.size() + ndofA); btAssert(m_data.m_jacobians.size() == m_data.m_deltaVelocitiesUnitImpulse.size()); - btScalar* jac1=&m_data.m_jacobians[solverConstraint.m_jacAindex]; + btScalar* jac1 = &m_data.m_jacobians[solverConstraint.m_jacAindex]; multiBodyA->fillContactJacobianMultiDof(solverConstraint.m_linkA, cp.getPositionWorldOnA(), contactNormal, jac1, m_data.scratch_r, m_data.scratch_v, m_data.scratch_m); btScalar* delta = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacAindex]; - multiBodyA->calcAccelerationDeltasMultiDof(&m_data.m_jacobians[solverConstraint.m_jacAindex],delta,m_data.scratch_r, m_data.scratch_v); + multiBodyA->calcAccelerationDeltasMultiDof(&m_data.m_jacobians[solverConstraint.m_jacAindex], delta, m_data.scratch_r, m_data.scratch_v); btVector3 torqueAxis0 = rel_pos1.cross(contactNormal); solverConstraint.m_relpos1CrossNormal = torqueAxis0; solverConstraint.m_contactNormal1 = contactNormal; - } else + } + else { btVector3 torqueAxis0 = rel_pos1.cross(contactNormal); solverConstraint.m_relpos1CrossNormal = torqueAxis0; solverConstraint.m_contactNormal1 = contactNormal; - solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld()*torqueAxis0*rb0->getAngularFactor() : btVector3(0,0,0); + solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld() * torqueAxis0 * rb0->getAngularFactor() : btVector3(0, 0, 0); } - - if (multiBodyB) { - if (solverConstraint.m_linkB<0) + if (solverConstraint.m_linkB < 0) { rel_pos2 = pos2 - multiBodyB->getBasePos(); - } else + } + else { rel_pos2 = pos2 - multiBodyB->getLink(solverConstraint.m_linkB).m_cachedWorldTransform.getOrigin(); } - const int ndofB = multiBodyB->getNumDofs() + 6; + const int ndofB = multiBodyB->getNumDofs() + 6; solverConstraint.m_deltaVelBindex = multiBodyB->getCompanionId(); - if (solverConstraint.m_deltaVelBindex <0) + if (solverConstraint.m_deltaVelBindex < 0) { solverConstraint.m_deltaVelBindex = m_data.m_deltaVelocities.size(); multiBodyB->setCompanionId(solverConstraint.m_deltaVelBindex); - m_data.m_deltaVelocities.resize(m_data.m_deltaVelocities.size()+ndofB); + m_data.m_deltaVelocities.resize(m_data.m_deltaVelocities.size() + ndofB); } solverConstraint.m_jacBindex = m_data.m_jacobians.size(); - m_data.m_jacobians.resize(m_data.m_jacobians.size()+ndofB); - m_data.m_deltaVelocitiesUnitImpulse.resize(m_data.m_deltaVelocitiesUnitImpulse.size()+ndofB); + m_data.m_jacobians.resize(m_data.m_jacobians.size() + ndofB); + m_data.m_deltaVelocitiesUnitImpulse.resize(m_data.m_deltaVelocitiesUnitImpulse.size() + ndofB); btAssert(m_data.m_jacobians.size() == m_data.m_deltaVelocitiesUnitImpulse.size()); multiBodyB->fillContactJacobianMultiDof(solverConstraint.m_linkB, cp.getPositionWorldOnB(), -contactNormal, &m_data.m_jacobians[solverConstraint.m_jacBindex], m_data.scratch_r, m_data.scratch_v, m_data.scratch_m); - multiBodyB->calcAccelerationDeltasMultiDof(&m_data.m_jacobians[solverConstraint.m_jacBindex],&m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex],m_data.scratch_r, m_data.scratch_v); - - btVector3 torqueAxis1 = rel_pos2.cross(contactNormal); + multiBodyB->calcAccelerationDeltasMultiDof(&m_data.m_jacobians[solverConstraint.m_jacBindex], &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex], m_data.scratch_r, m_data.scratch_v); + + btVector3 torqueAxis1 = rel_pos2.cross(contactNormal); solverConstraint.m_relpos2CrossNormal = -torqueAxis1; solverConstraint.m_contactNormal2 = -contactNormal; - - } else + } + else { - btVector3 torqueAxis1 = rel_pos2.cross(contactNormal); + btVector3 torqueAxis1 = rel_pos2.cross(contactNormal); solverConstraint.m_relpos2CrossNormal = -torqueAxis1; solverConstraint.m_contactNormal2 = -contactNormal; - - solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld()*-torqueAxis1*rb1->getAngularFactor() : btVector3(0,0,0); + + solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld() * -torqueAxis1 * rb1->getAngularFactor() : btVector3(0, 0, 0); } { - btVector3 vec; btScalar denom0 = 0.f; btScalar denom1 = 0.f; btScalar* jacB = 0; btScalar* jacA = 0; - btScalar* lambdaA =0; - btScalar* lambdaB =0; - int ndofA = 0; + btScalar* lambdaA = 0; + btScalar* lambdaB = 0; + int ndofA = 0; if (multiBodyA) { - ndofA = multiBodyA->getNumDofs() + 6; + ndofA = multiBodyA->getNumDofs() + 6; jacA = &m_data.m_jacobians[solverConstraint.m_jacAindex]; lambdaA = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacAindex]; for (int i = 0; i < ndofA; ++i) { - btScalar j = jacA[i] ; - btScalar l =lambdaA[i]; - denom0 += j*l; + btScalar j = jacA[i]; + btScalar l = lambdaA[i]; + denom0 += j * l; } - } else + } + else { if (rb0) { - vec = ( solverConstraint.m_angularComponentA).cross(rel_pos1); + vec = (solverConstraint.m_angularComponentA).cross(rel_pos1); denom0 = rb0->getInvMass() + contactNormal.dot(vec); } } if (multiBodyB) { - const int ndofB = multiBodyB->getNumDofs() + 6; + const int ndofB = multiBodyB->getNumDofs() + 6; jacB = &m_data.m_jacobians[solverConstraint.m_jacBindex]; lambdaB = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex]; for (int i = 0; i < ndofB; ++i) { - btScalar j = jacB[i] ; - btScalar l =lambdaB[i]; - denom1 += j*l; + btScalar j = jacB[i]; + btScalar l = lambdaB[i]; + denom1 += j * l; } - - } else + } + else { if (rb1) { - vec = ( -solverConstraint.m_angularComponentB).cross(rel_pos2); + vec = (-solverConstraint.m_angularComponentB).cross(rel_pos2); denom1 = rb1->getInvMass() + contactNormal.dot(vec); } } - - - btScalar d = denom0+denom1+cfm; - if (d>SIMD_EPSILON) - { - solverConstraint.m_jacDiagABInv = relaxation/(d); - } else - { + btScalar d = denom0 + denom1 + cfm; + if (d > SIMD_EPSILON) + { + solverConstraint.m_jacDiagABInv = relaxation / (d); + } + else + { //disable the constraint row to handle singularity/redundant constraint - solverConstraint.m_jacDiagABInv = 0.f; - } - + solverConstraint.m_jacDiagABInv = 0.f; + } } - //compute rhs and remaining solverConstraint fields - - btScalar restitution = 0.f; - btScalar distance = 0; - if (!isFriction) - { - distance = cp.getDistance()+infoGlobal.m_linearSlop; - } else - { - if (cp.m_contactPointFlags & BT_CONTACT_FLAG_FRICTION_ANCHOR) - { - distance = (cp.getPositionWorldOnA() - cp.getPositionWorldOnB()).dot(contactNormal); - } - } - - - btScalar rel_vel = 0.f; - int ndofA = 0; - int ndofB = 0; + btScalar distance = 0; + if (!isFriction) { + distance = cp.getDistance() + infoGlobal.m_linearSlop; + } + else + { + if (cp.m_contactPointFlags & BT_CONTACT_FLAG_FRICTION_ANCHOR) + { + distance = (cp.getPositionWorldOnA() - cp.getPositionWorldOnB()).dot(contactNormal); + } + } - btVector3 vel1,vel2; + btScalar rel_vel = 0.f; + int ndofA = 0; + int ndofB = 0; + { + btVector3 vel1, vel2; if (multiBodyA) { - ndofA = multiBodyA->getNumDofs() + 6; + ndofA = multiBodyA->getNumDofs() + 6; btScalar* jacA = &m_data.m_jacobians[solverConstraint.m_jacAindex]; - for (int i = 0; i < ndofA ; ++i) + for (int i = 0; i < ndofA; ++i) rel_vel += multiBodyA->getVelocityVector()[i] * jacA[i]; - } else + } + else { if (rb0) { - rel_vel += (rb0->getVelocityInLocalPoint(rel_pos1) + - (rb0->getTotalTorque()*rb0->getInvInertiaTensorWorld()*infoGlobal.m_timeStep).cross(rel_pos1)+ - rb0->getTotalForce()*rb0->getInvMass()*infoGlobal.m_timeStep).dot(solverConstraint.m_contactNormal1); + rel_vel += (rb0->getVelocityInLocalPoint(rel_pos1) + + (rb0->getTotalTorque() * rb0->getInvInertiaTensorWorld() * infoGlobal.m_timeStep).cross(rel_pos1) + + rb0->getTotalForce() * rb0->getInvMass() * infoGlobal.m_timeStep) + .dot(solverConstraint.m_contactNormal1); } } if (multiBodyB) { - ndofB = multiBodyB->getNumDofs() + 6; + ndofB = multiBodyB->getNumDofs() + 6; btScalar* jacB = &m_data.m_jacobians[solverConstraint.m_jacBindex]; - for (int i = 0; i < ndofB ; ++i) + for (int i = 0; i < ndofB; ++i) rel_vel += multiBodyB->getVelocityVector()[i] * jacB[i]; - - } else + } + else { if (rb1) { - rel_vel += (rb1->getVelocityInLocalPoint(rel_pos2)+ - (rb1->getTotalTorque()*rb1->getInvInertiaTensorWorld()*infoGlobal.m_timeStep).cross(rel_pos2) + - rb1->getTotalForce()*rb1->getInvMass()*infoGlobal.m_timeStep).dot(solverConstraint.m_contactNormal2); + rel_vel += (rb1->getVelocityInLocalPoint(rel_pos2) + + (rb1->getTotalTorque() * rb1->getInvInertiaTensorWorld() * infoGlobal.m_timeStep).cross(rel_pos2) + + rb1->getTotalForce() * rb1->getInvMass() * infoGlobal.m_timeStep) + .dot(solverConstraint.m_contactNormal2); } } solverConstraint.m_friction = cp.m_combinedFriction; - if(!isFriction) + if (!isFriction) { - restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution, infoGlobal.m_restitutionVelocityThreshold); + restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution, infoGlobal.m_restitutionVelocityThreshold); if (restitution <= btScalar(0.)) { restitution = 0.f; @@ -751,10 +745,9 @@ void btMultiBodyConstraintSolver::setupMultiBodyContactConstraint(btMultiBodySol } } - ///warm starting (or zero if disabled) //disable warmstarting for btMultiBody, it has issues gaining energy (==explosion) - if (0)//infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) + if (0) //infoGlobal.m_solverMode & SOLVER_USE_WARMSTARTING) { solverConstraint.m_appliedImpulse = isFriction ? 0 : cp.m_appliedImpulse * infoGlobal.m_warmstartingFactor; @@ -764,27 +757,30 @@ void btMultiBodyConstraintSolver::setupMultiBodyContactConstraint(btMultiBodySol { btScalar impulse = solverConstraint.m_appliedImpulse; btScalar* deltaV = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacAindex]; - multiBodyA->applyDeltaVeeMultiDof(deltaV,impulse); - - applyDeltaVee(deltaV,impulse,solverConstraint.m_deltaVelAindex,ndofA); - } else + multiBodyA->applyDeltaVeeMultiDof(deltaV, impulse); + + applyDeltaVee(deltaV, impulse, solverConstraint.m_deltaVelAindex, ndofA); + } + else { if (rb0) - bodyA->internalApplyImpulse(solverConstraint.m_contactNormal1*bodyA->internalGetInvMass()*rb0->getLinearFactor(),solverConstraint.m_angularComponentA,solverConstraint.m_appliedImpulse); + bodyA->internalApplyImpulse(solverConstraint.m_contactNormal1 * bodyA->internalGetInvMass() * rb0->getLinearFactor(), solverConstraint.m_angularComponentA, solverConstraint.m_appliedImpulse); } if (multiBodyB) { btScalar impulse = solverConstraint.m_appliedImpulse; btScalar* deltaV = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex]; - multiBodyB->applyDeltaVeeMultiDof(deltaV,impulse); - applyDeltaVee(deltaV,impulse,solverConstraint.m_deltaVelBindex,ndofB); - } else + multiBodyB->applyDeltaVeeMultiDof(deltaV, impulse); + applyDeltaVee(deltaV, impulse, solverConstraint.m_deltaVelBindex, ndofB); + } + else { if (rb1) - bodyB->internalApplyImpulse(-solverConstraint.m_contactNormal2*bodyB->internalGetInvMass()*rb1->getLinearFactor(),-solverConstraint.m_angularComponentB,-(btScalar)solverConstraint.m_appliedImpulse); + bodyB->internalApplyImpulse(-solverConstraint.m_contactNormal2 * bodyB->internalGetInvMass() * rb1->getLinearFactor(), -solverConstraint.m_angularComponentB, -(btScalar)solverConstraint.m_appliedImpulse); } } - } else + } + else { solverConstraint.m_appliedImpulse = 0.f; } @@ -792,38 +788,37 @@ void btMultiBodyConstraintSolver::setupMultiBodyContactConstraint(btMultiBodySol solverConstraint.m_appliedPushImpulse = 0.f; { - btScalar positionalError = 0.f; - btScalar velocityError = restitution - rel_vel;// * damping; //note for friction restitution is always set to 0 (check above) so it is acutally velocityError = -rel_vel for friction + btScalar velocityError = restitution - rel_vel; // * damping; //note for friction restitution is always set to 0 (check above) so it is acutally velocityError = -rel_vel for friction if (isFriction) { - positionalError = -distance * erp/infoGlobal.m_timeStep; - } else + positionalError = -distance * erp / infoGlobal.m_timeStep; + } + else { - if (distance>0) + if (distance > 0) { positionalError = 0; velocityError -= distance / infoGlobal.m_timeStep; - - } else + } + else { - positionalError = -distance * erp/infoGlobal.m_timeStep; + positionalError = -distance * erp / infoGlobal.m_timeStep; } } - btScalar penetrationImpulse = positionalError*solverConstraint.m_jacDiagABInv; - btScalar velocityImpulse = velocityError *solverConstraint.m_jacDiagABInv; + btScalar penetrationImpulse = positionalError * solverConstraint.m_jacDiagABInv; + btScalar velocityImpulse = velocityError * solverConstraint.m_jacDiagABInv; - if(!isFriction) + if (!isFriction) { - // if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold)) + // if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold)) { //combine position and velocity into rhs - solverConstraint.m_rhs = penetrationImpulse+velocityImpulse; + solverConstraint.m_rhs = penetrationImpulse + velocityImpulse; solverConstraint.m_rhsPenetration = 0.f; - } - /*else + /*else { //split position and velocity into rhs and m_rhsPenetration solverConstraint.m_rhs = velocityImpulse; @@ -835,309 +830,288 @@ void btMultiBodyConstraintSolver::setupMultiBodyContactConstraint(btMultiBodySol } else { - solverConstraint.m_rhs = penetrationImpulse+velocityImpulse; + solverConstraint.m_rhs = penetrationImpulse + velocityImpulse; solverConstraint.m_rhsPenetration = 0.f; solverConstraint.m_lowerLimit = -solverConstraint.m_friction; solverConstraint.m_upperLimit = solverConstraint.m_friction; } - solverConstraint.m_cfm = cfm*solverConstraint.m_jacDiagABInv; - - - + solverConstraint.m_cfm = cfm * solverConstraint.m_jacDiagABInv; } - } void btMultiBodyConstraintSolver::setupMultiBodyTorsionalFrictionConstraint(btMultiBodySolverConstraint& solverConstraint, - const btVector3& constraintNormal, - btManifoldPoint& cp, - btScalar combinedTorsionalFriction, - const btContactSolverInfo& infoGlobal, - btScalar& relaxation, - bool isFriction, btScalar desiredVelocity, btScalar cfmSlip) + const btVector3& constraintNormal, + btManifoldPoint& cp, + btScalar combinedTorsionalFriction, + const btContactSolverInfo& infoGlobal, + btScalar& relaxation, + bool isFriction, btScalar desiredVelocity, btScalar cfmSlip) { - - BT_PROFILE("setupMultiBodyRollingFrictionConstraint"); - btVector3 rel_pos1; - btVector3 rel_pos2; - - btMultiBody* multiBodyA = solverConstraint.m_multiBodyA; - btMultiBody* multiBodyB = solverConstraint.m_multiBodyB; - - const btVector3& pos1 = cp.getPositionWorldOnA(); - const btVector3& pos2 = cp.getPositionWorldOnB(); - - btSolverBody* bodyA = multiBodyA ? 0 : &m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA]; - btSolverBody* bodyB = multiBodyB ? 0 : &m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB]; - - btRigidBody* rb0 = multiBodyA ? 0 : bodyA->m_originalBody; - btRigidBody* rb1 = multiBodyB ? 0 : bodyB->m_originalBody; - - if (bodyA) - rel_pos1 = pos1 - bodyA->getWorldTransform().getOrigin(); - if (bodyB) - rel_pos2 = pos2 - bodyB->getWorldTransform().getOrigin(); - - relaxation = infoGlobal.m_sor; - - // btScalar invTimeStep = btScalar(1)/infoGlobal.m_timeStep; - - - if (multiBodyA) - { - if (solverConstraint.m_linkA<0) - { - rel_pos1 = pos1 - multiBodyA->getBasePos(); - } else - { - rel_pos1 = pos1 - multiBodyA->getLink(solverConstraint.m_linkA).m_cachedWorldTransform.getOrigin(); - } - const int ndofA = multiBodyA->getNumDofs() + 6; - - solverConstraint.m_deltaVelAindex = multiBodyA->getCompanionId(); - - if (solverConstraint.m_deltaVelAindex <0) - { - solverConstraint.m_deltaVelAindex = m_data.m_deltaVelocities.size(); - multiBodyA->setCompanionId(solverConstraint.m_deltaVelAindex); - m_data.m_deltaVelocities.resize(m_data.m_deltaVelocities.size()+ndofA); - } else - { - btAssert(m_data.m_deltaVelocities.size() >= solverConstraint.m_deltaVelAindex+ndofA); - } - - solverConstraint.m_jacAindex = m_data.m_jacobians.size(); - m_data.m_jacobians.resize(m_data.m_jacobians.size()+ndofA); - m_data.m_deltaVelocitiesUnitImpulse.resize(m_data.m_deltaVelocitiesUnitImpulse.size()+ndofA); - btAssert(m_data.m_jacobians.size() == m_data.m_deltaVelocitiesUnitImpulse.size()); - - btScalar* jac1=&m_data.m_jacobians[solverConstraint.m_jacAindex]; - multiBodyA->fillConstraintJacobianMultiDof(solverConstraint.m_linkA, cp.getPositionWorldOnA(), constraintNormal, btVector3(0,0,0), jac1, m_data.scratch_r, m_data.scratch_v, m_data.scratch_m); - btScalar* delta = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacAindex]; - multiBodyA->calcAccelerationDeltasMultiDof(&m_data.m_jacobians[solverConstraint.m_jacAindex],delta,m_data.scratch_r, m_data.scratch_v); - - btVector3 torqueAxis0 = -constraintNormal; - solverConstraint.m_relpos1CrossNormal = torqueAxis0; - solverConstraint.m_contactNormal1 = btVector3(0,0,0); - } else - { - btVector3 torqueAxis0 = -constraintNormal; - solverConstraint.m_relpos1CrossNormal = torqueAxis0; - solverConstraint.m_contactNormal1 = btVector3(0,0,0); - solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld()*torqueAxis0*rb0->getAngularFactor() : btVector3(0,0,0); - } - - - - if (multiBodyB) - { - if (solverConstraint.m_linkB<0) - { - rel_pos2 = pos2 - multiBodyB->getBasePos(); - } else - { - rel_pos2 = pos2 - multiBodyB->getLink(solverConstraint.m_linkB).m_cachedWorldTransform.getOrigin(); - } - - const int ndofB = multiBodyB->getNumDofs() + 6; - - solverConstraint.m_deltaVelBindex = multiBodyB->getCompanionId(); - if (solverConstraint.m_deltaVelBindex <0) - { - solverConstraint.m_deltaVelBindex = m_data.m_deltaVelocities.size(); - multiBodyB->setCompanionId(solverConstraint.m_deltaVelBindex); - m_data.m_deltaVelocities.resize(m_data.m_deltaVelocities.size()+ndofB); - } - - solverConstraint.m_jacBindex = m_data.m_jacobians.size(); - - m_data.m_jacobians.resize(m_data.m_jacobians.size()+ndofB); - m_data.m_deltaVelocitiesUnitImpulse.resize(m_data.m_deltaVelocitiesUnitImpulse.size()+ndofB); - btAssert(m_data.m_jacobians.size() == m_data.m_deltaVelocitiesUnitImpulse.size()); - - multiBodyB->fillConstraintJacobianMultiDof(solverConstraint.m_linkB, cp.getPositionWorldOnB(), -constraintNormal, btVector3(0,0,0), &m_data.m_jacobians[solverConstraint.m_jacBindex], m_data.scratch_r, m_data.scratch_v, m_data.scratch_m); - multiBodyB->calcAccelerationDeltasMultiDof(&m_data.m_jacobians[solverConstraint.m_jacBindex],&m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex],m_data.scratch_r, m_data.scratch_v); - - btVector3 torqueAxis1 = constraintNormal; - solverConstraint.m_relpos2CrossNormal = torqueAxis1; - solverConstraint.m_contactNormal2 = -btVector3(0,0,0); - - } else - { - btVector3 torqueAxis1 = constraintNormal; - solverConstraint.m_relpos2CrossNormal = torqueAxis1; - solverConstraint.m_contactNormal2 = -btVector3(0,0,0); - - solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld()*torqueAxis1*rb1->getAngularFactor() : btVector3(0,0,0); - } - - { - - btScalar denom0 = 0.f; - btScalar denom1 = 0.f; - btScalar* jacB = 0; - btScalar* jacA = 0; - btScalar* lambdaA =0; - btScalar* lambdaB =0; - int ndofA = 0; - if (multiBodyA) - { - ndofA = multiBodyA->getNumDofs() + 6; - jacA = &m_data.m_jacobians[solverConstraint.m_jacAindex]; - lambdaA = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacAindex]; - for (int i = 0; i < ndofA; ++i) - { - btScalar j = jacA[i] ; - btScalar l =lambdaA[i]; - denom0 += j*l; - } - } else - { - if (rb0) - { - btVector3 iMJaA = rb0?rb0->getInvInertiaTensorWorld()*solverConstraint.m_relpos1CrossNormal:btVector3(0,0,0); + BT_PROFILE("setupMultiBodyRollingFrictionConstraint"); + btVector3 rel_pos1; + btVector3 rel_pos2; + + btMultiBody* multiBodyA = solverConstraint.m_multiBodyA; + btMultiBody* multiBodyB = solverConstraint.m_multiBodyB; + + const btVector3& pos1 = cp.getPositionWorldOnA(); + const btVector3& pos2 = cp.getPositionWorldOnB(); + + btSolverBody* bodyA = multiBodyA ? 0 : &m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA]; + btSolverBody* bodyB = multiBodyB ? 0 : &m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB]; + + btRigidBody* rb0 = multiBodyA ? 0 : bodyA->m_originalBody; + btRigidBody* rb1 = multiBodyB ? 0 : bodyB->m_originalBody; + + if (bodyA) + rel_pos1 = pos1 - bodyA->getWorldTransform().getOrigin(); + if (bodyB) + rel_pos2 = pos2 - bodyB->getWorldTransform().getOrigin(); + + relaxation = infoGlobal.m_sor; + + // btScalar invTimeStep = btScalar(1)/infoGlobal.m_timeStep; + + if (multiBodyA) + { + if (solverConstraint.m_linkA < 0) + { + rel_pos1 = pos1 - multiBodyA->getBasePos(); + } + else + { + rel_pos1 = pos1 - multiBodyA->getLink(solverConstraint.m_linkA).m_cachedWorldTransform.getOrigin(); + } + const int ndofA = multiBodyA->getNumDofs() + 6; + + solverConstraint.m_deltaVelAindex = multiBodyA->getCompanionId(); + + if (solverConstraint.m_deltaVelAindex < 0) + { + solverConstraint.m_deltaVelAindex = m_data.m_deltaVelocities.size(); + multiBodyA->setCompanionId(solverConstraint.m_deltaVelAindex); + m_data.m_deltaVelocities.resize(m_data.m_deltaVelocities.size() + ndofA); + } + else + { + btAssert(m_data.m_deltaVelocities.size() >= solverConstraint.m_deltaVelAindex + ndofA); + } + + solverConstraint.m_jacAindex = m_data.m_jacobians.size(); + m_data.m_jacobians.resize(m_data.m_jacobians.size() + ndofA); + m_data.m_deltaVelocitiesUnitImpulse.resize(m_data.m_deltaVelocitiesUnitImpulse.size() + ndofA); + btAssert(m_data.m_jacobians.size() == m_data.m_deltaVelocitiesUnitImpulse.size()); + + btScalar* jac1 = &m_data.m_jacobians[solverConstraint.m_jacAindex]; + multiBodyA->fillConstraintJacobianMultiDof(solverConstraint.m_linkA, cp.getPositionWorldOnA(), constraintNormal, btVector3(0, 0, 0), jac1, m_data.scratch_r, m_data.scratch_v, m_data.scratch_m); + btScalar* delta = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacAindex]; + multiBodyA->calcAccelerationDeltasMultiDof(&m_data.m_jacobians[solverConstraint.m_jacAindex], delta, m_data.scratch_r, m_data.scratch_v); + + btVector3 torqueAxis0 = -constraintNormal; + solverConstraint.m_relpos1CrossNormal = torqueAxis0; + solverConstraint.m_contactNormal1 = btVector3(0, 0, 0); + } + else + { + btVector3 torqueAxis0 = -constraintNormal; + solverConstraint.m_relpos1CrossNormal = torqueAxis0; + solverConstraint.m_contactNormal1 = btVector3(0, 0, 0); + solverConstraint.m_angularComponentA = rb0 ? rb0->getInvInertiaTensorWorld() * torqueAxis0 * rb0->getAngularFactor() : btVector3(0, 0, 0); + } + + if (multiBodyB) + { + if (solverConstraint.m_linkB < 0) + { + rel_pos2 = pos2 - multiBodyB->getBasePos(); + } + else + { + rel_pos2 = pos2 - multiBodyB->getLink(solverConstraint.m_linkB).m_cachedWorldTransform.getOrigin(); + } + + const int ndofB = multiBodyB->getNumDofs() + 6; + + solverConstraint.m_deltaVelBindex = multiBodyB->getCompanionId(); + if (solverConstraint.m_deltaVelBindex < 0) + { + solverConstraint.m_deltaVelBindex = m_data.m_deltaVelocities.size(); + multiBodyB->setCompanionId(solverConstraint.m_deltaVelBindex); + m_data.m_deltaVelocities.resize(m_data.m_deltaVelocities.size() + ndofB); + } + + solverConstraint.m_jacBindex = m_data.m_jacobians.size(); + + m_data.m_jacobians.resize(m_data.m_jacobians.size() + ndofB); + m_data.m_deltaVelocitiesUnitImpulse.resize(m_data.m_deltaVelocitiesUnitImpulse.size() + ndofB); + btAssert(m_data.m_jacobians.size() == m_data.m_deltaVelocitiesUnitImpulse.size()); + + multiBodyB->fillConstraintJacobianMultiDof(solverConstraint.m_linkB, cp.getPositionWorldOnB(), -constraintNormal, btVector3(0, 0, 0), &m_data.m_jacobians[solverConstraint.m_jacBindex], m_data.scratch_r, m_data.scratch_v, m_data.scratch_m); + multiBodyB->calcAccelerationDeltasMultiDof(&m_data.m_jacobians[solverConstraint.m_jacBindex], &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex], m_data.scratch_r, m_data.scratch_v); + + btVector3 torqueAxis1 = constraintNormal; + solverConstraint.m_relpos2CrossNormal = torqueAxis1; + solverConstraint.m_contactNormal2 = -btVector3(0, 0, 0); + } + else + { + btVector3 torqueAxis1 = constraintNormal; + solverConstraint.m_relpos2CrossNormal = torqueAxis1; + solverConstraint.m_contactNormal2 = -btVector3(0, 0, 0); + + solverConstraint.m_angularComponentB = rb1 ? rb1->getInvInertiaTensorWorld() * torqueAxis1 * rb1->getAngularFactor() : btVector3(0, 0, 0); + } + + { + btScalar denom0 = 0.f; + btScalar denom1 = 0.f; + btScalar* jacB = 0; + btScalar* jacA = 0; + btScalar* lambdaA = 0; + btScalar* lambdaB = 0; + int ndofA = 0; + if (multiBodyA) + { + ndofA = multiBodyA->getNumDofs() + 6; + jacA = &m_data.m_jacobians[solverConstraint.m_jacAindex]; + lambdaA = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacAindex]; + for (int i = 0; i < ndofA; ++i) + { + btScalar j = jacA[i]; + btScalar l = lambdaA[i]; + denom0 += j * l; + } + } + else + { + if (rb0) + { + btVector3 iMJaA = rb0 ? rb0->getInvInertiaTensorWorld() * solverConstraint.m_relpos1CrossNormal : btVector3(0, 0, 0); denom0 = iMJaA.dot(solverConstraint.m_relpos1CrossNormal); - } - } - if (multiBodyB) - { - const int ndofB = multiBodyB->getNumDofs() + 6; - jacB = &m_data.m_jacobians[solverConstraint.m_jacBindex]; - lambdaB = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex]; - for (int i = 0; i < ndofB; ++i) - { - btScalar j = jacB[i] ; - btScalar l =lambdaB[i]; - denom1 += j*l; - } - - } else - { - if (rb1) - { - btVector3 iMJaB = rb1?rb1->getInvInertiaTensorWorld()*solverConstraint.m_relpos2CrossNormal:btVector3(0,0,0); + } + } + if (multiBodyB) + { + const int ndofB = multiBodyB->getNumDofs() + 6; + jacB = &m_data.m_jacobians[solverConstraint.m_jacBindex]; + lambdaB = &m_data.m_deltaVelocitiesUnitImpulse[solverConstraint.m_jacBindex]; + for (int i = 0; i < ndofB; ++i) + { + btScalar j = jacB[i]; + btScalar l = lambdaB[i]; + denom1 += j * l; + } + } + else + { + if (rb1) + { + btVector3 iMJaB = rb1 ? rb1->getInvInertiaTensorWorld() * solverConstraint.m_relpos2CrossNormal : btVector3(0, 0, 0); denom1 = iMJaB.dot(solverConstraint.m_relpos2CrossNormal); - } - } - - - - btScalar d = denom0+denom1+infoGlobal.m_globalCfm; - if (d>SIMD_EPSILON) - { - solverConstraint.m_jacDiagABInv = relaxation/(d); - } else - { - //disable the constraint row to handle singularity/redundant constraint - solverConstraint.m_jacDiagABInv = 0.f; - } - - } - - - //compute rhs and remaining solverConstraint fields - - - - btScalar restitution = 0.f; - btScalar penetration = isFriction? 0 : cp.getDistance(); - - btScalar rel_vel = 0.f; - int ndofA = 0; - int ndofB = 0; - { - - btVector3 vel1,vel2; - if (multiBodyA) - { - ndofA = multiBodyA->getNumDofs() + 6; - btScalar* jacA = &m_data.m_jacobians[solverConstraint.m_jacAindex]; - for (int i = 0; i < ndofA ; ++i) - rel_vel += multiBodyA->getVelocityVector()[i] * jacA[i]; - } else - { - if (rb0) - { + } + } + + btScalar d = denom0 + denom1 + infoGlobal.m_globalCfm; + if (d > SIMD_EPSILON) + { + solverConstraint.m_jacDiagABInv = relaxation / (d); + } + else + { + //disable the constraint row to handle singularity/redundant constraint + solverConstraint.m_jacDiagABInv = 0.f; + } + } + + //compute rhs and remaining solverConstraint fields + + btScalar restitution = 0.f; + btScalar penetration = isFriction ? 0 : cp.getDistance(); + + btScalar rel_vel = 0.f; + int ndofA = 0; + int ndofB = 0; + { + btVector3 vel1, vel2; + if (multiBodyA) + { + ndofA = multiBodyA->getNumDofs() + 6; + btScalar* jacA = &m_data.m_jacobians[solverConstraint.m_jacAindex]; + for (int i = 0; i < ndofA; ++i) + rel_vel += multiBodyA->getVelocityVector()[i] * jacA[i]; + } + else + { + if (rb0) + { btSolverBody* solverBodyA = &m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdA]; - rel_vel += solverConstraint.m_contactNormal1.dot(rb0?solverBodyA->m_linearVelocity+solverBodyA->m_externalForceImpulse:btVector3(0,0,0)) - + solverConstraint.m_relpos1CrossNormal.dot(rb0?solverBodyA->m_angularVelocity:btVector3(0,0,0)); - - } - } - if (multiBodyB) - { - ndofB = multiBodyB->getNumDofs() + 6; - btScalar* jacB = &m_data.m_jacobians[solverConstraint.m_jacBindex]; - for (int i = 0; i < ndofB ; ++i) - rel_vel += multiBodyB->getVelocityVector()[i] * jacB[i]; - - } else - { - if (rb1) - { + rel_vel += solverConstraint.m_contactNormal1.dot(rb0 ? solverBodyA->m_linearVelocity + solverBodyA->m_externalForceImpulse : btVector3(0, 0, 0)) + solverConstraint.m_relpos1CrossNormal.dot(rb0 ? solverBodyA->m_angularVelocity : btVector3(0, 0, 0)); + } + } + if (multiBodyB) + { + ndofB = multiBodyB->getNumDofs() + 6; + btScalar* jacB = &m_data.m_jacobians[solverConstraint.m_jacBindex]; + for (int i = 0; i < ndofB; ++i) + rel_vel += multiBodyB->getVelocityVector()[i] * jacB[i]; + } + else + { + if (rb1) + { btSolverBody* solverBodyB = &m_tmpSolverBodyPool[solverConstraint.m_solverBodyIdB]; - rel_vel += solverConstraint.m_contactNormal2.dot(rb1?solverBodyB->m_linearVelocity+solverBodyB->m_externalForceImpulse:btVector3(0,0,0)) - + solverConstraint.m_relpos2CrossNormal.dot(rb1?solverBodyB->m_angularVelocity:btVector3(0,0,0)); + rel_vel += solverConstraint.m_contactNormal2.dot(rb1 ? solverBodyB->m_linearVelocity + solverBodyB->m_externalForceImpulse : btVector3(0, 0, 0)) + solverConstraint.m_relpos2CrossNormal.dot(rb1 ? solverBodyB->m_angularVelocity : btVector3(0, 0, 0)); + } + } - } - } + solverConstraint.m_friction = combinedTorsionalFriction; - solverConstraint.m_friction =combinedTorsionalFriction; - - if(!isFriction) - { - restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution, infoGlobal.m_restitutionVelocityThreshold); - if (restitution <= btScalar(0.)) - { - restitution = 0.f; - } - } - } - - - solverConstraint.m_appliedImpulse = 0.f; - solverConstraint.m_appliedPushImpulse = 0.f; - - { - - btScalar velocityError = 0 - rel_vel;// * damping; //note for friction restitution is always set to 0 (check above) so it is acutally velocityError = -rel_vel for friction - - - - btScalar velocityImpulse = velocityError*solverConstraint.m_jacDiagABInv; - - solverConstraint.m_rhs = velocityImpulse; - solverConstraint.m_rhsPenetration = 0.f; - solverConstraint.m_lowerLimit = -solverConstraint.m_friction; - solverConstraint.m_upperLimit = solverConstraint.m_friction; - - solverConstraint.m_cfm = infoGlobal.m_globalCfm*solverConstraint.m_jacDiagABInv; - - - - } - + if (!isFriction) + { + restitution = restitutionCurve(rel_vel, cp.m_combinedRestitution, infoGlobal.m_restitutionVelocityThreshold); + if (restitution <= btScalar(0.)) + { + restitution = 0.f; + } + } + } + + solverConstraint.m_appliedImpulse = 0.f; + solverConstraint.m_appliedPushImpulse = 0.f; + + { + btScalar velocityError = 0 - rel_vel; // * damping; //note for friction restitution is always set to 0 (check above) so it is acutally velocityError = -rel_vel for friction + + btScalar velocityImpulse = velocityError * solverConstraint.m_jacDiagABInv; + + solverConstraint.m_rhs = velocityImpulse; + solverConstraint.m_rhsPenetration = 0.f; + solverConstraint.m_lowerLimit = -solverConstraint.m_friction; + solverConstraint.m_upperLimit = solverConstraint.m_friction; + + solverConstraint.m_cfm = infoGlobal.m_globalCfm * solverConstraint.m_jacDiagABInv; + } } -btMultiBodySolverConstraint& btMultiBodyConstraintSolver::addMultiBodyFrictionConstraint(const btVector3& normalAxis,btPersistentManifold* manifold,int frictionIndex,btManifoldPoint& cp,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity, btScalar cfmSlip) +btMultiBodySolverConstraint& btMultiBodyConstraintSolver::addMultiBodyFrictionConstraint(const btVector3& normalAxis, btPersistentManifold* manifold, int frictionIndex, btManifoldPoint& cp, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity, btScalar cfmSlip) { BT_PROFILE("addMultiBodyFrictionConstraint"); btMultiBodySolverConstraint& solverConstraint = m_multiBodyFrictionContactConstraints.expandNonInitializing(); - solverConstraint.m_orgConstraint = 0; - solverConstraint.m_orgDofIndex = -1; - + solverConstraint.m_orgConstraint = 0; + solverConstraint.m_orgDofIndex = -1; + solverConstraint.m_frictionIndex = frictionIndex; bool isFriction = true; const btMultiBodyLinkCollider* fcA = btMultiBodyLinkCollider::upcast(manifold->getBody0()); const btMultiBodyLinkCollider* fcB = btMultiBodyLinkCollider::upcast(manifold->getBody1()); - - btMultiBody* mbA = fcA? fcA->m_multiBody : 0; - btMultiBody* mbB = fcB? fcB->m_multiBody : 0; - int solverBodyIdA = mbA? -1 : getOrInitSolverBody(*colObj0,infoGlobal.m_timeStep); - int solverBodyIdB = mbB ? -1 : getOrInitSolverBody(*colObj1,infoGlobal.m_timeStep); + btMultiBody* mbA = fcA ? fcA->m_multiBody : 0; + btMultiBody* mbB = fcB ? fcB->m_multiBody : 0; + + int solverBodyIdA = mbA ? -1 : getOrInitSolverBody(*colObj0, infoGlobal.m_timeStep); + int solverBodyIdB = mbB ? -1 : getOrInitSolverBody(*colObj1, infoGlobal.m_timeStep); solverConstraint.m_solverBodyIdA = solverBodyIdA; solverConstraint.m_solverBodyIdB = solverBodyIdB; @@ -1151,95 +1125,92 @@ btMultiBodySolverConstraint& btMultiBodyConstraintSolver::addMultiBodyFrictionCo solverConstraint.m_originalContactPoint = &cp; - setupMultiBodyContactConstraint(solverConstraint, normalAxis, cp, infoGlobal,relaxation,isFriction, desiredVelocity, cfmSlip); + setupMultiBodyContactConstraint(solverConstraint, normalAxis, cp, infoGlobal, relaxation, isFriction, desiredVelocity, cfmSlip); return solverConstraint; } -btMultiBodySolverConstraint& btMultiBodyConstraintSolver::addMultiBodyTorsionalFrictionConstraint(const btVector3& normalAxis,btPersistentManifold* manifold,int frictionIndex,btManifoldPoint& cp, - btScalar combinedTorsionalFriction, - btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity, btScalar cfmSlip) +btMultiBodySolverConstraint& btMultiBodyConstraintSolver::addMultiBodyTorsionalFrictionConstraint(const btVector3& normalAxis, btPersistentManifold* manifold, int frictionIndex, btManifoldPoint& cp, + btScalar combinedTorsionalFriction, + btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity, btScalar cfmSlip) { - BT_PROFILE("addMultiBodyRollingFrictionConstraint"); + BT_PROFILE("addMultiBodyRollingFrictionConstraint"); - bool useTorsionalAndConeFriction = (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS && ((infoGlobal.m_solverMode&SOLVER_DISABLE_IMPLICIT_CONE_FRICTION) == 0)); + bool useTorsionalAndConeFriction = (infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS && ((infoGlobal.m_solverMode & SOLVER_DISABLE_IMPLICIT_CONE_FRICTION) == 0)); - btMultiBodySolverConstraint& solverConstraint = useTorsionalAndConeFriction? m_multiBodyTorsionalFrictionContactConstraints.expandNonInitializing() : m_multiBodyFrictionContactConstraints.expandNonInitializing(); - solverConstraint.m_orgConstraint = 0; - solverConstraint.m_orgDofIndex = -1; - - solverConstraint.m_frictionIndex = frictionIndex; - bool isFriction = true; - - const btMultiBodyLinkCollider* fcA = btMultiBodyLinkCollider::upcast(manifold->getBody0()); - const btMultiBodyLinkCollider* fcB = btMultiBodyLinkCollider::upcast(manifold->getBody1()); - - btMultiBody* mbA = fcA? fcA->m_multiBody : 0; - btMultiBody* mbB = fcB? fcB->m_multiBody : 0; - - int solverBodyIdA = mbA? -1 : getOrInitSolverBody(*colObj0,infoGlobal.m_timeStep); - int solverBodyIdB = mbB ? -1 : getOrInitSolverBody(*colObj1,infoGlobal.m_timeStep); - - solverConstraint.m_solverBodyIdA = solverBodyIdA; - solverConstraint.m_solverBodyIdB = solverBodyIdB; - solverConstraint.m_multiBodyA = mbA; - if (mbA) - solverConstraint.m_linkA = fcA->m_link; - - solverConstraint.m_multiBodyB = mbB; - if (mbB) - solverConstraint.m_linkB = fcB->m_link; - - solverConstraint.m_originalContactPoint = &cp; - - setupMultiBodyTorsionalFrictionConstraint(solverConstraint, normalAxis, cp, combinedTorsionalFriction,infoGlobal,relaxation,isFriction, desiredVelocity, cfmSlip); - return solverConstraint; + btMultiBodySolverConstraint& solverConstraint = useTorsionalAndConeFriction ? m_multiBodyTorsionalFrictionContactConstraints.expandNonInitializing() : m_multiBodyFrictionContactConstraints.expandNonInitializing(); + solverConstraint.m_orgConstraint = 0; + solverConstraint.m_orgDofIndex = -1; + + solverConstraint.m_frictionIndex = frictionIndex; + bool isFriction = true; + + const btMultiBodyLinkCollider* fcA = btMultiBodyLinkCollider::upcast(manifold->getBody0()); + const btMultiBodyLinkCollider* fcB = btMultiBodyLinkCollider::upcast(manifold->getBody1()); + + btMultiBody* mbA = fcA ? fcA->m_multiBody : 0; + btMultiBody* mbB = fcB ? fcB->m_multiBody : 0; + + int solverBodyIdA = mbA ? -1 : getOrInitSolverBody(*colObj0, infoGlobal.m_timeStep); + int solverBodyIdB = mbB ? -1 : getOrInitSolverBody(*colObj1, infoGlobal.m_timeStep); + + solverConstraint.m_solverBodyIdA = solverBodyIdA; + solverConstraint.m_solverBodyIdB = solverBodyIdB; + solverConstraint.m_multiBodyA = mbA; + if (mbA) + solverConstraint.m_linkA = fcA->m_link; + + solverConstraint.m_multiBodyB = mbB; + if (mbB) + solverConstraint.m_linkB = fcB->m_link; + + solverConstraint.m_originalContactPoint = &cp; + + setupMultiBodyTorsionalFrictionConstraint(solverConstraint, normalAxis, cp, combinedTorsionalFriction, infoGlobal, relaxation, isFriction, desiredVelocity, cfmSlip); + return solverConstraint; } -void btMultiBodyConstraintSolver::convertMultiBodyContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal) +void btMultiBodyConstraintSolver::convertMultiBodyContact(btPersistentManifold* manifold, const btContactSolverInfo& infoGlobal) { const btMultiBodyLinkCollider* fcA = btMultiBodyLinkCollider::upcast(manifold->getBody0()); const btMultiBodyLinkCollider* fcB = btMultiBodyLinkCollider::upcast(manifold->getBody1()); - - btMultiBody* mbA = fcA? fcA->m_multiBody : 0; - btMultiBody* mbB = fcB? fcB->m_multiBody : 0; - btCollisionObject* colObj0=0,*colObj1=0; + btMultiBody* mbA = fcA ? fcA->m_multiBody : 0; + btMultiBody* mbB = fcB ? fcB->m_multiBody : 0; + + btCollisionObject *colObj0 = 0, *colObj1 = 0; colObj0 = (btCollisionObject*)manifold->getBody0(); colObj1 = (btCollisionObject*)manifold->getBody1(); - int solverBodyIdA = mbA? -1 : getOrInitSolverBody(*colObj0,infoGlobal.m_timeStep); - int solverBodyIdB = mbB ? -1 : getOrInitSolverBody(*colObj1,infoGlobal.m_timeStep); - -// btSolverBody* solverBodyA = mbA ? 0 : &m_tmpSolverBodyPool[solverBodyIdA]; -// btSolverBody* solverBodyB = mbB ? 0 : &m_tmpSolverBodyPool[solverBodyIdB]; + int solverBodyIdA = mbA ? -1 : getOrInitSolverBody(*colObj0, infoGlobal.m_timeStep); + int solverBodyIdB = mbB ? -1 : getOrInitSolverBody(*colObj1, infoGlobal.m_timeStep); + // btSolverBody* solverBodyA = mbA ? 0 : &m_tmpSolverBodyPool[solverBodyIdA]; + // btSolverBody* solverBodyB = mbB ? 0 : &m_tmpSolverBodyPool[solverBodyIdB]; ///avoid collision response between two static objects -// if (!solverBodyA || (solverBodyA->m_invMass.isZero() && (!solverBodyB || solverBodyB->m_invMass.isZero()))) + // if (!solverBodyA || (solverBodyA->m_invMass.isZero() && (!solverBodyB || solverBodyB->m_invMass.isZero()))) // return; - //only a single rollingFriction per manifold - int rollingFriction=1; - - for (int j=0;jgetNumContacts();j++) - { + //only a single rollingFriction per manifold + int rollingFriction = 1; + for (int j = 0; j < manifold->getNumContacts(); j++) + { btManifoldPoint& cp = manifold->getContactPoint(j); if (cp.getDistance() <= manifold->getContactProcessingThreshold()) { - btScalar relaxation; int frictionIndex = m_multiBodyNormalContactConstraints.size(); btMultiBodySolverConstraint& solverConstraint = m_multiBodyNormalContactConstraints.expandNonInitializing(); - // btRigidBody* rb0 = btRigidBody::upcast(colObj0); - // btRigidBody* rb1 = btRigidBody::upcast(colObj1); - solverConstraint.m_orgConstraint = 0; - solverConstraint.m_orgDofIndex = -1; + // btRigidBody* rb0 = btRigidBody::upcast(colObj0); + // btRigidBody* rb1 = btRigidBody::upcast(colObj1); + solverConstraint.m_orgConstraint = 0; + solverConstraint.m_orgDofIndex = -1; solverConstraint.m_solverBodyIdA = solverBodyIdA; solverConstraint.m_solverBodyIdB = solverBodyIdB; solverConstraint.m_multiBodyA = mbA; @@ -1253,10 +1224,10 @@ void btMultiBodyConstraintSolver::convertMultiBodyContact(btPersistentManifold* solverConstraint.m_originalContactPoint = &cp; bool isFriction = false; - setupMultiBodyContactConstraint(solverConstraint, cp.m_normalWorldOnB,cp, infoGlobal, relaxation, isFriction); + setupMultiBodyContactConstraint(solverConstraint, cp.m_normalWorldOnB, cp, infoGlobal, relaxation, isFriction); -// const btVector3& pos1 = cp.getPositionWorldOnA(); -// const btVector3& pos2 = cp.getPositionWorldOnB(); + // const btVector3& pos1 = cp.getPositionWorldOnA(); + // const btVector3& pos2 = cp.getPositionWorldOnB(); /////setup the friction constraints #define ENABLE_FRICTION @@ -1267,46 +1238,45 @@ void btMultiBodyConstraintSolver::convertMultiBodyContact(btPersistentManifold* ///By default, each contact has only a single friction direction that is recomputed automatically every frame ///based on the relative linear velocity. ///If the relative velocity is zero, it will automatically compute a friction direction. - + ///You can also enable two friction directions, using the SOLVER_USE_2_FRICTION_DIRECTIONS. ///In that case, the second friction direction will be orthogonal to both contact normal and first friction direction. /// ///If you choose SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION, then the friction will be independent from the relative projected velocity. /// - ///The user can manually override the friction directions for certain contacts using a contact callback, + ///The user can manually override the friction directions for certain contacts using a contact callback, ///and set the cp.m_lateralFrictionInitialized to true ///In that case, you can set the target relative motion in each friction direction (cp.m_contactMotion1 and cp.m_contactMotion2) ///this will give a conveyor belt effect /// - btPlaneSpace1(cp.m_normalWorldOnB,cp.m_lateralFrictionDir1,cp.m_lateralFrictionDir2); + btPlaneSpace1(cp.m_normalWorldOnB, cp.m_lateralFrictionDir1, cp.m_lateralFrictionDir2); cp.m_lateralFrictionDir1.normalize(); cp.m_lateralFrictionDir2.normalize(); - if (rollingFriction > 0 ) - { - if (cp.m_combinedSpinningFriction>0) - { - addMultiBodyTorsionalFrictionConstraint(cp.m_normalWorldOnB,manifold,frictionIndex,cp,cp.m_combinedSpinningFriction, colObj0,colObj1, relaxation,infoGlobal); - } - if (cp.m_combinedRollingFriction>0) - { + if (rollingFriction > 0) + { + if (cp.m_combinedSpinningFriction > 0) + { + addMultiBodyTorsionalFrictionConstraint(cp.m_normalWorldOnB, manifold, frictionIndex, cp, cp.m_combinedSpinningFriction, colObj0, colObj1, relaxation, infoGlobal); + } + if (cp.m_combinedRollingFriction > 0) + { + applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); + applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); + applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); + applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); - applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); - applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); - applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); - applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_ROLLING_FRICTION); - - if (cp.m_lateralFrictionDir1.length()>0.001) - addMultiBodyTorsionalFrictionConstraint(cp.m_lateralFrictionDir1,manifold,frictionIndex,cp,cp.m_combinedRollingFriction, colObj0,colObj1, relaxation,infoGlobal); + if (cp.m_lateralFrictionDir1.length() > 0.001) + addMultiBodyTorsionalFrictionConstraint(cp.m_lateralFrictionDir1, manifold, frictionIndex, cp, cp.m_combinedRollingFriction, colObj0, colObj1, relaxation, infoGlobal); - if (cp.m_lateralFrictionDir2.length()>0.001) - addMultiBodyTorsionalFrictionConstraint(cp.m_lateralFrictionDir2,manifold,frictionIndex,cp,cp.m_combinedRollingFriction, colObj0,colObj1, relaxation,infoGlobal); - } - rollingFriction--; - } - if (!(infoGlobal.m_solverMode & SOLVER_ENABLE_FRICTION_DIRECTION_CACHING) || !(cp.m_contactPointFlags&BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED)) - {/* + if (cp.m_lateralFrictionDir2.length() > 0.001) + addMultiBodyTorsionalFrictionConstraint(cp.m_lateralFrictionDir2, manifold, frictionIndex, cp, cp.m_combinedRollingFriction, colObj0, colObj1, relaxation, infoGlobal); + } + rollingFriction--; + } + if (!(infoGlobal.m_solverMode & SOLVER_ENABLE_FRICTION_DIRECTION_CACHING) || !(cp.m_contactPointFlags & BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED)) + { /* cp.m_lateralFrictionDir1 = vel - cp.m_normalWorldOnB * rel_vel; btScalar lat_rel_vel = cp.m_lateralFrictionDir1.length2(); if (!(infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION) && lat_rel_vel > SIMD_EPSILON) @@ -1329,85 +1299,77 @@ void btMultiBodyConstraintSolver::convertMultiBodyContact(btPersistentManifold* } else */ { - - - applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION); - applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir1,btCollisionObject::CF_ANISOTROPIC_FRICTION); - addMultiBodyFrictionConstraint(cp.m_lateralFrictionDir1,manifold,frictionIndex,cp,colObj0,colObj1, relaxation,infoGlobal); - + applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION); + applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir1, btCollisionObject::CF_ANISOTROPIC_FRICTION); + addMultiBodyFrictionConstraint(cp.m_lateralFrictionDir1, manifold, frictionIndex, cp, colObj0, colObj1, relaxation, infoGlobal); if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) { - applyAnisotropicFriction(colObj0,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION); - applyAnisotropicFriction(colObj1,cp.m_lateralFrictionDir2,btCollisionObject::CF_ANISOTROPIC_FRICTION); - addMultiBodyFrictionConstraint(cp.m_lateralFrictionDir2,manifold,frictionIndex,cp,colObj0,colObj1, relaxation,infoGlobal); + applyAnisotropicFriction(colObj0, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION); + applyAnisotropicFriction(colObj1, cp.m_lateralFrictionDir2, btCollisionObject::CF_ANISOTROPIC_FRICTION); + addMultiBodyFrictionConstraint(cp.m_lateralFrictionDir2, manifold, frictionIndex, cp, colObj0, colObj1, relaxation, infoGlobal); } if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS) && (infoGlobal.m_solverMode & SOLVER_DISABLE_VELOCITY_DEPENDENT_FRICTION_DIRECTION)) { - cp.m_contactPointFlags|=BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED; + cp.m_contactPointFlags |= BT_CONTACT_FLAG_LATERAL_FRICTION_INITIALIZED; } } - - } else + } + else { - addMultiBodyFrictionConstraint(cp.m_lateralFrictionDir1,manifold,frictionIndex,cp,colObj0,colObj1, relaxation,infoGlobal,cp.m_contactMotion1, cp.m_frictionCFM); + addMultiBodyFrictionConstraint(cp.m_lateralFrictionDir1, manifold, frictionIndex, cp, colObj0, colObj1, relaxation, infoGlobal, cp.m_contactMotion1, cp.m_frictionCFM); if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) - addMultiBodyFrictionConstraint(cp.m_lateralFrictionDir2,manifold,frictionIndex,cp,colObj0,colObj1, relaxation, infoGlobal,cp.m_contactMotion2, cp.m_frictionCFM); + addMultiBodyFrictionConstraint(cp.m_lateralFrictionDir2, manifold, frictionIndex, cp, colObj0, colObj1, relaxation, infoGlobal, cp.m_contactMotion2, cp.m_frictionCFM); //setMultiBodyFrictionConstraintImpulse( solverConstraint, solverBodyIdA, solverBodyIdB, cp, infoGlobal); //todo: solverConstraint.m_appliedImpulse = 0.f; solverConstraint.m_appliedPushImpulse = 0.f; } - - -#endif //ENABLE_FRICTION +#endif //ENABLE_FRICTION } } } -void btMultiBodyConstraintSolver::convertContacts(btPersistentManifold** manifoldPtr,int numManifolds, const btContactSolverInfo& infoGlobal) +void btMultiBodyConstraintSolver::convertContacts(btPersistentManifold** manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal) { //btPersistentManifold* manifold = 0; - for (int i=0;igetBody0()); const btMultiBodyLinkCollider* fcB = btMultiBodyLinkCollider::upcast(manifold->getBody1()); if (!fcA && !fcB) { //the contact doesn't involve any Featherstone btMultiBody, so deal with the regular btRigidBody/btCollisionObject case - convertContact(manifold,infoGlobal); - } else + convertContact(manifold, infoGlobal); + } + else { - convertMultiBodyContact(manifold,infoGlobal); + convertMultiBodyContact(manifold, infoGlobal); } } //also convert the multibody constraints, if any - - for (int i=0;icreateConstraintRows(m_multiBodyNonContactConstraints,m_data, infoGlobal); - } + c->createConstraintRows(m_multiBodyNonContactConstraints, m_data, infoGlobal); + } } - - -btScalar btMultiBodyConstraintSolver::solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer,btDispatcher* dispatcher) +btScalar btMultiBodyConstraintSolver::solveGroup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifold, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btDispatcher* dispatcher) { //printf("btMultiBodyConstraintSolver::solveGroup: numBodies=%d, numConstraints=%d\n", numBodies, numConstraints); - return btSequentialImpulseConstraintSolver::solveGroup(bodies,numBodies,manifold,numManifolds,constraints,numConstraints,info,debugDrawer,dispatcher); + return btSequentialImpulseConstraintSolver::solveGroup(bodies, numBodies, manifold, numManifolds, constraints, numConstraints, info, debugDrawer, dispatcher); } #if 0 @@ -1431,56 +1393,54 @@ static void applyJointFeedback(btMultiBodyJacobianData& data, const btMultiBodyS } #endif - void btMultiBodyConstraintSolver::writeBackSolverBodyToMultiBody(btMultiBodySolverConstraint& c, btScalar deltaTime) { -#if 1 - +#if 1 + //bod->addBaseForce(m_gravity * bod->getBaseMass()); //bod->addLinkForce(j, m_gravity * bod->getLinkMass(j)); if (c.m_orgConstraint) { - c.m_orgConstraint->internalSetAppliedImpulse(c.m_orgDofIndex,c.m_appliedImpulse); + c.m_orgConstraint->internalSetAppliedImpulse(c.m_orgDofIndex, c.m_appliedImpulse); } - if (c.m_multiBodyA) { - c.m_multiBodyA->setCompanionId(-1); - btVector3 force = c.m_contactNormal1*(c.m_appliedImpulse/deltaTime); - btVector3 torque = c.m_relpos1CrossNormal*(c.m_appliedImpulse/deltaTime); - if (c.m_linkA<0) + btVector3 force = c.m_contactNormal1 * (c.m_appliedImpulse / deltaTime); + btVector3 torque = c.m_relpos1CrossNormal * (c.m_appliedImpulse / deltaTime); + if (c.m_linkA < 0) { c.m_multiBodyA->addBaseConstraintForce(force); c.m_multiBodyA->addBaseConstraintTorque(torque); - } else + } + else { - c.m_multiBodyA->addLinkConstraintForce(c.m_linkA,force); - //b3Printf("force = %f,%f,%f\n",force[0],force[1],force[2]);//[0],torque[1],torque[2]); - c.m_multiBodyA->addLinkConstraintTorque(c.m_linkA,torque); + c.m_multiBodyA->addLinkConstraintForce(c.m_linkA, force); + //b3Printf("force = %f,%f,%f\n",force[0],force[1],force[2]);//[0],torque[1],torque[2]); + c.m_multiBodyA->addLinkConstraintTorque(c.m_linkA, torque); } } - + if (c.m_multiBodyB) { { c.m_multiBodyB->setCompanionId(-1); - btVector3 force = c.m_contactNormal2*(c.m_appliedImpulse/deltaTime); - btVector3 torque = c.m_relpos2CrossNormal*(c.m_appliedImpulse/deltaTime); - if (c.m_linkB<0) + btVector3 force = c.m_contactNormal2 * (c.m_appliedImpulse / deltaTime); + btVector3 torque = c.m_relpos2CrossNormal * (c.m_appliedImpulse / deltaTime); + if (c.m_linkB < 0) { c.m_multiBodyB->addBaseConstraintForce(force); c.m_multiBodyB->addBaseConstraintTorque(torque); - } else + } + else { { - c.m_multiBodyB->addLinkConstraintForce(c.m_linkB,force); + c.m_multiBodyB->addLinkConstraintForce(c.m_linkB, force); //b3Printf("t = %f,%f,%f\n",force[0],force[1],force[2]);//[0],torque[1],torque[2]); - c.m_multiBodyB->addLinkConstraintTorque(c.m_linkB,torque); + c.m_multiBodyB->addLinkConstraintTorque(c.m_linkB, torque); } - } } } @@ -1490,63 +1450,57 @@ void btMultiBodyConstraintSolver::writeBackSolverBodyToMultiBody(btMultiBodySolv if (c.m_multiBodyA) { - c.m_multiBodyA->applyDeltaVeeMultiDof(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacAindex],c.m_appliedImpulse); + c.m_multiBodyA->applyDeltaVeeMultiDof(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacAindex], c.m_appliedImpulse); } - + if (c.m_multiBodyB) { - c.m_multiBodyB->applyDeltaVeeMultiDof(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacBindex],c.m_appliedImpulse); + c.m_multiBodyB->applyDeltaVeeMultiDof(&m_data.m_deltaVelocitiesUnitImpulse[c.m_jacBindex], c.m_appliedImpulse); } #endif - - - } -btScalar btMultiBodyConstraintSolver::solveGroupCacheFriendlyFinish(btCollisionObject** bodies,int numBodies,const btContactSolverInfo& infoGlobal) +btScalar btMultiBodyConstraintSolver::solveGroupCacheFriendlyFinish(btCollisionObject** bodies, int numBodies, const btContactSolverInfo& infoGlobal) { BT_PROFILE("btMultiBodyConstraintSolver::solveGroupCacheFriendlyFinish"); int numPoolConstraints = m_multiBodyNormalContactConstraints.size(); - - //write back the delta v to the multi bodies, either as applied impulse (direct velocity change) + //write back the delta v to the multi bodies, either as applied impulse (direct velocity change) //or as applied force, so we can measure the joint reaction forces easier - for (int i=0;im_appliedImpulse = solverConstraint.m_appliedImpulse; pt->m_appliedImpulseLateral1 = m_multiBodyFrictionContactConstraints[solverConstraint.m_frictionIndex].m_appliedImpulse; - + //printf("pt->m_appliedImpulseLateral1 = %f\n", pt->m_appliedImpulseLateral1); if ((infoGlobal.m_solverMode & SOLVER_USE_2_FRICTION_DIRECTIONS)) { - pt->m_appliedImpulseLateral2 = m_multiBodyFrictionContactConstraints[solverConstraint.m_frictionIndex+1].m_appliedImpulse; + pt->m_appliedImpulseLateral2 = m_multiBodyFrictionContactConstraints[solverConstraint.m_frictionIndex + 1].m_appliedImpulse; } //do a callback here? } @@ -1648,25 +1602,22 @@ btScalar btMultiBodyConstraintSolver::solveGroupCacheFriendlyFinish(btCollisionO } } -#endif +#endif #endif - return btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinish(bodies,numBodies,infoGlobal); + return btSequentialImpulseConstraintSolver::solveGroupCacheFriendlyFinish(bodies, numBodies, infoGlobal); } - -void btMultiBodyConstraintSolver::solveMultiBodyGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,btMultiBodyConstraint** multiBodyConstraints, int numMultiBodyConstraints, const btContactSolverInfo& info, btIDebugDraw* debugDrawer,btDispatcher* dispatcher) +void btMultiBodyConstraintSolver::solveMultiBodyGroup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifold, int numManifolds, btTypedConstraint** constraints, int numConstraints, btMultiBodyConstraint** multiBodyConstraints, int numMultiBodyConstraints, const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btDispatcher* dispatcher) { //printf("solveMultiBodyGroup: numBodies=%d, numConstraints=%d, numManifolds=%d, numMultiBodyConstraints=%d\n", numBodies, numConstraints, numManifolds, numMultiBodyConstraints); //printf("solveMultiBodyGroup start\n"); m_tmpMultiBodyConstraints = multiBodyConstraints; m_tmpNumMultiBodyConstraints = numMultiBodyConstraints; - - btSequentialImpulseConstraintSolver::solveGroup(bodies,numBodies,manifold,numManifolds,constraints,numConstraints,info,debugDrawer,dispatcher); + + btSequentialImpulseConstraintSolver::solveGroup(bodies, numBodies, manifold, numManifolds, constraints, numConstraints, info, debugDrawer, dispatcher); m_tmpMultiBodyConstraints = 0; m_tmpNumMultiBodyConstraints = 0; - - } diff --git a/src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h b/src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h index 29f484e1d..f39f2879f 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h +++ b/src/BulletDynamics/Featherstone/btMultiBodyConstraintSolver.h @@ -25,80 +25,71 @@ class btMultiBody; #include "btMultiBodyConstraint.h" - - -ATTRIBUTE_ALIGNED16(class) btMultiBodyConstraintSolver : public btSequentialImpulseConstraintSolver +ATTRIBUTE_ALIGNED16(class) +btMultiBodyConstraintSolver : public btSequentialImpulseConstraintSolver { - protected: + btMultiBodyConstraintArray m_multiBodyNonContactConstraints; - btMultiBodyConstraintArray m_multiBodyNonContactConstraints; + btMultiBodyConstraintArray m_multiBodyNormalContactConstraints; + btMultiBodyConstraintArray m_multiBodyFrictionContactConstraints; + btMultiBodyConstraintArray m_multiBodyTorsionalFrictionContactConstraints; - btMultiBodyConstraintArray m_multiBodyNormalContactConstraints; - btMultiBodyConstraintArray m_multiBodyFrictionContactConstraints; - btMultiBodyConstraintArray m_multiBodyTorsionalFrictionContactConstraints; + btMultiBodyJacobianData m_data; - btMultiBodyJacobianData m_data; - //temp storage for multi body constraints for a specific island/group called by 'solveGroup' - btMultiBodyConstraint** m_tmpMultiBodyConstraints; - int m_tmpNumMultiBodyConstraints; + btMultiBodyConstraint** m_tmpMultiBodyConstraints; + int m_tmpNumMultiBodyConstraints; btScalar resolveSingleConstraintRowGeneric(const btMultiBodySolverConstraint& c); - + //solve 2 friction directions and clamp against the implicit friction cone btScalar resolveConeFrictionConstraintRows(const btMultiBodySolverConstraint& cA1, const btMultiBodySolverConstraint& cB); - - void convertContacts(btPersistentManifold** manifoldPtr,int numManifolds, const btContactSolverInfo& infoGlobal); - - btMultiBodySolverConstraint& addMultiBodyFrictionConstraint(const btVector3& normalAxis,btPersistentManifold* manifold,int frictionIndex,btManifoldPoint& cp,btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity=0, btScalar cfmSlip=0); + void convertContacts(btPersistentManifold * *manifoldPtr, int numManifolds, const btContactSolverInfo& infoGlobal); - btMultiBodySolverConstraint& addMultiBodyTorsionalFrictionConstraint(const btVector3& normalAxis,btPersistentManifold* manifold,int frictionIndex,btManifoldPoint& cp, - btScalar combinedTorsionalFriction, - btCollisionObject* colObj0,btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity=0, btScalar cfmSlip=0); + btMultiBodySolverConstraint& addMultiBodyFrictionConstraint(const btVector3& normalAxis, btPersistentManifold* manifold, int frictionIndex, btManifoldPoint& cp, btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity = 0, btScalar cfmSlip = 0); - void setupMultiBodyJointLimitConstraint(btMultiBodySolverConstraint& constraintRow, - btScalar* jacA,btScalar* jacB, - btScalar penetration,btScalar combinedFrictionCoeff, btScalar combinedRestitutionCoeff, - const btContactSolverInfo& infoGlobal); + btMultiBodySolverConstraint& addMultiBodyTorsionalFrictionConstraint(const btVector3& normalAxis, btPersistentManifold* manifold, int frictionIndex, btManifoldPoint& cp, + btScalar combinedTorsionalFriction, + btCollisionObject* colObj0, btCollisionObject* colObj1, btScalar relaxation, const btContactSolverInfo& infoGlobal, btScalar desiredVelocity = 0, btScalar cfmSlip = 0); - void setupMultiBodyContactConstraint(btMultiBodySolverConstraint& solverConstraint, - const btVector3& contactNormal, - btManifoldPoint& cp, const btContactSolverInfo& infoGlobal, - btScalar& relaxation, - bool isFriction, btScalar desiredVelocity=0, btScalar cfmSlip=0); - - //either rolling or spinning friction - void setupMultiBodyTorsionalFrictionConstraint(btMultiBodySolverConstraint& solverConstraint, - const btVector3& contactNormal, - btManifoldPoint& cp, - btScalar combinedTorsionalFriction, - const btContactSolverInfo& infoGlobal, - btScalar& relaxation, - bool isFriction, btScalar desiredVelocity=0, btScalar cfmSlip=0); + void setupMultiBodyJointLimitConstraint(btMultiBodySolverConstraint & constraintRow, + btScalar * jacA, btScalar * jacB, + btScalar penetration, btScalar combinedFrictionCoeff, btScalar combinedRestitutionCoeff, + const btContactSolverInfo& infoGlobal); - void convertMultiBodyContact(btPersistentManifold* manifold,const btContactSolverInfo& infoGlobal); - virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer); -// virtual btScalar solveGroupCacheFriendlyIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer); + void setupMultiBodyContactConstraint(btMultiBodySolverConstraint & solverConstraint, + const btVector3& contactNormal, + btManifoldPoint& cp, const btContactSolverInfo& infoGlobal, + btScalar& relaxation, + bool isFriction, btScalar desiredVelocity = 0, btScalar cfmSlip = 0); + + //either rolling or spinning friction + void setupMultiBodyTorsionalFrictionConstraint(btMultiBodySolverConstraint & solverConstraint, + const btVector3& contactNormal, + btManifoldPoint& cp, + btScalar combinedTorsionalFriction, + const btContactSolverInfo& infoGlobal, + btScalar& relaxation, + bool isFriction, btScalar desiredVelocity = 0, btScalar cfmSlip = 0); + + void convertMultiBodyContact(btPersistentManifold * manifold, const btContactSolverInfo& infoGlobal); + virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer); + // virtual btScalar solveGroupCacheFriendlyIterations(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer); + + virtual btScalar solveSingleIteration(int iteration, btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer); + void applyDeltaVee(btScalar * deltaV, btScalar impulse, int velocityIndex, int ndof); + void writeBackSolverBodyToMultiBody(btMultiBodySolverConstraint & constraint, btScalar deltaTime); - virtual btScalar solveSingleIteration(int iteration, btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer); - void applyDeltaVee(btScalar* deltaV, btScalar impulse, int velocityIndex, int ndof); - void writeBackSolverBodyToMultiBody(btMultiBodySolverConstraint& constraint, btScalar deltaTime); public: - BT_DECLARE_ALIGNED_ALLOCATOR(); ///this method should not be called, it was just used during porting/integration of Featherstone btMultiBody, providing backwards compatibility but no support for btMultiBodyConstraint (only contact constraints) - virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer,btDispatcher* dispatcher); - virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject** bodies,int numBodies,const btContactSolverInfo& infoGlobal); - - virtual void solveMultiBodyGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,btMultiBodyConstraint** multiBodyConstraints, int numMultiBodyConstraints, const btContactSolverInfo& info, btIDebugDraw* debugDrawer,btDispatcher* dispatcher); + virtual btScalar solveGroup(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifold, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btDispatcher* dispatcher); + virtual btScalar solveGroupCacheFriendlyFinish(btCollisionObject * *bodies, int numBodies, const btContactSolverInfo& infoGlobal); + + virtual void solveMultiBodyGroup(btCollisionObject * *bodies, int numBodies, btPersistentManifold** manifold, int numManifolds, btTypedConstraint** constraints, int numConstraints, btMultiBodyConstraint** multiBodyConstraints, int numMultiBodyConstraints, const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btDispatcher* dispatcher); }; - - - - -#endif //BT_MULTIBODY_CONSTRAINT_SOLVER_H - +#endif //BT_MULTIBODY_CONSTRAINT_SOLVER_H diff --git a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp index 9c5f3ad8a..a452d61b7 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp +++ b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.cpp @@ -23,45 +23,43 @@ subject to the following restrictions: #include "LinearMath/btIDebugDraw.h" #include "LinearMath/btSerializer.h" - -void btMultiBodyDynamicsWorld::addMultiBody(btMultiBody* body, int group, int mask) +void btMultiBodyDynamicsWorld::addMultiBody(btMultiBody* body, int group, int mask) { m_multiBodies.push_back(body); - } -void btMultiBodyDynamicsWorld::removeMultiBody(btMultiBody* body) +void btMultiBodyDynamicsWorld::removeMultiBody(btMultiBody* body) { m_multiBodies.remove(body); } -void btMultiBodyDynamicsWorld::calculateSimulationIslands() +void btMultiBodyDynamicsWorld::calculateSimulationIslands() { BT_PROFILE("calculateSimulationIslands"); - getSimulationIslandManager()->updateActivationState(getCollisionWorld(),getCollisionWorld()->getDispatcher()); + getSimulationIslandManager()->updateActivationState(getCollisionWorld(), getCollisionWorld()->getDispatcher()); + + { + //merge islands based on speculative contact manifolds too + for (int i = 0; i < this->m_predictiveManifolds.size(); i++) + { + btPersistentManifold* manifold = m_predictiveManifolds[i]; + + const btCollisionObject* colObj0 = manifold->getBody0(); + const btCollisionObject* colObj1 = manifold->getBody1(); + + if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) && + ((colObj1) && (!(colObj1)->isStaticOrKinematicObject()))) + { + getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(), (colObj1)->getIslandTag()); + } + } + } - { - //merge islands based on speculative contact manifolds too - for (int i=0;im_predictiveManifolds.size();i++) - { - btPersistentManifold* manifold = m_predictiveManifolds[i]; - - const btCollisionObject* colObj0 = manifold->getBody0(); - const btCollisionObject* colObj1 = manifold->getBody1(); - - if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) && - ((colObj1) && (!(colObj1)->isStaticOrKinematicObject()))) - { - getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag()); - } - } - } - { int i; int numConstraints = int(m_constraints.size()); - for (i=0;i< numConstraints ; i++ ) + for (i = 0; i < numConstraints; i++) { btTypedConstraint* constraint = m_constraints[i]; if (constraint->isEnabled()) @@ -72,23 +70,23 @@ void btMultiBodyDynamicsWorld::calculateSimulationIslands() if (((colObj0) && (!(colObj0)->isStaticOrKinematicObject())) && ((colObj1) && (!(colObj1)->isStaticOrKinematicObject()))) { - getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(),(colObj1)->getIslandTag()); + getSimulationIslandManager()->getUnionFind().unite((colObj0)->getIslandTag(), (colObj1)->getIslandTag()); } } } } //merge islands linked by Featherstone link colliders - for (int i=0;igetBaseCollider(); - for (int b=0;bgetNumLinks();b++) + for (int b = 0; b < body->getNumLinks(); b++) { btMultiBodyLinkCollider* cur = body->getLink(b).m_collider; - + if (((cur) && (!(cur)->isStaticOrKinematicObject())) && ((prev) && (!(prev)->isStaticOrKinematicObject()))) { @@ -98,36 +96,31 @@ void btMultiBodyDynamicsWorld::calculateSimulationIslands() } if (cur && !cur->isStaticOrKinematicObject()) prev = cur; - } } } //merge islands linked by multibody constraints { - for (int i=0;im_multiBodyConstraints.size();i++) + for (int i = 0; i < this->m_multiBodyConstraints.size(); i++) { btMultiBodyConstraint* c = m_multiBodyConstraints[i]; int tagA = c->getIslandIdA(); int tagB = c->getIslandIdB(); - if (tagA>=0 && tagB>=0) + if (tagA >= 0 && tagB >= 0) getSimulationIslandManager()->getUnionFind().unite(tagA, tagB); } } //Store the island id in each body getSimulationIslandManager()->storeIslandActivationState(getCollisionWorld()); - } - -void btMultiBodyDynamicsWorld::updateActivationState(btScalar timeStep) +void btMultiBodyDynamicsWorld::updateActivationState(btScalar timeStep) { BT_PROFILE("btMultiBodyDynamicsWorld::updateActivationState"); - - - for ( int i=0;igetBaseCollider(); if (col && col->getActivationState() == ACTIVE_TAG) { - col->setActivationState( WANTS_DEACTIVATION); + col->setActivationState(WANTS_DEACTIVATION); col->setDeactivationTime(0.f); } - for (int b=0;bgetNumLinks();b++) + for (int b = 0; b < body->getNumLinks(); b++) { btMultiBodyLinkCollider* col = body->getLink(b).m_collider; if (col && col->getActivationState() == ACTIVE_TAG) { - col->setActivationState( WANTS_DEACTIVATION); + col->setActivationState(WANTS_DEACTIVATION); col->setDeactivationTime(0.f); } } - } else + } + else { btMultiBodyLinkCollider* col = body->getBaseCollider(); if (col && col->getActivationState() != DISABLE_DEACTIVATION) - col->setActivationState( ACTIVE_TAG ); + col->setActivationState(ACTIVE_TAG); - for (int b=0;bgetNumLinks();b++) + for (int b = 0; b < body->getNumLinks(); b++) { btMultiBodyLinkCollider* col = body->getLink(b).m_collider; if (col && col->getActivationState() != DISABLE_DEACTIVATION) - col->setActivationState( ACTIVE_TAG ); + col->setActivationState(ACTIVE_TAG); } } - } } btDiscreteDynamicsWorld::updateActivationState(timeStep); } - -SIMD_FORCE_INLINE int btGetConstraintIslandId2(const btTypedConstraint* lhs) +SIMD_FORCE_INLINE int btGetConstraintIslandId2(const btTypedConstraint* lhs) { int islandId; - + const btCollisionObject& rcolObj0 = lhs->getRigidBodyA(); const btCollisionObject& rcolObj1 = lhs->getRigidBodyB(); - islandId= rcolObj0.getIslandTag()>=0?rcolObj0.getIslandTag():rcolObj1.getIslandTag(); + islandId = rcolObj0.getIslandTag() >= 0 ? rcolObj0.getIslandTag() : rcolObj1.getIslandTag(); return islandId; - } - class btSortConstraintOnIslandPredicate2 { - public: - - bool operator() ( const btTypedConstraint* lhs, const btTypedConstraint* rhs ) const - { - int rIslandId0,lIslandId0; - rIslandId0 = btGetConstraintIslandId2(rhs); - lIslandId0 = btGetConstraintIslandId2(lhs); - return lIslandId0 < rIslandId0; - } +public: + bool operator()(const btTypedConstraint* lhs, const btTypedConstraint* rhs) const + { + int rIslandId0, lIslandId0; + rIslandId0 = btGetConstraintIslandId2(rhs); + lIslandId0 = btGetConstraintIslandId2(lhs); + return lIslandId0 < rIslandId0; + } }; - - -SIMD_FORCE_INLINE int btGetMultiBodyConstraintIslandId(const btMultiBodyConstraint* lhs) +SIMD_FORCE_INLINE int btGetMultiBodyConstraintIslandId(const btMultiBodyConstraint* lhs) { int islandId; - + int islandTagA = lhs->getIslandIdA(); int islandTagB = lhs->getIslandIdB(); - islandId= islandTagA>=0?islandTagA:islandTagB; + islandId = islandTagA >= 0 ? islandTagA : islandTagB; return islandId; - } - class btSortMultiBodyConstraintOnIslandPredicate { - public: - - bool operator() ( const btMultiBodyConstraint* lhs, const btMultiBodyConstraint* rhs ) const - { - int rIslandId0,lIslandId0; - rIslandId0 = btGetMultiBodyConstraintIslandId(rhs); - lIslandId0 = btGetMultiBodyConstraintIslandId(lhs); - return lIslandId0 < rIslandId0; - } +public: + bool operator()(const btMultiBodyConstraint* lhs, const btMultiBodyConstraint* rhs) const + { + int rIslandId0, lIslandId0; + rIslandId0 = btGetMultiBodyConstraintIslandId(rhs); + lIslandId0 = btGetMultiBodyConstraintIslandId(lhs); + return lIslandId0 < rIslandId0; + } }; struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager::IslandCallback { - btContactSolverInfo* m_solverInfo; - btMultiBodyConstraintSolver* m_solver; - btMultiBodyConstraint** m_multiBodySortedConstraints; - int m_numMultiBodyConstraints; - - btTypedConstraint** m_sortedConstraints; - int m_numConstraints; - btIDebugDraw* m_debugDrawer; - btDispatcher* m_dispatcher; - + btContactSolverInfo* m_solverInfo; + btMultiBodyConstraintSolver* m_solver; + btMultiBodyConstraint** m_multiBodySortedConstraints; + int m_numMultiBodyConstraints; + + btTypedConstraint** m_sortedConstraints; + int m_numConstraints; + btIDebugDraw* m_debugDrawer; + btDispatcher* m_dispatcher; + btAlignedObjectArray m_bodies; btAlignedObjectArray m_manifolds; btAlignedObjectArray m_constraints; btAlignedObjectArray m_multiBodyConstraints; - - MultiBodyInplaceSolverIslandCallback( btMultiBodyConstraintSolver* solver, - btDispatcher* dispatcher) - :m_solverInfo(NULL), - m_solver(solver), - m_multiBodySortedConstraints(NULL), - m_numConstraints(0), - m_debugDrawer(NULL), - m_dispatcher(dispatcher) + MultiBodyInplaceSolverIslandCallback(btMultiBodyConstraintSolver* solver, + btDispatcher* dispatcher) + : m_solverInfo(NULL), + m_solver(solver), + m_multiBodySortedConstraints(NULL), + m_numConstraints(0), + m_debugDrawer(NULL), + m_dispatcher(dispatcher) { - } MultiBodyInplaceSolverIslandCallback& operator=(MultiBodyInplaceSolverIslandCallback& other) @@ -260,7 +242,7 @@ struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager:: return *this; } - SIMD_FORCE_INLINE void setup ( btContactSolverInfo* solverInfo, btTypedConstraint** sortedConstraints, int numConstraints, btMultiBodyConstraint** sortedMultiBodyConstraints, int numMultiBodyConstraints, btIDebugDraw* debugDrawer) + SIMD_FORCE_INLINE void setup(btContactSolverInfo* solverInfo, btTypedConstraint** sortedConstraints, int numConstraints, btMultiBodyConstraint** sortedMultiBodyConstraints, int numMultiBodyConstraints, btIDebugDraw* debugDrawer) { btAssert(solverInfo); m_solverInfo = solverInfo; @@ -271,26 +253,27 @@ struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager:: m_numConstraints = numConstraints; m_debugDrawer = debugDrawer; - m_bodies.resize (0); - m_manifolds.resize (0); - m_constraints.resize (0); + m_bodies.resize(0); + m_manifolds.resize(0); + m_constraints.resize(0); m_multiBodyConstraints.resize(0); } - void setMultiBodyConstraintSolver(btMultiBodyConstraintSolver* solver) - { - m_solver = solver; - } - - virtual void processIsland(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifolds,int numManifolds, int islandId) + void setMultiBodyConstraintSolver(btMultiBodyConstraintSolver* solver) { - if (islandId<0) + m_solver = solver; + } + + virtual void processIsland(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifolds, int numManifolds, int islandId) + { + if (islandId < 0) { ///we don't split islands, so all constraints/contact manifolds/bodies are passed into the solver regardless the island id - m_solver->solveMultiBodyGroup( bodies,numBodies,manifolds, numManifolds,m_sortedConstraints, m_numConstraints, &m_multiBodySortedConstraints[0],m_numConstraints,*m_solverInfo,m_debugDrawer,m_dispatcher); - } else + m_solver->solveMultiBodyGroup(bodies, numBodies, manifolds, numManifolds, m_sortedConstraints, m_numConstraints, &m_multiBodySortedConstraints[0], m_numConstraints, *m_solverInfo, m_debugDrawer, m_dispatcher); + } + else { - //also add all non-contact constraints/joints for this island + //also add all non-contact constraints/joints for this island btTypedConstraint** startConstraint = 0; btMultiBodyConstraint** startMultiBodyConstraint = 0; @@ -298,10 +281,10 @@ struct MultiBodyInplaceSolverIslandCallback : public btSimulationIslandManager:: int numCurMultiBodyConstraints = 0; int i; - + //find the first constraint for this island - for (i=0;isolveGroup( bodies,numBodies,manifolds, numManifolds,startConstraint,numCurConstraints,*m_solverInfo,m_debugDrawer,m_dispatcher); //} else { - - for (i=0;im_solverInfo->m_minimumSolverBatchSize) + + if ((m_multiBodyConstraints.size() + m_constraints.size() + m_manifolds.size()) > m_solverInfo->m_minimumSolverBatchSize) { processConstraints(); - } else + } + else { //printf("deferred\n"); } } } } - void processConstraints() + void processConstraints() { - - btCollisionObject** bodies = m_bodies.size()? &m_bodies[0]:0; - btPersistentManifold** manifold = m_manifolds.size()?&m_manifolds[0]:0; - btTypedConstraint** constraints = m_constraints.size()?&m_constraints[0]:0; - btMultiBodyConstraint** multiBodyConstraints = m_multiBodyConstraints.size() ? &m_multiBodyConstraints[0] : 0; + btCollisionObject** bodies = m_bodies.size() ? &m_bodies[0] : 0; + btPersistentManifold** manifold = m_manifolds.size() ? &m_manifolds[0] : 0; + btTypedConstraint** constraints = m_constraints.size() ? &m_constraints[0] : 0; + btMultiBodyConstraint** multiBodyConstraints = m_multiBodyConstraints.size() ? &m_multiBodyConstraints[0] : 0; //printf("mb contacts = %d, mb constraints = %d\n", mbContacts, m_multiBodyConstraints.size()); - - m_solver->solveMultiBodyGroup( bodies,m_bodies.size(),manifold, m_manifolds.size(),constraints, m_constraints.size() ,multiBodyConstraints, m_multiBodyConstraints.size(), *m_solverInfo,m_debugDrawer,m_dispatcher); + + m_solver->solveMultiBodyGroup(bodies, m_bodies.size(), manifold, m_manifolds.size(), constraints, m_constraints.size(), multiBodyConstraints, m_multiBodyConstraints.size(), *m_solverInfo, m_debugDrawer, m_dispatcher); m_bodies.resize(0); m_manifolds.resize(0); m_constraints.resize(0); m_multiBodyConstraints.resize(0); } - }; - - -btMultiBodyDynamicsWorld::btMultiBodyDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btMultiBodyConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration) - :btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration), - m_multiBodyConstraintSolver(constraintSolver) +btMultiBodyDynamicsWorld::btMultiBodyDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btMultiBodyConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration) + : btDiscreteDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration), + m_multiBodyConstraintSolver(constraintSolver) { //split impulse is not yet supported for Featherstone hierarchies -// getSolverInfo().m_splitImpulse = false; - getSolverInfo().m_solverMode |=SOLVER_USE_2_FRICTION_DIRECTIONS; - m_solverMultiBodyIslandCallback = new MultiBodyInplaceSolverIslandCallback(constraintSolver,dispatcher); + // getSolverInfo().m_splitImpulse = false; + getSolverInfo().m_solverMode |= SOLVER_USE_2_FRICTION_DIRECTIONS; + m_solverMultiBodyIslandCallback = new MultiBodyInplaceSolverIslandCallback(constraintSolver, dispatcher); } -btMultiBodyDynamicsWorld::~btMultiBodyDynamicsWorld () +btMultiBodyDynamicsWorld::~btMultiBodyDynamicsWorld() { delete m_solverMultiBodyIslandCallback; } -void btMultiBodyDynamicsWorld::setMultiBodyConstraintSolver(btMultiBodyConstraintSolver* solver) +void btMultiBodyDynamicsWorld::setMultiBodyConstraintSolver(btMultiBodyConstraintSolver* solver) { - m_multiBodyConstraintSolver = solver; - m_solverMultiBodyIslandCallback->setMultiBodyConstraintSolver(solver); - btDiscreteDynamicsWorld::setConstraintSolver(solver); + m_multiBodyConstraintSolver = solver; + m_solverMultiBodyIslandCallback->setMultiBodyConstraintSolver(solver); + btDiscreteDynamicsWorld::setConstraintSolver(solver); } -void btMultiBodyDynamicsWorld::setConstraintSolver(btConstraintSolver* solver) +void btMultiBodyDynamicsWorld::setConstraintSolver(btConstraintSolver* solver) { - if (solver->getSolverType()==BT_MULTIBODY_SOLVER) - { - m_multiBodyConstraintSolver = (btMultiBodyConstraintSolver*)solver; - } - btDiscreteDynamicsWorld::setConstraintSolver(solver); + if (solver->getSolverType() == BT_MULTIBODY_SOLVER) + { + m_multiBodyConstraintSolver = (btMultiBodyConstraintSolver*)solver; + } + btDiscreteDynamicsWorld::setConstraintSolver(solver); } -void btMultiBodyDynamicsWorld::forwardKinematics() +void btMultiBodyDynamicsWorld::forwardKinematics() { - - for (int b=0;bforwardKinematics(m_scratch_world_to_local,m_scratch_local_origin); + bod->forwardKinematics(m_scratch_world_to_local, m_scratch_local_origin); } } -void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) +void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) { forwardKinematics(); - - BT_PROFILE("solveConstraints"); - + clearMultiBodyConstraintForces(); - m_sortedConstraints.resize( m_constraints.size()); - int i; - for (i=0;isetup(&solverInfo,constraintsPtr,m_sortedConstraints.size(),sortedMultiBodyConstraints,m_sortedMultiBodyConstraints.size(), getDebugDrawer()); + m_solverMultiBodyIslandCallback->setup(&solverInfo, constraintsPtr, m_sortedConstraints.size(), sortedMultiBodyConstraints, m_sortedMultiBodyConstraints.size(), getDebugDrawer()); m_constraintSolver->prepareSolve(getCollisionWorld()->getNumCollisionObjects(), getCollisionWorld()->getDispatcher()->getNumManifolds()); - #ifndef BT_USE_VIRTUAL_CLEARFORCES_AND_GRAVITY { BT_PROFILE("btMultiBody addForce"); - for (int i=0;im_multiBodies.size();i++) + for (int i = 0; i < this->m_multiBodies.size(); i++) { btMultiBody* bod = m_multiBodies[i]; bool isSleeping = false; - + if (bod->getBaseCollider() && bod->getBaseCollider()->getActivationState() == ISLAND_SLEEPING) { isSleeping = true; - } - for (int b=0;bgetNumLinks();b++) + } + for (int b = 0; b < bod->getNumLinks(); b++) { - if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState()==ISLAND_SLEEPING) + if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState() == ISLAND_SLEEPING) isSleeping = true; - } + } if (!isSleeping) { //useless? they get resized in stepVelocities once again (AND DIFFERENTLY) - m_scratch_r.resize(bod->getNumLinks()+1); //multidof? ("Y"s use it and it is used to store qdd) - m_scratch_v.resize(bod->getNumLinks()+1); - m_scratch_m.resize(bod->getNumLinks()+1); + m_scratch_r.resize(bod->getNumLinks() + 1); //multidof? ("Y"s use it and it is used to store qdd) + m_scratch_v.resize(bod->getNumLinks() + 1); + m_scratch_m.resize(bod->getNumLinks() + 1); bod->addBaseForce(m_gravity * bod->getBaseMass()); - for (int j = 0; j < bod->getNumLinks(); ++j) + for (int j = 0; j < bod->getNumLinks(); ++j) { bod->addLinkForce(j, m_gravity * bod->getLinkMass(j)); } - }//if (!isSleeping) + } //if (!isSleeping) } } -#endif //BT_USE_VIRTUAL_CLEARFORCES_AND_GRAVITY - +#endif //BT_USE_VIRTUAL_CLEARFORCES_AND_GRAVITY { BT_PROFILE("btMultiBody stepVelocities"); - for (int i=0;im_multiBodies.size();i++) + for (int i = 0; i < this->m_multiBodies.size(); i++) { btMultiBody* bod = m_multiBodies[i]; bool isSleeping = false; - + if (bod->getBaseCollider() && bod->getBaseCollider()->getActivationState() == ISLAND_SLEEPING) { isSleeping = true; - } - for (int b=0;bgetNumLinks();b++) + } + for (int b = 0; b < bod->getNumLinks(); b++) { - if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState()==ISLAND_SLEEPING) + if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState() == ISLAND_SLEEPING) isSleeping = true; - } + } if (!isSleeping) { //useless? they get resized in stepVelocities once again (AND DIFFERENTLY) - m_scratch_r.resize(bod->getNumLinks()+1); //multidof? ("Y"s use it and it is used to store qdd) - m_scratch_v.resize(bod->getNumLinks()+1); - m_scratch_m.resize(bod->getNumLinks()+1); + m_scratch_r.resize(bod->getNumLinks() + 1); //multidof? ("Y"s use it and it is used to store qdd) + m_scratch_v.resize(bod->getNumLinks() + 1); + m_scratch_m.resize(bod->getNumLinks() + 1); bool doNotUpdatePos = false; { - if(!bod->isUsingRK4Integration()) + if (!bod->isUsingRK4Integration()) { bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(solverInfo.m_timeStep, m_scratch_r, m_scratch_v, m_scratch_m); } else - { + { // int numDofs = bod->getNumDofs() + 6; int numPosVars = bod->getNumPosVars() + 7; - btAlignedObjectArray scratch_r2; scratch_r2.resize(2*numPosVars + 8*numDofs); + btAlignedObjectArray scratch_r2; + scratch_r2.resize(2 * numPosVars + 8 * numDofs); //convenience - btScalar *pMem = &scratch_r2[0]; - btScalar *scratch_q0 = pMem; pMem += numPosVars; - btScalar *scratch_qx = pMem; pMem += numPosVars; - btScalar *scratch_qd0 = pMem; pMem += numDofs; - btScalar *scratch_qd1 = pMem; pMem += numDofs; - btScalar *scratch_qd2 = pMem; pMem += numDofs; - btScalar *scratch_qd3 = pMem; pMem += numDofs; - btScalar *scratch_qdd0 = pMem; pMem += numDofs; - btScalar *scratch_qdd1 = pMem; pMem += numDofs; - btScalar *scratch_qdd2 = pMem; pMem += numDofs; - btScalar *scratch_qdd3 = pMem; pMem += numDofs; - btAssert((pMem - (2*numPosVars + 8*numDofs)) == &scratch_r2[0]); + btScalar* pMem = &scratch_r2[0]; + btScalar* scratch_q0 = pMem; + pMem += numPosVars; + btScalar* scratch_qx = pMem; + pMem += numPosVars; + btScalar* scratch_qd0 = pMem; + pMem += numDofs; + btScalar* scratch_qd1 = pMem; + pMem += numDofs; + btScalar* scratch_qd2 = pMem; + pMem += numDofs; + btScalar* scratch_qd3 = pMem; + pMem += numDofs; + btScalar* scratch_qdd0 = pMem; + pMem += numDofs; + btScalar* scratch_qdd1 = pMem; + pMem += numDofs; + btScalar* scratch_qdd2 = pMem; + pMem += numDofs; + btScalar* scratch_qdd3 = pMem; + pMem += numDofs; + btAssert((pMem - (2 * numPosVars + 8 * numDofs)) == &scratch_r2[0]); - ///// + ///// //copy q0 to scratch_q0 and qd0 to scratch_qd0 scratch_q0[0] = bod->getWorldToBaseRot().x(); scratch_q0[1] = bod->getWorldToBaseRot().y(); @@ -555,69 +538,68 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) scratch_q0[5] = bod->getBasePos().y(); scratch_q0[6] = bod->getBasePos().z(); // - for(int link = 0; link < bod->getNumLinks(); ++link) + for (int link = 0; link < bod->getNumLinks(); ++link) { - for(int dof = 0; dof < bod->getLink(link).m_posVarCount; ++dof) - scratch_q0[7 + bod->getLink(link).m_cfgOffset + dof] = bod->getLink(link).m_jointPos[dof]; + for (int dof = 0; dof < bod->getLink(link).m_posVarCount; ++dof) + scratch_q0[7 + bod->getLink(link).m_cfgOffset + dof] = bod->getLink(link).m_jointPos[dof]; } // - for(int dof = 0; dof < numDofs; ++dof) + for (int dof = 0; dof < numDofs; ++dof) scratch_qd0[dof] = bod->getVelocityVector()[dof]; //// struct { - btMultiBody *bod; - btScalar *scratch_qx, *scratch_q0; + btMultiBody* bod; + btScalar *scratch_qx, *scratch_q0; - void operator()() - { - for(int dof = 0; dof < bod->getNumPosVars() + 7; ++dof) - scratch_qx[dof] = scratch_q0[dof]; - } + void operator()() + { + for (int dof = 0; dof < bod->getNumPosVars() + 7; ++dof) + scratch_qx[dof] = scratch_q0[dof]; + } } pResetQx = {bod, scratch_qx, scratch_q0}; // struct { - void operator()(btScalar dt, const btScalar *pDer, const btScalar *pCurVal, btScalar *pVal, int size) - { - for(int i = 0; i < size; ++i) - pVal[i] = pCurVal[i] + dt * pDer[i]; - } + void operator()(btScalar dt, const btScalar* pDer, const btScalar* pCurVal, btScalar* pVal, int size) + { + for (int i = 0; i < size; ++i) + pVal[i] = pCurVal[i] + dt * pDer[i]; + } } pEulerIntegrate; // struct - { - void operator()(btMultiBody *pBody, const btScalar *pData) - { - btScalar *pVel = const_cast(pBody->getVelocityVector()); - - for(int i = 0; i < pBody->getNumDofs() + 6; ++i) - pVel[i] = pData[i]; - - } - } pCopyToVelocityVector; - // - struct { - void operator()(const btScalar *pSrc, btScalar *pDst, int start, int size) - { - for(int i = 0; i < size; ++i) - pDst[i] = pSrc[start + i]; - } + void operator()(btMultiBody* pBody, const btScalar* pData) + { + btScalar* pVel = const_cast(pBody->getVelocityVector()); + + for (int i = 0; i < pBody->getNumDofs() + 6; ++i) + pVel[i] = pData[i]; + } + } pCopyToVelocityVector; + // + struct + { + void operator()(const btScalar* pSrc, btScalar* pDst, int start, int size) + { + for (int i = 0; i < size; ++i) + pDst[i] = pSrc[start + i]; + } } pCopy; // btScalar h = solverInfo.m_timeStep; - #define output &m_scratch_r[bod->getNumDofs()] - //calc qdd0 from: q0 & qd0 +#define output &m_scratch_r[bod->getNumDofs()] + //calc qdd0 from: q0 & qd0 bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0., m_scratch_r, m_scratch_v, m_scratch_m); pCopy(output, scratch_qdd0, 0, numDofs); //calc q1 = q0 + h/2 * qd0 pResetQx(); - bod->stepPositionsMultiDof(btScalar(.5)*h, scratch_qx, scratch_qd0); + bod->stepPositionsMultiDof(btScalar(.5) * h, scratch_qx, scratch_qd0); //calc qd1 = qd0 + h/2 * qdd0 - pEulerIntegrate(btScalar(.5)*h, scratch_qdd0, scratch_qd0, scratch_qd1, numDofs); + pEulerIntegrate(btScalar(.5) * h, scratch_qdd0, scratch_qd0, scratch_qd1, numDofs); // //calc qdd1 from: q1 & qd1 pCopyToVelocityVector(bod, scratch_qd1); @@ -625,9 +607,9 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) pCopy(output, scratch_qdd1, 0, numDofs); //calc q2 = q0 + h/2 * qd1 pResetQx(); - bod->stepPositionsMultiDof(btScalar(.5)*h, scratch_qx, scratch_qd1); + bod->stepPositionsMultiDof(btScalar(.5) * h, scratch_qx, scratch_qd1); //calc qd2 = qd0 + h/2 * qdd1 - pEulerIntegrate(btScalar(.5)*h, scratch_qdd1, scratch_qd0, scratch_qd2, numDofs); + pEulerIntegrate(btScalar(.5) * h, scratch_qdd1, scratch_qd0, scratch_qd2, numDofs); // //calc qdd2 from: q2 & qd2 pCopyToVelocityVector(bod, scratch_qd2); @@ -646,151 +628,147 @@ void btMultiBodyDynamicsWorld::solveConstraints(btContactSolverInfo& solverInfo) // //calc q = q0 + h/6(qd0 + 2*(qd1 + qd2) + qd3) - //calc qd = qd0 + h/6(qdd0 + 2*(qdd1 + qdd2) + qdd3) - btAlignedObjectArray delta_q; delta_q.resize(numDofs); - btAlignedObjectArray delta_qd; delta_qd.resize(numDofs); - for(int i = 0; i < numDofs; ++i) + //calc qd = qd0 + h/6(qdd0 + 2*(qdd1 + qdd2) + qdd3) + btAlignedObjectArray delta_q; + delta_q.resize(numDofs); + btAlignedObjectArray delta_qd; + delta_qd.resize(numDofs); + for (int i = 0; i < numDofs; ++i) { - delta_q[i] = h/btScalar(6.)*(scratch_qd0[i] + 2*scratch_qd1[i] + 2*scratch_qd2[i] + scratch_qd3[i]); - delta_qd[i] = h/btScalar(6.)*(scratch_qdd0[i] + 2*scratch_qdd1[i] + 2*scratch_qdd2[i] + scratch_qdd3[i]); + delta_q[i] = h / btScalar(6.) * (scratch_qd0[i] + 2 * scratch_qd1[i] + 2 * scratch_qd2[i] + scratch_qd3[i]); + delta_qd[i] = h / btScalar(6.) * (scratch_qdd0[i] + 2 * scratch_qdd1[i] + 2 * scratch_qdd2[i] + scratch_qdd3[i]); //delta_q[i] = h*scratch_qd0[i]; //delta_qd[i] = h*scratch_qdd0[i]; } // pCopyToVelocityVector(bod, scratch_qd0); - bod->applyDeltaVeeMultiDof(&delta_qd[0], 1); + bod->applyDeltaVeeMultiDof(&delta_qd[0], 1); // - if(!doNotUpdatePos) + if (!doNotUpdatePos) { - btScalar *pRealBuf = const_cast(bod->getVelocityVector()); - pRealBuf += 6 + bod->getNumDofs() + bod->getNumDofs()*bod->getNumDofs(); + btScalar* pRealBuf = const_cast(bod->getVelocityVector()); + pRealBuf += 6 + bod->getNumDofs() + bod->getNumDofs() * bod->getNumDofs(); - for(int i = 0; i < numDofs; ++i) + for (int i = 0; i < numDofs; ++i) pRealBuf[i] = delta_q[i]; //bod->stepPositionsMultiDof(1, 0, &delta_q[0]); - bod->setPosUpdated(true); + bod->setPosUpdated(true); } //ugly hack which resets the cached data to t0 (needed for constraint solver) { - for(int link = 0; link < bod->getNumLinks(); ++link) + for (int link = 0; link < bod->getNumLinks(); ++link) bod->getLink(link).updateCacheMultiDof(); bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(0, m_scratch_r, m_scratch_v, m_scratch_m); } - } } - + #ifndef BT_USE_VIRTUAL_CLEARFORCES_AND_GRAVITY bod->clearForcesAndTorques(); -#endif //BT_USE_VIRTUAL_CLEARFORCES_AND_GRAVITY - }//if (!isSleeping) +#endif //BT_USE_VIRTUAL_CLEARFORCES_AND_GRAVITY + } //if (!isSleeping) } } /// solve all the constraints for this island m_islandManager->buildAndProcessIslands(getCollisionWorld()->getDispatcher(), getCollisionWorld(), m_solverMultiBodyIslandCallback); - m_solverMultiBodyIslandCallback->processConstraints(); - + m_constraintSolver->allSolved(solverInfo, m_debugDrawer); { - BT_PROFILE("btMultiBody stepVelocities"); - for (int i=0;im_multiBodies.size();i++) - { - btMultiBody* bod = m_multiBodies[i]; + BT_PROFILE("btMultiBody stepVelocities"); + for (int i = 0; i < this->m_multiBodies.size(); i++) + { + btMultiBody* bod = m_multiBodies[i]; - bool isSleeping = false; + bool isSleeping = false; - if (bod->getBaseCollider() && bod->getBaseCollider()->getActivationState() == ISLAND_SLEEPING) - { - isSleeping = true; - } - for (int b=0;bgetNumLinks();b++) - { - if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState()==ISLAND_SLEEPING) - isSleeping = true; - } + if (bod->getBaseCollider() && bod->getBaseCollider()->getActivationState() == ISLAND_SLEEPING) + { + isSleeping = true; + } + for (int b = 0; b < bod->getNumLinks(); b++) + { + if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState() == ISLAND_SLEEPING) + isSleeping = true; + } - if (!isSleeping) - { - //useless? they get resized in stepVelocities once again (AND DIFFERENTLY) - m_scratch_r.resize(bod->getNumLinks()+1); //multidof? ("Y"s use it and it is used to store qdd) - m_scratch_v.resize(bod->getNumLinks()+1); - m_scratch_m.resize(bod->getNumLinks()+1); + if (!isSleeping) + { + //useless? they get resized in stepVelocities once again (AND DIFFERENTLY) + m_scratch_r.resize(bod->getNumLinks() + 1); //multidof? ("Y"s use it and it is used to store qdd) + m_scratch_v.resize(bod->getNumLinks() + 1); + m_scratch_m.resize(bod->getNumLinks() + 1); - - { - if(!bod->isUsingRK4Integration()) - { - bool isConstraintPass = true; - bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(solverInfo.m_timeStep, m_scratch_r, m_scratch_v, m_scratch_m, isConstraintPass); - } + { + if (!bod->isUsingRK4Integration()) + { + bool isConstraintPass = true; + bod->computeAccelerationsArticulatedBodyAlgorithmMultiDof(solverInfo.m_timeStep, m_scratch_r, m_scratch_v, m_scratch_m, isConstraintPass); + } } } } } - for (int i=0;im_multiBodies.size();i++) + for (int i = 0; i < this->m_multiBodies.size(); i++) { btMultiBody* bod = m_multiBodies[i]; bod->processDeltaVeeMultiDof2(); } - } -void btMultiBodyDynamicsWorld::integrateTransforms(btScalar timeStep) +void btMultiBodyDynamicsWorld::integrateTransforms(btScalar timeStep) { btDiscreteDynamicsWorld::integrateTransforms(timeStep); { BT_PROFILE("btMultiBody stepPositions"); //integrate and update the Featherstone hierarchies - - for (int b=0;bgetBaseCollider() && bod->getBaseCollider()->getActivationState() == ISLAND_SLEEPING) { isSleeping = true; - } - for (int b=0;bgetNumLinks();b++) + } + for (int b = 0; b < bod->getNumLinks(); b++) { - if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState()==ISLAND_SLEEPING) + if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState() == ISLAND_SLEEPING) isSleeping = true; } - if (!isSleeping) { int nLinks = bod->getNumLinks(); ///base + num m_links - - + { - if(!bod->isPosUpdated()) + if (!bod->isPosUpdated()) bod->stepPositionsMultiDof(timeStep); else { - btScalar *pRealBuf = const_cast(bod->getVelocityVector()); - pRealBuf += 6 + bod->getNumDofs() + bod->getNumDofs()*bod->getNumDofs(); + btScalar* pRealBuf = const_cast(bod->getVelocityVector()); + pRealBuf += 6 + bod->getNumDofs() + bod->getNumDofs() * bod->getNumDofs(); bod->stepPositionsMultiDof(1, 0, pRealBuf); bod->setPosUpdated(false); } } - - m_scratch_world_to_local.resize(nLinks+1); - m_scratch_local_origin.resize(nLinks+1); - bod->updateCollisionObjectWorldTransforms(m_scratch_world_to_local,m_scratch_local_origin); - - } else + m_scratch_world_to_local.resize(nLinks + 1); + m_scratch_local_origin.resize(nLinks + 1); + + bod->updateCollisionObjectWorldTransforms(m_scratch_world_to_local, m_scratch_local_origin); + } + else { bod->clearVelocities(); } @@ -798,14 +776,12 @@ void btMultiBodyDynamicsWorld::integrateTransforms(btScalar timeStep) } } - - -void btMultiBodyDynamicsWorld::addMultiBodyConstraint( btMultiBodyConstraint* constraint) +void btMultiBodyDynamicsWorld::addMultiBodyConstraint(btMultiBodyConstraint* constraint) { m_multiBodyConstraints.push_back(constraint); } -void btMultiBodyDynamicsWorld::removeMultiBodyConstraint( btMultiBodyConstraint* constraint) +void btMultiBodyDynamicsWorld::removeMultiBodyConstraint(btMultiBodyConstraint* constraint) { m_multiBodyConstraints.remove(constraint); } @@ -815,8 +791,7 @@ void btMultiBodyDynamicsWorld::debugDrawMultiBodyConstraint(btMultiBodyConstrain constraint->debugDraw(getDebugDrawer()); } - -void btMultiBodyDynamicsWorld::debugDrawWorld() +void btMultiBodyDynamicsWorld::debugDrawWorld() { BT_PROFILE("btMultiBodyDynamicsWorld debugDrawWorld"); @@ -826,7 +801,7 @@ void btMultiBodyDynamicsWorld::debugDrawWorld() if (getDebugDrawer()) { int mode = getDebugDrawer()->getDebugMode(); - if (mode & (btIDebugDraw::DBG_DrawConstraints | btIDebugDraw::DBG_DrawConstraintLimits)) + if (mode & (btIDebugDraw::DBG_DrawConstraints | btIDebugDraw::DBG_DrawConstraintLimits)) { drawConstraints = true; } @@ -834,160 +809,148 @@ void btMultiBodyDynamicsWorld::debugDrawWorld() if (drawConstraints) { BT_PROFILE("btMultiBody debugDrawWorld"); - - for (int c=0;cforwardKinematics(m_scratch_world_to_local1,m_scratch_local_origin1); - - if (mode & btIDebugDraw::DBG_DrawFrames) + bod->forwardKinematics(m_scratch_world_to_local1, m_scratch_local_origin1); + + if (mode & btIDebugDraw::DBG_DrawFrames) { getDebugDrawer()->drawTransform(bod->getBaseWorldTransform(), 0.1); } - for (int m = 0; mgetNumLinks(); m++) + for (int m = 0; m < bod->getNumLinks(); m++) { - const btTransform& tr = bod->getLink(m).m_cachedWorldTransform; - if (mode & btIDebugDraw::DBG_DrawFrames) + if (mode & btIDebugDraw::DBG_DrawFrames) { getDebugDrawer()->drawTransform(tr, 0.1); } - //draw the joint axis - if (bod->getLink(m).m_jointType==btMultibodyLink::eRevolute) + //draw the joint axis + if (bod->getLink(m).m_jointType == btMultibodyLink::eRevolute) { - btVector3 vec = quatRotate(tr.getRotation(),bod->getLink(m).m_axes[0].m_topVec)*0.1; - - btVector4 color(0,0,0,1);//1,1,1); - btVector3 from = vec+tr.getOrigin()-quatRotate(tr.getRotation(),bod->getLink(m).m_dVector); - btVector3 to = tr.getOrigin()-quatRotate(tr.getRotation(),bod->getLink(m).m_dVector); - getDebugDrawer()->drawLine(from,to,color); + btVector3 vec = quatRotate(tr.getRotation(), bod->getLink(m).m_axes[0].m_topVec) * 0.1; + + btVector4 color(0, 0, 0, 1); //1,1,1); + btVector3 from = vec + tr.getOrigin() - quatRotate(tr.getRotation(), bod->getLink(m).m_dVector); + btVector3 to = tr.getOrigin() - quatRotate(tr.getRotation(), bod->getLink(m).m_dVector); + getDebugDrawer()->drawLine(from, to, color); } - if (bod->getLink(m).m_jointType==btMultibodyLink::eFixed) + if (bod->getLink(m).m_jointType == btMultibodyLink::eFixed) { - btVector3 vec = quatRotate(tr.getRotation(),bod->getLink(m).m_axes[0].m_bottomVec)*0.1; - - btVector4 color(0,0,0,1);//1,1,1); - btVector3 from = vec+tr.getOrigin()-quatRotate(tr.getRotation(),bod->getLink(m).m_dVector); - btVector3 to = tr.getOrigin()-quatRotate(tr.getRotation(),bod->getLink(m).m_dVector); - getDebugDrawer()->drawLine(from,to,color); + btVector3 vec = quatRotate(tr.getRotation(), bod->getLink(m).m_axes[0].m_bottomVec) * 0.1; + + btVector4 color(0, 0, 0, 1); //1,1,1); + btVector3 from = vec + tr.getOrigin() - quatRotate(tr.getRotation(), bod->getLink(m).m_dVector); + btVector3 to = tr.getOrigin() - quatRotate(tr.getRotation(), bod->getLink(m).m_dVector); + getDebugDrawer()->drawLine(from, to, color); } - if (bod->getLink(m).m_jointType==btMultibodyLink::ePrismatic) + if (bod->getLink(m).m_jointType == btMultibodyLink::ePrismatic) { - btVector3 vec = quatRotate(tr.getRotation(),bod->getLink(m).m_axes[0].m_bottomVec)*0.1; - - btVector4 color(0,0,0,1);//1,1,1); - btVector3 from = vec+tr.getOrigin()-quatRotate(tr.getRotation(),bod->getLink(m).m_dVector); - btVector3 to = tr.getOrigin()-quatRotate(tr.getRotation(),bod->getLink(m).m_dVector); - getDebugDrawer()->drawLine(from,to,color); + btVector3 vec = quatRotate(tr.getRotation(), bod->getLink(m).m_axes[0].m_bottomVec) * 0.1; + + btVector4 color(0, 0, 0, 1); //1,1,1); + btVector3 from = vec + tr.getOrigin() - quatRotate(tr.getRotation(), bod->getLink(m).m_dVector); + btVector3 to = tr.getOrigin() - quatRotate(tr.getRotation(), bod->getLink(m).m_dVector); + getDebugDrawer()->drawLine(from, to, color); } - } } } } - - } - - void btMultiBodyDynamicsWorld::applyGravity() { - btDiscreteDynamicsWorld::applyGravity(); + btDiscreteDynamicsWorld::applyGravity(); #ifdef BT_USE_VIRTUAL_CLEARFORCES_AND_GRAVITY - BT_PROFILE("btMultiBody addGravity"); - for (int i=0;im_multiBodies.size();i++) - { - btMultiBody* bod = m_multiBodies[i]; + BT_PROFILE("btMultiBody addGravity"); + for (int i = 0; i < this->m_multiBodies.size(); i++) + { + btMultiBody* bod = m_multiBodies[i]; - bool isSleeping = false; + bool isSleeping = false; - if (bod->getBaseCollider() && bod->getBaseCollider()->getActivationState() == ISLAND_SLEEPING) - { - isSleeping = true; - } - for (int b=0;bgetNumLinks();b++) - { - if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState()==ISLAND_SLEEPING) - isSleeping = true; - } + if (bod->getBaseCollider() && bod->getBaseCollider()->getActivationState() == ISLAND_SLEEPING) + { + isSleeping = true; + } + for (int b = 0; b < bod->getNumLinks(); b++) + { + if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState() == ISLAND_SLEEPING) + isSleeping = true; + } - if (!isSleeping) - { - bod->addBaseForce(m_gravity * bod->getBaseMass()); + if (!isSleeping) + { + bod->addBaseForce(m_gravity * bod->getBaseMass()); - for (int j = 0; j < bod->getNumLinks(); ++j) - { - bod->addLinkForce(j, m_gravity * bod->getLinkMass(j)); - } - }//if (!isSleeping) - } -#endif //BT_USE_VIRTUAL_CLEARFORCES_AND_GRAVITY + for (int j = 0; j < bod->getNumLinks(); ++j) + { + bod->addLinkForce(j, m_gravity * bod->getLinkMass(j)); + } + } //if (!isSleeping) + } +#endif //BT_USE_VIRTUAL_CLEARFORCES_AND_GRAVITY } void btMultiBodyDynamicsWorld::clearMultiBodyConstraintForces() -{ - for (int i=0;im_multiBodies.size();i++) - { - btMultiBody* bod = m_multiBodies[i]; - bod->clearConstraintForces(); - } +{ + for (int i = 0; i < this->m_multiBodies.size(); i++) + { + btMultiBody* bod = m_multiBodies[i]; + bod->clearConstraintForces(); + } } void btMultiBodyDynamicsWorld::clearMultiBodyForces() { - { - // BT_PROFILE("clearMultiBodyForces"); - for (int i=0;im_multiBodies.size();i++) - { - btMultiBody* bod = m_multiBodies[i]; + { + // BT_PROFILE("clearMultiBodyForces"); + for (int i = 0; i < this->m_multiBodies.size(); i++) + { + btMultiBody* bod = m_multiBodies[i]; - bool isSleeping = false; + bool isSleeping = false; - if (bod->getBaseCollider() && bod->getBaseCollider()->getActivationState() == ISLAND_SLEEPING) - { - isSleeping = true; - } - for (int b=0;bgetNumLinks();b++) - { - if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState()==ISLAND_SLEEPING) - isSleeping = true; - } + if (bod->getBaseCollider() && bod->getBaseCollider()->getActivationState() == ISLAND_SLEEPING) + { + isSleeping = true; + } + for (int b = 0; b < bod->getNumLinks(); b++) + { + if (bod->getLink(b).m_collider && bod->getLink(b).m_collider->getActivationState() == ISLAND_SLEEPING) + isSleeping = true; + } - if (!isSleeping) - { - btMultiBody* bod = m_multiBodies[i]; - bod->clearForcesAndTorques(); - } + if (!isSleeping) + { + btMultiBody* bod = m_multiBodies[i]; + bod->clearForcesAndTorques(); + } } } - } void btMultiBodyDynamicsWorld::clearForces() { - btDiscreteDynamicsWorld::clearForces(); + btDiscreteDynamicsWorld::clearForces(); #ifdef BT_USE_VIRTUAL_CLEARFORCES_AND_GRAVITY clearMultiBodyForces(); #endif } - - - -void btMultiBodyDynamicsWorld::serialize(btSerializer* serializer) +void btMultiBodyDynamicsWorld::serialize(btSerializer* serializer) { - serializer->startSerialization(); - serializeDynamicsWorldInfo( serializer); + serializeDynamicsWorldInfo(serializer); serializeMultiBodies(serializer); @@ -1000,32 +963,31 @@ void btMultiBodyDynamicsWorld::serialize(btSerializer* serializer) serializer->finishSerialization(); } -void btMultiBodyDynamicsWorld::serializeMultiBodies(btSerializer* serializer) +void btMultiBodyDynamicsWorld::serializeMultiBodies(btSerializer* serializer) { int i; //serialize all collision objects - for (i=0;icalculateSerializeBufferSize(); - btChunk* chunk = serializer->allocate(len,1); + btChunk* chunk = serializer->allocate(len, 1); const char* structType = mb->serialize(chunk->m_oldPtr, serializer); - serializer->finalizeChunk(chunk,structType,BT_MULTIBODY_CODE,mb); + serializer->finalizeChunk(chunk, structType, BT_MULTIBODY_CODE, mb); } } //serialize all multibody links (collision objects) - for (i=0;igetInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) { int len = colObj->calculateSerializeBufferSize(); - btChunk* chunk = serializer->allocate(len,1); + btChunk* chunk = serializer->allocate(len, 1); const char* structType = colObj->serialize(chunk->m_oldPtr, serializer); - serializer->finalizeChunk(chunk,structType,BT_MB_LINKCOLLIDER_CODE,colObj); + serializer->finalizeChunk(chunk, structType, BT_MB_LINKCOLLIDER_CODE, colObj); } } - } diff --git a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h index 2fbf089d8..641238f3b 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h +++ b/src/BulletDynamics/Featherstone/btMultiBodyDynamicsWorld.h @@ -33,8 +33,8 @@ protected: btAlignedObjectArray m_multiBodies; btAlignedObjectArray m_multiBodyConstraints; btAlignedObjectArray m_sortedMultiBodyConstraints; - btMultiBodyConstraintSolver* m_multiBodyConstraintSolver; - MultiBodyInplaceSolverIslandCallback* m_solverMultiBodyIslandCallback; + btMultiBodyConstraintSolver* m_multiBodyConstraintSolver; + MultiBodyInplaceSolverIslandCallback* m_solverMultiBodyIslandCallback; //cached data to avoid memory allocations btAlignedObjectArray m_scratch_world_to_local; @@ -45,72 +45,69 @@ protected: btAlignedObjectArray m_scratch_v; btAlignedObjectArray m_scratch_m; - - virtual void calculateSimulationIslands(); - virtual void updateActivationState(btScalar timeStep); - virtual void solveConstraints(btContactSolverInfo& solverInfo); - - virtual void serializeMultiBodies(btSerializer* serializer); + virtual void calculateSimulationIslands(); + virtual void updateActivationState(btScalar timeStep); + virtual void solveConstraints(btContactSolverInfo& solverInfo); + + virtual void serializeMultiBodies(btSerializer* serializer); public: + btMultiBodyDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btMultiBodyConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration); - btMultiBodyDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btMultiBodyConstraintSolver* constraintSolver,btCollisionConfiguration* collisionConfiguration); + virtual ~btMultiBodyDynamicsWorld(); - virtual ~btMultiBodyDynamicsWorld (); + virtual void addMultiBody(btMultiBody* body, int group = btBroadphaseProxy::DefaultFilter, int mask = btBroadphaseProxy::AllFilter); - virtual void addMultiBody(btMultiBody* body, int group= btBroadphaseProxy::DefaultFilter, int mask=btBroadphaseProxy::AllFilter); + virtual void removeMultiBody(btMultiBody* body); - virtual void removeMultiBody(btMultiBody* body); - - virtual int getNumMultibodies() const + virtual int getNumMultibodies() const { return m_multiBodies.size(); } - btMultiBody* getMultiBody(int mbIndex) + btMultiBody* getMultiBody(int mbIndex) { return m_multiBodies[mbIndex]; } - const btMultiBody* getMultiBody(int mbIndex) const + const btMultiBody* getMultiBody(int mbIndex) const { return m_multiBodies[mbIndex]; } - virtual void addMultiBodyConstraint( btMultiBodyConstraint* constraint); + virtual void addMultiBodyConstraint(btMultiBodyConstraint* constraint); - virtual int getNumMultiBodyConstraints() const + virtual int getNumMultiBodyConstraints() const { - return m_multiBodyConstraints.size(); + return m_multiBodyConstraints.size(); } - virtual btMultiBodyConstraint* getMultiBodyConstraint( int constraintIndex) + virtual btMultiBodyConstraint* getMultiBodyConstraint(int constraintIndex) { - return m_multiBodyConstraints[constraintIndex]; + return m_multiBodyConstraints[constraintIndex]; } - virtual const btMultiBodyConstraint* getMultiBodyConstraint( int constraintIndex) const + virtual const btMultiBodyConstraint* getMultiBodyConstraint(int constraintIndex) const { - return m_multiBodyConstraints[constraintIndex]; + return m_multiBodyConstraints[constraintIndex]; } - virtual void removeMultiBodyConstraint( btMultiBodyConstraint* constraint); + virtual void removeMultiBodyConstraint(btMultiBodyConstraint* constraint); - virtual void integrateTransforms(btScalar timeStep); + virtual void integrateTransforms(btScalar timeStep); - virtual void debugDrawWorld(); + virtual void debugDrawWorld(); - virtual void debugDrawMultiBodyConstraint(btMultiBodyConstraint* constraint); - - void forwardKinematics(); + virtual void debugDrawMultiBodyConstraint(btMultiBodyConstraint* constraint); + + void forwardKinematics(); virtual void clearForces(); virtual void clearMultiBodyConstraintForces(); virtual void clearMultiBodyForces(); virtual void applyGravity(); - - virtual void serialize(btSerializer* serializer); - virtual void setMultiBodyConstraintSolver(btMultiBodyConstraintSolver* solver); - virtual void setConstraintSolver(btConstraintSolver* solver); + virtual void serialize(btSerializer* serializer); + virtual void setMultiBodyConstraintSolver(btMultiBodyConstraintSolver* solver); + virtual void setConstraintSolver(btConstraintSolver* solver); }; -#endif //BT_MULTIBODY_DYNAMICS_WORLD_H +#endif //BT_MULTIBODY_DYNAMICS_WORLD_H diff --git a/src/BulletDynamics/Featherstone/btMultiBodyFixedConstraint.cpp b/src/BulletDynamics/Featherstone/btMultiBodyFixedConstraint.cpp index cc41ab39e..fc0b86958 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyFixedConstraint.cpp +++ b/src/BulletDynamics/Featherstone/btMultiBodyFixedConstraint.cpp @@ -24,27 +24,27 @@ subject to the following restrictions: #define BTMBFIXEDCONSTRAINT_DIM 6 btMultiBodyFixedConstraint::btMultiBodyFixedConstraint(btMultiBody* body, int link, btRigidBody* bodyB, const btVector3& pivotInA, const btVector3& pivotInB, const btMatrix3x3& frameInA, const btMatrix3x3& frameInB) - :btMultiBodyConstraint(body,0,link,-1,BTMBFIXEDCONSTRAINT_DIM,false), - m_rigidBodyA(0), - m_rigidBodyB(bodyB), - m_pivotInA(pivotInA), - m_pivotInB(pivotInB), - m_frameInA(frameInA), - m_frameInB(frameInB) + : btMultiBodyConstraint(body, 0, link, -1, BTMBFIXEDCONSTRAINT_DIM, false), + m_rigidBodyA(0), + m_rigidBodyB(bodyB), + m_pivotInA(pivotInA), + m_pivotInB(pivotInB), + m_frameInA(frameInA), + m_frameInB(frameInB) { - m_data.resize(BTMBFIXEDCONSTRAINT_DIM);//at least store the applied impulses + m_data.resize(BTMBFIXEDCONSTRAINT_DIM); //at least store the applied impulses } btMultiBodyFixedConstraint::btMultiBodyFixedConstraint(btMultiBody* bodyA, int linkA, btMultiBody* bodyB, int linkB, const btVector3& pivotInA, const btVector3& pivotInB, const btMatrix3x3& frameInA, const btMatrix3x3& frameInB) - :btMultiBodyConstraint(bodyA,bodyB,linkA,linkB,BTMBFIXEDCONSTRAINT_DIM,false), - m_rigidBodyA(0), - m_rigidBodyB(0), - m_pivotInA(pivotInA), - m_pivotInB(pivotInB), - m_frameInA(frameInA), - m_frameInB(frameInB) + : btMultiBodyConstraint(bodyA, bodyB, linkA, linkB, BTMBFIXEDCONSTRAINT_DIM, false), + m_rigidBodyA(0), + m_rigidBodyB(0), + m_pivotInA(pivotInA), + m_pivotInB(pivotInB), + m_frameInA(frameInA), + m_frameInB(frameInB) { - m_data.resize(BTMBFIXEDCONSTRAINT_DIM);//at least store the applied impulses + m_data.resize(BTMBFIXEDCONSTRAINT_DIM); //at least store the applied impulses } void btMultiBodyFixedConstraint::finalizeMultiDof() @@ -57,7 +57,6 @@ btMultiBodyFixedConstraint::~btMultiBodyFixedConstraint() { } - int btMultiBodyFixedConstraint::getIslandIdA() const { if (m_rigidBodyA) @@ -103,82 +102,83 @@ int btMultiBodyFixedConstraint::getIslandIdB() const void btMultiBodyFixedConstraint::createConstraintRows(btMultiBodyConstraintArray& constraintRows, btMultiBodyJacobianData& data, const btContactSolverInfo& infoGlobal) { - int numDim = BTMBFIXEDCONSTRAINT_DIM; - for (int i=0;igetCompanionId(); - pivotAworld = m_rigidBodyA->getCenterOfMassTransform()*m_pivotInA; - frameAworld = frameAworld.transpose()*btMatrix3x3(m_rigidBodyA->getOrientation()); - - } else - { - if (m_bodyA) { - pivotAworld = m_bodyA->localPosToWorld(m_linkA, m_pivotInA); - frameAworld = m_bodyA->localFrameToWorld(m_linkA, frameAworld); - } - } - btVector3 pivotBworld = m_pivotInB; - btMatrix3x3 frameBworld = m_frameInB; - if (m_rigidBodyB) - { - constraintRow.m_solverBodyIdB = m_rigidBodyB->getCompanionId(); - pivotBworld = m_rigidBodyB->getCenterOfMassTransform()*m_pivotInB; - frameBworld = frameBworld.transpose()*btMatrix3x3(m_rigidBodyB->getOrientation()); - - } else - { - if (m_bodyB) { - pivotBworld = m_bodyB->localPosToWorld(m_linkB, m_pivotInB); - frameBworld = m_bodyB->localFrameToWorld(m_linkB, frameBworld); - } - } - - btMatrix3x3 relRot = frameAworld.inverse()*frameBworld; - btVector3 angleDiff; - btGeneric6DofSpring2Constraint::matrixToEulerXYZ(relRot,angleDiff); - - btVector3 constraintNormalLin(0,0,0); - btVector3 constraintNormalAng(0,0,0); - btScalar posError = 0.0; - if (i < 3) { - constraintNormalLin[i] = 1; - posError = (pivotAworld-pivotBworld).dot(constraintNormalLin); - fillMultiBodyConstraint(constraintRow, data, 0, 0, constraintNormalAng, - constraintNormalLin, pivotAworld, pivotBworld, - posError, - infoGlobal, - -m_maxAppliedImpulse, m_maxAppliedImpulse - ); - } - else { //i>=3 - constraintNormalAng = frameAworld.getColumn(i%3); - posError = angleDiff[i%3]; - fillMultiBodyConstraint(constraintRow, data, 0, 0, constraintNormalAng, - constraintNormalLin, pivotAworld, pivotBworld, - posError, - infoGlobal, - -m_maxAppliedImpulse, m_maxAppliedImpulse, true - ); - } + btMultiBodySolverConstraint& constraintRow = constraintRows.expandNonInitializing(); + constraintRow.m_orgConstraint = this; + constraintRow.m_orgDofIndex = i; + constraintRow.m_relpos1CrossNormal.setValue(0, 0, 0); + constraintRow.m_contactNormal1.setValue(0, 0, 0); + constraintRow.m_relpos2CrossNormal.setValue(0, 0, 0); + constraintRow.m_contactNormal2.setValue(0, 0, 0); + constraintRow.m_angularComponentA.setValue(0, 0, 0); + constraintRow.m_angularComponentB.setValue(0, 0, 0); + + constraintRow.m_solverBodyIdA = data.m_fixedBodyId; + constraintRow.m_solverBodyIdB = data.m_fixedBodyId; + + // Convert local points back to world + btVector3 pivotAworld = m_pivotInA; + btMatrix3x3 frameAworld = m_frameInA; + if (m_rigidBodyA) + { + constraintRow.m_solverBodyIdA = m_rigidBodyA->getCompanionId(); + pivotAworld = m_rigidBodyA->getCenterOfMassTransform() * m_pivotInA; + frameAworld = frameAworld.transpose() * btMatrix3x3(m_rigidBodyA->getOrientation()); + } + else + { + if (m_bodyA) + { + pivotAworld = m_bodyA->localPosToWorld(m_linkA, m_pivotInA); + frameAworld = m_bodyA->localFrameToWorld(m_linkA, frameAworld); + } + } + btVector3 pivotBworld = m_pivotInB; + btMatrix3x3 frameBworld = m_frameInB; + if (m_rigidBodyB) + { + constraintRow.m_solverBodyIdB = m_rigidBodyB->getCompanionId(); + pivotBworld = m_rigidBodyB->getCenterOfMassTransform() * m_pivotInB; + frameBworld = frameBworld.transpose() * btMatrix3x3(m_rigidBodyB->getOrientation()); + } + else + { + if (m_bodyB) + { + pivotBworld = m_bodyB->localPosToWorld(m_linkB, m_pivotInB); + frameBworld = m_bodyB->localFrameToWorld(m_linkB, frameBworld); + } + } + + btMatrix3x3 relRot = frameAworld.inverse() * frameBworld; + btVector3 angleDiff; + btGeneric6DofSpring2Constraint::matrixToEulerXYZ(relRot, angleDiff); + + btVector3 constraintNormalLin(0, 0, 0); + btVector3 constraintNormalAng(0, 0, 0); + btScalar posError = 0.0; + if (i < 3) + { + constraintNormalLin[i] = 1; + posError = (pivotAworld - pivotBworld).dot(constraintNormalLin); + fillMultiBodyConstraint(constraintRow, data, 0, 0, constraintNormalAng, + constraintNormalLin, pivotAworld, pivotBworld, + posError, + infoGlobal, + -m_maxAppliedImpulse, m_maxAppliedImpulse); + } + else + { //i>=3 + constraintNormalAng = frameAworld.getColumn(i % 3); + posError = angleDiff[i % 3]; + fillMultiBodyConstraint(constraintRow, data, 0, 0, constraintNormalAng, + constraintNormalLin, pivotAworld, pivotBworld, + posError, + infoGlobal, + -m_maxAppliedImpulse, m_maxAppliedImpulse, true); + } } } diff --git a/src/BulletDynamics/Featherstone/btMultiBodyFixedConstraint.h b/src/BulletDynamics/Featherstone/btMultiBodyFixedConstraint.h index 036025136..adb1cb47d 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyFixedConstraint.h +++ b/src/BulletDynamics/Featherstone/btMultiBodyFixedConstraint.h @@ -23,16 +23,14 @@ subject to the following restrictions: class btMultiBodyFixedConstraint : public btMultiBodyConstraint { protected: - - btRigidBody* m_rigidBodyA; - btRigidBody* m_rigidBodyB; - btVector3 m_pivotInA; - btVector3 m_pivotInB; - btMatrix3x3 m_frameInA; - btMatrix3x3 m_frameInB; + btRigidBody* m_rigidBodyA; + btRigidBody* m_rigidBodyB; + btVector3 m_pivotInA; + btVector3 m_pivotInB; + btMatrix3x3 m_frameInA; + btMatrix3x3 m_frameInB; public: - btMultiBodyFixedConstraint(btMultiBody* body, int link, btRigidBody* bodyB, const btVector3& pivotInA, const btVector3& pivotInB, const btMatrix3x3& frameInA, const btMatrix3x3& frameInB); btMultiBodyFixedConstraint(btMultiBody* bodyA, int linkA, btMultiBody* bodyB, int linkB, const btVector3& pivotInA, const btVector3& pivotInB, const btMatrix3x3& frameInA, const btMatrix3x3& frameInB); @@ -44,18 +42,18 @@ public: virtual int getIslandIdB() const; virtual void createConstraintRows(btMultiBodyConstraintArray& constraintRows, - btMultiBodyJacobianData& data, - const btContactSolverInfo& infoGlobal); + btMultiBodyJacobianData& data, + const btContactSolverInfo& infoGlobal); - const btVector3& getPivotInA() const - { - return m_pivotInA; - } - - void setPivotInA(const btVector3& pivotInA) - { - m_pivotInA = pivotInA; - } + const btVector3& getPivotInA() const + { + return m_pivotInA; + } + + void setPivotInA(const btVector3& pivotInA) + { + m_pivotInA = pivotInA; + } const btVector3& getPivotInB() const { @@ -66,29 +64,28 @@ public: { m_pivotInB = pivotInB; } - - const btMatrix3x3& getFrameInA() const - { - return m_frameInA; - } - - void setFrameInA(const btMatrix3x3& frameInA) - { - m_frameInA = frameInA; - } - - const btMatrix3x3& getFrameInB() const - { - return m_frameInB; - } - - virtual void setFrameInB(const btMatrix3x3& frameInB) - { - m_frameInB = frameInB; - } + + const btMatrix3x3& getFrameInA() const + { + return m_frameInA; + } + + void setFrameInA(const btMatrix3x3& frameInA) + { + m_frameInA = frameInA; + } + + const btMatrix3x3& getFrameInB() const + { + return m_frameInB; + } + + virtual void setFrameInB(const btMatrix3x3& frameInB) + { + m_frameInB = frameInB; + } virtual void debugDraw(class btIDebugDraw* drawer); - }; -#endif //BT_MULTIBODY_FIXED_CONSTRAINT_H +#endif //BT_MULTIBODY_FIXED_CONSTRAINT_H diff --git a/src/BulletDynamics/Featherstone/btMultiBodyGearConstraint.cpp b/src/BulletDynamics/Featherstone/btMultiBodyGearConstraint.cpp index 09ddd65cd..bf6b811d2 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyGearConstraint.cpp +++ b/src/BulletDynamics/Featherstone/btMultiBodyGearConstraint.cpp @@ -21,20 +21,18 @@ subject to the following restrictions: #include "BulletCollision/CollisionDispatch/btCollisionObject.h" btMultiBodyGearConstraint::btMultiBodyGearConstraint(btMultiBody* bodyA, int linkA, btMultiBody* bodyB, int linkB, const btVector3& pivotInA, const btVector3& pivotInB, const btMatrix3x3& frameInA, const btMatrix3x3& frameInB) - :btMultiBodyConstraint(bodyA,bodyB,linkA,linkB,1,false), - m_gearRatio(1), - m_gearAuxLink(-1), - m_erp(0), - m_relativePositionTarget(0) + : btMultiBodyConstraint(bodyA, bodyB, linkA, linkB, 1, false), + m_gearRatio(1), + m_gearAuxLink(-1), + m_erp(0), + m_relativePositionTarget(0) { - } void btMultiBodyGearConstraint::finalizeMultiDof() { - allocateJacobiansMultiDof(); - + m_numDofsFinalized = m_jacSizeBoth; } @@ -42,7 +40,6 @@ btMultiBodyGearConstraint::~btMultiBodyGearConstraint() { } - int btMultiBodyGearConstraint::getIslandIdA() const { if (m_bodyA) @@ -81,27 +78,25 @@ int btMultiBodyGearConstraint::getIslandIdB() const return -1; } - void btMultiBodyGearConstraint::createConstraintRows(btMultiBodyConstraintArray& constraintRows, - btMultiBodyJacobianData& data, - const btContactSolverInfo& infoGlobal) + btMultiBodyJacobianData& data, + const btContactSolverInfo& infoGlobal) { - // only positions need to be updated -- data.m_jacobians and force - // directions were set in the ctor and never change. - + // only positions need to be updated -- data.m_jacobians and force + // directions were set in the ctor and never change. + if (m_numDofsFinalized != m_jacSizeBoth) { - finalizeMultiDof(); + finalizeMultiDof(); } //don't crash if (m_numDofsFinalized != m_jacSizeBoth) return; - - if (m_maxAppliedImpulse==0.f) + if (m_maxAppliedImpulse == 0.f) return; - + // note: we rely on the fact that data.m_jacobians are // always initialized to zero by the Constraint ctor int linkDoF = 0; @@ -114,67 +109,66 @@ void btMultiBodyGearConstraint::createConstraintRows(btMultiBodyConstraintArray& btScalar posError = 0; const btVector3 dummy(0, 0, 0); - + btScalar kp = 1; btScalar kd = 1; int numRows = getNumRows(); - for (int row=0;rowgetJointPosMultiDof(m_linkA)[dof]; - btScalar currentVelocity = m_bodyA->getJointVelMultiDof(m_linkA)[dof]; + int dof = 0; + btScalar currentPosition = m_bodyA->getJointPosMultiDof(m_linkA)[dof]; + btScalar currentVelocity = m_bodyA->getJointVelMultiDof(m_linkA)[dof]; btScalar auxVel = 0; - - if (m_gearAuxLink>=0) + + if (m_gearAuxLink >= 0) { auxVel = m_bodyA->getJointVelMultiDof(m_gearAuxLink)[dof]; } currentVelocity += auxVel; - if (m_erp!=0) + if (m_erp != 0) { btScalar currentPositionA = m_bodyA->getJointPosMultiDof(m_linkA)[dof]; if (m_gearAuxLink >= 0) { currentPositionA -= m_bodyA->getJointPosMultiDof(m_gearAuxLink)[dof]; } - btScalar currentPositionB = m_gearRatio*m_bodyA->getJointPosMultiDof(m_linkB)[dof]; - btScalar diff = currentPositionB+currentPositionA; + btScalar currentPositionB = m_gearRatio * m_bodyA->getJointPosMultiDof(m_linkB)[dof]; + btScalar diff = currentPositionB + currentPositionA; btScalar desiredPositionDiff = this->m_relativePositionTarget; - posError = -m_erp*(desiredPositionDiff - diff); + posError = -m_erp * (desiredPositionDiff - diff); } - - btScalar desiredRelativeVelocity = auxVel; - - fillMultiBodyConstraint(constraintRow,data,jacobianA(row),jacobianB(row),dummy,dummy,dummy,dummy,posError,infoGlobal,-m_maxAppliedImpulse,m_maxAppliedImpulse,false,1,false,desiredRelativeVelocity); + + btScalar desiredRelativeVelocity = auxVel; + + fillMultiBodyConstraint(constraintRow, data, jacobianA(row), jacobianB(row), dummy, dummy, dummy, dummy, posError, infoGlobal, -m_maxAppliedImpulse, m_maxAppliedImpulse, false, 1, false, desiredRelativeVelocity); constraintRow.m_orgConstraint = this; constraintRow.m_orgDofIndex = row; { //expect either prismatic or revolute joint type for now - btAssert((m_bodyA->getLink(m_linkA).m_jointType == btMultibodyLink::eRevolute)||(m_bodyA->getLink(m_linkA).m_jointType == btMultibodyLink::ePrismatic)); + btAssert((m_bodyA->getLink(m_linkA).m_jointType == btMultibodyLink::eRevolute) || (m_bodyA->getLink(m_linkA).m_jointType == btMultibodyLink::ePrismatic)); switch (m_bodyA->getLink(m_linkA).m_jointType) { case btMultibodyLink::eRevolute: { constraintRow.m_contactNormal1.setZero(); constraintRow.m_contactNormal2.setZero(); - btVector3 revoluteAxisInWorld = quatRotate(m_bodyA->getLink(m_linkA).m_cachedWorldTransform.getRotation(),m_bodyA->getLink(m_linkA).m_axes[0].m_topVec); - constraintRow.m_relpos1CrossNormal=revoluteAxisInWorld; - constraintRow.m_relpos2CrossNormal=-revoluteAxisInWorld; - + btVector3 revoluteAxisInWorld = quatRotate(m_bodyA->getLink(m_linkA).m_cachedWorldTransform.getRotation(), m_bodyA->getLink(m_linkA).m_axes[0].m_topVec); + constraintRow.m_relpos1CrossNormal = revoluteAxisInWorld; + constraintRow.m_relpos2CrossNormal = -revoluteAxisInWorld; + break; } case btMultibodyLink::ePrismatic: { - btVector3 prismaticAxisInWorld = quatRotate(m_bodyA->getLink(m_linkA).m_cachedWorldTransform.getRotation(),m_bodyA->getLink(m_linkA).m_axes[0].m_bottomVec); - constraintRow.m_contactNormal1=prismaticAxisInWorld; - constraintRow.m_contactNormal2=-prismaticAxisInWorld; + btVector3 prismaticAxisInWorld = quatRotate(m_bodyA->getLink(m_linkA).m_cachedWorldTransform.getRotation(), m_bodyA->getLink(m_linkA).m_axes[0].m_bottomVec); + constraintRow.m_contactNormal1 = prismaticAxisInWorld; + constraintRow.m_contactNormal2 = -prismaticAxisInWorld; constraintRow.m_relpos1CrossNormal.setZero(); - constraintRow.m_relpos2CrossNormal.setZero(); + constraintRow.m_relpos2CrossNormal.setZero(); break; } default: @@ -182,10 +176,6 @@ void btMultiBodyGearConstraint::createConstraintRows(btMultiBodyConstraintArray& btAssert(0); } }; - } - } - } - diff --git a/src/BulletDynamics/Featherstone/btMultiBodyGearConstraint.h b/src/BulletDynamics/Featherstone/btMultiBodyGearConstraint.h index 0115de624..31888fbc6 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyGearConstraint.h +++ b/src/BulletDynamics/Featherstone/btMultiBodyGearConstraint.h @@ -23,20 +23,18 @@ subject to the following restrictions: class btMultiBodyGearConstraint : public btMultiBodyConstraint { protected: + btRigidBody* m_rigidBodyA; + btRigidBody* m_rigidBodyB; + btVector3 m_pivotInA; + btVector3 m_pivotInB; + btMatrix3x3 m_frameInA; + btMatrix3x3 m_frameInB; + btScalar m_gearRatio; + int m_gearAuxLink; + btScalar m_erp; + btScalar m_relativePositionTarget; - btRigidBody* m_rigidBodyA; - btRigidBody* m_rigidBodyB; - btVector3 m_pivotInA; - btVector3 m_pivotInB; - btMatrix3x3 m_frameInA; - btMatrix3x3 m_frameInB; - btScalar m_gearRatio; - int m_gearAuxLink; - btScalar m_erp; - btScalar m_relativePositionTarget; - public: - //btMultiBodyGearConstraint(btMultiBody* body, int link, btRigidBody* bodyB, const btVector3& pivotInA, const btVector3& pivotInB, const btMatrix3x3& frameInA, const btMatrix3x3& frameInB); btMultiBodyGearConstraint(btMultiBody* bodyA, int linkA, btMultiBody* bodyB, int linkB, const btVector3& pivotInA, const btVector3& pivotInB, const btMatrix3x3& frameInA, const btMatrix3x3& frameInB); @@ -48,18 +46,18 @@ public: virtual int getIslandIdB() const; virtual void createConstraintRows(btMultiBodyConstraintArray& constraintRows, - btMultiBodyJacobianData& data, - const btContactSolverInfo& infoGlobal); + btMultiBodyJacobianData& data, + const btContactSolverInfo& infoGlobal); - const btVector3& getPivotInA() const - { - return m_pivotInA; - } - - void setPivotInA(const btVector3& pivotInA) - { - m_pivotInA = pivotInA; - } + const btVector3& getPivotInA() const + { + return m_pivotInA; + } + + void setPivotInA(const btVector3& pivotInA) + { + m_pivotInA = pivotInA; + } const btVector3& getPivotInB() const { @@ -70,32 +68,32 @@ public: { m_pivotInB = pivotInB; } - - const btMatrix3x3& getFrameInA() const - { - return m_frameInA; - } - - void setFrameInA(const btMatrix3x3& frameInA) - { - m_frameInA = frameInA; - } - - const btMatrix3x3& getFrameInB() const - { - return m_frameInB; - } - - virtual void setFrameInB(const btMatrix3x3& frameInB) - { - m_frameInB = frameInB; - } + + const btMatrix3x3& getFrameInA() const + { + return m_frameInA; + } + + void setFrameInA(const btMatrix3x3& frameInA) + { + m_frameInA = frameInA; + } + + const btMatrix3x3& getFrameInB() const + { + return m_frameInB; + } + + virtual void setFrameInB(const btMatrix3x3& frameInB) + { + m_frameInB = frameInB; + } virtual void debugDraw(class btIDebugDraw* drawer) { //todo(erwincoumans) } - + virtual void setGearRatio(btScalar gearRatio) { m_gearRatio = gearRatio; @@ -114,4 +112,4 @@ public: } }; -#endif //BT_MULTIBODY_GEAR_CONSTRAINT_H +#endif //BT_MULTIBODY_GEAR_CONSTRAINT_H diff --git a/src/BulletDynamics/Featherstone/btMultiBodyJointFeedback.h b/src/BulletDynamics/Featherstone/btMultiBodyJointFeedback.h index 5c2fa8ed5..d943019e7 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyJointFeedback.h +++ b/src/BulletDynamics/Featherstone/btMultiBodyJointFeedback.h @@ -12,8 +12,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #ifndef BT_MULTIBODY_JOINT_FEEDBACK_H #define BT_MULTIBODY_JOINT_FEEDBACK_H @@ -21,7 +19,7 @@ subject to the following restrictions: struct btMultiBodyJointFeedback { - btSpatialForceVector m_reactionForces; + btSpatialForceVector m_reactionForces; }; -#endif //BT_MULTIBODY_JOINT_FEEDBACK_H +#endif //BT_MULTIBODY_JOINT_FEEDBACK_H diff --git a/src/BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.cpp b/src/BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.cpp index 35c929f7c..8791ad286 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.cpp +++ b/src/BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.cpp @@ -20,21 +20,18 @@ subject to the following restrictions: #include "btMultiBodyLinkCollider.h" #include "BulletCollision/CollisionDispatch/btCollisionObject.h" - - btMultiBodyJointLimitConstraint::btMultiBodyJointLimitConstraint(btMultiBody* body, int link, btScalar lower, btScalar upper) //:btMultiBodyConstraint(body,0,link,-1,2,true), - :btMultiBodyConstraint(body,body,link,body->getLink(link).m_parent,2,true), - m_lowerBound(lower), - m_upperBound(upper) + : btMultiBodyConstraint(body, body, link, body->getLink(link).m_parent, 2, true), + m_lowerBound(lower), + m_upperBound(upper) { - } void btMultiBodyJointLimitConstraint::finalizeMultiDof() { // the data.m_jacobians never change, so may as well - // initialize them here + // initialize them here allocateJacobiansMultiDof(); @@ -53,10 +50,8 @@ btMultiBodyJointLimitConstraint::~btMultiBodyJointLimitConstraint() { } - int btMultiBodyJointLimitConstraint::getIslandIdA() const { - if (m_bodyA) { if (m_linkA < 0) @@ -93,72 +88,69 @@ int btMultiBodyJointLimitConstraint::getIslandIdB() const return -1; } - void btMultiBodyJointLimitConstraint::createConstraintRows(btMultiBodyConstraintArray& constraintRows, - btMultiBodyJacobianData& data, - const btContactSolverInfo& infoGlobal) + btMultiBodyJacobianData& data, + const btContactSolverInfo& infoGlobal) { - - // only positions need to be updated -- data.m_jacobians and force - // directions were set in the ctor and never change. + // only positions need to be updated -- data.m_jacobians and force + // directions were set in the ctor and never change. if (m_numDofsFinalized != m_jacSizeBoth) { - finalizeMultiDof(); + finalizeMultiDof(); } + // row 0: the lower bound + setPosition(0, m_bodyA->getJointPos(m_linkA) - m_lowerBound); //multidof: this is joint-type dependent - // row 0: the lower bound - setPosition(0, m_bodyA->getJointPos(m_linkA) - m_lowerBound); //multidof: this is joint-type dependent + // row 1: the upper bound + setPosition(1, m_upperBound - m_bodyA->getJointPos(m_linkA)); - // row 1: the upper bound - setPosition(1, m_upperBound - m_bodyA->getJointPos(m_linkA)); - - for (int row=0;row0) + if (penetration > 0) { continue; } - btScalar direction = row? -1 : 1; + btScalar direction = row ? -1 : 1; btMultiBodySolverConstraint& constraintRow = constraintRows.expandNonInitializing(); - constraintRow.m_orgConstraint = this; - constraintRow.m_orgDofIndex = row; - + constraintRow.m_orgConstraint = this; + constraintRow.m_orgDofIndex = row; + constraintRow.m_multiBodyA = m_bodyA; constraintRow.m_multiBodyB = m_bodyB; - const btScalar posError = 0; //why assume it's zero? + const btScalar posError = 0; //why assume it's zero? const btVector3 dummy(0, 0, 0); - btScalar rel_vel = fillMultiBodyConstraint(constraintRow,data,jacobianA(row),jacobianB(row),dummy,dummy,dummy,dummy,posError,infoGlobal,0,m_maxAppliedImpulse); + btScalar rel_vel = fillMultiBodyConstraint(constraintRow, data, jacobianA(row), jacobianB(row), dummy, dummy, dummy, dummy, posError, infoGlobal, 0, m_maxAppliedImpulse); { //expect either prismatic or revolute joint type for now - btAssert((m_bodyA->getLink(m_linkA).m_jointType == btMultibodyLink::eRevolute)||(m_bodyA->getLink(m_linkA).m_jointType == btMultibodyLink::ePrismatic)); + btAssert((m_bodyA->getLink(m_linkA).m_jointType == btMultibodyLink::eRevolute) || (m_bodyA->getLink(m_linkA).m_jointType == btMultibodyLink::ePrismatic)); switch (m_bodyA->getLink(m_linkA).m_jointType) { case btMultibodyLink::eRevolute: { constraintRow.m_contactNormal1.setZero(); constraintRow.m_contactNormal2.setZero(); - btVector3 revoluteAxisInWorld = direction*quatRotate(m_bodyA->getLink(m_linkA).m_cachedWorldTransform.getRotation(),m_bodyA->getLink(m_linkA).m_axes[0].m_topVec); - constraintRow.m_relpos1CrossNormal=revoluteAxisInWorld; - constraintRow.m_relpos2CrossNormal=-revoluteAxisInWorld; - + btVector3 revoluteAxisInWorld = direction * quatRotate(m_bodyA->getLink(m_linkA).m_cachedWorldTransform.getRotation(), m_bodyA->getLink(m_linkA).m_axes[0].m_topVec); + constraintRow.m_relpos1CrossNormal = revoluteAxisInWorld; + constraintRow.m_relpos2CrossNormal = -revoluteAxisInWorld; + break; } case btMultibodyLink::ePrismatic: { - btVector3 prismaticAxisInWorld = direction* quatRotate(m_bodyA->getLink(m_linkA).m_cachedWorldTransform.getRotation(),m_bodyA->getLink(m_linkA).m_axes[0].m_bottomVec); - constraintRow.m_contactNormal1=prismaticAxisInWorld; - constraintRow.m_contactNormal2=-prismaticAxisInWorld; + btVector3 prismaticAxisInWorld = direction * quatRotate(m_bodyA->getLink(m_linkA).m_cachedWorldTransform.getRotation(), m_bodyA->getLink(m_linkA).m_axes[0].m_bottomVec); + constraintRow.m_contactNormal1 = prismaticAxisInWorld; + constraintRow.m_contactNormal2 = -prismaticAxisInWorld; constraintRow.m_relpos1CrossNormal.setZero(); constraintRow.m_relpos2CrossNormal.setZero(); - + break; } default: @@ -166,36 +158,35 @@ void btMultiBodyJointLimitConstraint::createConstraintRows(btMultiBodyConstraint btAssert(0); } }; - } { - btScalar positionalError = 0.f; - btScalar velocityError = - rel_vel;// * damping; + btScalar velocityError = -rel_vel; // * damping; btScalar erp = infoGlobal.m_erp2; if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold)) { erp = infoGlobal.m_erp; } - if (penetration>0) + if (penetration > 0) { positionalError = 0; velocityError = -penetration / infoGlobal.m_timeStep; - } else + } + else { - positionalError = -penetration * erp/infoGlobal.m_timeStep; + positionalError = -penetration * erp / infoGlobal.m_timeStep; } - btScalar penetrationImpulse = positionalError*constraintRow.m_jacDiagABInv; - btScalar velocityImpulse = velocityError *constraintRow.m_jacDiagABInv; + btScalar penetrationImpulse = positionalError * constraintRow.m_jacDiagABInv; + btScalar velocityImpulse = velocityError * constraintRow.m_jacDiagABInv; if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold)) { //combine position and velocity into rhs - constraintRow.m_rhs = penetrationImpulse+velocityImpulse; + constraintRow.m_rhs = penetrationImpulse + velocityImpulse; constraintRow.m_rhsPenetration = 0.f; - - } else + } + else { //split position and velocity into rhs and m_rhsPenetration constraintRow.m_rhs = velocityImpulse; @@ -203,9 +194,4 @@ void btMultiBodyJointLimitConstraint::createConstraintRows(btMultiBodyConstraint } } } - } - - - - diff --git a/src/BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.h b/src/BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.h index 55b8d122b..6716ba490 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.h +++ b/src/BulletDynamics/Featherstone/btMultiBodyJointLimitConstraint.h @@ -22,11 +22,10 @@ struct btSolverInfo; class btMultiBodyJointLimitConstraint : public btMultiBodyConstraint { protected: + btScalar m_lowerBound; + btScalar m_upperBound; - btScalar m_lowerBound; - btScalar m_upperBound; public: - btMultiBodyJointLimitConstraint(btMultiBody* body, int link, btScalar lower, btScalar upper); virtual ~btMultiBodyJointLimitConstraint(); @@ -36,15 +35,13 @@ public: virtual int getIslandIdB() const; virtual void createConstraintRows(btMultiBodyConstraintArray& constraintRows, - btMultiBodyJacobianData& data, - const btContactSolverInfo& infoGlobal); + btMultiBodyJacobianData& data, + const btContactSolverInfo& infoGlobal); virtual void debugDraw(class btIDebugDraw* drawer) { //todo(erwincoumans) } - }; -#endif //BT_MULTIBODY_JOINT_LIMIT_CONSTRAINT_H - +#endif //BT_MULTIBODY_JOINT_LIMIT_CONSTRAINT_H diff --git a/src/BulletDynamics/Featherstone/btMultiBodyJointMotor.cpp b/src/BulletDynamics/Featherstone/btMultiBodyJointMotor.cpp index be9713da3..cc7156c64 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyJointMotor.cpp +++ b/src/BulletDynamics/Featherstone/btMultiBodyJointMotor.cpp @@ -20,22 +20,18 @@ subject to the following restrictions: #include "btMultiBodyLinkCollider.h" #include "BulletCollision/CollisionDispatch/btCollisionObject.h" - btMultiBodyJointMotor::btMultiBodyJointMotor(btMultiBody* body, int link, btScalar desiredVelocity, btScalar maxMotorImpulse) - :btMultiBodyConstraint(body,body,link,body->getLink(link).m_parent,1,true), - m_desiredVelocity(desiredVelocity), - m_desiredPosition(0), - m_kd(1.), - m_kp(0), - m_erp(1), - m_rhsClamp(SIMD_INFINITY) + : btMultiBodyConstraint(body, body, link, body->getLink(link).m_parent, 1, true), + m_desiredVelocity(desiredVelocity), + m_desiredPosition(0), + m_kd(1.), + m_kp(0), + m_erp(1), + m_rhsClamp(SIMD_INFINITY) { - m_maxAppliedImpulse = maxMotorImpulse; // the data.m_jacobians never change, so may as well - // initialize them here - - + // initialize them here } void btMultiBodyJointMotor::finalizeMultiDof() @@ -55,18 +51,17 @@ void btMultiBodyJointMotor::finalizeMultiDof() btMultiBodyJointMotor::btMultiBodyJointMotor(btMultiBody* body, int link, int linkDoF, btScalar desiredVelocity, btScalar maxMotorImpulse) //:btMultiBodyConstraint(body,0,link,-1,1,true), - :btMultiBodyConstraint(body,body,link,body->getLink(link).m_parent,1,true), - m_desiredVelocity(desiredVelocity), - m_desiredPosition(0), - m_kd(1.), - m_kp(0), - m_erp(1), - m_rhsClamp(SIMD_INFINITY) + : btMultiBodyConstraint(body, body, link, body->getLink(link).m_parent, 1, true), + m_desiredVelocity(desiredVelocity), + m_desiredPosition(0), + m_kd(1.), + m_kp(0), + m_erp(1), + m_rhsClamp(SIMD_INFINITY) { btAssert(linkDoF < body->getLink(link).m_dofCount); m_maxAppliedImpulse = maxMotorImpulse; - } btMultiBodyJointMotor::~btMultiBodyJointMotor() { @@ -108,76 +103,74 @@ int btMultiBodyJointMotor::getIslandIdB() const return -1; } - void btMultiBodyJointMotor::createConstraintRows(btMultiBodyConstraintArray& constraintRows, - btMultiBodyJacobianData& data, - const btContactSolverInfo& infoGlobal) + btMultiBodyJacobianData& data, + const btContactSolverInfo& infoGlobal) { - // only positions need to be updated -- data.m_jacobians and force - // directions were set in the ctor and never change. - + // only positions need to be updated -- data.m_jacobians and force + // directions were set in the ctor and never change. + if (m_numDofsFinalized != m_jacSizeBoth) { - finalizeMultiDof(); + finalizeMultiDof(); } //don't crash if (m_numDofsFinalized != m_jacSizeBoth) return; - if (m_maxAppliedImpulse==0.f) + if (m_maxAppliedImpulse == 0.f) return; const btScalar posError = 0; const btVector3 dummy(0, 0, 0); - for (int row=0;rowgetJointPosMultiDof(m_linkA)[dof]; - btScalar currentVelocity = m_bodyA->getJointVelMultiDof(m_linkA)[dof]; - btScalar positionStabiliationTerm = m_erp*(m_desiredPosition-currentPosition)/infoGlobal.m_timeStep; - - btScalar velocityError = (m_desiredVelocity - currentVelocity); - btScalar rhs = m_kp * positionStabiliationTerm + currentVelocity+m_kd * velocityError; - if (rhs>m_rhsClamp) + int dof = 0; + btScalar currentPosition = m_bodyA->getJointPosMultiDof(m_linkA)[dof]; + btScalar currentVelocity = m_bodyA->getJointVelMultiDof(m_linkA)[dof]; + btScalar positionStabiliationTerm = m_erp * (m_desiredPosition - currentPosition) / infoGlobal.m_timeStep; + + btScalar velocityError = (m_desiredVelocity - currentVelocity); + btScalar rhs = m_kp * positionStabiliationTerm + currentVelocity + m_kd * velocityError; + if (rhs > m_rhsClamp) { - rhs=m_rhsClamp; + rhs = m_rhsClamp; } - if (rhs<-m_rhsClamp) + if (rhs < -m_rhsClamp) { - rhs=-m_rhsClamp; + rhs = -m_rhsClamp; } - - - fillMultiBodyConstraint(constraintRow,data,jacobianA(row),jacobianB(row),dummy,dummy,dummy,dummy,posError,infoGlobal,-m_maxAppliedImpulse,m_maxAppliedImpulse,false,1,false,rhs); + + fillMultiBodyConstraint(constraintRow, data, jacobianA(row), jacobianB(row), dummy, dummy, dummy, dummy, posError, infoGlobal, -m_maxAppliedImpulse, m_maxAppliedImpulse, false, 1, false, rhs); constraintRow.m_orgConstraint = this; constraintRow.m_orgDofIndex = row; { //expect either prismatic or revolute joint type for now - btAssert((m_bodyA->getLink(m_linkA).m_jointType == btMultibodyLink::eRevolute)||(m_bodyA->getLink(m_linkA).m_jointType == btMultibodyLink::ePrismatic)); + btAssert((m_bodyA->getLink(m_linkA).m_jointType == btMultibodyLink::eRevolute) || (m_bodyA->getLink(m_linkA).m_jointType == btMultibodyLink::ePrismatic)); switch (m_bodyA->getLink(m_linkA).m_jointType) { case btMultibodyLink::eRevolute: { constraintRow.m_contactNormal1.setZero(); constraintRow.m_contactNormal2.setZero(); - btVector3 revoluteAxisInWorld = quatRotate(m_bodyA->getLink(m_linkA).m_cachedWorldTransform.getRotation(),m_bodyA->getLink(m_linkA).m_axes[0].m_topVec); - constraintRow.m_relpos1CrossNormal=revoluteAxisInWorld; - constraintRow.m_relpos2CrossNormal=-revoluteAxisInWorld; - + btVector3 revoluteAxisInWorld = quatRotate(m_bodyA->getLink(m_linkA).m_cachedWorldTransform.getRotation(), m_bodyA->getLink(m_linkA).m_axes[0].m_topVec); + constraintRow.m_relpos1CrossNormal = revoluteAxisInWorld; + constraintRow.m_relpos2CrossNormal = -revoluteAxisInWorld; + break; } case btMultibodyLink::ePrismatic: { - btVector3 prismaticAxisInWorld = quatRotate(m_bodyA->getLink(m_linkA).m_cachedWorldTransform.getRotation(),m_bodyA->getLink(m_linkA).m_axes[0].m_bottomVec); - constraintRow.m_contactNormal1=prismaticAxisInWorld; - constraintRow.m_contactNormal2=-prismaticAxisInWorld; + btVector3 prismaticAxisInWorld = quatRotate(m_bodyA->getLink(m_linkA).m_cachedWorldTransform.getRotation(), m_bodyA->getLink(m_linkA).m_axes[0].m_bottomVec); + constraintRow.m_contactNormal1 = prismaticAxisInWorld; + constraintRow.m_contactNormal2 = -prismaticAxisInWorld; constraintRow.m_relpos1CrossNormal.setZero(); constraintRow.m_relpos2CrossNormal.setZero(); - + break; } default: @@ -185,10 +178,6 @@ void btMultiBodyJointMotor::createConstraintRows(btMultiBodyConstraintArray& con btAssert(0); } }; - } - } - } - diff --git a/src/BulletDynamics/Featherstone/btMultiBodyJointMotor.h b/src/BulletDynamics/Featherstone/btMultiBodyJointMotor.h index 7cf57311a..8d7210600 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyJointMotor.h +++ b/src/BulletDynamics/Featherstone/btMultiBodyJointMotor.h @@ -24,41 +24,38 @@ struct btSolverInfo; class btMultiBodyJointMotor : public btMultiBodyConstraint { protected: - - btScalar m_desiredVelocity; - btScalar m_desiredPosition; - btScalar m_kd; - btScalar m_kp; - btScalar m_erp; - btScalar m_rhsClamp;//maximum error - + btScalar m_desiredVelocity; + btScalar m_desiredPosition; + btScalar m_kd; + btScalar m_kp; + btScalar m_erp; + btScalar m_rhsClamp; //maximum error public: - btMultiBodyJointMotor(btMultiBody* body, int link, btScalar desiredVelocity, btScalar maxMotorImpulse); btMultiBodyJointMotor(btMultiBody* body, int link, int linkDoF, btScalar desiredVelocity, btScalar maxMotorImpulse); virtual ~btMultiBodyJointMotor(); - virtual void finalizeMultiDof(); + virtual void finalizeMultiDof(); virtual int getIslandIdA() const; virtual int getIslandIdB() const; virtual void createConstraintRows(btMultiBodyConstraintArray& constraintRows, - btMultiBodyJacobianData& data, - const btContactSolverInfo& infoGlobal); + btMultiBodyJacobianData& data, + const btContactSolverInfo& infoGlobal); - virtual void setVelocityTarget(btScalar velTarget, btScalar kd = 1.f) - { - m_desiredVelocity = velTarget; - m_kd = kd; - } + virtual void setVelocityTarget(btScalar velTarget, btScalar kd = 1.f) + { + m_desiredVelocity = velTarget; + m_kd = kd; + } + + virtual void setPositionTarget(btScalar posTarget, btScalar kp = 1.f) + { + m_desiredPosition = posTarget; + m_kp = kp; + } - virtual void setPositionTarget(btScalar posTarget, btScalar kp = 1.f) - { - m_desiredPosition = posTarget; - m_kp = kp; - } - virtual void setErp(btScalar erp) { m_erp = erp; @@ -77,5 +74,4 @@ public: } }; -#endif //BT_MULTIBODY_JOINT_MOTOR_H - +#endif //BT_MULTIBODY_JOINT_MOTOR_H diff --git a/src/BulletDynamics/Featherstone/btMultiBodyLink.h b/src/BulletDynamics/Featherstone/btMultiBodyLink.h index 13e906cd6..ee0fc193b 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyLink.h +++ b/src/BulletDynamics/Featherstone/btMultiBodyLink.h @@ -20,7 +20,7 @@ subject to the following restrictions: #include "LinearMath/btVector3.h" #include "BulletCollision/CollisionDispatch/btCollisionObject.h" -enum btMultiBodyLinkFlags +enum btMultiBodyLinkFlags { BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION = 1, BT_MULTIBODYLINKFLAGS_DISABLE_ALL_PARENT_COLLISION = 2, @@ -36,7 +36,6 @@ enum btMultiBodyLinkFlags //namespace { - #include "LinearMath/btSpatialAlgebra.h" //} @@ -45,27 +44,26 @@ enum btMultiBodyLinkFlags // Link struct // -struct btMultibodyLink +struct btMultibodyLink { - BT_DECLARE_ALIGNED_ALLOCATOR(); - btScalar m_mass; // mass of link - btVector3 m_inertiaLocal; // inertia of link (local frame; diagonal) + btScalar m_mass; // mass of link + btVector3 m_inertiaLocal; // inertia of link (local frame; diagonal) - int m_parent; // index of the parent link (assumed to be < index of this link), or -1 if parent is the base link. + int m_parent; // index of the parent link (assumed to be < index of this link), or -1 if parent is the base link. - btQuaternion m_zeroRotParentToThis; // rotates vectors in parent-frame to vectors in local-frame (when q=0). constant. + btQuaternion m_zeroRotParentToThis; // rotates vectors in parent-frame to vectors in local-frame (when q=0). constant. - btVector3 m_dVector; // vector from the inboard joint pos to this link's COM. (local frame.) constant. - //this is set to zero for planar joint (see also m_eVector comment) - - // m_eVector is constant, but depends on the joint type: - // revolute, fixed, prismatic, spherical: vector from parent's COM to the pivot point, in PARENT's frame. + btVector3 m_dVector; // vector from the inboard joint pos to this link's COM. (local frame.) constant. + //this is set to zero for planar joint (see also m_eVector comment) + + // m_eVector is constant, but depends on the joint type: + // revolute, fixed, prismatic, spherical: vector from parent's COM to the pivot point, in PARENT's frame. // planar: vector from COM of parent to COM of this link, WHEN Q = 0. (local frame.) // todo: fix the planar so it is consistent with the other joints - - btVector3 m_eVector; + + btVector3 m_eVector; btSpatialMotionVector m_absFrameTotVelocity, m_absFrameLocVelocity; @@ -79,13 +77,11 @@ struct btMultibodyLink eInvalid }; - - // "axis" = spatial joint axis (Mirtich Defn 9 p104). (expressed in local frame.) constant. - // for prismatic: m_axesTop[0] = zero; - // m_axesBottom[0] = unit vector along the joint axis. - // for revolute: m_axesTop[0] = unit vector along the rotation axis (u); - // m_axesBottom[0] = u cross m_dVector (i.e. COM linear motion due to the rotation at the joint) + // for prismatic: m_axesTop[0] = zero; + // m_axesBottom[0] = unit vector along the joint axis. + // for revolute: m_axesTop[0] = unit vector along the rotation axis (u); + // m_axesBottom[0] = u cross m_dVector (i.e. COM linear motion due to the rotation at the joint) // // for spherical: m_axesTop[0][1][2] (u1,u2,u3) form a 3x3 identity matrix (3 rotation axes) // m_axesBottom[0][1][2] cross u1,u2,u3 (i.e. COM linear motion due to the rotation at the joint) @@ -93,143 +89,141 @@ struct btMultibodyLink // for planar: m_axesTop[0] = unit vector along the rotation axis (u); defines the plane of motion // m_axesTop[1][2] = zero // m_axesBottom[0] = zero - // m_axesBottom[1][2] = unit vectors along the translational axes on that plane + // m_axesBottom[1][2] = unit vectors along the translational axes on that plane btSpatialMotionVector m_axes[6]; void setAxisTop(int dof, const btVector3 &axis) { m_axes[dof].m_topVec = axis; } - void setAxisBottom(int dof, const btVector3 &axis) - { - m_axes[dof].m_bottomVec = axis; - } - void setAxisTop(int dof, const btScalar &x, const btScalar &y, const btScalar &z) + void setAxisBottom(int dof, const btVector3 &axis) { - m_axes[dof].m_topVec.setValue(x, y, z); + m_axes[dof].m_bottomVec = axis; } - void setAxisBottom(int dof, const btScalar &x, const btScalar &y, const btScalar &z) - { - m_axes[dof].m_bottomVec.setValue(x, y, z); + void setAxisTop(int dof, const btScalar &x, const btScalar &y, const btScalar &z) + { + m_axes[dof].m_topVec.setValue(x, y, z); } - const btVector3 & getAxisTop(int dof) const { return m_axes[dof].m_topVec; } - const btVector3 & getAxisBottom(int dof) const { return m_axes[dof].m_bottomVec; } + void setAxisBottom(int dof, const btScalar &x, const btScalar &y, const btScalar &z) + { + m_axes[dof].m_bottomVec.setValue(x, y, z); + } + const btVector3 &getAxisTop(int dof) const { return m_axes[dof].m_topVec; } + const btVector3 &getAxisBottom(int dof) const { return m_axes[dof].m_bottomVec; } int m_dofOffset, m_cfgOffset; - btQuaternion m_cachedRotParentToThis; // rotates vectors in parent frame to vectors in local frame - btVector3 m_cachedRVector; // vector from COM of parent to COM of this link, in local frame. + btQuaternion m_cachedRotParentToThis; // rotates vectors in parent frame to vectors in local frame + btVector3 m_cachedRVector; // vector from COM of parent to COM of this link, in local frame. - btVector3 m_appliedForce; // In WORLD frame - btVector3 m_appliedTorque; // In WORLD frame + btVector3 m_appliedForce; // In WORLD frame + btVector3 m_appliedTorque; // In WORLD frame -btVector3 m_appliedConstraintForce; // In WORLD frame - btVector3 m_appliedConstraintTorque; // In WORLD frame + btVector3 m_appliedConstraintForce; // In WORLD frame + btVector3 m_appliedConstraintTorque; // In WORLD frame btScalar m_jointPos[7]; - - //m_jointTorque is the joint torque applied by the user using 'addJointTorque'. - //It gets set to zero after each internal stepSimulation call + + //m_jointTorque is the joint torque applied by the user using 'addJointTorque'. + //It gets set to zero after each internal stepSimulation call btScalar m_jointTorque[6]; - - class btMultiBodyLinkCollider* m_collider; + + class btMultiBodyLinkCollider *m_collider; int m_flags; - - - int m_dofCount, m_posVarCount; //redundant but handy - + + int m_dofCount, m_posVarCount; //redundant but handy + eFeatherstoneJointType m_jointType; - - struct btMultiBodyJointFeedback* m_jointFeedback; - btTransform m_cachedWorldTransform;//this cache is updated when calling btMultiBody::forwardKinematics + struct btMultiBodyJointFeedback *m_jointFeedback; + + btTransform m_cachedWorldTransform; //this cache is updated when calling btMultiBody::forwardKinematics + + const char *m_linkName; //m_linkName memory needs to be managed by the developer/user! + const char *m_jointName; //m_jointName memory needs to be managed by the developer/user! + const void *m_userPtr; //m_userPtr ptr needs to be managed by the developer/user! + + btScalar m_jointDamping; //todo: implement this internally. It is unused for now, it is set by a URDF loader. User can apply manual damping. + btScalar m_jointFriction; //todo: implement this internally. It is unused for now, it is set by a URDF loader. User can apply manual friction using a velocity motor. + btScalar m_jointLowerLimit; //todo: implement this internally. It is unused for now, it is set by a URDF loader. + btScalar m_jointUpperLimit; //todo: implement this internally. It is unused for now, it is set by a URDF loader. + btScalar m_jointMaxForce; //todo: implement this internally. It is unused for now, it is set by a URDF loader. + btScalar m_jointMaxVelocity; //todo: implement this internally. It is unused for now, it is set by a URDF loader. - const char* m_linkName;//m_linkName memory needs to be managed by the developer/user! - const char* m_jointName;//m_jointName memory needs to be managed by the developer/user! - const void* m_userPtr;//m_userPtr ptr needs to be managed by the developer/user! - - btScalar m_jointDamping; //todo: implement this internally. It is unused for now, it is set by a URDF loader. User can apply manual damping. - btScalar m_jointFriction; //todo: implement this internally. It is unused for now, it is set by a URDF loader. User can apply manual friction using a velocity motor. - btScalar m_jointLowerLimit; //todo: implement this internally. It is unused for now, it is set by a URDF loader. - btScalar m_jointUpperLimit; //todo: implement this internally. It is unused for now, it is set by a URDF loader. - btScalar m_jointMaxForce; //todo: implement this internally. It is unused for now, it is set by a URDF loader. - btScalar m_jointMaxVelocity;//todo: implement this internally. It is unused for now, it is set by a URDF loader. - // ctor: set some sensible defaults btMultibodyLink() - : m_mass(1), - m_parent(-1), - m_zeroRotParentToThis(0, 0, 0, 1), - m_cachedRotParentToThis(0, 0, 0, 1), - m_collider(0), - m_flags(0), - m_dofCount(0), - m_posVarCount(0), - m_jointType(btMultibodyLink::eInvalid), - m_jointFeedback(0), - m_linkName(0), - m_jointName(0), - m_userPtr(0), - m_jointDamping(0), - m_jointFriction(0), - m_jointLowerLimit(0), - m_jointUpperLimit(0), - m_jointMaxForce(0), - m_jointMaxVelocity(0) + : m_mass(1), + m_parent(-1), + m_zeroRotParentToThis(0, 0, 0, 1), + m_cachedRotParentToThis(0, 0, 0, 1), + m_collider(0), + m_flags(0), + m_dofCount(0), + m_posVarCount(0), + m_jointType(btMultibodyLink::eInvalid), + m_jointFeedback(0), + m_linkName(0), + m_jointName(0), + m_userPtr(0), + m_jointDamping(0), + m_jointFriction(0), + m_jointLowerLimit(0), + m_jointUpperLimit(0), + m_jointMaxForce(0), + m_jointMaxVelocity(0) { - m_inertiaLocal.setValue(1, 1, 1); setAxisTop(0, 0., 0., 0.); setAxisBottom(0, 1., 0., 0.); m_dVector.setValue(0, 0, 0); m_eVector.setValue(0, 0, 0); m_cachedRVector.setValue(0, 0, 0); - m_appliedForce.setValue( 0, 0, 0); + m_appliedForce.setValue(0, 0, 0); m_appliedTorque.setValue(0, 0, 0); - m_appliedConstraintForce.setValue(0,0,0); - m_appliedConstraintTorque.setValue(0,0,0); - // + m_appliedConstraintForce.setValue(0, 0, 0); + m_appliedConstraintTorque.setValue(0, 0, 0); + // m_jointPos[0] = m_jointPos[1] = m_jointPos[2] = m_jointPos[4] = m_jointPos[5] = m_jointPos[6] = 0.f; - m_jointPos[3] = 1.f; //"quat.w" + m_jointPos[3] = 1.f; //"quat.w" m_jointTorque[0] = m_jointTorque[1] = m_jointTorque[2] = m_jointTorque[3] = m_jointTorque[4] = m_jointTorque[5] = 0.f; m_cachedWorldTransform.setIdentity(); } - // routine to update m_cachedRotParentToThis and m_cachedRVector + // routine to update m_cachedRotParentToThis and m_cachedRVector void updateCacheMultiDof(btScalar *pq = 0) { btScalar *pJointPos = (pq ? pq : &m_jointPos[0]); - switch(m_jointType) + switch (m_jointType) { case eRevolute: { - m_cachedRotParentToThis = btQuaternion(getAxisTop(0),-pJointPos[0]) * m_zeroRotParentToThis; - m_cachedRVector = m_dVector + quatRotate(m_cachedRotParentToThis,m_eVector); + m_cachedRotParentToThis = btQuaternion(getAxisTop(0), -pJointPos[0]) * m_zeroRotParentToThis; + m_cachedRVector = m_dVector + quatRotate(m_cachedRotParentToThis, m_eVector); break; } case ePrismatic: { // m_cachedRotParentToThis never changes, so no need to update - m_cachedRVector = m_dVector + quatRotate(m_cachedRotParentToThis,m_eVector) + pJointPos[0] * getAxisBottom(0); + m_cachedRVector = m_dVector + quatRotate(m_cachedRotParentToThis, m_eVector) + pJointPos[0] * getAxisBottom(0); break; } case eSpherical: { m_cachedRotParentToThis = btQuaternion(pJointPos[0], pJointPos[1], pJointPos[2], -pJointPos[3]) * m_zeroRotParentToThis; - m_cachedRVector = m_dVector + quatRotate(m_cachedRotParentToThis,m_eVector); + m_cachedRVector = m_dVector + quatRotate(m_cachedRotParentToThis, m_eVector); break; } case ePlanar: { - m_cachedRotParentToThis = btQuaternion(getAxisTop(0),-pJointPos[0]) * m_zeroRotParentToThis; - m_cachedRVector = quatRotate(btQuaternion(getAxisTop(0),-pJointPos[0]), pJointPos[1] * getAxisBottom(1) + pJointPos[2] * getAxisBottom(2)) + quatRotate(m_cachedRotParentToThis,m_eVector); + m_cachedRotParentToThis = btQuaternion(getAxisTop(0), -pJointPos[0]) * m_zeroRotParentToThis; + m_cachedRVector = quatRotate(btQuaternion(getAxisTop(0), -pJointPos[0]), pJointPos[1] * getAxisBottom(1) + pJointPos[2] * getAxisBottom(2)) + quatRotate(m_cachedRotParentToThis, m_eVector); break; } case eFixed: { m_cachedRotParentToThis = m_zeroRotParentToThis; - m_cachedRVector = m_dVector + quatRotate(m_cachedRotParentToThis,m_eVector); + m_cachedRVector = m_dVector + quatRotate(m_cachedRotParentToThis, m_eVector); break; } @@ -242,5 +236,4 @@ btVector3 m_appliedConstraintForce; // In WORLD frame } }; - -#endif //BT_MULTIBODY_LINK_H +#endif //BT_MULTIBODY_LINK_H diff --git a/src/BulletDynamics/Featherstone/btMultiBodyLinkCollider.h b/src/BulletDynamics/Featherstone/btMultiBodyLinkCollider.h index 7092e62b5..f91c001f1 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyLinkCollider.h +++ b/src/BulletDynamics/Featherstone/btMultiBodyLinkCollider.h @@ -29,21 +29,18 @@ subject to the following restrictions: #define btMultiBodyLinkColliderDataName "btMultiBodyLinkColliderFloatData" #endif - class btMultiBodyLinkCollider : public btCollisionObject { -//protected: + //protected: public: - btMultiBody* m_multiBody; int m_link; - - btMultiBodyLinkCollider (btMultiBody* multiBody,int link) - :m_multiBody(multiBody), - m_link(link) + btMultiBodyLinkCollider(btMultiBody* multiBody, int link) + : m_multiBody(multiBody), + m_link(link) { - m_checkCollideWith = true; + m_checkCollideWith = true; //we need to remove the 'CF_STATIC_OBJECT' flag, otherwise links/base doesn't merge islands //this means that some constraints might point to bodies that are not in the islands, causing crashes //if (link>=0 || (multiBody && !multiBody->hasFixedBase())) @@ -59,18 +56,18 @@ public: } static btMultiBodyLinkCollider* upcast(btCollisionObject* colObj) { - if (colObj->getInternalType()&btCollisionObject::CO_FEATHERSTONE_LINK) + if (colObj->getInternalType() & btCollisionObject::CO_FEATHERSTONE_LINK) return (btMultiBodyLinkCollider*)colObj; return 0; } static const btMultiBodyLinkCollider* upcast(const btCollisionObject* colObj) { - if (colObj->getInternalType()&btCollisionObject::CO_FEATHERSTONE_LINK) + if (colObj->getInternalType() & btCollisionObject::CO_FEATHERSTONE_LINK) return (btMultiBodyLinkCollider*)colObj; return 0; } - virtual bool checkCollideWithOverride(const btCollisionObject* co) const + virtual bool checkCollideWithOverride(const btCollisionObject* co) const { const btMultiBodyLinkCollider* other = btMultiBodyLinkCollider::upcast(co); if (!other) @@ -81,47 +78,46 @@ public: return false; //check if 'link' has collision disabled - if (m_link>=0) + if (m_link >= 0) { const btMultibodyLink& link = m_multiBody->getLink(this->m_link); - if (link.m_flags&BT_MULTIBODYLINKFLAGS_DISABLE_ALL_PARENT_COLLISION) + if (link.m_flags & BT_MULTIBODYLINKFLAGS_DISABLE_ALL_PARENT_COLLISION) { int parent_of_this = m_link; while (1) { - if (parent_of_this==-1) + if (parent_of_this == -1) break; parent_of_this = m_multiBody->getLink(parent_of_this).m_parent; - if (parent_of_this==other->m_link) + if (parent_of_this == other->m_link) { return false; } } } - else if (link.m_flags&BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION) + else if (link.m_flags & BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION) { - if ( link.m_parent == other->m_link) + if (link.m_parent == other->m_link) return false; } - } - if (other->m_link>=0) + if (other->m_link >= 0) { const btMultibodyLink& otherLink = other->m_multiBody->getLink(other->m_link); - if (otherLink.m_flags& BT_MULTIBODYLINKFLAGS_DISABLE_ALL_PARENT_COLLISION) + if (otherLink.m_flags & BT_MULTIBODYLINKFLAGS_DISABLE_ALL_PARENT_COLLISION) { int parent_of_other = other->m_link; while (1) { - if (parent_of_other==-1) + if (parent_of_other == -1) break; parent_of_other = m_multiBody->getLink(parent_of_other).m_parent; - if (parent_of_other==this->m_link) + if (parent_of_other == this->m_link) return false; } } - else if (otherLink.m_flags& BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION) + else if (otherLink.m_flags & BT_MULTIBODYLINKFLAGS_DISABLE_PARENT_COLLISION) { if (otherLink.m_parent == this->m_link) return false; @@ -130,13 +126,13 @@ public: return true; } - virtual int calculateSerializeBufferSize() const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const; - + virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const; }; +// clang-format off struct btMultiBodyLinkColliderFloatData { @@ -154,16 +150,18 @@ struct btMultiBodyLinkColliderDoubleData char m_padding[4]; }; -SIMD_FORCE_INLINE int btMultiBodyLinkCollider::calculateSerializeBufferSize() const +// clang-format on + +SIMD_FORCE_INLINE int btMultiBodyLinkCollider::calculateSerializeBufferSize() const { return sizeof(btMultiBodyLinkColliderData); } -SIMD_FORCE_INLINE const char* btMultiBodyLinkCollider::serialize(void* dataBuffer, class btSerializer* serializer) const +SIMD_FORCE_INLINE const char* btMultiBodyLinkCollider::serialize(void* dataBuffer, class btSerializer* serializer) const { btMultiBodyLinkColliderData* dataOut = (btMultiBodyLinkColliderData*)dataBuffer; - btCollisionObject::serialize(&dataOut->m_colObjData,serializer); - + btCollisionObject::serialize(&dataOut->m_colObjData, serializer); + dataOut->m_link = this->m_link; dataOut->m_multiBody = (btMultiBodyData*)serializer->getUniquePointer(m_multiBody); @@ -173,5 +171,4 @@ SIMD_FORCE_INLINE const char* btMultiBodyLinkCollider::serialize(void* dataBuffe return btMultiBodyLinkColliderDataName; } -#endif //BT_FEATHERSTONE_LINK_COLLIDER_H - +#endif //BT_FEATHERSTONE_LINK_COLLIDER_H diff --git a/src/BulletDynamics/Featherstone/btMultiBodyPoint2Point.cpp b/src/BulletDynamics/Featherstone/btMultiBodyPoint2Point.cpp index 33ee28c46..b61ae1d77 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyPoint2Point.cpp +++ b/src/BulletDynamics/Featherstone/btMultiBodyPoint2Point.cpp @@ -21,29 +21,29 @@ subject to the following restrictions: #include "LinearMath/btIDebugDraw.h" #ifndef BTMBP2PCONSTRAINT_BLOCK_ANGULAR_MOTION_TEST - #define BTMBP2PCONSTRAINT_DIM 3 +#define BTMBP2PCONSTRAINT_DIM 3 #else - #define BTMBP2PCONSTRAINT_DIM 6 +#define BTMBP2PCONSTRAINT_DIM 6 #endif btMultiBodyPoint2Point::btMultiBodyPoint2Point(btMultiBody* body, int link, btRigidBody* bodyB, const btVector3& pivotInA, const btVector3& pivotInB) - :btMultiBodyConstraint(body,0,link,-1,BTMBP2PCONSTRAINT_DIM,false), - m_rigidBodyA(0), - m_rigidBodyB(bodyB), - m_pivotInA(pivotInA), - m_pivotInB(pivotInB) + : btMultiBodyConstraint(body, 0, link, -1, BTMBP2PCONSTRAINT_DIM, false), + m_rigidBodyA(0), + m_rigidBodyB(bodyB), + m_pivotInA(pivotInA), + m_pivotInB(pivotInB) { - m_data.resize(BTMBP2PCONSTRAINT_DIM);//at least store the applied impulses + m_data.resize(BTMBP2PCONSTRAINT_DIM); //at least store the applied impulses } btMultiBodyPoint2Point::btMultiBodyPoint2Point(btMultiBody* bodyA, int linkA, btMultiBody* bodyB, int linkB, const btVector3& pivotInA, const btVector3& pivotInB) - :btMultiBodyConstraint(bodyA,bodyB,linkA,linkB,BTMBP2PCONSTRAINT_DIM,false), - m_rigidBodyA(0), - m_rigidBodyB(0), - m_pivotInA(pivotInA), - m_pivotInB(pivotInB) + : btMultiBodyConstraint(bodyA, bodyB, linkA, linkB, BTMBP2PCONSTRAINT_DIM, false), + m_rigidBodyA(0), + m_rigidBodyB(0), + m_pivotInA(pivotInA), + m_pivotInB(pivotInB) { - m_data.resize(BTMBP2PCONSTRAINT_DIM);//at least store the applied impulses + m_data.resize(BTMBP2PCONSTRAINT_DIM); //at least store the applied impulses } void btMultiBodyPoint2Point::finalizeMultiDof() @@ -56,7 +56,6 @@ btMultiBodyPoint2Point::~btMultiBodyPoint2Point() { } - int btMultiBodyPoint2Point::getIslandIdA() const { if (m_rigidBodyA) @@ -73,7 +72,7 @@ int btMultiBodyPoint2Point::getIslandIdA() const else { if (m_bodyA->getLink(m_linkA).m_collider) - return m_bodyA->getLink(m_linkA).m_collider->getIslandTag(); + return m_bodyA->getLink(m_linkA).m_collider->getIslandTag(); } } return -1; @@ -100,48 +99,43 @@ int btMultiBodyPoint2Point::getIslandIdB() const return -1; } - - void btMultiBodyPoint2Point::createConstraintRows(btMultiBodyConstraintArray& constraintRows, - btMultiBodyJacobianData& data, - const btContactSolverInfo& infoGlobal) + btMultiBodyJacobianData& data, + const btContactSolverInfo& infoGlobal) { - -// int i=1; -int numDim = BTMBP2PCONSTRAINT_DIM; - for (int i=0;igetCompanionId(); - pivotAworld = m_rigidBodyA->getCenterOfMassTransform()*m_pivotInA; - } else + pivotAworld = m_rigidBodyA->getCenterOfMassTransform() * m_pivotInA; + } + else { if (m_bodyA) pivotAworld = m_bodyA->localPosToWorld(m_linkA, m_pivotInA); @@ -150,44 +144,41 @@ int numDim = BTMBP2PCONSTRAINT_DIM; if (m_rigidBodyB) { constraintRow.m_solverBodyIdB = m_rigidBodyB->getCompanionId(); - pivotBworld = m_rigidBodyB->getCenterOfMassTransform()*m_pivotInB; - } else + pivotBworld = m_rigidBodyB->getCenterOfMassTransform() * m_pivotInB; + } + else { if (m_bodyB) pivotBworld = m_bodyB->localPosToWorld(m_linkB, m_pivotInB); - } - btScalar posError = i < 3 ? (pivotAworld-pivotBworld).dot(contactNormalOnB) : 0; + btScalar posError = i < 3 ? (pivotAworld - pivotBworld).dot(contactNormalOnB) : 0; #ifndef BTMBP2PCONSTRAINT_BLOCK_ANGULAR_MOTION_TEST - - fillMultiBodyConstraint(constraintRow, data, 0, 0, btVector3(0,0,0), - contactNormalOnB, pivotAworld, pivotBworld, //sucks but let it be this way "for the time being" - posError, - infoGlobal, - -m_maxAppliedImpulse, m_maxAppliedImpulse - ); - //@todo: support the case of btMultiBody versus btRigidBody, - //see btPoint2PointConstraint::getInfo2NonVirtual + fillMultiBodyConstraint(constraintRow, data, 0, 0, btVector3(0, 0, 0), + contactNormalOnB, pivotAworld, pivotBworld, //sucks but let it be this way "for the time being" + posError, + infoGlobal, + -m_maxAppliedImpulse, m_maxAppliedImpulse); + //@todo: support the case of btMultiBody versus btRigidBody, + //see btPoint2PointConstraint::getInfo2NonVirtual #else const btVector3 dummy(0, 0, 0); btAssert(m_bodyA->isMultiDof()); btScalar* jac1 = jacobianA(i); - const btVector3 &normalAng = i >= 3 ? contactNormalOnB : dummy; - const btVector3 &normalLin = i < 3 ? contactNormalOnB : dummy; + const btVector3& normalAng = i >= 3 ? contactNormalOnB : dummy; + const btVector3& normalLin = i < 3 ? contactNormalOnB : dummy; m_bodyA->filConstraintJacobianMultiDof(m_linkA, pivotAworld, normalAng, normalLin, jac1, data.scratch_r, data.scratch_v, data.scratch_m); fillMultiBodyConstraint(constraintRow, data, jac1, 0, - dummy, dummy, dummy, //sucks but let it be this way "for the time being" - posError, - infoGlobal, - -m_maxAppliedImpulse, m_maxAppliedImpulse - ); + dummy, dummy, dummy, //sucks but let it be this way "for the time being" + posError, + infoGlobal, + -m_maxAppliedImpulse, m_maxAppliedImpulse); #endif } } diff --git a/src/BulletDynamics/Featherstone/btMultiBodyPoint2Point.h b/src/BulletDynamics/Featherstone/btMultiBodyPoint2Point.h index bf39acc5b..ef03a557e 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodyPoint2Point.h +++ b/src/BulletDynamics/Featherstone/btMultiBodyPoint2Point.h @@ -22,22 +22,20 @@ subject to the following restrictions: //#define BTMBP2PCONSTRAINT_BLOCK_ANGULAR_MOTION_TEST -ATTRIBUTE_ALIGNED16(class) btMultiBodyPoint2Point : public btMultiBodyConstraint +ATTRIBUTE_ALIGNED16(class) +btMultiBodyPoint2Point : public btMultiBodyConstraint { protected: - - btRigidBody* m_rigidBodyA; - btRigidBody* m_rigidBodyB; - btVector3 m_pivotInA; - btVector3 m_pivotInB; - + btRigidBody* m_rigidBodyA; + btRigidBody* m_rigidBodyB; + btVector3 m_pivotInA; + btVector3 m_pivotInB; public: - BT_DECLARE_ALIGNED_ALLOCATOR(); - btMultiBodyPoint2Point(btMultiBody* body, int link, btRigidBody* bodyB, const btVector3& pivotInA, const btVector3& pivotInB); - btMultiBodyPoint2Point(btMultiBody* bodyA, int linkA, btMultiBody* bodyB, int linkB, const btVector3& pivotInA, const btVector3& pivotInB); + btMultiBodyPoint2Point(btMultiBody * body, int link, btRigidBody* bodyB, const btVector3& pivotInA, const btVector3& pivotInB); + btMultiBodyPoint2Point(btMultiBody * bodyA, int linkA, btMultiBody* bodyB, int linkB, const btVector3& pivotInA, const btVector3& pivotInB); virtual ~btMultiBodyPoint2Point(); @@ -46,9 +44,9 @@ public: virtual int getIslandIdA() const; virtual int getIslandIdB() const; - virtual void createConstraintRows(btMultiBodyConstraintArray& constraintRows, - btMultiBodyJacobianData& data, - const btContactSolverInfo& infoGlobal); + virtual void createConstraintRows(btMultiBodyConstraintArray & constraintRows, + btMultiBodyJacobianData & data, + const btContactSolverInfo& infoGlobal); const btVector3& getPivotInB() const { @@ -60,9 +58,7 @@ public: m_pivotInB = pivotInB; } - - virtual void debugDraw(class btIDebugDraw* drawer); - + virtual void debugDraw(class btIDebugDraw * drawer); }; -#endif //BT_MULTIBODY_POINT2POINT_H +#endif //BT_MULTIBODY_POINT2POINT_H diff --git a/src/BulletDynamics/Featherstone/btMultiBodySliderConstraint.cpp b/src/BulletDynamics/Featherstone/btMultiBodySliderConstraint.cpp index cabd7dc0c..addd5bf89 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodySliderConstraint.cpp +++ b/src/BulletDynamics/Featherstone/btMultiBodySliderConstraint.cpp @@ -25,29 +25,29 @@ subject to the following restrictions: #define EPSILON 0.000001 btMultiBodySliderConstraint::btMultiBodySliderConstraint(btMultiBody* body, int link, btRigidBody* bodyB, const btVector3& pivotInA, const btVector3& pivotInB, const btMatrix3x3& frameInA, const btMatrix3x3& frameInB, const btVector3& jointAxis) - :btMultiBodyConstraint(body,0,link,-1,BTMBSLIDERCONSTRAINT_DIM,false), - m_rigidBodyA(0), - m_rigidBodyB(bodyB), - m_pivotInA(pivotInA), - m_pivotInB(pivotInB), - m_frameInA(frameInA), - m_frameInB(frameInB), - m_jointAxis(jointAxis) + : btMultiBodyConstraint(body, 0, link, -1, BTMBSLIDERCONSTRAINT_DIM, false), + m_rigidBodyA(0), + m_rigidBodyB(bodyB), + m_pivotInA(pivotInA), + m_pivotInB(pivotInB), + m_frameInA(frameInA), + m_frameInB(frameInB), + m_jointAxis(jointAxis) { - m_data.resize(BTMBSLIDERCONSTRAINT_DIM);//at least store the applied impulses + m_data.resize(BTMBSLIDERCONSTRAINT_DIM); //at least store the applied impulses } btMultiBodySliderConstraint::btMultiBodySliderConstraint(btMultiBody* bodyA, int linkA, btMultiBody* bodyB, int linkB, const btVector3& pivotInA, const btVector3& pivotInB, const btMatrix3x3& frameInA, const btMatrix3x3& frameInB, const btVector3& jointAxis) - :btMultiBodyConstraint(bodyA,bodyB,linkA,linkB,BTMBSLIDERCONSTRAINT_DIM,false), - m_rigidBodyA(0), - m_rigidBodyB(0), - m_pivotInA(pivotInA), - m_pivotInB(pivotInB), - m_frameInA(frameInA), - m_frameInB(frameInB), - m_jointAxis(jointAxis) + : btMultiBodyConstraint(bodyA, bodyB, linkA, linkB, BTMBSLIDERCONSTRAINT_DIM, false), + m_rigidBodyA(0), + m_rigidBodyB(0), + m_pivotInA(pivotInA), + m_pivotInB(pivotInB), + m_frameInA(frameInA), + m_frameInB(frameInB), + m_jointAxis(jointAxis) { - m_data.resize(BTMBSLIDERCONSTRAINT_DIM);//at least store the applied impulses + m_data.resize(BTMBSLIDERCONSTRAINT_DIM); //at least store the applied impulses } void btMultiBodySliderConstraint::finalizeMultiDof() @@ -60,7 +60,6 @@ btMultiBodySliderConstraint::~btMultiBodySliderConstraint() { } - int btMultiBodySliderConstraint::getIslandIdA() const { if (m_rigidBodyA) @@ -105,98 +104,100 @@ int btMultiBodySliderConstraint::getIslandIdB() const } void btMultiBodySliderConstraint::createConstraintRows(btMultiBodyConstraintArray& constraintRows, btMultiBodyJacobianData& data, const btContactSolverInfo& infoGlobal) { - // Convert local points back to world - btVector3 pivotAworld = m_pivotInA; - btMatrix3x3 frameAworld = m_frameInA; - btVector3 jointAxis = m_jointAxis; - if (m_rigidBodyA) - { - pivotAworld = m_rigidBodyA->getCenterOfMassTransform()*m_pivotInA; - frameAworld = m_frameInA.transpose()*btMatrix3x3(m_rigidBodyA->getOrientation()); - jointAxis = quatRotate(m_rigidBodyA->getOrientation(),m_jointAxis); - - } else if (m_bodyA) { - pivotAworld = m_bodyA->localPosToWorld(m_linkA, m_pivotInA); - frameAworld = m_bodyA->localFrameToWorld(m_linkA, m_frameInA); - jointAxis = m_bodyA->localDirToWorld(m_linkA, m_jointAxis); - } - btVector3 pivotBworld = m_pivotInB; - btMatrix3x3 frameBworld = m_frameInB; - if (m_rigidBodyB) - { - pivotBworld = m_rigidBodyB->getCenterOfMassTransform()*m_pivotInB; - frameBworld = m_frameInB.transpose()*btMatrix3x3(m_rigidBodyB->getOrientation()); - - } else if (m_bodyB) { - pivotBworld = m_bodyB->localPosToWorld(m_linkB, m_pivotInB); - frameBworld = m_bodyB->localFrameToWorld(m_linkB, m_frameInB); - } - - btVector3 constraintAxis[2]; - for (int i = 0; i < 3; ++i) - { - constraintAxis[0] = frameAworld.getColumn(i).cross(jointAxis); - if (constraintAxis[0].safeNorm() > EPSILON) - { - constraintAxis[0] = constraintAxis[0].normalized(); - constraintAxis[1] = jointAxis.cross(constraintAxis[0]); - constraintAxis[1] = constraintAxis[1].normalized(); - break; - } - } - - btMatrix3x3 relRot = frameAworld.inverse()*frameBworld; - btVector3 angleDiff; - btGeneric6DofSpring2Constraint::matrixToEulerXYZ(relRot,angleDiff); - - int numDim = BTMBSLIDERCONSTRAINT_DIM; - for (int i=0;igetCompanionId(); - } - if (m_rigidBodyB) - { - constraintRow.m_solverBodyIdB = m_rigidBodyB->getCompanionId(); - } - - btVector3 constraintNormalLin(0,0,0); - btVector3 constraintNormalAng(0,0,0); - btScalar posError = 0.0; - if (i < 2) { - constraintNormalLin = constraintAxis[i]; - posError = (pivotAworld-pivotBworld).dot(constraintNormalLin); - fillMultiBodyConstraint(constraintRow, data, 0, 0, constraintNormalAng, - constraintNormalLin, pivotAworld, pivotBworld, - posError, - infoGlobal, - -m_maxAppliedImpulse, m_maxAppliedImpulse - ); - } - else { //i>=2 - constraintNormalAng = frameAworld.getColumn(i%3); - posError = angleDiff[i%3]; - fillMultiBodyConstraint(constraintRow, data, 0, 0, constraintNormalAng, - constraintNormalLin, pivotAworld, pivotBworld, - posError, - infoGlobal, - -m_maxAppliedImpulse, m_maxAppliedImpulse, true - ); - } + pivotAworld = m_rigidBodyA->getCenterOfMassTransform() * m_pivotInA; + frameAworld = m_frameInA.transpose() * btMatrix3x3(m_rigidBodyA->getOrientation()); + jointAxis = quatRotate(m_rigidBodyA->getOrientation(), m_jointAxis); + } + else if (m_bodyA) + { + pivotAworld = m_bodyA->localPosToWorld(m_linkA, m_pivotInA); + frameAworld = m_bodyA->localFrameToWorld(m_linkA, m_frameInA); + jointAxis = m_bodyA->localDirToWorld(m_linkA, m_jointAxis); + } + btVector3 pivotBworld = m_pivotInB; + btMatrix3x3 frameBworld = m_frameInB; + if (m_rigidBodyB) + { + pivotBworld = m_rigidBodyB->getCenterOfMassTransform() * m_pivotInB; + frameBworld = m_frameInB.transpose() * btMatrix3x3(m_rigidBodyB->getOrientation()); + } + else if (m_bodyB) + { + pivotBworld = m_bodyB->localPosToWorld(m_linkB, m_pivotInB); + frameBworld = m_bodyB->localFrameToWorld(m_linkB, m_frameInB); + } + + btVector3 constraintAxis[2]; + for (int i = 0; i < 3; ++i) + { + constraintAxis[0] = frameAworld.getColumn(i).cross(jointAxis); + if (constraintAxis[0].safeNorm() > EPSILON) + { + constraintAxis[0] = constraintAxis[0].normalized(); + constraintAxis[1] = jointAxis.cross(constraintAxis[0]); + constraintAxis[1] = constraintAxis[1].normalized(); + break; + } + } + + btMatrix3x3 relRot = frameAworld.inverse() * frameBworld; + btVector3 angleDiff; + btGeneric6DofSpring2Constraint::matrixToEulerXYZ(relRot, angleDiff); + + int numDim = BTMBSLIDERCONSTRAINT_DIM; + for (int i = 0; i < numDim; i++) + { + btMultiBodySolverConstraint& constraintRow = constraintRows.expandNonInitializing(); + constraintRow.m_orgConstraint = this; + constraintRow.m_orgDofIndex = i; + constraintRow.m_relpos1CrossNormal.setValue(0, 0, 0); + constraintRow.m_contactNormal1.setValue(0, 0, 0); + constraintRow.m_relpos2CrossNormal.setValue(0, 0, 0); + constraintRow.m_contactNormal2.setValue(0, 0, 0); + constraintRow.m_angularComponentA.setValue(0, 0, 0); + constraintRow.m_angularComponentB.setValue(0, 0, 0); + + constraintRow.m_solverBodyIdA = data.m_fixedBodyId; + constraintRow.m_solverBodyIdB = data.m_fixedBodyId; + + if (m_rigidBodyA) + { + constraintRow.m_solverBodyIdA = m_rigidBodyA->getCompanionId(); + } + if (m_rigidBodyB) + { + constraintRow.m_solverBodyIdB = m_rigidBodyB->getCompanionId(); + } + + btVector3 constraintNormalLin(0, 0, 0); + btVector3 constraintNormalAng(0, 0, 0); + btScalar posError = 0.0; + if (i < 2) + { + constraintNormalLin = constraintAxis[i]; + posError = (pivotAworld - pivotBworld).dot(constraintNormalLin); + fillMultiBodyConstraint(constraintRow, data, 0, 0, constraintNormalAng, + constraintNormalLin, pivotAworld, pivotBworld, + posError, + infoGlobal, + -m_maxAppliedImpulse, m_maxAppliedImpulse); + } + else + { //i>=2 + constraintNormalAng = frameAworld.getColumn(i % 3); + posError = angleDiff[i % 3]; + fillMultiBodyConstraint(constraintRow, data, 0, 0, constraintNormalAng, + constraintNormalLin, pivotAworld, pivotBworld, + posError, + infoGlobal, + -m_maxAppliedImpulse, m_maxAppliedImpulse, true); + } } } diff --git a/src/BulletDynamics/Featherstone/btMultiBodySliderConstraint.h b/src/BulletDynamics/Featherstone/btMultiBodySliderConstraint.h index 0a6cf3df1..b192b6f8f 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodySliderConstraint.h +++ b/src/BulletDynamics/Featherstone/btMultiBodySliderConstraint.h @@ -23,17 +23,15 @@ subject to the following restrictions: class btMultiBodySliderConstraint : public btMultiBodyConstraint { protected: - - btRigidBody* m_rigidBodyA; - btRigidBody* m_rigidBodyB; - btVector3 m_pivotInA; - btVector3 m_pivotInB; - btMatrix3x3 m_frameInA; - btMatrix3x3 m_frameInB; - btVector3 m_jointAxis; + btRigidBody* m_rigidBodyA; + btRigidBody* m_rigidBodyB; + btVector3 m_pivotInA; + btVector3 m_pivotInB; + btMatrix3x3 m_frameInA; + btMatrix3x3 m_frameInB; + btVector3 m_jointAxis; public: - btMultiBodySliderConstraint(btMultiBody* body, int link, btRigidBody* bodyB, const btVector3& pivotInA, const btVector3& pivotInB, const btMatrix3x3& frameInA, const btMatrix3x3& frameInB, const btVector3& jointAxis); btMultiBodySliderConstraint(btMultiBody* bodyA, int linkA, btMultiBody* bodyB, int linkB, const btVector3& pivotInA, const btVector3& pivotInB, const btMatrix3x3& frameInA, const btMatrix3x3& frameInB, const btVector3& jointAxis); @@ -45,18 +43,18 @@ public: virtual int getIslandIdB() const; virtual void createConstraintRows(btMultiBodyConstraintArray& constraintRows, - btMultiBodyJacobianData& data, - const btContactSolverInfo& infoGlobal); + btMultiBodyJacobianData& data, + const btContactSolverInfo& infoGlobal); - const btVector3& getPivotInA() const - { - return m_pivotInA; - } - - void setPivotInA(const btVector3& pivotInA) - { - m_pivotInA = pivotInA; - } + const btVector3& getPivotInA() const + { + return m_pivotInA; + } + + void setPivotInA(const btVector3& pivotInA) + { + m_pivotInA = pivotInA; + } const btVector3& getPivotInB() const { @@ -67,39 +65,38 @@ public: { m_pivotInB = pivotInB; } - - const btMatrix3x3& getFrameInA() const - { - return m_frameInA; - } - - void setFrameInA(const btMatrix3x3& frameInA) - { - m_frameInA = frameInA; - } - - const btMatrix3x3& getFrameInB() const - { - return m_frameInB; - } - - virtual void setFrameInB(const btMatrix3x3& frameInB) - { - m_frameInB = frameInB; - } - - const btVector3& getJointAxis() const - { - return m_jointAxis; - } - - void setJointAxis(const btVector3& jointAxis) - { - m_jointAxis = jointAxis; - } + + const btMatrix3x3& getFrameInA() const + { + return m_frameInA; + } + + void setFrameInA(const btMatrix3x3& frameInA) + { + m_frameInA = frameInA; + } + + const btMatrix3x3& getFrameInB() const + { + return m_frameInB; + } + + virtual void setFrameInB(const btMatrix3x3& frameInB) + { + m_frameInB = frameInB; + } + + const btVector3& getJointAxis() const + { + return m_jointAxis; + } + + void setJointAxis(const btVector3& jointAxis) + { + m_jointAxis = jointAxis; + } virtual void debugDraw(class btIDebugDraw* drawer); - }; -#endif //BT_MULTIBODY_SLIDER_CONSTRAINT_H +#endif //BT_MULTIBODY_SLIDER_CONSTRAINT_H diff --git a/src/BulletDynamics/Featherstone/btMultiBodySolverConstraint.h b/src/BulletDynamics/Featherstone/btMultiBodySolverConstraint.h index 6fa1550e9..deed3e2a1 100644 --- a/src/BulletDynamics/Featherstone/btMultiBodySolverConstraint.h +++ b/src/BulletDynamics/Featherstone/btMultiBodySolverConstraint.h @@ -25,66 +25,66 @@ class btMultiBodyConstraint; #include "BulletDynamics/ConstraintSolver/btContactSolverInfo.h" ///1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and friction constraints. -ATTRIBUTE_ALIGNED16 (struct) btMultiBodySolverConstraint +ATTRIBUTE_ALIGNED16(struct) +btMultiBodySolverConstraint { BT_DECLARE_ALIGNED_ALLOCATOR(); - btMultiBodySolverConstraint() : m_solverBodyIdA(-1), m_multiBodyA(0), m_linkA(-1), m_solverBodyIdB(-1), m_multiBodyB(0), m_linkB(-1),m_orgConstraint(0), m_orgDofIndex(-1) - {} - - int m_deltaVelAindex;//more generic version of m_relpos1CrossNormal/m_contactNormal1 - int m_jacAindex; - int m_deltaVelBindex; - int m_jacBindex; - - btVector3 m_relpos1CrossNormal; - btVector3 m_contactNormal1; - btVector3 m_relpos2CrossNormal; - btVector3 m_contactNormal2; //usually m_contactNormal2 == -m_contactNormal1, but not always - - - btVector3 m_angularComponentA; - btVector3 m_angularComponentB; - - mutable btSimdScalar m_appliedPushImpulse; - mutable btSimdScalar m_appliedImpulse; - - btScalar m_friction; - btScalar m_jacDiagABInv; - btScalar m_rhs; - btScalar m_cfm; - - btScalar m_lowerLimit; - btScalar m_upperLimit; - btScalar m_rhsPenetration; - union + btMultiBodySolverConstraint() : m_solverBodyIdA(-1), m_multiBodyA(0), m_linkA(-1), m_solverBodyIdB(-1), m_multiBodyB(0), m_linkB(-1), m_orgConstraint(0), m_orgDofIndex(-1) { - void* m_originalContactPoint; - btScalar m_unusedPadding4; + } + + int m_deltaVelAindex; //more generic version of m_relpos1CrossNormal/m_contactNormal1 + int m_jacAindex; + int m_deltaVelBindex; + int m_jacBindex; + + btVector3 m_relpos1CrossNormal; + btVector3 m_contactNormal1; + btVector3 m_relpos2CrossNormal; + btVector3 m_contactNormal2; //usually m_contactNormal2 == -m_contactNormal1, but not always + + btVector3 m_angularComponentA; + btVector3 m_angularComponentB; + + mutable btSimdScalar m_appliedPushImpulse; + mutable btSimdScalar m_appliedImpulse; + + btScalar m_friction; + btScalar m_jacDiagABInv; + btScalar m_rhs; + btScalar m_cfm; + + btScalar m_lowerLimit; + btScalar m_upperLimit; + btScalar m_rhsPenetration; + union { + void* m_originalContactPoint; + btScalar m_unusedPadding4; }; - int m_overrideNumSolverIterations; - int m_frictionIndex; + int m_overrideNumSolverIterations; + int m_frictionIndex; int m_solverBodyIdA; btMultiBody* m_multiBodyA; - int m_linkA; - + int m_linkA; + int m_solverBodyIdB; btMultiBody* m_multiBodyB; - int m_linkB; + int m_linkB; //for writing back applied impulses - btMultiBodyConstraint* m_orgConstraint; + btMultiBodyConstraint* m_orgConstraint; int m_orgDofIndex; - enum btSolverConstraintType + enum btSolverConstraintType { BT_SOLVER_CONTACT_1D = 0, BT_SOLVER_FRICTION_1D }; }; -typedef btAlignedObjectArray btMultiBodyConstraintArray; +typedef btAlignedObjectArray btMultiBodyConstraintArray; -#endif //BT_MULTIBODY_SOLVER_CONSTRAINT_H +#endif //BT_MULTIBODY_SOLVER_CONSTRAINT_H diff --git a/src/BulletDynamics/MLCPSolvers/btDantzigLCP.cpp b/src/BulletDynamics/MLCPSolvers/btDantzigLCP.cpp index 986f21487..98ecdc079 100644 --- a/src/BulletDynamics/MLCPSolvers/btDantzigLCP.cpp +++ b/src/BulletDynamics/MLCPSolvers/btDantzigLCP.cpp @@ -108,18 +108,16 @@ rows/columns and manipulate C. */ - #include "btDantzigLCP.h" -#include //memcpy +#include //memcpy bool s_error = false; //*************************************************************************** // code generation parameters - -#define btLCP_FAST // use fast btLCP object +#define btLCP_FAST // use fast btLCP object // option 1 : matrix row pointers (less data copying) #define BTROWPTRS @@ -133,8 +131,6 @@ bool s_error = false; #define BTNUB_OPTIMIZATIONS - - /* solve L*X=B, with B containing 1 right hand sides. * L is an n*n lower triangular matrix with ones on the diagonal. * L is stored by rows and its leading dimension is lskip. @@ -145,66 +141,69 @@ bool s_error = false; * if this is in the factorizer source file, n must be a multiple of 2. */ -static void btSolveL1_1 (const btScalar *L, btScalar *B, int n, int lskip1) -{ - /* declare variables - Z matrix, p and q vectors, etc */ - btScalar Z11,m11,Z21,m21,p1,q1,p2,*ex; - const btScalar *ell; - int i,j; - /* compute all 2 x 1 blocks of X */ - for (i=0; i < n; i+=2) { - /* compute all 2 x 1 block of X, from rows i..i+2-1 */ - /* set the Z matrix to 0 */ - Z11=0; - Z21=0; - ell = L + i*lskip1; - ex = B; - /* the inner loop that computes outer products and adds them to Z */ - for (j=i-2; j >= 0; j -= 2) { - /* compute outer product and add it to the Z matrix */ - p1=ell[0]; - q1=ex[0]; - m11 = p1 * q1; - p2=ell[lskip1]; - m21 = p2 * q1; - Z11 += m11; - Z21 += m21; - /* compute outer product and add it to the Z matrix */ - p1=ell[1]; - q1=ex[1]; - m11 = p1 * q1; - p2=ell[1+lskip1]; - m21 = p2 * q1; - /* advance pointers */ - ell += 2; - ex += 2; - Z11 += m11; - Z21 += m21; - /* end of inner loop */ - } - /* compute left-over iterations */ - j += 2; - for (; j > 0; j--) { - /* compute outer product and add it to the Z matrix */ - p1=ell[0]; - q1=ex[0]; - m11 = p1 * q1; - p2=ell[lskip1]; - m21 = p2 * q1; - /* advance pointers */ - ell += 1; - ex += 1; - Z11 += m11; - Z21 += m21; - } - /* finish computing the X(i) block */ - Z11 = ex[0] - Z11; - ex[0] = Z11; - p1 = ell[lskip1]; - Z21 = ex[1] - Z21 - p1*Z11; - ex[1] = Z21; - /* end of outer loop */ - } +static void btSolveL1_1(const btScalar *L, btScalar *B, int n, int lskip1) +{ + /* declare variables - Z matrix, p and q vectors, etc */ + btScalar Z11, m11, Z21, m21, p1, q1, p2, *ex; + const btScalar *ell; + int i, j; + /* compute all 2 x 1 blocks of X */ + for (i = 0; i < n; i += 2) + { + /* compute all 2 x 1 block of X, from rows i..i+2-1 */ + /* set the Z matrix to 0 */ + Z11 = 0; + Z21 = 0; + ell = L + i * lskip1; + ex = B; + /* the inner loop that computes outer products and adds them to Z */ + for (j = i - 2; j >= 0; j -= 2) + { + /* compute outer product and add it to the Z matrix */ + p1 = ell[0]; + q1 = ex[0]; + m11 = p1 * q1; + p2 = ell[lskip1]; + m21 = p2 * q1; + Z11 += m11; + Z21 += m21; + /* compute outer product and add it to the Z matrix */ + p1 = ell[1]; + q1 = ex[1]; + m11 = p1 * q1; + p2 = ell[1 + lskip1]; + m21 = p2 * q1; + /* advance pointers */ + ell += 2; + ex += 2; + Z11 += m11; + Z21 += m21; + /* end of inner loop */ + } + /* compute left-over iterations */ + j += 2; + for (; j > 0; j--) + { + /* compute outer product and add it to the Z matrix */ + p1 = ell[0]; + q1 = ex[0]; + m11 = p1 * q1; + p2 = ell[lskip1]; + m21 = p2 * q1; + /* advance pointers */ + ell += 1; + ex += 1; + Z11 += m11; + Z21 += m21; + } + /* finish computing the X(i) block */ + Z11 = ex[0] - Z11; + ex[0] = Z11; + p1 = ell[lskip1]; + Z21 = ex[1] - Z21 - p1 * Z11; + ex[1] = Z21; + /* end of outer loop */ + } } /* solve L*X=B, with B containing 2 right hand sides. @@ -217,300 +216,308 @@ static void btSolveL1_1 (const btScalar *L, btScalar *B, int n, int lskip1) * if this is in the factorizer source file, n must be a multiple of 2. */ -static void btSolveL1_2 (const btScalar *L, btScalar *B, int n, int lskip1) -{ - /* declare variables - Z matrix, p and q vectors, etc */ - btScalar Z11,m11,Z12,m12,Z21,m21,Z22,m22,p1,q1,p2,q2,*ex; - const btScalar *ell; - int i,j; - /* compute all 2 x 2 blocks of X */ - for (i=0; i < n; i+=2) { - /* compute all 2 x 2 block of X, from rows i..i+2-1 */ - /* set the Z matrix to 0 */ - Z11=0; - Z12=0; - Z21=0; - Z22=0; - ell = L + i*lskip1; - ex = B; - /* the inner loop that computes outer products and adds them to Z */ - for (j=i-2; j >= 0; j -= 2) { - /* compute outer product and add it to the Z matrix */ - p1=ell[0]; - q1=ex[0]; - m11 = p1 * q1; - q2=ex[lskip1]; - m12 = p1 * q2; - p2=ell[lskip1]; - m21 = p2 * q1; - m22 = p2 * q2; - Z11 += m11; - Z12 += m12; - Z21 += m21; - Z22 += m22; - /* compute outer product and add it to the Z matrix */ - p1=ell[1]; - q1=ex[1]; - m11 = p1 * q1; - q2=ex[1+lskip1]; - m12 = p1 * q2; - p2=ell[1+lskip1]; - m21 = p2 * q1; - m22 = p2 * q2; - /* advance pointers */ - ell += 2; - ex += 2; - Z11 += m11; - Z12 += m12; - Z21 += m21; - Z22 += m22; - /* end of inner loop */ - } - /* compute left-over iterations */ - j += 2; - for (; j > 0; j--) { - /* compute outer product and add it to the Z matrix */ - p1=ell[0]; - q1=ex[0]; - m11 = p1 * q1; - q2=ex[lskip1]; - m12 = p1 * q2; - p2=ell[lskip1]; - m21 = p2 * q1; - m22 = p2 * q2; - /* advance pointers */ - ell += 1; - ex += 1; - Z11 += m11; - Z12 += m12; - Z21 += m21; - Z22 += m22; - } - /* finish computing the X(i) block */ - Z11 = ex[0] - Z11; - ex[0] = Z11; - Z12 = ex[lskip1] - Z12; - ex[lskip1] = Z12; - p1 = ell[lskip1]; - Z21 = ex[1] - Z21 - p1*Z11; - ex[1] = Z21; - Z22 = ex[1+lskip1] - Z22 - p1*Z12; - ex[1+lskip1] = Z22; - /* end of outer loop */ - } +static void btSolveL1_2(const btScalar *L, btScalar *B, int n, int lskip1) +{ + /* declare variables - Z matrix, p and q vectors, etc */ + btScalar Z11, m11, Z12, m12, Z21, m21, Z22, m22, p1, q1, p2, q2, *ex; + const btScalar *ell; + int i, j; + /* compute all 2 x 2 blocks of X */ + for (i = 0; i < n; i += 2) + { + /* compute all 2 x 2 block of X, from rows i..i+2-1 */ + /* set the Z matrix to 0 */ + Z11 = 0; + Z12 = 0; + Z21 = 0; + Z22 = 0; + ell = L + i * lskip1; + ex = B; + /* the inner loop that computes outer products and adds them to Z */ + for (j = i - 2; j >= 0; j -= 2) + { + /* compute outer product and add it to the Z matrix */ + p1 = ell[0]; + q1 = ex[0]; + m11 = p1 * q1; + q2 = ex[lskip1]; + m12 = p1 * q2; + p2 = ell[lskip1]; + m21 = p2 * q1; + m22 = p2 * q2; + Z11 += m11; + Z12 += m12; + Z21 += m21; + Z22 += m22; + /* compute outer product and add it to the Z matrix */ + p1 = ell[1]; + q1 = ex[1]; + m11 = p1 * q1; + q2 = ex[1 + lskip1]; + m12 = p1 * q2; + p2 = ell[1 + lskip1]; + m21 = p2 * q1; + m22 = p2 * q2; + /* advance pointers */ + ell += 2; + ex += 2; + Z11 += m11; + Z12 += m12; + Z21 += m21; + Z22 += m22; + /* end of inner loop */ + } + /* compute left-over iterations */ + j += 2; + for (; j > 0; j--) + { + /* compute outer product and add it to the Z matrix */ + p1 = ell[0]; + q1 = ex[0]; + m11 = p1 * q1; + q2 = ex[lskip1]; + m12 = p1 * q2; + p2 = ell[lskip1]; + m21 = p2 * q1; + m22 = p2 * q2; + /* advance pointers */ + ell += 1; + ex += 1; + Z11 += m11; + Z12 += m12; + Z21 += m21; + Z22 += m22; + } + /* finish computing the X(i) block */ + Z11 = ex[0] - Z11; + ex[0] = Z11; + Z12 = ex[lskip1] - Z12; + ex[lskip1] = Z12; + p1 = ell[lskip1]; + Z21 = ex[1] - Z21 - p1 * Z11; + ex[1] = Z21; + Z22 = ex[1 + lskip1] - Z22 - p1 * Z12; + ex[1 + lskip1] = Z22; + /* end of outer loop */ + } } +void btFactorLDLT(btScalar *A, btScalar *d, int n, int nskip1) +{ + int i, j; + btScalar sum, *ell, *dee, dd, p1, p2, q1, q2, Z11, m11, Z21, m21, Z22, m22; + if (n < 1) return; -void btFactorLDLT (btScalar *A, btScalar *d, int n, int nskip1) -{ - int i,j; - btScalar sum,*ell,*dee,dd,p1,p2,q1,q2,Z11,m11,Z21,m21,Z22,m22; - if (n < 1) return; - - for (i=0; i<=n-2; i += 2) { - /* solve L*(D*l)=a, l is scaled elements in 2 x i block at A(i,0) */ - btSolveL1_2 (A,A+i*nskip1,i,nskip1); - /* scale the elements in a 2 x i block at A(i,0), and also */ - /* compute Z = the outer product matrix that we'll need. */ - Z11 = 0; - Z21 = 0; - Z22 = 0; - ell = A+i*nskip1; - dee = d; - for (j=i-6; j >= 0; j -= 6) { - p1 = ell[0]; - p2 = ell[nskip1]; - dd = dee[0]; - q1 = p1*dd; - q2 = p2*dd; - ell[0] = q1; - ell[nskip1] = q2; - m11 = p1*q1; - m21 = p2*q1; - m22 = p2*q2; - Z11 += m11; - Z21 += m21; - Z22 += m22; - p1 = ell[1]; - p2 = ell[1+nskip1]; - dd = dee[1]; - q1 = p1*dd; - q2 = p2*dd; - ell[1] = q1; - ell[1+nskip1] = q2; - m11 = p1*q1; - m21 = p2*q1; - m22 = p2*q2; - Z11 += m11; - Z21 += m21; - Z22 += m22; - p1 = ell[2]; - p2 = ell[2+nskip1]; - dd = dee[2]; - q1 = p1*dd; - q2 = p2*dd; - ell[2] = q1; - ell[2+nskip1] = q2; - m11 = p1*q1; - m21 = p2*q1; - m22 = p2*q2; - Z11 += m11; - Z21 += m21; - Z22 += m22; - p1 = ell[3]; - p2 = ell[3+nskip1]; - dd = dee[3]; - q1 = p1*dd; - q2 = p2*dd; - ell[3] = q1; - ell[3+nskip1] = q2; - m11 = p1*q1; - m21 = p2*q1; - m22 = p2*q2; - Z11 += m11; - Z21 += m21; - Z22 += m22; - p1 = ell[4]; - p2 = ell[4+nskip1]; - dd = dee[4]; - q1 = p1*dd; - q2 = p2*dd; - ell[4] = q1; - ell[4+nskip1] = q2; - m11 = p1*q1; - m21 = p2*q1; - m22 = p2*q2; - Z11 += m11; - Z21 += m21; - Z22 += m22; - p1 = ell[5]; - p2 = ell[5+nskip1]; - dd = dee[5]; - q1 = p1*dd; - q2 = p2*dd; - ell[5] = q1; - ell[5+nskip1] = q2; - m11 = p1*q1; - m21 = p2*q1; - m22 = p2*q2; - Z11 += m11; - Z21 += m21; - Z22 += m22; - ell += 6; - dee += 6; - } - /* compute left-over iterations */ - j += 6; - for (; j > 0; j--) { - p1 = ell[0]; - p2 = ell[nskip1]; - dd = dee[0]; - q1 = p1*dd; - q2 = p2*dd; - ell[0] = q1; - ell[nskip1] = q2; - m11 = p1*q1; - m21 = p2*q1; - m22 = p2*q2; - Z11 += m11; - Z21 += m21; - Z22 += m22; - ell++; - dee++; - } - /* solve for diagonal 2 x 2 block at A(i,i) */ - Z11 = ell[0] - Z11; - Z21 = ell[nskip1] - Z21; - Z22 = ell[1+nskip1] - Z22; - dee = d + i; - /* factorize 2 x 2 block Z,dee */ - /* factorize row 1 */ - dee[0] = btRecip(Z11); - /* factorize row 2 */ - sum = 0; - q1 = Z21; - q2 = q1 * dee[0]; - Z21 = q2; - sum += q1*q2; - dee[1] = btRecip(Z22 - sum); - /* done factorizing 2 x 2 block */ - ell[nskip1] = Z21; - } - /* compute the (less than 2) rows at the bottom */ - switch (n-i) { - case 0: - break; - - case 1: - btSolveL1_1 (A,A+i*nskip1,i,nskip1); - /* scale the elements in a 1 x i block at A(i,0), and also */ - /* compute Z = the outer product matrix that we'll need. */ - Z11 = 0; - ell = A+i*nskip1; - dee = d; - for (j=i-6; j >= 0; j -= 6) { - p1 = ell[0]; - dd = dee[0]; - q1 = p1*dd; - ell[0] = q1; - m11 = p1*q1; - Z11 += m11; - p1 = ell[1]; - dd = dee[1]; - q1 = p1*dd; - ell[1] = q1; - m11 = p1*q1; - Z11 += m11; - p1 = ell[2]; - dd = dee[2]; - q1 = p1*dd; - ell[2] = q1; - m11 = p1*q1; - Z11 += m11; - p1 = ell[3]; - dd = dee[3]; - q1 = p1*dd; - ell[3] = q1; - m11 = p1*q1; - Z11 += m11; - p1 = ell[4]; - dd = dee[4]; - q1 = p1*dd; - ell[4] = q1; - m11 = p1*q1; - Z11 += m11; - p1 = ell[5]; - dd = dee[5]; - q1 = p1*dd; - ell[5] = q1; - m11 = p1*q1; - Z11 += m11; - ell += 6; - dee += 6; - } - /* compute left-over iterations */ - j += 6; - for (; j > 0; j--) { - p1 = ell[0]; - dd = dee[0]; - q1 = p1*dd; - ell[0] = q1; - m11 = p1*q1; - Z11 += m11; - ell++; - dee++; - } - /* solve for diagonal 1 x 1 block at A(i,i) */ - Z11 = ell[0] - Z11; - dee = d + i; - /* factorize 1 x 1 block Z,dee */ - /* factorize row 1 */ - dee[0] = btRecip(Z11); - /* done factorizing 1 x 1 block */ - break; - - //default: *((char*)0)=0; /* this should never happen! */ - } + for (i = 0; i <= n - 2; i += 2) + { + /* solve L*(D*l)=a, l is scaled elements in 2 x i block at A(i,0) */ + btSolveL1_2(A, A + i * nskip1, i, nskip1); + /* scale the elements in a 2 x i block at A(i,0), and also */ + /* compute Z = the outer product matrix that we'll need. */ + Z11 = 0; + Z21 = 0; + Z22 = 0; + ell = A + i * nskip1; + dee = d; + for (j = i - 6; j >= 0; j -= 6) + { + p1 = ell[0]; + p2 = ell[nskip1]; + dd = dee[0]; + q1 = p1 * dd; + q2 = p2 * dd; + ell[0] = q1; + ell[nskip1] = q2; + m11 = p1 * q1; + m21 = p2 * q1; + m22 = p2 * q2; + Z11 += m11; + Z21 += m21; + Z22 += m22; + p1 = ell[1]; + p2 = ell[1 + nskip1]; + dd = dee[1]; + q1 = p1 * dd; + q2 = p2 * dd; + ell[1] = q1; + ell[1 + nskip1] = q2; + m11 = p1 * q1; + m21 = p2 * q1; + m22 = p2 * q2; + Z11 += m11; + Z21 += m21; + Z22 += m22; + p1 = ell[2]; + p2 = ell[2 + nskip1]; + dd = dee[2]; + q1 = p1 * dd; + q2 = p2 * dd; + ell[2] = q1; + ell[2 + nskip1] = q2; + m11 = p1 * q1; + m21 = p2 * q1; + m22 = p2 * q2; + Z11 += m11; + Z21 += m21; + Z22 += m22; + p1 = ell[3]; + p2 = ell[3 + nskip1]; + dd = dee[3]; + q1 = p1 * dd; + q2 = p2 * dd; + ell[3] = q1; + ell[3 + nskip1] = q2; + m11 = p1 * q1; + m21 = p2 * q1; + m22 = p2 * q2; + Z11 += m11; + Z21 += m21; + Z22 += m22; + p1 = ell[4]; + p2 = ell[4 + nskip1]; + dd = dee[4]; + q1 = p1 * dd; + q2 = p2 * dd; + ell[4] = q1; + ell[4 + nskip1] = q2; + m11 = p1 * q1; + m21 = p2 * q1; + m22 = p2 * q2; + Z11 += m11; + Z21 += m21; + Z22 += m22; + p1 = ell[5]; + p2 = ell[5 + nskip1]; + dd = dee[5]; + q1 = p1 * dd; + q2 = p2 * dd; + ell[5] = q1; + ell[5 + nskip1] = q2; + m11 = p1 * q1; + m21 = p2 * q1; + m22 = p2 * q2; + Z11 += m11; + Z21 += m21; + Z22 += m22; + ell += 6; + dee += 6; + } + /* compute left-over iterations */ + j += 6; + for (; j > 0; j--) + { + p1 = ell[0]; + p2 = ell[nskip1]; + dd = dee[0]; + q1 = p1 * dd; + q2 = p2 * dd; + ell[0] = q1; + ell[nskip1] = q2; + m11 = p1 * q1; + m21 = p2 * q1; + m22 = p2 * q2; + Z11 += m11; + Z21 += m21; + Z22 += m22; + ell++; + dee++; + } + /* solve for diagonal 2 x 2 block at A(i,i) */ + Z11 = ell[0] - Z11; + Z21 = ell[nskip1] - Z21; + Z22 = ell[1 + nskip1] - Z22; + dee = d + i; + /* factorize 2 x 2 block Z,dee */ + /* factorize row 1 */ + dee[0] = btRecip(Z11); + /* factorize row 2 */ + sum = 0; + q1 = Z21; + q2 = q1 * dee[0]; + Z21 = q2; + sum += q1 * q2; + dee[1] = btRecip(Z22 - sum); + /* done factorizing 2 x 2 block */ + ell[nskip1] = Z21; + } + /* compute the (less than 2) rows at the bottom */ + switch (n - i) + { + case 0: + break; + + case 1: + btSolveL1_1(A, A + i * nskip1, i, nskip1); + /* scale the elements in a 1 x i block at A(i,0), and also */ + /* compute Z = the outer product matrix that we'll need. */ + Z11 = 0; + ell = A + i * nskip1; + dee = d; + for (j = i - 6; j >= 0; j -= 6) + { + p1 = ell[0]; + dd = dee[0]; + q1 = p1 * dd; + ell[0] = q1; + m11 = p1 * q1; + Z11 += m11; + p1 = ell[1]; + dd = dee[1]; + q1 = p1 * dd; + ell[1] = q1; + m11 = p1 * q1; + Z11 += m11; + p1 = ell[2]; + dd = dee[2]; + q1 = p1 * dd; + ell[2] = q1; + m11 = p1 * q1; + Z11 += m11; + p1 = ell[3]; + dd = dee[3]; + q1 = p1 * dd; + ell[3] = q1; + m11 = p1 * q1; + Z11 += m11; + p1 = ell[4]; + dd = dee[4]; + q1 = p1 * dd; + ell[4] = q1; + m11 = p1 * q1; + Z11 += m11; + p1 = ell[5]; + dd = dee[5]; + q1 = p1 * dd; + ell[5] = q1; + m11 = p1 * q1; + Z11 += m11; + ell += 6; + dee += 6; + } + /* compute left-over iterations */ + j += 6; + for (; j > 0; j--) + { + p1 = ell[0]; + dd = dee[0]; + q1 = p1 * dd; + ell[0] = q1; + m11 = p1 * q1; + Z11 += m11; + ell++; + dee++; + } + /* solve for diagonal 1 x 1 block at A(i,i) */ + Z11 = ell[0] - Z11; + dee = d + i; + /* factorize 1 x 1 block Z,dee */ + /* factorize row 1 */ + dee[0] = btRecip(Z11); + /* done factorizing 1 x 1 block */ + break; + + //default: *((char*)0)=0; /* this should never happen! */ + } } /* solve L*X=B, with B containing 1 right hand sides. @@ -523,289 +530,295 @@ void btFactorLDLT (btScalar *A, btScalar *d, int n, int nskip1) * if this is in the factorizer source file, n must be a multiple of 4. */ -void btSolveL1 (const btScalar *L, btScalar *B, int n, int lskip1) -{ - /* declare variables - Z matrix, p and q vectors, etc */ - btScalar Z11,Z21,Z31,Z41,p1,q1,p2,p3,p4,*ex; - const btScalar *ell; - int lskip2,lskip3,i,j; - /* compute lskip values */ - lskip2 = 2*lskip1; - lskip3 = 3*lskip1; - /* compute all 4 x 1 blocks of X */ - for (i=0; i <= n-4; i+=4) { - /* compute all 4 x 1 block of X, from rows i..i+4-1 */ - /* set the Z matrix to 0 */ - Z11=0; - Z21=0; - Z31=0; - Z41=0; - ell = L + i*lskip1; - ex = B; - /* the inner loop that computes outer products and adds them to Z */ - for (j=i-12; j >= 0; j -= 12) { - /* load p and q values */ - p1=ell[0]; - q1=ex[0]; - p2=ell[lskip1]; - p3=ell[lskip2]; - p4=ell[lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[1]; - q1=ex[1]; - p2=ell[1+lskip1]; - p3=ell[1+lskip2]; - p4=ell[1+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[2]; - q1=ex[2]; - p2=ell[2+lskip1]; - p3=ell[2+lskip2]; - p4=ell[2+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[3]; - q1=ex[3]; - p2=ell[3+lskip1]; - p3=ell[3+lskip2]; - p4=ell[3+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[4]; - q1=ex[4]; - p2=ell[4+lskip1]; - p3=ell[4+lskip2]; - p4=ell[4+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[5]; - q1=ex[5]; - p2=ell[5+lskip1]; - p3=ell[5+lskip2]; - p4=ell[5+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[6]; - q1=ex[6]; - p2=ell[6+lskip1]; - p3=ell[6+lskip2]; - p4=ell[6+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[7]; - q1=ex[7]; - p2=ell[7+lskip1]; - p3=ell[7+lskip2]; - p4=ell[7+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[8]; - q1=ex[8]; - p2=ell[8+lskip1]; - p3=ell[8+lskip2]; - p4=ell[8+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[9]; - q1=ex[9]; - p2=ell[9+lskip1]; - p3=ell[9+lskip2]; - p4=ell[9+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[10]; - q1=ex[10]; - p2=ell[10+lskip1]; - p3=ell[10+lskip2]; - p4=ell[10+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* load p and q values */ - p1=ell[11]; - q1=ex[11]; - p2=ell[11+lskip1]; - p3=ell[11+lskip2]; - p4=ell[11+lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* advance pointers */ - ell += 12; - ex += 12; - /* end of inner loop */ - } - /* compute left-over iterations */ - j += 12; - for (; j > 0; j--) { - /* load p and q values */ - p1=ell[0]; - q1=ex[0]; - p2=ell[lskip1]; - p3=ell[lskip2]; - p4=ell[lskip3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - Z21 += p2 * q1; - Z31 += p3 * q1; - Z41 += p4 * q1; - /* advance pointers */ - ell += 1; - ex += 1; - } - /* finish computing the X(i) block */ - Z11 = ex[0] - Z11; - ex[0] = Z11; - p1 = ell[lskip1]; - Z21 = ex[1] - Z21 - p1*Z11; - ex[1] = Z21; - p1 = ell[lskip2]; - p2 = ell[1+lskip2]; - Z31 = ex[2] - Z31 - p1*Z11 - p2*Z21; - ex[2] = Z31; - p1 = ell[lskip3]; - p2 = ell[1+lskip3]; - p3 = ell[2+lskip3]; - Z41 = ex[3] - Z41 - p1*Z11 - p2*Z21 - p3*Z31; - ex[3] = Z41; - /* end of outer loop */ - } - /* compute rows at end that are not a multiple of block size */ - for (; i < n; i++) { - /* compute all 1 x 1 block of X, from rows i..i+1-1 */ - /* set the Z matrix to 0 */ - Z11=0; - ell = L + i*lskip1; - ex = B; - /* the inner loop that computes outer products and adds them to Z */ - for (j=i-12; j >= 0; j -= 12) { - /* load p and q values */ - p1=ell[0]; - q1=ex[0]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[1]; - q1=ex[1]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[2]; - q1=ex[2]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[3]; - q1=ex[3]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[4]; - q1=ex[4]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[5]; - q1=ex[5]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[6]; - q1=ex[6]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[7]; - q1=ex[7]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[8]; - q1=ex[8]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[9]; - q1=ex[9]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[10]; - q1=ex[10]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* load p and q values */ - p1=ell[11]; - q1=ex[11]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* advance pointers */ - ell += 12; - ex += 12; - /* end of inner loop */ - } - /* compute left-over iterations */ - j += 12; - for (; j > 0; j--) { - /* load p and q values */ - p1=ell[0]; - q1=ex[0]; - /* compute outer product and add it to the Z matrix */ - Z11 += p1 * q1; - /* advance pointers */ - ell += 1; - ex += 1; - } - /* finish computing the X(i) block */ - Z11 = ex[0] - Z11; - ex[0] = Z11; - } +void btSolveL1(const btScalar *L, btScalar *B, int n, int lskip1) +{ + /* declare variables - Z matrix, p and q vectors, etc */ + btScalar Z11, Z21, Z31, Z41, p1, q1, p2, p3, p4, *ex; + const btScalar *ell; + int lskip2, lskip3, i, j; + /* compute lskip values */ + lskip2 = 2 * lskip1; + lskip3 = 3 * lskip1; + /* compute all 4 x 1 blocks of X */ + for (i = 0; i <= n - 4; i += 4) + { + /* compute all 4 x 1 block of X, from rows i..i+4-1 */ + /* set the Z matrix to 0 */ + Z11 = 0; + Z21 = 0; + Z31 = 0; + Z41 = 0; + ell = L + i * lskip1; + ex = B; + /* the inner loop that computes outer products and adds them to Z */ + for (j = i - 12; j >= 0; j -= 12) + { + /* load p and q values */ + p1 = ell[0]; + q1 = ex[0]; + p2 = ell[lskip1]; + p3 = ell[lskip2]; + p4 = ell[lskip3]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z21 += p2 * q1; + Z31 += p3 * q1; + Z41 += p4 * q1; + /* load p and q values */ + p1 = ell[1]; + q1 = ex[1]; + p2 = ell[1 + lskip1]; + p3 = ell[1 + lskip2]; + p4 = ell[1 + lskip3]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z21 += p2 * q1; + Z31 += p3 * q1; + Z41 += p4 * q1; + /* load p and q values */ + p1 = ell[2]; + q1 = ex[2]; + p2 = ell[2 + lskip1]; + p3 = ell[2 + lskip2]; + p4 = ell[2 + lskip3]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z21 += p2 * q1; + Z31 += p3 * q1; + Z41 += p4 * q1; + /* load p and q values */ + p1 = ell[3]; + q1 = ex[3]; + p2 = ell[3 + lskip1]; + p3 = ell[3 + lskip2]; + p4 = ell[3 + lskip3]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z21 += p2 * q1; + Z31 += p3 * q1; + Z41 += p4 * q1; + /* load p and q values */ + p1 = ell[4]; + q1 = ex[4]; + p2 = ell[4 + lskip1]; + p3 = ell[4 + lskip2]; + p4 = ell[4 + lskip3]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z21 += p2 * q1; + Z31 += p3 * q1; + Z41 += p4 * q1; + /* load p and q values */ + p1 = ell[5]; + q1 = ex[5]; + p2 = ell[5 + lskip1]; + p3 = ell[5 + lskip2]; + p4 = ell[5 + lskip3]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z21 += p2 * q1; + Z31 += p3 * q1; + Z41 += p4 * q1; + /* load p and q values */ + p1 = ell[6]; + q1 = ex[6]; + p2 = ell[6 + lskip1]; + p3 = ell[6 + lskip2]; + p4 = ell[6 + lskip3]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z21 += p2 * q1; + Z31 += p3 * q1; + Z41 += p4 * q1; + /* load p and q values */ + p1 = ell[7]; + q1 = ex[7]; + p2 = ell[7 + lskip1]; + p3 = ell[7 + lskip2]; + p4 = ell[7 + lskip3]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z21 += p2 * q1; + Z31 += p3 * q1; + Z41 += p4 * q1; + /* load p and q values */ + p1 = ell[8]; + q1 = ex[8]; + p2 = ell[8 + lskip1]; + p3 = ell[8 + lskip2]; + p4 = ell[8 + lskip3]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z21 += p2 * q1; + Z31 += p3 * q1; + Z41 += p4 * q1; + /* load p and q values */ + p1 = ell[9]; + q1 = ex[9]; + p2 = ell[9 + lskip1]; + p3 = ell[9 + lskip2]; + p4 = ell[9 + lskip3]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z21 += p2 * q1; + Z31 += p3 * q1; + Z41 += p4 * q1; + /* load p and q values */ + p1 = ell[10]; + q1 = ex[10]; + p2 = ell[10 + lskip1]; + p3 = ell[10 + lskip2]; + p4 = ell[10 + lskip3]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z21 += p2 * q1; + Z31 += p3 * q1; + Z41 += p4 * q1; + /* load p and q values */ + p1 = ell[11]; + q1 = ex[11]; + p2 = ell[11 + lskip1]; + p3 = ell[11 + lskip2]; + p4 = ell[11 + lskip3]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z21 += p2 * q1; + Z31 += p3 * q1; + Z41 += p4 * q1; + /* advance pointers */ + ell += 12; + ex += 12; + /* end of inner loop */ + } + /* compute left-over iterations */ + j += 12; + for (; j > 0; j--) + { + /* load p and q values */ + p1 = ell[0]; + q1 = ex[0]; + p2 = ell[lskip1]; + p3 = ell[lskip2]; + p4 = ell[lskip3]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + Z21 += p2 * q1; + Z31 += p3 * q1; + Z41 += p4 * q1; + /* advance pointers */ + ell += 1; + ex += 1; + } + /* finish computing the X(i) block */ + Z11 = ex[0] - Z11; + ex[0] = Z11; + p1 = ell[lskip1]; + Z21 = ex[1] - Z21 - p1 * Z11; + ex[1] = Z21; + p1 = ell[lskip2]; + p2 = ell[1 + lskip2]; + Z31 = ex[2] - Z31 - p1 * Z11 - p2 * Z21; + ex[2] = Z31; + p1 = ell[lskip3]; + p2 = ell[1 + lskip3]; + p3 = ell[2 + lskip3]; + Z41 = ex[3] - Z41 - p1 * Z11 - p2 * Z21 - p3 * Z31; + ex[3] = Z41; + /* end of outer loop */ + } + /* compute rows at end that are not a multiple of block size */ + for (; i < n; i++) + { + /* compute all 1 x 1 block of X, from rows i..i+1-1 */ + /* set the Z matrix to 0 */ + Z11 = 0; + ell = L + i * lskip1; + ex = B; + /* the inner loop that computes outer products and adds them to Z */ + for (j = i - 12; j >= 0; j -= 12) + { + /* load p and q values */ + p1 = ell[0]; + q1 = ex[0]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + /* load p and q values */ + p1 = ell[1]; + q1 = ex[1]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + /* load p and q values */ + p1 = ell[2]; + q1 = ex[2]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + /* load p and q values */ + p1 = ell[3]; + q1 = ex[3]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + /* load p and q values */ + p1 = ell[4]; + q1 = ex[4]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + /* load p and q values */ + p1 = ell[5]; + q1 = ex[5]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + /* load p and q values */ + p1 = ell[6]; + q1 = ex[6]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + /* load p and q values */ + p1 = ell[7]; + q1 = ex[7]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + /* load p and q values */ + p1 = ell[8]; + q1 = ex[8]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + /* load p and q values */ + p1 = ell[9]; + q1 = ex[9]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + /* load p and q values */ + p1 = ell[10]; + q1 = ex[10]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + /* load p and q values */ + p1 = ell[11]; + q1 = ex[11]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + /* advance pointers */ + ell += 12; + ex += 12; + /* end of inner loop */ + } + /* compute left-over iterations */ + j += 12; + for (; j > 0; j--) + { + /* load p and q values */ + p1 = ell[0]; + q1 = ex[0]; + /* compute outer product and add it to the Z matrix */ + Z11 += p1 * q1; + /* advance pointers */ + ell += 1; + ex += 1; + } + /* finish computing the X(i) block */ + Z11 = ex[0] - Z11; + ex[0] = Z11; + } } /* solve L^T * x=b, with b containing 1 right hand side. @@ -816,214 +829,217 @@ void btSolveL1 (const btScalar *L, btScalar *B, int n, int lskip1) * this processes blocks of 4. */ -void btSolveL1T (const btScalar *L, btScalar *B, int n, int lskip1) -{ - /* declare variables - Z matrix, p and q vectors, etc */ - btScalar Z11,m11,Z21,m21,Z31,m31,Z41,m41,p1,q1,p2,p3,p4,*ex; - const btScalar *ell; - int lskip2,i,j; -// int lskip3; - /* special handling for L and B because we're solving L1 *transpose* */ - L = L + (n-1)*(lskip1+1); - B = B + n-1; - lskip1 = -lskip1; - /* compute lskip values */ - lskip2 = 2*lskip1; - //lskip3 = 3*lskip1; - /* compute all 4 x 1 blocks of X */ - for (i=0; i <= n-4; i+=4) { - /* compute all 4 x 1 block of X, from rows i..i+4-1 */ - /* set the Z matrix to 0 */ - Z11=0; - Z21=0; - Z31=0; - Z41=0; - ell = L - i; - ex = B; - /* the inner loop that computes outer products and adds them to Z */ - for (j=i-4; j >= 0; j -= 4) { - /* load p and q values */ - p1=ell[0]; - q1=ex[0]; - p2=ell[-1]; - p3=ell[-2]; - p4=ell[-3]; - /* compute outer product and add it to the Z matrix */ - m11 = p1 * q1; - m21 = p2 * q1; - m31 = p3 * q1; - m41 = p4 * q1; - ell += lskip1; - Z11 += m11; - Z21 += m21; - Z31 += m31; - Z41 += m41; - /* load p and q values */ - p1=ell[0]; - q1=ex[-1]; - p2=ell[-1]; - p3=ell[-2]; - p4=ell[-3]; - /* compute outer product and add it to the Z matrix */ - m11 = p1 * q1; - m21 = p2 * q1; - m31 = p3 * q1; - m41 = p4 * q1; - ell += lskip1; - Z11 += m11; - Z21 += m21; - Z31 += m31; - Z41 += m41; - /* load p and q values */ - p1=ell[0]; - q1=ex[-2]; - p2=ell[-1]; - p3=ell[-2]; - p4=ell[-3]; - /* compute outer product and add it to the Z matrix */ - m11 = p1 * q1; - m21 = p2 * q1; - m31 = p3 * q1; - m41 = p4 * q1; - ell += lskip1; - Z11 += m11; - Z21 += m21; - Z31 += m31; - Z41 += m41; - /* load p and q values */ - p1=ell[0]; - q1=ex[-3]; - p2=ell[-1]; - p3=ell[-2]; - p4=ell[-3]; - /* compute outer product and add it to the Z matrix */ - m11 = p1 * q1; - m21 = p2 * q1; - m31 = p3 * q1; - m41 = p4 * q1; - ell += lskip1; - ex -= 4; - Z11 += m11; - Z21 += m21; - Z31 += m31; - Z41 += m41; - /* end of inner loop */ - } - /* compute left-over iterations */ - j += 4; - for (; j > 0; j--) { - /* load p and q values */ - p1=ell[0]; - q1=ex[0]; - p2=ell[-1]; - p3=ell[-2]; - p4=ell[-3]; - /* compute outer product and add it to the Z matrix */ - m11 = p1 * q1; - m21 = p2 * q1; - m31 = p3 * q1; - m41 = p4 * q1; - ell += lskip1; - ex -= 1; - Z11 += m11; - Z21 += m21; - Z31 += m31; - Z41 += m41; - } - /* finish computing the X(i) block */ - Z11 = ex[0] - Z11; - ex[0] = Z11; - p1 = ell[-1]; - Z21 = ex[-1] - Z21 - p1*Z11; - ex[-1] = Z21; - p1 = ell[-2]; - p2 = ell[-2+lskip1]; - Z31 = ex[-2] - Z31 - p1*Z11 - p2*Z21; - ex[-2] = Z31; - p1 = ell[-3]; - p2 = ell[-3+lskip1]; - p3 = ell[-3+lskip2]; - Z41 = ex[-3] - Z41 - p1*Z11 - p2*Z21 - p3*Z31; - ex[-3] = Z41; - /* end of outer loop */ - } - /* compute rows at end that are not a multiple of block size */ - for (; i < n; i++) { - /* compute all 1 x 1 block of X, from rows i..i+1-1 */ - /* set the Z matrix to 0 */ - Z11=0; - ell = L - i; - ex = B; - /* the inner loop that computes outer products and adds them to Z */ - for (j=i-4; j >= 0; j -= 4) { - /* load p and q values */ - p1=ell[0]; - q1=ex[0]; - /* compute outer product and add it to the Z matrix */ - m11 = p1 * q1; - ell += lskip1; - Z11 += m11; - /* load p and q values */ - p1=ell[0]; - q1=ex[-1]; - /* compute outer product and add it to the Z matrix */ - m11 = p1 * q1; - ell += lskip1; - Z11 += m11; - /* load p and q values */ - p1=ell[0]; - q1=ex[-2]; - /* compute outer product and add it to the Z matrix */ - m11 = p1 * q1; - ell += lskip1; - Z11 += m11; - /* load p and q values */ - p1=ell[0]; - q1=ex[-3]; - /* compute outer product and add it to the Z matrix */ - m11 = p1 * q1; - ell += lskip1; - ex -= 4; - Z11 += m11; - /* end of inner loop */ - } - /* compute left-over iterations */ - j += 4; - for (; j > 0; j--) { - /* load p and q values */ - p1=ell[0]; - q1=ex[0]; - /* compute outer product and add it to the Z matrix */ - m11 = p1 * q1; - ell += lskip1; - ex -= 1; - Z11 += m11; - } - /* finish computing the X(i) block */ - Z11 = ex[0] - Z11; - ex[0] = Z11; - } -} - - - -void btVectorScale (btScalar *a, const btScalar *d, int n) +void btSolveL1T(const btScalar *L, btScalar *B, int n, int lskip1) { - btAssert (a && d && n >= 0); - for (int i=0; i= 0; j -= 4) + { + /* load p and q values */ + p1 = ell[0]; + q1 = ex[0]; + p2 = ell[-1]; + p3 = ell[-2]; + p4 = ell[-3]; + /* compute outer product and add it to the Z matrix */ + m11 = p1 * q1; + m21 = p2 * q1; + m31 = p3 * q1; + m41 = p4 * q1; + ell += lskip1; + Z11 += m11; + Z21 += m21; + Z31 += m31; + Z41 += m41; + /* load p and q values */ + p1 = ell[0]; + q1 = ex[-1]; + p2 = ell[-1]; + p3 = ell[-2]; + p4 = ell[-3]; + /* compute outer product and add it to the Z matrix */ + m11 = p1 * q1; + m21 = p2 * q1; + m31 = p3 * q1; + m41 = p4 * q1; + ell += lskip1; + Z11 += m11; + Z21 += m21; + Z31 += m31; + Z41 += m41; + /* load p and q values */ + p1 = ell[0]; + q1 = ex[-2]; + p2 = ell[-1]; + p3 = ell[-2]; + p4 = ell[-3]; + /* compute outer product and add it to the Z matrix */ + m11 = p1 * q1; + m21 = p2 * q1; + m31 = p3 * q1; + m41 = p4 * q1; + ell += lskip1; + Z11 += m11; + Z21 += m21; + Z31 += m31; + Z41 += m41; + /* load p and q values */ + p1 = ell[0]; + q1 = ex[-3]; + p2 = ell[-1]; + p3 = ell[-2]; + p4 = ell[-3]; + /* compute outer product and add it to the Z matrix */ + m11 = p1 * q1; + m21 = p2 * q1; + m31 = p3 * q1; + m41 = p4 * q1; + ell += lskip1; + ex -= 4; + Z11 += m11; + Z21 += m21; + Z31 += m31; + Z41 += m41; + /* end of inner loop */ + } + /* compute left-over iterations */ + j += 4; + for (; j > 0; j--) + { + /* load p and q values */ + p1 = ell[0]; + q1 = ex[0]; + p2 = ell[-1]; + p3 = ell[-2]; + p4 = ell[-3]; + /* compute outer product and add it to the Z matrix */ + m11 = p1 * q1; + m21 = p2 * q1; + m31 = p3 * q1; + m41 = p4 * q1; + ell += lskip1; + ex -= 1; + Z11 += m11; + Z21 += m21; + Z31 += m31; + Z41 += m41; + } + /* finish computing the X(i) block */ + Z11 = ex[0] - Z11; + ex[0] = Z11; + p1 = ell[-1]; + Z21 = ex[-1] - Z21 - p1 * Z11; + ex[-1] = Z21; + p1 = ell[-2]; + p2 = ell[-2 + lskip1]; + Z31 = ex[-2] - Z31 - p1 * Z11 - p2 * Z21; + ex[-2] = Z31; + p1 = ell[-3]; + p2 = ell[-3 + lskip1]; + p3 = ell[-3 + lskip2]; + Z41 = ex[-3] - Z41 - p1 * Z11 - p2 * Z21 - p3 * Z31; + ex[-3] = Z41; + /* end of outer loop */ + } + /* compute rows at end that are not a multiple of block size */ + for (; i < n; i++) + { + /* compute all 1 x 1 block of X, from rows i..i+1-1 */ + /* set the Z matrix to 0 */ + Z11 = 0; + ell = L - i; + ex = B; + /* the inner loop that computes outer products and adds them to Z */ + for (j = i - 4; j >= 0; j -= 4) + { + /* load p and q values */ + p1 = ell[0]; + q1 = ex[0]; + /* compute outer product and add it to the Z matrix */ + m11 = p1 * q1; + ell += lskip1; + Z11 += m11; + /* load p and q values */ + p1 = ell[0]; + q1 = ex[-1]; + /* compute outer product and add it to the Z matrix */ + m11 = p1 * q1; + ell += lskip1; + Z11 += m11; + /* load p and q values */ + p1 = ell[0]; + q1 = ex[-2]; + /* compute outer product and add it to the Z matrix */ + m11 = p1 * q1; + ell += lskip1; + Z11 += m11; + /* load p and q values */ + p1 = ell[0]; + q1 = ex[-3]; + /* compute outer product and add it to the Z matrix */ + m11 = p1 * q1; + ell += lskip1; + ex -= 4; + Z11 += m11; + /* end of inner loop */ + } + /* compute left-over iterations */ + j += 4; + for (; j > 0; j--) + { + /* load p and q values */ + p1 = ell[0]; + q1 = ex[0]; + /* compute outer product and add it to the Z matrix */ + m11 = p1 * q1; + ell += lskip1; + ex -= 1; + Z11 += m11; + } + /* finish computing the X(i) block */ + Z11 = ex[0] - Z11; + ex[0] = Z11; + } } -void btSolveLDLT (const btScalar *L, const btScalar *d, btScalar *b, int n, int nskip) +void btVectorScale(btScalar *a, const btScalar *d, int n) { - btAssert (L && d && b && n > 0 && nskip >= n); - btSolveL1 (L,b,n,nskip); - btVectorScale (b,d,n); - btSolveL1T (L,b,n,nskip); + btAssert(a && d && n >= 0); + for (int i = 0; i < n; i++) + { + a[i] *= d[i]; + } } - +void btSolveLDLT(const btScalar *L, const btScalar *d, btScalar *b, int n, int nskip) +{ + btAssert(L && d && b && n > 0 && nskip >= n); + btSolveL1(L, b, n, nskip); + btVectorScale(b, d, n); + btSolveL1T(L, b, n, nskip); +} //*************************************************************************** @@ -1033,125 +1049,130 @@ void btSolveLDLT (const btScalar *L, const btScalar *d, btScalar *b, int n, int // rows will be swapped by exchanging row pointers. otherwise the data will // be copied. -static void btSwapRowsAndCols (BTATYPE A, int n, int i1, int i2, int nskip, - int do_fast_row_swaps) +static void btSwapRowsAndCols(BTATYPE A, int n, int i1, int i2, int nskip, + int do_fast_row_swaps) { - btAssert (A && n > 0 && i1 >= 0 && i2 >= 0 && i1 < n && i2 < n && - nskip >= n && i1 < i2); + btAssert(A && n > 0 && i1 >= 0 && i2 >= 0 && i1 < n && i2 < n && + nskip >= n && i1 < i2); -# ifdef BTROWPTRS - btScalar *A_i1 = A[i1]; - btScalar *A_i2 = A[i2]; - for (int i=i1+1; i0 && i1 >=0 && i2 >= 0 && i1 < n && i2 < n && nskip >= n && i1 <= i2); - if (i1==i2) return; - - btSwapRowsAndCols (A,n,i1,i2,nskip,do_fast_row_swaps); - - tmpr = x[i1]; - x[i1] = x[i2]; - x[i2] = tmpr; - - tmpr = b[i1]; - b[i1] = b[i2]; - b[i2] = tmpr; - - tmpr = w[i1]; - w[i1] = w[i2]; - w[i2] = tmpr; - - tmpr = lo[i1]; - lo[i1] = lo[i2]; - lo[i2] = tmpr; + btScalar tmpr; + int tmpi; + bool tmpb; + btAssert(n > 0 && i1 >= 0 && i2 >= 0 && i1 < n && i2 < n && nskip >= n && i1 <= i2); + if (i1 == i2) return; - tmpr = hi[i1]; - hi[i1] = hi[i2]; - hi[i2] = tmpr; + btSwapRowsAndCols(A, n, i1, i2, nskip, do_fast_row_swaps); - tmpi = p[i1]; - p[i1] = p[i2]; - p[i2] = tmpi; + tmpr = x[i1]; + x[i1] = x[i2]; + x[i2] = tmpr; - tmpb = state[i1]; - state[i1] = state[i2]; - state[i2] = tmpb; + tmpr = b[i1]; + b[i1] = b[i2]; + b[i2] = tmpr; - if (findex) { - tmpi = findex[i1]; - findex[i1] = findex[i2]; - findex[i2] = tmpi; - } + tmpr = w[i1]; + w[i1] = w[i2]; + w[i2] = tmpr; + + tmpr = lo[i1]; + lo[i1] = lo[i2]; + lo[i2] = tmpr; + + tmpr = hi[i1]; + hi[i1] = hi[i2]; + hi[i2] = tmpr; + + tmpi = p[i1]; + p[i1] = p[i2]; + p[i2] = tmpi; + + tmpb = state[i1]; + state[i1] = state[i2]; + state[i2] = tmpb; + + if (findex) + { + tmpi = findex[i1]; + findex[i1] = findex[i2]; + findex[i2] = tmpi; + } } - - - //*************************************************************************** // btLCP manipulator object. this represents an n*n LCP problem. // @@ -1186,79 +1207,88 @@ static void btSwapProblem (BTATYPE A, btScalar *x, btScalar *b, btScalar *w, btS #ifdef btLCP_FAST -struct btLCP +struct btLCP { const int m_n; const int m_nskip; int m_nub; - int m_nC, m_nN; // size of each index set - BTATYPE const m_A; // A rows - btScalar *const m_x, * const m_b, *const m_w, *const m_lo,* const m_hi; // permuted LCP problem data - btScalar *const m_L, *const m_d; // L*D*L' factorization of set C + int m_nC, m_nN; // size of each index set + BTATYPE const m_A; // A rows + btScalar *const m_x, *const m_b, *const m_w, *const m_lo, *const m_hi; // permuted LCP problem data + btScalar *const m_L, *const m_d; // L*D*L' factorization of set C btScalar *const m_Dell, *const m_ell, *const m_tmp; bool *const m_state; int *const m_findex, *const m_p, *const m_C; - btLCP (int _n, int _nskip, int _nub, btScalar *_Adata, btScalar *_x, btScalar *_b, btScalar *_w, - btScalar *_lo, btScalar *_hi, btScalar *l, btScalar *_d, - btScalar *_Dell, btScalar *_ell, btScalar *_tmp, - bool *_state, int *_findex, int *p, int *c, btScalar **Arows); + btLCP(int _n, int _nskip, int _nub, btScalar *_Adata, btScalar *_x, btScalar *_b, btScalar *_w, + btScalar *_lo, btScalar *_hi, btScalar *l, btScalar *_d, + btScalar *_Dell, btScalar *_ell, btScalar *_tmp, + bool *_state, int *_findex, int *p, int *c, btScalar **Arows); int getNub() const { return m_nub; } - void transfer_i_to_C (int i); - void transfer_i_to_N (int i) { m_nN++; } // because we can assume C and N span 1:i-1 - void transfer_i_from_N_to_C (int i); - void transfer_i_from_C_to_N (int i, btAlignedObjectArray& scratch); + void transfer_i_to_C(int i); + void transfer_i_to_N(int i) { m_nN++; } // because we can assume C and N span 1:i-1 + void transfer_i_from_N_to_C(int i); + void transfer_i_from_C_to_N(int i, btAlignedObjectArray &scratch); int numC() const { return m_nC; } int numN() const { return m_nN; } - int indexC (int i) const { return i; } - int indexN (int i) const { return i+m_nC; } - btScalar Aii (int i) const { return BTAROW(i)[i]; } - btScalar AiC_times_qC (int i, btScalar *q) const { return btLargeDot (BTAROW(i), q, m_nC); } - btScalar AiN_times_qN (int i, btScalar *q) const { return btLargeDot (BTAROW(i)+m_nC, q+m_nC, m_nN); } - void pN_equals_ANC_times_qC (btScalar *p, btScalar *q); - void pN_plusequals_ANi (btScalar *p, int i, int sign=1); - void pC_plusequals_s_times_qC (btScalar *p, btScalar s, btScalar *q); - void pN_plusequals_s_times_qN (btScalar *p, btScalar s, btScalar *q); - void solve1 (btScalar *a, int i, int dir=1, int only_transfer=0); + int indexC(int i) const { return i; } + int indexN(int i) const { return i + m_nC; } + btScalar Aii(int i) const { return BTAROW(i)[i]; } + btScalar AiC_times_qC(int i, btScalar *q) const { return btLargeDot(BTAROW(i), q, m_nC); } + btScalar AiN_times_qN(int i, btScalar *q) const { return btLargeDot(BTAROW(i) + m_nC, q + m_nC, m_nN); } + void pN_equals_ANC_times_qC(btScalar *p, btScalar *q); + void pN_plusequals_ANi(btScalar *p, int i, int sign = 1); + void pC_plusequals_s_times_qC(btScalar *p, btScalar s, btScalar *q); + void pN_plusequals_s_times_qN(btScalar *p, btScalar s, btScalar *q); + void solve1(btScalar *a, int i, int dir = 1, int only_transfer = 0); void unpermute(); }; - -btLCP::btLCP (int _n, int _nskip, int _nub, btScalar *_Adata, btScalar *_x, btScalar *_b, btScalar *_w, - btScalar *_lo, btScalar *_hi, btScalar *l, btScalar *_d, - btScalar *_Dell, btScalar *_ell, btScalar *_tmp, - bool *_state, int *_findex, int *p, int *c, btScalar **Arows): - m_n(_n), m_nskip(_nskip), m_nub(_nub), m_nC(0), m_nN(0), -# ifdef BTROWPTRS - m_A(Arows), +btLCP::btLCP(int _n, int _nskip, int _nub, btScalar *_Adata, btScalar *_x, btScalar *_b, btScalar *_w, + btScalar *_lo, btScalar *_hi, btScalar *l, btScalar *_d, + btScalar *_Dell, btScalar *_ell, btScalar *_tmp, + bool *_state, int *_findex, int *p, int *c, btScalar **Arows) : m_n(_n), m_nskip(_nskip), m_nub(_nub), m_nC(0), m_nN(0), +#ifdef BTROWPTRS + m_A(Arows), #else - m_A(_Adata), + m_A(_Adata), #endif - m_x(_x), m_b(_b), m_w(_w), m_lo(_lo), m_hi(_hi), - m_L(l), m_d(_d), m_Dell(_Dell), m_ell(_ell), m_tmp(_tmp), - m_state(_state), m_findex(_findex), m_p(p), m_C(c) + m_x(_x), + m_b(_b), + m_w(_w), + m_lo(_lo), + m_hi(_hi), + m_L(l), + m_d(_d), + m_Dell(_Dell), + m_ell(_ell), + m_tmp(_tmp), + m_state(_state), + m_findex(_findex), + m_p(p), + m_C(c) { - { - btSetZero (m_x,m_n); - } + { + btSetZero(m_x, m_n); + } - { -# ifdef BTROWPTRS - // make matrix row pointers - btScalar *aptr = _Adata; - BTATYPE A = m_A; - const int n = m_n, nskip = m_nskip; - for (int k=0; k nub { const int n = m_n; @@ -1277,63 +1307,69 @@ btLCP::btLCP (int _n, int _nskip, int _nub, btScalar *_Adata, btScalar *_x, btSc } */ - // permute the problem so that *all* the unbounded variables are at the - // start, i.e. look for unbounded variables not included in `nub'. we can - // potentially push up `nub' this way and get a bigger initial factorization. - // note that when we swap rows/cols here we must not just swap row pointers, - // as the initial factorization relies on the data being all in one chunk. - // variables that have findex >= 0 are *not* considered to be unbounded even - // if lo=-inf and hi=inf - this is because these limits may change during the - // solution process. + // permute the problem so that *all* the unbounded variables are at the + // start, i.e. look for unbounded variables not included in `nub'. we can + // potentially push up `nub' this way and get a bigger initial factorization. + // note that when we swap rows/cols here we must not just swap row pointers, + // as the initial factorization relies on the data being all in one chunk. + // variables that have findex >= 0 are *not* considered to be unbounded even + // if lo=-inf and hi=inf - this is because these limits may change during the + // solution process. - { - int *findex = m_findex; - btScalar *lo = m_lo, *hi = m_hi; - const int n = m_n; - for (int k = m_nub; k= 0) continue; - if (lo[k]==-BT_INFINITY && hi[k]==BT_INFINITY) { - btSwapProblem (m_A,m_x,m_b,m_w,lo,hi,m_p,m_state,findex,n,m_nub,k,m_nskip,0); - m_nub++; - } - } - } + { + int *findex = m_findex; + btScalar *lo = m_lo, *hi = m_hi; + const int n = m_n; + for (int k = m_nub; k < n; ++k) + { + if (findex && findex[k] >= 0) continue; + if (lo[k] == -BT_INFINITY && hi[k] == BT_INFINITY) + { + btSwapProblem(m_A, m_x, m_b, m_w, lo, hi, m_p, m_state, findex, n, m_nub, k, m_nskip, 0); + m_nub++; + } + } + } - // if there are unbounded variables at the start, factorize A up to that - // point and solve for x. this puts all indexes 0..nub-1 into C. - if (m_nub > 0) { - const int nub = m_nub; - { - btScalar *Lrow = m_L; - const int nskip = m_nskip; - for (int j=0; j 0) + { + const int nub = m_nub; + { + btScalar *Lrow = m_L; + const int nskip = m_nskip; + for (int j = 0; j < nub; Lrow += nskip, ++j) memcpy(Lrow, BTAROW(j), (j + 1) * sizeof(btScalar)); + } + btFactorLDLT(m_L, m_d, nub, m_nskip); + memcpy(m_x, m_b, nub * sizeof(btScalar)); + btSolveLDLT(m_L, m_d, m_x, nub, m_nskip); + btSetZero(m_w, nub); + { + int *C = m_C; + for (int k = 0; k < nub; ++k) C[k] = k; + } + m_nC = nub; + } - // permute the indexes > nub such that all findex variables are at the end - if (m_findex) { - const int nub = m_nub; - int *findex = m_findex; - int num_at_end = 0; - for (int k=m_n-1; k >= nub; k--) { - if (findex[k] >= 0) { - btSwapProblem (m_A,m_x,m_b,m_w,m_lo,m_hi,m_p,m_state,findex,m_n,k,m_n-1-num_at_end,m_nskip,1); - num_at_end++; - } - } - } + // permute the indexes > nub such that all findex variables are at the end + if (m_findex) + { + const int nub = m_nub; + int *findex = m_findex; + int num_at_end = 0; + for (int k = m_n - 1; k >= nub; k--) + { + if (findex[k] >= 0) + { + btSwapProblem(m_A, m_x, m_b, m_w, m_lo, m_hi, m_p, m_state, findex, m_n, k, m_n - 1 - num_at_end, m_nskip, 1); + num_at_end++; + } + } + } - // print info about indexes - /* + // print info about indexes + /* { const int n = m_n; const int nub = m_nub; @@ -1347,734 +1383,776 @@ btLCP::btLCP (int _n, int _nskip, int _nub, btScalar *_Adata, btScalar *_x, btSc */ } - -void btLCP::transfer_i_to_C (int i) +void btLCP::transfer_i_to_C(int i) { - { - if (m_nC > 0) { - // ell,Dell were computed by solve1(). note, ell = D \ L1solve (L,A(i,C)) - { - const int nC = m_nC; - btScalar *const Ltgt = m_L + nC*m_nskip, *ell = m_ell; - for (int j=0; j 0) + { + // ell,Dell were computed by solve1(). note, ell = D \ L1solve (L,A(i,C)) + { + const int nC = m_nC; + btScalar *const Ltgt = m_L + nC * m_nskip, *ell = m_ell; + for (int j = 0; j < nC; ++j) Ltgt[j] = ell[j]; + } + const int nC = m_nC; + m_d[nC] = btRecip(BTAROW(i)[i] - btLargeDot(m_ell, m_Dell, nC)); + } + else + { + m_d[0] = btRecip(BTAROW(i)[i]); + } - btSwapProblem (m_A,m_x,m_b,m_w,m_lo,m_hi,m_p,m_state,m_findex,m_n,m_nC,i,m_nskip,1); - - const int nC = m_nC; - m_C[nC] = nC; - m_nC = nC + 1; // nC value is outdated after this line - } + btSwapProblem(m_A, m_x, m_b, m_w, m_lo, m_hi, m_p, m_state, m_findex, m_n, m_nC, i, m_nskip, 1); + const int nC = m_nC; + m_C[nC] = nC; + m_nC = nC + 1; // nC value is outdated after this line + } } - -void btLCP::transfer_i_from_N_to_C (int i) +void btLCP::transfer_i_from_N_to_C(int i) { - { - if (m_nC > 0) { - { - btScalar *const aptr = BTAROW(i); - btScalar *Dell = m_Dell; - const int *C = m_C; -# ifdef BTNUB_OPTIMIZATIONS - // if nub>0, initial part of aptr unpermuted - const int nub = m_nub; - int j=0; - for ( ; j 0) + { + { + btScalar *const aptr = BTAROW(i); + btScalar *Dell = m_Dell; + const int *C = m_C; +#ifdef BTNUB_OPTIMIZATIONS + // if nub>0, initial part of aptr unpermuted + const int nub = m_nub; + int j = 0; + for (; j < nub; ++j) Dell[j] = aptr[j]; + const int nC = m_nC; + for (; j < nC; ++j) Dell[j] = aptr[C[j]]; +#else + const int nC = m_nC; + for (int j = 0; j < nC; ++j) Dell[j] = aptr[C[j]]; +#endif + } + btSolveL1(m_L, m_Dell, m_nC, m_nskip); + { + const int nC = m_nC; + btScalar *const Ltgt = m_L + nC * m_nskip; + btScalar *ell = m_ell, *Dell = m_Dell, *d = m_d; + for (int j = 0; j < nC; ++j) Ltgt[j] = ell[j] = Dell[j] * d[j]; + } + const int nC = m_nC; + m_d[nC] = btRecip(BTAROW(i)[i] - btLargeDot(m_ell, m_Dell, nC)); + } + else + { + m_d[0] = btRecip(BTAROW(i)[i]); + } - btSwapProblem (m_A,m_x,m_b,m_w,m_lo,m_hi,m_p,m_state,m_findex,m_n,m_nC,i,m_nskip,1); + btSwapProblem(m_A, m_x, m_b, m_w, m_lo, m_hi, m_p, m_state, m_findex, m_n, m_nC, i, m_nskip, 1); - const int nC = m_nC; - m_C[nC] = nC; - m_nN--; - m_nC = nC + 1; // nC value is outdated after this line - } - - // @@@ TO DO LATER - // if we just finish here then we'll go back and re-solve for - // delta_x. but actually we can be more efficient and incrementally - // update delta_x here. but if we do this, we wont have ell and Dell - // to use in updating the factorization later. + const int nC = m_nC; + m_C[nC] = nC; + m_nN--; + m_nC = nC + 1; // nC value is outdated after this line + } + // @@@ TO DO LATER + // if we just finish here then we'll go back and re-solve for + // delta_x. but actually we can be more efficient and incrementally + // update delta_x here. but if we do this, we wont have ell and Dell + // to use in updating the factorization later. } -void btRemoveRowCol (btScalar *A, int n, int nskip, int r) +void btRemoveRowCol(btScalar *A, int n, int nskip, int r) { - btAssert(A && n > 0 && nskip >= n && r >= 0 && r < n); - if (r >= n-1) return; - if (r > 0) { - { - const size_t move_size = (n-r-1)*sizeof(btScalar); - btScalar *Adst = A + r; - for (int i=0; i 0 && nskip >= n && r >= 0 && r < n); + if (r >= n - 1) return; + if (r > 0) + { + { + const size_t move_size = (n - r - 1) * sizeof(btScalar); + btScalar *Adst = A + r; + for (int i = 0; i < r; Adst += nskip, ++i) + { + btScalar *Asrc = Adst + 1; + memmove(Adst, Asrc, move_size); + } + } + { + const size_t cpy_size = r * sizeof(btScalar); + btScalar *Adst = A + r * nskip; + for (int i = r; i < (n - 1); ++i) + { + btScalar *Asrc = Adst + nskip; + memcpy(Adst, Asrc, cpy_size); + Adst = Asrc; + } + } + } + { + const size_t cpy_size = (n - r - 1) * sizeof(btScalar); + btScalar *Adst = A + r * (nskip + 1); + for (int i = r; i < (n - 1); ++i) + { + btScalar *Asrc = Adst + (nskip + 1); + memcpy(Adst, Asrc, cpy_size); + Adst = Asrc - 1; + } + } } - - - -void btLDLTAddTL (btScalar *L, btScalar *d, const btScalar *a, int n, int nskip, btAlignedObjectArray& scratch) +void btLDLTAddTL(btScalar *L, btScalar *d, const btScalar *a, int n, int nskip, btAlignedObjectArray &scratch) { - btAssert (L && d && a && n > 0 && nskip >= n); + btAssert(L && d && a && n > 0 && nskip >= n); - if (n < 2) return; - scratch.resize(2*nskip); - btScalar *W1 = &scratch[0]; - - btScalar *W2 = W1 + nskip; + if (n < 2) return; + scratch.resize(2 * nskip); + btScalar *W1 = &scratch[0]; - W1[0] = btScalar(0.0); - W2[0] = btScalar(0.0); - for (int j=1; j j) ? _BTGETA(i,j) : _BTGETA(j,i)) +#define BTGETA(i, j) ((i > j) ? _BTGETA(i, j) : _BTGETA(j, i)) inline size_t btEstimateLDLTAddTLTmpbufSize(int nskip) { - return nskip * 2 * sizeof(btScalar); + return nskip * 2 * sizeof(btScalar); } - -void btLDLTRemove (btScalar **A, const int *p, btScalar *L, btScalar *d, - int n1, int n2, int r, int nskip, btAlignedObjectArray& scratch) +void btLDLTRemove(btScalar **A, const int *p, btScalar *L, btScalar *d, + int n1, int n2, int r, int nskip, btAlignedObjectArray &scratch) { - btAssert(A && p && L && d && n1 > 0 && n2 > 0 && r >= 0 && r < n2 && - n1 >= n2 && nskip >= n1); - #ifdef BT_DEBUG - for (int i=0; i 0 && n2 > 0 && r >= 0 && r < n2 && + n1 >= n2 && nskip >= n1); +#ifdef BT_DEBUG + for (int i = 0; i < n2; ++i) btAssert(p[i] >= 0 && p[i] < n1); - #endif +#endif - if (r==n2-1) { - return; // deleting last row/col is easy - } - else { - size_t LDLTAddTL_size = btEstimateLDLTAddTLTmpbufSize(nskip); - btAssert(LDLTAddTL_size % sizeof(btScalar) == 0); - scratch.resize(nskip * 2+n2); - btScalar *tmp = &scratch[0]; - if (r==0) { - btScalar *a = (btScalar *)((char *)tmp + LDLTAddTL_size); - const int p_0 = p[0]; - for (int i=0; i& scratch) +void btLCP::transfer_i_from_C_to_N(int i, btAlignedObjectArray &scratch) { - { - int *C = m_C; - // remove a row/column from the factorization, and adjust the - // indexes (black magic!) - int last_idx = -1; - const int nC = m_nC; - int j = 0; - for ( ; j 0) { - const int nN = m_nN; - for (int j=0; j 0) + { + const int nN = m_nN; + for (int j = 0; j < nN; ++j) ptgt[j] += aptr[j]; + } + else + { + const int nN = m_nN; + for (int j = 0; j < nN; ++j) ptgt[j] -= aptr[j]; + } } -void btLCP::pC_plusequals_s_times_qC (btScalar *p, btScalar s, btScalar *q) +void btLCP::pC_plusequals_s_times_qC(btScalar *p, btScalar s, btScalar *q) { - const int nC = m_nC; - for (int i=0; i 0) { - { - btScalar *Dell = m_Dell; - int *C = m_C; - btScalar *aptr = BTAROW(i); -# ifdef BTNUB_OPTIMIZATIONS - // if nub>0, initial part of aptr[] is guaranteed unpermuted - const int nub = m_nub; - int j=0; - for ( ; j 0) + { + { + btScalar *Dell = m_Dell; + int *C = m_C; + btScalar *aptr = BTAROW(i); +#ifdef BTNUB_OPTIMIZATIONS + // if nub>0, initial part of aptr[] is guaranteed unpermuted + const int nub = m_nub; + int j = 0; + for (; j < nub; ++j) Dell[j] = aptr[j]; + const int nC = m_nC; + for (; j < nC; ++j) Dell[j] = aptr[C[j]]; +#else + const int nC = m_nC; + for (int j = 0; j < nC; ++j) Dell[j] = aptr[C[j]]; +#endif + } + btSolveL1(m_L, m_Dell, m_nC, m_nskip); + { + btScalar *ell = m_ell, *Dell = m_Dell, *d = m_d; + const int nC = m_nC; + for (int j = 0; j < nC; ++j) ell[j] = Dell[j] * d[j]; + } - if (!only_transfer) { - btScalar *tmp = m_tmp, *ell = m_ell; - { - const int nC = m_nC; - for (int j=0; j 0) { - int *C = m_C; - btScalar *tmp = m_tmp; - const int nC = m_nC; - for (int j=0; j 0) + { + int *C = m_C; + btScalar *tmp = m_tmp; + const int nC = m_nC; + for (int j = 0; j < nC; ++j) a[C[j]] = -tmp[j]; + } + else + { + int *C = m_C; + btScalar *tmp = m_tmp; + const int nC = m_nC; + for (int j = 0; j < nC; ++j) a[C[j]] = tmp[j]; + } + } + } } - void btLCP::unpermute() { - // now we have to un-permute x and w - { - memcpy (m_tmp,m_x,m_n*sizeof(btScalar)); - btScalar *x = m_x, *tmp = m_tmp; - const int *p = m_p; - const int n = m_n; - for (int j=0; j0 && A && x && b && lo && hi && nub >= 0 && nub <= n); - btAssert(outer_w); + // printf("btSolveDantzigLCP n=%d\n",n); + btAssert(n > 0 && A && x && b && lo && hi && nub >= 0 && nub <= n); + btAssert(outer_w); #ifdef BT_DEBUG - { - // check restrictions on lo and hi - for (int k=0; k= 0); - } -# endif - - - // if all the variables are unbounded then we can just factor, solve, - // and return - if (nub >= n) - { - - - int nskip = (n); - btFactorLDLT (A, outer_w, n, nskip); - btSolveLDLT (A, outer_w, b, n, nskip); - memcpy (x, b, n*sizeof(btScalar)); - - return !s_error; - } - - const int nskip = (n); - scratchMem.L.resize(n*nskip); - - scratchMem.d.resize(n); - - btScalar *w = outer_w; - scratchMem.delta_w.resize(n); - scratchMem.delta_x.resize(n); - scratchMem.Dell.resize(n); - scratchMem.ell.resize(n); - scratchMem.Arows.resize(n); - scratchMem.p.resize(n); - scratchMem.C.resize(n); - - // for i in N, state[i] is 0 if x(i)==lo(i) or 1 if x(i)==hi(i) - scratchMem.state.resize(n); - - - // create LCP object. note that tmp is set to delta_w to save space, this - // optimization relies on knowledge of how tmp is used, so be careful! - btLCP lcp(n,nskip,nub,A,x,b,w,lo,hi,&scratchMem.L[0],&scratchMem.d[0],&scratchMem.Dell[0],&scratchMem.ell[0],&scratchMem.delta_w[0],&scratchMem.state[0],findex,&scratchMem.p[0],&scratchMem.C[0],&scratchMem.Arows[0]); - int adj_nub = lcp.getNub(); - - // loop over all indexes adj_nub..n-1. for index i, if x(i),w(i) satisfy the - // LCP conditions then i is added to the appropriate index set. otherwise - // x(i),w(i) is driven either +ve or -ve to force it to the valid region. - // as we drive x(i), x(C) is also adjusted to keep w(C) at zero. - // while driving x(i) we maintain the LCP conditions on the other variables - // 0..i-1. we do this by watching out for other x(i),w(i) values going - // outside the valid region, and then switching them between index sets - // when that happens. - - bool hit_first_friction_index = false; - for (int i=adj_nub; i= 0) { - // un-permute x into delta_w, which is not being used at the moment - for (int j=0; j= 0) { - lcp.transfer_i_to_N (i); - scratchMem.state[i] = false; - } - else if (hi[i]==0 && w[i] <= 0) { - lcp.transfer_i_to_N (i); - scratchMem.state[i] = true; - } - else if (w[i]==0) { - // this is a degenerate case. by the time we get to this test we know - // that lo != 0, which means that lo < 0 as lo is not allowed to be +ve, - // and similarly that hi > 0. this means that the line segment - // corresponding to set C is at least finite in extent, and we are on it. - // NOTE: we must call lcp.solve1() before lcp.transfer_i_to_C() - lcp.solve1 (&scratchMem.delta_x[0],i,0,1); - - lcp.transfer_i_to_C (i); - } - else { - // we must push x(i) and w(i) - for (;;) { - int dir; - btScalar dirf; - // find direction to push on x(i) - if (w[i] <= 0) { - dir = 1; - dirf = btScalar(1.0); - } - else { - dir = -1; - dirf = btScalar(-1.0); - } - - // compute: delta_x(C) = -dir*A(C,C)\A(C,i) - lcp.solve1 (&scratchMem.delta_x[0],i,dir); - - // note that delta_x[i] = dirf, but we wont bother to set it - - // compute: delta_w = A*delta_x ... note we only care about - // delta_w(N) and delta_w(i), the rest is ignored - lcp.pN_equals_ANC_times_qC (&scratchMem.delta_w[0],&scratchMem.delta_x[0]); - lcp.pN_plusequals_ANi (&scratchMem.delta_w[0],i,dir); - scratchMem.delta_w[i] = lcp.AiC_times_qC (i,&scratchMem.delta_x[0]) + lcp.Aii(i)*dirf; - - // find largest step we can take (size=s), either to drive x(i),w(i) - // to the valid LCP region or to drive an already-valid variable - // outside the valid region. - - int cmd = 1; // index switching command - int si = 0; // si = index to switch if cmd>3 - btScalar s = -w[i]/scratchMem.delta_w[i]; - if (dir > 0) { - if (hi[i] < BT_INFINITY) { - btScalar s2 = (hi[i]-x[i])*dirf; // was (hi[i]-x[i])/dirf // step to x(i)=hi(i) - if (s2 < s) { - s = s2; - cmd = 3; - } - } - } - else { - if (lo[i] > -BT_INFINITY) { - btScalar s2 = (lo[i]-x[i])*dirf; // was (lo[i]-x[i])/dirf // step to x(i)=lo(i) - if (s2 < s) { - s = s2; - cmd = 2; - } - } - } - - { - const int numN = lcp.numN(); - for (int k=0; k < numN; ++k) { - const int indexN_k = lcp.indexN(k); - if (!scratchMem.state[indexN_k] ? scratchMem.delta_w[indexN_k] < 0 : scratchMem.delta_w[indexN_k] > 0) { - // don't bother checking if lo=hi=0 - if (lo[indexN_k] == 0 && hi[indexN_k] == 0) continue; - btScalar s2 = -w[indexN_k] / scratchMem.delta_w[indexN_k]; - if (s2 < s) { - s = s2; - cmd = 4; - si = indexN_k; - } - } - } - } - - { - const int numC = lcp.numC(); - for (int k=adj_nub; k < numC; ++k) { - const int indexC_k = lcp.indexC(k); - if (scratchMem.delta_x[indexC_k] < 0 && lo[indexC_k] > -BT_INFINITY) { - btScalar s2 = (lo[indexC_k]-x[indexC_k]) / scratchMem.delta_x[indexC_k]; - if (s2 < s) { - s = s2; - cmd = 5; - si = indexC_k; - } - } - if (scratchMem.delta_x[indexC_k] > 0 && hi[indexC_k] < BT_INFINITY) { - btScalar s2 = (hi[indexC_k]-x[indexC_k]) / scratchMem.delta_x[indexC_k]; - if (s2 < s) { - s = s2; - cmd = 6; - si = indexC_k; - } - } - } - } - - //static char* cmdstring[8] = {0,"->C","->NL","->NH","N->C", - // "C->NL","C->NH"}; - //printf ("cmd=%d (%s), si=%d\n",cmd,cmdstring[cmd],(cmd>3) ? si : i); - - // if s <= 0 then we've got a problem. if we just keep going then - // we're going to get stuck in an infinite loop. instead, just cross - // our fingers and exit with the current solution. - if (s <= btScalar(0.0)) - { -// printf("LCP internal error, s <= 0 (s=%.4e)",(double)s); - if (i < n) { - btSetZero (x+i,n-i); - btSetZero (w+i,n-i); - } - s_error = true; - break; - } - - // apply x = x + s * delta_x - lcp.pC_plusequals_s_times_qC (x, s, &scratchMem.delta_x[0]); - x[i] += s * dirf; - - // apply w = w + s * delta_w - lcp.pN_plusequals_s_times_qN (w, s, &scratchMem.delta_w[0]); - w[i] += s * scratchMem.delta_w[i]; - -// void *tmpbuf; - // switch indexes between sets if necessary - switch (cmd) { - case 1: // done - w[i] = 0; - lcp.transfer_i_to_C (i); - break; - case 2: // done - x[i] = lo[i]; - scratchMem.state[i] = false; - lcp.transfer_i_to_N (i); - break; - case 3: // done - x[i] = hi[i]; - scratchMem.state[i] = true; - lcp.transfer_i_to_N (i); - break; - case 4: // keep going - w[si] = 0; - lcp.transfer_i_from_N_to_C (si); - break; - case 5: // keep going - x[si] = lo[si]; - scratchMem.state[si] = false; - lcp.transfer_i_from_C_to_N (si, scratchMem.m_scratch); - break; - case 6: // keep going - x[si] = hi[si]; - scratchMem.state[si] = true; - lcp.transfer_i_from_C_to_N (si, scratchMem.m_scratch); - break; - } - - if (cmd <= 3) break; - } // for (;;) - } // else - - if (s_error) { - break; - } - } // for (int i=adj_nub; i= 0); + } +#endif - lcp.unpermute(); + // if all the variables are unbounded then we can just factor, solve, + // and return + if (nub >= n) + { + int nskip = (n); + btFactorLDLT(A, outer_w, n, nskip); + btSolveLDLT(A, outer_w, b, n, nskip); + memcpy(x, b, n * sizeof(btScalar)); + return !s_error; + } - return !s_error; + const int nskip = (n); + scratchMem.L.resize(n * nskip); + + scratchMem.d.resize(n); + + btScalar *w = outer_w; + scratchMem.delta_w.resize(n); + scratchMem.delta_x.resize(n); + scratchMem.Dell.resize(n); + scratchMem.ell.resize(n); + scratchMem.Arows.resize(n); + scratchMem.p.resize(n); + scratchMem.C.resize(n); + + // for i in N, state[i] is 0 if x(i)==lo(i) or 1 if x(i)==hi(i) + scratchMem.state.resize(n); + + // create LCP object. note that tmp is set to delta_w to save space, this + // optimization relies on knowledge of how tmp is used, so be careful! + btLCP lcp(n, nskip, nub, A, x, b, w, lo, hi, &scratchMem.L[0], &scratchMem.d[0], &scratchMem.Dell[0], &scratchMem.ell[0], &scratchMem.delta_w[0], &scratchMem.state[0], findex, &scratchMem.p[0], &scratchMem.C[0], &scratchMem.Arows[0]); + int adj_nub = lcp.getNub(); + + // loop over all indexes adj_nub..n-1. for index i, if x(i),w(i) satisfy the + // LCP conditions then i is added to the appropriate index set. otherwise + // x(i),w(i) is driven either +ve or -ve to force it to the valid region. + // as we drive x(i), x(C) is also adjusted to keep w(C) at zero. + // while driving x(i) we maintain the LCP conditions on the other variables + // 0..i-1. we do this by watching out for other x(i),w(i) values going + // outside the valid region, and then switching them between index sets + // when that happens. + + bool hit_first_friction_index = false; + for (int i = adj_nub; i < n; ++i) + { + s_error = false; + // the index i is the driving index and indexes i+1..n-1 are "dont care", + // i.e. when we make changes to the system those x's will be zero and we + // don't care what happens to those w's. in other words, we only consider + // an (i+1)*(i+1) sub-problem of A*x=b+w. + + // if we've hit the first friction index, we have to compute the lo and + // hi values based on the values of x already computed. we have been + // permuting the indexes, so the values stored in the findex vector are + // no longer valid. thus we have to temporarily unpermute the x vector. + // for the purposes of this computation, 0*infinity = 0 ... so if the + // contact constraint's normal force is 0, there should be no tangential + // force applied. + + if (!hit_first_friction_index && findex && findex[i] >= 0) + { + // un-permute x into delta_w, which is not being used at the moment + for (int j = 0; j < n; ++j) scratchMem.delta_w[scratchMem.p[j]] = x[j]; + + // set lo and hi values + for (int k = i; k < n; ++k) + { + btScalar wfk = scratchMem.delta_w[findex[k]]; + if (wfk == 0) + { + hi[k] = 0; + lo[k] = 0; + } + else + { + hi[k] = btFabs(hi[k] * wfk); + lo[k] = -hi[k]; + } + } + hit_first_friction_index = true; + } + + // thus far we have not even been computing the w values for indexes + // greater than i, so compute w[i] now. + w[i] = lcp.AiC_times_qC(i, x) + lcp.AiN_times_qN(i, x) - b[i]; + + // if lo=hi=0 (which can happen for tangential friction when normals are + // 0) then the index will be assigned to set N with some state. however, + // set C's line has zero size, so the index will always remain in set N. + // with the "normal" switching logic, if w changed sign then the index + // would have to switch to set C and then back to set N with an inverted + // state. this is pointless, and also computationally expensive. to + // prevent this from happening, we use the rule that indexes with lo=hi=0 + // will never be checked for set changes. this means that the state for + // these indexes may be incorrect, but that doesn't matter. + + // see if x(i),w(i) is in a valid region + if (lo[i] == 0 && w[i] >= 0) + { + lcp.transfer_i_to_N(i); + scratchMem.state[i] = false; + } + else if (hi[i] == 0 && w[i] <= 0) + { + lcp.transfer_i_to_N(i); + scratchMem.state[i] = true; + } + else if (w[i] == 0) + { + // this is a degenerate case. by the time we get to this test we know + // that lo != 0, which means that lo < 0 as lo is not allowed to be +ve, + // and similarly that hi > 0. this means that the line segment + // corresponding to set C is at least finite in extent, and we are on it. + // NOTE: we must call lcp.solve1() before lcp.transfer_i_to_C() + lcp.solve1(&scratchMem.delta_x[0], i, 0, 1); + + lcp.transfer_i_to_C(i); + } + else + { + // we must push x(i) and w(i) + for (;;) + { + int dir; + btScalar dirf; + // find direction to push on x(i) + if (w[i] <= 0) + { + dir = 1; + dirf = btScalar(1.0); + } + else + { + dir = -1; + dirf = btScalar(-1.0); + } + + // compute: delta_x(C) = -dir*A(C,C)\A(C,i) + lcp.solve1(&scratchMem.delta_x[0], i, dir); + + // note that delta_x[i] = dirf, but we wont bother to set it + + // compute: delta_w = A*delta_x ... note we only care about + // delta_w(N) and delta_w(i), the rest is ignored + lcp.pN_equals_ANC_times_qC(&scratchMem.delta_w[0], &scratchMem.delta_x[0]); + lcp.pN_plusequals_ANi(&scratchMem.delta_w[0], i, dir); + scratchMem.delta_w[i] = lcp.AiC_times_qC(i, &scratchMem.delta_x[0]) + lcp.Aii(i) * dirf; + + // find largest step we can take (size=s), either to drive x(i),w(i) + // to the valid LCP region or to drive an already-valid variable + // outside the valid region. + + int cmd = 1; // index switching command + int si = 0; // si = index to switch if cmd>3 + btScalar s = -w[i] / scratchMem.delta_w[i]; + if (dir > 0) + { + if (hi[i] < BT_INFINITY) + { + btScalar s2 = (hi[i] - x[i]) * dirf; // was (hi[i]-x[i])/dirf // step to x(i)=hi(i) + if (s2 < s) + { + s = s2; + cmd = 3; + } + } + } + else + { + if (lo[i] > -BT_INFINITY) + { + btScalar s2 = (lo[i] - x[i]) * dirf; // was (lo[i]-x[i])/dirf // step to x(i)=lo(i) + if (s2 < s) + { + s = s2; + cmd = 2; + } + } + } + + { + const int numN = lcp.numN(); + for (int k = 0; k < numN; ++k) + { + const int indexN_k = lcp.indexN(k); + if (!scratchMem.state[indexN_k] ? scratchMem.delta_w[indexN_k] < 0 : scratchMem.delta_w[indexN_k] > 0) + { + // don't bother checking if lo=hi=0 + if (lo[indexN_k] == 0 && hi[indexN_k] == 0) continue; + btScalar s2 = -w[indexN_k] / scratchMem.delta_w[indexN_k]; + if (s2 < s) + { + s = s2; + cmd = 4; + si = indexN_k; + } + } + } + } + + { + const int numC = lcp.numC(); + for (int k = adj_nub; k < numC; ++k) + { + const int indexC_k = lcp.indexC(k); + if (scratchMem.delta_x[indexC_k] < 0 && lo[indexC_k] > -BT_INFINITY) + { + btScalar s2 = (lo[indexC_k] - x[indexC_k]) / scratchMem.delta_x[indexC_k]; + if (s2 < s) + { + s = s2; + cmd = 5; + si = indexC_k; + } + } + if (scratchMem.delta_x[indexC_k] > 0 && hi[indexC_k] < BT_INFINITY) + { + btScalar s2 = (hi[indexC_k] - x[indexC_k]) / scratchMem.delta_x[indexC_k]; + if (s2 < s) + { + s = s2; + cmd = 6; + si = indexC_k; + } + } + } + } + + //static char* cmdstring[8] = {0,"->C","->NL","->NH","N->C", + // "C->NL","C->NH"}; + //printf ("cmd=%d (%s), si=%d\n",cmd,cmdstring[cmd],(cmd>3) ? si : i); + + // if s <= 0 then we've got a problem. if we just keep going then + // we're going to get stuck in an infinite loop. instead, just cross + // our fingers and exit with the current solution. + if (s <= btScalar(0.0)) + { + // printf("LCP internal error, s <= 0 (s=%.4e)",(double)s); + if (i < n) + { + btSetZero(x + i, n - i); + btSetZero(w + i, n - i); + } + s_error = true; + break; + } + + // apply x = x + s * delta_x + lcp.pC_plusequals_s_times_qC(x, s, &scratchMem.delta_x[0]); + x[i] += s * dirf; + + // apply w = w + s * delta_w + lcp.pN_plusequals_s_times_qN(w, s, &scratchMem.delta_w[0]); + w[i] += s * scratchMem.delta_w[i]; + + // void *tmpbuf; + // switch indexes between sets if necessary + switch (cmd) + { + case 1: // done + w[i] = 0; + lcp.transfer_i_to_C(i); + break; + case 2: // done + x[i] = lo[i]; + scratchMem.state[i] = false; + lcp.transfer_i_to_N(i); + break; + case 3: // done + x[i] = hi[i]; + scratchMem.state[i] = true; + lcp.transfer_i_to_N(i); + break; + case 4: // keep going + w[si] = 0; + lcp.transfer_i_from_N_to_C(si); + break; + case 5: // keep going + x[si] = lo[si]; + scratchMem.state[si] = false; + lcp.transfer_i_from_C_to_N(si, scratchMem.m_scratch); + break; + case 6: // keep going + x[si] = hi[si]; + scratchMem.state[si] = true; + lcp.transfer_i_from_C_to_N(si, scratchMem.m_scratch); + break; + } + + if (cmd <= 3) break; + } // for (;;) + } // else + + if (s_error) + { + break; + } + } // for (int i=adj_nub; i #include - #include "LinearMath/btScalar.h" #include "LinearMath/btAlignedObjectArray.h" @@ -62,16 +60,14 @@ struct btDantzigScratchMemory btAlignedObjectArray delta_x; btAlignedObjectArray Dell; btAlignedObjectArray ell; - btAlignedObjectArray Arows; + btAlignedObjectArray Arows; btAlignedObjectArray p; btAlignedObjectArray C; btAlignedObjectArray state; }; //return false if solving failed -bool btSolveDantzigLCP (int n, btScalar *A, btScalar *x, btScalar *b, btScalar *w, - int nub, btScalar *lo, btScalar *hi, int *findex,btDantzigScratchMemory& scratch); +bool btSolveDantzigLCP(int n, btScalar *A, btScalar *x, btScalar *b, btScalar *w, + int nub, btScalar *lo, btScalar *hi, int *findex, btDantzigScratchMemory &scratch); - - -#endif //_BT_LCP_H_ +#endif //_BT_LCP_H_ diff --git a/src/BulletDynamics/MLCPSolvers/btDantzigSolver.h b/src/BulletDynamics/MLCPSolvers/btDantzigSolver.h index 2a2f2d3d3..1f669751c 100644 --- a/src/BulletDynamics/MLCPSolvers/btDantzigSolver.h +++ b/src/BulletDynamics/MLCPSolvers/btDantzigSolver.h @@ -20,30 +20,28 @@ subject to the following restrictions: #include "btMLCPSolverInterface.h" #include "btDantzigLCP.h" - class btDantzigSolver : public btMLCPSolverInterface { protected: - btScalar m_acceptableUpperLimitSolution; - btAlignedObjectArray m_tempBuffer; + btAlignedObjectArray m_tempBuffer; btAlignedObjectArray m_A; btAlignedObjectArray m_b; btAlignedObjectArray m_x; btAlignedObjectArray m_lo; btAlignedObjectArray m_hi; - btAlignedObjectArray m_dependencies; + btAlignedObjectArray m_dependencies; btDantzigScratchMemory m_scratchMemory; -public: +public: btDantzigSolver() - :m_acceptableUpperLimitSolution(btScalar(1000)) + : m_acceptableUpperLimitSolution(btScalar(1000)) { } - virtual bool solveMLCP(const btMatrixXu & A, const btVectorXu & b, btVectorXu& x, const btVectorXu & lo,const btVectorXu & hi,const btAlignedObjectArray& limitDependency, int numIterations, bool useSparsity = true) + virtual bool solveMLCP(const btMatrixXu& A, const btVectorXu& b, btVectorXu& x, const btVectorXu& lo, const btVectorXu& hi, const btAlignedObjectArray& limitDependency, int numIterations, bool useSparsity = true) { bool result = true; int n = b.rows(); @@ -52,14 +50,12 @@ public: int nub = 0; btAlignedObjectArray ww; ww.resize(n); - const btScalar* Aptr = A.getBufferPointer(); - m_A.resize(n*n); - for (int i=0;i= 1) { - cout << "Dimension = " << dim << endl; - } -#endif //BT_DEBUG_OSTREAM + if (DEBUGLEVEL >= 1) + { + cout << "Dimension = " << dim << endl; + } +#endif //BT_DEBUG_OSTREAM btVectorXu solutionVector(2 * dim); solutionVector.setZero(); - - //, INIT, 0.); + + //, INIT, 0.); btMatrixXu ident(dim, dim); ident.setIdentity(); @@ -85,287 +81,289 @@ btScalar btEpsRoot() { #endif btMatrixXu mNeg = m_M.negative(); - - btMatrixXu A(dim, 2 * dim + 2); + + btMatrixXu A(dim, 2 * dim + 2); // - A.setSubMatrix(0, 0, dim - 1, dim - 1,ident); - A.setSubMatrix(0, dim, dim - 1, 2 * dim - 1,mNeg); + A.setSubMatrix(0, 0, dim - 1, dim - 1, ident); + A.setSubMatrix(0, dim, dim - 1, 2 * dim - 1, mNeg); A.setSubMatrix(0, 2 * dim, dim - 1, 2 * dim, -1.f); - A.setSubMatrix(0, 2 * dim + 1, dim - 1, 2 * dim + 1,m_q); + A.setSubMatrix(0, 2 * dim + 1, dim - 1, 2 * dim + 1, m_q); #ifdef BT_DEBUG_OSTREAM cout << A << std::endl; -#endif //BT_DEBUG_OSTREAM +#endif //BT_DEBUG_OSTREAM + // btVectorXu q_; + // q_ >> A(0, 2 * dim + 1, dim - 1, 2 * dim + 1); - // btVectorXu q_; - // q_ >> A(0, 2 * dim + 1, dim - 1, 2 * dim + 1); - - btAlignedObjectArray basis; - //At first, all w-values are in the basis - for (int i = 0; i < dim; i++) - basis.push_back(i); + btAlignedObjectArray basis; + //At first, all w-values are in the basis + for (int i = 0; i < dim; i++) + basis.push_back(i); int pivotRowIndex = -1; btScalar minValue = 1e30f; bool greaterZero = true; - for (int i=0;i= 3) + if (DEBUGLEVEL >= 3) { - // cout << "A: " << A << endl; - cout << "pivotRowIndex " << pivotRowIndex << endl; - cout << "pivotColIndex " << pivotColIndex << endl; - cout << "Basis: "; - for (int i = 0; i < basis.size(); i++) - cout << basis[i] << " "; - cout << endl; - } -#endif //BT_DEBUG_OSTREAM + // cout << "A: " << A << endl; + cout << "pivotRowIndex " << pivotRowIndex << endl; + cout << "pivotColIndex " << pivotColIndex << endl; + cout << "Basis: "; + for (int i = 0; i < basis.size(); i++) + cout << basis[i] << " "; + cout << endl; + } +#endif //BT_DEBUG_OSTREAM if (!greaterZero) { + if (maxloops == 0) + { + maxloops = 100; + // maxloops = UINT_MAX; //TODO: not a really nice way, problem is: maxloops should be 2^dim (=1<= 3) { - // cout << "A: " << A << endl; - cout << "pivotRowIndex " << pivotRowIndex << endl; - cout << "pivotColIndex " << pivotColIndex << endl; - cout << "Basis: "; - for (int i = 0; i < basis.size(); i++) - cout << basis[i] << " "; - cout << endl; - } -#endif //BT_DEBUG_OSTREAM + if (DEBUGLEVEL >= 3) + { + // cout << "A: " << A << endl; + cout << "pivotRowIndex " << pivotRowIndex << endl; + cout << "pivotColIndex " << pivotColIndex << endl; + cout << "Basis: "; + for (int i = 0; i < basis.size(); i++) + cout << basis[i] << " "; + cout << endl; + } +#endif //BT_DEBUG_OSTREAM - int pivotColIndexOld = pivotColIndex; + int pivotColIndexOld = pivotColIndex; - /*find new column index */ - if (basis[pivotRowIndex] < dim) //if a w-value left the basis get in the correspondent z-value - pivotColIndex = basis[pivotRowIndex] + dim; - else - //else do it the other way round and get in the corresponding w-value - pivotColIndex = basis[pivotRowIndex] - dim; + /*find new column index */ + if (basis[pivotRowIndex] < dim) //if a w-value left the basis get in the correspondent z-value + pivotColIndex = basis[pivotRowIndex] + dim; + else + //else do it the other way round and get in the corresponding w-value + pivotColIndex = basis[pivotRowIndex] - dim; - /*the column becomes part of the basis*/ - basis[pivotRowIndex] = pivotColIndexOld; + /*the column becomes part of the basis*/ + basis[pivotRowIndex] = pivotColIndexOld; - pivotRowIndex = findLexicographicMinimum(A, pivotColIndex); + pivotRowIndex = findLexicographicMinimum(A, pivotColIndex); - if(z0Row == pivotRowIndex) { //if z0 leaves the basis the solution is found --> one last elimination step is necessary - GaussJordanEliminationStep(A, pivotRowIndex, pivotColIndex, basis); - basis[pivotRowIndex] = pivotColIndex; //update basis - break; - } - - } + if (z0Row == pivotRowIndex) + { //if z0 leaves the basis the solution is found --> one last elimination step is necessary + GaussJordanEliminationStep(A, pivotRowIndex, pivotColIndex, basis); + basis[pivotRowIndex] = pivotColIndex; //update basis + break; + } + } #ifdef BT_DEBUG_OSTREAM - if(DEBUGLEVEL >= 1) { - cout << "Number of loops: " << steps << endl; - cout << "Number of maximal loops: " << maxloops << endl; - } -#endif //BT_DEBUG_OSTREAM + if (DEBUGLEVEL >= 1) + { + cout << "Number of loops: " << steps << endl; + cout << "Number of maximal loops: " << maxloops << endl; + } +#endif //BT_DEBUG_OSTREAM - if(!validBasis(basis)) { - info = -1; + if (!validBasis(basis)) + { + info = -1; #ifdef BT_DEBUG_OSTREAM - if(DEBUGLEVEL >= 1) - cerr << "Lemke-Algorithm ended with Ray-Termination (no valid solution)." << endl; -#endif //BT_DEBUG_OSTREAM + if (DEBUGLEVEL >= 1) + cerr << "Lemke-Algorithm ended with Ray-Termination (no valid solution)." << endl; +#endif //BT_DEBUG_OSTREAM - return solutionVector; - } - - } + return solutionVector; + } + } #ifdef BT_DEBUG_OSTREAM - if (DEBUGLEVEL >= 2) { - // cout << "A: " << A << endl; - cout << "pivotRowIndex " << pivotRowIndex << endl; - cout << "pivotColIndex " << pivotColIndex << endl; - } -#endif //BT_DEBUG_OSTREAM - - for (int i = 0; i < basis.size(); i++) + if (DEBUGLEVEL >= 2) { - solutionVector[basis[i]] = A(i,2*dim+1);//q_[i]; + // cout << "A: " << A << endl; + cout << "pivotRowIndex " << pivotRowIndex << endl; + cout << "pivotColIndex " << pivotColIndex << endl; + } +#endif //BT_DEBUG_OSTREAM + + for (int i = 0; i < basis.size(); i++) + { + solutionVector[basis[i]] = A(i, 2 * dim + 1); //q_[i]; } - info = 0; + info = 0; - return solutionVector; - } + return solutionVector; +} - int btLemkeAlgorithm::findLexicographicMinimum(const btMatrixXu& A, const int & pivotColIndex) { - int RowIndex = 0; - int dim = A.rows(); - btAlignedObjectArray Rows; - for (int row = 0; row < dim; row++) - { - - btVectorXu vec(dim + 1); - vec.setZero();//, INIT, 0.) - Rows.push_back(vec); - btScalar a = A(row, pivotColIndex); - if (a > 0) { - Rows[row][0] = A(row, 2 * dim + 1) / a; - Rows[row][1] = A(row, 2 * dim) / a; - for (int j = 2; j < dim + 1; j++) - Rows[row][j] = A(row, j - 1) / a; +int btLemkeAlgorithm::findLexicographicMinimum(const btMatrixXu& A, const int& pivotColIndex) +{ + int RowIndex = 0; + int dim = A.rows(); + btAlignedObjectArray Rows; + for (int row = 0; row < dim; row++) + { + btVectorXu vec(dim + 1); + vec.setZero(); //, INIT, 0.) + Rows.push_back(vec); + btScalar a = A(row, pivotColIndex); + if (a > 0) + { + Rows[row][0] = A(row, 2 * dim + 1) / a; + Rows[row][1] = A(row, 2 * dim) / a; + for (int j = 2; j < dim + 1; j++) + Rows[row][j] = A(row, j - 1) / a; #ifdef BT_DEBUG_OSTREAM - // if (DEBUGLEVEL) { - // cout << "Rows(" << row << ") = " << Rows[row] << endl; + // if (DEBUGLEVEL) { + // cout << "Rows(" << row << ") = " << Rows[row] << endl; // } -#endif - } - } +#endif + } + } - for (int i = 0; i < Rows.size(); i++) - { - if (Rows[i].nrm2() > 0.) { + for (int i = 0; i < Rows.size(); i++) + { + if (Rows[i].nrm2() > 0.) + { + int j = 0; + for (; j < Rows.size(); j++) + { + if (i != j) + { + if (Rows[j].nrm2() > 0.) + { + btVectorXu test(dim + 1); + for (int ii = 0; ii < dim + 1; ii++) + { + test[ii] = Rows[j][ii] - Rows[i][ii]; + } - int j = 0; - for (; j < Rows.size(); j++) - { - if(i != j) - { - if(Rows[j].nrm2() > 0.) - { - btVectorXu test(dim + 1); - for (int ii=0;ii 0) - return true; + while (i < v.size() - 1 && fabs(v[i]) < btMachEps()) + i++; + if (v[i] > 0) + return true; - return false; - } + return false; +} -void btLemkeAlgorithm::GaussJordanEliminationStep(btMatrixXu& A, int pivotRowIndex, int pivotColumnIndex, const btAlignedObjectArray& basis) +void btLemkeAlgorithm::GaussJordanEliminationStep(btMatrixXu& A, int pivotRowIndex, int pivotColumnIndex, const btAlignedObjectArray& basis) { - btScalar a = -1 / A(pivotRowIndex, pivotColumnIndex); #ifdef BT_DEBUG_OSTREAM cout << A << std::endl; #endif - for (int i = 0; i < A.rows(); i++) + for (int i = 0; i < A.rows(); i++) { - if (i != pivotRowIndex) - { - for (int j = 0; j < A.cols(); j++) + if (i != pivotRowIndex) { - if (j != pivotColumnIndex) - { - btScalar v = A(i, j); - v += A(pivotRowIndex, j) * A(i, pivotColumnIndex) * a; - A.setElem(i, j, v); - } + for (int j = 0; j < A.cols(); j++) + { + if (j != pivotColumnIndex) + { + btScalar v = A(i, j); + v += A(pivotRowIndex, j) * A(i, pivotColumnIndex) * a; + A.setElem(i, j, v); + } + } } - } } #ifdef BT_DEBUG_OSTREAM cout << A << std::endl; -#endif //BT_DEBUG_OSTREAM - for (int i = 0; i < A.cols(); i++) +#endif //BT_DEBUG_OSTREAM + for (int i = 0; i < A.cols(); i++) { - A.mulElem(pivotRowIndex, i,-a); - } -#ifdef BT_DEBUG_OSTREAM - cout << A << std::endl; -#endif //#ifdef BT_DEBUG_OSTREAM - - for (int i = 0; i < A.rows(); i++) - { - if (i != pivotRowIndex) - { - A.setElem(i, pivotColumnIndex,0); - } + A.mulElem(pivotRowIndex, i, -a); } #ifdef BT_DEBUG_OSTREAM cout << A << std::endl; -#endif //#ifdef BT_DEBUG_OSTREAM - } +#endif //#ifdef BT_DEBUG_OSTREAM - bool btLemkeAlgorithm::greaterZero(const btVectorXu & vector) + for (int i = 0; i < A.rows(); i++) + { + if (i != pivotRowIndex) + { + A.setElem(i, pivotColumnIndex, 0); + } + } +#ifdef BT_DEBUG_OSTREAM + cout << A << std::endl; +#endif //#ifdef BT_DEBUG_OSTREAM +} + +bool btLemkeAlgorithm::greaterZero(const btVectorXu& vector) { - bool isGreater = true; - for (int i = 0; i < vector.size(); i++) { - if (vector[i] < 0) { - isGreater = false; - break; - } - } + bool isGreater = true; + for (int i = 0; i < vector.size(); i++) + { + if (vector[i] < 0) + { + isGreater = false; + break; + } + } - return isGreater; - } - - bool btLemkeAlgorithm::validBasis(const btAlignedObjectArray& basis) - { - bool isValid = true; - for (int i = 0; i < basis.size(); i++) { - if (basis[i] >= basis.size() * 2) { //then z0 is in the base - isValid = false; - break; - } - } - - return isValid; - } + return isGreater; +} +bool btLemkeAlgorithm::validBasis(const btAlignedObjectArray& basis) +{ + bool isValid = true; + for (int i = 0; i < basis.size(); i++) + { + if (basis[i] >= basis.size() * 2) + { //then z0 is in the base + isValid = false; + break; + } + } + return isValid; +} diff --git a/src/BulletDynamics/MLCPSolvers/btLemkeAlgorithm.h b/src/BulletDynamics/MLCPSolvers/btLemkeAlgorithm.h index 7555cd9d2..3c6bf72a2 100644 --- a/src/BulletDynamics/MLCPSolvers/btLemkeAlgorithm.h +++ b/src/BulletDynamics/MLCPSolvers/btLemkeAlgorithm.h @@ -19,90 +19,84 @@ subject to the following restrictions: //Math library was replaced from fmatvec to a the file src/LinearMath/btMatrixX.h //STL/std::vector replaced by btAlignedObjectArray - - #ifndef BT_NUMERICS_LEMKE_ALGORITHM_H_ #define BT_NUMERICS_LEMKE_ALGORITHM_H_ #include "LinearMath/btMatrixX.h" - -#include //todo: replace by btAlignedObjectArray +#include //todo: replace by btAlignedObjectArray class btLemkeAlgorithm { public: - + btLemkeAlgorithm(const btMatrixXu& M_, const btVectorXu& q_, const int& DEBUGLEVEL_ = 0) : DEBUGLEVEL(DEBUGLEVEL_) + { + setSystem(M_, q_); + } - btLemkeAlgorithm(const btMatrixXu& M_, const btVectorXu& q_, const int & DEBUGLEVEL_ = 0) : - DEBUGLEVEL(DEBUGLEVEL_) - { - setSystem(M_, q_); - } - - /* GETTER / SETTER */ - /** + /* GETTER / SETTER */ + /** * \brief return info of solution process */ - int getInfo() { - return info; - } + int getInfo() + { + return info; + } - /** + /** * \brief get the number of steps until the solution was found */ - int getSteps(void) { - return steps; - } + int getSteps(void) + { + return steps; + } - - - /** + /** * \brief set system with Matrix M and vector q */ - void setSystem(const btMatrixXu & M_, const btVectorXu & q_) + void setSystem(const btMatrixXu& M_, const btVectorXu& q_) { m_M = M_; m_q = q_; - } - /***************************************************/ + } + /***************************************************/ - /** + /** * \brief solve algorithm adapted from : Fast Implementation of Lemke’s Algorithm for Rigid Body Contact Simulation (John E. Lloyd) */ - btVectorXu solve(unsigned int maxloops = 0); + btVectorXu solve(unsigned int maxloops = 0); - virtual ~btLemkeAlgorithm() { - } + virtual ~btLemkeAlgorithm() + { + } protected: - int findLexicographicMinimum(const btMatrixXu &A, const int & pivotColIndex); - bool LexicographicPositive(const btVectorXu & v); - void GaussJordanEliminationStep(btMatrixXu &A, int pivotRowIndex, int pivotColumnIndex, const btAlignedObjectArray& basis); - bool greaterZero(const btVectorXu & vector); - bool validBasis(const btAlignedObjectArray& basis); + int findLexicographicMinimum(const btMatrixXu& A, const int& pivotColIndex); + bool LexicographicPositive(const btVectorXu& v); + void GaussJordanEliminationStep(btMatrixXu& A, int pivotRowIndex, int pivotColumnIndex, const btAlignedObjectArray& basis); + bool greaterZero(const btVectorXu& vector); + bool validBasis(const btAlignedObjectArray& basis); - btMatrixXu m_M; - btVectorXu m_q; + btMatrixXu m_M; + btVectorXu m_q; - /** + /** * \brief number of steps until the Lemke algorithm found a solution */ - unsigned int steps; + unsigned int steps; - /** + /** * \brief define level of debug output */ - int DEBUGLEVEL; + int DEBUGLEVEL; - /** + /** * \brief did the algorithm find a solution * * -1 : not successful * 0 : successful */ - int info; + int info; }; - #endif /* BT_NUMERICS_LEMKE_ALGORITHM_H_ */ diff --git a/src/BulletDynamics/MLCPSolvers/btLemkeSolver.h b/src/BulletDynamics/MLCPSolvers/btLemkeSolver.h index 98484c379..3f215e56b 100644 --- a/src/BulletDynamics/MLCPSolvers/btLemkeSolver.h +++ b/src/BulletDynamics/MLCPSolvers/btLemkeSolver.h @@ -17,334 +17,322 @@ subject to the following restrictions: #ifndef BT_LEMKE_SOLVER_H #define BT_LEMKE_SOLVER_H - #include "btMLCPSolverInterface.h" #include "btLemkeAlgorithm.h" - - - ///The btLemkeSolver is based on "Fast Implementation of Lemke’s Algorithm for Rigid Body Contact Simulation (John E. Lloyd) " ///It is a slower but more accurate solver. Increase the m_maxLoops for better convergence, at the cost of more CPU time. ///The original implementation of the btLemkeAlgorithm was done by Kilian Grundl from the MBSim team class btLemkeSolver : public btMLCPSolverInterface { protected: - public: - - btScalar m_maxValue; - int m_debugLevel; - int m_maxLoops; - bool m_useLoHighBounds; - - + btScalar m_maxValue; + int m_debugLevel; + int m_maxLoops; + bool m_useLoHighBounds; btLemkeSolver() - :m_maxValue(100000), - m_debugLevel(0), - m_maxLoops(1000), - m_useLoHighBounds(true) + : m_maxValue(100000), + m_debugLevel(0), + m_maxLoops(1000), + m_useLoHighBounds(true) { } - virtual bool solveMLCP(const btMatrixXu & A, const btVectorXu & b, btVectorXu& x, const btVectorXu & lo,const btVectorXu & hi,const btAlignedObjectArray& limitDependency, int numIterations, bool useSparsity = true) + virtual bool solveMLCP(const btMatrixXu& A, const btVectorXu& b, btVectorXu& x, const btVectorXu& lo, const btVectorXu& hi, const btAlignedObjectArray& limitDependency, int numIterations, bool useSparsity = true) { - if (m_useLoHighBounds) { + BT_PROFILE("btLemkeSolver::solveMLCP"); + int n = A.rows(); + if (0 == n) + return true; - BT_PROFILE("btLemkeSolver::solveMLCP"); - int n = A.rows(); - if (0==n) - return true; - - bool fail = false; + bool fail = false; - btVectorXu solution(n); - btVectorXu q1; - q1.resize(n); - for (int row=0;rowm_maxValue) - { - if (x[i]> errorValueMax) + b1.setElem(row, 0, -b[row]); + for (int col = 0; col < n; col++) { - fail = true; - errorIndexMax = i; - errorValueMax = x[i]; - } - ////printf("x[i] = %f,",x[i]); - } - if (x[i]<-m_maxValue) - { - if (x[i] m_maxValue) + { + if (x[i] > errorValueMax) + { + fail = true; + errorIndexMax = i; + errorValueMax = x[i]; + } + ////printf("x[i] = %f,",x[i]); + } + if (x[i] < -m_maxValue) + { + if (x[i] < errorValueMin) + { + errorIndexMin = i; + errorValueMin = x[i]; + fail = true; + //printf("x[i] = %f,",x[i]); + } + } + } + if (fail) + { + int m_errorCountTimes = 0; + if (errorIndexMin < 0) + errorValueMin = 0.f; + if (errorIndexMax < 0) + errorValueMax = 0.f; + m_errorCountTimes++; + // printf("Error (x[%d] = %f, x[%d] = %f), resetting %d times\n", errorIndexMin,errorValueMin, errorIndexMax, errorValueMax, errorCountTimes++); + for (int i = 0; i < n; i++) + { + x[i] = 0.f; + } + } + return !fail; } - return !fail; - } else - - { + else + + { int dimension = A.rows(); - if (0==dimension) - return true; - -// printf("================ solving using Lemke/Newton/Fixpoint\n"); + if (0 == dimension) + return true; - btVectorXu q; - q.resize(dimension); - for (int row=0;rowm_maxValue) + + btLemkeAlgorithm lemke(A, q, m_debugLevel); + + lemke.setSystem(A, q); + + btVectorXu solution = lemke.solve(m_maxLoops); + + //check solution + + bool fail = false; + int errorIndexMax = -1; + int errorIndexMin = -1; + float errorValueMax = -1e30; + float errorValueMin = 1e30; + + for (int i = 0; i < dimension; i++) { - if (x[i]> errorValueMax) + x[i] = solution[i + dimension]; + volatile btScalar check = x[i]; + if (x[i] != check) { - fail = true; - errorIndexMax = i; - errorValueMax = x[i]; + x.setZero(); + return false; } - ////printf("x[i] = %f,",x[i]); - } - if (x[i]<-m_maxValue) - { - if (x[i] m_maxValue) { - errorIndexMin = i; - errorValueMin = x[i]; - fail = true; - //printf("x[i] = %f,",x[i]); + if (x[i] > errorValueMax) + { + fail = true; + errorIndexMax = i; + errorValueMax = x[i]; + } + ////printf("x[i] = %f,",x[i]); + } + if (x[i] < -m_maxValue) + { + if (x[i] < errorValueMin) + { + errorIndexMin = i; + errorValueMin = x[i]; + fail = true; + //printf("x[i] = %f,",x[i]); + } } } - } - if (fail) - { - static int errorCountTimes = 0; - if (errorIndexMin<0) - errorValueMin = 0.f; - if (errorIndexMax<0) - errorValueMax = 0.f; - printf("Error (x[%d] = %f, x[%d] = %f), resetting %d times\n", errorIndexMin,errorValueMin, errorIndexMax, errorValueMax, errorCountTimes++); - for (int i=0;i limitDependenciesCopy = m_limitDependencies; -// printf("solve first LCP\n"); - result = m_solver->solveMLCP(m_A, m_b, m_x, m_lo,m_hi, m_limitDependencies,infoGlobal.m_numIterations ); + // printf("solve first LCP\n"); + result = m_solver->solveMLCP(m_A, m_b, m_x, m_lo, m_hi, m_limitDependencies, infoGlobal.m_numIterations); if (result) - result = m_solver->solveMLCP(Acopy, m_bSplit, m_xSplit, m_lo,m_hi, limitDependenciesCopy,infoGlobal.m_numIterations ); - - } else + result = m_solver->solveMLCP(Acopy, m_bSplit, m_xSplit, m_lo, m_hi, limitDependenciesCopy, infoGlobal.m_numIterations); + } + else { - result = m_solver->solveMLCP(m_A, m_b, m_x, m_lo,m_hi, m_limitDependencies,infoGlobal.m_numIterations ); + result = m_solver->solveMLCP(m_A, m_b, m_x, m_lo, m_hi, m_limitDependencies, infoGlobal.m_numIterations); } return result; } struct btJointNode { - int jointIndex; // pointer to enclosing dxJoint object - int otherBodyIndex; // *other* body this joint is connected to - int nextJointNodeIndex;//-1 for null + int jointIndex; // pointer to enclosing dxJoint object + int otherBodyIndex; // *other* body this joint is connected to + int nextJointNodeIndex; //-1 for null int constraintRowIndex; }; - - void btMLCPSolver::createMLCPFast(const btContactSolverInfo& infoGlobal) { int numContactRows = interleaveContactAndFriction ? 3 : 1; @@ -163,36 +157,36 @@ void btMLCPSolver::createMLCPFast(const btContactSolverInfo& infoGlobal) m_bSplit.resize(numConstraintRows); m_b.setZero(); m_bSplit.setZero(); - for (int i=0;im_jacDiagABInv; if (!btFuzzyZero(jacDiag)) { btScalar rhs = m_allConstraintPtrArray[i]->m_rhs; btScalar rhsPenetration = m_allConstraintPtrArray[i]->m_rhsPenetration; - m_b[i]=rhs/jacDiag; - m_bSplit[i] = rhsPenetration/jacDiag; + m_b[i] = rhs / jacDiag; + m_bSplit[i] = rhsPenetration / jacDiag; } - } } -// btScalar* w = 0; -// int nub = 0; + // btScalar* w = 0; + // int nub = 0; m_lo.resize(numConstraintRows); m_hi.resize(numConstraintRows); - + { BT_PROFILE("init lo/ho"); - for (int i=0;i=0) + if (0) //m_limitDependencies[i]>=0) { m_lo[i] = -BT_INFINITY; m_hi[i] = BT_INFINITY; - } else + } + else { m_lo[i] = m_allConstraintPtrArray[i]->m_lowerLimit; m_hi[i] = m_allConstraintPtrArray[i]->m_upperLimit; @@ -201,48 +195,48 @@ void btMLCPSolver::createMLCPFast(const btContactSolverInfo& infoGlobal) } // - int m=m_allConstraintPtrArray.size(); + int m = m_allConstraintPtrArray.size(); int numBodies = m_tmpSolverBodyPool.size(); btAlignedObjectArray bodyJointNodeArray; { BT_PROFILE("bodyJointNodeArray.resize"); - bodyJointNodeArray.resize(numBodies,-1); + bodyJointNodeArray.resize(numBodies, -1); } btAlignedObjectArray jointNodeArray; { BT_PROFILE("jointNodeArray.reserve"); - jointNodeArray.reserve(2*m_allConstraintPtrArray.size()); + jointNodeArray.reserve(2 * m_allConstraintPtrArray.size()); } - btMatrixXu& J3 = m_scratchJ3; + btMatrixXu& J3 = m_scratchJ3; { BT_PROFILE("J3.resize"); - J3.resize(2*m,8); + J3.resize(2 * m, 8); } - btMatrixXu& JinvM3 = m_scratchJInvM3; + btMatrixXu& JinvM3 = m_scratchJInvM3; { BT_PROFILE("JinvM3.resize/setZero"); - JinvM3.resize(2*m,8); + JinvM3.resize(2 * m, 8); JinvM3.setZero(); J3.setZero(); } - int cur=0; + int cur = 0; int rowOffset = 0; - btAlignedObjectArray& ofs = m_scratchOfs; + btAlignedObjectArray& ofs = m_scratchOfs; { BT_PROFILE("ofs resize"); ofs.resize(0); ofs.resizeNoInitialize(m_allConstraintPtrArray.size()); - } + } { BT_PROFILE("Compute J and JinvM"); - int c=0; + int c = 0; int numRows = 0; - for (int i=0;im_solverBodyIdA; @@ -250,14 +244,14 @@ void btMLCPSolver::createMLCPFast(const btContactSolverInfo& infoGlobal) btRigidBody* orgBodyA = m_tmpSolverBodyPool[sbA].m_originalBody; btRigidBody* orgBodyB = m_tmpSolverBodyPool[sbB].m_originalBody; - numRows = im_contactNormal1 * orgBodyA->getInvMass(); - btVector3 relPosCrossNormalInvInertia = m_allConstraintPtrArray[i+row]->m_relpos1CrossNormal * orgBodyA->getInvInertiaTensorWorld(); + btVector3 normalInvMass = m_allConstraintPtrArray[i + row]->m_contactNormal1 * orgBodyA->getInvMass(); + btVector3 relPosCrossNormalInvInertia = m_allConstraintPtrArray[i + row]->m_relpos1CrossNormal * orgBodyA->getInvInertiaTensorWorld(); - for (int r=0;r<3;r++) + for (int r = 0; r < 3; r++) { - J3.setElem(cur,r,m_allConstraintPtrArray[i+row]->m_contactNormal1[r]); - J3.setElem(cur,r+4,m_allConstraintPtrArray[i+row]->m_relpos1CrossNormal[r]); - JinvM3.setElem(cur,r,normalInvMass[r]); - JinvM3.setElem(cur,r+4,relPosCrossNormalInvInertia[r]); + J3.setElem(cur, r, m_allConstraintPtrArray[i + row]->m_contactNormal1[r]); + J3.setElem(cur, r + 4, m_allConstraintPtrArray[i + row]->m_relpos1CrossNormal[r]); + JinvM3.setElem(cur, r, normalInvMass[r]); + JinvM3.setElem(cur, r + 4, relPosCrossNormalInvInertia[r]); } - J3.setElem(cur,3,0); - JinvM3.setElem(cur,3,0); - J3.setElem(cur,7,0); - JinvM3.setElem(cur,7,0); + J3.setElem(cur, 3, 0); + JinvM3.setElem(cur, 3, 0); + J3.setElem(cur, 7, 0); + JinvM3.setElem(cur, 7, 0); } - } else + } + else { cur += numRows; } if (orgBodyB) { - { - int slotB=-1; + int slotB = -1; //find free jointNode slot for sbA - slotB =jointNodeArray.size(); - jointNodeArray.expand();//NonInitializing(); + slotB = jointNodeArray.size(); + jointNodeArray.expand(); //NonInitializing(); int prevSlot = bodyJointNodeArray[sbB]; bodyJointNodeArray[sbB] = slotB; jointNodeArray[slotB].nextJointNodeIndex = prevSlot; @@ -302,78 +296,74 @@ void btMLCPSolver::createMLCPFast(const btContactSolverInfo& infoGlobal) jointNodeArray[slotB].constraintRowIndex = i; } - for (int row=0;rowm_contactNormal2*orgBodyB->getInvMass(); - btVector3 relPosInvInertiaB = m_allConstraintPtrArray[i+row]->m_relpos2CrossNormal * orgBodyB->getInvInertiaTensorWorld(); + btVector3 normalInvMassB = m_allConstraintPtrArray[i + row]->m_contactNormal2 * orgBodyB->getInvMass(); + btVector3 relPosInvInertiaB = m_allConstraintPtrArray[i + row]->m_relpos2CrossNormal * orgBodyB->getInvInertiaTensorWorld(); - for (int r=0;r<3;r++) + for (int r = 0; r < 3; r++) { - J3.setElem(cur,r,m_allConstraintPtrArray[i+row]->m_contactNormal2[r]); - J3.setElem(cur,r+4,m_allConstraintPtrArray[i+row]->m_relpos2CrossNormal[r]); - JinvM3.setElem(cur,r,normalInvMassB[r]); - JinvM3.setElem(cur,r+4,relPosInvInertiaB[r]); + J3.setElem(cur, r, m_allConstraintPtrArray[i + row]->m_contactNormal2[r]); + J3.setElem(cur, r + 4, m_allConstraintPtrArray[i + row]->m_relpos2CrossNormal[r]); + JinvM3.setElem(cur, r, normalInvMassB[r]); + JinvM3.setElem(cur, r + 4, relPosInvInertiaB[r]); } - J3.setElem(cur,3,0); - JinvM3.setElem(cur,3,0); - J3.setElem(cur,7,0); - JinvM3.setElem(cur,7,0); + J3.setElem(cur, 3, 0); + JinvM3.setElem(cur, 3, 0); + J3.setElem(cur, 7, 0); + JinvM3.setElem(cur, 7, 0); } } else { cur += numRows; } - rowOffset+=numRows; - + rowOffset += numRows; } - } - //compute JinvM = J*invM. const btScalar* JinvM = JinvM3.getBufferPointer(); const btScalar* Jptr = J3.getBufferPointer(); { BT_PROFILE("m_A.resize"); - m_A.resize(n,n); + m_A.resize(n, n); } - + { BT_PROFILE("m_A.setZero"); m_A.setZero(); } - int c=0; + int c = 0; { int numRows = 0; BT_PROFILE("Compute A"); - for (int i=0;im_solverBodyIdA; int sbB = m_allConstraintPtrArray[i]->m_solverBodyIdB; - // btRigidBody* orgBodyA = m_tmpSolverBodyPool[sbA].m_originalBody; - // btRigidBody* orgBodyB = m_tmpSolverBodyPool[sbB].m_originalBody; + // btRigidBody* orgBodyA = m_tmpSolverBodyPool[sbA].m_originalBody; + // btRigidBody* orgBodyB = m_tmpSolverBodyPool[sbB].m_originalBody; - numRows = i=0) + while (startJointNodeA >= 0) { int j0 = jointNodeArray[startJointNodeA].jointIndex; int cr0 = jointNodeArray[startJointNodeA].constraintRowIndex; - if (j0m_solverBodyIdB == sbA) ? 8*numRowsOther : 0; + size_t ofsother = (m_allConstraintPtrArray[cr0]->m_solverBodyIdB == sbA) ? 8 * numRowsOther : 0; //printf("%d joint i %d and j0: %d: ",count++,i,j0); - m_A.multiplyAdd2_p8r ( JinvMrow, - Jptr + 2*8*(size_t)ofs[j0] + ofsother, numRows, numRowsOther, row__,ofs[j0]); + m_A.multiplyAdd2_p8r(JinvMrow, + Jptr + 2 * 8 * (size_t)ofs[j0] + ofsother, numRows, numRowsOther, row__, ofs[j0]); } startJointNodeA = jointNodeArray[startJointNodeA].nextJointNodeIndex; } @@ -381,17 +371,17 @@ void btMLCPSolver::createMLCPFast(const btContactSolverInfo& infoGlobal) { int startJointNodeB = bodyJointNodeArray[sbB]; - while (startJointNodeB>=0) + while (startJointNodeB >= 0) { int j1 = jointNodeArray[startJointNodeB].jointIndex; int cj1 = jointNodeArray[startJointNodeB].constraintRowIndex; - if (j1m_solverBodyIdB == sbB) ? 8*numRowsOther : 0; - m_A.multiplyAdd2_p8r ( JinvMrow + 8*(size_t)numRows, - Jptr + 2*8*(size_t)ofs[j1] + ofsother, numRows, numRowsOther, row__,ofs[j1]); + int numRowsOther = cj1 < m_tmpSolverNonContactConstraintPool.size() ? m_tmpConstraintSizesPool[j1].m_numConstraintRows : numContactRows; + size_t ofsother = (m_allConstraintPtrArray[cj1]->m_solverBodyIdB == sbB) ? 8 * numRowsOther : 0; + m_A.multiplyAdd2_p8r(JinvMrow + 8 * (size_t)numRows, + Jptr + 2 * 8 * (size_t)ofs[j1] + ofsother, numRows, numRowsOther, row__, ofs[j1]); } startJointNodeB = jointNodeArray[startJointNodeB].nextJointNodeIndex; } @@ -402,27 +392,25 @@ void btMLCPSolver::createMLCPFast(const btContactSolverInfo& infoGlobal) BT_PROFILE("compute diagonal"); // compute diagonal blocks of m_A - int row__ = 0; + int row__ = 0; int numJointRows = m_allConstraintPtrArray.size(); - int jj=0; - for (;row__m_solverBodyIdA; int sbB = m_allConstraintPtrArray[row__]->m_solverBodyIdB; - // btRigidBody* orgBodyA = m_tmpSolverBodyPool[sbA].m_originalBody; + // btRigidBody* orgBodyA = m_tmpSolverBodyPool[sbA].m_originalBody; btRigidBody* orgBodyB = m_tmpSolverBodyPool[sbB].m_originalBody; + const unsigned int infom = row__ < m_tmpSolverNonContactConstraintPool.size() ? m_tmpConstraintSizesPool[jj].m_numConstraintRows : numContactRows; - const unsigned int infom = row__ < m_tmpSolverNonContactConstraintPool.size() ? m_tmpConstraintSizesPool[jj].m_numConstraintRows : numContactRows; - - const btScalar *JinvMrow = JinvM + 2*8*(size_t)row__; - const btScalar *Jrow = Jptr + 2*8*(size_t)row__; - m_A.multiply2_p8r (JinvMrow, Jrow, infom, infom, row__,row__); - if (orgBodyB) + const btScalar* JinvMrow = JinvM + 2 * 8 * (size_t)row__; + const btScalar* Jrow = Jptr + 2 * 8 * (size_t)row__; + m_A.multiply2_p8r(JinvMrow, Jrow, infom, infom, row__, row__); + if (orgBodyB) { - m_A.multiplyAdd2_p8r (JinvMrow + 8*(size_t)infom, Jrow + 8*(size_t)infom, infom, infom, row__,row__); + m_A.multiplyAdd2_p8r(JinvMrow + 8 * (size_t)infom, Jrow + 8 * (size_t)infom, infom, infom, row__, row__); } row__ += infom; jj++; @@ -433,12 +421,12 @@ void btMLCPSolver::createMLCPFast(const btContactSolverInfo& infoGlobal) if (1) { // add cfm to the diagonal of m_A - for ( int i=0; im_jacDiagABInv) { - m_b[i]=m_allConstraintPtrArray[i]->m_rhs/m_allConstraintPtrArray[i]->m_jacDiagABInv; + m_b[i] = m_allConstraintPtrArray[i]->m_rhs / m_allConstraintPtrArray[i]->m_jacDiagABInv; if (infoGlobal.m_splitImpulse) - m_bSplit[i] = m_allConstraintPtrArray[i]->m_rhsPenetration/m_allConstraintPtrArray[i]->m_jacDiagABInv; + m_bSplit[i] = m_allConstraintPtrArray[i]->m_rhsPenetration / m_allConstraintPtrArray[i]->m_jacDiagABInv; } } - - btMatrixXu& Minv = m_scratchMInv; - Minv.resize(6*numBodies,6*numBodies); + + btMatrixXu& Minv = m_scratchMInv; + Minv.resize(6 * numBodies, 6 * numBodies); Minv.setZero(); - for (int i=0;igetInvInertiaTensorWorld()[r][c] : 0); + + for (int r = 0; r < 3; r++) + for (int c = 0; c < 3; c++) + setElem(Minv, i * 6 + 3 + r, i * 6 + 3 + c, orgBody ? orgBody->getInvInertiaTensorWorld()[r][c] : 0); } - - btMatrixXu& J = m_scratchJ; - J.resize(numConstraintRows,6*numBodies); + + btMatrixXu& J = m_scratchJ; + J.resize(numConstraintRows, 6 * numBodies); J.setZero(); - + m_lo.resize(numConstraintRows); m_hi.resize(numConstraintRows); - - for (int i=0;im_lowerLimit; m_hi[i] = m_allConstraintPtrArray[i]->m_upperLimit; - + int bodyIndex0 = m_allConstraintPtrArray[i]->m_solverBodyIdA; int bodyIndex1 = m_allConstraintPtrArray[i]->m_solverBodyIdB; if (m_tmpSolverBodyPool[bodyIndex0].m_originalBody) { - setElem(J,i,6*bodyIndex0+0,m_allConstraintPtrArray[i]->m_contactNormal1[0]); - setElem(J,i,6*bodyIndex0+1,m_allConstraintPtrArray[i]->m_contactNormal1[1]); - setElem(J,i,6*bodyIndex0+2,m_allConstraintPtrArray[i]->m_contactNormal1[2]); - setElem(J,i,6*bodyIndex0+3,m_allConstraintPtrArray[i]->m_relpos1CrossNormal[0]); - setElem(J,i,6*bodyIndex0+4,m_allConstraintPtrArray[i]->m_relpos1CrossNormal[1]); - setElem(J,i,6*bodyIndex0+5,m_allConstraintPtrArray[i]->m_relpos1CrossNormal[2]); + setElem(J, i, 6 * bodyIndex0 + 0, m_allConstraintPtrArray[i]->m_contactNormal1[0]); + setElem(J, i, 6 * bodyIndex0 + 1, m_allConstraintPtrArray[i]->m_contactNormal1[1]); + setElem(J, i, 6 * bodyIndex0 + 2, m_allConstraintPtrArray[i]->m_contactNormal1[2]); + setElem(J, i, 6 * bodyIndex0 + 3, m_allConstraintPtrArray[i]->m_relpos1CrossNormal[0]); + setElem(J, i, 6 * bodyIndex0 + 4, m_allConstraintPtrArray[i]->m_relpos1CrossNormal[1]); + setElem(J, i, 6 * bodyIndex0 + 5, m_allConstraintPtrArray[i]->m_relpos1CrossNormal[2]); } if (m_tmpSolverBodyPool[bodyIndex1].m_originalBody) { - setElem(J,i,6*bodyIndex1+0,m_allConstraintPtrArray[i]->m_contactNormal2[0]); - setElem(J,i,6*bodyIndex1+1,m_allConstraintPtrArray[i]->m_contactNormal2[1]); - setElem(J,i,6*bodyIndex1+2,m_allConstraintPtrArray[i]->m_contactNormal2[2]); - setElem(J,i,6*bodyIndex1+3,m_allConstraintPtrArray[i]->m_relpos2CrossNormal[0]); - setElem(J,i,6*bodyIndex1+4,m_allConstraintPtrArray[i]->m_relpos2CrossNormal[1]); - setElem(J,i,6*bodyIndex1+5,m_allConstraintPtrArray[i]->m_relpos2CrossNormal[2]); + setElem(J, i, 6 * bodyIndex1 + 0, m_allConstraintPtrArray[i]->m_contactNormal2[0]); + setElem(J, i, 6 * bodyIndex1 + 1, m_allConstraintPtrArray[i]->m_contactNormal2[1]); + setElem(J, i, 6 * bodyIndex1 + 2, m_allConstraintPtrArray[i]->m_contactNormal2[2]); + setElem(J, i, 6 * bodyIndex1 + 3, m_allConstraintPtrArray[i]->m_relpos2CrossNormal[0]); + setElem(J, i, 6 * bodyIndex1 + 4, m_allConstraintPtrArray[i]->m_relpos2CrossNormal[1]); + setElem(J, i, 6 * bodyIndex1 + 5, m_allConstraintPtrArray[i]->m_relpos2CrossNormal[2]); } } - - btMatrixXu& J_transpose = m_scratchJTranspose; - J_transpose= J.transpose(); - btMatrixXu& tmp = m_scratchTmp; + btMatrixXu& J_transpose = m_scratchJTranspose; + J_transpose = J.transpose(); + + btMatrixXu& tmp = m_scratchTmp; { { BT_PROFILE("J*Minv"); - tmp = J*Minv; - + tmp = J * Minv; } { BT_PROFILE("J*tmp"); - m_A = tmp*J_transpose; + m_A = tmp * J_transpose; } } if (1) { // add cfm to the diagonal of m_A - for ( int i=0; i m_limitDependencies; - btAlignedObjectArray m_allConstraintPtrArray; + btAlignedObjectArray m_allConstraintPtrArray; btMLCPSolverInterface* m_solver; int m_fallback; - /// The following scratch variables are not stateful -- contents are cleared prior to each use. - /// They are only cached here to avoid extra memory allocations and deallocations and to ensure - /// that multiple instances of the solver can be run in parallel. - btMatrixXu m_scratchJ3; - btMatrixXu m_scratchJInvM3; - btAlignedObjectArray m_scratchOfs; - btMatrixXu m_scratchMInv; - btMatrixXu m_scratchJ; - btMatrixXu m_scratchJTranspose; - btMatrixXu m_scratchTmp; - - virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer); - virtual btScalar solveGroupCacheFriendlyIterations(btCollisionObject** bodies ,int numBodies,btPersistentManifold** manifoldPtr, int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& infoGlobal,btIDebugDraw* debugDrawer); + /// The following scratch variables are not stateful -- contents are cleared prior to each use. + /// They are only cached here to avoid extra memory allocations and deallocations and to ensure + /// that multiple instances of the solver can be run in parallel. + btMatrixXu m_scratchJ3; + btMatrixXu m_scratchJInvM3; + btAlignedObjectArray m_scratchOfs; + btMatrixXu m_scratchMInv; + btMatrixXu m_scratchJ; + btMatrixXu m_scratchJTranspose; + btMatrixXu m_scratchTmp; + virtual btScalar solveGroupCacheFriendlySetup(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer); + virtual btScalar solveGroupCacheFriendlyIterations(btCollisionObject** bodies, int numBodies, btPersistentManifold** manifoldPtr, int numManifolds, btTypedConstraint** constraints, int numConstraints, const btContactSolverInfo& infoGlobal, btIDebugDraw* debugDrawer); virtual void createMLCP(const btContactSolverInfo& infoGlobal); virtual void createMLCPFast(const btContactSolverInfo& infoGlobal); @@ -65,8 +62,7 @@ protected: virtual bool solveMLCP(const btContactSolverInfo& infoGlobal); public: - - btMLCPSolver( btMLCPSolverInterface* solver); + btMLCPSolver(btMLCPSolverInterface* solver); virtual ~btMLCPSolver(); void setMLCPSolver(btMLCPSolverInterface* solver) @@ -83,12 +79,10 @@ public: m_fallback = num; } - virtual btConstraintSolverType getSolverType() const + virtual btConstraintSolverType getSolverType() const { return BT_MLCP_SOLVER; } - }; - -#endif //BT_MLCP_SOLVER_H +#endif //BT_MLCP_SOLVER_H diff --git a/src/BulletDynamics/MLCPSolvers/btMLCPSolverInterface.h b/src/BulletDynamics/MLCPSolvers/btMLCPSolverInterface.h index 25bb3f6d3..6b0465b88 100644 --- a/src/BulletDynamics/MLCPSolvers/btMLCPSolverInterface.h +++ b/src/BulletDynamics/MLCPSolvers/btMLCPSolverInterface.h @@ -27,7 +27,7 @@ public: } //return true is it solves the problem successfully - virtual bool solveMLCP(const btMatrixXu & A, const btVectorXu & b, btVectorXu& x, const btVectorXu & lo,const btVectorXu & hi,const btAlignedObjectArray& limitDependency, int numIterations, bool useSparsity = true)=0; + virtual bool solveMLCP(const btMatrixXu& A, const btVectorXu& b, btVectorXu& x, const btVectorXu& lo, const btVectorXu& hi, const btAlignedObjectArray& limitDependency, int numIterations, bool useSparsity = true) = 0; }; -#endif //BT_MLCP_SOLVER_INTERFACE_H +#endif //BT_MLCP_SOLVER_INTERFACE_H diff --git a/src/BulletDynamics/MLCPSolvers/btPATHSolver.h b/src/BulletDynamics/MLCPSolvers/btPATHSolver.h index 9ec31a6d4..7f8eec3f6 100644 --- a/src/BulletDynamics/MLCPSolvers/btPATHSolver.h +++ b/src/BulletDynamics/MLCPSolvers/btPATHSolver.h @@ -14,38 +14,35 @@ subject to the following restrictions: */ ///original version written by Erwin Coumans, October 2013 - #ifndef BT_PATH_SOLVER_H #define BT_PATH_SOLVER_H //#define BT_USE_PATH #ifdef BT_USE_PATH -extern "C" { +extern "C" +{ #include "PATH/SimpleLCP.h" #include "PATH/License.h" #include "PATH/Error_Interface.h" }; - void __stdcall MyError(Void *data, Char *msg) +void __stdcall MyError(Void *data, Char *msg) { - printf("Path Error: %s\n",msg); + printf("Path Error: %s\n", msg); } - void __stdcall MyWarning(Void *data, Char *msg) +void __stdcall MyWarning(Void *data, Char *msg) { - printf("Path Warning: %s\n",msg); + printf("Path Warning: %s\n", msg); } Error_Interface e; - - #include "btMLCPSolverInterface.h" #include "Dantzig/lcp.h" class btPathSolver : public btMLCPSolverInterface { public: - btPathSolver() { License_SetString("2069810742&Courtesy_License&&&USR&2013&14_12_2011&1000&PATH&GEN&31_12_2013&0_0_0&0&0_0"); @@ -55,17 +52,15 @@ public: Error_SetInterface(&e); } - - virtual bool solveMLCP(const btMatrixXu & A, const btVectorXu & b, btVectorXu& x, const btVectorXu & lo,const btVectorXu & hi,const btAlignedObjectArray& limitDependency, int numIterations, bool useSparsity = true) + virtual bool solveMLCP(const btMatrixXu &A, const btVectorXu &b, btVectorXu &x, const btVectorXu &lo, const btVectorXu &hi, const btAlignedObjectArray &limitDependency, int numIterations, bool useSparsity = true) { MCP_Termination status; - int numVariables = b.rows(); - if (0==numVariables) + if (0 == numVariables) return true; - /* - variables - the number of variables in the problem + /* - variables - the number of variables in the problem - m_nnz - the number of nonzeros in the M matrix - m_i - a vector of size m_nnz containing the row indices for M - m_j - a vector of size m_nnz containing the column indices for M @@ -78,16 +73,16 @@ public: btAlignedObjectArray rowIndices; btAlignedObjectArray colIndices; - for (int i=0;i rhs; btAlignedObjectArray upperBounds; btAlignedObjectArray lowerBounds; - for (int i=0;i& limitDependency, int numIterations, bool useSparsity = true) + virtual bool solveMLCP(const btMatrixXu& A, const btVectorXu& b, btVectorXu& x, const btVectorXu& lo, const btVectorXu& hi, const btAlignedObjectArray& limitDependency, int numIterations, bool useSparsity = true) { if (!A.rows()) return true; @@ -46,65 +43,65 @@ public: btAssert(A.rows() == b.rows()); int i, j, numRows = A.rows(); - + btScalar delta; - for (int k = 0; k =0) + if (limitDependency[i] >= 0) { s = x[limitDependency[i]]; - if (s<0) - s=1; + if (s < 0) + s = 1; } - - if (x[i]hi[i]*s) - x[i]=hi[i]*s; + + if (x[i] < lo[i] * s) + x[i] = lo[i] * s; + if (x[i] > hi[i] * s) + x[i] = hi[i] * s; btScalar diff = x[i] - xOld; - m_leastSquaresResidual += diff*diff; + m_leastSquaresResidual += diff * diff; } - btScalar eps = m_leastSquaresResidualThreshold; - if ((m_leastSquaresResidual < eps) || (k >=(numIterations-1))) + btScalar eps = m_leastSquaresResidualThreshold; + if ((m_leastSquaresResidual < eps) || (k >= (numIterations - 1))) { #ifdef VERBOSE_PRINTF_RESIDUAL - printf("totalLenSqr = %f at iteration #%d\n", m_leastSquaresResidual,k); + printf("totalLenSqr = %f at iteration #%d\n", m_leastSquaresResidual, k); #endif break; } } return true; } - }; -#endif //BT_SOLVE_PROJECTED_GAUSS_SEIDEL_H +#endif //BT_SOLVE_PROJECTED_GAUSS_SEIDEL_H diff --git a/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp b/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp index f299aa34e..fc70d8e63 100644 --- a/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp +++ b/src/BulletDynamics/Vehicle/btRaycastVehicle.cpp @@ -24,17 +24,16 @@ #define ROLLING_INFLUENCE_FIX - btRigidBody& btActionInterface::getFixedBody() { - static btRigidBody s_fixed(0, 0,0); - s_fixed.setMassProps(btScalar(0.),btVector3(btScalar(0.),btScalar(0.),btScalar(0.))); + static btRigidBody s_fixed(0, 0, 0); + s_fixed.setMassProps(btScalar(0.), btVector3(btScalar(0.), btScalar(0.), btScalar(0.))); return s_fixed; } -btRaycastVehicle::btRaycastVehicle(const btVehicleTuning& tuning,btRigidBody* chassis, btVehicleRaycaster* raycaster ) -:m_vehicleRaycaster(raycaster), -m_pitchControl(btScalar(0.)) +btRaycastVehicle::btRaycastVehicle(const btVehicleTuning& tuning, btRigidBody* chassis, btVehicleRaycaster* raycaster) + : m_vehicleRaycaster(raycaster), + m_pitchControl(btScalar(0.)) { m_chassisBody = chassis; m_indexRightAxis = 0; @@ -43,28 +42,22 @@ m_pitchControl(btScalar(0.)) defaultInit(tuning); } - void btRaycastVehicle::defaultInit(const btVehicleTuning& tuning) { (void)tuning; m_currentVehicleSpeedKmHour = btScalar(0.); m_steeringValue = btScalar(0.); - } - - btRaycastVehicle::~btRaycastVehicle() { } - // // basically most of the code is general for 2 or 4 wheel vehicles, but some of it needs to be reviewed // -btWheelInfo& btRaycastVehicle::addWheel( const btVector3& connectionPointCS, const btVector3& wheelDirectionCS0,const btVector3& wheelAxleCS, btScalar suspensionRestLength, btScalar wheelRadius,const btVehicleTuning& tuning, bool isFrontWheel) +btWheelInfo& btRaycastVehicle::addWheel(const btVector3& connectionPointCS, const btVector3& wheelDirectionCS0, const btVector3& wheelAxleCS, btScalar suspensionRestLength, btScalar wheelRadius, const btVehicleTuning& tuning, bool isFrontWheel) { - btWheelInfoConstructionInfo ci; ci.m_chassisConnectionCS = connectionPointCS; @@ -80,83 +73,76 @@ btWheelInfo& btRaycastVehicle::addWheel( const btVector3& connectionPointCS, con ci.m_maxSuspensionTravelCm = tuning.m_maxSuspensionTravelCm; ci.m_maxSuspensionForce = tuning.m_maxSuspensionForce; - m_wheelInfo.push_back( btWheelInfo(ci)); - - btWheelInfo& wheel = m_wheelInfo[getNumWheels()-1]; - - updateWheelTransformsWS( wheel , false ); - updateWheelTransform(getNumWheels()-1,false); + m_wheelInfo.push_back(btWheelInfo(ci)); + + btWheelInfo& wheel = m_wheelInfo[getNumWheels() - 1]; + + updateWheelTransformsWS(wheel, false); + updateWheelTransform(getNumWheels() - 1, false); return wheel; } - - - -const btTransform& btRaycastVehicle::getWheelTransformWS( int wheelIndex ) const +const btTransform& btRaycastVehicle::getWheelTransformWS(int wheelIndex) const { btAssert(wheelIndex < getNumWheels()); const btWheelInfo& wheel = m_wheelInfo[wheelIndex]; return wheel.m_worldTransform; - } -void btRaycastVehicle::updateWheelTransform( int wheelIndex , bool interpolatedTransform) +void btRaycastVehicle::updateWheelTransform(int wheelIndex, bool interpolatedTransform) { - - btWheelInfo& wheel = m_wheelInfo[ wheelIndex ]; - updateWheelTransformsWS(wheel,interpolatedTransform); + btWheelInfo& wheel = m_wheelInfo[wheelIndex]; + updateWheelTransformsWS(wheel, interpolatedTransform); btVector3 up = -wheel.m_raycastInfo.m_wheelDirectionWS; const btVector3& right = wheel.m_raycastInfo.m_wheelAxleWS; btVector3 fwd = up.cross(right); fwd = fwd.normalize(); -// up = right.cross(fwd); -// up.normalize(); + // up = right.cross(fwd); + // up.normalize(); //rotate around steering over de wheelAxleWS btScalar steering = wheel.m_steering; - - btQuaternion steeringOrn(up,steering);//wheel.m_steering); + + btQuaternion steeringOrn(up, steering); //wheel.m_steering); btMatrix3x3 steeringMat(steeringOrn); - btQuaternion rotatingOrn(right,-wheel.m_rotation); + btQuaternion rotatingOrn(right, -wheel.m_rotation); btMatrix3x3 rotatingMat(rotatingOrn); - btMatrix3x3 basis2; - basis2[0][m_indexRightAxis] = -right[0]; - basis2[1][m_indexRightAxis] = -right[1]; - basis2[2][m_indexRightAxis] = -right[2]; + btMatrix3x3 basis2; + basis2[0][m_indexRightAxis] = -right[0]; + basis2[1][m_indexRightAxis] = -right[1]; + basis2[2][m_indexRightAxis] = -right[2]; - basis2[0][m_indexUpAxis] = up[0]; - basis2[1][m_indexUpAxis] = up[1]; - basis2[2][m_indexUpAxis] = up[2]; + basis2[0][m_indexUpAxis] = up[0]; + basis2[1][m_indexUpAxis] = up[1]; + basis2[2][m_indexUpAxis] = up[2]; - basis2[0][m_indexForwardAxis] = fwd[0]; - basis2[1][m_indexForwardAxis] = fwd[1]; - basis2[2][m_indexForwardAxis] = fwd[2]; + basis2[0][m_indexForwardAxis] = fwd[0]; + basis2[1][m_indexForwardAxis] = fwd[1]; + basis2[2][m_indexForwardAxis] = fwd[2]; wheel.m_worldTransform.setBasis(steeringMat * rotatingMat * basis2); wheel.m_worldTransform.setOrigin( - wheel.m_raycastInfo.m_hardPointWS + wheel.m_raycastInfo.m_wheelDirectionWS * wheel.m_raycastInfo.m_suspensionLength - ); + wheel.m_raycastInfo.m_hardPointWS + wheel.m_raycastInfo.m_wheelDirectionWS * wheel.m_raycastInfo.m_suspensionLength); } void btRaycastVehicle::resetSuspension() { - int i; - for (i=0;igetMotionState()->getWorldTransform(chassisTrans); } - wheel.m_raycastInfo.m_hardPointWS = chassisTrans( wheel.m_chassisConnectionPointCS ); - wheel.m_raycastInfo.m_wheelDirectionWS = chassisTrans.getBasis() * wheel.m_wheelDirectionCS ; + wheel.m_raycastInfo.m_hardPointWS = chassisTrans(wheel.m_chassisConnectionPointCS); + wheel.m_raycastInfo.m_wheelDirectionWS = chassisTrans.getBasis() * wheel.m_wheelDirectionCS; wheel.m_raycastInfo.m_wheelAxleWS = chassisTrans.getBasis() * wheel.m_wheelAxleCS; } btScalar btRaycastVehicle::rayCast(btWheelInfo& wheel) { - updateWheelTransformsWS( wheel,false); + updateWheelTransformsWS(wheel, false); - btScalar depth = -1; - - btScalar raylen = wheel.getSuspensionRestLength()+wheel.m_wheelsRadius; + + btScalar raylen = wheel.getSuspensionRestLength() + wheel.m_wheelsRadius; btVector3 rayvector = wheel.m_raycastInfo.m_wheelDirectionWS * (raylen); const btVector3& source = wheel.m_raycastInfo.m_hardPointWS; @@ -186,12 +171,12 @@ btScalar btRaycastVehicle::rayCast(btWheelInfo& wheel) const btVector3& target = wheel.m_raycastInfo.m_contactPointWS; btScalar param = btScalar(0.); - - btVehicleRaycaster::btVehicleRaycasterResult rayResults; + + btVehicleRaycaster::btVehicleRaycasterResult rayResults; btAssert(m_vehicleRaycaster); - void* object = m_vehicleRaycaster->castRay(source,target,rayResults); + void* object = m_vehicleRaycaster->castRay(source, target, rayResults); wheel.m_raycastInfo.m_groundObject = 0; @@ -199,19 +184,18 @@ btScalar btRaycastVehicle::rayCast(btWheelInfo& wheel) { param = rayResults.m_distFraction; depth = raylen * rayResults.m_distFraction; - wheel.m_raycastInfo.m_contactNormalWS = rayResults.m_hitNormalInWorld; + wheel.m_raycastInfo.m_contactNormalWS = rayResults.m_hitNormalInWorld; wheel.m_raycastInfo.m_isInContact = true; - - wheel.m_raycastInfo.m_groundObject = &getFixedBody();///@todo for driving on dynamic/movable objects!; + + wheel.m_raycastInfo.m_groundObject = &getFixedBody(); ///@todo for driving on dynamic/movable objects!; //wheel.m_raycastInfo.m_groundObject = object; - - btScalar hitDistance = param*raylen; + btScalar hitDistance = param * raylen; wheel.m_raycastInfo.m_suspensionLength = hitDistance - wheel.m_wheelsRadius; //clamp on max suspension travel - btScalar minSuspensionLength = wheel.getSuspensionRestLength() - wheel.m_maxSuspensionTravelCm*btScalar(0.01); - btScalar maxSuspensionLength = wheel.getSuspensionRestLength()+ wheel.m_maxSuspensionTravelCm*btScalar(0.01); + btScalar minSuspensionLength = wheel.getSuspensionRestLength() - wheel.m_maxSuspensionTravelCm * btScalar(0.01); + btScalar maxSuspensionLength = wheel.getSuspensionRestLength() + wheel.m_maxSuspensionTravelCm * btScalar(0.01); if (wheel.m_raycastInfo.m_suspensionLength < minSuspensionLength) { wheel.m_raycastInfo.m_suspensionLength = minSuspensionLength; @@ -223,16 +207,16 @@ btScalar btRaycastVehicle::rayCast(btWheelInfo& wheel) wheel.m_raycastInfo.m_contactPointWS = rayResults.m_hitPointInWorld; - btScalar denominator= wheel.m_raycastInfo.m_contactNormalWS.dot( wheel.m_raycastInfo.m_wheelDirectionWS ); + btScalar denominator = wheel.m_raycastInfo.m_contactNormalWS.dot(wheel.m_raycastInfo.m_wheelDirectionWS); btVector3 chassis_velocity_at_contactPoint; - btVector3 relpos = wheel.m_raycastInfo.m_contactPointWS-getRigidBody()->getCenterOfMassPosition(); + btVector3 relpos = wheel.m_raycastInfo.m_contactPointWS - getRigidBody()->getCenterOfMassPosition(); chassis_velocity_at_contactPoint = getRigidBody()->getVelocityInLocalPoint(relpos); - btScalar projVel = wheel.m_raycastInfo.m_contactNormalWS.dot( chassis_velocity_at_contactPoint ); + btScalar projVel = wheel.m_raycastInfo.m_contactNormalWS.dot(chassis_velocity_at_contactPoint); - if ( denominator >= btScalar(-0.1)) + if (denominator >= btScalar(-0.1)) { wheel.m_suspensionRelativeVelocity = btScalar(0.0); wheel.m_clippedInvContactDotSuspension = btScalar(1.0) / btScalar(0.1); @@ -243,20 +227,19 @@ btScalar btRaycastVehicle::rayCast(btWheelInfo& wheel) wheel.m_suspensionRelativeVelocity = projVel * inv; wheel.m_clippedInvContactDotSuspension = inv; } - - } else + } + else { //put wheel info as in rest position wheel.m_raycastInfo.m_suspensionLength = wheel.getSuspensionRestLength(); wheel.m_suspensionRelativeVelocity = btScalar(0.0); - wheel.m_raycastInfo.m_contactNormalWS = - wheel.m_raycastInfo.m_wheelDirectionWS; + wheel.m_raycastInfo.m_contactNormalWS = -wheel.m_raycastInfo.m_wheelDirectionWS; wheel.m_clippedInvContactDotSuspension = btScalar(1.0); } return depth; } - const btTransform& btRaycastVehicle::getChassisWorldTransform() const { /*if (getRigidBody()->getMotionState()) @@ -267,26 +250,23 @@ const btTransform& btRaycastVehicle::getChassisWorldTransform() const } */ - return getRigidBody()->getCenterOfMassTransform(); } - -void btRaycastVehicle::updateVehicle( btScalar step ) +void btRaycastVehicle::updateVehicle(btScalar step) { { - for (int i=0;igetLinearVelocity().length(); - + const btTransform& chassisTrans = getChassisWorldTransform(); - btVector3 forwardW ( + btVector3 forwardW( chassisTrans.getBasis()[0][m_indexForwardAxis], chassisTrans.getBasis()[1][m_indexForwardAxis], chassisTrans.getBasis()[2][m_indexForwardAxis]); @@ -299,52 +279,47 @@ void btRaycastVehicle::updateVehicle( btScalar step ) // // simulate suspension // - - int i=0; - for (i=0;i wheel.m_maxSuspensionForce) { suspensionForce = wheel.m_maxSuspensionForce; } btVector3 impulse = wheel.m_raycastInfo.m_contactNormalWS * suspensionForce * step; btVector3 relpos = wheel.m_raycastInfo.m_contactPointWS - getRigidBody()->getCenterOfMassPosition(); - + getRigidBody()->applyImpulse(impulse, relpos); - } - - - updateFriction( step); + updateFriction(step); - - for (i=0;igetCenterOfMassPosition(); - btVector3 vel = getRigidBody()->getVelocityInLocalPoint( relpos ); + btVector3 vel = getRigidBody()->getVelocityInLocalPoint(relpos); if (wheel.m_raycastInfo.m_isInContact) { - const btTransform& chassisWorldTransform = getChassisWorldTransform(); + const btTransform& chassisWorldTransform = getChassisWorldTransform(); - btVector3 fwd ( + btVector3 fwd( chassisWorldTransform.getBasis()[0][m_indexForwardAxis], chassisWorldTransform.getBasis()[1][m_indexForwardAxis], chassisWorldTransform.getBasis()[2][m_indexForwardAxis]); @@ -353,99 +328,88 @@ void btRaycastVehicle::updateVehicle( btScalar step ) fwd -= wheel.m_raycastInfo.m_contactNormalWS * proj; btScalar proj2 = fwd.dot(vel); - + wheel.m_deltaRotation = (proj2 * step) / (wheel.m_wheelsRadius); wheel.m_rotation += wheel.m_deltaRotation; - - } else + } + else { wheel.m_rotation += wheel.m_deltaRotation; } - - wheel.m_deltaRotation *= btScalar(0.99);//damping of rotation when not in contact + wheel.m_deltaRotation *= btScalar(0.99); //damping of rotation when not in contact } - - - } - -void btRaycastVehicle::setSteeringValue(btScalar steering,int wheel) +void btRaycastVehicle::setSteeringValue(btScalar steering, int wheel) { - btAssert(wheel>=0 && wheel < getNumWheels()); + btAssert(wheel >= 0 && wheel < getNumWheels()); btWheelInfo& wheelInfo = getWheelInfo(wheel); wheelInfo.m_steering = steering; } - - -btScalar btRaycastVehicle::getSteeringValue(int wheel) const +btScalar btRaycastVehicle::getSteeringValue(int wheel) const { return getWheelInfo(wheel).m_steering; } - -void btRaycastVehicle::applyEngineForce(btScalar force, int wheel) +void btRaycastVehicle::applyEngineForce(btScalar force, int wheel) { - btAssert(wheel>=0 && wheel < getNumWheels()); + btAssert(wheel >= 0 && wheel < getNumWheels()); btWheelInfo& wheelInfo = getWheelInfo(wheel); wheelInfo.m_engineForce = force; } - -const btWheelInfo& btRaycastVehicle::getWheelInfo(int index) const +const btWheelInfo& btRaycastVehicle::getWheelInfo(int index) const { - btAssert((index >= 0) && (index < getNumWheels())); - + btAssert((index >= 0) && (index < getNumWheels())); + return m_wheelInfo[index]; } -btWheelInfo& btRaycastVehicle::getWheelInfo(int index) +btWheelInfo& btRaycastVehicle::getWheelInfo(int index) { - btAssert((index >= 0) && (index < getNumWheels())); - + btAssert((index >= 0) && (index < getNumWheels())); + return m_wheelInfo[index]; } -void btRaycastVehicle::setBrake(btScalar brake,int wheelIndex) +void btRaycastVehicle::setBrake(btScalar brake, int wheelIndex) { - btAssert((wheelIndex >= 0) && (wheelIndex < getNumWheels())); + btAssert((wheelIndex >= 0) && (wheelIndex < getNumWheels())); getWheelInfo(wheelIndex).m_brake = brake; } - -void btRaycastVehicle::updateSuspension(btScalar deltaTime) +void btRaycastVehicle::updateSuspension(btScalar deltaTime) { (void)deltaTime; btScalar chassisMass = btScalar(1.) / m_chassisBody->getInvMass(); - - for (int w_it=0; w_itcomputeImpulseDenominator(frictionPosWorld,frictionDirectionWorld); - btScalar denom1 = body1->computeImpulseDenominator(frictionPosWorld,frictionDirectionWorld); - btScalar relaxation = 1.f; - m_jacDiagABInv = relaxation/(denom0+denom1); + btScalar denom0 = body0->computeImpulseDenominator(frictionPosWorld, frictionDirectionWorld); + btScalar denom1 = body1->computeImpulseDenominator(frictionPosWorld, frictionDirectionWorld); + btScalar relaxation = 1.f; + m_jacDiagABInv = relaxation / (denom0 + denom1); } - - - }; btScalar calcRollingFriction(btWheelContactPoint& contactPoint, int numWheelsOnGround); btScalar calcRollingFriction(btWheelContactPoint& contactPoint, int numWheelsOnGround) { - - btScalar j1=0.f; + btScalar j1 = 0.f; const btVector3& contactPosWorld = contactPoint.m_frictionPositionWorld; - btVector3 rel_pos1 = contactPosWorld - contactPoint.m_body0->getCenterOfMassPosition(); + btVector3 rel_pos1 = contactPosWorld - contactPoint.m_body0->getCenterOfMassPosition(); btVector3 rel_pos2 = contactPosWorld - contactPoint.m_body1->getCenterOfMassPosition(); - - btScalar maxImpulse = contactPoint.m_maxImpulse; - + + btScalar maxImpulse = contactPoint.m_maxImpulse; + btVector3 vel1 = contactPoint.m_body0->getVelocityInLocalPoint(rel_pos1); btVector3 vel2 = contactPoint.m_body1->getVelocityInLocalPoint(rel_pos2); btVector3 vel = vel1 - vel2; @@ -520,253 +477,225 @@ btScalar calcRollingFriction(btWheelContactPoint& contactPoint, int numWheelsOnG btScalar vrel = contactPoint.m_frictionDirectionWorld.dot(vel); // calculate j that moves us to zero relative velocity - j1 = -vrel * contactPoint.m_jacDiagABInv/btScalar(numWheelsOnGround); + j1 = -vrel * contactPoint.m_jacDiagABInv / btScalar(numWheelsOnGround); btSetMin(j1, maxImpulse); btSetMax(j1, -maxImpulse); return j1; } - - - btScalar sideFrictionStiffness2 = btScalar(1.0); -void btRaycastVehicle::updateFriction(btScalar timeStep) +void btRaycastVehicle::updateFriction(btScalar timeStep) { + //calculate the impulse, so that the wheels don't move sidewards + int numWheel = getNumWheels(); + if (!numWheel) + return; - //calculate the impulse, so that the wheels don't move sidewards - int numWheel = getNumWheels(); - if (!numWheel) - return; + m_forwardWS.resize(numWheel); + m_axle.resize(numWheel); + m_forwardImpulse.resize(numWheel); + m_sideImpulse.resize(numWheel); - m_forwardWS.resize(numWheel); - m_axle.resize(numWheel); - m_forwardImpulse.resize(numWheel); - m_sideImpulse.resize(numWheel); - - int numWheelsOnGround = 0; - + int numWheelsOnGround = 0; - //collapse all those loops into one! - for (int i=0;i 0); rollingFriction = calcRollingFriction(contactPt, numWheelsOnGround); } } //switch between active rolling (throttle), braking and non-active rolling friction (no throttle/break) - - - m_forwardImpulse[wheel] = btScalar(0.); - m_wheelInfo[wheel].m_skidInfo= btScalar(1.); + m_wheelInfo[wheel].m_skidInfo = btScalar(1.); if (groundObject) { - m_wheelInfo[wheel].m_skidInfo= btScalar(1.); - + m_wheelInfo[wheel].m_skidInfo = btScalar(1.); + btScalar maximp = wheelInfo.m_wheelsSuspensionForce * timeStep * wheelInfo.m_frictionSlip; btScalar maximpSide = maximp; btScalar maximpSquared = maximp * maximpSide; - - m_forwardImpulse[wheel] = rollingFriction;//wheelInfo.m_engineForce* timeStep; + m_forwardImpulse[wheel] = rollingFriction; //wheelInfo.m_engineForce* timeStep; - btScalar x = (m_forwardImpulse[wheel] ) * fwdFactor; - btScalar y = (m_sideImpulse[wheel] ) * sideFactor; - - btScalar impulseSquared = (x*x + y*y); + btScalar x = (m_forwardImpulse[wheel]) * fwdFactor; + btScalar y = (m_sideImpulse[wheel]) * sideFactor; + + btScalar impulseSquared = (x * x + y * y); if (impulseSquared > maximpSquared) { sliding = true; - + btScalar factor = maximp / btSqrt(impulseSquared); - + m_wheelInfo[wheel].m_skidInfo *= factor; } - } - + } } } - - - - if (sliding) + if (sliding) + { + for (int wheel = 0; wheel < getNumWheels(); wheel++) { - for (int wheel = 0;wheel < getNumWheels(); wheel++) + if (m_sideImpulse[wheel] != btScalar(0.)) { - if (m_sideImpulse[wheel] != btScalar(0.)) + if (m_wheelInfo[wheel].m_skidInfo < btScalar(1.)) { - if (m_wheelInfo[wheel].m_skidInfo< btScalar(1.)) - { - m_forwardImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo; - m_sideImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo; - } + m_forwardImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo; + m_sideImpulse[wheel] *= m_wheelInfo[wheel].m_skidInfo; } } } + } - // apply the impulses + // apply the impulses + { + for (int wheel = 0; wheel < getNumWheels(); wheel++) { - for (int wheel = 0;wheelgetCenterOfMassPosition(); + + if (m_forwardImpulse[wheel] != btScalar(0.)) { - btWheelInfo& wheelInfo = m_wheelInfo[wheel]; + m_chassisBody->applyImpulse(m_forwardWS[wheel] * (m_forwardImpulse[wheel]), rel_pos); + } + if (m_sideImpulse[wheel] != btScalar(0.)) + { + class btRigidBody* groundObject = (class btRigidBody*)m_wheelInfo[wheel].m_raycastInfo.m_groundObject; - btVector3 rel_pos = wheelInfo.m_raycastInfo.m_contactPointWS - - m_chassisBody->getCenterOfMassPosition(); + btVector3 rel_pos2 = wheelInfo.m_raycastInfo.m_contactPointWS - + groundObject->getCenterOfMassPosition(); - if (m_forwardImpulse[wheel] != btScalar(0.)) - { - m_chassisBody->applyImpulse(m_forwardWS[wheel]*(m_forwardImpulse[wheel]),rel_pos); - } - if (m_sideImpulse[wheel] != btScalar(0.)) - { - class btRigidBody* groundObject = (class btRigidBody*) m_wheelInfo[wheel].m_raycastInfo.m_groundObject; + btVector3 sideImp = m_axle[wheel] * m_sideImpulse[wheel]; - btVector3 rel_pos2 = wheelInfo.m_raycastInfo.m_contactPointWS - - groundObject->getCenterOfMassPosition(); - - - btVector3 sideImp = m_axle[wheel] * m_sideImpulse[wheel]; - -#if defined ROLLING_INFLUENCE_FIX // fix. It only worked if car's up was along Y - VT. - btVector3 vChassisWorldUp = getRigidBody()->getCenterOfMassTransform().getBasis().getColumn(m_indexUpAxis); - rel_pos -= vChassisWorldUp * (vChassisWorldUp.dot(rel_pos) * (1.f-wheelInfo.m_rollInfluence)); +#if defined ROLLING_INFLUENCE_FIX // fix. It only worked if car's up was along Y - VT. + btVector3 vChassisWorldUp = getRigidBody()->getCenterOfMassTransform().getBasis().getColumn(m_indexUpAxis); + rel_pos -= vChassisWorldUp * (vChassisWorldUp.dot(rel_pos) * (1.f - wheelInfo.m_rollInfluence)); #else - rel_pos[m_indexUpAxis] *= wheelInfo.m_rollInfluence; + rel_pos[m_indexUpAxis] *= wheelInfo.m_rollInfluence; #endif - m_chassisBody->applyImpulse(sideImp,rel_pos); + m_chassisBody->applyImpulse(sideImp, rel_pos); - //apply friction impulse on the ground - groundObject->applyImpulse(-sideImp,rel_pos2); - } + //apply friction impulse on the ground + groundObject->applyImpulse(-sideImp, rel_pos2); } } - - + } } - - -void btRaycastVehicle::debugDraw(btIDebugDraw* debugDrawer) +void btRaycastVehicle::debugDraw(btIDebugDraw* debugDrawer) { - - for (int v=0;vgetNumWheels();v++) + for (int v = 0; v < this->getNumWheels(); v++) { - btVector3 wheelColor(0,1,1); + btVector3 wheelColor(0, 1, 1); if (getWheelInfo(v).m_raycastInfo.m_isInContact) { - wheelColor.setValue(0,0,1); - } else + wheelColor.setValue(0, 0, 1); + } + else { - wheelColor.setValue(1,0,1); + wheelColor.setValue(1, 0, 1); } btVector3 wheelPosWS = getWheelInfo(v).m_worldTransform.getOrigin(); - btVector3 axle = btVector3( + btVector3 axle = btVector3( getWheelInfo(v).m_worldTransform.getBasis()[0][getRightAxis()], getWheelInfo(v).m_worldTransform.getBasis()[1][getRightAxis()], getWheelInfo(v).m_worldTransform.getBasis()[2][getRightAxis()]); //debug wheels (cylinders) - debugDrawer->drawLine(wheelPosWS,wheelPosWS+axle,wheelColor); - debugDrawer->drawLine(wheelPosWS,getWheelInfo(v).m_raycastInfo.m_contactPointWS,wheelColor); - + debugDrawer->drawLine(wheelPosWS, wheelPosWS + axle, wheelColor); + debugDrawer->drawLine(wheelPosWS, getWheelInfo(v).m_raycastInfo.m_contactPointWS, wheelColor); } } - -void* btDefaultVehicleRaycaster::castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result) +void* btDefaultVehicleRaycaster::castRay(const btVector3& from, const btVector3& to, btVehicleRaycasterResult& result) { -// RayResultCallback& resultCallback; + // RayResultCallback& resultCallback; - btCollisionWorld::ClosestRayResultCallback rayCallback(from,to); + btCollisionWorld::ClosestRayResultCallback rayCallback(from, to); m_dynamicsWorld->rayTest(from, to, rayCallback); if (rayCallback.hasHit()) { - const btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject); - if (body && body->hasContactResponse()) + if (body && body->hasContactResponse()) { result.m_hitPointInWorld = rayCallback.m_hitPointWorld; result.m_hitNormalInWorld = rayCallback.m_hitNormalWorld; @@ -777,4 +706,3 @@ void* btDefaultVehicleRaycaster::castRay(const btVector3& from,const btVector3& } return 0; } - diff --git a/src/BulletDynamics/Vehicle/btRaycastVehicle.h b/src/BulletDynamics/Vehicle/btRaycastVehicle.h index 04656b912..99d6894e5 100644 --- a/src/BulletDynamics/Vehicle/btRaycastVehicle.h +++ b/src/BulletDynamics/Vehicle/btRaycastVehicle.h @@ -24,122 +24,111 @@ class btDynamicsWorld; ///rayCast vehicle, very special constraint that turn a rigidbody into a vehicle. class btRaycastVehicle : public btActionInterface { + btAlignedObjectArray m_forwardWS; + btAlignedObjectArray m_axle; + btAlignedObjectArray m_forwardImpulse; + btAlignedObjectArray m_sideImpulse; - btAlignedObjectArray m_forwardWS; - btAlignedObjectArray m_axle; - btAlignedObjectArray m_forwardImpulse; - btAlignedObjectArray m_sideImpulse; - - ///backwards compatibility - int m_userConstraintType; - int m_userConstraintId; + ///backwards compatibility + int m_userConstraintType; + int m_userConstraintId; public: class btVehicleTuning + { + public: + btVehicleTuning() + : m_suspensionStiffness(btScalar(5.88)), + m_suspensionCompression(btScalar(0.83)), + m_suspensionDamping(btScalar(0.88)), + m_maxSuspensionTravelCm(btScalar(500.)), + m_frictionSlip(btScalar(10.5)), + m_maxSuspensionForce(btScalar(6000.)) { - public: + } + btScalar m_suspensionStiffness; + btScalar m_suspensionCompression; + btScalar m_suspensionDamping; + btScalar m_maxSuspensionTravelCm; + btScalar m_frictionSlip; + btScalar m_maxSuspensionForce; + }; - btVehicleTuning() - :m_suspensionStiffness(btScalar(5.88)), - m_suspensionCompression(btScalar(0.83)), - m_suspensionDamping(btScalar(0.88)), - m_maxSuspensionTravelCm(btScalar(500.)), - m_frictionSlip(btScalar(10.5)), - m_maxSuspensionForce(btScalar(6000.)) - { - } - btScalar m_suspensionStiffness; - btScalar m_suspensionCompression; - btScalar m_suspensionDamping; - btScalar m_maxSuspensionTravelCm; - btScalar m_frictionSlip; - btScalar m_maxSuspensionForce; - - }; private: - - btVehicleRaycaster* m_vehicleRaycaster; - btScalar m_pitchControl; - btScalar m_steeringValue; + btVehicleRaycaster* m_vehicleRaycaster; + btScalar m_pitchControl; + btScalar m_steeringValue; btScalar m_currentVehicleSpeedKmHour; btRigidBody* m_chassisBody; int m_indexRightAxis; int m_indexUpAxis; - int m_indexForwardAxis; + int m_indexForwardAxis; void defaultInit(const btVehicleTuning& tuning); public: - //constructor to create a car from an existing rigidbody - btRaycastVehicle(const btVehicleTuning& tuning,btRigidBody* chassis, btVehicleRaycaster* raycaster ); - - virtual ~btRaycastVehicle() ; + btRaycastVehicle(const btVehicleTuning& tuning, btRigidBody* chassis, btVehicleRaycaster* raycaster); + virtual ~btRaycastVehicle(); ///btActionInterface interface - virtual void updateAction( btCollisionWorld* collisionWorld, btScalar step) + virtual void updateAction(btCollisionWorld* collisionWorld, btScalar step) { - (void) collisionWorld; + (void)collisionWorld; updateVehicle(step); } - ///btActionInterface interface - void debugDraw(btIDebugDraw* debugDrawer); - + void debugDraw(btIDebugDraw* debugDrawer); + const btTransform& getChassisWorldTransform() const; - + btScalar rayCast(btWheelInfo& wheel); virtual void updateVehicle(btScalar step); - - + void resetSuspension(); - btScalar getSteeringValue(int wheel) const; + btScalar getSteeringValue(int wheel) const; - void setSteeringValue(btScalar steering,int wheel); + void setSteeringValue(btScalar steering, int wheel); + void applyEngineForce(btScalar force, int wheel); - void applyEngineForce(btScalar force, int wheel); + const btTransform& getWheelTransformWS(int wheelIndex) const; - const btTransform& getWheelTransformWS( int wheelIndex ) const; + void updateWheelTransform(int wheelIndex, bool interpolatedTransform = true); - void updateWheelTransform( int wheelIndex, bool interpolatedTransform = true ); - -// void setRaycastWheelInfo( int wheelIndex , bool isInContact, const btVector3& hitPoint, const btVector3& hitNormal,btScalar depth); + // void setRaycastWheelInfo( int wheelIndex , bool isInContact, const btVector3& hitPoint, const btVector3& hitNormal,btScalar depth); - btWheelInfo& addWheel( const btVector3& connectionPointCS0, const btVector3& wheelDirectionCS0,const btVector3& wheelAxleCS,btScalar suspensionRestLength,btScalar wheelRadius,const btVehicleTuning& tuning, bool isFrontWheel); + btWheelInfo& addWheel(const btVector3& connectionPointCS0, const btVector3& wheelDirectionCS0, const btVector3& wheelAxleCS, btScalar suspensionRestLength, btScalar wheelRadius, const btVehicleTuning& tuning, bool isFrontWheel); - inline int getNumWheels() const { - return int (m_wheelInfo.size()); + inline int getNumWheels() const + { + return int(m_wheelInfo.size()); } - - btAlignedObjectArray m_wheelInfo; + btAlignedObjectArray m_wheelInfo; - const btWheelInfo& getWheelInfo(int index) const; + const btWheelInfo& getWheelInfo(int index) const; - btWheelInfo& getWheelInfo(int index); + btWheelInfo& getWheelInfo(int index); - void updateWheelTransformsWS(btWheelInfo& wheel , bool interpolatedTransform = true); + void updateWheelTransformsWS(btWheelInfo& wheel, bool interpolatedTransform = true); - - void setBrake(btScalar brake,int wheelIndex); + void setBrake(btScalar brake, int wheelIndex); - void setPitchControl(btScalar pitch) + void setPitchControl(btScalar pitch) { m_pitchControl = pitch; } - - void updateSuspension(btScalar deltaTime); - - virtual void updateFriction(btScalar timeStep); + void updateSuspension(btScalar deltaTime); + virtual void updateFriction(btScalar timeStep); inline btRigidBody* getRigidBody() { @@ -151,7 +140,7 @@ public: return m_chassisBody; } - inline int getRightAxis() const + inline int getRightAxis() const { return m_indexRightAxis; } @@ -165,46 +154,44 @@ public: return m_indexForwardAxis; } - ///Worldspace forward vector btVector3 getForwardVector() const { - const btTransform& chassisTrans = getChassisWorldTransform(); + const btTransform& chassisTrans = getChassisWorldTransform(); - btVector3 forwardW ( - chassisTrans.getBasis()[0][m_indexForwardAxis], - chassisTrans.getBasis()[1][m_indexForwardAxis], - chassisTrans.getBasis()[2][m_indexForwardAxis]); + btVector3 forwardW( + chassisTrans.getBasis()[0][m_indexForwardAxis], + chassisTrans.getBasis()[1][m_indexForwardAxis], + chassisTrans.getBasis()[2][m_indexForwardAxis]); return forwardW; } ///Velocity of vehicle (positive if velocity vector has same direction as foward vector) - btScalar getCurrentSpeedKmHour() const + btScalar getCurrentSpeedKmHour() const { return m_currentVehicleSpeedKmHour; } - virtual void setCoordinateSystem(int rightIndex,int upIndex,int forwardIndex) + virtual void setCoordinateSystem(int rightIndex, int upIndex, int forwardIndex) { m_indexRightAxis = rightIndex; m_indexUpAxis = upIndex; m_indexForwardAxis = forwardIndex; } - ///backwards compatibility int getUserConstraintType() const { - return m_userConstraintType ; + return m_userConstraintType; } - void setUserConstraintType(int userConstraintType) + void setUserConstraintType(int userConstraintType) { m_userConstraintType = userConstraintType; }; - void setUserConstraintId(int uid) + void setUserConstraintId(int uid) { m_userConstraintId = uid; } @@ -213,22 +200,19 @@ public: { return m_userConstraintId; } - }; class btDefaultVehicleRaycaster : public btVehicleRaycaster { - btDynamicsWorld* m_dynamicsWorld; + btDynamicsWorld* m_dynamicsWorld; + public: btDefaultVehicleRaycaster(btDynamicsWorld* world) - :m_dynamicsWorld(world) + : m_dynamicsWorld(world) { } - virtual void* castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result); - + virtual void* castRay(const btVector3& from, const btVector3& to, btVehicleRaycasterResult& result); }; - -#endif //BT_RAYCASTVEHICLE_H - +#endif //BT_RAYCASTVEHICLE_H diff --git a/src/BulletDynamics/Vehicle/btVehicleRaycaster.h b/src/BulletDynamics/Vehicle/btVehicleRaycaster.h index 3cc909c65..2c44ce546 100644 --- a/src/BulletDynamics/Vehicle/btVehicleRaycaster.h +++ b/src/BulletDynamics/Vehicle/btVehicleRaycaster.h @@ -16,20 +16,18 @@ /// btVehicleRaycaster is provides interface for between vehicle simulation and raycasting struct btVehicleRaycaster { -virtual ~btVehicleRaycaster() -{ -} + virtual ~btVehicleRaycaster() + { + } struct btVehicleRaycasterResult { - btVehicleRaycasterResult() :m_distFraction(btScalar(-1.)){}; - btVector3 m_hitPointInWorld; - btVector3 m_hitNormalInWorld; - btScalar m_distFraction; + btVehicleRaycasterResult() : m_distFraction(btScalar(-1.)){}; + btVector3 m_hitPointInWorld; + btVector3 m_hitNormalInWorld; + btScalar m_distFraction; }; - virtual void* castRay(const btVector3& from,const btVector3& to, btVehicleRaycasterResult& result) = 0; - + virtual void* castRay(const btVector3& from, const btVector3& to, btVehicleRaycasterResult& result) = 0; }; -#endif //BT_VEHICLE_RAYCASTER_H - +#endif //BT_VEHICLE_RAYCASTER_H diff --git a/src/BulletDynamics/Vehicle/btWheelInfo.cpp b/src/BulletDynamics/Vehicle/btWheelInfo.cpp index ef93c16ff..d5c12f223 100644 --- a/src/BulletDynamics/Vehicle/btWheelInfo.cpp +++ b/src/BulletDynamics/Vehicle/btWheelInfo.cpp @@ -9,30 +9,26 @@ * It is provided "as is" without express or implied warranty. */ #include "btWheelInfo.h" -#include "BulletDynamics/Dynamics/btRigidBody.h" // for pointvelocity - +#include "BulletDynamics/Dynamics/btRigidBody.h" // for pointvelocity btScalar btWheelInfo::getSuspensionRestLength() const { - return m_suspensionRestLength1; - } -void btWheelInfo::updateWheel(const btRigidBody& chassis,RaycastInfo& raycastInfo) +void btWheelInfo::updateWheel(const btRigidBody& chassis, RaycastInfo& raycastInfo) { (void)raycastInfo; - if (m_raycastInfo.m_isInContact) { - btScalar project= m_raycastInfo.m_contactNormalWS.dot( m_raycastInfo.m_wheelDirectionWS ); - btVector3 chassis_velocity_at_contactPoint; + btScalar project = m_raycastInfo.m_contactNormalWS.dot(m_raycastInfo.m_wheelDirectionWS); + btVector3 chassis_velocity_at_contactPoint; btVector3 relpos = m_raycastInfo.m_contactPointWS - chassis.getCenterOfMassPosition(); - chassis_velocity_at_contactPoint = chassis.getVelocityInLocalPoint( relpos ); - btScalar projVel = m_raycastInfo.m_contactNormalWS.dot( chassis_velocity_at_contactPoint ); - if ( project >= btScalar(-0.1)) + chassis_velocity_at_contactPoint = chassis.getVelocityInLocalPoint(relpos); + btScalar projVel = m_raycastInfo.m_contactNormalWS.dot(chassis_velocity_at_contactPoint); + if (project >= btScalar(-0.1)) { m_suspensionRelativeVelocity = btScalar(0.0); m_clippedInvContactDotSuspension = btScalar(1.0) / btScalar(0.1); @@ -43,10 +39,9 @@ void btWheelInfo::updateWheel(const btRigidBody& chassis,RaycastInfo& raycastInf m_suspensionRelativeVelocity = projVel * inv; m_clippedInvContactDotSuspension = inv; } - } - else // Not in contact : position wheel in a nice (rest length) position + else // Not in contact : position wheel in a nice (rest length) position { m_raycastInfo.m_suspensionLength = this->getSuspensionRestLength(); m_suspensionRelativeVelocity = btScalar(0.0); diff --git a/src/BulletDynamics/Vehicle/btWheelInfo.h b/src/BulletDynamics/Vehicle/btWheelInfo.h index f991a57b6..af88b8ff8 100644 --- a/src/BulletDynamics/Vehicle/btWheelInfo.h +++ b/src/BulletDynamics/Vehicle/btWheelInfo.h @@ -18,20 +18,19 @@ class btRigidBody; struct btWheelInfoConstructionInfo { - btVector3 m_chassisConnectionCS; - btVector3 m_wheelDirectionCS; - btVector3 m_wheelAxleCS; - btScalar m_suspensionRestLength; - btScalar m_maxSuspensionTravelCm; - btScalar m_wheelRadius; - - btScalar m_suspensionStiffness; - btScalar m_wheelsDampingCompression; - btScalar m_wheelsDampingRelaxation; - btScalar m_frictionSlip; - btScalar m_maxSuspensionForce; + btVector3 m_chassisConnectionCS; + btVector3 m_wheelDirectionCS; + btVector3 m_wheelAxleCS; + btScalar m_suspensionRestLength; + btScalar m_maxSuspensionTravelCm; + btScalar m_wheelRadius; + + btScalar m_suspensionStiffness; + btScalar m_wheelsDampingCompression; + btScalar m_wheelsDampingRelaxation; + btScalar m_frictionSlip; + btScalar m_maxSuspensionForce; bool m_bIsFrontWheel; - }; /// btWheelInfo contains information per wheel about friction and suspension. @@ -40,51 +39,50 @@ struct btWheelInfo struct RaycastInfo { //set by raycaster - btVector3 m_contactNormalWS;//contactnormal - btVector3 m_contactPointWS;//raycast hitpoint - btScalar m_suspensionLength; - btVector3 m_hardPointWS;//raycast starting point - btVector3 m_wheelDirectionWS; //direction in worldspace - btVector3 m_wheelAxleWS; // axle in worldspace - bool m_isInContact; - void* m_groundObject; //could be general void* ptr + btVector3 m_contactNormalWS; //contactnormal + btVector3 m_contactPointWS; //raycast hitpoint + btScalar m_suspensionLength; + btVector3 m_hardPointWS; //raycast starting point + btVector3 m_wheelDirectionWS; //direction in worldspace + btVector3 m_wheelAxleWS; // axle in worldspace + bool m_isInContact; + void* m_groundObject; //could be general void* ptr }; - RaycastInfo m_raycastInfo; + RaycastInfo m_raycastInfo; - btTransform m_worldTransform; - - btVector3 m_chassisConnectionPointCS; //const - btVector3 m_wheelDirectionCS;//const - btVector3 m_wheelAxleCS; // const or modified by steering - btScalar m_suspensionRestLength1;//const - btScalar m_maxSuspensionTravelCm; + btTransform m_worldTransform; + + btVector3 m_chassisConnectionPointCS; //const + btVector3 m_wheelDirectionCS; //const + btVector3 m_wheelAxleCS; // const or modified by steering + btScalar m_suspensionRestLength1; //const + btScalar m_maxSuspensionTravelCm; btScalar getSuspensionRestLength() const; - btScalar m_wheelsRadius;//const - btScalar m_suspensionStiffness;//const - btScalar m_wheelsDampingCompression;//const - btScalar m_wheelsDampingRelaxation;//const - btScalar m_frictionSlip; - btScalar m_steering; - btScalar m_rotation; - btScalar m_deltaRotation; - btScalar m_rollInfluence; - btScalar m_maxSuspensionForce; + btScalar m_wheelsRadius; //const + btScalar m_suspensionStiffness; //const + btScalar m_wheelsDampingCompression; //const + btScalar m_wheelsDampingRelaxation; //const + btScalar m_frictionSlip; + btScalar m_steering; + btScalar m_rotation; + btScalar m_deltaRotation; + btScalar m_rollInfluence; + btScalar m_maxSuspensionForce; - btScalar m_engineForce; + btScalar m_engineForce; + + btScalar m_brake; - btScalar m_brake; - bool m_bIsFrontWheel; - - void* m_clientInfo;//can be used to store pointer to sync transforms... + + void* m_clientInfo; //can be used to store pointer to sync transforms... btWheelInfo() {} btWheelInfo(btWheelInfoConstructionInfo& ci) { - m_suspensionRestLength1 = ci.m_suspensionRestLength; m_maxSuspensionTravelCm = ci.m_maxSuspensionTravelCm; @@ -104,18 +102,15 @@ struct btWheelInfo m_rollInfluence = btScalar(0.1); m_bIsFrontWheel = ci.m_bIsFrontWheel; m_maxSuspensionForce = ci.m_maxSuspensionForce; - } - void updateWheel(const btRigidBody& chassis,RaycastInfo& raycastInfo); + void updateWheel(const btRigidBody& chassis, RaycastInfo& raycastInfo); - btScalar m_clippedInvContactDotSuspension; - btScalar m_suspensionRelativeVelocity; + btScalar m_clippedInvContactDotSuspension; + btScalar m_suspensionRelativeVelocity; //calculated by suspension - btScalar m_wheelsSuspensionForce; - btScalar m_skidInfo; - + btScalar m_wheelsSuspensionForce; + btScalar m_skidInfo; }; -#endif //BT_WHEEL_INFO_H - +#endif //BT_WHEEL_INFO_H diff --git a/src/BulletInverseDynamics/IDConfig.hpp b/src/BulletInverseDynamics/IDConfig.hpp index ebb10e7a1..b662b8015 100644 --- a/src/BulletInverseDynamics/IDConfig.hpp +++ b/src/BulletInverseDynamics/IDConfig.hpp @@ -32,10 +32,10 @@ #define BT_ID_POW(x, y) btPow(x, y) #define BT_ID_PI SIMD_PI #ifdef _WIN32 - #define BT_ID_SNPRINTF _snprintf +#define BT_ID_SNPRINTF _snprintf #else - #define BT_ID_SNPRINTF snprintf -#endif // +#define BT_ID_SNPRINTF snprintf +#endif // #endif // error messages #include "IDErrorMessages.hpp" @@ -52,8 +52,8 @@ #error "custom inverse dynamics config, but no custom namespace defined" #endif -#define BT_ID_MAX(a,b) std::max(a,b) -#define BT_ID_MIN(a,b) std::min(a,b) +#define BT_ID_MAX(a, b) std::max(a, b) +#define BT_ID_MIN(a, b) std::min(a, b) #else #define btInverseDynamics btInverseDynamicsBullet3 @@ -62,8 +62,8 @@ #include "LinearMath/btScalar.h" typedef btScalar idScalar; #include "LinearMath/btMinMax.h" -#define BT_ID_MAX(a,b) btMax(a,b) -#define BT_ID_MIN(a,b) btMin(a,b) +#define BT_ID_MAX(a, b) btMax(a, b) +#define BT_ID_MIN(a, b) btMin(a, b) #ifdef BT_USE_DOUBLE_PRECISION #define BT_ID_USE_DOUBLE_PRECISION @@ -71,31 +71,31 @@ typedef btScalar idScalar; #ifndef BT_USE_INVERSE_DYNAMICS_WITH_BULLET2 - // use bullet types for arrays and array indices #include "Bullet3Common/b3AlignedObjectArray.h" // this is to make it work with C++2003, otherwise we could do this: // template // using idArray = b3AlignedObjectArray; template -struct idArray { +struct idArray +{ typedef b3AlignedObjectArray type; }; typedef int idArrayIdx; #define ID_DECLARE_ALIGNED_ALLOCATOR() B3_DECLARE_ALIGNED_ALLOCATOR() -#else // BT_USE_INVERSE_DYNAMICS_WITH_BULLET2 +#else // BT_USE_INVERSE_DYNAMICS_WITH_BULLET2 #include "LinearMath/btAlignedObjectArray.h" template -struct idArray { +struct idArray +{ typedef btAlignedObjectArray type; }; typedef int idArrayIdx; #define ID_DECLARE_ALIGNED_ALLOCATOR() BT_DECLARE_ALIGNED_ALLOCATOR() -#endif // BT_USE_INVERSE_DYNAMICS_WITH_BULLET2 - +#endif // BT_USE_INVERSE_DYNAMICS_WITH_BULLET2 // use bullet's allocator functions #define idMalloc btAllocFunc diff --git a/src/BulletInverseDynamics/IDConfigBuiltin.hpp b/src/BulletInverseDynamics/IDConfigBuiltin.hpp index 130c19c6d..639236792 100644 --- a/src/BulletInverseDynamics/IDConfigBuiltin.hpp +++ b/src/BulletInverseDynamics/IDConfigBuiltin.hpp @@ -14,7 +14,8 @@ typedef float idScalar; // template // using idArray = std::vector; template -struct idArray { +struct idArray +{ typedef std::vector type; }; typedef std::vector::size_type idArrayIdx; @@ -23,14 +24,14 @@ typedef std::vector::size_type idArrayIdx; #define idMalloc ::malloc #define idFree ::free // currently not aligned at all... -#define ID_DECLARE_ALIGNED_ALLOCATOR() \ - inline void* operator new(std::size_t sizeInBytes) { return idMalloc(sizeInBytes); } \ - inline void operator delete(void* ptr) { idFree(ptr); } \ - inline void* operator new(std::size_t, void* ptr) { return ptr; } \ - inline void operator delete(void*, void*) {} \ - inline void* operator new[](std::size_t sizeInBytes) { return idMalloc(sizeInBytes); } \ - inline void operator delete[](void* ptr) { idFree(ptr); } \ - inline void* operator new[](std::size_t, void* ptr) { return ptr; } \ +#define ID_DECLARE_ALIGNED_ALLOCATOR() \ + inline void* operator new(std::size_t sizeInBytes) { return idMalloc(sizeInBytes); } \ + inline void operator delete(void* ptr) { idFree(ptr); } \ + inline void* operator new(std::size_t, void* ptr) { return ptr; } \ + inline void operator delete(void*, void*) {} \ + inline void* operator new[](std::size_t sizeInBytes) { return idMalloc(sizeInBytes); } \ + inline void operator delete[](void* ptr) { idFree(ptr); } \ + inline void* operator new[](std::size_t, void* ptr) { return ptr; } \ inline void operator delete[](void*, void*) {} #include "details/IDMatVec.hpp" diff --git a/src/BulletInverseDynamics/IDConfigEigen.hpp b/src/BulletInverseDynamics/IDConfigEigen.hpp index cbd7e8a9c..cfb308ee5 100644 --- a/src/BulletInverseDynamics/IDConfigEigen.hpp +++ b/src/BulletInverseDynamics/IDConfigEigen.hpp @@ -15,7 +15,8 @@ typedef float idScalar; // template // using idArray = std::vector; template -struct idArray { +struct idArray +{ typedef std::vector type; }; typedef std::vector::size_type idArrayIdx; diff --git a/src/BulletInverseDynamics/IDErrorMessages.hpp b/src/BulletInverseDynamics/IDErrorMessages.hpp index 1b3fd268a..5a98f0149 100644 --- a/src/BulletInverseDynamics/IDErrorMessages.hpp +++ b/src/BulletInverseDynamics/IDErrorMessages.hpp @@ -13,16 +13,18 @@ #else // BT_ID_WO_BULLET #include /// print error message with file/line information -#define bt_id_error_message(...) \ - do { \ - fprintf(stderr, "[Error:%s:%d] ", __INVDYN_FILE_WO_DIR__, __LINE__); \ - fprintf(stderr, __VA_ARGS__); \ +#define bt_id_error_message(...) \ + do \ + { \ + fprintf(stderr, "[Error:%s:%d] ", __INVDYN_FILE_WO_DIR__, __LINE__); \ + fprintf(stderr, __VA_ARGS__); \ } while (0) /// print warning message with file/line information -#define bt_id_warning_message(...) \ - do { \ - fprintf(stderr, "[Warning:%s:%d] ", __INVDYN_FILE_WO_DIR__, __LINE__); \ - fprintf(stderr, __VA_ARGS__); \ +#define bt_id_warning_message(...) \ + do \ + { \ + fprintf(stderr, "[Warning:%s:%d] ", __INVDYN_FILE_WO_DIR__, __LINE__); \ + fprintf(stderr, __VA_ARGS__); \ } while (0) #define id_printf(...) printf(__VA_ARGS__) #endif // BT_ID_WO_BULLET diff --git a/src/BulletInverseDynamics/IDMath.cpp b/src/BulletInverseDynamics/IDMath.cpp index d279d3435..2f120ed48 100644 --- a/src/BulletInverseDynamics/IDMath.cpp +++ b/src/BulletInverseDynamics/IDMath.cpp @@ -3,25 +3,30 @@ #include #include -namespace btInverseDynamics { +namespace btInverseDynamics +{ static const idScalar kIsZero = 5 * std::numeric_limits::epsilon(); // requirements for axis length deviation from 1.0 // experimentally set from random euler angle rotation matrices static const idScalar kAxisLengthEpsilon = 10 * kIsZero; -void setZero(vec3 &v) { +void setZero(vec3 &v) +{ v(0) = 0; v(1) = 0; v(2) = 0; } -void setZero(vecx &v) { - for (int i = 0; i < v.size(); i++) { +void setZero(vecx &v) +{ + for (int i = 0; i < v.size(); i++) + { v(i) = 0; } } -void setZero(mat33 &m) { +void setZero(mat33 &m) +{ m(0, 0) = 0; m(0, 1) = 0; m(0, 2) = 0; @@ -33,7 +38,8 @@ void setZero(mat33 &m) { m(2, 2) = 0; } -void skew(vec3& v, mat33* result) { +void skew(vec3 &v, mat33 *result) +{ (*result)(0, 0) = 0.0; (*result)(0, 1) = -v(2); (*result)(0, 2) = v(1); @@ -45,22 +51,28 @@ void skew(vec3& v, mat33* result) { (*result)(2, 2) = 0.0; } -idScalar maxAbs(const vecx &v) { +idScalar maxAbs(const vecx &v) +{ idScalar result = 0.0; - for (int i = 0; i < v.size(); i++) { + for (int i = 0; i < v.size(); i++) + { const idScalar tmp = BT_ID_FABS(v(i)); - if (tmp > result) { + if (tmp > result) + { result = tmp; } } return result; } -idScalar maxAbs(const vec3 &v) { +idScalar maxAbs(const vec3 &v) +{ idScalar result = 0.0; - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 3; i++) + { const idScalar tmp = BT_ID_FABS(v(i)); - if (tmp > result) { + if (tmp > result) + { result = tmp; } } @@ -68,60 +80,75 @@ idScalar maxAbs(const vec3 &v) { } #if (defined BT_ID_HAVE_MAT3X) -idScalar maxAbsMat3x(const mat3x &m) { - // only used for tests -- so just loop here for portability - idScalar result = 0.0; - for (idArrayIdx col = 0; col < m.cols(); col++) { - for (idArrayIdx row = 0; row < 3; row++) { - result = BT_ID_MAX(result, std::fabs(m(row, col))); - } - } - return result; +idScalar maxAbsMat3x(const mat3x &m) +{ + // only used for tests -- so just loop here for portability + idScalar result = 0.0; + for (idArrayIdx col = 0; col < m.cols(); col++) + { + for (idArrayIdx row = 0; row < 3; row++) + { + result = BT_ID_MAX(result, std::fabs(m(row, col))); + } + } + return result; } -void mul(const mat33 &a, const mat3x &b, mat3x *result) { - if (b.cols() != result->cols()) { - bt_id_error_message("size missmatch. b.cols()= %d, result->cols()= %d\n", - static_cast(b.cols()), static_cast(result->cols())); - abort(); - } +void mul(const mat33 &a, const mat3x &b, mat3x *result) +{ + if (b.cols() != result->cols()) + { + bt_id_error_message("size missmatch. b.cols()= %d, result->cols()= %d\n", + static_cast(b.cols()), static_cast(result->cols())); + abort(); + } - for (idArrayIdx col = 0; col < b.cols(); col++) { - const idScalar x = a(0,0)*b(0,col)+a(0,1)*b(1,col)+a(0,2)*b(2,col); - const idScalar y = a(1,0)*b(0,col)+a(1,1)*b(1,col)+a(1,2)*b(2,col); - const idScalar z = a(2,0)*b(0,col)+a(2,1)*b(1,col)+a(2,2)*b(2,col); - setMat3xElem(0, col, x, result); - setMat3xElem(1, col, y, result); - setMat3xElem(2, col, z, result); - } + for (idArrayIdx col = 0; col < b.cols(); col++) + { + const idScalar x = a(0, 0) * b(0, col) + a(0, 1) * b(1, col) + a(0, 2) * b(2, col); + const idScalar y = a(1, 0) * b(0, col) + a(1, 1) * b(1, col) + a(1, 2) * b(2, col); + const idScalar z = a(2, 0) * b(0, col) + a(2, 1) * b(1, col) + a(2, 2) * b(2, col); + setMat3xElem(0, col, x, result); + setMat3xElem(1, col, y, result); + setMat3xElem(2, col, z, result); + } } -void add(const mat3x &a, const mat3x &b, mat3x *result) { - if (a.cols() != b.cols()) { - bt_id_error_message("size missmatch. a.cols()= %d, b.cols()= %d\n", - static_cast(a.cols()), static_cast(b.cols())); - abort(); - } - for (idArrayIdx col = 0; col < b.cols(); col++) { - for (idArrayIdx row = 0; row < 3; row++) { - setMat3xElem(row, col, a(row, col) + b(row, col), result); - } - } +void add(const mat3x &a, const mat3x &b, mat3x *result) +{ + if (a.cols() != b.cols()) + { + bt_id_error_message("size missmatch. a.cols()= %d, b.cols()= %d\n", + static_cast(a.cols()), static_cast(b.cols())); + abort(); + } + for (idArrayIdx col = 0; col < b.cols(); col++) + { + for (idArrayIdx row = 0; row < 3; row++) + { + setMat3xElem(row, col, a(row, col) + b(row, col), result); + } + } } -void sub(const mat3x &a, const mat3x &b, mat3x *result) { - if (a.cols() != b.cols()) { - bt_id_error_message("size missmatch. a.cols()= %d, b.cols()= %d\n", - static_cast(a.cols()), static_cast(b.cols())); - abort(); - } - for (idArrayIdx col = 0; col < b.cols(); col++) { - for (idArrayIdx row = 0; row < 3; row++) { - setMat3xElem(row, col, a(row, col) - b(row, col), result); - } - } +void sub(const mat3x &a, const mat3x &b, mat3x *result) +{ + if (a.cols() != b.cols()) + { + bt_id_error_message("size missmatch. a.cols()= %d, b.cols()= %d\n", + static_cast(a.cols()), static_cast(b.cols())); + abort(); + } + for (idArrayIdx col = 0; col < b.cols(); col++) + { + for (idArrayIdx row = 0; row < 3; row++) + { + setMat3xElem(row, col, a(row, col) - b(row, col), result); + } + } } #endif -mat33 transformX(const idScalar &alpha) { +mat33 transformX(const idScalar &alpha) +{ mat33 T; const idScalar cos_alpha = BT_ID_COS(alpha); const idScalar sin_alpha = BT_ID_SIN(alpha); @@ -143,7 +170,8 @@ mat33 transformX(const idScalar &alpha) { return T; } -mat33 transformY(const idScalar &beta) { +mat33 transformY(const idScalar &beta) +{ mat33 T; const idScalar cos_beta = BT_ID_COS(beta); const idScalar sin_beta = BT_ID_SIN(beta); @@ -165,7 +193,8 @@ mat33 transformY(const idScalar &beta) { return T; } -mat33 transformZ(const idScalar &gamma) { +mat33 transformZ(const idScalar &gamma) +{ mat33 T; const idScalar cos_gamma = BT_ID_COS(gamma); const idScalar sin_gamma = BT_ID_SIN(gamma); @@ -187,7 +216,8 @@ mat33 transformZ(const idScalar &gamma) { return T; } -mat33 tildeOperator(const vec3 &v) { +mat33 tildeOperator(const vec3 &v) +{ mat33 m; m(0, 0) = 0.0; m(0, 1) = -v(2); @@ -201,7 +231,8 @@ mat33 tildeOperator(const vec3 &v) { return m; } -void getVecMatFromDH(idScalar theta, idScalar d, idScalar a, idScalar alpha, vec3 *r, mat33 *T) { +void getVecMatFromDH(idScalar theta, idScalar d, idScalar a, idScalar alpha, vec3 *r, mat33 *T) +{ const idScalar sa = BT_ID_SIN(alpha); const idScalar ca = BT_ID_COS(alpha); const idScalar st = BT_ID_SIN(theta); @@ -224,7 +255,8 @@ void getVecMatFromDH(idScalar theta, idScalar d, idScalar a, idScalar alpha, vec (*T)(2, 2) = ca; } -void bodyTParentFromAxisAngle(const vec3 &axis, const idScalar &angle, mat33 *T) { +void bodyTParentFromAxisAngle(const vec3 &axis, const idScalar &angle, mat33 *T) +{ const idScalar c = BT_ID_COS(angle); const idScalar s = -BT_ID_SIN(angle); const idScalar one_m_c = 1.0 - c; @@ -246,175 +278,214 @@ void bodyTParentFromAxisAngle(const vec3 &axis, const idScalar &angle, mat33 *T) (*T)(2, 2) = z * z * one_m_c + c; } -bool isPositiveDefinite(const mat33 &m) { +bool isPositiveDefinite(const mat33 &m) +{ // test if all upper left determinants are positive - if (m(0, 0) <= 0) { // upper 1x1 + if (m(0, 0) <= 0) + { // upper 1x1 return false; } - if (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0) <= 0) { // upper 2x2 + if (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0) <= 0) + { // upper 2x2 return false; } if ((m(0, 0) * (m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1)) - m(0, 1) * (m(1, 0) * m(2, 2) - m(1, 2) * m(2, 0)) + - m(0, 2) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0))) < 0) { + m(0, 2) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0))) < 0) + { return false; } return true; } -bool isPositiveSemiDefinite(const mat33 &m) { +bool isPositiveSemiDefinite(const mat33 &m) +{ // test if all upper left determinants are positive - if (m(0, 0) < 0) { // upper 1x1 + if (m(0, 0) < 0) + { // upper 1x1 return false; } - if (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0) < 0) { // upper 2x2 + if (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0) < 0) + { // upper 2x2 return false; } if ((m(0, 0) * (m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1)) - m(0, 1) * (m(1, 0) * m(2, 2) - m(1, 2) * m(2, 0)) + - m(0, 2) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0))) < 0) { + m(0, 2) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0))) < 0) + { return false; } return true; } -bool isPositiveSemiDefiniteFuzzy(const mat33 &m) { +bool isPositiveSemiDefiniteFuzzy(const mat33 &m) +{ // test if all upper left determinants are positive - if (m(0, 0) < -kIsZero) { // upper 1x1 + if (m(0, 0) < -kIsZero) + { // upper 1x1 return false; } - if (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0) < -kIsZero) { // upper 2x2 + if (m(0, 0) * m(1, 1) - m(0, 1) * m(1, 0) < -kIsZero) + { // upper 2x2 return false; } if ((m(0, 0) * (m(1, 1) * m(2, 2) - m(1, 2) * m(2, 1)) - m(0, 1) * (m(1, 0) * m(2, 2) - m(1, 2) * m(2, 0)) + - m(0, 2) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0))) < -kIsZero) { + m(0, 2) * (m(1, 0) * m(2, 1) - m(1, 1) * m(2, 0))) < -kIsZero) + { return false; } return true; } -idScalar determinant(const mat33 &m) { +idScalar determinant(const mat33 &m) +{ return m(0, 0) * m(1, 1) * m(2, 2) + m(0, 1) * m(1, 2) * m(2, 0) + m(0, 2) * m(1, 0) * m(2, 1) - m(0, 2) * m(1, 1) * m(2, 0) - m(0, 0) * m(1, 2) * m(2, 1) - m(0, 1) * m(1, 0) * m(2, 2); } -bool isValidInertiaMatrix(const mat33 &I, const int index, bool has_fixed_joint) { +bool isValidInertiaMatrix(const mat33 &I, const int index, bool has_fixed_joint) +{ // TODO(Thomas) do we really want this? // in cases where the inertia tensor about the center of mass is zero, // the determinant of the inertia tensor about the joint axis is almost // zero and can have a very small negative value. - if (!isPositiveSemiDefiniteFuzzy(I)) { - bt_id_error_message("invalid inertia matrix for body %d, not positive definite " - "(fixed joint)\n", - index); - bt_id_error_message("matrix is:\n" - "[%.20e %.20e %.20e;\n" - "%.20e %.20e %.20e;\n" - "%.20e %.20e %.20e]\n", - I(0, 0), I(0, 1), I(0, 2), I(1, 0), I(1, 1), I(1, 2), I(2, 0), I(2, 1), - I(2, 2)); + if (!isPositiveSemiDefiniteFuzzy(I)) + { + bt_id_error_message( + "invalid inertia matrix for body %d, not positive definite " + "(fixed joint)\n", + index); + bt_id_error_message( + "matrix is:\n" + "[%.20e %.20e %.20e;\n" + "%.20e %.20e %.20e;\n" + "%.20e %.20e %.20e]\n", + I(0, 0), I(0, 1), I(0, 2), I(1, 0), I(1, 1), I(1, 2), I(2, 0), I(2, 1), + I(2, 2)); return false; } // check triangle inequality, must have I(i,i)+I(j,j)>=I(k,k) - if (!has_fixed_joint) { - if (I(0, 0) + I(1, 1) < I(2, 2)) { + if (!has_fixed_joint) + { + if (I(0, 0) + I(1, 1) < I(2, 2)) + { bt_id_error_message("invalid inertia tensor for body %d, I(0,0) + I(1,1) < I(2,2)\n", index); - bt_id_error_message("matrix is:\n" - "[%.20e %.20e %.20e;\n" - "%.20e %.20e %.20e;\n" - "%.20e %.20e %.20e]\n", - I(0, 0), I(0, 1), I(0, 2), I(1, 0), I(1, 1), I(1, 2), I(2, 0), I(2, 1), - I(2, 2)); + bt_id_error_message( + "matrix is:\n" + "[%.20e %.20e %.20e;\n" + "%.20e %.20e %.20e;\n" + "%.20e %.20e %.20e]\n", + I(0, 0), I(0, 1), I(0, 2), I(1, 0), I(1, 1), I(1, 2), I(2, 0), I(2, 1), + I(2, 2)); return false; } - if (I(0, 0) + I(1, 1) < I(2, 2)) { + if (I(0, 0) + I(1, 1) < I(2, 2)) + { bt_id_error_message("invalid inertia tensor for body %d, I(0,0) + I(1,1) < I(2,2)\n", index); - bt_id_error_message("matrix is:\n" - "[%.20e %.20e %.20e;\n" - "%.20e %.20e %.20e;\n" - "%.20e %.20e %.20e]\n", - I(0, 0), I(0, 1), I(0, 2), I(1, 0), I(1, 1), I(1, 2), I(2, 0), I(2, 1), - I(2, 2)); + bt_id_error_message( + "matrix is:\n" + "[%.20e %.20e %.20e;\n" + "%.20e %.20e %.20e;\n" + "%.20e %.20e %.20e]\n", + I(0, 0), I(0, 1), I(0, 2), I(1, 0), I(1, 1), I(1, 2), I(2, 0), I(2, 1), + I(2, 2)); return false; } - if (I(1, 1) + I(2, 2) < I(0, 0)) { + if (I(1, 1) + I(2, 2) < I(0, 0)) + { bt_id_error_message("invalid inertia tensor for body %d, I(1,1) + I(2,2) < I(0,0)\n", index); - bt_id_error_message("matrix is:\n" - "[%.20e %.20e %.20e;\n" - "%.20e %.20e %.20e;\n" - "%.20e %.20e %.20e]\n", - I(0, 0), I(0, 1), I(0, 2), I(1, 0), I(1, 1), I(1, 2), I(2, 0), I(2, 1), - I(2, 2)); + bt_id_error_message( + "matrix is:\n" + "[%.20e %.20e %.20e;\n" + "%.20e %.20e %.20e;\n" + "%.20e %.20e %.20e]\n", + I(0, 0), I(0, 1), I(0, 2), I(1, 0), I(1, 1), I(1, 2), I(2, 0), I(2, 1), + I(2, 2)); return false; } } // check positive/zero diagonal elements - for (int i = 0; i < 3; i++) { - if (I(i, i) < 0) { // accept zero + for (int i = 0; i < 3; i++) + { + if (I(i, i) < 0) + { // accept zero bt_id_error_message("invalid inertia tensor, I(%d,%d)= %e <0\n", i, i, I(i, i)); return false; } } // check symmetry - if (BT_ID_FABS(I(1, 0) - I(0, 1)) > kIsZero) { - bt_id_error_message("invalid inertia tensor for body %d I(1,0)!=I(0,1). I(1,0)-I(0,1)= " - "%e\n", - index, I(1, 0) - I(0, 1)); + if (BT_ID_FABS(I(1, 0) - I(0, 1)) > kIsZero) + { + bt_id_error_message( + "invalid inertia tensor for body %d I(1,0)!=I(0,1). I(1,0)-I(0,1)= " + "%e\n", + index, I(1, 0) - I(0, 1)); return false; } - if (BT_ID_FABS(I(2, 0) - I(0, 2)) > kIsZero) { - bt_id_error_message("invalid inertia tensor for body %d I(2,0)!=I(0,2). I(2,0)-I(0,2)= " - "%e\n", - index, I(2, 0) - I(0, 2)); + if (BT_ID_FABS(I(2, 0) - I(0, 2)) > kIsZero) + { + bt_id_error_message( + "invalid inertia tensor for body %d I(2,0)!=I(0,2). I(2,0)-I(0,2)= " + "%e\n", + index, I(2, 0) - I(0, 2)); return false; } - if (BT_ID_FABS(I(1, 2) - I(2, 1)) > kIsZero) { + if (BT_ID_FABS(I(1, 2) - I(2, 1)) > kIsZero) + { bt_id_error_message("invalid inertia tensor body %d I(1,2)!=I(2,1). I(1,2)-I(2,1)= %e\n", index, - I(1, 2) - I(2, 1)); + I(1, 2) - I(2, 1)); return false; } return true; } -bool isValidTransformMatrix(const mat33 &m) { -#define print_mat(x) \ - bt_id_error_message("matrix is [%e, %e, %e; %e, %e, %e; %e, %e, %e]\n", x(0, 0), x(0, 1), x(0, 2), \ - x(1, 0), x(1, 1), x(1, 2), x(2, 0), x(2, 1), x(2, 2)) +bool isValidTransformMatrix(const mat33 &m) +{ +#define print_mat(x) \ + bt_id_error_message("matrix is [%e, %e, %e; %e, %e, %e; %e, %e, %e]\n", x(0, 0), x(0, 1), x(0, 2), \ + x(1, 0), x(1, 1), x(1, 2), x(2, 0), x(2, 1), x(2, 2)) // check for unit length column vectors - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 3; i++) + { const idScalar length_minus_1 = BT_ID_FABS(m(0, i) * m(0, i) + m(1, i) * m(1, i) + m(2, i) * m(2, i) - 1.0); - if (length_minus_1 > kAxisLengthEpsilon) { - bt_id_error_message("Not a valid rotation matrix (column %d not unit length)\n" - "column = [%.18e %.18e %.18e]\n" - "length-1.0= %.18e\n", - i, m(0, i), m(1, i), m(2, i), length_minus_1); + if (length_minus_1 > kAxisLengthEpsilon) + { + bt_id_error_message( + "Not a valid rotation matrix (column %d not unit length)\n" + "column = [%.18e %.18e %.18e]\n" + "length-1.0= %.18e\n", + i, m(0, i), m(1, i), m(2, i), length_minus_1); print_mat(m); return false; } } // check for orthogonal column vectors - if (BT_ID_FABS(m(0, 0) * m(0, 1) + m(1, 0) * m(1, 1) + m(2, 0) * m(2, 1)) > kAxisLengthEpsilon) { + if (BT_ID_FABS(m(0, 0) * m(0, 1) + m(1, 0) * m(1, 1) + m(2, 0) * m(2, 1)) > kAxisLengthEpsilon) + { bt_id_error_message("Not a valid rotation matrix (columns 0 and 1 not orthogonal)\n"); print_mat(m); return false; } - if (BT_ID_FABS(m(0, 0) * m(0, 2) + m(1, 0) * m(1, 2) + m(2, 0) * m(2, 2)) > kAxisLengthEpsilon) { + if (BT_ID_FABS(m(0, 0) * m(0, 2) + m(1, 0) * m(1, 2) + m(2, 0) * m(2, 2)) > kAxisLengthEpsilon) + { bt_id_error_message("Not a valid rotation matrix (columns 0 and 2 not orthogonal)\n"); print_mat(m); return false; } - if (BT_ID_FABS(m(0, 1) * m(0, 2) + m(1, 1) * m(1, 2) + m(2, 1) * m(2, 2)) > kAxisLengthEpsilon) { + if (BT_ID_FABS(m(0, 1) * m(0, 2) + m(1, 1) * m(1, 2) + m(2, 1) * m(2, 2)) > kAxisLengthEpsilon) + { bt_id_error_message("Not a valid rotation matrix (columns 0 and 2 not orthogonal)\n"); print_mat(m); return false; } // check determinant (rotation not reflection) - if (determinant(m) <= 0) { + if (determinant(m) <= 0) + { bt_id_error_message("Not a valid rotation matrix (determinant <=0)\n"); print_mat(m); return false; @@ -422,16 +493,18 @@ bool isValidTransformMatrix(const mat33 &m) { return true; } -bool isUnitVector(const vec3 &vector) { +bool isUnitVector(const vec3 &vector) +{ return BT_ID_FABS(vector(0) * vector(0) + vector(1) * vector(1) + vector(2) * vector(2) - 1.0) < kIsZero; } -vec3 rpyFromMatrix(const mat33 &rot) { +vec3 rpyFromMatrix(const mat33 &rot) +{ vec3 rpy; rpy(2) = BT_ID_ATAN2(-rot(1, 0), rot(0, 0)); rpy(1) = BT_ID_ATAN2(rot(2, 0), BT_ID_COS(rpy(2)) * rot(0, 0) - BT_ID_SIN(rpy(0)) * rot(1, 0)); rpy(0) = BT_ID_ATAN2(-rot(2, 0), rot(2, 2)); return rpy; } -} +} // namespace btInverseDynamics diff --git a/src/BulletInverseDynamics/IDMath.hpp b/src/BulletInverseDynamics/IDMath.hpp index b355474d4..40bee5302 100644 --- a/src/BulletInverseDynamics/IDMath.hpp +++ b/src/BulletInverseDynamics/IDMath.hpp @@ -5,7 +5,8 @@ #define IDMATH_HPP_ #include "IDConfig.hpp" -namespace btInverseDynamics { +namespace btInverseDynamics +{ /// set all elements to zero void setZero(vec3& v); /// set all elements to zero @@ -23,11 +24,11 @@ idScalar maxAbs(const vec3& v); #if (defined BT_ID_HAVE_MAT3X) idScalar maxAbsMat3x(const mat3x& m); -void setZero(mat3x&m); +void setZero(mat3x& m); // define math functions on mat3x here to avoid allocations in operators. -void mul(const mat33&a, const mat3x&b, mat3x* result); -void add(const mat3x&a, const mat3x&b, mat3x* result); -void sub(const mat3x&a, const mat3x&b, mat3x* result); +void mul(const mat33& a, const mat3x& b, mat3x* result); +void add(const mat3x& a, const mat3x& b, mat3x* result); +void sub(const mat3x& a, const mat3x& b, mat3x* result); #endif /// get offset vector & transform matrix from DH parameters @@ -94,6 +95,6 @@ mat33 transformZ(const idScalar& gamma); ///calculate rpy angles (x-y-z Euler angles) from a given rotation matrix /// @param rot rotation matrix /// @returns x-y-z Euler angles -vec3 rpyFromMatrix(const mat33&rot); -} +vec3 rpyFromMatrix(const mat33& rot); +} // namespace btInverseDynamics #endif // IDMATH_HPP_ diff --git a/src/BulletInverseDynamics/MultiBodyTree.cpp b/src/BulletInverseDynamics/MultiBodyTree.cpp index becfe0f4a..dadf0bab0 100644 --- a/src/BulletInverseDynamics/MultiBodyTree.cpp +++ b/src/BulletInverseDynamics/MultiBodyTree.cpp @@ -8,69 +8,84 @@ #include "details/MultiBodyTreeImpl.hpp" #include "details/MultiBodyTreeInitCache.hpp" -namespace btInverseDynamics { - +namespace btInverseDynamics +{ MultiBodyTree::MultiBodyTree() : m_is_finalized(false), m_mass_parameters_are_valid(true), m_accept_invalid_mass_parameters(false), m_impl(0x0), - m_init_cache(0x0) { + m_init_cache(0x0) +{ m_init_cache = new InitCache(); } -MultiBodyTree::~MultiBodyTree() { +MultiBodyTree::~MultiBodyTree() +{ delete m_impl; delete m_init_cache; } -void MultiBodyTree::setAcceptInvalidMassParameters(bool flag) { +void MultiBodyTree::setAcceptInvalidMassParameters(bool flag) +{ m_accept_invalid_mass_parameters = flag; } -bool MultiBodyTree::getAcceptInvalidMassProperties() const { +bool MultiBodyTree::getAcceptInvalidMassProperties() const +{ return m_accept_invalid_mass_parameters; } -int MultiBodyTree::getBodyOrigin(const int body_index, vec3 *world_origin) const { +int MultiBodyTree::getBodyOrigin(const int body_index, vec3 *world_origin) const +{ return m_impl->getBodyOrigin(body_index, world_origin); } -int MultiBodyTree::getBodyCoM(const int body_index, vec3 *world_com) const { +int MultiBodyTree::getBodyCoM(const int body_index, vec3 *world_com) const +{ return m_impl->getBodyCoM(body_index, world_com); } -int MultiBodyTree::getBodyTransform(const int body_index, mat33 *world_T_body) const { +int MultiBodyTree::getBodyTransform(const int body_index, mat33 *world_T_body) const +{ return m_impl->getBodyTransform(body_index, world_T_body); } -int MultiBodyTree::getBodyAngularVelocity(const int body_index, vec3 *world_omega) const { +int MultiBodyTree::getBodyAngularVelocity(const int body_index, vec3 *world_omega) const +{ return m_impl->getBodyAngularVelocity(body_index, world_omega); } -int MultiBodyTree::getBodyLinearVelocity(const int body_index, vec3 *world_velocity) const { +int MultiBodyTree::getBodyLinearVelocity(const int body_index, vec3 *world_velocity) const +{ return m_impl->getBodyLinearVelocity(body_index, world_velocity); } -int MultiBodyTree::getBodyLinearVelocityCoM(const int body_index, vec3 *world_velocity) const { +int MultiBodyTree::getBodyLinearVelocityCoM(const int body_index, vec3 *world_velocity) const +{ return m_impl->getBodyLinearVelocityCoM(body_index, world_velocity); } -int MultiBodyTree::getBodyAngularAcceleration(const int body_index, vec3 *world_dot_omega) const { +int MultiBodyTree::getBodyAngularAcceleration(const int body_index, vec3 *world_dot_omega) const +{ return m_impl->getBodyAngularAcceleration(body_index, world_dot_omega); } -int MultiBodyTree::getBodyLinearAcceleration(const int body_index, vec3 *world_acceleration) const { +int MultiBodyTree::getBodyLinearAcceleration(const int body_index, vec3 *world_acceleration) const +{ return m_impl->getBodyLinearAcceleration(body_index, world_acceleration); } -int MultiBodyTree::getParentRParentBodyRef(const int body_index, vec3* r) const { - return m_impl->getParentRParentBodyRef(body_index, r); +int MultiBodyTree::getParentRParentBodyRef(const int body_index, vec3 *r) const +{ + return m_impl->getParentRParentBodyRef(body_index, r); } -int MultiBodyTree::getBodyTParentRef(const int body_index, mat33* T) const { - return m_impl->getBodyTParentRef(body_index, T); +int MultiBodyTree::getBodyTParentRef(const int body_index, mat33 *T) const +{ + return m_impl->getBodyTParentRef(body_index, T); } -int MultiBodyTree::getBodyAxisOfMotion(const int body_index, vec3* axis) const { - return m_impl->getBodyAxisOfMotion(body_index, axis); +int MultiBodyTree::getBodyAxisOfMotion(const int body_index, vec3 *axis) const +{ + return m_impl->getBodyAxisOfMotion(body_index, axis); } void MultiBodyTree::printTree() { m_impl->printTree(); } @@ -81,12 +96,15 @@ int MultiBodyTree::numBodies() const { return m_impl->m_num_bodies; } int MultiBodyTree::numDoFs() const { return m_impl->m_num_dofs; } int MultiBodyTree::calculateInverseDynamics(const vecx &q, const vecx &u, const vecx &dot_u, - vecx *joint_forces) { - if (false == m_is_finalized) { + vecx *joint_forces) +{ + if (false == m_is_finalized) + { bt_id_error_message("system has not been initialized\n"); return -1; } - if (-1 == m_impl->calculateInverseDynamics(q, u, dot_u, joint_forces)) { + if (-1 == m_impl->calculateInverseDynamics(q, u, dot_u, joint_forces)) + { bt_id_error_message("error in inverse dynamics calculation\n"); return -1; } @@ -95,141 +113,164 @@ int MultiBodyTree::calculateInverseDynamics(const vecx &q, const vecx &u, const int MultiBodyTree::calculateMassMatrix(const vecx &q, const bool update_kinematics, const bool initialize_matrix, - const bool set_lower_triangular_matrix, matxx *mass_matrix) { - if (false == m_is_finalized) { + const bool set_lower_triangular_matrix, matxx *mass_matrix) +{ + if (false == m_is_finalized) + { bt_id_error_message("system has not been initialized\n"); return -1; } if (-1 == m_impl->calculateMassMatrix(q, update_kinematics, initialize_matrix, - set_lower_triangular_matrix, mass_matrix)) { + set_lower_triangular_matrix, mass_matrix)) + { bt_id_error_message("error in mass matrix calculation\n"); return -1; } return 0; } -int MultiBodyTree::calculateMassMatrix(const vecx &q, matxx *mass_matrix) { +int MultiBodyTree::calculateMassMatrix(const vecx &q, matxx *mass_matrix) +{ return calculateMassMatrix(q, true, true, true, mass_matrix); } +int MultiBodyTree::calculateKinematics(const vecx &q, const vecx &u, const vecx &dot_u) +{ + vec3 world_gravity(m_impl->m_world_gravity); + // temporarily set gravity to zero, to ensure we get the actual accelerations + setZero(m_impl->m_world_gravity); + if (false == m_is_finalized) + { + bt_id_error_message("system has not been initialized\n"); + return -1; + } + if (-1 == m_impl->calculateKinematics(q, u, dot_u, + MultiBodyTree::MultiBodyImpl::POSITION_VELOCITY_ACCELERATION)) + { + bt_id_error_message("error in kinematics calculation\n"); + return -1; + } -int MultiBodyTree::calculateKinematics(const vecx& q, const vecx& u, const vecx& dot_u) { - vec3 world_gravity(m_impl->m_world_gravity); - // temporarily set gravity to zero, to ensure we get the actual accelerations - setZero(m_impl->m_world_gravity); - - if (false == m_is_finalized) { - bt_id_error_message("system has not been initialized\n"); - return -1; - } - if (-1 == m_impl->calculateKinematics(q, u, dot_u, - MultiBodyTree::MultiBodyImpl::POSITION_VELOCITY_ACCELERATION)) { - bt_id_error_message("error in kinematics calculation\n"); - return -1; - } - - m_impl->m_world_gravity=world_gravity; - return 0; + m_impl->m_world_gravity = world_gravity; + return 0; } - -int MultiBodyTree::calculatePositionKinematics(const vecx& q) { - if (false == m_is_finalized) { +int MultiBodyTree::calculatePositionKinematics(const vecx &q) +{ + if (false == m_is_finalized) + { bt_id_error_message("system has not been initialized\n"); return -1; } if (-1 == m_impl->calculateKinematics(q, q, q, - MultiBodyTree::MultiBodyImpl::POSITION_VELOCITY)) { + MultiBodyTree::MultiBodyImpl::POSITION_VELOCITY)) + { bt_id_error_message("error in kinematics calculation\n"); return -1; } return 0; } -int MultiBodyTree::calculatePositionAndVelocityKinematics(const vecx& q, const vecx& u) { - if (false == m_is_finalized) { +int MultiBodyTree::calculatePositionAndVelocityKinematics(const vecx &q, const vecx &u) +{ + if (false == m_is_finalized) + { bt_id_error_message("system has not been initialized\n"); return -1; } if (-1 == m_impl->calculateKinematics(q, u, u, - MultiBodyTree::MultiBodyImpl::POSITION_VELOCITY)) { + MultiBodyTree::MultiBodyImpl::POSITION_VELOCITY)) + { bt_id_error_message("error in kinematics calculation\n"); return -1; } return 0; } - #if (defined BT_ID_HAVE_MAT3X) && (defined BT_ID_WITH_JACOBIANS) -int MultiBodyTree::calculateJacobians(const vecx& q, const vecx& u) { - if (false == m_is_finalized) { - bt_id_error_message("system has not been initialized\n"); - return -1; - } - if (-1 == m_impl->calculateJacobians(q, u, - MultiBodyTree::MultiBodyImpl::POSITION_VELOCITY)) { - bt_id_error_message("error in jacobian calculation\n"); - return -1; - } - return 0; +int MultiBodyTree::calculateJacobians(const vecx &q, const vecx &u) +{ + if (false == m_is_finalized) + { + bt_id_error_message("system has not been initialized\n"); + return -1; + } + if (-1 == m_impl->calculateJacobians(q, u, + MultiBodyTree::MultiBodyImpl::POSITION_VELOCITY)) + { + bt_id_error_message("error in jacobian calculation\n"); + return -1; + } + return 0; } -int MultiBodyTree::calculateJacobians(const vecx& q){ - if (false == m_is_finalized) { - bt_id_error_message("system has not been initialized\n"); - return -1; - } - if (-1 == m_impl->calculateJacobians(q, q, - MultiBodyTree::MultiBodyImpl::POSITION_ONLY)) { - bt_id_error_message("error in jacobian calculation\n"); - return -1; - } - return 0; +int MultiBodyTree::calculateJacobians(const vecx &q) +{ + if (false == m_is_finalized) + { + bt_id_error_message("system has not been initialized\n"); + return -1; + } + if (-1 == m_impl->calculateJacobians(q, q, + MultiBodyTree::MultiBodyImpl::POSITION_ONLY)) + { + bt_id_error_message("error in jacobian calculation\n"); + return -1; + } + return 0; } -int MultiBodyTree::getBodyDotJacobianTransU(const int body_index, vec3* world_dot_jac_trans_u) const { - return m_impl->getBodyDotJacobianTransU(body_index,world_dot_jac_trans_u); +int MultiBodyTree::getBodyDotJacobianTransU(const int body_index, vec3 *world_dot_jac_trans_u) const +{ + return m_impl->getBodyDotJacobianTransU(body_index, world_dot_jac_trans_u); } -int MultiBodyTree::getBodyDotJacobianRotU(const int body_index, vec3* world_dot_jac_rot_u) const { - return m_impl->getBodyDotJacobianRotU(body_index,world_dot_jac_rot_u); +int MultiBodyTree::getBodyDotJacobianRotU(const int body_index, vec3 *world_dot_jac_rot_u) const +{ + return m_impl->getBodyDotJacobianRotU(body_index, world_dot_jac_rot_u); } -int MultiBodyTree::getBodyJacobianTrans(const int body_index, mat3x* world_jac_trans) const { - return m_impl->getBodyJacobianTrans(body_index,world_jac_trans); +int MultiBodyTree::getBodyJacobianTrans(const int body_index, mat3x *world_jac_trans) const +{ + return m_impl->getBodyJacobianTrans(body_index, world_jac_trans); } -int MultiBodyTree::getBodyJacobianRot(const int body_index, mat3x* world_jac_rot) const { - return m_impl->getBodyJacobianRot(body_index,world_jac_rot); +int MultiBodyTree::getBodyJacobianRot(const int body_index, mat3x *world_jac_rot) const +{ + return m_impl->getBodyJacobianRot(body_index, world_jac_rot); } - #endif int MultiBodyTree::addBody(int body_index, int parent_index, JointType joint_type, const vec3 &parent_r_parent_body_ref, const mat33 &body_T_parent_ref, const vec3 &body_axis_of_motion_, idScalar mass, const vec3 &body_r_body_com, const mat33 &body_I_body, - const int user_int, void *user_ptr) { - if (body_index < 0) { + const int user_int, void *user_ptr) +{ + if (body_index < 0) + { bt_id_error_message("body index must be positive (got %d)\n", body_index); return -1; } vec3 body_axis_of_motion(body_axis_of_motion_); - switch (joint_type) { + switch (joint_type) + { case REVOLUTE: case PRISMATIC: // check if axis is unit vector - if (!isUnitVector(body_axis_of_motion)) { + if (!isUnitVector(body_axis_of_motion)) + { bt_id_warning_message( "axis of motion not a unit axis ([%f %f %f]), will use normalized vector\n", body_axis_of_motion(0), body_axis_of_motion(1), body_axis_of_motion(2)); idScalar length = BT_ID_SQRT(BT_ID_POW(body_axis_of_motion(0), 2) + - BT_ID_POW(body_axis_of_motion(1), 2) + - BT_ID_POW(body_axis_of_motion(2), 2)); - if (length < BT_ID_SQRT(std::numeric_limits::min())) { + BT_ID_POW(body_axis_of_motion(1), 2) + + BT_ID_POW(body_axis_of_motion(2), 2)); + if (length < BT_ID_SQRT(std::numeric_limits::min())) + { bt_id_error_message("axis of motion vector too short (%e)\n", length); return -1; } @@ -246,23 +287,28 @@ int MultiBodyTree::addBody(int body_index, int parent_index, JointType joint_typ } // sanity check for mass properties. Zero mass is OK. - if (mass < 0) { + if (mass < 0) + { m_mass_parameters_are_valid = false; bt_id_error_message("Body %d has invalid mass %e\n", body_index, mass); - if (!m_accept_invalid_mass_parameters) { + if (!m_accept_invalid_mass_parameters) + { return -1; } } - if (!isValidInertiaMatrix(body_I_body, body_index, FIXED == joint_type)) { + if (!isValidInertiaMatrix(body_I_body, body_index, FIXED == joint_type)) + { m_mass_parameters_are_valid = false; // error message printed in function call - if (!m_accept_invalid_mass_parameters) { + if (!m_accept_invalid_mass_parameters) + { return -1; } } - if (!isValidTransformMatrix(body_T_parent_ref)) { + if (!isValidTransformMatrix(body_T_parent_ref)) + { return -1; } @@ -271,52 +317,63 @@ int MultiBodyTree::addBody(int body_index, int parent_index, JointType joint_typ body_I_body, user_int, user_ptr); } -int MultiBodyTree::getParentIndex(const int body_index, int *parent_index) const { +int MultiBodyTree::getParentIndex(const int body_index, int *parent_index) const +{ return m_impl->getParentIndex(body_index, parent_index); } -int MultiBodyTree::getUserInt(const int body_index, int *user_int) const { +int MultiBodyTree::getUserInt(const int body_index, int *user_int) const +{ return m_impl->getUserInt(body_index, user_int); } -int MultiBodyTree::getUserPtr(const int body_index, void **user_ptr) const { +int MultiBodyTree::getUserPtr(const int body_index, void **user_ptr) const +{ return m_impl->getUserPtr(body_index, user_ptr); } -int MultiBodyTree::setUserInt(const int body_index, const int user_int) { +int MultiBodyTree::setUserInt(const int body_index, const int user_int) +{ return m_impl->setUserInt(body_index, user_int); } -int MultiBodyTree::setUserPtr(const int body_index, void *const user_ptr) { +int MultiBodyTree::setUserPtr(const int body_index, void *const user_ptr) +{ return m_impl->setUserPtr(body_index, user_ptr); } -int MultiBodyTree::finalize() { +int MultiBodyTree::finalize() +{ const int &num_bodies = m_init_cache->numBodies(); const int &num_dofs = m_init_cache->numDoFs(); - if(num_dofs<=0) { - bt_id_error_message("Need num_dofs>=1, but num_dofs= %d\n", num_dofs); - //return -1; - } + if (num_dofs <= 0) + { + bt_id_error_message("Need num_dofs>=1, but num_dofs= %d\n", num_dofs); + //return -1; + } // 1 allocate internal MultiBody structure m_impl = new MultiBodyImpl(num_bodies, num_dofs); // 2 build new index set assuring index(parent) < index(child) - if (-1 == m_init_cache->buildIndexSets()) { + if (-1 == m_init_cache->buildIndexSets()) + { return -1; } m_init_cache->getParentIndexArray(&m_impl->m_parent_index); // 3 setup internal kinematic and dynamic data - for (int index = 0; index < num_bodies; index++) { + for (int index = 0; index < num_bodies; index++) + { InertiaData inertia; JointData joint; - if (-1 == m_init_cache->getInertiaData(index, &inertia)) { + if (-1 == m_init_cache->getInertiaData(index, &inertia)) + { return -1; } - if (-1 == m_init_cache->getJointData(index, &joint)) { + if (-1 == m_init_cache->getJointData(index, &joint)) + { return -1; } @@ -332,24 +389,29 @@ int MultiBodyTree::finalize() { rigid_body.m_joint_type = joint.m_type; int user_int; - if (-1 == m_init_cache->getUserInt(index, &user_int)) { + if (-1 == m_init_cache->getUserInt(index, &user_int)) + { return -1; } - if (-1 == m_impl->setUserInt(index, user_int)) { + if (-1 == m_impl->setUserInt(index, user_int)) + { return -1; } - void* user_ptr; - if (-1 == m_init_cache->getUserPtr(index, &user_ptr)) { + void *user_ptr; + if (-1 == m_init_cache->getUserPtr(index, &user_ptr)) + { return -1; } - if (-1 == m_impl->setUserPtr(index, user_ptr)) { + if (-1 == m_impl->setUserPtr(index, user_ptr)) + { return -1; } // Set joint Jacobians. Note that the dimension is always 3x1 here to avoid variable sized // matrices. - switch (rigid_body.m_joint_type) { + switch (rigid_body.m_joint_type) + { case REVOLUTE: rigid_body.m_Jac_JR(0) = joint.m_child_axis_of_motion(0); rigid_body.m_Jac_JR(1) = joint.m_child_axis_of_motion(1); @@ -392,7 +454,8 @@ int MultiBodyTree::finalize() { } // 4 assign degree of freedom indices & build per-joint-type index arrays - if (-1 == m_impl->generateIndexSets()) { + if (-1 == m_impl->generateIndexSets()) + { bt_id_error_message("generating index sets\n"); return -1; } @@ -408,54 +471,66 @@ int MultiBodyTree::finalize() { return 0; } -int MultiBodyTree::setGravityInWorldFrame(const vec3 &gravity) { +int MultiBodyTree::setGravityInWorldFrame(const vec3 &gravity) +{ return m_impl->setGravityInWorldFrame(gravity); } -int MultiBodyTree::getJointType(const int body_index, JointType *joint_type) const { +int MultiBodyTree::getJointType(const int body_index, JointType *joint_type) const +{ return m_impl->getJointType(body_index, joint_type); } -int MultiBodyTree::getJointTypeStr(const int body_index, const char **joint_type) const { +int MultiBodyTree::getJointTypeStr(const int body_index, const char **joint_type) const +{ return m_impl->getJointTypeStr(body_index, joint_type); } -int MultiBodyTree::getDoFOffset(const int body_index, int *q_offset) const { +int MultiBodyTree::getDoFOffset(const int body_index, int *q_offset) const +{ return m_impl->getDoFOffset(body_index, q_offset); } -int MultiBodyTree::setBodyMass(const int body_index, idScalar mass) { +int MultiBodyTree::setBodyMass(const int body_index, idScalar mass) +{ return m_impl->setBodyMass(body_index, mass); } -int MultiBodyTree::setBodyFirstMassMoment(const int body_index, const vec3& first_mass_moment) { +int MultiBodyTree::setBodyFirstMassMoment(const int body_index, const vec3 &first_mass_moment) +{ return m_impl->setBodyFirstMassMoment(body_index, first_mass_moment); } -int MultiBodyTree::setBodySecondMassMoment(const int body_index, const mat33& second_mass_moment) { +int MultiBodyTree::setBodySecondMassMoment(const int body_index, const mat33 &second_mass_moment) +{ return m_impl->setBodySecondMassMoment(body_index, second_mass_moment); } -int MultiBodyTree::getBodyMass(const int body_index, idScalar *mass) const { +int MultiBodyTree::getBodyMass(const int body_index, idScalar *mass) const +{ return m_impl->getBodyMass(body_index, mass); } -int MultiBodyTree::getBodyFirstMassMoment(const int body_index, vec3 *first_mass_moment) const { +int MultiBodyTree::getBodyFirstMassMoment(const int body_index, vec3 *first_mass_moment) const +{ return m_impl->getBodyFirstMassMoment(body_index, first_mass_moment); } -int MultiBodyTree::getBodySecondMassMoment(const int body_index, mat33 *second_mass_moment) const { +int MultiBodyTree::getBodySecondMassMoment(const int body_index, mat33 *second_mass_moment) const +{ return m_impl->getBodySecondMassMoment(body_index, second_mass_moment); } void MultiBodyTree::clearAllUserForcesAndMoments() { m_impl->clearAllUserForcesAndMoments(); } -int MultiBodyTree::addUserForce(const int body_index, const vec3 &body_force) { +int MultiBodyTree::addUserForce(const int body_index, const vec3 &body_force) +{ return m_impl->addUserForce(body_index, body_force); } -int MultiBodyTree::addUserMoment(const int body_index, const vec3 &body_moment) { +int MultiBodyTree::addUserMoment(const int body_index, const vec3 &body_moment) +{ return m_impl->addUserMoment(body_index, body_moment); } -} +} // namespace btInverseDynamics diff --git a/src/BulletInverseDynamics/MultiBodyTree.hpp b/src/BulletInverseDynamics/MultiBodyTree.hpp index d235aa6e7..ae45e6109 100644 --- a/src/BulletInverseDynamics/MultiBodyTree.hpp +++ b/src/BulletInverseDynamics/MultiBodyTree.hpp @@ -4,10 +4,11 @@ #include "IDConfig.hpp" #include "IDMath.hpp" -namespace btInverseDynamics { - +namespace btInverseDynamics +{ /// Enumeration of supported joint types -enum JointType { +enum JointType +{ /// no degree of freedom, moves with parent FIXED = 0, /// one rotational degree of freedom relative to parent @@ -49,9 +50,10 @@ enum JointType { /// /// TODO - force element interface (friction, springs, dampers, etc) /// - gears and motor inertia -class MultiBodyTree { +class MultiBodyTree +{ public: - ID_DECLARE_ALIGNED_ALLOCATOR(); + ID_DECLARE_ALIGNED_ALLOCATOR(); /// The contructor. /// Initialization & allocation is via addBody and buildSystem calls. MultiBodyTree(); @@ -119,9 +121,9 @@ public: /// print tree data to stdout void printTreeData(); /// Calculate joint forces for given generalized state & derivatives. - /// This also updates kinematic terms computed in calculateKinematics. - /// If gravity is not set to zero, acceleration terms will contain - /// gravitational acceleration. + /// This also updates kinematic terms computed in calculateKinematics. + /// If gravity is not set to zero, acceleration terms will contain + /// gravitational acceleration. /// @param q generalized coordinates /// @param u generalized velocities. In the general case, u=T(q)*dot(q) and dim(q)>=dim(u) /// @param dot_u time derivative of u @@ -152,30 +154,28 @@ public: /// @return -1 on error, 0 on success int calculateMassMatrix(const vecx& q, matxx* mass_matrix); - - /// Calculates kinematics also calculated in calculateInverseDynamics, - /// but not dynamics. - /// This function ensures that correct accelerations are computed that do not - /// contain gravitational acceleration terms. - /// Does not calculate Jacobians, but only vector quantities (positions, velocities & accelerations) - int calculateKinematics(const vecx& q, const vecx& u, const vecx& dot_u); - /// Calculate position kinematics - int calculatePositionKinematics(const vecx& q); - /// Calculate position and velocity kinematics - int calculatePositionAndVelocityKinematics(const vecx& q, const vecx& u); + /// Calculates kinematics also calculated in calculateInverseDynamics, + /// but not dynamics. + /// This function ensures that correct accelerations are computed that do not + /// contain gravitational acceleration terms. + /// Does not calculate Jacobians, but only vector quantities (positions, velocities & accelerations) + int calculateKinematics(const vecx& q, const vecx& u, const vecx& dot_u); + /// Calculate position kinematics + int calculatePositionKinematics(const vecx& q); + /// Calculate position and velocity kinematics + int calculatePositionAndVelocityKinematics(const vecx& q, const vecx& u); #if (defined BT_ID_HAVE_MAT3X) && (defined BT_ID_WITH_JACOBIANS) - /// Calculate Jacobians (dvel/du), as well as velocity-dependent accelearation components - /// d(Jacobian)/dt*u - /// This function assumes that calculateInverseDynamics was called, or calculateKinematics, - /// or calculatePositionAndVelocityKinematics - int calculateJacobians(const vecx& q, const vecx& u); - /// Calculate Jacobians (dvel/du) - /// This function assumes that calculateInverseDynamics was called, or - /// one of the calculateKineamtics functions - int calculateJacobians(const vecx& q); -#endif // BT_ID_HAVE_MAT3X - + /// Calculate Jacobians (dvel/du), as well as velocity-dependent accelearation components + /// d(Jacobian)/dt*u + /// This function assumes that calculateInverseDynamics was called, or calculateKinematics, + /// or calculatePositionAndVelocityKinematics + int calculateJacobians(const vecx& q, const vecx& u); + /// Calculate Jacobians (dvel/du) + /// This function assumes that calculateInverseDynamics was called, or + /// one of the calculateKineamtics functions + int calculateJacobians(const vecx& q); +#endif // BT_ID_HAVE_MAT3X /// set gravitational acceleration /// the default is [0;0;-9.8] in the world frame @@ -231,15 +231,15 @@ public: int getBodyLinearAcceleration(const int body_index, vec3* world_acceleration) const; #if (defined BT_ID_HAVE_MAT3X) && (defined BT_ID_WITH_JACOBIANS) - // get translational jacobian, in world frame (dworld_velocity/du) - int getBodyJacobianTrans(const int body_index, mat3x* world_jac_trans) const; - // get rotational jacobian, in world frame (dworld_omega/du) - int getBodyJacobianRot(const int body_index, mat3x* world_jac_rot) const; - // get product of translational jacobian derivative * generatlized velocities - int getBodyDotJacobianTransU(const int body_index, vec3* world_dot_jac_trans_u) const; - // get product of rotational jacobian derivative * generatlized velocities - int getBodyDotJacobianRotU(const int body_index, vec3* world_dot_jac_rot_u) const; -#endif // BT_ID_HAVE_MAT3X + // get translational jacobian, in world frame (dworld_velocity/du) + int getBodyJacobianTrans(const int body_index, mat3x* world_jac_trans) const; + // get rotational jacobian, in world frame (dworld_omega/du) + int getBodyJacobianRot(const int body_index, mat3x* world_jac_rot) const; + // get product of translational jacobian derivative * generatlized velocities + int getBodyDotJacobianTransU(const int body_index, vec3* world_dot_jac_trans_u) const; + // get product of rotational jacobian derivative * generatlized velocities + int getBodyDotJacobianRotU(const int body_index, vec3* world_dot_jac_rot_u) const; +#endif // BT_ID_HAVE_MAT3X /// returns the (internal) index of body /// @param body_index is the index of a body @@ -256,21 +256,21 @@ public: /// @param joint_type string naming the corresponding joint type /// @return 0 on success, -1 on failure int getJointTypeStr(const int body_index, const char** joint_type) const; - /// get offset translation to parent body (see addBody) + /// get offset translation to parent body (see addBody) /// @param body_index index of the body /// @param r the offset translation (see above) /// @return 0 on success, -1 on failure - int getParentRParentBodyRef(const int body_index, vec3* r) const; + int getParentRParentBodyRef(const int body_index, vec3* r) const; /// get offset rotation to parent body (see addBody) /// @param body_index index of the body /// @param T the transform (see above) /// @return 0 on success, -1 on failure - int getBodyTParentRef(const int body_index, mat33* T) const; + int getBodyTParentRef(const int body_index, mat33* T) const; /// get axis of motion (see addBody) /// @param body_index index of the body /// @param axis the axis (see above) /// @return 0 on success, -1 on failure - int getBodyAxisOfMotion(const int body_index, vec3* axis) const; + int getBodyAxisOfMotion(const int body_index, vec3* axis) const; /// get offset for degrees of freedom of this body into the q-vector /// @param body_index index of the body /// @param q_offset offset the q vector diff --git a/src/BulletInverseDynamics/details/IDEigenInterface.hpp b/src/BulletInverseDynamics/details/IDEigenInterface.hpp index 836395cea..fe4f10251 100644 --- a/src/BulletInverseDynamics/details/IDEigenInterface.hpp +++ b/src/BulletInverseDynamics/details/IDEigenInterface.hpp @@ -1,8 +1,8 @@ #ifndef INVDYNEIGENINTERFACE_HPP_ #define INVDYNEIGENINTERFACE_HPP_ #include "../IDConfig.hpp" -namespace btInverseDynamics { - +namespace btInverseDynamics +{ #define BT_ID_HAVE_MAT3X #ifdef BT_USE_DOUBLE_PRECISION @@ -19,18 +19,21 @@ typedef Eigen::Matrix m typedef Eigen::Matrix mat3x; #endif -inline void resize(mat3x &m, Eigen::Index size) { - m.resize(3, size); - m.setZero(); +inline void resize(mat3x &m, Eigen::Index size) +{ + m.resize(3, size); + m.setZero(); } -inline void setMatxxElem(const idArrayIdx row, const idArrayIdx col, const idScalar val, matxx*m){ - (*m)(row, col) = val; +inline void setMatxxElem(const idArrayIdx row, const idArrayIdx col, const idScalar val, matxx *m) +{ + (*m)(row, col) = val; } -inline void setMat3xElem(const idArrayIdx row, const idArrayIdx col, const idScalar val, mat3x*m){ - (*m)(row, col) = val; +inline void setMat3xElem(const idArrayIdx row, const idArrayIdx col, const idScalar val, mat3x *m) +{ + (*m)(row, col) = val; } -} +} // namespace btInverseDynamics #endif // INVDYNEIGENINTERFACE_HPP_ diff --git a/src/BulletInverseDynamics/details/IDLinearMathInterface.hpp b/src/BulletInverseDynamics/details/IDLinearMathInterface.hpp index c179daeec..0c398a372 100644 --- a/src/BulletInverseDynamics/details/IDLinearMathInterface.hpp +++ b/src/BulletInverseDynamics/details/IDLinearMathInterface.hpp @@ -10,32 +10,37 @@ #include "../../LinearMath/btMatrixX.h" #define BT_ID_HAVE_MAT3X -namespace btInverseDynamics { +namespace btInverseDynamics +{ class vec3; class vecx; class mat33; typedef btMatrixX matxx; -class vec3 : public btVector3 { +class vec3 : public btVector3 +{ public: vec3() : btVector3() {} vec3(const btVector3& btv) { *this = btv; } idScalar& operator()(int i) { return (*this)[i]; } const idScalar& operator()(int i) const { return (*this)[i]; } int size() const { return 3; } - const vec3& operator=(const btVector3& rhs) { + const vec3& operator=(const btVector3& rhs) + { *static_cast(this) = rhs; return *this; } }; -class mat33 : public btMatrix3x3 { +class mat33 : public btMatrix3x3 +{ public: mat33() : btMatrix3x3() {} mat33(const btMatrix3x3& btm) { *this = btm; } idScalar& operator()(int i, int j) { return (*this)[i][j]; } const idScalar& operator()(int i, int j) const { return (*this)[i][j]; } - const mat33& operator=(const btMatrix3x3& rhs) { + const mat33& operator=(const btMatrix3x3& rhs) + { *static_cast(this) = rhs; return *this; } @@ -47,10 +52,12 @@ inline mat33 operator/(const mat33& a, const idScalar& s) { return a * (1.0 / s) inline mat33 operator*(const idScalar& s, const mat33& a) { return a * s; } -class vecx : public btVectorX { +class vecx : public btVectorX +{ public: vecx(int size) : btVectorX(size) {} - const vecx& operator=(const btVectorX& rhs) { + const vecx& operator=(const btVectorX& rhs) + { *static_cast*>(this) = rhs; return *this; } @@ -66,43 +73,53 @@ public: friend vecx operator/(const vecx& a, const idScalar& s); }; -inline vecx operator*(const vecx& a, const idScalar& s) { +inline vecx operator*(const vecx& a, const idScalar& s) +{ vecx result(a.size()); - for (int i = 0; i < result.size(); i++) { + for (int i = 0; i < result.size(); i++) + { result(i) = a(i) * s; } return result; } inline vecx operator*(const idScalar& s, const vecx& a) { return a * s; } -inline vecx operator+(const vecx& a, const vecx& b) { +inline vecx operator+(const vecx& a, const vecx& b) +{ vecx result(a.size()); // TODO: error handling for a.size() != b.size()?? - if (a.size() != b.size()) { + if (a.size() != b.size()) + { bt_id_error_message("size missmatch. a.size()= %d, b.size()= %d\n", a.size(), b.size()); abort(); } - for (int i = 0; i < a.size(); i++) { + for (int i = 0; i < a.size(); i++) + { result(i) = a(i) + b(i); } return result; } -inline vecx operator-(const vecx& a, const vecx& b) { +inline vecx operator-(const vecx& a, const vecx& b) +{ vecx result(a.size()); // TODO: error handling for a.size() != b.size()?? - if (a.size() != b.size()) { + if (a.size() != b.size()) + { bt_id_error_message("size missmatch. a.size()= %d, b.size()= %d\n", a.size(), b.size()); abort(); } - for (int i = 0; i < a.size(); i++) { + for (int i = 0; i < a.size(); i++) + { result(i) = a(i) - b(i); } return result; } -inline vecx operator/(const vecx& a, const idScalar& s) { +inline vecx operator/(const vecx& a, const idScalar& s) +{ vecx result(a.size()); - for (int i = 0; i < result.size(); i++) { + for (int i = 0; i < result.size(); i++) + { result(i) = a(i) / s; } @@ -110,63 +127,76 @@ inline vecx operator/(const vecx& a, const idScalar& s) { } // use btMatrixX to implement 3xX matrix -class mat3x : public matxx { +class mat3x : public matxx +{ public: - mat3x(){} - mat3x(const mat3x&rhs) { - matxx::resize(rhs.rows(), rhs.cols()); - *this = rhs; - } - mat3x(int rows, int cols): matxx(3,cols) { - } - void operator=(const mat3x& rhs) { - if (m_cols != rhs.m_cols) { - bt_id_error_message("size missmatch, cols= %d but rhs.cols= %d\n", cols(), rhs.cols()); - abort(); + mat3x() {} + mat3x(const mat3x& rhs) + { + matxx::resize(rhs.rows(), rhs.cols()); + *this = rhs; + } + mat3x(int rows, int cols) : matxx(3, cols) + { + } + void operator=(const mat3x& rhs) + { + if (m_cols != rhs.m_cols) + { + bt_id_error_message("size missmatch, cols= %d but rhs.cols= %d\n", cols(), rhs.cols()); + abort(); + } + for (int i = 0; i < rows(); i++) + { + for (int k = 0; k < cols(); k++) + { + setElem(i, k, rhs(i, k)); + } + } + } + void setZero() + { + matxx::setZero(); } - for(int i=0;isetElem(row, col, val); +inline void setMatxxElem(const idArrayIdx row, const idArrayIdx col, const idScalar val, matxx* m) +{ + m->setElem(row, col, val); } -inline void setMat3xElem(const idArrayIdx row, const idArrayIdx col, const idScalar val, mat3x*m){ - m->setElem(row, col, val); +inline void setMat3xElem(const idArrayIdx row, const idArrayIdx col, const idScalar val, mat3x* m) +{ + m->setElem(row, col, val); } -} +} // namespace btInverseDynamics #endif // IDLINEARMATHINTERFACE_HPP_ diff --git a/src/BulletInverseDynamics/details/IDMatVec.hpp b/src/BulletInverseDynamics/details/IDMatVec.hpp index c89db5e12..1c786095e 100644 --- a/src/BulletInverseDynamics/details/IDMatVec.hpp +++ b/src/BulletInverseDynamics/details/IDMatVec.hpp @@ -7,7 +7,8 @@ #include "../IDConfig.hpp" #define BT_ID_HAVE_MAT3X -namespace btInverseDynamics { +namespace btInverseDynamics +{ class vec3; class vecx; class mat33; @@ -17,7 +18,8 @@ class mat3x; /// This is a very basic implementation to enable stand-alone use of the library. /// The implementation is not really optimized and misses many features that you would /// want from a "fully featured" linear math library. -class vec3 { +class vec3 +{ public: idScalar& operator()(int i) { return m_data[i]; } const idScalar& operator()(int i) const { return m_data[i]; } @@ -40,7 +42,8 @@ private: idScalar m_data[3]; }; -class mat33 { +class mat33 +{ public: idScalar& operator()(int i, int j) { return m_data[3 * i + j]; } const idScalar& operator()(int i, int j) const { return m_data[3 * i + j]; } @@ -62,9 +65,11 @@ private: idScalar m_data[9]; }; -class vecx { +class vecx +{ public: - vecx(int size) : m_size(size) { + vecx(int size) : m_size(size) + { m_data = static_cast(idMalloc(sizeof(idScalar) * size)); } ~vecx() { idFree(m_data); } @@ -85,14 +90,17 @@ private: idScalar* m_data; }; -class matxx { +class matxx +{ public: - matxx() { - m_data = 0x0; - m_cols=0; - m_rows=0; - } - matxx(int rows, int cols) : m_rows(rows), m_cols(cols) { + matxx() + { + m_data = 0x0; + m_cols = 0; + m_rows = 0; + } + matxx(int rows, int cols) : m_rows(rows), m_cols(cols) + { m_data = static_cast(idMalloc(sizeof(idScalar) * rows * cols)); } ~matxx() { idFree(m_data); } @@ -107,69 +115,86 @@ private: idScalar* m_data; }; -class mat3x { +class mat3x +{ public: - mat3x() { - m_data = 0x0; - m_cols=0; - } - mat3x(const mat3x&rhs) { - m_cols=rhs.m_cols; - allocate(); - *this = rhs; - } - mat3x(int rows, int cols): m_cols(cols) { - allocate(); - }; - void operator=(const mat3x& rhs) { - if (m_cols != rhs.m_cols) { - bt_id_error_message("size missmatch, cols= %d but rhs.cols= %d\n", cols(), rhs.cols()); - abort(); + mat3x() + { + m_data = 0x0; + m_cols = 0; + } + mat3x(const mat3x& rhs) + { + m_cols = rhs.m_cols; + allocate(); + *this = rhs; + } + mat3x(int rows, int cols) : m_cols(cols) + { + allocate(); + }; + void operator=(const mat3x& rhs) + { + if (m_cols != rhs.m_cols) + { + bt_id_error_message("size missmatch, cols= %d but rhs.cols= %d\n", cols(), rhs.cols()); + abort(); + } + for (int i = 0; i < 3 * m_cols; i++) + { + m_data[i] = rhs.m_data[i]; + } } - for(int i=0;i<3*m_cols;i++) { - m_data[i] = rhs.m_data[i]; - } - } - ~mat3x() { - free(); - } - idScalar& operator()(int row, int col) { return m_data[row * m_cols + col]; } - const idScalar& operator()(int row, int col) const { return m_data[row * m_cols + col]; } - int rows() const { return m_rows; } - const int& cols() const { return m_cols; } - void resize(int rows, int cols) { - m_cols=cols; - free(); - allocate(); - } - void setZero() { - memset(m_data,0x0,sizeof(idScalar)*m_rows*m_cols); - } - // avoid operators that would allocate -- use functions sub/add/mul in IDMath.hpp instead + ~mat3x() + { + free(); + } + idScalar& operator()(int row, int col) { return m_data[row * m_cols + col]; } + const idScalar& operator()(int row, int col) const { return m_data[row * m_cols + col]; } + int rows() const { return m_rows; } + const int& cols() const { return m_cols; } + void resize(int rows, int cols) + { + m_cols = cols; + free(); + allocate(); + } + void setZero() + { + memset(m_data, 0x0, sizeof(idScalar) * m_rows * m_cols); + } + // avoid operators that would allocate -- use functions sub/add/mul in IDMath.hpp instead private: - void allocate(){m_data = static_cast(idMalloc(sizeof(idScalar) * m_rows * m_cols));} - void free() { idFree(m_data);} - enum {m_rows=3}; - int m_cols; - idScalar* m_data; + void allocate() { m_data = static_cast(idMalloc(sizeof(idScalar) * m_rows * m_cols)); } + void free() { idFree(m_data); } + enum + { + m_rows = 3 + }; + int m_cols; + idScalar* m_data; }; -inline void resize(mat3x &m, idArrayIdx size) { - m.resize(3, size); - m.setZero(); +inline void resize(mat3x& m, idArrayIdx size) +{ + m.resize(3, size); + m.setZero(); } ////////////////////////////////////////////////// // Implementations -inline const vec3& vec3::operator=(const vec3& rhs) { - if (&rhs != this) { +inline const vec3& vec3::operator=(const vec3& rhs) +{ + if (&rhs != this) + { memcpy(m_data, rhs.m_data, 3 * sizeof(idScalar)); } return *this; } -inline vec3 vec3::cross(const vec3& b) const { +inline vec3 vec3::cross(const vec3& b) const +{ vec3 result; result.m_data[0] = m_data[1] * b.m_data[2] - m_data[2] * b.m_data[1]; result.m_data[1] = m_data[2] * b.m_data[0] - m_data[0] * b.m_data[2]; @@ -178,17 +203,21 @@ inline vec3 vec3::cross(const vec3& b) const { return result; } -inline idScalar vec3::dot(const vec3& b) const { +inline idScalar vec3::dot(const vec3& b) const +{ return m_data[0] * b.m_data[0] + m_data[1] * b.m_data[1] + m_data[2] * b.m_data[2]; } -inline const mat33& mat33::operator=(const mat33& rhs) { - if (&rhs != this) { +inline const mat33& mat33::operator=(const mat33& rhs) +{ + if (&rhs != this) + { memcpy(m_data, rhs.m_data, 9 * sizeof(idScalar)); } return *this; } -inline mat33 mat33::transpose() const { +inline mat33 mat33::transpose() const +{ mat33 result; result.m_data[0] = m_data[0]; result.m_data[1] = m_data[3]; @@ -203,7 +232,8 @@ inline mat33 mat33::transpose() const { return result; } -inline mat33 operator*(const mat33& a, const mat33& b) { +inline mat33 operator*(const mat33& a, const mat33& b) +{ mat33 result; result.m_data[0] = a.m_data[0] * b.m_data[0] + a.m_data[1] * b.m_data[3] + a.m_data[2] * b.m_data[6]; @@ -227,22 +257,27 @@ inline mat33 operator*(const mat33& a, const mat33& b) { return result; } -inline const mat33& mat33::operator+=(const mat33& b) { - for (int i = 0; i < 9; i++) { +inline const mat33& mat33::operator+=(const mat33& b) +{ + for (int i = 0; i < 9; i++) + { m_data[i] += b.m_data[i]; } return *this; } -inline const mat33& mat33::operator-=(const mat33& b) { - for (int i = 0; i < 9; i++) { +inline const mat33& mat33::operator-=(const mat33& b) +{ + for (int i = 0; i < 9; i++) + { m_data[i] -= b.m_data[i]; } return *this; } -inline vec3 operator*(const mat33& a, const vec3& b) { +inline vec3 operator*(const mat33& a, const vec3& b) +{ vec3 result; result.m_data[0] = @@ -255,23 +290,29 @@ inline vec3 operator*(const mat33& a, const vec3& b) { return result; } -inline const vec3& vec3::operator+=(const vec3& b) { - for (int i = 0; i < 3; i++) { +inline const vec3& vec3::operator+=(const vec3& b) +{ + for (int i = 0; i < 3; i++) + { m_data[i] += b.m_data[i]; } return *this; } -inline const vec3& vec3::operator-=(const vec3& b) { - for (int i = 0; i < 3; i++) { +inline const vec3& vec3::operator-=(const vec3& b) +{ + for (int i = 0; i < 3; i++) + { m_data[i] -= b.m_data[i]; } return *this; } -inline mat33 operator*(const mat33& a, const idScalar& s) { +inline mat33 operator*(const mat33& a, const idScalar& s) +{ mat33 result; - for (int i = 0; i < 9; i++) { + for (int i = 0; i < 9; i++) + { result.m_data[i] = a.m_data[i] * s; } return result; @@ -279,137 +320,170 @@ inline mat33 operator*(const mat33& a, const idScalar& s) { inline mat33 operator*(const idScalar& s, const mat33& a) { return a * s; } -inline vec3 operator*(const vec3& a, const idScalar& s) { +inline vec3 operator*(const vec3& a, const idScalar& s) +{ vec3 result; - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 3; i++) + { result.m_data[i] = a.m_data[i] * s; } return result; } inline vec3 operator*(const idScalar& s, const vec3& a) { return a * s; } -inline mat33 operator+(const mat33& a, const mat33& b) { +inline mat33 operator+(const mat33& a, const mat33& b) +{ mat33 result; - for (int i = 0; i < 9; i++) { + for (int i = 0; i < 9; i++) + { result.m_data[i] = a.m_data[i] + b.m_data[i]; } return result; } -inline vec3 operator+(const vec3& a, const vec3& b) { +inline vec3 operator+(const vec3& a, const vec3& b) +{ vec3 result; - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 3; i++) + { result.m_data[i] = a.m_data[i] + b.m_data[i]; } return result; } -inline mat33 operator-(const mat33& a, const mat33& b) { +inline mat33 operator-(const mat33& a, const mat33& b) +{ mat33 result; - for (int i = 0; i < 9; i++) { + for (int i = 0; i < 9; i++) + { result.m_data[i] = a.m_data[i] - b.m_data[i]; } return result; } -inline vec3 operator-(const vec3& a, const vec3& b) { +inline vec3 operator-(const vec3& a, const vec3& b) +{ vec3 result; - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 3; i++) + { result.m_data[i] = a.m_data[i] - b.m_data[i]; } return result; } -inline mat33 operator/(const mat33& a, const idScalar& s) { +inline mat33 operator/(const mat33& a, const idScalar& s) +{ mat33 result; - for (int i = 0; i < 9; i++) { + for (int i = 0; i < 9; i++) + { result.m_data[i] = a.m_data[i] / s; } return result; } -inline vec3 operator/(const vec3& a, const idScalar& s) { +inline vec3 operator/(const vec3& a, const idScalar& s) +{ vec3 result; - for (int i = 0; i < 3; i++) { + for (int i = 0; i < 3; i++) + { result.m_data[i] = a.m_data[i] / s; } return result; } -inline const vecx& vecx::operator=(const vecx& rhs) { - if (size() != rhs.size()) { +inline const vecx& vecx::operator=(const vecx& rhs) +{ + if (size() != rhs.size()) + { bt_id_error_message("size missmatch, size()= %d but rhs.size()= %d\n", size(), rhs.size()); abort(); } - if (&rhs != this) { + if (&rhs != this) + { memcpy(m_data, rhs.m_data, rhs.size() * sizeof(idScalar)); } return *this; } -inline vecx operator*(const vecx& a, const idScalar& s) { +inline vecx operator*(const vecx& a, const idScalar& s) +{ vecx result(a.size()); - for (int i = 0; i < result.size(); i++) { + for (int i = 0; i < result.size(); i++) + { result.m_data[i] = a.m_data[i] * s; } return result; } inline vecx operator*(const idScalar& s, const vecx& a) { return a * s; } -inline vecx operator+(const vecx& a, const vecx& b) { +inline vecx operator+(const vecx& a, const vecx& b) +{ vecx result(a.size()); // TODO: error handling for a.size() != b.size()?? - if (a.size() != b.size()) { + if (a.size() != b.size()) + { bt_id_error_message("size missmatch. a.size()= %d, b.size()= %d\n", a.size(), b.size()); abort(); } - for (int i = 0; i < a.size(); i++) { + for (int i = 0; i < a.size(); i++) + { result.m_data[i] = a.m_data[i] + b.m_data[i]; } return result; } -inline vecx operator-(const vecx& a, const vecx& b) { +inline vecx operator-(const vecx& a, const vecx& b) +{ vecx result(a.size()); // TODO: error handling for a.size() != b.size()?? - if (a.size() != b.size()) { + if (a.size() != b.size()) + { bt_id_error_message("size missmatch. a.size()= %d, b.size()= %d\n", a.size(), b.size()); abort(); } - for (int i = 0; i < a.size(); i++) { + for (int i = 0; i < a.size(); i++) + { result.m_data[i] = a.m_data[i] - b.m_data[i]; } return result; } -inline vecx operator/(const vecx& a, const idScalar& s) { +inline vecx operator/(const vecx& a, const idScalar& s) +{ vecx result(a.size()); - for (int i = 0; i < result.size(); i++) { + for (int i = 0; i < result.size(); i++) + { result.m_data[i] = a.m_data[i] / s; } return result; } -inline vec3 operator*(const mat3x& a, const vecx& b) { - vec3 result; - if (a.cols() != b.size()) { - bt_id_error_message("size missmatch. a.cols()= %d, b.size()= %d\n", a.cols(), b.size()); - abort(); - } - result(0)=0.0; - result(1)=0.0; - result(2)=0.0; - for(int i=0;i(i)); id_printf("type: %s\n", jointTypeToString(body.m_joint_type)); @@ -59,19 +65,22 @@ void MultiBodyTree::MultiBodyImpl::printTreeData() { id_printf("mass = %f\n", body.m_mass); id_printf("mass * com = [%f %f %f]\n", body.m_body_mass_com(0), body.m_body_mass_com(1), body.m_body_mass_com(2)); - id_printf("I_o= [%f %f %f;\n" - " %f %f %f;\n" - " %f %f %f]\n", - body.m_body_I_body(0, 0), body.m_body_I_body(0, 1), body.m_body_I_body(0, 2), - body.m_body_I_body(1, 0), body.m_body_I_body(1, 1), body.m_body_I_body(1, 2), - body.m_body_I_body(2, 0), body.m_body_I_body(2, 1), body.m_body_I_body(2, 2)); + id_printf( + "I_o= [%f %f %f;\n" + " %f %f %f;\n" + " %f %f %f]\n", + body.m_body_I_body(0, 0), body.m_body_I_body(0, 1), body.m_body_I_body(0, 2), + body.m_body_I_body(1, 0), body.m_body_I_body(1, 1), body.m_body_I_body(1, 2), + body.m_body_I_body(2, 0), body.m_body_I_body(2, 1), body.m_body_I_body(2, 2)); id_printf("parent_pos_parent_body_ref= [%f %f %f]\n", body.m_parent_pos_parent_body_ref(0), body.m_parent_pos_parent_body_ref(1), body.m_parent_pos_parent_body_ref(2)); } } -int MultiBodyTree::MultiBodyImpl::bodyNumDoFs(const JointType &type) const { - switch (type) { +int MultiBodyTree::MultiBodyImpl::bodyNumDoFs(const JointType &type) const +{ + switch (type) + { case FIXED: return 0; case REVOLUTE: @@ -84,7 +93,8 @@ int MultiBodyTree::MultiBodyImpl::bodyNumDoFs(const JointType &type) const { return 0; } -void MultiBodyTree::MultiBodyImpl::printTree(int index, int indentation) { +void MultiBodyTree::MultiBodyImpl::printTree(int index, int indentation) +{ // this is adapted from URDF2Bullet. // TODO: fix this and print proper graph (similar to git --log --graph) int num_children = m_child_indices[index].size(); @@ -92,7 +102,8 @@ void MultiBodyTree::MultiBodyImpl::printTree(int index, int indentation) { indentation += 2; int count = 0; - for (int i = 0; i < num_children; i++) { + for (int i = 0; i < num_children; i++) + { int child_index = m_child_indices[index][i]; indent(indentation); id_printf("body %.2d[%s]: %.2d is child no. %d (qi= %d .. %d) \n", index, @@ -104,19 +115,23 @@ void MultiBodyTree::MultiBodyImpl::printTree(int index, int indentation) { } } -int MultiBodyTree::MultiBodyImpl::setGravityInWorldFrame(const vec3 &gravity) { +int MultiBodyTree::MultiBodyImpl::setGravityInWorldFrame(const vec3 &gravity) +{ m_world_gravity = gravity; return 0; } -int MultiBodyTree::MultiBodyImpl::generateIndexSets() { +int MultiBodyTree::MultiBodyImpl::generateIndexSets() +{ m_body_revolute_list.resize(0); m_body_prismatic_list.resize(0); int q_index = 0; - for (idArrayIdx i = 0; i < m_body_list.size(); i++) { + for (idArrayIdx i = 0; i < m_body_list.size(); i++) + { RigidBody &body = m_body_list[i]; body.m_q_index = -1; - switch (body.m_joint_type) { + switch (body.m_joint_type) + { case REVOLUTE: m_body_revolute_list.push_back(i); body.m_q_index = q_index; @@ -141,22 +156,30 @@ int MultiBodyTree::MultiBodyImpl::generateIndexSets() { } } // sanity check - if (q_index != m_num_dofs) { + if (q_index != m_num_dofs) + { bt_id_error_message("internal error, q_index= %d but num_dofs %d\n", q_index, m_num_dofs); return -1; } m_child_indices.resize(m_body_list.size()); - for (idArrayIdx child = 1; child < m_parent_index.size(); child++) { + for (idArrayIdx child = 1; child < m_parent_index.size(); child++) + { const int &parent = m_parent_index[child]; - if (parent >= 0 && parent < (static_cast(m_parent_index.size()) - 1)) { + if (parent >= 0 && parent < (static_cast(m_parent_index.size()) - 1)) + { m_child_indices[parent].push_back(child); - } else { - if (-1 == parent) { + } + else + { + if (-1 == parent) + { // multiple bodies are directly linked to the environment, ie, not a single root bt_id_error_message("building index sets parent(%zu)= -1 (multiple roots)\n", child); - } else { + } + else + { // should never happen bt_id_error_message( "building index sets. parent_index[%zu]= %d, but m_parent_index.size()= %d\n", @@ -169,11 +192,14 @@ int MultiBodyTree::MultiBodyImpl::generateIndexSets() { return 0; } -void MultiBodyTree::MultiBodyImpl::calculateStaticData() { +void MultiBodyTree::MultiBodyImpl::calculateStaticData() +{ // relative kinematics that are not a function of q, u, dot_u - for (idArrayIdx i = 0; i < m_body_list.size(); i++) { + for (idArrayIdx i = 0; i < m_body_list.size(); i++) + { RigidBody &body = m_body_list[i]; - switch (body.m_joint_type) { + switch (body.m_joint_type) + { case REVOLUTE: body.m_parent_vel_rel(0) = 0; body.m_parent_vel_rel(1) = 0; @@ -214,39 +240,44 @@ void MultiBodyTree::MultiBodyImpl::calculateStaticData() { break; } - // resize & initialize jacobians to zero. + // resize & initialize jacobians to zero. #if (defined BT_ID_HAVE_MAT3X) && (defined BT_ID_WITH_JACOBIANS) - body.m_body_dot_Jac_T_u(0) = 0.0; - body.m_body_dot_Jac_T_u(1) = 0.0; - body.m_body_dot_Jac_T_u(2) = 0.0; - body.m_body_dot_Jac_R_u(0) = 0.0; - body.m_body_dot_Jac_R_u(1) = 0.0; - body.m_body_dot_Jac_R_u(2) = 0.0; - resize(body.m_body_Jac_T,m_num_dofs); - resize(body.m_body_Jac_R,m_num_dofs); - body.m_body_Jac_T.setZero(); - body.m_body_Jac_R.setZero(); -#endif // + body.m_body_dot_Jac_T_u(0) = 0.0; + body.m_body_dot_Jac_T_u(1) = 0.0; + body.m_body_dot_Jac_T_u(2) = 0.0; + body.m_body_dot_Jac_R_u(0) = 0.0; + body.m_body_dot_Jac_R_u(1) = 0.0; + body.m_body_dot_Jac_R_u(2) = 0.0; + resize(body.m_body_Jac_T, m_num_dofs); + resize(body.m_body_Jac_R, m_num_dofs); + body.m_body_Jac_T.setZero(); + body.m_body_Jac_R.setZero(); +#endif // } } int MultiBodyTree::MultiBodyImpl::calculateInverseDynamics(const vecx &q, const vecx &u, - const vecx &dot_u, vecx *joint_forces) { + const vecx &dot_u, vecx *joint_forces) +{ if (q.size() != m_num_dofs || u.size() != m_num_dofs || dot_u.size() != m_num_dofs || - joint_forces->size() != m_num_dofs) { - bt_id_error_message("wrong vector dimension. system has %d DOFs,\n" - "but dim(q)= %d, dim(u)= %d, dim(dot_u)= %d, dim(joint_forces)= %d\n", - m_num_dofs, static_cast(q.size()), static_cast(u.size()), - static_cast(dot_u.size()), static_cast(joint_forces->size())); + joint_forces->size() != m_num_dofs) + { + bt_id_error_message( + "wrong vector dimension. system has %d DOFs,\n" + "but dim(q)= %d, dim(u)= %d, dim(dot_u)= %d, dim(joint_forces)= %d\n", + m_num_dofs, static_cast(q.size()), static_cast(u.size()), + static_cast(dot_u.size()), static_cast(joint_forces->size())); return -1; } // 1. relative kinematics - if(-1 == calculateKinematics(q,u,dot_u, POSITION_VELOCITY_ACCELERATION)) { - bt_id_error_message("error in calculateKinematics\n"); - return -1; - } - // 2. update contributions to equations of motion for every body. - for (idArrayIdx i = 0; i < m_body_list.size(); i++) { + if (-1 == calculateKinematics(q, u, dot_u, POSITION_VELOCITY_ACCELERATION)) + { + bt_id_error_message("error in calculateKinematics\n"); + return -1; + } + // 2. update contributions to equations of motion for every body. + for (idArrayIdx i = 0; i < m_body_list.size(); i++) + { RigidBody &body = m_body_list[i]; // 3.4 update dynamic terms (rate of change of angular & linear momentum) body.m_eom_lhs_rotational = @@ -268,14 +299,16 @@ int MultiBodyTree::MultiBodyImpl::calculateInverseDynamics(const vecx &q, const // Also, this enables adding zero weight bodies as a way to calculate frame poses // for force elements, etc. - for (int body_idx = m_body_list.size() - 1; body_idx >= 0; body_idx--) { + for (int body_idx = m_body_list.size() - 1; body_idx >= 0; body_idx--) + { // sum of forces and moments acting on this body from its children vec3 sum_f_children; vec3 sum_m_children; setZero(sum_f_children); setZero(sum_m_children); for (idArrayIdx child_list_idx = 0; child_list_idx < m_child_indices[body_idx].size(); - child_list_idx++) { + child_list_idx++) + { const RigidBody &child = m_body_list[m_child_indices[body_idx][child_list_idx]]; vec3 child_joint_force_in_this_frame = child.m_body_T_parent.transpose() * child.m_force_at_joint; @@ -293,19 +326,22 @@ int MultiBodyTree::MultiBodyImpl::calculateInverseDynamics(const vecx &q, const // These are the components of force_at_joint/moment_at_joint // in the free directions given by Jac_JT/Jac_JR // 4.1 revolute joints - for (idArrayIdx i = 0; i < m_body_revolute_list.size(); i++) { + for (idArrayIdx i = 0; i < m_body_revolute_list.size(); i++) + { RigidBody &body = m_body_list[m_body_revolute_list[i]]; // (*joint_forces)(body.m_q_index) = body.m_Jac_JR.transpose() * body.m_moment_at_joint; (*joint_forces)(body.m_q_index) = body.m_Jac_JR.dot(body.m_moment_at_joint); } // 4.2 for prismatic joints - for (idArrayIdx i = 0; i < m_body_prismatic_list.size(); i++) { + for (idArrayIdx i = 0; i < m_body_prismatic_list.size(); i++) + { RigidBody &body = m_body_list[m_body_prismatic_list[i]]; // (*joint_forces)(body.m_q_index) = body.m_Jac_JT.transpose() * body.m_force_at_joint; (*joint_forces)(body.m_q_index) = body.m_Jac_JT.dot(body.m_force_at_joint); } // 4.3 floating bodies (6-DoF joints) - for (idArrayIdx i = 0; i < m_body_floating_list.size(); i++) { + for (idArrayIdx i = 0; i < m_body_floating_list.size(); i++) + { RigidBody &body = m_body_list[m_body_floating_list[i]]; (*joint_forces)(body.m_q_index + 0) = body.m_moment_at_joint(0); (*joint_forces)(body.m_q_index + 1) = body.m_moment_at_joint(1); @@ -319,50 +355,61 @@ int MultiBodyTree::MultiBodyImpl::calculateInverseDynamics(const vecx &q, const return 0; } -int MultiBodyTree::MultiBodyImpl::calculateKinematics(const vecx &q, const vecx &u, const vecx& dot_u, - const KinUpdateType type) { - if (q.size() != m_num_dofs || u.size() != m_num_dofs || dot_u.size() != m_num_dofs ) { - bt_id_error_message("wrong vector dimension. system has %d DOFs,\n" - "but dim(q)= %d, dim(u)= %d, dim(dot_u)= %d\n", - m_num_dofs, static_cast(q.size()), static_cast(u.size()), - static_cast(dot_u.size())); +int MultiBodyTree::MultiBodyImpl::calculateKinematics(const vecx &q, const vecx &u, const vecx &dot_u, + const KinUpdateType type) +{ + if (q.size() != m_num_dofs || u.size() != m_num_dofs || dot_u.size() != m_num_dofs) + { + bt_id_error_message( + "wrong vector dimension. system has %d DOFs,\n" + "but dim(q)= %d, dim(u)= %d, dim(dot_u)= %d\n", + m_num_dofs, static_cast(q.size()), static_cast(u.size()), + static_cast(dot_u.size())); + return -1; + } + if (type != POSITION_ONLY && type != POSITION_VELOCITY && type != POSITION_VELOCITY_ACCELERATION) + { + bt_id_error_message("invalid type %d\n", type); return -1; } - if(type != POSITION_ONLY && type != POSITION_VELOCITY && type != POSITION_VELOCITY_ACCELERATION) { - bt_id_error_message("invalid type %d\n", type); - return -1; - } // 1. update relative kinematics // 1.1 for revolute - for (idArrayIdx i = 0; i < m_body_revolute_list.size(); i++) { + for (idArrayIdx i = 0; i < m_body_revolute_list.size(); i++) + { RigidBody &body = m_body_list[m_body_revolute_list[i]]; mat33 T; bodyTParentFromAxisAngle(body.m_Jac_JR, q(body.m_q_index), &T); body.m_body_T_parent = T * body.m_body_T_parent_ref; - if(type >= POSITION_VELOCITY) { - body.m_body_ang_vel_rel = body.m_Jac_JR * u(body.m_q_index); - } - if(type >= POSITION_VELOCITY_ACCELERATION) { - body.m_body_ang_acc_rel = body.m_Jac_JR * dot_u(body.m_q_index); - } + if (type >= POSITION_VELOCITY) + { + body.m_body_ang_vel_rel = body.m_Jac_JR * u(body.m_q_index); + } + if (type >= POSITION_VELOCITY_ACCELERATION) + { + body.m_body_ang_acc_rel = body.m_Jac_JR * dot_u(body.m_q_index); + } } // 1.2 for prismatic - for (idArrayIdx i = 0; i < m_body_prismatic_list.size(); i++) { + for (idArrayIdx i = 0; i < m_body_prismatic_list.size(); i++) + { RigidBody &body = m_body_list[m_body_prismatic_list[i]]; body.m_parent_pos_parent_body = body.m_parent_pos_parent_body_ref + body.m_parent_Jac_JT * q(body.m_q_index); - if(type >= POSITION_VELOCITY) { - body.m_parent_vel_rel = - body.m_body_T_parent_ref.transpose() * body.m_Jac_JT * u(body.m_q_index); - } - if(type >= POSITION_VELOCITY_ACCELERATION) { - body.m_parent_acc_rel = body.m_parent_Jac_JT * dot_u(body.m_q_index); - } + if (type >= POSITION_VELOCITY) + { + body.m_parent_vel_rel = + body.m_body_T_parent_ref.transpose() * body.m_Jac_JT * u(body.m_q_index); + } + if (type >= POSITION_VELOCITY_ACCELERATION) + { + body.m_parent_acc_rel = body.m_parent_Jac_JT * dot_u(body.m_q_index); + } } // 1.3 fixed joints: nothing to do // 1.4 6dof joints: - for (idArrayIdx i = 0; i < m_body_floating_list.size(); i++) { + for (idArrayIdx i = 0; i < m_body_floating_list.size(); i++) + { RigidBody &body = m_body_list[m_body_floating_list[i]]; body.m_body_T_parent = transformZ(q(body.m_q_index + 2)) * @@ -372,28 +419,30 @@ int MultiBodyTree::MultiBodyImpl::calculateKinematics(const vecx &q, const vecx body.m_parent_pos_parent_body(2) = q(body.m_q_index + 5); body.m_parent_pos_parent_body = body.m_body_T_parent * body.m_parent_pos_parent_body; - if(type >= POSITION_VELOCITY) { - body.m_body_ang_vel_rel(0) = u(body.m_q_index + 0); - body.m_body_ang_vel_rel(1) = u(body.m_q_index + 1); - body.m_body_ang_vel_rel(2) = u(body.m_q_index + 2); + if (type >= POSITION_VELOCITY) + { + body.m_body_ang_vel_rel(0) = u(body.m_q_index + 0); + body.m_body_ang_vel_rel(1) = u(body.m_q_index + 1); + body.m_body_ang_vel_rel(2) = u(body.m_q_index + 2); - body.m_parent_vel_rel(0) = u(body.m_q_index + 3); - body.m_parent_vel_rel(1) = u(body.m_q_index + 4); - body.m_parent_vel_rel(2) = u(body.m_q_index + 5); + body.m_parent_vel_rel(0) = u(body.m_q_index + 3); + body.m_parent_vel_rel(1) = u(body.m_q_index + 4); + body.m_parent_vel_rel(2) = u(body.m_q_index + 5); - body.m_parent_vel_rel = body.m_body_T_parent.transpose() * body.m_parent_vel_rel; - } - if(type >= POSITION_VELOCITY_ACCELERATION) { - body.m_body_ang_acc_rel(0) = dot_u(body.m_q_index + 0); - body.m_body_ang_acc_rel(1) = dot_u(body.m_q_index + 1); - body.m_body_ang_acc_rel(2) = dot_u(body.m_q_index + 2); + body.m_parent_vel_rel = body.m_body_T_parent.transpose() * body.m_parent_vel_rel; + } + if (type >= POSITION_VELOCITY_ACCELERATION) + { + body.m_body_ang_acc_rel(0) = dot_u(body.m_q_index + 0); + body.m_body_ang_acc_rel(1) = dot_u(body.m_q_index + 1); + body.m_body_ang_acc_rel(2) = dot_u(body.m_q_index + 2); - body.m_parent_acc_rel(0) = dot_u(body.m_q_index + 3); - body.m_parent_acc_rel(1) = dot_u(body.m_q_index + 4); - body.m_parent_acc_rel(2) = dot_u(body.m_q_index + 5); + body.m_parent_acc_rel(0) = dot_u(body.m_q_index + 3); + body.m_parent_acc_rel(1) = dot_u(body.m_q_index + 4); + body.m_parent_acc_rel(2) = dot_u(body.m_q_index + 5); - body.m_parent_acc_rel = body.m_body_T_parent.transpose() * body.m_parent_acc_rel; - } + body.m_parent_acc_rel = body.m_body_T_parent.transpose() * body.m_parent_acc_rel; + } } // 2. absolute kinematic quantities (vector valued) @@ -410,26 +459,29 @@ int MultiBodyTree::MultiBodyImpl::calculateKinematics(const vecx &q, const vecx body.m_body_pos = body.m_body_T_parent * body.m_parent_pos_parent_body; body.m_body_T_world = body.m_body_T_parent; - if(type >= POSITION_VELOCITY) { - // 3.2 update absolute velocities - body.m_body_ang_vel = body.m_body_ang_vel_rel; - body.m_body_vel = body.m_parent_vel_rel; - } - if(type >= POSITION_VELOCITY_ACCELERATION) { - // 3.3 update absolute accelerations - // NOTE: assumption: dot(J_JR) = 0; true here, but not for general joints - body.m_body_ang_acc = body.m_body_ang_acc_rel; - body.m_body_acc = body.m_body_T_parent * body.m_parent_acc_rel; - // add gravitational acceleration to root body - // this is an efficient way to add gravitational terms, - // but it does mean that the kinematics are no longer - // correct at the acceleration level - // NOTE: To get correct acceleration kinematics, just set world_gravity to zero - body.m_body_acc = body.m_body_acc - body.m_body_T_parent * m_world_gravity; - } + if (type >= POSITION_VELOCITY) + { + // 3.2 update absolute velocities + body.m_body_ang_vel = body.m_body_ang_vel_rel; + body.m_body_vel = body.m_parent_vel_rel; + } + if (type >= POSITION_VELOCITY_ACCELERATION) + { + // 3.3 update absolute accelerations + // NOTE: assumption: dot(J_JR) = 0; true here, but not for general joints + body.m_body_ang_acc = body.m_body_ang_acc_rel; + body.m_body_acc = body.m_body_T_parent * body.m_parent_acc_rel; + // add gravitational acceleration to root body + // this is an efficient way to add gravitational terms, + // but it does mean that the kinematics are no longer + // correct at the acceleration level + // NOTE: To get correct acceleration kinematics, just set world_gravity to zero + body.m_body_acc = body.m_body_acc - body.m_body_T_parent * m_world_gravity; + } } - for (idArrayIdx i = 1; i < m_body_list.size(); i++) { + for (idArrayIdx i = 1; i < m_body_list.size(); i++) + { RigidBody &body = m_body_list[i]; RigidBody &parent = m_body_list[m_parent_index[i]]; // 2.1 update absolute positions and orientations: @@ -439,121 +491,127 @@ int MultiBodyTree::MultiBodyImpl::calculateKinematics(const vecx &q, const vecx body.m_body_T_parent * (parent.m_body_pos + body.m_parent_pos_parent_body); body.m_body_T_world = body.m_body_T_parent * parent.m_body_T_world; - if(type >= POSITION_VELOCITY) { - // 2.2 update absolute velocities - body.m_body_ang_vel = - body.m_body_T_parent * parent.m_body_ang_vel + body.m_body_ang_vel_rel; + if (type >= POSITION_VELOCITY) + { + // 2.2 update absolute velocities + body.m_body_ang_vel = + body.m_body_T_parent * parent.m_body_ang_vel + body.m_body_ang_vel_rel; - body.m_body_vel = - body.m_body_T_parent * - (parent.m_body_vel + parent.m_body_ang_vel.cross(body.m_parent_pos_parent_body) + - body.m_parent_vel_rel); - } - if(type >= POSITION_VELOCITY_ACCELERATION) { - // 2.3 update absolute accelerations - // NOTE: assumption: dot(J_JR) = 0; true here, but not for general joints - body.m_body_ang_acc = - body.m_body_T_parent * parent.m_body_ang_acc - - body.m_body_ang_vel_rel.cross(body.m_body_T_parent * parent.m_body_ang_vel) + - body.m_body_ang_acc_rel; - body.m_body_acc = - body.m_body_T_parent * - (parent.m_body_acc + parent.m_body_ang_acc.cross(body.m_parent_pos_parent_body) + - parent.m_body_ang_vel.cross(parent.m_body_ang_vel.cross(body.m_parent_pos_parent_body)) + - 2.0 * parent.m_body_ang_vel.cross(body.m_parent_vel_rel) + body.m_parent_acc_rel); - } + body.m_body_vel = + body.m_body_T_parent * + (parent.m_body_vel + parent.m_body_ang_vel.cross(body.m_parent_pos_parent_body) + + body.m_parent_vel_rel); + } + if (type >= POSITION_VELOCITY_ACCELERATION) + { + // 2.3 update absolute accelerations + // NOTE: assumption: dot(J_JR) = 0; true here, but not for general joints + body.m_body_ang_acc = + body.m_body_T_parent * parent.m_body_ang_acc - + body.m_body_ang_vel_rel.cross(body.m_body_T_parent * parent.m_body_ang_vel) + + body.m_body_ang_acc_rel; + body.m_body_acc = + body.m_body_T_parent * + (parent.m_body_acc + parent.m_body_ang_acc.cross(body.m_parent_pos_parent_body) + + parent.m_body_ang_vel.cross(parent.m_body_ang_vel.cross(body.m_parent_pos_parent_body)) + + 2.0 * parent.m_body_ang_vel.cross(body.m_parent_vel_rel) + body.m_parent_acc_rel); + } } - return 0; + return 0; } #if (defined BT_ID_HAVE_MAT3X) && (defined BT_ID_WITH_JACOBIANS) -void MultiBodyTree::MultiBodyImpl::addRelativeJacobianComponent(RigidBody&body) { - const int& idx=body.m_q_index; - switch(body.m_joint_type) { - case FIXED: - break; - case REVOLUTE: - setMat3xElem(0,idx, body.m_Jac_JR(0), &body.m_body_Jac_R); - setMat3xElem(1,idx, body.m_Jac_JR(1), &body.m_body_Jac_R); - setMat3xElem(2,idx, body.m_Jac_JR(2), &body.m_body_Jac_R); - break; - case PRISMATIC: - setMat3xElem(0,idx, body.m_body_T_parent_ref(0,0)*body.m_Jac_JT(0) - +body.m_body_T_parent_ref(1,0)*body.m_Jac_JT(1) - +body.m_body_T_parent_ref(2,0)*body.m_Jac_JT(2), - &body.m_body_Jac_T); - setMat3xElem(1,idx,body.m_body_T_parent_ref(0,1)*body.m_Jac_JT(0) - +body.m_body_T_parent_ref(1,1)*body.m_Jac_JT(1) - +body.m_body_T_parent_ref(2,1)*body.m_Jac_JT(2), - &body.m_body_Jac_T); - setMat3xElem(2,idx, body.m_body_T_parent_ref(0,2)*body.m_Jac_JT(0) - +body.m_body_T_parent_ref(1,2)*body.m_Jac_JT(1) - +body.m_body_T_parent_ref(2,2)*body.m_Jac_JT(2), - &body.m_body_Jac_T); - break; - case FLOATING: - setMat3xElem(0,idx+0, 1.0, &body.m_body_Jac_R); - setMat3xElem(1,idx+1, 1.0, &body.m_body_Jac_R); - setMat3xElem(2,idx+2, 1.0, &body.m_body_Jac_R); - // body_Jac_T = body_T_parent.transpose(); - setMat3xElem(0,idx+3, body.m_body_T_parent(0,0), &body.m_body_Jac_T); - setMat3xElem(0,idx+4, body.m_body_T_parent(1,0), &body.m_body_Jac_T); - setMat3xElem(0,idx+5, body.m_body_T_parent(2,0), &body.m_body_Jac_T); +void MultiBodyTree::MultiBodyImpl::addRelativeJacobianComponent(RigidBody &body) +{ + const int &idx = body.m_q_index; + switch (body.m_joint_type) + { + case FIXED: + break; + case REVOLUTE: + setMat3xElem(0, idx, body.m_Jac_JR(0), &body.m_body_Jac_R); + setMat3xElem(1, idx, body.m_Jac_JR(1), &body.m_body_Jac_R); + setMat3xElem(2, idx, body.m_Jac_JR(2), &body.m_body_Jac_R); + break; + case PRISMATIC: + setMat3xElem(0, idx, body.m_body_T_parent_ref(0, 0) * body.m_Jac_JT(0) + body.m_body_T_parent_ref(1, 0) * body.m_Jac_JT(1) + body.m_body_T_parent_ref(2, 0) * body.m_Jac_JT(2), + &body.m_body_Jac_T); + setMat3xElem(1, idx, body.m_body_T_parent_ref(0, 1) * body.m_Jac_JT(0) + body.m_body_T_parent_ref(1, 1) * body.m_Jac_JT(1) + body.m_body_T_parent_ref(2, 1) * body.m_Jac_JT(2), + &body.m_body_Jac_T); + setMat3xElem(2, idx, body.m_body_T_parent_ref(0, 2) * body.m_Jac_JT(0) + body.m_body_T_parent_ref(1, 2) * body.m_Jac_JT(1) + body.m_body_T_parent_ref(2, 2) * body.m_Jac_JT(2), + &body.m_body_Jac_T); + break; + case FLOATING: + setMat3xElem(0, idx + 0, 1.0, &body.m_body_Jac_R); + setMat3xElem(1, idx + 1, 1.0, &body.m_body_Jac_R); + setMat3xElem(2, idx + 2, 1.0, &body.m_body_Jac_R); + // body_Jac_T = body_T_parent.transpose(); + setMat3xElem(0, idx + 3, body.m_body_T_parent(0, 0), &body.m_body_Jac_T); + setMat3xElem(0, idx + 4, body.m_body_T_parent(1, 0), &body.m_body_Jac_T); + setMat3xElem(0, idx + 5, body.m_body_T_parent(2, 0), &body.m_body_Jac_T); - setMat3xElem(1,idx+3, body.m_body_T_parent(0,1), &body.m_body_Jac_T); - setMat3xElem(1,idx+4, body.m_body_T_parent(1,1), &body.m_body_Jac_T); - setMat3xElem(1,idx+5, body.m_body_T_parent(2,1), &body.m_body_Jac_T); + setMat3xElem(1, idx + 3, body.m_body_T_parent(0, 1), &body.m_body_Jac_T); + setMat3xElem(1, idx + 4, body.m_body_T_parent(1, 1), &body.m_body_Jac_T); + setMat3xElem(1, idx + 5, body.m_body_T_parent(2, 1), &body.m_body_Jac_T); - setMat3xElem(2,idx+3, body.m_body_T_parent(0,2), &body.m_body_Jac_T); - setMat3xElem(2,idx+4, body.m_body_T_parent(1,2), &body.m_body_Jac_T); - setMat3xElem(2,idx+5, body.m_body_T_parent(2,2), &body.m_body_Jac_T); + setMat3xElem(2, idx + 3, body.m_body_T_parent(0, 2), &body.m_body_Jac_T); + setMat3xElem(2, idx + 4, body.m_body_T_parent(1, 2), &body.m_body_Jac_T); + setMat3xElem(2, idx + 5, body.m_body_T_parent(2, 2), &body.m_body_Jac_T); - break; - } + break; + } } -int MultiBodyTree::MultiBodyImpl::calculateJacobians(const vecx& q, const vecx& u, const KinUpdateType type) { - if (q.size() != m_num_dofs || u.size() != m_num_dofs) { - bt_id_error_message("wrong vector dimension. system has %d DOFs,\n" - "but dim(q)= %d, dim(u)= %d\n", - m_num_dofs, static_cast(q.size()), static_cast(u.size())); - return -1; - } - if(type != POSITION_ONLY && type != POSITION_VELOCITY) { - bt_id_error_message("invalid type %d\n", type); - return -1; - } +int MultiBodyTree::MultiBodyImpl::calculateJacobians(const vecx &q, const vecx &u, const KinUpdateType type) +{ + if (q.size() != m_num_dofs || u.size() != m_num_dofs) + { + bt_id_error_message( + "wrong vector dimension. system has %d DOFs,\n" + "but dim(q)= %d, dim(u)= %d\n", + m_num_dofs, static_cast(q.size()), static_cast(u.size())); + return -1; + } + if (type != POSITION_ONLY && type != POSITION_VELOCITY) + { + bt_id_error_message("invalid type %d\n", type); + return -1; + } - addRelativeJacobianComponent(m_body_list[0]); - for (idArrayIdx i = 1; i < m_body_list.size(); i++) { - RigidBody &body = m_body_list[i]; - RigidBody &parent = m_body_list[m_parent_index[i]]; + addRelativeJacobianComponent(m_body_list[0]); + for (idArrayIdx i = 1; i < m_body_list.size(); i++) + { + RigidBody &body = m_body_list[i]; + RigidBody &parent = m_body_list[m_parent_index[i]]; - mul(body.m_body_T_parent, parent.m_body_Jac_R,& body.m_body_Jac_R); - body.m_body_Jac_T = parent.m_body_Jac_T; - mul(tildeOperator(body.m_parent_pos_parent_body),parent.m_body_Jac_R,&m_m3x); - sub(body.m_body_Jac_T,m_m3x, &body.m_body_Jac_T); + mul(body.m_body_T_parent, parent.m_body_Jac_R, &body.m_body_Jac_R); + body.m_body_Jac_T = parent.m_body_Jac_T; + mul(tildeOperator(body.m_parent_pos_parent_body), parent.m_body_Jac_R, &m_m3x); + sub(body.m_body_Jac_T, m_m3x, &body.m_body_Jac_T); - addRelativeJacobianComponent(body); - mul(body.m_body_T_parent, body.m_body_Jac_T,&body.m_body_Jac_T); + addRelativeJacobianComponent(body); + mul(body.m_body_T_parent, body.m_body_Jac_T, &body.m_body_Jac_T); - if(type >= POSITION_VELOCITY) { - body.m_body_dot_Jac_R_u = body.m_body_T_parent * parent.m_body_dot_Jac_R_u - - body.m_body_ang_vel_rel.cross(body.m_body_T_parent * parent.m_body_ang_vel); - body.m_body_dot_Jac_T_u = body.m_body_T_parent * - (parent.m_body_dot_Jac_T_u + parent.m_body_dot_Jac_R_u.cross(body.m_parent_pos_parent_body) + - parent.m_body_ang_vel.cross(parent.m_body_ang_vel.cross(body.m_parent_pos_parent_body)) + - 2.0 * parent.m_body_ang_vel.cross(body.m_parent_vel_rel)); - } - } - return 0; + if (type >= POSITION_VELOCITY) + { + body.m_body_dot_Jac_R_u = body.m_body_T_parent * parent.m_body_dot_Jac_R_u - + body.m_body_ang_vel_rel.cross(body.m_body_T_parent * parent.m_body_ang_vel); + body.m_body_dot_Jac_T_u = body.m_body_T_parent * + (parent.m_body_dot_Jac_T_u + parent.m_body_dot_Jac_R_u.cross(body.m_parent_pos_parent_body) + + parent.m_body_ang_vel.cross(parent.m_body_ang_vel.cross(body.m_parent_pos_parent_body)) + + 2.0 * parent.m_body_ang_vel.cross(body.m_parent_vel_rel)); + } + } + return 0; } #endif -static inline void setSixDoFJacobians(const int dof, vec3 &Jac_JR, vec3 &Jac_JT) { - switch (dof) { +static inline void setSixDoFJacobians(const int dof, vec3 &Jac_JR, vec3 &Jac_JT) +{ + switch (dof) + { // rotational part case 0: Jac_JR(0) = 1; @@ -595,8 +653,10 @@ static inline void setSixDoFJacobians(const int dof, vec3 &Jac_JR, vec3 &Jac_JT) } } -static inline int jointNumDoFs(const JointType &type) { - switch (type) { +static inline int jointNumDoFs(const JointType &type) +{ + switch (type) + { case FIXED: return 0; case REVOLUTE: @@ -615,37 +675,45 @@ static inline int jointNumDoFs(const JointType &type) { int MultiBodyTree::MultiBodyImpl::calculateMassMatrix(const vecx &q, const bool update_kinematics, const bool initialize_matrix, const bool set_lower_triangular_matrix, - matxx *mass_matrix) { -// This calculates the joint space mass matrix for the multibody system. -// The algorithm is essentially an implementation of "method 3" -// in "Efficient Dynamic Simulation of Robotic Mechanisms" (Walker and Orin, 1982) -// (Later named "Composite Rigid Body Algorithm" by Featherstone). -// -// This implementation, however, handles branched systems and uses a formulation centered -// on the origin of the body-fixed frame to avoid re-computing various quantities at the com. + matxx *mass_matrix) +{ + // This calculates the joint space mass matrix for the multibody system. + // The algorithm is essentially an implementation of "method 3" + // in "Efficient Dynamic Simulation of Robotic Mechanisms" (Walker and Orin, 1982) + // (Later named "Composite Rigid Body Algorithm" by Featherstone). + // + // This implementation, however, handles branched systems and uses a formulation centered + // on the origin of the body-fixed frame to avoid re-computing various quantities at the com. if (q.size() != m_num_dofs || mass_matrix->rows() != m_num_dofs || - mass_matrix->cols() != m_num_dofs) { - bt_id_error_message("Dimension error. System has %d DOFs,\n" - "but dim(q)= %d, dim(mass_matrix)= %d x %d\n", - m_num_dofs, static_cast(q.size()), static_cast(mass_matrix->rows()), - static_cast(mass_matrix->cols())); + mass_matrix->cols() != m_num_dofs) + { + bt_id_error_message( + "Dimension error. System has %d DOFs,\n" + "but dim(q)= %d, dim(mass_matrix)= %d x %d\n", + m_num_dofs, static_cast(q.size()), static_cast(mass_matrix->rows()), + static_cast(mass_matrix->cols())); return -1; } // TODO add optimized zeroing function? - if (initialize_matrix) { - for (int i = 0; i < m_num_dofs; i++) { - for (int j = 0; j < m_num_dofs; j++) { - setMatxxElem(i, j, 0.0, mass_matrix); + if (initialize_matrix) + { + for (int i = 0; i < m_num_dofs; i++) + { + for (int j = 0; j < m_num_dofs; j++) + { + setMatxxElem(i, j, 0.0, mass_matrix); } } } - if (update_kinematics) { + if (update_kinematics) + { // 1. update relative kinematics // 1.1 for revolute joints - for (idArrayIdx i = 0; i < m_body_revolute_list.size(); i++) { + for (idArrayIdx i = 0; i < m_body_revolute_list.size(); i++) + { RigidBody &body = m_body_list[m_body_revolute_list[i]]; // from reference orientation (q=0) of body-fixed frame to current orientation mat33 body_T_body_ref; @@ -653,7 +721,8 @@ int MultiBodyTree::MultiBodyImpl::calculateMassMatrix(const vecx &q, const bool body.m_body_T_parent = body_T_body_ref * body.m_body_T_parent_ref; } // 1.2 for prismatic joints - for (idArrayIdx i = 0; i < m_body_prismatic_list.size(); i++) { + for (idArrayIdx i = 0; i < m_body_prismatic_list.size(); i++) + { RigidBody &body = m_body_list[m_body_prismatic_list[i]]; // body.m_body_T_parent= fixed body.m_parent_pos_parent_body = @@ -661,7 +730,8 @@ int MultiBodyTree::MultiBodyImpl::calculateMassMatrix(const vecx &q, const bool } // 1.3 fixed joints: nothing to do // 1.4 6dof joints: - for (idArrayIdx i = 0; i < m_body_floating_list.size(); i++) { + for (idArrayIdx i = 0; i < m_body_floating_list.size(); i++) + { RigidBody &body = m_body_list[m_body_floating_list[i]]; body.m_body_T_parent = transformZ(q(body.m_q_index + 2)) * @@ -674,7 +744,8 @@ int MultiBodyTree::MultiBodyImpl::calculateMassMatrix(const vecx &q, const bool body.m_parent_pos_parent_body = body.m_body_T_parent * body.m_parent_pos_parent_body; } } - for (int i = m_body_list.size() - 1; i >= 0; i--) { + for (int i = m_body_list.size() - 1; i >= 0; i--) + { RigidBody &body = m_body_list[i]; // calculate mass, center of mass and inertia of "composite rigid body", // ie, sub-tree starting at current body @@ -682,7 +753,8 @@ int MultiBodyTree::MultiBodyImpl::calculateMassMatrix(const vecx &q, const bool body.m_body_subtree_mass_com = body.m_body_mass_com; body.m_body_subtree_I_body = body.m_body_I_body; - for (idArrayIdx c = 0; c < m_child_indices[i].size(); c++) { + for (idArrayIdx c = 0; c < m_child_indices[i].size(); c++) + { RigidBody &child = m_body_list[m_child_indices[i][c]]; mat33 body_T_child = child.m_body_T_parent.transpose(); @@ -692,7 +764,8 @@ int MultiBodyTree::MultiBodyImpl::calculateMassMatrix(const vecx &q, const bool body.m_body_subtree_I_body += body_T_child * child.m_body_subtree_I_body * child.m_body_T_parent; - if (child.m_subtree_mass > 0) { + if (child.m_subtree_mass > 0) + { // Shift the reference point for the child subtree inertia using the // Huygens-Steiner ("parallel axis") theorem. // (First shift from child origin to child com, then from there to this body's @@ -707,7 +780,8 @@ int MultiBodyTree::MultiBodyImpl::calculateMassMatrix(const vecx &q, const bool } } - for (int i = m_body_list.size() - 1; i >= 0; i--) { + for (int i = m_body_list.size() - 1; i >= 0; i--) + { const RigidBody &body = m_body_list[i]; // determine DoF-range for body @@ -717,9 +791,11 @@ int MultiBodyTree::MultiBodyImpl::calculateMassMatrix(const vecx &q, const bool // local joint jacobians (ok as is for 1-DoF joints) vec3 Jac_JR = body.m_Jac_JR; vec3 Jac_JT = body.m_Jac_JT; - for (int col = q_index_max; col >= q_index_min; col--) { + for (int col = q_index_max; col >= q_index_min; col--) + { // set jacobians for 6-DoF joints - if (FLOATING == body.m_joint_type) { + if (FLOATING == body.m_joint_type) + { setSixDoFJacobians(col - q_index_min, Jac_JR, Jac_JT); } @@ -732,8 +808,10 @@ int MultiBodyTree::MultiBodyImpl::calculateMassMatrix(const vecx &q, const bool // rest of the mass matrix column upwards { // 1. for multi-dof joints, rest of the dofs of this body - for (int row = col - 1; row >= q_index_min; row--) { - if (FLOATING != body.m_joint_type) { + for (int row = col - 1; row >= q_index_min; row--) + { + if (FLOATING != body.m_joint_type) + { bt_id_error_message("??\n"); return -1; } @@ -744,7 +822,8 @@ int MultiBodyTree::MultiBodyImpl::calculateMassMatrix(const vecx &q, const bool // 2. ancestor dofs int child_idx = i; int parent_idx = m_parent_index[i]; - while (parent_idx >= 0) { + while (parent_idx >= 0) + { const RigidBody &child_body = m_body_list[child_idx]; const RigidBody &parent_body = m_body_list[parent_idx]; @@ -758,9 +837,11 @@ int MultiBodyTree::MultiBodyImpl::calculateMassMatrix(const vecx &q, const bool parent_body_q_index_min + jointNumDoFs(parent_body.m_joint_type) - 1; vec3 Jac_JR = parent_body.m_Jac_JR; vec3 Jac_JT = parent_body.m_Jac_JT; - for (int row = parent_body_q_index_max; row >= parent_body_q_index_min; row--) { + for (int row = parent_body_q_index_max; row >= parent_body_q_index_min; row--) + { // set jacobians for 6-DoF joints - if (FLOATING == parent_body.m_joint_type) { + if (FLOATING == parent_body.m_joint_type) + { setSixDoFJacobians(row - parent_body_q_index_min, Jac_JR, Jac_JT); } const double Mrc = Jac_JR.dot(body_eom_rot) + Jac_JT.dot(body_eom_trans); @@ -774,10 +855,13 @@ int MultiBodyTree::MultiBodyImpl::calculateMassMatrix(const vecx &q, const bool } } - if (set_lower_triangular_matrix) { - for (int col = 0; col < m_num_dofs; col++) { - for (int row = 0; row < col; row++) { - setMatxxElem(row, col, (*mass_matrix)(col, row), mass_matrix); + if (set_lower_triangular_matrix) + { + for (int col = 0; col < m_num_dofs; col++) + { + for (int row = 0; row < col; row++) + { + setMatxxElem(row, col, (*mass_matrix)(col, row), mass_matrix); } } } @@ -785,76 +869,91 @@ int MultiBodyTree::MultiBodyImpl::calculateMassMatrix(const vecx &q, const bool } // utility macro -#define CHECK_IF_BODY_INDEX_IS_VALID(index) \ - do { \ - if (index < 0 || index >= m_num_bodies) { \ - bt_id_error_message("invalid index %d (num_bodies= %d)\n", index, m_num_bodies); \ - return -1; \ - } \ +#define CHECK_IF_BODY_INDEX_IS_VALID(index) \ + do \ + { \ + if (index < 0 || index >= m_num_bodies) \ + { \ + bt_id_error_message("invalid index %d (num_bodies= %d)\n", index, m_num_bodies); \ + return -1; \ + } \ } while (0) -int MultiBodyTree::MultiBodyImpl::getParentIndex(const int body_index, int *p) { +int MultiBodyTree::MultiBodyImpl::getParentIndex(const int body_index, int *p) +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); *p = m_parent_index[body_index]; return 0; } -int MultiBodyTree::MultiBodyImpl::getUserInt(const int body_index, int *user_int) const { +int MultiBodyTree::MultiBodyImpl::getUserInt(const int body_index, int *user_int) const +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); *user_int = m_user_int[body_index]; return 0; } -int MultiBodyTree::MultiBodyImpl::getUserPtr(const int body_index, void **user_ptr) const { +int MultiBodyTree::MultiBodyImpl::getUserPtr(const int body_index, void **user_ptr) const +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); *user_ptr = m_user_ptr[body_index]; return 0; } -int MultiBodyTree::MultiBodyImpl::setUserInt(const int body_index, const int user_int) { +int MultiBodyTree::MultiBodyImpl::setUserInt(const int body_index, const int user_int) +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); m_user_int[body_index] = user_int; return 0; } -int MultiBodyTree::MultiBodyImpl::setUserPtr(const int body_index, void *const user_ptr) { +int MultiBodyTree::MultiBodyImpl::setUserPtr(const int body_index, void *const user_ptr) +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); m_user_ptr[body_index] = user_ptr; return 0; } -int MultiBodyTree::MultiBodyImpl::getBodyOrigin(int body_index, vec3 *world_origin) const { +int MultiBodyTree::MultiBodyImpl::getBodyOrigin(int body_index, vec3 *world_origin) const +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); const RigidBody &body = m_body_list[body_index]; *world_origin = body.m_body_T_world.transpose() * body.m_body_pos; return 0; } -int MultiBodyTree::MultiBodyImpl::getBodyCoM(int body_index, vec3 *world_com) const { +int MultiBodyTree::MultiBodyImpl::getBodyCoM(int body_index, vec3 *world_com) const +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); const RigidBody &body = m_body_list[body_index]; - if (body.m_mass > 0) { + if (body.m_mass > 0) + { *world_com = body.m_body_T_world.transpose() * (body.m_body_pos + body.m_body_mass_com / body.m_mass); - } else { + } + else + { *world_com = body.m_body_T_world.transpose() * (body.m_body_pos); } return 0; } -int MultiBodyTree::MultiBodyImpl::getBodyTransform(int body_index, mat33 *world_T_body) const { +int MultiBodyTree::MultiBodyImpl::getBodyTransform(int body_index, mat33 *world_T_body) const +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); const RigidBody &body = m_body_list[body_index]; *world_T_body = body.m_body_T_world.transpose(); return 0; } -int MultiBodyTree::MultiBodyImpl::getBodyAngularVelocity(int body_index, vec3 *world_omega) const { +int MultiBodyTree::MultiBodyImpl::getBodyAngularVelocity(int body_index, vec3 *world_omega) const +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); const RigidBody &body = m_body_list[body_index]; *world_omega = body.m_body_T_world.transpose() * body.m_body_ang_vel; return 0; } int MultiBodyTree::MultiBodyImpl::getBodyLinearVelocity(int body_index, - vec3 *world_velocity) const { + vec3 *world_velocity) const +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); const RigidBody &body = m_body_list[body_index]; *world_velocity = body.m_body_T_world.transpose() * body.m_body_vel; @@ -862,13 +961,17 @@ int MultiBodyTree::MultiBodyImpl::getBodyLinearVelocity(int body_index, } int MultiBodyTree::MultiBodyImpl::getBodyLinearVelocityCoM(int body_index, - vec3 *world_velocity) const { + vec3 *world_velocity) const +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); const RigidBody &body = m_body_list[body_index]; vec3 com; - if (body.m_mass > 0) { + if (body.m_mass > 0) + { com = body.m_body_mass_com / body.m_mass; - } else { + } + else + { com(0) = 0; com(1) = 0; com(2) = 0; @@ -880,149 +983,173 @@ int MultiBodyTree::MultiBodyImpl::getBodyLinearVelocityCoM(int body_index, } int MultiBodyTree::MultiBodyImpl::getBodyAngularAcceleration(int body_index, - vec3 *world_dot_omega) const { + vec3 *world_dot_omega) const +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); const RigidBody &body = m_body_list[body_index]; *world_dot_omega = body.m_body_T_world.transpose() * body.m_body_ang_acc; return 0; } int MultiBodyTree::MultiBodyImpl::getBodyLinearAcceleration(int body_index, - vec3 *world_acceleration) const { + vec3 *world_acceleration) const +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); const RigidBody &body = m_body_list[body_index]; *world_acceleration = body.m_body_T_world.transpose() * body.m_body_acc; return 0; } -int MultiBodyTree::MultiBodyImpl::getJointType(const int body_index, JointType *joint_type) const { +int MultiBodyTree::MultiBodyImpl::getJointType(const int body_index, JointType *joint_type) const +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); *joint_type = m_body_list[body_index].m_joint_type; return 0; } int MultiBodyTree::MultiBodyImpl::getJointTypeStr(const int body_index, - const char **joint_type) const { + const char **joint_type) const +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); *joint_type = jointTypeToString(m_body_list[body_index].m_joint_type); return 0; } -int MultiBodyTree::MultiBodyImpl::getParentRParentBodyRef(const int body_index, vec3* r) const{ - CHECK_IF_BODY_INDEX_IS_VALID(body_index); - *r=m_body_list[body_index].m_parent_pos_parent_body_ref; - return 0; +int MultiBodyTree::MultiBodyImpl::getParentRParentBodyRef(const int body_index, vec3 *r) const +{ + CHECK_IF_BODY_INDEX_IS_VALID(body_index); + *r = m_body_list[body_index].m_parent_pos_parent_body_ref; + return 0; } -int MultiBodyTree::MultiBodyImpl::getBodyTParentRef(const int body_index, mat33* T) const{ - CHECK_IF_BODY_INDEX_IS_VALID(body_index); - *T=m_body_list[body_index].m_body_T_parent_ref; - return 0; +int MultiBodyTree::MultiBodyImpl::getBodyTParentRef(const int body_index, mat33 *T) const +{ + CHECK_IF_BODY_INDEX_IS_VALID(body_index); + *T = m_body_list[body_index].m_body_T_parent_ref; + return 0; } -int MultiBodyTree::MultiBodyImpl::getBodyAxisOfMotion(const int body_index, vec3* axis) const{ - CHECK_IF_BODY_INDEX_IS_VALID(body_index); - if(m_body_list[body_index].m_joint_type == REVOLUTE) { - *axis = m_body_list[body_index].m_Jac_JR; - return 0; - } - if(m_body_list[body_index].m_joint_type == PRISMATIC) { - *axis = m_body_list[body_index].m_Jac_JT; - return 0; - } - setZero(*axis); - return 0; +int MultiBodyTree::MultiBodyImpl::getBodyAxisOfMotion(const int body_index, vec3 *axis) const +{ + CHECK_IF_BODY_INDEX_IS_VALID(body_index); + if (m_body_list[body_index].m_joint_type == REVOLUTE) + { + *axis = m_body_list[body_index].m_Jac_JR; + return 0; + } + if (m_body_list[body_index].m_joint_type == PRISMATIC) + { + *axis = m_body_list[body_index].m_Jac_JT; + return 0; + } + setZero(*axis); + return 0; } -int MultiBodyTree::MultiBodyImpl::getDoFOffset(const int body_index, int *q_index) const { +int MultiBodyTree::MultiBodyImpl::getDoFOffset(const int body_index, int *q_index) const +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); *q_index = m_body_list[body_index].m_q_index; return 0; } -int MultiBodyTree::MultiBodyImpl::setBodyMass(const int body_index, const idScalar mass) { +int MultiBodyTree::MultiBodyImpl::setBodyMass(const int body_index, const idScalar mass) +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); m_body_list[body_index].m_mass = mass; return 0; } int MultiBodyTree::MultiBodyImpl::setBodyFirstMassMoment(const int body_index, - const vec3& first_mass_moment) { + const vec3 &first_mass_moment) +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); m_body_list[body_index].m_body_mass_com = first_mass_moment; return 0; } int MultiBodyTree::MultiBodyImpl::setBodySecondMassMoment(const int body_index, - const mat33& second_mass_moment) { + const mat33 &second_mass_moment) +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); m_body_list[body_index].m_body_I_body = second_mass_moment; return 0; } -int MultiBodyTree::MultiBodyImpl::getBodyMass(const int body_index, idScalar *mass) const { +int MultiBodyTree::MultiBodyImpl::getBodyMass(const int body_index, idScalar *mass) const +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); *mass = m_body_list[body_index].m_mass; return 0; } int MultiBodyTree::MultiBodyImpl::getBodyFirstMassMoment(const int body_index, - vec3 *first_mass_moment) const { + vec3 *first_mass_moment) const +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); *first_mass_moment = m_body_list[body_index].m_body_mass_com; return 0; } int MultiBodyTree::MultiBodyImpl::getBodySecondMassMoment(const int body_index, - mat33 *second_mass_moment) const { + mat33 *second_mass_moment) const +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); *second_mass_moment = m_body_list[body_index].m_body_I_body; return 0; } -void MultiBodyTree::MultiBodyImpl::clearAllUserForcesAndMoments() { - for (int index = 0; index < m_num_bodies; index++) { +void MultiBodyTree::MultiBodyImpl::clearAllUserForcesAndMoments() +{ + for (int index = 0; index < m_num_bodies; index++) + { RigidBody &body = m_body_list[index]; setZero(body.m_body_force_user); setZero(body.m_body_moment_user); } } -int MultiBodyTree::MultiBodyImpl::addUserForce(const int body_index, const vec3 &body_force) { +int MultiBodyTree::MultiBodyImpl::addUserForce(const int body_index, const vec3 &body_force) +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); m_body_list[body_index].m_body_force_user += body_force; return 0; } -int MultiBodyTree::MultiBodyImpl::addUserMoment(const int body_index, const vec3 &body_moment) { +int MultiBodyTree::MultiBodyImpl::addUserMoment(const int body_index, const vec3 &body_moment) +{ CHECK_IF_BODY_INDEX_IS_VALID(body_index); m_body_list[body_index].m_body_moment_user += body_moment; return 0; } #if (defined BT_ID_HAVE_MAT3X) && (defined BT_ID_WITH_JACOBIANS) -int MultiBodyTree::MultiBodyImpl::getBodyDotJacobianTransU(const int body_index, vec3* world_dot_jac_trans_u) const { - CHECK_IF_BODY_INDEX_IS_VALID(body_index); - const RigidBody &body = m_body_list[body_index]; - *world_dot_jac_trans_u = body.m_body_T_world.transpose() * body.m_body_dot_Jac_T_u; - return 0; +int MultiBodyTree::MultiBodyImpl::getBodyDotJacobianTransU(const int body_index, vec3 *world_dot_jac_trans_u) const +{ + CHECK_IF_BODY_INDEX_IS_VALID(body_index); + const RigidBody &body = m_body_list[body_index]; + *world_dot_jac_trans_u = body.m_body_T_world.transpose() * body.m_body_dot_Jac_T_u; + return 0; } -int MultiBodyTree::MultiBodyImpl::getBodyDotJacobianRotU(const int body_index, vec3* world_dot_jac_rot_u) const{ - CHECK_IF_BODY_INDEX_IS_VALID(body_index); - const RigidBody &body = m_body_list[body_index]; - *world_dot_jac_rot_u = body.m_body_T_world.transpose() * body.m_body_dot_Jac_R_u; - return 0; +int MultiBodyTree::MultiBodyImpl::getBodyDotJacobianRotU(const int body_index, vec3 *world_dot_jac_rot_u) const +{ + CHECK_IF_BODY_INDEX_IS_VALID(body_index); + const RigidBody &body = m_body_list[body_index]; + *world_dot_jac_rot_u = body.m_body_T_world.transpose() * body.m_body_dot_Jac_R_u; + return 0; } -int MultiBodyTree::MultiBodyImpl::getBodyJacobianTrans(const int body_index, mat3x* world_jac_trans) const{ - CHECK_IF_BODY_INDEX_IS_VALID(body_index); - const RigidBody &body = m_body_list[body_index]; - mul(body.m_body_T_world.transpose(), body.m_body_Jac_T, world_jac_trans); - return 0; +int MultiBodyTree::MultiBodyImpl::getBodyJacobianTrans(const int body_index, mat3x *world_jac_trans) const +{ + CHECK_IF_BODY_INDEX_IS_VALID(body_index); + const RigidBody &body = m_body_list[body_index]; + mul(body.m_body_T_world.transpose(), body.m_body_Jac_T, world_jac_trans); + return 0; } -int MultiBodyTree::MultiBodyImpl::getBodyJacobianRot(const int body_index, mat3x* world_jac_rot) const{ - CHECK_IF_BODY_INDEX_IS_VALID(body_index); - const RigidBody &body = m_body_list[body_index]; - mul(body.m_body_T_world.transpose(), body.m_body_Jac_R,world_jac_rot); - return 0; +int MultiBodyTree::MultiBodyImpl::getBodyJacobianRot(const int body_index, mat3x *world_jac_rot) const +{ + CHECK_IF_BODY_INDEX_IS_VALID(body_index); + const RigidBody &body = m_body_list[body_index]; + mul(body.m_body_T_world.transpose(), body.m_body_Jac_R, world_jac_rot); + return 0; } #endif -} +} // namespace btInverseDynamics diff --git a/src/BulletInverseDynamics/details/MultiBodyTreeImpl.hpp b/src/BulletInverseDynamics/details/MultiBodyTreeImpl.hpp index 3efe9d049..d858ff859 100644 --- a/src/BulletInverseDynamics/details/MultiBodyTreeImpl.hpp +++ b/src/BulletInverseDynamics/details/MultiBodyTreeImpl.hpp @@ -8,12 +8,13 @@ #include "../IDConfig.hpp" #include "../MultiBodyTree.hpp" -namespace btInverseDynamics { - +namespace btInverseDynamics +{ /// Structure for for rigid body mass properties, connectivity and kinematic state /// all vectors and matrices are in body-fixed frame, if not indicated otherwise. /// The body-fixed frame is located in the joint connecting the body to its parent. -struct RigidBody { +struct RigidBody +{ ID_DECLARE_ALIGNED_ALLOCATOR(); // 1 Inertial properties /// Mass @@ -112,31 +113,33 @@ struct RigidBody { mat33 m_body_subtree_I_body; #if (defined BT_ID_HAVE_MAT3X) && (defined BT_ID_WITH_JACOBIANS) - /// translational jacobian in body-fixed frame d(m_body_vel)/du - mat3x m_body_Jac_T; - /// rotationsl jacobian in body-fixed frame d(m_body_ang_vel)/du - mat3x m_body_Jac_R; - /// components of linear acceleration depending on u - /// (same as is d(m_Jac_T)/dt*u) - vec3 m_body_dot_Jac_T_u; - /// components of angular acceleration depending on u - /// (same as is d(m_Jac_T)/dt*u) - vec3 m_body_dot_Jac_R_u; + /// translational jacobian in body-fixed frame d(m_body_vel)/du + mat3x m_body_Jac_T; + /// rotationsl jacobian in body-fixed frame d(m_body_ang_vel)/du + mat3x m_body_Jac_R; + /// components of linear acceleration depending on u + /// (same as is d(m_Jac_T)/dt*u) + vec3 m_body_dot_Jac_T_u; + /// components of angular acceleration depending on u + /// (same as is d(m_Jac_T)/dt*u) + vec3 m_body_dot_Jac_R_u; #endif }; /// The MBS implements a tree structured multibody system -class MultiBodyTree::MultiBodyImpl { +class MultiBodyTree::MultiBodyImpl +{ friend class MultiBodyTree; public: ID_DECLARE_ALIGNED_ALLOCATOR(); - enum KinUpdateType { - POSITION_ONLY, - POSITION_VELOCITY, - POSITION_VELOCITY_ACCELERATION - }; + enum KinUpdateType + { + POSITION_ONLY, + POSITION_VELOCITY, + POSITION_VELOCITY_ACCELERATION + }; /// constructor /// @param num_bodies the number of bodies in the system @@ -150,24 +153,24 @@ public: int calculateMassMatrix(const vecx& q, const bool update_kinematics, const bool initialize_matrix, const bool set_lower_triangular_matrix, matxx* mass_matrix); - /// calculate kinematics (vector quantities) - /// Depending on type, update positions only, positions & velocities, or positions, velocities - /// and accelerations. - int calculateKinematics(const vecx& q, const vecx& u, const vecx& dot_u, const KinUpdateType type); + /// calculate kinematics (vector quantities) + /// Depending on type, update positions only, positions & velocities, or positions, velocities + /// and accelerations. + int calculateKinematics(const vecx& q, const vecx& u, const vecx& dot_u, const KinUpdateType type); #if (defined BT_ID_HAVE_MAT3X) && (defined BT_ID_WITH_JACOBIANS) - /// calculate jacobians and (if type == POSITION_VELOCITY), also velocity-dependent accelration terms. - int calculateJacobians(const vecx& q, const vecx& u, const KinUpdateType type); - /// \copydoc MultiBodyTree::getBodyDotJacobianTransU - int getBodyDotJacobianTransU(const int body_index, vec3* world_dot_jac_trans_u) const ; - /// \copydoc MultiBodyTree::getBodyDotJacobianRotU - int getBodyDotJacobianRotU(const int body_index, vec3* world_dot_jac_rot_u) const; - /// \copydoc MultiBodyTree::getBodyJacobianTrans - int getBodyJacobianTrans(const int body_index, mat3x* world_jac_trans) const ; - /// \copydoc MultiBodyTree::getBodyJacobianRot - int getBodyJacobianRot(const int body_index, mat3x* world_jac_rot) const; - /// Add relative Jacobian component from motion relative to parent body - /// @param body the body to add the Jacobian component for - void addRelativeJacobianComponent(RigidBody&body); + /// calculate jacobians and (if type == POSITION_VELOCITY), also velocity-dependent accelration terms. + int calculateJacobians(const vecx& q, const vecx& u, const KinUpdateType type); + /// \copydoc MultiBodyTree::getBodyDotJacobianTransU + int getBodyDotJacobianTransU(const int body_index, vec3* world_dot_jac_trans_u) const; + /// \copydoc MultiBodyTree::getBodyDotJacobianRotU + int getBodyDotJacobianRotU(const int body_index, vec3* world_dot_jac_rot_u) const; + /// \copydoc MultiBodyTree::getBodyJacobianTrans + int getBodyJacobianTrans(const int body_index, mat3x* world_jac_trans) const; + /// \copydoc MultiBodyTree::getBodyJacobianRot + int getBodyJacobianRot(const int body_index, mat3x* world_jac_rot) const; + /// Add relative Jacobian component from motion relative to parent body + /// @param body the body to add the Jacobian component for + void addRelativeJacobianComponent(RigidBody& body); #endif /// generate additional index sets from the parent_index array /// @return -1 on error, 0 on success @@ -190,12 +193,12 @@ public: int getJointType(const int body_index, JointType* joint_type) const; /// \copydoc MultiBodyTree::getJointTypeStr int getJointTypeStr(const int body_index, const char** joint_type) const; - /// \copydoc MultiBodyTree::getParentRParentBodyRef - int getParentRParentBodyRef(const int body_index, vec3* r) const; - /// \copydoc MultiBodyTree::getBodyTParentRef - int getBodyTParentRef(const int body_index, mat33* T) const; - /// \copydoc MultiBodyTree::getBodyAxisOfMotion - int getBodyAxisOfMotion(const int body_index, vec3* axis) const; + /// \copydoc MultiBodyTree::getParentRParentBodyRef + int getParentRParentBodyRef(const int body_index, vec3* r) const; + /// \copydoc MultiBodyTree::getBodyTParentRef + int getBodyTParentRef(const int body_index, mat33* T) const; + /// \copydoc MultiBodyTree::getBodyAxisOfMotion + int getBodyAxisOfMotion(const int body_index, vec3* axis) const; /// \copydoc MultiBodyTree:getDoFOffset int getDoFOffset(const int body_index, int* q_index) const; /// \copydoc MultiBodyTree::getBodyOrigin @@ -276,8 +279,8 @@ private: // a user-provided pointer idArray::type m_user_ptr; #if (defined BT_ID_HAVE_MAT3X) && (defined BT_ID_WITH_JACOBIANS) - mat3x m_m3x; + mat3x m_m3x; #endif }; -} +} // namespace btInverseDynamics #endif diff --git a/src/BulletInverseDynamics/details/MultiBodyTreeInitCache.cpp b/src/BulletInverseDynamics/details/MultiBodyTreeInitCache.cpp index e9511b707..cf41af5b2 100644 --- a/src/BulletInverseDynamics/details/MultiBodyTreeInitCache.cpp +++ b/src/BulletInverseDynamics/details/MultiBodyTreeInitCache.cpp @@ -1,12 +1,13 @@ #include "MultiBodyTreeInitCache.hpp" -namespace btInverseDynamics { - -MultiBodyTree::InitCache::InitCache() { +namespace btInverseDynamics +{ +MultiBodyTree::InitCache::InitCache() +{ m_inertias.resize(0); m_joints.resize(0); m_num_dofs = 0; - m_root_index=-1; + m_root_index = -1; } int MultiBodyTree::InitCache::addBody(const int body_index, const int parent_index, @@ -15,8 +16,10 @@ int MultiBodyTree::InitCache::addBody(const int body_index, const int parent_ind const mat33& body_T_parent_ref, const vec3& body_axis_of_motion, const idScalar mass, const vec3& body_r_body_com, const mat33& body_I_body, - const int user_int, void* user_ptr) { - switch (joint_type) { + const int user_int, void* user_ptr) +{ + switch (joint_type) + { case REVOLUTE: case PRISMATIC: m_num_dofs += 1; @@ -33,13 +36,15 @@ int MultiBodyTree::InitCache::addBody(const int body_index, const int parent_ind return -1; } - if(-1 == parent_index) { - if(m_root_index>=0) { + if (-1 == parent_index) + { + if (m_root_index >= 0) + { bt_id_error_message("trying to add body %d as root, but already added %d as root body\n", - body_index, m_root_index); + body_index, m_root_index); return -1; } - m_root_index=body_index; + m_root_index = body_index; } JointData joint; @@ -61,8 +66,10 @@ int MultiBodyTree::InitCache::addBody(const int body_index, const int parent_ind m_user_ptr.push_back(user_ptr); return 0; } -int MultiBodyTree::InitCache::getInertiaData(const int index, InertiaData* inertia) const { - if (index < 0 || index > static_cast(m_inertias.size())) { +int MultiBodyTree::InitCache::getInertiaData(const int index, InertiaData* inertia) const +{ + if (index < 0 || index > static_cast(m_inertias.size())) + { bt_id_error_message("index out of range\n"); return -1; } @@ -71,8 +78,10 @@ int MultiBodyTree::InitCache::getInertiaData(const int index, InertiaData* inert return 0; } -int MultiBodyTree::InitCache::getUserInt(const int index, int* user_int) const { - if (index < 0 || index > static_cast(m_user_int.size())) { +int MultiBodyTree::InitCache::getUserInt(const int index, int* user_int) const +{ + if (index < 0 || index > static_cast(m_user_int.size())) + { bt_id_error_message("index out of range\n"); return -1; } @@ -80,8 +89,10 @@ int MultiBodyTree::InitCache::getUserInt(const int index, int* user_int) const { return 0; } -int MultiBodyTree::InitCache::getUserPtr(const int index, void** user_ptr) const { - if (index < 0 || index > static_cast(m_user_ptr.size())) { +int MultiBodyTree::InitCache::getUserPtr(const int index, void** user_ptr) const +{ + if (index < 0 || index > static_cast(m_user_ptr.size())) + { bt_id_error_message("index out of range\n"); return -1; } @@ -89,8 +100,10 @@ int MultiBodyTree::InitCache::getUserPtr(const int index, void** user_ptr) const return 0; } -int MultiBodyTree::InitCache::getJointData(const int index, JointData* joint) const { - if (index < 0 || index > static_cast(m_joints.size())) { +int MultiBodyTree::InitCache::getJointData(const int index, JointData* joint) const +{ + if (index < 0 || index > static_cast(m_joints.size())) + { bt_id_error_message("index out of range\n"); return -1; } @@ -98,16 +111,18 @@ int MultiBodyTree::InitCache::getJointData(const int index, JointData* joint) co return 0; } -int MultiBodyTree::InitCache::buildIndexSets() { +int MultiBodyTree::InitCache::buildIndexSets() +{ // NOTE: This function assumes that proper indices were provided // User2InternalIndex from utils can be used to facilitate this. m_parent_index.resize(numBodies()); - for (idArrayIdx j = 0; j < m_joints.size(); j++) { + for (idArrayIdx j = 0; j < m_joints.size(); j++) + { const JointData& joint = m_joints[j]; m_parent_index[joint.m_child] = joint.m_parent; } return 0; } -} +} // namespace btInverseDynamics diff --git a/src/BulletInverseDynamics/details/MultiBodyTreeInitCache.hpp b/src/BulletInverseDynamics/details/MultiBodyTreeInitCache.hpp index 0d2aa4a07..dbdb3ff60 100644 --- a/src/BulletInverseDynamics/details/MultiBodyTreeInitCache.hpp +++ b/src/BulletInverseDynamics/details/MultiBodyTreeInitCache.hpp @@ -5,9 +5,11 @@ #include "../IDMath.hpp" #include "../MultiBodyTree.hpp" -namespace btInverseDynamics { +namespace btInverseDynamics +{ /// Mass properties of a rigid body -struct InertiaData { +struct InertiaData +{ ID_DECLARE_ALIGNED_ALLOCATOR(); /// mass @@ -21,7 +23,8 @@ struct InertiaData { }; /// Joint properties -struct JointData { +struct JointData +{ ID_DECLARE_ALIGNED_ALLOCATOR(); /// type of joint @@ -48,7 +51,8 @@ struct JointData { /// Data structure to store data passed by the user. /// This is used in MultiBodyTree::finalize to build internal data structures. -class MultiBodyTree::InitCache { +class MultiBodyTree::InitCache +{ public: ID_DECLARE_ALIGNED_ALLOCATOR(); /// constructor @@ -105,5 +109,5 @@ private: // index of root body (or -1 if not set) int m_root_index; }; -} +} // namespace btInverseDynamics #endif // MULTIBODYTREEINITCACHE_HPP_ diff --git a/src/BulletSoftBody/btDefaultSoftBodySolver.cpp b/src/BulletSoftBody/btDefaultSoftBodySolver.cpp index 9c2040307..8b7ff9abc 100644 --- a/src/BulletSoftBody/btDefaultSoftBodySolver.cpp +++ b/src/BulletSoftBody/btDefaultSoftBodySolver.cpp @@ -21,11 +21,10 @@ subject to the following restrictions: #include "BulletCollision/CollisionShapes/btCapsuleShape.h" #include "BulletSoftBody/btSoftBody.h" - btDefaultSoftBodySolver::btDefaultSoftBodySolver() { // Initial we will clearly need to update solver constants - // For now this is global for the cloths linked with this solver - we should probably make this body specific + // For now this is global for the cloths linked with this solver - we should probably make this body specific // for performance in future once we understand more clearly when constants need to be updated m_updateSolverConstants = true; } @@ -37,67 +36,65 @@ btDefaultSoftBodySolver::~btDefaultSoftBodySolver() // In this case the data is already in the soft bodies so there is no need for us to do anything void btDefaultSoftBodySolver::copyBackToSoftBodies(bool bMove) { - } -void btDefaultSoftBodySolver::optimize( btAlignedObjectArray< btSoftBody * > &softBodies , bool forceUpdate) +void btDefaultSoftBodySolver::optimize(btAlignedObjectArray &softBodies, bool forceUpdate) { - m_softBodySet.copyFromArray( softBodies ); + m_softBodySet.copyFromArray(softBodies); } -void btDefaultSoftBodySolver::updateSoftBodies( ) +void btDefaultSoftBodySolver::updateSoftBodies() { - for ( int i=0; i < m_softBodySet.size(); i++) + for (int i = 0; i < m_softBodySet.size(); i++) { - btSoftBody* psb=(btSoftBody*)m_softBodySet[i]; + btSoftBody *psb = (btSoftBody *)m_softBodySet[i]; if (psb->isActive()) { - psb->integrateMotion(); + psb->integrateMotion(); } } -} // updateSoftBodies +} // updateSoftBodies bool btDefaultSoftBodySolver::checkInitialized() { return true; } -void btDefaultSoftBodySolver::solveConstraints( float solverdt ) +void btDefaultSoftBodySolver::solveConstraints(float solverdt) { // Solve constraints for non-solver softbodies - for(int i=0; i < m_softBodySet.size(); ++i) + for (int i = 0; i < m_softBodySet.size(); ++i) { - btSoftBody* psb = static_cast(m_softBodySet[i]); + btSoftBody *psb = static_cast(m_softBodySet[i]); if (psb->isActive()) { psb->solveConstraints(); } - } -} // btDefaultSoftBodySolver::solveConstraints + } +} // btDefaultSoftBodySolver::solveConstraints - -void btDefaultSoftBodySolver::copySoftBodyToVertexBuffer( const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer ) +void btDefaultSoftBodySolver::copySoftBodyToVertexBuffer(const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer) { // Currently only support CPU output buffers // TODO: check for DX11 buffers. Take all offsets into the same DX11 buffer // and use them together on a single kernel call if possible by setting up a // per-cloth target buffer array for the copy kernel. - if( vertexBuffer->getBufferType() == btVertexBufferDescriptor::CPU_BUFFER ) + if (vertexBuffer->getBufferType() == btVertexBufferDescriptor::CPU_BUFFER) { - const btAlignedObjectArray &clothVertices( softBody->m_nodes ); + const btAlignedObjectArray &clothVertices(softBody->m_nodes); int numVertices = clothVertices.size(); - const btCPUVertexBufferDescriptor *cpuVertexBuffer = static_cast< btCPUVertexBufferDescriptor* >(vertexBuffer); - float *basePointer = cpuVertexBuffer->getBasePointer(); + const btCPUVertexBufferDescriptor *cpuVertexBuffer = static_cast(vertexBuffer); + float *basePointer = cpuVertexBuffer->getBasePointer(); - if( vertexBuffer->hasVertexPositions() ) + if (vertexBuffer->hasVertexPositions()) { const int vertexOffset = cpuVertexBuffer->getVertexOffset(); const int vertexStride = cpuVertexBuffer->getVertexStride(); float *vertexPointer = basePointer + vertexOffset; - for( int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex ) + for (int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex) { btVector3 position = clothVertices[vertexIndex].m_x; *(vertexPointer + 0) = (float)position.getX(); @@ -106,13 +103,13 @@ void btDefaultSoftBodySolver::copySoftBodyToVertexBuffer( const btSoftBody *cons vertexPointer += vertexStride; } } - if( vertexBuffer->hasNormals() ) + if (vertexBuffer->hasNormals()) { const int normalOffset = cpuVertexBuffer->getNormalOffset(); const int normalStride = cpuVertexBuffer->getNormalStride(); float *normalPointer = basePointer + normalOffset; - for( int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex ) + for (int vertexIndex = 0; vertexIndex < numVertices; ++vertexIndex) { btVector3 normal = clothVertices[vertexIndex].m_n; *(normalPointer + 0) = (float)normal.getX(); @@ -122,30 +119,28 @@ void btDefaultSoftBodySolver::copySoftBodyToVertexBuffer( const btSoftBody *cons } } } -} // btDefaultSoftBodySolver::copySoftBodyToVertexBuffer +} // btDefaultSoftBodySolver::copySoftBodyToVertexBuffer -void btDefaultSoftBodySolver::processCollision( btSoftBody* softBody, btSoftBody* otherSoftBody) +void btDefaultSoftBodySolver::processCollision(btSoftBody *softBody, btSoftBody *otherSoftBody) { - softBody->defaultCollisionHandler( otherSoftBody); + softBody->defaultCollisionHandler(otherSoftBody); } // For the default solver just leave the soft body to do its collision processing -void btDefaultSoftBodySolver::processCollision( btSoftBody *softBody, const btCollisionObjectWrapper* collisionObjectWrap ) +void btDefaultSoftBodySolver::processCollision(btSoftBody *softBody, const btCollisionObjectWrapper *collisionObjectWrap) { - softBody->defaultCollisionHandler( collisionObjectWrap ); -} // btDefaultSoftBodySolver::processCollision + softBody->defaultCollisionHandler(collisionObjectWrap); +} // btDefaultSoftBodySolver::processCollision - -void btDefaultSoftBodySolver::predictMotion( float timeStep ) +void btDefaultSoftBodySolver::predictMotion(float timeStep) { - for ( int i=0; i < m_softBodySet.size(); ++i) + for (int i = 0; i < m_softBodySet.size(); ++i) { - btSoftBody* psb = m_softBodySet[i]; + btSoftBody *psb = m_softBodySet[i]; if (psb->isActive()) { - psb->predictMotion(timeStep); + psb->predictMotion(timeStep); } } } - diff --git a/src/BulletSoftBody/btDefaultSoftBodySolver.h b/src/BulletSoftBody/btDefaultSoftBodySolver.h index 1c17ffcbb..50bd73516 100644 --- a/src/BulletSoftBody/btDefaultSoftBodySolver.h +++ b/src/BulletSoftBody/btDefaultSoftBodySolver.h @@ -16,25 +16,23 @@ subject to the following restrictions: #ifndef BT_SOFT_BODY_DEFAULT_SOLVER_H #define BT_SOFT_BODY_DEFAULT_SOLVER_H - #include "BulletSoftBody/btSoftBodySolvers.h" #include "btSoftBodySolverVertexBuffer.h" struct btCollisionObjectWrapper; class btDefaultSoftBodySolver : public btSoftBodySolver { -protected: +protected: /** Variable to define whether we need to update solver constants on the next iteration */ bool m_updateSolverConstants; - btAlignedObjectArray< btSoftBody * > m_softBodySet; - + btAlignedObjectArray m_softBodySet; public: btDefaultSoftBodySolver(); - + virtual ~btDefaultSoftBodySolver(); - + virtual SolverTypes getSolverType() const { return DEFAULT_SOLVER; @@ -42,22 +40,21 @@ public: virtual bool checkInitialized(); - virtual void updateSoftBodies( ); + virtual void updateSoftBodies(); - virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies,bool forceUpdate=false ); + virtual void optimize(btAlignedObjectArray &softBodies, bool forceUpdate = false); virtual void copyBackToSoftBodies(bool bMove = true); - virtual void solveConstraints( float solverdt ); + virtual void solveConstraints(float solverdt); - virtual void predictMotion( float solverdt ); + virtual void predictMotion(float solverdt); - virtual void copySoftBodyToVertexBuffer( const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer ); + virtual void copySoftBodyToVertexBuffer(const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer); - virtual void processCollision( btSoftBody *, const btCollisionObjectWrapper* ); - - virtual void processCollision( btSoftBody*, btSoftBody* ); + virtual void processCollision(btSoftBody *, const btCollisionObjectWrapper *); + virtual void processCollision(btSoftBody *, btSoftBody *); }; -#endif // #ifndef BT_ACCELERATED_SOFT_BODY_CPU_SOLVER_H +#endif // #ifndef BT_ACCELERATED_SOFT_BODY_CPU_SOLVER_H diff --git a/src/BulletSoftBody/btSoftBody.cpp b/src/BulletSoftBody/btSoftBody.cpp index 48efb0d8d..58796a88d 100644 --- a/src/BulletSoftBody/btSoftBody.cpp +++ b/src/BulletSoftBody/btSoftBody.cpp @@ -21,97 +21,94 @@ subject to the following restrictions: #include "BulletDynamics/Featherstone/btMultiBodyLinkCollider.h" #include "BulletDynamics/Featherstone/btMultiBodyConstraint.h" - // -btSoftBody::btSoftBody(btSoftBodyWorldInfo* worldInfo,int node_count, const btVector3* x, const btScalar* m) -:m_softBodySolver(0),m_worldInfo(worldInfo) -{ - /* Init */ +btSoftBody::btSoftBody(btSoftBodyWorldInfo* worldInfo, int node_count, const btVector3* x, const btScalar* m) + : m_softBodySolver(0), m_worldInfo(worldInfo) +{ + /* Init */ initDefaults(); - /* Default material */ - Material* pm=appendMaterial(); - pm->m_kLST = 1; - pm->m_kAST = 1; - pm->m_kVST = 1; - pm->m_flags = fMaterial::Default; + /* Default material */ + Material* pm = appendMaterial(); + pm->m_kLST = 1; + pm->m_kAST = 1; + pm->m_kVST = 1; + pm->m_flags = fMaterial::Default; - /* Nodes */ - const btScalar margin=getCollisionShape()->getMargin(); + /* Nodes */ + const btScalar margin = getCollisionShape()->getMargin(); m_nodes.resize(node_count); - for(int i=0,ni=node_count;i0?1/n.m_im:0; - n.m_leaf = m_ndbvt.insert(btDbvtVolume::FromCR(n.m_x,margin),&n); - n.m_material= pm; + n.m_x = x ? *x++ : btVector3(0, 0, 0); + n.m_q = n.m_x; + n.m_im = m ? *m++ : 1; + n.m_im = n.m_im > 0 ? 1 / n.m_im : 0; + n.m_leaf = m_ndbvt.insert(btDbvtVolume::FromCR(n.m_x, margin), &n); + n.m_material = pm; } - updateBounds(); - + updateBounds(); } -btSoftBody::btSoftBody(btSoftBodyWorldInfo* worldInfo) -:m_worldInfo(worldInfo) +btSoftBody::btSoftBody(btSoftBodyWorldInfo* worldInfo) + : m_worldInfo(worldInfo) { initDefaults(); } - -void btSoftBody::initDefaults() +void btSoftBody::initDefaults() { - m_internalType = CO_SOFT_BODY; - m_cfg.aeromodel = eAeroModel::V_Point; - m_cfg.kVCF = 1; - m_cfg.kDG = 0; - m_cfg.kLF = 0; - m_cfg.kDP = 0; - m_cfg.kPR = 0; - m_cfg.kVC = 0; - m_cfg.kDF = (btScalar)0.2; - m_cfg.kMT = 0; - m_cfg.kCHR = (btScalar)1.0; - m_cfg.kKHR = (btScalar)0.1; - m_cfg.kSHR = (btScalar)1.0; - m_cfg.kAHR = (btScalar)0.7; - m_cfg.kSRHR_CL = (btScalar)0.1; - m_cfg.kSKHR_CL = (btScalar)1; - m_cfg.kSSHR_CL = (btScalar)0.5; - m_cfg.kSR_SPLT_CL = (btScalar)0.5; - m_cfg.kSK_SPLT_CL = (btScalar)0.5; - m_cfg.kSS_SPLT_CL = (btScalar)0.5; - m_cfg.maxvolume = (btScalar)1; - m_cfg.timescale = 1; - m_cfg.viterations = 0; - m_cfg.piterations = 1; - m_cfg.diterations = 0; - m_cfg.citerations = 4; - m_cfg.collisions = fCollision::Default; - m_pose.m_bvolume = false; - m_pose.m_bframe = false; - m_pose.m_volume = 0; - m_pose.m_com = btVector3(0,0,0); + m_internalType = CO_SOFT_BODY; + m_cfg.aeromodel = eAeroModel::V_Point; + m_cfg.kVCF = 1; + m_cfg.kDG = 0; + m_cfg.kLF = 0; + m_cfg.kDP = 0; + m_cfg.kPR = 0; + m_cfg.kVC = 0; + m_cfg.kDF = (btScalar)0.2; + m_cfg.kMT = 0; + m_cfg.kCHR = (btScalar)1.0; + m_cfg.kKHR = (btScalar)0.1; + m_cfg.kSHR = (btScalar)1.0; + m_cfg.kAHR = (btScalar)0.7; + m_cfg.kSRHR_CL = (btScalar)0.1; + m_cfg.kSKHR_CL = (btScalar)1; + m_cfg.kSSHR_CL = (btScalar)0.5; + m_cfg.kSR_SPLT_CL = (btScalar)0.5; + m_cfg.kSK_SPLT_CL = (btScalar)0.5; + m_cfg.kSS_SPLT_CL = (btScalar)0.5; + m_cfg.maxvolume = (btScalar)1; + m_cfg.timescale = 1; + m_cfg.viterations = 0; + m_cfg.piterations = 1; + m_cfg.diterations = 0; + m_cfg.citerations = 4; + m_cfg.collisions = fCollision::Default; + m_pose.m_bvolume = false; + m_pose.m_bframe = false; + m_pose.m_volume = 0; + m_pose.m_com = btVector3(0, 0, 0); m_pose.m_rot.setIdentity(); m_pose.m_scl.setIdentity(); - m_tag = 0; - m_timeacc = 0; - m_bUpdateRtCst = true; - m_bounds[0] = btVector3(0,0,0); - m_bounds[1] = btVector3(0,0,0); + m_tag = 0; + m_timeacc = 0; + m_bUpdateRtCst = true; + m_bounds[0] = btVector3(0, 0, 0); + m_bounds[1] = btVector3(0, 0, 0); m_worldTransform.setIdentity(); setSolver(eSolverPresets::Positions); - - /* Collision shape */ + + /* Collision shape */ ///for now, create a collision shape internally m_collisionShape = new btSoftBodyCollisionShape(this); m_collisionShape->setMargin(0.25f); - + m_initialWorldTransform.setIdentity(); - m_windVelocity = btVector3(0,0,0); + m_windVelocity = btVector3(0, 0, 0); m_restLengthScale = btScalar(1.0); } @@ -119,343 +116,361 @@ void btSoftBody::initDefaults() btSoftBody::~btSoftBody() { //for now, delete the internal shape - delete m_collisionShape; + delete m_collisionShape; int i; releaseClusters(); - for(i=0;i0) - *pm=*m_materials[0]; + Material* pm = new (btAlignedAlloc(sizeof(Material), 16)) Material(); + if (m_materials.size() > 0) + *pm = *m_materials[0]; else ZeroInitialize(*pm); m_materials.push_back(pm); - return(pm); + return (pm); } // -void btSoftBody::appendNote( const char* text, - const btVector3& o, - const btVector4& c, - Node* n0, - Node* n1, - Node* n2, - Node* n3) +void btSoftBody::appendNote(const char* text, + const btVector3& o, + const btVector4& c, + Node* n0, + Node* n1, + Node* n2, + Node* n3) { - Note n; + Note n; ZeroInitialize(n); - n.m_rank = 0; - n.m_text = text; - n.m_offset = o; - n.m_coords[0] = c.x(); - n.m_coords[1] = c.y(); - n.m_coords[2] = c.z(); - n.m_coords[3] = c.w(); - n.m_nodes[0] = n0;n.m_rank+=n0?1:0; - n.m_nodes[1] = n1;n.m_rank+=n1?1:0; - n.m_nodes[2] = n2;n.m_rank+=n2?1:0; - n.m_nodes[3] = n3;n.m_rank+=n3?1:0; + n.m_rank = 0; + n.m_text = text; + n.m_offset = o; + n.m_coords[0] = c.x(); + n.m_coords[1] = c.y(); + n.m_coords[2] = c.z(); + n.m_coords[3] = c.w(); + n.m_nodes[0] = n0; + n.m_rank += n0 ? 1 : 0; + n.m_nodes[1] = n1; + n.m_rank += n1 ? 1 : 0; + n.m_nodes[2] = n2; + n.m_rank += n2 ? 1 : 0; + n.m_nodes[3] = n3; + n.m_rank += n3 ? 1 : 0; m_notes.push_back(n); } // -void btSoftBody::appendNote( const char* text, - const btVector3& o, - Node* feature) +void btSoftBody::appendNote(const char* text, + const btVector3& o, + Node* feature) { - appendNote(text,o,btVector4(1,0,0,0),feature); + appendNote(text, o, btVector4(1, 0, 0, 0), feature); } // -void btSoftBody::appendNote( const char* text, - const btVector3& o, - Link* feature) +void btSoftBody::appendNote(const char* text, + const btVector3& o, + Link* feature) { - static const btScalar w=1/(btScalar)2; - appendNote(text,o,btVector4(w,w,0,0), feature->m_n[0], - feature->m_n[1]); + static const btScalar w = 1 / (btScalar)2; + appendNote(text, o, btVector4(w, w, 0, 0), feature->m_n[0], + feature->m_n[1]); } // -void btSoftBody::appendNote( const char* text, - const btVector3& o, - Face* feature) +void btSoftBody::appendNote(const char* text, + const btVector3& o, + Face* feature) { - static const btScalar w=1/(btScalar)3; - appendNote(text,o,btVector4(w,w,w,0), feature->m_n[0], - feature->m_n[1], - feature->m_n[2]); + static const btScalar w = 1 / (btScalar)3; + appendNote(text, o, btVector4(w, w, w, 0), feature->m_n[0], + feature->m_n[1], + feature->m_n[2]); } // -void btSoftBody::appendNode( const btVector3& x,btScalar m) +void btSoftBody::appendNode(const btVector3& x, btScalar m) { - if(m_nodes.capacity()==m_nodes.size()) + if (m_nodes.capacity() == m_nodes.size()) { pointersToIndices(); - m_nodes.reserve(m_nodes.size()*2+1); + m_nodes.reserve(m_nodes.size() * 2 + 1); indicesToPointers(); } - const btScalar margin=getCollisionShape()->getMargin(); + const btScalar margin = getCollisionShape()->getMargin(); m_nodes.push_back(Node()); - Node& n=m_nodes[m_nodes.size()-1]; + Node& n = m_nodes[m_nodes.size() - 1]; ZeroInitialize(n); - n.m_x = x; - n.m_q = n.m_x; - n.m_im = m>0?1/m:0; - n.m_material = m_materials[0]; - n.m_leaf = m_ndbvt.insert(btDbvtVolume::FromCR(n.m_x,margin),&n); + n.m_x = x; + n.m_q = n.m_x; + n.m_im = m > 0 ? 1 / m : 0; + n.m_material = m_materials[0]; + n.m_leaf = m_ndbvt.insert(btDbvtVolume::FromCR(n.m_x, margin), &n); } // -void btSoftBody::appendLink(int model,Material* mat) +void btSoftBody::appendLink(int model, Material* mat) { - Link l; - if(model>=0) - l=m_links[model]; + Link l; + if (model >= 0) + l = m_links[model]; else - { ZeroInitialize(l);l.m_material=mat?mat:m_materials[0]; } + { + ZeroInitialize(l); + l.m_material = mat ? mat : m_materials[0]; + } m_links.push_back(l); } // -void btSoftBody::appendLink( int node0, - int node1, - Material* mat, - bool bcheckexist) +void btSoftBody::appendLink(int node0, + int node1, + Material* mat, + bool bcheckexist) { - appendLink(&m_nodes[node0],&m_nodes[node1],mat,bcheckexist); + appendLink(&m_nodes[node0], &m_nodes[node1], mat, bcheckexist); } // -void btSoftBody::appendLink( Node* node0, - Node* node1, - Material* mat, - bool bcheckexist) +void btSoftBody::appendLink(Node* node0, + Node* node1, + Material* mat, + bool bcheckexist) { - if((!bcheckexist)||(!checkLink(node0,node1))) + if ((!bcheckexist) || (!checkLink(node0, node1))) { - appendLink(-1,mat); - Link& l=m_links[m_links.size()-1]; - l.m_n[0] = node0; - l.m_n[1] = node1; - l.m_rl = (l.m_n[0]->m_x-l.m_n[1]->m_x).length(); - m_bUpdateRtCst=true; + appendLink(-1, mat); + Link& l = m_links[m_links.size() - 1]; + l.m_n[0] = node0; + l.m_n[1] = node1; + l.m_rl = (l.m_n[0]->m_x - l.m_n[1]->m_x).length(); + m_bUpdateRtCst = true; } } // -void btSoftBody::appendFace(int model,Material* mat) +void btSoftBody::appendFace(int model, Material* mat) { - Face f; - if(model>=0) - { f=m_faces[model]; } + Face f; + if (model >= 0) + { + f = m_faces[model]; + } else - { ZeroInitialize(f);f.m_material=mat?mat:m_materials[0]; } + { + ZeroInitialize(f); + f.m_material = mat ? mat : m_materials[0]; + } m_faces.push_back(f); } // -void btSoftBody::appendFace(int node0,int node1,int node2,Material* mat) +void btSoftBody::appendFace(int node0, int node1, int node2, Material* mat) { - if (node0==node1) + if (node0 == node1) return; - if (node1==node2) + if (node1 == node2) return; - if (node2==node0) + if (node2 == node0) return; - appendFace(-1,mat); - Face& f=m_faces[m_faces.size()-1]; - btAssert(node0!=node1); - btAssert(node1!=node2); - btAssert(node2!=node0); - f.m_n[0] = &m_nodes[node0]; - f.m_n[1] = &m_nodes[node1]; - f.m_n[2] = &m_nodes[node2]; - f.m_ra = AreaOf( f.m_n[0]->m_x, - f.m_n[1]->m_x, - f.m_n[2]->m_x); - m_bUpdateRtCst=true; + appendFace(-1, mat); + Face& f = m_faces[m_faces.size() - 1]; + btAssert(node0 != node1); + btAssert(node1 != node2); + btAssert(node2 != node0); + f.m_n[0] = &m_nodes[node0]; + f.m_n[1] = &m_nodes[node1]; + f.m_n[2] = &m_nodes[node2]; + f.m_ra = AreaOf(f.m_n[0]->m_x, + f.m_n[1]->m_x, + f.m_n[2]->m_x); + m_bUpdateRtCst = true; } // -void btSoftBody::appendTetra(int model,Material* mat) +void btSoftBody::appendTetra(int model, Material* mat) { -Tetra t; -if(model>=0) - t=m_tetras[model]; + Tetra t; + if (model >= 0) + t = m_tetras[model]; else - { ZeroInitialize(t);t.m_material=mat?mat:m_materials[0]; } -m_tetras.push_back(t); + { + ZeroInitialize(t); + t.m_material = mat ? mat : m_materials[0]; + } + m_tetras.push_back(t); } // -void btSoftBody::appendTetra(int node0, - int node1, - int node2, - int node3, - Material* mat) +void btSoftBody::appendTetra(int node0, + int node1, + int node2, + int node3, + Material* mat) { - appendTetra(-1,mat); - Tetra& t=m_tetras[m_tetras.size()-1]; - t.m_n[0] = &m_nodes[node0]; - t.m_n[1] = &m_nodes[node1]; - t.m_n[2] = &m_nodes[node2]; - t.m_n[3] = &m_nodes[node3]; - t.m_rv = VolumeOf(t.m_n[0]->m_x,t.m_n[1]->m_x,t.m_n[2]->m_x,t.m_n[3]->m_x); - m_bUpdateRtCst=true; + appendTetra(-1, mat); + Tetra& t = m_tetras[m_tetras.size() - 1]; + t.m_n[0] = &m_nodes[node0]; + t.m_n[1] = &m_nodes[node1]; + t.m_n[2] = &m_nodes[node2]; + t.m_n[3] = &m_nodes[node3]; + t.m_rv = VolumeOf(t.m_n[0]->m_x, t.m_n[1]->m_x, t.m_n[2]->m_x, t.m_n[3]->m_x); + m_bUpdateRtCst = true; } // -void btSoftBody::appendAnchor(int node,btRigidBody* body, bool disableCollisionBetweenLinkedBodies,btScalar influence) +void btSoftBody::appendAnchor(int node, btRigidBody* body, bool disableCollisionBetweenLinkedBodies, btScalar influence) { - btVector3 local = body->getWorldTransform().inverse()*m_nodes[node].m_x; - appendAnchor(node,body,local,disableCollisionBetweenLinkedBodies,influence); + btVector3 local = body->getWorldTransform().inverse() * m_nodes[node].m_x; + appendAnchor(node, body, local, disableCollisionBetweenLinkedBodies, influence); } // -void btSoftBody::appendAnchor(int node,btRigidBody* body, const btVector3& localPivot,bool disableCollisionBetweenLinkedBodies,btScalar influence) +void btSoftBody::appendAnchor(int node, btRigidBody* body, const btVector3& localPivot, bool disableCollisionBetweenLinkedBodies, btScalar influence) { if (disableCollisionBetweenLinkedBodies) { - if (m_collisionDisabledObjects.findLinearSearch(body)==m_collisionDisabledObjects.size()) + if (m_collisionDisabledObjects.findLinearSearch(body) == m_collisionDisabledObjects.size()) { m_collisionDisabledObjects.push_back(body); } } - Anchor a; - a.m_node = &m_nodes[node]; - a.m_body = body; - a.m_local = localPivot; - a.m_node->m_battach = 1; + Anchor a; + a.m_node = &m_nodes[node]; + a.m_body = body; + a.m_local = localPivot; + a.m_node->m_battach = 1; a.m_influence = influence; m_anchors.push_back(a); } // -void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1) +void btSoftBody::appendLinearJoint(const LJoint::Specs& specs, Cluster* body0, Body body1) { - LJoint* pj = new(btAlignedAlloc(sizeof(LJoint),16)) LJoint(); - pj->m_bodies[0] = body0; - pj->m_bodies[1] = body1; - pj->m_refs[0] = pj->m_bodies[0].xform().inverse()*specs.position; - pj->m_refs[1] = pj->m_bodies[1].xform().inverse()*specs.position; - pj->m_cfm = specs.cfm; - pj->m_erp = specs.erp; - pj->m_split = specs.split; + LJoint* pj = new (btAlignedAlloc(sizeof(LJoint), 16)) LJoint(); + pj->m_bodies[0] = body0; + pj->m_bodies[1] = body1; + pj->m_refs[0] = pj->m_bodies[0].xform().inverse() * specs.position; + pj->m_refs[1] = pj->m_bodies[1].xform().inverse() * specs.position; + pj->m_cfm = specs.cfm; + pj->m_erp = specs.erp; + pj->m_split = specs.split; m_joints.push_back(pj); } // -void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,Body body) +void btSoftBody::appendLinearJoint(const LJoint::Specs& specs, Body body) { - appendLinearJoint(specs,m_clusters[0],body); + appendLinearJoint(specs, m_clusters[0], body); } // -void btSoftBody::appendLinearJoint(const LJoint::Specs& specs,btSoftBody* body) +void btSoftBody::appendLinearJoint(const LJoint::Specs& specs, btSoftBody* body) { - appendLinearJoint(specs,m_clusters[0],body->m_clusters[0]); + appendLinearJoint(specs, m_clusters[0], body->m_clusters[0]); } // -void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,Cluster* body0,Body body1) +void btSoftBody::appendAngularJoint(const AJoint::Specs& specs, Cluster* body0, Body body1) { - AJoint* pj = new(btAlignedAlloc(sizeof(AJoint),16)) AJoint(); - pj->m_bodies[0] = body0; - pj->m_bodies[1] = body1; - pj->m_refs[0] = pj->m_bodies[0].xform().inverse().getBasis()*specs.axis; - pj->m_refs[1] = pj->m_bodies[1].xform().inverse().getBasis()*specs.axis; - pj->m_cfm = specs.cfm; - pj->m_erp = specs.erp; - pj->m_split = specs.split; - pj->m_icontrol = specs.icontrol; + AJoint* pj = new (btAlignedAlloc(sizeof(AJoint), 16)) AJoint(); + pj->m_bodies[0] = body0; + pj->m_bodies[1] = body1; + pj->m_refs[0] = pj->m_bodies[0].xform().inverse().getBasis() * specs.axis; + pj->m_refs[1] = pj->m_bodies[1].xform().inverse().getBasis() * specs.axis; + pj->m_cfm = specs.cfm; + pj->m_erp = specs.erp; + pj->m_split = specs.split; + pj->m_icontrol = specs.icontrol; m_joints.push_back(pj); } // -void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,Body body) +void btSoftBody::appendAngularJoint(const AJoint::Specs& specs, Body body) { - appendAngularJoint(specs,m_clusters[0],body); + appendAngularJoint(specs, m_clusters[0], body); } // -void btSoftBody::appendAngularJoint(const AJoint::Specs& specs,btSoftBody* body) +void btSoftBody::appendAngularJoint(const AJoint::Specs& specs, btSoftBody* body) { - appendAngularJoint(specs,m_clusters[0],body->m_clusters[0]); + appendAngularJoint(specs, m_clusters[0], body->m_clusters[0]); } // -void btSoftBody::addForce(const btVector3& force) +void btSoftBody::addForce(const btVector3& force) { - for(int i=0,ni=m_nodes.size();i0) + Node& n = m_nodes[node]; + if (n.m_im > 0) { - n.m_f += force; + n.m_f += force; } } -void btSoftBody::addAeroForceToNode(const btVector3& windVelocity,int nodeIndex) +void btSoftBody::addAeroForceToNode(const btVector3& windVelocity, int nodeIndex) { btAssert(nodeIndex >= 0 && nodeIndex < m_nodes.size()); @@ -464,51 +479,51 @@ void btSoftBody::addAeroForceToNode(const btVector3& windVelocity,int nodeInde const btScalar kDG = m_cfg.kDG; //const btScalar kPR = m_cfg.kPR; //const btScalar kVC = m_cfg.kVC; - const bool as_lift = kLF>0; - const bool as_drag = kDG>0; + const bool as_lift = kLF > 0; + const bool as_drag = kDG > 0; const bool as_aero = as_lift || as_drag; const bool as_vaero = as_aero && (m_cfg.aeromodel < btSoftBody::eAeroModel::F_TwoSided); Node& n = m_nodes[nodeIndex]; - if( n.m_im>0 ) + if (n.m_im > 0) { - btSoftBody::sMedium medium; + btSoftBody::sMedium medium; EvaluateMedium(m_worldInfo, n.m_x, medium); medium.m_velocity = windVelocity; medium.m_density = m_worldInfo->air_density; - /* Aerodynamics */ - if(as_vaero) - { - const btVector3 rel_v = n.m_v - medium.m_velocity; + /* Aerodynamics */ + if (as_vaero) + { + const btVector3 rel_v = n.m_v - medium.m_velocity; const btScalar rel_v_len = rel_v.length(); - const btScalar rel_v2 = rel_v.length2(); + const btScalar rel_v2 = rel_v.length2(); - if(rel_v2>SIMD_EPSILON) + if (rel_v2 > SIMD_EPSILON) { const btVector3 rel_v_nrm = rel_v.normalized(); - btVector3 nrm = n.m_n; + btVector3 nrm = n.m_n; if (m_cfg.aeromodel == btSoftBody::eAeroModel::V_TwoSidedLiftDrag) { - nrm *= (btScalar)( (btDot(nrm,rel_v) < 0) ? -1 : +1); + nrm *= (btScalar)((btDot(nrm, rel_v) < 0) ? -1 : +1); btVector3 fDrag(0, 0, 0); btVector3 fLift(0, 0, 0); btScalar n_dot_v = nrm.dot(rel_v_nrm); btScalar tri_area = 0.5f * n.m_area; - + fDrag = 0.5f * kDG * medium.m_density * rel_v2 * tri_area * n_dot_v * (-rel_v_nrm); - + // Check angle of attack // cos(10º) = 0.98480 - if ( 0 < n_dot_v && n_dot_v < 0.98480f) - fLift = 0.5f * kLF * medium.m_density * rel_v_len * tri_area * btSqrt(1.0f-n_dot_v*n_dot_v) * (nrm.cross(rel_v_nrm).cross(rel_v_nrm)); + if (0 < n_dot_v && n_dot_v < 0.98480f) + fLift = 0.5f * kLF * medium.m_density * rel_v_len * tri_area * btSqrt(1.0f - n_dot_v * n_dot_v) * (nrm.cross(rel_v_nrm).cross(rel_v_nrm)); // Check if the velocity change resulted by aero drag force exceeds the current velocity of the node. - btVector3 del_v_by_fDrag = fDrag*n.m_im*m_sst.sdt; + btVector3 del_v_by_fDrag = fDrag * n.m_im * m_sst.sdt; btScalar del_v_by_fDrag_len2 = del_v_by_fDrag.length2(); btScalar v_len2 = n.m_v.length2(); @@ -516,7 +531,7 @@ void btSoftBody::addAeroForceToNode(const btVector3& windVelocity,int nodeInde { btScalar del_v_by_fDrag_len = del_v_by_fDrag.length(); btScalar v_len = n.m_v.length(); - fDrag *= btScalar(0.8)*(v_len / del_v_by_fDrag_len); + fDrag *= btScalar(0.8) * (v_len / del_v_by_fDrag_len); } n.m_f += fDrag; @@ -525,83 +540,83 @@ void btSoftBody::addAeroForceToNode(const btVector3& windVelocity,int nodeInde else if (m_cfg.aeromodel == btSoftBody::eAeroModel::V_Point || m_cfg.aeromodel == btSoftBody::eAeroModel::V_OneSided || m_cfg.aeromodel == btSoftBody::eAeroModel::V_TwoSided) { if (m_cfg.aeromodel == btSoftBody::eAeroModel::V_TwoSided) - nrm *= (btScalar)( (btDot(nrm,rel_v) < 0) ? -1 : +1); + nrm *= (btScalar)((btDot(nrm, rel_v) < 0) ? -1 : +1); - const btScalar dvn = btDot(rel_v,nrm); - /* Compute forces */ - if(dvn>0) + const btScalar dvn = btDot(rel_v, nrm); + /* Compute forces */ + if (dvn > 0) { - btVector3 force(0,0,0); - const btScalar c0 = n.m_area * dvn * rel_v2/2; - const btScalar c1 = c0 * medium.m_density; - force += nrm*(-c1*kLF); - force += rel_v.normalized() * (-c1 * kDG); + btVector3 force(0, 0, 0); + const btScalar c0 = n.m_area * dvn * rel_v2 / 2; + const btScalar c1 = c0 * medium.m_density; + force += nrm * (-c1 * kLF); + force += rel_v.normalized() * (-c1 * kDG); ApplyClampedForce(n, force, dt); } - } + } } } } } -void btSoftBody::addAeroForceToFace(const btVector3& windVelocity,int faceIndex) +void btSoftBody::addAeroForceToFace(const btVector3& windVelocity, int faceIndex) { const btScalar dt = m_sst.sdt; const btScalar kLF = m_cfg.kLF; const btScalar kDG = m_cfg.kDG; -// const btScalar kPR = m_cfg.kPR; -// const btScalar kVC = m_cfg.kVC; - const bool as_lift = kLF>0; - const bool as_drag = kDG>0; + // const btScalar kPR = m_cfg.kPR; + // const btScalar kVC = m_cfg.kVC; + const bool as_lift = kLF > 0; + const bool as_drag = kDG > 0; const bool as_aero = as_lift || as_drag; const bool as_faero = as_aero && (m_cfg.aeromodel >= btSoftBody::eAeroModel::F_TwoSided); - if(as_faero) + if (as_faero) { - btSoftBody::Face& f=m_faces[faceIndex]; + btSoftBody::Face& f = m_faces[faceIndex]; - btSoftBody::sMedium medium; - - const btVector3 v=(f.m_n[0]->m_v+f.m_n[1]->m_v+f.m_n[2]->m_v)/3; - const btVector3 x=(f.m_n[0]->m_x+f.m_n[1]->m_x+f.m_n[2]->m_x)/3; - EvaluateMedium(m_worldInfo,x,medium); + btSoftBody::sMedium medium; + + const btVector3 v = (f.m_n[0]->m_v + f.m_n[1]->m_v + f.m_n[2]->m_v) / 3; + const btVector3 x = (f.m_n[0]->m_x + f.m_n[1]->m_x + f.m_n[2]->m_x) / 3; + EvaluateMedium(m_worldInfo, x, medium); medium.m_velocity = windVelocity; medium.m_density = m_worldInfo->air_density; - const btVector3 rel_v=v-medium.m_velocity; + const btVector3 rel_v = v - medium.m_velocity; const btScalar rel_v_len = rel_v.length(); - const btScalar rel_v2=rel_v.length2(); + const btScalar rel_v2 = rel_v.length2(); - if(rel_v2>SIMD_EPSILON) + if (rel_v2 > SIMD_EPSILON) { const btVector3 rel_v_nrm = rel_v.normalized(); - btVector3 nrm = f.m_normal; + btVector3 nrm = f.m_normal; if (m_cfg.aeromodel == btSoftBody::eAeroModel::F_TwoSidedLiftDrag) { - nrm *= (btScalar)( (btDot(nrm,rel_v) < 0) ? -1 : +1); + nrm *= (btScalar)((btDot(nrm, rel_v) < 0) ? -1 : +1); btVector3 fDrag(0, 0, 0); btVector3 fLift(0, 0, 0); btScalar n_dot_v = nrm.dot(rel_v_nrm); btScalar tri_area = 0.5f * f.m_ra; - + fDrag = 0.5f * kDG * medium.m_density * rel_v2 * tri_area * n_dot_v * (-rel_v_nrm); // Check angle of attack // cos(10º) = 0.98480 - if ( 0 < n_dot_v && n_dot_v < 0.98480f) - fLift = 0.5f * kLF * medium.m_density * rel_v_len * tri_area * btSqrt(1.0f-n_dot_v*n_dot_v) * (nrm.cross(rel_v_nrm).cross(rel_v_nrm)); + if (0 < n_dot_v && n_dot_v < 0.98480f) + fLift = 0.5f * kLF * medium.m_density * rel_v_len * tri_area * btSqrt(1.0f - n_dot_v * n_dot_v) * (nrm.cross(rel_v_nrm).cross(rel_v_nrm)); fDrag /= 3; fLift /= 3; - for(int j=0;j<3;++j) + for (int j = 0; j < 3; ++j) { - if (f.m_n[j]->m_im>0) + if (f.m_n[j]->m_im > 0) { // Check if the velocity change resulted by aero drag force exceeds the current velocity of the node. - btVector3 del_v_by_fDrag = fDrag*f.m_n[j]->m_im*m_sst.sdt; + btVector3 del_v_by_fDrag = fDrag * f.m_n[j]->m_im * m_sst.sdt; btScalar del_v_by_fDrag_len2 = del_v_by_fDrag.length2(); btScalar v_len2 = f.m_n[j]->m_v.length2(); @@ -609,10 +624,10 @@ void btSoftBody::addAeroForceToFace(const btVector3& windVelocity,int faceInde { btScalar del_v_by_fDrag_len = del_v_by_fDrag.length(); btScalar v_len = f.m_n[j]->m_v.length(); - fDrag *= btScalar(0.8)*(v_len / del_v_by_fDrag_len); + fDrag *= btScalar(0.8) * (v_len / del_v_by_fDrag_len); } - f.m_n[j]->m_f += fDrag; + f.m_n[j]->m_f += fDrag; f.m_n[j]->m_f += fLift; } } @@ -620,183 +635,181 @@ void btSoftBody::addAeroForceToFace(const btVector3& windVelocity,int faceInde else if (m_cfg.aeromodel == btSoftBody::eAeroModel::F_OneSided || m_cfg.aeromodel == btSoftBody::eAeroModel::F_TwoSided) { if (m_cfg.aeromodel == btSoftBody::eAeroModel::F_TwoSided) - nrm *= (btScalar)( (btDot(nrm,rel_v) < 0) ? -1 : +1); + nrm *= (btScalar)((btDot(nrm, rel_v) < 0) ? -1 : +1); - const btScalar dvn=btDot(rel_v,nrm); - /* Compute forces */ - if(dvn>0) + const btScalar dvn = btDot(rel_v, nrm); + /* Compute forces */ + if (dvn > 0) { - btVector3 force(0,0,0); - const btScalar c0 = f.m_ra*dvn*rel_v2; - const btScalar c1 = c0*medium.m_density; - force += nrm*(-c1*kLF); - force += rel_v.normalized()*(-c1*kDG); - force /= 3; - for(int j=0;j<3;++j) ApplyClampedForce(*f.m_n[j],force,dt); + btVector3 force(0, 0, 0); + const btScalar c0 = f.m_ra * dvn * rel_v2; + const btScalar c1 = c0 * medium.m_density; + force += nrm * (-c1 * kLF); + force += rel_v.normalized() * (-c1 * kDG); + force /= 3; + for (int j = 0; j < 3; ++j) ApplyClampedForce(*f.m_n[j], force, dt); } } } } - } // -void btSoftBody::addVelocity(const btVector3& velocity) +void btSoftBody::addVelocity(const btVector3& velocity) { - for(int i=0,ni=m_nodes.size();i0) + Node& n = m_nodes[i]; + if (n.m_im > 0) { - n.m_v = velocity; + n.m_v = velocity; } } } - // -void btSoftBody::addVelocity(const btVector3& velocity,int node) +void btSoftBody::addVelocity(const btVector3& velocity, int node) { - Node& n=m_nodes[node]; - if(n.m_im>0) + Node& n = m_nodes[node]; + if (n.m_im > 0) { - n.m_v += velocity; + n.m_v += velocity; } } // -void btSoftBody::setMass(int node,btScalar mass) +void btSoftBody::setMass(int node, btScalar mass) { - m_nodes[node].m_im=mass>0?1/mass:0; - m_bUpdateRtCst=true; + m_nodes[node].m_im = mass > 0 ? 1 / mass : 0; + m_bUpdateRtCst = true; } // -btScalar btSoftBody::getMass(int node) const +btScalar btSoftBody::getMass(int node) const { - return(m_nodes[node].m_im>0?1/m_nodes[node].m_im:0); + return (m_nodes[node].m_im > 0 ? 1 / m_nodes[node].m_im : 0); } // -btScalar btSoftBody::getTotalMass() const +btScalar btSoftBody::getTotalMass() const { - btScalar mass=0; - for(int i=0;im_x, - f.m_n[1]->m_x, - f.m_n[2]->m_x); - for(int j=0;j<3;++j) + const Face& f = m_faces[i]; + const btScalar twicearea = AreaOf(f.m_n[0]->m_x, + f.m_n[1]->m_x, + f.m_n[2]->m_x); + for (int j = 0; j < 3; ++j) { - f.m_n[j]->m_im+=twicearea; + f.m_n[j]->m_im += twicearea; } } - for( i=0;i ranks; -ranks.resize(m_nodes.size(),0); -int i; + btAlignedObjectArray ranks; + ranks.resize(m_nodes.size(), 0); + int i; -for(i=0;im_im+=btFabs(t.m_rv); - ranks[int(t.m_n[j]-&m_nodes[0])]+=1; + t.m_n[j]->m_im += btFabs(t.m_rv); + ranks[int(t.m_n[j] - &m_nodes[0])] += 1; } } -for( i=0;i0) + if (m_nodes[i].m_im > 0) { - m_nodes[i].m_im=ranks[i]/m_nodes[i].m_im; + m_nodes[i].m_im = ranks[i] / m_nodes[i].m_im; } } -setTotalMass(mass,false); + setTotalMass(mass, false); } // -void btSoftBody::setVolumeDensity(btScalar density) +void btSoftBody::setVolumeDensity(btScalar density) { -btScalar volume=0; -for(int i=0;igetMargin(); - ATTRIBUTE_ALIGNED16(btDbvtVolume) vol; - - for(int i=0,ni=m_nodes.size();igetMargin(); + ATTRIBUTE_ALIGNED16(btDbvtVolume) + vol; + + for (int i = 0, ni = m_nodes.size(); i < ni; ++i) { - Node& n=m_nodes[i]; - n.m_x=trs*n.m_x; - n.m_q=trs*n.m_q; - n.m_n=trs.getBasis()*n.m_n; - vol = btDbvtVolume::FromCR(n.m_x,margin); - - m_ndbvt.update(n.m_leaf,vol); + Node& n = m_nodes[i]; + n.m_x = trs * n.m_x; + n.m_q = trs * n.m_q; + n.m_n = trs.getBasis() * n.m_n; + vol = btDbvtVolume::FromCR(n.m_x, margin); + + m_ndbvt.update(n.m_leaf, vol); } updateNormals(); updateBounds(); @@ -805,37 +818,37 @@ void btSoftBody::transform(const btTransform& trs) } // -void btSoftBody::translate(const btVector3& trs) +void btSoftBody::translate(const btVector3& trs) { - btTransform t; + btTransform t; t.setIdentity(); t.setOrigin(trs); transform(t); } // -void btSoftBody::rotate( const btQuaternion& rot) +void btSoftBody::rotate(const btQuaternion& rot) { - btTransform t; + btTransform t; t.setIdentity(); t.setRotation(rot); transform(t); } // -void btSoftBody::scale(const btVector3& scl) +void btSoftBody::scale(const btVector3& scl) { + const btScalar margin = getCollisionShape()->getMargin(); + ATTRIBUTE_ALIGNED16(btDbvtVolume) + vol; - const btScalar margin=getCollisionShape()->getMargin(); - ATTRIBUTE_ALIGNED16(btDbvtVolume) vol; - - for(int i=0,ni=m_nodes.size();i0 ? - 1/(m_nodes[i].m_im*tmass) : - kmass/tmass; + Node& n = m_nodes[i]; + m_pose.m_wgh[i] = n.m_im > 0 ? 1 / (m_nodes[i].m_im * tmass) : kmass / tmass; } - /* Pos */ - const btVector3 com=evaluateCom(); + /* Pos */ + const btVector3 com = evaluateCom(); m_pose.m_pos.resize(m_nodes.size()); - for( i=0,ni=m_nodes.size();im_x-l.m_n[1]->m_x).length(); - l.m_c1 = l.m_rl*l.m_rl; + Link& l = m_links[i]; + l.m_rl = (l.m_n[0]->m_x - l.m_n[1]->m_x).length(); + l.m_c1 = l.m_rl * l.m_rl; } } // -btScalar btSoftBody::getVolume() const +btScalar btSoftBody::getVolume() const { - btScalar vol=0; - if(m_nodes.size()>0) + btScalar vol = 0; + if (m_nodes.size() > 0) { - int i,ni; + int i, ni; - const btVector3 org=m_nodes[0].m_x; - for(i=0,ni=m_faces.size();im_x-org,btCross(f.m_n[1]->m_x-org,f.m_n[2]->m_x-org)); + const Face& f = m_faces[i]; + vol += btDot(f.m_n[0]->m_x - org, btCross(f.m_n[1]->m_x - org, f.m_n[2]->m_x - org)); } - vol/=(btScalar)6; + vol /= (btScalar)6; } - return(vol); + return (vol); } // -int btSoftBody::clusterCount() const +int btSoftBody::clusterCount() const { - return(m_clusters.size()); + return (m_clusters.size()); } // -btVector3 btSoftBody::clusterCom(const Cluster* cluster) +btVector3 btSoftBody::clusterCom(const Cluster* cluster) { - btVector3 com(0,0,0); - for(int i=0,ni=cluster->m_nodes.size();im_nodes.size(); i < ni; ++i) { - com+=cluster->m_nodes[i]->m_x*cluster->m_masses[i]; + com += cluster->m_nodes[i]->m_x * cluster->m_masses[i]; } - return(com*cluster->m_imass); + return (com * cluster->m_imass); } // -btVector3 btSoftBody::clusterCom(int cluster) const +btVector3 btSoftBody::clusterCom(int cluster) const { - return(clusterCom(m_clusters[cluster])); + return (clusterCom(m_clusters[cluster])); } // -btVector3 btSoftBody::clusterVelocity(const Cluster* cluster,const btVector3& rpos) +btVector3 btSoftBody::clusterVelocity(const Cluster* cluster, const btVector3& rpos) { - return(cluster->m_lv+btCross(cluster->m_av,rpos)); + return (cluster->m_lv + btCross(cluster->m_av, rpos)); } // -void btSoftBody::clusterVImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse) +void btSoftBody::clusterVImpulse(Cluster* cluster, const btVector3& rpos, const btVector3& impulse) { - const btVector3 li=cluster->m_imass*impulse; - const btVector3 ai=cluster->m_invwi*btCross(rpos,impulse); - cluster->m_vimpulses[0]+=li;cluster->m_lv+=li; - cluster->m_vimpulses[1]+=ai;cluster->m_av+=ai; + const btVector3 li = cluster->m_imass * impulse; + const btVector3 ai = cluster->m_invwi * btCross(rpos, impulse); + cluster->m_vimpulses[0] += li; + cluster->m_lv += li; + cluster->m_vimpulses[1] += ai; + cluster->m_av += ai; cluster->m_nvimpulses++; } // -void btSoftBody::clusterDImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse) +void btSoftBody::clusterDImpulse(Cluster* cluster, const btVector3& rpos, const btVector3& impulse) { - const btVector3 li=cluster->m_imass*impulse; - const btVector3 ai=cluster->m_invwi*btCross(rpos,impulse); - cluster->m_dimpulses[0]+=li; - cluster->m_dimpulses[1]+=ai; + const btVector3 li = cluster->m_imass * impulse; + const btVector3 ai = cluster->m_invwi * btCross(rpos, impulse); + cluster->m_dimpulses[0] += li; + cluster->m_dimpulses[1] += ai; cluster->m_ndimpulses++; } // -void btSoftBody::clusterImpulse(Cluster* cluster,const btVector3& rpos,const Impulse& impulse) +void btSoftBody::clusterImpulse(Cluster* cluster, const btVector3& rpos, const Impulse& impulse) { - if(impulse.m_asVelocity) clusterVImpulse(cluster,rpos,impulse.m_velocity); - if(impulse.m_asDrift) clusterDImpulse(cluster,rpos,impulse.m_drift); + if (impulse.m_asVelocity) clusterVImpulse(cluster, rpos, impulse.m_velocity); + if (impulse.m_asDrift) clusterDImpulse(cluster, rpos, impulse.m_drift); } // -void btSoftBody::clusterVAImpulse(Cluster* cluster,const btVector3& impulse) +void btSoftBody::clusterVAImpulse(Cluster* cluster, const btVector3& impulse) { - const btVector3 ai=cluster->m_invwi*impulse; - cluster->m_vimpulses[1]+=ai;cluster->m_av+=ai; + const btVector3 ai = cluster->m_invwi * impulse; + cluster->m_vimpulses[1] += ai; + cluster->m_av += ai; cluster->m_nvimpulses++; } // -void btSoftBody::clusterDAImpulse(Cluster* cluster,const btVector3& impulse) +void btSoftBody::clusterDAImpulse(Cluster* cluster, const btVector3& impulse) { - const btVector3 ai=cluster->m_invwi*impulse; - cluster->m_dimpulses[1]+=ai; + const btVector3 ai = cluster->m_invwi * impulse; + cluster->m_dimpulses[1] += ai; cluster->m_ndimpulses++; } // -void btSoftBody::clusterAImpulse(Cluster* cluster,const Impulse& impulse) +void btSoftBody::clusterAImpulse(Cluster* cluster, const Impulse& impulse) { - if(impulse.m_asVelocity) clusterVAImpulse(cluster,impulse.m_velocity); - if(impulse.m_asDrift) clusterDAImpulse(cluster,impulse.m_drift); + if (impulse.m_asVelocity) clusterVAImpulse(cluster, impulse.m_velocity); + if (impulse.m_asDrift) clusterDAImpulse(cluster, impulse.m_drift); } // -void btSoftBody::clusterDCImpulse(Cluster* cluster,const btVector3& impulse) +void btSoftBody::clusterDCImpulse(Cluster* cluster, const btVector3& impulse) { - cluster->m_dimpulses[0]+=impulse*cluster->m_imass; + cluster->m_dimpulses[0] += impulse * cluster->m_imass; cluster->m_ndimpulses++; } struct NodeLinks { - btAlignedObjectArray m_links; + btAlignedObjectArray m_links; }; - - // -int btSoftBody::generateBendingConstraints(int distance,Material* mat) +int btSoftBody::generateBendingConstraints(int distance, Material* mat) { - int i,j; + int i, j; - if(distance>1) + if (distance > 1) { - /* Build graph */ - const int n=m_nodes.size(); - const unsigned inf=(~(unsigned)0)>>1; - unsigned* adj=new unsigned[n*n]; - + /* Build graph */ + const int n = m_nodes.size(); + const unsigned inf = (~(unsigned)0) >> 1; + unsigned* adj = new unsigned[n * n]; -#define IDX(_x_,_y_) ((_y_)*n+(_x_)) - for(j=0;j nodeLinks; - /* Build node links */ nodeLinks.resize(m_nodes.size()); - for( i=0;isum) + const unsigned sum = adj[IDX(i, k)] + adj[IDX(k, j)]; + btAssert(sum == 2); + if (adj[IDX(i, j)] > sum) { - adj[IDX(i,j)]=adj[IDX(j,i)]=sum; + adj[IDX(i, j)] = adj[IDX(j, i)] = sum; } } - } } } - } else + } + else { ///generic Floyd's algorithm - for(int k=0;ksum) + const unsigned sum = adj[IDX(i, k)] + adj[IDX(k, j)]; + if (adj[IDX(i, j)] > sum) { - adj[IDX(i,j)]=adj[IDX(j,i)]=sum; + adj[IDX(i, j)] = adj[IDX(j, i)] = sum; } } } } } - - /* Build links */ - int nlinks=0; - for(j=0;jm_leaf) m_cdbvt.remove(c->m_leaf); + Cluster* c = m_clusters[index]; + if (c->m_leaf) m_cdbvt.remove(c->m_leaf); c->~Cluster(); btAlignedFree(c); m_clusters.remove(c); } // -void btSoftBody::releaseClusters() +void btSoftBody::releaseClusters() { - while(m_clusters.size()>0) releaseCluster(0); + while (m_clusters.size() > 0) releaseCluster(0); } // -int btSoftBody::generateClusters(int k,int maxiterations) +int btSoftBody::generateClusters(int k, int maxiterations) { int i; releaseClusters(); - m_clusters.resize(btMin(k,m_nodes.size())); - for(i=0;im_collide= true; + m_clusters[i] = new (btAlignedAlloc(sizeof(Cluster), 16)) Cluster(); + m_clusters[i]->m_collide = true; } - k=m_clusters.size(); - if(k>0) + k = m_clusters.size(); + if (k > 0) { - /* Initialize */ - btAlignedObjectArray centers; - btVector3 cog(0,0,0); - int i; - for(i=0;i centers; + btVector3 cog(0, 0, 0); + int i; + for (i = 0; i < m_nodes.size(); ++i) { - cog+=m_nodes[i].m_x; - m_clusters[(i*29873)%m_clusters.size()]->m_nodes.push_back(&m_nodes[i]); + cog += m_nodes[i].m_x; + m_clusters[(i * 29873) % m_clusters.size()]->m_nodes.push_back(&m_nodes[i]); } - cog/=(btScalar)m_nodes.size(); - centers.resize(k,cog); - /* Iterate */ - const btScalar slope=16; - bool changed; - int iterations=0; - do { - const btScalar w=2-btMin(1,iterations/slope); - changed=false; - iterations++; + cog /= (btScalar)m_nodes.size(); + centers.resize(k, cog); + /* Iterate */ + const btScalar slope = 16; + bool changed; + int iterations = 0; + do + { + const btScalar w = 2 - btMin(1, iterations / slope); + changed = false; + iterations++; int i; - for(i=0;im_nodes.size();++j) + btVector3 c(0, 0, 0); + for (int j = 0; j < m_clusters[i]->m_nodes.size(); ++j) { - c+=m_clusters[i]->m_nodes[j]->m_x; + c += m_clusters[i]->m_nodes[j]->m_x; } - if(m_clusters[i]->m_nodes.size()) + if (m_clusters[i]->m_nodes.size()) { - c /= (btScalar)m_clusters[i]->m_nodes.size(); - c = centers[i]+(c-centers[i])*w; - changed |= ((c-centers[i]).length2()>SIMD_EPSILON); - centers[i] = c; + c /= (btScalar)m_clusters[i]->m_nodes.size(); + c = centers[i] + (c - centers[i]) * w; + changed |= ((c - centers[i]).length2() > SIMD_EPSILON); + centers[i] = c; m_clusters[i]->m_nodes.resize(0); - } + } } - for(i=0;im_nodes.push_back(&m_nodes[i]); - } - } while(changed&&(iterations cids; - cids.resize(m_nodes.size(),-1); - for(i=0;i cids; + cids.resize(m_nodes.size(), -1); + for (i = 0; i < m_clusters.size(); ++i) { - for(int j=0;jm_nodes.size();++j) + for (int j = 0; j < m_clusters[i]->m_nodes.size(); ++j) { - cids[int(m_clusters[i]->m_nodes[j]-&m_nodes[0])]=i; + cids[int(m_clusters[i]->m_nodes[j] - &m_nodes[0])] = i; } } - for(i=0;im_nodes.findLinearSearch(&m_nodes[kid])==m_clusters[cid]->m_nodes.size()) + if (m_clusters[cid]->m_nodes.findLinearSearch(&m_nodes[kid]) == m_clusters[cid]->m_nodes.size()) { m_clusters[cid]->m_nodes.push_back(&m_nodes[kid]); } @@ -1289,55 +1297,56 @@ int btSoftBody::generateClusters(int k,int maxiterations) } } } - /* Master */ - if(m_clusters.size()>1) + /* Master */ + if (m_clusters.size() > 1) { - Cluster* pmaster=new(btAlignedAlloc(sizeof(Cluster),16)) Cluster(); - pmaster->m_collide = false; + Cluster* pmaster = new (btAlignedAlloc(sizeof(Cluster), 16)) Cluster(); + pmaster->m_collide = false; pmaster->m_nodes.reserve(m_nodes.size()); - for(int i=0;im_nodes.push_back(&m_nodes[i]); + for (int i = 0; i < m_nodes.size(); ++i) pmaster->m_nodes.push_back(&m_nodes[i]); m_clusters.push_back(pmaster); - btSwap(m_clusters[0],m_clusters[m_clusters.size()-1]); + btSwap(m_clusters[0], m_clusters[m_clusters.size() - 1]); } - /* Terminate */ - for(i=0;im_nodes.size()==0) + if (m_clusters[i]->m_nodes.size() == 0) { releaseCluster(i--); } } - } else + } + else { //create a cluster for each tetrahedron (if tetrahedra exist) or each face if (m_tetras.size()) { m_clusters.resize(m_tetras.size()); - for(i=0;im_collide= true; + m_clusters[i] = new (btAlignedAlloc(sizeof(Cluster), 16)) Cluster(); + m_clusters[i]->m_collide = true; } - for (i=0;im_nodes.push_back(m_tetras[i].m_n[j]); } } - - } else + } + else { m_clusters.resize(m_faces.size()); - for(i=0;im_collide= true; + m_clusters[i] = new (btAlignedAlloc(sizeof(Cluster), 16)) Cluster(); + m_clusters[i]->m_collide = true; } - for(i=0;im_nodes.push_back(m_faces[i].m_n[j]); } @@ -1350,261 +1359,272 @@ int btSoftBody::generateClusters(int k,int maxiterations) initializeClusters(); updateClusters(); - //for self-collision - m_clusterConnectivity.resize(m_clusters.size()*m_clusters.size()); + m_clusterConnectivity.resize(m_clusters.size() * m_clusters.size()); { - for (int c0=0;c0m_clusterIndex=c0; - for (int c1=0;c1m_clusterIndex = c0; + for (int c1 = 0; c1 < m_clusters.size(); c1++) { - - bool connected=false; + bool connected = false; Cluster* cla = m_clusters[c0]; Cluster* clb = m_clusters[c1]; - for (int i=0;!connected&&im_nodes.size();i++) + for (int i = 0; !connected && i < cla->m_nodes.size(); i++) { - for (int j=0;jm_nodes.size();j++) + for (int j = 0; j < clb->m_nodes.size(); j++) { if (cla->m_nodes[i] == clb->m_nodes[j]) { - connected=true; + connected = true; break; } } } - m_clusterConnectivity[c0+c1*m_clusters.size()]=connected; + m_clusterConnectivity[c0 + c1 * m_clusters.size()] = connected; } } } } - return(m_clusters.size()); + return (m_clusters.size()); } // -void btSoftBody::refine(ImplicitFn* ifn,btScalar accurary,bool cut) +void btSoftBody::refine(ImplicitFn* ifn, btScalar accurary, bool cut) { - const Node* nbase = &m_nodes[0]; - int ncount = m_nodes.size(); - btSymMatrix edges(ncount,-2); - int newnodes=0; - int i,j,k,ni; + const Node* nbase = &m_nodes[0]; + int ncount = m_nodes.size(); + btSymMatrix edges(ncount, -2); + int newnodes = 0; + int i, j, k, ni; - /* Filter out */ - for(i=0;iEval(l.m_n[0]->m_x),ifn->Eval(l.m_n[1]->m_x))) + if (!SameSign(ifn->Eval(l.m_n[0]->m_x), ifn->Eval(l.m_n[1]->m_x))) { - btSwap(m_links[i],m_links[m_links.size()-1]); - m_links.pop_back();--i; + btSwap(m_links[i], m_links[m_links.size() - 1]); + m_links.pop_back(); + --i; } - } + } } - /* Fill edges */ - for(i=0;i0) + Node& a = m_nodes[i]; + Node& b = m_nodes[j]; + const btScalar t = ImplicitSolve(ifn, a.m_x, b.m_x, accurary); + if (t > 0) { - const btVector3 x=Lerp(a.m_x,b.m_x,t); - const btVector3 v=Lerp(a.m_v,b.m_v,t); - btScalar m=0; - if(a.m_im>0) + const btVector3 x = Lerp(a.m_x, b.m_x, t); + const btVector3 v = Lerp(a.m_v, b.m_v, t); + btScalar m = 0; + if (a.m_im > 0) { - if(b.m_im>0) + if (b.m_im > 0) { - const btScalar ma=1/a.m_im; - const btScalar mb=1/b.m_im; - const btScalar mc=Lerp(ma,mb,t); - const btScalar f=(ma+mb)/(ma+mb+mc); - a.m_im=1/(ma*f); - b.m_im=1/(mb*f); - m=mc*f; + const btScalar ma = 1 / a.m_im; + const btScalar mb = 1 / b.m_im; + const btScalar mc = Lerp(ma, mb, t); + const btScalar f = (ma + mb) / (ma + mb + mc); + a.m_im = 1 / (ma * f); + b.m_im = 1 / (mb * f); + m = mc * f; } else - { a.m_im/=0.5f;m=1/a.m_im; } + { + a.m_im /= 0.5f; + m = 1 / a.m_im; + } } else { - if(b.m_im>0) - { b.m_im/=0.5f;m=1/b.m_im; } + if (b.m_im > 0) + { + b.m_im /= 0.5f; + m = 1 / b.m_im; + } else - m=0; + m = 0; } - appendNode(x,m); - edges(i,j)=m_nodes.size()-1; - m_nodes[edges(i,j)].m_v=v; + appendNode(x, m); + edges(i, j) = m_nodes.size() - 1; + m_nodes[edges(i, j)].m_v = v; ++newnodes; } } } } - nbase=&m_nodes[0]; - /* Refine links */ - for(i=0,ni=m_links.size();i0) + const int ni = edges(idx[0], idx[1]); + if (ni > 0) { appendLink(i); - Link* pft[]={ &m_links[i], - &m_links[m_links.size()-1]}; - pft[0]->m_n[0]=&m_nodes[idx[0]]; - pft[0]->m_n[1]=&m_nodes[ni]; - pft[1]->m_n[0]=&m_nodes[ni]; - pft[1]->m_n[1]=&m_nodes[idx[1]]; + Link* pft[] = {&m_links[i], + &m_links[m_links.size() - 1]}; + pft[0]->m_n[0] = &m_nodes[idx[0]]; + pft[0]->m_n[1] = &m_nodes[ni]; + pft[1]->m_n[0] = &m_nodes[ni]; + pft[1]->m_n[1] = &m_nodes[idx[1]]; } } } - /* Refine faces */ - for(i=0;i0) + const int ni = edges(idx[j], idx[k]); + if (ni > 0) { appendFace(i); - const int l=(k+1)%3; - Face* pft[]={ &m_faces[i], - &m_faces[m_faces.size()-1]}; - pft[0]->m_n[0]=&m_nodes[idx[l]]; - pft[0]->m_n[1]=&m_nodes[idx[j]]; - pft[0]->m_n[2]=&m_nodes[ni]; - pft[1]->m_n[0]=&m_nodes[ni]; - pft[1]->m_n[1]=&m_nodes[idx[k]]; - pft[1]->m_n[2]=&m_nodes[idx[l]]; - appendLink(ni,idx[l],pft[0]->m_material); - --i;break; + const int l = (k + 1) % 3; + Face* pft[] = {&m_faces[i], + &m_faces[m_faces.size() - 1]}; + pft[0]->m_n[0] = &m_nodes[idx[l]]; + pft[0]->m_n[1] = &m_nodes[idx[j]]; + pft[0]->m_n[2] = &m_nodes[ni]; + pft[1]->m_n[0] = &m_nodes[ni]; + pft[1]->m_n[1] = &m_nodes[idx[k]]; + pft[1]->m_n[2] = &m_nodes[idx[l]]; + appendLink(ni, idx[l], pft[0]->m_material); + --i; + break; } } } } - /* Cut */ - if(cut) - { - btAlignedObjectArray cnodes; - const int pcount=ncount; - int i; - ncount=m_nodes.size(); - cnodes.resize(ncount,0); - /* Nodes */ - for(i=0;i cnodes; + const int pcount = ncount; + int i; + ncount = m_nodes.size(); + cnodes.resize(ncount, 0); + /* Nodes */ + for (i = 0; i < ncount; ++i) { - const btVector3 x=m_nodes[i].m_x; - if((i>=pcount)||(btFabs(ifn->Eval(x))= pcount) || (btFabs(ifn->Eval(x)) < accurary)) { - const btVector3 v=m_nodes[i].m_v; - btScalar m=getMass(i); - if(m>0) { m*=0.5f;m_nodes[i].m_im/=0.5f; } - appendNode(x,m); - cnodes[i]=m_nodes.size()-1; - m_nodes[cnodes[i]].m_v=v; + const btVector3 v = m_nodes[i].m_v; + btScalar m = getMass(i); + if (m > 0) + { + m *= 0.5f; + m_nodes[i].m_im /= 0.5f; + } + appendNode(x, m); + cnodes[i] = m_nodes.size() - 1; + m_nodes[cnodes[i]].m_v = v; } } - nbase=&m_nodes[0]; - /* Links */ - for(i=0,ni=m_links.size();iEval(m_nodes[id[0]].m_x)Eval(m_nodes[id[1]].m_x)Eval(m_nodes[id[0]].m_x) < accurary) && + (ifn->Eval(m_nodes[id[1]].m_x) < accurary))) + todetach = i; } - if(todetach) + if (todetach) { - Link& l=m_links[todetach]; - for(int j=0;j<2;++j) + Link& l = m_links[todetach]; + for (int j = 0; j < 2; ++j) { - int cn=cnodes[int(l.m_n[j]-nbase)]; - if(cn) l.m_n[j]=&m_nodes[cn]; - } - } - } - /* Faces */ - for(i=0,ni=m_faces.size();iEval(n[0]->m_x)Eval(n[1]->m_x)Eval(n[2]->m_x) ranks; - btAlignedObjectArray todelete; - ranks.resize(nnodes,0); - for(i=0,ni=m_links.size();iEval(n[0]->m_x) < accurary) && + (ifn->Eval(n[1]->m_x) < accurary) && + (ifn->Eval(n[2]->m_x) < accurary)) + { + for (int j = 0; j < 3; ++j) + { + int cn = cnodes[int(n[j] - nbase)]; + if (cn) n[j] = &m_nodes[cn]; + } + } } - for(i=0,ni=m_faces.size();i ranks; + btAlignedObjectArray todelete; + ranks.resize(nnodes, 0); + for (i = 0, ni = m_links.size(); i < ni; ++i) { - for(int j=0;j<3;++j) ranks[int(m_faces[i].m_n[j]-nbase)]++; + for (int j = 0; j < 2; ++j) ranks[int(m_links[i].m_n[j] - nbase)]++; } - for(i=0;im_v=v; - pn[1]->m_v=v; - for(i=0,ni=m_links.size();im_v = v; + pn[1]->m_v = v; + for (i = 0, ni = m_links.size(); i < ni; ++i) { - const int mtch=MatchEdge(m_links[i].m_n[0],m_links[i].m_n[1],pa,pb); - if(mtch!=-1) + const int mtch = MatchEdge(m_links[i].m_n[0], m_links[i].m_n[1], pa, pb); + if (mtch != -1) { appendLink(i); - Link* pft[]={&m_links[i],&m_links[m_links.size()-1]}; - pft[0]->m_n[1]=pn[mtch]; - pft[1]->m_n[0]=pn[1-mtch]; - done=true; + Link* pft[] = {&m_links[i], &m_links[m_links.size() - 1]}; + pft[0]->m_n[1] = pn[mtch]; + pft[1]->m_n[0] = pn[1 - mtch]; + done = true; } } - for(i=0,ni=m_faces.size();im_n[l]=pn[mtch]; - pft[1]->m_n[k]=pn[1-mtch]; - appendLink(pn[0],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true); - appendLink(pn[1],pft[0]->m_n[(l+1)%3],pft[0]->m_material,true); + Face* pft[] = {&m_faces[i], &m_faces[m_faces.size() - 1]}; + pft[0]->m_n[l] = pn[mtch]; + pft[1]->m_n[k] = pn[1 - mtch]; + appendLink(pn[0], pft[0]->m_n[(l + 1) % 3], pft[0]->m_material, true); + appendLink(pn[1], pft[0]->m_n[(l + 1) % 3], pft[0]->m_material, true); } } } - if(!done) + if (!done) { m_ndbvt.remove(pn[0]->m_leaf); m_ndbvt.remove(pn[1]->m_leaf); m_nodes.pop_back(); m_nodes.pop_back(); } - return(done); + return (done); } // -bool btSoftBody::rayTest(const btVector3& rayFrom, - const btVector3& rayTo, - sRayCast& results) +bool btSoftBody::rayTest(const btVector3& rayFrom, + const btVector3& rayTo, + sRayCast& results) { - if(m_faces.size()&&m_fdbvt.empty()) + if (m_faces.size() && m_fdbvt.empty()) initializeFaceTree(); - results.body = this; + results.body = this; results.fraction = 1.f; - results.feature = eFeature::None; - results.index = -1; + results.feature = eFeature::None; + results.index = -1; - return(rayTest(rayFrom,rayTo,results.fraction,results.feature,results.index,false)!=0); + return (rayTest(rayFrom, rayTo, results.fraction, results.feature, results.index, false) != 0); } // -void btSoftBody::setSolver(eSolverPresets::_ preset) +void btSoftBody::setSolver(eSolverPresets::_ preset) { m_cfg.m_vsequence.clear(); m_cfg.m_psequence.clear(); m_cfg.m_dsequence.clear(); - switch(preset) + switch (preset) { - case eSolverPresets::Positions: - m_cfg.m_psequence.push_back(ePSolver::Anchors); - m_cfg.m_psequence.push_back(ePSolver::RContacts); - m_cfg.m_psequence.push_back(ePSolver::SContacts); - m_cfg.m_psequence.push_back(ePSolver::Linear); - break; - case eSolverPresets::Velocities: - m_cfg.m_vsequence.push_back(eVSolver::Linear); + case eSolverPresets::Positions: + m_cfg.m_psequence.push_back(ePSolver::Anchors); + m_cfg.m_psequence.push_back(ePSolver::RContacts); + m_cfg.m_psequence.push_back(ePSolver::SContacts); + m_cfg.m_psequence.push_back(ePSolver::Linear); + break; + case eSolverPresets::Velocities: + m_cfg.m_vsequence.push_back(eVSolver::Linear); - m_cfg.m_psequence.push_back(ePSolver::Anchors); - m_cfg.m_psequence.push_back(ePSolver::RContacts); - m_cfg.m_psequence.push_back(ePSolver::SContacts); + m_cfg.m_psequence.push_back(ePSolver::Anchors); + m_cfg.m_psequence.push_back(ePSolver::RContacts); + m_cfg.m_psequence.push_back(ePSolver::SContacts); - m_cfg.m_dsequence.push_back(ePSolver::Linear); - break; + m_cfg.m_dsequence.push_back(ePSolver::Linear); + break; } } // -void btSoftBody::predictMotion(btScalar dt) +void btSoftBody::predictMotion(btScalar dt) { + int i, ni; - int i,ni; - - /* Update */ - if(m_bUpdateRtCst) + /* Update */ + if (m_bUpdateRtCst) { - m_bUpdateRtCst=false; + m_bUpdateRtCst = false; updateConstants(); m_fdbvt.clear(); - if(m_cfg.collisions&fCollision::VF_SS) + if (m_cfg.collisions & fCollision::VF_SS) { - initializeFaceTree(); + initializeFaceTree(); } } - /* Prepare */ - m_sst.sdt = dt*m_cfg.timescale; - m_sst.isdt = 1/m_sst.sdt; - m_sst.velmrg = m_sst.sdt*3; - m_sst.radmrg = getCollisionShape()->getMargin(); - m_sst.updmrg = m_sst.radmrg*(btScalar)0.25; - /* Forces */ - addVelocity(m_worldInfo->m_gravity*m_sst.sdt); + /* Prepare */ + m_sst.sdt = dt * m_cfg.timescale; + m_sst.isdt = 1 / m_sst.sdt; + m_sst.velmrg = m_sst.sdt * 3; + m_sst.radmrg = getCollisionShape()->getMargin(); + m_sst.updmrg = m_sst.radmrg * (btScalar)0.25; + /* Forces */ + addVelocity(m_worldInfo->m_gravity * m_sst.sdt); applyForces(); - /* Integrate */ - for(i=0,ni=m_nodes.size();im_maxDisplacement; - btScalar clampDeltaV = maxDisplacement/m_sst.sdt; - for (int c=0;c<3;c++) + btScalar clampDeltaV = maxDisplacement / m_sst.sdt; + for (int c = 0; c < 3; c++) { - if (deltaV[c]>clampDeltaV) + if (deltaV[c] > clampDeltaV) { deltaV[c] = clampDeltaV; } - if (deltaV[c]<-clampDeltaV) + if (deltaV[c] < -clampDeltaV) { - deltaV[c]=-clampDeltaV; + deltaV[c] = -clampDeltaV; } } } - n.m_v += deltaV; - n.m_x += n.m_v*m_sst.sdt; - n.m_f = btVector3(0,0,0); + n.m_v += deltaV; + n.m_x += n.m_v * m_sst.sdt; + n.m_f = btVector3(0, 0, 0); } - /* Clusters */ + /* Clusters */ updateClusters(); - /* Bounds */ - updateBounds(); - /* Nodes */ - ATTRIBUTE_ALIGNED16(btDbvtVolume) vol; - for(i=0,ni=m_nodes.size();im_v+ - f.m_n[1]->m_v+ - f.m_n[2]->m_v)/3; - vol = VolumeOf(f,m_sst.radmrg); - m_fdbvt.update( f.m_leaf, - vol, - v*m_sst.velmrg, - m_sst.updmrg); + Face& f = m_faces[i]; + const btVector3 v = (f.m_n[0]->m_v + + f.m_n[1]->m_v + + f.m_n[2]->m_v) / + 3; + vol = VolumeOf(f, m_sst.radmrg); + m_fdbvt.update(f.m_leaf, + vol, + v * m_sst.velmrg, + m_sst.updmrg); } } - /* Pose */ + /* Pose */ updatePose(); - /* Match */ - if(m_pose.m_bframe&&(m_cfg.kMT>0)) + /* Match */ + if (m_pose.m_bframe && (m_cfg.kMT > 0)) { - const btMatrix3x3 posetrs=m_pose.m_rot; - for(int i=0,ni=m_nodes.size();i0) + Node& n = m_nodes[i]; + if (n.m_im > 0) { - const btVector3 x=posetrs*m_pose.m_pos[i]+m_pose.m_com; - n.m_x=Lerp(n.m_x,x,m_cfg.kMT); + const btVector3 x = posetrs * m_pose.m_pos[i] + m_pose.m_com; + n.m_x = Lerp(n.m_x, x, m_cfg.kMT); } } } - /* Clear contacts */ + /* Clear contacts */ m_rcontacts.resize(0); m_scontacts.resize(0); - /* Optimize dbvt's */ + /* Optimize dbvt's */ m_ndbvt.optimizeIncremental(1); m_fdbvt.optimizeIncremental(1); m_cdbvt.optimizeIncremental(1); } // -void btSoftBody::solveConstraints() +void btSoftBody::solveConstraints() { - - /* Apply clusters */ + /* Apply clusters */ applyClusters(false); - /* Prepare links */ + /* Prepare links */ - int i,ni; + int i, ni; - for(i=0,ni=m_links.size();im_q-l.m_n[0]->m_q; - l.m_c2 = 1/(l.m_c3.length2()*l.m_c0); + Link& l = m_links[i]; + l.m_c3 = l.m_n[1]->m_q - l.m_n[0]->m_q; + l.m_c2 = 1 / (l.m_c3.length2() * l.m_c0); } - /* Prepare anchors */ - for(i=0,ni=m_anchors.size();igetWorldTransform().getBasis()*a.m_local; - a.m_c0 = ImpulseMatrix( m_sst.sdt, - a.m_node->m_im, - a.m_body->getInvMass(), - a.m_body->getInvInertiaTensorWorld(), - ra); - a.m_c1 = ra; - a.m_c2 = m_sst.sdt*a.m_node->m_im; + Anchor& a = m_anchors[i]; + const btVector3 ra = a.m_body->getWorldTransform().getBasis() * a.m_local; + a.m_c0 = ImpulseMatrix(m_sst.sdt, + a.m_node->m_im, + a.m_body->getInvMass(), + a.m_body->getInvInertiaTensorWorld(), + ra); + a.m_c1 = ra; + a.m_c2 = m_sst.sdt * a.m_node->m_im; a.m_body->activate(); } - /* Solve velocities */ - if(m_cfg.viterations>0) + /* Solve velocities */ + if (m_cfg.viterations > 0) { - /* Solve */ - for(int isolve=0;isolve0) + /* Solve positions */ + if (m_cfg.piterations > 0) { - for(int isolve=0;isolve0) + /* Solve drift */ + if (m_cfg.diterations > 0) { - const btScalar vcf=m_cfg.kVCF*m_sst.isdt; - for(i=0,ni=m_nodes.size();i& bodies) +void btSoftBody::solveClusters(const btAlignedObjectArray& bodies) { - const int nb=bodies.size(); - int iterations=0; + const int nb = bodies.size(); + int iterations = 0; int i; - for(i=0;im_cfg.citerations); + iterations = btMax(iterations, bodies[i]->m_cfg.citerations); } - for(i=0;iprepareClusters(iterations); } - for(i=0;isolveClusters(sor); } } - for(i=0;icleanupClusters(); } } // -void btSoftBody::integrateMotion() +void btSoftBody::integrateMotion() { - /* Update */ + /* Update */ updateNormals(); } // -btSoftBody::RayFromToCaster::RayFromToCaster(const btVector3& rayFrom,const btVector3& rayTo,btScalar mxt) +btSoftBody::RayFromToCaster::RayFromToCaster(const btVector3& rayFrom, const btVector3& rayTo, btScalar mxt) { m_rayFrom = rayFrom; - m_rayNormalizedDirection = (rayTo-rayFrom); + m_rayNormalizedDirection = (rayTo - rayFrom); m_rayTo = rayTo; - m_mint = mxt; - m_face = 0; - m_tests = 0; + m_mint = mxt; + m_face = 0; + m_tests = 0; } // -void btSoftBody::RayFromToCaster::Process(const btDbvtNode* leaf) +void btSoftBody::RayFromToCaster::Process(const btDbvtNode* leaf) { - btSoftBody::Face& f=*(btSoftBody::Face*)leaf->data; - const btScalar t=rayFromToTriangle( m_rayFrom,m_rayTo,m_rayNormalizedDirection, - f.m_n[0]->m_x, - f.m_n[1]->m_x, - f.m_n[2]->m_x, - m_mint); - if((t>0)&&(tdata; + const btScalar t = rayFromToTriangle(m_rayFrom, m_rayTo, m_rayNormalizedDirection, + f.m_n[0]->m_x, + f.m_n[1]->m_x, + f.m_n[2]->m_x, + m_mint); + if ((t > 0) && (t < m_mint)) + { + m_mint = t; + m_face = &f; } ++m_tests; } // -btScalar btSoftBody::RayFromToCaster::rayFromToTriangle( const btVector3& rayFrom, - const btVector3& rayTo, - const btVector3& rayNormalizedDirection, - const btVector3& a, - const btVector3& b, - const btVector3& c, - btScalar maxt) +btScalar btSoftBody::RayFromToCaster::rayFromToTriangle(const btVector3& rayFrom, + const btVector3& rayTo, + const btVector3& rayNormalizedDirection, + const btVector3& a, + const btVector3& b, + const btVector3& c, + btScalar maxt) { - static const btScalar ceps=-SIMD_EPSILON*10; - static const btScalar teps=SIMD_EPSILON*10; + static const btScalar ceps = -SIMD_EPSILON * 10; + static const btScalar teps = SIMD_EPSILON * 10; - const btVector3 n=btCross(b-a,c-a); - const btScalar d=btDot(a,n); - const btScalar den=btDot(rayNormalizedDirection,n); - if(!btFuzzyZero(den)) + const btVector3 n = btCross(b - a, c - a); + const btScalar d = btDot(a, n); + const btScalar den = btDot(rayNormalizedDirection, n); + if (!btFuzzyZero(den)) { - const btScalar num=btDot(rayFrom,n)-d; - const btScalar t=-num/den; - if((t>teps)&&(t teps) && (t < maxt)) { - const btVector3 hit=rayFrom+rayNormalizedDirection*t; - if( (btDot(n,btCross(a-hit,b-hit))>ceps) && - (btDot(n,btCross(b-hit,c-hit))>ceps) && - (btDot(n,btCross(c-hit,a-hit))>ceps)) + const btVector3 hit = rayFrom + rayNormalizedDirection * t; + if ((btDot(n, btCross(a - hit, b - hit)) > ceps) && + (btDot(n, btCross(b - hit, c - hit)) > ceps) && + (btDot(n, btCross(c - hit, a - hit)) > ceps)) { - return(t); + return (t); } } } - return(-1); + return (-1); } // -void btSoftBody::pointersToIndices() +void btSoftBody::pointersToIndices() { -#define PTR2IDX(_p_,_b_) reinterpret_cast((_p_)-(_b_)) - btSoftBody::Node* base=m_nodes.size() ? &m_nodes[0] : 0; - int i,ni; +#define PTR2IDX(_p_, _b_) reinterpret_cast((_p_) - (_b_)) + btSoftBody::Node* base = m_nodes.size() ? &m_nodes[0] : 0; + int i, ni; - for(i=0,ni=m_nodes.size();idata=*(void**)&i; + m_nodes[i].m_leaf->data = *(void**)&i; } } - for(i=0,ni=m_links.size();idata=*(void**)&i; + m_faces[i].m_leaf->data = *(void**)&i; } } - for(i=0,ni=m_anchors.size();idata=&m_nodes[i]; + m_nodes[i].m_leaf->data = &m_nodes[i]; } } - for(i=0,ni=m_links.size();idata=&m_faces[i]; + m_faces[i].m_leaf->data = &m_faces[i]; } } - for(i=0,ni=m_anchors.size();im_x, - f.m_n[1]->m_x, - f.m_n[2]->m_x, - mint); - if(t>0) + const btScalar t = RayFromToCaster::rayFromToTriangle(rayFrom, rayTo, dir, + f.m_n[0]->m_x, + f.m_n[1]->m_x, + f.m_n[2]->m_x, + mint); + if (t > 0) { ++cnt; - if(!bcountonly) + if (!bcountonly) { - feature=btSoftBody::eFeature::Face; - index=i; - mint=t; + feature = btSoftBody::eFeature::Face; + index = i; + mint = t; } } } } else - {/* Use dbvt */ - RayFromToCaster collider(rayFrom,rayTo,mint); + { /* Use dbvt */ + RayFromToCaster collider(rayFrom, rayTo, mint); - btDbvt::rayTest(m_fdbvt.m_root,rayFrom,rayTo,collider); - if(collider.m_face) + btDbvt::rayTest(m_fdbvt.m_root, rayFrom, rayTo, collider); + if (collider.m_face) { - mint=collider.m_mint; - feature=btSoftBody::eFeature::Face; - index=(int)(collider.m_face-&m_faces[0]); - cnt=1; + mint = collider.m_mint; + feature = btSoftBody::eFeature::Face; + index = (int)(collider.m_face - &m_faces[0]); + cnt = 1; } } - for (int i=0;im_x; + btVector3 v1 = tet.m_n[index1]->m_x; + btVector3 v2 = tet.m_n[index2]->m_x; - int index0=tetfaces[f][0]; - int index1=tetfaces[f][1]; - int index2=tetfaces[f][2]; - btVector3 v0=tet.m_n[index0]->m_x; - btVector3 v1=tet.m_n[index1]->m_x; - btVector3 v2=tet.m_n[index2]->m_x; - - - const btScalar t=RayFromToCaster::rayFromToTriangle( rayFrom,rayTo,dir, - v0,v1,v2, - mint); - if(t>0) + const btScalar t = RayFromToCaster::rayFromToTriangle(rayFrom, rayTo, dir, + v0, v1, v2, + mint); + if (t > 0) { ++cnt; - if(!bcountonly) + if (!bcountonly) { - feature=btSoftBody::eFeature::Tetra; - index=i; - mint=t; + feature = btSoftBody::eFeature::Tetra; + index = i; + mint = t; } } } } - return(cnt); + return (cnt); } // -void btSoftBody::initializeFaceTree() +void btSoftBody::initializeFaceTree() { m_fdbvt.clear(); - for(int i=0;igetCollisionShape(); -// const btRigidBody *tmpRigid = btRigidBody::upcast(colObjWrap->getCollisionObject()); + const btCollisionShape* shp = colObjWrap->getCollisionShape(); + // const btRigidBody *tmpRigid = btRigidBody::upcast(colObjWrap->getCollisionObject()); //const btTransform &wtr = tmpRigid ? tmpRigid->getWorldTransform() : colObjWrap->getWorldTransform(); - const btTransform &wtr = colObjWrap->getWorldTransform(); + const btTransform& wtr = colObjWrap->getWorldTransform(); //todo: check which transform is needed here - btScalar dst = - m_worldInfo->m_sparsesdf.Evaluate( + btScalar dst = + m_worldInfo->m_sparsesdf.Evaluate( wtr.invXform(x), shp, nrm, margin); - if(dst<0) + if (dst < 0) { cti.m_colObj = colObjWrap->getCollisionObject(); - cti.m_normal = wtr.getBasis()*nrm; - cti.m_offset = -btDot( cti.m_normal, x - cti.m_normal * dst ); - return(true); + cti.m_normal = wtr.getBasis() * nrm; + cti.m_offset = -btDot(cti.m_normal, x - cti.m_normal * dst); + return (true); } - return(false); + return (false); } // -void btSoftBody::updateNormals() +void btSoftBody::updateNormals() { + const btVector3 zv(0, 0, 0); + int i, ni; - const btVector3 zv(0,0,0); - int i,ni; - - for(i=0,ni=m_nodes.size();im_x-f.m_n[0]->m_x, - f.m_n[2]->m_x-f.m_n[0]->m_x); - f.m_normal=n.normalized(); - f.m_n[0]->m_n+=n; - f.m_n[1]->m_n+=n; - f.m_n[2]->m_n+=n; + btSoftBody::Face& f = m_faces[i]; + const btVector3 n = btCross(f.m_n[1]->m_x - f.m_n[0]->m_x, + f.m_n[2]->m_x - f.m_n[0]->m_x); + f.m_normal = n.normalized(); + f.m_n[0]->m_n += n; + f.m_n[1]->m_n += n; + f.m_n[2]->m_n += n; } - for(i=0,ni=m_nodes.size();iSIMD_EPSILON) + if (len > SIMD_EPSILON) m_nodes[i].m_n /= len; } } // -void btSoftBody::updateBounds() +void btSoftBody::updateBounds() { /*if( m_acceleratedSoftBody ) { @@ -2317,258 +2333,259 @@ void btSoftBody::updateBounds() m_bounds[1] = btVector3(1000, 1000, 1000); } else {*/ - if(m_ndbvt.m_root) + if (m_ndbvt.m_root) + { + const btVector3& mins = m_ndbvt.m_root->volume.Mins(); + const btVector3& maxs = m_ndbvt.m_root->volume.Maxs(); + const btScalar csm = getCollisionShape()->getMargin(); + const btVector3 mrg = btVector3(csm, + csm, + csm) * + 1; // ??? to investigate... + m_bounds[0] = mins - mrg; + m_bounds[1] = maxs + mrg; + if (0 != getBroadphaseHandle()) { - const btVector3& mins=m_ndbvt.m_root->volume.Mins(); - const btVector3& maxs=m_ndbvt.m_root->volume.Maxs(); - const btScalar csm=getCollisionShape()->getMargin(); - const btVector3 mrg=btVector3( csm, - csm, - csm)*1; // ??? to investigate... - m_bounds[0]=mins-mrg; - m_bounds[1]=maxs+mrg; - if(0!=getBroadphaseHandle()) - { - m_worldInfo->m_broadphase->setAabb( getBroadphaseHandle(), - m_bounds[0], - m_bounds[1], - m_worldInfo->m_dispatcher); - } + m_worldInfo->m_broadphase->setAabb(getBroadphaseHandle(), + m_bounds[0], + m_bounds[1], + m_worldInfo->m_dispatcher); } - else - { - m_bounds[0]= - m_bounds[1]=btVector3(0,0,0); - } + } + else + { + m_bounds[0] = + m_bounds[1] = btVector3(0, 0, 0); + } //} } - // -void btSoftBody::updatePose() +void btSoftBody::updatePose() { - if(m_pose.m_bframe) + if (m_pose.m_bframe) { - btSoftBody::Pose& pose=m_pose; - const btVector3 com=evaluateCom(); - /* Com */ - pose.m_com = com; - /* Rotation */ - btMatrix3x3 Apq; - const btScalar eps=SIMD_EPSILON; - Apq[0]=Apq[1]=Apq[2]=btVector3(0,0,0); - Apq[0].setX(eps);Apq[1].setY(eps*2);Apq[2].setZ(eps*3); - for(int i=0,ni=m_nodes.size();i1) + btMatrix3x3 r, s; + PolarDecompose(Apq, r, s); + pose.m_rot = r; + pose.m_scl = pose.m_aqq * r.transpose() * Apq; + if (m_cfg.maxvolume > 1) { - const btScalar idet=Clamp( 1/pose.m_scl.determinant(), - 1,m_cfg.maxvolume); - pose.m_scl=Mul(pose.m_scl,idet); + const btScalar idet = Clamp(1 / pose.m_scl.determinant(), + 1, m_cfg.maxvolume); + pose.m_scl = Mul(pose.m_scl, idet); } - } } // -void btSoftBody::updateArea(bool averageArea) +void btSoftBody::updateArea(bool averageArea) { - int i,ni; + int i, ni; - /* Face area */ - for(i=0,ni=m_faces.size();im_x,f.m_n[1]->m_x,f.m_n[2]->m_x); + Face& f = m_faces[i]; + f.m_ra = AreaOf(f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x); } - - /* Node area */ + + /* Node area */ if (averageArea) { - btAlignedObjectArray counts; - counts.resize(m_nodes.size(),0); - for(i=0,ni=m_nodes.size();i counts; + counts.resize(m_nodes.size(), 0); + for (i = 0, ni = m_nodes.size(); i < ni; ++i) { - m_nodes[i].m_area = 0; + m_nodes[i].m_area = 0; } - for(i=0,ni=m_faces.size();im_area+=btFabs(f.m_ra); + f.m_n[j]->m_area += btFabs(f.m_ra); } } - for(i=0,ni=m_nodes.size();i0) - m_nodes[i].m_area/=(btScalar)counts[i]; + if (counts[i] > 0) + m_nodes[i].m_area /= (btScalar)counts[i]; else - m_nodes[i].m_area=0; + m_nodes[i].m_area = 0; } } else { // initialize node area as zero - for(i=0,ni=m_nodes.size();im_area += f.m_ra; } } - for(i=0,ni=m_nodes.size();im_im+l.m_n[1]->m_im)/m.m_kLST; + Link& l = m_links[i]; + Material& m = *l.m_material; + l.m_c0 = (l.m_n[0]->m_im + l.m_n[1]->m_im) / m.m_kLST; } } -void btSoftBody::updateConstants() +void btSoftBody::updateConstants() { resetLinkRestLengths(); updateLinkConstants(); updateArea(); } - - // -void btSoftBody::initializeClusters() +void btSoftBody::initializeClusters() { int i; - for( i=0;im_im==0) + if (c.m_nodes[j]->m_im == 0) { c.m_containsAnchor = true; - c.m_masses[j] = BT_LARGE_FLOAT; - } else - { - c.m_masses[j] = btScalar(1.)/c.m_nodes[j]->m_im; + c.m_masses[j] = BT_LARGE_FLOAT; } - c.m_imass += c.m_masses[j]; + else + { + c.m_masses[j] = btScalar(1.) / c.m_nodes[j]->m_im; + } + c.m_imass += c.m_masses[j]; } - c.m_imass = btScalar(1.)/c.m_imass; - c.m_com = btSoftBody::clusterCom(&c); - c.m_lv = btVector3(0,0,0); - c.m_av = btVector3(0,0,0); - c.m_leaf = 0; - /* Inertia */ - btMatrix3x3& ii=c.m_locii; - ii[0]=ii[1]=ii[2]=btVector3(0,0,0); + c.m_imass = btScalar(1.) / c.m_imass; + c.m_com = btSoftBody::clusterCom(&c); + c.m_lv = btVector3(0, 0, 0); + c.m_av = btVector3(0, 0, 0); + c.m_leaf = 0; + /* Inertia */ + btMatrix3x3& ii = c.m_locii; + ii[0] = ii[1] = ii[2] = btVector3(0, 0, 0); { - int i,ni; + int i, ni; - for(i=0,ni=c.m_nodes.size();im_x-c.m_com; - const btVector3 q=k*k; - const btScalar m=c.m_masses[i]; - ii[0][0] += m*(q[1]+q[2]); - ii[1][1] += m*(q[0]+q[2]); - ii[2][2] += m*(q[0]+q[1]); - ii[0][1] -= m*k[0]*k[1]; - ii[0][2] -= m*k[0]*k[2]; - ii[1][2] -= m*k[1]*k[2]; + const btVector3 k = c.m_nodes[i]->m_x - c.m_com; + const btVector3 q = k * k; + const btScalar m = c.m_masses[i]; + ii[0][0] += m * (q[1] + q[2]); + ii[1][1] += m * (q[0] + q[2]); + ii[2][2] += m * (q[0] + q[1]); + ii[0][1] -= m * k[0] * k[1]; + ii[0][2] -= m * k[0] * k[2]; + ii[1][2] -= m * k[1] * k[2]; } } - ii[1][0]=ii[0][1]; - ii[2][0]=ii[0][2]; - ii[2][1]=ii[1][2]; - + ii[1][0] = ii[0][1]; + ii[2][0] = ii[0][2]; + ii[2][1] = ii[1][2]; + ii = ii.inverse(); - /* Frame */ + /* Frame */ c.m_framexform.setIdentity(); c.m_framexform.setOrigin(c.m_com); c.m_framerefs.resize(c.m_nodes.size()); { int i; - for(i=0;im_x-c.m_com; + c.m_framerefs[i] = c.m_nodes[i]->m_x - c.m_com; } } } } // -void btSoftBody::updateClusters() +void btSoftBody::updateClusters() { BT_PROFILE("UpdateClusters"); int i; - for(i=0;im_x-c.m_com; - const btVector3& b=c.m_framerefs[i]; - m[0]+=a[0]*b;m[1]+=a[1]*b;m[2]+=a[2]*b; + const btVector3 a = c.m_nodes[i]->m_x - c.m_com; + const btVector3& b = c.m_framerefs[i]; + m[0] += a[0] * b; + m[1] += a[1] * b; + m[2] += a[2] * b; } - PolarDecompose(m,r,s); + PolarDecompose(m, r, s); c.m_framexform.setOrigin(c.m_com); - c.m_framexform.setBasis(r); - /* Inertia */ -#if 1/* Constant */ - c.m_invwi=c.m_framexform.getBasis()*c.m_locii*c.m_framexform.getBasis().transpose(); + c.m_framexform.setBasis(r); + /* Inertia */ +#if 1 /* Constant */ + c.m_invwi = c.m_framexform.getBasis() * c.m_locii * c.m_framexform.getBasis().transpose(); #else -#if 0/* Sphere */ +#if 0 /* Sphere */ const btScalar rk=(2*c.m_extents.length2())/(5*c.m_imass); const btVector3 inertia(rk,rk,rk); const btVector3 iin(btFabs(inertia[0])>SIMD_EPSILON?1/inertia[0]:0, @@ -2576,186 +2593,181 @@ void btSoftBody::updateClusters() btFabs(inertia[2])>SIMD_EPSILON?1/inertia[2]:0); c.m_invwi=c.m_xform.getBasis().scaled(iin)*c.m_xform.getBasis().transpose(); -#else/* Actual */ - c.m_invwi[0]=c.m_invwi[1]=c.m_invwi[2]=btVector3(0,0,0); - for(int i=0;im_x-c.m_com; - const btVector3 q=k*k; - const btScalar m=1/c.m_nodes[i]->m_im; - c.m_invwi[0][0] += m*(q[1]+q[2]); - c.m_invwi[1][1] += m*(q[0]+q[2]); - c.m_invwi[2][2] += m*(q[0]+q[1]); - c.m_invwi[0][1] -= m*k[0]*k[1]; - c.m_invwi[0][2] -= m*k[0]*k[2]; - c.m_invwi[1][2] -= m*k[1]*k[2]; + const btVector3 k = c.m_nodes[i]->m_x - c.m_com; + const btVector3 q = k * k; + const btScalar m = 1 / c.m_nodes[i]->m_im; + c.m_invwi[0][0] += m * (q[1] + q[2]); + c.m_invwi[1][1] += m * (q[0] + q[2]); + c.m_invwi[2][2] += m * (q[0] + q[1]); + c.m_invwi[0][1] -= m * k[0] * k[1]; + c.m_invwi[0][2] -= m * k[0] * k[2]; + c.m_invwi[1][2] -= m * k[1] * k[2]; } - c.m_invwi[1][0]=c.m_invwi[0][1]; - c.m_invwi[2][0]=c.m_invwi[0][2]; - c.m_invwi[2][1]=c.m_invwi[1][2]; - c.m_invwi=c.m_invwi.inverse(); + c.m_invwi[1][0] = c.m_invwi[0][1]; + c.m_invwi[2][0] = c.m_invwi[0][2]; + c.m_invwi[2][1] = c.m_invwi[1][2]; + c.m_invwi = c.m_invwi.inverse(); #endif #endif - /* Velocities */ - c.m_lv=btVector3(0,0,0); - c.m_av=btVector3(0,0,0); + /* Velocities */ + c.m_lv = btVector3(0, 0, 0); + c.m_av = btVector3(0, 0, 0); { int i; - for(i=0;im_v*c.m_masses[i]; - c.m_lv += v; - c.m_av += btCross(c.m_nodes[i]->m_x-c.m_com,v); + const btVector3 v = c.m_nodes[i]->m_v * c.m_masses[i]; + c.m_lv += v; + c.m_av += btCross(c.m_nodes[i]->m_x - c.m_com, v); } } - c.m_lv=c.m_imass*c.m_lv*(1-c.m_ldamping); - c.m_av=c.m_invwi*c.m_av*(1-c.m_adamping); - c.m_vimpulses[0] = - c.m_vimpulses[1] = btVector3(0,0,0); - c.m_dimpulses[0] = - c.m_dimpulses[1] = btVector3(0,0,0); - c.m_nvimpulses = 0; - c.m_ndimpulses = 0; - /* Matching */ - if(c.m_matching>0) + c.m_lv = c.m_imass * c.m_lv * (1 - c.m_ldamping); + c.m_av = c.m_invwi * c.m_av * (1 - c.m_adamping); + c.m_vimpulses[0] = + c.m_vimpulses[1] = btVector3(0, 0, 0); + c.m_dimpulses[0] = + c.m_dimpulses[1] = btVector3(0, 0, 0); + c.m_nvimpulses = 0; + c.m_ndimpulses = 0; + /* Matching */ + if (c.m_matching > 0) { - for(int j=0;jm_x; - btVector3 mx=mi; - for(int j=1;jm_x; + btVector3 mx = mi; + for (int j = 1; j < n; ++j) { mi.setMin(c.m_nodes[j]->m_x); mx.setMax(c.m_nodes[j]->m_x); - } - ATTRIBUTE_ALIGNED16(btDbvtVolume) bounds=btDbvtVolume::FromMM(mi,mx); - if(c.m_leaf) - m_cdbvt.update(c.m_leaf,bounds,c.m_lv*m_sst.sdt*3,m_sst.radmrg); + } + ATTRIBUTE_ALIGNED16(btDbvtVolume) + bounds = btDbvtVolume::FromMM(mi, mx); + if (c.m_leaf) + m_cdbvt.update(c.m_leaf, bounds, c.m_lv * m_sst.sdt * 3, m_sst.radmrg); else - c.m_leaf=m_cdbvt.insert(bounds,&c); + c.m_leaf = m_cdbvt.insert(bounds, &c); } } } - - } - - - // -void btSoftBody::cleanupClusters() +void btSoftBody::cleanupClusters() { - for(int i=0;iTerminate(m_sst.sdt); - if(m_joints[i]->m_delete) + if (m_joints[i]->m_delete) { btAlignedFree(m_joints[i]); m_joints.remove(m_joints[i--]); - } + } } } // -void btSoftBody::prepareClusters(int iterations) +void btSoftBody::prepareClusters(int iterations) { - for(int i=0;iPrepare(m_sst.sdt,iterations); + m_joints[i]->Prepare(m_sst.sdt, iterations); } } - // -void btSoftBody::solveClusters(btScalar sor) +void btSoftBody::solveClusters(btScalar sor) { - for(int i=0,ni=m_joints.size();iSolve(m_sst.sdt,sor); + m_joints[i]->Solve(m_sst.sdt, sor); } } // -void btSoftBody::applyClusters(bool drift) +void btSoftBody::applyClusters(bool drift) { BT_PROFILE("ApplyClusters"); -// const btScalar f0=m_sst.sdt; + // const btScalar f0=m_sst.sdt; //const btScalar f1=f0/2; btAlignedObjectArray deltas; btAlignedObjectArray weights; - deltas.resize(m_nodes.size(),btVector3(0,0,0)); - weights.resize(m_nodes.size(),0); + deltas.resize(m_nodes.size(), btVector3(0, 0, 0)); + weights.resize(m_nodes.size(), 0); int i; - if(drift) + if (drift) { - for(i=0;im_x; - const btScalar q=c.m_masses[j]; - deltas[idx] += (v+btCross(w,x-c.m_com))*q; - weights[idx] += q; + const int idx = int(c.m_nodes[j] - &m_nodes[0]); + const btVector3& x = c.m_nodes[j]->m_x; + const btScalar q = c.m_masses[j]; + deltas[idx] += (v + btCross(w, x - c.m_com)) * q; + weights[idx] += q; } } } - for(i=0;i0) + if (weights[i] > 0) { - m_nodes[i].m_x+=deltas[i]/weights[i]; + m_nodes[i].m_x += deltas[i] / weights[i]; } } } // -void btSoftBody::dampClusters() +void btSoftBody::dampClusters() { int i; - for(i=0;i0) + Cluster& c = *m_clusters[i]; + if (c.m_ndamping > 0) { - for(int j=0;j0) + Node& n = *c.m_nodes[j]; + if (n.m_im > 0) { - const btVector3 vx=c.m_lv+btCross(c.m_av,c.m_nodes[j]->m_q-c.m_com); - if(vx.length2()<=n.m_v.length2()) - { - n.m_v += c.m_ndamping*(vx-n.m_v); - } + const btVector3 vx = c.m_lv + btCross(c.m_av, c.m_nodes[j]->m_q - c.m_com); + if (vx.length2() <= n.m_v.length2()) + { + n.m_v += c.m_ndamping * (vx - n.m_v); + } } } } @@ -2763,710 +2775,696 @@ void btSoftBody::dampClusters() } // -void btSoftBody::Joint::Prepare(btScalar dt,int) +void btSoftBody::Joint::Prepare(btScalar dt, int) { m_bodies[0].activate(); m_bodies[1].activate(); } // -void btSoftBody::LJoint::Prepare(btScalar dt,int iterations) +void btSoftBody::LJoint::Prepare(btScalar dt, int iterations) { - static const btScalar maxdrift=4; - Joint::Prepare(dt,iterations); - m_rpos[0] = m_bodies[0].xform()*m_refs[0]; - m_rpos[1] = m_bodies[1].xform()*m_refs[1]; - m_drift = Clamp(m_rpos[0]-m_rpos[1],maxdrift)*m_erp/dt; - m_rpos[0] -= m_bodies[0].xform().getOrigin(); - m_rpos[1] -= m_bodies[1].xform().getOrigin(); - m_massmatrix = ImpulseMatrix( m_bodies[0].invMass(),m_bodies[0].invWorldInertia(),m_rpos[0], - m_bodies[1].invMass(),m_bodies[1].invWorldInertia(),m_rpos[1]); - if(m_split>0) + static const btScalar maxdrift = 4; + Joint::Prepare(dt, iterations); + m_rpos[0] = m_bodies[0].xform() * m_refs[0]; + m_rpos[1] = m_bodies[1].xform() * m_refs[1]; + m_drift = Clamp(m_rpos[0] - m_rpos[1], maxdrift) * m_erp / dt; + m_rpos[0] -= m_bodies[0].xform().getOrigin(); + m_rpos[1] -= m_bodies[1].xform().getOrigin(); + m_massmatrix = ImpulseMatrix(m_bodies[0].invMass(), m_bodies[0].invWorldInertia(), m_rpos[0], + m_bodies[1].invMass(), m_bodies[1].invWorldInertia(), m_rpos[1]); + if (m_split > 0) { - m_sdrift = m_massmatrix*(m_drift*m_split); - m_drift *= 1-m_split; + m_sdrift = m_massmatrix * (m_drift * m_split); + m_drift *= 1 - m_split; } - m_drift /=(btScalar)iterations; + m_drift /= (btScalar)iterations; } // -void btSoftBody::LJoint::Solve(btScalar dt,btScalar sor) +void btSoftBody::LJoint::Solve(btScalar dt, btScalar sor) { - const btVector3 va=m_bodies[0].velocity(m_rpos[0]); - const btVector3 vb=m_bodies[1].velocity(m_rpos[1]); - const btVector3 vr=va-vb; - btSoftBody::Impulse impulse; - impulse.m_asVelocity = 1; - impulse.m_velocity = m_massmatrix*(m_drift+vr*m_cfm)*sor; - m_bodies[0].applyImpulse(-impulse,m_rpos[0]); - m_bodies[1].applyImpulse( impulse,m_rpos[1]); + const btVector3 va = m_bodies[0].velocity(m_rpos[0]); + const btVector3 vb = m_bodies[1].velocity(m_rpos[1]); + const btVector3 vr = va - vb; + btSoftBody::Impulse impulse; + impulse.m_asVelocity = 1; + impulse.m_velocity = m_massmatrix * (m_drift + vr * m_cfm) * sor; + m_bodies[0].applyImpulse(-impulse, m_rpos[0]); + m_bodies[1].applyImpulse(impulse, m_rpos[1]); } // -void btSoftBody::LJoint::Terminate(btScalar dt) +void btSoftBody::LJoint::Terminate(btScalar dt) { - if(m_split>0) + if (m_split > 0) { - m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]); - m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]); + m_bodies[0].applyDImpulse(-m_sdrift, m_rpos[0]); + m_bodies[1].applyDImpulse(m_sdrift, m_rpos[1]); } } // -void btSoftBody::AJoint::Prepare(btScalar dt,int iterations) +void btSoftBody::AJoint::Prepare(btScalar dt, int iterations) { - static const btScalar maxdrift=SIMD_PI/16; + static const btScalar maxdrift = SIMD_PI / 16; m_icontrol->Prepare(this); - Joint::Prepare(dt,iterations); - m_axis[0] = m_bodies[0].xform().getBasis()*m_refs[0]; - m_axis[1] = m_bodies[1].xform().getBasis()*m_refs[1]; - m_drift = NormalizeAny(btCross(m_axis[1],m_axis[0])); - m_drift *= btMin(maxdrift,btAcos(Clamp(btDot(m_axis[0],m_axis[1]),-1,+1))); - m_drift *= m_erp/dt; - m_massmatrix= AngularImpulseMatrix(m_bodies[0].invWorldInertia(),m_bodies[1].invWorldInertia()); - if(m_split>0) + Joint::Prepare(dt, iterations); + m_axis[0] = m_bodies[0].xform().getBasis() * m_refs[0]; + m_axis[1] = m_bodies[1].xform().getBasis() * m_refs[1]; + m_drift = NormalizeAny(btCross(m_axis[1], m_axis[0])); + m_drift *= btMin(maxdrift, btAcos(Clamp(btDot(m_axis[0], m_axis[1]), -1, +1))); + m_drift *= m_erp / dt; + m_massmatrix = AngularImpulseMatrix(m_bodies[0].invWorldInertia(), m_bodies[1].invWorldInertia()); + if (m_split > 0) { - m_sdrift = m_massmatrix*(m_drift*m_split); - m_drift *= 1-m_split; + m_sdrift = m_massmatrix * (m_drift * m_split); + m_drift *= 1 - m_split; } - m_drift /=(btScalar)iterations; + m_drift /= (btScalar)iterations; } // -void btSoftBody::AJoint::Solve(btScalar dt,btScalar sor) +void btSoftBody::AJoint::Solve(btScalar dt, btScalar sor) { - const btVector3 va=m_bodies[0].angularVelocity(); - const btVector3 vb=m_bodies[1].angularVelocity(); - const btVector3 vr=va-vb; - const btScalar sp=btDot(vr,m_axis[0]); - const btVector3 vc=vr-m_axis[0]*m_icontrol->Speed(this,sp); - btSoftBody::Impulse impulse; - impulse.m_asVelocity = 1; - impulse.m_velocity = m_massmatrix*(m_drift+vc*m_cfm)*sor; + const btVector3 va = m_bodies[0].angularVelocity(); + const btVector3 vb = m_bodies[1].angularVelocity(); + const btVector3 vr = va - vb; + const btScalar sp = btDot(vr, m_axis[0]); + const btVector3 vc = vr - m_axis[0] * m_icontrol->Speed(this, sp); + btSoftBody::Impulse impulse; + impulse.m_asVelocity = 1; + impulse.m_velocity = m_massmatrix * (m_drift + vc * m_cfm) * sor; m_bodies[0].applyAImpulse(-impulse); - m_bodies[1].applyAImpulse( impulse); + m_bodies[1].applyAImpulse(impulse); } // -void btSoftBody::AJoint::Terminate(btScalar dt) +void btSoftBody::AJoint::Terminate(btScalar dt) { - if(m_split>0) + if (m_split > 0) { m_bodies[0].applyDAImpulse(-m_sdrift); - m_bodies[1].applyDAImpulse( m_sdrift); + m_bodies[1].applyDAImpulse(m_sdrift); } } // -void btSoftBody::CJoint::Prepare(btScalar dt,int iterations) +void btSoftBody::CJoint::Prepare(btScalar dt, int iterations) { - Joint::Prepare(dt,iterations); - const bool dodrift=(m_life==0); - m_delete=(++m_life)>m_maxlife; - if(dodrift) + Joint::Prepare(dt, iterations); + const bool dodrift = (m_life == 0); + m_delete = (++m_life) > m_maxlife; + if (dodrift) { - m_drift=m_drift*m_erp/dt; - if(m_split>0) + m_drift = m_drift * m_erp / dt; + if (m_split > 0) { - m_sdrift = m_massmatrix*(m_drift*m_split); - m_drift *= 1-m_split; + m_sdrift = m_massmatrix * (m_drift * m_split); + m_drift *= 1 - m_split; } - m_drift/=(btScalar)iterations; + m_drift /= (btScalar)iterations; } else { - m_drift=m_sdrift=btVector3(0,0,0); + m_drift = m_sdrift = btVector3(0, 0, 0); } } // -void btSoftBody::CJoint::Solve(btScalar dt,btScalar sor) +void btSoftBody::CJoint::Solve(btScalar dt, btScalar sor) { - const btVector3 va=m_bodies[0].velocity(m_rpos[0]); - const btVector3 vb=m_bodies[1].velocity(m_rpos[1]); - const btVector3 vrel=va-vb; - const btScalar rvac=btDot(vrel,m_normal); - btSoftBody::Impulse impulse; - impulse.m_asVelocity = 1; - impulse.m_velocity = m_drift; - if(rvac<0) + const btVector3 va = m_bodies[0].velocity(m_rpos[0]); + const btVector3 vb = m_bodies[1].velocity(m_rpos[1]); + const btVector3 vrel = va - vb; + const btScalar rvac = btDot(vrel, m_normal); + btSoftBody::Impulse impulse; + impulse.m_asVelocity = 1; + impulse.m_velocity = m_drift; + if (rvac < 0) { - const btVector3 iv=m_normal*rvac; - const btVector3 fv=vrel-iv; - impulse.m_velocity += iv+fv*m_friction; + const btVector3 iv = m_normal * rvac; + const btVector3 fv = vrel - iv; + impulse.m_velocity += iv + fv * m_friction; } - impulse.m_velocity=m_massmatrix*impulse.m_velocity*sor; - - if (m_bodies[0].m_soft==m_bodies[1].m_soft) + impulse.m_velocity = m_massmatrix * impulse.m_velocity * sor; + + if (m_bodies[0].m_soft == m_bodies[1].m_soft) { - if ((impulse.m_velocity.getX() ==impulse.m_velocity.getX())&&(impulse.m_velocity.getY() ==impulse.m_velocity.getY())&& - (impulse.m_velocity.getZ() ==impulse.m_velocity.getZ())) + if ((impulse.m_velocity.getX() == impulse.m_velocity.getX()) && (impulse.m_velocity.getY() == impulse.m_velocity.getY()) && + (impulse.m_velocity.getZ() == impulse.m_velocity.getZ())) { if (impulse.m_asVelocity) { - if (impulse.m_velocity.length() m_maxSelfCollisionImpulse) + if (impulse.m_velocity.length() < m_bodies[0].m_soft->m_maxSelfCollisionImpulse) { - - } else + } + else { - m_bodies[0].applyImpulse(-impulse*m_bodies[0].m_soft->m_selfCollisionImpulseFactor,m_rpos[0]); - m_bodies[1].applyImpulse( impulse*m_bodies[0].m_soft->m_selfCollisionImpulseFactor,m_rpos[1]); + m_bodies[0].applyImpulse(-impulse * m_bodies[0].m_soft->m_selfCollisionImpulseFactor, m_rpos[0]); + m_bodies[1].applyImpulse(impulse * m_bodies[0].m_soft->m_selfCollisionImpulseFactor, m_rpos[1]); } } } - } else + } + else { - m_bodies[0].applyImpulse(-impulse,m_rpos[0]); - m_bodies[1].applyImpulse( impulse,m_rpos[1]); + m_bodies[0].applyImpulse(-impulse, m_rpos[0]); + m_bodies[1].applyImpulse(impulse, m_rpos[1]); } } // -void btSoftBody::CJoint::Terminate(btScalar dt) +void btSoftBody::CJoint::Terminate(btScalar dt) { - if(m_split>0) + if (m_split > 0) { - m_bodies[0].applyDImpulse(-m_sdrift,m_rpos[0]); - m_bodies[1].applyDImpulse( m_sdrift,m_rpos[1]); + m_bodies[0].applyDImpulse(-m_sdrift, m_rpos[0]); + m_bodies[1].applyDImpulse(m_sdrift, m_rpos[1]); } } // -void btSoftBody::applyForces() +void btSoftBody::applyForces() { - BT_PROFILE("SoftBody applyForces"); -// const btScalar dt = m_sst.sdt; - const btScalar kLF = m_cfg.kLF; - const btScalar kDG = m_cfg.kDG; - const btScalar kPR = m_cfg.kPR; - const btScalar kVC = m_cfg.kVC; - const bool as_lift = kLF>0; - const bool as_drag = kDG>0; - const bool as_pressure = kPR!=0; - const bool as_volume = kVC>0; - const bool as_aero = as_lift || - as_drag ; + // const btScalar dt = m_sst.sdt; + const btScalar kLF = m_cfg.kLF; + const btScalar kDG = m_cfg.kDG; + const btScalar kPR = m_cfg.kPR; + const btScalar kVC = m_cfg.kVC; + const bool as_lift = kLF > 0; + const bool as_drag = kDG > 0; + const bool as_pressure = kPR != 0; + const bool as_volume = kVC > 0; + const bool as_aero = as_lift || + as_drag; //const bool as_vaero = as_aero && // (m_cfg.aeromodel < btSoftBody::eAeroModel::F_TwoSided); //const bool as_faero = as_aero && // (m_cfg.aeromodel >= btSoftBody::eAeroModel::F_TwoSided); - const bool use_medium = as_aero; - const bool use_volume = as_pressure || - as_volume ; - btScalar volume = 0; - btScalar ivolumetp = 0; - btScalar dvolumetv = 0; - btSoftBody::sMedium medium; - if(use_volume) + const bool use_medium = as_aero; + const bool use_volume = as_pressure || + as_volume; + btScalar volume = 0; + btScalar ivolumetp = 0; + btScalar dvolumetv = 0; + btSoftBody::sMedium medium; + if (use_volume) { - volume = getVolume(); - ivolumetp = 1/btFabs(volume)*kPR; - dvolumetv = (m_pose.m_volume-volume)*kVC; + volume = getVolume(); + ivolumetp = 1 / btFabs(volume) * kPR; + dvolumetv = (m_pose.m_volume - volume) * kVC; } - /* Per vertex forces */ - int i,ni; + /* Per vertex forces */ + int i, ni; - for(i=0,ni=m_nodes.size();i0) + btSoftBody::Node& n = m_nodes[i]; + if (n.m_im > 0) { - if(use_medium) + if (use_medium) { - /* Aerodynamics */ + /* Aerodynamics */ addAeroForceToNode(m_windVelocity, i); } - /* Pressure */ - if(as_pressure) + /* Pressure */ + if (as_pressure) { - n.m_f += n.m_n*(n.m_area*ivolumetp); + n.m_f += n.m_n * (n.m_area * ivolumetp); } - /* Volume */ - if(as_volume) + /* Volume */ + if (as_volume) { - n.m_f += n.m_n*(n.m_area*dvolumetv); + n.m_f += n.m_n * (n.m_area * dvolumetv); } } } - /* Per face forces */ - for(i=0,ni=m_faces.size();im_cfg.kAHR*kst; - const btScalar dt=psb->m_sst.sdt; - for(int i=0,ni=psb->m_anchors.size();im_cfg.kAHR * kst; + const btScalar dt = psb->m_sst.sdt; + for (int i = 0, ni = psb->m_anchors.size(); i < ni; ++i) { - const Anchor& a=psb->m_anchors[i]; - const btTransform& t=a.m_body->getWorldTransform(); - Node& n=*a.m_node; - const btVector3 wa=t*a.m_local; - const btVector3 va=a.m_body->getVelocityInLocalPoint(a.m_c1)*dt; - const btVector3 vb=n.m_x-n.m_q; - const btVector3 vr=(va-vb)+(wa-n.m_x)*kAHR; - const btVector3 impulse=a.m_c0*vr*a.m_influence; - n.m_x+=impulse*a.m_c2; - a.m_body->applyImpulse(-impulse,a.m_c1); + const Anchor& a = psb->m_anchors[i]; + const btTransform& t = a.m_body->getWorldTransform(); + Node& n = *a.m_node; + const btVector3 wa = t * a.m_local; + const btVector3 va = a.m_body->getVelocityInLocalPoint(a.m_c1) * dt; + const btVector3 vb = n.m_x - n.m_q; + const btVector3 vr = (va - vb) + (wa - n.m_x) * kAHR; + const btVector3 impulse = a.m_c0 * vr * a.m_influence; + n.m_x += impulse * a.m_c2; + a.m_body->applyImpulse(-impulse, a.m_c1); } } - // void btSoftBody::PSolve_RContacts(btSoftBody* psb, btScalar kst, btScalar ti) { BT_PROFILE("PSolve_RContacts"); - const btScalar dt = psb->m_sst.sdt; - const btScalar mrg = psb->getCollisionShape()->getMargin(); + const btScalar dt = psb->m_sst.sdt; + const btScalar mrg = psb->getCollisionShape()->getMargin(); btMultiBodyJacobianData jacobianData; - for(int i=0,ni=psb->m_rcontacts.size();im_rcontacts.size(); i < ni; ++i) { - const RContact& c = psb->m_rcontacts[i]; - const sCti& cti = c.m_cti; - if (cti.m_colObj->hasContactResponse()) + const RContact& c = psb->m_rcontacts[i]; + const sCti& cti = c.m_cti; + if (cti.m_colObj->hasContactResponse()) { - btVector3 va(0,0,0); - btRigidBody* rigidCol=0; - btMultiBodyLinkCollider* multibodyLinkCol=0; - btScalar* deltaV; - - if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) - { - rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); - va = rigidCol ? rigidCol->getVelocityInLocalPoint(c.m_c1)*dt : btVector3(0,0,0); - } - else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) - { - multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); - if (multibodyLinkCol) - { - const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; - jacobianData.m_jacobians.resize(ndof); - jacobianData.m_deltaVelocitiesUnitImpulse.resize(ndof); - btScalar* jac=&jacobianData.m_jacobians[0]; - - multibodyLinkCol->m_multiBody->fillContactJacobianMultiDof(multibodyLinkCol->m_link, c.m_node->m_x, cti.m_normal, jac, jacobianData.scratch_r, jacobianData.scratch_v, jacobianData.scratch_m); - deltaV = &jacobianData.m_deltaVelocitiesUnitImpulse[0]; - multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0],deltaV,jacobianData.scratch_r, jacobianData.scratch_v); - - btScalar vel = 0.0; - for (int j = 0; j < ndof ; ++j) { - vel += multibodyLinkCol->m_multiBody->getVelocityVector()[j] * jac[j]; - } - va = cti.m_normal*vel*dt; - } - } - - const btVector3 vb = c.m_node->m_x-c.m_node->m_q; - const btVector3 vr = vb-va; - const btScalar dn = btDot(vr, cti.m_normal); - if(dn<=SIMD_EPSILON) + btVector3 va(0, 0, 0); + btRigidBody* rigidCol = 0; + btMultiBodyLinkCollider* multibodyLinkCol = 0; + btScalar* deltaV; + + if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) { - const btScalar dp = btMin( (btDot(c.m_node->m_x, cti.m_normal) + cti.m_offset), mrg ); - const btVector3 fv = vr - (cti.m_normal * dn); + rigidCol = (btRigidBody*)btRigidBody::upcast(cti.m_colObj); + va = rigidCol ? rigidCol->getVelocityInLocalPoint(c.m_c1) * dt : btVector3(0, 0, 0); + } + else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + { + multibodyLinkCol = (btMultiBodyLinkCollider*)btMultiBodyLinkCollider::upcast(cti.m_colObj); + if (multibodyLinkCol) + { + const int ndof = multibodyLinkCol->m_multiBody->getNumDofs() + 6; + jacobianData.m_jacobians.resize(ndof); + jacobianData.m_deltaVelocitiesUnitImpulse.resize(ndof); + btScalar* jac = &jacobianData.m_jacobians[0]; + + multibodyLinkCol->m_multiBody->fillContactJacobianMultiDof(multibodyLinkCol->m_link, c.m_node->m_x, cti.m_normal, jac, jacobianData.scratch_r, jacobianData.scratch_v, jacobianData.scratch_m); + deltaV = &jacobianData.m_deltaVelocitiesUnitImpulse[0]; + multibodyLinkCol->m_multiBody->calcAccelerationDeltasMultiDof(&jacobianData.m_jacobians[0], deltaV, jacobianData.scratch_r, jacobianData.scratch_v); + + btScalar vel = 0.0; + for (int j = 0; j < ndof; ++j) + { + vel += multibodyLinkCol->m_multiBody->getVelocityVector()[j] * jac[j]; + } + va = cti.m_normal * vel * dt; + } + } + + const btVector3 vb = c.m_node->m_x - c.m_node->m_q; + const btVector3 vr = vb - va; + const btScalar dn = btDot(vr, cti.m_normal); + if (dn <= SIMD_EPSILON) + { + const btScalar dp = btMin((btDot(c.m_node->m_x, cti.m_normal) + cti.m_offset), mrg); + const btVector3 fv = vr - (cti.m_normal * dn); // c0 is the impulse matrix, c3 is 1 - the friction coefficient or 0, c4 is the contact hardness coefficient - const btVector3 impulse = c.m_c0 * ( (vr - (fv * c.m_c3) + (cti.m_normal * (dp * c.m_c4))) * kst ); + const btVector3 impulse = c.m_c0 * ((vr - (fv * c.m_c3) + (cti.m_normal * (dp * c.m_c4))) * kst); c.m_node->m_x -= impulse * c.m_c2; - - if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) - { - if (rigidCol) - rigidCol->applyImpulse(impulse,c.m_c1); - } - else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) - { - if (multibodyLinkCol) - { - double multiplier = 0.5; - multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV,-impulse.length()*multiplier); - } - } + + if (cti.m_colObj->getInternalType() == btCollisionObject::CO_RIGID_BODY) + { + if (rigidCol) + rigidCol->applyImpulse(impulse, c.m_c1); + } + else if (cti.m_colObj->getInternalType() == btCollisionObject::CO_FEATHERSTONE_LINK) + { + if (multibodyLinkCol) + { + double multiplier = 0.5; + multibodyLinkCol->m_multiBody->applyDeltaVeeMultiDof(deltaV, -impulse.length() * multiplier); + } + } } } } } // -void btSoftBody::PSolve_SContacts(btSoftBody* psb,btScalar,btScalar ti) +void btSoftBody::PSolve_SContacts(btSoftBody* psb, btScalar, btScalar ti) { BT_PROFILE("PSolve_SContacts"); - - for(int i=0,ni=psb->m_scontacts.size();im_scontacts.size(); i < ni; ++i) { - const SContact& c=psb->m_scontacts[i]; - const btVector3& nr=c.m_normal; - Node& n=*c.m_node; - Face& f=*c.m_face; - const btVector3 p=BaryEval( f.m_n[0]->m_x, - f.m_n[1]->m_x, - f.m_n[2]->m_x, - c.m_weights); - const btVector3 q=BaryEval( f.m_n[0]->m_q, - f.m_n[1]->m_q, - f.m_n[2]->m_q, - c.m_weights); - const btVector3 vr=(n.m_x-n.m_q)-(p-q); - btVector3 corr(0,0,0); - btScalar dot = btDot(vr,nr); - if(dot<0) + const SContact& c = psb->m_scontacts[i]; + const btVector3& nr = c.m_normal; + Node& n = *c.m_node; + Face& f = *c.m_face; + const btVector3 p = BaryEval(f.m_n[0]->m_x, + f.m_n[1]->m_x, + f.m_n[2]->m_x, + c.m_weights); + const btVector3 q = BaryEval(f.m_n[0]->m_q, + f.m_n[1]->m_q, + f.m_n[2]->m_q, + c.m_weights); + const btVector3 vr = (n.m_x - n.m_q) - (p - q); + btVector3 corr(0, 0, 0); + btScalar dot = btDot(vr, nr); + if (dot < 0) { - const btScalar j=c.m_margin-(btDot(nr,n.m_x)-btDot(nr,p)); - corr+=c.m_normal*j; + const btScalar j = c.m_margin - (btDot(nr, n.m_x) - btDot(nr, p)); + corr += c.m_normal * j; } - corr -= ProjectOnPlane(vr,nr)*c.m_friction; - n.m_x += corr*c.m_cfm[0]; - f.m_n[0]->m_x -= corr*(c.m_cfm[1]*c.m_weights.x()); - f.m_n[1]->m_x -= corr*(c.m_cfm[1]*c.m_weights.y()); - f.m_n[2]->m_x -= corr*(c.m_cfm[1]*c.m_weights.z()); + corr -= ProjectOnPlane(vr, nr) * c.m_friction; + n.m_x += corr * c.m_cfm[0]; + f.m_n[0]->m_x -= corr * (c.m_cfm[1] * c.m_weights.x()); + f.m_n[1]->m_x -= corr * (c.m_cfm[1] * c.m_weights.y()); + f.m_n[2]->m_x -= corr * (c.m_cfm[1] * c.m_weights.z()); } } // -void btSoftBody::PSolve_Links(btSoftBody* psb,btScalar kst,btScalar ti) +void btSoftBody::PSolve_Links(btSoftBody* psb, btScalar kst, btScalar ti) { -BT_PROFILE("PSolve_Links"); - for(int i=0,ni=psb->m_links.size();im_links[i]; - if(l.m_c0>0) + BT_PROFILE("PSolve_Links"); + for (int i = 0, ni = psb->m_links.size(); i < ni; ++i) + { + Link& l = psb->m_links[i]; + if (l.m_c0 > 0) { - Node& a=*l.m_n[0]; - Node& b=*l.m_n[1]; - const btVector3 del=b.m_x-a.m_x; - const btScalar len=del.length2(); - if (l.m_c1+len > SIMD_EPSILON) + Node& a = *l.m_n[0]; + Node& b = *l.m_n[1]; + const btVector3 del = b.m_x - a.m_x; + const btScalar len = del.length2(); + if (l.m_c1 + len > SIMD_EPSILON) { - const btScalar k=((l.m_c1-len)/(l.m_c0*(l.m_c1+len)))*kst; - a.m_x-=del*(k*a.m_im); - b.m_x+=del*(k*b.m_im); + const btScalar k = ((l.m_c1 - len) / (l.m_c0 * (l.m_c1 + len))) * kst; + a.m_x -= del * (k * a.m_im); + b.m_x += del * (k * b.m_im); } } } } // -void btSoftBody::VSolve_Links(btSoftBody* psb,btScalar kst) +void btSoftBody::VSolve_Links(btSoftBody* psb, btScalar kst) { BT_PROFILE("VSolve_Links"); - for(int i=0,ni=psb->m_links.size();im_links[i]; - Node** n=l.m_n; - const btScalar j=-btDot(l.m_c3,n[0]->m_v-n[1]->m_v)*l.m_c2*kst; - n[0]->m_v+= l.m_c3*(j*n[0]->m_im); - n[1]->m_v-= l.m_c3*(j*n[1]->m_im); + for (int i = 0, ni = psb->m_links.size(); i < ni; ++i) + { + Link& l = psb->m_links[i]; + Node** n = l.m_n; + const btScalar j = -btDot(l.m_c3, n[0]->m_v - n[1]->m_v) * l.m_c2 * kst; + n[0]->m_v += l.m_c3 * (j * n[0]->m_im); + n[1]->m_v -= l.m_c3 * (j * n[1]->m_im); } } // -btSoftBody::psolver_t btSoftBody::getSolver(ePSolver::_ solver) +btSoftBody::psolver_t btSoftBody::getSolver(ePSolver::_ solver) { - switch(solver) + switch (solver) { - case ePSolver::Anchors: - return(&btSoftBody::PSolve_Anchors); - case ePSolver::Linear: - return(&btSoftBody::PSolve_Links); - case ePSolver::RContacts: - return(&btSoftBody::PSolve_RContacts); - case ePSolver::SContacts: - return(&btSoftBody::PSolve_SContacts); + case ePSolver::Anchors: + return (&btSoftBody::PSolve_Anchors); + case ePSolver::Linear: + return (&btSoftBody::PSolve_Links); + case ePSolver::RContacts: + return (&btSoftBody::PSolve_RContacts); + case ePSolver::SContacts: + return (&btSoftBody::PSolve_SContacts); default: { } } - return(0); + return (0); } // -btSoftBody::vsolver_t btSoftBody::getSolver(eVSolver::_ solver) +btSoftBody::vsolver_t btSoftBody::getSolver(eVSolver::_ solver) { - switch(solver) + switch (solver) { - case eVSolver::Linear: return(&btSoftBody::VSolve_Links); + case eVSolver::Linear: + return (&btSoftBody::VSolve_Links); default: { } } - return(0); + return (0); } // -void btSoftBody::defaultCollisionHandler(const btCollisionObjectWrapper* pcoWrap) +void btSoftBody::defaultCollisionHandler(const btCollisionObjectWrapper* pcoWrap) { - - switch(m_cfg.collisions&fCollision::RVSmask) + switch (m_cfg.collisions & fCollision::RVSmask) { - case fCollision::SDF_RS: + case fCollision::SDF_RS: { - btSoftColliders::CollideSDF_RS docollide; - btRigidBody* prb1=(btRigidBody*) btRigidBody::upcast(pcoWrap->getCollisionObject()); - btTransform wtr=pcoWrap->getWorldTransform(); + btSoftColliders::CollideSDF_RS docollide; + btRigidBody* prb1 = (btRigidBody*)btRigidBody::upcast(pcoWrap->getCollisionObject()); + btTransform wtr = pcoWrap->getWorldTransform(); - const btTransform ctr=pcoWrap->getWorldTransform(); - const btScalar timemargin=(wtr.getOrigin()-ctr.getOrigin()).length(); - const btScalar basemargin=getCollisionShape()->getMargin(); - btVector3 mins; - btVector3 maxs; - ATTRIBUTE_ALIGNED16(btDbvtVolume) volume; - pcoWrap->getCollisionShape()->getAabb( pcoWrap->getWorldTransform(), - mins, - maxs); - volume=btDbvtVolume::FromMM(mins,maxs); - volume.Expand(btVector3(basemargin,basemargin,basemargin)); - docollide.psb = this; + const btTransform ctr = pcoWrap->getWorldTransform(); + const btScalar timemargin = (wtr.getOrigin() - ctr.getOrigin()).length(); + const btScalar basemargin = getCollisionShape()->getMargin(); + btVector3 mins; + btVector3 maxs; + ATTRIBUTE_ALIGNED16(btDbvtVolume) + volume; + pcoWrap->getCollisionShape()->getAabb(pcoWrap->getWorldTransform(), + mins, + maxs); + volume = btDbvtVolume::FromMM(mins, maxs); + volume.Expand(btVector3(basemargin, basemargin, basemargin)); + docollide.psb = this; docollide.m_colObj1Wrap = pcoWrap; docollide.m_rigidBody = prb1; - docollide.dynmargin = basemargin+timemargin; - docollide.stamargin = basemargin; - m_ndbvt.collideTV(m_ndbvt.m_root,volume,docollide); + docollide.dynmargin = basemargin + timemargin; + docollide.stamargin = basemargin; + m_ndbvt.collideTV(m_ndbvt.m_root, volume, docollide); } break; - case fCollision::CL_RS: + case fCollision::CL_RS: { - btSoftColliders::CollideCL_RS collider; - collider.ProcessColObj(this,pcoWrap); + btSoftColliders::CollideCL_RS collider; + collider.ProcessColObj(this, pcoWrap); } break; } } // -void btSoftBody::defaultCollisionHandler(btSoftBody* psb) +void btSoftBody::defaultCollisionHandler(btSoftBody* psb) { - const int cf=m_cfg.collisions&psb->m_cfg.collisions; - switch(cf&fCollision::SVSmask) + const int cf = m_cfg.collisions & psb->m_cfg.collisions; + switch (cf & fCollision::SVSmask) { - case fCollision::CL_SS: + case fCollision::CL_SS: { - //support self-collision if CL_SELF flag set - if (this!=psb || psb->m_cfg.collisions&fCollision::CL_SELF) + if (this != psb || psb->m_cfg.collisions & fCollision::CL_SELF) { - btSoftColliders::CollideCL_SS docollide; - docollide.ProcessSoftSoft(this,psb); + btSoftColliders::CollideCL_SS docollide; + docollide.ProcessSoftSoft(this, psb); } - } break; - case fCollision::VF_SS: + case fCollision::VF_SS: { //only self-collision for Cluster, not Vertex-Face yet - if (this!=psb) + if (this != psb) { - btSoftColliders::CollideVF_SS docollide; - /* common */ - docollide.mrg= getCollisionShape()->getMargin()+ - psb->getCollisionShape()->getMargin(); - /* psb0 nodes vs psb1 faces */ - docollide.psb[0]=this; - docollide.psb[1]=psb; - docollide.psb[0]->m_ndbvt.collideTT( docollide.psb[0]->m_ndbvt.m_root, - docollide.psb[1]->m_fdbvt.m_root, - docollide); - /* psb1 nodes vs psb0 faces */ - docollide.psb[0]=psb; - docollide.psb[1]=this; - docollide.psb[0]->m_ndbvt.collideTT( docollide.psb[0]->m_ndbvt.m_root, - docollide.psb[1]->m_fdbvt.m_root, - docollide); + btSoftColliders::CollideVF_SS docollide; + /* common */ + docollide.mrg = getCollisionShape()->getMargin() + + psb->getCollisionShape()->getMargin(); + /* psb0 nodes vs psb1 faces */ + docollide.psb[0] = this; + docollide.psb[1] = psb; + docollide.psb[0]->m_ndbvt.collideTT(docollide.psb[0]->m_ndbvt.m_root, + docollide.psb[1]->m_fdbvt.m_root, + docollide); + /* psb1 nodes vs psb0 faces */ + docollide.psb[0] = psb; + docollide.psb[1] = this; + docollide.psb[0]->m_ndbvt.collideTT(docollide.psb[0]->m_ndbvt.m_root, + docollide.psb[1]->m_fdbvt.m_root, + docollide); } } break; - default: + default: { - } } } - - -void btSoftBody::setWindVelocity( const btVector3 &velocity ) +void btSoftBody::setWindVelocity(const btVector3& velocity) { m_windVelocity = velocity; } - const btVector3& btSoftBody::getWindVelocity() { return m_windVelocity; } - - -int btSoftBody::calculateSerializeBufferSize() const +int btSoftBody::calculateSerializeBufferSize() const { int sz = sizeof(btSoftBodyData); return sz; } - ///fills the dataBuffer and returns the struct name (and 0 on failure) -const char* btSoftBody::serialize(void* dataBuffer, class btSerializer* serializer) const +///fills the dataBuffer and returns the struct name (and 0 on failure) +const char* btSoftBody::serialize(void* dataBuffer, class btSerializer* serializer) const { - btSoftBodyData* sbd = (btSoftBodyData*) dataBuffer; + btSoftBodyData* sbd = (btSoftBodyData*)dataBuffer; btCollisionObject::serialize(&sbd->m_collisionObjectData, serializer); - btHashMap m_nodeIndexMap; + btHashMap m_nodeIndexMap; sbd->m_numMaterials = m_materials.size(); - sbd->m_materials = sbd->m_numMaterials? (SoftBodyMaterialData**) serializer->getUniquePointer((void*)&m_materials): 0; + sbd->m_materials = sbd->m_numMaterials ? (SoftBodyMaterialData**)serializer->getUniquePointer((void*)&m_materials) : 0; if (sbd->m_materials) { int sz = sizeof(SoftBodyMaterialData*); int numElem = sbd->m_numMaterials; - btChunk* chunk = serializer->allocate(sz,numElem); + btChunk* chunk = serializer->allocate(sz, numElem); //SoftBodyMaterialData** memPtr = chunk->m_oldPtr; SoftBodyMaterialData** memPtr = (SoftBodyMaterialData**)chunk->m_oldPtr; - for (int i=0;igetUniquePointer((void*)mat) : 0; if (!serializer->findPointer(mat)) { //serialize it here - btChunk* chunk = serializer->allocate(sizeof(SoftBodyMaterialData),1); + btChunk* chunk = serializer->allocate(sizeof(SoftBodyMaterialData), 1); SoftBodyMaterialData* memPtr = (SoftBodyMaterialData*)chunk->m_oldPtr; memPtr->m_flags = mat->m_flags; memPtr->m_angularStiffness = mat->m_kAST; memPtr->m_linearStiffness = mat->m_kLST; memPtr->m_volumeStiffness = mat->m_kVST; - serializer->finalizeChunk(chunk,"SoftBodyMaterialData",BT_SBMATERIAL_CODE,mat); + serializer->finalizeChunk(chunk, "SoftBodyMaterialData", BT_SBMATERIAL_CODE, mat); } } - serializer->finalizeChunk(chunk,"SoftBodyMaterialData",BT_ARRAY_CODE,(void*) &m_materials); + serializer->finalizeChunk(chunk, "SoftBodyMaterialData", BT_ARRAY_CODE, (void*)&m_materials); } - - - sbd->m_numNodes = m_nodes.size(); - sbd->m_nodes = sbd->m_numNodes ? (SoftBodyNodeData*)serializer->getUniquePointer((void*)&m_nodes): 0; + sbd->m_nodes = sbd->m_numNodes ? (SoftBodyNodeData*)serializer->getUniquePointer((void*)&m_nodes) : 0; if (sbd->m_nodes) { int sz = sizeof(SoftBodyNodeData); int numElem = sbd->m_numNodes; - btChunk* chunk = serializer->allocate(sz,numElem); + btChunk* chunk = serializer->allocate(sz, numElem); SoftBodyNodeData* memPtr = (SoftBodyNodeData*)chunk->m_oldPtr; - for (int i=0;im_accumulatedForce); + m_nodes[i].m_f.serializeFloat(memPtr->m_accumulatedForce); memPtr->m_area = m_nodes[i].m_area; memPtr->m_attach = m_nodes[i].m_battach; memPtr->m_inverseMass = m_nodes[i].m_im; - memPtr->m_material = m_nodes[i].m_material? (SoftBodyMaterialData*)serializer->getUniquePointer((void*) m_nodes[i].m_material):0; + memPtr->m_material = m_nodes[i].m_material ? (SoftBodyMaterialData*)serializer->getUniquePointer((void*)m_nodes[i].m_material) : 0; m_nodes[i].m_n.serializeFloat(memPtr->m_normal); m_nodes[i].m_x.serializeFloat(memPtr->m_position); m_nodes[i].m_q.serializeFloat(memPtr->m_previousPosition); m_nodes[i].m_v.serializeFloat(memPtr->m_velocity); - m_nodeIndexMap.insert(&m_nodes[i],i); + m_nodeIndexMap.insert(&m_nodes[i], i); } - serializer->finalizeChunk(chunk,"SoftBodyNodeData",BT_SBNODE_CODE,(void*) &m_nodes); + serializer->finalizeChunk(chunk, "SoftBodyNodeData", BT_SBNODE_CODE, (void*)&m_nodes); } sbd->m_numLinks = m_links.size(); - sbd->m_links = sbd->m_numLinks? (SoftBodyLinkData*) serializer->getUniquePointer((void*)&m_links[0]):0; + sbd->m_links = sbd->m_numLinks ? (SoftBodyLinkData*)serializer->getUniquePointer((void*)&m_links[0]) : 0; if (sbd->m_links) { int sz = sizeof(SoftBodyLinkData); int numElem = sbd->m_numLinks; - btChunk* chunk = serializer->allocate(sz,numElem); + btChunk* chunk = serializer->allocate(sz, numElem); SoftBodyLinkData* memPtr = (SoftBodyLinkData*)chunk->m_oldPtr; - for (int i=0;im_bbending = m_links[i].m_bbending; - memPtr->m_material = m_links[i].m_material? (SoftBodyMaterialData*)serializer->getUniquePointer((void*) m_links[i].m_material):0; - memPtr->m_nodeIndices[0] = m_links[i].m_n[0] ? m_links[i].m_n[0] - &m_nodes[0]: -1; - memPtr->m_nodeIndices[1] = m_links[i].m_n[1] ? m_links[i].m_n[1] - &m_nodes[0]: -1; - btAssert(memPtr->m_nodeIndices[0]m_nodeIndices[1]m_material = m_links[i].m_material ? (SoftBodyMaterialData*)serializer->getUniquePointer((void*)m_links[i].m_material) : 0; + memPtr->m_nodeIndices[0] = m_links[i].m_n[0] ? m_links[i].m_n[0] - &m_nodes[0] : -1; + memPtr->m_nodeIndices[1] = m_links[i].m_n[1] ? m_links[i].m_n[1] - &m_nodes[0] : -1; + btAssert(memPtr->m_nodeIndices[0] < m_nodes.size()); + btAssert(memPtr->m_nodeIndices[1] < m_nodes.size()); memPtr->m_restLength = m_links[i].m_rl; } - serializer->finalizeChunk(chunk,"SoftBodyLinkData",BT_ARRAY_CODE,(void*) &m_links[0]); - + serializer->finalizeChunk(chunk, "SoftBodyLinkData", BT_ARRAY_CODE, (void*)&m_links[0]); } - sbd->m_numFaces = m_faces.size(); - sbd->m_faces = sbd->m_numFaces? (SoftBodyFaceData*) serializer->getUniquePointer((void*)&m_faces[0]):0; + sbd->m_faces = sbd->m_numFaces ? (SoftBodyFaceData*)serializer->getUniquePointer((void*)&m_faces[0]) : 0; if (sbd->m_faces) { int sz = sizeof(SoftBodyFaceData); int numElem = sbd->m_numFaces; - btChunk* chunk = serializer->allocate(sz,numElem); + btChunk* chunk = serializer->allocate(sz, numElem); SoftBodyFaceData* memPtr = (SoftBodyFaceData*)chunk->m_oldPtr; - for (int i=0;im_material = m_faces[i].m_material ? (SoftBodyMaterialData*) serializer->getUniquePointer((void*)m_faces[i].m_material): 0; - m_faces[i].m_normal.serializeFloat( memPtr->m_normal); - for (int j=0;j<3;j++) + memPtr->m_material = m_faces[i].m_material ? (SoftBodyMaterialData*)serializer->getUniquePointer((void*)m_faces[i].m_material) : 0; + m_faces[i].m_normal.serializeFloat(memPtr->m_normal); + for (int j = 0; j < 3; j++) { - memPtr->m_nodeIndices[j] = m_faces[i].m_n[j]? m_faces[i].m_n[j] - &m_nodes[0]: -1; + memPtr->m_nodeIndices[j] = m_faces[i].m_n[j] ? m_faces[i].m_n[j] - &m_nodes[0] : -1; } memPtr->m_restArea = m_faces[i].m_ra; } - serializer->finalizeChunk(chunk,"SoftBodyFaceData",BT_ARRAY_CODE,(void*) &m_faces[0]); + serializer->finalizeChunk(chunk, "SoftBodyFaceData", BT_ARRAY_CODE, (void*)&m_faces[0]); } - sbd->m_numTetrahedra = m_tetras.size(); - sbd->m_tetrahedra = sbd->m_numTetrahedra ? (SoftBodyTetraData*) serializer->getUniquePointer((void*)&m_tetras[0]):0; + sbd->m_tetrahedra = sbd->m_numTetrahedra ? (SoftBodyTetraData*)serializer->getUniquePointer((void*)&m_tetras[0]) : 0; if (sbd->m_tetrahedra) { int sz = sizeof(SoftBodyTetraData); int numElem = sbd->m_numTetrahedra; - btChunk* chunk = serializer->allocate(sz,numElem); + btChunk* chunk = serializer->allocate(sz, numElem); SoftBodyTetraData* memPtr = (SoftBodyTetraData*)chunk->m_oldPtr; - for (int i=0;im_c0[j] ); - memPtr->m_nodeIndices[j] = m_tetras[j].m_n[j]? m_tetras[j].m_n[j]-&m_nodes[0] : -1; + m_tetras[i].m_c0[j].serializeFloat(memPtr->m_c0[j]); + memPtr->m_nodeIndices[j] = m_tetras[j].m_n[j] ? m_tetras[j].m_n[j] - &m_nodes[0] : -1; } memPtr->m_c1 = m_tetras[i].m_c1; memPtr->m_c2 = m_tetras[i].m_c2; - memPtr->m_material = m_tetras[i].m_material ? (SoftBodyMaterialData*)serializer->getUniquePointer((void*) m_tetras[i].m_material): 0; + memPtr->m_material = m_tetras[i].m_material ? (SoftBodyMaterialData*)serializer->getUniquePointer((void*)m_tetras[i].m_material) : 0; memPtr->m_restVolume = m_tetras[i].m_rv; } - serializer->finalizeChunk(chunk,"SoftBodyTetraData",BT_ARRAY_CODE,(void*) &m_tetras[0]); + serializer->finalizeChunk(chunk, "SoftBodyTetraData", BT_ARRAY_CODE, (void*)&m_tetras[0]); } sbd->m_numAnchors = m_anchors.size(); - sbd->m_anchors = sbd->m_numAnchors ? (SoftRigidAnchorData*) serializer->getUniquePointer((void*)&m_anchors[0]):0; + sbd->m_anchors = sbd->m_numAnchors ? (SoftRigidAnchorData*)serializer->getUniquePointer((void*)&m_anchors[0]) : 0; if (sbd->m_anchors) { int sz = sizeof(SoftRigidAnchorData); int numElem = sbd->m_numAnchors; - btChunk* chunk = serializer->allocate(sz,numElem); + btChunk* chunk = serializer->allocate(sz, numElem); SoftRigidAnchorData* memPtr = (SoftRigidAnchorData*)chunk->m_oldPtr; - for (int i=0;im_c0); m_anchors[i].m_c1.serializeFloat(memPtr->m_c1); memPtr->m_c2 = m_anchors[i].m_c2; m_anchors[i].m_local.serializeFloat(memPtr->m_localFrame); - memPtr->m_nodeIndex = m_anchors[i].m_node? m_anchors[i].m_node-&m_nodes[0]: -1; - - memPtr->m_rigidBody = m_anchors[i].m_body? (btRigidBodyData*) serializer->getUniquePointer((void*)m_anchors[i].m_body): 0; + memPtr->m_nodeIndex = m_anchors[i].m_node ? m_anchors[i].m_node - &m_nodes[0] : -1; + + memPtr->m_rigidBody = m_anchors[i].m_body ? (btRigidBodyData*)serializer->getUniquePointer((void*)m_anchors[i].m_body) : 0; btAssert(memPtr->m_nodeIndex < m_nodes.size()); } - serializer->finalizeChunk(chunk,"SoftRigidAnchorData",BT_ARRAY_CODE,(void*) &m_anchors[0]); + serializer->finalizeChunk(chunk, "SoftRigidAnchorData", BT_ARRAY_CODE, (void*)&m_anchors[0]); } - sbd->m_config.m_dynamicFriction = m_cfg.kDF; sbd->m_config.m_baumgarte = m_cfg.kVCF; @@ -3501,64 +3499,63 @@ const char* btSoftBody::serialize(void* dataBuffer, class btSerializer* serializ sbd->m_pose = (SoftBodyPoseData*)serializer->getUniquePointer((void*)&m_pose); int sz = sizeof(SoftBodyPoseData); - btChunk* chunk = serializer->allocate(sz,1); + btChunk* chunk = serializer->allocate(sz, 1); SoftBodyPoseData* memPtr = (SoftBodyPoseData*)chunk->m_oldPtr; - + m_pose.m_aqq.serializeFloat(memPtr->m_aqq); memPtr->m_bframe = m_pose.m_bframe; memPtr->m_bvolume = m_pose.m_bvolume; m_pose.m_com.serializeFloat(memPtr->m_com); - + memPtr->m_numPositions = m_pose.m_pos.size(); - memPtr->m_positions = memPtr->m_numPositions ? (btVector3FloatData*)serializer->getUniquePointer((void*)&m_pose.m_pos[0]): 0; + memPtr->m_positions = memPtr->m_numPositions ? (btVector3FloatData*)serializer->getUniquePointer((void*)&m_pose.m_pos[0]) : 0; if (memPtr->m_numPositions) { int numElem = memPtr->m_numPositions; int sz = sizeof(btVector3Data); - btChunk* chunk = serializer->allocate(sz,numElem); + btChunk* chunk = serializer->allocate(sz, numElem); btVector3FloatData* memPtr = (btVector3FloatData*)chunk->m_oldPtr; - for (int i=0;ifinalizeChunk(chunk,"btVector3FloatData",BT_ARRAY_CODE,(void*)&m_pose.m_pos[0]); + serializer->finalizeChunk(chunk, "btVector3FloatData", BT_ARRAY_CODE, (void*)&m_pose.m_pos[0]); } memPtr->m_restVolume = m_pose.m_volume; m_pose.m_rot.serializeFloat(memPtr->m_rot); m_pose.m_scl.serializeFloat(memPtr->m_scale); memPtr->m_numWeigts = m_pose.m_wgh.size(); - memPtr->m_weights = memPtr->m_numWeigts? (float*) serializer->getUniquePointer((void*) &m_pose.m_wgh[0]) : 0; + memPtr->m_weights = memPtr->m_numWeigts ? (float*)serializer->getUniquePointer((void*)&m_pose.m_wgh[0]) : 0; if (memPtr->m_numWeigts) { - int numElem = memPtr->m_numWeigts; int sz = sizeof(float); - btChunk* chunk = serializer->allocate(sz,numElem); - float* memPtr = (float*) chunk->m_oldPtr; - for (int i=0;iallocate(sz, numElem); + float* memPtr = (float*)chunk->m_oldPtr; + for (int i = 0; i < numElem; i++, memPtr++) { *memPtr = m_pose.m_wgh[i]; } - serializer->finalizeChunk(chunk,"float",BT_ARRAY_CODE,(void*)&m_pose.m_wgh[0]); + serializer->finalizeChunk(chunk, "float", BT_ARRAY_CODE, (void*)&m_pose.m_wgh[0]); } - serializer->finalizeChunk(chunk,"SoftBodyPoseData",BT_ARRAY_CODE,(void*)&m_pose); + serializer->finalizeChunk(chunk, "SoftBodyPoseData", BT_ARRAY_CODE, (void*)&m_pose); } //clusters for convex-cluster collision detection sbd->m_numClusters = m_clusters.size(); - sbd->m_clusters = sbd->m_numClusters? (SoftBodyClusterData*) serializer->getUniquePointer((void*)m_clusters[0]) : 0; + sbd->m_clusters = sbd->m_numClusters ? (SoftBodyClusterData*)serializer->getUniquePointer((void*)m_clusters[0]) : 0; if (sbd->m_numClusters) { int numElem = sbd->m_numClusters; int sz = sizeof(SoftBodyClusterData); - btChunk* chunk = serializer->allocate(sz,numElem); - SoftBodyClusterData* memPtr = (SoftBodyClusterData*) chunk->m_oldPtr; - for (int i=0;iallocate(sz, numElem); + SoftBodyClusterData* memPtr = (SoftBodyClusterData*)chunk->m_oldPtr; + for (int i = 0; i < numElem; i++, memPtr++) { - memPtr->m_adamping= m_clusters[i]->m_adamping; + memPtr->m_adamping = m_clusters[i]->m_adamping; m_clusters[i]->m_av.serializeFloat(memPtr->m_av); memPtr->m_clusterIndex = m_clusters[i]->m_clusterIndex; memPtr->m_collide = m_clusters[i]->m_collide; @@ -3589,69 +3586,64 @@ const char* btSoftBody::serialize(void* dataBuffer, class btSerializer* serializ m_clusters[i]->m_vimpulses[1].serializeFloat(memPtr->m_vimpulses[1]); memPtr->m_ndimpulses = m_clusters[i]->m_ndimpulses; - - - memPtr->m_framerefs = memPtr->m_numFrameRefs? (btVector3FloatData*)serializer->getUniquePointer((void*)&m_clusters[i]->m_framerefs[0]) : 0; + memPtr->m_framerefs = memPtr->m_numFrameRefs ? (btVector3FloatData*)serializer->getUniquePointer((void*)&m_clusters[i]->m_framerefs[0]) : 0; if (memPtr->m_framerefs) { int numElem = memPtr->m_numFrameRefs; int sz = sizeof(btVector3FloatData); - btChunk* chunk = serializer->allocate(sz,numElem); - btVector3FloatData* memPtr = (btVector3FloatData*) chunk->m_oldPtr; - for (int j=0;jallocate(sz, numElem); + btVector3FloatData* memPtr = (btVector3FloatData*)chunk->m_oldPtr; + for (int j = 0; j < numElem; j++, memPtr++) { m_clusters[i]->m_framerefs[j].serializeFloat(*memPtr); } - serializer->finalizeChunk(chunk,"btVector3FloatData",BT_ARRAY_CODE,(void*)&m_clusters[i]->m_framerefs[0]); + serializer->finalizeChunk(chunk, "btVector3FloatData", BT_ARRAY_CODE, (void*)&m_clusters[i]->m_framerefs[0]); } - - memPtr->m_masses = memPtr->m_numMasses ? (float*) serializer->getUniquePointer((void*)&m_clusters[i]->m_masses[0]): 0; + + memPtr->m_masses = memPtr->m_numMasses ? (float*)serializer->getUniquePointer((void*)&m_clusters[i]->m_masses[0]) : 0; if (memPtr->m_masses) { int numElem = memPtr->m_numMasses; int sz = sizeof(float); - btChunk* chunk = serializer->allocate(sz,numElem); - float* memPtr = (float*) chunk->m_oldPtr; - for (int j=0;jallocate(sz, numElem); + float* memPtr = (float*)chunk->m_oldPtr; + for (int j = 0; j < numElem; j++, memPtr++) { *memPtr = m_clusters[i]->m_masses[j]; } - serializer->finalizeChunk(chunk,"float",BT_ARRAY_CODE,(void*)&m_clusters[i]->m_masses[0]); + serializer->finalizeChunk(chunk, "float", BT_ARRAY_CODE, (void*)&m_clusters[i]->m_masses[0]); } - memPtr->m_nodeIndices = memPtr->m_numNodes ? (int*) serializer->getUniquePointer((void*) &m_clusters[i]->m_nodes) : 0; - if (memPtr->m_nodeIndices ) + memPtr->m_nodeIndices = memPtr->m_numNodes ? (int*)serializer->getUniquePointer((void*)&m_clusters[i]->m_nodes) : 0; + if (memPtr->m_nodeIndices) { int numElem = memPtr->m_numMasses; int sz = sizeof(int); - btChunk* chunk = serializer->allocate(sz,numElem); - int* memPtr = (int*) chunk->m_oldPtr; - for (int j=0;jallocate(sz, numElem); + int* memPtr = (int*)chunk->m_oldPtr; + for (int j = 0; j < numElem; j++, memPtr++) { int* indexPtr = m_nodeIndexMap.find(m_clusters[i]->m_nodes[j]); btAssert(indexPtr); *memPtr = *indexPtr; } - serializer->finalizeChunk(chunk,"int",BT_ARRAY_CODE,(void*)&m_clusters[i]->m_nodes); + serializer->finalizeChunk(chunk, "int", BT_ARRAY_CODE, (void*)&m_clusters[i]->m_nodes); } } - serializer->finalizeChunk(chunk,"SoftBodyClusterData",BT_ARRAY_CODE,(void*)m_clusters[0]); - + serializer->finalizeChunk(chunk, "SoftBodyClusterData", BT_ARRAY_CODE, (void*)m_clusters[0]); } - - sbd->m_numJoints = m_joints.size(); - sbd->m_joints = m_joints.size()? (btSoftBodyJointData*) serializer->getUniquePointer((void*)&m_joints[0]) : 0; + sbd->m_joints = m_joints.size() ? (btSoftBodyJointData*)serializer->getUniquePointer((void*)&m_joints[0]) : 0; if (sbd->m_joints) { int sz = sizeof(btSoftBodyJointData); int numElem = m_joints.size(); - btChunk* chunk = serializer->allocate(sz,numElem); + btChunk* chunk = serializer->allocate(sz, numElem); btSoftBodyJointData* memPtr = (btSoftBodyJointData*)chunk->m_oldPtr; - for (int i=0;im_jointType = (int)m_joints[i]->Type(); m_joints[i]->m_refs[0].serializeFloat(memPtr->m_refs[0]); @@ -3660,8 +3652,8 @@ const char* btSoftBody::serialize(void* dataBuffer, class btSerializer* serializ memPtr->m_erp = float(m_joints[i]->m_erp); memPtr->m_split = float(m_joints[i]->m_split); memPtr->m_delete = m_joints[i]->m_delete; - - for (int j=0;j<4;j++) + + for (int j = 0; j < 4; j++) { memPtr->m_relPosition[0].m_floats[j] = 0.f; memPtr->m_relPosition[1].m_floats[j] = 0.f; @@ -3700,10 +3692,8 @@ const char* btSoftBody::serialize(void* dataBuffer, class btSerializer* serializ memPtr->m_bodyB = serializer->getUniquePointer((void*)m_joints[i]->m_bodies[1].m_rigid); } } - serializer->finalizeChunk(chunk,"btSoftBodyJointData",BT_ARRAY_CODE,(void*) &m_joints[0]); + serializer->finalizeChunk(chunk, "btSoftBodyJointData", BT_ARRAY_CODE, (void*)&m_joints[0]); } - return btSoftBodyDataName; } - diff --git a/src/BulletSoftBody/btSoftBody.h b/src/BulletSoftBody/btSoftBody.h index ada0dfd1a..9b35b799d 100644 --- a/src/BulletSoftBody/btSoftBody.h +++ b/src/BulletSoftBody/btSoftBody.h @@ -31,862 +31,890 @@ subject to the following restrictions: //#define btRigidBodyData btRigidBodyDoubleData //#define btRigidBodyDataName "btRigidBodyDoubleData" //#else -#define btSoftBodyData btSoftBodyFloatData -#define btSoftBodyDataName "btSoftBodyFloatData" +#define btSoftBodyData btSoftBodyFloatData +#define btSoftBodyDataName "btSoftBodyFloatData" //#endif //BT_USE_DOUBLE_PRECISION class btBroadphaseInterface; class btDispatcher; class btSoftBodySolver; -/* btSoftBodyWorldInfo */ -struct btSoftBodyWorldInfo +/* btSoftBodyWorldInfo */ +struct btSoftBodyWorldInfo { - btScalar air_density; - btScalar water_density; - btScalar water_offset; - btScalar m_maxDisplacement; - btVector3 water_normal; - btBroadphaseInterface* m_broadphase; - btDispatcher* m_dispatcher; - btVector3 m_gravity; - btSparseSdf<3> m_sparsesdf; + btScalar air_density; + btScalar water_density; + btScalar water_offset; + btScalar m_maxDisplacement; + btVector3 water_normal; + btBroadphaseInterface* m_broadphase; + btDispatcher* m_dispatcher; + btVector3 m_gravity; + btSparseSdf<3> m_sparsesdf; btSoftBodyWorldInfo() - :air_density((btScalar)1.2), - water_density(0), - water_offset(0), - m_maxDisplacement(1000.f),//avoid soft body from 'exploding' so use some upper threshold of maximum motion that a node can travel per frame - water_normal(0,0,0), - m_broadphase(0), - m_dispatcher(0), - m_gravity(0,-10,0) + : air_density((btScalar)1.2), + water_density(0), + water_offset(0), + m_maxDisplacement(1000.f), //avoid soft body from 'exploding' so use some upper threshold of maximum motion that a node can travel per frame + water_normal(0, 0, 0), + m_broadphase(0), + m_dispatcher(0), + m_gravity(0, -10, 0) { } -}; +}; - -///The btSoftBody is an class to simulate cloth and volumetric soft bodies. +///The btSoftBody is an class to simulate cloth and volumetric soft bodies. ///There is two-way interaction between btSoftBody and btRigidBody/btCollisionObject. -class btSoftBody : public btCollisionObject +class btSoftBody : public btCollisionObject { public: btAlignedObjectArray m_collisionDisabledObjects; // The solver object that handles this soft body - btSoftBodySolver *m_softBodySolver; + btSoftBodySolver* m_softBodySolver; // // Enumerations // - ///eAeroModel - struct eAeroModel { enum _ { - V_Point, ///Vertex normals are oriented toward velocity - V_TwoSided, ///Vertex normals are flipped to match velocity - V_TwoSidedLiftDrag, ///Vertex normals are flipped to match velocity and lift and drag forces are applied - V_OneSided, ///Vertex normals are taken as it is - F_TwoSided, ///Face normals are flipped to match velocity - F_TwoSidedLiftDrag, ///Face normals are flipped to match velocity and lift and drag forces are applied - F_OneSided, ///Face normals are taken as it is - END - };}; + ///eAeroModel + struct eAeroModel + { + enum _ + { + V_Point, ///Vertex normals are oriented toward velocity + V_TwoSided, ///Vertex normals are flipped to match velocity + V_TwoSidedLiftDrag, ///Vertex normals are flipped to match velocity and lift and drag forces are applied + V_OneSided, ///Vertex normals are taken as it is + F_TwoSided, ///Face normals are flipped to match velocity + F_TwoSidedLiftDrag, ///Face normals are flipped to match velocity and lift and drag forces are applied + F_OneSided, ///Face normals are taken as it is + END + }; + }; ///eVSolver : velocities solvers - struct eVSolver { enum _ { - Linear, ///Linear solver - END - };}; + struct eVSolver + { + enum _ + { + Linear, ///Linear solver + END + }; + }; ///ePSolver : positions solvers - struct ePSolver { enum _ { - Linear, ///Linear solver - Anchors, ///Anchor solver - RContacts, ///Rigid contacts solver - SContacts, ///Soft contacts solver - END - };}; + struct ePSolver + { + enum _ + { + Linear, ///Linear solver + Anchors, ///Anchor solver + RContacts, ///Rigid contacts solver + SContacts, ///Soft contacts solver + END + }; + }; ///eSolverPresets - struct eSolverPresets { enum _ { - Positions, - Velocities, - Default = Positions, - END - };}; + struct eSolverPresets + { + enum _ + { + Positions, + Velocities, + Default = Positions, + END + }; + }; ///eFeature - struct eFeature { enum _ { - None, - Node, - Link, - Face, - Tetra, - END - };}; + struct eFeature + { + enum _ + { + None, + Node, + Link, + Face, + Tetra, + END + }; + }; - typedef btAlignedObjectArray tVSolverArray; - typedef btAlignedObjectArray tPSolverArray; + typedef btAlignedObjectArray tVSolverArray; + typedef btAlignedObjectArray tPSolverArray; // // Flags // ///fCollision - struct fCollision { enum _ { - RVSmask = 0x000f, ///Rigid versus soft mask - SDF_RS = 0x0001, ///SDF based rigid vs soft - CL_RS = 0x0002, ///Cluster vs convex rigid vs soft + struct fCollision + { + enum _ + { + RVSmask = 0x000f, ///Rigid versus soft mask + SDF_RS = 0x0001, ///SDF based rigid vs soft + CL_RS = 0x0002, ///Cluster vs convex rigid vs soft - SVSmask = 0x0030, ///Rigid versus soft mask - VF_SS = 0x0010, ///Vertex vs face soft vs soft handling - CL_SS = 0x0020, ///Cluster vs cluster soft vs soft handling - CL_SELF = 0x0040, ///Cluster soft body self collision - /* presets */ - Default = SDF_RS, - END - };}; + SVSmask = 0x0030, ///Rigid versus soft mask + VF_SS = 0x0010, ///Vertex vs face soft vs soft handling + CL_SS = 0x0020, ///Cluster vs cluster soft vs soft handling + CL_SELF = 0x0040, ///Cluster soft body self collision + /* presets */ + Default = SDF_RS, + END + }; + }; ///fMaterial - struct fMaterial { enum _ { - DebugDraw = 0x0001, /// Enable debug draw - /* presets */ - Default = DebugDraw, - END - };}; + struct fMaterial + { + enum _ + { + DebugDraw = 0x0001, /// Enable debug draw + /* presets */ + Default = DebugDraw, + END + }; + }; // // API Types // - /* sRayCast */ + /* sRayCast */ struct sRayCast { - btSoftBody* body; /// soft body - eFeature::_ feature; /// feature type - int index; /// feature index - btScalar fraction; /// time of impact fraction (rayorg+(rayto-rayfrom)*fraction) + btSoftBody* body; /// soft body + eFeature::_ feature; /// feature type + int index; /// feature index + btScalar fraction; /// time of impact fraction (rayorg+(rayto-rayfrom)*fraction) }; - /* ImplicitFn */ - struct ImplicitFn + /* ImplicitFn */ + struct ImplicitFn { virtual ~ImplicitFn() {} - virtual btScalar Eval(const btVector3& x)=0; + virtual btScalar Eval(const btVector3& x) = 0; }; // // Internal types // - typedef btAlignedObjectArray tScalarArray; - typedef btAlignedObjectArray tVector3Array; + typedef btAlignedObjectArray tScalarArray; + typedef btAlignedObjectArray tVector3Array; - /* sCti is Softbody contact info */ - struct sCti + /* sCti is Softbody contact info */ + struct sCti { - const btCollisionObject* m_colObj; /* Rigid body */ - btVector3 m_normal; /* Outward normal */ - btScalar m_offset; /* Offset from origin */ - }; - - /* sMedium */ - struct sMedium - { - btVector3 m_velocity; /* Velocity */ - btScalar m_pressure; /* Pressure */ - btScalar m_density; /* Density */ + const btCollisionObject* m_colObj; /* Rigid body */ + btVector3 m_normal; /* Outward normal */ + btScalar m_offset; /* Offset from origin */ }; - /* Base type */ - struct Element + /* sMedium */ + struct sMedium { - void* m_tag; // User data + btVector3 m_velocity; /* Velocity */ + btScalar m_pressure; /* Pressure */ + btScalar m_density; /* Density */ + }; + + /* Base type */ + struct Element + { + void* m_tag; // User data Element() : m_tag(0) {} }; - /* Material */ - struct Material : Element + /* Material */ + struct Material : Element { - btScalar m_kLST; // Linear stiffness coefficient [0,1] - btScalar m_kAST; // Area/Angular stiffness coefficient [0,1] - btScalar m_kVST; // Volume stiffness coefficient [0,1] - int m_flags; // Flags + btScalar m_kLST; // Linear stiffness coefficient [0,1] + btScalar m_kAST; // Area/Angular stiffness coefficient [0,1] + btScalar m_kVST; // Volume stiffness coefficient [0,1] + int m_flags; // Flags }; - /* Feature */ - struct Feature : Element + /* Feature */ + struct Feature : Element { - Material* m_material; // Material + Material* m_material; // Material }; - /* Node */ - struct Node : Feature + /* Node */ + struct Node : Feature { - btVector3 m_x; // Position - btVector3 m_q; // Previous step position - btVector3 m_v; // Velocity - btVector3 m_f; // Force accumulator - btVector3 m_n; // Normal - btScalar m_im; // 1/mass - btScalar m_area; // Area - btDbvtNode* m_leaf; // Leaf data - int m_battach:1; // Attached + btVector3 m_x; // Position + btVector3 m_q; // Previous step position + btVector3 m_v; // Velocity + btVector3 m_f; // Force accumulator + btVector3 m_n; // Normal + btScalar m_im; // 1/mass + btScalar m_area; // Area + btDbvtNode* m_leaf; // Leaf data + int m_battach : 1; // Attached }; - /* Link */ - ATTRIBUTE_ALIGNED16(struct) Link : Feature + /* Link */ + ATTRIBUTE_ALIGNED16(struct) + Link : Feature { - btVector3 m_c3; // gradient - Node* m_n[2]; // Node pointers - btScalar m_rl; // Rest length - int m_bbending:1; // Bending link - btScalar m_c0; // (ima+imb)*kLST - btScalar m_c1; // rl^2 - btScalar m_c2; // |gradient|^2/c0 - + btVector3 m_c3; // gradient + Node* m_n[2]; // Node pointers + btScalar m_rl; // Rest length + int m_bbending : 1; // Bending link + btScalar m_c0; // (ima+imb)*kLST + btScalar m_c1; // rl^2 + btScalar m_c2; // |gradient|^2/c0 + BT_DECLARE_ALIGNED_ALLOCATOR(); - }; - /* Face */ - struct Face : Feature + /* Face */ + struct Face : Feature { - Node* m_n[3]; // Node pointers - btVector3 m_normal; // Normal - btScalar m_ra; // Rest area - btDbvtNode* m_leaf; // Leaf data + Node* m_n[3]; // Node pointers + btVector3 m_normal; // Normal + btScalar m_ra; // Rest area + btDbvtNode* m_leaf; // Leaf data }; - /* Tetra */ - struct Tetra : Feature + /* Tetra */ + struct Tetra : Feature { - Node* m_n[4]; // Node pointers - btScalar m_rv; // Rest volume - btDbvtNode* m_leaf; // Leaf data - btVector3 m_c0[4]; // gradients - btScalar m_c1; // (4*kVST)/(im0+im1+im2+im3) - btScalar m_c2; // m_c1/sum(|g0..3|^2) + Node* m_n[4]; // Node pointers + btScalar m_rv; // Rest volume + btDbvtNode* m_leaf; // Leaf data + btVector3 m_c0[4]; // gradients + btScalar m_c1; // (4*kVST)/(im0+im1+im2+im3) + btScalar m_c2; // m_c1/sum(|g0..3|^2) }; - /* RContact */ - struct RContact + /* RContact */ + struct RContact { - sCti m_cti; // Contact infos - Node* m_node; // Owner node - btMatrix3x3 m_c0; // Impulse matrix - btVector3 m_c1; // Relative anchor - btScalar m_c2; // ima*dt - btScalar m_c3; // Friction - btScalar m_c4; // Hardness + sCti m_cti; // Contact infos + Node* m_node; // Owner node + btMatrix3x3 m_c0; // Impulse matrix + btVector3 m_c1; // Relative anchor + btScalar m_c2; // ima*dt + btScalar m_c3; // Friction + btScalar m_c4; // Hardness }; - /* SContact */ - struct SContact + /* SContact */ + struct SContact { - Node* m_node; // Node - Face* m_face; // Face - btVector3 m_weights; // Weigths - btVector3 m_normal; // Normal - btScalar m_margin; // Margin - btScalar m_friction; // Friction - btScalar m_cfm[2]; // Constraint force mixing + Node* m_node; // Node + Face* m_face; // Face + btVector3 m_weights; // Weigths + btVector3 m_normal; // Normal + btScalar m_margin; // Margin + btScalar m_friction; // Friction + btScalar m_cfm[2]; // Constraint force mixing }; - /* Anchor */ - struct Anchor + /* Anchor */ + struct Anchor { - Node* m_node; // Node pointer - btVector3 m_local; // Anchor position in body space - btRigidBody* m_body; // Body - btScalar m_influence; - btMatrix3x3 m_c0; // Impulse matrix - btVector3 m_c1; // Relative anchor - btScalar m_c2; // ima*dt + Node* m_node; // Node pointer + btVector3 m_local; // Anchor position in body space + btRigidBody* m_body; // Body + btScalar m_influence; + btMatrix3x3 m_c0; // Impulse matrix + btVector3 m_c1; // Relative anchor + btScalar m_c2; // ima*dt }; - /* Note */ - struct Note : Element + /* Note */ + struct Note : Element { - const char* m_text; // Text - btVector3 m_offset; // Offset - int m_rank; // Rank - Node* m_nodes[4]; // Nodes - btScalar m_coords[4]; // Coordinates - }; - /* Pose */ - struct Pose - { - bool m_bvolume; // Is valid - bool m_bframe; // Is frame - btScalar m_volume; // Rest volume - tVector3Array m_pos; // Reference positions - tScalarArray m_wgh; // Weights - btVector3 m_com; // COM - btMatrix3x3 m_rot; // Rotation - btMatrix3x3 m_scl; // Scale - btMatrix3x3 m_aqq; // Base scaling + const char* m_text; // Text + btVector3 m_offset; // Offset + int m_rank; // Rank + Node* m_nodes[4]; // Nodes + btScalar m_coords[4]; // Coordinates }; - /* Cluster */ - struct Cluster + /* Pose */ + struct Pose { - tScalarArray m_masses; - btAlignedObjectArray m_nodes; - tVector3Array m_framerefs; - btTransform m_framexform; - btScalar m_idmass; - btScalar m_imass; - btMatrix3x3 m_locii; - btMatrix3x3 m_invwi; - btVector3 m_com; - btVector3 m_vimpulses[2]; - btVector3 m_dimpulses[2]; - int m_nvimpulses; - int m_ndimpulses; - btVector3 m_lv; - btVector3 m_av; - btDbvtNode* m_leaf; - btScalar m_ndamping; /* Node damping */ - btScalar m_ldamping; /* Linear damping */ - btScalar m_adamping; /* Angular damping */ - btScalar m_matching; - btScalar m_maxSelfCollisionImpulse; - btScalar m_selfCollisionImpulseFactor; - bool m_containsAnchor; - bool m_collide; - int m_clusterIndex; - Cluster() : m_leaf(0),m_ndamping(0),m_ldamping(0),m_adamping(0),m_matching(0) - ,m_maxSelfCollisionImpulse(100.f), - m_selfCollisionImpulseFactor(0.01f), - m_containsAnchor(false) - {} + bool m_bvolume; // Is valid + bool m_bframe; // Is frame + btScalar m_volume; // Rest volume + tVector3Array m_pos; // Reference positions + tScalarArray m_wgh; // Weights + btVector3 m_com; // COM + btMatrix3x3 m_rot; // Rotation + btMatrix3x3 m_scl; // Scale + btMatrix3x3 m_aqq; // Base scaling }; - /* Impulse */ - struct Impulse + /* Cluster */ + struct Cluster { - btVector3 m_velocity; - btVector3 m_drift; - int m_asVelocity:1; - int m_asDrift:1; - Impulse() : m_velocity(0,0,0),m_drift(0,0,0),m_asVelocity(0),m_asDrift(0) {} - Impulse operator -() const + tScalarArray m_masses; + btAlignedObjectArray m_nodes; + tVector3Array m_framerefs; + btTransform m_framexform; + btScalar m_idmass; + btScalar m_imass; + btMatrix3x3 m_locii; + btMatrix3x3 m_invwi; + btVector3 m_com; + btVector3 m_vimpulses[2]; + btVector3 m_dimpulses[2]; + int m_nvimpulses; + int m_ndimpulses; + btVector3 m_lv; + btVector3 m_av; + btDbvtNode* m_leaf; + btScalar m_ndamping; /* Node damping */ + btScalar m_ldamping; /* Linear damping */ + btScalar m_adamping; /* Angular damping */ + btScalar m_matching; + btScalar m_maxSelfCollisionImpulse; + btScalar m_selfCollisionImpulseFactor; + bool m_containsAnchor; + bool m_collide; + int m_clusterIndex; + Cluster() : m_leaf(0), m_ndamping(0), m_ldamping(0), m_adamping(0), m_matching(0), m_maxSelfCollisionImpulse(100.f), m_selfCollisionImpulseFactor(0.01f), m_containsAnchor(false) { - Impulse i=*this; - i.m_velocity=-i.m_velocity; - i.m_drift=-i.m_drift; - return(i); - } - Impulse operator*(btScalar x) const - { - Impulse i=*this; - i.m_velocity*=x; - i.m_drift*=x; - return(i); } }; - /* Body */ - struct Body + /* Impulse */ + struct Impulse { - Cluster* m_soft; - btRigidBody* m_rigid; - const btCollisionObject* m_collisionObject; + btVector3 m_velocity; + btVector3 m_drift; + int m_asVelocity : 1; + int m_asDrift : 1; + Impulse() : m_velocity(0, 0, 0), m_drift(0, 0, 0), m_asVelocity(0), m_asDrift(0) {} + Impulse operator-() const + { + Impulse i = *this; + i.m_velocity = -i.m_velocity; + i.m_drift = -i.m_drift; + return (i); + } + Impulse operator*(btScalar x) const + { + Impulse i = *this; + i.m_velocity *= x; + i.m_drift *= x; + return (i); + } + }; + /* Body */ + struct Body + { + Cluster* m_soft; + btRigidBody* m_rigid; + const btCollisionObject* m_collisionObject; - Body() : m_soft(0),m_rigid(0),m_collisionObject(0) {} - Body(Cluster* p) : m_soft(p),m_rigid(0),m_collisionObject(0) {} - Body(const btCollisionObject* colObj) : m_soft(0),m_collisionObject(colObj) + Body() : m_soft(0), m_rigid(0), m_collisionObject(0) {} + Body(Cluster* p) : m_soft(p), m_rigid(0), m_collisionObject(0) {} + Body(const btCollisionObject* colObj) : m_soft(0), m_collisionObject(colObj) { m_rigid = (btRigidBody*)btRigidBody::upcast(m_collisionObject); } - void activate() const + void activate() const { - if(m_rigid) + if (m_rigid) m_rigid->activate(); if (m_collisionObject) m_collisionObject->activate(); - } - const btMatrix3x3& invWorldInertia() const + const btMatrix3x3& invWorldInertia() const { - static const btMatrix3x3 iwi(0,0,0,0,0,0,0,0,0); - if(m_rigid) return(m_rigid->getInvInertiaTensorWorld()); - if(m_soft) return(m_soft->m_invwi); - return(iwi); + static const btMatrix3x3 iwi(0, 0, 0, 0, 0, 0, 0, 0, 0); + if (m_rigid) return (m_rigid->getInvInertiaTensorWorld()); + if (m_soft) return (m_soft->m_invwi); + return (iwi); } - btScalar invMass() const + btScalar invMass() const { - if(m_rigid) return(m_rigid->getInvMass()); - if(m_soft) return(m_soft->m_imass); - return(0); + if (m_rigid) return (m_rigid->getInvMass()); + if (m_soft) return (m_soft->m_imass); + return (0); } - const btTransform& xform() const + const btTransform& xform() const { - static const btTransform identity=btTransform::getIdentity(); - if(m_collisionObject) return(m_collisionObject->getWorldTransform()); - if(m_soft) return(m_soft->m_framexform); - return(identity); + static const btTransform identity = btTransform::getIdentity(); + if (m_collisionObject) return (m_collisionObject->getWorldTransform()); + if (m_soft) return (m_soft->m_framexform); + return (identity); } - btVector3 linearVelocity() const + btVector3 linearVelocity() const { - if(m_rigid) return(m_rigid->getLinearVelocity()); - if(m_soft) return(m_soft->m_lv); - return(btVector3(0,0,0)); + if (m_rigid) return (m_rigid->getLinearVelocity()); + if (m_soft) return (m_soft->m_lv); + return (btVector3(0, 0, 0)); } - btVector3 angularVelocity(const btVector3& rpos) const - { - if(m_rigid) return(btCross(m_rigid->getAngularVelocity(),rpos)); - if(m_soft) return(btCross(m_soft->m_av,rpos)); - return(btVector3(0,0,0)); - } - btVector3 angularVelocity() const - { - if(m_rigid) return(m_rigid->getAngularVelocity()); - if(m_soft) return(m_soft->m_av); - return(btVector3(0,0,0)); - } - btVector3 velocity(const btVector3& rpos) const + btVector3 angularVelocity(const btVector3& rpos) const { - return(linearVelocity()+angularVelocity(rpos)); + if (m_rigid) return (btCross(m_rigid->getAngularVelocity(), rpos)); + if (m_soft) return (btCross(m_soft->m_av, rpos)); + return (btVector3(0, 0, 0)); } - void applyVImpulse(const btVector3& impulse,const btVector3& rpos) const + btVector3 angularVelocity() const { - if(m_rigid) m_rigid->applyImpulse(impulse,rpos); - if(m_soft) btSoftBody::clusterVImpulse(m_soft,rpos,impulse); + if (m_rigid) return (m_rigid->getAngularVelocity()); + if (m_soft) return (m_soft->m_av); + return (btVector3(0, 0, 0)); } - void applyDImpulse(const btVector3& impulse,const btVector3& rpos) const + btVector3 velocity(const btVector3& rpos) const { - if(m_rigid) m_rigid->applyImpulse(impulse,rpos); - if(m_soft) btSoftBody::clusterDImpulse(m_soft,rpos,impulse); - } - void applyImpulse(const Impulse& impulse,const btVector3& rpos) const + return (linearVelocity() + angularVelocity(rpos)); + } + void applyVImpulse(const btVector3& impulse, const btVector3& rpos) const { - if(impulse.m_asVelocity) + if (m_rigid) m_rigid->applyImpulse(impulse, rpos); + if (m_soft) btSoftBody::clusterVImpulse(m_soft, rpos, impulse); + } + void applyDImpulse(const btVector3& impulse, const btVector3& rpos) const + { + if (m_rigid) m_rigid->applyImpulse(impulse, rpos); + if (m_soft) btSoftBody::clusterDImpulse(m_soft, rpos, impulse); + } + void applyImpulse(const Impulse& impulse, const btVector3& rpos) const + { + if (impulse.m_asVelocity) { -// printf("impulse.m_velocity = %f,%f,%f\n",impulse.m_velocity.getX(),impulse.m_velocity.getY(),impulse.m_velocity.getZ()); - applyVImpulse(impulse.m_velocity,rpos); + // printf("impulse.m_velocity = %f,%f,%f\n",impulse.m_velocity.getX(),impulse.m_velocity.getY(),impulse.m_velocity.getZ()); + applyVImpulse(impulse.m_velocity, rpos); } - if(impulse.m_asDrift) + if (impulse.m_asDrift) { -// printf("impulse.m_drift = %f,%f,%f\n",impulse.m_drift.getX(),impulse.m_drift.getY(),impulse.m_drift.getZ()); - applyDImpulse(impulse.m_drift,rpos); + // printf("impulse.m_drift = %f,%f,%f\n",impulse.m_drift.getX(),impulse.m_drift.getY(),impulse.m_drift.getZ()); + applyDImpulse(impulse.m_drift, rpos); } } - void applyVAImpulse(const btVector3& impulse) const + void applyVAImpulse(const btVector3& impulse) const { - if(m_rigid) m_rigid->applyTorqueImpulse(impulse); - if(m_soft) btSoftBody::clusterVAImpulse(m_soft,impulse); + if (m_rigid) m_rigid->applyTorqueImpulse(impulse); + if (m_soft) btSoftBody::clusterVAImpulse(m_soft, impulse); } - void applyDAImpulse(const btVector3& impulse) const + void applyDAImpulse(const btVector3& impulse) const { - if(m_rigid) m_rigid->applyTorqueImpulse(impulse); - if(m_soft) btSoftBody::clusterDAImpulse(m_soft,impulse); + if (m_rigid) m_rigid->applyTorqueImpulse(impulse); + if (m_soft) btSoftBody::clusterDAImpulse(m_soft, impulse); } - void applyAImpulse(const Impulse& impulse) const + void applyAImpulse(const Impulse& impulse) const { - if(impulse.m_asVelocity) applyVAImpulse(impulse.m_velocity); - if(impulse.m_asDrift) applyDAImpulse(impulse.m_drift); + if (impulse.m_asVelocity) applyVAImpulse(impulse.m_velocity); + if (impulse.m_asDrift) applyDAImpulse(impulse.m_drift); } - void applyDCImpulse(const btVector3& impulse) const + void applyDCImpulse(const btVector3& impulse) const { - if(m_rigid) m_rigid->applyCentralImpulse(impulse); - if(m_soft) btSoftBody::clusterDCImpulse(m_soft,impulse); + if (m_rigid) m_rigid->applyCentralImpulse(impulse); + if (m_soft) btSoftBody::clusterDCImpulse(m_soft, impulse); } }; - /* Joint */ - struct Joint + /* Joint */ + struct Joint { - struct eType { enum _ { - Linear=0, - Angular, - Contact - };}; + struct eType + { + enum _ + { + Linear = 0, + Angular, + Contact + }; + }; struct Specs { - Specs() : erp(1),cfm(1),split(1) {} - btScalar erp; - btScalar cfm; - btScalar split; + Specs() : erp(1), cfm(1), split(1) {} + btScalar erp; + btScalar cfm; + btScalar split; }; - Body m_bodies[2]; - btVector3 m_refs[2]; - btScalar m_cfm; - btScalar m_erp; - btScalar m_split; - btVector3 m_drift; - btVector3 m_sdrift; - btMatrix3x3 m_massmatrix; - bool m_delete; - virtual ~Joint() {} + Body m_bodies[2]; + btVector3 m_refs[2]; + btScalar m_cfm; + btScalar m_erp; + btScalar m_split; + btVector3 m_drift; + btVector3 m_sdrift; + btMatrix3x3 m_massmatrix; + bool m_delete; + virtual ~Joint() {} Joint() : m_delete(false) {} - virtual void Prepare(btScalar dt,int iterations); - virtual void Solve(btScalar dt,btScalar sor)=0; - virtual void Terminate(btScalar dt)=0; - virtual eType::_ Type() const=0; + virtual void Prepare(btScalar dt, int iterations); + virtual void Solve(btScalar dt, btScalar sor) = 0; + virtual void Terminate(btScalar dt) = 0; + virtual eType::_ Type() const = 0; }; - /* LJoint */ - struct LJoint : Joint + /* LJoint */ + struct LJoint : Joint { struct Specs : Joint::Specs { - btVector3 position; - }; - btVector3 m_rpos[2]; - void Prepare(btScalar dt,int iterations); - void Solve(btScalar dt,btScalar sor); - void Terminate(btScalar dt); - eType::_ Type() const { return(eType::Linear); } + btVector3 position; + }; + btVector3 m_rpos[2]; + void Prepare(btScalar dt, int iterations); + void Solve(btScalar dt, btScalar sor); + void Terminate(btScalar dt); + eType::_ Type() const { return (eType::Linear); } }; - /* AJoint */ - struct AJoint : Joint + /* AJoint */ + struct AJoint : Joint { struct IControl { virtual ~IControl() {} - virtual void Prepare(AJoint*) {} - virtual btScalar Speed(AJoint*,btScalar current) { return(current); } - static IControl* Default() { static IControl def;return(&def); } + virtual void Prepare(AJoint*) {} + virtual btScalar Speed(AJoint*, btScalar current) { return (current); } + static IControl* Default() + { + static IControl def; + return (&def); + } }; struct Specs : Joint::Specs { Specs() : icontrol(IControl::Default()) {} - btVector3 axis; - IControl* icontrol; - }; - btVector3 m_axis[2]; - IControl* m_icontrol; - void Prepare(btScalar dt,int iterations); - void Solve(btScalar dt,btScalar sor); - void Terminate(btScalar dt); - eType::_ Type() const { return(eType::Angular); } + btVector3 axis; + IControl* icontrol; + }; + btVector3 m_axis[2]; + IControl* m_icontrol; + void Prepare(btScalar dt, int iterations); + void Solve(btScalar dt, btScalar sor); + void Terminate(btScalar dt); + eType::_ Type() const { return (eType::Angular); } }; - /* CJoint */ - struct CJoint : Joint - { - int m_life; - int m_maxlife; - btVector3 m_rpos[2]; - btVector3 m_normal; - btScalar m_friction; - void Prepare(btScalar dt,int iterations); - void Solve(btScalar dt,btScalar sor); - void Terminate(btScalar dt); - eType::_ Type() const { return(eType::Contact); } - }; - /* Config */ - struct Config + /* CJoint */ + struct CJoint : Joint { - eAeroModel::_ aeromodel; // Aerodynamic model (default: V_Point) - btScalar kVCF; // Velocities correction factor (Baumgarte) - btScalar kDP; // Damping coefficient [0,1] - btScalar kDG; // Drag coefficient [0,+inf] - btScalar kLF; // Lift coefficient [0,+inf] - btScalar kPR; // Pressure coefficient [-inf,+inf] - btScalar kVC; // Volume conversation coefficient [0,+inf] - btScalar kDF; // Dynamic friction coefficient [0,1] - btScalar kMT; // Pose matching coefficient [0,1] - btScalar kCHR; // Rigid contacts hardness [0,1] - btScalar kKHR; // Kinetic contacts hardness [0,1] - btScalar kSHR; // Soft contacts hardness [0,1] - btScalar kAHR; // Anchors hardness [0,1] - btScalar kSRHR_CL; // Soft vs rigid hardness [0,1] (cluster only) - btScalar kSKHR_CL; // Soft vs kinetic hardness [0,1] (cluster only) - btScalar kSSHR_CL; // Soft vs soft hardness [0,1] (cluster only) - btScalar kSR_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only) - btScalar kSK_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only) - btScalar kSS_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only) - btScalar maxvolume; // Maximum volume ratio for pose - btScalar timescale; // Time scale - int viterations; // Velocities solver iterations - int piterations; // Positions solver iterations - int diterations; // Drift solver iterations - int citerations; // Cluster solver iterations - int collisions; // Collisions flags - tVSolverArray m_vsequence; // Velocity solvers sequence - tPSolverArray m_psequence; // Position solvers sequence - tPSolverArray m_dsequence; // Drift solvers sequence + int m_life; + int m_maxlife; + btVector3 m_rpos[2]; + btVector3 m_normal; + btScalar m_friction; + void Prepare(btScalar dt, int iterations); + void Solve(btScalar dt, btScalar sor); + void Terminate(btScalar dt); + eType::_ Type() const { return (eType::Contact); } }; - /* SolverState */ - struct SolverState + /* Config */ + struct Config { - btScalar sdt; // dt*timescale - btScalar isdt; // 1/sdt - btScalar velmrg; // velocity margin - btScalar radmrg; // radial margin - btScalar updmrg; // Update margin - }; + eAeroModel::_ aeromodel; // Aerodynamic model (default: V_Point) + btScalar kVCF; // Velocities correction factor (Baumgarte) + btScalar kDP; // Damping coefficient [0,1] + btScalar kDG; // Drag coefficient [0,+inf] + btScalar kLF; // Lift coefficient [0,+inf] + btScalar kPR; // Pressure coefficient [-inf,+inf] + btScalar kVC; // Volume conversation coefficient [0,+inf] + btScalar kDF; // Dynamic friction coefficient [0,1] + btScalar kMT; // Pose matching coefficient [0,1] + btScalar kCHR; // Rigid contacts hardness [0,1] + btScalar kKHR; // Kinetic contacts hardness [0,1] + btScalar kSHR; // Soft contacts hardness [0,1] + btScalar kAHR; // Anchors hardness [0,1] + btScalar kSRHR_CL; // Soft vs rigid hardness [0,1] (cluster only) + btScalar kSKHR_CL; // Soft vs kinetic hardness [0,1] (cluster only) + btScalar kSSHR_CL; // Soft vs soft hardness [0,1] (cluster only) + btScalar kSR_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only) + btScalar kSK_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only) + btScalar kSS_SPLT_CL; // Soft vs rigid impulse split [0,1] (cluster only) + btScalar maxvolume; // Maximum volume ratio for pose + btScalar timescale; // Time scale + int viterations; // Velocities solver iterations + int piterations; // Positions solver iterations + int diterations; // Drift solver iterations + int citerations; // Cluster solver iterations + int collisions; // Collisions flags + tVSolverArray m_vsequence; // Velocity solvers sequence + tPSolverArray m_psequence; // Position solvers sequence + tPSolverArray m_dsequence; // Drift solvers sequence + }; + /* SolverState */ + struct SolverState + { + btScalar sdt; // dt*timescale + btScalar isdt; // 1/sdt + btScalar velmrg; // velocity margin + btScalar radmrg; // radial margin + btScalar updmrg; // Update margin + }; /// RayFromToCaster takes a ray from, ray to (instead of direction!) - struct RayFromToCaster : btDbvt::ICollide + struct RayFromToCaster : btDbvt::ICollide { - btVector3 m_rayFrom; - btVector3 m_rayTo; - btVector3 m_rayNormalizedDirection; - btScalar m_mint; - Face* m_face; - int m_tests; - RayFromToCaster(const btVector3& rayFrom,const btVector3& rayTo,btScalar mxt); - void Process(const btDbvtNode* leaf); + btVector3 m_rayFrom; + btVector3 m_rayTo; + btVector3 m_rayNormalizedDirection; + btScalar m_mint; + Face* m_face; + int m_tests; + RayFromToCaster(const btVector3& rayFrom, const btVector3& rayTo, btScalar mxt); + void Process(const btDbvtNode* leaf); - static /*inline*/ btScalar rayFromToTriangle(const btVector3& rayFrom, - const btVector3& rayTo, - const btVector3& rayNormalizedDirection, - const btVector3& a, - const btVector3& b, - const btVector3& c, - btScalar maxt=SIMD_INFINITY); + static /*inline*/ btScalar rayFromToTriangle(const btVector3& rayFrom, + const btVector3& rayTo, + const btVector3& rayNormalizedDirection, + const btVector3& a, + const btVector3& b, + const btVector3& c, + btScalar maxt = SIMD_INFINITY); }; // // Typedefs // - typedef void (*psolver_t)(btSoftBody*,btScalar,btScalar); - typedef void (*vsolver_t)(btSoftBody*,btScalar); - typedef btAlignedObjectArray tClusterArray; - typedef btAlignedObjectArray tNoteArray; - typedef btAlignedObjectArray tNodeArray; - typedef btAlignedObjectArray tLeafArray; - typedef btAlignedObjectArray tLinkArray; - typedef btAlignedObjectArray tFaceArray; - typedef btAlignedObjectArray tTetraArray; - typedef btAlignedObjectArray tAnchorArray; - typedef btAlignedObjectArray tRContactArray; - typedef btAlignedObjectArray tSContactArray; - typedef btAlignedObjectArray tMaterialArray; - typedef btAlignedObjectArray tJointArray; - typedef btAlignedObjectArray tSoftBodyArray; + typedef void (*psolver_t)(btSoftBody*, btScalar, btScalar); + typedef void (*vsolver_t)(btSoftBody*, btScalar); + typedef btAlignedObjectArray tClusterArray; + typedef btAlignedObjectArray tNoteArray; + typedef btAlignedObjectArray tNodeArray; + typedef btAlignedObjectArray tLeafArray; + typedef btAlignedObjectArray tLinkArray; + typedef btAlignedObjectArray tFaceArray; + typedef btAlignedObjectArray tTetraArray; + typedef btAlignedObjectArray tAnchorArray; + typedef btAlignedObjectArray tRContactArray; + typedef btAlignedObjectArray tSContactArray; + typedef btAlignedObjectArray tMaterialArray; + typedef btAlignedObjectArray tJointArray; + typedef btAlignedObjectArray tSoftBodyArray; // // Fields // - Config m_cfg; // Configuration - SolverState m_sst; // Solver state - Pose m_pose; // Pose - void* m_tag; // User data - btSoftBodyWorldInfo* m_worldInfo; // World info - tNoteArray m_notes; // Notes - tNodeArray m_nodes; // Nodes - tLinkArray m_links; // Links - tFaceArray m_faces; // Faces - tTetraArray m_tetras; // Tetras - tAnchorArray m_anchors; // Anchors - tRContactArray m_rcontacts; // Rigid contacts - tSContactArray m_scontacts; // Soft contacts - tJointArray m_joints; // Joints - tMaterialArray m_materials; // Materials - btScalar m_timeacc; // Time accumulator - btVector3 m_bounds[2]; // Spatial bounds - bool m_bUpdateRtCst; // Update runtime constants - btDbvt m_ndbvt; // Nodes tree - btDbvt m_fdbvt; // Faces tree - btDbvt m_cdbvt; // Clusters tree - tClusterArray m_clusters; // Clusters + Config m_cfg; // Configuration + SolverState m_sst; // Solver state + Pose m_pose; // Pose + void* m_tag; // User data + btSoftBodyWorldInfo* m_worldInfo; // World info + tNoteArray m_notes; // Notes + tNodeArray m_nodes; // Nodes + tLinkArray m_links; // Links + tFaceArray m_faces; // Faces + tTetraArray m_tetras; // Tetras + tAnchorArray m_anchors; // Anchors + tRContactArray m_rcontacts; // Rigid contacts + tSContactArray m_scontacts; // Soft contacts + tJointArray m_joints; // Joints + tMaterialArray m_materials; // Materials + btScalar m_timeacc; // Time accumulator + btVector3 m_bounds[2]; // Spatial bounds + bool m_bUpdateRtCst; // Update runtime constants + btDbvt m_ndbvt; // Nodes tree + btDbvt m_fdbvt; // Faces tree + btDbvt m_cdbvt; // Clusters tree + tClusterArray m_clusters; // Clusters - btAlignedObjectArraym_clusterConnectivity;//cluster connectivity, for self-collision + btAlignedObjectArray m_clusterConnectivity; //cluster connectivity, for self-collision - btTransform m_initialWorldTransform; + btTransform m_initialWorldTransform; + + btVector3 m_windVelocity; + + btScalar m_restLengthScale; - btVector3 m_windVelocity; - - btScalar m_restLengthScale; - // // Api // - /* ctor */ - btSoftBody( btSoftBodyWorldInfo* worldInfo,int node_count, const btVector3* x, const btScalar* m); + /* ctor */ + btSoftBody(btSoftBodyWorldInfo* worldInfo, int node_count, const btVector3* x, const btScalar* m); - /* ctor */ - btSoftBody( btSoftBodyWorldInfo* worldInfo); + /* ctor */ + btSoftBody(btSoftBodyWorldInfo* worldInfo); - void initDefaults(); + void initDefaults(); - /* dtor */ + /* dtor */ virtual ~btSoftBody(); - /* Check for existing link */ + /* Check for existing link */ - btAlignedObjectArray m_userIndexMapping; + btAlignedObjectArray m_userIndexMapping; - btSoftBodyWorldInfo* getWorldInfo() + btSoftBodyWorldInfo* getWorldInfo() { return m_worldInfo; } ///@todo: avoid internal softbody shape hack and move collision code to collision library - virtual void setCollisionShape(btCollisionShape* collisionShape) + virtual void setCollisionShape(btCollisionShape* collisionShape) { - } - bool checkLink( int node0, - int node1) const; - bool checkLink( const Node* node0, - const Node* node1) const; - /* Check for existring face */ - bool checkFace( int node0, - int node1, - int node2) const; - /* Append material */ - Material* appendMaterial(); - /* Append note */ - void appendNote( const char* text, - const btVector3& o, - const btVector4& c=btVector4(1,0,0,0), - Node* n0=0, - Node* n1=0, - Node* n2=0, - Node* n3=0); - void appendNote( const char* text, - const btVector3& o, - Node* feature); - void appendNote( const char* text, - const btVector3& o, - Link* feature); - void appendNote( const char* text, - const btVector3& o, - Face* feature); - /* Append node */ - void appendNode( const btVector3& x,btScalar m); - /* Append link */ - void appendLink(int model=-1,Material* mat=0); - void appendLink( int node0, - int node1, - Material* mat=0, - bool bcheckexist=false); - void appendLink( Node* node0, - Node* node1, - Material* mat=0, - bool bcheckexist=false); - /* Append face */ - void appendFace(int model=-1,Material* mat=0); - void appendFace( int node0, - int node1, - int node2, - Material* mat=0); - void appendTetra(int model,Material* mat); + bool checkLink(int node0, + int node1) const; + bool checkLink(const Node* node0, + const Node* node1) const; + /* Check for existring face */ + bool checkFace(int node0, + int node1, + int node2) const; + /* Append material */ + Material* appendMaterial(); + /* Append note */ + void appendNote(const char* text, + const btVector3& o, + const btVector4& c = btVector4(1, 0, 0, 0), + Node* n0 = 0, + Node* n1 = 0, + Node* n2 = 0, + Node* n3 = 0); + void appendNote(const char* text, + const btVector3& o, + Node* feature); + void appendNote(const char* text, + const btVector3& o, + Link* feature); + void appendNote(const char* text, + const btVector3& o, + Face* feature); + /* Append node */ + void appendNode(const btVector3& x, btScalar m); + /* Append link */ + void appendLink(int model = -1, Material* mat = 0); + void appendLink(int node0, + int node1, + Material* mat = 0, + bool bcheckexist = false); + void appendLink(Node* node0, + Node* node1, + Material* mat = 0, + bool bcheckexist = false); + /* Append face */ + void appendFace(int model = -1, Material* mat = 0); + void appendFace(int node0, + int node1, + int node2, + Material* mat = 0); + void appendTetra(int model, Material* mat); // - void appendTetra(int node0, - int node1, - int node2, - int node3, - Material* mat=0); + void appendTetra(int node0, + int node1, + int node2, + int node3, + Material* mat = 0); - - /* Append anchor */ - void appendAnchor( int node, - btRigidBody* body, bool disableCollisionBetweenLinkedBodies=false,btScalar influence = 1); - void appendAnchor(int node,btRigidBody* body, const btVector3& localPivot,bool disableCollisionBetweenLinkedBodies=false,btScalar influence = 1); - /* Append linear joint */ - void appendLinearJoint(const LJoint::Specs& specs,Cluster* body0,Body body1); - void appendLinearJoint(const LJoint::Specs& specs,Body body=Body()); - void appendLinearJoint(const LJoint::Specs& specs,btSoftBody* body); - /* Append linear joint */ - void appendAngularJoint(const AJoint::Specs& specs,Cluster* body0,Body body1); - void appendAngularJoint(const AJoint::Specs& specs,Body body=Body()); - void appendAngularJoint(const AJoint::Specs& specs,btSoftBody* body); - /* Add force (or gravity) to the entire body */ - void addForce( const btVector3& force); - /* Add force (or gravity) to a node of the body */ - void addForce( const btVector3& force, - int node); + /* Append anchor */ + void appendAnchor(int node, + btRigidBody* body, bool disableCollisionBetweenLinkedBodies = false, btScalar influence = 1); + void appendAnchor(int node, btRigidBody* body, const btVector3& localPivot, bool disableCollisionBetweenLinkedBodies = false, btScalar influence = 1); + /* Append linear joint */ + void appendLinearJoint(const LJoint::Specs& specs, Cluster* body0, Body body1); + void appendLinearJoint(const LJoint::Specs& specs, Body body = Body()); + void appendLinearJoint(const LJoint::Specs& specs, btSoftBody* body); + /* Append linear joint */ + void appendAngularJoint(const AJoint::Specs& specs, Cluster* body0, Body body1); + void appendAngularJoint(const AJoint::Specs& specs, Body body = Body()); + void appendAngularJoint(const AJoint::Specs& specs, btSoftBody* body); + /* Add force (or gravity) to the entire body */ + void addForce(const btVector3& force); + /* Add force (or gravity) to a node of the body */ + void addForce(const btVector3& force, + int node); /* Add aero force to a node of the body */ - void addAeroForceToNode(const btVector3& windVelocity,int nodeIndex); + void addAeroForceToNode(const btVector3& windVelocity, int nodeIndex); /* Add aero force to a face of the body */ - void addAeroForceToFace(const btVector3& windVelocity,int faceIndex); + void addAeroForceToFace(const btVector3& windVelocity, int faceIndex); - /* Add velocity to the entire body */ - void addVelocity( const btVector3& velocity); + /* Add velocity to the entire body */ + void addVelocity(const btVector3& velocity); - /* Set velocity for the entire body */ - void setVelocity( const btVector3& velocity); + /* Set velocity for the entire body */ + void setVelocity(const btVector3& velocity); - /* Add velocity to a node of the body */ - void addVelocity( const btVector3& velocity, - int node); - /* Set mass */ - void setMass( int node, - btScalar mass); - /* Get mass */ - btScalar getMass( int node) const; - /* Get total mass */ - btScalar getTotalMass() const; - /* Set total mass (weighted by previous masses) */ - void setTotalMass( btScalar mass, - bool fromfaces=false); - /* Set total density */ - void setTotalDensity(btScalar density); + /* Add velocity to a node of the body */ + void addVelocity(const btVector3& velocity, + int node); + /* Set mass */ + void setMass(int node, + btScalar mass); + /* Get mass */ + btScalar getMass(int node) const; + /* Get total mass */ + btScalar getTotalMass() const; + /* Set total mass (weighted by previous masses) */ + void setTotalMass(btScalar mass, + bool fromfaces = false); + /* Set total density */ + void setTotalDensity(btScalar density); /* Set volume mass (using tetrahedrons) */ - void setVolumeMass( btScalar mass); + void setVolumeMass(btScalar mass); /* Set volume density (using tetrahedrons) */ - void setVolumeDensity( btScalar density); - /* Transform */ - void transform( const btTransform& trs); - /* Translate */ - void translate( const btVector3& trs); - /* Rotate */ - void rotate( const btQuaternion& rot); - /* Scale */ - void scale( const btVector3& scl); + void setVolumeDensity(btScalar density); + /* Transform */ + void transform(const btTransform& trs); + /* Translate */ + void translate(const btVector3& trs); + /* Rotate */ + void rotate(const btQuaternion& rot); + /* Scale */ + void scale(const btVector3& scl); /* Get link resting lengths scale */ - btScalar getRestLengthScale(); + btScalar getRestLengthScale(); /* Scale resting length of all springs */ - void setRestLengthScale(btScalar restLength); - /* Set current state as pose */ - void setPose( bool bvolume, - bool bframe); - /* Set current link lengths as resting lengths */ - void resetLinkRestLengths(); - /* Return the volume */ - btScalar getVolume() const; - /* Cluster count */ - int clusterCount() const; - /* Cluster center of mass */ - static btVector3 clusterCom(const Cluster* cluster); - btVector3 clusterCom(int cluster) const; - /* Cluster velocity at rpos */ - static btVector3 clusterVelocity(const Cluster* cluster,const btVector3& rpos); - /* Cluster impulse */ - static void clusterVImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse); - static void clusterDImpulse(Cluster* cluster,const btVector3& rpos,const btVector3& impulse); - static void clusterImpulse(Cluster* cluster,const btVector3& rpos,const Impulse& impulse); - static void clusterVAImpulse(Cluster* cluster,const btVector3& impulse); - static void clusterDAImpulse(Cluster* cluster,const btVector3& impulse); - static void clusterAImpulse(Cluster* cluster,const Impulse& impulse); - static void clusterDCImpulse(Cluster* cluster,const btVector3& impulse); - /* Generate bending constraints based on distance in the adjency graph */ - int generateBendingConstraints( int distance, - Material* mat=0); - /* Randomize constraints to reduce solver bias */ - void randomizeConstraints(); - /* Release clusters */ - void releaseCluster(int index); - void releaseClusters(); - /* Generate clusters (K-mean) */ + void setRestLengthScale(btScalar restLength); + /* Set current state as pose */ + void setPose(bool bvolume, + bool bframe); + /* Set current link lengths as resting lengths */ + void resetLinkRestLengths(); + /* Return the volume */ + btScalar getVolume() const; + /* Cluster count */ + int clusterCount() const; + /* Cluster center of mass */ + static btVector3 clusterCom(const Cluster* cluster); + btVector3 clusterCom(int cluster) const; + /* Cluster velocity at rpos */ + static btVector3 clusterVelocity(const Cluster* cluster, const btVector3& rpos); + /* Cluster impulse */ + static void clusterVImpulse(Cluster* cluster, const btVector3& rpos, const btVector3& impulse); + static void clusterDImpulse(Cluster* cluster, const btVector3& rpos, const btVector3& impulse); + static void clusterImpulse(Cluster* cluster, const btVector3& rpos, const Impulse& impulse); + static void clusterVAImpulse(Cluster* cluster, const btVector3& impulse); + static void clusterDAImpulse(Cluster* cluster, const btVector3& impulse); + static void clusterAImpulse(Cluster* cluster, const Impulse& impulse); + static void clusterDCImpulse(Cluster* cluster, const btVector3& impulse); + /* Generate bending constraints based on distance in the adjency graph */ + int generateBendingConstraints(int distance, + Material* mat = 0); + /* Randomize constraints to reduce solver bias */ + void randomizeConstraints(); + /* Release clusters */ + void releaseCluster(int index); + void releaseClusters(); + /* Generate clusters (K-mean) */ ///generateClusters with k=0 will create a convex cluster for each tetrahedron or triangle ///otherwise an approximation will be used (better performance) - int generateClusters(int k,int maxiterations=8192); - /* Refine */ - void refine(ImplicitFn* ifn,btScalar accurary,bool cut); - /* CutLink */ - bool cutLink(int node0,int node1,btScalar position); - bool cutLink(const Node* node0,const Node* node1,btScalar position); + int generateClusters(int k, int maxiterations = 8192); + /* Refine */ + void refine(ImplicitFn* ifn, btScalar accurary, bool cut); + /* CutLink */ + bool cutLink(int node0, int node1, btScalar position); + bool cutLink(const Node* node0, const Node* node1, btScalar position); ///Ray casting using rayFrom and rayTo in worldspace, (not direction!) - bool rayTest(const btVector3& rayFrom, - const btVector3& rayTo, - sRayCast& results); - /* Solver presets */ - void setSolver(eSolverPresets::_ preset); - /* predictMotion */ - void predictMotion(btScalar dt); - /* solveConstraints */ - void solveConstraints(); - /* staticSolve */ - void staticSolve(int iterations); - /* solveCommonConstraints */ - static void solveCommonConstraints(btSoftBody** bodies,int count,int iterations); - /* solveClusters */ - static void solveClusters(const btAlignedObjectArray& bodies); - /* integrateMotion */ - void integrateMotion(); - /* defaultCollisionHandlers */ - void defaultCollisionHandler(const btCollisionObjectWrapper* pcoWrap); - void defaultCollisionHandler(btSoftBody* psb); - - + bool rayTest(const btVector3& rayFrom, + const btVector3& rayTo, + sRayCast& results); + /* Solver presets */ + void setSolver(eSolverPresets::_ preset); + /* predictMotion */ + void predictMotion(btScalar dt); + /* solveConstraints */ + void solveConstraints(); + /* staticSolve */ + void staticSolve(int iterations); + /* solveCommonConstraints */ + static void solveCommonConstraints(btSoftBody** bodies, int count, int iterations); + /* solveClusters */ + static void solveClusters(const btAlignedObjectArray& bodies); + /* integrateMotion */ + void integrateMotion(); + /* defaultCollisionHandlers */ + void defaultCollisionHandler(const btCollisionObjectWrapper* pcoWrap); + void defaultCollisionHandler(btSoftBody* psb); // // Functionality to deal with new accelerated solvers. @@ -895,8 +923,7 @@ public: /** * Set a wind velocity for interaction with the air. */ - void setWindVelocity( const btVector3 &velocity ); - + void setWindVelocity(const btVector3& velocity); /** * Return the wind velocity for interaction with the air. @@ -907,41 +934,40 @@ public: // Set the solver that handles this soft body // Should not be allowed to get out of sync with reality // Currently called internally on addition to the world - void setSoftBodySolver( btSoftBodySolver *softBodySolver ) + void setSoftBodySolver(btSoftBodySolver* softBodySolver) { m_softBodySolver = softBodySolver; } // // Return the solver that handles this soft body - // - btSoftBodySolver *getSoftBodySolver() + // + btSoftBodySolver* getSoftBodySolver() { return m_softBodySolver; } // // Return the solver that handles this soft body - // - btSoftBodySolver *getSoftBodySolver() const + // + btSoftBodySolver* getSoftBodySolver() const { return m_softBodySolver; } - // // Cast // - static const btSoftBody* upcast(const btCollisionObject* colObj) + static const btSoftBody* upcast(const btCollisionObject* colObj) { - if (colObj->getInternalType()==CO_SOFT_BODY) + if (colObj->getInternalType() == CO_SOFT_BODY) return (const btSoftBody*)colObj; return 0; } - static btSoftBody* upcast(btCollisionObject* colObj) + static btSoftBody* upcast(btCollisionObject* colObj) { - if (colObj->getInternalType()==CO_SOFT_BODY) + if (colObj->getInternalType() == CO_SOFT_BODY) return (btSoftBody*)colObj; return 0; } @@ -950,7 +976,7 @@ public: // ::btCollisionObject // - virtual void getAabb(btVector3& aabbMin,btVector3& aabbMax) const + virtual void getAabb(btVector3& aabbMin, btVector3& aabbMax) const { aabbMin = m_bounds[0]; aabbMax = m_bounds[1]; @@ -958,48 +984,42 @@ public: // // Private // - void pointersToIndices(); - void indicesToPointers(const int* map=0); + void pointersToIndices(); + void indicesToPointers(const int* map = 0); - int rayTest(const btVector3& rayFrom,const btVector3& rayTo, - btScalar& mint,eFeature::_& feature,int& index,bool bcountonly) const; - void initializeFaceTree(); - btVector3 evaluateCom() const; - bool checkContact(const btCollisionObjectWrapper* colObjWrap,const btVector3& x,btScalar margin,btSoftBody::sCti& cti) const; - void updateNormals(); - void updateBounds(); - void updatePose(); - void updateConstants(); - void updateLinkConstants(); - void updateArea(bool averageArea = true); - void initializeClusters(); - void updateClusters(); - void cleanupClusters(); - void prepareClusters(int iterations); - void solveClusters(btScalar sor); - void applyClusters(bool drift); - void dampClusters(); - void applyForces(); - static void PSolve_Anchors(btSoftBody* psb,btScalar kst,btScalar ti); - static void PSolve_RContacts(btSoftBody* psb,btScalar kst,btScalar ti); - static void PSolve_SContacts(btSoftBody* psb,btScalar,btScalar ti); - static void PSolve_Links(btSoftBody* psb,btScalar kst,btScalar ti); - static void VSolve_Links(btSoftBody* psb,btScalar kst); - static psolver_t getSolver(ePSolver::_ solver); - static vsolver_t getSolver(eVSolver::_ solver); + int rayTest(const btVector3& rayFrom, const btVector3& rayTo, + btScalar& mint, eFeature::_& feature, int& index, bool bcountonly) const; + void initializeFaceTree(); + btVector3 evaluateCom() const; + bool checkContact(const btCollisionObjectWrapper* colObjWrap, const btVector3& x, btScalar margin, btSoftBody::sCti& cti) const; + void updateNormals(); + void updateBounds(); + void updatePose(); + void updateConstants(); + void updateLinkConstants(); + void updateArea(bool averageArea = true); + void initializeClusters(); + void updateClusters(); + void cleanupClusters(); + void prepareClusters(int iterations); + void solveClusters(btScalar sor); + void applyClusters(bool drift); + void dampClusters(); + void applyForces(); + static void PSolve_Anchors(btSoftBody* psb, btScalar kst, btScalar ti); + static void PSolve_RContacts(btSoftBody* psb, btScalar kst, btScalar ti); + static void PSolve_SContacts(btSoftBody* psb, btScalar, btScalar ti); + static void PSolve_Links(btSoftBody* psb, btScalar kst, btScalar ti); + static void VSolve_Links(btSoftBody* psb, btScalar kst); + static psolver_t getSolver(ePSolver::_ solver); + static vsolver_t getSolver(eVSolver::_ solver); - - virtual int calculateSerializeBufferSize() const; + virtual int calculateSerializeBufferSize() const; ///fills the dataBuffer and returns the struct name (and 0 on failure) - virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const; + virtual const char* serialize(void* dataBuffer, class btSerializer* serializer) const; //virtual void serializeSingleObject(class btSerializer* serializer) const; - - }; - - - -#endif //_BT_SOFT_BODY_H +#endif //_BT_SOFT_BODY_H diff --git a/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp b/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp index ab84bddf2..750718f57 100644 --- a/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp +++ b/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btSoftBodyConcaveCollisionAlgorithm.h" #include "BulletCollision/CollisionDispatch/btCollisionObject.h" #include "BulletCollision/CollisionShapes/btMultiSphereShape.h" @@ -27,34 +26,28 @@ subject to the following restrictions: #include "BulletCollision/CollisionShapes/btConvexHullShape.h" #include "BulletCollision/CollisionDispatch/btCollisionObjectWrapper.h" - #include "LinearMath/btIDebugDraw.h" #include "BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.h" #include "BulletSoftBody/btSoftBody.h" -#define BT_SOFTBODY_TRIANGLE_EXTRUSION btScalar(0.06)//make this configurable +#define BT_SOFTBODY_TRIANGLE_EXTRUSION btScalar(0.06) //make this configurable -btSoftBodyConcaveCollisionAlgorithm::btSoftBodyConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped) -: btCollisionAlgorithm(ci), -m_isSwapped(isSwapped), -m_btSoftBodyTriangleCallback(ci.m_dispatcher1,body0Wrap,body1Wrap,isSwapped) +btSoftBodyConcaveCollisionAlgorithm::btSoftBodyConcaveCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, bool isSwapped) + : btCollisionAlgorithm(ci), + m_isSwapped(isSwapped), + m_btSoftBodyTriangleCallback(ci.m_dispatcher1, body0Wrap, body1Wrap, isSwapped) { } - - btSoftBodyConcaveCollisionAlgorithm::~btSoftBodyConcaveCollisionAlgorithm() { } - - -btSoftBodyTriangleCallback::btSoftBodyTriangleCallback(btDispatcher* dispatcher,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped): -m_dispatcher(dispatcher), -m_dispatchInfoPtr(0) +btSoftBodyTriangleCallback::btSoftBodyTriangleCallback(btDispatcher* dispatcher, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, bool isSwapped) : m_dispatcher(dispatcher), + m_dispatchInfoPtr(0) { - m_softBody = (isSwapped? (btSoftBody*)body1Wrap->getCollisionObject():(btSoftBody*)body0Wrap->getCollisionObject()); - m_triBody = isSwapped? body0Wrap->getCollisionObject():body1Wrap->getCollisionObject(); + m_softBody = (isSwapped ? (btSoftBody*)body1Wrap->getCollisionObject() : (btSoftBody*)body0Wrap->getCollisionObject()); + m_triBody = isSwapped ? body0Wrap->getCollisionObject() : body1Wrap->getCollisionObject(); // // create the manifold from the dispatcher 'manifold pool' @@ -68,46 +61,42 @@ btSoftBodyTriangleCallback::~btSoftBodyTriangleCallback() { clearCache(); // m_dispatcher->releaseManifold( m_manifoldPtr ); - } - -void btSoftBodyTriangleCallback::clearCache() +void btSoftBodyTriangleCallback::clearCache() { - for (int i=0;im_childShape); - m_softBody->getWorldInfo()->m_sparsesdf.RemoveReferences(tmp->m_childShape);//necessary? + m_softBody->getWorldInfo()->m_sparsesdf.RemoveReferences(tmp->m_childShape); //necessary? delete tmp->m_childShape; } m_shapeCache.clear(); } - -void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle,int partId, int triangleIndex) +void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle, int partId, int triangleIndex) { //just for debugging purposes //printf("triangle %d",m_triangleCount++); - + btCollisionAlgorithmConstructionInfo ci; ci.m_dispatcher1 = m_dispatcher; ///debug drawing of the overlapping triangles - if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() &btIDebugDraw::DBG_DrawWireframe)) + if (m_dispatchInfoPtr && m_dispatchInfoPtr->m_debugDraw && (m_dispatchInfoPtr->m_debugDraw->getDebugMode() & btIDebugDraw::DBG_DrawWireframe)) { - btVector3 color(1,1,0); + btVector3 color(1, 1, 0); const btTransform& tr = m_triBody->getWorldTransform(); - m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]),tr(triangle[1]),color); - m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]),tr(triangle[2]),color); - m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]),tr(triangle[0]),color); + m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]), tr(triangle[1]), color); + m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]), tr(triangle[2]), color); + m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]), tr(triangle[0]), color); } - btTriIndex triIndex(partId,triangleIndex,0); + btTriIndex triIndex(partId, triangleIndex, 0); btHashKey triKey(triIndex.getUid()); - btTriIndex* shapeIndex = m_shapeCache[triKey]; if (shapeIndex) { @@ -117,82 +106,73 @@ void btSoftBodyTriangleCallback::processTriangle(btVector3* triangle,int partId, //copy over user pointers to temporary shape tm->setUserPointer(m_triBody->getCollisionShape()->getUserPointer()); - btCollisionObjectWrapper softBody(0,m_softBody->getCollisionShape(),m_softBody,m_softBody->getWorldTransform(),-1,-1); + btCollisionObjectWrapper softBody(0, m_softBody->getCollisionShape(), m_softBody, m_softBody->getWorldTransform(), -1, -1); //btCollisionObjectWrapper triBody(0,tm, ob, btTransform::getIdentity());//ob->getWorldTransform());//?? - btCollisionObjectWrapper triBody(0,tm, m_triBody, m_triBody->getWorldTransform(),partId, triangleIndex); + btCollisionObjectWrapper triBody(0, tm, m_triBody, m_triBody->getWorldTransform(), partId, triangleIndex); ebtDispatcherQueryType algoType = m_resultOut->m_closestPointDistanceThreshold > 0 ? BT_CLOSEST_POINT_ALGORITHMS : BT_CONTACT_POINT_ALGORITHMS; - btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(&softBody,&triBody,0, algoType);//m_manifoldPtr); + btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(&softBody, &triBody, 0, algoType); //m_manifoldPtr); - colAlgo->processCollision(&softBody,&triBody,*m_dispatchInfoPtr,m_resultOut); + colAlgo->processCollision(&softBody, &triBody, *m_dispatchInfoPtr, m_resultOut); colAlgo->~btCollisionAlgorithm(); ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo); - + return; } - //aabb filter is already applied! + //aabb filter is already applied! //btCollisionObject* colObj = static_cast(m_convexProxy->m_clientObject); // if (m_softBody->getCollisionShape()->getShapeType()== { // btVector3 other; - btVector3 normal = (triangle[1]-triangle[0]).cross(triangle[2]-triangle[0]); + btVector3 normal = (triangle[1] - triangle[0]).cross(triangle[2] - triangle[0]); normal.normalize(); - normal*= BT_SOFTBODY_TRIANGLE_EXTRUSION; + normal *= BT_SOFTBODY_TRIANGLE_EXTRUSION; // other=(triangle[0]+triangle[1]+triangle[2])*0.333333f; // other+=normal*22.f; - btVector3 pts[6] = {triangle[0]+normal, - triangle[1]+normal, - triangle[2]+normal, - triangle[0]-normal, - triangle[1]-normal, - triangle[2]-normal}; - - btConvexHullShape* tm = new btConvexHullShape(&pts[0].getX(),6); + btVector3 pts[6] = {triangle[0] + normal, + triangle[1] + normal, + triangle[2] + normal, + triangle[0] - normal, + triangle[1] - normal, + triangle[2] - normal}; + btConvexHullShape* tm = new btConvexHullShape(&pts[0].getX(), 6); // btBU_Simplex1to4 tm(triangle[0],triangle[1],triangle[2],other); - //btTriangleShape tm(triangle[0],triangle[1],triangle[2]); + //btTriangleShape tm(triangle[0],triangle[1],triangle[2]); // tm.setMargin(m_collisionMarginTriangle); //copy over user pointers to temporary shape tm->setUserPointer(m_triBody->getCollisionShape()->getUserPointer()); - - btCollisionObjectWrapper softBody(0,m_softBody->getCollisionShape(),m_softBody,m_softBody->getWorldTransform(),-1,-1); - btCollisionObjectWrapper triBody(0,tm, m_triBody, m_triBody->getWorldTransform(),partId, triangleIndex);//btTransform::getIdentity());//?? + btCollisionObjectWrapper softBody(0, m_softBody->getCollisionShape(), m_softBody, m_softBody->getWorldTransform(), -1, -1); + btCollisionObjectWrapper triBody(0, tm, m_triBody, m_triBody->getWorldTransform(), partId, triangleIndex); //btTransform::getIdentity());//?? ebtDispatcherQueryType algoType = m_resultOut->m_closestPointDistanceThreshold > 0 ? BT_CLOSEST_POINT_ALGORITHMS : BT_CONTACT_POINT_ALGORITHMS; - btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(&softBody,&triBody,0, algoType);//m_manifoldPtr); + btCollisionAlgorithm* colAlgo = ci.m_dispatcher1->findAlgorithm(&softBody, &triBody, 0, algoType); //m_manifoldPtr); - colAlgo->processCollision(&softBody,&triBody,*m_dispatchInfoPtr,m_resultOut); + colAlgo->processCollision(&softBody, &triBody, *m_dispatchInfoPtr, m_resultOut); colAlgo->~btCollisionAlgorithm(); ci.m_dispatcher1->freeCollisionAlgorithm(colAlgo); triIndex.m_childShape = tm; - m_shapeCache.insert(triKey,triIndex); - + m_shapeCache.insert(triKey, triIndex); } - - - } - - -void btSoftBodyTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle,const btCollisionObjectWrapper* triBodyWrap, const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +void btSoftBodyTriangleCallback::setTimeStepAndCounters(btScalar collisionMarginTriangle, const btCollisionObjectWrapper* triBodyWrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { m_dispatchInfoPtr = &dispatchInfo; - m_collisionMarginTriangle = collisionMarginTriangle+btScalar(BT_SOFTBODY_TRIANGLE_EXTRUSION); + m_collisionMarginTriangle = collisionMarginTriangle + btScalar(BT_SOFTBODY_TRIANGLE_EXTRUSION); m_resultOut = resultOut; - - btVector3 aabbWorldSpaceMin,aabbWorldSpaceMax; - m_softBody->getAabb(aabbWorldSpaceMin,aabbWorldSpaceMax); - btVector3 halfExtents = (aabbWorldSpaceMax-aabbWorldSpaceMin)*btScalar(0.5); - btVector3 softBodyCenter = (aabbWorldSpaceMax+aabbWorldSpaceMin)*btScalar(0.5); + btVector3 aabbWorldSpaceMin, aabbWorldSpaceMax; + m_softBody->getAabb(aabbWorldSpaceMin, aabbWorldSpaceMax); + btVector3 halfExtents = (aabbWorldSpaceMax - aabbWorldSpaceMin) * btScalar(0.5); + btVector3 softBodyCenter = (aabbWorldSpaceMax + aabbWorldSpaceMin) * btScalar(0.5); btTransform softTransform; softTransform.setIdentity(); @@ -200,56 +180,45 @@ void btSoftBodyTriangleCallback::setTimeStepAndCounters(btScalar collisionMargin btTransform convexInTriangleSpace; convexInTriangleSpace = triBodyWrap->getWorldTransform().inverse() * softTransform; - btTransformAabb(halfExtents,m_collisionMarginTriangle,convexInTriangleSpace,m_aabbMin,m_aabbMax); + btTransformAabb(halfExtents, m_collisionMarginTriangle, convexInTriangleSpace, m_aabbMin, m_aabbMax); } void btSoftBodyConcaveCollisionAlgorithm::clearCache() { m_btSoftBodyTriangleCallback.clearCache(); - } -void btSoftBodyConcaveCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +void btSoftBodyConcaveCollisionAlgorithm::processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { - - //btCollisionObject* convexBody = m_isSwapped ? body1 : body0; const btCollisionObjectWrapper* triBody = m_isSwapped ? body0Wrap : body1Wrap; if (triBody->getCollisionShape()->isConcave()) { - - - const btCollisionObject* triOb = triBody->getCollisionObject(); - const btConcaveShape* concaveShape = static_cast( triOb->getCollisionShape()); + const btCollisionObject* triOb = triBody->getCollisionObject(); + const btConcaveShape* concaveShape = static_cast(triOb->getCollisionShape()); // if (convexBody->getCollisionShape()->isConvex()) { btScalar collisionMarginTriangle = concaveShape->getMargin(); // resultOut->setPersistentManifold(m_btSoftBodyTriangleCallback.m_manifoldPtr); - m_btSoftBodyTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle,triBody,dispatchInfo,resultOut); + m_btSoftBodyTriangleCallback.setTimeStepAndCounters(collisionMarginTriangle, triBody, dispatchInfo, resultOut); - - concaveShape->processAllTriangles( &m_btSoftBodyTriangleCallback,m_btSoftBodyTriangleCallback.getAabbMin(),m_btSoftBodyTriangleCallback.getAabbMax()); + concaveShape->processAllTriangles(&m_btSoftBodyTriangleCallback, m_btSoftBodyTriangleCallback.getAabbMin(), m_btSoftBodyTriangleCallback.getAabbMax()); // resultOut->refreshContactPoints(); - } - } - } - -btScalar btSoftBodyConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +btScalar btSoftBodyConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { (void)resultOut; (void)dispatchInfo; btCollisionObject* convexbody = m_isSwapped ? body1 : body0; btCollisionObject* triBody = m_isSwapped ? body0 : body1; - //quick approximation using raycast, todo: hook up to the continuous collision detection (one of the btConvexCast) //only perform CCD above a certain threshold, this prevents blocking on the long run @@ -268,25 +237,23 @@ btScalar btSoftBodyConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionO btTransform convexFromLocal = triInv * convexbody->getWorldTransform(); btTransform convexToLocal = triInv * convexbody->getInterpolationWorldTransform(); - struct LocalTriangleSphereCastCallback : public btTriangleCallback + struct LocalTriangleSphereCastCallback : public btTriangleCallback { btTransform m_ccdSphereFromTrans; btTransform m_ccdSphereToTrans; - btTransform m_meshTransform; + btTransform m_meshTransform; - btScalar m_ccdSphereRadius; - btScalar m_hitFraction; + btScalar m_ccdSphereRadius; + btScalar m_hitFraction; - - LocalTriangleSphereCastCallback(const btTransform& from,const btTransform& to,btScalar ccdSphereRadius,btScalar hitFraction) - :m_ccdSphereFromTrans(from), - m_ccdSphereToTrans(to), - m_ccdSphereRadius(ccdSphereRadius), - m_hitFraction(hitFraction) - { + LocalTriangleSphereCastCallback(const btTransform& from, const btTransform& to, btScalar ccdSphereRadius, btScalar hitFraction) + : m_ccdSphereFromTrans(from), + m_ccdSphereToTrans(to), + m_ccdSphereRadius(ccdSphereRadius), + m_hitFraction(hitFraction) + { } - virtual void processTriangle(btVector3* triangle, int partId, int triangleIndex) { (void)partId; @@ -296,29 +263,23 @@ btScalar btSoftBodyConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionO ident.setIdentity(); btConvexCast::CastResult castResult; castResult.m_fraction = m_hitFraction; - btSphereShape pointShape(m_ccdSphereRadius); - btTriangleShape triShape(triangle[0],triangle[1],triangle[2]); - btVoronoiSimplexSolver simplexSolver; - btSubsimplexConvexCast convexCaster(&pointShape,&triShape,&simplexSolver); + btSphereShape pointShape(m_ccdSphereRadius); + btTriangleShape triShape(triangle[0], triangle[1], triangle[2]); + btVoronoiSimplexSolver simplexSolver; + btSubsimplexConvexCast convexCaster(&pointShape, &triShape, &simplexSolver); //GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver); //ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0); //local space? - if (convexCaster.calcTimeOfImpact(m_ccdSphereFromTrans,m_ccdSphereToTrans, - ident,ident,castResult)) + if (convexCaster.calcTimeOfImpact(m_ccdSphereFromTrans, m_ccdSphereToTrans, + ident, ident, castResult)) { if (m_hitFraction > castResult.m_fraction) m_hitFraction = castResult.m_fraction; } - } - }; - - - - if (triBody->getCollisionShape()->isConcave()) { btVector3 rayAabbMin = convexFromLocal.getOrigin(); @@ -326,33 +287,30 @@ btScalar btSoftBodyConcaveCollisionAlgorithm::calculateTimeOfImpact(btCollisionO btVector3 rayAabbMax = convexFromLocal.getOrigin(); rayAabbMax.setMax(convexToLocal.getOrigin()); btScalar ccdRadius0 = convexbody->getCcdSweptSphereRadius(); - rayAabbMin -= btVector3(ccdRadius0,ccdRadius0,ccdRadius0); - rayAabbMax += btVector3(ccdRadius0,ccdRadius0,ccdRadius0); + rayAabbMin -= btVector3(ccdRadius0, ccdRadius0, ccdRadius0); + rayAabbMax += btVector3(ccdRadius0, ccdRadius0, ccdRadius0); - btScalar curHitFraction = btScalar(1.); //is this available? - LocalTriangleSphereCastCallback raycastCallback(convexFromLocal,convexToLocal, - convexbody->getCcdSweptSphereRadius(),curHitFraction); + btScalar curHitFraction = btScalar(1.); //is this available? + LocalTriangleSphereCastCallback raycastCallback(convexFromLocal, convexToLocal, + convexbody->getCcdSweptSphereRadius(), curHitFraction); raycastCallback.m_hitFraction = convexbody->getHitFraction(); btCollisionObject* concavebody = triBody; - btConcaveShape* triangleMesh = (btConcaveShape*) concavebody->getCollisionShape(); + btConcaveShape* triangleMesh = (btConcaveShape*)concavebody->getCollisionShape(); if (triangleMesh) { - triangleMesh->processAllTriangles(&raycastCallback,rayAabbMin,rayAabbMax); + triangleMesh->processAllTriangles(&raycastCallback, rayAabbMin, rayAabbMax); } - - if (raycastCallback.m_hitFraction < convexbody->getHitFraction()) { - convexbody->setHitFraction( raycastCallback.m_hitFraction); + convexbody->setHitFraction(raycastCallback.m_hitFraction); return raycastCallback.m_hitFraction; } } return btScalar(1.); - } diff --git a/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h b/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h index 11c7b88f9..3adedbd80 100644 --- a/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h +++ b/src/BulletSoftBody/btSoftBodyConcaveCollisionAlgorithm.h @@ -29,63 +29,62 @@ class btCollisionShape; #include "LinearMath/btHashMap.h" -#include "BulletCollision/BroadphaseCollision/btQuantizedBvh.h" //for definition of MAX_NUM_PARTS_IN_BITS +#include "BulletCollision/BroadphaseCollision/btQuantizedBvh.h" //for definition of MAX_NUM_PARTS_IN_BITS struct btTriIndex { int m_PartIdTriangleIndex; - class btCollisionShape* m_childShape; + class btCollisionShape* m_childShape; - btTriIndex(int partId,int triangleIndex,btCollisionShape* shape) + btTriIndex(int partId, int triangleIndex, btCollisionShape* shape) { - m_PartIdTriangleIndex = (partId<<(31-MAX_NUM_PARTS_IN_BITS)) | triangleIndex; + m_PartIdTriangleIndex = (partId << (31 - MAX_NUM_PARTS_IN_BITS)) | triangleIndex; m_childShape = shape; } - int getTriangleIndex() const + int getTriangleIndex() const { // Get only the lower bits where the triangle index is stored unsigned int x = 0; - unsigned int y = (~(x&0))<<(31-MAX_NUM_PARTS_IN_BITS); - return (m_PartIdTriangleIndex&~(y)); + unsigned int y = (~(x & 0)) << (31 - MAX_NUM_PARTS_IN_BITS); + return (m_PartIdTriangleIndex & ~(y)); } - int getPartId() const + int getPartId() const { // Get only the highest bits where the part index is stored - return (m_PartIdTriangleIndex>>(31-MAX_NUM_PARTS_IN_BITS)); + return (m_PartIdTriangleIndex >> (31 - MAX_NUM_PARTS_IN_BITS)); } - int getUid() const + int getUid() const { return m_PartIdTriangleIndex; } }; - ///For each triangle in the concave mesh that overlaps with the AABB of a soft body (m_softBody), processTriangle is called. class btSoftBodyTriangleCallback : public btTriangleCallback { btSoftBody* m_softBody; const btCollisionObject* m_triBody; - btVector3 m_aabbMin; - btVector3 m_aabbMax ; + btVector3 m_aabbMin; + btVector3 m_aabbMax; btManifoldResult* m_resultOut; - btDispatcher* m_dispatcher; + btDispatcher* m_dispatcher; const btDispatcherInfo* m_dispatchInfoPtr; btScalar m_collisionMarginTriangle; - btHashMap,btTriIndex> m_shapeCache; + btHashMap, btTriIndex> m_shapeCache; public: - int m_triangleCount; + int m_triangleCount; // btPersistentManifold* m_manifoldPtr; - btSoftBodyTriangleCallback(btDispatcher* dispatcher,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped); + btSoftBodyTriangleCallback(btDispatcher* dispatcher, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, bool isSwapped); - void setTimeStepAndCounters(btScalar collisionMarginTriangle,const btCollisionObjectWrapper* triObjWrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + void setTimeStepAndCounters(btScalar collisionMarginTriangle, const btCollisionObjectWrapper* triObjWrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); virtual ~btSoftBodyTriangleCallback(); @@ -101,55 +100,48 @@ public: { return m_aabbMax; } - }; - - - /// btSoftBodyConcaveCollisionAlgorithm supports collision between soft body shapes and (concave) trianges meshes. -class btSoftBodyConcaveCollisionAlgorithm : public btCollisionAlgorithm +class btSoftBodyConcaveCollisionAlgorithm : public btCollisionAlgorithm { - - bool m_isSwapped; + bool m_isSwapped; btSoftBodyTriangleCallback m_btSoftBodyTriangleCallback; public: - - btSoftBodyConcaveCollisionAlgorithm( const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,bool isSwapped); + btSoftBodyConcaveCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, bool isSwapped); virtual ~btSoftBodyConcaveCollisionAlgorithm(); - virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) { //we don't add any manifolds } - void clearCache(); + void clearCache(); - struct CreateFunc :public btCollisionAlgorithmCreateFunc + struct CreateFunc : public btCollisionAlgorithmCreateFunc { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSoftBodyConcaveCollisionAlgorithm)); - return new(mem) btSoftBodyConcaveCollisionAlgorithm(ci,body0Wrap,body1Wrap,false); + return new (mem) btSoftBodyConcaveCollisionAlgorithm(ci, body0Wrap, body1Wrap, false); } }; - struct SwappedCreateFunc :public btCollisionAlgorithmCreateFunc + struct SwappedCreateFunc : public btCollisionAlgorithmCreateFunc { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSoftBodyConcaveCollisionAlgorithm)); - return new(mem) btSoftBodyConcaveCollisionAlgorithm(ci,body0Wrap,body1Wrap,true); + return new (mem) btSoftBodyConcaveCollisionAlgorithm(ci, body0Wrap, body1Wrap, true); } }; - }; -#endif //BT_SOFT_BODY_CONCAVE_COLLISION_ALGORITHM_H +#endif //BT_SOFT_BODY_CONCAVE_COLLISION_ALGORITHM_H diff --git a/src/BulletSoftBody/btSoftBodyData.h b/src/BulletSoftBody/btSoftBodyData.h index 87d8841cf..cec6f401e 100644 --- a/src/BulletSoftBody/btSoftBodyData.h +++ b/src/BulletSoftBody/btSoftBodyData.h @@ -19,199 +19,194 @@ subject to the following restrictions: #include "BulletCollision/CollisionDispatch/btCollisionObject.h" #include "BulletDynamics/Dynamics/btRigidBody.h" - -struct SoftBodyMaterialData +struct SoftBodyMaterialData { - float m_linearStiffness; - float m_angularStiffness; - float m_volumeStiffness; - int m_flags; + float m_linearStiffness; + float m_angularStiffness; + float m_volumeStiffness; + int m_flags; }; -struct SoftBodyNodeData +struct SoftBodyNodeData { - SoftBodyMaterialData *m_material; - btVector3FloatData m_position; - btVector3FloatData m_previousPosition; - btVector3FloatData m_velocity; - btVector3FloatData m_accumulatedForce; - btVector3FloatData m_normal; - float m_inverseMass; - float m_area; - int m_attach; - int m_pad; + SoftBodyMaterialData *m_material; + btVector3FloatData m_position; + btVector3FloatData m_previousPosition; + btVector3FloatData m_velocity; + btVector3FloatData m_accumulatedForce; + btVector3FloatData m_normal; + float m_inverseMass; + float m_area; + int m_attach; + int m_pad; }; -struct SoftBodyLinkData +struct SoftBodyLinkData { - SoftBodyMaterialData *m_material; - int m_nodeIndices[2]; // Node pointers - float m_restLength; // Rest length - int m_bbending; // Bending link + SoftBodyMaterialData *m_material; + int m_nodeIndices[2]; // Node pointers + float m_restLength; // Rest length + int m_bbending; // Bending link }; -struct SoftBodyFaceData +struct SoftBodyFaceData { - btVector3FloatData m_normal; // Normal - SoftBodyMaterialData *m_material; - int m_nodeIndices[3]; // Node pointers - float m_restArea; // Rest area -}; - -struct SoftBodyTetraData -{ - btVector3FloatData m_c0[4]; // gradients - SoftBodyMaterialData *m_material; - int m_nodeIndices[4]; // Node pointers - float m_restVolume; // Rest volume - float m_c1; // (4*kVST)/(im0+im1+im2+im3) - float m_c2; // m_c1/sum(|g0..3|^2) - int m_pad; + btVector3FloatData m_normal; // Normal + SoftBodyMaterialData *m_material; + int m_nodeIndices[3]; // Node pointers + float m_restArea; // Rest area }; -struct SoftRigidAnchorData +struct SoftBodyTetraData { - btMatrix3x3FloatData m_c0; // Impulse matrix - btVector3FloatData m_c1; // Relative anchor - btVector3FloatData m_localFrame; // Anchor position in body space - btRigidBodyData *m_rigidBody; - int m_nodeIndex; // Node pointer - float m_c2; // ima*dt + btVector3FloatData m_c0[4]; // gradients + SoftBodyMaterialData *m_material; + int m_nodeIndices[4]; // Node pointers + float m_restVolume; // Rest volume + float m_c1; // (4*kVST)/(im0+im1+im2+im3) + float m_c2; // m_c1/sum(|g0..3|^2) + int m_pad; }; - - -struct SoftBodyConfigData +struct SoftRigidAnchorData { - int m_aeroModel; // Aerodynamic model (default: V_Point) - float m_baumgarte; // Velocities correction factor (Baumgarte) - float m_damping; // Damping coefficient [0,1] - float m_drag; // Drag coefficient [0,+inf] - float m_lift; // Lift coefficient [0,+inf] - float m_pressure; // Pressure coefficient [-inf,+inf] - float m_volume; // Volume conversation coefficient [0,+inf] - float m_dynamicFriction; // Dynamic friction coefficient [0,1] - float m_poseMatch; // Pose matching coefficient [0,1] - float m_rigidContactHardness; // Rigid contacts hardness [0,1] - float m_kineticContactHardness; // Kinetic contacts hardness [0,1] - float m_softContactHardness; // Soft contacts hardness [0,1] - float m_anchorHardness; // Anchors hardness [0,1] - float m_softRigidClusterHardness; // Soft vs rigid hardness [0,1] (cluster only) - float m_softKineticClusterHardness; // Soft vs kinetic hardness [0,1] (cluster only) - float m_softSoftClusterHardness; // Soft vs soft hardness [0,1] (cluster only) - float m_softRigidClusterImpulseSplit; // Soft vs rigid impulse split [0,1] (cluster only) - float m_softKineticClusterImpulseSplit; // Soft vs rigid impulse split [0,1] (cluster only) - float m_softSoftClusterImpulseSplit; // Soft vs rigid impulse split [0,1] (cluster only) - float m_maxVolume; // Maximum volume ratio for pose - float m_timeScale; // Time scale - int m_velocityIterations; // Velocities solver iterations - int m_positionIterations; // Positions solver iterations - int m_driftIterations; // Drift solver iterations - int m_clusterIterations; // Cluster solver iterations - int m_collisionFlags; // Collisions flags + btMatrix3x3FloatData m_c0; // Impulse matrix + btVector3FloatData m_c1; // Relative anchor + btVector3FloatData m_localFrame; // Anchor position in body space + btRigidBodyData *m_rigidBody; + int m_nodeIndex; // Node pointer + float m_c2; // ima*dt }; -struct SoftBodyPoseData +struct SoftBodyConfigData { - btMatrix3x3FloatData m_rot; // Rotation - btMatrix3x3FloatData m_scale; // Scale - btMatrix3x3FloatData m_aqq; // Base scaling - btVector3FloatData m_com; // COM - - btVector3FloatData *m_positions; // Reference positions - float *m_weights; // Weights - int m_numPositions; - int m_numWeigts; - - int m_bvolume; // Is valid - int m_bframe; // Is frame - float m_restVolume; // Rest volume - int m_pad; + int m_aeroModel; // Aerodynamic model (default: V_Point) + float m_baumgarte; // Velocities correction factor (Baumgarte) + float m_damping; // Damping coefficient [0,1] + float m_drag; // Drag coefficient [0,+inf] + float m_lift; // Lift coefficient [0,+inf] + float m_pressure; // Pressure coefficient [-inf,+inf] + float m_volume; // Volume conversation coefficient [0,+inf] + float m_dynamicFriction; // Dynamic friction coefficient [0,1] + float m_poseMatch; // Pose matching coefficient [0,1] + float m_rigidContactHardness; // Rigid contacts hardness [0,1] + float m_kineticContactHardness; // Kinetic contacts hardness [0,1] + float m_softContactHardness; // Soft contacts hardness [0,1] + float m_anchorHardness; // Anchors hardness [0,1] + float m_softRigidClusterHardness; // Soft vs rigid hardness [0,1] (cluster only) + float m_softKineticClusterHardness; // Soft vs kinetic hardness [0,1] (cluster only) + float m_softSoftClusterHardness; // Soft vs soft hardness [0,1] (cluster only) + float m_softRigidClusterImpulseSplit; // Soft vs rigid impulse split [0,1] (cluster only) + float m_softKineticClusterImpulseSplit; // Soft vs rigid impulse split [0,1] (cluster only) + float m_softSoftClusterImpulseSplit; // Soft vs rigid impulse split [0,1] (cluster only) + float m_maxVolume; // Maximum volume ratio for pose + float m_timeScale; // Time scale + int m_velocityIterations; // Velocities solver iterations + int m_positionIterations; // Positions solver iterations + int m_driftIterations; // Drift solver iterations + int m_clusterIterations; // Cluster solver iterations + int m_collisionFlags; // Collisions flags }; -struct SoftBodyClusterData +struct SoftBodyPoseData { - btTransformFloatData m_framexform; - btMatrix3x3FloatData m_locii; - btMatrix3x3FloatData m_invwi; - btVector3FloatData m_com; - btVector3FloatData m_vimpulses[2]; - btVector3FloatData m_dimpulses[2]; - btVector3FloatData m_lv; - btVector3FloatData m_av; - - btVector3FloatData *m_framerefs; - int *m_nodeIndices; - float *m_masses; + btMatrix3x3FloatData m_rot; // Rotation + btMatrix3x3FloatData m_scale; // Scale + btMatrix3x3FloatData m_aqq; // Base scaling + btVector3FloatData m_com; // COM - int m_numFrameRefs; - int m_numNodes; - int m_numMasses; + btVector3FloatData *m_positions; // Reference positions + float *m_weights; // Weights + int m_numPositions; + int m_numWeigts; - float m_idmass; - float m_imass; - int m_nvimpulses; - int m_ndimpulses; - float m_ndamping; - float m_ldamping; - float m_adamping; - float m_matching; - float m_maxSelfCollisionImpulse; - float m_selfCollisionImpulseFactor; - int m_containsAnchor; - int m_collide; - int m_clusterIndex; + int m_bvolume; // Is valid + int m_bframe; // Is frame + float m_restVolume; // Rest volume + int m_pad; }; - -enum btSoftJointBodyType +struct SoftBodyClusterData { - BT_JOINT_SOFT_BODY_CLUSTER=1, + btTransformFloatData m_framexform; + btMatrix3x3FloatData m_locii; + btMatrix3x3FloatData m_invwi; + btVector3FloatData m_com; + btVector3FloatData m_vimpulses[2]; + btVector3FloatData m_dimpulses[2]; + btVector3FloatData m_lv; + btVector3FloatData m_av; + + btVector3FloatData *m_framerefs; + int *m_nodeIndices; + float *m_masses; + + int m_numFrameRefs; + int m_numNodes; + int m_numMasses; + + float m_idmass; + float m_imass; + int m_nvimpulses; + int m_ndimpulses; + float m_ndamping; + float m_ldamping; + float m_adamping; + float m_matching; + float m_maxSelfCollisionImpulse; + float m_selfCollisionImpulseFactor; + int m_containsAnchor; + int m_collide; + int m_clusterIndex; +}; + +enum btSoftJointBodyType +{ + BT_JOINT_SOFT_BODY_CLUSTER = 1, BT_JOINT_RIGID_BODY, BT_JOINT_COLLISION_OBJECT }; -struct btSoftBodyJointData +struct btSoftBodyJointData { - void *m_bodyA; - void *m_bodyB; - btVector3FloatData m_refs[2]; - float m_cfm; - float m_erp; - float m_split; - int m_delete; - btVector3FloatData m_relPosition[2];//linear - int m_bodyAtype; - int m_bodyBtype; - int m_jointType; - int m_pad; + void *m_bodyA; + void *m_bodyB; + btVector3FloatData m_refs[2]; + float m_cfm; + float m_erp; + float m_split; + int m_delete; + btVector3FloatData m_relPosition[2]; //linear + int m_bodyAtype; + int m_bodyBtype; + int m_jointType; + int m_pad; }; ///do not change those serialization structures, it requires an updated sBulletDNAstr/sBulletDNAstr64 -struct btSoftBodyFloatData +struct btSoftBodyFloatData { - btCollisionObjectFloatData m_collisionObjectData; + btCollisionObjectFloatData m_collisionObjectData; - SoftBodyPoseData *m_pose; - SoftBodyMaterialData **m_materials; - SoftBodyNodeData *m_nodes; - SoftBodyLinkData *m_links; - SoftBodyFaceData *m_faces; - SoftBodyTetraData *m_tetrahedra; - SoftRigidAnchorData *m_anchors; - SoftBodyClusterData *m_clusters; - btSoftBodyJointData *m_joints; + SoftBodyPoseData *m_pose; + SoftBodyMaterialData **m_materials; + SoftBodyNodeData *m_nodes; + SoftBodyLinkData *m_links; + SoftBodyFaceData *m_faces; + SoftBodyTetraData *m_tetrahedra; + SoftRigidAnchorData *m_anchors; + SoftBodyClusterData *m_clusters; + btSoftBodyJointData *m_joints; - int m_numMaterials; - int m_numNodes; - int m_numLinks; - int m_numFaces; - int m_numTetrahedra; - int m_numAnchors; - int m_numClusters; - int m_numJoints; - SoftBodyConfigData m_config; + int m_numMaterials; + int m_numNodes; + int m_numLinks; + int m_numFaces; + int m_numTetrahedra; + int m_numAnchors; + int m_numClusters; + int m_numJoints; + SoftBodyConfigData m_config; }; -#endif //BT_SOFTBODY_FLOAT_DATA - +#endif //BT_SOFTBODY_FLOAT_DATA diff --git a/src/BulletSoftBody/btSoftBodyHelpers.cpp b/src/BulletSoftBody/btSoftBodyHelpers.cpp index 51fcd16da..d0a9921d8 100644 --- a/src/BulletSoftBody/btSoftBodyHelpers.cpp +++ b/src/BulletSoftBody/btSoftBodyHelpers.cpp @@ -21,106 +21,111 @@ subject to the following restrictions: #include "LinearMath/btConvexHull.h" #include "LinearMath/btConvexHullComputer.h" - // -static void drawVertex( btIDebugDraw* idraw, - const btVector3& x,btScalar s,const btVector3& c) +static void drawVertex(btIDebugDraw* idraw, + const btVector3& x, btScalar s, const btVector3& c) { - idraw->drawLine(x-btVector3(s,0,0),x+btVector3(s,0,0),c); - idraw->drawLine(x-btVector3(0,s,0),x+btVector3(0,s,0),c); - idraw->drawLine(x-btVector3(0,0,s),x+btVector3(0,0,s),c); + idraw->drawLine(x - btVector3(s, 0, 0), x + btVector3(s, 0, 0), c); + idraw->drawLine(x - btVector3(0, s, 0), x + btVector3(0, s, 0), c); + idraw->drawLine(x - btVector3(0, 0, s), x + btVector3(0, 0, s), c); } // -static void drawBox( btIDebugDraw* idraw, - const btVector3& mins, - const btVector3& maxs, - const btVector3& color) +static void drawBox(btIDebugDraw* idraw, + const btVector3& mins, + const btVector3& maxs, + const btVector3& color) { - const btVector3 c[]={ btVector3(mins.x(),mins.y(),mins.z()), - btVector3(maxs.x(),mins.y(),mins.z()), - btVector3(maxs.x(),maxs.y(),mins.z()), - btVector3(mins.x(),maxs.y(),mins.z()), - btVector3(mins.x(),mins.y(),maxs.z()), - btVector3(maxs.x(),mins.y(),maxs.z()), - btVector3(maxs.x(),maxs.y(),maxs.z()), - btVector3(mins.x(),maxs.y(),maxs.z())}; - idraw->drawLine(c[0],c[1],color);idraw->drawLine(c[1],c[2],color); - idraw->drawLine(c[2],c[3],color);idraw->drawLine(c[3],c[0],color); - idraw->drawLine(c[4],c[5],color);idraw->drawLine(c[5],c[6],color); - idraw->drawLine(c[6],c[7],color);idraw->drawLine(c[7],c[4],color); - idraw->drawLine(c[0],c[4],color);idraw->drawLine(c[1],c[5],color); - idraw->drawLine(c[2],c[6],color);idraw->drawLine(c[3],c[7],color); + const btVector3 c[] = {btVector3(mins.x(), mins.y(), mins.z()), + btVector3(maxs.x(), mins.y(), mins.z()), + btVector3(maxs.x(), maxs.y(), mins.z()), + btVector3(mins.x(), maxs.y(), mins.z()), + btVector3(mins.x(), mins.y(), maxs.z()), + btVector3(maxs.x(), mins.y(), maxs.z()), + btVector3(maxs.x(), maxs.y(), maxs.z()), + btVector3(mins.x(), maxs.y(), maxs.z())}; + idraw->drawLine(c[0], c[1], color); + idraw->drawLine(c[1], c[2], color); + idraw->drawLine(c[2], c[3], color); + idraw->drawLine(c[3], c[0], color); + idraw->drawLine(c[4], c[5], color); + idraw->drawLine(c[5], c[6], color); + idraw->drawLine(c[6], c[7], color); + idraw->drawLine(c[7], c[4], color); + idraw->drawLine(c[0], c[4], color); + idraw->drawLine(c[1], c[5], color); + idraw->drawLine(c[2], c[6], color); + idraw->drawLine(c[3], c[7], color); } // -static void drawTree( btIDebugDraw* idraw, - const btDbvtNode* node, - int depth, - const btVector3& ncolor, - const btVector3& lcolor, - int mindepth, - int maxdepth) +static void drawTree(btIDebugDraw* idraw, + const btDbvtNode* node, + int depth, + const btVector3& ncolor, + const btVector3& lcolor, + int mindepth, + int maxdepth) { - if(node) + if (node) { - if(node->isinternal()&&((depthisinternal() && ((depth < maxdepth) || (maxdepth < 0))) { - drawTree(idraw,node->childs[0],depth+1,ncolor,lcolor,mindepth,maxdepth); - drawTree(idraw,node->childs[1],depth+1,ncolor,lcolor,mindepth,maxdepth); + drawTree(idraw, node->childs[0], depth + 1, ncolor, lcolor, mindepth, maxdepth); + drawTree(idraw, node->childs[1], depth + 1, ncolor, lcolor, mindepth, maxdepth); } - if(depth>=mindepth) + if (depth >= mindepth) { - const btScalar scl=(btScalar)(node->isinternal()?1:1); - const btVector3 mi=node->volume.Center()-node->volume.Extents()*scl; - const btVector3 mx=node->volume.Center()+node->volume.Extents()*scl; - drawBox(idraw,mi,mx,node->isleaf()?lcolor:ncolor); + const btScalar scl = (btScalar)(node->isinternal() ? 1 : 1); + const btVector3 mi = node->volume.Center() - node->volume.Extents() * scl; + const btVector3 mx = node->volume.Center() + node->volume.Extents() * scl; + drawBox(idraw, mi, mx, node->isleaf() ? lcolor : ncolor); } } } // template -static inline T sum(const btAlignedObjectArray& items) +static inline T sum(const btAlignedObjectArray& items) { - T v; - if(items.size()) + T v; + if (items.size()) { - v=items[0]; - for(int i=1,ni=items.size();i -static inline void add(btAlignedObjectArray& items,const Q& value) +template +static inline void add(btAlignedObjectArray& items, const Q& value) { - for(int i=0,ni=items.size();i -static inline void mul(btAlignedObjectArray& items,const Q& value) +template +static inline void mul(btAlignedObjectArray& items, const Q& value) { - for(int i=0,ni=items.size();i -static inline T average(const btAlignedObjectArray& items) +static inline T average(const btAlignedObjectArray& items) { - const btScalar n=(btScalar)(items.size()>0?items.size():1); - return(sum(items)/n); + const btScalar n = (btScalar)(items.size() > 0 ? items.size() : 1); + return (sum(items) / n); } #if 0 @@ -158,86 +163,84 @@ static btVector3 stresscolor(btScalar stress) #endif // -void btSoftBodyHelpers::Draw( btSoftBody* psb, - btIDebugDraw* idraw, - int drawflags) +void btSoftBodyHelpers::Draw(btSoftBody* psb, + btIDebugDraw* idraw, + int drawflags) { - const btScalar scl=(btScalar)0.1; - const btScalar nscl=scl*5; - const btVector3 lcolor=btVector3(0,0,0); - const btVector3 ncolor=btVector3(1,1,1); - const btVector3 ccolor=btVector3(1,0,0); - int i,j,nj; + const btScalar scl = (btScalar)0.1; + const btScalar nscl = scl * 5; + const btVector3 lcolor = btVector3(0, 0, 0); + const btVector3 ncolor = btVector3(1, 1, 1); + const btVector3 ccolor = btVector3(1, 0, 0); + int i, j, nj; - /* Clusters */ - if(0!=(drawflags&fDrawFlags::Clusters)) + /* Clusters */ + if (0 != (drawflags & fDrawFlags::Clusters)) { srand(1806); - for(i=0;im_clusters.size();++i) + for (i = 0; i < psb->m_clusters.size(); ++i) { - if(psb->m_clusters[i]->m_collide) + if (psb->m_clusters[i]->m_collide) { - btVector3 color( rand()/(btScalar)RAND_MAX, - rand()/(btScalar)RAND_MAX, - rand()/(btScalar)RAND_MAX); - color=color.normalized()*0.75; - btAlignedObjectArray vertices; + btVector3 color(rand() / (btScalar)RAND_MAX, + rand() / (btScalar)RAND_MAX, + rand() / (btScalar)RAND_MAX); + color = color.normalized() * 0.75; + btAlignedObjectArray vertices; vertices.resize(psb->m_clusters[i]->m_nodes.size()); - for(j=0,nj=vertices.size();jm_clusters[i]->m_nodes[j]->m_x; + for (j = 0, nj = vertices.size(); j < nj; ++j) + { + vertices[j] = psb->m_clusters[i]->m_nodes[j]->m_x; } #define USE_NEW_CONVEX_HULL_COMPUTER #ifdef USE_NEW_CONVEX_HULL_COMPUTER - btConvexHullComputer computer; + btConvexHullComputer computer; int stride = sizeof(btVector3); int count = vertices.size(); - btScalar shrink=0.f; - btScalar shrinkClamp=0.f; - computer.compute(&vertices[0].getX(),stride,count,shrink,shrinkClamp); - for (int i=0;igetNextEdgeOfFace(); + const btConvexHullComputer::Edge* firstEdge = &computer.edges[face]; + const btConvexHullComputer::Edge* edge = firstEdge->getNextEdgeOfFace(); int v0 = firstEdge->getSourceVertex(); int v1 = firstEdge->getTargetVertex(); - while (edge!=firstEdge) + while (edge != firstEdge) { int v2 = edge->getTargetVertex(); - idraw->drawTriangle(computer.vertices[v0],computer.vertices[v1],computer.vertices[v2],color,1); + idraw->drawTriangle(computer.vertices[v0], computer.vertices[v1], computer.vertices[v2], color, 1); edge = edge->getNextEdgeOfFace(); - v0=v1; - v1=v2; + v0 = v1; + v1 = v2; }; } #else - HullDesc hdsc(QF_TRIANGLES,vertices.size(),&vertices[0]); - HullResult hres; - HullLibrary hlib; - hdsc.mMaxVertices=vertices.size(); - hlib.CreateConvexHull(hdsc,hres); - const btVector3 center=average(hres.m_OutputVertices); - add(hres.m_OutputVertices,-center); - mul(hres.m_OutputVertices,(btScalar)1); - add(hres.m_OutputVertices,center); - for(j=0;j<(int)hres.mNumFaces;++j) + HullDesc hdsc(QF_TRIANGLES, vertices.size(), &vertices[0]); + HullResult hres; + HullLibrary hlib; + hdsc.mMaxVertices = vertices.size(); + hlib.CreateConvexHull(hdsc, hres); + const btVector3 center = average(hres.m_OutputVertices); + add(hres.m_OutputVertices, -center); + mul(hres.m_OutputVertices, (btScalar)1); + add(hres.m_OutputVertices, center); + for (j = 0; j < (int)hres.mNumFaces; ++j) { - const int idx[]={hres.m_Indices[j*3+0],hres.m_Indices[j*3+1],hres.m_Indices[j*3+2]}; + const int idx[] = {hres.m_Indices[j * 3 + 0], hres.m_Indices[j * 3 + 1], hres.m_Indices[j * 3 + 2]}; idraw->drawTriangle(hres.m_OutputVertices[idx[0]], - hres.m_OutputVertices[idx[1]], - hres.m_OutputVertices[idx[2]], - color,1); + hres.m_OutputVertices[idx[1]], + hres.m_OutputVertices[idx[2]], + color, 1); } hlib.ReleaseResult(hres); #endif - } - /* Velocities */ + /* Velocities */ #if 0 for(int j=0;jm_clusters[i].m_nodes.size();++j) { @@ -247,273 +250,269 @@ void btSoftBodyHelpers::Draw( btSoftBody* psb, idraw->drawLine(c.m_nodes[j]->m_x,c.m_nodes[j]->m_x+v,btVector3(1,0,0)); } #endif - /* Frame */ - // btSoftBody::Cluster& c=*psb->m_clusters[i]; - // idraw->drawLine(c.m_com,c.m_framexform*btVector3(10,0,0),btVector3(1,0,0)); - // idraw->drawLine(c.m_com,c.m_framexform*btVector3(0,10,0),btVector3(0,1,0)); - // idraw->drawLine(c.m_com,c.m_framexform*btVector3(0,0,10),btVector3(0,0,1)); + /* Frame */ + // btSoftBody::Cluster& c=*psb->m_clusters[i]; + // idraw->drawLine(c.m_com,c.m_framexform*btVector3(10,0,0),btVector3(1,0,0)); + // idraw->drawLine(c.m_com,c.m_framexform*btVector3(0,10,0),btVector3(0,1,0)); + // idraw->drawLine(c.m_com,c.m_framexform*btVector3(0,0,10),btVector3(0,0,1)); } } else { - /* Nodes */ - if(0!=(drawflags&fDrawFlags::Nodes)) + /* Nodes */ + if (0 != (drawflags & fDrawFlags::Nodes)) { - for(i=0;im_nodes.size();++i) + for (i = 0; i < psb->m_nodes.size(); ++i) { - const btSoftBody::Node& n=psb->m_nodes[i]; - if(0==(n.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue; - idraw->drawLine(n.m_x-btVector3(scl,0,0),n.m_x+btVector3(scl,0,0),btVector3(1,0,0)); - idraw->drawLine(n.m_x-btVector3(0,scl,0),n.m_x+btVector3(0,scl,0),btVector3(0,1,0)); - idraw->drawLine(n.m_x-btVector3(0,0,scl),n.m_x+btVector3(0,0,scl),btVector3(0,0,1)); + const btSoftBody::Node& n = psb->m_nodes[i]; + if (0 == (n.m_material->m_flags & btSoftBody::fMaterial::DebugDraw)) continue; + idraw->drawLine(n.m_x - btVector3(scl, 0, 0), n.m_x + btVector3(scl, 0, 0), btVector3(1, 0, 0)); + idraw->drawLine(n.m_x - btVector3(0, scl, 0), n.m_x + btVector3(0, scl, 0), btVector3(0, 1, 0)); + idraw->drawLine(n.m_x - btVector3(0, 0, scl), n.m_x + btVector3(0, 0, scl), btVector3(0, 0, 1)); } } - /* Links */ - if(0!=(drawflags&fDrawFlags::Links)) + /* Links */ + if (0 != (drawflags & fDrawFlags::Links)) { - for(i=0;im_links.size();++i) + for (i = 0; i < psb->m_links.size(); ++i) { - const btSoftBody::Link& l=psb->m_links[i]; - if(0==(l.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue; - idraw->drawLine(l.m_n[0]->m_x,l.m_n[1]->m_x,lcolor); + const btSoftBody::Link& l = psb->m_links[i]; + if (0 == (l.m_material->m_flags & btSoftBody::fMaterial::DebugDraw)) continue; + idraw->drawLine(l.m_n[0]->m_x, l.m_n[1]->m_x, lcolor); } } - /* Normals */ - if(0!=(drawflags&fDrawFlags::Normals)) + /* Normals */ + if (0 != (drawflags & fDrawFlags::Normals)) { - for(i=0;im_nodes.size();++i) + for (i = 0; i < psb->m_nodes.size(); ++i) { - const btSoftBody::Node& n=psb->m_nodes[i]; - if(0==(n.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue; - const btVector3 d=n.m_n*nscl; - idraw->drawLine(n.m_x,n.m_x+d,ncolor); - idraw->drawLine(n.m_x,n.m_x-d,ncolor*0.5); + const btSoftBody::Node& n = psb->m_nodes[i]; + if (0 == (n.m_material->m_flags & btSoftBody::fMaterial::DebugDraw)) continue; + const btVector3 d = n.m_n * nscl; + idraw->drawLine(n.m_x, n.m_x + d, ncolor); + idraw->drawLine(n.m_x, n.m_x - d, ncolor * 0.5); } } - /* Contacts */ - if(0!=(drawflags&fDrawFlags::Contacts)) + /* Contacts */ + if (0 != (drawflags & fDrawFlags::Contacts)) { - static const btVector3 axis[]={btVector3(1,0,0), - btVector3(0,1,0), - btVector3(0,0,1)}; - for(i=0;im_rcontacts.size();++i) - { - const btSoftBody::RContact& c=psb->m_rcontacts[i]; - const btVector3 o= c.m_node->m_x-c.m_cti.m_normal* - (btDot(c.m_node->m_x,c.m_cti.m_normal)+c.m_cti.m_offset); - const btVector3 x=btCross(c.m_cti.m_normal,axis[c.m_cti.m_normal.minAxis()]).normalized(); - const btVector3 y=btCross(x,c.m_cti.m_normal).normalized(); - idraw->drawLine(o-x*nscl,o+x*nscl,ccolor); - idraw->drawLine(o-y*nscl,o+y*nscl,ccolor); - idraw->drawLine(o,o+c.m_cti.m_normal*nscl*3,btVector3(1,1,0)); + static const btVector3 axis[] = {btVector3(1, 0, 0), + btVector3(0, 1, 0), + btVector3(0, 0, 1)}; + for (i = 0; i < psb->m_rcontacts.size(); ++i) + { + const btSoftBody::RContact& c = psb->m_rcontacts[i]; + const btVector3 o = c.m_node->m_x - c.m_cti.m_normal * + (btDot(c.m_node->m_x, c.m_cti.m_normal) + c.m_cti.m_offset); + const btVector3 x = btCross(c.m_cti.m_normal, axis[c.m_cti.m_normal.minAxis()]).normalized(); + const btVector3 y = btCross(x, c.m_cti.m_normal).normalized(); + idraw->drawLine(o - x * nscl, o + x * nscl, ccolor); + idraw->drawLine(o - y * nscl, o + y * nscl, ccolor); + idraw->drawLine(o, o + c.m_cti.m_normal * nscl * 3, btVector3(1, 1, 0)); } } - /* Faces */ - if(0!=(drawflags&fDrawFlags::Faces)) + /* Faces */ + if (0 != (drawflags & fDrawFlags::Faces)) + { + const btScalar scl = (btScalar)0.8; + const btScalar alp = (btScalar)1; + const btVector3 col(0, (btScalar)0.7, 0); + for (i = 0; i < psb->m_faces.size(); ++i) + { + const btSoftBody::Face& f = psb->m_faces[i]; + if (0 == (f.m_material->m_flags & btSoftBody::fMaterial::DebugDraw)) continue; + const btVector3 x[] = {f.m_n[0]->m_x, f.m_n[1]->m_x, f.m_n[2]->m_x}; + const btVector3 c = (x[0] + x[1] + x[2]) / 3; + idraw->drawTriangle((x[0] - c) * scl + c, + (x[1] - c) * scl + c, + (x[2] - c) * scl + c, + col, alp); + } + } + /* Tetras */ + if (0 != (drawflags & fDrawFlags::Tetras)) + { + const btScalar scl = (btScalar)0.8; + const btScalar alp = (btScalar)1; + const btVector3 col((btScalar)0.3, (btScalar)0.3, (btScalar)0.7); + for (int i = 0; i < psb->m_tetras.size(); ++i) + { + const btSoftBody::Tetra& t = psb->m_tetras[i]; + if (0 == (t.m_material->m_flags & btSoftBody::fMaterial::DebugDraw)) continue; + const btVector3 x[] = {t.m_n[0]->m_x, t.m_n[1]->m_x, t.m_n[2]->m_x, t.m_n[3]->m_x}; + const btVector3 c = (x[0] + x[1] + x[2] + x[3]) / 4; + idraw->drawTriangle((x[0] - c) * scl + c, (x[1] - c) * scl + c, (x[2] - c) * scl + c, col, alp); + idraw->drawTriangle((x[0] - c) * scl + c, (x[1] - c) * scl + c, (x[3] - c) * scl + c, col, alp); + idraw->drawTriangle((x[1] - c) * scl + c, (x[2] - c) * scl + c, (x[3] - c) * scl + c, col, alp); + idraw->drawTriangle((x[2] - c) * scl + c, (x[0] - c) * scl + c, (x[3] - c) * scl + c, col, alp); + } + } + } + /* Anchors */ + if (0 != (drawflags & fDrawFlags::Anchors)) { - const btScalar scl=(btScalar)0.8; - const btScalar alp=(btScalar)1; - const btVector3 col(0,(btScalar)0.7,0); - for(i=0;im_faces.size();++i) + for (i = 0; i < psb->m_anchors.size(); ++i) { - const btSoftBody::Face& f=psb->m_faces[i]; - if(0==(f.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue; - const btVector3 x[]={f.m_n[0]->m_x,f.m_n[1]->m_x,f.m_n[2]->m_x}; - const btVector3 c=(x[0]+x[1]+x[2])/3; - idraw->drawTriangle((x[0]-c)*scl+c, - (x[1]-c)*scl+c, - (x[2]-c)*scl+c, - col,alp); - } - } - /* Tetras */ - if(0!=(drawflags&fDrawFlags::Tetras)) - { - const btScalar scl=(btScalar)0.8; - const btScalar alp=(btScalar)1; - const btVector3 col((btScalar)0.3,(btScalar)0.3,(btScalar)0.7); - for(int i=0;im_tetras.size();++i) - { - const btSoftBody::Tetra& t=psb->m_tetras[i]; - if(0==(t.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue; - const btVector3 x[]={t.m_n[0]->m_x,t.m_n[1]->m_x,t.m_n[2]->m_x,t.m_n[3]->m_x}; - const btVector3 c=(x[0]+x[1]+x[2]+x[3])/4; - idraw->drawTriangle((x[0]-c)*scl+c,(x[1]-c)*scl+c,(x[2]-c)*scl+c,col,alp); - idraw->drawTriangle((x[0]-c)*scl+c,(x[1]-c)*scl+c,(x[3]-c)*scl+c,col,alp); - idraw->drawTriangle((x[1]-c)*scl+c,(x[2]-c)*scl+c,(x[3]-c)*scl+c,col,alp); - idraw->drawTriangle((x[2]-c)*scl+c,(x[0]-c)*scl+c,(x[3]-c)*scl+c,col,alp); - } - } - } - /* Anchors */ - if(0!=(drawflags&fDrawFlags::Anchors)) - { - for(i=0;im_anchors.size();++i) - { - const btSoftBody::Anchor& a=psb->m_anchors[i]; - const btVector3 q=a.m_body->getWorldTransform()*a.m_local; - drawVertex(idraw,a.m_node->m_x,0.25,btVector3(1,0,0)); - drawVertex(idraw,q,0.25,btVector3(0,1,0)); - idraw->drawLine(a.m_node->m_x,q,btVector3(1,1,1)); + const btSoftBody::Anchor& a = psb->m_anchors[i]; + const btVector3 q = a.m_body->getWorldTransform() * a.m_local; + drawVertex(idraw, a.m_node->m_x, 0.25, btVector3(1, 0, 0)); + drawVertex(idraw, q, 0.25, btVector3(0, 1, 0)); + idraw->drawLine(a.m_node->m_x, q, btVector3(1, 1, 1)); } - for(i=0;im_nodes.size();++i) + for (i = 0; i < psb->m_nodes.size(); ++i) { - const btSoftBody::Node& n=psb->m_nodes[i]; - if(0==(n.m_material->m_flags&btSoftBody::fMaterial::DebugDraw)) continue; - if(n.m_im<=0) + const btSoftBody::Node& n = psb->m_nodes[i]; + if (0 == (n.m_material->m_flags & btSoftBody::fMaterial::DebugDraw)) continue; + if (n.m_im <= 0) { - drawVertex(idraw,n.m_x,0.25,btVector3(1,0,0)); + drawVertex(idraw, n.m_x, 0.25, btVector3(1, 0, 0)); } } } - - /* Notes */ - if(0!=(drawflags&fDrawFlags::Notes)) + /* Notes */ + if (0 != (drawflags & fDrawFlags::Notes)) { - for(i=0;im_notes.size();++i) + for (i = 0; i < psb->m_notes.size(); ++i) { - const btSoftBody::Note& n=psb->m_notes[i]; - btVector3 p=n.m_offset; - for(int j=0;jm_notes[i]; + btVector3 p = n.m_offset; + for (int j = 0; j < n.m_rank; ++j) { - p+=n.m_nodes[j]->m_x*n.m_coords[j]; + p += n.m_nodes[j]->m_x * n.m_coords[j]; } - idraw->draw3dText(p,n.m_text); + idraw->draw3dText(p, n.m_text); } } - /* Node tree */ - if(0!=(drawflags&fDrawFlags::NodeTree)) DrawNodeTree(psb,idraw); - /* Face tree */ - if(0!=(drawflags&fDrawFlags::FaceTree)) DrawFaceTree(psb,idraw); - /* Cluster tree */ - if(0!=(drawflags&fDrawFlags::ClusterTree)) DrawClusterTree(psb,idraw); - /* Joints */ - if(0!=(drawflags&fDrawFlags::Joints)) + /* Node tree */ + if (0 != (drawflags & fDrawFlags::NodeTree)) DrawNodeTree(psb, idraw); + /* Face tree */ + if (0 != (drawflags & fDrawFlags::FaceTree)) DrawFaceTree(psb, idraw); + /* Cluster tree */ + if (0 != (drawflags & fDrawFlags::ClusterTree)) DrawClusterTree(psb, idraw); + /* Joints */ + if (0 != (drawflags & fDrawFlags::Joints)) { - for(i=0;im_joints.size();++i) + for (i = 0; i < psb->m_joints.size(); ++i) { - const btSoftBody::Joint* pj=psb->m_joints[i]; - switch(pj->Type()) + const btSoftBody::Joint* pj = psb->m_joints[i]; + switch (pj->Type()) { - case btSoftBody::Joint::eType::Linear: + case btSoftBody::Joint::eType::Linear: { - const btSoftBody::LJoint* pjl=(const btSoftBody::LJoint*)pj; - const btVector3 a0=pj->m_bodies[0].xform()*pjl->m_refs[0]; - const btVector3 a1=pj->m_bodies[1].xform()*pjl->m_refs[1]; - idraw->drawLine(pj->m_bodies[0].xform().getOrigin(),a0,btVector3(1,1,0)); - idraw->drawLine(pj->m_bodies[1].xform().getOrigin(),a1,btVector3(0,1,1)); - drawVertex(idraw,a0,0.25,btVector3(1,1,0)); - drawVertex(idraw,a1,0.25,btVector3(0,1,1)); + const btSoftBody::LJoint* pjl = (const btSoftBody::LJoint*)pj; + const btVector3 a0 = pj->m_bodies[0].xform() * pjl->m_refs[0]; + const btVector3 a1 = pj->m_bodies[1].xform() * pjl->m_refs[1]; + idraw->drawLine(pj->m_bodies[0].xform().getOrigin(), a0, btVector3(1, 1, 0)); + idraw->drawLine(pj->m_bodies[1].xform().getOrigin(), a1, btVector3(0, 1, 1)); + drawVertex(idraw, a0, 0.25, btVector3(1, 1, 0)); + drawVertex(idraw, a1, 0.25, btVector3(0, 1, 1)); } break; - case btSoftBody::Joint::eType::Angular: + case btSoftBody::Joint::eType::Angular: { //const btSoftBody::AJoint* pja=(const btSoftBody::AJoint*)pj; - const btVector3 o0=pj->m_bodies[0].xform().getOrigin(); - const btVector3 o1=pj->m_bodies[1].xform().getOrigin(); - const btVector3 a0=pj->m_bodies[0].xform().getBasis()*pj->m_refs[0]; - const btVector3 a1=pj->m_bodies[1].xform().getBasis()*pj->m_refs[1]; - idraw->drawLine(o0,o0+a0*10,btVector3(1,1,0)); - idraw->drawLine(o0,o0+a1*10,btVector3(1,1,0)); - idraw->drawLine(o1,o1+a0*10,btVector3(0,1,1)); - idraw->drawLine(o1,o1+a1*10,btVector3(0,1,1)); + const btVector3 o0 = pj->m_bodies[0].xform().getOrigin(); + const btVector3 o1 = pj->m_bodies[1].xform().getOrigin(); + const btVector3 a0 = pj->m_bodies[0].xform().getBasis() * pj->m_refs[0]; + const btVector3 a1 = pj->m_bodies[1].xform().getBasis() * pj->m_refs[1]; + idraw->drawLine(o0, o0 + a0 * 10, btVector3(1, 1, 0)); + idraw->drawLine(o0, o0 + a1 * 10, btVector3(1, 1, 0)); + idraw->drawLine(o1, o1 + a0 * 10, btVector3(0, 1, 1)); + idraw->drawLine(o1, o1 + a1 * 10, btVector3(0, 1, 1)); break; } default: { } - - } + } } } } // -void btSoftBodyHelpers::DrawInfos( btSoftBody* psb, - btIDebugDraw* idraw, - bool masses, - bool areas, - bool /*stress*/) +void btSoftBodyHelpers::DrawInfos(btSoftBody* psb, + btIDebugDraw* idraw, + bool masses, + bool areas, + bool /*stress*/) { - for(int i=0;im_nodes.size();++i) + for (int i = 0; i < psb->m_nodes.size(); ++i) { - const btSoftBody::Node& n=psb->m_nodes[i]; - char text[2048]={0}; - char buff[1024]; - if(masses) + const btSoftBody::Node& n = psb->m_nodes[i]; + char text[2048] = {0}; + char buff[1024]; + if (masses) { - sprintf(buff," M(%.2f)",1/n.m_im); - strcat(text,buff); + sprintf(buff, " M(%.2f)", 1 / n.m_im); + strcat(text, buff); } - if(areas) + if (areas) { - sprintf(buff," A(%.2f)",n.m_area); - strcat(text,buff); + sprintf(buff, " A(%.2f)", n.m_area); + strcat(text, buff); } - if(text[0]) idraw->draw3dText(n.m_x,text); + if (text[0]) idraw->draw3dText(n.m_x, text); } } // -void btSoftBodyHelpers::DrawNodeTree( btSoftBody* psb, - btIDebugDraw* idraw, - int mindepth, - int maxdepth) +void btSoftBodyHelpers::DrawNodeTree(btSoftBody* psb, + btIDebugDraw* idraw, + int mindepth, + int maxdepth) { - drawTree(idraw,psb->m_ndbvt.m_root,0,btVector3(1,0,1),btVector3(1,1,1),mindepth,maxdepth); + drawTree(idraw, psb->m_ndbvt.m_root, 0, btVector3(1, 0, 1), btVector3(1, 1, 1), mindepth, maxdepth); } // -void btSoftBodyHelpers::DrawFaceTree( btSoftBody* psb, - btIDebugDraw* idraw, - int mindepth, - int maxdepth) +void btSoftBodyHelpers::DrawFaceTree(btSoftBody* psb, + btIDebugDraw* idraw, + int mindepth, + int maxdepth) { - drawTree(idraw,psb->m_fdbvt.m_root,0,btVector3(0,1,0),btVector3(1,0,0),mindepth,maxdepth); + drawTree(idraw, psb->m_fdbvt.m_root, 0, btVector3(0, 1, 0), btVector3(1, 0, 0), mindepth, maxdepth); } // -void btSoftBodyHelpers::DrawClusterTree( btSoftBody* psb, - btIDebugDraw* idraw, - int mindepth, - int maxdepth) +void btSoftBodyHelpers::DrawClusterTree(btSoftBody* psb, + btIDebugDraw* idraw, + int mindepth, + int maxdepth) { - drawTree(idraw,psb->m_cdbvt.m_root,0,btVector3(0,1,1),btVector3(1,0,0),mindepth,maxdepth); + drawTree(idraw, psb->m_cdbvt.m_root, 0, btVector3(0, 1, 1), btVector3(1, 0, 0), mindepth, maxdepth); } - //The btSoftBody object from the BulletSDK includes an array of Nodes and Links. These links appear -// to be first set up to connect a node to between 5 and 6 of its neighbors [480 links], -//and then to the rest of the nodes after the execution of the Floyd-Warshall graph algorithm -//[another 930 links]. +// to be first set up to connect a node to between 5 and 6 of its neighbors [480 links], +//and then to the rest of the nodes after the execution of the Floyd-Warshall graph algorithm +//[another 930 links]. //The way the links are stored by default, we have a number of cases where adjacent links share a node in common -// - this leads to the creation of a data dependency through memory. -//The PSolve_Links() function reads and writes nodes as it iterates over each link. -//So, we now have the possibility of a data dependency between iteration X -//that processes link L with iteration X+1 that processes link L+1 -//because L and L+1 have one node in common, and iteration X updates the positions of that node, +// - this leads to the creation of a data dependency through memory. +//The PSolve_Links() function reads and writes nodes as it iterates over each link. +//So, we now have the possibility of a data dependency between iteration X +//that processes link L with iteration X+1 that processes link L+1 +//because L and L+1 have one node in common, and iteration X updates the positions of that node, //and iteration X+1 reads in the position of that shared node. // -//Such a memory dependency limits the ability of a modern CPU to speculate beyond -//a certain point because it has to respect a possible dependency -//- this prevents the CPU from making full use of its out-of-order resources. -//If we re-order the links such that we minimize the cases where a link L and L+1 share a common node, -//we create a temporal gap between when the node position is written, -//and when it is subsequently read. This in turn allows the CPU to continue execution without -//risking a dependency violation. Such a reordering would result in significant speedups on -//modern CPUs with lots of execution resources. -//In our testing, we see it have a tremendous impact not only on the A7, -//but also on all x86 cores that ship with modern Macs. -//The attached source file includes a single function (ReoptimizeLinkOrder) which can be called on a -//btSoftBody object in the solveConstraints() function before the actual solver is invoked, +//Such a memory dependency limits the ability of a modern CPU to speculate beyond +//a certain point because it has to respect a possible dependency +//- this prevents the CPU from making full use of its out-of-order resources. +//If we re-order the links such that we minimize the cases where a link L and L+1 share a common node, +//we create a temporal gap between when the node position is written, +//and when it is subsequently read. This in turn allows the CPU to continue execution without +//risking a dependency violation. Such a reordering would result in significant speedups on +//modern CPUs with lots of execution resources. +//In our testing, we see it have a tremendous impact not only on the A7, +//but also on all x86 cores that ship with modern Macs. +//The attached source file includes a single function (ReoptimizeLinkOrder) which can be called on a +//btSoftBody object in the solveConstraints() function before the actual solver is invoked, //or right after generateBendingConstraints() once we have all 1410 links. - //=================================================================== // // -// This function takes in a list of interdependent Links and tries +// This function takes in a list of interdependent Links and tries // to maximize the distance between calculation // of dependent links. This increases the amount of parallelism that can // be exploited by out-of-order instruction processors with large but @@ -522,93 +521,103 @@ void btSoftBodyHelpers::DrawClusterTree( btSoftBody* psb, //=================================================================== // A small structure to track lists of dependent link calculations -class LinkDeps_t { - public: - int value; // A link calculation that is dependent on this one - // Positive values = "input A" while negative values = "input B" - LinkDeps_t *next; // Next dependence in the list +class LinkDeps_t +{ +public: + int value; // A link calculation that is dependent on this one + // Positive values = "input A" while negative values = "input B" + LinkDeps_t* next; // Next dependence in the list }; -typedef LinkDeps_t *LinkDepsPtr_t; +typedef LinkDeps_t* LinkDepsPtr_t; // Dependency list constants -#define REOP_NOT_DEPENDENT -1 -#define REOP_NODE_COMPLETE -2 // Must be less than REOP_NOT_DEPENDENT +#define REOP_NOT_DEPENDENT -1 +#define REOP_NODE_COMPLETE -2 // Must be less than REOP_NOT_DEPENDENT - -void btSoftBodyHelpers::ReoptimizeLinkOrder(btSoftBody *psb /* This can be replaced by a btSoftBody pointer */) +void btSoftBodyHelpers::ReoptimizeLinkOrder(btSoftBody* psb /* This can be replaced by a btSoftBody pointer */) { - int i, nLinks=psb->m_links.size(), nNodes=psb->m_nodes.size(); - btSoftBody::Link *lr; + int i, nLinks = psb->m_links.size(), nNodes = psb->m_nodes.size(); + btSoftBody::Link* lr; int ar, br; - btSoftBody::Node *node0 = &(psb->m_nodes[0]); - btSoftBody::Node *node1 = &(psb->m_nodes[1]); + btSoftBody::Node* node0 = &(psb->m_nodes[0]); + btSoftBody::Node* node1 = &(psb->m_nodes[1]); LinkDepsPtr_t linkDep; int readyListHead, readyListTail, linkNum, linkDepFrees, depLink; - + // Allocate temporary buffers - int *nodeWrittenAt = new int[nNodes+1]; // What link calculation produced this node's current values? - int *linkDepA = new int[nLinks]; // Link calculation input is dependent upon prior calculation #N - int *linkDepB = new int[nLinks]; - int *readyList = new int[nLinks]; // List of ready-to-process link calculations (# of links, maximum) - LinkDeps_t *linkDepFreeList = new LinkDeps_t[2*nLinks]; // Dependent-on-me list elements (2x# of links, maximum) - LinkDepsPtr_t *linkDepListStarts = new LinkDepsPtr_t[nLinks]; // Start nodes of dependent-on-me lists, one for each link - + int* nodeWrittenAt = new int[nNodes + 1]; // What link calculation produced this node's current values? + int* linkDepA = new int[nLinks]; // Link calculation input is dependent upon prior calculation #N + int* linkDepB = new int[nLinks]; + int* readyList = new int[nLinks]; // List of ready-to-process link calculations (# of links, maximum) + LinkDeps_t* linkDepFreeList = new LinkDeps_t[2 * nLinks]; // Dependent-on-me list elements (2x# of links, maximum) + LinkDepsPtr_t* linkDepListStarts = new LinkDepsPtr_t[nLinks]; // Start nodes of dependent-on-me lists, one for each link + // Copy the original, unsorted links to a side buffer - btSoftBody::Link *linkBuffer = new btSoftBody::Link[nLinks]; - memcpy(linkBuffer, &(psb->m_links[0]), sizeof(btSoftBody::Link)*nLinks); + btSoftBody::Link* linkBuffer = new btSoftBody::Link[nLinks]; + memcpy(linkBuffer, &(psb->m_links[0]), sizeof(btSoftBody::Link) * nLinks); // Clear out the node setup and ready list - for (i=0; i < nNodes+1; i++) { + for (i = 0; i < nNodes + 1; i++) + { nodeWrittenAt[i] = REOP_NOT_DEPENDENT; } - for (i=0; i < nLinks; i++) { + for (i = 0; i < nLinks; i++) + { linkDepListStarts[i] = NULL; } readyListHead = readyListTail = linkDepFrees = 0; // Initial link analysis to set up data structures - for (i=0; i < nLinks; i++) { - + for (i = 0; i < nLinks; i++) + { // Note which prior link calculations we are dependent upon & build up dependence lists lr = &(psb->m_links[i]); - ar = (lr->m_n[0] - node0)/(node1 - node0); - br = (lr->m_n[1] - node0)/(node1 - node0); - if (nodeWrittenAt[ar] > REOP_NOT_DEPENDENT) { + ar = (lr->m_n[0] - node0) / (node1 - node0); + br = (lr->m_n[1] - node0) / (node1 - node0); + if (nodeWrittenAt[ar] > REOP_NOT_DEPENDENT) + { linkDepA[i] = nodeWrittenAt[ar]; linkDep = &linkDepFreeList[linkDepFrees++]; linkDep->value = i; linkDep->next = linkDepListStarts[nodeWrittenAt[ar]]; linkDepListStarts[nodeWrittenAt[ar]] = linkDep; - } else { + } + else + { linkDepA[i] = REOP_NOT_DEPENDENT; } - if (nodeWrittenAt[br] > REOP_NOT_DEPENDENT) { + if (nodeWrittenAt[br] > REOP_NOT_DEPENDENT) + { linkDepB[i] = nodeWrittenAt[br]; linkDep = &linkDepFreeList[linkDepFrees++]; - linkDep->value = -(i+1); + linkDep->value = -(i + 1); linkDep->next = linkDepListStarts[nodeWrittenAt[br]]; linkDepListStarts[nodeWrittenAt[br]] = linkDep; - } else { + } + else + { linkDepB[i] = REOP_NOT_DEPENDENT; } - + // Add this link to the initial ready list, if it is not dependent on any other links - if ((linkDepA[i] == REOP_NOT_DEPENDENT) && (linkDepB[i] == REOP_NOT_DEPENDENT)) { + if ((linkDepA[i] == REOP_NOT_DEPENDENT) && (linkDepB[i] == REOP_NOT_DEPENDENT)) + { readyList[readyListTail++] = i; - linkDepA[i] = linkDepB[i] = REOP_NODE_COMPLETE; // Probably not needed now + linkDepA[i] = linkDepB[i] = REOP_NODE_COMPLETE; // Probably not needed now } - + // Update the nodes to mark which ones are calculated by this link nodeWrittenAt[ar] = nodeWrittenAt[br] = i; } - + // Process the ready list and create the sorted list of links // -- By treating the ready list as a queue, we maximize the distance between any // inter-dependent node calculations // -- All other (non-related) nodes in the ready list will automatically be inserted // in between each set of inter-dependent link calculations by this loop i = 0; - while (readyListHead != readyListTail) { + while (readyListHead != readyListTail) + { // Use ready list to select the next link to process linkNum = readyList[readyListHead++]; // Copy the next-to-calculate link back into the original link array @@ -616,180 +625,183 @@ void btSoftBodyHelpers::ReoptimizeLinkOrder(btSoftBody *psb /* This can be repla // Free up any link inputs that are dependent on this one linkDep = linkDepListStarts[linkNum]; - while (linkDep) { + while (linkDep) + { depLink = linkDep->value; - if (depLink >= 0) { + if (depLink >= 0) + { linkDepA[depLink] = REOP_NOT_DEPENDENT; - } else { + } + else + { depLink = -depLink - 1; linkDepB[depLink] = REOP_NOT_DEPENDENT; } // Add this dependent link calculation to the ready list if *both* inputs are clear - if ((linkDepA[depLink] == REOP_NOT_DEPENDENT) && (linkDepB[depLink] == REOP_NOT_DEPENDENT)) { + if ((linkDepA[depLink] == REOP_NOT_DEPENDENT) && (linkDepB[depLink] == REOP_NOT_DEPENDENT)) + { readyList[readyListTail++] = depLink; - linkDepA[depLink] = linkDepB[depLink] = REOP_NODE_COMPLETE; // Probably not needed now + linkDepA[depLink] = linkDepB[depLink] = REOP_NODE_COMPLETE; // Probably not needed now } linkDep = linkDep->next; } } // Delete the temporary buffers - delete [] nodeWrittenAt; - delete [] linkDepA; - delete [] linkDepB; - delete [] readyList; - delete [] linkDepFreeList; - delete [] linkDepListStarts; - delete [] linkBuffer; + delete[] nodeWrittenAt; + delete[] linkDepA; + delete[] linkDepB; + delete[] readyList; + delete[] linkDepFreeList; + delete[] linkDepListStarts; + delete[] linkBuffer; } - // -void btSoftBodyHelpers::DrawFrame( btSoftBody* psb, - btIDebugDraw* idraw) +void btSoftBodyHelpers::DrawFrame(btSoftBody* psb, + btIDebugDraw* idraw) { - if(psb->m_pose.m_bframe) + if (psb->m_pose.m_bframe) { - static const btScalar ascl=10; - static const btScalar nscl=(btScalar)0.1; - const btVector3 com=psb->m_pose.m_com; - const btMatrix3x3 trs=psb->m_pose.m_rot*psb->m_pose.m_scl; - const btVector3 Xaxis=(trs*btVector3(1,0,0)).normalized(); - const btVector3 Yaxis=(trs*btVector3(0,1,0)).normalized(); - const btVector3 Zaxis=(trs*btVector3(0,0,1)).normalized(); - idraw->drawLine(com,com+Xaxis*ascl,btVector3(1,0,0)); - idraw->drawLine(com,com+Yaxis*ascl,btVector3(0,1,0)); - idraw->drawLine(com,com+Zaxis*ascl,btVector3(0,0,1)); - for(int i=0;im_pose.m_pos.size();++i) + static const btScalar ascl = 10; + static const btScalar nscl = (btScalar)0.1; + const btVector3 com = psb->m_pose.m_com; + const btMatrix3x3 trs = psb->m_pose.m_rot * psb->m_pose.m_scl; + const btVector3 Xaxis = (trs * btVector3(1, 0, 0)).normalized(); + const btVector3 Yaxis = (trs * btVector3(0, 1, 0)).normalized(); + const btVector3 Zaxis = (trs * btVector3(0, 0, 1)).normalized(); + idraw->drawLine(com, com + Xaxis * ascl, btVector3(1, 0, 0)); + idraw->drawLine(com, com + Yaxis * ascl, btVector3(0, 1, 0)); + idraw->drawLine(com, com + Zaxis * ascl, btVector3(0, 0, 1)); + for (int i = 0; i < psb->m_pose.m_pos.size(); ++i) { - const btVector3 x=com+trs*psb->m_pose.m_pos[i]; - drawVertex(idraw,x,nscl,btVector3(1,0,1)); + const btVector3 x = com + trs * psb->m_pose.m_pos[i]; + drawVertex(idraw, x, nscl, btVector3(1, 0, 1)); } } } // -btSoftBody* btSoftBodyHelpers::CreateRope( btSoftBodyWorldInfo& worldInfo, const btVector3& from, - const btVector3& to, - int res, - int fixeds) +btSoftBody* btSoftBodyHelpers::CreateRope(btSoftBodyWorldInfo& worldInfo, const btVector3& from, + const btVector3& to, + int res, + int fixeds) { - /* Create nodes */ - const int r=res+2; - btVector3* x=new btVector3[r]; - btScalar* m=new btScalar[r]; + /* Create nodes */ + const int r = res + 2; + btVector3* x = new btVector3[r]; + btScalar* m = new btScalar[r]; int i; - for(i=0;isetMass(0,0); - if(fixeds&2) psb->setMass(r-1,0); + btSoftBody* psb = new btSoftBody(&worldInfo, r, x, m); + if (fixeds & 1) psb->setMass(0, 0); + if (fixeds & 2) psb->setMass(r - 1, 0); delete[] x; delete[] m; - /* Create links */ - for(i=1;iappendLink(i-1,i); + psb->appendLink(i - 1, i); } - /* Finished */ - return(psb); + /* Finished */ + return (psb); } // -btSoftBody* btSoftBodyHelpers::CreatePatch(btSoftBodyWorldInfo& worldInfo,const btVector3& corner00, - const btVector3& corner10, - const btVector3& corner01, - const btVector3& corner11, - int resx, - int resy, - int fixeds, - bool gendiags) +btSoftBody* btSoftBodyHelpers::CreatePatch(btSoftBodyWorldInfo& worldInfo, const btVector3& corner00, + const btVector3& corner10, + const btVector3& corner01, + const btVector3& corner11, + int resx, + int resy, + int fixeds, + bool gendiags) { -#define IDX(_x_,_y_) ((_y_)*rx+(_x_)) - /* Create nodes */ - if((resx<2)||(resy<2)) return(0); - const int rx=resx; - const int ry=resy; - const int tot=rx*ry; - btVector3* x=new btVector3[tot]; - btScalar* m=new btScalar[tot]; +#define IDX(_x_, _y_) ((_y_)*rx + (_x_)) + /* Create nodes */ + if ((resx < 2) || (resy < 2)) return (0); + const int rx = resx; + const int ry = resy; + const int tot = rx * ry; + btVector3* x = new btVector3[tot]; + btScalar* m = new btScalar[tot]; int iy; - for(iy=0;iysetMass(IDX(0,0),0); - if(fixeds&2) psb->setMass(IDX(rx-1,0),0); - if(fixeds&4) psb->setMass(IDX(0,ry-1),0); - if(fixeds&8) psb->setMass(IDX(rx-1,ry-1),0); + btSoftBody* psb = new btSoftBody(&worldInfo, tot, x, m); + if (fixeds & 1) psb->setMass(IDX(0, 0), 0); + if (fixeds & 2) psb->setMass(IDX(rx - 1, 0), 0); + if (fixeds & 4) psb->setMass(IDX(0, ry - 1), 0); + if (fixeds & 8) psb->setMass(IDX(rx - 1, ry - 1), 0); delete[] x; delete[] m; - /* Create links and faces */ - for(iy=0;iyappendLink(idx,IDX(ix+1,iy)); - if(mdy) psb->appendLink(idx,IDX(ix,iy+1)); - if(mdx&&mdy) + const int idx = IDX(ix, iy); + const bool mdx = (ix + 1) < rx; + const bool mdy = (iy + 1) < ry; + if (mdx) psb->appendLink(idx, IDX(ix + 1, iy)); + if (mdy) psb->appendLink(idx, IDX(ix, iy + 1)); + if (mdx && mdy) { - if((ix+iy)&1) + if ((ix + iy) & 1) { - psb->appendFace(IDX(ix,iy),IDX(ix+1,iy),IDX(ix+1,iy+1)); - psb->appendFace(IDX(ix,iy),IDX(ix+1,iy+1),IDX(ix,iy+1)); - if(gendiags) + psb->appendFace(IDX(ix, iy), IDX(ix + 1, iy), IDX(ix + 1, iy + 1)); + psb->appendFace(IDX(ix, iy), IDX(ix + 1, iy + 1), IDX(ix, iy + 1)); + if (gendiags) { - psb->appendLink(IDX(ix,iy),IDX(ix+1,iy+1)); + psb->appendLink(IDX(ix, iy), IDX(ix + 1, iy + 1)); } } else { - psb->appendFace(IDX(ix,iy+1),IDX(ix,iy),IDX(ix+1,iy)); - psb->appendFace(IDX(ix,iy+1),IDX(ix+1,iy),IDX(ix+1,iy+1)); - if(gendiags) + psb->appendFace(IDX(ix, iy + 1), IDX(ix, iy), IDX(ix + 1, iy)); + psb->appendFace(IDX(ix, iy + 1), IDX(ix + 1, iy), IDX(ix + 1, iy + 1)); + if (gendiags) { - psb->appendLink(IDX(ix+1,iy),IDX(ix,iy+1)); + psb->appendLink(IDX(ix + 1, iy), IDX(ix, iy + 1)); } } } } } - /* Finished */ + /* Finished */ #undef IDX - return(psb); + return (psb); } // -btSoftBody* btSoftBodyHelpers::CreatePatchUV(btSoftBodyWorldInfo& worldInfo, - const btVector3& corner00, - const btVector3& corner10, - const btVector3& corner01, - const btVector3& corner11, - int resx, - int resy, - int fixeds, - bool gendiags, - float* tex_coords) +btSoftBody* btSoftBodyHelpers::CreatePatchUV(btSoftBodyWorldInfo& worldInfo, + const btVector3& corner00, + const btVector3& corner10, + const btVector3& corner01, + const btVector3& corner11, + int resx, + int resy, + int fixeds, + bool gendiags, + float* tex_coords) { - /* * * corners: @@ -857,92 +869,92 @@ btSoftBody* btSoftBodyHelpers::CreatePatchUV(btSoftBodyWorldInfo& worldInfo, * */ -#define IDX(_x_,_y_) ((_y_)*rx+(_x_)) - /* Create nodes */ - if((resx<2)||(resy<2)) return(0); - const int rx=resx; - const int ry=resy; - const int tot=rx*ry; - btVector3* x=new btVector3[tot]; - btScalar* m=new btScalar[tot]; +#define IDX(_x_, _y_) ((_y_)*rx + (_x_)) + /* Create nodes */ + if ((resx < 2) || (resy < 2)) return (0); + const int rx = resx; + const int ry = resy; + const int tot = rx * ry; + btVector3* x = new btVector3[tot]; + btScalar* m = new btScalar[tot]; int iy; - for(iy=0;iysetMass(IDX(0,0),0); - if(fixeds&2) psb->setMass(IDX(rx-1,0),0); - if(fixeds&4) psb->setMass(IDX(0,ry-1),0); - if(fixeds&8) psb->setMass(IDX(rx-1,ry-1),0); - if(fixeds&16) psb->setMass(IDX((rx-1)/2,0),0); - if(fixeds&32) psb->setMass(IDX(0,(ry-1)/2),0); - if(fixeds&64) psb->setMass(IDX(rx-1,(ry-1)/2),0); - if(fixeds&128) psb->setMass(IDX((rx-1)/2,ry-1),0); - if(fixeds&256) psb->setMass(IDX((rx-1)/2,(ry-1)/2),0); + btSoftBody* psb = new btSoftBody(&worldInfo, tot, x, m); + if (fixeds & 1) psb->setMass(IDX(0, 0), 0); + if (fixeds & 2) psb->setMass(IDX(rx - 1, 0), 0); + if (fixeds & 4) psb->setMass(IDX(0, ry - 1), 0); + if (fixeds & 8) psb->setMass(IDX(rx - 1, ry - 1), 0); + if (fixeds & 16) psb->setMass(IDX((rx - 1) / 2, 0), 0); + if (fixeds & 32) psb->setMass(IDX(0, (ry - 1) / 2), 0); + if (fixeds & 64) psb->setMass(IDX(rx - 1, (ry - 1) / 2), 0); + if (fixeds & 128) psb->setMass(IDX((rx - 1) / 2, ry - 1), 0); + if (fixeds & 256) psb->setMass(IDX((rx - 1) / 2, (ry - 1) / 2), 0); delete[] x; delete[] m; - int z = 0; - /* Create links and faces */ - for(iy=0;iyappendLink(node00,node01); - if(mdy) psb->appendLink(node00,node10); - if(mdx&&mdy) + if (mdx) psb->appendLink(node00, node01); + if (mdy) psb->appendLink(node00, node10); + if (mdx && mdy) { - psb->appendFace(node00,node10,node11); - if (tex_coords) { - tex_coords[z+0]=CalculateUV(resx,resy,ix,iy,0); - tex_coords[z+1]=CalculateUV(resx,resy,ix,iy,1); - tex_coords[z+2]=CalculateUV(resx,resy,ix,iy,0); - tex_coords[z+3]=CalculateUV(resx,resy,ix,iy,2); - tex_coords[z+4]=CalculateUV(resx,resy,ix,iy,3); - tex_coords[z+5]=CalculateUV(resx,resy,ix,iy,2); + psb->appendFace(node00, node10, node11); + if (tex_coords) + { + tex_coords[z + 0] = CalculateUV(resx, resy, ix, iy, 0); + tex_coords[z + 1] = CalculateUV(resx, resy, ix, iy, 1); + tex_coords[z + 2] = CalculateUV(resx, resy, ix, iy, 0); + tex_coords[z + 3] = CalculateUV(resx, resy, ix, iy, 2); + tex_coords[z + 4] = CalculateUV(resx, resy, ix, iy, 3); + tex_coords[z + 5] = CalculateUV(resx, resy, ix, iy, 2); } - psb->appendFace(node11,node01,node00); - if (tex_coords) { - tex_coords[z+6 ]=CalculateUV(resx,resy,ix,iy,3); - tex_coords[z+7 ]=CalculateUV(resx,resy,ix,iy,2); - tex_coords[z+8 ]=CalculateUV(resx,resy,ix,iy,3); - tex_coords[z+9 ]=CalculateUV(resx,resy,ix,iy,1); - tex_coords[z+10]=CalculateUV(resx,resy,ix,iy,0); - tex_coords[z+11]=CalculateUV(resx,resy,ix,iy,1); + psb->appendFace(node11, node01, node00); + if (tex_coords) + { + tex_coords[z + 6] = CalculateUV(resx, resy, ix, iy, 3); + tex_coords[z + 7] = CalculateUV(resx, resy, ix, iy, 2); + tex_coords[z + 8] = CalculateUV(resx, resy, ix, iy, 3); + tex_coords[z + 9] = CalculateUV(resx, resy, ix, iy, 1); + tex_coords[z + 10] = CalculateUV(resx, resy, ix, iy, 0); + tex_coords[z + 11] = CalculateUV(resx, resy, ix, iy, 1); } - if (gendiags) psb->appendLink(node00,node11); + if (gendiags) psb->appendLink(node00, node11); z += 12; } } } - /* Finished */ + /* Finished */ #undef IDX - return(psb); + return (psb); } -float btSoftBodyHelpers::CalculateUV(int resx,int resy,int ix,int iy,int id) +float btSoftBodyHelpers::CalculateUV(int resx, int resy, int ix, int iy, int id) { - /* * * @@ -968,90 +980,93 @@ float btSoftBodyHelpers::CalculateUV(int resx,int resy,int ix,int iy,int id) * */ - float tc=0.0f; - if (id == 0) { - tc = (1.0f/((resx-1))*ix); + float tc = 0.0f; + if (id == 0) + { + tc = (1.0f / ((resx - 1)) * ix); } - else if (id==1) { - tc = (1.0f/((resy-1))*(resy-1-iy)); + else if (id == 1) + { + tc = (1.0f / ((resy - 1)) * (resy - 1 - iy)); } - else if (id==2) { - tc = (1.0f/((resy-1))*(resy-1-iy-1)); + else if (id == 2) + { + tc = (1.0f / ((resy - 1)) * (resy - 1 - iy - 1)); } - else if (id==3) { - tc = (1.0f/((resx-1))*(ix+1)); + else if (id == 3) + { + tc = (1.0f / ((resx - 1)) * (ix + 1)); } return tc; } // -btSoftBody* btSoftBodyHelpers::CreateEllipsoid(btSoftBodyWorldInfo& worldInfo,const btVector3& center, - const btVector3& radius, - int res) +btSoftBody* btSoftBodyHelpers::CreateEllipsoid(btSoftBodyWorldInfo& worldInfo, const btVector3& center, + const btVector3& radius, + int res) { - struct Hammersley + struct Hammersley { - static void Generate(btVector3* x,int n) + static void Generate(btVector3* x, int n) { - for(int i=0;i>=1) if(j&1) t+=p; - btScalar w=2*t-1; - btScalar a=(SIMD_PI+2*i*SIMD_PI)/n; - btScalar s=btSqrt(1-w*w); - *x++=btVector3(s*btCos(a),s*btSin(a),w); + btScalar p = 0.5, t = 0; + for (int j = i; j; p *= 0.5, j >>= 1) + if (j & 1) t += p; + btScalar w = 2 * t - 1; + btScalar a = (SIMD_PI + 2 * i * SIMD_PI) / n; + btScalar s = btSqrt(1 - w * w); + *x++ = btVector3(s * btCos(a), s * btSin(a), w); } } }; - btAlignedObjectArray vtx; - vtx.resize(3+res); - Hammersley::Generate(&vtx[0],vtx.size()); - for(int i=0;i vtx; + vtx.resize(3 + res); + Hammersley::Generate(&vtx[0], vtx.size()); + for (int i = 0; i < vtx.size(); ++i) { - vtx[i]=vtx[i]*radius+center; + vtx[i] = vtx[i] * radius + center; } - return(CreateFromConvexHull(worldInfo,&vtx[0],vtx.size())); + return (CreateFromConvexHull(worldInfo, &vtx[0], vtx.size())); } - - // -btSoftBody* btSoftBodyHelpers::CreateFromTriMesh(btSoftBodyWorldInfo& worldInfo,const btScalar* vertices, - const int* triangles, - int ntriangles, bool randomizeConstraints) +btSoftBody* btSoftBodyHelpers::CreateFromTriMesh(btSoftBodyWorldInfo& worldInfo, const btScalar* vertices, + const int* triangles, + int ntriangles, bool randomizeConstraints) { - int maxidx=0; - int i,j,ni; + int maxidx = 0; + int i, j, ni; - for(i=0,ni=ntriangles*3;i chks; - btAlignedObjectArray vtx; - chks.resize(maxidx*maxidx,false); + btAlignedObjectArray chks; + btAlignedObjectArray vtx; + chks.resize(maxidx * maxidx, false); vtx.resize(maxidx); - for(i=0,j=0,ni=maxidx*3;iappendLink(idx[j],idx[k]); + chks[IDX(idx[j], idx[k])] = true; + chks[IDX(idx[k], idx[j])] = true; + psb->appendLink(idx[j], idx[k]); } } #undef IDX - psb->appendFace(idx[0],idx[1],idx[2]); + psb->appendFace(idx[0], idx[1], idx[2]); } if (randomizeConstraints) @@ -1059,44 +1074,41 @@ btSoftBody* btSoftBodyHelpers::CreateFromTriMesh(btSoftBodyWorldInfo& worldInfo psb->randomizeConstraints(); } - return(psb); + return (psb); } // -btSoftBody* btSoftBodyHelpers::CreateFromConvexHull(btSoftBodyWorldInfo& worldInfo, const btVector3* vertices, - int nvertices, bool randomizeConstraints) +btSoftBody* btSoftBodyHelpers::CreateFromConvexHull(btSoftBodyWorldInfo& worldInfo, const btVector3* vertices, + int nvertices, bool randomizeConstraints) { - HullDesc hdsc(QF_TRIANGLES,nvertices,vertices); - HullResult hres; - HullLibrary hlib;/*??*/ - hdsc.mMaxVertices=nvertices; - hlib.CreateConvexHull(hdsc,hres); - btSoftBody* psb=new btSoftBody(&worldInfo,(int)hres.mNumOutputVertices, - &hres.m_OutputVertices[0],0); - for(int i=0;i<(int)hres.mNumFaces;++i) + HullDesc hdsc(QF_TRIANGLES, nvertices, vertices); + HullResult hres; + HullLibrary hlib; /*??*/ + hdsc.mMaxVertices = nvertices; + hlib.CreateConvexHull(hdsc, hres); + btSoftBody* psb = new btSoftBody(&worldInfo, (int)hres.mNumOutputVertices, + &hres.m_OutputVertices[0], 0); + for (int i = 0; i < (int)hres.mNumFaces; ++i) { - const int idx[]={ static_cast(hres.m_Indices[i*3+0]), - static_cast(hres.m_Indices[i*3+1]), - static_cast(hres.m_Indices[i*3+2])}; - if(idx[0]appendLink( idx[0],idx[1]); - if(idx[1]appendLink( idx[1],idx[2]); - if(idx[2]appendLink( idx[2],idx[0]); - psb->appendFace(idx[0],idx[1],idx[2]); + const int idx[] = {static_cast(hres.m_Indices[i * 3 + 0]), + static_cast(hres.m_Indices[i * 3 + 1]), + static_cast(hres.m_Indices[i * 3 + 2])}; + if (idx[0] < idx[1]) psb->appendLink(idx[0], idx[1]); + if (idx[1] < idx[2]) psb->appendLink(idx[1], idx[2]); + if (idx[2] < idx[0]) psb->appendLink(idx[2], idx[0]); + psb->appendFace(idx[0], idx[1], idx[2]); } hlib.ReleaseResult(hres); if (randomizeConstraints) { psb->randomizeConstraints(); } - return(psb); + return (psb); } - - - static int nextLine(const char* buffer) { - int numBytesRead=0; + int numBytesRead = 0; while (*buffer != '\n') { @@ -1104,8 +1116,7 @@ static int nextLine(const char* buffer) numBytesRead++; } - - if (buffer[0]==0x0a) + if (buffer[0] == 0x0a) { buffer++; numBytesRead++; @@ -1113,8 +1124,8 @@ static int nextLine(const char* buffer) return numBytesRead; } -/* Create from TetGen .ele, .face, .node data */ -btSoftBody* btSoftBodyHelpers::CreateFromTetGenData(btSoftBodyWorldInfo& worldInfo, +/* Create from TetGen .ele, .face, .node data */ +btSoftBody* btSoftBodyHelpers::CreateFromTetGenData(btSoftBodyWorldInfo& worldInfo, const char* ele, const char* face, const char* node, @@ -1122,38 +1133,38 @@ btSoftBody* btSoftBodyHelpers::CreateFromTetGenData(btSoftBodyWorldInfo& worldIn bool btetralinks, bool bfacesfromtetras) { -btAlignedObjectArray pos; -int nnode=0; -int ndims=0; -int nattrb=0; -int hasbounds=0; -int result = sscanf(node,"%d %d %d %d",&nnode,&ndims,&nattrb,&hasbounds); -result = sscanf(node,"%d %d %d %d",&nnode,&ndims,&nattrb,&hasbounds); -node += nextLine(node); - -pos.resize(nnode); -for(int i=0;i>index; -// sn>>x;sn>>y;sn>>z; + btAlignedObjectArray pos; + int nnode = 0; + int ndims = 0; + int nattrb = 0; + int hasbounds = 0; + int result = sscanf(node, "%d %d %d %d", &nnode, &ndims, &nattrb, &hasbounds); + result = sscanf(node, "%d %d %d %d", &nnode, &ndims, &nattrb, &hasbounds); node += nextLine(node); - //for(int j=0;j>a; + pos.resize(nnode); + for (int i = 0; i < pos.size(); ++i) + { + int index = 0; + //int bound=0; + float x, y, z; + sscanf(node, "%d %f %f %f", &index, &x, &y, &z); - //if(hasbounds) - // sn>>bound; + // sn>>index; + // sn>>x;sn>>y;sn>>z; + node += nextLine(node); - pos[index].setX(btScalar(x)); - pos[index].setY(btScalar(y)); - pos[index].setZ(btScalar(z)); + //for(int j=0;j>a; + + //if(hasbounds) + // sn>>bound; + + pos[index].setX(btScalar(x)); + pos[index].setY(btScalar(y)); + pos[index].setZ(btScalar(z)); } -btSoftBody* psb=new btSoftBody(&worldInfo,nnode,&pos[0],0); + btSoftBody* psb = new btSoftBody(&worldInfo, nnode, &pos[0], 0); #if 0 if(face&&face[0]) { @@ -1178,42 +1189,41 @@ if(face&&face[0]) } #endif -if(ele&&ele[0]) + if (ele && ele[0]) { - int ntetra=0; - int ncorner=0; - int neattrb=0; - sscanf(ele,"%d %d %d",&ntetra,&ncorner,&neattrb); - ele += nextLine(ele); - - //se>>ntetra;se>>ncorner;se>>neattrb; - for(int i=0;i>index; - //se>>ni[0];se>>ni[1];se>>ni[2];se>>ni[3]; - sscanf(ele,"%d %d %d %d %d",&index,&ni[0],&ni[1],&ni[2],&ni[3]); - ele+=nextLine(ele); - //for(int j=0;j>a; - psb->appendTetra(ni[0],ni[1],ni[2],ni[3]); - if(btetralinks) + //se>>ntetra;se>>ncorner;se>>neattrb; + for (int i = 0; i < ntetra; ++i) + { + int index = 0; + int ni[4]; + + //se>>index; + //se>>ni[0];se>>ni[1];se>>ni[2];se>>ni[3]; + sscanf(ele, "%d %d %d %d %d", &index, &ni[0], &ni[1], &ni[2], &ni[3]); + ele += nextLine(ele); + //for(int j=0;j>a; + psb->appendTetra(ni[0], ni[1], ni[2], ni[3]); + if (btetralinks) { - psb->appendLink(ni[0],ni[1],0,true); - psb->appendLink(ni[1],ni[2],0,true); - psb->appendLink(ni[2],ni[0],0,true); - psb->appendLink(ni[0],ni[3],0,true); - psb->appendLink(ni[1],ni[3],0,true); - psb->appendLink(ni[2],ni[3],0,true); + psb->appendLink(ni[0], ni[1], 0, true); + psb->appendLink(ni[1], ni[2], 0, true); + psb->appendLink(ni[2], ni[0], 0, true); + psb->appendLink(ni[0], ni[3], 0, true); + psb->appendLink(ni[1], ni[3], 0, true); + psb->appendLink(ni[2], ni[3], 0, true); } } } -printf("Nodes: %u\r\n",psb->m_nodes.size()); -printf("Links: %u\r\n",psb->m_links.size()); -printf("Faces: %u\r\n",psb->m_faces.size()); -printf("Tetras: %u\r\n",psb->m_tetras.size()); -return(psb); + printf("Nodes: %u\r\n", psb->m_nodes.size()); + printf("Links: %u\r\n", psb->m_links.size()); + printf("Faces: %u\r\n", psb->m_faces.size()); + printf("Tetras: %u\r\n", psb->m_tetras.size()); + return (psb); } - diff --git a/src/BulletSoftBody/btSoftBodyHelpers.h b/src/BulletSoftBody/btSoftBodyHelpers.h index 727153010..e433558c1 100644 --- a/src/BulletSoftBody/btSoftBodyHelpers.h +++ b/src/BulletSoftBody/btSoftBodyHelpers.h @@ -22,127 +22,130 @@ subject to the following restrictions: // Helpers // -/* fDrawFlags */ -struct fDrawFlags { enum _ { - Nodes = 0x0001, - Links = 0x0002, - Faces = 0x0004, - Tetras = 0x0008, - Normals = 0x0010, - Contacts = 0x0020, - Anchors = 0x0040, - Notes = 0x0080, - Clusters = 0x0100, - NodeTree = 0x0200, - FaceTree = 0x0400, - ClusterTree = 0x0800, - Joints = 0x1000, - /* presets */ - Std = Links+Faces+Tetras+Anchors+Notes+Joints, - StdTetra = Std-Faces+Tetras -};}; - -struct btSoftBodyHelpers +/* fDrawFlags */ +struct fDrawFlags { - /* Draw body */ - static void Draw( btSoftBody* psb, - btIDebugDraw* idraw, - int drawflags=fDrawFlags::Std); - /* Draw body infos */ - static void DrawInfos( btSoftBody* psb, - btIDebugDraw* idraw, - bool masses, - bool areas, - bool stress); - /* Draw node tree */ - static void DrawNodeTree( btSoftBody* psb, - btIDebugDraw* idraw, - int mindepth=0, - int maxdepth=-1); - /* Draw face tree */ - static void DrawFaceTree( btSoftBody* psb, - btIDebugDraw* idraw, - int mindepth=0, - int maxdepth=-1); - /* Draw cluster tree */ - static void DrawClusterTree(btSoftBody* psb, - btIDebugDraw* idraw, - int mindepth=0, - int maxdepth=-1); - /* Draw rigid frame */ - static void DrawFrame( btSoftBody* psb, - btIDebugDraw* idraw); - /* Create a rope */ - static btSoftBody* CreateRope( btSoftBodyWorldInfo& worldInfo, - const btVector3& from, - const btVector3& to, - int res, - int fixeds); - /* Create a patch */ - static btSoftBody* CreatePatch(btSoftBodyWorldInfo& worldInfo, - const btVector3& corner00, - const btVector3& corner10, - const btVector3& corner01, - const btVector3& corner11, - int resx, - int resy, - int fixeds, - bool gendiags); - /* Create a patch with UV Texture Coordinates */ - static btSoftBody* CreatePatchUV(btSoftBodyWorldInfo& worldInfo, - const btVector3& corner00, - const btVector3& corner10, - const btVector3& corner01, - const btVector3& corner11, - int resx, - int resy, - int fixeds, - bool gendiags, - float* tex_coords=0); - static float CalculateUV(int resx,int resy,int ix,int iy,int id); - /* Create an ellipsoid */ - static btSoftBody* CreateEllipsoid(btSoftBodyWorldInfo& worldInfo, - const btVector3& center, - const btVector3& radius, - int res); - /* Create from trimesh */ - static btSoftBody* CreateFromTriMesh( btSoftBodyWorldInfo& worldInfo, - const btScalar* vertices, - const int* triangles, - int ntriangles, - bool randomizeConstraints = true); - /* Create from convex-hull */ - static btSoftBody* CreateFromConvexHull( btSoftBodyWorldInfo& worldInfo, - const btVector3* vertices, - int nvertices, - bool randomizeConstraints = true); + enum _ + { + Nodes = 0x0001, + Links = 0x0002, + Faces = 0x0004, + Tetras = 0x0008, + Normals = 0x0010, + Contacts = 0x0020, + Anchors = 0x0040, + Notes = 0x0080, + Clusters = 0x0100, + NodeTree = 0x0200, + FaceTree = 0x0400, + ClusterTree = 0x0800, + Joints = 0x1000, + /* presets */ + Std = Links + Faces + Tetras + Anchors + Notes + Joints, + StdTetra = Std - Faces + Tetras + }; +}; +struct btSoftBodyHelpers +{ + /* Draw body */ + static void Draw(btSoftBody* psb, + btIDebugDraw* idraw, + int drawflags = fDrawFlags::Std); + /* Draw body infos */ + static void DrawInfos(btSoftBody* psb, + btIDebugDraw* idraw, + bool masses, + bool areas, + bool stress); + /* Draw node tree */ + static void DrawNodeTree(btSoftBody* psb, + btIDebugDraw* idraw, + int mindepth = 0, + int maxdepth = -1); + /* Draw face tree */ + static void DrawFaceTree(btSoftBody* psb, + btIDebugDraw* idraw, + int mindepth = 0, + int maxdepth = -1); + /* Draw cluster tree */ + static void DrawClusterTree(btSoftBody* psb, + btIDebugDraw* idraw, + int mindepth = 0, + int maxdepth = -1); + /* Draw rigid frame */ + static void DrawFrame(btSoftBody* psb, + btIDebugDraw* idraw); + /* Create a rope */ + static btSoftBody* CreateRope(btSoftBodyWorldInfo& worldInfo, + const btVector3& from, + const btVector3& to, + int res, + int fixeds); + /* Create a patch */ + static btSoftBody* CreatePatch(btSoftBodyWorldInfo& worldInfo, + const btVector3& corner00, + const btVector3& corner10, + const btVector3& corner01, + const btVector3& corner11, + int resx, + int resy, + int fixeds, + bool gendiags); + /* Create a patch with UV Texture Coordinates */ + static btSoftBody* CreatePatchUV(btSoftBodyWorldInfo& worldInfo, + const btVector3& corner00, + const btVector3& corner10, + const btVector3& corner01, + const btVector3& corner11, + int resx, + int resy, + int fixeds, + bool gendiags, + float* tex_coords = 0); + static float CalculateUV(int resx, int resy, int ix, int iy, int id); + /* Create an ellipsoid */ + static btSoftBody* CreateEllipsoid(btSoftBodyWorldInfo& worldInfo, + const btVector3& center, + const btVector3& radius, + int res); + /* Create from trimesh */ + static btSoftBody* CreateFromTriMesh(btSoftBodyWorldInfo& worldInfo, + const btScalar* vertices, + const int* triangles, + int ntriangles, + bool randomizeConstraints = true); + /* Create from convex-hull */ + static btSoftBody* CreateFromConvexHull(btSoftBodyWorldInfo& worldInfo, + const btVector3* vertices, + int nvertices, + bool randomizeConstraints = true); - /* Export TetGen compatible .smesh file */ -// static void ExportAsSMeshFile( btSoftBody* psb, -// const char* filename); - /* Create from TetGen .ele, .face, .node files */ -// static btSoftBody* CreateFromTetGenFile( btSoftBodyWorldInfo& worldInfo, -// const char* ele, -// const char* face, -// const char* node, -// bool bfacelinks, -// bool btetralinks, -// bool bfacesfromtetras); - /* Create from TetGen .ele, .face, .node data */ - static btSoftBody* CreateFromTetGenData( btSoftBodyWorldInfo& worldInfo, - const char* ele, - const char* face, - const char* node, - bool bfacelinks, - bool btetralinks, - bool bfacesfromtetras); + /* Export TetGen compatible .smesh file */ + // static void ExportAsSMeshFile( btSoftBody* psb, + // const char* filename); + /* Create from TetGen .ele, .face, .node files */ + // static btSoftBody* CreateFromTetGenFile( btSoftBodyWorldInfo& worldInfo, + // const char* ele, + // const char* face, + // const char* node, + // bool bfacelinks, + // bool btetralinks, + // bool bfacesfromtetras); + /* Create from TetGen .ele, .face, .node data */ + static btSoftBody* CreateFromTetGenData(btSoftBodyWorldInfo& worldInfo, + const char* ele, + const char* face, + const char* node, + bool bfacelinks, + bool btetralinks, + bool bfacesfromtetras); /// Sort the list of links to move link calculations that are dependent upon earlier /// ones as far as possible away from the calculation of those values /// This tends to make adjacent loop iterations not dependent upon one another, /// so out-of-order processors can execute instructions from multiple iterations at once - static void ReoptimizeLinkOrder(btSoftBody *psb ); + static void ReoptimizeLinkOrder(btSoftBody* psb); }; -#endif //BT_SOFT_BODY_HELPERS_H +#endif //BT_SOFT_BODY_HELPERS_H diff --git a/src/BulletSoftBody/btSoftBodyInternals.h b/src/BulletSoftBody/btSoftBodyInternals.h index 1ad82616e..7efe514f3 100644 --- a/src/BulletSoftBody/btSoftBodyInternals.h +++ b/src/BulletSoftBody/btSoftBodyInternals.h @@ -19,29 +19,37 @@ subject to the following restrictions: #include "btSoftBody.h" - #include "LinearMath/btQuickprof.h" #include "LinearMath/btPolarDecomposition.h" #include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h" #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h" #include "BulletCollision/CollisionShapes/btConvexInternalShape.h" #include "BulletCollision/NarrowPhaseCollision/btGjkEpa2.h" -#include //for memset +#include //for memset // // btSymMatrix // template struct btSymMatrix { - btSymMatrix() : dim(0) {} - btSymMatrix(int n,const T& init=T()) { resize(n,init); } - void resize(int n,const T& init=T()) { dim=n;store.resize((n*(n+1))/2,init); } - int index(int c,int r) const { if(c>r) btSwap(c,r);btAssert(r store; - int dim; -}; + btSymMatrix() : dim(0) {} + btSymMatrix(int n, const T& init = T()) { resize(n, init); } + void resize(int n, const T& init = T()) + { + dim = n; + store.resize((n * (n + 1)) / 2, init); + } + int index(int c, int r) const + { + if (c > r) btSwap(c, r); + btAssert(r < dim); + return ((r * (r + 1)) / 2 + c); + } + T& operator()(int c, int r) { return (store[index(c, r)]); } + const T& operator()(int c, int r) const { return (store[index(c, r)]); } + btAlignedObjectArray store; + int dim; +}; // // btSoftBodyCollisionShape @@ -49,67 +57,64 @@ struct btSymMatrix class btSoftBodyCollisionShape : public btConcaveShape { public: - btSoftBody* m_body; + btSoftBody* m_body; btSoftBodyCollisionShape(btSoftBody* backptr) { m_shapeType = SOFTBODY_SHAPE_PROXYTYPE; - m_body=backptr; + m_body = backptr; } virtual ~btSoftBodyCollisionShape() { - } - void processAllTriangles(btTriangleCallback* /*callback*/,const btVector3& /*aabbMin*/,const btVector3& /*aabbMax*/) const + void processAllTriangles(btTriangleCallback* /*callback*/, const btVector3& /*aabbMin*/, const btVector3& /*aabbMax*/) const { //not yet btAssert(0); } ///getAabb returns the axis aligned bounding box in the coordinate frame of the given transform t. - virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const + virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const { /* t is usually identity, except when colliding against btCompoundShape. See Issue 512 */ - const btVector3 mins=m_body->m_bounds[0]; - const btVector3 maxs=m_body->m_bounds[1]; - const btVector3 crns[]={t*btVector3(mins.x(),mins.y(),mins.z()), - t*btVector3(maxs.x(),mins.y(),mins.z()), - t*btVector3(maxs.x(),maxs.y(),mins.z()), - t*btVector3(mins.x(),maxs.y(),mins.z()), - t*btVector3(mins.x(),mins.y(),maxs.z()), - t*btVector3(maxs.x(),mins.y(),maxs.z()), - t*btVector3(maxs.x(),maxs.y(),maxs.z()), - t*btVector3(mins.x(),maxs.y(),maxs.z())}; - aabbMin=aabbMax=crns[0]; - for(int i=1;i<8;++i) + const btVector3 mins = m_body->m_bounds[0]; + const btVector3 maxs = m_body->m_bounds[1]; + const btVector3 crns[] = {t * btVector3(mins.x(), mins.y(), mins.z()), + t * btVector3(maxs.x(), mins.y(), mins.z()), + t * btVector3(maxs.x(), maxs.y(), mins.z()), + t * btVector3(mins.x(), maxs.y(), mins.z()), + t * btVector3(mins.x(), mins.y(), maxs.z()), + t * btVector3(maxs.x(), mins.y(), maxs.z()), + t * btVector3(maxs.x(), maxs.y(), maxs.z()), + t * btVector3(mins.x(), maxs.y(), maxs.z())}; + aabbMin = aabbMax = crns[0]; + for (int i = 1; i < 8; ++i) { aabbMin.setMin(crns[i]); aabbMax.setMax(crns[i]); } } - - virtual void setLocalScaling(const btVector3& /*scaling*/) - { + virtual void setLocalScaling(const btVector3& /*scaling*/) + { ///na } virtual const btVector3& getLocalScaling() const { - static const btVector3 dummy(1,1,1); + static const btVector3 dummy(1, 1, 1); return dummy; } - virtual void calculateLocalInertia(btScalar /*mass*/,btVector3& /*inertia*/) const + virtual void calculateLocalInertia(btScalar /*mass*/, btVector3& /*inertia*/) const { ///not yet btAssert(0); } - virtual const char* getName()const + virtual const char* getName() const { return "SoftBody"; } - }; // @@ -118,48 +123,53 @@ public: class btSoftClusterCollisionShape : public btConvexInternalShape { public: - const btSoftBody::Cluster* m_cluster; + const btSoftBody::Cluster* m_cluster; - btSoftClusterCollisionShape (const btSoftBody::Cluster* cluster) : m_cluster(cluster) { setMargin(0); } + btSoftClusterCollisionShape(const btSoftBody::Cluster* cluster) : m_cluster(cluster) { setMargin(0); } - - virtual btVector3 localGetSupportingVertex(const btVector3& vec) const + virtual btVector3 localGetSupportingVertex(const btVector3& vec) const { - btSoftBody::Node* const * n=&m_cluster->m_nodes[0]; - btScalar d=btDot(vec,n[0]->m_x); - int j=0; - for(int i=1,ni=m_cluster->m_nodes.size();im_nodes[0]; + btScalar d = btDot(vec, n[0]->m_x); + int j = 0; + for (int i = 1, ni = m_cluster->m_nodes.size(); i < ni; ++i) { - const btScalar k=btDot(vec,n[i]->m_x); - if(k>d) { d=k;j=i; } + const btScalar k = btDot(vec, n[i]->m_x); + if (k > d) + { + d = k; + j = i; + } } - return(n[j]->m_x); + return (n[j]->m_x); } - virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec)const + virtual btVector3 localGetSupportingVertexWithoutMargin(const btVector3& vec) const { - return(localGetSupportingVertex(vec)); + return (localGetSupportingVertex(vec)); } //notice that the vectors should be unit length - virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors,btVector3* supportVerticesOut,int numVectors) const - {} + virtual void batchedUnitVectorGetSupportingVertexWithoutMargin(const btVector3* vectors, btVector3* supportVerticesOut, int numVectors) const + { + } + virtual void calculateLocalInertia(btScalar mass, btVector3& inertia) const + { + } - virtual void calculateLocalInertia(btScalar mass,btVector3& inertia) const - {} + virtual void getAabb(const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const + { + } - virtual void getAabb(const btTransform& t,btVector3& aabbMin,btVector3& aabbMax) const - {} - - virtual int getShapeType() const { return SOFTBODY_SHAPE_PROXYTYPE; } + virtual int getShapeType() const { return SOFTBODY_SHAPE_PROXYTYPE; } //debugging - virtual const char* getName()const {return "SOFTCLUSTER";} + virtual const char* getName() const { return "SOFTCLUSTER"; } - virtual void setMargin(btScalar margin) + virtual void setMargin(btScalar margin) { btConvexInternalShape::setMargin(margin); } - virtual btScalar getMargin() const + virtual btScalar getMargin() const { return btConvexInternalShape::getMargin(); } @@ -171,229 +181,247 @@ public: // template -static inline void ZeroInitialize(T& value) +static inline void ZeroInitialize(T& value) { - memset(&value,0,sizeof(T)); + memset(&value, 0, sizeof(T)); } // template -static inline bool CompLess(const T& a,const T& b) -{ return(a -static inline bool CompGreater(const T& a,const T& b) -{ return(a>b); } -// -template -static inline T Lerp(const T& a,const T& b,btScalar t) -{ return(a+(b-a)*t); } -// -template -static inline T InvLerp(const T& a,const T& b,btScalar t) -{ return((b+a*t-b*t)/(a*b)); } -// -static inline btMatrix3x3 Lerp( const btMatrix3x3& a, - const btMatrix3x3& b, - btScalar t) +static inline bool CompLess(const T& a, const T& b) { - btMatrix3x3 r; - r[0]=Lerp(a[0],b[0],t); - r[1]=Lerp(a[1],b[1],t); - r[2]=Lerp(a[2],b[2],t); - return(r); + return (a < b); } // -static inline btVector3 Clamp(const btVector3& v,btScalar maxlength) +template +static inline bool CompGreater(const T& a, const T& b) { - const btScalar sql=v.length2(); - if(sql>(maxlength*maxlength)) - return((v*maxlength)/btSqrt(sql)); + return (a > b); +} +// +template +static inline T Lerp(const T& a, const T& b, btScalar t) +{ + return (a + (b - a) * t); +} +// +template +static inline T InvLerp(const T& a, const T& b, btScalar t) +{ + return ((b + a * t - b * t) / (a * b)); +} +// +static inline btMatrix3x3 Lerp(const btMatrix3x3& a, + const btMatrix3x3& b, + btScalar t) +{ + btMatrix3x3 r; + r[0] = Lerp(a[0], b[0], t); + r[1] = Lerp(a[1], b[1], t); + r[2] = Lerp(a[2], b[2], t); + return (r); +} +// +static inline btVector3 Clamp(const btVector3& v, btScalar maxlength) +{ + const btScalar sql = v.length2(); + if (sql > (maxlength * maxlength)) + return ((v * maxlength) / btSqrt(sql)); else - return(v); + return (v); } // template -static inline T Clamp(const T& x,const T& l,const T& h) -{ return(xh?h:x); } +static inline T Clamp(const T& x, const T& l, const T& h) +{ + return (x < l ? l : x > h ? h : x); +} // template -static inline T Sq(const T& x) -{ return(x*x); } +static inline T Sq(const T& x) +{ + return (x * x); +} // template -static inline T Cube(const T& x) -{ return(x*x*x); } +static inline T Cube(const T& x) +{ + return (x * x * x); +} // template -static inline T Sign(const T& x) -{ return((T)(x<0?-1:+1)); } +static inline T Sign(const T& x) +{ + return ((T)(x < 0 ? -1 : +1)); +} // template -static inline bool SameSign(const T& x,const T& y) -{ return((x*y)>0); } -// -static inline btScalar ClusterMetric(const btVector3& x,const btVector3& y) +static inline bool SameSign(const T& x, const T& y) { - const btVector3 d=x-y; - return(btFabs(d[0])+btFabs(d[1])+btFabs(d[2])); + return ((x * y) > 0); } // -static inline btMatrix3x3 ScaleAlongAxis(const btVector3& a,btScalar s) +static inline btScalar ClusterMetric(const btVector3& x, const btVector3& y) { - const btScalar xx=a.x()*a.x(); - const btScalar yy=a.y()*a.y(); - const btScalar zz=a.z()*a.z(); - const btScalar xy=a.x()*a.y(); - const btScalar yz=a.y()*a.z(); - const btScalar zx=a.z()*a.x(); - btMatrix3x3 m; - m[0]=btVector3(1-xx+xx*s,xy*s-xy,zx*s-zx); - m[1]=btVector3(xy*s-xy,1-yy+yy*s,yz*s-yz); - m[2]=btVector3(zx*s-zx,yz*s-yz,1-zz+zz*s); - return(m); + const btVector3 d = x - y; + return (btFabs(d[0]) + btFabs(d[1]) + btFabs(d[2])); } // -static inline btMatrix3x3 Cross(const btVector3& v) +static inline btMatrix3x3 ScaleAlongAxis(const btVector3& a, btScalar s) { - btMatrix3x3 m; - m[0]=btVector3(0,-v.z(),+v.y()); - m[1]=btVector3(+v.z(),0,-v.x()); - m[2]=btVector3(-v.y(),+v.x(),0); - return(m); + const btScalar xx = a.x() * a.x(); + const btScalar yy = a.y() * a.y(); + const btScalar zz = a.z() * a.z(); + const btScalar xy = a.x() * a.y(); + const btScalar yz = a.y() * a.z(); + const btScalar zx = a.z() * a.x(); + btMatrix3x3 m; + m[0] = btVector3(1 - xx + xx * s, xy * s - xy, zx * s - zx); + m[1] = btVector3(xy * s - xy, 1 - yy + yy * s, yz * s - yz); + m[2] = btVector3(zx * s - zx, yz * s - yz, 1 - zz + zz * s); + return (m); } // -static inline btMatrix3x3 Diagonal(btScalar x) +static inline btMatrix3x3 Cross(const btVector3& v) { - btMatrix3x3 m; - m[0]=btVector3(x,0,0); - m[1]=btVector3(0,x,0); - m[2]=btVector3(0,0,x); - return(m); + btMatrix3x3 m; + m[0] = btVector3(0, -v.z(), +v.y()); + m[1] = btVector3(+v.z(), 0, -v.x()); + m[2] = btVector3(-v.y(), +v.x(), 0); + return (m); } // -static inline btMatrix3x3 Add(const btMatrix3x3& a, - const btMatrix3x3& b) +static inline btMatrix3x3 Diagonal(btScalar x) { - btMatrix3x3 r; - for(int i=0;i<3;++i) r[i]=a[i]+b[i]; - return(r); + btMatrix3x3 m; + m[0] = btVector3(x, 0, 0); + m[1] = btVector3(0, x, 0); + m[2] = btVector3(0, 0, x); + return (m); } // -static inline btMatrix3x3 Sub(const btMatrix3x3& a, - const btMatrix3x3& b) +static inline btMatrix3x3 Add(const btMatrix3x3& a, + const btMatrix3x3& b) { - btMatrix3x3 r; - for(int i=0;i<3;++i) r[i]=a[i]-b[i]; - return(r); + btMatrix3x3 r; + for (int i = 0; i < 3; ++i) r[i] = a[i] + b[i]; + return (r); } // -static inline btMatrix3x3 Mul(const btMatrix3x3& a, - btScalar b) +static inline btMatrix3x3 Sub(const btMatrix3x3& a, + const btMatrix3x3& b) { - btMatrix3x3 r; - for(int i=0;i<3;++i) r[i]=a[i]*b; - return(r); + btMatrix3x3 r; + for (int i = 0; i < 3; ++i) r[i] = a[i] - b[i]; + return (r); } // -static inline void Orthogonalize(btMatrix3x3& m) +static inline btMatrix3x3 Mul(const btMatrix3x3& a, + btScalar b) { - m[2]=btCross(m[0],m[1]).normalized(); - m[1]=btCross(m[2],m[0]).normalized(); - m[0]=btCross(m[1],m[2]).normalized(); + btMatrix3x3 r; + for (int i = 0; i < 3; ++i) r[i] = a[i] * b; + return (r); } // -static inline btMatrix3x3 MassMatrix(btScalar im,const btMatrix3x3& iwi,const btVector3& r) +static inline void Orthogonalize(btMatrix3x3& m) { - const btMatrix3x3 cr=Cross(r); - return(Sub(Diagonal(im),cr*iwi*cr)); + m[2] = btCross(m[0], m[1]).normalized(); + m[1] = btCross(m[2], m[0]).normalized(); + m[0] = btCross(m[1], m[2]).normalized(); +} +// +static inline btMatrix3x3 MassMatrix(btScalar im, const btMatrix3x3& iwi, const btVector3& r) +{ + const btMatrix3x3 cr = Cross(r); + return (Sub(Diagonal(im), cr * iwi * cr)); } // -static inline btMatrix3x3 ImpulseMatrix( btScalar dt, - btScalar ima, - btScalar imb, - const btMatrix3x3& iwi, - const btVector3& r) +static inline btMatrix3x3 ImpulseMatrix(btScalar dt, + btScalar ima, + btScalar imb, + const btMatrix3x3& iwi, + const btVector3& r) { - return(Diagonal(1/dt)*Add(Diagonal(ima),MassMatrix(imb,iwi,r)).inverse()); + return (Diagonal(1 / dt) * Add(Diagonal(ima), MassMatrix(imb, iwi, r)).inverse()); } // -static inline btMatrix3x3 ImpulseMatrix( btScalar ima,const btMatrix3x3& iia,const btVector3& ra, - btScalar imb,const btMatrix3x3& iib,const btVector3& rb) +static inline btMatrix3x3 ImpulseMatrix(btScalar ima, const btMatrix3x3& iia, const btVector3& ra, + btScalar imb, const btMatrix3x3& iib, const btVector3& rb) { - return(Add(MassMatrix(ima,iia,ra),MassMatrix(imb,iib,rb)).inverse()); + return (Add(MassMatrix(ima, iia, ra), MassMatrix(imb, iib, rb)).inverse()); } // -static inline btMatrix3x3 AngularImpulseMatrix( const btMatrix3x3& iia, - const btMatrix3x3& iib) +static inline btMatrix3x3 AngularImpulseMatrix(const btMatrix3x3& iia, + const btMatrix3x3& iib) { - return(Add(iia,iib).inverse()); + return (Add(iia, iib).inverse()); } // -static inline btVector3 ProjectOnAxis( const btVector3& v, - const btVector3& a) +static inline btVector3 ProjectOnAxis(const btVector3& v, + const btVector3& a) { - return(a*btDot(v,a)); + return (a * btDot(v, a)); } // -static inline btVector3 ProjectOnPlane( const btVector3& v, - const btVector3& a) +static inline btVector3 ProjectOnPlane(const btVector3& v, + const btVector3& a) { - return(v-ProjectOnAxis(v,a)); + return (v - ProjectOnAxis(v, a)); } // -static inline void ProjectOrigin( const btVector3& a, - const btVector3& b, - btVector3& prj, - btScalar& sqd) +static inline void ProjectOrigin(const btVector3& a, + const btVector3& b, + btVector3& prj, + btScalar& sqd) { - const btVector3 d=b-a; - const btScalar m2=d.length2(); - if(m2>SIMD_EPSILON) - { - const btScalar t=Clamp(-btDot(a,d)/m2,0,1); - const btVector3 p=a+d*t; - const btScalar l2=p.length2(); - if(l2 SIMD_EPSILON) + { + const btScalar t = Clamp(-btDot(a, d) / m2, 0, 1); + const btVector3 p = a + d * t; + const btScalar l2 = p.length2(); + if (l2 < sqd) { - prj=p; - sqd=l2; + prj = p; + sqd = l2; } } } // -static inline void ProjectOrigin( const btVector3& a, - const btVector3& b, - const btVector3& c, - btVector3& prj, - btScalar& sqd) +static inline void ProjectOrigin(const btVector3& a, + const btVector3& b, + const btVector3& c, + btVector3& prj, + btScalar& sqd) { - const btVector3& q=btCross(b-a,c-a); - const btScalar m2=q.length2(); - if(m2>SIMD_EPSILON) + const btVector3& q = btCross(b - a, c - a); + const btScalar m2 = q.length2(); + if (m2 > SIMD_EPSILON) { - const btVector3 n=q/btSqrt(m2); - const btScalar k=btDot(a,n); - const btScalar k2=k*k; - if(k20)&& - (btDot(btCross(b-p,c-p),q)>0)&& - (btDot(btCross(c-p,a-p),q)>0)) - { - prj=p; - sqd=k2; + const btVector3 p = n * k; + if ((btDot(btCross(a - p, b - p), q) > 0) && + (btDot(btCross(b - p, c - p), q) > 0) && + (btDot(btCross(c - p, a - p), q) > 0)) + { + prj = p; + sqd = k2; } else { - ProjectOrigin(a,b,prj,sqd); - ProjectOrigin(b,c,prj,sqd); - ProjectOrigin(c,a,prj,sqd); + ProjectOrigin(a, b, prj, sqd); + ProjectOrigin(b, c, prj, sqd); + ProjectOrigin(c, a, prj, sqd); } } } @@ -401,155 +429,159 @@ static inline void ProjectOrigin( const btVector3& a, // template -static inline T BaryEval( const T& a, - const T& b, - const T& c, - const btVector3& coord) +static inline T BaryEval(const T& a, + const T& b, + const T& c, + const btVector3& coord) { - return(a*coord.x()+b*coord.y()+c*coord.z()); + return (a * coord.x() + b * coord.y() + c * coord.z()); } // -static inline btVector3 BaryCoord( const btVector3& a, - const btVector3& b, - const btVector3& c, - const btVector3& p) +static inline btVector3 BaryCoord(const btVector3& a, + const btVector3& b, + const btVector3& c, + const btVector3& p) { - const btScalar w[]={ btCross(a-p,b-p).length(), - btCross(b-p,c-p).length(), - btCross(c-p,a-p).length()}; - const btScalar isum=1/(w[0]+w[1]+w[2]); - return(btVector3(w[1]*isum,w[2]*isum,w[0]*isum)); + const btScalar w[] = {btCross(a - p, b - p).length(), + btCross(b - p, c - p).length(), + btCross(c - p, a - p).length()}; + const btScalar isum = 1 / (w[0] + w[1] + w[2]); + return (btVector3(w[1] * isum, w[2] * isum, w[0] * isum)); } // -inline static btScalar ImplicitSolve( btSoftBody::ImplicitFn* fn, - const btVector3& a, - const btVector3& b, - const btScalar accuracy, - const int maxiterations=256) +inline static btScalar ImplicitSolve(btSoftBody::ImplicitFn* fn, + const btVector3& a, + const btVector3& b, + const btScalar accuracy, + const int maxiterations = 256) { - btScalar span[2]={0,1}; - btScalar values[2]={fn->Eval(a),fn->Eval(b)}; - if(values[0]>values[1]) + btScalar span[2] = {0, 1}; + btScalar values[2] = {fn->Eval(a), fn->Eval(b)}; + if (values[0] > values[1]) { - btSwap(span[0],span[1]); - btSwap(values[0],values[1]); + btSwap(span[0], span[1]); + btSwap(values[0], values[1]); } - if(values[0]>-accuracy) return(-1); - if(values[1]<+accuracy) return(-1); - for(int i=0;i -accuracy) return (-1); + if (values[1] < +accuracy) return (-1); + for (int i = 0; i < maxiterations; ++i) { - const btScalar t=Lerp(span[0],span[1],values[0]/(values[0]-values[1])); - const btScalar v=fn->Eval(Lerp(a,b,t)); - if((t<=0)||(t>=1)) break; - if(btFabs(v)air_density; - if(wfi->water_density>0) - { - const btScalar depth=-(btDot(x,wfi->water_normal)+wfi->water_offset); - if(depth>0) + const btScalar t = Lerp(span[0], span[1], values[0] / (values[0] - values[1])); + const btScalar v = fn->Eval(Lerp(a, b, t)); + if ((t <= 0) || (t >= 1)) break; + if (btFabs(v) < accuracy) return (t); + if (v < 0) { - medium.m_density = wfi->water_density; - medium.m_pressure = depth*wfi->water_density*wfi->m_gravity.length(); + span[0] = t; + values[0] = v; + } + else + { + span[1] = t; + values[1] = v; + } + } + return (-1); +} + +inline static void EvaluateMedium(const btSoftBodyWorldInfo* wfi, + const btVector3& x, + btSoftBody::sMedium& medium) +{ + medium.m_velocity = btVector3(0, 0, 0); + medium.m_pressure = 0; + medium.m_density = wfi->air_density; + if (wfi->water_density > 0) + { + const btScalar depth = -(btDot(x, wfi->water_normal) + wfi->water_offset); + if (depth > 0) + { + medium.m_density = wfi->water_density; + medium.m_pressure = depth * wfi->water_density * wfi->m_gravity.length(); } } } - // -static inline btVector3 NormalizeAny(const btVector3& v) +static inline btVector3 NormalizeAny(const btVector3& v) { - const btScalar l=v.length(); - if(l>SIMD_EPSILON) - return(v/l); + const btScalar l = v.length(); + if (l > SIMD_EPSILON) + return (v / l); else - return(btVector3(0,0,0)); + return (btVector3(0, 0, 0)); } // -static inline btDbvtVolume VolumeOf( const btSoftBody::Face& f, - btScalar margin) +static inline btDbvtVolume VolumeOf(const btSoftBody::Face& f, + btScalar margin) { - const btVector3* pts[]={ &f.m_n[0]->m_x, - &f.m_n[1]->m_x, - &f.m_n[2]->m_x}; - btDbvtVolume vol=btDbvtVolume::FromPoints(pts,3); - vol.Expand(btVector3(margin,margin,margin)); - return(vol); + const btVector3* pts[] = {&f.m_n[0]->m_x, + &f.m_n[1]->m_x, + &f.m_n[2]->m_x}; + btDbvtVolume vol = btDbvtVolume::FromPoints(pts, 3); + vol.Expand(btVector3(margin, margin, margin)); + return (vol); } // -static inline btVector3 CenterOf( const btSoftBody::Face& f) +static inline btVector3 CenterOf(const btSoftBody::Face& f) { - return((f.m_n[0]->m_x+f.m_n[1]->m_x+f.m_n[2]->m_x)/3); + return ((f.m_n[0]->m_x + f.m_n[1]->m_x + f.m_n[2]->m_x) / 3); } // -static inline btScalar AreaOf( const btVector3& x0, - const btVector3& x1, - const btVector3& x2) +static inline btScalar AreaOf(const btVector3& x0, + const btVector3& x1, + const btVector3& x2) { - const btVector3 a=x1-x0; - const btVector3 b=x2-x0; - const btVector3 cr=btCross(a,b); - const btScalar area=cr.length(); - return(area); + const btVector3 a = x1 - x0; + const btVector3 b = x2 - x0; + const btVector3 cr = btCross(a, b); + const btScalar area = cr.length(); + return (area); } // -static inline btScalar VolumeOf( const btVector3& x0, - const btVector3& x1, - const btVector3& x2, - const btVector3& x3) +static inline btScalar VolumeOf(const btVector3& x0, + const btVector3& x1, + const btVector3& x2, + const btVector3& x3) { - const btVector3 a=x1-x0; - const btVector3 b=x2-x0; - const btVector3 c=x3-x0; - return(btDot(a,btCross(b,c))); + const btVector3 a = x1 - x0; + const btVector3 b = x2 - x0; + const btVector3 c = x3 - x0; + return (btDot(a, btCross(b, c))); } // - // -static inline void ApplyClampedForce( btSoftBody::Node& n, - const btVector3& f, - btScalar dt) +static inline void ApplyClampedForce(btSoftBody::Node& n, + const btVector3& f, + btScalar dt) { - const btScalar dtim=dt*n.m_im; - if((f*dtim).length2()>n.m_v.length2()) - {/* Clamp */ - n.m_f-=ProjectOnAxis(n.m_v,f.normalized())/dtim; + const btScalar dtim = dt * n.m_im; + if ((f * dtim).length2() > n.m_v.length2()) + { /* Clamp */ + n.m_f -= ProjectOnAxis(n.m_v, f.normalized()) / dtim; } else - {/* Apply */ - n.m_f+=f; + { /* Apply */ + n.m_f += f; } } // -static inline int MatchEdge( const btSoftBody::Node* a, - const btSoftBody::Node* b, - const btSoftBody::Node* ma, - const btSoftBody::Node* mb) +static inline int MatchEdge(const btSoftBody::Node* a, + const btSoftBody::Node* b, + const btSoftBody::Node* ma, + const btSoftBody::Node* mb) { - if((a==ma)&&(b==mb)) return(0); - if((a==mb)&&(b==ma)) return(1); - return(-1); + if ((a == ma) && (b == mb)) return (0); + if ((a == mb) && (b == ma)) return (1); + return (-1); } // @@ -557,58 +589,72 @@ static inline int MatchEdge( const btSoftBody::Node* a, // straitforward implementation of http://math.fullerton.edu/mathews/n2003/JacobiMethodMod.html // outputs are NOT sorted. // -struct btEigen +struct btEigen { - static int system(btMatrix3x3& a,btMatrix3x3* vectors,btVector3* values=0) + static int system(btMatrix3x3& a, btMatrix3x3* vectors, btVector3* values = 0) { - static const int maxiterations=16; - static const btScalar accuracy=(btScalar)0.0001; - btMatrix3x3& v=*vectors; - int iterations=0; + static const int maxiterations = 16; + static const btScalar accuracy = (btScalar)0.0001; + btMatrix3x3& v = *vectors; + int iterations = 0; vectors->setIdentity(); - do { - int p=0,q=1; - if(btFabs(a[p][q])accuracy) - { - const btScalar w=(a[q][q]-a[p][p])/(2*a[p][q]); - const btScalar z=btFabs(w); - const btScalar t=w/(z*(btSqrt(1+w*w)+z)); - if(t==t)/* [WARNING] let hope that one does not get thrown aways by some compilers... */ - { - const btScalar c=1/btSqrt(t*t+1); - const btScalar s=c*t; - mulPQ(a,c,s,p,q); - mulTPQ(a,c,s,p,q); - mulPQ(v,c,s,p,q); - } else break; - } else break; - } while((++iterations) accuracy) + { + const btScalar w = (a[q][q] - a[p][p]) / (2 * a[p][q]); + const btScalar z = btFabs(w); + const btScalar t = w / (z * (btSqrt(1 + w * w) + z)); + if (t == t) /* [WARNING] let hope that one does not get thrown aways by some compilers... */ + { + const btScalar c = 1 / btSqrt(t * t + 1); + const btScalar s = c * t; + mulPQ(a, c, s, p, q); + mulTPQ(a, c, s, p, q); + mulPQ(v, c, s, p, q); + } + else + break; + } + else + break; + } while ((++iterations) < maxiterations); + if (values) + { + *values = btVector3(a[0][0], a[1][1], a[2][2]); } - return(iterations); + return (iterations); } + private: - static inline void mulTPQ(btMatrix3x3& a,btScalar c,btScalar s,int p,int q) + static inline void mulTPQ(btMatrix3x3& a, btScalar c, btScalar s, int p, int q) { - const btScalar m[2][3]={ {a[p][0],a[p][1],a[p][2]}, - {a[q][0],a[q][1],a[q][2]}}; + const btScalar m[2][3] = {{a[p][0], a[p][1], a[p][2]}, + {a[q][0], a[q][1], a[q][2]}}; int i; - for(i=0;i<3;++i) a[p][i]=c*m[0][i]-s*m[1][i]; - for(i=0;i<3;++i) a[q][i]=c*m[1][i]+s*m[0][i]; + for (i = 0; i < 3; ++i) a[p][i] = c * m[0][i] - s * m[1][i]; + for (i = 0; i < 3; ++i) a[q][i] = c * m[1][i] + s * m[0][i]; } - static inline void mulPQ(btMatrix3x3& a,btScalar c,btScalar s,int p,int q) + static inline void mulPQ(btMatrix3x3& a, btScalar c, btScalar s, int p, int q) { - const btScalar m[2][3]={ {a[0][p],a[1][p],a[2][p]}, - {a[0][q],a[1][q],a[2][q]}}; + const btScalar m[2][3] = {{a[0][p], a[1][p], a[2][p]}, + {a[0][q], a[1][q], a[2][q]}}; int i; - for(i=0;i<3;++i) a[i][p]=c*m[0][i]-s*m[1][i]; - for(i=0;i<3;++i) a[i][q]=c*m[1][i]+s*m[0][i]; + for (i = 0; i < 3; ++i) a[i][p] = c * m[0][i] - s * m[1][i]; + for (i = 0; i < 3; ++i) a[i][q] = c * m[1][i] + s * m[0][i]; } }; @@ -616,9 +662,9 @@ private: // Polar decomposition, // "Computing the Polar Decomposition with Applications", Nicholas J. Higham, 1986. // -static inline int PolarDecompose( const btMatrix3x3& m,btMatrix3x3& q,btMatrix3x3& s) +static inline int PolarDecompose(const btMatrix3x3& m, btMatrix3x3& q, btMatrix3x3& s) { - static const btPolarDecomposition polar; + static const btPolarDecomposition polar; return polar.decompose(m, q, s); } @@ -630,282 +676,284 @@ struct btSoftColliders // // ClusterBase // - struct ClusterBase : btDbvt::ICollide + struct ClusterBase : btDbvt::ICollide { - btScalar erp; - btScalar idt; - btScalar m_margin; - btScalar friction; - btScalar threshold; + btScalar erp; + btScalar idt; + btScalar m_margin; + btScalar friction; + btScalar threshold; ClusterBase() { - erp =(btScalar)1; - idt =0; - m_margin =0; - friction =0; - threshold =(btScalar)0; + erp = (btScalar)1; + idt = 0; + m_margin = 0; + friction = 0; + threshold = (btScalar)0; } - bool SolveContact( const btGjkEpaSolver2::sResults& res, - btSoftBody::Body ba,const btSoftBody::Body bb, - btSoftBody::CJoint& joint) + bool SolveContact(const btGjkEpaSolver2::sResults& res, + btSoftBody::Body ba, const btSoftBody::Body bb, + btSoftBody::CJoint& joint) { - if(res.distancedata; - btSoftClusterCollisionShape cshape(cluster); - - const btConvexShape* rshape=(const btConvexShape*)m_colObjWrap->getCollisionShape(); + btSoftBody::Cluster* cluster = (btSoftBody::Cluster*)leaf->data; + btSoftClusterCollisionShape cshape(cluster); + + const btConvexShape* rshape = (const btConvexShape*)m_colObjWrap->getCollisionShape(); ///don't collide an anchored cluster with a static/kinematic object - if(m_colObjWrap->getCollisionObject()->isStaticOrKinematicObject() && cluster->m_containsAnchor) + if (m_colObjWrap->getCollisionObject()->isStaticOrKinematicObject() && cluster->m_containsAnchor) return; - btGjkEpaSolver2::sResults res; - if(btGjkEpaSolver2::SignedDistance( &cshape,btTransform::getIdentity(), - rshape,m_colObjWrap->getWorldTransform(), - btVector3(1,0,0),res)) + btGjkEpaSolver2::sResults res; + if (btGjkEpaSolver2::SignedDistance(&cshape, btTransform::getIdentity(), + rshape, m_colObjWrap->getWorldTransform(), + btVector3(1, 0, 0), res)) { - btSoftBody::CJoint joint; - if(SolveContact(res,cluster,m_colObjWrap->getCollisionObject(),joint))//prb,joint)) + btSoftBody::CJoint joint; + if (SolveContact(res, cluster, m_colObjWrap->getCollisionObject(), joint)) //prb,joint)) { - btSoftBody::CJoint* pj=new(btAlignedAlloc(sizeof(btSoftBody::CJoint),16)) btSoftBody::CJoint(); - *pj=joint;psb->m_joints.push_back(pj); - if(m_colObjWrap->getCollisionObject()->isStaticOrKinematicObject()) + btSoftBody::CJoint* pj = new (btAlignedAlloc(sizeof(btSoftBody::CJoint), 16)) btSoftBody::CJoint(); + *pj = joint; + psb->m_joints.push_back(pj); + if (m_colObjWrap->getCollisionObject()->isStaticOrKinematicObject()) { - pj->m_erp *= psb->m_cfg.kSKHR_CL; - pj->m_split *= psb->m_cfg.kSK_SPLT_CL; + pj->m_erp *= psb->m_cfg.kSKHR_CL; + pj->m_split *= psb->m_cfg.kSK_SPLT_CL; } else { - pj->m_erp *= psb->m_cfg.kSRHR_CL; - pj->m_split *= psb->m_cfg.kSR_SPLT_CL; + pj->m_erp *= psb->m_cfg.kSRHR_CL; + pj->m_split *= psb->m_cfg.kSR_SPLT_CL; } } } } - void ProcessColObj(btSoftBody* ps,const btCollisionObjectWrapper* colObWrap) + void ProcessColObj(btSoftBody* ps, const btCollisionObjectWrapper* colObWrap) { - psb = ps; - m_colObjWrap = colObWrap; - idt = ps->m_sst.isdt; - m_margin = m_colObjWrap->getCollisionShape()->getMargin()+psb->getCollisionShape()->getMargin(); + psb = ps; + m_colObjWrap = colObWrap; + idt = ps->m_sst.isdt; + m_margin = m_colObjWrap->getCollisionShape()->getMargin() + psb->getCollisionShape()->getMargin(); ///Bullet rigid body uses multiply instead of minimum to determine combined friction. Some customization would be useful. - friction = btMin(psb->m_cfg.kDF,m_colObjWrap->getCollisionObject()->getFriction()); - btVector3 mins; - btVector3 maxs; + friction = btMin(psb->m_cfg.kDF, m_colObjWrap->getCollisionObject()->getFriction()); + btVector3 mins; + btVector3 maxs; - ATTRIBUTE_ALIGNED16(btDbvtVolume) volume; - colObWrap->getCollisionShape()->getAabb(colObWrap->getWorldTransform(),mins,maxs); - volume=btDbvtVolume::FromMM(mins,maxs); - volume.Expand(btVector3(1,1,1)*m_margin); - ps->m_cdbvt.collideTV(ps->m_cdbvt.m_root,volume,*this); - } + ATTRIBUTE_ALIGNED16(btDbvtVolume) + volume; + colObWrap->getCollisionShape()->getAabb(colObWrap->getWorldTransform(), mins, maxs); + volume = btDbvtVolume::FromMM(mins, maxs); + volume.Expand(btVector3(1, 1, 1) * m_margin); + ps->m_cdbvt.collideTV(ps->m_cdbvt.m_root, volume, *this); + } }; // // CollideCL_SS // - struct CollideCL_SS : ClusterBase + struct CollideCL_SS : ClusterBase { - btSoftBody* bodies[2]; - void Process(const btDbvtNode* la,const btDbvtNode* lb) + btSoftBody* bodies[2]; + void Process(const btDbvtNode* la, const btDbvtNode* lb) { - btSoftBody::Cluster* cla=(btSoftBody::Cluster*)la->data; - btSoftBody::Cluster* clb=(btSoftBody::Cluster*)lb->data; + btSoftBody::Cluster* cla = (btSoftBody::Cluster*)la->data; + btSoftBody::Cluster* clb = (btSoftBody::Cluster*)lb->data; - - bool connected=false; - if ((bodies[0]==bodies[1])&&(bodies[0]->m_clusterConnectivity.size())) + bool connected = false; + if ((bodies[0] == bodies[1]) && (bodies[0]->m_clusterConnectivity.size())) { - connected = bodies[0]->m_clusterConnectivity[cla->m_clusterIndex+bodies[0]->m_clusters.size()*clb->m_clusterIndex]; + connected = bodies[0]->m_clusterConnectivity[cla->m_clusterIndex + bodies[0]->m_clusters.size() * clb->m_clusterIndex]; } if (!connected) { - btSoftClusterCollisionShape csa(cla); - btSoftClusterCollisionShape csb(clb); - btGjkEpaSolver2::sResults res; - if(btGjkEpaSolver2::SignedDistance( &csa,btTransform::getIdentity(), - &csb,btTransform::getIdentity(), - cla->m_com-clb->m_com,res)) + btSoftClusterCollisionShape csa(cla); + btSoftClusterCollisionShape csb(clb); + btGjkEpaSolver2::sResults res; + if (btGjkEpaSolver2::SignedDistance(&csa, btTransform::getIdentity(), + &csb, btTransform::getIdentity(), + cla->m_com - clb->m_com, res)) { - btSoftBody::CJoint joint; - if(SolveContact(res,cla,clb,joint)) + btSoftBody::CJoint joint; + if (SolveContact(res, cla, clb, joint)) { - btSoftBody::CJoint* pj=new(btAlignedAlloc(sizeof(btSoftBody::CJoint),16)) btSoftBody::CJoint(); - *pj=joint;bodies[0]->m_joints.push_back(pj); - pj->m_erp *= btMax(bodies[0]->m_cfg.kSSHR_CL,bodies[1]->m_cfg.kSSHR_CL); - pj->m_split *= (bodies[0]->m_cfg.kSS_SPLT_CL+bodies[1]->m_cfg.kSS_SPLT_CL)/2; + btSoftBody::CJoint* pj = new (btAlignedAlloc(sizeof(btSoftBody::CJoint), 16)) btSoftBody::CJoint(); + *pj = joint; + bodies[0]->m_joints.push_back(pj); + pj->m_erp *= btMax(bodies[0]->m_cfg.kSSHR_CL, bodies[1]->m_cfg.kSSHR_CL); + pj->m_split *= (bodies[0]->m_cfg.kSS_SPLT_CL + bodies[1]->m_cfg.kSS_SPLT_CL) / 2; } } - } else + } + else { - static int count=0; + static int count = 0; count++; //printf("count=%d\n",count); - } } - void ProcessSoftSoft(btSoftBody* psa,btSoftBody* psb) + void ProcessSoftSoft(btSoftBody* psa, btSoftBody* psb) { - idt = psa->m_sst.isdt; + idt = psa->m_sst.isdt; //m_margin = (psa->getCollisionShape()->getMargin()+psb->getCollisionShape()->getMargin())/2; - m_margin = (psa->getCollisionShape()->getMargin()+psb->getCollisionShape()->getMargin()); - friction = btMin(psa->m_cfg.kDF,psb->m_cfg.kDF); - bodies[0] = psa; - bodies[1] = psb; - psa->m_cdbvt.collideTT(psa->m_cdbvt.m_root,psb->m_cdbvt.m_root,*this); - } + m_margin = (psa->getCollisionShape()->getMargin() + psb->getCollisionShape()->getMargin()); + friction = btMin(psa->m_cfg.kDF, psb->m_cfg.kDF); + bodies[0] = psa; + bodies[1] = psb; + psa->m_cdbvt.collideTT(psa->m_cdbvt.m_root, psb->m_cdbvt.m_root, *this); + } }; // // CollideSDF_RS // - struct CollideSDF_RS : btDbvt::ICollide + struct CollideSDF_RS : btDbvt::ICollide { - void Process(const btDbvtNode* leaf) + void Process(const btDbvtNode* leaf) { - btSoftBody::Node* node=(btSoftBody::Node*)leaf->data; + btSoftBody::Node* node = (btSoftBody::Node*)leaf->data; DoNode(*node); } - void DoNode(btSoftBody::Node& n) const + void DoNode(btSoftBody::Node& n) const { - const btScalar m=n.m_im>0?dynmargin:stamargin; - btSoftBody::RContact c; + const btScalar m = n.m_im > 0 ? dynmargin : stamargin; + btSoftBody::RContact c; - if( (!n.m_battach)&& - psb->checkContact(m_colObj1Wrap,n.m_x,m,c.m_cti)) + if ((!n.m_battach) && + psb->checkContact(m_colObj1Wrap, n.m_x, m, c.m_cti)) { - const btScalar ima=n.m_im; - const btScalar imb= m_rigidBody? m_rigidBody->getInvMass() : 0.f; - const btScalar ms=ima+imb; - if(ms>0) + const btScalar ima = n.m_im; + const btScalar imb = m_rigidBody ? m_rigidBody->getInvMass() : 0.f; + const btScalar ms = ima + imb; + if (ms > 0) { - const btTransform& wtr=m_rigidBody?m_rigidBody->getWorldTransform() : m_colObj1Wrap->getCollisionObject()->getWorldTransform(); - static const btMatrix3x3 iwiStatic(0,0,0,0,0,0,0,0,0); - const btMatrix3x3& iwi=m_rigidBody?m_rigidBody->getInvInertiaTensorWorld() : iwiStatic; - const btVector3 ra=n.m_x-wtr.getOrigin(); - const btVector3 va=m_rigidBody ? m_rigidBody->getVelocityInLocalPoint(ra)*psb->m_sst.sdt : btVector3(0,0,0); - const btVector3 vb=n.m_x-n.m_q; - const btVector3 vr=vb-va; - const btScalar dn=btDot(vr,c.m_cti.m_normal); - const btVector3 fv=vr-c.m_cti.m_normal*dn; - const btScalar fc=psb->m_cfg.kDF*m_colObj1Wrap->getCollisionObject()->getFriction(); - c.m_node = &n; - c.m_c0 = ImpulseMatrix(psb->m_sst.sdt,ima,imb,iwi,ra); - c.m_c1 = ra; - c.m_c2 = ima*psb->m_sst.sdt; - c.m_c3 = fv.length2()<(dn*fc*dn*fc)?0:1-fc; - c.m_c4 = m_colObj1Wrap->getCollisionObject()->isStaticOrKinematicObject()?psb->m_cfg.kKHR:psb->m_cfg.kCHR; + const btTransform& wtr = m_rigidBody ? m_rigidBody->getWorldTransform() : m_colObj1Wrap->getCollisionObject()->getWorldTransform(); + static const btMatrix3x3 iwiStatic(0, 0, 0, 0, 0, 0, 0, 0, 0); + const btMatrix3x3& iwi = m_rigidBody ? m_rigidBody->getInvInertiaTensorWorld() : iwiStatic; + const btVector3 ra = n.m_x - wtr.getOrigin(); + const btVector3 va = m_rigidBody ? m_rigidBody->getVelocityInLocalPoint(ra) * psb->m_sst.sdt : btVector3(0, 0, 0); + const btVector3 vb = n.m_x - n.m_q; + const btVector3 vr = vb - va; + const btScalar dn = btDot(vr, c.m_cti.m_normal); + const btVector3 fv = vr - c.m_cti.m_normal * dn; + const btScalar fc = psb->m_cfg.kDF * m_colObj1Wrap->getCollisionObject()->getFriction(); + c.m_node = &n; + c.m_c0 = ImpulseMatrix(psb->m_sst.sdt, ima, imb, iwi, ra); + c.m_c1 = ra; + c.m_c2 = ima * psb->m_sst.sdt; + c.m_c3 = fv.length2() < (dn * fc * dn * fc) ? 0 : 1 - fc; + c.m_c4 = m_colObj1Wrap->getCollisionObject()->isStaticOrKinematicObject() ? psb->m_cfg.kKHR : psb->m_cfg.kCHR; psb->m_rcontacts.push_back(c); if (m_rigidBody) m_rigidBody->activate(); } } } - btSoftBody* psb; - const btCollisionObjectWrapper* m_colObj1Wrap; - btRigidBody* m_rigidBody; - btScalar dynmargin; - btScalar stamargin; + btSoftBody* psb; + const btCollisionObjectWrapper* m_colObj1Wrap; + btRigidBody* m_rigidBody; + btScalar dynmargin; + btScalar stamargin; }; // // CollideVF_SS // - struct CollideVF_SS : btDbvt::ICollide + struct CollideVF_SS : btDbvt::ICollide { - void Process(const btDbvtNode* lnode, - const btDbvtNode* lface) + void Process(const btDbvtNode* lnode, + const btDbvtNode* lface) { - btSoftBody::Node* node=(btSoftBody::Node*)lnode->data; - btSoftBody::Face* face=(btSoftBody::Face*)lface->data; - btVector3 o=node->m_x; - btVector3 p; - btScalar d=SIMD_INFINITY; - ProjectOrigin( face->m_n[0]->m_x-o, - face->m_n[1]->m_x-o, - face->m_n[2]->m_x-o, - p,d); - const btScalar m=mrg+(o-node->m_q).length()*2; - if(d<(m*m)) + btSoftBody::Node* node = (btSoftBody::Node*)lnode->data; + btSoftBody::Face* face = (btSoftBody::Face*)lface->data; + btVector3 o = node->m_x; + btVector3 p; + btScalar d = SIMD_INFINITY; + ProjectOrigin(face->m_n[0]->m_x - o, + face->m_n[1]->m_x - o, + face->m_n[2]->m_x - o, + p, d); + const btScalar m = mrg + (o - node->m_q).length() * 2; + if (d < (m * m)) { - const btSoftBody::Node* n[]={face->m_n[0],face->m_n[1],face->m_n[2]}; - const btVector3 w=BaryCoord(n[0]->m_x,n[1]->m_x,n[2]->m_x,p+o); - const btScalar ma=node->m_im; - btScalar mb=BaryEval(n[0]->m_im,n[1]->m_im,n[2]->m_im,w); - if( (n[0]->m_im<=0)|| - (n[1]->m_im<=0)|| - (n[2]->m_im<=0)) + const btSoftBody::Node* n[] = {face->m_n[0], face->m_n[1], face->m_n[2]}; + const btVector3 w = BaryCoord(n[0]->m_x, n[1]->m_x, n[2]->m_x, p + o); + const btScalar ma = node->m_im; + btScalar mb = BaryEval(n[0]->m_im, n[1]->m_im, n[2]->m_im, w); + if ((n[0]->m_im <= 0) || + (n[1]->m_im <= 0) || + (n[2]->m_im <= 0)) { - mb=0; + mb = 0; } - const btScalar ms=ma+mb; - if(ms>0) + const btScalar ms = ma + mb; + if (ms > 0) { - btSoftBody::SContact c; - c.m_normal = p/-btSqrt(d); - c.m_margin = m; - c.m_node = node; - c.m_face = face; - c.m_weights = w; - c.m_friction = btMax(psb[0]->m_cfg.kDF,psb[1]->m_cfg.kDF); - c.m_cfm[0] = ma/ms*psb[0]->m_cfg.kSHR; - c.m_cfm[1] = mb/ms*psb[1]->m_cfg.kSHR; + btSoftBody::SContact c; + c.m_normal = p / -btSqrt(d); + c.m_margin = m; + c.m_node = node; + c.m_face = face; + c.m_weights = w; + c.m_friction = btMax(psb[0]->m_cfg.kDF, psb[1]->m_cfg.kDF); + c.m_cfm[0] = ma / ms * psb[0]->m_cfg.kSHR; + c.m_cfm[1] = mb / ms * psb[1]->m_cfg.kSHR; psb[0]->m_scontacts.push_back(c); } - } + } } - btSoftBody* psb[2]; - btScalar mrg; + btSoftBody* psb[2]; + btScalar mrg; }; }; -#endif //_BT_SOFT_BODY_INTERNALS_H +#endif //_BT_SOFT_BODY_INTERNALS_H diff --git a/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp b/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp index f5a67f6d8..3127369cc 100644 --- a/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp +++ b/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.cpp @@ -23,27 +23,27 @@ subject to the following restrictions: #define ENABLE_SOFTBODY_CONCAVE_COLLISIONS 1 btSoftBodyRigidBodyCollisionConfiguration::btSoftBodyRigidBodyCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo) -:btDefaultCollisionConfiguration(constructionInfo) + : btDefaultCollisionConfiguration(constructionInfo) { void* mem; - mem = btAlignedAlloc(sizeof(btSoftSoftCollisionAlgorithm::CreateFunc),16); - m_softSoftCreateFunc = new(mem) btSoftSoftCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc(sizeof(btSoftSoftCollisionAlgorithm::CreateFunc), 16); + m_softSoftCreateFunc = new (mem) btSoftSoftCollisionAlgorithm::CreateFunc; - mem = btAlignedAlloc(sizeof(btSoftRigidCollisionAlgorithm::CreateFunc),16); - m_softRigidConvexCreateFunc = new(mem) btSoftRigidCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc(sizeof(btSoftRigidCollisionAlgorithm::CreateFunc), 16); + m_softRigidConvexCreateFunc = new (mem) btSoftRigidCollisionAlgorithm::CreateFunc; - mem = btAlignedAlloc(sizeof(btSoftRigidCollisionAlgorithm::CreateFunc),16); - m_swappedSoftRigidConvexCreateFunc = new(mem) btSoftRigidCollisionAlgorithm::CreateFunc; - m_swappedSoftRigidConvexCreateFunc->m_swapped=true; + mem = btAlignedAlloc(sizeof(btSoftRigidCollisionAlgorithm::CreateFunc), 16); + m_swappedSoftRigidConvexCreateFunc = new (mem) btSoftRigidCollisionAlgorithm::CreateFunc; + m_swappedSoftRigidConvexCreateFunc->m_swapped = true; #ifdef ENABLE_SOFTBODY_CONCAVE_COLLISIONS - mem = btAlignedAlloc(sizeof(btSoftBodyConcaveCollisionAlgorithm::CreateFunc),16); - m_softRigidConcaveCreateFunc = new(mem) btSoftBodyConcaveCollisionAlgorithm::CreateFunc; + mem = btAlignedAlloc(sizeof(btSoftBodyConcaveCollisionAlgorithm::CreateFunc), 16); + m_softRigidConcaveCreateFunc = new (mem) btSoftBodyConcaveCollisionAlgorithm::CreateFunc; - mem = btAlignedAlloc(sizeof(btSoftBodyConcaveCollisionAlgorithm::CreateFunc),16); - m_swappedSoftRigidConcaveCreateFunc = new(mem) btSoftBodyConcaveCollisionAlgorithm::SwappedCreateFunc; - m_swappedSoftRigidConcaveCreateFunc->m_swapped=true; + mem = btAlignedAlloc(sizeof(btSoftBodyConcaveCollisionAlgorithm::CreateFunc), 16); + m_swappedSoftRigidConcaveCreateFunc = new (mem) btSoftBodyConcaveCollisionAlgorithm::SwappedCreateFunc; + m_swappedSoftRigidConcaveCreateFunc->m_swapped = true; #endif //replace pool by a new one, with potential larger size @@ -53,82 +53,79 @@ btSoftBodyRigidBodyCollisionConfiguration::btSoftBodyRigidBodyCollisionConfigura int curElemSize = m_collisionAlgorithmPool->getElementSize(); ///calculate maximum element size, big enough to fit any collision algorithm in the memory pool - int maxSize0 = sizeof(btSoftSoftCollisionAlgorithm); int maxSize1 = sizeof(btSoftRigidCollisionAlgorithm); int maxSize2 = sizeof(btSoftBodyConcaveCollisionAlgorithm); - int collisionAlgorithmMaxElementSize = btMax(maxSize0,maxSize1); - collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize,maxSize2); - + int collisionAlgorithmMaxElementSize = btMax(maxSize0, maxSize1); + collisionAlgorithmMaxElementSize = btMax(collisionAlgorithmMaxElementSize, maxSize2); + if (collisionAlgorithmMaxElementSize > curElemSize) { m_collisionAlgorithmPool->~btPoolAllocator(); btAlignedFree(m_collisionAlgorithmPool); - void* mem = btAlignedAlloc(sizeof(btPoolAllocator),16); - m_collisionAlgorithmPool = new(mem) btPoolAllocator(collisionAlgorithmMaxElementSize,constructionInfo.m_defaultMaxCollisionAlgorithmPoolSize); + void* mem = btAlignedAlloc(sizeof(btPoolAllocator), 16); + m_collisionAlgorithmPool = new (mem) btPoolAllocator(collisionAlgorithmMaxElementSize, constructionInfo.m_defaultMaxCollisionAlgorithmPoolSize); } } - } btSoftBodyRigidBodyCollisionConfiguration::~btSoftBodyRigidBodyCollisionConfiguration() { m_softSoftCreateFunc->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_softSoftCreateFunc); + btAlignedFree(m_softSoftCreateFunc); m_softRigidConvexCreateFunc->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_softRigidConvexCreateFunc); + btAlignedFree(m_softRigidConvexCreateFunc); m_swappedSoftRigidConvexCreateFunc->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_swappedSoftRigidConvexCreateFunc); + btAlignedFree(m_swappedSoftRigidConvexCreateFunc); #ifdef ENABLE_SOFTBODY_CONCAVE_COLLISIONS m_softRigidConcaveCreateFunc->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_softRigidConcaveCreateFunc); + btAlignedFree(m_softRigidConcaveCreateFunc); m_swappedSoftRigidConcaveCreateFunc->~btCollisionAlgorithmCreateFunc(); - btAlignedFree( m_swappedSoftRigidConcaveCreateFunc); + btAlignedFree(m_swappedSoftRigidConcaveCreateFunc); #endif } ///creation of soft-soft and soft-rigid, and otherwise fallback to base class implementation -btCollisionAlgorithmCreateFunc* btSoftBodyRigidBodyCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1) +btCollisionAlgorithmCreateFunc* btSoftBodyRigidBodyCollisionConfiguration::getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1) { - ///try to handle the softbody interactions first - if ((proxyType0 == SOFTBODY_SHAPE_PROXYTYPE ) && (proxyType1==SOFTBODY_SHAPE_PROXYTYPE)) + if ((proxyType0 == SOFTBODY_SHAPE_PROXYTYPE) && (proxyType1 == SOFTBODY_SHAPE_PROXYTYPE)) { - return m_softSoftCreateFunc; + return m_softSoftCreateFunc; } ///softbody versus convex - if (proxyType0 == SOFTBODY_SHAPE_PROXYTYPE && btBroadphaseProxy::isConvex(proxyType1)) + if (proxyType0 == SOFTBODY_SHAPE_PROXYTYPE && btBroadphaseProxy::isConvex(proxyType1)) { - return m_softRigidConvexCreateFunc; + return m_softRigidConvexCreateFunc; } ///convex versus soft body - if (btBroadphaseProxy::isConvex(proxyType0) && proxyType1 == SOFTBODY_SHAPE_PROXYTYPE ) + if (btBroadphaseProxy::isConvex(proxyType0) && proxyType1 == SOFTBODY_SHAPE_PROXYTYPE) { - return m_swappedSoftRigidConvexCreateFunc; + return m_swappedSoftRigidConvexCreateFunc; } #ifdef ENABLE_SOFTBODY_CONCAVE_COLLISIONS ///softbody versus convex - if (proxyType0 == SOFTBODY_SHAPE_PROXYTYPE && btBroadphaseProxy::isConcave(proxyType1)) + if (proxyType0 == SOFTBODY_SHAPE_PROXYTYPE && btBroadphaseProxy::isConcave(proxyType1)) { - return m_softRigidConcaveCreateFunc; + return m_softRigidConcaveCreateFunc; } ///convex versus soft body - if (btBroadphaseProxy::isConcave(proxyType0) && proxyType1 == SOFTBODY_SHAPE_PROXYTYPE ) + if (btBroadphaseProxy::isConcave(proxyType0) && proxyType1 == SOFTBODY_SHAPE_PROXYTYPE) { - return m_swappedSoftRigidConcaveCreateFunc; + return m_swappedSoftRigidConcaveCreateFunc; } #endif ///fallback to the regular rigid collision shape - return btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(proxyType0,proxyType1); + return btDefaultCollisionConfiguration::getCollisionAlgorithmCreateFunc(proxyType0, proxyType1); } diff --git a/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h b/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h index 21addcfe2..0396a52da 100644 --- a/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h +++ b/src/BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h @@ -21,28 +21,23 @@ subject to the following restrictions: class btVoronoiSimplexSolver; class btGjkEpaPenetrationDepthSolver; - ///btSoftBodyRigidBodyCollisionConfiguration add softbody interaction on top of btDefaultCollisionConfiguration -class btSoftBodyRigidBodyCollisionConfiguration : public btDefaultCollisionConfiguration +class btSoftBodyRigidBodyCollisionConfiguration : public btDefaultCollisionConfiguration { - //default CreationFunctions, filling the m_doubleDispatch table - btCollisionAlgorithmCreateFunc* m_softSoftCreateFunc; - btCollisionAlgorithmCreateFunc* m_softRigidConvexCreateFunc; - btCollisionAlgorithmCreateFunc* m_swappedSoftRigidConvexCreateFunc; - btCollisionAlgorithmCreateFunc* m_softRigidConcaveCreateFunc; - btCollisionAlgorithmCreateFunc* m_swappedSoftRigidConcaveCreateFunc; + btCollisionAlgorithmCreateFunc* m_softSoftCreateFunc; + btCollisionAlgorithmCreateFunc* m_softRigidConvexCreateFunc; + btCollisionAlgorithmCreateFunc* m_swappedSoftRigidConvexCreateFunc; + btCollisionAlgorithmCreateFunc* m_softRigidConcaveCreateFunc; + btCollisionAlgorithmCreateFunc* m_swappedSoftRigidConcaveCreateFunc; public: - btSoftBodyRigidBodyCollisionConfiguration(const btDefaultCollisionConstructionInfo& constructionInfo = btDefaultCollisionConstructionInfo()); virtual ~btSoftBodyRigidBodyCollisionConfiguration(); ///creation of soft-soft and soft-rigid, and otherwise fallback to base class implementation - virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0,int proxyType1); - + virtual btCollisionAlgorithmCreateFunc* getCollisionAlgorithmCreateFunc(int proxyType0, int proxyType1); }; -#endif //BT_SOFTBODY_RIGIDBODY_COLLISION_CONFIGURATION - +#endif //BT_SOFTBODY_RIGIDBODY_COLLISION_CONFIGURATION diff --git a/src/BulletSoftBody/btSoftBodySolverVertexBuffer.h b/src/BulletSoftBody/btSoftBodySolverVertexBuffer.h index c4733d640..bc538db4a 100644 --- a/src/BulletSoftBody/btSoftBodySolverVertexBuffer.h +++ b/src/BulletSoftBody/btSoftBodySolverVertexBuffer.h @@ -16,7 +16,6 @@ subject to the following restrictions: #ifndef BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_H #define BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_H - class btVertexBufferDescriptor { public: @@ -27,8 +26,7 @@ public: OPENGL_BUFFER }; -protected: - +protected: bool m_hasVertexPositions; bool m_hasNormals; @@ -51,7 +49,6 @@ public: virtual ~btVertexBufferDescriptor() { - } virtual bool hasVertexPositions() const @@ -102,7 +99,6 @@ public: } }; - class btCPUVertexBufferDescriptor : public btVertexBufferDescriptor { protected: @@ -114,7 +110,7 @@ public: * vertexOffset is the offset in floats to the first vertex. * vertexStride is the stride in floats between vertices. */ - btCPUVertexBufferDescriptor( float *basePointer, int vertexOffset, int vertexStride ) + btCPUVertexBufferDescriptor(float *basePointer, int vertexOffset, int vertexStride) { m_basePointer = basePointer; m_vertexOffset = vertexOffset; @@ -127,7 +123,7 @@ public: * vertexOffset is the offset in floats to the first vertex. * vertexStride is the stride in floats between vertices. */ - btCPUVertexBufferDescriptor( float *basePointer, int vertexOffset, int vertexStride, int normalOffset, int normalStride ) + btCPUVertexBufferDescriptor(float *basePointer, int vertexOffset, int vertexStride, int normalOffset, int normalStride) { m_basePointer = basePointer; @@ -142,7 +138,6 @@ public: virtual ~btCPUVertexBufferDescriptor() { - } /** @@ -162,4 +157,4 @@ public: } }; -#endif // #ifndef BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_H +#endif // #ifndef BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_H diff --git a/src/BulletSoftBody/btSoftBodySolvers.h b/src/BulletSoftBody/btSoftBodySolvers.h index 6947bc27d..dcf508265 100644 --- a/src/BulletSoftBody/btSoftBodySolvers.h +++ b/src/BulletSoftBody/btSoftBodySolvers.h @@ -18,7 +18,6 @@ subject to the following restrictions: #include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h" - class btSoftBodyTriangleData; class btSoftBodyLinkData; class btSoftBodyVertexData; @@ -26,7 +25,6 @@ class btVertexBufferDescriptor; class btCollisionObject; class btSoftBody; - class btSoftBodySolver { public: @@ -40,17 +38,15 @@ public: DX_SIMD_SOLVER }; - protected: int m_numberOfPositionIterations; int m_numberOfVelocityIterations; // Simulation timescale float m_timeScale; - + public: - btSoftBodySolver() : - m_numberOfPositionIterations( 10 ), - m_timeScale( 1 ) + btSoftBodySolver() : m_numberOfPositionIterations(10), + m_timeScale(1) { m_numberOfVelocityIterations = 0; m_numberOfPositionIterations = 5; @@ -59,39 +55,38 @@ public: virtual ~btSoftBodySolver() { } - + /** * Return the type of the solver. */ virtual SolverTypes getSolverType() const = 0; - /** Ensure that this solver is initialized. */ virtual bool checkInitialized() = 0; /** Optimize soft bodies in this solver. */ - virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies , bool forceUpdate=false) = 0; + virtual void optimize(btAlignedObjectArray &softBodies, bool forceUpdate = false) = 0; /** Copy necessary data back to the original soft body source objects. */ virtual void copyBackToSoftBodies(bool bMove = true) = 0; /** Predict motion of soft bodies into next timestep */ - virtual void predictMotion( float solverdt ) = 0; + virtual void predictMotion(float solverdt) = 0; /** Solve constraints for a set of soft bodies */ - virtual void solveConstraints( float solverdt ) = 0; + virtual void solveConstraints(float solverdt) = 0; /** Perform necessary per-step updates of soft bodies such as recomputing normals and bounding boxes */ virtual void updateSoftBodies() = 0; /** Process a collision between one of the world's soft bodies and another collision object */ - virtual void processCollision( btSoftBody *, const struct btCollisionObjectWrapper* ) = 0; + virtual void processCollision(btSoftBody *, const struct btCollisionObjectWrapper *) = 0; /** Process a collision between two soft bodies */ - virtual void processCollision( btSoftBody*, btSoftBody* ) = 0; + virtual void processCollision(btSoftBody *, btSoftBody *) = 0; /** Set the number of velocity constraint solver iterations this solver uses. */ - virtual void setNumberOfPositionIterations( int iterations ) + virtual void setNumberOfPositionIterations(int iterations) { m_numberOfPositionIterations = iterations; } @@ -103,7 +98,7 @@ public: } /** Set the number of velocity constraint solver iterations this solver uses. */ - virtual void setNumberOfVelocityIterations( int iterations ) + virtual void setNumberOfVelocityIterations(int iterations) { m_numberOfVelocityIterations = iterations; } @@ -135,7 +130,6 @@ public: class btSoftBodySolverOutput { protected: - public: btSoftBodySolverOutput() { @@ -145,10 +139,8 @@ public: { } - /** Output current computed vertex data to the vertex buffers for all cloths in the solver. */ - virtual void copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer ) = 0; + virtual void copySoftBodyToVertexBuffer(const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer) = 0; }; - -#endif // #ifndef BT_SOFT_BODY_SOLVERS_H +#endif // #ifndef BT_SOFT_BODY_SOLVERS_H diff --git a/src/BulletSoftBody/btSoftMultiBodyDynamicsWorld.cpp b/src/BulletSoftBody/btSoftMultiBodyDynamicsWorld.cpp index 6facce4e8..282dbf75f 100644 --- a/src/BulletSoftBody/btSoftMultiBodyDynamicsWorld.cpp +++ b/src/BulletSoftBody/btSoftMultiBodyDynamicsWorld.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btSoftMultiBodyDynamicsWorld.h" #include "LinearMath/btQuickprof.h" @@ -24,42 +23,38 @@ subject to the following restrictions: #include "BulletSoftBody/btDefaultSoftBodySolver.h" #include "LinearMath/btSerializer.h" - btSoftMultiBodyDynamicsWorld::btSoftMultiBodyDynamicsWorld( btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btMultiBodyConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration, - btSoftBodySolver *softBodySolver ) : - btMultiBodyDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration), - m_softBodySolver( softBodySolver ), - m_ownsSolver(false) + btSoftBodySolver* softBodySolver) : btMultiBodyDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration), + m_softBodySolver(softBodySolver), + m_ownsSolver(false) { - if( !m_softBodySolver ) + if (!m_softBodySolver) { - void* ptr = btAlignedAlloc(sizeof(btDefaultSoftBodySolver),16); - m_softBodySolver = new(ptr) btDefaultSoftBodySolver(); + void* ptr = btAlignedAlloc(sizeof(btDefaultSoftBodySolver), 16); + m_softBodySolver = new (ptr) btDefaultSoftBodySolver(); m_ownsSolver = true; } - m_drawFlags = fDrawFlags::Std; - m_drawNodeTree = true; - m_drawFaceTree = false; - m_drawClusterTree = false; + m_drawFlags = fDrawFlags::Std; + m_drawNodeTree = true; + m_drawFaceTree = false; + m_drawClusterTree = false; m_sbi.m_broadphase = pairCache; m_sbi.m_dispatcher = dispatcher; m_sbi.m_sparsesdf.Initialize(); m_sbi.m_sparsesdf.Reset(); - m_sbi.air_density = (btScalar)1.2; - m_sbi.water_density = 0; - m_sbi.water_offset = 0; - m_sbi.water_normal = btVector3(0,0,0); - m_sbi.m_gravity.setValue(0,-10,0); + m_sbi.air_density = (btScalar)1.2; + m_sbi.water_density = 0; + m_sbi.water_offset = 0; + m_sbi.water_normal = btVector3(0, 0, 0); + m_sbi.m_gravity.setValue(0, -10, 0); m_sbi.m_sparsesdf.Initialize(); - - } btSoftMultiBodyDynamicsWorld::~btSoftMultiBodyDynamicsWorld() @@ -71,82 +66,78 @@ btSoftMultiBodyDynamicsWorld::~btSoftMultiBodyDynamicsWorld() } } -void btSoftMultiBodyDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) +void btSoftMultiBodyDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) { - btDiscreteDynamicsWorld::predictUnconstraintMotion( timeStep ); + btDiscreteDynamicsWorld::predictUnconstraintMotion(timeStep); { BT_PROFILE("predictUnconstraintMotionSoftBody"); - m_softBodySolver->predictMotion( float(timeStep) ); + m_softBodySolver->predictMotion(float(timeStep)); } } -void btSoftMultiBodyDynamicsWorld::internalSingleStepSimulation( btScalar timeStep ) +void btSoftMultiBodyDynamicsWorld::internalSingleStepSimulation(btScalar timeStep) { - // Let the solver grab the soft bodies and if necessary optimize for it - m_softBodySolver->optimize( getSoftBodyArray() ); + m_softBodySolver->optimize(getSoftBodyArray()); - if( !m_softBodySolver->checkInitialized() ) + if (!m_softBodySolver->checkInitialized()) { - btAssert( "Solver initialization failed\n" ); + btAssert("Solver initialization failed\n"); } - btDiscreteDynamicsWorld::internalSingleStepSimulation( timeStep ); + btDiscreteDynamicsWorld::internalSingleStepSimulation(timeStep); ///solve soft bodies constraints - solveSoftBodiesConstraints( timeStep ); + solveSoftBodiesConstraints(timeStep); //self collisions - for ( int i=0;idefaultCollisionHandler(psb); } ///update soft bodies - m_softBodySolver->updateSoftBodies( ); - + m_softBodySolver->updateSoftBodies(); + // End solver-wise simulation step // /////////////////////////////// - } -void btSoftMultiBodyDynamicsWorld::solveSoftBodiesConstraints( btScalar timeStep ) +void btSoftMultiBodyDynamicsWorld::solveSoftBodiesConstraints(btScalar timeStep) { BT_PROFILE("solveSoftConstraints"); - if(m_softBodies.size()) + if (m_softBodies.size()) { btSoftBody::solveClusters(m_softBodies); } // Solve constraints solver-wise - m_softBodySolver->solveConstraints( timeStep * m_softBodySolver->getTimeScale() ); - + m_softBodySolver->solveConstraints(timeStep * m_softBodySolver->getTimeScale()); } -void btSoftMultiBodyDynamicsWorld::addSoftBody(btSoftBody* body, int collisionFilterGroup, int collisionFilterMask) +void btSoftMultiBodyDynamicsWorld::addSoftBody(btSoftBody* body, int collisionFilterGroup, int collisionFilterMask) { m_softBodies.push_back(body); // Set the soft body solver that will deal with this body // to be the world's solver - body->setSoftBodySolver( m_softBodySolver ); + body->setSoftBodySolver(m_softBodySolver); btCollisionWorld::addCollisionObject(body, - collisionFilterGroup, - collisionFilterMask); - + collisionFilterGroup, + collisionFilterMask); } -void btSoftMultiBodyDynamicsWorld::removeSoftBody(btSoftBody* body) +void btSoftMultiBodyDynamicsWorld::removeSoftBody(btSoftBody* body) { m_softBodies.remove(body); btCollisionWorld::removeCollisionObject(body); } -void btSoftMultiBodyDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject) +void btSoftMultiBodyDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject) { btSoftBody* body = btSoftBody::upcast(collisionObject); if (body) @@ -155,60 +146,57 @@ void btSoftMultiBodyDynamicsWorld::removeCollisionObject(btCollisionObject* coll btDiscreteDynamicsWorld::removeCollisionObject(collisionObject); } -void btSoftMultiBodyDynamicsWorld::debugDrawWorld() +void btSoftMultiBodyDynamicsWorld::debugDrawWorld() { btMultiBodyDynamicsWorld::debugDrawWorld(); if (getDebugDrawer()) { int i; - for ( i=0;im_softBodies.size();i++) + for (i = 0; i < this->m_softBodies.size(); i++) { - btSoftBody* psb=(btSoftBody*)this->m_softBodies[i]; + btSoftBody* psb = (btSoftBody*)this->m_softBodies[i]; if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe))) { - btSoftBodyHelpers::DrawFrame(psb,m_debugDrawer); - btSoftBodyHelpers::Draw(psb,m_debugDrawer,m_drawFlags); + btSoftBodyHelpers::DrawFrame(psb, m_debugDrawer); + btSoftBodyHelpers::Draw(psb, m_debugDrawer, m_drawFlags); } - + if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb)) { - if(m_drawNodeTree) btSoftBodyHelpers::DrawNodeTree(psb,m_debugDrawer); - if(m_drawFaceTree) btSoftBodyHelpers::DrawFaceTree(psb,m_debugDrawer); - if(m_drawClusterTree) btSoftBodyHelpers::DrawClusterTree(psb,m_debugDrawer); + if (m_drawNodeTree) btSoftBodyHelpers::DrawNodeTree(psb, m_debugDrawer); + if (m_drawFaceTree) btSoftBodyHelpers::DrawFaceTree(psb, m_debugDrawer); + if (m_drawClusterTree) btSoftBodyHelpers::DrawClusterTree(psb, m_debugDrawer); } - } - } + } + } } - - - struct btSoftSingleRayCallback : public btBroadphaseRayCallback { - btVector3 m_rayFromWorld; - btVector3 m_rayToWorld; - btTransform m_rayFromTrans; - btTransform m_rayToTrans; - btVector3 m_hitNormal; + btVector3 m_rayFromWorld; + btVector3 m_rayToWorld; + btTransform m_rayFromTrans; + btTransform m_rayToTrans; + btVector3 m_hitNormal; - const btSoftMultiBodyDynamicsWorld* m_world; - btCollisionWorld::RayResultCallback& m_resultCallback; + const btSoftMultiBodyDynamicsWorld* m_world; + btCollisionWorld::RayResultCallback& m_resultCallback; - btSoftSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btSoftMultiBodyDynamicsWorld* world,btCollisionWorld::RayResultCallback& resultCallback) - :m_rayFromWorld(rayFromWorld), - m_rayToWorld(rayToWorld), - m_world(world), - m_resultCallback(resultCallback) + btSoftSingleRayCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld, const btSoftMultiBodyDynamicsWorld* world, btCollisionWorld::RayResultCallback& resultCallback) + : m_rayFromWorld(rayFromWorld), + m_rayToWorld(rayToWorld), + m_world(world), + m_resultCallback(resultCallback) { m_rayFromTrans.setIdentity(); m_rayFromTrans.setOrigin(m_rayFromWorld); m_rayToTrans.setIdentity(); m_rayToTrans.setOrigin(m_rayToWorld); - btVector3 rayDir = (rayToWorld-rayFromWorld); + btVector3 rayDir = (rayToWorld - rayFromWorld); - rayDir.normalize (); + rayDir.normalize(); ///what about division by zero? --> just set rayDirection[i] to INF/1e30 m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0]; m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1]; @@ -217,22 +205,19 @@ struct btSoftSingleRayCallback : public btBroadphaseRayCallback m_signs[1] = m_rayDirectionInverse[1] < 0.0; m_signs[2] = m_rayDirectionInverse[2] < 0.0; - m_lambda_max = rayDir.dot(m_rayToWorld-m_rayFromWorld); - + m_lambda_max = rayDir.dot(m_rayToWorld - m_rayFromWorld); } - - - virtual bool process(const btBroadphaseProxy* proxy) + virtual bool process(const btBroadphaseProxy* proxy) { ///terminate further ray tests, once the closestHitFraction reached zero if (m_resultCallback.m_closestHitFraction == btScalar(0.f)) return false; - btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject; + btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject; //only perform raycast if filterMask matches - if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) + if (m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) { //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); //btVector3 collisionObjectAabbMin,collisionObjectAabbMax; @@ -250,110 +235,106 @@ struct btSoftSingleRayCallback : public btBroadphaseRayCallback //culling already done by broadphase //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal)) { - m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans, - collisionObject, - collisionObject->getCollisionShape(), - collisionObject->getWorldTransform(), - m_resultCallback); + m_world->rayTestSingle(m_rayFromTrans, m_rayToTrans, + collisionObject, + collisionObject->getCollisionShape(), + collisionObject->getWorldTransform(), + m_resultCallback); } } return true; } }; -void btSoftMultiBodyDynamicsWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const +void btSoftMultiBodyDynamicsWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const { BT_PROFILE("rayTest"); /// use the broadphase to accelerate the search for objects, based on their aabb /// and for each object with ray-aabb overlap, perform an exact ray test - btSoftSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback); + btSoftSingleRayCallback rayCB(rayFromWorld, rayToWorld, this, resultCallback); #ifndef USE_BRUTEFORCE_RAYBROADPHASE - m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB); + m_broadphasePairCache->rayTest(rayFromWorld, rayToWorld, rayCB); #else - for (int i=0;igetNumCollisionObjects();i++) + for (int i = 0; i < this->getNumCollisionObjects(); i++) { rayCB.process(m_collisionObjects[i]->getBroadphaseHandle()); - } -#endif //USE_BRUTEFORCE_RAYBROADPHASE - + } +#endif //USE_BRUTEFORCE_RAYBROADPHASE } - -void btSoftMultiBodyDynamicsWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans, - btCollisionObject* collisionObject, - const btCollisionShape* collisionShape, - const btTransform& colObjWorldTransform, - RayResultCallback& resultCallback) +void btSoftMultiBodyDynamicsWorld::rayTestSingle(const btTransform& rayFromTrans, const btTransform& rayToTrans, + btCollisionObject* collisionObject, + const btCollisionShape* collisionShape, + const btTransform& colObjWorldTransform, + RayResultCallback& resultCallback) { - if (collisionShape->isSoftBody()) { + if (collisionShape->isSoftBody()) + { btSoftBody* softBody = btSoftBody::upcast(collisionObject); - if (softBody) { + if (softBody) + { btSoftBody::sRayCast softResult; - if (softBody->rayTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult)) + if (softBody->rayTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult)) { - - if (softResult.fraction<= resultCallback.m_closestHitFraction) + if (softResult.fraction <= resultCallback.m_closestHitFraction) { - btCollisionWorld::LocalShapeInfo shapeInfo; shapeInfo.m_shapePart = 0; shapeInfo.m_triangleIndex = softResult.index; // get the normal btVector3 rayDir = rayToTrans.getOrigin() - rayFromTrans.getOrigin(); - btVector3 normal=-rayDir; + btVector3 normal = -rayDir; normal.normalize(); if (softResult.feature == btSoftBody::eFeature::Face) { normal = softBody->m_faces[softResult.index].m_normal; - if (normal.dot(rayDir) > 0) { + if (normal.dot(rayDir) > 0) + { // normal always point toward origin of the ray normal = -normal; } } - - btCollisionWorld::LocalRayResult rayResult - (collisionObject, - &shapeInfo, - normal, - softResult.fraction); - bool normalInWorldSpace = true; - resultCallback.addSingleResult(rayResult,normalInWorldSpace); + + btCollisionWorld::LocalRayResult rayResult(collisionObject, + &shapeInfo, + normal, + softResult.fraction); + bool normalInWorldSpace = true; + resultCallback.addSingleResult(rayResult, normalInWorldSpace); } } } - } - else { - btCollisionWorld::rayTestSingle(rayFromTrans,rayToTrans,collisionObject,collisionShape,colObjWorldTransform,resultCallback); + } + else + { + btCollisionWorld::rayTestSingle(rayFromTrans, rayToTrans, collisionObject, collisionShape, colObjWorldTransform, resultCallback); } } - -void btSoftMultiBodyDynamicsWorld::serializeSoftBodies(btSerializer* serializer) +void btSoftMultiBodyDynamicsWorld::serializeSoftBodies(btSerializer* serializer) { int i; //serialize all collision objects - for (i=0;igetInternalType() & btCollisionObject::CO_SOFT_BODY) { int len = colObj->calculateSerializeBufferSize(); - btChunk* chunk = serializer->allocate(len,1); + btChunk* chunk = serializer->allocate(len, 1); const char* structType = colObj->serialize(chunk->m_oldPtr, serializer); - serializer->finalizeChunk(chunk,structType,BT_SOFTBODY_CODE,colObj); + serializer->finalizeChunk(chunk, structType, BT_SOFTBODY_CODE, colObj); } } - } -void btSoftMultiBodyDynamicsWorld::serialize(btSerializer* serializer) +void btSoftMultiBodyDynamicsWorld::serialize(btSerializer* serializer) { - serializer->startSerialization(); - serializeDynamicsWorldInfo( serializer); + serializeDynamicsWorldInfo(serializer); serializeSoftBodies(serializer); @@ -367,5 +348,3 @@ void btSoftMultiBodyDynamicsWorld::serialize(btSerializer* serializer) serializer->finishSerialization(); } - - diff --git a/src/BulletSoftBody/btSoftMultiBodyDynamicsWorld.h b/src/BulletSoftBody/btSoftMultiBodyDynamicsWorld.h index 6d46a21db..f295945a6 100644 --- a/src/BulletSoftBody/btSoftMultiBodyDynamicsWorld.h +++ b/src/BulletSoftBody/btSoftMultiBodyDynamicsWorld.h @@ -21,64 +21,61 @@ subject to the following restrictions: #include "BulletSoftBody/btSoftBody.h" #ifndef BT_SOFT_RIGID_DYNAMICS_WORLD_H -typedef btAlignedObjectArray btSoftBodyArray; +typedef btAlignedObjectArray btSoftBodyArray; #endif class btSoftBodySolver; class btSoftMultiBodyDynamicsWorld : public btMultiBodyDynamicsWorld { - - btSoftBodyArray m_softBodies; - int m_drawFlags; - bool m_drawNodeTree; - bool m_drawFaceTree; - bool m_drawClusterTree; + btSoftBodyArray m_softBodies; + int m_drawFlags; + bool m_drawNodeTree; + bool m_drawFaceTree; + bool m_drawClusterTree; btSoftBodyWorldInfo m_sbi; ///Solver classes that encapsulate multiple soft bodies for solving - btSoftBodySolver *m_softBodySolver; - bool m_ownsSolver; + btSoftBodySolver* m_softBodySolver; + bool m_ownsSolver; protected: + virtual void predictUnconstraintMotion(btScalar timeStep); - virtual void predictUnconstraintMotion(btScalar timeStep); + virtual void internalSingleStepSimulation(btScalar timeStep); - virtual void internalSingleStepSimulation( btScalar timeStep); + void solveSoftBodiesConstraints(btScalar timeStep); - void solveSoftBodiesConstraints( btScalar timeStep ); - - void serializeSoftBodies(btSerializer* serializer); + void serializeSoftBodies(btSerializer* serializer); public: - - btSoftMultiBodyDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btMultiBodyConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration, btSoftBodySolver *softBodySolver = 0 ); + btSoftMultiBodyDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btMultiBodyConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration, btSoftBodySolver* softBodySolver = 0); virtual ~btSoftMultiBodyDynamicsWorld(); - virtual void debugDrawWorld(); + virtual void debugDrawWorld(); - void addSoftBody(btSoftBody* body, int collisionFilterGroup=btBroadphaseProxy::DefaultFilter, int collisionFilterMask=btBroadphaseProxy::AllFilter); + void addSoftBody(btSoftBody* body, int collisionFilterGroup = btBroadphaseProxy::DefaultFilter, int collisionFilterMask = btBroadphaseProxy::AllFilter); - void removeSoftBody(btSoftBody* body); + void removeSoftBody(btSoftBody* body); ///removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise call btDiscreteDynamicsWorld::removeCollisionObject - virtual void removeCollisionObject(btCollisionObject* collisionObject); + virtual void removeCollisionObject(btCollisionObject* collisionObject); - int getDrawFlags() const { return(m_drawFlags); } - void setDrawFlags(int f) { m_drawFlags=f; } + int getDrawFlags() const { return (m_drawFlags); } + void setDrawFlags(int f) { m_drawFlags = f; } - btSoftBodyWorldInfo& getWorldInfo() + btSoftBodyWorldInfo& getWorldInfo() { return m_sbi; } - const btSoftBodyWorldInfo& getWorldInfo() const + const btSoftBodyWorldInfo& getWorldInfo() const { return m_sbi; } - virtual btDynamicsWorldType getWorldType() const + virtual btDynamicsWorldType getWorldType() const { - return BT_SOFT_MULTIBODY_DYNAMICS_WORLD; + return BT_SOFT_MULTIBODY_DYNAMICS_WORLD; } btSoftBodyArray& getSoftBodyArray() @@ -91,20 +88,18 @@ public: return m_softBodies; } - - virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const; + virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const; /// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest. /// In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape. /// This allows more customization. - static void rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans, - btCollisionObject* collisionObject, - const btCollisionShape* collisionShape, - const btTransform& colObjWorldTransform, - RayResultCallback& resultCallback); - - virtual void serialize(btSerializer* serializer); + static void rayTestSingle(const btTransform& rayFromTrans, const btTransform& rayToTrans, + btCollisionObject* collisionObject, + const btCollisionShape* collisionShape, + const btTransform& colObjWorldTransform, + RayResultCallback& resultCallback); + virtual void serialize(btSerializer* serializer); }; -#endif //BT_SOFT_MULTIBODY_DYNAMICS_WORLD_H +#endif //BT_SOFT_MULTIBODY_DYNAMICS_WORLD_H diff --git a/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp b/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp index 01c148a2c..56d8083f2 100644 --- a/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp +++ b/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.cpp @@ -27,18 +27,16 @@ subject to the following restrictions: //#include -btSoftRigidCollisionAlgorithm::btSoftRigidCollisionAlgorithm(btPersistentManifold* /*mf*/,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* ,const btCollisionObjectWrapper* , bool isSwapped) -: btCollisionAlgorithm(ci), -//m_ownManifold(false), -//m_manifoldPtr(mf), -m_isSwapped(isSwapped) +btSoftRigidCollisionAlgorithm::btSoftRigidCollisionAlgorithm(btPersistentManifold* /*mf*/, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper*, const btCollisionObjectWrapper*, bool isSwapped) + : btCollisionAlgorithm(ci), + //m_ownManifold(false), + //m_manifoldPtr(mf), + m_isSwapped(isSwapped) { } - btSoftRigidCollisionAlgorithm::~btSoftRigidCollisionAlgorithm() { - //m_softBody->m_overlappingRigidBodies.remove(m_rigidCollisionObject); /*if (m_ownManifold) @@ -47,31 +45,27 @@ btSoftRigidCollisionAlgorithm::~btSoftRigidCollisionAlgorithm() m_dispatcher->releaseManifold(m_manifoldPtr); } */ - } - #include -void btSoftRigidCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +void btSoftRigidCollisionAlgorithm::processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { (void)dispatchInfo; (void)resultOut; //printf("btSoftRigidCollisionAlgorithm\n"); -// const btCollisionObjectWrapper* softWrap = m_isSwapped?body1Wrap:body0Wrap; -// const btCollisionObjectWrapper* rigidWrap = m_isSwapped?body0Wrap:body1Wrap; - btSoftBody* softBody = m_isSwapped? (btSoftBody*)body1Wrap->getCollisionObject() : (btSoftBody*)body0Wrap->getCollisionObject(); - const btCollisionObjectWrapper* rigidCollisionObjectWrap = m_isSwapped? body0Wrap : body1Wrap; - - if (softBody->m_collisionDisabledObjects.findLinearSearch(rigidCollisionObjectWrap->getCollisionObject())==softBody->m_collisionDisabledObjects.size()) + // const btCollisionObjectWrapper* softWrap = m_isSwapped?body1Wrap:body0Wrap; + // const btCollisionObjectWrapper* rigidWrap = m_isSwapped?body0Wrap:body1Wrap; + btSoftBody* softBody = m_isSwapped ? (btSoftBody*)body1Wrap->getCollisionObject() : (btSoftBody*)body0Wrap->getCollisionObject(); + const btCollisionObjectWrapper* rigidCollisionObjectWrap = m_isSwapped ? body0Wrap : body1Wrap; + + if (softBody->m_collisionDisabledObjects.findLinearSearch(rigidCollisionObjectWrap->getCollisionObject()) == softBody->m_collisionDisabledObjects.size()) { softBody->getSoftBodySolver()->processCollision(softBody, rigidCollisionObjectWrap); } - - } -btScalar btSoftRigidCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0,btCollisionObject* col1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut) +btScalar btSoftRigidCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* col0, btCollisionObject* col1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut) { (void)resultOut; (void)dispatchInfo; @@ -81,6 +75,3 @@ btScalar btSoftRigidCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* //not yet return btScalar(1.); } - - - diff --git a/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h b/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h index 93fcc6065..9773af19a 100644 --- a/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h +++ b/src/BulletSoftBody/btSoftRigidCollisionAlgorithm.h @@ -35,41 +35,37 @@ class btSoftRigidCollisionAlgorithm : public btCollisionAlgorithm //btCollisionObject* m_rigidCollisionObject; ///for rigid versus soft (instead of soft versus rigid), we use this swapped boolean - bool m_isSwapped; + bool m_isSwapped; public: - - btSoftRigidCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* col0,const btCollisionObjectWrapper* col1Wrap, bool isSwapped); + btSoftRigidCollisionAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* col0, const btCollisionObjectWrapper* col1Wrap, bool isSwapped); virtual ~btSoftRigidCollisionAlgorithm(); - virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) { //we don't add any manifolds } - - struct CreateFunc :public btCollisionAlgorithmCreateFunc + struct CreateFunc : public btCollisionAlgorithmCreateFunc { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(btSoftRigidCollisionAlgorithm)); if (!m_swapped) { - return new(mem) btSoftRigidCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,false); - } else + return new (mem) btSoftRigidCollisionAlgorithm(0, ci, body0Wrap, body1Wrap, false); + } + else { - return new(mem) btSoftRigidCollisionAlgorithm(0,ci,body0Wrap,body1Wrap,true); + return new (mem) btSoftRigidCollisionAlgorithm(0, ci, body0Wrap, body1Wrap, true); } } }; - }; -#endif //BT_SOFT_RIGID_COLLISION_ALGORITHM_H - - +#endif //BT_SOFT_RIGID_COLLISION_ALGORITHM_H diff --git a/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp b/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp index 204b4f576..510b731fc 100644 --- a/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp +++ b/src/BulletSoftBody/btSoftRigidDynamicsWorld.cpp @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btSoftRigidDynamicsWorld.h" #include "LinearMath/btQuickprof.h" @@ -24,42 +23,38 @@ subject to the following restrictions: #include "btDefaultSoftBodySolver.h" #include "LinearMath/btSerializer.h" - btSoftRigidDynamicsWorld::btSoftRigidDynamicsWorld( btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration, - btSoftBodySolver *softBodySolver ) : - btDiscreteDynamicsWorld(dispatcher,pairCache,constraintSolver,collisionConfiguration), - m_softBodySolver( softBodySolver ), - m_ownsSolver(false) + btSoftBodySolver* softBodySolver) : btDiscreteDynamicsWorld(dispatcher, pairCache, constraintSolver, collisionConfiguration), + m_softBodySolver(softBodySolver), + m_ownsSolver(false) { - if( !m_softBodySolver ) + if (!m_softBodySolver) { - void* ptr = btAlignedAlloc(sizeof(btDefaultSoftBodySolver),16); - m_softBodySolver = new(ptr) btDefaultSoftBodySolver(); + void* ptr = btAlignedAlloc(sizeof(btDefaultSoftBodySolver), 16); + m_softBodySolver = new (ptr) btDefaultSoftBodySolver(); m_ownsSolver = true; } - m_drawFlags = fDrawFlags::Std; - m_drawNodeTree = true; - m_drawFaceTree = false; - m_drawClusterTree = false; + m_drawFlags = fDrawFlags::Std; + m_drawNodeTree = true; + m_drawFaceTree = false; + m_drawClusterTree = false; m_sbi.m_broadphase = pairCache; m_sbi.m_dispatcher = dispatcher; m_sbi.m_sparsesdf.Initialize(); m_sbi.m_sparsesdf.Reset(); - m_sbi.air_density = (btScalar)1.2; - m_sbi.water_density = 0; - m_sbi.water_offset = 0; - m_sbi.water_normal = btVector3(0,0,0); - m_sbi.m_gravity.setValue(0,-10,0); + m_sbi.air_density = (btScalar)1.2; + m_sbi.water_density = 0; + m_sbi.water_offset = 0; + m_sbi.water_normal = btVector3(0, 0, 0); + m_sbi.m_gravity.setValue(0, -10, 0); m_sbi.m_sparsesdf.Initialize(); - - } btSoftRigidDynamicsWorld::~btSoftRigidDynamicsWorld() @@ -71,82 +66,78 @@ btSoftRigidDynamicsWorld::~btSoftRigidDynamicsWorld() } } -void btSoftRigidDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) +void btSoftRigidDynamicsWorld::predictUnconstraintMotion(btScalar timeStep) { - btDiscreteDynamicsWorld::predictUnconstraintMotion( timeStep ); + btDiscreteDynamicsWorld::predictUnconstraintMotion(timeStep); { BT_PROFILE("predictUnconstraintMotionSoftBody"); - m_softBodySolver->predictMotion( float(timeStep) ); + m_softBodySolver->predictMotion(float(timeStep)); } } -void btSoftRigidDynamicsWorld::internalSingleStepSimulation( btScalar timeStep ) +void btSoftRigidDynamicsWorld::internalSingleStepSimulation(btScalar timeStep) { - // Let the solver grab the soft bodies and if necessary optimize for it - m_softBodySolver->optimize( getSoftBodyArray() ); + m_softBodySolver->optimize(getSoftBodyArray()); - if( !m_softBodySolver->checkInitialized() ) + if (!m_softBodySolver->checkInitialized()) { - btAssert( "Solver initialization failed\n" ); + btAssert("Solver initialization failed\n"); } - btDiscreteDynamicsWorld::internalSingleStepSimulation( timeStep ); + btDiscreteDynamicsWorld::internalSingleStepSimulation(timeStep); ///solve soft bodies constraints - solveSoftBodiesConstraints( timeStep ); + solveSoftBodiesConstraints(timeStep); //self collisions - for ( int i=0;idefaultCollisionHandler(psb); } ///update soft bodies - m_softBodySolver->updateSoftBodies( ); - + m_softBodySolver->updateSoftBodies(); + // End solver-wise simulation step // /////////////////////////////// - } -void btSoftRigidDynamicsWorld::solveSoftBodiesConstraints( btScalar timeStep ) +void btSoftRigidDynamicsWorld::solveSoftBodiesConstraints(btScalar timeStep) { BT_PROFILE("solveSoftConstraints"); - if(m_softBodies.size()) + if (m_softBodies.size()) { btSoftBody::solveClusters(m_softBodies); } // Solve constraints solver-wise - m_softBodySolver->solveConstraints( timeStep * m_softBodySolver->getTimeScale() ); - + m_softBodySolver->solveConstraints(timeStep * m_softBodySolver->getTimeScale()); } -void btSoftRigidDynamicsWorld::addSoftBody(btSoftBody* body, int collisionFilterGroup, int collisionFilterMask) +void btSoftRigidDynamicsWorld::addSoftBody(btSoftBody* body, int collisionFilterGroup, int collisionFilterMask) { m_softBodies.push_back(body); // Set the soft body solver that will deal with this body // to be the world's solver - body->setSoftBodySolver( m_softBodySolver ); + body->setSoftBodySolver(m_softBodySolver); btCollisionWorld::addCollisionObject(body, - collisionFilterGroup, - collisionFilterMask); - + collisionFilterGroup, + collisionFilterMask); } -void btSoftRigidDynamicsWorld::removeSoftBody(btSoftBody* body) +void btSoftRigidDynamicsWorld::removeSoftBody(btSoftBody* body) { m_softBodies.remove(body); btCollisionWorld::removeCollisionObject(body); } -void btSoftRigidDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject) +void btSoftRigidDynamicsWorld::removeCollisionObject(btCollisionObject* collisionObject) { btSoftBody* body = btSoftBody::upcast(collisionObject); if (body) @@ -155,60 +146,57 @@ void btSoftRigidDynamicsWorld::removeCollisionObject(btCollisionObject* collisio btDiscreteDynamicsWorld::removeCollisionObject(collisionObject); } -void btSoftRigidDynamicsWorld::debugDrawWorld() +void btSoftRigidDynamicsWorld::debugDrawWorld() { btDiscreteDynamicsWorld::debugDrawWorld(); if (getDebugDrawer()) { int i; - for ( i=0;im_softBodies.size();i++) + for (i = 0; i < this->m_softBodies.size(); i++) { - btSoftBody* psb=(btSoftBody*)this->m_softBodies[i]; + btSoftBody* psb = (btSoftBody*)this->m_softBodies[i]; if (getDebugDrawer() && (getDebugDrawer()->getDebugMode() & (btIDebugDraw::DBG_DrawWireframe))) { - btSoftBodyHelpers::DrawFrame(psb,m_debugDrawer); - btSoftBodyHelpers::Draw(psb,m_debugDrawer,m_drawFlags); + btSoftBodyHelpers::DrawFrame(psb, m_debugDrawer); + btSoftBodyHelpers::Draw(psb, m_debugDrawer, m_drawFlags); } - + if (m_debugDrawer && (m_debugDrawer->getDebugMode() & btIDebugDraw::DBG_DrawAabb)) { - if(m_drawNodeTree) btSoftBodyHelpers::DrawNodeTree(psb,m_debugDrawer); - if(m_drawFaceTree) btSoftBodyHelpers::DrawFaceTree(psb,m_debugDrawer); - if(m_drawClusterTree) btSoftBodyHelpers::DrawClusterTree(psb,m_debugDrawer); + if (m_drawNodeTree) btSoftBodyHelpers::DrawNodeTree(psb, m_debugDrawer); + if (m_drawFaceTree) btSoftBodyHelpers::DrawFaceTree(psb, m_debugDrawer); + if (m_drawClusterTree) btSoftBodyHelpers::DrawClusterTree(psb, m_debugDrawer); } - } - } + } + } } - - - struct btSoftSingleRayCallback : public btBroadphaseRayCallback { - btVector3 m_rayFromWorld; - btVector3 m_rayToWorld; - btTransform m_rayFromTrans; - btTransform m_rayToTrans; - btVector3 m_hitNormal; + btVector3 m_rayFromWorld; + btVector3 m_rayToWorld; + btTransform m_rayFromTrans; + btTransform m_rayToTrans; + btVector3 m_hitNormal; - const btSoftRigidDynamicsWorld* m_world; - btCollisionWorld::RayResultCallback& m_resultCallback; + const btSoftRigidDynamicsWorld* m_world; + btCollisionWorld::RayResultCallback& m_resultCallback; - btSoftSingleRayCallback(const btVector3& rayFromWorld,const btVector3& rayToWorld,const btSoftRigidDynamicsWorld* world,btCollisionWorld::RayResultCallback& resultCallback) - :m_rayFromWorld(rayFromWorld), - m_rayToWorld(rayToWorld), - m_world(world), - m_resultCallback(resultCallback) + btSoftSingleRayCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld, const btSoftRigidDynamicsWorld* world, btCollisionWorld::RayResultCallback& resultCallback) + : m_rayFromWorld(rayFromWorld), + m_rayToWorld(rayToWorld), + m_world(world), + m_resultCallback(resultCallback) { m_rayFromTrans.setIdentity(); m_rayFromTrans.setOrigin(m_rayFromWorld); m_rayToTrans.setIdentity(); m_rayToTrans.setOrigin(m_rayToWorld); - btVector3 rayDir = (rayToWorld-rayFromWorld); + btVector3 rayDir = (rayToWorld - rayFromWorld); - rayDir.normalize (); + rayDir.normalize(); ///what about division by zero? --> just set rayDirection[i] to INF/1e30 m_rayDirectionInverse[0] = rayDir[0] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[0]; m_rayDirectionInverse[1] = rayDir[1] == btScalar(0.0) ? btScalar(1e30) : btScalar(1.0) / rayDir[1]; @@ -217,22 +205,19 @@ struct btSoftSingleRayCallback : public btBroadphaseRayCallback m_signs[1] = m_rayDirectionInverse[1] < 0.0; m_signs[2] = m_rayDirectionInverse[2] < 0.0; - m_lambda_max = rayDir.dot(m_rayToWorld-m_rayFromWorld); - + m_lambda_max = rayDir.dot(m_rayToWorld - m_rayFromWorld); } - - - virtual bool process(const btBroadphaseProxy* proxy) + virtual bool process(const btBroadphaseProxy* proxy) { ///terminate further ray tests, once the closestHitFraction reached zero if (m_resultCallback.m_closestHitFraction == btScalar(0.f)) return false; - btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject; + btCollisionObject* collisionObject = (btCollisionObject*)proxy->m_clientObject; //only perform raycast if filterMask matches - if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) + if (m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) { //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject(); //btVector3 collisionObjectAabbMin,collisionObjectAabbMax; @@ -250,110 +235,106 @@ struct btSoftSingleRayCallback : public btBroadphaseRayCallback //culling already done by broadphase //if (btRayAabb(m_rayFromWorld,m_rayToWorld,collisionObjectAabbMin,collisionObjectAabbMax,hitLambda,m_hitNormal)) { - m_world->rayTestSingle(m_rayFromTrans,m_rayToTrans, - collisionObject, - collisionObject->getCollisionShape(), - collisionObject->getWorldTransform(), - m_resultCallback); + m_world->rayTestSingle(m_rayFromTrans, m_rayToTrans, + collisionObject, + collisionObject->getCollisionShape(), + collisionObject->getWorldTransform(), + m_resultCallback); } } return true; } }; -void btSoftRigidDynamicsWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const +void btSoftRigidDynamicsWorld::rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const { BT_PROFILE("rayTest"); /// use the broadphase to accelerate the search for objects, based on their aabb /// and for each object with ray-aabb overlap, perform an exact ray test - btSoftSingleRayCallback rayCB(rayFromWorld,rayToWorld,this,resultCallback); + btSoftSingleRayCallback rayCB(rayFromWorld, rayToWorld, this, resultCallback); #ifndef USE_BRUTEFORCE_RAYBROADPHASE - m_broadphasePairCache->rayTest(rayFromWorld,rayToWorld,rayCB); + m_broadphasePairCache->rayTest(rayFromWorld, rayToWorld, rayCB); #else - for (int i=0;igetNumCollisionObjects();i++) + for (int i = 0; i < this->getNumCollisionObjects(); i++) { rayCB.process(m_collisionObjects[i]->getBroadphaseHandle()); - } -#endif //USE_BRUTEFORCE_RAYBROADPHASE - + } +#endif //USE_BRUTEFORCE_RAYBROADPHASE } - -void btSoftRigidDynamicsWorld::rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans, - btCollisionObject* collisionObject, - const btCollisionShape* collisionShape, - const btTransform& colObjWorldTransform, - RayResultCallback& resultCallback) +void btSoftRigidDynamicsWorld::rayTestSingle(const btTransform& rayFromTrans, const btTransform& rayToTrans, + btCollisionObject* collisionObject, + const btCollisionShape* collisionShape, + const btTransform& colObjWorldTransform, + RayResultCallback& resultCallback) { - if (collisionShape->isSoftBody()) { + if (collisionShape->isSoftBody()) + { btSoftBody* softBody = btSoftBody::upcast(collisionObject); - if (softBody) { + if (softBody) + { btSoftBody::sRayCast softResult; - if (softBody->rayTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult)) + if (softBody->rayTest(rayFromTrans.getOrigin(), rayToTrans.getOrigin(), softResult)) { - - if (softResult.fraction<= resultCallback.m_closestHitFraction) + if (softResult.fraction <= resultCallback.m_closestHitFraction) { - btCollisionWorld::LocalShapeInfo shapeInfo; shapeInfo.m_shapePart = 0; shapeInfo.m_triangleIndex = softResult.index; // get the normal btVector3 rayDir = rayToTrans.getOrigin() - rayFromTrans.getOrigin(); - btVector3 normal=-rayDir; + btVector3 normal = -rayDir; normal.normalize(); if (softResult.feature == btSoftBody::eFeature::Face) { normal = softBody->m_faces[softResult.index].m_normal; - if (normal.dot(rayDir) > 0) { + if (normal.dot(rayDir) > 0) + { // normal always point toward origin of the ray normal = -normal; } } - - btCollisionWorld::LocalRayResult rayResult - (collisionObject, - &shapeInfo, - normal, - softResult.fraction); - bool normalInWorldSpace = true; - resultCallback.addSingleResult(rayResult,normalInWorldSpace); + + btCollisionWorld::LocalRayResult rayResult(collisionObject, + &shapeInfo, + normal, + softResult.fraction); + bool normalInWorldSpace = true; + resultCallback.addSingleResult(rayResult, normalInWorldSpace); } } } - } - else { - btCollisionWorld::rayTestSingle(rayFromTrans,rayToTrans,collisionObject,collisionShape,colObjWorldTransform,resultCallback); + } + else + { + btCollisionWorld::rayTestSingle(rayFromTrans, rayToTrans, collisionObject, collisionShape, colObjWorldTransform, resultCallback); } } - -void btSoftRigidDynamicsWorld::serializeSoftBodies(btSerializer* serializer) +void btSoftRigidDynamicsWorld::serializeSoftBodies(btSerializer* serializer) { int i; //serialize all collision objects - for (i=0;igetInternalType() & btCollisionObject::CO_SOFT_BODY) { int len = colObj->calculateSerializeBufferSize(); - btChunk* chunk = serializer->allocate(len,1); + btChunk* chunk = serializer->allocate(len, 1); const char* structType = colObj->serialize(chunk->m_oldPtr, serializer); - serializer->finalizeChunk(chunk,structType,BT_SOFTBODY_CODE,colObj); + serializer->finalizeChunk(chunk, structType, BT_SOFTBODY_CODE, colObj); } } - } -void btSoftRigidDynamicsWorld::serialize(btSerializer* serializer) +void btSoftRigidDynamicsWorld::serialize(btSerializer* serializer) { - serializer->startSerialization(); - serializeDynamicsWorldInfo( serializer); + serializeDynamicsWorldInfo(serializer); serializeSoftBodies(serializer); @@ -363,5 +344,3 @@ void btSoftRigidDynamicsWorld::serialize(btSerializer* serializer) serializer->finishSerialization(); } - - diff --git a/src/BulletSoftBody/btSoftRigidDynamicsWorld.h b/src/BulletSoftBody/btSoftRigidDynamicsWorld.h index d921a6488..be49c444d 100644 --- a/src/BulletSoftBody/btSoftRigidDynamicsWorld.h +++ b/src/BulletSoftBody/btSoftRigidDynamicsWorld.h @@ -19,63 +19,60 @@ subject to the following restrictions: #include "BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h" #include "btSoftBody.h" -typedef btAlignedObjectArray btSoftBodyArray; +typedef btAlignedObjectArray btSoftBodyArray; class btSoftBodySolver; class btSoftRigidDynamicsWorld : public btDiscreteDynamicsWorld { - - btSoftBodyArray m_softBodies; - int m_drawFlags; - bool m_drawNodeTree; - bool m_drawFaceTree; - bool m_drawClusterTree; + btSoftBodyArray m_softBodies; + int m_drawFlags; + bool m_drawNodeTree; + bool m_drawFaceTree; + bool m_drawClusterTree; btSoftBodyWorldInfo m_sbi; ///Solver classes that encapsulate multiple soft bodies for solving - btSoftBodySolver *m_softBodySolver; - bool m_ownsSolver; + btSoftBodySolver* m_softBodySolver; + bool m_ownsSolver; protected: + virtual void predictUnconstraintMotion(btScalar timeStep); - virtual void predictUnconstraintMotion(btScalar timeStep); + virtual void internalSingleStepSimulation(btScalar timeStep); - virtual void internalSingleStepSimulation( btScalar timeStep); + void solveSoftBodiesConstraints(btScalar timeStep); - void solveSoftBodiesConstraints( btScalar timeStep ); - - void serializeSoftBodies(btSerializer* serializer); + void serializeSoftBodies(btSerializer* serializer); public: - - btSoftRigidDynamicsWorld(btDispatcher* dispatcher,btBroadphaseInterface* pairCache,btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration, btSoftBodySolver *softBodySolver = 0 ); + btSoftRigidDynamicsWorld(btDispatcher* dispatcher, btBroadphaseInterface* pairCache, btConstraintSolver* constraintSolver, btCollisionConfiguration* collisionConfiguration, btSoftBodySolver* softBodySolver = 0); virtual ~btSoftRigidDynamicsWorld(); - virtual void debugDrawWorld(); + virtual void debugDrawWorld(); - void addSoftBody(btSoftBody* body, int collisionFilterGroup=btBroadphaseProxy::DefaultFilter, int collisionFilterMask=btBroadphaseProxy::AllFilter); + void addSoftBody(btSoftBody* body, int collisionFilterGroup = btBroadphaseProxy::DefaultFilter, int collisionFilterMask = btBroadphaseProxy::AllFilter); - void removeSoftBody(btSoftBody* body); + void removeSoftBody(btSoftBody* body); ///removeCollisionObject will first check if it is a rigid body, if so call removeRigidBody otherwise call btDiscreteDynamicsWorld::removeCollisionObject - virtual void removeCollisionObject(btCollisionObject* collisionObject); + virtual void removeCollisionObject(btCollisionObject* collisionObject); - int getDrawFlags() const { return(m_drawFlags); } - void setDrawFlags(int f) { m_drawFlags=f; } + int getDrawFlags() const { return (m_drawFlags); } + void setDrawFlags(int f) { m_drawFlags = f; } - btSoftBodyWorldInfo& getWorldInfo() + btSoftBodyWorldInfo& getWorldInfo() { return m_sbi; } - const btSoftBodyWorldInfo& getWorldInfo() const + const btSoftBodyWorldInfo& getWorldInfo() const { return m_sbi; } - virtual btDynamicsWorldType getWorldType() const + virtual btDynamicsWorldType getWorldType() const { - return BT_SOFT_RIGID_DYNAMICS_WORLD; + return BT_SOFT_RIGID_DYNAMICS_WORLD; } btSoftBodyArray& getSoftBodyArray() @@ -88,20 +85,18 @@ public: return m_softBodies; } - - virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const; + virtual void rayTest(const btVector3& rayFromWorld, const btVector3& rayToWorld, RayResultCallback& resultCallback) const; /// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest. /// In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape. /// This allows more customization. - static void rayTestSingle(const btTransform& rayFromTrans,const btTransform& rayToTrans, - btCollisionObject* collisionObject, - const btCollisionShape* collisionShape, - const btTransform& colObjWorldTransform, - RayResultCallback& resultCallback); - - virtual void serialize(btSerializer* serializer); + static void rayTestSingle(const btTransform& rayFromTrans, const btTransform& rayToTrans, + btCollisionObject* collisionObject, + const btCollisionShape* collisionShape, + const btTransform& colObjWorldTransform, + RayResultCallback& resultCallback); + virtual void serialize(btSerializer* serializer); }; -#endif //BT_SOFT_RIGID_DYNAMICS_WORLD_H +#endif //BT_SOFT_RIGID_DYNAMICS_WORLD_H diff --git a/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp b/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp index 72043e69e..9c3e904f6 100644 --- a/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp +++ b/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.cpp @@ -23,8 +23,8 @@ subject to the following restrictions: #define USE_PERSISTENT_CONTACTS 1 -btSoftSoftCollisionAlgorithm::btSoftSoftCollisionAlgorithm(btPersistentManifold* /*mf*/,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* /*obj0*/,const btCollisionObjectWrapper* /*obj1*/) -: btCollisionAlgorithm(ci) +btSoftSoftCollisionAlgorithm::btSoftSoftCollisionAlgorithm(btPersistentManifold* /*mf*/, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* /*obj0*/, const btCollisionObjectWrapper* /*obj1*/) + : btCollisionAlgorithm(ci) //m_ownManifold(false), //m_manifoldPtr(mf) { @@ -34,14 +34,14 @@ btSoftSoftCollisionAlgorithm::~btSoftSoftCollisionAlgorithm() { } -void btSoftSoftCollisionAlgorithm::processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& /*dispatchInfo*/,btManifoldResult* /*resultOut*/) +void btSoftSoftCollisionAlgorithm::processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& /*dispatchInfo*/, btManifoldResult* /*resultOut*/) { - btSoftBody* soft0 = (btSoftBody*)body0Wrap->getCollisionObject(); - btSoftBody* soft1 = (btSoftBody*)body1Wrap->getCollisionObject(); + btSoftBody* soft0 = (btSoftBody*)body0Wrap->getCollisionObject(); + btSoftBody* soft1 = (btSoftBody*)body1Wrap->getCollisionObject(); soft0->getSoftBodySolver()->processCollision(soft0, soft1); } -btScalar btSoftSoftCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* /*body0*/,btCollisionObject* /*body1*/,const btDispatcherInfo& /*dispatchInfo*/,btManifoldResult* /*resultOut*/) +btScalar btSoftSoftCollisionAlgorithm::calculateTimeOfImpact(btCollisionObject* /*body0*/, btCollisionObject* /*body1*/, const btDispatcherInfo& /*dispatchInfo*/, btManifoldResult* /*resultOut*/) { //not yet return 1.f; diff --git a/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h b/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h index 4eab7aea2..6f871f5b8 100644 --- a/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h +++ b/src/BulletSoftBody/btSoftSoftCollisionAlgorithm.h @@ -27,43 +27,39 @@ class btSoftBody; ///collision detection between two btSoftBody shapes class btSoftSoftCollisionAlgorithm : public btCollisionAlgorithm { - bool m_ownManifold; - btPersistentManifold* m_manifoldPtr; - -// btSoftBody* m_softBody0; -// btSoftBody* m_softBody1; + bool m_ownManifold; + btPersistentManifold* m_manifoldPtr; + // btSoftBody* m_softBody0; + // btSoftBody* m_softBody1; public: btSoftSoftCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci) : btCollisionAlgorithm(ci) {} - virtual void processCollision (const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual void processCollision(const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut); + virtual btScalar calculateTimeOfImpact(btCollisionObject* body0, btCollisionObject* body1, const btDispatcherInfo& dispatchInfo, btManifoldResult* resultOut); - virtual void getAllContactManifolds(btManifoldArray& manifoldArray) + virtual void getAllContactManifolds(btManifoldArray& manifoldArray) { if (m_manifoldPtr && m_ownManifold) manifoldArray.push_back(m_manifoldPtr); } - btSoftSoftCollisionAlgorithm(btPersistentManifold* mf,const btCollisionAlgorithmConstructionInfo& ci,const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap); + btSoftSoftCollisionAlgorithm(btPersistentManifold* mf, const btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap); virtual ~btSoftSoftCollisionAlgorithm(); - struct CreateFunc :public btCollisionAlgorithmCreateFunc + struct CreateFunc : public btCollisionAlgorithmCreateFunc { - virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap,const btCollisionObjectWrapper* body1Wrap) + virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, const btCollisionObjectWrapper* body0Wrap, const btCollisionObjectWrapper* body1Wrap) { int bbsize = sizeof(btSoftSoftCollisionAlgorithm); void* ptr = ci.m_dispatcher1->allocateCollisionAlgorithm(bbsize); - return new(ptr) btSoftSoftCollisionAlgorithm(0,ci,body0Wrap,body1Wrap); + return new (ptr) btSoftSoftCollisionAlgorithm(0, ci, body0Wrap, body1Wrap); } }; - }; -#endif //BT_SOFT_SOFT_COLLISION_ALGORITHM_H - - +#endif //BT_SOFT_SOFT_COLLISION_ALGORITHM_H diff --git a/src/BulletSoftBody/btSparseSDF.h b/src/BulletSoftBody/btSparseSDF.h index ba437c28e..11a693631 100644 --- a/src/BulletSoftBody/btSparseSDF.h +++ b/src/BulletSoftBody/btSparseSDF.h @@ -24,296 +24,320 @@ subject to the following restrictions: template unsigned int HsiehHash(const void* pdata) { - const unsigned short* data=(const unsigned short*)pdata; - unsigned hash=DWORDLEN<<2,tmp; - for(int i=0;i>11; + hash += data[0]; + tmp = (data[1] << 11) ^ hash; + hash = (hash << 16) ^ tmp; + data += 2; + hash += hash >> 11; } - hash^=hash<<3;hash+=hash>>5; - hash^=hash<<4;hash+=hash>>17; - hash^=hash<<25;hash+=hash>>6; - return(hash); + hash ^= hash << 3; + hash += hash >> 5; + hash ^= hash << 4; + hash += hash >> 17; + hash ^= hash << 25; + hash += hash >> 6; + return (hash); } template -struct btSparseSdf +struct btSparseSdf { // // Inner types // struct IntFrac { - int b; - int i; - btScalar f; + int b; + int i; + btScalar f; }; - struct Cell + struct Cell { - btScalar d[CELLSIZE+1][CELLSIZE+1][CELLSIZE+1]; - int c[3]; - int puid; - unsigned hash; - const btCollisionShape* pclient; - Cell* next; + btScalar d[CELLSIZE + 1][CELLSIZE + 1][CELLSIZE + 1]; + int c[3]; + int puid; + unsigned hash; + const btCollisionShape* pclient; + Cell* next; }; // // Fields // - btAlignedObjectArray cells; - btScalar voxelsz; - int puid; - int ncells; - int m_clampCells; - int nprobes; - int nqueries; + btAlignedObjectArray cells; + btScalar voxelsz; + int puid; + int ncells; + int m_clampCells; + int nprobes; + int nqueries; // // Methods // // - void Initialize(int hashsize=2383, int clampCells = 256*1024) + void Initialize(int hashsize = 2383, int clampCells = 256 * 1024) { //avoid a crash due to running out of memory, so clamp the maximum number of cells allocated //if this limit is reached, the SDF is reset (at the cost of some performance during the reset) m_clampCells = clampCells; - cells.resize(hashsize,0); + cells.resize(hashsize, 0); Reset(); } // - void Reset() + void Reset() { - for(int i=0,ni=cells.size();inext; + Cell* pn = pc->next; delete pc; - pc=pn; + pc = pn; } } - voxelsz =0.25; - puid =0; - ncells =0; - nprobes =1; - nqueries =1; + voxelsz = 0.25; + puid = 0; + ncells = 0; + nprobes = 1; + nqueries = 1; } // - void GarbageCollect(int lifetime=256) + void GarbageCollect(int lifetime = 256) { - const int life=puid-lifetime; - for(int i=0;inext; - if(pc->puidnext; + if (pc->puid < life) { - if(pp) pp->next=pn; else root=pn; - delete pc;pc=pp;--ncells; + if (pp) + pp->next = pn; + else + root = pn; + delete pc; + pc = pp; + --ncells; } - pp=pc;pc=pn; + pp = pc; + pc = pn; } } //printf("GC[%d]: %d cells, PpQ: %f\r\n",puid,ncells,nprobes/(btScalar)nqueries); - nqueries=1; - nprobes=1; - ++puid; ///@todo: Reset puid's when int range limit is reached */ - /* else setup a priority list... */ + nqueries = 1; + nprobes = 1; + ++puid; ///@todo: Reset puid's when int range limit is reached */ + /* else setup a priority list... */ } // - int RemoveReferences(btCollisionShape* pcs) + int RemoveReferences(btCollisionShape* pcs) { - int refcount=0; - for(int i=0;inext; - if(pc->pclient==pcs) + Cell* pn = pc->next; + if (pc->pclient == pcs) { - if(pp) pp->next=pn; else root=pn; - delete pc;pc=pp;++refcount; + if (pp) + pp->next = pn; + else + root = pn; + delete pc; + pc = pp; + ++refcount; } - pp=pc;pc=pn; + pp = pc; + pc = pn; } } - return(refcount); + return (refcount); } // - btScalar Evaluate( const btVector3& x, - const btCollisionShape* shape, - btVector3& normal, - btScalar margin) + btScalar Evaluate(const btVector3& x, + const btCollisionShape* shape, + btVector3& normal, + btScalar margin) { - /* Lookup cell */ - const btVector3 scx=x/voxelsz; - const IntFrac ix=Decompose(scx.x()); - const IntFrac iy=Decompose(scx.y()); - const IntFrac iz=Decompose(scx.z()); - const unsigned h=Hash(ix.b,iy.b,iz.b,shape); - Cell*& root=cells[static_cast(h%cells.size())]; - Cell* c=root; + /* Lookup cell */ + const btVector3 scx = x / voxelsz; + const IntFrac ix = Decompose(scx.x()); + const IntFrac iy = Decompose(scx.y()); + const IntFrac iz = Decompose(scx.z()); + const unsigned h = Hash(ix.b, iy.b, iz.b, shape); + Cell*& root = cells[static_cast(h % cells.size())]; + Cell* c = root; ++nqueries; - while(c) + while (c) { ++nprobes; - if( (c->hash==h) && - (c->c[0]==ix.b) && - (c->c[1]==iy.b) && - (c->c[2]==iz.b) && - (c->pclient==shape)) - { break; } + if ((c->hash == h) && + (c->c[0] == ix.b) && + (c->c[1] == iy.b) && + (c->c[2] == iz.b) && + (c->pclient == shape)) + { + break; + } else - { c=c->next; } + { + c = c->next; + } } - if(!c) + if (!c) { - ++nprobes; + ++nprobes; ++ncells; //int sz = sizeof(Cell); - if (ncells>m_clampCells) + if (ncells > m_clampCells) { - static int numResets=0; + static int numResets = 0; numResets++; -// printf("numResets=%d\n",numResets); + // printf("numResets=%d\n",numResets); Reset(); } - c=new Cell(); - c->next=root;root=c; - c->pclient=shape; - c->hash=h; - c->c[0]=ix.b;c->c[1]=iy.b;c->c[2]=iz.b; + c = new Cell(); + c->next = root; + root = c; + c->pclient = shape; + c->hash = h; + c->c[0] = ix.b; + c->c[1] = iy.b; + c->c[2] = iz.b; BuildCell(*c); } - c->puid=puid; - /* Extract infos */ - const int o[]={ ix.i,iy.i,iz.i}; - const btScalar d[]={ c->d[o[0]+0][o[1]+0][o[2]+0], - c->d[o[0]+1][o[1]+0][o[2]+0], - c->d[o[0]+1][o[1]+1][o[2]+0], - c->d[o[0]+0][o[1]+1][o[2]+0], - c->d[o[0]+0][o[1]+0][o[2]+1], - c->d[o[0]+1][o[1]+0][o[2]+1], - c->d[o[0]+1][o[1]+1][o[2]+1], - c->d[o[0]+0][o[1]+1][o[2]+1]}; - /* Normal */ + c->puid = puid; + /* Extract infos */ + const int o[] = {ix.i, iy.i, iz.i}; + const btScalar d[] = {c->d[o[0] + 0][o[1] + 0][o[2] + 0], + c->d[o[0] + 1][o[1] + 0][o[2] + 0], + c->d[o[0] + 1][o[1] + 1][o[2] + 0], + c->d[o[0] + 0][o[1] + 1][o[2] + 0], + c->d[o[0] + 0][o[1] + 0][o[2] + 1], + c->d[o[0] + 1][o[1] + 0][o[2] + 1], + c->d[o[0] + 1][o[1] + 1][o[2] + 1], + c->d[o[0] + 0][o[1] + 1][o[2] + 1]}; + /* Normal */ #if 1 - const btScalar gx[]={ d[1]-d[0],d[2]-d[3], - d[5]-d[4],d[6]-d[7]}; - const btScalar gy[]={ d[3]-d[0],d[2]-d[1], - d[7]-d[4],d[6]-d[5]}; - const btScalar gz[]={ d[4]-d[0],d[5]-d[1], - d[7]-d[3],d[6]-d[2]}; - normal.setX(Lerp( Lerp(gx[0],gx[1],iy.f), - Lerp(gx[2],gx[3],iy.f),iz.f)); - normal.setY(Lerp( Lerp(gy[0],gy[1],ix.f), - Lerp(gy[2],gy[3],ix.f),iz.f)); - normal.setZ(Lerp( Lerp(gz[0],gz[1],ix.f), - Lerp(gz[2],gz[3],ix.f),iy.f)); - normal = normal.normalized(); + const btScalar gx[] = {d[1] - d[0], d[2] - d[3], + d[5] - d[4], d[6] - d[7]}; + const btScalar gy[] = {d[3] - d[0], d[2] - d[1], + d[7] - d[4], d[6] - d[5]}; + const btScalar gz[] = {d[4] - d[0], d[5] - d[1], + d[7] - d[3], d[6] - d[2]}; + normal.setX(Lerp(Lerp(gx[0], gx[1], iy.f), + Lerp(gx[2], gx[3], iy.f), iz.f)); + normal.setY(Lerp(Lerp(gy[0], gy[1], ix.f), + Lerp(gy[2], gy[3], ix.f), iz.f)); + normal.setZ(Lerp(Lerp(gz[0], gz[1], ix.f), + Lerp(gz[2], gz[3], ix.f), iy.f)); + normal = normal.normalized(); #else - normal = btVector3(d[1]-d[0],d[3]-d[0],d[4]-d[0]).normalized(); + normal = btVector3(d[1] - d[0], d[3] - d[0], d[4] - d[0]).normalized(); #endif - /* Distance */ - const btScalar d0=Lerp(Lerp(d[0],d[1],ix.f), - Lerp(d[3],d[2],ix.f),iy.f); - const btScalar d1=Lerp(Lerp(d[4],d[5],ix.f), - Lerp(d[7],d[6],ix.f),iy.f); - return(Lerp(d0,d1,iz.f)-margin); + /* Distance */ + const btScalar d0 = Lerp(Lerp(d[0], d[1], ix.f), + Lerp(d[3], d[2], ix.f), iy.f); + const btScalar d1 = Lerp(Lerp(d[4], d[5], ix.f), + Lerp(d[7], d[6], ix.f), iy.f); + return (Lerp(d0, d1, iz.f) - margin); } // - void BuildCell(Cell& c) + void BuildCell(Cell& c) { - const btVector3 org=btVector3( (btScalar)c.c[0], - (btScalar)c.c[1], - (btScalar)c.c[2]) * - CELLSIZE*voxelsz; - for(int k=0;k<=CELLSIZE;++k) + const btVector3 org = btVector3((btScalar)c.c[0], + (btScalar)c.c[1], + (btScalar)c.c[2]) * + CELLSIZE * voxelsz; + for (int k = 0; k <= CELLSIZE; ++k) { - const btScalar z=voxelsz*k+org.z(); - for(int j=0;j<=CELLSIZE;++j) + const btScalar z = voxelsz * k + org.z(); + for (int j = 0; j <= CELLSIZE; ++j) { - const btScalar y=voxelsz*j+org.y(); - for(int i=0;i<=CELLSIZE;++i) + const btScalar y = voxelsz * j + org.y(); + for (int i = 0; i <= CELLSIZE; ++i) { - const btScalar x=voxelsz*i+org.x(); - c.d[i][j][k]=DistanceToShape( btVector3(x,y,z), - c.pclient); + const btScalar x = voxelsz * i + org.x(); + c.d[i][j][k] = DistanceToShape(btVector3(x, y, z), + c.pclient); } } } } // - static inline btScalar DistanceToShape(const btVector3& x, - const btCollisionShape* shape) + static inline btScalar DistanceToShape(const btVector3& x, + const btCollisionShape* shape) { - btTransform unit; + btTransform unit; unit.setIdentity(); - if(shape->isConvex()) + if (shape->isConvex()) { - btGjkEpaSolver2::sResults res; - const btConvexShape* csh=static_cast(shape); - return(btGjkEpaSolver2::SignedDistance(x,0,csh,unit,res)); + btGjkEpaSolver2::sResults res; + const btConvexShape* csh = static_cast(shape); + return (btGjkEpaSolver2::SignedDistance(x, 0, csh, unit, res)); } - return(0); + return (0); } // - static inline IntFrac Decompose(btScalar x) + static inline IntFrac Decompose(btScalar x) { /* That one need a lot of improvements... */ - /* Remove test, faster floor... */ - IntFrac r; - x/=CELLSIZE; - const int o=x<0?(int)(-x+1):0; - x+=o;r.b=(int)x; - const btScalar k=(x-r.b)*CELLSIZE; - r.i=(int)k;r.f=k-r.i;r.b-=o; - return(r); + /* Remove test, faster floor... */ + IntFrac r; + x /= CELLSIZE; + const int o = x < 0 ? (int)(-x + 1) : 0; + x += o; + r.b = (int)x; + const btScalar k = (x - r.b) * CELLSIZE; + r.i = (int)k; + r.f = k - r.i; + r.b -= o; + return (r); } // - static inline btScalar Lerp(btScalar a,btScalar b,btScalar t) + static inline btScalar Lerp(btScalar a, btScalar b, btScalar t) { - return(a+(b-a)*t); + return (a + (b - a) * t); } - - // - static inline unsigned int Hash(int x,int y,int z,const btCollisionShape* shape) + static inline unsigned int Hash(int x, int y, int z, const btCollisionShape* shape) { struct btS - { - int x,y,z; + { + int x, y, z; void* p; }; btS myset; - myset.x=x;myset.y=y;myset.z=z;myset.p=(void*)shape; + myset.x = x; + myset.y = y; + myset.z = z; + myset.p = (void*)shape; const void* ptr = &myset; - unsigned int result = HsiehHash (ptr); - + unsigned int result = HsiehHash(ptr); return result; } }; - -#endif //BT_SPARSE_SDF_H +#endif //BT_SPARSE_SDF_H diff --git a/src/LinearMath/TaskScheduler/btTaskScheduler.cpp b/src/LinearMath/TaskScheduler/btTaskScheduler.cpp index 49510d166..5f1115c40 100644 --- a/src/LinearMath/TaskScheduler/btTaskScheduler.cpp +++ b/src/LinearMath/TaskScheduler/btTaskScheduler.cpp @@ -6,13 +6,11 @@ #include #include - - #if BT_THREADSAFE #include "btThreadSupportInterface.h" -#if defined( _WIN32 ) +#if defined(_WIN32) #define WIN32_LEAN_AND_MEAN @@ -20,404 +18,399 @@ #endif - typedef unsigned long long btU64; static const int kCacheLineSize = 64; void btSpinPause() { -#if defined( _WIN32 ) - YieldProcessor(); +#if defined(_WIN32) + YieldProcessor(); #endif } - struct WorkerThreadStatus { - enum Type - { - kInvalid, - kWaitingForWork, - kWorking, - kSleeping, - }; + enum Type + { + kInvalid, + kWaitingForWork, + kWorking, + kSleeping, + }; }; - -ATTRIBUTE_ALIGNED64(class) WorkerThreadDirectives +ATTRIBUTE_ALIGNED64(class) +WorkerThreadDirectives { - static const int kMaxThreadCount = BT_MAX_THREAD_COUNT; - // directives for all worker threads packed into a single cacheline - char m_threadDirs[kMaxThreadCount]; + static const int kMaxThreadCount = BT_MAX_THREAD_COUNT; + // directives for all worker threads packed into a single cacheline + char m_threadDirs[kMaxThreadCount]; public: - enum Type - { - kInvalid, - kGoToSleep, // go to sleep - kStayAwakeButIdle, // wait for not checking job queue - kScanForJobs, // actively scan job queue for jobs - }; - WorkerThreadDirectives() - { - for ( int i = 0; i < kMaxThreadCount; ++i ) - { - m_threadDirs[ i ] = 0; - } - } + enum Type + { + kInvalid, + kGoToSleep, // go to sleep + kStayAwakeButIdle, // wait for not checking job queue + kScanForJobs, // actively scan job queue for jobs + }; + WorkerThreadDirectives() + { + for (int i = 0; i < kMaxThreadCount; ++i) + { + m_threadDirs[i] = 0; + } + } - Type getDirective(int threadId) - { - btAssert(threadId < kMaxThreadCount); - return static_cast(m_threadDirs[threadId]); - } + Type getDirective(int threadId) + { + btAssert(threadId < kMaxThreadCount); + return static_cast(m_threadDirs[threadId]); + } - void setDirectiveByRange(int threadBegin, int threadEnd, Type dir) - { - btAssert( threadBegin < threadEnd ); - btAssert( threadEnd <= kMaxThreadCount ); - char dirChar = static_cast(dir); - for ( int i = threadBegin; i < threadEnd; ++i ) - { - m_threadDirs[ i ] = dirChar; - } - } + void setDirectiveByRange(int threadBegin, int threadEnd, Type dir) + { + btAssert(threadBegin < threadEnd); + btAssert(threadEnd <= kMaxThreadCount); + char dirChar = static_cast(dir); + for (int i = threadBegin; i < threadEnd; ++i) + { + m_threadDirs[i] = dirChar; + } + } }; class JobQueue; -ATTRIBUTE_ALIGNED64(struct) ThreadLocalStorage +ATTRIBUTE_ALIGNED64(struct) +ThreadLocalStorage { - int m_threadId; - WorkerThreadStatus::Type m_status; - int m_numJobsFinished; - btSpinMutex m_mutex; - btScalar m_sumResult; - WorkerThreadDirectives * m_directive; - JobQueue* m_queue; - btClock* m_clock; - unsigned int m_cooldownTime; + int m_threadId; + WorkerThreadStatus::Type m_status; + int m_numJobsFinished; + btSpinMutex m_mutex; + btScalar m_sumResult; + WorkerThreadDirectives* m_directive; + JobQueue* m_queue; + btClock* m_clock; + unsigned int m_cooldownTime; }; - struct IJob { - virtual void executeJob(int threadId) = 0; + virtual void executeJob(int threadId) = 0; }; class ParallelForJob : public IJob { - const btIParallelForBody* m_body; - int m_begin; - int m_end; + const btIParallelForBody* m_body; + int m_begin; + int m_end; public: - ParallelForJob( int iBegin, int iEnd, const btIParallelForBody& body ) - { - m_body = &body; - m_begin = iBegin; - m_end = iEnd; - } - virtual void executeJob(int threadId) BT_OVERRIDE - { - BT_PROFILE( "executeJob" ); + ParallelForJob(int iBegin, int iEnd, const btIParallelForBody& body) + { + m_body = &body; + m_begin = iBegin; + m_end = iEnd; + } + virtual void executeJob(int threadId) BT_OVERRIDE + { + BT_PROFILE("executeJob"); - // call the functor body to do the work - m_body->forLoop( m_begin, m_end ); - } + // call the functor body to do the work + m_body->forLoop(m_begin, m_end); + } }; - class ParallelSumJob : public IJob { - const btIParallelSumBody* m_body; - ThreadLocalStorage* m_threadLocalStoreArray; - int m_begin; - int m_end; + const btIParallelSumBody* m_body; + ThreadLocalStorage* m_threadLocalStoreArray; + int m_begin; + int m_end; public: - ParallelSumJob( int iBegin, int iEnd, const btIParallelSumBody& body, ThreadLocalStorage* tls ) - { - m_body = &body; - m_threadLocalStoreArray = tls; - m_begin = iBegin; - m_end = iEnd; - } - virtual void executeJob( int threadId ) BT_OVERRIDE - { - BT_PROFILE( "executeJob" ); + ParallelSumJob(int iBegin, int iEnd, const btIParallelSumBody& body, ThreadLocalStorage* tls) + { + m_body = &body; + m_threadLocalStoreArray = tls; + m_begin = iBegin; + m_end = iEnd; + } + virtual void executeJob(int threadId) BT_OVERRIDE + { + BT_PROFILE("executeJob"); - // call the functor body to do the work - btScalar val = m_body->sumLoop( m_begin, m_end ); + // call the functor body to do the work + btScalar val = m_body->sumLoop(m_begin, m_end); #if BT_PARALLEL_SUM_DETERMINISTISM - // by truncating bits of the result, we can make the parallelSum deterministic (at the expense of precision) - const float TRUNC_SCALE = float(1<<19); - val = floor(val*TRUNC_SCALE+0.5f)/TRUNC_SCALE; // truncate some bits + // by truncating bits of the result, we can make the parallelSum deterministic (at the expense of precision) + const float TRUNC_SCALE = float(1 << 19); + val = floor(val * TRUNC_SCALE + 0.5f) / TRUNC_SCALE; // truncate some bits #endif - m_threadLocalStoreArray[threadId].m_sumResult += val; - } + m_threadLocalStoreArray[threadId].m_sumResult += val; + } }; - -ATTRIBUTE_ALIGNED64(class) JobQueue +ATTRIBUTE_ALIGNED64(class) +JobQueue { - btThreadSupportInterface* m_threadSupport; - btCriticalSection* m_queueLock; - btSpinMutex m_mutex; + btThreadSupportInterface* m_threadSupport; + btCriticalSection* m_queueLock; + btSpinMutex m_mutex; - btAlignedObjectArray m_jobQueue; - char* m_jobMem; - int m_jobMemSize; - bool m_queueIsEmpty; - int m_tailIndex; - int m_headIndex; - int m_allocSize; - bool m_useSpinMutex; - btAlignedObjectArray m_neighborContexts; - char m_cachePadding[kCacheLineSize]; // prevent false sharing + btAlignedObjectArray m_jobQueue; + char* m_jobMem; + int m_jobMemSize; + bool m_queueIsEmpty; + int m_tailIndex; + int m_headIndex; + int m_allocSize; + bool m_useSpinMutex; + btAlignedObjectArray m_neighborContexts; + char m_cachePadding[kCacheLineSize]; // prevent false sharing - void freeJobMem() - { - if ( m_jobMem ) - { - // free old - btAlignedFree(m_jobMem); - m_jobMem = NULL; - } - } - void resizeJobMem(int newSize) - { - if (newSize > m_jobMemSize) - { - freeJobMem(); - m_jobMem = static_cast(btAlignedAlloc(newSize, kCacheLineSize)); - m_jobMemSize = newSize; - } - } - -public: - - JobQueue() - { - m_jobMem = NULL; - m_jobMemSize = 0; - m_threadSupport = NULL; - m_queueLock = NULL; - m_headIndex = 0; - m_tailIndex = 0; - m_useSpinMutex = false; - } - ~JobQueue() - { - exit(); - } - void exit() - { - freeJobMem(); - if (m_queueLock && m_threadSupport) - { - m_threadSupport->deleteCriticalSection(m_queueLock); - m_queueLock = NULL; - m_threadSupport = 0; - } + void freeJobMem() + { + if (m_jobMem) + { + // free old + btAlignedFree(m_jobMem); + m_jobMem = NULL; + } + } + void resizeJobMem(int newSize) + { + if (newSize > m_jobMemSize) + { + freeJobMem(); + m_jobMem = static_cast(btAlignedAlloc(newSize, kCacheLineSize)); + m_jobMemSize = newSize; + } } - void init(btThreadSupportInterface* threadSup, btAlignedObjectArray* contextArray) - { - m_threadSupport = threadSup; - if (threadSup) - { - m_queueLock = m_threadSupport->createCriticalSection(); - } - setupJobStealing(contextArray, contextArray->size()); - } - void setupJobStealing(btAlignedObjectArray* contextArray, int numActiveContexts) - { - btAlignedObjectArray& contexts = *contextArray; - int selfIndex = 0; - for (int i = 0; i < contexts.size(); ++i) - { - if ( this == &contexts[ i ] ) - { - selfIndex = i; - break; - } - } - int numNeighbors = btMin(2, contexts.size() - 1); - int neighborOffsets[ ] = {-1, 1, -2, 2, -3, 3}; - int numOffsets = sizeof(neighborOffsets)/sizeof(neighborOffsets[0]); - m_neighborContexts.reserve( numNeighbors ); - m_neighborContexts.resizeNoInitialize(0); - for (int i = 0; i < numOffsets && m_neighborContexts.size() < numNeighbors; i++) - { - int neighborIndex = selfIndex + neighborOffsets[i]; - if ( neighborIndex >= 0 && neighborIndex < numActiveContexts) - { - m_neighborContexts.push_back( &contexts[ neighborIndex ] ); - } - } - } +public: + JobQueue() + { + m_jobMem = NULL; + m_jobMemSize = 0; + m_threadSupport = NULL; + m_queueLock = NULL; + m_headIndex = 0; + m_tailIndex = 0; + m_useSpinMutex = false; + } + ~JobQueue() + { + exit(); + } + void exit() + { + freeJobMem(); + if (m_queueLock && m_threadSupport) + { + m_threadSupport->deleteCriticalSection(m_queueLock); + m_queueLock = NULL; + m_threadSupport = 0; + } + } - bool isQueueEmpty() const {return m_queueIsEmpty;} - void lockQueue() - { - if ( m_useSpinMutex ) - { - m_mutex.lock(); - } - else - { - m_queueLock->lock(); - } - } - void unlockQueue() - { - if ( m_useSpinMutex ) - { - m_mutex.unlock(); - } - else - { - m_queueLock->unlock(); - } - } - void clearQueue(int jobCount, int jobSize) - { - lockQueue(); - m_headIndex = 0; - m_tailIndex = 0; - m_allocSize = 0; - m_queueIsEmpty = true; - int jobBufSize = jobSize * jobCount; - // make sure we have enough memory allocated to store jobs - if ( jobBufSize > m_jobMemSize ) - { - resizeJobMem( jobBufSize ); - } - // make sure job queue is big enough - if ( jobCount > m_jobQueue.capacity() ) - { - m_jobQueue.reserve( jobCount ); - } - unlockQueue(); - m_jobQueue.resizeNoInitialize( 0 ); - } - void* allocJobMem(int jobSize) - { - btAssert(m_jobMemSize >= (m_allocSize + jobSize)); - void* jobMem = &m_jobMem[m_allocSize]; - m_allocSize += jobSize; - return jobMem; - } - void submitJob( IJob* job ) - { - btAssert( reinterpret_cast( job ) >= &m_jobMem[ 0 ] && reinterpret_cast( job ) < &m_jobMem[ 0 ] + m_allocSize ); - m_jobQueue.push_back( job ); - lockQueue(); - m_tailIndex++; - m_queueIsEmpty = false; - unlockQueue(); - } - IJob* consumeJobFromOwnQueue() - { - if ( m_queueIsEmpty ) - { - // lock free path. even if this is taken erroneously it isn't harmful - return NULL; - } - IJob* job = NULL; - lockQueue(); - if ( !m_queueIsEmpty ) - { - job = m_jobQueue[ m_headIndex++ ]; - btAssert( reinterpret_cast( job ) >= &m_jobMem[ 0 ] && reinterpret_cast( job ) < &m_jobMem[ 0 ] + m_allocSize ); - if ( m_headIndex == m_tailIndex ) - { - m_queueIsEmpty = true; - } - } - unlockQueue(); - return job; - } - IJob* consumeJob() - { - if (IJob* job = consumeJobFromOwnQueue()) - { - return job; - } - // own queue is empty, try to steal from neighbor - for (int i = 0; i < m_neighborContexts.size(); ++i) - { - JobQueue* otherContext = m_neighborContexts[ i ]; - if ( IJob* job = otherContext->consumeJobFromOwnQueue() ) - { - return job; - } - } - return NULL; - } + void init(btThreadSupportInterface * threadSup, btAlignedObjectArray * contextArray) + { + m_threadSupport = threadSup; + if (threadSup) + { + m_queueLock = m_threadSupport->createCriticalSection(); + } + setupJobStealing(contextArray, contextArray->size()); + } + void setupJobStealing(btAlignedObjectArray * contextArray, int numActiveContexts) + { + btAlignedObjectArray& contexts = *contextArray; + int selfIndex = 0; + for (int i = 0; i < contexts.size(); ++i) + { + if (this == &contexts[i]) + { + selfIndex = i; + break; + } + } + int numNeighbors = btMin(2, contexts.size() - 1); + int neighborOffsets[] = {-1, 1, -2, 2, -3, 3}; + int numOffsets = sizeof(neighborOffsets) / sizeof(neighborOffsets[0]); + m_neighborContexts.reserve(numNeighbors); + m_neighborContexts.resizeNoInitialize(0); + for (int i = 0; i < numOffsets && m_neighborContexts.size() < numNeighbors; i++) + { + int neighborIndex = selfIndex + neighborOffsets[i]; + if (neighborIndex >= 0 && neighborIndex < numActiveContexts) + { + m_neighborContexts.push_back(&contexts[neighborIndex]); + } + } + } + + bool isQueueEmpty() const { return m_queueIsEmpty; } + void lockQueue() + { + if (m_useSpinMutex) + { + m_mutex.lock(); + } + else + { + m_queueLock->lock(); + } + } + void unlockQueue() + { + if (m_useSpinMutex) + { + m_mutex.unlock(); + } + else + { + m_queueLock->unlock(); + } + } + void clearQueue(int jobCount, int jobSize) + { + lockQueue(); + m_headIndex = 0; + m_tailIndex = 0; + m_allocSize = 0; + m_queueIsEmpty = true; + int jobBufSize = jobSize * jobCount; + // make sure we have enough memory allocated to store jobs + if (jobBufSize > m_jobMemSize) + { + resizeJobMem(jobBufSize); + } + // make sure job queue is big enough + if (jobCount > m_jobQueue.capacity()) + { + m_jobQueue.reserve(jobCount); + } + unlockQueue(); + m_jobQueue.resizeNoInitialize(0); + } + void* allocJobMem(int jobSize) + { + btAssert(m_jobMemSize >= (m_allocSize + jobSize)); + void* jobMem = &m_jobMem[m_allocSize]; + m_allocSize += jobSize; + return jobMem; + } + void submitJob(IJob * job) + { + btAssert(reinterpret_cast(job) >= &m_jobMem[0] && reinterpret_cast(job) < &m_jobMem[0] + m_allocSize); + m_jobQueue.push_back(job); + lockQueue(); + m_tailIndex++; + m_queueIsEmpty = false; + unlockQueue(); + } + IJob* consumeJobFromOwnQueue() + { + if (m_queueIsEmpty) + { + // lock free path. even if this is taken erroneously it isn't harmful + return NULL; + } + IJob* job = NULL; + lockQueue(); + if (!m_queueIsEmpty) + { + job = m_jobQueue[m_headIndex++]; + btAssert(reinterpret_cast(job) >= &m_jobMem[0] && reinterpret_cast(job) < &m_jobMem[0] + m_allocSize); + if (m_headIndex == m_tailIndex) + { + m_queueIsEmpty = true; + } + } + unlockQueue(); + return job; + } + IJob* consumeJob() + { + if (IJob* job = consumeJobFromOwnQueue()) + { + return job; + } + // own queue is empty, try to steal from neighbor + for (int i = 0; i < m_neighborContexts.size(); ++i) + { + JobQueue* otherContext = m_neighborContexts[i]; + if (IJob* job = otherContext->consumeJobFromOwnQueue()) + { + return job; + } + } + return NULL; + } }; - -static void WorkerThreadFunc( void* userPtr ) +static void WorkerThreadFunc(void* userPtr) { - BT_PROFILE( "WorkerThreadFunc" ); - ThreadLocalStorage* localStorage = (ThreadLocalStorage*) userPtr; - JobQueue* jobQueue = localStorage->m_queue; + BT_PROFILE("WorkerThreadFunc"); + ThreadLocalStorage* localStorage = (ThreadLocalStorage*)userPtr; + JobQueue* jobQueue = localStorage->m_queue; - bool shouldSleep = false; - int threadId = localStorage->m_threadId; - while (! shouldSleep) - { - // do work - localStorage->m_mutex.lock(); - while ( IJob* job = jobQueue->consumeJob() ) - { - localStorage->m_status = WorkerThreadStatus::kWorking; - job->executeJob( threadId ); - localStorage->m_numJobsFinished++; - } - localStorage->m_status = WorkerThreadStatus::kWaitingForWork; - localStorage->m_mutex.unlock(); - btU64 clockStart = localStorage->m_clock->getTimeMicroseconds(); - // while queue is empty, - while (jobQueue->isQueueEmpty()) - { - // todo: spin wait a bit to avoid hammering the empty queue - btSpinPause(); - if ( localStorage->m_directive->getDirective(threadId) == WorkerThreadDirectives::kGoToSleep ) - { - shouldSleep = true; - break; - } - // if jobs are incoming, - if ( localStorage->m_directive->getDirective( threadId ) == WorkerThreadDirectives::kScanForJobs ) - { - clockStart = localStorage->m_clock->getTimeMicroseconds(); // reset clock - } - else - { - for ( int i = 0; i < 50; ++i ) - { - btSpinPause(); - btSpinPause(); - btSpinPause(); - btSpinPause(); - if (localStorage->m_directive->getDirective( threadId ) == WorkerThreadDirectives::kScanForJobs || !jobQueue->isQueueEmpty()) - { - break; - } - } - // if no jobs incoming and queue has been empty for the cooldown time, sleep - btU64 timeElapsed = localStorage->m_clock->getTimeMicroseconds() - clockStart; - if (timeElapsed > localStorage->m_cooldownTime) - { - shouldSleep = true; - break; - } - } - } - } + bool shouldSleep = false; + int threadId = localStorage->m_threadId; + while (!shouldSleep) + { + // do work + localStorage->m_mutex.lock(); + while (IJob* job = jobQueue->consumeJob()) + { + localStorage->m_status = WorkerThreadStatus::kWorking; + job->executeJob(threadId); + localStorage->m_numJobsFinished++; + } + localStorage->m_status = WorkerThreadStatus::kWaitingForWork; + localStorage->m_mutex.unlock(); + btU64 clockStart = localStorage->m_clock->getTimeMicroseconds(); + // while queue is empty, + while (jobQueue->isQueueEmpty()) + { + // todo: spin wait a bit to avoid hammering the empty queue + btSpinPause(); + if (localStorage->m_directive->getDirective(threadId) == WorkerThreadDirectives::kGoToSleep) + { + shouldSleep = true; + break; + } + // if jobs are incoming, + if (localStorage->m_directive->getDirective(threadId) == WorkerThreadDirectives::kScanForJobs) + { + clockStart = localStorage->m_clock->getTimeMicroseconds(); // reset clock + } + else + { + for (int i = 0; i < 50; ++i) + { + btSpinPause(); + btSpinPause(); + btSpinPause(); + btSpinPause(); + if (localStorage->m_directive->getDirective(threadId) == WorkerThreadDirectives::kScanForJobs || !jobQueue->isQueueEmpty()) + { + break; + } + } + // if no jobs incoming and queue has been empty for the cooldown time, sleep + btU64 timeElapsed = localStorage->m_clock->getTimeMicroseconds() - clockStart; + if (timeElapsed > localStorage->m_cooldownTime) + { + shouldSleep = true; + break; + } + } + } + } { BT_PROFILE("sleep"); // go sleep @@ -427,376 +420,373 @@ static void WorkerThreadFunc( void* userPtr ) } } - class btTaskSchedulerDefault : public btITaskScheduler { - btThreadSupportInterface* m_threadSupport; - WorkerThreadDirectives* m_workerDirective; - btAlignedObjectArray m_jobQueues; - btAlignedObjectArray m_perThreadJobQueues; - btAlignedObjectArray m_threadLocalStorage; - btSpinMutex m_antiNestingLock; // prevent nested parallel-for - btClock m_clock; - int m_numThreads; - int m_numWorkerThreads; - int m_numActiveJobQueues; - int m_maxNumThreads; - int m_numJobs; - static const int kFirstWorkerThreadId = 1; + btThreadSupportInterface* m_threadSupport; + WorkerThreadDirectives* m_workerDirective; + btAlignedObjectArray m_jobQueues; + btAlignedObjectArray m_perThreadJobQueues; + btAlignedObjectArray m_threadLocalStorage; + btSpinMutex m_antiNestingLock; // prevent nested parallel-for + btClock m_clock; + int m_numThreads; + int m_numWorkerThreads; + int m_numActiveJobQueues; + int m_maxNumThreads; + int m_numJobs; + static const int kFirstWorkerThreadId = 1; + public: + btTaskSchedulerDefault() : btITaskScheduler("ThreadSupport") + { + m_threadSupport = NULL; + m_workerDirective = NULL; + } - btTaskSchedulerDefault() : btITaskScheduler("ThreadSupport") - { - m_threadSupport = NULL; - m_workerDirective = NULL; - } + virtual ~btTaskSchedulerDefault() + { + waitForWorkersToSleep(); - virtual ~btTaskSchedulerDefault() - { - waitForWorkersToSleep(); + for (int i = 0; i < m_jobQueues.size(); ++i) + { + m_jobQueues[i].exit(); + } - for ( int i = 0; i < m_jobQueues.size(); ++i ) - { - m_jobQueues[i].exit(); - } + if (m_threadSupport) + { + delete m_threadSupport; + m_threadSupport = NULL; + } + if (m_workerDirective) + { + btAlignedFree(m_workerDirective); + m_workerDirective = NULL; + } + } - if (m_threadSupport) - { - delete m_threadSupport; - m_threadSupport = NULL; - } - if (m_workerDirective) - { - btAlignedFree(m_workerDirective); - m_workerDirective = NULL; - } - } + void init() + { + btThreadSupportInterface::ConstructionInfo constructionInfo("TaskScheduler", WorkerThreadFunc); + m_threadSupport = btThreadSupportInterface::create(constructionInfo); + m_workerDirective = static_cast(btAlignedAlloc(sizeof(*m_workerDirective), 64)); - void init() - { - btThreadSupportInterface::ConstructionInfo constructionInfo( "TaskScheduler", WorkerThreadFunc ); - m_threadSupport = btThreadSupportInterface::create( constructionInfo ); - m_workerDirective = static_cast(btAlignedAlloc(sizeof(*m_workerDirective), 64)); + m_numWorkerThreads = m_threadSupport->getNumWorkerThreads(); + m_maxNumThreads = m_threadSupport->getNumWorkerThreads() + 1; + m_numThreads = m_maxNumThreads; + // ideal to have one job queue for each physical processor (except for the main thread which needs no queue) + int numThreadsPerQueue = m_threadSupport->getLogicalToPhysicalCoreRatio(); + int numJobQueues = (numThreadsPerQueue == 1) ? (m_maxNumThreads - 1) : (m_maxNumThreads / numThreadsPerQueue); + m_jobQueues.resize(numJobQueues); + m_numActiveJobQueues = numJobQueues; + for (int i = 0; i < m_jobQueues.size(); ++i) + { + m_jobQueues[i].init(m_threadSupport, &m_jobQueues); + } + m_perThreadJobQueues.resize(m_numThreads); + for (int i = 0; i < m_numThreads; i++) + { + JobQueue* jq = NULL; + // only worker threads get a job queue + if (i > 0) + { + if (numThreadsPerQueue == 1) + { + // one queue per worker thread + jq = &m_jobQueues[i - kFirstWorkerThreadId]; + } + else + { + // 2 threads share each queue + jq = &m_jobQueues[i / numThreadsPerQueue]; + } + } + m_perThreadJobQueues[i] = jq; + } + m_threadLocalStorage.resize(m_numThreads); + for (int i = 0; i < m_numThreads; i++) + { + ThreadLocalStorage& storage = m_threadLocalStorage[i]; + storage.m_threadId = i; + storage.m_directive = m_workerDirective; + storage.m_status = WorkerThreadStatus::kSleeping; + storage.m_cooldownTime = 100; // 100 microseconds, threads go to sleep after this long if they have nothing to do + storage.m_clock = &m_clock; + storage.m_queue = m_perThreadJobQueues[i]; + } + setWorkerDirectives(WorkerThreadDirectives::kGoToSleep); // no work for them yet + setNumThreads(m_threadSupport->getCacheFriendlyNumThreads()); + } - m_numWorkerThreads = m_threadSupport->getNumWorkerThreads(); - m_maxNumThreads = m_threadSupport->getNumWorkerThreads() + 1; - m_numThreads = m_maxNumThreads; - // ideal to have one job queue for each physical processor (except for the main thread which needs no queue) - int numThreadsPerQueue = m_threadSupport->getLogicalToPhysicalCoreRatio(); - int numJobQueues = (numThreadsPerQueue == 1) ? (m_maxNumThreads-1) : (m_maxNumThreads / numThreadsPerQueue); - m_jobQueues.resize(numJobQueues); - m_numActiveJobQueues = numJobQueues; - for ( int i = 0; i < m_jobQueues.size(); ++i ) - { - m_jobQueues[i].init( m_threadSupport, &m_jobQueues ); - } - m_perThreadJobQueues.resize(m_numThreads); - for ( int i = 0; i < m_numThreads; i++ ) - { - JobQueue* jq = NULL; - // only worker threads get a job queue - if (i > 0) - { - if (numThreadsPerQueue == 1) - { - // one queue per worker thread - jq = &m_jobQueues[ i - kFirstWorkerThreadId ]; - } - else - { - // 2 threads share each queue - jq = &m_jobQueues[ i / numThreadsPerQueue ]; - } - } - m_perThreadJobQueues[i] = jq; - } - m_threadLocalStorage.resize(m_numThreads); - for ( int i = 0; i < m_numThreads; i++ ) - { - ThreadLocalStorage& storage = m_threadLocalStorage[i]; - storage.m_threadId = i; - storage.m_directive = m_workerDirective; - storage.m_status = WorkerThreadStatus::kSleeping; - storage.m_cooldownTime = 100; // 100 microseconds, threads go to sleep after this long if they have nothing to do - storage.m_clock = &m_clock; - storage.m_queue = m_perThreadJobQueues[i]; - } - setWorkerDirectives( WorkerThreadDirectives::kGoToSleep ); // no work for them yet - setNumThreads( m_threadSupport->getCacheFriendlyNumThreads() ); - } + void setWorkerDirectives(WorkerThreadDirectives::Type dir) + { + m_workerDirective->setDirectiveByRange(kFirstWorkerThreadId, m_numThreads, dir); + } - void setWorkerDirectives(WorkerThreadDirectives::Type dir) - { - m_workerDirective->setDirectiveByRange(kFirstWorkerThreadId, m_numThreads, dir); - } + virtual int getMaxNumThreads() const BT_OVERRIDE + { + return m_maxNumThreads; + } - virtual int getMaxNumThreads() const BT_OVERRIDE - { - return m_maxNumThreads; - } + virtual int getNumThreads() const BT_OVERRIDE + { + return m_numThreads; + } - virtual int getNumThreads() const BT_OVERRIDE - { - return m_numThreads; - } + virtual void setNumThreads(int numThreads) BT_OVERRIDE + { + m_numThreads = btMax(btMin(numThreads, int(m_maxNumThreads)), 1); + m_numWorkerThreads = m_numThreads - 1; + m_numActiveJobQueues = 0; + // if there is at least 1 worker, + if (m_numWorkerThreads > 0) + { + // re-setup job stealing between queues to avoid attempting to steal from an inactive job queue + JobQueue* lastActiveContext = m_perThreadJobQueues[m_numThreads - 1]; + int iLastActiveContext = lastActiveContext - &m_jobQueues[0]; + m_numActiveJobQueues = iLastActiveContext + 1; + for (int i = 0; i < m_jobQueues.size(); ++i) + { + m_jobQueues[i].setupJobStealing(&m_jobQueues, m_numActiveJobQueues); + } + } + m_workerDirective->setDirectiveByRange(m_numThreads, BT_MAX_THREAD_COUNT, WorkerThreadDirectives::kGoToSleep); + } - virtual void setNumThreads( int numThreads ) BT_OVERRIDE - { - m_numThreads = btMax( btMin(numThreads, int(m_maxNumThreads)), 1 ); - m_numWorkerThreads = m_numThreads - 1; - m_numActiveJobQueues = 0; - // if there is at least 1 worker, - if ( m_numWorkerThreads > 0 ) - { - // re-setup job stealing between queues to avoid attempting to steal from an inactive job queue - JobQueue* lastActiveContext = m_perThreadJobQueues[ m_numThreads - 1 ]; - int iLastActiveContext = lastActiveContext - &m_jobQueues[0]; - m_numActiveJobQueues = iLastActiveContext + 1; - for ( int i = 0; i < m_jobQueues.size(); ++i ) - { - m_jobQueues[ i ].setupJobStealing( &m_jobQueues, m_numActiveJobQueues ); - } - } - m_workerDirective->setDirectiveByRange(m_numThreads, BT_MAX_THREAD_COUNT, WorkerThreadDirectives::kGoToSleep); - } + void waitJobs() + { + BT_PROFILE("waitJobs"); + // have the main thread work until the job queues are empty + int numMainThreadJobsFinished = 0; + for (int i = 0; i < m_numActiveJobQueues; ++i) + { + while (IJob* job = m_jobQueues[i].consumeJob()) + { + job->executeJob(0); + numMainThreadJobsFinished++; + } + } - void waitJobs() - { - BT_PROFILE( "waitJobs" ); - // have the main thread work until the job queues are empty - int numMainThreadJobsFinished = 0; - for ( int i = 0; i < m_numActiveJobQueues; ++i ) - { - while ( IJob* job = m_jobQueues[i].consumeJob() ) - { - job->executeJob( 0 ); - numMainThreadJobsFinished++; - } - } + // done with jobs for now, tell workers to rest (but not sleep) + setWorkerDirectives(WorkerThreadDirectives::kStayAwakeButIdle); - // done with jobs for now, tell workers to rest (but not sleep) - setWorkerDirectives( WorkerThreadDirectives::kStayAwakeButIdle ); + btU64 clockStart = m_clock.getTimeMicroseconds(); + // wait for workers to finish any jobs in progress + while (true) + { + int numWorkerJobsFinished = 0; + for (int iThread = kFirstWorkerThreadId; iThread < m_numThreads; ++iThread) + { + ThreadLocalStorage* storage = &m_threadLocalStorage[iThread]; + storage->m_mutex.lock(); + numWorkerJobsFinished += storage->m_numJobsFinished; + storage->m_mutex.unlock(); + } + if (numWorkerJobsFinished + numMainThreadJobsFinished == m_numJobs) + { + break; + } + btU64 timeElapsed = m_clock.getTimeMicroseconds() - clockStart; + btAssert(timeElapsed < 1000); + if (timeElapsed > 100000) + { + break; + } + btSpinPause(); + } + } - btU64 clockStart = m_clock.getTimeMicroseconds(); - // wait for workers to finish any jobs in progress - while ( true ) - { - int numWorkerJobsFinished = 0; - for ( int iThread = kFirstWorkerThreadId; iThread < m_numThreads; ++iThread ) - { - ThreadLocalStorage* storage = &m_threadLocalStorage[iThread]; - storage->m_mutex.lock(); - numWorkerJobsFinished += storage->m_numJobsFinished; - storage->m_mutex.unlock(); - } - if (numWorkerJobsFinished + numMainThreadJobsFinished == m_numJobs) - { - break; - } - btU64 timeElapsed = m_clock.getTimeMicroseconds() - clockStart; - btAssert(timeElapsed < 1000); - if (timeElapsed > 100000) - { - break; - } - btSpinPause(); - } - } + void wakeWorkers(int numWorkersToWake) + { + BT_PROFILE("wakeWorkers"); + btAssert(m_workerDirective->getDirective(1) == WorkerThreadDirectives::kScanForJobs); + int numDesiredWorkers = btMin(numWorkersToWake, m_numWorkerThreads); + int numActiveWorkers = 0; + for (int iWorker = 0; iWorker < m_numWorkerThreads; ++iWorker) + { + // note this count of active workers is not necessarily totally reliable, because a worker thread could be + // just about to put itself to sleep. So we may on occasion fail to wake up all the workers. It should be rare. + ThreadLocalStorage& storage = m_threadLocalStorage[kFirstWorkerThreadId + iWorker]; + if (storage.m_status != WorkerThreadStatus::kSleeping) + { + numActiveWorkers++; + } + } + for (int iWorker = 0; iWorker < m_numWorkerThreads && numActiveWorkers < numDesiredWorkers; ++iWorker) + { + ThreadLocalStorage& storage = m_threadLocalStorage[kFirstWorkerThreadId + iWorker]; + if (storage.m_status == WorkerThreadStatus::kSleeping) + { + m_threadSupport->runTask(iWorker, &storage); + numActiveWorkers++; + } + } + } - void wakeWorkers(int numWorkersToWake) - { - BT_PROFILE( "wakeWorkers" ); - btAssert( m_workerDirective->getDirective(1) == WorkerThreadDirectives::kScanForJobs ); - int numDesiredWorkers = btMin(numWorkersToWake, m_numWorkerThreads); - int numActiveWorkers = 0; - for ( int iWorker = 0; iWorker < m_numWorkerThreads; ++iWorker ) - { - // note this count of active workers is not necessarily totally reliable, because a worker thread could be - // just about to put itself to sleep. So we may on occasion fail to wake up all the workers. It should be rare. - ThreadLocalStorage& storage = m_threadLocalStorage[ kFirstWorkerThreadId + iWorker ]; - if (storage.m_status != WorkerThreadStatus::kSleeping) - { - numActiveWorkers++; - } - } - for ( int iWorker = 0; iWorker < m_numWorkerThreads && numActiveWorkers < numDesiredWorkers; ++iWorker ) - { - ThreadLocalStorage& storage = m_threadLocalStorage[ kFirstWorkerThreadId + iWorker ]; - if (storage.m_status == WorkerThreadStatus::kSleeping) - { - m_threadSupport->runTask( iWorker, &storage ); - numActiveWorkers++; - } - } - } + void waitForWorkersToSleep() + { + BT_PROFILE("waitForWorkersToSleep"); + setWorkerDirectives(WorkerThreadDirectives::kGoToSleep); + m_threadSupport->waitForAllTasks(); + for (int i = kFirstWorkerThreadId; i < m_numThreads; i++) + { + ThreadLocalStorage& storage = m_threadLocalStorage[i]; + btAssert(storage.m_status == WorkerThreadStatus::kSleeping); + } + } - void waitForWorkersToSleep() - { - BT_PROFILE( "waitForWorkersToSleep" ); - setWorkerDirectives( WorkerThreadDirectives::kGoToSleep ); - m_threadSupport->waitForAllTasks(); - for ( int i = kFirstWorkerThreadId; i < m_numThreads; i++ ) - { - ThreadLocalStorage& storage = m_threadLocalStorage[i]; - btAssert( storage.m_status == WorkerThreadStatus::kSleeping ); - } - } + virtual void sleepWorkerThreadsHint() BT_OVERRIDE + { + BT_PROFILE("sleepWorkerThreadsHint"); + // hint the task scheduler that we may not be using these threads for a little while + setWorkerDirectives(WorkerThreadDirectives::kGoToSleep); + } - virtual void sleepWorkerThreadsHint() BT_OVERRIDE - { - BT_PROFILE( "sleepWorkerThreadsHint" ); - // hint the task scheduler that we may not be using these threads for a little while - setWorkerDirectives( WorkerThreadDirectives::kGoToSleep ); - } + void prepareWorkerThreads() + { + for (int i = kFirstWorkerThreadId; i < m_numThreads; ++i) + { + ThreadLocalStorage& storage = m_threadLocalStorage[i]; + storage.m_mutex.lock(); + storage.m_numJobsFinished = 0; + storage.m_mutex.unlock(); + } + setWorkerDirectives(WorkerThreadDirectives::kScanForJobs); + } - void prepareWorkerThreads() - { - for ( int i = kFirstWorkerThreadId; i < m_numThreads; ++i ) - { - ThreadLocalStorage& storage = m_threadLocalStorage[i]; - storage.m_mutex.lock(); - storage.m_numJobsFinished = 0; - storage.m_mutex.unlock(); - } - setWorkerDirectives( WorkerThreadDirectives::kScanForJobs ); - } + virtual void parallelFor(int iBegin, int iEnd, int grainSize, const btIParallelForBody& body) BT_OVERRIDE + { + BT_PROFILE("parallelFor_ThreadSupport"); + btAssert(iEnd >= iBegin); + btAssert(grainSize >= 1); + int iterationCount = iEnd - iBegin; + if (iterationCount > grainSize && m_numWorkerThreads > 0 && m_antiNestingLock.tryLock()) + { + typedef ParallelForJob JobType; + int jobCount = (iterationCount + grainSize - 1) / grainSize; + m_numJobs = jobCount; + btAssert(jobCount >= 2); // need more than one job for multithreading + int jobSize = sizeof(JobType); - virtual void parallelFor( int iBegin, int iEnd, int grainSize, const btIParallelForBody& body ) BT_OVERRIDE - { - BT_PROFILE( "parallelFor_ThreadSupport" ); - btAssert( iEnd >= iBegin ); - btAssert( grainSize >= 1 ); - int iterationCount = iEnd - iBegin; - if ( iterationCount > grainSize && m_numWorkerThreads > 0 && m_antiNestingLock.tryLock() ) - { - typedef ParallelForJob JobType; - int jobCount = ( iterationCount + grainSize - 1 ) / grainSize; - m_numJobs = jobCount; - btAssert( jobCount >= 2 ); // need more than one job for multithreading - int jobSize = sizeof( JobType ); + for (int i = 0; i < m_numActiveJobQueues; ++i) + { + m_jobQueues[i].clearQueue(jobCount, jobSize); + } + // prepare worker threads for incoming work + prepareWorkerThreads(); + // submit all of the jobs + int iJob = 0; + int iThread = kFirstWorkerThreadId; // first worker thread + for (int i = iBegin; i < iEnd; i += grainSize) + { + btAssert(iJob < jobCount); + int iE = btMin(i + grainSize, iEnd); + JobQueue* jq = m_perThreadJobQueues[iThread]; + btAssert(jq); + btAssert((jq - &m_jobQueues[0]) < m_numActiveJobQueues); + void* jobMem = jq->allocJobMem(jobSize); + JobType* job = new (jobMem) ParallelForJob(i, iE, body); // placement new + jq->submitJob(job); + iJob++; + iThread++; + if (iThread >= m_numThreads) + { + iThread = kFirstWorkerThreadId; // first worker thread + } + } + wakeWorkers(jobCount - 1); - for (int i = 0; i < m_numActiveJobQueues; ++i) - { - m_jobQueues[i].clearQueue( jobCount, jobSize ); - } - // prepare worker threads for incoming work - prepareWorkerThreads(); - // submit all of the jobs - int iJob = 0; - int iThread = kFirstWorkerThreadId; // first worker thread - for ( int i = iBegin; i < iEnd; i += grainSize ) - { - btAssert( iJob < jobCount ); - int iE = btMin( i + grainSize, iEnd ); - JobQueue* jq = m_perThreadJobQueues[ iThread ]; - btAssert(jq); - btAssert((jq - &m_jobQueues[0]) < m_numActiveJobQueues); - void* jobMem = jq->allocJobMem(jobSize); - JobType* job = new ( jobMem ) ParallelForJob( i, iE, body ); // placement new - jq->submitJob( job ); - iJob++; - iThread++; - if ( iThread >= m_numThreads ) - { - iThread = kFirstWorkerThreadId; // first worker thread - } - } - wakeWorkers( jobCount - 1 ); + // put the main thread to work on emptying the job queue and then wait for all workers to finish + waitJobs(); + m_antiNestingLock.unlock(); + } + else + { + BT_PROFILE("parallelFor_mainThread"); + // just run on main thread + body.forLoop(iBegin, iEnd); + } + } + virtual btScalar parallelSum(int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body) BT_OVERRIDE + { + BT_PROFILE("parallelSum_ThreadSupport"); + btAssert(iEnd >= iBegin); + btAssert(grainSize >= 1); + int iterationCount = iEnd - iBegin; + if (iterationCount > grainSize && m_numWorkerThreads > 0 && m_antiNestingLock.tryLock()) + { + typedef ParallelSumJob JobType; + int jobCount = (iterationCount + grainSize - 1) / grainSize; + m_numJobs = jobCount; + btAssert(jobCount >= 2); // need more than one job for multithreading + int jobSize = sizeof(JobType); + for (int i = 0; i < m_numActiveJobQueues; ++i) + { + m_jobQueues[i].clearQueue(jobCount, jobSize); + } - // put the main thread to work on emptying the job queue and then wait for all workers to finish - waitJobs(); - m_antiNestingLock.unlock(); - } - else - { - BT_PROFILE( "parallelFor_mainThread" ); - // just run on main thread - body.forLoop( iBegin, iEnd ); - } - } - virtual btScalar parallelSum( int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body ) BT_OVERRIDE - { - BT_PROFILE( "parallelSum_ThreadSupport" ); - btAssert( iEnd >= iBegin ); - btAssert( grainSize >= 1 ); - int iterationCount = iEnd - iBegin; - if ( iterationCount > grainSize && m_numWorkerThreads > 0 && m_antiNestingLock.tryLock() ) - { - typedef ParallelSumJob JobType; - int jobCount = ( iterationCount + grainSize - 1 ) / grainSize; - m_numJobs = jobCount; - btAssert( jobCount >= 2 ); // need more than one job for multithreading - int jobSize = sizeof( JobType ); - for (int i = 0; i < m_numActiveJobQueues; ++i) - { - m_jobQueues[i].clearQueue( jobCount, jobSize ); - } + // initialize summation + for (int iThread = 0; iThread < m_numThreads; ++iThread) + { + m_threadLocalStorage[iThread].m_sumResult = btScalar(0); + } - // initialize summation - for ( int iThread = 0; iThread < m_numThreads; ++iThread ) - { - m_threadLocalStorage[iThread].m_sumResult = btScalar(0); - } + // prepare worker threads for incoming work + prepareWorkerThreads(); + // submit all of the jobs + int iJob = 0; + int iThread = kFirstWorkerThreadId; // first worker thread + for (int i = iBegin; i < iEnd; i += grainSize) + { + btAssert(iJob < jobCount); + int iE = btMin(i + grainSize, iEnd); + JobQueue* jq = m_perThreadJobQueues[iThread]; + btAssert(jq); + btAssert((jq - &m_jobQueues[0]) < m_numActiveJobQueues); + void* jobMem = jq->allocJobMem(jobSize); + JobType* job = new (jobMem) ParallelSumJob(i, iE, body, &m_threadLocalStorage[0]); // placement new + jq->submitJob(job); + iJob++; + iThread++; + if (iThread >= m_numThreads) + { + iThread = kFirstWorkerThreadId; // first worker thread + } + } + wakeWorkers(jobCount - 1); - // prepare worker threads for incoming work - prepareWorkerThreads(); - // submit all of the jobs - int iJob = 0; - int iThread = kFirstWorkerThreadId; // first worker thread - for ( int i = iBegin; i < iEnd; i += grainSize ) - { - btAssert( iJob < jobCount ); - int iE = btMin( i + grainSize, iEnd ); - JobQueue* jq = m_perThreadJobQueues[ iThread ]; - btAssert(jq); - btAssert((jq - &m_jobQueues[0]) < m_numActiveJobQueues); - void* jobMem = jq->allocJobMem(jobSize); - JobType* job = new ( jobMem ) ParallelSumJob( i, iE, body, &m_threadLocalStorage[0] ); // placement new - jq->submitJob( job ); - iJob++; - iThread++; - if ( iThread >= m_numThreads ) - { - iThread = kFirstWorkerThreadId; // first worker thread - } - } - wakeWorkers( jobCount - 1 ); + // put the main thread to work on emptying the job queue and then wait for all workers to finish + waitJobs(); - // put the main thread to work on emptying the job queue and then wait for all workers to finish - waitJobs(); - - // add up all the thread sums - btScalar sum = btScalar(0); - for ( int iThread = 0; iThread < m_numThreads; ++iThread ) - { - sum += m_threadLocalStorage[ iThread ].m_sumResult; - } - m_antiNestingLock.unlock(); - return sum; - } - else - { - BT_PROFILE( "parallelSum_mainThread" ); - // just run on main thread - return body.sumLoop( iBegin, iEnd ); - } - } + // add up all the thread sums + btScalar sum = btScalar(0); + for (int iThread = 0; iThread < m_numThreads; ++iThread) + { + sum += m_threadLocalStorage[iThread].m_sumResult; + } + m_antiNestingLock.unlock(); + return sum; + } + else + { + BT_PROFILE("parallelSum_mainThread"); + // just run on main thread + return body.sumLoop(iBegin, iEnd); + } + } }; +btITaskScheduler* btCreateDefaultTaskScheduler() +{ + btTaskSchedulerDefault* ts = new btTaskSchedulerDefault(); + ts->init(); + return ts; +} +#else // #if BT_THREADSAFE btITaskScheduler* btCreateDefaultTaskScheduler() { - btTaskSchedulerDefault* ts = new btTaskSchedulerDefault(); - ts->init(); - return ts; + return NULL; } -#else // #if BT_THREADSAFE - -btITaskScheduler* btCreateDefaultTaskScheduler() -{ - return NULL; -} - -#endif // #else // #if BT_THREADSAFE +#endif // #else // #if BT_THREADSAFE diff --git a/src/LinearMath/TaskScheduler/btThreadSupportInterface.h b/src/LinearMath/TaskScheduler/btThreadSupportInterface.h index a0ad802b1..1fe49335a 100644 --- a/src/LinearMath/TaskScheduler/btThreadSupportInterface.h +++ b/src/LinearMath/TaskScheduler/btThreadSupportInterface.h @@ -16,55 +16,49 @@ subject to the following restrictions: #ifndef BT_THREAD_SUPPORT_INTERFACE_H #define BT_THREAD_SUPPORT_INTERFACE_H - - class btCriticalSection { public: - btCriticalSection() {} - virtual ~btCriticalSection() {} + btCriticalSection() {} + virtual ~btCriticalSection() {} - virtual void lock() = 0; - virtual void unlock() = 0; + virtual void lock() = 0; + virtual void unlock() = 0; }; - class btThreadSupportInterface { public: + virtual ~btThreadSupportInterface() {} - virtual ~btThreadSupportInterface() {} + virtual int getNumWorkerThreads() const = 0; // number of worker threads (total number of logical processors - 1) + virtual int getCacheFriendlyNumThreads() const = 0; // the number of logical processors sharing a single L3 cache + virtual int getLogicalToPhysicalCoreRatio() const = 0; // the number of logical processors per physical processor (usually 1 or 2) + virtual void runTask(int threadIndex, void* userData) = 0; + virtual void waitForAllTasks() = 0; - virtual int getNumWorkerThreads() const = 0; // number of worker threads (total number of logical processors - 1) - virtual int getCacheFriendlyNumThreads() const = 0; // the number of logical processors sharing a single L3 cache - virtual int getLogicalToPhysicalCoreRatio() const = 0; // the number of logical processors per physical processor (usually 1 or 2) - virtual void runTask( int threadIndex, void* userData ) = 0; - virtual void waitForAllTasks() = 0; + virtual btCriticalSection* createCriticalSection() = 0; + virtual void deleteCriticalSection(btCriticalSection* criticalSection) = 0; - virtual btCriticalSection* createCriticalSection() = 0; - virtual void deleteCriticalSection( btCriticalSection* criticalSection ) = 0; + typedef void (*ThreadFunc)(void* userPtr); - typedef void( *ThreadFunc )( void* userPtr ); + struct ConstructionInfo + { + ConstructionInfo(const char* uniqueName, + ThreadFunc userThreadFunc, + int threadStackSize = 65535) + : m_uniqueName(uniqueName), + m_userThreadFunc(userThreadFunc), + m_threadStackSize(threadStackSize) + { + } - struct ConstructionInfo - { - ConstructionInfo( const char* uniqueName, - ThreadFunc userThreadFunc, - int threadStackSize = 65535 - ) - :m_uniqueName( uniqueName ), - m_userThreadFunc( userThreadFunc ), - m_threadStackSize( threadStackSize ) - { - } + const char* m_uniqueName; + ThreadFunc m_userThreadFunc; + int m_threadStackSize; + }; - const char* m_uniqueName; - ThreadFunc m_userThreadFunc; - int m_threadStackSize; - }; - - static btThreadSupportInterface* create( const ConstructionInfo& info ); + static btThreadSupportInterface* create(const ConstructionInfo& info); }; -#endif //BT_THREAD_SUPPORT_INTERFACE_H - +#endif //BT_THREAD_SUPPORT_INTERFACE_H diff --git a/src/LinearMath/TaskScheduler/btThreadSupportPosix.cpp b/src/LinearMath/TaskScheduler/btThreadSupportPosix.cpp index 50ca060df..47f57943b 100644 --- a/src/LinearMath/TaskScheduler/btThreadSupportPosix.cpp +++ b/src/LinearMath/TaskScheduler/btThreadSupportPosix.cpp @@ -13,9 +13,7 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - -#if BT_THREADSAFE && !defined( _WIN32 ) - +#if BT_THREADSAFE && !defined(_WIN32) #include "LinearMath/btScalar.h" #include "LinearMath/btAlignedObjectArray.h" @@ -27,14 +25,12 @@ subject to the following restrictions: #include #include - #ifndef _XOPEN_SOURCE -#define _XOPEN_SOURCE 600 //for definition of pthread_barrier_t, see http://pages.cs.wisc.edu/~travitch/pthreads_primer.html -#endif //_XOPEN_SOURCE +#define _XOPEN_SOURCE 600 //for definition of pthread_barrier_t, see http://pages.cs.wisc.edu/~travitch/pthreads_primer.html +#endif //_XOPEN_SOURCE #include #include -#include //for sysconf - +#include //for sysconf /// /// getNumHardwareThreads() @@ -48,318 +44,309 @@ subject to the following restrictions: int btGetNumHardwareThreads() { - return btMin(BT_MAX_THREAD_COUNT, std::thread::hardware_concurrency()); + return btMin(BT_MAX_THREAD_COUNT, std::thread::hardware_concurrency()); } #else int btGetNumHardwareThreads() { - return btMin(BT_MAX_THREAD_COUNT, sysconf( _SC_NPROCESSORS_ONLN )); + return btMin(BT_MAX_THREAD_COUNT, sysconf(_SC_NPROCESSORS_ONLN)); } #endif - // btThreadSupportPosix helps to initialize/shutdown libspe2, start/stop SPU tasks and communication class btThreadSupportPosix : public btThreadSupportInterface { public: - struct btThreadStatus - { - int m_taskId; - int m_commandId; - int m_status; + struct btThreadStatus + { + int m_taskId; + int m_commandId; + int m_status; - ThreadFunc m_userThreadFunc; - void* m_userPtr; //for taskDesc etc + ThreadFunc m_userThreadFunc; + void* m_userPtr; //for taskDesc etc - pthread_t thread; - //each tread will wait until this signal to start its work - sem_t* startSemaphore; + pthread_t thread; + //each tread will wait until this signal to start its work + sem_t* startSemaphore; + + // this is a copy of m_mainSemaphore, + //each tread will signal once it is finished with its work + sem_t* m_mainSemaphore; + unsigned long threadUsed; + }; - // this is a copy of m_mainSemaphore, - //each tread will signal once it is finished with its work - sem_t* m_mainSemaphore; - unsigned long threadUsed; - }; private: - typedef unsigned long long UINT64; + typedef unsigned long long UINT64; - btAlignedObjectArray m_activeThreadStatus; - // m_mainSemaphoresemaphore will signal, if and how many threads are finished with their work - sem_t* m_mainSemaphore; - int m_numThreads; - UINT64 m_startedThreadsMask; - void startThreads( const ConstructionInfo& threadInfo ); - void stopThreads(); - int waitForResponse(); + btAlignedObjectArray m_activeThreadStatus; + // m_mainSemaphoresemaphore will signal, if and how many threads are finished with their work + sem_t* m_mainSemaphore; + int m_numThreads; + UINT64 m_startedThreadsMask; + void startThreads(const ConstructionInfo& threadInfo); + void stopThreads(); + int waitForResponse(); public: - btThreadSupportPosix( const ConstructionInfo& threadConstructionInfo ); - virtual ~btThreadSupportPosix(); + btThreadSupportPosix(const ConstructionInfo& threadConstructionInfo); + virtual ~btThreadSupportPosix(); - virtual int getNumWorkerThreads() const BT_OVERRIDE { return m_numThreads; } - // TODO: return the number of logical processors sharing the first L3 cache - virtual int getCacheFriendlyNumThreads() const BT_OVERRIDE { return m_numThreads + 1; } - // TODO: detect if CPU has hyperthreading enabled - virtual int getLogicalToPhysicalCoreRatio() const BT_OVERRIDE { return 1; } + virtual int getNumWorkerThreads() const BT_OVERRIDE { return m_numThreads; } + // TODO: return the number of logical processors sharing the first L3 cache + virtual int getCacheFriendlyNumThreads() const BT_OVERRIDE { return m_numThreads + 1; } + // TODO: detect if CPU has hyperthreading enabled + virtual int getLogicalToPhysicalCoreRatio() const BT_OVERRIDE { return 1; } - virtual void runTask( int threadIndex, void* userData ) BT_OVERRIDE; - virtual void waitForAllTasks() BT_OVERRIDE; + virtual void runTask(int threadIndex, void* userData) BT_OVERRIDE; + virtual void waitForAllTasks() BT_OVERRIDE; - virtual btCriticalSection* createCriticalSection() BT_OVERRIDE; - virtual void deleteCriticalSection( btCriticalSection* criticalSection ) BT_OVERRIDE; + virtual btCriticalSection* createCriticalSection() BT_OVERRIDE; + virtual void deleteCriticalSection(btCriticalSection* criticalSection) BT_OVERRIDE; }; - -#define checkPThreadFunction(returnValue) \ - if(0 != returnValue) { \ - printf("PThread problem at line %i in file %s: %i %d\n", __LINE__, __FILE__, returnValue, errno); \ - } +#define checkPThreadFunction(returnValue) \ + if (0 != returnValue) \ + { \ + printf("PThread problem at line %i in file %s: %i %d\n", __LINE__, __FILE__, returnValue, errno); \ + } // The number of threads should be equal to the number of available cores // Todo: each worker should be linked to a single core, using SetThreadIdealProcessor. - -btThreadSupportPosix::btThreadSupportPosix( const ConstructionInfo& threadConstructionInfo ) +btThreadSupportPosix::btThreadSupportPosix(const ConstructionInfo& threadConstructionInfo) { - startThreads( threadConstructionInfo ); + startThreads(threadConstructionInfo); } // cleanup/shutdown Libspe2 btThreadSupportPosix::~btThreadSupportPosix() { - stopThreads(); + stopThreads(); } -#if (defined (__APPLE__)) +#if (defined(__APPLE__)) #define NAMED_SEMAPHORES #endif - -static sem_t* createSem( const char* baseName ) +static sem_t* createSem(const char* baseName) { - static int semCount = 0; + static int semCount = 0; #ifdef NAMED_SEMAPHORES - /// Named semaphore begin - char name[ 32 ]; - snprintf( name, 32, "/%8.s-%4.d-%4.4d", baseName, getpid(), semCount++ ); - sem_t* tempSem = sem_open( name, O_CREAT, 0600, 0 ); + /// Named semaphore begin + char name[32]; + snprintf(name, 32, "/%8.s-%4.d-%4.4d", baseName, getpid(), semCount++); + sem_t* tempSem = sem_open(name, O_CREAT, 0600, 0); - if ( tempSem != reinterpret_cast( SEM_FAILED ) ) - { - // printf("Created \"%s\" Semaphore %p\n", name, tempSem); - } - else - { - //printf("Error creating Semaphore %d\n", errno); - exit( -1 ); - } - /// Named semaphore end + if (tempSem != reinterpret_cast(SEM_FAILED)) + { + // printf("Created \"%s\" Semaphore %p\n", name, tempSem); + } + else + { + //printf("Error creating Semaphore %d\n", errno); + exit(-1); + } + /// Named semaphore end #else - sem_t* tempSem = new sem_t; - checkPThreadFunction( sem_init( tempSem, 0, 0 ) ); + sem_t* tempSem = new sem_t; + checkPThreadFunction(sem_init(tempSem, 0, 0)); #endif - return tempSem; + return tempSem; } -static void destroySem( sem_t* semaphore ) +static void destroySem(sem_t* semaphore) { #ifdef NAMED_SEMAPHORES - checkPThreadFunction( sem_close( semaphore ) ); + checkPThreadFunction(sem_close(semaphore)); #else - checkPThreadFunction( sem_destroy( semaphore ) ); - delete semaphore; + checkPThreadFunction(sem_destroy(semaphore)); + delete semaphore; #endif } -static void *threadFunction( void *argument ) +static void* threadFunction(void* argument) { - btThreadSupportPosix::btThreadStatus* status = ( btThreadSupportPosix::btThreadStatus* )argument; + btThreadSupportPosix::btThreadStatus* status = (btThreadSupportPosix::btThreadStatus*)argument; - while ( 1 ) - { - checkPThreadFunction( sem_wait( status->startSemaphore ) ); - void* userPtr = status->m_userPtr; + while (1) + { + checkPThreadFunction(sem_wait(status->startSemaphore)); + void* userPtr = status->m_userPtr; - if ( userPtr ) - { - btAssert( status->m_status ); - status->m_userThreadFunc( userPtr ); - status->m_status = 2; - checkPThreadFunction( sem_post( status->m_mainSemaphore ) ); - status->threadUsed++; - } - else - { - //exit Thread - status->m_status = 3; - checkPThreadFunction( sem_post( status->m_mainSemaphore ) ); - printf( "Thread with taskId %i exiting\n", status->m_taskId ); - break; - } - } + if (userPtr) + { + btAssert(status->m_status); + status->m_userThreadFunc(userPtr); + status->m_status = 2; + checkPThreadFunction(sem_post(status->m_mainSemaphore)); + status->threadUsed++; + } + else + { + //exit Thread + status->m_status = 3; + checkPThreadFunction(sem_post(status->m_mainSemaphore)); + printf("Thread with taskId %i exiting\n", status->m_taskId); + break; + } + } - printf( "Thread TERMINATED\n" ); - return 0; + printf("Thread TERMINATED\n"); + return 0; } ///send messages to SPUs -void btThreadSupportPosix::runTask( int threadIndex, void* userData ) +void btThreadSupportPosix::runTask(int threadIndex, void* userData) { - ///we should spawn an SPU task here, and in 'waitForResponse' it should wait for response of the (one of) the first tasks that finished - btThreadStatus& threadStatus = m_activeThreadStatus[ threadIndex ]; - btAssert( threadIndex >= 0 ); - btAssert( threadIndex < m_activeThreadStatus.size() ); + ///we should spawn an SPU task here, and in 'waitForResponse' it should wait for response of the (one of) the first tasks that finished + btThreadStatus& threadStatus = m_activeThreadStatus[threadIndex]; + btAssert(threadIndex >= 0); + btAssert(threadIndex < m_activeThreadStatus.size()); - threadStatus.m_commandId = 1; - threadStatus.m_status = 1; - threadStatus.m_userPtr = userData; - m_startedThreadsMask |= UINT64( 1 ) << threadIndex; + threadStatus.m_commandId = 1; + threadStatus.m_status = 1; + threadStatus.m_userPtr = userData; + m_startedThreadsMask |= UINT64(1) << threadIndex; - // fire event to start new task - checkPThreadFunction( sem_post( threadStatus.startSemaphore ) ); + // fire event to start new task + checkPThreadFunction(sem_post(threadStatus.startSemaphore)); } - ///check for messages from SPUs int btThreadSupportPosix::waitForResponse() { - ///We should wait for (one of) the first tasks to finish (or other SPU messages), and report its response - ///A possible response can be 'yes, SPU handled it', or 'no, please do a PPU fallback' + ///We should wait for (one of) the first tasks to finish (or other SPU messages), and report its response + ///A possible response can be 'yes, SPU handled it', or 'no, please do a PPU fallback' - btAssert( m_activeThreadStatus.size() ); + btAssert(m_activeThreadStatus.size()); - // wait for any of the threads to finish - checkPThreadFunction( sem_wait( m_mainSemaphore ) ); - // get at least one thread which has finished - size_t last = -1; + // wait for any of the threads to finish + checkPThreadFunction(sem_wait(m_mainSemaphore)); + // get at least one thread which has finished + size_t last = -1; - for ( size_t t = 0; t < size_t( m_activeThreadStatus.size() ); ++t ) - { - if ( 2 == m_activeThreadStatus[ t ].m_status ) - { - last = t; - break; - } - } + for (size_t t = 0; t < size_t(m_activeThreadStatus.size()); ++t) + { + if (2 == m_activeThreadStatus[t].m_status) + { + last = t; + break; + } + } - btThreadStatus& threadStatus = m_activeThreadStatus[ last ]; + btThreadStatus& threadStatus = m_activeThreadStatus[last]; - btAssert( threadStatus.m_status > 1 ); - threadStatus.m_status = 0; + btAssert(threadStatus.m_status > 1); + threadStatus.m_status = 0; - // need to find an active spu - btAssert( last >= 0 ); - m_startedThreadsMask &= ~( UINT64( 1 ) << last ); + // need to find an active spu + btAssert(last >= 0); + m_startedThreadsMask &= ~(UINT64(1) << last); - return last; + return last; } - void btThreadSupportPosix::waitForAllTasks() { - while ( m_startedThreadsMask ) - { - waitForResponse(); - } + while (m_startedThreadsMask) + { + waitForResponse(); + } } - -void btThreadSupportPosix::startThreads( const ConstructionInfo& threadConstructionInfo ) +void btThreadSupportPosix::startThreads(const ConstructionInfo& threadConstructionInfo) { - m_numThreads = btGetNumHardwareThreads() - 1; // main thread exists already - printf( "%s creating %i threads.\n", __FUNCTION__, m_numThreads ); - m_activeThreadStatus.resize( m_numThreads ); - m_startedThreadsMask = 0; + m_numThreads = btGetNumHardwareThreads() - 1; // main thread exists already + printf("%s creating %i threads.\n", __FUNCTION__, m_numThreads); + m_activeThreadStatus.resize(m_numThreads); + m_startedThreadsMask = 0; - m_mainSemaphore = createSem( "main" ); - //checkPThreadFunction(sem_wait(mainSemaphore)); + m_mainSemaphore = createSem("main"); + //checkPThreadFunction(sem_wait(mainSemaphore)); - for ( int i = 0; i < m_numThreads; i++ ) - { - printf( "starting thread %d\n", i ); - btThreadStatus& threadStatus = m_activeThreadStatus[ i ]; - threadStatus.startSemaphore = createSem( "threadLocal" ); - checkPThreadFunction( pthread_create( &threadStatus.thread, NULL, &threadFunction, (void*) &threadStatus ) ); + for (int i = 0; i < m_numThreads; i++) + { + printf("starting thread %d\n", i); + btThreadStatus& threadStatus = m_activeThreadStatus[i]; + threadStatus.startSemaphore = createSem("threadLocal"); + checkPThreadFunction(pthread_create(&threadStatus.thread, NULL, &threadFunction, (void*)&threadStatus)); - threadStatus.m_userPtr = 0; - threadStatus.m_taskId = i; - threadStatus.m_commandId = 0; - threadStatus.m_status = 0; - threadStatus.m_mainSemaphore = m_mainSemaphore; - threadStatus.m_userThreadFunc = threadConstructionInfo.m_userThreadFunc; - threadStatus.threadUsed = 0; + threadStatus.m_userPtr = 0; + threadStatus.m_taskId = i; + threadStatus.m_commandId = 0; + threadStatus.m_status = 0; + threadStatus.m_mainSemaphore = m_mainSemaphore; + threadStatus.m_userThreadFunc = threadConstructionInfo.m_userThreadFunc; + threadStatus.threadUsed = 0; - printf( "started thread %d \n", i ); - } + printf("started thread %d \n", i); + } } ///tell the task scheduler we are done with the SPU tasks void btThreadSupportPosix::stopThreads() { - for ( size_t t = 0; t < size_t( m_activeThreadStatus.size() ); ++t ) - { - btThreadStatus& threadStatus = m_activeThreadStatus[ t ]; - printf( "%s: Thread %i used: %ld\n", __FUNCTION__, int( t ), threadStatus.threadUsed ); + for (size_t t = 0; t < size_t(m_activeThreadStatus.size()); ++t) + { + btThreadStatus& threadStatus = m_activeThreadStatus[t]; + printf("%s: Thread %i used: %ld\n", __FUNCTION__, int(t), threadStatus.threadUsed); - threadStatus.m_userPtr = 0; - checkPThreadFunction( sem_post( threadStatus.startSemaphore ) ); - checkPThreadFunction( sem_wait( m_mainSemaphore ) ); + threadStatus.m_userPtr = 0; + checkPThreadFunction(sem_post(threadStatus.startSemaphore)); + checkPThreadFunction(sem_wait(m_mainSemaphore)); - printf( "destroy semaphore\n" ); - destroySem( threadStatus.startSemaphore ); - printf( "semaphore destroyed\n" ); - checkPThreadFunction( pthread_join( threadStatus.thread, 0 ) ); - - } - printf( "destroy main semaphore\n" ); - destroySem( m_mainSemaphore ); - printf( "main semaphore destroyed\n" ); - m_activeThreadStatus.clear(); + printf("destroy semaphore\n"); + destroySem(threadStatus.startSemaphore); + printf("semaphore destroyed\n"); + checkPThreadFunction(pthread_join(threadStatus.thread, 0)); + } + printf("destroy main semaphore\n"); + destroySem(m_mainSemaphore); + printf("main semaphore destroyed\n"); + m_activeThreadStatus.clear(); } class btCriticalSectionPosix : public btCriticalSection { - pthread_mutex_t m_mutex; + pthread_mutex_t m_mutex; public: - btCriticalSectionPosix() - { - pthread_mutex_init( &m_mutex, NULL ); - } - virtual ~btCriticalSectionPosix() - { - pthread_mutex_destroy( &m_mutex ); - } + btCriticalSectionPosix() + { + pthread_mutex_init(&m_mutex, NULL); + } + virtual ~btCriticalSectionPosix() + { + pthread_mutex_destroy(&m_mutex); + } - virtual void lock() - { - pthread_mutex_lock( &m_mutex ); - } - virtual void unlock() - { - pthread_mutex_unlock( &m_mutex ); - } + virtual void lock() + { + pthread_mutex_lock(&m_mutex); + } + virtual void unlock() + { + pthread_mutex_unlock(&m_mutex); + } }; - btCriticalSection* btThreadSupportPosix::createCriticalSection() { - return new btCriticalSectionPosix(); + return new btCriticalSectionPosix(); } -void btThreadSupportPosix::deleteCriticalSection( btCriticalSection* cs ) +void btThreadSupportPosix::deleteCriticalSection(btCriticalSection* cs) { - delete cs; + delete cs; } - -btThreadSupportInterface* btThreadSupportInterface::create( const ConstructionInfo& info ) +btThreadSupportInterface* btThreadSupportInterface::create(const ConstructionInfo& info) { - return new btThreadSupportPosix( info ); + return new btThreadSupportPosix(info); } -#endif // BT_THREADSAFE && !defined( _WIN32 ) - +#endif // BT_THREADSAFE && !defined( _WIN32 ) diff --git a/src/LinearMath/TaskScheduler/btThreadSupportWin32.cpp b/src/LinearMath/TaskScheduler/btThreadSupportWin32.cpp index 00edac650..922e449cc 100644 --- a/src/LinearMath/TaskScheduler/btThreadSupportWin32.cpp +++ b/src/LinearMath/TaskScheduler/btThreadSupportWin32.cpp @@ -13,7 +13,7 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ -#if defined( _WIN32 ) && BT_THREADSAFE +#if defined(_WIN32) && BT_THREADSAFE #include "LinearMath/btScalar.h" #include "LinearMath/btMinMax.h" @@ -23,450 +23,430 @@ subject to the following restrictions: #include #include - struct btProcessorInfo { - int numLogicalProcessors; - int numCores; - int numNumaNodes; - int numL1Cache; - int numL2Cache; - int numL3Cache; - int numPhysicalPackages; - static const int maxNumTeamMasks = 32; - int numTeamMasks; - UINT64 processorTeamMasks[ maxNumTeamMasks ]; + int numLogicalProcessors; + int numCores; + int numNumaNodes; + int numL1Cache; + int numL2Cache; + int numL3Cache; + int numPhysicalPackages; + static const int maxNumTeamMasks = 32; + int numTeamMasks; + UINT64 processorTeamMasks[maxNumTeamMasks]; }; -UINT64 getProcessorTeamMask( const btProcessorInfo& procInfo, int procId ) +UINT64 getProcessorTeamMask(const btProcessorInfo& procInfo, int procId) { - UINT64 procMask = UINT64( 1 ) << procId; - for ( int i = 0; i < procInfo.numTeamMasks; ++i ) - { - if ( procMask & procInfo.processorTeamMasks[ i ] ) - { - return procInfo.processorTeamMasks[ i ]; - } - } - return 0; + UINT64 procMask = UINT64(1) << procId; + for (int i = 0; i < procInfo.numTeamMasks; ++i) + { + if (procMask & procInfo.processorTeamMasks[i]) + { + return procInfo.processorTeamMasks[i]; + } + } + return 0; } -int getProcessorTeamIndex( const btProcessorInfo& procInfo, int procId ) +int getProcessorTeamIndex(const btProcessorInfo& procInfo, int procId) { - UINT64 procMask = UINT64( 1 ) << procId; - for ( int i = 0; i < procInfo.numTeamMasks; ++i ) - { - if ( procMask & procInfo.processorTeamMasks[ i ] ) - { - return i; - } - } - return -1; + UINT64 procMask = UINT64(1) << procId; + for (int i = 0; i < procInfo.numTeamMasks; ++i) + { + if (procMask & procInfo.processorTeamMasks[i]) + { + return i; + } + } + return -1; } -int countSetBits( ULONG64 bits ) +int countSetBits(ULONG64 bits) { - int count = 0; - while ( bits ) - { - if ( bits & 1 ) - { - count++; - } - bits >>= 1; - } - return count; + int count = 0; + while (bits) + { + if (bits & 1) + { + count++; + } + bits >>= 1; + } + return count; } +typedef BOOL(WINAPI* Pfn_GetLogicalProcessorInformation)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD); -typedef BOOL( WINAPI *Pfn_GetLogicalProcessorInformation )( PSYSTEM_LOGICAL_PROCESSOR_INFORMATION, PDWORD ); - - -void getProcessorInformation( btProcessorInfo* procInfo ) +void getProcessorInformation(btProcessorInfo* procInfo) { - memset( procInfo, 0, sizeof( *procInfo ) ); - Pfn_GetLogicalProcessorInformation getLogicalProcInfo = - (Pfn_GetLogicalProcessorInformation) GetProcAddress( GetModuleHandle( TEXT( "kernel32" ) ), "GetLogicalProcessorInformation" ); - if ( getLogicalProcInfo == NULL ) - { - // no info - return; - } - PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buf = NULL; - DWORD bufSize = 0; - while ( true ) - { - if ( getLogicalProcInfo( buf, &bufSize ) ) - { - break; - } - else - { - if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER ) - { - if ( buf ) - { - free( buf ); - } - buf = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION) malloc( bufSize ); - } - } - } + memset(procInfo, 0, sizeof(*procInfo)); + Pfn_GetLogicalProcessorInformation getLogicalProcInfo = + (Pfn_GetLogicalProcessorInformation)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "GetLogicalProcessorInformation"); + if (getLogicalProcInfo == NULL) + { + // no info + return; + } + PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buf = NULL; + DWORD bufSize = 0; + while (true) + { + if (getLogicalProcInfo(buf, &bufSize)) + { + break; + } + else + { + if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + if (buf) + { + free(buf); + } + buf = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)malloc(bufSize); + } + } + } - int len = bufSize / sizeof( *buf ); - for ( int i = 0; i < len; ++i ) - { - PSYSTEM_LOGICAL_PROCESSOR_INFORMATION info = buf + i; - switch ( info->Relationship ) - { - case RelationNumaNode: - procInfo->numNumaNodes++; - break; + int len = bufSize / sizeof(*buf); + for (int i = 0; i < len; ++i) + { + PSYSTEM_LOGICAL_PROCESSOR_INFORMATION info = buf + i; + switch (info->Relationship) + { + case RelationNumaNode: + procInfo->numNumaNodes++; + break; - case RelationProcessorCore: - procInfo->numCores++; - procInfo->numLogicalProcessors += countSetBits( info->ProcessorMask ); - break; + case RelationProcessorCore: + procInfo->numCores++; + procInfo->numLogicalProcessors += countSetBits(info->ProcessorMask); + break; - case RelationCache: - if ( info->Cache.Level == 1 ) - { - procInfo->numL1Cache++; - } - else if ( info->Cache.Level == 2 ) - { - procInfo->numL2Cache++; - } - else if ( info->Cache.Level == 3 ) - { - procInfo->numL3Cache++; - // processors that share L3 cache are considered to be on the same team - // because they can more easily work together on the same data. - // Large performance penalties will occur if 2 or more threads from different - // teams attempt to frequently read and modify the same cache lines. - // - // On the AMD Ryzen 7 CPU for example, the 8 cores on the CPU are split into - // 2 CCX units of 4 cores each. Each CCX has a separate L3 cache, so if both - // CCXs are operating on the same data, many cycles will be spent keeping the - // two caches coherent. - if ( procInfo->numTeamMasks < btProcessorInfo::maxNumTeamMasks ) - { - procInfo->processorTeamMasks[ procInfo->numTeamMasks ] = info->ProcessorMask; - procInfo->numTeamMasks++; - } - } - break; + case RelationCache: + if (info->Cache.Level == 1) + { + procInfo->numL1Cache++; + } + else if (info->Cache.Level == 2) + { + procInfo->numL2Cache++; + } + else if (info->Cache.Level == 3) + { + procInfo->numL3Cache++; + // processors that share L3 cache are considered to be on the same team + // because they can more easily work together on the same data. + // Large performance penalties will occur if 2 or more threads from different + // teams attempt to frequently read and modify the same cache lines. + // + // On the AMD Ryzen 7 CPU for example, the 8 cores on the CPU are split into + // 2 CCX units of 4 cores each. Each CCX has a separate L3 cache, so if both + // CCXs are operating on the same data, many cycles will be spent keeping the + // two caches coherent. + if (procInfo->numTeamMasks < btProcessorInfo::maxNumTeamMasks) + { + procInfo->processorTeamMasks[procInfo->numTeamMasks] = info->ProcessorMask; + procInfo->numTeamMasks++; + } + } + break; - case RelationProcessorPackage: - procInfo->numPhysicalPackages++; - break; - } - } - free( buf ); + case RelationProcessorPackage: + procInfo->numPhysicalPackages++; + break; + } + } + free(buf); } - - ///btThreadSupportWin32 helps to initialize/shutdown libspe2, start/stop SPU tasks and communication class btThreadSupportWin32 : public btThreadSupportInterface { public: - struct btThreadStatus - { - int m_taskId; - int m_commandId; - int m_status; + struct btThreadStatus + { + int m_taskId; + int m_commandId; + int m_status; - ThreadFunc m_userThreadFunc; - void* m_userPtr; //for taskDesc etc + ThreadFunc m_userThreadFunc; + void* m_userPtr; //for taskDesc etc - void* m_threadHandle; //this one is calling 'Win32ThreadFunc' + void* m_threadHandle; //this one is calling 'Win32ThreadFunc' - void* m_eventStartHandle; - char m_eventStartHandleName[ 32 ]; + void* m_eventStartHandle; + char m_eventStartHandleName[32]; - void* m_eventCompleteHandle; - char m_eventCompleteHandleName[ 32 ]; - }; + void* m_eventCompleteHandle; + char m_eventCompleteHandleName[32]; + }; private: - btAlignedObjectArray m_activeThreadStatus; - btAlignedObjectArray m_completeHandles; - int m_numThreads; - DWORD_PTR m_startedThreadMask; - btProcessorInfo m_processorInfo; + btAlignedObjectArray m_activeThreadStatus; + btAlignedObjectArray m_completeHandles; + int m_numThreads; + DWORD_PTR m_startedThreadMask; + btProcessorInfo m_processorInfo; - void startThreads( const ConstructionInfo& threadInfo ); - void stopThreads(); - int waitForResponse(); + void startThreads(const ConstructionInfo& threadInfo); + void stopThreads(); + int waitForResponse(); public: + btThreadSupportWin32(const ConstructionInfo& threadConstructionInfo); + virtual ~btThreadSupportWin32(); - btThreadSupportWin32( const ConstructionInfo& threadConstructionInfo ); - virtual ~btThreadSupportWin32(); + virtual int getNumWorkerThreads() const BT_OVERRIDE { return m_numThreads; } + virtual int getCacheFriendlyNumThreads() const BT_OVERRIDE { return countSetBits(m_processorInfo.processorTeamMasks[0]); } + virtual int getLogicalToPhysicalCoreRatio() const BT_OVERRIDE { return m_processorInfo.numLogicalProcessors / m_processorInfo.numCores; } - virtual int getNumWorkerThreads() const BT_OVERRIDE { return m_numThreads; } - virtual int getCacheFriendlyNumThreads() const BT_OVERRIDE { return countSetBits(m_processorInfo.processorTeamMasks[0]); } - virtual int getLogicalToPhysicalCoreRatio() const BT_OVERRIDE { return m_processorInfo.numLogicalProcessors / m_processorInfo.numCores; } + virtual void runTask(int threadIndex, void* userData) BT_OVERRIDE; + virtual void waitForAllTasks() BT_OVERRIDE; - virtual void runTask( int threadIndex, void* userData ) BT_OVERRIDE; - virtual void waitForAllTasks() BT_OVERRIDE; - - virtual btCriticalSection* createCriticalSection() BT_OVERRIDE; - virtual void deleteCriticalSection( btCriticalSection* criticalSection ) BT_OVERRIDE; + virtual btCriticalSection* createCriticalSection() BT_OVERRIDE; + virtual void deleteCriticalSection(btCriticalSection* criticalSection) BT_OVERRIDE; }; - -btThreadSupportWin32::btThreadSupportWin32( const ConstructionInfo & threadConstructionInfo ) +btThreadSupportWin32::btThreadSupportWin32(const ConstructionInfo& threadConstructionInfo) { - startThreads( threadConstructionInfo ); + startThreads(threadConstructionInfo); } - btThreadSupportWin32::~btThreadSupportWin32() { - stopThreads(); + stopThreads(); } - -DWORD WINAPI win32threadStartFunc( LPVOID lpParam ) +DWORD WINAPI win32threadStartFunc(LPVOID lpParam) { - btThreadSupportWin32::btThreadStatus* status = ( btThreadSupportWin32::btThreadStatus* )lpParam; + btThreadSupportWin32::btThreadStatus* status = (btThreadSupportWin32::btThreadStatus*)lpParam; - while ( 1 ) - { - WaitForSingleObject( status->m_eventStartHandle, INFINITE ); - void* userPtr = status->m_userPtr; + while (1) + { + WaitForSingleObject(status->m_eventStartHandle, INFINITE); + void* userPtr = status->m_userPtr; - if ( userPtr ) - { - btAssert( status->m_status ); - status->m_userThreadFunc( userPtr ); - status->m_status = 2; - SetEvent( status->m_eventCompleteHandle ); - } - else - { - //exit Thread - status->m_status = 3; - printf( "Thread with taskId %i with handle %p exiting\n", status->m_taskId, status->m_threadHandle ); - SetEvent( status->m_eventCompleteHandle ); - break; - } - } - printf( "Thread TERMINATED\n" ); - return 0; + if (userPtr) + { + btAssert(status->m_status); + status->m_userThreadFunc(userPtr); + status->m_status = 2; + SetEvent(status->m_eventCompleteHandle); + } + else + { + //exit Thread + status->m_status = 3; + printf("Thread with taskId %i with handle %p exiting\n", status->m_taskId, status->m_threadHandle); + SetEvent(status->m_eventCompleteHandle); + break; + } + } + printf("Thread TERMINATED\n"); + return 0; } - -void btThreadSupportWin32::runTask( int threadIndex, void* userData ) +void btThreadSupportWin32::runTask(int threadIndex, void* userData) { - btThreadStatus& threadStatus = m_activeThreadStatus[ threadIndex ]; - btAssert( threadIndex >= 0 ); - btAssert( int( threadIndex ) < m_activeThreadStatus.size() ); + btThreadStatus& threadStatus = m_activeThreadStatus[threadIndex]; + btAssert(threadIndex >= 0); + btAssert(int(threadIndex) < m_activeThreadStatus.size()); - threadStatus.m_commandId = 1; - threadStatus.m_status = 1; - threadStatus.m_userPtr = userData; - m_startedThreadMask |= DWORD_PTR( 1 ) << threadIndex; + threadStatus.m_commandId = 1; + threadStatus.m_status = 1; + threadStatus.m_userPtr = userData; + m_startedThreadMask |= DWORD_PTR(1) << threadIndex; - ///fire event to start new task - SetEvent( threadStatus.m_eventStartHandle ); + ///fire event to start new task + SetEvent(threadStatus.m_eventStartHandle); } - int btThreadSupportWin32::waitForResponse() { - btAssert( m_activeThreadStatus.size() ); + btAssert(m_activeThreadStatus.size()); - int last = -1; - DWORD res = WaitForMultipleObjects( m_completeHandles.size(), &m_completeHandles[ 0 ], FALSE, INFINITE ); - btAssert( res != WAIT_FAILED ); - last = res - WAIT_OBJECT_0; + int last = -1; + DWORD res = WaitForMultipleObjects(m_completeHandles.size(), &m_completeHandles[0], FALSE, INFINITE); + btAssert(res != WAIT_FAILED); + last = res - WAIT_OBJECT_0; - btThreadStatus& threadStatus = m_activeThreadStatus[ last ]; - btAssert( threadStatus.m_threadHandle ); - btAssert( threadStatus.m_eventCompleteHandle ); + btThreadStatus& threadStatus = m_activeThreadStatus[last]; + btAssert(threadStatus.m_threadHandle); + btAssert(threadStatus.m_eventCompleteHandle); - //WaitForSingleObject(threadStatus.m_eventCompleteHandle, INFINITE); - btAssert( threadStatus.m_status > 1 ); - threadStatus.m_status = 0; + //WaitForSingleObject(threadStatus.m_eventCompleteHandle, INFINITE); + btAssert(threadStatus.m_status > 1); + threadStatus.m_status = 0; - ///need to find an active spu - btAssert( last >= 0 ); - m_startedThreadMask &= ~( DWORD_PTR( 1 ) << last ); + ///need to find an active spu + btAssert(last >= 0); + m_startedThreadMask &= ~(DWORD_PTR(1) << last); - return last; + return last; } - void btThreadSupportWin32::waitForAllTasks() { - while ( m_startedThreadMask ) - { - waitForResponse(); - } + while (m_startedThreadMask) + { + waitForResponse(); + } } - -void btThreadSupportWin32::startThreads( const ConstructionInfo& threadConstructionInfo ) +void btThreadSupportWin32::startThreads(const ConstructionInfo& threadConstructionInfo) { - static int uniqueId = 0; - uniqueId++; - btProcessorInfo& procInfo = m_processorInfo; - getProcessorInformation( &procInfo ); - DWORD_PTR dwProcessAffinityMask = 0; - DWORD_PTR dwSystemAffinityMask = 0; - if ( !GetProcessAffinityMask( GetCurrentProcess(), &dwProcessAffinityMask, &dwSystemAffinityMask ) ) - { - dwProcessAffinityMask = 0; - } - ///The number of threads should be equal to the number of available cores - 1 - m_numThreads = btMin(procInfo.numLogicalProcessors, int(BT_MAX_THREAD_COUNT)) - 1; // cap to max thread count (-1 because main thread already exists) + static int uniqueId = 0; + uniqueId++; + btProcessorInfo& procInfo = m_processorInfo; + getProcessorInformation(&procInfo); + DWORD_PTR dwProcessAffinityMask = 0; + DWORD_PTR dwSystemAffinityMask = 0; + if (!GetProcessAffinityMask(GetCurrentProcess(), &dwProcessAffinityMask, &dwSystemAffinityMask)) + { + dwProcessAffinityMask = 0; + } + ///The number of threads should be equal to the number of available cores - 1 + m_numThreads = btMin(procInfo.numLogicalProcessors, int(BT_MAX_THREAD_COUNT)) - 1; // cap to max thread count (-1 because main thread already exists) - m_activeThreadStatus.resize( m_numThreads ); - m_completeHandles.resize( m_numThreads ); - m_startedThreadMask = 0; + m_activeThreadStatus.resize(m_numThreads); + m_completeHandles.resize(m_numThreads); + m_startedThreadMask = 0; - // set main thread affinity - if ( DWORD_PTR mask = dwProcessAffinityMask & getProcessorTeamMask( procInfo, 0 )) - { - SetThreadAffinityMask( GetCurrentThread(), mask ); - SetThreadIdealProcessor( GetCurrentThread(), 0 ); - } + // set main thread affinity + if (DWORD_PTR mask = dwProcessAffinityMask & getProcessorTeamMask(procInfo, 0)) + { + SetThreadAffinityMask(GetCurrentThread(), mask); + SetThreadIdealProcessor(GetCurrentThread(), 0); + } - for ( int i = 0; i < m_numThreads; i++ ) - { - printf( "starting thread %d\n", i ); + for (int i = 0; i < m_numThreads; i++) + { + printf("starting thread %d\n", i); - btThreadStatus& threadStatus = m_activeThreadStatus[ i ]; + btThreadStatus& threadStatus = m_activeThreadStatus[i]; - LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL; - SIZE_T dwStackSize = threadConstructionInfo.m_threadStackSize; - LPTHREAD_START_ROUTINE lpStartAddress = &win32threadStartFunc; - LPVOID lpParameter = &threadStatus; - DWORD dwCreationFlags = 0; - LPDWORD lpThreadId = 0; + LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL; + SIZE_T dwStackSize = threadConstructionInfo.m_threadStackSize; + LPTHREAD_START_ROUTINE lpStartAddress = &win32threadStartFunc; + LPVOID lpParameter = &threadStatus; + DWORD dwCreationFlags = 0; + LPDWORD lpThreadId = 0; - threadStatus.m_userPtr = 0; + threadStatus.m_userPtr = 0; - sprintf( threadStatus.m_eventStartHandleName, "es%.8s%d%d", threadConstructionInfo.m_uniqueName, uniqueId, i ); - threadStatus.m_eventStartHandle = CreateEventA( 0, false, false, threadStatus.m_eventStartHandleName ); + sprintf(threadStatus.m_eventStartHandleName, "es%.8s%d%d", threadConstructionInfo.m_uniqueName, uniqueId, i); + threadStatus.m_eventStartHandle = CreateEventA(0, false, false, threadStatus.m_eventStartHandleName); - sprintf( threadStatus.m_eventCompleteHandleName, "ec%.8s%d%d", threadConstructionInfo.m_uniqueName, uniqueId, i ); - threadStatus.m_eventCompleteHandle = CreateEventA( 0, false, false, threadStatus.m_eventCompleteHandleName ); + sprintf(threadStatus.m_eventCompleteHandleName, "ec%.8s%d%d", threadConstructionInfo.m_uniqueName, uniqueId, i); + threadStatus.m_eventCompleteHandle = CreateEventA(0, false, false, threadStatus.m_eventCompleteHandleName); - m_completeHandles[ i ] = threadStatus.m_eventCompleteHandle; + m_completeHandles[i] = threadStatus.m_eventCompleteHandle; - HANDLE handle = CreateThread( lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId ); - //SetThreadPriority( handle, THREAD_PRIORITY_HIGHEST ); - // highest priority -- can cause erratic performance when numThreads > numCores - // we don't want worker threads to be higher priority than the main thread or the main thread could get - // totally shut out and unable to tell the workers to stop - //SetThreadPriority( handle, THREAD_PRIORITY_BELOW_NORMAL ); + HANDLE handle = CreateThread(lpThreadAttributes, dwStackSize, lpStartAddress, lpParameter, dwCreationFlags, lpThreadId); + //SetThreadPriority( handle, THREAD_PRIORITY_HIGHEST ); + // highest priority -- can cause erratic performance when numThreads > numCores + // we don't want worker threads to be higher priority than the main thread or the main thread could get + // totally shut out and unable to tell the workers to stop + //SetThreadPriority( handle, THREAD_PRIORITY_BELOW_NORMAL ); - { - int processorId = i + 1; // leave processor 0 for main thread - DWORD_PTR teamMask = getProcessorTeamMask( procInfo, processorId ); - if ( teamMask ) - { - // bind each thread to only execute on processors of it's assigned team - // - for single-socket Intel x86 CPUs this has no effect (only a single, shared L3 cache so there is only 1 team) - // - for multi-socket Intel this will keep threads from migrating from one socket to another - // - for AMD Ryzen this will keep threads from migrating from one CCX to another - DWORD_PTR mask = teamMask & dwProcessAffinityMask; - if ( mask ) - { - SetThreadAffinityMask( handle, mask ); - } - } - SetThreadIdealProcessor( handle, processorId ); - } + { + int processorId = i + 1; // leave processor 0 for main thread + DWORD_PTR teamMask = getProcessorTeamMask(procInfo, processorId); + if (teamMask) + { + // bind each thread to only execute on processors of it's assigned team + // - for single-socket Intel x86 CPUs this has no effect (only a single, shared L3 cache so there is only 1 team) + // - for multi-socket Intel this will keep threads from migrating from one socket to another + // - for AMD Ryzen this will keep threads from migrating from one CCX to another + DWORD_PTR mask = teamMask & dwProcessAffinityMask; + if (mask) + { + SetThreadAffinityMask(handle, mask); + } + } + SetThreadIdealProcessor(handle, processorId); + } - threadStatus.m_taskId = i; - threadStatus.m_commandId = 0; - threadStatus.m_status = 0; - threadStatus.m_threadHandle = handle; - threadStatus.m_userThreadFunc = threadConstructionInfo.m_userThreadFunc; + threadStatus.m_taskId = i; + threadStatus.m_commandId = 0; + threadStatus.m_status = 0; + threadStatus.m_threadHandle = handle; + threadStatus.m_userThreadFunc = threadConstructionInfo.m_userThreadFunc; - printf( "started %s thread %d with threadHandle %p\n", threadConstructionInfo.m_uniqueName, i, handle ); - } + printf("started %s thread %d with threadHandle %p\n", threadConstructionInfo.m_uniqueName, i, handle); + } } ///tell the task scheduler we are done with the SPU tasks void btThreadSupportWin32::stopThreads() { - for ( int i = 0; i < m_activeThreadStatus.size(); i++ ) - { - btThreadStatus& threadStatus = m_activeThreadStatus[ i ]; - if ( threadStatus.m_status > 0 ) - { - WaitForSingleObject( threadStatus.m_eventCompleteHandle, INFINITE ); - } + for (int i = 0; i < m_activeThreadStatus.size(); i++) + { + btThreadStatus& threadStatus = m_activeThreadStatus[i]; + if (threadStatus.m_status > 0) + { + WaitForSingleObject(threadStatus.m_eventCompleteHandle, INFINITE); + } - threadStatus.m_userPtr = NULL; - SetEvent( threadStatus.m_eventStartHandle ); - WaitForSingleObject( threadStatus.m_eventCompleteHandle, INFINITE ); + threadStatus.m_userPtr = NULL; + SetEvent(threadStatus.m_eventStartHandle); + WaitForSingleObject(threadStatus.m_eventCompleteHandle, INFINITE); - CloseHandle( threadStatus.m_eventCompleteHandle ); - CloseHandle( threadStatus.m_eventStartHandle ); - CloseHandle( threadStatus.m_threadHandle ); + CloseHandle(threadStatus.m_eventCompleteHandle); + CloseHandle(threadStatus.m_eventStartHandle); + CloseHandle(threadStatus.m_threadHandle); + } - } - - m_activeThreadStatus.clear(); - m_completeHandles.clear(); + m_activeThreadStatus.clear(); + m_completeHandles.clear(); } - class btWin32CriticalSection : public btCriticalSection { private: - CRITICAL_SECTION mCriticalSection; + CRITICAL_SECTION mCriticalSection; public: - btWin32CriticalSection() - { - InitializeCriticalSection( &mCriticalSection ); - } + btWin32CriticalSection() + { + InitializeCriticalSection(&mCriticalSection); + } - ~btWin32CriticalSection() - { - DeleteCriticalSection( &mCriticalSection ); - } + ~btWin32CriticalSection() + { + DeleteCriticalSection(&mCriticalSection); + } - void lock() - { - EnterCriticalSection( &mCriticalSection ); - } + void lock() + { + EnterCriticalSection(&mCriticalSection); + } - void unlock() - { - LeaveCriticalSection( &mCriticalSection ); - } + void unlock() + { + LeaveCriticalSection(&mCriticalSection); + } }; - btCriticalSection* btThreadSupportWin32::createCriticalSection() { - unsigned char* mem = (unsigned char*) btAlignedAlloc( sizeof( btWin32CriticalSection ), 16 ); - btWin32CriticalSection* cs = new( mem ) btWin32CriticalSection(); - return cs; + unsigned char* mem = (unsigned char*)btAlignedAlloc(sizeof(btWin32CriticalSection), 16); + btWin32CriticalSection* cs = new (mem) btWin32CriticalSection(); + return cs; } -void btThreadSupportWin32::deleteCriticalSection( btCriticalSection* criticalSection ) +void btThreadSupportWin32::deleteCriticalSection(btCriticalSection* criticalSection) { - criticalSection->~btCriticalSection(); - btAlignedFree( criticalSection ); + criticalSection->~btCriticalSection(); + btAlignedFree(criticalSection); } - -btThreadSupportInterface* btThreadSupportInterface::create( const ConstructionInfo& info ) +btThreadSupportInterface* btThreadSupportInterface::create(const ConstructionInfo& info) { - return new btThreadSupportWin32( info ); + return new btThreadSupportWin32(info); } - - -#endif //defined(_WIN32) && BT_THREADSAFE - +#endif //defined(_WIN32) && BT_THREADSAFE diff --git a/src/LinearMath/btAabbUtil2.h b/src/LinearMath/btAabbUtil2.h index d2997b4e6..eea49dd33 100644 --- a/src/LinearMath/btAabbUtil2.h +++ b/src/LinearMath/btAabbUtil2.h @@ -12,8 +12,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #ifndef BT_AABB_UTIL2 #define BT_AABB_UTIL2 @@ -21,20 +19,18 @@ subject to the following restrictions: #include "btVector3.h" #include "btMinMax.h" - - -SIMD_FORCE_INLINE void AabbExpand (btVector3& aabbMin, - btVector3& aabbMax, - const btVector3& expansionMin, - const btVector3& expansionMax) +SIMD_FORCE_INLINE void AabbExpand(btVector3& aabbMin, + btVector3& aabbMax, + const btVector3& expansionMin, + const btVector3& expansionMax) { aabbMin = aabbMin + expansionMin; aabbMax = aabbMax + expansionMax; } /// conservative test for overlap between two aabbs -SIMD_FORCE_INLINE bool TestPointAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1, - const btVector3 &point) +SIMD_FORCE_INLINE bool TestPointAgainstAabb2(const btVector3& aabbMin1, const btVector3& aabbMax1, + const btVector3& point) { bool overlap = true; overlap = (aabbMin1.getX() > point.getX() || aabbMax1.getX() < point.getX()) ? false : overlap; @@ -43,10 +39,9 @@ SIMD_FORCE_INLINE bool TestPointAgainstAabb2(const btVector3 &aabbMin1, const bt return overlap; } - /// conservative test for overlap between two aabbs -SIMD_FORCE_INLINE bool TestAabbAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1, - const btVector3 &aabbMin2, const btVector3 &aabbMax2) +SIMD_FORCE_INLINE bool TestAabbAgainstAabb2(const btVector3& aabbMin1, const btVector3& aabbMax1, + const btVector3& aabbMin2, const btVector3& aabbMax2) { bool overlap = true; overlap = (aabbMin1.getX() > aabbMax2.getX() || aabbMax1.getX() < aabbMin2.getX()) ? false : overlap; @@ -56,37 +51,34 @@ SIMD_FORCE_INLINE bool TestAabbAgainstAabb2(const btVector3 &aabbMin1, const btV } /// conservative test for overlap between triangle and aabb -SIMD_FORCE_INLINE bool TestTriangleAgainstAabb2(const btVector3 *vertices, - const btVector3 &aabbMin, const btVector3 &aabbMax) +SIMD_FORCE_INLINE bool TestTriangleAgainstAabb2(const btVector3* vertices, + const btVector3& aabbMin, const btVector3& aabbMax) { - const btVector3 &p1 = vertices[0]; - const btVector3 &p2 = vertices[1]; - const btVector3 &p3 = vertices[2]; + const btVector3& p1 = vertices[0]; + const btVector3& p2 = vertices[1]; + const btVector3& p3 = vertices[2]; if (btMin(btMin(p1[0], p2[0]), p3[0]) > aabbMax[0]) return false; if (btMax(btMax(p1[0], p2[0]), p3[0]) < aabbMin[0]) return false; if (btMin(btMin(p1[2], p2[2]), p3[2]) > aabbMax[2]) return false; if (btMax(btMax(p1[2], p2[2]), p3[2]) < aabbMin[2]) return false; - + if (btMin(btMin(p1[1], p2[1]), p3[1]) > aabbMax[1]) return false; if (btMax(btMax(p1[1], p2[1]), p3[1]) < aabbMin[1]) return false; return true; } - -SIMD_FORCE_INLINE int btOutcode(const btVector3& p,const btVector3& halfExtent) +SIMD_FORCE_INLINE int btOutcode(const btVector3& p, const btVector3& halfExtent) { - return (p.getX() < -halfExtent.getX() ? 0x01 : 0x0) | - (p.getX() > halfExtent.getX() ? 0x08 : 0x0) | - (p.getY() < -halfExtent.getY() ? 0x02 : 0x0) | - (p.getY() > halfExtent.getY() ? 0x10 : 0x0) | - (p.getZ() < -halfExtent.getZ() ? 0x4 : 0x0) | - (p.getZ() > halfExtent.getZ() ? 0x20 : 0x0); + return (p.getX() < -halfExtent.getX() ? 0x01 : 0x0) | + (p.getX() > halfExtent.getX() ? 0x08 : 0x0) | + (p.getY() < -halfExtent.getY() ? 0x02 : 0x0) | + (p.getY() > halfExtent.getY() ? 0x10 : 0x0) | + (p.getZ() < -halfExtent.getZ() ? 0x4 : 0x0) | + (p.getZ() > halfExtent.getZ() ? 0x20 : 0x0); } - - SIMD_FORCE_INLINE bool btRayAabb2(const btVector3& rayFrom, const btVector3& rayInvDirection, const unsigned int raySign[3], @@ -97,11 +89,11 @@ SIMD_FORCE_INLINE bool btRayAabb2(const btVector3& rayFrom, { btScalar tmax, tymin, tymax, tzmin, tzmax; tmin = (bounds[raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX(); - tmax = (bounds[1-raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX(); + tmax = (bounds[1 - raySign[0]].getX() - rayFrom.getX()) * rayInvDirection.getX(); tymin = (bounds[raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY(); - tymax = (bounds[1-raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY(); + tymax = (bounds[1 - raySign[1]].getY() - rayFrom.getY()) * rayInvDirection.getY(); - if ( (tmin > tymax) || (tymin > tmax) ) + if ((tmin > tymax) || (tymin > tmax)) return false; if (tymin > tmin) @@ -111,59 +103,59 @@ SIMD_FORCE_INLINE bool btRayAabb2(const btVector3& rayFrom, tmax = tymax; tzmin = (bounds[raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ(); - tzmax = (bounds[1-raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ(); + tzmax = (bounds[1 - raySign[2]].getZ() - rayFrom.getZ()) * rayInvDirection.getZ(); - if ( (tmin > tzmax) || (tzmin > tmax) ) + if ((tmin > tzmax) || (tzmin > tmax)) return false; if (tzmin > tmin) tmin = tzmin; if (tzmax < tmax) tmax = tzmax; - return ( (tmin < lambda_max) && (tmax > lambda_min) ); + return ((tmin < lambda_max) && (tmax > lambda_min)); } -SIMD_FORCE_INLINE bool btRayAabb(const btVector3& rayFrom, - const btVector3& rayTo, - const btVector3& aabbMin, +SIMD_FORCE_INLINE bool btRayAabb(const btVector3& rayFrom, + const btVector3& rayTo, + const btVector3& aabbMin, const btVector3& aabbMax, - btScalar& param, btVector3& normal) + btScalar& param, btVector3& normal) { - btVector3 aabbHalfExtent = (aabbMax-aabbMin)* btScalar(0.5); - btVector3 aabbCenter = (aabbMax+aabbMin)* btScalar(0.5); - btVector3 source = rayFrom - aabbCenter; - btVector3 target = rayTo - aabbCenter; - int sourceOutcode = btOutcode(source,aabbHalfExtent); - int targetOutcode = btOutcode(target,aabbHalfExtent); + btVector3 aabbHalfExtent = (aabbMax - aabbMin) * btScalar(0.5); + btVector3 aabbCenter = (aabbMax + aabbMin) * btScalar(0.5); + btVector3 source = rayFrom - aabbCenter; + btVector3 target = rayTo - aabbCenter; + int sourceOutcode = btOutcode(source, aabbHalfExtent); + int targetOutcode = btOutcode(target, aabbHalfExtent); if ((sourceOutcode & targetOutcode) == 0x0) { btScalar lambda_enter = btScalar(0.0); - btScalar lambda_exit = param; + btScalar lambda_exit = param; btVector3 r = target - source; int i; - btScalar normSign = 1; - btVector3 hitNormal(0,0,0); - int bit=1; + btScalar normSign = 1; + btVector3 hitNormal(0, 0, 0); + int bit = 1; - for (int j=0;j<2;j++) + for (int j = 0; j < 2; j++) { for (i = 0; i != 3; ++i) { if (sourceOutcode & bit) { - btScalar lambda = (-source[i] - aabbHalfExtent[i]*normSign) / r[i]; + btScalar lambda = (-source[i] - aabbHalfExtent[i] * normSign) / r[i]; if (lambda_enter <= lambda) { lambda_enter = lambda; - hitNormal.setValue(0,0,0); + hitNormal.setValue(0, 0, 0); hitNormal[i] = normSign; } } - else if (targetOutcode & bit) + else if (targetOutcode & bit) { - btScalar lambda = (-source[i] - aabbHalfExtent[i]*normSign) / r[i]; + btScalar lambda = (-source[i] - aabbHalfExtent[i] * normSign) / r[i]; btSetMin(lambda_exit, lambda); } - bit<<=1; + bit <<= 1; } normSign = btScalar(-1.); } @@ -177,56 +169,49 @@ SIMD_FORCE_INLINE bool btRayAabb(const btVector3& rayFrom, return false; } - - -SIMD_FORCE_INLINE void btTransformAabb(const btVector3& halfExtents, btScalar margin,const btTransform& t,btVector3& aabbMinOut,btVector3& aabbMaxOut) +SIMD_FORCE_INLINE void btTransformAabb(const btVector3& halfExtents, btScalar margin, const btTransform& t, btVector3& aabbMinOut, btVector3& aabbMaxOut) { - btVector3 halfExtentsWithMargin = halfExtents+btVector3(margin,margin,margin); - btMatrix3x3 abs_b = t.getBasis().absolute(); + btVector3 halfExtentsWithMargin = halfExtents + btVector3(margin, margin, margin); + btMatrix3x3 abs_b = t.getBasis().absolute(); btVector3 center = t.getOrigin(); - btVector3 extent = halfExtentsWithMargin.dot3( abs_b[0], abs_b[1], abs_b[2] ); + btVector3 extent = halfExtentsWithMargin.dot3(abs_b[0], abs_b[1], abs_b[2]); aabbMinOut = center - extent; aabbMaxOut = center + extent; } - -SIMD_FORCE_INLINE void btTransformAabb(const btVector3& localAabbMin,const btVector3& localAabbMax, btScalar margin,const btTransform& trans,btVector3& aabbMinOut,btVector3& aabbMaxOut) +SIMD_FORCE_INLINE void btTransformAabb(const btVector3& localAabbMin, const btVector3& localAabbMax, btScalar margin, const btTransform& trans, btVector3& aabbMinOut, btVector3& aabbMaxOut) { - btAssert(localAabbMin.getX() <= localAabbMax.getX()); - btAssert(localAabbMin.getY() <= localAabbMax.getY()); - btAssert(localAabbMin.getZ() <= localAabbMax.getZ()); - btVector3 localHalfExtents = btScalar(0.5)*(localAabbMax-localAabbMin); - localHalfExtents+=btVector3(margin,margin,margin); + btAssert(localAabbMin.getX() <= localAabbMax.getX()); + btAssert(localAabbMin.getY() <= localAabbMax.getY()); + btAssert(localAabbMin.getZ() <= localAabbMax.getZ()); + btVector3 localHalfExtents = btScalar(0.5) * (localAabbMax - localAabbMin); + localHalfExtents += btVector3(margin, margin, margin); - btVector3 localCenter = btScalar(0.5)*(localAabbMax+localAabbMin); - btMatrix3x3 abs_b = trans.getBasis().absolute(); - btVector3 center = trans(localCenter); - btVector3 extent = localHalfExtents.dot3( abs_b[0], abs_b[1], abs_b[2] ); - aabbMinOut = center-extent; - aabbMaxOut = center+extent; + btVector3 localCenter = btScalar(0.5) * (localAabbMax + localAabbMin); + btMatrix3x3 abs_b = trans.getBasis().absolute(); + btVector3 center = trans(localCenter); + btVector3 extent = localHalfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); + aabbMinOut = center - extent; + aabbMaxOut = center + extent; } #define USE_BANCHLESS 1 #ifdef USE_BANCHLESS - //This block replaces the block below and uses no branches, and replaces the 8 bit return with a 32 bit return for improved performance (~3x on XBox 360) - SIMD_FORCE_INLINE unsigned testQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1,const unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) - { - return static_cast(btSelect((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0]) - & (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2]) - & (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])), - 1, 0)); - } +//This block replaces the block below and uses no branches, and replaces the 8 bit return with a 32 bit return for improved performance (~3x on XBox 360) +SIMD_FORCE_INLINE unsigned testQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1, const unsigned short int* aabbMax1, const unsigned short int* aabbMin2, const unsigned short int* aabbMax2) +{ + return static_cast(btSelect((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0]) & (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2]) & (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])), + 1, 0)); +} #else - SIMD_FORCE_INLINE bool testQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1,const unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2) - { - bool overlap = true; - overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap; - overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap; - overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap; - return overlap; - } -#endif //USE_BANCHLESS - -#endif //BT_AABB_UTIL2 - +SIMD_FORCE_INLINE bool testQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1, const unsigned short int* aabbMax1, const unsigned short int* aabbMin2, const unsigned short int* aabbMax2) +{ + bool overlap = true; + overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap; + overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap; + overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap; + return overlap; +} +#endif //USE_BANCHLESS +#endif //BT_AABB_UTIL2 diff --git a/src/LinearMath/btAlignedAllocator.cpp b/src/LinearMath/btAlignedAllocator.cpp index 0526a4228..39b302b60 100644 --- a/src/LinearMath/btAlignedAllocator.cpp +++ b/src/LinearMath/btAlignedAllocator.cpp @@ -18,8 +18,8 @@ subject to the following restrictions: #ifdef BT_DEBUG_MEMORY_ALLOCATIONS int gNumAlignedAllocs = 0; int gNumAlignedFree = 0; -int gTotalBytesAlignedAllocs = 0;//detect memory leaks -#endif //BT_DEBUG_MEMORY_ALLOCATIONST_DEBUG_ALLOCATIONS +int gTotalBytesAlignedAllocs = 0; //detect memory leaks +#endif //BT_DEBUG_MEMORY_ALLOCATIONST_DEBUG_ALLOCATIONS static void *btAllocDefault(size_t size) { @@ -34,9 +34,7 @@ static void btFreeDefault(void *ptr) static btAllocFunc *sAllocFunc = btAllocDefault; static btFreeFunc *sFreeFunc = btFreeDefault; - - -#if defined (BT_HAS_ALIGNED_ALLOCATOR) +#if defined(BT_HAS_ALIGNED_ALLOCATOR) #include static void *btAlignedAllocDefault(size_t size, int alignment) { @@ -61,49 +59,48 @@ static inline void btAlignedFreeDefault(void *ptr) } #else - - - - static inline void *btAlignedAllocDefault(size_t size, int alignment) { - void *ret; - char *real; - real = (char *)sAllocFunc(size + sizeof(void *) + (alignment-1)); - if (real) { - ret = btAlignPointer(real + sizeof(void *),alignment); - *((void **)(ret)-1) = (void *)(real); - } else { - ret = (void *)(real); - } - return (ret); + void *ret; + char *real; + real = (char *)sAllocFunc(size + sizeof(void *) + (alignment - 1)); + if (real) + { + ret = btAlignPointer(real + sizeof(void *), alignment); + *((void **)(ret)-1) = (void *)(real); + } + else + { + ret = (void *)(real); + } + return (ret); } static inline void btAlignedFreeDefault(void *ptr) { - void* real; + void *real; - if (ptr) { - real = *((void **)(ptr)-1); - sFreeFunc(real); - } + if (ptr) + { + real = *((void **)(ptr)-1); + sFreeFunc(real); + } } #endif - static btAlignedAllocFunc *sAlignedAllocFunc = btAlignedAllocDefault; static btAlignedFreeFunc *sAlignedFreeFunc = btAlignedFreeDefault; void btAlignedAllocSetCustomAligned(btAlignedAllocFunc *allocFunc, btAlignedFreeFunc *freeFunc) { - sAlignedAllocFunc = allocFunc ? allocFunc : btAlignedAllocDefault; - sAlignedFreeFunc = freeFunc ? freeFunc : btAlignedFreeDefault; + sAlignedAllocFunc = allocFunc ? allocFunc : btAlignedAllocDefault; + sAlignedFreeFunc = freeFunc ? freeFunc : btAlignedFreeDefault; } void btAlignedAllocSetCustom(btAllocFunc *allocFunc, btFreeFunc *freeFunc) { - sAllocFunc = allocFunc ? allocFunc : btAllocDefault; - sFreeFunc = freeFunc ? freeFunc : btFreeDefault; + sAllocFunc = allocFunc ? allocFunc : btAllocDefault; + sFreeFunc = freeFunc ? freeFunc : btFreeDefault; } #ifdef BT_DEBUG_MEMORY_ALLOCATIONS @@ -116,15 +113,15 @@ static int mynumallocs = 0; int btDumpMemoryLeaks() { int totalLeak = 0; - - for (int i=0;i1024*1024) -// { -// printf("big alloc!%d\n", size); -// } + void *ret; + char *real; - gTotalBytesAlignedAllocs += size; - gNumAlignedAllocs++; + // to find some particular memory leak, you could do something like this: + // if (allocId==172) + // { + // printf("catch me!\n"); + // } + // if (size>1024*1024) + // { + // printf("big alloc!%d\n", size); + // } - -int sz4prt = 4*sizeof(void *); - - real = (char *)sAllocFunc(size + sz4prt + (alignment-1)); - if (real) { - - ret = (void*) btAlignPointer(real + sz4prt, alignment); - btDebugPtrMagic p; - p.vptr = ret; - p.cptr-=sizeof(void*); - *p.vptrptr = (void*)real; - p.cptr-=sizeof(void*); - *p.iptr = size; - p.cptr-=sizeof(void*); - *p.iptr = allocId; - - allocations_id[mynumallocs] = allocId; - allocations_bytes[mynumallocs] = size; - mynumallocs++; + gTotalBytesAlignedAllocs += size; + gNumAlignedAllocs++; - } else { - ret = (void *)(real);//?? - } + int sz4prt = 4 * sizeof(void *); - printf("allocation %d at address %x, from %s,line %d, size %d (total allocated = %d)\n",allocId,real, filename,line,size,gTotalBytesAlignedAllocs); + real = (char *)sAllocFunc(size + sz4prt + (alignment - 1)); + if (real) + { + ret = (void *)btAlignPointer(real + sz4prt, alignment); + btDebugPtrMagic p; + p.vptr = ret; + p.cptr -= sizeof(void *); + *p.vptrptr = (void *)real; + p.cptr -= sizeof(void *); + *p.iptr = size; + p.cptr -= sizeof(void *); + *p.iptr = allocId; + + allocations_id[mynumallocs] = allocId; + allocations_bytes[mynumallocs] = size; + mynumallocs++; + } + else + { + ret = (void *)(real); //?? + } + + printf("allocation %d at address %x, from %s,line %d, size %d (total allocated = %d)\n", allocId, real, filename, line, size, gTotalBytesAlignedAllocs); allocId++; - - int* ptr = (int*)ret; - *ptr = 12; - return (ret); + + int *ptr = (int *)ret; + *ptr = 12; + return (ret); } -void btAlignedFreeInternal (void* ptr,int line,char* filename) +void btAlignedFreeInternal(void *ptr, int line, char *filename) { + void *real; - void* real; + if (ptr) + { + gNumAlignedFree++; - if (ptr) { - gNumAlignedFree++; + btDebugPtrMagic p; + p.vptr = ptr; + p.cptr -= sizeof(void *); + real = *p.vptrptr; + p.cptr -= sizeof(void *); + int size = *p.iptr; + p.cptr -= sizeof(void *); + int allocId = *p.iptr; - btDebugPtrMagic p; - p.vptr = ptr; - p.cptr-=sizeof(void*); - real = *p.vptrptr; - p.cptr-=sizeof(void*); - int size = *p.iptr; - p.cptr-=sizeof(void*); - int allocId = *p.iptr; + bool found = false; - bool found = false; - - for (int i=0;i -class btAlignedAllocator { - - typedef btAlignedAllocator< T , Alignment > self_type; - -public: +template +class btAlignedAllocator +{ + typedef btAlignedAllocator self_type; +public: //just going down a list: btAlignedAllocator() {} /* btAlignedAllocator( const self_type & ) {} */ - template < typename Other > - btAlignedAllocator( const btAlignedAllocator< Other , Alignment > & ) {} + template + btAlignedAllocator(const btAlignedAllocator&) + { + } - typedef const T* const_pointer; - typedef const T& const_reference; - typedef T* pointer; - typedef T& reference; - typedef T value_type; + typedef const T* const_pointer; + typedef const T& const_reference; + typedef T* pointer; + typedef T& reference; + typedef T value_type; - pointer address ( reference ref ) const { return &ref; } - const_pointer address ( const_reference ref ) const { return &ref; } - pointer allocate ( size_type n , const_pointer * hint = 0 ) { + pointer address(reference ref) const { return &ref; } + const_pointer address(const_reference ref) const { return &ref; } + pointer allocate(size_type n, const_pointer* hint = 0) + { (void)hint; - return reinterpret_cast< pointer >(btAlignedAlloc( sizeof(value_type) * n , Alignment )); + return reinterpret_cast(btAlignedAlloc(sizeof(value_type) * n, Alignment)); } - void construct ( pointer ptr , const value_type & value ) { new (ptr) value_type( value ); } - void deallocate( pointer ptr ) { - btAlignedFree( reinterpret_cast< void * >( ptr ) ); + void construct(pointer ptr, const value_type& value) { new (ptr) value_type(value); } + void deallocate(pointer ptr) + { + btAlignedFree(reinterpret_cast(ptr)); } - void destroy ( pointer ptr ) { ptr->~value_type(); } - + void destroy(pointer ptr) { ptr->~value_type(); } - template < typename O > struct rebind { - typedef btAlignedAllocator< O , Alignment > other; + template + struct rebind + { + typedef btAlignedAllocator other; }; - template < typename O > - self_type & operator=( const btAlignedAllocator< O , Alignment > & ) { return *this; } + template + self_type& operator=(const btAlignedAllocator&) + { + return *this; + } - friend bool operator==( const self_type & , const self_type & ) { return true; } + friend bool operator==(const self_type&, const self_type&) { return true; } }; - - -#endif //BT_ALIGNED_ALLOCATOR - +#endif //BT_ALIGNED_ALLOCATOR diff --git a/src/LinearMath/btAlignedObjectArray.h b/src/LinearMath/btAlignedObjectArray.h index f0b646529..b4671bc19 100644 --- a/src/LinearMath/btAlignedObjectArray.h +++ b/src/LinearMath/btAlignedObjectArray.h @@ -13,11 +13,10 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef BT_OBJECT_ARRAY__ #define BT_OBJECT_ARRAY__ -#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE +#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE #include "btAlignedAllocator.h" ///If the platform doesn't support placement new, you can disable BT_USE_PLACEMENT_NEW @@ -28,16 +27,16 @@ subject to the following restrictions: #define BT_USE_PLACEMENT_NEW 1 //#define BT_USE_MEMCPY 1 //disable, because it is cumbersome to find out for each platform where memcpy is defined. It can be in or or otherwise... -#define BT_ALLOW_ARRAY_COPY_OPERATOR // enabling this can accidently perform deep copies of data if you are not careful +#define BT_ALLOW_ARRAY_COPY_OPERATOR // enabling this can accidently perform deep copies of data if you are not careful #ifdef BT_USE_MEMCPY #include #include -#endif //BT_USE_MEMCPY +#endif //BT_USE_MEMCPY #ifdef BT_USE_PLACEMENT_NEW -#include //for placement new -#endif //BT_USE_PLACEMENT_NEW +#include //for placement new +#endif //BT_USE_PLACEMENT_NEW // The register keyword is deprecated in C++11 so don't use it. #if __cplusplus > 199711L @@ -48,374 +47,358 @@ subject to the following restrictions: ///The btAlignedObjectArray template class uses a subset of the stl::vector interface for its methods ///It is developed to replace stl::vector to avoid portability issues, including STL alignment issues to add SIMD/SSE data -template -//template +template +//template class btAlignedObjectArray { - btAlignedAllocator m_allocator; + btAlignedAllocator m_allocator; - int m_size; - int m_capacity; - T* m_data; + int m_size; + int m_capacity; + T* m_data; //PCK: added this line - bool m_ownsMemory; + bool m_ownsMemory; #ifdef BT_ALLOW_ARRAY_COPY_OPERATOR public: - SIMD_FORCE_INLINE btAlignedObjectArray& operator=(const btAlignedObjectArray &other) + SIMD_FORCE_INLINE btAlignedObjectArray& operator=(const btAlignedObjectArray& other) { copyFromArray(other); return *this; } -#else//BT_ALLOW_ARRAY_COPY_OPERATOR +#else //BT_ALLOW_ARRAY_COPY_OPERATOR private: - SIMD_FORCE_INLINE btAlignedObjectArray& operator=(const btAlignedObjectArray &other); -#endif//BT_ALLOW_ARRAY_COPY_OPERATOR + SIMD_FORCE_INLINE btAlignedObjectArray& operator=(const btAlignedObjectArray& other); +#endif //BT_ALLOW_ARRAY_COPY_OPERATOR protected: - SIMD_FORCE_INLINE int allocSize(int size) - { - return (size ? size*2 : 1); - } - SIMD_FORCE_INLINE void copy(int start,int end, T* dest) const - { - int i; - for (i=start;i= 0); + btAssert(n < size()); + return m_data[n]; + } + + SIMD_FORCE_INLINE T& at(int n) + { + btAssert(n >= 0); + btAssert(n < size()); + return m_data[n]; + } + + SIMD_FORCE_INLINE const T& operator[](int n) const + { + btAssert(n >= 0); + btAssert(n < size()); + return m_data[n]; + } + + SIMD_FORCE_INLINE T& operator[](int n) + { + btAssert(n >= 0); + btAssert(n < size()); + return m_data[n]; + } + + ///clear the array, deallocated memory. Generally it is better to use array.resize(0), to reduce performance overhead of run-time memory (de)allocations. + SIMD_FORCE_INLINE void clear() + { + destroy(0, size()); + + deallocate(); + + init(); + } + + SIMD_FORCE_INLINE void pop_back() + { + btAssert(m_size > 0); + m_size--; + m_data[m_size].~T(); + } + + ///resize changes the number of elements in the array. If the new size is larger, the new elements will be constructed using the optional second argument. + ///when the new number of elements is smaller, the destructor will be called, but memory will not be freed, to reduce performance overhead of run-time memory (de)allocations. + SIMD_FORCE_INLINE void resizeNoInitialize(int newsize) + { + if (newsize > size()) + { + reserve(newsize); + } + m_size = newsize; + } + + SIMD_FORCE_INLINE void resize(int newsize, const T& fillData = T()) + { + const BT_REGISTER int curSize = size(); + + if (newsize < curSize) + { + for (int i = newsize; i < curSize; i++) { m_data[i].~T(); } } - - SIMD_FORCE_INLINE void* allocate(int size) + else { - if (size) - return m_allocator.allocate(size); - return 0; - } - - SIMD_FORCE_INLINE void deallocate() - { - if(m_data) { - //PCK: enclosed the deallocation in this block - if (m_ownsMemory) - { - m_allocator.deallocate(m_data); - } - m_data = 0; - } - } - - - - - public: - - btAlignedObjectArray() - { - init(); - } - - ~btAlignedObjectArray() - { - clear(); - } - - ///Generally it is best to avoid using the copy constructor of an btAlignedObjectArray, and use a (const) reference to the array instead. - btAlignedObjectArray(const btAlignedObjectArray& otherArray) - { - init(); - - int otherSize = otherArray.size(); - resize (otherSize); - otherArray.copy(0, otherSize, m_data); - } - - - - /// return the number of elements in the array - SIMD_FORCE_INLINE int size() const - { - return m_size; - } - - SIMD_FORCE_INLINE const T& at(int n) const - { - btAssert(n>=0); - btAssert(n=0); - btAssert(n=0); - btAssert(n=0); - btAssert(n0); - m_size--; - m_data[m_size].~T(); - } - - - ///resize changes the number of elements in the array. If the new size is larger, the new elements will be constructed using the optional second argument. - ///when the new number of elements is smaller, the destructor will be called, but memory will not be freed, to reduce performance overhead of run-time memory (de)allocations. - SIMD_FORCE_INLINE void resizeNoInitialize(int newsize) - { - if (newsize > size()) + if (newsize > curSize) { reserve(newsize); } - m_size = newsize; +#ifdef BT_USE_PLACEMENT_NEW + for (int i = curSize; i < newsize; i++) + { + new (&m_data[i]) T(fillData); + } +#endif //BT_USE_PLACEMENT_NEW } - - SIMD_FORCE_INLINE void resize(int newsize, const T& fillData=T()) + + m_size = newsize; + } + SIMD_FORCE_INLINE T& expandNonInitializing() + { + const BT_REGISTER int sz = size(); + if (sz == capacity()) { - const BT_REGISTER int curSize = size(); - - if (newsize < curSize) - { - for(int i = newsize; i < curSize; i++) - { - m_data[i].~T(); - } - } else - { - if (newsize > curSize) - { - reserve(newsize); - } -#ifdef BT_USE_PLACEMENT_NEW - for (int i=curSize;i - void quickSortInternal(const L& CompareFunc,int lo, int hi) - { + template + void quickSortInternal(const L& CompareFunc, int lo, int hi) + { // lo is the lower index, hi is the upper index // of the region of array a that is to be sorted - int i=lo, j=hi; - T x=m_data[(lo+hi)/2]; + int i = lo, j = hi; + T x = m_data[(lo + hi) / 2]; - // partition - do - { - while (CompareFunc(m_data[i],x)) - i++; - while (CompareFunc(x,m_data[j])) - j--; - if (i<=j) - { - swap(i,j); - i++; j--; - } - } while (i<=j); - - // recursion - if (lo - void quickSort(const L& CompareFunc) + // partition + do { - //don't sort 0 or 1 elements - if (size()>1) + while (CompareFunc(m_data[i], x)) + i++; + while (CompareFunc(x, m_data[j])) + j--; + if (i <= j) { - quickSortInternal(CompareFunc,0,size()-1); + swap(i, j); + i++; + j--; + } + } while (i <= j); + + // recursion + if (lo < j) + quickSortInternal(CompareFunc, lo, j); + if (i < hi) + quickSortInternal(CompareFunc, i, hi); + } + + template + void quickSort(const L& CompareFunc) + { + //don't sort 0 or 1 elements + if (size() > 1) + { + quickSortInternal(CompareFunc, 0, size() - 1); + } + } + + ///heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/ + template + void downHeap(T* pArr, int k, int n, const L& CompareFunc) + { + /* PRE: a[k+1..N] is a heap */ + /* POST: a[k..N] is a heap */ + + T temp = pArr[k - 1]; + /* k has child(s) */ + while (k <= n / 2) + { + int child = 2 * k; + + if ((child < n) && CompareFunc(pArr[child - 1], pArr[child])) + { + child++; + } + /* pick larger child */ + if (CompareFunc(temp, pArr[child - 1])) + { + /* move child up */ + pArr[k - 1] = pArr[child - 1]; + k = child; + } + else + { + break; } } + pArr[k - 1] = temp; + } /*downHeap*/ - - ///heap sort from http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Sort/Heap/ - template - void downHeap(T *pArr, int k, int n, const L& CompareFunc) - { - /* PRE: a[k+1..N] is a heap */ - /* POST: a[k..N] is a heap */ - - T temp = pArr[k - 1]; - /* k has child(s) */ - while (k <= n/2) - { - int child = 2*k; - - if ((child < n) && CompareFunc(pArr[child - 1] , pArr[child])) - { - child++; - } - /* pick larger child */ - if (CompareFunc(temp , pArr[child - 1])) - { - /* move child up */ - pArr[k - 1] = pArr[child - 1]; - k = child; - } - else - { - break; - } - } - pArr[k - 1] = temp; - } /*downHeap*/ - - void swap(int index0,int index1) - { + void swap(int index0, int index1) + { #ifdef BT_USE_MEMCPY - char temp[sizeof(T)]; - memcpy(temp,&m_data[index0],sizeof(T)); - memcpy(&m_data[index0],&m_data[index1],sizeof(T)); - memcpy(&m_data[index1],temp,sizeof(T)); + char temp[sizeof(T)]; + memcpy(temp, &m_data[index0], sizeof(T)); + memcpy(&m_data[index0], &m_data[index1], sizeof(T)); + memcpy(&m_data[index1], temp, sizeof(T)); #else - T temp = m_data[index0]; - m_data[index0] = m_data[index1]; - m_data[index1] = temp; -#endif //BT_USE_PLACEMENT_NEW - - } + T temp = m_data[index0]; + m_data[index0] = m_data[index1]; + m_data[index1] = temp; +#endif //BT_USE_PLACEMENT_NEW + } template void heapSort(const L& CompareFunc) @@ -423,49 +406,48 @@ protected: /* sort a[0..N-1], N.B. 0 to N-1 */ int k; int n = m_size; - for (k = n/2; k > 0; k--) + for (k = n / 2; k > 0; k--) { downHeap(m_data, k, n, CompareFunc); } /* a[1..N] is now a heap */ - while ( n>=1 ) + while (n >= 1) { - swap(0,n-1); /* largest of a[0..n-1] */ - + swap(0, n - 1); /* largest of a[0..n-1] */ n = n - 1; /* restore a[1..i-1] heap */ downHeap(m_data, 1, n, CompareFunc); - } + } } ///non-recursive binary search, assumes sorted array - int findBinarySearch(const T& key) const + int findBinarySearch(const T& key) const { int first = 0; - int last = size()-1; + int last = size() - 1; //assume sorted array - while (first <= last) { + while (first <= last) + { int mid = (first + last) / 2; // compute mid point. - if (key > m_data[mid]) + if (key > m_data[mid]) first = mid + 1; // repeat search in top half. - else if (key < m_data[mid]) - last = mid - 1; // repeat search in bottom half. + else if (key < m_data[mid]) + last = mid - 1; // repeat search in bottom half. else - return mid; // found it. return position ///// + return mid; // found it. return position ///// } - return size(); // failed to find key + return size(); // failed to find key } - - int findLinearSearch(const T& key) const + int findLinearSearch(const T& key) const { - int index=size(); + int index = size(); int i; - for (i=0;i btScalar(0.000001)); - + quotient = btScalar(-1.) / quotient; n2n3 *= p0.dist; n3n1 *= p1.dist; @@ -74,105 +75,96 @@ btVector3 ThreePlaneIntersection(const btPlane &p0,const btPlane &p1, const btP potentialVertex += n1n2; potentialVertex *= quotient; - btVector3 result(potentialVertex.getX(),potentialVertex.getY(),potentialVertex.getZ()); + btVector3 result(potentialVertex.getX(), potentialVertex.getY(), potentialVertex.getZ()); return result; - } -btScalar DistanceBetweenLines(const btVector3 &ustart, const btVector3 &udir, const btVector3 &vstart, const btVector3 &vdir, btVector3 *upoint=NULL, btVector3 *vpoint=NULL); -btVector3 TriNormal(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2); -btVector3 NormalOf(const btVector3 *vert, const int n); - +btScalar DistanceBetweenLines(const btVector3 &ustart, const btVector3 &udir, const btVector3 &vstart, const btVector3 &vdir, btVector3 *upoint = NULL, btVector3 *vpoint = NULL); +btVector3 TriNormal(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2); +btVector3 NormalOf(const btVector3 *vert, const int n); btVector3 PlaneLineIntersection(const btPlane &plane, const btVector3 &p0, const btVector3 &p1) { // returns the point where the line p0-p1 intersects the plane n&d - btVector3 dif; - dif = p1-p0; - btScalar dn= btDot(plane.normal,dif); - btScalar t = -(plane.dist+btDot(plane.normal,p0) )/dn; - return p0 + (dif*t); + btVector3 dif; + dif = p1 - p0; + btScalar dn = btDot(plane.normal, dif); + btScalar t = -(plane.dist + btDot(plane.normal, p0)) / dn; + return p0 + (dif * t); } btVector3 PlaneProject(const btPlane &plane, const btVector3 &point) { - return point - plane.normal * (btDot(point,plane.normal)+plane.dist); + return point - plane.normal * (btDot(point, plane.normal) + plane.dist); } btVector3 TriNormal(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2) { // return the normal of the triangle // inscribed by v0, v1, and v2 - btVector3 cp=btCross(v1-v0,v2-v1); - btScalar m=cp.length(); - if(m==0) return btVector3(1,0,0); - return cp*(btScalar(1.0)/m); + btVector3 cp = btCross(v1 - v0, v2 - v1); + btScalar m = cp.length(); + if (m == 0) return btVector3(1, 0, 0); + return cp * (btScalar(1.0) / m); } - btScalar DistanceBetweenLines(const btVector3 &ustart, const btVector3 &udir, const btVector3 &vstart, const btVector3 &vdir, btVector3 *upoint, btVector3 *vpoint) { btVector3 cp; - cp = btCross(udir,vdir).normalized(); + cp = btCross(udir, vdir).normalized(); - btScalar distu = -btDot(cp,ustart); - btScalar distv = -btDot(cp,vstart); - btScalar dist = (btScalar)fabs(distu-distv); - if(upoint) - { + btScalar distu = -btDot(cp, ustart); + btScalar distv = -btDot(cp, vstart); + btScalar dist = (btScalar)fabs(distu - distv); + if (upoint) + { btPlane plane; - plane.normal = btCross(vdir,cp).normalized(); - plane.dist = -btDot(plane.normal,vstart); - *upoint = PlaneLineIntersection(plane,ustart,ustart+udir); + plane.normal = btCross(vdir, cp).normalized(); + plane.dist = -btDot(plane.normal, vstart); + *upoint = PlaneLineIntersection(plane, ustart, ustart + udir); } - if(vpoint) - { + if (vpoint) + { btPlane plane; - plane.normal = btCross(udir,cp).normalized(); - plane.dist = -btDot(plane.normal,ustart); - *vpoint = PlaneLineIntersection(plane,vstart,vstart+vdir); + plane.normal = btCross(udir, cp).normalized(); + plane.dist = -btDot(plane.normal, ustart); + *vpoint = PlaneLineIntersection(plane, vstart, vstart + vdir); } return dist; } - - - - - - -#define COPLANAR (0) -#define UNDER (1) -#define OVER (2) -#define SPLIT (OVER|UNDER) +#define COPLANAR (0) +#define UNDER (1) +#define OVER (2) +#define SPLIT (OVER | UNDER) #define PAPERWIDTH (btScalar(0.001)) btScalar planetestepsilon = PAPERWIDTH; - - typedef ConvexH::HalfEdge HalfEdge; -ConvexH::ConvexH(int vertices_size,int edges_size,int facets_size) +ConvexH::ConvexH(int vertices_size, int edges_size, int facets_size) { vertices.resize(vertices_size); edges.resize(edges_size); facets.resize(facets_size); } - int PlaneTest(const btPlane &p, const btVector3 &v); -int PlaneTest(const btPlane &p, const btVector3 &v) { - btScalar a = btDot(v,p.normal)+p.dist; - int flag = (a>planetestepsilon)?OVER:((a<-planetestepsilon)?UNDER:COPLANAR); +int PlaneTest(const btPlane &p, const btVector3 &v) +{ + btScalar a = btDot(v, p.normal) + p.dist; + int flag = (a > planetestepsilon) ? OVER : ((a < -planetestepsilon) ? UNDER : COPLANAR); return flag; } -int SplitTest(ConvexH &convex,const btPlane &plane); -int SplitTest(ConvexH &convex,const btPlane &plane) { - int flag=0; - for(int i=0;i -int maxdirfiltered(const T *p,int count,const T &dir,btAlignedObjectArray &allow) +template +int maxdirfiltered(const T *p, int count, const T &dir, btAlignedObjectArray &allow) { btAssert(count); - int m=-1; - for(int i=0;ibtDot(p[m],dir)) - m=i; + if (m == -1 || btDot(p[i], dir) > btDot(p[m], dir)) + m = i; } - btAssert(m!=-1); + btAssert(m != -1); return m; -} +} btVector3 orth(const btVector3 &v); btVector3 orth(const btVector3 &v) { - btVector3 a=btCross(v,btVector3(0,0,1)); - btVector3 b=btCross(v,btVector3(0,1,0)); + btVector3 a = btCross(v, btVector3(0, 0, 1)); + btVector3 b = btCross(v, btVector3(0, 1, 0)); if (a.length() > b.length()) { return a.normalized(); - } else { + } + else + { return b.normalized(); } } - -template -int maxdirsterid(const T *p,int count,const T &dir,btAlignedObjectArray &allow) +template +int maxdirsterid(const T *p, int count, const T &dir, btAlignedObjectArray &allow) { - int m=-1; - while(m==-1) + int m = -1; + while (m == -1) { - m = maxdirfiltered(p,count,dir,allow); - if(allow[m]==3) return m; + m = maxdirfiltered(p, count, dir, allow); + if (allow[m] == 3) return m; T u = orth(dir); - T v = btCross(u,dir); - int ma=-1; - for(btScalar x = btScalar(0.0) ; x<= btScalar(360.0) ; x+= btScalar(45.0)) + T v = btCross(u, dir); + int ma = -1; + for (btScalar x = btScalar(0.0); x <= btScalar(360.0); x += btScalar(45.0)) { - btScalar s = btSin(SIMD_RADS_PER_DEG*(x)); - btScalar c = btCos(SIMD_RADS_PER_DEG*(x)); - int mb = maxdirfiltered(p,count,dir+(u*s+v*c)*btScalar(0.025),allow); - if(ma==m && mb==m) + btScalar s = btSin(SIMD_RADS_PER_DEG * (x)); + btScalar c = btCos(SIMD_RADS_PER_DEG * (x)); + int mb = maxdirfiltered(p, count, dir + (u * s + v * c) * btScalar(0.025), allow); + if (ma == m && mb == m) { - allow[m]=3; + allow[m] = 3; return m; } - if(ma!=-1 && ma!=mb) // Yuck - this is really ugly + if (ma != -1 && ma != mb) // Yuck - this is really ugly { int mc = ma; - for(btScalar xx = x-btScalar(40.0) ; xx <= x ; xx+= btScalar(5.0)) + for (btScalar xx = x - btScalar(40.0); xx <= x; xx += btScalar(5.0)) { - btScalar s = btSin(SIMD_RADS_PER_DEG*(xx)); - btScalar c = btCos(SIMD_RADS_PER_DEG*(xx)); - int md = maxdirfiltered(p,count,dir+(u*s+v*c)*btScalar(0.025),allow); - if(mc==m && md==m) + btScalar s = btSin(SIMD_RADS_PER_DEG * (xx)); + btScalar c = btCos(SIMD_RADS_PER_DEG * (xx)); + int md = maxdirfiltered(p, count, dir + (u * s + v * c) * btScalar(0.025), allow); + if (mc == m && md == m) { - allow[m]=3; + allow[m] = 3; return m; } - mc=md; + mc = md; } } - ma=mb; + ma = mb; } - allow[m]=0; - m=-1; + allow[m] = 0; + m = -1; } btAssert(0); return m; -} +} - - - -int operator ==(const int3 &a,const int3 &b); -int operator ==(const int3 &a,const int3 &b) +int operator==(const int3 &a, const int3 &b); +int operator==(const int3 &a, const int3 &b) { - for(int i=0;i<3;i++) + for (int i = 0; i < 3; i++) { - if(a[i]!=b[i]) return 0; + if (a[i] != b[i]) return 0; } return 1; } - -int above(btVector3* vertices,const int3& t, const btVector3 &p, btScalar epsilon); -int above(btVector3* vertices,const int3& t, const btVector3 &p, btScalar epsilon) +int above(btVector3 *vertices, const int3 &t, const btVector3 &p, btScalar epsilon); +int above(btVector3 *vertices, const int3 &t, const btVector3 &p, btScalar epsilon) { - btVector3 n=TriNormal(vertices[t[0]],vertices[t[1]],vertices[t[2]]); - return (btDot(n,p-vertices[t[0]]) > epsilon); // EPSILON??? + btVector3 n = TriNormal(vertices[t[0]], vertices[t[1]], vertices[t[2]]); + return (btDot(n, p - vertices[t[0]]) > epsilon); // EPSILON??? } -int hasedge(const int3 &t, int a,int b); -int hasedge(const int3 &t, int a,int b) +int hasedge(const int3 &t, int a, int b); +int hasedge(const int3 &t, int a, int b) { - for(int i=0;i<3;i++) + for (int i = 0; i < 3; i++) { - int i1= (i+1)%3; - if(t[i]==a && t[i1]==b) return 1; + int i1 = (i + 1) % 3; + if (t[i] == a && t[i1] == b) return 1; } return 0; } int hasvert(const int3 &t, int v); int hasvert(const int3 &t, int v) { - return (t[0]==v || t[1]==v || t[2]==v) ; + return (t[0] == v || t[1] == v || t[2] == v); } -int shareedge(const int3 &a,const int3 &b); -int shareedge(const int3 &a,const int3 &b) +int shareedge(const int3 &a, const int3 &b); +int shareedge(const int3 &a, const int3 &b) { int i; - for(i=0;i<3;i++) + for (i = 0; i < 3; i++) { - int i1= (i+1)%3; - if(hasedge(a,b[i1],b[i])) return 1; + int i1 = (i + 1) % 3; + if (hasedge(a, b[i1], b[i])) return 1; } return 0; } class btHullTriangle; - - class btHullTriangle : public int3 { public: @@ -346,51 +327,50 @@ public: int id; int vmax; btScalar rise; - btHullTriangle(int a,int b,int c):int3(a,b,c),n(-1,-1,-1) + btHullTriangle(int a, int b, int c) : int3(a, b, c), n(-1, -1, -1) { - vmax=-1; + vmax = -1; rise = btScalar(0.0); } ~btHullTriangle() { } - int &neib(int a,int b); + int &neib(int a, int b); }; - -int &btHullTriangle::neib(int a,int b) +int &btHullTriangle::neib(int a, int b) { - static int er=-1; + static int er = -1; int i; - for(i=0;i<3;i++) + for (i = 0; i < 3; i++) { - int i1=(i+1)%3; - int i2=(i+2)%3; - if((*this)[i]==a && (*this)[i1]==b) return n[i2]; - if((*this)[i]==b && (*this)[i1]==a) return n[i2]; + int i1 = (i + 1) % 3; + int i2 = (i + 2) % 3; + if ((*this)[i] == a && (*this)[i1] == b) return n[i2]; + if ((*this)[i] == b && (*this)[i1] == a) return n[i2]; } btAssert(0); return er; } -void HullLibrary::b2bfix(btHullTriangle* s,btHullTriangle*t) +void HullLibrary::b2bfix(btHullTriangle *s, btHullTriangle *t) { int i; - for(i=0;i<3;i++) + for (i = 0; i < 3; i++) { - int i1=(i+1)%3; - int i2=(i+2)%3; + int i1 = (i + 1) % 3; + int i2 = (i + 2) % 3; int a = (*s)[i1]; int b = (*s)[i2]; - btAssert(m_tris[s->neib(a,b)]->neib(b,a) == s->id); - btAssert(m_tris[t->neib(a,b)]->neib(b,a) == t->id); - m_tris[s->neib(a,b)]->neib(b,a) = t->neib(b,a); - m_tris[t->neib(b,a)]->neib(a,b) = s->neib(a,b); + btAssert(m_tris[s->neib(a, b)]->neib(b, a) == s->id); + btAssert(m_tris[t->neib(a, b)]->neib(b, a) == t->id); + m_tris[s->neib(a, b)]->neib(b, a) = t->neib(b, a); + m_tris[t->neib(b, a)]->neib(a, b) = s->neib(a, b); } } -void HullLibrary::removeb2b(btHullTriangle* s,btHullTriangle*t) +void HullLibrary::removeb2b(btHullTriangle *s, btHullTriangle *t) { - b2bfix(s,t); + b2bfix(s, t); deAllocateTriangle(s); deAllocateTriangle(t); @@ -401,11 +381,11 @@ void HullLibrary::checkit(btHullTriangle *t) (void)t; int i; - btAssert(m_tris[t->id]==t); - for(i=0;i<3;i++) + btAssert(m_tris[t->id] == t); + for (i = 0; i < 3; i++) { - int i1=(i+1)%3; - int i2=(i+2)%3; + int i1 = (i + 1) % 3; + int i2 = (i + 2) % 3; int a = (*t)[i1]; int b = (*t)[i2]; @@ -415,226 +395,233 @@ void HullLibrary::checkit(btHullTriangle *t) (void)a; (void)b; - btAssert(a!=b); - btAssert( m_tris[t->n[i]]->neib(b,a) == t->id); + btAssert(a != b); + btAssert(m_tris[t->n[i]]->neib(b, a) == t->id); } } -btHullTriangle* HullLibrary::allocateTriangle(int a,int b,int c) +btHullTriangle *HullLibrary::allocateTriangle(int a, int b, int c) { - void* mem = btAlignedAlloc(sizeof(btHullTriangle),16); - btHullTriangle* tr = new (mem)btHullTriangle(a,b,c); + void *mem = btAlignedAlloc(sizeof(btHullTriangle), 16); + btHullTriangle *tr = new (mem) btHullTriangle(a, b, c); tr->id = m_tris.size(); m_tris.push_back(tr); return tr; } -void HullLibrary::deAllocateTriangle(btHullTriangle* tri) +void HullLibrary::deAllocateTriangle(btHullTriangle *tri) { - btAssert(m_tris[tri->id]==tri); - m_tris[tri->id]=NULL; + btAssert(m_tris[tri->id] == tri); + m_tris[tri->id] = NULL; tri->~btHullTriangle(); btAlignedFree(tri); } - -void HullLibrary::extrude(btHullTriangle *t0,int v) +void HullLibrary::extrude(btHullTriangle *t0, int v) { - int3 t= *t0; + int3 t = *t0; int n = m_tris.size(); - btHullTriangle* ta = allocateTriangle(v,t[1],t[2]); - ta->n = int3(t0->n[0],n+1,n+2); - m_tris[t0->n[0]]->neib(t[1],t[2]) = n+0; - btHullTriangle* tb = allocateTriangle(v,t[2],t[0]); - tb->n = int3(t0->n[1],n+2,n+0); - m_tris[t0->n[1]]->neib(t[2],t[0]) = n+1; - btHullTriangle* tc = allocateTriangle(v,t[0],t[1]); - tc->n = int3(t0->n[2],n+0,n+1); - m_tris[t0->n[2]]->neib(t[0],t[1]) = n+2; + btHullTriangle *ta = allocateTriangle(v, t[1], t[2]); + ta->n = int3(t0->n[0], n + 1, n + 2); + m_tris[t0->n[0]]->neib(t[1], t[2]) = n + 0; + btHullTriangle *tb = allocateTriangle(v, t[2], t[0]); + tb->n = int3(t0->n[1], n + 2, n + 0); + m_tris[t0->n[1]]->neib(t[2], t[0]) = n + 1; + btHullTriangle *tc = allocateTriangle(v, t[0], t[1]); + tc->n = int3(t0->n[2], n + 0, n + 1); + m_tris[t0->n[2]]->neib(t[0], t[1]) = n + 2; checkit(ta); checkit(tb); checkit(tc); - if(hasvert(*m_tris[ta->n[0]],v)) removeb2b(ta,m_tris[ta->n[0]]); - if(hasvert(*m_tris[tb->n[0]],v)) removeb2b(tb,m_tris[tb->n[0]]); - if(hasvert(*m_tris[tc->n[0]],v)) removeb2b(tc,m_tris[tc->n[0]]); + if (hasvert(*m_tris[ta->n[0]], v)) removeb2b(ta, m_tris[ta->n[0]]); + if (hasvert(*m_tris[tb->n[0]], v)) removeb2b(tb, m_tris[tb->n[0]]); + if (hasvert(*m_tris[tc->n[0]], v)) removeb2b(tc, m_tris[tc->n[0]]); deAllocateTriangle(t0); - } -btHullTriangle* HullLibrary::extrudable(btScalar epsilon) +btHullTriangle *HullLibrary::extrudable(btScalar epsilon) { int i; - btHullTriangle *t=NULL; - for(i=0;iriserise)) + if (!t || (m_tris[i] && t->rise < m_tris[i]->rise)) { t = m_tris[i]; } } - return (t->rise >epsilon)?t:NULL ; + return (t->rise > epsilon) ? t : NULL; } - - - -int4 HullLibrary::FindSimplex(btVector3 *verts,int verts_count,btAlignedObjectArray &allow) +int4 HullLibrary::FindSimplex(btVector3 *verts, int verts_count, btAlignedObjectArray &allow) { btVector3 basis[3]; - basis[0] = btVector3( btScalar(0.01), btScalar(0.02), btScalar(1.0) ); - int p0 = maxdirsterid(verts,verts_count, basis[0],allow); - int p1 = maxdirsterid(verts,verts_count,-basis[0],allow); - basis[0] = verts[p0]-verts[p1]; - if(p0==p1 || basis[0]==btVector3(0,0,0)) - return int4(-1,-1,-1,-1); - basis[1] = btCross(btVector3( btScalar(1),btScalar(0.02), btScalar(0)),basis[0]); - basis[2] = btCross(btVector3(btScalar(-0.02), btScalar(1), btScalar(0)),basis[0]); + basis[0] = btVector3(btScalar(0.01), btScalar(0.02), btScalar(1.0)); + int p0 = maxdirsterid(verts, verts_count, basis[0], allow); + int p1 = maxdirsterid(verts, verts_count, -basis[0], allow); + basis[0] = verts[p0] - verts[p1]; + if (p0 == p1 || basis[0] == btVector3(0, 0, 0)) + return int4(-1, -1, -1, -1); + basis[1] = btCross(btVector3(btScalar(1), btScalar(0.02), btScalar(0)), basis[0]); + basis[2] = btCross(btVector3(btScalar(-0.02), btScalar(1), btScalar(0)), basis[0]); if (basis[1].length() > basis[2].length()) { basis[1].normalize(); - } else { - basis[1] = basis[2]; - basis[1].normalize (); } - int p2 = maxdirsterid(verts,verts_count,basis[1],allow); - if(p2 == p0 || p2 == p1) + else { - p2 = maxdirsterid(verts,verts_count,-basis[1],allow); + basis[1] = basis[2]; + basis[1].normalize(); } - if(p2 == p0 || p2 == p1) - return int4(-1,-1,-1,-1); + int p2 = maxdirsterid(verts, verts_count, basis[1], allow); + if (p2 == p0 || p2 == p1) + { + p2 = maxdirsterid(verts, verts_count, -basis[1], allow); + } + if (p2 == p0 || p2 == p1) + return int4(-1, -1, -1, -1); basis[1] = verts[p2] - verts[p0]; - basis[2] = btCross(basis[1],basis[0]).normalized(); - int p3 = maxdirsterid(verts,verts_count,basis[2],allow); - if(p3==p0||p3==p1||p3==p2) p3 = maxdirsterid(verts,verts_count,-basis[2],allow); - if(p3==p0||p3==p1||p3==p2) - return int4(-1,-1,-1,-1); - btAssert(!(p0==p1||p0==p2||p0==p3||p1==p2||p1==p3||p2==p3)); - if(btDot(verts[p3]-verts[p0],btCross(verts[p1]-verts[p0],verts[p2]-verts[p0])) <0) {btSwap(p2,p3);} - return int4(p0,p1,p2,p3); + basis[2] = btCross(basis[1], basis[0]).normalized(); + int p3 = maxdirsterid(verts, verts_count, basis[2], allow); + if (p3 == p0 || p3 == p1 || p3 == p2) p3 = maxdirsterid(verts, verts_count, -basis[2], allow); + if (p3 == p0 || p3 == p1 || p3 == p2) + return int4(-1, -1, -1, -1); + btAssert(!(p0 == p1 || p0 == p2 || p0 == p3 || p1 == p2 || p1 == p3 || p2 == p3)); + if (btDot(verts[p3] - verts[p0], btCross(verts[p1] - verts[p0], verts[p2] - verts[p0])) < 0) + { + btSwap(p2, p3); + } + return int4(p0, p1, p2, p3); } -int HullLibrary::calchullgen(btVector3 *verts,int verts_count, int vlimit) +int HullLibrary::calchullgen(btVector3 *verts, int verts_count, int vlimit) { - if(verts_count <4) return 0; - if(vlimit==0) vlimit=1000000000; + if (verts_count < 4) return 0; + if (vlimit == 0) vlimit = 1000000000; int j; - btVector3 bmin(*verts),bmax(*verts); + btVector3 bmin(*verts), bmax(*verts); btAlignedObjectArray isextreme; isextreme.reserve(verts_count); btAlignedObjectArray allow; allow.reserve(verts_count); - for(j=0;jn = int3(2, 3, 1); + btHullTriangle *t1 = allocateTriangle(p[3], p[2], p[0]); + t1->n = int3(3, 2, 0); + btHullTriangle *t2 = allocateTriangle(p[0], p[1], p[3]); + t2->n = int3(0, 1, 3); + btHullTriangle *t3 = allocateTriangle(p[1], p[0], p[2]); + t3->n = int3(1, 0, 2); + isextreme[p[0]] = isextreme[p[1]] = isextreme[p[2]] = isextreme[p[3]] = 1; + checkit(t0); + checkit(t1); + checkit(t2); + checkit(t3); - - - btVector3 center = (verts[p[0]]+verts[p[1]]+verts[p[2]]+verts[p[3]]) / btScalar(4.0); // a valid interior point - btHullTriangle *t0 = allocateTriangle(p[2],p[3],p[1]); t0->n=int3(2,3,1); - btHullTriangle *t1 = allocateTriangle(p[3],p[2],p[0]); t1->n=int3(3,2,0); - btHullTriangle *t2 = allocateTriangle(p[0],p[1],p[3]); t2->n=int3(0,1,3); - btHullTriangle *t3 = allocateTriangle(p[1],p[0],p[2]); t3->n=int3(1,0,2); - isextreme[p[0]]=isextreme[p[1]]=isextreme[p[2]]=isextreme[p[3]]=1; - checkit(t0);checkit(t1);checkit(t2);checkit(t3); - - for(j=0;jvmax<0); - btVector3 n=TriNormal(verts[(*t)[0]],verts[(*t)[1]],verts[(*t)[2]]); - t->vmax = maxdirsterid(verts,verts_count,n,allow); - t->rise = btDot(n,verts[t->vmax]-verts[(*t)[0]]); + btAssert(t->vmax < 0); + btVector3 n = TriNormal(verts[(*t)[0]], verts[(*t)[1]], verts[(*t)[2]]); + t->vmax = maxdirsterid(verts, verts_count, n, allow); + t->rise = btDot(n, verts[t->vmax] - verts[(*t)[0]]); } btHullTriangle *te; - vlimit-=4; - while(vlimit >0 && ((te=extrudable(epsilon)) != 0)) + vlimit -= 4; + while (vlimit > 0 && ((te = extrudable(epsilon)) != 0)) { //int3 ti=*te; - int v=te->vmax; + int v = te->vmax; btAssert(v != -1); btAssert(!isextreme[v]); // wtf we've already done this vertex - isextreme[v]=1; + isextreme[v] = 1; //if(v==p0 || v==p1 || v==p2 || v==p3) continue; // done these already - j=m_tris.size(); - while(j--) { - if(!m_tris[j]) continue; - int3 t=*m_tris[j]; - if(above(verts,t,verts[v],btScalar(0.01)*epsilon)) + j = m_tris.size(); + while (j--) + { + if (!m_tris[j]) continue; + int3 t = *m_tris[j]; + if (above(verts, t, verts[v], btScalar(0.01) * epsilon)) { - extrude(m_tris[j],v); + extrude(m_tris[j], v); } } // now check for those degenerate cases where we have a flipped triangle or a really skinny triangle - j=m_tris.size(); - while(j--) + j = m_tris.size(); + while (j--) { - if(!m_tris[j]) continue; - if(!hasvert(*m_tris[j],v)) break; - int3 nt=*m_tris[j]; - if(above(verts,nt,center,btScalar(0.01)*epsilon) || btCross(verts[nt[1]]-verts[nt[0]],verts[nt[2]]-verts[nt[1]]).length()< epsilon*epsilon*btScalar(0.1) ) + if (!m_tris[j]) continue; + if (!hasvert(*m_tris[j], v)) break; + int3 nt = *m_tris[j]; + if (above(verts, nt, center, btScalar(0.01) * epsilon) || btCross(verts[nt[1]] - verts[nt[0]], verts[nt[2]] - verts[nt[1]]).length() < epsilon * epsilon * btScalar(0.1)) { btHullTriangle *nb = m_tris[m_tris[j]->n[0]]; - btAssert(nb);btAssert(!hasvert(*nb,v));btAssert(nb->idid < j); + extrude(nb, v); + j = m_tris.size(); } - } - j=m_tris.size(); - while(j--) + } + j = m_tris.size(); + while (j--) { - btHullTriangle *t=m_tris[j]; - if(!t) continue; - if(t->vmax>=0) break; - btVector3 n=TriNormal(verts[(*t)[0]],verts[(*t)[1]],verts[(*t)[2]]); - t->vmax = maxdirsterid(verts,verts_count,n,allow); - if(isextreme[t->vmax]) + btHullTriangle *t = m_tris[j]; + if (!t) continue; + if (t->vmax >= 0) break; + btVector3 n = TriNormal(verts[(*t)[0]], verts[(*t)[1]], verts[(*t)[2]]); + t->vmax = maxdirsterid(verts, verts_count, n, allow); + if (isextreme[t->vmax]) { - t->vmax=-1; // already done that vertex - algorithm needs to be able to terminate. + t->vmax = -1; // already done that vertex - algorithm needs to be able to terminate. } else { - t->rise = btDot(n,verts[t->vmax]-verts[(*t)[0]]); + t->rise = btDot(n, verts[t->vmax] - verts[(*t)[0]]); } } - vlimit --; + vlimit--; } return 1; } -int HullLibrary::calchull(btVector3 *verts,int verts_count, TUIntArray& tris_out, int &tris_count,int vlimit) +int HullLibrary::calchull(btVector3 *verts, int verts_count, TUIntArray &tris_out, int &tris_count, int vlimit) { - int rc=calchullgen(verts,verts_count, vlimit) ; - if(!rc) return 0; + int rc = calchullgen(verts, verts_count, vlimit); + if (!rc) return 0; btAlignedObjectArray ts; int i; - for(i=0;i(ts[i]); } @@ -643,29 +630,22 @@ int HullLibrary::calchull(btVector3 *verts,int verts_count, TUIntArray& tris_out return 1; } - - - - -bool HullLibrary::ComputeHull(unsigned int vcount,const btVector3 *vertices,PHullResult &result,unsigned int vlimit) +bool HullLibrary::ComputeHull(unsigned int vcount, const btVector3 *vertices, PHullResult &result, unsigned int vlimit) { - - int tris_count; - int ret = calchull( (btVector3 *) vertices, (int) vcount, result.m_Indices, tris_count, static_cast(vlimit) ); - if(!ret) return false; - result.mIndexCount = (unsigned int) (tris_count*3); - result.mFaceCount = (unsigned int) tris_count; - result.mVertices = (btVector3*) vertices; - result.mVcount = (unsigned int) vcount; + int tris_count; + int ret = calchull((btVector3 *)vertices, (int)vcount, result.m_Indices, tris_count, static_cast(vlimit)); + if (!ret) return false; + result.mIndexCount = (unsigned int)(tris_count * 3); + result.mFaceCount = (unsigned int)tris_count; + result.mVertices = (btVector3 *)vertices; + result.mVcount = (unsigned int)vcount; return true; - } - void ReleaseHull(PHullResult &result); void ReleaseHull(PHullResult &result) { - if ( result.m_Indices.size() ) + if (result.m_Indices.size()) { result.m_Indices.clear(); } @@ -675,7 +655,6 @@ void ReleaseHull(PHullResult &result) result.mVertices = 0; } - //********************************************************************* //********************************************************************* //******** HullLib header @@ -688,16 +667,15 @@ void ReleaseHull(PHullResult &result) //********************************************************************* //********************************************************************* -HullError HullLibrary::CreateConvexHull(const HullDesc &desc, // describes the input request - HullResult &result) // contains the resulst +HullError HullLibrary::CreateConvexHull(const HullDesc &desc, // describes the input request + HullResult &result) // contains the resulst { HullError ret = QE_FAIL; - PHullResult hr; unsigned int vcount = desc.mVcount; - if ( vcount < 8 ) vcount = 8; + if (vcount < 8) vcount = 8; btAlignedObjectArray vertexSource; vertexSource.resize(static_cast(vcount)); @@ -706,87 +684,82 @@ HullError HullLibrary::CreateConvexHull(const HullDesc &desc, // unsigned int ovcount; - bool ok = CleanupVertices(desc.mVcount,desc.mVertices, desc.mVertexStride, ovcount, &vertexSource[0], desc.mNormalEpsilon, scale ); // normalize point cloud, remove duplicates! + bool ok = CleanupVertices(desc.mVcount, desc.mVertices, desc.mVertexStride, ovcount, &vertexSource[0], desc.mNormalEpsilon, scale); // normalize point cloud, remove duplicates! - if ( ok ) + if (ok) { - - -// if ( 1 ) // scale vertices back to their original size. + // if ( 1 ) // scale vertices back to their original size. { - for (unsigned int i=0; i(i)]; - v[0]*=scale[0]; - v[1]*=scale[1]; - v[2]*=scale[2]; + btVector3 &v = vertexSource[static_cast(i)]; + v[0] *= scale[0]; + v[1] *= scale[1]; + v[2] *= scale[2]; } } - ok = ComputeHull(ovcount,&vertexSource[0],hr,desc.mMaxVertices); + ok = ComputeHull(ovcount, &vertexSource[0], hr, desc.mMaxVertices); - if ( ok ) + if (ok) { - // re-index triangle mesh so it refers to only used vertices, rebuild a new vertex table. - btAlignedObjectArray vertexScratch; + btAlignedObjectArray vertexScratch; vertexScratch.resize(static_cast(hr.mVcount)); - BringOutYourDead(hr.mVertices,hr.mVcount, &vertexScratch[0], ovcount, &hr.m_Indices[0], hr.mIndexCount ); + BringOutYourDead(hr.mVertices, hr.mVcount, &vertexScratch[0], ovcount, &hr.m_Indices[0], hr.mIndexCount); ret = QE_OK; - if ( desc.HasHullFlag(QF_TRIANGLES) ) // if he wants the results as triangle! + if (desc.HasHullFlag(QF_TRIANGLES)) // if he wants the results as triangle! { - result.mPolygons = false; + result.mPolygons = false; result.mNumOutputVertices = ovcount; result.m_OutputVertices.resize(static_cast(ovcount)); - result.mNumFaces = hr.mFaceCount; - result.mNumIndices = hr.mIndexCount; + result.mNumFaces = hr.mFaceCount; + result.mNumIndices = hr.mIndexCount; result.m_Indices.resize(static_cast(hr.mIndexCount)); - memcpy(&result.m_OutputVertices[0], &vertexScratch[0], sizeof(btVector3)*ovcount ); + memcpy(&result.m_OutputVertices[0], &vertexScratch[0], sizeof(btVector3) * ovcount); - if ( desc.HasHullFlag(QF_REVERSE_ORDER) ) + if (desc.HasHullFlag(QF_REVERSE_ORDER)) { - const unsigned int *source = &hr.m_Indices[0]; - unsigned int *dest = &result.m_Indices[0]; + unsigned int *dest = &result.m_Indices[0]; - for (unsigned int i=0; i(ovcount)); - result.mNumFaces = hr.mFaceCount; - result.mNumIndices = hr.mIndexCount+hr.mFaceCount; + result.mNumFaces = hr.mFaceCount; + result.mNumIndices = hr.mIndexCount + hr.mFaceCount; result.m_Indices.resize(static_cast(result.mNumIndices)); - memcpy(&result.m_OutputVertices[0], &vertexScratch[0], sizeof(btVector3)*ovcount ); + memcpy(&result.m_OutputVertices[0], &vertexScratch[0], sizeof(btVector3) * ovcount); -// if ( 1 ) + // if ( 1 ) { const unsigned int *source = &hr.m_Indices[0]; - unsigned int *dest = &result.m_Indices[0]; - for (unsigned int i=0; i bmax[j] ) bmax[j] = p[j]; + if (p[j] < bmin[j]) bmin[j] = p[j]; + if (p[j] > bmax[j]) bmax[j] = p[j]; } } } @@ -905,28 +871,27 @@ bool HullLibrary::CleanupVertices(unsigned int svcount, btVector3 center; - center[0] = dx*btScalar(0.5) + bmin[0]; - center[1] = dy*btScalar(0.5) + bmin[1]; - center[2] = dz*btScalar(0.5) + bmin[2]; + center[0] = dx * btScalar(0.5) + bmin[0]; + center[1] = dy * btScalar(0.5) + bmin[1]; + center[2] = dz * btScalar(0.5) + bmin[2]; - if ( dx < EPSILON || dy < EPSILON || dz < EPSILON || svcount < 3 ) + if (dx < EPSILON || dy < EPSILON || dz < EPSILON || svcount < 3) { - btScalar len = FLT_MAX; - if ( dx > EPSILON && dx < len ) len = dx; - if ( dy > EPSILON && dy < len ) len = dy; - if ( dz > EPSILON && dz < len ) len = dz; + if (dx > EPSILON && dx < len) len = dx; + if (dy > EPSILON && dy < len) len = dy; + if (dz > EPSILON && dz < len) len = dz; - if ( len == FLT_MAX ) + if (len == FLT_MAX) { - dx = dy = dz = btScalar(0.01); // one centimeter + dx = dy = dz = btScalar(0.01); // one centimeter } else { - if ( dx < EPSILON ) dx = len * btScalar(0.05); // 1/5th the shortest non-zero edge. - if ( dy < EPSILON ) dy = len * btScalar(0.05); - if ( dz < EPSILON ) dz = len * btScalar(0.05); + if (dx < EPSILON) dx = len * btScalar(0.05); // 1/5th the shortest non-zero edge. + if (dy < EPSILON) dy = len * btScalar(0.05); + if (dz < EPSILON) dz = len * btScalar(0.05); } btScalar x1 = center[0] - dx; @@ -938,22 +903,20 @@ bool HullLibrary::CleanupVertices(unsigned int svcount, btScalar z1 = center[2] - dz; btScalar z2 = center[2] + dz; - addPoint(vcount,vertices,x1,y1,z1); - addPoint(vcount,vertices,x2,y1,z1); - addPoint(vcount,vertices,x2,y2,z1); - addPoint(vcount,vertices,x1,y2,z1); - addPoint(vcount,vertices,x1,y1,z2); - addPoint(vcount,vertices,x2,y1,z2); - addPoint(vcount,vertices,x2,y2,z2); - addPoint(vcount,vertices,x1,y2,z2); - - return true; // return cube - + addPoint(vcount, vertices, x1, y1, z1); + addPoint(vcount, vertices, x2, y1, z1); + addPoint(vcount, vertices, x2, y2, z1); + addPoint(vcount, vertices, x1, y2, z1); + addPoint(vcount, vertices, x1, y1, z2); + addPoint(vcount, vertices, x2, y1, z2); + addPoint(vcount, vertices, x2, y2, z2); + addPoint(vcount, vertices, x1, y2, z2); + return true; // return cube } else { - if ( scale ) + if (scale) { scale[0] = dx; scale[1] = dy; @@ -963,75 +926,70 @@ bool HullLibrary::CleanupVertices(unsigned int svcount, recip[1] = 1 / dy; recip[2] = 1 / dz; - center[0]*=recip[0]; - center[1]*=recip[1]; - center[2]*=recip[2]; - + center[0] *= recip[0]; + center[1] *= recip[1]; + center[2] *= recip[2]; } - } + vtx = (const char *)svertices; - - vtx = (const char *) svertices; - - for (unsigned int i=0; igetX(); btScalar py = p->getY(); btScalar pz = p->getZ(); - if ( scale ) + if (scale) { - px = px*recip[0]; // normalize - py = py*recip[1]; // normalize - pz = pz*recip[2]; // normalize + px = px * recip[0]; // normalize + py = py * recip[1]; // normalize + pz = pz * recip[2]; // normalize } -// if ( 1 ) + // if ( 1 ) { unsigned int j; - for (j=0; j dist2 ) + if (dist1 > dist2) { v[0] = px; v[1] = py; v[2] = pz; - } break; } } - if ( j == vcount ) + if (j == vcount) { - btVector3& dest = vertices[vcount]; + btVector3 &dest = vertices[vcount]; dest[0] = px; dest[1] = py; dest[2] = pz; @@ -1042,18 +1000,18 @@ bool HullLibrary::CleanupVertices(unsigned int svcount, } // ok..now make sure we didn't prune so many vertices it is now invalid. -// if ( 1 ) + // if ( 1 ) { - btScalar bmin[3] = { FLT_MAX, FLT_MAX, FLT_MAX }; - btScalar bmax[3] = { -FLT_MAX, -FLT_MAX, -FLT_MAX }; + btScalar bmin[3] = {FLT_MAX, FLT_MAX, FLT_MAX}; + btScalar bmax[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}; - for (unsigned int i=0; i bmax[j] ) bmax[j] = p[j]; + if (p[j] < bmin[j]) bmin[j] = p[j]; + if (p[j] > bmax[j]) bmax[j] = p[j]; } } @@ -1061,27 +1019,27 @@ bool HullLibrary::CleanupVertices(unsigned int svcount, btScalar dy = bmax[1] - bmin[1]; btScalar dz = bmax[2] - bmin[2]; - if ( dx < EPSILON || dy < EPSILON || dz < EPSILON || vcount < 3) + if (dx < EPSILON || dy < EPSILON || dz < EPSILON || vcount < 3) { - btScalar cx = dx*btScalar(0.5) + bmin[0]; - btScalar cy = dy*btScalar(0.5) + bmin[1]; - btScalar cz = dz*btScalar(0.5) + bmin[2]; + btScalar cx = dx * btScalar(0.5) + bmin[0]; + btScalar cy = dy * btScalar(0.5) + bmin[1]; + btScalar cz = dz * btScalar(0.5) + bmin[2]; btScalar len = FLT_MAX; - if ( dx >= EPSILON && dx < len ) len = dx; - if ( dy >= EPSILON && dy < len ) len = dy; - if ( dz >= EPSILON && dz < len ) len = dz; + if (dx >= EPSILON && dx < len) len = dx; + if (dy >= EPSILON && dy < len) len = dy; + if (dz >= EPSILON && dz < len) len = dz; - if ( len == FLT_MAX ) + if (len == FLT_MAX) { - dx = dy = dz = btScalar(0.01); // one centimeter + dx = dy = dz = btScalar(0.01); // one centimeter } else { - if ( dx < EPSILON ) dx = len * btScalar(0.05); // 1/5th the shortest non-zero edge. - if ( dy < EPSILON ) dy = len * btScalar(0.05); - if ( dz < EPSILON ) dz = len * btScalar(0.05); + if (dx < EPSILON) dx = len * btScalar(0.05); // 1/5th the shortest non-zero edge. + if (dy < EPSILON) dy = len * btScalar(0.05); + if (dz < EPSILON) dz = len * btScalar(0.05); } btScalar x1 = cx - dx; @@ -1093,16 +1051,16 @@ bool HullLibrary::CleanupVertices(unsigned int svcount, btScalar z1 = cz - dz; btScalar z2 = cz + dz; - vcount = 0; // add box + vcount = 0; // add box - addPoint(vcount,vertices,x1,y1,z1); - addPoint(vcount,vertices,x2,y1,z1); - addPoint(vcount,vertices,x2,y2,z1); - addPoint(vcount,vertices,x1,y2,z1); - addPoint(vcount,vertices,x1,y1,z2); - addPoint(vcount,vertices,x2,y1,z2); - addPoint(vcount,vertices,x2,y2,z2); - addPoint(vcount,vertices,x1,y2,z2); + addPoint(vcount, vertices, x1, y1, z1); + addPoint(vcount, vertices, x2, y1, z1); + addPoint(vcount, vertices, x2, y2, z1); + addPoint(vcount, vertices, x1, y2, z1); + addPoint(vcount, vertices, x1, y1, z2); + addPoint(vcount, vertices, x2, y1, z2); + addPoint(vcount, vertices, x2, y2, z2); + addPoint(vcount, vertices, x1, y2, z2); return true; } @@ -1111,57 +1069,52 @@ bool HullLibrary::CleanupVertices(unsigned int svcount, return true; } -void HullLibrary::BringOutYourDead(const btVector3* verts,unsigned int vcount, btVector3* overts,unsigned int &ocount,unsigned int *indices,unsigned indexcount) +void HullLibrary::BringOutYourDead(const btVector3 *verts, unsigned int vcount, btVector3 *overts, unsigned int &ocount, unsigned int *indices, unsigned indexcount) { - btAlignedObjectArraytmpIndices; + btAlignedObjectArray tmpIndices; tmpIndices.resize(m_vertexIndexMapping.size()); int i; - for (i=0;i(vcount)); - memset(&usedIndices[0],0,sizeof(unsigned int)*vcount); + memset(&usedIndices[0], 0, sizeof(unsigned int) * vcount); ocount = 0; - for (i=0; i= 0 && v < vcount ); + btAssert(v >= 0 && v < vcount); - if ( usedIndices[static_cast(v)] ) // if already remapped + if (usedIndices[static_cast(v)]) // if already remapped { - indices[i] = usedIndices[static_cast(v)]-1; // index to new array + indices[i] = usedIndices[static_cast(v)] - 1; // index to new array } else { + indices[i] = ocount; // new index mapping - indices[i] = ocount; // new index mapping - - overts[ocount][0] = verts[v][0]; // copy old vert to new vert array + overts[ocount][0] = verts[v][0]; // copy old vert to new vert array overts[ocount][1] = verts[v][1]; overts[ocount][2] = verts[v][2]; - for (int k=0;k=0 && ocount <= vcount ); + btAssert(ocount >= 0 && ocount <= vcount); - usedIndices[static_cast(v)] = ocount; // assign new index remapping - - + usedIndices[static_cast(v)] = ocount; // assign new index remapping } } - - } diff --git a/src/LinearMath/btConvexHull.h b/src/LinearMath/btConvexHull.h index 69c52bc6f..f890d75ea 100644 --- a/src/LinearMath/btConvexHull.h +++ b/src/LinearMath/btConvexHull.h @@ -34,106 +34,102 @@ public: mNumFaces = 0; mNumIndices = 0; } - bool mPolygons; // true if indices represents polygons, false indices are triangles - unsigned int mNumOutputVertices; // number of vertices in the output hull - btAlignedObjectArray m_OutputVertices; // array of vertices - unsigned int mNumFaces; // the number of faces produced - unsigned int mNumIndices; // the total number of indices - btAlignedObjectArray m_Indices; // pointer to indices. + bool mPolygons; // true if indices represents polygons, false indices are triangles + unsigned int mNumOutputVertices; // number of vertices in the output hull + btAlignedObjectArray m_OutputVertices; // array of vertices + unsigned int mNumFaces; // the number of faces produced + unsigned int mNumIndices; // the total number of indices + btAlignedObjectArray m_Indices; // pointer to indices. -// If triangles, then indices are array indexes into the vertex list. -// If polygons, indices are in the form (number of points in face) (p1, p2, p3, ..) etc.. + // If triangles, then indices are array indexes into the vertex list. + // If polygons, indices are in the form (number of points in face) (p1, p2, p3, ..) etc.. }; enum HullFlag { - QF_TRIANGLES = (1<<0), // report results as triangles, not polygons. - QF_REVERSE_ORDER = (1<<1), // reverse order of the triangle indices. - QF_DEFAULT = QF_TRIANGLES + QF_TRIANGLES = (1 << 0), // report results as triangles, not polygons. + QF_REVERSE_ORDER = (1 << 1), // reverse order of the triangle indices. + QF_DEFAULT = QF_TRIANGLES }; - class HullDesc { public: HullDesc(void) { - mFlags = QF_DEFAULT; - mVcount = 0; - mVertices = 0; - mVertexStride = sizeof(btVector3); - mNormalEpsilon = 0.001f; - mMaxVertices = 4096; // maximum number of points to be considered for a convex hull. - mMaxFaces = 4096; + mFlags = QF_DEFAULT; + mVcount = 0; + mVertices = 0; + mVertexStride = sizeof(btVector3); + mNormalEpsilon = 0.001f; + mMaxVertices = 4096; // maximum number of points to be considered for a convex hull. + mMaxFaces = 4096; }; HullDesc(HullFlag flag, - unsigned int vcount, - const btVector3 *vertices, - unsigned int stride = sizeof(btVector3)) + unsigned int vcount, + const btVector3* vertices, + unsigned int stride = sizeof(btVector3)) { - mFlags = flag; - mVcount = vcount; - mVertices = vertices; - mVertexStride = stride; - mNormalEpsilon = btScalar(0.001); - mMaxVertices = 4096; + mFlags = flag; + mVcount = vcount; + mVertices = vertices; + mVertexStride = stride; + mNormalEpsilon = btScalar(0.001); + mMaxVertices = 4096; } bool HasHullFlag(HullFlag flag) const { - if ( mFlags & flag ) return true; + if (mFlags & flag) return true; return false; } void SetHullFlag(HullFlag flag) { - mFlags|=flag; + mFlags |= flag; } void ClearHullFlag(HullFlag flag) { - mFlags&=~flag; + mFlags &= ~flag; } - unsigned int mFlags; // flags to use when generating the convex hull. - unsigned int mVcount; // number of vertices in the input point cloud - const btVector3 *mVertices; // the array of vertices. - unsigned int mVertexStride; // the stride of each vertex, in bytes. - btScalar mNormalEpsilon; // the epsilon for removing duplicates. This is a normalized value, if normalized bit is on. - unsigned int mMaxVertices; // maximum number of vertices to be considered for the hull! - unsigned int mMaxFaces; + unsigned int mFlags; // flags to use when generating the convex hull. + unsigned int mVcount; // number of vertices in the input point cloud + const btVector3* mVertices; // the array of vertices. + unsigned int mVertexStride; // the stride of each vertex, in bytes. + btScalar mNormalEpsilon; // the epsilon for removing duplicates. This is a normalized value, if normalized bit is on. + unsigned int mMaxVertices; // maximum number of vertices to be considered for the hull! + unsigned int mMaxFaces; }; enum HullError { - QE_OK, // success! - QE_FAIL // failed. + QE_OK, // success! + QE_FAIL // failed. }; class btPlane { - public: - btVector3 normal; - btScalar dist; // distance below origin - the D from plane equasion Ax+By+Cz+D=0 - btPlane(const btVector3 &n,btScalar d):normal(n),dist(d){} - btPlane():normal(),dist(0){} - +public: + btVector3 normal; + btScalar dist; // distance below origin - the D from plane equasion Ax+By+Cz+D=0 + btPlane(const btVector3& n, btScalar d) : normal(n), dist(d) {} + btPlane() : normal(), dist(0) {} }; - - -class ConvexH +class ConvexH { - public: +public: class HalfEdge { - public: + public: short ea; // the other half of the edge (index into edges list) unsigned char v; // the vertex at the start of this edge (index into vertices list) unsigned char p; // the facet on which this edge lies (index into facets list) - HalfEdge(){} - HalfEdge(short _ea,unsigned char _v, unsigned char _p):ea(_ea),v(_v),p(_p){} + HalfEdge() {} + HalfEdge(short _ea, unsigned char _v, unsigned char _p) : ea(_ea), v(_v), p(_p) {} }; ConvexH() { @@ -143,25 +139,29 @@ class ConvexH } btAlignedObjectArray vertices; btAlignedObjectArray edges; - btAlignedObjectArray facets; - ConvexH(int vertices_size,int edges_size,int facets_size); + btAlignedObjectArray facets; + ConvexH(int vertices_size, int edges_size, int facets_size); }; - class int4 { public: - int x,y,z,w; + int x, y, z, w; int4(){}; - int4(int _x,int _y, int _z,int _w){x=_x;y=_y;z=_z;w=_w;} - const int& operator[](int i) const {return (&x)[i];} - int& operator[](int i) {return (&x)[i];} + int4(int _x, int _y, int _z, int _w) + { + x = _x; + y = _y; + z = _z; + w = _w; + } + const int& operator[](int i) const { return (&x)[i]; } + int& operator[](int i) { return (&x)[i]; } }; class PHullResult { public: - PHullResult(void) { mVcount = 0; @@ -173,69 +173,61 @@ public: unsigned int mVcount; unsigned int mIndexCount; unsigned int mFaceCount; - btVector3* mVertices; + btVector3* mVertices; TUIntArray m_Indices; }; - - ///The HullLibrary class can create a convex hull from a collection of vertices, using the ComputeHull method. ///The btShapeHull class uses this HullLibrary to create a approximate convex mesh given a general (non-polyhedral) convex shape. class HullLibrary { - btAlignedObjectArray m_tris; public: - btAlignedObjectArray m_vertexIndexMapping; - - HullError CreateConvexHull(const HullDesc& desc, // describes the input request - HullResult& result); // contains the resulst - HullError ReleaseResult(HullResult &result); // release memory allocated for this result, we are done with it. + HullError CreateConvexHull(const HullDesc& desc, // describes the input request + HullResult& result); // contains the resulst + HullError ReleaseResult(HullResult& result); // release memory allocated for this result, we are done with it. private: + bool ComputeHull(unsigned int vcount, const btVector3* vertices, PHullResult& result, unsigned int vlimit); - bool ComputeHull(unsigned int vcount,const btVector3 *vertices,PHullResult &result,unsigned int vlimit); + class btHullTriangle* allocateTriangle(int a, int b, int c); + void deAllocateTriangle(btHullTriangle*); + void b2bfix(btHullTriangle* s, btHullTriangle* t); - class btHullTriangle* allocateTriangle(int a,int b,int c); - void deAllocateTriangle(btHullTriangle*); - void b2bfix(btHullTriangle* s,btHullTriangle*t); + void removeb2b(btHullTriangle* s, btHullTriangle* t); - void removeb2b(btHullTriangle* s,btHullTriangle*t); - - void checkit(btHullTriangle *t); + void checkit(btHullTriangle* t); btHullTriangle* extrudable(btScalar epsilon); - int calchull(btVector3 *verts,int verts_count, TUIntArray& tris_out, int &tris_count,int vlimit); + int calchull(btVector3* verts, int verts_count, TUIntArray& tris_out, int& tris_count, int vlimit); - int calchullgen(btVector3 *verts,int verts_count, int vlimit); + int calchullgen(btVector3* verts, int verts_count, int vlimit); - int4 FindSimplex(btVector3 *verts,int verts_count,btAlignedObjectArray &allow); + int4 FindSimplex(btVector3* verts, int verts_count, btAlignedObjectArray& allow); - class ConvexH* ConvexHCrop(ConvexH& convex,const btPlane& slice); + class ConvexH* ConvexHCrop(ConvexH& convex, const btPlane& slice); - void extrude(class btHullTriangle* t0,int v); + void extrude(class btHullTriangle* t0, int v); ConvexH* test_cube(); - //BringOutYourDead (John Ratcliff): When you create a convex hull you hand it a large input set of vertices forming a 'point cloud'. + //BringOutYourDead (John Ratcliff): When you create a convex hull you hand it a large input set of vertices forming a 'point cloud'. //After the hull is generated it give you back a set of polygon faces which index the *original* point cloud. //The thing is, often times, there are many 'dead vertices' in the point cloud that are on longer referenced by the hull. //The routine 'BringOutYourDead' find only the referenced vertices, copies them to an new buffer, and re-indexes the hull so that it is a minimal representation. - void BringOutYourDead(const btVector3* verts,unsigned int vcount, btVector3* overts,unsigned int &ocount,unsigned int* indices,unsigned indexcount); + void BringOutYourDead(const btVector3* verts, unsigned int vcount, btVector3* overts, unsigned int& ocount, unsigned int* indices, unsigned indexcount); bool CleanupVertices(unsigned int svcount, - const btVector3* svertices, - unsigned int stride, - unsigned int &vcount, // output number of vertices - btVector3* vertices, // location to store the results. - btScalar normalepsilon, - btVector3& scale); + const btVector3* svertices, + unsigned int stride, + unsigned int& vcount, // output number of vertices + btVector3* vertices, // location to store the results. + btScalar normalepsilon, + btVector3& scale); }; - -#endif //BT_CD_HULL_H - +#endif //BT_CD_HULL_H diff --git a/src/LinearMath/btConvexHullComputer.cpp b/src/LinearMath/btConvexHullComputer.cpp index 2ea22cbe3..df4ad0629 100644 --- a/src/LinearMath/btConvexHullComputer.cpp +++ b/src/LinearMath/btConvexHullComputer.cpp @@ -20,846 +20,847 @@ subject to the following restrictions: #include "btVector3.h" #ifdef __GNUC__ - #include +#include #elif defined(_MSC_VER) - typedef __int32 int32_t; - typedef __int64 int64_t; - typedef unsigned __int32 uint32_t; - typedef unsigned __int64 uint64_t; +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; #else - typedef int int32_t; - typedef long long int int64_t; - typedef unsigned int uint32_t; - typedef unsigned long long int uint64_t; +typedef int int32_t; +typedef long long int int64_t; +typedef unsigned int uint32_t; +typedef unsigned long long int uint64_t; #endif - //The definition of USE_X86_64_ASM is moved into the build system. You can enable it manually by commenting out the following lines //#if (defined(__GNUC__) && defined(__x86_64__) && !defined(__ICL)) // || (defined(__ICL) && defined(_M_X64)) bug in Intel compiler, disable inline assembly // #define USE_X86_64_ASM //#endif - //#define DEBUG_CONVEX_HULL //#define SHOW_ITERATIONS #if defined(DEBUG_CONVEX_HULL) || defined(SHOW_ITERATIONS) - #include +#include #endif // Convex hull implementation based on Preparata and Hong // Ole Kniemeyer, MAXON Computer GmbH class btConvexHullInternal { +public: + class Point64 + { public: - - class Point64 + int64_t x; + int64_t y; + int64_t z; + + Point64(int64_t x, int64_t y, int64_t z) : x(x), y(y), z(z) { - public: - int64_t x; - int64_t y; - int64_t z; - - Point64(int64_t x, int64_t y, int64_t z): x(x), y(y), z(z) - { - } - - bool isZero() - { - return (x == 0) && (y == 0) && (z == 0); - } - - int64_t dot(const Point64& b) const - { - return x * b.x + y * b.y + z * b.z; - } - }; - - class Point32 - { - public: - int32_t x; - int32_t y; - int32_t z; - int index; - - Point32() - { - } - - Point32(int32_t x, int32_t y, int32_t z): x(x), y(y), z(z), index(-1) - { - } - - bool operator==(const Point32& b) const - { - return (x == b.x) && (y == b.y) && (z == b.z); - } - - bool operator!=(const Point32& b) const - { - return (x != b.x) || (y != b.y) || (z != b.z); - } - - bool isZero() - { - return (x == 0) && (y == 0) && (z == 0); - } - - Point64 cross(const Point32& b) const - { - return Point64(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); - } - - Point64 cross(const Point64& b) const - { - return Point64(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); - } - - int64_t dot(const Point32& b) const - { - return x * b.x + y * b.y + z * b.z; - } - - int64_t dot(const Point64& b) const - { - return x * b.x + y * b.y + z * b.z; - } - - Point32 operator+(const Point32& b) const - { - return Point32(x + b.x, y + b.y, z + b.z); - } - - Point32 operator-(const Point32& b) const - { - return Point32(x - b.x, y - b.y, z - b.z); - } - }; - - class Int128 - { - public: - uint64_t low; - uint64_t high; - - Int128() - { - } - - Int128(uint64_t low, uint64_t high): low(low), high(high) - { - } - - Int128(uint64_t low): low(low), high(0) - { - } - - Int128(int64_t value): low(value), high((value >= 0) ? 0 : (uint64_t) -1LL) - { - } - - static Int128 mul(int64_t a, int64_t b); - - static Int128 mul(uint64_t a, uint64_t b); - - Int128 operator-() const - { - return Int128((uint64_t) -(int64_t)low, ~high + (low == 0)); - } - - Int128 operator+(const Int128& b) const - { -#ifdef USE_X86_64_ASM - Int128 result; - __asm__ ("addq %[bl], %[rl]\n\t" - "adcq %[bh], %[rh]\n\t" - : [rl] "=r" (result.low), [rh] "=r" (result.high) - : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) - : "cc" ); - return result; -#else - uint64_t lo = low + b.low; - return Int128(lo, high + b.high + (lo < low)); -#endif - } - - Int128 operator-(const Int128& b) const - { -#ifdef USE_X86_64_ASM - Int128 result; - __asm__ ("subq %[bl], %[rl]\n\t" - "sbbq %[bh], %[rh]\n\t" - : [rl] "=r" (result.low), [rh] "=r" (result.high) - : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) - : "cc" ); - return result; -#else - return *this + -b; -#endif - } - - Int128& operator+=(const Int128& b) - { -#ifdef USE_X86_64_ASM - __asm__ ("addq %[bl], %[rl]\n\t" - "adcq %[bh], %[rh]\n\t" - : [rl] "=r" (low), [rh] "=r" (high) - : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) - : "cc" ); -#else - uint64_t lo = low + b.low; - if (lo < low) - { - ++high; - } - low = lo; - high += b.high; -#endif - return *this; - } - - Int128& operator++() - { - if (++low == 0) - { - ++high; - } - return *this; - } - - Int128 operator*(int64_t b) const; - - btScalar toScalar() const - { - return ((int64_t) high >= 0) ? btScalar(high) * (btScalar(0x100000000LL) * btScalar(0x100000000LL)) + btScalar(low) - : -(-*this).toScalar(); - } - - int getSign() const - { - return ((int64_t) high < 0) ? -1 : (high || low) ? 1 : 0; - } - - bool operator<(const Int128& b) const - { - return (high < b.high) || ((high == b.high) && (low < b.low)); - } - - int ucmp(const Int128&b) const - { - if (high < b.high) - { - return -1; - } - if (high > b.high) - { - return 1; - } - if (low < b.low) - { - return -1; - } - if (low > b.low) - { - return 1; - } - return 0; - } - }; - - - class Rational64 - { - private: - uint64_t m_numerator; - uint64_t m_denominator; - int sign; - - public: - Rational64(int64_t numerator, int64_t denominator) - { - if (numerator > 0) - { - sign = 1; - m_numerator = (uint64_t) numerator; - } - else if (numerator < 0) - { - sign = -1; - m_numerator = (uint64_t) -numerator; - } - else - { - sign = 0; - m_numerator = 0; - } - if (denominator > 0) - { - m_denominator = (uint64_t) denominator; - } - else if (denominator < 0) - { - sign = -sign; - m_denominator = (uint64_t) -denominator; - } - else - { - m_denominator = 0; - } - } - - bool isNegativeInfinity() const - { - return (sign < 0) && (m_denominator == 0); - } - - bool isNaN() const - { - return (sign == 0) && (m_denominator == 0); - } - - int compare(const Rational64& b) const; - - btScalar toScalar() const - { - return sign * ((m_denominator == 0) ? SIMD_INFINITY : (btScalar) m_numerator / m_denominator); - } - }; - - - class Rational128 - { - private: - Int128 numerator; - Int128 denominator; - int sign; - bool isInt64; - - public: - Rational128(int64_t value) - { - if (value > 0) - { - sign = 1; - this->numerator = value; - } - else if (value < 0) - { - sign = -1; - this->numerator = -value; - } - else - { - sign = 0; - this->numerator = (uint64_t) 0; - } - this->denominator = (uint64_t) 1; - isInt64 = true; - } - - Rational128(const Int128& numerator, const Int128& denominator) - { - sign = numerator.getSign(); - if (sign >= 0) - { - this->numerator = numerator; - } - else - { - this->numerator = -numerator; - } - int dsign = denominator.getSign(); - if (dsign >= 0) - { - this->denominator = denominator; - } - else - { - sign = -sign; - this->denominator = -denominator; - } - isInt64 = false; - } - - int compare(const Rational128& b) const; - - int compare(int64_t b) const; - - btScalar toScalar() const - { - return sign * ((denominator.getSign() == 0) ? SIMD_INFINITY : numerator.toScalar() / denominator.toScalar()); - } - }; - - class PointR128 - { - public: - Int128 x; - Int128 y; - Int128 z; - Int128 denominator; - - PointR128() - { - } - - PointR128(Int128 x, Int128 y, Int128 z, Int128 denominator): x(x), y(y), z(z), denominator(denominator) - { - } - - btScalar xvalue() const - { - return x.toScalar() / denominator.toScalar(); - } - - btScalar yvalue() const - { - return y.toScalar() / denominator.toScalar(); - } - - btScalar zvalue() const - { - return z.toScalar() / denominator.toScalar(); - } - }; - - - class Edge; - class Face; - - class Vertex - { - public: - Vertex* next; - Vertex* prev; - Edge* edges; - Face* firstNearbyFace; - Face* lastNearbyFace; - PointR128 point128; - Point32 point; - int copy; - - Vertex(): next(NULL), prev(NULL), edges(NULL), firstNearbyFace(NULL), lastNearbyFace(NULL), copy(-1) - { - } - -#ifdef DEBUG_CONVEX_HULL - void print() - { - printf("V%d (%d, %d, %d)", point.index, point.x, point.y, point.z); - } - - void printGraph(); -#endif - - Point32 operator-(const Vertex& b) const - { - return point - b.point; - } - - Rational128 dot(const Point64& b) const - { - return (point.index >= 0) ? Rational128(point.dot(b)) - : Rational128(point128.x * b.x + point128.y * b.y + point128.z * b.z, point128.denominator); - } - - btScalar xvalue() const - { - return (point.index >= 0) ? btScalar(point.x) : point128.xvalue(); - } - - btScalar yvalue() const - { - return (point.index >= 0) ? btScalar(point.y) : point128.yvalue(); - } - - btScalar zvalue() const - { - return (point.index >= 0) ? btScalar(point.z) : point128.zvalue(); - } - - void receiveNearbyFaces(Vertex* src) - { - if (lastNearbyFace) - { - lastNearbyFace->nextWithSameNearbyVertex = src->firstNearbyFace; - } - else - { - firstNearbyFace = src->firstNearbyFace; - } - if (src->lastNearbyFace) - { - lastNearbyFace = src->lastNearbyFace; - } - for (Face* f = src->firstNearbyFace; f; f = f->nextWithSameNearbyVertex) - { - btAssert(f->nearbyVertex == src); - f->nearbyVertex = this; - } - src->firstNearbyFace = NULL; - src->lastNearbyFace = NULL; - } - }; - - - class Edge - { - public: - Edge* next; - Edge* prev; - Edge* reverse; - Vertex* target; - Face* face; - int copy; - - ~Edge() - { - next = NULL; - prev = NULL; - reverse = NULL; - target = NULL; - face = NULL; - } - - void link(Edge* n) - { - btAssert(reverse->target == n->reverse->target); - next = n; - n->prev = this; - } - -#ifdef DEBUG_CONVEX_HULL - void print() - { - printf("E%p : %d -> %d, n=%p p=%p (0 %d\t%d\t%d) -> (%d %d %d)", this, reverse->target->point.index, target->point.index, next, prev, - reverse->target->point.x, reverse->target->point.y, reverse->target->point.z, target->point.x, target->point.y, target->point.z); - } -#endif - }; - - class Face - { - public: - Face* next; - Vertex* nearbyVertex; - Face* nextWithSameNearbyVertex; - Point32 origin; - Point32 dir0; - Point32 dir1; - - Face(): next(NULL), nearbyVertex(NULL), nextWithSameNearbyVertex(NULL) - { - } - - void init(Vertex* a, Vertex* b, Vertex* c) - { - nearbyVertex = a; - origin = a->point; - dir0 = *b - *a; - dir1 = *c - *a; - if (a->lastNearbyFace) - { - a->lastNearbyFace->nextWithSameNearbyVertex = this; - } - else - { - a->firstNearbyFace = this; - } - a->lastNearbyFace = this; - } - - Point64 getNormal() - { - return dir0.cross(dir1); - } - }; - - template class DMul - { - private: - static uint32_t high(uint64_t value) - { - return (uint32_t) (value >> 32); - } - - static uint32_t low(uint64_t value) - { - return (uint32_t) value; - } - - static uint64_t mul(uint32_t a, uint32_t b) - { - return (uint64_t) a * (uint64_t) b; - } - - static void shlHalf(uint64_t& value) - { - value <<= 32; - } - - static uint64_t high(Int128 value) - { - return value.high; - } - - static uint64_t low(Int128 value) - { - return value.low; - } - - static Int128 mul(uint64_t a, uint64_t b) - { - return Int128::mul(a, b); - } - - static void shlHalf(Int128& value) - { - value.high = value.low; - value.low = 0; - } - - public: - - static void mul(UWord a, UWord b, UWord& resLow, UWord& resHigh) - { - UWord p00 = mul(low(a), low(b)); - UWord p01 = mul(low(a), high(b)); - UWord p10 = mul(high(a), low(b)); - UWord p11 = mul(high(a), high(b)); - UWord p0110 = UWord(low(p01)) + UWord(low(p10)); - p11 += high(p01); - p11 += high(p10); - p11 += high(p0110); - shlHalf(p0110); - p00 += p0110; - if (p00 < p0110) - { - ++p11; - } - resLow = p00; - resHigh = p11; - } - }; - - private: - - class IntermediateHull - { - public: - Vertex* minXy; - Vertex* maxXy; - Vertex* minYx; - Vertex* maxYx; - - IntermediateHull(): minXy(NULL), maxXy(NULL), minYx(NULL), maxYx(NULL) - { - } - - void print(); - }; - - enum Orientation {NONE, CLOCKWISE, COUNTER_CLOCKWISE}; - - template class PoolArray - { - private: - T* array; - int size; - - public: - PoolArray* next; - - PoolArray(int size): size(size), next(NULL) - { - array = (T*) btAlignedAlloc(sizeof(T) * size, 16); - } - - ~PoolArray() - { - btAlignedFree(array); - } - - T* init() - { - T* o = array; - for (int i = 0; i < size; i++, o++) - { - o->next = (i+1 < size) ? o + 1 : NULL; - } - return array; - } - }; - - template class Pool - { - private: - PoolArray* arrays; - PoolArray* nextArray; - T* freeObjects; - int arraySize; - - public: - Pool(): arrays(NULL), nextArray(NULL), freeObjects(NULL), arraySize(256) - { - } - - ~Pool() - { - while (arrays) - { - PoolArray* p = arrays; - arrays = p->next; - p->~PoolArray(); - btAlignedFree(p); - } - } - - void reset() - { - nextArray = arrays; - freeObjects = NULL; - } - - void setArraySize(int arraySize) - { - this->arraySize = arraySize; - } - - T* newObject() - { - T* o = freeObjects; - if (!o) - { - PoolArray* p = nextArray; - if (p) - { - nextArray = p->next; - } - else - { - p = new(btAlignedAlloc(sizeof(PoolArray), 16)) PoolArray(arraySize); - p->next = arrays; - arrays = p; - } - o = p->init(); - } - freeObjects = o->next; - return new(o) T(); - }; - - void freeObject(T* object) - { - object->~T(); - object->next = freeObjects; - freeObjects = object; - } - }; - - btVector3 scaling; - btVector3 center; - Pool vertexPool; - Pool edgePool; - Pool facePool; - btAlignedObjectArray originalVertices; - int mergeStamp; - int minAxis; - int medAxis; - int maxAxis; - int usedEdgePairs; - int maxUsedEdgePairs; - - static Orientation getOrientation(const Edge* prev, const Edge* next, const Point32& s, const Point32& t); - Edge* findMaxAngle(bool ccw, const Vertex* start, const Point32& s, const Point64& rxs, const Point64& sxrxs, Rational64& minCot); - void findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge*& e0, Edge*& e1, Vertex* stop0, Vertex* stop1); - - Edge* newEdgePair(Vertex* from, Vertex* to); - - void removeEdgePair(Edge* edge) - { - Edge* n = edge->next; - Edge* r = edge->reverse; - - btAssert(edge->target && r->target); - - if (n != edge) - { - n->prev = edge->prev; - edge->prev->next = n; - r->target->edges = n; - } - else - { - r->target->edges = NULL; - } - - n = r->next; - - if (n != r) - { - n->prev = r->prev; - r->prev->next = n; - edge->target->edges = n; - } - else - { - edge->target->edges = NULL; - } - - edgePool.freeObject(edge); - edgePool.freeObject(r); - usedEdgePairs--; } - - void computeInternal(int start, int end, IntermediateHull& result); - - bool mergeProjection(IntermediateHull& h0, IntermediateHull& h1, Vertex*& c0, Vertex*& c1); - - void merge(IntermediateHull& h0, IntermediateHull& h1); - btVector3 toBtVector(const Point32& v); + bool isZero() + { + return (x == 0) && (y == 0) && (z == 0); + } - btVector3 getBtNormal(Face* face); + int64_t dot(const Point64& b) const + { + return x * b.x + y * b.y + z * b.z; + } + }; - bool shiftFace(Face* face, btScalar amount, btAlignedObjectArray stack); + class Point32 + { + public: + int32_t x; + int32_t y; + int32_t z; + int index; + + Point32() + { + } + + Point32(int32_t x, int32_t y, int32_t z) : x(x), y(y), z(z), index(-1) + { + } + + bool operator==(const Point32& b) const + { + return (x == b.x) && (y == b.y) && (z == b.z); + } + + bool operator!=(const Point32& b) const + { + return (x != b.x) || (y != b.y) || (z != b.z); + } + + bool isZero() + { + return (x == 0) && (y == 0) && (z == 0); + } + + Point64 cross(const Point32& b) const + { + return Point64(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); + } + + Point64 cross(const Point64& b) const + { + return Point64(y * b.z - z * b.y, z * b.x - x * b.z, x * b.y - y * b.x); + } + + int64_t dot(const Point32& b) const + { + return x * b.x + y * b.y + z * b.z; + } + + int64_t dot(const Point64& b) const + { + return x * b.x + y * b.y + z * b.z; + } + + Point32 operator+(const Point32& b) const + { + return Point32(x + b.x, y + b.y, z + b.z); + } + + Point32 operator-(const Point32& b) const + { + return Point32(x - b.x, y - b.y, z - b.z); + } + }; + + class Int128 + { + public: + uint64_t low; + uint64_t high; + + Int128() + { + } + + Int128(uint64_t low, uint64_t high) : low(low), high(high) + { + } + + Int128(uint64_t low) : low(low), high(0) + { + } + + Int128(int64_t value) : low(value), high((value >= 0) ? 0 : (uint64_t)-1LL) + { + } + + static Int128 mul(int64_t a, int64_t b); + + static Int128 mul(uint64_t a, uint64_t b); + + Int128 operator-() const + { + return Int128((uint64_t) - (int64_t)low, ~high + (low == 0)); + } + + Int128 operator+(const Int128& b) const + { +#ifdef USE_X86_64_ASM + Int128 result; + __asm__( + "addq %[bl], %[rl]\n\t" + "adcq %[bh], %[rh]\n\t" + : [rl] "=r"(result.low), [rh] "=r"(result.high) + : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) + : "cc"); + return result; +#else + uint64_t lo = low + b.low; + return Int128(lo, high + b.high + (lo < low)); +#endif + } + + Int128 operator-(const Int128& b) const + { +#ifdef USE_X86_64_ASM + Int128 result; + __asm__( + "subq %[bl], %[rl]\n\t" + "sbbq %[bh], %[rh]\n\t" + : [rl] "=r"(result.low), [rh] "=r"(result.high) + : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) + : "cc"); + return result; +#else + return *this + -b; +#endif + } + + Int128& operator+=(const Int128& b) + { +#ifdef USE_X86_64_ASM + __asm__( + "addq %[bl], %[rl]\n\t" + "adcq %[bh], %[rh]\n\t" + : [rl] "=r"(low), [rh] "=r"(high) + : "0"(low), "1"(high), [bl] "g"(b.low), [bh] "g"(b.high) + : "cc"); +#else + uint64_t lo = low + b.low; + if (lo < low) + { + ++high; + } + low = lo; + high += b.high; +#endif + return *this; + } + + Int128& operator++() + { + if (++low == 0) + { + ++high; + } + return *this; + } + + Int128 operator*(int64_t b) const; + + btScalar toScalar() const + { + return ((int64_t)high >= 0) ? btScalar(high) * (btScalar(0x100000000LL) * btScalar(0x100000000LL)) + btScalar(low) + : -(-*this).toScalar(); + } + + int getSign() const + { + return ((int64_t)high < 0) ? -1 : (high || low) ? 1 : 0; + } + + bool operator<(const Int128& b) const + { + return (high < b.high) || ((high == b.high) && (low < b.low)); + } + + int ucmp(const Int128& b) const + { + if (high < b.high) + { + return -1; + } + if (high > b.high) + { + return 1; + } + if (low < b.low) + { + return -1; + } + if (low > b.low) + { + return 1; + } + return 0; + } + }; + + class Rational64 + { + private: + uint64_t m_numerator; + uint64_t m_denominator; + int sign; public: - Vertex* vertexList; + Rational64(int64_t numerator, int64_t denominator) + { + if (numerator > 0) + { + sign = 1; + m_numerator = (uint64_t)numerator; + } + else if (numerator < 0) + { + sign = -1; + m_numerator = (uint64_t)-numerator; + } + else + { + sign = 0; + m_numerator = 0; + } + if (denominator > 0) + { + m_denominator = (uint64_t)denominator; + } + else if (denominator < 0) + { + sign = -sign; + m_denominator = (uint64_t)-denominator; + } + else + { + m_denominator = 0; + } + } - void compute(const void* coords, bool doubleCoords, int stride, int count); + bool isNegativeInfinity() const + { + return (sign < 0) && (m_denominator == 0); + } - btVector3 getCoordinates(const Vertex* v); + bool isNaN() const + { + return (sign == 0) && (m_denominator == 0); + } - btScalar shrink(btScalar amount, btScalar clampAmount); + int compare(const Rational64& b) const; + + btScalar toScalar() const + { + return sign * ((m_denominator == 0) ? SIMD_INFINITY : (btScalar)m_numerator / m_denominator); + } + }; + + class Rational128 + { + private: + Int128 numerator; + Int128 denominator; + int sign; + bool isInt64; + + public: + Rational128(int64_t value) + { + if (value > 0) + { + sign = 1; + this->numerator = value; + } + else if (value < 0) + { + sign = -1; + this->numerator = -value; + } + else + { + sign = 0; + this->numerator = (uint64_t)0; + } + this->denominator = (uint64_t)1; + isInt64 = true; + } + + Rational128(const Int128& numerator, const Int128& denominator) + { + sign = numerator.getSign(); + if (sign >= 0) + { + this->numerator = numerator; + } + else + { + this->numerator = -numerator; + } + int dsign = denominator.getSign(); + if (dsign >= 0) + { + this->denominator = denominator; + } + else + { + sign = -sign; + this->denominator = -denominator; + } + isInt64 = false; + } + + int compare(const Rational128& b) const; + + int compare(int64_t b) const; + + btScalar toScalar() const + { + return sign * ((denominator.getSign() == 0) ? SIMD_INFINITY : numerator.toScalar() / denominator.toScalar()); + } + }; + + class PointR128 + { + public: + Int128 x; + Int128 y; + Int128 z; + Int128 denominator; + + PointR128() + { + } + + PointR128(Int128 x, Int128 y, Int128 z, Int128 denominator) : x(x), y(y), z(z), denominator(denominator) + { + } + + btScalar xvalue() const + { + return x.toScalar() / denominator.toScalar(); + } + + btScalar yvalue() const + { + return y.toScalar() / denominator.toScalar(); + } + + btScalar zvalue() const + { + return z.toScalar() / denominator.toScalar(); + } + }; + + class Edge; + class Face; + + class Vertex + { + public: + Vertex* next; + Vertex* prev; + Edge* edges; + Face* firstNearbyFace; + Face* lastNearbyFace; + PointR128 point128; + Point32 point; + int copy; + + Vertex() : next(NULL), prev(NULL), edges(NULL), firstNearbyFace(NULL), lastNearbyFace(NULL), copy(-1) + { + } + +#ifdef DEBUG_CONVEX_HULL + void print() + { + printf("V%d (%d, %d, %d)", point.index, point.x, point.y, point.z); + } + + void printGraph(); +#endif + + Point32 operator-(const Vertex& b) const + { + return point - b.point; + } + + Rational128 dot(const Point64& b) const + { + return (point.index >= 0) ? Rational128(point.dot(b)) + : Rational128(point128.x * b.x + point128.y * b.y + point128.z * b.z, point128.denominator); + } + + btScalar xvalue() const + { + return (point.index >= 0) ? btScalar(point.x) : point128.xvalue(); + } + + btScalar yvalue() const + { + return (point.index >= 0) ? btScalar(point.y) : point128.yvalue(); + } + + btScalar zvalue() const + { + return (point.index >= 0) ? btScalar(point.z) : point128.zvalue(); + } + + void receiveNearbyFaces(Vertex* src) + { + if (lastNearbyFace) + { + lastNearbyFace->nextWithSameNearbyVertex = src->firstNearbyFace; + } + else + { + firstNearbyFace = src->firstNearbyFace; + } + if (src->lastNearbyFace) + { + lastNearbyFace = src->lastNearbyFace; + } + for (Face* f = src->firstNearbyFace; f; f = f->nextWithSameNearbyVertex) + { + btAssert(f->nearbyVertex == src); + f->nearbyVertex = this; + } + src->firstNearbyFace = NULL; + src->lastNearbyFace = NULL; + } + }; + + class Edge + { + public: + Edge* next; + Edge* prev; + Edge* reverse; + Vertex* target; + Face* face; + int copy; + + ~Edge() + { + next = NULL; + prev = NULL; + reverse = NULL; + target = NULL; + face = NULL; + } + + void link(Edge* n) + { + btAssert(reverse->target == n->reverse->target); + next = n; + n->prev = this; + } + +#ifdef DEBUG_CONVEX_HULL + void print() + { + printf("E%p : %d -> %d, n=%p p=%p (0 %d\t%d\t%d) -> (%d %d %d)", this, reverse->target->point.index, target->point.index, next, prev, + reverse->target->point.x, reverse->target->point.y, reverse->target->point.z, target->point.x, target->point.y, target->point.z); + } +#endif + }; + + class Face + { + public: + Face* next; + Vertex* nearbyVertex; + Face* nextWithSameNearbyVertex; + Point32 origin; + Point32 dir0; + Point32 dir1; + + Face() : next(NULL), nearbyVertex(NULL), nextWithSameNearbyVertex(NULL) + { + } + + void init(Vertex* a, Vertex* b, Vertex* c) + { + nearbyVertex = a; + origin = a->point; + dir0 = *b - *a; + dir1 = *c - *a; + if (a->lastNearbyFace) + { + a->lastNearbyFace->nextWithSameNearbyVertex = this; + } + else + { + a->firstNearbyFace = this; + } + a->lastNearbyFace = this; + } + + Point64 getNormal() + { + return dir0.cross(dir1); + } + }; + + template + class DMul + { + private: + static uint32_t high(uint64_t value) + { + return (uint32_t)(value >> 32); + } + + static uint32_t low(uint64_t value) + { + return (uint32_t)value; + } + + static uint64_t mul(uint32_t a, uint32_t b) + { + return (uint64_t)a * (uint64_t)b; + } + + static void shlHalf(uint64_t& value) + { + value <<= 32; + } + + static uint64_t high(Int128 value) + { + return value.high; + } + + static uint64_t low(Int128 value) + { + return value.low; + } + + static Int128 mul(uint64_t a, uint64_t b) + { + return Int128::mul(a, b); + } + + static void shlHalf(Int128& value) + { + value.high = value.low; + value.low = 0; + } + + public: + static void mul(UWord a, UWord b, UWord& resLow, UWord& resHigh) + { + UWord p00 = mul(low(a), low(b)); + UWord p01 = mul(low(a), high(b)); + UWord p10 = mul(high(a), low(b)); + UWord p11 = mul(high(a), high(b)); + UWord p0110 = UWord(low(p01)) + UWord(low(p10)); + p11 += high(p01); + p11 += high(p10); + p11 += high(p0110); + shlHalf(p0110); + p00 += p0110; + if (p00 < p0110) + { + ++p11; + } + resLow = p00; + resHigh = p11; + } + }; + +private: + class IntermediateHull + { + public: + Vertex* minXy; + Vertex* maxXy; + Vertex* minYx; + Vertex* maxYx; + + IntermediateHull() : minXy(NULL), maxXy(NULL), minYx(NULL), maxYx(NULL) + { + } + + void print(); + }; + + enum Orientation + { + NONE, + CLOCKWISE, + COUNTER_CLOCKWISE + }; + + template + class PoolArray + { + private: + T* array; + int size; + + public: + PoolArray* next; + + PoolArray(int size) : size(size), next(NULL) + { + array = (T*)btAlignedAlloc(sizeof(T) * size, 16); + } + + ~PoolArray() + { + btAlignedFree(array); + } + + T* init() + { + T* o = array; + for (int i = 0; i < size; i++, o++) + { + o->next = (i + 1 < size) ? o + 1 : NULL; + } + return array; + } + }; + + template + class Pool + { + private: + PoolArray* arrays; + PoolArray* nextArray; + T* freeObjects; + int arraySize; + + public: + Pool() : arrays(NULL), nextArray(NULL), freeObjects(NULL), arraySize(256) + { + } + + ~Pool() + { + while (arrays) + { + PoolArray* p = arrays; + arrays = p->next; + p->~PoolArray(); + btAlignedFree(p); + } + } + + void reset() + { + nextArray = arrays; + freeObjects = NULL; + } + + void setArraySize(int arraySize) + { + this->arraySize = arraySize; + } + + T* newObject() + { + T* o = freeObjects; + if (!o) + { + PoolArray* p = nextArray; + if (p) + { + nextArray = p->next; + } + else + { + p = new (btAlignedAlloc(sizeof(PoolArray), 16)) PoolArray(arraySize); + p->next = arrays; + arrays = p; + } + o = p->init(); + } + freeObjects = o->next; + return new (o) T(); + }; + + void freeObject(T* object) + { + object->~T(); + object->next = freeObjects; + freeObjects = object; + } + }; + + btVector3 scaling; + btVector3 center; + Pool vertexPool; + Pool edgePool; + Pool facePool; + btAlignedObjectArray originalVertices; + int mergeStamp; + int minAxis; + int medAxis; + int maxAxis; + int usedEdgePairs; + int maxUsedEdgePairs; + + static Orientation getOrientation(const Edge* prev, const Edge* next, const Point32& s, const Point32& t); + Edge* findMaxAngle(bool ccw, const Vertex* start, const Point32& s, const Point64& rxs, const Point64& sxrxs, Rational64& minCot); + void findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge*& e0, Edge*& e1, Vertex* stop0, Vertex* stop1); + + Edge* newEdgePair(Vertex* from, Vertex* to); + + void removeEdgePair(Edge* edge) + { + Edge* n = edge->next; + Edge* r = edge->reverse; + + btAssert(edge->target && r->target); + + if (n != edge) + { + n->prev = edge->prev; + edge->prev->next = n; + r->target->edges = n; + } + else + { + r->target->edges = NULL; + } + + n = r->next; + + if (n != r) + { + n->prev = r->prev; + r->prev->next = n; + edge->target->edges = n; + } + else + { + edge->target->edges = NULL; + } + + edgePool.freeObject(edge); + edgePool.freeObject(r); + usedEdgePairs--; + } + + void computeInternal(int start, int end, IntermediateHull& result); + + bool mergeProjection(IntermediateHull& h0, IntermediateHull& h1, Vertex*& c0, Vertex*& c1); + + void merge(IntermediateHull& h0, IntermediateHull& h1); + + btVector3 toBtVector(const Point32& v); + + btVector3 getBtNormal(Face* face); + + bool shiftFace(Face* face, btScalar amount, btAlignedObjectArray stack); + +public: + Vertex* vertexList; + + void compute(const void* coords, bool doubleCoords, int stride, int count); + + btVector3 getCoordinates(const Vertex* v); + + btScalar shrink(btScalar amount, btScalar clampAmount); }; - btConvexHullInternal::Int128 btConvexHullInternal::Int128::operator*(int64_t b) const { - bool negative = (int64_t) high < 0; + bool negative = (int64_t)high < 0; Int128 a = negative ? -*this : *this; if (b < 0) { negative = !negative; b = -b; } - Int128 result = mul(a.low, (uint64_t) b); - result.high += a.high * (uint64_t) b; + Int128 result = mul(a.low, (uint64_t)b); + result.high += a.high * (uint64_t)b; return negative ? -result : result; } btConvexHullInternal::Int128 btConvexHullInternal::Int128::mul(int64_t a, int64_t b) { Int128 result; - + #ifdef USE_X86_64_ASM - __asm__ ("imulq %[b]" - : "=a" (result.low), "=d" (result.high) - : "0"(a), [b] "r"(b) - : "cc" ); + __asm__("imulq %[b]" + : "=a"(result.low), "=d"(result.high) + : "0"(a), [b] "r"(b) + : "cc"); return result; - + #else bool negative = a < 0; if (negative) @@ -871,7 +872,7 @@ btConvexHullInternal::Int128 btConvexHullInternal::Int128::mul(int64_t a, int64_ negative = !negative; b = -b; } - DMul::mul((uint64_t) a, (uint64_t) b, result.low, result.high); + DMul::mul((uint64_t)a, (uint64_t)b, result.low, result.high); return negative ? -result : result; #endif } @@ -881,10 +882,10 @@ btConvexHullInternal::Int128 btConvexHullInternal::Int128::mul(uint64_t a, uint6 Int128 result; #ifdef USE_X86_64_ASM - __asm__ ("mulq %[b]" - : "=a" (result.low), "=d" (result.high) - : "0"(a), [b] "r"(b) - : "cc" ); + __asm__("mulq %[b]" + : "=a"(result.low), "=d"(result.high) + : "0"(a), [b] "r"(b) + : "cc"); #else DMul::mul(a, b, result.low, result.high); @@ -911,24 +912,25 @@ int btConvexHullInternal::Rational64::compare(const Rational64& b) const int result; int64_t tmp; int64_t dummy; - __asm__ ("mulq %[bn]\n\t" - "movq %%rax, %[tmp]\n\t" - "movq %%rdx, %%rbx\n\t" - "movq %[tn], %%rax\n\t" - "mulq %[bd]\n\t" - "subq %[tmp], %%rax\n\t" - "sbbq %%rbx, %%rdx\n\t" // rdx:rax contains 128-bit-difference "numerator*b.denominator - b.numerator*denominator" - "setnsb %%bh\n\t" // bh=1 if difference is non-negative, bh=0 otherwise - "orq %%rdx, %%rax\n\t" - "setnzb %%bl\n\t" // bl=1 if difference if non-zero, bl=0 if it is zero - "decb %%bh\n\t" // now bx=0x0000 if difference is zero, 0xff01 if it is negative, 0x0001 if it is positive (i.e., same sign as difference) - "shll $16, %%ebx\n\t" // ebx has same sign as difference - : "=&b"(result), [tmp] "=&r"(tmp), "=a"(dummy) - : "a"(denominator), [bn] "g"(b.numerator), [tn] "g"(numerator), [bd] "g"(b.denominator) - : "%rdx", "cc" ); - return result ? result ^ sign // if sign is +1, only bit 0 of result is inverted, which does not change the sign of result (and cannot result in zero) - // if sign is -1, all bits of result are inverted, which changes the sign of result (and again cannot result in zero) - : 0; + __asm__( + "mulq %[bn]\n\t" + "movq %%rax, %[tmp]\n\t" + "movq %%rdx, %%rbx\n\t" + "movq %[tn], %%rax\n\t" + "mulq %[bd]\n\t" + "subq %[tmp], %%rax\n\t" + "sbbq %%rbx, %%rdx\n\t" // rdx:rax contains 128-bit-difference "numerator*b.denominator - b.numerator*denominator" + "setnsb %%bh\n\t" // bh=1 if difference is non-negative, bh=0 otherwise + "orq %%rdx, %%rax\n\t" + "setnzb %%bl\n\t" // bl=1 if difference if non-zero, bl=0 if it is zero + "decb %%bh\n\t" // now bx=0x0000 if difference is zero, 0xff01 if it is negative, 0x0001 if it is positive (i.e., same sign as difference) + "shll $16, %%ebx\n\t" // ebx has same sign as difference + : "=&b"(result), [tmp] "=&r"(tmp), "=a"(dummy) + : "a"(denominator), [bn] "g"(b.numerator), [tn] "g"(numerator), [bd] "g"(b.denominator) + : "%rdx", "cc"); + return result ? result ^ sign // if sign is +1, only bit 0 of result is inverted, which does not change the sign of result (and cannot result in zero) + // if sign is -1, all bits of result are inverted, which changes the sign of result (and again cannot result in zero) + : 0; #else @@ -949,7 +951,7 @@ int btConvexHullInternal::Rational128::compare(const Rational128& b) const } if (isInt64) { - return -b.compare(sign * (int64_t) numerator.low); + return -b.compare(sign * (int64_t)numerator.low); } Int128 nbdLow, nbdHigh, dbnLow, dbnHigh; @@ -968,7 +970,7 @@ int btConvexHullInternal::Rational128::compare(int64_t b) const { if (isInt64) { - int64_t a = sign * (int64_t) numerator.low; + int64_t a = sign * (int64_t)numerator.low; return (a > b) ? 1 : (a < b) ? -1 : 0; } if (b > 0) @@ -994,7 +996,6 @@ int btConvexHullInternal::Rational128::compare(int64_t b) const return numerator.ucmp(denominator * b) * sign; } - btConvexHullInternal::Edge* btConvexHullInternal::newEdgePair(Vertex* from, Vertex* to) { btAssert(from && to); @@ -1062,7 +1063,7 @@ bool btConvexHullInternal::mergeProjection(IntermediateHull& h0, IntermediateHul } } } - + v0 = h0.maxXy; v1 = h1.maxXy; Vertex* v00 = NULL; @@ -1070,7 +1071,7 @@ bool btConvexHullInternal::mergeProjection(IntermediateHull& h0, IntermediateHul int32_t sign = 1; for (int side = 0; side <= 1; side++) - { + { int32_t dx = (v1->point.x - v0->point.x) * sign; if (dx > 0) { @@ -1113,7 +1114,7 @@ bool btConvexHullInternal::mergeProjection(IntermediateHull& h0, IntermediateHul while (true) { int32_t dy = v1->point.y - v0->point.y; - + Vertex* w1 = side ? v1->prev : v1->next; if (w1 != v1) { @@ -1126,7 +1127,7 @@ bool btConvexHullInternal::mergeProjection(IntermediateHull& h0, IntermediateHul continue; } } - + Vertex* w0 = side ? v0->prev : v0->next; if (w0 != v0) { @@ -1140,7 +1141,7 @@ bool btConvexHullInternal::mergeProjection(IntermediateHull& h0, IntermediateHul continue; } } - + break; } } @@ -1166,7 +1167,7 @@ bool btConvexHullInternal::mergeProjection(IntermediateHull& h0, IntermediateHul } v1 = w1; } - + if (side == 0) { v00 = v0; @@ -1192,7 +1193,7 @@ bool btConvexHullInternal::mergeProjection(IntermediateHull& h0, IntermediateHul { h0.maxXy = h1.maxXy; } - + h0.maxYx = h1.maxYx; c0 = v00; @@ -1279,19 +1280,19 @@ void btConvexHullInternal::computeInternal(int start, int end, IntermediateHull& } { Vertex* v = originalVertices[start]; - v->edges = NULL; - v->next = v; - v->prev = v; + v->edges = NULL; + v->next = v; + v->prev = v; - result.minXy = v; - result.maxXy = v; - result.minYx = v; - result.maxYx = v; + result.minXy = v; + result.maxXy = v; + result.minYx = v; + result.maxYx = v; } - + return; } - + case 1: { Vertex* v = originalVertices[start]; @@ -1309,7 +1310,7 @@ void btConvexHullInternal::computeInternal(int start, int end, IntermediateHull& } int split0 = start + n / 2; - Point32 p = originalVertices[split0-1]->point; + Point32 p = originalVertices[split0 - 1]->point; int split1 = split0; while ((split1 < end) && (originalVertices[split1]->point == p)) { @@ -1334,7 +1335,7 @@ void btConvexHullInternal::computeInternal(int start, int end, IntermediateHull& void btConvexHullInternal::IntermediateHull::print() { printf(" Hull\n"); - for (Vertex* v = minXy; v; ) + for (Vertex* v = minXy; v;) { printf(" "); v->print(); @@ -1362,7 +1363,7 @@ void btConvexHullInternal::IntermediateHull::print() } } if (minXy) - { + { minXy->copy = (minXy->copy == -1) ? -2 : -1; minXy->printGraph(); } @@ -1438,7 +1439,7 @@ btConvexHullInternal::Edge* btConvexHullInternal::findMaxAngle(bool ccw, const V Point32 t = *e->target - *start; Rational64 cot(t.dot(sxrxs), t.dot(rxs)); #ifdef DEBUG_CONVEX_HULL - printf(" Angle is %f (%d) for ", (float) btAtan(cot.toScalar()), (int) cot.isNaN()); + printf(" Angle is %f (%d) for ", (float)btAtan(cot.toScalar()), (int)cot.isNaN()); e->print(); #endif if (cot.isNaN()) @@ -1485,7 +1486,7 @@ void btConvexHullInternal::findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge btAssert(!start1 || (start1->target->point.dot(normal) == dist)); Point64 perp = s.cross(normal); btAssert(!perp.isZero()); - + #ifdef DEBUG_CONVEX_HULL printf(" Advancing %d %d (%p %p, %d %d)\n", c0->point.index, c1->point.index, start0, start1, start0 ? start0->target->point.index : -1, start1 ? start1->target->point.index : -1); #endif @@ -1515,7 +1516,7 @@ void btConvexHullInternal::findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge et0 = e->target->point; } } - + int64_t maxDot1 = et1.dot(perp); if (e1) { @@ -1552,7 +1553,7 @@ void btConvexHullInternal::findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge while (true) { int64_t dy = (et1 - et0).dot(s); - + if (e0 && (e0->target != stop0)) { Edge* f0 = e0->next->reverse; @@ -1569,7 +1570,7 @@ void btConvexHullInternal::findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge } } } - + if (e1 && (e1->target != stop1)) { Edge* f1 = e1->reverse->next; @@ -1604,7 +1605,7 @@ void btConvexHullInternal::findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge while (true) { int64_t dy = (et1 - et0).dot(s); - + if (e1 && (e1->target != stop1)) { Edge* f1 = e1->prev->reverse; @@ -1621,7 +1622,7 @@ void btConvexHullInternal::findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge } } } - + if (e0 && (e0->target != stop0)) { Edge* f0 = e0->reverse->prev; @@ -1656,7 +1657,6 @@ void btConvexHullInternal::findEdgeForCoplanarFaces(Vertex* c0, Vertex* c1, Edge #endif } - void btConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) { if (!h1.maxXy) @@ -1668,7 +1668,7 @@ void btConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) h0 = h1; return; } - + mergeStamp--; Vertex* c0 = NULL; @@ -1708,7 +1708,7 @@ void btConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) e = e->next; } while (e != c0->edges); } - + e = c1->edges; Edge* start1 = NULL; if (e) @@ -1760,7 +1760,7 @@ void btConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) Point32 r = prevPoint - c0->point; Point64 rxs = r.cross(s); Point64 sxrxs = s.cross(rxs); - + #ifdef DEBUG_CONVEX_HULL printf("\n Checking %d %d\n", c0->point.index, c1->point.index); #endif @@ -1811,7 +1811,7 @@ void btConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) e->prev = pendingTail1; pendingTail1 = e; } - + Edge* e0 = min0; Edge* e1 = min1; @@ -1828,7 +1828,7 @@ void btConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) { if (toPrev1) { - for (Edge* e = toPrev1->next, *n = NULL; e != min1; e = n) + for (Edge *e = toPrev1->next, *n = NULL; e != min1; e = n) { n = e->next; removeEdgePair(e); @@ -1864,7 +1864,7 @@ void btConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) { if (toPrev0) { - for (Edge* e = toPrev0->prev, *n = NULL; e != min0; e = n) + for (Edge *e = toPrev0->prev, *n = NULL; e != min0; e = n) { n = e->prev; removeEdgePair(e); @@ -1906,7 +1906,7 @@ void btConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) } else { - for (Edge* e = toPrev0->prev, *n = NULL; e != firstNew0; e = n) + for (Edge *e = toPrev0->prev, *n = NULL; e != firstNew0; e = n) { n = e->prev; removeEdgePair(e); @@ -1925,7 +1925,7 @@ void btConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) } else { - for (Edge* e = toPrev1->next, *n = NULL; e != firstNew1; e = n) + for (Edge *e = toPrev1->next, *n = NULL; e != firstNew1; e = n) { n = e->next; removeEdgePair(e); @@ -1936,7 +1936,7 @@ void btConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) pendingTail1->link(firstNew1); } } - + return; } @@ -1946,24 +1946,23 @@ void btConvexHullInternal::merge(IntermediateHull& h0, IntermediateHull& h1) class pointCmp { - public: - - bool operator() ( const btConvexHullInternal::Point32& p, const btConvexHullInternal::Point32& q ) const - { - return (p.y < q.y) || ((p.y == q.y) && ((p.x < q.x) || ((p.x == q.x) && (p.z < q.z)))); - } +public: + bool operator()(const btConvexHullInternal::Point32& p, const btConvexHullInternal::Point32& q) const + { + return (p.y < q.y) || ((p.y == q.y) && ((p.x < q.x) || ((p.x == q.x) && (p.z < q.z)))); + } }; void btConvexHullInternal::compute(const void* coords, bool doubleCoords, int stride, int count) { btVector3 min(btScalar(1e30), btScalar(1e30), btScalar(1e30)), max(btScalar(-1e30), btScalar(-1e30), btScalar(-1e30)); - const char* ptr = (const char*) coords; + const char* ptr = (const char*)coords; if (doubleCoords) { for (int i = 0; i < count; i++) { - const double* v = (const double*) ptr; - btVector3 p((btScalar) v[0], (btScalar) v[1], (btScalar) v[2]); + const double* v = (const double*)ptr; + btVector3 p((btScalar)v[0], (btScalar)v[1], (btScalar)v[2]); ptr += stride; min.setMin(p); max.setMax(p); @@ -1973,7 +1972,7 @@ void btConvexHullInternal::compute(const void* coords, bool doubleCoords, int st { for (int i = 0; i < count; i++) { - const float* v = (const float*) ptr; + const float* v = (const float*)ptr; btVector3 p(v[0], v[1], v[2]); ptr += stride; min.setMin(p); @@ -2014,18 +2013,18 @@ void btConvexHullInternal::compute(const void* coords, bool doubleCoords, int st btAlignedObjectArray points; points.resize(count); - ptr = (const char*) coords; + ptr = (const char*)coords; if (doubleCoords) { for (int i = 0; i < count; i++) { - const double* v = (const double*) ptr; - btVector3 p((btScalar) v[0], (btScalar) v[1], (btScalar) v[2]); + const double* v = (const double*)ptr; + btVector3 p((btScalar)v[0], (btScalar)v[1], (btScalar)v[2]); ptr += stride; p = (p - center) * s; - points[i].x = (int32_t) p[medAxis]; - points[i].y = (int32_t) p[maxAxis]; - points[i].z = (int32_t) p[minAxis]; + points[i].x = (int32_t)p[medAxis]; + points[i].y = (int32_t)p[maxAxis]; + points[i].z = (int32_t)p[minAxis]; points[i].index = i; } } @@ -2033,13 +2032,13 @@ void btConvexHullInternal::compute(const void* coords, bool doubleCoords, int st { for (int i = 0; i < count; i++) { - const float* v = (const float*) ptr; + const float* v = (const float*)ptr; btVector3 p(v[0], v[1], v[2]); ptr += stride; p = (p - center) * s; - points[i].x = (int32_t) p[medAxis]; - points[i].y = (int32_t) p[maxAxis]; - points[i].z = (int32_t) p[minAxis]; + points[i].x = (int32_t)p[medAxis]; + points[i].y = (int32_t)p[maxAxis]; + points[i].z = (int32_t)p[minAxis]; points[i].index = i; } } @@ -2193,7 +2192,7 @@ btScalar btConvexHullInternal::shrink(btScalar amount, btScalar clampAmount) minDist = dist; } } - + if (minDist <= 0) { return 0; @@ -2234,7 +2233,7 @@ bool btConvexHullInternal::shiftFace(Face* face, btScalar amount, btAlignedObjec { origShift[2] /= scaling[2]; } - Point32 shift((int32_t) origShift[medAxis], (int32_t) origShift[maxAxis], (int32_t) origShift[minAxis]); + Point32 shift((int32_t)origShift[medAxis], (int32_t)origShift[maxAxis], (int32_t)origShift[minAxis]); if (shift.isZero()) { return true; @@ -2242,7 +2241,7 @@ bool btConvexHullInternal::shiftFace(Face* face, btScalar amount, btAlignedObjec Point64 normal = face->getNormal(); #ifdef DEBUG_CONVEX_HULL printf("\nShrinking face (%d %d %d) (%d %d %d) (%d %d %d) by (%d %d %d)\n", - face->origin.x, face->origin.y, face->origin.z, face->dir0.x, face->dir0.y, face->dir0.z, face->dir1.x, face->dir1.y, face->dir1.z, shift.x, shift.y, shift.z); + face->origin.x, face->origin.y, face->origin.z, face->dir0.x, face->dir0.y, face->dir0.z, face->dir1.x, face->dir1.y, face->dir1.z, shift.x, shift.y, shift.z); #endif int64_t origDot = face->origin.dot(normal); Point32 shiftedOrigin = face->origin + shift; @@ -2279,7 +2278,7 @@ bool btConvexHullInternal::shiftFace(Face* face, btScalar amount, btAlignedObjec #ifdef DEBUG_CONVEX_HULL printf("Moving downwards, edge is "); e->print(); - printf(", dot is %f (%f %lld)\n", (float) dot.toScalar(), (float) optDot.toScalar(), shiftedDot); + printf(", dot is %f (%f %lld)\n", (float)dot.toScalar(), (float)optDot.toScalar(), shiftedDot); #endif if (dot.compare(optDot) < 0) { @@ -2315,7 +2314,7 @@ bool btConvexHullInternal::shiftFace(Face* face, btScalar amount, btAlignedObjec #ifdef DEBUG_CONVEX_HULL printf("Moving upwards, edge is "); e->print(); - printf(", dot is %f (%f %lld)\n", (float) dot.toScalar(), (float) optDot.toScalar(), shiftedDot); + printf(", dot is %f (%f %lld)\n", (float)dot.toScalar(), (float)optDot.toScalar(), shiftedDot); #endif if (dot.compare(optDot) > 0) { @@ -2331,7 +2330,7 @@ bool btConvexHullInternal::shiftFace(Face* face, btScalar amount, btAlignedObjec } e = e->prev; } while (e != startEdge); - + if (!intersection) { return true; @@ -2368,7 +2367,7 @@ bool btConvexHullInternal::shiftFace(Face* face, btScalar amount, btAlignedObjec printf("Needed %d iterations to check for complete containment\n", n); #endif } - + Edge* firstIntersection = NULL; Edge* faceEdge = NULL; Edge* firstFaceEdge = NULL; @@ -2477,7 +2476,7 @@ bool btConvexHullInternal::shiftFace(Face* face, btScalar amount, btAlignedObjec #ifdef DEBUG_CONVEX_HULL printf("1: Removed part contains (%d %d %d)\n", removed->point.x, removed->point.y, removed->point.z); #endif - + Point64 n0 = intersection->face->getNormal(); Point64 n1 = intersection->reverse->face->getNormal(); int64_t m00 = face->dir0.dot(n0); @@ -2491,16 +2490,13 @@ bool btConvexHullInternal::shiftFace(Face* face, btScalar amount, btAlignedObjec Vertex* v = vertexPool.newObject(); v->point.index = -1; v->copy = -1; - v->point128 = PointR128(Int128::mul(face->dir0.x * r0, m11) - Int128::mul(face->dir0.x * r1, m01) - + Int128::mul(face->dir1.x * r1, m00) - Int128::mul(face->dir1.x * r0, m10) + det * shiftedOrigin.x, - Int128::mul(face->dir0.y * r0, m11) - Int128::mul(face->dir0.y * r1, m01) - + Int128::mul(face->dir1.y * r1, m00) - Int128::mul(face->dir1.y * r0, m10) + det * shiftedOrigin.y, - Int128::mul(face->dir0.z * r0, m11) - Int128::mul(face->dir0.z * r1, m01) - + Int128::mul(face->dir1.z * r1, m00) - Int128::mul(face->dir1.z * r0, m10) + det * shiftedOrigin.z, - det); - v->point.x = (int32_t) v->point128.xvalue(); - v->point.y = (int32_t) v->point128.yvalue(); - v->point.z = (int32_t) v->point128.zvalue(); + v->point128 = PointR128(Int128::mul(face->dir0.x * r0, m11) - Int128::mul(face->dir0.x * r1, m01) + Int128::mul(face->dir1.x * r1, m00) - Int128::mul(face->dir1.x * r0, m10) + det * shiftedOrigin.x, + Int128::mul(face->dir0.y * r0, m11) - Int128::mul(face->dir0.y * r1, m01) + Int128::mul(face->dir1.y * r1, m00) - Int128::mul(face->dir1.y * r0, m10) + det * shiftedOrigin.y, + Int128::mul(face->dir0.z * r0, m11) - Int128::mul(face->dir0.z * r1, m01) + Int128::mul(face->dir1.z * r1, m00) - Int128::mul(face->dir1.z * r0, m10) + det * shiftedOrigin.z, + det); + v->point.x = (int32_t)v->point128.xvalue(); + v->point.y = (int32_t)v->point128.yvalue(); + v->point.z = (int32_t)v->point128.zvalue(); intersection->target = v; v->edges = e; @@ -2639,7 +2635,6 @@ bool btConvexHullInternal::shiftFace(Face* face, btScalar amount, btAlignedObjec return true; } - static int getVertexCopy(btConvexHullInternal::Vertex* vertex, btAlignedObjectArray& vertices) { int index = vertex->copy; @@ -2761,8 +2756,3 @@ btScalar btConvexHullComputer::compute(const void* coords, bool doubleCoords, in return shift; } - - - - - diff --git a/src/LinearMath/btConvexHullComputer.h b/src/LinearMath/btConvexHullComputer.h index 7240ac4fb..cba684f2d 100644 --- a/src/LinearMath/btConvexHullComputer.h +++ b/src/LinearMath/btConvexHullComputer.h @@ -23,58 +23,56 @@ subject to the following restrictions: /// Ole Kniemeyer, MAXON Computer GmbH class btConvexHullComputer { +private: + btScalar compute(const void* coords, bool doubleCoords, int stride, int count, btScalar shrink, btScalar shrinkClamp); + +public: + class Edge + { private: - btScalar compute(const void* coords, bool doubleCoords, int stride, int count, btScalar shrink, btScalar shrinkClamp); + int next; + int reverse; + int targetVertex; + + friend class btConvexHullComputer; public: - - class Edge + int getSourceVertex() const { - private: - int next; - int reverse; - int targetVertex; + return (this + reverse)->targetVertex; + } - friend class btConvexHullComputer; + int getTargetVertex() const + { + return targetVertex; + } - public: - int getSourceVertex() const - { - return (this + reverse)->targetVertex; - } + const Edge* getNextEdgeOfVertex() const // clockwise list of all edges of a vertex + { + return this + next; + } - int getTargetVertex() const - { - return targetVertex; - } + const Edge* getNextEdgeOfFace() const // counter-clockwise list of all edges of a face + { + return (this + reverse)->getNextEdgeOfVertex(); + } - const Edge* getNextEdgeOfVertex() const // clockwise list of all edges of a vertex - { - return this + next; - } + const Edge* getReverseEdge() const + { + return this + reverse; + } + }; - const Edge* getNextEdgeOfFace() const // counter-clockwise list of all edges of a face - { - return (this + reverse)->getNextEdgeOfVertex(); - } + // Vertices of the output hull + btAlignedObjectArray vertices; - const Edge* getReverseEdge() const - { - return this + reverse; - } - }; + // Edges of the output hull + btAlignedObjectArray edges; + // Faces of the convex hull. Each entry is an index into the "edges" array pointing to an edge of the face. Faces are planar n-gons + btAlignedObjectArray faces; - // Vertices of the output hull - btAlignedObjectArray vertices; - - // Edges of the output hull - btAlignedObjectArray edges; - - // Faces of the convex hull. Each entry is an index into the "edges" array pointing to an edge of the face. Faces are planar n-gons - btAlignedObjectArray faces; - - /* + /* Compute convex hull of "count" vertices stored in "coords". "stride" is the difference in bytes between the addresses of consecutive vertices. If "shrink" is positive, the convex hull is shrunken by that amount (each face is moved by "shrink" length units towards the center along its normal). @@ -86,18 +84,16 @@ class btConvexHullComputer The output convex hull can be found in the member variables "vertices", "edges", "faces". */ - btScalar compute(const float* coords, int stride, int count, btScalar shrink, btScalar shrinkClamp) - { - return compute(coords, false, stride, count, shrink, shrinkClamp); - } + btScalar compute(const float* coords, int stride, int count, btScalar shrink, btScalar shrinkClamp) + { + return compute(coords, false, stride, count, shrink, shrinkClamp); + } - // same as above, but double precision - btScalar compute(const double* coords, int stride, int count, btScalar shrink, btScalar shrinkClamp) - { - return compute(coords, true, stride, count, shrink, shrinkClamp); - } + // same as above, but double precision + btScalar compute(const double* coords, int stride, int count, btScalar shrink, btScalar shrinkClamp) + { + return compute(coords, true, stride, count, shrink, shrinkClamp); + } }; - -#endif //BT_CONVEX_HULL_COMPUTER_H - +#endif //BT_CONVEX_HULL_COMPUTER_H diff --git a/src/LinearMath/btCpuFeatureUtility.h b/src/LinearMath/btCpuFeatureUtility.h index d2cab52d4..5e4b9a313 100644 --- a/src/LinearMath/btCpuFeatureUtility.h +++ b/src/LinearMath/btCpuFeatureUtility.h @@ -4,20 +4,20 @@ #include "LinearMath/btScalar.h" -#include //memset -#ifdef USE_SIMD +#include //memset +#ifdef USE_SIMD #include #ifdef BT_ALLOW_SSE4 #include -#endif //BT_ALLOW_SSE4 -#endif //USE_SIMD +#endif //BT_ALLOW_SSE4 +#endif //USE_SIMD #if defined BT_USE_NEON -#define ARM_NEON_GCC_COMPATIBILITY 1 +#define ARM_NEON_GCC_COMPATIBILITY 1 #include #include -#include //for sysctlbyname -#endif //BT_USE_NEON +#include //for sysctlbyname +#endif //BT_USE_NEON ///Rudimentary btCpuFeatureUtility for CPU features: only report the features that Bullet actually uses (SSE4/FMA3, NEON_HPFP) ///We assume SSE2 in case BT_USE_SSE2 is defined in LinearMath/btScalar.h @@ -26,14 +26,13 @@ class btCpuFeatureUtility public: enum btCpuFeature { - CPU_FEATURE_FMA3=1, - CPU_FEATURE_SSE4_1=2, - CPU_FEATURE_NEON_HPFP=4 + CPU_FEATURE_FMA3 = 1, + CPU_FEATURE_SSE4_1 = 2, + CPU_FEATURE_NEON_HPFP = 4 }; static int getCpuFeatures() { - static int capabilities = 0; static bool testedCapabilities = false; if (0 != testedCapabilities) @@ -49,15 +48,15 @@ public: if (0 == err && hasFeature) capabilities |= CPU_FEATURE_NEON_HPFP; } -#endif //BT_USE_NEON +#endif //BT_USE_NEON -#ifdef BT_ALLOW_SSE4 +#ifdef BT_ALLOW_SSE4 { - int cpuInfo[4]; + int cpuInfo[4]; memset(cpuInfo, 0, sizeof(cpuInfo)); - unsigned long long sseExt = 0; + unsigned long long sseExt = 0; __cpuid(cpuInfo, 1); - + bool osUsesXSAVE_XRSTORE = cpuInfo[2] & (1 << 27) || false; bool cpuAVXSuport = cpuInfo[2] & (1 << 28) || false; @@ -79,14 +78,11 @@ public: capabilities |= btCpuFeatureUtility::CPU_FEATURE_SSE4_1; } } -#endif//BT_ALLOW_SSE4 +#endif //BT_ALLOW_SSE4 testedCapabilities = true; return capabilities; } - - }; - -#endif //BT_CPU_UTILITY_H +#endif //BT_CPU_UTILITY_H diff --git a/src/LinearMath/btDefaultMotionState.h b/src/LinearMath/btDefaultMotionState.h index 01c5f8d93..14c40d36b 100644 --- a/src/LinearMath/btDefaultMotionState.h +++ b/src/LinearMath/btDefaultMotionState.h @@ -4,39 +4,37 @@ #include "btMotionState.h" ///The btDefaultMotionState provides a common implementation to synchronize world transforms with offsets. -ATTRIBUTE_ALIGNED16(struct) btDefaultMotionState : public btMotionState +ATTRIBUTE_ALIGNED16(struct) +btDefaultMotionState : public btMotionState { btTransform m_graphicsWorldTrans; - btTransform m_centerOfMassOffset; + btTransform m_centerOfMassOffset; btTransform m_startWorldTrans; - void* m_userPointer; + void* m_userPointer; BT_DECLARE_ALIGNED_ALLOCATOR(); - btDefaultMotionState(const btTransform& startTrans = btTransform::getIdentity(),const btTransform& centerOfMassOffset = btTransform::getIdentity()) + btDefaultMotionState(const btTransform& startTrans = btTransform::getIdentity(), const btTransform& centerOfMassOffset = btTransform::getIdentity()) : m_graphicsWorldTrans(startTrans), - m_centerOfMassOffset(centerOfMassOffset), - m_startWorldTrans(startTrans), - m_userPointer(0) + m_centerOfMassOffset(centerOfMassOffset), + m_startWorldTrans(startTrans), + m_userPointer(0) { } ///synchronizes world transform from user to physics - virtual void getWorldTransform(btTransform& centerOfMassWorldTrans ) const + virtual void getWorldTransform(btTransform & centerOfMassWorldTrans) const { - centerOfMassWorldTrans = m_graphicsWorldTrans * m_centerOfMassOffset.inverse() ; + centerOfMassWorldTrans = m_graphicsWorldTrans * m_centerOfMassOffset.inverse(); } ///synchronizes world transform from physics to user ///Bullet only calls the update of worldtransform for active objects - virtual void setWorldTransform(const btTransform& centerOfMassWorldTrans) + virtual void setWorldTransform(const btTransform& centerOfMassWorldTrans) { - m_graphicsWorldTrans = centerOfMassWorldTrans * m_centerOfMassOffset; + m_graphicsWorldTrans = centerOfMassWorldTrans * m_centerOfMassOffset; } - - - }; -#endif //BT_DEFAULT_MOTION_STATE_H +#endif //BT_DEFAULT_MOTION_STATE_H diff --git a/src/LinearMath/btGeometryUtil.cpp b/src/LinearMath/btGeometryUtil.cpp index 5ac230f71..115e3eab8 100644 --- a/src/LinearMath/btGeometryUtil.cpp +++ b/src/LinearMath/btGeometryUtil.cpp @@ -12,49 +12,43 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #include "btGeometryUtil.h" - /* Make sure this dummy function never changes so that it can be used by probes that are checking whether the library is actually installed. */ extern "C" -{ - void btBulletMathProbe (); +{ + void btBulletMathProbe(); - void btBulletMathProbe () {} + void btBulletMathProbe() {} } - -bool btGeometryUtil::isPointInsidePlanes(const btAlignedObjectArray& planeEquations, const btVector3& point, btScalar margin) +bool btGeometryUtil::isPointInsidePlanes(const btAlignedObjectArray& planeEquations, const btVector3& point, btScalar margin) { int numbrushes = planeEquations.size(); - for (int i=0;ibtScalar(0.)) + btScalar dist = btScalar(N1.dot(point)) + btScalar(N1[3]) - margin; + if (dist > btScalar(0.)) { return false; } } return true; - } - -bool btGeometryUtil::areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray& vertices, btScalar margin) +bool btGeometryUtil::areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray& vertices, btScalar margin) { int numvertices = vertices.size(); - for (int i=0;ibtScalar(0.)) + btScalar dist = btScalar(planeNormal.dot(N1)) + btScalar(planeNormal[3]) - margin; + if (dist > btScalar(0.)) { return false; } @@ -62,102 +56,98 @@ bool btGeometryUtil::areVerticesBehindPlane(const btVector3& planeNormal, const return true; } -bool notExist(const btVector3& planeEquation,const btAlignedObjectArray& planeEquations); +bool notExist(const btVector3& planeEquation, const btAlignedObjectArray& planeEquations); -bool notExist(const btVector3& planeEquation,const btAlignedObjectArray& planeEquations) +bool notExist(const btVector3& planeEquation, const btAlignedObjectArray& planeEquations) { int numbrushes = planeEquations.size(); - for (int i=0;i btScalar(0.999)) { return false; - } + } } return true; } -void btGeometryUtil::getPlaneEquationsFromVertices(btAlignedObjectArray& vertices, btAlignedObjectArray& planeEquationsOut ) +void btGeometryUtil::getPlaneEquationsFromVertices(btAlignedObjectArray& vertices, btAlignedObjectArray& planeEquationsOut) { - const int numvertices = vertices.size(); + const int numvertices = vertices.size(); // brute force: - for (int i=0;i btScalar(0.0001)) { planeEquation.normalize(); - if (notExist(planeEquation,planeEquationsOut)) + if (notExist(planeEquation, planeEquationsOut)) { planeEquation[3] = -planeEquation.dot(N1); - - //check if inside, and replace supportingVertexOut if needed - if (areVerticesBehindPlane(planeEquation,vertices,btScalar(0.01))) - { - planeEquationsOut.push_back(planeEquation); - } + + //check if inside, and replace supportingVertexOut if needed + if (areVerticesBehindPlane(planeEquation, vertices, btScalar(0.01))) + { + planeEquationsOut.push_back(planeEquation); + } } } normalSign = btScalar(-1.); } - } } } - } -void btGeometryUtil::getVerticesFromPlaneEquations(const btAlignedObjectArray& planeEquations , btAlignedObjectArray& verticesOut ) +void btGeometryUtil::getVerticesFromPlaneEquations(const btAlignedObjectArray& planeEquations, btAlignedObjectArray& verticesOut) { const int numbrushes = planeEquations.size(); // brute force: - for (int i=0;i btScalar(0.0001) ) && - ( n3n1.length2() > btScalar(0.0001) ) && - ( n1n2.length2() > btScalar(0.0001) ) ) + btVector3 n2n3; + n2n3 = N2.cross(N3); + btVector3 n3n1; + n3n1 = N3.cross(N1); + btVector3 n1n2; + n1n2 = N1.cross(N2); + + if ((n2n3.length2() > btScalar(0.0001)) && + (n3n1.length2() > btScalar(0.0001)) && + (n1n2.length2() > btScalar(0.0001))) { //point P out of 3 plane equations: - // d1 ( N2 * N3 ) + d2 ( N3 * N1 ) + d3 ( N1 * N2 ) - //P = ------------------------------------------------------------------------- - // N1 . ( N2 * N3 ) - + // d1 ( N2 * N3 ) + d2 ( N3 * N1 ) + d3 ( N1 * N2 ) + //P = ------------------------------------------------------------------------- + // N1 . ( N2 * N3 ) btScalar quotient = (N1.dot(n2n3)); if (btFabs(quotient) > btScalar(0.000001)) @@ -172,7 +162,7 @@ void btGeometryUtil::getVerticesFromPlaneEquations(const btAlignedObjectArray& vertices, btAlignedObjectArray& planeEquationsOut ); +public: + static void getPlaneEquationsFromVertices(btAlignedObjectArray& vertices, btAlignedObjectArray& planeEquationsOut); - static void getVerticesFromPlaneEquations(const btAlignedObjectArray& planeEquations , btAlignedObjectArray& verticesOut ); - - static bool isInside(const btAlignedObjectArray& vertices, const btVector3& planeNormal, btScalar margin); - - static bool isPointInsidePlanes(const btAlignedObjectArray& planeEquations, const btVector3& point, btScalar margin); + static void getVerticesFromPlaneEquations(const btAlignedObjectArray& planeEquations, btAlignedObjectArray& verticesOut); - static bool areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray& vertices, btScalar margin); + static bool isInside(const btAlignedObjectArray& vertices, const btVector3& planeNormal, btScalar margin); + static bool isPointInsidePlanes(const btAlignedObjectArray& planeEquations, const btVector3& point, btScalar margin); + + static bool areVerticesBehindPlane(const btVector3& planeNormal, const btAlignedObjectArray& vertices, btScalar margin); }; - -#endif //BT_GEOMETRY_UTIL_H - +#endif //BT_GEOMETRY_UTIL_H diff --git a/src/LinearMath/btGrahamScan2dConvexHull.h b/src/LinearMath/btGrahamScan2dConvexHull.h index 13a79aa58..0fcb28597 100644 --- a/src/LinearMath/btGrahamScan2dConvexHull.h +++ b/src/LinearMath/btGrahamScan2dConvexHull.h @@ -13,41 +13,40 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef GRAHAM_SCAN_2D_CONVEX_HULL_H #define GRAHAM_SCAN_2D_CONVEX_HULL_H - #include "btVector3.h" #include "btAlignedObjectArray.h" struct GrahamVector3 : public btVector3 { GrahamVector3(const btVector3& org, int orgIndex) - :btVector3(org), - m_orgIndex(orgIndex) + : btVector3(org), + m_orgIndex(orgIndex) { } - btScalar m_angle; + btScalar m_angle; int m_orgIndex; }; - -struct btAngleCompareFunc { +struct btAngleCompareFunc +{ btVector3 m_anchor; btAngleCompareFunc(const btVector3& anchor) - : m_anchor(anchor) + : m_anchor(anchor) { } - bool operator()(const GrahamVector3& a, const GrahamVector3& b) const { + bool operator()(const GrahamVector3& a, const GrahamVector3& b) const + { if (a.m_angle != b.m_angle) return a.m_angle < b.m_angle; else { - btScalar al = (a-m_anchor).length2(); - btScalar bl = (b-m_anchor).length2(); + btScalar al = (a - m_anchor).length2(); + btScalar bl = (b - m_anchor).length2(); if (al != bl) - return al < bl; + return al < bl; else { return a.m_orgIndex < b.m_orgIndex; @@ -58,73 +57,73 @@ struct btAngleCompareFunc { inline void GrahamScanConvexHull2D(btAlignedObjectArray& originalPoints, btAlignedObjectArray& hull, const btVector3& normalAxis) { - btVector3 axis0,axis1; - btPlaneSpace1(normalAxis,axis0,axis1); - + btVector3 axis0, axis1; + btPlaneSpace1(normalAxis, axis0, axis1); - if (originalPoints.size()<=1) + if (originalPoints.size() <= 1) { - for (int i=0;i1) { - btVector3& a = hull[hull.size()-2]; - btVector3& b = hull[hull.size()-1]; - isConvex = btCross(a-b,a-originalPoints[i]).dot(normalAxis)> 0; + while (!isConvex && hull.size() > 1) + { + btVector3& a = hull[hull.size() - 2]; + btVector3& b = hull[hull.size() - 1]; + isConvex = btCross(a - b, a - originalPoints[i]).dot(normalAxis) > 0; if (!isConvex) hull.pop_back(); - else + else hull.push_back(originalPoints[i]); } - if( hull.size() == 1 ) - { - hull.push_back( originalPoints[i] ); - } + if (hull.size() == 1) + { + hull.push_back(originalPoints[i]); + } } } -#endif //GRAHAM_SCAN_2D_CONVEX_HULL_H +#endif //GRAHAM_SCAN_2D_CONVEX_HULL_H diff --git a/src/LinearMath/btHashMap.h b/src/LinearMath/btHashMap.h index 180e7b44a..1fca0fb73 100644 --- a/src/LinearMath/btHashMap.h +++ b/src/LinearMath/btHashMap.h @@ -13,7 +13,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef BT_HASH_MAP_H #define BT_HASH_MAP_H @@ -24,32 +23,32 @@ subject to the following restrictions: struct btHashString { std::string m_string1; - unsigned int m_hash; + unsigned int m_hash; - SIMD_FORCE_INLINE unsigned int getHash()const + SIMD_FORCE_INLINE unsigned int getHash() const { return m_hash; } btHashString() { - m_string1=""; - m_hash=0; + m_string1 = ""; + m_hash = 0; } btHashString(const char* name) - :m_string1(name) + : m_string1(name) { /* magic numbers from http://www.isthe.com/chongo/tech/comp/fnv/ */ - static const unsigned int InitialFNV = 2166136261u; + static const unsigned int InitialFNV = 2166136261u; static const unsigned int FNVMultiple = 16777619u; /* Fowler / Noll / Vo (FNV) Hash */ unsigned int hash = InitialFNV; - - for(int i = 0; m_string1.c_str()[i]; i++) + + for (int i = 0; m_string1.c_str()[i]; i++) { - hash = hash ^ (m_string1.c_str()[i]); /* xor the low 8 bits */ - hash = hash * FNVMultiple; /* multiply by the magic number */ + hash = hash ^ (m_string1.c_str()[i]); /* xor the low 8 bits */ + hash = hash * FNVMultiple; /* multiply by the magic number */ } m_hash = hash; } @@ -60,28 +59,27 @@ struct btHashString } }; -const int BT_HASH_NULL=0xffffffff; - +const int BT_HASH_NULL = 0xffffffff; class btHashInt { - int m_uid; -public: + int m_uid; +public: btHashInt() { } - btHashInt(int uid) :m_uid(uid) + btHashInt(int uid) : m_uid(uid) { } - int getUid1() const + int getUid1() const { return m_uid; } - void setUid1(int uid) + void setUid1(int uid) { m_uid = uid; } @@ -91,35 +89,35 @@ public: return getUid1() == other.getUid1(); } //to our success - SIMD_FORCE_INLINE unsigned int getHash()const + SIMD_FORCE_INLINE unsigned int getHash() const { unsigned int key = m_uid; // Thomas Wang's hash - key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16); - + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); + return key; } }; - - class btHashPtr { - - union - { - const void* m_pointer; - unsigned int m_hashValues[2]; + union { + const void* m_pointer; + unsigned int m_hashValues[2]; }; public: - btHashPtr(const void* ptr) - :m_pointer(ptr) + : m_pointer(ptr) { } - const void* getPointer() const + const void* getPointer() const { return m_pointer; } @@ -130,64 +128,68 @@ public: } //to our success - SIMD_FORCE_INLINE unsigned int getHash()const + SIMD_FORCE_INLINE unsigned int getHash() const { - const bool VOID_IS_8 = ((sizeof(void*)==8)); - - unsigned int key = VOID_IS_8? m_hashValues[0]+m_hashValues[1] : m_hashValues[0]; + const bool VOID_IS_8 = ((sizeof(void*) == 8)); + + unsigned int key = VOID_IS_8 ? m_hashValues[0] + m_hashValues[1] : m_hashValues[0]; // Thomas Wang's hash - key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16); + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); return key; } - - }; - template class btHashKeyPtr { - int m_uid; + int m_uid; + public: + btHashKeyPtr(int uid) : m_uid(uid) + { + } - btHashKeyPtr(int uid) :m_uid(uid) - { - } + int getUid1() const + { + return m_uid; + } - int getUid1() const - { - return m_uid; - } + bool equals(const btHashKeyPtr& other) const + { + return getUid1() == other.getUid1(); + } - bool equals(const btHashKeyPtr& other) const - { - return getUid1() == other.getUid1(); - } - - //to our success - SIMD_FORCE_INLINE unsigned int getHash()const - { - unsigned int key = m_uid; - // Thomas Wang's hash - key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16); - return key; - } - - + //to our success + SIMD_FORCE_INLINE unsigned int getHash() const + { + unsigned int key = m_uid; + // Thomas Wang's hash + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); + return key; + } }; - template class btHashKey { - int m_uid; -public: + int m_uid; - btHashKey(int uid) :m_uid(uid) +public: + btHashKey(int uid) : m_uid(uid) { } - int getUid1() const + int getUid1() const { return m_uid; } @@ -197,30 +199,33 @@ public: return getUid1() == other.getUid1(); } //to our success - SIMD_FORCE_INLINE unsigned int getHash()const + SIMD_FORCE_INLINE unsigned int getHash() const { unsigned int key = m_uid; // Thomas Wang's hash - key += ~(key << 15); key ^= (key >> 10); key += (key << 3); key ^= (key >> 6); key += ~(key << 11); key ^= (key >> 16); + key += ~(key << 15); + key ^= (key >> 10); + key += (key << 3); + key ^= (key >> 6); + key += ~(key << 11); + key ^= (key >> 16); return key; } }; - ///The btHashMap template class implements a generic and lightweight hashmap. ///A basic sample of how to use btHashMap is located in Demos\BasicDemo\main.cpp template class btHashMap { - protected: - btAlignedObjectArray m_hashTable; - btAlignedObjectArray m_next; - - btAlignedObjectArray m_valueArray; - btAlignedObjectArray m_keyArray; + btAlignedObjectArray m_hashTable; + btAlignedObjectArray m_next; - void growTables(const Key& /*key*/) + btAlignedObjectArray m_valueArray; + btAlignedObjectArray m_keyArray; + + void growTables(const Key& /*key*/) { int newCapacity = m_valueArray.capacity(); @@ -234,7 +239,7 @@ protected: int i; - for (i= 0; i < newCapacity; ++i) + for (i = 0; i < newCapacity; ++i) { m_hashTable[i] = BT_HASH_NULL; } @@ -243,30 +248,28 @@ protected: m_next[i] = BT_HASH_NULL; } - for(i=0;i=0); - if (index>=0 && index < m_valueArray.size()) + btAssert(index >= 0); + if (index >= 0 && index < m_valueArray.size()) { return &m_valueArray[index]; } @@ -388,38 +389,39 @@ protected: Value* getAtIndex(int index) { btAssert(index < m_valueArray.size()); - btAssert(index>=0); - if (index>=0 && index < m_valueArray.size()) + btAssert(index >= 0); + if (index >= 0 && index < m_valueArray.size()) { return &m_valueArray[index]; } return 0; } - Key getKeyAtIndex(int index) - { - btAssert(index < m_keyArray.size()); - btAssert(index>=0); + Key getKeyAtIndex(int index) + { + btAssert(index < m_keyArray.size()); + btAssert(index >= 0); return m_keyArray[index]; - } - - const Key getKeyAtIndex(int index) const - { - btAssert(index < m_keyArray.size()); - btAssert(index>=0); + } + + const Key getKeyAtIndex(int index) const + { + btAssert(index < m_keyArray.size()); + btAssert(index >= 0); return m_keyArray[index]; - } + } - - Value* operator[](const Key& key) { + Value* operator[](const Key& key) + { return find(key); } - const Value* operator[](const Key& key) const { + const Value* operator[](const Key& key) const + { return find(key); } - const Value* find(const Key& key) const + const Value* find(const Key& key) const { int index = findIndex(key); if (index == BT_HASH_NULL) @@ -429,7 +431,7 @@ protected: return &m_valueArray[index]; } - Value* find(const Key& key) + Value* find(const Key& key) { int index = findIndex(key); if (index == BT_HASH_NULL) @@ -439,10 +441,9 @@ protected: return &m_valueArray[index]; } - - int findIndex(const Key& key) const + int findIndex(const Key& key) const { - unsigned int hash = key.getHash() & (m_valueArray.capacity()-1); + unsigned int hash = key.getHash() & (m_valueArray.capacity() - 1); if (hash >= (unsigned int)m_hashTable.size()) { @@ -457,14 +458,13 @@ protected: return index; } - void clear() + void clear() { m_hashTable.clear(); m_next.clear(); m_valueArray.clear(); m_keyArray.clear(); } - }; -#endif //BT_HASH_MAP_H +#endif //BT_HASH_MAP_H diff --git a/src/LinearMath/btIDebugDraw.h b/src/LinearMath/btIDebugDraw.h index b57282717..82ec19a69 100644 --- a/src/LinearMath/btIDebugDraw.h +++ b/src/LinearMath/btIDebugDraw.h @@ -13,86 +13,84 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef BT_IDEBUG_DRAW__H #define BT_IDEBUG_DRAW__H #include "btVector3.h" #include "btTransform.h" - - ///The btIDebugDraw interface class allows hooking up a debug renderer to visually debug simulations. ///Typical use case: create a debug drawer object, and assign it to a btCollisionWorld or btDynamicsWorld using setDebugDrawer and call debugDrawWorld. ///A class that implements the btIDebugDraw interface has to implement the drawLine method at a minimum. ///For color arguments the X,Y,Z components refer to Red, Green and Blue each in the range [0..1] -class btIDebugDraw +class btIDebugDraw { - public: - - ATTRIBUTE_ALIGNED16(struct) DefaultColors +public: + ATTRIBUTE_ALIGNED16(struct) + DefaultColors { - btVector3 m_activeObject; - btVector3 m_deactivatedObject; - btVector3 m_wantsDeactivationObject; - btVector3 m_disabledDeactivationObject; - btVector3 m_disabledSimulationObject; - btVector3 m_aabb; + btVector3 m_activeObject; + btVector3 m_deactivatedObject; + btVector3 m_wantsDeactivationObject; + btVector3 m_disabledDeactivationObject; + btVector3 m_disabledSimulationObject; + btVector3 m_aabb; btVector3 m_contactPoint; - + DefaultColors() - : m_activeObject(1,1,1), - m_deactivatedObject(0,1,0), - m_wantsDeactivationObject(0,1,1), - m_disabledDeactivationObject(1,0,0), - m_disabledSimulationObject(1,1,0), - m_aabb(1,0,0), - m_contactPoint(1,1,0) + : m_activeObject(1, 1, 1), + m_deactivatedObject(0, 1, 0), + m_wantsDeactivationObject(0, 1, 1), + m_disabledDeactivationObject(1, 0, 0), + m_disabledSimulationObject(1, 1, 0), + m_aabb(1, 0, 0), + m_contactPoint(1, 1, 0) { } }; - - enum DebugDrawModes + enum DebugDrawModes { - DBG_NoDebug=0, + DBG_NoDebug = 0, DBG_DrawWireframe = 1, - DBG_DrawAabb=2, - DBG_DrawFeaturesText=4, - DBG_DrawContactPoints=8, - DBG_NoDeactivation=16, + DBG_DrawAabb = 2, + DBG_DrawFeaturesText = 4, + DBG_DrawContactPoints = 8, + DBG_NoDeactivation = 16, DBG_NoHelpText = 32, - DBG_DrawText=64, + DBG_DrawText = 64, DBG_ProfileTimings = 128, DBG_EnableSatComparison = 256, DBG_DisableBulletLCP = 512, DBG_EnableCCD = 1024, DBG_DrawConstraints = (1 << 11), DBG_DrawConstraintLimits = (1 << 12), - DBG_FastWireframe = (1<<13), - DBG_DrawNormals = (1<<14), - DBG_DrawFrames = (1<<15), + DBG_FastWireframe = (1 << 13), + DBG_DrawNormals = (1 << 14), + DBG_DrawFrames = (1 << 15), DBG_MAX_DEBUG_DRAW_MODE }; - virtual ~btIDebugDraw() {}; + virtual ~btIDebugDraw(){}; - - virtual DefaultColors getDefaultColors() const { DefaultColors colors; return colors; } + virtual DefaultColors getDefaultColors() const + { + DefaultColors colors; + return colors; + } ///the default implementation for setDefaultColors has no effect. A derived class can implement it and store the colors. virtual void setDefaultColors(const DefaultColors& /*colors*/) {} - - virtual void drawLine(const btVector3& from,const btVector3& to,const btVector3& color)=0; - - virtual void drawLine(const btVector3& from,const btVector3& to, const btVector3& fromColor, const btVector3& toColor) + + virtual void drawLine(const btVector3& from, const btVector3& to, const btVector3& color) = 0; + + virtual void drawLine(const btVector3& from, const btVector3& to, const btVector3& fromColor, const btVector3& toColor) { - (void) toColor; - drawLine (from, to, fromColor); + (void)toColor; + drawLine(from, to, fromColor); } - virtual void drawSphere(btScalar radius, const btTransform& transform, const btVector3& color) + virtual void drawSphere(btScalar radius, const btTransform& transform, const btVector3& color) { - btVector3 center = transform.getOrigin(); btVector3 up = transform.getBasis().getColumn(1); btVector3 axis = transform.getBasis().getColumn(0); @@ -101,103 +99,102 @@ class btIDebugDraw btScalar minPs = -SIMD_HALF_PI; btScalar maxPs = SIMD_HALF_PI; btScalar stepDegrees = 30.f; - drawSpherePatch(center, up, axis, radius,minTh, maxTh, minPs, maxPs, color, stepDegrees ,false); - drawSpherePatch(center, up, -axis, radius,minTh, maxTh, minPs, maxPs, color, stepDegrees,false ); + drawSpherePatch(center, up, axis, radius, minTh, maxTh, minPs, maxPs, color, stepDegrees, false); + drawSpherePatch(center, up, -axis, radius, minTh, maxTh, minPs, maxPs, color, stepDegrees, false); } - - virtual void drawSphere (const btVector3& p, btScalar radius, const btVector3& color) + + virtual void drawSphere(const btVector3& p, btScalar radius, const btVector3& color) { btTransform tr; tr.setIdentity(); tr.setOrigin(p); - drawSphere(radius,tr,color); - } - - virtual void drawTriangle(const btVector3& v0,const btVector3& v1,const btVector3& v2,const btVector3& /*n0*/,const btVector3& /*n1*/,const btVector3& /*n2*/,const btVector3& color, btScalar alpha) - { - drawTriangle(v0,v1,v2,color,alpha); - } - virtual void drawTriangle(const btVector3& v0,const btVector3& v1,const btVector3& v2,const btVector3& color, btScalar /*alpha*/) - { - drawLine(v0,v1,color); - drawLine(v1,v2,color); - drawLine(v2,v0,color); + drawSphere(radius, tr, color); } - virtual void drawContactPoint(const btVector3& PointOnB,const btVector3& normalOnB,btScalar distance,int lifeTime,const btVector3& color)=0; - - virtual void reportErrorWarning(const char* warningString) = 0; - - virtual void draw3dText(const btVector3& location,const char* textString) = 0; - - virtual void setDebugMode(int debugMode) =0; - - virtual int getDebugMode() const = 0; - - virtual void drawAabb(const btVector3& from,const btVector3& to,const btVector3& color) + virtual void drawTriangle(const btVector3& v0, const btVector3& v1, const btVector3& v2, const btVector3& /*n0*/, const btVector3& /*n1*/, const btVector3& /*n2*/, const btVector3& color, btScalar alpha) { + drawTriangle(v0, v1, v2, color, alpha); + } + virtual void drawTriangle(const btVector3& v0, const btVector3& v1, const btVector3& v2, const btVector3& color, btScalar /*alpha*/) + { + drawLine(v0, v1, color); + drawLine(v1, v2, color); + drawLine(v2, v0, color); + } - btVector3 halfExtents = (to-from)* 0.5f; - btVector3 center = (to+from) *0.5f; - int i,j; + virtual void drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color) = 0; - btVector3 edgecoord(1.f,1.f,1.f),pa,pb; - for (i=0;i<4;i++) + virtual void reportErrorWarning(const char* warningString) = 0; + + virtual void draw3dText(const btVector3& location, const char* textString) = 0; + + virtual void setDebugMode(int debugMode) = 0; + + virtual int getDebugMode() const = 0; + + virtual void drawAabb(const btVector3& from, const btVector3& to, const btVector3& color) + { + btVector3 halfExtents = (to - from) * 0.5f; + btVector3 center = (to + from) * 0.5f; + int i, j; + + btVector3 edgecoord(1.f, 1.f, 1.f), pa, pb; + for (i = 0; i < 4; i++) { - for (j=0;j<3;j++) + for (j = 0; j < 3; j++) { - pa = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1], - edgecoord[2]*halfExtents[2]); - pa+=center; + pa = btVector3(edgecoord[0] * halfExtents[0], edgecoord[1] * halfExtents[1], + edgecoord[2] * halfExtents[2]); + pa += center; - int othercoord = j%3; - edgecoord[othercoord]*=-1.f; - pb = btVector3(edgecoord[0]*halfExtents[0], edgecoord[1]*halfExtents[1], - edgecoord[2]*halfExtents[2]); - pb+=center; + int othercoord = j % 3; + edgecoord[othercoord] *= -1.f; + pb = btVector3(edgecoord[0] * halfExtents[0], edgecoord[1] * halfExtents[1], + edgecoord[2] * halfExtents[2]); + pb += center; - drawLine(pa,pb,color); + drawLine(pa, pb, color); } - edgecoord = btVector3(-1.f,-1.f,-1.f); - if (i<3) - edgecoord[i]*=-1.f; + edgecoord = btVector3(-1.f, -1.f, -1.f); + if (i < 3) + edgecoord[i] *= -1.f; } } virtual void drawTransform(const btTransform& transform, btScalar orthoLen) { btVector3 start = transform.getOrigin(); - drawLine(start, start+transform.getBasis() * btVector3(orthoLen, 0, 0), btVector3(btScalar(1.), btScalar(0.3), btScalar(0.3))); - drawLine(start, start+transform.getBasis() * btVector3(0, orthoLen, 0), btVector3(btScalar(0.3), btScalar(1.), btScalar(0.3))); - drawLine(start, start+transform.getBasis() * btVector3(0, 0, orthoLen), btVector3(btScalar(0.3), btScalar(0.3), btScalar(1.))); + drawLine(start, start + transform.getBasis() * btVector3(orthoLen, 0, 0), btVector3(btScalar(1.), btScalar(0.3), btScalar(0.3))); + drawLine(start, start + transform.getBasis() * btVector3(0, orthoLen, 0), btVector3(btScalar(0.3), btScalar(1.), btScalar(0.3))); + drawLine(start, start + transform.getBasis() * btVector3(0, 0, orthoLen), btVector3(btScalar(0.3), btScalar(0.3), btScalar(1.))); } - virtual void drawArc(const btVector3& center, const btVector3& normal, const btVector3& axis, btScalar radiusA, btScalar radiusB, btScalar minAngle, btScalar maxAngle, - const btVector3& color, bool drawSect, btScalar stepDegrees = btScalar(10.f)) + virtual void drawArc(const btVector3& center, const btVector3& normal, const btVector3& axis, btScalar radiusA, btScalar radiusB, btScalar minAngle, btScalar maxAngle, + const btVector3& color, bool drawSect, btScalar stepDegrees = btScalar(10.f)) { const btVector3& vx = axis; btVector3 vy = normal.cross(axis); btScalar step = stepDegrees * SIMD_RADS_PER_DEG; int nSteps = (int)btFabs((maxAngle - minAngle) / step); - if(!nSteps) nSteps = 1; + if (!nSteps) nSteps = 1; btVector3 prev = center + radiusA * vx * btCos(minAngle) + radiusB * vy * btSin(minAngle); - if(drawSect) + if (drawSect) { drawLine(center, prev, color); } - for(int i = 1; i <= nSteps; i++) + for (int i = 1; i <= nSteps; i++) { btScalar angle = minAngle + (maxAngle - minAngle) * btScalar(i) / btScalar(nSteps); btVector3 next = center + radiusA * vx * btCos(angle) + radiusB * vy * btSin(angle); drawLine(prev, next, color); prev = next; } - if(drawSect) + if (drawSect) { drawLine(center, prev, color); } } - virtual void drawSpherePatch(const btVector3& center, const btVector3& up, const btVector3& axis, btScalar radius, - btScalar minTh, btScalar maxTh, btScalar minPs, btScalar maxPs, const btVector3& color, btScalar stepDegrees = btScalar(10.f),bool drawCenter = true) + virtual void drawSpherePatch(const btVector3& center, const btVector3& up, const btVector3& axis, btScalar radius, + btScalar minTh, btScalar maxTh, btScalar minPs, btScalar maxPs, const btVector3& color, btScalar stepDegrees = btScalar(10.f), bool drawCenter = true) { btVector3 vA[74]; btVector3 vB[74]; @@ -211,33 +208,33 @@ class btIDebugDraw btVector3 jv = kv.cross(iv); bool drawN = false; bool drawS = false; - if(minTh <= -SIMD_HALF_PI) + if (minTh <= -SIMD_HALF_PI) { minTh = -SIMD_HALF_PI + step; drawN = true; } - if(maxTh >= SIMD_HALF_PI) + if (maxTh >= SIMD_HALF_PI) { maxTh = SIMD_HALF_PI - step; drawS = true; } - if(minTh > maxTh) + if (minTh > maxTh) { minTh = -SIMD_HALF_PI + step; - maxTh = SIMD_HALF_PI - step; + maxTh = SIMD_HALF_PI - step; drawN = drawS = true; } int n_hor = (int)((maxTh - minTh) / step) + 1; - if(n_hor < 2) n_hor = 2; + if (n_hor < 2) n_hor = 2; btScalar step_h = (maxTh - minTh) / btScalar(n_hor - 1); bool isClosed = false; - if(minPs > maxPs) + if (minPs > maxPs) { minPs = -SIMD_PI + step; - maxPs = SIMD_PI; + maxPs = SIMD_PI; isClosed = true; } - else if((maxPs - minPs) >= SIMD_PI * btScalar(2.f)) + else if ((maxPs - minPs) >= SIMD_PI * btScalar(2.f)) { isClosed = true; } @@ -246,63 +243,64 @@ class btIDebugDraw isClosed = false; } int n_vert = (int)((maxPs - minPs) / step) + 1; - if(n_vert < 2) n_vert = 2; + if (n_vert < 2) n_vert = 2; btScalar step_v = (maxPs - minPs) / btScalar(n_vert - 1); - for(int i = 0; i < n_hor; i++) + for (int i = 0; i < n_hor; i++) { btScalar th = minTh + btScalar(i) * step_h; btScalar sth = radius * btSin(th); btScalar cth = radius * btCos(th); - for(int j = 0; j < n_vert; j++) + for (int j = 0; j < n_vert; j++) { btScalar psi = minPs + btScalar(j) * step_v; btScalar sps = btSin(psi); btScalar cps = btCos(psi); pvB[j] = center + cth * cps * iv + cth * sps * jv + sth * kv; - if(i) + if (i) { drawLine(pvA[j], pvB[j], color); } - else if(drawS) + else if (drawS) { drawLine(spole, pvB[j], color); } - if(j) + if (j) { - drawLine(pvB[j-1], pvB[j], color); + drawLine(pvB[j - 1], pvB[j], color); } else { arcStart = pvB[j]; } - if((i == (n_hor - 1)) && drawN) + if ((i == (n_hor - 1)) && drawN) { drawLine(npole, pvB[j], color); } - + if (drawCenter) { - if(isClosed) + if (isClosed) { - if(j == (n_vert-1)) + if (j == (n_vert - 1)) { drawLine(arcStart, pvB[j], color); } } else { - if(((!i) || (i == (n_hor-1))) && ((!j) || (j == (n_vert-1)))) + if (((!i) || (i == (n_hor - 1))) && ((!j) || (j == (n_vert - 1)))) { drawLine(center, pvB[j], color); } } } } - pT = pvA; pvA = pvB; pvB = pT; + pT = pvA; + pvA = pvB; + pvB = pT; } } - - + virtual void drawBox(const btVector3& bbMin, const btVector3& bbMax, const btVector3& color) { drawLine(btVector3(bbMin[0], bbMin[1], bbMin[2]), btVector3(bbMax[0], bbMin[1], bbMin[2]), color); @@ -338,31 +336,27 @@ class btIDebugDraw { int stepDegrees = 30; - btVector3 capStart(0.f,0.f,0.f); + btVector3 capStart(0.f, 0.f, 0.f); capStart[upAxis] = -halfHeight; - btVector3 capEnd(0.f,0.f,0.f); + btVector3 capEnd(0.f, 0.f, 0.f); capEnd[upAxis] = halfHeight; // Draw the ends { - btTransform childTransform = transform; childTransform.getOrigin() = transform * capStart; { btVector3 center = childTransform.getOrigin(); - btVector3 up = childTransform.getBasis().getColumn((upAxis+1)%3); + btVector3 up = childTransform.getBasis().getColumn((upAxis + 1) % 3); btVector3 axis = -childTransform.getBasis().getColumn(upAxis); btScalar minTh = -SIMD_HALF_PI; btScalar maxTh = SIMD_HALF_PI; btScalar minPs = -SIMD_HALF_PI; btScalar maxPs = SIMD_HALF_PI; - - drawSpherePatch(center, up, axis, radius,minTh, maxTh, minPs, maxPs, color, btScalar(stepDegrees) ,false); + + drawSpherePatch(center, up, axis, radius, minTh, maxTh, minPs, maxPs, color, btScalar(stepDegrees), false); } - - - } { @@ -370,52 +364,51 @@ class btIDebugDraw childTransform.getOrigin() = transform * capEnd; { btVector3 center = childTransform.getOrigin(); - btVector3 up = childTransform.getBasis().getColumn((upAxis+1)%3); + btVector3 up = childTransform.getBasis().getColumn((upAxis + 1) % 3); btVector3 axis = childTransform.getBasis().getColumn(upAxis); btScalar minTh = -SIMD_HALF_PI; btScalar maxTh = SIMD_HALF_PI; btScalar minPs = -SIMD_HALF_PI; btScalar maxPs = SIMD_HALF_PI; - drawSpherePatch(center, up, axis, radius,minTh, maxTh, minPs, maxPs, color, btScalar(stepDegrees) ,false); + drawSpherePatch(center, up, axis, radius, minTh, maxTh, minPs, maxPs, color, btScalar(stepDegrees), false); } } // Draw some additional lines btVector3 start = transform.getOrigin(); - for (int i=0;i<360;i+=stepDegrees) + for (int i = 0; i < 360; i += stepDegrees) { - capEnd[(upAxis+1)%3] = capStart[(upAxis+1)%3] = btSin(btScalar(i)*SIMD_RADS_PER_DEG)*radius; - capEnd[(upAxis+2)%3] = capStart[(upAxis+2)%3] = btCos(btScalar(i)*SIMD_RADS_PER_DEG)*radius; - drawLine(start+transform.getBasis() * capStart,start+transform.getBasis() * capEnd, color); + capEnd[(upAxis + 1) % 3] = capStart[(upAxis + 1) % 3] = btSin(btScalar(i) * SIMD_RADS_PER_DEG) * radius; + capEnd[(upAxis + 2) % 3] = capStart[(upAxis + 2) % 3] = btCos(btScalar(i) * SIMD_RADS_PER_DEG) * radius; + drawLine(start + transform.getBasis() * capStart, start + transform.getBasis() * capEnd, color); } - } virtual void drawCylinder(btScalar radius, btScalar halfHeight, int upAxis, const btTransform& transform, const btVector3& color) { btVector3 start = transform.getOrigin(); - btVector3 offsetHeight(0,0,0); + btVector3 offsetHeight(0, 0, 0); offsetHeight[upAxis] = halfHeight; - int stepDegrees=30; - btVector3 capStart(0.f,0.f,0.f); + int stepDegrees = 30; + btVector3 capStart(0.f, 0.f, 0.f); capStart[upAxis] = -halfHeight; - btVector3 capEnd(0.f,0.f,0.f); + btVector3 capEnd(0.f, 0.f, 0.f); capEnd[upAxis] = halfHeight; - for (int i=0;i<360;i+=stepDegrees) + for (int i = 0; i < 360; i += stepDegrees) { - capEnd[(upAxis+1)%3] = capStart[(upAxis+1)%3] = btSin(btScalar(i)*SIMD_RADS_PER_DEG)*radius; - capEnd[(upAxis+2)%3] = capStart[(upAxis+2)%3] = btCos(btScalar(i)*SIMD_RADS_PER_DEG)*radius; - drawLine(start+transform.getBasis() * capStart,start+transform.getBasis() * capEnd, color); + capEnd[(upAxis + 1) % 3] = capStart[(upAxis + 1) % 3] = btSin(btScalar(i) * SIMD_RADS_PER_DEG) * radius; + capEnd[(upAxis + 2) % 3] = capStart[(upAxis + 2) % 3] = btCos(btScalar(i) * SIMD_RADS_PER_DEG) * radius; + drawLine(start + transform.getBasis() * capStart, start + transform.getBasis() * capEnd, color); } // Drawing top and bottom caps of the cylinder - btVector3 yaxis(0,0,0); + btVector3 yaxis(0, 0, 0); yaxis[upAxis] = btScalar(1.0); - btVector3 xaxis(0,0,0); - xaxis[(upAxis+1)%3] = btScalar(1.0); - drawArc(start-transform.getBasis()*(offsetHeight),transform.getBasis()*yaxis,transform.getBasis()*xaxis,radius,radius,0,SIMD_2_PI,color,false,btScalar(10.0)); - drawArc(start+transform.getBasis()*(offsetHeight),transform.getBasis()*yaxis,transform.getBasis()*xaxis,radius,radius,0,SIMD_2_PI,color,false,btScalar(10.0)); + btVector3 xaxis(0, 0, 0); + xaxis[(upAxis + 1) % 3] = btScalar(1.0); + drawArc(start - transform.getBasis() * (offsetHeight), transform.getBasis() * yaxis, transform.getBasis() * xaxis, radius, radius, 0, SIMD_2_PI, color, false, btScalar(10.0)); + drawArc(start + transform.getBasis() * (offsetHeight), transform.getBasis() * yaxis, transform.getBasis() * xaxis, radius, radius, 0, SIMD_2_PI, color, false, btScalar(10.0)); } virtual void drawCone(btScalar radius, btScalar height, int upAxis, const btTransform& transform, const btVector3& color) @@ -423,50 +416,49 @@ class btIDebugDraw int stepDegrees = 30; btVector3 start = transform.getOrigin(); - btVector3 offsetHeight(0,0,0); + btVector3 offsetHeight(0, 0, 0); btScalar halfHeight = height * btScalar(0.5); offsetHeight[upAxis] = halfHeight; - btVector3 offsetRadius(0,0,0); - offsetRadius[(upAxis+1)%3] = radius; - btVector3 offset2Radius(0,0,0); - offset2Radius[(upAxis+2)%3] = radius; + btVector3 offsetRadius(0, 0, 0); + offsetRadius[(upAxis + 1) % 3] = radius; + btVector3 offset2Radius(0, 0, 0); + offset2Radius[(upAxis + 2) % 3] = radius; - - btVector3 capEnd(0.f,0.f,0.f); + btVector3 capEnd(0.f, 0.f, 0.f); capEnd[upAxis] = -halfHeight; - for (int i=0;i<360;i+=stepDegrees) + for (int i = 0; i < 360; i += stepDegrees) { - capEnd[(upAxis+1)%3] = btSin(btScalar(i)*SIMD_RADS_PER_DEG)*radius; - capEnd[(upAxis+2)%3] = btCos(btScalar(i)*SIMD_RADS_PER_DEG)*radius; - drawLine(start+transform.getBasis() * (offsetHeight),start+transform.getBasis() * capEnd, color); + capEnd[(upAxis + 1) % 3] = btSin(btScalar(i) * SIMD_RADS_PER_DEG) * radius; + capEnd[(upAxis + 2) % 3] = btCos(btScalar(i) * SIMD_RADS_PER_DEG) * radius; + drawLine(start + transform.getBasis() * (offsetHeight), start + transform.getBasis() * capEnd, color); } - drawLine(start+transform.getBasis() * (offsetHeight),start+transform.getBasis() * (-offsetHeight+offsetRadius),color); - drawLine(start+transform.getBasis() * (offsetHeight),start+transform.getBasis() * (-offsetHeight-offsetRadius),color); - drawLine(start+transform.getBasis() * (offsetHeight),start+transform.getBasis() * (-offsetHeight+offset2Radius),color); - drawLine(start+transform.getBasis() * (offsetHeight),start+transform.getBasis() * (-offsetHeight-offset2Radius),color); + drawLine(start + transform.getBasis() * (offsetHeight), start + transform.getBasis() * (-offsetHeight + offsetRadius), color); + drawLine(start + transform.getBasis() * (offsetHeight), start + transform.getBasis() * (-offsetHeight - offsetRadius), color); + drawLine(start + transform.getBasis() * (offsetHeight), start + transform.getBasis() * (-offsetHeight + offset2Radius), color); + drawLine(start + transform.getBasis() * (offsetHeight), start + transform.getBasis() * (-offsetHeight - offset2Radius), color); // Drawing the base of the cone - btVector3 yaxis(0,0,0); + btVector3 yaxis(0, 0, 0); yaxis[upAxis] = btScalar(1.0); - btVector3 xaxis(0,0,0); - xaxis[(upAxis+1)%3] = btScalar(1.0); - drawArc(start-transform.getBasis()*(offsetHeight),transform.getBasis()*yaxis,transform.getBasis()*xaxis,radius,radius,0,SIMD_2_PI,color,false,10.0); + btVector3 xaxis(0, 0, 0); + xaxis[(upAxis + 1) % 3] = btScalar(1.0); + drawArc(start - transform.getBasis() * (offsetHeight), transform.getBasis() * yaxis, transform.getBasis() * xaxis, radius, radius, 0, SIMD_2_PI, color, false, 10.0); } virtual void drawPlane(const btVector3& planeNormal, btScalar planeConst, const btTransform& transform, const btVector3& color) { btVector3 planeOrigin = planeNormal * planeConst; - btVector3 vec0,vec1; - btPlaneSpace1(planeNormal,vec0,vec1); + btVector3 vec0, vec1; + btPlaneSpace1(planeNormal, vec0, vec1); btScalar vecLen = 100.f; - btVector3 pt0 = planeOrigin + vec0*vecLen; - btVector3 pt1 = planeOrigin - vec0*vecLen; - btVector3 pt2 = planeOrigin + vec1*vecLen; - btVector3 pt3 = planeOrigin - vec1*vecLen; - drawLine(transform*pt0,transform*pt1,color); - drawLine(transform*pt2,transform*pt3,color); + btVector3 pt0 = planeOrigin + vec0 * vecLen; + btVector3 pt1 = planeOrigin - vec0 * vecLen; + btVector3 pt2 = planeOrigin + vec1 * vecLen; + btVector3 pt3 = planeOrigin - vec1 * vecLen; + drawLine(transform * pt0, transform * pt1, color); + drawLine(transform * pt2, transform * pt3, color); } virtual void clearLines() @@ -478,6 +470,4 @@ class btIDebugDraw } }; - -#endif //BT_IDEBUG_DRAW__H - +#endif //BT_IDEBUG_DRAW__H diff --git a/src/LinearMath/btList.h b/src/LinearMath/btList.h index eec80a706..b255938c3 100644 --- a/src/LinearMath/btList.h +++ b/src/LinearMath/btList.h @@ -12,62 +12,62 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #ifndef BT_GEN_LIST_H #define BT_GEN_LIST_H -class btGEN_Link { +class btGEN_Link +{ public: - btGEN_Link() : m_next(0), m_prev(0) {} - btGEN_Link(btGEN_Link *next, btGEN_Link *prev) : m_next(next), m_prev(prev) {} - - btGEN_Link *getNext() const { return m_next; } - btGEN_Link *getPrev() const { return m_prev; } + btGEN_Link() : m_next(0), m_prev(0) {} + btGEN_Link(btGEN_Link *next, btGEN_Link *prev) : m_next(next), m_prev(prev) {} - bool isHead() const { return m_prev == 0; } - bool isTail() const { return m_next == 0; } + btGEN_Link *getNext() const { return m_next; } + btGEN_Link *getPrev() const { return m_prev; } - void insertBefore(btGEN_Link *link) { - m_next = link; - m_prev = link->m_prev; - m_next->m_prev = this; - m_prev->m_next = this; - } + bool isHead() const { return m_prev == 0; } + bool isTail() const { return m_next == 0; } - void insertAfter(btGEN_Link *link) { - m_next = link->m_next; - m_prev = link; - m_next->m_prev = this; - m_prev->m_next = this; - } + void insertBefore(btGEN_Link *link) + { + m_next = link; + m_prev = link->m_prev; + m_next->m_prev = this; + m_prev->m_next = this; + } - void remove() { - m_next->m_prev = m_prev; - m_prev->m_next = m_next; - } + void insertAfter(btGEN_Link *link) + { + m_next = link->m_next; + m_prev = link; + m_next->m_prev = this; + m_prev->m_next = this; + } -private: - btGEN_Link *m_next; - btGEN_Link *m_prev; -}; + void remove() + { + m_next->m_prev = m_prev; + m_prev->m_next = m_next; + } -class btGEN_List { -public: - btGEN_List() : m_head(&m_tail, 0), m_tail(0, &m_head) {} - - btGEN_Link *getHead() const { return m_head.getNext(); } - btGEN_Link *getTail() const { return m_tail.getPrev(); } - - void addHead(btGEN_Link *link) { link->insertAfter(&m_head); } - void addTail(btGEN_Link *link) { link->insertBefore(&m_tail); } - private: - btGEN_Link m_head; - btGEN_Link m_tail; + btGEN_Link *m_next; + btGEN_Link *m_prev; }; -#endif //BT_GEN_LIST_H +class btGEN_List +{ +public: + btGEN_List() : m_head(&m_tail, 0), m_tail(0, &m_head) {} + btGEN_Link *getHead() const { return m_head.getNext(); } + btGEN_Link *getTail() const { return m_tail.getPrev(); } + void addHead(btGEN_Link *link) { link->insertAfter(&m_head); } + void addTail(btGEN_Link *link) { link->insertBefore(&m_tail); } +private: + btGEN_Link m_head; + btGEN_Link m_tail; +}; + +#endif //BT_GEN_LIST_H diff --git a/src/LinearMath/btMatrix3x3.h b/src/LinearMath/btMatrix3x3.h index 6cc4993da..0a08ae409 100644 --- a/src/LinearMath/btMatrix3x3.h +++ b/src/LinearMath/btMatrix3x3.h @@ -12,8 +12,7 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - -#ifndef BT_MATRIX3x3_H +#ifndef BT_MATRIX3x3_H #define BT_MATRIX3x3_H #include "btVector3.h" @@ -23,13 +22,13 @@ subject to the following restrictions: #ifdef BT_USE_SSE //const __m128 ATTRIBUTE_ALIGNED16(v2220) = {2.0f, 2.0f, 2.0f, 0.0f}; //const __m128 ATTRIBUTE_ALIGNED16(vMPPP) = {-0.0f, +0.0f, +0.0f, +0.0f}; -#define vMPPP (_mm_set_ps (+0.0f, +0.0f, +0.0f, -0.0f)) +#define vMPPP (_mm_set_ps(+0.0f, +0.0f, +0.0f, -0.0f)) #endif #if defined(BT_USE_SSE) -#define v1000 (_mm_set_ps(0.0f,0.0f,0.0f,1.0f)) -#define v0100 (_mm_set_ps(0.0f,0.0f,1.0f,0.0f)) -#define v0010 (_mm_set_ps(0.0f,1.0f,0.0f,0.0f)) +#define v1000 (_mm_set_ps(0.0f, 0.0f, 0.0f, 1.0f)) +#define v0100 (_mm_set_ps(0.0f, 0.0f, 1.0f, 0.0f)) +#define v0010 (_mm_set_ps(0.0f, 1.0f, 0.0f, 0.0f)) #elif defined(BT_USE_NEON) const btSimdFloat4 ATTRIBUTE_ALIGNED16(v1000) = {1.0f, 0.0f, 0.0f, 0.0f}; const btSimdFloat4 ATTRIBUTE_ALIGNED16(v0100) = {0.0f, 1.0f, 0.0f, 0.0f}; @@ -37,22 +36,22 @@ const btSimdFloat4 ATTRIBUTE_ALIGNED16(v0010) = {0.0f, 0.0f, 1.0f, 0.0f}; #endif #ifdef BT_USE_DOUBLE_PRECISION -#define btMatrix3x3Data btMatrix3x3DoubleData +#define btMatrix3x3Data btMatrix3x3DoubleData #else -#define btMatrix3x3Data btMatrix3x3FloatData -#endif //BT_USE_DOUBLE_PRECISION - +#define btMatrix3x3Data btMatrix3x3FloatData +#endif //BT_USE_DOUBLE_PRECISION /**@brief The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with btQuaternion, btTransform and btVector3. * Make sure to only include a pure orthogonal matrix without scaling. */ -ATTRIBUTE_ALIGNED16(class) btMatrix3x3 { - +ATTRIBUTE_ALIGNED16(class) +btMatrix3x3 +{ ///Data storage for the matrix, each vector is a row of the matrix btVector3 m_el[3]; public: /** @brief No initializaion constructor */ - btMatrix3x3 () {} + btMatrix3x3() {} // explicit btMatrix3x3(const btScalar *m) { setFromOpenGLSubMatrix(m); } @@ -67,27 +66,27 @@ public: */ /** @brief Constructor with row major formatting */ btMatrix3x3(const btScalar& xx, const btScalar& xy, const btScalar& xz, - const btScalar& yx, const btScalar& yy, const btScalar& yz, - const btScalar& zx, const btScalar& zy, const btScalar& zz) - { - setValue(xx, xy, xz, - yx, yy, yz, - zx, zy, zz); + const btScalar& yx, const btScalar& yy, const btScalar& yz, + const btScalar& zx, const btScalar& zy, const btScalar& zz) + { + setValue(xx, xy, xz, + yx, yy, yz, + zx, zy, zz); } -#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON) - SIMD_FORCE_INLINE btMatrix3x3 (const btSimdFloat4 v0, const btSimdFloat4 v1, const btSimdFloat4 v2 ) +#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) || defined(BT_USE_NEON) + SIMD_FORCE_INLINE btMatrix3x3(const btSimdFloat4 v0, const btSimdFloat4 v1, const btSimdFloat4 v2) { - m_el[0].mVec128 = v0; - m_el[1].mVec128 = v1; - m_el[2].mVec128 = v2; + m_el[0].mVec128 = v0; + m_el[1].mVec128 = v1; + m_el[2].mVec128 = v2; } - SIMD_FORCE_INLINE btMatrix3x3 (const btVector3& v0, const btVector3& v1, const btVector3& v2 ) + SIMD_FORCE_INLINE btMatrix3x3(const btVector3& v0, const btVector3& v1, const btVector3& v2) { - m_el[0] = v0; - m_el[1] = v1; - m_el[2] = v2; + m_el[0] = v0; + m_el[1] = v1; + m_el[2] = v2; } // Copy constructor @@ -99,25 +98,25 @@ public: } // Assignment Operator - SIMD_FORCE_INLINE btMatrix3x3& operator=(const btMatrix3x3& m) + SIMD_FORCE_INLINE btMatrix3x3& operator=(const btMatrix3x3& m) { m_el[0].mVec128 = m.m_el[0].mVec128; m_el[1].mVec128 = m.m_el[1].mVec128; m_el[2].mVec128 = m.m_el[2].mVec128; - + return *this; } #else /** @brief Copy constructor */ - SIMD_FORCE_INLINE btMatrix3x3 (const btMatrix3x3& other) + SIMD_FORCE_INLINE btMatrix3x3(const btMatrix3x3& other) { m_el[0] = other.m_el[0]; m_el[1] = other.m_el[1]; m_el[2] = other.m_el[2]; } - + /** @brief Assignment Operator */ SIMD_FORCE_INLINE btMatrix3x3& operator=(const btMatrix3x3& other) { @@ -133,10 +132,9 @@ public: * @param i Column number 0 indexed */ SIMD_FORCE_INLINE btVector3 getColumn(int i) const { - return btVector3(m_el[0][i],m_el[1][i],m_el[2][i]); + return btVector3(m_el[0][i], m_el[1][i], m_el[2][i]); } - /** @brief Get a row of the matrix as a vector * @param i Row number 0 indexed */ SIMD_FORCE_INLINE const btVector3& getRow(int i) const @@ -147,10 +145,10 @@ public: /** @brief Get a mutable reference to a row of the matrix as a vector * @param i Row number 0 indexed */ - SIMD_FORCE_INLINE btVector3& operator[](int i) - { + SIMD_FORCE_INLINE btVector3& operator[](int i) + { btFullAssert(0 <= i && i < 3); - return m_el[i]; + return m_el[i]; } /** @brief Get a const reference to a row of the matrix as a vector @@ -158,32 +156,31 @@ public: SIMD_FORCE_INLINE const btVector3& operator[](int i) const { btFullAssert(0 <= i && i < 3); - return m_el[i]; + return m_el[i]; } /** @brief Multiply by the target matrix on the right * @param m Rotation matrix to be applied * Equivilant to this = this * m */ - btMatrix3x3& operator*=(const btMatrix3x3& m); + btMatrix3x3& operator*=(const btMatrix3x3& m); /** @brief Adds by the target matrix on the right * @param m matrix to be applied * Equivilant to this = this + m */ - btMatrix3x3& operator+=(const btMatrix3x3& m); + btMatrix3x3& operator+=(const btMatrix3x3& m); /** @brief Substractss by the target matrix on the right * @param m matrix to be applied * Equivilant to this = this - m */ - btMatrix3x3& operator-=(const btMatrix3x3& m); + btMatrix3x3& operator-=(const btMatrix3x3& m); /** @brief Set from the rotational part of a 4x4 OpenGL matrix * @param m A pointer to the beginning of the array of scalars*/ - void setFromOpenGLSubMatrix(const btScalar *m) + void setFromOpenGLSubMatrix(const btScalar* m) { - m_el[0].setValue(m[0],m[4],m[8]); - m_el[1].setValue(m[1],m[5],m[9]); - m_el[2].setValue(m[2],m[6],m[10]); - + m_el[0].setValue(m[0], m[4], m[8]); + m_el[1].setValue(m[1], m[5], m[9]); + m_el[2].setValue(m[2], m[6], m[10]); } /** @brief Set the values of the matrix explicitly (row major) * @param xx Top left @@ -195,93 +192,92 @@ public: * @param zx Bottom Left * @param zy Bottom Middle * @param zz Bottom Right*/ - void setValue(const btScalar& xx, const btScalar& xy, const btScalar& xz, - const btScalar& yx, const btScalar& yy, const btScalar& yz, - const btScalar& zx, const btScalar& zy, const btScalar& zz) + void setValue(const btScalar& xx, const btScalar& xy, const btScalar& xz, + const btScalar& yx, const btScalar& yy, const btScalar& yz, + const btScalar& zx, const btScalar& zy, const btScalar& zz) { - m_el[0].setValue(xx,xy,xz); - m_el[1].setValue(yx,yy,yz); - m_el[2].setValue(zx,zy,zz); + m_el[0].setValue(xx, xy, xz); + m_el[1].setValue(yx, yy, yz); + m_el[2].setValue(zx, zy, zz); } /** @brief Set the matrix from a quaternion - * @param q The Quaternion to match */ - void setRotation(const btQuaternion& q) + * @param q The Quaternion to match */ + void setRotation(const btQuaternion& q) { btScalar d = q.length2(); btFullAssert(d != btScalar(0.0)); btScalar s = btScalar(2.0) / d; - - #if defined BT_USE_SIMD_VECTOR3 && defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) - __m128 vs, Q = q.get128(); + +#if defined BT_USE_SIMD_VECTOR3 && defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) + __m128 vs, Q = q.get128(); __m128i Qi = btCastfTo128i(Q); - __m128 Y, Z; - __m128 V1, V2, V3; - __m128 V11, V21, V31; - __m128 NQ = _mm_xor_ps(Q, btvMzeroMask); + __m128 Y, Z; + __m128 V1, V2, V3; + __m128 V11, V21, V31; + __m128 NQ = _mm_xor_ps(Q, btvMzeroMask); __m128i NQi = btCastfTo128i(NQ); - - V1 = btCastiTo128f(_mm_shuffle_epi32 (Qi, BT_SHUFFLE(1,0,2,3))); // Y X Z W - V2 = _mm_shuffle_ps(NQ, Q, BT_SHUFFLE(0,0,1,3)); // -X -X Y W - V3 = btCastiTo128f(_mm_shuffle_epi32 (Qi, BT_SHUFFLE(2,1,0,3))); // Z Y X W - V1 = _mm_xor_ps(V1, vMPPP); // change the sign of the first element - - V11 = btCastiTo128f(_mm_shuffle_epi32 (Qi, BT_SHUFFLE(1,1,0,3))); // Y Y X W - V21 = _mm_unpackhi_ps(Q, Q); // Z Z W W - V31 = _mm_shuffle_ps(Q, NQ, BT_SHUFFLE(0,2,0,3)); // X Z -X -W - V2 = V2 * V1; // - V1 = V1 * V11; // - V3 = V3 * V31; // + V1 = btCastiTo128f(_mm_shuffle_epi32(Qi, BT_SHUFFLE(1, 0, 2, 3))); // Y X Z W + V2 = _mm_shuffle_ps(NQ, Q, BT_SHUFFLE(0, 0, 1, 3)); // -X -X Y W + V3 = btCastiTo128f(_mm_shuffle_epi32(Qi, BT_SHUFFLE(2, 1, 0, 3))); // Z Y X W + V1 = _mm_xor_ps(V1, vMPPP); // change the sign of the first element - V11 = _mm_shuffle_ps(NQ, Q, BT_SHUFFLE(2,3,1,3)); // -Z -W Y W - V11 = V11 * V21; // - V21 = _mm_xor_ps(V21, vMPPP); // change the sign of the first element - V31 = _mm_shuffle_ps(Q, NQ, BT_SHUFFLE(3,3,1,3)); // W W -Y -W - V31 = _mm_xor_ps(V31, vMPPP); // change the sign of the first element - Y = btCastiTo128f(_mm_shuffle_epi32 (NQi, BT_SHUFFLE(3,2,0,3))); // -W -Z -X -W - Z = btCastiTo128f(_mm_shuffle_epi32 (Qi, BT_SHUFFLE(1,0,1,3))); // Y X Y W + V11 = btCastiTo128f(_mm_shuffle_epi32(Qi, BT_SHUFFLE(1, 1, 0, 3))); // Y Y X W + V21 = _mm_unpackhi_ps(Q, Q); // Z Z W W + V31 = _mm_shuffle_ps(Q, NQ, BT_SHUFFLE(0, 2, 0, 3)); // X Z -X -W + + V2 = V2 * V1; // + V1 = V1 * V11; // + V3 = V3 * V31; // + + V11 = _mm_shuffle_ps(NQ, Q, BT_SHUFFLE(2, 3, 1, 3)); // -Z -W Y W + V11 = V11 * V21; // + V21 = _mm_xor_ps(V21, vMPPP); // change the sign of the first element + V31 = _mm_shuffle_ps(Q, NQ, BT_SHUFFLE(3, 3, 1, 3)); // W W -Y -W + V31 = _mm_xor_ps(V31, vMPPP); // change the sign of the first element + Y = btCastiTo128f(_mm_shuffle_epi32(NQi, BT_SHUFFLE(3, 2, 0, 3))); // -W -Z -X -W + Z = btCastiTo128f(_mm_shuffle_epi32(Qi, BT_SHUFFLE(1, 0, 1, 3))); // Y X Y W vs = _mm_load_ss(&s); V21 = V21 * Y; V31 = V31 * Z; V1 = V1 + V11; - V2 = V2 + V21; - V3 = V3 + V31; + V2 = V2 + V21; + V3 = V3 + V31; - vs = bt_splat3_ps(vs, 0); - // s ready - V1 = V1 * vs; - V2 = V2 * vs; - V3 = V3 * vs; - - V1 = V1 + v1000; - V2 = V2 + v0100; - V3 = V3 + v0010; - - m_el[0] = V1; - m_el[1] = V2; - m_el[2] = V3; - #else - btScalar xs = q.x() * s, ys = q.y() * s, zs = q.z() * s; - btScalar wx = q.w() * xs, wy = q.w() * ys, wz = q.w() * zs; - btScalar xx = q.x() * xs, xy = q.x() * ys, xz = q.x() * zs; - btScalar yy = q.y() * ys, yz = q.y() * zs, zz = q.z() * zs; + vs = bt_splat3_ps(vs, 0); + // s ready + V1 = V1 * vs; + V2 = V2 * vs; + V3 = V3 * vs; + + V1 = V1 + v1000; + V2 = V2 + v0100; + V3 = V3 + v0010; + + m_el[0] = V1; + m_el[1] = V2; + m_el[2] = V3; +#else + btScalar xs = q.x() * s, ys = q.y() * s, zs = q.z() * s; + btScalar wx = q.w() * xs, wy = q.w() * ys, wz = q.w() * zs; + btScalar xx = q.x() * xs, xy = q.x() * ys, xz = q.x() * zs; + btScalar yy = q.y() * ys, yz = q.y() * zs, zz = q.z() * zs; setValue( - btScalar(1.0) - (yy + zz), xy - wz, xz + wy, + btScalar(1.0) - (yy + zz), xy - wz, xz + wy, xy + wz, btScalar(1.0) - (xx + zz), yz - wx, xz - wy, yz + wx, btScalar(1.0) - (xx + yy)); - #endif - } - +#endif + } /** @brief Set the matrix from euler angles using YPR around YXZ respectively * @param yaw Yaw about Y axis * @param pitch Pitch about X axis * @param roll Roll about Z axis */ - void setEulerYPR(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) + void setEulerYPR(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) { setEulerZYX(roll, pitch, yaw); } @@ -295,182 +291,197 @@ public: * angles are applied in ZYX order. I.e a vector is first rotated * about X then Y and then Z **/ - void setEulerZYX(btScalar eulerX,btScalar eulerY,btScalar eulerZ) { + void setEulerZYX(btScalar eulerX, btScalar eulerY, btScalar eulerZ) + { ///@todo proposed to reverse this since it's labeled zyx but takes arguments xyz and it will match all other parts of the code - btScalar ci ( btCos(eulerX)); - btScalar cj ( btCos(eulerY)); - btScalar ch ( btCos(eulerZ)); - btScalar si ( btSin(eulerX)); - btScalar sj ( btSin(eulerY)); - btScalar sh ( btSin(eulerZ)); - btScalar cc = ci * ch; - btScalar cs = ci * sh; - btScalar sc = si * ch; + btScalar ci(btCos(eulerX)); + btScalar cj(btCos(eulerY)); + btScalar ch(btCos(eulerZ)); + btScalar si(btSin(eulerX)); + btScalar sj(btSin(eulerY)); + btScalar sh(btSin(eulerZ)); + btScalar cc = ci * ch; + btScalar cs = ci * sh; + btScalar sc = si * ch; btScalar ss = si * sh; setValue(cj * ch, sj * sc - cs, sj * cc + ss, - cj * sh, sj * ss + cc, sj * cs - sc, - -sj, cj * si, cj * ci); + cj * sh, sj * ss + cc, sj * cs - sc, + -sj, cj * si, cj * ci); } /**@brief Set the matrix to the identity */ void setIdentity() - { -#if (defined(BT_USE_SSE_IN_API)&& defined (BT_USE_SSE)) || defined(BT_USE_NEON) - m_el[0] = v1000; - m_el[1] = v0100; - m_el[2] = v0010; + { +#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) || defined(BT_USE_NEON) + m_el[0] = v1000; + m_el[1] = v0100; + m_el[2] = v0010; #else - setValue(btScalar(1.0), btScalar(0.0), btScalar(0.0), - btScalar(0.0), btScalar(1.0), btScalar(0.0), - btScalar(0.0), btScalar(0.0), btScalar(1.0)); + setValue(btScalar(1.0), btScalar(0.0), btScalar(0.0), + btScalar(0.0), btScalar(1.0), btScalar(0.0), + btScalar(0.0), btScalar(0.0), btScalar(1.0)); #endif } - static const btMatrix3x3& getIdentity() + static const btMatrix3x3& getIdentity() { -#if (defined(BT_USE_SSE_IN_API)&& defined (BT_USE_SSE)) || defined(BT_USE_NEON) - static const btMatrix3x3 - identityMatrix(v1000, v0100, v0010); +#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) || defined(BT_USE_NEON) + static const btMatrix3x3 + identityMatrix(v1000, v0100, v0010); #else - static const btMatrix3x3 - identityMatrix( - btScalar(1.0), btScalar(0.0), btScalar(0.0), - btScalar(0.0), btScalar(1.0), btScalar(0.0), - btScalar(0.0), btScalar(0.0), btScalar(1.0)); + static const btMatrix3x3 + identityMatrix( + btScalar(1.0), btScalar(0.0), btScalar(0.0), + btScalar(0.0), btScalar(1.0), btScalar(0.0), + btScalar(0.0), btScalar(0.0), btScalar(1.0)); #endif return identityMatrix; } /**@brief Fill the rotational part of an OpenGL matrix and clear the shear/perspective * @param m The array to be filled */ - void getOpenGLSubMatrix(btScalar *m) const + void getOpenGLSubMatrix(btScalar * m) const { -#if defined BT_USE_SIMD_VECTOR3 && defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) - __m128 v0 = m_el[0].mVec128; - __m128 v1 = m_el[1].mVec128; - __m128 v2 = m_el[2].mVec128; // x2 y2 z2 w2 - __m128 *vm = (__m128 *)m; - __m128 vT; - - v2 = _mm_and_ps(v2, btvFFF0fMask); // x2 y2 z2 0 - - vT = _mm_unpackhi_ps(v0, v1); // z0 z1 * * - v0 = _mm_unpacklo_ps(v0, v1); // x0 x1 y0 y1 +#if defined BT_USE_SIMD_VECTOR3 && defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) + __m128 v0 = m_el[0].mVec128; + __m128 v1 = m_el[1].mVec128; + __m128 v2 = m_el[2].mVec128; // x2 y2 z2 w2 + __m128* vm = (__m128*)m; + __m128 vT; - v1 = _mm_shuffle_ps(v0, v2, BT_SHUFFLE(2, 3, 1, 3) ); // y0 y1 y2 0 - v0 = _mm_shuffle_ps(v0, v2, BT_SHUFFLE(0, 1, 0, 3) ); // x0 x1 x2 0 - v2 = btCastdTo128f(_mm_move_sd(btCastfTo128d(v2), btCastfTo128d(vT))); // z0 z1 z2 0 + v2 = _mm_and_ps(v2, btvFFF0fMask); // x2 y2 z2 0 - vm[0] = v0; - vm[1] = v1; - vm[2] = v2; + vT = _mm_unpackhi_ps(v0, v1); // z0 z1 * * + v0 = _mm_unpacklo_ps(v0, v1); // x0 x1 y0 y1 + + v1 = _mm_shuffle_ps(v0, v2, BT_SHUFFLE(2, 3, 1, 3)); // y0 y1 y2 0 + v0 = _mm_shuffle_ps(v0, v2, BT_SHUFFLE(0, 1, 0, 3)); // x0 x1 x2 0 + v2 = btCastdTo128f(_mm_move_sd(btCastfTo128d(v2), btCastfTo128d(vT))); // z0 z1 z2 0 + + vm[0] = v0; + vm[1] = v1; + vm[2] = v2; #elif defined(BT_USE_NEON) - // note: zeros the w channel. We can preserve it at the cost of two more vtrn instructions. - static const uint32x2_t zMask = (const uint32x2_t) {static_cast(-1), 0 }; - float32x4_t *vm = (float32x4_t *)m; - float32x4x2_t top = vtrnq_f32( m_el[0].mVec128, m_el[1].mVec128 ); // {x0 x1 z0 z1}, {y0 y1 w0 w1} - float32x2x2_t bl = vtrn_f32( vget_low_f32(m_el[2].mVec128), vdup_n_f32(0.0f) ); // {x2 0 }, {y2 0} - float32x4_t v0 = vcombine_f32( vget_low_f32(top.val[0]), bl.val[0] ); - float32x4_t v1 = vcombine_f32( vget_low_f32(top.val[1]), bl.val[1] ); - float32x2_t q = (float32x2_t) vand_u32( (uint32x2_t) vget_high_f32( m_el[2].mVec128), zMask ); - float32x4_t v2 = vcombine_f32( vget_high_f32(top.val[0]), q ); // z0 z1 z2 0 + // note: zeros the w channel. We can preserve it at the cost of two more vtrn instructions. + static const uint32x2_t zMask = (const uint32x2_t){static_cast(-1), 0}; + float32x4_t* vm = (float32x4_t*)m; + float32x4x2_t top = vtrnq_f32(m_el[0].mVec128, m_el[1].mVec128); // {x0 x1 z0 z1}, {y0 y1 w0 w1} + float32x2x2_t bl = vtrn_f32(vget_low_f32(m_el[2].mVec128), vdup_n_f32(0.0f)); // {x2 0 }, {y2 0} + float32x4_t v0 = vcombine_f32(vget_low_f32(top.val[0]), bl.val[0]); + float32x4_t v1 = vcombine_f32(vget_low_f32(top.val[1]), bl.val[1]); + float32x2_t q = (float32x2_t)vand_u32((uint32x2_t)vget_high_f32(m_el[2].mVec128), zMask); + float32x4_t v2 = vcombine_f32(vget_high_f32(top.val[0]), q); // z0 z1 z2 0 - vm[0] = v0; - vm[1] = v1; - vm[2] = v2; + vm[0] = v0; + vm[1] = v1; + vm[2] = v2; #else - m[0] = btScalar(m_el[0].x()); - m[1] = btScalar(m_el[1].x()); - m[2] = btScalar(m_el[2].x()); - m[3] = btScalar(0.0); - m[4] = btScalar(m_el[0].y()); - m[5] = btScalar(m_el[1].y()); - m[6] = btScalar(m_el[2].y()); - m[7] = btScalar(0.0); - m[8] = btScalar(m_el[0].z()); - m[9] = btScalar(m_el[1].z()); + m[0] = btScalar(m_el[0].x()); + m[1] = btScalar(m_el[1].x()); + m[2] = btScalar(m_el[2].x()); + m[3] = btScalar(0.0); + m[4] = btScalar(m_el[0].y()); + m[5] = btScalar(m_el[1].y()); + m[6] = btScalar(m_el[2].y()); + m[7] = btScalar(0.0); + m[8] = btScalar(m_el[0].z()); + m[9] = btScalar(m_el[1].z()); m[10] = btScalar(m_el[2].z()); - m[11] = btScalar(0.0); + m[11] = btScalar(0.0); #endif } /**@brief Get the matrix represented as a quaternion * @param q The quaternion which will be set */ - void getRotation(btQuaternion& q) const + void getRotation(btQuaternion & q) const { -#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON) - btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z(); - btScalar s, x; - - union { - btSimdFloat4 vec; - btScalar f[4]; - } temp; - - if (trace > btScalar(0.0)) - { - x = trace + btScalar(1.0); +#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) || defined(BT_USE_NEON) + btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z(); + btScalar s, x; - temp.f[0]=m_el[2].y() - m_el[1].z(); - temp.f[1]=m_el[0].z() - m_el[2].x(); - temp.f[2]=m_el[1].x() - m_el[0].y(); - temp.f[3]=x; - //temp.f[3]= s * btScalar(0.5); - } - else - { - int i, j, k; - if(m_el[0].x() < m_el[1].y()) - { - if( m_el[1].y() < m_el[2].z() ) - { i = 2; j = 0; k = 1; } - else - { i = 1; j = 2; k = 0; } - } - else - { - if( m_el[0].x() < m_el[2].z()) - { i = 2; j = 0; k = 1; } - else - { i = 0; j = 1; k = 2; } - } + union { + btSimdFloat4 vec; + btScalar f[4]; + } temp; - x = m_el[i][i] - m_el[j][j] - m_el[k][k] + btScalar(1.0); + if (trace > btScalar(0.0)) + { + x = trace + btScalar(1.0); - temp.f[3] = (m_el[k][j] - m_el[j][k]); - temp.f[j] = (m_el[j][i] + m_el[i][j]); - temp.f[k] = (m_el[k][i] + m_el[i][k]); - temp.f[i] = x; - //temp.f[i] = s * btScalar(0.5); - } + temp.f[0] = m_el[2].y() - m_el[1].z(); + temp.f[1] = m_el[0].z() - m_el[2].x(); + temp.f[2] = m_el[1].x() - m_el[0].y(); + temp.f[3] = x; + //temp.f[3]= s * btScalar(0.5); + } + else + { + int i, j, k; + if (m_el[0].x() < m_el[1].y()) + { + if (m_el[1].y() < m_el[2].z()) + { + i = 2; + j = 0; + k = 1; + } + else + { + i = 1; + j = 2; + k = 0; + } + } + else + { + if (m_el[0].x() < m_el[2].z()) + { + i = 2; + j = 0; + k = 1; + } + else + { + i = 0; + j = 1; + k = 2; + } + } - s = btSqrt(x); - q.set128(temp.vec); - s = btScalar(0.5) / s; + x = m_el[i][i] - m_el[j][j] - m_el[k][k] + btScalar(1.0); - q *= s; -#else + temp.f[3] = (m_el[k][j] - m_el[j][k]); + temp.f[j] = (m_el[j][i] + m_el[i][j]); + temp.f[k] = (m_el[k][i] + m_el[i][k]); + temp.f[i] = x; + //temp.f[i] = s * btScalar(0.5); + } + + s = btSqrt(x); + q.set128(temp.vec); + s = btScalar(0.5) / s; + + q *= s; +#else btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z(); btScalar temp[4]; - if (trace > btScalar(0.0)) + if (trace > btScalar(0.0)) { btScalar s = btSqrt(trace + btScalar(1.0)); - temp[3]=(s * btScalar(0.5)); + temp[3] = (s * btScalar(0.5)); s = btScalar(0.5) / s; - temp[0]=((m_el[2].y() - m_el[1].z()) * s); - temp[1]=((m_el[0].z() - m_el[2].x()) * s); - temp[2]=((m_el[1].x() - m_el[0].y()) * s); - } - else + temp[0] = ((m_el[2].y() - m_el[1].z()) * s); + temp[1] = ((m_el[0].z() - m_el[2].x()) * s); + temp[2] = ((m_el[1].x() - m_el[0].y()) * s); + } + else { - int i = m_el[0].x() < m_el[1].y() ? - (m_el[1].y() < m_el[2].z() ? 2 : 1) : - (m_el[0].x() < m_el[2].z() ? 2 : 0); - int j = (i + 1) % 3; + int i = m_el[0].x() < m_el[1].y() ? (m_el[1].y() < m_el[2].z() ? 2 : 1) : (m_el[0].x() < m_el[2].z() ? 2 : 0); + int j = (i + 1) % 3; int k = (i + 2) % 3; btScalar s = btSqrt(m_el[i][i] - m_el[j][j] - m_el[k][k] + btScalar(1.0)); @@ -481,44 +492,42 @@ public: temp[j] = (m_el[j][i] + m_el[i][j]) * s; temp[k] = (m_el[k][i] + m_el[i][k]) * s; } - q.setValue(temp[0],temp[1],temp[2],temp[3]); + q.setValue(temp[0], temp[1], temp[2], temp[3]); #endif } /**@brief Get the matrix represented as euler angles around YXZ, roundtrip with setEulerYPR * @param yaw Yaw around Y axis * @param pitch Pitch around X axis - * @param roll around Z axis */ - void getEulerYPR(btScalar& yaw, btScalar& pitch, btScalar& roll) const + * @param roll around Z axis */ + void getEulerYPR(btScalar & yaw, btScalar & pitch, btScalar & roll) const { - // first use the normal calculus yaw = btScalar(btAtan2(m_el[1].x(), m_el[0].x())); pitch = btScalar(btAsin(-m_el[2].x())); roll = btScalar(btAtan2(m_el[2].y(), m_el[2].z())); // on pitch = +/-HalfPI - if (btFabs(pitch)==SIMD_HALF_PI) + if (btFabs(pitch) == SIMD_HALF_PI) { - if (yaw>0) - yaw-=SIMD_PI; + if (yaw > 0) + yaw -= SIMD_PI; else - yaw+=SIMD_PI; + yaw += SIMD_PI; - if (roll>0) - roll-=SIMD_PI; + if (roll > 0) + roll -= SIMD_PI; else - roll+=SIMD_PI; + roll += SIMD_PI; } }; - /**@brief Get the matrix represented as euler angles around ZYX * @param yaw Yaw around Z axis * @param pitch Pitch around Y axis * @param roll around X axis - * @param solution_number Which solution of two possible solutions ( 1 or 2) are possible values*/ - void getEulerZYX(btScalar& yaw, btScalar& pitch, btScalar& roll, unsigned int solution_number = 1) const + * @param solution_number Which solution of two possible solutions ( 1 or 2) are possible values*/ + void getEulerZYX(btScalar & yaw, btScalar & pitch, btScalar & roll, unsigned int solution_number = 1) const { struct Euler { @@ -528,7 +537,7 @@ public: }; Euler euler_out; - Euler euler_out2; //second solution + Euler euler_out2; //second solution //get the pointer to the raw data // Check that pitch is not at a singularity @@ -538,7 +547,7 @@ public: euler_out2.yaw = 0; // From difference of angles formula - btScalar delta = btAtan2(m_el[0].x(),m_el[0].z()); + btScalar delta = btAtan2(m_el[0].x(), m_el[0].z()); if (m_el[2].x() > 0) //gimbal locked up { euler_out.pitch = SIMD_PI / btScalar(2.0); @@ -546,7 +555,7 @@ public: euler_out.roll = euler_out.pitch + delta; euler_out2.roll = euler_out.pitch + delta; } - else // gimbal locked down + else // gimbal locked down { euler_out.pitch = -SIMD_PI / btScalar(2.0); euler_out2.pitch = -SIMD_PI / btScalar(2.0); @@ -556,29 +565,29 @@ public: } else { - euler_out.pitch = - btAsin(m_el[2].x()); + euler_out.pitch = -btAsin(m_el[2].x()); euler_out2.pitch = SIMD_PI - euler_out.pitch; - euler_out.roll = btAtan2(m_el[2].y()/btCos(euler_out.pitch), - m_el[2].z()/btCos(euler_out.pitch)); - euler_out2.roll = btAtan2(m_el[2].y()/btCos(euler_out2.pitch), - m_el[2].z()/btCos(euler_out2.pitch)); + euler_out.roll = btAtan2(m_el[2].y() / btCos(euler_out.pitch), + m_el[2].z() / btCos(euler_out.pitch)); + euler_out2.roll = btAtan2(m_el[2].y() / btCos(euler_out2.pitch), + m_el[2].z() / btCos(euler_out2.pitch)); - euler_out.yaw = btAtan2(m_el[1].x()/btCos(euler_out.pitch), - m_el[0].x()/btCos(euler_out.pitch)); - euler_out2.yaw = btAtan2(m_el[1].x()/btCos(euler_out2.pitch), - m_el[0].x()/btCos(euler_out2.pitch)); + euler_out.yaw = btAtan2(m_el[1].x() / btCos(euler_out.pitch), + m_el[0].x() / btCos(euler_out.pitch)); + euler_out2.yaw = btAtan2(m_el[1].x() / btCos(euler_out2.pitch), + m_el[0].x() / btCos(euler_out2.pitch)); } if (solution_number == 1) - { - yaw = euler_out.yaw; + { + yaw = euler_out.yaw; pitch = euler_out.pitch; roll = euler_out.roll; } else - { - yaw = euler_out2.yaw; + { + yaw = euler_out2.yaw; pitch = euler_out2.pitch; roll = euler_out2.roll; } @@ -589,18 +598,18 @@ public: btMatrix3x3 scaled(const btVector3& s) const { -#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON) +#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) || defined(BT_USE_NEON) return btMatrix3x3(m_el[0] * s, m_el[1] * s, m_el[2] * s); -#else +#else return btMatrix3x3( - m_el[0].x() * s.x(), m_el[0].y() * s.y(), m_el[0].z() * s.z(), + m_el[0].x() * s.x(), m_el[0].y() * s.y(), m_el[0].z() * s.z(), m_el[1].x() * s.x(), m_el[1].y() * s.y(), m_el[1].z() * s.z(), m_el[2].x() * s.x(), m_el[2].y() * s.y(), m_el[2].z() * s.z()); #endif } /**@brief Return the determinant of the matrix */ - btScalar determinant() const; + btScalar determinant() const; /**@brief Return the adjoint of the matrix */ btMatrix3x3 adjoint() const; /**@brief Return the matrix with all values non negative */ @@ -608,7 +617,7 @@ public: /**@brief Return the transpose of the matrix */ btMatrix3x3 transpose() const; /**@brief Return the inverse of the matrix */ - btMatrix3x3 inverse() const; + btMatrix3x3 inverse() const; /// Solve A * x = b, where b is a column vector. This is more efficient /// than computing the inverse in one-shot cases. @@ -618,9 +627,9 @@ public: btVector3 col1 = getColumn(0); btVector3 col2 = getColumn(1); btVector3 col3 = getColumn(2); - + btScalar det = btDot(col1, btCross(col2, col3)); - if (btFabs(det)>SIMD_EPSILON) + if (btFabs(det) > SIMD_EPSILON) { det = 1.0f / det; } @@ -634,15 +643,15 @@ public: btMatrix3x3 transposeTimes(const btMatrix3x3& m) const; btMatrix3x3 timesTranspose(const btMatrix3x3& m) const; - SIMD_FORCE_INLINE btScalar tdotx(const btVector3& v) const + SIMD_FORCE_INLINE btScalar tdotx(const btVector3& v) const { return m_el[0].x() * v.x() + m_el[1].x() * v.y() + m_el[2].x() * v.z(); } - SIMD_FORCE_INLINE btScalar tdoty(const btVector3& v) const + SIMD_FORCE_INLINE btScalar tdoty(const btVector3& v) const { return m_el[0].y() * v.x() + m_el[1].y() * v.y() + m_el[2].y() * v.z(); } - SIMD_FORCE_INLINE btScalar tdotz(const btVector3& v) const + SIMD_FORCE_INLINE btScalar tdotz(const btVector3& v) const { return m_el[0].z() * v.x() + m_el[1].z() * v.y() + m_el[2].z() * v.z(); } @@ -653,31 +662,25 @@ public: ///symmetric matrix S: ///A = R*S. ///note that R can include both rotation and scaling. - SIMD_FORCE_INLINE void extractRotation(btQuaternion &q,btScalar tolerance = 1.0e-9, int maxIter=100) + SIMD_FORCE_INLINE void extractRotation(btQuaternion & q, btScalar tolerance = 1.0e-9, int maxIter = 100) { - int iter =0; + int iter = 0; btScalar w; - const btMatrix3x3& A=*this; - for(iter = 0; iter < maxIter; iter++) + const btMatrix3x3& A = *this; + for (iter = 0; iter < maxIter; iter++) { btMatrix3x3 R(q); - btVector3 omega = (R.getColumn(0).cross(A.getColumn(0)) + R.getColumn(1).cross(A.getColumn(1)) - + R.getColumn(2).cross(A.getColumn(2)) - ) * (btScalar(1.0) / btFabs(R.getColumn(0).dot(A.getColumn(0)) + R.getColumn - (1).dot(A.getColumn(1)) + R.getColumn(2).dot(A.getColumn(2))) + - tolerance); + btVector3 omega = (R.getColumn(0).cross(A.getColumn(0)) + R.getColumn(1).cross(A.getColumn(1)) + R.getColumn(2).cross(A.getColumn(2))) * (btScalar(1.0) / btFabs(R.getColumn(0).dot(A.getColumn(0)) + R.getColumn(1).dot(A.getColumn(1)) + R.getColumn(2).dot(A.getColumn(2))) + + tolerance); w = omega.norm(); - if(w < tolerance) + if (w < tolerance) break; - q = btQuaternion(btVector3((btScalar(1.0) / w) * omega),w) * + q = btQuaternion(btVector3((btScalar(1.0) / w) * omega), w) * q; q.normalize(); } } - - - /**@brief diagonalizes this matrix by the Jacobi method. * @param rot stores the rotation from the coordinate system in which the matrix is diagonal to the original * coordinate system, i.e., old_this = rot * new_this * rot^T. @@ -687,7 +690,7 @@ public: * * Note that this matrix is assumed to be symmetric. */ - void diagonalize(btMatrix3x3& rot, btScalar threshold, int maxSteps) + void diagonalize(btMatrix3x3 & rot, btScalar threshold, int maxSteps) { rot.setIdentity(); for (int step = maxSteps; step > 0; step--) @@ -723,7 +726,7 @@ public: step = 1; } - // compute Jacobi rotation J which leads to a zero for element [p][q] + // compute Jacobi rotation J which leads to a zero for element [p][q] btScalar mpq = m_el[p][q]; btScalar theta = (m_el[q][q] - m_el[p][p]) / (2 * mpq); btScalar theta2 = theta * theta; @@ -732,7 +735,7 @@ public: if (theta2 * theta2 < btScalar(10 / SIMD_EPSILON)) { t = (theta >= 0) ? 1 / (theta + btSqrt(1 + theta2)) - : 1 / (theta - btSqrt(1 + theta2)); + : 1 / (theta - btSqrt(1 + theta2)); cos = 1 / btSqrt(1 + t * t); sin = cos * t; } @@ -765,8 +768,6 @@ public: } } - - /**@brief Calculate the matrix cofactor * @param r1 The first row to use for calculating the cofactor * @param c1 The first column to use for calculating the cofactor @@ -774,304 +775,298 @@ public: * @param c1 The second column to use for calculating the cofactor * See http://en.wikipedia.org/wiki/Cofactor_(linear_algebra) for more details */ - btScalar cofac(int r1, int c1, int r2, int c2) const + btScalar cofac(int r1, int c1, int r2, int c2) const { return m_el[r1][c1] * m_el[r2][c2] - m_el[r1][c2] * m_el[r2][c1]; } - void serialize(struct btMatrix3x3Data& dataOut) const; + void serialize(struct btMatrix3x3Data & dataOut) const; - void serializeFloat(struct btMatrix3x3FloatData& dataOut) const; + void serializeFloat(struct btMatrix3x3FloatData & dataOut) const; - void deSerialize(const struct btMatrix3x3Data& dataIn); + void deSerialize(const struct btMatrix3x3Data& dataIn); - void deSerializeFloat(const struct btMatrix3x3FloatData& dataIn); - - void deSerializeDouble(const struct btMatrix3x3DoubleData& dataIn); + void deSerializeFloat(const struct btMatrix3x3FloatData& dataIn); + void deSerializeDouble(const struct btMatrix3x3DoubleData& dataIn); }; - -SIMD_FORCE_INLINE btMatrix3x3& +SIMD_FORCE_INLINE btMatrix3x3& btMatrix3x3::operator*=(const btMatrix3x3& m) { -#if defined BT_USE_SIMD_VECTOR3 && defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) - __m128 rv00, rv01, rv02; - __m128 rv10, rv11, rv12; - __m128 rv20, rv21, rv22; - __m128 mv0, mv1, mv2; +#if defined BT_USE_SIMD_VECTOR3 && defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) + __m128 rv00, rv01, rv02; + __m128 rv10, rv11, rv12; + __m128 rv20, rv21, rv22; + __m128 mv0, mv1, mv2; - rv02 = m_el[0].mVec128; - rv12 = m_el[1].mVec128; - rv22 = m_el[2].mVec128; + rv02 = m_el[0].mVec128; + rv12 = m_el[1].mVec128; + rv22 = m_el[2].mVec128; - mv0 = _mm_and_ps(m[0].mVec128, btvFFF0fMask); - mv1 = _mm_and_ps(m[1].mVec128, btvFFF0fMask); - mv2 = _mm_and_ps(m[2].mVec128, btvFFF0fMask); - - // rv0 - rv00 = bt_splat_ps(rv02, 0); - rv01 = bt_splat_ps(rv02, 1); - rv02 = bt_splat_ps(rv02, 2); - - rv00 = _mm_mul_ps(rv00, mv0); - rv01 = _mm_mul_ps(rv01, mv1); - rv02 = _mm_mul_ps(rv02, mv2); - - // rv1 - rv10 = bt_splat_ps(rv12, 0); - rv11 = bt_splat_ps(rv12, 1); - rv12 = bt_splat_ps(rv12, 2); - - rv10 = _mm_mul_ps(rv10, mv0); - rv11 = _mm_mul_ps(rv11, mv1); - rv12 = _mm_mul_ps(rv12, mv2); - - // rv2 - rv20 = bt_splat_ps(rv22, 0); - rv21 = bt_splat_ps(rv22, 1); - rv22 = bt_splat_ps(rv22, 2); - - rv20 = _mm_mul_ps(rv20, mv0); - rv21 = _mm_mul_ps(rv21, mv1); - rv22 = _mm_mul_ps(rv22, mv2); + mv0 = _mm_and_ps(m[0].mVec128, btvFFF0fMask); + mv1 = _mm_and_ps(m[1].mVec128, btvFFF0fMask); + mv2 = _mm_and_ps(m[2].mVec128, btvFFF0fMask); - rv00 = _mm_add_ps(rv00, rv01); - rv10 = _mm_add_ps(rv10, rv11); - rv20 = _mm_add_ps(rv20, rv21); + // rv0 + rv00 = bt_splat_ps(rv02, 0); + rv01 = bt_splat_ps(rv02, 1); + rv02 = bt_splat_ps(rv02, 2); - m_el[0].mVec128 = _mm_add_ps(rv00, rv02); - m_el[1].mVec128 = _mm_add_ps(rv10, rv12); - m_el[2].mVec128 = _mm_add_ps(rv20, rv22); + rv00 = _mm_mul_ps(rv00, mv0); + rv01 = _mm_mul_ps(rv01, mv1); + rv02 = _mm_mul_ps(rv02, mv2); + + // rv1 + rv10 = bt_splat_ps(rv12, 0); + rv11 = bt_splat_ps(rv12, 1); + rv12 = bt_splat_ps(rv12, 2); + + rv10 = _mm_mul_ps(rv10, mv0); + rv11 = _mm_mul_ps(rv11, mv1); + rv12 = _mm_mul_ps(rv12, mv2); + + // rv2 + rv20 = bt_splat_ps(rv22, 0); + rv21 = bt_splat_ps(rv22, 1); + rv22 = bt_splat_ps(rv22, 2); + + rv20 = _mm_mul_ps(rv20, mv0); + rv21 = _mm_mul_ps(rv21, mv1); + rv22 = _mm_mul_ps(rv22, mv2); + + rv00 = _mm_add_ps(rv00, rv01); + rv10 = _mm_add_ps(rv10, rv11); + rv20 = _mm_add_ps(rv20, rv21); + + m_el[0].mVec128 = _mm_add_ps(rv00, rv02); + m_el[1].mVec128 = _mm_add_ps(rv10, rv12); + m_el[2].mVec128 = _mm_add_ps(rv20, rv22); #elif defined(BT_USE_NEON) - float32x4_t rv0, rv1, rv2; - float32x4_t v0, v1, v2; - float32x4_t mv0, mv1, mv2; + float32x4_t rv0, rv1, rv2; + float32x4_t v0, v1, v2; + float32x4_t mv0, mv1, mv2; - v0 = m_el[0].mVec128; - v1 = m_el[1].mVec128; - v2 = m_el[2].mVec128; + v0 = m_el[0].mVec128; + v1 = m_el[1].mVec128; + v2 = m_el[2].mVec128; - mv0 = (float32x4_t) vandq_s32((int32x4_t)m[0].mVec128, btvFFF0Mask); - mv1 = (float32x4_t) vandq_s32((int32x4_t)m[1].mVec128, btvFFF0Mask); - mv2 = (float32x4_t) vandq_s32((int32x4_t)m[2].mVec128, btvFFF0Mask); - - rv0 = vmulq_lane_f32(mv0, vget_low_f32(v0), 0); - rv1 = vmulq_lane_f32(mv0, vget_low_f32(v1), 0); - rv2 = vmulq_lane_f32(mv0, vget_low_f32(v2), 0); - - rv0 = vmlaq_lane_f32(rv0, mv1, vget_low_f32(v0), 1); - rv1 = vmlaq_lane_f32(rv1, mv1, vget_low_f32(v1), 1); - rv2 = vmlaq_lane_f32(rv2, mv1, vget_low_f32(v2), 1); - - rv0 = vmlaq_lane_f32(rv0, mv2, vget_high_f32(v0), 0); - rv1 = vmlaq_lane_f32(rv1, mv2, vget_high_f32(v1), 0); - rv2 = vmlaq_lane_f32(rv2, mv2, vget_high_f32(v2), 0); + mv0 = (float32x4_t)vandq_s32((int32x4_t)m[0].mVec128, btvFFF0Mask); + mv1 = (float32x4_t)vandq_s32((int32x4_t)m[1].mVec128, btvFFF0Mask); + mv2 = (float32x4_t)vandq_s32((int32x4_t)m[2].mVec128, btvFFF0Mask); - m_el[0].mVec128 = rv0; - m_el[1].mVec128 = rv1; - m_el[2].mVec128 = rv2; -#else + rv0 = vmulq_lane_f32(mv0, vget_low_f32(v0), 0); + rv1 = vmulq_lane_f32(mv0, vget_low_f32(v1), 0); + rv2 = vmulq_lane_f32(mv0, vget_low_f32(v2), 0); + + rv0 = vmlaq_lane_f32(rv0, mv1, vget_low_f32(v0), 1); + rv1 = vmlaq_lane_f32(rv1, mv1, vget_low_f32(v1), 1); + rv2 = vmlaq_lane_f32(rv2, mv1, vget_low_f32(v2), 1); + + rv0 = vmlaq_lane_f32(rv0, mv2, vget_high_f32(v0), 0); + rv1 = vmlaq_lane_f32(rv1, mv2, vget_high_f32(v1), 0); + rv2 = vmlaq_lane_f32(rv2, mv2, vget_high_f32(v2), 0); + + m_el[0].mVec128 = rv0; + m_el[1].mVec128 = rv1; + m_el[2].mVec128 = rv2; +#else setValue( - m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]), + m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]), m.tdotx(m_el[1]), m.tdoty(m_el[1]), m.tdotz(m_el[1]), m.tdotx(m_el[2]), m.tdoty(m_el[2]), m.tdotz(m_el[2])); #endif return *this; } -SIMD_FORCE_INLINE btMatrix3x3& +SIMD_FORCE_INLINE btMatrix3x3& btMatrix3x3::operator+=(const btMatrix3x3& m) { -#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON) - m_el[0].mVec128 = m_el[0].mVec128 + m.m_el[0].mVec128; - m_el[1].mVec128 = m_el[1].mVec128 + m.m_el[1].mVec128; - m_el[2].mVec128 = m_el[2].mVec128 + m.m_el[2].mVec128; +#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) || defined(BT_USE_NEON) + m_el[0].mVec128 = m_el[0].mVec128 + m.m_el[0].mVec128; + m_el[1].mVec128 = m_el[1].mVec128 + m.m_el[1].mVec128; + m_el[2].mVec128 = m_el[2].mVec128 + m.m_el[2].mVec128; #else setValue( - m_el[0][0]+m.m_el[0][0], - m_el[0][1]+m.m_el[0][1], - m_el[0][2]+m.m_el[0][2], - m_el[1][0]+m.m_el[1][0], - m_el[1][1]+m.m_el[1][1], - m_el[1][2]+m.m_el[1][2], - m_el[2][0]+m.m_el[2][0], - m_el[2][1]+m.m_el[2][1], - m_el[2][2]+m.m_el[2][2]); + m_el[0][0] + m.m_el[0][0], + m_el[0][1] + m.m_el[0][1], + m_el[0][2] + m.m_el[0][2], + m_el[1][0] + m.m_el[1][0], + m_el[1][1] + m.m_el[1][1], + m_el[1][2] + m.m_el[1][2], + m_el[2][0] + m.m_el[2][0], + m_el[2][1] + m.m_el[2][1], + m_el[2][2] + m.m_el[2][2]); #endif return *this; } SIMD_FORCE_INLINE btMatrix3x3 -operator*(const btMatrix3x3& m, const btScalar & k) +operator*(const btMatrix3x3& m, const btScalar& k) { -#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)) - __m128 vk = bt_splat_ps(_mm_load_ss((float *)&k), 0x80); - return btMatrix3x3( - _mm_mul_ps(m[0].mVec128, vk), - _mm_mul_ps(m[1].mVec128, vk), - _mm_mul_ps(m[2].mVec128, vk)); +#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) + __m128 vk = bt_splat_ps(_mm_load_ss((float*)&k), 0x80); + return btMatrix3x3( + _mm_mul_ps(m[0].mVec128, vk), + _mm_mul_ps(m[1].mVec128, vk), + _mm_mul_ps(m[2].mVec128, vk)); #elif defined(BT_USE_NEON) - return btMatrix3x3( - vmulq_n_f32(m[0].mVec128, k), - vmulq_n_f32(m[1].mVec128, k), - vmulq_n_f32(m[2].mVec128, k)); + return btMatrix3x3( + vmulq_n_f32(m[0].mVec128, k), + vmulq_n_f32(m[1].mVec128, k), + vmulq_n_f32(m[2].mVec128, k)); #else return btMatrix3x3( - m[0].x()*k,m[0].y()*k,m[0].z()*k, - m[1].x()*k,m[1].y()*k,m[1].z()*k, - m[2].x()*k,m[2].y()*k,m[2].z()*k); + m[0].x() * k, m[0].y() * k, m[0].z() * k, + m[1].x() * k, m[1].y() * k, m[1].z() * k, + m[2].x() * k, m[2].y() * k, m[2].z() * k); #endif } -SIMD_FORCE_INLINE btMatrix3x3 +SIMD_FORCE_INLINE btMatrix3x3 operator+(const btMatrix3x3& m1, const btMatrix3x3& m2) { -#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON) +#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) || defined(BT_USE_NEON) return btMatrix3x3( - m1[0].mVec128 + m2[0].mVec128, - m1[1].mVec128 + m2[1].mVec128, - m1[2].mVec128 + m2[2].mVec128); + m1[0].mVec128 + m2[0].mVec128, + m1[1].mVec128 + m2[1].mVec128, + m1[2].mVec128 + m2[2].mVec128); #else return btMatrix3x3( - m1[0][0]+m2[0][0], - m1[0][1]+m2[0][1], - m1[0][2]+m2[0][2], - - m1[1][0]+m2[1][0], - m1[1][1]+m2[1][1], - m1[1][2]+m2[1][2], - - m1[2][0]+m2[2][0], - m1[2][1]+m2[2][1], - m1[2][2]+m2[2][2]); -#endif -} + m1[0][0] + m2[0][0], + m1[0][1] + m2[0][1], + m1[0][2] + m2[0][2], -SIMD_FORCE_INLINE btMatrix3x3 -operator-(const btMatrix3x3& m1, const btMatrix3x3& m2) -{ -#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON) - return btMatrix3x3( - m1[0].mVec128 - m2[0].mVec128, - m1[1].mVec128 - m2[1].mVec128, - m1[2].mVec128 - m2[2].mVec128); -#else - return btMatrix3x3( - m1[0][0]-m2[0][0], - m1[0][1]-m2[0][1], - m1[0][2]-m2[0][2], - - m1[1][0]-m2[1][0], - m1[1][1]-m2[1][1], - m1[1][2]-m2[1][2], - - m1[2][0]-m2[2][0], - m1[2][1]-m2[2][1], - m1[2][2]-m2[2][2]); + m1[1][0] + m2[1][0], + m1[1][1] + m2[1][1], + m1[1][2] + m2[1][2], + + m1[2][0] + m2[2][0], + m1[2][1] + m2[2][1], + m1[2][2] + m2[2][2]); #endif } +SIMD_FORCE_INLINE btMatrix3x3 +operator-(const btMatrix3x3& m1, const btMatrix3x3& m2) +{ +#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) || defined(BT_USE_NEON) + return btMatrix3x3( + m1[0].mVec128 - m2[0].mVec128, + m1[1].mVec128 - m2[1].mVec128, + m1[2].mVec128 - m2[2].mVec128); +#else + return btMatrix3x3( + m1[0][0] - m2[0][0], + m1[0][1] - m2[0][1], + m1[0][2] - m2[0][2], -SIMD_FORCE_INLINE btMatrix3x3& + m1[1][0] - m2[1][0], + m1[1][1] - m2[1][1], + m1[1][2] - m2[1][2], + + m1[2][0] - m2[2][0], + m1[2][1] - m2[2][1], + m1[2][2] - m2[2][2]); +#endif +} + +SIMD_FORCE_INLINE btMatrix3x3& btMatrix3x3::operator-=(const btMatrix3x3& m) { -#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON) - m_el[0].mVec128 = m_el[0].mVec128 - m.m_el[0].mVec128; - m_el[1].mVec128 = m_el[1].mVec128 - m.m_el[1].mVec128; - m_el[2].mVec128 = m_el[2].mVec128 - m.m_el[2].mVec128; +#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) || defined(BT_USE_NEON) + m_el[0].mVec128 = m_el[0].mVec128 - m.m_el[0].mVec128; + m_el[1].mVec128 = m_el[1].mVec128 - m.m_el[1].mVec128; + m_el[2].mVec128 = m_el[2].mVec128 - m.m_el[2].mVec128; #else setValue( - m_el[0][0]-m.m_el[0][0], - m_el[0][1]-m.m_el[0][1], - m_el[0][2]-m.m_el[0][2], - m_el[1][0]-m.m_el[1][0], - m_el[1][1]-m.m_el[1][1], - m_el[1][2]-m.m_el[1][2], - m_el[2][0]-m.m_el[2][0], - m_el[2][1]-m.m_el[2][1], - m_el[2][2]-m.m_el[2][2]); + m_el[0][0] - m.m_el[0][0], + m_el[0][1] - m.m_el[0][1], + m_el[0][2] - m.m_el[0][2], + m_el[1][0] - m.m_el[1][0], + m_el[1][1] - m.m_el[1][1], + m_el[1][2] - m.m_el[1][2], + m_el[2][0] - m.m_el[2][0], + m_el[2][1] - m.m_el[2][1], + m_el[2][2] - m.m_el[2][2]); #endif return *this; } - -SIMD_FORCE_INLINE btScalar +SIMD_FORCE_INLINE btScalar btMatrix3x3::determinant() const -{ +{ return btTriple((*this)[0], (*this)[1], (*this)[2]); } - -SIMD_FORCE_INLINE btMatrix3x3 +SIMD_FORCE_INLINE btMatrix3x3 btMatrix3x3::absolute() const { -#if defined BT_USE_SIMD_VECTOR3 && (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)) - return btMatrix3x3( - _mm_and_ps(m_el[0].mVec128, btvAbsfMask), - _mm_and_ps(m_el[1].mVec128, btvAbsfMask), - _mm_and_ps(m_el[2].mVec128, btvAbsfMask)); -#elif defined(BT_USE_NEON) - return btMatrix3x3( - (float32x4_t)vandq_s32((int32x4_t)m_el[0].mVec128, btv3AbsMask), - (float32x4_t)vandq_s32((int32x4_t)m_el[1].mVec128, btv3AbsMask), - (float32x4_t)vandq_s32((int32x4_t)m_el[2].mVec128, btv3AbsMask)); -#else +#if defined BT_USE_SIMD_VECTOR3 && (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) return btMatrix3x3( - btFabs(m_el[0].x()), btFabs(m_el[0].y()), btFabs(m_el[0].z()), - btFabs(m_el[1].x()), btFabs(m_el[1].y()), btFabs(m_el[1].z()), - btFabs(m_el[2].x()), btFabs(m_el[2].y()), btFabs(m_el[2].z())); -#endif -} - -SIMD_FORCE_INLINE btMatrix3x3 -btMatrix3x3::transpose() const -{ -#if defined BT_USE_SIMD_VECTOR3 && (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)) - __m128 v0 = m_el[0].mVec128; - __m128 v1 = m_el[1].mVec128; - __m128 v2 = m_el[2].mVec128; // x2 y2 z2 w2 - __m128 vT; - - v2 = _mm_and_ps(v2, btvFFF0fMask); // x2 y2 z2 0 - - vT = _mm_unpackhi_ps(v0, v1); // z0 z1 * * - v0 = _mm_unpacklo_ps(v0, v1); // x0 x1 y0 y1 - - v1 = _mm_shuffle_ps(v0, v2, BT_SHUFFLE(2, 3, 1, 3) ); // y0 y1 y2 0 - v0 = _mm_shuffle_ps(v0, v2, BT_SHUFFLE(0, 1, 0, 3) ); // x0 x1 x2 0 - v2 = btCastdTo128f(_mm_move_sd(btCastfTo128d(v2), btCastfTo128d(vT))); // z0 z1 z2 0 - - - return btMatrix3x3( v0, v1, v2 ); + _mm_and_ps(m_el[0].mVec128, btvAbsfMask), + _mm_and_ps(m_el[1].mVec128, btvAbsfMask), + _mm_and_ps(m_el[2].mVec128, btvAbsfMask)); #elif defined(BT_USE_NEON) - // note: zeros the w channel. We can preserve it at the cost of two more vtrn instructions. - static const uint32x2_t zMask = (const uint32x2_t) {static_cast(-1), 0 }; - float32x4x2_t top = vtrnq_f32( m_el[0].mVec128, m_el[1].mVec128 ); // {x0 x1 z0 z1}, {y0 y1 w0 w1} - float32x2x2_t bl = vtrn_f32( vget_low_f32(m_el[2].mVec128), vdup_n_f32(0.0f) ); // {x2 0 }, {y2 0} - float32x4_t v0 = vcombine_f32( vget_low_f32(top.val[0]), bl.val[0] ); - float32x4_t v1 = vcombine_f32( vget_low_f32(top.val[1]), bl.val[1] ); - float32x2_t q = (float32x2_t) vand_u32( (uint32x2_t) vget_high_f32( m_el[2].mVec128), zMask ); - float32x4_t v2 = vcombine_f32( vget_high_f32(top.val[0]), q ); // z0 z1 z2 0 - return btMatrix3x3( v0, v1, v2 ); + return btMatrix3x3( + (float32x4_t)vandq_s32((int32x4_t)m_el[0].mVec128, btv3AbsMask), + (float32x4_t)vandq_s32((int32x4_t)m_el[1].mVec128, btv3AbsMask), + (float32x4_t)vandq_s32((int32x4_t)m_el[2].mVec128, btv3AbsMask)); #else - return btMatrix3x3( m_el[0].x(), m_el[1].x(), m_el[2].x(), - m_el[0].y(), m_el[1].y(), m_el[2].y(), - m_el[0].z(), m_el[1].z(), m_el[2].z()); + return btMatrix3x3( + btFabs(m_el[0].x()), btFabs(m_el[0].y()), btFabs(m_el[0].z()), + btFabs(m_el[1].x()), btFabs(m_el[1].y()), btFabs(m_el[1].z()), + btFabs(m_el[2].x()), btFabs(m_el[2].y()), btFabs(m_el[2].z())); #endif } -SIMD_FORCE_INLINE btMatrix3x3 -btMatrix3x3::adjoint() const +SIMD_FORCE_INLINE btMatrix3x3 +btMatrix3x3::transpose() const +{ +#if defined BT_USE_SIMD_VECTOR3 && (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) + __m128 v0 = m_el[0].mVec128; + __m128 v1 = m_el[1].mVec128; + __m128 v2 = m_el[2].mVec128; // x2 y2 z2 w2 + __m128 vT; + + v2 = _mm_and_ps(v2, btvFFF0fMask); // x2 y2 z2 0 + + vT = _mm_unpackhi_ps(v0, v1); // z0 z1 * * + v0 = _mm_unpacklo_ps(v0, v1); // x0 x1 y0 y1 + + v1 = _mm_shuffle_ps(v0, v2, BT_SHUFFLE(2, 3, 1, 3)); // y0 y1 y2 0 + v0 = _mm_shuffle_ps(v0, v2, BT_SHUFFLE(0, 1, 0, 3)); // x0 x1 x2 0 + v2 = btCastdTo128f(_mm_move_sd(btCastfTo128d(v2), btCastfTo128d(vT))); // z0 z1 z2 0 + + return btMatrix3x3(v0, v1, v2); +#elif defined(BT_USE_NEON) + // note: zeros the w channel. We can preserve it at the cost of two more vtrn instructions. + static const uint32x2_t zMask = (const uint32x2_t){static_cast(-1), 0}; + float32x4x2_t top = vtrnq_f32(m_el[0].mVec128, m_el[1].mVec128); // {x0 x1 z0 z1}, {y0 y1 w0 w1} + float32x2x2_t bl = vtrn_f32(vget_low_f32(m_el[2].mVec128), vdup_n_f32(0.0f)); // {x2 0 }, {y2 0} + float32x4_t v0 = vcombine_f32(vget_low_f32(top.val[0]), bl.val[0]); + float32x4_t v1 = vcombine_f32(vget_low_f32(top.val[1]), bl.val[1]); + float32x2_t q = (float32x2_t)vand_u32((uint32x2_t)vget_high_f32(m_el[2].mVec128), zMask); + float32x4_t v2 = vcombine_f32(vget_high_f32(top.val[0]), q); // z0 z1 z2 0 + return btMatrix3x3(v0, v1, v2); +#else + return btMatrix3x3(m_el[0].x(), m_el[1].x(), m_el[2].x(), + m_el[0].y(), m_el[1].y(), m_el[2].y(), + m_el[0].z(), m_el[1].z(), m_el[2].z()); +#endif +} + +SIMD_FORCE_INLINE btMatrix3x3 +btMatrix3x3::adjoint() const { return btMatrix3x3(cofac(1, 1, 2, 2), cofac(0, 2, 2, 1), cofac(0, 1, 1, 2), - cofac(1, 2, 2, 0), cofac(0, 0, 2, 2), cofac(0, 2, 1, 0), - cofac(1, 0, 2, 1), cofac(0, 1, 2, 0), cofac(0, 0, 1, 1)); + cofac(1, 2, 2, 0), cofac(0, 0, 2, 2), cofac(0, 2, 1, 0), + cofac(1, 0, 2, 1), cofac(0, 1, 2, 0), cofac(0, 0, 1, 1)); } -SIMD_FORCE_INLINE btMatrix3x3 +SIMD_FORCE_INLINE btMatrix3x3 btMatrix3x3::inverse() const { btVector3 co(cofac(1, 1, 2, 2), cofac(1, 2, 2, 0), cofac(1, 0, 2, 1)); @@ -1080,54 +1075,54 @@ btMatrix3x3::inverse() const btAssert(det != btScalar(0.0)); btScalar s = btScalar(1.0) / det; return btMatrix3x3(co.x() * s, cofac(0, 2, 2, 1) * s, cofac(0, 1, 1, 2) * s, - co.y() * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s, - co.z() * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s); + co.y() * s, cofac(0, 0, 2, 2) * s, cofac(0, 2, 1, 0) * s, + co.z() * s, cofac(0, 1, 2, 0) * s, cofac(0, 0, 1, 1) * s); } -SIMD_FORCE_INLINE btMatrix3x3 +SIMD_FORCE_INLINE btMatrix3x3 btMatrix3x3::transposeTimes(const btMatrix3x3& m) const { -#if defined BT_USE_SIMD_VECTOR3 && (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)) - // zeros w -// static const __m128i xyzMask = (const __m128i){ -1ULL, 0xffffffffULL }; - __m128 row = m_el[0].mVec128; - __m128 m0 = _mm_and_ps( m.getRow(0).mVec128, btvFFF0fMask ); - __m128 m1 = _mm_and_ps( m.getRow(1).mVec128, btvFFF0fMask); - __m128 m2 = _mm_and_ps( m.getRow(2).mVec128, btvFFF0fMask ); - __m128 r0 = _mm_mul_ps(m0, _mm_shuffle_ps(row, row, 0)); - __m128 r1 = _mm_mul_ps(m0, _mm_shuffle_ps(row, row, 0x55)); - __m128 r2 = _mm_mul_ps(m0, _mm_shuffle_ps(row, row, 0xaa)); - row = m_el[1].mVec128; - r0 = _mm_add_ps( r0, _mm_mul_ps(m1, _mm_shuffle_ps(row, row, 0))); - r1 = _mm_add_ps( r1, _mm_mul_ps(m1, _mm_shuffle_ps(row, row, 0x55))); - r2 = _mm_add_ps( r2, _mm_mul_ps(m1, _mm_shuffle_ps(row, row, 0xaa))); - row = m_el[2].mVec128; - r0 = _mm_add_ps( r0, _mm_mul_ps(m2, _mm_shuffle_ps(row, row, 0))); - r1 = _mm_add_ps( r1, _mm_mul_ps(m2, _mm_shuffle_ps(row, row, 0x55))); - r2 = _mm_add_ps( r2, _mm_mul_ps(m2, _mm_shuffle_ps(row, row, 0xaa))); - return btMatrix3x3( r0, r1, r2 ); +#if defined BT_USE_SIMD_VECTOR3 && (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) + // zeros w + // static const __m128i xyzMask = (const __m128i){ -1ULL, 0xffffffffULL }; + __m128 row = m_el[0].mVec128; + __m128 m0 = _mm_and_ps(m.getRow(0).mVec128, btvFFF0fMask); + __m128 m1 = _mm_and_ps(m.getRow(1).mVec128, btvFFF0fMask); + __m128 m2 = _mm_and_ps(m.getRow(2).mVec128, btvFFF0fMask); + __m128 r0 = _mm_mul_ps(m0, _mm_shuffle_ps(row, row, 0)); + __m128 r1 = _mm_mul_ps(m0, _mm_shuffle_ps(row, row, 0x55)); + __m128 r2 = _mm_mul_ps(m0, _mm_shuffle_ps(row, row, 0xaa)); + row = m_el[1].mVec128; + r0 = _mm_add_ps(r0, _mm_mul_ps(m1, _mm_shuffle_ps(row, row, 0))); + r1 = _mm_add_ps(r1, _mm_mul_ps(m1, _mm_shuffle_ps(row, row, 0x55))); + r2 = _mm_add_ps(r2, _mm_mul_ps(m1, _mm_shuffle_ps(row, row, 0xaa))); + row = m_el[2].mVec128; + r0 = _mm_add_ps(r0, _mm_mul_ps(m2, _mm_shuffle_ps(row, row, 0))); + r1 = _mm_add_ps(r1, _mm_mul_ps(m2, _mm_shuffle_ps(row, row, 0x55))); + r2 = _mm_add_ps(r2, _mm_mul_ps(m2, _mm_shuffle_ps(row, row, 0xaa))); + return btMatrix3x3(r0, r1, r2); #elif defined BT_USE_NEON - // zeros w - static const uint32x4_t xyzMask = (const uint32x4_t){ static_cast(-1), static_cast(-1), static_cast(-1), 0 }; - float32x4_t m0 = (float32x4_t) vandq_u32( (uint32x4_t) m.getRow(0).mVec128, xyzMask ); - float32x4_t m1 = (float32x4_t) vandq_u32( (uint32x4_t) m.getRow(1).mVec128, xyzMask ); - float32x4_t m2 = (float32x4_t) vandq_u32( (uint32x4_t) m.getRow(2).mVec128, xyzMask ); - float32x4_t row = m_el[0].mVec128; - float32x4_t r0 = vmulq_lane_f32( m0, vget_low_f32(row), 0); - float32x4_t r1 = vmulq_lane_f32( m0, vget_low_f32(row), 1); - float32x4_t r2 = vmulq_lane_f32( m0, vget_high_f32(row), 0); - row = m_el[1].mVec128; - r0 = vmlaq_lane_f32( r0, m1, vget_low_f32(row), 0); - r1 = vmlaq_lane_f32( r1, m1, vget_low_f32(row), 1); - r2 = vmlaq_lane_f32( r2, m1, vget_high_f32(row), 0); - row = m_el[2].mVec128; - r0 = vmlaq_lane_f32( r0, m2, vget_low_f32(row), 0); - r1 = vmlaq_lane_f32( r1, m2, vget_low_f32(row), 1); - r2 = vmlaq_lane_f32( r2, m2, vget_high_f32(row), 0); - return btMatrix3x3( r0, r1, r2 ); + // zeros w + static const uint32x4_t xyzMask = (const uint32x4_t){static_cast(-1), static_cast(-1), static_cast(-1), 0}; + float32x4_t m0 = (float32x4_t)vandq_u32((uint32x4_t)m.getRow(0).mVec128, xyzMask); + float32x4_t m1 = (float32x4_t)vandq_u32((uint32x4_t)m.getRow(1).mVec128, xyzMask); + float32x4_t m2 = (float32x4_t)vandq_u32((uint32x4_t)m.getRow(2).mVec128, xyzMask); + float32x4_t row = m_el[0].mVec128; + float32x4_t r0 = vmulq_lane_f32(m0, vget_low_f32(row), 0); + float32x4_t r1 = vmulq_lane_f32(m0, vget_low_f32(row), 1); + float32x4_t r2 = vmulq_lane_f32(m0, vget_high_f32(row), 0); + row = m_el[1].mVec128; + r0 = vmlaq_lane_f32(r0, m1, vget_low_f32(row), 0); + r1 = vmlaq_lane_f32(r1, m1, vget_low_f32(row), 1); + r2 = vmlaq_lane_f32(r2, m1, vget_high_f32(row), 0); + row = m_el[2].mVec128; + r0 = vmlaq_lane_f32(r0, m2, vget_low_f32(row), 0); + r1 = vmlaq_lane_f32(r1, m2, vget_low_f32(row), 1); + r2 = vmlaq_lane_f32(r2, m2, vget_high_f32(row), 0); + return btMatrix3x3(r0, r1, r2); #else - return btMatrix3x3( + return btMatrix3x3( m_el[0].x() * m[0].x() + m_el[1].x() * m[1].x() + m_el[2].x() * m[2].x(), m_el[0].x() * m[0].y() + m_el[1].x() * m[1].y() + m_el[2].x() * m[2].y(), m_el[0].x() * m[0].z() + m_el[1].x() * m[1].z() + m_el[2].x() * m[2].z(), @@ -1140,51 +1135,51 @@ btMatrix3x3::transposeTimes(const btMatrix3x3& m) const #endif } -SIMD_FORCE_INLINE btMatrix3x3 +SIMD_FORCE_INLINE btMatrix3x3 btMatrix3x3::timesTranspose(const btMatrix3x3& m) const { -#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)) - __m128 a0 = m_el[0].mVec128; - __m128 a1 = m_el[1].mVec128; - __m128 a2 = m_el[2].mVec128; - - btMatrix3x3 mT = m.transpose(); // we rely on transpose() zeroing w channel so that we don't have to do it here - __m128 mx = mT[0].mVec128; - __m128 my = mT[1].mVec128; - __m128 mz = mT[2].mVec128; - - __m128 r0 = _mm_mul_ps(mx, _mm_shuffle_ps(a0, a0, 0x00)); - __m128 r1 = _mm_mul_ps(mx, _mm_shuffle_ps(a1, a1, 0x00)); - __m128 r2 = _mm_mul_ps(mx, _mm_shuffle_ps(a2, a2, 0x00)); - r0 = _mm_add_ps(r0, _mm_mul_ps(my, _mm_shuffle_ps(a0, a0, 0x55))); - r1 = _mm_add_ps(r1, _mm_mul_ps(my, _mm_shuffle_ps(a1, a1, 0x55))); - r2 = _mm_add_ps(r2, _mm_mul_ps(my, _mm_shuffle_ps(a2, a2, 0x55))); - r0 = _mm_add_ps(r0, _mm_mul_ps(mz, _mm_shuffle_ps(a0, a0, 0xaa))); - r1 = _mm_add_ps(r1, _mm_mul_ps(mz, _mm_shuffle_ps(a1, a1, 0xaa))); - r2 = _mm_add_ps(r2, _mm_mul_ps(mz, _mm_shuffle_ps(a2, a2, 0xaa))); - return btMatrix3x3( r0, r1, r2); - +#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) + __m128 a0 = m_el[0].mVec128; + __m128 a1 = m_el[1].mVec128; + __m128 a2 = m_el[2].mVec128; + + btMatrix3x3 mT = m.transpose(); // we rely on transpose() zeroing w channel so that we don't have to do it here + __m128 mx = mT[0].mVec128; + __m128 my = mT[1].mVec128; + __m128 mz = mT[2].mVec128; + + __m128 r0 = _mm_mul_ps(mx, _mm_shuffle_ps(a0, a0, 0x00)); + __m128 r1 = _mm_mul_ps(mx, _mm_shuffle_ps(a1, a1, 0x00)); + __m128 r2 = _mm_mul_ps(mx, _mm_shuffle_ps(a2, a2, 0x00)); + r0 = _mm_add_ps(r0, _mm_mul_ps(my, _mm_shuffle_ps(a0, a0, 0x55))); + r1 = _mm_add_ps(r1, _mm_mul_ps(my, _mm_shuffle_ps(a1, a1, 0x55))); + r2 = _mm_add_ps(r2, _mm_mul_ps(my, _mm_shuffle_ps(a2, a2, 0x55))); + r0 = _mm_add_ps(r0, _mm_mul_ps(mz, _mm_shuffle_ps(a0, a0, 0xaa))); + r1 = _mm_add_ps(r1, _mm_mul_ps(mz, _mm_shuffle_ps(a1, a1, 0xaa))); + r2 = _mm_add_ps(r2, _mm_mul_ps(mz, _mm_shuffle_ps(a2, a2, 0xaa))); + return btMatrix3x3(r0, r1, r2); + #elif defined BT_USE_NEON - float32x4_t a0 = m_el[0].mVec128; - float32x4_t a1 = m_el[1].mVec128; - float32x4_t a2 = m_el[2].mVec128; - - btMatrix3x3 mT = m.transpose(); // we rely on transpose() zeroing w channel so that we don't have to do it here - float32x4_t mx = mT[0].mVec128; - float32x4_t my = mT[1].mVec128; - float32x4_t mz = mT[2].mVec128; - - float32x4_t r0 = vmulq_lane_f32( mx, vget_low_f32(a0), 0); - float32x4_t r1 = vmulq_lane_f32( mx, vget_low_f32(a1), 0); - float32x4_t r2 = vmulq_lane_f32( mx, vget_low_f32(a2), 0); - r0 = vmlaq_lane_f32( r0, my, vget_low_f32(a0), 1); - r1 = vmlaq_lane_f32( r1, my, vget_low_f32(a1), 1); - r2 = vmlaq_lane_f32( r2, my, vget_low_f32(a2), 1); - r0 = vmlaq_lane_f32( r0, mz, vget_high_f32(a0), 0); - r1 = vmlaq_lane_f32( r1, mz, vget_high_f32(a1), 0); - r2 = vmlaq_lane_f32( r2, mz, vget_high_f32(a2), 0); - return btMatrix3x3( r0, r1, r2 ); - + float32x4_t a0 = m_el[0].mVec128; + float32x4_t a1 = m_el[1].mVec128; + float32x4_t a2 = m_el[2].mVec128; + + btMatrix3x3 mT = m.transpose(); // we rely on transpose() zeroing w channel so that we don't have to do it here + float32x4_t mx = mT[0].mVec128; + float32x4_t my = mT[1].mVec128; + float32x4_t mz = mT[2].mVec128; + + float32x4_t r0 = vmulq_lane_f32(mx, vget_low_f32(a0), 0); + float32x4_t r1 = vmulq_lane_f32(mx, vget_low_f32(a1), 0); + float32x4_t r2 = vmulq_lane_f32(mx, vget_low_f32(a2), 0); + r0 = vmlaq_lane_f32(r0, my, vget_low_f32(a0), 1); + r1 = vmlaq_lane_f32(r1, my, vget_low_f32(a1), 1); + r2 = vmlaq_lane_f32(r2, my, vget_low_f32(a2), 1); + r0 = vmlaq_lane_f32(r0, mz, vget_high_f32(a0), 0); + r1 = vmlaq_lane_f32(r1, mz, vget_high_f32(a1), 0); + r2 = vmlaq_lane_f32(r2, mz, vget_high_f32(a2), 0); + return btMatrix3x3(r0, r1, r2); + #else return btMatrix3x3( m_el[0].dot(m[0]), m_el[0].dot(m[1]), m_el[0].dot(m[2]), @@ -1193,139 +1188,138 @@ btMatrix3x3::timesTranspose(const btMatrix3x3& m) const #endif } -SIMD_FORCE_INLINE btVector3 -operator*(const btMatrix3x3& m, const btVector3& v) +SIMD_FORCE_INLINE btVector3 +operator*(const btMatrix3x3& m, const btVector3& v) { -#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE))|| defined (BT_USE_NEON) - return v.dot3(m[0], m[1], m[2]); +#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) || defined(BT_USE_NEON) + return v.dot3(m[0], m[1], m[2]); #else return btVector3(m[0].dot(v), m[1].dot(v), m[2].dot(v)); #endif } - SIMD_FORCE_INLINE btVector3 operator*(const btVector3& v, const btMatrix3x3& m) { -#if defined BT_USE_SIMD_VECTOR3 && (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)) +#if defined BT_USE_SIMD_VECTOR3 && (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) - const __m128 vv = v.mVec128; + const __m128 vv = v.mVec128; - __m128 c0 = bt_splat_ps( vv, 0); - __m128 c1 = bt_splat_ps( vv, 1); - __m128 c2 = bt_splat_ps( vv, 2); + __m128 c0 = bt_splat_ps(vv, 0); + __m128 c1 = bt_splat_ps(vv, 1); + __m128 c2 = bt_splat_ps(vv, 2); - c0 = _mm_mul_ps(c0, _mm_and_ps(m[0].mVec128, btvFFF0fMask) ); - c1 = _mm_mul_ps(c1, _mm_and_ps(m[1].mVec128, btvFFF0fMask) ); - c0 = _mm_add_ps(c0, c1); - c2 = _mm_mul_ps(c2, _mm_and_ps(m[2].mVec128, btvFFF0fMask) ); - - return btVector3(_mm_add_ps(c0, c2)); + c0 = _mm_mul_ps(c0, _mm_and_ps(m[0].mVec128, btvFFF0fMask)); + c1 = _mm_mul_ps(c1, _mm_and_ps(m[1].mVec128, btvFFF0fMask)); + c0 = _mm_add_ps(c0, c1); + c2 = _mm_mul_ps(c2, _mm_and_ps(m[2].mVec128, btvFFF0fMask)); + + return btVector3(_mm_add_ps(c0, c2)); #elif defined(BT_USE_NEON) - const float32x4_t vv = v.mVec128; - const float32x2_t vlo = vget_low_f32(vv); - const float32x2_t vhi = vget_high_f32(vv); + const float32x4_t vv = v.mVec128; + const float32x2_t vlo = vget_low_f32(vv); + const float32x2_t vhi = vget_high_f32(vv); - float32x4_t c0, c1, c2; + float32x4_t c0, c1, c2; - c0 = (float32x4_t) vandq_s32((int32x4_t)m[0].mVec128, btvFFF0Mask); - c1 = (float32x4_t) vandq_s32((int32x4_t)m[1].mVec128, btvFFF0Mask); - c2 = (float32x4_t) vandq_s32((int32x4_t)m[2].mVec128, btvFFF0Mask); + c0 = (float32x4_t)vandq_s32((int32x4_t)m[0].mVec128, btvFFF0Mask); + c1 = (float32x4_t)vandq_s32((int32x4_t)m[1].mVec128, btvFFF0Mask); + c2 = (float32x4_t)vandq_s32((int32x4_t)m[2].mVec128, btvFFF0Mask); - c0 = vmulq_lane_f32(c0, vlo, 0); - c1 = vmulq_lane_f32(c1, vlo, 1); - c2 = vmulq_lane_f32(c2, vhi, 0); - c0 = vaddq_f32(c0, c1); - c0 = vaddq_f32(c0, c2); - - return btVector3(c0); + c0 = vmulq_lane_f32(c0, vlo, 0); + c1 = vmulq_lane_f32(c1, vlo, 1); + c2 = vmulq_lane_f32(c2, vhi, 0); + c0 = vaddq_f32(c0, c1); + c0 = vaddq_f32(c0, c2); + + return btVector3(c0); #else return btVector3(m.tdotx(v), m.tdoty(v), m.tdotz(v)); #endif } -SIMD_FORCE_INLINE btMatrix3x3 +SIMD_FORCE_INLINE btMatrix3x3 operator*(const btMatrix3x3& m1, const btMatrix3x3& m2) { -#if defined BT_USE_SIMD_VECTOR3 && (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)) +#if defined BT_USE_SIMD_VECTOR3 && (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) - __m128 m10 = m1[0].mVec128; - __m128 m11 = m1[1].mVec128; - __m128 m12 = m1[2].mVec128; - - __m128 m2v = _mm_and_ps(m2[0].mVec128, btvFFF0fMask); - - __m128 c0 = bt_splat_ps( m10, 0); - __m128 c1 = bt_splat_ps( m11, 0); - __m128 c2 = bt_splat_ps( m12, 0); - - c0 = _mm_mul_ps(c0, m2v); - c1 = _mm_mul_ps(c1, m2v); - c2 = _mm_mul_ps(c2, m2v); - - m2v = _mm_and_ps(m2[1].mVec128, btvFFF0fMask); - - __m128 c0_1 = bt_splat_ps( m10, 1); - __m128 c1_1 = bt_splat_ps( m11, 1); - __m128 c2_1 = bt_splat_ps( m12, 1); - - c0_1 = _mm_mul_ps(c0_1, m2v); - c1_1 = _mm_mul_ps(c1_1, m2v); - c2_1 = _mm_mul_ps(c2_1, m2v); - - m2v = _mm_and_ps(m2[2].mVec128, btvFFF0fMask); - - c0 = _mm_add_ps(c0, c0_1); - c1 = _mm_add_ps(c1, c1_1); - c2 = _mm_add_ps(c2, c2_1); - - m10 = bt_splat_ps( m10, 2); - m11 = bt_splat_ps( m11, 2); - m12 = bt_splat_ps( m12, 2); - - m10 = _mm_mul_ps(m10, m2v); - m11 = _mm_mul_ps(m11, m2v); - m12 = _mm_mul_ps(m12, m2v); - - c0 = _mm_add_ps(c0, m10); - c1 = _mm_add_ps(c1, m11); - c2 = _mm_add_ps(c2, m12); - - return btMatrix3x3(c0, c1, c2); + __m128 m10 = m1[0].mVec128; + __m128 m11 = m1[1].mVec128; + __m128 m12 = m1[2].mVec128; + + __m128 m2v = _mm_and_ps(m2[0].mVec128, btvFFF0fMask); + + __m128 c0 = bt_splat_ps(m10, 0); + __m128 c1 = bt_splat_ps(m11, 0); + __m128 c2 = bt_splat_ps(m12, 0); + + c0 = _mm_mul_ps(c0, m2v); + c1 = _mm_mul_ps(c1, m2v); + c2 = _mm_mul_ps(c2, m2v); + + m2v = _mm_and_ps(m2[1].mVec128, btvFFF0fMask); + + __m128 c0_1 = bt_splat_ps(m10, 1); + __m128 c1_1 = bt_splat_ps(m11, 1); + __m128 c2_1 = bt_splat_ps(m12, 1); + + c0_1 = _mm_mul_ps(c0_1, m2v); + c1_1 = _mm_mul_ps(c1_1, m2v); + c2_1 = _mm_mul_ps(c2_1, m2v); + + m2v = _mm_and_ps(m2[2].mVec128, btvFFF0fMask); + + c0 = _mm_add_ps(c0, c0_1); + c1 = _mm_add_ps(c1, c1_1); + c2 = _mm_add_ps(c2, c2_1); + + m10 = bt_splat_ps(m10, 2); + m11 = bt_splat_ps(m11, 2); + m12 = bt_splat_ps(m12, 2); + + m10 = _mm_mul_ps(m10, m2v); + m11 = _mm_mul_ps(m11, m2v); + m12 = _mm_mul_ps(m12, m2v); + + c0 = _mm_add_ps(c0, m10); + c1 = _mm_add_ps(c1, m11); + c2 = _mm_add_ps(c2, m12); + + return btMatrix3x3(c0, c1, c2); #elif defined(BT_USE_NEON) - float32x4_t rv0, rv1, rv2; - float32x4_t v0, v1, v2; - float32x4_t mv0, mv1, mv2; + float32x4_t rv0, rv1, rv2; + float32x4_t v0, v1, v2; + float32x4_t mv0, mv1, mv2; - v0 = m1[0].mVec128; - v1 = m1[1].mVec128; - v2 = m1[2].mVec128; + v0 = m1[0].mVec128; + v1 = m1[1].mVec128; + v2 = m1[2].mVec128; - mv0 = (float32x4_t) vandq_s32((int32x4_t)m2[0].mVec128, btvFFF0Mask); - mv1 = (float32x4_t) vandq_s32((int32x4_t)m2[1].mVec128, btvFFF0Mask); - mv2 = (float32x4_t) vandq_s32((int32x4_t)m2[2].mVec128, btvFFF0Mask); - - rv0 = vmulq_lane_f32(mv0, vget_low_f32(v0), 0); - rv1 = vmulq_lane_f32(mv0, vget_low_f32(v1), 0); - rv2 = vmulq_lane_f32(mv0, vget_low_f32(v2), 0); - - rv0 = vmlaq_lane_f32(rv0, mv1, vget_low_f32(v0), 1); - rv1 = vmlaq_lane_f32(rv1, mv1, vget_low_f32(v1), 1); - rv2 = vmlaq_lane_f32(rv2, mv1, vget_low_f32(v2), 1); - - rv0 = vmlaq_lane_f32(rv0, mv2, vget_high_f32(v0), 0); - rv1 = vmlaq_lane_f32(rv1, mv2, vget_high_f32(v1), 0); - rv2 = vmlaq_lane_f32(rv2, mv2, vget_high_f32(v2), 0); + mv0 = (float32x4_t)vandq_s32((int32x4_t)m2[0].mVec128, btvFFF0Mask); + mv1 = (float32x4_t)vandq_s32((int32x4_t)m2[1].mVec128, btvFFF0Mask); + mv2 = (float32x4_t)vandq_s32((int32x4_t)m2[2].mVec128, btvFFF0Mask); + + rv0 = vmulq_lane_f32(mv0, vget_low_f32(v0), 0); + rv1 = vmulq_lane_f32(mv0, vget_low_f32(v1), 0); + rv2 = vmulq_lane_f32(mv0, vget_low_f32(v2), 0); + + rv0 = vmlaq_lane_f32(rv0, mv1, vget_low_f32(v0), 1); + rv1 = vmlaq_lane_f32(rv1, mv1, vget_low_f32(v1), 1); + rv2 = vmlaq_lane_f32(rv2, mv1, vget_low_f32(v2), 1); + + rv0 = vmlaq_lane_f32(rv0, mv2, vget_high_f32(v0), 0); + rv1 = vmlaq_lane_f32(rv1, mv2, vget_high_f32(v1), 0); + rv2 = vmlaq_lane_f32(rv2, mv2, vget_high_f32(v2), 0); return btMatrix3x3(rv0, rv1, rv2); - -#else + +#else return btMatrix3x3( - m2.tdotx( m1[0]), m2.tdoty( m1[0]), m2.tdotz( m1[0]), - m2.tdotx( m1[1]), m2.tdoty( m1[1]), m2.tdotz( m1[1]), - m2.tdotx( m1[2]), m2.tdoty( m1[2]), m2.tdotz( m1[2])); + m2.tdotx(m1[0]), m2.tdoty(m1[0]), m2.tdotz(m1[0]), + m2.tdotx(m1[1]), m2.tdoty(m1[1]), m2.tdotz(m1[1]), + m2.tdotx(m1[2]), m2.tdoty(m1[2]), m2.tdotz(m1[2])); #endif } @@ -1348,73 +1342,67 @@ m1[0][2] * m2[0][2] + m1[1][2] * m2[1][2] + m1[2][2] * m2[2][2]); * It will test all elements are equal. */ SIMD_FORCE_INLINE bool operator==(const btMatrix3x3& m1, const btMatrix3x3& m2) { -#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE)) +#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) - __m128 c0, c1, c2; + __m128 c0, c1, c2; - c0 = _mm_cmpeq_ps(m1[0].mVec128, m2[0].mVec128); - c1 = _mm_cmpeq_ps(m1[1].mVec128, m2[1].mVec128); - c2 = _mm_cmpeq_ps(m1[2].mVec128, m2[2].mVec128); - - c0 = _mm_and_ps(c0, c1); - c0 = _mm_and_ps(c0, c2); + c0 = _mm_cmpeq_ps(m1[0].mVec128, m2[0].mVec128); + c1 = _mm_cmpeq_ps(m1[1].mVec128, m2[1].mVec128); + c2 = _mm_cmpeq_ps(m1[2].mVec128, m2[2].mVec128); + + c0 = _mm_and_ps(c0, c1); + c0 = _mm_and_ps(c0, c2); int m = _mm_movemask_ps((__m128)c0); return (0x7 == (m & 0x7)); - -#else - return - ( m1[0][0] == m2[0][0] && m1[1][0] == m2[1][0] && m1[2][0] == m2[2][0] && - m1[0][1] == m2[0][1] && m1[1][1] == m2[1][1] && m1[2][1] == m2[2][1] && - m1[0][2] == m2[0][2] && m1[1][2] == m2[1][2] && m1[2][2] == m2[2][2] ); + +#else + return (m1[0][0] == m2[0][0] && m1[1][0] == m2[1][0] && m1[2][0] == m2[2][0] && + m1[0][1] == m2[0][1] && m1[1][1] == m2[1][1] && m1[2][1] == m2[2][1] && + m1[0][2] == m2[0][2] && m1[1][2] == m2[1][2] && m1[2][2] == m2[2][2]); #endif } ///for serialization -struct btMatrix3x3FloatData +struct btMatrix3x3FloatData { btVector3FloatData m_el[3]; }; ///for serialization -struct btMatrix3x3DoubleData +struct btMatrix3x3DoubleData { btVector3DoubleData m_el[3]; }; - - - -SIMD_FORCE_INLINE void btMatrix3x3::serialize(struct btMatrix3x3Data& dataOut) const +SIMD_FORCE_INLINE void btMatrix3x3::serialize(struct btMatrix3x3Data& dataOut) const { - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) m_el[i].serialize(dataOut.m_el[i]); } -SIMD_FORCE_INLINE void btMatrix3x3::serializeFloat(struct btMatrix3x3FloatData& dataOut) const +SIMD_FORCE_INLINE void btMatrix3x3::serializeFloat(struct btMatrix3x3FloatData& dataOut) const { - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) m_el[i].serializeFloat(dataOut.m_el[i]); } - -SIMD_FORCE_INLINE void btMatrix3x3::deSerialize(const struct btMatrix3x3Data& dataIn) +SIMD_FORCE_INLINE void btMatrix3x3::deSerialize(const struct btMatrix3x3Data& dataIn) { - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) m_el[i].deSerialize(dataIn.m_el[i]); } -SIMD_FORCE_INLINE void btMatrix3x3::deSerializeFloat(const struct btMatrix3x3FloatData& dataIn) +SIMD_FORCE_INLINE void btMatrix3x3::deSerializeFloat(const struct btMatrix3x3FloatData& dataIn) { - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) m_el[i].deSerializeFloat(dataIn.m_el[i]); } -SIMD_FORCE_INLINE void btMatrix3x3::deSerializeDouble(const struct btMatrix3x3DoubleData& dataIn) +SIMD_FORCE_INLINE void btMatrix3x3::deSerializeDouble(const struct btMatrix3x3DoubleData& dataIn) { - for (int i=0;i<3;i++) + for (int i = 0; i < 3; i++) m_el[i].deSerializeDouble(dataIn.m_el[i]); } -#endif //BT_MATRIX3x3_H - +#endif //BT_MATRIX3x3_H diff --git a/src/LinearMath/btMatrixX.h b/src/LinearMath/btMatrixX.h index 42caed42e..9df9e4946 100644 --- a/src/LinearMath/btMatrixX.h +++ b/src/LinearMath/btMatrixX.h @@ -24,24 +24,23 @@ subject to the following restrictions: //#define BT_DEBUG_OSTREAM #ifdef BT_DEBUG_OSTREAM #include -#include // std::setw -#endif //BT_DEBUG_OSTREAM +#include // std::setw +#endif //BT_DEBUG_OSTREAM class btIntSortPredicate { - public: - bool operator() ( const int& a, const int& b ) const - { - return a < b; - } +public: + bool operator()(const int& a, const int& b) const + { + return a < b; + } }; - template struct btVectorX { - btAlignedObjectArray m_storage; - + btAlignedObjectArray m_storage; + btVectorX() { } @@ -49,7 +48,7 @@ struct btVectorX { m_storage.resize(numRows); } - + void resize(int rows) { m_storage.resize(rows); @@ -66,13 +65,13 @@ struct btVectorX { return rows(); } - + T nrm2() const { T norm = T(0); - + int nn = rows(); - + { if (nn == 1) { @@ -82,11 +81,11 @@ struct btVectorX { T scale = 0.0; T ssq = 1.0; - + /* The following loop is equivalent to this call to the LAPACK auxiliary routine: CALL SLASSQ( N, X, INCX, SCALE, SSQ ) */ - - for (int ix=0;ix @@ -151,8 +148,7 @@ struct btVectorX } */ - -template +template struct btMatrixX { int m_rows; @@ -161,10 +157,10 @@ struct btMatrixX int m_resizeOperations; int m_setElemOperations; - btAlignedObjectArray m_storage; - mutable btAlignedObjectArray< btAlignedObjectArray > m_rowNonZeroElements1; + btAlignedObjectArray m_storage; + mutable btAlignedObjectArray > m_rowNonZeroElements1; - T* getBufferPointerWritable() + T* getBufferPointerWritable() { return m_storage.size() ? &m_storage[0] : 0; } @@ -174,21 +170,21 @@ struct btMatrixX return m_storage.size() ? &m_storage[0] : 0; } btMatrixX() - :m_rows(0), - m_cols(0), - m_operations(0), - m_resizeOperations(0), - m_setElemOperations(0) + : m_rows(0), + m_cols(0), + m_operations(0), + m_resizeOperations(0), + m_setElemOperations(0) { } - btMatrixX(int rows,int cols) - :m_rows(rows), - m_cols(cols), - m_operations(0), - m_resizeOperations(0), - m_setElemOperations(0) + btMatrixX(int rows, int cols) + : m_rows(rows), + m_cols(cols), + m_operations(0), + m_resizeOperations(0), + m_setElemOperations(0) { - resize(rows,cols); + resize(rows, cols); } void resize(int rows, int cols) { @@ -197,7 +193,7 @@ struct btMatrixX m_cols = cols; { BT_PROFILE("m_storage.resize"); - m_storage.resize(rows*cols); + m_storage.resize(rows * cols); } } int cols() const @@ -215,108 +211,99 @@ struct btMatrixX } */ - void addElem(int row,int col, T val) + void addElem(int row, int col, T val) { if (val) { - if (m_storage[col+row*m_cols]==0.f) + if (m_storage[col + row * m_cols] == 0.f) { - setElem(row,col,val); - } else + setElem(row, col, val); + } + else { - m_storage[row*m_cols+col] += val; + m_storage[row * m_cols + col] += val; } } } - - - void setElem(int row,int col, T val) + + void setElem(int row, int col, T val) { m_setElemOperations++; - m_storage[row*m_cols+col] = val; + m_storage[row * m_cols + col] = val; } - - void mulElem(int row,int col, T val) + + void mulElem(int row, int col, T val) { m_setElemOperations++; //mul doesn't change sparsity info - m_storage[row*m_cols+col] *= val; + m_storage[row * m_cols + col] *= val; } - - - - + void copyLowerToUpperTriangle() { - int count=0; - for (int row=0;row0 && numRowsOther>0 && B && C); - const btScalar *bb = B; - for ( int i = 0;i 0 && numRowsOther > 0 && B && C); + const btScalar* bb = B; + for (int i = 0; i < numRows; i++) { - const btScalar *cc = C; - for ( int j = 0;j& block) + void setSubMatrix(int rowstart, int colstart, int rowend, int colend, const btVectorX& block) { - btAssert(rowend+1-rowstart == block.rows()); - btAssert(colend+1-colstart == block.cols()); - for (int row=0;row btMatrixXf; typedef btVectorX btVectorXf; typedef btMatrixX btMatrixXd; typedef btVectorX btVectorXd; - #ifdef BT_DEBUG_OSTREAM -template -std::ostream& operator<< (std::ostream& os, const btMatrixX& mat) +template +std::ostream& operator<<(std::ostream& os, const btMatrixX& mat) +{ + os << " ["; + //printf("%s ---------------------\n",msg); + for (int i = 0; i < mat.rows(); i++) { - - os << " ["; - //printf("%s ---------------------\n",msg); - for (int i=0;i -std::ostream& operator<< (std::ostream& os, const btVectorX& mat) + os << " ]"; + //printf("\n---------------------\n"); + + return os; +} +template +std::ostream& operator<<(std::ostream& os, const btVectorX& mat) +{ + os << " ["; + //printf("%s ---------------------\n",msg); + for (int i = 0; i < mat.rows(); i++) { - - os << " ["; - //printf("%s ---------------------\n",msg); - for (int i=0;i -SIMD_FORCE_INLINE const T& btMin(const T& a, const T& b) +SIMD_FORCE_INLINE const T& btMin(const T& a, const T& b) { - return a < b ? a : b ; + return a < b ? a : b; } template -SIMD_FORCE_INLINE const T& btMax(const T& a, const T& b) +SIMD_FORCE_INLINE const T& btMax(const T& a, const T& b) { - return a > b ? a : b; + return a > b ? a : b; } template -SIMD_FORCE_INLINE const T& btClamped(const T& a, const T& lb, const T& ub) +SIMD_FORCE_INLINE const T& btClamped(const T& a, const T& lb, const T& ub) { - return a < lb ? lb : (ub < a ? ub : a); + return a < lb ? lb : (ub < a ? ub : a); } template -SIMD_FORCE_INLINE void btSetMin(T& a, const T& b) +SIMD_FORCE_INLINE void btSetMin(T& a, const T& b) { - if (b < a) + if (b < a) { a = b; } } template -SIMD_FORCE_INLINE void btSetMax(T& a, const T& b) +SIMD_FORCE_INLINE void btSetMax(T& a, const T& b) { - if (a < b) + if (a < b) { a = b; } } template -SIMD_FORCE_INLINE void btClamp(T& a, const T& lb, const T& ub) +SIMD_FORCE_INLINE void btClamp(T& a, const T& lb, const T& ub) { - if (a < lb) + if (a < lb) { - a = lb; + a = lb; } - else if (ub < a) + else if (ub < a) { a = ub; } } -#endif //BT_GEN_MINMAX_H +#endif //BT_GEN_MINMAX_H diff --git a/src/LinearMath/btMotionState.h b/src/LinearMath/btMotionState.h index 943181409..ae6a51611 100644 --- a/src/LinearMath/btMotionState.h +++ b/src/LinearMath/btMotionState.h @@ -20,21 +20,17 @@ subject to the following restrictions: ///The btMotionState interface class allows the dynamics world to synchronize and interpolate the updated world transforms with graphics ///For optimizations, potentially only moving objects get synchronized (using setWorldPosition/setWorldOrientation) -class btMotionState +class btMotionState { - public: - - virtual ~btMotionState() - { - - } - - virtual void getWorldTransform(btTransform& worldTrans ) const =0; +public: + virtual ~btMotionState() + { + } - //Bullet only calls the update of worldtransform for active objects - virtual void setWorldTransform(const btTransform& worldTrans)=0; - - + virtual void getWorldTransform(btTransform& worldTrans) const = 0; + + //Bullet only calls the update of worldtransform for active objects + virtual void setWorldTransform(const btTransform& worldTrans) = 0; }; -#endif //BT_MOTIONSTATE_H +#endif //BT_MOTIONSTATE_H diff --git a/src/LinearMath/btPolarDecomposition.cpp b/src/LinearMath/btPolarDecomposition.cpp index b3664faa4..d9c72a801 100644 --- a/src/LinearMath/btPolarDecomposition.cpp +++ b/src/LinearMath/btPolarDecomposition.cpp @@ -3,96 +3,92 @@ namespace { - btScalar abs_column_sum(const btMatrix3x3& a, int i) - { - return btFabs(a[0][i]) + btFabs(a[1][i]) + btFabs(a[2][i]); - } - - btScalar abs_row_sum(const btMatrix3x3& a, int i) - { - return btFabs(a[i][0]) + btFabs(a[i][1]) + btFabs(a[i][2]); - } - - btScalar p1_norm(const btMatrix3x3& a) - { - const btScalar sum0 = abs_column_sum(a,0); - const btScalar sum1 = abs_column_sum(a,1); - const btScalar sum2 = abs_column_sum(a,2); - return btMax(btMax(sum0, sum1), sum2); - } - - btScalar pinf_norm(const btMatrix3x3& a) - { - const btScalar sum0 = abs_row_sum(a,0); - const btScalar sum1 = abs_row_sum(a,1); - const btScalar sum2 = abs_row_sum(a,2); - return btMax(btMax(sum0, sum1), sum2); - } +btScalar abs_column_sum(const btMatrix3x3& a, int i) +{ + return btFabs(a[0][i]) + btFabs(a[1][i]) + btFabs(a[2][i]); } +btScalar abs_row_sum(const btMatrix3x3& a, int i) +{ + return btFabs(a[i][0]) + btFabs(a[i][1]) + btFabs(a[i][2]); +} +btScalar p1_norm(const btMatrix3x3& a) +{ + const btScalar sum0 = abs_column_sum(a, 0); + const btScalar sum1 = abs_column_sum(a, 1); + const btScalar sum2 = abs_column_sum(a, 2); + return btMax(btMax(sum0, sum1), sum2); +} + +btScalar pinf_norm(const btMatrix3x3& a) +{ + const btScalar sum0 = abs_row_sum(a, 0); + const btScalar sum1 = abs_row_sum(a, 1); + const btScalar sum2 = abs_row_sum(a, 2); + return btMax(btMax(sum0, sum1), sum2); +} +} // namespace btPolarDecomposition::btPolarDecomposition(btScalar tolerance, unsigned int maxIterations) -: m_tolerance(tolerance) -, m_maxIterations(maxIterations) + : m_tolerance(tolerance), m_maxIterations(maxIterations) { } unsigned int btPolarDecomposition::decompose(const btMatrix3x3& a, btMatrix3x3& u, btMatrix3x3& h) const { - // Use the 'u' and 'h' matrices for intermediate calculations - u = a; - h = a.inverse(); + // Use the 'u' and 'h' matrices for intermediate calculations + u = a; + h = a.inverse(); - for (unsigned int i = 0; i < m_maxIterations; ++i) - { - const btScalar h_1 = p1_norm(h); - const btScalar h_inf = pinf_norm(h); - const btScalar u_1 = p1_norm(u); - const btScalar u_inf = pinf_norm(u); + for (unsigned int i = 0; i < m_maxIterations; ++i) + { + const btScalar h_1 = p1_norm(h); + const btScalar h_inf = pinf_norm(h); + const btScalar u_1 = p1_norm(u); + const btScalar u_inf = pinf_norm(u); - const btScalar h_norm = h_1 * h_inf; - const btScalar u_norm = u_1 * u_inf; + const btScalar h_norm = h_1 * h_inf; + const btScalar u_norm = u_1 * u_inf; - // The matrix is effectively singular so we cannot invert it - if (btFuzzyZero(h_norm) || btFuzzyZero(u_norm)) - break; + // The matrix is effectively singular so we cannot invert it + if (btFuzzyZero(h_norm) || btFuzzyZero(u_norm)) + break; - const btScalar gamma = btPow(h_norm / u_norm, 0.25f); - const btScalar inv_gamma = btScalar(1.0) / gamma; + const btScalar gamma = btPow(h_norm / u_norm, 0.25f); + const btScalar inv_gamma = btScalar(1.0) / gamma; - // Determine the delta to 'u' - const btMatrix3x3 delta = (u * (gamma - btScalar(2.0)) + h.transpose() * inv_gamma) * btScalar(0.5); + // Determine the delta to 'u' + const btMatrix3x3 delta = (u * (gamma - btScalar(2.0)) + h.transpose() * inv_gamma) * btScalar(0.5); - // Update the matrices - u += delta; - h = u.inverse(); + // Update the matrices + u += delta; + h = u.inverse(); - // Check for convergence - if (p1_norm(delta) <= m_tolerance * u_1) - { - h = u.transpose() * a; - h = (h + h.transpose()) * 0.5; - return i; - } - } + // Check for convergence + if (p1_norm(delta) <= m_tolerance * u_1) + { + h = u.transpose() * a; + h = (h + h.transpose()) * 0.5; + return i; + } + } - // The algorithm has failed to converge to the specified tolerance, but we - // want to make sure that the matrices returned are in the right form. - h = u.transpose() * a; - h = (h + h.transpose()) * 0.5; + // The algorithm has failed to converge to the specified tolerance, but we + // want to make sure that the matrices returned are in the right form. + h = u.transpose() * a; + h = (h + h.transpose()) * 0.5; - return m_maxIterations; + return m_maxIterations; } unsigned int btPolarDecomposition::maxIterations() const { - return m_maxIterations; + return m_maxIterations; } unsigned int polarDecompose(const btMatrix3x3& a, btMatrix3x3& u, btMatrix3x3& h) { - static btPolarDecomposition polar; - return polar.decompose(a, u, h); + static btPolarDecomposition polar; + return polar.decompose(a, u, h); } - diff --git a/src/LinearMath/btPolarDecomposition.h b/src/LinearMath/btPolarDecomposition.h index 1feea0f78..bf29140a1 100644 --- a/src/LinearMath/btPolarDecomposition.h +++ b/src/LinearMath/btPolarDecomposition.h @@ -13,10 +13,8 @@ */ class btPolarDecomposition { - public: - - - /** +public: + /** * Creates an instance with optional parameters. * * @param tolerance - the tolerance used to determine convergence of the @@ -24,10 +22,10 @@ class btPolarDecomposition * @param maxIterations - the maximum number of iterations used to achieve * convergence */ - btPolarDecomposition(btScalar tolerance = btScalar(0.0001), - unsigned int maxIterations = 16); + btPolarDecomposition(btScalar tolerance = btScalar(0.0001), + unsigned int maxIterations = 16); - /** + /** * Decomposes a matrix into orthogonal and symmetric, positive-definite * parts. If the number of iterations returned by this function is equal to * the maximum number of iterations, the algorithm has failed to converge. @@ -38,19 +36,19 @@ class btPolarDecomposition * * @return the number of iterations performed by the algorithm. */ - unsigned int decompose(const btMatrix3x3& a, btMatrix3x3& u, btMatrix3x3& h) const; + unsigned int decompose(const btMatrix3x3& a, btMatrix3x3& u, btMatrix3x3& h) const; - /** + /** * Returns the maximum number of iterations that this algorithm will perform * to achieve convergence. * * @return maximum number of iterations */ - unsigned int maxIterations() const; + unsigned int maxIterations() const; - private: - btScalar m_tolerance; - unsigned int m_maxIterations; +private: + btScalar m_tolerance; + unsigned int m_maxIterations; }; /** @@ -66,7 +64,6 @@ class btPolarDecomposition * * @return the number of iterations performed by the algorithm. */ -unsigned int polarDecompose(const btMatrix3x3& a, btMatrix3x3& u, btMatrix3x3& h); - -#endif // POLARDECOMPOSITION_H +unsigned int polarDecompose(const btMatrix3x3& a, btMatrix3x3& u, btMatrix3x3& h); +#endif // POLARDECOMPOSITION_H diff --git a/src/LinearMath/btPoolAllocator.h b/src/LinearMath/btPoolAllocator.h index efdeda8ff..4e7b49660 100644 --- a/src/LinearMath/btPoolAllocator.h +++ b/src/LinearMath/btPoolAllocator.h @@ -12,7 +12,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef _BT_POOL_ALLOCATOR_H #define _BT_POOL_ALLOCATOR_H @@ -23,38 +22,38 @@ subject to the following restrictions: ///The btPoolAllocator class allows to efficiently allocate a large pool of objects, instead of dynamically allocating them separately. class btPoolAllocator { - int m_elemSize; - int m_maxElements; - int m_freeCount; - void* m_firstFree; - unsigned char* m_pool; - btSpinMutex m_mutex; // only used if BT_THREADSAFE + int m_elemSize; + int m_maxElements; + int m_freeCount; + void* m_firstFree; + unsigned char* m_pool; + btSpinMutex m_mutex; // only used if BT_THREADSAFE public: - btPoolAllocator(int elemSize, int maxElements) - :m_elemSize(elemSize), - m_maxElements(maxElements) + : m_elemSize(elemSize), + m_maxElements(maxElements) { - m_pool = (unsigned char*) btAlignedAlloc( static_cast(m_elemSize*m_maxElements),16); + m_pool = (unsigned char*)btAlignedAlloc(static_cast(m_elemSize * m_maxElements), 16); unsigned char* p = m_pool; - m_firstFree = p; - m_freeCount = m_maxElements; - int count = m_maxElements; - while (--count) { - *(void**)p = (p + m_elemSize); - p += m_elemSize; - } - *(void**)p = 0; - } + m_firstFree = p; + m_freeCount = m_maxElements; + int count = m_maxElements; + while (--count) + { + *(void**)p = (p + m_elemSize); + p += m_elemSize; + } + *(void**)p = 0; + } ~btPoolAllocator() { - btAlignedFree( m_pool); + btAlignedFree(m_pool); } - int getFreeCount() const + int getFreeCount() const { return m_freeCount; } @@ -69,26 +68,27 @@ public: return m_maxElements; } - void* allocate(int size) + void* allocate(int size) { // release mode fix (void)size; - btMutexLock(&m_mutex); - btAssert(!size || size<=m_elemSize); + btMutexLock(&m_mutex); + btAssert(!size || size <= m_elemSize); //btAssert(m_freeCount>0); // should return null if all full - void* result = m_firstFree; - if (NULL != m_firstFree) - { - m_firstFree = *(void**)m_firstFree; - --m_freeCount; - } - btMutexUnlock(&m_mutex); - return result; + void* result = m_firstFree; + if (NULL != m_firstFree) + { + m_firstFree = *(void**)m_firstFree; + --m_freeCount; + } + btMutexUnlock(&m_mutex); + return result; } bool validPtr(void* ptr) { - if (ptr) { + if (ptr) + { if (((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize)) { return true; @@ -97,34 +97,34 @@ public: return false; } - void freeMemory(void* ptr) + void freeMemory(void* ptr) { - if (ptr) { - btAssert((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize); + if (ptr) + { + btAssert((unsigned char*)ptr >= m_pool && (unsigned char*)ptr < m_pool + m_maxElements * m_elemSize); - btMutexLock(&m_mutex); - *(void**)ptr = m_firstFree; - m_firstFree = ptr; - ++m_freeCount; - btMutexUnlock(&m_mutex); - } + btMutexLock(&m_mutex); + *(void**)ptr = m_firstFree; + m_firstFree = ptr; + ++m_freeCount; + btMutexUnlock(&m_mutex); + } } - int getElementSize() const + int getElementSize() const { return m_elemSize; } - unsigned char* getPoolAddress() + unsigned char* getPoolAddress() { return m_pool; } - const unsigned char* getPoolAddress() const + const unsigned char* getPoolAddress() const { return m_pool; } - }; -#endif //_BT_POOL_ALLOCATOR_H +#endif //_BT_POOL_ALLOCATOR_H diff --git a/src/LinearMath/btQuadWord.h b/src/LinearMath/btQuadWord.h index fcfb3be44..ab2d3175a 100644 --- a/src/LinearMath/btQuadWord.h +++ b/src/LinearMath/btQuadWord.h @@ -12,18 +12,13 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef BT_SIMD_QUADWORD_H #define BT_SIMD_QUADWORD_H #include "btScalar.h" #include "btMinMax.h" - - - - -#if defined (__CELLOS_LV2) && defined (__SPU__) +#if defined(__CELLOS_LV2) && defined(__SPU__) #include #endif @@ -31,51 +26,53 @@ subject to the following restrictions: * Some issues under PS3 Linux with IBM 2.1 SDK, gcc compiler prevent from using aligned quadword. */ #ifndef USE_LIBSPE2 -ATTRIBUTE_ALIGNED16(class) btQuadWord +ATTRIBUTE_ALIGNED16(class) +btQuadWord #else class btQuadWord #endif { protected: - -#if defined (__SPU__) && defined (__CELLOS_LV2__) +#if defined(__SPU__) && defined(__CELLOS_LV2__) union { vec_float4 mVec128; - btScalar m_floats[4]; + btScalar m_floats[4]; }; + public: - vec_float4 get128() const + vec_float4 get128() const { return mVec128; } -protected: -#else //__CELLOS_LV2__ __SPU__ -#if defined(BT_USE_SSE) || defined(BT_USE_NEON) +protected: +#else //__CELLOS_LV2__ __SPU__ + +#if defined(BT_USE_SSE) || defined(BT_USE_NEON) union { btSimdFloat4 mVec128; - btScalar m_floats[4]; + btScalar m_floats[4]; }; + public: - SIMD_FORCE_INLINE btSimdFloat4 get128() const + SIMD_FORCE_INLINE btSimdFloat4 get128() const { return mVec128; } - SIMD_FORCE_INLINE void set128(btSimdFloat4 v128) + SIMD_FORCE_INLINE void set128(btSimdFloat4 v128) { mVec128 = v128; } #else - btScalar m_floats[4]; -#endif // BT_USE_SSE + btScalar m_floats[4]; +#endif // BT_USE_SSE -#endif //__CELLOS_LV2__ __SPU__ +#endif //__CELLOS_LV2__ __SPU__ - public: - +public: #if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) || defined(BT_USE_NEON) - // Set Vector + // Set Vector SIMD_FORCE_INLINE btQuadWord(const btSimdFloat4 vec) { mVec128 = vec; @@ -88,157 +85,154 @@ public: } // Assignment Operator - SIMD_FORCE_INLINE btQuadWord& - operator=(const btQuadWord& v) + SIMD_FORCE_INLINE btQuadWord& + operator=(const btQuadWord& v) { mVec128 = v.mVec128; - + return *this; } - + #endif - /**@brief Return the x value */ - SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; } - /**@brief Return the y value */ - SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; } - /**@brief Return the z value */ - SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; } - /**@brief Set the x value */ - SIMD_FORCE_INLINE void setX(btScalar _x) { m_floats[0] = _x;}; - /**@brief Set the y value */ - SIMD_FORCE_INLINE void setY(btScalar _y) { m_floats[1] = _y;}; - /**@brief Set the z value */ - SIMD_FORCE_INLINE void setZ(btScalar _z) { m_floats[2] = _z;}; - /**@brief Set the w value */ - SIMD_FORCE_INLINE void setW(btScalar _w) { m_floats[3] = _w;}; - /**@brief Return the x value */ - SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; } - /**@brief Return the y value */ - SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; } - /**@brief Return the z value */ - SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; } - /**@brief Return the w value */ - SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; } + /**@brief Return the x value */ + SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; } + /**@brief Return the y value */ + SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; } + /**@brief Return the z value */ + SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; } + /**@brief Set the x value */ + SIMD_FORCE_INLINE void setX(btScalar _x) { m_floats[0] = _x; }; + /**@brief Set the y value */ + SIMD_FORCE_INLINE void setY(btScalar _y) { m_floats[1] = _y; }; + /**@brief Set the z value */ + SIMD_FORCE_INLINE void setZ(btScalar _z) { m_floats[2] = _z; }; + /**@brief Set the w value */ + SIMD_FORCE_INLINE void setW(btScalar _w) { m_floats[3] = _w; }; + /**@brief Return the x value */ + SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; } + /**@brief Return the y value */ + SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; } + /**@brief Return the z value */ + SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; } + /**@brief Return the w value */ + SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; } - //SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_floats[0])[i]; } + //SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_floats[0])[i]; } //SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_floats[0])[i]; } ///operator btScalar*() replaces operator[], using implicit conversion. We added operator != and operator == to avoid pointer comparisons. - SIMD_FORCE_INLINE operator btScalar *() { return &m_floats[0]; } - SIMD_FORCE_INLINE operator const btScalar *() const { return &m_floats[0]; } + SIMD_FORCE_INLINE operator btScalar*() { return &m_floats[0]; } + SIMD_FORCE_INLINE operator const btScalar*() const { return &m_floats[0]; } - SIMD_FORCE_INLINE bool operator==(const btQuadWord& other) const + SIMD_FORCE_INLINE bool operator==(const btQuadWord& other) const { #ifdef BT_USE_SSE - return (0xf == _mm_movemask_ps((__m128)_mm_cmpeq_ps(mVec128, other.mVec128))); -#else - return ((m_floats[3]==other.m_floats[3]) && - (m_floats[2]==other.m_floats[2]) && - (m_floats[1]==other.m_floats[1]) && - (m_floats[0]==other.m_floats[0])); + return (0xf == _mm_movemask_ps((__m128)_mm_cmpeq_ps(mVec128, other.mVec128))); +#else + return ((m_floats[3] == other.m_floats[3]) && + (m_floats[2] == other.m_floats[2]) && + (m_floats[1] == other.m_floats[1]) && + (m_floats[0] == other.m_floats[0])); #endif } - SIMD_FORCE_INLINE bool operator!=(const btQuadWord& other) const + SIMD_FORCE_INLINE bool operator!=(const btQuadWord& other) const { return !(*this == other); } - /**@brief Set x,y,z and zero w + /**@brief Set x,y,z and zero w * @param x Value of x * @param y Value of y * @param z Value of z */ - SIMD_FORCE_INLINE void setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z) - { - m_floats[0]=_x; - m_floats[1]=_y; - m_floats[2]=_z; - m_floats[3] = 0.f; - } + SIMD_FORCE_INLINE void setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z) + { + m_floats[0] = _x; + m_floats[1] = _y; + m_floats[2] = _z; + m_floats[3] = 0.f; + } -/* void getValue(btScalar *m) const + /* void getValue(btScalar *m) const { m[0] = m_floats[0]; m[1] = m_floats[1]; m[2] = m_floats[2]; } */ -/**@brief Set the values + /**@brief Set the values * @param x Value of x * @param y Value of y * @param z Value of z * @param w Value of w */ - SIMD_FORCE_INLINE void setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z,const btScalar& _w) - { - m_floats[0]=_x; - m_floats[1]=_y; - m_floats[2]=_z; - m_floats[3]=_w; - } - /**@brief No initialization constructor */ - SIMD_FORCE_INLINE btQuadWord() - // :m_floats[0](btScalar(0.)),m_floats[1](btScalar(0.)),m_floats[2](btScalar(0.)),m_floats[3](btScalar(0.)) - { - } - - /**@brief Three argument constructor (zeros w) + SIMD_FORCE_INLINE void setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z, const btScalar& _w) + { + m_floats[0] = _x; + m_floats[1] = _y; + m_floats[2] = _z; + m_floats[3] = _w; + } + /**@brief No initialization constructor */ + SIMD_FORCE_INLINE btQuadWord() + // :m_floats[0](btScalar(0.)),m_floats[1](btScalar(0.)),m_floats[2](btScalar(0.)),m_floats[3](btScalar(0.)) + { + } + + /**@brief Three argument constructor (zeros w) * @param x Value of x * @param y Value of y * @param z Value of z */ - SIMD_FORCE_INLINE btQuadWord(const btScalar& _x, const btScalar& _y, const btScalar& _z) - { - m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = 0.0f; - } + SIMD_FORCE_INLINE btQuadWord(const btScalar& _x, const btScalar& _y, const btScalar& _z) + { + m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = 0.0f; + } -/**@brief Initializing constructor + /**@brief Initializing constructor * @param x Value of x * @param y Value of y * @param z Value of z * @param w Value of w */ - SIMD_FORCE_INLINE btQuadWord(const btScalar& _x, const btScalar& _y, const btScalar& _z,const btScalar& _w) - { - m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = _w; - } + SIMD_FORCE_INLINE btQuadWord(const btScalar& _x, const btScalar& _y, const btScalar& _z, const btScalar& _w) + { + m_floats[0] = _x, m_floats[1] = _y, m_floats[2] = _z, m_floats[3] = _w; + } - /**@brief Set each element to the max of the current values and the values of another btQuadWord + /**@brief Set each element to the max of the current values and the values of another btQuadWord * @param other The other btQuadWord to compare with */ - SIMD_FORCE_INLINE void setMax(const btQuadWord& other) - { - #ifdef BT_USE_SSE - mVec128 = _mm_max_ps(mVec128, other.mVec128); - #elif defined(BT_USE_NEON) - mVec128 = vmaxq_f32(mVec128, other.mVec128); - #else - btSetMax(m_floats[0], other.m_floats[0]); - btSetMax(m_floats[1], other.m_floats[1]); - btSetMax(m_floats[2], other.m_floats[2]); - btSetMax(m_floats[3], other.m_floats[3]); - #endif - } - /**@brief Set each element to the min of the current values and the values of another btQuadWord + SIMD_FORCE_INLINE void setMax(const btQuadWord& other) + { +#ifdef BT_USE_SSE + mVec128 = _mm_max_ps(mVec128, other.mVec128); +#elif defined(BT_USE_NEON) + mVec128 = vmaxq_f32(mVec128, other.mVec128); +#else + btSetMax(m_floats[0], other.m_floats[0]); + btSetMax(m_floats[1], other.m_floats[1]); + btSetMax(m_floats[2], other.m_floats[2]); + btSetMax(m_floats[3], other.m_floats[3]); +#endif + } + /**@brief Set each element to the min of the current values and the values of another btQuadWord * @param other The other btQuadWord to compare with */ - SIMD_FORCE_INLINE void setMin(const btQuadWord& other) - { - #ifdef BT_USE_SSE - mVec128 = _mm_min_ps(mVec128, other.mVec128); - #elif defined(BT_USE_NEON) - mVec128 = vminq_f32(mVec128, other.mVec128); - #else - btSetMin(m_floats[0], other.m_floats[0]); - btSetMin(m_floats[1], other.m_floats[1]); - btSetMin(m_floats[2], other.m_floats[2]); - btSetMin(m_floats[3], other.m_floats[3]); - #endif - } - - - + SIMD_FORCE_INLINE void setMin(const btQuadWord& other) + { +#ifdef BT_USE_SSE + mVec128 = _mm_min_ps(mVec128, other.mVec128); +#elif defined(BT_USE_NEON) + mVec128 = vminq_f32(mVec128, other.mVec128); +#else + btSetMin(m_floats[0], other.m_floats[0]); + btSetMin(m_floats[1], other.m_floats[1]); + btSetMin(m_floats[2], other.m_floats[2]); + btSetMin(m_floats[3], other.m_floats[3]); +#endif + } }; -#endif //BT_SIMD_QUADWORD_H +#endif //BT_SIMD_QUADWORD_H diff --git a/src/LinearMath/btQuaternion.h b/src/LinearMath/btQuaternion.h index a98fec7bc..53e8169b8 100644 --- a/src/LinearMath/btQuaternion.h +++ b/src/LinearMath/btQuaternion.h @@ -12,25 +12,19 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #ifndef BT_SIMD__QUATERNION_H_ #define BT_SIMD__QUATERNION_H_ - #include "btVector3.h" #include "btQuadWord.h" - #ifdef BT_USE_DOUBLE_PRECISION #define btQuaternionData btQuaternionDoubleData #define btQuaternionDataName "btQuaternionDoubleData" #else #define btQuaternionData btQuaternionFloatData #define btQuaternionDataName "btQuaternionFloatData" -#endif //BT_USE_DOUBLE_PRECISION - - +#endif //BT_USE_DOUBLE_PRECISION #ifdef BT_USE_SSE @@ -39,7 +33,7 @@ subject to the following restrictions: #endif -#if defined(BT_USE_SSE) +#if defined(BT_USE_SSE) #define vQInv (_mm_set_ps(+0.0f, -0.0f, -0.0f, -0.0f)) #define vPPPM (_mm_set_ps(-0.0f, +0.0f, +0.0f, +0.0f)) @@ -52,13 +46,14 @@ const btSimdFloat4 ATTRIBUTE_ALIGNED16(vPPPM) = {+0.0f, +0.0f, +0.0f, -0.0f}; #endif /**@brief The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatrix3x3, btVector3 and btTransform. */ -class btQuaternion : public btQuadWord { +class btQuaternion : public btQuadWord +{ public: - /**@brief No initialization constructor */ + /**@brief No initialization constructor */ btQuaternion() {} -#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE))|| defined(BT_USE_NEON) - // Set Vector +#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) || defined(BT_USE_NEON) + // Set Vector SIMD_FORCE_INLINE btQuaternion(const btSimdFloat4 vec) { mVec128 = vec; @@ -71,42 +66,43 @@ public: } // Assignment Operator - SIMD_FORCE_INLINE btQuaternion& - operator=(const btQuaternion& v) + SIMD_FORCE_INLINE btQuaternion& + operator=(const btQuaternion& v) { mVec128 = v.mVec128; - + return *this; } - + #endif // template // explicit Quaternion(const btScalar *v) : Tuple4(v) {} - /**@brief Constructor from scalars */ - btQuaternion(const btScalar& _x, const btScalar& _y, const btScalar& _z, const btScalar& _w) - : btQuadWord(_x, _y, _z, _w) - {} - /**@brief Axis angle Constructor + /**@brief Constructor from scalars */ + btQuaternion(const btScalar& _x, const btScalar& _y, const btScalar& _z, const btScalar& _w) + : btQuadWord(_x, _y, _z, _w) + { + } + /**@brief Axis angle Constructor * @param axis The axis which the rotation is around * @param angle The magnitude of the rotation around the angle (Radians) */ - btQuaternion(const btVector3& _axis, const btScalar& _angle) - { - setRotation(_axis, _angle); + btQuaternion(const btVector3& _axis, const btScalar& _angle) + { + setRotation(_axis, _angle); } - /**@brief Constructor from Euler angles + /**@brief Constructor from Euler angles * @param yaw Angle around Y unless BT_EULER_DEFAULT_ZYX defined then Z * @param pitch Angle around X unless BT_EULER_DEFAULT_ZYX defined then Y * @param roll Angle around Z unless BT_EULER_DEFAULT_ZYX defined then X */ btQuaternion(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) - { + { #ifndef BT_EULER_DEFAULT_ZYX - setEuler(yaw, pitch, roll); + setEuler(yaw, pitch, roll); #else - setEulerZYX(yaw, pitch, roll); -#endif + setEulerZYX(yaw, pitch, roll); +#endif } - /**@brief Set the rotation using axis angle notation + /**@brief Set the rotation using axis angle notation * @param axis The axis around which to rotate * @param angle The magnitude of the rotation in Radians */ void setRotation(const btVector3& axis, const btScalar& _angle) @@ -114,18 +110,18 @@ public: btScalar d = axis.length(); btAssert(d != btScalar(0.0)); btScalar s = btSin(_angle * btScalar(0.5)) / d; - setValue(axis.x() * s, axis.y() * s, axis.z() * s, - btCos(_angle * btScalar(0.5))); + setValue(axis.x() * s, axis.y() * s, axis.z() * s, + btCos(_angle * btScalar(0.5))); } - /**@brief Set the quaternion using Euler angles + /**@brief Set the quaternion using Euler angles * @param yaw Angle around Y * @param pitch Angle around X * @param roll Angle around Z */ void setEuler(const btScalar& yaw, const btScalar& pitch, const btScalar& roll) { - btScalar halfYaw = btScalar(yaw) * btScalar(0.5); - btScalar halfPitch = btScalar(pitch) * btScalar(0.5); - btScalar halfRoll = btScalar(roll) * btScalar(0.5); + btScalar halfYaw = btScalar(yaw) * btScalar(0.5); + btScalar halfPitch = btScalar(pitch) * btScalar(0.5); + btScalar halfRoll = btScalar(roll) * btScalar(0.5); btScalar cosYaw = btCos(halfYaw); btScalar sinYaw = btSin(halfYaw); btScalar cosPitch = btCos(halfPitch); @@ -133,32 +129,32 @@ public: btScalar cosRoll = btCos(halfRoll); btScalar sinRoll = btSin(halfRoll); setValue(cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, - cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, - sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, - cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); + cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, + sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, + cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); } - /**@brief Set the quaternion using euler angles + /**@brief Set the quaternion using euler angles * @param yaw Angle around Z * @param pitch Angle around Y * @param roll Angle around X */ void setEulerZYX(const btScalar& yawZ, const btScalar& pitchY, const btScalar& rollX) { - btScalar halfYaw = btScalar(yawZ) * btScalar(0.5); - btScalar halfPitch = btScalar(pitchY) * btScalar(0.5); - btScalar halfRoll = btScalar(rollX) * btScalar(0.5); + btScalar halfYaw = btScalar(yawZ) * btScalar(0.5); + btScalar halfPitch = btScalar(pitchY) * btScalar(0.5); + btScalar halfRoll = btScalar(rollX) * btScalar(0.5); btScalar cosYaw = btCos(halfYaw); btScalar sinYaw = btSin(halfYaw); btScalar cosPitch = btCos(halfPitch); btScalar sinPitch = btSin(halfPitch); btScalar cosRoll = btCos(halfRoll); btScalar sinRoll = btSin(halfRoll); - setValue(sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, //x - cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, //y - cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, //z - cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); //formerly yzx + setValue(sinRoll * cosPitch * cosYaw - cosRoll * sinPitch * sinYaw, //x + cosRoll * sinPitch * cosYaw + sinRoll * cosPitch * sinYaw, //y + cosRoll * cosPitch * sinYaw - sinRoll * sinPitch * cosYaw, //z + cosRoll * cosPitch * cosYaw + sinRoll * sinPitch * sinYaw); //formerly yzx } - /**@brief Get the euler angles from this quaternion + /**@brief Get the euler angles from this quaternion * @param yaw Angle around Z * @param pitch Angle around Y * @param roll Angle around X */ @@ -173,23 +169,25 @@ public: sqy = m_floats[1] * m_floats[1]; sqz = m_floats[2] * m_floats[2]; squ = m_floats[3] * m_floats[3]; - sarg = btScalar(-2.) * (m_floats[0] * m_floats[2] - m_floats[3] * m_floats[1]); - + sarg = btScalar(-2.) * (m_floats[0] * m_floats[2] - m_floats[3] * m_floats[1]); + // If the pitch angle is PI/2 or -PI/2, we can only compute // the sum roll + yaw. However, any combination that gives // the right sum will produce the correct orientation, so we // set rollX = 0 and compute yawZ. if (sarg <= -btScalar(0.99999)) { - pitchY = btScalar(-0.5)*SIMD_PI; - rollX = 0; - yawZ = btScalar(2) * btAtan2(m_floats[0],-m_floats[1]); - } else if (sarg >= btScalar(0.99999)) + pitchY = btScalar(-0.5) * SIMD_PI; + rollX = 0; + yawZ = btScalar(2) * btAtan2(m_floats[0], -m_floats[1]); + } + else if (sarg >= btScalar(0.99999)) { - pitchY = btScalar(0.5)*SIMD_PI; - rollX = 0; - yawZ = btScalar(2) * btAtan2(-m_floats[0], m_floats[1]); - } else + pitchY = btScalar(0.5) * SIMD_PI; + rollX = 0; + yawZ = btScalar(2) * btAtan2(-m_floats[0], m_floats[1]); + } + else { pitchY = btAsin(sarg); rollX = btAtan2(2 * (m_floats[1] * m_floats[2] + m_floats[3] * m_floats[0]), squ - sqx - sqy + sqz); @@ -197,178 +195,178 @@ public: } } - /**@brief Add two quaternions + /**@brief Add two quaternions * @param q The quaternion to add to this one */ - SIMD_FORCE_INLINE btQuaternion& operator+=(const btQuaternion& q) + SIMD_FORCE_INLINE btQuaternion& operator+=(const btQuaternion& q) { -#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) mVec128 = _mm_add_ps(mVec128, q.mVec128); #elif defined(BT_USE_NEON) mVec128 = vaddq_f32(mVec128, q.mVec128); -#else - m_floats[0] += q.x(); - m_floats[1] += q.y(); - m_floats[2] += q.z(); - m_floats[3] += q.m_floats[3]; +#else + m_floats[0] += q.x(); + m_floats[1] += q.y(); + m_floats[2] += q.z(); + m_floats[3] += q.m_floats[3]; #endif return *this; } - /**@brief Subtract out a quaternion + /**@brief Subtract out a quaternion * @param q The quaternion to subtract from this one */ - btQuaternion& operator-=(const btQuaternion& q) + btQuaternion& operator-=(const btQuaternion& q) { -#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) mVec128 = _mm_sub_ps(mVec128, q.mVec128); #elif defined(BT_USE_NEON) mVec128 = vsubq_f32(mVec128, q.mVec128); -#else - m_floats[0] -= q.x(); - m_floats[1] -= q.y(); - m_floats[2] -= q.z(); - m_floats[3] -= q.m_floats[3]; +#else + m_floats[0] -= q.x(); + m_floats[1] -= q.y(); + m_floats[2] -= q.z(); + m_floats[3] -= q.m_floats[3]; #endif - return *this; + return *this; } - /**@brief Scale this quaternion + /**@brief Scale this quaternion * @param s The scalar to scale by */ btQuaternion& operator*=(const btScalar& s) { -#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) - __m128 vs = _mm_load_ss(&s); // (S 0 0 0) - vs = bt_pshufd_ps(vs, 0); // (S S S S) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) + __m128 vs = _mm_load_ss(&s); // (S 0 0 0) + vs = bt_pshufd_ps(vs, 0); // (S S S S) mVec128 = _mm_mul_ps(mVec128, vs); #elif defined(BT_USE_NEON) mVec128 = vmulq_n_f32(mVec128, s); #else - m_floats[0] *= s; - m_floats[1] *= s; - m_floats[2] *= s; - m_floats[3] *= s; + m_floats[0] *= s; + m_floats[1] *= s; + m_floats[2] *= s; + m_floats[3] *= s; #endif return *this; } - /**@brief Multiply this quaternion by q on the right + /**@brief Multiply this quaternion by q on the right * @param q The other quaternion * Equivilant to this = this * q */ btQuaternion& operator*=(const btQuaternion& q) { -#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) __m128 vQ2 = q.get128(); - - __m128 A1 = bt_pshufd_ps(mVec128, BT_SHUFFLE(0,1,2,0)); - __m128 B1 = bt_pshufd_ps(vQ2, BT_SHUFFLE(3,3,3,0)); - + + __m128 A1 = bt_pshufd_ps(mVec128, BT_SHUFFLE(0, 1, 2, 0)); + __m128 B1 = bt_pshufd_ps(vQ2, BT_SHUFFLE(3, 3, 3, 0)); + A1 = A1 * B1; - - __m128 A2 = bt_pshufd_ps(mVec128, BT_SHUFFLE(1,2,0,1)); - __m128 B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(2,0,1,1)); - + + __m128 A2 = bt_pshufd_ps(mVec128, BT_SHUFFLE(1, 2, 0, 1)); + __m128 B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(2, 0, 1, 1)); + A2 = A2 * B2; - - B1 = bt_pshufd_ps(mVec128, BT_SHUFFLE(2,0,1,2)); - B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(1,2,0,2)); - - B1 = B1 * B2; // A3 *= B3 - - mVec128 = bt_splat_ps(mVec128, 3); // A0 - mVec128 = mVec128 * vQ2; // A0 * B0 - - A1 = A1 + A2; // AB12 - mVec128 = mVec128 - B1; // AB03 = AB0 - AB3 - A1 = _mm_xor_ps(A1, vPPPM); // change sign of the last element - mVec128 = mVec128+ A1; // AB03 + AB12 -#elif defined(BT_USE_NEON) + B1 = bt_pshufd_ps(mVec128, BT_SHUFFLE(2, 0, 1, 2)); + B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(1, 2, 0, 2)); - float32x4_t vQ1 = mVec128; - float32x4_t vQ2 = q.get128(); - float32x4_t A0, A1, B1, A2, B2, A3, B3; - float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz; - - { - float32x2x2_t tmp; - tmp = vtrn_f32( vget_high_f32(vQ1), vget_low_f32(vQ1) ); // {z x}, {w y} - vQ1zx = tmp.val[0]; + B1 = B1 * B2; // A3 *= B3 - tmp = vtrn_f32( vget_high_f32(vQ2), vget_low_f32(vQ2) ); // {z x}, {w y} - vQ2zx = tmp.val[0]; - } - vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1); + mVec128 = bt_splat_ps(mVec128, 3); // A0 + mVec128 = mVec128 * vQ2; // A0 * B0 - vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1); + A1 = A1 + A2; // AB12 + mVec128 = mVec128 - B1; // AB03 = AB0 - AB3 + A1 = _mm_xor_ps(A1, vPPPM); // change sign of the last element + mVec128 = mVec128 + A1; // AB03 + AB12 - vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1); - vQ2xz = vext_f32(vQ2zx, vQ2zx, 1); +#elif defined(BT_USE_NEON) - A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx); // X Y z x - B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx); // W W W X + float32x4_t vQ1 = mVec128; + float32x4_t vQ2 = q.get128(); + float32x4_t A0, A1, B1, A2, B2, A3, B3; + float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz; - A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1)); - B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1)); + { + float32x2x2_t tmp; + tmp = vtrn_f32(vget_high_f32(vQ1), vget_low_f32(vQ1)); // {z x}, {w y} + vQ1zx = tmp.val[0]; - A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z - B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z + tmp = vtrn_f32(vget_high_f32(vQ2), vget_low_f32(vQ2)); // {z x}, {w y} + vQ2zx = tmp.val[0]; + } + vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1); - A1 = vmulq_f32(A1, B1); - A2 = vmulq_f32(A2, B2); - A3 = vmulq_f32(A3, B3); // A3 *= B3 - A0 = vmulq_lane_f32(vQ2, vget_high_f32(vQ1), 1); // A0 * B0 + vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1); - A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2 - A0 = vsubq_f32(A0, A3); // AB03 = AB0 - AB3 - - // change the sign of the last element - A1 = (btSimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)vPPPM); - A0 = vaddq_f32(A0, A1); // AB03 + AB12 - - mVec128 = A0; + vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1); + vQ2xz = vext_f32(vQ2zx, vQ2zx, 1); + + A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx); // X Y z x + B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx); // W W W X + + A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1)); + B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1)); + + A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z + B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z + + A1 = vmulq_f32(A1, B1); + A2 = vmulq_f32(A2, B2); + A3 = vmulq_f32(A3, B3); // A3 *= B3 + A0 = vmulq_lane_f32(vQ2, vget_high_f32(vQ1), 1); // A0 * B0 + + A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2 + A0 = vsubq_f32(A0, A3); // AB03 = AB0 - AB3 + + // change the sign of the last element + A1 = (btSimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)vPPPM); + A0 = vaddq_f32(A0, A1); // AB03 + AB12 + + mVec128 = A0; #else setValue( - m_floats[3] * q.x() + m_floats[0] * q.m_floats[3] + m_floats[1] * q.z() - m_floats[2] * q.y(), + m_floats[3] * q.x() + m_floats[0] * q.m_floats[3] + m_floats[1] * q.z() - m_floats[2] * q.y(), m_floats[3] * q.y() + m_floats[1] * q.m_floats[3] + m_floats[2] * q.x() - m_floats[0] * q.z(), m_floats[3] * q.z() + m_floats[2] * q.m_floats[3] + m_floats[0] * q.y() - m_floats[1] * q.x(), m_floats[3] * q.m_floats[3] - m_floats[0] * q.x() - m_floats[1] * q.y() - m_floats[2] * q.z()); #endif return *this; } - /**@brief Return the dot product between this quaternion and another + /**@brief Return the dot product between this quaternion and another * @param q The other quaternion */ btScalar dot(const btQuaternion& q) const { -#if defined BT_USE_SIMD_VECTOR3 && defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) - __m128 vd; - +#if defined BT_USE_SIMD_VECTOR3 && defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) + __m128 vd; + vd = _mm_mul_ps(mVec128, q.mVec128); - - __m128 t = _mm_movehl_ps(vd, vd); + + __m128 t = _mm_movehl_ps(vd, vd); vd = _mm_add_ps(vd, t); t = _mm_shuffle_ps(vd, vd, 0x55); vd = _mm_add_ss(vd, t); - - return _mm_cvtss_f32(vd); + + return _mm_cvtss_f32(vd); #elif defined(BT_USE_NEON) float32x4_t vd = vmulq_f32(mVec128, q.mVec128); - float32x2_t x = vpadd_f32(vget_low_f32(vd), vget_high_f32(vd)); + float32x2_t x = vpadd_f32(vget_low_f32(vd), vget_high_f32(vd)); x = vpadd_f32(x, x); return vget_lane_f32(x, 0); -#else - return m_floats[0] * q.x() + - m_floats[1] * q.y() + - m_floats[2] * q.z() + - m_floats[3] * q.m_floats[3]; +#else + return m_floats[0] * q.x() + + m_floats[1] * q.y() + + m_floats[2] * q.z() + + m_floats[3] * q.m_floats[3]; #endif } - /**@brief Return the length squared of the quaternion */ + /**@brief Return the length squared of the quaternion */ btScalar length2() const { return dot(*this); } - /**@brief Return the length of the quaternion */ + /**@brief Return the length of the quaternion */ btScalar length() const { return btSqrt(length2()); @@ -376,46 +374,46 @@ public: btQuaternion& safeNormalize() { btScalar l2 = length2(); - if (l2>SIMD_EPSILON) + if (l2 > SIMD_EPSILON) { normalize(); } return *this; } - /**@brief Normalize the quaternion + /**@brief Normalize the quaternion * Such that x^2 + y^2 + z^2 +w^2 = 1 */ - btQuaternion& normalize() + btQuaternion& normalize() { -#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) - __m128 vd; - +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) + __m128 vd; + vd = _mm_mul_ps(mVec128, mVec128); - - __m128 t = _mm_movehl_ps(vd, vd); + + __m128 t = _mm_movehl_ps(vd, vd); vd = _mm_add_ps(vd, t); t = _mm_shuffle_ps(vd, vd, 0x55); vd = _mm_add_ss(vd, t); vd = _mm_sqrt_ss(vd); vd = _mm_div_ss(vOnes, vd); - vd = bt_pshufd_ps(vd, 0); // splat + vd = bt_pshufd_ps(vd, 0); // splat mVec128 = _mm_mul_ps(mVec128, vd); - + return *this; -#else +#else return *this /= length(); #endif } - /**@brief Return a scaled version of this quaternion + /**@brief Return a scaled version of this quaternion * @param s The scale factor */ SIMD_FORCE_INLINE btQuaternion operator*(const btScalar& s) const { -#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) - __m128 vs = _mm_load_ss(&s); // (S 0 0 0) - vs = bt_pshufd_ps(vs, 0x00); // (S S S S) - +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) + __m128 vs = _mm_load_ss(&s); // (S 0 0 0) + vs = bt_pshufd_ps(vs, 0x00); // (S S S S) + return btQuaternion(_mm_mul_ps(mVec128, vs)); #elif defined(BT_USE_NEON) return btQuaternion(vmulq_n_f32(mVec128, s)); @@ -424,7 +422,7 @@ public: #endif } - /**@brief Return an inversely scaled versionof this quaternion + /**@brief Return an inversely scaled versionof this quaternion * @param s The inverse scale factor */ btQuaternion operator/(const btScalar& s) const { @@ -432,49 +430,49 @@ public: return *this * (btScalar(1.0) / s); } - /**@brief Inversely scale this quaternion + /**@brief Inversely scale this quaternion * @param s The scale factor */ - btQuaternion& operator/=(const btScalar& s) + btQuaternion& operator/=(const btScalar& s) { btAssert(s != btScalar(0.0)); return *this *= btScalar(1.0) / s; } - /**@brief Return a normalized version of this quaternion */ - btQuaternion normalized() const + /**@brief Return a normalized version of this quaternion */ + btQuaternion normalized() const { return *this / length(); - } + } /**@brief Return the ***half*** angle between this quaternion and the other * @param q The other quaternion */ - btScalar angle(const btQuaternion& q) const + btScalar angle(const btQuaternion& q) const { btScalar s = btSqrt(length2() * q.length2()); btAssert(s != btScalar(0.0)); return btAcos(dot(q) / s); } - + /**@brief Return the angle between this quaternion and the other along the shortest path * @param q The other quaternion */ - btScalar angleShortestPath(const btQuaternion& q) const + btScalar angleShortestPath(const btQuaternion& q) const { btScalar s = btSqrt(length2() * q.length2()); btAssert(s != btScalar(0.0)); - if (dot(q) < 0) // Take care of long angle case see http://en.wikipedia.org/wiki/Slerp + if (dot(q) < 0) // Take care of long angle case see http://en.wikipedia.org/wiki/Slerp return btAcos(dot(-q) / s) * btScalar(2.0); - else + else return btAcos(dot(q) / s) * btScalar(2.0); } /**@brief Return the angle [0, 2Pi] of rotation represented by this quaternion */ - btScalar getAngle() const + btScalar getAngle() const { btScalar s = btScalar(2.) * btAcos(m_floats[3]); return s; } /**@brief Return the angle [0, Pi] of rotation represented by this quaternion along the shortest path */ - btScalar getAngleShortestPath() const + btScalar getAngleShortestPath() const { btScalar s; if (m_floats[3] >= 0) @@ -484,120 +482,117 @@ public: return s; } - /**@brief Return the axis of the rotation represented by this quaternion */ btVector3 getAxis() const { - btScalar s_squared = 1.f-m_floats[3]*m_floats[3]; - - if (s_squared < btScalar(10.) * SIMD_EPSILON) //Check for divide by zero - return btVector3(1.0, 0.0, 0.0); // Arbitrary - btScalar s = 1.f/btSqrt(s_squared); + btScalar s_squared = 1.f - m_floats[3] * m_floats[3]; + + if (s_squared < btScalar(10.) * SIMD_EPSILON) //Check for divide by zero + return btVector3(1.0, 0.0, 0.0); // Arbitrary + btScalar s = 1.f / btSqrt(s_squared); return btVector3(m_floats[0] * s, m_floats[1] * s, m_floats[2] * s); } /**@brief Return the inverse of this quaternion */ btQuaternion inverse() const { -#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) return btQuaternion(_mm_xor_ps(mVec128, vQInv)); #elif defined(BT_USE_NEON) - return btQuaternion((btSimdFloat4)veorq_s32((int32x4_t)mVec128, (int32x4_t)vQInv)); -#else + return btQuaternion((btSimdFloat4)veorq_s32((int32x4_t)mVec128, (int32x4_t)vQInv)); +#else return btQuaternion(-m_floats[0], -m_floats[1], -m_floats[2], m_floats[3]); #endif } - /**@brief Return the sum of this quaternion and the other + /**@brief Return the sum of this quaternion and the other * @param q2 The other quaternion */ SIMD_FORCE_INLINE btQuaternion operator+(const btQuaternion& q2) const { -#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) return btQuaternion(_mm_add_ps(mVec128, q2.mVec128)); #elif defined(BT_USE_NEON) - return btQuaternion(vaddq_f32(mVec128, q2.mVec128)); -#else + return btQuaternion(vaddq_f32(mVec128, q2.mVec128)); +#else const btQuaternion& q1 = *this; return btQuaternion(q1.x() + q2.x(), q1.y() + q2.y(), q1.z() + q2.z(), q1.m_floats[3] + q2.m_floats[3]); #endif } - /**@brief Return the difference between this quaternion and the other + /**@brief Return the difference between this quaternion and the other * @param q2 The other quaternion */ SIMD_FORCE_INLINE btQuaternion operator-(const btQuaternion& q2) const { -#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) return btQuaternion(_mm_sub_ps(mVec128, q2.mVec128)); #elif defined(BT_USE_NEON) - return btQuaternion(vsubq_f32(mVec128, q2.mVec128)); -#else + return btQuaternion(vsubq_f32(mVec128, q2.mVec128)); +#else const btQuaternion& q1 = *this; return btQuaternion(q1.x() - q2.x(), q1.y() - q2.y(), q1.z() - q2.z(), q1.m_floats[3] - q2.m_floats[3]); #endif } - /**@brief Return the negative of this quaternion + /**@brief Return the negative of this quaternion * This simply negates each element */ SIMD_FORCE_INLINE btQuaternion operator-() const { -#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) return btQuaternion(_mm_xor_ps(mVec128, btvMzeroMask)); #elif defined(BT_USE_NEON) - return btQuaternion((btSimdFloat4)veorq_s32((int32x4_t)mVec128, (int32x4_t)btvMzeroMask) ); -#else + return btQuaternion((btSimdFloat4)veorq_s32((int32x4_t)mVec128, (int32x4_t)btvMzeroMask)); +#else const btQuaternion& q2 = *this; - return btQuaternion( - q2.x(), - q2.y(), - q2.z(), - q2.m_floats[3]); + return btQuaternion(-q2.x(), -q2.y(), -q2.z(), -q2.m_floats[3]); #endif } - /**@todo document this and it's use */ - SIMD_FORCE_INLINE btQuaternion farthest( const btQuaternion& qd) const + /**@todo document this and it's use */ + SIMD_FORCE_INLINE btQuaternion farthest(const btQuaternion& qd) const { - btQuaternion diff,sum; + btQuaternion diff, sum; diff = *this - qd; sum = *this + qd; - if( diff.dot(diff) > sum.dot(sum) ) + if (diff.dot(diff) > sum.dot(sum)) return qd; return (-qd); } /**@todo document this and it's use */ - SIMD_FORCE_INLINE btQuaternion nearest( const btQuaternion& qd) const + SIMD_FORCE_INLINE btQuaternion nearest(const btQuaternion& qd) const { - btQuaternion diff,sum; + btQuaternion diff, sum; diff = *this - qd; sum = *this + qd; - if( diff.dot(diff) < sum.dot(sum) ) + if (diff.dot(diff) < sum.dot(sum)) return qd; return (-qd); } - - /**@brief Return the quaternion which is the result of Spherical Linear Interpolation between this and the other quaternion + /**@brief Return the quaternion which is the result of Spherical Linear Interpolation between this and the other quaternion * @param q The other quaternion to interpolate with * @param t The ratio between this and q to interpolate. If t = 0 the result is this, if t=1 the result is q. * Slerp interpolates assuming constant velocity. */ btQuaternion slerp(const btQuaternion& q, const btScalar& t) const { - const btScalar magnitude = btSqrt(length2() * q.length2()); btAssert(magnitude > btScalar(0)); - + const btScalar product = dot(q) / magnitude; const btScalar absproduct = btFabs(product); - - if(absproduct < btScalar(1.0 - SIMD_EPSILON)) + + if (absproduct < btScalar(1.0 - SIMD_EPSILON)) { // Take care of long angle case see http://en.wikipedia.org/wiki/Slerp const btScalar theta = btAcos(absproduct); const btScalar d = btSin(theta); btAssert(d > btScalar(0)); - + const btScalar sign = (product < 0) ? btScalar(-1) : btScalar(1); const btScalar s0 = btSin((btScalar(1.0) - t) * theta) / d; const btScalar s1 = btSin(sign * t * theta) / d; - + return btQuaternion( (m_floats[0] * s0 + q.x() * s1), (m_floats[1] * s0 + q.y() * s1), @@ -610,314 +605,308 @@ public: } } - static const btQuaternion& getIdentity() + static const btQuaternion& getIdentity() { - static const btQuaternion identityQuat(btScalar(0.),btScalar(0.),btScalar(0.),btScalar(1.)); + static const btQuaternion identityQuat(btScalar(0.), btScalar(0.), btScalar(0.), btScalar(1.)); return identityQuat; } SIMD_FORCE_INLINE const btScalar& getW() const { return m_floats[3]; } - SIMD_FORCE_INLINE void serialize(struct btQuaternionData& dataOut) const; + SIMD_FORCE_INLINE void serialize(struct btQuaternionData& dataOut) const; - SIMD_FORCE_INLINE void deSerialize(const struct btQuaternionFloatData& dataIn); + SIMD_FORCE_INLINE void deSerialize(const struct btQuaternionFloatData& dataIn); - SIMD_FORCE_INLINE void deSerialize(const struct btQuaternionDoubleData& dataIn); + SIMD_FORCE_INLINE void deSerialize(const struct btQuaternionDoubleData& dataIn); - SIMD_FORCE_INLINE void serializeFloat(struct btQuaternionFloatData& dataOut) const; + SIMD_FORCE_INLINE void serializeFloat(struct btQuaternionFloatData& dataOut) const; - SIMD_FORCE_INLINE void deSerializeFloat(const struct btQuaternionFloatData& dataIn); + SIMD_FORCE_INLINE void deSerializeFloat(const struct btQuaternionFloatData& dataIn); - SIMD_FORCE_INLINE void serializeDouble(struct btQuaternionDoubleData& dataOut) const; - - SIMD_FORCE_INLINE void deSerializeDouble(const struct btQuaternionDoubleData& dataIn); + SIMD_FORCE_INLINE void serializeDouble(struct btQuaternionDoubleData& dataOut) const; + SIMD_FORCE_INLINE void deSerializeDouble(const struct btQuaternionDoubleData& dataIn); }; - - - - /**@brief Return the product of two quaternions */ SIMD_FORCE_INLINE btQuaternion -operator*(const btQuaternion& q1, const btQuaternion& q2) +operator*(const btQuaternion& q1, const btQuaternion& q2) { -#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) __m128 vQ1 = q1.get128(); __m128 vQ2 = q2.get128(); __m128 A0, A1, B1, A2, B2; - - A1 = bt_pshufd_ps(vQ1, BT_SHUFFLE(0,1,2,0)); // X Y z x // vtrn - B1 = bt_pshufd_ps(vQ2, BT_SHUFFLE(3,3,3,0)); // W W W X // vdup vext + + A1 = bt_pshufd_ps(vQ1, BT_SHUFFLE(0, 1, 2, 0)); // X Y z x // vtrn + B1 = bt_pshufd_ps(vQ2, BT_SHUFFLE(3, 3, 3, 0)); // W W W X // vdup vext A1 = A1 * B1; - - A2 = bt_pshufd_ps(vQ1, BT_SHUFFLE(1,2,0,1)); // Y Z X Y // vext - B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(2,0,1,1)); // z x Y Y // vtrn vdup + + A2 = bt_pshufd_ps(vQ1, BT_SHUFFLE(1, 2, 0, 1)); // Y Z X Y // vext + B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(2, 0, 1, 1)); // z x Y Y // vtrn vdup A2 = A2 * B2; - B1 = bt_pshufd_ps(vQ1, BT_SHUFFLE(2,0,1,2)); // z x Y Z // vtrn vext - B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(1,2,0,2)); // Y Z x z // vext vtrn - - B1 = B1 * B2; // A3 *= B3 + B1 = bt_pshufd_ps(vQ1, BT_SHUFFLE(2, 0, 1, 2)); // z x Y Z // vtrn vext + B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(1, 2, 0, 2)); // Y Z x z // vext vtrn - A0 = bt_splat_ps(vQ1, 3); // A0 - A0 = A0 * vQ2; // A0 * B0 + B1 = B1 * B2; // A3 *= B3 + + A0 = bt_splat_ps(vQ1, 3); // A0 + A0 = A0 * vQ2; // A0 * B0 + + A1 = A1 + A2; // AB12 + A0 = A0 - B1; // AB03 = AB0 - AB3 + + A1 = _mm_xor_ps(A1, vPPPM); // change sign of the last element + A0 = A0 + A1; // AB03 + AB12 - A1 = A1 + A2; // AB12 - A0 = A0 - B1; // AB03 = AB0 - AB3 - - A1 = _mm_xor_ps(A1, vPPPM); // change sign of the last element - A0 = A0 + A1; // AB03 + AB12 - return btQuaternion(A0); -#elif defined(BT_USE_NEON) +#elif defined(BT_USE_NEON) float32x4_t vQ1 = q1.get128(); float32x4_t vQ2 = q2.get128(); float32x4_t A0, A1, B1, A2, B2, A3, B3; - float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz; - - { - float32x2x2_t tmp; - tmp = vtrn_f32( vget_high_f32(vQ1), vget_low_f32(vQ1) ); // {z x}, {w y} - vQ1zx = tmp.val[0]; + float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz; - tmp = vtrn_f32( vget_high_f32(vQ2), vget_low_f32(vQ2) ); // {z x}, {w y} - vQ2zx = tmp.val[0]; - } - vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1); + { + float32x2x2_t tmp; + tmp = vtrn_f32(vget_high_f32(vQ1), vget_low_f32(vQ1)); // {z x}, {w y} + vQ1zx = tmp.val[0]; - vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1); + tmp = vtrn_f32(vget_high_f32(vQ2), vget_low_f32(vQ2)); // {z x}, {w y} + vQ2zx = tmp.val[0]; + } + vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1); - vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1); - vQ2xz = vext_f32(vQ2zx, vQ2zx, 1); + vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1); - A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx); // X Y z x - B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx); // W W W X + vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1); + vQ2xz = vext_f32(vQ2zx, vQ2zx, 1); + + A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx); // X Y z x + B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx); // W W W X A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1)); - B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1)); + B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1)); - A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z - B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z + A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z + B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z A1 = vmulq_f32(A1, B1); A2 = vmulq_f32(A2, B2); - A3 = vmulq_f32(A3, B3); // A3 *= B3 - A0 = vmulq_lane_f32(vQ2, vget_high_f32(vQ1), 1); // A0 * B0 + A3 = vmulq_f32(A3, B3); // A3 *= B3 + A0 = vmulq_lane_f32(vQ2, vget_high_f32(vQ1), 1); // A0 * B0 + + A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2 + A0 = vsubq_f32(A0, A3); // AB03 = AB0 - AB3 + + // change the sign of the last element + A1 = (btSimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)vPPPM); + A0 = vaddq_f32(A0, A1); // AB03 + AB12 - A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2 - A0 = vsubq_f32(A0, A3); // AB03 = AB0 - AB3 - - // change the sign of the last element - A1 = (btSimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)vPPPM); - A0 = vaddq_f32(A0, A1); // AB03 + AB12 - return btQuaternion(A0); #else return btQuaternion( - q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(), + q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(), q1.w() * q2.y() + q1.y() * q2.w() + q1.z() * q2.x() - q1.x() * q2.z(), q1.w() * q2.z() + q1.z() * q2.w() + q1.x() * q2.y() - q1.y() * q2.x(), - q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z()); + q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z()); #endif } SIMD_FORCE_INLINE btQuaternion operator*(const btQuaternion& q, const btVector3& w) { -#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) __m128 vQ1 = q.get128(); __m128 vQ2 = w.get128(); __m128 A1, B1, A2, B2, A3, B3; - - A1 = bt_pshufd_ps(vQ1, BT_SHUFFLE(3,3,3,0)); - B1 = bt_pshufd_ps(vQ2, BT_SHUFFLE(0,1,2,0)); + + A1 = bt_pshufd_ps(vQ1, BT_SHUFFLE(3, 3, 3, 0)); + B1 = bt_pshufd_ps(vQ2, BT_SHUFFLE(0, 1, 2, 0)); A1 = A1 * B1; - - A2 = bt_pshufd_ps(vQ1, BT_SHUFFLE(1,2,0,1)); - B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(2,0,1,1)); + + A2 = bt_pshufd_ps(vQ1, BT_SHUFFLE(1, 2, 0, 1)); + B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(2, 0, 1, 1)); A2 = A2 * B2; - A3 = bt_pshufd_ps(vQ1, BT_SHUFFLE(2,0,1,2)); - B3 = bt_pshufd_ps(vQ2, BT_SHUFFLE(1,2,0,2)); - - A3 = A3 * B3; // A3 *= B3 + A3 = bt_pshufd_ps(vQ1, BT_SHUFFLE(2, 0, 1, 2)); + B3 = bt_pshufd_ps(vQ2, BT_SHUFFLE(1, 2, 0, 2)); + + A3 = A3 * B3; // A3 *= B3 + + A1 = A1 + A2; // AB12 + A1 = _mm_xor_ps(A1, vPPPM); // change sign of the last element + A1 = A1 - A3; // AB123 = AB12 - AB3 - A1 = A1 + A2; // AB12 - A1 = _mm_xor_ps(A1, vPPPM); // change sign of the last element - A1 = A1 - A3; // AB123 = AB12 - AB3 - return btQuaternion(A1); - -#elif defined(BT_USE_NEON) + +#elif defined(BT_USE_NEON) float32x4_t vQ1 = q.get128(); float32x4_t vQ2 = w.get128(); float32x4_t A1, B1, A2, B2, A3, B3; - float32x2_t vQ1wx, vQ2zx, vQ1yz, vQ2yz, vQ1zx, vQ2xz; - - vQ1wx = vext_f32(vget_high_f32(vQ1), vget_low_f32(vQ1), 1); - { - float32x2x2_t tmp; + float32x2_t vQ1wx, vQ2zx, vQ1yz, vQ2yz, vQ1zx, vQ2xz; - tmp = vtrn_f32( vget_high_f32(vQ2), vget_low_f32(vQ2) ); // {z x}, {w y} - vQ2zx = tmp.val[0]; + vQ1wx = vext_f32(vget_high_f32(vQ1), vget_low_f32(vQ1), 1); + { + float32x2x2_t tmp; - tmp = vtrn_f32( vget_high_f32(vQ1), vget_low_f32(vQ1) ); // {z x}, {w y} - vQ1zx = tmp.val[0]; - } + tmp = vtrn_f32(vget_high_f32(vQ2), vget_low_f32(vQ2)); // {z x}, {w y} + vQ2zx = tmp.val[0]; - vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1); + tmp = vtrn_f32(vget_high_f32(vQ1), vget_low_f32(vQ1)); // {z x}, {w y} + vQ1zx = tmp.val[0]; + } - vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1); - vQ2xz = vext_f32(vQ2zx, vQ2zx, 1); + vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1); - A1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ1), 1), vQ1wx); // W W W X - B1 = vcombine_f32(vget_low_f32(vQ2), vQ2zx); // X Y z x + vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1); + vQ2xz = vext_f32(vQ2zx, vQ2zx, 1); + + A1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ1), 1), vQ1wx); // W W W X + B1 = vcombine_f32(vget_low_f32(vQ2), vQ2zx); // X Y z x A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1)); - B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1)); + B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1)); - A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z - B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z + A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z + B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z A1 = vmulq_f32(A1, B1); A2 = vmulq_f32(A2, B2); - A3 = vmulq_f32(A3, B3); // A3 *= B3 + A3 = vmulq_f32(A3, B3); // A3 *= B3 + + A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2 + + // change the sign of the last element + A1 = (btSimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)vPPPM); + + A1 = vsubq_f32(A1, A3); // AB123 = AB12 - AB3 - A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2 - - // change the sign of the last element - A1 = (btSimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)vPPPM); - - A1 = vsubq_f32(A1, A3); // AB123 = AB12 - AB3 - return btQuaternion(A1); - + #else - return btQuaternion( - q.w() * w.x() + q.y() * w.z() - q.z() * w.y(), - q.w() * w.y() + q.z() * w.x() - q.x() * w.z(), - q.w() * w.z() + q.x() * w.y() - q.y() * w.x(), - -q.x() * w.x() - q.y() * w.y() - q.z() * w.z()); + return btQuaternion( + q.w() * w.x() + q.y() * w.z() - q.z() * w.y(), + q.w() * w.y() + q.z() * w.x() - q.x() * w.z(), + q.w() * w.z() + q.x() * w.y() - q.y() * w.x(), + -q.x() * w.x() - q.y() * w.y() - q.z() * w.z()); #endif } SIMD_FORCE_INLINE btQuaternion operator*(const btVector3& w, const btQuaternion& q) { -#if defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) __m128 vQ1 = w.get128(); __m128 vQ2 = q.get128(); __m128 A1, B1, A2, B2, A3, B3; - - A1 = bt_pshufd_ps(vQ1, BT_SHUFFLE(0,1,2,0)); // X Y z x - B1 = bt_pshufd_ps(vQ2, BT_SHUFFLE(3,3,3,0)); // W W W X + + A1 = bt_pshufd_ps(vQ1, BT_SHUFFLE(0, 1, 2, 0)); // X Y z x + B1 = bt_pshufd_ps(vQ2, BT_SHUFFLE(3, 3, 3, 0)); // W W W X A1 = A1 * B1; - - A2 = bt_pshufd_ps(vQ1, BT_SHUFFLE(1,2,0,1)); - B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(2,0,1,1)); - A2 = A2 *B2; + A2 = bt_pshufd_ps(vQ1, BT_SHUFFLE(1, 2, 0, 1)); + B2 = bt_pshufd_ps(vQ2, BT_SHUFFLE(2, 0, 1, 1)); - A3 = bt_pshufd_ps(vQ1, BT_SHUFFLE(2,0,1,2)); - B3 = bt_pshufd_ps(vQ2, BT_SHUFFLE(1,2,0,2)); - - A3 = A3 * B3; // A3 *= B3 + A2 = A2 * B2; + + A3 = bt_pshufd_ps(vQ1, BT_SHUFFLE(2, 0, 1, 2)); + B3 = bt_pshufd_ps(vQ2, BT_SHUFFLE(1, 2, 0, 2)); + + A3 = A3 * B3; // A3 *= B3 + + A1 = A1 + A2; // AB12 + A1 = _mm_xor_ps(A1, vPPPM); // change sign of the last element + A1 = A1 - A3; // AB123 = AB12 - AB3 - A1 = A1 + A2; // AB12 - A1 = _mm_xor_ps(A1, vPPPM); // change sign of the last element - A1 = A1 - A3; // AB123 = AB12 - AB3 - return btQuaternion(A1); -#elif defined(BT_USE_NEON) +#elif defined(BT_USE_NEON) float32x4_t vQ1 = w.get128(); float32x4_t vQ2 = q.get128(); - float32x4_t A1, B1, A2, B2, A3, B3; - float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz; - - { - float32x2x2_t tmp; - - tmp = vtrn_f32( vget_high_f32(vQ1), vget_low_f32(vQ1) ); // {z x}, {w y} - vQ1zx = tmp.val[0]; + float32x4_t A1, B1, A2, B2, A3, B3; + float32x2_t vQ1zx, vQ2wx, vQ1yz, vQ2zx, vQ2yz, vQ2xz; - tmp = vtrn_f32( vget_high_f32(vQ2), vget_low_f32(vQ2) ); // {z x}, {w y} - vQ2zx = tmp.val[0]; - } - vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1); + { + float32x2x2_t tmp; - vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1); + tmp = vtrn_f32(vget_high_f32(vQ1), vget_low_f32(vQ1)); // {z x}, {w y} + vQ1zx = tmp.val[0]; - vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1); - vQ2xz = vext_f32(vQ2zx, vQ2zx, 1); + tmp = vtrn_f32(vget_high_f32(vQ2), vget_low_f32(vQ2)); // {z x}, {w y} + vQ2zx = tmp.val[0]; + } + vQ2wx = vext_f32(vget_high_f32(vQ2), vget_low_f32(vQ2), 1); - A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx); // X Y z x - B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx); // W W W X + vQ1yz = vext_f32(vget_low_f32(vQ1), vget_high_f32(vQ1), 1); + + vQ2yz = vext_f32(vget_low_f32(vQ2), vget_high_f32(vQ2), 1); + vQ2xz = vext_f32(vQ2zx, vQ2zx, 1); + + A1 = vcombine_f32(vget_low_f32(vQ1), vQ1zx); // X Y z x + B1 = vcombine_f32(vdup_lane_f32(vget_high_f32(vQ2), 1), vQ2wx); // W W W X A2 = vcombine_f32(vQ1yz, vget_low_f32(vQ1)); - B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1)); + B2 = vcombine_f32(vQ2zx, vdup_lane_f32(vget_low_f32(vQ2), 1)); - A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z - B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z + A3 = vcombine_f32(vQ1zx, vQ1yz); // Z X Y Z + B3 = vcombine_f32(vQ2yz, vQ2xz); // Y Z x z A1 = vmulq_f32(A1, B1); A2 = vmulq_f32(A2, B2); - A3 = vmulq_f32(A3, B3); // A3 *= B3 + A3 = vmulq_f32(A3, B3); // A3 *= B3 + + A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2 + + // change the sign of the last element + A1 = (btSimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)vPPPM); + + A1 = vsubq_f32(A1, A3); // AB123 = AB12 - AB3 - A1 = vaddq_f32(A1, A2); // AB12 = AB1 + AB2 - - // change the sign of the last element - A1 = (btSimdFloat4)veorq_s32((int32x4_t)A1, (int32x4_t)vPPPM); - - A1 = vsubq_f32(A1, A3); // AB123 = AB12 - AB3 - return btQuaternion(A1); - + #else - return btQuaternion( - +w.x() * q.w() + w.y() * q.z() - w.z() * q.y(), + return btQuaternion( + +w.x() * q.w() + w.y() * q.z() - w.z() * q.y(), +w.y() * q.w() + w.z() * q.x() - w.x() * q.z(), +w.z() * q.w() + w.x() * q.y() - w.y() * q.x(), - -w.x() * q.x() - w.y() * q.y() - w.z() * q.z()); + -w.x() * q.x() - w.y() * q.y() - w.z() * q.z()); #endif } /**@brief Calculate the dot product between two quaternions */ -SIMD_FORCE_INLINE btScalar -dot(const btQuaternion& q1, const btQuaternion& q2) -{ - return q1.dot(q2); +SIMD_FORCE_INLINE btScalar +dot(const btQuaternion& q1, const btQuaternion& q2) +{ + return q1.dot(q2); } - /**@brief Return the length of a quaternion */ SIMD_FORCE_INLINE btScalar -length(const btQuaternion& q) -{ - return q.length(); +length(const btQuaternion& q) +{ + return q.length(); } /**@brief Return the angle between two quaternions*/ SIMD_FORCE_INLINE btScalar -btAngle(const btQuaternion& q1, const btQuaternion& q2) -{ - return q1.angle(q2); +btAngle(const btQuaternion& q1, const btQuaternion& q2) +{ + return q1.angle(q2); } /**@brief Return the inverse of a quaternion*/ SIMD_FORCE_INLINE btQuaternion -inverse(const btQuaternion& q) +inverse(const btQuaternion& q) { return q.inverse(); } @@ -928,115 +917,105 @@ inverse(const btQuaternion& q) * @param t The ration between q1 and q2. t = 0 return q1, t=1 returns q2 * Slerp assumes constant velocity between positions. */ SIMD_FORCE_INLINE btQuaternion -slerp(const btQuaternion& q1, const btQuaternion& q2, const btScalar& t) +slerp(const btQuaternion& q1, const btQuaternion& q2, const btScalar& t) { return q1.slerp(q2, t); } -SIMD_FORCE_INLINE btVector3 -quatRotate(const btQuaternion& rotation, const btVector3& v) +SIMD_FORCE_INLINE btVector3 +quatRotate(const btQuaternion& rotation, const btVector3& v) { btQuaternion q = rotation * v; q *= rotation.inverse(); -#if defined BT_USE_SIMD_VECTOR3 && defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined BT_USE_SIMD_VECTOR3 && defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) return btVector3(_mm_and_ps(q.get128(), btvFFF0fMask)); #elif defined(BT_USE_NEON) - return btVector3((float32x4_t)vandq_s32((int32x4_t)q.get128(), btvFFF0Mask)); -#else - return btVector3(q.getX(),q.getY(),q.getZ()); + return btVector3((float32x4_t)vandq_s32((int32x4_t)q.get128(), btvFFF0Mask)); +#else + return btVector3(q.getX(), q.getY(), q.getZ()); #endif } -SIMD_FORCE_INLINE btQuaternion -shortestArcQuat(const btVector3& v0, const btVector3& v1) // Game Programming Gems 2.10. make sure v0,v1 are normalized +SIMD_FORCE_INLINE btQuaternion +shortestArcQuat(const btVector3& v0, const btVector3& v1) // Game Programming Gems 2.10. make sure v0,v1 are normalized { btVector3 c = v0.cross(v1); - btScalar d = v0.dot(v1); + btScalar d = v0.dot(v1); if (d < -1.0 + SIMD_EPSILON) { - btVector3 n,unused; - btPlaneSpace1(v0,n,unused); - return btQuaternion(n.x(),n.y(),n.z(),0.0f); // just pick any vector that is orthogonal to v0 + btVector3 n, unused; + btPlaneSpace1(v0, n, unused); + return btQuaternion(n.x(), n.y(), n.z(), 0.0f); // just pick any vector that is orthogonal to v0 } - btScalar s = btSqrt((1.0f + d) * 2.0f); + btScalar s = btSqrt((1.0f + d) * 2.0f); btScalar rs = 1.0f / s; - return btQuaternion(c.getX()*rs,c.getY()*rs,c.getZ()*rs,s * 0.5f); + return btQuaternion(c.getX() * rs, c.getY() * rs, c.getZ() * rs, s * 0.5f); } -SIMD_FORCE_INLINE btQuaternion -shortestArcQuatNormalize2(btVector3& v0,btVector3& v1) +SIMD_FORCE_INLINE btQuaternion +shortestArcQuatNormalize2(btVector3& v0, btVector3& v1) { v0.normalize(); v1.normalize(); - return shortestArcQuat(v0,v1); + return shortestArcQuat(v0, v1); } - - - -struct btQuaternionFloatData +struct btQuaternionFloatData { - float m_floats[4]; + float m_floats[4]; }; -struct btQuaternionDoubleData +struct btQuaternionDoubleData { - double m_floats[4]; - + double m_floats[4]; }; -SIMD_FORCE_INLINE void btQuaternion::serializeFloat(struct btQuaternionFloatData& dataOut) const +SIMD_FORCE_INLINE void btQuaternion::serializeFloat(struct btQuaternionFloatData& dataOut) const { ///could also do a memcpy, check if it is worth it - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) dataOut.m_floats[i] = float(m_floats[i]); } -SIMD_FORCE_INLINE void btQuaternion::deSerializeFloat(const struct btQuaternionFloatData& dataIn) +SIMD_FORCE_INLINE void btQuaternion::deSerializeFloat(const struct btQuaternionFloatData& dataIn) { - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) m_floats[i] = btScalar(dataIn.m_floats[i]); } - -SIMD_FORCE_INLINE void btQuaternion::serializeDouble(struct btQuaternionDoubleData& dataOut) const +SIMD_FORCE_INLINE void btQuaternion::serializeDouble(struct btQuaternionDoubleData& dataOut) const { ///could also do a memcpy, check if it is worth it - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) dataOut.m_floats[i] = double(m_floats[i]); } -SIMD_FORCE_INLINE void btQuaternion::deSerializeDouble(const struct btQuaternionDoubleData& dataIn) +SIMD_FORCE_INLINE void btQuaternion::deSerializeDouble(const struct btQuaternionDoubleData& dataIn) { - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) m_floats[i] = btScalar(dataIn.m_floats[i]); } - -SIMD_FORCE_INLINE void btQuaternion::serialize(struct btQuaternionData& dataOut) const +SIMD_FORCE_INLINE void btQuaternion::serialize(struct btQuaternionData& dataOut) const { ///could also do a memcpy, check if it is worth it - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) dataOut.m_floats[i] = m_floats[i]; } -SIMD_FORCE_INLINE void btQuaternion::deSerialize(const struct btQuaternionFloatData& dataIn) +SIMD_FORCE_INLINE void btQuaternion::deSerialize(const struct btQuaternionFloatData& dataIn) { - for (int i = 0; i<4; i++) + for (int i = 0; i < 4; i++) m_floats[i] = (btScalar)dataIn.m_floats[i]; } -SIMD_FORCE_INLINE void btQuaternion::deSerialize(const struct btQuaternionDoubleData& dataIn) +SIMD_FORCE_INLINE void btQuaternion::deSerialize(const struct btQuaternionDoubleData& dataIn) { - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) m_floats[i] = (btScalar)dataIn.m_floats[i]; } - -#endif //BT_SIMD__QUATERNION_H_ - - - +#endif //BT_SIMD__QUATERNION_H_ diff --git a/src/LinearMath/btQuickprof.cpp b/src/LinearMath/btQuickprof.cpp index 1572b9626..8d3310981 100644 --- a/src/LinearMath/btQuickprof.cpp +++ b/src/LinearMath/btQuickprof.cpp @@ -16,16 +16,13 @@ #include "btQuickprof.h" #include "btThreads.h" - - - #ifdef __CELLOS_LV2__ #include #include #include #endif -#if defined (SUNOS) || defined (__SUNOS__) +#if defined(SUNOS) || defined(__SUNOS__) #include #endif #ifdef __APPLE__ @@ -42,49 +39,46 @@ #define NOIME #ifdef _XBOX - #include -#else //_XBOX - #include +#include +#else //_XBOX +#include -#if WINVER <0x0602 +#if WINVER < 0x0602 #define GetTickCount64 GetTickCount #endif -#endif //_XBOX +#endif //_XBOX #include - -#else //_WIN32 +#else //_WIN32 #include #ifdef BT_LINUX_REALTIME //required linking against rt (librt) #include -#endif //BT_LINUX_REALTIME +#endif //BT_LINUX_REALTIME -#endif //_WIN32 +#endif //_WIN32 -#define mymin(a,b) (a > b ? a : b) +#define mymin(a, b) (a > b ? a : b) struct btClockData { - #ifdef BT_USE_WINDOWS_TIMERS LARGE_INTEGER mClockFrequency; LONGLONG mStartTick; LARGE_INTEGER mStartTime; #else #ifdef __CELLOS_LV2__ - uint64_t mStartTime; + uint64_t mStartTime; #else #ifdef __APPLE__ - uint64_t mStartTimeNano; + uint64_t mStartTimeNano; #endif struct timeval mStartTime; #endif -#endif //__CELLOS_LV2__ - +#endif //__CELLOS_LV2__ }; ///The btClock is a portable basic clock that measures accurate time in seconds, use for profiling. @@ -114,8 +108,7 @@ btClock& btClock::operator=(const btClock& other) return *this; } - - /// Resets the initial reference time. +/// Resets the initial reference time. void btClock::reset() { #ifdef BT_USE_WINDOWS_TIMERS @@ -124,14 +117,14 @@ void btClock::reset() #else #ifdef __CELLOS_LV2__ - typedef uint64_t ClockSize; + typedef uint64_t ClockSize; ClockSize newTime; //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); - SYS_TIMEBASE_GET( newTime ); + SYS_TIMEBASE_GET(newTime); m_data->mStartTime = newTime; #else #ifdef __APPLE__ - m_data->mStartTimeNano = mach_absolute_time(); + m_data->mStartTimeNano = mach_absolute_time(); #endif gettimeofday(&m_data->mStartTime, 0); #endif @@ -146,66 +139,66 @@ unsigned long long int btClock::getTimeMilliseconds() LARGE_INTEGER currentTime; QueryPerformanceCounter(¤tTime); LONGLONG elapsedTime = currentTime.QuadPart - - m_data->mStartTime.QuadPart; - // Compute the number of millisecond ticks elapsed. + m_data->mStartTime.QuadPart; + // Compute the number of millisecond ticks elapsed. unsigned long msecTicks = (unsigned long)(1000 * elapsedTime / - m_data->mClockFrequency.QuadPart); + m_data->mClockFrequency.QuadPart); - return msecTicks; + return msecTicks; #else #ifdef __CELLOS_LV2__ - uint64_t freq=sys_time_get_timebase_frequency(); - double dFreq=((double) freq) / 1000.0; - typedef uint64_t ClockSize; - ClockSize newTime; - SYS_TIMEBASE_GET( newTime ); - //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); + uint64_t freq = sys_time_get_timebase_frequency(); + double dFreq = ((double)freq) / 1000.0; + typedef uint64_t ClockSize; + ClockSize newTime; + SYS_TIMEBASE_GET(newTime); + //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); - return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq); + return (unsigned long int)((double(newTime - m_data->mStartTime)) / dFreq); #else - struct timeval currentTime; - gettimeofday(¤tTime, 0); - return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000 + - (currentTime.tv_usec - m_data->mStartTime.tv_usec) / 1000; -#endif //__CELLOS_LV2__ + struct timeval currentTime; + gettimeofday(¤tTime, 0); + return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000 + + (currentTime.tv_usec - m_data->mStartTime.tv_usec) / 1000; +#endif //__CELLOS_LV2__ #endif } - /// Returns the time in us since the last call to reset or since - /// the Clock was created. +/// Returns the time in us since the last call to reset or since +/// the Clock was created. unsigned long long int btClock::getTimeMicroseconds() { #ifdef BT_USE_WINDOWS_TIMERS - //see https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx - LARGE_INTEGER currentTime, elapsedTime; - - QueryPerformanceCounter(¤tTime); - elapsedTime.QuadPart = currentTime.QuadPart - - m_data->mStartTime.QuadPart; - elapsedTime.QuadPart *= 1000000; - elapsedTime.QuadPart /= m_data->mClockFrequency.QuadPart; + //see https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx + LARGE_INTEGER currentTime, elapsedTime; - return (unsigned long long) elapsedTime.QuadPart; + QueryPerformanceCounter(¤tTime); + elapsedTime.QuadPart = currentTime.QuadPart - + m_data->mStartTime.QuadPart; + elapsedTime.QuadPart *= 1000000; + elapsedTime.QuadPart /= m_data->mClockFrequency.QuadPart; + + return (unsigned long long)elapsedTime.QuadPart; #else #ifdef __CELLOS_LV2__ - uint64_t freq=sys_time_get_timebase_frequency(); - double dFreq=((double) freq)/ 1000000.0; - typedef uint64_t ClockSize; - ClockSize newTime; - //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); - SYS_TIMEBASE_GET( newTime ); + uint64_t freq = sys_time_get_timebase_frequency(); + double dFreq = ((double)freq) / 1000000.0; + typedef uint64_t ClockSize; + ClockSize newTime; + //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); + SYS_TIMEBASE_GET(newTime); - return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq); + return (unsigned long int)((double(newTime - m_data->mStartTime)) / dFreq); #else - struct timeval currentTime; - gettimeofday(¤tTime, 0); - return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000000 + - (currentTime.tv_usec - m_data->mStartTime.tv_usec); -#endif//__CELLOS_LV2__ + struct timeval currentTime; + gettimeofday(¤tTime, 0); + return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1000000 + + (currentTime.tv_usec - m_data->mStartTime.tv_usec); +#endif //__CELLOS_LV2__ #endif } @@ -213,65 +206,63 @@ unsigned long long int btClock::getTimeNanoseconds() { #ifdef BT_USE_WINDOWS_TIMERS //see https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx - LARGE_INTEGER currentTime, elapsedTime; - - QueryPerformanceCounter(¤tTime); - elapsedTime.QuadPart = currentTime.QuadPart - - m_data->mStartTime.QuadPart; - elapsedTime.QuadPart *= 1000000000; - elapsedTime.QuadPart /= m_data->mClockFrequency.QuadPart; + LARGE_INTEGER currentTime, elapsedTime; - return (unsigned long long) elapsedTime.QuadPart; + QueryPerformanceCounter(¤tTime); + elapsedTime.QuadPart = currentTime.QuadPart - + m_data->mStartTime.QuadPart; + elapsedTime.QuadPart *= 1000000000; + elapsedTime.QuadPart /= m_data->mClockFrequency.QuadPart; + + return (unsigned long long)elapsedTime.QuadPart; #else #ifdef __CELLOS_LV2__ - uint64_t freq=sys_time_get_timebase_frequency(); - double dFreq=((double) freq)/ 1e9; - typedef uint64_t ClockSize; - ClockSize newTime; - //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); - SYS_TIMEBASE_GET( newTime ); + uint64_t freq = sys_time_get_timebase_frequency(); + double dFreq = ((double)freq) / 1e9; + typedef uint64_t ClockSize; + ClockSize newTime; + //__asm __volatile__( "mftb %0" : "=r" (newTime) : : "memory"); + SYS_TIMEBASE_GET(newTime); - return (unsigned long int)((double(newTime-m_data->mStartTime)) / dFreq); + return (unsigned long int)((double(newTime - m_data->mStartTime)) / dFreq); #else #ifdef __APPLE__ - uint64_t ticks = mach_absolute_time() - m_data->mStartTimeNano; - static long double conversion = 0.0L; - if( 0.0L == conversion ) - { - // attempt to get conversion to nanoseconds - mach_timebase_info_data_t info; - int err = mach_timebase_info( &info ); - if( err ) - { - btAssert(0); - conversion = 1.; - } - conversion = info.numer / info.denom; - } - return (ticks * conversion); + uint64_t ticks = mach_absolute_time() - m_data->mStartTimeNano; + static long double conversion = 0.0L; + if (0.0L == conversion) + { + // attempt to get conversion to nanoseconds + mach_timebase_info_data_t info; + int err = mach_timebase_info(&info); + if (err) + { + btAssert(0); + conversion = 1.; + } + conversion = info.numer / info.denom; + } + return (ticks * conversion); + +#else //__APPLE__ - -#else//__APPLE__ - #ifdef BT_LINUX_REALTIME - timespec ts; - clock_gettime(CLOCK_REALTIME,&ts); - return 1000000000*ts.tv_sec + ts.tv_nsec; + timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return 1000000000 * ts.tv_sec + ts.tv_nsec; #else - struct timeval currentTime; - gettimeofday(¤tTime, 0); - return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1e9 + - (currentTime.tv_usec - m_data->mStartTime.tv_usec)*1000; -#endif //BT_LINUX_REALTIME + struct timeval currentTime; + gettimeofday(¤tTime, 0); + return (currentTime.tv_sec - m_data->mStartTime.tv_sec) * 1e9 + + (currentTime.tv_usec - m_data->mStartTime.tv_usec) * 1000; +#endif //BT_LINUX_REALTIME -#endif//__APPLE__ -#endif//__CELLOS_LV2__ -#endif +#endif //__APPLE__ +#endif //__CELLOS_LV2__ +#endif } - -/// Returns the time in s since the last call to reset or since +/// Returns the time in s since the last call to reset or since /// the Clock was created. btScalar btClock::getTimeSeconds() { @@ -281,23 +272,19 @@ btScalar btClock::getTimeSeconds() #ifndef BT_NO_PROFILE - static btClock gProfileClock; - -inline void Profile_Get_Ticks(unsigned long int * ticks) +inline void Profile_Get_Ticks(unsigned long int* ticks) { *ticks = (unsigned long int)gProfileClock.getTimeMicroseconds(); } inline float Profile_Get_Tick_Rate(void) { -// return 1000000.f; + // return 1000000.f; return 1000.f; - } - /*************************************************************************************************** ** ** CProfileNode @@ -313,35 +300,32 @@ inline float Profile_Get_Tick_Rate(void) * The name is assumed to be a static pointer, only the pointer is stored and compared for * * efficiency reasons. * *=============================================================================================*/ -CProfileNode::CProfileNode( const char * name, CProfileNode * parent ) : - Name( name ), - TotalCalls( 0 ), - TotalTime( 0 ), - StartTime( 0 ), - RecursionCounter( 0 ), - Parent( parent ), - Child( NULL ), - Sibling( NULL ), - m_userPtr(0) +CProfileNode::CProfileNode(const char* name, CProfileNode* parent) : Name(name), + TotalCalls(0), + TotalTime(0), + StartTime(0), + RecursionCounter(0), + Parent(parent), + Child(NULL), + Sibling(NULL), + m_userPtr(0) { Reset(); } - -void CProfileNode::CleanupMemory() +void CProfileNode::CleanupMemory() { - delete ( Child); + delete (Child); Child = NULL; - delete ( Sibling); + delete (Sibling); Sibling = NULL; } -CProfileNode::~CProfileNode( void ) +CProfileNode::~CProfileNode(void) { CleanupMemory(); } - /*********************************************************************************************** * INPUT: * * name - static string pointer to the name of the node we are searching for * @@ -350,12 +334,14 @@ CProfileNode::~CProfileNode( void ) * All profile names are assumed to be static strings so this function uses pointer compares * * to find the named node. * *=============================================================================================*/ -CProfileNode * CProfileNode::Get_Sub_Node( const char * name ) +CProfileNode* CProfileNode::Get_Sub_Node(const char* name) { // Try to find this sub node - CProfileNode * child = Child; - while ( child ) { - if ( child->Name == name ) { + CProfileNode* child = Child; + while (child) + { + if (child->Name == name) + { return child; } child = child->Sibling; @@ -363,176 +349,212 @@ CProfileNode * CProfileNode::Get_Sub_Node( const char * name ) // We didn't find it, so add it - CProfileNode * node = new CProfileNode( name, this ); + CProfileNode* node = new CProfileNode(name, this); node->Sibling = Child; Child = node; return node; } - -void CProfileNode::Reset( void ) +void CProfileNode::Reset(void) { TotalCalls = 0; TotalTime = 0.0f; - - if ( Child ) { + if (Child) + { Child->Reset(); } - if ( Sibling ) { + if (Sibling) + { Sibling->Reset(); } } - -void CProfileNode::Call( void ) +void CProfileNode::Call(void) { TotalCalls++; - if (RecursionCounter++ == 0) { + if (RecursionCounter++ == 0) + { Profile_Get_Ticks(&StartTime); } } - -bool CProfileNode::Return( void ) +bool CProfileNode::Return(void) { - if ( --RecursionCounter == 0 && TotalCalls != 0 ) { + if (--RecursionCounter == 0 && TotalCalls != 0) + { unsigned long int time; Profile_Get_Ticks(&time); - time-=StartTime; + time -= StartTime; TotalTime += (float)time / Profile_Get_Tick_Rate(); } - return ( RecursionCounter == 0 ); + return (RecursionCounter == 0); } - /*************************************************************************************************** ** ** CProfileIterator ** ***************************************************************************************************/ -CProfileIterator::CProfileIterator( CProfileNode * start ) +CProfileIterator::CProfileIterator(CProfileNode* start) { CurrentParent = start; CurrentChild = CurrentParent->Get_Child(); } - -void CProfileIterator::First(void) +void CProfileIterator::First(void) { CurrentChild = CurrentParent->Get_Child(); } - -void CProfileIterator::Next(void) +void CProfileIterator::Next(void) { CurrentChild = CurrentChild->Get_Sibling(); } - -bool CProfileIterator::Is_Done(void) +bool CProfileIterator::Is_Done(void) { return CurrentChild == NULL; } - -void CProfileIterator::Enter_Child( int index ) +void CProfileIterator::Enter_Child(int index) { CurrentChild = CurrentParent->Get_Child(); - while ( (CurrentChild != NULL) && (index != 0) ) { + while ((CurrentChild != NULL) && (index != 0)) + { index--; CurrentChild = CurrentChild->Get_Sibling(); } - if ( CurrentChild != NULL ) { + if (CurrentChild != NULL) + { CurrentParent = CurrentChild; CurrentChild = CurrentParent->Get_Child(); } } - -void CProfileIterator::Enter_Parent( void ) +void CProfileIterator::Enter_Parent(void) { - if ( CurrentParent->Get_Parent() != NULL ) { + if (CurrentParent->Get_Parent() != NULL) + { CurrentParent = CurrentParent->Get_Parent(); } CurrentChild = CurrentParent->Get_Child(); } - /*************************************************************************************************** ** ** CProfileManager ** ***************************************************************************************************/ +CProfileNode gRoots[BT_QUICKPROF_MAX_THREAD_COUNT] = { + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), + CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL), CProfileNode("Root", NULL)}; - - -CProfileNode gRoots[BT_QUICKPROF_MAX_THREAD_COUNT]={ - CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL), - CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL), - CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL), - CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL), - CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL), - CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL), - CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL), - CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL), - CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL), - CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL), - CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL), - CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL), - CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL), - CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL), - CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL), - CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL),CProfileNode("Root",NULL) +CProfileNode* gCurrentNodes[BT_QUICKPROF_MAX_THREAD_COUNT] = + { + &gRoots[0], + &gRoots[1], + &gRoots[2], + &gRoots[3], + &gRoots[4], + &gRoots[5], + &gRoots[6], + &gRoots[7], + &gRoots[8], + &gRoots[9], + &gRoots[10], + &gRoots[11], + &gRoots[12], + &gRoots[13], + &gRoots[14], + &gRoots[15], + &gRoots[16], + &gRoots[17], + &gRoots[18], + &gRoots[19], + &gRoots[20], + &gRoots[21], + &gRoots[22], + &gRoots[23], + &gRoots[24], + &gRoots[25], + &gRoots[26], + &gRoots[27], + &gRoots[28], + &gRoots[29], + &gRoots[30], + &gRoots[31], + &gRoots[32], + &gRoots[33], + &gRoots[34], + &gRoots[35], + &gRoots[36], + &gRoots[37], + &gRoots[38], + &gRoots[39], + &gRoots[40], + &gRoots[41], + &gRoots[42], + &gRoots[43], + &gRoots[44], + &gRoots[45], + &gRoots[46], + &gRoots[47], + &gRoots[48], + &gRoots[49], + &gRoots[50], + &gRoots[51], + &gRoots[52], + &gRoots[53], + &gRoots[54], + &gRoots[55], + &gRoots[56], + &gRoots[57], + &gRoots[58], + &gRoots[59], + &gRoots[60], + &gRoots[61], + &gRoots[62], + &gRoots[63], }; +int CProfileManager::FrameCounter = 0; +unsigned long int CProfileManager::ResetTime = 0; -CProfileNode* gCurrentNodes[BT_QUICKPROF_MAX_THREAD_COUNT]= +CProfileIterator* CProfileManager::Get_Iterator(void) { - &gRoots[ 0], &gRoots[ 1], &gRoots[ 2], &gRoots[ 3], - &gRoots[ 4], &gRoots[ 5], &gRoots[ 6], &gRoots[ 7], - &gRoots[ 8], &gRoots[ 9], &gRoots[10], &gRoots[11], - &gRoots[12], &gRoots[13], &gRoots[14], &gRoots[15], - &gRoots[16], &gRoots[17], &gRoots[18], &gRoots[19], - &gRoots[20], &gRoots[21], &gRoots[22], &gRoots[23], - &gRoots[24], &gRoots[25], &gRoots[26], &gRoots[27], - &gRoots[28], &gRoots[29], &gRoots[30], &gRoots[31], - &gRoots[32], &gRoots[33], &gRoots[34], &gRoots[35], - &gRoots[36], &gRoots[37], &gRoots[38], &gRoots[39], - &gRoots[40], &gRoots[41], &gRoots[42], &gRoots[43], - &gRoots[44], &gRoots[45], &gRoots[46], &gRoots[47], - &gRoots[48], &gRoots[49], &gRoots[50], &gRoots[51], - &gRoots[52], &gRoots[53], &gRoots[54], &gRoots[55], - &gRoots[56], &gRoots[57], &gRoots[58], &gRoots[59], - &gRoots[60], &gRoots[61], &gRoots[62], &gRoots[63], -}; + int threadIndex = btQuickprofGetCurrentThreadIndex2(); + if ((threadIndex < 0) || threadIndex >= BT_QUICKPROF_MAX_THREAD_COUNT) + return 0; - -int CProfileManager::FrameCounter = 0; -unsigned long int CProfileManager::ResetTime = 0; - -CProfileIterator * CProfileManager::Get_Iterator( void ) -{ - - int threadIndex = btQuickprofGetCurrentThreadIndex2(); - if ((threadIndex<0) || threadIndex >= BT_QUICKPROF_MAX_THREAD_COUNT) - return 0; - - return new CProfileIterator( &gRoots[threadIndex]); + return new CProfileIterator(&gRoots[threadIndex]); } -void CProfileManager::CleanupMemory(void) +void CProfileManager::CleanupMemory(void) { - for (int i=0;i= BT_QUICKPROF_MAX_THREAD_COUNT) + if ((threadIndex < 0) || threadIndex >= BT_QUICKPROF_MAX_THREAD_COUNT) return; - if (name != gCurrentNodes[threadIndex]->Get_Name()) { - gCurrentNodes[threadIndex] = gCurrentNodes[threadIndex]->Get_Sub_Node( name ); + if (name != gCurrentNodes[threadIndex]->Get_Name()) + { + gCurrentNodes[threadIndex] = gCurrentNodes[threadIndex]->Get_Sub_Node(name); } gCurrentNodes[threadIndex]->Call(); } - /*********************************************************************************************** * CProfileManager::Stop_Profile -- Stop timing and record the results. * *=============================================================================================*/ -void CProfileManager::Stop_Profile( void ) +void CProfileManager::Stop_Profile(void) { int threadIndex = btQuickprofGetCurrentThreadIndex2(); - if ((threadIndex<0) || threadIndex >= BT_QUICKPROF_MAX_THREAD_COUNT) + if ((threadIndex < 0) || threadIndex >= BT_QUICKPROF_MAX_THREAD_COUNT) return; // Return will indicate whether we should back up to our parent (we may // be profiling a recursive function) - if (gCurrentNodes[threadIndex]->Return()) { + if (gCurrentNodes[threadIndex]->Return()) + { gCurrentNodes[threadIndex] = gCurrentNodes[threadIndex]->Get_Parent(); } } - - - - - /*********************************************************************************************** * CProfileManager::Reset -- Reset the contents of the profiling system * * * * This resets everything except for the tree structure. All of the timing data is reset. * *=============================================================================================*/ -void CProfileManager::Reset( void ) +void CProfileManager::Reset(void) { gProfileClock.reset(); int threadIndex = btQuickprofGetCurrentThreadIndex2(); - if ((threadIndex<0) || threadIndex >= BT_QUICKPROF_MAX_THREAD_COUNT) + if ((threadIndex < 0) || threadIndex >= BT_QUICKPROF_MAX_THREAD_COUNT) return; gRoots[threadIndex].Reset(); gRoots[threadIndex].Call(); @@ -598,20 +616,18 @@ void CProfileManager::Reset( void ) Profile_Get_Ticks(&ResetTime); } - /*********************************************************************************************** * CProfileManager::Increment_Frame_Counter -- Increment the frame counter * *=============================================================================================*/ -void CProfileManager::Increment_Frame_Counter( void ) +void CProfileManager::Increment_Frame_Counter(void) { FrameCounter++; } - /*********************************************************************************************** * CProfileManager::Get_Time_Since_Reset -- returns the elapsed time since last reset * *=============================================================================================*/ -float CProfileManager::Get_Time_Since_Reset( void ) +float CProfileManager::Get_Time_Since_Reset(void) { unsigned long int time; Profile_Get_Ticks(&time); @@ -621,34 +637,34 @@ float CProfileManager::Get_Time_Since_Reset( void ) #include -void CProfileManager::dumpRecursive(CProfileIterator* profileIterator, int spacing) +void CProfileManager::dumpRecursive(CProfileIterator* profileIterator, int spacing) { profileIterator->First(); if (profileIterator->Is_Done()) return; - float accumulated_time=0,parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time(); + float accumulated_time = 0, parent_time = profileIterator->Is_Root() ? CProfileManager::Get_Time_Since_Reset() : profileIterator->Get_Current_Parent_Total_Time(); int i; int frames_since_reset = CProfileManager::Get_Frame_Count_Since_Reset(); - for (i=0;iGet_Current_Parent_Name(), parent_time ); + for (i = 0; i < spacing; i++) printf("."); + printf("Profiling: %s (total running time: %.3f ms) ---\n", profileIterator->Get_Current_Parent_Name(), parent_time); float totalTime = 0.f; - int numChildren = 0; - for (i = 0; !profileIterator->Is_Done(); i++,profileIterator->Next()) + for (i = 0; !profileIterator->Is_Done(); i++, profileIterator->Next()) { numChildren++; float current_total_time = profileIterator->Get_Current_Total_Time(); accumulated_time += current_total_time; float fraction = parent_time > SIMD_EPSILON ? (current_total_time / parent_time) * 100 : 0.f; { - int i; for (i=0;iGet_Current_Name(), fraction,(current_total_time / (double)frames_since_reset),profileIterator->Get_Current_Total_Calls()); + printf("%d -- %s (%.2f %%) :: %.3f ms / frame (%d calls)\n", i, profileIterator->Get_Current_Name(), fraction, (current_total_time / (double)frames_since_reset), profileIterator->Get_Current_Total_Calls()); totalTime += current_total_time; //recurse into children } @@ -657,25 +673,23 @@ void CProfileManager::dumpRecursive(CProfileIterator* profileIterator, int spaci { //printf("what's wrong\n"); } - for (i=0;i SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time); + for (i = 0; i < spacing; i++) printf("."); + printf("%s (%.3f %%) :: %.3f ms\n", "Unaccounted:", parent_time > SIMD_EPSILON ? ((parent_time - accumulated_time) / parent_time) * 100 : 0.f, parent_time - accumulated_time); - for (i=0;iEnter_Child(i); - dumpRecursive(profileIterator,spacing+3); + dumpRecursive(profileIterator, spacing + 3); profileIterator->Enter_Parent(); } } - - -void CProfileManager::dumpAll() +void CProfileManager::dumpAll() { CProfileIterator* profileIterator = 0; profileIterator = CProfileManager::Get_Iterator(); - dumpRecursive(profileIterator,0); + dumpRecursive(profileIterator, 0); CProfileManager::Release_Iterator(profileIterator); } @@ -703,50 +717,47 @@ void CProfileManager::dumpAll() #endif // defined(__ANDROID__) && defined(__clang__) // clang-format on -unsigned int btQuickprofGetCurrentThreadIndex2() { - const unsigned int kNullIndex = ~0U; +unsigned int btQuickprofGetCurrentThreadIndex2() +{ + const unsigned int kNullIndex = ~0U; #if BT_THREADSAFE - return btGetCurrentThreadIndex(); + return btGetCurrentThreadIndex(); #else #if defined(BT_HAVE_TLS) - static __thread unsigned int sThreadIndex = kNullIndex; + static __thread unsigned int sThreadIndex = kNullIndex; #elif defined(_WIN32) - __declspec(thread) static unsigned int sThreadIndex = kNullIndex; + __declspec(thread) static unsigned int sThreadIndex = kNullIndex; #else - unsigned int sThreadIndex = 0; - return -1; + unsigned int sThreadIndex = 0; + return -1; #endif - static int gThreadCounter = 0; + static int gThreadCounter = 0; - if (sThreadIndex == kNullIndex) { - sThreadIndex = gThreadCounter++; - } - return sThreadIndex; -#endif //BT_THREADSAFE + if (sThreadIndex == kNullIndex) + { + sThreadIndex = gThreadCounter++; + } + return sThreadIndex; +#endif //BT_THREADSAFE } -void btEnterProfileZoneDefault(const char* name) +void btEnterProfileZoneDefault(const char* name) { } -void btLeaveProfileZoneDefault() +void btLeaveProfileZoneDefault() { } - #else -void btEnterProfileZoneDefault(const char* name) +void btEnterProfileZoneDefault(const char* name) { } -void btLeaveProfileZoneDefault() +void btLeaveProfileZoneDefault() { } -#endif //BT_NO_PROFILE - - - - +#endif //BT_NO_PROFILE static btEnterProfileZoneFunc* bts_enterFunc = btEnterProfileZoneDefault; static btLeaveProfileZoneFunc* bts_leaveFunc = btLeaveProfileZoneDefault; @@ -762,14 +773,13 @@ void btLeaveProfileZone() btEnterProfileZoneFunc* btGetCurrentEnterProfileZoneFunc() { - return bts_enterFunc ; + return bts_enterFunc; } btLeaveProfileZoneFunc* btGetCurrentLeaveProfileZoneFunc() { return bts_leaveFunc; } - void btSetCustomEnterProfileZoneFunc(btEnterProfileZoneFunc* enterFunc) { bts_enterFunc = enterFunc; @@ -779,13 +789,12 @@ void btSetCustomLeaveProfileZoneFunc(btLeaveProfileZoneFunc* leaveFunc) bts_leaveFunc = leaveFunc; } -CProfileSample::CProfileSample( const char * name ) -{ +CProfileSample::CProfileSample(const char* name) +{ btEnterProfileZone(name); } -CProfileSample::~CProfileSample( void ) -{ +CProfileSample::~CProfileSample(void) +{ btLeaveProfileZone(); } - diff --git a/src/LinearMath/btQuickprof.h b/src/LinearMath/btQuickprof.h index 98a267577..18ba4d5fb 100644 --- a/src/LinearMath/btQuickprof.h +++ b/src/LinearMath/btQuickprof.h @@ -7,11 +7,9 @@ ** ***************************************************************************************************/ -// Credits: The Clock class was inspired by the Timer classes in +// Credits: The Clock class was inspired by the Timer classes in // Ogre (www.ogre3d.org). - - #ifndef BT_QUICK_PROF_H #define BT_QUICK_PROF_H @@ -34,97 +32,87 @@ public: /// Resets the initial reference time. void reset(); - /// Returns the time in ms since the last call to reset or since + /// Returns the time in ms since the last call to reset or since /// the btClock was created. unsigned long long int getTimeMilliseconds(); - /// Returns the time in us since the last call to reset or since + /// Returns the time in us since the last call to reset or since /// the Clock was created. unsigned long long int getTimeMicroseconds(); - + unsigned long long int getTimeNanoseconds(); - /// Returns the time in s since the last call to reset or since + /// Returns the time in s since the last call to reset or since /// the Clock was created. btScalar getTimeSeconds(); - + private: struct btClockData* m_data; }; -#endif //USE_BT_CLOCK +#endif //USE_BT_CLOCK -typedef void (btEnterProfileZoneFunc)(const char* msg); -typedef void (btLeaveProfileZoneFunc)(); +typedef void(btEnterProfileZoneFunc)(const char* msg); +typedef void(btLeaveProfileZoneFunc)(); btEnterProfileZoneFunc* btGetCurrentEnterProfileZoneFunc(); btLeaveProfileZoneFunc* btGetCurrentLeaveProfileZoneFunc(); - - void btSetCustomEnterProfileZoneFunc(btEnterProfileZoneFunc* enterFunc); void btSetCustomLeaveProfileZoneFunc(btLeaveProfileZoneFunc* leaveFunc); -#ifndef BT_NO_PROFILE // FIX redefinition +#ifndef BT_NO_PROFILE // FIX redefinition //To disable built-in profiling, please comment out next line //#define BT_NO_PROFILE 1 -#endif //BT_NO_PROFILE +#endif //BT_NO_PROFILE const unsigned int BT_QUICKPROF_MAX_THREAD_COUNT = 64; #ifndef BT_NO_PROFILE -//btQuickprofGetCurrentThreadIndex will return -1 if thread index cannot be determined, +//btQuickprofGetCurrentThreadIndex will return -1 if thread index cannot be determined, //otherwise returns thread index in range [0..maxThreads] unsigned int btQuickprofGetCurrentThreadIndex2(); -#include //@todo remove this, backwards compatibility +#include //@todo remove this, backwards compatibility #include "btAlignedAllocator.h" #include - - - - - - - - ///A node in the Profile Hierarchy Tree -class CProfileNode { - +class CProfileNode +{ public: - CProfileNode( const char * name, CProfileNode * parent ); - ~CProfileNode( void ); + CProfileNode(const char* name, CProfileNode* parent); + ~CProfileNode(void); - CProfileNode * Get_Sub_Node( const char * name ); + CProfileNode* Get_Sub_Node(const char* name); - CProfileNode * Get_Parent( void ) { return Parent; } - CProfileNode * Get_Sibling( void ) { return Sibling; } - CProfileNode * Get_Child( void ) { return Child; } + CProfileNode* Get_Parent(void) { return Parent; } + CProfileNode* Get_Sibling(void) { return Sibling; } + CProfileNode* Get_Child(void) { return Child; } - void CleanupMemory(); - void Reset( void ); - void Call( void ); - bool Return( void ); + void CleanupMemory(); + void Reset(void); + void Call(void); + bool Return(void); + + const char* Get_Name(void) { return Name; } + int Get_Total_Calls(void) { return TotalCalls; } + float Get_Total_Time(void) { return TotalTime; } + void* GetUserPointer() const { return m_userPtr; } + void SetUserPointer(void* ptr) { m_userPtr = ptr; } - const char * Get_Name( void ) { return Name; } - int Get_Total_Calls( void ) { return TotalCalls; } - float Get_Total_Time( void ) { return TotalTime; } - void* GetUserPointer() const {return m_userPtr;} - void SetUserPointer(void* ptr) { m_userPtr = ptr;} protected: + const char* Name; + int TotalCalls; + float TotalTime; + unsigned long int StartTime; + int RecursionCounter; - const char * Name; - int TotalCalls; - float TotalTime; - unsigned long int StartTime; - int RecursionCounter; - - CProfileNode * Parent; - CProfileNode * Child; - CProfileNode * Sibling; - void* m_userPtr; + CProfileNode* Parent; + CProfileNode* Child; + CProfileNode* Sibling; + void* m_userPtr; }; ///An iterator to navigate through the tree @@ -132,91 +120,80 @@ class CProfileIterator { public: // Access all the children of the current parent - void First(void); - void Next(void); - bool Is_Done(void); - bool Is_Root(void) { return (CurrentParent->Get_Parent() == 0); } + void First(void); + void Next(void); + bool Is_Done(void); + bool Is_Root(void) { return (CurrentParent->Get_Parent() == 0); } - void Enter_Child( int index ); // Make the given child the new parent - void Enter_Largest_Child( void ); // Make the largest child the new parent - void Enter_Parent( void ); // Make the current parent's parent the new parent + void Enter_Child(int index); // Make the given child the new parent + void Enter_Largest_Child(void); // Make the largest child the new parent + void Enter_Parent(void); // Make the current parent's parent the new parent // Access the current child - const char * Get_Current_Name( void ) { return CurrentChild->Get_Name(); } - int Get_Current_Total_Calls( void ) { return CurrentChild->Get_Total_Calls(); } - float Get_Current_Total_Time( void ) { return CurrentChild->Get_Total_Time(); } + const char* Get_Current_Name(void) { return CurrentChild->Get_Name(); } + int Get_Current_Total_Calls(void) { return CurrentChild->Get_Total_Calls(); } + float Get_Current_Total_Time(void) { return CurrentChild->Get_Total_Time(); } - void* Get_Current_UserPointer( void ) { return CurrentChild->GetUserPointer(); } - void Set_Current_UserPointer(void* ptr) {CurrentChild->SetUserPointer(ptr);} + void* Get_Current_UserPointer(void) { return CurrentChild->GetUserPointer(); } + void Set_Current_UserPointer(void* ptr) { CurrentChild->SetUserPointer(ptr); } // Access the current parent - const char * Get_Current_Parent_Name( void ) { return CurrentParent->Get_Name(); } - int Get_Current_Parent_Total_Calls( void ) { return CurrentParent->Get_Total_Calls(); } - float Get_Current_Parent_Total_Time( void ) { return CurrentParent->Get_Total_Time(); } - - + const char* Get_Current_Parent_Name(void) { return CurrentParent->Get_Name(); } + int Get_Current_Parent_Total_Calls(void) { return CurrentParent->Get_Total_Calls(); } + float Get_Current_Parent_Total_Time(void) { return CurrentParent->Get_Total_Time(); } protected: + CProfileNode* CurrentParent; + CProfileNode* CurrentChild; - CProfileNode * CurrentParent; - CProfileNode * CurrentChild; - - - CProfileIterator( CProfileNode * start ); - friend class CProfileManager; + CProfileIterator(CProfileNode* start); + friend class CProfileManager; }; - ///The Manager for the Profile system -class CProfileManager { +class CProfileManager +{ public: - static void Start_Profile( const char * name ); - static void Stop_Profile( void ); + static void Start_Profile(const char* name); + static void Stop_Profile(void); - static void CleanupMemory(void); -// { -// Root.CleanupMemory(); -// } + static void CleanupMemory(void); + // { + // Root.CleanupMemory(); + // } - static void Reset( void ); - static void Increment_Frame_Counter( void ); - static int Get_Frame_Count_Since_Reset( void ) { return FrameCounter; } - static float Get_Time_Since_Reset( void ); + static void Reset(void); + static void Increment_Frame_Counter(void); + static int Get_Frame_Count_Since_Reset(void) { return FrameCounter; } + static float Get_Time_Since_Reset(void); - static CProfileIterator * Get_Iterator( void ); -// { -// -// return new CProfileIterator( &Root ); -// } - static void Release_Iterator( CProfileIterator * iterator ) { delete ( iterator); } + static CProfileIterator* Get_Iterator(void); + // { + // + // return new CProfileIterator( &Root ); + // } + static void Release_Iterator(CProfileIterator* iterator) { delete (iterator); } - static void dumpRecursive(CProfileIterator* profileIterator, int spacing); + static void dumpRecursive(CProfileIterator* profileIterator, int spacing); - static void dumpAll(); + static void dumpAll(); private: - - static int FrameCounter; - static unsigned long int ResetTime; + static int FrameCounter; + static unsigned long int ResetTime; }; - - - -#endif //#ifndef BT_NO_PROFILE +#endif //#ifndef BT_NO_PROFILE ///ProfileSampleClass is a simple way to profile a function's scope ///Use the BT_PROFILE macro at the start of scope to time -class CProfileSample { +class CProfileSample +{ public: - CProfileSample( const char * name ); + CProfileSample(const char* name); - ~CProfileSample( void ); + ~CProfileSample(void); }; -#define BT_PROFILE( name ) CProfileSample __profile( name ) - - - -#endif //BT_QUICK_PROF_H - +#define BT_PROFILE(name) CProfileSample __profile(name) +#endif //BT_QUICK_PROF_H diff --git a/src/LinearMath/btRandom.h b/src/LinearMath/btRandom.h index 4cbfc6bfe..e659af860 100644 --- a/src/LinearMath/btRandom.h +++ b/src/LinearMath/btRandom.h @@ -12,8 +12,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #ifndef BT_GEN_RANDOM_H #define BT_GEN_RANDOM_H @@ -24,8 +22,8 @@ subject to the following restrictions: #define GEN_RAND_MAX UINT_MAX -SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { init_genrand(seed); } -SIMD_FORCE_INLINE unsigned int GEN_rand() { return genrand_int32(); } +SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { init_genrand(seed); } +SIMD_FORCE_INLINE unsigned int GEN_rand() { return genrand_int32(); } #else @@ -33,10 +31,9 @@ SIMD_FORCE_INLINE unsigned int GEN_rand() { return genrand_int #define GEN_RAND_MAX RAND_MAX -SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { srand(seed); } -SIMD_FORCE_INLINE unsigned int GEN_rand() { return rand(); } +SIMD_FORCE_INLINE void GEN_srand(unsigned int seed) { srand(seed); } +SIMD_FORCE_INLINE unsigned int GEN_rand() { return rand(); } #endif -#endif //BT_GEN_RANDOM_H - +#endif //BT_GEN_RANDOM_H diff --git a/src/LinearMath/btScalar.h b/src/LinearMath/btScalar.h index 24e8454c1..c198bd4b3 100644 --- a/src/LinearMath/btScalar.h +++ b/src/LinearMath/btScalar.h @@ -32,7 +32,6 @@ inline int btGetVersion() return BT_BULLET_VERSION; } - // The following macro "BT_NOT_EMPTY_FILE" can be put into a file // in order suppress the MS Visual C++ Linker warning 4221 // @@ -44,16 +43,19 @@ inline int btGetVersion() // // see more https://stackoverflow.com/questions/1822887/what-is-the-best-way-to-eliminate-ms-visual-c-linker-warning-warning-lnk422 -#if defined (_MSC_VER) - #define BT_NOT_EMPTY_FILE_CAT_II(p, res) res - #define BT_NOT_EMPTY_FILE_CAT_I(a, b) BT_NOT_EMPTY_FILE_CAT_II(~, a ## b) - #define BT_NOT_EMPTY_FILE_CAT(a, b) BT_NOT_EMPTY_FILE_CAT_I(a, b) - #define BT_NOT_EMPTY_FILE namespace { char BT_NOT_EMPTY_FILE_CAT(NoEmptyFileDummy, __COUNTER__); } +#if defined(_MSC_VER) +#define BT_NOT_EMPTY_FILE_CAT_II(p, res) res +#define BT_NOT_EMPTY_FILE_CAT_I(a, b) BT_NOT_EMPTY_FILE_CAT_II(~, a##b) +#define BT_NOT_EMPTY_FILE_CAT(a, b) BT_NOT_EMPTY_FILE_CAT_I(a, b) +#define BT_NOT_EMPTY_FILE \ + namespace \ + { \ + char BT_NOT_EMPTY_FILE_CAT(NoEmptyFileDummy, __COUNTER__); \ + } #else - #define BT_NOT_EMPTY_FILE +#define BT_NOT_EMPTY_FILE #endif - // clang and most formatting tools don't support indentation of preprocessor guards, so turn it off // clang-format off #if defined(DEBUG) || defined (_DEBUG) diff --git a/src/LinearMath/btSerializer.cpp b/src/LinearMath/btSerializer.cpp index 4faa8f536..18683c8fa 100644 --- a/src/LinearMath/btSerializer.cpp +++ b/src/LinearMath/btSerializer.cpp @@ -1,3 +1,4 @@ +// clang-format off char sBulletDNAstr[]= { char(83),char(68),char(78),char(65),char(78),char(65),char(77),char(69),char(-76),char(1),char(0),char(0),char(109),char(95),char(115),char(105),char(122),char(101),char(0),char(109), char(95),char(99),char(97),char(112),char(97),char(99),char(105),char(116),char(121),char(0),char(42),char(109),char(95),char(100),char(97),char(116),char(97),char(0),char(109),char(95), @@ -687,3 +688,5 @@ char(97),char(0),char(4),char(0),char(50),char(0),char(-79),char(1),char(96),cha char(98),char(0),char(4),char(0),char(48),char(0),char(-79),char(1),char(95),char(0),char(-78),char(1),char(4),char(0),char(-77),char(1),char(0),char(0),char(37),char(0), }; int sBulletDNAlen= sizeof(sBulletDNAstr); + +// clang-format on diff --git a/src/LinearMath/btSerializer.h b/src/LinearMath/btSerializer.h index 39be3f810..ba3444161 100644 --- a/src/LinearMath/btSerializer.h +++ b/src/LinearMath/btSerializer.h @@ -16,49 +16,45 @@ subject to the following restrictions: #ifndef BT_SERIALIZER_H #define BT_SERIALIZER_H -#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE +#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE #include "btHashMap.h" -#if !defined( __CELLOS_LV2__) && !defined(__MWERKS__) +#if !defined(__CELLOS_LV2__) && !defined(__MWERKS__) #include #endif #include - - - extern char sBulletDNAstr[]; extern int sBulletDNAlen; extern char sBulletDNAstr64[]; extern int sBulletDNAlen64; -SIMD_FORCE_INLINE int btStrLen(const char* str) +SIMD_FORCE_INLINE int btStrLen(const char* str) { - if (!str) - return(0); + if (!str) + return (0); int len = 0; while (*str != 0) { - str++; - len++; - } + str++; + len++; + } - return len; + return len; } - class btChunk { public: - int m_chunkCode; - int m_length; - void *m_oldPtr; - int m_dna_nr; - int m_number; + int m_chunkCode; + int m_length; + void* m_oldPtr; + int m_dna_nr; + int m_number; }; -enum btSerializationFlags +enum btSerializationFlags { BT_SERIALIZE_NO_BVH = 1, BT_SERIALIZE_NO_TRIANGLEINFOMAP = 2, @@ -66,78 +62,71 @@ enum btSerializationFlags BT_SERIALIZE_CONTACT_MANIFOLDS = 8, }; -class btSerializer +class btSerializer { - public: - virtual ~btSerializer() {} - virtual const unsigned char* getBufferPointer() const = 0; + virtual const unsigned char* getBufferPointer() const = 0; - virtual int getCurrentBufferSize() const = 0; + virtual int getCurrentBufferSize() const = 0; - virtual btChunk* allocate(size_t size, int numElements) = 0; + virtual btChunk* allocate(size_t size, int numElements) = 0; - virtual void finalizeChunk(btChunk* chunk, const char* structType, int chunkCode,void* oldPtr)= 0; + virtual void finalizeChunk(btChunk* chunk, const char* structType, int chunkCode, void* oldPtr) = 0; - virtual void* findPointer(void* oldPtr) = 0; + virtual void* findPointer(void* oldPtr) = 0; - virtual void* getUniquePointer(void*oldPtr) = 0; + virtual void* getUniquePointer(void* oldPtr) = 0; - virtual void startSerialization() = 0; + virtual void startSerialization() = 0; - virtual void finishSerialization() = 0; + virtual void finishSerialization() = 0; - virtual const char* findNameForPointer(const void* ptr) const = 0; + virtual const char* findNameForPointer(const void* ptr) const = 0; - virtual void registerNameForPointer(const void* ptr, const char* name) = 0; + virtual void registerNameForPointer(const void* ptr, const char* name) = 0; - virtual void serializeName(const char* ptr) = 0; + virtual void serializeName(const char* ptr) = 0; - virtual int getSerializationFlags() const = 0; + virtual int getSerializationFlags() const = 0; - virtual void setSerializationFlags(int flags) = 0; + virtual void setSerializationFlags(int flags) = 0; virtual int getNumChunks() const = 0; virtual const btChunk* getChunk(int chunkIndex) const = 0; - }; - - #define BT_HEADER_LENGTH 12 -#if defined(__sgi) || defined (__sparc) || defined (__sparc__) || defined (__PPC__) || defined (__ppc__) || defined (__BIG_ENDIAN__) -# define BT_MAKE_ID(a,b,c,d) ( (int)(a)<<24 | (int)(b)<<16 | (c)<<8 | (d) ) +#if defined(__sgi) || defined(__sparc) || defined(__sparc__) || defined(__PPC__) || defined(__ppc__) || defined(__BIG_ENDIAN__) +#define BT_MAKE_ID(a, b, c, d) ((int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d)) #else -# define BT_MAKE_ID(a,b,c,d) ( (int)(d)<<24 | (int)(c)<<16 | (b)<<8 | (a) ) +#define BT_MAKE_ID(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a)) #endif +#define BT_MULTIBODY_CODE BT_MAKE_ID('M', 'B', 'D', 'Y') +#define BT_MB_LINKCOLLIDER_CODE BT_MAKE_ID('M', 'B', 'L', 'C') +#define BT_SOFTBODY_CODE BT_MAKE_ID('S', 'B', 'D', 'Y') +#define BT_COLLISIONOBJECT_CODE BT_MAKE_ID('C', 'O', 'B', 'J') +#define BT_RIGIDBODY_CODE BT_MAKE_ID('R', 'B', 'D', 'Y') +#define BT_CONSTRAINT_CODE BT_MAKE_ID('C', 'O', 'N', 'S') +#define BT_BOXSHAPE_CODE BT_MAKE_ID('B', 'O', 'X', 'S') +#define BT_QUANTIZED_BVH_CODE BT_MAKE_ID('Q', 'B', 'V', 'H') +#define BT_TRIANLGE_INFO_MAP BT_MAKE_ID('T', 'M', 'A', 'P') +#define BT_SHAPE_CODE BT_MAKE_ID('S', 'H', 'A', 'P') +#define BT_ARRAY_CODE BT_MAKE_ID('A', 'R', 'A', 'Y') +#define BT_SBMATERIAL_CODE BT_MAKE_ID('S', 'B', 'M', 'T') +#define BT_SBNODE_CODE BT_MAKE_ID('S', 'B', 'N', 'D') +#define BT_DYNAMICSWORLD_CODE BT_MAKE_ID('D', 'W', 'L', 'D') +#define BT_CONTACTMANIFOLD_CODE BT_MAKE_ID('C', 'O', 'N', 'T') +#define BT_DNA_CODE BT_MAKE_ID('D', 'N', 'A', '1') -#define BT_MULTIBODY_CODE BT_MAKE_ID('M','B','D','Y') -#define BT_MB_LINKCOLLIDER_CODE BT_MAKE_ID('M','B','L','C') -#define BT_SOFTBODY_CODE BT_MAKE_ID('S','B','D','Y') -#define BT_COLLISIONOBJECT_CODE BT_MAKE_ID('C','O','B','J') -#define BT_RIGIDBODY_CODE BT_MAKE_ID('R','B','D','Y') -#define BT_CONSTRAINT_CODE BT_MAKE_ID('C','O','N','S') -#define BT_BOXSHAPE_CODE BT_MAKE_ID('B','O','X','S') -#define BT_QUANTIZED_BVH_CODE BT_MAKE_ID('Q','B','V','H') -#define BT_TRIANLGE_INFO_MAP BT_MAKE_ID('T','M','A','P') -#define BT_SHAPE_CODE BT_MAKE_ID('S','H','A','P') -#define BT_ARRAY_CODE BT_MAKE_ID('A','R','A','Y') -#define BT_SBMATERIAL_CODE BT_MAKE_ID('S','B','M','T') -#define BT_SBNODE_CODE BT_MAKE_ID('S','B','N','D') -#define BT_DYNAMICSWORLD_CODE BT_MAKE_ID('D','W','L','D') -#define BT_CONTACTMANIFOLD_CODE BT_MAKE_ID('C','O','N','T') -#define BT_DNA_CODE BT_MAKE_ID('D','N','A','1') - -struct btPointerUid +struct btPointerUid { - union - { - void* m_ptr; - int m_uniqueIds[2]; + union { + void* m_ptr; + int m_uniqueIds[2]; }; }; @@ -146,8 +135,8 @@ struct btBulletSerializedArrays btBulletSerializedArrays() { } - btAlignedObjectArray m_bvhsDouble; - btAlignedObjectArray m_bvhsFloat; + btAlignedObjectArray m_bvhsDouble; + btAlignedObjectArray m_bvhsFloat; btAlignedObjectArray m_colShapeData; btAlignedObjectArray m_dynamicWorldInfoDataDouble; btAlignedObjectArray m_dynamicWorldInfoDataFloat; @@ -157,51 +146,42 @@ struct btBulletSerializedArrays btAlignedObjectArray m_collisionObjectDataFloat; btAlignedObjectArray m_constraintDataFloat; btAlignedObjectArray m_constraintDataDouble; - btAlignedObjectArray m_constraintData;//for backwards compatibility + btAlignedObjectArray m_constraintData; //for backwards compatibility btAlignedObjectArray m_softBodyFloatData; btAlignedObjectArray m_softBodyDoubleData; - }; - ///The btDefaultSerializer is the main Bullet serialization class. ///The constructor takes an optional argument for backwards compatibility, it is recommended to leave this empty/zero. -class btDefaultSerializer : public btSerializer +class btDefaultSerializer : public btSerializer { +protected: + btAlignedObjectArray mTypes; + btAlignedObjectArray mStructs; + btAlignedObjectArray mTlens; + btHashMap mStructReverse; + btHashMap mTypeLookup; + + btHashMap m_chunkP; + + btHashMap m_nameMap; + + btHashMap m_uniquePointers; + int m_uniqueIdGenerator; + + int m_totalSize; + unsigned char* m_buffer; + bool m_ownsBuffer; + int m_currentSize; + void* m_dna; + int m_dnaLength; + + int m_serializationFlags; + + btAlignedObjectArray m_chunkPtrs; protected: - - btAlignedObjectArray mTypes; - btAlignedObjectArray mStructs; - btAlignedObjectArray mTlens; - btHashMap mStructReverse; - btHashMap mTypeLookup; - - - - btHashMap m_chunkP; - - btHashMap m_nameMap; - - btHashMap m_uniquePointers; - int m_uniqueIdGenerator; - - int m_totalSize; - unsigned char* m_buffer; - bool m_ownsBuffer; - int m_currentSize; - void* m_dna; - int m_dnaLength; - - int m_serializationFlags; - - - btAlignedObjectArray m_chunkPtrs; - -protected: - - - virtual void* findPointer(void* oldPtr) + virtual void* findPointer(void* oldPtr) { void** ptr = m_chunkP.find(oldPtr); if (ptr && *ptr) @@ -209,48 +189,43 @@ protected: return 0; } + virtual void writeDNA() + { + btChunk* dnaChunk = allocate(m_dnaLength, 1); + memcpy(dnaChunk->m_oldPtr, m_dna, m_dnaLength); + finalizeChunk(dnaChunk, "DNA1", BT_DNA_CODE, m_dna); + } + int getReverseType(const char* type) const + { + btHashString key(type); + const int* valuePtr = mTypeLookup.find(key); + if (valuePtr) + return *valuePtr; + return -1; + } + void initDNA(const char* bdnaOrg, int dnalen) + { + ///was already initialized + if (m_dna) + return; - virtual void writeDNA() - { - btChunk* dnaChunk = allocate(m_dnaLength,1); - memcpy(dnaChunk->m_oldPtr,m_dna,m_dnaLength); - finalizeChunk(dnaChunk,"DNA1",BT_DNA_CODE, m_dna); - } + int littleEndian = 1; + littleEndian = ((char*)&littleEndian)[0]; - int getReverseType(const char *type) const - { + m_dna = btAlignedAlloc(dnalen, 16); + memcpy(m_dna, bdnaOrg, dnalen); + m_dnaLength = dnalen; - btHashString key(type); - const int* valuePtr = mTypeLookup.find(key); - if (valuePtr) - return *valuePtr; + int* intPtr = 0; + short* shtPtr = 0; + char* cp = 0; + int dataLen = 0; + intPtr = (int*)m_dna; - return -1; - } - - void initDNA(const char* bdnaOrg,int dnalen) - { - ///was already initialized - if (m_dna) - return; - - int littleEndian= 1; - littleEndian= ((char*)&littleEndian)[0]; - - - m_dna = btAlignedAlloc(dnalen,16); - memcpy(m_dna,bdnaOrg,dnalen); - m_dnaLength = dnalen; - - int *intPtr=0; - short *shtPtr=0; - char *cp = 0;int dataLen =0; - intPtr = (int*)m_dna; - - /* + /* SDNA (4 bytes) (magic number) NAME (4 bytes) (4 bytes) amount of names (int) @@ -258,81 +233,81 @@ protected: */ - if (strncmp((const char*)m_dna, "SDNA", 4)==0) - { - // skip ++ NAME - intPtr++; intPtr++; - } - - // Parse names - if (!littleEndian) - *intPtr = btSwapEndian(*intPtr); - - dataLen = *intPtr; - + if (strncmp((const char*)m_dna, "SDNA", 4) == 0) + { + // skip ++ NAME intPtr++; + intPtr++; + } - cp = (char*)intPtr; - int i; - for ( i=0; i amount of types (int) */ - intPtr = (int*)cp; - btAssert(strncmp(cp, "TYPE", 4)==0); intPtr++; + intPtr = (int*)cp; + btAssert(strncmp(cp, "TYPE", 4) == 0); + intPtr++; - if (!littleEndian) - *intPtr = btSwapEndian(*intPtr); + if (!littleEndian) + *intPtr = btSwapEndian(*intPtr); - dataLen = *intPtr; - intPtr++; + dataLen = *intPtr; + intPtr++; + cp = (char*)intPtr; + for (i = 0; i < dataLen; i++) + { + mTypes.push_back(cp); + while (*cp) cp++; + cp++; + } - cp = (char*)intPtr; - for (i=0; i (short) the lengths of types */ - // Parse type lens - intPtr = (int*)cp; - btAssert(strncmp(cp, "TLEN", 4)==0); intPtr++; + // Parse type lens + intPtr = (int*)cp; + btAssert(strncmp(cp, "TLEN", 4) == 0); + intPtr++; - dataLen = (int)mTypes.size(); + dataLen = (int)mTypes.size(); - shtPtr = (short*)intPtr; - for (i=0; i amount of structs (int) @@ -343,384 +318,372 @@ protected: */ - intPtr = (int*)shtPtr; - cp = (char*)intPtr; - btAssert(strncmp(cp, "STRC", 4)==0); intPtr++; + intPtr = (int*)shtPtr; + cp = (char*)intPtr; + btAssert(strncmp(cp, "STRC", 4) == 0); + intPtr++; + + if (!littleEndian) + *intPtr = btSwapEndian(*intPtr); + dataLen = *intPtr; + intPtr++; + + shtPtr = (short*)intPtr; + for (i = 0; i < dataLen; i++) + { + mStructs.push_back(shtPtr); if (!littleEndian) - *intPtr = btSwapEndian(*intPtr); - dataLen = *intPtr ; - intPtr++; - - - shtPtr = (short*)intPtr; - for (i=0; i m_skipPointers; - btHashMap m_skipPointers; - - - btDefaultSerializer(int totalSize=0, unsigned char* buffer=0) - :m_uniqueIdGenerator(0), - m_totalSize(totalSize), - m_currentSize(0), - m_dna(0), - m_dnaLength(0), - m_serializationFlags(0) + btDefaultSerializer(int totalSize = 0, unsigned char* buffer = 0) + : m_uniqueIdGenerator(0), + m_totalSize(totalSize), + m_currentSize(0), + m_dna(0), + m_dnaLength(0), + m_serializationFlags(0) + { + if (buffer == 0) { - if (buffer==0) - { - m_buffer = m_totalSize?(unsigned char*)btAlignedAlloc(totalSize,16):0; - m_ownsBuffer = true; - } else - { - m_buffer = buffer; - m_ownsBuffer = false; - } + m_buffer = m_totalSize ? (unsigned char*)btAlignedAlloc(totalSize, 16) : 0; + m_ownsBuffer = true; + } + else + { + m_buffer = buffer; + m_ownsBuffer = false; + } - const bool VOID_IS_8 = ((sizeof(void*)==8)); + const bool VOID_IS_8 = ((sizeof(void*) == 8)); #ifdef BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES - if (VOID_IS_8) - { + if (VOID_IS_8) + { #if _WIN64 - initDNA((const char*)sBulletDNAstr64,sBulletDNAlen64); + initDNA((const char*)sBulletDNAstr64, sBulletDNAlen64); #else - btAssert(0); + btAssert(0); #endif - } else - { + } + else + { #ifndef _WIN64 - initDNA((const char*)sBulletDNAstr,sBulletDNAlen); + initDNA((const char*)sBulletDNAstr, sBulletDNAlen); #else - btAssert(0); + btAssert(0); #endif - } - -#else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES - if (VOID_IS_8) - { - initDNA((const char*)sBulletDNAstr64,sBulletDNAlen64); - } else - { - initDNA((const char*)sBulletDNAstr,sBulletDNAlen); - } -#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES - } - virtual ~btDefaultSerializer() +#else //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES + if (VOID_IS_8) { - if (m_buffer && m_ownsBuffer) - btAlignedFree(m_buffer); - if (m_dna) - btAlignedFree(m_dna); + initDNA((const char*)sBulletDNAstr64, sBulletDNAlen64); } - - static int getMemoryDnaSizeInBytes() + else { - const bool VOID_IS_8 = ((sizeof(void*) == 8)); - - if (VOID_IS_8) - { - return sBulletDNAlen64; - } - return sBulletDNAlen; + initDNA((const char*)sBulletDNAstr, sBulletDNAlen); } - static const char* getMemoryDna() +#endif //BT_INTERNAL_UPDATE_SERIALIZATION_STRUCTURES + } + + virtual ~btDefaultSerializer() + { + if (m_buffer && m_ownsBuffer) + btAlignedFree(m_buffer); + if (m_dna) + btAlignedFree(m_dna); + } + + static int getMemoryDnaSizeInBytes() + { + const bool VOID_IS_8 = ((sizeof(void*) == 8)); + + if (VOID_IS_8) { - const bool VOID_IS_8 = ((sizeof(void*) == 8)); - if (VOID_IS_8) - { - return (const char*)sBulletDNAstr64; - } - return (const char*)sBulletDNAstr; + return sBulletDNAlen64; } - - void insertHeader() + return sBulletDNAlen; + } + static const char* getMemoryDna() + { + const bool VOID_IS_8 = ((sizeof(void*) == 8)); + if (VOID_IS_8) { - writeHeader(m_buffer); - m_currentSize += BT_HEADER_LENGTH; + return (const char*)sBulletDNAstr64; } + return (const char*)sBulletDNAstr; + } - void writeHeader(unsigned char* buffer) const - { + void insertHeader() + { + writeHeader(m_buffer); + m_currentSize += BT_HEADER_LENGTH; + } - -#ifdef BT_USE_DOUBLE_PRECISION - memcpy(buffer, "BULLETd", 7); + void writeHeader(unsigned char* buffer) const + { +#ifdef BT_USE_DOUBLE_PRECISION + memcpy(buffer, "BULLETd", 7); #else - memcpy(buffer, "BULLETf", 7); -#endif //BT_USE_DOUBLE_PRECISION + memcpy(buffer, "BULLETf", 7); +#endif //BT_USE_DOUBLE_PRECISION - int littleEndian= 1; - littleEndian= ((char*)&littleEndian)[0]; + int littleEndian = 1; + littleEndian = ((char*)&littleEndian)[0]; - if (sizeof(void*)==8) + if (sizeof(void*) == 8) + { + buffer[7] = '-'; + } + else + { + buffer[7] = '_'; + } + + if (littleEndian) + { + buffer[8] = 'v'; + } + else + { + buffer[8] = 'V'; + } + + buffer[9] = '2'; + buffer[10] = '8'; + buffer[11] = '8'; + } + + virtual void startSerialization() + { + m_uniqueIdGenerator = 1; + if (m_totalSize) + { + unsigned char* buffer = internalAlloc(BT_HEADER_LENGTH); + writeHeader(buffer); + } + } + + virtual void finishSerialization() + { + writeDNA(); + + //if we didn't pre-allocate a buffer, we need to create a contiguous buffer now + int mysize = 0; + if (!m_totalSize) + { + if (m_buffer) + btAlignedFree(m_buffer); + + m_currentSize += BT_HEADER_LENGTH; + m_buffer = (unsigned char*)btAlignedAlloc(m_currentSize, 16); + + unsigned char* currentPtr = m_buffer; + writeHeader(m_buffer); + currentPtr += BT_HEADER_LENGTH; + mysize += BT_HEADER_LENGTH; + for (int i = 0; i < m_chunkPtrs.size(); i++) { - buffer[7] = '-'; - } else - { - buffer[7] = '_'; + int curLength = sizeof(btChunk) + m_chunkPtrs[i]->m_length; + memcpy(currentPtr, m_chunkPtrs[i], curLength); + btAlignedFree(m_chunkPtrs[i]); + currentPtr += curLength; + mysize += curLength; } - - if (littleEndian) - { - buffer[8]='v'; - } else - { - buffer[8]='V'; - } - - - buffer[9] = '2'; - buffer[10] = '8'; - buffer[11] = '8'; - } - virtual void startSerialization() - { - m_uniqueIdGenerator= 1; - if (m_totalSize) - { - unsigned char* buffer = internalAlloc(BT_HEADER_LENGTH); - writeHeader(buffer); - } + mTypes.clear(); + mStructs.clear(); + mTlens.clear(); + mStructReverse.clear(); + mTypeLookup.clear(); + m_skipPointers.clear(); + m_chunkP.clear(); + m_nameMap.clear(); + m_uniquePointers.clear(); + m_chunkPtrs.clear(); + } - } - - virtual void finishSerialization() - { - writeDNA(); - - //if we didn't pre-allocate a buffer, we need to create a contiguous buffer now - int mysize = 0; - if (!m_totalSize) - { - if (m_buffer) - btAlignedFree(m_buffer); - - m_currentSize += BT_HEADER_LENGTH; - m_buffer = (unsigned char*)btAlignedAlloc(m_currentSize,16); - - unsigned char* currentPtr = m_buffer; - writeHeader(m_buffer); - currentPtr += BT_HEADER_LENGTH; - mysize+=BT_HEADER_LENGTH; - for (int i=0;i< m_chunkPtrs.size();i++) - { - int curLength = sizeof(btChunk)+m_chunkPtrs[i]->m_length; - memcpy(currentPtr,m_chunkPtrs[i], curLength); - btAlignedFree(m_chunkPtrs[i]); - currentPtr+=curLength; - mysize+=curLength; - } - } - - mTypes.clear(); - mStructs.clear(); - mTlens.clear(); - mStructReverse.clear(); - mTypeLookup.clear(); - m_skipPointers.clear(); - m_chunkP.clear(); - m_nameMap.clear(); - m_uniquePointers.clear(); - m_chunkPtrs.clear(); - } - - virtual void* getUniquePointer(void*oldPtr) - { - btAssert(m_uniqueIdGenerator >= 0); - if (!oldPtr) - return 0; - - btPointerUid* uptr = (btPointerUid*)m_uniquePointers.find(oldPtr); - if (uptr) - { - return uptr->m_ptr; - } - - void** ptr2 = m_skipPointers[oldPtr]; - if (ptr2) - { - return 0; - } - - m_uniqueIdGenerator++; - - btPointerUid uid; - uid.m_uniqueIds[0] = m_uniqueIdGenerator; - uid.m_uniqueIds[1] = m_uniqueIdGenerator; - m_uniquePointers.insert(oldPtr,uid); - return uid.m_ptr; - - } - - virtual const unsigned char* getBufferPointer() const - { - return m_buffer; - } - - virtual int getCurrentBufferSize() const - { - return m_currentSize; - } - - virtual void finalizeChunk(btChunk* chunk, const char* structType, int chunkCode,void* oldPtr) - { - if (!(m_serializationFlags&BT_SERIALIZE_NO_DUPLICATE_ASSERT)) - { - btAssert(!findPointer(oldPtr)); - } - - chunk->m_dna_nr = getReverseType(structType); - - chunk->m_chunkCode = chunkCode; - - void* uniquePtr = getUniquePointer(oldPtr); - - m_chunkP.insert(oldPtr,uniquePtr);//chunk->m_oldPtr); - chunk->m_oldPtr = uniquePtr;//oldPtr; - - } - - - virtual unsigned char* internalAlloc(size_t size) - { - unsigned char* ptr = 0; - - if (m_totalSize) - { - ptr = m_buffer+m_currentSize; - m_currentSize += int(size); - btAssert(m_currentSizem_chunkCode = 0; - chunk->m_oldPtr = data; - chunk->m_length = int(size)*numElements; - chunk->m_number = numElements; - - m_chunkPtrs.push_back(chunk); - - - return chunk; - } - - virtual const char* findNameForPointer(const void* ptr) const - { - const char*const * namePtr = m_nameMap.find(ptr); - if (namePtr && *namePtr) - return *namePtr; + virtual void* getUniquePointer(void* oldPtr) + { + btAssert(m_uniqueIdGenerator >= 0); + if (!oldPtr) return 0; + btPointerUid* uptr = (btPointerUid*)m_uniquePointers.find(oldPtr); + if (uptr) + { + return uptr->m_ptr; } - virtual void registerNameForPointer(const void* ptr, const char* name) + void** ptr2 = m_skipPointers[oldPtr]; + if (ptr2) { - m_nameMap.insert(ptr,name); + return 0; } - virtual void serializeName(const char* name) + m_uniqueIdGenerator++; + + btPointerUid uid; + uid.m_uniqueIds[0] = m_uniqueIdGenerator; + uid.m_uniqueIds[1] = m_uniqueIdGenerator; + m_uniquePointers.insert(oldPtr, uid); + return uid.m_ptr; + } + + virtual const unsigned char* getBufferPointer() const + { + return m_buffer; + } + + virtual int getCurrentBufferSize() const + { + return m_currentSize; + } + + virtual void finalizeChunk(btChunk* chunk, const char* structType, int chunkCode, void* oldPtr) + { + if (!(m_serializationFlags & BT_SERIALIZE_NO_DUPLICATE_ASSERT)) { - if (name) + btAssert(!findPointer(oldPtr)); + } + + chunk->m_dna_nr = getReverseType(structType); + + chunk->m_chunkCode = chunkCode; + + void* uniquePtr = getUniquePointer(oldPtr); + + m_chunkP.insert(oldPtr, uniquePtr); //chunk->m_oldPtr); + chunk->m_oldPtr = uniquePtr; //oldPtr; + } + + virtual unsigned char* internalAlloc(size_t size) + { + unsigned char* ptr = 0; + + if (m_totalSize) + { + ptr = m_buffer + m_currentSize; + m_currentSize += int(size); + btAssert(m_currentSize < m_totalSize); + } + else + { + ptr = (unsigned char*)btAlignedAlloc(size, 16); + m_currentSize += int(size); + } + return ptr; + } + + virtual btChunk* allocate(size_t size, int numElements) + { + unsigned char* ptr = internalAlloc(int(size) * numElements + sizeof(btChunk)); + + unsigned char* data = ptr + sizeof(btChunk); + + btChunk* chunk = (btChunk*)ptr; + chunk->m_chunkCode = 0; + chunk->m_oldPtr = data; + chunk->m_length = int(size) * numElements; + chunk->m_number = numElements; + + m_chunkPtrs.push_back(chunk); + + return chunk; + } + + virtual const char* findNameForPointer(const void* ptr) const + { + const char* const* namePtr = m_nameMap.find(ptr); + if (namePtr && *namePtr) + return *namePtr; + return 0; + } + + virtual void registerNameForPointer(const void* ptr, const char* name) + { + m_nameMap.insert(ptr, name); + } + + virtual void serializeName(const char* name) + { + if (name) + { + //don't serialize name twice + if (findPointer((void*)name)) + return; + + int len = btStrLen(name); + if (len) { - //don't serialize name twice - if (findPointer((void*)name)) - return; + int newLen = len + 1; + int padding = ((newLen + 3) & ~3) - newLen; + newLen += padding; - int len = btStrLen(name); - if (len) + //serialize name string now + btChunk* chunk = allocate(sizeof(char), newLen); + char* destinationName = (char*)chunk->m_oldPtr; + for (int i = 0; i < len; i++) { - - int newLen = len+1; - int padding = ((newLen+3)&~3)-newLen; - newLen += padding; - - //serialize name string now - btChunk* chunk = allocate(sizeof(char),newLen); - char* destinationName = (char*)chunk->m_oldPtr; - for (int i=0;i m_uid2ChunkPtr; - btHashMap m_orgPtr2UniqueDataPtr; - btHashMap m_names2Ptr; - + btHashMap m_uid2ChunkPtr; + btHashMap m_orgPtr2UniqueDataPtr; + btHashMap m_names2Ptr; - btBulletSerializedArrays m_arrays; + btBulletSerializedArrays m_arrays; - btInMemorySerializer(int totalSize=0, unsigned char* buffer=0) - :btDefaultSerializer(totalSize,buffer) - { - - } + btInMemorySerializer(int totalSize = 0, unsigned char* buffer = 0) + : btDefaultSerializer(totalSize, buffer) + { + } - virtual void startSerialization() - { - m_uid2ChunkPtr.clear(); - //todo: m_arrays.clear(); - btDefaultSerializer::startSerialization(); - } + virtual void startSerialization() + { + m_uid2ChunkPtr.clear(); + //todo: m_arrays.clear(); + btDefaultSerializer::startSerialization(); + } - + btChunk* findChunkFromUniquePointer(void* uniquePointer) + { + btChunk** chkPtr = m_uid2ChunkPtr[uniquePointer]; + if (chkPtr) + { + return *chkPtr; + } + return 0; + } - btChunk* findChunkFromUniquePointer(void* uniquePointer) - { - btChunk** chkPtr = m_uid2ChunkPtr[uniquePointer]; - if (chkPtr) - { - return *chkPtr; - } - return 0; - } + virtual void registerNameForPointer(const void* ptr, const char* name) + { + btDefaultSerializer::registerNameForPointer(ptr, name); + m_names2Ptr.insert(name, ptr); + } - virtual void registerNameForPointer(const void* ptr, const char* name) - { - btDefaultSerializer::registerNameForPointer(ptr,name); - m_names2Ptr.insert(name,ptr); - } + virtual void finishSerialization() + { + } - virtual void finishSerialization() - { - } + virtual void* getUniquePointer(void* oldPtr) + { + if (oldPtr == 0) + return 0; - virtual void* getUniquePointer(void*oldPtr) - { - if (oldPtr==0) - return 0; - - // void* uniquePtr = getUniquePointer(oldPtr); - btChunk* chunk = findChunkFromUniquePointer(oldPtr); - if (chunk) - { - return chunk->m_oldPtr; - } else - { - const char* n = (const char*) oldPtr; - const void** ptr = m_names2Ptr[n]; - if (ptr) - { - return oldPtr; - } else - { - void** ptr2 = m_skipPointers[oldPtr]; - if (ptr2) - { - return 0; - } else - { - //If this assert hit, serialization happened in the wrong order - // 'getUniquePointer' - btAssert(0); - } - - } - return 0; - } - return oldPtr; - } - - virtual void finalizeChunk(btChunk* chunk, const char* structType, int chunkCode,void* oldPtr) - { - if (!(m_serializationFlags&BT_SERIALIZE_NO_DUPLICATE_ASSERT)) - { - btAssert(!findPointer(oldPtr)); - } - - chunk->m_dna_nr = getReverseType(structType); - chunk->m_chunkCode = chunkCode; - //void* uniquePtr = getUniquePointer(oldPtr); - m_chunkP.insert(oldPtr,oldPtr);//chunk->m_oldPtr); - // chunk->m_oldPtr = uniquePtr;//oldPtr; - - void* uid = findPointer(oldPtr); - m_uid2ChunkPtr.insert(uid,chunk); - - switch (chunk->m_chunkCode) + // void* uniquePtr = getUniquePointer(oldPtr); + btChunk* chunk = findChunkFromUniquePointer(oldPtr); + if (chunk) + { + return chunk->m_oldPtr; + } + else + { + const char* n = (const char*)oldPtr; + const void** ptr = m_names2Ptr[n]; + if (ptr) { + return oldPtr; + } + else + { + void** ptr2 = m_skipPointers[oldPtr]; + if (ptr2) + { + return 0; + } + else + { + //If this assert hit, serialization happened in the wrong order + // 'getUniquePointer' + btAssert(0); + } + } + return 0; + } + return oldPtr; + } + + virtual void finalizeChunk(btChunk* chunk, const char* structType, int chunkCode, void* oldPtr) + { + if (!(m_serializationFlags & BT_SERIALIZE_NO_DUPLICATE_ASSERT)) + { + btAssert(!findPointer(oldPtr)); + } + + chunk->m_dna_nr = getReverseType(structType); + chunk->m_chunkCode = chunkCode; + //void* uniquePtr = getUniquePointer(oldPtr); + m_chunkP.insert(oldPtr, oldPtr); //chunk->m_oldPtr); + // chunk->m_oldPtr = uniquePtr;//oldPtr; + + void* uid = findPointer(oldPtr); + m_uid2ChunkPtr.insert(uid, chunk); + + switch (chunk->m_chunkCode) + { case BT_SOFTBODY_CODE: { - #ifdef BT_USE_DOUBLE_PRECISION - m_arrays.m_softBodyDoubleData.push_back((btSoftBodyDoubleData*) chunk->m_oldPtr); - #else - m_arrays.m_softBodyFloatData.push_back((btSoftBodyFloatData*) chunk->m_oldPtr); - #endif - break; - } +#ifdef BT_USE_DOUBLE_PRECISION + m_arrays.m_softBodyDoubleData.push_back((btSoftBodyDoubleData*)chunk->m_oldPtr); +#else + m_arrays.m_softBodyFloatData.push_back((btSoftBodyFloatData*)chunk->m_oldPtr); +#endif + break; + } case BT_COLLISIONOBJECT_CODE: - { - #ifdef BT_USE_DOUBLE_PRECISION - m_arrays.m_collisionObjectDataDouble.push_back((btCollisionObjectDoubleData*)chunk->m_oldPtr); - #else//BT_USE_DOUBLE_PRECISION - m_arrays.m_collisionObjectDataFloat.push_back((btCollisionObjectFloatData*)chunk->m_oldPtr); - #endif //BT_USE_DOUBLE_PRECISION - break; - } + { +#ifdef BT_USE_DOUBLE_PRECISION + m_arrays.m_collisionObjectDataDouble.push_back((btCollisionObjectDoubleData*)chunk->m_oldPtr); +#else //BT_USE_DOUBLE_PRECISION + m_arrays.m_collisionObjectDataFloat.push_back((btCollisionObjectFloatData*)chunk->m_oldPtr); +#endif //BT_USE_DOUBLE_PRECISION + break; + } case BT_RIGIDBODY_CODE: - { - #ifdef BT_USE_DOUBLE_PRECISION - m_arrays.m_rigidBodyDataDouble.push_back((btRigidBodyDoubleData*)chunk->m_oldPtr); - #else - m_arrays.m_rigidBodyDataFloat.push_back((btRigidBodyFloatData*)chunk->m_oldPtr); - #endif//BT_USE_DOUBLE_PRECISION - break; - }; + { +#ifdef BT_USE_DOUBLE_PRECISION + m_arrays.m_rigidBodyDataDouble.push_back((btRigidBodyDoubleData*)chunk->m_oldPtr); +#else + m_arrays.m_rigidBodyDataFloat.push_back((btRigidBodyFloatData*)chunk->m_oldPtr); +#endif //BT_USE_DOUBLE_PRECISION + break; + }; case BT_CONSTRAINT_CODE: - { - #ifdef BT_USE_DOUBLE_PRECISION - m_arrays.m_constraintDataDouble.push_back((btTypedConstraintDoubleData*)chunk->m_oldPtr); - #else - m_arrays.m_constraintDataFloat.push_back((btTypedConstraintFloatData*)chunk->m_oldPtr); - #endif - break; - } + { +#ifdef BT_USE_DOUBLE_PRECISION + m_arrays.m_constraintDataDouble.push_back((btTypedConstraintDoubleData*)chunk->m_oldPtr); +#else + m_arrays.m_constraintDataFloat.push_back((btTypedConstraintFloatData*)chunk->m_oldPtr); +#endif + break; + } case BT_QUANTIZED_BVH_CODE: - { - #ifdef BT_USE_DOUBLE_PRECISION - m_arrays.m_bvhsDouble.push_back((btQuantizedBvhDoubleData*) chunk->m_oldPtr); - #else - m_arrays.m_bvhsFloat.push_back((btQuantizedBvhFloatData*) chunk->m_oldPtr); - #endif - break; - } + { +#ifdef BT_USE_DOUBLE_PRECISION + m_arrays.m_bvhsDouble.push_back((btQuantizedBvhDoubleData*)chunk->m_oldPtr); +#else + m_arrays.m_bvhsFloat.push_back((btQuantizedBvhFloatData*)chunk->m_oldPtr); +#endif + break; + } case BT_SHAPE_CODE: - { - btCollisionShapeData* shapeData = (btCollisionShapeData*) chunk->m_oldPtr; - m_arrays.m_colShapeData.push_back(shapeData); - break; - } + { + btCollisionShapeData* shapeData = (btCollisionShapeData*)chunk->m_oldPtr; + m_arrays.m_colShapeData.push_back(shapeData); + break; + } case BT_TRIANLGE_INFO_MAP: case BT_ARRAY_CODE: case BT_SBMATERIAL_CODE: case BT_SBNODE_CODE: case BT_DYNAMICSWORLD_CODE: case BT_DNA_CODE: - { - break; - } + { + break; + } default: - { - } - }; - } + { + } + }; + } - int getNumChunks() const - { - return m_uid2ChunkPtr.size(); - } - - const btChunk* getChunk(int chunkIndex) const - { - return *m_uid2ChunkPtr.getAtIndex(chunkIndex); - } + int getNumChunks() const + { + return m_uid2ChunkPtr.size(); + } + const btChunk* getChunk(int chunkIndex) const + { + return *m_uid2ChunkPtr.getAtIndex(chunkIndex); + } }; -#endif //ENABLE_INMEMORY_SERIALIZER - -#endif //BT_SERIALIZER_H +#endif //ENABLE_INMEMORY_SERIALIZER +#endif //BT_SERIALIZER_H diff --git a/src/LinearMath/btSerializer64.cpp b/src/LinearMath/btSerializer64.cpp index 0aa5cbf30..cf281cdb3 100644 --- a/src/LinearMath/btSerializer64.cpp +++ b/src/LinearMath/btSerializer64.cpp @@ -1,3 +1,4 @@ +// clang-format off char sBulletDNAstr64[]= { char(83),char(68),char(78),char(65),char(78),char(65),char(77),char(69),char(-76),char(1),char(0),char(0),char(109),char(95),char(115),char(105),char(122),char(101),char(0),char(109), char(95),char(99),char(97),char(112),char(97),char(99),char(105),char(116),char(121),char(0),char(42),char(109),char(95),char(100),char(97),char(116),char(97),char(0),char(109),char(95), @@ -687,3 +688,4 @@ char(97),char(0),char(4),char(0),char(50),char(0),char(-79),char(1),char(96),cha char(98),char(0),char(4),char(0),char(48),char(0),char(-79),char(1),char(95),char(0),char(-78),char(1),char(4),char(0),char(-77),char(1),char(0),char(0),char(37),char(0), }; int sBulletDNAlen64= sizeof(sBulletDNAstr64); +// clang-format on diff --git a/src/LinearMath/btSpatialAlgebra.h b/src/LinearMath/btSpatialAlgebra.h index 8e59658bc..6ad67a108 100644 --- a/src/LinearMath/btSpatialAlgebra.h +++ b/src/LinearMath/btSpatialAlgebra.h @@ -12,18 +12,17 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ -///These spatial algebra classes are used for btMultiBody, +///These spatial algebra classes are used for btMultiBody, ///see BulletDynamics/Featherstone #ifndef BT_SPATIAL_ALGEBRA_H #define BT_SPATIAL_ALGEBRA_H - #include "btMatrix3x3.h" struct btSpatialForceVector -{ - btVector3 m_topVec, m_bottomVec; +{ + btVector3 m_topVec, m_bottomVec; // btSpatialForceVector() { setZero(); } btSpatialForceVector(const btVector3 &angular, const btVector3 &linear) : m_topVec(linear), m_bottomVec(angular) {} @@ -32,21 +31,34 @@ struct btSpatialForceVector setValue(ax, ay, az, lx, ly, lz); } // - void setVector(const btVector3 &angular, const btVector3 &linear) { m_topVec = linear; m_bottomVec = angular; } + void setVector(const btVector3 &angular, const btVector3 &linear) + { + m_topVec = linear; + m_bottomVec = angular; + } void setValue(const btScalar &ax, const btScalar &ay, const btScalar &az, const btScalar &lx, const btScalar &ly, const btScalar &lz) { - m_bottomVec.setValue(ax, ay, az); m_topVec.setValue(lx, ly, lz); + m_bottomVec.setValue(ax, ay, az); + m_topVec.setValue(lx, ly, lz); } // - void addVector(const btVector3 &angular, const btVector3 &linear) { m_topVec += linear; m_bottomVec += angular; } + void addVector(const btVector3 &angular, const btVector3 &linear) + { + m_topVec += linear; + m_bottomVec += angular; + } void addValue(const btScalar &ax, const btScalar &ay, const btScalar &az, const btScalar &lx, const btScalar &ly, const btScalar &lz) { - m_bottomVec[0] += ax; m_bottomVec[1] += ay; m_bottomVec[2] += az; - m_topVec[0] += lx; m_topVec[1] += ly; m_topVec[2] += lz; + m_bottomVec[0] += ax; + m_bottomVec[1] += ay; + m_bottomVec[2] += az; + m_topVec[0] += lx; + m_topVec[1] += ly; + m_topVec[2] += lz; } // - const btVector3 & getLinear() const { return m_topVec; } - const btVector3 & getAngular() const { return m_bottomVec; } + const btVector3 &getLinear() const { return m_topVec; } + const btVector3 &getAngular() const { return m_bottomVec; } // void setLinear(const btVector3 &linear) { m_topVec = linear; } void setAngular(const btVector3 &angular) { m_bottomVec = angular; } @@ -54,14 +66,28 @@ struct btSpatialForceVector void addAngular(const btVector3 &angular) { m_bottomVec += angular; } void addLinear(const btVector3 &linear) { m_topVec += linear; } // - void setZero() { m_topVec.setZero(); m_bottomVec.setZero(); } + void setZero() + { + m_topVec.setZero(); + m_bottomVec.setZero(); + } // - btSpatialForceVector & operator += (const btSpatialForceVector &vec) { m_topVec += vec.m_topVec; m_bottomVec += vec.m_bottomVec; return *this; } - btSpatialForceVector & operator -= (const btSpatialForceVector &vec) { m_topVec -= vec.m_topVec; m_bottomVec -= vec.m_bottomVec; return *this; } - btSpatialForceVector operator - (const btSpatialForceVector &vec) const { return btSpatialForceVector(m_bottomVec - vec.m_bottomVec, m_topVec - vec.m_topVec); } - btSpatialForceVector operator + (const btSpatialForceVector &vec) const { return btSpatialForceVector(m_bottomVec + vec.m_bottomVec, m_topVec + vec.m_topVec); } - btSpatialForceVector operator - () const { return btSpatialForceVector(-m_bottomVec, -m_topVec); } - btSpatialForceVector operator * (const btScalar &s) const { return btSpatialForceVector(s * m_bottomVec, s * m_topVec); } + btSpatialForceVector &operator+=(const btSpatialForceVector &vec) + { + m_topVec += vec.m_topVec; + m_bottomVec += vec.m_bottomVec; + return *this; + } + btSpatialForceVector &operator-=(const btSpatialForceVector &vec) + { + m_topVec -= vec.m_topVec; + m_bottomVec -= vec.m_bottomVec; + return *this; + } + btSpatialForceVector operator-(const btSpatialForceVector &vec) const { return btSpatialForceVector(m_bottomVec - vec.m_bottomVec, m_topVec - vec.m_topVec); } + btSpatialForceVector operator+(const btSpatialForceVector &vec) const { return btSpatialForceVector(m_bottomVec + vec.m_bottomVec, m_topVec + vec.m_topVec); } + btSpatialForceVector operator-() const { return btSpatialForceVector(-m_bottomVec, -m_topVec); } + btSpatialForceVector operator*(const btScalar &s) const { return btSpatialForceVector(s * m_bottomVec, s * m_topVec); } //btSpatialForceVector & operator = (const btSpatialForceVector &vec) { m_topVec = vec.m_topVec; m_bottomVec = vec.m_bottomVec; return *this; } }; @@ -70,23 +96,36 @@ struct btSpatialMotionVector btVector3 m_topVec, m_bottomVec; // btSpatialMotionVector() { setZero(); } - btSpatialMotionVector(const btVector3 &angular, const btVector3 &linear) : m_topVec(angular), m_bottomVec(linear) {} + btSpatialMotionVector(const btVector3 &angular, const btVector3 &linear) : m_topVec(angular), m_bottomVec(linear) {} // - void setVector(const btVector3 &angular, const btVector3 &linear) { m_topVec = angular; m_bottomVec = linear; } + void setVector(const btVector3 &angular, const btVector3 &linear) + { + m_topVec = angular; + m_bottomVec = linear; + } void setValue(const btScalar &ax, const btScalar &ay, const btScalar &az, const btScalar &lx, const btScalar &ly, const btScalar &lz) { - m_topVec.setValue(ax, ay, az); m_bottomVec.setValue(lx, ly, lz); + m_topVec.setValue(ax, ay, az); + m_bottomVec.setValue(lx, ly, lz); } // - void addVector(const btVector3 &angular, const btVector3 &linear) { m_topVec += linear; m_bottomVec += angular; } + void addVector(const btVector3 &angular, const btVector3 &linear) + { + m_topVec += linear; + m_bottomVec += angular; + } void addValue(const btScalar &ax, const btScalar &ay, const btScalar &az, const btScalar &lx, const btScalar &ly, const btScalar &lz) { - m_topVec[0] += ax; m_topVec[1] += ay; m_topVec[2] += az; - m_bottomVec[0] += lx; m_bottomVec[1] += ly; m_bottomVec[2] += lz; + m_topVec[0] += ax; + m_topVec[1] += ay; + m_topVec[2] += az; + m_bottomVec[0] += lx; + m_bottomVec[1] += ly; + m_bottomVec[2] += lz; } - // - const btVector3 & getAngular() const { return m_topVec; } - const btVector3 & getLinear() const { return m_bottomVec; } + // + const btVector3 &getAngular() const { return m_topVec; } + const btVector3 &getLinear() const { return m_bottomVec; } // void setAngular(const btVector3 &angular) { m_topVec = angular; } void setLinear(const btVector3 &linear) { m_bottomVec = linear; } @@ -94,20 +133,24 @@ struct btSpatialMotionVector void addAngular(const btVector3 &angular) { m_topVec += angular; } void addLinear(const btVector3 &linear) { m_bottomVec += linear; } // - void setZero() { m_topVec.setZero(); m_bottomVec.setZero(); } + void setZero() + { + m_topVec.setZero(); + m_bottomVec.setZero(); + } // btScalar dot(const btSpatialForceVector &b) const { return m_bottomVec.dot(b.m_topVec) + m_topVec.dot(b.m_bottomVec); } // - template + template void cross(const SpatialVectorType &b, SpatialVectorType &out) const { out.m_topVec = m_topVec.cross(b.m_topVec); out.m_bottomVec = m_bottomVec.cross(b.m_topVec) + m_topVec.cross(b.m_bottomVec); } - template + template SpatialVectorType cross(const SpatialVectorType &b) const { SpatialVectorType out; @@ -116,21 +159,36 @@ struct btSpatialMotionVector return out; } // - btSpatialMotionVector & operator += (const btSpatialMotionVector &vec) { m_topVec += vec.m_topVec; m_bottomVec += vec.m_bottomVec; return *this; } - btSpatialMotionVector & operator -= (const btSpatialMotionVector &vec) { m_topVec -= vec.m_topVec; m_bottomVec -= vec.m_bottomVec; return *this; } - btSpatialMotionVector & operator *= (const btScalar &s) { m_topVec *= s; m_bottomVec *= s; return *this; } - btSpatialMotionVector operator - (const btSpatialMotionVector &vec) const { return btSpatialMotionVector(m_topVec - vec.m_topVec, m_bottomVec - vec.m_bottomVec); } - btSpatialMotionVector operator + (const btSpatialMotionVector &vec) const { return btSpatialMotionVector(m_topVec + vec.m_topVec, m_bottomVec + vec.m_bottomVec); } - btSpatialMotionVector operator - () const { return btSpatialMotionVector(-m_topVec, -m_bottomVec); } - btSpatialMotionVector operator * (const btScalar &s) const { return btSpatialMotionVector(s * m_topVec, s * m_bottomVec); } + btSpatialMotionVector &operator+=(const btSpatialMotionVector &vec) + { + m_topVec += vec.m_topVec; + m_bottomVec += vec.m_bottomVec; + return *this; + } + btSpatialMotionVector &operator-=(const btSpatialMotionVector &vec) + { + m_topVec -= vec.m_topVec; + m_bottomVec -= vec.m_bottomVec; + return *this; + } + btSpatialMotionVector &operator*=(const btScalar &s) + { + m_topVec *= s; + m_bottomVec *= s; + return *this; + } + btSpatialMotionVector operator-(const btSpatialMotionVector &vec) const { return btSpatialMotionVector(m_topVec - vec.m_topVec, m_bottomVec - vec.m_bottomVec); } + btSpatialMotionVector operator+(const btSpatialMotionVector &vec) const { return btSpatialMotionVector(m_topVec + vec.m_topVec, m_bottomVec + vec.m_bottomVec); } + btSpatialMotionVector operator-() const { return btSpatialMotionVector(-m_topVec, -m_bottomVec); } + btSpatialMotionVector operator*(const btScalar &s) const { return btSpatialMotionVector(s * m_topVec, s * m_bottomVec); } }; struct btSymmetricSpatialDyad { btMatrix3x3 m_topLeftMat, m_topRightMat, m_bottomLeftMat; - // + // btSymmetricSpatialDyad() { setIdentity(); } - btSymmetricSpatialDyad(const btMatrix3x3 &topLeftMat, const btMatrix3x3 &topRightMat, const btMatrix3x3 &bottomLeftMat) { setMatrix(topLeftMat, topRightMat, bottomLeftMat); } + btSymmetricSpatialDyad(const btMatrix3x3 &topLeftMat, const btMatrix3x3 &topRightMat, const btMatrix3x3 &bottomLeftMat) { setMatrix(topLeftMat, topRightMat, bottomLeftMat); } // void setMatrix(const btMatrix3x3 &topLeftMat, const btMatrix3x3 &topRightMat, const btMatrix3x3 &bottomLeftMat) { @@ -146,17 +204,22 @@ struct btSymmetricSpatialDyad m_bottomLeftMat += bottomLeftMat; } // - void setIdentity() { m_topLeftMat.setIdentity(); m_topRightMat.setIdentity(); m_bottomLeftMat.setIdentity(); } + void setIdentity() + { + m_topLeftMat.setIdentity(); + m_topRightMat.setIdentity(); + m_bottomLeftMat.setIdentity(); + } // - btSymmetricSpatialDyad & operator -= (const btSymmetricSpatialDyad &mat) + btSymmetricSpatialDyad &operator-=(const btSymmetricSpatialDyad &mat) { m_topLeftMat -= mat.m_topLeftMat; m_topRightMat -= mat.m_topRightMat; m_bottomLeftMat -= mat.m_bottomLeftMat; - return *this; + return *this; } // - btSpatialForceVector operator * (const btSpatialMotionVector &vec) + btSpatialForceVector operator*(const btSpatialMotionVector &vec) { return btSpatialForceVector(m_bottomLeftMat * vec.m_topVec + m_topLeftMat.transpose() * vec.m_bottomVec, m_topLeftMat * vec.m_topVec + m_topRightMat * vec.m_bottomVec); } @@ -164,7 +227,7 @@ struct btSymmetricSpatialDyad struct btSpatialTransformationMatrix { - btMatrix3x3 m_rotMat; //btMatrix3x3 m_trnCrossMat; + btMatrix3x3 m_rotMat; //btMatrix3x3 m_trnCrossMat; btVector3 m_trnVec; // enum eOutputOperation @@ -174,128 +237,124 @@ struct btSpatialTransformationMatrix Subtract = 2 }; // - template - void transform( const SpatialVectorType &inVec, - SpatialVectorType &outVec, - eOutputOperation outOp = None) + template + void transform(const SpatialVectorType &inVec, + SpatialVectorType &outVec, + eOutputOperation outOp = None) { - if(outOp == None) + if (outOp == None) { outVec.m_topVec = m_rotMat * inVec.m_topVec; outVec.m_bottomVec = -m_trnVec.cross(outVec.m_topVec) + m_rotMat * inVec.m_bottomVec; } - else if(outOp == Add) + else if (outOp == Add) { outVec.m_topVec += m_rotMat * inVec.m_topVec; outVec.m_bottomVec += -m_trnVec.cross(outVec.m_topVec) + m_rotMat * inVec.m_bottomVec; } - else if(outOp == Subtract) + else if (outOp == Subtract) { outVec.m_topVec -= m_rotMat * inVec.m_topVec; outVec.m_bottomVec -= -m_trnVec.cross(outVec.m_topVec) + m_rotMat * inVec.m_bottomVec; } - } - template - void transformRotationOnly( const SpatialVectorType &inVec, - SpatialVectorType &outVec, - eOutputOperation outOp = None) + template + void transformRotationOnly(const SpatialVectorType &inVec, + SpatialVectorType &outVec, + eOutputOperation outOp = None) { - if(outOp == None) + if (outOp == None) { outVec.m_topVec = m_rotMat * inVec.m_topVec; outVec.m_bottomVec = m_rotMat * inVec.m_bottomVec; } - else if(outOp == Add) + else if (outOp == Add) { outVec.m_topVec += m_rotMat * inVec.m_topVec; outVec.m_bottomVec += m_rotMat * inVec.m_bottomVec; } - else if(outOp == Subtract) + else if (outOp == Subtract) { outVec.m_topVec -= m_rotMat * inVec.m_topVec; outVec.m_bottomVec -= m_rotMat * inVec.m_bottomVec; } - } - template - void transformInverse( const SpatialVectorType &inVec, - SpatialVectorType &outVec, - eOutputOperation outOp = None) + template + void transformInverse(const SpatialVectorType &inVec, + SpatialVectorType &outVec, + eOutputOperation outOp = None) { - if(outOp == None) + if (outOp == None) { outVec.m_topVec = m_rotMat.transpose() * inVec.m_topVec; outVec.m_bottomVec = m_rotMat.transpose() * (inVec.m_bottomVec + m_trnVec.cross(inVec.m_topVec)); } - else if(outOp == Add) + else if (outOp == Add) { outVec.m_topVec += m_rotMat.transpose() * inVec.m_topVec; outVec.m_bottomVec += m_rotMat.transpose() * (inVec.m_bottomVec + m_trnVec.cross(inVec.m_topVec)); } - else if(outOp == Subtract) + else if (outOp == Subtract) { outVec.m_topVec -= m_rotMat.transpose() * inVec.m_topVec; outVec.m_bottomVec -= m_rotMat.transpose() * (inVec.m_bottomVec + m_trnVec.cross(inVec.m_topVec)); - } + } } - template - void transformInverseRotationOnly( const SpatialVectorType &inVec, - SpatialVectorType &outVec, - eOutputOperation outOp = None) + template + void transformInverseRotationOnly(const SpatialVectorType &inVec, + SpatialVectorType &outVec, + eOutputOperation outOp = None) { - if(outOp == None) + if (outOp == None) { outVec.m_topVec = m_rotMat.transpose() * inVec.m_topVec; outVec.m_bottomVec = m_rotMat.transpose() * inVec.m_bottomVec; } - else if(outOp == Add) + else if (outOp == Add) { outVec.m_topVec += m_rotMat.transpose() * inVec.m_topVec; outVec.m_bottomVec += m_rotMat.transpose() * inVec.m_bottomVec; } - else if(outOp == Subtract) + else if (outOp == Subtract) { outVec.m_topVec -= m_rotMat.transpose() * inVec.m_topVec; outVec.m_bottomVec -= m_rotMat.transpose() * inVec.m_bottomVec; } - } - void transformInverse( const btSymmetricSpatialDyad &inMat, - btSymmetricSpatialDyad &outMat, - eOutputOperation outOp = None) + void transformInverse(const btSymmetricSpatialDyad &inMat, + btSymmetricSpatialDyad &outMat, + eOutputOperation outOp = None) { - const btMatrix3x3 r_cross( 0, -m_trnVec[2], m_trnVec[1], - m_trnVec[2], 0, -m_trnVec[0], - -m_trnVec[1], m_trnVec[0], 0); + const btMatrix3x3 r_cross(0, -m_trnVec[2], m_trnVec[1], + m_trnVec[2], 0, -m_trnVec[0], + -m_trnVec[1], m_trnVec[0], 0); - - if(outOp == None) + if (outOp == None) { - outMat.m_topLeftMat = m_rotMat.transpose() * ( inMat.m_topLeftMat - inMat.m_topRightMat * r_cross ) * m_rotMat; + outMat.m_topLeftMat = m_rotMat.transpose() * (inMat.m_topLeftMat - inMat.m_topRightMat * r_cross) * m_rotMat; outMat.m_topRightMat = m_rotMat.transpose() * inMat.m_topRightMat * m_rotMat; outMat.m_bottomLeftMat = m_rotMat.transpose() * (r_cross * (inMat.m_topLeftMat - inMat.m_topRightMat * r_cross) + inMat.m_bottomLeftMat - inMat.m_topLeftMat.transpose() * r_cross) * m_rotMat; } - else if(outOp == Add) + else if (outOp == Add) { - outMat.m_topLeftMat += m_rotMat.transpose() * ( inMat.m_topLeftMat - inMat.m_topRightMat * r_cross ) * m_rotMat; + outMat.m_topLeftMat += m_rotMat.transpose() * (inMat.m_topLeftMat - inMat.m_topRightMat * r_cross) * m_rotMat; outMat.m_topRightMat += m_rotMat.transpose() * inMat.m_topRightMat * m_rotMat; outMat.m_bottomLeftMat += m_rotMat.transpose() * (r_cross * (inMat.m_topLeftMat - inMat.m_topRightMat * r_cross) + inMat.m_bottomLeftMat - inMat.m_topLeftMat.transpose() * r_cross) * m_rotMat; } - else if(outOp == Subtract) + else if (outOp == Subtract) { - outMat.m_topLeftMat -= m_rotMat.transpose() * ( inMat.m_topLeftMat - inMat.m_topRightMat * r_cross ) * m_rotMat; + outMat.m_topLeftMat -= m_rotMat.transpose() * (inMat.m_topLeftMat - inMat.m_topRightMat * r_cross) * m_rotMat; outMat.m_topRightMat -= m_rotMat.transpose() * inMat.m_topRightMat * m_rotMat; outMat.m_bottomLeftMat -= m_rotMat.transpose() * (r_cross * (inMat.m_topLeftMat - inMat.m_topRightMat * r_cross) + inMat.m_bottomLeftMat - inMat.m_topLeftMat.transpose() * r_cross) * m_rotMat; } } - template - SpatialVectorType operator * (const SpatialVectorType &vec) + template + SpatialVectorType operator*(const SpatialVectorType &vec) { SpatialVectorType out; transform(vec, out); @@ -303,7 +362,7 @@ struct btSpatialTransformationMatrix } }; -template +template void symmetricSpatialOuterProduct(const SpatialVectorType &a, const SpatialVectorType &b, btSymmetricSpatialDyad &out) { //output op maybe? @@ -314,7 +373,7 @@ void symmetricSpatialOuterProduct(const SpatialVectorType &a, const SpatialVecto //maybe simple a*spatTranspose(a) would be nicer? } -template +template btSymmetricSpatialDyad symmetricSpatialOuterProduct(const SpatialVectorType &a, const SpatialVectorType &b) { btSymmetricSpatialDyad out; @@ -327,5 +386,4 @@ btSymmetricSpatialDyad symmetricSpatialOuterProduct(const SpatialVectorType &a, //maybe simple a*spatTranspose(a) would be nicer? } -#endif //BT_SPATIAL_ALGEBRA_H - +#endif //BT_SPATIAL_ALGEBRA_H diff --git a/src/LinearMath/btStackAlloc.h b/src/LinearMath/btStackAlloc.h index 397b08487..3fc208497 100644 --- a/src/LinearMath/btStackAlloc.h +++ b/src/LinearMath/btStackAlloc.h @@ -20,97 +20,99 @@ Nov.2006 #ifndef BT_STACK_ALLOC #define BT_STACK_ALLOC -#include "btScalar.h" //for btAssert +#include "btScalar.h" //for btAssert #include "btAlignedAllocator.h" ///The btBlock class is an internal structure for the btStackAlloc memory allocator. struct btBlock { - btBlock* previous; - unsigned char* address; + btBlock* previous; + unsigned char* address; }; ///The StackAlloc class provides some fast stack-based memory allocator (LIFO last-in first-out) class btStackAlloc { public: + btStackAlloc(unsigned int size) + { + ctor(); + create(size); + } + ~btStackAlloc() { destroy(); } - btStackAlloc(unsigned int size) { ctor();create(size); } - ~btStackAlloc() { destroy(); } - - inline void create(unsigned int size) + inline void create(unsigned int size) { destroy(); - data = (unsigned char*) btAlignedAlloc(size,16); - totalsize = size; + data = (unsigned char*)btAlignedAlloc(size, 16); + totalsize = size; } - inline void destroy() + inline void destroy() { - btAssert(usedsize==0); + btAssert(usedsize == 0); //Raise(L"StackAlloc is still in use"); - if(usedsize==0) + if (usedsize == 0) { - if(!ischild && data) + if (!ischild && data) btAlignedFree(data); - data = 0; - usedsize = 0; + data = 0; + usedsize = 0; } - } - int getAvailableMemory() const + int getAvailableMemory() const { return static_cast(totalsize - usedsize); } - unsigned char* allocate(unsigned int size) + unsigned char* allocate(unsigned int size) { - const unsigned int nus(usedsize+size); - if(nusprevious = current; - pb->address = data+usedsize; - current = pb; - return(pb); + btBlock* pb = (btBlock*)allocate(sizeof(btBlock)); + pb->previous = current; + pb->address = data + usedsize; + current = pb; + return (pb); } - SIMD_FORCE_INLINE void endBlock(btBlock* block) + SIMD_FORCE_INLINE void endBlock(btBlock* block) { - btAssert(block==current); + btAssert(block == current); //Raise(L"Unmatched blocks"); - if(block==current) + if (block == current) { - current = block->previous; - usedsize = (unsigned int)((block->address-data)-sizeof(btBlock)); + current = block->previous; + usedsize = (unsigned int)((block->address - data) - sizeof(btBlock)); } } private: - void ctor() + void ctor() { - data = 0; - totalsize = 0; - usedsize = 0; - current = 0; - ischild = false; + data = 0; + totalsize = 0; + usedsize = 0; + current = 0; + ischild = false; } - unsigned char* data; - unsigned int totalsize; - unsigned int usedsize; - btBlock* current; - bool ischild; + unsigned char* data; + unsigned int totalsize; + unsigned int usedsize; + btBlock* current; + bool ischild; }; -#endif //BT_STACK_ALLOC +#endif //BT_STACK_ALLOC diff --git a/src/LinearMath/btThreads.cpp b/src/LinearMath/btThreads.cpp index c037626ff..7504b15f7 100644 --- a/src/LinearMath/btThreads.cpp +++ b/src/LinearMath/btThreads.cpp @@ -12,18 +12,15 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include "btThreads.h" #include "btQuickprof.h" #include // for min and max - #if BT_USE_OPENMP && BT_THREADSAFE #include -#endif // #if BT_USE_OPENMP && BT_THREADSAFE - +#endif // #if BT_USE_OPENMP && BT_THREADSAFE #if BT_USE_PPL && BT_THREADSAFE @@ -32,8 +29,7 @@ subject to the following restrictions: // Visual Studio 2010 and later should come with it #include // for GetProcessorCount() -#endif // #if BT_USE_PPL && BT_THREADSAFE - +#endif // #if BT_USE_PPL && BT_THREADSAFE #if BT_USE_TBB && BT_THREADSAFE @@ -44,8 +40,7 @@ subject to the following restrictions: #include #include -#endif // #if BT_USE_TBB && BT_THREADSAFE - +#endif // #if BT_USE_TBB && BT_THREADSAFE #if BT_THREADSAFE // @@ -53,7 +48,7 @@ subject to the following restrictions: // Using ordinary system-provided mutexes like Windows critical sections was noticeably slower // presumably because when it fails to lock at first it would sleep the thread and trigger costly // context switching. -// +// #if __cplusplus >= 201103L @@ -61,25 +56,24 @@ subject to the following restrictions: // on GCC or Clang you need to compile with -std=c++11 #define USE_CPP11_ATOMICS 1 -#elif defined( _MSC_VER ) +#elif defined(_MSC_VER) // on MSVC, use intrinsics instead #define USE_MSVC_INTRINSICS 1 -#elif defined( __GNUC__ ) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) +#elif defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) // available since GCC 4.7 and some versions of clang // todo: check for clang #define USE_GCC_BUILTIN_ATOMICS 1 -#elif defined( __GNUC__ ) && (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) +#elif defined(__GNUC__) && (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) // available since GCC 4.1 #define USE_GCC_BUILTIN_ATOMICS_OLD 1 #endif - #if USE_CPP11_ATOMICS #include @@ -89,27 +83,26 @@ subject to the following restrictions: bool btSpinMutex::tryLock() { - std::atomic* aDest = reinterpret_cast*>(&mLock); - int expected = 0; - return std::atomic_compare_exchange_weak_explicit( aDest, &expected, int(1), std::memory_order_acq_rel, std::memory_order_acquire ); + std::atomic* aDest = reinterpret_cast*>(&mLock); + int expected = 0; + return std::atomic_compare_exchange_weak_explicit(aDest, &expected, int(1), std::memory_order_acq_rel, std::memory_order_acquire); } void btSpinMutex::lock() { - // note: this lock does not sleep the thread. - while (! tryLock()) - { - // spin - } + // note: this lock does not sleep the thread. + while (!tryLock()) + { + // spin + } } void btSpinMutex::unlock() { - std::atomic* aDest = reinterpret_cast*>(&mLock); - std::atomic_store_explicit( aDest, int(0), std::memory_order_release ); + std::atomic* aDest = reinterpret_cast*>(&mLock); + std::atomic_store_explicit(aDest, int(0), std::memory_order_release); } - #elif USE_MSVC_INTRINSICS #define WIN32_LEAN_AND_MEAN @@ -117,148 +110,142 @@ void btSpinMutex::unlock() #include #include -#define THREAD_LOCAL_STATIC __declspec( thread ) static - +#define THREAD_LOCAL_STATIC __declspec(thread) static bool btSpinMutex::tryLock() { - volatile long* aDest = reinterpret_cast(&mLock); - return ( 0 == _InterlockedCompareExchange( aDest, 1, 0) ); + volatile long* aDest = reinterpret_cast(&mLock); + return (0 == _InterlockedCompareExchange(aDest, 1, 0)); } void btSpinMutex::lock() { - // note: this lock does not sleep the thread - while (! tryLock()) - { - // spin - } + // note: this lock does not sleep the thread + while (!tryLock()) + { + // spin + } } void btSpinMutex::unlock() { - volatile long* aDest = reinterpret_cast( &mLock ); - _InterlockedExchange( aDest, 0 ); + volatile long* aDest = reinterpret_cast(&mLock); + _InterlockedExchange(aDest, 0); } #elif USE_GCC_BUILTIN_ATOMICS #define THREAD_LOCAL_STATIC static __thread - bool btSpinMutex::tryLock() { - int expected = 0; - bool weak = false; - const int memOrderSuccess = __ATOMIC_ACQ_REL; - const int memOrderFail = __ATOMIC_ACQUIRE; - return __atomic_compare_exchange_n(&mLock, &expected, int(1), weak, memOrderSuccess, memOrderFail); + int expected = 0; + bool weak = false; + const int memOrderSuccess = __ATOMIC_ACQ_REL; + const int memOrderFail = __ATOMIC_ACQUIRE; + return __atomic_compare_exchange_n(&mLock, &expected, int(1), weak, memOrderSuccess, memOrderFail); } void btSpinMutex::lock() { - // note: this lock does not sleep the thread - while (! tryLock()) - { - // spin - } + // note: this lock does not sleep the thread + while (!tryLock()) + { + // spin + } } void btSpinMutex::unlock() { - __atomic_store_n(&mLock, int(0), __ATOMIC_RELEASE); + __atomic_store_n(&mLock, int(0), __ATOMIC_RELEASE); } #elif USE_GCC_BUILTIN_ATOMICS_OLD - #define THREAD_LOCAL_STATIC static __thread bool btSpinMutex::tryLock() { - return __sync_bool_compare_and_swap(&mLock, int(0), int(1)); + return __sync_bool_compare_and_swap(&mLock, int(0), int(1)); } void btSpinMutex::lock() { - // note: this lock does not sleep the thread - while (! tryLock()) - { - // spin - } + // note: this lock does not sleep the thread + while (!tryLock()) + { + // spin + } } void btSpinMutex::unlock() { - // write 0 - __sync_fetch_and_and(&mLock, int(0)); + // write 0 + __sync_fetch_and_and(&mLock, int(0)); } -#else //#elif USE_MSVC_INTRINSICS +#else //#elif USE_MSVC_INTRINSICS #error "no threading primitives defined -- unknown platform" #endif //#else //#elif USE_MSVC_INTRINSICS -#else //#if BT_THREADSAFE +#else //#if BT_THREADSAFE // These should not be called ever void btSpinMutex::lock() { - btAssert( !"unimplemented btSpinMutex::lock() called" ); + btAssert(!"unimplemented btSpinMutex::lock() called"); } void btSpinMutex::unlock() { - btAssert( !"unimplemented btSpinMutex::unlock() called" ); + btAssert(!"unimplemented btSpinMutex::unlock() called"); } bool btSpinMutex::tryLock() { - btAssert( !"unimplemented btSpinMutex::tryLock() called" ); - return true; + btAssert(!"unimplemented btSpinMutex::tryLock() called"); + return true; } #define THREAD_LOCAL_STATIC static -#endif // #else //#if BT_THREADSAFE - +#endif // #else //#if BT_THREADSAFE struct ThreadsafeCounter { - unsigned int mCounter; - btSpinMutex mMutex; + unsigned int mCounter; + btSpinMutex mMutex; - ThreadsafeCounter() - { - mCounter = 0; - --mCounter; // first count should come back 0 - } + ThreadsafeCounter() + { + mCounter = 0; + --mCounter; // first count should come back 0 + } - unsigned int getNext() - { - // no need to optimize this with atomics, it is only called ONCE per thread! - mMutex.lock(); - mCounter++; - if ( mCounter >= BT_MAX_THREAD_COUNT ) - { - btAssert( !"thread counter exceeded" ); - // wrap back to the first worker index - mCounter = 1; - } - unsigned int val = mCounter; - mMutex.unlock(); - return val; - } + unsigned int getNext() + { + // no need to optimize this with atomics, it is only called ONCE per thread! + mMutex.lock(); + mCounter++; + if (mCounter >= BT_MAX_THREAD_COUNT) + { + btAssert(!"thread counter exceeded"); + // wrap back to the first worker index + mCounter = 1; + } + unsigned int val = mCounter; + mMutex.unlock(); + return val; + } }; - static btITaskScheduler* gBtTaskScheduler; static int gThreadsRunningCounter = 0; // useful for detecting if we are trying to do nested parallel-for calls static btSpinMutex gThreadsRunningCounterMutex; static ThreadsafeCounter gThreadCounter; - // // BT_DETECT_BAD_THREAD_INDEX tries to detect when there are multiple threads assigned the same thread index. // @@ -276,7 +263,7 @@ static ThreadsafeCounter gThreadCounter; // We allocate thread-indexes as needed with a sequential global thread counter. // // Our simple thread-counting scheme falls apart if the task scheduler destroys some threads but -// continues to re-use other threads and the application repeatedly resizes the thread pool of the +// continues to re-use other threads and the application repeatedly resizes the thread pool of the // task scheduler. // In order to prevent the thread-counter from exceeding the global max (BT_MAX_THREAD_COUNT), we // wrap the thread counter back to 1. This should only happen if the worker threads have all been @@ -290,197 +277,192 @@ static ThreadsafeCounter gThreadCounter; typedef DWORD ThreadId_t; const static ThreadId_t kInvalidThreadId = 0; -ThreadId_t gDebugThreadIds[ BT_MAX_THREAD_COUNT ]; +ThreadId_t gDebugThreadIds[BT_MAX_THREAD_COUNT]; static ThreadId_t getDebugThreadId() { - return GetCurrentThreadId(); + return GetCurrentThreadId(); } -#endif // #if BT_DETECT_BAD_THREAD_INDEX - +#endif // #if BT_DETECT_BAD_THREAD_INDEX // return a unique index per thread, main thread is 0, worker threads are in [1, BT_MAX_THREAD_COUNT) unsigned int btGetCurrentThreadIndex() { - const unsigned int kNullIndex = ~0U; - THREAD_LOCAL_STATIC unsigned int sThreadIndex = kNullIndex; - if ( sThreadIndex == kNullIndex ) - { - sThreadIndex = gThreadCounter.getNext(); - btAssert( sThreadIndex < BT_MAX_THREAD_COUNT ); - } + const unsigned int kNullIndex = ~0U; + THREAD_LOCAL_STATIC unsigned int sThreadIndex = kNullIndex; + if (sThreadIndex == kNullIndex) + { + sThreadIndex = gThreadCounter.getNext(); + btAssert(sThreadIndex < BT_MAX_THREAD_COUNT); + } #if BT_DETECT_BAD_THREAD_INDEX - if ( gBtTaskScheduler && sThreadIndex > 0 ) - { - ThreadId_t tid = getDebugThreadId(); - // if not set - if ( gDebugThreadIds[ sThreadIndex ] == kInvalidThreadId ) - { - // set it - gDebugThreadIds[ sThreadIndex ] = tid; - } - else - { - if ( gDebugThreadIds[ sThreadIndex ] != tid ) - { - // this could indicate the task scheduler is breaking our assumptions about - // how threads are managed when threadpool is resized - btAssert( !"there are 2 or more threads with the same thread-index!" ); - __debugbreak(); - } - } - } -#endif // #if BT_DETECT_BAD_THREAD_INDEX - return sThreadIndex; + if (gBtTaskScheduler && sThreadIndex > 0) + { + ThreadId_t tid = getDebugThreadId(); + // if not set + if (gDebugThreadIds[sThreadIndex] == kInvalidThreadId) + { + // set it + gDebugThreadIds[sThreadIndex] = tid; + } + else + { + if (gDebugThreadIds[sThreadIndex] != tid) + { + // this could indicate the task scheduler is breaking our assumptions about + // how threads are managed when threadpool is resized + btAssert(!"there are 2 or more threads with the same thread-index!"); + __debugbreak(); + } + } + } +#endif // #if BT_DETECT_BAD_THREAD_INDEX + return sThreadIndex; } bool btIsMainThread() { - return btGetCurrentThreadIndex() == 0; + return btGetCurrentThreadIndex() == 0; } void btResetThreadIndexCounter() { - // for when all current worker threads are destroyed - btAssert( btIsMainThread() ); - gThreadCounter.mCounter = 0; + // for when all current worker threads are destroyed + btAssert(btIsMainThread()); + gThreadCounter.mCounter = 0; } -btITaskScheduler::btITaskScheduler( const char* name ) +btITaskScheduler::btITaskScheduler(const char* name) { - m_name = name; - m_savedThreadCounter = 0; - m_isActive = false; + m_name = name; + m_savedThreadCounter = 0; + m_isActive = false; } void btITaskScheduler::activate() { - // gThreadCounter is used to assign a thread-index to each worker thread in a task scheduler. - // The main thread is always thread-index 0, and worker threads are numbered from 1 to 63 (BT_MAX_THREAD_COUNT-1) - // The thread-indexes need to be unique amongst the threads that can be running simultaneously. - // Since only one task scheduler can be used at a time, it is OK for a pair of threads that belong to different - // task schedulers to share the same thread index because they can't be running at the same time. - // So each task scheduler needs to keep its own thread counter value - if ( !m_isActive ) - { - gThreadCounter.mCounter = m_savedThreadCounter; // restore saved thread counter - m_isActive = true; - } + // gThreadCounter is used to assign a thread-index to each worker thread in a task scheduler. + // The main thread is always thread-index 0, and worker threads are numbered from 1 to 63 (BT_MAX_THREAD_COUNT-1) + // The thread-indexes need to be unique amongst the threads that can be running simultaneously. + // Since only one task scheduler can be used at a time, it is OK for a pair of threads that belong to different + // task schedulers to share the same thread index because they can't be running at the same time. + // So each task scheduler needs to keep its own thread counter value + if (!m_isActive) + { + gThreadCounter.mCounter = m_savedThreadCounter; // restore saved thread counter + m_isActive = true; + } } void btITaskScheduler::deactivate() { - if ( m_isActive ) - { - m_savedThreadCounter = gThreadCounter.mCounter; // save thread counter - m_isActive = false; - } + if (m_isActive) + { + m_savedThreadCounter = gThreadCounter.mCounter; // save thread counter + m_isActive = false; + } } void btPushThreadsAreRunning() { - gThreadsRunningCounterMutex.lock(); - gThreadsRunningCounter++; - gThreadsRunningCounterMutex.unlock(); + gThreadsRunningCounterMutex.lock(); + gThreadsRunningCounter++; + gThreadsRunningCounterMutex.unlock(); } void btPopThreadsAreRunning() { - gThreadsRunningCounterMutex.lock(); - gThreadsRunningCounter--; - gThreadsRunningCounterMutex.unlock(); + gThreadsRunningCounterMutex.lock(); + gThreadsRunningCounter--; + gThreadsRunningCounterMutex.unlock(); } bool btThreadsAreRunning() { - return gThreadsRunningCounter != 0; + return gThreadsRunningCounter != 0; } - -void btSetTaskScheduler( btITaskScheduler* ts ) +void btSetTaskScheduler(btITaskScheduler* ts) { - int threadId = btGetCurrentThreadIndex(); // make sure we call this on main thread at least once before any workers run - if ( threadId != 0 ) - { - btAssert( !"btSetTaskScheduler must be called from the main thread!" ); - return; - } - if ( gBtTaskScheduler ) - { - // deactivate old task scheduler - gBtTaskScheduler->deactivate(); - } - gBtTaskScheduler = ts; - if ( ts ) - { - // activate new task scheduler - ts->activate(); - } + int threadId = btGetCurrentThreadIndex(); // make sure we call this on main thread at least once before any workers run + if (threadId != 0) + { + btAssert(!"btSetTaskScheduler must be called from the main thread!"); + return; + } + if (gBtTaskScheduler) + { + // deactivate old task scheduler + gBtTaskScheduler->deactivate(); + } + gBtTaskScheduler = ts; + if (ts) + { + // activate new task scheduler + ts->activate(); + } } - btITaskScheduler* btGetTaskScheduler() { - return gBtTaskScheduler; + return gBtTaskScheduler; } - -void btParallelFor( int iBegin, int iEnd, int grainSize, const btIParallelForBody& body ) +void btParallelFor(int iBegin, int iEnd, int grainSize, const btIParallelForBody& body) { #if BT_THREADSAFE #if BT_DETECT_BAD_THREAD_INDEX - if ( !btThreadsAreRunning() ) - { - // clear out thread ids - for ( int i = 0; i < BT_MAX_THREAD_COUNT; ++i ) - { - gDebugThreadIds[ i ] = kInvalidThreadId; - } - } -#endif // #if BT_DETECT_BAD_THREAD_INDEX + if (!btThreadsAreRunning()) + { + // clear out thread ids + for (int i = 0; i < BT_MAX_THREAD_COUNT; ++i) + { + gDebugThreadIds[i] = kInvalidThreadId; + } + } +#endif // #if BT_DETECT_BAD_THREAD_INDEX - btAssert( gBtTaskScheduler != NULL ); // call btSetTaskScheduler() with a valid task scheduler first! - gBtTaskScheduler->parallelFor( iBegin, iEnd, grainSize, body ); + btAssert(gBtTaskScheduler != NULL); // call btSetTaskScheduler() with a valid task scheduler first! + gBtTaskScheduler->parallelFor(iBegin, iEnd, grainSize, body); -#else // #if BT_THREADSAFE +#else // #if BT_THREADSAFE - // non-parallel version of btParallelFor - btAssert( !"called btParallelFor in non-threadsafe build. enable BT_THREADSAFE" ); - body.forLoop( iBegin, iEnd ); + // non-parallel version of btParallelFor + btAssert(!"called btParallelFor in non-threadsafe build. enable BT_THREADSAFE"); + body.forLoop(iBegin, iEnd); -#endif// #if BT_THREADSAFE +#endif // #if BT_THREADSAFE } -btScalar btParallelSum( int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body ) +btScalar btParallelSum(int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body) { #if BT_THREADSAFE #if BT_DETECT_BAD_THREAD_INDEX - if ( !btThreadsAreRunning() ) - { - // clear out thread ids - for ( int i = 0; i < BT_MAX_THREAD_COUNT; ++i ) - { - gDebugThreadIds[ i ] = kInvalidThreadId; - } - } -#endif // #if BT_DETECT_BAD_THREAD_INDEX + if (!btThreadsAreRunning()) + { + // clear out thread ids + for (int i = 0; i < BT_MAX_THREAD_COUNT; ++i) + { + gDebugThreadIds[i] = kInvalidThreadId; + } + } +#endif // #if BT_DETECT_BAD_THREAD_INDEX - btAssert( gBtTaskScheduler != NULL ); // call btSetTaskScheduler() with a valid task scheduler first! - return gBtTaskScheduler->parallelSum( iBegin, iEnd, grainSize, body ); + btAssert(gBtTaskScheduler != NULL); // call btSetTaskScheduler() with a valid task scheduler first! + return gBtTaskScheduler->parallelSum(iBegin, iEnd, grainSize, body); -#else // #if BT_THREADSAFE +#else // #if BT_THREADSAFE - // non-parallel version of btParallelSum - btAssert( !"called btParallelFor in non-threadsafe build. enable BT_THREADSAFE" ); - return body.sumLoop( iBegin, iEnd ); + // non-parallel version of btParallelSum + btAssert(!"called btParallelFor in non-threadsafe build. enable BT_THREADSAFE"); + return body.sumLoop(iBegin, iEnd); -#endif //#else // #if BT_THREADSAFE +#endif //#else // #if BT_THREADSAFE } - /// /// btTaskSchedulerSequential -- non-threaded implementation of task scheduler /// (really just useful for testing performance of single threaded vs multi) @@ -488,86 +470,86 @@ btScalar btParallelSum( int iBegin, int iEnd, int grainSize, const btIParallelSu class btTaskSchedulerSequential : public btITaskScheduler { public: - btTaskSchedulerSequential() : btITaskScheduler( "Sequential" ) {} - virtual int getMaxNumThreads() const BT_OVERRIDE { return 1; } - virtual int getNumThreads() const BT_OVERRIDE { return 1; } - virtual void setNumThreads( int numThreads ) BT_OVERRIDE {} - virtual void parallelFor( int iBegin, int iEnd, int grainSize, const btIParallelForBody& body ) BT_OVERRIDE - { - BT_PROFILE( "parallelFor_sequential" ); - body.forLoop( iBegin, iEnd ); - } - virtual btScalar parallelSum( int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body ) BT_OVERRIDE - { - BT_PROFILE( "parallelSum_sequential" ); - return body.sumLoop( iBegin, iEnd ); - } + btTaskSchedulerSequential() : btITaskScheduler("Sequential") {} + virtual int getMaxNumThreads() const BT_OVERRIDE { return 1; } + virtual int getNumThreads() const BT_OVERRIDE { return 1; } + virtual void setNumThreads(int numThreads) BT_OVERRIDE {} + virtual void parallelFor(int iBegin, int iEnd, int grainSize, const btIParallelForBody& body) BT_OVERRIDE + { + BT_PROFILE("parallelFor_sequential"); + body.forLoop(iBegin, iEnd); + } + virtual btScalar parallelSum(int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body) BT_OVERRIDE + { + BT_PROFILE("parallelSum_sequential"); + return body.sumLoop(iBegin, iEnd); + } }; - #if BT_USE_OPENMP && BT_THREADSAFE /// /// btTaskSchedulerOpenMP -- wrapper around OpenMP task scheduler /// class btTaskSchedulerOpenMP : public btITaskScheduler { - int m_numThreads; -public: - btTaskSchedulerOpenMP() : btITaskScheduler( "OpenMP" ) - { - m_numThreads = 0; - } - virtual int getMaxNumThreads() const BT_OVERRIDE - { - return omp_get_max_threads(); - } - virtual int getNumThreads() const BT_OVERRIDE - { - return m_numThreads; - } - virtual void setNumThreads( int numThreads ) BT_OVERRIDE - { - // With OpenMP, because it is a standard with various implementations, we can't - // know for sure if every implementation has the same behavior of destroying all - // previous threads when resizing the threadpool - m_numThreads = ( std::max )( 1, ( std::min )( int( BT_MAX_THREAD_COUNT ), numThreads ) ); - omp_set_num_threads( 1 ); // hopefully, all previous threads get destroyed here - omp_set_num_threads( m_numThreads ); - m_savedThreadCounter = 0; - if ( m_isActive ) - { - btResetThreadIndexCounter(); - } - } - virtual void parallelFor( int iBegin, int iEnd, int grainSize, const btIParallelForBody& body ) BT_OVERRIDE - { - BT_PROFILE( "parallelFor_OpenMP" ); - btPushThreadsAreRunning(); -#pragma omp parallel for schedule( static, 1 ) - for ( int i = iBegin; i < iEnd; i += grainSize ) - { - BT_PROFILE( "OpenMP_forJob" ); - body.forLoop( i, ( std::min )( i + grainSize, iEnd ) ); - } - btPopThreadsAreRunning(); - } - virtual btScalar parallelSum( int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body ) BT_OVERRIDE - { - BT_PROFILE( "parallelFor_OpenMP" ); - btPushThreadsAreRunning(); - btScalar sum = btScalar( 0 ); -#pragma omp parallel for schedule( static, 1 ) reduction(+:sum) - for ( int i = iBegin; i < iEnd; i += grainSize ) - { - BT_PROFILE( "OpenMP_sumJob" ); - sum += body.sumLoop( i, ( std::min )( i + grainSize, iEnd ) ); - } - btPopThreadsAreRunning(); - return sum; - } -}; -#endif // #if BT_USE_OPENMP && BT_THREADSAFE + int m_numThreads; +public: + btTaskSchedulerOpenMP() : btITaskScheduler("OpenMP") + { + m_numThreads = 0; + } + virtual int getMaxNumThreads() const BT_OVERRIDE + { + return omp_get_max_threads(); + } + virtual int getNumThreads() const BT_OVERRIDE + { + return m_numThreads; + } + virtual void setNumThreads(int numThreads) BT_OVERRIDE + { + // With OpenMP, because it is a standard with various implementations, we can't + // know for sure if every implementation has the same behavior of destroying all + // previous threads when resizing the threadpool + m_numThreads = (std::max)(1, (std::min)(int(BT_MAX_THREAD_COUNT), numThreads)); + omp_set_num_threads(1); // hopefully, all previous threads get destroyed here + omp_set_num_threads(m_numThreads); + m_savedThreadCounter = 0; + if (m_isActive) + { + btResetThreadIndexCounter(); + } + } + virtual void parallelFor(int iBegin, int iEnd, int grainSize, const btIParallelForBody& body) BT_OVERRIDE + { + BT_PROFILE("parallelFor_OpenMP"); + btPushThreadsAreRunning(); +#pragma omp parallel for schedule(static, 1) + for (int i = iBegin; i < iEnd; i += grainSize) + { + BT_PROFILE("OpenMP_forJob"); + body.forLoop(i, (std::min)(i + grainSize, iEnd)); + } + btPopThreadsAreRunning(); + } + virtual btScalar parallelSum(int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body) BT_OVERRIDE + { + BT_PROFILE("parallelFor_OpenMP"); + btPushThreadsAreRunning(); + btScalar sum = btScalar(0); +#pragma omp parallel for schedule(static, 1) reduction(+ \ + : sum) + for (int i = iBegin; i < iEnd; i += grainSize) + { + BT_PROFILE("OpenMP_sumJob"); + sum += body.sumLoop(i, (std::min)(i + grainSize, iEnd)); + } + btPopThreadsAreRunning(); + return sum; + } +}; +#endif // #if BT_USE_OPENMP && BT_THREADSAFE #if BT_USE_TBB && BT_THREADSAFE /// @@ -575,96 +557,94 @@ public: /// class btTaskSchedulerTBB : public btITaskScheduler { - int m_numThreads; - tbb::task_scheduler_init* m_tbbSchedulerInit; + int m_numThreads; + tbb::task_scheduler_init* m_tbbSchedulerInit; public: - btTaskSchedulerTBB() : btITaskScheduler( "IntelTBB" ) - { - m_numThreads = 0; - m_tbbSchedulerInit = NULL; - } - ~btTaskSchedulerTBB() - { - if ( m_tbbSchedulerInit ) - { - delete m_tbbSchedulerInit; - m_tbbSchedulerInit = NULL; - } - } + btTaskSchedulerTBB() : btITaskScheduler("IntelTBB") + { + m_numThreads = 0; + m_tbbSchedulerInit = NULL; + } + ~btTaskSchedulerTBB() + { + if (m_tbbSchedulerInit) + { + delete m_tbbSchedulerInit; + m_tbbSchedulerInit = NULL; + } + } - virtual int getMaxNumThreads() const BT_OVERRIDE - { - return tbb::task_scheduler_init::default_num_threads(); - } - virtual int getNumThreads() const BT_OVERRIDE - { - return m_numThreads; - } - virtual void setNumThreads( int numThreads ) BT_OVERRIDE - { - m_numThreads = ( std::max )( 1, ( std::min )( int(BT_MAX_THREAD_COUNT), numThreads ) ); - if ( m_tbbSchedulerInit ) - { - // destroys all previous threads - delete m_tbbSchedulerInit; - m_tbbSchedulerInit = NULL; - } - m_tbbSchedulerInit = new tbb::task_scheduler_init( m_numThreads ); - m_savedThreadCounter = 0; - if ( m_isActive ) - { - btResetThreadIndexCounter(); - } - } - struct ForBodyAdapter - { - const btIParallelForBody* mBody; + virtual int getMaxNumThreads() const BT_OVERRIDE + { + return tbb::task_scheduler_init::default_num_threads(); + } + virtual int getNumThreads() const BT_OVERRIDE + { + return m_numThreads; + } + virtual void setNumThreads(int numThreads) BT_OVERRIDE + { + m_numThreads = (std::max)(1, (std::min)(int(BT_MAX_THREAD_COUNT), numThreads)); + if (m_tbbSchedulerInit) + { + // destroys all previous threads + delete m_tbbSchedulerInit; + m_tbbSchedulerInit = NULL; + } + m_tbbSchedulerInit = new tbb::task_scheduler_init(m_numThreads); + m_savedThreadCounter = 0; + if (m_isActive) + { + btResetThreadIndexCounter(); + } + } + struct ForBodyAdapter + { + const btIParallelForBody* mBody; - ForBodyAdapter( const btIParallelForBody* body ) : mBody( body ) {} - void operator()( const tbb::blocked_range& range ) const - { - BT_PROFILE( "TBB_forJob" ); - mBody->forLoop( range.begin(), range.end() ); - } - }; - virtual void parallelFor( int iBegin, int iEnd, int grainSize, const btIParallelForBody& body ) BT_OVERRIDE - { - BT_PROFILE( "parallelFor_TBB" ); - ForBodyAdapter tbbBody( &body ); - btPushThreadsAreRunning(); - tbb::parallel_for( tbb::blocked_range( iBegin, iEnd, grainSize ), - tbbBody, - tbb::simple_partitioner() - ); - btPopThreadsAreRunning(); - } - struct SumBodyAdapter - { - const btIParallelSumBody* mBody; - btScalar mSum; + ForBodyAdapter(const btIParallelForBody* body) : mBody(body) {} + void operator()(const tbb::blocked_range& range) const + { + BT_PROFILE("TBB_forJob"); + mBody->forLoop(range.begin(), range.end()); + } + }; + virtual void parallelFor(int iBegin, int iEnd, int grainSize, const btIParallelForBody& body) BT_OVERRIDE + { + BT_PROFILE("parallelFor_TBB"); + ForBodyAdapter tbbBody(&body); + btPushThreadsAreRunning(); + tbb::parallel_for(tbb::blocked_range(iBegin, iEnd, grainSize), + tbbBody, + tbb::simple_partitioner()); + btPopThreadsAreRunning(); + } + struct SumBodyAdapter + { + const btIParallelSumBody* mBody; + btScalar mSum; - SumBodyAdapter( const btIParallelSumBody* body ) : mBody( body ), mSum( btScalar( 0 ) ) {} - SumBodyAdapter( const SumBodyAdapter& src, tbb::split ) : mBody( src.mBody ), mSum( btScalar( 0 ) ) {} - void join( const SumBodyAdapter& src ) { mSum += src.mSum; } - void operator()( const tbb::blocked_range& range ) - { - BT_PROFILE( "TBB_sumJob" ); - mSum += mBody->sumLoop( range.begin(), range.end() ); - } - }; - virtual btScalar parallelSum( int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body ) BT_OVERRIDE - { - BT_PROFILE( "parallelSum_TBB" ); - SumBodyAdapter tbbBody( &body ); - btPushThreadsAreRunning(); - tbb::parallel_deterministic_reduce( tbb::blocked_range( iBegin, iEnd, grainSize ), tbbBody ); - btPopThreadsAreRunning(); - return tbbBody.mSum; - } + SumBodyAdapter(const btIParallelSumBody* body) : mBody(body), mSum(btScalar(0)) {} + SumBodyAdapter(const SumBodyAdapter& src, tbb::split) : mBody(src.mBody), mSum(btScalar(0)) {} + void join(const SumBodyAdapter& src) { mSum += src.mSum; } + void operator()(const tbb::blocked_range& range) + { + BT_PROFILE("TBB_sumJob"); + mSum += mBody->sumLoop(range.begin(), range.end()); + } + }; + virtual btScalar parallelSum(int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body) BT_OVERRIDE + { + BT_PROFILE("parallelSum_TBB"); + SumBodyAdapter tbbBody(&body); + btPushThreadsAreRunning(); + tbb::parallel_deterministic_reduce(tbb::blocked_range(iBegin, iEnd, grainSize), tbbBody); + btPopThreadsAreRunning(); + return tbbBody.mSum; + } }; -#endif // #if BT_USE_TBB && BT_THREADSAFE - +#endif // #if BT_USE_TBB && BT_THREADSAFE #if BT_USE_PPL && BT_THREADSAFE /// @@ -672,148 +652,141 @@ public: /// class btTaskSchedulerPPL : public btITaskScheduler { - int m_numThreads; - concurrency::combinable m_sum; // for parallelSum + int m_numThreads; + concurrency::combinable m_sum; // for parallelSum public: - btTaskSchedulerPPL() : btITaskScheduler( "PPL" ) - { - m_numThreads = 0; - } - virtual int getMaxNumThreads() const BT_OVERRIDE - { - return concurrency::GetProcessorCount(); - } - virtual int getNumThreads() const BT_OVERRIDE - { - return m_numThreads; - } - virtual void setNumThreads( int numThreads ) BT_OVERRIDE - { - // capping the thread count for PPL due to a thread-index issue - const int maxThreadCount = (std::min)(int(BT_MAX_THREAD_COUNT), 31); - m_numThreads = ( std::max )( 1, ( std::min )( maxThreadCount, numThreads ) ); - using namespace concurrency; - if ( CurrentScheduler::Id() != -1 ) - { - CurrentScheduler::Detach(); - } - SchedulerPolicy policy; - { - // PPL seems to destroy threads when threadpool is shrunk, but keeps reusing old threads - // force it to destroy old threads - policy.SetConcurrencyLimits( 1, 1 ); - CurrentScheduler::Create( policy ); - CurrentScheduler::Detach(); - } - policy.SetConcurrencyLimits( m_numThreads, m_numThreads ); - CurrentScheduler::Create( policy ); - m_savedThreadCounter = 0; - if ( m_isActive ) - { - btResetThreadIndexCounter(); - } - } - struct ForBodyAdapter - { - const btIParallelForBody* mBody; - int mGrainSize; - int mIndexEnd; + btTaskSchedulerPPL() : btITaskScheduler("PPL") + { + m_numThreads = 0; + } + virtual int getMaxNumThreads() const BT_OVERRIDE + { + return concurrency::GetProcessorCount(); + } + virtual int getNumThreads() const BT_OVERRIDE + { + return m_numThreads; + } + virtual void setNumThreads(int numThreads) BT_OVERRIDE + { + // capping the thread count for PPL due to a thread-index issue + const int maxThreadCount = (std::min)(int(BT_MAX_THREAD_COUNT), 31); + m_numThreads = (std::max)(1, (std::min)(maxThreadCount, numThreads)); + using namespace concurrency; + if (CurrentScheduler::Id() != -1) + { + CurrentScheduler::Detach(); + } + SchedulerPolicy policy; + { + // PPL seems to destroy threads when threadpool is shrunk, but keeps reusing old threads + // force it to destroy old threads + policy.SetConcurrencyLimits(1, 1); + CurrentScheduler::Create(policy); + CurrentScheduler::Detach(); + } + policy.SetConcurrencyLimits(m_numThreads, m_numThreads); + CurrentScheduler::Create(policy); + m_savedThreadCounter = 0; + if (m_isActive) + { + btResetThreadIndexCounter(); + } + } + struct ForBodyAdapter + { + const btIParallelForBody* mBody; + int mGrainSize; + int mIndexEnd; - ForBodyAdapter( const btIParallelForBody* body, int grainSize, int end ) : mBody( body ), mGrainSize( grainSize ), mIndexEnd( end ) {} - void operator()( int i ) const - { - BT_PROFILE( "PPL_forJob" ); - mBody->forLoop( i, ( std::min )( i + mGrainSize, mIndexEnd ) ); - } - }; - virtual void parallelFor( int iBegin, int iEnd, int grainSize, const btIParallelForBody& body ) BT_OVERRIDE - { - BT_PROFILE( "parallelFor_PPL" ); - // PPL dispatch - ForBodyAdapter pplBody( &body, grainSize, iEnd ); - btPushThreadsAreRunning(); - // note: MSVC 2010 doesn't support partitioner args, so avoid them - concurrency::parallel_for( iBegin, - iEnd, - grainSize, - pplBody - ); - btPopThreadsAreRunning(); - } - struct SumBodyAdapter - { - const btIParallelSumBody* mBody; - concurrency::combinable* mSum; - int mGrainSize; - int mIndexEnd; + ForBodyAdapter(const btIParallelForBody* body, int grainSize, int end) : mBody(body), mGrainSize(grainSize), mIndexEnd(end) {} + void operator()(int i) const + { + BT_PROFILE("PPL_forJob"); + mBody->forLoop(i, (std::min)(i + mGrainSize, mIndexEnd)); + } + }; + virtual void parallelFor(int iBegin, int iEnd, int grainSize, const btIParallelForBody& body) BT_OVERRIDE + { + BT_PROFILE("parallelFor_PPL"); + // PPL dispatch + ForBodyAdapter pplBody(&body, grainSize, iEnd); + btPushThreadsAreRunning(); + // note: MSVC 2010 doesn't support partitioner args, so avoid them + concurrency::parallel_for(iBegin, + iEnd, + grainSize, + pplBody); + btPopThreadsAreRunning(); + } + struct SumBodyAdapter + { + const btIParallelSumBody* mBody; + concurrency::combinable* mSum; + int mGrainSize; + int mIndexEnd; - SumBodyAdapter( const btIParallelSumBody* body, concurrency::combinable* sum, int grainSize, int end ) : mBody( body ), mSum(sum), mGrainSize( grainSize ), mIndexEnd( end ) {} - void operator()( int i ) const - { - BT_PROFILE( "PPL_sumJob" ); - mSum->local() += mBody->sumLoop( i, ( std::min )( i + mGrainSize, mIndexEnd ) ); - } - }; - static btScalar sumFunc( btScalar a, btScalar b ) { return a + b; } - virtual btScalar parallelSum( int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body ) BT_OVERRIDE - { - BT_PROFILE( "parallelSum_PPL" ); - m_sum.clear(); - SumBodyAdapter pplBody( &body, &m_sum, grainSize, iEnd ); - btPushThreadsAreRunning(); - // note: MSVC 2010 doesn't support partitioner args, so avoid them - concurrency::parallel_for( iBegin, - iEnd, - grainSize, - pplBody - ); - btPopThreadsAreRunning(); - return m_sum.combine( sumFunc ); - } + SumBodyAdapter(const btIParallelSumBody* body, concurrency::combinable* sum, int grainSize, int end) : mBody(body), mSum(sum), mGrainSize(grainSize), mIndexEnd(end) {} + void operator()(int i) const + { + BT_PROFILE("PPL_sumJob"); + mSum->local() += mBody->sumLoop(i, (std::min)(i + mGrainSize, mIndexEnd)); + } + }; + static btScalar sumFunc(btScalar a, btScalar b) { return a + b; } + virtual btScalar parallelSum(int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body) BT_OVERRIDE + { + BT_PROFILE("parallelSum_PPL"); + m_sum.clear(); + SumBodyAdapter pplBody(&body, &m_sum, grainSize, iEnd); + btPushThreadsAreRunning(); + // note: MSVC 2010 doesn't support partitioner args, so avoid them + concurrency::parallel_for(iBegin, + iEnd, + grainSize, + pplBody); + btPopThreadsAreRunning(); + return m_sum.combine(sumFunc); + } }; -#endif // #if BT_USE_PPL && BT_THREADSAFE - +#endif // #if BT_USE_PPL && BT_THREADSAFE // create a non-threaded task scheduler (always available) btITaskScheduler* btGetSequentialTaskScheduler() { - static btTaskSchedulerSequential sTaskScheduler; - return &sTaskScheduler; + static btTaskSchedulerSequential sTaskScheduler; + return &sTaskScheduler; } - // create an OpenMP task scheduler (if available, otherwise returns null) btITaskScheduler* btGetOpenMPTaskScheduler() { #if BT_USE_OPENMP && BT_THREADSAFE - static btTaskSchedulerOpenMP sTaskScheduler; - return &sTaskScheduler; + static btTaskSchedulerOpenMP sTaskScheduler; + return &sTaskScheduler; #else - return NULL; + return NULL; #endif } - // create an Intel TBB task scheduler (if available, otherwise returns null) btITaskScheduler* btGetTBBTaskScheduler() { #if BT_USE_TBB && BT_THREADSAFE - static btTaskSchedulerTBB sTaskScheduler; - return &sTaskScheduler; + static btTaskSchedulerTBB sTaskScheduler; + return &sTaskScheduler; #else - return NULL; + return NULL; #endif } - // create a PPL task scheduler (if available, otherwise returns null) btITaskScheduler* btGetPPLTaskScheduler() { #if BT_USE_PPL && BT_THREADSAFE - static btTaskSchedulerPPL sTaskScheduler; - return &sTaskScheduler; + static btTaskSchedulerPPL sTaskScheduler; + return &sTaskScheduler; #else - return NULL; + return NULL; #endif } - diff --git a/src/LinearMath/btThreads.h b/src/LinearMath/btThreads.h index 921fd088c..b2227e172 100644 --- a/src/LinearMath/btThreads.h +++ b/src/LinearMath/btThreads.h @@ -12,14 +12,12 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #ifndef BT_THREADS_H #define BT_THREADS_H -#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE +#include "btScalar.h" // has definitions like SIMD_FORCE_INLINE -#if defined (_MSC_VER) && _MSC_VER >= 1600 +#if defined(_MSC_VER) && _MSC_VER >= 1600 // give us a compile error if any signatures of overriden methods is changed #define BT_OVERRIDE override #endif @@ -36,7 +34,7 @@ const unsigned int BT_MAX_THREAD_COUNT = 64; // only if BT_THREADSAFE is 1 bool btIsMainThread(); bool btThreadsAreRunning(); unsigned int btGetCurrentThreadIndex(); -void btResetThreadIndexCounter(); // notify that all worker threads have been destroyed +void btResetThreadIndexCounter(); // notify that all worker threads have been destroyed /// /// btSpinMutex -- lightweight spin-mutex implemented with atomic ops, never puts @@ -46,19 +44,18 @@ void btResetThreadIndexCounter(); // notify that all worker threads have been de /// class btSpinMutex { - int mLock; + int mLock; public: - btSpinMutex() - { - mLock = 0; - } - void lock(); - void unlock(); - bool tryLock(); + btSpinMutex() + { + mLock = 0; + } + void lock(); + void unlock(); + bool tryLock(); }; - // // NOTE: btMutex* is for internal Bullet use only // @@ -70,43 +67,42 @@ public: // of bad because if you call any of these functions from external code // (where BT_THREADSAFE is undefined) you will get unexpected race conditions. // -SIMD_FORCE_INLINE void btMutexLock( btSpinMutex* mutex ) +SIMD_FORCE_INLINE void btMutexLock(btSpinMutex* mutex) { #if BT_THREADSAFE - mutex->lock(); + mutex->lock(); #else - (void)mutex; -#endif // #if BT_THREADSAFE + (void)mutex; +#endif // #if BT_THREADSAFE } -SIMD_FORCE_INLINE void btMutexUnlock( btSpinMutex* mutex ) +SIMD_FORCE_INLINE void btMutexUnlock(btSpinMutex* mutex) { #if BT_THREADSAFE - mutex->unlock(); + mutex->unlock(); #else - (void)mutex; -#endif // #if BT_THREADSAFE + (void)mutex; +#endif // #if BT_THREADSAFE } -SIMD_FORCE_INLINE bool btMutexTryLock( btSpinMutex* mutex ) +SIMD_FORCE_INLINE bool btMutexTryLock(btSpinMutex* mutex) { #if BT_THREADSAFE - return mutex->tryLock(); + return mutex->tryLock(); #else - (void)mutex; - return true; -#endif // #if BT_THREADSAFE + (void)mutex; + return true; +#endif // #if BT_THREADSAFE } - // // btIParallelForBody -- subclass this to express work that can be done in parallel // class btIParallelForBody { public: - virtual ~btIParallelForBody() {} - virtual void forLoop( int iBegin, int iEnd ) const = 0; + virtual ~btIParallelForBody() {} + virtual void forLoop(int iBegin, int iEnd) const = 0; }; // @@ -116,8 +112,8 @@ public: class btIParallelSumBody { public: - virtual ~btIParallelSumBody() {} - virtual btScalar sumLoop( int iBegin, int iEnd ) const = 0; + virtual ~btIParallelSumBody() {} + virtual btScalar sumLoop(int iBegin, int iEnd) const = 0; }; // @@ -127,30 +123,30 @@ public: class btITaskScheduler { public: - btITaskScheduler( const char* name ); - virtual ~btITaskScheduler() {} - const char* getName() const { return m_name; } + btITaskScheduler(const char* name); + virtual ~btITaskScheduler() {} + const char* getName() const { return m_name; } - virtual int getMaxNumThreads() const = 0; - virtual int getNumThreads() const = 0; - virtual void setNumThreads( int numThreads ) = 0; - virtual void parallelFor( int iBegin, int iEnd, int grainSize, const btIParallelForBody& body ) = 0; - virtual btScalar parallelSum( int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body ) = 0; - virtual void sleepWorkerThreadsHint() {} // hint the task scheduler that we may not be using these threads for a little while + virtual int getMaxNumThreads() const = 0; + virtual int getNumThreads() const = 0; + virtual void setNumThreads(int numThreads) = 0; + virtual void parallelFor(int iBegin, int iEnd, int grainSize, const btIParallelForBody& body) = 0; + virtual btScalar parallelSum(int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body) = 0; + virtual void sleepWorkerThreadsHint() {} // hint the task scheduler that we may not be using these threads for a little while - // internal use only - virtual void activate(); - virtual void deactivate(); + // internal use only + virtual void activate(); + virtual void deactivate(); protected: - const char* m_name; - unsigned int m_savedThreadCounter; - bool m_isActive; + const char* m_name; + unsigned int m_savedThreadCounter; + bool m_isActive; }; // set the task scheduler to use for all calls to btParallelFor() // NOTE: you must set this prior to using any of the multi-threaded "Mt" classes -void btSetTaskScheduler( btITaskScheduler* ts ); +void btSetTaskScheduler(btITaskScheduler* ts); // get the current task scheduler btITaskScheduler* btGetTaskScheduler(); @@ -172,11 +168,10 @@ btITaskScheduler* btGetPPLTaskScheduler(); // btParallelFor -- call this to dispatch work like a for-loop // (iterations may be done out of order, so no dependencies are allowed) -void btParallelFor( int iBegin, int iEnd, int grainSize, const btIParallelForBody& body ); +void btParallelFor(int iBegin, int iEnd, int grainSize, const btIParallelForBody& body); // btParallelSum -- call this to dispatch work like a for-loop, returns the sum of all iterations // (iterations may be done out of order, so no dependencies are allowed) -btScalar btParallelSum( int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body ); - +btScalar btParallelSum(int iBegin, int iEnd, int grainSize, const btIParallelSumBody& body); #endif diff --git a/src/LinearMath/btTransform.h b/src/LinearMath/btTransform.h index d4f939a5d..6f2f99818 100644 --- a/src/LinearMath/btTransform.h +++ b/src/LinearMath/btTransform.h @@ -12,12 +12,9 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #ifndef BT_TRANSFORM_H #define BT_TRANSFORM_H - #include "btMatrix3x3.h" #ifdef BT_USE_DOUBLE_PRECISION @@ -26,46 +23,45 @@ subject to the following restrictions: #define btTransformData btTransformFloatData #endif - - - /**@brief The btTransform class supports rigid transforms with only translation and rotation and no scaling/shear. *It can be used in combination with btVector3, btQuaternion and btMatrix3x3 linear algebra classes. */ -ATTRIBUTE_ALIGNED16(class) btTransform { - - ///Storage for the rotation +ATTRIBUTE_ALIGNED16(class) +btTransform +{ + ///Storage for the rotation btMatrix3x3 m_basis; - ///Storage for the translation - btVector3 m_origin; + ///Storage for the translation + btVector3 m_origin; public: - - /**@brief No initialization constructor */ + /**@brief No initialization constructor */ btTransform() {} - /**@brief Constructor from btQuaternion (optional btVector3 ) + /**@brief Constructor from btQuaternion (optional btVector3 ) * @param q Rotation from quaternion * @param c Translation from Vector (default 0,0,0) */ - explicit SIMD_FORCE_INLINE btTransform(const btQuaternion& q, - const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0))) + explicit SIMD_FORCE_INLINE btTransform(const btQuaternion& q, + const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0))) : m_basis(q), - m_origin(c) - {} - - /**@brief Constructor from btMatrix3x3 (optional btVector3) - * @param b Rotation from Matrix - * @param c Translation from Vector default (0,0,0)*/ - explicit SIMD_FORCE_INLINE btTransform(const btMatrix3x3& b, - const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0))) - : m_basis(b), - m_origin(c) - {} - /**@brief Copy constructor */ - SIMD_FORCE_INLINE btTransform (const btTransform& other) - : m_basis(other.m_basis), - m_origin(other.m_origin) + m_origin(c) { } - /**@brief Assignment Operator */ + + /**@brief Constructor from btMatrix3x3 (optional btVector3) + * @param b Rotation from Matrix + * @param c Translation from Vector default (0,0,0)*/ + explicit SIMD_FORCE_INLINE btTransform(const btMatrix3x3& b, + const btVector3& c = btVector3(btScalar(0), btScalar(0), btScalar(0))) + : m_basis(b), + m_origin(c) + { + } + /**@brief Copy constructor */ + SIMD_FORCE_INLINE btTransform(const btTransform& other) + : m_basis(other.m_basis), + m_origin(other.m_origin) + { + } + /**@brief Assignment Operator */ SIMD_FORCE_INLINE btTransform& operator=(const btTransform& other) { m_basis = other.m_basis; @@ -73,70 +69,70 @@ public: return *this; } - - /**@brief Set the current transform as the value of the product of two transforms + /**@brief Set the current transform as the value of the product of two transforms * @param t1 Transform 1 * @param t2 Transform 2 * This = Transform1 * Transform2 */ - SIMD_FORCE_INLINE void mult(const btTransform& t1, const btTransform& t2) { - m_basis = t1.m_basis * t2.m_basis; - m_origin = t1(t2.m_origin); - } + SIMD_FORCE_INLINE void mult(const btTransform& t1, const btTransform& t2) + { + m_basis = t1.m_basis * t2.m_basis; + m_origin = t1(t2.m_origin); + } -/* void multInverseLeft(const btTransform& t1, const btTransform& t2) { + /* void multInverseLeft(const btTransform& t1, const btTransform& t2) { btVector3 v = t2.m_origin - t1.m_origin; m_basis = btMultTransposeLeft(t1.m_basis, t2.m_basis); m_origin = v * t1.m_basis; } */ -/**@brief Return the transform of the vector */ + /**@brief Return the transform of the vector */ SIMD_FORCE_INLINE btVector3 operator()(const btVector3& x) const { - return x.dot3(m_basis[0], m_basis[1], m_basis[2]) + m_origin; + return x.dot3(m_basis[0], m_basis[1], m_basis[2]) + m_origin; } - /**@brief Return the transform of the vector */ + /**@brief Return the transform of the vector */ SIMD_FORCE_INLINE btVector3 operator*(const btVector3& x) const { return (*this)(x); } - /**@brief Return the transform of the btQuaternion */ + /**@brief Return the transform of the btQuaternion */ SIMD_FORCE_INLINE btQuaternion operator*(const btQuaternion& q) const { return getRotation() * q; } - /**@brief Return the basis matrix for the rotation */ - SIMD_FORCE_INLINE btMatrix3x3& getBasis() { return m_basis; } - /**@brief Return the basis matrix for the rotation */ - SIMD_FORCE_INLINE const btMatrix3x3& getBasis() const { return m_basis; } + /**@brief Return the basis matrix for the rotation */ + SIMD_FORCE_INLINE btMatrix3x3& getBasis() { return m_basis; } + /**@brief Return the basis matrix for the rotation */ + SIMD_FORCE_INLINE const btMatrix3x3& getBasis() const { return m_basis; } - /**@brief Return the origin vector translation */ - SIMD_FORCE_INLINE btVector3& getOrigin() { return m_origin; } - /**@brief Return the origin vector translation */ - SIMD_FORCE_INLINE const btVector3& getOrigin() const { return m_origin; } + /**@brief Return the origin vector translation */ + SIMD_FORCE_INLINE btVector3& getOrigin() { return m_origin; } + /**@brief Return the origin vector translation */ + SIMD_FORCE_INLINE const btVector3& getOrigin() const { return m_origin; } - /**@brief Return a quaternion representing the rotation */ - btQuaternion getRotation() const { + /**@brief Return a quaternion representing the rotation */ + btQuaternion getRotation() const + { btQuaternion q; m_basis.getRotation(q); return q; } - - - /**@brief Set from an array + + /**@brief Set from an array * @param m A pointer to a 16 element array (12 rotation(row major padded on the right by 1), and 3 translation */ - void setFromOpenGLMatrix(const btScalar *m) + void setFromOpenGLMatrix(const btScalar* m) { m_basis.setFromOpenGLSubMatrix(m); - m_origin.setValue(m[12],m[13],m[14]); + m_origin.setValue(m[12], m[13], m[14]); } - /**@brief Fill an array representation + /**@brief Fill an array representation * @param m A pointer to a 16 element array (12 rotation(row major padded on the right by 1), and 3 translation */ - void getOpenGLMatrix(btScalar *m) const + void getOpenGLMatrix(btScalar * m) const { m_basis.getOpenGLSubMatrix(m); m[12] = m_origin.x(); @@ -145,80 +141,76 @@ public: m[15] = btScalar(1.0); } - /**@brief Set the translational element + /**@brief Set the translational element * @param origin The vector to set the translation to */ - SIMD_FORCE_INLINE void setOrigin(const btVector3& origin) - { + SIMD_FORCE_INLINE void setOrigin(const btVector3& origin) + { m_origin = origin; } SIMD_FORCE_INLINE btVector3 invXform(const btVector3& inVec) const; - - /**@brief Set the rotational element by btMatrix3x3 */ + /**@brief Set the rotational element by btMatrix3x3 */ SIMD_FORCE_INLINE void setBasis(const btMatrix3x3& basis) - { + { m_basis = basis; } - /**@brief Set the rotational element by btQuaternion */ + /**@brief Set the rotational element by btQuaternion */ SIMD_FORCE_INLINE void setRotation(const btQuaternion& q) { m_basis.setRotation(q); } - - /**@brief Set this transformation to the identity */ + /**@brief Set this transformation to the identity */ void setIdentity() { m_basis.setIdentity(); m_origin.setValue(btScalar(0.0), btScalar(0.0), btScalar(0.0)); } - /**@brief Multiply this Transform by another(this = this * another) + /**@brief Multiply this Transform by another(this = this * another) * @param t The other transform */ - btTransform& operator*=(const btTransform& t) + btTransform& operator*=(const btTransform& t) { m_origin += m_basis * t.m_origin; m_basis *= t.m_basis; return *this; } - /**@brief Return the inverse of this transform */ + /**@brief Return the inverse of this transform */ btTransform inverse() const - { + { btMatrix3x3 inv = m_basis.transpose(); return btTransform(inv, inv * -m_origin); } - /**@brief Return the inverse of this transform times the other transform + /**@brief Return the inverse of this transform times the other transform * @param t The other transform * return this.inverse() * the other */ - btTransform inverseTimes(const btTransform& t) const; + btTransform inverseTimes(const btTransform& t) const; - /**@brief Return the product of this transform and the other */ + /**@brief Return the product of this transform and the other */ btTransform operator*(const btTransform& t) const; - /**@brief Return an identity transform */ - static const btTransform& getIdentity() + /**@brief Return an identity transform */ + static const btTransform& getIdentity() { static const btTransform identityTransform(btMatrix3x3::getIdentity()); return identityTransform; } - void serialize(struct btTransformData& dataOut) const; + void serialize(struct btTransformData & dataOut) const; - void serializeFloat(struct btTransformFloatData& dataOut) const; + void serializeFloat(struct btTransformFloatData & dataOut) const; - void deSerialize(const struct btTransformData& dataIn); + void deSerialize(const struct btTransformData& dataIn); - void deSerializeDouble(const struct btTransformDoubleData& dataIn); - - void deSerializeFloat(const struct btTransformFloatData& dataIn); + void deSerializeDouble(const struct btTransformDoubleData& dataIn); + void deSerializeFloat(const struct btTransformFloatData& dataIn); }; - SIMD_FORCE_INLINE btVector3 btTransform::invXform(const btVector3& inVec) const { @@ -226,80 +218,69 @@ btTransform::invXform(const btVector3& inVec) const return (m_basis.transpose() * v); } -SIMD_FORCE_INLINE btTransform -btTransform::inverseTimes(const btTransform& t) const +SIMD_FORCE_INLINE btTransform +btTransform::inverseTimes(const btTransform& t) const { btVector3 v = t.getOrigin() - m_origin; - return btTransform(m_basis.transposeTimes(t.m_basis), - v * m_basis); + return btTransform(m_basis.transposeTimes(t.m_basis), + v * m_basis); } -SIMD_FORCE_INLINE btTransform -btTransform::operator*(const btTransform& t) const +SIMD_FORCE_INLINE btTransform + btTransform::operator*(const btTransform& t) const { - return btTransform(m_basis * t.m_basis, - (*this)(t.m_origin)); + return btTransform(m_basis * t.m_basis, + (*this)(t.m_origin)); } /**@brief Test if two transforms have all elements equal */ SIMD_FORCE_INLINE bool operator==(const btTransform& t1, const btTransform& t2) { - return ( t1.getBasis() == t2.getBasis() && - t1.getOrigin() == t2.getOrigin() ); + return (t1.getBasis() == t2.getBasis() && + t1.getOrigin() == t2.getOrigin()); } - ///for serialization -struct btTransformFloatData +struct btTransformFloatData { - btMatrix3x3FloatData m_basis; - btVector3FloatData m_origin; + btMatrix3x3FloatData m_basis; + btVector3FloatData m_origin; }; -struct btTransformDoubleData +struct btTransformDoubleData { - btMatrix3x3DoubleData m_basis; - btVector3DoubleData m_origin; + btMatrix3x3DoubleData m_basis; + btVector3DoubleData m_origin; }; - - -SIMD_FORCE_INLINE void btTransform::serialize(btTransformData& dataOut) const +SIMD_FORCE_INLINE void btTransform::serialize(btTransformData& dataOut) const { m_basis.serialize(dataOut.m_basis); m_origin.serialize(dataOut.m_origin); } -SIMD_FORCE_INLINE void btTransform::serializeFloat(btTransformFloatData& dataOut) const +SIMD_FORCE_INLINE void btTransform::serializeFloat(btTransformFloatData& dataOut) const { m_basis.serializeFloat(dataOut.m_basis); m_origin.serializeFloat(dataOut.m_origin); } - -SIMD_FORCE_INLINE void btTransform::deSerialize(const btTransformData& dataIn) +SIMD_FORCE_INLINE void btTransform::deSerialize(const btTransformData& dataIn) { m_basis.deSerialize(dataIn.m_basis); m_origin.deSerialize(dataIn.m_origin); } -SIMD_FORCE_INLINE void btTransform::deSerializeFloat(const btTransformFloatData& dataIn) +SIMD_FORCE_INLINE void btTransform::deSerializeFloat(const btTransformFloatData& dataIn) { m_basis.deSerializeFloat(dataIn.m_basis); m_origin.deSerializeFloat(dataIn.m_origin); } -SIMD_FORCE_INLINE void btTransform::deSerializeDouble(const btTransformDoubleData& dataIn) +SIMD_FORCE_INLINE void btTransform::deSerializeDouble(const btTransformDoubleData& dataIn) { m_basis.deSerializeDouble(dataIn.m_basis); m_origin.deSerializeDouble(dataIn.m_origin); } - -#endif //BT_TRANSFORM_H - - - - - - +#endif //BT_TRANSFORM_H diff --git a/src/LinearMath/btTransformUtil.h b/src/LinearMath/btTransformUtil.h index 182cc43fa..b874dd680 100644 --- a/src/LinearMath/btTransformUtil.h +++ b/src/LinearMath/btTransformUtil.h @@ -12,77 +12,66 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #ifndef BT_TRANSFORM_UTIL_H #define BT_TRANSFORM_UTIL_H #include "btTransform.h" -#define ANGULAR_MOTION_THRESHOLD btScalar(0.5)*SIMD_HALF_PI +#define ANGULAR_MOTION_THRESHOLD btScalar(0.5) * SIMD_HALF_PI - - - -SIMD_FORCE_INLINE btVector3 btAabbSupport(const btVector3& halfExtents,const btVector3& supportDir) +SIMD_FORCE_INLINE btVector3 btAabbSupport(const btVector3& halfExtents, const btVector3& supportDir) { return btVector3(supportDir.x() < btScalar(0.0) ? -halfExtents.x() : halfExtents.x(), - supportDir.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(), - supportDir.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z()); + supportDir.y() < btScalar(0.0) ? -halfExtents.y() : halfExtents.y(), + supportDir.z() < btScalar(0.0) ? -halfExtents.z() : halfExtents.z()); } - - - - - /// Utils related to temporal transforms class btTransformUtil { - public: - - static void integrateTransform(const btTransform& curTrans,const btVector3& linvel,const btVector3& angvel,btScalar timeStep,btTransform& predictedTransform) + static void integrateTransform(const btTransform& curTrans, const btVector3& linvel, const btVector3& angvel, btScalar timeStep, btTransform& predictedTransform) { predictedTransform.setOrigin(curTrans.getOrigin() + linvel * timeStep); -// #define QUATERNION_DERIVATIVE - #ifdef QUATERNION_DERIVATIVE + // #define QUATERNION_DERIVATIVE +#ifdef QUATERNION_DERIVATIVE btQuaternion predictedOrn = curTrans.getRotation(); predictedOrn += (angvel * predictedOrn) * (timeStep * btScalar(0.5)); predictedOrn.safeNormalize(); - #else +#else //Exponential map //google for "Practical Parameterization of Rotations Using the Exponential Map", F. Sebastian Grassia btVector3 axis; - btScalar fAngle2 = angvel.length2(); - btScalar fAngle = 0; - if (fAngle2>SIMD_EPSILON) - { - fAngle = btSqrt(fAngle2); - } + btScalar fAngle2 = angvel.length2(); + btScalar fAngle = 0; + if (fAngle2 > SIMD_EPSILON) + { + fAngle = btSqrt(fAngle2); + } //limit the angular motion - if (fAngle*timeStep > ANGULAR_MOTION_THRESHOLD) + if (fAngle * timeStep > ANGULAR_MOTION_THRESHOLD) { fAngle = ANGULAR_MOTION_THRESHOLD / timeStep; } - if ( fAngle < btScalar(0.001) ) + if (fAngle < btScalar(0.001)) { // use Taylor's expansions of sync function - axis = angvel*( btScalar(0.5)*timeStep-(timeStep*timeStep*timeStep)*(btScalar(0.020833333333))*fAngle*fAngle ); + axis = angvel * (btScalar(0.5) * timeStep - (timeStep * timeStep * timeStep) * (btScalar(0.020833333333)) * fAngle * fAngle); } else { // sync(fAngle) = sin(c*fAngle)/t - axis = angvel*( btSin(btScalar(0.5)*fAngle*timeStep)/fAngle ); + axis = angvel * (btSin(btScalar(0.5) * fAngle * timeStep) / fAngle); } - btQuaternion dorn (axis.x(),axis.y(),axis.z(),btCos( fAngle*timeStep*btScalar(0.5) )); + btQuaternion dorn(axis.x(), axis.y(), axis.z(), btCos(fAngle * timeStep * btScalar(0.5))); btQuaternion orn0 = curTrans.getRotation(); btQuaternion predictedOrn = dorn * orn0; predictedOrn.safeNormalize(); - #endif - if (predictedOrn.length2()>SIMD_EPSILON) +#endif + if (predictedOrn.length2() > SIMD_EPSILON) { predictedTransform.setRotation(predictedOrn); } @@ -92,137 +81,133 @@ public: } } - static void calculateVelocityQuaternion(const btVector3& pos0,const btVector3& pos1,const btQuaternion& orn0,const btQuaternion& orn1,btScalar timeStep,btVector3& linVel,btVector3& angVel) + static void calculateVelocityQuaternion(const btVector3& pos0, const btVector3& pos1, const btQuaternion& orn0, const btQuaternion& orn1, btScalar timeStep, btVector3& linVel, btVector3& angVel) { linVel = (pos1 - pos0) / timeStep; btVector3 axis; - btScalar angle; + btScalar angle; if (orn0 != orn1) { - calculateDiffAxisAngleQuaternion(orn0,orn1,axis,angle); + calculateDiffAxisAngleQuaternion(orn0, orn1, axis, angle); angVel = axis * angle / timeStep; - } else + } + else { - angVel.setValue(0,0,0); + angVel.setValue(0, 0, 0); } } - static void calculateDiffAxisAngleQuaternion(const btQuaternion& orn0,const btQuaternion& orn1a,btVector3& axis,btScalar& angle) + static void calculateDiffAxisAngleQuaternion(const btQuaternion& orn0, const btQuaternion& orn1a, btVector3& axis, btScalar& angle) { btQuaternion orn1 = orn0.nearest(orn1a); btQuaternion dorn = orn1 * orn0.inverse(); angle = dorn.getAngle(); - axis = btVector3(dorn.x(),dorn.y(),dorn.z()); + axis = btVector3(dorn.x(), dorn.y(), dorn.z()); axis[3] = btScalar(0.); //check for axis length btScalar len = axis.length2(); - if (len < SIMD_EPSILON*SIMD_EPSILON) - axis = btVector3(btScalar(1.),btScalar(0.),btScalar(0.)); + if (len < SIMD_EPSILON * SIMD_EPSILON) + axis = btVector3(btScalar(1.), btScalar(0.), btScalar(0.)); else axis /= btSqrt(len); } - static void calculateVelocity(const btTransform& transform0,const btTransform& transform1,btScalar timeStep,btVector3& linVel,btVector3& angVel) + static void calculateVelocity(const btTransform& transform0, const btTransform& transform1, btScalar timeStep, btVector3& linVel, btVector3& angVel) { linVel = (transform1.getOrigin() - transform0.getOrigin()) / timeStep; btVector3 axis; - btScalar angle; - calculateDiffAxisAngle(transform0,transform1,axis,angle); + btScalar angle; + calculateDiffAxisAngle(transform0, transform1, axis, angle); angVel = axis * angle / timeStep; } - static void calculateDiffAxisAngle(const btTransform& transform0,const btTransform& transform1,btVector3& axis,btScalar& angle) + static void calculateDiffAxisAngle(const btTransform& transform0, const btTransform& transform1, btVector3& axis, btScalar& angle) { btMatrix3x3 dmat = transform1.getBasis() * transform0.getBasis().inverse(); btQuaternion dorn; dmat.getRotation(dorn); - ///floating point inaccuracy can lead to w component > 1..., which breaks + ///floating point inaccuracy can lead to w component > 1..., which breaks dorn.normalize(); - + angle = dorn.getAngle(); - axis = btVector3(dorn.x(),dorn.y(),dorn.z()); + axis = btVector3(dorn.x(), dorn.y(), dorn.z()); axis[3] = btScalar(0.); //check for axis length btScalar len = axis.length2(); - if (len < SIMD_EPSILON*SIMD_EPSILON) - axis = btVector3(btScalar(1.),btScalar(0.),btScalar(0.)); + if (len < SIMD_EPSILON * SIMD_EPSILON) + axis = btVector3(btScalar(1.), btScalar(0.), btScalar(0.)); else axis /= btSqrt(len); } - }; - -///The btConvexSeparatingDistanceUtil can help speed up convex collision detection +///The btConvexSeparatingDistanceUtil can help speed up convex collision detection ///by conservatively updating a cached separating distance/vector instead of re-calculating the closest distance -class btConvexSeparatingDistanceUtil +class btConvexSeparatingDistanceUtil { - btQuaternion m_ornA; - btQuaternion m_ornB; - btVector3 m_posA; - btVector3 m_posB; - - btVector3 m_separatingNormal; + btQuaternion m_ornA; + btQuaternion m_ornB; + btVector3 m_posA; + btVector3 m_posB; - btScalar m_boundingRadiusA; - btScalar m_boundingRadiusB; - btScalar m_separatingDistance; + btVector3 m_separatingNormal; + + btScalar m_boundingRadiusA; + btScalar m_boundingRadiusB; + btScalar m_separatingDistance; public: - - btConvexSeparatingDistanceUtil(btScalar boundingRadiusA,btScalar boundingRadiusB) - :m_boundingRadiusA(boundingRadiusA), - m_boundingRadiusB(boundingRadiusB), - m_separatingDistance(0.f) + btConvexSeparatingDistanceUtil(btScalar boundingRadiusA, btScalar boundingRadiusB) + : m_boundingRadiusA(boundingRadiusA), + m_boundingRadiusB(boundingRadiusB), + m_separatingDistance(0.f) { } - btScalar getConservativeSeparatingDistance() + btScalar getConservativeSeparatingDistance() { return m_separatingDistance; } - void updateSeparatingDistance(const btTransform& transA,const btTransform& transB) + void updateSeparatingDistance(const btTransform& transA, const btTransform& transB) { const btVector3& toPosA = transA.getOrigin(); const btVector3& toPosB = transB.getOrigin(); btQuaternion toOrnA = transA.getRotation(); btQuaternion toOrnB = transB.getRotation(); - if (m_separatingDistance>0.f) + if (m_separatingDistance > 0.f) { - - - btVector3 linVelA,angVelA,linVelB,angVelB; - btTransformUtil::calculateVelocityQuaternion(m_posA,toPosA,m_ornA,toOrnA,btScalar(1.),linVelA,angVelA); - btTransformUtil::calculateVelocityQuaternion(m_posB,toPosB,m_ornB,toOrnB,btScalar(1.),linVelB,angVelB); + btVector3 linVelA, angVelA, linVelB, angVelB; + btTransformUtil::calculateVelocityQuaternion(m_posA, toPosA, m_ornA, toOrnA, btScalar(1.), linVelA, angVelA); + btTransformUtil::calculateVelocityQuaternion(m_posB, toPosB, m_ornB, toOrnB, btScalar(1.), linVelB, angVelB); btScalar maxAngularProjectedVelocity = angVelA.length() * m_boundingRadiusA + angVelB.length() * m_boundingRadiusB; - btVector3 relLinVel = (linVelB-linVelA); + btVector3 relLinVel = (linVelB - linVelA); btScalar relLinVelocLength = relLinVel.dot(m_separatingNormal); - if (relLinVelocLength<0.f) + if (relLinVelocLength < 0.f) { relLinVelocLength = 0.f; } - - btScalar projectedMotion = maxAngularProjectedVelocity +relLinVelocLength; + + btScalar projectedMotion = maxAngularProjectedVelocity + relLinVelocLength; m_separatingDistance -= projectedMotion; } - + m_posA = toPosA; m_posB = toPosB; m_ornA = toOrnA; m_ornB = toOrnB; } - void initSeparatingDistance(const btVector3& separatingVector,btScalar separatingDistance,const btTransform& transA,const btTransform& transB) + void initSeparatingDistance(const btVector3& separatingVector, btScalar separatingDistance, const btTransform& transA, const btTransform& transB) { m_separatingDistance = separatingDistance; - if (m_separatingDistance>0.f) + if (m_separatingDistance > 0.f) { m_separatingNormal = separatingVector; - + const btVector3& toPosA = transA.getOrigin(); const btVector3& toPosB = transB.getOrigin(); btQuaternion toOrnA = transA.getRotation(); @@ -233,9 +218,6 @@ public: m_ornB = toOrnB; } } - }; - -#endif //BT_TRANSFORM_UTIL_H - +#endif //BT_TRANSFORM_UTIL_H diff --git a/src/LinearMath/btVector3.cpp b/src/LinearMath/btVector3.cpp index e05bdccd6..13111157a 100644 --- a/src/LinearMath/btVector3.cpp +++ b/src/LinearMath/btVector3.cpp @@ -15,282 +15,285 @@ This source version has been altered. */ -#if defined (_WIN32) || defined (__i386__) +#if defined(_WIN32) || defined(__i386__) #define BT_USE_SSE_IN_API #endif - #include "btVector3.h" - - #if defined BT_USE_SIMD_VECTOR3 #if DEBUG -#include //for memset +#include //for memset #endif - #ifdef __APPLE__ #include -typedef float float4 __attribute__ ((vector_size(16))); +typedef float float4 __attribute__((vector_size(16))); #else #define float4 __m128 #endif //typedef uint32_t uint4 __attribute__ ((vector_size(16))); - #if defined BT_USE_SSE || defined _WIN32 -#define LOG2_ARRAY_SIZE 6 -#define STACK_ARRAY_COUNT (1UL << LOG2_ARRAY_SIZE) +#define LOG2_ARRAY_SIZE 6 +#define STACK_ARRAY_COUNT (1UL << LOG2_ARRAY_SIZE) #include -long _maxdot_large( const float *vv, const float *vec, unsigned long count, float *dotResult ); -long _maxdot_large( const float *vv, const float *vec, unsigned long count, float *dotResult ) +long _maxdot_large(const float *vv, const float *vec, unsigned long count, float *dotResult); +long _maxdot_large(const float *vv, const float *vec, unsigned long count, float *dotResult) { - const float4 *vertices = (const float4*) vv; - static const unsigned char indexTable[16] = {(unsigned char)-1, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 }; - float4 dotMax = btAssign128( -BT_INFINITY, -BT_INFINITY, -BT_INFINITY, -BT_INFINITY ); - float4 vvec = _mm_loadu_ps( vec ); - float4 vHi = btCastiTo128f(_mm_shuffle_epi32( btCastfTo128i( vvec), 0xaa )); /// zzzz - float4 vLo = _mm_movelh_ps( vvec, vvec ); /// xyxy - - long maxIndex = -1L; - - size_t segment = 0; - float4 stack_array[ STACK_ARRAY_COUNT ]; - + const float4 *vertices = (const float4 *)vv; + static const unsigned char indexTable[16] = {(unsigned char)-1, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0}; + float4 dotMax = btAssign128(-BT_INFINITY, -BT_INFINITY, -BT_INFINITY, -BT_INFINITY); + float4 vvec = _mm_loadu_ps(vec); + float4 vHi = btCastiTo128f(_mm_shuffle_epi32(btCastfTo128i(vvec), 0xaa)); /// zzzz + float4 vLo = _mm_movelh_ps(vvec, vvec); /// xyxy + + long maxIndex = -1L; + + size_t segment = 0; + float4 stack_array[STACK_ARRAY_COUNT]; + #if DEBUG - //memset( stack_array, -1, STACK_ARRAY_COUNT * sizeof(stack_array[0]) ); + //memset( stack_array, -1, STACK_ARRAY_COUNT * sizeof(stack_array[0]) ); #endif - - size_t index; - float4 max; - // Faster loop without cleanup code for full tiles - for ( segment = 0; segment + STACK_ARRAY_COUNT*4 <= count; segment += STACK_ARRAY_COUNT*4 ) - { - max = dotMax; - - for( index = 0; index < STACK_ARRAY_COUNT; index+= 4 ) - { // do four dot products at a time. Carefully avoid touching the w element. - float4 v0 = vertices[0]; - float4 v1 = vertices[1]; - float4 v2 = vertices[2]; - float4 v3 = vertices[3]; vertices += 4; - - float4 lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - float4 hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - float4 lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - float4 hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 - - lo0 = lo0*vLo; - lo1 = lo1*vLo; - float4 z = _mm_shuffle_ps(hi0, hi1, 0x88); - float4 x = _mm_shuffle_ps(lo0, lo1, 0x88); - float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index] = x; - max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan - - v0 = vertices[0]; - v1 = vertices[1]; - v2 = vertices[2]; - v3 = vertices[3]; vertices += 4; - - lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 - - lo0 = lo0*vLo; - lo1 = lo1*vLo; - z = _mm_shuffle_ps(hi0, hi1, 0x88); - x = _mm_shuffle_ps(lo0, lo1, 0x88); - y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index+1] = x; - max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan - - v0 = vertices[0]; - v1 = vertices[1]; - v2 = vertices[2]; - v3 = vertices[3]; vertices += 4; - - lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 - - lo0 = lo0*vLo; - lo1 = lo1*vLo; - z = _mm_shuffle_ps(hi0, hi1, 0x88); - x = _mm_shuffle_ps(lo0, lo1, 0x88); - y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index+2] = x; - max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan - - v0 = vertices[0]; - v1 = vertices[1]; - v2 = vertices[2]; - v3 = vertices[3]; vertices += 4; - - lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 - - lo0 = lo0*vLo; - lo1 = lo1*vLo; - z = _mm_shuffle_ps(hi0, hi1, 0x88); - x = _mm_shuffle_ps(lo0, lo1, 0x88); - y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index+3] = x; - max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan - - // It is too costly to keep the index of the max here. We will look for it again later. We save a lot of work this way. - } - - // If we found a new max - if( 0xf != _mm_movemask_ps( (float4) _mm_cmpeq_ps(max, dotMax))) - { - // copy the new max across all lanes of our max accumulator - max = _mm_max_ps(max, (float4) _mm_shuffle_ps( max, max, 0x4e)); - max = _mm_max_ps(max, (float4) _mm_shuffle_ps( max, max, 0xb1)); - - dotMax = max; - - // find first occurrence of that max - size_t test; - for( index = 0; 0 == (test=_mm_movemask_ps( _mm_cmpeq_ps( stack_array[index], max))); index++ ) // local_count must be a multiple of 4 - {} - // record where it is. - maxIndex = 4*index + segment + indexTable[test]; - } - } - - // account for work we've already done - count -= segment; - - // Deal with the last < STACK_ARRAY_COUNT vectors - max = dotMax; - index = 0; - - - if( btUnlikely( count > 16) ) - { - for( ; index + 4 <= count / 4; index+=4 ) - { // do four dot products at a time. Carefully avoid touching the w element. - float4 v0 = vertices[0]; - float4 v1 = vertices[1]; - float4 v2 = vertices[2]; - float4 v3 = vertices[3]; vertices += 4; - - float4 lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - float4 hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - float4 lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - float4 hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 - - lo0 = lo0*vLo; - lo1 = lo1*vLo; - float4 z = _mm_shuffle_ps(hi0, hi1, 0x88); - float4 x = _mm_shuffle_ps(lo0, lo1, 0x88); - float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index] = x; - max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan - - v0 = vertices[0]; - v1 = vertices[1]; - v2 = vertices[2]; - v3 = vertices[3]; vertices += 4; - - lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 - - lo0 = lo0*vLo; - lo1 = lo1*vLo; - z = _mm_shuffle_ps(hi0, hi1, 0x88); - x = _mm_shuffle_ps(lo0, lo1, 0x88); - y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index+1] = x; - max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan - - v0 = vertices[0]; - v1 = vertices[1]; - v2 = vertices[2]; - v3 = vertices[3]; vertices += 4; - - lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 - - lo0 = lo0*vLo; - lo1 = lo1*vLo; - z = _mm_shuffle_ps(hi0, hi1, 0x88); - x = _mm_shuffle_ps(lo0, lo1, 0x88); - y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index+2] = x; - max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan - - v0 = vertices[0]; - v1 = vertices[1]; - v2 = vertices[2]; - v3 = vertices[3]; vertices += 4; - - lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 - - lo0 = lo0*vLo; - lo1 = lo1*vLo; - z = _mm_shuffle_ps(hi0, hi1, 0x88); - x = _mm_shuffle_ps(lo0, lo1, 0x88); - y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index+3] = x; - max = _mm_max_ps( x, max ); // control the order here so that max is never NaN even if x is nan - - // It is too costly to keep the index of the max here. We will look for it again later. We save a lot of work this way. - } - } - - size_t localCount = (count & -4L) - 4*index; - if( localCount ) - { + + size_t index; + float4 max; + // Faster loop without cleanup code for full tiles + for (segment = 0; segment + STACK_ARRAY_COUNT * 4 <= count; segment += STACK_ARRAY_COUNT * 4) + { + max = dotMax; + + for (index = 0; index < STACK_ARRAY_COUNT; index += 4) + { // do four dot products at a time. Carefully avoid touching the w element. + float4 v0 = vertices[0]; + float4 v1 = vertices[1]; + float4 v2 = vertices[2]; + float4 v3 = vertices[3]; + vertices += 4; + + float4 lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + float4 hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + float4 lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + float4 hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 + + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + float4 z = _mm_shuffle_ps(hi0, hi1, 0x88); + float4 x = _mm_shuffle_ps(lo0, lo1, 0x88); + float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index] = x; + max = _mm_max_ps(x, max); // control the order here so that max is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; + + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 + + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 1] = x; + max = _mm_max_ps(x, max); // control the order here so that max is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; + + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 + + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 2] = x; + max = _mm_max_ps(x, max); // control the order here so that max is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; + + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 + + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 3] = x; + max = _mm_max_ps(x, max); // control the order here so that max is never NaN even if x is nan + + // It is too costly to keep the index of the max here. We will look for it again later. We save a lot of work this way. + } + + // If we found a new max + if (0xf != _mm_movemask_ps((float4)_mm_cmpeq_ps(max, dotMax))) + { + // copy the new max across all lanes of our max accumulator + max = _mm_max_ps(max, (float4)_mm_shuffle_ps(max, max, 0x4e)); + max = _mm_max_ps(max, (float4)_mm_shuffle_ps(max, max, 0xb1)); + + dotMax = max; + + // find first occurrence of that max + size_t test; + for (index = 0; 0 == (test = _mm_movemask_ps(_mm_cmpeq_ps(stack_array[index], max))); index++) // local_count must be a multiple of 4 + { + } + // record where it is. + maxIndex = 4 * index + segment + indexTable[test]; + } + } + + // account for work we've already done + count -= segment; + + // Deal with the last < STACK_ARRAY_COUNT vectors + max = dotMax; + index = 0; + + if (btUnlikely(count > 16)) + { + for (; index + 4 <= count / 4; index += 4) + { // do four dot products at a time. Carefully avoid touching the w element. + float4 v0 = vertices[0]; + float4 v1 = vertices[1]; + float4 v2 = vertices[2]; + float4 v3 = vertices[3]; + vertices += 4; + + float4 lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + float4 hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + float4 lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + float4 hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 + + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + float4 z = _mm_shuffle_ps(hi0, hi1, 0x88); + float4 x = _mm_shuffle_ps(lo0, lo1, 0x88); + float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index] = x; + max = _mm_max_ps(x, max); // control the order here so that max is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; + + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 + + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 1] = x; + max = _mm_max_ps(x, max); // control the order here so that max is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; + + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 + + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 2] = x; + max = _mm_max_ps(x, max); // control the order here so that max is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; + + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 + + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 3] = x; + max = _mm_max_ps(x, max); // control the order here so that max is never NaN even if x is nan + + // It is too costly to keep the index of the max here. We will look for it again later. We save a lot of work this way. + } + } + + size_t localCount = (count & -4L) - 4 * index; + if (localCount) + { #ifdef __APPLE__ - float4 t0, t1, t2, t3, t4; - float4 * sap = &stack_array[index + localCount / 4]; - vertices += localCount; // counter the offset - size_t byteIndex = -(localCount) * sizeof(float); - //AT&T Code style assembly - asm volatile - ( ".align 4 \n\ + float4 t0, t1, t2, t3, t4; + float4 *sap = &stack_array[index + localCount / 4]; + vertices += localCount; // counter the offset + size_t byteIndex = -(localCount) * sizeof(float); + //AT&T Code style assembly + asm volatile( + ".align 4 \n\ 0: movaps %[max], %[t2] // move max out of the way to avoid propagating NaNs in max \n\ movaps (%[vertices], %[byteIndex], 4), %[t0] // vertices[0] \n\ movaps 16(%[vertices], %[byteIndex], 4), %[t1] // vertices[1] \n\ @@ -316,368 +319,374 @@ long _maxdot_large( const float *vv, const float *vec, unsigned long count, floa add $16, %[byteIndex] // advance loop counter\n\ jnz 0b \n\ " - : [max] "+x" (max), [t0] "=&x" (t0), [t1] "=&x" (t1), [t2] "=&x" (t2), [t3] "=&x" (t3), [t4] "=&x" (t4), [byteIndex] "+r" (byteIndex) - : [vLo] "x" (vLo), [vHi] "x" (vHi), [vertices] "r" (vertices), [sap] "r" (sap) - : "memory", "cc" - ); - index += localCount/4; + : [max] "+x"(max), [t0] "=&x"(t0), [t1] "=&x"(t1), [t2] "=&x"(t2), [t3] "=&x"(t3), [t4] "=&x"(t4), [byteIndex] "+r"(byteIndex) + : [vLo] "x"(vLo), [vHi] "x"(vHi), [vertices] "r"(vertices), [sap] "r"(sap) + : "memory", "cc"); + index += localCount / 4; #else - { - for( unsigned int i=0; i 16) ) - { - for( ; index + 4 <= count / 4; index+=4 ) - { // do four dot products at a time. Carefully avoid touching the w element. - float4 v0 = vertices[0]; - float4 v1 = vertices[1]; - float4 v2 = vertices[2]; - float4 v3 = vertices[3]; vertices += 4; - - float4 lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - float4 hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - float4 lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - float4 hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 - - lo0 = lo0*vLo; - lo1 = lo1*vLo; - float4 z = _mm_shuffle_ps(hi0, hi1, 0x88); - float4 x = _mm_shuffle_ps(lo0, lo1, 0x88); - float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index] = x; - min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan - - v0 = vertices[0]; - v1 = vertices[1]; - v2 = vertices[2]; - v3 = vertices[3]; vertices += 4; - - lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 - - lo0 = lo0*vLo; - lo1 = lo1*vLo; - z = _mm_shuffle_ps(hi0, hi1, 0x88); - x = _mm_shuffle_ps(lo0, lo1, 0x88); - y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index+1] = x; - min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan - - v0 = vertices[0]; - v1 = vertices[1]; - v2 = vertices[2]; - v3 = vertices[3]; vertices += 4; - - lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 - - lo0 = lo0*vLo; - lo1 = lo1*vLo; - z = _mm_shuffle_ps(hi0, hi1, 0x88); - x = _mm_shuffle_ps(lo0, lo1, 0x88); - y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index+2] = x; - min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan - - v0 = vertices[0]; - v1 = vertices[1]; - v2 = vertices[2]; - v3 = vertices[3]; vertices += 4; - - lo0 = _mm_movelh_ps( v0, v1); // x0y0x1y1 - hi0 = _mm_movehl_ps( v1, v0); // z0?0z1?1 - lo1 = _mm_movelh_ps( v2, v3); // x2y2x3y3 - hi1 = _mm_movehl_ps( v3, v2); // z2?2z3?3 - - lo0 = lo0*vLo; - lo1 = lo1*vLo; - z = _mm_shuffle_ps(hi0, hi1, 0x88); - x = _mm_shuffle_ps(lo0, lo1, 0x88); - y = _mm_shuffle_ps(lo0, lo1, 0xdd); - z = z*vHi; - x = x+y; - x = x+z; - stack_array[index+3] = x; - min = _mm_min_ps( x, min ); // control the order here so that min is never NaN even if x is nan - - // It is too costly to keep the index of the min here. We will look for it again later. We save a lot of work this way. - } - } - - size_t localCount = (count & -4L) - 4*index; - if( localCount ) - { - - + + size_t index; + float4 min; + // Faster loop without cleanup code for full tiles + for (segment = 0; segment + STACK_ARRAY_COUNT * 4 <= count; segment += STACK_ARRAY_COUNT * 4) + { + min = dotmin; + + for (index = 0; index < STACK_ARRAY_COUNT; index += 4) + { // do four dot products at a time. Carefully avoid touching the w element. + float4 v0 = vertices[0]; + float4 v1 = vertices[1]; + float4 v2 = vertices[2]; + float4 v3 = vertices[3]; + vertices += 4; + + float4 lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + float4 hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + float4 lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + float4 hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 + + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + float4 z = _mm_shuffle_ps(hi0, hi1, 0x88); + float4 x = _mm_shuffle_ps(lo0, lo1, 0x88); + float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index] = x; + min = _mm_min_ps(x, min); // control the order here so that min is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; + + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 + + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 1] = x; + min = _mm_min_ps(x, min); // control the order here so that min is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; + + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 + + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 2] = x; + min = _mm_min_ps(x, min); // control the order here so that min is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; + + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 + + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 3] = x; + min = _mm_min_ps(x, min); // control the order here so that min is never NaN even if x is nan + + // It is too costly to keep the index of the min here. We will look for it again later. We save a lot of work this way. + } + + // If we found a new min + if (0xf != _mm_movemask_ps((float4)_mm_cmpeq_ps(min, dotmin))) + { + // copy the new min across all lanes of our min accumulator + min = _mm_min_ps(min, (float4)_mm_shuffle_ps(min, min, 0x4e)); + min = _mm_min_ps(min, (float4)_mm_shuffle_ps(min, min, 0xb1)); + + dotmin = min; + + // find first occurrence of that min + size_t test; + for (index = 0; 0 == (test = _mm_movemask_ps(_mm_cmpeq_ps(stack_array[index], min))); index++) // local_count must be a multiple of 4 + { + } + // record where it is. + minIndex = 4 * index + segment + indexTable[test]; + } + } + + // account for work we've already done + count -= segment; + + // Deal with the last < STACK_ARRAY_COUNT vectors + min = dotmin; + index = 0; + + if (btUnlikely(count > 16)) + { + for (; index + 4 <= count / 4; index += 4) + { // do four dot products at a time. Carefully avoid touching the w element. + float4 v0 = vertices[0]; + float4 v1 = vertices[1]; + float4 v2 = vertices[2]; + float4 v3 = vertices[3]; + vertices += 4; + + float4 lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + float4 hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + float4 lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + float4 hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 + + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + float4 z = _mm_shuffle_ps(hi0, hi1, 0x88); + float4 x = _mm_shuffle_ps(lo0, lo1, 0x88); + float4 y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index] = x; + min = _mm_min_ps(x, min); // control the order here so that min is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; + + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 + + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 1] = x; + min = _mm_min_ps(x, min); // control the order here so that min is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; + + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 + + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 2] = x; + min = _mm_min_ps(x, min); // control the order here so that min is never NaN even if x is nan + + v0 = vertices[0]; + v1 = vertices[1]; + v2 = vertices[2]; + v3 = vertices[3]; + vertices += 4; + + lo0 = _mm_movelh_ps(v0, v1); // x0y0x1y1 + hi0 = _mm_movehl_ps(v1, v0); // z0?0z1?1 + lo1 = _mm_movelh_ps(v2, v3); // x2y2x3y3 + hi1 = _mm_movehl_ps(v3, v2); // z2?2z3?3 + + lo0 = lo0 * vLo; + lo1 = lo1 * vLo; + z = _mm_shuffle_ps(hi0, hi1, 0x88); + x = _mm_shuffle_ps(lo0, lo1, 0x88); + y = _mm_shuffle_ps(lo0, lo1, 0xdd); + z = z * vHi; + x = x + y; + x = x + z; + stack_array[index + 3] = x; + min = _mm_min_ps(x, min); // control the order here so that min is never NaN even if x is nan + + // It is too costly to keep the index of the min here. We will look for it again later. We save a lot of work this way. + } + } + + size_t localCount = (count & -4L) - 4 * index; + if (localCount) + { #ifdef __APPLE__ - vertices += localCount; // counter the offset - float4 t0, t1, t2, t3, t4; - size_t byteIndex = -(localCount) * sizeof(float); - float4 * sap = &stack_array[index + localCount / 4]; - - asm volatile - ( ".align 4 \n\ + vertices += localCount; // counter the offset + float4 t0, t1, t2, t3, t4; + size_t byteIndex = -(localCount) * sizeof(float); + float4 *sap = &stack_array[index + localCount / 4]; + + asm volatile( + ".align 4 \n\ 0: movaps %[min], %[t2] // move min out of the way to avoid propagating NaNs in min \n\ movaps (%[vertices], %[byteIndex], 4), %[t0] // vertices[0] \n\ movaps 16(%[vertices], %[byteIndex], 4), %[t1] // vertices[1] \n\ @@ -703,968 +712,953 @@ long _mindot_large( const float *vv, const float *vec, unsigned long count, floa add $16, %[byteIndex] // advance loop counter\n\ jnz 0b \n\ " - : [min] "+x" (min), [t0] "=&x" (t0), [t1] "=&x" (t1), [t2] "=&x" (t2), [t3] "=&x" (t3), [t4] "=&x" (t4), [byteIndex] "+r" (byteIndex) - : [vLo] "x" (vLo), [vHi] "x" (vHi), [vertices] "r" (vertices), [sap] "r" (sap) - : "memory", "cc" - ); - index += localCount/4; + : [min] "+x"(min), [t0] "=&x"(t0), [t1] "=&x"(t1), [t2] "=&x"(t2), [t3] "=&x"(t3), [t4] "=&x"(t4), [byteIndex] "+r"(byteIndex) + : [vLo] "x"(vLo), [vHi] "x"(vHi), [vertices] "r"(vertices), [sap] "r"(sap) + : "memory", "cc"); + index += localCount / 4; #else - { - for( unsigned int i=0; i #include -#include //for sysctlbyname +#include //for sysctlbyname -static long _maxdot_large_v0( const float *vv, const float *vec, unsigned long count, float *dotResult ); -static long _maxdot_large_v1( const float *vv, const float *vec, unsigned long count, float *dotResult ); -static long _maxdot_large_sel( const float *vv, const float *vec, unsigned long count, float *dotResult ); -static long _mindot_large_v0( const float *vv, const float *vec, unsigned long count, float *dotResult ); -static long _mindot_large_v1( const float *vv, const float *vec, unsigned long count, float *dotResult ); -static long _mindot_large_sel( const float *vv, const float *vec, unsigned long count, float *dotResult ); +static long _maxdot_large_v0(const float *vv, const float *vec, unsigned long count, float *dotResult); +static long _maxdot_large_v1(const float *vv, const float *vec, unsigned long count, float *dotResult); +static long _maxdot_large_sel(const float *vv, const float *vec, unsigned long count, float *dotResult); +static long _mindot_large_v0(const float *vv, const float *vec, unsigned long count, float *dotResult); +static long _mindot_large_v1(const float *vv, const float *vec, unsigned long count, float *dotResult); +static long _mindot_large_sel(const float *vv, const float *vec, unsigned long count, float *dotResult); -long (*_maxdot_large)( const float *vv, const float *vec, unsigned long count, float *dotResult ) = _maxdot_large_sel; -long (*_mindot_large)( const float *vv, const float *vec, unsigned long count, float *dotResult ) = _mindot_large_sel; +long (*_maxdot_large)(const float *vv, const float *vec, unsigned long count, float *dotResult) = _maxdot_large_sel; +long (*_mindot_large)(const float *vv, const float *vec, unsigned long count, float *dotResult) = _mindot_large_sel; - -static inline uint32_t btGetCpuCapabilities( void ) +static inline uint32_t btGetCpuCapabilities(void) { - static uint32_t capabilities = 0; - static bool testedCapabilities = false; + static uint32_t capabilities = 0; + static bool testedCapabilities = false; - if( 0 == testedCapabilities) - { - uint32_t hasFeature = 0; - size_t featureSize = sizeof( hasFeature ); - int err = sysctlbyname( "hw.optional.neon_hpfp", &hasFeature, &featureSize, NULL, 0 ); + if (0 == testedCapabilities) + { + uint32_t hasFeature = 0; + size_t featureSize = sizeof(hasFeature); + int err = sysctlbyname("hw.optional.neon_hpfp", &hasFeature, &featureSize, NULL, 0); - if( 0 == err && hasFeature) - capabilities |= 0x2000; + if (0 == err && hasFeature) + capabilities |= 0x2000; testedCapabilities = true; - } - - return capabilities; + } + + return capabilities; } - - - -static long _maxdot_large_sel( const float *vv, const float *vec, unsigned long count, float *dotResult ) +static long _maxdot_large_sel(const float *vv, const float *vec, unsigned long count, float *dotResult) { + if (btGetCpuCapabilities() & 0x2000) + _maxdot_large = _maxdot_large_v1; + else + _maxdot_large = _maxdot_large_v0; - if( btGetCpuCapabilities() & 0x2000 ) - _maxdot_large = _maxdot_large_v1; - else - _maxdot_large = _maxdot_large_v0; - - return _maxdot_large(vv, vec, count, dotResult); + return _maxdot_large(vv, vec, count, dotResult); } -static long _mindot_large_sel( const float *vv, const float *vec, unsigned long count, float *dotResult ) +static long _mindot_large_sel(const float *vv, const float *vec, unsigned long count, float *dotResult) { + if (btGetCpuCapabilities() & 0x2000) + _mindot_large = _mindot_large_v1; + else + _mindot_large = _mindot_large_v0; - if( btGetCpuCapabilities() & 0x2000 ) - _mindot_large = _mindot_large_v1; - else - _mindot_large = _mindot_large_v0; - - return _mindot_large(vv, vec, count, dotResult); + return _mindot_large(vv, vec, count, dotResult); } - - #if defined __arm__ -# define vld1q_f32_aligned_postincrement( _ptr ) ({ float32x4_t _r; asm( "vld1.f32 {%0}, [%1, :128]!\n" : "=w" (_r), "+r" (_ptr) ); /*return*/ _r; }) +#define vld1q_f32_aligned_postincrement(_ptr) ({ float32x4_t _r; asm( "vld1.f32 {%0}, [%1, :128]!\n" : "=w" (_r), "+r" (_ptr) ); /*return*/ _r; }) #else //support 64bit arm -# define vld1q_f32_aligned_postincrement( _ptr) ({ float32x4_t _r = ((float32x4_t*)(_ptr))[0]; (_ptr) = (const float*) ((const char*)(_ptr) + 16L); /*return*/ _r; }) +#define vld1q_f32_aligned_postincrement(_ptr) ({ float32x4_t _r = ((float32x4_t*)(_ptr))[0]; (_ptr) = (const float*) ((const char*)(_ptr) + 16L); /*return*/ _r; }) #endif - -long _maxdot_large_v0( const float *vv, const float *vec, unsigned long count, float *dotResult ) +long _maxdot_large_v0(const float *vv, const float *vec, unsigned long count, float *dotResult) { - unsigned long i = 0; - float32x4_t vvec = vld1q_f32_aligned_postincrement( vec ); - float32x2_t vLo = vget_low_f32(vvec); - float32x2_t vHi = vdup_lane_f32(vget_high_f32(vvec), 0); - float32x2_t dotMaxLo = (float32x2_t) { -BT_INFINITY, -BT_INFINITY }; - float32x2_t dotMaxHi = (float32x2_t) { -BT_INFINITY, -BT_INFINITY }; - uint32x2_t indexLo = (uint32x2_t) {0, 1}; - uint32x2_t indexHi = (uint32x2_t) {2, 3}; - uint32x2_t iLo = (uint32x2_t) {static_cast(-1), static_cast(-1)}; - uint32x2_t iHi = (uint32x2_t) {static_cast(-1), static_cast(-1)}; - const uint32x2_t four = (uint32x2_t) {4,4}; + unsigned long i = 0; + float32x4_t vvec = vld1q_f32_aligned_postincrement(vec); + float32x2_t vLo = vget_low_f32(vvec); + float32x2_t vHi = vdup_lane_f32(vget_high_f32(vvec), 0); + float32x2_t dotMaxLo = (float32x2_t){-BT_INFINITY, -BT_INFINITY}; + float32x2_t dotMaxHi = (float32x2_t){-BT_INFINITY, -BT_INFINITY}; + uint32x2_t indexLo = (uint32x2_t){0, 1}; + uint32x2_t indexHi = (uint32x2_t){2, 3}; + uint32x2_t iLo = (uint32x2_t){static_cast(-1), static_cast(-1)}; + uint32x2_t iHi = (uint32x2_t){static_cast(-1), static_cast(-1)}; + const uint32x2_t four = (uint32x2_t){4, 4}; - for( ; i+8 <= count; i+= 8 ) - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); - - float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); - float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); - float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo); - float32x2_t xy3 = vmul_f32( vget_low_f32(v3), vLo); - - float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x2x2_t z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3)); - float32x2_t zLo = vmul_f32( z0.val[0], vHi); - float32x2_t zHi = vmul_f32( z1.val[0], vHi); - - float32x2_t rLo = vpadd_f32( xy0, xy1); - float32x2_t rHi = vpadd_f32( xy2, xy3); - rLo = vadd_f32(rLo, zLo); - rHi = vadd_f32(rHi, zHi); - - uint32x2_t maskLo = vcgt_f32( rLo, dotMaxLo ); - uint32x2_t maskHi = vcgt_f32( rHi, dotMaxHi ); - dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo); - dotMaxHi = vbsl_f32( maskHi, rHi, dotMaxHi); - iLo = vbsl_u32(maskLo, indexLo, iLo); - iHi = vbsl_u32(maskHi, indexHi, iHi); - indexLo = vadd_u32(indexLo, four); - indexHi = vadd_u32(indexHi, four); + for (; i + 8 <= count; i += 8) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v3 = vld1q_f32_aligned_postincrement(vv); - v0 = vld1q_f32_aligned_postincrement( vv ); - v1 = vld1q_f32_aligned_postincrement( vv ); - v2 = vld1q_f32_aligned_postincrement( vv ); - v3 = vld1q_f32_aligned_postincrement( vv ); - - xy0 = vmul_f32( vget_low_f32(v0), vLo); - xy1 = vmul_f32( vget_low_f32(v1), vLo); - xy2 = vmul_f32( vget_low_f32(v2), vLo); - xy3 = vmul_f32( vget_low_f32(v3), vLo); - - z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); - z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3)); - zLo = vmul_f32( z0.val[0], vHi); - zHi = vmul_f32( z1.val[0], vHi); - - rLo = vpadd_f32( xy0, xy1); - rHi = vpadd_f32( xy2, xy3); - rLo = vadd_f32(rLo, zLo); - rHi = vadd_f32(rHi, zHi); - - maskLo = vcgt_f32( rLo, dotMaxLo ); - maskHi = vcgt_f32( rHi, dotMaxHi ); - dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo); - dotMaxHi = vbsl_f32( maskHi, rHi, dotMaxHi); - iLo = vbsl_u32(maskLo, indexLo, iLo); - iHi = vbsl_u32(maskHi, indexHi, iHi); - indexLo = vadd_u32(indexLo, four); - indexHi = vadd_u32(indexHi, four); - } + float32x2_t xy0 = vmul_f32(vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32(vget_low_f32(v1), vLo); + float32x2_t xy2 = vmul_f32(vget_low_f32(v2), vLo); + float32x2_t xy3 = vmul_f32(vget_low_f32(v3), vLo); - for( ; i+4 <= count; i+= 4 ) - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); - - float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); - float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); - float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo); - float32x2_t xy3 = vmul_f32( vget_low_f32(v3), vLo); - - float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x2x2_t z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3)); - float32x2_t zLo = vmul_f32( z0.val[0], vHi); - float32x2_t zHi = vmul_f32( z1.val[0], vHi); - - float32x2_t rLo = vpadd_f32( xy0, xy1); - float32x2_t rHi = vpadd_f32( xy2, xy3); - rLo = vadd_f32(rLo, zLo); - rHi = vadd_f32(rHi, zHi); - - uint32x2_t maskLo = vcgt_f32( rLo, dotMaxLo ); - uint32x2_t maskHi = vcgt_f32( rHi, dotMaxHi ); - dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo); - dotMaxHi = vbsl_f32( maskHi, rHi, dotMaxHi); - iLo = vbsl_u32(maskLo, indexLo, iLo); - iHi = vbsl_u32(maskHi, indexHi, iHi); - indexLo = vadd_u32(indexLo, four); - indexHi = vadd_u32(indexHi, four); - } - - switch( count & 3 ) - { - case 3: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - - float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); - float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); - float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo); - - float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x2_t zLo = vmul_f32( z0.val[0], vHi); - float32x2_t zHi = vmul_f32( vdup_lane_f32(vget_high_f32(v2), 0), vHi); - - float32x2_t rLo = vpadd_f32( xy0, xy1); - float32x2_t rHi = vpadd_f32( xy2, xy2); - rLo = vadd_f32(rLo, zLo); - rHi = vadd_f32(rHi, zHi); - - uint32x2_t maskLo = vcgt_f32( rLo, dotMaxLo ); - uint32x2_t maskHi = vcgt_f32( rHi, dotMaxHi ); - dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo); - dotMaxHi = vbsl_f32( maskHi, rHi, dotMaxHi); - iLo = vbsl_u32(maskLo, indexLo, iLo); - iHi = vbsl_u32(maskHi, indexHi, iHi); - } - break; - case 2: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - - float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); - float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); - - float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x2_t zLo = vmul_f32( z0.val[0], vHi); - - float32x2_t rLo = vpadd_f32( xy0, xy1); - rLo = vadd_f32(rLo, zLo); - - uint32x2_t maskLo = vcgt_f32( rLo, dotMaxLo ); - dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo); - iLo = vbsl_u32(maskLo, indexLo, iLo); - } - break; - case 1: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); - float32x2_t z0 = vdup_lane_f32(vget_high_f32(v0), 0); - float32x2_t zLo = vmul_f32( z0, vHi); - float32x2_t rLo = vpadd_f32( xy0, xy0); - rLo = vadd_f32(rLo, zLo); - uint32x2_t maskLo = vcgt_f32( rLo, dotMaxLo ); - dotMaxLo = vbsl_f32( maskLo, rLo, dotMaxLo); - iLo = vbsl_u32(maskLo, indexLo, iLo); - } - break; - - default: - break; - } - - // select best answer between hi and lo results - uint32x2_t mask = vcgt_f32( dotMaxHi, dotMaxLo ); - dotMaxLo = vbsl_f32(mask, dotMaxHi, dotMaxLo); - iLo = vbsl_u32(mask, iHi, iLo); - - // select best answer between even and odd results - dotMaxHi = vdup_lane_f32(dotMaxLo, 1); - iHi = vdup_lane_u32(iLo, 1); - mask = vcgt_f32( dotMaxHi, dotMaxLo ); - dotMaxLo = vbsl_f32(mask, dotMaxHi, dotMaxLo); - iLo = vbsl_u32(mask, iHi, iLo); - - *dotResult = vget_lane_f32( dotMaxLo, 0); - return vget_lane_u32(iLo, 0); + float32x2x2_t z0 = vtrn_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x2x2_t z1 = vtrn_f32(vget_high_f32(v2), vget_high_f32(v3)); + float32x2_t zLo = vmul_f32(z0.val[0], vHi); + float32x2_t zHi = vmul_f32(z1.val[0], vHi); + + float32x2_t rLo = vpadd_f32(xy0, xy1); + float32x2_t rHi = vpadd_f32(xy2, xy3); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); + + uint32x2_t maskLo = vcgt_f32(rLo, dotMaxLo); + uint32x2_t maskHi = vcgt_f32(rHi, dotMaxHi); + dotMaxLo = vbsl_f32(maskLo, rLo, dotMaxLo); + dotMaxHi = vbsl_f32(maskHi, rHi, dotMaxHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + indexLo = vadd_u32(indexLo, four); + indexHi = vadd_u32(indexHi, four); + + v0 = vld1q_f32_aligned_postincrement(vv); + v1 = vld1q_f32_aligned_postincrement(vv); + v2 = vld1q_f32_aligned_postincrement(vv); + v3 = vld1q_f32_aligned_postincrement(vv); + + xy0 = vmul_f32(vget_low_f32(v0), vLo); + xy1 = vmul_f32(vget_low_f32(v1), vLo); + xy2 = vmul_f32(vget_low_f32(v2), vLo); + xy3 = vmul_f32(vget_low_f32(v3), vLo); + + z0 = vtrn_f32(vget_high_f32(v0), vget_high_f32(v1)); + z1 = vtrn_f32(vget_high_f32(v2), vget_high_f32(v3)); + zLo = vmul_f32(z0.val[0], vHi); + zHi = vmul_f32(z1.val[0], vHi); + + rLo = vpadd_f32(xy0, xy1); + rHi = vpadd_f32(xy2, xy3); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); + + maskLo = vcgt_f32(rLo, dotMaxLo); + maskHi = vcgt_f32(rHi, dotMaxHi); + dotMaxLo = vbsl_f32(maskLo, rLo, dotMaxLo); + dotMaxHi = vbsl_f32(maskHi, rHi, dotMaxHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + indexLo = vadd_u32(indexLo, four); + indexHi = vadd_u32(indexHi, four); + } + + for (; i + 4 <= count; i += 4) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v3 = vld1q_f32_aligned_postincrement(vv); + + float32x2_t xy0 = vmul_f32(vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32(vget_low_f32(v1), vLo); + float32x2_t xy2 = vmul_f32(vget_low_f32(v2), vLo); + float32x2_t xy3 = vmul_f32(vget_low_f32(v3), vLo); + + float32x2x2_t z0 = vtrn_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x2x2_t z1 = vtrn_f32(vget_high_f32(v2), vget_high_f32(v3)); + float32x2_t zLo = vmul_f32(z0.val[0], vHi); + float32x2_t zHi = vmul_f32(z1.val[0], vHi); + + float32x2_t rLo = vpadd_f32(xy0, xy1); + float32x2_t rHi = vpadd_f32(xy2, xy3); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); + + uint32x2_t maskLo = vcgt_f32(rLo, dotMaxLo); + uint32x2_t maskHi = vcgt_f32(rHi, dotMaxHi); + dotMaxLo = vbsl_f32(maskLo, rLo, dotMaxLo); + dotMaxHi = vbsl_f32(maskHi, rHi, dotMaxHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + indexLo = vadd_u32(indexLo, four); + indexHi = vadd_u32(indexHi, four); + } + + switch (count & 3) + { + case 3: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + + float32x2_t xy0 = vmul_f32(vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32(vget_low_f32(v1), vLo); + float32x2_t xy2 = vmul_f32(vget_low_f32(v2), vLo); + + float32x2x2_t z0 = vtrn_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x2_t zLo = vmul_f32(z0.val[0], vHi); + float32x2_t zHi = vmul_f32(vdup_lane_f32(vget_high_f32(v2), 0), vHi); + + float32x2_t rLo = vpadd_f32(xy0, xy1); + float32x2_t rHi = vpadd_f32(xy2, xy2); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); + + uint32x2_t maskLo = vcgt_f32(rLo, dotMaxLo); + uint32x2_t maskHi = vcgt_f32(rHi, dotMaxHi); + dotMaxLo = vbsl_f32(maskLo, rLo, dotMaxLo); + dotMaxHi = vbsl_f32(maskHi, rHi, dotMaxHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + } + break; + case 2: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + + float32x2_t xy0 = vmul_f32(vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32(vget_low_f32(v1), vLo); + + float32x2x2_t z0 = vtrn_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x2_t zLo = vmul_f32(z0.val[0], vHi); + + float32x2_t rLo = vpadd_f32(xy0, xy1); + rLo = vadd_f32(rLo, zLo); + + uint32x2_t maskLo = vcgt_f32(rLo, dotMaxLo); + dotMaxLo = vbsl_f32(maskLo, rLo, dotMaxLo); + iLo = vbsl_u32(maskLo, indexLo, iLo); + } + break; + case 1: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x2_t xy0 = vmul_f32(vget_low_f32(v0), vLo); + float32x2_t z0 = vdup_lane_f32(vget_high_f32(v0), 0); + float32x2_t zLo = vmul_f32(z0, vHi); + float32x2_t rLo = vpadd_f32(xy0, xy0); + rLo = vadd_f32(rLo, zLo); + uint32x2_t maskLo = vcgt_f32(rLo, dotMaxLo); + dotMaxLo = vbsl_f32(maskLo, rLo, dotMaxLo); + iLo = vbsl_u32(maskLo, indexLo, iLo); + } + break; + + default: + break; + } + + // select best answer between hi and lo results + uint32x2_t mask = vcgt_f32(dotMaxHi, dotMaxLo); + dotMaxLo = vbsl_f32(mask, dotMaxHi, dotMaxLo); + iLo = vbsl_u32(mask, iHi, iLo); + + // select best answer between even and odd results + dotMaxHi = vdup_lane_f32(dotMaxLo, 1); + iHi = vdup_lane_u32(iLo, 1); + mask = vcgt_f32(dotMaxHi, dotMaxLo); + dotMaxLo = vbsl_f32(mask, dotMaxHi, dotMaxLo); + iLo = vbsl_u32(mask, iHi, iLo); + + *dotResult = vget_lane_f32(dotMaxLo, 0); + return vget_lane_u32(iLo, 0); } - -long _maxdot_large_v1( const float *vv, const float *vec, unsigned long count, float *dotResult ) +long _maxdot_large_v1(const float *vv, const float *vec, unsigned long count, float *dotResult) { - float32x4_t vvec = vld1q_f32_aligned_postincrement( vec ); - float32x4_t vLo = vcombine_f32(vget_low_f32(vvec), vget_low_f32(vvec)); - float32x4_t vHi = vdupq_lane_f32(vget_high_f32(vvec), 0); - const uint32x4_t four = (uint32x4_t){ 4, 4, 4, 4 }; - uint32x4_t local_index = (uint32x4_t) {0, 1, 2, 3}; - uint32x4_t index = (uint32x4_t) { static_cast(-1), static_cast(-1), static_cast(-1), static_cast(-1) }; - float32x4_t maxDot = (float32x4_t) { -BT_INFINITY, -BT_INFINITY, -BT_INFINITY, -BT_INFINITY }; - - unsigned long i = 0; - for( ; i + 8 <= count; i += 8 ) - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); - - // the next two lines should resolve to a single vswp d, d - float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); - float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3)); - // the next two lines should resolve to a single vswp d, d - float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3)); - - xy0 = vmulq_f32(xy0, vLo); - xy1 = vmulq_f32(xy1, vLo); - - float32x4x2_t zb = vuzpq_f32( z0, z1); - float32x4_t z = vmulq_f32( zb.val[0], vHi); - float32x4x2_t xy = vuzpq_f32( xy0, xy1); - float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); - - uint32x4_t mask = vcgtq_f32(x, maxDot); - maxDot = vbslq_f32( mask, x, maxDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); + float32x4_t vvec = vld1q_f32_aligned_postincrement(vec); + float32x4_t vLo = vcombine_f32(vget_low_f32(vvec), vget_low_f32(vvec)); + float32x4_t vHi = vdupq_lane_f32(vget_high_f32(vvec), 0); + const uint32x4_t four = (uint32x4_t){4, 4, 4, 4}; + uint32x4_t local_index = (uint32x4_t){0, 1, 2, 3}; + uint32x4_t index = (uint32x4_t){static_cast(-1), static_cast(-1), static_cast(-1), static_cast(-1)}; + float32x4_t maxDot = (float32x4_t){-BT_INFINITY, -BT_INFINITY, -BT_INFINITY, -BT_INFINITY}; - v0 = vld1q_f32_aligned_postincrement( vv ); - v1 = vld1q_f32_aligned_postincrement( vv ); - v2 = vld1q_f32_aligned_postincrement( vv ); - v3 = vld1q_f32_aligned_postincrement( vv ); - - // the next two lines should resolve to a single vswp d, d - xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); - xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3)); - // the next two lines should resolve to a single vswp d, d - z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); - z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3)); - - xy0 = vmulq_f32(xy0, vLo); - xy1 = vmulq_f32(xy1, vLo); - - zb = vuzpq_f32( z0, z1); - z = vmulq_f32( zb.val[0], vHi); - xy = vuzpq_f32( xy0, xy1); - x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); - - mask = vcgtq_f32(x, maxDot); - maxDot = vbslq_f32( mask, x, maxDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - } + unsigned long i = 0; + for (; i + 8 <= count; i += 8) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v3 = vld1q_f32_aligned_postincrement(vv); - for( ; i + 4 <= count; i += 4 ) - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v1)); + float32x4_t xy1 = vcombine_f32(vget_low_f32(v2), vget_low_f32(v3)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x4_t z1 = vcombine_f32(vget_high_f32(v2), vget_high_f32(v3)); - // the next two lines should resolve to a single vswp d, d - float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); - float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3)); - // the next two lines should resolve to a single vswp d, d - float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3)); - - xy0 = vmulq_f32(xy0, vLo); - xy1 = vmulq_f32(xy1, vLo); - - float32x4x2_t zb = vuzpq_f32( z0, z1); - float32x4_t z = vmulq_f32( zb.val[0], vHi); - float32x4x2_t xy = vuzpq_f32( xy0, xy1); - float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); - - uint32x4_t mask = vcgtq_f32(x, maxDot); - maxDot = vbslq_f32( mask, x, maxDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - } - - switch (count & 3) { - case 3: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - - // the next two lines should resolve to a single vswp d, d - float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); - float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v2)); - // the next two lines should resolve to a single vswp d, d - float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v2)); - - xy0 = vmulq_f32(xy0, vLo); - xy1 = vmulq_f32(xy1, vLo); - - float32x4x2_t zb = vuzpq_f32( z0, z1); - float32x4_t z = vmulq_f32( zb.val[0], vHi); - float32x4x2_t xy = vuzpq_f32( xy0, xy1); - float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); - - uint32x4_t mask = vcgtq_f32(x, maxDot); - maxDot = vbslq_f32( mask, x, maxDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - } - break; + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); - case 2: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - - // the next two lines should resolve to a single vswp d, d - float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); - // the next two lines should resolve to a single vswp d, d - float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); - - xy0 = vmulq_f32(xy0, vLo); - - float32x4x2_t zb = vuzpq_f32( z0, z0); - float32x4_t z = vmulq_f32( zb.val[0], vHi); - float32x4x2_t xy = vuzpq_f32( xy0, xy0); - float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); - - uint32x4_t mask = vcgtq_f32(x, maxDot); - maxDot = vbslq_f32( mask, x, maxDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - } - break; + float32x4x2_t zb = vuzpq_f32(z0, z1); + float32x4_t z = vmulq_f32(zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32(xy0, xy1); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); - case 1: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - - // the next two lines should resolve to a single vswp d, d - float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v0)); - // the next two lines should resolve to a single vswp d, d - float32x4_t z = vdupq_lane_f32(vget_high_f32(v0), 0); - - xy0 = vmulq_f32(xy0, vLo); - - z = vmulq_f32( z, vHi); - float32x4x2_t xy = vuzpq_f32( xy0, xy0); - float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); - - uint32x4_t mask = vcgtq_f32(x, maxDot); - maxDot = vbslq_f32( mask, x, maxDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - } - break; + uint32x4_t mask = vcgtq_f32(x, maxDot); + maxDot = vbslq_f32(mask, x, maxDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); - default: - break; - } - - - // select best answer between hi and lo results - uint32x2_t mask = vcgt_f32( vget_high_f32(maxDot), vget_low_f32(maxDot)); - float32x2_t maxDot2 = vbsl_f32(mask, vget_high_f32(maxDot), vget_low_f32(maxDot)); - uint32x2_t index2 = vbsl_u32(mask, vget_high_u32(index), vget_low_u32(index)); - - // select best answer between even and odd results - float32x2_t maxDotO = vdup_lane_f32(maxDot2, 1); - uint32x2_t indexHi = vdup_lane_u32(index2, 1); - mask = vcgt_f32( maxDotO, maxDot2 ); - maxDot2 = vbsl_f32(mask, maxDotO, maxDot2); - index2 = vbsl_u32(mask, indexHi, index2); - - *dotResult = vget_lane_f32( maxDot2, 0); - return vget_lane_u32(index2, 0); - + v0 = vld1q_f32_aligned_postincrement(vv); + v1 = vld1q_f32_aligned_postincrement(vv); + v2 = vld1q_f32_aligned_postincrement(vv); + v3 = vld1q_f32_aligned_postincrement(vv); + + // the next two lines should resolve to a single vswp d, d + xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v1)); + xy1 = vcombine_f32(vget_low_f32(v2), vget_low_f32(v3)); + // the next two lines should resolve to a single vswp d, d + z0 = vcombine_f32(vget_high_f32(v0), vget_high_f32(v1)); + z1 = vcombine_f32(vget_high_f32(v2), vget_high_f32(v3)); + + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); + + zb = vuzpq_f32(z0, z1); + z = vmulq_f32(zb.val[0], vHi); + xy = vuzpq_f32(xy0, xy1); + x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + mask = vcgtq_f32(x, maxDot); + maxDot = vbslq_f32(mask, x, maxDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + + for (; i + 4 <= count; i += 4) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v3 = vld1q_f32_aligned_postincrement(vv); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v1)); + float32x4_t xy1 = vcombine_f32(vget_low_f32(v2), vget_low_f32(v3)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x4_t z1 = vcombine_f32(vget_high_f32(v2), vget_high_f32(v3)); + + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); + + float32x4x2_t zb = vuzpq_f32(z0, z1); + float32x4_t z = vmulq_f32(zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32(xy0, xy1); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcgtq_f32(x, maxDot); + maxDot = vbslq_f32(mask, x, maxDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + + switch (count & 3) + { + case 3: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v1)); + float32x4_t xy1 = vcombine_f32(vget_low_f32(v2), vget_low_f32(v2)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x4_t z1 = vcombine_f32(vget_high_f32(v2), vget_high_f32(v2)); + + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); + + float32x4x2_t zb = vuzpq_f32(z0, z1); + float32x4_t z = vmulq_f32(zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32(xy0, xy1); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcgtq_f32(x, maxDot); + maxDot = vbslq_f32(mask, x, maxDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + break; + + case 2: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v1)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32(vget_high_f32(v0), vget_high_f32(v1)); + + xy0 = vmulq_f32(xy0, vLo); + + float32x4x2_t zb = vuzpq_f32(z0, z0); + float32x4_t z = vmulq_f32(zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32(xy0, xy0); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcgtq_f32(x, maxDot); + maxDot = vbslq_f32(mask, x, maxDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + break; + + case 1: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v0)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z = vdupq_lane_f32(vget_high_f32(v0), 0); + + xy0 = vmulq_f32(xy0, vLo); + + z = vmulq_f32(z, vHi); + float32x4x2_t xy = vuzpq_f32(xy0, xy0); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcgtq_f32(x, maxDot); + maxDot = vbslq_f32(mask, x, maxDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + break; + + default: + break; + } + + // select best answer between hi and lo results + uint32x2_t mask = vcgt_f32(vget_high_f32(maxDot), vget_low_f32(maxDot)); + float32x2_t maxDot2 = vbsl_f32(mask, vget_high_f32(maxDot), vget_low_f32(maxDot)); + uint32x2_t index2 = vbsl_u32(mask, vget_high_u32(index), vget_low_u32(index)); + + // select best answer between even and odd results + float32x2_t maxDotO = vdup_lane_f32(maxDot2, 1); + uint32x2_t indexHi = vdup_lane_u32(index2, 1); + mask = vcgt_f32(maxDotO, maxDot2); + maxDot2 = vbsl_f32(mask, maxDotO, maxDot2); + index2 = vbsl_u32(mask, indexHi, index2); + + *dotResult = vget_lane_f32(maxDot2, 0); + return vget_lane_u32(index2, 0); } -long _mindot_large_v0( const float *vv, const float *vec, unsigned long count, float *dotResult ) +long _mindot_large_v0(const float *vv, const float *vec, unsigned long count, float *dotResult) { - unsigned long i = 0; - float32x4_t vvec = vld1q_f32_aligned_postincrement( vec ); - float32x2_t vLo = vget_low_f32(vvec); - float32x2_t vHi = vdup_lane_f32(vget_high_f32(vvec), 0); - float32x2_t dotMinLo = (float32x2_t) { BT_INFINITY, BT_INFINITY }; - float32x2_t dotMinHi = (float32x2_t) { BT_INFINITY, BT_INFINITY }; - uint32x2_t indexLo = (uint32x2_t) {0, 1}; - uint32x2_t indexHi = (uint32x2_t) {2, 3}; - uint32x2_t iLo = (uint32x2_t) {static_cast(-1), static_cast(-1)}; - uint32x2_t iHi = (uint32x2_t) {static_cast(-1), static_cast(-1)}; - const uint32x2_t four = (uint32x2_t) {4,4}; - - for( ; i+8 <= count; i+= 8 ) - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); - - float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); - float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); - float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo); - float32x2_t xy3 = vmul_f32( vget_low_f32(v3), vLo); - - float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x2x2_t z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3)); - float32x2_t zLo = vmul_f32( z0.val[0], vHi); - float32x2_t zHi = vmul_f32( z1.val[0], vHi); - - float32x2_t rLo = vpadd_f32( xy0, xy1); - float32x2_t rHi = vpadd_f32( xy2, xy3); - rLo = vadd_f32(rLo, zLo); - rHi = vadd_f32(rHi, zHi); - - uint32x2_t maskLo = vclt_f32( rLo, dotMinLo ); - uint32x2_t maskHi = vclt_f32( rHi, dotMinHi ); - dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo); - dotMinHi = vbsl_f32( maskHi, rHi, dotMinHi); - iLo = vbsl_u32(maskLo, indexLo, iLo); - iHi = vbsl_u32(maskHi, indexHi, iHi); - indexLo = vadd_u32(indexLo, four); - indexHi = vadd_u32(indexHi, four); - - v0 = vld1q_f32_aligned_postincrement( vv ); - v1 = vld1q_f32_aligned_postincrement( vv ); - v2 = vld1q_f32_aligned_postincrement( vv ); - v3 = vld1q_f32_aligned_postincrement( vv ); - - xy0 = vmul_f32( vget_low_f32(v0), vLo); - xy1 = vmul_f32( vget_low_f32(v1), vLo); - xy2 = vmul_f32( vget_low_f32(v2), vLo); - xy3 = vmul_f32( vget_low_f32(v3), vLo); - - z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); - z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3)); - zLo = vmul_f32( z0.val[0], vHi); - zHi = vmul_f32( z1.val[0], vHi); - - rLo = vpadd_f32( xy0, xy1); - rHi = vpadd_f32( xy2, xy3); - rLo = vadd_f32(rLo, zLo); - rHi = vadd_f32(rHi, zHi); - - maskLo = vclt_f32( rLo, dotMinLo ); - maskHi = vclt_f32( rHi, dotMinHi ); - dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo); - dotMinHi = vbsl_f32( maskHi, rHi, dotMinHi); - iLo = vbsl_u32(maskLo, indexLo, iLo); - iHi = vbsl_u32(maskHi, indexHi, iHi); - indexLo = vadd_u32(indexLo, four); - indexHi = vadd_u32(indexHi, four); - } + unsigned long i = 0; + float32x4_t vvec = vld1q_f32_aligned_postincrement(vec); + float32x2_t vLo = vget_low_f32(vvec); + float32x2_t vHi = vdup_lane_f32(vget_high_f32(vvec), 0); + float32x2_t dotMinLo = (float32x2_t){BT_INFINITY, BT_INFINITY}; + float32x2_t dotMinHi = (float32x2_t){BT_INFINITY, BT_INFINITY}; + uint32x2_t indexLo = (uint32x2_t){0, 1}; + uint32x2_t indexHi = (uint32x2_t){2, 3}; + uint32x2_t iLo = (uint32x2_t){static_cast(-1), static_cast(-1)}; + uint32x2_t iHi = (uint32x2_t){static_cast(-1), static_cast(-1)}; + const uint32x2_t four = (uint32x2_t){4, 4}; - for( ; i+4 <= count; i+= 4 ) - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); - - float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); - float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); - float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo); - float32x2_t xy3 = vmul_f32( vget_low_f32(v3), vLo); - - float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x2x2_t z1 = vtrn_f32( vget_high_f32(v2), vget_high_f32(v3)); - float32x2_t zLo = vmul_f32( z0.val[0], vHi); - float32x2_t zHi = vmul_f32( z1.val[0], vHi); - - float32x2_t rLo = vpadd_f32( xy0, xy1); - float32x2_t rHi = vpadd_f32( xy2, xy3); - rLo = vadd_f32(rLo, zLo); - rHi = vadd_f32(rHi, zHi); - - uint32x2_t maskLo = vclt_f32( rLo, dotMinLo ); - uint32x2_t maskHi = vclt_f32( rHi, dotMinHi ); - dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo); - dotMinHi = vbsl_f32( maskHi, rHi, dotMinHi); - iLo = vbsl_u32(maskLo, indexLo, iLo); - iHi = vbsl_u32(maskHi, indexHi, iHi); - indexLo = vadd_u32(indexLo, four); - indexHi = vadd_u32(indexHi, four); - } - switch( count & 3 ) - { - case 3: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - - float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); - float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); - float32x2_t xy2 = vmul_f32( vget_low_f32(v2), vLo); - - float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x2_t zLo = vmul_f32( z0.val[0], vHi); - float32x2_t zHi = vmul_f32( vdup_lane_f32(vget_high_f32(v2), 0), vHi); - - float32x2_t rLo = vpadd_f32( xy0, xy1); - float32x2_t rHi = vpadd_f32( xy2, xy2); - rLo = vadd_f32(rLo, zLo); - rHi = vadd_f32(rHi, zHi); - - uint32x2_t maskLo = vclt_f32( rLo, dotMinLo ); - uint32x2_t maskHi = vclt_f32( rHi, dotMinHi ); - dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo); - dotMinHi = vbsl_f32( maskHi, rHi, dotMinHi); - iLo = vbsl_u32(maskLo, indexLo, iLo); - iHi = vbsl_u32(maskHi, indexHi, iHi); - } - break; - case 2: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - - float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); - float32x2_t xy1 = vmul_f32( vget_low_f32(v1), vLo); - - float32x2x2_t z0 = vtrn_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x2_t zLo = vmul_f32( z0.val[0], vHi); - - float32x2_t rLo = vpadd_f32( xy0, xy1); - rLo = vadd_f32(rLo, zLo); - - uint32x2_t maskLo = vclt_f32( rLo, dotMinLo ); - dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo); - iLo = vbsl_u32(maskLo, indexLo, iLo); - } - break; - case 1: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x2_t xy0 = vmul_f32( vget_low_f32(v0), vLo); - float32x2_t z0 = vdup_lane_f32(vget_high_f32(v0), 0); - float32x2_t zLo = vmul_f32( z0, vHi); - float32x2_t rLo = vpadd_f32( xy0, xy0); - rLo = vadd_f32(rLo, zLo); - uint32x2_t maskLo = vclt_f32( rLo, dotMinLo ); - dotMinLo = vbsl_f32( maskLo, rLo, dotMinLo); - iLo = vbsl_u32(maskLo, indexLo, iLo); - } - break; - - default: - break; - } - - // select best answer between hi and lo results - uint32x2_t mask = vclt_f32( dotMinHi, dotMinLo ); - dotMinLo = vbsl_f32(mask, dotMinHi, dotMinLo); - iLo = vbsl_u32(mask, iHi, iLo); - - // select best answer between even and odd results - dotMinHi = vdup_lane_f32(dotMinLo, 1); - iHi = vdup_lane_u32(iLo, 1); - mask = vclt_f32( dotMinHi, dotMinLo ); - dotMinLo = vbsl_f32(mask, dotMinHi, dotMinLo); - iLo = vbsl_u32(mask, iHi, iLo); - - *dotResult = vget_lane_f32( dotMinLo, 0); - return vget_lane_u32(iLo, 0); + for (; i + 8 <= count; i += 8) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v3 = vld1q_f32_aligned_postincrement(vv); + + float32x2_t xy0 = vmul_f32(vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32(vget_low_f32(v1), vLo); + float32x2_t xy2 = vmul_f32(vget_low_f32(v2), vLo); + float32x2_t xy3 = vmul_f32(vget_low_f32(v3), vLo); + + float32x2x2_t z0 = vtrn_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x2x2_t z1 = vtrn_f32(vget_high_f32(v2), vget_high_f32(v3)); + float32x2_t zLo = vmul_f32(z0.val[0], vHi); + float32x2_t zHi = vmul_f32(z1.val[0], vHi); + + float32x2_t rLo = vpadd_f32(xy0, xy1); + float32x2_t rHi = vpadd_f32(xy2, xy3); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); + + uint32x2_t maskLo = vclt_f32(rLo, dotMinLo); + uint32x2_t maskHi = vclt_f32(rHi, dotMinHi); + dotMinLo = vbsl_f32(maskLo, rLo, dotMinLo); + dotMinHi = vbsl_f32(maskHi, rHi, dotMinHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + indexLo = vadd_u32(indexLo, four); + indexHi = vadd_u32(indexHi, four); + + v0 = vld1q_f32_aligned_postincrement(vv); + v1 = vld1q_f32_aligned_postincrement(vv); + v2 = vld1q_f32_aligned_postincrement(vv); + v3 = vld1q_f32_aligned_postincrement(vv); + + xy0 = vmul_f32(vget_low_f32(v0), vLo); + xy1 = vmul_f32(vget_low_f32(v1), vLo); + xy2 = vmul_f32(vget_low_f32(v2), vLo); + xy3 = vmul_f32(vget_low_f32(v3), vLo); + + z0 = vtrn_f32(vget_high_f32(v0), vget_high_f32(v1)); + z1 = vtrn_f32(vget_high_f32(v2), vget_high_f32(v3)); + zLo = vmul_f32(z0.val[0], vHi); + zHi = vmul_f32(z1.val[0], vHi); + + rLo = vpadd_f32(xy0, xy1); + rHi = vpadd_f32(xy2, xy3); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); + + maskLo = vclt_f32(rLo, dotMinLo); + maskHi = vclt_f32(rHi, dotMinHi); + dotMinLo = vbsl_f32(maskLo, rLo, dotMinLo); + dotMinHi = vbsl_f32(maskHi, rHi, dotMinHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + indexLo = vadd_u32(indexLo, four); + indexHi = vadd_u32(indexHi, four); + } + + for (; i + 4 <= count; i += 4) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v3 = vld1q_f32_aligned_postincrement(vv); + + float32x2_t xy0 = vmul_f32(vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32(vget_low_f32(v1), vLo); + float32x2_t xy2 = vmul_f32(vget_low_f32(v2), vLo); + float32x2_t xy3 = vmul_f32(vget_low_f32(v3), vLo); + + float32x2x2_t z0 = vtrn_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x2x2_t z1 = vtrn_f32(vget_high_f32(v2), vget_high_f32(v3)); + float32x2_t zLo = vmul_f32(z0.val[0], vHi); + float32x2_t zHi = vmul_f32(z1.val[0], vHi); + + float32x2_t rLo = vpadd_f32(xy0, xy1); + float32x2_t rHi = vpadd_f32(xy2, xy3); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); + + uint32x2_t maskLo = vclt_f32(rLo, dotMinLo); + uint32x2_t maskHi = vclt_f32(rHi, dotMinHi); + dotMinLo = vbsl_f32(maskLo, rLo, dotMinLo); + dotMinHi = vbsl_f32(maskHi, rHi, dotMinHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + indexLo = vadd_u32(indexLo, four); + indexHi = vadd_u32(indexHi, four); + } + switch (count & 3) + { + case 3: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + + float32x2_t xy0 = vmul_f32(vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32(vget_low_f32(v1), vLo); + float32x2_t xy2 = vmul_f32(vget_low_f32(v2), vLo); + + float32x2x2_t z0 = vtrn_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x2_t zLo = vmul_f32(z0.val[0], vHi); + float32x2_t zHi = vmul_f32(vdup_lane_f32(vget_high_f32(v2), 0), vHi); + + float32x2_t rLo = vpadd_f32(xy0, xy1); + float32x2_t rHi = vpadd_f32(xy2, xy2); + rLo = vadd_f32(rLo, zLo); + rHi = vadd_f32(rHi, zHi); + + uint32x2_t maskLo = vclt_f32(rLo, dotMinLo); + uint32x2_t maskHi = vclt_f32(rHi, dotMinHi); + dotMinLo = vbsl_f32(maskLo, rLo, dotMinLo); + dotMinHi = vbsl_f32(maskHi, rHi, dotMinHi); + iLo = vbsl_u32(maskLo, indexLo, iLo); + iHi = vbsl_u32(maskHi, indexHi, iHi); + } + break; + case 2: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + + float32x2_t xy0 = vmul_f32(vget_low_f32(v0), vLo); + float32x2_t xy1 = vmul_f32(vget_low_f32(v1), vLo); + + float32x2x2_t z0 = vtrn_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x2_t zLo = vmul_f32(z0.val[0], vHi); + + float32x2_t rLo = vpadd_f32(xy0, xy1); + rLo = vadd_f32(rLo, zLo); + + uint32x2_t maskLo = vclt_f32(rLo, dotMinLo); + dotMinLo = vbsl_f32(maskLo, rLo, dotMinLo); + iLo = vbsl_u32(maskLo, indexLo, iLo); + } + break; + case 1: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x2_t xy0 = vmul_f32(vget_low_f32(v0), vLo); + float32x2_t z0 = vdup_lane_f32(vget_high_f32(v0), 0); + float32x2_t zLo = vmul_f32(z0, vHi); + float32x2_t rLo = vpadd_f32(xy0, xy0); + rLo = vadd_f32(rLo, zLo); + uint32x2_t maskLo = vclt_f32(rLo, dotMinLo); + dotMinLo = vbsl_f32(maskLo, rLo, dotMinLo); + iLo = vbsl_u32(maskLo, indexLo, iLo); + } + break; + + default: + break; + } + + // select best answer between hi and lo results + uint32x2_t mask = vclt_f32(dotMinHi, dotMinLo); + dotMinLo = vbsl_f32(mask, dotMinHi, dotMinLo); + iLo = vbsl_u32(mask, iHi, iLo); + + // select best answer between even and odd results + dotMinHi = vdup_lane_f32(dotMinLo, 1); + iHi = vdup_lane_u32(iLo, 1); + mask = vclt_f32(dotMinHi, dotMinLo); + dotMinLo = vbsl_f32(mask, dotMinHi, dotMinLo); + iLo = vbsl_u32(mask, iHi, iLo); + + *dotResult = vget_lane_f32(dotMinLo, 0); + return vget_lane_u32(iLo, 0); } -long _mindot_large_v1( const float *vv, const float *vec, unsigned long count, float *dotResult ) +long _mindot_large_v1(const float *vv, const float *vec, unsigned long count, float *dotResult) { - float32x4_t vvec = vld1q_f32_aligned_postincrement( vec ); - float32x4_t vLo = vcombine_f32(vget_low_f32(vvec), vget_low_f32(vvec)); - float32x4_t vHi = vdupq_lane_f32(vget_high_f32(vvec), 0); - const uint32x4_t four = (uint32x4_t){ 4, 4, 4, 4 }; - uint32x4_t local_index = (uint32x4_t) {0, 1, 2, 3}; - uint32x4_t index = (uint32x4_t) { static_cast(-1), static_cast(-1), static_cast(-1), static_cast(-1) }; - float32x4_t minDot = (float32x4_t) { BT_INFINITY, BT_INFINITY, BT_INFINITY, BT_INFINITY }; - - unsigned long i = 0; - for( ; i + 8 <= count; i += 8 ) - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); - - // the next two lines should resolve to a single vswp d, d - float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); - float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3)); - // the next two lines should resolve to a single vswp d, d - float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3)); - - xy0 = vmulq_f32(xy0, vLo); - xy1 = vmulq_f32(xy1, vLo); - - float32x4x2_t zb = vuzpq_f32( z0, z1); - float32x4_t z = vmulq_f32( zb.val[0], vHi); - float32x4x2_t xy = vuzpq_f32( xy0, xy1); - float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); - - uint32x4_t mask = vcltq_f32(x, minDot); - minDot = vbslq_f32( mask, x, minDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - - v0 = vld1q_f32_aligned_postincrement( vv ); - v1 = vld1q_f32_aligned_postincrement( vv ); - v2 = vld1q_f32_aligned_postincrement( vv ); - v3 = vld1q_f32_aligned_postincrement( vv ); - - // the next two lines should resolve to a single vswp d, d - xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); - xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3)); - // the next two lines should resolve to a single vswp d, d - z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); - z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3)); - - xy0 = vmulq_f32(xy0, vLo); - xy1 = vmulq_f32(xy1, vLo); - - zb = vuzpq_f32( z0, z1); - z = vmulq_f32( zb.val[0], vHi); - xy = vuzpq_f32( xy0, xy1); - x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); - - mask = vcltq_f32(x, minDot); - minDot = vbslq_f32( mask, x, minDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - } - - for( ; i + 4 <= count; i += 4 ) - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v3 = vld1q_f32_aligned_postincrement( vv ); - - // the next two lines should resolve to a single vswp d, d - float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); - float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v3)); - // the next two lines should resolve to a single vswp d, d - float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v3)); - - xy0 = vmulq_f32(xy0, vLo); - xy1 = vmulq_f32(xy1, vLo); - - float32x4x2_t zb = vuzpq_f32( z0, z1); - float32x4_t z = vmulq_f32( zb.val[0], vHi); - float32x4x2_t xy = vuzpq_f32( xy0, xy1); - float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); - - uint32x4_t mask = vcltq_f32(x, minDot); - minDot = vbslq_f32( mask, x, minDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - } - - switch (count & 3) { - case 3: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v2 = vld1q_f32_aligned_postincrement( vv ); - - // the next two lines should resolve to a single vswp d, d - float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); - float32x4_t xy1 = vcombine_f32( vget_low_f32(v2), vget_low_f32(v2)); - // the next two lines should resolve to a single vswp d, d - float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); - float32x4_t z1 = vcombine_f32( vget_high_f32(v2), vget_high_f32(v2)); - - xy0 = vmulq_f32(xy0, vLo); - xy1 = vmulq_f32(xy1, vLo); - - float32x4x2_t zb = vuzpq_f32( z0, z1); - float32x4_t z = vmulq_f32( zb.val[0], vHi); - float32x4x2_t xy = vuzpq_f32( xy0, xy1); - float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); - - uint32x4_t mask = vcltq_f32(x, minDot); - minDot = vbslq_f32( mask, x, minDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - } - break; - - case 2: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - float32x4_t v1 = vld1q_f32_aligned_postincrement( vv ); - - // the next two lines should resolve to a single vswp d, d - float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v1)); - // the next two lines should resolve to a single vswp d, d - float32x4_t z0 = vcombine_f32( vget_high_f32(v0), vget_high_f32(v1)); - - xy0 = vmulq_f32(xy0, vLo); - - float32x4x2_t zb = vuzpq_f32( z0, z0); - float32x4_t z = vmulq_f32( zb.val[0], vHi); - float32x4x2_t xy = vuzpq_f32( xy0, xy0); - float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); - - uint32x4_t mask = vcltq_f32(x, minDot); - minDot = vbslq_f32( mask, x, minDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - } - break; - - case 1: - { - float32x4_t v0 = vld1q_f32_aligned_postincrement( vv ); - - // the next two lines should resolve to a single vswp d, d - float32x4_t xy0 = vcombine_f32( vget_low_f32(v0), vget_low_f32(v0)); - // the next two lines should resolve to a single vswp d, d - float32x4_t z = vdupq_lane_f32(vget_high_f32(v0), 0); - - xy0 = vmulq_f32(xy0, vLo); - - z = vmulq_f32( z, vHi); - float32x4x2_t xy = vuzpq_f32( xy0, xy0); - float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); - x = vaddq_f32(x, z); - - uint32x4_t mask = vcltq_f32(x, minDot); - minDot = vbslq_f32( mask, x, minDot); - index = vbslq_u32(mask, local_index, index); - local_index = vaddq_u32(local_index, four); - } - break; - - default: - break; - } - - - // select best answer between hi and lo results - uint32x2_t mask = vclt_f32( vget_high_f32(minDot), vget_low_f32(minDot)); - float32x2_t minDot2 = vbsl_f32(mask, vget_high_f32(minDot), vget_low_f32(minDot)); - uint32x2_t index2 = vbsl_u32(mask, vget_high_u32(index), vget_low_u32(index)); - - // select best answer between even and odd results - float32x2_t minDotO = vdup_lane_f32(minDot2, 1); - uint32x2_t indexHi = vdup_lane_u32(index2, 1); - mask = vclt_f32( minDotO, minDot2 ); - minDot2 = vbsl_f32(mask, minDotO, minDot2); - index2 = vbsl_u32(mask, indexHi, index2); - - *dotResult = vget_lane_f32( minDot2, 0); - return vget_lane_u32(index2, 0); - + float32x4_t vvec = vld1q_f32_aligned_postincrement(vec); + float32x4_t vLo = vcombine_f32(vget_low_f32(vvec), vget_low_f32(vvec)); + float32x4_t vHi = vdupq_lane_f32(vget_high_f32(vvec), 0); + const uint32x4_t four = (uint32x4_t){4, 4, 4, 4}; + uint32x4_t local_index = (uint32x4_t){0, 1, 2, 3}; + uint32x4_t index = (uint32x4_t){static_cast(-1), static_cast(-1), static_cast(-1), static_cast(-1)}; + float32x4_t minDot = (float32x4_t){BT_INFINITY, BT_INFINITY, BT_INFINITY, BT_INFINITY}; + + unsigned long i = 0; + for (; i + 8 <= count; i += 8) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v3 = vld1q_f32_aligned_postincrement(vv); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v1)); + float32x4_t xy1 = vcombine_f32(vget_low_f32(v2), vget_low_f32(v3)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x4_t z1 = vcombine_f32(vget_high_f32(v2), vget_high_f32(v3)); + + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); + + float32x4x2_t zb = vuzpq_f32(z0, z1); + float32x4_t z = vmulq_f32(zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32(xy0, xy1); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcltq_f32(x, minDot); + minDot = vbslq_f32(mask, x, minDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + + v0 = vld1q_f32_aligned_postincrement(vv); + v1 = vld1q_f32_aligned_postincrement(vv); + v2 = vld1q_f32_aligned_postincrement(vv); + v3 = vld1q_f32_aligned_postincrement(vv); + + // the next two lines should resolve to a single vswp d, d + xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v1)); + xy1 = vcombine_f32(vget_low_f32(v2), vget_low_f32(v3)); + // the next two lines should resolve to a single vswp d, d + z0 = vcombine_f32(vget_high_f32(v0), vget_high_f32(v1)); + z1 = vcombine_f32(vget_high_f32(v2), vget_high_f32(v3)); + + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); + + zb = vuzpq_f32(z0, z1); + z = vmulq_f32(zb.val[0], vHi); + xy = vuzpq_f32(xy0, xy1); + x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + mask = vcltq_f32(x, minDot); + minDot = vbslq_f32(mask, x, minDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + + for (; i + 4 <= count; i += 4) + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v3 = vld1q_f32_aligned_postincrement(vv); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v1)); + float32x4_t xy1 = vcombine_f32(vget_low_f32(v2), vget_low_f32(v3)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x4_t z1 = vcombine_f32(vget_high_f32(v2), vget_high_f32(v3)); + + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); + + float32x4x2_t zb = vuzpq_f32(z0, z1); + float32x4_t z = vmulq_f32(zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32(xy0, xy1); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcltq_f32(x, minDot); + minDot = vbslq_f32(mask, x, minDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + + switch (count & 3) + { + case 3: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v2 = vld1q_f32_aligned_postincrement(vv); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v1)); + float32x4_t xy1 = vcombine_f32(vget_low_f32(v2), vget_low_f32(v2)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32(vget_high_f32(v0), vget_high_f32(v1)); + float32x4_t z1 = vcombine_f32(vget_high_f32(v2), vget_high_f32(v2)); + + xy0 = vmulq_f32(xy0, vLo); + xy1 = vmulq_f32(xy1, vLo); + + float32x4x2_t zb = vuzpq_f32(z0, z1); + float32x4_t z = vmulq_f32(zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32(xy0, xy1); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcltq_f32(x, minDot); + minDot = vbslq_f32(mask, x, minDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + break; + + case 2: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + float32x4_t v1 = vld1q_f32_aligned_postincrement(vv); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v1)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z0 = vcombine_f32(vget_high_f32(v0), vget_high_f32(v1)); + + xy0 = vmulq_f32(xy0, vLo); + + float32x4x2_t zb = vuzpq_f32(z0, z0); + float32x4_t z = vmulq_f32(zb.val[0], vHi); + float32x4x2_t xy = vuzpq_f32(xy0, xy0); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcltq_f32(x, minDot); + minDot = vbslq_f32(mask, x, minDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + break; + + case 1: + { + float32x4_t v0 = vld1q_f32_aligned_postincrement(vv); + + // the next two lines should resolve to a single vswp d, d + float32x4_t xy0 = vcombine_f32(vget_low_f32(v0), vget_low_f32(v0)); + // the next two lines should resolve to a single vswp d, d + float32x4_t z = vdupq_lane_f32(vget_high_f32(v0), 0); + + xy0 = vmulq_f32(xy0, vLo); + + z = vmulq_f32(z, vHi); + float32x4x2_t xy = vuzpq_f32(xy0, xy0); + float32x4_t x = vaddq_f32(xy.val[0], xy.val[1]); + x = vaddq_f32(x, z); + + uint32x4_t mask = vcltq_f32(x, minDot); + minDot = vbslq_f32(mask, x, minDot); + index = vbslq_u32(mask, local_index, index); + local_index = vaddq_u32(local_index, four); + } + break; + + default: + break; + } + + // select best answer between hi and lo results + uint32x2_t mask = vclt_f32(vget_high_f32(minDot), vget_low_f32(minDot)); + float32x2_t minDot2 = vbsl_f32(mask, vget_high_f32(minDot), vget_low_f32(minDot)); + uint32x2_t index2 = vbsl_u32(mask, vget_high_u32(index), vget_low_u32(index)); + + // select best answer between even and odd results + float32x2_t minDotO = vdup_lane_f32(minDot2, 1); + uint32x2_t indexHi = vdup_lane_u32(index2, 1); + mask = vclt_f32(minDotO, minDot2); + minDot2 = vbsl_f32(mask, minDotO, minDot2); + index2 = vbsl_u32(mask, indexHi, index2); + + *dotResult = vget_lane_f32(minDot2, 0); + return vget_lane_u32(index2, 0); } #else - #error Unhandled __APPLE__ arch +#error Unhandled __APPLE__ arch #endif -#endif /* __APPLE__ */ - - +#endif /* __APPLE__ */ diff --git a/src/LinearMath/btVector3.h b/src/LinearMath/btVector3.h index 76024f123..61fd8d1e4 100644 --- a/src/LinearMath/btVector3.h +++ b/src/LinearMath/btVector3.h @@ -12,8 +12,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - - #ifndef BT_VECTOR3_H #define BT_VECTOR3_H @@ -28,25 +26,24 @@ subject to the following restrictions: #else #define btVector3Data btVector3FloatData #define btVector3DataName "btVector3FloatData" -#endif //BT_USE_DOUBLE_PRECISION +#endif //BT_USE_DOUBLE_PRECISION #if defined BT_USE_SSE //typedef uint32_t __m128i __attribute__ ((vector_size(16))); #ifdef _MSC_VER -#pragma warning(disable: 4556) // value of intrinsic immediate argument '4294967239' is out of range '0 - 255' +#pragma warning(disable : 4556) // value of intrinsic immediate argument '4294967239' is out of range '0 - 255' #endif - -#define BT_SHUFFLE(x,y,z,w) ((w)<<6 | (z)<<4 | (y)<<2 | (x)) +#define BT_SHUFFLE(x, y, z, w) ((w) << 6 | (z) << 4 | (y) << 2 | (x)) //#define bt_pshufd_ps( _a, _mask ) (__m128) _mm_shuffle_epi32((__m128i)(_a), (_mask) ) -#define bt_pshufd_ps( _a, _mask ) _mm_shuffle_ps((_a), (_a), (_mask) ) -#define bt_splat3_ps( _a, _i ) bt_pshufd_ps((_a), BT_SHUFFLE(_i,_i,_i, 3) ) -#define bt_splat_ps( _a, _i ) bt_pshufd_ps((_a), BT_SHUFFLE(_i,_i,_i,_i) ) +#define bt_pshufd_ps(_a, _mask) _mm_shuffle_ps((_a), (_a), (_mask)) +#define bt_splat3_ps(_a, _i) bt_pshufd_ps((_a), BT_SHUFFLE(_i, _i, _i, 3)) +#define bt_splat_ps(_a, _i) bt_pshufd_ps((_a), BT_SHUFFLE(_i, _i, _i, _i)) #define btv3AbsiMask (_mm_set_epi32(0x00000000, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF)) -#define btvAbsMask (_mm_set_epi32( 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF)) +#define btvAbsMask (_mm_set_epi32(0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF)) #define btvFFF0Mask (_mm_set_epi32(0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF)) #define btv3AbsfMask btCastiTo128f(btv3AbsiMask) #define btvFFF0fMask btCastiTo128f(btvFFF0Mask) @@ -55,9 +52,9 @@ subject to the following restrictions: //there is an issue with XCode 3.2 (LCx errors) #define btvMzeroMask (_mm_set_ps(-0.0f, -0.0f, -0.0f, -0.0f)) -#define v1110 (_mm_set_ps(0.0f, 1.0f, 1.0f, 1.0f)) -#define vHalf (_mm_set_ps(0.5f, 0.5f, 0.5f, 0.5f)) -#define v1_5 (_mm_set_ps(1.5f, 1.5f, 1.5f, 1.5f)) +#define v1110 (_mm_set_ps(0.0f, 1.0f, 1.0f, 1.0f)) +#define vHalf (_mm_set_ps(0.5f, 0.5f, 0.5f, 0.5f)) +#define v1_5 (_mm_set_ps(1.5f, 1.5f, 1.5f, 1.5f)) //const __m128 ATTRIBUTE_ALIGNED16(btvMzeroMask) = {-0.0f, -0.0f, -0.0f, -0.0f}; //const __m128 ATTRIBUTE_ALIGNED16(v1110) = {1.0f, 1.0f, 1.0f, 0.0f}; @@ -70,7 +67,7 @@ subject to the following restrictions: const float32x4_t ATTRIBUTE_ALIGNED16(btvMzeroMask) = (float32x4_t){-0.0f, -0.0f, -0.0f, -0.0f}; const int32x4_t ATTRIBUTE_ALIGNED16(btvFFF0Mask) = (int32x4_t){static_cast(0xFFFFFFFF), - static_cast(0xFFFFFFFF), static_cast(0xFFFFFFFF), 0x0}; + static_cast(0xFFFFFFFF), static_cast(0xFFFFFFFF), 0x0}; const int32x4_t ATTRIBUTE_ALIGNED16(btvAbsMask) = (int32x4_t){0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF}; const int32x4_t ATTRIBUTE_ALIGNED16(btv3AbsMask) = (int32x4_t){0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x0}; @@ -80,50 +77,48 @@ const int32x4_t ATTRIBUTE_ALIGNED16(btv3AbsMask) = (int32x4_t){0x7FFFFFFF, 0x7FF * It has an un-used w component to suit 16-byte alignment when btVector3 is stored in containers. This extra component can be used by derived classes (Quaternion?) or by user * Ideally, this class should be replaced by a platform optimized SIMD version that keeps the data in registers */ -ATTRIBUTE_ALIGNED16(class) btVector3 +ATTRIBUTE_ALIGNED16(class) +btVector3 { public: - BT_DECLARE_ALIGNED_ALLOCATOR(); -#if defined (__SPU__) && defined (__CELLOS_LV2__) - btScalar m_floats[4]; +#if defined(__SPU__) && defined(__CELLOS_LV2__) + btScalar m_floats[4]; + public: - SIMD_FORCE_INLINE const vec_float4& get128() const + SIMD_FORCE_INLINE const vec_float4& get128() const { return *((const vec_float4*)&m_floats[0]); } + public: -#else //__CELLOS_LV2__ __SPU__ - #if defined (BT_USE_SSE) || defined(BT_USE_NEON) // _WIN32 || ARM - union { - btSimdFloat4 mVec128; - btScalar m_floats[4]; - }; - SIMD_FORCE_INLINE btSimdFloat4 get128() const - { - return mVec128; - } - SIMD_FORCE_INLINE void set128(btSimdFloat4 v128) - { - mVec128 = v128; - } - #else - btScalar m_floats[4]; - #endif -#endif //__CELLOS_LV2__ __SPU__ - - public: - - /**@brief No initialization constructor */ - SIMD_FORCE_INLINE btVector3() +#else //__CELLOS_LV2__ __SPU__ +#if defined(BT_USE_SSE) || defined(BT_USE_NEON) // _WIN32 || ARM + union { + btSimdFloat4 mVec128; + btScalar m_floats[4]; + }; + SIMD_FORCE_INLINE btSimdFloat4 get128() const { + return mVec128; + } + SIMD_FORCE_INLINE void set128(btSimdFloat4 v128) + { + mVec128 = v128; + } +#else + btScalar m_floats[4]; +#endif +#endif //__CELLOS_LV2__ __SPU__ +public: + /**@brief No initialization constructor */ + SIMD_FORCE_INLINE btVector3() + { } - - - /**@brief Constructor from scalars + /**@brief Constructor from scalars * @param x X value * @param y Y value * @param z Z value @@ -136,9 +131,9 @@ public: m_floats[3] = btScalar(0.f); } -#if (defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) )|| defined (BT_USE_NEON) - // Set Vector - SIMD_FORCE_INLINE btVector3( btSimdFloat4 v) +#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) || defined(BT_USE_NEON) + // Set Vector + SIMD_FORCE_INLINE btVector3(btSimdFloat4 v) { mVec128 = v; } @@ -150,73 +145,72 @@ public: } // Assignment Operator - SIMD_FORCE_INLINE btVector3& - operator=(const btVector3& v) + SIMD_FORCE_INLINE btVector3& + operator=(const btVector3& v) { mVec128 = v.mVec128; - + return *this; } -#endif // #if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - -/**@brief Add a vector to this one +#endif // #if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) + + /**@brief Add a vector to this one * @param The vector to add to this one */ SIMD_FORCE_INLINE btVector3& operator+=(const btVector3& v) { -#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) mVec128 = _mm_add_ps(mVec128, v.mVec128); #elif defined(BT_USE_NEON) mVec128 = vaddq_f32(mVec128, v.mVec128); #else - m_floats[0] += v.m_floats[0]; + m_floats[0] += v.m_floats[0]; m_floats[1] += v.m_floats[1]; m_floats[2] += v.m_floats[2]; #endif return *this; } - - /**@brief Subtract a vector from this one + /**@brief Subtract a vector from this one * @param The vector to subtract */ - SIMD_FORCE_INLINE btVector3& operator-=(const btVector3& v) + SIMD_FORCE_INLINE btVector3& operator-=(const btVector3& v) { -#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) mVec128 = _mm_sub_ps(mVec128, v.mVec128); #elif defined(BT_USE_NEON) mVec128 = vsubq_f32(mVec128, v.mVec128); #else - m_floats[0] -= v.m_floats[0]; + m_floats[0] -= v.m_floats[0]; m_floats[1] -= v.m_floats[1]; m_floats[2] -= v.m_floats[2]; #endif return *this; } - - /**@brief Scale the vector + + /**@brief Scale the vector * @param s Scale factor */ SIMD_FORCE_INLINE btVector3& operator*=(const btScalar& s) { -#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) - __m128 vs = _mm_load_ss(&s); // (S 0 0 0) - vs = bt_pshufd_ps(vs, 0x80); // (S S S 0.0) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) + __m128 vs = _mm_load_ss(&s); // (S 0 0 0) + vs = bt_pshufd_ps(vs, 0x80); // (S S S 0.0) mVec128 = _mm_mul_ps(mVec128, vs); #elif defined(BT_USE_NEON) mVec128 = vmulq_n_f32(mVec128, s); #else - m_floats[0] *= s; + m_floats[0] *= s; m_floats[1] *= s; m_floats[2] *= s; #endif return *this; } - /**@brief Inversely scale the vector + /**@brief Inversely scale the vector * @param s Scale factor to divide by */ - SIMD_FORCE_INLINE btVector3& operator/=(const btScalar& s) + SIMD_FORCE_INLINE btVector3& operator/=(const btScalar& s) { btFullAssert(s != btScalar(0.0)); -#if 0 //defined(BT_USE_SSE_IN_API) +#if 0 //defined(BT_USE_SSE_IN_API) // this code is not faster ! __m128 vs = _mm_load_ss(&s); vs = _mm_div_ss(v1110, vs); @@ -230,11 +224,11 @@ public: #endif } - /**@brief Return the dot product + /**@brief Return the dot product * @param v The other vector in the dot product */ SIMD_FORCE_INLINE btScalar dot(const btVector3& v) const { -#if defined BT_USE_SIMD_VECTOR3 && defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined BT_USE_SIMD_VECTOR3 && defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) __m128 vd = _mm_mul_ps(mVec128, v.mVec128); __m128 z = _mm_movehl_ps(vd, vd); __m128 y = _mm_shuffle_ps(vd, vd, 0x55); @@ -243,23 +237,23 @@ public: return _mm_cvtss_f32(vd); #elif defined(BT_USE_NEON) float32x4_t vd = vmulq_f32(mVec128, v.mVec128); - float32x2_t x = vpadd_f32(vget_low_f32(vd), vget_low_f32(vd)); + float32x2_t x = vpadd_f32(vget_low_f32(vd), vget_low_f32(vd)); x = vadd_f32(x, vget_high_f32(vd)); return vget_lane_f32(x, 0); -#else - return m_floats[0] * v.m_floats[0] + - m_floats[1] * v.m_floats[1] + - m_floats[2] * v.m_floats[2]; +#else + return m_floats[0] * v.m_floats[0] + + m_floats[1] * v.m_floats[1] + + m_floats[2] * v.m_floats[2]; #endif } - /**@brief Return the length of the vector squared */ + /**@brief Return the length of the vector squared */ SIMD_FORCE_INLINE btScalar length2() const { return dot(*this); } - /**@brief Return the length of the vector */ + /**@brief Return the length of the vector */ SIMD_FORCE_INLINE btScalar length() const { return btSqrt(length2()); @@ -267,7 +261,7 @@ public: /**@brief Return the norm (length) of the vector */ SIMD_FORCE_INLINE btScalar norm() const - { + { return length(); } @@ -276,24 +270,24 @@ public: { btScalar d = length2(); //workaround for some clang/gcc issue of sqrtf(tiny number) = -INF - if (d>SIMD_EPSILON) + if (d > SIMD_EPSILON) return btSqrt(d); return btScalar(0); } - /**@brief Return the distance squared between the ends of this and another vector + /**@brief Return the distance squared between the ends of this and another vector * This is symantically treating the vector like a point */ SIMD_FORCE_INLINE btScalar distance2(const btVector3& v) const; - /**@brief Return the distance between the ends of this and another vector + /**@brief Return the distance between the ends of this and another vector * This is symantically treating the vector like a point */ SIMD_FORCE_INLINE btScalar distance(const btVector3& v) const; - SIMD_FORCE_INLINE btVector3& safeNormalize() + SIMD_FORCE_INLINE btVector3& safeNormalize() { btScalar l2 = length2(); //triNormal.normalize(); - if (l2 >= SIMD_EPSILON*SIMD_EPSILON) + if (l2 >= SIMD_EPSILON * SIMD_EPSILON) { (*this) /= btSqrt(l2); } @@ -304,100 +298,97 @@ public: return *this; } - /**@brief Normalize this vector + /**@brief Normalize this vector * x^2 + y^2 + z^2 = 1 */ - SIMD_FORCE_INLINE btVector3& normalize() + SIMD_FORCE_INLINE btVector3& normalize() { - btAssert(!fuzzyZero()); -#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) - // dot product first +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) + // dot product first __m128 vd = _mm_mul_ps(mVec128, mVec128); __m128 z = _mm_movehl_ps(vd, vd); __m128 y = _mm_shuffle_ps(vd, vd, 0x55); vd = _mm_add_ss(vd, y); vd = _mm_add_ss(vd, z); - - #if 0 + +#if 0 vd = _mm_sqrt_ss(vd); vd = _mm_div_ss(v1110, vd); vd = bt_splat_ps(vd, 0x80); mVec128 = _mm_mul_ps(mVec128, vd); - #else - - // NR step 1/sqrt(x) - vd is x, y is output - y = _mm_rsqrt_ss(vd); // estimate - - // one step NR - z = v1_5; - vd = _mm_mul_ss(vd, vHalf); // vd * 0.5 - //x2 = vd; - vd = _mm_mul_ss(vd, y); // vd * 0.5 * y0 - vd = _mm_mul_ss(vd, y); // vd * 0.5 * y0 * y0 - z = _mm_sub_ss(z, vd); // 1.5 - vd * 0.5 * y0 * y0 +#else - y = _mm_mul_ss(y, z); // y0 * (1.5 - vd * 0.5 * y0 * y0) + // NR step 1/sqrt(x) - vd is x, y is output + y = _mm_rsqrt_ss(vd); // estimate + + // one step NR + z = v1_5; + vd = _mm_mul_ss(vd, vHalf); // vd * 0.5 + //x2 = vd; + vd = _mm_mul_ss(vd, y); // vd * 0.5 * y0 + vd = _mm_mul_ss(vd, y); // vd * 0.5 * y0 * y0 + z = _mm_sub_ss(z, vd); // 1.5 - vd * 0.5 * y0 * y0 + + y = _mm_mul_ss(y, z); // y0 * (1.5 - vd * 0.5 * y0 * y0) y = bt_splat_ps(y, 0x80); mVec128 = _mm_mul_ps(mVec128, y); - #endif +#endif - return *this; -#else +#else return *this /= length(); #endif } - /**@brief Return a normalized version of this vector */ + /**@brief Return a normalized version of this vector */ SIMD_FORCE_INLINE btVector3 normalized() const; - /**@brief Return a rotated version of this vector + /**@brief Return a rotated version of this vector * @param wAxis The axis to rotate about * @param angle The angle to rotate by */ - SIMD_FORCE_INLINE btVector3 rotate( const btVector3& wAxis, const btScalar angle ) const; + SIMD_FORCE_INLINE btVector3 rotate(const btVector3& wAxis, const btScalar angle) const; - /**@brief Return the angle between this and another vector + /**@brief Return the angle between this and another vector * @param v The other vector */ - SIMD_FORCE_INLINE btScalar angle(const btVector3& v) const + SIMD_FORCE_INLINE btScalar angle(const btVector3& v) const { btScalar s = btSqrt(length2() * v.length2()); btFullAssert(s != btScalar(0.0)); return btAcos(dot(v) / s); } - - /**@brief Return a vector with the absolute values of each element */ - SIMD_FORCE_INLINE btVector3 absolute() const - { -#if defined BT_USE_SIMD_VECTOR3 && defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + /**@brief Return a vector with the absolute values of each element */ + SIMD_FORCE_INLINE btVector3 absolute() const + { +#if defined BT_USE_SIMD_VECTOR3 && defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) return btVector3(_mm_and_ps(mVec128, btv3AbsfMask)); #elif defined(BT_USE_NEON) return btVector3(vabsq_f32(mVec128)); -#else +#else return btVector3( - btFabs(m_floats[0]), - btFabs(m_floats[1]), + btFabs(m_floats[0]), + btFabs(m_floats[1]), btFabs(m_floats[2])); #endif } - - /**@brief Return the cross product between this and another vector + + /**@brief Return the cross product between this and another vector * @param v The other vector */ SIMD_FORCE_INLINE btVector3 cross(const btVector3& v) const { -#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) - __m128 T, V; - - T = bt_pshufd_ps(mVec128, BT_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0) - V = bt_pshufd_ps(v.mVec128, BT_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0) - +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) + __m128 T, V; + + T = bt_pshufd_ps(mVec128, BT_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0) + V = bt_pshufd_ps(v.mVec128, BT_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0) + V = _mm_mul_ps(V, mVec128); T = _mm_mul_ps(T, v.mVec128); V = _mm_sub_ps(V, T); - + V = bt_pshufd_ps(V, BT_SHUFFLE(1, 2, 0, 3)); return btVector3(V); #elif defined(BT_USE_NEON) @@ -407,7 +398,7 @@ public: float32x2_t Vlow = vget_low_f32(v.mVec128); T = vcombine_f32(vext_f32(Tlow, vget_high_f32(mVec128), 1), Tlow); V = vcombine_f32(vext_f32(Vlow, vget_high_f32(v.mVec128), 1), Vlow); - + V = vmulq_f32(V, mVec128); T = vmulq_f32(T, v.mVec128); V = vsubq_f32(V, T); @@ -415,7 +406,7 @@ public: // form (Y, Z, X, _); V = vcombine_f32(vext_f32(Vlow, vget_high_f32(V), 1), Vlow); V = (float32x4_t)vandq_s32((int32x4_t)V, btvFFF0Mask); - + return btVector3(V); #else return btVector3( @@ -427,18 +418,18 @@ public: SIMD_FORCE_INLINE btScalar triple(const btVector3& v1, const btVector3& v2) const { -#if defined BT_USE_SIMD_VECTOR3 && defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined BT_USE_SIMD_VECTOR3 && defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) // cross: - __m128 T = _mm_shuffle_ps(v1.mVec128, v1.mVec128, BT_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0) - __m128 V = _mm_shuffle_ps(v2.mVec128, v2.mVec128, BT_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0) - + __m128 T = _mm_shuffle_ps(v1.mVec128, v1.mVec128, BT_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0) + __m128 V = _mm_shuffle_ps(v2.mVec128, v2.mVec128, BT_SHUFFLE(1, 2, 0, 3)); // (Y Z X 0) + V = _mm_mul_ps(V, v1.mVec128); T = _mm_mul_ps(T, v2.mVec128); V = _mm_sub_ps(V, T); - + V = _mm_shuffle_ps(V, V, BT_SHUFFLE(1, 2, 0, 3)); - // dot: + // dot: V = _mm_mul_ps(V, mVec128); __m128 z = _mm_movehl_ps(V, V); __m128 y = _mm_shuffle_ps(V, V, 0x55); @@ -454,7 +445,7 @@ public: float32x2_t Vlow = vget_low_f32(v2.mVec128); T = vcombine_f32(vext_f32(Tlow, vget_high_f32(v1.mVec128), 1), Tlow); V = vcombine_f32(vext_f32(Vlow, vget_high_f32(v2.mVec128), 1), Vlow); - + V = vmulq_f32(V, v1.mVec128); T = vmulq_f32(T, v2.mVec128); V = vsubq_f32(V, T); @@ -462,31 +453,30 @@ public: // form (Y, Z, X, _); V = vcombine_f32(vext_f32(Vlow, vget_high_f32(V), 1), Vlow); - // dot: + // dot: V = vmulq_f32(mVec128, V); - float32x2_t x = vpadd_f32(vget_low_f32(V), vget_low_f32(V)); + float32x2_t x = vpadd_f32(vget_low_f32(V), vget_low_f32(V)); x = vadd_f32(x, vget_high_f32(V)); return vget_lane_f32(x, 0); #else - return - m_floats[0] * (v1.m_floats[1] * v2.m_floats[2] - v1.m_floats[2] * v2.m_floats[1]) + - m_floats[1] * (v1.m_floats[2] * v2.m_floats[0] - v1.m_floats[0] * v2.m_floats[2]) + - m_floats[2] * (v1.m_floats[0] * v2.m_floats[1] - v1.m_floats[1] * v2.m_floats[0]); + return m_floats[0] * (v1.m_floats[1] * v2.m_floats[2] - v1.m_floats[2] * v2.m_floats[1]) + + m_floats[1] * (v1.m_floats[2] * v2.m_floats[0] - v1.m_floats[0] * v2.m_floats[2]) + + m_floats[2] * (v1.m_floats[0] * v2.m_floats[1] - v1.m_floats[1] * v2.m_floats[0]); #endif } - /**@brief Return the axis with the smallest value + /**@brief Return the axis with the smallest value * Note return values are 0,1,2 for x, y, or z */ SIMD_FORCE_INLINE int minAxis() const { - return m_floats[0] < m_floats[1] ? (m_floats[0] return this, t=1 => return other) */ - SIMD_FORCE_INLINE btVector3 lerp(const btVector3& v, const btScalar& t) const + SIMD_FORCE_INLINE btVector3 lerp(const btVector3& v, const btScalar& t) const { -#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) - __m128 vt = _mm_load_ss(&t); // (t 0 0 0) - vt = bt_pshufd_ps(vt, 0x80); // (rt rt rt 0.0) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) + __m128 vt = _mm_load_ss(&t); // (t 0 0 0) + vt = bt_pshufd_ps(vt, 0x80); // (rt rt rt 0.0) __m128 vl = _mm_sub_ps(v.mVec128, mVec128); vl = _mm_mul_ps(vl, vt); vl = _mm_add_ps(vl, mVec128); - + return btVector3(vl); #elif defined(BT_USE_NEON) float32x4_t vl = vsubq_f32(v.mVec128, mVec128); vl = vmulq_n_f32(vl, t); vl = vaddq_f32(vl, mVec128); - + return btVector3(vl); -#else - return - btVector3( m_floats[0] + (v.m_floats[0] - m_floats[0]) * t, - m_floats[1] + (v.m_floats[1] - m_floats[1]) * t, - m_floats[2] + (v.m_floats[2] - m_floats[2]) * t); +#else + return btVector3(m_floats[0] + (v.m_floats[0] - m_floats[0]) * t, + m_floats[1] + (v.m_floats[1] - m_floats[1]) * t, + m_floats[2] + (v.m_floats[2] - m_floats[2]) * t); #endif } - /**@brief Elementwise multiply this vector by the other + /**@brief Elementwise multiply this vector by the other * @param v The other vector */ SIMD_FORCE_INLINE btVector3& operator*=(const btVector3& v) { -#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) mVec128 = _mm_mul_ps(mVec128, v.mVec128); #elif defined(BT_USE_NEON) mVec128 = vmulq_f32(mVec128, v.mVec128); -#else - m_floats[0] *= v.m_floats[0]; +#else + m_floats[0] *= v.m_floats[0]; m_floats[1] *= v.m_floats[1]; m_floats[2] *= v.m_floats[2]; #endif return *this; } - /**@brief Return the x value */ - SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; } - /**@brief Return the y value */ - SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; } - /**@brief Return the z value */ - SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; } - /**@brief Set the x value */ - SIMD_FORCE_INLINE void setX(btScalar _x) { m_floats[0] = _x;}; - /**@brief Set the y value */ - SIMD_FORCE_INLINE void setY(btScalar _y) { m_floats[1] = _y;}; - /**@brief Set the z value */ - SIMD_FORCE_INLINE void setZ(btScalar _z) { m_floats[2] = _z;}; - /**@brief Set the w value */ - SIMD_FORCE_INLINE void setW(btScalar _w) { m_floats[3] = _w;}; - /**@brief Return the x value */ - SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; } - /**@brief Return the y value */ - SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; } - /**@brief Return the z value */ - SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; } - /**@brief Return the w value */ - SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; } + /**@brief Return the x value */ + SIMD_FORCE_INLINE const btScalar& getX() const { return m_floats[0]; } + /**@brief Return the y value */ + SIMD_FORCE_INLINE const btScalar& getY() const { return m_floats[1]; } + /**@brief Return the z value */ + SIMD_FORCE_INLINE const btScalar& getZ() const { return m_floats[2]; } + /**@brief Set the x value */ + SIMD_FORCE_INLINE void setX(btScalar _x) { m_floats[0] = _x; }; + /**@brief Set the y value */ + SIMD_FORCE_INLINE void setY(btScalar _y) { m_floats[1] = _y; }; + /**@brief Set the z value */ + SIMD_FORCE_INLINE void setZ(btScalar _z) { m_floats[2] = _z; }; + /**@brief Set the w value */ + SIMD_FORCE_INLINE void setW(btScalar _w) { m_floats[3] = _w; }; + /**@brief Return the x value */ + SIMD_FORCE_INLINE const btScalar& x() const { return m_floats[0]; } + /**@brief Return the y value */ + SIMD_FORCE_INLINE const btScalar& y() const { return m_floats[1]; } + /**@brief Return the z value */ + SIMD_FORCE_INLINE const btScalar& z() const { return m_floats[2]; } + /**@brief Return the w value */ + SIMD_FORCE_INLINE const btScalar& w() const { return m_floats[3]; } - //SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_floats[0])[i]; } + //SIMD_FORCE_INLINE btScalar& operator[](int i) { return (&m_floats[0])[i]; } //SIMD_FORCE_INLINE const btScalar& operator[](int i) const { return (&m_floats[0])[i]; } ///operator btScalar*() replaces operator[], using implicit conversion. We added operator != and operator == to avoid pointer comparisons. - SIMD_FORCE_INLINE operator btScalar *() { return &m_floats[0]; } - SIMD_FORCE_INLINE operator const btScalar *() const { return &m_floats[0]; } + SIMD_FORCE_INLINE operator btScalar*() { return &m_floats[0]; } + SIMD_FORCE_INLINE operator const btScalar*() const { return &m_floats[0]; } - SIMD_FORCE_INLINE bool operator==(const btVector3& other) const + SIMD_FORCE_INLINE bool operator==(const btVector3& other) const { -#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) - return (0xf == _mm_movemask_ps((__m128)_mm_cmpeq_ps(mVec128, other.mVec128))); -#else - return ((m_floats[3]==other.m_floats[3]) && - (m_floats[2]==other.m_floats[2]) && - (m_floats[1]==other.m_floats[1]) && - (m_floats[0]==other.m_floats[0])); +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) + return (0xf == _mm_movemask_ps((__m128)_mm_cmpeq_ps(mVec128, other.mVec128))); +#else + return ((m_floats[3] == other.m_floats[3]) && + (m_floats[2] == other.m_floats[2]) && + (m_floats[1] == other.m_floats[1]) && + (m_floats[0] == other.m_floats[0])); #endif } - SIMD_FORCE_INLINE bool operator!=(const btVector3& other) const + SIMD_FORCE_INLINE bool operator!=(const btVector3& other) const { return !(*this == other); } - /**@brief Set each element to the max of the current values and the values of another btVector3 + /**@brief Set each element to the max of the current values and the values of another btVector3 * @param other The other btVector3 to compare with */ - SIMD_FORCE_INLINE void setMax(const btVector3& other) + SIMD_FORCE_INLINE void setMax(const btVector3& other) { -#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) mVec128 = _mm_max_ps(mVec128, other.mVec128); #elif defined(BT_USE_NEON) mVec128 = vmaxq_f32(mVec128, other.mVec128); @@ -632,12 +620,12 @@ public: #endif } - /**@brief Set each element to the min of the current values and the values of another btVector3 + /**@brief Set each element to the min of the current values and the values of another btVector3 * @param other The other btVector3 to compare with */ - SIMD_FORCE_INLINE void setMin(const btVector3& other) + SIMD_FORCE_INLINE void setMin(const btVector3& other) { -#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) mVec128 = _mm_min_ps(mVec128, other.mVec128); #elif defined(BT_USE_NEON) mVec128 = vminq_f32(mVec128, other.mVec128); @@ -649,156 +637,155 @@ public: #endif } - SIMD_FORCE_INLINE void setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z) + SIMD_FORCE_INLINE void setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z) { - m_floats[0]=_x; - m_floats[1]=_y; - m_floats[2]=_z; + m_floats[0] = _x; + m_floats[1] = _y; + m_floats[2] = _z; m_floats[3] = btScalar(0.f); } - void getSkewSymmetricMatrix(btVector3* v0,btVector3* v1,btVector3* v2) const + void getSkewSymmetricMatrix(btVector3 * v0, btVector3 * v1, btVector3 * v2) const { -#if defined BT_USE_SIMD_VECTOR3 && defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) - - __m128 V = _mm_and_ps(mVec128, btvFFF0fMask); +#if defined BT_USE_SIMD_VECTOR3 && defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) + + __m128 V = _mm_and_ps(mVec128, btvFFF0fMask); __m128 V0 = _mm_xor_ps(btvMzeroMask, V); __m128 V2 = _mm_movelh_ps(V0, V); - + __m128 V1 = _mm_shuffle_ps(V, V0, 0xCE); - - V0 = _mm_shuffle_ps(V0, V, 0xDB); + + V0 = _mm_shuffle_ps(V0, V, 0xDB); V2 = _mm_shuffle_ps(V2, V, 0xF9); - + v0->mVec128 = V0; v1->mVec128 = V1; v2->mVec128 = V2; #else - v0->setValue(0. ,-z() ,y()); - v1->setValue(z() ,0. ,-x()); - v2->setValue(-y() ,x() ,0.); + v0->setValue(0., -z(), y()); + v1->setValue(z(), 0., -x()); + v2->setValue(-y(), x(), 0.); #endif } void setZero() { -#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) mVec128 = (__m128)_mm_xor_ps(mVec128, mVec128); #elif defined(BT_USE_NEON) - int32x4_t vi = vdupq_n_s32(0); + int32x4_t vi = vdupq_n_s32(0); mVec128 = vreinterpretq_f32_s32(vi); -#else - setValue(btScalar(0.),btScalar(0.),btScalar(0.)); +#else + setValue(btScalar(0.), btScalar(0.), btScalar(0.)); #endif } - SIMD_FORCE_INLINE bool isZero() const + SIMD_FORCE_INLINE bool isZero() const { return m_floats[0] == btScalar(0) && m_floats[1] == btScalar(0) && m_floats[2] == btScalar(0); } - - SIMD_FORCE_INLINE bool fuzzyZero() const + SIMD_FORCE_INLINE bool fuzzyZero() const { - return length2() < SIMD_EPSILON*SIMD_EPSILON; + return length2() < SIMD_EPSILON * SIMD_EPSILON; } - SIMD_FORCE_INLINE void serialize(struct btVector3Data& dataOut) const; + SIMD_FORCE_INLINE void serialize(struct btVector3Data & dataOut) const; - SIMD_FORCE_INLINE void deSerialize(const struct btVector3DoubleData& dataIn); + SIMD_FORCE_INLINE void deSerialize(const struct btVector3DoubleData& dataIn); - SIMD_FORCE_INLINE void deSerialize(const struct btVector3FloatData& dataIn); + SIMD_FORCE_INLINE void deSerialize(const struct btVector3FloatData& dataIn); - SIMD_FORCE_INLINE void serializeFloat(struct btVector3FloatData& dataOut) const; + SIMD_FORCE_INLINE void serializeFloat(struct btVector3FloatData & dataOut) const; - SIMD_FORCE_INLINE void deSerializeFloat(const struct btVector3FloatData& dataIn); + SIMD_FORCE_INLINE void deSerializeFloat(const struct btVector3FloatData& dataIn); - SIMD_FORCE_INLINE void serializeDouble(struct btVector3DoubleData& dataOut) const; + SIMD_FORCE_INLINE void serializeDouble(struct btVector3DoubleData & dataOut) const; - SIMD_FORCE_INLINE void deSerializeDouble(const struct btVector3DoubleData& dataIn); - - /**@brief returns index of maximum dot product between this and vectors in array[] + SIMD_FORCE_INLINE void deSerializeDouble(const struct btVector3DoubleData& dataIn); + + /**@brief returns index of maximum dot product between this and vectors in array[] * @param array The other vectors * @param array_count The number of other vectors * @param dotOut The maximum dot product */ - SIMD_FORCE_INLINE long maxDot( const btVector3 *array, long array_count, btScalar &dotOut ) const; + SIMD_FORCE_INLINE long maxDot(const btVector3* array, long array_count, btScalar& dotOut) const; - /**@brief returns index of minimum dot product between this and vectors in array[] + /**@brief returns index of minimum dot product between this and vectors in array[] * @param array The other vectors * @param array_count The number of other vectors - * @param dotOut The minimum dot product */ - SIMD_FORCE_INLINE long minDot( const btVector3 *array, long array_count, btScalar &dotOut ) const; + * @param dotOut The minimum dot product */ + SIMD_FORCE_INLINE long minDot(const btVector3* array, long array_count, btScalar& dotOut) const; - /* create a vector as btVector3( this->dot( btVector3 v0 ), this->dot( btVector3 v1), this->dot( btVector3 v2 )) */ - SIMD_FORCE_INLINE btVector3 dot3( const btVector3 &v0, const btVector3 &v1, const btVector3 &v2 ) const - { -#if defined BT_USE_SIMD_VECTOR3 && defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) + /* create a vector as btVector3( this->dot( btVector3 v0 ), this->dot( btVector3 v1), this->dot( btVector3 v2 )) */ + SIMD_FORCE_INLINE btVector3 dot3(const btVector3& v0, const btVector3& v1, const btVector3& v2) const + { +#if defined BT_USE_SIMD_VECTOR3 && defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) + + __m128 a0 = _mm_mul_ps(v0.mVec128, this->mVec128); + __m128 a1 = _mm_mul_ps(v1.mVec128, this->mVec128); + __m128 a2 = _mm_mul_ps(v2.mVec128, this->mVec128); + __m128 b0 = _mm_unpacklo_ps(a0, a1); + __m128 b1 = _mm_unpackhi_ps(a0, a1); + __m128 b2 = _mm_unpacklo_ps(a2, _mm_setzero_ps()); + __m128 r = _mm_movelh_ps(b0, b2); + r = _mm_add_ps(r, _mm_movehl_ps(b2, b0)); + a2 = _mm_and_ps(a2, btvxyzMaskf); + r = _mm_add_ps(r, btCastdTo128f(_mm_move_sd(btCastfTo128d(a2), btCastfTo128d(b1)))); + return btVector3(r); - __m128 a0 = _mm_mul_ps( v0.mVec128, this->mVec128 ); - __m128 a1 = _mm_mul_ps( v1.mVec128, this->mVec128 ); - __m128 a2 = _mm_mul_ps( v2.mVec128, this->mVec128 ); - __m128 b0 = _mm_unpacklo_ps( a0, a1 ); - __m128 b1 = _mm_unpackhi_ps( a0, a1 ); - __m128 b2 = _mm_unpacklo_ps( a2, _mm_setzero_ps() ); - __m128 r = _mm_movelh_ps( b0, b2 ); - r = _mm_add_ps( r, _mm_movehl_ps( b2, b0 )); - a2 = _mm_and_ps( a2, btvxyzMaskf); - r = _mm_add_ps( r, btCastdTo128f (_mm_move_sd( btCastfTo128d(a2), btCastfTo128d(b1) ))); - return btVector3(r); - #elif defined(BT_USE_NEON) - static const uint32x4_t xyzMask = (const uint32x4_t){ static_cast(-1), static_cast(-1), static_cast(-1), 0 }; - float32x4_t a0 = vmulq_f32( v0.mVec128, this->mVec128); - float32x4_t a1 = vmulq_f32( v1.mVec128, this->mVec128); - float32x4_t a2 = vmulq_f32( v2.mVec128, this->mVec128); - float32x2x2_t zLo = vtrn_f32( vget_high_f32(a0), vget_high_f32(a1)); - a2 = (float32x4_t) vandq_u32((uint32x4_t) a2, xyzMask ); - float32x2_t b0 = vadd_f32( vpadd_f32( vget_low_f32(a0), vget_low_f32(a1)), zLo.val[0] ); - float32x2_t b1 = vpadd_f32( vpadd_f32( vget_low_f32(a2), vget_high_f32(a2)), vdup_n_f32(0.0f)); - return btVector3( vcombine_f32(b0, b1) ); -#else - return btVector3( dot(v0), dot(v1), dot(v2)); + static const uint32x4_t xyzMask = (const uint32x4_t){static_cast(-1), static_cast(-1), static_cast(-1), 0}; + float32x4_t a0 = vmulq_f32(v0.mVec128, this->mVec128); + float32x4_t a1 = vmulq_f32(v1.mVec128, this->mVec128); + float32x4_t a2 = vmulq_f32(v2.mVec128, this->mVec128); + float32x2x2_t zLo = vtrn_f32(vget_high_f32(a0), vget_high_f32(a1)); + a2 = (float32x4_t)vandq_u32((uint32x4_t)a2, xyzMask); + float32x2_t b0 = vadd_f32(vpadd_f32(vget_low_f32(a0), vget_low_f32(a1)), zLo.val[0]); + float32x2_t b1 = vpadd_f32(vpadd_f32(vget_low_f32(a2), vget_high_f32(a2)), vdup_n_f32(0.0f)); + return btVector3(vcombine_f32(b0, b1)); +#else + return btVector3(dot(v0), dot(v1), dot(v2)); #endif - } + } }; /**@brief Return the sum of two vectors (Point symantics)*/ -SIMD_FORCE_INLINE btVector3 -operator+(const btVector3& v1, const btVector3& v2) +SIMD_FORCE_INLINE btVector3 +operator+(const btVector3& v1, const btVector3& v2) { -#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) return btVector3(_mm_add_ps(v1.mVec128, v2.mVec128)); #elif defined(BT_USE_NEON) return btVector3(vaddq_f32(v1.mVec128, v2.mVec128)); #else return btVector3( - v1.m_floats[0] + v2.m_floats[0], - v1.m_floats[1] + v2.m_floats[1], - v1.m_floats[2] + v2.m_floats[2]); + v1.m_floats[0] + v2.m_floats[0], + v1.m_floats[1] + v2.m_floats[1], + v1.m_floats[2] + v2.m_floats[2]); #endif } /**@brief Return the elementwise product of two vectors */ -SIMD_FORCE_INLINE btVector3 -operator*(const btVector3& v1, const btVector3& v2) +SIMD_FORCE_INLINE btVector3 +operator*(const btVector3& v1, const btVector3& v2) { -#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) return btVector3(_mm_mul_ps(v1.mVec128, v2.mVec128)); #elif defined(BT_USE_NEON) return btVector3(vmulq_f32(v1.mVec128, v2.mVec128)); #else return btVector3( - v1.m_floats[0] * v2.m_floats[0], - v1.m_floats[1] * v2.m_floats[1], - v1.m_floats[2] * v2.m_floats[2]); + v1.m_floats[0] * v2.m_floats[0], + v1.m_floats[1] * v2.m_floats[1], + v1.m_floats[2] * v2.m_floats[2]); #endif } /**@brief Return the difference between two vectors */ -SIMD_FORCE_INLINE btVector3 +SIMD_FORCE_INLINE btVector3 operator-(const btVector3& v1, const btVector3& v2) { -#if defined BT_USE_SIMD_VECTOR3 && (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) +#if defined BT_USE_SIMD_VECTOR3 && (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) // without _mm_and_ps this code causes slowdown in Concave moving __m128 r = _mm_sub_ps(v1.mVec128, v2.mVec128); @@ -808,33 +795,33 @@ operator-(const btVector3& v1, const btVector3& v2) return btVector3((float32x4_t)vandq_s32((int32x4_t)r, btvFFF0Mask)); #else return btVector3( - v1.m_floats[0] - v2.m_floats[0], - v1.m_floats[1] - v2.m_floats[1], - v1.m_floats[2] - v2.m_floats[2]); + v1.m_floats[0] - v2.m_floats[0], + v1.m_floats[1] - v2.m_floats[1], + v1.m_floats[2] - v2.m_floats[2]); #endif } /**@brief Return the negative of the vector */ -SIMD_FORCE_INLINE btVector3 +SIMD_FORCE_INLINE btVector3 operator-(const btVector3& v) { -#if defined BT_USE_SIMD_VECTOR3 && (defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE)) +#if defined BT_USE_SIMD_VECTOR3 && (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) __m128 r = _mm_xor_ps(v.mVec128, btvMzeroMask); - return btVector3(_mm_and_ps(r, btvFFF0fMask)); + return btVector3(_mm_and_ps(r, btvFFF0fMask)); #elif defined(BT_USE_NEON) return btVector3((btSimdFloat4)veorq_s32((int32x4_t)v.mVec128, (int32x4_t)btvMzeroMask)); -#else +#else return btVector3(-v.m_floats[0], -v.m_floats[1], -v.m_floats[2]); #endif } /**@brief Return the vector scaled by s */ -SIMD_FORCE_INLINE btVector3 +SIMD_FORCE_INLINE btVector3 operator*(const btVector3& v, const btScalar& s) { -#if defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) - __m128 vs = _mm_load_ss(&s); // (S 0 0 0) - vs = bt_pshufd_ps(vs, 0x80); // (S S S 0.0) +#if defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) + __m128 vs = _mm_load_ss(&s); // (S 0 0 0) + vs = bt_pshufd_ps(vs, 0x80); // (S S S 0.0) return btVector3(_mm_mul_ps(v.mVec128, vs)); #elif defined(BT_USE_NEON) float32x4_t r = vmulq_n_f32(v.mVec128, s); @@ -845,10 +832,10 @@ operator*(const btVector3& v, const btScalar& s) } /**@brief Return the vector scaled by s */ -SIMD_FORCE_INLINE btVector3 +SIMD_FORCE_INLINE btVector3 operator*(const btScalar& s, const btVector3& v) -{ - return v * s; +{ + return v * s; } /**@brief Return the vector inversely scaled by s */ @@ -856,7 +843,7 @@ SIMD_FORCE_INLINE btVector3 operator/(const btVector3& v, const btScalar& s) { btFullAssert(s != btScalar(0.0)); -#if 0 //defined(BT_USE_SSE_IN_API) +#if 0 //defined(BT_USE_SSE_IN_API) // this code is not faster ! __m128 vs = _mm_load_ss(&s); vs = _mm_div_ss(v1110, vs); @@ -872,67 +859,65 @@ operator/(const btVector3& v, const btScalar& s) SIMD_FORCE_INLINE btVector3 operator/(const btVector3& v1, const btVector3& v2) { -#if defined BT_USE_SIMD_VECTOR3 && (defined(BT_USE_SSE_IN_API)&& defined (BT_USE_SSE)) +#if defined BT_USE_SIMD_VECTOR3 && (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) __m128 vec = _mm_div_ps(v1.mVec128, v2.mVec128); vec = _mm_and_ps(vec, btvFFF0fMask); - return btVector3(vec); + return btVector3(vec); #elif defined(BT_USE_NEON) float32x4_t x, y, v, m; x = v1.mVec128; y = v2.mVec128; - - v = vrecpeq_f32(y); // v ~ 1/y - m = vrecpsq_f32(y, v); // m = (2-v*y) - v = vmulq_f32(v, m); // vv = v*m ~~ 1/y - m = vrecpsq_f32(y, v); // mm = (2-vv*y) - v = vmulq_f32(v, x); // x*vv - v = vmulq_f32(v, m); // (x*vv)*(2-vv*y) = x*(vv(2-vv*y)) ~~~ x/y + + v = vrecpeq_f32(y); // v ~ 1/y + m = vrecpsq_f32(y, v); // m = (2-v*y) + v = vmulq_f32(v, m); // vv = v*m ~~ 1/y + m = vrecpsq_f32(y, v); // mm = (2-vv*y) + v = vmulq_f32(v, x); // x*vv + v = vmulq_f32(v, m); // (x*vv)*(2-vv*y) = x*(vv(2-vv*y)) ~~~ x/y return btVector3(v); #else return btVector3( - v1.m_floats[0] / v2.m_floats[0], - v1.m_floats[1] / v2.m_floats[1], - v1.m_floats[2] / v2.m_floats[2]); + v1.m_floats[0] / v2.m_floats[0], + v1.m_floats[1] / v2.m_floats[1], + v1.m_floats[2] / v2.m_floats[2]); #endif } /**@brief Return the dot product between two vectors */ -SIMD_FORCE_INLINE btScalar -btDot(const btVector3& v1, const btVector3& v2) -{ - return v1.dot(v2); +SIMD_FORCE_INLINE btScalar +btDot(const btVector3& v1, const btVector3& v2) +{ + return v1.dot(v2); } - /**@brief Return the distance squared between two vectors */ SIMD_FORCE_INLINE btScalar -btDistance2(const btVector3& v1, const btVector3& v2) -{ - return v1.distance2(v2); +btDistance2(const btVector3& v1, const btVector3& v2) +{ + return v1.distance2(v2); } - /**@brief Return the distance between two vectors */ SIMD_FORCE_INLINE btScalar -btDistance(const btVector3& v1, const btVector3& v2) -{ - return v1.distance(v2); +btDistance(const btVector3& v1, const btVector3& v2) +{ + return v1.distance(v2); } /**@brief Return the angle between two vectors */ SIMD_FORCE_INLINE btScalar -btAngle(const btVector3& v1, const btVector3& v2) -{ - return v1.angle(v2); +btAngle(const btVector3& v1, const btVector3& v2) +{ + return v1.angle(v2); } /**@brief Return the cross product of two vectors */ -SIMD_FORCE_INLINE btVector3 -btCross(const btVector3& v1, const btVector3& v2) -{ - return v1.cross(v2); +SIMD_FORCE_INLINE btVector3 +btCross(const btVector3& v1, const btVector3& v2) +{ + return v1.cross(v2); } SIMD_FORCE_INLINE btScalar @@ -945,14 +930,12 @@ btTriple(const btVector3& v1, const btVector3& v2, const btVector3& v3) * @param v1 One vector * @param v2 The other vector * @param t The ration of this to v (t = 0 => return v1, t=1 => return v2) */ -SIMD_FORCE_INLINE btVector3 +SIMD_FORCE_INLINE btVector3 lerp(const btVector3& v1, const btVector3& v2, const btScalar& t) { return v1.lerp(v2, t); } - - SIMD_FORCE_INLINE btScalar btVector3::distance2(const btVector3& v) const { return (v - *this).length2(); @@ -968,140 +951,137 @@ SIMD_FORCE_INLINE btVector3 btVector3::normalized() const btVector3 nrm = *this; return nrm.normalize(); -} +} -SIMD_FORCE_INLINE btVector3 btVector3::rotate( const btVector3& wAxis, const btScalar _angle ) const +SIMD_FORCE_INLINE btVector3 btVector3::rotate(const btVector3& wAxis, const btScalar _angle) const { // wAxis must be a unit lenght vector -#if defined BT_USE_SIMD_VECTOR3 && defined (BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined BT_USE_SIMD_VECTOR3 && defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) - __m128 O = _mm_mul_ps(wAxis.mVec128, mVec128); - btScalar ssin = btSin( _angle ); - __m128 C = wAxis.cross( mVec128 ).mVec128; + __m128 O = _mm_mul_ps(wAxis.mVec128, mVec128); + btScalar ssin = btSin(_angle); + __m128 C = wAxis.cross(mVec128).mVec128; O = _mm_and_ps(O, btvFFF0fMask); - btScalar scos = btCos( _angle ); - - __m128 vsin = _mm_load_ss(&ssin); // (S 0 0 0) - __m128 vcos = _mm_load_ss(&scos); // (S 0 0 0) - - __m128 Y = bt_pshufd_ps(O, 0xC9); // (Y Z X 0) - __m128 Z = bt_pshufd_ps(O, 0xD2); // (Z X Y 0) + btScalar scos = btCos(_angle); + + __m128 vsin = _mm_load_ss(&ssin); // (S 0 0 0) + __m128 vcos = _mm_load_ss(&scos); // (S 0 0 0) + + __m128 Y = bt_pshufd_ps(O, 0xC9); // (Y Z X 0) + __m128 Z = bt_pshufd_ps(O, 0xD2); // (Z X Y 0) O = _mm_add_ps(O, Y); - vsin = bt_pshufd_ps(vsin, 0x80); // (S S S 0) + vsin = bt_pshufd_ps(vsin, 0x80); // (S S S 0) O = _mm_add_ps(O, Z); - vcos = bt_pshufd_ps(vcos, 0x80); // (S S S 0) - - vsin = vsin * C; - O = O * wAxis.mVec128; - __m128 X = mVec128 - O; - - O = O + vsin; + vcos = bt_pshufd_ps(vcos, 0x80); // (S S S 0) + + vsin = vsin * C; + O = O * wAxis.mVec128; + __m128 X = mVec128 - O; + + O = O + vsin; vcos = vcos * X; - O = O + vcos; - + O = O + vcos; + return btVector3(O); #else - btVector3 o = wAxis * wAxis.dot( *this ); + btVector3 o = wAxis * wAxis.dot(*this); btVector3 _x = *this - o; btVector3 _y; - _y = wAxis.cross( *this ); + _y = wAxis.cross(*this); - return ( o + _x * btCos( _angle ) + _y * btSin( _angle ) ); + return (o + _x * btCos(_angle) + _y * btSin(_angle)); #endif } -SIMD_FORCE_INLINE long btVector3::maxDot( const btVector3 *array, long array_count, btScalar &dotOut ) const +SIMD_FORCE_INLINE long btVector3::maxDot(const btVector3* array, long array_count, btScalar& dotOut) const { -#if (defined BT_USE_SSE && defined BT_USE_SIMD_VECTOR3 && defined BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - #if defined _WIN32 || defined (BT_USE_SSE) - const long scalar_cutoff = 10; - long _maxdot_large( const float *array, const float *vec, unsigned long array_count, float *dotOut ); - #elif defined BT_USE_NEON - const long scalar_cutoff = 4; - extern long (*_maxdot_large)( const float *array, const float *vec, unsigned long array_count, float *dotOut ); - #endif - if( array_count < scalar_cutoff ) +#if (defined BT_USE_SSE && defined BT_USE_SIMD_VECTOR3 && defined BT_USE_SSE_IN_API) || defined(BT_USE_NEON) +#if defined _WIN32 || defined(BT_USE_SSE) + const long scalar_cutoff = 10; + long _maxdot_large(const float* array, const float* vec, unsigned long array_count, float* dotOut); +#elif defined BT_USE_NEON + const long scalar_cutoff = 4; + extern long (*_maxdot_large)(const float* array, const float* vec, unsigned long array_count, float* dotOut); #endif - { - btScalar maxDot1 = -SIMD_INFINITY; - int i = 0; - int ptIndex = -1; - for( i = 0; i < array_count; i++ ) - { - btScalar dot = array[i].dot(*this); - - if( dot > maxDot1 ) - { - maxDot1 = dot; - ptIndex = i; - } - } - - dotOut = maxDot1; - return ptIndex; - } -#if (defined BT_USE_SSE && defined BT_USE_SIMD_VECTOR3 && defined BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - return _maxdot_large( (float*) array, (float*) &m_floats[0], array_count, &dotOut ); + if (array_count < scalar_cutoff) +#endif + { + btScalar maxDot1 = -SIMD_INFINITY; + int i = 0; + int ptIndex = -1; + for (i = 0; i < array_count; i++) + { + btScalar dot = array[i].dot(*this); + + if (dot > maxDot1) + { + maxDot1 = dot; + ptIndex = i; + } + } + + dotOut = maxDot1; + return ptIndex; + } +#if (defined BT_USE_SSE && defined BT_USE_SIMD_VECTOR3 && defined BT_USE_SSE_IN_API) || defined(BT_USE_NEON) + return _maxdot_large((float*)array, (float*)&m_floats[0], array_count, &dotOut); #endif } -SIMD_FORCE_INLINE long btVector3::minDot( const btVector3 *array, long array_count, btScalar &dotOut ) const +SIMD_FORCE_INLINE long btVector3::minDot(const btVector3* array, long array_count, btScalar& dotOut) const { -#if (defined BT_USE_SSE && defined BT_USE_SIMD_VECTOR3 && defined BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - #if defined BT_USE_SSE - const long scalar_cutoff = 10; - long _mindot_large( const float *array, const float *vec, unsigned long array_count, float *dotOut ); - #elif defined BT_USE_NEON - const long scalar_cutoff = 4; - extern long (*_mindot_large)( const float *array, const float *vec, unsigned long array_count, float *dotOut ); - #else - #error unhandled arch! - #endif - - if( array_count < scalar_cutoff ) +#if (defined BT_USE_SSE && defined BT_USE_SIMD_VECTOR3 && defined BT_USE_SSE_IN_API) || defined(BT_USE_NEON) +#if defined BT_USE_SSE + const long scalar_cutoff = 10; + long _mindot_large(const float* array, const float* vec, unsigned long array_count, float* dotOut); +#elif defined BT_USE_NEON + const long scalar_cutoff = 4; + extern long (*_mindot_large)(const float* array, const float* vec, unsigned long array_count, float* dotOut); +#else +#error unhandled arch! #endif - { - btScalar minDot = SIMD_INFINITY; - int i = 0; - int ptIndex = -1; - - for( i = 0; i < array_count; i++ ) - { - btScalar dot = array[i].dot(*this); - - if( dot < minDot ) - { - minDot = dot; - ptIndex = i; - } - } - - dotOut = minDot; - - return ptIndex; - } -#if (defined BT_USE_SSE && defined BT_USE_SIMD_VECTOR3 && defined BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - return _mindot_large( (float*) array, (float*) &m_floats[0], array_count, &dotOut ); -#endif//BT_USE_SIMD_VECTOR3 -} + if (array_count < scalar_cutoff) +#endif + { + btScalar minDot = SIMD_INFINITY; + int i = 0; + int ptIndex = -1; + + for (i = 0; i < array_count; i++) + { + btScalar dot = array[i].dot(*this); + + if (dot < minDot) + { + minDot = dot; + ptIndex = i; + } + } + + dotOut = minDot; + + return ptIndex; + } +#if (defined BT_USE_SSE && defined BT_USE_SIMD_VECTOR3 && defined BT_USE_SSE_IN_API) || defined(BT_USE_NEON) + return _mindot_large((float*)array, (float*)&m_floats[0], array_count, &dotOut); +#endif //BT_USE_SIMD_VECTOR3 +} class btVector4 : public btVector3 { public: - SIMD_FORCE_INLINE btVector4() {} - - SIMD_FORCE_INLINE btVector4(const btScalar& _x, const btScalar& _y, const btScalar& _z,const btScalar& _w) - : btVector3(_x,_y,_z) + SIMD_FORCE_INLINE btVector4(const btScalar& _x, const btScalar& _y, const btScalar& _z, const btScalar& _w) + : btVector3(_x, _y, _z) { m_floats[3] = _w; } -#if (defined (BT_USE_SSE_IN_API)&& defined (BT_USE_SSE)) || defined (BT_USE_NEON) +#if (defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE)) || defined(BT_USE_NEON) SIMD_FORCE_INLINE btVector4(const btSimdFloat4 vec) { mVec128 = vec; @@ -1112,34 +1092,32 @@ public: mVec128 = rhs.mVec128; } - SIMD_FORCE_INLINE btVector4& - operator=(const btVector4& v) + SIMD_FORCE_INLINE btVector4& + operator=(const btVector4& v) { mVec128 = v.mVec128; return *this; } -#endif // #if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) +#endif // #if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - SIMD_FORCE_INLINE btVector4 absolute4() const + SIMD_FORCE_INLINE btVector4 absolute4() const { -#if defined BT_USE_SIMD_VECTOR3 && defined(BT_USE_SSE_IN_API) && defined (BT_USE_SSE) +#if defined BT_USE_SIMD_VECTOR3 && defined(BT_USE_SSE_IN_API) && defined(BT_USE_SSE) return btVector4(_mm_and_ps(mVec128, btvAbsfMask)); #elif defined(BT_USE_NEON) return btVector4(vabsq_f32(mVec128)); -#else +#else return btVector4( - btFabs(m_floats[0]), - btFabs(m_floats[1]), + btFabs(m_floats[0]), + btFabs(m_floats[1]), btFabs(m_floats[2]), btFabs(m_floats[3])); #endif } + btScalar getW() const { return m_floats[3]; } - btScalar getW() const { return m_floats[3];} - - - SIMD_FORCE_INLINE int maxAxis4() const + SIMD_FORCE_INLINE int maxAxis4() const { int maxIndex = -1; btScalar maxVal = btScalar(-BT_LARGE_FLOAT); @@ -1156,7 +1134,7 @@ public: if (m_floats[2] > maxVal) { maxIndex = 2; - maxVal =m_floats[2]; + maxVal = m_floats[2]; } if (m_floats[3] > maxVal) { @@ -1166,7 +1144,6 @@ public: return maxIndex; } - SIMD_FORCE_INLINE int minAxis4() const { int minIndex = -1; @@ -1184,190 +1161,176 @@ public: if (m_floats[2] < minVal) { minIndex = 2; - minVal =m_floats[2]; + minVal = m_floats[2]; } if (m_floats[3] < minVal) { minIndex = 3; } - + return minIndex; } - - SIMD_FORCE_INLINE int closestAxis4() const + SIMD_FORCE_INLINE int closestAxis4() const { return absolute4().maxAxis4(); } - - - - /**@brief Set x,y,z and zero w + /**@brief Set x,y,z and zero w * @param x Value of x * @param y Value of y * @param z Value of z */ - -/* void getValue(btScalar *m) const + /* void getValue(btScalar *m) const { m[0] = m_floats[0]; m[1] = m_floats[1]; m[2] =m_floats[2]; } */ -/**@brief Set the values + /**@brief Set the values * @param x Value of x * @param y Value of y * @param z Value of z * @param w Value of w */ - SIMD_FORCE_INLINE void setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z,const btScalar& _w) - { - m_floats[0]=_x; - m_floats[1]=_y; - m_floats[2]=_z; - m_floats[3]=_w; - } - - + SIMD_FORCE_INLINE void setValue(const btScalar& _x, const btScalar& _y, const btScalar& _z, const btScalar& _w) + { + m_floats[0] = _x; + m_floats[1] = _y; + m_floats[2] = _z; + m_floats[3] = _w; + } }; - ///btSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization -SIMD_FORCE_INLINE void btSwapScalarEndian(const btScalar& sourceVal, btScalar& destVal) +SIMD_FORCE_INLINE void btSwapScalarEndian(const btScalar& sourceVal, btScalar& destVal) { #ifdef BT_USE_DOUBLE_PRECISION - unsigned char* dest = (unsigned char*) &destVal; - const unsigned char* src = (const unsigned char*) &sourceVal; + unsigned char* dest = (unsigned char*)&destVal; + const unsigned char* src = (const unsigned char*)&sourceVal; dest[0] = src[7]; - dest[1] = src[6]; - dest[2] = src[5]; - dest[3] = src[4]; - dest[4] = src[3]; - dest[5] = src[2]; - dest[6] = src[1]; - dest[7] = src[0]; + dest[1] = src[6]; + dest[2] = src[5]; + dest[3] = src[4]; + dest[4] = src[3]; + dest[5] = src[2]; + dest[6] = src[1]; + dest[7] = src[0]; #else - unsigned char* dest = (unsigned char*) &destVal; - const unsigned char* src = (const unsigned char*) &sourceVal; + unsigned char* dest = (unsigned char*)&destVal; + const unsigned char* src = (const unsigned char*)&sourceVal; dest[0] = src[3]; - dest[1] = src[2]; - dest[2] = src[1]; - dest[3] = src[0]; -#endif //BT_USE_DOUBLE_PRECISION + dest[1] = src[2]; + dest[2] = src[1]; + dest[3] = src[0]; +#endif //BT_USE_DOUBLE_PRECISION } ///btSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization -SIMD_FORCE_INLINE void btSwapVector3Endian(const btVector3& sourceVec, btVector3& destVec) +SIMD_FORCE_INLINE void btSwapVector3Endian(const btVector3& sourceVec, btVector3& destVec) { - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) { - btSwapScalarEndian(sourceVec[i],destVec[i]); + btSwapScalarEndian(sourceVec[i], destVec[i]); } - } ///btUnSwapVector3Endian swaps vector endianness, useful for network and cross-platform serialization -SIMD_FORCE_INLINE void btUnSwapVector3Endian(btVector3& vector) +SIMD_FORCE_INLINE void btUnSwapVector3Endian(btVector3& vector) { - - btVector3 swappedVec; - for (int i=0;i<4;i++) + btVector3 swappedVec; + for (int i = 0; i < 4; i++) { - btSwapScalarEndian(vector[i],swappedVec[i]); + btSwapScalarEndian(vector[i], swappedVec[i]); } vector = swappedVec; } template -SIMD_FORCE_INLINE void btPlaneSpace1 (const T& n, T& p, T& q) +SIMD_FORCE_INLINE void btPlaneSpace1(const T& n, T& p, T& q) { - if (btFabs(n[2]) > SIMDSQRT12) { - // choose p in y-z plane - btScalar a = n[1]*n[1] + n[2]*n[2]; - btScalar k = btRecipSqrt (a); - p[0] = 0; - p[1] = -n[2]*k; - p[2] = n[1]*k; - // set q = n x p - q[0] = a*k; - q[1] = -n[0]*p[2]; - q[2] = n[0]*p[1]; - } - else { - // choose p in x-y plane - btScalar a = n[0]*n[0] + n[1]*n[1]; - btScalar k = btRecipSqrt (a); - p[0] = -n[1]*k; - p[1] = n[0]*k; - p[2] = 0; - // set q = n x p - q[0] = -n[2]*p[1]; - q[1] = n[2]*p[0]; - q[2] = a*k; - } + if (btFabs(n[2]) > SIMDSQRT12) + { + // choose p in y-z plane + btScalar a = n[1] * n[1] + n[2] * n[2]; + btScalar k = btRecipSqrt(a); + p[0] = 0; + p[1] = -n[2] * k; + p[2] = n[1] * k; + // set q = n x p + q[0] = a * k; + q[1] = -n[0] * p[2]; + q[2] = n[0] * p[1]; + } + else + { + // choose p in x-y plane + btScalar a = n[0] * n[0] + n[1] * n[1]; + btScalar k = btRecipSqrt(a); + p[0] = -n[1] * k; + p[1] = n[0] * k; + p[2] = 0; + // set q = n x p + q[0] = -n[2] * p[1]; + q[1] = n[2] * p[0]; + q[2] = a * k; + } } - -struct btVector3FloatData +struct btVector3FloatData { - float m_floats[4]; + float m_floats[4]; }; -struct btVector3DoubleData +struct btVector3DoubleData { - double m_floats[4]; - + double m_floats[4]; }; -SIMD_FORCE_INLINE void btVector3::serializeFloat(struct btVector3FloatData& dataOut) const +SIMD_FORCE_INLINE void btVector3::serializeFloat(struct btVector3FloatData& dataOut) const { ///could also do a memcpy, check if it is worth it - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) dataOut.m_floats[i] = float(m_floats[i]); } -SIMD_FORCE_INLINE void btVector3::deSerializeFloat(const struct btVector3FloatData& dataIn) +SIMD_FORCE_INLINE void btVector3::deSerializeFloat(const struct btVector3FloatData& dataIn) { - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) m_floats[i] = btScalar(dataIn.m_floats[i]); } - -SIMD_FORCE_INLINE void btVector3::serializeDouble(struct btVector3DoubleData& dataOut) const +SIMD_FORCE_INLINE void btVector3::serializeDouble(struct btVector3DoubleData& dataOut) const { ///could also do a memcpy, check if it is worth it - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) dataOut.m_floats[i] = double(m_floats[i]); } -SIMD_FORCE_INLINE void btVector3::deSerializeDouble(const struct btVector3DoubleData& dataIn) +SIMD_FORCE_INLINE void btVector3::deSerializeDouble(const struct btVector3DoubleData& dataIn) { - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) m_floats[i] = btScalar(dataIn.m_floats[i]); } - -SIMD_FORCE_INLINE void btVector3::serialize(struct btVector3Data& dataOut) const +SIMD_FORCE_INLINE void btVector3::serialize(struct btVector3Data& dataOut) const { ///could also do a memcpy, check if it is worth it - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) dataOut.m_floats[i] = m_floats[i]; } - -SIMD_FORCE_INLINE void btVector3::deSerialize(const struct btVector3FloatData& dataIn) +SIMD_FORCE_INLINE void btVector3::deSerialize(const struct btVector3FloatData& dataIn) { - for (int i = 0; i<4; i++) + for (int i = 0; i < 4; i++) m_floats[i] = (btScalar)dataIn.m_floats[i]; } - -SIMD_FORCE_INLINE void btVector3::deSerialize(const struct btVector3DoubleData& dataIn) +SIMD_FORCE_INLINE void btVector3::deSerialize(const struct btVector3DoubleData& dataIn) { - for (int i=0;i<4;i++) + for (int i = 0; i < 4; i++) m_floats[i] = (btScalar)dataIn.m_floats[i]; } -#endif //BT_VECTOR3_H +#endif //BT_VECTOR3_H diff --git a/src/btBulletCollisionCommon.h b/src/btBulletCollisionCommon.h index 948e02eb4..4f523756a 100644 --- a/src/btBulletCollisionCommon.h +++ b/src/btBulletCollisionCommon.h @@ -62,6 +62,4 @@ subject to the following restrictions: #include "LinearMath/btIDebugDraw.h" #include "LinearMath/btSerializer.h" - -#endif //BULLET_COLLISION_COMMON_H - +#endif //BULLET_COLLISION_COMMON_H diff --git a/src/btBulletDynamicsCommon.h b/src/btBulletDynamicsCommon.h index 50282bf21..a421fa446 100644 --- a/src/btBulletDynamicsCommon.h +++ b/src/btBulletDynamicsCommon.h @@ -35,17 +35,9 @@ subject to the following restrictions: #include "BulletDynamics/ConstraintSolver/btGearConstraint.h" #include "BulletDynamics/ConstraintSolver/btFixedConstraint.h" - #include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h" - ///Vehicle simulation, with wheel contact simulated by raycasts #include "BulletDynamics/Vehicle/btRaycastVehicle.h" - - - - - -#endif //BULLET_DYNAMICS_COMMON_H - +#endif //BULLET_DYNAMICS_COMMON_H diff --git a/src/clew/clew.c b/src/clew/clew.c index 5afc42a48..90caced53 100644 --- a/src/clew/clew.c +++ b/src/clew/clew.c @@ -9,23 +9,23 @@ #include "clew.h" #ifdef _WIN32 - #define WIN32_LEAN_AND_MEAN - #define VC_EXTRALEAN - #include +#define WIN32_LEAN_AND_MEAN +#define VC_EXTRALEAN +#include - typedef HMODULE CLEW_DYNLIB_HANDLE; +typedef HMODULE CLEW_DYNLIB_HANDLE; - #define CLEW_DYNLIB_OPEN LoadLibraryA - #define CLEW_DYNLIB_CLOSE FreeLibrary - #define CLEW_DYNLIB_IMPORT GetProcAddress +#define CLEW_DYNLIB_OPEN LoadLibraryA +#define CLEW_DYNLIB_CLOSE FreeLibrary +#define CLEW_DYNLIB_IMPORT GetProcAddress #else - #include - - typedef void* CLEW_DYNLIB_HANDLE; +#include - #define CLEW_DYNLIB_OPEN(path) dlopen(path, RTLD_NOW | RTLD_GLOBAL) - #define CLEW_DYNLIB_CLOSE dlclose - #define CLEW_DYNLIB_IMPORT dlsym +typedef void* CLEW_DYNLIB_HANDLE; + +#define CLEW_DYNLIB_OPEN(path) dlopen(path, RTLD_NOW | RTLD_GLOBAL) +#define CLEW_DYNLIB_CLOSE dlclose +#define CLEW_DYNLIB_IMPORT dlsym #endif #include @@ -34,279 +34,341 @@ static CLEW_DYNLIB_HANDLE module = NULL; // Variables holding function entry points -PFNCLGETPLATFORMIDS __clewGetPlatformIDs = NULL; -PFNCLGETPLATFORMINFO __clewGetPlatformInfo = NULL; -PFNCLGETDEVICEIDS __clewGetDeviceIDs = NULL; -PFNCLGETDEVICEINFO __clewGetDeviceInfo = NULL; -PFNCLCREATECONTEXT __clewCreateContext = NULL; -PFNCLCREATECONTEXTFROMTYPE __clewCreateContextFromType = NULL; -PFNCLRETAINCONTEXT __clewRetainContext = NULL; -PFNCLRELEASECONTEXT __clewReleaseContext = NULL; -PFNCLGETCONTEXTINFO __clewGetContextInfo = NULL; -PFNCLCREATECOMMANDQUEUE __clewCreateCommandQueue = NULL; -PFNCLRETAINCOMMANDQUEUE __clewRetainCommandQueue = NULL; -PFNCLRELEASECOMMANDQUEUE __clewReleaseCommandQueue = NULL; -PFNCLGETCOMMANDQUEUEINFO __clewGetCommandQueueInfo = NULL; +PFNCLGETPLATFORMIDS __clewGetPlatformIDs = NULL; +PFNCLGETPLATFORMINFO __clewGetPlatformInfo = NULL; +PFNCLGETDEVICEIDS __clewGetDeviceIDs = NULL; +PFNCLGETDEVICEINFO __clewGetDeviceInfo = NULL; +PFNCLCREATECONTEXT __clewCreateContext = NULL; +PFNCLCREATECONTEXTFROMTYPE __clewCreateContextFromType = NULL; +PFNCLRETAINCONTEXT __clewRetainContext = NULL; +PFNCLRELEASECONTEXT __clewReleaseContext = NULL; +PFNCLGETCONTEXTINFO __clewGetContextInfo = NULL; +PFNCLCREATECOMMANDQUEUE __clewCreateCommandQueue = NULL; +PFNCLRETAINCOMMANDQUEUE __clewRetainCommandQueue = NULL; +PFNCLRELEASECOMMANDQUEUE __clewReleaseCommandQueue = NULL; +PFNCLGETCOMMANDQUEUEINFO __clewGetCommandQueueInfo = NULL; #ifdef CL_USE_DEPRECATED_OPENCL_1_0_APIS -PFNCLSETCOMMANDQUEUEPROPERTY __clewSetCommandQueueProperty = NULL; +PFNCLSETCOMMANDQUEUEPROPERTY __clewSetCommandQueueProperty = NULL; #endif -PFNCLCREATEBUFFER __clewCreateBuffer = NULL; -PFNCLCREATESUBBUFFER __clewCreateSubBuffer = NULL; -PFNCLCREATEIMAGE2D __clewCreateImage2D = NULL; -PFNCLCREATEIMAGE3D __clewCreateImage3D = NULL; -PFNCLRETAINMEMOBJECT __clewRetainMemObject = NULL; -PFNCLRELEASEMEMOBJECT __clewReleaseMemObject = NULL; -PFNCLGETSUPPORTEDIMAGEFORMATS __clewGetSupportedImageFormats = NULL; -PFNCLGETMEMOBJECTINFO __clewGetMemObjectInfo = NULL; -PFNCLGETIMAGEINFO __clewGetImageInfo = NULL; +PFNCLCREATEBUFFER __clewCreateBuffer = NULL; +PFNCLCREATESUBBUFFER __clewCreateSubBuffer = NULL; +PFNCLCREATEIMAGE2D __clewCreateImage2D = NULL; +PFNCLCREATEIMAGE3D __clewCreateImage3D = NULL; +PFNCLRETAINMEMOBJECT __clewRetainMemObject = NULL; +PFNCLRELEASEMEMOBJECT __clewReleaseMemObject = NULL; +PFNCLGETSUPPORTEDIMAGEFORMATS __clewGetSupportedImageFormats = NULL; +PFNCLGETMEMOBJECTINFO __clewGetMemObjectInfo = NULL; +PFNCLGETIMAGEINFO __clewGetImageInfo = NULL; PFNCLSETMEMOBJECTDESTRUCTORCALLBACK __clewSetMemObjectDestructorCallback = NULL; -PFNCLCREATESAMPLER __clewCreateSampler = NULL; -PFNCLRETAINSAMPLER __clewRetainSampler = NULL; -PFNCLRELEASESAMPLER __clewReleaseSampler = NULL; -PFNCLGETSAMPLERINFO __clewGetSamplerInfo = NULL; -PFNCLCREATEPROGRAMWITHSOURCE __clewCreateProgramWithSource = NULL; -PFNCLCREATEPROGRAMWITHBINARY __clewCreateProgramWithBinary = NULL; -PFNCLRETAINPROGRAM __clewRetainProgram = NULL; -PFNCLRELEASEPROGRAM __clewReleaseProgram = NULL; -PFNCLBUILDPROGRAM __clewBuildProgram = NULL; -PFNCLUNLOADCOMPILER __clewUnloadCompiler = NULL; -PFNCLGETPROGRAMINFO __clewGetProgramInfo = NULL; -PFNCLGETPROGRAMBUILDINFO __clewGetProgramBuildInfo = NULL; -PFNCLCREATEKERNEL __clewCreateKernel = NULL; -PFNCLCREATEKERNELSINPROGRAM __clewCreateKernelsInProgram = NULL; -PFNCLRETAINKERNEL __clewRetainKernel = NULL; -PFNCLRELEASEKERNEL __clewReleaseKernel = NULL; -PFNCLSETKERNELARG __clewSetKernelArg = NULL; -PFNCLGETKERNELINFO __clewGetKernelInfo = NULL; -PFNCLGETKERNELWORKGROUPINFO __clewGetKernelWorkGroupInfo = NULL; -PFNCLWAITFOREVENTS __clewWaitForEvents = NULL; -PFNCLGETEVENTINFO __clewGetEventInfo = NULL; -PFNCLCREATEUSEREVENT __clewCreateUserEvent = NULL; -PFNCLRETAINEVENT __clewRetainEvent = NULL; -PFNCLRELEASEEVENT __clewReleaseEvent = NULL; -PFNCLSETUSEREVENTSTATUS __clewSetUserEventStatus = NULL; -PFNCLSETEVENTCALLBACK __clewSetEventCallback = NULL; -PFNCLGETEVENTPROFILINGINFO __clewGetEventProfilingInfo = NULL; -PFNCLFLUSH __clewFlush = NULL; -PFNCLFINISH __clewFinish = NULL; -PFNCLENQUEUEREADBUFFER __clewEnqueueReadBuffer = NULL; -PFNCLENQUEUEREADBUFFERRECT __clewEnqueueReadBufferRect = NULL; -PFNCLENQUEUEWRITEBUFFER __clewEnqueueWriteBuffer = NULL; -PFNCLENQUEUEWRITEBUFFERRECT __clewEnqueueWriteBufferRect = NULL; -PFNCLENQUEUECOPYBUFFER __clewEnqueueCopyBuffer = NULL; -PFNCLENQUEUEREADIMAGE __clewEnqueueReadImage = NULL; -PFNCLENQUEUEWRITEIMAGE __clewEnqueueWriteImage = NULL; -PFNCLENQUEUECOPYIMAGE __clewEnqueueCopyImage = NULL; -PFNCLENQUEUECOPYBUFFERRECT __clewEnqueueCopyBufferRect = NULL; -PFNCLENQUEUECOPYIMAGETOBUFFER __clewEnqueueCopyImageToBuffer = NULL; -PFNCLENQUEUECOPYBUFFERTOIMAGE __clewEnqueueCopyBufferToImage = NULL; -PFNCLENQUEUEMAPBUFFER __clewEnqueueMapBuffer = NULL; -PFNCLENQUEUEMAPIMAGE __clewEnqueueMapImage = NULL; -PFNCLENQUEUEUNMAPMEMOBJECT __clewEnqueueUnmapMemObject = NULL; -PFNCLENQUEUENDRANGEKERNEL __clewEnqueueNDRangeKernel = NULL; -PFNCLENQUEUETASK __clewEnqueueTask = NULL; -PFNCLENQUEUENATIVEKERNEL __clewEnqueueNativeKernel = NULL; -PFNCLENQUEUEMARKER __clewEnqueueMarker = NULL; -PFNCLENQUEUEWAITFOREVENTS __clewEnqueueWaitForEvents = NULL; -PFNCLENQUEUEBARRIER __clewEnqueueBarrier = NULL; -PFNCLGETEXTENSIONFUNCTIONADDRESS __clewGetExtensionFunctionAddress = NULL; - +PFNCLCREATESAMPLER __clewCreateSampler = NULL; +PFNCLRETAINSAMPLER __clewRetainSampler = NULL; +PFNCLRELEASESAMPLER __clewReleaseSampler = NULL; +PFNCLGETSAMPLERINFO __clewGetSamplerInfo = NULL; +PFNCLCREATEPROGRAMWITHSOURCE __clewCreateProgramWithSource = NULL; +PFNCLCREATEPROGRAMWITHBINARY __clewCreateProgramWithBinary = NULL; +PFNCLRETAINPROGRAM __clewRetainProgram = NULL; +PFNCLRELEASEPROGRAM __clewReleaseProgram = NULL; +PFNCLBUILDPROGRAM __clewBuildProgram = NULL; +PFNCLUNLOADCOMPILER __clewUnloadCompiler = NULL; +PFNCLGETPROGRAMINFO __clewGetProgramInfo = NULL; +PFNCLGETPROGRAMBUILDINFO __clewGetProgramBuildInfo = NULL; +PFNCLCREATEKERNEL __clewCreateKernel = NULL; +PFNCLCREATEKERNELSINPROGRAM __clewCreateKernelsInProgram = NULL; +PFNCLRETAINKERNEL __clewRetainKernel = NULL; +PFNCLRELEASEKERNEL __clewReleaseKernel = NULL; +PFNCLSETKERNELARG __clewSetKernelArg = NULL; +PFNCLGETKERNELINFO __clewGetKernelInfo = NULL; +PFNCLGETKERNELWORKGROUPINFO __clewGetKernelWorkGroupInfo = NULL; +PFNCLWAITFOREVENTS __clewWaitForEvents = NULL; +PFNCLGETEVENTINFO __clewGetEventInfo = NULL; +PFNCLCREATEUSEREVENT __clewCreateUserEvent = NULL; +PFNCLRETAINEVENT __clewRetainEvent = NULL; +PFNCLRELEASEEVENT __clewReleaseEvent = NULL; +PFNCLSETUSEREVENTSTATUS __clewSetUserEventStatus = NULL; +PFNCLSETEVENTCALLBACK __clewSetEventCallback = NULL; +PFNCLGETEVENTPROFILINGINFO __clewGetEventProfilingInfo = NULL; +PFNCLFLUSH __clewFlush = NULL; +PFNCLFINISH __clewFinish = NULL; +PFNCLENQUEUEREADBUFFER __clewEnqueueReadBuffer = NULL; +PFNCLENQUEUEREADBUFFERRECT __clewEnqueueReadBufferRect = NULL; +PFNCLENQUEUEWRITEBUFFER __clewEnqueueWriteBuffer = NULL; +PFNCLENQUEUEWRITEBUFFERRECT __clewEnqueueWriteBufferRect = NULL; +PFNCLENQUEUECOPYBUFFER __clewEnqueueCopyBuffer = NULL; +PFNCLENQUEUEREADIMAGE __clewEnqueueReadImage = NULL; +PFNCLENQUEUEWRITEIMAGE __clewEnqueueWriteImage = NULL; +PFNCLENQUEUECOPYIMAGE __clewEnqueueCopyImage = NULL; +PFNCLENQUEUECOPYBUFFERRECT __clewEnqueueCopyBufferRect = NULL; +PFNCLENQUEUECOPYIMAGETOBUFFER __clewEnqueueCopyImageToBuffer = NULL; +PFNCLENQUEUECOPYBUFFERTOIMAGE __clewEnqueueCopyBufferToImage = NULL; +PFNCLENQUEUEMAPBUFFER __clewEnqueueMapBuffer = NULL; +PFNCLENQUEUEMAPIMAGE __clewEnqueueMapImage = NULL; +PFNCLENQUEUEUNMAPMEMOBJECT __clewEnqueueUnmapMemObject = NULL; +PFNCLENQUEUENDRANGEKERNEL __clewEnqueueNDRangeKernel = NULL; +PFNCLENQUEUETASK __clewEnqueueTask = NULL; +PFNCLENQUEUENATIVEKERNEL __clewEnqueueNativeKernel = NULL; +PFNCLENQUEUEMARKER __clewEnqueueMarker = NULL; +PFNCLENQUEUEWAITFOREVENTS __clewEnqueueWaitForEvents = NULL; +PFNCLENQUEUEBARRIER __clewEnqueueBarrier = NULL; +PFNCLGETEXTENSIONFUNCTIONADDRESS __clewGetExtensionFunctionAddress = NULL; void clewExit(void) { - if (module != NULL) - { - // Ignore errors - CLEW_DYNLIB_CLOSE(module); - module = NULL; - } + if (module != NULL) + { + // Ignore errors + CLEW_DYNLIB_CLOSE(module); + module = NULL; + } } int clewInit(const char* path) { - int error = 0; + int error = 0; - // Check if already initialized - if (module != NULL) - { - return CLEW_SUCCESS; - } + // Check if already initialized + if (module != NULL) + { + return CLEW_SUCCESS; + } - // Load library - module = CLEW_DYNLIB_OPEN(path); + // Load library + module = CLEW_DYNLIB_OPEN(path); - // Check for errors - if (module == NULL) - { - return CLEW_ERROR_OPEN_FAILED; - } + // Check for errors + if (module == NULL) + { + return CLEW_ERROR_OPEN_FAILED; + } - // Set unloading - error = atexit(clewExit); + // Set unloading + error = atexit(clewExit); - if (error) - { - // Failure queuing atexit, shutdown with error - CLEW_DYNLIB_CLOSE(module); - module = NULL; + if (error) + { + // Failure queuing atexit, shutdown with error + CLEW_DYNLIB_CLOSE(module); + module = NULL; - return CLEW_ERROR_ATEXIT_FAILED; - } + return CLEW_ERROR_ATEXIT_FAILED; + } - // Determine function entry-points - __clewGetPlatformIDs = (PFNCLGETPLATFORMIDS )CLEW_DYNLIB_IMPORT(module, "clGetPlatformIDs"); - __clewGetPlatformInfo = (PFNCLGETPLATFORMINFO )CLEW_DYNLIB_IMPORT(module, "clGetPlatformInfo"); - __clewGetDeviceIDs = (PFNCLGETDEVICEIDS )CLEW_DYNLIB_IMPORT(module, "clGetDeviceIDs"); - __clewGetDeviceInfo = (PFNCLGETDEVICEINFO )CLEW_DYNLIB_IMPORT(module, "clGetDeviceInfo"); - __clewCreateContext = (PFNCLCREATECONTEXT )CLEW_DYNLIB_IMPORT(module, "clCreateContext"); - __clewCreateContextFromType = (PFNCLCREATECONTEXTFROMTYPE )CLEW_DYNLIB_IMPORT(module, "clCreateContextFromType"); - __clewRetainContext = (PFNCLRETAINCONTEXT )CLEW_DYNLIB_IMPORT(module, "clRetainContext"); - __clewReleaseContext = (PFNCLRELEASECONTEXT )CLEW_DYNLIB_IMPORT(module, "clReleaseContext"); - __clewGetContextInfo = (PFNCLGETCONTEXTINFO )CLEW_DYNLIB_IMPORT(module, "clGetContextInfo"); - __clewCreateCommandQueue = (PFNCLCREATECOMMANDQUEUE )CLEW_DYNLIB_IMPORT(module, "clCreateCommandQueue"); - __clewRetainCommandQueue = (PFNCLRETAINCOMMANDQUEUE )CLEW_DYNLIB_IMPORT(module, "clRetainCommandQueue"); - __clewReleaseCommandQueue = (PFNCLRELEASECOMMANDQUEUE )CLEW_DYNLIB_IMPORT(module, "clReleaseCommandQueue"); - __clewGetCommandQueueInfo = (PFNCLGETCOMMANDQUEUEINFO )CLEW_DYNLIB_IMPORT(module, "clGetCommandQueueInfo"); + // Determine function entry-points + __clewGetPlatformIDs = (PFNCLGETPLATFORMIDS)CLEW_DYNLIB_IMPORT(module, "clGetPlatformIDs"); + __clewGetPlatformInfo = (PFNCLGETPLATFORMINFO)CLEW_DYNLIB_IMPORT(module, "clGetPlatformInfo"); + __clewGetDeviceIDs = (PFNCLGETDEVICEIDS)CLEW_DYNLIB_IMPORT(module, "clGetDeviceIDs"); + __clewGetDeviceInfo = (PFNCLGETDEVICEINFO)CLEW_DYNLIB_IMPORT(module, "clGetDeviceInfo"); + __clewCreateContext = (PFNCLCREATECONTEXT)CLEW_DYNLIB_IMPORT(module, "clCreateContext"); + __clewCreateContextFromType = (PFNCLCREATECONTEXTFROMTYPE)CLEW_DYNLIB_IMPORT(module, "clCreateContextFromType"); + __clewRetainContext = (PFNCLRETAINCONTEXT)CLEW_DYNLIB_IMPORT(module, "clRetainContext"); + __clewReleaseContext = (PFNCLRELEASECONTEXT)CLEW_DYNLIB_IMPORT(module, "clReleaseContext"); + __clewGetContextInfo = (PFNCLGETCONTEXTINFO)CLEW_DYNLIB_IMPORT(module, "clGetContextInfo"); + __clewCreateCommandQueue = (PFNCLCREATECOMMANDQUEUE)CLEW_DYNLIB_IMPORT(module, "clCreateCommandQueue"); + __clewRetainCommandQueue = (PFNCLRETAINCOMMANDQUEUE)CLEW_DYNLIB_IMPORT(module, "clRetainCommandQueue"); + __clewReleaseCommandQueue = (PFNCLRELEASECOMMANDQUEUE)CLEW_DYNLIB_IMPORT(module, "clReleaseCommandQueue"); + __clewGetCommandQueueInfo = (PFNCLGETCOMMANDQUEUEINFO)CLEW_DYNLIB_IMPORT(module, "clGetCommandQueueInfo"); #ifdef CL_USE_DEPRECATED_OPENCL_1_0_APIS - __clewSetCommandQueueProperty = (PFNCLSETCOMMANDQUEUEPROPERTY )CLEW_DYNLIB_IMPORT(module, "clSetCommandQueueProperty"); + __clewSetCommandQueueProperty = (PFNCLSETCOMMANDQUEUEPROPERTY)CLEW_DYNLIB_IMPORT(module, "clSetCommandQueueProperty"); #endif - __clewCreateBuffer = (PFNCLCREATEBUFFER )CLEW_DYNLIB_IMPORT(module, "clCreateBuffer"); - __clewCreateSubBuffer = (PFNCLCREATESUBBUFFER )CLEW_DYNLIB_IMPORT(module, "clCreateBuffer"); - __clewCreateImage2D = (PFNCLCREATEIMAGE2D )CLEW_DYNLIB_IMPORT(module, "clCreateImage2D"); - __clewCreateImage3D = (PFNCLCREATEIMAGE3D )CLEW_DYNLIB_IMPORT(module, "clCreateImage3D"); - __clewRetainMemObject = (PFNCLRETAINMEMOBJECT )CLEW_DYNLIB_IMPORT(module, "clRetainMemObject"); - __clewReleaseMemObject = (PFNCLRELEASEMEMOBJECT )CLEW_DYNLIB_IMPORT(module, "clReleaseMemObject"); - __clewGetSupportedImageFormats = (PFNCLGETSUPPORTEDIMAGEFORMATS )CLEW_DYNLIB_IMPORT(module, "clGetSupportedImageFormats"); - __clewGetMemObjectInfo = (PFNCLGETMEMOBJECTINFO )CLEW_DYNLIB_IMPORT(module, "clGetMemObjectInfo"); - __clewGetImageInfo = (PFNCLGETIMAGEINFO )CLEW_DYNLIB_IMPORT(module, "clGetImageInfo"); - __clewSetMemObjectDestructorCallback = (PFNCLSETMEMOBJECTDESTRUCTORCALLBACK)CLEW_DYNLIB_IMPORT(module, "clSetMemObjectDestructorCallback"); - __clewCreateSampler = (PFNCLCREATESAMPLER )CLEW_DYNLIB_IMPORT(module, "clCreateSampler"); - __clewRetainSampler = (PFNCLRETAINSAMPLER )CLEW_DYNLIB_IMPORT(module, "clRetainSampler"); - __clewReleaseSampler = (PFNCLRELEASESAMPLER )CLEW_DYNLIB_IMPORT(module, "clReleaseSampler"); - __clewGetSamplerInfo = (PFNCLGETSAMPLERINFO )CLEW_DYNLIB_IMPORT(module, "clGetSamplerInfo"); - __clewCreateProgramWithSource = (PFNCLCREATEPROGRAMWITHSOURCE )CLEW_DYNLIB_IMPORT(module, "clCreateProgramWithSource"); - __clewCreateProgramWithBinary = (PFNCLCREATEPROGRAMWITHBINARY )CLEW_DYNLIB_IMPORT(module, "clCreateProgramWithBinary"); - __clewRetainProgram = (PFNCLRETAINPROGRAM )CLEW_DYNLIB_IMPORT(module, "clRetainProgram"); - __clewReleaseProgram = (PFNCLRELEASEPROGRAM )CLEW_DYNLIB_IMPORT(module, "clReleaseProgram"); - __clewBuildProgram = (PFNCLBUILDPROGRAM )CLEW_DYNLIB_IMPORT(module, "clBuildProgram"); - __clewUnloadCompiler = (PFNCLUNLOADCOMPILER )CLEW_DYNLIB_IMPORT(module, "clUnloadCompiler"); - __clewGetProgramInfo = (PFNCLGETPROGRAMINFO )CLEW_DYNLIB_IMPORT(module, "clGetProgramInfo"); - __clewGetProgramBuildInfo = (PFNCLGETPROGRAMBUILDINFO )CLEW_DYNLIB_IMPORT(module, "clGetProgramBuildInfo"); - __clewCreateKernel = (PFNCLCREATEKERNEL )CLEW_DYNLIB_IMPORT(module, "clCreateKernel"); - __clewCreateKernelsInProgram = (PFNCLCREATEKERNELSINPROGRAM )CLEW_DYNLIB_IMPORT(module, "clCreateKernelsInProgram"); - __clewRetainKernel = (PFNCLRETAINKERNEL )CLEW_DYNLIB_IMPORT(module, "clRetainKernel"); - __clewReleaseKernel = (PFNCLRELEASEKERNEL )CLEW_DYNLIB_IMPORT(module, "clReleaseKernel"); - __clewSetKernelArg = (PFNCLSETKERNELARG )CLEW_DYNLIB_IMPORT(module, "clSetKernelArg"); - __clewGetKernelInfo = (PFNCLGETKERNELINFO )CLEW_DYNLIB_IMPORT(module, "clGetKernelInfo"); - __clewGetKernelWorkGroupInfo = (PFNCLGETKERNELWORKGROUPINFO )CLEW_DYNLIB_IMPORT(module, "clGetKernelWorkGroupInfo"); - __clewWaitForEvents = (PFNCLWAITFOREVENTS )CLEW_DYNLIB_IMPORT(module, "clWaitForEvents"); - __clewGetEventInfo = (PFNCLGETEVENTINFO )CLEW_DYNLIB_IMPORT(module, "clGetEventInfo"); - __clewCreateUserEvent = (PFNCLCREATEUSEREVENT )CLEW_DYNLIB_IMPORT(module, "clCreateUserEvent"); - __clewRetainEvent = (PFNCLRETAINEVENT )CLEW_DYNLIB_IMPORT(module, "clRetainEvent"); - __clewReleaseEvent = (PFNCLRELEASEEVENT )CLEW_DYNLIB_IMPORT(module, "clReleaseEvent"); - __clewSetUserEventStatus = (PFNCLSETUSEREVENTSTATUS )CLEW_DYNLIB_IMPORT(module, "clSetUserEventStatus"); - __clewSetEventCallback = (PFNCLSETEVENTCALLBACK )CLEW_DYNLIB_IMPORT(module, "clSetEventCallback"); - __clewGetEventProfilingInfo = (PFNCLGETEVENTPROFILINGINFO )CLEW_DYNLIB_IMPORT(module, "clGetEventProfilingInfo"); - __clewFlush = (PFNCLFLUSH )CLEW_DYNLIB_IMPORT(module, "clFlush"); - __clewFinish = (PFNCLFINISH )CLEW_DYNLIB_IMPORT(module, "clFinish"); - __clewEnqueueReadBuffer = (PFNCLENQUEUEREADBUFFER )CLEW_DYNLIB_IMPORT(module, "clEnqueueReadBuffer"); - __clewEnqueueReadBufferRect = (PFNCLENQUEUEREADBUFFERRECT )CLEW_DYNLIB_IMPORT(module, "clEnqueueReadBufferRect"); - __clewEnqueueWriteBuffer = (PFNCLENQUEUEWRITEBUFFER )CLEW_DYNLIB_IMPORT(module, "clEnqueueWriteBuffer"); - __clewEnqueueWriteBufferRect = (PFNCLENQUEUEWRITEBUFFERRECT )CLEW_DYNLIB_IMPORT(module, "clEnqueueWriteBufferRect"); - __clewEnqueueCopyBuffer = (PFNCLENQUEUECOPYBUFFER )CLEW_DYNLIB_IMPORT(module, "clEnqueueCopyBuffer"); - __clewEnqueueCopyBufferRect = (PFNCLENQUEUECOPYBUFFERRECT )CLEW_DYNLIB_IMPORT(module, "clEnqueueCopyBufferRect"); - __clewEnqueueReadImage = (PFNCLENQUEUEREADIMAGE )CLEW_DYNLIB_IMPORT(module, "clEnqueueReadImage"); - __clewEnqueueWriteImage = (PFNCLENQUEUEWRITEIMAGE )CLEW_DYNLIB_IMPORT(module, "clEnqueueWriteImage"); - __clewEnqueueCopyImage = (PFNCLENQUEUECOPYIMAGE )CLEW_DYNLIB_IMPORT(module, "clEnqueueCopyImage"); - __clewEnqueueCopyImageToBuffer = (PFNCLENQUEUECOPYIMAGETOBUFFER )CLEW_DYNLIB_IMPORT(module, "clEnqueueCopyImageToBuffer"); - __clewEnqueueCopyBufferToImage = (PFNCLENQUEUECOPYBUFFERTOIMAGE )CLEW_DYNLIB_IMPORT(module, "clEnqueueCopyBufferToImage"); - __clewEnqueueMapBuffer = (PFNCLENQUEUEMAPBUFFER )CLEW_DYNLIB_IMPORT(module, "clEnqueueMapBuffer"); - __clewEnqueueMapImage = (PFNCLENQUEUEMAPIMAGE )CLEW_DYNLIB_IMPORT(module, "clEnqueueMapImage"); - __clewEnqueueUnmapMemObject = (PFNCLENQUEUEUNMAPMEMOBJECT )CLEW_DYNLIB_IMPORT(module, "clEnqueueUnmapMemObject"); - __clewEnqueueNDRangeKernel = (PFNCLENQUEUENDRANGEKERNEL )CLEW_DYNLIB_IMPORT(module, "clEnqueueNDRangeKernel"); - __clewEnqueueTask = (PFNCLENQUEUETASK )CLEW_DYNLIB_IMPORT(module, "clEnqueueTask"); - __clewEnqueueNativeKernel = (PFNCLENQUEUENATIVEKERNEL )CLEW_DYNLIB_IMPORT(module, "clEnqueueNativeKernel"); - __clewEnqueueMarker = (PFNCLENQUEUEMARKER )CLEW_DYNLIB_IMPORT(module, "clEnqueueMarker"); - __clewEnqueueWaitForEvents = (PFNCLENQUEUEWAITFOREVENTS )CLEW_DYNLIB_IMPORT(module, "clEnqueueWaitForEvents"); - __clewEnqueueBarrier = (PFNCLENQUEUEBARRIER )CLEW_DYNLIB_IMPORT(module, "clEnqueueBarrier"); - __clewGetExtensionFunctionAddress = (PFNCLGETEXTENSIONFUNCTIONADDRESS )CLEW_DYNLIB_IMPORT(module, "clGetExtensionFunctionAddress"); + __clewCreateBuffer = (PFNCLCREATEBUFFER)CLEW_DYNLIB_IMPORT(module, "clCreateBuffer"); + __clewCreateSubBuffer = (PFNCLCREATESUBBUFFER)CLEW_DYNLIB_IMPORT(module, "clCreateBuffer"); + __clewCreateImage2D = (PFNCLCREATEIMAGE2D)CLEW_DYNLIB_IMPORT(module, "clCreateImage2D"); + __clewCreateImage3D = (PFNCLCREATEIMAGE3D)CLEW_DYNLIB_IMPORT(module, "clCreateImage3D"); + __clewRetainMemObject = (PFNCLRETAINMEMOBJECT)CLEW_DYNLIB_IMPORT(module, "clRetainMemObject"); + __clewReleaseMemObject = (PFNCLRELEASEMEMOBJECT)CLEW_DYNLIB_IMPORT(module, "clReleaseMemObject"); + __clewGetSupportedImageFormats = (PFNCLGETSUPPORTEDIMAGEFORMATS)CLEW_DYNLIB_IMPORT(module, "clGetSupportedImageFormats"); + __clewGetMemObjectInfo = (PFNCLGETMEMOBJECTINFO)CLEW_DYNLIB_IMPORT(module, "clGetMemObjectInfo"); + __clewGetImageInfo = (PFNCLGETIMAGEINFO)CLEW_DYNLIB_IMPORT(module, "clGetImageInfo"); + __clewSetMemObjectDestructorCallback = (PFNCLSETMEMOBJECTDESTRUCTORCALLBACK)CLEW_DYNLIB_IMPORT(module, "clSetMemObjectDestructorCallback"); + __clewCreateSampler = (PFNCLCREATESAMPLER)CLEW_DYNLIB_IMPORT(module, "clCreateSampler"); + __clewRetainSampler = (PFNCLRETAINSAMPLER)CLEW_DYNLIB_IMPORT(module, "clRetainSampler"); + __clewReleaseSampler = (PFNCLRELEASESAMPLER)CLEW_DYNLIB_IMPORT(module, "clReleaseSampler"); + __clewGetSamplerInfo = (PFNCLGETSAMPLERINFO)CLEW_DYNLIB_IMPORT(module, "clGetSamplerInfo"); + __clewCreateProgramWithSource = (PFNCLCREATEPROGRAMWITHSOURCE)CLEW_DYNLIB_IMPORT(module, "clCreateProgramWithSource"); + __clewCreateProgramWithBinary = (PFNCLCREATEPROGRAMWITHBINARY)CLEW_DYNLIB_IMPORT(module, "clCreateProgramWithBinary"); + __clewRetainProgram = (PFNCLRETAINPROGRAM)CLEW_DYNLIB_IMPORT(module, "clRetainProgram"); + __clewReleaseProgram = (PFNCLRELEASEPROGRAM)CLEW_DYNLIB_IMPORT(module, "clReleaseProgram"); + __clewBuildProgram = (PFNCLBUILDPROGRAM)CLEW_DYNLIB_IMPORT(module, "clBuildProgram"); + __clewUnloadCompiler = (PFNCLUNLOADCOMPILER)CLEW_DYNLIB_IMPORT(module, "clUnloadCompiler"); + __clewGetProgramInfo = (PFNCLGETPROGRAMINFO)CLEW_DYNLIB_IMPORT(module, "clGetProgramInfo"); + __clewGetProgramBuildInfo = (PFNCLGETPROGRAMBUILDINFO)CLEW_DYNLIB_IMPORT(module, "clGetProgramBuildInfo"); + __clewCreateKernel = (PFNCLCREATEKERNEL)CLEW_DYNLIB_IMPORT(module, "clCreateKernel"); + __clewCreateKernelsInProgram = (PFNCLCREATEKERNELSINPROGRAM)CLEW_DYNLIB_IMPORT(module, "clCreateKernelsInProgram"); + __clewRetainKernel = (PFNCLRETAINKERNEL)CLEW_DYNLIB_IMPORT(module, "clRetainKernel"); + __clewReleaseKernel = (PFNCLRELEASEKERNEL)CLEW_DYNLIB_IMPORT(module, "clReleaseKernel"); + __clewSetKernelArg = (PFNCLSETKERNELARG)CLEW_DYNLIB_IMPORT(module, "clSetKernelArg"); + __clewGetKernelInfo = (PFNCLGETKERNELINFO)CLEW_DYNLIB_IMPORT(module, "clGetKernelInfo"); + __clewGetKernelWorkGroupInfo = (PFNCLGETKERNELWORKGROUPINFO)CLEW_DYNLIB_IMPORT(module, "clGetKernelWorkGroupInfo"); + __clewWaitForEvents = (PFNCLWAITFOREVENTS)CLEW_DYNLIB_IMPORT(module, "clWaitForEvents"); + __clewGetEventInfo = (PFNCLGETEVENTINFO)CLEW_DYNLIB_IMPORT(module, "clGetEventInfo"); + __clewCreateUserEvent = (PFNCLCREATEUSEREVENT)CLEW_DYNLIB_IMPORT(module, "clCreateUserEvent"); + __clewRetainEvent = (PFNCLRETAINEVENT)CLEW_DYNLIB_IMPORT(module, "clRetainEvent"); + __clewReleaseEvent = (PFNCLRELEASEEVENT)CLEW_DYNLIB_IMPORT(module, "clReleaseEvent"); + __clewSetUserEventStatus = (PFNCLSETUSEREVENTSTATUS)CLEW_DYNLIB_IMPORT(module, "clSetUserEventStatus"); + __clewSetEventCallback = (PFNCLSETEVENTCALLBACK)CLEW_DYNLIB_IMPORT(module, "clSetEventCallback"); + __clewGetEventProfilingInfo = (PFNCLGETEVENTPROFILINGINFO)CLEW_DYNLIB_IMPORT(module, "clGetEventProfilingInfo"); + __clewFlush = (PFNCLFLUSH)CLEW_DYNLIB_IMPORT(module, "clFlush"); + __clewFinish = (PFNCLFINISH)CLEW_DYNLIB_IMPORT(module, "clFinish"); + __clewEnqueueReadBuffer = (PFNCLENQUEUEREADBUFFER)CLEW_DYNLIB_IMPORT(module, "clEnqueueReadBuffer"); + __clewEnqueueReadBufferRect = (PFNCLENQUEUEREADBUFFERRECT)CLEW_DYNLIB_IMPORT(module, "clEnqueueReadBufferRect"); + __clewEnqueueWriteBuffer = (PFNCLENQUEUEWRITEBUFFER)CLEW_DYNLIB_IMPORT(module, "clEnqueueWriteBuffer"); + __clewEnqueueWriteBufferRect = (PFNCLENQUEUEWRITEBUFFERRECT)CLEW_DYNLIB_IMPORT(module, "clEnqueueWriteBufferRect"); + __clewEnqueueCopyBuffer = (PFNCLENQUEUECOPYBUFFER)CLEW_DYNLIB_IMPORT(module, "clEnqueueCopyBuffer"); + __clewEnqueueCopyBufferRect = (PFNCLENQUEUECOPYBUFFERRECT)CLEW_DYNLIB_IMPORT(module, "clEnqueueCopyBufferRect"); + __clewEnqueueReadImage = (PFNCLENQUEUEREADIMAGE)CLEW_DYNLIB_IMPORT(module, "clEnqueueReadImage"); + __clewEnqueueWriteImage = (PFNCLENQUEUEWRITEIMAGE)CLEW_DYNLIB_IMPORT(module, "clEnqueueWriteImage"); + __clewEnqueueCopyImage = (PFNCLENQUEUECOPYIMAGE)CLEW_DYNLIB_IMPORT(module, "clEnqueueCopyImage"); + __clewEnqueueCopyImageToBuffer = (PFNCLENQUEUECOPYIMAGETOBUFFER)CLEW_DYNLIB_IMPORT(module, "clEnqueueCopyImageToBuffer"); + __clewEnqueueCopyBufferToImage = (PFNCLENQUEUECOPYBUFFERTOIMAGE)CLEW_DYNLIB_IMPORT(module, "clEnqueueCopyBufferToImage"); + __clewEnqueueMapBuffer = (PFNCLENQUEUEMAPBUFFER)CLEW_DYNLIB_IMPORT(module, "clEnqueueMapBuffer"); + __clewEnqueueMapImage = (PFNCLENQUEUEMAPIMAGE)CLEW_DYNLIB_IMPORT(module, "clEnqueueMapImage"); + __clewEnqueueUnmapMemObject = (PFNCLENQUEUEUNMAPMEMOBJECT)CLEW_DYNLIB_IMPORT(module, "clEnqueueUnmapMemObject"); + __clewEnqueueNDRangeKernel = (PFNCLENQUEUENDRANGEKERNEL)CLEW_DYNLIB_IMPORT(module, "clEnqueueNDRangeKernel"); + __clewEnqueueTask = (PFNCLENQUEUETASK)CLEW_DYNLIB_IMPORT(module, "clEnqueueTask"); + __clewEnqueueNativeKernel = (PFNCLENQUEUENATIVEKERNEL)CLEW_DYNLIB_IMPORT(module, "clEnqueueNativeKernel"); + __clewEnqueueMarker = (PFNCLENQUEUEMARKER)CLEW_DYNLIB_IMPORT(module, "clEnqueueMarker"); + __clewEnqueueWaitForEvents = (PFNCLENQUEUEWAITFOREVENTS)CLEW_DYNLIB_IMPORT(module, "clEnqueueWaitForEvents"); + __clewEnqueueBarrier = (PFNCLENQUEUEBARRIER)CLEW_DYNLIB_IMPORT(module, "clEnqueueBarrier"); + __clewGetExtensionFunctionAddress = (PFNCLGETEXTENSIONFUNCTIONADDRESS)CLEW_DYNLIB_IMPORT(module, "clGetExtensionFunctionAddress"); - return CLEW_SUCCESS; + return CLEW_SUCCESS; } const char* clewErrorString(cl_int error) { - static const char* strings[] = - { - // Error Codes - "CL_SUCCESS" // 0 - , "CL_DEVICE_NOT_FOUND" // -1 - , "CL_DEVICE_NOT_AVAILABLE" // -2 - , "CL_COMPILER_NOT_AVAILABLE" // -3 - , "CL_MEM_OBJECT_ALLOCATION_FAILURE" // -4 - , "CL_OUT_OF_RESOURCES" // -5 - , "CL_OUT_OF_HOST_MEMORY" // -6 - , "CL_PROFILING_INFO_NOT_AVAILABLE" // -7 - , "CL_MEM_COPY_OVERLAP" // -8 - , "CL_IMAGE_FORMAT_MISMATCH" // -9 - , "CL_IMAGE_FORMAT_NOT_SUPPORTED" // -10 - , "CL_BUILD_PROGRAM_FAILURE" // -11 - , "CL_MAP_FAILURE" // -12 + static const char* strings[] = + { + // Error Codes + "CL_SUCCESS" // 0 + , + "CL_DEVICE_NOT_FOUND" // -1 + , + "CL_DEVICE_NOT_AVAILABLE" // -2 + , + "CL_COMPILER_NOT_AVAILABLE" // -3 + , + "CL_MEM_OBJECT_ALLOCATION_FAILURE" // -4 + , + "CL_OUT_OF_RESOURCES" // -5 + , + "CL_OUT_OF_HOST_MEMORY" // -6 + , + "CL_PROFILING_INFO_NOT_AVAILABLE" // -7 + , + "CL_MEM_COPY_OVERLAP" // -8 + , + "CL_IMAGE_FORMAT_MISMATCH" // -9 + , + "CL_IMAGE_FORMAT_NOT_SUPPORTED" // -10 + , + "CL_BUILD_PROGRAM_FAILURE" // -11 + , + "CL_MAP_FAILURE" // -12 - , "" // -13 - , "" // -14 - , "" // -15 - , "" // -16 - , "" // -17 - , "" // -18 - , "" // -19 + , + "" // -13 + , + "" // -14 + , + "" // -15 + , + "" // -16 + , + "" // -17 + , + "" // -18 + , + "" // -19 - , "" // -20 - , "" // -21 - , "" // -22 - , "" // -23 - , "" // -24 - , "" // -25 - , "" // -26 - , "" // -27 - , "" // -28 - , "" // -29 + , + "" // -20 + , + "" // -21 + , + "" // -22 + , + "" // -23 + , + "" // -24 + , + "" // -25 + , + "" // -26 + , + "" // -27 + , + "" // -28 + , + "" // -29 - , "CL_INVALID_VALUE" // -30 - , "CL_INVALID_DEVICE_TYPE" // -31 - , "CL_INVALID_PLATFORM" // -32 - , "CL_INVALID_DEVICE" // -33 - , "CL_INVALID_CONTEXT" // -34 - , "CL_INVALID_QUEUE_PROPERTIES" // -35 - , "CL_INVALID_COMMAND_QUEUE" // -36 - , "CL_INVALID_HOST_PTR" // -37 - , "CL_INVALID_MEM_OBJECT" // -38 - , "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR" // -39 - , "CL_INVALID_IMAGE_SIZE" // -40 - , "CL_INVALID_SAMPLER" // -41 - , "CL_INVALID_BINARY" // -42 - , "CL_INVALID_BUILD_OPTIONS" // -43 - , "CL_INVALID_PROGRAM" // -44 - , "CL_INVALID_PROGRAM_EXECUTABLE" // -45 - , "CL_INVALID_KERNEL_NAME" // -46 - , "CL_INVALID_KERNEL_DEFINITION" // -47 - , "CL_INVALID_KERNEL" // -48 - , "CL_INVALID_ARG_INDEX" // -49 - , "CL_INVALID_ARG_VALUE" // -50 - , "CL_INVALID_ARG_SIZE" // -51 - , "CL_INVALID_KERNEL_ARGS" // -52 - , "CL_INVALID_WORK_DIMENSION" // -53 - , "CL_INVALID_WORK_GROUP_SIZE" // -54 - , "CL_INVALID_WORK_ITEM_SIZE" // -55 - , "CL_INVALID_GLOBAL_OFFSET" // -56 - , "CL_INVALID_EVENT_WAIT_LIST" // -57 - , "CL_INVALID_EVENT" // -58 - , "CL_INVALID_OPERATION" // -59 - , "CL_INVALID_GL_OBJECT" // -60 - , "CL_INVALID_BUFFER_SIZE" // -61 - , "CL_INVALID_MIP_LEVEL" // -62 - , "CL_INVALID_GLOBAL_WORK_SIZE" // -63 - }; + , + "CL_INVALID_VALUE" // -30 + , + "CL_INVALID_DEVICE_TYPE" // -31 + , + "CL_INVALID_PLATFORM" // -32 + , + "CL_INVALID_DEVICE" // -33 + , + "CL_INVALID_CONTEXT" // -34 + , + "CL_INVALID_QUEUE_PROPERTIES" // -35 + , + "CL_INVALID_COMMAND_QUEUE" // -36 + , + "CL_INVALID_HOST_PTR" // -37 + , + "CL_INVALID_MEM_OBJECT" // -38 + , + "CL_INVALID_IMAGE_FORMAT_DESCRIPTOR" // -39 + , + "CL_INVALID_IMAGE_SIZE" // -40 + , + "CL_INVALID_SAMPLER" // -41 + , + "CL_INVALID_BINARY" // -42 + , + "CL_INVALID_BUILD_OPTIONS" // -43 + , + "CL_INVALID_PROGRAM" // -44 + , + "CL_INVALID_PROGRAM_EXECUTABLE" // -45 + , + "CL_INVALID_KERNEL_NAME" // -46 + , + "CL_INVALID_KERNEL_DEFINITION" // -47 + , + "CL_INVALID_KERNEL" // -48 + , + "CL_INVALID_ARG_INDEX" // -49 + , + "CL_INVALID_ARG_VALUE" // -50 + , + "CL_INVALID_ARG_SIZE" // -51 + , + "CL_INVALID_KERNEL_ARGS" // -52 + , + "CL_INVALID_WORK_DIMENSION" // -53 + , + "CL_INVALID_WORK_GROUP_SIZE" // -54 + , + "CL_INVALID_WORK_ITEM_SIZE" // -55 + , + "CL_INVALID_GLOBAL_OFFSET" // -56 + , + "CL_INVALID_EVENT_WAIT_LIST" // -57 + , + "CL_INVALID_EVENT" // -58 + , + "CL_INVALID_OPERATION" // -59 + , + "CL_INVALID_GL_OBJECT" // -60 + , + "CL_INVALID_BUFFER_SIZE" // -61 + , + "CL_INVALID_MIP_LEVEL" // -62 + , + "CL_INVALID_GLOBAL_WORK_SIZE" // -63 + }; - return strings[-error]; + return strings[-error]; } diff --git a/src/clew/clew.h b/src/clew/clew.h index ee0fef18b..cba858523 100644 --- a/src/clew/clew.h +++ b/src/clew/clew.h @@ -11,7 +11,7 @@ //! \file clew.h //! \brief OpenCL run-time loader header //! -//! This file contains a copy of the contents of CL.H and CL_PLATFORM.H from the +//! This file contains a copy of the contents of CL.H and CL_PLATFORM.H from the //! official OpenCL spec. The purpose of this code is to load the OpenCL dynamic //! library at run-time and thus allow the executable to function on many //! platforms regardless of the vendor of the OpenCL driver actually installed. @@ -19,11 +19,11 @@ //! library (http://glew.sourceforge.net/) // Run-time dynamic linking functionality based on concepts used in GLEW -#ifdef __OPENCL_CL_H +#ifdef __OPENCL_CL_H #error cl.h included before clew.h #endif -#ifdef __OPENCL_CL_PLATFORM_H +#ifdef __OPENCL_CL_PLATFORM_H #error cl_platform.h included before clew.h #endif @@ -55,238 +55,239 @@ * MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. ******************************************************************************/ #ifdef __APPLE__ - /* Contains #defines for AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER below */ - #include +/* Contains #defines for AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER below */ +#include #endif #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif #if defined(_WIN32) - #define CL_API_ENTRY - #define CL_API_CALL __stdcall - #define CL_CALLBACK __stdcall +#define CL_API_ENTRY +#define CL_API_CALL __stdcall +#define CL_CALLBACK __stdcall #else - #define CL_API_ENTRY - #define CL_API_CALL - #define CL_CALLBACK +#define CL_API_ENTRY +#define CL_API_CALL +#define CL_CALLBACK #endif -//disabled the APPLE thing, don't know why it is there, is just causes tons of warnings + //disabled the APPLE thing, don't know why it is there, is just causes tons of warnings #ifdef __APPLE1__ - #define CL_EXTENSION_WEAK_LINK __attribute__((weak_import)) - #define CL_API_SUFFIX__VERSION_1_0 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER - #define CL_EXT_SUFFIX__VERSION_1_0 CL_EXTENSION_WEAK_LINK AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER - #define CL_API_SUFFIX__VERSION_1_1 CL_EXTENSION_WEAK_LINK - #define CL_EXT_SUFFIX__VERSION_1_1 CL_EXTENSION_WEAK_LINK - #define CL_EXT_SUFFIX__VERSION_1_0_DEPRECATED CL_EXTENSION_WEAK_LINK AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#define CL_EXTENSION_WEAK_LINK __attribute__((weak_import)) +#define CL_API_SUFFIX__VERSION_1_0 AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#define CL_EXT_SUFFIX__VERSION_1_0 CL_EXTENSION_WEAK_LINK AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER +#define CL_API_SUFFIX__VERSION_1_1 CL_EXTENSION_WEAK_LINK +#define CL_EXT_SUFFIX__VERSION_1_1 CL_EXTENSION_WEAK_LINK +#define CL_EXT_SUFFIX__VERSION_1_0_DEPRECATED CL_EXTENSION_WEAK_LINK AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER #else - #define CL_EXTENSION_WEAK_LINK - #define CL_API_SUFFIX__VERSION_1_0 - #define CL_EXT_SUFFIX__VERSION_1_0 - #define CL_API_SUFFIX__VERSION_1_1 - #define CL_EXT_SUFFIX__VERSION_1_1 - #define CL_EXT_SUFFIX__VERSION_1_0_DEPRECATED +#define CL_EXTENSION_WEAK_LINK +#define CL_API_SUFFIX__VERSION_1_0 +#define CL_EXT_SUFFIX__VERSION_1_0 +#define CL_API_SUFFIX__VERSION_1_1 +#define CL_EXT_SUFFIX__VERSION_1_1 +#define CL_EXT_SUFFIX__VERSION_1_0_DEPRECATED #endif -#if (defined (_WIN32) && defined(_MSC_VER)) +#if (defined(_WIN32) && defined(_MSC_VER)) -/* scalar types */ -typedef signed __int8 cl_char; -typedef unsigned __int8 cl_uchar; -typedef signed __int16 cl_short; -typedef unsigned __int16 cl_ushort; -typedef signed __int32 cl_int; -typedef unsigned __int32 cl_uint; -typedef signed __int64 cl_long; -typedef unsigned __int64 cl_ulong; + /* scalar types */ + typedef signed __int8 cl_char; + typedef unsigned __int8 cl_uchar; + typedef signed __int16 cl_short; + typedef unsigned __int16 cl_ushort; + typedef signed __int32 cl_int; + typedef unsigned __int32 cl_uint; + typedef signed __int64 cl_long; + typedef unsigned __int64 cl_ulong; -typedef unsigned __int16 cl_half; -typedef float cl_float; -typedef double cl_double; + typedef unsigned __int16 cl_half; + typedef float cl_float; + typedef double cl_double; /* Macro names and corresponding values defined by OpenCL */ -#define CL_CHAR_BIT 8 -#define CL_SCHAR_MAX 127 -#define CL_SCHAR_MIN (-127-1) -#define CL_CHAR_MAX CL_SCHAR_MAX -#define CL_CHAR_MIN CL_SCHAR_MIN -#define CL_UCHAR_MAX 255 -#define CL_SHRT_MAX 32767 -#define CL_SHRT_MIN (-32767-1) -#define CL_USHRT_MAX 65535 -#define CL_INT_MAX 2147483647 -#define CL_INT_MIN (-2147483647-1) -#define CL_UINT_MAX 0xffffffffU -#define CL_LONG_MAX ((cl_long) 0x7FFFFFFFFFFFFFFFLL) -#define CL_LONG_MIN ((cl_long) -0x7FFFFFFFFFFFFFFFLL - 1LL) -#define CL_ULONG_MAX ((cl_ulong) 0xFFFFFFFFFFFFFFFFULL) +#define CL_CHAR_BIT 8 +#define CL_SCHAR_MAX 127 +#define CL_SCHAR_MIN (-127 - 1) +#define CL_CHAR_MAX CL_SCHAR_MAX +#define CL_CHAR_MIN CL_SCHAR_MIN +#define CL_UCHAR_MAX 255 +#define CL_SHRT_MAX 32767 +#define CL_SHRT_MIN (-32767 - 1) +#define CL_USHRT_MAX 65535 +#define CL_INT_MAX 2147483647 +#define CL_INT_MIN (-2147483647 - 1) +#define CL_UINT_MAX 0xffffffffU +#define CL_LONG_MAX ((cl_long)0x7FFFFFFFFFFFFFFFLL) +#define CL_LONG_MIN ((cl_long)-0x7FFFFFFFFFFFFFFFLL - 1LL) +#define CL_ULONG_MAX ((cl_ulong)0xFFFFFFFFFFFFFFFFULL) -#define CL_FLT_DIG 6 -#define CL_FLT_MANT_DIG 24 -#define CL_FLT_MAX_10_EXP +38 -#define CL_FLT_MAX_EXP +128 -#define CL_FLT_MIN_10_EXP -37 -#define CL_FLT_MIN_EXP -125 -#define CL_FLT_RADIX 2 -#define CL_FLT_MAX 340282346638528859811704183484516925440.0f -#define CL_FLT_MIN 1.175494350822287507969e-38f -#define CL_FLT_EPSILON 0x1.0p-23f +#define CL_FLT_DIG 6 +#define CL_FLT_MANT_DIG 24 +#define CL_FLT_MAX_10_EXP +38 +#define CL_FLT_MAX_EXP +128 +#define CL_FLT_MIN_10_EXP -37 +#define CL_FLT_MIN_EXP -125 +#define CL_FLT_RADIX 2 +#define CL_FLT_MAX 340282346638528859811704183484516925440.0f +#define CL_FLT_MIN 1.175494350822287507969e-38f +#define CL_FLT_EPSILON 0x1.0p-23f -#define CL_DBL_DIG 15 -#define CL_DBL_MANT_DIG 53 -#define CL_DBL_MAX_10_EXP +308 -#define CL_DBL_MAX_EXP +1024 -#define CL_DBL_MIN_10_EXP -307 -#define CL_DBL_MIN_EXP -1021 -#define CL_DBL_RADIX 2 -#define CL_DBL_MAX 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0 -#define CL_DBL_MIN 2.225073858507201383090e-308 -#define CL_DBL_EPSILON 2.220446049250313080847e-16 +#define CL_DBL_DIG 15 +#define CL_DBL_MANT_DIG 53 +#define CL_DBL_MAX_10_EXP +308 +#define CL_DBL_MAX_EXP +1024 +#define CL_DBL_MIN_10_EXP -307 +#define CL_DBL_MIN_EXP -1021 +#define CL_DBL_RADIX 2 +#define CL_DBL_MAX 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368.0 +#define CL_DBL_MIN 2.225073858507201383090e-308 +#define CL_DBL_EPSILON 2.220446049250313080847e-16 -#define CL_M_E 2.718281828459045090796 -#define CL_M_LOG2E 1.442695040888963387005 -#define CL_M_LOG10E 0.434294481903251816668 -#define CL_M_LN2 0.693147180559945286227 -#define CL_M_LN10 2.302585092994045901094 -#define CL_M_PI 3.141592653589793115998 -#define CL_M_PI_2 1.570796326794896557999 -#define CL_M_PI_4 0.785398163397448278999 -#define CL_M_1_PI 0.318309886183790691216 -#define CL_M_2_PI 0.636619772367581382433 -#define CL_M_2_SQRTPI 1.128379167095512558561 -#define CL_M_SQRT2 1.414213562373095145475 -#define CL_M_SQRT1_2 0.707106781186547572737 +#define CL_M_E 2.718281828459045090796 +#define CL_M_LOG2E 1.442695040888963387005 +#define CL_M_LOG10E 0.434294481903251816668 +#define CL_M_LN2 0.693147180559945286227 +#define CL_M_LN10 2.302585092994045901094 +#define CL_M_PI 3.141592653589793115998 +#define CL_M_PI_2 1.570796326794896557999 +#define CL_M_PI_4 0.785398163397448278999 +#define CL_M_1_PI 0.318309886183790691216 +#define CL_M_2_PI 0.636619772367581382433 +#define CL_M_2_SQRTPI 1.128379167095512558561 +#define CL_M_SQRT2 1.414213562373095145475 +#define CL_M_SQRT1_2 0.707106781186547572737 -#define CL_M_E_F 2.71828174591064f -#define CL_M_LOG2E_F 1.44269502162933f -#define CL_M_LOG10E_F 0.43429449200630f -#define CL_M_LN2_F 0.69314718246460f -#define CL_M_LN10_F 2.30258512496948f -#define CL_M_PI_F 3.14159274101257f -#define CL_M_PI_2_F 1.57079637050629f -#define CL_M_PI_4_F 0.78539818525314f -#define CL_M_1_PI_F 0.31830987334251f -#define CL_M_2_PI_F 0.63661974668503f -#define CL_M_2_SQRTPI_F 1.12837922573090f -#define CL_M_SQRT2_F 1.41421353816986f -#define CL_M_SQRT1_2_F 0.70710676908493f +#define CL_M_E_F 2.71828174591064f +#define CL_M_LOG2E_F 1.44269502162933f +#define CL_M_LOG10E_F 0.43429449200630f +#define CL_M_LN2_F 0.69314718246460f +#define CL_M_LN10_F 2.30258512496948f +#define CL_M_PI_F 3.14159274101257f +#define CL_M_PI_2_F 1.57079637050629f +#define CL_M_PI_4_F 0.78539818525314f +#define CL_M_1_PI_F 0.31830987334251f +#define CL_M_2_PI_F 0.63661974668503f +#define CL_M_2_SQRTPI_F 1.12837922573090f +#define CL_M_SQRT2_F 1.41421353816986f +#define CL_M_SQRT1_2_F 0.70710676908493f -#define CL_NAN (CL_INFINITY - CL_INFINITY) -#define CL_HUGE_VALF ((cl_float) 1e50) -#define CL_HUGE_VAL ((cl_double) 1e500) -#define CL_MAXFLOAT CL_FLT_MAX -#define CL_INFINITY CL_HUGE_VALF +#define CL_NAN (CL_INFINITY - CL_INFINITY) +#define CL_HUGE_VALF ((cl_float)1e50) +#define CL_HUGE_VAL ((cl_double)1e500) +#define CL_MAXFLOAT CL_FLT_MAX +#define CL_INFINITY CL_HUGE_VALF #else #include /* scalar types */ -typedef int8_t cl_char; -typedef uint8_t cl_uchar; -typedef int16_t cl_short __attribute__((aligned(2))); -typedef uint16_t cl_ushort __attribute__((aligned(2))); -typedef int32_t cl_int __attribute__((aligned(4))); -typedef uint32_t cl_uint __attribute__((aligned(4))); -typedef int64_t cl_long __attribute__((aligned(8))); -typedef uint64_t cl_ulong __attribute__((aligned(8))); +typedef int8_t cl_char; +typedef uint8_t cl_uchar; +typedef int16_t cl_short __attribute__((aligned(2))); +typedef uint16_t cl_ushort __attribute__((aligned(2))); +typedef int32_t cl_int __attribute__((aligned(4))); +typedef uint32_t cl_uint __attribute__((aligned(4))); +typedef int64_t cl_long __attribute__((aligned(8))); +typedef uint64_t cl_ulong __attribute__((aligned(8))); -typedef uint16_t cl_half __attribute__((aligned(2))); -typedef float cl_float __attribute__((aligned(4))); -typedef double cl_double __attribute__((aligned(8))); +typedef uint16_t cl_half __attribute__((aligned(2))); +typedef float cl_float __attribute__((aligned(4))); +typedef double cl_double __attribute__((aligned(8))); /* Macro names and corresponding values defined by OpenCL */ -#define CL_CHAR_BIT 8 -#define CL_SCHAR_MAX 127 -#define CL_SCHAR_MIN (-127-1) -#define CL_CHAR_MAX CL_SCHAR_MAX -#define CL_CHAR_MIN CL_SCHAR_MIN -#define CL_UCHAR_MAX 255 -#define CL_SHRT_MAX 32767 -#define CL_SHRT_MIN (-32767-1) -#define CL_USHRT_MAX 65535 -#define CL_INT_MAX 2147483647 -#define CL_INT_MIN (-2147483647-1) -#define CL_UINT_MAX 0xffffffffU -#define CL_LONG_MAX ((cl_long) 0x7FFFFFFFFFFFFFFFLL) -#define CL_LONG_MIN ((cl_long) -0x7FFFFFFFFFFFFFFFLL - 1LL) -#define CL_ULONG_MAX ((cl_ulong) 0xFFFFFFFFFFFFFFFFULL) +#define CL_CHAR_BIT 8 +#define CL_SCHAR_MAX 127 +#define CL_SCHAR_MIN (-127 - 1) +#define CL_CHAR_MAX CL_SCHAR_MAX +#define CL_CHAR_MIN CL_SCHAR_MIN +#define CL_UCHAR_MAX 255 +#define CL_SHRT_MAX 32767 +#define CL_SHRT_MIN (-32767 - 1) +#define CL_USHRT_MAX 65535 +#define CL_INT_MAX 2147483647 +#define CL_INT_MIN (-2147483647 - 1) +#define CL_UINT_MAX 0xffffffffU +#define CL_LONG_MAX ((cl_long)0x7FFFFFFFFFFFFFFFLL) +#define CL_LONG_MIN ((cl_long)-0x7FFFFFFFFFFFFFFFLL - 1LL) +#define CL_ULONG_MAX ((cl_ulong)0xFFFFFFFFFFFFFFFFULL) -#define CL_FLT_DIG 6 -#define CL_FLT_MANT_DIG 24 -#define CL_FLT_MAX_10_EXP +38 -#define CL_FLT_MAX_EXP +128 -#define CL_FLT_MIN_10_EXP -37 -#define CL_FLT_MIN_EXP -125 -#define CL_FLT_RADIX 2 -#define CL_FLT_MAX 0x1.fffffep127f -#define CL_FLT_MIN 0x1.0p-126f -#define CL_FLT_EPSILON 0x1.0p-23f +#define CL_FLT_DIG 6 +#define CL_FLT_MANT_DIG 24 +#define CL_FLT_MAX_10_EXP +38 +#define CL_FLT_MAX_EXP +128 +#define CL_FLT_MIN_10_EXP -37 +#define CL_FLT_MIN_EXP -125 +#define CL_FLT_RADIX 2 +#define CL_FLT_MAX 0x1.fffffep127f +#define CL_FLT_MIN 0x1.0p-126f +#define CL_FLT_EPSILON 0x1.0p-23f -#define CL_DBL_DIG 15 -#define CL_DBL_MANT_DIG 53 -#define CL_DBL_MAX_10_EXP +308 -#define CL_DBL_MAX_EXP +1024 -#define CL_DBL_MIN_10_EXP -307 -#define CL_DBL_MIN_EXP -1021 -#define CL_DBL_RADIX 2 -#define CL_DBL_MAX 0x1.fffffffffffffp1023 -#define CL_DBL_MIN 0x1.0p-1022 -#define CL_DBL_EPSILON 0x1.0p-52 +#define CL_DBL_DIG 15 +#define CL_DBL_MANT_DIG 53 +#define CL_DBL_MAX_10_EXP +308 +#define CL_DBL_MAX_EXP +1024 +#define CL_DBL_MIN_10_EXP -307 +#define CL_DBL_MIN_EXP -1021 +#define CL_DBL_RADIX 2 +#define CL_DBL_MAX 0x1.fffffffffffffp1023 +#define CL_DBL_MIN 0x1.0p-1022 +#define CL_DBL_EPSILON 0x1.0p-52 -#define CL_M_E 2.718281828459045090796 -#define CL_M_LOG2E 1.442695040888963387005 -#define CL_M_LOG10E 0.434294481903251816668 -#define CL_M_LN2 0.693147180559945286227 -#define CL_M_LN10 2.302585092994045901094 -#define CL_M_PI 3.141592653589793115998 -#define CL_M_PI_2 1.570796326794896557999 -#define CL_M_PI_4 0.785398163397448278999 -#define CL_M_1_PI 0.318309886183790691216 -#define CL_M_2_PI 0.636619772367581382433 -#define CL_M_2_SQRTPI 1.128379167095512558561 -#define CL_M_SQRT2 1.414213562373095145475 -#define CL_M_SQRT1_2 0.707106781186547572737 +#define CL_M_E 2.718281828459045090796 +#define CL_M_LOG2E 1.442695040888963387005 +#define CL_M_LOG10E 0.434294481903251816668 +#define CL_M_LN2 0.693147180559945286227 +#define CL_M_LN10 2.302585092994045901094 +#define CL_M_PI 3.141592653589793115998 +#define CL_M_PI_2 1.570796326794896557999 +#define CL_M_PI_4 0.785398163397448278999 +#define CL_M_1_PI 0.318309886183790691216 +#define CL_M_2_PI 0.636619772367581382433 +#define CL_M_2_SQRTPI 1.128379167095512558561 +#define CL_M_SQRT2 1.414213562373095145475 +#define CL_M_SQRT1_2 0.707106781186547572737 -#define CL_M_E_F 2.71828174591064f -#define CL_M_LOG2E_F 1.44269502162933f -#define CL_M_LOG10E_F 0.43429449200630f -#define CL_M_LN2_F 0.69314718246460f -#define CL_M_LN10_F 2.30258512496948f -#define CL_M_PI_F 3.14159274101257f -#define CL_M_PI_2_F 1.57079637050629f -#define CL_M_PI_4_F 0.78539818525314f -#define CL_M_1_PI_F 0.31830987334251f -#define CL_M_2_PI_F 0.63661974668503f -#define CL_M_2_SQRTPI_F 1.12837922573090f -#define CL_M_SQRT2_F 1.41421353816986f -#define CL_M_SQRT1_2_F 0.70710676908493f +#define CL_M_E_F 2.71828174591064f +#define CL_M_LOG2E_F 1.44269502162933f +#define CL_M_LOG10E_F 0.43429449200630f +#define CL_M_LN2_F 0.69314718246460f +#define CL_M_LN10_F 2.30258512496948f +#define CL_M_PI_F 3.14159274101257f +#define CL_M_PI_2_F 1.57079637050629f +#define CL_M_PI_4_F 0.78539818525314f +#define CL_M_1_PI_F 0.31830987334251f +#define CL_M_2_PI_F 0.63661974668503f +#define CL_M_2_SQRTPI_F 1.12837922573090f +#define CL_M_SQRT2_F 1.41421353816986f +#define CL_M_SQRT1_2_F 0.70710676908493f -#if defined( __GNUC__ ) - #define CL_HUGE_VALF __builtin_huge_valf() - #define CL_HUGE_VAL __builtin_huge_val() - #define CL_NAN __builtin_nanf( "" ) +#if defined(__GNUC__) +#define CL_HUGE_VALF __builtin_huge_valf() +#define CL_HUGE_VAL __builtin_huge_val() +#define CL_NAN __builtin_nanf("") #else - #define CL_HUGE_VALF ((cl_float) 1e50) - #define CL_HUGE_VAL ((cl_double) 1e500) - float nanf( const char * ); - #define CL_NAN nanf( "" ) +#define CL_HUGE_VALF ((cl_float)1e50) +#define CL_HUGE_VAL ((cl_double)1e500) +float nanf(const char *); +#define CL_NAN nanf("") #endif -#define CL_MAXFLOAT CL_FLT_MAX -#define CL_INFINITY CL_HUGE_VALF +#define CL_MAXFLOAT CL_FLT_MAX +#define CL_INFINITY CL_HUGE_VALF #endif #include -/* Mirror types to GL types. Mirror types allow us to avoid deciding which headers to load based on whether we are using GL or GLES here. */ -typedef unsigned int cl_GLuint; -typedef int cl_GLint; -typedef unsigned int cl_GLenum; + /* Mirror types to GL types. Mirror types allow us to avoid deciding which headers to load based on whether we are using GL or GLES here. */ + typedef unsigned int cl_GLuint; + typedef int cl_GLint; + typedef unsigned int cl_GLenum; -/* + /* * Vector types * * Note: OpenCL requires that all types be naturally aligned. @@ -302,7 +303,6 @@ typedef unsigned int cl_GLenum; * Maintaining proper alignment is the user's responsibility. */ - #ifdef _MSC_VER #if defined(_M_IX86) #if _M_IX86_FP >= 0 @@ -318,904 +318,1218 @@ typedef unsigned int cl_GLenum; #endif /* Define basic vector types */ -#if defined( __VEC__ ) - #include /* may be omitted depending on compiler. AltiVec spec provides no way to detect whether the header is required. */ - typedef vector unsigned char __cl_uchar16; - typedef vector signed char __cl_char16; - typedef vector unsigned short __cl_ushort8; - typedef vector signed short __cl_short8; - typedef vector unsigned int __cl_uint4; - typedef vector signed int __cl_int4; - typedef vector float __cl_float4; - #define __CL_UCHAR16__ 1 - #define __CL_CHAR16__ 1 - #define __CL_USHORT8__ 1 - #define __CL_SHORT8__ 1 - #define __CL_UINT4__ 1 - #define __CL_INT4__ 1 - #define __CL_FLOAT4__ 1 +#if defined(__VEC__) +#include /* may be omitted depending on compiler. AltiVec spec provides no way to detect whether the header is required. */ + typedef vector unsigned char __cl_uchar16; + typedef vector signed char __cl_char16; + typedef vector unsigned short __cl_ushort8; + typedef vector signed short __cl_short8; + typedef vector unsigned int __cl_uint4; + typedef vector signed int __cl_int4; + typedef vector float __cl_float4; +#define __CL_UCHAR16__ 1 +#define __CL_CHAR16__ 1 +#define __CL_USHORT8__ 1 +#define __CL_SHORT8__ 1 +#define __CL_UINT4__ 1 +#define __CL_INT4__ 1 +#define __CL_FLOAT4__ 1 #endif -#if defined( __SSE__ ) - #if defined( __MINGW64__ ) - #include - #else - #include - #endif - #if defined( __GNUC__ ) && !defined( __ICC ) - typedef float __cl_float4 __attribute__((vector_size(16))); - #else - typedef __m128 __cl_float4; - #endif - #define __CL_FLOAT4__ 1 +#if defined(__SSE__) +#if defined(__MINGW64__) +#include +#else +#include +#endif +#if defined(__GNUC__) && !defined(__ICC) + typedef float __cl_float4 __attribute__((vector_size(16))); +#else + typedef __m128 __cl_float4; +#endif +#define __CL_FLOAT4__ 1 #endif -#if defined( __SSE2__ ) - #if defined( __MINGW64__ ) - #include - #else - #include - #endif - #if defined( __GNUC__ ) && !defined( __ICC ) - typedef cl_uchar __cl_uchar16 __attribute__((vector_size(16))); - typedef cl_char __cl_char16 __attribute__((vector_size(16))); - typedef cl_ushort __cl_ushort8 __attribute__((vector_size(16))); - typedef cl_short __cl_short8 __attribute__((vector_size(16))); - typedef cl_uint __cl_uint4 __attribute__((vector_size(16))); - typedef cl_int __cl_int4 __attribute__((vector_size(16))); - typedef cl_ulong __cl_ulong2 __attribute__((vector_size(16))); - typedef cl_long __cl_long2 __attribute__((vector_size(16))); - typedef cl_double __cl_double2 __attribute__((vector_size(16))); - #else - typedef __m128i __cl_uchar16; - typedef __m128i __cl_char16; - typedef __m128i __cl_ushort8; - typedef __m128i __cl_short8; - typedef __m128i __cl_uint4; - typedef __m128i __cl_int4; - typedef __m128i __cl_ulong2; - typedef __m128i __cl_long2; - typedef __m128d __cl_double2; - #endif - #define __CL_UCHAR16__ 1 - #define __CL_CHAR16__ 1 - #define __CL_USHORT8__ 1 - #define __CL_SHORT8__ 1 - #define __CL_INT4__ 1 - #define __CL_UINT4__ 1 - #define __CL_ULONG2__ 1 - #define __CL_LONG2__ 1 - #define __CL_DOUBLE2__ 1 +#if defined(__SSE2__) +#if defined(__MINGW64__) +#include +#else +#include +#endif +#if defined(__GNUC__) && !defined(__ICC) + typedef cl_uchar __cl_uchar16 __attribute__((vector_size(16))); + typedef cl_char __cl_char16 __attribute__((vector_size(16))); + typedef cl_ushort __cl_ushort8 __attribute__((vector_size(16))); + typedef cl_short __cl_short8 __attribute__((vector_size(16))); + typedef cl_uint __cl_uint4 __attribute__((vector_size(16))); + typedef cl_int __cl_int4 __attribute__((vector_size(16))); + typedef cl_ulong __cl_ulong2 __attribute__((vector_size(16))); + typedef cl_long __cl_long2 __attribute__((vector_size(16))); + typedef cl_double __cl_double2 __attribute__((vector_size(16))); +#else + typedef __m128i __cl_uchar16; + typedef __m128i __cl_char16; + typedef __m128i __cl_ushort8; + typedef __m128i __cl_short8; + typedef __m128i __cl_uint4; + typedef __m128i __cl_int4; + typedef __m128i __cl_ulong2; + typedef __m128i __cl_long2; + typedef __m128d __cl_double2; +#endif +#define __CL_UCHAR16__ 1 +#define __CL_CHAR16__ 1 +#define __CL_USHORT8__ 1 +#define __CL_SHORT8__ 1 +#define __CL_INT4__ 1 +#define __CL_UINT4__ 1 +#define __CL_ULONG2__ 1 +#define __CL_LONG2__ 1 +#define __CL_DOUBLE2__ 1 #endif -#if defined( __MMX__ ) - #include - #if defined( __GNUC__ ) && !defined( __ICC ) - typedef cl_uchar __cl_uchar8 __attribute__((vector_size(8))); - typedef cl_char __cl_char8 __attribute__((vector_size(8))); - typedef cl_ushort __cl_ushort4 __attribute__((vector_size(8))); - typedef cl_short __cl_short4 __attribute__((vector_size(8))); - typedef cl_uint __cl_uint2 __attribute__((vector_size(8))); - typedef cl_int __cl_int2 __attribute__((vector_size(8))); - typedef cl_ulong __cl_ulong1 __attribute__((vector_size(8))); - typedef cl_long __cl_long1 __attribute__((vector_size(8))); - typedef cl_float __cl_float2 __attribute__((vector_size(8))); - #else - typedef __m64 __cl_uchar8; - typedef __m64 __cl_char8; - typedef __m64 __cl_ushort4; - typedef __m64 __cl_short4; - typedef __m64 __cl_uint2; - typedef __m64 __cl_int2; - typedef __m64 __cl_ulong1; - typedef __m64 __cl_long1; - typedef __m64 __cl_float2; - #endif - #define __CL_UCHAR8__ 1 - #define __CL_CHAR8__ 1 - #define __CL_USHORT4__ 1 - #define __CL_SHORT4__ 1 - #define __CL_INT2__ 1 - #define __CL_UINT2__ 1 - #define __CL_ULONG1__ 1 - #define __CL_LONG1__ 1 - #define __CL_FLOAT2__ 1 +#if defined(__MMX__) +#include +#if defined(__GNUC__) && !defined(__ICC) + typedef cl_uchar __cl_uchar8 __attribute__((vector_size(8))); + typedef cl_char __cl_char8 __attribute__((vector_size(8))); + typedef cl_ushort __cl_ushort4 __attribute__((vector_size(8))); + typedef cl_short __cl_short4 __attribute__((vector_size(8))); + typedef cl_uint __cl_uint2 __attribute__((vector_size(8))); + typedef cl_int __cl_int2 __attribute__((vector_size(8))); + typedef cl_ulong __cl_ulong1 __attribute__((vector_size(8))); + typedef cl_long __cl_long1 __attribute__((vector_size(8))); + typedef cl_float __cl_float2 __attribute__((vector_size(8))); +#else + typedef __m64 __cl_uchar8; + typedef __m64 __cl_char8; + typedef __m64 __cl_ushort4; + typedef __m64 __cl_short4; + typedef __m64 __cl_uint2; + typedef __m64 __cl_int2; + typedef __m64 __cl_ulong1; + typedef __m64 __cl_long1; + typedef __m64 __cl_float2; +#endif +#define __CL_UCHAR8__ 1 +#define __CL_CHAR8__ 1 +#define __CL_USHORT4__ 1 +#define __CL_SHORT4__ 1 +#define __CL_INT2__ 1 +#define __CL_UINT2__ 1 +#define __CL_ULONG1__ 1 +#define __CL_LONG1__ 1 +#define __CL_FLOAT2__ 1 #endif -#if defined( __AVX__ ) - #if defined( __MINGW64__ ) - #include - #else - #include - #endif - #if defined( __GNUC__ ) && !defined( __ICC ) - typedef cl_float __cl_float8 __attribute__((vector_size(32))); - typedef cl_double __cl_double4 __attribute__((vector_size(32))); - #else - typedef __m256 __cl_float8; - typedef __m256d __cl_double4; - #endif - #define __CL_FLOAT8__ 1 - #define __CL_DOUBLE4__ 1 +#if defined(__AVX__) +#if defined(__MINGW64__) +#include +#else +#include +#endif +#if defined(__GNUC__) && !defined(__ICC) + typedef cl_float __cl_float8 __attribute__((vector_size(32))); + typedef cl_double __cl_double4 __attribute__((vector_size(32))); +#else + typedef __m256 __cl_float8; + typedef __m256d __cl_double4; +#endif +#define __CL_FLOAT8__ 1 +#define __CL_DOUBLE4__ 1 #endif /* Define alignment keys */ -#if defined( __GNUC__ ) - #define CL_ALIGNED(_x) __attribute__ ((aligned(_x))) -#elif defined( _WIN32) && (_MSC_VER) - /* Alignment keys neutered on windows because MSVC can't swallow function arguments with alignment requirements */ - /* http://msdn.microsoft.com/en-us/library/373ak2y1%28VS.71%29.aspx */ - /* #include */ - /* #define CL_ALIGNED(_x) _CRT_ALIGN(_x) */ - #define CL_ALIGNED(_x) +#if defined(__GNUC__) +#define CL_ALIGNED(_x) __attribute__((aligned(_x))) +#elif defined(_WIN32) && (_MSC_VER) +/* Alignment keys neutered on windows because MSVC can't swallow function arguments with alignment requirements */ +/* http://msdn.microsoft.com/en-us/library/373ak2y1%28VS.71%29.aspx */ +/* #include */ +/* #define CL_ALIGNED(_x) _CRT_ALIGN(_x) */ +#define CL_ALIGNED(_x) #else - #warning Need to implement some method to align data here - #define CL_ALIGNED(_x) +#warning Need to implement some method to align data here +#define CL_ALIGNED(_x) #endif /* Indicate whether .xyzw, .s0123 and .hi.lo are supported */ -#if (defined( __GNUC__) && ! defined( __STRICT_ANSI__ )) || (defined( _MSC_VER ) && ! defined( __STDC__ )) - /* .xyzw and .s0123...{f|F} are supported */ - #define CL_HAS_NAMED_VECTOR_FIELDS 1 - /* .hi and .lo are supported */ - #define CL_HAS_HI_LO_VECTOR_FIELDS 1 +#if (defined(__GNUC__) && !defined(__STRICT_ANSI__)) || (defined(_MSC_VER) && !defined(__STDC__)) +/* .xyzw and .s0123...{f|F} are supported */ +#define CL_HAS_NAMED_VECTOR_FIELDS 1 +/* .hi and .lo are supported */ +#define CL_HAS_HI_LO_VECTOR_FIELDS 1 - #define CL_NAMED_STRUCT_SUPPORTED +#define CL_NAMED_STRUCT_SUPPORTED #endif -#if defined( CL_NAMED_STRUCT_SUPPORTED) && defined( _MSC_VER ) -#define __extension__ __pragma(warning(suppress:4201)) +#if defined(CL_NAMED_STRUCT_SUPPORTED) && defined(_MSC_VER) +#define __extension__ __pragma(warning(suppress : 4201)) #endif -/* Define cl_vector types */ + /* Define cl_vector types */ -/* ---- cl_charn ---- */ -typedef union -{ - cl_char CL_ALIGNED(2) s[2]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_char x, y; }; - __extension__ struct{ cl_char s0, s1; }; - __extension__ struct{ cl_char lo, hi; }; + /* ---- cl_charn ---- */ + typedef union { + cl_char CL_ALIGNED(2) s[2]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_char x, y; + }; + __extension__ struct + { + cl_char s0, s1; + }; + __extension__ struct + { + cl_char lo, hi; + }; #endif -#if defined( __CL_CHAR2__) - __cl_char2 v2; +#if defined(__CL_CHAR2__) + __cl_char2 v2; #endif -}cl_char2; + } cl_char2; -typedef union -{ - cl_char CL_ALIGNED(4) s[4]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_char x, y, z, w; }; - __extension__ struct{ cl_char s0, s1, s2, s3; }; - __extension__ struct{ cl_char2 lo, hi; }; + typedef union { + cl_char CL_ALIGNED(4) s[4]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_char x, y, z, w; + }; + __extension__ struct + { + cl_char s0, s1, s2, s3; + }; + __extension__ struct + { + cl_char2 lo, hi; + }; #endif -#if defined( __CL_CHAR2__) - __cl_char2 v2[2]; +#if defined(__CL_CHAR2__) + __cl_char2 v2[2]; #endif -#if defined( __CL_CHAR4__) - __cl_char4 v4; +#if defined(__CL_CHAR4__) + __cl_char4 v4; #endif -}cl_char4; + } cl_char4; -/* cl_char3 is identical in size, alignment and behavior to cl_char4. See section 6.1.5. */ -typedef cl_char4 cl_char3; + /* cl_char3 is identical in size, alignment and behavior to cl_char4. See section 6.1.5. */ + typedef cl_char4 cl_char3; -typedef union -{ - cl_char CL_ALIGNED(8) s[8]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_char x, y, z, w; }; - __extension__ struct{ cl_char s0, s1, s2, s3, s4, s5, s6, s7; }; - __extension__ struct{ cl_char4 lo, hi; }; + typedef union { + cl_char CL_ALIGNED(8) s[8]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_char x, y, z, w; + }; + __extension__ struct + { + cl_char s0, s1, s2, s3, s4, s5, s6, s7; + }; + __extension__ struct + { + cl_char4 lo, hi; + }; #endif -#if defined( __CL_CHAR2__) - __cl_char2 v2[4]; +#if defined(__CL_CHAR2__) + __cl_char2 v2[4]; #endif -#if defined( __CL_CHAR4__) - __cl_char4 v4[2]; +#if defined(__CL_CHAR4__) + __cl_char4 v4[2]; #endif -#if defined( __CL_CHAR8__ ) - __cl_char8 v8; +#if defined(__CL_CHAR8__) + __cl_char8 v8; #endif -}cl_char8; + } cl_char8; -typedef union -{ - cl_char CL_ALIGNED(16) s[16]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_char x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; - __extension__ struct{ cl_char s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; - __extension__ struct{ cl_char8 lo, hi; }; + typedef union { + cl_char CL_ALIGNED(16) s[16]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_char x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; + }; + __extension__ struct + { + cl_char s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; + }; + __extension__ struct + { + cl_char8 lo, hi; + }; #endif -#if defined( __CL_CHAR2__) - __cl_char2 v2[8]; +#if defined(__CL_CHAR2__) + __cl_char2 v2[8]; #endif -#if defined( __CL_CHAR4__) - __cl_char4 v4[4]; +#if defined(__CL_CHAR4__) + __cl_char4 v4[4]; #endif -#if defined( __CL_CHAR8__ ) - __cl_char8 v8[2]; +#if defined(__CL_CHAR8__) + __cl_char8 v8[2]; #endif -#if defined( __CL_CHAR16__ ) - __cl_char16 v16; +#if defined(__CL_CHAR16__) + __cl_char16 v16; #endif -}cl_char16; + } cl_char16; + /* ---- cl_ucharn ---- */ + typedef union { + cl_uchar CL_ALIGNED(2) s[2]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_uchar x, y; + }; + __extension__ struct + { + cl_uchar s0, s1; + }; + __extension__ struct + { + cl_uchar lo, hi; + }; +#endif +#if defined(__cl_uchar2__) + __cl_uchar2 v2; +#endif + } cl_uchar2; -/* ---- cl_ucharn ---- */ -typedef union -{ - cl_uchar CL_ALIGNED(2) s[2]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_uchar x, y; }; - __extension__ struct{ cl_uchar s0, s1; }; - __extension__ struct{ cl_uchar lo, hi; }; + typedef union { + cl_uchar CL_ALIGNED(4) s[4]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_uchar x, y, z, w; + }; + __extension__ struct + { + cl_uchar s0, s1, s2, s3; + }; + __extension__ struct + { + cl_uchar2 lo, hi; + }; #endif -#if defined( __cl_uchar2__) - __cl_uchar2 v2; +#if defined(__CL_UCHAR2__) + __cl_uchar2 v2[2]; #endif -}cl_uchar2; +#if defined(__CL_UCHAR4__) + __cl_uchar4 v4; +#endif + } cl_uchar4; -typedef union -{ - cl_uchar CL_ALIGNED(4) s[4]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_uchar x, y, z, w; }; - __extension__ struct{ cl_uchar s0, s1, s2, s3; }; - __extension__ struct{ cl_uchar2 lo, hi; }; -#endif -#if defined( __CL_UCHAR2__) - __cl_uchar2 v2[2]; -#endif -#if defined( __CL_UCHAR4__) - __cl_uchar4 v4; -#endif -}cl_uchar4; + /* cl_uchar3 is identical in size, alignment and behavior to cl_uchar4. See section 6.1.5. */ + typedef cl_uchar4 cl_uchar3; -/* cl_uchar3 is identical in size, alignment and behavior to cl_uchar4. See section 6.1.5. */ -typedef cl_uchar4 cl_uchar3; + typedef union { + cl_uchar CL_ALIGNED(8) s[8]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_uchar x, y, z, w; + }; + __extension__ struct + { + cl_uchar s0, s1, s2, s3, s4, s5, s6, s7; + }; + __extension__ struct + { + cl_uchar4 lo, hi; + }; +#endif +#if defined(__CL_UCHAR2__) + __cl_uchar2 v2[4]; +#endif +#if defined(__CL_UCHAR4__) + __cl_uchar4 v4[2]; +#endif +#if defined(__CL_UCHAR8__) + __cl_uchar8 v8; +#endif + } cl_uchar8; -typedef union -{ - cl_uchar CL_ALIGNED(8) s[8]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_uchar x, y, z, w; }; - __extension__ struct{ cl_uchar s0, s1, s2, s3, s4, s5, s6, s7; }; - __extension__ struct{ cl_uchar4 lo, hi; }; + typedef union { + cl_uchar CL_ALIGNED(16) s[16]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_uchar x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; + }; + __extension__ struct + { + cl_uchar s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; + }; + __extension__ struct + { + cl_uchar8 lo, hi; + }; #endif -#if defined( __CL_UCHAR2__) - __cl_uchar2 v2[4]; +#if defined(__CL_UCHAR2__) + __cl_uchar2 v2[8]; #endif -#if defined( __CL_UCHAR4__) - __cl_uchar4 v4[2]; +#if defined(__CL_UCHAR4__) + __cl_uchar4 v4[4]; #endif -#if defined( __CL_UCHAR8__ ) - __cl_uchar8 v8; +#if defined(__CL_UCHAR8__) + __cl_uchar8 v8[2]; #endif -}cl_uchar8; +#if defined(__CL_UCHAR16__) + __cl_uchar16 v16; +#endif + } cl_uchar16; -typedef union -{ - cl_uchar CL_ALIGNED(16) s[16]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_uchar x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; - __extension__ struct{ cl_uchar s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; - __extension__ struct{ cl_uchar8 lo, hi; }; + /* ---- cl_shortn ---- */ + typedef union { + cl_short CL_ALIGNED(4) s[2]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_short x, y; + }; + __extension__ struct + { + cl_short s0, s1; + }; + __extension__ struct + { + cl_short lo, hi; + }; #endif -#if defined( __CL_UCHAR2__) - __cl_uchar2 v2[8]; +#if defined(__CL_SHORT2__) + __cl_short2 v2; #endif -#if defined( __CL_UCHAR4__) - __cl_uchar4 v4[4]; -#endif -#if defined( __CL_UCHAR8__ ) - __cl_uchar8 v8[2]; -#endif -#if defined( __CL_UCHAR16__ ) - __cl_uchar16 v16; -#endif -}cl_uchar16; + } cl_short2; + typedef union { + cl_short CL_ALIGNED(8) s[4]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_short x, y, z, w; + }; + __extension__ struct + { + cl_short s0, s1, s2, s3; + }; + __extension__ struct + { + cl_short2 lo, hi; + }; +#endif +#if defined(__CL_SHORT2__) + __cl_short2 v2[2]; +#endif +#if defined(__CL_SHORT4__) + __cl_short4 v4; +#endif + } cl_short4; -/* ---- cl_shortn ---- */ -typedef union -{ - cl_short CL_ALIGNED(4) s[2]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_short x, y; }; - __extension__ struct{ cl_short s0, s1; }; - __extension__ struct{ cl_short lo, hi; }; -#endif -#if defined( __CL_SHORT2__) - __cl_short2 v2; -#endif -}cl_short2; + /* cl_short3 is identical in size, alignment and behavior to cl_short4. See section 6.1.5. */ + typedef cl_short4 cl_short3; -typedef union -{ - cl_short CL_ALIGNED(8) s[4]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_short x, y, z, w; }; - __extension__ struct{ cl_short s0, s1, s2, s3; }; - __extension__ struct{ cl_short2 lo, hi; }; + typedef union { + cl_short CL_ALIGNED(16) s[8]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_short x, y, z, w; + }; + __extension__ struct + { + cl_short s0, s1, s2, s3, s4, s5, s6, s7; + }; + __extension__ struct + { + cl_short4 lo, hi; + }; #endif -#if defined( __CL_SHORT2__) - __cl_short2 v2[2]; +#if defined(__CL_SHORT2__) + __cl_short2 v2[4]; #endif -#if defined( __CL_SHORT4__) - __cl_short4 v4; +#if defined(__CL_SHORT4__) + __cl_short4 v4[2]; #endif -}cl_short4; +#if defined(__CL_SHORT8__) + __cl_short8 v8; +#endif + } cl_short8; -/* cl_short3 is identical in size, alignment and behavior to cl_short4. See section 6.1.5. */ -typedef cl_short4 cl_short3; + typedef union { + cl_short CL_ALIGNED(32) s[16]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_short x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; + }; + __extension__ struct + { + cl_short s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; + }; + __extension__ struct + { + cl_short8 lo, hi; + }; +#endif +#if defined(__CL_SHORT2__) + __cl_short2 v2[8]; +#endif +#if defined(__CL_SHORT4__) + __cl_short4 v4[4]; +#endif +#if defined(__CL_SHORT8__) + __cl_short8 v8[2]; +#endif +#if defined(__CL_SHORT16__) + __cl_short16 v16; +#endif + } cl_short16; -typedef union -{ - cl_short CL_ALIGNED(16) s[8]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_short x, y, z, w; }; - __extension__ struct{ cl_short s0, s1, s2, s3, s4, s5, s6, s7; }; - __extension__ struct{ cl_short4 lo, hi; }; + /* ---- cl_ushortn ---- */ + typedef union { + cl_ushort CL_ALIGNED(4) s[2]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_ushort x, y; + }; + __extension__ struct + { + cl_ushort s0, s1; + }; + __extension__ struct + { + cl_ushort lo, hi; + }; #endif -#if defined( __CL_SHORT2__) - __cl_short2 v2[4]; +#if defined(__CL_USHORT2__) + __cl_ushort2 v2; #endif -#if defined( __CL_SHORT4__) - __cl_short4 v4[2]; -#endif -#if defined( __CL_SHORT8__ ) - __cl_short8 v8; -#endif -}cl_short8; + } cl_ushort2; -typedef union -{ - cl_short CL_ALIGNED(32) s[16]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_short x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; - __extension__ struct{ cl_short s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; - __extension__ struct{ cl_short8 lo, hi; }; + typedef union { + cl_ushort CL_ALIGNED(8) s[4]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_ushort x, y, z, w; + }; + __extension__ struct + { + cl_ushort s0, s1, s2, s3; + }; + __extension__ struct + { + cl_ushort2 lo, hi; + }; #endif -#if defined( __CL_SHORT2__) - __cl_short2 v2[8]; +#if defined(__CL_USHORT2__) + __cl_ushort2 v2[2]; #endif -#if defined( __CL_SHORT4__) - __cl_short4 v4[4]; +#if defined(__CL_USHORT4__) + __cl_ushort4 v4; #endif -#if defined( __CL_SHORT8__ ) - __cl_short8 v8[2]; -#endif -#if defined( __CL_SHORT16__ ) - __cl_short16 v16; -#endif -}cl_short16; + } cl_ushort4; + /* cl_ushort3 is identical in size, alignment and behavior to cl_ushort4. See section 6.1.5. */ + typedef cl_ushort4 cl_ushort3; -/* ---- cl_ushortn ---- */ -typedef union -{ - cl_ushort CL_ALIGNED(4) s[2]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_ushort x, y; }; - __extension__ struct{ cl_ushort s0, s1; }; - __extension__ struct{ cl_ushort lo, hi; }; + typedef union { + cl_ushort CL_ALIGNED(16) s[8]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_ushort x, y, z, w; + }; + __extension__ struct + { + cl_ushort s0, s1, s2, s3, s4, s5, s6, s7; + }; + __extension__ struct + { + cl_ushort4 lo, hi; + }; #endif -#if defined( __CL_USHORT2__) - __cl_ushort2 v2; +#if defined(__CL_USHORT2__) + __cl_ushort2 v2[4]; #endif -}cl_ushort2; +#if defined(__CL_USHORT4__) + __cl_ushort4 v4[2]; +#endif +#if defined(__CL_USHORT8__) + __cl_ushort8 v8; +#endif + } cl_ushort8; -typedef union -{ - cl_ushort CL_ALIGNED(8) s[4]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_ushort x, y, z, w; }; - __extension__ struct{ cl_ushort s0, s1, s2, s3; }; - __extension__ struct{ cl_ushort2 lo, hi; }; + typedef union { + cl_ushort CL_ALIGNED(32) s[16]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_ushort x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; + }; + __extension__ struct + { + cl_ushort s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; + }; + __extension__ struct + { + cl_ushort8 lo, hi; + }; #endif -#if defined( __CL_USHORT2__) - __cl_ushort2 v2[2]; +#if defined(__CL_USHORT2__) + __cl_ushort2 v2[8]; #endif -#if defined( __CL_USHORT4__) - __cl_ushort4 v4; +#if defined(__CL_USHORT4__) + __cl_ushort4 v4[4]; #endif -}cl_ushort4; +#if defined(__CL_USHORT8__) + __cl_ushort8 v8[2]; +#endif +#if defined(__CL_USHORT16__) + __cl_ushort16 v16; +#endif + } cl_ushort16; -/* cl_ushort3 is identical in size, alignment and behavior to cl_ushort4. See section 6.1.5. */ -typedef cl_ushort4 cl_ushort3; + /* ---- cl_intn ---- */ + typedef union { + cl_int CL_ALIGNED(8) s[2]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_int x, y; + }; + __extension__ struct + { + cl_int s0, s1; + }; + __extension__ struct + { + cl_int lo, hi; + }; +#endif +#if defined(__CL_INT2__) + __cl_int2 v2; +#endif + } cl_int2; -typedef union -{ - cl_ushort CL_ALIGNED(16) s[8]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_ushort x, y, z, w; }; - __extension__ struct{ cl_ushort s0, s1, s2, s3, s4, s5, s6, s7; }; - __extension__ struct{ cl_ushort4 lo, hi; }; + typedef union { + cl_int CL_ALIGNED(16) s[4]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_int x, y, z, w; + }; + __extension__ struct + { + cl_int s0, s1, s2, s3; + }; + __extension__ struct + { + cl_int2 lo, hi; + }; #endif -#if defined( __CL_USHORT2__) - __cl_ushort2 v2[4]; +#if defined(__CL_INT2__) + __cl_int2 v2[2]; #endif -#if defined( __CL_USHORT4__) - __cl_ushort4 v4[2]; +#if defined(__CL_INT4__) + __cl_int4 v4; #endif -#if defined( __CL_USHORT8__ ) - __cl_ushort8 v8; -#endif -}cl_ushort8; + } cl_int4; -typedef union -{ - cl_ushort CL_ALIGNED(32) s[16]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_ushort x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; - __extension__ struct{ cl_ushort s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; - __extension__ struct{ cl_ushort8 lo, hi; }; -#endif -#if defined( __CL_USHORT2__) - __cl_ushort2 v2[8]; -#endif -#if defined( __CL_USHORT4__) - __cl_ushort4 v4[4]; -#endif -#if defined( __CL_USHORT8__ ) - __cl_ushort8 v8[2]; -#endif -#if defined( __CL_USHORT16__ ) - __cl_ushort16 v16; -#endif -}cl_ushort16; + /* cl_int3 is identical in size, alignment and behavior to cl_int4. See section 6.1.5. */ + typedef cl_int4 cl_int3; -/* ---- cl_intn ---- */ -typedef union -{ - cl_int CL_ALIGNED(8) s[2]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_int x, y; }; - __extension__ struct{ cl_int s0, s1; }; - __extension__ struct{ cl_int lo, hi; }; + typedef union { + cl_int CL_ALIGNED(32) s[8]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_int x, y, z, w; + }; + __extension__ struct + { + cl_int s0, s1, s2, s3, s4, s5, s6, s7; + }; + __extension__ struct + { + cl_int4 lo, hi; + }; #endif -#if defined( __CL_INT2__) - __cl_int2 v2; +#if defined(__CL_INT2__) + __cl_int2 v2[4]; #endif -}cl_int2; +#if defined(__CL_INT4__) + __cl_int4 v4[2]; +#endif +#if defined(__CL_INT8__) + __cl_int8 v8; +#endif + } cl_int8; -typedef union -{ - cl_int CL_ALIGNED(16) s[4]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_int x, y, z, w; }; - __extension__ struct{ cl_int s0, s1, s2, s3; }; - __extension__ struct{ cl_int2 lo, hi; }; + typedef union { + cl_int CL_ALIGNED(64) s[16]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_int x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; + }; + __extension__ struct + { + cl_int s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; + }; + __extension__ struct + { + cl_int8 lo, hi; + }; #endif -#if defined( __CL_INT2__) - __cl_int2 v2[2]; +#if defined(__CL_INT2__) + __cl_int2 v2[8]; #endif -#if defined( __CL_INT4__) - __cl_int4 v4; +#if defined(__CL_INT4__) + __cl_int4 v4[4]; #endif -}cl_int4; +#if defined(__CL_INT8__) + __cl_int8 v8[2]; +#endif +#if defined(__CL_INT16__) + __cl_int16 v16; +#endif + } cl_int16; -/* cl_int3 is identical in size, alignment and behavior to cl_int4. See section 6.1.5. */ -typedef cl_int4 cl_int3; + /* ---- cl_uintn ---- */ + typedef union { + cl_uint CL_ALIGNED(8) s[2]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_uint x, y; + }; + __extension__ struct + { + cl_uint s0, s1; + }; + __extension__ struct + { + cl_uint lo, hi; + }; +#endif +#if defined(__CL_UINT2__) + __cl_uint2 v2; +#endif + } cl_uint2; -typedef union -{ - cl_int CL_ALIGNED(32) s[8]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_int x, y, z, w; }; - __extension__ struct{ cl_int s0, s1, s2, s3, s4, s5, s6, s7; }; - __extension__ struct{ cl_int4 lo, hi; }; + typedef union { + cl_uint CL_ALIGNED(16) s[4]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_uint x, y, z, w; + }; + __extension__ struct + { + cl_uint s0, s1, s2, s3; + }; + __extension__ struct + { + cl_uint2 lo, hi; + }; #endif -#if defined( __CL_INT2__) - __cl_int2 v2[4]; +#if defined(__CL_UINT2__) + __cl_uint2 v2[2]; #endif -#if defined( __CL_INT4__) - __cl_int4 v4[2]; +#if defined(__CL_UINT4__) + __cl_uint4 v4; #endif -#if defined( __CL_INT8__ ) - __cl_int8 v8; -#endif -}cl_int8; + } cl_uint4; -typedef union -{ - cl_int CL_ALIGNED(64) s[16]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_int x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; - __extension__ struct{ cl_int s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; - __extension__ struct{ cl_int8 lo, hi; }; -#endif -#if defined( __CL_INT2__) - __cl_int2 v2[8]; -#endif -#if defined( __CL_INT4__) - __cl_int4 v4[4]; -#endif -#if defined( __CL_INT8__ ) - __cl_int8 v8[2]; -#endif -#if defined( __CL_INT16__ ) - __cl_int16 v16; -#endif -}cl_int16; + /* cl_uint3 is identical in size, alignment and behavior to cl_uint4. See section 6.1.5. */ + typedef cl_uint4 cl_uint3; + typedef union { + cl_uint CL_ALIGNED(32) s[8]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_uint x, y, z, w; + }; + __extension__ struct + { + cl_uint s0, s1, s2, s3, s4, s5, s6, s7; + }; + __extension__ struct + { + cl_uint4 lo, hi; + }; +#endif +#if defined(__CL_UINT2__) + __cl_uint2 v2[4]; +#endif +#if defined(__CL_UINT4__) + __cl_uint4 v4[2]; +#endif +#if defined(__CL_UINT8__) + __cl_uint8 v8; +#endif + } cl_uint8; -/* ---- cl_uintn ---- */ -typedef union -{ - cl_uint CL_ALIGNED(8) s[2]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_uint x, y; }; - __extension__ struct{ cl_uint s0, s1; }; - __extension__ struct{ cl_uint lo, hi; }; + typedef union { + cl_uint CL_ALIGNED(64) s[16]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_uint x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; + }; + __extension__ struct + { + cl_uint s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; + }; + __extension__ struct + { + cl_uint8 lo, hi; + }; #endif -#if defined( __CL_UINT2__) - __cl_uint2 v2; +#if defined(__CL_UINT2__) + __cl_uint2 v2[8]; #endif -}cl_uint2; +#if defined(__CL_UINT4__) + __cl_uint4 v4[4]; +#endif +#if defined(__CL_UINT8__) + __cl_uint8 v8[2]; +#endif +#if defined(__CL_UINT16__) + __cl_uint16 v16; +#endif + } cl_uint16; -typedef union -{ - cl_uint CL_ALIGNED(16) s[4]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_uint x, y, z, w; }; - __extension__ struct{ cl_uint s0, s1, s2, s3; }; - __extension__ struct{ cl_uint2 lo, hi; }; + /* ---- cl_longn ---- */ + typedef union { + cl_long CL_ALIGNED(16) s[2]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_long x, y; + }; + __extension__ struct + { + cl_long s0, s1; + }; + __extension__ struct + { + cl_long lo, hi; + }; #endif -#if defined( __CL_UINT2__) - __cl_uint2 v2[2]; +#if defined(__CL_LONG2__) + __cl_long2 v2; #endif -#if defined( __CL_UINT4__) - __cl_uint4 v4; -#endif -}cl_uint4; + } cl_long2; -/* cl_uint3 is identical in size, alignment and behavior to cl_uint4. See section 6.1.5. */ -typedef cl_uint4 cl_uint3; + typedef union { + cl_long CL_ALIGNED(32) s[4]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_long x, y, z, w; + }; + __extension__ struct + { + cl_long s0, s1, s2, s3; + }; + __extension__ struct + { + cl_long2 lo, hi; + }; +#endif +#if defined(__CL_LONG2__) + __cl_long2 v2[2]; +#endif +#if defined(__CL_LONG4__) + __cl_long4 v4; +#endif + } cl_long4; -typedef union -{ - cl_uint CL_ALIGNED(32) s[8]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_uint x, y, z, w; }; - __extension__ struct{ cl_uint s0, s1, s2, s3, s4, s5, s6, s7; }; - __extension__ struct{ cl_uint4 lo, hi; }; -#endif -#if defined( __CL_UINT2__) - __cl_uint2 v2[4]; -#endif -#if defined( __CL_UINT4__) - __cl_uint4 v4[2]; -#endif -#if defined( __CL_UINT8__ ) - __cl_uint8 v8; -#endif -}cl_uint8; + /* cl_long3 is identical in size, alignment and behavior to cl_long4. See section 6.1.5. */ + typedef cl_long4 cl_long3; -typedef union -{ - cl_uint CL_ALIGNED(64) s[16]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_uint x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; - __extension__ struct{ cl_uint s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; - __extension__ struct{ cl_uint8 lo, hi; }; + typedef union { + cl_long CL_ALIGNED(64) s[8]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_long x, y, z, w; + }; + __extension__ struct + { + cl_long s0, s1, s2, s3, s4, s5, s6, s7; + }; + __extension__ struct + { + cl_long4 lo, hi; + }; #endif -#if defined( __CL_UINT2__) - __cl_uint2 v2[8]; +#if defined(__CL_LONG2__) + __cl_long2 v2[4]; #endif -#if defined( __CL_UINT4__) - __cl_uint4 v4[4]; +#if defined(__CL_LONG4__) + __cl_long4 v4[2]; #endif -#if defined( __CL_UINT8__ ) - __cl_uint8 v8[2]; +#if defined(__CL_LONG8__) + __cl_long8 v8; #endif -#if defined( __CL_UINT16__ ) - __cl_uint16 v16; -#endif -}cl_uint16; + } cl_long8; -/* ---- cl_longn ---- */ -typedef union -{ - cl_long CL_ALIGNED(16) s[2]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_long x, y; }; - __extension__ struct{ cl_long s0, s1; }; - __extension__ struct{ cl_long lo, hi; }; + typedef union { + cl_long CL_ALIGNED(128) s[16]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_long x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; + }; + __extension__ struct + { + cl_long s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; + }; + __extension__ struct + { + cl_long8 lo, hi; + }; #endif -#if defined( __CL_LONG2__) - __cl_long2 v2; +#if defined(__CL_LONG2__) + __cl_long2 v2[8]; #endif -}cl_long2; +#if defined(__CL_LONG4__) + __cl_long4 v4[4]; +#endif +#if defined(__CL_LONG8__) + __cl_long8 v8[2]; +#endif +#if defined(__CL_LONG16__) + __cl_long16 v16; +#endif + } cl_long16; -typedef union -{ - cl_long CL_ALIGNED(32) s[4]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_long x, y, z, w; }; - __extension__ struct{ cl_long s0, s1, s2, s3; }; - __extension__ struct{ cl_long2 lo, hi; }; + /* ---- cl_ulongn ---- */ + typedef union { + cl_ulong CL_ALIGNED(16) s[2]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_ulong x, y; + }; + __extension__ struct + { + cl_ulong s0, s1; + }; + __extension__ struct + { + cl_ulong lo, hi; + }; #endif -#if defined( __CL_LONG2__) - __cl_long2 v2[2]; +#if defined(__CL_ULONG2__) + __cl_ulong2 v2; #endif -#if defined( __CL_LONG4__) - __cl_long4 v4; -#endif -}cl_long4; + } cl_ulong2; -/* cl_long3 is identical in size, alignment and behavior to cl_long4. See section 6.1.5. */ -typedef cl_long4 cl_long3; + typedef union { + cl_ulong CL_ALIGNED(32) s[4]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_ulong x, y, z, w; + }; + __extension__ struct + { + cl_ulong s0, s1, s2, s3; + }; + __extension__ struct + { + cl_ulong2 lo, hi; + }; +#endif +#if defined(__CL_ULONG2__) + __cl_ulong2 v2[2]; +#endif +#if defined(__CL_ULONG4__) + __cl_ulong4 v4; +#endif + } cl_ulong4; -typedef union -{ - cl_long CL_ALIGNED(64) s[8]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_long x, y, z, w; }; - __extension__ struct{ cl_long s0, s1, s2, s3, s4, s5, s6, s7; }; - __extension__ struct{ cl_long4 lo, hi; }; -#endif -#if defined( __CL_LONG2__) - __cl_long2 v2[4]; -#endif -#if defined( __CL_LONG4__) - __cl_long4 v4[2]; -#endif -#if defined( __CL_LONG8__ ) - __cl_long8 v8; -#endif -}cl_long8; + /* cl_ulong3 is identical in size, alignment and behavior to cl_ulong4. See section 6.1.5. */ + typedef cl_ulong4 cl_ulong3; -typedef union -{ - cl_long CL_ALIGNED(128) s[16]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_long x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; - __extension__ struct{ cl_long s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; - __extension__ struct{ cl_long8 lo, hi; }; + typedef union { + cl_ulong CL_ALIGNED(64) s[8]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_ulong x, y, z, w; + }; + __extension__ struct + { + cl_ulong s0, s1, s2, s3, s4, s5, s6, s7; + }; + __extension__ struct + { + cl_ulong4 lo, hi; + }; #endif -#if defined( __CL_LONG2__) - __cl_long2 v2[8]; +#if defined(__CL_ULONG2__) + __cl_ulong2 v2[4]; #endif -#if defined( __CL_LONG4__) - __cl_long4 v4[4]; +#if defined(__CL_ULONG4__) + __cl_ulong4 v4[2]; #endif -#if defined( __CL_LONG8__ ) - __cl_long8 v8[2]; +#if defined(__CL_ULONG8__) + __cl_ulong8 v8; #endif -#if defined( __CL_LONG16__ ) - __cl_long16 v16; -#endif -}cl_long16; + } cl_ulong8; + typedef union { + cl_ulong CL_ALIGNED(128) s[16]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_ulong x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; + }; + __extension__ struct + { + cl_ulong s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; + }; + __extension__ struct + { + cl_ulong8 lo, hi; + }; +#endif +#if defined(__CL_ULONG2__) + __cl_ulong2 v2[8]; +#endif +#if defined(__CL_ULONG4__) + __cl_ulong4 v4[4]; +#endif +#if defined(__CL_ULONG8__) + __cl_ulong8 v8[2]; +#endif +#if defined(__CL_ULONG16__) + __cl_ulong16 v16; +#endif + } cl_ulong16; -/* ---- cl_ulongn ---- */ -typedef union -{ - cl_ulong CL_ALIGNED(16) s[2]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_ulong x, y; }; - __extension__ struct{ cl_ulong s0, s1; }; - __extension__ struct{ cl_ulong lo, hi; }; -#endif -#if defined( __CL_ULONG2__) - __cl_ulong2 v2; -#endif -}cl_ulong2; + /* --- cl_floatn ---- */ -typedef union -{ - cl_ulong CL_ALIGNED(32) s[4]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_ulong x, y, z, w; }; - __extension__ struct{ cl_ulong s0, s1, s2, s3; }; - __extension__ struct{ cl_ulong2 lo, hi; }; + typedef union { + cl_float CL_ALIGNED(8) s[2]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_float x, y; + }; + __extension__ struct + { + cl_float s0, s1; + }; + __extension__ struct + { + cl_float lo, hi; + }; #endif -#if defined( __CL_ULONG2__) - __cl_ulong2 v2[2]; +#if defined(__CL_FLOAT2__) + __cl_float2 v2; #endif -#if defined( __CL_ULONG4__) - __cl_ulong4 v4; -#endif -}cl_ulong4; + } cl_float2; -/* cl_ulong3 is identical in size, alignment and behavior to cl_ulong4. See section 6.1.5. */ -typedef cl_ulong4 cl_ulong3; + typedef union { + cl_float CL_ALIGNED(16) s[4]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_float x, y, z, w; + }; + __extension__ struct + { + cl_float s0, s1, s2, s3; + }; + __extension__ struct + { + cl_float2 lo, hi; + }; +#endif +#if defined(__CL_FLOAT2__) + __cl_float2 v2[2]; +#endif +#if defined(__CL_FLOAT4__) + __cl_float4 v4; +#endif + } cl_float4; -typedef union -{ - cl_ulong CL_ALIGNED(64) s[8]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_ulong x, y, z, w; }; - __extension__ struct{ cl_ulong s0, s1, s2, s3, s4, s5, s6, s7; }; - __extension__ struct{ cl_ulong4 lo, hi; }; -#endif -#if defined( __CL_ULONG2__) - __cl_ulong2 v2[4]; -#endif -#if defined( __CL_ULONG4__) - __cl_ulong4 v4[2]; -#endif -#if defined( __CL_ULONG8__ ) - __cl_ulong8 v8; -#endif -}cl_ulong8; + /* cl_float3 is identical in size, alignment and behavior to cl_float4. See section 6.1.5. */ + typedef cl_float4 cl_float3; -typedef union -{ - cl_ulong CL_ALIGNED(128) s[16]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_ulong x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; - __extension__ struct{ cl_ulong s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; - __extension__ struct{ cl_ulong8 lo, hi; }; + typedef union { + cl_float CL_ALIGNED(32) s[8]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_float x, y, z, w; + }; + __extension__ struct + { + cl_float s0, s1, s2, s3, s4, s5, s6, s7; + }; + __extension__ struct + { + cl_float4 lo, hi; + }; #endif -#if defined( __CL_ULONG2__) - __cl_ulong2 v2[8]; +#if defined(__CL_FLOAT2__) + __cl_float2 v2[4]; #endif -#if defined( __CL_ULONG4__) - __cl_ulong4 v4[4]; +#if defined(__CL_FLOAT4__) + __cl_float4 v4[2]; #endif -#if defined( __CL_ULONG8__ ) - __cl_ulong8 v8[2]; +#if defined(__CL_FLOAT8__) + __cl_float8 v8; #endif -#if defined( __CL_ULONG16__ ) - __cl_ulong16 v16; -#endif -}cl_ulong16; + } cl_float8; + typedef union { + cl_float CL_ALIGNED(64) s[16]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_float x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; + }; + __extension__ struct + { + cl_float s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; + }; + __extension__ struct + { + cl_float8 lo, hi; + }; +#endif +#if defined(__CL_FLOAT2__) + __cl_float2 v2[8]; +#endif +#if defined(__CL_FLOAT4__) + __cl_float4 v4[4]; +#endif +#if defined(__CL_FLOAT8__) + __cl_float8 v8[2]; +#endif +#if defined(__CL_FLOAT16__) + __cl_float16 v16; +#endif + } cl_float16; -/* --- cl_floatn ---- */ + /* --- cl_doublen ---- */ -typedef union -{ - cl_float CL_ALIGNED(8) s[2]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_float x, y; }; - __extension__ struct{ cl_float s0, s1; }; - __extension__ struct{ cl_float lo, hi; }; + typedef union { + cl_double CL_ALIGNED(16) s[2]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_double x, y; + }; + __extension__ struct + { + cl_double s0, s1; + }; + __extension__ struct + { + cl_double lo, hi; + }; #endif -#if defined( __CL_FLOAT2__) - __cl_float2 v2; +#if defined(__CL_DOUBLE2__) + __cl_double2 v2; #endif -}cl_float2; + } cl_double2; -typedef union -{ - cl_float CL_ALIGNED(16) s[4]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_float x, y, z, w; }; - __extension__ struct{ cl_float s0, s1, s2, s3; }; - __extension__ struct{ cl_float2 lo, hi; }; + typedef union { + cl_double CL_ALIGNED(32) s[4]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_double x, y, z, w; + }; + __extension__ struct + { + cl_double s0, s1, s2, s3; + }; + __extension__ struct + { + cl_double2 lo, hi; + }; #endif -#if defined( __CL_FLOAT2__) - __cl_float2 v2[2]; +#if defined(__CL_DOUBLE2__) + __cl_double2 v2[2]; #endif -#if defined( __CL_FLOAT4__) - __cl_float4 v4; +#if defined(__CL_DOUBLE4__) + __cl_double4 v4; #endif -}cl_float4; + } cl_double4; -/* cl_float3 is identical in size, alignment and behavior to cl_float4. See section 6.1.5. */ -typedef cl_float4 cl_float3; + /* cl_double3 is identical in size, alignment and behavior to cl_double4. See section 6.1.5. */ + typedef cl_double4 cl_double3; -typedef union -{ - cl_float CL_ALIGNED(32) s[8]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_float x, y, z, w; }; - __extension__ struct{ cl_float s0, s1, s2, s3, s4, s5, s6, s7; }; - __extension__ struct{ cl_float4 lo, hi; }; + typedef union { + cl_double CL_ALIGNED(64) s[8]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_double x, y, z, w; + }; + __extension__ struct + { + cl_double s0, s1, s2, s3, s4, s5, s6, s7; + }; + __extension__ struct + { + cl_double4 lo, hi; + }; #endif -#if defined( __CL_FLOAT2__) - __cl_float2 v2[4]; +#if defined(__CL_DOUBLE2__) + __cl_double2 v2[4]; #endif -#if defined( __CL_FLOAT4__) - __cl_float4 v4[2]; +#if defined(__CL_DOUBLE4__) + __cl_double4 v4[2]; #endif -#if defined( __CL_FLOAT8__ ) - __cl_float8 v8; +#if defined(__CL_DOUBLE8__) + __cl_double8 v8; #endif -}cl_float8; + } cl_double8; -typedef union -{ - cl_float CL_ALIGNED(64) s[16]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_float x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; - __extension__ struct{ cl_float s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; - __extension__ struct{ cl_float8 lo, hi; }; + typedef union { + cl_double CL_ALIGNED(128) s[16]; +#if defined(CL_NAMED_STRUCT_SUPPORTED) + __extension__ struct + { + cl_double x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; + }; + __extension__ struct + { + cl_double s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; + }; + __extension__ struct + { + cl_double8 lo, hi; + }; #endif -#if defined( __CL_FLOAT2__) - __cl_float2 v2[8]; +#if defined(__CL_DOUBLE2__) + __cl_double2 v2[8]; #endif -#if defined( __CL_FLOAT4__) - __cl_float4 v4[4]; +#if defined(__CL_DOUBLE4__) + __cl_double4 v4[4]; #endif -#if defined( __CL_FLOAT8__ ) - __cl_float8 v8[2]; +#if defined(__CL_DOUBLE8__) + __cl_double8 v8[2]; #endif -#if defined( __CL_FLOAT16__ ) - __cl_float16 v16; +#if defined(__CL_DOUBLE16__) + __cl_double16 v16; #endif -}cl_float16; - -/* --- cl_doublen ---- */ - -typedef union -{ - cl_double CL_ALIGNED(16) s[2]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_double x, y; }; - __extension__ struct{ cl_double s0, s1; }; - __extension__ struct{ cl_double lo, hi; }; -#endif -#if defined( __CL_DOUBLE2__) - __cl_double2 v2; -#endif -}cl_double2; - -typedef union -{ - cl_double CL_ALIGNED(32) s[4]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_double x, y, z, w; }; - __extension__ struct{ cl_double s0, s1, s2, s3; }; - __extension__ struct{ cl_double2 lo, hi; }; -#endif -#if defined( __CL_DOUBLE2__) - __cl_double2 v2[2]; -#endif -#if defined( __CL_DOUBLE4__) - __cl_double4 v4; -#endif -}cl_double4; - -/* cl_double3 is identical in size, alignment and behavior to cl_double4. See section 6.1.5. */ -typedef cl_double4 cl_double3; - -typedef union -{ - cl_double CL_ALIGNED(64) s[8]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_double x, y, z, w; }; - __extension__ struct{ cl_double s0, s1, s2, s3, s4, s5, s6, s7; }; - __extension__ struct{ cl_double4 lo, hi; }; -#endif -#if defined( __CL_DOUBLE2__) - __cl_double2 v2[4]; -#endif -#if defined( __CL_DOUBLE4__) - __cl_double4 v4[2]; -#endif -#if defined( __CL_DOUBLE8__ ) - __cl_double8 v8; -#endif -}cl_double8; - -typedef union -{ - cl_double CL_ALIGNED(128) s[16]; -#if defined( CL_NAMED_STRUCT_SUPPORTED ) - __extension__ struct{ cl_double x, y, z, w, __spacer4, __spacer5, __spacer6, __spacer7, __spacer8, __spacer9, sa, sb, sc, sd, se, sf; }; - __extension__ struct{ cl_double s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, sA, sB, sC, sD, sE, sF; }; - __extension__ struct{ cl_double8 lo, hi; }; -#endif -#if defined( __CL_DOUBLE2__) - __cl_double2 v2[8]; -#endif -#if defined( __CL_DOUBLE4__) - __cl_double4 v4[4]; -#endif -#if defined( __CL_DOUBLE8__ ) - __cl_double8 v8[2]; -#endif -#if defined( __CL_DOUBLE16__ ) - __cl_double16 v16; -#endif -}cl_double16; + } cl_double16; /* Macro to facilitate debugging * Usage: @@ -1237,967 +1551,967 @@ typedef union * This should correctly set up the line, (column) and file information for your source * string so you can do source level debugging. */ -#define __CL_STRINGIFY( _x ) # _x -#define _CL_STRINGIFY( _x ) __CL_STRINGIFY( _x ) -#define CL_PROGRAM_STRING_DEBUG_INFO "#line " _CL_STRINGIFY(__LINE__) " \"" __FILE__ "\" \n\n" +#define __CL_STRINGIFY(_x) #_x +#define _CL_STRINGIFY(_x) __CL_STRINGIFY(_x) +#define CL_PROGRAM_STRING_DEBUG_INFO "#line " _CL_STRINGIFY(__LINE__) " \"" __FILE__ "\" \n\n" -// CL.h contents -/******************************************************************************/ + // CL.h contents + /******************************************************************************/ -typedef struct _cl_platform_id * cl_platform_id; -typedef struct _cl_device_id * cl_device_id; -typedef struct _cl_context * cl_context; -typedef struct _cl_command_queue * cl_command_queue; -typedef struct _cl_mem * cl_mem; -typedef struct _cl_program * cl_program; -typedef struct _cl_kernel * cl_kernel; -typedef struct _cl_event * cl_event; -typedef struct _cl_sampler * cl_sampler; + typedef struct _cl_platform_id *cl_platform_id; + typedef struct _cl_device_id *cl_device_id; + typedef struct _cl_context *cl_context; + typedef struct _cl_command_queue *cl_command_queue; + typedef struct _cl_mem *cl_mem; + typedef struct _cl_program *cl_program; + typedef struct _cl_kernel *cl_kernel; + typedef struct _cl_event *cl_event; + typedef struct _cl_sampler *cl_sampler; -typedef cl_uint cl_bool; /* WARNING! Unlike cl_ types in cl_platform.h, cl_bool is not guaranteed to be the same size as the bool in kernels. */ -typedef cl_ulong cl_bitfield; -typedef cl_bitfield cl_device_type; -typedef cl_uint cl_platform_info; -typedef cl_uint cl_device_info; -typedef cl_bitfield cl_device_fp_config; -typedef cl_uint cl_device_mem_cache_type; -typedef cl_uint cl_device_local_mem_type; -typedef cl_bitfield cl_device_exec_capabilities; -typedef cl_bitfield cl_command_queue_properties; + typedef cl_uint cl_bool; /* WARNING! Unlike cl_ types in cl_platform.h, cl_bool is not guaranteed to be the same size as the bool in kernels. */ + typedef cl_ulong cl_bitfield; + typedef cl_bitfield cl_device_type; + typedef cl_uint cl_platform_info; + typedef cl_uint cl_device_info; + typedef cl_bitfield cl_device_fp_config; + typedef cl_uint cl_device_mem_cache_type; + typedef cl_uint cl_device_local_mem_type; + typedef cl_bitfield cl_device_exec_capabilities; + typedef cl_bitfield cl_command_queue_properties; -typedef intptr_t cl_context_properties; -typedef cl_uint cl_context_info; -typedef cl_uint cl_command_queue_info; -typedef cl_uint cl_channel_order; -typedef cl_uint cl_channel_type; -typedef cl_bitfield cl_mem_flags; -typedef cl_uint cl_mem_object_type; -typedef cl_uint cl_mem_info; -typedef cl_uint cl_image_info; -typedef cl_uint cl_buffer_create_type; -typedef cl_uint cl_addressing_mode; -typedef cl_uint cl_filter_mode; -typedef cl_uint cl_sampler_info; -typedef cl_bitfield cl_map_flags; -typedef cl_uint cl_program_info; -typedef cl_uint cl_program_build_info; -typedef cl_int cl_build_status; -typedef cl_uint cl_kernel_info; -typedef cl_uint cl_kernel_work_group_info; -typedef cl_uint cl_event_info; -typedef cl_uint cl_command_type; -typedef cl_uint cl_profiling_info; + typedef intptr_t cl_context_properties; + typedef cl_uint cl_context_info; + typedef cl_uint cl_command_queue_info; + typedef cl_uint cl_channel_order; + typedef cl_uint cl_channel_type; + typedef cl_bitfield cl_mem_flags; + typedef cl_uint cl_mem_object_type; + typedef cl_uint cl_mem_info; + typedef cl_uint cl_image_info; + typedef cl_uint cl_buffer_create_type; + typedef cl_uint cl_addressing_mode; + typedef cl_uint cl_filter_mode; + typedef cl_uint cl_sampler_info; + typedef cl_bitfield cl_map_flags; + typedef cl_uint cl_program_info; + typedef cl_uint cl_program_build_info; + typedef cl_int cl_build_status; + typedef cl_uint cl_kernel_info; + typedef cl_uint cl_kernel_work_group_info; + typedef cl_uint cl_event_info; + typedef cl_uint cl_command_type; + typedef cl_uint cl_profiling_info; -typedef struct _cl_image_format { - cl_channel_order image_channel_order; - cl_channel_type image_channel_data_type; -} cl_image_format; + typedef struct _cl_image_format + { + cl_channel_order image_channel_order; + cl_channel_type image_channel_data_type; + } cl_image_format; - -typedef struct _cl_buffer_region { - size_t origin; - size_t size; -} cl_buffer_region; + typedef struct _cl_buffer_region + { + size_t origin; + size_t size; + } cl_buffer_region; /******************************************************************************/ /* Error Codes */ -#define CL_SUCCESS 0 -#define CL_DEVICE_NOT_FOUND -1 -#define CL_DEVICE_NOT_AVAILABLE -2 -#define CL_COMPILER_NOT_AVAILABLE -3 -#define CL_MEM_OBJECT_ALLOCATION_FAILURE -4 -#define CL_OUT_OF_RESOURCES -5 -#define CL_OUT_OF_HOST_MEMORY -6 -#define CL_PROFILING_INFO_NOT_AVAILABLE -7 -#define CL_MEM_COPY_OVERLAP -8 -#define CL_IMAGE_FORMAT_MISMATCH -9 -#define CL_IMAGE_FORMAT_NOT_SUPPORTED -10 -#define CL_BUILD_PROGRAM_FAILURE -11 -#define CL_MAP_FAILURE -12 -#define CL_MISALIGNED_SUB_BUFFER_OFFSET -13 +#define CL_SUCCESS 0 +#define CL_DEVICE_NOT_FOUND -1 +#define CL_DEVICE_NOT_AVAILABLE -2 +#define CL_COMPILER_NOT_AVAILABLE -3 +#define CL_MEM_OBJECT_ALLOCATION_FAILURE -4 +#define CL_OUT_OF_RESOURCES -5 +#define CL_OUT_OF_HOST_MEMORY -6 +#define CL_PROFILING_INFO_NOT_AVAILABLE -7 +#define CL_MEM_COPY_OVERLAP -8 +#define CL_IMAGE_FORMAT_MISMATCH -9 +#define CL_IMAGE_FORMAT_NOT_SUPPORTED -10 +#define CL_BUILD_PROGRAM_FAILURE -11 +#define CL_MAP_FAILURE -12 +#define CL_MISALIGNED_SUB_BUFFER_OFFSET -13 #define CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST -14 -#define CL_INVALID_VALUE -30 -#define CL_INVALID_DEVICE_TYPE -31 -#define CL_INVALID_PLATFORM -32 -#define CL_INVALID_DEVICE -33 -#define CL_INVALID_CONTEXT -34 -#define CL_INVALID_QUEUE_PROPERTIES -35 -#define CL_INVALID_COMMAND_QUEUE -36 -#define CL_INVALID_HOST_PTR -37 -#define CL_INVALID_MEM_OBJECT -38 -#define CL_INVALID_IMAGE_FORMAT_DESCRIPTOR -39 -#define CL_INVALID_IMAGE_SIZE -40 -#define CL_INVALID_SAMPLER -41 -#define CL_INVALID_BINARY -42 -#define CL_INVALID_BUILD_OPTIONS -43 -#define CL_INVALID_PROGRAM -44 -#define CL_INVALID_PROGRAM_EXECUTABLE -45 -#define CL_INVALID_KERNEL_NAME -46 -#define CL_INVALID_KERNEL_DEFINITION -47 -#define CL_INVALID_KERNEL -48 -#define CL_INVALID_ARG_INDEX -49 -#define CL_INVALID_ARG_VALUE -50 -#define CL_INVALID_ARG_SIZE -51 -#define CL_INVALID_KERNEL_ARGS -52 -#define CL_INVALID_WORK_DIMENSION -53 -#define CL_INVALID_WORK_GROUP_SIZE -54 -#define CL_INVALID_WORK_ITEM_SIZE -55 -#define CL_INVALID_GLOBAL_OFFSET -56 -#define CL_INVALID_EVENT_WAIT_LIST -57 -#define CL_INVALID_EVENT -58 -#define CL_INVALID_OPERATION -59 -#define CL_INVALID_GL_OBJECT -60 -#define CL_INVALID_BUFFER_SIZE -61 -#define CL_INVALID_MIP_LEVEL -62 -#define CL_INVALID_GLOBAL_WORK_SIZE -63 -#define CL_INVALID_PROPERTY -64 +#define CL_INVALID_VALUE -30 +#define CL_INVALID_DEVICE_TYPE -31 +#define CL_INVALID_PLATFORM -32 +#define CL_INVALID_DEVICE -33 +#define CL_INVALID_CONTEXT -34 +#define CL_INVALID_QUEUE_PROPERTIES -35 +#define CL_INVALID_COMMAND_QUEUE -36 +#define CL_INVALID_HOST_PTR -37 +#define CL_INVALID_MEM_OBJECT -38 +#define CL_INVALID_IMAGE_FORMAT_DESCRIPTOR -39 +#define CL_INVALID_IMAGE_SIZE -40 +#define CL_INVALID_SAMPLER -41 +#define CL_INVALID_BINARY -42 +#define CL_INVALID_BUILD_OPTIONS -43 +#define CL_INVALID_PROGRAM -44 +#define CL_INVALID_PROGRAM_EXECUTABLE -45 +#define CL_INVALID_KERNEL_NAME -46 +#define CL_INVALID_KERNEL_DEFINITION -47 +#define CL_INVALID_KERNEL -48 +#define CL_INVALID_ARG_INDEX -49 +#define CL_INVALID_ARG_VALUE -50 +#define CL_INVALID_ARG_SIZE -51 +#define CL_INVALID_KERNEL_ARGS -52 +#define CL_INVALID_WORK_DIMENSION -53 +#define CL_INVALID_WORK_GROUP_SIZE -54 +#define CL_INVALID_WORK_ITEM_SIZE -55 +#define CL_INVALID_GLOBAL_OFFSET -56 +#define CL_INVALID_EVENT_WAIT_LIST -57 +#define CL_INVALID_EVENT -58 +#define CL_INVALID_OPERATION -59 +#define CL_INVALID_GL_OBJECT -60 +#define CL_INVALID_BUFFER_SIZE -61 +#define CL_INVALID_MIP_LEVEL -62 +#define CL_INVALID_GLOBAL_WORK_SIZE -63 +#define CL_INVALID_PROPERTY -64 /* OpenCL Version */ -#define CL_VERSION_1_0 1 -#define CL_VERSION_1_1 1 +#define CL_VERSION_1_0 1 +#define CL_VERSION_1_1 1 /* cl_bool */ -#define CL_FALSE 0 -#define CL_TRUE 1 +#define CL_FALSE 0 +#define CL_TRUE 1 /* cl_platform_info */ -#define CL_PLATFORM_PROFILE 0x0900 -#define CL_PLATFORM_VERSION 0x0901 -#define CL_PLATFORM_NAME 0x0902 -#define CL_PLATFORM_VENDOR 0x0903 -#define CL_PLATFORM_EXTENSIONS 0x0904 +#define CL_PLATFORM_PROFILE 0x0900 +#define CL_PLATFORM_VERSION 0x0901 +#define CL_PLATFORM_NAME 0x0902 +#define CL_PLATFORM_VENDOR 0x0903 +#define CL_PLATFORM_EXTENSIONS 0x0904 /* cl_device_type - bitfield */ -#define CL_DEVICE_TYPE_DEFAULT (1 << 0) -#define CL_DEVICE_TYPE_CPU (1 << 1) -#define CL_DEVICE_TYPE_GPU (1 << 2) -#define CL_DEVICE_TYPE_ACCELERATOR (1 << 3) -#define CL_DEVICE_TYPE_ALL 0xFFFFFFFF +#define CL_DEVICE_TYPE_DEFAULT (1 << 0) +#define CL_DEVICE_TYPE_CPU (1 << 1) +#define CL_DEVICE_TYPE_GPU (1 << 2) +#define CL_DEVICE_TYPE_ACCELERATOR (1 << 3) +#define CL_DEVICE_TYPE_ALL 0xFFFFFFFF /* cl_device_info */ -#define CL_DEVICE_TYPE 0x1000 -#define CL_DEVICE_VENDOR_ID 0x1001 -#define CL_DEVICE_MAX_COMPUTE_UNITS 0x1002 -#define CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS 0x1003 -#define CL_DEVICE_MAX_WORK_GROUP_SIZE 0x1004 -#define CL_DEVICE_MAX_WORK_ITEM_SIZES 0x1005 -#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR 0x1006 -#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT 0x1007 -#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT 0x1008 -#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG 0x1009 -#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT 0x100A -#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE 0x100B -#define CL_DEVICE_MAX_CLOCK_FREQUENCY 0x100C -#define CL_DEVICE_ADDRESS_BITS 0x100D -#define CL_DEVICE_MAX_READ_IMAGE_ARGS 0x100E -#define CL_DEVICE_MAX_WRITE_IMAGE_ARGS 0x100F -#define CL_DEVICE_MAX_MEM_ALLOC_SIZE 0x1010 -#define CL_DEVICE_IMAGE2D_MAX_WIDTH 0x1011 -#define CL_DEVICE_IMAGE2D_MAX_HEIGHT 0x1012 -#define CL_DEVICE_IMAGE3D_MAX_WIDTH 0x1013 -#define CL_DEVICE_IMAGE3D_MAX_HEIGHT 0x1014 -#define CL_DEVICE_IMAGE3D_MAX_DEPTH 0x1015 -#define CL_DEVICE_IMAGE_SUPPORT 0x1016 -#define CL_DEVICE_MAX_PARAMETER_SIZE 0x1017 -#define CL_DEVICE_MAX_SAMPLERS 0x1018 -#define CL_DEVICE_MEM_BASE_ADDR_ALIGN 0x1019 -#define CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE 0x101A -#define CL_DEVICE_SINGLE_FP_CONFIG 0x101B -#define CL_DEVICE_GLOBAL_MEM_CACHE_TYPE 0x101C -#define CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE 0x101D -#define CL_DEVICE_GLOBAL_MEM_CACHE_SIZE 0x101E -#define CL_DEVICE_GLOBAL_MEM_SIZE 0x101F -#define CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE 0x1020 -#define CL_DEVICE_MAX_CONSTANT_ARGS 0x1021 -#define CL_DEVICE_LOCAL_MEM_TYPE 0x1022 -#define CL_DEVICE_LOCAL_MEM_SIZE 0x1023 -#define CL_DEVICE_ERROR_CORRECTION_SUPPORT 0x1024 -#define CL_DEVICE_PROFILING_TIMER_RESOLUTION 0x1025 -#define CL_DEVICE_ENDIAN_LITTLE 0x1026 -#define CL_DEVICE_AVAILABLE 0x1027 -#define CL_DEVICE_COMPILER_AVAILABLE 0x1028 -#define CL_DEVICE_EXECUTION_CAPABILITIES 0x1029 -#define CL_DEVICE_QUEUE_PROPERTIES 0x102A -#define CL_DEVICE_NAME 0x102B -#define CL_DEVICE_VENDOR 0x102C -#define CL_DRIVER_VERSION 0x102D -#define CL_DEVICE_PROFILE 0x102E -#define CL_DEVICE_VERSION 0x102F -#define CL_DEVICE_EXTENSIONS 0x1030 -#define CL_DEVICE_PLATFORM 0x1031 +#define CL_DEVICE_TYPE 0x1000 +#define CL_DEVICE_VENDOR_ID 0x1001 +#define CL_DEVICE_MAX_COMPUTE_UNITS 0x1002 +#define CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS 0x1003 +#define CL_DEVICE_MAX_WORK_GROUP_SIZE 0x1004 +#define CL_DEVICE_MAX_WORK_ITEM_SIZES 0x1005 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR 0x1006 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT 0x1007 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT 0x1008 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG 0x1009 +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT 0x100A +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE 0x100B +#define CL_DEVICE_MAX_CLOCK_FREQUENCY 0x100C +#define CL_DEVICE_ADDRESS_BITS 0x100D +#define CL_DEVICE_MAX_READ_IMAGE_ARGS 0x100E +#define CL_DEVICE_MAX_WRITE_IMAGE_ARGS 0x100F +#define CL_DEVICE_MAX_MEM_ALLOC_SIZE 0x1010 +#define CL_DEVICE_IMAGE2D_MAX_WIDTH 0x1011 +#define CL_DEVICE_IMAGE2D_MAX_HEIGHT 0x1012 +#define CL_DEVICE_IMAGE3D_MAX_WIDTH 0x1013 +#define CL_DEVICE_IMAGE3D_MAX_HEIGHT 0x1014 +#define CL_DEVICE_IMAGE3D_MAX_DEPTH 0x1015 +#define CL_DEVICE_IMAGE_SUPPORT 0x1016 +#define CL_DEVICE_MAX_PARAMETER_SIZE 0x1017 +#define CL_DEVICE_MAX_SAMPLERS 0x1018 +#define CL_DEVICE_MEM_BASE_ADDR_ALIGN 0x1019 +#define CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE 0x101A +#define CL_DEVICE_SINGLE_FP_CONFIG 0x101B +#define CL_DEVICE_GLOBAL_MEM_CACHE_TYPE 0x101C +#define CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE 0x101D +#define CL_DEVICE_GLOBAL_MEM_CACHE_SIZE 0x101E +#define CL_DEVICE_GLOBAL_MEM_SIZE 0x101F +#define CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE 0x1020 +#define CL_DEVICE_MAX_CONSTANT_ARGS 0x1021 +#define CL_DEVICE_LOCAL_MEM_TYPE 0x1022 +#define CL_DEVICE_LOCAL_MEM_SIZE 0x1023 +#define CL_DEVICE_ERROR_CORRECTION_SUPPORT 0x1024 +#define CL_DEVICE_PROFILING_TIMER_RESOLUTION 0x1025 +#define CL_DEVICE_ENDIAN_LITTLE 0x1026 +#define CL_DEVICE_AVAILABLE 0x1027 +#define CL_DEVICE_COMPILER_AVAILABLE 0x1028 +#define CL_DEVICE_EXECUTION_CAPABILITIES 0x1029 +#define CL_DEVICE_QUEUE_PROPERTIES 0x102A +#define CL_DEVICE_NAME 0x102B +#define CL_DEVICE_VENDOR 0x102C +#define CL_DRIVER_VERSION 0x102D +#define CL_DEVICE_PROFILE 0x102E +#define CL_DEVICE_VERSION 0x102F +#define CL_DEVICE_EXTENSIONS 0x1030 +#define CL_DEVICE_PLATFORM 0x1031 /* 0x1032 reserved for CL_DEVICE_DOUBLE_FP_CONFIG */ /* 0x1033 reserved for CL_DEVICE_HALF_FP_CONFIG */ -#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF 0x1034 -#define CL_DEVICE_HOST_UNIFIED_MEMORY 0x1035 -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR 0x1036 -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT 0x1037 -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_INT 0x1038 -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG 0x1039 -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT 0x103A -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE 0x103B -#define CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF 0x103C -#define CL_DEVICE_OPENCL_C_VERSION 0x103D +#define CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF 0x1034 +#define CL_DEVICE_HOST_UNIFIED_MEMORY 0x1035 +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR 0x1036 +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT 0x1037 +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_INT 0x1038 +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG 0x1039 +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT 0x103A +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE 0x103B +#define CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF 0x103C +#define CL_DEVICE_OPENCL_C_VERSION 0x103D /* cl_device_fp_config - bitfield */ -#define CL_FP_DENORM (1 << 0) -#define CL_FP_INF_NAN (1 << 1) -#define CL_FP_ROUND_TO_NEAREST (1 << 2) -#define CL_FP_ROUND_TO_ZERO (1 << 3) -#define CL_FP_ROUND_TO_INF (1 << 4) -#define CL_FP_FMA (1 << 5) -#define CL_FP_SOFT_FLOAT (1 << 6) +#define CL_FP_DENORM (1 << 0) +#define CL_FP_INF_NAN (1 << 1) +#define CL_FP_ROUND_TO_NEAREST (1 << 2) +#define CL_FP_ROUND_TO_ZERO (1 << 3) +#define CL_FP_ROUND_TO_INF (1 << 4) +#define CL_FP_FMA (1 << 5) +#define CL_FP_SOFT_FLOAT (1 << 6) /* cl_device_mem_cache_type */ -#define CL_NONE 0x0 -#define CL_READ_ONLY_CACHE 0x1 -#define CL_READ_WRITE_CACHE 0x2 +#define CL_NONE 0x0 +#define CL_READ_ONLY_CACHE 0x1 +#define CL_READ_WRITE_CACHE 0x2 /* cl_device_local_mem_type */ -#define CL_LOCAL 0x1 -#define CL_GLOBAL 0x2 +#define CL_LOCAL 0x1 +#define CL_GLOBAL 0x2 /* cl_device_exec_capabilities - bitfield */ -#define CL_EXEC_KERNEL (1 << 0) -#define CL_EXEC_NATIVE_KERNEL (1 << 1) +#define CL_EXEC_KERNEL (1 << 0) +#define CL_EXEC_NATIVE_KERNEL (1 << 1) /* cl_command_queue_properties - bitfield */ -#define CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE (1 << 0) -#define CL_QUEUE_PROFILING_ENABLE (1 << 1) +#define CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE (1 << 0) +#define CL_QUEUE_PROFILING_ENABLE (1 << 1) /* cl_context_info */ -#define CL_CONTEXT_REFERENCE_COUNT 0x1080 -#define CL_CONTEXT_DEVICES 0x1081 -#define CL_CONTEXT_PROPERTIES 0x1082 -#define CL_CONTEXT_NUM_DEVICES 0x1083 +#define CL_CONTEXT_REFERENCE_COUNT 0x1080 +#define CL_CONTEXT_DEVICES 0x1081 +#define CL_CONTEXT_PROPERTIES 0x1082 +#define CL_CONTEXT_NUM_DEVICES 0x1083 /* cl_context_info + cl_context_properties */ -#define CL_CONTEXT_PLATFORM 0x1084 +#define CL_CONTEXT_PLATFORM 0x1084 /* cl_command_queue_info */ -#define CL_QUEUE_CONTEXT 0x1090 -#define CL_QUEUE_DEVICE 0x1091 -#define CL_QUEUE_REFERENCE_COUNT 0x1092 -#define CL_QUEUE_PROPERTIES 0x1093 +#define CL_QUEUE_CONTEXT 0x1090 +#define CL_QUEUE_DEVICE 0x1091 +#define CL_QUEUE_REFERENCE_COUNT 0x1092 +#define CL_QUEUE_PROPERTIES 0x1093 /* cl_mem_flags - bitfield */ -#define CL_MEM_READ_WRITE (1 << 0) -#define CL_MEM_WRITE_ONLY (1 << 1) -#define CL_MEM_READ_ONLY (1 << 2) -#define CL_MEM_USE_HOST_PTR (1 << 3) -#define CL_MEM_ALLOC_HOST_PTR (1 << 4) -#define CL_MEM_COPY_HOST_PTR (1 << 5) +#define CL_MEM_READ_WRITE (1 << 0) +#define CL_MEM_WRITE_ONLY (1 << 1) +#define CL_MEM_READ_ONLY (1 << 2) +#define CL_MEM_USE_HOST_PTR (1 << 3) +#define CL_MEM_ALLOC_HOST_PTR (1 << 4) +#define CL_MEM_COPY_HOST_PTR (1 << 5) /* cl_channel_order */ -#define CL_R 0x10B0 -#define CL_A 0x10B1 -#define CL_RG 0x10B2 -#define CL_RA 0x10B3 -#define CL_RGB 0x10B4 -#define CL_RGBA 0x10B5 -#define CL_BGRA 0x10B6 -#define CL_ARGB 0x10B7 -#define CL_INTENSITY 0x10B8 -#define CL_LUMINANCE 0x10B9 -#define CL_Rx 0x10BA -#define CL_RGx 0x10BB -#define CL_RGBx 0x10BC +#define CL_R 0x10B0 +#define CL_A 0x10B1 +#define CL_RG 0x10B2 +#define CL_RA 0x10B3 +#define CL_RGB 0x10B4 +#define CL_RGBA 0x10B5 +#define CL_BGRA 0x10B6 +#define CL_ARGB 0x10B7 +#define CL_INTENSITY 0x10B8 +#define CL_LUMINANCE 0x10B9 +#define CL_Rx 0x10BA +#define CL_RGx 0x10BB +#define CL_RGBx 0x10BC /* cl_channel_type */ -#define CL_SNORM_INT8 0x10D0 -#define CL_SNORM_INT16 0x10D1 -#define CL_UNORM_INT8 0x10D2 -#define CL_UNORM_INT16 0x10D3 -#define CL_UNORM_SHORT_565 0x10D4 -#define CL_UNORM_SHORT_555 0x10D5 -#define CL_UNORM_INT_101010 0x10D6 -#define CL_SIGNED_INT8 0x10D7 -#define CL_SIGNED_INT16 0x10D8 -#define CL_SIGNED_INT32 0x10D9 -#define CL_UNSIGNED_INT8 0x10DA -#define CL_UNSIGNED_INT16 0x10DB -#define CL_UNSIGNED_INT32 0x10DC -#define CL_HALF_FLOAT 0x10DD -#define CL_FLOAT 0x10DE +#define CL_SNORM_INT8 0x10D0 +#define CL_SNORM_INT16 0x10D1 +#define CL_UNORM_INT8 0x10D2 +#define CL_UNORM_INT16 0x10D3 +#define CL_UNORM_SHORT_565 0x10D4 +#define CL_UNORM_SHORT_555 0x10D5 +#define CL_UNORM_INT_101010 0x10D6 +#define CL_SIGNED_INT8 0x10D7 +#define CL_SIGNED_INT16 0x10D8 +#define CL_SIGNED_INT32 0x10D9 +#define CL_UNSIGNED_INT8 0x10DA +#define CL_UNSIGNED_INT16 0x10DB +#define CL_UNSIGNED_INT32 0x10DC +#define CL_HALF_FLOAT 0x10DD +#define CL_FLOAT 0x10DE /* cl_mem_object_type */ -#define CL_MEM_OBJECT_BUFFER 0x10F0 -#define CL_MEM_OBJECT_IMAGE2D 0x10F1 -#define CL_MEM_OBJECT_IMAGE3D 0x10F2 +#define CL_MEM_OBJECT_BUFFER 0x10F0 +#define CL_MEM_OBJECT_IMAGE2D 0x10F1 +#define CL_MEM_OBJECT_IMAGE3D 0x10F2 /* cl_mem_info */ -#define CL_MEM_TYPE 0x1100 -#define CL_MEM_FLAGS 0x1101 -#define CL_MEM_SIZE 0x1102 -#define CL_MEM_HOST_PTR 0x1103 -#define CL_MEM_MAP_COUNT 0x1104 -#define CL_MEM_REFERENCE_COUNT 0x1105 -#define CL_MEM_CONTEXT 0x1106 -#define CL_MEM_ASSOCIATED_MEMOBJECT 0x1107 -#define CL_MEM_OFFSET 0x1108 +#define CL_MEM_TYPE 0x1100 +#define CL_MEM_FLAGS 0x1101 +#define CL_MEM_SIZE 0x1102 +#define CL_MEM_HOST_PTR 0x1103 +#define CL_MEM_MAP_COUNT 0x1104 +#define CL_MEM_REFERENCE_COUNT 0x1105 +#define CL_MEM_CONTEXT 0x1106 +#define CL_MEM_ASSOCIATED_MEMOBJECT 0x1107 +#define CL_MEM_OFFSET 0x1108 /* cl_image_info */ -#define CL_IMAGE_FORMAT 0x1110 -#define CL_IMAGE_ELEMENT_SIZE 0x1111 -#define CL_IMAGE_ROW_PITCH 0x1112 -#define CL_IMAGE_SLICE_PITCH 0x1113 -#define CL_IMAGE_WIDTH 0x1114 -#define CL_IMAGE_HEIGHT 0x1115 -#define CL_IMAGE_DEPTH 0x1116 +#define CL_IMAGE_FORMAT 0x1110 +#define CL_IMAGE_ELEMENT_SIZE 0x1111 +#define CL_IMAGE_ROW_PITCH 0x1112 +#define CL_IMAGE_SLICE_PITCH 0x1113 +#define CL_IMAGE_WIDTH 0x1114 +#define CL_IMAGE_HEIGHT 0x1115 +#define CL_IMAGE_DEPTH 0x1116 /* cl_addressing_mode */ -#define CL_ADDRESS_NONE 0x1130 -#define CL_ADDRESS_CLAMP_TO_EDGE 0x1131 -#define CL_ADDRESS_CLAMP 0x1132 -#define CL_ADDRESS_REPEAT 0x1133 -#define CL_ADDRESS_MIRRORED_REPEAT 0x1134 +#define CL_ADDRESS_NONE 0x1130 +#define CL_ADDRESS_CLAMP_TO_EDGE 0x1131 +#define CL_ADDRESS_CLAMP 0x1132 +#define CL_ADDRESS_REPEAT 0x1133 +#define CL_ADDRESS_MIRRORED_REPEAT 0x1134 /* cl_filter_mode */ -#define CL_FILTER_NEAREST 0x1140 -#define CL_FILTER_LINEAR 0x1141 +#define CL_FILTER_NEAREST 0x1140 +#define CL_FILTER_LINEAR 0x1141 /* cl_sampler_info */ -#define CL_SAMPLER_REFERENCE_COUNT 0x1150 -#define CL_SAMPLER_CONTEXT 0x1151 -#define CL_SAMPLER_NORMALIZED_COORDS 0x1152 -#define CL_SAMPLER_ADDRESSING_MODE 0x1153 -#define CL_SAMPLER_FILTER_MODE 0x1154 +#define CL_SAMPLER_REFERENCE_COUNT 0x1150 +#define CL_SAMPLER_CONTEXT 0x1151 +#define CL_SAMPLER_NORMALIZED_COORDS 0x1152 +#define CL_SAMPLER_ADDRESSING_MODE 0x1153 +#define CL_SAMPLER_FILTER_MODE 0x1154 /* cl_map_flags - bitfield */ -#define CL_MAP_READ (1 << 0) -#define CL_MAP_WRITE (1 << 1) +#define CL_MAP_READ (1 << 0) +#define CL_MAP_WRITE (1 << 1) /* cl_program_info */ -#define CL_PROGRAM_REFERENCE_COUNT 0x1160 -#define CL_PROGRAM_CONTEXT 0x1161 -#define CL_PROGRAM_NUM_DEVICES 0x1162 -#define CL_PROGRAM_DEVICES 0x1163 -#define CL_PROGRAM_SOURCE 0x1164 -#define CL_PROGRAM_BINARY_SIZES 0x1165 -#define CL_PROGRAM_BINARIES 0x1166 +#define CL_PROGRAM_REFERENCE_COUNT 0x1160 +#define CL_PROGRAM_CONTEXT 0x1161 +#define CL_PROGRAM_NUM_DEVICES 0x1162 +#define CL_PROGRAM_DEVICES 0x1163 +#define CL_PROGRAM_SOURCE 0x1164 +#define CL_PROGRAM_BINARY_SIZES 0x1165 +#define CL_PROGRAM_BINARIES 0x1166 /* cl_program_build_info */ -#define CL_PROGRAM_BUILD_STATUS 0x1181 -#define CL_PROGRAM_BUILD_OPTIONS 0x1182 -#define CL_PROGRAM_BUILD_LOG 0x1183 +#define CL_PROGRAM_BUILD_STATUS 0x1181 +#define CL_PROGRAM_BUILD_OPTIONS 0x1182 +#define CL_PROGRAM_BUILD_LOG 0x1183 /* cl_build_status */ -#define CL_BUILD_SUCCESS 0 -#define CL_BUILD_NONE -1 -#define CL_BUILD_ERROR -2 -#define CL_BUILD_IN_PROGRESS -3 +#define CL_BUILD_SUCCESS 0 +#define CL_BUILD_NONE -1 +#define CL_BUILD_ERROR -2 +#define CL_BUILD_IN_PROGRESS -3 /* cl_kernel_info */ -#define CL_KERNEL_FUNCTION_NAME 0x1190 -#define CL_KERNEL_NUM_ARGS 0x1191 -#define CL_KERNEL_REFERENCE_COUNT 0x1192 -#define CL_KERNEL_CONTEXT 0x1193 -#define CL_KERNEL_PROGRAM 0x1194 +#define CL_KERNEL_FUNCTION_NAME 0x1190 +#define CL_KERNEL_NUM_ARGS 0x1191 +#define CL_KERNEL_REFERENCE_COUNT 0x1192 +#define CL_KERNEL_CONTEXT 0x1193 +#define CL_KERNEL_PROGRAM 0x1194 /* cl_kernel_work_group_info */ -#define CL_KERNEL_WORK_GROUP_SIZE 0x11B0 -#define CL_KERNEL_COMPILE_WORK_GROUP_SIZE 0x11B1 -#define CL_KERNEL_LOCAL_MEM_SIZE 0x11B2 +#define CL_KERNEL_WORK_GROUP_SIZE 0x11B0 +#define CL_KERNEL_COMPILE_WORK_GROUP_SIZE 0x11B1 +#define CL_KERNEL_LOCAL_MEM_SIZE 0x11B2 #define CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE 0x11B3 -#define CL_KERNEL_PRIVATE_MEM_SIZE 0x11B4 +#define CL_KERNEL_PRIVATE_MEM_SIZE 0x11B4 /* cl_event_info */ -#define CL_EVENT_COMMAND_QUEUE 0x11D0 -#define CL_EVENT_COMMAND_TYPE 0x11D1 -#define CL_EVENT_REFERENCE_COUNT 0x11D2 -#define CL_EVENT_COMMAND_EXECUTION_STATUS 0x11D3 -#define CL_EVENT_CONTEXT 0x11D4 +#define CL_EVENT_COMMAND_QUEUE 0x11D0 +#define CL_EVENT_COMMAND_TYPE 0x11D1 +#define CL_EVENT_REFERENCE_COUNT 0x11D2 +#define CL_EVENT_COMMAND_EXECUTION_STATUS 0x11D3 +#define CL_EVENT_CONTEXT 0x11D4 /* cl_command_type */ -#define CL_COMMAND_NDRANGE_KERNEL 0x11F0 -#define CL_COMMAND_TASK 0x11F1 -#define CL_COMMAND_NATIVE_KERNEL 0x11F2 -#define CL_COMMAND_READ_BUFFER 0x11F3 -#define CL_COMMAND_WRITE_BUFFER 0x11F4 -#define CL_COMMAND_COPY_BUFFER 0x11F5 -#define CL_COMMAND_READ_IMAGE 0x11F6 -#define CL_COMMAND_WRITE_IMAGE 0x11F7 -#define CL_COMMAND_COPY_IMAGE 0x11F8 -#define CL_COMMAND_COPY_IMAGE_TO_BUFFER 0x11F9 -#define CL_COMMAND_COPY_BUFFER_TO_IMAGE 0x11FA -#define CL_COMMAND_MAP_BUFFER 0x11FB -#define CL_COMMAND_MAP_IMAGE 0x11FC -#define CL_COMMAND_UNMAP_MEM_OBJECT 0x11FD -#define CL_COMMAND_MARKER 0x11FE -#define CL_COMMAND_ACQUIRE_GL_OBJECTS 0x11FF -#define CL_COMMAND_RELEASE_GL_OBJECTS 0x1200 -#define CL_COMMAND_READ_BUFFER_RECT 0x1201 -#define CL_COMMAND_WRITE_BUFFER_RECT 0x1202 -#define CL_COMMAND_COPY_BUFFER_RECT 0x1203 -#define CL_COMMAND_USER 0x1204 +#define CL_COMMAND_NDRANGE_KERNEL 0x11F0 +#define CL_COMMAND_TASK 0x11F1 +#define CL_COMMAND_NATIVE_KERNEL 0x11F2 +#define CL_COMMAND_READ_BUFFER 0x11F3 +#define CL_COMMAND_WRITE_BUFFER 0x11F4 +#define CL_COMMAND_COPY_BUFFER 0x11F5 +#define CL_COMMAND_READ_IMAGE 0x11F6 +#define CL_COMMAND_WRITE_IMAGE 0x11F7 +#define CL_COMMAND_COPY_IMAGE 0x11F8 +#define CL_COMMAND_COPY_IMAGE_TO_BUFFER 0x11F9 +#define CL_COMMAND_COPY_BUFFER_TO_IMAGE 0x11FA +#define CL_COMMAND_MAP_BUFFER 0x11FB +#define CL_COMMAND_MAP_IMAGE 0x11FC +#define CL_COMMAND_UNMAP_MEM_OBJECT 0x11FD +#define CL_COMMAND_MARKER 0x11FE +#define CL_COMMAND_ACQUIRE_GL_OBJECTS 0x11FF +#define CL_COMMAND_RELEASE_GL_OBJECTS 0x1200 +#define CL_COMMAND_READ_BUFFER_RECT 0x1201 +#define CL_COMMAND_WRITE_BUFFER_RECT 0x1202 +#define CL_COMMAND_COPY_BUFFER_RECT 0x1203 +#define CL_COMMAND_USER 0x1204 /* command execution status */ -#define CL_COMPLETE 0x0 -#define CL_RUNNING 0x1 -#define CL_SUBMITTED 0x2 -#define CL_QUEUED 0x3 - +#define CL_COMPLETE 0x0 +#define CL_RUNNING 0x1 +#define CL_SUBMITTED 0x2 +#define CL_QUEUED 0x3 + /* cl_buffer_create_type */ -#define CL_BUFFER_CREATE_TYPE_REGION 0x1220 +#define CL_BUFFER_CREATE_TYPE_REGION 0x1220 /* cl_profiling_info */ -#define CL_PROFILING_COMMAND_QUEUED 0x1280 -#define CL_PROFILING_COMMAND_SUBMIT 0x1281 -#define CL_PROFILING_COMMAND_START 0x1282 -#define CL_PROFILING_COMMAND_END 0x1283 - -/********************************************************************************************************/ - -/********************************************************************************************************/ - -/* Function signature typedef's */ - -/* Platform API */ -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLGETPLATFORMIDS)(cl_uint /* num_entries */, - cl_platform_id * /* platforms */, - cl_uint * /* num_platforms */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLGETPLATFORMINFO)(cl_platform_id /* platform */, - cl_platform_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -/* Device APIs */ -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLGETDEVICEIDS)(cl_platform_id /* platform */, - cl_device_type /* device_type */, - cl_uint /* num_entries */, - cl_device_id * /* devices */, - cl_uint * /* num_devices */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLGETDEVICEINFO)(cl_device_id /* device */, - cl_device_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -// Context APIs -typedef CL_API_ENTRY cl_context (CL_API_CALL * -PFNCLCREATECONTEXT)(const cl_context_properties * /* properties */, - cl_uint /* num_devices */, - const cl_device_id * /* devices */, - void (CL_CALLBACK * /* pfn_notify */)(const char *, const void *, size_t, void *), - void * /* user_data */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_context (CL_API_CALL * -PFNCLCREATECONTEXTFROMTYPE)(const cl_context_properties * /* properties */, - cl_device_type /* device_type */, - void (CL_CALLBACK * /* pfn_notify*/ )(const char *, const void *, size_t, void *), - void * /* user_data */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLRETAINCONTEXT)(cl_context /* context */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLRELEASECONTEXT)(cl_context /* context */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLGETCONTEXTINFO)(cl_context /* context */, - cl_context_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -/* Command Queue APIs */ -typedef CL_API_ENTRY cl_command_queue (CL_API_CALL * -PFNCLCREATECOMMANDQUEUE)(cl_context /* context */, - cl_device_id /* device */, - cl_command_queue_properties /* properties */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLRETAINCOMMANDQUEUE)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLRELEASECOMMANDQUEUE)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLGETCOMMANDQUEUEINFO)(cl_command_queue /* command_queue */, - cl_command_queue_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLSETCOMMANDQUEUEPROPERTY)(cl_command_queue /* command_queue */, - cl_command_queue_properties /* properties */, - cl_bool /* enable */, - cl_command_queue_properties * /* old_properties */) CL_API_SUFFIX__VERSION_1_0; - -/* Memory Object APIs */ -typedef CL_API_ENTRY cl_mem (CL_API_CALL * -PFNCLCREATEBUFFER)(cl_context /* context */, - cl_mem_flags /* flags */, - size_t /* size */, - void * /* host_ptr */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_mem (CL_API_CALL * -PFNCLCREATESUBBUFFER)(cl_mem /* buffer */, - cl_mem_flags /* flags */, - cl_buffer_create_type /* buffer_create_type */, - const void * /* buffer_create_info */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_1; - -typedef CL_API_ENTRY cl_mem (CL_API_CALL * -PFNCLCREATEIMAGE2D)(cl_context /* context */, - cl_mem_flags /* flags */, - const cl_image_format * /* image_format */, - size_t /* image_width */, - size_t /* image_height */, - size_t /* image_row_pitch */, - void * /* host_ptr */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_mem (CL_API_CALL * -PFNCLCREATEIMAGE3D)(cl_context /* context */, - cl_mem_flags /* flags */, - const cl_image_format * /* image_format */, - size_t /* image_width */, - size_t /* image_height */, - size_t /* image_depth */, - size_t /* image_row_pitch */, - size_t /* image_slice_pitch */, - void * /* host_ptr */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLRETAINMEMOBJECT)(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLRELEASEMEMOBJECT)(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLGETSUPPORTEDIMAGEFORMATS)(cl_context /* context */, - cl_mem_flags /* flags */, - cl_mem_object_type /* image_type */, - cl_uint /* num_entries */, - cl_image_format * /* image_formats */, - cl_uint * /* num_image_formats */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLGETMEMOBJECTINFO)(cl_mem /* memobj */, - cl_mem_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLGETIMAGEINFO)(cl_mem /* image */, - cl_image_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLSETMEMOBJECTDESTRUCTORCALLBACK)( cl_mem /* memobj */, - void (CL_CALLBACK * /*pfn_notify*/)( cl_mem /* memobj */, void* /*user_data*/), - void * /*user_data */ ) CL_API_SUFFIX__VERSION_1_1; - -/* Sampler APIs */ -typedef CL_API_ENTRY cl_sampler (CL_API_CALL * -PFNCLCREATESAMPLER)(cl_context /* context */, - cl_bool /* normalized_coords */, - cl_addressing_mode /* addressing_mode */, - cl_filter_mode /* filter_mode */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLRETAINSAMPLER)(cl_sampler /* sampler */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLRELEASESAMPLER)(cl_sampler /* sampler */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLGETSAMPLERINFO)(cl_sampler /* sampler */, - cl_sampler_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -/* Program Object APIs */ -typedef CL_API_ENTRY cl_program (CL_API_CALL * -PFNCLCREATEPROGRAMWITHSOURCE)(cl_context /* context */, - cl_uint /* count */, - const char ** /* strings */, - const size_t * /* lengths */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_program (CL_API_CALL * -PFNCLCREATEPROGRAMWITHBINARY)(cl_context /* context */, - cl_uint /* num_devices */, - const cl_device_id * /* device_list */, - const size_t * /* lengths */, - const unsigned char ** /* binaries */, - cl_int * /* binary_status */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLRETAINPROGRAM)(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLRELEASEPROGRAM)(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLBUILDPROGRAM)(cl_program /* program */, - cl_uint /* num_devices */, - const cl_device_id * /* device_list */, - const char * /* options */, - void (CL_CALLBACK * /* pfn_notify */)(cl_program /* program */, void * /* user_data */), - void * /* user_data */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLUNLOADCOMPILER)(void) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLGETPROGRAMINFO)(cl_program /* program */, - cl_program_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLGETPROGRAMBUILDINFO)(cl_program /* program */, - cl_device_id /* device */, - cl_program_build_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -/* Kernel Object APIs */ -typedef CL_API_ENTRY cl_kernel (CL_API_CALL * -PFNCLCREATEKERNEL)(cl_program /* program */, - const char * /* kernel_name */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLCREATEKERNELSINPROGRAM)(cl_program /* program */, - cl_uint /* num_kernels */, - cl_kernel * /* kernels */, - cl_uint * /* num_kernels_ret */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLRETAINKERNEL)(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLRELEASEKERNEL)(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLSETKERNELARG)(cl_kernel /* kernel */, - cl_uint /* arg_index */, - size_t /* arg_size */, - const void * /* arg_value */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLGETKERNELINFO)(cl_kernel /* kernel */, - cl_kernel_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLGETKERNELWORKGROUPINFO)(cl_kernel /* kernel */, - cl_device_id /* device */, - cl_kernel_work_group_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -// Event Object APIs -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLWAITFOREVENTS)(cl_uint /* num_events */, - const cl_event * /* event_list */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLGETEVENTINFO)(cl_event /* event */, - cl_event_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_event (CL_API_CALL * -PFNCLCREATEUSEREVENT)(cl_context /* context */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_1; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLRETAINEVENT)(cl_event /* event */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLRELEASEEVENT)(cl_event /* event */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLSETUSEREVENTSTATUS)(cl_event /* event */, - cl_int /* execution_status */) CL_API_SUFFIX__VERSION_1_1; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLSETEVENTCALLBACK)( cl_event /* event */, - cl_int /* command_exec_callback_type */, - void (CL_CALLBACK * /* pfn_notify */)(cl_event, cl_int, void *), - void * /* user_data */) CL_API_SUFFIX__VERSION_1_1; - -/* Profiling APIs */ -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLGETEVENTPROFILINGINFO)(cl_event /* event */, - cl_profiling_info /* param_name */, - size_t /* param_value_size */, - void * /* param_value */, - size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; - -// Flush and Finish APIs -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLFLUSH)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLFINISH)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; - -/* Enqueued Commands APIs */ -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLENQUEUEREADBUFFER)(cl_command_queue /* command_queue */, - cl_mem /* buffer */, - cl_bool /* blocking_read */, - size_t /* offset */, - size_t /* cb */, - void * /* ptr */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLENQUEUEREADBUFFERRECT)(cl_command_queue /* command_queue */, - cl_mem /* buffer */, - cl_bool /* blocking_read */, - const size_t * /* buffer_origin */, - const size_t * /* host_origin */, - const size_t * /* region */, - size_t /* buffer_row_pitch */, - size_t /* buffer_slice_pitch */, - size_t /* host_row_pitch */, - size_t /* host_slice_pitch */, - void * /* ptr */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_1; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLENQUEUEWRITEBUFFER)(cl_command_queue /* command_queue */, - cl_mem /* buffer */, - cl_bool /* blocking_write */, - size_t /* offset */, - size_t /* cb */, - const void * /* ptr */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLENQUEUEWRITEBUFFERRECT)(cl_command_queue /* command_queue */, - cl_mem /* buffer */, - cl_bool /* blocking_write */, - const size_t * /* buffer_origin */, - const size_t * /* host_origin */, - const size_t * /* region */, - size_t /* buffer_row_pitch */, - size_t /* buffer_slice_pitch */, - size_t /* host_row_pitch */, - size_t /* host_slice_pitch */, - const void * /* ptr */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_1; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLENQUEUECOPYBUFFER)(cl_command_queue /* command_queue */, - cl_mem /* src_buffer */, - cl_mem /* dst_buffer */, - size_t /* src_offset */, - size_t /* dst_offset */, - size_t /* cb */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLENQUEUECOPYBUFFERRECT)(cl_command_queue /* command_queue */, - cl_mem /* src_buffer */, - cl_mem /* dst_buffer */, - const size_t * /* src_origin */, - const size_t * /* dst_origin */, - const size_t * /* region */, - size_t /* src_row_pitch */, - size_t /* src_slice_pitch */, - size_t /* dst_row_pitch */, - size_t /* dst_slice_pitch */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_1; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLENQUEUEREADIMAGE)(cl_command_queue /* command_queue */, - cl_mem /* image */, - cl_bool /* blocking_read */, - const size_t * /* origin[3] */, - const size_t * /* region[3] */, - size_t /* row_pitch */, - size_t /* slice_pitch */, - void * /* ptr */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLENQUEUEWRITEIMAGE)(cl_command_queue /* command_queue */, - cl_mem /* image */, - cl_bool /* blocking_write */, - const size_t * /* origin[3] */, - const size_t * /* region[3] */, - size_t /* input_row_pitch */, - size_t /* input_slice_pitch */, - const void * /* ptr */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLENQUEUECOPYIMAGE)(cl_command_queue /* command_queue */, - cl_mem /* src_image */, - cl_mem /* dst_image */, - const size_t * /* src_origin[3] */, - const size_t * /* dst_origin[3] */, - const size_t * /* region[3] */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLENQUEUECOPYIMAGETOBUFFER)(cl_command_queue /* command_queue */, - cl_mem /* src_image */, - cl_mem /* dst_buffer */, - const size_t * /* src_origin[3] */, - const size_t * /* region[3] */, - size_t /* dst_offset */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLENQUEUECOPYBUFFERTOIMAGE)(cl_command_queue /* command_queue */, - cl_mem /* src_buffer */, - cl_mem /* dst_image */, - size_t /* src_offset */, - const size_t * /* dst_origin[3] */, - const size_t * /* region[3] */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY void * (CL_API_CALL * -PFNCLENQUEUEMAPBUFFER)(cl_command_queue /* command_queue */, - cl_mem /* buffer */, - cl_bool /* blocking_map */, - cl_map_flags /* map_flags */, - size_t /* offset */, - size_t /* cb */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY void * (CL_API_CALL * -PFNCLENQUEUEMAPIMAGE)(cl_command_queue /* command_queue */, - cl_mem /* image */, - cl_bool /* blocking_map */, - cl_map_flags /* map_flags */, - const size_t * /* origin[3] */, - const size_t * /* region[3] */, - size_t * /* image_row_pitch */, - size_t * /* image_slice_pitch */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */, - cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLENQUEUEUNMAPMEMOBJECT)(cl_command_queue /* command_queue */, - cl_mem /* memobj */, - void * /* mapped_ptr */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLENQUEUENDRANGEKERNEL)(cl_command_queue /* command_queue */, - cl_kernel /* kernel */, - cl_uint /* work_dim */, - const size_t * /* global_work_offset */, - const size_t * /* global_work_size */, - const size_t * /* local_work_size */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLENQUEUETASK)(cl_command_queue /* command_queue */, - cl_kernel /* kernel */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLENQUEUENATIVEKERNEL)(cl_command_queue /* command_queue */, - void (*user_func)(void *), - void * /* args */, - size_t /* cb_args */, - cl_uint /* num_mem_objects */, - const cl_mem * /* mem_list */, - const void ** /* args_mem_loc */, - cl_uint /* num_events_in_wait_list */, - const cl_event * /* event_wait_list */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLENQUEUEMARKER)(cl_command_queue /* command_queue */, - cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLENQUEUEWAITFOREVENTS)(cl_command_queue /* command_queue */, - cl_uint /* num_events */, - const cl_event * /* event_list */) CL_API_SUFFIX__VERSION_1_0; - -typedef CL_API_ENTRY cl_int (CL_API_CALL * -PFNCLENQUEUEBARRIER)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; - -// Extension function access -// -// Returns the extension function address for the given function name, -// or NULL if a valid function can not be found. The client must -// check to make sure the address is not NULL, before using or -// calling the returned function address. -// -typedef CL_API_ENTRY void * (CL_API_CALL * PFNCLGETEXTENSIONFUNCTIONADDRESS)(const char * /* func_name */) CL_API_SUFFIX__VERSION_1_0; - +#define CL_PROFILING_COMMAND_QUEUED 0x1280 +#define CL_PROFILING_COMMAND_SUBMIT 0x1281 +#define CL_PROFILING_COMMAND_START 0x1282 +#define CL_PROFILING_COMMAND_END 0x1283 + + /********************************************************************************************************/ + + /********************************************************************************************************/ + + /* Function signature typedef's */ + + /* Platform API */ + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLGETPLATFORMIDS)(cl_uint /* num_entries */, + cl_platform_id * /* platforms */, + cl_uint * /* num_platforms */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLGETPLATFORMINFO)(cl_platform_id /* platform */, + cl_platform_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + + /* Device APIs */ + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLGETDEVICEIDS)(cl_platform_id /* platform */, + cl_device_type /* device_type */, + cl_uint /* num_entries */, + cl_device_id * /* devices */, + cl_uint * /* num_devices */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLGETDEVICEINFO)(cl_device_id /* device */, + cl_device_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + + // Context APIs + typedef CL_API_ENTRY cl_context(CL_API_CALL * + PFNCLCREATECONTEXT)(const cl_context_properties * /* properties */, + cl_uint /* num_devices */, + const cl_device_id * /* devices */, + void(CL_CALLBACK * /* pfn_notify */)(const char *, const void *, size_t, void *), + void * /* user_data */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_context(CL_API_CALL * + PFNCLCREATECONTEXTFROMTYPE)(const cl_context_properties * /* properties */, + cl_device_type /* device_type */, + void(CL_CALLBACK * /* pfn_notify*/)(const char *, const void *, size_t, void *), + void * /* user_data */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLRETAINCONTEXT)(cl_context /* context */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLRELEASECONTEXT)(cl_context /* context */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLGETCONTEXTINFO)(cl_context /* context */, + cl_context_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + + /* Command Queue APIs */ + typedef CL_API_ENTRY cl_command_queue(CL_API_CALL * + PFNCLCREATECOMMANDQUEUE)(cl_context /* context */, + cl_device_id /* device */, + cl_command_queue_properties /* properties */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLRETAINCOMMANDQUEUE)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLRELEASECOMMANDQUEUE)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLGETCOMMANDQUEUEINFO)(cl_command_queue /* command_queue */, + cl_command_queue_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLSETCOMMANDQUEUEPROPERTY)(cl_command_queue /* command_queue */, + cl_command_queue_properties /* properties */, + cl_bool /* enable */, + cl_command_queue_properties * /* old_properties */) CL_API_SUFFIX__VERSION_1_0; + + /* Memory Object APIs */ + typedef CL_API_ENTRY cl_mem(CL_API_CALL * + PFNCLCREATEBUFFER)(cl_context /* context */, + cl_mem_flags /* flags */, + size_t /* size */, + void * /* host_ptr */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_mem(CL_API_CALL * + PFNCLCREATESUBBUFFER)(cl_mem /* buffer */, + cl_mem_flags /* flags */, + cl_buffer_create_type /* buffer_create_type */, + const void * /* buffer_create_info */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_1; + + typedef CL_API_ENTRY cl_mem(CL_API_CALL * + PFNCLCREATEIMAGE2D)(cl_context /* context */, + cl_mem_flags /* flags */, + const cl_image_format * /* image_format */, + size_t /* image_width */, + size_t /* image_height */, + size_t /* image_row_pitch */, + void * /* host_ptr */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_mem(CL_API_CALL * + PFNCLCREATEIMAGE3D)(cl_context /* context */, + cl_mem_flags /* flags */, + const cl_image_format * /* image_format */, + size_t /* image_width */, + size_t /* image_height */, + size_t /* image_depth */, + size_t /* image_row_pitch */, + size_t /* image_slice_pitch */, + void * /* host_ptr */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLRETAINMEMOBJECT)(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLRELEASEMEMOBJECT)(cl_mem /* memobj */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLGETSUPPORTEDIMAGEFORMATS)(cl_context /* context */, + cl_mem_flags /* flags */, + cl_mem_object_type /* image_type */, + cl_uint /* num_entries */, + cl_image_format * /* image_formats */, + cl_uint * /* num_image_formats */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLGETMEMOBJECTINFO)(cl_mem /* memobj */, + cl_mem_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLGETIMAGEINFO)(cl_mem /* image */, + cl_image_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLSETMEMOBJECTDESTRUCTORCALLBACK)(cl_mem /* memobj */, + void(CL_CALLBACK * /*pfn_notify*/)(cl_mem /* memobj */, void * /*user_data*/), + void * /*user_data */) CL_API_SUFFIX__VERSION_1_1; + + /* Sampler APIs */ + typedef CL_API_ENTRY cl_sampler(CL_API_CALL * + PFNCLCREATESAMPLER)(cl_context /* context */, + cl_bool /* normalized_coords */, + cl_addressing_mode /* addressing_mode */, + cl_filter_mode /* filter_mode */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLRETAINSAMPLER)(cl_sampler /* sampler */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLRELEASESAMPLER)(cl_sampler /* sampler */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLGETSAMPLERINFO)(cl_sampler /* sampler */, + cl_sampler_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + + /* Program Object APIs */ + typedef CL_API_ENTRY cl_program(CL_API_CALL * + PFNCLCREATEPROGRAMWITHSOURCE)(cl_context /* context */, + cl_uint /* count */, + const char ** /* strings */, + const size_t * /* lengths */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_program(CL_API_CALL * + PFNCLCREATEPROGRAMWITHBINARY)(cl_context /* context */, + cl_uint /* num_devices */, + const cl_device_id * /* device_list */, + const size_t * /* lengths */, + const unsigned char ** /* binaries */, + cl_int * /* binary_status */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLRETAINPROGRAM)(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLRELEASEPROGRAM)(cl_program /* program */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLBUILDPROGRAM)(cl_program /* program */, + cl_uint /* num_devices */, + const cl_device_id * /* device_list */, + const char * /* options */, + void(CL_CALLBACK * /* pfn_notify */)(cl_program /* program */, void * /* user_data */), + void * /* user_data */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLUNLOADCOMPILER)(void) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLGETPROGRAMINFO)(cl_program /* program */, + cl_program_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLGETPROGRAMBUILDINFO)(cl_program /* program */, + cl_device_id /* device */, + cl_program_build_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + + /* Kernel Object APIs */ + typedef CL_API_ENTRY cl_kernel(CL_API_CALL * + PFNCLCREATEKERNEL)(cl_program /* program */, + const char * /* kernel_name */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLCREATEKERNELSINPROGRAM)(cl_program /* program */, + cl_uint /* num_kernels */, + cl_kernel * /* kernels */, + cl_uint * /* num_kernels_ret */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLRETAINKERNEL)(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLRELEASEKERNEL)(cl_kernel /* kernel */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLSETKERNELARG)(cl_kernel /* kernel */, + cl_uint /* arg_index */, + size_t /* arg_size */, + const void * /* arg_value */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLGETKERNELINFO)(cl_kernel /* kernel */, + cl_kernel_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLGETKERNELWORKGROUPINFO)(cl_kernel /* kernel */, + cl_device_id /* device */, + cl_kernel_work_group_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + + // Event Object APIs + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLWAITFOREVENTS)(cl_uint /* num_events */, + const cl_event * /* event_list */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLGETEVENTINFO)(cl_event /* event */, + cl_event_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_event(CL_API_CALL * + PFNCLCREATEUSEREVENT)(cl_context /* context */, + cl_int * /* errcode_ret */) CL_API_SUFFIX__VERSION_1_1; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLRETAINEVENT)(cl_event /* event */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLRELEASEEVENT)(cl_event /* event */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLSETUSEREVENTSTATUS)(cl_event /* event */, + cl_int /* execution_status */) CL_API_SUFFIX__VERSION_1_1; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLSETEVENTCALLBACK)(cl_event /* event */, + cl_int /* command_exec_callback_type */, + void(CL_CALLBACK * /* pfn_notify */)(cl_event, cl_int, void *), + void * /* user_data */) CL_API_SUFFIX__VERSION_1_1; + + /* Profiling APIs */ + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLGETEVENTPROFILINGINFO)(cl_event /* event */, + cl_profiling_info /* param_name */, + size_t /* param_value_size */, + void * /* param_value */, + size_t * /* param_value_size_ret */) CL_API_SUFFIX__VERSION_1_0; + + // Flush and Finish APIs + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLFLUSH)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLFINISH)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; + + /* Enqueued Commands APIs */ + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLENQUEUEREADBUFFER)(cl_command_queue /* command_queue */, + cl_mem /* buffer */, + cl_bool /* blocking_read */, + size_t /* offset */, + size_t /* cb */, + void * /* ptr */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLENQUEUEREADBUFFERRECT)(cl_command_queue /* command_queue */, + cl_mem /* buffer */, + cl_bool /* blocking_read */, + const size_t * /* buffer_origin */, + const size_t * /* host_origin */, + const size_t * /* region */, + size_t /* buffer_row_pitch */, + size_t /* buffer_slice_pitch */, + size_t /* host_row_pitch */, + size_t /* host_slice_pitch */, + void * /* ptr */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_1; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLENQUEUEWRITEBUFFER)(cl_command_queue /* command_queue */, + cl_mem /* buffer */, + cl_bool /* blocking_write */, + size_t /* offset */, + size_t /* cb */, + const void * /* ptr */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLENQUEUEWRITEBUFFERRECT)(cl_command_queue /* command_queue */, + cl_mem /* buffer */, + cl_bool /* blocking_write */, + const size_t * /* buffer_origin */, + const size_t * /* host_origin */, + const size_t * /* region */, + size_t /* buffer_row_pitch */, + size_t /* buffer_slice_pitch */, + size_t /* host_row_pitch */, + size_t /* host_slice_pitch */, + const void * /* ptr */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_1; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLENQUEUECOPYBUFFER)(cl_command_queue /* command_queue */, + cl_mem /* src_buffer */, + cl_mem /* dst_buffer */, + size_t /* src_offset */, + size_t /* dst_offset */, + size_t /* cb */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLENQUEUECOPYBUFFERRECT)(cl_command_queue /* command_queue */, + cl_mem /* src_buffer */, + cl_mem /* dst_buffer */, + const size_t * /* src_origin */, + const size_t * /* dst_origin */, + const size_t * /* region */, + size_t /* src_row_pitch */, + size_t /* src_slice_pitch */, + size_t /* dst_row_pitch */, + size_t /* dst_slice_pitch */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_1; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLENQUEUEREADIMAGE)(cl_command_queue /* command_queue */, + cl_mem /* image */, + cl_bool /* blocking_read */, + const size_t * /* origin[3] */, + const size_t * /* region[3] */, + size_t /* row_pitch */, + size_t /* slice_pitch */, + void * /* ptr */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLENQUEUEWRITEIMAGE)(cl_command_queue /* command_queue */, + cl_mem /* image */, + cl_bool /* blocking_write */, + const size_t * /* origin[3] */, + const size_t * /* region[3] */, + size_t /* input_row_pitch */, + size_t /* input_slice_pitch */, + const void * /* ptr */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLENQUEUECOPYIMAGE)(cl_command_queue /* command_queue */, + cl_mem /* src_image */, + cl_mem /* dst_image */, + const size_t * /* src_origin[3] */, + const size_t * /* dst_origin[3] */, + const size_t * /* region[3] */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLENQUEUECOPYIMAGETOBUFFER)(cl_command_queue /* command_queue */, + cl_mem /* src_image */, + cl_mem /* dst_buffer */, + const size_t * /* src_origin[3] */, + const size_t * /* region[3] */, + size_t /* dst_offset */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLENQUEUECOPYBUFFERTOIMAGE)(cl_command_queue /* command_queue */, + cl_mem /* src_buffer */, + cl_mem /* dst_image */, + size_t /* src_offset */, + const size_t * /* dst_origin[3] */, + const size_t * /* region[3] */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY void *(CL_API_CALL * + PFNCLENQUEUEMAPBUFFER)(cl_command_queue /* command_queue */, + cl_mem /* buffer */, + cl_bool /* blocking_map */, + cl_map_flags /* map_flags */, + size_t /* offset */, + size_t /* cb */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */, + cl_int * /* errcode_ret */)CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY void *(CL_API_CALL * + PFNCLENQUEUEMAPIMAGE)(cl_command_queue /* command_queue */, + cl_mem /* image */, + cl_bool /* blocking_map */, + cl_map_flags /* map_flags */, + const size_t * /* origin[3] */, + const size_t * /* region[3] */, + size_t * /* image_row_pitch */, + size_t * /* image_slice_pitch */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */, + cl_int * /* errcode_ret */)CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLENQUEUEUNMAPMEMOBJECT)(cl_command_queue /* command_queue */, + cl_mem /* memobj */, + void * /* mapped_ptr */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLENQUEUENDRANGEKERNEL)(cl_command_queue /* command_queue */, + cl_kernel /* kernel */, + cl_uint /* work_dim */, + const size_t * /* global_work_offset */, + const size_t * /* global_work_size */, + const size_t * /* local_work_size */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLENQUEUETASK)(cl_command_queue /* command_queue */, + cl_kernel /* kernel */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLENQUEUENATIVEKERNEL)(cl_command_queue /* command_queue */, + void (*user_func)(void *), + void * /* args */, + size_t /* cb_args */, + cl_uint /* num_mem_objects */, + const cl_mem * /* mem_list */, + const void ** /* args_mem_loc */, + cl_uint /* num_events_in_wait_list */, + const cl_event * /* event_wait_list */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLENQUEUEMARKER)(cl_command_queue /* command_queue */, + cl_event * /* event */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLENQUEUEWAITFOREVENTS)(cl_command_queue /* command_queue */, + cl_uint /* num_events */, + const cl_event * /* event_list */) CL_API_SUFFIX__VERSION_1_0; + + typedef CL_API_ENTRY cl_int(CL_API_CALL * + PFNCLENQUEUEBARRIER)(cl_command_queue /* command_queue */) CL_API_SUFFIX__VERSION_1_0; + + // Extension function access + // + // Returns the extension function address for the given function name, + // or NULL if a valid function can not be found. The client must + // check to make sure the address is not NULL, before using or + // calling the returned function address. + // + typedef CL_API_ENTRY void *(CL_API_CALL *PFNCLGETEXTENSIONFUNCTIONADDRESS)(const char * /* func_name */)CL_API_SUFFIX__VERSION_1_0; #define CLEW_STATIC #ifdef CLEW_STATIC -# define CLEWAPI extern +#define CLEWAPI extern #else -# ifdef CLEW_BUILD -# define CLEWAPI extern __declspec(dllexport) -# else -# define CLEWAPI extern __declspec(dllimport) -# endif +#ifdef CLEW_BUILD +#define CLEWAPI extern __declspec(dllexport) +#else +#define CLEWAPI extern __declspec(dllimport) +#endif #endif #if defined(_WIN32) @@ -2208,99 +2522,97 @@ typedef CL_API_ENTRY void * (CL_API_CALL * PFNCLGETEXTENSIONFUNCTIONADDRESS)(con #define CLEW_GET_FUN(x) x - -// Variables holding function entry points -CLEW_FUN_EXPORT PFNCLGETPLATFORMIDS __clewGetPlatformIDs ; -CLEW_FUN_EXPORT PFNCLGETPLATFORMINFO __clewGetPlatformInfo ; -CLEW_FUN_EXPORT PFNCLGETDEVICEIDS __clewGetDeviceIDs ; -CLEW_FUN_EXPORT PFNCLGETDEVICEINFO __clewGetDeviceInfo ; -CLEW_FUN_EXPORT PFNCLCREATECONTEXT __clewCreateContext ; -CLEW_FUN_EXPORT PFNCLCREATECONTEXTFROMTYPE __clewCreateContextFromType ; -CLEW_FUN_EXPORT PFNCLRETAINCONTEXT __clewRetainContext ; -CLEW_FUN_EXPORT PFNCLRELEASECONTEXT __clewReleaseContext ; -CLEW_FUN_EXPORT PFNCLGETCONTEXTINFO __clewGetContextInfo ; -CLEW_FUN_EXPORT PFNCLCREATECOMMANDQUEUE __clewCreateCommandQueue ; -CLEW_FUN_EXPORT PFNCLRETAINCOMMANDQUEUE __clewRetainCommandQueue ; -CLEW_FUN_EXPORT PFNCLRELEASECOMMANDQUEUE __clewReleaseCommandQueue ; -CLEW_FUN_EXPORT PFNCLGETCOMMANDQUEUEINFO __clewGetCommandQueueInfo ; + // Variables holding function entry points + CLEW_FUN_EXPORT PFNCLGETPLATFORMIDS __clewGetPlatformIDs; + CLEW_FUN_EXPORT PFNCLGETPLATFORMINFO __clewGetPlatformInfo; + CLEW_FUN_EXPORT PFNCLGETDEVICEIDS __clewGetDeviceIDs; + CLEW_FUN_EXPORT PFNCLGETDEVICEINFO __clewGetDeviceInfo; + CLEW_FUN_EXPORT PFNCLCREATECONTEXT __clewCreateContext; + CLEW_FUN_EXPORT PFNCLCREATECONTEXTFROMTYPE __clewCreateContextFromType; + CLEW_FUN_EXPORT PFNCLRETAINCONTEXT __clewRetainContext; + CLEW_FUN_EXPORT PFNCLRELEASECONTEXT __clewReleaseContext; + CLEW_FUN_EXPORT PFNCLGETCONTEXTINFO __clewGetContextInfo; + CLEW_FUN_EXPORT PFNCLCREATECOMMANDQUEUE __clewCreateCommandQueue; + CLEW_FUN_EXPORT PFNCLRETAINCOMMANDQUEUE __clewRetainCommandQueue; + CLEW_FUN_EXPORT PFNCLRELEASECOMMANDQUEUE __clewReleaseCommandQueue; + CLEW_FUN_EXPORT PFNCLGETCOMMANDQUEUEINFO __clewGetCommandQueueInfo; #ifdef CL_USE_DEPRECATED_OPENCL_1_0_APIS -CLEW_FUN_EXPORT PFNCLSETCOMMANDQUEUEPROPERTY __clewSetCommandQueueProperty ; + CLEW_FUN_EXPORT PFNCLSETCOMMANDQUEUEPROPERTY __clewSetCommandQueueProperty; #endif -CLEW_FUN_EXPORT PFNCLCREATEBUFFER __clewCreateBuffer ; -CLEW_FUN_EXPORT PFNCLCREATESUBBUFFER __clewCreateSubBuffer ; -CLEW_FUN_EXPORT PFNCLCREATEIMAGE2D __clewCreateImage2D ; -CLEW_FUN_EXPORT PFNCLCREATEIMAGE3D __clewCreateImage3D ; -CLEW_FUN_EXPORT PFNCLRETAINMEMOBJECT __clewRetainMemObject ; -CLEW_FUN_EXPORT PFNCLRELEASEMEMOBJECT __clewReleaseMemObject ; -CLEW_FUN_EXPORT PFNCLGETSUPPORTEDIMAGEFORMATS __clewGetSupportedImageFormats ; -CLEW_FUN_EXPORT PFNCLGETMEMOBJECTINFO __clewGetMemObjectInfo ; -CLEW_FUN_EXPORT PFNCLGETIMAGEINFO __clewGetImageInfo ; -CLEW_FUN_EXPORT PFNCLSETMEMOBJECTDESTRUCTORCALLBACK __clewSetMemObjectDestructorCallback; -CLEW_FUN_EXPORT PFNCLCREATESAMPLER __clewCreateSampler ; -CLEW_FUN_EXPORT PFNCLRETAINSAMPLER __clewRetainSampler ; -CLEW_FUN_EXPORT PFNCLRELEASESAMPLER __clewReleaseSampler ; -CLEW_FUN_EXPORT PFNCLGETSAMPLERINFO __clewGetSamplerInfo ; -CLEW_FUN_EXPORT PFNCLCREATEPROGRAMWITHSOURCE __clewCreateProgramWithSource ; -CLEW_FUN_EXPORT PFNCLCREATEPROGRAMWITHBINARY __clewCreateProgramWithBinary ; -CLEW_FUN_EXPORT PFNCLRETAINPROGRAM __clewRetainProgram ; -CLEW_FUN_EXPORT PFNCLRELEASEPROGRAM __clewReleaseProgram ; -CLEW_FUN_EXPORT PFNCLBUILDPROGRAM __clewBuildProgram ; -CLEW_FUN_EXPORT PFNCLUNLOADCOMPILER __clewUnloadCompiler ; -CLEW_FUN_EXPORT PFNCLGETPROGRAMINFO __clewGetProgramInfo ; -CLEW_FUN_EXPORT PFNCLGETPROGRAMBUILDINFO __clewGetProgramBuildInfo ; -CLEW_FUN_EXPORT PFNCLCREATEKERNEL __clewCreateKernel ; -CLEW_FUN_EXPORT PFNCLCREATEKERNELSINPROGRAM __clewCreateKernelsInProgram ; -CLEW_FUN_EXPORT PFNCLRETAINKERNEL __clewRetainKernel ; -CLEW_FUN_EXPORT PFNCLRELEASEKERNEL __clewReleaseKernel ; -CLEW_FUN_EXPORT PFNCLSETKERNELARG __clewSetKernelArg ; -CLEW_FUN_EXPORT PFNCLGETKERNELINFO __clewGetKernelInfo ; -CLEW_FUN_EXPORT PFNCLGETKERNELWORKGROUPINFO __clewGetKernelWorkGroupInfo ; -CLEW_FUN_EXPORT PFNCLWAITFOREVENTS __clewWaitForEvents ; -CLEW_FUN_EXPORT PFNCLGETEVENTINFO __clewGetEventInfo ; -CLEW_FUN_EXPORT PFNCLCREATEUSEREVENT __clewCreateUserEvent ; -CLEW_FUN_EXPORT PFNCLRETAINEVENT __clewRetainEvent ; -CLEW_FUN_EXPORT PFNCLRELEASEEVENT __clewReleaseEvent ; -CLEW_FUN_EXPORT PFNCLSETUSEREVENTSTATUS __clewSetUserEventStatus ; -CLEW_FUN_EXPORT PFNCLSETEVENTCALLBACK __clewSetEventCallback ; -CLEW_FUN_EXPORT PFNCLGETEVENTPROFILINGINFO __clewGetEventProfilingInfo ; -CLEW_FUN_EXPORT PFNCLFLUSH __clewFlush ; -CLEW_FUN_EXPORT PFNCLFINISH __clewFinish ; -CLEW_FUN_EXPORT PFNCLENQUEUEREADBUFFER __clewEnqueueReadBuffer ; -CLEW_FUN_EXPORT PFNCLENQUEUEREADBUFFERRECT __clewEnqueueReadBufferRect ; -CLEW_FUN_EXPORT PFNCLENQUEUEWRITEBUFFER __clewEnqueueWriteBuffer ; -CLEW_FUN_EXPORT PFNCLENQUEUEWRITEBUFFERRECT __clewEnqueueWriteBufferRect ; -CLEW_FUN_EXPORT PFNCLENQUEUECOPYBUFFER __clewEnqueueCopyBuffer ; -CLEW_FUN_EXPORT PFNCLENQUEUECOPYBUFFERRECT __clewEnqueueCopyBufferRect ; -CLEW_FUN_EXPORT PFNCLENQUEUEREADIMAGE __clewEnqueueReadImage ; -CLEW_FUN_EXPORT PFNCLENQUEUEWRITEIMAGE __clewEnqueueWriteImage ; -CLEW_FUN_EXPORT PFNCLENQUEUECOPYIMAGE __clewEnqueueCopyImage ; -CLEW_FUN_EXPORT PFNCLENQUEUECOPYIMAGETOBUFFER __clewEnqueueCopyImageToBuffer ; -CLEW_FUN_EXPORT PFNCLENQUEUECOPYBUFFERTOIMAGE __clewEnqueueCopyBufferToImage ; -CLEW_FUN_EXPORT PFNCLENQUEUEMAPBUFFER __clewEnqueueMapBuffer ; -CLEW_FUN_EXPORT PFNCLENQUEUEMAPIMAGE __clewEnqueueMapImage ; -CLEW_FUN_EXPORT PFNCLENQUEUEUNMAPMEMOBJECT __clewEnqueueUnmapMemObject ; -CLEW_FUN_EXPORT PFNCLENQUEUENDRANGEKERNEL __clewEnqueueNDRangeKernel ; -CLEW_FUN_EXPORT PFNCLENQUEUETASK __clewEnqueueTask ; -CLEW_FUN_EXPORT PFNCLENQUEUENATIVEKERNEL __clewEnqueueNativeKernel ; -CLEW_FUN_EXPORT PFNCLENQUEUEMARKER __clewEnqueueMarker ; -CLEW_FUN_EXPORT PFNCLENQUEUEWAITFOREVENTS __clewEnqueueWaitForEvents ; -CLEW_FUN_EXPORT PFNCLENQUEUEBARRIER __clewEnqueueBarrier ; -CLEW_FUN_EXPORT PFNCLGETEXTENSIONFUNCTIONADDRESS __clewGetExtensionFunctionAddress ; + CLEW_FUN_EXPORT PFNCLCREATEBUFFER __clewCreateBuffer; + CLEW_FUN_EXPORT PFNCLCREATESUBBUFFER __clewCreateSubBuffer; + CLEW_FUN_EXPORT PFNCLCREATEIMAGE2D __clewCreateImage2D; + CLEW_FUN_EXPORT PFNCLCREATEIMAGE3D __clewCreateImage3D; + CLEW_FUN_EXPORT PFNCLRETAINMEMOBJECT __clewRetainMemObject; + CLEW_FUN_EXPORT PFNCLRELEASEMEMOBJECT __clewReleaseMemObject; + CLEW_FUN_EXPORT PFNCLGETSUPPORTEDIMAGEFORMATS __clewGetSupportedImageFormats; + CLEW_FUN_EXPORT PFNCLGETMEMOBJECTINFO __clewGetMemObjectInfo; + CLEW_FUN_EXPORT PFNCLGETIMAGEINFO __clewGetImageInfo; + CLEW_FUN_EXPORT PFNCLSETMEMOBJECTDESTRUCTORCALLBACK __clewSetMemObjectDestructorCallback; + CLEW_FUN_EXPORT PFNCLCREATESAMPLER __clewCreateSampler; + CLEW_FUN_EXPORT PFNCLRETAINSAMPLER __clewRetainSampler; + CLEW_FUN_EXPORT PFNCLRELEASESAMPLER __clewReleaseSampler; + CLEW_FUN_EXPORT PFNCLGETSAMPLERINFO __clewGetSamplerInfo; + CLEW_FUN_EXPORT PFNCLCREATEPROGRAMWITHSOURCE __clewCreateProgramWithSource; + CLEW_FUN_EXPORT PFNCLCREATEPROGRAMWITHBINARY __clewCreateProgramWithBinary; + CLEW_FUN_EXPORT PFNCLRETAINPROGRAM __clewRetainProgram; + CLEW_FUN_EXPORT PFNCLRELEASEPROGRAM __clewReleaseProgram; + CLEW_FUN_EXPORT PFNCLBUILDPROGRAM __clewBuildProgram; + CLEW_FUN_EXPORT PFNCLUNLOADCOMPILER __clewUnloadCompiler; + CLEW_FUN_EXPORT PFNCLGETPROGRAMINFO __clewGetProgramInfo; + CLEW_FUN_EXPORT PFNCLGETPROGRAMBUILDINFO __clewGetProgramBuildInfo; + CLEW_FUN_EXPORT PFNCLCREATEKERNEL __clewCreateKernel; + CLEW_FUN_EXPORT PFNCLCREATEKERNELSINPROGRAM __clewCreateKernelsInProgram; + CLEW_FUN_EXPORT PFNCLRETAINKERNEL __clewRetainKernel; + CLEW_FUN_EXPORT PFNCLRELEASEKERNEL __clewReleaseKernel; + CLEW_FUN_EXPORT PFNCLSETKERNELARG __clewSetKernelArg; + CLEW_FUN_EXPORT PFNCLGETKERNELINFO __clewGetKernelInfo; + CLEW_FUN_EXPORT PFNCLGETKERNELWORKGROUPINFO __clewGetKernelWorkGroupInfo; + CLEW_FUN_EXPORT PFNCLWAITFOREVENTS __clewWaitForEvents; + CLEW_FUN_EXPORT PFNCLGETEVENTINFO __clewGetEventInfo; + CLEW_FUN_EXPORT PFNCLCREATEUSEREVENT __clewCreateUserEvent; + CLEW_FUN_EXPORT PFNCLRETAINEVENT __clewRetainEvent; + CLEW_FUN_EXPORT PFNCLRELEASEEVENT __clewReleaseEvent; + CLEW_FUN_EXPORT PFNCLSETUSEREVENTSTATUS __clewSetUserEventStatus; + CLEW_FUN_EXPORT PFNCLSETEVENTCALLBACK __clewSetEventCallback; + CLEW_FUN_EXPORT PFNCLGETEVENTPROFILINGINFO __clewGetEventProfilingInfo; + CLEW_FUN_EXPORT PFNCLFLUSH __clewFlush; + CLEW_FUN_EXPORT PFNCLFINISH __clewFinish; + CLEW_FUN_EXPORT PFNCLENQUEUEREADBUFFER __clewEnqueueReadBuffer; + CLEW_FUN_EXPORT PFNCLENQUEUEREADBUFFERRECT __clewEnqueueReadBufferRect; + CLEW_FUN_EXPORT PFNCLENQUEUEWRITEBUFFER __clewEnqueueWriteBuffer; + CLEW_FUN_EXPORT PFNCLENQUEUEWRITEBUFFERRECT __clewEnqueueWriteBufferRect; + CLEW_FUN_EXPORT PFNCLENQUEUECOPYBUFFER __clewEnqueueCopyBuffer; + CLEW_FUN_EXPORT PFNCLENQUEUECOPYBUFFERRECT __clewEnqueueCopyBufferRect; + CLEW_FUN_EXPORT PFNCLENQUEUEREADIMAGE __clewEnqueueReadImage; + CLEW_FUN_EXPORT PFNCLENQUEUEWRITEIMAGE __clewEnqueueWriteImage; + CLEW_FUN_EXPORT PFNCLENQUEUECOPYIMAGE __clewEnqueueCopyImage; + CLEW_FUN_EXPORT PFNCLENQUEUECOPYIMAGETOBUFFER __clewEnqueueCopyImageToBuffer; + CLEW_FUN_EXPORT PFNCLENQUEUECOPYBUFFERTOIMAGE __clewEnqueueCopyBufferToImage; + CLEW_FUN_EXPORT PFNCLENQUEUEMAPBUFFER __clewEnqueueMapBuffer; + CLEW_FUN_EXPORT PFNCLENQUEUEMAPIMAGE __clewEnqueueMapImage; + CLEW_FUN_EXPORT PFNCLENQUEUEUNMAPMEMOBJECT __clewEnqueueUnmapMemObject; + CLEW_FUN_EXPORT PFNCLENQUEUENDRANGEKERNEL __clewEnqueueNDRangeKernel; + CLEW_FUN_EXPORT PFNCLENQUEUETASK __clewEnqueueTask; + CLEW_FUN_EXPORT PFNCLENQUEUENATIVEKERNEL __clewEnqueueNativeKernel; + CLEW_FUN_EXPORT PFNCLENQUEUEMARKER __clewEnqueueMarker; + CLEW_FUN_EXPORT PFNCLENQUEUEWAITFOREVENTS __clewEnqueueWaitForEvents; + CLEW_FUN_EXPORT PFNCLENQUEUEBARRIER __clewEnqueueBarrier; + CLEW_FUN_EXPORT PFNCLGETEXTENSIONFUNCTIONADDRESS __clewGetExtensionFunctionAddress; - -#define clGetPlatformIDs CLEW_GET_FUN(__clewGetPlatformIDs ) -#define clGetPlatformInfo CLEW_GET_FUN(__clewGetPlatformInfo ) -#define clGetDeviceIDs CLEW_GET_FUN(__clewGetDeviceIDs ) -#define clGetDeviceInfo CLEW_GET_FUN(__clewGetDeviceInfo ) -#define clCreateContext CLEW_GET_FUN(__clewCreateContext ) -#define clCreateContextFromType CLEW_GET_FUN(__clewCreateContextFromType ) -#define clRetainContext CLEW_GET_FUN(__clewRetainContext ) -#define clReleaseContext CLEW_GET_FUN(__clewReleaseContext ) -#define clGetContextInfo CLEW_GET_FUN(__clewGetContextInfo ) -#define clCreateCommandQueue CLEW_GET_FUN(__clewCreateCommandQueue ) -#define clRetainCommandQueue CLEW_GET_FUN(__clewRetainCommandQueue ) -#define clReleaseCommandQueue CLEW_GET_FUN(__clewReleaseCommandQueue ) -#define clGetCommandQueueInfo CLEW_GET_FUN(__clewGetCommandQueueInfo ) +#define clGetPlatformIDs CLEW_GET_FUN(__clewGetPlatformIDs) +#define clGetPlatformInfo CLEW_GET_FUN(__clewGetPlatformInfo) +#define clGetDeviceIDs CLEW_GET_FUN(__clewGetDeviceIDs) +#define clGetDeviceInfo CLEW_GET_FUN(__clewGetDeviceInfo) +#define clCreateContext CLEW_GET_FUN(__clewCreateContext) +#define clCreateContextFromType CLEW_GET_FUN(__clewCreateContextFromType) +#define clRetainContext CLEW_GET_FUN(__clewRetainContext) +#define clReleaseContext CLEW_GET_FUN(__clewReleaseContext) +#define clGetContextInfo CLEW_GET_FUN(__clewGetContextInfo) +#define clCreateCommandQueue CLEW_GET_FUN(__clewCreateCommandQueue) +#define clRetainCommandQueue CLEW_GET_FUN(__clewRetainCommandQueue) +#define clReleaseCommandQueue CLEW_GET_FUN(__clewReleaseCommandQueue) +#define clGetCommandQueueInfo CLEW_GET_FUN(__clewGetCommandQueueInfo) #ifdef CL_USE_DEPRECATED_OPENCL_1_0_APIS #warning CL_USE_DEPRECATED_OPENCL_1_0_APIS is defined. These APIs are unsupported and untested in OpenCL 1.1! /* @@ -2313,82 +2625,81 @@ CLEW_FUN_EXPORT PFNCLGETEXTENSIONFUNCTIONADDRESS __clewGetExtensionFuncti * Software developers previously relying on this API are instructed to set the command queue * properties when creating the queue, instead. */ -#define clSetCommandQueueProperty CLEW_GET_FUN(__clewSetCommandQueueProperty ) +#define clSetCommandQueueProperty CLEW_GET_FUN(__clewSetCommandQueueProperty) #endif /* CL_USE_DEPRECATED_OPENCL_1_0_APIS */ -#define clCreateBuffer CLEW_GET_FUN(__clewCreateBuffer ) -#define clCreateSubBuffer CLEW_GET_FUN(__clewCreateSubBuffer ) -#define clCreateImage2D CLEW_GET_FUN(__clewCreateImage2D ) -#define clCreateImage3D CLEW_GET_FUN(__clewCreateImage3D ) -#define clRetainMemObject CLEW_GET_FUN(__clewRetainMemObject ) -#define clReleaseMemObject CLEW_GET_FUN(__clewReleaseMemObject ) -#define clGetSupportedImageFormats CLEW_GET_FUN(__clewGetSupportedImageFormats ) -#define clGetMemObjectInfo CLEW_GET_FUN(__clewGetMemObjectInfo ) -#define clGetImageInfo CLEW_GET_FUN(__clewGetImageInfo ) -#define clSetMemObjectDestructorCallback CLEW_GET_FUN(__clewSetMemObjectDestructorCallback) -#define clCreateSampler CLEW_GET_FUN(__clewCreateSampler ) -#define clRetainSampler CLEW_GET_FUN(__clewRetainSampler ) -#define clReleaseSampler CLEW_GET_FUN(__clewReleaseSampler ) -#define clGetSamplerInfo CLEW_GET_FUN(__clewGetSamplerInfo ) -#define clCreateProgramWithSource CLEW_GET_FUN(__clewCreateProgramWithSource ) -#define clCreateProgramWithBinary CLEW_GET_FUN(__clewCreateProgramWithBinary ) -#define clRetainProgram CLEW_GET_FUN(__clewRetainProgram ) -#define clReleaseProgram CLEW_GET_FUN(__clewReleaseProgram ) -#define clBuildProgram CLEW_GET_FUN(__clewBuildProgram ) -#define clUnloadCompiler CLEW_GET_FUN(__clewUnloadCompiler ) -#define clGetProgramInfo CLEW_GET_FUN(__clewGetProgramInfo ) -#define clGetProgramBuildInfo CLEW_GET_FUN(__clewGetProgramBuildInfo ) -#define clCreateKernel CLEW_GET_FUN(__clewCreateKernel ) -#define clCreateKernelsInProgram CLEW_GET_FUN(__clewCreateKernelsInProgram ) -#define clRetainKernel CLEW_GET_FUN(__clewRetainKernel ) -#define clReleaseKernel CLEW_GET_FUN(__clewReleaseKernel ) -#define clSetKernelArg CLEW_GET_FUN(__clewSetKernelArg ) -#define clGetKernelInfo CLEW_GET_FUN(__clewGetKernelInfo ) -#define clGetKernelWorkGroupInfo CLEW_GET_FUN(__clewGetKernelWorkGroupInfo ) -#define clWaitForEvents CLEW_GET_FUN(__clewWaitForEvents ) -#define clGetEventInfo CLEW_GET_FUN(__clewGetEventInfo ) -#define clCreateUserEvent CLEW_GET_FUN(__clewCreateUserEvent ) -#define clRetainEvent CLEW_GET_FUN(__clewRetainEvent ) -#define clReleaseEvent CLEW_GET_FUN(__clewReleaseEvent ) -#define clSetUserEventStatus CLEW_GET_FUN(__clewSetUserEventStatus ) -#define clSetEventCallback CLEW_GET_FUN(__clewSetEventCallback ) -#define clGetEventProfilingInfo CLEW_GET_FUN(__clewGetEventProfilingInfo ) -#define clFlush CLEW_GET_FUN(__clewFlush ) -#define clFinish CLEW_GET_FUN(__clewFinish ) -#define clEnqueueReadBuffer CLEW_GET_FUN(__clewEnqueueReadBuffer ) -#define clEnqueueReadBufferRect CLEW_GET_FUN(__clewEnqueueReadBufferRect ) -#define clEnqueueWriteBuffer CLEW_GET_FUN(__clewEnqueueWriteBuffer ) -#define clEnqueueWriteBufferRect CLEW_GET_FUN(__clewEnqueueWriteBufferRect ) -#define clEnqueueCopyBuffer CLEW_GET_FUN(__clewEnqueueCopyBuffer ) -#define clEnqueueCopyBufferRect CLEW_GET_FUN(__clewEnqueueCopyBufferRect ) -#define clEnqueueReadImage CLEW_GET_FUN(__clewEnqueueReadImage ) -#define clEnqueueWriteImage CLEW_GET_FUN(__clewEnqueueWriteImage ) -#define clEnqueueCopyImage CLEW_GET_FUN(__clewEnqueueCopyImage ) -#define clEnqueueCopyImageToBuffer CLEW_GET_FUN(__clewEnqueueCopyImageToBuffer ) -#define clEnqueueCopyBufferToImage CLEW_GET_FUN(__clewEnqueueCopyBufferToImage ) -#define clEnqueueMapBuffer CLEW_GET_FUN(__clewEnqueueMapBuffer ) -#define clEnqueueMapImage CLEW_GET_FUN(__clewEnqueueMapImage ) -#define clEnqueueUnmapMemObject CLEW_GET_FUN(__clewEnqueueUnmapMemObject ) -#define clEnqueueNDRangeKernel CLEW_GET_FUN(__clewEnqueueNDRangeKernel ) -#define clEnqueueTask CLEW_GET_FUN(__clewEnqueueTask ) -#define clEnqueueNativeKernel CLEW_GET_FUN(__clewEnqueueNativeKernel ) -#define clEnqueueMarker CLEW_GET_FUN(__clewEnqueueMarker ) -#define clEnqueueWaitForEvents CLEW_GET_FUN(__clewEnqueueWaitForEvents ) -#define clEnqueueBarrier CLEW_GET_FUN(__clewEnqueueBarrier ) -#define clGetExtensionFunctionAddress CLEW_GET_FUN(__clewGetExtensionFunctionAddress ) +#define clCreateBuffer CLEW_GET_FUN(__clewCreateBuffer) +#define clCreateSubBuffer CLEW_GET_FUN(__clewCreateSubBuffer) +#define clCreateImage2D CLEW_GET_FUN(__clewCreateImage2D) +#define clCreateImage3D CLEW_GET_FUN(__clewCreateImage3D) +#define clRetainMemObject CLEW_GET_FUN(__clewRetainMemObject) +#define clReleaseMemObject CLEW_GET_FUN(__clewReleaseMemObject) +#define clGetSupportedImageFormats CLEW_GET_FUN(__clewGetSupportedImageFormats) +#define clGetMemObjectInfo CLEW_GET_FUN(__clewGetMemObjectInfo) +#define clGetImageInfo CLEW_GET_FUN(__clewGetImageInfo) +#define clSetMemObjectDestructorCallback CLEW_GET_FUN(__clewSetMemObjectDestructorCallback) +#define clCreateSampler CLEW_GET_FUN(__clewCreateSampler) +#define clRetainSampler CLEW_GET_FUN(__clewRetainSampler) +#define clReleaseSampler CLEW_GET_FUN(__clewReleaseSampler) +#define clGetSamplerInfo CLEW_GET_FUN(__clewGetSamplerInfo) +#define clCreateProgramWithSource CLEW_GET_FUN(__clewCreateProgramWithSource) +#define clCreateProgramWithBinary CLEW_GET_FUN(__clewCreateProgramWithBinary) +#define clRetainProgram CLEW_GET_FUN(__clewRetainProgram) +#define clReleaseProgram CLEW_GET_FUN(__clewReleaseProgram) +#define clBuildProgram CLEW_GET_FUN(__clewBuildProgram) +#define clUnloadCompiler CLEW_GET_FUN(__clewUnloadCompiler) +#define clGetProgramInfo CLEW_GET_FUN(__clewGetProgramInfo) +#define clGetProgramBuildInfo CLEW_GET_FUN(__clewGetProgramBuildInfo) +#define clCreateKernel CLEW_GET_FUN(__clewCreateKernel) +#define clCreateKernelsInProgram CLEW_GET_FUN(__clewCreateKernelsInProgram) +#define clRetainKernel CLEW_GET_FUN(__clewRetainKernel) +#define clReleaseKernel CLEW_GET_FUN(__clewReleaseKernel) +#define clSetKernelArg CLEW_GET_FUN(__clewSetKernelArg) +#define clGetKernelInfo CLEW_GET_FUN(__clewGetKernelInfo) +#define clGetKernelWorkGroupInfo CLEW_GET_FUN(__clewGetKernelWorkGroupInfo) +#define clWaitForEvents CLEW_GET_FUN(__clewWaitForEvents) +#define clGetEventInfo CLEW_GET_FUN(__clewGetEventInfo) +#define clCreateUserEvent CLEW_GET_FUN(__clewCreateUserEvent) +#define clRetainEvent CLEW_GET_FUN(__clewRetainEvent) +#define clReleaseEvent CLEW_GET_FUN(__clewReleaseEvent) +#define clSetUserEventStatus CLEW_GET_FUN(__clewSetUserEventStatus) +#define clSetEventCallback CLEW_GET_FUN(__clewSetEventCallback) +#define clGetEventProfilingInfo CLEW_GET_FUN(__clewGetEventProfilingInfo) +#define clFlush CLEW_GET_FUN(__clewFlush) +#define clFinish CLEW_GET_FUN(__clewFinish) +#define clEnqueueReadBuffer CLEW_GET_FUN(__clewEnqueueReadBuffer) +#define clEnqueueReadBufferRect CLEW_GET_FUN(__clewEnqueueReadBufferRect) +#define clEnqueueWriteBuffer CLEW_GET_FUN(__clewEnqueueWriteBuffer) +#define clEnqueueWriteBufferRect CLEW_GET_FUN(__clewEnqueueWriteBufferRect) +#define clEnqueueCopyBuffer CLEW_GET_FUN(__clewEnqueueCopyBuffer) +#define clEnqueueCopyBufferRect CLEW_GET_FUN(__clewEnqueueCopyBufferRect) +#define clEnqueueReadImage CLEW_GET_FUN(__clewEnqueueReadImage) +#define clEnqueueWriteImage CLEW_GET_FUN(__clewEnqueueWriteImage) +#define clEnqueueCopyImage CLEW_GET_FUN(__clewEnqueueCopyImage) +#define clEnqueueCopyImageToBuffer CLEW_GET_FUN(__clewEnqueueCopyImageToBuffer) +#define clEnqueueCopyBufferToImage CLEW_GET_FUN(__clewEnqueueCopyBufferToImage) +#define clEnqueueMapBuffer CLEW_GET_FUN(__clewEnqueueMapBuffer) +#define clEnqueueMapImage CLEW_GET_FUN(__clewEnqueueMapImage) +#define clEnqueueUnmapMemObject CLEW_GET_FUN(__clewEnqueueUnmapMemObject) +#define clEnqueueNDRangeKernel CLEW_GET_FUN(__clewEnqueueNDRangeKernel) +#define clEnqueueTask CLEW_GET_FUN(__clewEnqueueTask) +#define clEnqueueNativeKernel CLEW_GET_FUN(__clewEnqueueNativeKernel) +#define clEnqueueMarker CLEW_GET_FUN(__clewEnqueueMarker) +#define clEnqueueWaitForEvents CLEW_GET_FUN(__clewEnqueueWaitForEvents) +#define clEnqueueBarrier CLEW_GET_FUN(__clewEnqueueBarrier) +#define clGetExtensionFunctionAddress CLEW_GET_FUN(__clewGetExtensionFunctionAddress) +#define CLEW_SUCCESS 0 //!< Success error code +#define CLEW_ERROR_OPEN_FAILED -1 //!< Error code for failing to open the dynamic library +#define CLEW_ERROR_ATEXIT_FAILED -2 //!< Error code for failing to queue the closing of the dynamic library to atexit() -#define CLEW_SUCCESS 0 //!< Success error code -#define CLEW_ERROR_OPEN_FAILED -1 //!< Error code for failing to open the dynamic library -#define CLEW_ERROR_ATEXIT_FAILED -2 //!< Error code for failing to queue the closing of the dynamic library to atexit() + //! \brief Load OpenCL dynamic library and set function entry points + int clewInit(const char *); -//! \brief Load OpenCL dynamic library and set function entry points -int clewInit (const char*); + //! \brief Exit clew and unload OpenCL dynamic library + void clewExit(); -//! \brief Exit clew and unload OpenCL dynamic library -void clewExit(); - -//! \brief Convert an OpenCL error code to its string equivalent -const char* clewErrorString (cl_int error); + //! \brief Convert an OpenCL error code to its string equivalent + const char *clewErrorString(cl_int error); #ifdef __cplusplus } diff --git a/test/Bullet2/Source/TestList.cpp b/test/Bullet2/Source/TestList.cpp index 7e342b1bf..17d966271 100644 --- a/test/Bullet2/Source/TestList.cpp +++ b/test/Bullet2/Source/TestList.cpp @@ -42,7 +42,10 @@ #include "Test_quat_aos_neon.h" #include "LinearMath/btScalar.h" -#define ENTRY( _name, _func ) { _name, _func } +#define ENTRY(_name, _func) \ + { \ + _name, _func \ + } // // Test functions have the form int (*TestFunc)( void ) @@ -50,48 +53,46 @@ // // Please see handy stuff in Utils.h, vector.h when writing your test code. // -#if defined (BT_USE_NEON) || defined (BT_USE_SSE_IN_API) +#if defined(BT_USE_NEON) || defined(BT_USE_SSE_IN_API) -TestDesc gTestList[] = -{ - ENTRY( "maxdot", Test_maxdot ), - ENTRY( "mindot", Test_mindot ), +TestDesc gTestList[] = + { + ENTRY("maxdot", Test_maxdot), + ENTRY("mindot", Test_mindot), - ENTRY( "qtmul", Test_qtmul ), - ENTRY( "qtmulQV3", Test_qtmulQV3 ), - ENTRY( "qtmulV3Q", Test_qtmulV3Q ), - ENTRY( "qtdot", Test_qtdot ), - ENTRY( "qtnorm", Test_qtnorm ), + ENTRY("qtmul", Test_qtmul), + ENTRY("qtmulQV3", Test_qtmulQV3), + ENTRY("qtmulV3Q", Test_qtmulV3Q), + ENTRY("qtdot", Test_qtdot), + ENTRY("qtnorm", Test_qtnorm), - ENTRY( "v3dot", Test_v3dot ), - ENTRY( "v3sdiv", Test_v3sdiv ), - ENTRY( "v3norm", Test_v3norm ), - ENTRY( "v3cross", Test_v3cross ), - ENTRY( "v3triple", Test_v3triple ), - ENTRY( "v3interp", Test_v3interp ), - ENTRY( "v3lerp", Test_v3lerp ), - ENTRY( "v3skew", Test_v3skew ), - ENTRY( "v3div", Test_v3div ), - ENTRY( "v3rotate", Test_v3rotate ), + ENTRY("v3dot", Test_v3dot), + ENTRY("v3sdiv", Test_v3sdiv), + ENTRY("v3norm", Test_v3norm), + ENTRY("v3cross", Test_v3cross), + ENTRY("v3triple", Test_v3triple), + ENTRY("v3interp", Test_v3interp), + ENTRY("v3lerp", Test_v3lerp), + ENTRY("v3skew", Test_v3skew), + ENTRY("v3div", Test_v3div), + ENTRY("v3rotate", Test_v3rotate), - ENTRY( "dot3", Test_dot3 ), - ENTRY( "3x3transpose", Test_3x3transpose ), - ENTRY( "3x3transposeTimes", Test_3x3transposeTimes ), - ENTRY( "3x3timesTranspose", Test_3x3timesTranspose ), - ENTRY( "3x3mulM", Test_3x3mulM ), - ENTRY( "3x3mulM1M2", Test_3x3mulM1M2 ), - ENTRY( "3x3mulMV", Test_3x3mulMV ), - ENTRY( "3x3mulVM", Test_3x3mulMV ), - ENTRY( "3x3setRot", Test_3x3setRot ), - ENTRY( "3x3getRot", Test_3x3getRot ), - - ENTRY( "btDbvt", Test_btDbvt ), - ENTRY("quat_aos_neon", Test_quat_aos_neon), - - { NULL, NULL } -}; + ENTRY("dot3", Test_dot3), + ENTRY("3x3transpose", Test_3x3transpose), + ENTRY("3x3transposeTimes", Test_3x3transposeTimes), + ENTRY("3x3timesTranspose", Test_3x3timesTranspose), + ENTRY("3x3mulM", Test_3x3mulM), + ENTRY("3x3mulM1M2", Test_3x3mulM1M2), + ENTRY("3x3mulMV", Test_3x3mulMV), + ENTRY("3x3mulVM", Test_3x3mulMV), + ENTRY("3x3setRot", Test_3x3setRot), + ENTRY("3x3getRot", Test_3x3getRot), + + ENTRY("btDbvt", Test_btDbvt), + ENTRY("quat_aos_neon", Test_quat_aos_neon), + + {NULL, NULL}}; #else -TestDesc gTestList[]={{NULL,NULL}}; +TestDesc gTestList[] = {{NULL, NULL}}; #endif - diff --git a/test/Bullet2/Source/TestList.h b/test/Bullet2/Source/TestList.h index f66d4c67c..ac3381476 100644 --- a/test/Bullet2/Source/TestList.h +++ b/test/Bullet2/Source/TestList.h @@ -9,18 +9,18 @@ #define BulletTest_TestList_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif - -typedef struct TestDesc -{ - const char *name; - int (*test_func)(void); // return 0 for success, non-zero for failure -}TestDesc; + typedef struct TestDesc + { + const char *name; + int (*test_func)(void); // return 0 for success, non-zero for failure + } TestDesc; + + extern TestDesc gTestList[]; -extern TestDesc gTestList[]; - #ifdef __cplusplus } #endif diff --git a/test/Bullet2/Source/Tests/Test_3x3getRot.cpp b/test/Bullet2/Source/Tests/Test_3x3getRot.cpp index dbf2241e7..a49897245 100644 --- a/test/Bullet2/Source/Tests/Test_3x3getRot.cpp +++ b/test/Bullet2/Source/Tests/Test_3x3getRot.cpp @@ -5,9 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_3x3getRot.h" #include "vector.h" @@ -23,136 +22,136 @@ static inline btSimdFloat4 rand_f4(void) { - return btAssign128( RANDF_m1p1, RANDF_m1p1, RANDF_m1p1, BT_NAN ); // w channel NaN + return btAssign128(RANDF_m1p1, RANDF_m1p1, RANDF_m1p1, BT_NAN); // w channel NaN } static inline btSimdFloat4 qtNAN_f4(void) { - return btAssign128( BT_NAN, BT_NAN, BT_NAN, BT_NAN ); + return btAssign128(BT_NAN, BT_NAN, BT_NAN, BT_NAN); } -static void M3x3getRot_ref( const btMatrix3x3 &m, btQuaternion &q ) +static void M3x3getRot_ref(const btMatrix3x3 &m, btQuaternion &q) { - btVector3 m_el[3] = { m[0], m[1], m[2] }; + btVector3 m_el[3] = {m[0], m[1], m[2]}; - btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z(); + btScalar trace = m_el[0].x() + m_el[1].y() + m_el[2].z(); - btScalar temp[4]; + btScalar temp[4]; - if (trace > btScalar(0.0)) - { - btScalar s = btSqrt(trace + btScalar(1.0)); - temp[3]=(s * btScalar(0.5)); - s = btScalar(0.5) / s; + if (trace > btScalar(0.0)) + { + btScalar s = btSqrt(trace + btScalar(1.0)); + temp[3] = (s * btScalar(0.5)); + s = btScalar(0.5) / s; - temp[0]=((m_el[2].y() - m_el[1].z()) * s); - temp[1]=((m_el[0].z() - m_el[2].x()) * s); - temp[2]=((m_el[1].x() - m_el[0].y()) * s); - } - else - { - int i = m_el[0].x() < m_el[1].y() ? - (m_el[1].y() < m_el[2].z() ? 2 : 1) : - (m_el[0].x() < m_el[2].z() ? 2 : 0); - int j = (i + 1) % 3; - int k = (i + 2) % 3; + temp[0] = ((m_el[2].y() - m_el[1].z()) * s); + temp[1] = ((m_el[0].z() - m_el[2].x()) * s); + temp[2] = ((m_el[1].x() - m_el[0].y()) * s); + } + else + { + int i = m_el[0].x() < m_el[1].y() ? (m_el[1].y() < m_el[2].z() ? 2 : 1) : (m_el[0].x() < m_el[2].z() ? 2 : 0); + int j = (i + 1) % 3; + int k = (i + 2) % 3; - btScalar s = btSqrt(m_el[i][i] - m_el[j][j] - m_el[k][k] + btScalar(1.0)); - temp[i] = s * btScalar(0.5); - s = btScalar(0.5) / s; + btScalar s = btSqrt(m_el[i][i] - m_el[j][j] - m_el[k][k] + btScalar(1.0)); + temp[i] = s * btScalar(0.5); + s = btScalar(0.5) / s; - temp[3] = (m_el[k][j] - m_el[j][k]) * s; - temp[j] = (m_el[j][i] + m_el[i][j]) * s; - temp[k] = (m_el[k][i] + m_el[i][k]) * s; - } - q.setValue(temp[0],temp[1],temp[2],temp[3]); + temp[3] = (m_el[k][j] - m_el[j][k]) * s; + temp[j] = (m_el[j][i] + m_el[i][j]) * s; + temp[k] = (m_el[k][i] + m_el[i][k]) * s; + } + q.setValue(temp[0], temp[1], temp[2], temp[3]); } -static int operator!= ( const btQuaternion &a, const btQuaternion &b ) +static int operator!=(const btQuaternion &a, const btQuaternion &b) { - if( fabs(a.x() - b.x()) + - fabs(a.y() - b.y()) + - fabs(a.z() - b.z()) + - fabs(a.w() - b.w()) > FLT_EPSILON * 4) - return 1; - - return 0; + if (fabs(a.x() - b.x()) + + fabs(a.y() - b.y()) + + fabs(a.z() - b.z()) + + fabs(a.w() - b.w()) > + FLT_EPSILON * 4) + return 1; + + return 0; } int Test_3x3getRot(void) { - // Init an array flanked by guard pages - btMatrix3x3 in1[ARRAY_SIZE]; - btQuaternion out[ARRAY_SIZE]; - btQuaternion out2[ARRAY_SIZE]; - - // Init the data - size_t i, j; - for( i = 0; i < ARRAY_SIZE; i++ ) - { - in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); - out[i] = btQuaternion(qtNAN_f4()); - out2[i] = btQuaternion(qtNAN_f4()); - - M3x3getRot_ref(in1[i], out[i]); - in1[i].getRotation(out2[i]); + // Init an array flanked by guard pages + btMatrix3x3 in1[ARRAY_SIZE]; + btQuaternion out[ARRAY_SIZE]; + btQuaternion out2[ARRAY_SIZE]; - if( out[i] != out2[i] ) - { - vlog( "Error - M3x3getRot result error! "); - vlog( "failure @ %ld\n", i); - vlog( "\ncorrect = (%10.7f, %10.7f, %10.7f, %10.7f) " - "\ntested = (%10.7f, %10.7f, %10.7f, %10.7f) \n", - out[i].x(), out[i].y(), out[i].z(), out[i].w(), - out2[i].x(), out2[i].y(), out2[i].z(), out2[i].w()); - - return -1; - } - } - - uint64_t scalarTime, vectorTime; - uint64_t startTime, bestTime, currentTime; - bestTime = ~(bestTime&0);//-1ULL; - scalarTime = 0; - for (j = 0; j < LOOPCOUNT; j++) - { - startTime = ReadTicks(); - for( i = 0; i < ARRAY_SIZE; i++ ) - M3x3getRot_ref(in1[i], out[i]); - currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= LOOPCOUNT; - - bestTime = ~(bestTime&0);//-1ULL; - vectorTime = 0; - for (j = 0; j < LOOPCOUNT; j++) - { - startTime = ReadTicks(); - for( i = 0; i < ARRAY_SIZE; i++ ) - { - in1[i].getRotation(out2[i]); - } - currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= LOOPCOUNT; - - vlog( "Timing:\n" ); - vlog( "\t scalar\t vector\n" ); - vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE ); - - return 0; + // Init the data + size_t i, j; + for (i = 0; i < ARRAY_SIZE; i++) + { + in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4()); + out[i] = btQuaternion(qtNAN_f4()); + out2[i] = btQuaternion(qtNAN_f4()); + + M3x3getRot_ref(in1[i], out[i]); + in1[i].getRotation(out2[i]); + + if (out[i] != out2[i]) + { + vlog("Error - M3x3getRot result error! "); + vlog("failure @ %ld\n", i); + vlog( + "\ncorrect = (%10.7f, %10.7f, %10.7f, %10.7f) " + "\ntested = (%10.7f, %10.7f, %10.7f, %10.7f) \n", + out[i].x(), out[i].y(), out[i].z(), out[i].w(), + out2[i].x(), out2[i].y(), out2[i].z(), out2[i].w()); + + return -1; + } + } + + uint64_t scalarTime, vectorTime; + uint64_t startTime, bestTime, currentTime; + bestTime = ~(bestTime & 0); //-1ULL; + scalarTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for (i = 0; i < ARRAY_SIZE; i++) + M3x3getRot_ref(in1[i], out[i]); + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= LOOPCOUNT; + + bestTime = ~(bestTime & 0); //-1ULL; + vectorTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for (i = 0; i < ARRAY_SIZE; i++) + { + in1[i].getRotation(out2[i]); + } + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= LOOPCOUNT; + + vlog("Timing:\n"); + vlog("\t scalar\t vector\n"); + vlog("\t%10.2f\t%10.2f\n", TicksToCycles(scalarTime) / ARRAY_SIZE, TicksToCycles(vectorTime) / ARRAY_SIZE); + + return 0; } -#endif//BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_3x3getRot.h b/test/Bullet2/Source/Tests/Test_3x3getRot.h index 1998763bb..a8ab756f5 100644 --- a/test/Bullet2/Source/Tests/Test_3x3getRot.h +++ b/test/Bullet2/Source/Tests/Test_3x3getRot.h @@ -9,14 +9,14 @@ #define BulletTest_Test_3x3getRot_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_3x3getRot(void); + int Test_3x3getRot(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_3x3mulM.cpp b/test/Bullet2/Source/Tests/Test_3x3mulM.cpp index 51a013e1f..4648bffde 100644 --- a/test/Bullet2/Source/Tests/Test_3x3mulM.cpp +++ b/test/Bullet2/Source/Tests/Test_3x3mulM.cpp @@ -5,9 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_3x3mulM.h" #include "vector.h" @@ -23,147 +22,148 @@ static inline btSimdFloat4 rand_f4(void) { - return btAssign128( RANDF_01, RANDF_01, RANDF_01, BT_NAN ); // w channel NaN + return btAssign128(RANDF_01, RANDF_01, RANDF_01, BT_NAN); // w channel NaN } -static btMatrix3x3 M3x3mulM_ref( btMatrix3x3 &in, const btMatrix3x3 &m ) +static btMatrix3x3 M3x3mulM_ref(btMatrix3x3 &in, const btMatrix3x3 &m) { - btVector3 m_el[3] = { in[0], in[1], in[2] }; + btVector3 m_el[3] = {in[0], in[1], in[2]}; in.setValue( - m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]), + m.tdotx(m_el[0]), m.tdoty(m_el[0]), m.tdotz(m_el[0]), m.tdotx(m_el[1]), m.tdoty(m_el[1]), m.tdotz(m_el[1]), m.tdotx(m_el[2]), m.tdoty(m_el[2]), m.tdotz(m_el[2])); - return in; + return in; } -static SIMD_FORCE_INLINE bool fuzzyEqualSlow(const btVector3& ref, const btVector3& other) +static SIMD_FORCE_INLINE bool fuzzyEqualSlow(const btVector3 &ref, const btVector3 &other) { const btScalar epsilon = SIMD_EPSILON; - return ((btFabs(ref.m_floats[3]-other.m_floats[3])<=epsilon) && - (btFabs(ref.m_floats[2]-other.m_floats[2])<=epsilon) && - (btFabs(ref.m_floats[1]-other.m_floats[1])<=epsilon) && - (btFabs(ref.m_floats[0]-other.m_floats[0])<=epsilon)); + return ((btFabs(ref.m_floats[3] - other.m_floats[3]) <= epsilon) && + (btFabs(ref.m_floats[2] - other.m_floats[2]) <= epsilon) && + (btFabs(ref.m_floats[1] - other.m_floats[1]) <= epsilon) && + (btFabs(ref.m_floats[0] - other.m_floats[0]) <= epsilon)); } - -static int operator!= ( const btMatrix3x3 &a, const btMatrix3x3 &b ) +static int operator!=(const btMatrix3x3 &a, const btMatrix3x3 &b) { - if( a.getRow(0) != b.getRow(0) ) + if (a.getRow(0) != b.getRow(0)) { - if (!fuzzyEqualSlow(a.getRow(0),b.getRow(0))) + if (!fuzzyEqualSlow(a.getRow(0), b.getRow(0))) { return 1; } } - if( a.getRow(1) != b.getRow(1) ) + if (a.getRow(1) != b.getRow(1)) { - if( !fuzzyEqualSlow(a.getRow(1),b.getRow(1)) ) - return 1; + if (!fuzzyEqualSlow(a.getRow(1), b.getRow(1))) + return 1; } - if( a.getRow(2) != b.getRow(2) ) + if (a.getRow(2) != b.getRow(2)) { - if( !fuzzyEqualSlow(a.getRow(2),b.getRow(2)) ) + if (!fuzzyEqualSlow(a.getRow(2), b.getRow(2))) { return 1; } } - return 0; + return 0; } int Test_3x3mulM(void) { - // Init an array flanked by guard pages - btMatrix3x3 in1[ARRAY_SIZE]; - btMatrix3x3 in2[ARRAY_SIZE]; - btMatrix3x3 in3[ARRAY_SIZE]; - btMatrix3x3 out[ARRAY_SIZE]; - btMatrix3x3 out2[ARRAY_SIZE]; - - // Init the data - size_t i, j; - for( i = 0; i < ARRAY_SIZE; i++ ) - { - in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); - in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); - in3[i] = in1[i]; - - out[i] = M3x3mulM_ref(in1[i], in2[i]); - out2[i] = (in3[i] *= in2[i]); - - if( out[i] != out2[i] ) - { - vlog( "Error - M3x3mulM result error! "); - vlog( "failure @ %ld\n", i); - btVector3 m0, m1, m2; - m0 = out[i].getRow(0); - m1 = out[i].getRow(1); - m2 = out[i].getRow(2); - - vlog( "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " - "\n (%10.4f, %10.4f, %10.4f, %10.4f) " - "\n (%10.4f, %10.4f, %10.4f, %10.4f) \n", - m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], - m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], - m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + // Init an array flanked by guard pages + btMatrix3x3 in1[ARRAY_SIZE]; + btMatrix3x3 in2[ARRAY_SIZE]; + btMatrix3x3 in3[ARRAY_SIZE]; + btMatrix3x3 out[ARRAY_SIZE]; + btMatrix3x3 out2[ARRAY_SIZE]; - m0 = out2[i].getRow(0); - m1 = out2[i].getRow(1); - m2 = out2[i].getRow(2); - - vlog( "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) " - "\n (%10.4f, %10.4f, %10.4f, %10.4f) " - "\n (%10.4f, %10.4f, %10.4f, %10.4f) \n", - m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], - m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], - m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + // Init the data + size_t i, j; + for (i = 0; i < ARRAY_SIZE; i++) + { + in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4()); + in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4()); + in3[i] = in1[i]; - return -1; - } - } - - uint64_t scalarTime, vectorTime; - uint64_t startTime, bestTime, currentTime; - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < LOOPCOUNT; j++) - { - startTime = ReadTicks(); - for( i = 0; i < ARRAY_SIZE; i++ ) - out[i] = M3x3mulM_ref(in1[i], in2[i]); - currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= LOOPCOUNT; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < LOOPCOUNT; j++) - { - startTime = ReadTicks(); - for( i = 0; i < ARRAY_SIZE; i++ ) - out2[i] = (in3[i] *= in2[i]); - currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= LOOPCOUNT; - - vlog( "Timing:\n" ); - vlog( "\t scalar\t vector\n" ); - vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE ); - - return 0; + out[i] = M3x3mulM_ref(in1[i], in2[i]); + out2[i] = (in3[i] *= in2[i]); + + if (out[i] != out2[i]) + { + vlog("Error - M3x3mulM result error! "); + vlog("failure @ %ld\n", i); + btVector3 m0, m1, m2; + m0 = out[i].getRow(0); + m1 = out[i].getRow(1); + m2 = out[i].getRow(2); + + vlog( + "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) \n", + m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], + m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], + m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + + m0 = out2[i].getRow(0); + m1 = out2[i].getRow(1); + m2 = out2[i].getRow(2); + + vlog( + "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) \n", + m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], + m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], + m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + + return -1; + } + } + + uint64_t scalarTime, vectorTime; + uint64_t startTime, bestTime, currentTime; + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for (i = 0; i < ARRAY_SIZE; i++) + out[i] = M3x3mulM_ref(in1[i], in2[i]); + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= LOOPCOUNT; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for (i = 0; i < ARRAY_SIZE; i++) + out2[i] = (in3[i] *= in2[i]); + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= LOOPCOUNT; + + vlog("Timing:\n"); + vlog("\t scalar\t vector\n"); + vlog("\t%10.2f\t%10.2f\n", TicksToCycles(scalarTime) / ARRAY_SIZE, TicksToCycles(vectorTime) / ARRAY_SIZE); + + return 0; } -#endif //BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_3x3mulM.h b/test/Bullet2/Source/Tests/Test_3x3mulM.h index fb5128e66..3815585b9 100644 --- a/test/Bullet2/Source/Tests/Test_3x3mulM.h +++ b/test/Bullet2/Source/Tests/Test_3x3mulM.h @@ -9,14 +9,14 @@ #define BulletTest_Test_3x3mulM_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_3x3mulM(void); + int Test_3x3mulM(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_3x3mulM1M2.cpp b/test/Bullet2/Source/Tests/Test_3x3mulM1M2.cpp index c435c546c..00f08b869 100644 --- a/test/Bullet2/Source/Tests/Test_3x3mulM1M2.cpp +++ b/test/Bullet2/Source/Tests/Test_3x3mulM1M2.cpp @@ -5,10 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_3x3mulM1M2.h" #include "vector.h" @@ -24,141 +22,142 @@ static inline btSimdFloat4 rand_f4(void) { - return btAssign128( RANDF_01, RANDF_01, RANDF_01, BT_NAN ); // w channel NaN + return btAssign128(RANDF_01, RANDF_01, RANDF_01, BT_NAN); // w channel NaN } -static btMatrix3x3 M3x3mulM1M2_ref( const btMatrix3x3 &m1, const btMatrix3x3 &m2 ) +static btMatrix3x3 M3x3mulM1M2_ref(const btMatrix3x3 &m1, const btMatrix3x3 &m2) { return btMatrix3x3( - m2.tdotx(m1[0]), m2.tdoty(m1[0]), m2.tdotz(m1[0]), + m2.tdotx(m1[0]), m2.tdoty(m1[0]), m2.tdotz(m1[0]), m2.tdotx(m1[1]), m2.tdoty(m1[1]), m2.tdotz(m1[1]), m2.tdotx(m1[2]), m2.tdoty(m1[2]), m2.tdotz(m1[2])); } -static bool fuzzyEqualSlow(const btVector3& ref, const btVector3& other) +static bool fuzzyEqualSlow(const btVector3 &ref, const btVector3 &other) { const btScalar epsilon = SIMD_EPSILON; - return ((btFabs(ref.m_floats[3]-other.m_floats[3])<=epsilon) && - (btFabs(ref.m_floats[2]-other.m_floats[2])<=epsilon) && - (btFabs(ref.m_floats[1]-other.m_floats[1])<=epsilon) && - (btFabs(ref.m_floats[0]-other.m_floats[0])<=epsilon)); + return ((btFabs(ref.m_floats[3] - other.m_floats[3]) <= epsilon) && + (btFabs(ref.m_floats[2] - other.m_floats[2]) <= epsilon) && + (btFabs(ref.m_floats[1] - other.m_floats[1]) <= epsilon) && + (btFabs(ref.m_floats[0] - other.m_floats[0]) <= epsilon)); } - -static int operator!= ( const btMatrix3x3 &a, const btMatrix3x3 &b ) +static int operator!=(const btMatrix3x3 &a, const btMatrix3x3 &b) { - if( a.getRow(0) != b.getRow(0) ) + if (a.getRow(0) != b.getRow(0)) { - if (!fuzzyEqualSlow(a.getRow(0),b.getRow(0))) + if (!fuzzyEqualSlow(a.getRow(0), b.getRow(0))) { return 1; } } - if( a.getRow(1) != b.getRow(1) ) + if (a.getRow(1) != b.getRow(1)) { - if( !fuzzyEqualSlow(a.getRow(1),b.getRow(1)) ) - return 1; + if (!fuzzyEqualSlow(a.getRow(1), b.getRow(1))) + return 1; } - if( a.getRow(2) != b.getRow(2) ) + if (a.getRow(2) != b.getRow(2)) { - if( !fuzzyEqualSlow(a.getRow(2),b.getRow(2)) ) + if (!fuzzyEqualSlow(a.getRow(2), b.getRow(2))) { return 1; } } - return 0; + return 0; } int Test_3x3mulM1M2(void) { - // Init an array flanked by guard pages - btMatrix3x3 in1[ARRAY_SIZE]; - btMatrix3x3 in2[ARRAY_SIZE]; - btMatrix3x3 out[ARRAY_SIZE]; - btMatrix3x3 out2[ARRAY_SIZE]; - - // Init the data - size_t i, j; - for( i = 0; i < ARRAY_SIZE; i++ ) - { - in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); - in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); - - out[i] = M3x3mulM1M2_ref(in1[i], in2[i]); - out2[i] = (in1[i] * in2[i]); - - if( out[i] != out2[i] ) - { - vlog( "Error - M3x3mulM1M2 result error! "); - vlog( "failure @ %ld\n", i); - btVector3 m0, m1, m2; - m0 = out[i].getRow(0); - m1 = out[i].getRow(1); - m2 = out[i].getRow(2); - - vlog( "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " - "\n (%10.4f, %10.4f, %10.4f, %10.4f) " - "\n (%10.4f, %10.4f, %10.4f, %10.4f) \n", - m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], - m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], - m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + // Init an array flanked by guard pages + btMatrix3x3 in1[ARRAY_SIZE]; + btMatrix3x3 in2[ARRAY_SIZE]; + btMatrix3x3 out[ARRAY_SIZE]; + btMatrix3x3 out2[ARRAY_SIZE]; - m0 = out2[i].getRow(0); - m1 = out2[i].getRow(1); - m2 = out2[i].getRow(2); - - vlog( "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) " - "\n (%10.4f, %10.4f, %10.4f, %10.4f) " - "\n (%10.4f, %10.4f, %10.4f, %10.4f) \n", - m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], - m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], - m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + // Init the data + size_t i, j; + for (i = 0; i < ARRAY_SIZE; i++) + { + in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4()); + in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4()); - return -1; - } - } - - uint64_t scalarTime, vectorTime; - uint64_t startTime, bestTime, currentTime; - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < LOOPCOUNT; j++) - { - startTime = ReadTicks(); - for( i = 0; i < ARRAY_SIZE; i++ ) - out[i] = M3x3mulM1M2_ref(in1[i], in2[i]); - currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= LOOPCOUNT; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < LOOPCOUNT; j++) - { - startTime = ReadTicks(); - for( i = 0; i < ARRAY_SIZE; i++ ) - out2[i] = (in1[i] * in2[i]); - currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= LOOPCOUNT; - - vlog( "Timing:\n" ); - vlog( "\t scalar\t vector\n" ); - vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE ); - - return 0; + out[i] = M3x3mulM1M2_ref(in1[i], in2[i]); + out2[i] = (in1[i] * in2[i]); + + if (out[i] != out2[i]) + { + vlog("Error - M3x3mulM1M2 result error! "); + vlog("failure @ %ld\n", i); + btVector3 m0, m1, m2; + m0 = out[i].getRow(0); + m1 = out[i].getRow(1); + m2 = out[i].getRow(2); + + vlog( + "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) \n", + m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], + m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], + m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + + m0 = out2[i].getRow(0); + m1 = out2[i].getRow(1); + m2 = out2[i].getRow(2); + + vlog( + "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) \n", + m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], + m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], + m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + + return -1; + } + } + + uint64_t scalarTime, vectorTime; + uint64_t startTime, bestTime, currentTime; + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for (i = 0; i < ARRAY_SIZE; i++) + out[i] = M3x3mulM1M2_ref(in1[i], in2[i]); + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= LOOPCOUNT; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for (i = 0; i < ARRAY_SIZE; i++) + out2[i] = (in1[i] * in2[i]); + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= LOOPCOUNT; + + vlog("Timing:\n"); + vlog("\t scalar\t vector\n"); + vlog("\t%10.2f\t%10.2f\n", TicksToCycles(scalarTime) / ARRAY_SIZE, TicksToCycles(vectorTime) / ARRAY_SIZE); + + return 0; } -#endif //BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_3x3mulM1M2.h b/test/Bullet2/Source/Tests/Test_3x3mulM1M2.h index a3075bd86..3c4d1fbcb 100644 --- a/test/Bullet2/Source/Tests/Test_3x3mulM1M2.h +++ b/test/Bullet2/Source/Tests/Test_3x3mulM1M2.h @@ -9,14 +9,14 @@ #define BulletTest_Test_3x3mulM1M2_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_3x3mulM1M2(void); + int Test_3x3mulM1M2(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_3x3mulMV.cpp b/test/Bullet2/Source/Tests/Test_3x3mulMV.cpp index ba07831e3..b2edc3c76 100644 --- a/test/Bullet2/Source/Tests/Test_3x3mulMV.cpp +++ b/test/Bullet2/Source/Tests/Test_3x3mulMV.cpp @@ -5,11 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_3x3mulMV.h" #include "vector.h" @@ -25,88 +22,90 @@ static inline btSimdFloat4 rand_f4(void) { - return btAssign128(RANDF_01, RANDF_01, RANDF_01, BT_NAN ); // w channel NaN + return btAssign128(RANDF_01, RANDF_01, RANDF_01, BT_NAN); // w channel NaN } -static btVector3 M3x3mulMV_ref( const btMatrix3x3 &m, const btVector3 &v ) +static btVector3 M3x3mulMV_ref(const btMatrix3x3 &m, const btVector3 &v) { return btVector3(m[0].dot(v), m[1].dot(v), m[2].dot(v)); } int Test_3x3mulMV(void) { - // Init an array flanked by guard pages - btMatrix3x3 in1[ARRAY_SIZE]; - btVector3 in2[ARRAY_SIZE]; - btVector3 out[ARRAY_SIZE]; - btVector3 out2[ARRAY_SIZE]; - - // Init the data - size_t i, j; - for( i = 0; i < ARRAY_SIZE; i++ ) - { - in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); - in2[i] = btVector3(rand_f4()); - - out[i] = M3x3mulMV_ref(in1[i], in2[i]); - out2[i] = (in1[i] * in2[i]); + // Init an array flanked by guard pages + btMatrix3x3 in1[ARRAY_SIZE]; + btVector3 in2[ARRAY_SIZE]; + btVector3 out[ARRAY_SIZE]; + btVector3 out2[ARRAY_SIZE]; + + // Init the data + size_t i, j; + for (i = 0; i < ARRAY_SIZE; i++) + { + in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4()); + in2[i] = btVector3(rand_f4()); + + out[i] = M3x3mulMV_ref(in1[i], in2[i]); + out2[i] = (in1[i] * in2[i]); + + if (fabsf(out[i].m_floats[0] - out2[i].m_floats[0]) + + fabsf(out[i].m_floats[1] - out2[i].m_floats[1]) + + fabsf(out[i].m_floats[2] - out2[i].m_floats[2]) + + fabsf(out[i].m_floats[3] - out2[i].m_floats[3]) > + FLT_EPSILON * 4) + { + vlog("Error - M3x3mulMV result error! "); + vlog("failure @ %ld\n", i); + vlog( + "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) \n", + out[i].m_floats[0], out[i].m_floats[1], out[i].m_floats[2], out[i].m_floats[3], + out2[i].m_floats[0], out2[i].m_floats[1], out2[i].m_floats[2], out2[i].m_floats[3]); - if( fabsf(out[i].m_floats[0] - out2[i].m_floats[0]) + - fabsf(out[i].m_floats[1] - out2[i].m_floats[1]) + - fabsf(out[i].m_floats[2] - out2[i].m_floats[2]) + - fabsf(out[i].m_floats[3] - out2[i].m_floats[3]) > FLT_EPSILON*4 ) - { - vlog( "Error - M3x3mulMV result error! "); - vlog( "failure @ %ld\n", i); - vlog( "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " - "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) \n", - out[i].m_floats[0], out[i].m_floats[1], out[i].m_floats[2], out[i].m_floats[3], - out2[i].m_floats[0], out2[i].m_floats[1], out2[i].m_floats[2], out2[i].m_floats[3]); - return 1; } - } - - uint64_t scalarTime, vectorTime; - uint64_t startTime, bestTime, currentTime; - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < LOOPCOUNT; j++) - { - startTime = ReadTicks(); - for( i = 0; i < ARRAY_SIZE; i++ ) - out[i] = M3x3mulMV_ref(in1[i], in2[i]); - currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= LOOPCOUNT; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < LOOPCOUNT; j++) - { - startTime = ReadTicks(); - for( i = 0; i < ARRAY_SIZE; i++ ) - out2[i] = (in1[i] * in2[i]); - currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= LOOPCOUNT; - - vlog( "Timing:\n" ); - vlog( "\t scalar\t vector\n" ); - vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE ); - - return 0; + } + + uint64_t scalarTime, vectorTime; + uint64_t startTime, bestTime, currentTime; + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for (i = 0; i < ARRAY_SIZE; i++) + out[i] = M3x3mulMV_ref(in1[i], in2[i]); + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= LOOPCOUNT; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for (i = 0; i < ARRAY_SIZE; i++) + out2[i] = (in1[i] * in2[i]); + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= LOOPCOUNT; + + vlog("Timing:\n"); + vlog("\t scalar\t vector\n"); + vlog("\t%10.2f\t%10.2f\n", TicksToCycles(scalarTime) / ARRAY_SIZE, TicksToCycles(vectorTime) / ARRAY_SIZE); + + return 0; } -#endif //BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_3x3mulMV.h b/test/Bullet2/Source/Tests/Test_3x3mulMV.h index 877380d3d..b99bb7aa2 100644 --- a/test/Bullet2/Source/Tests/Test_3x3mulMV.h +++ b/test/Bullet2/Source/Tests/Test_3x3mulMV.h @@ -9,15 +9,14 @@ #define BulletTest_Test_3x3mulMV_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_3x3mulMV(void); + int Test_3x3mulMV(void); #ifdef __cplusplus } #endif - #endif - diff --git a/test/Bullet2/Source/Tests/Test_3x3mulVM.cpp b/test/Bullet2/Source/Tests/Test_3x3mulVM.cpp index 86db895ca..a4813a1b8 100644 --- a/test/Bullet2/Source/Tests/Test_3x3mulVM.cpp +++ b/test/Bullet2/Source/Tests/Test_3x3mulVM.cpp @@ -5,11 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_3x3mulVM.h" #include "vector.h" @@ -25,88 +22,90 @@ static inline btSimdFloat4 rand_f4(void) { - return btAssign128( RANDF_01, RANDF_01, RANDF_01, BT_NAN ); // w channel NaN + return btAssign128(RANDF_01, RANDF_01, RANDF_01, BT_NAN); // w channel NaN } -static btVector3 M3x3mulVM_ref( const btVector3 &v, const btMatrix3x3 &m) +static btVector3 M3x3mulVM_ref(const btVector3 &v, const btMatrix3x3 &m) { return btVector3(m.tdotx(v), m.tdoty(v), m.tdotz(v)); } int Test_3x3mulVM(void) { - // Init an array flanked by guard pages - btVector3 in1[ARRAY_SIZE]; - btMatrix3x3 in2[ARRAY_SIZE]; - btVector3 out[ARRAY_SIZE]; - btVector3 out2[ARRAY_SIZE]; - - // Init the data - size_t i, j; - for( i = 0; i < ARRAY_SIZE; i++ ) - { - in1[i] = btVector3(rand_f4()); - in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); - - out[i] = M3x3mulVM_ref(in1[i], in2[i]); - out2[i] = (in1[i] * in2[i]); + // Init an array flanked by guard pages + btVector3 in1[ARRAY_SIZE]; + btMatrix3x3 in2[ARRAY_SIZE]; + btVector3 out[ARRAY_SIZE]; + btVector3 out2[ARRAY_SIZE]; + + // Init the data + size_t i, j; + for (i = 0; i < ARRAY_SIZE; i++) + { + in1[i] = btVector3(rand_f4()); + in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4()); + + out[i] = M3x3mulVM_ref(in1[i], in2[i]); + out2[i] = (in1[i] * in2[i]); + + if (fabsf(out[i].m_floats[0] - out2[i].m_floats[0]) + + fabsf(out[i].m_floats[1] - out2[i].m_floats[1]) + + fabsf(out[i].m_floats[2] - out2[i].m_floats[2]) + + fabsf(out[i].m_floats[3] - out2[i].m_floats[3]) > + FLT_EPSILON * 4) + { + vlog("Error - M3x3mulVM result error! "); + vlog("failure @ %ld\n", i); + vlog( + "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) \n", + out[i].m_floats[0], out[i].m_floats[1], out[i].m_floats[2], out[i].m_floats[3], + out2[i].m_floats[0], out2[i].m_floats[1], out2[i].m_floats[2], out2[i].m_floats[3]); - if( fabsf(out[i].m_floats[0] - out2[i].m_floats[0]) + - fabsf(out[i].m_floats[1] - out2[i].m_floats[1]) + - fabsf(out[i].m_floats[2] - out2[i].m_floats[2]) + - fabsf(out[i].m_floats[3] - out2[i].m_floats[3]) > FLT_EPSILON*4 ) - { - vlog( "Error - M3x3mulVM result error! "); - vlog( "failure @ %ld\n", i); - vlog( "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " - "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) \n", - out[i].m_floats[0], out[i].m_floats[1], out[i].m_floats[2], out[i].m_floats[3], - out2[i].m_floats[0], out2[i].m_floats[1], out2[i].m_floats[2], out2[i].m_floats[3]); - return 1; } - } - - uint64_t scalarTime, vectorTime; - uint64_t startTime, bestTime, currentTime; - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < LOOPCOUNT; j++) - { - startTime = ReadTicks(); - for( i = 0; i < ARRAY_SIZE; i++ ) - out[i] = M3x3mulVM_ref(in1[i], in2[i]); - currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= LOOPCOUNT; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < LOOPCOUNT; j++) - { - startTime = ReadTicks(); - for( i = 0; i < ARRAY_SIZE; i++ ) - out2[i] = (in1[i] * in2[i]); - currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= LOOPCOUNT; - - vlog( "Timing:\n" ); - vlog( "\t scalar\t vector\n" ); - vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE ); - - return 0; + } + + uint64_t scalarTime, vectorTime; + uint64_t startTime, bestTime, currentTime; + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for (i = 0; i < ARRAY_SIZE; i++) + out[i] = M3x3mulVM_ref(in1[i], in2[i]); + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= LOOPCOUNT; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for (i = 0; i < ARRAY_SIZE; i++) + out2[i] = (in1[i] * in2[i]); + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= LOOPCOUNT; + + vlog("Timing:\n"); + vlog("\t scalar\t vector\n"); + vlog("\t%10.2f\t%10.2f\n", TicksToCycles(scalarTime) / ARRAY_SIZE, TicksToCycles(vectorTime) / ARRAY_SIZE); + + return 0; } -#endif //BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_3x3mulVM.h b/test/Bullet2/Source/Tests/Test_3x3mulVM.h index 81c34df89..c569472db 100644 --- a/test/Bullet2/Source/Tests/Test_3x3mulVM.h +++ b/test/Bullet2/Source/Tests/Test_3x3mulVM.h @@ -9,14 +9,14 @@ #define BulletTest_Test_3x3mulVM_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_3x3mulVM(void); + int Test_3x3mulVM(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_3x3setRot.cpp b/test/Bullet2/Source/Tests/Test_3x3setRot.cpp index 49f177521..1a4581e9c 100644 --- a/test/Bullet2/Source/Tests/Test_3x3setRot.cpp +++ b/test/Bullet2/Source/Tests/Test_3x3setRot.cpp @@ -5,10 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_3x3setRot.h" #include "vector.h" @@ -24,148 +22,149 @@ static inline btSimdFloat4 rand_f4(void) { - return btAssign128( RANDF_01, RANDF_01, RANDF_01, BT_NAN ); // w channel NaN + return btAssign128(RANDF_01, RANDF_01, RANDF_01, BT_NAN); // w channel NaN } static inline btSimdFloat4 qtrand_f4(void) { - return btAssign128( RANDF_01, RANDF_01, RANDF_01, RANDF_01 ); + return btAssign128(RANDF_01, RANDF_01, RANDF_01, RANDF_01); } -static btMatrix3x3 M3x3setRot_ref( btMatrix3x3 &m, const btQuaternion &q ) +static btMatrix3x3 M3x3setRot_ref(btMatrix3x3 &m, const btQuaternion &q) { - btScalar d = q.length2(); - btScalar s = btScalar(2.0) / d; + btScalar d = q.length2(); + btScalar s = btScalar(2.0) / d; - btScalar xs = q.x() * s, ys = q.y() * s, zs = q.z() * s; - - btScalar wx = q.w() * xs, wy = q.w() * ys, wz = q.w() * zs; - btScalar xx = q.x() * xs, xy = q.x() * ys, xz = q.x() * zs; - btScalar yy = q.y() * ys, yz = q.y() * zs, zz = q.z() * zs; - m.setValue( - btScalar(1.0) - (yy + zz), xy - wz, xz + wy, - xy + wz, btScalar(1.0) - (xx + zz), yz - wx, - xz - wy, yz + wx, btScalar(1.0) - (xx + yy)); + btScalar xs = q.x() * s, ys = q.y() * s, zs = q.z() * s; - return m; + btScalar wx = q.w() * xs, wy = q.w() * ys, wz = q.w() * zs; + btScalar xx = q.x() * xs, xy = q.x() * ys, xz = q.x() * zs; + btScalar yy = q.y() * ys, yz = q.y() * zs, zz = q.z() * zs; + m.setValue( + btScalar(1.0) - (yy + zz), xy - wz, xz + wy, + xy + wz, btScalar(1.0) - (xx + zz), yz - wx, + xz - wy, yz + wx, btScalar(1.0) - (xx + yy)); + + return m; } - -static int operator!= ( const btMatrix3x3 &a, const btMatrix3x3 &b ) +static int operator!=(const btMatrix3x3 &a, const btMatrix3x3 &b) { - int i; - btVector3 av3, bv3; + int i; + btVector3 av3, bv3; - for(i=0; i<3; i++) - { - av3 = a.getRow(i); - bv3 = b.getRow(i); - - if( fabs(av3.m_floats[0] - bv3.m_floats[0]) + - fabs(av3.m_floats[1] - bv3.m_floats[1]) + - fabs(av3.m_floats[2] - bv3.m_floats[2]) > FLT_EPSILON * 4) - return 1; - } - - return 0; + for (i = 0; i < 3; i++) + { + av3 = a.getRow(i); + bv3 = b.getRow(i); + + if (fabs(av3.m_floats[0] - bv3.m_floats[0]) + + fabs(av3.m_floats[1] - bv3.m_floats[1]) + + fabs(av3.m_floats[2] - bv3.m_floats[2]) > + FLT_EPSILON * 4) + return 1; + } + + return 0; } int Test_3x3setRot(void) { - // Init an array flanked by guard pages - btMatrix3x3 in1[ARRAY_SIZE]; - btQuaternion in2[ARRAY_SIZE]; - btMatrix3x3 in3[ARRAY_SIZE]; - btMatrix3x3 out[ARRAY_SIZE]; - btMatrix3x3 out2[ARRAY_SIZE]; - - // Init the data - size_t i, j; - for( i = 0; i < ARRAY_SIZE; i++ ) - { - in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); - in2[i] = btQuaternion(qtrand_f4()); - in3[i] = in1[i]; - - out[i] = M3x3setRot_ref(in1[i], in2[i]); - in3[i].setRotation(in2[i]); - out2[i] = in3[i]; + // Init an array flanked by guard pages + btMatrix3x3 in1[ARRAY_SIZE]; + btQuaternion in2[ARRAY_SIZE]; + btMatrix3x3 in3[ARRAY_SIZE]; + btMatrix3x3 out[ARRAY_SIZE]; + btMatrix3x3 out2[ARRAY_SIZE]; - if( out[i] != out2[i] ) - { - vlog( "Error - M3x3setRot result error! "); - vlog( "failure @ %ld\n", i); - btVector3 m0, m1, m2; - m0 = out[i].getRow(0); - m1 = out[i].getRow(1); - m2 = out[i].getRow(2); - - vlog( "\ncorrect = (%10.7f, %10.7f, %10.7f, %10.7f) " - "\n (%10.7f, %10.7f, %10.7f, %10.7f) " - "\n (%10.7f, %10.7f, %10.7f, %10.7f) \n", - m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], - m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], - m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + // Init the data + size_t i, j; + for (i = 0; i < ARRAY_SIZE; i++) + { + in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4()); + in2[i] = btQuaternion(qtrand_f4()); + in3[i] = in1[i]; - m0 = out2[i].getRow(0); - m1 = out2[i].getRow(1); - m2 = out2[i].getRow(2); - - vlog( "\ntested = (%10.7f, %10.7f, %10.7f, %10.7f) " - "\n (%10.7f, %10.7f, %10.7f, %10.7f) " - "\n (%10.7f, %10.7f, %10.7f, %10.7f) \n", - m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], - m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], - m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + out[i] = M3x3setRot_ref(in1[i], in2[i]); + in3[i].setRotation(in2[i]); + out2[i] = in3[i]; - return -1; - } - } - - uint64_t scalarTime, vectorTime; - uint64_t startTime, bestTime, currentTime; - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < LOOPCOUNT; j++) - { - startTime = ReadTicks(); - for( i = 0; i < ARRAY_SIZE; i++ ) - out[i] = M3x3setRot_ref(in1[i], in2[i]); - currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= LOOPCOUNT; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < LOOPCOUNT; j++) - { - startTime = ReadTicks(); - for( i = 0; i < ARRAY_SIZE; i++ ) - { - in3[i].setRotation(in2[i]); - out2[i] = in3[i]; - } - currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= LOOPCOUNT; - - vlog( "Timing:\n" ); - vlog( "\t scalar\t vector\n" ); - vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE ); - - return 0; + if (out[i] != out2[i]) + { + vlog("Error - M3x3setRot result error! "); + vlog("failure @ %ld\n", i); + btVector3 m0, m1, m2; + m0 = out[i].getRow(0); + m1 = out[i].getRow(1); + m2 = out[i].getRow(2); + + vlog( + "\ncorrect = (%10.7f, %10.7f, %10.7f, %10.7f) " + "\n (%10.7f, %10.7f, %10.7f, %10.7f) " + "\n (%10.7f, %10.7f, %10.7f, %10.7f) \n", + m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], + m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], + m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + + m0 = out2[i].getRow(0); + m1 = out2[i].getRow(1); + m2 = out2[i].getRow(2); + + vlog( + "\ntested = (%10.7f, %10.7f, %10.7f, %10.7f) " + "\n (%10.7f, %10.7f, %10.7f, %10.7f) " + "\n (%10.7f, %10.7f, %10.7f, %10.7f) \n", + m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], + m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], + m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + + return -1; + } + } + + uint64_t scalarTime, vectorTime; + uint64_t startTime, bestTime, currentTime; + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for (i = 0; i < ARRAY_SIZE; i++) + out[i] = M3x3setRot_ref(in1[i], in2[i]); + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= LOOPCOUNT; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for (i = 0; i < ARRAY_SIZE; i++) + { + in3[i].setRotation(in2[i]); + out2[i] = in3[i]; + } + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= LOOPCOUNT; + + vlog("Timing:\n"); + vlog("\t scalar\t vector\n"); + vlog("\t%10.2f\t%10.2f\n", TicksToCycles(scalarTime) / ARRAY_SIZE, TicksToCycles(vectorTime) / ARRAY_SIZE); + + return 0; } -#endif //BT_USE_SSE - +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_3x3setRot.h b/test/Bullet2/Source/Tests/Test_3x3setRot.h index aac0ebf9a..7325dfb60 100644 --- a/test/Bullet2/Source/Tests/Test_3x3setRot.h +++ b/test/Bullet2/Source/Tests/Test_3x3setRot.h @@ -9,14 +9,14 @@ #define BulletTest_Test_3x3setRot_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_3x3setRot(void); + int Test_3x3setRot(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_3x3timesTranspose.cpp b/test/Bullet2/Source/Tests/Test_3x3timesTranspose.cpp index 70e12e4ad..049731556 100644 --- a/test/Bullet2/Source/Tests/Test_3x3timesTranspose.cpp +++ b/test/Bullet2/Source/Tests/Test_3x3timesTranspose.cpp @@ -5,11 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_3x3timesTranspose.h" #include "vector.h" @@ -25,93 +22,95 @@ static inline btSimdFloat4 rand_f4(void) { - return btAssign128( RANDF, RANDF, RANDF, BT_NAN ); // w channel NaN + return btAssign128(RANDF, RANDF, RANDF, BT_NAN); // w channel NaN } -static btMatrix3x3 timesTranspose( const btMatrix3x3 &in, const btMatrix3x3 &m ) +static btMatrix3x3 timesTranspose(const btMatrix3x3 &in, const btMatrix3x3 &m) { - btVector3 m_el[3] = { in[0], in[1], in[2] }; + btVector3 m_el[3] = {in[0], in[1], in[2]}; return btMatrix3x3( - m_el[0].dot(m[0]), m_el[0].dot(m[1]), m_el[0].dot(m[2]), - m_el[1].dot(m[0]), m_el[1].dot(m[1]), m_el[1].dot(m[2]), - m_el[2].dot(m[0]), m_el[2].dot(m[1]), m_el[2].dot(m[2])); + m_el[0].dot(m[0]), m_el[0].dot(m[1]), m_el[0].dot(m[2]), + m_el[1].dot(m[0]), m_el[1].dot(m[1]), m_el[1].dot(m[2]), + m_el[2].dot(m[0]), m_el[2].dot(m[1]), m_el[2].dot(m[2])); } -static int operator!= ( const btMatrix3x3 &a, const btMatrix3x3 &b ) +static int operator!=(const btMatrix3x3 &a, const btMatrix3x3 &b) { - if( a.getRow(0) != b.getRow(0) ) - return 1; - if( a.getRow(1) != b.getRow(1) ) - return 1; - if( a.getRow(2) != b.getRow(2) ) - return 1; - return 0; + if (a.getRow(0) != b.getRow(0)) + return 1; + if (a.getRow(1) != b.getRow(1)) + return 1; + if (a.getRow(2) != b.getRow(2)) + return 1; + return 0; } int Test_3x3timesTranspose(void) { - // Init an array flanked by guard pages - btMatrix3x3 in1[ARRAY_SIZE]; - btMatrix3x3 in2[ARRAY_SIZE]; - btMatrix3x3 out[ARRAY_SIZE]; - btMatrix3x3 out2[ARRAY_SIZE]; - - // Init the data - size_t i, j; - for( i = 0; i < ARRAY_SIZE; i++ ) - { - in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); - in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); - - out[i] = timesTranspose(in1[i], in2[i]); - out2[i] = in1[i].timesTranspose(in2[i]); - - if( out[i] != out2[i] ) - { - printf( "failure @ %ld\n", i); - return -1; - } - } - - uint64_t scalarTime, vectorTime; - uint64_t startTime, bestTime, currentTime; - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < LOOPCOUNT; j++) { - startTime = ReadTicks(); - for( i = 0; i < ARRAY_SIZE; i++ ) - out[i] = timesTranspose(in1[i], in2[i]); - currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= LOOPCOUNT; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < LOOPCOUNT; j++) { - startTime = ReadTicks(); - for( i = 0; i < ARRAY_SIZE; i++ ) - out[i] = in1[i].timesTranspose(in2[i]); - currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= LOOPCOUNT; - - vlog( "Timing:\n" ); - vlog( "\t scalar\t vector\n" ); - vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE ); - - return 0; + // Init an array flanked by guard pages + btMatrix3x3 in1[ARRAY_SIZE]; + btMatrix3x3 in2[ARRAY_SIZE]; + btMatrix3x3 out[ARRAY_SIZE]; + btMatrix3x3 out2[ARRAY_SIZE]; + + // Init the data + size_t i, j; + for (i = 0; i < ARRAY_SIZE; i++) + { + in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4()); + in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4()); + + out[i] = timesTranspose(in1[i], in2[i]); + out2[i] = in1[i].timesTranspose(in2[i]); + + if (out[i] != out2[i]) + { + printf("failure @ %ld\n", i); + return -1; + } + } + + uint64_t scalarTime, vectorTime; + uint64_t startTime, bestTime, currentTime; + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for (i = 0; i < ARRAY_SIZE; i++) + out[i] = timesTranspose(in1[i], in2[i]); + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= LOOPCOUNT; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for (i = 0; i < ARRAY_SIZE; i++) + out[i] = in1[i].timesTranspose(in2[i]); + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= LOOPCOUNT; + + vlog("Timing:\n"); + vlog("\t scalar\t vector\n"); + vlog("\t%10.2f\t%10.2f\n", TicksToCycles(scalarTime) / ARRAY_SIZE, TicksToCycles(vectorTime) / ARRAY_SIZE); + + return 0; } -#endif //BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_3x3timesTranspose.h b/test/Bullet2/Source/Tests/Test_3x3timesTranspose.h index a1c396bd2..083b936cb 100644 --- a/test/Bullet2/Source/Tests/Test_3x3timesTranspose.h +++ b/test/Bullet2/Source/Tests/Test_3x3timesTranspose.h @@ -9,14 +9,14 @@ #define BulletTest_Test_3x3timesTranspose_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_3x3timesTranspose(void); + int Test_3x3timesTranspose(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_3x3transpose.cpp b/test/Bullet2/Source/Tests/Test_3x3transpose.cpp index c85333ff2..141557ed3 100644 --- a/test/Bullet2/Source/Tests/Test_3x3transpose.cpp +++ b/test/Bullet2/Source/Tests/Test_3x3transpose.cpp @@ -5,10 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_3x3transpose.h" #include "vector.h" @@ -20,97 +18,98 @@ #include #define LOOPCOUNT 1000 -#define ARRAY_SIZE 1024 +#define ARRAY_SIZE 1024 static inline btSimdFloat4 rand_f4(void) { - return btAssign128( RANDF, RANDF, RANDF, BT_NAN ); // w channel NaN + return btAssign128(RANDF, RANDF, RANDF, BT_NAN); // w channel NaN } -static btMatrix3x3 Transpose( btMatrix3x3 &in ) +static btMatrix3x3 Transpose(btMatrix3x3 &in) { - btVector3 row0 = in.getRow(0); - btVector3 row1 = in.getRow(1); - btVector3 row2 = in.getRow(2); - btVector3 col0 = btAssign128(row0.x(), row1.x(), row2.x(), 0 ); - btVector3 col1 = btAssign128(row0.y(), row1.y(), row2.y(), 0 ); + btVector3 row0 = in.getRow(0); + btVector3 row1 = in.getRow(1); + btVector3 row2 = in.getRow(2); + btVector3 col0 = btAssign128(row0.x(), row1.x(), row2.x(), 0); + btVector3 col1 = btAssign128(row0.y(), row1.y(), row2.y(), 0); btVector3 col2 = btAssign128(row0.z(), row1.z(), row2.z(), 0); - return btMatrix3x3( col0, col1, col2); + return btMatrix3x3(col0, col1, col2); } -static int operator!= ( const btMatrix3x3 &a, const btMatrix3x3 &b ) +static int operator!=(const btMatrix3x3 &a, const btMatrix3x3 &b) { - if( a.getRow(0) != b.getRow(0) ) - return 1; - if( a.getRow(1) != b.getRow(1) ) - return 1; - if( a.getRow(2) != b.getRow(2) ) - return 1; - return 0; + if (a.getRow(0) != b.getRow(0)) + return 1; + if (a.getRow(1) != b.getRow(1)) + return 1; + if (a.getRow(2) != b.getRow(2)) + return 1; + return 0; } int Test_3x3transpose(void) { - // Init an array flanked by guard pages - btMatrix3x3 in[ARRAY_SIZE]; - btMatrix3x3 out[ARRAY_SIZE]; - btMatrix3x3 out2[ARRAY_SIZE]; - - // Init the data - size_t i, j; - for( i = 0; i < ARRAY_SIZE; i++ ) - { - in[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); - - out[i] = Transpose(in[i]); - out2[i] = in[i].transpose(); - - if( out[i] != out2[i] ) - { - printf( "failure @ %ld\n", i); - return -1; - } - } + // Init an array flanked by guard pages + btMatrix3x3 in[ARRAY_SIZE]; + btMatrix3x3 out[ARRAY_SIZE]; + btMatrix3x3 out2[ARRAY_SIZE]; - uint64_t scalarTime, vectorTime; - uint64_t startTime, bestTime, currentTime; - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < LOOPCOUNT; j++) { - startTime = ReadTicks(); - for( i = 0; i < ARRAY_SIZE; i++ ) - out[i] = Transpose(in[i]); - currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= LOOPCOUNT; + // Init the data + size_t i, j; + for (i = 0; i < ARRAY_SIZE; i++) + { + in[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4()); - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < LOOPCOUNT; j++) { - startTime = ReadTicks(); - for( i = 0; i < ARRAY_SIZE; i++ ) - out[i] = in[i].transpose(); - currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= LOOPCOUNT; - - vlog( "Timing:\n" ); - vlog( "\t scalar\t vector\n" ); - vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE ); - - return 0; + out[i] = Transpose(in[i]); + out2[i] = in[i].transpose(); + + if (out[i] != out2[i]) + { + printf("failure @ %ld\n", i); + return -1; + } + } + + uint64_t scalarTime, vectorTime; + uint64_t startTime, bestTime, currentTime; + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for (i = 0; i < ARRAY_SIZE; i++) + out[i] = Transpose(in[i]); + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= LOOPCOUNT; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for (i = 0; i < ARRAY_SIZE; i++) + out[i] = in[i].transpose(); + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= LOOPCOUNT; + + vlog("Timing:\n"); + vlog("\t scalar\t vector\n"); + vlog("\t%10.2f\t%10.2f\n", TicksToCycles(scalarTime) / ARRAY_SIZE, TicksToCycles(vectorTime) / ARRAY_SIZE); + + return 0; } -#endif //BT_USE_SSE - +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_3x3transpose.h b/test/Bullet2/Source/Tests/Test_3x3transpose.h index 3c4b834c2..9c8b3a071 100644 --- a/test/Bullet2/Source/Tests/Test_3x3transpose.h +++ b/test/Bullet2/Source/Tests/Test_3x3transpose.h @@ -9,14 +9,14 @@ #define BulletTest_Test_3x3transpose_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif - - int Test_3x3transpose(void); - + + int Test_3x3transpose(void); + #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_3x3transposeTimes.cpp b/test/Bullet2/Source/Tests/Test_3x3transposeTimes.cpp index 5f14caf76..fce2856cb 100644 --- a/test/Bullet2/Source/Tests/Test_3x3transposeTimes.cpp +++ b/test/Bullet2/Source/Tests/Test_3x3transposeTimes.cpp @@ -5,10 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_3x3transposeTimes.h" #include "vector.h" @@ -24,145 +22,148 @@ static inline btSimdFloat4 rand_f4(void) { - return btAssign128( RANDF_01, RANDF_01, RANDF_01, BT_NAN ); // w channel NaN + return btAssign128(RANDF_01, RANDF_01, RANDF_01, BT_NAN); // w channel NaN } -static btMatrix3x3 TransposeTimesReference( const btMatrix3x3 &in, const btMatrix3x3 &m ) +static btMatrix3x3 TransposeTimesReference(const btMatrix3x3 &in, const btMatrix3x3 &m) { - btVector3 m_el[3] = { in[0], in[1], in[2] }; - btSimdFloat4 r0 = btAssign128(m_el[0].x() * m[0].x() + m_el[1].x() * m[1].x() + m_el[2].x() * m[2].x(), - m_el[0].x() * m[0].y() + m_el[1].x() * m[1].y() + m_el[2].x() * m[2].y(), - m_el[0].x() * m[0].z() + m_el[1].x() * m[1].z() + m_el[2].x() * m[2].z(), - 0.0f ); - btSimdFloat4 r1 = btAssign128( m_el[0].y() * m[0].x() + m_el[1].y() * m[1].x() + m_el[2].y() * m[2].x(), - m_el[0].y() * m[0].y() + m_el[1].y() * m[1].y() + m_el[2].y() * m[2].y(), - m_el[0].y() * m[0].z() + m_el[1].y() * m[1].z() + m_el[2].y() * m[2].z(), - 0.0f ); - btSimdFloat4 r2 = btAssign128( m_el[0].z() * m[0].x() + m_el[1].z() * m[1].x() + m_el[2].z() * m[2].x(), - m_el[0].z() * m[0].y() + m_el[1].z() * m[1].y() + m_el[2].z() * m[2].y(), - m_el[0].z() * m[0].z() + m_el[1].z() * m[1].z() + m_el[2].z() * m[2].z(), - 0.0f ); - return btMatrix3x3( r0, r1, r2 ); + btVector3 m_el[3] = {in[0], in[1], in[2]}; + btSimdFloat4 r0 = btAssign128(m_el[0].x() * m[0].x() + m_el[1].x() * m[1].x() + m_el[2].x() * m[2].x(), + m_el[0].x() * m[0].y() + m_el[1].x() * m[1].y() + m_el[2].x() * m[2].y(), + m_el[0].x() * m[0].z() + m_el[1].x() * m[1].z() + m_el[2].x() * m[2].z(), + 0.0f); + btSimdFloat4 r1 = btAssign128(m_el[0].y() * m[0].x() + m_el[1].y() * m[1].x() + m_el[2].y() * m[2].x(), + m_el[0].y() * m[0].y() + m_el[1].y() * m[1].y() + m_el[2].y() * m[2].y(), + m_el[0].y() * m[0].z() + m_el[1].y() * m[1].z() + m_el[2].y() * m[2].z(), + 0.0f); + btSimdFloat4 r2 = btAssign128(m_el[0].z() * m[0].x() + m_el[1].z() * m[1].x() + m_el[2].z() * m[2].x(), + m_el[0].z() * m[0].y() + m_el[1].z() * m[1].y() + m_el[2].z() * m[2].y(), + m_el[0].z() * m[0].z() + m_el[1].z() * m[1].z() + m_el[2].z() * m[2].z(), + 0.0f); + return btMatrix3x3(r0, r1, r2); } -static int operator!= ( const btMatrix3x3 &a, const btMatrix3x3 &b ) +static int operator!=(const btMatrix3x3 &a, const btMatrix3x3 &b) { - if( a.getRow(0) != b.getRow(0) ) - return 1; - if( a.getRow(1) != b.getRow(1) ) - return 1; - if( a.getRow(2) != b.getRow(2) ) - return 1; - return 0; + if (a.getRow(0) != b.getRow(0)) + return 1; + if (a.getRow(1) != b.getRow(1)) + return 1; + if (a.getRow(2) != b.getRow(2)) + return 1; + return 0; } int Test_3x3transposeTimes(void) { - // Init an array flanked by guard pages - btMatrix3x3 in1[ARRAY_SIZE]; - btMatrix3x3 in2[ARRAY_SIZE]; - btMatrix3x3 out[ARRAY_SIZE]; - btMatrix3x3 out2[ARRAY_SIZE]; - - float maxRelativeError = 0.f; - // Init the data - size_t i, j; - for( i = 0; i < ARRAY_SIZE; i++ ) - { - in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); - in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4() ); - - out[i] = TransposeTimesReference(in1[i], in2[i]); - out2[i] = in1[i].transposeTimes(in2[i]); - - if( out[i] != out2[i] ) - { + // Init an array flanked by guard pages + btMatrix3x3 in1[ARRAY_SIZE]; + btMatrix3x3 in2[ARRAY_SIZE]; + btMatrix3x3 out[ARRAY_SIZE]; + btMatrix3x3 out2[ARRAY_SIZE]; + float maxRelativeError = 0.f; + // Init the data + size_t i, j; + for (i = 0; i < ARRAY_SIZE; i++) + { + in1[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4()); + in2[i] = btMatrix3x3(rand_f4(), rand_f4(), rand_f4()); + + out[i] = TransposeTimesReference(in1[i], in2[i]); + out2[i] = in1[i].transposeTimes(in2[i]); + + if (out[i] != out2[i]) + { float relativeError = 0.f; - for (int column=0;column<3;column++) - for (int row=0;row<3;row++) - relativeError = btMax(relativeError,btFabs(out2[i][row][column] - out[i][row][column]) / out[i][row][column]); + for (int column = 0; column < 3; column++) + for (int row = 0; row < 3; row++) + relativeError = btMax(relativeError, btFabs(out2[i][row][column] - out[i][row][column]) / out[i][row][column]); - if (relativeError>1e-6) + if (relativeError > 1e-6) { - vlog( "failure @ %ld\n", i); + vlog("failure @ %ld\n", i); btVector3 m0, m1, m2; m0 = out[i].getRow(0); m1 = out[i].getRow(1); m2 = out[i].getRow(2); - - vlog( "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " - "\n (%10.4f, %10.4f, %10.4f, %10.4f) " - "\n (%10.4f, %10.4f, %10.4f, %10.4f) \n", - m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], - m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], - m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + + vlog( + "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) \n", + m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], + m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], + m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); m0 = out2[i].getRow(0); m1 = out2[i].getRow(1); m2 = out2[i].getRow(2); - - vlog( "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) " - "\n (%10.4f, %10.4f, %10.4f, %10.4f) " - "\n (%10.4f, %10.4f, %10.4f, %10.4f) \n", - m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], - m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], - m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); + + vlog( + "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) " + "\n (%10.4f, %10.4f, %10.4f, %10.4f) \n", + m0.m_floats[0], m0.m_floats[1], m0.m_floats[2], m0.m_floats[3], + m1.m_floats[0], m1.m_floats[1], m1.m_floats[2], m1.m_floats[3], + m2.m_floats[0], m2.m_floats[1], m2.m_floats[2], m2.m_floats[3]); return -1; - } else + } + else { - if (relativeError>maxRelativeError) + if (relativeError > maxRelativeError) maxRelativeError = relativeError; } - } - } - + } + } + if (maxRelativeError) { - printf("Warning: maxRelativeError = %e\n",maxRelativeError); + printf("Warning: maxRelativeError = %e\n", maxRelativeError); } - uint64_t scalarTime, vectorTime; - uint64_t startTime, bestTime, currentTime; - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < LOOPCOUNT; j++) { - startTime = ReadTicks(); - for( i = 0; i < ARRAY_SIZE; i++ ) - out[i] = TransposeTimesReference(in1[i], in2[i]); - currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= LOOPCOUNT; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < LOOPCOUNT; j++) { - startTime = ReadTicks(); - for( i = 0; i < ARRAY_SIZE; i++ ) - out[i] = in1[i].transposeTimes(in2[i]); - currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= LOOPCOUNT; - - vlog( "Timing:\n" ); - vlog( "\t scalar\t vector\n" ); - vlog( "\t%10.2f\t%10.2f\n", TicksToCycles( scalarTime ) / ARRAY_SIZE, TicksToCycles( vectorTime ) / ARRAY_SIZE ); - - return 0; + uint64_t scalarTime, vectorTime; + uint64_t startTime, bestTime, currentTime; + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for (i = 0; i < ARRAY_SIZE; i++) + out[i] = TransposeTimesReference(in1[i], in2[i]); + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= LOOPCOUNT; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < LOOPCOUNT; j++) + { + startTime = ReadTicks(); + for (i = 0; i < ARRAY_SIZE; i++) + out[i] = in1[i].transposeTimes(in2[i]); + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= LOOPCOUNT; + + vlog("Timing:\n"); + vlog("\t scalar\t vector\n"); + vlog("\t%10.2f\t%10.2f\n", TicksToCycles(scalarTime) / ARRAY_SIZE, TicksToCycles(vectorTime) / ARRAY_SIZE); + + return 0; } -#endif //BT_USE_SSE - +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_3x3transposeTimes.h b/test/Bullet2/Source/Tests/Test_3x3transposeTimes.h index 08af2e1e0..a7b93ac51 100644 --- a/test/Bullet2/Source/Tests/Test_3x3transposeTimes.h +++ b/test/Bullet2/Source/Tests/Test_3x3transposeTimes.h @@ -9,14 +9,14 @@ #define BulletTest_Test_3x3transposeTimes_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_3x3transposeTimes(void); + int Test_3x3transposeTimes(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_btDbvt.cpp b/test/Bullet2/Source/Tests/Test_btDbvt.cpp index 96ce52508..af3327461 100644 --- a/test/Bullet2/Source/Tests/Test_btDbvt.cpp +++ b/test/Bullet2/Source/Tests/Test_btDbvt.cpp @@ -5,10 +5,8 @@ // Copyright (c) 2011 Apple Inc., Inc. // - - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_btDbvt.h" #include "vector.h" @@ -20,55 +18,49 @@ #include // reference code for testing purposes -SIMD_FORCE_INLINE bool Intersect_ref( btDbvtAabbMm& a, btDbvtAabbMm& b) +SIMD_FORCE_INLINE bool Intersect_ref(btDbvtAabbMm& a, btDbvtAabbMm& b) { - return( (a.tMins().x()<=b.tMaxs().x())&& - (a.tMaxs().x()>=b.tMins().x())&& - (a.tMins().y()<=b.tMaxs().y())&& - (a.tMaxs().y()>=b.tMins().y())&& - (a.tMins().z()<=b.tMaxs().z())&& - (a.tMaxs().z()>=b.tMins().z())); - - } - - -SIMD_FORCE_INLINE btScalar Proximity_ref( btDbvtAabbMm& a, - btDbvtAabbMm& b) -{ - const btVector3 d=(a.tMins()+a.tMaxs())-(b.tMins()+b.tMaxs()); - return(btFabs(d.x())+btFabs(d.y())+btFabs(d.z())); + return ((a.tMins().x() <= b.tMaxs().x()) && + (a.tMaxs().x() >= b.tMins().x()) && + (a.tMins().y() <= b.tMaxs().y()) && + (a.tMaxs().y() >= b.tMins().y()) && + (a.tMins().z() <= b.tMaxs().z()) && + (a.tMaxs().z() >= b.tMins().z())); } - - -SIMD_FORCE_INLINE int Select_ref( btDbvtAabbMm& o, - btDbvtAabbMm& a, - btDbvtAabbMm& b) +SIMD_FORCE_INLINE btScalar Proximity_ref(btDbvtAabbMm& a, + btDbvtAabbMm& b) { - return(Proximity_ref(o,a)b.tMaxs().m_floats[i]) - r.tMaxs().m_floats[i]=a.tMaxs().m_floats[i]; - else - r.tMaxs().m_floats[i]=b.tMaxs().m_floats[i]; + if (a.tMins().m_floats[i] < b.tMins().m_floats[i]) + r.tMins().m_floats[i] = a.tMins().m_floats[i]; + else + r.tMins().m_floats[i] = b.tMins().m_floats[i]; + + if (a.tMaxs().m_floats[i] > b.tMaxs().m_floats[i]) + r.tMaxs().m_floats[i] = a.tMaxs().m_floats[i]; + else + r.tMaxs().m_floats[i] = b.tMaxs().m_floats[i]; } } /* @@ -99,244 +91,235 @@ SIMD_FORCE_INLINE void Merge_ref( btDbvtAabbMm& a, int Test_btDbvt(void) { - btDbvtAabbMm a[DATA_SIZE], b[DATA_SIZE], c[DATA_SIZE]; - btDbvtAabbMm a_ref[DATA_SIZE], b_ref[DATA_SIZE], c_ref[DATA_SIZE]; - - int i; - - bool Intersect_Test_Res[DATA_SIZE], Intersect_Ref_Res[DATA_SIZE]; - int Select_Test_Res[DATA_SIZE], Select_Ref_Res[DATA_SIZE]; - - - for (i = 0; i < DATA_SIZE; i++) - { - a[i].tMins().m_floats[0] = (float)rand() / (float)RAND_MAX; - a[i].tMins().m_floats[1] = (float)rand() / (float)RAND_MAX; - a[i].tMins().m_floats[2] = (float)rand() / (float)RAND_MAX; - a[i].tMins().m_floats[3] = (float)rand() / (float)RAND_MAX; - - a[i].tMaxs().m_floats[0] = (float)rand() / (float)RAND_MAX; - a[i].tMaxs().m_floats[1] = (float)rand() / (float)RAND_MAX; - a[i].tMaxs().m_floats[2] = (float)rand() / (float)RAND_MAX; - a[i].tMaxs().m_floats[3] = (float)rand() / (float)RAND_MAX; - - b[i].tMins().m_floats[0] = (float)rand() / (float)RAND_MAX; - b[i].tMins().m_floats[1] = (float)rand() / (float)RAND_MAX; - b[i].tMins().m_floats[2] = (float)rand() / (float)RAND_MAX; - b[i].tMins().m_floats[3] = (float)rand() / (float)RAND_MAX; - - b[i].tMaxs().m_floats[0] = (float)rand() / (float)RAND_MAX; - b[i].tMaxs().m_floats[1] = (float)rand() / (float)RAND_MAX; - b[i].tMaxs().m_floats[2] = (float)rand() / (float)RAND_MAX; - b[i].tMaxs().m_floats[3] = (float)rand() / (float)RAND_MAX; - - c[i].tMins().m_floats[0] = (float)rand() / (float)RAND_MAX; - c[i].tMins().m_floats[1] = (float)rand() / (float)RAND_MAX; - c[i].tMins().m_floats[2] = (float)rand() / (float)RAND_MAX; - c[i].tMins().m_floats[3] = (float)rand() / (float)RAND_MAX; - - c[i].tMaxs().m_floats[0] = (float)rand() / (float)RAND_MAX; - c[i].tMaxs().m_floats[1] = (float)rand() / (float)RAND_MAX; - c[i].tMaxs().m_floats[2] = (float)rand() / (float)RAND_MAX; - c[i].tMaxs().m_floats[3] = (float)rand() / (float)RAND_MAX; - - - a_ref[i].tMins().m_floats[0] = a[i].tMins().m_floats[0]; - a_ref[i].tMins().m_floats[1] = a[i].tMins().m_floats[1]; - a_ref[i].tMins().m_floats[2] = a[i].tMins().m_floats[2]; - a_ref[i].tMins().m_floats[3] = a[i].tMins().m_floats[3]; - - a_ref[i].tMaxs().m_floats[0] = a[i].tMaxs().m_floats[0]; - a_ref[i].tMaxs().m_floats[1] = a[i].tMaxs().m_floats[1]; - a_ref[i].tMaxs().m_floats[2] = a[i].tMaxs().m_floats[2]; - a_ref[i].tMaxs().m_floats[3] = a[i].tMaxs().m_floats[3]; - - b_ref[i].tMins().m_floats[0] = b[i].tMins().m_floats[0]; - b_ref[i].tMins().m_floats[1] = b[i].tMins().m_floats[1]; - b_ref[i].tMins().m_floats[2] = b[i].tMins().m_floats[2]; - b_ref[i].tMins().m_floats[3] = b[i].tMins().m_floats[3]; - - b_ref[i].tMaxs().m_floats[0] = b[i].tMaxs().m_floats[0]; - b_ref[i].tMaxs().m_floats[1] = b[i].tMaxs().m_floats[1]; - b_ref[i].tMaxs().m_floats[2] = b[i].tMaxs().m_floats[2]; - b_ref[i].tMaxs().m_floats[3] = b[i].tMaxs().m_floats[3]; - - c_ref[i].tMins().m_floats[0] = c[i].tMins().m_floats[0]; - c_ref[i].tMins().m_floats[1] = c[i].tMins().m_floats[1]; - c_ref[i].tMins().m_floats[2] = c[i].tMins().m_floats[2]; - c_ref[i].tMins().m_floats[3] = c[i].tMins().m_floats[3]; - - c_ref[i].tMaxs().m_floats[0] = c[i].tMaxs().m_floats[0]; - c_ref[i].tMaxs().m_floats[1] = c[i].tMaxs().m_floats[1]; - c_ref[i].tMaxs().m_floats[2] = c[i].tMaxs().m_floats[2]; - c_ref[i].tMaxs().m_floats[3] = c[i].tMaxs().m_floats[3]; - - } - - -#if 1 - for (i = 0; i < DATA_SIZE; i++) - { - - Intersect_Test_Res[i] = Intersect(a[i], b[i]); - Intersect_Ref_Res[i] = Intersect_ref(a_ref[i], b_ref[i]); - - if(Intersect_Test_Res[i] != Intersect_Ref_Res[i]) - { - printf("Diff on %d\n", i); - - printf("a_mx_f[0] = %.3f, a_mx_f[1] = %.3f, a_mx_f[2] = %.3f, a_mx_f[3] = %.3f\n", a[i].tMaxs().m_floats[0], a[i].tMaxs().m_floats[1], a[i].tMaxs().m_floats[2], a[i].tMaxs().m_floats[3]); - printf("a_mi_f[0] = %.3f, a_mi_f[1] = %.3f, a_mi_f[2] = %.3f, a_mi_f[3] = %.3f\n", a[i].tMins().m_floats[0], a[i].tMins().m_floats[1], a[i].tMins().m_floats[2], a[i].tMins().m_floats[3]); - printf("b_mx_f[0] = %.3f, b_mx_f[1] = %.3f, b_mx_f[2] = %.3f, b_mx_f[3] = %.3f\n", b[i].tMaxs().m_floats[0], b[i].tMaxs().m_floats[1], b[i].tMaxs().m_floats[2], b[i].tMaxs().m_floats[3]); - printf("b_mi_f[0] = %.3f, b_mi_f[1] = %.3f, b_mi_f[2] = %.3f, b_mi_f[3] = %.3f\n", b[i].tMins().m_floats[0], b[i].tMins().m_floats[1], b[i].tMins().m_floats[2], b[i].tMins().m_floats[3]); - - printf("a_mx_f_ref[0] = %.3f, a_mx_f_ref[1] = %.3f, a_mx_f_ref[2] = %.3f, a_mx_f_ref[3] = %.3f\n", a_ref[i].tMaxs().m_floats[0], a_ref[i].tMaxs().m_floats[1], a_ref[i].tMaxs().m_floats[2], a_ref[i].tMaxs().m_floats[3]); - printf("a_mi_f_ref[0] = %.3f, a_mi_f_ref[1] = %.3f, a_mi_f_ref[2] = %.3f, a_mi_f_ref[3] = %.3f\n", a_ref[i].tMins().m_floats[0], a_ref[i].tMins().m_floats[1], a_ref[i].tMins().m_floats[2], a_ref[i].tMins().m_floats[3]); - printf("b_mx_f_ref[0] = %.3f, b_mx_f_ref[1] = %.3f, b_mx_f_ref[2] = %.3f, b_mx_f_ref[3] = %.3f\n", b_ref[i].tMaxs().m_floats[0], b_ref[i].tMaxs().m_floats[1], b_ref[i].tMaxs().m_floats[2], b_ref[i].tMaxs().m_floats[3]); - printf("b_mi_f_ref[0] = %.3f, b_mi_f_ref[1] = %.3f, b_mi_f_ref[2] = %.3f, b_mi_f_ref[3] = %.3f\n", b_ref[i].tMins().m_floats[0], b_ref[i].tMins().m_floats[1], b_ref[i].tMins().m_floats[2], b_ref[i].tMins().m_floats[3]); - } - } -#endif - - uint64_t scalarTime; - uint64_t vectorTime; - size_t j; - - - //////////////////////////////////// - // - // Time and Test Intersect - // - //////////////////////////////////// + btDbvtAabbMm a[DATA_SIZE], b[DATA_SIZE], c[DATA_SIZE]; + btDbvtAabbMm a_ref[DATA_SIZE], b_ref[DATA_SIZE], c_ref[DATA_SIZE]; + + int i; + + bool Intersect_Test_Res[DATA_SIZE], Intersect_Ref_Res[DATA_SIZE]; + int Select_Test_Res[DATA_SIZE], Select_Ref_Res[DATA_SIZE]; + + for (i = 0; i < DATA_SIZE; i++) { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + a[i].tMins().m_floats[0] = (float)rand() / (float)RAND_MAX; + a[i].tMins().m_floats[1] = (float)rand() / (float)RAND_MAX; + a[i].tMins().m_floats[2] = (float)rand() / (float)RAND_MAX; + a[i].tMins().m_floats[3] = (float)rand() / (float)RAND_MAX; + + a[i].tMaxs().m_floats[0] = (float)rand() / (float)RAND_MAX; + a[i].tMaxs().m_floats[1] = (float)rand() / (float)RAND_MAX; + a[i].tMaxs().m_floats[2] = (float)rand() / (float)RAND_MAX; + a[i].tMaxs().m_floats[3] = (float)rand() / (float)RAND_MAX; + + b[i].tMins().m_floats[0] = (float)rand() / (float)RAND_MAX; + b[i].tMins().m_floats[1] = (float)rand() / (float)RAND_MAX; + b[i].tMins().m_floats[2] = (float)rand() / (float)RAND_MAX; + b[i].tMins().m_floats[3] = (float)rand() / (float)RAND_MAX; + + b[i].tMaxs().m_floats[0] = (float)rand() / (float)RAND_MAX; + b[i].tMaxs().m_floats[1] = (float)rand() / (float)RAND_MAX; + b[i].tMaxs().m_floats[2] = (float)rand() / (float)RAND_MAX; + b[i].tMaxs().m_floats[3] = (float)rand() / (float)RAND_MAX; + + c[i].tMins().m_floats[0] = (float)rand() / (float)RAND_MAX; + c[i].tMins().m_floats[1] = (float)rand() / (float)RAND_MAX; + c[i].tMins().m_floats[2] = (float)rand() / (float)RAND_MAX; + c[i].tMins().m_floats[3] = (float)rand() / (float)RAND_MAX; + + c[i].tMaxs().m_floats[0] = (float)rand() / (float)RAND_MAX; + c[i].tMaxs().m_floats[1] = (float)rand() / (float)RAND_MAX; + c[i].tMaxs().m_floats[2] = (float)rand() / (float)RAND_MAX; + c[i].tMaxs().m_floats[3] = (float)rand() / (float)RAND_MAX; + + a_ref[i].tMins().m_floats[0] = a[i].tMins().m_floats[0]; + a_ref[i].tMins().m_floats[1] = a[i].tMins().m_floats[1]; + a_ref[i].tMins().m_floats[2] = a[i].tMins().m_floats[2]; + a_ref[i].tMins().m_floats[3] = a[i].tMins().m_floats[3]; + + a_ref[i].tMaxs().m_floats[0] = a[i].tMaxs().m_floats[0]; + a_ref[i].tMaxs().m_floats[1] = a[i].tMaxs().m_floats[1]; + a_ref[i].tMaxs().m_floats[2] = a[i].tMaxs().m_floats[2]; + a_ref[i].tMaxs().m_floats[3] = a[i].tMaxs().m_floats[3]; + + b_ref[i].tMins().m_floats[0] = b[i].tMins().m_floats[0]; + b_ref[i].tMins().m_floats[1] = b[i].tMins().m_floats[1]; + b_ref[i].tMins().m_floats[2] = b[i].tMins().m_floats[2]; + b_ref[i].tMins().m_floats[3] = b[i].tMins().m_floats[3]; + + b_ref[i].tMaxs().m_floats[0] = b[i].tMaxs().m_floats[0]; + b_ref[i].tMaxs().m_floats[1] = b[i].tMaxs().m_floats[1]; + b_ref[i].tMaxs().m_floats[2] = b[i].tMaxs().m_floats[2]; + b_ref[i].tMaxs().m_floats[3] = b[i].tMaxs().m_floats[3]; + + c_ref[i].tMins().m_floats[0] = c[i].tMins().m_floats[0]; + c_ref[i].tMins().m_floats[1] = c[i].tMins().m_floats[1]; + c_ref[i].tMins().m_floats[2] = c[i].tMins().m_floats[2]; + c_ref[i].tMins().m_floats[3] = c[i].tMins().m_floats[3]; + + c_ref[i].tMaxs().m_floats[0] = c[i].tMaxs().m_floats[0]; + c_ref[i].tMaxs().m_floats[1] = c[i].tMaxs().m_floats[1]; + c_ref[i].tMaxs().m_floats[2] = c[i].tMaxs().m_floats[2]; + c_ref[i].tMaxs().m_floats[3] = c[i].tMaxs().m_floats[3]; + } + +#if 1 + for (i = 0; i < DATA_SIZE; i++) + { + Intersect_Test_Res[i] = Intersect(a[i], b[i]); + Intersect_Ref_Res[i] = Intersect_ref(a_ref[i], b_ref[i]); + + if (Intersect_Test_Res[i] != Intersect_Ref_Res[i]) { - startTime = ReadTicks(); - - - for (i = 0; i < DATA_SIZE; i++) - { - Intersect_Ref_Res[i] = Intersect_ref(a_ref[i], b_ref[i]); - } - - currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= NUM_CYCLES; - } - - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + printf("Diff on %d\n", i); + + printf("a_mx_f[0] = %.3f, a_mx_f[1] = %.3f, a_mx_f[2] = %.3f, a_mx_f[3] = %.3f\n", a[i].tMaxs().m_floats[0], a[i].tMaxs().m_floats[1], a[i].tMaxs().m_floats[2], a[i].tMaxs().m_floats[3]); + printf("a_mi_f[0] = %.3f, a_mi_f[1] = %.3f, a_mi_f[2] = %.3f, a_mi_f[3] = %.3f\n", a[i].tMins().m_floats[0], a[i].tMins().m_floats[1], a[i].tMins().m_floats[2], a[i].tMins().m_floats[3]); + printf("b_mx_f[0] = %.3f, b_mx_f[1] = %.3f, b_mx_f[2] = %.3f, b_mx_f[3] = %.3f\n", b[i].tMaxs().m_floats[0], b[i].tMaxs().m_floats[1], b[i].tMaxs().m_floats[2], b[i].tMaxs().m_floats[3]); + printf("b_mi_f[0] = %.3f, b_mi_f[1] = %.3f, b_mi_f[2] = %.3f, b_mi_f[3] = %.3f\n", b[i].tMins().m_floats[0], b[i].tMins().m_floats[1], b[i].tMins().m_floats[2], b[i].tMins().m_floats[3]); + + printf("a_mx_f_ref[0] = %.3f, a_mx_f_ref[1] = %.3f, a_mx_f_ref[2] = %.3f, a_mx_f_ref[3] = %.3f\n", a_ref[i].tMaxs().m_floats[0], a_ref[i].tMaxs().m_floats[1], a_ref[i].tMaxs().m_floats[2], a_ref[i].tMaxs().m_floats[3]); + printf("a_mi_f_ref[0] = %.3f, a_mi_f_ref[1] = %.3f, a_mi_f_ref[2] = %.3f, a_mi_f_ref[3] = %.3f\n", a_ref[i].tMins().m_floats[0], a_ref[i].tMins().m_floats[1], a_ref[i].tMins().m_floats[2], a_ref[i].tMins().m_floats[3]); + printf("b_mx_f_ref[0] = %.3f, b_mx_f_ref[1] = %.3f, b_mx_f_ref[2] = %.3f, b_mx_f_ref[3] = %.3f\n", b_ref[i].tMaxs().m_floats[0], b_ref[i].tMaxs().m_floats[1], b_ref[i].tMaxs().m_floats[2], b_ref[i].tMaxs().m_floats[3]); + printf("b_mi_f_ref[0] = %.3f, b_mi_f_ref[1] = %.3f, b_mi_f_ref[2] = %.3f, b_mi_f_ref[3] = %.3f\n", b_ref[i].tMins().m_floats[0], b_ref[i].tMins().m_floats[1], b_ref[i].tMins().m_floats[2], b_ref[i].tMins().m_floats[3]); + } + } +#endif + + uint64_t scalarTime; + uint64_t vectorTime; + size_t j; + + //////////////////////////////////// + // + // Time and Test Intersect + // + //////////////////////////////////// + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - startTime = ReadTicks(); - - for (i = 0; i < DATA_SIZE; i++) - { - Intersect_Test_Res[i] = Intersect(a[i], b[i]); - } + startTime = ReadTicks(); + + for (i = 0; i < DATA_SIZE; i++) + { + Intersect_Ref_Res[i] = Intersect_ref(a_ref[i], b_ref[i]); + } currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= NUM_CYCLES; - } - - vlog( "Intersect Timing:\n" ); - vlog( " \t scalar\t vector\n" ); - vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, TicksToCycles( vectorTime ) / LOOPCOUNT ); - - //printf("scalar = %llu, vector = %llu\n", scalarTime, vectorTime); - - for (i = 0; i < DATA_SIZE; i++) - { - if(Intersect_Test_Res[i] != Intersect_Ref_Res[i]) - { - printf("Intersect fail at %d\n", i); - return 1; - } - } - - //////////////////////////////////// - // - // Time and Test Merge - // - //////////////////////////////////// + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - startTime = ReadTicks(); - - - for (i = 0; i < DATA_SIZE; i++) - { - Merge_ref(a_ref[i], b_ref[i], c_ref[i]); - } - + startTime = ReadTicks(); + + for (i = 0; i < DATA_SIZE; i++) + { + Intersect_Test_Res[i] = Intersect(a[i], b[i]); + } + currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= NUM_CYCLES; - } - - - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog("Intersect Timing:\n"); + vlog(" \t scalar\t vector\n"); + vlog(" \t%10.4f\t%10.4f\n", TicksToCycles(scalarTime) / LOOPCOUNT, TicksToCycles(vectorTime) / LOOPCOUNT); + + //printf("scalar = %llu, vector = %llu\n", scalarTime, vectorTime); + + for (i = 0; i < DATA_SIZE; i++) + { + if (Intersect_Test_Res[i] != Intersect_Ref_Res[i]) { - startTime = ReadTicks(); - - for (i = 0; i < DATA_SIZE; i++) - { - Merge(a[i], b[i], c[i]); - } - + printf("Intersect fail at %d\n", i); + return 1; + } + } + + //////////////////////////////////// + // + // Time and Test Merge + // + //////////////////////////////////// + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + startTime = ReadTicks(); + + for (i = 0; i < DATA_SIZE; i++) + { + Merge_ref(a_ref[i], b_ref[i], c_ref[i]); + } + currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= NUM_CYCLES; - } - - vlog( "Merge Timing:\n" ); - vlog( " \t scalar\t vector\n" ); - vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, TicksToCycles( vectorTime ) / LOOPCOUNT ); - - //printf("scalar = %llu, vector = %llu\n", scalarTime, vectorTime); - /* + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + startTime = ReadTicks(); + + for (i = 0; i < DATA_SIZE; i++) + { + Merge(a[i], b[i], c[i]); + } + + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog("Merge Timing:\n"); + vlog(" \t scalar\t vector\n"); + vlog(" \t%10.4f\t%10.4f\n", TicksToCycles(scalarTime) / LOOPCOUNT, TicksToCycles(vectorTime) / LOOPCOUNT); + + //printf("scalar = %llu, vector = %llu\n", scalarTime, vectorTime); + /* c [0] float32_t 0.00455523 [1] float32_t 0.559712 [2] float32_t 0.0795838 @@ -360,136 +343,127 @@ c [0] float32_t 0.829904 [2] float32_t 0.961654 [3] float32_t 0.522878 */ - for (i = 0; i < DATA_SIZE; i++) - { - //ignore 4th component because it is not computed in all code-paths - if( (fabs(c[i].tMaxs().m_floats[0] - c_ref[i].tMaxs().m_floats[0]) > 0.001) || - (fabs(c[i].tMaxs().m_floats[1] - c_ref[i].tMaxs().m_floats[1]) > 0.001) || - (fabs(c[i].tMaxs().m_floats[2] - c_ref[i].tMaxs().m_floats[2]) > 0.001) || - // (fabs(c[i].tMaxs().m_floats[3] - c_ref[i].tMaxs().m_floats[3]) > 0.001) || - (fabs(c[i].tMins().m_floats[0] - c_ref[i].tMins().m_floats[0]) > 0.001) || - (fabs(c[i].tMins().m_floats[1] - c_ref[i].tMins().m_floats[1]) > 0.001) || - (fabs(c[i].tMins().m_floats[2] - c_ref[i].tMins().m_floats[2]) > 0.001) - //|| (fabs(c[i].tMins().m_floats[3] - c_ref[i].tMins().m_floats[3]) > 0.001) - ) - - - //if((c[i].tMaxs().m_floats[0] != c_ref[i].tMaxs().m_floats[0]) || (c[i].tMaxs().m_floats[1] != c_ref[i].tMaxs().m_floats[1]) || (c[i].tMaxs().m_floats[2] != c_ref[i].tMaxs().m_floats[2]) || (c[i].tMaxs().m_floats[3] != c_ref[i].tMaxs().m_floats[3]) || (c[i].tMins().m_floats[0] != c_ref[i].tMins().m_floats[0]) || (c[i].tMins().m_floats[1] != c_ref[i].tMins().m_floats[1]) || (c[i].tMins().m_floats[2] != c_ref[i].tMins().m_floats[2]) || (c[i].tMins().m_floats[3] != c_ref[i].tMins().m_floats[3])) - { - printf("Merge fail at %d with test = %d, ref = %d\n", i, Select_Test_Res[i], Select_Ref_Res[i]); - - printf("a_mx_f[0] = %.3f, a_mx_f[1] = %.3f, a_mx_f[2] = %.3f, a_mx_f[3] = %.3f\n", a[i].tMaxs().m_floats[0], a[i].tMaxs().m_floats[1], a[i].tMaxs().m_floats[2], a[i].tMaxs().m_floats[3]); - printf("a_mi_f[0] = %.3f, a_mi_f[1] = %.3f, a_mi_f[2] = %.3f, a_mi_f[3] = %.3f\n", a[i].tMins().m_floats[0], a[i].tMins().m_floats[1], a[i].tMins().m_floats[2], a[i].tMins().m_floats[3]); - printf("b_mx_f[0] = %.3f, b_mx_f[1] = %.3f, b_mx_f[2] = %.3f, b_mx_f[3] = %.3f\n", b[i].tMaxs().m_floats[0], b[i].tMaxs().m_floats[1], b[i].tMaxs().m_floats[2], b[i].tMaxs().m_floats[3]); - printf("b_mi_f[0] = %.3f, b_mi_f[1] = %.3f, b_mi_f[2] = %.3f, b_mi_f[3] = %.3f\n", b[i].tMins().m_floats[0], b[i].tMins().m_floats[1], b[i].tMins().m_floats[2], b[i].tMins().m_floats[3]); - printf("c_mx_f[0] = %.3f, c_mx_f[1] = %.3f, c_mx_f[2] = %.3f, c_mx_f[3] = %.3f\n", c[i].tMaxs().m_floats[0], c[i].tMaxs().m_floats[1], c[i].tMaxs().m_floats[2], c[i].tMaxs().m_floats[3]); - printf("c_mi_f[0] = %.3f, c_mi_f[1] = %.3f, c_mi_f[2] = %.3f, c_mi_f[3] = %.3f\n", c[i].tMins().m_floats[0], c[i].tMins().m_floats[1], c[i].tMins().m_floats[2], c[i].tMins().m_floats[3]); - - printf("a_mx_f_ref[0] = %.3f, a_mx_f_ref[1] = %.3f, a_mx_f_ref[2] = %.3f, a_mx_f_ref[3] = %.3f\n", a_ref[i].tMaxs().m_floats[0], a_ref[i].tMaxs().m_floats[1], a_ref[i].tMaxs().m_floats[2], a_ref[i].tMaxs().m_floats[3]); - printf("a_mi_f_ref[0] = %.3f, a_mi_f_ref[1] = %.3f, a_mi_f_ref[2] = %.3f, a_mi_f_ref[3] = %.3f\n", a_ref[i].tMins().m_floats[0], a_ref[i].tMins().m_floats[1], a_ref[i].tMins().m_floats[2], a_ref[i].tMins().m_floats[3]); - printf("b_mx_f_ref[0] = %.3f, b_mx_f_ref[1] = %.3f, b_mx_f_ref[2] = %.3f, b_mx_f_ref[3] = %.3f\n", b_ref[i].tMaxs().m_floats[0], b_ref[i].tMaxs().m_floats[1], b_ref[i].tMaxs().m_floats[2], b_ref[i].tMaxs().m_floats[3]); - printf("b_mi_f_ref[0] = %.3f, b_mi_f_ref[1] = %.3f, b_mi_f_ref[2] = %.3f, b_mi_f_ref[3] = %.3f\n", b_ref[i].tMins().m_floats[0], b_ref[i].tMins().m_floats[1], b_ref[i].tMins().m_floats[2], b_ref[i].tMins().m_floats[3]); - printf("c_mx_f_ref[0] = %.3f, c_mx_f_ref[1] = %.3f, c_mx_f_ref[2] = %.3f, c_mx_f_ref[3] = %.3f\n", c_ref[i].tMaxs().m_floats[0], c_ref[i].tMaxs().m_floats[1], c_ref[i].tMaxs().m_floats[2], c_ref[i].tMaxs().m_floats[3]); - printf("c_mi_f_ref[0] = %.3f, c_mi_f_ref[1] = %.3f, c_mi_f_ref[2] = %.3f, c_mi_f_ref[3] = %.3f\n", c_ref[i].tMins().m_floats[0], c_ref[i].tMins().m_floats[1], c_ref[i].tMins().m_floats[2], c_ref[i].tMins().m_floats[3]); - return 1; - - } - - } - - //////////////////////////////////// - // - // Time and Test Select - // - //////////////////////////////////// + for (i = 0; i < DATA_SIZE; i++) { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + //ignore 4th component because it is not computed in all code-paths + if ((fabs(c[i].tMaxs().m_floats[0] - c_ref[i].tMaxs().m_floats[0]) > 0.001) || + (fabs(c[i].tMaxs().m_floats[1] - c_ref[i].tMaxs().m_floats[1]) > 0.001) || + (fabs(c[i].tMaxs().m_floats[2] - c_ref[i].tMaxs().m_floats[2]) > 0.001) || + // (fabs(c[i].tMaxs().m_floats[3] - c_ref[i].tMaxs().m_floats[3]) > 0.001) || + (fabs(c[i].tMins().m_floats[0] - c_ref[i].tMins().m_floats[0]) > 0.001) || + (fabs(c[i].tMins().m_floats[1] - c_ref[i].tMins().m_floats[1]) > 0.001) || + (fabs(c[i].tMins().m_floats[2] - c_ref[i].tMins().m_floats[2]) > 0.001) + //|| (fabs(c[i].tMins().m_floats[3] - c_ref[i].tMins().m_floats[3]) > 0.001) + ) + + //if((c[i].tMaxs().m_floats[0] != c_ref[i].tMaxs().m_floats[0]) || (c[i].tMaxs().m_floats[1] != c_ref[i].tMaxs().m_floats[1]) || (c[i].tMaxs().m_floats[2] != c_ref[i].tMaxs().m_floats[2]) || (c[i].tMaxs().m_floats[3] != c_ref[i].tMaxs().m_floats[3]) || (c[i].tMins().m_floats[0] != c_ref[i].tMins().m_floats[0]) || (c[i].tMins().m_floats[1] != c_ref[i].tMins().m_floats[1]) || (c[i].tMins().m_floats[2] != c_ref[i].tMins().m_floats[2]) || (c[i].tMins().m_floats[3] != c_ref[i].tMins().m_floats[3])) { - startTime = ReadTicks(); - - - for (i = 0; i < DATA_SIZE; i++) - { - Select_Ref_Res[i] = Select_ref(a_ref[i], b_ref[i], c_ref[i]); - } - - currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= NUM_CYCLES; - } - - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < NUM_CYCLES; j++) - { - startTime = ReadTicks(); - - for (i = 0; i < DATA_SIZE; i++) - { - Select_Test_Res[i] = Select(a[i], b[i], c[i]); - } - - currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= NUM_CYCLES; - } - - vlog( "Select Timing:\n" ); - vlog( " \t scalar\t vector\n" ); - vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, TicksToCycles( vectorTime ) / LOOPCOUNT ); - - //printf("scalar = %llu, vector = %llu\n", scalarTime, vectorTime); - - for (i = 0; i < DATA_SIZE; i++) - { - Select_Ref_Res[i] = Select_ref(a_ref[i], b_ref[i], c_ref[i]); - Select_Test_Res[i] = Select(a[i], b[i], c[i]); - - if(Select_Test_Res[i] != Select_Ref_Res[i]) - { - printf("Select fail at %d with test = %d, ref = %d\n", i, Select_Test_Res[i], Select_Ref_Res[i]); - - printf("a_mx_f[0] = %.3f, a_mx_f[1] = %.3f, a_mx_f[2] = %.3f, a_mx_f[3] = %.3f\n", a[i].tMaxs().m_floats[0], a[i].tMaxs().m_floats[1], a[i].tMaxs().m_floats[2], a[i].tMaxs().m_floats[3]); - printf("a_mi_f[0] = %.3f, a_mi_f[1] = %.3f, a_mi_f[2] = %.3f, a_mi_f[3] = %.3f\n", a[i].tMins().m_floats[0], a[i].tMins().m_floats[1], a[i].tMins().m_floats[2], a[i].tMins().m_floats[3]); - printf("b_mx_f[0] = %.3f, b_mx_f[1] = %.3f, b_mx_f[2] = %.3f, b_mx_f[3] = %.3f\n", b[i].tMaxs().m_floats[0], b[i].tMaxs().m_floats[1], b[i].tMaxs().m_floats[2], b[i].tMaxs().m_floats[3]); - printf("b_mi_f[0] = %.3f, b_mi_f[1] = %.3f, b_mi_f[2] = %.3f, b_mi_f[3] = %.3f\n", b[i].tMins().m_floats[0], b[i].tMins().m_floats[1], b[i].tMins().m_floats[2], b[i].tMins().m_floats[3]); - printf("c_mx_f[0] = %.3f, c_mx_f[1] = %.3f, c_mx_f[2] = %.3f, c_mx_f[3] = %.3f\n", c[i].tMaxs().m_floats[0], c[i].tMaxs().m_floats[1], c[i].tMaxs().m_floats[2], c[i].tMaxs().m_floats[3]); - printf("c_mi_f[0] = %.3f, c_mi_f[1] = %.3f, c_mi_f[2] = %.3f, c_mi_f[3] = %.3f\n", c[i].tMins().m_floats[0], c[i].tMins().m_floats[1], c[i].tMins().m_floats[2], c[i].tMins().m_floats[3]); - - printf("a_mx_f_ref[0] = %.3f, a_mx_f_ref[1] = %.3f, a_mx_f_ref[2] = %.3f, a_mx_f_ref[3] = %.3f\n", a_ref[i].tMaxs().m_floats[0], a_ref[i].tMaxs().m_floats[1], a_ref[i].tMaxs().m_floats[2], a_ref[i].tMaxs().m_floats[3]); - printf("a_mi_f_ref[0] = %.3f, a_mi_f_ref[1] = %.3f, a_mi_f_ref[2] = %.3f, a_mi_f_ref[3] = %.3f\n", a_ref[i].tMins().m_floats[0], a_ref[i].tMins().m_floats[1], a_ref[i].tMins().m_floats[2], a_ref[i].tMins().m_floats[3]); - printf("b_mx_f_ref[0] = %.3f, b_mx_f_ref[1] = %.3f, b_mx_f_ref[2] = %.3f, b_mx_f_ref[3] = %.3f\n", b_ref[i].tMaxs().m_floats[0], b_ref[i].tMaxs().m_floats[1], b_ref[i].tMaxs().m_floats[2], b_ref[i].tMaxs().m_floats[3]); - printf("b_mi_f_ref[0] = %.3f, b_mi_f_ref[1] = %.3f, b_mi_f_ref[2] = %.3f, b_mi_f_ref[3] = %.3f\n", b_ref[i].tMins().m_floats[0], b_ref[i].tMins().m_floats[1], b_ref[i].tMins().m_floats[2], b_ref[i].tMins().m_floats[3]); - printf("c_mx_f_ref[0] = %.3f, c_mx_f_ref[1] = %.3f, c_mx_f_ref[2] = %.3f, c_mx_f_ref[3] = %.3f\n", c_ref[i].tMaxs().m_floats[0], c_ref[i].tMaxs().m_floats[1], c_ref[i].tMaxs().m_floats[2], c_ref[i].tMaxs().m_floats[3]); - printf("c_mi_f_ref[0] = %.3f, c_mi_f_ref[1] = %.3f, c_mi_f_ref[2] = %.3f, c_mi_f_ref[3] = %.3f\n", c_ref[i].tMins().m_floats[0], c_ref[i].tMins().m_floats[1], c_ref[i].tMins().m_floats[2], c_ref[i].tMins().m_floats[3]); + printf("Merge fail at %d with test = %d, ref = %d\n", i, Select_Test_Res[i], Select_Ref_Res[i]); + + printf("a_mx_f[0] = %.3f, a_mx_f[1] = %.3f, a_mx_f[2] = %.3f, a_mx_f[3] = %.3f\n", a[i].tMaxs().m_floats[0], a[i].tMaxs().m_floats[1], a[i].tMaxs().m_floats[2], a[i].tMaxs().m_floats[3]); + printf("a_mi_f[0] = %.3f, a_mi_f[1] = %.3f, a_mi_f[2] = %.3f, a_mi_f[3] = %.3f\n", a[i].tMins().m_floats[0], a[i].tMins().m_floats[1], a[i].tMins().m_floats[2], a[i].tMins().m_floats[3]); + printf("b_mx_f[0] = %.3f, b_mx_f[1] = %.3f, b_mx_f[2] = %.3f, b_mx_f[3] = %.3f\n", b[i].tMaxs().m_floats[0], b[i].tMaxs().m_floats[1], b[i].tMaxs().m_floats[2], b[i].tMaxs().m_floats[3]); + printf("b_mi_f[0] = %.3f, b_mi_f[1] = %.3f, b_mi_f[2] = %.3f, b_mi_f[3] = %.3f\n", b[i].tMins().m_floats[0], b[i].tMins().m_floats[1], b[i].tMins().m_floats[2], b[i].tMins().m_floats[3]); + printf("c_mx_f[0] = %.3f, c_mx_f[1] = %.3f, c_mx_f[2] = %.3f, c_mx_f[3] = %.3f\n", c[i].tMaxs().m_floats[0], c[i].tMaxs().m_floats[1], c[i].tMaxs().m_floats[2], c[i].tMaxs().m_floats[3]); + printf("c_mi_f[0] = %.3f, c_mi_f[1] = %.3f, c_mi_f[2] = %.3f, c_mi_f[3] = %.3f\n", c[i].tMins().m_floats[0], c[i].tMins().m_floats[1], c[i].tMins().m_floats[2], c[i].tMins().m_floats[3]); + + printf("a_mx_f_ref[0] = %.3f, a_mx_f_ref[1] = %.3f, a_mx_f_ref[2] = %.3f, a_mx_f_ref[3] = %.3f\n", a_ref[i].tMaxs().m_floats[0], a_ref[i].tMaxs().m_floats[1], a_ref[i].tMaxs().m_floats[2], a_ref[i].tMaxs().m_floats[3]); + printf("a_mi_f_ref[0] = %.3f, a_mi_f_ref[1] = %.3f, a_mi_f_ref[2] = %.3f, a_mi_f_ref[3] = %.3f\n", a_ref[i].tMins().m_floats[0], a_ref[i].tMins().m_floats[1], a_ref[i].tMins().m_floats[2], a_ref[i].tMins().m_floats[3]); + printf("b_mx_f_ref[0] = %.3f, b_mx_f_ref[1] = %.3f, b_mx_f_ref[2] = %.3f, b_mx_f_ref[3] = %.3f\n", b_ref[i].tMaxs().m_floats[0], b_ref[i].tMaxs().m_floats[1], b_ref[i].tMaxs().m_floats[2], b_ref[i].tMaxs().m_floats[3]); + printf("b_mi_f_ref[0] = %.3f, b_mi_f_ref[1] = %.3f, b_mi_f_ref[2] = %.3f, b_mi_f_ref[3] = %.3f\n", b_ref[i].tMins().m_floats[0], b_ref[i].tMins().m_floats[1], b_ref[i].tMins().m_floats[2], b_ref[i].tMins().m_floats[3]); + printf("c_mx_f_ref[0] = %.3f, c_mx_f_ref[1] = %.3f, c_mx_f_ref[2] = %.3f, c_mx_f_ref[3] = %.3f\n", c_ref[i].tMaxs().m_floats[0], c_ref[i].tMaxs().m_floats[1], c_ref[i].tMaxs().m_floats[2], c_ref[i].tMaxs().m_floats[3]); + printf("c_mi_f_ref[0] = %.3f, c_mi_f_ref[1] = %.3f, c_mi_f_ref[2] = %.3f, c_mi_f_ref[3] = %.3f\n", c_ref[i].tMins().m_floats[0], c_ref[i].tMins().m_floats[1], c_ref[i].tMins().m_floats[2], c_ref[i].tMins().m_floats[3]); return 1; } - - } - - return 0; + } + + //////////////////////////////////// + // + // Time and Test Select + // + //////////////////////////////////// + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + startTime = ReadTicks(); + + for (i = 0; i < DATA_SIZE; i++) + { + Select_Ref_Res[i] = Select_ref(a_ref[i], b_ref[i], c_ref[i]); + } + + currentTime = ReadTicks() - startTime; + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + startTime = ReadTicks(); + + for (i = 0; i < DATA_SIZE; i++) + { + Select_Test_Res[i] = Select(a[i], b[i], c[i]); + } + + currentTime = ReadTicks() - startTime; + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog("Select Timing:\n"); + vlog(" \t scalar\t vector\n"); + vlog(" \t%10.4f\t%10.4f\n", TicksToCycles(scalarTime) / LOOPCOUNT, TicksToCycles(vectorTime) / LOOPCOUNT); + + //printf("scalar = %llu, vector = %llu\n", scalarTime, vectorTime); + + for (i = 0; i < DATA_SIZE; i++) + { + Select_Ref_Res[i] = Select_ref(a_ref[i], b_ref[i], c_ref[i]); + Select_Test_Res[i] = Select(a[i], b[i], c[i]); + + if (Select_Test_Res[i] != Select_Ref_Res[i]) + { + printf("Select fail at %d with test = %d, ref = %d\n", i, Select_Test_Res[i], Select_Ref_Res[i]); + + printf("a_mx_f[0] = %.3f, a_mx_f[1] = %.3f, a_mx_f[2] = %.3f, a_mx_f[3] = %.3f\n", a[i].tMaxs().m_floats[0], a[i].tMaxs().m_floats[1], a[i].tMaxs().m_floats[2], a[i].tMaxs().m_floats[3]); + printf("a_mi_f[0] = %.3f, a_mi_f[1] = %.3f, a_mi_f[2] = %.3f, a_mi_f[3] = %.3f\n", a[i].tMins().m_floats[0], a[i].tMins().m_floats[1], a[i].tMins().m_floats[2], a[i].tMins().m_floats[3]); + printf("b_mx_f[0] = %.3f, b_mx_f[1] = %.3f, b_mx_f[2] = %.3f, b_mx_f[3] = %.3f\n", b[i].tMaxs().m_floats[0], b[i].tMaxs().m_floats[1], b[i].tMaxs().m_floats[2], b[i].tMaxs().m_floats[3]); + printf("b_mi_f[0] = %.3f, b_mi_f[1] = %.3f, b_mi_f[2] = %.3f, b_mi_f[3] = %.3f\n", b[i].tMins().m_floats[0], b[i].tMins().m_floats[1], b[i].tMins().m_floats[2], b[i].tMins().m_floats[3]); + printf("c_mx_f[0] = %.3f, c_mx_f[1] = %.3f, c_mx_f[2] = %.3f, c_mx_f[3] = %.3f\n", c[i].tMaxs().m_floats[0], c[i].tMaxs().m_floats[1], c[i].tMaxs().m_floats[2], c[i].tMaxs().m_floats[3]); + printf("c_mi_f[0] = %.3f, c_mi_f[1] = %.3f, c_mi_f[2] = %.3f, c_mi_f[3] = %.3f\n", c[i].tMins().m_floats[0], c[i].tMins().m_floats[1], c[i].tMins().m_floats[2], c[i].tMins().m_floats[3]); + + printf("a_mx_f_ref[0] = %.3f, a_mx_f_ref[1] = %.3f, a_mx_f_ref[2] = %.3f, a_mx_f_ref[3] = %.3f\n", a_ref[i].tMaxs().m_floats[0], a_ref[i].tMaxs().m_floats[1], a_ref[i].tMaxs().m_floats[2], a_ref[i].tMaxs().m_floats[3]); + printf("a_mi_f_ref[0] = %.3f, a_mi_f_ref[1] = %.3f, a_mi_f_ref[2] = %.3f, a_mi_f_ref[3] = %.3f\n", a_ref[i].tMins().m_floats[0], a_ref[i].tMins().m_floats[1], a_ref[i].tMins().m_floats[2], a_ref[i].tMins().m_floats[3]); + printf("b_mx_f_ref[0] = %.3f, b_mx_f_ref[1] = %.3f, b_mx_f_ref[2] = %.3f, b_mx_f_ref[3] = %.3f\n", b_ref[i].tMaxs().m_floats[0], b_ref[i].tMaxs().m_floats[1], b_ref[i].tMaxs().m_floats[2], b_ref[i].tMaxs().m_floats[3]); + printf("b_mi_f_ref[0] = %.3f, b_mi_f_ref[1] = %.3f, b_mi_f_ref[2] = %.3f, b_mi_f_ref[3] = %.3f\n", b_ref[i].tMins().m_floats[0], b_ref[i].tMins().m_floats[1], b_ref[i].tMins().m_floats[2], b_ref[i].tMins().m_floats[3]); + printf("c_mx_f_ref[0] = %.3f, c_mx_f_ref[1] = %.3f, c_mx_f_ref[2] = %.3f, c_mx_f_ref[3] = %.3f\n", c_ref[i].tMaxs().m_floats[0], c_ref[i].tMaxs().m_floats[1], c_ref[i].tMaxs().m_floats[2], c_ref[i].tMaxs().m_floats[3]); + printf("c_mi_f_ref[0] = %.3f, c_mi_f_ref[1] = %.3f, c_mi_f_ref[2] = %.3f, c_mi_f_ref[3] = %.3f\n", c_ref[i].tMins().m_floats[0], c_ref[i].tMins().m_floats[1], c_ref[i].tMins().m_floats[2], c_ref[i].tMins().m_floats[3]); + return 1; + } + } + + return 0; } #endif - - - - diff --git a/test/Bullet2/Source/Tests/Test_btDbvt.h b/test/Bullet2/Source/Tests/Test_btDbvt.h index 92e309a11..5fc17d531 100644 --- a/test/Bullet2/Source/Tests/Test_btDbvt.h +++ b/test/Bullet2/Source/Tests/Test_btDbvt.h @@ -9,11 +9,12 @@ #define BulletTest_Test_btDbvt_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif - - int Test_btDbvt(void); - + + int Test_btDbvt(void); + #ifdef __cplusplus } #endif diff --git a/test/Bullet2/Source/Tests/Test_dot3.cpp b/test/Bullet2/Source/Tests/Test_dot3.cpp index ef3ff4a55..a46202a5f 100644 --- a/test/Bullet2/Source/Tests/Test_dot3.cpp +++ b/test/Bullet2/Source/Tests/Test_dot3.cpp @@ -5,10 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_dot3.h" #include "vector.h" @@ -20,10 +18,10 @@ #include // reference code for testing purposes -static btVector3 dot3_ref( const btVector3 &, const btVector3 &, const btVector3 &, const btVector3 &); -static btVector3 dot3_ref( const btVector3 &v, const btVector3 &v1, const btVector3 &v2, const btVector3 &v3) +static btVector3 dot3_ref(const btVector3 &, const btVector3 &, const btVector3 &, const btVector3 &); +static btVector3 dot3_ref(const btVector3 &v, const btVector3 &v1, const btVector3 &v2, const btVector3 &v3) { - return btVector3( v.dot(v1), v.dot(v2), v.dot(v3)); + return btVector3(v.dot(v1), v.dot(v2), v.dot(v3)); } /* @@ -44,110 +42,112 @@ SIMD_FORCE_INLINE int operator!=(const btVector3 &s, const btVector3 &v) #endif } */ - - #define LOOPCOUNT 1000 #define NUM_CYCLES 10000 int Test_dot3(void) { - btVector3 v, v1, v2, v3; - + btVector3 v, v1, v2, v3; + #define DATA_SIZE 1024 - + btVector3 vec3_arr[DATA_SIZE]; btVector3 vec3_arr1[DATA_SIZE]; btVector3 vec3_arr2[DATA_SIZE]; btVector3 vec3_arr3[DATA_SIZE]; - btVector3 res_arr[DATA_SIZE]; - - uint64_t scalarTime; - uint64_t vectorTime; - size_t j, k; - btVector3 correct, test; - - for( k = 0; k < DATA_SIZE; k++ ) + btVector3 res_arr[DATA_SIZE]; + + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; + btVector3 correct, test; + + for (k = 0; k < DATA_SIZE; k++) { - - vec3_arr[k] = btVector3( btAssign128( RANDF, RANDF, RANDF, BT_NAN)); - vec3_arr1[k] = btVector3( btAssign128( RANDF, RANDF, RANDF, BT_NAN)); - vec3_arr2[k] = btVector3( btAssign128( RANDF, RANDF, RANDF, BT_NAN )); - vec3_arr3[k] = btVector3( btAssign128( RANDF, RANDF, RANDF, BT_NAN)); + vec3_arr[k] = btVector3(btAssign128(RANDF, RANDF, RANDF, BT_NAN)); + vec3_arr1[k] = btVector3(btAssign128(RANDF, RANDF, RANDF, BT_NAN)); + vec3_arr2[k] = btVector3(btAssign128(RANDF, RANDF, RANDF, BT_NAN)); + vec3_arr3[k] = btVector3(btAssign128(RANDF, RANDF, RANDF, BT_NAN)); correct = dot3_ref(vec3_arr[k], vec3_arr1[k], vec3_arr2[k], vec3_arr3[k]); - test = vec3_arr[k].dot3( vec3_arr1[k], vec3_arr2[k], vec3_arr3[k]); - - if( correct != test ) + test = vec3_arr[k].dot3(vec3_arr1[k], vec3_arr2[k], vec3_arr3[k]); + + if (correct != test) { - vlog( "Error (%ld) - dot3 result error! *{%a, %a, %a, %a} != {%a, %a, %a, %a} \n", k, - correct.x(), correct.y(), correct.z(), correct.w(), - test.x(), test.y(), test.z(), test.w() ); - + vlog("Error (%ld) - dot3 result error! *{%a, %a, %a, %a} != {%a, %a, %a, %a} \n", k, + correct.x(), correct.y(), correct.z(), correct.w(), + test.x(), test.y(), test.z(), test.w()); + return 1; } - } - - + } + { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - startTime = ReadTicks(); - for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + startTime = ReadTicks(); + for (k = 0; k + 4 <= LOOPCOUNT; k += 4) { - size_t k32 = (k & (DATA_SIZE-1)); - res_arr[k32] = dot3_ref( vec3_arr[k32], vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); k32++; - res_arr[k32] = dot3_ref( vec3_arr[k32], vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); k32++; - res_arr[k32] = dot3_ref( vec3_arr[k32], vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); k32++; - res_arr[k32] = dot3_ref( vec3_arr[k32], vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); + size_t k32 = (k & (DATA_SIZE - 1)); + res_arr[k32] = dot3_ref(vec3_arr[k32], vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); + k32++; + res_arr[k32] = dot3_ref(vec3_arr[k32], vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); + k32++; + res_arr[k32] = dot3_ref(vec3_arr[k32], vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); + k32++; + res_arr[k32] = dot3_ref(vec3_arr[k32], vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); } currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= NUM_CYCLES; - } - - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - startTime = ReadTicks(); - for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + startTime = ReadTicks(); + for (k = 0; k + 4 <= LOOPCOUNT; k += 4) { - size_t k32 = (k & (DATA_SIZE-1)); - res_arr[k32] = vec3_arr[k32].dot3( vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); k32++; - res_arr[k32] = vec3_arr[k32].dot3( vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); k32++; - res_arr[k32] = vec3_arr[k32].dot3( vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); k32++; - res_arr[k32] = vec3_arr[k32].dot3( vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); + size_t k32 = (k & (DATA_SIZE - 1)); + res_arr[k32] = vec3_arr[k32].dot3(vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); + k32++; + res_arr[k32] = vec3_arr[k32].dot3(vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); + k32++; + res_arr[k32] = vec3_arr[k32].dot3(vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); + k32++; + res_arr[k32] = vec3_arr[k32].dot3(vec3_arr1[k32], vec3_arr2[k32], vec3_arr3[k32]); } currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= NUM_CYCLES; - } - - vlog( "Timing:\n" ); - vlog( " \t scalar\t vector\n" ); - vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, TicksToCycles( vectorTime ) / LOOPCOUNT ); - - return 0; + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } + + vlog("Timing:\n"); + vlog(" \t scalar\t vector\n"); + vlog(" \t%10.4f\t%10.4f\n", TicksToCycles(scalarTime) / LOOPCOUNT, TicksToCycles(vectorTime) / LOOPCOUNT); + + return 0; } -#endif //BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_dot3.h b/test/Bullet2/Source/Tests/Test_dot3.h index cb525f88a..0caf2fbb3 100644 --- a/test/Bullet2/Source/Tests/Test_dot3.h +++ b/test/Bullet2/Source/Tests/Test_dot3.h @@ -9,14 +9,14 @@ #define BulletTest_Test_dot3_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif - - int Test_dot3(void); - + + int Test_dot3(void); + #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_maxdot.cpp b/test/Bullet2/Source/Tests/Test_maxdot.cpp index acc0caeb4..d17fca742 100644 --- a/test/Bullet2/Source/Tests/Test_maxdot.cpp +++ b/test/Bullet2/Source/Tests/Test_maxdot.cpp @@ -5,11 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_maxdot.h" #include "vector.h" @@ -20,114 +17,109 @@ #include - // reference code for testing purposes -static long maxdot_ref( const btSimdFloat4 *vertices, - float *vec, - size_t count, - float *dotResult ); - - - - +static long maxdot_ref(const btSimdFloat4 *vertices, + float *vec, + size_t count, + float *dotResult); #ifdef __arm__ - #define MAX_LOG2_SIZE 9 +#define MAX_LOG2_SIZE 9 #else - #define MAX_LOG2_SIZE 10 +#define MAX_LOG2_SIZE 10 #endif -#define MAX_SIZE (1U << MAX_LOG2_SIZE) +#define MAX_SIZE (1U << MAX_LOG2_SIZE) #define LOOPCOUNT 10 int Test_maxdot(void) { - // Init an array flanked by guard pages - btSimdFloat4 *data = (btSimdFloat4*) GuardCalloc( 1, MAX_SIZE * sizeof(btSimdFloat4), NULL ); - float *fp = (float*) data; - long correct, test; - btVector3 localScaling( 0.1f, 0.2f, 0.3f); - size_t size; - - // Init the data - size_t i; - for( i = 0; i < MAX_SIZE; i++ ) - { - fp[4*i] = (int32_t) RANDF_16; - fp[4*i+1] = (int32_t) RANDF_16; - fp[4*i+2] = (int32_t) RANDF_16; - fp[4*i+3] = BT_NAN; // w channel NaN - } - - float correctDot, testDot; - fp = (float*) localScaling; + // Init an array flanked by guard pages + btSimdFloat4 *data = (btSimdFloat4 *)GuardCalloc(1, MAX_SIZE * sizeof(btSimdFloat4), NULL); + float *fp = (float *)data; + long correct, test; + btVector3 localScaling(0.1f, 0.2f, 0.3f); + size_t size; + + // Init the data + size_t i; + for (i = 0; i < MAX_SIZE; i++) + { + fp[4 * i] = (int32_t)RANDF_16; + fp[4 * i + 1] = (int32_t)RANDF_16; + fp[4 * i + 2] = (int32_t)RANDF_16; + fp[4 * i + 3] = BT_NAN; // w channel NaN + } + + float correctDot, testDot; + fp = (float *)localScaling; float maxRelativeError = 0.f; - - for( size = 1; size <= MAX_SIZE; size++ ) - { - float *in = (float*)(data + MAX_SIZE - size); - size_t position; - - for( position = 0; position < size; position++ ) - { - float *biggest = in + position * 4; - float old[4] = { biggest[0], biggest[1], biggest[2], biggest[3] }; - biggest[0] += LARGE_FLOAT17; - biggest[1] += LARGE_FLOAT17; - biggest[2] += LARGE_FLOAT17; - biggest[3] += LARGE_FLOAT17; - - correctDot = BT_NAN; - testDot = BT_NAN; - correct = maxdot_ref( (btSimdFloat4*) in, (float*) &localScaling, size, &correctDot); - test = localScaling.maxDot( (btVector3*) in, size, testDot); - if( test < 0 || test >= size ) - { - vlog( "Error @ %ld: index out of bounds! *%ld vs %ld \n", size, correct, test); - continue; - } - if( correct != test ) + + for (size = 1; size <= MAX_SIZE; size++) + { + float *in = (float *)(data + MAX_SIZE - size); + size_t position; + + for (position = 0; position < size; position++) + { + float *biggest = in + position * 4; + float old[4] = {biggest[0], biggest[1], biggest[2], biggest[3]}; + biggest[0] += LARGE_FLOAT17; + biggest[1] += LARGE_FLOAT17; + biggest[2] += LARGE_FLOAT17; + biggest[3] += LARGE_FLOAT17; + + correctDot = BT_NAN; + testDot = BT_NAN; + correct = maxdot_ref((btSimdFloat4 *)in, (float *)&localScaling, size, &correctDot); + test = localScaling.maxDot((btVector3 *)in, size, testDot); + if (test < 0 || test >= size) { - vlog( "Error @ %ld: index misreported! *%ld vs %ld (*%f, %f)\n", size, correct, test, - fp[0] * in[4*correct] + fp[1] * in[4*correct+1] + fp[2] * in[4*correct+2], - fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2] ); + vlog("Error @ %ld: index out of bounds! *%ld vs %ld \n", size, correct, test); + continue; + } + if (correct != test) + { + vlog("Error @ %ld: index misreported! *%ld vs %ld (*%f, %f)\n", size, correct, test, + fp[0] * in[4 * correct] + fp[1] * in[4 * correct + 1] + fp[2] * in[4 * correct + 2], + fp[0] * in[4 * test] + fp[1] * in[4 * test + 1] + fp[2] * in[4 * test + 2]); return 1; } - if( test != position ) + if (test != position) { - vlog( "Biggest not found where it is supposed to be: *%ld vs %ld (*%f, %f)\n", position, test, - fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2], - fp[0] * in[4*position] + fp[1] * in[4*position+1] + fp[2] * in[4*position+2] ); + vlog("Biggest not found where it is supposed to be: *%ld vs %ld (*%f, %f)\n", position, test, + fp[0] * in[4 * test] + fp[1] * in[4 * test + 1] + fp[2] * in[4 * test + 2], + fp[0] * in[4 * position] + fp[1] * in[4 * position + 1] + fp[2] * in[4 * position + 2]); return 1; } - if( correctDot != testDot ) + if (correctDot != testDot) { float relativeError = btFabs((testDot - correctDot) / correctDot); - if (relativeError>1e-6) + if (relativeError > 1e-6) { - vlog( "Error @ %ld: dotpr misreported! *%f vs %f (*%f, %f)\n", size, correctDot, testDot, - fp[0] * in[4*correct] + fp[1] * in[4*correct+1] + fp[2] * in[4*correct+2], - fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2] ); - return 1; - } else + vlog("Error @ %ld: dotpr misreported! *%f vs %f (*%f, %f)\n", size, correctDot, testDot, + fp[0] * in[4 * correct] + fp[1] * in[4 * correct + 1] + fp[2] * in[4 * correct + 2], + fp[0] * in[4 * test] + fp[1] * in[4 * test + 1] + fp[2] * in[4 * test + 2]); + return 1; + } + else { if (maxRelativeError < relativeError) { maxRelativeError = relativeError; #ifdef VERBOSE_WARNING - sprintf(errStr,"Warning @ %ld: dotpr misreported! *%f vs %f (*%f, %f)\n", size, correctDot, testDot, - fp[0] * in[4*correct] + fp[1] * in[4*correct+1] + fp[2] * in[4*correct+2], - fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2]); -#endif //VERBOSE_WARNING + sprintf(errStr, "Warning @ %ld: dotpr misreported! *%f vs %f (*%f, %f)\n", size, correctDot, testDot, + fp[0] * in[4 * correct] + fp[1] * in[4 * correct + 1] + fp[2] * in[4 * correct + 2], + fp[0] * in[4 * test] + fp[1] * in[4 * test + 1] + fp[2] * in[4 * test + 2]); +#endif //VERBOSE_WARNING } } } - - memcpy( biggest, old, 16 ); - } - } - - + + memcpy(biggest, old, 16); + } + } + if (maxRelativeError) { printf("Warning: relative error = %e\n", maxRelativeError); @@ -136,146 +128,149 @@ int Test_maxdot(void) #endif } - uint64_t scalarTimes[33 + (MAX_LOG2_SIZE-5)]; - uint64_t vectorTimes[33 + (MAX_LOG2_SIZE-5)]; - size_t j, k; - float *in = (float*) data; - for( size = 1; size <= 32; size++ ) - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - scalarTimes[size] = 0; - for (j = 0; j < 100; j++) { - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) - correct += maxdot_ref( (btSimdFloat4*) in, (float*) &localScaling, size, &correctDot); - currentTime = ReadTicks() - startTime; - scalarTimes[size] += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTimes[size] = bestTime; - else - scalarTimes[size] /= 100; - } - - uint64_t *timep = &scalarTimes[33]; - for( size = 64; size <= MAX_SIZE; size *= 2 ) - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - timep[0] =0; - for (j = 0; j < 100; j++) { - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) - correct += maxdot_ref( (btSimdFloat4*) in, (float*) &localScaling, size, &correctDot); - currentTime = ReadTicks() - startTime; - timep[0] += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - timep[0] = bestTime; - else - timep[0] /= 100; + uint64_t scalarTimes[33 + (MAX_LOG2_SIZE - 5)]; + uint64_t vectorTimes[33 + (MAX_LOG2_SIZE - 5)]; + size_t j, k; + float *in = (float *)data; + for (size = 1; size <= 32; size++) + { + uint64_t startTime, bestTime, currentTime; - timep++; - } + bestTime = -1LL; + scalarTimes[size] = 0; + for (j = 0; j < 100; j++) + { + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) + correct += maxdot_ref((btSimdFloat4 *)in, (float *)&localScaling, size, &correctDot); + currentTime = ReadTicks() - startTime; + scalarTimes[size] += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTimes[size] = bestTime; + else + scalarTimes[size] /= 100; + } - for( size = 1; size <= 32; size++ ) - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - vectorTimes[size] = 0; - for (j = 0; j < 100; j++) { - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) - test += localScaling.maxDot( (btVector3*) in, size, testDot); - currentTime = ReadTicks() - startTime; - vectorTimes[size] += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTimes[size] = bestTime; - else - vectorTimes[size] /= 100; - } - - timep = &vectorTimes[33]; - for( size = 64; size <= MAX_SIZE; size *= 2 ) - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - timep[0] =0; - for (j = 0; j < 100; j++) { - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) - test += localScaling.maxDot( (btVector3*) in, size, testDot); - currentTime = ReadTicks() - startTime; - timep[0] += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - timep[0] = bestTime; - else - timep[0] /= 100; - - timep++; - } - - vlog( "Timing:\n" ); - vlog( " size\t scalar\t vector\n" ); - for( size = 1; size <= 32; size++ ) - vlog( "%5lu\t%10.2f\t%10.2f\n", size, TicksToCycles( scalarTimes[size] ) / LOOPCOUNT, TicksToCycles( vectorTimes[size] ) / LOOPCOUNT ); - size_t index = 33; - for( size = 64; size <= MAX_SIZE; size *= 2 ) - { - vlog( "%5lu\t%10.2f\t%10.2f\n", size, TicksToCycles( scalarTimes[index] ) / LOOPCOUNT, TicksToCycles( vectorTimes[index] ) / LOOPCOUNT ); - index++; - } - - // Useless check to make sure that the timing loops are not optimized away - if( test != correct ) - vlog( "Error: Test != correct: *%ld vs. %ld\n", correct, test); - - GuardFree(data); - - return 0; + uint64_t *timep = &scalarTimes[33]; + for (size = 64; size <= MAX_SIZE; size *= 2) + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + timep[0] = 0; + for (j = 0; j < 100; j++) + { + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) + correct += maxdot_ref((btSimdFloat4 *)in, (float *)&localScaling, size, &correctDot); + currentTime = ReadTicks() - startTime; + timep[0] += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + timep[0] = bestTime; + else + timep[0] /= 100; + + timep++; + } + + for (size = 1; size <= 32; size++) + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTimes[size] = 0; + for (j = 0; j < 100; j++) + { + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) + test += localScaling.maxDot((btVector3 *)in, size, testDot); + currentTime = ReadTicks() - startTime; + vectorTimes[size] += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTimes[size] = bestTime; + else + vectorTimes[size] /= 100; + } + + timep = &vectorTimes[33]; + for (size = 64; size <= MAX_SIZE; size *= 2) + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + timep[0] = 0; + for (j = 0; j < 100; j++) + { + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) + test += localScaling.maxDot((btVector3 *)in, size, testDot); + currentTime = ReadTicks() - startTime; + timep[0] += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + timep[0] = bestTime; + else + timep[0] /= 100; + + timep++; + } + + vlog("Timing:\n"); + vlog(" size\t scalar\t vector\n"); + for (size = 1; size <= 32; size++) + vlog("%5lu\t%10.2f\t%10.2f\n", size, TicksToCycles(scalarTimes[size]) / LOOPCOUNT, TicksToCycles(vectorTimes[size]) / LOOPCOUNT); + size_t index = 33; + for (size = 64; size <= MAX_SIZE; size *= 2) + { + vlog("%5lu\t%10.2f\t%10.2f\n", size, TicksToCycles(scalarTimes[index]) / LOOPCOUNT, TicksToCycles(vectorTimes[index]) / LOOPCOUNT); + index++; + } + + // Useless check to make sure that the timing loops are not optimized away + if (test != correct) + vlog("Error: Test != correct: *%ld vs. %ld\n", correct, test); + + GuardFree(data); + + return 0; } - -static long maxdot_ref( const btSimdFloat4 *vertices, - float *vec, - size_t count, - float *dotResult ) +static long maxdot_ref(const btSimdFloat4 *vertices, + float *vec, + size_t count, + float *dotResult) { - - const float *dp = (const float*) vertices; - float maxDot = -BT_INFINITY; - long i = 0; - long ptIndex = -1; - - for( i = 0; i < count; i++ ) - { - float dot = vec[0] * dp[0] + vec[1] * dp[1] + vec[2] * dp[2]; dp += 4; - - if( dot > maxDot ) - { - maxDot = dot; - ptIndex = i; - } - } - - *dotResult = maxDot; - - return ptIndex; + const float *dp = (const float *)vertices; + float maxDot = -BT_INFINITY; + long i = 0; + long ptIndex = -1; + + for (i = 0; i < count; i++) + { + float dot = vec[0] * dp[0] + vec[1] * dp[1] + vec[2] * dp[2]; + dp += 4; + + if (dot > maxDot) + { + maxDot = dot; + ptIndex = i; + } + } + + *dotResult = maxDot; + + return ptIndex; } -#endif //BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_maxdot.h b/test/Bullet2/Source/Tests/Test_maxdot.h index 2e6c517f2..406ced90e 100644 --- a/test/Bullet2/Source/Tests/Test_maxdot.h +++ b/test/Bullet2/Source/Tests/Test_maxdot.h @@ -9,14 +9,14 @@ #define BulletTest_Test_maxdot_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_maxdot(void); + int Test_maxdot(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_mindot.cpp b/test/Bullet2/Source/Tests/Test_mindot.cpp index 2f4425621..b30718dee 100644 --- a/test/Bullet2/Source/Tests/Test_mindot.cpp +++ b/test/Bullet2/Source/Tests/Test_mindot.cpp @@ -5,11 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_mindot.h" #include "vector.h" @@ -20,92 +17,92 @@ #include - // reference code for testing purposes -static long mindot_ref( const btSimdFloat4 *vertices, - float *vec, - size_t count, - float *dotResult ); +static long mindot_ref(const btSimdFloat4 *vertices, + float *vec, + size_t count, + float *dotResult); #ifdef __arm__ - #define MAX_LOG2_SIZE 9 +#define MAX_LOG2_SIZE 9 #else - #define MAX_LOG2_SIZE 9 +#define MAX_LOG2_SIZE 9 #endif -#define MAX_SIZE (1U << MAX_LOG2_SIZE) +#define MAX_SIZE (1U << MAX_LOG2_SIZE) #define LOOPCOUNT 100 int Test_mindot(void) { - // Init an array flanked by guard pages - btSimdFloat4 *data = (btSimdFloat4*) GuardCalloc( 1, MAX_SIZE * sizeof(btSimdFloat4), NULL ); - float *fp = (float*) data; - long correct, test; - btVector3 localScaling( 0.1f, 0.2f, 0.3f); - size_t size; - - // Init the data - size_t i; - for( i = 0; i < MAX_SIZE; i++ ) - { - fp[4*i] = (int32_t) RANDF_16; - fp[4*i+1] = (int32_t) RANDF_16; - fp[4*i+2] = (int32_t) RANDF_16; - fp[4*i+3] = BT_NAN; // w channel NaN - } - - float correctDot, testDot; - fp = (float*) localScaling; + // Init an array flanked by guard pages + btSimdFloat4 *data = (btSimdFloat4 *)GuardCalloc(1, MAX_SIZE * sizeof(btSimdFloat4), NULL); + float *fp = (float *)data; + long correct, test; + btVector3 localScaling(0.1f, 0.2f, 0.3f); + size_t size; + + // Init the data + size_t i; + for (i = 0; i < MAX_SIZE; i++) + { + fp[4 * i] = (int32_t)RANDF_16; + fp[4 * i + 1] = (int32_t)RANDF_16; + fp[4 * i + 2] = (int32_t)RANDF_16; + fp[4 * i + 3] = BT_NAN; // w channel NaN + } + + float correctDot, testDot; + fp = (float *)localScaling; float maxRelativeError = 0.f; - for( size = 1; size <= MAX_SIZE; size++ ) - { - float *in = (float*)(data + MAX_SIZE - size); - size_t position; - - for( position = 0; position < size; position++ ) - { - float *biggest = in + position * 4; - float old[4] = { biggest[0], biggest[1], biggest[2], biggest[3] }; - biggest[0] -= LARGE_FLOAT17; - biggest[1] -= LARGE_FLOAT17; - biggest[2] -= LARGE_FLOAT17; - biggest[3] -= LARGE_FLOAT17; - - correctDot = BT_NAN; - testDot = BT_NAN; - correct = mindot_ref( (btSimdFloat4*) in, (float*) &localScaling, size, &correctDot); - test = localScaling.minDot( (btVector3*) in, size, testDot); - if( test < 0 || test >= size ) - { - vlog( "Error @ %ld: index out of bounds! *%ld vs %ld \n", size, correct, test); - continue; - } - if( correct != test ) + for (size = 1; size <= MAX_SIZE; size++) + { + float *in = (float *)(data + MAX_SIZE - size); + size_t position; + + for (position = 0; position < size; position++) + { + float *biggest = in + position * 4; + float old[4] = {biggest[0], biggest[1], biggest[2], biggest[3]}; + biggest[0] -= LARGE_FLOAT17; + biggest[1] -= LARGE_FLOAT17; + biggest[2] -= LARGE_FLOAT17; + biggest[3] -= LARGE_FLOAT17; + + correctDot = BT_NAN; + testDot = BT_NAN; + correct = mindot_ref((btSimdFloat4 *)in, (float *)&localScaling, size, &correctDot); + test = localScaling.minDot((btVector3 *)in, size, testDot); + if (test < 0 || test >= size) { - vlog( "Error @ %ld: index misreported! *%ld vs %ld (*%f, %f)\n", size, correct, test, - fp[0] * in[4*correct] + fp[1] * in[4*correct+1] + fp[2] * in[4*correct+2], - fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2] ); + vlog("Error @ %ld: index out of bounds! *%ld vs %ld \n", size, correct, test); + continue; + } + if (correct != test) + { + vlog("Error @ %ld: index misreported! *%ld vs %ld (*%f, %f)\n", size, correct, test, + fp[0] * in[4 * correct] + fp[1] * in[4 * correct + 1] + fp[2] * in[4 * correct + 2], + fp[0] * in[4 * test] + fp[1] * in[4 * test + 1] + fp[2] * in[4 * test + 2]); return 1; } - if( test != position ) + if (test != position) { - vlog( "Biggest not found where it is supposed to be: *%ld vs %ld (*%f, %f)\n", position, test, - fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2], - fp[0] * in[4*position] + fp[1] * in[4*position+1] + fp[2] * in[4*position+2] ); + vlog("Biggest not found where it is supposed to be: *%ld vs %ld (*%f, %f)\n", position, test, + fp[0] * in[4 * test] + fp[1] * in[4 * test + 1] + fp[2] * in[4 * test + 2], + fp[0] * in[4 * position] + fp[1] * in[4 * position + 1] + fp[2] * in[4 * position + 2]); return 1; } - if( correctDot != testDot ) + if (correctDot != testDot) { float relativeError = btFabs((testDot - correctDot) / correctDot); - if (relativeError>1e6) + if (relativeError > 1e6) { - vlog( "Error @ %ld: dotpr misreported! *%f vs %f (*%f, %f)\n", size, correctDot, testDot, - fp[0] * in[4*correct] + fp[1] * in[4*correct+1] + fp[2] * in[4*correct+2], - fp[0] * in[4*test] + fp[1] * in[4*test+1] + fp[2] * in[4*test+2] ); + vlog("Error @ %ld: dotpr misreported! *%f vs %f (*%f, %f)\n", size, correctDot, testDot, + fp[0] * in[4 * correct] + fp[1] * in[4 * correct + 1] + fp[2] * in[4 * correct + 2], + fp[0] * in[4 * test] + fp[1] * in[4 * test + 1] + fp[2] * in[4 * test + 2]); return 1; - } else + } + else { if (maxRelativeError < relativeError) { @@ -114,156 +111,157 @@ int Test_mindot(void) } } - - memcpy( biggest, old, 16 ); - } - } - + memcpy(biggest, old, 16); + } + } + if (maxRelativeError) { printf("Warning: relative error = %e\n", maxRelativeError); } - uint64_t scalarTimes[33 + (MAX_LOG2_SIZE-5)]; - uint64_t vectorTimes[33 + (MAX_LOG2_SIZE-5)]; - size_t j, k; - float *in = (float*) data; - for( size = 1; size <= 32; size++ ) - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - scalarTimes[size] = 0; - for (j = 0; j < 100; j++) { - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) - correct += mindot_ref( (btSimdFloat4*) in, (float*) &localScaling, size, &correctDot); - currentTime = ReadTicks() - startTime; - scalarTimes[size] += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTimes[size] = bestTime; - else - scalarTimes[size] /= 100; - } - - uint64_t *timep = &scalarTimes[33]; - for( size = 64; size <= MAX_SIZE; size *= 2 ) - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - timep[0] =0; - for (j = 0; j < 100; j++) { - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) - correct += mindot_ref( (btSimdFloat4*) in, (float*) &localScaling, size, &correctDot); - currentTime = ReadTicks() - startTime; - timep[0] += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - timep[0] = bestTime; - else - timep[0] /= 100; - - timep++; - } - - for( size = 1; size <= 32; size++ ) - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - vectorTimes[size] = 0; - for (j = 0; j < 100; j++) { - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) - test += localScaling.minDot( (btVector3*) in, size, testDot); - currentTime = ReadTicks() - startTime; - vectorTimes[size] += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTimes[size] = bestTime; - else - vectorTimes[size] /= 100; - } - - timep = &vectorTimes[33]; - for( size = 64; size <= MAX_SIZE; size *= 2 ) - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - timep[0] =0; - for (j = 0; j < 100; j++) { - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) - test += localScaling.minDot( (btVector3*) in, size, testDot); - currentTime = ReadTicks() - startTime; - timep[0] += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - timep[0] = bestTime; - else - timep[0] /= 100; - - timep++; - } - - vlog( "Timing:\n" ); - vlog( " size\t scalar\t vector\n" ); - for( size = 1; size <= 32; size++ ) - vlog( "%5lu\t%10.2f\t%10.2f\n", size, TicksToCycles( scalarTimes[size] ) / LOOPCOUNT, TicksToCycles( vectorTimes[size] ) / LOOPCOUNT ); - size_t index = 33; - for( size = 64; size <= MAX_SIZE; size *= 2 ) - { - vlog( "%5lu\t%10.2f\t%10.2f\n", size, TicksToCycles( scalarTimes[index] ) / LOOPCOUNT, TicksToCycles( vectorTimes[index] ) / LOOPCOUNT ); - index++; - } - - // Useless check to make sure that the timing loops are not optimized away - if( test != correct ) - vlog( "Error: Test != correct: *%ld vs. %ld\n", correct, test); - - GuardFree(data); - - return 0; + uint64_t scalarTimes[33 + (MAX_LOG2_SIZE - 5)]; + uint64_t vectorTimes[33 + (MAX_LOG2_SIZE - 5)]; + size_t j, k; + float *in = (float *)data; + for (size = 1; size <= 32; size++) + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTimes[size] = 0; + for (j = 0; j < 100; j++) + { + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) + correct += mindot_ref((btSimdFloat4 *)in, (float *)&localScaling, size, &correctDot); + currentTime = ReadTicks() - startTime; + scalarTimes[size] += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTimes[size] = bestTime; + else + scalarTimes[size] /= 100; + } + + uint64_t *timep = &scalarTimes[33]; + for (size = 64; size <= MAX_SIZE; size *= 2) + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + timep[0] = 0; + for (j = 0; j < 100; j++) + { + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) + correct += mindot_ref((btSimdFloat4 *)in, (float *)&localScaling, size, &correctDot); + currentTime = ReadTicks() - startTime; + timep[0] += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + timep[0] = bestTime; + else + timep[0] /= 100; + + timep++; + } + + for (size = 1; size <= 32; size++) + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTimes[size] = 0; + for (j = 0; j < 100; j++) + { + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) + test += localScaling.minDot((btVector3 *)in, size, testDot); + currentTime = ReadTicks() - startTime; + vectorTimes[size] += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTimes[size] = bestTime; + else + vectorTimes[size] /= 100; + } + + timep = &vectorTimes[33]; + for (size = 64; size <= MAX_SIZE; size *= 2) + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + timep[0] = 0; + for (j = 0; j < 100; j++) + { + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) + test += localScaling.minDot((btVector3 *)in, size, testDot); + currentTime = ReadTicks() - startTime; + timep[0] += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + timep[0] = bestTime; + else + timep[0] /= 100; + + timep++; + } + + vlog("Timing:\n"); + vlog(" size\t scalar\t vector\n"); + for (size = 1; size <= 32; size++) + vlog("%5lu\t%10.2f\t%10.2f\n", size, TicksToCycles(scalarTimes[size]) / LOOPCOUNT, TicksToCycles(vectorTimes[size]) / LOOPCOUNT); + size_t index = 33; + for (size = 64; size <= MAX_SIZE; size *= 2) + { + vlog("%5lu\t%10.2f\t%10.2f\n", size, TicksToCycles(scalarTimes[index]) / LOOPCOUNT, TicksToCycles(vectorTimes[index]) / LOOPCOUNT); + index++; + } + + // Useless check to make sure that the timing loops are not optimized away + if (test != correct) + vlog("Error: Test != correct: *%ld vs. %ld\n", correct, test); + + GuardFree(data); + + return 0; } - - -static long mindot_ref( const btSimdFloat4 *vertices, - float *vec, - size_t count, - float *dotResult ) +static long mindot_ref(const btSimdFloat4 *vertices, + float *vec, + size_t count, + float *dotResult) { - - const float *dp = (const float*) vertices; - float minDot = BT_INFINITY; - long i = 0; - long ptIndex = -1; - - for( i = 0; i < count; i++ ) - { - float dot = vec[0] * dp[0] + vec[1] * dp[1] + vec[2] * dp[2]; dp += 4; - - if( dot < minDot ) - { - minDot = dot; - ptIndex = i; - } - } - - *dotResult = minDot; - - return ptIndex; + const float *dp = (const float *)vertices; + float minDot = BT_INFINITY; + long i = 0; + long ptIndex = -1; + + for (i = 0; i < count; i++) + { + float dot = vec[0] * dp[0] + vec[1] * dp[1] + vec[2] * dp[2]; + dp += 4; + + if (dot < minDot) + { + minDot = dot; + ptIndex = i; + } + } + + *dotResult = minDot; + + return ptIndex; } -#endif //BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_mindot.h b/test/Bullet2/Source/Tests/Test_mindot.h index 4810dcd8d..2c8555384 100644 --- a/test/Bullet2/Source/Tests/Test_mindot.h +++ b/test/Bullet2/Source/Tests/Test_mindot.h @@ -9,14 +9,14 @@ #define BulletTest_Test_mindot_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif - - int Test_mindot(void); - + + int Test_mindot(void); + #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_qtdot.cpp b/test/Bullet2/Source/Tests/Test_qtdot.cpp index 3fad74d37..8b9cc1bf6 100644 --- a/test/Bullet2/Source/Tests/Test_qtdot.cpp +++ b/test/Bullet2/Source/Tests/Test_qtdot.cpp @@ -5,10 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_qtdot.h" #include "vector.h" @@ -19,17 +17,16 @@ #include -#define BT_OP(a, b) (a.dot(b)) +#define BT_OP(a, b) (a.dot(b)) // reference code for testing purposes static inline btScalar qtdot_ref(btQuaternion& q1, btQuaternion& q2); static inline btScalar qtdot_ref(btQuaternion& q1, btQuaternion& q2) { - return - q1.x() * q2.x() + - q1.y() * q2.y() + - q1.z() * q2.z() + - q1.w() * q2.w(); + return q1.x() * q2.x() + + q1.y() * q2.y() + + q1.z() * q2.z() + + q1.w() * q2.w(); } #define LOOPCOUNT 1024 @@ -37,126 +34,134 @@ static inline btScalar qtdot_ref(btQuaternion& q1, btQuaternion& q2) int Test_qtdot(void) { - btQuaternion q1, q2; + btQuaternion q1, q2; float x, y, z, w, vNaN; - vNaN = BT_NAN; // w channel NaN - - // Init the data - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - w = RANDF_01; - q1.setValue(x,y,z,w); - - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - w = RANDF_01; - q2.setValue(x,y,z,w); + vNaN = BT_NAN; // w channel NaN + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + q1.setValue(x, y, z, w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + q2.setValue(x, y, z, w); btScalar correct_res, test_res; - - { - correct_res = vNaN; + + { + correct_res = vNaN; test_res = vNaN; correct_res = qtdot_ref(q1, q2); - test_res = BT_OP(q1,q2); - - if( fabsf(correct_res - test_res) > FLT_EPSILON*4 ) - { - vlog( "Error - qtdot result error! " - "\ncorrect = %10.4f " - "\ntested = %10.4f \n", - correct_res, test_res); - + test_res = BT_OP(q1, q2); + + if (fabsf(correct_res - test_res) > FLT_EPSILON * 4) + { + vlog( + "Error - qtdot result error! " + "\ncorrect = %10.4f " + "\ntested = %10.4f \n", + correct_res, test_res); + return 1; } } - + #define DATA_SIZE LOOPCOUNT btQuaternion qt_arr1[DATA_SIZE]; btQuaternion qt_arr2[DATA_SIZE]; - btScalar res_arr[DATA_SIZE]; + btScalar res_arr[DATA_SIZE]; - uint64_t scalarTime; - uint64_t vectorTime; - size_t j, k; + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; - for( k = 0; k < DATA_SIZE; k++ ) - { - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - w = RANDF_01; - qt_arr1[k].setValue(x,y,z,w); + for (k = 0; k < DATA_SIZE; k++) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + qt_arr1[k].setValue(x, y, z, w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - w = RANDF_01; - qt_arr2[k].setValue(x,y,z,w); - } + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + qt_arr2[k].setValue(x, y, z, w); + } { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - startTime = ReadTicks(); - for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + startTime = ReadTicks(); + for (k = 0; k + 4 <= LOOPCOUNT; k += 4) { - size_t km = (k & (DATA_SIZE-1)); - res_arr[km] = qtdot_ref(qt_arr1[km], qt_arr2[km]);km++; - res_arr[km] = qtdot_ref(qt_arr1[km], qt_arr2[km]);km++; - res_arr[km] = qtdot_ref(qt_arr1[km], qt_arr2[km]);km++; - res_arr[km] = qtdot_ref(qt_arr1[km], qt_arr2[km]); + size_t km = (k & (DATA_SIZE - 1)); + res_arr[km] = qtdot_ref(qt_arr1[km], qt_arr2[km]); + km++; + res_arr[km] = qtdot_ref(qt_arr1[km], qt_arr2[km]); + km++; + res_arr[km] = qtdot_ref(qt_arr1[km], qt_arr2[km]); + km++; + res_arr[km] = qtdot_ref(qt_arr1[km], qt_arr2[km]); } currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= NUM_CYCLES; - } - - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - startTime = ReadTicks(); - for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + startTime = ReadTicks(); + for (k = 0; k + 4 <= LOOPCOUNT; k += 4) { - size_t km = (k & (DATA_SIZE-1)); - res_arr[km] = BT_OP(qt_arr1[km], qt_arr2[km]);km++; - res_arr[km] = BT_OP(qt_arr1[km], qt_arr2[km]);km++; - res_arr[km] = BT_OP(qt_arr1[km], qt_arr2[km]);km++; - res_arr[km] = BT_OP(qt_arr1[km], qt_arr2[km]);km++; + size_t km = (k & (DATA_SIZE - 1)); + res_arr[km] = BT_OP(qt_arr1[km], qt_arr2[km]); + km++; + res_arr[km] = BT_OP(qt_arr1[km], qt_arr2[km]); + km++; + res_arr[km] = BT_OP(qt_arr1[km], qt_arr2[km]); + km++; + res_arr[km] = BT_OP(qt_arr1[km], qt_arr2[km]); + km++; } currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= NUM_CYCLES; - } + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } - vlog( "Timing:\n" ); - vlog( " \t scalar\t vector\n" ); - vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, - TicksToCycles( vectorTime ) / LOOPCOUNT ); + vlog("Timing:\n"); + vlog(" \t scalar\t vector\n"); + vlog(" \t%10.4f\t%10.4f\n", TicksToCycles(scalarTime) / LOOPCOUNT, + TicksToCycles(vectorTime) / LOOPCOUNT); - return 0; + return 0; } -#endif //BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_qtdot.h b/test/Bullet2/Source/Tests/Test_qtdot.h index 4917780c9..3aa98a3f0 100644 --- a/test/Bullet2/Source/Tests/Test_qtdot.h +++ b/test/Bullet2/Source/Tests/Test_qtdot.h @@ -9,14 +9,14 @@ #define BulletTest_Test_qtdot_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_qtdot(void); + int Test_qtdot(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_qtmul.cpp b/test/Bullet2/Source/Tests/Test_qtmul.cpp index 7b83a7bb4..304cb777e 100644 --- a/test/Bullet2/Source/Tests/Test_qtmul.cpp +++ b/test/Bullet2/Source/Tests/Test_qtmul.cpp @@ -5,11 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_qtmul.h" #include "vector.h" @@ -20,19 +17,19 @@ #include -#define BT_OP(a, b) ((a) *= (b)) +#define BT_OP(a, b) ((a) *= (b)) // reference code for testing purposes static inline btQuaternion& qtmul_ref(btQuaternion& q1, btQuaternion& q2); static inline btQuaternion& qtmul_ref(btQuaternion& q1, btQuaternion& q2) { - float x,y,z,w; - x = q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(), - y = q1.w() * q2.y() + q1.y() * q2.w() + q1.z() * q2.x() - q1.x() * q2.z(), - z = q1.w() * q2.z() + q1.z() * q2.w() + q1.x() * q2.y() - q1.y() * q2.x(), - w = q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z(); + float x, y, z, w; + x = q1.w() * q2.x() + q1.x() * q2.w() + q1.y() * q2.z() - q1.z() * q2.y(), + y = q1.w() * q2.y() + q1.y() * q2.w() + q1.z() * q2.x() - q1.x() * q2.z(), + z = q1.w() * q2.z() + q1.z() * q2.w() + q1.x() * q2.y() - q1.y() * q2.x(), + w = q1.w() * q2.w() - q1.x() * q2.x() - q1.y() * q2.y() - q1.z() * q2.z(); - q1.setValue(x, y, z, w); + q1.setValue(x, y, z, w); return q1; } @@ -41,143 +38,145 @@ static inline btQuaternion& qtmul_ref(btQuaternion& q1, btQuaternion& q2) int Test_qtmul(void) { - btQuaternion q1, q2, q3; - - float x, y, z, w, vNaN; - - // Init the data - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - w = RANDF_01; - vNaN = BT_NAN; // w channel NaN - q1.setValue(x,y,z,w); - - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - w = RANDF_01; - q2.setValue(x,y,z,w); + btQuaternion q1, q2, q3; + + float x, y, z, w, vNaN; + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + vNaN = BT_NAN; // w channel NaN + q1.setValue(x, y, z, w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + q2.setValue(x, y, z, w); q3 = q1; - - btQuaternion correct_res, test_res; - - { + + btQuaternion correct_res, test_res; + + { float vNaN = BT_NAN; - correct_res.setValue(vNaN, vNaN, vNaN, vNaN); + correct_res.setValue(vNaN, vNaN, vNaN, vNaN); test_res.setValue(vNaN, vNaN, vNaN, vNaN); correct_res = qtmul_ref(q1, q2); - test_res = BT_OP(q3,q2); - - if( fabsf(correct_res.x() - test_res.x()) + - fabsf(correct_res.y() - test_res.y()) + - fabsf(correct_res.z() - test_res.z()) + - fabsf(correct_res.w() - test_res.w()) > FLT_EPSILON*10 ) - { - vlog( "Error - qtmul result error! " - "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " - "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) \n", - correct_res.x(), correct_res.y(), - correct_res.z(), correct_res.w(), - test_res.x(), test_res.y(), - test_res.z(), test_res.w()); - + test_res = BT_OP(q3, q2); + + if (fabsf(correct_res.x() - test_res.x()) + + fabsf(correct_res.y() - test_res.y()) + + fabsf(correct_res.z() - test_res.z()) + + fabsf(correct_res.w() - test_res.w()) > + FLT_EPSILON * 10) + { + vlog( + "Error - qtmul result error! " + "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) \n", + correct_res.x(), correct_res.y(), + correct_res.z(), correct_res.w(), + test_res.x(), test_res.y(), + test_res.z(), test_res.w()); + return 1; } } - + #define DATA_SIZE LOOPCOUNT btQuaternion qt_arr1[DATA_SIZE]; btQuaternion qt_arr2[DATA_SIZE]; - uint64_t scalarTime; - uint64_t vectorTime; - size_t j, k; + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < NUM_CYCLES; j++) - { - for( k = 0; k < DATA_SIZE; k++ ) - { - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - w = RANDF_01; - qt_arr1[k].setValue(x,y,z,w); + uint64_t startTime, bestTime, currentTime; - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for (k = 0; k < DATA_SIZE; k++) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; w = RANDF_01; - qt_arr2[k].setValue(x,y,z,w); + qt_arr1[k].setValue(x, y, z, w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + qt_arr2[k].setValue(x, y, z, w); } - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) { - qt_arr1[k] = qtmul_ref(qt_arr1[k], qt_arr2[k]); + qt_arr1[k] = qtmul_ref(qt_arr1[k], qt_arr2[k]); } currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= NUM_CYCLES; - } - - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < NUM_CYCLES; j++) - { - for( k = 0; k < DATA_SIZE; k++ ) - { - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - w = RANDF_01; - qt_arr1[k].setValue(x,y,z,w); + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for (k = 0; k < DATA_SIZE; k++) + { + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; w = RANDF_01; - qt_arr2[k].setValue(x,y,z,w); + qt_arr1[k].setValue(x, y, z, w); + + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + qt_arr2[k].setValue(x, y, z, w); } - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) { qt_arr1[k] = BT_OP(qt_arr1[k], qt_arr2[k]); } currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= NUM_CYCLES; - } + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } - vlog( "Timing:\n" ); - vlog( " \t scalar\t vector\n" ); - vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, - TicksToCycles( vectorTime ) / LOOPCOUNT ); + vlog("Timing:\n"); + vlog(" \t scalar\t vector\n"); + vlog(" \t%10.4f\t%10.4f\n", TicksToCycles(scalarTime) / LOOPCOUNT, + TicksToCycles(vectorTime) / LOOPCOUNT); - return 0; + return 0; } -#endif //BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_qtmul.h b/test/Bullet2/Source/Tests/Test_qtmul.h index 9109199b6..cb0aef590 100644 --- a/test/Bullet2/Source/Tests/Test_qtmul.h +++ b/test/Bullet2/Source/Tests/Test_qtmul.h @@ -9,14 +9,14 @@ #define BulletTest_Test_qtmul_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_qtmul(void); + int Test_qtmul(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_qtmulQV3.cpp b/test/Bullet2/Source/Tests/Test_qtmulQV3.cpp index 0a26b50d9..ea75aa573 100644 --- a/test/Bullet2/Source/Tests/Test_qtmulQV3.cpp +++ b/test/Bullet2/Source/Tests/Test_qtmulQV3.cpp @@ -5,10 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_qtmulQV3.h" #include "vector.h" @@ -19,17 +17,17 @@ #include -#define BT_OP(a, b) ((a) * (b)) +#define BT_OP(a, b) ((a) * (b)) // reference code for testing purposes static inline btQuaternion qtmulQV3_ref(const btQuaternion& q, const btVector3& w); static inline btQuaternion qtmulQV3_ref(const btQuaternion& q, const btVector3& w) { - return btQuaternion( - q.w() * w.x() + q.y() * w.z() - q.z() * w.y(), - q.w() * w.y() + q.z() * w.x() - q.x() * w.z(), - q.w() * w.z() + q.x() * w.y() - q.y() * w.x(), - -q.x() * w.x() - q.y() * w.y() - q.z() * w.z()); + return btQuaternion( + q.w() * w.x() + q.y() * w.z() - q.z() * w.y(), + q.w() * w.y() + q.z() * w.x() - q.x() * w.z(), + q.w() * w.z() + q.x() * w.y() - q.y() * w.x(), + -q.x() * w.x() - q.y() * w.y() - q.z() * w.z()); } #define LOOPCOUNT 1024 @@ -37,126 +35,128 @@ static inline btQuaternion qtmulQV3_ref(const btQuaternion& q, const btVector3& static inline btSimdFloat4 rand_f4(void) { - return btAssign128( RANDF_m1p1, RANDF_m1p1, RANDF_m1p1, BT_NAN ); // w channel NaN + return btAssign128(RANDF_m1p1, RANDF_m1p1, RANDF_m1p1, BT_NAN); // w channel NaN } static inline btSimdFloat4 qtrand_f4(void) { - return btAssign128( RANDF_m1p1, RANDF_m1p1, RANDF_m1p1, RANDF_m1p1 ); + return btAssign128(RANDF_m1p1, RANDF_m1p1, RANDF_m1p1, RANDF_m1p1); } static inline btSimdFloat4 qtNAN_f4(void) { - return btAssign128( BT_NAN, BT_NAN, BT_NAN, BT_NAN ); + return btAssign128(BT_NAN, BT_NAN, BT_NAN, BT_NAN); } int Test_qtmulQV3(void) { - btQuaternion q; + btQuaternion q; btVector3 v3; - - // Init the data - q = btQuaternion(qtrand_f4()); - v3 = btVector3(rand_f4()); - btQuaternion correct_res, test_res; - correct_res = btQuaternion(qtNAN_f4()); - test_res = btQuaternion(qtNAN_f4()); - - { + // Init the data + q = btQuaternion(qtrand_f4()); + v3 = btVector3(rand_f4()); + + btQuaternion correct_res, test_res; + correct_res = btQuaternion(qtNAN_f4()); + test_res = btQuaternion(qtNAN_f4()); + + { correct_res = qtmulQV3_ref(q, v3); test_res = BT_OP(q, v3); - - if( fabsf(correct_res.x() - test_res.x()) + - fabsf(correct_res.y() - test_res.y()) + - fabsf(correct_res.z() - test_res.z()) + - fabsf(correct_res.w() - test_res.w()) > FLT_EPSILON*8 ) - { - vlog( "Error - qtmulQV3 result error! " - "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " - "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) \n", - correct_res.x(), correct_res.y(), - correct_res.z(), correct_res.w(), - test_res.x(), test_res.y(), - test_res.z(), test_res.w()); - + + if (fabsf(correct_res.x() - test_res.x()) + + fabsf(correct_res.y() - test_res.y()) + + fabsf(correct_res.z() - test_res.z()) + + fabsf(correct_res.w() - test_res.w()) > + FLT_EPSILON * 8) + { + vlog( + "Error - qtmulQV3 result error! " + "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) \n", + correct_res.x(), correct_res.y(), + correct_res.z(), correct_res.w(), + test_res.x(), test_res.y(), + test_res.z(), test_res.w()); + return 1; } } - + #define DATA_SIZE LOOPCOUNT btQuaternion qt_arrR[DATA_SIZE]; btQuaternion qt_arr[DATA_SIZE]; btVector3 v3_arr[DATA_SIZE]; - uint64_t scalarTime; - uint64_t vectorTime; - size_t j, k; + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - for( k = 0; k < DATA_SIZE; k++ ) + for (k = 0; k < DATA_SIZE; k++) { - qt_arr[k] = btQuaternion(qtrand_f4()); - v3_arr[k] = btVector3(rand_f4()); + qt_arr[k] = btQuaternion(qtrand_f4()); + v3_arr[k] = btVector3(rand_f4()); } - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) { - qt_arrR[k] = qtmulQV3_ref(qt_arr[k], v3_arr[k]); + qt_arrR[k] = qtmulQV3_ref(qt_arr[k], v3_arr[k]); } currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= NUM_CYCLES; - } - - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - for( k = 0; k < DATA_SIZE; k++ ) + for (k = 0; k < DATA_SIZE; k++) { - qt_arr[k] = btQuaternion(qtrand_f4()); - v3_arr[k] = btVector3(rand_f4()); + qt_arr[k] = btQuaternion(qtrand_f4()); + v3_arr[k] = btVector3(rand_f4()); } - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) { qt_arrR[k] = BT_OP(qt_arr[k], v3_arr[k]); } currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= NUM_CYCLES; - } + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } - vlog( "Timing:\n" ); - vlog( " \t scalar\t vector\n" ); - vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, - TicksToCycles( vectorTime ) / LOOPCOUNT ); + vlog("Timing:\n"); + vlog(" \t scalar\t vector\n"); + vlog(" \t%10.4f\t%10.4f\n", TicksToCycles(scalarTime) / LOOPCOUNT, + TicksToCycles(vectorTime) / LOOPCOUNT); - return 0; + return 0; } -#endif //BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_qtmulQV3.h b/test/Bullet2/Source/Tests/Test_qtmulQV3.h index f7bffce0b..920daa11e 100644 --- a/test/Bullet2/Source/Tests/Test_qtmulQV3.h +++ b/test/Bullet2/Source/Tests/Test_qtmulQV3.h @@ -9,14 +9,14 @@ #define BulletTest_Test_qtmulQV3_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_qtmulQV3(void); + int Test_qtmulQV3(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_qtmulV3Q.cpp b/test/Bullet2/Source/Tests/Test_qtmulV3Q.cpp index 48f51245c..f537f09c9 100644 --- a/test/Bullet2/Source/Tests/Test_qtmulV3Q.cpp +++ b/test/Bullet2/Source/Tests/Test_qtmulV3Q.cpp @@ -5,9 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_qtmulV3Q.h" #include "vector.h" @@ -18,17 +17,17 @@ #include -#define BT_OP(a, b) ((a) * (b)) +#define BT_OP(a, b) ((a) * (b)) // reference code for testing purposes static inline btQuaternion qtmulV3Q_ref(const btVector3& w, const btQuaternion& q); static inline btQuaternion qtmulV3Q_ref(const btVector3& w, const btQuaternion& q) { - return btQuaternion( - +w.x() * q.w() + w.y() * q.z() - w.z() * q.y(), + return btQuaternion( + +w.x() * q.w() + w.y() * q.z() - w.z() * q.y(), +w.y() * q.w() + w.z() * q.x() - w.x() * q.z(), +w.z() * q.w() + w.x() * q.y() - w.y() * q.x(), - -w.x() * q.x() - w.y() * q.y() - w.z() * q.z()); + -w.x() * q.x() - w.y() * q.y() - w.z() * q.z()); } #define LOOPCOUNT 1024 @@ -36,126 +35,128 @@ static inline btQuaternion qtmulV3Q_ref(const btVector3& w, const btQuaternion& static inline btSimdFloat4 rand_f4(void) { - return btAssign128( RANDF_m1p1, RANDF_m1p1, RANDF_m1p1, BT_NAN ); // w channel NaN + return btAssign128(RANDF_m1p1, RANDF_m1p1, RANDF_m1p1, BT_NAN); // w channel NaN } static inline btSimdFloat4 qtrand_f4(void) { - return btAssign128( RANDF_m1p1, RANDF_m1p1, RANDF_m1p1, RANDF_m1p1 ); + return btAssign128(RANDF_m1p1, RANDF_m1p1, RANDF_m1p1, RANDF_m1p1); } static inline btSimdFloat4 qtNAN_f4(void) { - return btAssign128( BT_NAN, BT_NAN, BT_NAN, BT_NAN ); + return btAssign128(BT_NAN, BT_NAN, BT_NAN, BT_NAN); } int Test_qtmulV3Q(void) { - btQuaternion q; + btQuaternion q; btVector3 v3; - - // Init the data - q = btQuaternion(qtrand_f4()); - v3 = btVector3(rand_f4()); - btQuaternion correct_res, test_res; - correct_res = btQuaternion(qtNAN_f4()); - test_res = btQuaternion(qtNAN_f4()); - - { + // Init the data + q = btQuaternion(qtrand_f4()); + v3 = btVector3(rand_f4()); + + btQuaternion correct_res, test_res; + correct_res = btQuaternion(qtNAN_f4()); + test_res = btQuaternion(qtNAN_f4()); + + { correct_res = qtmulV3Q_ref(v3, q); test_res = BT_OP(v3, q); - - if( fabsf(correct_res.x() - test_res.x()) + - fabsf(correct_res.y() - test_res.y()) + - fabsf(correct_res.z() - test_res.z()) + - fabsf(correct_res.w() - test_res.w()) > FLT_EPSILON*8 ) - { - vlog( "Error - qtmulV3Q result error! " - "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " - "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) \n", - correct_res.x(), correct_res.y(), - correct_res.z(), correct_res.w(), - test_res.x(), test_res.y(), - test_res.z(), test_res.w()); - + + if (fabsf(correct_res.x() - test_res.x()) + + fabsf(correct_res.y() - test_res.y()) + + fabsf(correct_res.z() - test_res.z()) + + fabsf(correct_res.w() - test_res.w()) > + FLT_EPSILON * 8) + { + vlog( + "Error - qtmulV3Q result error! " + "\ncorrect = (%10.4f, %10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f, %10.4f) \n", + correct_res.x(), correct_res.y(), + correct_res.z(), correct_res.w(), + test_res.x(), test_res.y(), + test_res.z(), test_res.w()); + return 1; } } - + #define DATA_SIZE LOOPCOUNT btQuaternion qt_arrR[DATA_SIZE]; btQuaternion qt_arr[DATA_SIZE]; btVector3 v3_arr[DATA_SIZE]; - uint64_t scalarTime; - uint64_t vectorTime; - size_t j, k; + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - for( k = 0; k < DATA_SIZE; k++ ) + for (k = 0; k < DATA_SIZE; k++) { - qt_arr[k] = btQuaternion(qtrand_f4()); - v3_arr[k] = btVector3(rand_f4()); + qt_arr[k] = btQuaternion(qtrand_f4()); + v3_arr[k] = btVector3(rand_f4()); } - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) { - qt_arrR[k] = qtmulV3Q_ref(v3_arr[k], qt_arr[k]); + qt_arrR[k] = qtmulV3Q_ref(v3_arr[k], qt_arr[k]); } currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= NUM_CYCLES; - } - - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - for( k = 0; k < DATA_SIZE; k++ ) + for (k = 0; k < DATA_SIZE; k++) { - qt_arr[k] = btQuaternion(qtrand_f4()); - v3_arr[k] = btVector3(rand_f4()); + qt_arr[k] = btQuaternion(qtrand_f4()); + v3_arr[k] = btVector3(rand_f4()); } - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) { qt_arrR[k] = BT_OP(v3_arr[k], qt_arr[k]); } currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= NUM_CYCLES; - } + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } - vlog( "Timing:\n" ); - vlog( " \t scalar\t vector\n" ); - vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, - TicksToCycles( vectorTime ) / LOOPCOUNT ); + vlog("Timing:\n"); + vlog(" \t scalar\t vector\n"); + vlog(" \t%10.4f\t%10.4f\n", TicksToCycles(scalarTime) / LOOPCOUNT, + TicksToCycles(vectorTime) / LOOPCOUNT); - return 0; + return 0; } -#endif//#ifdef BT_USE_SSE +#endif //#ifdef BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_qtmulV3Q.h b/test/Bullet2/Source/Tests/Test_qtmulV3Q.h index f9714c9b6..af519eb67 100644 --- a/test/Bullet2/Source/Tests/Test_qtmulV3Q.h +++ b/test/Bullet2/Source/Tests/Test_qtmulV3Q.h @@ -9,14 +9,14 @@ #define BulletTest_Test_qtmulV3Q_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_qtmulV3Q(void); + int Test_qtmulV3Q(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_qtnorm.cpp b/test/Bullet2/Source/Tests/Test_qtnorm.cpp index 3d008bffd..a0b175f7e 100644 --- a/test/Bullet2/Source/Tests/Test_qtnorm.cpp +++ b/test/Bullet2/Source/Tests/Test_qtnorm.cpp @@ -5,11 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_qtnorm.h" #include "vector.h" @@ -20,23 +17,23 @@ #include -#define BT_OP(a) (a.normalize()) +#define BT_OP(a) (a.normalize()) // reference code for testing purposes static inline btQuaternion& qtnorm_ref(btQuaternion& q1); static inline btQuaternion& qtnorm_ref(btQuaternion& q1) { - float dot = - q1.x() * q1.x() + - q1.y() * q1.y() + - q1.z() * q1.z() + - q1.w() * q1.w(); + float dot = + q1.x() * q1.x() + + q1.y() * q1.y() + + q1.z() * q1.z() + + q1.w() * q1.w(); dot = 1.0f / sqrtf(dot); - q1.setValue(q1.x()*dot, q1.y()*dot, q1.z()*dot, q1.w()*dot); + q1.setValue(q1.x() * dot, q1.y() * dot, q1.z() * dot, q1.w() * dot); - return q1; + return q1; } #define LOOPCOUNT 1024 @@ -44,133 +41,142 @@ static inline btQuaternion& qtnorm_ref(btQuaternion& q1) int Test_qtnorm(void) { - int i; - btQuaternion q1, q2; + int i; + btQuaternion q1, q2; float x, y, z, w, vNaN; - vNaN = BT_NAN; // w channel NaN - - btQuaternion correct_res, test_res; - - for (i=0; i FLT_EPSILON*10 ) - { - vlog( "Error - qtnorm result error! " - "\ncorrect = (%10.7f, %10.7f, %10.7f, %10.7f) " - "\ntested = (%10.7f, %10.7f, %10.7f, %10.7f) \n", - correct_res.x(), correct_res.y(), - correct_res.z(), correct_res.w(), - test_res.x(), test_res.y(), - test_res.z(), test_res.w()); - + + if (fabsf(correct_res.x() - test_res.x()) + + fabsf(correct_res.y() - test_res.y()) + + fabsf(correct_res.z() - test_res.z()) + + fabsf(correct_res.w() - test_res.w()) > + FLT_EPSILON * 10) + { + vlog( + "Error - qtnorm result error! " + "\ncorrect = (%10.7f, %10.7f, %10.7f, %10.7f) " + "\ntested = (%10.7f, %10.7f, %10.7f, %10.7f) \n", + correct_res.x(), correct_res.y(), + correct_res.z(), correct_res.w(), + test_res.x(), test_res.y(), + test_res.z(), test_res.w()); + return 1; } } - + #define DATA_SIZE LOOPCOUNT btQuaternion qt_arr0[DATA_SIZE]; btQuaternion qt_arr1[DATA_SIZE]; - uint64_t scalarTime; - uint64_t vectorTime; - size_t j, k; + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < NUM_CYCLES; j++) - { - for( k = 0; k < DATA_SIZE; k++ ) - { - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - w = RANDF_01; - qt_arr1[k].setValue(x,y,z,w); - } + uint64_t startTime, bestTime, currentTime; - startTime = ReadTicks(); - for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) + { + for (k = 0; k < DATA_SIZE; k++) { - size_t km = (k & (DATA_SIZE-1)); - qt_arr0[km] = qtnorm_ref(qt_arr1[km]);km++; - qt_arr0[km] = qtnorm_ref(qt_arr1[km]);km++; - qt_arr0[km] = qtnorm_ref(qt_arr1[km]);km++; - qt_arr0[km] = qtnorm_ref(qt_arr1[km]); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + qt_arr1[k].setValue(x, y, z, w); + } + + startTime = ReadTicks(); + for (k = 0; k + 4 <= LOOPCOUNT; k += 4) + { + size_t km = (k & (DATA_SIZE - 1)); + qt_arr0[km] = qtnorm_ref(qt_arr1[km]); + km++; + qt_arr0[km] = qtnorm_ref(qt_arr1[km]); + km++; + qt_arr0[km] = qtnorm_ref(qt_arr1[km]); + km++; + qt_arr0[km] = qtnorm_ref(qt_arr1[km]); } currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= NUM_CYCLES; - } - - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - for( k = 0; k < DATA_SIZE; k++ ) - { - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - w = RANDF_01; - qt_arr1[k].setValue(x,y,z,w); - } - - startTime = ReadTicks(); - for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + for (k = 0; k < DATA_SIZE; k++) { - size_t km = (k & (DATA_SIZE-1)); - qt_arr0[km] = BT_OP(qt_arr1[km]);km++; - qt_arr0[km] = BT_OP(qt_arr1[km]);km++; - qt_arr0[km] = BT_OP(qt_arr1[km]);km++; - qt_arr0[km] = BT_OP(qt_arr1[km]);km++; + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = RANDF_01; + qt_arr1[k].setValue(x, y, z, w); + } + + startTime = ReadTicks(); + for (k = 0; k + 4 <= LOOPCOUNT; k += 4) + { + size_t km = (k & (DATA_SIZE - 1)); + qt_arr0[km] = BT_OP(qt_arr1[km]); + km++; + qt_arr0[km] = BT_OP(qt_arr1[km]); + km++; + qt_arr0[km] = BT_OP(qt_arr1[km]); + km++; + qt_arr0[km] = BT_OP(qt_arr1[km]); + km++; } currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= NUM_CYCLES; - } + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } - vlog( "Timing:\n" ); - vlog( " \t scalar\t vector\n" ); - vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, - TicksToCycles( vectorTime ) / LOOPCOUNT ); + vlog("Timing:\n"); + vlog(" \t scalar\t vector\n"); + vlog(" \t%10.4f\t%10.4f\n", TicksToCycles(scalarTime) / LOOPCOUNT, + TicksToCycles(vectorTime) / LOOPCOUNT); - return 0; + return 0; } -#endif //BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_qtnorm.h b/test/Bullet2/Source/Tests/Test_qtnorm.h index 5b0021709..c52be10f3 100644 --- a/test/Bullet2/Source/Tests/Test_qtnorm.h +++ b/test/Bullet2/Source/Tests/Test_qtnorm.h @@ -9,14 +9,14 @@ #define BulletTest_Test_qtnorm_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_qtnorm(void); + int Test_qtnorm(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_quat_aos_neon.cpp b/test/Bullet2/Source/Tests/Test_quat_aos_neon.cpp index 0a8f69724..816897af4 100644 --- a/test/Bullet2/Source/Tests/Test_quat_aos_neon.cpp +++ b/test/Bullet2/Source/Tests/Test_quat_aos_neon.cpp @@ -5,9 +5,8 @@ // Copyright (c) 2011 Apple Inc., Inc. // - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_quat_aos_neon.h" #include "vector.h" @@ -16,584 +15,574 @@ #include "../vectormath/vmInclude.h" - //typedef Vectormath::Aos::Vector3 vmVector3; //typedef Vectormath::Aos::Quat vmQuat; //typedef Vectormath::Aos::Matrix3 vmMatrix3; //typedef Vectormath::Aos::Transform3 vmTransform3; //typedef Vectormath::Aos::Point3 vmPoint3; - -typedef Vectormath::Aos::Vector4 vmVector4; +typedef Vectormath::Aos::Vector4 vmVector4; // reference code for testing purposes -ATTRIBUTE_ALIGNED16(class) Quat_ref +ATTRIBUTE_ALIGNED16(class) +Quat_ref { - float mX; - float mY; - float mZ; - float mW; - + float mX; + float mY; + float mZ; + float mW; + public: - // Default constructor; does no initialization - // - inline Quat_ref( ) { }; - - // Copy a quaternion - // - inline Quat_ref( const Quat_ref & quat ); - - // Construct a quaternion from x, y, z, and w elements - // - inline Quat_ref( float x, float y, float z, float w ); - - // Construct a quaternion from a 3-D vector and a scalar - // - inline Quat_ref( const vmVector3 & xyz, float w ); - - // Copy elements from a 4-D vector into a quaternion - // - explicit inline Quat_ref( const vmVector4 & vec ); - - // Convert a rotation matrix to a unit-length quaternion - // - explicit inline Quat_ref( const vmMatrix3 & rotMat ); - - // Set all elements of a quaternion to the same scalar value - // - explicit inline Quat_ref( float scalar ); - - // Assign one quaternion to another - // - inline Quat_ref & operator =( const Quat_ref & quat ); - - // Set the x, y, and z elements of a quaternion - // NOTE: - // This function does not change the w element. - // - inline Quat_ref & setXYZ( const vmVector3 & vec ); - - // Get the x, y, and z elements of a quaternion - // - inline const vmVector3 getXYZ( ) const; - - // Set the x element of a quaternion - // - inline Quat_ref & setX( float x ); - - // Set the y element of a quaternion - // - inline Quat_ref & setY( float y ); - - // Set the z element of a quaternion - // - inline Quat_ref & setZ( float z ); - - // Set the w element of a quaternion - // - inline Quat_ref & setW( float w ); - - // Get the x element of a quaternion - // - inline float getX( ) const; - - // Get the y element of a quaternion - // - inline float getY( ) const; - - // Get the z element of a quaternion - // - inline float getZ( ) const; - - // Get the w element of a quaternion - // - inline float getW( ) const; - - // Set an x, y, z, or w element of a quaternion by index - // - inline Quat_ref & setElem( int idx, float value ); - - // Get an x, y, z, or w element of a quaternion by index - // - inline float getElem( int idx ) const; - - // Subscripting operator to set or get an element - // - inline float & operator []( int idx ); - - // Subscripting operator to get an element - // - inline float operator []( int idx ) const; - - // Add two quaternions - // - inline const Quat_ref operator +( const Quat_ref & quat ) const; - - // Subtract a quaternion from another quaternion - // - inline const Quat_ref operator -( const Quat_ref & quat ) const; - - // Multiply two quaternions - // - inline const Quat_ref operator *( const Quat_ref & quat ) const; - - // Multiply a quaternion by a scalar - // - inline const Quat_ref operator *( float scalar ) const; - - // Divide a quaternion by a scalar - // - inline const Quat_ref operator /( float scalar ) const; - - // Perform compound assignment and addition with a quaternion - // - inline Quat_ref & operator +=( const Quat_ref & quat ); - - // Perform compound assignment and subtraction by a quaternion - // - inline Quat_ref & operator -=( const Quat_ref & quat ); - - // Perform compound assignment and multiplication by a quaternion - // - inline Quat_ref & operator *=( const Quat_ref & quat ); - - // Perform compound assignment and multiplication by a scalar - // - inline Quat_ref & operator *=( float scalar ); - - // Perform compound assignment and division by a scalar - // - inline Quat_ref & operator /=( float scalar ); - - // Negate all elements of a quaternion - // - inline const Quat_ref operator -( ) const; - - // Construct an identity quaternion - // - static inline const Quat_ref identity( ); - - // Construct a quaternion to rotate between two unit-length 3-D vectors - // NOTE: - // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. - // - static inline const Quat_ref rotation( const vmVector3 & unitVec0, const vmVector3 & unitVec1 ); - - // Construct a quaternion to rotate around a unit-length 3-D vector - // - static inline const Quat_ref rotation( float radians, const vmVector3 & unitVec ); - - // Construct a quaternion to rotate around the x axis - // - static inline const Quat_ref rotationX( float radians ); - - // Construct a quaternion to rotate around the y axis - // - static inline const Quat_ref rotationY( float radians ); - - // Construct a quaternion to rotate around the z axis - // - static inline const Quat_ref rotationZ( float radians ); - + // Default constructor; does no initialization + // + inline Quat_ref(){}; + + // Copy a quaternion + // + inline Quat_ref(const Quat_ref &quat); + + // Construct a quaternion from x, y, z, and w elements + // + inline Quat_ref(float x, float y, float z, float w); + + // Construct a quaternion from a 3-D vector and a scalar + // + inline Quat_ref(const vmVector3 &xyz, float w); + + // Copy elements from a 4-D vector into a quaternion + // + explicit inline Quat_ref(const vmVector4 &vec); + + // Convert a rotation matrix to a unit-length quaternion + // + explicit inline Quat_ref(const vmMatrix3 &rotMat); + + // Set all elements of a quaternion to the same scalar value + // + explicit inline Quat_ref(float scalar); + + // Assign one quaternion to another + // + inline Quat_ref &operator=(const Quat_ref &quat); + + // Set the x, y, and z elements of a quaternion + // NOTE: + // This function does not change the w element. + // + inline Quat_ref &setXYZ(const vmVector3 &vec); + + // Get the x, y, and z elements of a quaternion + // + inline const vmVector3 getXYZ() const; + + // Set the x element of a quaternion + // + inline Quat_ref &setX(float x); + + // Set the y element of a quaternion + // + inline Quat_ref &setY(float y); + + // Set the z element of a quaternion + // + inline Quat_ref &setZ(float z); + + // Set the w element of a quaternion + // + inline Quat_ref &setW(float w); + + // Get the x element of a quaternion + // + inline float getX() const; + + // Get the y element of a quaternion + // + inline float getY() const; + + // Get the z element of a quaternion + // + inline float getZ() const; + + // Get the w element of a quaternion + // + inline float getW() const; + + // Set an x, y, z, or w element of a quaternion by index + // + inline Quat_ref &setElem(int idx, float value); + + // Get an x, y, z, or w element of a quaternion by index + // + inline float getElem(int idx) const; + + // Subscripting operator to set or get an element + // + inline float &operator[](int idx); + + // Subscripting operator to get an element + // + inline float operator[](int idx) const; + + // Add two quaternions + // + inline const Quat_ref operator+(const Quat_ref &quat) const; + + // Subtract a quaternion from another quaternion + // + inline const Quat_ref operator-(const Quat_ref &quat) const; + + // Multiply two quaternions + // + inline const Quat_ref operator*(const Quat_ref &quat) const; + + // Multiply a quaternion by a scalar + // + inline const Quat_ref operator*(float scalar) const; + + // Divide a quaternion by a scalar + // + inline const Quat_ref operator/(float scalar) const; + + // Perform compound assignment and addition with a quaternion + // + inline Quat_ref &operator+=(const Quat_ref &quat); + + // Perform compound assignment and subtraction by a quaternion + // + inline Quat_ref &operator-=(const Quat_ref &quat); + + // Perform compound assignment and multiplication by a quaternion + // + inline Quat_ref &operator*=(const Quat_ref &quat); + + // Perform compound assignment and multiplication by a scalar + // + inline Quat_ref &operator*=(float scalar); + + // Perform compound assignment and division by a scalar + // + inline Quat_ref &operator/=(float scalar); + + // Negate all elements of a quaternion + // + inline const Quat_ref operator-() const; + + // Construct an identity quaternion + // + static inline const Quat_ref identity(); + + // Construct a quaternion to rotate between two unit-length 3-D vectors + // NOTE: + // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. + // + static inline const Quat_ref rotation(const vmVector3 &unitVec0, const vmVector3 &unitVec1); + + // Construct a quaternion to rotate around a unit-length 3-D vector + // + static inline const Quat_ref rotation(float radians, const vmVector3 &unitVec); + + // Construct a quaternion to rotate around the x axis + // + static inline const Quat_ref rotationX(float radians); + + // Construct a quaternion to rotate around the y axis + // + static inline const Quat_ref rotationY(float radians); + + // Construct a quaternion to rotate around the z axis + // + static inline const Quat_ref rotationZ(float radians); }; -inline Quat_ref::Quat_ref( const Quat_ref & quat ) +inline Quat_ref::Quat_ref(const Quat_ref &quat) { - mX = quat.mX; - mY = quat.mY; - mZ = quat.mZ; - mW = quat.mW; + mX = quat.mX; + mY = quat.mY; + mZ = quat.mZ; + mW = quat.mW; } -inline Quat_ref::Quat_ref( float _x, float _y, float _z, float _w ) +inline Quat_ref::Quat_ref(float _x, float _y, float _z, float _w) { - mX = _x; - mY = _y; - mZ = _z; - mW = _w; + mX = _x; + mY = _y; + mZ = _z; + mW = _w; } -inline Quat_ref::Quat_ref( const vmVector3 & xyz, float _w ) +inline Quat_ref::Quat_ref(const vmVector3 &xyz, float _w) { - this->setXYZ( xyz ); - this->setW( _w ); + this->setXYZ(xyz); + this->setW(_w); } -inline Quat_ref::Quat_ref( const vmVector4 & vec ) +inline Quat_ref::Quat_ref(const vmVector4 &vec) { - mX = vec.getX(); - mY = vec.getY(); - mZ = vec.getZ(); - mW = vec.getW(); + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + mW = vec.getW(); } -inline Quat_ref::Quat_ref( float scalar ) +inline Quat_ref::Quat_ref(float scalar) { - mX = scalar; - mY = scalar; - mZ = scalar; - mW = scalar; + mX = scalar; + mY = scalar; + mZ = scalar; + mW = scalar; } -inline const Quat_ref Quat_ref::identity( ) +inline const Quat_ref Quat_ref::identity() { - return Quat_ref( 0.0f, 0.0f, 0.0f, 1.0f ); + return Quat_ref(0.0f, 0.0f, 0.0f, 1.0f); } - -inline void loadXYZW_ref( Quat_ref & quat, const float * fptr ) +inline void loadXYZW_ref(Quat_ref &quat, const float *fptr) { - quat = Quat_ref( fptr[0], fptr[1], fptr[2], fptr[3] ); + quat = Quat_ref(fptr[0], fptr[1], fptr[2], fptr[3]); } -inline void storeXYZW_ref( const Quat_ref & quat, float * fptr ) +inline void storeXYZW_ref(const Quat_ref &quat, float *fptr) { - fptr[0] = quat.getX(); - fptr[1] = quat.getY(); - fptr[2] = quat.getZ(); - fptr[3] = quat.getW(); + fptr[0] = quat.getX(); + fptr[1] = quat.getY(); + fptr[2] = quat.getZ(); + fptr[3] = quat.getW(); } -inline Quat_ref & Quat_ref::operator =( const Quat_ref & quat ) +inline Quat_ref &Quat_ref::operator=(const Quat_ref &quat) { - mX = quat.mX; - mY = quat.mY; - mZ = quat.mZ; - mW = quat.mW; - return *this; + mX = quat.mX; + mY = quat.mY; + mZ = quat.mZ; + mW = quat.mW; + return *this; } -inline Quat_ref & Quat_ref::setXYZ( const vmVector3 & vec ) +inline Quat_ref &Quat_ref::setXYZ(const vmVector3 &vec) { - mX = vec.getX(); - mY = vec.getY(); - mZ = vec.getZ(); - return *this; + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + return *this; } -inline const vmVector3 Quat_ref::getXYZ( ) const +inline const vmVector3 Quat_ref::getXYZ() const { - return vmVector3( mX, mY, mZ ); + return vmVector3(mX, mY, mZ); } -inline Quat_ref & Quat_ref::setX( float _x ) +inline Quat_ref &Quat_ref::setX(float _x) { - mX = _x; - return *this; + mX = _x; + return *this; } -inline float Quat_ref::getX( ) const +inline float Quat_ref::getX() const { - return mX; + return mX; } -inline Quat_ref & Quat_ref::setY( float _y ) +inline Quat_ref &Quat_ref::setY(float _y) { - mY = _y; - return *this; + mY = _y; + return *this; } -inline float Quat_ref::getY( ) const +inline float Quat_ref::getY() const { - return mY; + return mY; } -inline Quat_ref & Quat_ref::setZ( float _z ) +inline Quat_ref &Quat_ref::setZ(float _z) { - mZ = _z; - return *this; + mZ = _z; + return *this; } -inline float Quat_ref::getZ( ) const +inline float Quat_ref::getZ() const { - return mZ; + return mZ; } -inline Quat_ref & Quat_ref::setW( float _w ) +inline Quat_ref &Quat_ref::setW(float _w) { - mW = _w; - return *this; + mW = _w; + return *this; } -inline float Quat_ref::getW( ) const +inline float Quat_ref::getW() const { - return mW; + return mW; } -inline Quat_ref & Quat_ref::setElem( int idx, float value ) +inline Quat_ref &Quat_ref::setElem(int idx, float value) { - *(&mX + idx) = value; - return *this; + *(&mX + idx) = value; + return *this; } -inline float Quat_ref::getElem( int idx ) const +inline float Quat_ref::getElem(int idx) const { - return *(&mX + idx); + return *(&mX + idx); } -inline float & Quat_ref::operator []( int idx ) +inline float &Quat_ref::operator[](int idx) { - return *(&mX + idx); + return *(&mX + idx); } -inline float Quat_ref::operator []( int idx ) const +inline float Quat_ref::operator[](int idx) const { - return *(&mX + idx); + return *(&mX + idx); } -inline const Quat_ref Quat_ref::operator +( const Quat_ref & quat ) const +inline const Quat_ref Quat_ref::operator+(const Quat_ref &quat) const { - return Quat_ref( - ( mX + quat.mX ), - ( mY + quat.mY ), - ( mZ + quat.mZ ), - ( mW + quat.mW ) - ); + return Quat_ref( + (mX + quat.mX), + (mY + quat.mY), + (mZ + quat.mZ), + (mW + quat.mW)); } -inline const Quat_ref Quat_ref::operator -( const Quat_ref & quat ) const +inline const Quat_ref Quat_ref::operator-(const Quat_ref &quat) const { - return Quat_ref( - ( mX - quat.mX ), - ( mY - quat.mY ), - ( mZ - quat.mZ ), - ( mW - quat.mW ) - ); + return Quat_ref( + (mX - quat.mX), + (mY - quat.mY), + (mZ - quat.mZ), + (mW - quat.mW)); } -inline const Quat_ref Quat_ref::operator *( float scalar ) const +inline const Quat_ref Quat_ref::operator*(float scalar) const { - return Quat_ref( - ( mX * scalar ), - ( mY * scalar ), - ( mZ * scalar ), - ( mW * scalar ) - ); + return Quat_ref( + (mX * scalar), + (mY * scalar), + (mZ * scalar), + (mW * scalar)); } -inline Quat_ref & Quat_ref::operator +=( const Quat_ref & quat ) +inline Quat_ref &Quat_ref::operator+=(const Quat_ref &quat) { - *this = *this + quat; - return *this; + *this = *this + quat; + return *this; } -inline Quat_ref & Quat_ref::operator -=( const Quat_ref & quat ) +inline Quat_ref &Quat_ref::operator-=(const Quat_ref &quat) { - *this = *this - quat; - return *this; + *this = *this - quat; + return *this; } -inline Quat_ref & Quat_ref::operator *=( float scalar ) +inline Quat_ref &Quat_ref::operator*=(float scalar) { - *this = *this * scalar; - return *this; + *this = *this * scalar; + return *this; } -inline const Quat_ref Quat_ref::operator /( float scalar ) const +inline const Quat_ref Quat_ref::operator/(float scalar) const { - return Quat_ref( - ( mX / scalar ), - ( mY / scalar ), - ( mZ / scalar ), - ( mW / scalar ) - ); + return Quat_ref( + (mX / scalar), + (mY / scalar), + (mZ / scalar), + (mW / scalar)); } -inline Quat_ref & Quat_ref::operator /=( float scalar ) +inline Quat_ref &Quat_ref::operator/=(float scalar) { - *this = *this / scalar; - return *this; + *this = *this / scalar; + return *this; } -inline const Quat_ref Quat_ref::operator -( ) const +inline const Quat_ref Quat_ref::operator-() const { - return Quat_ref( - -mX, - -mY, - -mZ, - -mW - ); + return Quat_ref( + -mX, + -mY, + -mZ, + -mW); } -inline const Quat_ref operator *( float scalar, const Quat_ref & quat ) +inline const Quat_ref operator*(float scalar, const Quat_ref &quat) { - return quat * scalar; + return quat * scalar; } -inline float dot( const Quat_ref & quat0, const Quat_ref & quat1 ) +inline float dot(const Quat_ref &quat0, const Quat_ref &quat1) { - float result; - result = ( quat0.getX() * quat1.getX() ); - result = ( result + ( quat0.getY() * quat1.getY() ) ); - result = ( result + ( quat0.getZ() * quat1.getZ() ) ); - result = ( result + ( quat0.getW() * quat1.getW() ) ); - return result; + float result; + result = (quat0.getX() * quat1.getX()); + result = (result + (quat0.getY() * quat1.getY())); + result = (result + (quat0.getZ() * quat1.getZ())); + result = (result + (quat0.getW() * quat1.getW())); + return result; } -inline const Quat_ref lerp( float t, const Quat_ref & quat0, const Quat_ref & quat1 ) +inline const Quat_ref lerp(float t, const Quat_ref &quat0, const Quat_ref &quat1) { - return ( quat0 + ( ( quat1 - quat0 ) * t ) ); + return (quat0 + ((quat1 - quat0) * t)); } -inline const Quat_ref slerp( float t, const Quat_ref & unitQuat0, const Quat_ref & unitQuat1 ) +inline const Quat_ref slerp(float t, const Quat_ref &unitQuat0, const Quat_ref &unitQuat1) { - Quat_ref start; - float recipSinAngle, scale0, scale1, cosAngle, angle; - cosAngle = dot( unitQuat0, unitQuat1 ); - if ( cosAngle < 0.0f ) { - cosAngle = -cosAngle; - start = ( -unitQuat0 ); - } else { - start = unitQuat0; - } - if ( cosAngle < _VECTORMATH_SLERP_TOL ) { - angle = acosf( cosAngle ); - recipSinAngle = ( 1.0f / sinf( angle ) ); - scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); - scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); - } else { - scale0 = ( 1.0f - t ); - scale1 = t; - } - return ( ( start * scale0 ) + ( unitQuat1 * scale1 ) ); + Quat_ref start; + float recipSinAngle, scale0, scale1, cosAngle, angle; + cosAngle = dot(unitQuat0, unitQuat1); + if (cosAngle < 0.0f) + { + cosAngle = -cosAngle; + start = (-unitQuat0); + } + else + { + start = unitQuat0; + } + if (cosAngle < _VECTORMATH_SLERP_TOL) + { + angle = acosf(cosAngle); + recipSinAngle = (1.0f / sinf(angle)); + scale0 = (sinf(((1.0f - t) * angle)) * recipSinAngle); + scale1 = (sinf((t * angle)) * recipSinAngle); + } + else + { + scale0 = (1.0f - t); + scale1 = t; + } + return ((start * scale0) + (unitQuat1 * scale1)); } -inline const Quat_ref squad( float t, const Quat_ref & unitQuat0, const Quat_ref & unitQuat1, const Quat_ref & unitQuat2, const Quat_ref & unitQuat3 ) +inline const Quat_ref squad(float t, const Quat_ref &unitQuat0, const Quat_ref &unitQuat1, const Quat_ref &unitQuat2, const Quat_ref &unitQuat3) { - Quat_ref tmp0, tmp1; - tmp0 = slerp( t, unitQuat0, unitQuat3 ); - tmp1 = slerp( t, unitQuat1, unitQuat2 ); - return slerp( ( ( 2.0f * t ) * ( 1.0f - t ) ), tmp0, tmp1 ); + Quat_ref tmp0, tmp1; + tmp0 = slerp(t, unitQuat0, unitQuat3); + tmp1 = slerp(t, unitQuat1, unitQuat2); + return slerp(((2.0f * t) * (1.0f - t)), tmp0, tmp1); } -inline float norm( const Quat_ref & quat ) +inline float norm(const Quat_ref &quat) { - float result; - result = ( quat.getX() * quat.getX() ); - result = ( result + ( quat.getY() * quat.getY() ) ); - result = ( result + ( quat.getZ() * quat.getZ() ) ); - result = ( result + ( quat.getW() * quat.getW() ) ); - return result; + float result; + result = (quat.getX() * quat.getX()); + result = (result + (quat.getY() * quat.getY())); + result = (result + (quat.getZ() * quat.getZ())); + result = (result + (quat.getW() * quat.getW())); + return result; } -inline float length( const Quat_ref & quat ) +inline float length(const Quat_ref &quat) { - return ::sqrtf( norm( quat ) ); + return ::sqrtf(norm(quat)); } -inline const Quat_ref normalize( const Quat_ref & quat ) +inline const Quat_ref normalize(const Quat_ref &quat) { - float lenSqr, lenInv; - lenSqr = norm( quat ); - lenInv = ( 1.0f / sqrtf( lenSqr ) ); - return Quat_ref( - ( quat.getX() * lenInv ), - ( quat.getY() * lenInv ), - ( quat.getZ() * lenInv ), - ( quat.getW() * lenInv ) - ); + float lenSqr, lenInv; + lenSqr = norm(quat); + lenInv = (1.0f / sqrtf(lenSqr)); + return Quat_ref( + (quat.getX() * lenInv), + (quat.getY() * lenInv), + (quat.getZ() * lenInv), + (quat.getW() * lenInv)); } -inline const Quat_ref Quat_ref::rotation( const vmVector3 & unitVec0, const vmVector3 & unitVec1 ) +inline const Quat_ref Quat_ref::rotation(const vmVector3 &unitVec0, const vmVector3 &unitVec1) { - float cosHalfAngleX2, recipCosHalfAngleX2; - cosHalfAngleX2 = sqrtf( ( 2.0f * ( 1.0f + dot( unitVec0, unitVec1 ) ) ) ); - recipCosHalfAngleX2 = ( 1.0f / cosHalfAngleX2 ); - return Quat_ref( ( cross( unitVec0, unitVec1 ) * recipCosHalfAngleX2 ), ( cosHalfAngleX2 * 0.5f ) ); + float cosHalfAngleX2, recipCosHalfAngleX2; + cosHalfAngleX2 = sqrtf((2.0f * (1.0f + dot(unitVec0, unitVec1)))); + recipCosHalfAngleX2 = (1.0f / cosHalfAngleX2); + return Quat_ref((cross(unitVec0, unitVec1) * recipCosHalfAngleX2), (cosHalfAngleX2 * 0.5f)); } -inline const Quat_ref Quat_ref::rotation( float radians, const vmVector3 & unitVec ) +inline const Quat_ref Quat_ref::rotation(float radians, const vmVector3 &unitVec) { - float s, c, angle; - angle = ( radians * 0.5f ); - s = sinf( angle ); - c = cosf( angle ); - return Quat_ref( ( unitVec * s ), c ); + float s, c, angle; + angle = (radians * 0.5f); + s = sinf(angle); + c = cosf(angle); + return Quat_ref((unitVec * s), c); } -inline const Quat_ref Quat_ref::rotationX( float radians ) +inline const Quat_ref Quat_ref::rotationX(float radians) { - float s, c, angle; - angle = ( radians * 0.5f ); - s = sinf( angle ); - c = cosf( angle ); - return Quat_ref( s, 0.0f, 0.0f, c ); + float s, c, angle; + angle = (radians * 0.5f); + s = sinf(angle); + c = cosf(angle); + return Quat_ref(s, 0.0f, 0.0f, c); } -inline const Quat_ref Quat_ref::rotationY( float radians ) +inline const Quat_ref Quat_ref::rotationY(float radians) { - float s, c, angle; - angle = ( radians * 0.5f ); - s = sinf( angle ); - c = cosf( angle ); - return Quat_ref( 0.0f, s, 0.0f, c ); + float s, c, angle; + angle = (radians * 0.5f); + s = sinf(angle); + c = cosf(angle); + return Quat_ref(0.0f, s, 0.0f, c); } -inline const Quat_ref Quat_ref::rotationZ( float radians ) +inline const Quat_ref Quat_ref::rotationZ(float radians) { - float s, c, angle; - angle = ( radians * 0.5f ); - s = sinf( angle ); - c = cosf( angle ); - return Quat_ref( 0.0f, 0.0f, s, c ); + float s, c, angle; + angle = (radians * 0.5f); + s = sinf(angle); + c = cosf(angle); + return Quat_ref(0.0f, 0.0f, s, c); } -inline const Quat_ref Quat_ref::operator *( const Quat_ref & quat ) const +inline const Quat_ref Quat_ref::operator*(const Quat_ref &quat) const { - return Quat_ref( - ( ( ( ( mW * quat.mX ) + ( mX * quat.mW ) ) + ( mY * quat.mZ ) ) - ( mZ * quat.mY ) ), - ( ( ( ( mW * quat.mY ) + ( mY * quat.mW ) ) + ( mZ * quat.mX ) ) - ( mX * quat.mZ ) ), - ( ( ( ( mW * quat.mZ ) + ( mZ * quat.mW ) ) + ( mX * quat.mY ) ) - ( mY * quat.mX ) ), - ( ( ( ( mW * quat.mW ) - ( mX * quat.mX ) ) - ( mY * quat.mY ) ) - ( mZ * quat.mZ ) ) - ); + return Quat_ref( + ((((mW * quat.mX) + (mX * quat.mW)) + (mY * quat.mZ)) - (mZ * quat.mY)), + ((((mW * quat.mY) + (mY * quat.mW)) + (mZ * quat.mX)) - (mX * quat.mZ)), + ((((mW * quat.mZ) + (mZ * quat.mW)) + (mX * quat.mY)) - (mY * quat.mX)), + ((((mW * quat.mW) - (mX * quat.mX)) - (mY * quat.mY)) - (mZ * quat.mZ))); } -inline Quat_ref & Quat_ref::operator *=( const Quat_ref & quat ) +inline Quat_ref &Quat_ref::operator*=(const Quat_ref &quat) { - *this = *this * quat; - return *this; + *this = *this * quat; + return *this; } -inline const vmVector3 rotate( const Quat_ref & quat, const vmVector3 & vec ) +inline const vmVector3 rotate(const Quat_ref &quat, const vmVector3 &vec) { - float tmpX, tmpY, tmpZ, tmpW; - tmpX = ( ( ( quat.getW() * vec.getX() ) + ( quat.getY() * vec.getZ() ) ) - ( quat.getZ() * vec.getY() ) ); - tmpY = ( ( ( quat.getW() * vec.getY() ) + ( quat.getZ() * vec.getX() ) ) - ( quat.getX() * vec.getZ() ) ); - tmpZ = ( ( ( quat.getW() * vec.getZ() ) + ( quat.getX() * vec.getY() ) ) - ( quat.getY() * vec.getX() ) ); - tmpW = ( ( ( quat.getX() * vec.getX() ) + ( quat.getY() * vec.getY() ) ) + ( quat.getZ() * vec.getZ() ) ); - return vmVector3( - ( ( ( ( tmpW * quat.getX() ) + ( tmpX * quat.getW() ) ) - ( tmpY * quat.getZ() ) ) + ( tmpZ * quat.getY() ) ), - ( ( ( ( tmpW * quat.getY() ) + ( tmpY * quat.getW() ) ) - ( tmpZ * quat.getX() ) ) + ( tmpX * quat.getZ() ) ), - ( ( ( ( tmpW * quat.getZ() ) + ( tmpZ * quat.getW() ) ) - ( tmpX * quat.getY() ) ) + ( tmpY * quat.getX() ) ) - ); + float tmpX, tmpY, tmpZ, tmpW; + tmpX = (((quat.getW() * vec.getX()) + (quat.getY() * vec.getZ())) - (quat.getZ() * vec.getY())); + tmpY = (((quat.getW() * vec.getY()) + (quat.getZ() * vec.getX())) - (quat.getX() * vec.getZ())); + tmpZ = (((quat.getW() * vec.getZ()) + (quat.getX() * vec.getY())) - (quat.getY() * vec.getX())); + tmpW = (((quat.getX() * vec.getX()) + (quat.getY() * vec.getY())) + (quat.getZ() * vec.getZ())); + return vmVector3( + ((((tmpW * quat.getX()) + (tmpX * quat.getW())) - (tmpY * quat.getZ())) + (tmpZ * quat.getY())), + ((((tmpW * quat.getY()) + (tmpY * quat.getW())) - (tmpZ * quat.getX())) + (tmpX * quat.getZ())), + ((((tmpW * quat.getZ()) + (tmpZ * quat.getW())) - (tmpX * quat.getY())) + (tmpY * quat.getX()))); } -inline const Quat_ref conj( const Quat_ref & quat ) +inline const Quat_ref conj(const Quat_ref &quat) { - return Quat_ref( -quat.getX(), -quat.getY(), -quat.getZ(), quat.getW() ); + return Quat_ref(-quat.getX(), -quat.getY(), -quat.getZ(), quat.getW()); } -inline const Quat_ref select( const Quat_ref & quat0, const Quat_ref & quat1, bool select1 ) +inline const Quat_ref select(const Quat_ref &quat0, const Quat_ref &quat1, bool select1) { - return Quat_ref( - ( select1 )? quat1.getX() : quat0.getX(), - ( select1 )? quat1.getY() : quat0.getY(), - ( select1 )? quat1.getZ() : quat0.getZ(), - ( select1 )? quat1.getW() : quat0.getW() - ); + return Quat_ref( + (select1) ? quat1.getX() : quat0.getX(), + (select1) ? quat1.getY() : quat0.getY(), + (select1) ? quat1.getZ() : quat0.getZ(), + (select1) ? quat1.getW() : quat0.getW()); } - - #define LOOPCOUNT 1000 #define NUM_CYCLES 10000 #define DATA_SIZE 1024 int Test_quat_aos_neon(void) { - - return 0; + return 0; } #endif - diff --git a/test/Bullet2/Source/Tests/Test_quat_aos_neon.h b/test/Bullet2/Source/Tests/Test_quat_aos_neon.h index e751a41be..6e3bf8454 100644 --- a/test/Bullet2/Source/Tests/Test_quat_aos_neon.h +++ b/test/Bullet2/Source/Tests/Test_quat_aos_neon.h @@ -9,11 +9,12 @@ #define BulletTest_Test_quat_aos_neon_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif - - int Test_quat_aos_neon(void); - + + int Test_quat_aos_neon(void); + #ifdef __cplusplus } #endif diff --git a/test/Bullet2/Source/Tests/Test_v3cross.cpp b/test/Bullet2/Source/Tests/Test_v3cross.cpp index 00ff4e421..da44d48b7 100644 --- a/test/Bullet2/Source/Tests/Test_v3cross.cpp +++ b/test/Bullet2/Source/Tests/Test_v3cross.cpp @@ -5,10 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_v3cross.h" #include "vector.h" @@ -27,155 +25,156 @@ static btVector3& v3cross_ref(btVector3& v1, btVector3& v2); int Test_v3cross(void) { - btVector3 v1, v2, v3; - - float x,y,z,w; - - // Init the data - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - w = BT_NAN; // w channel NaN - v1.setValue(x,y,z); + btVector3 v1, v2, v3; + + float x, y, z, w; + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = BT_NAN; // w channel NaN + v1.setValue(x, y, z); v1.setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - v2.setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v2.setValue(x, y, z); v2.setW(w); v3 = v1; - - btVector3 correct_res, test_res; - - { + + btVector3 correct_res, test_res; + + { float vNaN = BT_NAN; - correct_res.setValue(vNaN, vNaN, vNaN); + correct_res.setValue(vNaN, vNaN, vNaN); test_res.setValue(vNaN, vNaN, vNaN); correct_res = v3cross_ref(v1, v2); test_res = v3.cross(v2); - - if( fabs(correct_res.m_floats[0] - test_res.m_floats[0]) + - fabs(correct_res.m_floats[1] - test_res.m_floats[1]) + - fabs(correct_res.m_floats[2] - test_res.m_floats[2]) > FLT_EPSILON * 4) - { - vlog( "Error - v3cross result error! " - "\ncorrect = (%10.4f, %10.4f, %10.4f) " - "\ntested = (%10.4f, %10.4f, %10.4f) \n", - correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], - test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2]); - + + if (fabs(correct_res.m_floats[0] - test_res.m_floats[0]) + + fabs(correct_res.m_floats[1] - test_res.m_floats[1]) + + fabs(correct_res.m_floats[2] - test_res.m_floats[2]) > + FLT_EPSILON * 4) + { + vlog( + "Error - v3cross result error! " + "\ncorrect = (%10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f) \n", + correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], + test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2]); + return 1; } } - + #define DATA_SIZE LOOPCOUNT btVector3 vec3_arr1[DATA_SIZE]; btVector3 vec3_arr2[DATA_SIZE]; - uint64_t scalarTime; - uint64_t vectorTime; - size_t j, k; + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - for( k = 0; k < DATA_SIZE; k++ ) + for (k = 0; k < DATA_SIZE; k++) { - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr1[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x, y, z); vec3_arr1[k].setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr2[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr2[k].setValue(x, y, z); vec3_arr2[k].setW(w); } - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) { - vec3_arr1[k] = v3cross_ref(vec3_arr1[k], vec3_arr2[k]); + vec3_arr1[k] = v3cross_ref(vec3_arr1[k], vec3_arr2[k]); } currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= NUM_CYCLES; - } - - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - for( k = 0; k < DATA_SIZE; k++ ) + for (k = 0; k < DATA_SIZE; k++) { - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr1[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x, y, z); vec3_arr1[k].setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr2[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr2[k].setValue(x, y, z); vec3_arr2[k].setW(w); } - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) { vec3_arr1[k] = vec3_arr1[k].cross(vec3_arr2[k]); } currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= NUM_CYCLES; - } + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } - vlog( "Timing:\n" ); - vlog( " \t scalar\t vector\n" ); - vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, - TicksToCycles( vectorTime ) / LOOPCOUNT ); + vlog("Timing:\n"); + vlog(" \t scalar\t vector\n"); + vlog(" \t%10.4f\t%10.4f\n", TicksToCycles(scalarTime) / LOOPCOUNT, + TicksToCycles(vectorTime) / LOOPCOUNT); - return 0; + return 0; } static btVector3& v3cross_ref(btVector3& v1, btVector3& v2) { - btScalar x,y,z; + btScalar x, y, z; x = v1.m_floats[1] * v2.m_floats[2] - v1.m_floats[2] * v2.m_floats[1]; y = v1.m_floats[2] * v2.m_floats[0] - v1.m_floats[0] * v2.m_floats[2]; z = v1.m_floats[0] * v2.m_floats[1] - v1.m_floats[1] * v2.m_floats[0]; - + v1.m_floats[0] = x; v1.m_floats[1] = y; v1.m_floats[2] = z; - + return v1; } - -#endif //BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_v3cross.h b/test/Bullet2/Source/Tests/Test_v3cross.h index 79854fe91..6ac862d50 100644 --- a/test/Bullet2/Source/Tests/Test_v3cross.h +++ b/test/Bullet2/Source/Tests/Test_v3cross.h @@ -9,14 +9,14 @@ #define BulletTest_Test_v3cross_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_v3cross(void); + int Test_v3cross(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_v3div.cpp b/test/Bullet2/Source/Tests/Test_v3div.cpp index bd5800289..c0d523713 100644 --- a/test/Bullet2/Source/Tests/Test_v3div.cpp +++ b/test/Bullet2/Source/Tests/Test_v3div.cpp @@ -5,11 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_v3div.h" #include "vector.h" @@ -20,16 +17,16 @@ #include -#define BT_OP(a, b) ((a) / (b)) +#define BT_OP(a, b) ((a) / (b)) // reference code for testing purposes static inline btVector3& v3div_ref(btVector3& v1, btVector3& v2); static btVector3& v3div_ref(btVector3& v0, btVector3& v1, btVector3& v2) { - v0.m_floats[0] = BT_OP(v1.m_floats[0] , v2.m_floats[0]), - v0.m_floats[1] = BT_OP(v1.m_floats[1] , v2.m_floats[1]), - v0.m_floats[2] = BT_OP(v1.m_floats[2] , v2.m_floats[2]); - + v0.m_floats[0] = BT_OP(v1.m_floats[0], v2.m_floats[0]), + v0.m_floats[1] = BT_OP(v1.m_floats[1], v2.m_floats[1]), + v0.m_floats[2] = BT_OP(v1.m_floats[2], v2.m_floats[2]); + return v0; } @@ -38,141 +35,143 @@ static btVector3& v3div_ref(btVector3& v0, btVector3& v1, btVector3& v2) int Test_v3div(void) { - btVector3 v1, v2, v3; - - float x,y,z,w; - - // Init the data - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - w = BT_NAN; // w channel NaN - v1.setValue(x,y,z); + btVector3 v1, v2, v3; + + float x, y, z, w; + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = BT_NAN; // w channel NaN + v1.setValue(x, y, z); v1.setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - v2.setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v2.setValue(x, y, z); v2.setW(w); v3 = v1; - - btVector3 correct_res, test_res; - - { + + btVector3 correct_res, test_res; + + { float vNaN = BT_NAN; - correct_res.setValue(vNaN, vNaN, vNaN); + correct_res.setValue(vNaN, vNaN, vNaN); test_res.setValue(vNaN, vNaN, vNaN); correct_res = v3div_ref(correct_res, v1, v2); - test_res = BT_OP(v3,v2); - - if( fabsf(correct_res.m_floats[0] - test_res.m_floats[0]) + - fabsf(correct_res.m_floats[1] - test_res.m_floats[1]) + - fabsf(correct_res.m_floats[2] - test_res.m_floats[2]) > FLT_EPSILON*10 ) - { - vlog( "Error - v3div result error! " - "\ncorrect = (%10.4f, %10.4f, %10.4f) " - "\ntested = (%10.4f, %10.4f, %10.4f) \n", - correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], - test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2]); - + test_res = BT_OP(v3, v2); + + if (fabsf(correct_res.m_floats[0] - test_res.m_floats[0]) + + fabsf(correct_res.m_floats[1] - test_res.m_floats[1]) + + fabsf(correct_res.m_floats[2] - test_res.m_floats[2]) > + FLT_EPSILON * 10) + { + vlog( + "Error - v3div result error! " + "\ncorrect = (%10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f) \n", + correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], + test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2]); + return 1; } } - + #define DATA_SIZE LOOPCOUNT btVector3 vec3_arr0[DATA_SIZE]; btVector3 vec3_arr1[DATA_SIZE]; btVector3 vec3_arr2[DATA_SIZE]; - uint64_t scalarTime; - uint64_t vectorTime; - size_t j, k; + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; { - uint64_t startTime, bestTime, currentTime; - w = BT_NAN; // w channel NaN - - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + uint64_t startTime, bestTime, currentTime; + w = BT_NAN; // w channel NaN + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - for( k = 0; k < DATA_SIZE; k++ ) + for (k = 0; k < DATA_SIZE; k++) { - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr1[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x, y, z); vec3_arr1[k].setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr2[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr2[k].setValue(x, y, z); vec3_arr2[k].setW(w); } - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) { - vec3_arr0[k] = v3div_ref(vec3_arr0[k], vec3_arr1[k], vec3_arr2[k]); + vec3_arr0[k] = v3div_ref(vec3_arr0[k], vec3_arr1[k], vec3_arr2[k]); } currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= NUM_CYCLES; - } - - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - for( k = 0; k < DATA_SIZE; k++ ) + for (k = 0; k < DATA_SIZE; k++) { - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr1[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x, y, z); vec3_arr1[k].setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr2[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr2[k].setValue(x, y, z); vec3_arr2[k].setW(w); } - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) { - vec3_arr0[k] = BT_OP(vec3_arr1[k] , vec3_arr2[k]); + vec3_arr0[k] = BT_OP(vec3_arr1[k], vec3_arr2[k]); } currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= NUM_CYCLES; - } + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } - vlog( "Timing:\n" ); - vlog( " \t scalar\t vector\n" ); - vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, - TicksToCycles( vectorTime ) / LOOPCOUNT ); + vlog("Timing:\n"); + vlog(" \t scalar\t vector\n"); + vlog(" \t%10.4f\t%10.4f\n", TicksToCycles(scalarTime) / LOOPCOUNT, + TicksToCycles(vectorTime) / LOOPCOUNT); - return 0; + return 0; } -#endif //BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_v3div.h b/test/Bullet2/Source/Tests/Test_v3div.h index 21bfb6131..e71d556e8 100644 --- a/test/Bullet2/Source/Tests/Test_v3div.h +++ b/test/Bullet2/Source/Tests/Test_v3div.h @@ -9,14 +9,14 @@ #define BulletTest_Test_v3div_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_v3div(void); + int Test_v3div(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_v3dot.cpp b/test/Bullet2/Source/Tests/Test_v3dot.cpp index caa2967d2..b22bbda14 100644 --- a/test/Bullet2/Source/Tests/Test_v3dot.cpp +++ b/test/Bullet2/Source/Tests/Test_v3dot.cpp @@ -5,10 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_v3dot.h" #include "vector.h" @@ -20,9 +18,8 @@ #include // reference code for testing purposes -static inline -btScalar v3dot_ref( - const btVector3& v1, +static inline btScalar v3dot_ref( + const btVector3& v1, const btVector3& v2); #define LOOPCOUNT 1000 @@ -30,135 +27,141 @@ btScalar v3dot_ref( int Test_v3dot(void) { - btVector3 v1, v2; - - float x,y,z,w; - - // Init the data - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - w = BT_NAN; // w channel NaN - v1.setValue(x,y,z); + btVector3 v1, v2; + + float x, y, z, w; + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = BT_NAN; // w channel NaN + v1.setValue(x, y, z); v1.setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - v2.setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v2.setValue(x, y, z); v2.setW(w); - - float correctDot0, testDot0; - { + float correctDot0, testDot0; + + { correctDot0 = w; - testDot0 = w; ; + testDot0 = w; + ; correctDot0 = v3dot_ref(v1, v2); testDot0 = v1.dot(v2); - - if( fabsf(correctDot0 - testDot0) > FLT_EPSILON * 4 ) + + if (fabsf(correctDot0 - testDot0) > FLT_EPSILON * 4) { - vlog( "Error - v3dot result error! %f != %f \n", correctDot0, testDot0); - + vlog("Error - v3dot result error! %f != %f \n", correctDot0, testDot0); + return 1; } } - + #define DATA_SIZE 1024 btVector3 vec3_arr1[DATA_SIZE]; btVector3 vec3_arr2[DATA_SIZE]; - btScalar res_arr[DATA_SIZE]; - - uint64_t scalarTime; - uint64_t vectorTime; - size_t j, k; + btScalar res_arr[DATA_SIZE]; - for( k = 0; k < DATA_SIZE; k++ ) + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; + + for (k = 0; k < DATA_SIZE; k++) { - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr1[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x, y, z); vec3_arr1[k].setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr2[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr2[k].setValue(x, y, z); vec3_arr2[k].setW(w); - - res_arr[k] = w; - } - + + res_arr[k] = w; + } + { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - startTime = ReadTicks(); - for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + startTime = ReadTicks(); + for (k = 0; k + 4 <= LOOPCOUNT; k += 4) { - size_t k32 = (k & (DATA_SIZE-1)); - res_arr[k32] = v3dot_ref( vec3_arr1[k32], vec3_arr2[k32]); k32++; - res_arr[k32] = v3dot_ref( vec3_arr1[k32], vec3_arr2[k32]); k32++; - res_arr[k32] = v3dot_ref( vec3_arr1[k32], vec3_arr2[k32]); k32++; - res_arr[k32] = v3dot_ref( vec3_arr1[k32], vec3_arr2[k32]); + size_t k32 = (k & (DATA_SIZE - 1)); + res_arr[k32] = v3dot_ref(vec3_arr1[k32], vec3_arr2[k32]); + k32++; + res_arr[k32] = v3dot_ref(vec3_arr1[k32], vec3_arr2[k32]); + k32++; + res_arr[k32] = v3dot_ref(vec3_arr1[k32], vec3_arr2[k32]); + k32++; + res_arr[k32] = v3dot_ref(vec3_arr1[k32], vec3_arr2[k32]); } currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= NUM_CYCLES; - } - - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - startTime = ReadTicks(); - for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + startTime = ReadTicks(); + for (k = 0; k + 4 <= LOOPCOUNT; k += 4) { - size_t k32 = k & (DATA_SIZE -1); - res_arr[k32] = vec3_arr1[k32].dot(vec3_arr2[k32]); k32++; - res_arr[k32] = vec3_arr1[k32].dot(vec3_arr2[k32]); k32++; - res_arr[k32] = vec3_arr1[k32].dot(vec3_arr2[k32]); k32++; + size_t k32 = k & (DATA_SIZE - 1); + res_arr[k32] = vec3_arr1[k32].dot(vec3_arr2[k32]); + k32++; + res_arr[k32] = vec3_arr1[k32].dot(vec3_arr2[k32]); + k32++; + res_arr[k32] = vec3_arr1[k32].dot(vec3_arr2[k32]); + k32++; res_arr[k32] = vec3_arr1[k32].dot(vec3_arr2[k32]); } currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= NUM_CYCLES; - } + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } - vlog( "Timing:\n" ); - vlog( " \t scalar\t vector\n" ); - vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, TicksToCycles( vectorTime ) / LOOPCOUNT ); + vlog("Timing:\n"); + vlog(" \t scalar\t vector\n"); + vlog(" \t%10.4f\t%10.4f\n", TicksToCycles(scalarTime) / LOOPCOUNT, TicksToCycles(vectorTime) / LOOPCOUNT); - return 0; + return 0; } - -static btScalar v3dot_ref(const btVector3& v1, - const btVector3& v2) +static btScalar v3dot_ref(const btVector3& v1, + const btVector3& v2) { - return (v1.m_floats[0] * v2.m_floats[0] + - v1.m_floats[1] * v2.m_floats[1] + - v1.m_floats[2] * v2.m_floats[2]); + return (v1.m_floats[0] * v2.m_floats[0] + + v1.m_floats[1] * v2.m_floats[1] + + v1.m_floats[2] * v2.m_floats[2]); } -#endif //BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_v3dot.h b/test/Bullet2/Source/Tests/Test_v3dot.h index b80a3af64..f974bd978 100644 --- a/test/Bullet2/Source/Tests/Test_v3dot.h +++ b/test/Bullet2/Source/Tests/Test_v3dot.h @@ -9,14 +9,14 @@ #define BulletTest_Test_v3dot_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_v3dot(void); + int Test_v3dot(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_v3interp.cpp b/test/Bullet2/Source/Tests/Test_v3interp.cpp index 33d47db02..af6e642e2 100644 --- a/test/Bullet2/Source/Tests/Test_v3interp.cpp +++ b/test/Bullet2/Source/Tests/Test_v3interp.cpp @@ -5,11 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - - - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_v3interp.h" #include "vector.h" @@ -21,177 +18,178 @@ #include // reference code for testing purposes -static inline -btVector3& v3interp_ref( - btVector3& vr, - btVector3& v0, - btVector3& v1, - btScalar& rt); +static inline btVector3& v3interp_ref( + btVector3& vr, + btVector3& v0, + btVector3& v1, + btScalar& rt); #define LOOPCOUNT 1024 #define NUM_CYCLES 1000 int Test_v3interp(void) { - btVector3 v1, v2; + btVector3 v1, v2; btScalar rt; - - float x,y,z,w; + + float x, y, z, w; float vNaN = BT_NAN; - w = BT_NAN; // w channel NaN - - btVector3 correct_res, test_res; + w = BT_NAN; // w channel NaN - for (rt = 0.0f; rt <= 1.0f; rt += 0.1f) - { - correct_res.setValue(vNaN, vNaN, vNaN); + btVector3 correct_res, test_res; + + for (rt = 0.0f; rt <= 1.0f; rt += 0.1f) + { + correct_res.setValue(vNaN, vNaN, vNaN); test_res.setValue(vNaN, vNaN, vNaN); - // Init the data - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - v1.setValue(x,y,z); - v1.setW(w); + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v1.setValue(x, y, z); + v1.setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - v2.setValue(x,y,z); - v2.setW(w); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v2.setValue(x, y, z); + v2.setW(w); - correct_res = v3interp_ref(correct_res, v1, v2, rt); - //test self-referencing vector, see issue https://github.com/bulletphysics/bullet3/pull/313 + correct_res = v3interp_ref(correct_res, v1, v2, rt); + //test self-referencing vector, see issue https://github.com/bulletphysics/bullet3/pull/313 test_res = v1; test_res.setInterpolate3(test_res, v2, rt); - - if( fabs(correct_res.m_floats[0] - test_res.m_floats[0]) + - fabs(correct_res.m_floats[1] - test_res.m_floats[1]) + - fabs(correct_res.m_floats[2] - test_res.m_floats[2]) > FLT_EPSILON * 4) - { - vlog( "Error - v3interp result error! " - "\ncorrect = (%10.4f, %10.4f, %10.4f) " - "\ntested = (%10.4f, %10.4f, %10.4f) \n" - "\n rt=%10.4f", - correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], - test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2], rt); - + + if (fabs(correct_res.m_floats[0] - test_res.m_floats[0]) + + fabs(correct_res.m_floats[1] - test_res.m_floats[1]) + + fabs(correct_res.m_floats[2] - test_res.m_floats[2]) > + FLT_EPSILON * 4) + { + vlog( + "Error - v3interp result error! " + "\ncorrect = (%10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f) \n" + "\n rt=%10.4f", + correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], + test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2], rt); + return 1; } } - + #define DATA_SIZE LOOPCOUNT btVector3 vec3_arr1[DATA_SIZE]; btVector3 vec3_arr2[DATA_SIZE]; - btScalar rt_arr[DATA_SIZE]; + btScalar rt_arr[DATA_SIZE]; - uint64_t scalarTime; - uint64_t vectorTime; - size_t j, k; + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - for( k = 0; k < DATA_SIZE; k++ ) + for (k = 0; k < DATA_SIZE; k++) { - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr1[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x, y, z); vec3_arr1[k].setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr2[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr2[k].setValue(x, y, z); vec3_arr2[k].setW(w); - - rt_arr[k] = RANDF_01; - } - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) + rt_arr[k] = RANDF_01; + } + + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) { - v3interp_ref(vec3_arr1[k], vec3_arr1[k], vec3_arr2[k], rt_arr[k]); + v3interp_ref(vec3_arr1[k], vec3_arr1[k], vec3_arr2[k], rt_arr[k]); } currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= NUM_CYCLES; - } - - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - for( k = 0; k < DATA_SIZE; k++ ) + for (k = 0; k < DATA_SIZE; k++) { - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr1[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x, y, z); vec3_arr1[k].setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr2[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr2[k].setValue(x, y, z); vec3_arr2[k].setW(w); - - rt_arr[k] = RANDF_01; + + rt_arr[k] = RANDF_01; } - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) { vec3_arr1[k].setInterpolate3(vec3_arr1[k], vec3_arr2[k], rt_arr[k]); } currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= NUM_CYCLES; - } + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } - vlog( "Timing:\n" ); - vlog( " \t scalar\t vector\n" ); - vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, - TicksToCycles( vectorTime ) / LOOPCOUNT ); + vlog("Timing:\n"); + vlog(" \t scalar\t vector\n"); + vlog(" \t%10.4f\t%10.4f\n", TicksToCycles(scalarTime) / LOOPCOUNT, + TicksToCycles(vectorTime) / LOOPCOUNT); - return 0; + return 0; } -static btVector3& +static btVector3& v3interp_ref( - btVector3& vr, - btVector3& v0, - btVector3& v1, - btScalar& rt) + btVector3& vr, + btVector3& v0, + btVector3& v1, + btScalar& rt) { - btScalar s = btScalar(1.0) - rt; - vr.m_floats[0] = s * v0.m_floats[0] + rt * v1.m_floats[0]; - vr.m_floats[1] = s * v0.m_floats[1] + rt * v1.m_floats[1]; - vr.m_floats[2] = s * v0.m_floats[2] + rt * v1.m_floats[2]; + btScalar s = btScalar(1.0) - rt; + vr.m_floats[0] = s * v0.m_floats[0] + rt * v1.m_floats[0]; + vr.m_floats[1] = s * v0.m_floats[1] + rt * v1.m_floats[1]; + vr.m_floats[2] = s * v0.m_floats[2] + rt * v1.m_floats[2]; return vr; } -#endif //BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_v3interp.h b/test/Bullet2/Source/Tests/Test_v3interp.h index 502b1ad73..f6cc88ffb 100644 --- a/test/Bullet2/Source/Tests/Test_v3interp.h +++ b/test/Bullet2/Source/Tests/Test_v3interp.h @@ -9,14 +9,14 @@ #define BulletTest_Test_v3interp_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_v3interp(void); + int Test_v3interp(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_v3lerp.cpp b/test/Bullet2/Source/Tests/Test_v3lerp.cpp index 311d0bd4e..dc0c9ec1a 100644 --- a/test/Bullet2/Source/Tests/Test_v3lerp.cpp +++ b/test/Bullet2/Source/Tests/Test_v3lerp.cpp @@ -5,11 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_v3lerp.h" #include "vector.h" @@ -21,178 +18,177 @@ #include // reference code for testing purposes -static inline -btVector3& +static inline btVector3& v3lerp_ref( - btVector3& vr, - btVector3& v0, - btVector3& v1, - btScalar& rt); + btVector3& vr, + btVector3& v0, + btVector3& v1, + btScalar& rt); #define LOOPCOUNT 1024 #define NUM_CYCLES 1000 int Test_v3lerp(void) { - btVector3 v1, v2; + btVector3 v1, v2; btScalar rt; - - float x,y,z,w; - float vNaN =BT_NAN; - w =BT_NAN; // w channel NaN - - btVector3 correct_res, test_res; + float x, y, z, w; - for (rt = 0.0f; rt <= 1.0f; rt += 0.1f) - { - correct_res.setValue(vNaN, vNaN, vNaN); + float vNaN = BT_NAN; + w = BT_NAN; // w channel NaN + + btVector3 correct_res, test_res; + + for (rt = 0.0f; rt <= 1.0f; rt += 0.1f) + { + correct_res.setValue(vNaN, vNaN, vNaN); test_res.setValue(vNaN, vNaN, vNaN); - // Init the data - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - v1.setValue(x,y,z); - v1.setW(w); + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v1.setValue(x, y, z); + v1.setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - v2.setValue(x,y,z); - v2.setW(w); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v2.setValue(x, y, z); + v2.setW(w); - correct_res = v3lerp_ref(correct_res, v1, v2, rt); + correct_res = v3lerp_ref(correct_res, v1, v2, rt); test_res = v1.lerp(v2, rt); - - if( fabs(correct_res.m_floats[0] - test_res.m_floats[0]) + - fabs(correct_res.m_floats[1] - test_res.m_floats[1]) + - fabs(correct_res.m_floats[2] - test_res.m_floats[2]) > FLT_EPSILON * 4) - { - vlog( "Error - v3lerp result error! " - "\ncorrect = (%10.4f, %10.4f, %10.4f) " - "\ntested = (%10.4f, %10.4f, %10.4f) \n" - "\n rt=%10.4f", - correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], - test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2], rt); - + + if (fabs(correct_res.m_floats[0] - test_res.m_floats[0]) + + fabs(correct_res.m_floats[1] - test_res.m_floats[1]) + + fabs(correct_res.m_floats[2] - test_res.m_floats[2]) > + FLT_EPSILON * 4) + { + vlog( + "Error - v3lerp result error! " + "\ncorrect = (%10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f) \n" + "\n rt=%10.4f", + correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], + test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2], rt); + return 1; } } - + #define DATA_SIZE LOOPCOUNT btVector3 vec3_arr1[DATA_SIZE]; btVector3 vec3_arr2[DATA_SIZE]; - btScalar rt_arr[DATA_SIZE]; + btScalar rt_arr[DATA_SIZE]; - uint64_t scalarTime; - uint64_t vectorTime; - size_t j, k; + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; { - uint64_t startTime, bestTime, currentTime; - w =BT_NAN; // w channel NaN - - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + uint64_t startTime, bestTime, currentTime; + w = BT_NAN; // w channel NaN + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - for( k = 0; k < DATA_SIZE; k++ ) + for (k = 0; k < DATA_SIZE; k++) { - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr1[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x, y, z); vec3_arr1[k].setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr2[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr2[k].setValue(x, y, z); vec3_arr2[k].setW(w); - rt_arr[k] = RANDF_01; + rt_arr[k] = RANDF_01; } - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) { - v3lerp_ref(vec3_arr1[k], vec3_arr1[k], vec3_arr2[k], rt_arr[k]); + v3lerp_ref(vec3_arr1[k], vec3_arr1[k], vec3_arr2[k], rt_arr[k]); } currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= NUM_CYCLES; - } - - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - for( k = 0; k < DATA_SIZE; k++ ) + for (k = 0; k < DATA_SIZE; k++) { - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr1[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x, y, z); vec3_arr1[k].setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr2[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr2[k].setValue(x, y, z); vec3_arr2[k].setW(w); - rt_arr[k] = RANDF_01; + rt_arr[k] = RANDF_01; } - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) { vec3_arr1[k] = vec3_arr1[k].lerp(vec3_arr2[k], rt_arr[k]); } currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= NUM_CYCLES; - } + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } - vlog( "Timing:\n" ); - vlog( " \t scalar\t vector\n" ); - vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, - TicksToCycles( vectorTime ) / LOOPCOUNT ); + vlog("Timing:\n"); + vlog(" \t scalar\t vector\n"); + vlog(" \t%10.4f\t%10.4f\n", TicksToCycles(scalarTime) / LOOPCOUNT, + TicksToCycles(vectorTime) / LOOPCOUNT); - return 0; + return 0; } -static -btVector3& +static btVector3& v3lerp_ref( - btVector3& vr, - btVector3& v0, - btVector3& v1, - btScalar& rt) + btVector3& vr, + btVector3& v0, + btVector3& v1, + btScalar& rt) { - vr.m_floats[0] = v0.m_floats[0] + rt * (v1.m_floats[0] - v0.m_floats[0]); - vr.m_floats[1] = v0.m_floats[1] + rt * (v1.m_floats[1] - v0.m_floats[1]); - vr.m_floats[2] = v0.m_floats[2] + rt * (v1.m_floats[2] - v0.m_floats[2]); + vr.m_floats[0] = v0.m_floats[0] + rt * (v1.m_floats[0] - v0.m_floats[0]); + vr.m_floats[1] = v0.m_floats[1] + rt * (v1.m_floats[1] - v0.m_floats[1]); + vr.m_floats[2] = v0.m_floats[2] + rt * (v1.m_floats[2] - v0.m_floats[2]); return vr; } -#endif //BT_USE_SSE - +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_v3lerp.h b/test/Bullet2/Source/Tests/Test_v3lerp.h index a38a12c19..5e9097586 100644 --- a/test/Bullet2/Source/Tests/Test_v3lerp.h +++ b/test/Bullet2/Source/Tests/Test_v3lerp.h @@ -9,14 +9,14 @@ #define BulletTest_Test_v3lerp_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_v3lerp(void); + int Test_v3lerp(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_v3norm.cpp b/test/Bullet2/Source/Tests/Test_v3norm.cpp index 51e0dd35c..0032c5165 100644 --- a/test/Bullet2/Source/Tests/Test_v3norm.cpp +++ b/test/Bullet2/Source/Tests/Test_v3norm.cpp @@ -5,11 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_v3norm.h" #include "vector.h" @@ -28,143 +25,144 @@ static inline btVector3& v3norm_ref(btVector3& v); int Test_v3norm(void) { - btVector3 v1, v2; - - float x,y,z,w; - - // Init the data - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - w = BT_NAN; // w channel NaN - v1.setValue(x,y,z); + btVector3 v1, v2; + + float x, y, z, w; + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = BT_NAN; // w channel NaN + v1.setValue(x, y, z); v1.setW(w); - v2 = v1; + v2 = v1; - btVector3 correct_res, test_res; - - { + btVector3 correct_res, test_res; + + { float vNaN = BT_NAN; - correct_res.setValue(vNaN, vNaN, vNaN); + correct_res.setValue(vNaN, vNaN, vNaN); test_res.setValue(vNaN, vNaN, vNaN); correct_res = v3norm_ref(v1); test_res = v2.normalize(); - - if( fabs(correct_res.m_floats[0] - test_res.m_floats[0]) + - fabs(correct_res.m_floats[1] - test_res.m_floats[1]) + - fabs(correct_res.m_floats[2] - test_res.m_floats[2]) > FLT_EPSILON * 4) - { - vlog( "Error - v3norm result error! " - "\ncorrect = (%10.4f, %10.4f, %10.4f) " - "\ntested = (%10.4f, %10.4f, %10.4f) \n", - correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], - test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2]); - + + if (fabs(correct_res.m_floats[0] - test_res.m_floats[0]) + + fabs(correct_res.m_floats[1] - test_res.m_floats[1]) + + fabs(correct_res.m_floats[2] - test_res.m_floats[2]) > + FLT_EPSILON * 4) + { + vlog( + "Error - v3norm result error! " + "\ncorrect = (%10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f) \n", + correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], + test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2]); + return 1; } } - + #define DATA_SIZE LOOPCOUNT btVector3 vec3_arr0[DATA_SIZE]; btVector3 vec3_arr1[DATA_SIZE]; - uint64_t scalarTime; - uint64_t vectorTime; - size_t j, k; + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - for( k = 0; k < DATA_SIZE; k++ ) + for (k = 0; k < DATA_SIZE; k++) { x = RANDF_01; y = RANDF_01; z = RANDF_01; - vec3_arr1[k].setValue(x,y,z); + vec3_arr1[k].setValue(x, y, z); vec3_arr1[k].setW(w); } - startTime = ReadTicks(); - for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + startTime = ReadTicks(); + for (k = 0; k + 4 <= LOOPCOUNT; k += 4) { - vec3_arr0[k] = v3norm_ref(vec3_arr1[k]); - vec3_arr0[k+1] = v3norm_ref(vec3_arr1[k+1]); - vec3_arr0[k+2] = v3norm_ref(vec3_arr1[k+2]); - vec3_arr0[k+3] = v3norm_ref(vec3_arr1[k+3]); + vec3_arr0[k] = v3norm_ref(vec3_arr1[k]); + vec3_arr0[k + 1] = v3norm_ref(vec3_arr1[k + 1]); + vec3_arr0[k + 2] = v3norm_ref(vec3_arr1[k + 2]); + vec3_arr0[k + 3] = v3norm_ref(vec3_arr1[k + 3]); } currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= NUM_CYCLES; - } - - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - for( k = 0; k < DATA_SIZE; k++ ) + for (k = 0; k < DATA_SIZE; k++) { x = RANDF_01; y = RANDF_01; z = RANDF_01; - vec3_arr1[k].setValue(x,y,z); + vec3_arr1[k].setValue(x, y, z); vec3_arr1[k].setW(w); } - startTime = ReadTicks(); - for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + startTime = ReadTicks(); + for (k = 0; k + 4 <= LOOPCOUNT; k += 4) { vec3_arr0[k] = vec3_arr1[k].normalize(); - vec3_arr0[k+1] = vec3_arr1[k+1].normalize(); - vec3_arr0[k+2] = vec3_arr1[k+2].normalize(); - vec3_arr0[k+3] = vec3_arr1[k+3].normalize(); + vec3_arr0[k + 1] = vec3_arr1[k + 1].normalize(); + vec3_arr0[k + 2] = vec3_arr1[k + 2].normalize(); + vec3_arr0[k + 3] = vec3_arr1[k + 3].normalize(); } currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= NUM_CYCLES; - } + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } - vlog( "Timing:\n" ); - vlog( " \t scalar\t vector\n" ); - vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, - TicksToCycles( vectorTime ) / LOOPCOUNT ); + vlog("Timing:\n"); + vlog(" \t scalar\t vector\n"); + vlog(" \t%10.4f\t%10.4f\n", TicksToCycles(scalarTime) / LOOPCOUNT, + TicksToCycles(vectorTime) / LOOPCOUNT); - return 0; + return 0; } static btVector3& v3norm_ref(btVector3& v) { - float dot = v.m_floats[0] * v.m_floats[0] + + float dot = v.m_floats[0] * v.m_floats[0] + v.m_floats[1] * v.m_floats[1] + v.m_floats[2] * v.m_floats[2]; - + dot = 1.0f / sqrtf(dot); - v.m_floats[0] *= dot; + v.m_floats[0] *= dot; v.m_floats[1] *= dot; v.m_floats[2] *= dot; return v; } -#endif //BT_USE_SSE - +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_v3norm.h b/test/Bullet2/Source/Tests/Test_v3norm.h index 5b86b4acd..caade8b27 100644 --- a/test/Bullet2/Source/Tests/Test_v3norm.h +++ b/test/Bullet2/Source/Tests/Test_v3norm.h @@ -9,14 +9,14 @@ #define BulletTest_Test_v3norm_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_v3norm(void); + int Test_v3norm(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_v3rotate.cpp b/test/Bullet2/Source/Tests/Test_v3rotate.cpp index 8c3aea99b..72d62db6e 100644 --- a/test/Bullet2/Source/Tests/Test_v3rotate.cpp +++ b/test/Bullet2/Source/Tests/Test_v3rotate.cpp @@ -5,10 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_v3rotate.h" #include "vector.h" @@ -20,10 +18,9 @@ #include // reference code for testing purposes -static inline -btVector3& v3rotate_ref( - btVector3& v0, - btVector3& v1, +static inline btVector3& v3rotate_ref( + btVector3& v0, + btVector3& v1, const btScalar& s); #define LOOPCOUNT 2048 @@ -31,164 +28,165 @@ btVector3& v3rotate_ref( int Test_v3rotate(void) { - btVector3 v1, v2; + btVector3 v1, v2; float s; - - float x,y,z,w; - - // Init the data - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - w = BT_NAN; // w channel NaN - v1.setValue(x,y,z); + + float x, y, z, w; + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = BT_NAN; // w channel NaN + v1.setValue(x, y, z); v1.setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - v2.setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v2.setValue(x, y, z); v2.setW(w); - s = RANDF_01 * (float) SIMD_PI; - - btVector3 correct_res, test_res; - - { + s = RANDF_01 * (float)SIMD_PI; + + btVector3 correct_res, test_res; + + { float vNaN = BT_NAN; - correct_res.setValue(vNaN, vNaN, vNaN); + correct_res.setValue(vNaN, vNaN, vNaN); test_res.setValue(vNaN, vNaN, vNaN); test_res = v1.rotate(v2, s); - correct_res = v3rotate_ref(v1, v2, s); - - if( fabs(correct_res.m_floats[0] - test_res.m_floats[0]) + - fabs(correct_res.m_floats[1] - test_res.m_floats[1]) + - fabs(correct_res.m_floats[2] - test_res.m_floats[2]) > FLT_EPSILON * 4) - { - vlog( "Error - v3rotate result error! " - "\ncorrect = (%10.4f, %10.4f, %10.4f) " - "\ntested = (%10.4f, %10.4f, %10.4f) \n", - correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], - test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2]); - + correct_res = v3rotate_ref(v1, v2, s); + + if (fabs(correct_res.m_floats[0] - test_res.m_floats[0]) + + fabs(correct_res.m_floats[1] - test_res.m_floats[1]) + + fabs(correct_res.m_floats[2] - test_res.m_floats[2]) > + FLT_EPSILON * 4) + { + vlog( + "Error - v3rotate result error! " + "\ncorrect = (%10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f) \n", + correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], + test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2]); + return 1; } } - + #define DATA_SIZE LOOPCOUNT btVector3 vec3_arr0[DATA_SIZE]; btVector3 vec3_arr1[DATA_SIZE]; - btScalar s_arr[DATA_SIZE]; + btScalar s_arr[DATA_SIZE]; - uint64_t scalarTime; - uint64_t vectorTime; - size_t j, k; + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - for( k = 0; k < DATA_SIZE; k++ ) + for (k = 0; k < DATA_SIZE; k++) { - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr0[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr0[k].setValue(x, y, z); vec3_arr0[k].setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr1[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x, y, z); vec3_arr1[k].setW(w); - + s_arr[k] = RANDF_01 * (float)SIMD_PI; } - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) { - vec3_arr0[k] = v3rotate_ref(vec3_arr0[k], vec3_arr1[k], s_arr[k]); + vec3_arr0[k] = v3rotate_ref(vec3_arr0[k], vec3_arr1[k], s_arr[k]); } currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= NUM_CYCLES; - } - - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - for( k = 0; k < DATA_SIZE; k++ ) + for (k = 0; k < DATA_SIZE; k++) { - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr0[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr0[k].setValue(x, y, z); vec3_arr0[k].setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr1[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr1[k].setValue(x, y, z); vec3_arr1[k].setW(w); - + s_arr[k] = RANDF_01 * (float)SIMD_PI; } - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) { - vec3_arr0[k ] = vec3_arr0[k ].rotate(vec3_arr1[k ], s_arr[k]); + vec3_arr0[k] = vec3_arr0[k].rotate(vec3_arr1[k], s_arr[k]); } currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= NUM_CYCLES; - } + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } - vlog( "Timing:\n" ); - vlog( " \t scalar\t vector\n" ); - vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, - TicksToCycles( vectorTime ) / LOOPCOUNT ); + vlog("Timing:\n"); + vlog(" \t scalar\t vector\n"); + vlog(" \t%10.4f\t%10.4f\n", TicksToCycles(scalarTime) / LOOPCOUNT, + TicksToCycles(vectorTime) / LOOPCOUNT); - return 0; + return 0; } -static inline -btVector3& +static inline btVector3& v3rotate_ref( - btVector3& v0, - btVector3& wAxis, - const btScalar& _angle) + btVector3& v0, + btVector3& wAxis, + const btScalar& _angle) { - btVector3 o = wAxis * wAxis.dot( v0 ); + btVector3 o = wAxis * wAxis.dot(v0); btVector3 _x = v0 - o; btVector3 _y; - _y = wAxis.cross( v0 ); + _y = wAxis.cross(v0); - v0 = o + _x * cosf( _angle ) + _y * sinf( _angle ); + v0 = o + _x * cosf(_angle) + _y * sinf(_angle); return v0; } -#endif //BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_v3rotate.h b/test/Bullet2/Source/Tests/Test_v3rotate.h index 0c40fc4a4..f40ed06b7 100644 --- a/test/Bullet2/Source/Tests/Test_v3rotate.h +++ b/test/Bullet2/Source/Tests/Test_v3rotate.h @@ -9,14 +9,14 @@ #define BulletTest_Test_v3rotate_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_v3rotate(void); + int Test_v3rotate(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_v3sdiv.cpp b/test/Bullet2/Source/Tests/Test_v3sdiv.cpp index 43d5735ad..9c3d75f49 100644 --- a/test/Bullet2/Source/Tests/Test_v3sdiv.cpp +++ b/test/Bullet2/Source/Tests/Test_v3sdiv.cpp @@ -5,11 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) - +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_v3sdiv.h" #include "vector.h" @@ -21,9 +18,8 @@ #include // reference code for testing purposes -static inline -btVector3& v3sdiv_ref( - btVector3& v, +static inline btVector3& v3sdiv_ref( + btVector3& v, const btScalar& s); #define LOOPCOUNT 2048 @@ -31,151 +27,152 @@ btVector3& v3sdiv_ref( int Test_v3sdiv(void) { - btVector3 v1, v2; + btVector3 v1, v2; btScalar s; - - float x,y,z,w; - - // Init the data - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - w = BT_NAN; // w channel NaN - v1.setValue(x,y,z); + + float x, y, z, w; + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = BT_NAN; // w channel NaN + v1.setValue(x, y, z); v1.setW(w); - v2.setValue(x,y,z); + v2.setValue(x, y, z); v2.setW(w); - s = (float) RANDF_16; - - btVector3 correct_res, test_res; - - { + s = (float)RANDF_16; + + btVector3 correct_res, test_res; + + { float vNaN = BT_NAN; - correct_res.setValue(vNaN, vNaN, vNaN); + correct_res.setValue(vNaN, vNaN, vNaN); test_res.setValue(vNaN, vNaN, vNaN); correct_res = v3sdiv_ref(v1, s); test_res = (v2 /= s); - - if( fabs(correct_res.m_floats[0] - test_res.m_floats[0]) + - fabs(correct_res.m_floats[1] - test_res.m_floats[1]) + - fabs(correct_res.m_floats[2] - test_res.m_floats[2]) > FLT_EPSILON * 4) - { - vlog( "Error - v3sdiv result error! " - "\ncorrect = (%10.4f, %10.4f, %10.4f) " - "\ntested = (%10.4f, %10.4f, %10.4f) \n", - correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], - test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2]); - + + if (fabs(correct_res.m_floats[0] - test_res.m_floats[0]) + + fabs(correct_res.m_floats[1] - test_res.m_floats[1]) + + fabs(correct_res.m_floats[2] - test_res.m_floats[2]) > + FLT_EPSILON * 4) + { + vlog( + "Error - v3sdiv result error! " + "\ncorrect = (%10.4f, %10.4f, %10.4f) " + "\ntested = (%10.4f, %10.4f, %10.4f) \n", + correct_res.m_floats[0], correct_res.m_floats[1], correct_res.m_floats[2], + test_res.m_floats[0], test_res.m_floats[1], test_res.m_floats[2]); + return 1; } } - + #define DATA_SIZE LOOPCOUNT btVector3 vec3_arr[DATA_SIZE]; - btScalar s_arr[DATA_SIZE]; + btScalar s_arr[DATA_SIZE]; - uint64_t scalarTime; - uint64_t vectorTime; - size_t j, k; + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; { - uint64_t startTime, bestTime, currentTime; - - bestTime = uint64_t(-1LL); - scalarTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + uint64_t startTime, bestTime, currentTime; + + bestTime = uint64_t(-1LL); + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - for( k = 0; k < DATA_SIZE; k++ ) + for (k = 0; k < DATA_SIZE; k++) { - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr[k].setValue(x, y, z); vec3_arr[k].setW(w); - + s_arr[k] = RANDF_01; } - startTime = ReadTicks(); - for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + startTime = ReadTicks(); + for (k = 0; k + 4 <= LOOPCOUNT; k += 4) { - v3sdiv_ref( vec3_arr[k], s_arr[k]); - v3sdiv_ref( vec3_arr[k+1], s_arr[k+1]); - v3sdiv_ref( vec3_arr[k+2], s_arr[k+2]); - v3sdiv_ref( vec3_arr[k+3], s_arr[k+3]); + v3sdiv_ref(vec3_arr[k], s_arr[k]); + v3sdiv_ref(vec3_arr[k + 1], s_arr[k + 1]); + v3sdiv_ref(vec3_arr[k + 2], s_arr[k + 2]); + v3sdiv_ref(vec3_arr[k + 3], s_arr[k + 3]); } currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= NUM_CYCLES; - } - - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - for( k = 0; k < DATA_SIZE; k++ ) + for (k = 0; k < DATA_SIZE; k++) { - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - vec3_arr[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + vec3_arr[k].setValue(x, y, z); vec3_arr[k].setW(w); - + s_arr[k] = RANDF_01; } - startTime = ReadTicks(); - for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + startTime = ReadTicks(); + for (k = 0; k + 4 <= LOOPCOUNT; k += 4) { vec3_arr[k] /= s_arr[k]; - vec3_arr[k+1] /= s_arr[k+1]; - vec3_arr[k+2] /= s_arr[k+2]; - vec3_arr[k+3] /= s_arr[k+3]; + vec3_arr[k + 1] /= s_arr[k + 1]; + vec3_arr[k + 2] /= s_arr[k + 2]; + vec3_arr[k + 3] /= s_arr[k + 3]; } currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= NUM_CYCLES; - } + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } - vlog( "Timing:\n" ); - vlog( " \t scalar\t vector\n" ); - vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, - TicksToCycles( vectorTime ) / LOOPCOUNT ); + vlog("Timing:\n"); + vlog(" \t scalar\t vector\n"); + vlog(" \t%10.4f\t%10.4f\n", TicksToCycles(scalarTime) / LOOPCOUNT, + TicksToCycles(vectorTime) / LOOPCOUNT); - return 0; + return 0; } -static inline -btVector3& +static inline btVector3& v3sdiv_ref( - btVector3& v, - const btScalar& s) + btVector3& v, + const btScalar& s) { btScalar recip = btScalar(1.0) / s; - - v.m_floats[0] *= recip; + + v.m_floats[0] *= recip; v.m_floats[1] *= recip; v.m_floats[2] *= recip; return v; } -#endif //BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_v3sdiv.h b/test/Bullet2/Source/Tests/Test_v3sdiv.h index 648715e09..8a21703c1 100644 --- a/test/Bullet2/Source/Tests/Test_v3sdiv.h +++ b/test/Bullet2/Source/Tests/Test_v3sdiv.h @@ -9,14 +9,14 @@ #define BulletTest_Test_v3sdiv_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_v3sdiv(void); + int Test_v3sdiv(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_v3skew.cpp b/test/Bullet2/Source/Tests/Test_v3skew.cpp index a9c90fb25..d4223c546 100644 --- a/test/Bullet2/Source/Tests/Test_v3skew.cpp +++ b/test/Bullet2/Source/Tests/Test_v3skew.cpp @@ -5,10 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_v3skew.h" #include "vector.h" @@ -20,51 +18,52 @@ #include // reference code for testing purposes -static void +static void v3skew_ref( - const btVector3* v, + const btVector3* v, btVector3* v1, btVector3* v2, - btVector3* v3); + btVector3* v3); #define LOOPCOUNT 2048 #define NUM_CYCLES 10000 int Test_v3skew(void) { - btVector3 v, v1, v2, v3, vt1, vt2, vt3; - - float x,y,z,w; - - // Init the data - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - w = BT_NAN; // w channel NaN - v.setValue(x,y,z); + btVector3 v, v1, v2, v3, vt1, vt2, vt3; + + float x, y, z, w; + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = BT_NAN; // w channel NaN + v.setValue(x, y, z); v.setW(w); - v1.setValue(w,w,w); + v1.setValue(w, w, w); v1.setW(w); - vt3 = vt2 = vt1 = v3 = v2 = v1; - - { + vt3 = vt2 = vt1 = v3 = v2 = v1; + + { v3skew_ref(&v, &v1, &v2, &v3); v.getSkewSymmetricMatrix(&vt1, &vt2, &vt3); - /* + /* if( v1.m_floats[0] != vt1.m_floats[0] || v1.m_floats[1] != vt1.m_floats[1] || v1.m_floats[2] != vt1.m_floats[2] ) */ - if(!(v1 == vt1)) - { - vlog( "Error - v3skew result error! " - "\ncorrect v1 = (%10.4f, %10.4f, %10.4f) " - "\ntested v1 = (%10.4f, %10.4f, %10.4f) \n", - v1.m_floats[0], v1.m_floats[1], v1.m_floats[2], - vt1.m_floats[0], vt1.m_floats[1], vt1.m_floats[2]); - + if (!(v1 == vt1)) + { + vlog( + "Error - v3skew result error! " + "\ncorrect v1 = (%10.4f, %10.4f, %10.4f) " + "\ntested v1 = (%10.4f, %10.4f, %10.4f) \n", + v1.m_floats[0], v1.m_floats[1], v1.m_floats[2], + vt1.m_floats[0], vt1.m_floats[1], vt1.m_floats[2]); + return 1; } @@ -73,14 +72,15 @@ int Test_v3skew(void) v2.m_floats[1] != vt2.m_floats[1] || v2.m_floats[2] != vt2.m_floats[2] ) */ - if(!(v2 == vt2)) - { - vlog( "Error - v3skew result error! " - "\ncorrect v2 = (%10.4f, %10.4f, %10.4f) " - "\ntested v2 = (%10.4f, %10.4f, %10.4f) \n", - v2.m_floats[0], v2.m_floats[1], v2.m_floats[2], - vt2.m_floats[0], vt2.m_floats[1], vt2.m_floats[2]); - + if (!(v2 == vt2)) + { + vlog( + "Error - v3skew result error! " + "\ncorrect v2 = (%10.4f, %10.4f, %10.4f) " + "\ntested v2 = (%10.4f, %10.4f, %10.4f) \n", + v2.m_floats[0], v2.m_floats[1], v2.m_floats[2], + vt2.m_floats[0], vt2.m_floats[1], vt2.m_floats[2]); + return 1; } @@ -89,18 +89,19 @@ int Test_v3skew(void) v3.m_floats[1] != vt3.m_floats[1] || v3.m_floats[2] != vt3.m_floats[2] ) */ - if(!(v3 == vt3)) - { - vlog( "Error - v3skew result error! " - "\ncorrect v3 = (%10.4f, %10.4f, %10.4f) " - "\ntested v3 = (%10.4f, %10.4f, %10.4f) \n", - v3.m_floats[0], v3.m_floats[1], v3.m_floats[2], - vt3.m_floats[0], vt3.m_floats[1], vt3.m_floats[2]); - + if (!(v3 == vt3)) + { + vlog( + "Error - v3skew result error! " + "\ncorrect v3 = (%10.4f, %10.4f, %10.4f) " + "\ntested v3 = (%10.4f, %10.4f, %10.4f) \n", + v3.m_floats[0], v3.m_floats[1], v3.m_floats[2], + vt3.m_floats[0], vt3.m_floats[1], vt3.m_floats[2]); + return 1; } } - + #define DATA_SIZE 256 btVector3 v3_arr0[DATA_SIZE]; @@ -108,90 +109,89 @@ int Test_v3skew(void) btVector3 v3_arr2[DATA_SIZE]; btVector3 v3_arr3[DATA_SIZE]; - uint64_t scalarTime; - uint64_t vectorTime; - size_t j, k; + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; - for( k = 0; k < DATA_SIZE; k++ ) + for (k = 0; k < DATA_SIZE; k++) { - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - v3_arr0[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v3_arr0[k].setValue(x, y, z); v3_arr0[k].setW(w); - v3_arr1[k].setValue(w,w,w); + v3_arr1[k].setValue(w, w, w); v3_arr1[k].setW(w); v3_arr3[k] = v3_arr2[k] = v3_arr1[k]; } - + { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - scalarTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) { - size_t k32 = (k & (DATA_SIZE-1)); - v3skew_ref( &v3_arr0[k32], &v3_arr1[k32], &v3_arr2[k32], &v3_arr3[k32]); + size_t k32 = (k & (DATA_SIZE - 1)); + v3skew_ref(&v3_arr0[k32], &v3_arr1[k32], &v3_arr2[k32], &v3_arr3[k32]); } currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= NUM_CYCLES; - } - - { - uint64_t startTime, bestTime, currentTime; - - bestTime = -1LL; - vectorTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = -1LL; + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - startTime = ReadTicks(); - for( k = 0; k < LOOPCOUNT; k++ ) + startTime = ReadTicks(); + for (k = 0; k < LOOPCOUNT; k++) { - size_t k32 = (k & (DATA_SIZE -1)); - v3_arr0[k32].getSkewSymmetricMatrix(&v3_arr1[k32], &v3_arr2[k32], &v3_arr3[k32]); + size_t k32 = (k & (DATA_SIZE - 1)); + v3_arr0[k32].getSkewSymmetricMatrix(&v3_arr1[k32], &v3_arr2[k32], &v3_arr3[k32]); } currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= NUM_CYCLES; - } + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } - vlog( "Timing:\n" ); - vlog( " \t scalar\t vector\n" ); - vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, TicksToCycles( vectorTime ) / LOOPCOUNT ); + vlog("Timing:\n"); + vlog(" \t scalar\t vector\n"); + vlog(" \t%10.4f\t%10.4f\n", TicksToCycles(scalarTime) / LOOPCOUNT, TicksToCycles(vectorTime) / LOOPCOUNT); - return 0; + return 0; } - -static void +static void v3skew_ref( - const btVector3* v, - btVector3* v1, - btVector3* v2, + const btVector3* v, + btVector3* v1, + btVector3* v2, btVector3* v3) { - v1->setValue(0. ,-v->z(),v->y()); - v2->setValue(v->z() ,0. ,-v->x()); - v3->setValue(-v->y(),v->x() ,0.); + v1->setValue(0., -v->z(), v->y()); + v2->setValue(v->z(), 0., -v->x()); + v3->setValue(-v->y(), v->x(), 0.); } -#endif //BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_v3skew.h b/test/Bullet2/Source/Tests/Test_v3skew.h index 255f4a225..a4bf8721c 100644 --- a/test/Bullet2/Source/Tests/Test_v3skew.h +++ b/test/Bullet2/Source/Tests/Test_v3skew.h @@ -9,14 +9,14 @@ #define BulletTest_Test_v3skew_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_v3skew(void); + int Test_v3skew(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Tests/Test_v3triple.cpp b/test/Bullet2/Source/Tests/Test_v3triple.cpp index f0ecbd48e..a0447319c 100644 --- a/test/Bullet2/Source/Tests/Test_v3triple.cpp +++ b/test/Bullet2/Source/Tests/Test_v3triple.cpp @@ -5,10 +5,8 @@ // Copyright (c) 2011 Apple Inc. // - - #include "LinearMath/btScalar.h" -#if defined (BT_USE_SSE_IN_API) || defined (BT_USE_NEON) +#if defined(BT_USE_SSE_IN_API) || defined(BT_USE_NEON) #include "Test_v3triple.h" #include "vector.h" @@ -20,9 +18,9 @@ #include // reference code for testing purposes -static btScalar +static btScalar v3triple_ref( - const btVector3& v, + const btVector3& v, const btVector3& v1, const btVector3& v2); @@ -31,150 +29,154 @@ v3triple_ref( int Test_v3triple(void) { - btVector3 v1, v2, v3; - - float x,y,z,w; - - // Init the data - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - w = BT_NAN; // w channel NaN - v1.setValue(x,y,z); + btVector3 v1, v2, v3; + + float x, y, z, w; + + // Init the data + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + w = BT_NAN; // w channel NaN + v1.setValue(x, y, z); v1.setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - v2.setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v2.setValue(x, y, z); v2.setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - v3.setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v3.setValue(x, y, z); v3.setW(w); - - float correctTriple0, testTriple0; - - { + + float correctTriple0, testTriple0; + + { correctTriple0 = w; testTriple0 = w; - testTriple0 = v3triple_ref(v1,v2,v3); + testTriple0 = v3triple_ref(v1, v2, v3); correctTriple0 = v1.triple(v2, v3); - - if( fabsf(correctTriple0 - testTriple0) > FLT_EPSILON * 4 ) + + if (fabsf(correctTriple0 - testTriple0) > FLT_EPSILON * 4) { - vlog( "Error - v3triple result error! %f != %f \n", correctTriple0, testTriple0); - + vlog("Error - v3triple result error! %f != %f \n", correctTriple0, testTriple0); + return 1; } } - + #define DATA_SIZE 1024 btVector3 v3_arr1[DATA_SIZE]; btVector3 v3_arr2[DATA_SIZE]; btVector3 v3_arr3[DATA_SIZE]; - btScalar res_arr[DATA_SIZE]; + btScalar res_arr[DATA_SIZE]; - uint64_t scalarTime; - uint64_t vectorTime; - size_t j, k; + uint64_t scalarTime; + uint64_t vectorTime; + size_t j, k; - for( k = 0; k < DATA_SIZE; k++ ) + for (k = 0; k < DATA_SIZE; k++) { - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - v3_arr1[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v3_arr1[k].setValue(x, y, z); v3_arr1[k].setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - v3_arr2[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v3_arr2[k].setValue(x, y, z); v3_arr2[k].setW(w); - x = RANDF_01; - y = RANDF_01; - z = RANDF_01; - v3_arr3[k].setValue(x,y,z); + x = RANDF_01; + y = RANDF_01; + z = RANDF_01; + v3_arr3[k].setValue(x, y, z); v3_arr3[k].setW(w); } - + { - uint64_t startTime, bestTime, currentTime; - - bestTime = uint64_t(-1LL); - scalarTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + uint64_t startTime, bestTime, currentTime; + + bestTime = uint64_t(-1LL); + scalarTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - startTime = ReadTicks(); - for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + startTime = ReadTicks(); + for (k = 0; k + 4 <= LOOPCOUNT; k += 4) { - size_t k32 = (k & (DATA_SIZE-1)); - res_arr[k32] = v3triple_ref( v3_arr1[k32], v3_arr2[k32], v3_arr3[k32]); k32++; - res_arr[k32] = v3triple_ref( v3_arr1[k32], v3_arr2[k32], v3_arr3[k32]); k32++; - res_arr[k32] = v3triple_ref( v3_arr1[k32], v3_arr2[k32], v3_arr3[k32]); k32++; - res_arr[k32] = v3triple_ref( v3_arr1[k32], v3_arr2[k32], v3_arr3[k32]); + size_t k32 = (k & (DATA_SIZE - 1)); + res_arr[k32] = v3triple_ref(v3_arr1[k32], v3_arr2[k32], v3_arr3[k32]); + k32++; + res_arr[k32] = v3triple_ref(v3_arr1[k32], v3_arr2[k32], v3_arr3[k32]); + k32++; + res_arr[k32] = v3triple_ref(v3_arr1[k32], v3_arr2[k32], v3_arr3[k32]); + k32++; + res_arr[k32] = v3triple_ref(v3_arr1[k32], v3_arr2[k32], v3_arr3[k32]); } currentTime = ReadTicks() - startTime; - scalarTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - scalarTime = bestTime; - else - scalarTime /= NUM_CYCLES; - } - - { - uint64_t startTime, bestTime, currentTime; - - bestTime = uint64_t(-1LL); - vectorTime = 0; - for (j = 0; j < NUM_CYCLES; j++) + scalarTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + scalarTime = bestTime; + else + scalarTime /= NUM_CYCLES; + } + + { + uint64_t startTime, bestTime, currentTime; + + bestTime = uint64_t(-1LL); + vectorTime = 0; + for (j = 0; j < NUM_CYCLES; j++) { - startTime = ReadTicks(); - for( k = 0; k+4 <= LOOPCOUNT; k+=4 ) + startTime = ReadTicks(); + for (k = 0; k + 4 <= LOOPCOUNT; k += 4) { - size_t k32 = k & (DATA_SIZE -1); - res_arr[k32] = v3_arr1[k32].triple(v3_arr2[k32], v3_arr3[k32]); k32++; - res_arr[k32] = v3_arr1[k32].triple(v3_arr2[k32], v3_arr3[k32]); k32++; - res_arr[k32] = v3_arr1[k32].triple(v3_arr2[k32], v3_arr3[k32]); k32++; - res_arr[k32] = v3_arr1[k32].triple(v3_arr2[k32], v3_arr3[k32]); + size_t k32 = k & (DATA_SIZE - 1); + res_arr[k32] = v3_arr1[k32].triple(v3_arr2[k32], v3_arr3[k32]); + k32++; + res_arr[k32] = v3_arr1[k32].triple(v3_arr2[k32], v3_arr3[k32]); + k32++; + res_arr[k32] = v3_arr1[k32].triple(v3_arr2[k32], v3_arr3[k32]); + k32++; + res_arr[k32] = v3_arr1[k32].triple(v3_arr2[k32], v3_arr3[k32]); } currentTime = ReadTicks() - startTime; - vectorTime += currentTime; - if( currentTime < bestTime ) - bestTime = currentTime; - } - if( 0 == gReportAverageTimes ) - vectorTime = bestTime; - else - vectorTime /= NUM_CYCLES; - } + vectorTime += currentTime; + if (currentTime < bestTime) + bestTime = currentTime; + } + if (0 == gReportAverageTimes) + vectorTime = bestTime; + else + vectorTime /= NUM_CYCLES; + } - vlog( "Timing:\n" ); - vlog( " \t scalar\t vector\n" ); - vlog( " \t%10.4f\t%10.4f\n", TicksToCycles( scalarTime ) / LOOPCOUNT, TicksToCycles( vectorTime ) / LOOPCOUNT ); + vlog("Timing:\n"); + vlog(" \t scalar\t vector\n"); + vlog(" \t%10.4f\t%10.4f\n", TicksToCycles(scalarTime) / LOOPCOUNT, TicksToCycles(vectorTime) / LOOPCOUNT); - return 0; + return 0; } - -static btScalar +static btScalar v3triple_ref( - const btVector3& v, - const btVector3& v1, + const btVector3& v, + const btVector3& v1, const btVector3& v2) { - return - v.m_floats[0] * (v1.m_floats[1] * v2.m_floats[2] - v1.m_floats[2] * v2.m_floats[1]) + - v.m_floats[1] * (v1.m_floats[2] * v2.m_floats[0] - v1.m_floats[0] * v2.m_floats[2]) + - v.m_floats[2] * (v1.m_floats[0] * v2.m_floats[1] - v1.m_floats[1] * v2.m_floats[0]); + return v.m_floats[0] * (v1.m_floats[1] * v2.m_floats[2] - v1.m_floats[2] * v2.m_floats[1]) + + v.m_floats[1] * (v1.m_floats[2] * v2.m_floats[0] - v1.m_floats[0] * v2.m_floats[2]) + + v.m_floats[2] * (v1.m_floats[0] * v2.m_floats[1] - v1.m_floats[1] * v2.m_floats[0]); } -#endif //BT_USE_SSE +#endif //BT_USE_SSE diff --git a/test/Bullet2/Source/Tests/Test_v3triple.h b/test/Bullet2/Source/Tests/Test_v3triple.h index 16fcf2b74..63be87ad2 100644 --- a/test/Bullet2/Source/Tests/Test_v3triple.h +++ b/test/Bullet2/Source/Tests/Test_v3triple.h @@ -9,14 +9,14 @@ #define BulletTest_Test_v3triple_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif -int Test_v3triple(void); + int Test_v3triple(void); #ifdef __cplusplus } #endif - #endif diff --git a/test/Bullet2/Source/Utils.cpp b/test/Bullet2/Source/Utils.cpp index 830f53a84..a65cec2a0 100644 --- a/test/Bullet2/Source/Utils.cpp +++ b/test/Bullet2/Source/Utils.cpp @@ -14,7 +14,7 @@ #else #include "LinearMath/btAlignedAllocator.h" -#endif //__APPLE__ +#endif //__APPLE__ #include @@ -26,247 +26,240 @@ int gReportNanoseconds = 0; #ifdef _WIN32 #include -uint64_t ReadTicks( void ) +uint64_t ReadTicks(void) { - return __rdtsc(); + return __rdtsc(); } -double TicksToCycles( uint64_t delta ) +double TicksToCycles(uint64_t delta) { return double(delta); } -double TicksToSeconds( uint64_t delta ) +double TicksToSeconds(uint64_t delta) { return double(delta); } -void *GuardCalloc( size_t count, size_t size, size_t *objectStride ) +void *GuardCalloc(size_t count, size_t size, size_t *objectStride) { if (objectStride) *objectStride = size; - return (void*) btAlignedAlloc(count * size,16); + return (void *)btAlignedAlloc(count * size, 16); } -void GuardFree( void *buf ) +void GuardFree(void *buf) { btAlignedFree(buf); } #endif - #ifdef __APPLE__ -uint64_t ReadTicks( void ) +uint64_t ReadTicks(void) { - return mach_absolute_time(); + return mach_absolute_time(); } -double TicksToCycles( uint64_t delta ) +double TicksToCycles(uint64_t delta) { - static long double conversion = 0.0L; - if( 0.0L == conversion ) - { - // attempt to get conversion to nanoseconds - mach_timebase_info_data_t info; - int err = mach_timebase_info( &info ); - if( err ) - return __builtin_nanf(""); - conversion = (long double) info.numer / info.denom; - - // attempt to get conversion to cycles - if( 0 == gReportNanoseconds ) - { - uint64_t frequency = 0; - size_t freq_size = sizeof( frequency ); - err = sysctlbyname( "hw.cpufrequency_max", &frequency, &freq_size, NULL, 0 ); - if( err || 0 == frequency ) - vlog( "Failed to get max cpu frequency. Reporting times as nanoseconds.\n" ); - else - { - conversion *= 1e-9L /* sec / ns */ * frequency /* cycles / sec */; - vlog( "Reporting times as cycles. (%2.2f MHz)\n", 1e-6 * frequency ); - } - } - else - vlog( "Reporting times as nanoseconds.\n" ); - } - - return (double) (delta * conversion); + static long double conversion = 0.0L; + if (0.0L == conversion) + { + // attempt to get conversion to nanoseconds + mach_timebase_info_data_t info; + int err = mach_timebase_info(&info); + if (err) + return __builtin_nanf(""); + conversion = (long double)info.numer / info.denom; + + // attempt to get conversion to cycles + if (0 == gReportNanoseconds) + { + uint64_t frequency = 0; + size_t freq_size = sizeof(frequency); + err = sysctlbyname("hw.cpufrequency_max", &frequency, &freq_size, NULL, 0); + if (err || 0 == frequency) + vlog("Failed to get max cpu frequency. Reporting times as nanoseconds.\n"); + else + { + conversion *= 1e-9L /* sec / ns */ * frequency /* cycles / sec */; + vlog("Reporting times as cycles. (%2.2f MHz)\n", 1e-6 * frequency); + } + } + else + vlog("Reporting times as nanoseconds.\n"); + } + + return (double)(delta * conversion); } -double TicksToSeconds( uint64_t delta ) +double TicksToSeconds(uint64_t delta) { - static long double conversion = 0.0L; - if( 0.0L == conversion ) - { - // attempt to get conversion to nanoseconds - mach_timebase_info_data_t info; - int err = mach_timebase_info( &info ); - if( err ) - return __builtin_nanf(""); - conversion = info.numer / (1e9L * info.denom); - } - - return (double) (delta * conversion); + static long double conversion = 0.0L; + if (0.0L == conversion) + { + // attempt to get conversion to nanoseconds + mach_timebase_info_data_t info; + int err = mach_timebase_info(&info); + if (err) + return __builtin_nanf(""); + conversion = info.numer / (1e9L * info.denom); + } + + return (double)(delta * conversion); } - - #pragma mark - #pragma mark GuardCalloc #define kPageSize 4096 - typedef struct BufInfo { - void *head; - size_t count; - size_t stride; - size_t totalSize; -}BufInfo; + void *head; + size_t count; + size_t stride; + size_t totalSize; +} BufInfo; -static int GuardMarkBuffer( void *buffer, int flag ); +static int GuardMarkBuffer(void *buffer, int flag); -void *GuardCalloc( size_t count, size_t size, size_t *objectStride ) +void *GuardCalloc(size_t count, size_t size, size_t *objectStride) { - if( objectStride ) - *objectStride = 0; - - // Round size up to a multiple of a page size - size_t stride = (size + kPageSize - 1) & -kPageSize; - - //Calculate total size of the allocation - size_t totalSize = count * (stride + kPageSize) + kPageSize; + if (objectStride) + *objectStride = 0; - // Allocate - char *buf = (char*)mmap( NULL, - totalSize, - PROT_READ | PROT_WRITE, - MAP_ANON | MAP_SHARED, - 0, 0 ); - if( MAP_FAILED == buf ) - { - vlog( "mmap failed: %d\n", errno ); - return NULL; - } + // Round size up to a multiple of a page size + size_t stride = (size + kPageSize - 1) & -kPageSize; - // Find the first byte of user data - char *result = buf + kPageSize; + //Calculate total size of the allocation + size_t totalSize = count * (stride + kPageSize) + kPageSize; - // Record what we did for posterity - BufInfo *bptr = (BufInfo*) result - 1; - bptr->head = buf; - bptr->count = count; - bptr->stride = stride; - bptr->totalSize = totalSize; - - // Place the first guard page. Masks our record above. - if( mprotect(buf, kPageSize, PROT_NONE) ) - { - munmap( buf, totalSize); - vlog( "mprotect -1 failed: %d\n", errno ); - return NULL; - } - - // Place the rest of the guard pages - size_t i; - char *p = result; - for( i = 0; i < count; i++ ) - { - p += stride; - if( mprotect(p, kPageSize, PROT_NONE) ) - { - munmap( buf, totalSize); - vlog( "mprotect %lu failed: %d\n", i, errno ); - return NULL; - } - p += kPageSize; - } - - // record the stride from object to object - if( objectStride ) - *objectStride = stride + kPageSize; - - // return pointer to first object - return result; + // Allocate + char *buf = (char *)mmap(NULL, + totalSize, + PROT_READ | PROT_WRITE, + MAP_ANON | MAP_SHARED, + 0, 0); + if (MAP_FAILED == buf) + { + vlog("mmap failed: %d\n", errno); + return NULL; + } + + // Find the first byte of user data + char *result = buf + kPageSize; + + // Record what we did for posterity + BufInfo *bptr = (BufInfo *)result - 1; + bptr->head = buf; + bptr->count = count; + bptr->stride = stride; + bptr->totalSize = totalSize; + + // Place the first guard page. Masks our record above. + if (mprotect(buf, kPageSize, PROT_NONE)) + { + munmap(buf, totalSize); + vlog("mprotect -1 failed: %d\n", errno); + return NULL; + } + + // Place the rest of the guard pages + size_t i; + char *p = result; + for (i = 0; i < count; i++) + { + p += stride; + if (mprotect(p, kPageSize, PROT_NONE)) + { + munmap(buf, totalSize); + vlog("mprotect %lu failed: %d\n", i, errno); + return NULL; + } + p += kPageSize; + } + + // record the stride from object to object + if (objectStride) + *objectStride = stride + kPageSize; + + // return pointer to first object + return result; } - -void GuardFree( void *buf ) +void GuardFree(void *buf) { - if( mprotect((char*)buf - kPageSize, kPageSize, PROT_READ) ) - { - vlog( "Unable to read buf info. GuardFree failed! %p (%d)\n", buf, errno ); - return; - } - - BufInfo *bptr = (BufInfo*) buf - 1; - - if( munmap( bptr->head, bptr->totalSize ) ) - vlog( "Unable to unmap data. GuardFree failed! %p (%d)\n", buf, errno ); + if (mprotect((char *)buf - kPageSize, kPageSize, PROT_READ)) + { + vlog("Unable to read buf info. GuardFree failed! %p (%d)\n", buf, errno); + return; + } + + BufInfo *bptr = (BufInfo *)buf - 1; + + if (munmap(bptr->head, bptr->totalSize)) + vlog("Unable to unmap data. GuardFree failed! %p (%d)\n", buf, errno); } -int GuardMarkReadOnly( void *buf ) +int GuardMarkReadOnly(void *buf) { - return GuardMarkBuffer(buf, PROT_READ); + return GuardMarkBuffer(buf, PROT_READ); } -int GuardMarkReadWrite( void *buf) +int GuardMarkReadWrite(void *buf) { - return GuardMarkBuffer(buf, PROT_READ | PROT_WRITE); + return GuardMarkBuffer(buf, PROT_READ | PROT_WRITE); } -int GuardMarkWriteOnly( void *buf) +int GuardMarkWriteOnly(void *buf) { - return GuardMarkBuffer(buf, PROT_WRITE); + return GuardMarkBuffer(buf, PROT_WRITE); } -static int GuardMarkBuffer( void *buf, int flag ) +static int GuardMarkBuffer(void *buf, int flag) { - if( mprotect((char*)buf - kPageSize, kPageSize, PROT_READ) ) - { - vlog( "Unable to read buf info. GuardMarkBuffer %d failed! %p (%d)\n", flag, buf, errno ); - return errno; - } - - BufInfo *bptr = (BufInfo*) buf - 1; - - size_t count = bptr->count; - size_t stride = bptr->stride; - - size_t i; - for( i = 0; i < count; i++ ) - { - if( mprotect(buf, stride, flag) ) - { - vlog( "Unable to protect segment %ld. GuardMarkBuffer %d failed! %p (%d)\n", i, flag, buf, errno ); - return errno; - } - bptr += stride + kPageSize; - } - - if( mprotect((char*)buf - kPageSize, kPageSize, PROT_NONE) ) - { - vlog( "Unable to protect leading guard page. GuardMarkBuffer %d failed! %p (%d)\n", flag, buf, errno ); - return errno; - } - - return 0; + if (mprotect((char *)buf - kPageSize, kPageSize, PROT_READ)) + { + vlog("Unable to read buf info. GuardMarkBuffer %d failed! %p (%d)\n", flag, buf, errno); + return errno; + } + + BufInfo *bptr = (BufInfo *)buf - 1; + + size_t count = bptr->count; + size_t stride = bptr->stride; + + size_t i; + for (i = 0; i < count; i++) + { + if (mprotect(buf, stride, flag)) + { + vlog("Unable to protect segment %ld. GuardMarkBuffer %d failed! %p (%d)\n", i, flag, buf, errno); + return errno; + } + bptr += stride + kPageSize; + } + + if (mprotect((char *)buf - kPageSize, kPageSize, PROT_NONE)) + { + vlog("Unable to protect leading guard page. GuardMarkBuffer %d failed! %p (%d)\n", flag, buf, errno); + return errno; + } + + return 0; } #endif uint32_t random_number32(void) { - return ((uint32_t) rand() << 16) ^ rand(); + return ((uint32_t)rand() << 16) ^ rand(); } - uint64_t random_number64(void) { - return ((uint64_t) rand() << 48) ^ - ((uint64_t) rand() << 32) ^ - ((uint64_t) rand() << 16) ^ - rand(); + return ((uint64_t)rand() << 48) ^ + ((uint64_t)rand() << 32) ^ + ((uint64_t)rand() << 16) ^ + rand(); } - diff --git a/test/Bullet2/Source/Utils.h b/test/Bullet2/Source/Utils.h index 9d30cd450..993ad4d01 100644 --- a/test/Bullet2/Source/Utils.h +++ b/test/Bullet2/Source/Utils.h @@ -10,63 +10,59 @@ #include "btIntDefines.h" - - #include #include #ifdef _WIN32 -#define LARGE_FLOAT17 (1.f * powf(2,17)) -#define RANDF_16 (random_number32() * powf(2,-16)) -#define RANDF_01 ( random_number32() * powf(2,-32) ) -#define RANDF ( random_number32() * powf(2,-8) ) -#define RANDF_m1p1 (2.0f*( random_number32() * powf(2,-32)-1.0f)) +#define LARGE_FLOAT17 (1.f * powf(2, 17)) +#define RANDF_16 (random_number32() * powf(2, -16)) +#define RANDF_01 (random_number32() * powf(2, -32)) +#define RANDF (random_number32() * powf(2, -8)) +#define RANDF_m1p1 (2.0f * (random_number32() * powf(2, -32) - 1.0f)) #else #define LARGE_FLOAT17 (0x1.0p17f) -#define RANDF_16 (random_number32() * 0x1.0p-16f) -#define RANDF_01 ( random_number32() * 0x1.0p-32f ) -#define RANDF ( random_number32() * 0x1.0p-8f ) -#define RANDF_m1p1 (2.0f*( random_number32() * 0x1.0p-32f )-1.0f) -#endif//_WIN32 - +#define RANDF_16 (random_number32() * 0x1.0p-16f) +#define RANDF_01 (random_number32() * 0x1.0p-32f) +#define RANDF (random_number32() * 0x1.0p-8f) +#define RANDF_m1p1 (2.0f * (random_number32() * 0x1.0p-32f) - 1.0f) +#endif //_WIN32 #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif - - /********************* + + /********************* * Timing * *********************/ - extern int gReportNanoseconds; + extern int gReportNanoseconds; - uint64_t ReadTicks( void ); - double TicksToCycles( uint64_t delta ); // Performance data should be reported in cycles most of the time. - double TicksToSeconds( uint64_t delta ); + uint64_t ReadTicks(void); + double TicksToCycles(uint64_t delta); // Performance data should be reported in cycles most of the time. + double TicksToSeconds(uint64_t delta); - - /********************* + /********************* * Guard Heap * *********************/ - // return buffer containing count objects of size size, with guard pages in betweeen. - // The stride between one object and the next is given by objectStride. - // objectStride may be NULL. Objects so created are freed with GuardFree - void *GuardCalloc( size_t count, size_t size, size_t *objectStride ); - void GuardFree( void * ); - // mark the contents of a guard buffer read-only or write-only. Return 0 on success. - int GuardMarkReadOnly( void *); - int GuardMarkWriteOnly( void *); - int GuardMarkReadWrite( void *); - - /********************* + // return buffer containing count objects of size size, with guard pages in betweeen. + // The stride between one object and the next is given by objectStride. + // objectStride may be NULL. Objects so created are freed with GuardFree + void *GuardCalloc(size_t count, size_t size, size_t *objectStride); + void GuardFree(void *); + // mark the contents of a guard buffer read-only or write-only. Return 0 on success. + int GuardMarkReadOnly(void *); + int GuardMarkWriteOnly(void *); + int GuardMarkReadWrite(void *); + +/********************* * Printing * *********************/ - #define vlog( ... ) printf( __VA_ARGS__ ) - uint32_t random_number32(void); - uint64_t random_number64(void); - +#define vlog(...) printf(__VA_ARGS__) + uint32_t random_number32(void); + uint64_t random_number64(void); + #ifdef __cplusplus - } +} #endif - #endif diff --git a/test/Bullet2/Source/btIntDefines.h b/test/Bullet2/Source/btIntDefines.h index c5dfd5fcc..07e3b4e56 100644 --- a/test/Bullet2/Source/btIntDefines.h +++ b/test/Bullet2/Source/btIntDefines.h @@ -3,17 +3,17 @@ #define BT_INT_DEFINES_H #ifdef __GNUC__ - #include +#include #elif defined(_MSC_VER) - typedef __int32 int32_t; - typedef __int64 int64_t; - typedef unsigned __int32 uint32_t; - typedef unsigned __int64 uint64_t; +typedef __int32 int32_t; +typedef __int64 int64_t; +typedef unsigned __int32 uint32_t; +typedef unsigned __int64 uint64_t; #else - typedef int int32_t; - typedef long long int int64_t; - typedef unsigned int uint32_t; - typedef unsigned long long int uint64_t; +typedef int int32_t; +typedef long long int int64_t; +typedef unsigned int uint32_t; +typedef unsigned long long int uint64_t; #endif -#endif //BT_INT_DEFINES_H +#endif //BT_INT_DEFINES_H diff --git a/test/Bullet2/Source/main.cpp b/test/Bullet2/Source/main.cpp index 55f3f8489..bf069612b 100644 --- a/test/Bullet2/Source/main.cpp +++ b/test/Bullet2/Source/main.cpp @@ -7,7 +7,7 @@ #include #ifdef __APPLE__ #include -#endif //__APPLE__ +#endif //__APPLE__ #include #include @@ -17,7 +17,7 @@ #include "TestList.h" #include "LinearMath/btScalar.h" -#if defined (BT_USE_NEON) || defined (BT_USE_SSE_IN_API) +#if defined(BT_USE_NEON) || defined(BT_USE_SSE_IN_API) #ifdef _WIN32 #define strcasecmp _stricmp @@ -37,284 +37,278 @@ const char **gArgv; typedef struct TestNode { - struct TestNode *next; - const char *name; -}TestNode; + struct TestNode *next; + const char *name; +} TestNode; TestNode *gNodeList = NULL; -static int ParseArgs( int argc, const char *argv[] ); -static void PrintUsage( void ); -static int Init( void ); -static void ListTests(void ); +static int ParseArgs(int argc, const char *argv[]); +static void PrintUsage(void); +static int Init(void); +static void ListTests(void); -const char *gArch = -#ifdef __i386__ - "i386"; +const char *gArch = +#ifdef __i386__ + "i386"; #elif defined __x86_64__ - "x86_64"; + "x86_64"; #elif defined __arm__ - "arm"; + "arm"; #elif defined _WIN64 "win64"; #elif defined _WIN32 "win32"; #else - #error unknown arch +#error unknown arch #endif - - - - #include -int main (int argc, const char * argv[]) +int main(int argc, const char *argv[]) { + // Enable just one test programatically (instead of command-line param) + // TestNode *node = (TestNode*) malloc( sizeof( TestNode ) ); + // node->name = "btDbvt"; + // node->next = 0; + // gNodeList = node; - // Enable just one test programatically (instead of command-line param) - // TestNode *node = (TestNode*) malloc( sizeof( TestNode ) ); - // node->name = "btDbvt"; - // node->next = 0; - // gNodeList = node; - srand(0.f); - int numPassedTests=0; - int numFailedTests= 0; + int numPassedTests = 0; + int numFailedTests = 0; - int err; - - // Parse arguments. Build gNodeList. - if( (err = ParseArgs( argc, argv ) ) ) - { - if( EXIT_NO_ERROR == err ) - return 0; - - PrintUsage(); - return err; - } - - printf("Arch: %s\n", gArch ); - - if( gReportAverageTimes ) - printf( "Reporting average times.\n" ); - else - printf( "Reporting best times.\n" ); - - // Set a few things up - if( (err = Init() )) - { - printf( "Init failed.\n" ); - return err; - } - - if( NULL == gNodeList ) - { // test everything - printf( "No function list found. Testing everything...\n" ); - size_t i; - for( i = 0; NULL != gTestList[i].test_func; i++ ) - { - printf( "\n----------------------------------------------\n" ); - printf( "Testing %s:\n", gTestList[i].name ); - printf( "----------------------------------------------\n" ); - uint64_t startTime = ReadTicks(); - int local_error = gTestList[i].test_func(); - uint64_t currentTime = ReadTicks() - startTime; - if( local_error ) - { + int err; + + // Parse arguments. Build gNodeList. + if ((err = ParseArgs(argc, argv))) + { + if (EXIT_NO_ERROR == err) + return 0; + + PrintUsage(); + return err; + } + + printf("Arch: %s\n", gArch); + + if (gReportAverageTimes) + printf("Reporting average times.\n"); + else + printf("Reporting best times.\n"); + + // Set a few things up + if ((err = Init())) + { + printf("Init failed.\n"); + return err; + } + + if (NULL == gNodeList) + { // test everything + printf("No function list found. Testing everything...\n"); + size_t i; + for (i = 0; NULL != gTestList[i].test_func; i++) + { + printf("\n----------------------------------------------\n"); + printf("Testing %s:\n", gTestList[i].name); + printf("----------------------------------------------\n"); + uint64_t startTime = ReadTicks(); + int local_error = gTestList[i].test_func(); + uint64_t currentTime = ReadTicks() - startTime; + if (local_error) + { numFailedTests++; - printf( "*** %s test failed with error: %d\n", gTestList[i].name, local_error ); - if( gExitOnError ) - return local_error; - if( 0 == err ) - err = local_error; - } - else + printf("*** %s test failed with error: %d\n", gTestList[i].name, local_error); + if (gExitOnError) + return local_error; + if (0 == err) + err = local_error; + } + else { numPassedTests++; - printf("%s Passed.\t\t\t(%2.2gs)\n", gTestList[i].name, TicksToSeconds(currentTime)); + printf("%s Passed.\t\t\t(%2.2gs)\n", gTestList[i].name, TicksToSeconds(currentTime)); } - } - } - else - { // test just the list - while( NULL != gNodeList ) - { - TestNode *currentNode = gNodeList; - gNodeList = gNodeList->next; - - // Find the test with that name - size_t i; - for( i = 0; NULL != gTestList[i].test_func; i++ ) - if( 0 == strcasecmp( currentNode->name, gTestList[i].name ) ) - break; - - if( NULL != gTestList[i].test_func ) - { - printf( "\n----------------------------------------------\n" ); - printf( "Testing %s:\n", gTestList[i].name ); - printf( "----------------------------------------------\n" ); - uint64_t startTime = ReadTicks(); - int local_error = gTestList[i].test_func(); - uint64_t currentTime = ReadTicks() - startTime; - if( local_error ) - { + } + } + else + { // test just the list + while (NULL != gNodeList) + { + TestNode *currentNode = gNodeList; + gNodeList = gNodeList->next; + + // Find the test with that name + size_t i; + for (i = 0; NULL != gTestList[i].test_func; i++) + if (0 == strcasecmp(currentNode->name, gTestList[i].name)) + break; + + if (NULL != gTestList[i].test_func) + { + printf("\n----------------------------------------------\n"); + printf("Testing %s:\n", gTestList[i].name); + printf("----------------------------------------------\n"); + uint64_t startTime = ReadTicks(); + int local_error = gTestList[i].test_func(); + uint64_t currentTime = ReadTicks() - startTime; + if (local_error) + { numFailedTests++; - printf( "*** %s test failed with error: %d\n", gTestList[i].name, local_error ); - if( gExitOnError ) - return local_error; - if( 0 == err ) - err = local_error; - } - else + printf("*** %s test failed with error: %d\n", gTestList[i].name, local_error); + if (gExitOnError) + return local_error; + if (0 == err) + err = local_error; + } + else { numPassedTests++; - printf("%s Passed.\t\t\t(%2.2gs)\n", gTestList[i].name, TicksToSeconds(currentTime)); + printf("%s Passed.\t\t\t(%2.2gs)\n", gTestList[i].name, TicksToSeconds(currentTime)); } - } - else - { - printf( "\n***Error: Test name \"%s\" not found! Skipping.\n", currentNode->name ); - err = -1; - if( gExitOnError ) - return -1; - } - - free( currentNode ); - } - } - printf( "\n----------------------------------------------\n" ); - printf("numPassedTests = %d, numFailedTests = %d\n",numPassedTests,numFailedTests); - - free(gFullPath); - return err; + } + else + { + printf("\n***Error: Test name \"%s\" not found! Skipping.\n", currentNode->name); + err = -1; + if (gExitOnError) + return -1; + } + + free(currentNode); + } + } + printf("\n----------------------------------------------\n"); + printf("numPassedTests = %d, numFailedTests = %d\n", numPassedTests, numFailedTests); + + free(gFullPath); + return err; } -static int Init( void ) +static int Init(void) { - // init the timer - TicksToCycles(0); - - return 0; + // init the timer + TicksToCycles(0); + + return 0; } -static int ParseArgs( int argc, const char *argv[] ) +static int ParseArgs(int argc, const char *argv[]) { - int listTests = 0; - TestNode *list = NULL; - - gArgc = argc; - gArgv = argv; - gFullPath = (char*)malloc( strlen(argv[0]) + 1); - strcpy(gFullPath, argv[0]); - gAppName = basename( gFullPath ); - if( NULL == gAppName ) - gAppName = ""; - - printf( "%s ", gAppName ); - int skipremaining=0; - - size_t i; - for( i = 1; i < argc; i++ ) - { - const char *arg = argv[i]; - printf( "\t%s", arg ); - if( arg[0] == '-' ) - { - arg++; - while( arg[0] != '\0' ) - { - int stop = 0; - switch( arg[0] ) - { - case 'a': - gReportAverageTimes ^= 1; - break; - case 'e': - gExitOnError ^= 1; - break; - case 'h': - PrintUsage(); - return EXIT_NO_ERROR; - case 'l': - listTests ^= 1; - return EXIT_NO_ERROR; - case 's': - gReportNanoseconds ^= 1; - break; - case ' ': - stop = 1; - break; - case 'N'://ignore the -NSDocumentRevisionsDebugMode argument from XCode 4.3.2 - skipremaining = 1; - stop = 1; - break; - default: - printf( "\nError: Unknown flag \'%c\'\n", arg[0] ); - return -1; - } - if( stop ) - break; - arg++; - } - } - else - { // add function name to the list - TestNode *node = (TestNode*) malloc( sizeof( TestNode ) ); - node->name = arg; - node->next = list; - list = node; - } - if (skipremaining) - break; - } - - // reverse the list of test names, and stick on gNodeList - while( list ) - { - TestNode *node = list; - TestNode *next = node->next; - node->next = gNodeList; - gNodeList = node; - list = next; - } - - printf( "\n" ); - if( listTests ) - ListTests(); - - return 0; + int listTests = 0; + TestNode *list = NULL; + + gArgc = argc; + gArgv = argv; + gFullPath = (char *)malloc(strlen(argv[0]) + 1); + strcpy(gFullPath, argv[0]); + gAppName = basename(gFullPath); + if (NULL == gAppName) + gAppName = ""; + + printf("%s ", gAppName); + int skipremaining = 0; + + size_t i; + for (i = 1; i < argc; i++) + { + const char *arg = argv[i]; + printf("\t%s", arg); + if (arg[0] == '-') + { + arg++; + while (arg[0] != '\0') + { + int stop = 0; + switch (arg[0]) + { + case 'a': + gReportAverageTimes ^= 1; + break; + case 'e': + gExitOnError ^= 1; + break; + case 'h': + PrintUsage(); + return EXIT_NO_ERROR; + case 'l': + listTests ^= 1; + return EXIT_NO_ERROR; + case 's': + gReportNanoseconds ^= 1; + break; + case ' ': + stop = 1; + break; + case 'N': //ignore the -NSDocumentRevisionsDebugMode argument from XCode 4.3.2 + skipremaining = 1; + stop = 1; + break; + default: + printf("\nError: Unknown flag \'%c\'\n", arg[0]); + return -1; + } + if (stop) + break; + arg++; + } + } + else + { // add function name to the list + TestNode *node = (TestNode *)malloc(sizeof(TestNode)); + node->name = arg; + node->next = list; + list = node; + } + if (skipremaining) + break; + } + + // reverse the list of test names, and stick on gNodeList + while (list) + { + TestNode *node = list; + TestNode *next = node->next; + node->next = gNodeList; + gNodeList = node; + list = next; + } + + printf("\n"); + if (listTests) + ListTests(); + + return 0; } - -static void PrintUsage( void ) +static void PrintUsage(void) { - printf("\nUsage:\n" ); - printf("%s: <-aehls> ", gAppName); - printf("Options:\n"); - printf("\t-a\tToggle report average times vs. best times. (Default: best times)\n"); - printf("\t-e\tToggle exit immediately on error behavior. (Default: off)\n"); - printf("\t-h\tPrint this message.\n"); - printf("\t-l\tToggle list available test names. (Default: off)\n"); - printf("\t-s\tToggle report times in cycles or nanoseconds. (Default: cycles)\n\n"); - printf("\tOptions may be followed by one or more test names. If no test names \n" ); - printf("\tare provided, then all tests are run.\n\n"); + printf("\nUsage:\n"); + printf("%s: <-aehls> ", gAppName); + printf("Options:\n"); + printf("\t-a\tToggle report average times vs. best times. (Default: best times)\n"); + printf("\t-e\tToggle exit immediately on error behavior. (Default: off)\n"); + printf("\t-h\tPrint this message.\n"); + printf("\t-l\tToggle list available test names. (Default: off)\n"); + printf("\t-s\tToggle report times in cycles or nanoseconds. (Default: cycles)\n\n"); + printf("\tOptions may be followed by one or more test names. If no test names \n"); + printf("\tare provided, then all tests are run.\n\n"); } -static void ListTests(void ) +static void ListTests(void) { - size_t i; - - printf("\nTests:\n"); - for( i = 0; NULL != gTestList[i].test_func; i++ ) - { - printf( "%19s", gTestList[i].name ); - if( NULL != gTestList[i].test_func ) - printf( "," ); - if( 3 == (i&3) ) - printf( "\n" ); - } + size_t i; + + printf("\nTests:\n"); + for (i = 0; NULL != gTestList[i].test_func; i++) + { + printf("%19s", gTestList[i].name); + if (NULL != gTestList[i].test_func) + printf(","); + if (3 == (i & 3)) + printf("\n"); + } } #else #include diff --git a/test/Bullet2/Source/main.h b/test/Bullet2/Source/main.h index e8e5dd284..45f282cee 100644 --- a/test/Bullet2/Source/main.h +++ b/test/Bullet2/Source/main.h @@ -9,17 +9,16 @@ #define BulletTest_main_h #ifdef __cplusplus -extern "C" { +extern "C" +{ #endif - extern int gReportAverageTimes; // if 0, report best times - extern int gExitOnError; // if non-zero, exit as soon an an error is encountered - extern const char *gAppName; // the name of this application - + extern int gReportAverageTimes; // if 0, report best times + extern int gExitOnError; // if non-zero, exit as soon an an error is encountered + extern const char *gAppName; // the name of this application + #ifdef __cplusplus } #endif - - #endif diff --git a/test/Bullet2/Source/vector.h b/test/Bullet2/Source/vector.h index c476a9e16..4dd03e542 100644 --- a/test/Bullet2/Source/vector.h +++ b/test/Bullet2/Source/vector.h @@ -9,62 +9,61 @@ #define BulletTest_vector_h #ifdef __SSE__ - typedef float float4 __attribute__ ((__vector_size__(16))); - #include +typedef float float4 __attribute__((__vector_size__(16))); +#include #endif #ifdef __SSE2__ - typedef double double2 __attribute__ ((__vector_size__(16))); - typedef char char16 __attribute__ ((__vector_size__(16))); - typedef unsigned char uchar16 __attribute__ ((__vector_size__(16))); - typedef short short8 __attribute__ ((__vector_size__(16))); - typedef unsigned short ushort8 __attribute__ ((__vector_size__(16))); - typedef int int4 __attribute__ ((__vector_size__(16))); - // typedef unsigned int uint4 __attribute__ ((__vector_size__(16))); - #ifdef __LP64__ - typedef long long2 __attribute__ ((__vector_size__(16))); - typedef unsigned long ulong2 __attribute__ ((__vector_size__(16))); - #else - typedef long long long2 __attribute__ ((__vector_size__(16))); - typedef unsigned long long ulong2 __attribute__ ((__vector_size__(16))); - #endif - #include +typedef double double2 __attribute__((__vector_size__(16))); +typedef char char16 __attribute__((__vector_size__(16))); +typedef unsigned char uchar16 __attribute__((__vector_size__(16))); +typedef short short8 __attribute__((__vector_size__(16))); +typedef unsigned short ushort8 __attribute__((__vector_size__(16))); +typedef int int4 __attribute__((__vector_size__(16))); +// typedef unsigned int uint4 __attribute__ ((__vector_size__(16))); +#ifdef __LP64__ +typedef long long2 __attribute__((__vector_size__(16))); +typedef unsigned long ulong2 __attribute__((__vector_size__(16))); +#else +typedef long long long2 __attribute__((__vector_size__(16))); +typedef unsigned long long ulong2 __attribute__((__vector_size__(16))); +#endif +#include #endif #ifdef __SSE3__ - #include +#include #endif #ifdef __SSSE3__ - #include +#include #endif #ifdef __SSE4_1__ - #include +#include #endif #ifdef __arm__ - #include - #ifdef _ARM_ARCH_7 - #define ARM_NEON_GCC_COMPATIBILITY 1 - #include - typedef float float4 __attribute__ ((__vector_size__(16))); - typedef double double2 __attribute__ ((__vector_size__(16))); - typedef char char16 __attribute__ ((__vector_size__(16))); - typedef unsigned char uchar16 __attribute__ ((__vector_size__(16))); - typedef short short8 __attribute__ ((__vector_size__(16))); - typedef unsigned short ushort8 __attribute__ ((__vector_size__(16))); - typedef int int4 __attribute__ ((__vector_size__(16))); - typedef unsigned int uint4 __attribute__ ((__vector_size__(16))); - #ifdef __LP64__ - typedef long long2 __attribute__ ((__vector_size__(16))); - typedef unsigned long ulong2 __attribute__ ((__vector_size__(16))); - #else - typedef long long long2 __attribute__ ((__vector_size__(16))); - typedef unsigned long long ulong2 __attribute__ ((__vector_size__(16))); - #endif - #endif +#include +#ifdef _ARM_ARCH_7 +#define ARM_NEON_GCC_COMPATIBILITY 1 +#include +typedef float float4 __attribute__((__vector_size__(16))); +typedef double double2 __attribute__((__vector_size__(16))); +typedef char char16 __attribute__((__vector_size__(16))); +typedef unsigned char uchar16 __attribute__((__vector_size__(16))); +typedef short short8 __attribute__((__vector_size__(16))); +typedef unsigned short ushort8 __attribute__((__vector_size__(16))); +typedef int int4 __attribute__((__vector_size__(16))); +typedef unsigned int uint4 __attribute__((__vector_size__(16))); +#ifdef __LP64__ +typedef long long2 __attribute__((__vector_size__(16))); +typedef unsigned long ulong2 __attribute__((__vector_size__(16))); +#else +typedef long long long2 __attribute__((__vector_size__(16))); +typedef unsigned long long ulong2 __attribute__((__vector_size__(16))); +#endif +#endif #endif - #endif diff --git a/test/Bullet2/vectormath/neon/boolInVec.h b/test/Bullet2/vectormath/neon/boolInVec.h index ba16838c0..cf67923bf 100644 --- a/test/Bullet2/vectormath/neon/boolInVec.h +++ b/test/Bullet2/vectormath/neon/boolInVec.h @@ -18,8 +18,8 @@ subject to the following restrictions: #define _BOOLINVEC_H #include -namespace Vectormath { - +namespace Vectormath +{ class floatInVec; //-------------------------------------------------------------------------------------------------- @@ -29,80 +29,77 @@ class floatInVec; class boolInVec { private: - unsigned int mData; + unsigned int mData; public: - // Default constructor; does no initialization - // - inline boolInVec( ) { }; + // Default constructor; does no initialization + // + inline boolInVec(){}; - // Construct from a value converted from float - // - inline boolInVec(floatInVec vec); + // Construct from a value converted from float + // + inline boolInVec(floatInVec vec); - // Explicit cast from bool - // - explicit inline boolInVec(bool scalar); + // Explicit cast from bool + // + explicit inline boolInVec(bool scalar); - // Explicit cast to bool - // - inline bool getAsBool() const; + // Explicit cast to bool + // + inline bool getAsBool() const; #ifndef _VECTORMATH_NO_SCALAR_CAST - // Implicit cast to bool - // - inline operator bool() const; + // Implicit cast to bool + // + inline operator bool() const; #endif - // Boolean negation operator - // - inline const boolInVec operator ! () const; + // Boolean negation operator + // + inline const boolInVec operator!() const; - // Assignment operator - // - inline boolInVec& operator = (boolInVec vec); + // Assignment operator + // + inline boolInVec& operator=(boolInVec vec); - // Boolean and assignment operator - // - inline boolInVec& operator &= (boolInVec vec); + // Boolean and assignment operator + // + inline boolInVec& operator&=(boolInVec vec); - // Boolean exclusive or assignment operator - // - inline boolInVec& operator ^= (boolInVec vec); - - // Boolean or assignment operator - // - inline boolInVec& operator |= (boolInVec vec); + // Boolean exclusive or assignment operator + // + inline boolInVec& operator^=(boolInVec vec); + // Boolean or assignment operator + // + inline boolInVec& operator|=(boolInVec vec); }; // Equal operator // -inline const boolInVec operator == (boolInVec vec0, boolInVec vec1); +inline const boolInVec operator==(boolInVec vec0, boolInVec vec1); // Not equal operator // -inline const boolInVec operator != (boolInVec vec0, boolInVec vec1); +inline const boolInVec operator!=(boolInVec vec0, boolInVec vec1); // And operator // -inline const boolInVec operator & (boolInVec vec0, boolInVec vec1); +inline const boolInVec operator&(boolInVec vec0, boolInVec vec1); // Exclusive or operator // -inline const boolInVec operator ^ (boolInVec vec0, boolInVec vec1); +inline const boolInVec operator^(boolInVec vec0, boolInVec vec1); // Or operator // -inline const boolInVec operator | (boolInVec vec0, boolInVec vec1); +inline const boolInVec operator|(boolInVec vec0, boolInVec vec1); // Conditionally select between two values // inline const boolInVec select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1); - -} // namespace Vectormath - +} // namespace Vectormath //-------------------------------------------------------------------------------------------------- // boolInVec implementation @@ -110,117 +107,101 @@ inline const boolInVec select(boolInVec vec0, boolInVec vec1, boolInVec select_v #include "floatInVec.h" -namespace Vectormath { - -inline -boolInVec::boolInVec(floatInVec vec) +namespace Vectormath { - *this = (vec != floatInVec(0.0f)); +inline boolInVec::boolInVec(floatInVec vec) +{ + *this = (vec != floatInVec(0.0f)); } -inline -boolInVec::boolInVec(bool scalar) +inline boolInVec::boolInVec(bool scalar) { - mData = -(int)scalar; + mData = -(int)scalar; } -inline -bool +inline bool boolInVec::getAsBool() const { - return (mData > 0); + return (mData > 0); } #ifndef _VECTORMATH_NO_SCALAR_CAST -inline -boolInVec::operator bool() const +inline boolInVec::operator bool() const { - return getAsBool(); + return getAsBool(); } #endif -inline -const boolInVec -boolInVec::operator ! () const +inline const boolInVec +boolInVec::operator!() const { - return boolInVec(!mData); + return boolInVec(!mData); } -inline -boolInVec& -boolInVec::operator = (boolInVec vec) +inline boolInVec& +boolInVec::operator=(boolInVec vec) { - mData = vec.mData; - return *this; + mData = vec.mData; + return *this; } -inline -boolInVec& -boolInVec::operator &= (boolInVec vec) +inline boolInVec& +boolInVec::operator&=(boolInVec vec) { - *this = *this & vec; - return *this; + *this = *this & vec; + return *this; } -inline -boolInVec& -boolInVec::operator ^= (boolInVec vec) +inline boolInVec& +boolInVec::operator^=(boolInVec vec) { - *this = *this ^ vec; - return *this; + *this = *this ^ vec; + return *this; } -inline -boolInVec& -boolInVec::operator |= (boolInVec vec) +inline boolInVec& +boolInVec::operator|=(boolInVec vec) { - *this = *this | vec; - return *this; + *this = *this | vec; + return *this; } -inline -const boolInVec -operator == (boolInVec vec0, boolInVec vec1) +inline const boolInVec +operator==(boolInVec vec0, boolInVec vec1) { - return boolInVec(vec0.getAsBool() == vec1.getAsBool()); + return boolInVec(vec0.getAsBool() == vec1.getAsBool()); } -inline -const boolInVec -operator != (boolInVec vec0, boolInVec vec1) +inline const boolInVec +operator!=(boolInVec vec0, boolInVec vec1) { - return !(vec0 == vec1); + return !(vec0 == vec1); } -inline -const boolInVec -operator & (boolInVec vec0, boolInVec vec1) +inline const boolInVec +operator&(boolInVec vec0, boolInVec vec1) { - return boolInVec(vec0.getAsBool() & vec1.getAsBool()); + return boolInVec(vec0.getAsBool() & vec1.getAsBool()); } -inline -const boolInVec -operator | (boolInVec vec0, boolInVec vec1) +inline const boolInVec +operator|(boolInVec vec0, boolInVec vec1) { - return boolInVec(vec0.getAsBool() | vec1.getAsBool()); + return boolInVec(vec0.getAsBool() | vec1.getAsBool()); } -inline -const boolInVec -operator ^ (boolInVec vec0, boolInVec vec1) +inline const boolInVec +operator^(boolInVec vec0, boolInVec vec1) { - return boolInVec(vec0.getAsBool() ^ vec1.getAsBool()); + return boolInVec(vec0.getAsBool() ^ vec1.getAsBool()); } -inline -const boolInVec +inline const boolInVec select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1) { - return (select_vec1.getAsBool() == 0) ? vec0 : vec1; + return (select_vec1.getAsBool() == 0) ? vec0 : vec1; } -} // namespace Vectormath - -#endif // boolInVec_h +} // namespace Vectormath +#endif // boolInVec_h diff --git a/test/Bullet2/vectormath/neon/floatInVec.h b/test/Bullet2/vectormath/neon/floatInVec.h index 26147d22b..7a3c2849c 100644 --- a/test/Bullet2/vectormath/neon/floatInVec.h +++ b/test/Bullet2/vectormath/neon/floatInVec.h @@ -17,8 +17,8 @@ subject to the following restrictions: #define _FLOATINVEC_H #include -namespace Vectormath { - +namespace Vectormath +{ class boolInVec; //-------------------------------------------------------------------------------------------------- @@ -30,120 +30,117 @@ class boolInVec; class floatInVec { private: - float mData; + float mData; public: - // Default constructor; does no initialization - // - inline floatInVec( ) { }; + // Default constructor; does no initialization + // + inline floatInVec(){}; - // Construct from a value converted from bool - // - inline floatInVec(boolInVec vec); + // Construct from a value converted from bool + // + inline floatInVec(boolInVec vec); - // Explicit cast from float - // - explicit inline floatInVec(float scalar); + // Explicit cast from float + // + explicit inline floatInVec(float scalar); - // Explicit cast to float - // - inline float getAsFloat() const; + // Explicit cast to float + // + inline float getAsFloat() const; #ifndef _VECTORMATH_NO_SCALAR_CAST - // Implicit cast to float - // - inline operator float() const; + // Implicit cast to float + // + inline operator float() const; #endif - // Post increment (add 1.0f) - // - inline const floatInVec operator ++ (int); + // Post increment (add 1.0f) + // + inline const floatInVec operator++(int); - // Post decrement (subtract 1.0f) - // - inline const floatInVec operator -- (int); + // Post decrement (subtract 1.0f) + // + inline const floatInVec operator--(int); - // Pre increment (add 1.0f) - // - inline floatInVec& operator ++ (); + // Pre increment (add 1.0f) + // + inline floatInVec& operator++(); - // Pre decrement (subtract 1.0f) - // - inline floatInVec& operator -- (); + // Pre decrement (subtract 1.0f) + // + inline floatInVec& operator--(); - // Negation operator - // - inline const floatInVec operator - () const; + // Negation operator + // + inline const floatInVec operator-() const; - // Assignment operator - // - inline floatInVec& operator = (floatInVec vec); + // Assignment operator + // + inline floatInVec& operator=(floatInVec vec); - // Multiplication assignment operator - // - inline floatInVec& operator *= (floatInVec vec); + // Multiplication assignment operator + // + inline floatInVec& operator*=(floatInVec vec); - // Division assignment operator - // - inline floatInVec& operator /= (floatInVec vec); + // Division assignment operator + // + inline floatInVec& operator/=(floatInVec vec); - // Addition assignment operator - // - inline floatInVec& operator += (floatInVec vec); - - // Subtraction assignment operator - // - inline floatInVec& operator -= (floatInVec vec); + // Addition assignment operator + // + inline floatInVec& operator+=(floatInVec vec); + // Subtraction assignment operator + // + inline floatInVec& operator-=(floatInVec vec); }; // Multiplication operator // -inline const floatInVec operator * (floatInVec vec0, floatInVec vec1); +inline const floatInVec operator*(floatInVec vec0, floatInVec vec1); // Division operator // -inline const floatInVec operator / (floatInVec vec0, floatInVec vec1); +inline const floatInVec operator/(floatInVec vec0, floatInVec vec1); // Addition operator // -inline const floatInVec operator + (floatInVec vec0, floatInVec vec1); +inline const floatInVec operator+(floatInVec vec0, floatInVec vec1); // Subtraction operator // -inline const floatInVec operator - (floatInVec vec0, floatInVec vec1); +inline const floatInVec operator-(floatInVec vec0, floatInVec vec1); // Less than operator // -inline const boolInVec operator < (floatInVec vec0, floatInVec vec1); +inline const boolInVec operator<(floatInVec vec0, floatInVec vec1); // Less than or equal operator // -inline const boolInVec operator <= (floatInVec vec0, floatInVec vec1); +inline const boolInVec operator<=(floatInVec vec0, floatInVec vec1); // Greater than operator // -inline const boolInVec operator > (floatInVec vec0, floatInVec vec1); +inline const boolInVec operator>(floatInVec vec0, floatInVec vec1); // Greater than or equal operator // -inline const boolInVec operator >= (floatInVec vec0, floatInVec vec1); +inline const boolInVec operator>=(floatInVec vec0, floatInVec vec1); // Equal operator // -inline const boolInVec operator == (floatInVec vec0, floatInVec vec1); +inline const boolInVec operator==(floatInVec vec0, floatInVec vec1); // Not equal operator // -inline const boolInVec operator != (floatInVec vec0, floatInVec vec1); +inline const boolInVec operator!=(floatInVec vec0, floatInVec vec1); // Conditionally select between two values // inline const floatInVec select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1); - -} // namespace Vectormath - +} // namespace Vectormath //-------------------------------------------------------------------------------------------------- // floatInVec implementation @@ -151,194 +148,168 @@ inline const floatInVec select(floatInVec vec0, floatInVec vec1, boolInVec selec #include "boolInVec.h" -namespace Vectormath { - -inline -floatInVec::floatInVec(boolInVec vec) +namespace Vectormath { - mData = float(vec.getAsBool()); +inline floatInVec::floatInVec(boolInVec vec) +{ + mData = float(vec.getAsBool()); } -inline -floatInVec::floatInVec(float scalar) +inline floatInVec::floatInVec(float scalar) { - mData = scalar; + mData = scalar; } -inline -float +inline float floatInVec::getAsFloat() const { - return mData; + return mData; } #ifndef _VECTORMATH_NO_SCALAR_CAST -inline -floatInVec::operator float() const +inline floatInVec::operator float() const { - return getAsFloat(); + return getAsFloat(); } #endif -inline -const floatInVec -floatInVec::operator ++ (int) +inline const floatInVec +floatInVec::operator++(int) { - float olddata = mData; - operator ++(); - return floatInVec(olddata); + float olddata = mData; + operator++(); + return floatInVec(olddata); } -inline -const floatInVec -floatInVec::operator -- (int) +inline const floatInVec +floatInVec::operator--(int) { - float olddata = mData; - operator --(); - return floatInVec(olddata); + float olddata = mData; + operator--(); + return floatInVec(olddata); } -inline -floatInVec& -floatInVec::operator ++ () +inline floatInVec& +floatInVec::operator++() { - *this += floatInVec(1.0f); - return *this; + *this += floatInVec(1.0f); + return *this; } -inline -floatInVec& -floatInVec::operator -- () +inline floatInVec& +floatInVec::operator--() { - *this -= floatInVec(1.0f); - return *this; + *this -= floatInVec(1.0f); + return *this; } -inline -const floatInVec -floatInVec::operator - () const +inline const floatInVec +floatInVec::operator-() const { - return floatInVec(-mData); + return floatInVec(-mData); } -inline -floatInVec& -floatInVec::operator = (floatInVec vec) +inline floatInVec& +floatInVec::operator=(floatInVec vec) { - mData = vec.mData; - return *this; + mData = vec.mData; + return *this; } -inline -floatInVec& -floatInVec::operator *= (floatInVec vec) +inline floatInVec& +floatInVec::operator*=(floatInVec vec) { - *this = *this * vec; - return *this; + *this = *this * vec; + return *this; } -inline -floatInVec& -floatInVec::operator /= (floatInVec vec) +inline floatInVec& +floatInVec::operator/=(floatInVec vec) { - *this = *this / vec; - return *this; + *this = *this / vec; + return *this; } -inline -floatInVec& -floatInVec::operator += (floatInVec vec) +inline floatInVec& +floatInVec::operator+=(floatInVec vec) { - *this = *this + vec; - return *this; + *this = *this + vec; + return *this; } -inline -floatInVec& -floatInVec::operator -= (floatInVec vec) +inline floatInVec& +floatInVec::operator-=(floatInVec vec) { - *this = *this - vec; - return *this; + *this = *this - vec; + return *this; } -inline -const floatInVec -operator * (floatInVec vec0, floatInVec vec1) +inline const floatInVec +operator*(floatInVec vec0, floatInVec vec1) { - return floatInVec(vec0.getAsFloat() * vec1.getAsFloat()); + return floatInVec(vec0.getAsFloat() * vec1.getAsFloat()); } -inline -const floatInVec -operator / (floatInVec num, floatInVec den) +inline const floatInVec +operator/(floatInVec num, floatInVec den) { - return floatInVec(num.getAsFloat() / den.getAsFloat()); + return floatInVec(num.getAsFloat() / den.getAsFloat()); } -inline -const floatInVec -operator + (floatInVec vec0, floatInVec vec1) +inline const floatInVec +operator+(floatInVec vec0, floatInVec vec1) { - return floatInVec(vec0.getAsFloat() + vec1.getAsFloat()); + return floatInVec(vec0.getAsFloat() + vec1.getAsFloat()); } -inline -const floatInVec -operator - (floatInVec vec0, floatInVec vec1) +inline const floatInVec +operator-(floatInVec vec0, floatInVec vec1) { - return floatInVec(vec0.getAsFloat() - vec1.getAsFloat()); + return floatInVec(vec0.getAsFloat() - vec1.getAsFloat()); } -inline -const boolInVec -operator < (floatInVec vec0, floatInVec vec1) +inline const boolInVec +operator<(floatInVec vec0, floatInVec vec1) { - return boolInVec(vec0.getAsFloat() < vec1.getAsFloat()); + return boolInVec(vec0.getAsFloat() < vec1.getAsFloat()); } -inline -const boolInVec -operator <= (floatInVec vec0, floatInVec vec1) +inline const boolInVec +operator<=(floatInVec vec0, floatInVec vec1) { - return !(vec0 > vec1); + return !(vec0 > vec1); } -inline -const boolInVec -operator > (floatInVec vec0, floatInVec vec1) +inline const boolInVec +operator>(floatInVec vec0, floatInVec vec1) { - return boolInVec(vec0.getAsFloat() > vec1.getAsFloat()); + return boolInVec(vec0.getAsFloat() > vec1.getAsFloat()); } -inline -const boolInVec -operator >= (floatInVec vec0, floatInVec vec1) +inline const boolInVec +operator>=(floatInVec vec0, floatInVec vec1) { - return !(vec0 < vec1); + return !(vec0 < vec1); } -inline -const boolInVec -operator == (floatInVec vec0, floatInVec vec1) +inline const boolInVec +operator==(floatInVec vec0, floatInVec vec1) { - return boolInVec(vec0.getAsFloat() == vec1.getAsFloat()); + return boolInVec(vec0.getAsFloat() == vec1.getAsFloat()); } -inline -const boolInVec -operator != (floatInVec vec0, floatInVec vec1) +inline const boolInVec +operator!=(floatInVec vec0, floatInVec vec1) { - return !(vec0 == vec1); + return !(vec0 == vec1); } -inline -const floatInVec +inline const floatInVec select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1) { - return (select_vec1.getAsBool() == 0) ? vec0 : vec1; + return (select_vec1.getAsBool() == 0) ? vec0 : vec1; } -} // namespace Vectormath - -#endif // floatInVec_h +} // namespace Vectormath +#endif // floatInVec_h diff --git a/test/Bullet2/vectormath/neon/mat_aos.h b/test/Bullet2/vectormath/neon/mat_aos.h index e61f601c3..2a8cd65a7 100644 --- a/test/Bullet2/vectormath/neon/mat_aos.h +++ b/test/Bullet2/vectormath/neon/mat_aos.h @@ -17,9 +17,10 @@ subject to the following restrictions: #ifndef _VECTORMATH_MAT_AOS_CPP_H #define _VECTORMATH_MAT_AOS_CPP_H -namespace Vectormath { -namespace Aos { - +namespace Vectormath +{ +namespace Aos +{ //----------------------------------------------------------------------------- // Constants @@ -28,1604 +29,1534 @@ namespace Aos { //----------------------------------------------------------------------------- // Definitions -inline Matrix3::Matrix3( const Matrix3 & mat ) +inline Matrix3::Matrix3(const Matrix3 &mat) { - mCol0 = mat.mCol0; - mCol1 = mat.mCol1; - mCol2 = mat.mCol2; + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; } -inline Matrix3::Matrix3( float scalar ) +inline Matrix3::Matrix3(float scalar) { - mCol0 = Vector3( scalar ); - mCol1 = Vector3( scalar ); - mCol2 = Vector3( scalar ); + mCol0 = Vector3(scalar); + mCol1 = Vector3(scalar); + mCol2 = Vector3(scalar); } -inline Matrix3::Matrix3( const Quat & unitQuat ) +inline Matrix3::Matrix3(const Quat &unitQuat) { - float qx, qy, qz, qw, qx2, qy2, qz2, qxqx2, qyqy2, qzqz2, qxqy2, qyqz2, qzqw2, qxqz2, qyqw2, qxqw2; - qx = unitQuat.getX(); - qy = unitQuat.getY(); - qz = unitQuat.getZ(); - qw = unitQuat.getW(); - qx2 = ( qx + qx ); - qy2 = ( qy + qy ); - qz2 = ( qz + qz ); - qxqx2 = ( qx * qx2 ); - qxqy2 = ( qx * qy2 ); - qxqz2 = ( qx * qz2 ); - qxqw2 = ( qw * qx2 ); - qyqy2 = ( qy * qy2 ); - qyqz2 = ( qy * qz2 ); - qyqw2 = ( qw * qy2 ); - qzqz2 = ( qz * qz2 ); - qzqw2 = ( qw * qz2 ); - mCol0 = Vector3( ( ( 1.0f - qyqy2 ) - qzqz2 ), ( qxqy2 + qzqw2 ), ( qxqz2 - qyqw2 ) ); - mCol1 = Vector3( ( qxqy2 - qzqw2 ), ( ( 1.0f - qxqx2 ) - qzqz2 ), ( qyqz2 + qxqw2 ) ); - mCol2 = Vector3( ( qxqz2 + qyqw2 ), ( qyqz2 - qxqw2 ), ( ( 1.0f - qxqx2 ) - qyqy2 ) ); + float qx, qy, qz, qw, qx2, qy2, qz2, qxqx2, qyqy2, qzqz2, qxqy2, qyqz2, qzqw2, qxqz2, qyqw2, qxqw2; + qx = unitQuat.getX(); + qy = unitQuat.getY(); + qz = unitQuat.getZ(); + qw = unitQuat.getW(); + qx2 = (qx + qx); + qy2 = (qy + qy); + qz2 = (qz + qz); + qxqx2 = (qx * qx2); + qxqy2 = (qx * qy2); + qxqz2 = (qx * qz2); + qxqw2 = (qw * qx2); + qyqy2 = (qy * qy2); + qyqz2 = (qy * qz2); + qyqw2 = (qw * qy2); + qzqz2 = (qz * qz2); + qzqw2 = (qw * qz2); + mCol0 = Vector3(((1.0f - qyqy2) - qzqz2), (qxqy2 + qzqw2), (qxqz2 - qyqw2)); + mCol1 = Vector3((qxqy2 - qzqw2), ((1.0f - qxqx2) - qzqz2), (qyqz2 + qxqw2)); + mCol2 = Vector3((qxqz2 + qyqw2), (qyqz2 - qxqw2), ((1.0f - qxqx2) - qyqy2)); } -inline Matrix3::Matrix3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2 ) +inline Matrix3::Matrix3(const Vector3 &_col0, const Vector3 &_col1, const Vector3 &_col2) { - mCol0 = _col0; - mCol1 = _col1; - mCol2 = _col2; + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; } -inline Matrix3 & Matrix3::setCol0( const Vector3 & _col0 ) +inline Matrix3 &Matrix3::setCol0(const Vector3 &_col0) { - mCol0 = _col0; - return *this; + mCol0 = _col0; + return *this; } -inline Matrix3 & Matrix3::setCol1( const Vector3 & _col1 ) +inline Matrix3 &Matrix3::setCol1(const Vector3 &_col1) { - mCol1 = _col1; - return *this; + mCol1 = _col1; + return *this; } -inline Matrix3 & Matrix3::setCol2( const Vector3 & _col2 ) +inline Matrix3 &Matrix3::setCol2(const Vector3 &_col2) { - mCol2 = _col2; - return *this; + mCol2 = _col2; + return *this; } -inline Matrix3 & Matrix3::setCol( int col, const Vector3 & vec ) +inline Matrix3 &Matrix3::setCol(int col, const Vector3 &vec) { - *(&mCol0 + col) = vec; - return *this; + *(&mCol0 + col) = vec; + return *this; } -inline Matrix3 & Matrix3::setRow( int row, const Vector3 & vec ) +inline Matrix3 &Matrix3::setRow(int row, const Vector3 &vec) { - mCol0.setElem( row, vec.getElem( 0 ) ); - mCol1.setElem( row, vec.getElem( 1 ) ); - mCol2.setElem( row, vec.getElem( 2 ) ); - return *this; + mCol0.setElem(row, vec.getElem(0)); + mCol1.setElem(row, vec.getElem(1)); + mCol2.setElem(row, vec.getElem(2)); + return *this; } -inline Matrix3 & Matrix3::setElem( int col, int row, float val ) +inline Matrix3 &Matrix3::setElem(int col, int row, float val) { - Vector3 tmpV3_0; - tmpV3_0 = this->getCol( col ); - tmpV3_0.setElem( row, val ); - this->setCol( col, tmpV3_0 ); - return *this; + Vector3 tmpV3_0; + tmpV3_0 = this->getCol(col); + tmpV3_0.setElem(row, val); + this->setCol(col, tmpV3_0); + return *this; } -inline float Matrix3::getElem( int col, int row ) const +inline float Matrix3::getElem(int col, int row) const { - return this->getCol( col ).getElem( row ); + return this->getCol(col).getElem(row); } -inline const Vector3 Matrix3::getCol0( ) const +inline const Vector3 Matrix3::getCol0() const { - return mCol0; + return mCol0; } -inline const Vector3 Matrix3::getCol1( ) const +inline const Vector3 Matrix3::getCol1() const { - return mCol1; + return mCol1; } -inline const Vector3 Matrix3::getCol2( ) const +inline const Vector3 Matrix3::getCol2() const { - return mCol2; + return mCol2; } -inline const Vector3 Matrix3::getCol( int col ) const +inline const Vector3 Matrix3::getCol(int col) const { - return *(&mCol0 + col); + return *(&mCol0 + col); } -inline const Vector3 Matrix3::getRow( int row ) const +inline const Vector3 Matrix3::getRow(int row) const { - return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) ); + return Vector3(mCol0.getElem(row), mCol1.getElem(row), mCol2.getElem(row)); } -inline Vector3 & Matrix3::operator []( int col ) +inline Vector3 &Matrix3::operator[](int col) { - return *(&mCol0 + col); + return *(&mCol0 + col); } -inline const Vector3 Matrix3::operator []( int col ) const +inline const Vector3 Matrix3::operator[](int col) const { - return *(&mCol0 + col); + return *(&mCol0 + col); } -inline Matrix3 & Matrix3::operator =( const Matrix3 & mat ) +inline Matrix3 &Matrix3::operator=(const Matrix3 &mat) { - mCol0 = mat.mCol0; - mCol1 = mat.mCol1; - mCol2 = mat.mCol2; - return *this; + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + return *this; } -inline const Matrix3 transpose( const Matrix3 & mat ) +inline const Matrix3 transpose(const Matrix3 &mat) { - return Matrix3( - Vector3( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX() ), - Vector3( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY() ), - Vector3( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ() ) - ); + return Matrix3( + Vector3(mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX()), + Vector3(mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY()), + Vector3(mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ())); } -inline const Matrix3 inverse( const Matrix3 & mat ) +inline const Matrix3 inverse(const Matrix3 &mat) { - Vector3 tmp0, tmp1, tmp2; - float detinv; - tmp0 = cross( mat.getCol1(), mat.getCol2() ); - tmp1 = cross( mat.getCol2(), mat.getCol0() ); - tmp2 = cross( mat.getCol0(), mat.getCol1() ); - detinv = ( 1.0f / dot( mat.getCol2(), tmp2 ) ); - return Matrix3( - Vector3( ( tmp0.getX() * detinv ), ( tmp1.getX() * detinv ), ( tmp2.getX() * detinv ) ), - Vector3( ( tmp0.getY() * detinv ), ( tmp1.getY() * detinv ), ( tmp2.getY() * detinv ) ), - Vector3( ( tmp0.getZ() * detinv ), ( tmp1.getZ() * detinv ), ( tmp2.getZ() * detinv ) ) - ); + Vector3 tmp0, tmp1, tmp2; + float detinv; + tmp0 = cross(mat.getCol1(), mat.getCol2()); + tmp1 = cross(mat.getCol2(), mat.getCol0()); + tmp2 = cross(mat.getCol0(), mat.getCol1()); + detinv = (1.0f / dot(mat.getCol2(), tmp2)); + return Matrix3( + Vector3((tmp0.getX() * detinv), (tmp1.getX() * detinv), (tmp2.getX() * detinv)), + Vector3((tmp0.getY() * detinv), (tmp1.getY() * detinv), (tmp2.getY() * detinv)), + Vector3((tmp0.getZ() * detinv), (tmp1.getZ() * detinv), (tmp2.getZ() * detinv))); } -inline float determinant( const Matrix3 & mat ) +inline float determinant(const Matrix3 &mat) { - return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) ); + return dot(mat.getCol2(), cross(mat.getCol0(), mat.getCol1())); } -inline const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const +inline const Matrix3 Matrix3::operator+(const Matrix3 &mat) const { - return Matrix3( - ( mCol0 + mat.mCol0 ), - ( mCol1 + mat.mCol1 ), - ( mCol2 + mat.mCol2 ) - ); + return Matrix3( + (mCol0 + mat.mCol0), + (mCol1 + mat.mCol1), + (mCol2 + mat.mCol2)); } -inline const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const +inline const Matrix3 Matrix3::operator-(const Matrix3 &mat) const { - return Matrix3( - ( mCol0 - mat.mCol0 ), - ( mCol1 - mat.mCol1 ), - ( mCol2 - mat.mCol2 ) - ); + return Matrix3( + (mCol0 - mat.mCol0), + (mCol1 - mat.mCol1), + (mCol2 - mat.mCol2)); } -inline Matrix3 & Matrix3::operator +=( const Matrix3 & mat ) +inline Matrix3 &Matrix3::operator+=(const Matrix3 &mat) { - *this = *this + mat; - return *this; + *this = *this + mat; + return *this; } -inline Matrix3 & Matrix3::operator -=( const Matrix3 & mat ) +inline Matrix3 &Matrix3::operator-=(const Matrix3 &mat) { - *this = *this - mat; - return *this; + *this = *this - mat; + return *this; } -inline const Matrix3 Matrix3::operator -( ) const +inline const Matrix3 Matrix3::operator-() const { - return Matrix3( - ( -mCol0 ), - ( -mCol1 ), - ( -mCol2 ) - ); + return Matrix3( + (-mCol0), + (-mCol1), + (-mCol2)); } -inline const Matrix3 absPerElem( const Matrix3 & mat ) +inline const Matrix3 absPerElem(const Matrix3 &mat) { - return Matrix3( - absPerElem( mat.getCol0() ), - absPerElem( mat.getCol1() ), - absPerElem( mat.getCol2() ) - ); + return Matrix3( + absPerElem(mat.getCol0()), + absPerElem(mat.getCol1()), + absPerElem(mat.getCol2())); } -inline const Matrix3 Matrix3::operator *( float scalar ) const +inline const Matrix3 Matrix3::operator*(float scalar) const { - return Matrix3( - ( mCol0 * scalar ), - ( mCol1 * scalar ), - ( mCol2 * scalar ) - ); + return Matrix3( + (mCol0 * scalar), + (mCol1 * scalar), + (mCol2 * scalar)); } -inline Matrix3 & Matrix3::operator *=( float scalar ) +inline Matrix3 &Matrix3::operator*=(float scalar) { - *this = *this * scalar; - return *this; + *this = *this * scalar; + return *this; } -inline const Matrix3 operator *( float scalar, const Matrix3 & mat ) +inline const Matrix3 operator*(float scalar, const Matrix3 &mat) { - return mat * scalar; + return mat * scalar; } -inline const Vector3 Matrix3::operator *( const Vector3 & vec ) const +inline const Vector3 Matrix3::operator*(const Vector3 &vec) const { - return Vector3( - ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), - ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), - ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) - ); + return Vector3( + (((mCol0.getX() * vec.getX()) + (mCol1.getX() * vec.getY())) + (mCol2.getX() * vec.getZ())), + (((mCol0.getY() * vec.getX()) + (mCol1.getY() * vec.getY())) + (mCol2.getY() * vec.getZ())), + (((mCol0.getZ() * vec.getX()) + (mCol1.getZ() * vec.getY())) + (mCol2.getZ() * vec.getZ()))); } -inline const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const +inline const Matrix3 Matrix3::operator*(const Matrix3 &mat) const { - return Matrix3( - ( *this * mat.mCol0 ), - ( *this * mat.mCol1 ), - ( *this * mat.mCol2 ) - ); + return Matrix3( + (*this * mat.mCol0), + (*this * mat.mCol1), + (*this * mat.mCol2)); } -inline Matrix3 & Matrix3::operator *=( const Matrix3 & mat ) +inline Matrix3 &Matrix3::operator*=(const Matrix3 &mat) { - *this = *this * mat; - return *this; + *this = *this * mat; + return *this; } -inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ) +inline const Matrix3 mulPerElem(const Matrix3 &mat0, const Matrix3 &mat1) { - return Matrix3( - mulPerElem( mat0.getCol0(), mat1.getCol0() ), - mulPerElem( mat0.getCol1(), mat1.getCol1() ), - mulPerElem( mat0.getCol2(), mat1.getCol2() ) - ); + return Matrix3( + mulPerElem(mat0.getCol0(), mat1.getCol0()), + mulPerElem(mat0.getCol1(), mat1.getCol1()), + mulPerElem(mat0.getCol2(), mat1.getCol2())); } -inline const Matrix3 Matrix3::identity( ) +inline const Matrix3 Matrix3::identity() { - return Matrix3( - Vector3::xAxis( ), - Vector3::yAxis( ), - Vector3::zAxis( ) - ); + return Matrix3( + Vector3::xAxis(), + Vector3::yAxis(), + Vector3::zAxis()); } -inline const Matrix3 Matrix3::rotationX( float radians ) +inline const Matrix3 Matrix3::rotationX(float radians) { - float s, c; - s = sinf( radians ); - c = cosf( radians ); - return Matrix3( - Vector3::xAxis( ), - Vector3( 0.0f, c, s ), - Vector3( 0.0f, -s, c ) - ); + float s, c; + s = sinf(radians); + c = cosf(radians); + return Matrix3( + Vector3::xAxis(), + Vector3(0.0f, c, s), + Vector3(0.0f, -s, c)); } -inline const Matrix3 Matrix3::rotationY( float radians ) +inline const Matrix3 Matrix3::rotationY(float radians) { - float s, c; - s = sinf( radians ); - c = cosf( radians ); - return Matrix3( - Vector3( c, 0.0f, -s ), - Vector3::yAxis( ), - Vector3( s, 0.0f, c ) - ); + float s, c; + s = sinf(radians); + c = cosf(radians); + return Matrix3( + Vector3(c, 0.0f, -s), + Vector3::yAxis(), + Vector3(s, 0.0f, c)); } -inline const Matrix3 Matrix3::rotationZ( float radians ) +inline const Matrix3 Matrix3::rotationZ(float radians) { - float s, c; - s = sinf( radians ); - c = cosf( radians ); - return Matrix3( - Vector3( c, s, 0.0f ), - Vector3( -s, c, 0.0f ), - Vector3::zAxis( ) - ); + float s, c; + s = sinf(radians); + c = cosf(radians); + return Matrix3( + Vector3(c, s, 0.0f), + Vector3(-s, c, 0.0f), + Vector3::zAxis()); } -inline const Matrix3 Matrix3::rotationZYX( const Vector3 & radiansXYZ ) +inline const Matrix3 Matrix3::rotationZYX(const Vector3 &radiansXYZ) { - float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; - sX = sinf( radiansXYZ.getX() ); - cX = cosf( radiansXYZ.getX() ); - sY = sinf( radiansXYZ.getY() ); - cY = cosf( radiansXYZ.getY() ); - sZ = sinf( radiansXYZ.getZ() ); - cZ = cosf( radiansXYZ.getZ() ); - tmp0 = ( cZ * sY ); - tmp1 = ( sZ * sY ); - return Matrix3( - Vector3( ( cZ * cY ), ( sZ * cY ), -sY ), - Vector3( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ) ), - Vector3( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ) ) - ); + float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; + sX = sinf(radiansXYZ.getX()); + cX = cosf(radiansXYZ.getX()); + sY = sinf(radiansXYZ.getY()); + cY = cosf(radiansXYZ.getY()); + sZ = sinf(radiansXYZ.getZ()); + cZ = cosf(radiansXYZ.getZ()); + tmp0 = (cZ * sY); + tmp1 = (sZ * sY); + return Matrix3( + Vector3((cZ * cY), (sZ * cY), -sY), + Vector3(((tmp0 * sX) - (sZ * cX)), ((tmp1 * sX) + (cZ * cX)), (cY * sX)), + Vector3(((tmp0 * cX) + (sZ * sX)), ((tmp1 * cX) - (cZ * sX)), (cY * cX))); } -inline const Matrix3 Matrix3::rotation( float radians, const Vector3 & unitVec ) +inline const Matrix3 Matrix3::rotation(float radians, const Vector3 &unitVec) { - float x, y, z, s, c, oneMinusC, xy, yz, zx; - s = sinf( radians ); - c = cosf( radians ); - x = unitVec.getX(); - y = unitVec.getY(); - z = unitVec.getZ(); - xy = ( x * y ); - yz = ( y * z ); - zx = ( z * x ); - oneMinusC = ( 1.0f - c ); - return Matrix3( - Vector3( ( ( ( x * x ) * oneMinusC ) + c ), ( ( xy * oneMinusC ) + ( z * s ) ), ( ( zx * oneMinusC ) - ( y * s ) ) ), - Vector3( ( ( xy * oneMinusC ) - ( z * s ) ), ( ( ( y * y ) * oneMinusC ) + c ), ( ( yz * oneMinusC ) + ( x * s ) ) ), - Vector3( ( ( zx * oneMinusC ) + ( y * s ) ), ( ( yz * oneMinusC ) - ( x * s ) ), ( ( ( z * z ) * oneMinusC ) + c ) ) - ); + float x, y, z, s, c, oneMinusC, xy, yz, zx; + s = sinf(radians); + c = cosf(radians); + x = unitVec.getX(); + y = unitVec.getY(); + z = unitVec.getZ(); + xy = (x * y); + yz = (y * z); + zx = (z * x); + oneMinusC = (1.0f - c); + return Matrix3( + Vector3((((x * x) * oneMinusC) + c), ((xy * oneMinusC) + (z * s)), ((zx * oneMinusC) - (y * s))), + Vector3(((xy * oneMinusC) - (z * s)), (((y * y) * oneMinusC) + c), ((yz * oneMinusC) + (x * s))), + Vector3(((zx * oneMinusC) + (y * s)), ((yz * oneMinusC) - (x * s)), (((z * z) * oneMinusC) + c))); } -inline const Matrix3 Matrix3::rotation( const Quat & unitQuat ) +inline const Matrix3 Matrix3::rotation(const Quat &unitQuat) { - return Matrix3( unitQuat ); + return Matrix3(unitQuat); } -inline const Matrix3 Matrix3::scale( const Vector3 & scaleVec ) +inline const Matrix3 Matrix3::scale(const Vector3 &scaleVec) { - return Matrix3( - Vector3( scaleVec.getX(), 0.0f, 0.0f ), - Vector3( 0.0f, scaleVec.getY(), 0.0f ), - Vector3( 0.0f, 0.0f, scaleVec.getZ() ) - ); + return Matrix3( + Vector3(scaleVec.getX(), 0.0f, 0.0f), + Vector3(0.0f, scaleVec.getY(), 0.0f), + Vector3(0.0f, 0.0f, scaleVec.getZ())); } -inline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec ) +inline const Matrix3 appendScale(const Matrix3 &mat, const Vector3 &scaleVec) { - return Matrix3( - ( mat.getCol0() * scaleVec.getX( ) ), - ( mat.getCol1() * scaleVec.getY( ) ), - ( mat.getCol2() * scaleVec.getZ( ) ) - ); + return Matrix3( + (mat.getCol0() * scaleVec.getX()), + (mat.getCol1() * scaleVec.getY()), + (mat.getCol2() * scaleVec.getZ())); } -inline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat ) +inline const Matrix3 prependScale(const Vector3 &scaleVec, const Matrix3 &mat) { - return Matrix3( - mulPerElem( mat.getCol0(), scaleVec ), - mulPerElem( mat.getCol1(), scaleVec ), - mulPerElem( mat.getCol2(), scaleVec ) - ); + return Matrix3( + mulPerElem(mat.getCol0(), scaleVec), + mulPerElem(mat.getCol1(), scaleVec), + mulPerElem(mat.getCol2(), scaleVec)); } -inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ) +inline const Matrix3 select(const Matrix3 &mat0, const Matrix3 &mat1, bool select1) { - return Matrix3( - select( mat0.getCol0(), mat1.getCol0(), select1 ), - select( mat0.getCol1(), mat1.getCol1(), select1 ), - select( mat0.getCol2(), mat1.getCol2(), select1 ) - ); + return Matrix3( + select(mat0.getCol0(), mat1.getCol0(), select1), + select(mat0.getCol1(), mat1.getCol1(), select1), + select(mat0.getCol2(), mat1.getCol2(), select1)); } #ifdef _VECTORMATH_DEBUG -inline void print( const Matrix3 & mat ) +inline void print(const Matrix3 &mat) { - print( mat.getRow( 0 ) ); - print( mat.getRow( 1 ) ); - print( mat.getRow( 2 ) ); + print(mat.getRow(0)); + print(mat.getRow(1)); + print(mat.getRow(2)); } -inline void print( const Matrix3 & mat, const char * name ) +inline void print(const Matrix3 &mat, const char *name) { - printf("%s:\n", name); - print( mat ); + printf("%s:\n", name); + print(mat); } #endif -inline Matrix4::Matrix4( const Matrix4 & mat ) +inline Matrix4::Matrix4(const Matrix4 &mat) { - mCol0 = mat.mCol0; - mCol1 = mat.mCol1; - mCol2 = mat.mCol2; - mCol3 = mat.mCol3; + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + mCol3 = mat.mCol3; } -inline Matrix4::Matrix4( float scalar ) +inline Matrix4::Matrix4(float scalar) { - mCol0 = Vector4( scalar ); - mCol1 = Vector4( scalar ); - mCol2 = Vector4( scalar ); - mCol3 = Vector4( scalar ); + mCol0 = Vector4(scalar); + mCol1 = Vector4(scalar); + mCol2 = Vector4(scalar); + mCol3 = Vector4(scalar); } -inline Matrix4::Matrix4( const Transform3 & mat ) +inline Matrix4::Matrix4(const Transform3 &mat) { - mCol0 = Vector4( mat.getCol0(), 0.0f ); - mCol1 = Vector4( mat.getCol1(), 0.0f ); - mCol2 = Vector4( mat.getCol2(), 0.0f ); - mCol3 = Vector4( mat.getCol3(), 1.0f ); + mCol0 = Vector4(mat.getCol0(), 0.0f); + mCol1 = Vector4(mat.getCol1(), 0.0f); + mCol2 = Vector4(mat.getCol2(), 0.0f); + mCol3 = Vector4(mat.getCol3(), 1.0f); } -inline Matrix4::Matrix4( const Vector4 & _col0, const Vector4 & _col1, const Vector4 & _col2, const Vector4 & _col3 ) +inline Matrix4::Matrix4(const Vector4 &_col0, const Vector4 &_col1, const Vector4 &_col2, const Vector4 &_col3) { - mCol0 = _col0; - mCol1 = _col1; - mCol2 = _col2; - mCol3 = _col3; + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; + mCol3 = _col3; } -inline Matrix4::Matrix4( const Matrix3 & mat, const Vector3 & translateVec ) +inline Matrix4::Matrix4(const Matrix3 &mat, const Vector3 &translateVec) { - mCol0 = Vector4( mat.getCol0(), 0.0f ); - mCol1 = Vector4( mat.getCol1(), 0.0f ); - mCol2 = Vector4( mat.getCol2(), 0.0f ); - mCol3 = Vector4( translateVec, 1.0f ); + mCol0 = Vector4(mat.getCol0(), 0.0f); + mCol1 = Vector4(mat.getCol1(), 0.0f); + mCol2 = Vector4(mat.getCol2(), 0.0f); + mCol3 = Vector4(translateVec, 1.0f); } -inline Matrix4::Matrix4( const Quat & unitQuat, const Vector3 & translateVec ) +inline Matrix4::Matrix4(const Quat &unitQuat, const Vector3 &translateVec) { - Matrix3 mat; - mat = Matrix3( unitQuat ); - mCol0 = Vector4( mat.getCol0(), 0.0f ); - mCol1 = Vector4( mat.getCol1(), 0.0f ); - mCol2 = Vector4( mat.getCol2(), 0.0f ); - mCol3 = Vector4( translateVec, 1.0f ); + Matrix3 mat; + mat = Matrix3(unitQuat); + mCol0 = Vector4(mat.getCol0(), 0.0f); + mCol1 = Vector4(mat.getCol1(), 0.0f); + mCol2 = Vector4(mat.getCol2(), 0.0f); + mCol3 = Vector4(translateVec, 1.0f); } -inline Matrix4 & Matrix4::setCol0( const Vector4 & _col0 ) +inline Matrix4 &Matrix4::setCol0(const Vector4 &_col0) { - mCol0 = _col0; - return *this; + mCol0 = _col0; + return *this; } -inline Matrix4 & Matrix4::setCol1( const Vector4 & _col1 ) +inline Matrix4 &Matrix4::setCol1(const Vector4 &_col1) { - mCol1 = _col1; - return *this; + mCol1 = _col1; + return *this; } -inline Matrix4 & Matrix4::setCol2( const Vector4 & _col2 ) +inline Matrix4 &Matrix4::setCol2(const Vector4 &_col2) { - mCol2 = _col2; - return *this; + mCol2 = _col2; + return *this; } -inline Matrix4 & Matrix4::setCol3( const Vector4 & _col3 ) +inline Matrix4 &Matrix4::setCol3(const Vector4 &_col3) { - mCol3 = _col3; - return *this; + mCol3 = _col3; + return *this; } -inline Matrix4 & Matrix4::setCol( int col, const Vector4 & vec ) +inline Matrix4 &Matrix4::setCol(int col, const Vector4 &vec) { - *(&mCol0 + col) = vec; - return *this; + *(&mCol0 + col) = vec; + return *this; } -inline Matrix4 & Matrix4::setRow( int row, const Vector4 & vec ) +inline Matrix4 &Matrix4::setRow(int row, const Vector4 &vec) { - mCol0.setElem( row, vec.getElem( 0 ) ); - mCol1.setElem( row, vec.getElem( 1 ) ); - mCol2.setElem( row, vec.getElem( 2 ) ); - mCol3.setElem( row, vec.getElem( 3 ) ); - return *this; + mCol0.setElem(row, vec.getElem(0)); + mCol1.setElem(row, vec.getElem(1)); + mCol2.setElem(row, vec.getElem(2)); + mCol3.setElem(row, vec.getElem(3)); + return *this; } -inline Matrix4 & Matrix4::setElem( int col, int row, float val ) +inline Matrix4 &Matrix4::setElem(int col, int row, float val) { - Vector4 tmpV3_0; - tmpV3_0 = this->getCol( col ); - tmpV3_0.setElem( row, val ); - this->setCol( col, tmpV3_0 ); - return *this; + Vector4 tmpV3_0; + tmpV3_0 = this->getCol(col); + tmpV3_0.setElem(row, val); + this->setCol(col, tmpV3_0); + return *this; } -inline float Matrix4::getElem( int col, int row ) const +inline float Matrix4::getElem(int col, int row) const { - return this->getCol( col ).getElem( row ); + return this->getCol(col).getElem(row); } -inline const Vector4 Matrix4::getCol0( ) const +inline const Vector4 Matrix4::getCol0() const { - return mCol0; + return mCol0; } -inline const Vector4 Matrix4::getCol1( ) const +inline const Vector4 Matrix4::getCol1() const { - return mCol1; + return mCol1; } -inline const Vector4 Matrix4::getCol2( ) const +inline const Vector4 Matrix4::getCol2() const { - return mCol2; + return mCol2; } -inline const Vector4 Matrix4::getCol3( ) const +inline const Vector4 Matrix4::getCol3() const { - return mCol3; + return mCol3; } -inline const Vector4 Matrix4::getCol( int col ) const +inline const Vector4 Matrix4::getCol(int col) const { - return *(&mCol0 + col); + return *(&mCol0 + col); } -inline const Vector4 Matrix4::getRow( int row ) const +inline const Vector4 Matrix4::getRow(int row) const { - return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); + return Vector4(mCol0.getElem(row), mCol1.getElem(row), mCol2.getElem(row), mCol3.getElem(row)); } -inline Vector4 & Matrix4::operator []( int col ) +inline Vector4 &Matrix4::operator[](int col) { - return *(&mCol0 + col); + return *(&mCol0 + col); } -inline const Vector4 Matrix4::operator []( int col ) const +inline const Vector4 Matrix4::operator[](int col) const { - return *(&mCol0 + col); + return *(&mCol0 + col); } -inline Matrix4 & Matrix4::operator =( const Matrix4 & mat ) +inline Matrix4 &Matrix4::operator=(const Matrix4 &mat) { - mCol0 = mat.mCol0; - mCol1 = mat.mCol1; - mCol2 = mat.mCol2; - mCol3 = mat.mCol3; - return *this; + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + mCol3 = mat.mCol3; + return *this; } -inline const Matrix4 transpose( const Matrix4 & mat ) +inline const Matrix4 transpose(const Matrix4 &mat) { - return Matrix4( - Vector4( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX(), mat.getCol3().getX() ), - Vector4( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY(), mat.getCol3().getY() ), - Vector4( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ(), mat.getCol3().getZ() ), - Vector4( mat.getCol0().getW(), mat.getCol1().getW(), mat.getCol2().getW(), mat.getCol3().getW() ) - ); + return Matrix4( + Vector4(mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX(), mat.getCol3().getX()), + Vector4(mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY(), mat.getCol3().getY()), + Vector4(mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ(), mat.getCol3().getZ()), + Vector4(mat.getCol0().getW(), mat.getCol1().getW(), mat.getCol2().getW(), mat.getCol3().getW())); } -inline const Matrix4 inverse( const Matrix4 & mat ) +inline const Matrix4 inverse(const Matrix4 &mat) { - Vector4 res0, res1, res2, res3; - float mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, detInv; - mA = mat.getCol0().getX(); - mB = mat.getCol0().getY(); - mC = mat.getCol0().getZ(); - mD = mat.getCol0().getW(); - mE = mat.getCol1().getX(); - mF = mat.getCol1().getY(); - mG = mat.getCol1().getZ(); - mH = mat.getCol1().getW(); - mI = mat.getCol2().getX(); - mJ = mat.getCol2().getY(); - mK = mat.getCol2().getZ(); - mL = mat.getCol2().getW(); - mM = mat.getCol3().getX(); - mN = mat.getCol3().getY(); - mO = mat.getCol3().getZ(); - mP = mat.getCol3().getW(); - tmp0 = ( ( mK * mD ) - ( mC * mL ) ); - tmp1 = ( ( mO * mH ) - ( mG * mP ) ); - tmp2 = ( ( mB * mK ) - ( mJ * mC ) ); - tmp3 = ( ( mF * mO ) - ( mN * mG ) ); - tmp4 = ( ( mJ * mD ) - ( mB * mL ) ); - tmp5 = ( ( mN * mH ) - ( mF * mP ) ); - res0.setX( ( ( ( mJ * tmp1 ) - ( mL * tmp3 ) ) - ( mK * tmp5 ) ) ); - res0.setY( ( ( ( mN * tmp0 ) - ( mP * tmp2 ) ) - ( mO * tmp4 ) ) ); - res0.setZ( ( ( ( mD * tmp3 ) + ( mC * tmp5 ) ) - ( mB * tmp1 ) ) ); - res0.setW( ( ( ( mH * tmp2 ) + ( mG * tmp4 ) ) - ( mF * tmp0 ) ) ); - detInv = ( 1.0f / ( ( ( ( mA * res0.getX() ) + ( mE * res0.getY() ) ) + ( mI * res0.getZ() ) ) + ( mM * res0.getW() ) ) ); - res1.setX( ( mI * tmp1 ) ); - res1.setY( ( mM * tmp0 ) ); - res1.setZ( ( mA * tmp1 ) ); - res1.setW( ( mE * tmp0 ) ); - res3.setX( ( mI * tmp3 ) ); - res3.setY( ( mM * tmp2 ) ); - res3.setZ( ( mA * tmp3 ) ); - res3.setW( ( mE * tmp2 ) ); - res2.setX( ( mI * tmp5 ) ); - res2.setY( ( mM * tmp4 ) ); - res2.setZ( ( mA * tmp5 ) ); - res2.setW( ( mE * tmp4 ) ); - tmp0 = ( ( mI * mB ) - ( mA * mJ ) ); - tmp1 = ( ( mM * mF ) - ( mE * mN ) ); - tmp2 = ( ( mI * mD ) - ( mA * mL ) ); - tmp3 = ( ( mM * mH ) - ( mE * mP ) ); - tmp4 = ( ( mI * mC ) - ( mA * mK ) ); - tmp5 = ( ( mM * mG ) - ( mE * mO ) ); - res2.setX( ( ( ( mL * tmp1 ) - ( mJ * tmp3 ) ) + res2.getX() ) ); - res2.setY( ( ( ( mP * tmp0 ) - ( mN * tmp2 ) ) + res2.getY() ) ); - res2.setZ( ( ( ( mB * tmp3 ) - ( mD * tmp1 ) ) - res2.getZ() ) ); - res2.setW( ( ( ( mF * tmp2 ) - ( mH * tmp0 ) ) - res2.getW() ) ); - res3.setX( ( ( ( mJ * tmp5 ) - ( mK * tmp1 ) ) + res3.getX() ) ); - res3.setY( ( ( ( mN * tmp4 ) - ( mO * tmp0 ) ) + res3.getY() ) ); - res3.setZ( ( ( ( mC * tmp1 ) - ( mB * tmp5 ) ) - res3.getZ() ) ); - res3.setW( ( ( ( mG * tmp0 ) - ( mF * tmp4 ) ) - res3.getW() ) ); - res1.setX( ( ( ( mK * tmp3 ) - ( mL * tmp5 ) ) - res1.getX() ) ); - res1.setY( ( ( ( mO * tmp2 ) - ( mP * tmp4 ) ) - res1.getY() ) ); - res1.setZ( ( ( ( mD * tmp5 ) - ( mC * tmp3 ) ) + res1.getZ() ) ); - res1.setW( ( ( ( mH * tmp4 ) - ( mG * tmp2 ) ) + res1.getW() ) ); - return Matrix4( - ( res0 * detInv ), - ( res1 * detInv ), - ( res2 * detInv ), - ( res3 * detInv ) - ); + Vector4 res0, res1, res2, res3; + float mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, detInv; + mA = mat.getCol0().getX(); + mB = mat.getCol0().getY(); + mC = mat.getCol0().getZ(); + mD = mat.getCol0().getW(); + mE = mat.getCol1().getX(); + mF = mat.getCol1().getY(); + mG = mat.getCol1().getZ(); + mH = mat.getCol1().getW(); + mI = mat.getCol2().getX(); + mJ = mat.getCol2().getY(); + mK = mat.getCol2().getZ(); + mL = mat.getCol2().getW(); + mM = mat.getCol3().getX(); + mN = mat.getCol3().getY(); + mO = mat.getCol3().getZ(); + mP = mat.getCol3().getW(); + tmp0 = ((mK * mD) - (mC * mL)); + tmp1 = ((mO * mH) - (mG * mP)); + tmp2 = ((mB * mK) - (mJ * mC)); + tmp3 = ((mF * mO) - (mN * mG)); + tmp4 = ((mJ * mD) - (mB * mL)); + tmp5 = ((mN * mH) - (mF * mP)); + res0.setX((((mJ * tmp1) - (mL * tmp3)) - (mK * tmp5))); + res0.setY((((mN * tmp0) - (mP * tmp2)) - (mO * tmp4))); + res0.setZ((((mD * tmp3) + (mC * tmp5)) - (mB * tmp1))); + res0.setW((((mH * tmp2) + (mG * tmp4)) - (mF * tmp0))); + detInv = (1.0f / ((((mA * res0.getX()) + (mE * res0.getY())) + (mI * res0.getZ())) + (mM * res0.getW()))); + res1.setX((mI * tmp1)); + res1.setY((mM * tmp0)); + res1.setZ((mA * tmp1)); + res1.setW((mE * tmp0)); + res3.setX((mI * tmp3)); + res3.setY((mM * tmp2)); + res3.setZ((mA * tmp3)); + res3.setW((mE * tmp2)); + res2.setX((mI * tmp5)); + res2.setY((mM * tmp4)); + res2.setZ((mA * tmp5)); + res2.setW((mE * tmp4)); + tmp0 = ((mI * mB) - (mA * mJ)); + tmp1 = ((mM * mF) - (mE * mN)); + tmp2 = ((mI * mD) - (mA * mL)); + tmp3 = ((mM * mH) - (mE * mP)); + tmp4 = ((mI * mC) - (mA * mK)); + tmp5 = ((mM * mG) - (mE * mO)); + res2.setX((((mL * tmp1) - (mJ * tmp3)) + res2.getX())); + res2.setY((((mP * tmp0) - (mN * tmp2)) + res2.getY())); + res2.setZ((((mB * tmp3) - (mD * tmp1)) - res2.getZ())); + res2.setW((((mF * tmp2) - (mH * tmp0)) - res2.getW())); + res3.setX((((mJ * tmp5) - (mK * tmp1)) + res3.getX())); + res3.setY((((mN * tmp4) - (mO * tmp0)) + res3.getY())); + res3.setZ((((mC * tmp1) - (mB * tmp5)) - res3.getZ())); + res3.setW((((mG * tmp0) - (mF * tmp4)) - res3.getW())); + res1.setX((((mK * tmp3) - (mL * tmp5)) - res1.getX())); + res1.setY((((mO * tmp2) - (mP * tmp4)) - res1.getY())); + res1.setZ((((mD * tmp5) - (mC * tmp3)) + res1.getZ())); + res1.setW((((mH * tmp4) - (mG * tmp2)) + res1.getW())); + return Matrix4( + (res0 * detInv), + (res1 * detInv), + (res2 * detInv), + (res3 * detInv)); } -inline const Matrix4 affineInverse( const Matrix4 & mat ) +inline const Matrix4 affineInverse(const Matrix4 &mat) { - Transform3 affineMat; - affineMat.setCol0( mat.getCol0().getXYZ( ) ); - affineMat.setCol1( mat.getCol1().getXYZ( ) ); - affineMat.setCol2( mat.getCol2().getXYZ( ) ); - affineMat.setCol3( mat.getCol3().getXYZ( ) ); - return Matrix4( inverse( affineMat ) ); + Transform3 affineMat; + affineMat.setCol0(mat.getCol0().getXYZ()); + affineMat.setCol1(mat.getCol1().getXYZ()); + affineMat.setCol2(mat.getCol2().getXYZ()); + affineMat.setCol3(mat.getCol3().getXYZ()); + return Matrix4(inverse(affineMat)); } -inline const Matrix4 orthoInverse( const Matrix4 & mat ) +inline const Matrix4 orthoInverse(const Matrix4 &mat) { - Transform3 affineMat; - affineMat.setCol0( mat.getCol0().getXYZ( ) ); - affineMat.setCol1( mat.getCol1().getXYZ( ) ); - affineMat.setCol2( mat.getCol2().getXYZ( ) ); - affineMat.setCol3( mat.getCol3().getXYZ( ) ); - return Matrix4( orthoInverse( affineMat ) ); + Transform3 affineMat; + affineMat.setCol0(mat.getCol0().getXYZ()); + affineMat.setCol1(mat.getCol1().getXYZ()); + affineMat.setCol2(mat.getCol2().getXYZ()); + affineMat.setCol3(mat.getCol3().getXYZ()); + return Matrix4(orthoInverse(affineMat)); } -inline float determinant( const Matrix4 & mat ) +inline float determinant(const Matrix4 &mat) { - float dx, dy, dz, dw, mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; - mA = mat.getCol0().getX(); - mB = mat.getCol0().getY(); - mC = mat.getCol0().getZ(); - mD = mat.getCol0().getW(); - mE = mat.getCol1().getX(); - mF = mat.getCol1().getY(); - mG = mat.getCol1().getZ(); - mH = mat.getCol1().getW(); - mI = mat.getCol2().getX(); - mJ = mat.getCol2().getY(); - mK = mat.getCol2().getZ(); - mL = mat.getCol2().getW(); - mM = mat.getCol3().getX(); - mN = mat.getCol3().getY(); - mO = mat.getCol3().getZ(); - mP = mat.getCol3().getW(); - tmp0 = ( ( mK * mD ) - ( mC * mL ) ); - tmp1 = ( ( mO * mH ) - ( mG * mP ) ); - tmp2 = ( ( mB * mK ) - ( mJ * mC ) ); - tmp3 = ( ( mF * mO ) - ( mN * mG ) ); - tmp4 = ( ( mJ * mD ) - ( mB * mL ) ); - tmp5 = ( ( mN * mH ) - ( mF * mP ) ); - dx = ( ( ( mJ * tmp1 ) - ( mL * tmp3 ) ) - ( mK * tmp5 ) ); - dy = ( ( ( mN * tmp0 ) - ( mP * tmp2 ) ) - ( mO * tmp4 ) ); - dz = ( ( ( mD * tmp3 ) + ( mC * tmp5 ) ) - ( mB * tmp1 ) ); - dw = ( ( ( mH * tmp2 ) + ( mG * tmp4 ) ) - ( mF * tmp0 ) ); - return ( ( ( ( mA * dx ) + ( mE * dy ) ) + ( mI * dz ) ) + ( mM * dw ) ); + float dx, dy, dz, dw, mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; + mA = mat.getCol0().getX(); + mB = mat.getCol0().getY(); + mC = mat.getCol0().getZ(); + mD = mat.getCol0().getW(); + mE = mat.getCol1().getX(); + mF = mat.getCol1().getY(); + mG = mat.getCol1().getZ(); + mH = mat.getCol1().getW(); + mI = mat.getCol2().getX(); + mJ = mat.getCol2().getY(); + mK = mat.getCol2().getZ(); + mL = mat.getCol2().getW(); + mM = mat.getCol3().getX(); + mN = mat.getCol3().getY(); + mO = mat.getCol3().getZ(); + mP = mat.getCol3().getW(); + tmp0 = ((mK * mD) - (mC * mL)); + tmp1 = ((mO * mH) - (mG * mP)); + tmp2 = ((mB * mK) - (mJ * mC)); + tmp3 = ((mF * mO) - (mN * mG)); + tmp4 = ((mJ * mD) - (mB * mL)); + tmp5 = ((mN * mH) - (mF * mP)); + dx = (((mJ * tmp1) - (mL * tmp3)) - (mK * tmp5)); + dy = (((mN * tmp0) - (mP * tmp2)) - (mO * tmp4)); + dz = (((mD * tmp3) + (mC * tmp5)) - (mB * tmp1)); + dw = (((mH * tmp2) + (mG * tmp4)) - (mF * tmp0)); + return ((((mA * dx) + (mE * dy)) + (mI * dz)) + (mM * dw)); } -inline const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const +inline const Matrix4 Matrix4::operator+(const Matrix4 &mat) const { - return Matrix4( - ( mCol0 + mat.mCol0 ), - ( mCol1 + mat.mCol1 ), - ( mCol2 + mat.mCol2 ), - ( mCol3 + mat.mCol3 ) - ); + return Matrix4( + (mCol0 + mat.mCol0), + (mCol1 + mat.mCol1), + (mCol2 + mat.mCol2), + (mCol3 + mat.mCol3)); } -inline const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const +inline const Matrix4 Matrix4::operator-(const Matrix4 &mat) const { - return Matrix4( - ( mCol0 - mat.mCol0 ), - ( mCol1 - mat.mCol1 ), - ( mCol2 - mat.mCol2 ), - ( mCol3 - mat.mCol3 ) - ); + return Matrix4( + (mCol0 - mat.mCol0), + (mCol1 - mat.mCol1), + (mCol2 - mat.mCol2), + (mCol3 - mat.mCol3)); } -inline Matrix4 & Matrix4::operator +=( const Matrix4 & mat ) +inline Matrix4 &Matrix4::operator+=(const Matrix4 &mat) { - *this = *this + mat; - return *this; + *this = *this + mat; + return *this; } -inline Matrix4 & Matrix4::operator -=( const Matrix4 & mat ) +inline Matrix4 &Matrix4::operator-=(const Matrix4 &mat) { - *this = *this - mat; - return *this; + *this = *this - mat; + return *this; } -inline const Matrix4 Matrix4::operator -( ) const +inline const Matrix4 Matrix4::operator-() const { - return Matrix4( - ( -mCol0 ), - ( -mCol1 ), - ( -mCol2 ), - ( -mCol3 ) - ); + return Matrix4( + (-mCol0), + (-mCol1), + (-mCol2), + (-mCol3)); } -inline const Matrix4 absPerElem( const Matrix4 & mat ) +inline const Matrix4 absPerElem(const Matrix4 &mat) { - return Matrix4( - absPerElem( mat.getCol0() ), - absPerElem( mat.getCol1() ), - absPerElem( mat.getCol2() ), - absPerElem( mat.getCol3() ) - ); + return Matrix4( + absPerElem(mat.getCol0()), + absPerElem(mat.getCol1()), + absPerElem(mat.getCol2()), + absPerElem(mat.getCol3())); } -inline const Matrix4 Matrix4::operator *( float scalar ) const +inline const Matrix4 Matrix4::operator*(float scalar) const { - return Matrix4( - ( mCol0 * scalar ), - ( mCol1 * scalar ), - ( mCol2 * scalar ), - ( mCol3 * scalar ) - ); + return Matrix4( + (mCol0 * scalar), + (mCol1 * scalar), + (mCol2 * scalar), + (mCol3 * scalar)); } -inline Matrix4 & Matrix4::operator *=( float scalar ) +inline Matrix4 &Matrix4::operator*=(float scalar) { - *this = *this * scalar; - return *this; + *this = *this * scalar; + return *this; } -inline const Matrix4 operator *( float scalar, const Matrix4 & mat ) +inline const Matrix4 operator*(float scalar, const Matrix4 &mat) { - return mat * scalar; + return mat * scalar; } -inline const Vector4 Matrix4::operator *( const Vector4 & vec ) const +inline const Vector4 Matrix4::operator*(const Vector4 &vec) const { - return Vector4( - ( ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ) + ( mCol3.getX() * vec.getW() ) ), - ( ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ) + ( mCol3.getY() * vec.getW() ) ), - ( ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) + ( mCol3.getZ() * vec.getW() ) ), - ( ( ( ( mCol0.getW() * vec.getX() ) + ( mCol1.getW() * vec.getY() ) ) + ( mCol2.getW() * vec.getZ() ) ) + ( mCol3.getW() * vec.getW() ) ) - ); + return Vector4( + ((((mCol0.getX() * vec.getX()) + (mCol1.getX() * vec.getY())) + (mCol2.getX() * vec.getZ())) + (mCol3.getX() * vec.getW())), + ((((mCol0.getY() * vec.getX()) + (mCol1.getY() * vec.getY())) + (mCol2.getY() * vec.getZ())) + (mCol3.getY() * vec.getW())), + ((((mCol0.getZ() * vec.getX()) + (mCol1.getZ() * vec.getY())) + (mCol2.getZ() * vec.getZ())) + (mCol3.getZ() * vec.getW())), + ((((mCol0.getW() * vec.getX()) + (mCol1.getW() * vec.getY())) + (mCol2.getW() * vec.getZ())) + (mCol3.getW() * vec.getW()))); } -inline const Vector4 Matrix4::operator *( const Vector3 & vec ) const +inline const Vector4 Matrix4::operator*(const Vector3 &vec) const { - return Vector4( - ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), - ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), - ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ), - ( ( ( mCol0.getW() * vec.getX() ) + ( mCol1.getW() * vec.getY() ) ) + ( mCol2.getW() * vec.getZ() ) ) - ); + return Vector4( + (((mCol0.getX() * vec.getX()) + (mCol1.getX() * vec.getY())) + (mCol2.getX() * vec.getZ())), + (((mCol0.getY() * vec.getX()) + (mCol1.getY() * vec.getY())) + (mCol2.getY() * vec.getZ())), + (((mCol0.getZ() * vec.getX()) + (mCol1.getZ() * vec.getY())) + (mCol2.getZ() * vec.getZ())), + (((mCol0.getW() * vec.getX()) + (mCol1.getW() * vec.getY())) + (mCol2.getW() * vec.getZ()))); } -inline const Vector4 Matrix4::operator *( const Point3 & pnt ) const +inline const Vector4 Matrix4::operator*(const Point3 &pnt) const { - return Vector4( - ( ( ( ( mCol0.getX() * pnt.getX() ) + ( mCol1.getX() * pnt.getY() ) ) + ( mCol2.getX() * pnt.getZ() ) ) + mCol3.getX() ), - ( ( ( ( mCol0.getY() * pnt.getX() ) + ( mCol1.getY() * pnt.getY() ) ) + ( mCol2.getY() * pnt.getZ() ) ) + mCol3.getY() ), - ( ( ( ( mCol0.getZ() * pnt.getX() ) + ( mCol1.getZ() * pnt.getY() ) ) + ( mCol2.getZ() * pnt.getZ() ) ) + mCol3.getZ() ), - ( ( ( ( mCol0.getW() * pnt.getX() ) + ( mCol1.getW() * pnt.getY() ) ) + ( mCol2.getW() * pnt.getZ() ) ) + mCol3.getW() ) - ); + return Vector4( + ((((mCol0.getX() * pnt.getX()) + (mCol1.getX() * pnt.getY())) + (mCol2.getX() * pnt.getZ())) + mCol3.getX()), + ((((mCol0.getY() * pnt.getX()) + (mCol1.getY() * pnt.getY())) + (mCol2.getY() * pnt.getZ())) + mCol3.getY()), + ((((mCol0.getZ() * pnt.getX()) + (mCol1.getZ() * pnt.getY())) + (mCol2.getZ() * pnt.getZ())) + mCol3.getZ()), + ((((mCol0.getW() * pnt.getX()) + (mCol1.getW() * pnt.getY())) + (mCol2.getW() * pnt.getZ())) + mCol3.getW())); } -inline const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const +inline const Matrix4 Matrix4::operator*(const Matrix4 &mat) const { - return Matrix4( - ( *this * mat.mCol0 ), - ( *this * mat.mCol1 ), - ( *this * mat.mCol2 ), - ( *this * mat.mCol3 ) - ); + return Matrix4( + (*this * mat.mCol0), + (*this * mat.mCol1), + (*this * mat.mCol2), + (*this * mat.mCol3)); } -inline Matrix4 & Matrix4::operator *=( const Matrix4 & mat ) +inline Matrix4 &Matrix4::operator*=(const Matrix4 &mat) { - *this = *this * mat; - return *this; + *this = *this * mat; + return *this; } -inline const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const +inline const Matrix4 Matrix4::operator*(const Transform3 &tfrm) const { - return Matrix4( - ( *this * tfrm.getCol0() ), - ( *this * tfrm.getCol1() ), - ( *this * tfrm.getCol2() ), - ( *this * Point3( tfrm.getCol3() ) ) - ); + return Matrix4( + (*this * tfrm.getCol0()), + (*this * tfrm.getCol1()), + (*this * tfrm.getCol2()), + (*this * Point3(tfrm.getCol3()))); } -inline Matrix4 & Matrix4::operator *=( const Transform3 & tfrm ) +inline Matrix4 &Matrix4::operator*=(const Transform3 &tfrm) { - *this = *this * tfrm; - return *this; + *this = *this * tfrm; + return *this; } -inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ) +inline const Matrix4 mulPerElem(const Matrix4 &mat0, const Matrix4 &mat1) { - return Matrix4( - mulPerElem( mat0.getCol0(), mat1.getCol0() ), - mulPerElem( mat0.getCol1(), mat1.getCol1() ), - mulPerElem( mat0.getCol2(), mat1.getCol2() ), - mulPerElem( mat0.getCol3(), mat1.getCol3() ) - ); + return Matrix4( + mulPerElem(mat0.getCol0(), mat1.getCol0()), + mulPerElem(mat0.getCol1(), mat1.getCol1()), + mulPerElem(mat0.getCol2(), mat1.getCol2()), + mulPerElem(mat0.getCol3(), mat1.getCol3())); } -inline const Matrix4 Matrix4::identity( ) +inline const Matrix4 Matrix4::identity() { - return Matrix4( - Vector4::xAxis( ), - Vector4::yAxis( ), - Vector4::zAxis( ), - Vector4::wAxis( ) - ); + return Matrix4( + Vector4::xAxis(), + Vector4::yAxis(), + Vector4::zAxis(), + Vector4::wAxis()); } -inline Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 ) +inline Matrix4 &Matrix4::setUpper3x3(const Matrix3 &mat3) { - mCol0.setXYZ( mat3.getCol0() ); - mCol1.setXYZ( mat3.getCol1() ); - mCol2.setXYZ( mat3.getCol2() ); - return *this; + mCol0.setXYZ(mat3.getCol0()); + mCol1.setXYZ(mat3.getCol1()); + mCol2.setXYZ(mat3.getCol2()); + return *this; } -inline const Matrix3 Matrix4::getUpper3x3( ) const +inline const Matrix3 Matrix4::getUpper3x3() const { - return Matrix3( - mCol0.getXYZ( ), - mCol1.getXYZ( ), - mCol2.getXYZ( ) - ); + return Matrix3( + mCol0.getXYZ(), + mCol1.getXYZ(), + mCol2.getXYZ()); } -inline Matrix4 & Matrix4::setTranslation( const Vector3 & translateVec ) +inline Matrix4 &Matrix4::setTranslation(const Vector3 &translateVec) { - mCol3.setXYZ( translateVec ); - return *this; + mCol3.setXYZ(translateVec); + return *this; } -inline const Vector3 Matrix4::getTranslation( ) const +inline const Vector3 Matrix4::getTranslation() const { - return mCol3.getXYZ( ); + return mCol3.getXYZ(); } -inline const Matrix4 Matrix4::rotationX( float radians ) +inline const Matrix4 Matrix4::rotationX(float radians) { - float s, c; - s = sinf( radians ); - c = cosf( radians ); - return Matrix4( - Vector4::xAxis( ), - Vector4( 0.0f, c, s, 0.0f ), - Vector4( 0.0f, -s, c, 0.0f ), - Vector4::wAxis( ) - ); + float s, c; + s = sinf(radians); + c = cosf(radians); + return Matrix4( + Vector4::xAxis(), + Vector4(0.0f, c, s, 0.0f), + Vector4(0.0f, -s, c, 0.0f), + Vector4::wAxis()); } -inline const Matrix4 Matrix4::rotationY( float radians ) +inline const Matrix4 Matrix4::rotationY(float radians) { - float s, c; - s = sinf( radians ); - c = cosf( radians ); - return Matrix4( - Vector4( c, 0.0f, -s, 0.0f ), - Vector4::yAxis( ), - Vector4( s, 0.0f, c, 0.0f ), - Vector4::wAxis( ) - ); + float s, c; + s = sinf(radians); + c = cosf(radians); + return Matrix4( + Vector4(c, 0.0f, -s, 0.0f), + Vector4::yAxis(), + Vector4(s, 0.0f, c, 0.0f), + Vector4::wAxis()); } -inline const Matrix4 Matrix4::rotationZ( float radians ) +inline const Matrix4 Matrix4::rotationZ(float radians) { - float s, c; - s = sinf( radians ); - c = cosf( radians ); - return Matrix4( - Vector4( c, s, 0.0f, 0.0f ), - Vector4( -s, c, 0.0f, 0.0f ), - Vector4::zAxis( ), - Vector4::wAxis( ) - ); + float s, c; + s = sinf(radians); + c = cosf(radians); + return Matrix4( + Vector4(c, s, 0.0f, 0.0f), + Vector4(-s, c, 0.0f, 0.0f), + Vector4::zAxis(), + Vector4::wAxis()); } -inline const Matrix4 Matrix4::rotationZYX( const Vector3 & radiansXYZ ) +inline const Matrix4 Matrix4::rotationZYX(const Vector3 &radiansXYZ) { - float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; - sX = sinf( radiansXYZ.getX() ); - cX = cosf( radiansXYZ.getX() ); - sY = sinf( radiansXYZ.getY() ); - cY = cosf( radiansXYZ.getY() ); - sZ = sinf( radiansXYZ.getZ() ); - cZ = cosf( radiansXYZ.getZ() ); - tmp0 = ( cZ * sY ); - tmp1 = ( sZ * sY ); - return Matrix4( - Vector4( ( cZ * cY ), ( sZ * cY ), -sY, 0.0f ), - Vector4( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ), 0.0f ), - Vector4( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ), 0.0f ), - Vector4::wAxis( ) - ); + float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; + sX = sinf(radiansXYZ.getX()); + cX = cosf(radiansXYZ.getX()); + sY = sinf(radiansXYZ.getY()); + cY = cosf(radiansXYZ.getY()); + sZ = sinf(radiansXYZ.getZ()); + cZ = cosf(radiansXYZ.getZ()); + tmp0 = (cZ * sY); + tmp1 = (sZ * sY); + return Matrix4( + Vector4((cZ * cY), (sZ * cY), -sY, 0.0f), + Vector4(((tmp0 * sX) - (sZ * cX)), ((tmp1 * sX) + (cZ * cX)), (cY * sX), 0.0f), + Vector4(((tmp0 * cX) + (sZ * sX)), ((tmp1 * cX) - (cZ * sX)), (cY * cX), 0.0f), + Vector4::wAxis()); } -inline const Matrix4 Matrix4::rotation( float radians, const Vector3 & unitVec ) +inline const Matrix4 Matrix4::rotation(float radians, const Vector3 &unitVec) { - float x, y, z, s, c, oneMinusC, xy, yz, zx; - s = sinf( radians ); - c = cosf( radians ); - x = unitVec.getX(); - y = unitVec.getY(); - z = unitVec.getZ(); - xy = ( x * y ); - yz = ( y * z ); - zx = ( z * x ); - oneMinusC = ( 1.0f - c ); - return Matrix4( - Vector4( ( ( ( x * x ) * oneMinusC ) + c ), ( ( xy * oneMinusC ) + ( z * s ) ), ( ( zx * oneMinusC ) - ( y * s ) ), 0.0f ), - Vector4( ( ( xy * oneMinusC ) - ( z * s ) ), ( ( ( y * y ) * oneMinusC ) + c ), ( ( yz * oneMinusC ) + ( x * s ) ), 0.0f ), - Vector4( ( ( zx * oneMinusC ) + ( y * s ) ), ( ( yz * oneMinusC ) - ( x * s ) ), ( ( ( z * z ) * oneMinusC ) + c ), 0.0f ), - Vector4::wAxis( ) - ); + float x, y, z, s, c, oneMinusC, xy, yz, zx; + s = sinf(radians); + c = cosf(radians); + x = unitVec.getX(); + y = unitVec.getY(); + z = unitVec.getZ(); + xy = (x * y); + yz = (y * z); + zx = (z * x); + oneMinusC = (1.0f - c); + return Matrix4( + Vector4((((x * x) * oneMinusC) + c), ((xy * oneMinusC) + (z * s)), ((zx * oneMinusC) - (y * s)), 0.0f), + Vector4(((xy * oneMinusC) - (z * s)), (((y * y) * oneMinusC) + c), ((yz * oneMinusC) + (x * s)), 0.0f), + Vector4(((zx * oneMinusC) + (y * s)), ((yz * oneMinusC) - (x * s)), (((z * z) * oneMinusC) + c), 0.0f), + Vector4::wAxis()); } -inline const Matrix4 Matrix4::rotation( const Quat & unitQuat ) +inline const Matrix4 Matrix4::rotation(const Quat &unitQuat) { - return Matrix4( Transform3::rotation( unitQuat ) ); + return Matrix4(Transform3::rotation(unitQuat)); } -inline const Matrix4 Matrix4::scale( const Vector3 & scaleVec ) +inline const Matrix4 Matrix4::scale(const Vector3 &scaleVec) { - return Matrix4( - Vector4( scaleVec.getX(), 0.0f, 0.0f, 0.0f ), - Vector4( 0.0f, scaleVec.getY(), 0.0f, 0.0f ), - Vector4( 0.0f, 0.0f, scaleVec.getZ(), 0.0f ), - Vector4::wAxis( ) - ); + return Matrix4( + Vector4(scaleVec.getX(), 0.0f, 0.0f, 0.0f), + Vector4(0.0f, scaleVec.getY(), 0.0f, 0.0f), + Vector4(0.0f, 0.0f, scaleVec.getZ(), 0.0f), + Vector4::wAxis()); } -inline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec ) +inline const Matrix4 appendScale(const Matrix4 &mat, const Vector3 &scaleVec) { - return Matrix4( - ( mat.getCol0() * scaleVec.getX( ) ), - ( mat.getCol1() * scaleVec.getY( ) ), - ( mat.getCol2() * scaleVec.getZ( ) ), - mat.getCol3() - ); + return Matrix4( + (mat.getCol0() * scaleVec.getX()), + (mat.getCol1() * scaleVec.getY()), + (mat.getCol2() * scaleVec.getZ()), + mat.getCol3()); } -inline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat ) +inline const Matrix4 prependScale(const Vector3 &scaleVec, const Matrix4 &mat) { - Vector4 scale4; - scale4 = Vector4( scaleVec, 1.0f ); - return Matrix4( - mulPerElem( mat.getCol0(), scale4 ), - mulPerElem( mat.getCol1(), scale4 ), - mulPerElem( mat.getCol2(), scale4 ), - mulPerElem( mat.getCol3(), scale4 ) - ); + Vector4 scale4; + scale4 = Vector4(scaleVec, 1.0f); + return Matrix4( + mulPerElem(mat.getCol0(), scale4), + mulPerElem(mat.getCol1(), scale4), + mulPerElem(mat.getCol2(), scale4), + mulPerElem(mat.getCol3(), scale4)); } -inline const Matrix4 Matrix4::translation( const Vector3 & translateVec ) +inline const Matrix4 Matrix4::translation(const Vector3 &translateVec) { - return Matrix4( - Vector4::xAxis( ), - Vector4::yAxis( ), - Vector4::zAxis( ), - Vector4( translateVec, 1.0f ) - ); + return Matrix4( + Vector4::xAxis(), + Vector4::yAxis(), + Vector4::zAxis(), + Vector4(translateVec, 1.0f)); } -inline const Matrix4 Matrix4::lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec ) +inline const Matrix4 Matrix4::lookAt(const Point3 &eyePos, const Point3 &lookAtPos, const Vector3 &upVec) { - Matrix4 m4EyeFrame; - Vector3 v3X, v3Y, v3Z; - v3Y = normalize( upVec ); - v3Z = normalize( ( eyePos - lookAtPos ) ); - v3X = normalize( cross( v3Y, v3Z ) ); - v3Y = cross( v3Z, v3X ); - m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) ); - return orthoInverse( m4EyeFrame ); + Matrix4 m4EyeFrame; + Vector3 v3X, v3Y, v3Z; + v3Y = normalize(upVec); + v3Z = normalize((eyePos - lookAtPos)); + v3X = normalize(cross(v3Y, v3Z)); + v3Y = cross(v3Z, v3X); + m4EyeFrame = Matrix4(Vector4(v3X), Vector4(v3Y), Vector4(v3Z), Vector4(eyePos)); + return orthoInverse(m4EyeFrame); } -inline const Matrix4 Matrix4::perspective( float fovyRadians, float aspect, float zNear, float zFar ) +inline const Matrix4 Matrix4::perspective(float fovyRadians, float aspect, float zNear, float zFar) { - float f, rangeInv; - f = tanf( ( (float)( _VECTORMATH_PI_OVER_2 ) - ( 0.5f * fovyRadians ) ) ); - rangeInv = ( 1.0f / ( zNear - zFar ) ); - return Matrix4( - Vector4( ( f / aspect ), 0.0f, 0.0f, 0.0f ), - Vector4( 0.0f, f, 0.0f, 0.0f ), - Vector4( 0.0f, 0.0f, ( ( zNear + zFar ) * rangeInv ), -1.0f ), - Vector4( 0.0f, 0.0f, ( ( ( zNear * zFar ) * rangeInv ) * 2.0f ), 0.0f ) - ); + float f, rangeInv; + f = tanf(((float)(_VECTORMATH_PI_OVER_2) - (0.5f * fovyRadians))); + rangeInv = (1.0f / (zNear - zFar)); + return Matrix4( + Vector4((f / aspect), 0.0f, 0.0f, 0.0f), + Vector4(0.0f, f, 0.0f, 0.0f), + Vector4(0.0f, 0.0f, ((zNear + zFar) * rangeInv), -1.0f), + Vector4(0.0f, 0.0f, (((zNear * zFar) * rangeInv) * 2.0f), 0.0f)); } -inline const Matrix4 Matrix4::frustum( float left, float right, float bottom, float top, float zNear, float zFar ) +inline const Matrix4 Matrix4::frustum(float left, float right, float bottom, float top, float zNear, float zFar) { - float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf, n2; - sum_rl = ( right + left ); - sum_tb = ( top + bottom ); - sum_nf = ( zNear + zFar ); - inv_rl = ( 1.0f / ( right - left ) ); - inv_tb = ( 1.0f / ( top - bottom ) ); - inv_nf = ( 1.0f / ( zNear - zFar ) ); - n2 = ( zNear + zNear ); - return Matrix4( - Vector4( ( n2 * inv_rl ), 0.0f, 0.0f, 0.0f ), - Vector4( 0.0f, ( n2 * inv_tb ), 0.0f, 0.0f ), - Vector4( ( sum_rl * inv_rl ), ( sum_tb * inv_tb ), ( sum_nf * inv_nf ), -1.0f ), - Vector4( 0.0f, 0.0f, ( ( n2 * inv_nf ) * zFar ), 0.0f ) - ); + float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf, n2; + sum_rl = (right + left); + sum_tb = (top + bottom); + sum_nf = (zNear + zFar); + inv_rl = (1.0f / (right - left)); + inv_tb = (1.0f / (top - bottom)); + inv_nf = (1.0f / (zNear - zFar)); + n2 = (zNear + zNear); + return Matrix4( + Vector4((n2 * inv_rl), 0.0f, 0.0f, 0.0f), + Vector4(0.0f, (n2 * inv_tb), 0.0f, 0.0f), + Vector4((sum_rl * inv_rl), (sum_tb * inv_tb), (sum_nf * inv_nf), -1.0f), + Vector4(0.0f, 0.0f, ((n2 * inv_nf) * zFar), 0.0f)); } -inline const Matrix4 Matrix4::orthographic( float left, float right, float bottom, float top, float zNear, float zFar ) +inline const Matrix4 Matrix4::orthographic(float left, float right, float bottom, float top, float zNear, float zFar) { - float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf; - sum_rl = ( right + left ); - sum_tb = ( top + bottom ); - sum_nf = ( zNear + zFar ); - inv_rl = ( 1.0f / ( right - left ) ); - inv_tb = ( 1.0f / ( top - bottom ) ); - inv_nf = ( 1.0f / ( zNear - zFar ) ); - return Matrix4( - Vector4( ( inv_rl + inv_rl ), 0.0f, 0.0f, 0.0f ), - Vector4( 0.0f, ( inv_tb + inv_tb ), 0.0f, 0.0f ), - Vector4( 0.0f, 0.0f, ( inv_nf + inv_nf ), 0.0f ), - Vector4( ( -sum_rl * inv_rl ), ( -sum_tb * inv_tb ), ( sum_nf * inv_nf ), 1.0f ) - ); + float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf; + sum_rl = (right + left); + sum_tb = (top + bottom); + sum_nf = (zNear + zFar); + inv_rl = (1.0f / (right - left)); + inv_tb = (1.0f / (top - bottom)); + inv_nf = (1.0f / (zNear - zFar)); + return Matrix4( + Vector4((inv_rl + inv_rl), 0.0f, 0.0f, 0.0f), + Vector4(0.0f, (inv_tb + inv_tb), 0.0f, 0.0f), + Vector4(0.0f, 0.0f, (inv_nf + inv_nf), 0.0f), + Vector4((-sum_rl * inv_rl), (-sum_tb * inv_tb), (sum_nf * inv_nf), 1.0f)); } -inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ) +inline const Matrix4 select(const Matrix4 &mat0, const Matrix4 &mat1, bool select1) { - return Matrix4( - select( mat0.getCol0(), mat1.getCol0(), select1 ), - select( mat0.getCol1(), mat1.getCol1(), select1 ), - select( mat0.getCol2(), mat1.getCol2(), select1 ), - select( mat0.getCol3(), mat1.getCol3(), select1 ) - ); + return Matrix4( + select(mat0.getCol0(), mat1.getCol0(), select1), + select(mat0.getCol1(), mat1.getCol1(), select1), + select(mat0.getCol2(), mat1.getCol2(), select1), + select(mat0.getCol3(), mat1.getCol3(), select1)); } #ifdef _VECTORMATH_DEBUG -inline void print( const Matrix4 & mat ) +inline void print(const Matrix4 &mat) { - print( mat.getRow( 0 ) ); - print( mat.getRow( 1 ) ); - print( mat.getRow( 2 ) ); - print( mat.getRow( 3 ) ); + print(mat.getRow(0)); + print(mat.getRow(1)); + print(mat.getRow(2)); + print(mat.getRow(3)); } -inline void print( const Matrix4 & mat, const char * name ) +inline void print(const Matrix4 &mat, const char *name) { - printf("%s:\n", name); - print( mat ); + printf("%s:\n", name); + print(mat); } #endif -inline Transform3::Transform3( const Transform3 & tfrm ) +inline Transform3::Transform3(const Transform3 &tfrm) { - mCol0 = tfrm.mCol0; - mCol1 = tfrm.mCol1; - mCol2 = tfrm.mCol2; - mCol3 = tfrm.mCol3; + mCol0 = tfrm.mCol0; + mCol1 = tfrm.mCol1; + mCol2 = tfrm.mCol2; + mCol3 = tfrm.mCol3; } -inline Transform3::Transform3( float scalar ) +inline Transform3::Transform3(float scalar) { - mCol0 = Vector3( scalar ); - mCol1 = Vector3( scalar ); - mCol2 = Vector3( scalar ); - mCol3 = Vector3( scalar ); + mCol0 = Vector3(scalar); + mCol1 = Vector3(scalar); + mCol2 = Vector3(scalar); + mCol3 = Vector3(scalar); } -inline Transform3::Transform3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2, const Vector3 & _col3 ) +inline Transform3::Transform3(const Vector3 &_col0, const Vector3 &_col1, const Vector3 &_col2, const Vector3 &_col3) { - mCol0 = _col0; - mCol1 = _col1; - mCol2 = _col2; - mCol3 = _col3; + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; + mCol3 = _col3; } -inline Transform3::Transform3( const Matrix3 & tfrm, const Vector3 & translateVec ) +inline Transform3::Transform3(const Matrix3 &tfrm, const Vector3 &translateVec) { - this->setUpper3x3( tfrm ); - this->setTranslation( translateVec ); + this->setUpper3x3(tfrm); + this->setTranslation(translateVec); } -inline Transform3::Transform3( const Quat & unitQuat, const Vector3 & translateVec ) +inline Transform3::Transform3(const Quat &unitQuat, const Vector3 &translateVec) { - this->setUpper3x3( Matrix3( unitQuat ) ); - this->setTranslation( translateVec ); + this->setUpper3x3(Matrix3(unitQuat)); + this->setTranslation(translateVec); } -inline Transform3 & Transform3::setCol0( const Vector3 & _col0 ) +inline Transform3 &Transform3::setCol0(const Vector3 &_col0) { - mCol0 = _col0; - return *this; + mCol0 = _col0; + return *this; } -inline Transform3 & Transform3::setCol1( const Vector3 & _col1 ) +inline Transform3 &Transform3::setCol1(const Vector3 &_col1) { - mCol1 = _col1; - return *this; + mCol1 = _col1; + return *this; } -inline Transform3 & Transform3::setCol2( const Vector3 & _col2 ) +inline Transform3 &Transform3::setCol2(const Vector3 &_col2) { - mCol2 = _col2; - return *this; + mCol2 = _col2; + return *this; } -inline Transform3 & Transform3::setCol3( const Vector3 & _col3 ) +inline Transform3 &Transform3::setCol3(const Vector3 &_col3) { - mCol3 = _col3; - return *this; + mCol3 = _col3; + return *this; } -inline Transform3 & Transform3::setCol( int col, const Vector3 & vec ) +inline Transform3 &Transform3::setCol(int col, const Vector3 &vec) { - *(&mCol0 + col) = vec; - return *this; + *(&mCol0 + col) = vec; + return *this; } -inline Transform3 & Transform3::setRow( int row, const Vector4 & vec ) +inline Transform3 &Transform3::setRow(int row, const Vector4 &vec) { - mCol0.setElem( row, vec.getElem( 0 ) ); - mCol1.setElem( row, vec.getElem( 1 ) ); - mCol2.setElem( row, vec.getElem( 2 ) ); - mCol3.setElem( row, vec.getElem( 3 ) ); - return *this; + mCol0.setElem(row, vec.getElem(0)); + mCol1.setElem(row, vec.getElem(1)); + mCol2.setElem(row, vec.getElem(2)); + mCol3.setElem(row, vec.getElem(3)); + return *this; } -inline Transform3 & Transform3::setElem( int col, int row, float val ) +inline Transform3 &Transform3::setElem(int col, int row, float val) { - Vector3 tmpV3_0; - tmpV3_0 = this->getCol( col ); - tmpV3_0.setElem( row, val ); - this->setCol( col, tmpV3_0 ); - return *this; + Vector3 tmpV3_0; + tmpV3_0 = this->getCol(col); + tmpV3_0.setElem(row, val); + this->setCol(col, tmpV3_0); + return *this; } -inline float Transform3::getElem( int col, int row ) const +inline float Transform3::getElem(int col, int row) const { - return this->getCol( col ).getElem( row ); + return this->getCol(col).getElem(row); } -inline const Vector3 Transform3::getCol0( ) const +inline const Vector3 Transform3::getCol0() const { - return mCol0; + return mCol0; } -inline const Vector3 Transform3::getCol1( ) const +inline const Vector3 Transform3::getCol1() const { - return mCol1; + return mCol1; } -inline const Vector3 Transform3::getCol2( ) const +inline const Vector3 Transform3::getCol2() const { - return mCol2; + return mCol2; } -inline const Vector3 Transform3::getCol3( ) const +inline const Vector3 Transform3::getCol3() const { - return mCol3; + return mCol3; } -inline const Vector3 Transform3::getCol( int col ) const +inline const Vector3 Transform3::getCol(int col) const { - return *(&mCol0 + col); + return *(&mCol0 + col); } -inline const Vector4 Transform3::getRow( int row ) const +inline const Vector4 Transform3::getRow(int row) const { - return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); + return Vector4(mCol0.getElem(row), mCol1.getElem(row), mCol2.getElem(row), mCol3.getElem(row)); } -inline Vector3 & Transform3::operator []( int col ) +inline Vector3 &Transform3::operator[](int col) { - return *(&mCol0 + col); + return *(&mCol0 + col); } -inline const Vector3 Transform3::operator []( int col ) const +inline const Vector3 Transform3::operator[](int col) const { - return *(&mCol0 + col); + return *(&mCol0 + col); } -inline Transform3 & Transform3::operator =( const Transform3 & tfrm ) +inline Transform3 &Transform3::operator=(const Transform3 &tfrm) { - mCol0 = tfrm.mCol0; - mCol1 = tfrm.mCol1; - mCol2 = tfrm.mCol2; - mCol3 = tfrm.mCol3; - return *this; + mCol0 = tfrm.mCol0; + mCol1 = tfrm.mCol1; + mCol2 = tfrm.mCol2; + mCol3 = tfrm.mCol3; + return *this; } -inline const Transform3 inverse( const Transform3 & tfrm ) +inline const Transform3 inverse(const Transform3 &tfrm) { - Vector3 tmp0, tmp1, tmp2, inv0, inv1, inv2; - float detinv; - tmp0 = cross( tfrm.getCol1(), tfrm.getCol2() ); - tmp1 = cross( tfrm.getCol2(), tfrm.getCol0() ); - tmp2 = cross( tfrm.getCol0(), tfrm.getCol1() ); - detinv = ( 1.0f / dot( tfrm.getCol2(), tmp2 ) ); - inv0 = Vector3( ( tmp0.getX() * detinv ), ( tmp1.getX() * detinv ), ( tmp2.getX() * detinv ) ); - inv1 = Vector3( ( tmp0.getY() * detinv ), ( tmp1.getY() * detinv ), ( tmp2.getY() * detinv ) ); - inv2 = Vector3( ( tmp0.getZ() * detinv ), ( tmp1.getZ() * detinv ), ( tmp2.getZ() * detinv ) ); - return Transform3( - inv0, - inv1, - inv2, - Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) ) - ); + Vector3 tmp0, tmp1, tmp2, inv0, inv1, inv2; + float detinv; + tmp0 = cross(tfrm.getCol1(), tfrm.getCol2()); + tmp1 = cross(tfrm.getCol2(), tfrm.getCol0()); + tmp2 = cross(tfrm.getCol0(), tfrm.getCol1()); + detinv = (1.0f / dot(tfrm.getCol2(), tmp2)); + inv0 = Vector3((tmp0.getX() * detinv), (tmp1.getX() * detinv), (tmp2.getX() * detinv)); + inv1 = Vector3((tmp0.getY() * detinv), (tmp1.getY() * detinv), (tmp2.getY() * detinv)); + inv2 = Vector3((tmp0.getZ() * detinv), (tmp1.getZ() * detinv), (tmp2.getZ() * detinv)); + return Transform3( + inv0, + inv1, + inv2, + Vector3((-((inv0 * tfrm.getCol3().getX()) + ((inv1 * tfrm.getCol3().getY()) + (inv2 * tfrm.getCol3().getZ())))))); } -inline const Transform3 orthoInverse( const Transform3 & tfrm ) +inline const Transform3 orthoInverse(const Transform3 &tfrm) { - Vector3 inv0, inv1, inv2; - inv0 = Vector3( tfrm.getCol0().getX(), tfrm.getCol1().getX(), tfrm.getCol2().getX() ); - inv1 = Vector3( tfrm.getCol0().getY(), tfrm.getCol1().getY(), tfrm.getCol2().getY() ); - inv2 = Vector3( tfrm.getCol0().getZ(), tfrm.getCol1().getZ(), tfrm.getCol2().getZ() ); - return Transform3( - inv0, - inv1, - inv2, - Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) ) - ); + Vector3 inv0, inv1, inv2; + inv0 = Vector3(tfrm.getCol0().getX(), tfrm.getCol1().getX(), tfrm.getCol2().getX()); + inv1 = Vector3(tfrm.getCol0().getY(), tfrm.getCol1().getY(), tfrm.getCol2().getY()); + inv2 = Vector3(tfrm.getCol0().getZ(), tfrm.getCol1().getZ(), tfrm.getCol2().getZ()); + return Transform3( + inv0, + inv1, + inv2, + Vector3((-((inv0 * tfrm.getCol3().getX()) + ((inv1 * tfrm.getCol3().getY()) + (inv2 * tfrm.getCol3().getZ())))))); } -inline const Transform3 absPerElem( const Transform3 & tfrm ) +inline const Transform3 absPerElem(const Transform3 &tfrm) { - return Transform3( - absPerElem( tfrm.getCol0() ), - absPerElem( tfrm.getCol1() ), - absPerElem( tfrm.getCol2() ), - absPerElem( tfrm.getCol3() ) - ); + return Transform3( + absPerElem(tfrm.getCol0()), + absPerElem(tfrm.getCol1()), + absPerElem(tfrm.getCol2()), + absPerElem(tfrm.getCol3())); } -inline const Vector3 Transform3::operator *( const Vector3 & vec ) const +inline const Vector3 Transform3::operator*(const Vector3 &vec) const { - return Vector3( - ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), - ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), - ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) - ); + return Vector3( + (((mCol0.getX() * vec.getX()) + (mCol1.getX() * vec.getY())) + (mCol2.getX() * vec.getZ())), + (((mCol0.getY() * vec.getX()) + (mCol1.getY() * vec.getY())) + (mCol2.getY() * vec.getZ())), + (((mCol0.getZ() * vec.getX()) + (mCol1.getZ() * vec.getY())) + (mCol2.getZ() * vec.getZ()))); } -inline const Point3 Transform3::operator *( const Point3 & pnt ) const +inline const Point3 Transform3::operator*(const Point3 &pnt) const { - return Point3( - ( ( ( ( mCol0.getX() * pnt.getX() ) + ( mCol1.getX() * pnt.getY() ) ) + ( mCol2.getX() * pnt.getZ() ) ) + mCol3.getX() ), - ( ( ( ( mCol0.getY() * pnt.getX() ) + ( mCol1.getY() * pnt.getY() ) ) + ( mCol2.getY() * pnt.getZ() ) ) + mCol3.getY() ), - ( ( ( ( mCol0.getZ() * pnt.getX() ) + ( mCol1.getZ() * pnt.getY() ) ) + ( mCol2.getZ() * pnt.getZ() ) ) + mCol3.getZ() ) - ); + return Point3( + ((((mCol0.getX() * pnt.getX()) + (mCol1.getX() * pnt.getY())) + (mCol2.getX() * pnt.getZ())) + mCol3.getX()), + ((((mCol0.getY() * pnt.getX()) + (mCol1.getY() * pnt.getY())) + (mCol2.getY() * pnt.getZ())) + mCol3.getY()), + ((((mCol0.getZ() * pnt.getX()) + (mCol1.getZ() * pnt.getY())) + (mCol2.getZ() * pnt.getZ())) + mCol3.getZ())); } -inline const Transform3 Transform3::operator *( const Transform3 & tfrm ) const +inline const Transform3 Transform3::operator*(const Transform3 &tfrm) const { - return Transform3( - ( *this * tfrm.mCol0 ), - ( *this * tfrm.mCol1 ), - ( *this * tfrm.mCol2 ), - Vector3( ( *this * Point3( tfrm.mCol3 ) ) ) - ); + return Transform3( + (*this * tfrm.mCol0), + (*this * tfrm.mCol1), + (*this * tfrm.mCol2), + Vector3((*this * Point3(tfrm.mCol3)))); } -inline Transform3 & Transform3::operator *=( const Transform3 & tfrm ) +inline Transform3 &Transform3::operator*=(const Transform3 &tfrm) { - *this = *this * tfrm; - return *this; + *this = *this * tfrm; + return *this; } -inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ) +inline const Transform3 mulPerElem(const Transform3 &tfrm0, const Transform3 &tfrm1) { - return Transform3( - mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ), - mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ), - mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ), - mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() ) - ); + return Transform3( + mulPerElem(tfrm0.getCol0(), tfrm1.getCol0()), + mulPerElem(tfrm0.getCol1(), tfrm1.getCol1()), + mulPerElem(tfrm0.getCol2(), tfrm1.getCol2()), + mulPerElem(tfrm0.getCol3(), tfrm1.getCol3())); } -inline const Transform3 Transform3::identity( ) +inline const Transform3 Transform3::identity() { - return Transform3( - Vector3::xAxis( ), - Vector3::yAxis( ), - Vector3::zAxis( ), - Vector3( 0.0f ) - ); + return Transform3( + Vector3::xAxis(), + Vector3::yAxis(), + Vector3::zAxis(), + Vector3(0.0f)); } -inline Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm ) +inline Transform3 &Transform3::setUpper3x3(const Matrix3 &tfrm) { - mCol0 = tfrm.getCol0(); - mCol1 = tfrm.getCol1(); - mCol2 = tfrm.getCol2(); - return *this; + mCol0 = tfrm.getCol0(); + mCol1 = tfrm.getCol1(); + mCol2 = tfrm.getCol2(); + return *this; } -inline const Matrix3 Transform3::getUpper3x3( ) const +inline const Matrix3 Transform3::getUpper3x3() const { - return Matrix3( mCol0, mCol1, mCol2 ); + return Matrix3(mCol0, mCol1, mCol2); } -inline Transform3 & Transform3::setTranslation( const Vector3 & translateVec ) +inline Transform3 &Transform3::setTranslation(const Vector3 &translateVec) { - mCol3 = translateVec; - return *this; + mCol3 = translateVec; + return *this; } -inline const Vector3 Transform3::getTranslation( ) const +inline const Vector3 Transform3::getTranslation() const { - return mCol3; + return mCol3; } -inline const Transform3 Transform3::rotationX( float radians ) +inline const Transform3 Transform3::rotationX(float radians) { - float s, c; - s = sinf( radians ); - c = cosf( radians ); - return Transform3( - Vector3::xAxis( ), - Vector3( 0.0f, c, s ), - Vector3( 0.0f, -s, c ), - Vector3( 0.0f ) - ); + float s, c; + s = sinf(radians); + c = cosf(radians); + return Transform3( + Vector3::xAxis(), + Vector3(0.0f, c, s), + Vector3(0.0f, -s, c), + Vector3(0.0f)); } -inline const Transform3 Transform3::rotationY( float radians ) +inline const Transform3 Transform3::rotationY(float radians) { - float s, c; - s = sinf( radians ); - c = cosf( radians ); - return Transform3( - Vector3( c, 0.0f, -s ), - Vector3::yAxis( ), - Vector3( s, 0.0f, c ), - Vector3( 0.0f ) - ); + float s, c; + s = sinf(radians); + c = cosf(radians); + return Transform3( + Vector3(c, 0.0f, -s), + Vector3::yAxis(), + Vector3(s, 0.0f, c), + Vector3(0.0f)); } -inline const Transform3 Transform3::rotationZ( float radians ) +inline const Transform3 Transform3::rotationZ(float radians) { - float s, c; - s = sinf( radians ); - c = cosf( radians ); - return Transform3( - Vector3( c, s, 0.0f ), - Vector3( -s, c, 0.0f ), - Vector3::zAxis( ), - Vector3( 0.0f ) - ); + float s, c; + s = sinf(radians); + c = cosf(radians); + return Transform3( + Vector3(c, s, 0.0f), + Vector3(-s, c, 0.0f), + Vector3::zAxis(), + Vector3(0.0f)); } -inline const Transform3 Transform3::rotationZYX( const Vector3 & radiansXYZ ) +inline const Transform3 Transform3::rotationZYX(const Vector3 &radiansXYZ) { - float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; - sX = sinf( radiansXYZ.getX() ); - cX = cosf( radiansXYZ.getX() ); - sY = sinf( radiansXYZ.getY() ); - cY = cosf( radiansXYZ.getY() ); - sZ = sinf( radiansXYZ.getZ() ); - cZ = cosf( radiansXYZ.getZ() ); - tmp0 = ( cZ * sY ); - tmp1 = ( sZ * sY ); - return Transform3( - Vector3( ( cZ * cY ), ( sZ * cY ), -sY ), - Vector3( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ) ), - Vector3( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ) ), - Vector3( 0.0f ) - ); + float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; + sX = sinf(radiansXYZ.getX()); + cX = cosf(radiansXYZ.getX()); + sY = sinf(radiansXYZ.getY()); + cY = cosf(radiansXYZ.getY()); + sZ = sinf(radiansXYZ.getZ()); + cZ = cosf(radiansXYZ.getZ()); + tmp0 = (cZ * sY); + tmp1 = (sZ * sY); + return Transform3( + Vector3((cZ * cY), (sZ * cY), -sY), + Vector3(((tmp0 * sX) - (sZ * cX)), ((tmp1 * sX) + (cZ * cX)), (cY * sX)), + Vector3(((tmp0 * cX) + (sZ * sX)), ((tmp1 * cX) - (cZ * sX)), (cY * cX)), + Vector3(0.0f)); } -inline const Transform3 Transform3::rotation( float radians, const Vector3 & unitVec ) +inline const Transform3 Transform3::rotation(float radians, const Vector3 &unitVec) { - return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( 0.0f ) ); + return Transform3(Matrix3::rotation(radians, unitVec), Vector3(0.0f)); } -inline const Transform3 Transform3::rotation( const Quat & unitQuat ) +inline const Transform3 Transform3::rotation(const Quat &unitQuat) { - return Transform3( Matrix3( unitQuat ), Vector3( 0.0f ) ); + return Transform3(Matrix3(unitQuat), Vector3(0.0f)); } -inline const Transform3 Transform3::scale( const Vector3 & scaleVec ) +inline const Transform3 Transform3::scale(const Vector3 &scaleVec) { - return Transform3( - Vector3( scaleVec.getX(), 0.0f, 0.0f ), - Vector3( 0.0f, scaleVec.getY(), 0.0f ), - Vector3( 0.0f, 0.0f, scaleVec.getZ() ), - Vector3( 0.0f ) - ); + return Transform3( + Vector3(scaleVec.getX(), 0.0f, 0.0f), + Vector3(0.0f, scaleVec.getY(), 0.0f), + Vector3(0.0f, 0.0f, scaleVec.getZ()), + Vector3(0.0f)); } -inline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec ) +inline const Transform3 appendScale(const Transform3 &tfrm, const Vector3 &scaleVec) { - return Transform3( - ( tfrm.getCol0() * scaleVec.getX( ) ), - ( tfrm.getCol1() * scaleVec.getY( ) ), - ( tfrm.getCol2() * scaleVec.getZ( ) ), - tfrm.getCol3() - ); + return Transform3( + (tfrm.getCol0() * scaleVec.getX()), + (tfrm.getCol1() * scaleVec.getY()), + (tfrm.getCol2() * scaleVec.getZ()), + tfrm.getCol3()); } -inline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm ) +inline const Transform3 prependScale(const Vector3 &scaleVec, const Transform3 &tfrm) { - return Transform3( - mulPerElem( tfrm.getCol0(), scaleVec ), - mulPerElem( tfrm.getCol1(), scaleVec ), - mulPerElem( tfrm.getCol2(), scaleVec ), - mulPerElem( tfrm.getCol3(), scaleVec ) - ); + return Transform3( + mulPerElem(tfrm.getCol0(), scaleVec), + mulPerElem(tfrm.getCol1(), scaleVec), + mulPerElem(tfrm.getCol2(), scaleVec), + mulPerElem(tfrm.getCol3(), scaleVec)); } -inline const Transform3 Transform3::translation( const Vector3 & translateVec ) +inline const Transform3 Transform3::translation(const Vector3 &translateVec) { - return Transform3( - Vector3::xAxis( ), - Vector3::yAxis( ), - Vector3::zAxis( ), - translateVec - ); + return Transform3( + Vector3::xAxis(), + Vector3::yAxis(), + Vector3::zAxis(), + translateVec); } -inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ) +inline const Transform3 select(const Transform3 &tfrm0, const Transform3 &tfrm1, bool select1) { - return Transform3( - select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ), - select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ), - select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ), - select( tfrm0.getCol3(), tfrm1.getCol3(), select1 ) - ); + return Transform3( + select(tfrm0.getCol0(), tfrm1.getCol0(), select1), + select(tfrm0.getCol1(), tfrm1.getCol1(), select1), + select(tfrm0.getCol2(), tfrm1.getCol2(), select1), + select(tfrm0.getCol3(), tfrm1.getCol3(), select1)); } #ifdef _VECTORMATH_DEBUG -inline void print( const Transform3 & tfrm ) +inline void print(const Transform3 &tfrm) { - print( tfrm.getRow( 0 ) ); - print( tfrm.getRow( 1 ) ); - print( tfrm.getRow( 2 ) ); + print(tfrm.getRow(0)); + print(tfrm.getRow(1)); + print(tfrm.getRow(2)); } -inline void print( const Transform3 & tfrm, const char * name ) +inline void print(const Transform3 &tfrm, const char *name) { - printf("%s:\n", name); - print( tfrm ); + printf("%s:\n", name); + print(tfrm); } #endif -inline Quat::Quat( const Matrix3 & tfrm ) +inline Quat::Quat(const Matrix3 &tfrm) { - float trace, radicand, scale, xx, yx, zx, xy, yy, zy, xz, yz, zz, tmpx, tmpy, tmpz, tmpw, qx, qy, qz, qw; - int negTrace, ZgtX, ZgtY, YgtX; - int largestXorY, largestYorZ, largestZorX; + float trace, radicand, scale, xx, yx, zx, xy, yy, zy, xz, yz, zz, tmpx, tmpy, tmpz, tmpw, qx, qy, qz, qw; + int negTrace, ZgtX, ZgtY, YgtX; + int largestXorY, largestYorZ, largestZorX; - xx = tfrm.getCol0().getX(); - yx = tfrm.getCol0().getY(); - zx = tfrm.getCol0().getZ(); - xy = tfrm.getCol1().getX(); - yy = tfrm.getCol1().getY(); - zy = tfrm.getCol1().getZ(); - xz = tfrm.getCol2().getX(); - yz = tfrm.getCol2().getY(); - zz = tfrm.getCol2().getZ(); + xx = tfrm.getCol0().getX(); + yx = tfrm.getCol0().getY(); + zx = tfrm.getCol0().getZ(); + xy = tfrm.getCol1().getX(); + yy = tfrm.getCol1().getY(); + zy = tfrm.getCol1().getZ(); + xz = tfrm.getCol2().getX(); + yz = tfrm.getCol2().getY(); + zz = tfrm.getCol2().getZ(); - trace = ( ( xx + yy ) + zz ); + trace = ((xx + yy) + zz); - negTrace = ( trace < 0.0f ); - ZgtX = zz > xx; - ZgtY = zz > yy; - YgtX = yy > xx; - largestXorY = ( !ZgtX || !ZgtY ) && negTrace; - largestYorZ = ( YgtX || ZgtX ) && negTrace; - largestZorX = ( ZgtY || !YgtX ) && negTrace; - - if ( largestXorY ) - { - zz = -zz; - xy = -xy; - } - if ( largestYorZ ) - { - xx = -xx; - yz = -yz; - } - if ( largestZorX ) - { - yy = -yy; - zx = -zx; - } + negTrace = (trace < 0.0f); + ZgtX = zz > xx; + ZgtY = zz > yy; + YgtX = yy > xx; + largestXorY = (!ZgtX || !ZgtY) && negTrace; + largestYorZ = (YgtX || ZgtX) && negTrace; + largestZorX = (ZgtY || !YgtX) && negTrace; - radicand = ( ( ( xx + yy ) + zz ) + 1.0f ); - scale = ( 0.5f * ( 1.0f / sqrtf( radicand ) ) ); + if (largestXorY) + { + zz = -zz; + xy = -xy; + } + if (largestYorZ) + { + xx = -xx; + yz = -yz; + } + if (largestZorX) + { + yy = -yy; + zx = -zx; + } - tmpx = ( ( zy - yz ) * scale ); - tmpy = ( ( xz - zx ) * scale ); - tmpz = ( ( yx - xy ) * scale ); - tmpw = ( radicand * scale ); - qx = tmpx; - qy = tmpy; - qz = tmpz; - qw = tmpw; + radicand = (((xx + yy) + zz) + 1.0f); + scale = (0.5f * (1.0f / sqrtf(radicand))); - if ( largestXorY ) - { - qx = tmpw; - qy = tmpz; - qz = tmpy; - qw = tmpx; - } - if ( largestYorZ ) - { - tmpx = qx; - tmpz = qz; - qx = qy; - qy = tmpx; - qz = qw; - qw = tmpz; - } + tmpx = ((zy - yz) * scale); + tmpy = ((xz - zx) * scale); + tmpz = ((yx - xy) * scale); + tmpw = (radicand * scale); + qx = tmpx; + qy = tmpy; + qz = tmpz; + qw = tmpw; - mXYZW[0] = qx; - mXYZW[1] = qy; - mXYZW[2] = qz; - mXYZW[3] = qw; + if (largestXorY) + { + qx = tmpw; + qy = tmpz; + qz = tmpy; + qw = tmpx; + } + if (largestYorZ) + { + tmpx = qx; + tmpz = qz; + qx = qy; + qy = tmpx; + qz = qw; + qw = tmpz; + } + + mXYZW[0] = qx; + mXYZW[1] = qy; + mXYZW[2] = qz; + mXYZW[3] = qw; } -inline const Matrix3 outer( const Vector3 & tfrm0, const Vector3 & tfrm1 ) +inline const Matrix3 outer(const Vector3 &tfrm0, const Vector3 &tfrm1) { - return Matrix3( - ( tfrm0 * tfrm1.getX( ) ), - ( tfrm0 * tfrm1.getY( ) ), - ( tfrm0 * tfrm1.getZ( ) ) - ); + return Matrix3( + (tfrm0 * tfrm1.getX()), + (tfrm0 * tfrm1.getY()), + (tfrm0 * tfrm1.getZ())); } -inline const Matrix4 outer( const Vector4 & tfrm0, const Vector4 & tfrm1 ) +inline const Matrix4 outer(const Vector4 &tfrm0, const Vector4 &tfrm1) { - return Matrix4( - ( tfrm0 * tfrm1.getX( ) ), - ( tfrm0 * tfrm1.getY( ) ), - ( tfrm0 * tfrm1.getZ( ) ), - ( tfrm0 * tfrm1.getW( ) ) - ); + return Matrix4( + (tfrm0 * tfrm1.getX()), + (tfrm0 * tfrm1.getY()), + (tfrm0 * tfrm1.getZ()), + (tfrm0 * tfrm1.getW())); } -inline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat ) +inline const Vector3 rowMul(const Vector3 &vec, const Matrix3 &mat) { - return Vector3( - ( ( ( vec.getX() * mat.getCol0().getX() ) + ( vec.getY() * mat.getCol0().getY() ) ) + ( vec.getZ() * mat.getCol0().getZ() ) ), - ( ( ( vec.getX() * mat.getCol1().getX() ) + ( vec.getY() * mat.getCol1().getY() ) ) + ( vec.getZ() * mat.getCol1().getZ() ) ), - ( ( ( vec.getX() * mat.getCol2().getX() ) + ( vec.getY() * mat.getCol2().getY() ) ) + ( vec.getZ() * mat.getCol2().getZ() ) ) - ); + return Vector3( + (((vec.getX() * mat.getCol0().getX()) + (vec.getY() * mat.getCol0().getY())) + (vec.getZ() * mat.getCol0().getZ())), + (((vec.getX() * mat.getCol1().getX()) + (vec.getY() * mat.getCol1().getY())) + (vec.getZ() * mat.getCol1().getZ())), + (((vec.getX() * mat.getCol2().getX()) + (vec.getY() * mat.getCol2().getY())) + (vec.getZ() * mat.getCol2().getZ()))); } -inline const Matrix3 crossMatrix( const Vector3 & vec ) +inline const Matrix3 crossMatrix(const Vector3 &vec) { - return Matrix3( - Vector3( 0.0f, vec.getZ(), -vec.getY() ), - Vector3( -vec.getZ(), 0.0f, vec.getX() ), - Vector3( vec.getY(), -vec.getX(), 0.0f ) - ); + return Matrix3( + Vector3(0.0f, vec.getZ(), -vec.getY()), + Vector3(-vec.getZ(), 0.0f, vec.getX()), + Vector3(vec.getY(), -vec.getX(), 0.0f)); } -inline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat ) +inline const Matrix3 crossMatrixMul(const Vector3 &vec, const Matrix3 &mat) { - return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) ); + return Matrix3(cross(vec, mat.getCol0()), cross(vec, mat.getCol1()), cross(vec, mat.getCol2())); } -} // namespace Aos -} // namespace Vectormath +} // namespace Aos +} // namespace Vectormath #endif - diff --git a/test/Bullet2/vectormath/neon/quat_aos.h b/test/Bullet2/vectormath/neon/quat_aos.h index d06184603..ef3c8c131 100644 --- a/test/Bullet2/vectormath/neon/quat_aos.h +++ b/test/Bullet2/vectormath/neon/quat_aos.h @@ -25,389 +25,390 @@ subject to the following restrictions: #endif -namespace Vectormath { -namespace Aos { +namespace Vectormath +{ +namespace Aos +{ +inline Quat::Quat(const Quat &quat) +{ + vXYZW = quat.vXYZW; +} - inline Quat::Quat( const Quat & quat ) - { - vXYZW = quat.vXYZW; - } - - inline Quat::Quat( float _x, float _y, float _z, float _w ) - { - mXYZW[0] = _x; - mXYZW[1] = _y; - mXYZW[2] = _z; - mXYZW[3] = _w; - } - - inline Quat::Quat( float32x4_t fXYZW ) - { - vXYZW = fXYZW; - } - - inline Quat::Quat( const Vector3 & xyz, float _w ) - { - this->setXYZ( xyz ); - this->setW( _w ); - } - - inline Quat::Quat( const Vector4 & vec ) - { - mXYZW[0] = vec.getX(); - mXYZW[1] = vec.getY(); - mXYZW[2] = vec.getZ(); - mXYZW[3] = vec.getW(); - } - - inline Quat::Quat( float scalar ) - { - vXYZW = vdupq_n_f32(scalar); - } - - inline const Quat Quat::identity( ) - { - return Quat( 0.0f, 0.0f, 0.0f, 1.0f ); - } - - inline const Quat lerp( float t, const Quat & quat0, const Quat & quat1 ) - { - return ( quat0 + ( ( quat1 - quat0 ) * t ) ); - } - - inline const Quat slerp( float t, const Quat & unitQuat0, const Quat & unitQuat1 ) - { - Quat start; - float recipSinAngle, scale0, scale1, cosAngle, angle; - cosAngle = dot( unitQuat0, unitQuat1 ); - if ( cosAngle < 0.0f ) { - cosAngle = -cosAngle; - start = ( -unitQuat0 ); - } else { - start = unitQuat0; - } - if ( cosAngle < _VECTORMATH_SLERP_TOL ) { - angle = acosf( cosAngle ); - recipSinAngle = ( 1.0f / sinf( angle ) ); - scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); - scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); - } else { - scale0 = ( 1.0f - t ); - scale1 = t; - } - return ( ( start * scale0 ) + ( unitQuat1 * scale1 ) ); - } - - inline const Quat squad( float t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 ) - { - Quat tmp0, tmp1; - tmp0 = slerp( t, unitQuat0, unitQuat3 ); - tmp1 = slerp( t, unitQuat1, unitQuat2 ); - return slerp( ( ( 2.0f * t ) * ( 1.0f - t ) ), tmp0, tmp1 ); - } - - inline void loadXYZW( Quat & quat, const float * fptr ) - { - quat = Quat( fptr[0], fptr[1], fptr[2], fptr[3] ); - } - - inline void storeXYZW( const Quat & quat, float * fptr ) - { - vst1q_f32(fptr, quat.getvXYZW()); - } - - inline Quat & Quat::operator =( const Quat & quat ) - { - vXYZW = quat.getvXYZW(); - return *this; - } - - inline Quat & Quat::setXYZ( const Vector3 & vec ) - { - mXYZW[0] = vec.getX(); - mXYZW[1] = vec.getY(); - mXYZW[2] = vec.getZ(); - return *this; - } - - inline const Vector3 Quat::getXYZ( ) const - { - return Vector3( mXYZW[0], mXYZW[1], mXYZW[2] ); - } - - inline float32x4_t Quat::getvXYZW( ) const - { - return vXYZW; - } - - inline Quat & Quat::setX( float _x ) - { - mXYZW[0] = _x; - return *this; - } - - inline float Quat::getX( ) const - { - return mXYZW[0]; - } - - inline Quat & Quat::setY( float _y ) - { - mXYZW[1] = _y; - return *this; - } - - inline float Quat::getY( ) const - { - return mXYZW[1]; - } - - inline Quat & Quat::setZ( float _z ) - { - mXYZW[2] = _z; - return *this; - } - - inline float Quat::getZ( ) const - { - return mXYZW[2]; - } - - inline Quat & Quat::setW( float _w ) - { - mXYZW[3] = _w; - return *this; - } - - inline float Quat::getW( ) const - { - return mXYZW[3]; - } - - inline Quat & Quat::setElem( int idx, float value ) - { - *(&mXYZW[0] + idx) = value; - return *this; - } - - inline float Quat::getElem( int idx ) const - { - return *(&mXYZW[0] + idx); - } - - inline float & Quat::operator []( int idx ) - { - return *(&mXYZW[0] + idx); - } - - inline float Quat::operator []( int idx ) const - { - return *(&mXYZW[0] + idx); - } - - inline const Quat Quat::operator +( const Quat & quat ) const - { - return Quat( vaddq_f32(vXYZW, quat.vXYZW) ); - } - - inline const Quat Quat::operator -( const Quat & quat ) const - { - return Quat( vsubq_f32(vXYZW, quat.vXYZW) ); - } - - inline const Quat Quat::operator *( float scalar ) const - { - float32x4_t v_scalar = vdupq_n_f32(scalar); - return Quat( vmulq_f32(vXYZW, v_scalar) ); - } - - inline Quat & Quat::operator +=( const Quat & quat ) - { - *this = *this + quat; - return *this; - } - - inline Quat & Quat::operator -=( const Quat & quat ) - { - *this = *this - quat; - return *this; - } - - inline Quat & Quat::operator *=( float scalar ) - { - *this = *this * scalar; - return *this; - } - - inline const Quat Quat::operator /( float scalar ) const - { - return Quat( - ( mXYZW[0] / scalar ), - ( mXYZW[1] / scalar ), - ( mXYZW[2] / scalar ), - ( mXYZW[3] / scalar ) - ); - } - - inline Quat & Quat::operator /=( float scalar ) - { - *this = *this / scalar; - return *this; - } - - inline const Quat Quat::operator -( ) const - { - return Quat( vnegq_f32(vXYZW) ); - } - - inline const Quat operator *( float scalar, const Quat & quat ) - { - return quat * scalar; - } - - inline float dot( const Quat & quat0, const Quat & quat1 ) - { - float result; - result = ( quat0.getX() * quat1.getX() ); - result = ( result + ( quat0.getY() * quat1.getY() ) ); - result = ( result + ( quat0.getZ() * quat1.getZ() ) ); - result = ( result + ( quat0.getW() * quat1.getW() ) ); - return result; - } - - inline float norm( const Quat & quat ) - { - float result; - result = ( quat.getX() * quat.getX() ); - result = ( result + ( quat.getY() * quat.getY() ) ); - result = ( result + ( quat.getZ() * quat.getZ() ) ); - result = ( result + ( quat.getW() * quat.getW() ) ); - return result; - } - - inline float length( const Quat & quat ) - { - return ::sqrtf( norm( quat ) ); - } - - inline const Quat normalize( const Quat & quat ) - { - float lenSqr, lenInv; - lenSqr = norm( quat ); - lenInv = ( 1.0f / sqrtf( lenSqr ) ); - return Quat( - ( quat.getX() * lenInv ), - ( quat.getY() * lenInv ), - ( quat.getZ() * lenInv ), - ( quat.getW() * lenInv ) - ); - } - - inline const Quat Quat::rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 ) - { - float cosHalfAngleX2, recipCosHalfAngleX2; - cosHalfAngleX2 = sqrtf( ( 2.0f * ( 1.0f + dot( unitVec0, unitVec1 ) ) ) ); - recipCosHalfAngleX2 = ( 1.0f / cosHalfAngleX2 ); - return Quat( ( cross( unitVec0, unitVec1 ) * recipCosHalfAngleX2 ), ( cosHalfAngleX2 * 0.5f ) ); - } - - inline const Quat Quat::rotation( float radians, const Vector3 & unitVec ) - { - float s, c, angle; - angle = ( radians * 0.5f ); - s = sinf( angle ); - c = cosf( angle ); - return Quat( ( unitVec * s ), c ); - } - - inline const Quat Quat::rotationX( float radians ) - { - float s, c, angle; - angle = ( radians * 0.5f ); - s = sinf( angle ); - c = cosf( angle ); - return Quat( s, 0.0f, 0.0f, c ); - } - - inline const Quat Quat::rotationY( float radians ) - { - float s, c, angle; - angle = ( radians * 0.5f ); - s = sinf( angle ); - c = cosf( angle ); - return Quat( 0.0f, s, 0.0f, c ); - } - - inline const Quat Quat::rotationZ( float radians ) - { - float s, c, angle; - angle = ( radians * 0.5f ); - s = sinf( angle ); - c = cosf( angle ); - return Quat( 0.0f, 0.0f, s, c ); - } - - inline const Quat Quat::operator *( const Quat & quat ) const - { - return Quat( - ( ( ( ( mXYZW[3] * quat.mXYZW[0] ) + ( mXYZW[0] * quat.mXYZW[3] ) ) + ( mXYZW[1] * quat.mXYZW[2] ) ) - ( mXYZW[2] * quat.mXYZW[1] ) ), - ( ( ( ( mXYZW[3] * quat.mXYZW[1] ) + ( mXYZW[1] * quat.mXYZW[3] ) ) + ( mXYZW[2] * quat.mXYZW[0] ) ) - ( mXYZW[0] * quat.mXYZW[2] ) ), - ( ( ( ( mXYZW[3] * quat.mXYZW[2] ) + ( mXYZW[2] * quat.mXYZW[3] ) ) + ( mXYZW[0] * quat.mXYZW[1] ) ) - ( mXYZW[1] * quat.mXYZW[0] ) ), - ( ( ( ( mXYZW[3] * quat.mXYZW[3] ) - ( mXYZW[0] * quat.mXYZW[0] ) ) - ( mXYZW[1] * quat.mXYZW[1] ) ) - ( mXYZW[2] * quat.mXYZW[2] ) ) - ); - } - - inline Quat & Quat::operator *=( const Quat & quat ) - { - *this = *this * quat; - return *this; - } - - inline const Vector3 rotate( const Quat & quat, const Vector3 & vec ) - { - float tmpX, tmpY, tmpZ, tmpW; - tmpX = ( ( ( quat.getW() * vec.getX() ) + ( quat.getY() * vec.getZ() ) ) - ( quat.getZ() * vec.getY() ) ); - tmpY = ( ( ( quat.getW() * vec.getY() ) + ( quat.getZ() * vec.getX() ) ) - ( quat.getX() * vec.getZ() ) ); - tmpZ = ( ( ( quat.getW() * vec.getZ() ) + ( quat.getX() * vec.getY() ) ) - ( quat.getY() * vec.getX() ) ); - tmpW = ( ( ( quat.getX() * vec.getX() ) + ( quat.getY() * vec.getY() ) ) + ( quat.getZ() * vec.getZ() ) ); - return Vector3( - ( ( ( ( tmpW * quat.getX() ) + ( tmpX * quat.getW() ) ) - ( tmpY * quat.getZ() ) ) + ( tmpZ * quat.getY() ) ), - ( ( ( ( tmpW * quat.getY() ) + ( tmpY * quat.getW() ) ) - ( tmpZ * quat.getX() ) ) + ( tmpX * quat.getZ() ) ), - ( ( ( ( tmpW * quat.getZ() ) + ( tmpZ * quat.getW() ) ) - ( tmpX * quat.getY() ) ) + ( tmpY * quat.getX() ) ) - ); - } - - inline const Quat conj( const Quat & quat ) - { - return Quat( -quat.getX(), -quat.getY(), -quat.getZ(), quat.getW() ); - } - - inline const Quat select( const Quat & quat0, const Quat & quat1, bool select1 ) - { - return Quat( - ( select1 )? quat1.getX() : quat0.getX(), - ( select1 )? quat1.getY() : quat0.getY(), - ( select1 )? quat1.getZ() : quat0.getZ(), - ( select1 )? quat1.getW() : quat0.getW() - ); - } +inline Quat::Quat(float _x, float _y, float _z, float _w) +{ + mXYZW[0] = _x; + mXYZW[1] = _y; + mXYZW[2] = _z; + mXYZW[3] = _w; +} + +inline Quat::Quat(float32x4_t fXYZW) +{ + vXYZW = fXYZW; +} + +inline Quat::Quat(const Vector3 &xyz, float _w) +{ + this->setXYZ(xyz); + this->setW(_w); +} + +inline Quat::Quat(const Vector4 &vec) +{ + mXYZW[0] = vec.getX(); + mXYZW[1] = vec.getY(); + mXYZW[2] = vec.getZ(); + mXYZW[3] = vec.getW(); +} + +inline Quat::Quat(float scalar) +{ + vXYZW = vdupq_n_f32(scalar); +} + +inline const Quat Quat::identity() +{ + return Quat(0.0f, 0.0f, 0.0f, 1.0f); +} + +inline const Quat lerp(float t, const Quat &quat0, const Quat &quat1) +{ + return (quat0 + ((quat1 - quat0) * t)); +} + +inline const Quat slerp(float t, const Quat &unitQuat0, const Quat &unitQuat1) +{ + Quat start; + float recipSinAngle, scale0, scale1, cosAngle, angle; + cosAngle = dot(unitQuat0, unitQuat1); + if (cosAngle < 0.0f) + { + cosAngle = -cosAngle; + start = (-unitQuat0); + } + else + { + start = unitQuat0; + } + if (cosAngle < _VECTORMATH_SLERP_TOL) + { + angle = acosf(cosAngle); + recipSinAngle = (1.0f / sinf(angle)); + scale0 = (sinf(((1.0f - t) * angle)) * recipSinAngle); + scale1 = (sinf((t * angle)) * recipSinAngle); + } + else + { + scale0 = (1.0f - t); + scale1 = t; + } + return ((start * scale0) + (unitQuat1 * scale1)); +} + +inline const Quat squad(float t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3) +{ + Quat tmp0, tmp1; + tmp0 = slerp(t, unitQuat0, unitQuat3); + tmp1 = slerp(t, unitQuat1, unitQuat2); + return slerp(((2.0f * t) * (1.0f - t)), tmp0, tmp1); +} + +inline void loadXYZW(Quat &quat, const float *fptr) +{ + quat = Quat(fptr[0], fptr[1], fptr[2], fptr[3]); +} + +inline void storeXYZW(const Quat &quat, float *fptr) +{ + vst1q_f32(fptr, quat.getvXYZW()); +} + +inline Quat &Quat::operator=(const Quat &quat) +{ + vXYZW = quat.getvXYZW(); + return *this; +} + +inline Quat &Quat::setXYZ(const Vector3 &vec) +{ + mXYZW[0] = vec.getX(); + mXYZW[1] = vec.getY(); + mXYZW[2] = vec.getZ(); + return *this; +} + +inline const Vector3 Quat::getXYZ() const +{ + return Vector3(mXYZW[0], mXYZW[1], mXYZW[2]); +} + +inline float32x4_t Quat::getvXYZW() const +{ + return vXYZW; +} + +inline Quat &Quat::setX(float _x) +{ + mXYZW[0] = _x; + return *this; +} + +inline float Quat::getX() const +{ + return mXYZW[0]; +} + +inline Quat &Quat::setY(float _y) +{ + mXYZW[1] = _y; + return *this; +} + +inline float Quat::getY() const +{ + return mXYZW[1]; +} + +inline Quat &Quat::setZ(float _z) +{ + mXYZW[2] = _z; + return *this; +} + +inline float Quat::getZ() const +{ + return mXYZW[2]; +} + +inline Quat &Quat::setW(float _w) +{ + mXYZW[3] = _w; + return *this; +} + +inline float Quat::getW() const +{ + return mXYZW[3]; +} + +inline Quat &Quat::setElem(int idx, float value) +{ + *(&mXYZW[0] + idx) = value; + return *this; +} + +inline float Quat::getElem(int idx) const +{ + return *(&mXYZW[0] + idx); +} + +inline float &Quat::operator[](int idx) +{ + return *(&mXYZW[0] + idx); +} + +inline float Quat::operator[](int idx) const +{ + return *(&mXYZW[0] + idx); +} + +inline const Quat Quat::operator+(const Quat &quat) const +{ + return Quat(vaddq_f32(vXYZW, quat.vXYZW)); +} + +inline const Quat Quat::operator-(const Quat &quat) const +{ + return Quat(vsubq_f32(vXYZW, quat.vXYZW)); +} + +inline const Quat Quat::operator*(float scalar) const +{ + float32x4_t v_scalar = vdupq_n_f32(scalar); + return Quat(vmulq_f32(vXYZW, v_scalar)); +} + +inline Quat &Quat::operator+=(const Quat &quat) +{ + *this = *this + quat; + return *this; +} + +inline Quat &Quat::operator-=(const Quat &quat) +{ + *this = *this - quat; + return *this; +} + +inline Quat &Quat::operator*=(float scalar) +{ + *this = *this * scalar; + return *this; +} + +inline const Quat Quat::operator/(float scalar) const +{ + return Quat( + (mXYZW[0] / scalar), + (mXYZW[1] / scalar), + (mXYZW[2] / scalar), + (mXYZW[3] / scalar)); +} + +inline Quat &Quat::operator/=(float scalar) +{ + *this = *this / scalar; + return *this; +} + +inline const Quat Quat::operator-() const +{ + return Quat(vnegq_f32(vXYZW)); +} + +inline const Quat operator*(float scalar, const Quat &quat) +{ + return quat * scalar; +} + +inline float dot(const Quat &quat0, const Quat &quat1) +{ + float result; + result = (quat0.getX() * quat1.getX()); + result = (result + (quat0.getY() * quat1.getY())); + result = (result + (quat0.getZ() * quat1.getZ())); + result = (result + (quat0.getW() * quat1.getW())); + return result; +} + +inline float norm(const Quat &quat) +{ + float result; + result = (quat.getX() * quat.getX()); + result = (result + (quat.getY() * quat.getY())); + result = (result + (quat.getZ() * quat.getZ())); + result = (result + (quat.getW() * quat.getW())); + return result; +} + +inline float length(const Quat &quat) +{ + return ::sqrtf(norm(quat)); +} + +inline const Quat normalize(const Quat &quat) +{ + float lenSqr, lenInv; + lenSqr = norm(quat); + lenInv = (1.0f / sqrtf(lenSqr)); + return Quat( + (quat.getX() * lenInv), + (quat.getY() * lenInv), + (quat.getZ() * lenInv), + (quat.getW() * lenInv)); +} + +inline const Quat Quat::rotation(const Vector3 &unitVec0, const Vector3 &unitVec1) +{ + float cosHalfAngleX2, recipCosHalfAngleX2; + cosHalfAngleX2 = sqrtf((2.0f * (1.0f + dot(unitVec0, unitVec1)))); + recipCosHalfAngleX2 = (1.0f / cosHalfAngleX2); + return Quat((cross(unitVec0, unitVec1) * recipCosHalfAngleX2), (cosHalfAngleX2 * 0.5f)); +} + +inline const Quat Quat::rotation(float radians, const Vector3 &unitVec) +{ + float s, c, angle; + angle = (radians * 0.5f); + s = sinf(angle); + c = cosf(angle); + return Quat((unitVec * s), c); +} + +inline const Quat Quat::rotationX(float radians) +{ + float s, c, angle; + angle = (radians * 0.5f); + s = sinf(angle); + c = cosf(angle); + return Quat(s, 0.0f, 0.0f, c); +} + +inline const Quat Quat::rotationY(float radians) +{ + float s, c, angle; + angle = (radians * 0.5f); + s = sinf(angle); + c = cosf(angle); + return Quat(0.0f, s, 0.0f, c); +} + +inline const Quat Quat::rotationZ(float radians) +{ + float s, c, angle; + angle = (radians * 0.5f); + s = sinf(angle); + c = cosf(angle); + return Quat(0.0f, 0.0f, s, c); +} + +inline const Quat Quat::operator*(const Quat &quat) const +{ + return Quat( + ((((mXYZW[3] * quat.mXYZW[0]) + (mXYZW[0] * quat.mXYZW[3])) + (mXYZW[1] * quat.mXYZW[2])) - (mXYZW[2] * quat.mXYZW[1])), + ((((mXYZW[3] * quat.mXYZW[1]) + (mXYZW[1] * quat.mXYZW[3])) + (mXYZW[2] * quat.mXYZW[0])) - (mXYZW[0] * quat.mXYZW[2])), + ((((mXYZW[3] * quat.mXYZW[2]) + (mXYZW[2] * quat.mXYZW[3])) + (mXYZW[0] * quat.mXYZW[1])) - (mXYZW[1] * quat.mXYZW[0])), + ((((mXYZW[3] * quat.mXYZW[3]) - (mXYZW[0] * quat.mXYZW[0])) - (mXYZW[1] * quat.mXYZW[1])) - (mXYZW[2] * quat.mXYZW[2]))); +} + +inline Quat &Quat::operator*=(const Quat &quat) +{ + *this = *this * quat; + return *this; +} + +inline const Vector3 rotate(const Quat &quat, const Vector3 &vec) +{ + float tmpX, tmpY, tmpZ, tmpW; + tmpX = (((quat.getW() * vec.getX()) + (quat.getY() * vec.getZ())) - (quat.getZ() * vec.getY())); + tmpY = (((quat.getW() * vec.getY()) + (quat.getZ() * vec.getX())) - (quat.getX() * vec.getZ())); + tmpZ = (((quat.getW() * vec.getZ()) + (quat.getX() * vec.getY())) - (quat.getY() * vec.getX())); + tmpW = (((quat.getX() * vec.getX()) + (quat.getY() * vec.getY())) + (quat.getZ() * vec.getZ())); + return Vector3( + ((((tmpW * quat.getX()) + (tmpX * quat.getW())) - (tmpY * quat.getZ())) + (tmpZ * quat.getY())), + ((((tmpW * quat.getY()) + (tmpY * quat.getW())) - (tmpZ * quat.getX())) + (tmpX * quat.getZ())), + ((((tmpW * quat.getZ()) + (tmpZ * quat.getW())) - (tmpX * quat.getY())) + (tmpY * quat.getX()))); +} + +inline const Quat conj(const Quat &quat) +{ + return Quat(-quat.getX(), -quat.getY(), -quat.getZ(), quat.getW()); +} + +inline const Quat select(const Quat &quat0, const Quat &quat1, bool select1) +{ + return Quat( + (select1) ? quat1.getX() : quat0.getX(), + (select1) ? quat1.getY() : quat0.getY(), + (select1) ? quat1.getZ() : quat0.getZ(), + (select1) ? quat1.getW() : quat0.getW()); +} #ifdef _VECTORMATH_DEBUG -inline void print( const Quat & quat ) +inline void print(const Quat &quat) { - printf( "( %f %f %f %f )\n", quat.getX(), quat.getY(), quat.getZ(), quat.getW() ); + printf("( %f %f %f %f )\n", quat.getX(), quat.getY(), quat.getZ(), quat.getW()); } -inline void print( const Quat & quat, const char * name ) +inline void print(const Quat &quat, const char *name) { - printf( "%s: ( %f %f %f %f )\n", name, quat.getX(), quat.getY(), quat.getZ(), quat.getW() ); + printf("%s: ( %f %f %f %f )\n", name, quat.getX(), quat.getY(), quat.getZ(), quat.getW()); } #endif -} // namespace Aos -} // namespace Vectormath +} // namespace Aos +} // namespace Vectormath #endif - diff --git a/test/Bullet2/vectormath/neon/vec_aos.h b/test/Bullet2/vectormath/neon/vec_aos.h index 7bcf8dbec..bf80a3d11 100644 --- a/test/Bullet2/vectormath/neon/vec_aos.h +++ b/test/Bullet2/vectormath/neon/vec_aos.h @@ -30,1398 +30,1390 @@ subject to the following restrictions: #endif -namespace Vectormath { -namespace Aos { - -inline Vector3::Vector3( const Vector3 & vec ) +namespace Vectormath { - mX = vec.mX; - mY = vec.mY; - mZ = vec.mZ; +namespace Aos +{ +inline Vector3::Vector3(const Vector3 &vec) +{ + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; } -inline Vector3::Vector3( float _x, float _y, float _z ) +inline Vector3::Vector3(float _x, float _y, float _z) { - mX = _x; - mY = _y; - mZ = _z; + mX = _x; + mY = _y; + mZ = _z; } -inline Vector3::Vector3( const Point3 & pnt ) +inline Vector3::Vector3(const Point3 &pnt) { - mX = pnt.getX(); - mY = pnt.getY(); - mZ = pnt.getZ(); + mX = pnt.getX(); + mY = pnt.getY(); + mZ = pnt.getZ(); } -inline Vector3::Vector3( float scalar ) +inline Vector3::Vector3(float scalar) { - mX = scalar; - mY = scalar; - mZ = scalar; + mX = scalar; + mY = scalar; + mZ = scalar; } -inline const Vector3 Vector3::xAxis( ) +inline const Vector3 Vector3::xAxis() { - return Vector3( 1.0f, 0.0f, 0.0f ); + return Vector3(1.0f, 0.0f, 0.0f); } -inline const Vector3 Vector3::yAxis( ) +inline const Vector3 Vector3::yAxis() { - return Vector3( 0.0f, 1.0f, 0.0f ); + return Vector3(0.0f, 1.0f, 0.0f); } -inline const Vector3 Vector3::zAxis( ) +inline const Vector3 Vector3::zAxis() { - return Vector3( 0.0f, 0.0f, 1.0f ); + return Vector3(0.0f, 0.0f, 1.0f); } -inline const Vector3 lerp( float t, const Vector3 & vec0, const Vector3 & vec1 ) +inline const Vector3 lerp(float t, const Vector3 &vec0, const Vector3 &vec1) { - return ( vec0 + ( ( vec1 - vec0 ) * t ) ); + return (vec0 + ((vec1 - vec0) * t)); } -inline const Vector3 slerp( float t, const Vector3 & unitVec0, const Vector3 & unitVec1 ) +inline const Vector3 slerp(float t, const Vector3 &unitVec0, const Vector3 &unitVec1) { - float recipSinAngle, scale0, scale1, cosAngle, angle; - cosAngle = dot( unitVec0, unitVec1 ); - if ( cosAngle < _VECTORMATH_SLERP_TOL ) { - angle = acosf( cosAngle ); - recipSinAngle = ( 1.0f / sinf( angle ) ); - scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); - scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); - } else { - scale0 = ( 1.0f - t ); - scale1 = t; - } - return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) ); + float recipSinAngle, scale0, scale1, cosAngle, angle; + cosAngle = dot(unitVec0, unitVec1); + if (cosAngle < _VECTORMATH_SLERP_TOL) + { + angle = acosf(cosAngle); + recipSinAngle = (1.0f / sinf(angle)); + scale0 = (sinf(((1.0f - t) * angle)) * recipSinAngle); + scale1 = (sinf((t * angle)) * recipSinAngle); + } + else + { + scale0 = (1.0f - t); + scale1 = t; + } + return ((unitVec0 * scale0) + (unitVec1 * scale1)); } -inline void loadXYZ( Vector3 & vec, const float * fptr ) +inline void loadXYZ(Vector3 &vec, const float *fptr) { - vec = Vector3( fptr[0], fptr[1], fptr[2] ); + vec = Vector3(fptr[0], fptr[1], fptr[2]); } -inline void storeXYZ( const Vector3 & vec, float * fptr ) +inline void storeXYZ(const Vector3 &vec, float *fptr) { - fptr[0] = vec.getX(); - fptr[1] = vec.getY(); - fptr[2] = vec.getZ(); + fptr[0] = vec.getX(); + fptr[1] = vec.getY(); + fptr[2] = vec.getZ(); } -inline void loadHalfFloats( Vector3 & vec, const unsigned short * hfptr ) +inline void loadHalfFloats(Vector3 &vec, const unsigned short *hfptr) { - union Data32 { - unsigned int u32; - float f32; - }; + union Data32 { + unsigned int u32; + float f32; + }; - for (int i = 0; i < 3; i++) { - unsigned short fp16 = hfptr[i]; - unsigned int sign = fp16 >> 15; - unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); - unsigned int mantissa = fp16 & ((1 << 10) - 1); + for (int i = 0; i < 3; i++) + { + unsigned short fp16 = hfptr[i]; + unsigned int sign = fp16 >> 15; + unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); + unsigned int mantissa = fp16 & ((1 << 10) - 1); - if (exponent == 0) { - // zero - mantissa = 0; + if (exponent == 0) + { + // zero + mantissa = 0; + } + else if (exponent == 31) + { + // infinity or nan -> infinity + exponent = 255; + mantissa = 0; + } + else + { + exponent += 127 - 15; + mantissa <<= 13; + } - } else if (exponent == 31) { - // infinity or nan -> infinity - exponent = 255; - mantissa = 0; - - } else { - exponent += 127 - 15; - mantissa <<= 13; - } - - Data32 d; - d.u32 = (sign << 31) | (exponent << 23) | mantissa; - vec[i] = d.f32; - } + Data32 d; + d.u32 = (sign << 31) | (exponent << 23) | mantissa; + vec[i] = d.f32; + } } -inline void storeHalfFloats( const Vector3 & vec, unsigned short * hfptr ) +inline void storeHalfFloats(const Vector3 &vec, unsigned short *hfptr) { - union Data32 { - unsigned int u32; - float f32; - }; + union Data32 { + unsigned int u32; + float f32; + }; - for (int i = 0; i < 3; i++) { - Data32 d; - d.f32 = vec[i]; + for (int i = 0; i < 3; i++) + { + Data32 d; + d.f32 = vec[i]; - unsigned int sign = d.u32 >> 31; - unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); - unsigned int mantissa = d.u32 & ((1 << 23) - 1);; + unsigned int sign = d.u32 >> 31; + unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); + unsigned int mantissa = d.u32 & ((1 << 23) - 1); + ; - if (exponent == 0) { - // zero or denorm -> zero - mantissa = 0; + if (exponent == 0) + { + // zero or denorm -> zero + mantissa = 0; + } + else if (exponent == 255 && mantissa != 0) + { + // nan -> infinity + exponent = 31; + mantissa = 0; + } + else if (exponent >= 127 - 15 + 31) + { + // overflow or infinity -> infinity + exponent = 31; + mantissa = 0; + } + else if (exponent <= 127 - 15) + { + // underflow -> zero + exponent = 0; + mantissa = 0; + } + else + { + exponent -= 127 - 15; + mantissa >>= 13; + } - } else if (exponent == 255 && mantissa != 0) { - // nan -> infinity - exponent = 31; - mantissa = 0; - - } else if (exponent >= 127 - 15 + 31) { - // overflow or infinity -> infinity - exponent = 31; - mantissa = 0; - - } else if (exponent <= 127 - 15) { - // underflow -> zero - exponent = 0; - mantissa = 0; - - } else { - exponent -= 127 - 15; - mantissa >>= 13; - } - - hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); - } + hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); + } } -inline Vector3 & Vector3::operator =( const Vector3 & vec ) +inline Vector3 &Vector3::operator=(const Vector3 &vec) { - mX = vec.mX; - mY = vec.mY; - mZ = vec.mZ; - return *this; + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; + return *this; } -inline Vector3 & Vector3::setX( float _x ) +inline Vector3 &Vector3::setX(float _x) { - mX = _x; - return *this; + mX = _x; + return *this; } -inline float Vector3::getX( ) const +inline float Vector3::getX() const { - return mX; + return mX; } -inline Vector3 & Vector3::setY( float _y ) +inline Vector3 &Vector3::setY(float _y) { - mY = _y; - return *this; + mY = _y; + return *this; } -inline float Vector3::getY( ) const +inline float Vector3::getY() const { - return mY; + return mY; } -inline Vector3 & Vector3::setZ( float _z ) +inline Vector3 &Vector3::setZ(float _z) { - mZ = _z; - return *this; + mZ = _z; + return *this; } -inline float Vector3::getZ( ) const +inline float Vector3::getZ() const { - return mZ; + return mZ; } -inline Vector3 & Vector3::setElem( int idx, float value ) +inline Vector3 &Vector3::setElem(int idx, float value) { - *(&mX + idx) = value; - return *this; + *(&mX + idx) = value; + return *this; } -inline float Vector3::getElem( int idx ) const +inline float Vector3::getElem(int idx) const { - return *(&mX + idx); + return *(&mX + idx); } -inline float & Vector3::operator []( int idx ) +inline float &Vector3::operator[](int idx) { - return *(&mX + idx); + return *(&mX + idx); } -inline float Vector3::operator []( int idx ) const +inline float Vector3::operator[](int idx) const { - return *(&mX + idx); + return *(&mX + idx); } -inline const Vector3 Vector3::operator +( const Vector3 & vec ) const +inline const Vector3 Vector3::operator+(const Vector3 &vec) const { - return Vector3( - ( mX + vec.mX ), - ( mY + vec.mY ), - ( mZ + vec.mZ ) - ); + return Vector3( + (mX + vec.mX), + (mY + vec.mY), + (mZ + vec.mZ)); } -inline const Vector3 Vector3::operator -( const Vector3 & vec ) const +inline const Vector3 Vector3::operator-(const Vector3 &vec) const { - return Vector3( - ( mX - vec.mX ), - ( mY - vec.mY ), - ( mZ - vec.mZ ) - ); + return Vector3( + (mX - vec.mX), + (mY - vec.mY), + (mZ - vec.mZ)); } -inline const Point3 Vector3::operator +( const Point3 & pnt ) const +inline const Point3 Vector3::operator+(const Point3 &pnt) const { - return Point3( - ( mX + pnt.getX() ), - ( mY + pnt.getY() ), - ( mZ + pnt.getZ() ) - ); + return Point3( + (mX + pnt.getX()), + (mY + pnt.getY()), + (mZ + pnt.getZ())); } -inline const Vector3 Vector3::operator *( float scalar ) const +inline const Vector3 Vector3::operator*(float scalar) const { - return Vector3( - ( mX * scalar ), - ( mY * scalar ), - ( mZ * scalar ) - ); + return Vector3( + (mX * scalar), + (mY * scalar), + (mZ * scalar)); } -inline Vector3 & Vector3::operator +=( const Vector3 & vec ) +inline Vector3 &Vector3::operator+=(const Vector3 &vec) { - *this = *this + vec; - return *this; + *this = *this + vec; + return *this; } -inline Vector3 & Vector3::operator -=( const Vector3 & vec ) +inline Vector3 &Vector3::operator-=(const Vector3 &vec) { - *this = *this - vec; - return *this; + *this = *this - vec; + return *this; } -inline Vector3 & Vector3::operator *=( float scalar ) +inline Vector3 &Vector3::operator*=(float scalar) { - *this = *this * scalar; - return *this; + *this = *this * scalar; + return *this; } -inline const Vector3 Vector3::operator /( float scalar ) const +inline const Vector3 Vector3::operator/(float scalar) const { - return Vector3( - ( mX / scalar ), - ( mY / scalar ), - ( mZ / scalar ) - ); + return Vector3( + (mX / scalar), + (mY / scalar), + (mZ / scalar)); } -inline Vector3 & Vector3::operator /=( float scalar ) +inline Vector3 &Vector3::operator/=(float scalar) { - *this = *this / scalar; - return *this; + *this = *this / scalar; + return *this; } -inline const Vector3 Vector3::operator -( ) const +inline const Vector3 Vector3::operator-() const { - return Vector3( - -mX, - -mY, - -mZ - ); + return Vector3( + -mX, + -mY, + -mZ); } -inline const Vector3 operator *( float scalar, const Vector3 & vec ) +inline const Vector3 operator*(float scalar, const Vector3 &vec) { - return vec * scalar; + return vec * scalar; } -inline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +inline const Vector3 mulPerElem(const Vector3 &vec0, const Vector3 &vec1) { - return Vector3( - ( vec0.getX() * vec1.getX() ), - ( vec0.getY() * vec1.getY() ), - ( vec0.getZ() * vec1.getZ() ) - ); + return Vector3( + (vec0.getX() * vec1.getX()), + (vec0.getY() * vec1.getY()), + (vec0.getZ() * vec1.getZ())); } -inline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +inline const Vector3 divPerElem(const Vector3 &vec0, const Vector3 &vec1) { - return Vector3( - ( vec0.getX() / vec1.getX() ), - ( vec0.getY() / vec1.getY() ), - ( vec0.getZ() / vec1.getZ() ) - ); + return Vector3( + (vec0.getX() / vec1.getX()), + (vec0.getY() / vec1.getY()), + (vec0.getZ() / vec1.getZ())); } -inline const Vector3 recipPerElem( const Vector3 & vec ) +inline const Vector3 recipPerElem(const Vector3 &vec) { - return Vector3( - ( 1.0f / vec.getX() ), - ( 1.0f / vec.getY() ), - ( 1.0f / vec.getZ() ) - ); + return Vector3( + (1.0f / vec.getX()), + (1.0f / vec.getY()), + (1.0f / vec.getZ())); } -inline const Vector3 sqrtPerElem( const Vector3 & vec ) +inline const Vector3 sqrtPerElem(const Vector3 &vec) { - return Vector3( - sqrtf( vec.getX() ), - sqrtf( vec.getY() ), - sqrtf( vec.getZ() ) - ); + return Vector3( + sqrtf(vec.getX()), + sqrtf(vec.getY()), + sqrtf(vec.getZ())); } -inline const Vector3 rsqrtPerElem( const Vector3 & vec ) +inline const Vector3 rsqrtPerElem(const Vector3 &vec) { - return Vector3( - ( 1.0f / sqrtf( vec.getX() ) ), - ( 1.0f / sqrtf( vec.getY() ) ), - ( 1.0f / sqrtf( vec.getZ() ) ) - ); + return Vector3( + (1.0f / sqrtf(vec.getX())), + (1.0f / sqrtf(vec.getY())), + (1.0f / sqrtf(vec.getZ()))); } -inline const Vector3 absPerElem( const Vector3 & vec ) +inline const Vector3 absPerElem(const Vector3 &vec) { - return Vector3( - fabsf( vec.getX() ), - fabsf( vec.getY() ), - fabsf( vec.getZ() ) - ); + return Vector3( + fabsf(vec.getX()), + fabsf(vec.getY()), + fabsf(vec.getZ())); } -inline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +inline const Vector3 copySignPerElem(const Vector3 &vec0, const Vector3 &vec1) { - return Vector3( - ( vec1.getX() < 0.0f )? -fabsf( vec0.getX() ) : fabsf( vec0.getX() ), - ( vec1.getY() < 0.0f )? -fabsf( vec0.getY() ) : fabsf( vec0.getY() ), - ( vec1.getZ() < 0.0f )? -fabsf( vec0.getZ() ) : fabsf( vec0.getZ() ) - ); + return Vector3( + (vec1.getX() < 0.0f) ? -fabsf(vec0.getX()) : fabsf(vec0.getX()), + (vec1.getY() < 0.0f) ? -fabsf(vec0.getY()) : fabsf(vec0.getY()), + (vec1.getZ() < 0.0f) ? -fabsf(vec0.getZ()) : fabsf(vec0.getZ())); } -inline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +inline const Vector3 maxPerElem(const Vector3 &vec0, const Vector3 &vec1) { - return Vector3( - (vec0.getX() > vec1.getX())? vec0.getX() : vec1.getX(), - (vec0.getY() > vec1.getY())? vec0.getY() : vec1.getY(), - (vec0.getZ() > vec1.getZ())? vec0.getZ() : vec1.getZ() - ); + return Vector3( + (vec0.getX() > vec1.getX()) ? vec0.getX() : vec1.getX(), + (vec0.getY() > vec1.getY()) ? vec0.getY() : vec1.getY(), + (vec0.getZ() > vec1.getZ()) ? vec0.getZ() : vec1.getZ()); } -inline float maxElem( const Vector3 & vec ) +inline float maxElem(const Vector3 &vec) { - float result; - result = (vec.getX() > vec.getY())? vec.getX() : vec.getY(); - result = (vec.getZ() > result)? vec.getZ() : result; - return result; + float result; + result = (vec.getX() > vec.getY()) ? vec.getX() : vec.getY(); + result = (vec.getZ() > result) ? vec.getZ() : result; + return result; } -inline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +inline const Vector3 minPerElem(const Vector3 &vec0, const Vector3 &vec1) { - return Vector3( - (vec0.getX() < vec1.getX())? vec0.getX() : vec1.getX(), - (vec0.getY() < vec1.getY())? vec0.getY() : vec1.getY(), - (vec0.getZ() < vec1.getZ())? vec0.getZ() : vec1.getZ() - ); + return Vector3( + (vec0.getX() < vec1.getX()) ? vec0.getX() : vec1.getX(), + (vec0.getY() < vec1.getY()) ? vec0.getY() : vec1.getY(), + (vec0.getZ() < vec1.getZ()) ? vec0.getZ() : vec1.getZ()); } -inline float minElem( const Vector3 & vec ) +inline float minElem(const Vector3 &vec) { - float result; - result = (vec.getX() < vec.getY())? vec.getX() : vec.getY(); - result = (vec.getZ() < result)? vec.getZ() : result; - return result; + float result; + result = (vec.getX() < vec.getY()) ? vec.getX() : vec.getY(); + result = (vec.getZ() < result) ? vec.getZ() : result; + return result; } -inline float sum( const Vector3 & vec ) +inline float sum(const Vector3 &vec) { - float result; - result = ( vec.getX() + vec.getY() ); - result = ( result + vec.getZ() ); - return result; + float result; + result = (vec.getX() + vec.getY()); + result = (result + vec.getZ()); + return result; } -inline float dot( const Vector3 & vec0, const Vector3 & vec1 ) +inline float dot(const Vector3 &vec0, const Vector3 &vec1) { - float result; - result = ( vec0.getX() * vec1.getX() ); - result = ( result + ( vec0.getY() * vec1.getY() ) ); - result = ( result + ( vec0.getZ() * vec1.getZ() ) ); - return result; + float result; + result = (vec0.getX() * vec1.getX()); + result = (result + (vec0.getY() * vec1.getY())); + result = (result + (vec0.getZ() * vec1.getZ())); + return result; } -inline float lengthSqr( const Vector3 & vec ) +inline float lengthSqr(const Vector3 &vec) { - float result; - result = ( vec.getX() * vec.getX() ); - result = ( result + ( vec.getY() * vec.getY() ) ); - result = ( result + ( vec.getZ() * vec.getZ() ) ); - return result; + float result; + result = (vec.getX() * vec.getX()); + result = (result + (vec.getY() * vec.getY())); + result = (result + (vec.getZ() * vec.getZ())); + return result; } -inline float length( const Vector3 & vec ) +inline float length(const Vector3 &vec) { - return ::sqrtf( lengthSqr( vec ) ); + return ::sqrtf(lengthSqr(vec)); } -inline const Vector3 normalize( const Vector3 & vec ) +inline const Vector3 normalize(const Vector3 &vec) { - float lenSqr, lenInv; - lenSqr = lengthSqr( vec ); - lenInv = ( 1.0f / sqrtf( lenSqr ) ); - return Vector3( - ( vec.getX() * lenInv ), - ( vec.getY() * lenInv ), - ( vec.getZ() * lenInv ) - ); + float lenSqr, lenInv; + lenSqr = lengthSqr(vec); + lenInv = (1.0f / sqrtf(lenSqr)); + return Vector3( + (vec.getX() * lenInv), + (vec.getY() * lenInv), + (vec.getZ() * lenInv)); } -inline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 ) +inline const Vector3 cross(const Vector3 &vec0, const Vector3 &vec1) { - return Vector3( - ( ( vec0.getY() * vec1.getZ() ) - ( vec0.getZ() * vec1.getY() ) ), - ( ( vec0.getZ() * vec1.getX() ) - ( vec0.getX() * vec1.getZ() ) ), - ( ( vec0.getX() * vec1.getY() ) - ( vec0.getY() * vec1.getX() ) ) - ); + return Vector3( + ((vec0.getY() * vec1.getZ()) - (vec0.getZ() * vec1.getY())), + ((vec0.getZ() * vec1.getX()) - (vec0.getX() * vec1.getZ())), + ((vec0.getX() * vec1.getY()) - (vec0.getY() * vec1.getX()))); } -inline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, bool select1 ) +inline const Vector3 select(const Vector3 &vec0, const Vector3 &vec1, bool select1) { - return Vector3( - ( select1 )? vec1.getX() : vec0.getX(), - ( select1 )? vec1.getY() : vec0.getY(), - ( select1 )? vec1.getZ() : vec0.getZ() - ); + return Vector3( + (select1) ? vec1.getX() : vec0.getX(), + (select1) ? vec1.getY() : vec0.getY(), + (select1) ? vec1.getZ() : vec0.getZ()); } #ifdef _VECTORMATH_DEBUG -inline void print( const Vector3 & vec ) +inline void print(const Vector3 &vec) { - printf( "( %f %f %f )\n", vec.getX(), vec.getY(), vec.getZ() ); + printf("( %f %f %f )\n", vec.getX(), vec.getY(), vec.getZ()); } -inline void print( const Vector3 & vec, const char * name ) +inline void print(const Vector3 &vec, const char *name) { - printf( "%s: ( %f %f %f )\n", name, vec.getX(), vec.getY(), vec.getZ() ); + printf("%s: ( %f %f %f )\n", name, vec.getX(), vec.getY(), vec.getZ()); } #endif -inline Vector4::Vector4( const Vector4 & vec ) +inline Vector4::Vector4(const Vector4 &vec) { - mX = vec.mX; - mY = vec.mY; - mZ = vec.mZ; - mW = vec.mW; + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; + mW = vec.mW; } -inline Vector4::Vector4( float _x, float _y, float _z, float _w ) +inline Vector4::Vector4(float _x, float _y, float _z, float _w) { - mX = _x; - mY = _y; - mZ = _z; - mW = _w; + mX = _x; + mY = _y; + mZ = _z; + mW = _w; } -inline Vector4::Vector4( const Vector3 & xyz, float _w ) +inline Vector4::Vector4(const Vector3 &xyz, float _w) { - this->setXYZ( xyz ); - this->setW( _w ); + this->setXYZ(xyz); + this->setW(_w); } -inline Vector4::Vector4( const Vector3 & vec ) +inline Vector4::Vector4(const Vector3 &vec) { - mX = vec.getX(); - mY = vec.getY(); - mZ = vec.getZ(); - mW = 0.0f; + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + mW = 0.0f; } -inline Vector4::Vector4( const Point3 & pnt ) +inline Vector4::Vector4(const Point3 &pnt) { - mX = pnt.getX(); - mY = pnt.getY(); - mZ = pnt.getZ(); - mW = 1.0f; + mX = pnt.getX(); + mY = pnt.getY(); + mZ = pnt.getZ(); + mW = 1.0f; } -inline Vector4::Vector4( const Quat & quat ) +inline Vector4::Vector4(const Quat &quat) { - mX = quat.getX(); - mY = quat.getY(); - mZ = quat.getZ(); - mW = quat.getW(); + mX = quat.getX(); + mY = quat.getY(); + mZ = quat.getZ(); + mW = quat.getW(); } -inline Vector4::Vector4( float scalar ) +inline Vector4::Vector4(float scalar) { - mX = scalar; - mY = scalar; - mZ = scalar; - mW = scalar; + mX = scalar; + mY = scalar; + mZ = scalar; + mW = scalar; } -inline const Vector4 Vector4::xAxis( ) +inline const Vector4 Vector4::xAxis() { - return Vector4( 1.0f, 0.0f, 0.0f, 0.0f ); + return Vector4(1.0f, 0.0f, 0.0f, 0.0f); } -inline const Vector4 Vector4::yAxis( ) +inline const Vector4 Vector4::yAxis() { - return Vector4( 0.0f, 1.0f, 0.0f, 0.0f ); + return Vector4(0.0f, 1.0f, 0.0f, 0.0f); } -inline const Vector4 Vector4::zAxis( ) +inline const Vector4 Vector4::zAxis() { - return Vector4( 0.0f, 0.0f, 1.0f, 0.0f ); + return Vector4(0.0f, 0.0f, 1.0f, 0.0f); } -inline const Vector4 Vector4::wAxis( ) +inline const Vector4 Vector4::wAxis() { - return Vector4( 0.0f, 0.0f, 0.0f, 1.0f ); + return Vector4(0.0f, 0.0f, 0.0f, 1.0f); } -inline const Vector4 lerp( float t, const Vector4 & vec0, const Vector4 & vec1 ) +inline const Vector4 lerp(float t, const Vector4 &vec0, const Vector4 &vec1) { - return ( vec0 + ( ( vec1 - vec0 ) * t ) ); + return (vec0 + ((vec1 - vec0) * t)); } -inline const Vector4 slerp( float t, const Vector4 & unitVec0, const Vector4 & unitVec1 ) +inline const Vector4 slerp(float t, const Vector4 &unitVec0, const Vector4 &unitVec1) { - float recipSinAngle, scale0, scale1, cosAngle, angle; - cosAngle = dot( unitVec0, unitVec1 ); - if ( cosAngle < _VECTORMATH_SLERP_TOL ) { - angle = acosf( cosAngle ); - recipSinAngle = ( 1.0f / sinf( angle ) ); - scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); - scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); - } else { - scale0 = ( 1.0f - t ); - scale1 = t; - } - return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) ); + float recipSinAngle, scale0, scale1, cosAngle, angle; + cosAngle = dot(unitVec0, unitVec1); + if (cosAngle < _VECTORMATH_SLERP_TOL) + { + angle = acosf(cosAngle); + recipSinAngle = (1.0f / sinf(angle)); + scale0 = (sinf(((1.0f - t) * angle)) * recipSinAngle); + scale1 = (sinf((t * angle)) * recipSinAngle); + } + else + { + scale0 = (1.0f - t); + scale1 = t; + } + return ((unitVec0 * scale0) + (unitVec1 * scale1)); } -inline void loadXYZW( Vector4 & vec, const float * fptr ) +inline void loadXYZW(Vector4 &vec, const float *fptr) { - vec = Vector4( fptr[0], fptr[1], fptr[2], fptr[3] ); + vec = Vector4(fptr[0], fptr[1], fptr[2], fptr[3]); } -inline void storeXYZW( const Vector4 & vec, float * fptr ) +inline void storeXYZW(const Vector4 &vec, float *fptr) { - fptr[0] = vec.getX(); - fptr[1] = vec.getY(); - fptr[2] = vec.getZ(); - fptr[3] = vec.getW(); + fptr[0] = vec.getX(); + fptr[1] = vec.getY(); + fptr[2] = vec.getZ(); + fptr[3] = vec.getW(); } -inline void loadHalfFloats( Vector4 & vec, const unsigned short * hfptr ) +inline void loadHalfFloats(Vector4 &vec, const unsigned short *hfptr) { - union Data32 { - unsigned int u32; - float f32; - }; + union Data32 { + unsigned int u32; + float f32; + }; - for (int i = 0; i < 4; i++) { - unsigned short fp16 = hfptr[i]; - unsigned int sign = fp16 >> 15; - unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); - unsigned int mantissa = fp16 & ((1 << 10) - 1); + for (int i = 0; i < 4; i++) + { + unsigned short fp16 = hfptr[i]; + unsigned int sign = fp16 >> 15; + unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); + unsigned int mantissa = fp16 & ((1 << 10) - 1); - if (exponent == 0) { - // zero - mantissa = 0; + if (exponent == 0) + { + // zero + mantissa = 0; + } + else if (exponent == 31) + { + // infinity or nan -> infinity + exponent = 255; + mantissa = 0; + } + else + { + exponent += 127 - 15; + mantissa <<= 13; + } - } else if (exponent == 31) { - // infinity or nan -> infinity - exponent = 255; - mantissa = 0; - - } else { - exponent += 127 - 15; - mantissa <<= 13; - } - - Data32 d; - d.u32 = (sign << 31) | (exponent << 23) | mantissa; - vec[i] = d.f32; - } + Data32 d; + d.u32 = (sign << 31) | (exponent << 23) | mantissa; + vec[i] = d.f32; + } } -inline void storeHalfFloats( const Vector4 & vec, unsigned short * hfptr ) +inline void storeHalfFloats(const Vector4 &vec, unsigned short *hfptr) { - union Data32 { - unsigned int u32; - float f32; - }; + union Data32 { + unsigned int u32; + float f32; + }; - for (int i = 0; i < 4; i++) { - Data32 d; - d.f32 = vec[i]; + for (int i = 0; i < 4; i++) + { + Data32 d; + d.f32 = vec[i]; - unsigned int sign = d.u32 >> 31; - unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); - unsigned int mantissa = d.u32 & ((1 << 23) - 1);; + unsigned int sign = d.u32 >> 31; + unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); + unsigned int mantissa = d.u32 & ((1 << 23) - 1); + ; - if (exponent == 0) { - // zero or denorm -> zero - mantissa = 0; + if (exponent == 0) + { + // zero or denorm -> zero + mantissa = 0; + } + else if (exponent == 255 && mantissa != 0) + { + // nan -> infinity + exponent = 31; + mantissa = 0; + } + else if (exponent >= 127 - 15 + 31) + { + // overflow or infinity -> infinity + exponent = 31; + mantissa = 0; + } + else if (exponent <= 127 - 15) + { + // underflow -> zero + exponent = 0; + mantissa = 0; + } + else + { + exponent -= 127 - 15; + mantissa >>= 13; + } - } else if (exponent == 255 && mantissa != 0) { - // nan -> infinity - exponent = 31; - mantissa = 0; - - } else if (exponent >= 127 - 15 + 31) { - // overflow or infinity -> infinity - exponent = 31; - mantissa = 0; - - } else if (exponent <= 127 - 15) { - // underflow -> zero - exponent = 0; - mantissa = 0; - - } else { - exponent -= 127 - 15; - mantissa >>= 13; - } - - hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); - } + hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); + } } -inline Vector4 & Vector4::operator =( const Vector4 & vec ) +inline Vector4 &Vector4::operator=(const Vector4 &vec) { - mX = vec.mX; - mY = vec.mY; - mZ = vec.mZ; - mW = vec.mW; - return *this; + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; + mW = vec.mW; + return *this; } -inline Vector4 & Vector4::setXYZ( const Vector3 & vec ) +inline Vector4 &Vector4::setXYZ(const Vector3 &vec) { - mX = vec.getX(); - mY = vec.getY(); - mZ = vec.getZ(); - return *this; + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + return *this; } -inline const Vector3 Vector4::getXYZ( ) const +inline const Vector3 Vector4::getXYZ() const { - return Vector3( mX, mY, mZ ); + return Vector3(mX, mY, mZ); } -inline Vector4 & Vector4::setX( float _x ) +inline Vector4 &Vector4::setX(float _x) { - mX = _x; - return *this; + mX = _x; + return *this; } -inline float Vector4::getX( ) const +inline float Vector4::getX() const { - return mX; + return mX; } -inline Vector4 & Vector4::setY( float _y ) +inline Vector4 &Vector4::setY(float _y) { - mY = _y; - return *this; + mY = _y; + return *this; } -inline float Vector4::getY( ) const +inline float Vector4::getY() const { - return mY; + return mY; } -inline Vector4 & Vector4::setZ( float _z ) +inline Vector4 &Vector4::setZ(float _z) { - mZ = _z; - return *this; + mZ = _z; + return *this; } -inline float Vector4::getZ( ) const +inline float Vector4::getZ() const { - return mZ; + return mZ; } -inline Vector4 & Vector4::setW( float _w ) +inline Vector4 &Vector4::setW(float _w) { - mW = _w; - return *this; + mW = _w; + return *this; } -inline float Vector4::getW( ) const +inline float Vector4::getW() const { - return mW; + return mW; } -inline Vector4 & Vector4::setElem( int idx, float value ) +inline Vector4 &Vector4::setElem(int idx, float value) { - *(&mX + idx) = value; - return *this; + *(&mX + idx) = value; + return *this; } -inline float Vector4::getElem( int idx ) const +inline float Vector4::getElem(int idx) const { - return *(&mX + idx); + return *(&mX + idx); } -inline float & Vector4::operator []( int idx ) +inline float &Vector4::operator[](int idx) { - return *(&mX + idx); + return *(&mX + idx); } -inline float Vector4::operator []( int idx ) const +inline float Vector4::operator[](int idx) const { - return *(&mX + idx); + return *(&mX + idx); } -inline const Vector4 Vector4::operator +( const Vector4 & vec ) const +inline const Vector4 Vector4::operator+(const Vector4 &vec) const { - return Vector4( - ( mX + vec.mX ), - ( mY + vec.mY ), - ( mZ + vec.mZ ), - ( mW + vec.mW ) - ); + return Vector4( + (mX + vec.mX), + (mY + vec.mY), + (mZ + vec.mZ), + (mW + vec.mW)); } -inline const Vector4 Vector4::operator -( const Vector4 & vec ) const +inline const Vector4 Vector4::operator-(const Vector4 &vec) const { - return Vector4( - ( mX - vec.mX ), - ( mY - vec.mY ), - ( mZ - vec.mZ ), - ( mW - vec.mW ) - ); + return Vector4( + (mX - vec.mX), + (mY - vec.mY), + (mZ - vec.mZ), + (mW - vec.mW)); } -inline const Vector4 Vector4::operator *( float scalar ) const +inline const Vector4 Vector4::operator*(float scalar) const { - return Vector4( - ( mX * scalar ), - ( mY * scalar ), - ( mZ * scalar ), - ( mW * scalar ) - ); + return Vector4( + (mX * scalar), + (mY * scalar), + (mZ * scalar), + (mW * scalar)); } -inline Vector4 & Vector4::operator +=( const Vector4 & vec ) +inline Vector4 &Vector4::operator+=(const Vector4 &vec) { - *this = *this + vec; - return *this; + *this = *this + vec; + return *this; } -inline Vector4 & Vector4::operator -=( const Vector4 & vec ) +inline Vector4 &Vector4::operator-=(const Vector4 &vec) { - *this = *this - vec; - return *this; + *this = *this - vec; + return *this; } -inline Vector4 & Vector4::operator *=( float scalar ) +inline Vector4 &Vector4::operator*=(float scalar) { - *this = *this * scalar; - return *this; + *this = *this * scalar; + return *this; } -inline const Vector4 Vector4::operator /( float scalar ) const +inline const Vector4 Vector4::operator/(float scalar) const { - return Vector4( - ( mX / scalar ), - ( mY / scalar ), - ( mZ / scalar ), - ( mW / scalar ) - ); + return Vector4( + (mX / scalar), + (mY / scalar), + (mZ / scalar), + (mW / scalar)); } -inline Vector4 & Vector4::operator /=( float scalar ) +inline Vector4 &Vector4::operator/=(float scalar) { - *this = *this / scalar; - return *this; + *this = *this / scalar; + return *this; } -inline const Vector4 Vector4::operator -( ) const +inline const Vector4 Vector4::operator-() const { - return Vector4( - -mX, - -mY, - -mZ, - -mW - ); + return Vector4( + -mX, + -mY, + -mZ, + -mW); } -inline const Vector4 operator *( float scalar, const Vector4 & vec ) +inline const Vector4 operator*(float scalar, const Vector4 &vec) { - return vec * scalar; + return vec * scalar; } -inline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +inline const Vector4 mulPerElem(const Vector4 &vec0, const Vector4 &vec1) { - return Vector4( - ( vec0.getX() * vec1.getX() ), - ( vec0.getY() * vec1.getY() ), - ( vec0.getZ() * vec1.getZ() ), - ( vec0.getW() * vec1.getW() ) - ); + return Vector4( + (vec0.getX() * vec1.getX()), + (vec0.getY() * vec1.getY()), + (vec0.getZ() * vec1.getZ()), + (vec0.getW() * vec1.getW())); } -inline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +inline const Vector4 divPerElem(const Vector4 &vec0, const Vector4 &vec1) { - return Vector4( - ( vec0.getX() / vec1.getX() ), - ( vec0.getY() / vec1.getY() ), - ( vec0.getZ() / vec1.getZ() ), - ( vec0.getW() / vec1.getW() ) - ); + return Vector4( + (vec0.getX() / vec1.getX()), + (vec0.getY() / vec1.getY()), + (vec0.getZ() / vec1.getZ()), + (vec0.getW() / vec1.getW())); } -inline const Vector4 recipPerElem( const Vector4 & vec ) +inline const Vector4 recipPerElem(const Vector4 &vec) { - return Vector4( - ( 1.0f / vec.getX() ), - ( 1.0f / vec.getY() ), - ( 1.0f / vec.getZ() ), - ( 1.0f / vec.getW() ) - ); + return Vector4( + (1.0f / vec.getX()), + (1.0f / vec.getY()), + (1.0f / vec.getZ()), + (1.0f / vec.getW())); } -inline const Vector4 sqrtPerElem( const Vector4 & vec ) +inline const Vector4 sqrtPerElem(const Vector4 &vec) { - return Vector4( - sqrtf( vec.getX() ), - sqrtf( vec.getY() ), - sqrtf( vec.getZ() ), - sqrtf( vec.getW() ) - ); + return Vector4( + sqrtf(vec.getX()), + sqrtf(vec.getY()), + sqrtf(vec.getZ()), + sqrtf(vec.getW())); } -inline const Vector4 rsqrtPerElem( const Vector4 & vec ) +inline const Vector4 rsqrtPerElem(const Vector4 &vec) { - return Vector4( - ( 1.0f / sqrtf( vec.getX() ) ), - ( 1.0f / sqrtf( vec.getY() ) ), - ( 1.0f / sqrtf( vec.getZ() ) ), - ( 1.0f / sqrtf( vec.getW() ) ) - ); + return Vector4( + (1.0f / sqrtf(vec.getX())), + (1.0f / sqrtf(vec.getY())), + (1.0f / sqrtf(vec.getZ())), + (1.0f / sqrtf(vec.getW()))); } -inline const Vector4 absPerElem( const Vector4 & vec ) +inline const Vector4 absPerElem(const Vector4 &vec) { - return Vector4( - fabsf( vec.getX() ), - fabsf( vec.getY() ), - fabsf( vec.getZ() ), - fabsf( vec.getW() ) - ); + return Vector4( + fabsf(vec.getX()), + fabsf(vec.getY()), + fabsf(vec.getZ()), + fabsf(vec.getW())); } -inline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +inline const Vector4 copySignPerElem(const Vector4 &vec0, const Vector4 &vec1) { - return Vector4( - ( vec1.getX() < 0.0f )? -fabsf( vec0.getX() ) : fabsf( vec0.getX() ), - ( vec1.getY() < 0.0f )? -fabsf( vec0.getY() ) : fabsf( vec0.getY() ), - ( vec1.getZ() < 0.0f )? -fabsf( vec0.getZ() ) : fabsf( vec0.getZ() ), - ( vec1.getW() < 0.0f )? -fabsf( vec0.getW() ) : fabsf( vec0.getW() ) - ); + return Vector4( + (vec1.getX() < 0.0f) ? -fabsf(vec0.getX()) : fabsf(vec0.getX()), + (vec1.getY() < 0.0f) ? -fabsf(vec0.getY()) : fabsf(vec0.getY()), + (vec1.getZ() < 0.0f) ? -fabsf(vec0.getZ()) : fabsf(vec0.getZ()), + (vec1.getW() < 0.0f) ? -fabsf(vec0.getW()) : fabsf(vec0.getW())); } -inline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +inline const Vector4 maxPerElem(const Vector4 &vec0, const Vector4 &vec1) { - return Vector4( - (vec0.getX() > vec1.getX())? vec0.getX() : vec1.getX(), - (vec0.getY() > vec1.getY())? vec0.getY() : vec1.getY(), - (vec0.getZ() > vec1.getZ())? vec0.getZ() : vec1.getZ(), - (vec0.getW() > vec1.getW())? vec0.getW() : vec1.getW() - ); + return Vector4( + (vec0.getX() > vec1.getX()) ? vec0.getX() : vec1.getX(), + (vec0.getY() > vec1.getY()) ? vec0.getY() : vec1.getY(), + (vec0.getZ() > vec1.getZ()) ? vec0.getZ() : vec1.getZ(), + (vec0.getW() > vec1.getW()) ? vec0.getW() : vec1.getW()); } -inline float maxElem( const Vector4 & vec ) +inline float maxElem(const Vector4 &vec) { - float result; - result = (vec.getX() > vec.getY())? vec.getX() : vec.getY(); - result = (vec.getZ() > result)? vec.getZ() : result; - result = (vec.getW() > result)? vec.getW() : result; - return result; + float result; + result = (vec.getX() > vec.getY()) ? vec.getX() : vec.getY(); + result = (vec.getZ() > result) ? vec.getZ() : result; + result = (vec.getW() > result) ? vec.getW() : result; + return result; } -inline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +inline const Vector4 minPerElem(const Vector4 &vec0, const Vector4 &vec1) { - return Vector4( - (vec0.getX() < vec1.getX())? vec0.getX() : vec1.getX(), - (vec0.getY() < vec1.getY())? vec0.getY() : vec1.getY(), - (vec0.getZ() < vec1.getZ())? vec0.getZ() : vec1.getZ(), - (vec0.getW() < vec1.getW())? vec0.getW() : vec1.getW() - ); + return Vector4( + (vec0.getX() < vec1.getX()) ? vec0.getX() : vec1.getX(), + (vec0.getY() < vec1.getY()) ? vec0.getY() : vec1.getY(), + (vec0.getZ() < vec1.getZ()) ? vec0.getZ() : vec1.getZ(), + (vec0.getW() < vec1.getW()) ? vec0.getW() : vec1.getW()); } -inline float minElem( const Vector4 & vec ) +inline float minElem(const Vector4 &vec) { - float result; - result = (vec.getX() < vec.getY())? vec.getX() : vec.getY(); - result = (vec.getZ() < result)? vec.getZ() : result; - result = (vec.getW() < result)? vec.getW() : result; - return result; + float result; + result = (vec.getX() < vec.getY()) ? vec.getX() : vec.getY(); + result = (vec.getZ() < result) ? vec.getZ() : result; + result = (vec.getW() < result) ? vec.getW() : result; + return result; } -inline float sum( const Vector4 & vec ) +inline float sum(const Vector4 &vec) { - float result; - result = ( vec.getX() + vec.getY() ); - result = ( result + vec.getZ() ); - result = ( result + vec.getW() ); - return result; + float result; + result = (vec.getX() + vec.getY()); + result = (result + vec.getZ()); + result = (result + vec.getW()); + return result; } -inline float dot( const Vector4 & vec0, const Vector4 & vec1 ) +inline float dot(const Vector4 &vec0, const Vector4 &vec1) { - float result; - result = ( vec0.getX() * vec1.getX() ); - result = ( result + ( vec0.getY() * vec1.getY() ) ); - result = ( result + ( vec0.getZ() * vec1.getZ() ) ); - result = ( result + ( vec0.getW() * vec1.getW() ) ); - return result; + float result; + result = (vec0.getX() * vec1.getX()); + result = (result + (vec0.getY() * vec1.getY())); + result = (result + (vec0.getZ() * vec1.getZ())); + result = (result + (vec0.getW() * vec1.getW())); + return result; } -inline float lengthSqr( const Vector4 & vec ) +inline float lengthSqr(const Vector4 &vec) { - float result; - result = ( vec.getX() * vec.getX() ); - result = ( result + ( vec.getY() * vec.getY() ) ); - result = ( result + ( vec.getZ() * vec.getZ() ) ); - result = ( result + ( vec.getW() * vec.getW() ) ); - return result; + float result; + result = (vec.getX() * vec.getX()); + result = (result + (vec.getY() * vec.getY())); + result = (result + (vec.getZ() * vec.getZ())); + result = (result + (vec.getW() * vec.getW())); + return result; } -inline float length( const Vector4 & vec ) +inline float length(const Vector4 &vec) { - return ::sqrtf( lengthSqr( vec ) ); + return ::sqrtf(lengthSqr(vec)); } -inline const Vector4 normalize( const Vector4 & vec ) +inline const Vector4 normalize(const Vector4 &vec) { - float lenSqr, lenInv; - lenSqr = lengthSqr( vec ); - lenInv = ( 1.0f / sqrtf( lenSqr ) ); - return Vector4( - ( vec.getX() * lenInv ), - ( vec.getY() * lenInv ), - ( vec.getZ() * lenInv ), - ( vec.getW() * lenInv ) - ); + float lenSqr, lenInv; + lenSqr = lengthSqr(vec); + lenInv = (1.0f / sqrtf(lenSqr)); + return Vector4( + (vec.getX() * lenInv), + (vec.getY() * lenInv), + (vec.getZ() * lenInv), + (vec.getW() * lenInv)); } -inline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, bool select1 ) +inline const Vector4 select(const Vector4 &vec0, const Vector4 &vec1, bool select1) { - return Vector4( - ( select1 )? vec1.getX() : vec0.getX(), - ( select1 )? vec1.getY() : vec0.getY(), - ( select1 )? vec1.getZ() : vec0.getZ(), - ( select1 )? vec1.getW() : vec0.getW() - ); + return Vector4( + (select1) ? vec1.getX() : vec0.getX(), + (select1) ? vec1.getY() : vec0.getY(), + (select1) ? vec1.getZ() : vec0.getZ(), + (select1) ? vec1.getW() : vec0.getW()); } #ifdef _VECTORMATH_DEBUG -inline void print( const Vector4 & vec ) +inline void print(const Vector4 &vec) { - printf( "( %f %f %f %f )\n", vec.getX(), vec.getY(), vec.getZ(), vec.getW() ); + printf("( %f %f %f %f )\n", vec.getX(), vec.getY(), vec.getZ(), vec.getW()); } -inline void print( const Vector4 & vec, const char * name ) +inline void print(const Vector4 &vec, const char *name) { - printf( "%s: ( %f %f %f %f )\n", name, vec.getX(), vec.getY(), vec.getZ(), vec.getW() ); + printf("%s: ( %f %f %f %f )\n", name, vec.getX(), vec.getY(), vec.getZ(), vec.getW()); } #endif -inline Point3::Point3( const Point3 & pnt ) +inline Point3::Point3(const Point3 &pnt) { - mX = pnt.mX; - mY = pnt.mY; - mZ = pnt.mZ; + mX = pnt.mX; + mY = pnt.mY; + mZ = pnt.mZ; } -inline Point3::Point3( float _x, float _y, float _z ) +inline Point3::Point3(float _x, float _y, float _z) { - mX = _x; - mY = _y; - mZ = _z; + mX = _x; + mY = _y; + mZ = _z; } -inline Point3::Point3( const Vector3 & vec ) +inline Point3::Point3(const Vector3 &vec) { - mX = vec.getX(); - mY = vec.getY(); - mZ = vec.getZ(); + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); } -inline Point3::Point3( float scalar ) +inline Point3::Point3(float scalar) { - mX = scalar; - mY = scalar; - mZ = scalar; + mX = scalar; + mY = scalar; + mZ = scalar; } -inline const Point3 lerp( float t, const Point3 & pnt0, const Point3 & pnt1 ) +inline const Point3 lerp(float t, const Point3 &pnt0, const Point3 &pnt1) { - return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) ); + return (pnt0 + ((pnt1 - pnt0) * t)); } -inline void loadXYZ( Point3 & pnt, const float * fptr ) +inline void loadXYZ(Point3 &pnt, const float *fptr) { - pnt = Point3( fptr[0], fptr[1], fptr[2] ); + pnt = Point3(fptr[0], fptr[1], fptr[2]); } -inline void storeXYZ( const Point3 & pnt, float * fptr ) +inline void storeXYZ(const Point3 &pnt, float *fptr) { - fptr[0] = pnt.getX(); - fptr[1] = pnt.getY(); - fptr[2] = pnt.getZ(); + fptr[0] = pnt.getX(); + fptr[1] = pnt.getY(); + fptr[2] = pnt.getZ(); } -inline void loadHalfFloats( Point3 & vec, const unsigned short * hfptr ) +inline void loadHalfFloats(Point3 &vec, const unsigned short *hfptr) { - union Data32 { - unsigned int u32; - float f32; - }; + union Data32 { + unsigned int u32; + float f32; + }; - for (int i = 0; i < 3; i++) { - unsigned short fp16 = hfptr[i]; - unsigned int sign = fp16 >> 15; - unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); - unsigned int mantissa = fp16 & ((1 << 10) - 1); + for (int i = 0; i < 3; i++) + { + unsigned short fp16 = hfptr[i]; + unsigned int sign = fp16 >> 15; + unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); + unsigned int mantissa = fp16 & ((1 << 10) - 1); - if (exponent == 0) { - // zero - mantissa = 0; + if (exponent == 0) + { + // zero + mantissa = 0; + } + else if (exponent == 31) + { + // infinity or nan -> infinity + exponent = 255; + mantissa = 0; + } + else + { + exponent += 127 - 15; + mantissa <<= 13; + } - } else if (exponent == 31) { - // infinity or nan -> infinity - exponent = 255; - mantissa = 0; - - } else { - exponent += 127 - 15; - mantissa <<= 13; - } - - Data32 d; - d.u32 = (sign << 31) | (exponent << 23) | mantissa; - vec[i] = d.f32; - } + Data32 d; + d.u32 = (sign << 31) | (exponent << 23) | mantissa; + vec[i] = d.f32; + } } -inline void storeHalfFloats( const Point3 & vec, unsigned short * hfptr ) +inline void storeHalfFloats(const Point3 &vec, unsigned short *hfptr) { - union Data32 { - unsigned int u32; - float f32; - }; + union Data32 { + unsigned int u32; + float f32; + }; - for (int i = 0; i < 3; i++) { - Data32 d; - d.f32 = vec[i]; + for (int i = 0; i < 3; i++) + { + Data32 d; + d.f32 = vec[i]; - unsigned int sign = d.u32 >> 31; - unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); - unsigned int mantissa = d.u32 & ((1 << 23) - 1);; + unsigned int sign = d.u32 >> 31; + unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); + unsigned int mantissa = d.u32 & ((1 << 23) - 1); + ; - if (exponent == 0) { - // zero or denorm -> zero - mantissa = 0; + if (exponent == 0) + { + // zero or denorm -> zero + mantissa = 0; + } + else if (exponent == 255 && mantissa != 0) + { + // nan -> infinity + exponent = 31; + mantissa = 0; + } + else if (exponent >= 127 - 15 + 31) + { + // overflow or infinity -> infinity + exponent = 31; + mantissa = 0; + } + else if (exponent <= 127 - 15) + { + // underflow -> zero + exponent = 0; + mantissa = 0; + } + else + { + exponent -= 127 - 15; + mantissa >>= 13; + } - } else if (exponent == 255 && mantissa != 0) { - // nan -> infinity - exponent = 31; - mantissa = 0; - - } else if (exponent >= 127 - 15 + 31) { - // overflow or infinity -> infinity - exponent = 31; - mantissa = 0; - - } else if (exponent <= 127 - 15) { - // underflow -> zero - exponent = 0; - mantissa = 0; - - } else { - exponent -= 127 - 15; - mantissa >>= 13; - } - - hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); - } + hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); + } } -inline Point3 & Point3::operator =( const Point3 & pnt ) +inline Point3 &Point3::operator=(const Point3 &pnt) { - mX = pnt.mX; - mY = pnt.mY; - mZ = pnt.mZ; - return *this; + mX = pnt.mX; + mY = pnt.mY; + mZ = pnt.mZ; + return *this; } -inline Point3 & Point3::setX( float _x ) +inline Point3 &Point3::setX(float _x) { - mX = _x; - return *this; + mX = _x; + return *this; } -inline float Point3::getX( ) const +inline float Point3::getX() const { - return mX; + return mX; } -inline Point3 & Point3::setY( float _y ) +inline Point3 &Point3::setY(float _y) { - mY = _y; - return *this; + mY = _y; + return *this; } -inline float Point3::getY( ) const +inline float Point3::getY() const { - return mY; + return mY; } -inline Point3 & Point3::setZ( float _z ) +inline Point3 &Point3::setZ(float _z) { - mZ = _z; - return *this; + mZ = _z; + return *this; } -inline float Point3::getZ( ) const +inline float Point3::getZ() const { - return mZ; + return mZ; } -inline Point3 & Point3::setElem( int idx, float value ) +inline Point3 &Point3::setElem(int idx, float value) { - *(&mX + idx) = value; - return *this; + *(&mX + idx) = value; + return *this; } -inline float Point3::getElem( int idx ) const +inline float Point3::getElem(int idx) const { - return *(&mX + idx); + return *(&mX + idx); } -inline float & Point3::operator []( int idx ) +inline float &Point3::operator[](int idx) { - return *(&mX + idx); + return *(&mX + idx); } -inline float Point3::operator []( int idx ) const +inline float Point3::operator[](int idx) const { - return *(&mX + idx); + return *(&mX + idx); } -inline const Vector3 Point3::operator -( const Point3 & pnt ) const +inline const Vector3 Point3::operator-(const Point3 &pnt) const { - return Vector3( - ( mX - pnt.mX ), - ( mY - pnt.mY ), - ( mZ - pnt.mZ ) - ); + return Vector3( + (mX - pnt.mX), + (mY - pnt.mY), + (mZ - pnt.mZ)); } -inline const Point3 Point3::operator +( const Vector3 & vec ) const +inline const Point3 Point3::operator+(const Vector3 &vec) const { - return Point3( - ( mX + vec.getX() ), - ( mY + vec.getY() ), - ( mZ + vec.getZ() ) - ); + return Point3( + (mX + vec.getX()), + (mY + vec.getY()), + (mZ + vec.getZ())); } -inline const Point3 Point3::operator -( const Vector3 & vec ) const +inline const Point3 Point3::operator-(const Vector3 &vec) const { - return Point3( - ( mX - vec.getX() ), - ( mY - vec.getY() ), - ( mZ - vec.getZ() ) - ); + return Point3( + (mX - vec.getX()), + (mY - vec.getY()), + (mZ - vec.getZ())); } -inline Point3 & Point3::operator +=( const Vector3 & vec ) +inline Point3 &Point3::operator+=(const Vector3 &vec) { - *this = *this + vec; - return *this; + *this = *this + vec; + return *this; } -inline Point3 & Point3::operator -=( const Vector3 & vec ) +inline Point3 &Point3::operator-=(const Vector3 &vec) { - *this = *this - vec; - return *this; + *this = *this - vec; + return *this; } -inline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +inline const Point3 mulPerElem(const Point3 &pnt0, const Point3 &pnt1) { - return Point3( - ( pnt0.getX() * pnt1.getX() ), - ( pnt0.getY() * pnt1.getY() ), - ( pnt0.getZ() * pnt1.getZ() ) - ); + return Point3( + (pnt0.getX() * pnt1.getX()), + (pnt0.getY() * pnt1.getY()), + (pnt0.getZ() * pnt1.getZ())); } -inline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +inline const Point3 divPerElem(const Point3 &pnt0, const Point3 &pnt1) { - return Point3( - ( pnt0.getX() / pnt1.getX() ), - ( pnt0.getY() / pnt1.getY() ), - ( pnt0.getZ() / pnt1.getZ() ) - ); + return Point3( + (pnt0.getX() / pnt1.getX()), + (pnt0.getY() / pnt1.getY()), + (pnt0.getZ() / pnt1.getZ())); } -inline const Point3 recipPerElem( const Point3 & pnt ) +inline const Point3 recipPerElem(const Point3 &pnt) { - return Point3( - ( 1.0f / pnt.getX() ), - ( 1.0f / pnt.getY() ), - ( 1.0f / pnt.getZ() ) - ); + return Point3( + (1.0f / pnt.getX()), + (1.0f / pnt.getY()), + (1.0f / pnt.getZ())); } -inline const Point3 sqrtPerElem( const Point3 & pnt ) +inline const Point3 sqrtPerElem(const Point3 &pnt) { - return Point3( - sqrtf( pnt.getX() ), - sqrtf( pnt.getY() ), - sqrtf( pnt.getZ() ) - ); + return Point3( + sqrtf(pnt.getX()), + sqrtf(pnt.getY()), + sqrtf(pnt.getZ())); } -inline const Point3 rsqrtPerElem( const Point3 & pnt ) +inline const Point3 rsqrtPerElem(const Point3 &pnt) { - return Point3( - ( 1.0f / sqrtf( pnt.getX() ) ), - ( 1.0f / sqrtf( pnt.getY() ) ), - ( 1.0f / sqrtf( pnt.getZ() ) ) - ); + return Point3( + (1.0f / sqrtf(pnt.getX())), + (1.0f / sqrtf(pnt.getY())), + (1.0f / sqrtf(pnt.getZ()))); } -inline const Point3 absPerElem( const Point3 & pnt ) +inline const Point3 absPerElem(const Point3 &pnt) { - return Point3( - fabsf( pnt.getX() ), - fabsf( pnt.getY() ), - fabsf( pnt.getZ() ) - ); + return Point3( + fabsf(pnt.getX()), + fabsf(pnt.getY()), + fabsf(pnt.getZ())); } -inline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +inline const Point3 copySignPerElem(const Point3 &pnt0, const Point3 &pnt1) { - return Point3( - ( pnt1.getX() < 0.0f )? -fabsf( pnt0.getX() ) : fabsf( pnt0.getX() ), - ( pnt1.getY() < 0.0f )? -fabsf( pnt0.getY() ) : fabsf( pnt0.getY() ), - ( pnt1.getZ() < 0.0f )? -fabsf( pnt0.getZ() ) : fabsf( pnt0.getZ() ) - ); + return Point3( + (pnt1.getX() < 0.0f) ? -fabsf(pnt0.getX()) : fabsf(pnt0.getX()), + (pnt1.getY() < 0.0f) ? -fabsf(pnt0.getY()) : fabsf(pnt0.getY()), + (pnt1.getZ() < 0.0f) ? -fabsf(pnt0.getZ()) : fabsf(pnt0.getZ())); } -inline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +inline const Point3 maxPerElem(const Point3 &pnt0, const Point3 &pnt1) { - return Point3( - (pnt0.getX() > pnt1.getX())? pnt0.getX() : pnt1.getX(), - (pnt0.getY() > pnt1.getY())? pnt0.getY() : pnt1.getY(), - (pnt0.getZ() > pnt1.getZ())? pnt0.getZ() : pnt1.getZ() - ); + return Point3( + (pnt0.getX() > pnt1.getX()) ? pnt0.getX() : pnt1.getX(), + (pnt0.getY() > pnt1.getY()) ? pnt0.getY() : pnt1.getY(), + (pnt0.getZ() > pnt1.getZ()) ? pnt0.getZ() : pnt1.getZ()); } -inline float maxElem( const Point3 & pnt ) +inline float maxElem(const Point3 &pnt) { - float result; - result = (pnt.getX() > pnt.getY())? pnt.getX() : pnt.getY(); - result = (pnt.getZ() > result)? pnt.getZ() : result; - return result; + float result; + result = (pnt.getX() > pnt.getY()) ? pnt.getX() : pnt.getY(); + result = (pnt.getZ() > result) ? pnt.getZ() : result; + return result; } -inline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +inline const Point3 minPerElem(const Point3 &pnt0, const Point3 &pnt1) { - return Point3( - (pnt0.getX() < pnt1.getX())? pnt0.getX() : pnt1.getX(), - (pnt0.getY() < pnt1.getY())? pnt0.getY() : pnt1.getY(), - (pnt0.getZ() < pnt1.getZ())? pnt0.getZ() : pnt1.getZ() - ); + return Point3( + (pnt0.getX() < pnt1.getX()) ? pnt0.getX() : pnt1.getX(), + (pnt0.getY() < pnt1.getY()) ? pnt0.getY() : pnt1.getY(), + (pnt0.getZ() < pnt1.getZ()) ? pnt0.getZ() : pnt1.getZ()); } -inline float minElem( const Point3 & pnt ) +inline float minElem(const Point3 &pnt) { - float result; - result = (pnt.getX() < pnt.getY())? pnt.getX() : pnt.getY(); - result = (pnt.getZ() < result)? pnt.getZ() : result; - return result; + float result; + result = (pnt.getX() < pnt.getY()) ? pnt.getX() : pnt.getY(); + result = (pnt.getZ() < result) ? pnt.getZ() : result; + return result; } -inline float sum( const Point3 & pnt ) +inline float sum(const Point3 &pnt) { - float result; - result = ( pnt.getX() + pnt.getY() ); - result = ( result + pnt.getZ() ); - return result; + float result; + result = (pnt.getX() + pnt.getY()); + result = (result + pnt.getZ()); + return result; } -inline const Point3 scale( const Point3 & pnt, float scaleVal ) +inline const Point3 scale(const Point3 &pnt, float scaleVal) { - return mulPerElem( pnt, Point3( scaleVal ) ); + return mulPerElem(pnt, Point3(scaleVal)); } -inline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec ) +inline const Point3 scale(const Point3 &pnt, const Vector3 &scaleVec) { - return mulPerElem( pnt, Point3( scaleVec ) ); + return mulPerElem(pnt, Point3(scaleVec)); } -inline float projection( const Point3 & pnt, const Vector3 & unitVec ) +inline float projection(const Point3 &pnt, const Vector3 &unitVec) { - float result; - result = ( pnt.getX() * unitVec.getX() ); - result = ( result + ( pnt.getY() * unitVec.getY() ) ); - result = ( result + ( pnt.getZ() * unitVec.getZ() ) ); - return result; + float result; + result = (pnt.getX() * unitVec.getX()); + result = (result + (pnt.getY() * unitVec.getY())); + result = (result + (pnt.getZ() * unitVec.getZ())); + return result; } -inline float distSqrFromOrigin( const Point3 & pnt ) +inline float distSqrFromOrigin(const Point3 &pnt) { - return lengthSqr( Vector3( pnt ) ); + return lengthSqr(Vector3(pnt)); } -inline float distFromOrigin( const Point3 & pnt ) +inline float distFromOrigin(const Point3 &pnt) { - return length( Vector3( pnt ) ); + return length(Vector3(pnt)); } -inline float distSqr( const Point3 & pnt0, const Point3 & pnt1 ) +inline float distSqr(const Point3 &pnt0, const Point3 &pnt1) { - return lengthSqr( ( pnt1 - pnt0 ) ); + return lengthSqr((pnt1 - pnt0)); } -inline float dist( const Point3 & pnt0, const Point3 & pnt1 ) +inline float dist(const Point3 &pnt0, const Point3 &pnt1) { - return length( ( pnt1 - pnt0 ) ); + return length((pnt1 - pnt0)); } -inline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, bool select1 ) +inline const Point3 select(const Point3 &pnt0, const Point3 &pnt1, bool select1) { - return Point3( - ( select1 )? pnt1.getX() : pnt0.getX(), - ( select1 )? pnt1.getY() : pnt0.getY(), - ( select1 )? pnt1.getZ() : pnt0.getZ() - ); + return Point3( + (select1) ? pnt1.getX() : pnt0.getX(), + (select1) ? pnt1.getY() : pnt0.getY(), + (select1) ? pnt1.getZ() : pnt0.getZ()); } #ifdef _VECTORMATH_DEBUG -inline void print( const Point3 & pnt ) +inline void print(const Point3 &pnt) { - printf( "( %f %f %f )\n", pnt.getX(), pnt.getY(), pnt.getZ() ); + printf("( %f %f %f )\n", pnt.getX(), pnt.getY(), pnt.getZ()); } -inline void print( const Point3 & pnt, const char * name ) +inline void print(const Point3 &pnt, const char *name) { - printf( "%s: ( %f %f %f )\n", name, pnt.getX(), pnt.getY(), pnt.getZ() ); + printf("%s: ( %f %f %f )\n", name, pnt.getX(), pnt.getY(), pnt.getZ()); } #endif -} // namespace Aos -} // namespace Vectormath +} // namespace Aos +} // namespace Vectormath #endif - diff --git a/test/Bullet2/vectormath/neon/vectormath_aos.h b/test/Bullet2/vectormath/neon/vectormath_aos.h index 97bdc278a..a6eba6f18 100644 --- a/test/Bullet2/vectormath/neon/vectormath_aos.h +++ b/test/Bullet2/vectormath/neon/vectormath_aos.h @@ -25,10 +25,10 @@ This source version has been altered. #include #endif -namespace Vectormath { - -namespace Aos { - +namespace Vectormath +{ +namespace Aos +{ //----------------------------------------------------------------------------- // Forward Declarations // @@ -45,288 +45,288 @@ class Transform3; // class Vector3 { - float mX; - float mY; - float mZ; + float mX; + float mY; + float mZ; #ifndef __GNUC__ - float d; + float d; #endif public: - // Default constructor; does no initialization - // - inline Vector3( ) { }; + // Default constructor; does no initialization + // + inline Vector3(){}; - // Copy a 3-D vector - // - inline Vector3( const Vector3 & vec ); + // Copy a 3-D vector + // + inline Vector3(const Vector3 &vec); - // Construct a 3-D vector from x, y, and z elements - // - inline Vector3( float x, float y, float z ); + // Construct a 3-D vector from x, y, and z elements + // + inline Vector3(float x, float y, float z); - // Copy elements from a 3-D point into a 3-D vector - // - explicit inline Vector3( const Point3 & pnt ); + // Copy elements from a 3-D point into a 3-D vector + // + explicit inline Vector3(const Point3 &pnt); - // Set all elements of a 3-D vector to the same scalar value - // - explicit inline Vector3( float scalar ); + // Set all elements of a 3-D vector to the same scalar value + // + explicit inline Vector3(float scalar); - // Assign one 3-D vector to another - // - inline Vector3 & operator =( const Vector3 & vec ); + // Assign one 3-D vector to another + // + inline Vector3 &operator=(const Vector3 &vec); - // Set the x element of a 3-D vector - // - inline Vector3 & setX( float x ); + // Set the x element of a 3-D vector + // + inline Vector3 &setX(float x); - // Set the y element of a 3-D vector - // - inline Vector3 & setY( float y ); + // Set the y element of a 3-D vector + // + inline Vector3 &setY(float y); - // Set the z element of a 3-D vector - // - inline Vector3 & setZ( float z ); + // Set the z element of a 3-D vector + // + inline Vector3 &setZ(float z); - // Get the x element of a 3-D vector - // - inline float getX( ) const; + // Get the x element of a 3-D vector + // + inline float getX() const; - // Get the y element of a 3-D vector - // - inline float getY( ) const; + // Get the y element of a 3-D vector + // + inline float getY() const; - // Get the z element of a 3-D vector - // - inline float getZ( ) const; + // Get the z element of a 3-D vector + // + inline float getZ() const; - // Set an x, y, or z element of a 3-D vector by index - // - inline Vector3 & setElem( int idx, float value ); + // Set an x, y, or z element of a 3-D vector by index + // + inline Vector3 &setElem(int idx, float value); - // Get an x, y, or z element of a 3-D vector by index - // - inline float getElem( int idx ) const; + // Get an x, y, or z element of a 3-D vector by index + // + inline float getElem(int idx) const; - // Subscripting operator to set or get an element - // - inline float & operator []( int idx ); + // Subscripting operator to set or get an element + // + inline float &operator[](int idx); - // Subscripting operator to get an element - // - inline float operator []( int idx ) const; + // Subscripting operator to get an element + // + inline float operator[](int idx) const; - // Add two 3-D vectors - // - inline const Vector3 operator +( const Vector3 & vec ) const; + // Add two 3-D vectors + // + inline const Vector3 operator+(const Vector3 &vec) const; - // Subtract a 3-D vector from another 3-D vector - // - inline const Vector3 operator -( const Vector3 & vec ) const; + // Subtract a 3-D vector from another 3-D vector + // + inline const Vector3 operator-(const Vector3 &vec) const; - // Add a 3-D vector to a 3-D point - // - inline const Point3 operator +( const Point3 & pnt ) const; + // Add a 3-D vector to a 3-D point + // + inline const Point3 operator+(const Point3 &pnt) const; - // Multiply a 3-D vector by a scalar - // - inline const Vector3 operator *( float scalar ) const; + // Multiply a 3-D vector by a scalar + // + inline const Vector3 operator*(float scalar) const; - // Divide a 3-D vector by a scalar - // - inline const Vector3 operator /( float scalar ) const; + // Divide a 3-D vector by a scalar + // + inline const Vector3 operator/(float scalar) const; - // Perform compound assignment and addition with a 3-D vector - // - inline Vector3 & operator +=( const Vector3 & vec ); + // Perform compound assignment and addition with a 3-D vector + // + inline Vector3 &operator+=(const Vector3 &vec); - // Perform compound assignment and subtraction by a 3-D vector - // - inline Vector3 & operator -=( const Vector3 & vec ); + // Perform compound assignment and subtraction by a 3-D vector + // + inline Vector3 &operator-=(const Vector3 &vec); - // Perform compound assignment and multiplication by a scalar - // - inline Vector3 & operator *=( float scalar ); + // Perform compound assignment and multiplication by a scalar + // + inline Vector3 &operator*=(float scalar); - // Perform compound assignment and division by a scalar - // - inline Vector3 & operator /=( float scalar ); + // Perform compound assignment and division by a scalar + // + inline Vector3 &operator/=(float scalar); - // Negate all elements of a 3-D vector - // - inline const Vector3 operator -( ) const; + // Negate all elements of a 3-D vector + // + inline const Vector3 operator-() const; - // Construct x axis - // - static inline const Vector3 xAxis( ); + // Construct x axis + // + static inline const Vector3 xAxis(); - // Construct y axis - // - static inline const Vector3 yAxis( ); + // Construct y axis + // + static inline const Vector3 yAxis(); - // Construct z axis - // - static inline const Vector3 zAxis( ); + // Construct z axis + // + static inline const Vector3 zAxis(); } #ifdef __GNUC__ -__attribute__ ((aligned(16))) +__attribute__((aligned(16))) #endif ; // Multiply a 3-D vector by a scalar -// -inline const Vector3 operator *( float scalar, const Vector3 & vec ); +// +inline const Vector3 operator*(float scalar, const Vector3 &vec); // Multiply two 3-D vectors per element -// -inline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 ); +// +inline const Vector3 mulPerElem(const Vector3 &vec0, const Vector3 &vec1); // Divide two 3-D vectors per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function divf4. -// -inline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 ); +// +inline const Vector3 divPerElem(const Vector3 &vec0, const Vector3 &vec1); // Compute the reciprocal of a 3-D vector per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function recipf4. -// -inline const Vector3 recipPerElem( const Vector3 & vec ); +// +inline const Vector3 recipPerElem(const Vector3 &vec); // Compute the square root of a 3-D vector per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function sqrtf4. -// -inline const Vector3 sqrtPerElem( const Vector3 & vec ); +// +inline const Vector3 sqrtPerElem(const Vector3 &vec); // Compute the reciprocal square root of a 3-D vector per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function rsqrtf4. -// -inline const Vector3 rsqrtPerElem( const Vector3 & vec ); +// +inline const Vector3 rsqrtPerElem(const Vector3 &vec); // Compute the absolute value of a 3-D vector per element -// -inline const Vector3 absPerElem( const Vector3 & vec ); +// +inline const Vector3 absPerElem(const Vector3 &vec); // Copy sign from one 3-D vector to another, per element -// -inline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 ); +// +inline const Vector3 copySignPerElem(const Vector3 &vec0, const Vector3 &vec1); // Maximum of two 3-D vectors per element -// -inline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 ); +// +inline const Vector3 maxPerElem(const Vector3 &vec0, const Vector3 &vec1); // Minimum of two 3-D vectors per element -// -inline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 ); +// +inline const Vector3 minPerElem(const Vector3 &vec0, const Vector3 &vec1); // Maximum element of a 3-D vector -// -inline float maxElem( const Vector3 & vec ); +// +inline float maxElem(const Vector3 &vec); // Minimum element of a 3-D vector -// -inline float minElem( const Vector3 & vec ); +// +inline float minElem(const Vector3 &vec); // Compute the sum of all elements of a 3-D vector -// -inline float sum( const Vector3 & vec ); +// +inline float sum(const Vector3 &vec); // Compute the dot product of two 3-D vectors -// -inline float dot( const Vector3 & vec0, const Vector3 & vec1 ); +// +inline float dot(const Vector3 &vec0, const Vector3 &vec1); // Compute the square of the length of a 3-D vector -// -inline float lengthSqr( const Vector3 & vec ); +// +inline float lengthSqr(const Vector3 &vec); // Compute the length of a 3-D vector -// -inline float length( const Vector3 & vec ); +// +inline float length(const Vector3 &vec); // Normalize a 3-D vector -// NOTE: +// NOTE: // The result is unpredictable when all elements of vec are at or near zero. -// -inline const Vector3 normalize( const Vector3 & vec ); +// +inline const Vector3 normalize(const Vector3 &vec); // Compute cross product of two 3-D vectors -// -inline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 ); +// +inline const Vector3 cross(const Vector3 &vec0, const Vector3 &vec1); // Outer product of two 3-D vectors -// -inline const Matrix3 outer( const Vector3 & vec0, const Vector3 & vec1 ); +// +inline const Matrix3 outer(const Vector3 &vec0, const Vector3 &vec1); // Pre-multiply a row vector by a 3x3 matrix -// -inline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat ); +// +inline const Vector3 rowMul(const Vector3 &vec, const Matrix3 &mat); // Cross-product matrix of a 3-D vector -// -inline const Matrix3 crossMatrix( const Vector3 & vec ); +// +inline const Matrix3 crossMatrix(const Vector3 &vec); // Create cross-product matrix and multiply -// NOTE: +// NOTE: // Faster than separately creating a cross-product matrix and multiplying. -// -inline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat ); +// +inline const Matrix3 crossMatrixMul(const Vector3 &vec, const Matrix3 &mat); // Linear interpolation between two 3-D vectors -// NOTE: +// NOTE: // Does not clamp t between 0 and 1. -// -inline const Vector3 lerp( float t, const Vector3 & vec0, const Vector3 & vec1 ); +// +inline const Vector3 lerp(float t, const Vector3 &vec0, const Vector3 &vec1); // Spherical linear interpolation between two 3-D vectors -// NOTE: +// NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. -// -inline const Vector3 slerp( float t, const Vector3 & unitVec0, const Vector3 & unitVec1 ); +// +inline const Vector3 slerp(float t, const Vector3 &unitVec0, const Vector3 &unitVec1); // Conditionally select between two 3-D vectors -// -inline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, bool select1 ); +// +inline const Vector3 select(const Vector3 &vec0, const Vector3 &vec1, bool select1); // Load x, y, and z elements from the first three words of a float array. -// -// -inline void loadXYZ( Vector3 & vec, const float * fptr ); +// +// +inline void loadXYZ(Vector3 &vec, const float *fptr); // Store x, y, and z elements of a 3-D vector in the first three words of a float array. // Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed -// -inline void storeXYZ( const Vector3 & vec, float * fptr ); +// +inline void storeXYZ(const Vector3 &vec, float *fptr); // Load three-half-floats as a 3-D vector -// NOTE: +// NOTE: // This transformation does not support either denormalized numbers or NaNs. -// -inline void loadHalfFloats( Vector3 & vec, const unsigned short * hfptr ); +// +inline void loadHalfFloats(Vector3 &vec, const unsigned short *hfptr); // Store a 3-D vector as half-floats. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. -// NOTE: +// NOTE: // This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. -// -inline void storeHalfFloats( const Vector3 & vec, unsigned short * hfptr ); +// +inline void storeHalfFloats(const Vector3 &vec, unsigned short *hfptr); #ifdef _VECTORMATH_DEBUG // Print a 3-D vector -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Vector3 & vec ); +// +inline void print(const Vector3 &vec); // Print a 3-D vector and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Vector3 & vec, const char * name ); +// +inline void print(const Vector3 &vec, const char *name); #endif @@ -334,298 +334,298 @@ inline void print( const Vector3 & vec, const char * name ); // class Vector4 { - float mX; - float mY; - float mZ; - float mW; + float mX; + float mY; + float mZ; + float mW; public: - // Default constructor; does no initialization - // - inline Vector4( ) { }; + // Default constructor; does no initialization + // + inline Vector4(){}; - // Copy a 4-D vector - // - inline Vector4( const Vector4 & vec ); + // Copy a 4-D vector + // + inline Vector4(const Vector4 &vec); - // Construct a 4-D vector from x, y, z, and w elements - // - inline Vector4( float x, float y, float z, float w ); + // Construct a 4-D vector from x, y, z, and w elements + // + inline Vector4(float x, float y, float z, float w); - // Construct a 4-D vector from a 3-D vector and a scalar - // - inline Vector4( const Vector3 & xyz, float w ); + // Construct a 4-D vector from a 3-D vector and a scalar + // + inline Vector4(const Vector3 &xyz, float w); - // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 - // - explicit inline Vector4( const Vector3 & vec ); + // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 + // + explicit inline Vector4(const Vector3 &vec); - // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 - // - explicit inline Vector4( const Point3 & pnt ); + // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 + // + explicit inline Vector4(const Point3 &pnt); - // Copy elements from a quaternion into a 4-D vector - // - explicit inline Vector4( const Quat & quat ); + // Copy elements from a quaternion into a 4-D vector + // + explicit inline Vector4(const Quat &quat); - // Set all elements of a 4-D vector to the same scalar value - // - explicit inline Vector4( float scalar ); + // Set all elements of a 4-D vector to the same scalar value + // + explicit inline Vector4(float scalar); - // Assign one 4-D vector to another - // - inline Vector4 & operator =( const Vector4 & vec ); + // Assign one 4-D vector to another + // + inline Vector4 &operator=(const Vector4 &vec); - // Set the x, y, and z elements of a 4-D vector - // NOTE: - // This function does not change the w element. - // - inline Vector4 & setXYZ( const Vector3 & vec ); + // Set the x, y, and z elements of a 4-D vector + // NOTE: + // This function does not change the w element. + // + inline Vector4 &setXYZ(const Vector3 &vec); - // Get the x, y, and z elements of a 4-D vector - // - inline const Vector3 getXYZ( ) const; + // Get the x, y, and z elements of a 4-D vector + // + inline const Vector3 getXYZ() const; - // Set the x element of a 4-D vector - // - inline Vector4 & setX( float x ); + // Set the x element of a 4-D vector + // + inline Vector4 &setX(float x); - // Set the y element of a 4-D vector - // - inline Vector4 & setY( float y ); + // Set the y element of a 4-D vector + // + inline Vector4 &setY(float y); - // Set the z element of a 4-D vector - // - inline Vector4 & setZ( float z ); + // Set the z element of a 4-D vector + // + inline Vector4 &setZ(float z); - // Set the w element of a 4-D vector - // - inline Vector4 & setW( float w ); + // Set the w element of a 4-D vector + // + inline Vector4 &setW(float w); - // Get the x element of a 4-D vector - // - inline float getX( ) const; + // Get the x element of a 4-D vector + // + inline float getX() const; - // Get the y element of a 4-D vector - // - inline float getY( ) const; + // Get the y element of a 4-D vector + // + inline float getY() const; - // Get the z element of a 4-D vector - // - inline float getZ( ) const; + // Get the z element of a 4-D vector + // + inline float getZ() const; - // Get the w element of a 4-D vector - // - inline float getW( ) const; + // Get the w element of a 4-D vector + // + inline float getW() const; - // Set an x, y, z, or w element of a 4-D vector by index - // - inline Vector4 & setElem( int idx, float value ); + // Set an x, y, z, or w element of a 4-D vector by index + // + inline Vector4 &setElem(int idx, float value); - // Get an x, y, z, or w element of a 4-D vector by index - // - inline float getElem( int idx ) const; + // Get an x, y, z, or w element of a 4-D vector by index + // + inline float getElem(int idx) const; - // Subscripting operator to set or get an element - // - inline float & operator []( int idx ); + // Subscripting operator to set or get an element + // + inline float &operator[](int idx); - // Subscripting operator to get an element - // - inline float operator []( int idx ) const; + // Subscripting operator to get an element + // + inline float operator[](int idx) const; - // Add two 4-D vectors - // - inline const Vector4 operator +( const Vector4 & vec ) const; + // Add two 4-D vectors + // + inline const Vector4 operator+(const Vector4 &vec) const; - // Subtract a 4-D vector from another 4-D vector - // - inline const Vector4 operator -( const Vector4 & vec ) const; + // Subtract a 4-D vector from another 4-D vector + // + inline const Vector4 operator-(const Vector4 &vec) const; - // Multiply a 4-D vector by a scalar - // - inline const Vector4 operator *( float scalar ) const; + // Multiply a 4-D vector by a scalar + // + inline const Vector4 operator*(float scalar) const; - // Divide a 4-D vector by a scalar - // - inline const Vector4 operator /( float scalar ) const; + // Divide a 4-D vector by a scalar + // + inline const Vector4 operator/(float scalar) const; - // Perform compound assignment and addition with a 4-D vector - // - inline Vector4 & operator +=( const Vector4 & vec ); + // Perform compound assignment and addition with a 4-D vector + // + inline Vector4 &operator+=(const Vector4 &vec); - // Perform compound assignment and subtraction by a 4-D vector - // - inline Vector4 & operator -=( const Vector4 & vec ); + // Perform compound assignment and subtraction by a 4-D vector + // + inline Vector4 &operator-=(const Vector4 &vec); - // Perform compound assignment and multiplication by a scalar - // - inline Vector4 & operator *=( float scalar ); + // Perform compound assignment and multiplication by a scalar + // + inline Vector4 &operator*=(float scalar); - // Perform compound assignment and division by a scalar - // - inline Vector4 & operator /=( float scalar ); + // Perform compound assignment and division by a scalar + // + inline Vector4 &operator/=(float scalar); - // Negate all elements of a 4-D vector - // - inline const Vector4 operator -( ) const; + // Negate all elements of a 4-D vector + // + inline const Vector4 operator-() const; - // Construct x axis - // - static inline const Vector4 xAxis( ); + // Construct x axis + // + static inline const Vector4 xAxis(); - // Construct y axis - // - static inline const Vector4 yAxis( ); + // Construct y axis + // + static inline const Vector4 yAxis(); - // Construct z axis - // - static inline const Vector4 zAxis( ); + // Construct z axis + // + static inline const Vector4 zAxis(); - // Construct w axis - // - static inline const Vector4 wAxis( ); + // Construct w axis + // + static inline const Vector4 wAxis(); } #ifdef __GNUC__ -__attribute__ ((aligned(16))) +__attribute__((aligned(16))) #endif ; // Multiply a 4-D vector by a scalar -// -inline const Vector4 operator *( float scalar, const Vector4 & vec ); +// +inline const Vector4 operator*(float scalar, const Vector4 &vec); // Multiply two 4-D vectors per element -// -inline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 ); +// +inline const Vector4 mulPerElem(const Vector4 &vec0, const Vector4 &vec1); // Divide two 4-D vectors per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function divf4. -// -inline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 ); +// +inline const Vector4 divPerElem(const Vector4 &vec0, const Vector4 &vec1); // Compute the reciprocal of a 4-D vector per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function recipf4. -// -inline const Vector4 recipPerElem( const Vector4 & vec ); +// +inline const Vector4 recipPerElem(const Vector4 &vec); // Compute the square root of a 4-D vector per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function sqrtf4. -// -inline const Vector4 sqrtPerElem( const Vector4 & vec ); +// +inline const Vector4 sqrtPerElem(const Vector4 &vec); // Compute the reciprocal square root of a 4-D vector per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function rsqrtf4. -// -inline const Vector4 rsqrtPerElem( const Vector4 & vec ); +// +inline const Vector4 rsqrtPerElem(const Vector4 &vec); // Compute the absolute value of a 4-D vector per element -// -inline const Vector4 absPerElem( const Vector4 & vec ); +// +inline const Vector4 absPerElem(const Vector4 &vec); // Copy sign from one 4-D vector to another, per element -// -inline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 ); +// +inline const Vector4 copySignPerElem(const Vector4 &vec0, const Vector4 &vec1); // Maximum of two 4-D vectors per element -// -inline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 ); +// +inline const Vector4 maxPerElem(const Vector4 &vec0, const Vector4 &vec1); // Minimum of two 4-D vectors per element -// -inline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 ); +// +inline const Vector4 minPerElem(const Vector4 &vec0, const Vector4 &vec1); // Maximum element of a 4-D vector -// -inline float maxElem( const Vector4 & vec ); +// +inline float maxElem(const Vector4 &vec); // Minimum element of a 4-D vector -// -inline float minElem( const Vector4 & vec ); +// +inline float minElem(const Vector4 &vec); // Compute the sum of all elements of a 4-D vector -// -inline float sum( const Vector4 & vec ); +// +inline float sum(const Vector4 &vec); // Compute the dot product of two 4-D vectors -// -inline float dot( const Vector4 & vec0, const Vector4 & vec1 ); +// +inline float dot(const Vector4 &vec0, const Vector4 &vec1); // Compute the square of the length of a 4-D vector -// -inline float lengthSqr( const Vector4 & vec ); +// +inline float lengthSqr(const Vector4 &vec); // Compute the length of a 4-D vector -// -inline float length( const Vector4 & vec ); +// +inline float length(const Vector4 &vec); // Normalize a 4-D vector -// NOTE: +// NOTE: // The result is unpredictable when all elements of vec are at or near zero. -// -inline const Vector4 normalize( const Vector4 & vec ); +// +inline const Vector4 normalize(const Vector4 &vec); // Outer product of two 4-D vectors -// -inline const Matrix4 outer( const Vector4 & vec0, const Vector4 & vec1 ); +// +inline const Matrix4 outer(const Vector4 &vec0, const Vector4 &vec1); // Linear interpolation between two 4-D vectors -// NOTE: +// NOTE: // Does not clamp t between 0 and 1. -// -inline const Vector4 lerp( float t, const Vector4 & vec0, const Vector4 & vec1 ); +// +inline const Vector4 lerp(float t, const Vector4 &vec0, const Vector4 &vec1); // Spherical linear interpolation between two 4-D vectors -// NOTE: +// NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. -// -inline const Vector4 slerp( float t, const Vector4 & unitVec0, const Vector4 & unitVec1 ); +// +inline const Vector4 slerp(float t, const Vector4 &unitVec0, const Vector4 &unitVec1); // Conditionally select between two 4-D vectors -// -inline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, bool select1 ); +// +inline const Vector4 select(const Vector4 &vec0, const Vector4 &vec1, bool select1); // Load x, y, z, and w elements from the first four words of a float array. -// -// -inline void loadXYZW( Vector4 & vec, const float * fptr ); +// +// +inline void loadXYZW(Vector4 &vec, const float *fptr); // Store x, y, z, and w elements of a 4-D vector in the first four words of a float array. // Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed -// -inline void storeXYZW( const Vector4 & vec, float * fptr ); +// +inline void storeXYZW(const Vector4 &vec, float *fptr); // Load four-half-floats as a 4-D vector -// NOTE: +// NOTE: // This transformation does not support either denormalized numbers or NaNs. -// -inline void loadHalfFloats( Vector4 & vec, const unsigned short * hfptr ); +// +inline void loadHalfFloats(Vector4 &vec, const unsigned short *hfptr); // Store a 4-D vector as half-floats. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. -// NOTE: +// NOTE: // This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. -// -inline void storeHalfFloats( const Vector4 & vec, unsigned short * hfptr ); +// +inline void storeHalfFloats(const Vector4 &vec, unsigned short *hfptr); #ifdef _VECTORMATH_DEBUG // Print a 4-D vector -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Vector4 & vec ); +// +inline void print(const Vector4 &vec); // Print a 4-D vector and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Vector4 & vec, const char * name ); +// +inline void print(const Vector4 &vec, const char *name); #endif @@ -633,233 +633,233 @@ inline void print( const Vector4 & vec, const char * name ); // class Point3 { - float mX; - float mY; - float mZ; + float mX; + float mY; + float mZ; #ifndef __GNUC__ - float d; + float d; #endif public: - // Default constructor; does no initialization - // - inline Point3( ) { }; + // Default constructor; does no initialization + // + inline Point3(){}; - // Copy a 3-D point - // - inline Point3( const Point3 & pnt ); + // Copy a 3-D point + // + inline Point3(const Point3 &pnt); - // Construct a 3-D point from x, y, and z elements - // - inline Point3( float x, float y, float z ); + // Construct a 3-D point from x, y, and z elements + // + inline Point3(float x, float y, float z); - // Copy elements from a 3-D vector into a 3-D point - // - explicit inline Point3( const Vector3 & vec ); + // Copy elements from a 3-D vector into a 3-D point + // + explicit inline Point3(const Vector3 &vec); - // Set all elements of a 3-D point to the same scalar value - // - explicit inline Point3( float scalar ); + // Set all elements of a 3-D point to the same scalar value + // + explicit inline Point3(float scalar); - // Assign one 3-D point to another - // - inline Point3 & operator =( const Point3 & pnt ); + // Assign one 3-D point to another + // + inline Point3 &operator=(const Point3 &pnt); - // Set the x element of a 3-D point - // - inline Point3 & setX( float x ); + // Set the x element of a 3-D point + // + inline Point3 &setX(float x); - // Set the y element of a 3-D point - // - inline Point3 & setY( float y ); + // Set the y element of a 3-D point + // + inline Point3 &setY(float y); - // Set the z element of a 3-D point - // - inline Point3 & setZ( float z ); + // Set the z element of a 3-D point + // + inline Point3 &setZ(float z); - // Get the x element of a 3-D point - // - inline float getX( ) const; + // Get the x element of a 3-D point + // + inline float getX() const; - // Get the y element of a 3-D point - // - inline float getY( ) const; + // Get the y element of a 3-D point + // + inline float getY() const; - // Get the z element of a 3-D point - // - inline float getZ( ) const; + // Get the z element of a 3-D point + // + inline float getZ() const; - // Set an x, y, or z element of a 3-D point by index - // - inline Point3 & setElem( int idx, float value ); + // Set an x, y, or z element of a 3-D point by index + // + inline Point3 &setElem(int idx, float value); - // Get an x, y, or z element of a 3-D point by index - // - inline float getElem( int idx ) const; + // Get an x, y, or z element of a 3-D point by index + // + inline float getElem(int idx) const; - // Subscripting operator to set or get an element - // - inline float & operator []( int idx ); + // Subscripting operator to set or get an element + // + inline float &operator[](int idx); - // Subscripting operator to get an element - // - inline float operator []( int idx ) const; + // Subscripting operator to get an element + // + inline float operator[](int idx) const; - // Subtract a 3-D point from another 3-D point - // - inline const Vector3 operator -( const Point3 & pnt ) const; + // Subtract a 3-D point from another 3-D point + // + inline const Vector3 operator-(const Point3 &pnt) const; - // Add a 3-D point to a 3-D vector - // - inline const Point3 operator +( const Vector3 & vec ) const; + // Add a 3-D point to a 3-D vector + // + inline const Point3 operator+(const Vector3 &vec) const; - // Subtract a 3-D vector from a 3-D point - // - inline const Point3 operator -( const Vector3 & vec ) const; + // Subtract a 3-D vector from a 3-D point + // + inline const Point3 operator-(const Vector3 &vec) const; - // Perform compound assignment and addition with a 3-D vector - // - inline Point3 & operator +=( const Vector3 & vec ); + // Perform compound assignment and addition with a 3-D vector + // + inline Point3 &operator+=(const Vector3 &vec); - // Perform compound assignment and subtraction by a 3-D vector - // - inline Point3 & operator -=( const Vector3 & vec ); + // Perform compound assignment and subtraction by a 3-D vector + // + inline Point3 &operator-=(const Vector3 &vec); } #ifdef __GNUC__ -__attribute__ ((aligned(16))) +__attribute__((aligned(16))) #endif ; // Multiply two 3-D points per element -// -inline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 ); +// +inline const Point3 mulPerElem(const Point3 &pnt0, const Point3 &pnt1); // Divide two 3-D points per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function divf4. -// -inline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 ); +// +inline const Point3 divPerElem(const Point3 &pnt0, const Point3 &pnt1); // Compute the reciprocal of a 3-D point per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function recipf4. -// -inline const Point3 recipPerElem( const Point3 & pnt ); +// +inline const Point3 recipPerElem(const Point3 &pnt); // Compute the square root of a 3-D point per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function sqrtf4. -// -inline const Point3 sqrtPerElem( const Point3 & pnt ); +// +inline const Point3 sqrtPerElem(const Point3 &pnt); // Compute the reciprocal square root of a 3-D point per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function rsqrtf4. -// -inline const Point3 rsqrtPerElem( const Point3 & pnt ); +// +inline const Point3 rsqrtPerElem(const Point3 &pnt); // Compute the absolute value of a 3-D point per element -// -inline const Point3 absPerElem( const Point3 & pnt ); +// +inline const Point3 absPerElem(const Point3 &pnt); // Copy sign from one 3-D point to another, per element -// -inline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 ); +// +inline const Point3 copySignPerElem(const Point3 &pnt0, const Point3 &pnt1); // Maximum of two 3-D points per element -// -inline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 ); +// +inline const Point3 maxPerElem(const Point3 &pnt0, const Point3 &pnt1); // Minimum of two 3-D points per element -// -inline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 ); +// +inline const Point3 minPerElem(const Point3 &pnt0, const Point3 &pnt1); // Maximum element of a 3-D point -// -inline float maxElem( const Point3 & pnt ); +// +inline float maxElem(const Point3 &pnt); // Minimum element of a 3-D point -// -inline float minElem( const Point3 & pnt ); +// +inline float minElem(const Point3 &pnt); // Compute the sum of all elements of a 3-D point -// -inline float sum( const Point3 & pnt ); +// +inline float sum(const Point3 &pnt); // Apply uniform scale to a 3-D point -// -inline const Point3 scale( const Point3 & pnt, float scaleVal ); +// +inline const Point3 scale(const Point3 &pnt, float scaleVal); // Apply non-uniform scale to a 3-D point -// -inline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec ); +// +inline const Point3 scale(const Point3 &pnt, const Vector3 &scaleVec); // Scalar projection of a 3-D point on a unit-length 3-D vector -// -inline float projection( const Point3 & pnt, const Vector3 & unitVec ); +// +inline float projection(const Point3 &pnt, const Vector3 &unitVec); // Compute the square of the distance of a 3-D point from the coordinate-system origin -// -inline float distSqrFromOrigin( const Point3 & pnt ); +// +inline float distSqrFromOrigin(const Point3 &pnt); // Compute the distance of a 3-D point from the coordinate-system origin -// -inline float distFromOrigin( const Point3 & pnt ); +// +inline float distFromOrigin(const Point3 &pnt); // Compute the square of the distance between two 3-D points -// -inline float distSqr( const Point3 & pnt0, const Point3 & pnt1 ); +// +inline float distSqr(const Point3 &pnt0, const Point3 &pnt1); // Compute the distance between two 3-D points -// -inline float dist( const Point3 & pnt0, const Point3 & pnt1 ); +// +inline float dist(const Point3 &pnt0, const Point3 &pnt1); // Linear interpolation between two 3-D points -// NOTE: +// NOTE: // Does not clamp t between 0 and 1. -// -inline const Point3 lerp( float t, const Point3 & pnt0, const Point3 & pnt1 ); +// +inline const Point3 lerp(float t, const Point3 &pnt0, const Point3 &pnt1); // Conditionally select between two 3-D points -// -inline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, bool select1 ); +// +inline const Point3 select(const Point3 &pnt0, const Point3 &pnt1, bool select1); // Load x, y, and z elements from the first three words of a float array. -// -// -inline void loadXYZ( Point3 & pnt, const float * fptr ); +// +// +inline void loadXYZ(Point3 &pnt, const float *fptr); // Store x, y, and z elements of a 3-D point in the first three words of a float array. // Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed -// -inline void storeXYZ( const Point3 & pnt, float * fptr ); +// +inline void storeXYZ(const Point3 &pnt, float *fptr); // Load three-half-floats as a 3-D point -// NOTE: +// NOTE: // This transformation does not support either denormalized numbers or NaNs. -// -inline void loadHalfFloats( Point3 & pnt, const unsigned short * hfptr ); +// +inline void loadHalfFloats(Point3 &pnt, const unsigned short *hfptr); // Store a 3-D point as half-floats. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. -// NOTE: +// NOTE: // This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. -// -inline void storeHalfFloats( const Point3 & pnt, unsigned short * hfptr ); +// +inline void storeHalfFloats(const Point3 &pnt, unsigned short *hfptr); #ifdef _VECTORMATH_DEBUG // Print a 3-D point -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Point3 & pnt ); +// +inline void print(const Point3 &pnt); // Print a 3-D point and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Point3 & pnt, const char * name ); +// +inline void print(const Point3 &pnt, const char *name); #endif @@ -867,267 +867,267 @@ inline void print( const Point3 & pnt, const char * name ); // class Quat { -#if defined( __APPLE__ ) && defined( BT_USE_NEON ) - union{ - float32x4_t vXYZW; - float mXYZW[4]; - }; +#if defined(__APPLE__) && defined(BT_USE_NEON) + union { + float32x4_t vXYZW; + float mXYZW[4]; + }; #else - float mX; - float mY; - float mZ; - float mW; + float mX; + float mY; + float mZ; + float mW; #endif public: - // Default constructor; does no initialization - // - inline Quat( ) { }; + // Default constructor; does no initialization + // + inline Quat(){}; - // Copy a quaternion - // - inline Quat( const Quat & quat ); + // Copy a quaternion + // + inline Quat(const Quat &quat); - // Construct a quaternion from x, y, z, and w elements - // - inline Quat( float x, float y, float z, float w ); - - // Construct a quaternion from vector of x, y, z, and w elements - // - inline Quat( float32x4_t fXYZW ); + // Construct a quaternion from x, y, z, and w elements + // + inline Quat(float x, float y, float z, float w); - // Construct a quaternion from a 3-D vector and a scalar - // - inline Quat( const Vector3 & xyz, float w ); + // Construct a quaternion from vector of x, y, z, and w elements + // + inline Quat(float32x4_t fXYZW); - // Copy elements from a 4-D vector into a quaternion - // - explicit inline Quat( const Vector4 & vec ); + // Construct a quaternion from a 3-D vector and a scalar + // + inline Quat(const Vector3 &xyz, float w); - // Convert a rotation matrix to a unit-length quaternion - // - explicit inline Quat( const Matrix3 & rotMat ); + // Copy elements from a 4-D vector into a quaternion + // + explicit inline Quat(const Vector4 &vec); - // Set all elements of a quaternion to the same scalar value - // - explicit inline Quat( float scalar ); - - // Assign one quaternion to another - // - inline Quat & operator =( const Quat & quat ); + // Convert a rotation matrix to a unit-length quaternion + // + explicit inline Quat(const Matrix3 &rotMat); - // Set the x, y, and z elements of a quaternion - // NOTE: - // This function does not change the w element. - // - inline Quat & setXYZ( const Vector3 & vec ); + // Set all elements of a quaternion to the same scalar value + // + explicit inline Quat(float scalar); - // Get the x, y, and z elements of a quaternion - // - inline const Vector3 getXYZ( ) const; + // Assign one quaternion to another + // + inline Quat &operator=(const Quat &quat); - // Set the x element of a quaternion - // - inline Quat & setX( float x ); + // Set the x, y, and z elements of a quaternion + // NOTE: + // This function does not change the w element. + // + inline Quat &setXYZ(const Vector3 &vec); - // Set the y element of a quaternion - // - inline Quat & setY( float y ); + // Get the x, y, and z elements of a quaternion + // + inline const Vector3 getXYZ() const; - // Set the z element of a quaternion - // - inline Quat & setZ( float z ); + // Set the x element of a quaternion + // + inline Quat &setX(float x); - // Set the w element of a quaternion - // - inline Quat & setW( float w ); + // Set the y element of a quaternion + // + inline Quat &setY(float y); -#if defined( __APPLE__ ) && defined( BT_USE_NEON ) - inline float32x4_t getvXYZW( ) const; + // Set the z element of a quaternion + // + inline Quat &setZ(float z); + + // Set the w element of a quaternion + // + inline Quat &setW(float w); + +#if defined(__APPLE__) && defined(BT_USE_NEON) + inline float32x4_t getvXYZW() const; #endif - - // Get the x element of a quaternion - // - inline float getX( ) const; - // Get the y element of a quaternion - // - inline float getY( ) const; + // Get the x element of a quaternion + // + inline float getX() const; - // Get the z element of a quaternion - // - inline float getZ( ) const; + // Get the y element of a quaternion + // + inline float getY() const; - // Get the w element of a quaternion - // - inline float getW( ) const; + // Get the z element of a quaternion + // + inline float getZ() const; - // Set an x, y, z, or w element of a quaternion by index - // - inline Quat & setElem( int idx, float value ); + // Get the w element of a quaternion + // + inline float getW() const; - // Get an x, y, z, or w element of a quaternion by index - // - inline float getElem( int idx ) const; + // Set an x, y, z, or w element of a quaternion by index + // + inline Quat &setElem(int idx, float value); - // Subscripting operator to set or get an element - // - inline float & operator []( int idx ); + // Get an x, y, z, or w element of a quaternion by index + // + inline float getElem(int idx) const; - // Subscripting operator to get an element - // - inline float operator []( int idx ) const; + // Subscripting operator to set or get an element + // + inline float &operator[](int idx); - // Add two quaternions - // - inline const Quat operator +( const Quat & quat ) const; + // Subscripting operator to get an element + // + inline float operator[](int idx) const; - // Subtract a quaternion from another quaternion - // - inline const Quat operator -( const Quat & quat ) const; + // Add two quaternions + // + inline const Quat operator+(const Quat &quat) const; - // Multiply two quaternions - // - inline const Quat operator *( const Quat & quat ) const; + // Subtract a quaternion from another quaternion + // + inline const Quat operator-(const Quat &quat) const; - // Multiply a quaternion by a scalar - // - inline const Quat operator *( float scalar ) const; + // Multiply two quaternions + // + inline const Quat operator*(const Quat &quat) const; - // Divide a quaternion by a scalar - // - inline const Quat operator /( float scalar ) const; + // Multiply a quaternion by a scalar + // + inline const Quat operator*(float scalar) const; - // Perform compound assignment and addition with a quaternion - // - inline Quat & operator +=( const Quat & quat ); + // Divide a quaternion by a scalar + // + inline const Quat operator/(float scalar) const; - // Perform compound assignment and subtraction by a quaternion - // - inline Quat & operator -=( const Quat & quat ); + // Perform compound assignment and addition with a quaternion + // + inline Quat &operator+=(const Quat &quat); - // Perform compound assignment and multiplication by a quaternion - // - inline Quat & operator *=( const Quat & quat ); + // Perform compound assignment and subtraction by a quaternion + // + inline Quat &operator-=(const Quat &quat); - // Perform compound assignment and multiplication by a scalar - // - inline Quat & operator *=( float scalar ); + // Perform compound assignment and multiplication by a quaternion + // + inline Quat &operator*=(const Quat &quat); - // Perform compound assignment and division by a scalar - // - inline Quat & operator /=( float scalar ); + // Perform compound assignment and multiplication by a scalar + // + inline Quat &operator*=(float scalar); - // Negate all elements of a quaternion - // - inline const Quat operator -( ) const; + // Perform compound assignment and division by a scalar + // + inline Quat &operator/=(float scalar); - // Construct an identity quaternion - // - static inline const Quat identity( ); + // Negate all elements of a quaternion + // + inline const Quat operator-() const; - // Construct a quaternion to rotate between two unit-length 3-D vectors - // NOTE: - // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. - // - static inline const Quat rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 ); + // Construct an identity quaternion + // + static inline const Quat identity(); - // Construct a quaternion to rotate around a unit-length 3-D vector - // - static inline const Quat rotation( float radians, const Vector3 & unitVec ); + // Construct a quaternion to rotate between two unit-length 3-D vectors + // NOTE: + // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. + // + static inline const Quat rotation(const Vector3 &unitVec0, const Vector3 &unitVec1); - // Construct a quaternion to rotate around the x axis - // - static inline const Quat rotationX( float radians ); + // Construct a quaternion to rotate around a unit-length 3-D vector + // + static inline const Quat rotation(float radians, const Vector3 &unitVec); - // Construct a quaternion to rotate around the y axis - // - static inline const Quat rotationY( float radians ); + // Construct a quaternion to rotate around the x axis + // + static inline const Quat rotationX(float radians); - // Construct a quaternion to rotate around the z axis - // - static inline const Quat rotationZ( float radians ); + // Construct a quaternion to rotate around the y axis + // + static inline const Quat rotationY(float radians); + + // Construct a quaternion to rotate around the z axis + // + static inline const Quat rotationZ(float radians); } #ifdef __GNUC__ -__attribute__ ((aligned(16))) +__attribute__((aligned(16))) #endif ; // Multiply a quaternion by a scalar -// -inline const Quat operator *( float scalar, const Quat & quat ); +// +inline const Quat operator*(float scalar, const Quat &quat); // Compute the conjugate of a quaternion -// -inline const Quat conj( const Quat & quat ); +// +inline const Quat conj(const Quat &quat); // Use a unit-length quaternion to rotate a 3-D vector -// -inline const Vector3 rotate( const Quat & unitQuat, const Vector3 & vec ); +// +inline const Vector3 rotate(const Quat &unitQuat, const Vector3 &vec); // Compute the dot product of two quaternions -// -inline float dot( const Quat & quat0, const Quat & quat1 ); +// +inline float dot(const Quat &quat0, const Quat &quat1); // Compute the norm of a quaternion -// -inline float norm( const Quat & quat ); +// +inline float norm(const Quat &quat); // Compute the length of a quaternion -// -inline float length( const Quat & quat ); +// +inline float length(const Quat &quat); // Normalize a quaternion -// NOTE: +// NOTE: // The result is unpredictable when all elements of quat are at or near zero. -// -inline const Quat normalize( const Quat & quat ); +// +inline const Quat normalize(const Quat &quat); // Linear interpolation between two quaternions -// NOTE: +// NOTE: // Does not clamp t between 0 and 1. -// -inline const Quat lerp( float t, const Quat & quat0, const Quat & quat1 ); +// +inline const Quat lerp(float t, const Quat &quat0, const Quat &quat1); // Spherical linear interpolation between two quaternions -// NOTE: +// NOTE: // Interpolates along the shortest path between orientations. // Does not clamp t between 0 and 1. -// -inline const Quat slerp( float t, const Quat & unitQuat0, const Quat & unitQuat1 ); +// +inline const Quat slerp(float t, const Quat &unitQuat0, const Quat &unitQuat1); // Spherical quadrangle interpolation -// -inline const Quat squad( float t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 ); +// +inline const Quat squad(float t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3); // Conditionally select between two quaternions -// -inline const Quat select( const Quat & quat0, const Quat & quat1, bool select1 ); +// +inline const Quat select(const Quat &quat0, const Quat &quat1, bool select1); // Load x, y, z, and w elements from the first four words of a float array. -// -// -inline void loadXYZW( Quat & quat, const float * fptr ); +// +// +inline void loadXYZW(Quat &quat, const float *fptr); // Store x, y, z, and w elements of a quaternion in the first four words of a float array. // Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed -// -inline void storeXYZW( const Quat & quat, float * fptr ); +// +inline void storeXYZW(const Quat &quat, float *fptr); #ifdef _VECTORMATH_DEBUG // Print a quaternion -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Quat & quat ); +// +inline void print(const Quat &quat); // Print a quaternion and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Quat & quat, const char * name ); +// +inline void print(const Quat &quat, const char *name); #endif @@ -1135,219 +1135,218 @@ inline void print( const Quat & quat, const char * name ); // class Matrix3 { - Vector3 mCol0; - Vector3 mCol1; - Vector3 mCol2; + Vector3 mCol0; + Vector3 mCol1; + Vector3 mCol2; public: - // Default constructor; does no initialization - // - inline Matrix3( ) { }; + // Default constructor; does no initialization + // + inline Matrix3(){}; - // Copy a 3x3 matrix - // - inline Matrix3( const Matrix3 & mat ); + // Copy a 3x3 matrix + // + inline Matrix3(const Matrix3 &mat); - // Construct a 3x3 matrix containing the specified columns - // - inline Matrix3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2 ); + // Construct a 3x3 matrix containing the specified columns + // + inline Matrix3(const Vector3 &col0, const Vector3 &col1, const Vector3 &col2); - // Construct a 3x3 rotation matrix from a unit-length quaternion - // - explicit inline Matrix3( const Quat & unitQuat ); + // Construct a 3x3 rotation matrix from a unit-length quaternion + // + explicit inline Matrix3(const Quat &unitQuat); - // Set all elements of a 3x3 matrix to the same scalar value - // - explicit inline Matrix3( float scalar ); + // Set all elements of a 3x3 matrix to the same scalar value + // + explicit inline Matrix3(float scalar); - // Assign one 3x3 matrix to another - // - inline Matrix3 & operator =( const Matrix3 & mat ); + // Assign one 3x3 matrix to another + // + inline Matrix3 &operator=(const Matrix3 &mat); - // Set column 0 of a 3x3 matrix - // - inline Matrix3 & setCol0( const Vector3 & col0 ); + // Set column 0 of a 3x3 matrix + // + inline Matrix3 &setCol0(const Vector3 &col0); - // Set column 1 of a 3x3 matrix - // - inline Matrix3 & setCol1( const Vector3 & col1 ); + // Set column 1 of a 3x3 matrix + // + inline Matrix3 &setCol1(const Vector3 &col1); - // Set column 2 of a 3x3 matrix - // - inline Matrix3 & setCol2( const Vector3 & col2 ); + // Set column 2 of a 3x3 matrix + // + inline Matrix3 &setCol2(const Vector3 &col2); - // Get column 0 of a 3x3 matrix - // - inline const Vector3 getCol0( ) const; + // Get column 0 of a 3x3 matrix + // + inline const Vector3 getCol0() const; - // Get column 1 of a 3x3 matrix - // - inline const Vector3 getCol1( ) const; + // Get column 1 of a 3x3 matrix + // + inline const Vector3 getCol1() const; - // Get column 2 of a 3x3 matrix - // - inline const Vector3 getCol2( ) const; + // Get column 2 of a 3x3 matrix + // + inline const Vector3 getCol2() const; - // Set the column of a 3x3 matrix referred to by the specified index - // - inline Matrix3 & setCol( int col, const Vector3 & vec ); + // Set the column of a 3x3 matrix referred to by the specified index + // + inline Matrix3 &setCol(int col, const Vector3 &vec); - // Set the row of a 3x3 matrix referred to by the specified index - // - inline Matrix3 & setRow( int row, const Vector3 & vec ); + // Set the row of a 3x3 matrix referred to by the specified index + // + inline Matrix3 &setRow(int row, const Vector3 &vec); - // Get the column of a 3x3 matrix referred to by the specified index - // - inline const Vector3 getCol( int col ) const; + // Get the column of a 3x3 matrix referred to by the specified index + // + inline const Vector3 getCol(int col) const; - // Get the row of a 3x3 matrix referred to by the specified index - // - inline const Vector3 getRow( int row ) const; + // Get the row of a 3x3 matrix referred to by the specified index + // + inline const Vector3 getRow(int row) const; - // Subscripting operator to set or get a column - // - inline Vector3 & operator []( int col ); + // Subscripting operator to set or get a column + // + inline Vector3 &operator[](int col); - // Subscripting operator to get a column - // - inline const Vector3 operator []( int col ) const; + // Subscripting operator to get a column + // + inline const Vector3 operator[](int col) const; - // Set the element of a 3x3 matrix referred to by column and row indices - // - inline Matrix3 & setElem( int col, int row, float val ); + // Set the element of a 3x3 matrix referred to by column and row indices + // + inline Matrix3 &setElem(int col, int row, float val); - // Get the element of a 3x3 matrix referred to by column and row indices - // - inline float getElem( int col, int row ) const; + // Get the element of a 3x3 matrix referred to by column and row indices + // + inline float getElem(int col, int row) const; - // Add two 3x3 matrices - // - inline const Matrix3 operator +( const Matrix3 & mat ) const; + // Add two 3x3 matrices + // + inline const Matrix3 operator+(const Matrix3 &mat) const; - // Subtract a 3x3 matrix from another 3x3 matrix - // - inline const Matrix3 operator -( const Matrix3 & mat ) const; + // Subtract a 3x3 matrix from another 3x3 matrix + // + inline const Matrix3 operator-(const Matrix3 &mat) const; - // Negate all elements of a 3x3 matrix - // - inline const Matrix3 operator -( ) const; + // Negate all elements of a 3x3 matrix + // + inline const Matrix3 operator-() const; - // Multiply a 3x3 matrix by a scalar - // - inline const Matrix3 operator *( float scalar ) const; + // Multiply a 3x3 matrix by a scalar + // + inline const Matrix3 operator*(float scalar) const; - // Multiply a 3x3 matrix by a 3-D vector - // - inline const Vector3 operator *( const Vector3 & vec ) const; + // Multiply a 3x3 matrix by a 3-D vector + // + inline const Vector3 operator*(const Vector3 &vec) const; - // Multiply two 3x3 matrices - // - inline const Matrix3 operator *( const Matrix3 & mat ) const; + // Multiply two 3x3 matrices + // + inline const Matrix3 operator*(const Matrix3 &mat) const; - // Perform compound assignment and addition with a 3x3 matrix - // - inline Matrix3 & operator +=( const Matrix3 & mat ); + // Perform compound assignment and addition with a 3x3 matrix + // + inline Matrix3 &operator+=(const Matrix3 &mat); - // Perform compound assignment and subtraction by a 3x3 matrix - // - inline Matrix3 & operator -=( const Matrix3 & mat ); + // Perform compound assignment and subtraction by a 3x3 matrix + // + inline Matrix3 &operator-=(const Matrix3 &mat); - // Perform compound assignment and multiplication by a scalar - // - inline Matrix3 & operator *=( float scalar ); + // Perform compound assignment and multiplication by a scalar + // + inline Matrix3 &operator*=(float scalar); - // Perform compound assignment and multiplication by a 3x3 matrix - // - inline Matrix3 & operator *=( const Matrix3 & mat ); + // Perform compound assignment and multiplication by a 3x3 matrix + // + inline Matrix3 &operator*=(const Matrix3 &mat); - // Construct an identity 3x3 matrix - // - static inline const Matrix3 identity( ); + // Construct an identity 3x3 matrix + // + static inline const Matrix3 identity(); - // Construct a 3x3 matrix to rotate around the x axis - // - static inline const Matrix3 rotationX( float radians ); + // Construct a 3x3 matrix to rotate around the x axis + // + static inline const Matrix3 rotationX(float radians); - // Construct a 3x3 matrix to rotate around the y axis - // - static inline const Matrix3 rotationY( float radians ); + // Construct a 3x3 matrix to rotate around the y axis + // + static inline const Matrix3 rotationY(float radians); - // Construct a 3x3 matrix to rotate around the z axis - // - static inline const Matrix3 rotationZ( float radians ); + // Construct a 3x3 matrix to rotate around the z axis + // + static inline const Matrix3 rotationZ(float radians); - // Construct a 3x3 matrix to rotate around the x, y, and z axes - // - static inline const Matrix3 rotationZYX( const Vector3 & radiansXYZ ); + // Construct a 3x3 matrix to rotate around the x, y, and z axes + // + static inline const Matrix3 rotationZYX(const Vector3 &radiansXYZ); - // Construct a 3x3 matrix to rotate around a unit-length 3-D vector - // - static inline const Matrix3 rotation( float radians, const Vector3 & unitVec ); + // Construct a 3x3 matrix to rotate around a unit-length 3-D vector + // + static inline const Matrix3 rotation(float radians, const Vector3 &unitVec); - // Construct a rotation matrix from a unit-length quaternion - // - static inline const Matrix3 rotation( const Quat & unitQuat ); - - // Construct a 3x3 matrix to perform scaling - // - static inline const Matrix3 scale( const Vector3 & scaleVec ); + // Construct a rotation matrix from a unit-length quaternion + // + static inline const Matrix3 rotation(const Quat &unitQuat); + // Construct a 3x3 matrix to perform scaling + // + static inline const Matrix3 scale(const Vector3 &scaleVec); }; // Multiply a 3x3 matrix by a scalar -// -inline const Matrix3 operator *( float scalar, const Matrix3 & mat ); +// +inline const Matrix3 operator*(float scalar, const Matrix3 &mat); // Append (post-multiply) a scale transformation to a 3x3 matrix -// NOTE: +// NOTE: // Faster than creating and multiplying a scale transformation matrix. -// -inline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec ); +// +inline const Matrix3 appendScale(const Matrix3 &mat, const Vector3 &scaleVec); // Prepend (pre-multiply) a scale transformation to a 3x3 matrix -// NOTE: +// NOTE: // Faster than creating and multiplying a scale transformation matrix. -// -inline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat ); +// +inline const Matrix3 prependScale(const Vector3 &scaleVec, const Matrix3 &mat); // Multiply two 3x3 matrices per element -// -inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ); +// +inline const Matrix3 mulPerElem(const Matrix3 &mat0, const Matrix3 &mat1); // Compute the absolute value of a 3x3 matrix per element -// -inline const Matrix3 absPerElem( const Matrix3 & mat ); +// +inline const Matrix3 absPerElem(const Matrix3 &mat); // Transpose of a 3x3 matrix -// -inline const Matrix3 transpose( const Matrix3 & mat ); +// +inline const Matrix3 transpose(const Matrix3 &mat); // Compute the inverse of a 3x3 matrix -// NOTE: +// NOTE: // Result is unpredictable when the determinant of mat is equal to or near 0. -// -inline const Matrix3 inverse( const Matrix3 & mat ); +// +inline const Matrix3 inverse(const Matrix3 &mat); // Determinant of a 3x3 matrix -// -inline float determinant( const Matrix3 & mat ); +// +inline float determinant(const Matrix3 &mat); // Conditionally select between two 3x3 matrices -// -inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ); +// +inline const Matrix3 select(const Matrix3 &mat0, const Matrix3 &mat1, bool select1); #ifdef _VECTORMATH_DEBUG // Print a 3x3 matrix -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Matrix3 & mat ); +// +inline void print(const Matrix3 &mat); // Print a 3x3 matrix and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Matrix3 & mat, const char * name ); +// +inline void print(const Matrix3 &mat, const char *name); #endif @@ -1355,304 +1354,303 @@ inline void print( const Matrix3 & mat, const char * name ); // class Matrix4 { - Vector4 mCol0; - Vector4 mCol1; - Vector4 mCol2; - Vector4 mCol3; + Vector4 mCol0; + Vector4 mCol1; + Vector4 mCol2; + Vector4 mCol3; public: - // Default constructor; does no initialization - // - inline Matrix4( ) { }; + // Default constructor; does no initialization + // + inline Matrix4(){}; - // Copy a 4x4 matrix - // - inline Matrix4( const Matrix4 & mat ); + // Copy a 4x4 matrix + // + inline Matrix4(const Matrix4 &mat); - // Construct a 4x4 matrix containing the specified columns - // - inline Matrix4( const Vector4 & col0, const Vector4 & col1, const Vector4 & col2, const Vector4 & col3 ); + // Construct a 4x4 matrix containing the specified columns + // + inline Matrix4(const Vector4 &col0, const Vector4 &col1, const Vector4 &col2, const Vector4 &col3); - // Construct a 4x4 matrix from a 3x4 transformation matrix - // - explicit inline Matrix4( const Transform3 & mat ); + // Construct a 4x4 matrix from a 3x4 transformation matrix + // + explicit inline Matrix4(const Transform3 &mat); - // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector - // - inline Matrix4( const Matrix3 & mat, const Vector3 & translateVec ); + // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector + // + inline Matrix4(const Matrix3 &mat, const Vector3 &translateVec); - // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector - // - inline Matrix4( const Quat & unitQuat, const Vector3 & translateVec ); + // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector + // + inline Matrix4(const Quat &unitQuat, const Vector3 &translateVec); - // Set all elements of a 4x4 matrix to the same scalar value - // - explicit inline Matrix4( float scalar ); + // Set all elements of a 4x4 matrix to the same scalar value + // + explicit inline Matrix4(float scalar); - // Assign one 4x4 matrix to another - // - inline Matrix4 & operator =( const Matrix4 & mat ); + // Assign one 4x4 matrix to another + // + inline Matrix4 &operator=(const Matrix4 &mat); - // Set the upper-left 3x3 submatrix - // NOTE: - // This function does not change the bottom row elements. - // - inline Matrix4 & setUpper3x3( const Matrix3 & mat3 ); + // Set the upper-left 3x3 submatrix + // NOTE: + // This function does not change the bottom row elements. + // + inline Matrix4 &setUpper3x3(const Matrix3 &mat3); - // Get the upper-left 3x3 submatrix of a 4x4 matrix - // - inline const Matrix3 getUpper3x3( ) const; + // Get the upper-left 3x3 submatrix of a 4x4 matrix + // + inline const Matrix3 getUpper3x3() const; - // Set translation component - // NOTE: - // This function does not change the bottom row elements. - // - inline Matrix4 & setTranslation( const Vector3 & translateVec ); + // Set translation component + // NOTE: + // This function does not change the bottom row elements. + // + inline Matrix4 &setTranslation(const Vector3 &translateVec); - // Get the translation component of a 4x4 matrix - // - inline const Vector3 getTranslation( ) const; + // Get the translation component of a 4x4 matrix + // + inline const Vector3 getTranslation() const; - // Set column 0 of a 4x4 matrix - // - inline Matrix4 & setCol0( const Vector4 & col0 ); + // Set column 0 of a 4x4 matrix + // + inline Matrix4 &setCol0(const Vector4 &col0); - // Set column 1 of a 4x4 matrix - // - inline Matrix4 & setCol1( const Vector4 & col1 ); + // Set column 1 of a 4x4 matrix + // + inline Matrix4 &setCol1(const Vector4 &col1); - // Set column 2 of a 4x4 matrix - // - inline Matrix4 & setCol2( const Vector4 & col2 ); + // Set column 2 of a 4x4 matrix + // + inline Matrix4 &setCol2(const Vector4 &col2); - // Set column 3 of a 4x4 matrix - // - inline Matrix4 & setCol3( const Vector4 & col3 ); + // Set column 3 of a 4x4 matrix + // + inline Matrix4 &setCol3(const Vector4 &col3); - // Get column 0 of a 4x4 matrix - // - inline const Vector4 getCol0( ) const; + // Get column 0 of a 4x4 matrix + // + inline const Vector4 getCol0() const; - // Get column 1 of a 4x4 matrix - // - inline const Vector4 getCol1( ) const; + // Get column 1 of a 4x4 matrix + // + inline const Vector4 getCol1() const; - // Get column 2 of a 4x4 matrix - // - inline const Vector4 getCol2( ) const; + // Get column 2 of a 4x4 matrix + // + inline const Vector4 getCol2() const; - // Get column 3 of a 4x4 matrix - // - inline const Vector4 getCol3( ) const; + // Get column 3 of a 4x4 matrix + // + inline const Vector4 getCol3() const; - // Set the column of a 4x4 matrix referred to by the specified index - // - inline Matrix4 & setCol( int col, const Vector4 & vec ); + // Set the column of a 4x4 matrix referred to by the specified index + // + inline Matrix4 &setCol(int col, const Vector4 &vec); - // Set the row of a 4x4 matrix referred to by the specified index - // - inline Matrix4 & setRow( int row, const Vector4 & vec ); + // Set the row of a 4x4 matrix referred to by the specified index + // + inline Matrix4 &setRow(int row, const Vector4 &vec); - // Get the column of a 4x4 matrix referred to by the specified index - // - inline const Vector4 getCol( int col ) const; + // Get the column of a 4x4 matrix referred to by the specified index + // + inline const Vector4 getCol(int col) const; - // Get the row of a 4x4 matrix referred to by the specified index - // - inline const Vector4 getRow( int row ) const; + // Get the row of a 4x4 matrix referred to by the specified index + // + inline const Vector4 getRow(int row) const; - // Subscripting operator to set or get a column - // - inline Vector4 & operator []( int col ); + // Subscripting operator to set or get a column + // + inline Vector4 &operator[](int col); - // Subscripting operator to get a column - // - inline const Vector4 operator []( int col ) const; + // Subscripting operator to get a column + // + inline const Vector4 operator[](int col) const; - // Set the element of a 4x4 matrix referred to by column and row indices - // - inline Matrix4 & setElem( int col, int row, float val ); + // Set the element of a 4x4 matrix referred to by column and row indices + // + inline Matrix4 &setElem(int col, int row, float val); - // Get the element of a 4x4 matrix referred to by column and row indices - // - inline float getElem( int col, int row ) const; + // Get the element of a 4x4 matrix referred to by column and row indices + // + inline float getElem(int col, int row) const; - // Add two 4x4 matrices - // - inline const Matrix4 operator +( const Matrix4 & mat ) const; + // Add two 4x4 matrices + // + inline const Matrix4 operator+(const Matrix4 &mat) const; - // Subtract a 4x4 matrix from another 4x4 matrix - // - inline const Matrix4 operator -( const Matrix4 & mat ) const; + // Subtract a 4x4 matrix from another 4x4 matrix + // + inline const Matrix4 operator-(const Matrix4 &mat) const; - // Negate all elements of a 4x4 matrix - // - inline const Matrix4 operator -( ) const; + // Negate all elements of a 4x4 matrix + // + inline const Matrix4 operator-() const; - // Multiply a 4x4 matrix by a scalar - // - inline const Matrix4 operator *( float scalar ) const; + // Multiply a 4x4 matrix by a scalar + // + inline const Matrix4 operator*(float scalar) const; - // Multiply a 4x4 matrix by a 4-D vector - // - inline const Vector4 operator *( const Vector4 & vec ) const; + // Multiply a 4x4 matrix by a 4-D vector + // + inline const Vector4 operator*(const Vector4 &vec) const; - // Multiply a 4x4 matrix by a 3-D vector - // - inline const Vector4 operator *( const Vector3 & vec ) const; + // Multiply a 4x4 matrix by a 3-D vector + // + inline const Vector4 operator*(const Vector3 &vec) const; - // Multiply a 4x4 matrix by a 3-D point - // - inline const Vector4 operator *( const Point3 & pnt ) const; + // Multiply a 4x4 matrix by a 3-D point + // + inline const Vector4 operator*(const Point3 &pnt) const; - // Multiply two 4x4 matrices - // - inline const Matrix4 operator *( const Matrix4 & mat ) const; + // Multiply two 4x4 matrices + // + inline const Matrix4 operator*(const Matrix4 &mat) const; - // Multiply a 4x4 matrix by a 3x4 transformation matrix - // - inline const Matrix4 operator *( const Transform3 & tfrm ) const; + // Multiply a 4x4 matrix by a 3x4 transformation matrix + // + inline const Matrix4 operator*(const Transform3 &tfrm) const; - // Perform compound assignment and addition with a 4x4 matrix - // - inline Matrix4 & operator +=( const Matrix4 & mat ); + // Perform compound assignment and addition with a 4x4 matrix + // + inline Matrix4 &operator+=(const Matrix4 &mat); - // Perform compound assignment and subtraction by a 4x4 matrix - // - inline Matrix4 & operator -=( const Matrix4 & mat ); + // Perform compound assignment and subtraction by a 4x4 matrix + // + inline Matrix4 &operator-=(const Matrix4 &mat); - // Perform compound assignment and multiplication by a scalar - // - inline Matrix4 & operator *=( float scalar ); + // Perform compound assignment and multiplication by a scalar + // + inline Matrix4 &operator*=(float scalar); - // Perform compound assignment and multiplication by a 4x4 matrix - // - inline Matrix4 & operator *=( const Matrix4 & mat ); + // Perform compound assignment and multiplication by a 4x4 matrix + // + inline Matrix4 &operator*=(const Matrix4 &mat); - // Perform compound assignment and multiplication by a 3x4 transformation matrix - // - inline Matrix4 & operator *=( const Transform3 & tfrm ); + // Perform compound assignment and multiplication by a 3x4 transformation matrix + // + inline Matrix4 &operator*=(const Transform3 &tfrm); - // Construct an identity 4x4 matrix - // - static inline const Matrix4 identity( ); + // Construct an identity 4x4 matrix + // + static inline const Matrix4 identity(); - // Construct a 4x4 matrix to rotate around the x axis - // - static inline const Matrix4 rotationX( float radians ); + // Construct a 4x4 matrix to rotate around the x axis + // + static inline const Matrix4 rotationX(float radians); - // Construct a 4x4 matrix to rotate around the y axis - // - static inline const Matrix4 rotationY( float radians ); + // Construct a 4x4 matrix to rotate around the y axis + // + static inline const Matrix4 rotationY(float radians); - // Construct a 4x4 matrix to rotate around the z axis - // - static inline const Matrix4 rotationZ( float radians ); + // Construct a 4x4 matrix to rotate around the z axis + // + static inline const Matrix4 rotationZ(float radians); - // Construct a 4x4 matrix to rotate around the x, y, and z axes - // - static inline const Matrix4 rotationZYX( const Vector3 & radiansXYZ ); + // Construct a 4x4 matrix to rotate around the x, y, and z axes + // + static inline const Matrix4 rotationZYX(const Vector3 &radiansXYZ); - // Construct a 4x4 matrix to rotate around a unit-length 3-D vector - // - static inline const Matrix4 rotation( float radians, const Vector3 & unitVec ); + // Construct a 4x4 matrix to rotate around a unit-length 3-D vector + // + static inline const Matrix4 rotation(float radians, const Vector3 &unitVec); - // Construct a rotation matrix from a unit-length quaternion - // - static inline const Matrix4 rotation( const Quat & unitQuat ); + // Construct a rotation matrix from a unit-length quaternion + // + static inline const Matrix4 rotation(const Quat &unitQuat); - // Construct a 4x4 matrix to perform scaling - // - static inline const Matrix4 scale( const Vector3 & scaleVec ); + // Construct a 4x4 matrix to perform scaling + // + static inline const Matrix4 scale(const Vector3 &scaleVec); - // Construct a 4x4 matrix to perform translation - // - static inline const Matrix4 translation( const Vector3 & translateVec ); + // Construct a 4x4 matrix to perform translation + // + static inline const Matrix4 translation(const Vector3 &translateVec); - // Construct viewing matrix based on eye position, position looked at, and up direction - // - static inline const Matrix4 lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec ); + // Construct viewing matrix based on eye position, position looked at, and up direction + // + static inline const Matrix4 lookAt(const Point3 &eyePos, const Point3 &lookAtPos, const Vector3 &upVec); - // Construct a perspective projection matrix - // - static inline const Matrix4 perspective( float fovyRadians, float aspect, float zNear, float zFar ); + // Construct a perspective projection matrix + // + static inline const Matrix4 perspective(float fovyRadians, float aspect, float zNear, float zFar); - // Construct a perspective projection matrix based on frustum - // - static inline const Matrix4 frustum( float left, float right, float bottom, float top, float zNear, float zFar ); - - // Construct an orthographic projection matrix - // - static inline const Matrix4 orthographic( float left, float right, float bottom, float top, float zNear, float zFar ); + // Construct a perspective projection matrix based on frustum + // + static inline const Matrix4 frustum(float left, float right, float bottom, float top, float zNear, float zFar); + // Construct an orthographic projection matrix + // + static inline const Matrix4 orthographic(float left, float right, float bottom, float top, float zNear, float zFar); }; // Multiply a 4x4 matrix by a scalar -// -inline const Matrix4 operator *( float scalar, const Matrix4 & mat ); +// +inline const Matrix4 operator*(float scalar, const Matrix4 &mat); // Append (post-multiply) a scale transformation to a 4x4 matrix -// NOTE: +// NOTE: // Faster than creating and multiplying a scale transformation matrix. -// -inline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec ); +// +inline const Matrix4 appendScale(const Matrix4 &mat, const Vector3 &scaleVec); // Prepend (pre-multiply) a scale transformation to a 4x4 matrix -// NOTE: +// NOTE: // Faster than creating and multiplying a scale transformation matrix. -// -inline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat ); +// +inline const Matrix4 prependScale(const Vector3 &scaleVec, const Matrix4 &mat); // Multiply two 4x4 matrices per element -// -inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ); +// +inline const Matrix4 mulPerElem(const Matrix4 &mat0, const Matrix4 &mat1); // Compute the absolute value of a 4x4 matrix per element -// -inline const Matrix4 absPerElem( const Matrix4 & mat ); +// +inline const Matrix4 absPerElem(const Matrix4 &mat); // Transpose of a 4x4 matrix -// -inline const Matrix4 transpose( const Matrix4 & mat ); +// +inline const Matrix4 transpose(const Matrix4 &mat); // Compute the inverse of a 4x4 matrix -// NOTE: +// NOTE: // Result is unpredictable when the determinant of mat is equal to or near 0. -// -inline const Matrix4 inverse( const Matrix4 & mat ); +// +inline const Matrix4 inverse(const Matrix4 &mat); // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix -// NOTE: +// NOTE: // This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. The result is unpredictable when the determinant of mat is equal to or near 0. -// -inline const Matrix4 affineInverse( const Matrix4 & mat ); +// +inline const Matrix4 affineInverse(const Matrix4 &mat); // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix -// NOTE: +// NOTE: // This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. -// -inline const Matrix4 orthoInverse( const Matrix4 & mat ); +// +inline const Matrix4 orthoInverse(const Matrix4 &mat); // Determinant of a 4x4 matrix -// -inline float determinant( const Matrix4 & mat ); +// +inline float determinant(const Matrix4 &mat); // Conditionally select between two 4x4 matrices -// -inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ); +// +inline const Matrix4 select(const Matrix4 &mat0, const Matrix4 &mat1, bool select1); #ifdef _VECTORMATH_DEBUG // Print a 4x4 matrix -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Matrix4 & mat ); +// +inline void print(const Matrix4 &mat); // Print a 4x4 matrix and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Matrix4 & mat, const char * name ); +// +inline void print(const Matrix4 &mat, const char *name); #endif @@ -1660,231 +1658,229 @@ inline void print( const Matrix4 & mat, const char * name ); // class Transform3 { - Vector3 mCol0; - Vector3 mCol1; - Vector3 mCol2; - Vector3 mCol3; + Vector3 mCol0; + Vector3 mCol1; + Vector3 mCol2; + Vector3 mCol3; public: - // Default constructor; does no initialization - // - inline Transform3( ) { }; + // Default constructor; does no initialization + // + inline Transform3(){}; - // Copy a 3x4 transformation matrix - // - inline Transform3( const Transform3 & tfrm ); + // Copy a 3x4 transformation matrix + // + inline Transform3(const Transform3 &tfrm); - // Construct a 3x4 transformation matrix containing the specified columns - // - inline Transform3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2, const Vector3 & col3 ); + // Construct a 3x4 transformation matrix containing the specified columns + // + inline Transform3(const Vector3 &col0, const Vector3 &col1, const Vector3 &col2, const Vector3 &col3); - // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector - // - inline Transform3( const Matrix3 & tfrm, const Vector3 & translateVec ); + // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector + // + inline Transform3(const Matrix3 &tfrm, const Vector3 &translateVec); - // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector - // - inline Transform3( const Quat & unitQuat, const Vector3 & translateVec ); + // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector + // + inline Transform3(const Quat &unitQuat, const Vector3 &translateVec); - // Set all elements of a 3x4 transformation matrix to the same scalar value - // - explicit inline Transform3( float scalar ); + // Set all elements of a 3x4 transformation matrix to the same scalar value + // + explicit inline Transform3(float scalar); - // Assign one 3x4 transformation matrix to another - // - inline Transform3 & operator =( const Transform3 & tfrm ); + // Assign one 3x4 transformation matrix to another + // + inline Transform3 &operator=(const Transform3 &tfrm); - // Set the upper-left 3x3 submatrix - // - inline Transform3 & setUpper3x3( const Matrix3 & mat3 ); + // Set the upper-left 3x3 submatrix + // + inline Transform3 &setUpper3x3(const Matrix3 &mat3); - // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix - // - inline const Matrix3 getUpper3x3( ) const; + // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix + // + inline const Matrix3 getUpper3x3() const; - // Set translation component - // - inline Transform3 & setTranslation( const Vector3 & translateVec ); + // Set translation component + // + inline Transform3 &setTranslation(const Vector3 &translateVec); - // Get the translation component of a 3x4 transformation matrix - // - inline const Vector3 getTranslation( ) const; + // Get the translation component of a 3x4 transformation matrix + // + inline const Vector3 getTranslation() const; - // Set column 0 of a 3x4 transformation matrix - // - inline Transform3 & setCol0( const Vector3 & col0 ); + // Set column 0 of a 3x4 transformation matrix + // + inline Transform3 &setCol0(const Vector3 &col0); - // Set column 1 of a 3x4 transformation matrix - // - inline Transform3 & setCol1( const Vector3 & col1 ); + // Set column 1 of a 3x4 transformation matrix + // + inline Transform3 &setCol1(const Vector3 &col1); - // Set column 2 of a 3x4 transformation matrix - // - inline Transform3 & setCol2( const Vector3 & col2 ); + // Set column 2 of a 3x4 transformation matrix + // + inline Transform3 &setCol2(const Vector3 &col2); - // Set column 3 of a 3x4 transformation matrix - // - inline Transform3 & setCol3( const Vector3 & col3 ); + // Set column 3 of a 3x4 transformation matrix + // + inline Transform3 &setCol3(const Vector3 &col3); - // Get column 0 of a 3x4 transformation matrix - // - inline const Vector3 getCol0( ) const; + // Get column 0 of a 3x4 transformation matrix + // + inline const Vector3 getCol0() const; - // Get column 1 of a 3x4 transformation matrix - // - inline const Vector3 getCol1( ) const; + // Get column 1 of a 3x4 transformation matrix + // + inline const Vector3 getCol1() const; - // Get column 2 of a 3x4 transformation matrix - // - inline const Vector3 getCol2( ) const; + // Get column 2 of a 3x4 transformation matrix + // + inline const Vector3 getCol2() const; - // Get column 3 of a 3x4 transformation matrix - // - inline const Vector3 getCol3( ) const; + // Get column 3 of a 3x4 transformation matrix + // + inline const Vector3 getCol3() const; - // Set the column of a 3x4 transformation matrix referred to by the specified index - // - inline Transform3 & setCol( int col, const Vector3 & vec ); + // Set the column of a 3x4 transformation matrix referred to by the specified index + // + inline Transform3 &setCol(int col, const Vector3 &vec); - // Set the row of a 3x4 transformation matrix referred to by the specified index - // - inline Transform3 & setRow( int row, const Vector4 & vec ); + // Set the row of a 3x4 transformation matrix referred to by the specified index + // + inline Transform3 &setRow(int row, const Vector4 &vec); - // Get the column of a 3x4 transformation matrix referred to by the specified index - // - inline const Vector3 getCol( int col ) const; + // Get the column of a 3x4 transformation matrix referred to by the specified index + // + inline const Vector3 getCol(int col) const; - // Get the row of a 3x4 transformation matrix referred to by the specified index - // - inline const Vector4 getRow( int row ) const; + // Get the row of a 3x4 transformation matrix referred to by the specified index + // + inline const Vector4 getRow(int row) const; - // Subscripting operator to set or get a column - // - inline Vector3 & operator []( int col ); + // Subscripting operator to set or get a column + // + inline Vector3 &operator[](int col); - // Subscripting operator to get a column - // - inline const Vector3 operator []( int col ) const; + // Subscripting operator to get a column + // + inline const Vector3 operator[](int col) const; - // Set the element of a 3x4 transformation matrix referred to by column and row indices - // - inline Transform3 & setElem( int col, int row, float val ); + // Set the element of a 3x4 transformation matrix referred to by column and row indices + // + inline Transform3 &setElem(int col, int row, float val); - // Get the element of a 3x4 transformation matrix referred to by column and row indices - // - inline float getElem( int col, int row ) const; + // Get the element of a 3x4 transformation matrix referred to by column and row indices + // + inline float getElem(int col, int row) const; - // Multiply a 3x4 transformation matrix by a 3-D vector - // - inline const Vector3 operator *( const Vector3 & vec ) const; + // Multiply a 3x4 transformation matrix by a 3-D vector + // + inline const Vector3 operator*(const Vector3 &vec) const; - // Multiply a 3x4 transformation matrix by a 3-D point - // - inline const Point3 operator *( const Point3 & pnt ) const; + // Multiply a 3x4 transformation matrix by a 3-D point + // + inline const Point3 operator*(const Point3 &pnt) const; - // Multiply two 3x4 transformation matrices - // - inline const Transform3 operator *( const Transform3 & tfrm ) const; + // Multiply two 3x4 transformation matrices + // + inline const Transform3 operator*(const Transform3 &tfrm) const; - // Perform compound assignment and multiplication by a 3x4 transformation matrix - // - inline Transform3 & operator *=( const Transform3 & tfrm ); + // Perform compound assignment and multiplication by a 3x4 transformation matrix + // + inline Transform3 &operator*=(const Transform3 &tfrm); - // Construct an identity 3x4 transformation matrix - // - static inline const Transform3 identity( ); + // Construct an identity 3x4 transformation matrix + // + static inline const Transform3 identity(); - // Construct a 3x4 transformation matrix to rotate around the x axis - // - static inline const Transform3 rotationX( float radians ); + // Construct a 3x4 transformation matrix to rotate around the x axis + // + static inline const Transform3 rotationX(float radians); - // Construct a 3x4 transformation matrix to rotate around the y axis - // - static inline const Transform3 rotationY( float radians ); + // Construct a 3x4 transformation matrix to rotate around the y axis + // + static inline const Transform3 rotationY(float radians); - // Construct a 3x4 transformation matrix to rotate around the z axis - // - static inline const Transform3 rotationZ( float radians ); + // Construct a 3x4 transformation matrix to rotate around the z axis + // + static inline const Transform3 rotationZ(float radians); - // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes - // - static inline const Transform3 rotationZYX( const Vector3 & radiansXYZ ); + // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes + // + static inline const Transform3 rotationZYX(const Vector3 &radiansXYZ); - // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector - // - static inline const Transform3 rotation( float radians, const Vector3 & unitVec ); + // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector + // + static inline const Transform3 rotation(float radians, const Vector3 &unitVec); - // Construct a rotation matrix from a unit-length quaternion - // - static inline const Transform3 rotation( const Quat & unitQuat ); + // Construct a rotation matrix from a unit-length quaternion + // + static inline const Transform3 rotation(const Quat &unitQuat); - // Construct a 3x4 transformation matrix to perform scaling - // - static inline const Transform3 scale( const Vector3 & scaleVec ); - - // Construct a 3x4 transformation matrix to perform translation - // - static inline const Transform3 translation( const Vector3 & translateVec ); + // Construct a 3x4 transformation matrix to perform scaling + // + static inline const Transform3 scale(const Vector3 &scaleVec); + // Construct a 3x4 transformation matrix to perform translation + // + static inline const Transform3 translation(const Vector3 &translateVec); }; // Append (post-multiply) a scale transformation to a 3x4 transformation matrix -// NOTE: +// NOTE: // Faster than creating and multiplying a scale transformation matrix. -// -inline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec ); +// +inline const Transform3 appendScale(const Transform3 &tfrm, const Vector3 &scaleVec); // Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix -// NOTE: +// NOTE: // Faster than creating and multiplying a scale transformation matrix. -// -inline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm ); +// +inline const Transform3 prependScale(const Vector3 &scaleVec, const Transform3 &tfrm); // Multiply two 3x4 transformation matrices per element -// -inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ); +// +inline const Transform3 mulPerElem(const Transform3 &tfrm0, const Transform3 &tfrm1); // Compute the absolute value of a 3x4 transformation matrix per element -// -inline const Transform3 absPerElem( const Transform3 & tfrm ); +// +inline const Transform3 absPerElem(const Transform3 &tfrm); // Inverse of a 3x4 transformation matrix -// NOTE: +// NOTE: // Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. -// -inline const Transform3 inverse( const Transform3 & tfrm ); +// +inline const Transform3 inverse(const Transform3 &tfrm); // Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix -// NOTE: +// NOTE: // This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. -// -inline const Transform3 orthoInverse( const Transform3 & tfrm ); +// +inline const Transform3 orthoInverse(const Transform3 &tfrm); // Conditionally select between two 3x4 transformation matrices -// -inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ); +// +inline const Transform3 select(const Transform3 &tfrm0, const Transform3 &tfrm1, bool select1); #ifdef _VECTORMATH_DEBUG // Print a 3x4 transformation matrix -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Transform3 & tfrm ); +// +inline void print(const Transform3 &tfrm); // Print a 3x4 transformation matrix and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Transform3 & tfrm, const char * name ); +// +inline void print(const Transform3 &tfrm, const char *name); #endif -} // namespace Aos -} // namespace Vectormath +} // namespace Aos +} // namespace Vectormath #include "vec_aos.h" #include "quat_aos.h" #include "mat_aos.h" #endif - diff --git a/test/Bullet2/vectormath/scalar/boolInVec.h b/test/Bullet2/vectormath/scalar/boolInVec.h index c5eeeebd7..cf67923bf 100644 --- a/test/Bullet2/vectormath/scalar/boolInVec.h +++ b/test/Bullet2/vectormath/scalar/boolInVec.h @@ -18,8 +18,8 @@ subject to the following restrictions: #define _BOOLINVEC_H #include -namespace Vectormath { - +namespace Vectormath +{ class floatInVec; //-------------------------------------------------------------------------------------------------- @@ -29,80 +29,77 @@ class floatInVec; class boolInVec { private: - unsigned int mData; + unsigned int mData; public: - // Default constructor; does no initialization - // - inline boolInVec( ) { }; + // Default constructor; does no initialization + // + inline boolInVec(){}; - // Construct from a value converted from float - // - inline boolInVec(floatInVec vec); + // Construct from a value converted from float + // + inline boolInVec(floatInVec vec); - // Explicit cast from bool - // - explicit inline boolInVec(bool scalar); + // Explicit cast from bool + // + explicit inline boolInVec(bool scalar); - // Explicit cast to bool - // - inline bool getAsBool() const; + // Explicit cast to bool + // + inline bool getAsBool() const; #ifndef _VECTORMATH_NO_SCALAR_CAST - // Implicit cast to bool - // - inline operator bool() const; + // Implicit cast to bool + // + inline operator bool() const; #endif - // Boolean negation operator - // - inline const boolInVec operator ! () const; + // Boolean negation operator + // + inline const boolInVec operator!() const; - // Assignment operator - // - inline boolInVec& operator = (boolInVec vec); + // Assignment operator + // + inline boolInVec& operator=(boolInVec vec); - // Boolean and assignment operator - // - inline boolInVec& operator &= (boolInVec vec); + // Boolean and assignment operator + // + inline boolInVec& operator&=(boolInVec vec); - // Boolean exclusive or assignment operator - // - inline boolInVec& operator ^= (boolInVec vec); - - // Boolean or assignment operator - // - inline boolInVec& operator |= (boolInVec vec); + // Boolean exclusive or assignment operator + // + inline boolInVec& operator^=(boolInVec vec); + // Boolean or assignment operator + // + inline boolInVec& operator|=(boolInVec vec); }; // Equal operator // -inline const boolInVec operator == (boolInVec vec0, boolInVec vec1); +inline const boolInVec operator==(boolInVec vec0, boolInVec vec1); // Not equal operator // -inline const boolInVec operator != (boolInVec vec0, boolInVec vec1); +inline const boolInVec operator!=(boolInVec vec0, boolInVec vec1); // And operator // -inline const boolInVec operator & (boolInVec vec0, boolInVec vec1); +inline const boolInVec operator&(boolInVec vec0, boolInVec vec1); // Exclusive or operator // -inline const boolInVec operator ^ (boolInVec vec0, boolInVec vec1); +inline const boolInVec operator^(boolInVec vec0, boolInVec vec1); // Or operator // -inline const boolInVec operator | (boolInVec vec0, boolInVec vec1); +inline const boolInVec operator|(boolInVec vec0, boolInVec vec1); // Conditionally select between two values // inline const boolInVec select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1); - -} // namespace Vectormath - +} // namespace Vectormath //-------------------------------------------------------------------------------------------------- // boolInVec implementation @@ -110,116 +107,101 @@ inline const boolInVec select(boolInVec vec0, boolInVec vec1, boolInVec select_v #include "floatInVec.h" -namespace Vectormath { - -inline -boolInVec::boolInVec(floatInVec vec) +namespace Vectormath { - *this = (vec != floatInVec(0.0f)); +inline boolInVec::boolInVec(floatInVec vec) +{ + *this = (vec != floatInVec(0.0f)); } -inline -boolInVec::boolInVec(bool scalar) +inline boolInVec::boolInVec(bool scalar) { - mData = -(int)scalar; + mData = -(int)scalar; } -inline -bool +inline bool boolInVec::getAsBool() const { - return (mData > 0); + return (mData > 0); } #ifndef _VECTORMATH_NO_SCALAR_CAST -inline -boolInVec::operator bool() const +inline boolInVec::operator bool() const { - return getAsBool(); + return getAsBool(); } #endif -inline -const boolInVec -boolInVec::operator ! () const +inline const boolInVec +boolInVec::operator!() const { - return boolInVec(!mData); + return boolInVec(!mData); } -inline -boolInVec& -boolInVec::operator = (boolInVec vec) +inline boolInVec& +boolInVec::operator=(boolInVec vec) { - mData = vec.mData; - return *this; + mData = vec.mData; + return *this; } -inline -boolInVec& -boolInVec::operator &= (boolInVec vec) +inline boolInVec& +boolInVec::operator&=(boolInVec vec) { - *this = *this & vec; - return *this; + *this = *this & vec; + return *this; } -inline -boolInVec& -boolInVec::operator ^= (boolInVec vec) +inline boolInVec& +boolInVec::operator^=(boolInVec vec) { - *this = *this ^ vec; - return *this; + *this = *this ^ vec; + return *this; } -inline -boolInVec& -boolInVec::operator |= (boolInVec vec) +inline boolInVec& +boolInVec::operator|=(boolInVec vec) { - *this = *this | vec; - return *this; + *this = *this | vec; + return *this; } -inline -const boolInVec -operator == (boolInVec vec0, boolInVec vec1) +inline const boolInVec +operator==(boolInVec vec0, boolInVec vec1) { - return boolInVec(vec0.getAsBool() == vec1.getAsBool()); + return boolInVec(vec0.getAsBool() == vec1.getAsBool()); } -inline -const boolInVec -operator != (boolInVec vec0, boolInVec vec1) +inline const boolInVec +operator!=(boolInVec vec0, boolInVec vec1) { - return !(vec0 == vec1); + return !(vec0 == vec1); } -inline -const boolInVec -operator & (boolInVec vec0, boolInVec vec1) +inline const boolInVec +operator&(boolInVec vec0, boolInVec vec1) { - return boolInVec(vec0.getAsBool() & vec1.getAsBool()); + return boolInVec(vec0.getAsBool() & vec1.getAsBool()); } -inline -const boolInVec -operator | (boolInVec vec0, boolInVec vec1) +inline const boolInVec +operator|(boolInVec vec0, boolInVec vec1) { - return boolInVec(vec0.getAsBool() | vec1.getAsBool()); + return boolInVec(vec0.getAsBool() | vec1.getAsBool()); } -inline -const boolInVec -operator ^ (boolInVec vec0, boolInVec vec1) +inline const boolInVec +operator^(boolInVec vec0, boolInVec vec1) { - return boolInVec(vec0.getAsBool() ^ vec1.getAsBool()); + return boolInVec(vec0.getAsBool() ^ vec1.getAsBool()); } -inline -const boolInVec +inline const boolInVec select(boolInVec vec0, boolInVec vec1, boolInVec select_vec1) { - return (select_vec1.getAsBool() == 0) ? vec0 : vec1; + return (select_vec1.getAsBool() == 0) ? vec0 : vec1; } -} // namespace Vectormath +} // namespace Vectormath -#endif // boolInVec_h +#endif // boolInVec_h diff --git a/test/Bullet2/vectormath/scalar/floatInVec.h b/test/Bullet2/vectormath/scalar/floatInVec.h index 12d89e43d..7a3c2849c 100644 --- a/test/Bullet2/vectormath/scalar/floatInVec.h +++ b/test/Bullet2/vectormath/scalar/floatInVec.h @@ -17,8 +17,8 @@ subject to the following restrictions: #define _FLOATINVEC_H #include -namespace Vectormath { - +namespace Vectormath +{ class boolInVec; //-------------------------------------------------------------------------------------------------- @@ -30,120 +30,117 @@ class boolInVec; class floatInVec { private: - float mData; + float mData; public: - // Default constructor; does no initialization - // - inline floatInVec( ) { }; + // Default constructor; does no initialization + // + inline floatInVec(){}; - // Construct from a value converted from bool - // - inline floatInVec(boolInVec vec); + // Construct from a value converted from bool + // + inline floatInVec(boolInVec vec); - // Explicit cast from float - // - explicit inline floatInVec(float scalar); + // Explicit cast from float + // + explicit inline floatInVec(float scalar); - // Explicit cast to float - // - inline float getAsFloat() const; + // Explicit cast to float + // + inline float getAsFloat() const; #ifndef _VECTORMATH_NO_SCALAR_CAST - // Implicit cast to float - // - inline operator float() const; + // Implicit cast to float + // + inline operator float() const; #endif - // Post increment (add 1.0f) - // - inline const floatInVec operator ++ (int); + // Post increment (add 1.0f) + // + inline const floatInVec operator++(int); - // Post decrement (subtract 1.0f) - // - inline const floatInVec operator -- (int); + // Post decrement (subtract 1.0f) + // + inline const floatInVec operator--(int); - // Pre increment (add 1.0f) - // - inline floatInVec& operator ++ (); + // Pre increment (add 1.0f) + // + inline floatInVec& operator++(); - // Pre decrement (subtract 1.0f) - // - inline floatInVec& operator -- (); + // Pre decrement (subtract 1.0f) + // + inline floatInVec& operator--(); - // Negation operator - // - inline const floatInVec operator - () const; + // Negation operator + // + inline const floatInVec operator-() const; - // Assignment operator - // - inline floatInVec& operator = (floatInVec vec); + // Assignment operator + // + inline floatInVec& operator=(floatInVec vec); - // Multiplication assignment operator - // - inline floatInVec& operator *= (floatInVec vec); + // Multiplication assignment operator + // + inline floatInVec& operator*=(floatInVec vec); - // Division assignment operator - // - inline floatInVec& operator /= (floatInVec vec); + // Division assignment operator + // + inline floatInVec& operator/=(floatInVec vec); - // Addition assignment operator - // - inline floatInVec& operator += (floatInVec vec); - - // Subtraction assignment operator - // - inline floatInVec& operator -= (floatInVec vec); + // Addition assignment operator + // + inline floatInVec& operator+=(floatInVec vec); + // Subtraction assignment operator + // + inline floatInVec& operator-=(floatInVec vec); }; // Multiplication operator // -inline const floatInVec operator * (floatInVec vec0, floatInVec vec1); +inline const floatInVec operator*(floatInVec vec0, floatInVec vec1); // Division operator // -inline const floatInVec operator / (floatInVec vec0, floatInVec vec1); +inline const floatInVec operator/(floatInVec vec0, floatInVec vec1); // Addition operator // -inline const floatInVec operator + (floatInVec vec0, floatInVec vec1); +inline const floatInVec operator+(floatInVec vec0, floatInVec vec1); // Subtraction operator // -inline const floatInVec operator - (floatInVec vec0, floatInVec vec1); +inline const floatInVec operator-(floatInVec vec0, floatInVec vec1); // Less than operator // -inline const boolInVec operator < (floatInVec vec0, floatInVec vec1); +inline const boolInVec operator<(floatInVec vec0, floatInVec vec1); // Less than or equal operator // -inline const boolInVec operator <= (floatInVec vec0, floatInVec vec1); +inline const boolInVec operator<=(floatInVec vec0, floatInVec vec1); // Greater than operator // -inline const boolInVec operator > (floatInVec vec0, floatInVec vec1); +inline const boolInVec operator>(floatInVec vec0, floatInVec vec1); // Greater than or equal operator // -inline const boolInVec operator >= (floatInVec vec0, floatInVec vec1); +inline const boolInVec operator>=(floatInVec vec0, floatInVec vec1); // Equal operator // -inline const boolInVec operator == (floatInVec vec0, floatInVec vec1); +inline const boolInVec operator==(floatInVec vec0, floatInVec vec1); // Not equal operator // -inline const boolInVec operator != (floatInVec vec0, floatInVec vec1); +inline const boolInVec operator!=(floatInVec vec0, floatInVec vec1); // Conditionally select between two values // inline const floatInVec select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1); - -} // namespace Vectormath - +} // namespace Vectormath //-------------------------------------------------------------------------------------------------- // floatInVec implementation @@ -151,193 +148,168 @@ inline const floatInVec select(floatInVec vec0, floatInVec vec1, boolInVec selec #include "boolInVec.h" -namespace Vectormath { - -inline -floatInVec::floatInVec(boolInVec vec) +namespace Vectormath { - mData = float(vec.getAsBool()); +inline floatInVec::floatInVec(boolInVec vec) +{ + mData = float(vec.getAsBool()); } -inline -floatInVec::floatInVec(float scalar) +inline floatInVec::floatInVec(float scalar) { - mData = scalar; + mData = scalar; } -inline -float +inline float floatInVec::getAsFloat() const { - return mData; + return mData; } #ifndef _VECTORMATH_NO_SCALAR_CAST -inline -floatInVec::operator float() const +inline floatInVec::operator float() const { - return getAsFloat(); + return getAsFloat(); } #endif -inline -const floatInVec -floatInVec::operator ++ (int) +inline const floatInVec +floatInVec::operator++(int) { - float olddata = mData; - operator ++(); - return floatInVec(olddata); + float olddata = mData; + operator++(); + return floatInVec(olddata); } -inline -const floatInVec -floatInVec::operator -- (int) +inline const floatInVec +floatInVec::operator--(int) { - float olddata = mData; - operator --(); - return floatInVec(olddata); + float olddata = mData; + operator--(); + return floatInVec(olddata); } -inline -floatInVec& -floatInVec::operator ++ () +inline floatInVec& +floatInVec::operator++() { - *this += floatInVec(1.0f); - return *this; + *this += floatInVec(1.0f); + return *this; } -inline -floatInVec& -floatInVec::operator -- () +inline floatInVec& +floatInVec::operator--() { - *this -= floatInVec(1.0f); - return *this; + *this -= floatInVec(1.0f); + return *this; } -inline -const floatInVec -floatInVec::operator - () const +inline const floatInVec +floatInVec::operator-() const { - return floatInVec(-mData); + return floatInVec(-mData); } -inline -floatInVec& -floatInVec::operator = (floatInVec vec) +inline floatInVec& +floatInVec::operator=(floatInVec vec) { - mData = vec.mData; - return *this; + mData = vec.mData; + return *this; } -inline -floatInVec& -floatInVec::operator *= (floatInVec vec) +inline floatInVec& +floatInVec::operator*=(floatInVec vec) { - *this = *this * vec; - return *this; + *this = *this * vec; + return *this; } -inline -floatInVec& -floatInVec::operator /= (floatInVec vec) +inline floatInVec& +floatInVec::operator/=(floatInVec vec) { - *this = *this / vec; - return *this; + *this = *this / vec; + return *this; } -inline -floatInVec& -floatInVec::operator += (floatInVec vec) +inline floatInVec& +floatInVec::operator+=(floatInVec vec) { - *this = *this + vec; - return *this; + *this = *this + vec; + return *this; } -inline -floatInVec& -floatInVec::operator -= (floatInVec vec) +inline floatInVec& +floatInVec::operator-=(floatInVec vec) { - *this = *this - vec; - return *this; + *this = *this - vec; + return *this; } -inline -const floatInVec -operator * (floatInVec vec0, floatInVec vec1) +inline const floatInVec +operator*(floatInVec vec0, floatInVec vec1) { - return floatInVec(vec0.getAsFloat() * vec1.getAsFloat()); + return floatInVec(vec0.getAsFloat() * vec1.getAsFloat()); } -inline -const floatInVec -operator / (floatInVec num, floatInVec den) +inline const floatInVec +operator/(floatInVec num, floatInVec den) { - return floatInVec(num.getAsFloat() / den.getAsFloat()); + return floatInVec(num.getAsFloat() / den.getAsFloat()); } -inline -const floatInVec -operator + (floatInVec vec0, floatInVec vec1) +inline const floatInVec +operator+(floatInVec vec0, floatInVec vec1) { - return floatInVec(vec0.getAsFloat() + vec1.getAsFloat()); + return floatInVec(vec0.getAsFloat() + vec1.getAsFloat()); } -inline -const floatInVec -operator - (floatInVec vec0, floatInVec vec1) +inline const floatInVec +operator-(floatInVec vec0, floatInVec vec1) { - return floatInVec(vec0.getAsFloat() - vec1.getAsFloat()); + return floatInVec(vec0.getAsFloat() - vec1.getAsFloat()); } -inline -const boolInVec -operator < (floatInVec vec0, floatInVec vec1) +inline const boolInVec +operator<(floatInVec vec0, floatInVec vec1) { - return boolInVec(vec0.getAsFloat() < vec1.getAsFloat()); + return boolInVec(vec0.getAsFloat() < vec1.getAsFloat()); } -inline -const boolInVec -operator <= (floatInVec vec0, floatInVec vec1) +inline const boolInVec +operator<=(floatInVec vec0, floatInVec vec1) { - return !(vec0 > vec1); + return !(vec0 > vec1); } -inline -const boolInVec -operator > (floatInVec vec0, floatInVec vec1) +inline const boolInVec +operator>(floatInVec vec0, floatInVec vec1) { - return boolInVec(vec0.getAsFloat() > vec1.getAsFloat()); + return boolInVec(vec0.getAsFloat() > vec1.getAsFloat()); } -inline -const boolInVec -operator >= (floatInVec vec0, floatInVec vec1) +inline const boolInVec +operator>=(floatInVec vec0, floatInVec vec1) { - return !(vec0 < vec1); + return !(vec0 < vec1); } -inline -const boolInVec -operator == (floatInVec vec0, floatInVec vec1) +inline const boolInVec +operator==(floatInVec vec0, floatInVec vec1) { - return boolInVec(vec0.getAsFloat() == vec1.getAsFloat()); + return boolInVec(vec0.getAsFloat() == vec1.getAsFloat()); } -inline -const boolInVec -operator != (floatInVec vec0, floatInVec vec1) +inline const boolInVec +operator!=(floatInVec vec0, floatInVec vec1) { - return !(vec0 == vec1); + return !(vec0 == vec1); } -inline -const floatInVec +inline const floatInVec select(floatInVec vec0, floatInVec vec1, boolInVec select_vec1) { - return (select_vec1.getAsBool() == 0) ? vec0 : vec1; + return (select_vec1.getAsBool() == 0) ? vec0 : vec1; } -} // namespace Vectormath +} // namespace Vectormath -#endif // floatInVec_h +#endif // floatInVec_h diff --git a/test/Bullet2/vectormath/scalar/mat_aos.h b/test/Bullet2/vectormath/scalar/mat_aos.h index e103243d1..0ec54833a 100644 --- a/test/Bullet2/vectormath/scalar/mat_aos.h +++ b/test/Bullet2/vectormath/scalar/mat_aos.h @@ -17,9 +17,10 @@ subject to the following restrictions: #ifndef _VECTORMATH_MAT_AOS_CPP_H #define _VECTORMATH_MAT_AOS_CPP_H -namespace Vectormath { -namespace Aos { - +namespace Vectormath +{ +namespace Aos +{ //----------------------------------------------------------------------------- // Constants @@ -28,1603 +29,1534 @@ namespace Aos { //----------------------------------------------------------------------------- // Definitions -inline Matrix3::Matrix3( const Matrix3 & mat ) +inline Matrix3::Matrix3(const Matrix3 &mat) { - mCol0 = mat.mCol0; - mCol1 = mat.mCol1; - mCol2 = mat.mCol2; + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; } -inline Matrix3::Matrix3( float scalar ) +inline Matrix3::Matrix3(float scalar) { - mCol0 = Vector3( scalar ); - mCol1 = Vector3( scalar ); - mCol2 = Vector3( scalar ); + mCol0 = Vector3(scalar); + mCol1 = Vector3(scalar); + mCol2 = Vector3(scalar); } -inline Matrix3::Matrix3( const Quat & unitQuat ) +inline Matrix3::Matrix3(const Quat &unitQuat) { - float qx, qy, qz, qw, qx2, qy2, qz2, qxqx2, qyqy2, qzqz2, qxqy2, qyqz2, qzqw2, qxqz2, qyqw2, qxqw2; - qx = unitQuat.getX(); - qy = unitQuat.getY(); - qz = unitQuat.getZ(); - qw = unitQuat.getW(); - qx2 = ( qx + qx ); - qy2 = ( qy + qy ); - qz2 = ( qz + qz ); - qxqx2 = ( qx * qx2 ); - qxqy2 = ( qx * qy2 ); - qxqz2 = ( qx * qz2 ); - qxqw2 = ( qw * qx2 ); - qyqy2 = ( qy * qy2 ); - qyqz2 = ( qy * qz2 ); - qyqw2 = ( qw * qy2 ); - qzqz2 = ( qz * qz2 ); - qzqw2 = ( qw * qz2 ); - mCol0 = Vector3( ( ( 1.0f - qyqy2 ) - qzqz2 ), ( qxqy2 + qzqw2 ), ( qxqz2 - qyqw2 ) ); - mCol1 = Vector3( ( qxqy2 - qzqw2 ), ( ( 1.0f - qxqx2 ) - qzqz2 ), ( qyqz2 + qxqw2 ) ); - mCol2 = Vector3( ( qxqz2 + qyqw2 ), ( qyqz2 - qxqw2 ), ( ( 1.0f - qxqx2 ) - qyqy2 ) ); + float qx, qy, qz, qw, qx2, qy2, qz2, qxqx2, qyqy2, qzqz2, qxqy2, qyqz2, qzqw2, qxqz2, qyqw2, qxqw2; + qx = unitQuat.getX(); + qy = unitQuat.getY(); + qz = unitQuat.getZ(); + qw = unitQuat.getW(); + qx2 = (qx + qx); + qy2 = (qy + qy); + qz2 = (qz + qz); + qxqx2 = (qx * qx2); + qxqy2 = (qx * qy2); + qxqz2 = (qx * qz2); + qxqw2 = (qw * qx2); + qyqy2 = (qy * qy2); + qyqz2 = (qy * qz2); + qyqw2 = (qw * qy2); + qzqz2 = (qz * qz2); + qzqw2 = (qw * qz2); + mCol0 = Vector3(((1.0f - qyqy2) - qzqz2), (qxqy2 + qzqw2), (qxqz2 - qyqw2)); + mCol1 = Vector3((qxqy2 - qzqw2), ((1.0f - qxqx2) - qzqz2), (qyqz2 + qxqw2)); + mCol2 = Vector3((qxqz2 + qyqw2), (qyqz2 - qxqw2), ((1.0f - qxqx2) - qyqy2)); } -inline Matrix3::Matrix3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2 ) +inline Matrix3::Matrix3(const Vector3 &_col0, const Vector3 &_col1, const Vector3 &_col2) { - mCol0 = _col0; - mCol1 = _col1; - mCol2 = _col2; + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; } -inline Matrix3 & Matrix3::setCol0( const Vector3 & _col0 ) +inline Matrix3 &Matrix3::setCol0(const Vector3 &_col0) { - mCol0 = _col0; - return *this; + mCol0 = _col0; + return *this; } -inline Matrix3 & Matrix3::setCol1( const Vector3 & _col1 ) +inline Matrix3 &Matrix3::setCol1(const Vector3 &_col1) { - mCol1 = _col1; - return *this; + mCol1 = _col1; + return *this; } -inline Matrix3 & Matrix3::setCol2( const Vector3 & _col2 ) +inline Matrix3 &Matrix3::setCol2(const Vector3 &_col2) { - mCol2 = _col2; - return *this; + mCol2 = _col2; + return *this; } -inline Matrix3 & Matrix3::setCol( int col, const Vector3 & vec ) +inline Matrix3 &Matrix3::setCol(int col, const Vector3 &vec) { - *(&mCol0 + col) = vec; - return *this; + *(&mCol0 + col) = vec; + return *this; } -inline Matrix3 & Matrix3::setRow( int row, const Vector3 & vec ) +inline Matrix3 &Matrix3::setRow(int row, const Vector3 &vec) { - mCol0.setElem( row, vec.getElem( 0 ) ); - mCol1.setElem( row, vec.getElem( 1 ) ); - mCol2.setElem( row, vec.getElem( 2 ) ); - return *this; + mCol0.setElem(row, vec.getElem(0)); + mCol1.setElem(row, vec.getElem(1)); + mCol2.setElem(row, vec.getElem(2)); + return *this; } -inline Matrix3 & Matrix3::setElem( int col, int row, float val ) +inline Matrix3 &Matrix3::setElem(int col, int row, float val) { - Vector3 tmpV3_0; - tmpV3_0 = this->getCol( col ); - tmpV3_0.setElem( row, val ); - this->setCol( col, tmpV3_0 ); - return *this; + Vector3 tmpV3_0; + tmpV3_0 = this->getCol(col); + tmpV3_0.setElem(row, val); + this->setCol(col, tmpV3_0); + return *this; } -inline float Matrix3::getElem( int col, int row ) const +inline float Matrix3::getElem(int col, int row) const { - return this->getCol( col ).getElem( row ); + return this->getCol(col).getElem(row); } -inline const Vector3 Matrix3::getCol0( ) const +inline const Vector3 Matrix3::getCol0() const { - return mCol0; + return mCol0; } -inline const Vector3 Matrix3::getCol1( ) const +inline const Vector3 Matrix3::getCol1() const { - return mCol1; + return mCol1; } -inline const Vector3 Matrix3::getCol2( ) const +inline const Vector3 Matrix3::getCol2() const { - return mCol2; + return mCol2; } -inline const Vector3 Matrix3::getCol( int col ) const +inline const Vector3 Matrix3::getCol(int col) const { - return *(&mCol0 + col); + return *(&mCol0 + col); } -inline const Vector3 Matrix3::getRow( int row ) const +inline const Vector3 Matrix3::getRow(int row) const { - return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) ); + return Vector3(mCol0.getElem(row), mCol1.getElem(row), mCol2.getElem(row)); } -inline Vector3 & Matrix3::operator []( int col ) +inline Vector3 &Matrix3::operator[](int col) { - return *(&mCol0 + col); + return *(&mCol0 + col); } -inline const Vector3 Matrix3::operator []( int col ) const +inline const Vector3 Matrix3::operator[](int col) const { - return *(&mCol0 + col); + return *(&mCol0 + col); } -inline Matrix3 & Matrix3::operator =( const Matrix3 & mat ) +inline Matrix3 &Matrix3::operator=(const Matrix3 &mat) { - mCol0 = mat.mCol0; - mCol1 = mat.mCol1; - mCol2 = mat.mCol2; - return *this; + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + return *this; } -inline const Matrix3 transpose( const Matrix3 & mat ) +inline const Matrix3 transpose(const Matrix3 &mat) { - return Matrix3( - Vector3( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX() ), - Vector3( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY() ), - Vector3( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ() ) - ); + return Matrix3( + Vector3(mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX()), + Vector3(mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY()), + Vector3(mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ())); } -inline const Matrix3 inverse( const Matrix3 & mat ) +inline const Matrix3 inverse(const Matrix3 &mat) { - Vector3 tmp0, tmp1, tmp2; - float detinv; - tmp0 = cross( mat.getCol1(), mat.getCol2() ); - tmp1 = cross( mat.getCol2(), mat.getCol0() ); - tmp2 = cross( mat.getCol0(), mat.getCol1() ); - detinv = ( 1.0f / dot( mat.getCol2(), tmp2 ) ); - return Matrix3( - Vector3( ( tmp0.getX() * detinv ), ( tmp1.getX() * detinv ), ( tmp2.getX() * detinv ) ), - Vector3( ( tmp0.getY() * detinv ), ( tmp1.getY() * detinv ), ( tmp2.getY() * detinv ) ), - Vector3( ( tmp0.getZ() * detinv ), ( tmp1.getZ() * detinv ), ( tmp2.getZ() * detinv ) ) - ); + Vector3 tmp0, tmp1, tmp2; + float detinv; + tmp0 = cross(mat.getCol1(), mat.getCol2()); + tmp1 = cross(mat.getCol2(), mat.getCol0()); + tmp2 = cross(mat.getCol0(), mat.getCol1()); + detinv = (1.0f / dot(mat.getCol2(), tmp2)); + return Matrix3( + Vector3((tmp0.getX() * detinv), (tmp1.getX() * detinv), (tmp2.getX() * detinv)), + Vector3((tmp0.getY() * detinv), (tmp1.getY() * detinv), (tmp2.getY() * detinv)), + Vector3((tmp0.getZ() * detinv), (tmp1.getZ() * detinv), (tmp2.getZ() * detinv))); } -inline float determinant( const Matrix3 & mat ) +inline float determinant(const Matrix3 &mat) { - return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) ); + return dot(mat.getCol2(), cross(mat.getCol0(), mat.getCol1())); } -inline const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const +inline const Matrix3 Matrix3::operator+(const Matrix3 &mat) const { - return Matrix3( - ( mCol0 + mat.mCol0 ), - ( mCol1 + mat.mCol1 ), - ( mCol2 + mat.mCol2 ) - ); + return Matrix3( + (mCol0 + mat.mCol0), + (mCol1 + mat.mCol1), + (mCol2 + mat.mCol2)); } -inline const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const +inline const Matrix3 Matrix3::operator-(const Matrix3 &mat) const { - return Matrix3( - ( mCol0 - mat.mCol0 ), - ( mCol1 - mat.mCol1 ), - ( mCol2 - mat.mCol2 ) - ); + return Matrix3( + (mCol0 - mat.mCol0), + (mCol1 - mat.mCol1), + (mCol2 - mat.mCol2)); } -inline Matrix3 & Matrix3::operator +=( const Matrix3 & mat ) +inline Matrix3 &Matrix3::operator+=(const Matrix3 &mat) { - *this = *this + mat; - return *this; + *this = *this + mat; + return *this; } -inline Matrix3 & Matrix3::operator -=( const Matrix3 & mat ) +inline Matrix3 &Matrix3::operator-=(const Matrix3 &mat) { - *this = *this - mat; - return *this; + *this = *this - mat; + return *this; } -inline const Matrix3 Matrix3::operator -( ) const +inline const Matrix3 Matrix3::operator-() const { - return Matrix3( - ( -mCol0 ), - ( -mCol1 ), - ( -mCol2 ) - ); + return Matrix3( + (-mCol0), + (-mCol1), + (-mCol2)); } -inline const Matrix3 absPerElem( const Matrix3 & mat ) +inline const Matrix3 absPerElem(const Matrix3 &mat) { - return Matrix3( - absPerElem( mat.getCol0() ), - absPerElem( mat.getCol1() ), - absPerElem( mat.getCol2() ) - ); + return Matrix3( + absPerElem(mat.getCol0()), + absPerElem(mat.getCol1()), + absPerElem(mat.getCol2())); } -inline const Matrix3 Matrix3::operator *( float scalar ) const +inline const Matrix3 Matrix3::operator*(float scalar) const { - return Matrix3( - ( mCol0 * scalar ), - ( mCol1 * scalar ), - ( mCol2 * scalar ) - ); + return Matrix3( + (mCol0 * scalar), + (mCol1 * scalar), + (mCol2 * scalar)); } -inline Matrix3 & Matrix3::operator *=( float scalar ) +inline Matrix3 &Matrix3::operator*=(float scalar) { - *this = *this * scalar; - return *this; + *this = *this * scalar; + return *this; } -inline const Matrix3 operator *( float scalar, const Matrix3 & mat ) +inline const Matrix3 operator*(float scalar, const Matrix3 &mat) { - return mat * scalar; + return mat * scalar; } -inline const Vector3 Matrix3::operator *( const Vector3 & vec ) const +inline const Vector3 Matrix3::operator*(const Vector3 &vec) const { - return Vector3( - ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), - ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), - ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) - ); + return Vector3( + (((mCol0.getX() * vec.getX()) + (mCol1.getX() * vec.getY())) + (mCol2.getX() * vec.getZ())), + (((mCol0.getY() * vec.getX()) + (mCol1.getY() * vec.getY())) + (mCol2.getY() * vec.getZ())), + (((mCol0.getZ() * vec.getX()) + (mCol1.getZ() * vec.getY())) + (mCol2.getZ() * vec.getZ()))); } -inline const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const +inline const Matrix3 Matrix3::operator*(const Matrix3 &mat) const { - return Matrix3( - ( *this * mat.mCol0 ), - ( *this * mat.mCol1 ), - ( *this * mat.mCol2 ) - ); + return Matrix3( + (*this * mat.mCol0), + (*this * mat.mCol1), + (*this * mat.mCol2)); } -inline Matrix3 & Matrix3::operator *=( const Matrix3 & mat ) +inline Matrix3 &Matrix3::operator*=(const Matrix3 &mat) { - *this = *this * mat; - return *this; + *this = *this * mat; + return *this; } -inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ) +inline const Matrix3 mulPerElem(const Matrix3 &mat0, const Matrix3 &mat1) { - return Matrix3( - mulPerElem( mat0.getCol0(), mat1.getCol0() ), - mulPerElem( mat0.getCol1(), mat1.getCol1() ), - mulPerElem( mat0.getCol2(), mat1.getCol2() ) - ); + return Matrix3( + mulPerElem(mat0.getCol0(), mat1.getCol0()), + mulPerElem(mat0.getCol1(), mat1.getCol1()), + mulPerElem(mat0.getCol2(), mat1.getCol2())); } -inline const Matrix3 Matrix3::identity( ) +inline const Matrix3 Matrix3::identity() { - return Matrix3( - Vector3::xAxis( ), - Vector3::yAxis( ), - Vector3::zAxis( ) - ); + return Matrix3( + Vector3::xAxis(), + Vector3::yAxis(), + Vector3::zAxis()); } -inline const Matrix3 Matrix3::rotationX( float radians ) +inline const Matrix3 Matrix3::rotationX(float radians) { - float s, c; - s = sinf( radians ); - c = cosf( radians ); - return Matrix3( - Vector3::xAxis( ), - Vector3( 0.0f, c, s ), - Vector3( 0.0f, -s, c ) - ); + float s, c; + s = sinf(radians); + c = cosf(radians); + return Matrix3( + Vector3::xAxis(), + Vector3(0.0f, c, s), + Vector3(0.0f, -s, c)); } -inline const Matrix3 Matrix3::rotationY( float radians ) +inline const Matrix3 Matrix3::rotationY(float radians) { - float s, c; - s = sinf( radians ); - c = cosf( radians ); - return Matrix3( - Vector3( c, 0.0f, -s ), - Vector3::yAxis( ), - Vector3( s, 0.0f, c ) - ); + float s, c; + s = sinf(radians); + c = cosf(radians); + return Matrix3( + Vector3(c, 0.0f, -s), + Vector3::yAxis(), + Vector3(s, 0.0f, c)); } -inline const Matrix3 Matrix3::rotationZ( float radians ) +inline const Matrix3 Matrix3::rotationZ(float radians) { - float s, c; - s = sinf( radians ); - c = cosf( radians ); - return Matrix3( - Vector3( c, s, 0.0f ), - Vector3( -s, c, 0.0f ), - Vector3::zAxis( ) - ); + float s, c; + s = sinf(radians); + c = cosf(radians); + return Matrix3( + Vector3(c, s, 0.0f), + Vector3(-s, c, 0.0f), + Vector3::zAxis()); } -inline const Matrix3 Matrix3::rotationZYX( const Vector3 & radiansXYZ ) +inline const Matrix3 Matrix3::rotationZYX(const Vector3 &radiansXYZ) { - float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; - sX = sinf( radiansXYZ.getX() ); - cX = cosf( radiansXYZ.getX() ); - sY = sinf( radiansXYZ.getY() ); - cY = cosf( radiansXYZ.getY() ); - sZ = sinf( radiansXYZ.getZ() ); - cZ = cosf( radiansXYZ.getZ() ); - tmp0 = ( cZ * sY ); - tmp1 = ( sZ * sY ); - return Matrix3( - Vector3( ( cZ * cY ), ( sZ * cY ), -sY ), - Vector3( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ) ), - Vector3( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ) ) - ); + float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; + sX = sinf(radiansXYZ.getX()); + cX = cosf(radiansXYZ.getX()); + sY = sinf(radiansXYZ.getY()); + cY = cosf(radiansXYZ.getY()); + sZ = sinf(radiansXYZ.getZ()); + cZ = cosf(radiansXYZ.getZ()); + tmp0 = (cZ * sY); + tmp1 = (sZ * sY); + return Matrix3( + Vector3((cZ * cY), (sZ * cY), -sY), + Vector3(((tmp0 * sX) - (sZ * cX)), ((tmp1 * sX) + (cZ * cX)), (cY * sX)), + Vector3(((tmp0 * cX) + (sZ * sX)), ((tmp1 * cX) - (cZ * sX)), (cY * cX))); } -inline const Matrix3 Matrix3::rotation( float radians, const Vector3 & unitVec ) +inline const Matrix3 Matrix3::rotation(float radians, const Vector3 &unitVec) { - float x, y, z, s, c, oneMinusC, xy, yz, zx; - s = sinf( radians ); - c = cosf( radians ); - x = unitVec.getX(); - y = unitVec.getY(); - z = unitVec.getZ(); - xy = ( x * y ); - yz = ( y * z ); - zx = ( z * x ); - oneMinusC = ( 1.0f - c ); - return Matrix3( - Vector3( ( ( ( x * x ) * oneMinusC ) + c ), ( ( xy * oneMinusC ) + ( z * s ) ), ( ( zx * oneMinusC ) - ( y * s ) ) ), - Vector3( ( ( xy * oneMinusC ) - ( z * s ) ), ( ( ( y * y ) * oneMinusC ) + c ), ( ( yz * oneMinusC ) + ( x * s ) ) ), - Vector3( ( ( zx * oneMinusC ) + ( y * s ) ), ( ( yz * oneMinusC ) - ( x * s ) ), ( ( ( z * z ) * oneMinusC ) + c ) ) - ); + float x, y, z, s, c, oneMinusC, xy, yz, zx; + s = sinf(radians); + c = cosf(radians); + x = unitVec.getX(); + y = unitVec.getY(); + z = unitVec.getZ(); + xy = (x * y); + yz = (y * z); + zx = (z * x); + oneMinusC = (1.0f - c); + return Matrix3( + Vector3((((x * x) * oneMinusC) + c), ((xy * oneMinusC) + (z * s)), ((zx * oneMinusC) - (y * s))), + Vector3(((xy * oneMinusC) - (z * s)), (((y * y) * oneMinusC) + c), ((yz * oneMinusC) + (x * s))), + Vector3(((zx * oneMinusC) + (y * s)), ((yz * oneMinusC) - (x * s)), (((z * z) * oneMinusC) + c))); } -inline const Matrix3 Matrix3::rotation( const Quat & unitQuat ) +inline const Matrix3 Matrix3::rotation(const Quat &unitQuat) { - return Matrix3( unitQuat ); + return Matrix3(unitQuat); } -inline const Matrix3 Matrix3::scale( const Vector3 & scaleVec ) +inline const Matrix3 Matrix3::scale(const Vector3 &scaleVec) { - return Matrix3( - Vector3( scaleVec.getX(), 0.0f, 0.0f ), - Vector3( 0.0f, scaleVec.getY(), 0.0f ), - Vector3( 0.0f, 0.0f, scaleVec.getZ() ) - ); + return Matrix3( + Vector3(scaleVec.getX(), 0.0f, 0.0f), + Vector3(0.0f, scaleVec.getY(), 0.0f), + Vector3(0.0f, 0.0f, scaleVec.getZ())); } -inline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec ) +inline const Matrix3 appendScale(const Matrix3 &mat, const Vector3 &scaleVec) { - return Matrix3( - ( mat.getCol0() * scaleVec.getX( ) ), - ( mat.getCol1() * scaleVec.getY( ) ), - ( mat.getCol2() * scaleVec.getZ( ) ) - ); + return Matrix3( + (mat.getCol0() * scaleVec.getX()), + (mat.getCol1() * scaleVec.getY()), + (mat.getCol2() * scaleVec.getZ())); } -inline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat ) +inline const Matrix3 prependScale(const Vector3 &scaleVec, const Matrix3 &mat) { - return Matrix3( - mulPerElem( mat.getCol0(), scaleVec ), - mulPerElem( mat.getCol1(), scaleVec ), - mulPerElem( mat.getCol2(), scaleVec ) - ); + return Matrix3( + mulPerElem(mat.getCol0(), scaleVec), + mulPerElem(mat.getCol1(), scaleVec), + mulPerElem(mat.getCol2(), scaleVec)); } -inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ) +inline const Matrix3 select(const Matrix3 &mat0, const Matrix3 &mat1, bool select1) { - return Matrix3( - select( mat0.getCol0(), mat1.getCol0(), select1 ), - select( mat0.getCol1(), mat1.getCol1(), select1 ), - select( mat0.getCol2(), mat1.getCol2(), select1 ) - ); + return Matrix3( + select(mat0.getCol0(), mat1.getCol0(), select1), + select(mat0.getCol1(), mat1.getCol1(), select1), + select(mat0.getCol2(), mat1.getCol2(), select1)); } #ifdef _VECTORMATH_DEBUG -inline void print( const Matrix3 & mat ) +inline void print(const Matrix3 &mat) { - print( mat.getRow( 0 ) ); - print( mat.getRow( 1 ) ); - print( mat.getRow( 2 ) ); + print(mat.getRow(0)); + print(mat.getRow(1)); + print(mat.getRow(2)); } -inline void print( const Matrix3 & mat, const char * name ) +inline void print(const Matrix3 &mat, const char *name) { - printf("%s:\n", name); - print( mat ); + printf("%s:\n", name); + print(mat); } #endif -inline Matrix4::Matrix4( const Matrix4 & mat ) +inline Matrix4::Matrix4(const Matrix4 &mat) { - mCol0 = mat.mCol0; - mCol1 = mat.mCol1; - mCol2 = mat.mCol2; - mCol3 = mat.mCol3; + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + mCol3 = mat.mCol3; } -inline Matrix4::Matrix4( float scalar ) +inline Matrix4::Matrix4(float scalar) { - mCol0 = Vector4( scalar ); - mCol1 = Vector4( scalar ); - mCol2 = Vector4( scalar ); - mCol3 = Vector4( scalar ); + mCol0 = Vector4(scalar); + mCol1 = Vector4(scalar); + mCol2 = Vector4(scalar); + mCol3 = Vector4(scalar); } -inline Matrix4::Matrix4( const Transform3 & mat ) +inline Matrix4::Matrix4(const Transform3 &mat) { - mCol0 = Vector4( mat.getCol0(), 0.0f ); - mCol1 = Vector4( mat.getCol1(), 0.0f ); - mCol2 = Vector4( mat.getCol2(), 0.0f ); - mCol3 = Vector4( mat.getCol3(), 1.0f ); + mCol0 = Vector4(mat.getCol0(), 0.0f); + mCol1 = Vector4(mat.getCol1(), 0.0f); + mCol2 = Vector4(mat.getCol2(), 0.0f); + mCol3 = Vector4(mat.getCol3(), 1.0f); } -inline Matrix4::Matrix4( const Vector4 & _col0, const Vector4 & _col1, const Vector4 & _col2, const Vector4 & _col3 ) +inline Matrix4::Matrix4(const Vector4 &_col0, const Vector4 &_col1, const Vector4 &_col2, const Vector4 &_col3) { - mCol0 = _col0; - mCol1 = _col1; - mCol2 = _col2; - mCol3 = _col3; + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; + mCol3 = _col3; } -inline Matrix4::Matrix4( const Matrix3 & mat, const Vector3 & translateVec ) +inline Matrix4::Matrix4(const Matrix3 &mat, const Vector3 &translateVec) { - mCol0 = Vector4( mat.getCol0(), 0.0f ); - mCol1 = Vector4( mat.getCol1(), 0.0f ); - mCol2 = Vector4( mat.getCol2(), 0.0f ); - mCol3 = Vector4( translateVec, 1.0f ); + mCol0 = Vector4(mat.getCol0(), 0.0f); + mCol1 = Vector4(mat.getCol1(), 0.0f); + mCol2 = Vector4(mat.getCol2(), 0.0f); + mCol3 = Vector4(translateVec, 1.0f); } -inline Matrix4::Matrix4( const Quat & unitQuat, const Vector3 & translateVec ) +inline Matrix4::Matrix4(const Quat &unitQuat, const Vector3 &translateVec) { - Matrix3 mat; - mat = Matrix3( unitQuat ); - mCol0 = Vector4( mat.getCol0(), 0.0f ); - mCol1 = Vector4( mat.getCol1(), 0.0f ); - mCol2 = Vector4( mat.getCol2(), 0.0f ); - mCol3 = Vector4( translateVec, 1.0f ); + Matrix3 mat; + mat = Matrix3(unitQuat); + mCol0 = Vector4(mat.getCol0(), 0.0f); + mCol1 = Vector4(mat.getCol1(), 0.0f); + mCol2 = Vector4(mat.getCol2(), 0.0f); + mCol3 = Vector4(translateVec, 1.0f); } -inline Matrix4 & Matrix4::setCol0( const Vector4 & _col0 ) +inline Matrix4 &Matrix4::setCol0(const Vector4 &_col0) { - mCol0 = _col0; - return *this; + mCol0 = _col0; + return *this; } -inline Matrix4 & Matrix4::setCol1( const Vector4 & _col1 ) +inline Matrix4 &Matrix4::setCol1(const Vector4 &_col1) { - mCol1 = _col1; - return *this; + mCol1 = _col1; + return *this; } -inline Matrix4 & Matrix4::setCol2( const Vector4 & _col2 ) +inline Matrix4 &Matrix4::setCol2(const Vector4 &_col2) { - mCol2 = _col2; - return *this; + mCol2 = _col2; + return *this; } -inline Matrix4 & Matrix4::setCol3( const Vector4 & _col3 ) +inline Matrix4 &Matrix4::setCol3(const Vector4 &_col3) { - mCol3 = _col3; - return *this; + mCol3 = _col3; + return *this; } -inline Matrix4 & Matrix4::setCol( int col, const Vector4 & vec ) +inline Matrix4 &Matrix4::setCol(int col, const Vector4 &vec) { - *(&mCol0 + col) = vec; - return *this; + *(&mCol0 + col) = vec; + return *this; } -inline Matrix4 & Matrix4::setRow( int row, const Vector4 & vec ) +inline Matrix4 &Matrix4::setRow(int row, const Vector4 &vec) { - mCol0.setElem( row, vec.getElem( 0 ) ); - mCol1.setElem( row, vec.getElem( 1 ) ); - mCol2.setElem( row, vec.getElem( 2 ) ); - mCol3.setElem( row, vec.getElem( 3 ) ); - return *this; + mCol0.setElem(row, vec.getElem(0)); + mCol1.setElem(row, vec.getElem(1)); + mCol2.setElem(row, vec.getElem(2)); + mCol3.setElem(row, vec.getElem(3)); + return *this; } -inline Matrix4 & Matrix4::setElem( int col, int row, float val ) +inline Matrix4 &Matrix4::setElem(int col, int row, float val) { - Vector4 tmpV3_0; - tmpV3_0 = this->getCol( col ); - tmpV3_0.setElem( row, val ); - this->setCol( col, tmpV3_0 ); - return *this; + Vector4 tmpV3_0; + tmpV3_0 = this->getCol(col); + tmpV3_0.setElem(row, val); + this->setCol(col, tmpV3_0); + return *this; } -inline float Matrix4::getElem( int col, int row ) const +inline float Matrix4::getElem(int col, int row) const { - return this->getCol( col ).getElem( row ); + return this->getCol(col).getElem(row); } -inline const Vector4 Matrix4::getCol0( ) const +inline const Vector4 Matrix4::getCol0() const { - return mCol0; + return mCol0; } -inline const Vector4 Matrix4::getCol1( ) const +inline const Vector4 Matrix4::getCol1() const { - return mCol1; + return mCol1; } -inline const Vector4 Matrix4::getCol2( ) const +inline const Vector4 Matrix4::getCol2() const { - return mCol2; + return mCol2; } -inline const Vector4 Matrix4::getCol3( ) const +inline const Vector4 Matrix4::getCol3() const { - return mCol3; + return mCol3; } -inline const Vector4 Matrix4::getCol( int col ) const +inline const Vector4 Matrix4::getCol(int col) const { - return *(&mCol0 + col); + return *(&mCol0 + col); } -inline const Vector4 Matrix4::getRow( int row ) const +inline const Vector4 Matrix4::getRow(int row) const { - return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); + return Vector4(mCol0.getElem(row), mCol1.getElem(row), mCol2.getElem(row), mCol3.getElem(row)); } -inline Vector4 & Matrix4::operator []( int col ) +inline Vector4 &Matrix4::operator[](int col) { - return *(&mCol0 + col); + return *(&mCol0 + col); } -inline const Vector4 Matrix4::operator []( int col ) const +inline const Vector4 Matrix4::operator[](int col) const { - return *(&mCol0 + col); + return *(&mCol0 + col); } -inline Matrix4 & Matrix4::operator =( const Matrix4 & mat ) +inline Matrix4 &Matrix4::operator=(const Matrix4 &mat) { - mCol0 = mat.mCol0; - mCol1 = mat.mCol1; - mCol2 = mat.mCol2; - mCol3 = mat.mCol3; - return *this; + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + mCol3 = mat.mCol3; + return *this; } -inline const Matrix4 transpose( const Matrix4 & mat ) +inline const Matrix4 transpose(const Matrix4 &mat) { - return Matrix4( - Vector4( mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX(), mat.getCol3().getX() ), - Vector4( mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY(), mat.getCol3().getY() ), - Vector4( mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ(), mat.getCol3().getZ() ), - Vector4( mat.getCol0().getW(), mat.getCol1().getW(), mat.getCol2().getW(), mat.getCol3().getW() ) - ); + return Matrix4( + Vector4(mat.getCol0().getX(), mat.getCol1().getX(), mat.getCol2().getX(), mat.getCol3().getX()), + Vector4(mat.getCol0().getY(), mat.getCol1().getY(), mat.getCol2().getY(), mat.getCol3().getY()), + Vector4(mat.getCol0().getZ(), mat.getCol1().getZ(), mat.getCol2().getZ(), mat.getCol3().getZ()), + Vector4(mat.getCol0().getW(), mat.getCol1().getW(), mat.getCol2().getW(), mat.getCol3().getW())); } -inline const Matrix4 inverse( const Matrix4 & mat ) +inline const Matrix4 inverse(const Matrix4 &mat) { - Vector4 res0, res1, res2, res3; - float mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, detInv; - mA = mat.getCol0().getX(); - mB = mat.getCol0().getY(); - mC = mat.getCol0().getZ(); - mD = mat.getCol0().getW(); - mE = mat.getCol1().getX(); - mF = mat.getCol1().getY(); - mG = mat.getCol1().getZ(); - mH = mat.getCol1().getW(); - mI = mat.getCol2().getX(); - mJ = mat.getCol2().getY(); - mK = mat.getCol2().getZ(); - mL = mat.getCol2().getW(); - mM = mat.getCol3().getX(); - mN = mat.getCol3().getY(); - mO = mat.getCol3().getZ(); - mP = mat.getCol3().getW(); - tmp0 = ( ( mK * mD ) - ( mC * mL ) ); - tmp1 = ( ( mO * mH ) - ( mG * mP ) ); - tmp2 = ( ( mB * mK ) - ( mJ * mC ) ); - tmp3 = ( ( mF * mO ) - ( mN * mG ) ); - tmp4 = ( ( mJ * mD ) - ( mB * mL ) ); - tmp5 = ( ( mN * mH ) - ( mF * mP ) ); - res0.setX( ( ( ( mJ * tmp1 ) - ( mL * tmp3 ) ) - ( mK * tmp5 ) ) ); - res0.setY( ( ( ( mN * tmp0 ) - ( mP * tmp2 ) ) - ( mO * tmp4 ) ) ); - res0.setZ( ( ( ( mD * tmp3 ) + ( mC * tmp5 ) ) - ( mB * tmp1 ) ) ); - res0.setW( ( ( ( mH * tmp2 ) + ( mG * tmp4 ) ) - ( mF * tmp0 ) ) ); - detInv = ( 1.0f / ( ( ( ( mA * res0.getX() ) + ( mE * res0.getY() ) ) + ( mI * res0.getZ() ) ) + ( mM * res0.getW() ) ) ); - res1.setX( ( mI * tmp1 ) ); - res1.setY( ( mM * tmp0 ) ); - res1.setZ( ( mA * tmp1 ) ); - res1.setW( ( mE * tmp0 ) ); - res3.setX( ( mI * tmp3 ) ); - res3.setY( ( mM * tmp2 ) ); - res3.setZ( ( mA * tmp3 ) ); - res3.setW( ( mE * tmp2 ) ); - res2.setX( ( mI * tmp5 ) ); - res2.setY( ( mM * tmp4 ) ); - res2.setZ( ( mA * tmp5 ) ); - res2.setW( ( mE * tmp4 ) ); - tmp0 = ( ( mI * mB ) - ( mA * mJ ) ); - tmp1 = ( ( mM * mF ) - ( mE * mN ) ); - tmp2 = ( ( mI * mD ) - ( mA * mL ) ); - tmp3 = ( ( mM * mH ) - ( mE * mP ) ); - tmp4 = ( ( mI * mC ) - ( mA * mK ) ); - tmp5 = ( ( mM * mG ) - ( mE * mO ) ); - res2.setX( ( ( ( mL * tmp1 ) - ( mJ * tmp3 ) ) + res2.getX() ) ); - res2.setY( ( ( ( mP * tmp0 ) - ( mN * tmp2 ) ) + res2.getY() ) ); - res2.setZ( ( ( ( mB * tmp3 ) - ( mD * tmp1 ) ) - res2.getZ() ) ); - res2.setW( ( ( ( mF * tmp2 ) - ( mH * tmp0 ) ) - res2.getW() ) ); - res3.setX( ( ( ( mJ * tmp5 ) - ( mK * tmp1 ) ) + res3.getX() ) ); - res3.setY( ( ( ( mN * tmp4 ) - ( mO * tmp0 ) ) + res3.getY() ) ); - res3.setZ( ( ( ( mC * tmp1 ) - ( mB * tmp5 ) ) - res3.getZ() ) ); - res3.setW( ( ( ( mG * tmp0 ) - ( mF * tmp4 ) ) - res3.getW() ) ); - res1.setX( ( ( ( mK * tmp3 ) - ( mL * tmp5 ) ) - res1.getX() ) ); - res1.setY( ( ( ( mO * tmp2 ) - ( mP * tmp4 ) ) - res1.getY() ) ); - res1.setZ( ( ( ( mD * tmp5 ) - ( mC * tmp3 ) ) + res1.getZ() ) ); - res1.setW( ( ( ( mH * tmp4 ) - ( mG * tmp2 ) ) + res1.getW() ) ); - return Matrix4( - ( res0 * detInv ), - ( res1 * detInv ), - ( res2 * detInv ), - ( res3 * detInv ) - ); + Vector4 res0, res1, res2, res3; + float mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, detInv; + mA = mat.getCol0().getX(); + mB = mat.getCol0().getY(); + mC = mat.getCol0().getZ(); + mD = mat.getCol0().getW(); + mE = mat.getCol1().getX(); + mF = mat.getCol1().getY(); + mG = mat.getCol1().getZ(); + mH = mat.getCol1().getW(); + mI = mat.getCol2().getX(); + mJ = mat.getCol2().getY(); + mK = mat.getCol2().getZ(); + mL = mat.getCol2().getW(); + mM = mat.getCol3().getX(); + mN = mat.getCol3().getY(); + mO = mat.getCol3().getZ(); + mP = mat.getCol3().getW(); + tmp0 = ((mK * mD) - (mC * mL)); + tmp1 = ((mO * mH) - (mG * mP)); + tmp2 = ((mB * mK) - (mJ * mC)); + tmp3 = ((mF * mO) - (mN * mG)); + tmp4 = ((mJ * mD) - (mB * mL)); + tmp5 = ((mN * mH) - (mF * mP)); + res0.setX((((mJ * tmp1) - (mL * tmp3)) - (mK * tmp5))); + res0.setY((((mN * tmp0) - (mP * tmp2)) - (mO * tmp4))); + res0.setZ((((mD * tmp3) + (mC * tmp5)) - (mB * tmp1))); + res0.setW((((mH * tmp2) + (mG * tmp4)) - (mF * tmp0))); + detInv = (1.0f / ((((mA * res0.getX()) + (mE * res0.getY())) + (mI * res0.getZ())) + (mM * res0.getW()))); + res1.setX((mI * tmp1)); + res1.setY((mM * tmp0)); + res1.setZ((mA * tmp1)); + res1.setW((mE * tmp0)); + res3.setX((mI * tmp3)); + res3.setY((mM * tmp2)); + res3.setZ((mA * tmp3)); + res3.setW((mE * tmp2)); + res2.setX((mI * tmp5)); + res2.setY((mM * tmp4)); + res2.setZ((mA * tmp5)); + res2.setW((mE * tmp4)); + tmp0 = ((mI * mB) - (mA * mJ)); + tmp1 = ((mM * mF) - (mE * mN)); + tmp2 = ((mI * mD) - (mA * mL)); + tmp3 = ((mM * mH) - (mE * mP)); + tmp4 = ((mI * mC) - (mA * mK)); + tmp5 = ((mM * mG) - (mE * mO)); + res2.setX((((mL * tmp1) - (mJ * tmp3)) + res2.getX())); + res2.setY((((mP * tmp0) - (mN * tmp2)) + res2.getY())); + res2.setZ((((mB * tmp3) - (mD * tmp1)) - res2.getZ())); + res2.setW((((mF * tmp2) - (mH * tmp0)) - res2.getW())); + res3.setX((((mJ * tmp5) - (mK * tmp1)) + res3.getX())); + res3.setY((((mN * tmp4) - (mO * tmp0)) + res3.getY())); + res3.setZ((((mC * tmp1) - (mB * tmp5)) - res3.getZ())); + res3.setW((((mG * tmp0) - (mF * tmp4)) - res3.getW())); + res1.setX((((mK * tmp3) - (mL * tmp5)) - res1.getX())); + res1.setY((((mO * tmp2) - (mP * tmp4)) - res1.getY())); + res1.setZ((((mD * tmp5) - (mC * tmp3)) + res1.getZ())); + res1.setW((((mH * tmp4) - (mG * tmp2)) + res1.getW())); + return Matrix4( + (res0 * detInv), + (res1 * detInv), + (res2 * detInv), + (res3 * detInv)); } -inline const Matrix4 affineInverse( const Matrix4 & mat ) +inline const Matrix4 affineInverse(const Matrix4 &mat) { - Transform3 affineMat; - affineMat.setCol0( mat.getCol0().getXYZ( ) ); - affineMat.setCol1( mat.getCol1().getXYZ( ) ); - affineMat.setCol2( mat.getCol2().getXYZ( ) ); - affineMat.setCol3( mat.getCol3().getXYZ( ) ); - return Matrix4( inverse( affineMat ) ); + Transform3 affineMat; + affineMat.setCol0(mat.getCol0().getXYZ()); + affineMat.setCol1(mat.getCol1().getXYZ()); + affineMat.setCol2(mat.getCol2().getXYZ()); + affineMat.setCol3(mat.getCol3().getXYZ()); + return Matrix4(inverse(affineMat)); } -inline const Matrix4 orthoInverse( const Matrix4 & mat ) +inline const Matrix4 orthoInverse(const Matrix4 &mat) { - Transform3 affineMat; - affineMat.setCol0( mat.getCol0().getXYZ( ) ); - affineMat.setCol1( mat.getCol1().getXYZ( ) ); - affineMat.setCol2( mat.getCol2().getXYZ( ) ); - affineMat.setCol3( mat.getCol3().getXYZ( ) ); - return Matrix4( orthoInverse( affineMat ) ); + Transform3 affineMat; + affineMat.setCol0(mat.getCol0().getXYZ()); + affineMat.setCol1(mat.getCol1().getXYZ()); + affineMat.setCol2(mat.getCol2().getXYZ()); + affineMat.setCol3(mat.getCol3().getXYZ()); + return Matrix4(orthoInverse(affineMat)); } -inline float determinant( const Matrix4 & mat ) +inline float determinant(const Matrix4 &mat) { - float dx, dy, dz, dw, mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; - mA = mat.getCol0().getX(); - mB = mat.getCol0().getY(); - mC = mat.getCol0().getZ(); - mD = mat.getCol0().getW(); - mE = mat.getCol1().getX(); - mF = mat.getCol1().getY(); - mG = mat.getCol1().getZ(); - mH = mat.getCol1().getW(); - mI = mat.getCol2().getX(); - mJ = mat.getCol2().getY(); - mK = mat.getCol2().getZ(); - mL = mat.getCol2().getW(); - mM = mat.getCol3().getX(); - mN = mat.getCol3().getY(); - mO = mat.getCol3().getZ(); - mP = mat.getCol3().getW(); - tmp0 = ( ( mK * mD ) - ( mC * mL ) ); - tmp1 = ( ( mO * mH ) - ( mG * mP ) ); - tmp2 = ( ( mB * mK ) - ( mJ * mC ) ); - tmp3 = ( ( mF * mO ) - ( mN * mG ) ); - tmp4 = ( ( mJ * mD ) - ( mB * mL ) ); - tmp5 = ( ( mN * mH ) - ( mF * mP ) ); - dx = ( ( ( mJ * tmp1 ) - ( mL * tmp3 ) ) - ( mK * tmp5 ) ); - dy = ( ( ( mN * tmp0 ) - ( mP * tmp2 ) ) - ( mO * tmp4 ) ); - dz = ( ( ( mD * tmp3 ) + ( mC * tmp5 ) ) - ( mB * tmp1 ) ); - dw = ( ( ( mH * tmp2 ) + ( mG * tmp4 ) ) - ( mF * tmp0 ) ); - return ( ( ( ( mA * dx ) + ( mE * dy ) ) + ( mI * dz ) ) + ( mM * dw ) ); + float dx, dy, dz, dw, mA, mB, mC, mD, mE, mF, mG, mH, mI, mJ, mK, mL, mM, mN, mO, mP, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; + mA = mat.getCol0().getX(); + mB = mat.getCol0().getY(); + mC = mat.getCol0().getZ(); + mD = mat.getCol0().getW(); + mE = mat.getCol1().getX(); + mF = mat.getCol1().getY(); + mG = mat.getCol1().getZ(); + mH = mat.getCol1().getW(); + mI = mat.getCol2().getX(); + mJ = mat.getCol2().getY(); + mK = mat.getCol2().getZ(); + mL = mat.getCol2().getW(); + mM = mat.getCol3().getX(); + mN = mat.getCol3().getY(); + mO = mat.getCol3().getZ(); + mP = mat.getCol3().getW(); + tmp0 = ((mK * mD) - (mC * mL)); + tmp1 = ((mO * mH) - (mG * mP)); + tmp2 = ((mB * mK) - (mJ * mC)); + tmp3 = ((mF * mO) - (mN * mG)); + tmp4 = ((mJ * mD) - (mB * mL)); + tmp5 = ((mN * mH) - (mF * mP)); + dx = (((mJ * tmp1) - (mL * tmp3)) - (mK * tmp5)); + dy = (((mN * tmp0) - (mP * tmp2)) - (mO * tmp4)); + dz = (((mD * tmp3) + (mC * tmp5)) - (mB * tmp1)); + dw = (((mH * tmp2) + (mG * tmp4)) - (mF * tmp0)); + return ((((mA * dx) + (mE * dy)) + (mI * dz)) + (mM * dw)); } -inline const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const +inline const Matrix4 Matrix4::operator+(const Matrix4 &mat) const { - return Matrix4( - ( mCol0 + mat.mCol0 ), - ( mCol1 + mat.mCol1 ), - ( mCol2 + mat.mCol2 ), - ( mCol3 + mat.mCol3 ) - ); + return Matrix4( + (mCol0 + mat.mCol0), + (mCol1 + mat.mCol1), + (mCol2 + mat.mCol2), + (mCol3 + mat.mCol3)); } -inline const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const +inline const Matrix4 Matrix4::operator-(const Matrix4 &mat) const { - return Matrix4( - ( mCol0 - mat.mCol0 ), - ( mCol1 - mat.mCol1 ), - ( mCol2 - mat.mCol2 ), - ( mCol3 - mat.mCol3 ) - ); + return Matrix4( + (mCol0 - mat.mCol0), + (mCol1 - mat.mCol1), + (mCol2 - mat.mCol2), + (mCol3 - mat.mCol3)); } -inline Matrix4 & Matrix4::operator +=( const Matrix4 & mat ) +inline Matrix4 &Matrix4::operator+=(const Matrix4 &mat) { - *this = *this + mat; - return *this; + *this = *this + mat; + return *this; } -inline Matrix4 & Matrix4::operator -=( const Matrix4 & mat ) +inline Matrix4 &Matrix4::operator-=(const Matrix4 &mat) { - *this = *this - mat; - return *this; + *this = *this - mat; + return *this; } -inline const Matrix4 Matrix4::operator -( ) const +inline const Matrix4 Matrix4::operator-() const { - return Matrix4( - ( -mCol0 ), - ( -mCol1 ), - ( -mCol2 ), - ( -mCol3 ) - ); + return Matrix4( + (-mCol0), + (-mCol1), + (-mCol2), + (-mCol3)); } -inline const Matrix4 absPerElem( const Matrix4 & mat ) +inline const Matrix4 absPerElem(const Matrix4 &mat) { - return Matrix4( - absPerElem( mat.getCol0() ), - absPerElem( mat.getCol1() ), - absPerElem( mat.getCol2() ), - absPerElem( mat.getCol3() ) - ); + return Matrix4( + absPerElem(mat.getCol0()), + absPerElem(mat.getCol1()), + absPerElem(mat.getCol2()), + absPerElem(mat.getCol3())); } -inline const Matrix4 Matrix4::operator *( float scalar ) const +inline const Matrix4 Matrix4::operator*(float scalar) const { - return Matrix4( - ( mCol0 * scalar ), - ( mCol1 * scalar ), - ( mCol2 * scalar ), - ( mCol3 * scalar ) - ); + return Matrix4( + (mCol0 * scalar), + (mCol1 * scalar), + (mCol2 * scalar), + (mCol3 * scalar)); } -inline Matrix4 & Matrix4::operator *=( float scalar ) +inline Matrix4 &Matrix4::operator*=(float scalar) { - *this = *this * scalar; - return *this; + *this = *this * scalar; + return *this; } -inline const Matrix4 operator *( float scalar, const Matrix4 & mat ) +inline const Matrix4 operator*(float scalar, const Matrix4 &mat) { - return mat * scalar; + return mat * scalar; } -inline const Vector4 Matrix4::operator *( const Vector4 & vec ) const +inline const Vector4 Matrix4::operator*(const Vector4 &vec) const { - return Vector4( - ( ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ) + ( mCol3.getX() * vec.getW() ) ), - ( ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ) + ( mCol3.getY() * vec.getW() ) ), - ( ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) + ( mCol3.getZ() * vec.getW() ) ), - ( ( ( ( mCol0.getW() * vec.getX() ) + ( mCol1.getW() * vec.getY() ) ) + ( mCol2.getW() * vec.getZ() ) ) + ( mCol3.getW() * vec.getW() ) ) - ); + return Vector4( + ((((mCol0.getX() * vec.getX()) + (mCol1.getX() * vec.getY())) + (mCol2.getX() * vec.getZ())) + (mCol3.getX() * vec.getW())), + ((((mCol0.getY() * vec.getX()) + (mCol1.getY() * vec.getY())) + (mCol2.getY() * vec.getZ())) + (mCol3.getY() * vec.getW())), + ((((mCol0.getZ() * vec.getX()) + (mCol1.getZ() * vec.getY())) + (mCol2.getZ() * vec.getZ())) + (mCol3.getZ() * vec.getW())), + ((((mCol0.getW() * vec.getX()) + (mCol1.getW() * vec.getY())) + (mCol2.getW() * vec.getZ())) + (mCol3.getW() * vec.getW()))); } -inline const Vector4 Matrix4::operator *( const Vector3 & vec ) const +inline const Vector4 Matrix4::operator*(const Vector3 &vec) const { - return Vector4( - ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), - ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), - ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ), - ( ( ( mCol0.getW() * vec.getX() ) + ( mCol1.getW() * vec.getY() ) ) + ( mCol2.getW() * vec.getZ() ) ) - ); + return Vector4( + (((mCol0.getX() * vec.getX()) + (mCol1.getX() * vec.getY())) + (mCol2.getX() * vec.getZ())), + (((mCol0.getY() * vec.getX()) + (mCol1.getY() * vec.getY())) + (mCol2.getY() * vec.getZ())), + (((mCol0.getZ() * vec.getX()) + (mCol1.getZ() * vec.getY())) + (mCol2.getZ() * vec.getZ())), + (((mCol0.getW() * vec.getX()) + (mCol1.getW() * vec.getY())) + (mCol2.getW() * vec.getZ()))); } -inline const Vector4 Matrix4::operator *( const Point3 & pnt ) const +inline const Vector4 Matrix4::operator*(const Point3 &pnt) const { - return Vector4( - ( ( ( ( mCol0.getX() * pnt.getX() ) + ( mCol1.getX() * pnt.getY() ) ) + ( mCol2.getX() * pnt.getZ() ) ) + mCol3.getX() ), - ( ( ( ( mCol0.getY() * pnt.getX() ) + ( mCol1.getY() * pnt.getY() ) ) + ( mCol2.getY() * pnt.getZ() ) ) + mCol3.getY() ), - ( ( ( ( mCol0.getZ() * pnt.getX() ) + ( mCol1.getZ() * pnt.getY() ) ) + ( mCol2.getZ() * pnt.getZ() ) ) + mCol3.getZ() ), - ( ( ( ( mCol0.getW() * pnt.getX() ) + ( mCol1.getW() * pnt.getY() ) ) + ( mCol2.getW() * pnt.getZ() ) ) + mCol3.getW() ) - ); + return Vector4( + ((((mCol0.getX() * pnt.getX()) + (mCol1.getX() * pnt.getY())) + (mCol2.getX() * pnt.getZ())) + mCol3.getX()), + ((((mCol0.getY() * pnt.getX()) + (mCol1.getY() * pnt.getY())) + (mCol2.getY() * pnt.getZ())) + mCol3.getY()), + ((((mCol0.getZ() * pnt.getX()) + (mCol1.getZ() * pnt.getY())) + (mCol2.getZ() * pnt.getZ())) + mCol3.getZ()), + ((((mCol0.getW() * pnt.getX()) + (mCol1.getW() * pnt.getY())) + (mCol2.getW() * pnt.getZ())) + mCol3.getW())); } -inline const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const +inline const Matrix4 Matrix4::operator*(const Matrix4 &mat) const { - return Matrix4( - ( *this * mat.mCol0 ), - ( *this * mat.mCol1 ), - ( *this * mat.mCol2 ), - ( *this * mat.mCol3 ) - ); + return Matrix4( + (*this * mat.mCol0), + (*this * mat.mCol1), + (*this * mat.mCol2), + (*this * mat.mCol3)); } -inline Matrix4 & Matrix4::operator *=( const Matrix4 & mat ) +inline Matrix4 &Matrix4::operator*=(const Matrix4 &mat) { - *this = *this * mat; - return *this; + *this = *this * mat; + return *this; } -inline const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const +inline const Matrix4 Matrix4::operator*(const Transform3 &tfrm) const { - return Matrix4( - ( *this * tfrm.getCol0() ), - ( *this * tfrm.getCol1() ), - ( *this * tfrm.getCol2() ), - ( *this * Point3( tfrm.getCol3() ) ) - ); + return Matrix4( + (*this * tfrm.getCol0()), + (*this * tfrm.getCol1()), + (*this * tfrm.getCol2()), + (*this * Point3(tfrm.getCol3()))); } -inline Matrix4 & Matrix4::operator *=( const Transform3 & tfrm ) +inline Matrix4 &Matrix4::operator*=(const Transform3 &tfrm) { - *this = *this * tfrm; - return *this; + *this = *this * tfrm; + return *this; } -inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ) +inline const Matrix4 mulPerElem(const Matrix4 &mat0, const Matrix4 &mat1) { - return Matrix4( - mulPerElem( mat0.getCol0(), mat1.getCol0() ), - mulPerElem( mat0.getCol1(), mat1.getCol1() ), - mulPerElem( mat0.getCol2(), mat1.getCol2() ), - mulPerElem( mat0.getCol3(), mat1.getCol3() ) - ); + return Matrix4( + mulPerElem(mat0.getCol0(), mat1.getCol0()), + mulPerElem(mat0.getCol1(), mat1.getCol1()), + mulPerElem(mat0.getCol2(), mat1.getCol2()), + mulPerElem(mat0.getCol3(), mat1.getCol3())); } -inline const Matrix4 Matrix4::identity( ) +inline const Matrix4 Matrix4::identity() { - return Matrix4( - Vector4::xAxis( ), - Vector4::yAxis( ), - Vector4::zAxis( ), - Vector4::wAxis( ) - ); + return Matrix4( + Vector4::xAxis(), + Vector4::yAxis(), + Vector4::zAxis(), + Vector4::wAxis()); } -inline Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 ) +inline Matrix4 &Matrix4::setUpper3x3(const Matrix3 &mat3) { - mCol0.setXYZ( mat3.getCol0() ); - mCol1.setXYZ( mat3.getCol1() ); - mCol2.setXYZ( mat3.getCol2() ); - return *this; + mCol0.setXYZ(mat3.getCol0()); + mCol1.setXYZ(mat3.getCol1()); + mCol2.setXYZ(mat3.getCol2()); + return *this; } -inline const Matrix3 Matrix4::getUpper3x3( ) const +inline const Matrix3 Matrix4::getUpper3x3() const { - return Matrix3( - mCol0.getXYZ( ), - mCol1.getXYZ( ), - mCol2.getXYZ( ) - ); + return Matrix3( + mCol0.getXYZ(), + mCol1.getXYZ(), + mCol2.getXYZ()); } -inline Matrix4 & Matrix4::setTranslation( const Vector3 & translateVec ) +inline Matrix4 &Matrix4::setTranslation(const Vector3 &translateVec) { - mCol3.setXYZ( translateVec ); - return *this; + mCol3.setXYZ(translateVec); + return *this; } -inline const Vector3 Matrix4::getTranslation( ) const +inline const Vector3 Matrix4::getTranslation() const { - return mCol3.getXYZ( ); + return mCol3.getXYZ(); } -inline const Matrix4 Matrix4::rotationX( float radians ) +inline const Matrix4 Matrix4::rotationX(float radians) { - float s, c; - s = sinf( radians ); - c = cosf( radians ); - return Matrix4( - Vector4::xAxis( ), - Vector4( 0.0f, c, s, 0.0f ), - Vector4( 0.0f, -s, c, 0.0f ), - Vector4::wAxis( ) - ); + float s, c; + s = sinf(radians); + c = cosf(radians); + return Matrix4( + Vector4::xAxis(), + Vector4(0.0f, c, s, 0.0f), + Vector4(0.0f, -s, c, 0.0f), + Vector4::wAxis()); } -inline const Matrix4 Matrix4::rotationY( float radians ) +inline const Matrix4 Matrix4::rotationY(float radians) { - float s, c; - s = sinf( radians ); - c = cosf( radians ); - return Matrix4( - Vector4( c, 0.0f, -s, 0.0f ), - Vector4::yAxis( ), - Vector4( s, 0.0f, c, 0.0f ), - Vector4::wAxis( ) - ); + float s, c; + s = sinf(radians); + c = cosf(radians); + return Matrix4( + Vector4(c, 0.0f, -s, 0.0f), + Vector4::yAxis(), + Vector4(s, 0.0f, c, 0.0f), + Vector4::wAxis()); } -inline const Matrix4 Matrix4::rotationZ( float radians ) +inline const Matrix4 Matrix4::rotationZ(float radians) { - float s, c; - s = sinf( radians ); - c = cosf( radians ); - return Matrix4( - Vector4( c, s, 0.0f, 0.0f ), - Vector4( -s, c, 0.0f, 0.0f ), - Vector4::zAxis( ), - Vector4::wAxis( ) - ); + float s, c; + s = sinf(radians); + c = cosf(radians); + return Matrix4( + Vector4(c, s, 0.0f, 0.0f), + Vector4(-s, c, 0.0f, 0.0f), + Vector4::zAxis(), + Vector4::wAxis()); } -inline const Matrix4 Matrix4::rotationZYX( const Vector3 & radiansXYZ ) +inline const Matrix4 Matrix4::rotationZYX(const Vector3 &radiansXYZ) { - float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; - sX = sinf( radiansXYZ.getX() ); - cX = cosf( radiansXYZ.getX() ); - sY = sinf( radiansXYZ.getY() ); - cY = cosf( radiansXYZ.getY() ); - sZ = sinf( radiansXYZ.getZ() ); - cZ = cosf( radiansXYZ.getZ() ); - tmp0 = ( cZ * sY ); - tmp1 = ( sZ * sY ); - return Matrix4( - Vector4( ( cZ * cY ), ( sZ * cY ), -sY, 0.0f ), - Vector4( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ), 0.0f ), - Vector4( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ), 0.0f ), - Vector4::wAxis( ) - ); + float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; + sX = sinf(radiansXYZ.getX()); + cX = cosf(radiansXYZ.getX()); + sY = sinf(radiansXYZ.getY()); + cY = cosf(radiansXYZ.getY()); + sZ = sinf(radiansXYZ.getZ()); + cZ = cosf(radiansXYZ.getZ()); + tmp0 = (cZ * sY); + tmp1 = (sZ * sY); + return Matrix4( + Vector4((cZ * cY), (sZ * cY), -sY, 0.0f), + Vector4(((tmp0 * sX) - (sZ * cX)), ((tmp1 * sX) + (cZ * cX)), (cY * sX), 0.0f), + Vector4(((tmp0 * cX) + (sZ * sX)), ((tmp1 * cX) - (cZ * sX)), (cY * cX), 0.0f), + Vector4::wAxis()); } -inline const Matrix4 Matrix4::rotation( float radians, const Vector3 & unitVec ) +inline const Matrix4 Matrix4::rotation(float radians, const Vector3 &unitVec) { - float x, y, z, s, c, oneMinusC, xy, yz, zx; - s = sinf( radians ); - c = cosf( radians ); - x = unitVec.getX(); - y = unitVec.getY(); - z = unitVec.getZ(); - xy = ( x * y ); - yz = ( y * z ); - zx = ( z * x ); - oneMinusC = ( 1.0f - c ); - return Matrix4( - Vector4( ( ( ( x * x ) * oneMinusC ) + c ), ( ( xy * oneMinusC ) + ( z * s ) ), ( ( zx * oneMinusC ) - ( y * s ) ), 0.0f ), - Vector4( ( ( xy * oneMinusC ) - ( z * s ) ), ( ( ( y * y ) * oneMinusC ) + c ), ( ( yz * oneMinusC ) + ( x * s ) ), 0.0f ), - Vector4( ( ( zx * oneMinusC ) + ( y * s ) ), ( ( yz * oneMinusC ) - ( x * s ) ), ( ( ( z * z ) * oneMinusC ) + c ), 0.0f ), - Vector4::wAxis( ) - ); + float x, y, z, s, c, oneMinusC, xy, yz, zx; + s = sinf(radians); + c = cosf(radians); + x = unitVec.getX(); + y = unitVec.getY(); + z = unitVec.getZ(); + xy = (x * y); + yz = (y * z); + zx = (z * x); + oneMinusC = (1.0f - c); + return Matrix4( + Vector4((((x * x) * oneMinusC) + c), ((xy * oneMinusC) + (z * s)), ((zx * oneMinusC) - (y * s)), 0.0f), + Vector4(((xy * oneMinusC) - (z * s)), (((y * y) * oneMinusC) + c), ((yz * oneMinusC) + (x * s)), 0.0f), + Vector4(((zx * oneMinusC) + (y * s)), ((yz * oneMinusC) - (x * s)), (((z * z) * oneMinusC) + c), 0.0f), + Vector4::wAxis()); } -inline const Matrix4 Matrix4::rotation( const Quat & unitQuat ) +inline const Matrix4 Matrix4::rotation(const Quat &unitQuat) { - return Matrix4( Transform3::rotation( unitQuat ) ); + return Matrix4(Transform3::rotation(unitQuat)); } -inline const Matrix4 Matrix4::scale( const Vector3 & scaleVec ) +inline const Matrix4 Matrix4::scale(const Vector3 &scaleVec) { - return Matrix4( - Vector4( scaleVec.getX(), 0.0f, 0.0f, 0.0f ), - Vector4( 0.0f, scaleVec.getY(), 0.0f, 0.0f ), - Vector4( 0.0f, 0.0f, scaleVec.getZ(), 0.0f ), - Vector4::wAxis( ) - ); + return Matrix4( + Vector4(scaleVec.getX(), 0.0f, 0.0f, 0.0f), + Vector4(0.0f, scaleVec.getY(), 0.0f, 0.0f), + Vector4(0.0f, 0.0f, scaleVec.getZ(), 0.0f), + Vector4::wAxis()); } -inline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec ) +inline const Matrix4 appendScale(const Matrix4 &mat, const Vector3 &scaleVec) { - return Matrix4( - ( mat.getCol0() * scaleVec.getX( ) ), - ( mat.getCol1() * scaleVec.getY( ) ), - ( mat.getCol2() * scaleVec.getZ( ) ), - mat.getCol3() - ); + return Matrix4( + (mat.getCol0() * scaleVec.getX()), + (mat.getCol1() * scaleVec.getY()), + (mat.getCol2() * scaleVec.getZ()), + mat.getCol3()); } -inline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat ) +inline const Matrix4 prependScale(const Vector3 &scaleVec, const Matrix4 &mat) { - Vector4 scale4; - scale4 = Vector4( scaleVec, 1.0f ); - return Matrix4( - mulPerElem( mat.getCol0(), scale4 ), - mulPerElem( mat.getCol1(), scale4 ), - mulPerElem( mat.getCol2(), scale4 ), - mulPerElem( mat.getCol3(), scale4 ) - ); + Vector4 scale4; + scale4 = Vector4(scaleVec, 1.0f); + return Matrix4( + mulPerElem(mat.getCol0(), scale4), + mulPerElem(mat.getCol1(), scale4), + mulPerElem(mat.getCol2(), scale4), + mulPerElem(mat.getCol3(), scale4)); } -inline const Matrix4 Matrix4::translation( const Vector3 & translateVec ) +inline const Matrix4 Matrix4::translation(const Vector3 &translateVec) { - return Matrix4( - Vector4::xAxis( ), - Vector4::yAxis( ), - Vector4::zAxis( ), - Vector4( translateVec, 1.0f ) - ); + return Matrix4( + Vector4::xAxis(), + Vector4::yAxis(), + Vector4::zAxis(), + Vector4(translateVec, 1.0f)); } -inline const Matrix4 Matrix4::lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec ) +inline const Matrix4 Matrix4::lookAt(const Point3 &eyePos, const Point3 &lookAtPos, const Vector3 &upVec) { - Matrix4 m4EyeFrame; - Vector3 v3X, v3Y, v3Z; - v3Y = normalize( upVec ); - v3Z = normalize( ( eyePos - lookAtPos ) ); - v3X = normalize( cross( v3Y, v3Z ) ); - v3Y = cross( v3Z, v3X ); - m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) ); - return orthoInverse( m4EyeFrame ); + Matrix4 m4EyeFrame; + Vector3 v3X, v3Y, v3Z; + v3Y = normalize(upVec); + v3Z = normalize((eyePos - lookAtPos)); + v3X = normalize(cross(v3Y, v3Z)); + v3Y = cross(v3Z, v3X); + m4EyeFrame = Matrix4(Vector4(v3X), Vector4(v3Y), Vector4(v3Z), Vector4(eyePos)); + return orthoInverse(m4EyeFrame); } -inline const Matrix4 Matrix4::perspective( float fovyRadians, float aspect, float zNear, float zFar ) +inline const Matrix4 Matrix4::perspective(float fovyRadians, float aspect, float zNear, float zFar) { - float f, rangeInv; - f = tanf( ( (float)( _VECTORMATH_PI_OVER_2 ) - ( 0.5f * fovyRadians ) ) ); - rangeInv = ( 1.0f / ( zNear - zFar ) ); - return Matrix4( - Vector4( ( f / aspect ), 0.0f, 0.0f, 0.0f ), - Vector4( 0.0f, f, 0.0f, 0.0f ), - Vector4( 0.0f, 0.0f, ( ( zNear + zFar ) * rangeInv ), -1.0f ), - Vector4( 0.0f, 0.0f, ( ( ( zNear * zFar ) * rangeInv ) * 2.0f ), 0.0f ) - ); + float f, rangeInv; + f = tanf(((float)(_VECTORMATH_PI_OVER_2) - (0.5f * fovyRadians))); + rangeInv = (1.0f / (zNear - zFar)); + return Matrix4( + Vector4((f / aspect), 0.0f, 0.0f, 0.0f), + Vector4(0.0f, f, 0.0f, 0.0f), + Vector4(0.0f, 0.0f, ((zNear + zFar) * rangeInv), -1.0f), + Vector4(0.0f, 0.0f, (((zNear * zFar) * rangeInv) * 2.0f), 0.0f)); } -inline const Matrix4 Matrix4::frustum( float left, float right, float bottom, float top, float zNear, float zFar ) +inline const Matrix4 Matrix4::frustum(float left, float right, float bottom, float top, float zNear, float zFar) { - float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf, n2; - sum_rl = ( right + left ); - sum_tb = ( top + bottom ); - sum_nf = ( zNear + zFar ); - inv_rl = ( 1.0f / ( right - left ) ); - inv_tb = ( 1.0f / ( top - bottom ) ); - inv_nf = ( 1.0f / ( zNear - zFar ) ); - n2 = ( zNear + zNear ); - return Matrix4( - Vector4( ( n2 * inv_rl ), 0.0f, 0.0f, 0.0f ), - Vector4( 0.0f, ( n2 * inv_tb ), 0.0f, 0.0f ), - Vector4( ( sum_rl * inv_rl ), ( sum_tb * inv_tb ), ( sum_nf * inv_nf ), -1.0f ), - Vector4( 0.0f, 0.0f, ( ( n2 * inv_nf ) * zFar ), 0.0f ) - ); + float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf, n2; + sum_rl = (right + left); + sum_tb = (top + bottom); + sum_nf = (zNear + zFar); + inv_rl = (1.0f / (right - left)); + inv_tb = (1.0f / (top - bottom)); + inv_nf = (1.0f / (zNear - zFar)); + n2 = (zNear + zNear); + return Matrix4( + Vector4((n2 * inv_rl), 0.0f, 0.0f, 0.0f), + Vector4(0.0f, (n2 * inv_tb), 0.0f, 0.0f), + Vector4((sum_rl * inv_rl), (sum_tb * inv_tb), (sum_nf * inv_nf), -1.0f), + Vector4(0.0f, 0.0f, ((n2 * inv_nf) * zFar), 0.0f)); } -inline const Matrix4 Matrix4::orthographic( float left, float right, float bottom, float top, float zNear, float zFar ) +inline const Matrix4 Matrix4::orthographic(float left, float right, float bottom, float top, float zNear, float zFar) { - float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf; - sum_rl = ( right + left ); - sum_tb = ( top + bottom ); - sum_nf = ( zNear + zFar ); - inv_rl = ( 1.0f / ( right - left ) ); - inv_tb = ( 1.0f / ( top - bottom ) ); - inv_nf = ( 1.0f / ( zNear - zFar ) ); - return Matrix4( - Vector4( ( inv_rl + inv_rl ), 0.0f, 0.0f, 0.0f ), - Vector4( 0.0f, ( inv_tb + inv_tb ), 0.0f, 0.0f ), - Vector4( 0.0f, 0.0f, ( inv_nf + inv_nf ), 0.0f ), - Vector4( ( -sum_rl * inv_rl ), ( -sum_tb * inv_tb ), ( sum_nf * inv_nf ), 1.0f ) - ); + float sum_rl, sum_tb, sum_nf, inv_rl, inv_tb, inv_nf; + sum_rl = (right + left); + sum_tb = (top + bottom); + sum_nf = (zNear + zFar); + inv_rl = (1.0f / (right - left)); + inv_tb = (1.0f / (top - bottom)); + inv_nf = (1.0f / (zNear - zFar)); + return Matrix4( + Vector4((inv_rl + inv_rl), 0.0f, 0.0f, 0.0f), + Vector4(0.0f, (inv_tb + inv_tb), 0.0f, 0.0f), + Vector4(0.0f, 0.0f, (inv_nf + inv_nf), 0.0f), + Vector4((-sum_rl * inv_rl), (-sum_tb * inv_tb), (sum_nf * inv_nf), 1.0f)); } -inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ) +inline const Matrix4 select(const Matrix4 &mat0, const Matrix4 &mat1, bool select1) { - return Matrix4( - select( mat0.getCol0(), mat1.getCol0(), select1 ), - select( mat0.getCol1(), mat1.getCol1(), select1 ), - select( mat0.getCol2(), mat1.getCol2(), select1 ), - select( mat0.getCol3(), mat1.getCol3(), select1 ) - ); + return Matrix4( + select(mat0.getCol0(), mat1.getCol0(), select1), + select(mat0.getCol1(), mat1.getCol1(), select1), + select(mat0.getCol2(), mat1.getCol2(), select1), + select(mat0.getCol3(), mat1.getCol3(), select1)); } #ifdef _VECTORMATH_DEBUG -inline void print( const Matrix4 & mat ) +inline void print(const Matrix4 &mat) { - print( mat.getRow( 0 ) ); - print( mat.getRow( 1 ) ); - print( mat.getRow( 2 ) ); - print( mat.getRow( 3 ) ); + print(mat.getRow(0)); + print(mat.getRow(1)); + print(mat.getRow(2)); + print(mat.getRow(3)); } -inline void print( const Matrix4 & mat, const char * name ) +inline void print(const Matrix4 &mat, const char *name) { - printf("%s:\n", name); - print( mat ); + printf("%s:\n", name); + print(mat); } #endif -inline Transform3::Transform3( const Transform3 & tfrm ) +inline Transform3::Transform3(const Transform3 &tfrm) { - mCol0 = tfrm.mCol0; - mCol1 = tfrm.mCol1; - mCol2 = tfrm.mCol2; - mCol3 = tfrm.mCol3; + mCol0 = tfrm.mCol0; + mCol1 = tfrm.mCol1; + mCol2 = tfrm.mCol2; + mCol3 = tfrm.mCol3; } -inline Transform3::Transform3( float scalar ) +inline Transform3::Transform3(float scalar) { - mCol0 = Vector3( scalar ); - mCol1 = Vector3( scalar ); - mCol2 = Vector3( scalar ); - mCol3 = Vector3( scalar ); + mCol0 = Vector3(scalar); + mCol1 = Vector3(scalar); + mCol2 = Vector3(scalar); + mCol3 = Vector3(scalar); } -inline Transform3::Transform3( const Vector3 & _col0, const Vector3 & _col1, const Vector3 & _col2, const Vector3 & _col3 ) +inline Transform3::Transform3(const Vector3 &_col0, const Vector3 &_col1, const Vector3 &_col2, const Vector3 &_col3) { - mCol0 = _col0; - mCol1 = _col1; - mCol2 = _col2; - mCol3 = _col3; + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; + mCol3 = _col3; } -inline Transform3::Transform3( const Matrix3 & tfrm, const Vector3 & translateVec ) +inline Transform3::Transform3(const Matrix3 &tfrm, const Vector3 &translateVec) { - this->setUpper3x3( tfrm ); - this->setTranslation( translateVec ); + this->setUpper3x3(tfrm); + this->setTranslation(translateVec); } -inline Transform3::Transform3( const Quat & unitQuat, const Vector3 & translateVec ) +inline Transform3::Transform3(const Quat &unitQuat, const Vector3 &translateVec) { - this->setUpper3x3( Matrix3( unitQuat ) ); - this->setTranslation( translateVec ); + this->setUpper3x3(Matrix3(unitQuat)); + this->setTranslation(translateVec); } -inline Transform3 & Transform3::setCol0( const Vector3 & _col0 ) +inline Transform3 &Transform3::setCol0(const Vector3 &_col0) { - mCol0 = _col0; - return *this; + mCol0 = _col0; + return *this; } -inline Transform3 & Transform3::setCol1( const Vector3 & _col1 ) +inline Transform3 &Transform3::setCol1(const Vector3 &_col1) { - mCol1 = _col1; - return *this; + mCol1 = _col1; + return *this; } -inline Transform3 & Transform3::setCol2( const Vector3 & _col2 ) +inline Transform3 &Transform3::setCol2(const Vector3 &_col2) { - mCol2 = _col2; - return *this; + mCol2 = _col2; + return *this; } -inline Transform3 & Transform3::setCol3( const Vector3 & _col3 ) +inline Transform3 &Transform3::setCol3(const Vector3 &_col3) { - mCol3 = _col3; - return *this; + mCol3 = _col3; + return *this; } -inline Transform3 & Transform3::setCol( int col, const Vector3 & vec ) +inline Transform3 &Transform3::setCol(int col, const Vector3 &vec) { - *(&mCol0 + col) = vec; - return *this; + *(&mCol0 + col) = vec; + return *this; } -inline Transform3 & Transform3::setRow( int row, const Vector4 & vec ) +inline Transform3 &Transform3::setRow(int row, const Vector4 &vec) { - mCol0.setElem( row, vec.getElem( 0 ) ); - mCol1.setElem( row, vec.getElem( 1 ) ); - mCol2.setElem( row, vec.getElem( 2 ) ); - mCol3.setElem( row, vec.getElem( 3 ) ); - return *this; + mCol0.setElem(row, vec.getElem(0)); + mCol1.setElem(row, vec.getElem(1)); + mCol2.setElem(row, vec.getElem(2)); + mCol3.setElem(row, vec.getElem(3)); + return *this; } -inline Transform3 & Transform3::setElem( int col, int row, float val ) +inline Transform3 &Transform3::setElem(int col, int row, float val) { - Vector3 tmpV3_0; - tmpV3_0 = this->getCol( col ); - tmpV3_0.setElem( row, val ); - this->setCol( col, tmpV3_0 ); - return *this; + Vector3 tmpV3_0; + tmpV3_0 = this->getCol(col); + tmpV3_0.setElem(row, val); + this->setCol(col, tmpV3_0); + return *this; } -inline float Transform3::getElem( int col, int row ) const +inline float Transform3::getElem(int col, int row) const { - return this->getCol( col ).getElem( row ); + return this->getCol(col).getElem(row); } -inline const Vector3 Transform3::getCol0( ) const +inline const Vector3 Transform3::getCol0() const { - return mCol0; + return mCol0; } -inline const Vector3 Transform3::getCol1( ) const +inline const Vector3 Transform3::getCol1() const { - return mCol1; + return mCol1; } -inline const Vector3 Transform3::getCol2( ) const +inline const Vector3 Transform3::getCol2() const { - return mCol2; + return mCol2; } -inline const Vector3 Transform3::getCol3( ) const +inline const Vector3 Transform3::getCol3() const { - return mCol3; + return mCol3; } -inline const Vector3 Transform3::getCol( int col ) const +inline const Vector3 Transform3::getCol(int col) const { - return *(&mCol0 + col); + return *(&mCol0 + col); } -inline const Vector4 Transform3::getRow( int row ) const +inline const Vector4 Transform3::getRow(int row) const { - return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); + return Vector4(mCol0.getElem(row), mCol1.getElem(row), mCol2.getElem(row), mCol3.getElem(row)); } -inline Vector3 & Transform3::operator []( int col ) +inline Vector3 &Transform3::operator[](int col) { - return *(&mCol0 + col); + return *(&mCol0 + col); } -inline const Vector3 Transform3::operator []( int col ) const +inline const Vector3 Transform3::operator[](int col) const { - return *(&mCol0 + col); + return *(&mCol0 + col); } -inline Transform3 & Transform3::operator =( const Transform3 & tfrm ) +inline Transform3 &Transform3::operator=(const Transform3 &tfrm) { - mCol0 = tfrm.mCol0; - mCol1 = tfrm.mCol1; - mCol2 = tfrm.mCol2; - mCol3 = tfrm.mCol3; - return *this; + mCol0 = tfrm.mCol0; + mCol1 = tfrm.mCol1; + mCol2 = tfrm.mCol2; + mCol3 = tfrm.mCol3; + return *this; } -inline const Transform3 inverse( const Transform3 & tfrm ) +inline const Transform3 inverse(const Transform3 &tfrm) { - Vector3 tmp0, tmp1, tmp2, inv0, inv1, inv2; - float detinv; - tmp0 = cross( tfrm.getCol1(), tfrm.getCol2() ); - tmp1 = cross( tfrm.getCol2(), tfrm.getCol0() ); - tmp2 = cross( tfrm.getCol0(), tfrm.getCol1() ); - detinv = ( 1.0f / dot( tfrm.getCol2(), tmp2 ) ); - inv0 = Vector3( ( tmp0.getX() * detinv ), ( tmp1.getX() * detinv ), ( tmp2.getX() * detinv ) ); - inv1 = Vector3( ( tmp0.getY() * detinv ), ( tmp1.getY() * detinv ), ( tmp2.getY() * detinv ) ); - inv2 = Vector3( ( tmp0.getZ() * detinv ), ( tmp1.getZ() * detinv ), ( tmp2.getZ() * detinv ) ); - return Transform3( - inv0, - inv1, - inv2, - Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) ) - ); + Vector3 tmp0, tmp1, tmp2, inv0, inv1, inv2; + float detinv; + tmp0 = cross(tfrm.getCol1(), tfrm.getCol2()); + tmp1 = cross(tfrm.getCol2(), tfrm.getCol0()); + tmp2 = cross(tfrm.getCol0(), tfrm.getCol1()); + detinv = (1.0f / dot(tfrm.getCol2(), tmp2)); + inv0 = Vector3((tmp0.getX() * detinv), (tmp1.getX() * detinv), (tmp2.getX() * detinv)); + inv1 = Vector3((tmp0.getY() * detinv), (tmp1.getY() * detinv), (tmp2.getY() * detinv)); + inv2 = Vector3((tmp0.getZ() * detinv), (tmp1.getZ() * detinv), (tmp2.getZ() * detinv)); + return Transform3( + inv0, + inv1, + inv2, + Vector3((-((inv0 * tfrm.getCol3().getX()) + ((inv1 * tfrm.getCol3().getY()) + (inv2 * tfrm.getCol3().getZ())))))); } -inline const Transform3 orthoInverse( const Transform3 & tfrm ) +inline const Transform3 orthoInverse(const Transform3 &tfrm) { - Vector3 inv0, inv1, inv2; - inv0 = Vector3( tfrm.getCol0().getX(), tfrm.getCol1().getX(), tfrm.getCol2().getX() ); - inv1 = Vector3( tfrm.getCol0().getY(), tfrm.getCol1().getY(), tfrm.getCol2().getY() ); - inv2 = Vector3( tfrm.getCol0().getZ(), tfrm.getCol1().getZ(), tfrm.getCol2().getZ() ); - return Transform3( - inv0, - inv1, - inv2, - Vector3( ( -( ( inv0 * tfrm.getCol3().getX() ) + ( ( inv1 * tfrm.getCol3().getY() ) + ( inv2 * tfrm.getCol3().getZ() ) ) ) ) ) - ); + Vector3 inv0, inv1, inv2; + inv0 = Vector3(tfrm.getCol0().getX(), tfrm.getCol1().getX(), tfrm.getCol2().getX()); + inv1 = Vector3(tfrm.getCol0().getY(), tfrm.getCol1().getY(), tfrm.getCol2().getY()); + inv2 = Vector3(tfrm.getCol0().getZ(), tfrm.getCol1().getZ(), tfrm.getCol2().getZ()); + return Transform3( + inv0, + inv1, + inv2, + Vector3((-((inv0 * tfrm.getCol3().getX()) + ((inv1 * tfrm.getCol3().getY()) + (inv2 * tfrm.getCol3().getZ())))))); } -inline const Transform3 absPerElem( const Transform3 & tfrm ) +inline const Transform3 absPerElem(const Transform3 &tfrm) { - return Transform3( - absPerElem( tfrm.getCol0() ), - absPerElem( tfrm.getCol1() ), - absPerElem( tfrm.getCol2() ), - absPerElem( tfrm.getCol3() ) - ); + return Transform3( + absPerElem(tfrm.getCol0()), + absPerElem(tfrm.getCol1()), + absPerElem(tfrm.getCol2()), + absPerElem(tfrm.getCol3())); } -inline const Vector3 Transform3::operator *( const Vector3 & vec ) const +inline const Vector3 Transform3::operator*(const Vector3 &vec) const { - return Vector3( - ( ( ( mCol0.getX() * vec.getX() ) + ( mCol1.getX() * vec.getY() ) ) + ( mCol2.getX() * vec.getZ() ) ), - ( ( ( mCol0.getY() * vec.getX() ) + ( mCol1.getY() * vec.getY() ) ) + ( mCol2.getY() * vec.getZ() ) ), - ( ( ( mCol0.getZ() * vec.getX() ) + ( mCol1.getZ() * vec.getY() ) ) + ( mCol2.getZ() * vec.getZ() ) ) - ); + return Vector3( + (((mCol0.getX() * vec.getX()) + (mCol1.getX() * vec.getY())) + (mCol2.getX() * vec.getZ())), + (((mCol0.getY() * vec.getX()) + (mCol1.getY() * vec.getY())) + (mCol2.getY() * vec.getZ())), + (((mCol0.getZ() * vec.getX()) + (mCol1.getZ() * vec.getY())) + (mCol2.getZ() * vec.getZ()))); } -inline const Point3 Transform3::operator *( const Point3 & pnt ) const +inline const Point3 Transform3::operator*(const Point3 &pnt) const { - return Point3( - ( ( ( ( mCol0.getX() * pnt.getX() ) + ( mCol1.getX() * pnt.getY() ) ) + ( mCol2.getX() * pnt.getZ() ) ) + mCol3.getX() ), - ( ( ( ( mCol0.getY() * pnt.getX() ) + ( mCol1.getY() * pnt.getY() ) ) + ( mCol2.getY() * pnt.getZ() ) ) + mCol3.getY() ), - ( ( ( ( mCol0.getZ() * pnt.getX() ) + ( mCol1.getZ() * pnt.getY() ) ) + ( mCol2.getZ() * pnt.getZ() ) ) + mCol3.getZ() ) - ); + return Point3( + ((((mCol0.getX() * pnt.getX()) + (mCol1.getX() * pnt.getY())) + (mCol2.getX() * pnt.getZ())) + mCol3.getX()), + ((((mCol0.getY() * pnt.getX()) + (mCol1.getY() * pnt.getY())) + (mCol2.getY() * pnt.getZ())) + mCol3.getY()), + ((((mCol0.getZ() * pnt.getX()) + (mCol1.getZ() * pnt.getY())) + (mCol2.getZ() * pnt.getZ())) + mCol3.getZ())); } -inline const Transform3 Transform3::operator *( const Transform3 & tfrm ) const +inline const Transform3 Transform3::operator*(const Transform3 &tfrm) const { - return Transform3( - ( *this * tfrm.mCol0 ), - ( *this * tfrm.mCol1 ), - ( *this * tfrm.mCol2 ), - Vector3( ( *this * Point3( tfrm.mCol3 ) ) ) - ); + return Transform3( + (*this * tfrm.mCol0), + (*this * tfrm.mCol1), + (*this * tfrm.mCol2), + Vector3((*this * Point3(tfrm.mCol3)))); } -inline Transform3 & Transform3::operator *=( const Transform3 & tfrm ) +inline Transform3 &Transform3::operator*=(const Transform3 &tfrm) { - *this = *this * tfrm; - return *this; + *this = *this * tfrm; + return *this; } -inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ) +inline const Transform3 mulPerElem(const Transform3 &tfrm0, const Transform3 &tfrm1) { - return Transform3( - mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ), - mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ), - mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ), - mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() ) - ); + return Transform3( + mulPerElem(tfrm0.getCol0(), tfrm1.getCol0()), + mulPerElem(tfrm0.getCol1(), tfrm1.getCol1()), + mulPerElem(tfrm0.getCol2(), tfrm1.getCol2()), + mulPerElem(tfrm0.getCol3(), tfrm1.getCol3())); } -inline const Transform3 Transform3::identity( ) +inline const Transform3 Transform3::identity() { - return Transform3( - Vector3::xAxis( ), - Vector3::yAxis( ), - Vector3::zAxis( ), - Vector3( 0.0f ) - ); + return Transform3( + Vector3::xAxis(), + Vector3::yAxis(), + Vector3::zAxis(), + Vector3(0.0f)); } -inline Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm ) +inline Transform3 &Transform3::setUpper3x3(const Matrix3 &tfrm) { - mCol0 = tfrm.getCol0(); - mCol1 = tfrm.getCol1(); - mCol2 = tfrm.getCol2(); - return *this; + mCol0 = tfrm.getCol0(); + mCol1 = tfrm.getCol1(); + mCol2 = tfrm.getCol2(); + return *this; } -inline const Matrix3 Transform3::getUpper3x3( ) const +inline const Matrix3 Transform3::getUpper3x3() const { - return Matrix3( mCol0, mCol1, mCol2 ); + return Matrix3(mCol0, mCol1, mCol2); } -inline Transform3 & Transform3::setTranslation( const Vector3 & translateVec ) +inline Transform3 &Transform3::setTranslation(const Vector3 &translateVec) { - mCol3 = translateVec; - return *this; + mCol3 = translateVec; + return *this; } -inline const Vector3 Transform3::getTranslation( ) const +inline const Vector3 Transform3::getTranslation() const { - return mCol3; + return mCol3; } -inline const Transform3 Transform3::rotationX( float radians ) +inline const Transform3 Transform3::rotationX(float radians) { - float s, c; - s = sinf( radians ); - c = cosf( radians ); - return Transform3( - Vector3::xAxis( ), - Vector3( 0.0f, c, s ), - Vector3( 0.0f, -s, c ), - Vector3( 0.0f ) - ); + float s, c; + s = sinf(radians); + c = cosf(radians); + return Transform3( + Vector3::xAxis(), + Vector3(0.0f, c, s), + Vector3(0.0f, -s, c), + Vector3(0.0f)); } -inline const Transform3 Transform3::rotationY( float radians ) +inline const Transform3 Transform3::rotationY(float radians) { - float s, c; - s = sinf( radians ); - c = cosf( radians ); - return Transform3( - Vector3( c, 0.0f, -s ), - Vector3::yAxis( ), - Vector3( s, 0.0f, c ), - Vector3( 0.0f ) - ); + float s, c; + s = sinf(radians); + c = cosf(radians); + return Transform3( + Vector3(c, 0.0f, -s), + Vector3::yAxis(), + Vector3(s, 0.0f, c), + Vector3(0.0f)); } -inline const Transform3 Transform3::rotationZ( float radians ) +inline const Transform3 Transform3::rotationZ(float radians) { - float s, c; - s = sinf( radians ); - c = cosf( radians ); - return Transform3( - Vector3( c, s, 0.0f ), - Vector3( -s, c, 0.0f ), - Vector3::zAxis( ), - Vector3( 0.0f ) - ); + float s, c; + s = sinf(radians); + c = cosf(radians); + return Transform3( + Vector3(c, s, 0.0f), + Vector3(-s, c, 0.0f), + Vector3::zAxis(), + Vector3(0.0f)); } -inline const Transform3 Transform3::rotationZYX( const Vector3 & radiansXYZ ) +inline const Transform3 Transform3::rotationZYX(const Vector3 &radiansXYZ) { - float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; - sX = sinf( radiansXYZ.getX() ); - cX = cosf( radiansXYZ.getX() ); - sY = sinf( radiansXYZ.getY() ); - cY = cosf( radiansXYZ.getY() ); - sZ = sinf( radiansXYZ.getZ() ); - cZ = cosf( radiansXYZ.getZ() ); - tmp0 = ( cZ * sY ); - tmp1 = ( sZ * sY ); - return Transform3( - Vector3( ( cZ * cY ), ( sZ * cY ), -sY ), - Vector3( ( ( tmp0 * sX ) - ( sZ * cX ) ), ( ( tmp1 * sX ) + ( cZ * cX ) ), ( cY * sX ) ), - Vector3( ( ( tmp0 * cX ) + ( sZ * sX ) ), ( ( tmp1 * cX ) - ( cZ * sX ) ), ( cY * cX ) ), - Vector3( 0.0f ) - ); + float sX, cX, sY, cY, sZ, cZ, tmp0, tmp1; + sX = sinf(radiansXYZ.getX()); + cX = cosf(radiansXYZ.getX()); + sY = sinf(radiansXYZ.getY()); + cY = cosf(radiansXYZ.getY()); + sZ = sinf(radiansXYZ.getZ()); + cZ = cosf(radiansXYZ.getZ()); + tmp0 = (cZ * sY); + tmp1 = (sZ * sY); + return Transform3( + Vector3((cZ * cY), (sZ * cY), -sY), + Vector3(((tmp0 * sX) - (sZ * cX)), ((tmp1 * sX) + (cZ * cX)), (cY * sX)), + Vector3(((tmp0 * cX) + (sZ * sX)), ((tmp1 * cX) - (cZ * sX)), (cY * cX)), + Vector3(0.0f)); } -inline const Transform3 Transform3::rotation( float radians, const Vector3 & unitVec ) +inline const Transform3 Transform3::rotation(float radians, const Vector3 &unitVec) { - return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( 0.0f ) ); + return Transform3(Matrix3::rotation(radians, unitVec), Vector3(0.0f)); } -inline const Transform3 Transform3::rotation( const Quat & unitQuat ) +inline const Transform3 Transform3::rotation(const Quat &unitQuat) { - return Transform3( Matrix3( unitQuat ), Vector3( 0.0f ) ); + return Transform3(Matrix3(unitQuat), Vector3(0.0f)); } -inline const Transform3 Transform3::scale( const Vector3 & scaleVec ) +inline const Transform3 Transform3::scale(const Vector3 &scaleVec) { - return Transform3( - Vector3( scaleVec.getX(), 0.0f, 0.0f ), - Vector3( 0.0f, scaleVec.getY(), 0.0f ), - Vector3( 0.0f, 0.0f, scaleVec.getZ() ), - Vector3( 0.0f ) - ); + return Transform3( + Vector3(scaleVec.getX(), 0.0f, 0.0f), + Vector3(0.0f, scaleVec.getY(), 0.0f), + Vector3(0.0f, 0.0f, scaleVec.getZ()), + Vector3(0.0f)); } -inline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec ) +inline const Transform3 appendScale(const Transform3 &tfrm, const Vector3 &scaleVec) { - return Transform3( - ( tfrm.getCol0() * scaleVec.getX( ) ), - ( tfrm.getCol1() * scaleVec.getY( ) ), - ( tfrm.getCol2() * scaleVec.getZ( ) ), - tfrm.getCol3() - ); + return Transform3( + (tfrm.getCol0() * scaleVec.getX()), + (tfrm.getCol1() * scaleVec.getY()), + (tfrm.getCol2() * scaleVec.getZ()), + tfrm.getCol3()); } -inline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm ) +inline const Transform3 prependScale(const Vector3 &scaleVec, const Transform3 &tfrm) { - return Transform3( - mulPerElem( tfrm.getCol0(), scaleVec ), - mulPerElem( tfrm.getCol1(), scaleVec ), - mulPerElem( tfrm.getCol2(), scaleVec ), - mulPerElem( tfrm.getCol3(), scaleVec ) - ); + return Transform3( + mulPerElem(tfrm.getCol0(), scaleVec), + mulPerElem(tfrm.getCol1(), scaleVec), + mulPerElem(tfrm.getCol2(), scaleVec), + mulPerElem(tfrm.getCol3(), scaleVec)); } -inline const Transform3 Transform3::translation( const Vector3 & translateVec ) +inline const Transform3 Transform3::translation(const Vector3 &translateVec) { - return Transform3( - Vector3::xAxis( ), - Vector3::yAxis( ), - Vector3::zAxis( ), - translateVec - ); + return Transform3( + Vector3::xAxis(), + Vector3::yAxis(), + Vector3::zAxis(), + translateVec); } -inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ) +inline const Transform3 select(const Transform3 &tfrm0, const Transform3 &tfrm1, bool select1) { - return Transform3( - select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ), - select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ), - select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ), - select( tfrm0.getCol3(), tfrm1.getCol3(), select1 ) - ); + return Transform3( + select(tfrm0.getCol0(), tfrm1.getCol0(), select1), + select(tfrm0.getCol1(), tfrm1.getCol1(), select1), + select(tfrm0.getCol2(), tfrm1.getCol2(), select1), + select(tfrm0.getCol3(), tfrm1.getCol3(), select1)); } #ifdef _VECTORMATH_DEBUG -inline void print( const Transform3 & tfrm ) +inline void print(const Transform3 &tfrm) { - print( tfrm.getRow( 0 ) ); - print( tfrm.getRow( 1 ) ); - print( tfrm.getRow( 2 ) ); + print(tfrm.getRow(0)); + print(tfrm.getRow(1)); + print(tfrm.getRow(2)); } -inline void print( const Transform3 & tfrm, const char * name ) +inline void print(const Transform3 &tfrm, const char *name) { - printf("%s:\n", name); - print( tfrm ); + printf("%s:\n", name); + print(tfrm); } #endif -inline Quat::Quat( const Matrix3 & tfrm ) +inline Quat::Quat(const Matrix3 &tfrm) { - float trace, radicand, scale, xx, yx, zx, xy, yy, zy, xz, yz, zz, tmpx, tmpy, tmpz, tmpw, qx, qy, qz, qw; - int negTrace, ZgtX, ZgtY, YgtX; - int largestXorY, largestYorZ, largestZorX; + float trace, radicand, scale, xx, yx, zx, xy, yy, zy, xz, yz, zz, tmpx, tmpy, tmpz, tmpw, qx, qy, qz, qw; + int negTrace, ZgtX, ZgtY, YgtX; + int largestXorY, largestYorZ, largestZorX; - xx = tfrm.getCol0().getX(); - yx = tfrm.getCol0().getY(); - zx = tfrm.getCol0().getZ(); - xy = tfrm.getCol1().getX(); - yy = tfrm.getCol1().getY(); - zy = tfrm.getCol1().getZ(); - xz = tfrm.getCol2().getX(); - yz = tfrm.getCol2().getY(); - zz = tfrm.getCol2().getZ(); + xx = tfrm.getCol0().getX(); + yx = tfrm.getCol0().getY(); + zx = tfrm.getCol0().getZ(); + xy = tfrm.getCol1().getX(); + yy = tfrm.getCol1().getY(); + zy = tfrm.getCol1().getZ(); + xz = tfrm.getCol2().getX(); + yz = tfrm.getCol2().getY(); + zz = tfrm.getCol2().getZ(); - trace = ( ( xx + yy ) + zz ); + trace = ((xx + yy) + zz); - negTrace = ( trace < 0.0f ); - ZgtX = zz > xx; - ZgtY = zz > yy; - YgtX = yy > xx; - largestXorY = ( !ZgtX || !ZgtY ) && negTrace; - largestYorZ = ( YgtX || ZgtX ) && negTrace; - largestZorX = ( ZgtY || !YgtX ) && negTrace; - - if ( largestXorY ) - { - zz = -zz; - xy = -xy; - } - if ( largestYorZ ) - { - xx = -xx; - yz = -yz; - } - if ( largestZorX ) - { - yy = -yy; - zx = -zx; - } + negTrace = (trace < 0.0f); + ZgtX = zz > xx; + ZgtY = zz > yy; + YgtX = yy > xx; + largestXorY = (!ZgtX || !ZgtY) && negTrace; + largestYorZ = (YgtX || ZgtX) && negTrace; + largestZorX = (ZgtY || !YgtX) && negTrace; - radicand = ( ( ( xx + yy ) + zz ) + 1.0f ); - scale = ( 0.5f * ( 1.0f / sqrtf( radicand ) ) ); + if (largestXorY) + { + zz = -zz; + xy = -xy; + } + if (largestYorZ) + { + xx = -xx; + yz = -yz; + } + if (largestZorX) + { + yy = -yy; + zx = -zx; + } - tmpx = ( ( zy - yz ) * scale ); - tmpy = ( ( xz - zx ) * scale ); - tmpz = ( ( yx - xy ) * scale ); - tmpw = ( radicand * scale ); - qx = tmpx; - qy = tmpy; - qz = tmpz; - qw = tmpw; + radicand = (((xx + yy) + zz) + 1.0f); + scale = (0.5f * (1.0f / sqrtf(radicand))); - if ( largestXorY ) - { - qx = tmpw; - qy = tmpz; - qz = tmpy; - qw = tmpx; - } - if ( largestYorZ ) - { - tmpx = qx; - tmpz = qz; - qx = qy; - qy = tmpx; - qz = qw; - qw = tmpz; - } + tmpx = ((zy - yz) * scale); + tmpy = ((xz - zx) * scale); + tmpz = ((yx - xy) * scale); + tmpw = (radicand * scale); + qx = tmpx; + qy = tmpy; + qz = tmpz; + qw = tmpw; - mX = qx; - mY = qy; - mZ = qz; - mW = qw; + if (largestXorY) + { + qx = tmpw; + qy = tmpz; + qz = tmpy; + qw = tmpx; + } + if (largestYorZ) + { + tmpx = qx; + tmpz = qz; + qx = qy; + qy = tmpx; + qz = qw; + qw = tmpz; + } + + mX = qx; + mY = qy; + mZ = qz; + mW = qw; } -inline const Matrix3 outer( const Vector3 & tfrm0, const Vector3 & tfrm1 ) +inline const Matrix3 outer(const Vector3 &tfrm0, const Vector3 &tfrm1) { - return Matrix3( - ( tfrm0 * tfrm1.getX( ) ), - ( tfrm0 * tfrm1.getY( ) ), - ( tfrm0 * tfrm1.getZ( ) ) - ); + return Matrix3( + (tfrm0 * tfrm1.getX()), + (tfrm0 * tfrm1.getY()), + (tfrm0 * tfrm1.getZ())); } -inline const Matrix4 outer( const Vector4 & tfrm0, const Vector4 & tfrm1 ) +inline const Matrix4 outer(const Vector4 &tfrm0, const Vector4 &tfrm1) { - return Matrix4( - ( tfrm0 * tfrm1.getX( ) ), - ( tfrm0 * tfrm1.getY( ) ), - ( tfrm0 * tfrm1.getZ( ) ), - ( tfrm0 * tfrm1.getW( ) ) - ); + return Matrix4( + (tfrm0 * tfrm1.getX()), + (tfrm0 * tfrm1.getY()), + (tfrm0 * tfrm1.getZ()), + (tfrm0 * tfrm1.getW())); } -inline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat ) +inline const Vector3 rowMul(const Vector3 &vec, const Matrix3 &mat) { - return Vector3( - ( ( ( vec.getX() * mat.getCol0().getX() ) + ( vec.getY() * mat.getCol0().getY() ) ) + ( vec.getZ() * mat.getCol0().getZ() ) ), - ( ( ( vec.getX() * mat.getCol1().getX() ) + ( vec.getY() * mat.getCol1().getY() ) ) + ( vec.getZ() * mat.getCol1().getZ() ) ), - ( ( ( vec.getX() * mat.getCol2().getX() ) + ( vec.getY() * mat.getCol2().getY() ) ) + ( vec.getZ() * mat.getCol2().getZ() ) ) - ); + return Vector3( + (((vec.getX() * mat.getCol0().getX()) + (vec.getY() * mat.getCol0().getY())) + (vec.getZ() * mat.getCol0().getZ())), + (((vec.getX() * mat.getCol1().getX()) + (vec.getY() * mat.getCol1().getY())) + (vec.getZ() * mat.getCol1().getZ())), + (((vec.getX() * mat.getCol2().getX()) + (vec.getY() * mat.getCol2().getY())) + (vec.getZ() * mat.getCol2().getZ()))); } -inline const Matrix3 crossMatrix( const Vector3 & vec ) +inline const Matrix3 crossMatrix(const Vector3 &vec) { - return Matrix3( - Vector3( 0.0f, vec.getZ(), -vec.getY() ), - Vector3( -vec.getZ(), 0.0f, vec.getX() ), - Vector3( vec.getY(), -vec.getX(), 0.0f ) - ); + return Matrix3( + Vector3(0.0f, vec.getZ(), -vec.getY()), + Vector3(-vec.getZ(), 0.0f, vec.getX()), + Vector3(vec.getY(), -vec.getX(), 0.0f)); } -inline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat ) +inline const Matrix3 crossMatrixMul(const Vector3 &vec, const Matrix3 &mat) { - return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) ); + return Matrix3(cross(vec, mat.getCol0()), cross(vec, mat.getCol1()), cross(vec, mat.getCol2())); } -} // namespace Aos -} // namespace Vectormath +} // namespace Aos +} // namespace Vectormath #endif diff --git a/test/Bullet2/vectormath/scalar/quat_aos.h b/test/Bullet2/vectormath/scalar/quat_aos.h index 764e01708..5e473af86 100644 --- a/test/Bullet2/vectormath/scalar/quat_aos.h +++ b/test/Bullet2/vectormath/scalar/quat_aos.h @@ -25,409 +25,407 @@ subject to the following restrictions: #endif -namespace Vectormath { -namespace Aos { - -inline Quat::Quat( const Quat & quat ) +namespace Vectormath { - mX = quat.mX; - mY = quat.mY; - mZ = quat.mZ; - mW = quat.mW; +namespace Aos +{ +inline Quat::Quat(const Quat &quat) +{ + mX = quat.mX; + mY = quat.mY; + mZ = quat.mZ; + mW = quat.mW; } -inline Quat::Quat( float _x, float _y, float _z, float _w ) +inline Quat::Quat(float _x, float _y, float _z, float _w) { - mX = _x; - mY = _y; - mZ = _z; - mW = _w; + mX = _x; + mY = _y; + mZ = _z; + mW = _w; } -inline Quat::Quat( const Vector3 & xyz, float _w ) +inline Quat::Quat(const Vector3 &xyz, float _w) { - this->setXYZ( xyz ); - this->setW( _w ); + this->setXYZ(xyz); + this->setW(_w); } -inline Quat::Quat( const Vector4 & vec ) +inline Quat::Quat(const Vector4 &vec) { - mX = vec.getX(); - mY = vec.getY(); - mZ = vec.getZ(); - mW = vec.getW(); + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + mW = vec.getW(); } -inline Quat::Quat( float scalar ) +inline Quat::Quat(float scalar) { - mX = scalar; - mY = scalar; - mZ = scalar; - mW = scalar; + mX = scalar; + mY = scalar; + mZ = scalar; + mW = scalar; } -inline const Quat Quat::identity( ) +inline const Quat Quat::identity() { - return Quat( 0.0f, 0.0f, 0.0f, 1.0f ); + return Quat(0.0f, 0.0f, 0.0f, 1.0f); } -inline const Quat lerp( float t, const Quat & quat0, const Quat & quat1 ) +inline const Quat lerp(float t, const Quat &quat0, const Quat &quat1) { - return ( quat0 + ( ( quat1 - quat0 ) * t ) ); + return (quat0 + ((quat1 - quat0) * t)); } -inline const Quat slerp( float t, const Quat & unitQuat0, const Quat & unitQuat1 ) +inline const Quat slerp(float t, const Quat &unitQuat0, const Quat &unitQuat1) { - Quat start; - float recipSinAngle, scale0, scale1, cosAngle, angle; - cosAngle = dot( unitQuat0, unitQuat1 ); - if ( cosAngle < 0.0f ) { - cosAngle = -cosAngle; - start = ( -unitQuat0 ); - } else { - start = unitQuat0; - } - if ( cosAngle < _VECTORMATH_SLERP_TOL ) { - angle = acosf( cosAngle ); - recipSinAngle = ( 1.0f / sinf( angle ) ); - scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); - scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); - } else { - scale0 = ( 1.0f - t ); - scale1 = t; - } - return ( ( start * scale0 ) + ( unitQuat1 * scale1 ) ); + Quat start; + float recipSinAngle, scale0, scale1, cosAngle, angle; + cosAngle = dot(unitQuat0, unitQuat1); + if (cosAngle < 0.0f) + { + cosAngle = -cosAngle; + start = (-unitQuat0); + } + else + { + start = unitQuat0; + } + if (cosAngle < _VECTORMATH_SLERP_TOL) + { + angle = acosf(cosAngle); + recipSinAngle = (1.0f / sinf(angle)); + scale0 = (sinf(((1.0f - t) * angle)) * recipSinAngle); + scale1 = (sinf((t * angle)) * recipSinAngle); + } + else + { + scale0 = (1.0f - t); + scale1 = t; + } + return ((start * scale0) + (unitQuat1 * scale1)); } -inline const Quat squad( float t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 ) +inline const Quat squad(float t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3) { - Quat tmp0, tmp1; - tmp0 = slerp( t, unitQuat0, unitQuat3 ); - tmp1 = slerp( t, unitQuat1, unitQuat2 ); - return slerp( ( ( 2.0f * t ) * ( 1.0f - t ) ), tmp0, tmp1 ); + Quat tmp0, tmp1; + tmp0 = slerp(t, unitQuat0, unitQuat3); + tmp1 = slerp(t, unitQuat1, unitQuat2); + return slerp(((2.0f * t) * (1.0f - t)), tmp0, tmp1); } -inline void loadXYZW( Quat & quat, const float * fptr ) +inline void loadXYZW(Quat &quat, const float *fptr) { - quat = Quat( fptr[0], fptr[1], fptr[2], fptr[3] ); + quat = Quat(fptr[0], fptr[1], fptr[2], fptr[3]); } -inline void storeXYZW( const Quat & quat, float * fptr ) +inline void storeXYZW(const Quat &quat, float *fptr) { - fptr[0] = quat.getX(); - fptr[1] = quat.getY(); - fptr[2] = quat.getZ(); - fptr[3] = quat.getW(); + fptr[0] = quat.getX(); + fptr[1] = quat.getY(); + fptr[2] = quat.getZ(); + fptr[3] = quat.getW(); } -inline Quat & Quat::operator =( const Quat & quat ) +inline Quat &Quat::operator=(const Quat &quat) { - mX = quat.mX; - mY = quat.mY; - mZ = quat.mZ; - mW = quat.mW; - return *this; + mX = quat.mX; + mY = quat.mY; + mZ = quat.mZ; + mW = quat.mW; + return *this; } -inline Quat & Quat::setXYZ( const Vector3 & vec ) +inline Quat &Quat::setXYZ(const Vector3 &vec) { - mX = vec.getX(); - mY = vec.getY(); - mZ = vec.getZ(); - return *this; + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + return *this; } -inline const Vector3 Quat::getXYZ( ) const +inline const Vector3 Quat::getXYZ() const { - return Vector3( mX, mY, mZ ); + return Vector3(mX, mY, mZ); } -inline Quat & Quat::setX( float _x ) +inline Quat &Quat::setX(float _x) { - mX = _x; - return *this; + mX = _x; + return *this; } -inline float Quat::getX( ) const +inline float Quat::getX() const { - return mX; + return mX; } -inline Quat & Quat::setY( float _y ) +inline Quat &Quat::setY(float _y) { - mY = _y; - return *this; + mY = _y; + return *this; } -inline float Quat::getY( ) const +inline float Quat::getY() const { - return mY; + return mY; } -inline Quat & Quat::setZ( float _z ) +inline Quat &Quat::setZ(float _z) { - mZ = _z; - return *this; + mZ = _z; + return *this; } -inline float Quat::getZ( ) const +inline float Quat::getZ() const { - return mZ; + return mZ; } -inline Quat & Quat::setW( float _w ) +inline Quat &Quat::setW(float _w) { - mW = _w; - return *this; + mW = _w; + return *this; } -inline float Quat::getW( ) const +inline float Quat::getW() const { - return mW; + return mW; } -inline Quat & Quat::setElem( int idx, float value ) +inline Quat &Quat::setElem(int idx, float value) { - *(&mX + idx) = value; - return *this; + *(&mX + idx) = value; + return *this; } -inline float Quat::getElem( int idx ) const +inline float Quat::getElem(int idx) const { - return *(&mX + idx); + return *(&mX + idx); } -inline float & Quat::operator []( int idx ) +inline float &Quat::operator[](int idx) { - return *(&mX + idx); + return *(&mX + idx); } -inline float Quat::operator []( int idx ) const +inline float Quat::operator[](int idx) const { - return *(&mX + idx); + return *(&mX + idx); } -inline const Quat Quat::operator +( const Quat & quat ) const +inline const Quat Quat::operator+(const Quat &quat) const { - return Quat( - ( mX + quat.mX ), - ( mY + quat.mY ), - ( mZ + quat.mZ ), - ( mW + quat.mW ) - ); + return Quat( + (mX + quat.mX), + (mY + quat.mY), + (mZ + quat.mZ), + (mW + quat.mW)); } -inline const Quat Quat::operator -( const Quat & quat ) const +inline const Quat Quat::operator-(const Quat &quat) const { - return Quat( - ( mX - quat.mX ), - ( mY - quat.mY ), - ( mZ - quat.mZ ), - ( mW - quat.mW ) - ); + return Quat( + (mX - quat.mX), + (mY - quat.mY), + (mZ - quat.mZ), + (mW - quat.mW)); } -inline const Quat Quat::operator *( float scalar ) const +inline const Quat Quat::operator*(float scalar) const { - return Quat( - ( mX * scalar ), - ( mY * scalar ), - ( mZ * scalar ), - ( mW * scalar ) - ); + return Quat( + (mX * scalar), + (mY * scalar), + (mZ * scalar), + (mW * scalar)); } -inline Quat & Quat::operator +=( const Quat & quat ) +inline Quat &Quat::operator+=(const Quat &quat) { - *this = *this + quat; - return *this; + *this = *this + quat; + return *this; } -inline Quat & Quat::operator -=( const Quat & quat ) +inline Quat &Quat::operator-=(const Quat &quat) { - *this = *this - quat; - return *this; + *this = *this - quat; + return *this; } -inline Quat & Quat::operator *=( float scalar ) +inline Quat &Quat::operator*=(float scalar) { - *this = *this * scalar; - return *this; + *this = *this * scalar; + return *this; } -inline const Quat Quat::operator /( float scalar ) const +inline const Quat Quat::operator/(float scalar) const { - return Quat( - ( mX / scalar ), - ( mY / scalar ), - ( mZ / scalar ), - ( mW / scalar ) - ); + return Quat( + (mX / scalar), + (mY / scalar), + (mZ / scalar), + (mW / scalar)); } -inline Quat & Quat::operator /=( float scalar ) +inline Quat &Quat::operator/=(float scalar) { - *this = *this / scalar; - return *this; + *this = *this / scalar; + return *this; } -inline const Quat Quat::operator -( ) const +inline const Quat Quat::operator-() const { - return Quat( - -mX, - -mY, - -mZ, - -mW - ); + return Quat( + -mX, + -mY, + -mZ, + -mW); } -inline const Quat operator *( float scalar, const Quat & quat ) +inline const Quat operator*(float scalar, const Quat &quat) { - return quat * scalar; + return quat * scalar; } -inline float dot( const Quat & quat0, const Quat & quat1 ) +inline float dot(const Quat &quat0, const Quat &quat1) { - float result; - result = ( quat0.getX() * quat1.getX() ); - result = ( result + ( quat0.getY() * quat1.getY() ) ); - result = ( result + ( quat0.getZ() * quat1.getZ() ) ); - result = ( result + ( quat0.getW() * quat1.getW() ) ); - return result; + float result; + result = (quat0.getX() * quat1.getX()); + result = (result + (quat0.getY() * quat1.getY())); + result = (result + (quat0.getZ() * quat1.getZ())); + result = (result + (quat0.getW() * quat1.getW())); + return result; } -inline float norm( const Quat & quat ) +inline float norm(const Quat &quat) { - float result; - result = ( quat.getX() * quat.getX() ); - result = ( result + ( quat.getY() * quat.getY() ) ); - result = ( result + ( quat.getZ() * quat.getZ() ) ); - result = ( result + ( quat.getW() * quat.getW() ) ); - return result; + float result; + result = (quat.getX() * quat.getX()); + result = (result + (quat.getY() * quat.getY())); + result = (result + (quat.getZ() * quat.getZ())); + result = (result + (quat.getW() * quat.getW())); + return result; } -inline float length( const Quat & quat ) +inline float length(const Quat &quat) { - return ::sqrtf( norm( quat ) ); + return ::sqrtf(norm(quat)); } -inline const Quat normalize( const Quat & quat ) +inline const Quat normalize(const Quat &quat) { - float lenSqr, lenInv; - lenSqr = norm( quat ); - lenInv = ( 1.0f / sqrtf( lenSqr ) ); - return Quat( - ( quat.getX() * lenInv ), - ( quat.getY() * lenInv ), - ( quat.getZ() * lenInv ), - ( quat.getW() * lenInv ) - ); + float lenSqr, lenInv; + lenSqr = norm(quat); + lenInv = (1.0f / sqrtf(lenSqr)); + return Quat( + (quat.getX() * lenInv), + (quat.getY() * lenInv), + (quat.getZ() * lenInv), + (quat.getW() * lenInv)); } -inline const Quat Quat::rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 ) +inline const Quat Quat::rotation(const Vector3 &unitVec0, const Vector3 &unitVec1) { - float cosHalfAngleX2, recipCosHalfAngleX2; - cosHalfAngleX2 = sqrtf( ( 2.0f * ( 1.0f + dot( unitVec0, unitVec1 ) ) ) ); - recipCosHalfAngleX2 = ( 1.0f / cosHalfAngleX2 ); - return Quat( ( cross( unitVec0, unitVec1 ) * recipCosHalfAngleX2 ), ( cosHalfAngleX2 * 0.5f ) ); + float cosHalfAngleX2, recipCosHalfAngleX2; + cosHalfAngleX2 = sqrtf((2.0f * (1.0f + dot(unitVec0, unitVec1)))); + recipCosHalfAngleX2 = (1.0f / cosHalfAngleX2); + return Quat((cross(unitVec0, unitVec1) * recipCosHalfAngleX2), (cosHalfAngleX2 * 0.5f)); } -inline const Quat Quat::rotation( float radians, const Vector3 & unitVec ) +inline const Quat Quat::rotation(float radians, const Vector3 &unitVec) { - float s, c, angle; - angle = ( radians * 0.5f ); - s = sinf( angle ); - c = cosf( angle ); - return Quat( ( unitVec * s ), c ); + float s, c, angle; + angle = (radians * 0.5f); + s = sinf(angle); + c = cosf(angle); + return Quat((unitVec * s), c); } -inline const Quat Quat::rotationX( float radians ) +inline const Quat Quat::rotationX(float radians) { - float s, c, angle; - angle = ( radians * 0.5f ); - s = sinf( angle ); - c = cosf( angle ); - return Quat( s, 0.0f, 0.0f, c ); + float s, c, angle; + angle = (radians * 0.5f); + s = sinf(angle); + c = cosf(angle); + return Quat(s, 0.0f, 0.0f, c); } -inline const Quat Quat::rotationY( float radians ) +inline const Quat Quat::rotationY(float radians) { - float s, c, angle; - angle = ( radians * 0.5f ); - s = sinf( angle ); - c = cosf( angle ); - return Quat( 0.0f, s, 0.0f, c ); + float s, c, angle; + angle = (radians * 0.5f); + s = sinf(angle); + c = cosf(angle); + return Quat(0.0f, s, 0.0f, c); } -inline const Quat Quat::rotationZ( float radians ) +inline const Quat Quat::rotationZ(float radians) { - float s, c, angle; - angle = ( radians * 0.5f ); - s = sinf( angle ); - c = cosf( angle ); - return Quat( 0.0f, 0.0f, s, c ); + float s, c, angle; + angle = (radians * 0.5f); + s = sinf(angle); + c = cosf(angle); + return Quat(0.0f, 0.0f, s, c); } -inline const Quat Quat::operator *( const Quat & quat ) const +inline const Quat Quat::operator*(const Quat &quat) const { - return Quat( - ( ( ( ( mW * quat.mX ) + ( mX * quat.mW ) ) + ( mY * quat.mZ ) ) - ( mZ * quat.mY ) ), - ( ( ( ( mW * quat.mY ) + ( mY * quat.mW ) ) + ( mZ * quat.mX ) ) - ( mX * quat.mZ ) ), - ( ( ( ( mW * quat.mZ ) + ( mZ * quat.mW ) ) + ( mX * quat.mY ) ) - ( mY * quat.mX ) ), - ( ( ( ( mW * quat.mW ) - ( mX * quat.mX ) ) - ( mY * quat.mY ) ) - ( mZ * quat.mZ ) ) - ); + return Quat( + ((((mW * quat.mX) + (mX * quat.mW)) + (mY * quat.mZ)) - (mZ * quat.mY)), + ((((mW * quat.mY) + (mY * quat.mW)) + (mZ * quat.mX)) - (mX * quat.mZ)), + ((((mW * quat.mZ) + (mZ * quat.mW)) + (mX * quat.mY)) - (mY * quat.mX)), + ((((mW * quat.mW) - (mX * quat.mX)) - (mY * quat.mY)) - (mZ * quat.mZ))); } -inline Quat & Quat::operator *=( const Quat & quat ) +inline Quat &Quat::operator*=(const Quat &quat) { - *this = *this * quat; - return *this; + *this = *this * quat; + return *this; } -inline const Vector3 rotate( const Quat & quat, const Vector3 & vec ) +inline const Vector3 rotate(const Quat &quat, const Vector3 &vec) { - float tmpX, tmpY, tmpZ, tmpW; - tmpX = ( ( ( quat.getW() * vec.getX() ) + ( quat.getY() * vec.getZ() ) ) - ( quat.getZ() * vec.getY() ) ); - tmpY = ( ( ( quat.getW() * vec.getY() ) + ( quat.getZ() * vec.getX() ) ) - ( quat.getX() * vec.getZ() ) ); - tmpZ = ( ( ( quat.getW() * vec.getZ() ) + ( quat.getX() * vec.getY() ) ) - ( quat.getY() * vec.getX() ) ); - tmpW = ( ( ( quat.getX() * vec.getX() ) + ( quat.getY() * vec.getY() ) ) + ( quat.getZ() * vec.getZ() ) ); - return Vector3( - ( ( ( ( tmpW * quat.getX() ) + ( tmpX * quat.getW() ) ) - ( tmpY * quat.getZ() ) ) + ( tmpZ * quat.getY() ) ), - ( ( ( ( tmpW * quat.getY() ) + ( tmpY * quat.getW() ) ) - ( tmpZ * quat.getX() ) ) + ( tmpX * quat.getZ() ) ), - ( ( ( ( tmpW * quat.getZ() ) + ( tmpZ * quat.getW() ) ) - ( tmpX * quat.getY() ) ) + ( tmpY * quat.getX() ) ) - ); + float tmpX, tmpY, tmpZ, tmpW; + tmpX = (((quat.getW() * vec.getX()) + (quat.getY() * vec.getZ())) - (quat.getZ() * vec.getY())); + tmpY = (((quat.getW() * vec.getY()) + (quat.getZ() * vec.getX())) - (quat.getX() * vec.getZ())); + tmpZ = (((quat.getW() * vec.getZ()) + (quat.getX() * vec.getY())) - (quat.getY() * vec.getX())); + tmpW = (((quat.getX() * vec.getX()) + (quat.getY() * vec.getY())) + (quat.getZ() * vec.getZ())); + return Vector3( + ((((tmpW * quat.getX()) + (tmpX * quat.getW())) - (tmpY * quat.getZ())) + (tmpZ * quat.getY())), + ((((tmpW * quat.getY()) + (tmpY * quat.getW())) - (tmpZ * quat.getX())) + (tmpX * quat.getZ())), + ((((tmpW * quat.getZ()) + (tmpZ * quat.getW())) - (tmpX * quat.getY())) + (tmpY * quat.getX()))); } -inline const Quat conj( const Quat & quat ) +inline const Quat conj(const Quat &quat) { - return Quat( -quat.getX(), -quat.getY(), -quat.getZ(), quat.getW() ); + return Quat(-quat.getX(), -quat.getY(), -quat.getZ(), quat.getW()); } -inline const Quat select( const Quat & quat0, const Quat & quat1, bool select1 ) +inline const Quat select(const Quat &quat0, const Quat &quat1, bool select1) { - return Quat( - ( select1 )? quat1.getX() : quat0.getX(), - ( select1 )? quat1.getY() : quat0.getY(), - ( select1 )? quat1.getZ() : quat0.getZ(), - ( select1 )? quat1.getW() : quat0.getW() - ); + return Quat( + (select1) ? quat1.getX() : quat0.getX(), + (select1) ? quat1.getY() : quat0.getY(), + (select1) ? quat1.getZ() : quat0.getZ(), + (select1) ? quat1.getW() : quat0.getW()); } #ifdef _VECTORMATH_DEBUG -inline void print( const Quat & quat ) +inline void print(const Quat &quat) { - printf( "( %f %f %f %f )\n", quat.getX(), quat.getY(), quat.getZ(), quat.getW() ); + printf("( %f %f %f %f )\n", quat.getX(), quat.getY(), quat.getZ(), quat.getW()); } -inline void print( const Quat & quat, const char * name ) +inline void print(const Quat &quat, const char *name) { - printf( "%s: ( %f %f %f %f )\n", name, quat.getX(), quat.getY(), quat.getZ(), quat.getW() ); + printf("%s: ( %f %f %f %f )\n", name, quat.getX(), quat.getY(), quat.getZ(), quat.getW()); } #endif -} // namespace Aos -} // namespace Vectormath +} // namespace Aos +} // namespace Vectormath #endif diff --git a/test/Bullet2/vectormath/scalar/vec_aos.h b/test/Bullet2/vectormath/scalar/vec_aos.h index 46d4d6b3e..bf80a3d11 100644 --- a/test/Bullet2/vectormath/scalar/vec_aos.h +++ b/test/Bullet2/vectormath/scalar/vec_aos.h @@ -30,1397 +30,1390 @@ subject to the following restrictions: #endif -namespace Vectormath { -namespace Aos { - -inline Vector3::Vector3( const Vector3 & vec ) +namespace Vectormath { - mX = vec.mX; - mY = vec.mY; - mZ = vec.mZ; +namespace Aos +{ +inline Vector3::Vector3(const Vector3 &vec) +{ + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; } -inline Vector3::Vector3( float _x, float _y, float _z ) +inline Vector3::Vector3(float _x, float _y, float _z) { - mX = _x; - mY = _y; - mZ = _z; + mX = _x; + mY = _y; + mZ = _z; } -inline Vector3::Vector3( const Point3 & pnt ) +inline Vector3::Vector3(const Point3 &pnt) { - mX = pnt.getX(); - mY = pnt.getY(); - mZ = pnt.getZ(); + mX = pnt.getX(); + mY = pnt.getY(); + mZ = pnt.getZ(); } -inline Vector3::Vector3( float scalar ) +inline Vector3::Vector3(float scalar) { - mX = scalar; - mY = scalar; - mZ = scalar; + mX = scalar; + mY = scalar; + mZ = scalar; } -inline const Vector3 Vector3::xAxis( ) +inline const Vector3 Vector3::xAxis() { - return Vector3( 1.0f, 0.0f, 0.0f ); + return Vector3(1.0f, 0.0f, 0.0f); } -inline const Vector3 Vector3::yAxis( ) +inline const Vector3 Vector3::yAxis() { - return Vector3( 0.0f, 1.0f, 0.0f ); + return Vector3(0.0f, 1.0f, 0.0f); } -inline const Vector3 Vector3::zAxis( ) +inline const Vector3 Vector3::zAxis() { - return Vector3( 0.0f, 0.0f, 1.0f ); + return Vector3(0.0f, 0.0f, 1.0f); } -inline const Vector3 lerp( float t, const Vector3 & vec0, const Vector3 & vec1 ) +inline const Vector3 lerp(float t, const Vector3 &vec0, const Vector3 &vec1) { - return ( vec0 + ( ( vec1 - vec0 ) * t ) ); + return (vec0 + ((vec1 - vec0) * t)); } -inline const Vector3 slerp( float t, const Vector3 & unitVec0, const Vector3 & unitVec1 ) +inline const Vector3 slerp(float t, const Vector3 &unitVec0, const Vector3 &unitVec1) { - float recipSinAngle, scale0, scale1, cosAngle, angle; - cosAngle = dot( unitVec0, unitVec1 ); - if ( cosAngle < _VECTORMATH_SLERP_TOL ) { - angle = acosf( cosAngle ); - recipSinAngle = ( 1.0f / sinf( angle ) ); - scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); - scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); - } else { - scale0 = ( 1.0f - t ); - scale1 = t; - } - return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) ); + float recipSinAngle, scale0, scale1, cosAngle, angle; + cosAngle = dot(unitVec0, unitVec1); + if (cosAngle < _VECTORMATH_SLERP_TOL) + { + angle = acosf(cosAngle); + recipSinAngle = (1.0f / sinf(angle)); + scale0 = (sinf(((1.0f - t) * angle)) * recipSinAngle); + scale1 = (sinf((t * angle)) * recipSinAngle); + } + else + { + scale0 = (1.0f - t); + scale1 = t; + } + return ((unitVec0 * scale0) + (unitVec1 * scale1)); } -inline void loadXYZ( Vector3 & vec, const float * fptr ) +inline void loadXYZ(Vector3 &vec, const float *fptr) { - vec = Vector3( fptr[0], fptr[1], fptr[2] ); + vec = Vector3(fptr[0], fptr[1], fptr[2]); } -inline void storeXYZ( const Vector3 & vec, float * fptr ) +inline void storeXYZ(const Vector3 &vec, float *fptr) { - fptr[0] = vec.getX(); - fptr[1] = vec.getY(); - fptr[2] = vec.getZ(); + fptr[0] = vec.getX(); + fptr[1] = vec.getY(); + fptr[2] = vec.getZ(); } -inline void loadHalfFloats( Vector3 & vec, const unsigned short * hfptr ) +inline void loadHalfFloats(Vector3 &vec, const unsigned short *hfptr) { - union Data32 { - unsigned int u32; - float f32; - }; + union Data32 { + unsigned int u32; + float f32; + }; - for (int i = 0; i < 3; i++) { - unsigned short fp16 = hfptr[i]; - unsigned int sign = fp16 >> 15; - unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); - unsigned int mantissa = fp16 & ((1 << 10) - 1); + for (int i = 0; i < 3; i++) + { + unsigned short fp16 = hfptr[i]; + unsigned int sign = fp16 >> 15; + unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); + unsigned int mantissa = fp16 & ((1 << 10) - 1); - if (exponent == 0) { - // zero - mantissa = 0; + if (exponent == 0) + { + // zero + mantissa = 0; + } + else if (exponent == 31) + { + // infinity or nan -> infinity + exponent = 255; + mantissa = 0; + } + else + { + exponent += 127 - 15; + mantissa <<= 13; + } - } else if (exponent == 31) { - // infinity or nan -> infinity - exponent = 255; - mantissa = 0; - - } else { - exponent += 127 - 15; - mantissa <<= 13; - } - - Data32 d; - d.u32 = (sign << 31) | (exponent << 23) | mantissa; - vec[i] = d.f32; - } + Data32 d; + d.u32 = (sign << 31) | (exponent << 23) | mantissa; + vec[i] = d.f32; + } } -inline void storeHalfFloats( const Vector3 & vec, unsigned short * hfptr ) +inline void storeHalfFloats(const Vector3 &vec, unsigned short *hfptr) { - union Data32 { - unsigned int u32; - float f32; - }; + union Data32 { + unsigned int u32; + float f32; + }; - for (int i = 0; i < 3; i++) { - Data32 d; - d.f32 = vec[i]; + for (int i = 0; i < 3; i++) + { + Data32 d; + d.f32 = vec[i]; - unsigned int sign = d.u32 >> 31; - unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); - unsigned int mantissa = d.u32 & ((1 << 23) - 1);; + unsigned int sign = d.u32 >> 31; + unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); + unsigned int mantissa = d.u32 & ((1 << 23) - 1); + ; - if (exponent == 0) { - // zero or denorm -> zero - mantissa = 0; + if (exponent == 0) + { + // zero or denorm -> zero + mantissa = 0; + } + else if (exponent == 255 && mantissa != 0) + { + // nan -> infinity + exponent = 31; + mantissa = 0; + } + else if (exponent >= 127 - 15 + 31) + { + // overflow or infinity -> infinity + exponent = 31; + mantissa = 0; + } + else if (exponent <= 127 - 15) + { + // underflow -> zero + exponent = 0; + mantissa = 0; + } + else + { + exponent -= 127 - 15; + mantissa >>= 13; + } - } else if (exponent == 255 && mantissa != 0) { - // nan -> infinity - exponent = 31; - mantissa = 0; - - } else if (exponent >= 127 - 15 + 31) { - // overflow or infinity -> infinity - exponent = 31; - mantissa = 0; - - } else if (exponent <= 127 - 15) { - // underflow -> zero - exponent = 0; - mantissa = 0; - - } else { - exponent -= 127 - 15; - mantissa >>= 13; - } - - hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); - } + hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); + } } -inline Vector3 & Vector3::operator =( const Vector3 & vec ) +inline Vector3 &Vector3::operator=(const Vector3 &vec) { - mX = vec.mX; - mY = vec.mY; - mZ = vec.mZ; - return *this; + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; + return *this; } -inline Vector3 & Vector3::setX( float _x ) +inline Vector3 &Vector3::setX(float _x) { - mX = _x; - return *this; + mX = _x; + return *this; } -inline float Vector3::getX( ) const +inline float Vector3::getX() const { - return mX; + return mX; } -inline Vector3 & Vector3::setY( float _y ) +inline Vector3 &Vector3::setY(float _y) { - mY = _y; - return *this; + mY = _y; + return *this; } -inline float Vector3::getY( ) const +inline float Vector3::getY() const { - return mY; + return mY; } -inline Vector3 & Vector3::setZ( float _z ) +inline Vector3 &Vector3::setZ(float _z) { - mZ = _z; - return *this; + mZ = _z; + return *this; } -inline float Vector3::getZ( ) const +inline float Vector3::getZ() const { - return mZ; + return mZ; } -inline Vector3 & Vector3::setElem( int idx, float value ) +inline Vector3 &Vector3::setElem(int idx, float value) { - *(&mX + idx) = value; - return *this; + *(&mX + idx) = value; + return *this; } -inline float Vector3::getElem( int idx ) const +inline float Vector3::getElem(int idx) const { - return *(&mX + idx); + return *(&mX + idx); } -inline float & Vector3::operator []( int idx ) +inline float &Vector3::operator[](int idx) { - return *(&mX + idx); + return *(&mX + idx); } -inline float Vector3::operator []( int idx ) const +inline float Vector3::operator[](int idx) const { - return *(&mX + idx); + return *(&mX + idx); } -inline const Vector3 Vector3::operator +( const Vector3 & vec ) const +inline const Vector3 Vector3::operator+(const Vector3 &vec) const { - return Vector3( - ( mX + vec.mX ), - ( mY + vec.mY ), - ( mZ + vec.mZ ) - ); + return Vector3( + (mX + vec.mX), + (mY + vec.mY), + (mZ + vec.mZ)); } -inline const Vector3 Vector3::operator -( const Vector3 & vec ) const +inline const Vector3 Vector3::operator-(const Vector3 &vec) const { - return Vector3( - ( mX - vec.mX ), - ( mY - vec.mY ), - ( mZ - vec.mZ ) - ); + return Vector3( + (mX - vec.mX), + (mY - vec.mY), + (mZ - vec.mZ)); } -inline const Point3 Vector3::operator +( const Point3 & pnt ) const +inline const Point3 Vector3::operator+(const Point3 &pnt) const { - return Point3( - ( mX + pnt.getX() ), - ( mY + pnt.getY() ), - ( mZ + pnt.getZ() ) - ); + return Point3( + (mX + pnt.getX()), + (mY + pnt.getY()), + (mZ + pnt.getZ())); } -inline const Vector3 Vector3::operator *( float scalar ) const +inline const Vector3 Vector3::operator*(float scalar) const { - return Vector3( - ( mX * scalar ), - ( mY * scalar ), - ( mZ * scalar ) - ); + return Vector3( + (mX * scalar), + (mY * scalar), + (mZ * scalar)); } -inline Vector3 & Vector3::operator +=( const Vector3 & vec ) +inline Vector3 &Vector3::operator+=(const Vector3 &vec) { - *this = *this + vec; - return *this; + *this = *this + vec; + return *this; } -inline Vector3 & Vector3::operator -=( const Vector3 & vec ) +inline Vector3 &Vector3::operator-=(const Vector3 &vec) { - *this = *this - vec; - return *this; + *this = *this - vec; + return *this; } -inline Vector3 & Vector3::operator *=( float scalar ) +inline Vector3 &Vector3::operator*=(float scalar) { - *this = *this * scalar; - return *this; + *this = *this * scalar; + return *this; } -inline const Vector3 Vector3::operator /( float scalar ) const +inline const Vector3 Vector3::operator/(float scalar) const { - return Vector3( - ( mX / scalar ), - ( mY / scalar ), - ( mZ / scalar ) - ); + return Vector3( + (mX / scalar), + (mY / scalar), + (mZ / scalar)); } -inline Vector3 & Vector3::operator /=( float scalar ) +inline Vector3 &Vector3::operator/=(float scalar) { - *this = *this / scalar; - return *this; + *this = *this / scalar; + return *this; } -inline const Vector3 Vector3::operator -( ) const +inline const Vector3 Vector3::operator-() const { - return Vector3( - -mX, - -mY, - -mZ - ); + return Vector3( + -mX, + -mY, + -mZ); } -inline const Vector3 operator *( float scalar, const Vector3 & vec ) +inline const Vector3 operator*(float scalar, const Vector3 &vec) { - return vec * scalar; + return vec * scalar; } -inline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +inline const Vector3 mulPerElem(const Vector3 &vec0, const Vector3 &vec1) { - return Vector3( - ( vec0.getX() * vec1.getX() ), - ( vec0.getY() * vec1.getY() ), - ( vec0.getZ() * vec1.getZ() ) - ); + return Vector3( + (vec0.getX() * vec1.getX()), + (vec0.getY() * vec1.getY()), + (vec0.getZ() * vec1.getZ())); } -inline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +inline const Vector3 divPerElem(const Vector3 &vec0, const Vector3 &vec1) { - return Vector3( - ( vec0.getX() / vec1.getX() ), - ( vec0.getY() / vec1.getY() ), - ( vec0.getZ() / vec1.getZ() ) - ); + return Vector3( + (vec0.getX() / vec1.getX()), + (vec0.getY() / vec1.getY()), + (vec0.getZ() / vec1.getZ())); } -inline const Vector3 recipPerElem( const Vector3 & vec ) +inline const Vector3 recipPerElem(const Vector3 &vec) { - return Vector3( - ( 1.0f / vec.getX() ), - ( 1.0f / vec.getY() ), - ( 1.0f / vec.getZ() ) - ); + return Vector3( + (1.0f / vec.getX()), + (1.0f / vec.getY()), + (1.0f / vec.getZ())); } -inline const Vector3 sqrtPerElem( const Vector3 & vec ) +inline const Vector3 sqrtPerElem(const Vector3 &vec) { - return Vector3( - sqrtf( vec.getX() ), - sqrtf( vec.getY() ), - sqrtf( vec.getZ() ) - ); + return Vector3( + sqrtf(vec.getX()), + sqrtf(vec.getY()), + sqrtf(vec.getZ())); } -inline const Vector3 rsqrtPerElem( const Vector3 & vec ) +inline const Vector3 rsqrtPerElem(const Vector3 &vec) { - return Vector3( - ( 1.0f / sqrtf( vec.getX() ) ), - ( 1.0f / sqrtf( vec.getY() ) ), - ( 1.0f / sqrtf( vec.getZ() ) ) - ); + return Vector3( + (1.0f / sqrtf(vec.getX())), + (1.0f / sqrtf(vec.getY())), + (1.0f / sqrtf(vec.getZ()))); } -inline const Vector3 absPerElem( const Vector3 & vec ) +inline const Vector3 absPerElem(const Vector3 &vec) { - return Vector3( - fabsf( vec.getX() ), - fabsf( vec.getY() ), - fabsf( vec.getZ() ) - ); + return Vector3( + fabsf(vec.getX()), + fabsf(vec.getY()), + fabsf(vec.getZ())); } -inline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +inline const Vector3 copySignPerElem(const Vector3 &vec0, const Vector3 &vec1) { - return Vector3( - ( vec1.getX() < 0.0f )? -fabsf( vec0.getX() ) : fabsf( vec0.getX() ), - ( vec1.getY() < 0.0f )? -fabsf( vec0.getY() ) : fabsf( vec0.getY() ), - ( vec1.getZ() < 0.0f )? -fabsf( vec0.getZ() ) : fabsf( vec0.getZ() ) - ); + return Vector3( + (vec1.getX() < 0.0f) ? -fabsf(vec0.getX()) : fabsf(vec0.getX()), + (vec1.getY() < 0.0f) ? -fabsf(vec0.getY()) : fabsf(vec0.getY()), + (vec1.getZ() < 0.0f) ? -fabsf(vec0.getZ()) : fabsf(vec0.getZ())); } -inline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +inline const Vector3 maxPerElem(const Vector3 &vec0, const Vector3 &vec1) { - return Vector3( - (vec0.getX() > vec1.getX())? vec0.getX() : vec1.getX(), - (vec0.getY() > vec1.getY())? vec0.getY() : vec1.getY(), - (vec0.getZ() > vec1.getZ())? vec0.getZ() : vec1.getZ() - ); + return Vector3( + (vec0.getX() > vec1.getX()) ? vec0.getX() : vec1.getX(), + (vec0.getY() > vec1.getY()) ? vec0.getY() : vec1.getY(), + (vec0.getZ() > vec1.getZ()) ? vec0.getZ() : vec1.getZ()); } -inline float maxElem( const Vector3 & vec ) +inline float maxElem(const Vector3 &vec) { - float result; - result = (vec.getX() > vec.getY())? vec.getX() : vec.getY(); - result = (vec.getZ() > result)? vec.getZ() : result; - return result; + float result; + result = (vec.getX() > vec.getY()) ? vec.getX() : vec.getY(); + result = (vec.getZ() > result) ? vec.getZ() : result; + return result; } -inline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 ) +inline const Vector3 minPerElem(const Vector3 &vec0, const Vector3 &vec1) { - return Vector3( - (vec0.getX() < vec1.getX())? vec0.getX() : vec1.getX(), - (vec0.getY() < vec1.getY())? vec0.getY() : vec1.getY(), - (vec0.getZ() < vec1.getZ())? vec0.getZ() : vec1.getZ() - ); + return Vector3( + (vec0.getX() < vec1.getX()) ? vec0.getX() : vec1.getX(), + (vec0.getY() < vec1.getY()) ? vec0.getY() : vec1.getY(), + (vec0.getZ() < vec1.getZ()) ? vec0.getZ() : vec1.getZ()); } -inline float minElem( const Vector3 & vec ) +inline float minElem(const Vector3 &vec) { - float result; - result = (vec.getX() < vec.getY())? vec.getX() : vec.getY(); - result = (vec.getZ() < result)? vec.getZ() : result; - return result; + float result; + result = (vec.getX() < vec.getY()) ? vec.getX() : vec.getY(); + result = (vec.getZ() < result) ? vec.getZ() : result; + return result; } -inline float sum( const Vector3 & vec ) +inline float sum(const Vector3 &vec) { - float result; - result = ( vec.getX() + vec.getY() ); - result = ( result + vec.getZ() ); - return result; + float result; + result = (vec.getX() + vec.getY()); + result = (result + vec.getZ()); + return result; } -inline float dot( const Vector3 & vec0, const Vector3 & vec1 ) +inline float dot(const Vector3 &vec0, const Vector3 &vec1) { - float result; - result = ( vec0.getX() * vec1.getX() ); - result = ( result + ( vec0.getY() * vec1.getY() ) ); - result = ( result + ( vec0.getZ() * vec1.getZ() ) ); - return result; + float result; + result = (vec0.getX() * vec1.getX()); + result = (result + (vec0.getY() * vec1.getY())); + result = (result + (vec0.getZ() * vec1.getZ())); + return result; } -inline float lengthSqr( const Vector3 & vec ) +inline float lengthSqr(const Vector3 &vec) { - float result; - result = ( vec.getX() * vec.getX() ); - result = ( result + ( vec.getY() * vec.getY() ) ); - result = ( result + ( vec.getZ() * vec.getZ() ) ); - return result; + float result; + result = (vec.getX() * vec.getX()); + result = (result + (vec.getY() * vec.getY())); + result = (result + (vec.getZ() * vec.getZ())); + return result; } -inline float length( const Vector3 & vec ) +inline float length(const Vector3 &vec) { - return ::sqrtf( lengthSqr( vec ) ); + return ::sqrtf(lengthSqr(vec)); } -inline const Vector3 normalize( const Vector3 & vec ) +inline const Vector3 normalize(const Vector3 &vec) { - float lenSqr, lenInv; - lenSqr = lengthSqr( vec ); - lenInv = ( 1.0f / sqrtf( lenSqr ) ); - return Vector3( - ( vec.getX() * lenInv ), - ( vec.getY() * lenInv ), - ( vec.getZ() * lenInv ) - ); + float lenSqr, lenInv; + lenSqr = lengthSqr(vec); + lenInv = (1.0f / sqrtf(lenSqr)); + return Vector3( + (vec.getX() * lenInv), + (vec.getY() * lenInv), + (vec.getZ() * lenInv)); } -inline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 ) +inline const Vector3 cross(const Vector3 &vec0, const Vector3 &vec1) { - return Vector3( - ( ( vec0.getY() * vec1.getZ() ) - ( vec0.getZ() * vec1.getY() ) ), - ( ( vec0.getZ() * vec1.getX() ) - ( vec0.getX() * vec1.getZ() ) ), - ( ( vec0.getX() * vec1.getY() ) - ( vec0.getY() * vec1.getX() ) ) - ); + return Vector3( + ((vec0.getY() * vec1.getZ()) - (vec0.getZ() * vec1.getY())), + ((vec0.getZ() * vec1.getX()) - (vec0.getX() * vec1.getZ())), + ((vec0.getX() * vec1.getY()) - (vec0.getY() * vec1.getX()))); } -inline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, bool select1 ) +inline const Vector3 select(const Vector3 &vec0, const Vector3 &vec1, bool select1) { - return Vector3( - ( select1 )? vec1.getX() : vec0.getX(), - ( select1 )? vec1.getY() : vec0.getY(), - ( select1 )? vec1.getZ() : vec0.getZ() - ); + return Vector3( + (select1) ? vec1.getX() : vec0.getX(), + (select1) ? vec1.getY() : vec0.getY(), + (select1) ? vec1.getZ() : vec0.getZ()); } #ifdef _VECTORMATH_DEBUG -inline void print( const Vector3 & vec ) +inline void print(const Vector3 &vec) { - printf( "( %f %f %f )\n", vec.getX(), vec.getY(), vec.getZ() ); + printf("( %f %f %f )\n", vec.getX(), vec.getY(), vec.getZ()); } -inline void print( const Vector3 & vec, const char * name ) +inline void print(const Vector3 &vec, const char *name) { - printf( "%s: ( %f %f %f )\n", name, vec.getX(), vec.getY(), vec.getZ() ); + printf("%s: ( %f %f %f )\n", name, vec.getX(), vec.getY(), vec.getZ()); } #endif -inline Vector4::Vector4( const Vector4 & vec ) +inline Vector4::Vector4(const Vector4 &vec) { - mX = vec.mX; - mY = vec.mY; - mZ = vec.mZ; - mW = vec.mW; + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; + mW = vec.mW; } -inline Vector4::Vector4( float _x, float _y, float _z, float _w ) +inline Vector4::Vector4(float _x, float _y, float _z, float _w) { - mX = _x; - mY = _y; - mZ = _z; - mW = _w; + mX = _x; + mY = _y; + mZ = _z; + mW = _w; } -inline Vector4::Vector4( const Vector3 & xyz, float _w ) +inline Vector4::Vector4(const Vector3 &xyz, float _w) { - this->setXYZ( xyz ); - this->setW( _w ); + this->setXYZ(xyz); + this->setW(_w); } -inline Vector4::Vector4( const Vector3 & vec ) +inline Vector4::Vector4(const Vector3 &vec) { - mX = vec.getX(); - mY = vec.getY(); - mZ = vec.getZ(); - mW = 0.0f; + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + mW = 0.0f; } -inline Vector4::Vector4( const Point3 & pnt ) +inline Vector4::Vector4(const Point3 &pnt) { - mX = pnt.getX(); - mY = pnt.getY(); - mZ = pnt.getZ(); - mW = 1.0f; + mX = pnt.getX(); + mY = pnt.getY(); + mZ = pnt.getZ(); + mW = 1.0f; } -inline Vector4::Vector4( const Quat & quat ) +inline Vector4::Vector4(const Quat &quat) { - mX = quat.getX(); - mY = quat.getY(); - mZ = quat.getZ(); - mW = quat.getW(); + mX = quat.getX(); + mY = quat.getY(); + mZ = quat.getZ(); + mW = quat.getW(); } -inline Vector4::Vector4( float scalar ) +inline Vector4::Vector4(float scalar) { - mX = scalar; - mY = scalar; - mZ = scalar; - mW = scalar; + mX = scalar; + mY = scalar; + mZ = scalar; + mW = scalar; } -inline const Vector4 Vector4::xAxis( ) +inline const Vector4 Vector4::xAxis() { - return Vector4( 1.0f, 0.0f, 0.0f, 0.0f ); + return Vector4(1.0f, 0.0f, 0.0f, 0.0f); } -inline const Vector4 Vector4::yAxis( ) +inline const Vector4 Vector4::yAxis() { - return Vector4( 0.0f, 1.0f, 0.0f, 0.0f ); + return Vector4(0.0f, 1.0f, 0.0f, 0.0f); } -inline const Vector4 Vector4::zAxis( ) +inline const Vector4 Vector4::zAxis() { - return Vector4( 0.0f, 0.0f, 1.0f, 0.0f ); + return Vector4(0.0f, 0.0f, 1.0f, 0.0f); } -inline const Vector4 Vector4::wAxis( ) +inline const Vector4 Vector4::wAxis() { - return Vector4( 0.0f, 0.0f, 0.0f, 1.0f ); + return Vector4(0.0f, 0.0f, 0.0f, 1.0f); } -inline const Vector4 lerp( float t, const Vector4 & vec0, const Vector4 & vec1 ) +inline const Vector4 lerp(float t, const Vector4 &vec0, const Vector4 &vec1) { - return ( vec0 + ( ( vec1 - vec0 ) * t ) ); + return (vec0 + ((vec1 - vec0) * t)); } -inline const Vector4 slerp( float t, const Vector4 & unitVec0, const Vector4 & unitVec1 ) +inline const Vector4 slerp(float t, const Vector4 &unitVec0, const Vector4 &unitVec1) { - float recipSinAngle, scale0, scale1, cosAngle, angle; - cosAngle = dot( unitVec0, unitVec1 ); - if ( cosAngle < _VECTORMATH_SLERP_TOL ) { - angle = acosf( cosAngle ); - recipSinAngle = ( 1.0f / sinf( angle ) ); - scale0 = ( sinf( ( ( 1.0f - t ) * angle ) ) * recipSinAngle ); - scale1 = ( sinf( ( t * angle ) ) * recipSinAngle ); - } else { - scale0 = ( 1.0f - t ); - scale1 = t; - } - return ( ( unitVec0 * scale0 ) + ( unitVec1 * scale1 ) ); + float recipSinAngle, scale0, scale1, cosAngle, angle; + cosAngle = dot(unitVec0, unitVec1); + if (cosAngle < _VECTORMATH_SLERP_TOL) + { + angle = acosf(cosAngle); + recipSinAngle = (1.0f / sinf(angle)); + scale0 = (sinf(((1.0f - t) * angle)) * recipSinAngle); + scale1 = (sinf((t * angle)) * recipSinAngle); + } + else + { + scale0 = (1.0f - t); + scale1 = t; + } + return ((unitVec0 * scale0) + (unitVec1 * scale1)); } -inline void loadXYZW( Vector4 & vec, const float * fptr ) +inline void loadXYZW(Vector4 &vec, const float *fptr) { - vec = Vector4( fptr[0], fptr[1], fptr[2], fptr[3] ); + vec = Vector4(fptr[0], fptr[1], fptr[2], fptr[3]); } -inline void storeXYZW( const Vector4 & vec, float * fptr ) +inline void storeXYZW(const Vector4 &vec, float *fptr) { - fptr[0] = vec.getX(); - fptr[1] = vec.getY(); - fptr[2] = vec.getZ(); - fptr[3] = vec.getW(); + fptr[0] = vec.getX(); + fptr[1] = vec.getY(); + fptr[2] = vec.getZ(); + fptr[3] = vec.getW(); } -inline void loadHalfFloats( Vector4 & vec, const unsigned short * hfptr ) +inline void loadHalfFloats(Vector4 &vec, const unsigned short *hfptr) { - union Data32 { - unsigned int u32; - float f32; - }; + union Data32 { + unsigned int u32; + float f32; + }; - for (int i = 0; i < 4; i++) { - unsigned short fp16 = hfptr[i]; - unsigned int sign = fp16 >> 15; - unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); - unsigned int mantissa = fp16 & ((1 << 10) - 1); + for (int i = 0; i < 4; i++) + { + unsigned short fp16 = hfptr[i]; + unsigned int sign = fp16 >> 15; + unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); + unsigned int mantissa = fp16 & ((1 << 10) - 1); - if (exponent == 0) { - // zero - mantissa = 0; + if (exponent == 0) + { + // zero + mantissa = 0; + } + else if (exponent == 31) + { + // infinity or nan -> infinity + exponent = 255; + mantissa = 0; + } + else + { + exponent += 127 - 15; + mantissa <<= 13; + } - } else if (exponent == 31) { - // infinity or nan -> infinity - exponent = 255; - mantissa = 0; - - } else { - exponent += 127 - 15; - mantissa <<= 13; - } - - Data32 d; - d.u32 = (sign << 31) | (exponent << 23) | mantissa; - vec[i] = d.f32; - } + Data32 d; + d.u32 = (sign << 31) | (exponent << 23) | mantissa; + vec[i] = d.f32; + } } -inline void storeHalfFloats( const Vector4 & vec, unsigned short * hfptr ) +inline void storeHalfFloats(const Vector4 &vec, unsigned short *hfptr) { - union Data32 { - unsigned int u32; - float f32; - }; + union Data32 { + unsigned int u32; + float f32; + }; - for (int i = 0; i < 4; i++) { - Data32 d; - d.f32 = vec[i]; + for (int i = 0; i < 4; i++) + { + Data32 d; + d.f32 = vec[i]; - unsigned int sign = d.u32 >> 31; - unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); - unsigned int mantissa = d.u32 & ((1 << 23) - 1);; + unsigned int sign = d.u32 >> 31; + unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); + unsigned int mantissa = d.u32 & ((1 << 23) - 1); + ; - if (exponent == 0) { - // zero or denorm -> zero - mantissa = 0; + if (exponent == 0) + { + // zero or denorm -> zero + mantissa = 0; + } + else if (exponent == 255 && mantissa != 0) + { + // nan -> infinity + exponent = 31; + mantissa = 0; + } + else if (exponent >= 127 - 15 + 31) + { + // overflow or infinity -> infinity + exponent = 31; + mantissa = 0; + } + else if (exponent <= 127 - 15) + { + // underflow -> zero + exponent = 0; + mantissa = 0; + } + else + { + exponent -= 127 - 15; + mantissa >>= 13; + } - } else if (exponent == 255 && mantissa != 0) { - // nan -> infinity - exponent = 31; - mantissa = 0; - - } else if (exponent >= 127 - 15 + 31) { - // overflow or infinity -> infinity - exponent = 31; - mantissa = 0; - - } else if (exponent <= 127 - 15) { - // underflow -> zero - exponent = 0; - mantissa = 0; - - } else { - exponent -= 127 - 15; - mantissa >>= 13; - } - - hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); - } + hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); + } } -inline Vector4 & Vector4::operator =( const Vector4 & vec ) +inline Vector4 &Vector4::operator=(const Vector4 &vec) { - mX = vec.mX; - mY = vec.mY; - mZ = vec.mZ; - mW = vec.mW; - return *this; + mX = vec.mX; + mY = vec.mY; + mZ = vec.mZ; + mW = vec.mW; + return *this; } -inline Vector4 & Vector4::setXYZ( const Vector3 & vec ) +inline Vector4 &Vector4::setXYZ(const Vector3 &vec) { - mX = vec.getX(); - mY = vec.getY(); - mZ = vec.getZ(); - return *this; + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); + return *this; } -inline const Vector3 Vector4::getXYZ( ) const +inline const Vector3 Vector4::getXYZ() const { - return Vector3( mX, mY, mZ ); + return Vector3(mX, mY, mZ); } -inline Vector4 & Vector4::setX( float _x ) +inline Vector4 &Vector4::setX(float _x) { - mX = _x; - return *this; + mX = _x; + return *this; } -inline float Vector4::getX( ) const +inline float Vector4::getX() const { - return mX; + return mX; } -inline Vector4 & Vector4::setY( float _y ) +inline Vector4 &Vector4::setY(float _y) { - mY = _y; - return *this; + mY = _y; + return *this; } -inline float Vector4::getY( ) const +inline float Vector4::getY() const { - return mY; + return mY; } -inline Vector4 & Vector4::setZ( float _z ) +inline Vector4 &Vector4::setZ(float _z) { - mZ = _z; - return *this; + mZ = _z; + return *this; } -inline float Vector4::getZ( ) const +inline float Vector4::getZ() const { - return mZ; + return mZ; } -inline Vector4 & Vector4::setW( float _w ) +inline Vector4 &Vector4::setW(float _w) { - mW = _w; - return *this; + mW = _w; + return *this; } -inline float Vector4::getW( ) const +inline float Vector4::getW() const { - return mW; + return mW; } -inline Vector4 & Vector4::setElem( int idx, float value ) +inline Vector4 &Vector4::setElem(int idx, float value) { - *(&mX + idx) = value; - return *this; + *(&mX + idx) = value; + return *this; } -inline float Vector4::getElem( int idx ) const +inline float Vector4::getElem(int idx) const { - return *(&mX + idx); + return *(&mX + idx); } -inline float & Vector4::operator []( int idx ) +inline float &Vector4::operator[](int idx) { - return *(&mX + idx); + return *(&mX + idx); } -inline float Vector4::operator []( int idx ) const +inline float Vector4::operator[](int idx) const { - return *(&mX + idx); + return *(&mX + idx); } -inline const Vector4 Vector4::operator +( const Vector4 & vec ) const +inline const Vector4 Vector4::operator+(const Vector4 &vec) const { - return Vector4( - ( mX + vec.mX ), - ( mY + vec.mY ), - ( mZ + vec.mZ ), - ( mW + vec.mW ) - ); + return Vector4( + (mX + vec.mX), + (mY + vec.mY), + (mZ + vec.mZ), + (mW + vec.mW)); } -inline const Vector4 Vector4::operator -( const Vector4 & vec ) const +inline const Vector4 Vector4::operator-(const Vector4 &vec) const { - return Vector4( - ( mX - vec.mX ), - ( mY - vec.mY ), - ( mZ - vec.mZ ), - ( mW - vec.mW ) - ); + return Vector4( + (mX - vec.mX), + (mY - vec.mY), + (mZ - vec.mZ), + (mW - vec.mW)); } -inline const Vector4 Vector4::operator *( float scalar ) const +inline const Vector4 Vector4::operator*(float scalar) const { - return Vector4( - ( mX * scalar ), - ( mY * scalar ), - ( mZ * scalar ), - ( mW * scalar ) - ); + return Vector4( + (mX * scalar), + (mY * scalar), + (mZ * scalar), + (mW * scalar)); } -inline Vector4 & Vector4::operator +=( const Vector4 & vec ) +inline Vector4 &Vector4::operator+=(const Vector4 &vec) { - *this = *this + vec; - return *this; + *this = *this + vec; + return *this; } -inline Vector4 & Vector4::operator -=( const Vector4 & vec ) +inline Vector4 &Vector4::operator-=(const Vector4 &vec) { - *this = *this - vec; - return *this; + *this = *this - vec; + return *this; } -inline Vector4 & Vector4::operator *=( float scalar ) +inline Vector4 &Vector4::operator*=(float scalar) { - *this = *this * scalar; - return *this; + *this = *this * scalar; + return *this; } -inline const Vector4 Vector4::operator /( float scalar ) const +inline const Vector4 Vector4::operator/(float scalar) const { - return Vector4( - ( mX / scalar ), - ( mY / scalar ), - ( mZ / scalar ), - ( mW / scalar ) - ); + return Vector4( + (mX / scalar), + (mY / scalar), + (mZ / scalar), + (mW / scalar)); } -inline Vector4 & Vector4::operator /=( float scalar ) +inline Vector4 &Vector4::operator/=(float scalar) { - *this = *this / scalar; - return *this; + *this = *this / scalar; + return *this; } -inline const Vector4 Vector4::operator -( ) const +inline const Vector4 Vector4::operator-() const { - return Vector4( - -mX, - -mY, - -mZ, - -mW - ); + return Vector4( + -mX, + -mY, + -mZ, + -mW); } -inline const Vector4 operator *( float scalar, const Vector4 & vec ) +inline const Vector4 operator*(float scalar, const Vector4 &vec) { - return vec * scalar; + return vec * scalar; } -inline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +inline const Vector4 mulPerElem(const Vector4 &vec0, const Vector4 &vec1) { - return Vector4( - ( vec0.getX() * vec1.getX() ), - ( vec0.getY() * vec1.getY() ), - ( vec0.getZ() * vec1.getZ() ), - ( vec0.getW() * vec1.getW() ) - ); + return Vector4( + (vec0.getX() * vec1.getX()), + (vec0.getY() * vec1.getY()), + (vec0.getZ() * vec1.getZ()), + (vec0.getW() * vec1.getW())); } -inline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +inline const Vector4 divPerElem(const Vector4 &vec0, const Vector4 &vec1) { - return Vector4( - ( vec0.getX() / vec1.getX() ), - ( vec0.getY() / vec1.getY() ), - ( vec0.getZ() / vec1.getZ() ), - ( vec0.getW() / vec1.getW() ) - ); + return Vector4( + (vec0.getX() / vec1.getX()), + (vec0.getY() / vec1.getY()), + (vec0.getZ() / vec1.getZ()), + (vec0.getW() / vec1.getW())); } -inline const Vector4 recipPerElem( const Vector4 & vec ) +inline const Vector4 recipPerElem(const Vector4 &vec) { - return Vector4( - ( 1.0f / vec.getX() ), - ( 1.0f / vec.getY() ), - ( 1.0f / vec.getZ() ), - ( 1.0f / vec.getW() ) - ); + return Vector4( + (1.0f / vec.getX()), + (1.0f / vec.getY()), + (1.0f / vec.getZ()), + (1.0f / vec.getW())); } -inline const Vector4 sqrtPerElem( const Vector4 & vec ) +inline const Vector4 sqrtPerElem(const Vector4 &vec) { - return Vector4( - sqrtf( vec.getX() ), - sqrtf( vec.getY() ), - sqrtf( vec.getZ() ), - sqrtf( vec.getW() ) - ); + return Vector4( + sqrtf(vec.getX()), + sqrtf(vec.getY()), + sqrtf(vec.getZ()), + sqrtf(vec.getW())); } -inline const Vector4 rsqrtPerElem( const Vector4 & vec ) +inline const Vector4 rsqrtPerElem(const Vector4 &vec) { - return Vector4( - ( 1.0f / sqrtf( vec.getX() ) ), - ( 1.0f / sqrtf( vec.getY() ) ), - ( 1.0f / sqrtf( vec.getZ() ) ), - ( 1.0f / sqrtf( vec.getW() ) ) - ); + return Vector4( + (1.0f / sqrtf(vec.getX())), + (1.0f / sqrtf(vec.getY())), + (1.0f / sqrtf(vec.getZ())), + (1.0f / sqrtf(vec.getW()))); } -inline const Vector4 absPerElem( const Vector4 & vec ) +inline const Vector4 absPerElem(const Vector4 &vec) { - return Vector4( - fabsf( vec.getX() ), - fabsf( vec.getY() ), - fabsf( vec.getZ() ), - fabsf( vec.getW() ) - ); + return Vector4( + fabsf(vec.getX()), + fabsf(vec.getY()), + fabsf(vec.getZ()), + fabsf(vec.getW())); } -inline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +inline const Vector4 copySignPerElem(const Vector4 &vec0, const Vector4 &vec1) { - return Vector4( - ( vec1.getX() < 0.0f )? -fabsf( vec0.getX() ) : fabsf( vec0.getX() ), - ( vec1.getY() < 0.0f )? -fabsf( vec0.getY() ) : fabsf( vec0.getY() ), - ( vec1.getZ() < 0.0f )? -fabsf( vec0.getZ() ) : fabsf( vec0.getZ() ), - ( vec1.getW() < 0.0f )? -fabsf( vec0.getW() ) : fabsf( vec0.getW() ) - ); + return Vector4( + (vec1.getX() < 0.0f) ? -fabsf(vec0.getX()) : fabsf(vec0.getX()), + (vec1.getY() < 0.0f) ? -fabsf(vec0.getY()) : fabsf(vec0.getY()), + (vec1.getZ() < 0.0f) ? -fabsf(vec0.getZ()) : fabsf(vec0.getZ()), + (vec1.getW() < 0.0f) ? -fabsf(vec0.getW()) : fabsf(vec0.getW())); } -inline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +inline const Vector4 maxPerElem(const Vector4 &vec0, const Vector4 &vec1) { - return Vector4( - (vec0.getX() > vec1.getX())? vec0.getX() : vec1.getX(), - (vec0.getY() > vec1.getY())? vec0.getY() : vec1.getY(), - (vec0.getZ() > vec1.getZ())? vec0.getZ() : vec1.getZ(), - (vec0.getW() > vec1.getW())? vec0.getW() : vec1.getW() - ); + return Vector4( + (vec0.getX() > vec1.getX()) ? vec0.getX() : vec1.getX(), + (vec0.getY() > vec1.getY()) ? vec0.getY() : vec1.getY(), + (vec0.getZ() > vec1.getZ()) ? vec0.getZ() : vec1.getZ(), + (vec0.getW() > vec1.getW()) ? vec0.getW() : vec1.getW()); } -inline float maxElem( const Vector4 & vec ) +inline float maxElem(const Vector4 &vec) { - float result; - result = (vec.getX() > vec.getY())? vec.getX() : vec.getY(); - result = (vec.getZ() > result)? vec.getZ() : result; - result = (vec.getW() > result)? vec.getW() : result; - return result; + float result; + result = (vec.getX() > vec.getY()) ? vec.getX() : vec.getY(); + result = (vec.getZ() > result) ? vec.getZ() : result; + result = (vec.getW() > result) ? vec.getW() : result; + return result; } -inline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 ) +inline const Vector4 minPerElem(const Vector4 &vec0, const Vector4 &vec1) { - return Vector4( - (vec0.getX() < vec1.getX())? vec0.getX() : vec1.getX(), - (vec0.getY() < vec1.getY())? vec0.getY() : vec1.getY(), - (vec0.getZ() < vec1.getZ())? vec0.getZ() : vec1.getZ(), - (vec0.getW() < vec1.getW())? vec0.getW() : vec1.getW() - ); + return Vector4( + (vec0.getX() < vec1.getX()) ? vec0.getX() : vec1.getX(), + (vec0.getY() < vec1.getY()) ? vec0.getY() : vec1.getY(), + (vec0.getZ() < vec1.getZ()) ? vec0.getZ() : vec1.getZ(), + (vec0.getW() < vec1.getW()) ? vec0.getW() : vec1.getW()); } -inline float minElem( const Vector4 & vec ) +inline float minElem(const Vector4 &vec) { - float result; - result = (vec.getX() < vec.getY())? vec.getX() : vec.getY(); - result = (vec.getZ() < result)? vec.getZ() : result; - result = (vec.getW() < result)? vec.getW() : result; - return result; + float result; + result = (vec.getX() < vec.getY()) ? vec.getX() : vec.getY(); + result = (vec.getZ() < result) ? vec.getZ() : result; + result = (vec.getW() < result) ? vec.getW() : result; + return result; } -inline float sum( const Vector4 & vec ) +inline float sum(const Vector4 &vec) { - float result; - result = ( vec.getX() + vec.getY() ); - result = ( result + vec.getZ() ); - result = ( result + vec.getW() ); - return result; + float result; + result = (vec.getX() + vec.getY()); + result = (result + vec.getZ()); + result = (result + vec.getW()); + return result; } -inline float dot( const Vector4 & vec0, const Vector4 & vec1 ) +inline float dot(const Vector4 &vec0, const Vector4 &vec1) { - float result; - result = ( vec0.getX() * vec1.getX() ); - result = ( result + ( vec0.getY() * vec1.getY() ) ); - result = ( result + ( vec0.getZ() * vec1.getZ() ) ); - result = ( result + ( vec0.getW() * vec1.getW() ) ); - return result; + float result; + result = (vec0.getX() * vec1.getX()); + result = (result + (vec0.getY() * vec1.getY())); + result = (result + (vec0.getZ() * vec1.getZ())); + result = (result + (vec0.getW() * vec1.getW())); + return result; } -inline float lengthSqr( const Vector4 & vec ) +inline float lengthSqr(const Vector4 &vec) { - float result; - result = ( vec.getX() * vec.getX() ); - result = ( result + ( vec.getY() * vec.getY() ) ); - result = ( result + ( vec.getZ() * vec.getZ() ) ); - result = ( result + ( vec.getW() * vec.getW() ) ); - return result; + float result; + result = (vec.getX() * vec.getX()); + result = (result + (vec.getY() * vec.getY())); + result = (result + (vec.getZ() * vec.getZ())); + result = (result + (vec.getW() * vec.getW())); + return result; } -inline float length( const Vector4 & vec ) +inline float length(const Vector4 &vec) { - return ::sqrtf( lengthSqr( vec ) ); + return ::sqrtf(lengthSqr(vec)); } -inline const Vector4 normalize( const Vector4 & vec ) +inline const Vector4 normalize(const Vector4 &vec) { - float lenSqr, lenInv; - lenSqr = lengthSqr( vec ); - lenInv = ( 1.0f / sqrtf( lenSqr ) ); - return Vector4( - ( vec.getX() * lenInv ), - ( vec.getY() * lenInv ), - ( vec.getZ() * lenInv ), - ( vec.getW() * lenInv ) - ); + float lenSqr, lenInv; + lenSqr = lengthSqr(vec); + lenInv = (1.0f / sqrtf(lenSqr)); + return Vector4( + (vec.getX() * lenInv), + (vec.getY() * lenInv), + (vec.getZ() * lenInv), + (vec.getW() * lenInv)); } -inline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, bool select1 ) +inline const Vector4 select(const Vector4 &vec0, const Vector4 &vec1, bool select1) { - return Vector4( - ( select1 )? vec1.getX() : vec0.getX(), - ( select1 )? vec1.getY() : vec0.getY(), - ( select1 )? vec1.getZ() : vec0.getZ(), - ( select1 )? vec1.getW() : vec0.getW() - ); + return Vector4( + (select1) ? vec1.getX() : vec0.getX(), + (select1) ? vec1.getY() : vec0.getY(), + (select1) ? vec1.getZ() : vec0.getZ(), + (select1) ? vec1.getW() : vec0.getW()); } #ifdef _VECTORMATH_DEBUG -inline void print( const Vector4 & vec ) +inline void print(const Vector4 &vec) { - printf( "( %f %f %f %f )\n", vec.getX(), vec.getY(), vec.getZ(), vec.getW() ); + printf("( %f %f %f %f )\n", vec.getX(), vec.getY(), vec.getZ(), vec.getW()); } -inline void print( const Vector4 & vec, const char * name ) +inline void print(const Vector4 &vec, const char *name) { - printf( "%s: ( %f %f %f %f )\n", name, vec.getX(), vec.getY(), vec.getZ(), vec.getW() ); + printf("%s: ( %f %f %f %f )\n", name, vec.getX(), vec.getY(), vec.getZ(), vec.getW()); } #endif -inline Point3::Point3( const Point3 & pnt ) +inline Point3::Point3(const Point3 &pnt) { - mX = pnt.mX; - mY = pnt.mY; - mZ = pnt.mZ; + mX = pnt.mX; + mY = pnt.mY; + mZ = pnt.mZ; } -inline Point3::Point3( float _x, float _y, float _z ) +inline Point3::Point3(float _x, float _y, float _z) { - mX = _x; - mY = _y; - mZ = _z; + mX = _x; + mY = _y; + mZ = _z; } -inline Point3::Point3( const Vector3 & vec ) +inline Point3::Point3(const Vector3 &vec) { - mX = vec.getX(); - mY = vec.getY(); - mZ = vec.getZ(); + mX = vec.getX(); + mY = vec.getY(); + mZ = vec.getZ(); } -inline Point3::Point3( float scalar ) +inline Point3::Point3(float scalar) { - mX = scalar; - mY = scalar; - mZ = scalar; + mX = scalar; + mY = scalar; + mZ = scalar; } -inline const Point3 lerp( float t, const Point3 & pnt0, const Point3 & pnt1 ) +inline const Point3 lerp(float t, const Point3 &pnt0, const Point3 &pnt1) { - return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) ); + return (pnt0 + ((pnt1 - pnt0) * t)); } -inline void loadXYZ( Point3 & pnt, const float * fptr ) +inline void loadXYZ(Point3 &pnt, const float *fptr) { - pnt = Point3( fptr[0], fptr[1], fptr[2] ); + pnt = Point3(fptr[0], fptr[1], fptr[2]); } -inline void storeXYZ( const Point3 & pnt, float * fptr ) +inline void storeXYZ(const Point3 &pnt, float *fptr) { - fptr[0] = pnt.getX(); - fptr[1] = pnt.getY(); - fptr[2] = pnt.getZ(); + fptr[0] = pnt.getX(); + fptr[1] = pnt.getY(); + fptr[2] = pnt.getZ(); } -inline void loadHalfFloats( Point3 & vec, const unsigned short * hfptr ) +inline void loadHalfFloats(Point3 &vec, const unsigned short *hfptr) { - union Data32 { - unsigned int u32; - float f32; - }; + union Data32 { + unsigned int u32; + float f32; + }; - for (int i = 0; i < 3; i++) { - unsigned short fp16 = hfptr[i]; - unsigned int sign = fp16 >> 15; - unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); - unsigned int mantissa = fp16 & ((1 << 10) - 1); + for (int i = 0; i < 3; i++) + { + unsigned short fp16 = hfptr[i]; + unsigned int sign = fp16 >> 15; + unsigned int exponent = (fp16 >> 10) & ((1 << 5) - 1); + unsigned int mantissa = fp16 & ((1 << 10) - 1); - if (exponent == 0) { - // zero - mantissa = 0; + if (exponent == 0) + { + // zero + mantissa = 0; + } + else if (exponent == 31) + { + // infinity or nan -> infinity + exponent = 255; + mantissa = 0; + } + else + { + exponent += 127 - 15; + mantissa <<= 13; + } - } else if (exponent == 31) { - // infinity or nan -> infinity - exponent = 255; - mantissa = 0; - - } else { - exponent += 127 - 15; - mantissa <<= 13; - } - - Data32 d; - d.u32 = (sign << 31) | (exponent << 23) | mantissa; - vec[i] = d.f32; - } + Data32 d; + d.u32 = (sign << 31) | (exponent << 23) | mantissa; + vec[i] = d.f32; + } } -inline void storeHalfFloats( const Point3 & vec, unsigned short * hfptr ) +inline void storeHalfFloats(const Point3 &vec, unsigned short *hfptr) { - union Data32 { - unsigned int u32; - float f32; - }; + union Data32 { + unsigned int u32; + float f32; + }; - for (int i = 0; i < 3; i++) { - Data32 d; - d.f32 = vec[i]; + for (int i = 0; i < 3; i++) + { + Data32 d; + d.f32 = vec[i]; - unsigned int sign = d.u32 >> 31; - unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); - unsigned int mantissa = d.u32 & ((1 << 23) - 1);; + unsigned int sign = d.u32 >> 31; + unsigned int exponent = (d.u32 >> 23) & ((1 << 8) - 1); + unsigned int mantissa = d.u32 & ((1 << 23) - 1); + ; - if (exponent == 0) { - // zero or denorm -> zero - mantissa = 0; + if (exponent == 0) + { + // zero or denorm -> zero + mantissa = 0; + } + else if (exponent == 255 && mantissa != 0) + { + // nan -> infinity + exponent = 31; + mantissa = 0; + } + else if (exponent >= 127 - 15 + 31) + { + // overflow or infinity -> infinity + exponent = 31; + mantissa = 0; + } + else if (exponent <= 127 - 15) + { + // underflow -> zero + exponent = 0; + mantissa = 0; + } + else + { + exponent -= 127 - 15; + mantissa >>= 13; + } - } else if (exponent == 255 && mantissa != 0) { - // nan -> infinity - exponent = 31; - mantissa = 0; - - } else if (exponent >= 127 - 15 + 31) { - // overflow or infinity -> infinity - exponent = 31; - mantissa = 0; - - } else if (exponent <= 127 - 15) { - // underflow -> zero - exponent = 0; - mantissa = 0; - - } else { - exponent -= 127 - 15; - mantissa >>= 13; - } - - hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); - } + hfptr[i] = (unsigned short)((sign << 15) | (exponent << 10) | mantissa); + } } -inline Point3 & Point3::operator =( const Point3 & pnt ) +inline Point3 &Point3::operator=(const Point3 &pnt) { - mX = pnt.mX; - mY = pnt.mY; - mZ = pnt.mZ; - return *this; + mX = pnt.mX; + mY = pnt.mY; + mZ = pnt.mZ; + return *this; } -inline Point3 & Point3::setX( float _x ) +inline Point3 &Point3::setX(float _x) { - mX = _x; - return *this; + mX = _x; + return *this; } -inline float Point3::getX( ) const +inline float Point3::getX() const { - return mX; + return mX; } -inline Point3 & Point3::setY( float _y ) +inline Point3 &Point3::setY(float _y) { - mY = _y; - return *this; + mY = _y; + return *this; } -inline float Point3::getY( ) const +inline float Point3::getY() const { - return mY; + return mY; } -inline Point3 & Point3::setZ( float _z ) +inline Point3 &Point3::setZ(float _z) { - mZ = _z; - return *this; + mZ = _z; + return *this; } -inline float Point3::getZ( ) const +inline float Point3::getZ() const { - return mZ; + return mZ; } -inline Point3 & Point3::setElem( int idx, float value ) +inline Point3 &Point3::setElem(int idx, float value) { - *(&mX + idx) = value; - return *this; + *(&mX + idx) = value; + return *this; } -inline float Point3::getElem( int idx ) const +inline float Point3::getElem(int idx) const { - return *(&mX + idx); + return *(&mX + idx); } -inline float & Point3::operator []( int idx ) +inline float &Point3::operator[](int idx) { - return *(&mX + idx); + return *(&mX + idx); } -inline float Point3::operator []( int idx ) const +inline float Point3::operator[](int idx) const { - return *(&mX + idx); + return *(&mX + idx); } -inline const Vector3 Point3::operator -( const Point3 & pnt ) const +inline const Vector3 Point3::operator-(const Point3 &pnt) const { - return Vector3( - ( mX - pnt.mX ), - ( mY - pnt.mY ), - ( mZ - pnt.mZ ) - ); + return Vector3( + (mX - pnt.mX), + (mY - pnt.mY), + (mZ - pnt.mZ)); } -inline const Point3 Point3::operator +( const Vector3 & vec ) const +inline const Point3 Point3::operator+(const Vector3 &vec) const { - return Point3( - ( mX + vec.getX() ), - ( mY + vec.getY() ), - ( mZ + vec.getZ() ) - ); + return Point3( + (mX + vec.getX()), + (mY + vec.getY()), + (mZ + vec.getZ())); } -inline const Point3 Point3::operator -( const Vector3 & vec ) const +inline const Point3 Point3::operator-(const Vector3 &vec) const { - return Point3( - ( mX - vec.getX() ), - ( mY - vec.getY() ), - ( mZ - vec.getZ() ) - ); + return Point3( + (mX - vec.getX()), + (mY - vec.getY()), + (mZ - vec.getZ())); } -inline Point3 & Point3::operator +=( const Vector3 & vec ) +inline Point3 &Point3::operator+=(const Vector3 &vec) { - *this = *this + vec; - return *this; + *this = *this + vec; + return *this; } -inline Point3 & Point3::operator -=( const Vector3 & vec ) +inline Point3 &Point3::operator-=(const Vector3 &vec) { - *this = *this - vec; - return *this; + *this = *this - vec; + return *this; } -inline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +inline const Point3 mulPerElem(const Point3 &pnt0, const Point3 &pnt1) { - return Point3( - ( pnt0.getX() * pnt1.getX() ), - ( pnt0.getY() * pnt1.getY() ), - ( pnt0.getZ() * pnt1.getZ() ) - ); + return Point3( + (pnt0.getX() * pnt1.getX()), + (pnt0.getY() * pnt1.getY()), + (pnt0.getZ() * pnt1.getZ())); } -inline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +inline const Point3 divPerElem(const Point3 &pnt0, const Point3 &pnt1) { - return Point3( - ( pnt0.getX() / pnt1.getX() ), - ( pnt0.getY() / pnt1.getY() ), - ( pnt0.getZ() / pnt1.getZ() ) - ); + return Point3( + (pnt0.getX() / pnt1.getX()), + (pnt0.getY() / pnt1.getY()), + (pnt0.getZ() / pnt1.getZ())); } -inline const Point3 recipPerElem( const Point3 & pnt ) +inline const Point3 recipPerElem(const Point3 &pnt) { - return Point3( - ( 1.0f / pnt.getX() ), - ( 1.0f / pnt.getY() ), - ( 1.0f / pnt.getZ() ) - ); + return Point3( + (1.0f / pnt.getX()), + (1.0f / pnt.getY()), + (1.0f / pnt.getZ())); } -inline const Point3 sqrtPerElem( const Point3 & pnt ) +inline const Point3 sqrtPerElem(const Point3 &pnt) { - return Point3( - sqrtf( pnt.getX() ), - sqrtf( pnt.getY() ), - sqrtf( pnt.getZ() ) - ); + return Point3( + sqrtf(pnt.getX()), + sqrtf(pnt.getY()), + sqrtf(pnt.getZ())); } -inline const Point3 rsqrtPerElem( const Point3 & pnt ) +inline const Point3 rsqrtPerElem(const Point3 &pnt) { - return Point3( - ( 1.0f / sqrtf( pnt.getX() ) ), - ( 1.0f / sqrtf( pnt.getY() ) ), - ( 1.0f / sqrtf( pnt.getZ() ) ) - ); + return Point3( + (1.0f / sqrtf(pnt.getX())), + (1.0f / sqrtf(pnt.getY())), + (1.0f / sqrtf(pnt.getZ()))); } -inline const Point3 absPerElem( const Point3 & pnt ) +inline const Point3 absPerElem(const Point3 &pnt) { - return Point3( - fabsf( pnt.getX() ), - fabsf( pnt.getY() ), - fabsf( pnt.getZ() ) - ); + return Point3( + fabsf(pnt.getX()), + fabsf(pnt.getY()), + fabsf(pnt.getZ())); } -inline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +inline const Point3 copySignPerElem(const Point3 &pnt0, const Point3 &pnt1) { - return Point3( - ( pnt1.getX() < 0.0f )? -fabsf( pnt0.getX() ) : fabsf( pnt0.getX() ), - ( pnt1.getY() < 0.0f )? -fabsf( pnt0.getY() ) : fabsf( pnt0.getY() ), - ( pnt1.getZ() < 0.0f )? -fabsf( pnt0.getZ() ) : fabsf( pnt0.getZ() ) - ); + return Point3( + (pnt1.getX() < 0.0f) ? -fabsf(pnt0.getX()) : fabsf(pnt0.getX()), + (pnt1.getY() < 0.0f) ? -fabsf(pnt0.getY()) : fabsf(pnt0.getY()), + (pnt1.getZ() < 0.0f) ? -fabsf(pnt0.getZ()) : fabsf(pnt0.getZ())); } -inline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +inline const Point3 maxPerElem(const Point3 &pnt0, const Point3 &pnt1) { - return Point3( - (pnt0.getX() > pnt1.getX())? pnt0.getX() : pnt1.getX(), - (pnt0.getY() > pnt1.getY())? pnt0.getY() : pnt1.getY(), - (pnt0.getZ() > pnt1.getZ())? pnt0.getZ() : pnt1.getZ() - ); + return Point3( + (pnt0.getX() > pnt1.getX()) ? pnt0.getX() : pnt1.getX(), + (pnt0.getY() > pnt1.getY()) ? pnt0.getY() : pnt1.getY(), + (pnt0.getZ() > pnt1.getZ()) ? pnt0.getZ() : pnt1.getZ()); } -inline float maxElem( const Point3 & pnt ) +inline float maxElem(const Point3 &pnt) { - float result; - result = (pnt.getX() > pnt.getY())? pnt.getX() : pnt.getY(); - result = (pnt.getZ() > result)? pnt.getZ() : result; - return result; + float result; + result = (pnt.getX() > pnt.getY()) ? pnt.getX() : pnt.getY(); + result = (pnt.getZ() > result) ? pnt.getZ() : result; + return result; } -inline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 ) +inline const Point3 minPerElem(const Point3 &pnt0, const Point3 &pnt1) { - return Point3( - (pnt0.getX() < pnt1.getX())? pnt0.getX() : pnt1.getX(), - (pnt0.getY() < pnt1.getY())? pnt0.getY() : pnt1.getY(), - (pnt0.getZ() < pnt1.getZ())? pnt0.getZ() : pnt1.getZ() - ); + return Point3( + (pnt0.getX() < pnt1.getX()) ? pnt0.getX() : pnt1.getX(), + (pnt0.getY() < pnt1.getY()) ? pnt0.getY() : pnt1.getY(), + (pnt0.getZ() < pnt1.getZ()) ? pnt0.getZ() : pnt1.getZ()); } -inline float minElem( const Point3 & pnt ) +inline float minElem(const Point3 &pnt) { - float result; - result = (pnt.getX() < pnt.getY())? pnt.getX() : pnt.getY(); - result = (pnt.getZ() < result)? pnt.getZ() : result; - return result; + float result; + result = (pnt.getX() < pnt.getY()) ? pnt.getX() : pnt.getY(); + result = (pnt.getZ() < result) ? pnt.getZ() : result; + return result; } -inline float sum( const Point3 & pnt ) +inline float sum(const Point3 &pnt) { - float result; - result = ( pnt.getX() + pnt.getY() ); - result = ( result + pnt.getZ() ); - return result; + float result; + result = (pnt.getX() + pnt.getY()); + result = (result + pnt.getZ()); + return result; } -inline const Point3 scale( const Point3 & pnt, float scaleVal ) +inline const Point3 scale(const Point3 &pnt, float scaleVal) { - return mulPerElem( pnt, Point3( scaleVal ) ); + return mulPerElem(pnt, Point3(scaleVal)); } -inline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec ) +inline const Point3 scale(const Point3 &pnt, const Vector3 &scaleVec) { - return mulPerElem( pnt, Point3( scaleVec ) ); + return mulPerElem(pnt, Point3(scaleVec)); } -inline float projection( const Point3 & pnt, const Vector3 & unitVec ) +inline float projection(const Point3 &pnt, const Vector3 &unitVec) { - float result; - result = ( pnt.getX() * unitVec.getX() ); - result = ( result + ( pnt.getY() * unitVec.getY() ) ); - result = ( result + ( pnt.getZ() * unitVec.getZ() ) ); - return result; + float result; + result = (pnt.getX() * unitVec.getX()); + result = (result + (pnt.getY() * unitVec.getY())); + result = (result + (pnt.getZ() * unitVec.getZ())); + return result; } -inline float distSqrFromOrigin( const Point3 & pnt ) +inline float distSqrFromOrigin(const Point3 &pnt) { - return lengthSqr( Vector3( pnt ) ); + return lengthSqr(Vector3(pnt)); } -inline float distFromOrigin( const Point3 & pnt ) +inline float distFromOrigin(const Point3 &pnt) { - return length( Vector3( pnt ) ); + return length(Vector3(pnt)); } -inline float distSqr( const Point3 & pnt0, const Point3 & pnt1 ) +inline float distSqr(const Point3 &pnt0, const Point3 &pnt1) { - return lengthSqr( ( pnt1 - pnt0 ) ); + return lengthSqr((pnt1 - pnt0)); } -inline float dist( const Point3 & pnt0, const Point3 & pnt1 ) +inline float dist(const Point3 &pnt0, const Point3 &pnt1) { - return length( ( pnt1 - pnt0 ) ); + return length((pnt1 - pnt0)); } -inline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, bool select1 ) +inline const Point3 select(const Point3 &pnt0, const Point3 &pnt1, bool select1) { - return Point3( - ( select1 )? pnt1.getX() : pnt0.getX(), - ( select1 )? pnt1.getY() : pnt0.getY(), - ( select1 )? pnt1.getZ() : pnt0.getZ() - ); + return Point3( + (select1) ? pnt1.getX() : pnt0.getX(), + (select1) ? pnt1.getY() : pnt0.getY(), + (select1) ? pnt1.getZ() : pnt0.getZ()); } #ifdef _VECTORMATH_DEBUG -inline void print( const Point3 & pnt ) +inline void print(const Point3 &pnt) { - printf( "( %f %f %f )\n", pnt.getX(), pnt.getY(), pnt.getZ() ); + printf("( %f %f %f )\n", pnt.getX(), pnt.getY(), pnt.getZ()); } -inline void print( const Point3 & pnt, const char * name ) +inline void print(const Point3 &pnt, const char *name) { - printf( "%s: ( %f %f %f )\n", name, pnt.getX(), pnt.getY(), pnt.getZ() ); + printf("%s: ( %f %f %f )\n", name, pnt.getX(), pnt.getY(), pnt.getZ()); } #endif -} // namespace Aos -} // namespace Vectormath +} // namespace Aos +} // namespace Vectormath #endif diff --git a/test/Bullet2/vectormath/scalar/vectormath_aos.h b/test/Bullet2/vectormath/scalar/vectormath_aos.h index d00456dfe..574c159d0 100644 --- a/test/Bullet2/vectormath/scalar/vectormath_aos.h +++ b/test/Bullet2/vectormath/scalar/vectormath_aos.h @@ -23,10 +23,10 @@ subject to the following restrictions: #include #endif -namespace Vectormath { - -namespace Aos { - +namespace Vectormath +{ +namespace Aos +{ //----------------------------------------------------------------------------- // Forward Declarations // @@ -43,288 +43,288 @@ class Transform3; // class Vector3 { - float mX; - float mY; - float mZ; + float mX; + float mY; + float mZ; #ifndef __GNUC__ - float d; + float d; #endif public: - // Default constructor; does no initialization - // - inline Vector3( ) { }; + // Default constructor; does no initialization + // + inline Vector3(){}; - // Copy a 3-D vector - // - inline Vector3( const Vector3 & vec ); + // Copy a 3-D vector + // + inline Vector3(const Vector3 &vec); - // Construct a 3-D vector from x, y, and z elements - // - inline Vector3( float x, float y, float z ); + // Construct a 3-D vector from x, y, and z elements + // + inline Vector3(float x, float y, float z); - // Copy elements from a 3-D point into a 3-D vector - // - explicit inline Vector3( const Point3 & pnt ); + // Copy elements from a 3-D point into a 3-D vector + // + explicit inline Vector3(const Point3 &pnt); - // Set all elements of a 3-D vector to the same scalar value - // - explicit inline Vector3( float scalar ); + // Set all elements of a 3-D vector to the same scalar value + // + explicit inline Vector3(float scalar); - // Assign one 3-D vector to another - // - inline Vector3 & operator =( const Vector3 & vec ); + // Assign one 3-D vector to another + // + inline Vector3 &operator=(const Vector3 &vec); - // Set the x element of a 3-D vector - // - inline Vector3 & setX( float x ); + // Set the x element of a 3-D vector + // + inline Vector3 &setX(float x); - // Set the y element of a 3-D vector - // - inline Vector3 & setY( float y ); + // Set the y element of a 3-D vector + // + inline Vector3 &setY(float y); - // Set the z element of a 3-D vector - // - inline Vector3 & setZ( float z ); + // Set the z element of a 3-D vector + // + inline Vector3 &setZ(float z); - // Get the x element of a 3-D vector - // - inline float getX( ) const; + // Get the x element of a 3-D vector + // + inline float getX() const; - // Get the y element of a 3-D vector - // - inline float getY( ) const; + // Get the y element of a 3-D vector + // + inline float getY() const; - // Get the z element of a 3-D vector - // - inline float getZ( ) const; + // Get the z element of a 3-D vector + // + inline float getZ() const; - // Set an x, y, or z element of a 3-D vector by index - // - inline Vector3 & setElem( int idx, float value ); + // Set an x, y, or z element of a 3-D vector by index + // + inline Vector3 &setElem(int idx, float value); - // Get an x, y, or z element of a 3-D vector by index - // - inline float getElem( int idx ) const; + // Get an x, y, or z element of a 3-D vector by index + // + inline float getElem(int idx) const; - // Subscripting operator to set or get an element - // - inline float & operator []( int idx ); + // Subscripting operator to set or get an element + // + inline float &operator[](int idx); - // Subscripting operator to get an element - // - inline float operator []( int idx ) const; + // Subscripting operator to get an element + // + inline float operator[](int idx) const; - // Add two 3-D vectors - // - inline const Vector3 operator +( const Vector3 & vec ) const; + // Add two 3-D vectors + // + inline const Vector3 operator+(const Vector3 &vec) const; - // Subtract a 3-D vector from another 3-D vector - // - inline const Vector3 operator -( const Vector3 & vec ) const; + // Subtract a 3-D vector from another 3-D vector + // + inline const Vector3 operator-(const Vector3 &vec) const; - // Add a 3-D vector to a 3-D point - // - inline const Point3 operator +( const Point3 & pnt ) const; + // Add a 3-D vector to a 3-D point + // + inline const Point3 operator+(const Point3 &pnt) const; - // Multiply a 3-D vector by a scalar - // - inline const Vector3 operator *( float scalar ) const; + // Multiply a 3-D vector by a scalar + // + inline const Vector3 operator*(float scalar) const; - // Divide a 3-D vector by a scalar - // - inline const Vector3 operator /( float scalar ) const; + // Divide a 3-D vector by a scalar + // + inline const Vector3 operator/(float scalar) const; - // Perform compound assignment and addition with a 3-D vector - // - inline Vector3 & operator +=( const Vector3 & vec ); + // Perform compound assignment and addition with a 3-D vector + // + inline Vector3 &operator+=(const Vector3 &vec); - // Perform compound assignment and subtraction by a 3-D vector - // - inline Vector3 & operator -=( const Vector3 & vec ); + // Perform compound assignment and subtraction by a 3-D vector + // + inline Vector3 &operator-=(const Vector3 &vec); - // Perform compound assignment and multiplication by a scalar - // - inline Vector3 & operator *=( float scalar ); + // Perform compound assignment and multiplication by a scalar + // + inline Vector3 &operator*=(float scalar); - // Perform compound assignment and division by a scalar - // - inline Vector3 & operator /=( float scalar ); + // Perform compound assignment and division by a scalar + // + inline Vector3 &operator/=(float scalar); - // Negate all elements of a 3-D vector - // - inline const Vector3 operator -( ) const; + // Negate all elements of a 3-D vector + // + inline const Vector3 operator-() const; - // Construct x axis - // - static inline const Vector3 xAxis( ); + // Construct x axis + // + static inline const Vector3 xAxis(); - // Construct y axis - // - static inline const Vector3 yAxis( ); + // Construct y axis + // + static inline const Vector3 yAxis(); - // Construct z axis - // - static inline const Vector3 zAxis( ); + // Construct z axis + // + static inline const Vector3 zAxis(); } #ifdef __GNUC__ -__attribute__ ((aligned(16))) +__attribute__((aligned(16))) #endif ; // Multiply a 3-D vector by a scalar -// -inline const Vector3 operator *( float scalar, const Vector3 & vec ); +// +inline const Vector3 operator*(float scalar, const Vector3 &vec); // Multiply two 3-D vectors per element -// -inline const Vector3 mulPerElem( const Vector3 & vec0, const Vector3 & vec1 ); +// +inline const Vector3 mulPerElem(const Vector3 &vec0, const Vector3 &vec1); // Divide two 3-D vectors per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function divf4. -// -inline const Vector3 divPerElem( const Vector3 & vec0, const Vector3 & vec1 ); +// +inline const Vector3 divPerElem(const Vector3 &vec0, const Vector3 &vec1); // Compute the reciprocal of a 3-D vector per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function recipf4. -// -inline const Vector3 recipPerElem( const Vector3 & vec ); +// +inline const Vector3 recipPerElem(const Vector3 &vec); // Compute the square root of a 3-D vector per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function sqrtf4. -// -inline const Vector3 sqrtPerElem( const Vector3 & vec ); +// +inline const Vector3 sqrtPerElem(const Vector3 &vec); // Compute the reciprocal square root of a 3-D vector per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function rsqrtf4. -// -inline const Vector3 rsqrtPerElem( const Vector3 & vec ); +// +inline const Vector3 rsqrtPerElem(const Vector3 &vec); // Compute the absolute value of a 3-D vector per element -// -inline const Vector3 absPerElem( const Vector3 & vec ); +// +inline const Vector3 absPerElem(const Vector3 &vec); // Copy sign from one 3-D vector to another, per element -// -inline const Vector3 copySignPerElem( const Vector3 & vec0, const Vector3 & vec1 ); +// +inline const Vector3 copySignPerElem(const Vector3 &vec0, const Vector3 &vec1); // Maximum of two 3-D vectors per element -// -inline const Vector3 maxPerElem( const Vector3 & vec0, const Vector3 & vec1 ); +// +inline const Vector3 maxPerElem(const Vector3 &vec0, const Vector3 &vec1); // Minimum of two 3-D vectors per element -// -inline const Vector3 minPerElem( const Vector3 & vec0, const Vector3 & vec1 ); +// +inline const Vector3 minPerElem(const Vector3 &vec0, const Vector3 &vec1); // Maximum element of a 3-D vector -// -inline float maxElem( const Vector3 & vec ); +// +inline float maxElem(const Vector3 &vec); // Minimum element of a 3-D vector -// -inline float minElem( const Vector3 & vec ); +// +inline float minElem(const Vector3 &vec); // Compute the sum of all elements of a 3-D vector -// -inline float sum( const Vector3 & vec ); +// +inline float sum(const Vector3 &vec); // Compute the dot product of two 3-D vectors -// -inline float dot( const Vector3 & vec0, const Vector3 & vec1 ); +// +inline float dot(const Vector3 &vec0, const Vector3 &vec1); // Compute the square of the length of a 3-D vector -// -inline float lengthSqr( const Vector3 & vec ); +// +inline float lengthSqr(const Vector3 &vec); // Compute the length of a 3-D vector -// -inline float length( const Vector3 & vec ); +// +inline float length(const Vector3 &vec); // Normalize a 3-D vector -// NOTE: +// NOTE: // The result is unpredictable when all elements of vec are at or near zero. -// -inline const Vector3 normalize( const Vector3 & vec ); +// +inline const Vector3 normalize(const Vector3 &vec); // Compute cross product of two 3-D vectors -// -inline const Vector3 cross( const Vector3 & vec0, const Vector3 & vec1 ); +// +inline const Vector3 cross(const Vector3 &vec0, const Vector3 &vec1); // Outer product of two 3-D vectors -// -inline const Matrix3 outer( const Vector3 & vec0, const Vector3 & vec1 ); +// +inline const Matrix3 outer(const Vector3 &vec0, const Vector3 &vec1); // Pre-multiply a row vector by a 3x3 matrix -// -inline const Vector3 rowMul( const Vector3 & vec, const Matrix3 & mat ); +// +inline const Vector3 rowMul(const Vector3 &vec, const Matrix3 &mat); // Cross-product matrix of a 3-D vector -// -inline const Matrix3 crossMatrix( const Vector3 & vec ); +// +inline const Matrix3 crossMatrix(const Vector3 &vec); // Create cross-product matrix and multiply -// NOTE: +// NOTE: // Faster than separately creating a cross-product matrix and multiplying. -// -inline const Matrix3 crossMatrixMul( const Vector3 & vec, const Matrix3 & mat ); +// +inline const Matrix3 crossMatrixMul(const Vector3 &vec, const Matrix3 &mat); // Linear interpolation between two 3-D vectors -// NOTE: +// NOTE: // Does not clamp t between 0 and 1. -// -inline const Vector3 lerp( float t, const Vector3 & vec0, const Vector3 & vec1 ); +// +inline const Vector3 lerp(float t, const Vector3 &vec0, const Vector3 &vec1); // Spherical linear interpolation between two 3-D vectors -// NOTE: +// NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. -// -inline const Vector3 slerp( float t, const Vector3 & unitVec0, const Vector3 & unitVec1 ); +// +inline const Vector3 slerp(float t, const Vector3 &unitVec0, const Vector3 &unitVec1); // Conditionally select between two 3-D vectors -// -inline const Vector3 select( const Vector3 & vec0, const Vector3 & vec1, bool select1 ); +// +inline const Vector3 select(const Vector3 &vec0, const Vector3 &vec1, bool select1); // Load x, y, and z elements from the first three words of a float array. -// -// -inline void loadXYZ( Vector3 & vec, const float * fptr ); +// +// +inline void loadXYZ(Vector3 &vec, const float *fptr); // Store x, y, and z elements of a 3-D vector in the first three words of a float array. // Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed -// -inline void storeXYZ( const Vector3 & vec, float * fptr ); +// +inline void storeXYZ(const Vector3 &vec, float *fptr); // Load three-half-floats as a 3-D vector -// NOTE: +// NOTE: // This transformation does not support either denormalized numbers or NaNs. -// -inline void loadHalfFloats( Vector3 & vec, const unsigned short * hfptr ); +// +inline void loadHalfFloats(Vector3 &vec, const unsigned short *hfptr); // Store a 3-D vector as half-floats. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. -// NOTE: +// NOTE: // This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. -// -inline void storeHalfFloats( const Vector3 & vec, unsigned short * hfptr ); +// +inline void storeHalfFloats(const Vector3 &vec, unsigned short *hfptr); #ifdef _VECTORMATH_DEBUG // Print a 3-D vector -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Vector3 & vec ); +// +inline void print(const Vector3 &vec); // Print a 3-D vector and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Vector3 & vec, const char * name ); +// +inline void print(const Vector3 &vec, const char *name); #endif @@ -332,298 +332,298 @@ inline void print( const Vector3 & vec, const char * name ); // class Vector4 { - float mX; - float mY; - float mZ; - float mW; + float mX; + float mY; + float mZ; + float mW; public: - // Default constructor; does no initialization - // - inline Vector4( ) { }; + // Default constructor; does no initialization + // + inline Vector4(){}; - // Copy a 4-D vector - // - inline Vector4( const Vector4 & vec ); + // Copy a 4-D vector + // + inline Vector4(const Vector4 &vec); - // Construct a 4-D vector from x, y, z, and w elements - // - inline Vector4( float x, float y, float z, float w ); + // Construct a 4-D vector from x, y, z, and w elements + // + inline Vector4(float x, float y, float z, float w); - // Construct a 4-D vector from a 3-D vector and a scalar - // - inline Vector4( const Vector3 & xyz, float w ); + // Construct a 4-D vector from a 3-D vector and a scalar + // + inline Vector4(const Vector3 &xyz, float w); - // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 - // - explicit inline Vector4( const Vector3 & vec ); + // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 + // + explicit inline Vector4(const Vector3 &vec); - // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 - // - explicit inline Vector4( const Point3 & pnt ); + // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 + // + explicit inline Vector4(const Point3 &pnt); - // Copy elements from a quaternion into a 4-D vector - // - explicit inline Vector4( const Quat & quat ); + // Copy elements from a quaternion into a 4-D vector + // + explicit inline Vector4(const Quat &quat); - // Set all elements of a 4-D vector to the same scalar value - // - explicit inline Vector4( float scalar ); + // Set all elements of a 4-D vector to the same scalar value + // + explicit inline Vector4(float scalar); - // Assign one 4-D vector to another - // - inline Vector4 & operator =( const Vector4 & vec ); + // Assign one 4-D vector to another + // + inline Vector4 &operator=(const Vector4 &vec); - // Set the x, y, and z elements of a 4-D vector - // NOTE: - // This function does not change the w element. - // - inline Vector4 & setXYZ( const Vector3 & vec ); + // Set the x, y, and z elements of a 4-D vector + // NOTE: + // This function does not change the w element. + // + inline Vector4 &setXYZ(const Vector3 &vec); - // Get the x, y, and z elements of a 4-D vector - // - inline const Vector3 getXYZ( ) const; + // Get the x, y, and z elements of a 4-D vector + // + inline const Vector3 getXYZ() const; - // Set the x element of a 4-D vector - // - inline Vector4 & setX( float x ); + // Set the x element of a 4-D vector + // + inline Vector4 &setX(float x); - // Set the y element of a 4-D vector - // - inline Vector4 & setY( float y ); + // Set the y element of a 4-D vector + // + inline Vector4 &setY(float y); - // Set the z element of a 4-D vector - // - inline Vector4 & setZ( float z ); + // Set the z element of a 4-D vector + // + inline Vector4 &setZ(float z); - // Set the w element of a 4-D vector - // - inline Vector4 & setW( float w ); + // Set the w element of a 4-D vector + // + inline Vector4 &setW(float w); - // Get the x element of a 4-D vector - // - inline float getX( ) const; + // Get the x element of a 4-D vector + // + inline float getX() const; - // Get the y element of a 4-D vector - // - inline float getY( ) const; + // Get the y element of a 4-D vector + // + inline float getY() const; - // Get the z element of a 4-D vector - // - inline float getZ( ) const; + // Get the z element of a 4-D vector + // + inline float getZ() const; - // Get the w element of a 4-D vector - // - inline float getW( ) const; + // Get the w element of a 4-D vector + // + inline float getW() const; - // Set an x, y, z, or w element of a 4-D vector by index - // - inline Vector4 & setElem( int idx, float value ); + // Set an x, y, z, or w element of a 4-D vector by index + // + inline Vector4 &setElem(int idx, float value); - // Get an x, y, z, or w element of a 4-D vector by index - // - inline float getElem( int idx ) const; + // Get an x, y, z, or w element of a 4-D vector by index + // + inline float getElem(int idx) const; - // Subscripting operator to set or get an element - // - inline float & operator []( int idx ); + // Subscripting operator to set or get an element + // + inline float &operator[](int idx); - // Subscripting operator to get an element - // - inline float operator []( int idx ) const; + // Subscripting operator to get an element + // + inline float operator[](int idx) const; - // Add two 4-D vectors - // - inline const Vector4 operator +( const Vector4 & vec ) const; + // Add two 4-D vectors + // + inline const Vector4 operator+(const Vector4 &vec) const; - // Subtract a 4-D vector from another 4-D vector - // - inline const Vector4 operator -( const Vector4 & vec ) const; + // Subtract a 4-D vector from another 4-D vector + // + inline const Vector4 operator-(const Vector4 &vec) const; - // Multiply a 4-D vector by a scalar - // - inline const Vector4 operator *( float scalar ) const; + // Multiply a 4-D vector by a scalar + // + inline const Vector4 operator*(float scalar) const; - // Divide a 4-D vector by a scalar - // - inline const Vector4 operator /( float scalar ) const; + // Divide a 4-D vector by a scalar + // + inline const Vector4 operator/(float scalar) const; - // Perform compound assignment and addition with a 4-D vector - // - inline Vector4 & operator +=( const Vector4 & vec ); + // Perform compound assignment and addition with a 4-D vector + // + inline Vector4 &operator+=(const Vector4 &vec); - // Perform compound assignment and subtraction by a 4-D vector - // - inline Vector4 & operator -=( const Vector4 & vec ); + // Perform compound assignment and subtraction by a 4-D vector + // + inline Vector4 &operator-=(const Vector4 &vec); - // Perform compound assignment and multiplication by a scalar - // - inline Vector4 & operator *=( float scalar ); + // Perform compound assignment and multiplication by a scalar + // + inline Vector4 &operator*=(float scalar); - // Perform compound assignment and division by a scalar - // - inline Vector4 & operator /=( float scalar ); + // Perform compound assignment and division by a scalar + // + inline Vector4 &operator/=(float scalar); - // Negate all elements of a 4-D vector - // - inline const Vector4 operator -( ) const; + // Negate all elements of a 4-D vector + // + inline const Vector4 operator-() const; - // Construct x axis - // - static inline const Vector4 xAxis( ); + // Construct x axis + // + static inline const Vector4 xAxis(); - // Construct y axis - // - static inline const Vector4 yAxis( ); + // Construct y axis + // + static inline const Vector4 yAxis(); - // Construct z axis - // - static inline const Vector4 zAxis( ); + // Construct z axis + // + static inline const Vector4 zAxis(); - // Construct w axis - // - static inline const Vector4 wAxis( ); + // Construct w axis + // + static inline const Vector4 wAxis(); } #ifdef __GNUC__ -__attribute__ ((aligned(16))) +__attribute__((aligned(16))) #endif ; // Multiply a 4-D vector by a scalar -// -inline const Vector4 operator *( float scalar, const Vector4 & vec ); +// +inline const Vector4 operator*(float scalar, const Vector4 &vec); // Multiply two 4-D vectors per element -// -inline const Vector4 mulPerElem( const Vector4 & vec0, const Vector4 & vec1 ); +// +inline const Vector4 mulPerElem(const Vector4 &vec0, const Vector4 &vec1); // Divide two 4-D vectors per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function divf4. -// -inline const Vector4 divPerElem( const Vector4 & vec0, const Vector4 & vec1 ); +// +inline const Vector4 divPerElem(const Vector4 &vec0, const Vector4 &vec1); // Compute the reciprocal of a 4-D vector per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function recipf4. -// -inline const Vector4 recipPerElem( const Vector4 & vec ); +// +inline const Vector4 recipPerElem(const Vector4 &vec); // Compute the square root of a 4-D vector per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function sqrtf4. -// -inline const Vector4 sqrtPerElem( const Vector4 & vec ); +// +inline const Vector4 sqrtPerElem(const Vector4 &vec); // Compute the reciprocal square root of a 4-D vector per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function rsqrtf4. -// -inline const Vector4 rsqrtPerElem( const Vector4 & vec ); +// +inline const Vector4 rsqrtPerElem(const Vector4 &vec); // Compute the absolute value of a 4-D vector per element -// -inline const Vector4 absPerElem( const Vector4 & vec ); +// +inline const Vector4 absPerElem(const Vector4 &vec); // Copy sign from one 4-D vector to another, per element -// -inline const Vector4 copySignPerElem( const Vector4 & vec0, const Vector4 & vec1 ); +// +inline const Vector4 copySignPerElem(const Vector4 &vec0, const Vector4 &vec1); // Maximum of two 4-D vectors per element -// -inline const Vector4 maxPerElem( const Vector4 & vec0, const Vector4 & vec1 ); +// +inline const Vector4 maxPerElem(const Vector4 &vec0, const Vector4 &vec1); // Minimum of two 4-D vectors per element -// -inline const Vector4 minPerElem( const Vector4 & vec0, const Vector4 & vec1 ); +// +inline const Vector4 minPerElem(const Vector4 &vec0, const Vector4 &vec1); // Maximum element of a 4-D vector -// -inline float maxElem( const Vector4 & vec ); +// +inline float maxElem(const Vector4 &vec); // Minimum element of a 4-D vector -// -inline float minElem( const Vector4 & vec ); +// +inline float minElem(const Vector4 &vec); // Compute the sum of all elements of a 4-D vector -// -inline float sum( const Vector4 & vec ); +// +inline float sum(const Vector4 &vec); // Compute the dot product of two 4-D vectors -// -inline float dot( const Vector4 & vec0, const Vector4 & vec1 ); +// +inline float dot(const Vector4 &vec0, const Vector4 &vec1); // Compute the square of the length of a 4-D vector -// -inline float lengthSqr( const Vector4 & vec ); +// +inline float lengthSqr(const Vector4 &vec); // Compute the length of a 4-D vector -// -inline float length( const Vector4 & vec ); +// +inline float length(const Vector4 &vec); // Normalize a 4-D vector -// NOTE: +// NOTE: // The result is unpredictable when all elements of vec are at or near zero. -// -inline const Vector4 normalize( const Vector4 & vec ); +// +inline const Vector4 normalize(const Vector4 &vec); // Outer product of two 4-D vectors -// -inline const Matrix4 outer( const Vector4 & vec0, const Vector4 & vec1 ); +// +inline const Matrix4 outer(const Vector4 &vec0, const Vector4 &vec1); // Linear interpolation between two 4-D vectors -// NOTE: +// NOTE: // Does not clamp t between 0 and 1. -// -inline const Vector4 lerp( float t, const Vector4 & vec0, const Vector4 & vec1 ); +// +inline const Vector4 lerp(float t, const Vector4 &vec0, const Vector4 &vec1); // Spherical linear interpolation between two 4-D vectors -// NOTE: +// NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. -// -inline const Vector4 slerp( float t, const Vector4 & unitVec0, const Vector4 & unitVec1 ); +// +inline const Vector4 slerp(float t, const Vector4 &unitVec0, const Vector4 &unitVec1); // Conditionally select between two 4-D vectors -// -inline const Vector4 select( const Vector4 & vec0, const Vector4 & vec1, bool select1 ); +// +inline const Vector4 select(const Vector4 &vec0, const Vector4 &vec1, bool select1); // Load x, y, z, and w elements from the first four words of a float array. -// -// -inline void loadXYZW( Vector4 & vec, const float * fptr ); +// +// +inline void loadXYZW(Vector4 &vec, const float *fptr); // Store x, y, z, and w elements of a 4-D vector in the first four words of a float array. // Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed -// -inline void storeXYZW( const Vector4 & vec, float * fptr ); +// +inline void storeXYZW(const Vector4 &vec, float *fptr); // Load four-half-floats as a 4-D vector -// NOTE: +// NOTE: // This transformation does not support either denormalized numbers or NaNs. -// -inline void loadHalfFloats( Vector4 & vec, const unsigned short * hfptr ); +// +inline void loadHalfFloats(Vector4 &vec, const unsigned short *hfptr); // Store a 4-D vector as half-floats. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. -// NOTE: +// NOTE: // This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. -// -inline void storeHalfFloats( const Vector4 & vec, unsigned short * hfptr ); +// +inline void storeHalfFloats(const Vector4 &vec, unsigned short *hfptr); #ifdef _VECTORMATH_DEBUG // Print a 4-D vector -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Vector4 & vec ); +// +inline void print(const Vector4 &vec); // Print a 4-D vector and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Vector4 & vec, const char * name ); +// +inline void print(const Vector4 &vec, const char *name); #endif @@ -631,233 +631,233 @@ inline void print( const Vector4 & vec, const char * name ); // class Point3 { - float mX; - float mY; - float mZ; + float mX; + float mY; + float mZ; #ifndef __GNUC__ - float d; + float d; #endif public: - // Default constructor; does no initialization - // - inline Point3( ) { }; + // Default constructor; does no initialization + // + inline Point3(){}; - // Copy a 3-D point - // - inline Point3( const Point3 & pnt ); + // Copy a 3-D point + // + inline Point3(const Point3 &pnt); - // Construct a 3-D point from x, y, and z elements - // - inline Point3( float x, float y, float z ); + // Construct a 3-D point from x, y, and z elements + // + inline Point3(float x, float y, float z); - // Copy elements from a 3-D vector into a 3-D point - // - explicit inline Point3( const Vector3 & vec ); + // Copy elements from a 3-D vector into a 3-D point + // + explicit inline Point3(const Vector3 &vec); - // Set all elements of a 3-D point to the same scalar value - // - explicit inline Point3( float scalar ); + // Set all elements of a 3-D point to the same scalar value + // + explicit inline Point3(float scalar); - // Assign one 3-D point to another - // - inline Point3 & operator =( const Point3 & pnt ); + // Assign one 3-D point to another + // + inline Point3 &operator=(const Point3 &pnt); - // Set the x element of a 3-D point - // - inline Point3 & setX( float x ); + // Set the x element of a 3-D point + // + inline Point3 &setX(float x); - // Set the y element of a 3-D point - // - inline Point3 & setY( float y ); + // Set the y element of a 3-D point + // + inline Point3 &setY(float y); - // Set the z element of a 3-D point - // - inline Point3 & setZ( float z ); + // Set the z element of a 3-D point + // + inline Point3 &setZ(float z); - // Get the x element of a 3-D point - // - inline float getX( ) const; + // Get the x element of a 3-D point + // + inline float getX() const; - // Get the y element of a 3-D point - // - inline float getY( ) const; + // Get the y element of a 3-D point + // + inline float getY() const; - // Get the z element of a 3-D point - // - inline float getZ( ) const; + // Get the z element of a 3-D point + // + inline float getZ() const; - // Set an x, y, or z element of a 3-D point by index - // - inline Point3 & setElem( int idx, float value ); + // Set an x, y, or z element of a 3-D point by index + // + inline Point3 &setElem(int idx, float value); - // Get an x, y, or z element of a 3-D point by index - // - inline float getElem( int idx ) const; + // Get an x, y, or z element of a 3-D point by index + // + inline float getElem(int idx) const; - // Subscripting operator to set or get an element - // - inline float & operator []( int idx ); + // Subscripting operator to set or get an element + // + inline float &operator[](int idx); - // Subscripting operator to get an element - // - inline float operator []( int idx ) const; + // Subscripting operator to get an element + // + inline float operator[](int idx) const; - // Subtract a 3-D point from another 3-D point - // - inline const Vector3 operator -( const Point3 & pnt ) const; + // Subtract a 3-D point from another 3-D point + // + inline const Vector3 operator-(const Point3 &pnt) const; - // Add a 3-D point to a 3-D vector - // - inline const Point3 operator +( const Vector3 & vec ) const; + // Add a 3-D point to a 3-D vector + // + inline const Point3 operator+(const Vector3 &vec) const; - // Subtract a 3-D vector from a 3-D point - // - inline const Point3 operator -( const Vector3 & vec ) const; + // Subtract a 3-D vector from a 3-D point + // + inline const Point3 operator-(const Vector3 &vec) const; - // Perform compound assignment and addition with a 3-D vector - // - inline Point3 & operator +=( const Vector3 & vec ); + // Perform compound assignment and addition with a 3-D vector + // + inline Point3 &operator+=(const Vector3 &vec); - // Perform compound assignment and subtraction by a 3-D vector - // - inline Point3 & operator -=( const Vector3 & vec ); + // Perform compound assignment and subtraction by a 3-D vector + // + inline Point3 &operator-=(const Vector3 &vec); } #ifdef __GNUC__ -__attribute__ ((aligned(16))) +__attribute__((aligned(16))) #endif ; // Multiply two 3-D points per element -// -inline const Point3 mulPerElem( const Point3 & pnt0, const Point3 & pnt1 ); +// +inline const Point3 mulPerElem(const Point3 &pnt0, const Point3 &pnt1); // Divide two 3-D points per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function divf4. -// -inline const Point3 divPerElem( const Point3 & pnt0, const Point3 & pnt1 ); +// +inline const Point3 divPerElem(const Point3 &pnt0, const Point3 &pnt1); // Compute the reciprocal of a 3-D point per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function recipf4. -// -inline const Point3 recipPerElem( const Point3 & pnt ); +// +inline const Point3 recipPerElem(const Point3 &pnt); // Compute the square root of a 3-D point per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function sqrtf4. -// -inline const Point3 sqrtPerElem( const Point3 & pnt ); +// +inline const Point3 sqrtPerElem(const Point3 &pnt); // Compute the reciprocal square root of a 3-D point per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function rsqrtf4. -// -inline const Point3 rsqrtPerElem( const Point3 & pnt ); +// +inline const Point3 rsqrtPerElem(const Point3 &pnt); // Compute the absolute value of a 3-D point per element -// -inline const Point3 absPerElem( const Point3 & pnt ); +// +inline const Point3 absPerElem(const Point3 &pnt); // Copy sign from one 3-D point to another, per element -// -inline const Point3 copySignPerElem( const Point3 & pnt0, const Point3 & pnt1 ); +// +inline const Point3 copySignPerElem(const Point3 &pnt0, const Point3 &pnt1); // Maximum of two 3-D points per element -// -inline const Point3 maxPerElem( const Point3 & pnt0, const Point3 & pnt1 ); +// +inline const Point3 maxPerElem(const Point3 &pnt0, const Point3 &pnt1); // Minimum of two 3-D points per element -// -inline const Point3 minPerElem( const Point3 & pnt0, const Point3 & pnt1 ); +// +inline const Point3 minPerElem(const Point3 &pnt0, const Point3 &pnt1); // Maximum element of a 3-D point -// -inline float maxElem( const Point3 & pnt ); +// +inline float maxElem(const Point3 &pnt); // Minimum element of a 3-D point -// -inline float minElem( const Point3 & pnt ); +// +inline float minElem(const Point3 &pnt); // Compute the sum of all elements of a 3-D point -// -inline float sum( const Point3 & pnt ); +// +inline float sum(const Point3 &pnt); // Apply uniform scale to a 3-D point -// -inline const Point3 scale( const Point3 & pnt, float scaleVal ); +// +inline const Point3 scale(const Point3 &pnt, float scaleVal); // Apply non-uniform scale to a 3-D point -// -inline const Point3 scale( const Point3 & pnt, const Vector3 & scaleVec ); +// +inline const Point3 scale(const Point3 &pnt, const Vector3 &scaleVec); // Scalar projection of a 3-D point on a unit-length 3-D vector -// -inline float projection( const Point3 & pnt, const Vector3 & unitVec ); +// +inline float projection(const Point3 &pnt, const Vector3 &unitVec); // Compute the square of the distance of a 3-D point from the coordinate-system origin -// -inline float distSqrFromOrigin( const Point3 & pnt ); +// +inline float distSqrFromOrigin(const Point3 &pnt); // Compute the distance of a 3-D point from the coordinate-system origin -// -inline float distFromOrigin( const Point3 & pnt ); +// +inline float distFromOrigin(const Point3 &pnt); // Compute the square of the distance between two 3-D points -// -inline float distSqr( const Point3 & pnt0, const Point3 & pnt1 ); +// +inline float distSqr(const Point3 &pnt0, const Point3 &pnt1); // Compute the distance between two 3-D points -// -inline float dist( const Point3 & pnt0, const Point3 & pnt1 ); +// +inline float dist(const Point3 &pnt0, const Point3 &pnt1); // Linear interpolation between two 3-D points -// NOTE: +// NOTE: // Does not clamp t between 0 and 1. -// -inline const Point3 lerp( float t, const Point3 & pnt0, const Point3 & pnt1 ); +// +inline const Point3 lerp(float t, const Point3 &pnt0, const Point3 &pnt1); // Conditionally select between two 3-D points -// -inline const Point3 select( const Point3 & pnt0, const Point3 & pnt1, bool select1 ); +// +inline const Point3 select(const Point3 &pnt0, const Point3 &pnt1, bool select1); // Load x, y, and z elements from the first three words of a float array. -// -// -inline void loadXYZ( Point3 & pnt, const float * fptr ); +// +// +inline void loadXYZ(Point3 &pnt, const float *fptr); // Store x, y, and z elements of a 3-D point in the first three words of a float array. // Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed -// -inline void storeXYZ( const Point3 & pnt, float * fptr ); +// +inline void storeXYZ(const Point3 &pnt, float *fptr); // Load three-half-floats as a 3-D point -// NOTE: +// NOTE: // This transformation does not support either denormalized numbers or NaNs. -// -inline void loadHalfFloats( Point3 & pnt, const unsigned short * hfptr ); +// +inline void loadHalfFloats(Point3 &pnt, const unsigned short *hfptr); // Store a 3-D point as half-floats. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. -// NOTE: +// NOTE: // This transformation does not support either denormalized numbers or NaNs. Memory area of previous 16 bytes and next 32 bytes from hfptr might be accessed. -// -inline void storeHalfFloats( const Point3 & pnt, unsigned short * hfptr ); +// +inline void storeHalfFloats(const Point3 &pnt, unsigned short *hfptr); #ifdef _VECTORMATH_DEBUG // Print a 3-D point -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Point3 & pnt ); +// +inline void print(const Point3 &pnt); // Print a 3-D point and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Point3 & pnt, const char * name ); +// +inline void print(const Point3 &pnt, const char *name); #endif @@ -865,252 +865,252 @@ inline void print( const Point3 & pnt, const char * name ); // class Quat { - float mX; - float mY; - float mZ; - float mW; + float mX; + float mY; + float mZ; + float mW; public: - // Default constructor; does no initialization - // - inline Quat( ) { }; + // Default constructor; does no initialization + // + inline Quat(){}; - // Copy a quaternion - // - inline Quat( const Quat & quat ); + // Copy a quaternion + // + inline Quat(const Quat &quat); - // Construct a quaternion from x, y, z, and w elements - // - inline Quat( float x, float y, float z, float w ); + // Construct a quaternion from x, y, z, and w elements + // + inline Quat(float x, float y, float z, float w); - // Construct a quaternion from a 3-D vector and a scalar - // - inline Quat( const Vector3 & xyz, float w ); + // Construct a quaternion from a 3-D vector and a scalar + // + inline Quat(const Vector3 &xyz, float w); - // Copy elements from a 4-D vector into a quaternion - // - explicit inline Quat( const Vector4 & vec ); + // Copy elements from a 4-D vector into a quaternion + // + explicit inline Quat(const Vector4 &vec); - // Convert a rotation matrix to a unit-length quaternion - // - explicit inline Quat( const Matrix3 & rotMat ); + // Convert a rotation matrix to a unit-length quaternion + // + explicit inline Quat(const Matrix3 &rotMat); - // Set all elements of a quaternion to the same scalar value - // - explicit inline Quat( float scalar ); + // Set all elements of a quaternion to the same scalar value + // + explicit inline Quat(float scalar); - // Assign one quaternion to another - // - inline Quat & operator =( const Quat & quat ); + // Assign one quaternion to another + // + inline Quat &operator=(const Quat &quat); - // Set the x, y, and z elements of a quaternion - // NOTE: - // This function does not change the w element. - // - inline Quat & setXYZ( const Vector3 & vec ); + // Set the x, y, and z elements of a quaternion + // NOTE: + // This function does not change the w element. + // + inline Quat &setXYZ(const Vector3 &vec); - // Get the x, y, and z elements of a quaternion - // - inline const Vector3 getXYZ( ) const; + // Get the x, y, and z elements of a quaternion + // + inline const Vector3 getXYZ() const; - // Set the x element of a quaternion - // - inline Quat & setX( float x ); + // Set the x element of a quaternion + // + inline Quat &setX(float x); - // Set the y element of a quaternion - // - inline Quat & setY( float y ); + // Set the y element of a quaternion + // + inline Quat &setY(float y); - // Set the z element of a quaternion - // - inline Quat & setZ( float z ); + // Set the z element of a quaternion + // + inline Quat &setZ(float z); - // Set the w element of a quaternion - // - inline Quat & setW( float w ); + // Set the w element of a quaternion + // + inline Quat &setW(float w); - // Get the x element of a quaternion - // - inline float getX( ) const; + // Get the x element of a quaternion + // + inline float getX() const; - // Get the y element of a quaternion - // - inline float getY( ) const; + // Get the y element of a quaternion + // + inline float getY() const; - // Get the z element of a quaternion - // - inline float getZ( ) const; + // Get the z element of a quaternion + // + inline float getZ() const; - // Get the w element of a quaternion - // - inline float getW( ) const; + // Get the w element of a quaternion + // + inline float getW() const; - // Set an x, y, z, or w element of a quaternion by index - // - inline Quat & setElem( int idx, float value ); + // Set an x, y, z, or w element of a quaternion by index + // + inline Quat &setElem(int idx, float value); - // Get an x, y, z, or w element of a quaternion by index - // - inline float getElem( int idx ) const; + // Get an x, y, z, or w element of a quaternion by index + // + inline float getElem(int idx) const; - // Subscripting operator to set or get an element - // - inline float & operator []( int idx ); + // Subscripting operator to set or get an element + // + inline float &operator[](int idx); - // Subscripting operator to get an element - // - inline float operator []( int idx ) const; + // Subscripting operator to get an element + // + inline float operator[](int idx) const; - // Add two quaternions - // - inline const Quat operator +( const Quat & quat ) const; + // Add two quaternions + // + inline const Quat operator+(const Quat &quat) const; - // Subtract a quaternion from another quaternion - // - inline const Quat operator -( const Quat & quat ) const; + // Subtract a quaternion from another quaternion + // + inline const Quat operator-(const Quat &quat) const; - // Multiply two quaternions - // - inline const Quat operator *( const Quat & quat ) const; + // Multiply two quaternions + // + inline const Quat operator*(const Quat &quat) const; - // Multiply a quaternion by a scalar - // - inline const Quat operator *( float scalar ) const; + // Multiply a quaternion by a scalar + // + inline const Quat operator*(float scalar) const; - // Divide a quaternion by a scalar - // - inline const Quat operator /( float scalar ) const; + // Divide a quaternion by a scalar + // + inline const Quat operator/(float scalar) const; - // Perform compound assignment and addition with a quaternion - // - inline Quat & operator +=( const Quat & quat ); + // Perform compound assignment and addition with a quaternion + // + inline Quat &operator+=(const Quat &quat); - // Perform compound assignment and subtraction by a quaternion - // - inline Quat & operator -=( const Quat & quat ); + // Perform compound assignment and subtraction by a quaternion + // + inline Quat &operator-=(const Quat &quat); - // Perform compound assignment and multiplication by a quaternion - // - inline Quat & operator *=( const Quat & quat ); + // Perform compound assignment and multiplication by a quaternion + // + inline Quat &operator*=(const Quat &quat); - // Perform compound assignment and multiplication by a scalar - // - inline Quat & operator *=( float scalar ); + // Perform compound assignment and multiplication by a scalar + // + inline Quat &operator*=(float scalar); - // Perform compound assignment and division by a scalar - // - inline Quat & operator /=( float scalar ); + // Perform compound assignment and division by a scalar + // + inline Quat &operator/=(float scalar); - // Negate all elements of a quaternion - // - inline const Quat operator -( ) const; + // Negate all elements of a quaternion + // + inline const Quat operator-() const; - // Construct an identity quaternion - // - static inline const Quat identity( ); + // Construct an identity quaternion + // + static inline const Quat identity(); - // Construct a quaternion to rotate between two unit-length 3-D vectors - // NOTE: - // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. - // - static inline const Quat rotation( const Vector3 & unitVec0, const Vector3 & unitVec1 ); + // Construct a quaternion to rotate between two unit-length 3-D vectors + // NOTE: + // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. + // + static inline const Quat rotation(const Vector3 &unitVec0, const Vector3 &unitVec1); - // Construct a quaternion to rotate around a unit-length 3-D vector - // - static inline const Quat rotation( float radians, const Vector3 & unitVec ); + // Construct a quaternion to rotate around a unit-length 3-D vector + // + static inline const Quat rotation(float radians, const Vector3 &unitVec); - // Construct a quaternion to rotate around the x axis - // - static inline const Quat rotationX( float radians ); + // Construct a quaternion to rotate around the x axis + // + static inline const Quat rotationX(float radians); - // Construct a quaternion to rotate around the y axis - // - static inline const Quat rotationY( float radians ); + // Construct a quaternion to rotate around the y axis + // + static inline const Quat rotationY(float radians); - // Construct a quaternion to rotate around the z axis - // - static inline const Quat rotationZ( float radians ); + // Construct a quaternion to rotate around the z axis + // + static inline const Quat rotationZ(float radians); } #ifdef __GNUC__ -__attribute__ ((aligned(16))) +__attribute__((aligned(16))) #endif ; // Multiply a quaternion by a scalar -// -inline const Quat operator *( float scalar, const Quat & quat ); +// +inline const Quat operator*(float scalar, const Quat &quat); // Compute the conjugate of a quaternion -// -inline const Quat conj( const Quat & quat ); +// +inline const Quat conj(const Quat &quat); // Use a unit-length quaternion to rotate a 3-D vector -// -inline const Vector3 rotate( const Quat & unitQuat, const Vector3 & vec ); +// +inline const Vector3 rotate(const Quat &unitQuat, const Vector3 &vec); // Compute the dot product of two quaternions -// -inline float dot( const Quat & quat0, const Quat & quat1 ); +// +inline float dot(const Quat &quat0, const Quat &quat1); // Compute the norm of a quaternion -// -inline float norm( const Quat & quat ); +// +inline float norm(const Quat &quat); // Compute the length of a quaternion -// -inline float length( const Quat & quat ); +// +inline float length(const Quat &quat); // Normalize a quaternion -// NOTE: +// NOTE: // The result is unpredictable when all elements of quat are at or near zero. -// -inline const Quat normalize( const Quat & quat ); +// +inline const Quat normalize(const Quat &quat); // Linear interpolation between two quaternions -// NOTE: +// NOTE: // Does not clamp t between 0 and 1. -// -inline const Quat lerp( float t, const Quat & quat0, const Quat & quat1 ); +// +inline const Quat lerp(float t, const Quat &quat0, const Quat &quat1); // Spherical linear interpolation between two quaternions -// NOTE: +// NOTE: // Interpolates along the shortest path between orientations. // Does not clamp t between 0 and 1. -// -inline const Quat slerp( float t, const Quat & unitQuat0, const Quat & unitQuat1 ); +// +inline const Quat slerp(float t, const Quat &unitQuat0, const Quat &unitQuat1); // Spherical quadrangle interpolation -// -inline const Quat squad( float t, const Quat & unitQuat0, const Quat & unitQuat1, const Quat & unitQuat2, const Quat & unitQuat3 ); +// +inline const Quat squad(float t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3); // Conditionally select between two quaternions -// -inline const Quat select( const Quat & quat0, const Quat & quat1, bool select1 ); +// +inline const Quat select(const Quat &quat0, const Quat &quat1, bool select1); // Load x, y, z, and w elements from the first four words of a float array. -// -// -inline void loadXYZW( Quat & quat, const float * fptr ); +// +// +inline void loadXYZW(Quat &quat, const float *fptr); // Store x, y, z, and w elements of a quaternion in the first four words of a float array. // Memory area of previous 16 bytes and next 32 bytes from fptr might be accessed -// -inline void storeXYZW( const Quat & quat, float * fptr ); +// +inline void storeXYZW(const Quat &quat, float *fptr); #ifdef _VECTORMATH_DEBUG // Print a quaternion -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Quat & quat ); +// +inline void print(const Quat &quat); // Print a quaternion and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Quat & quat, const char * name ); +// +inline void print(const Quat &quat, const char *name); #endif @@ -1118,219 +1118,218 @@ inline void print( const Quat & quat, const char * name ); // class Matrix3 { - Vector3 mCol0; - Vector3 mCol1; - Vector3 mCol2; + Vector3 mCol0; + Vector3 mCol1; + Vector3 mCol2; public: - // Default constructor; does no initialization - // - inline Matrix3( ) { }; + // Default constructor; does no initialization + // + inline Matrix3(){}; - // Copy a 3x3 matrix - // - inline Matrix3( const Matrix3 & mat ); + // Copy a 3x3 matrix + // + inline Matrix3(const Matrix3 &mat); - // Construct a 3x3 matrix containing the specified columns - // - inline Matrix3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2 ); + // Construct a 3x3 matrix containing the specified columns + // + inline Matrix3(const Vector3 &col0, const Vector3 &col1, const Vector3 &col2); - // Construct a 3x3 rotation matrix from a unit-length quaternion - // - explicit inline Matrix3( const Quat & unitQuat ); + // Construct a 3x3 rotation matrix from a unit-length quaternion + // + explicit inline Matrix3(const Quat &unitQuat); - // Set all elements of a 3x3 matrix to the same scalar value - // - explicit inline Matrix3( float scalar ); + // Set all elements of a 3x3 matrix to the same scalar value + // + explicit inline Matrix3(float scalar); - // Assign one 3x3 matrix to another - // - inline Matrix3 & operator =( const Matrix3 & mat ); + // Assign one 3x3 matrix to another + // + inline Matrix3 &operator=(const Matrix3 &mat); - // Set column 0 of a 3x3 matrix - // - inline Matrix3 & setCol0( const Vector3 & col0 ); + // Set column 0 of a 3x3 matrix + // + inline Matrix3 &setCol0(const Vector3 &col0); - // Set column 1 of a 3x3 matrix - // - inline Matrix3 & setCol1( const Vector3 & col1 ); + // Set column 1 of a 3x3 matrix + // + inline Matrix3 &setCol1(const Vector3 &col1); - // Set column 2 of a 3x3 matrix - // - inline Matrix3 & setCol2( const Vector3 & col2 ); + // Set column 2 of a 3x3 matrix + // + inline Matrix3 &setCol2(const Vector3 &col2); - // Get column 0 of a 3x3 matrix - // - inline const Vector3 getCol0( ) const; + // Get column 0 of a 3x3 matrix + // + inline const Vector3 getCol0() const; - // Get column 1 of a 3x3 matrix - // - inline const Vector3 getCol1( ) const; + // Get column 1 of a 3x3 matrix + // + inline const Vector3 getCol1() const; - // Get column 2 of a 3x3 matrix - // - inline const Vector3 getCol2( ) const; + // Get column 2 of a 3x3 matrix + // + inline const Vector3 getCol2() const; - // Set the column of a 3x3 matrix referred to by the specified index - // - inline Matrix3 & setCol( int col, const Vector3 & vec ); + // Set the column of a 3x3 matrix referred to by the specified index + // + inline Matrix3 &setCol(int col, const Vector3 &vec); - // Set the row of a 3x3 matrix referred to by the specified index - // - inline Matrix3 & setRow( int row, const Vector3 & vec ); + // Set the row of a 3x3 matrix referred to by the specified index + // + inline Matrix3 &setRow(int row, const Vector3 &vec); - // Get the column of a 3x3 matrix referred to by the specified index - // - inline const Vector3 getCol( int col ) const; + // Get the column of a 3x3 matrix referred to by the specified index + // + inline const Vector3 getCol(int col) const; - // Get the row of a 3x3 matrix referred to by the specified index - // - inline const Vector3 getRow( int row ) const; + // Get the row of a 3x3 matrix referred to by the specified index + // + inline const Vector3 getRow(int row) const; - // Subscripting operator to set or get a column - // - inline Vector3 & operator []( int col ); + // Subscripting operator to set or get a column + // + inline Vector3 &operator[](int col); - // Subscripting operator to get a column - // - inline const Vector3 operator []( int col ) const; + // Subscripting operator to get a column + // + inline const Vector3 operator[](int col) const; - // Set the element of a 3x3 matrix referred to by column and row indices - // - inline Matrix3 & setElem( int col, int row, float val ); + // Set the element of a 3x3 matrix referred to by column and row indices + // + inline Matrix3 &setElem(int col, int row, float val); - // Get the element of a 3x3 matrix referred to by column and row indices - // - inline float getElem( int col, int row ) const; + // Get the element of a 3x3 matrix referred to by column and row indices + // + inline float getElem(int col, int row) const; - // Add two 3x3 matrices - // - inline const Matrix3 operator +( const Matrix3 & mat ) const; + // Add two 3x3 matrices + // + inline const Matrix3 operator+(const Matrix3 &mat) const; - // Subtract a 3x3 matrix from another 3x3 matrix - // - inline const Matrix3 operator -( const Matrix3 & mat ) const; + // Subtract a 3x3 matrix from another 3x3 matrix + // + inline const Matrix3 operator-(const Matrix3 &mat) const; - // Negate all elements of a 3x3 matrix - // - inline const Matrix3 operator -( ) const; + // Negate all elements of a 3x3 matrix + // + inline const Matrix3 operator-() const; - // Multiply a 3x3 matrix by a scalar - // - inline const Matrix3 operator *( float scalar ) const; + // Multiply a 3x3 matrix by a scalar + // + inline const Matrix3 operator*(float scalar) const; - // Multiply a 3x3 matrix by a 3-D vector - // - inline const Vector3 operator *( const Vector3 & vec ) const; + // Multiply a 3x3 matrix by a 3-D vector + // + inline const Vector3 operator*(const Vector3 &vec) const; - // Multiply two 3x3 matrices - // - inline const Matrix3 operator *( const Matrix3 & mat ) const; + // Multiply two 3x3 matrices + // + inline const Matrix3 operator*(const Matrix3 &mat) const; - // Perform compound assignment and addition with a 3x3 matrix - // - inline Matrix3 & operator +=( const Matrix3 & mat ); + // Perform compound assignment and addition with a 3x3 matrix + // + inline Matrix3 &operator+=(const Matrix3 &mat); - // Perform compound assignment and subtraction by a 3x3 matrix - // - inline Matrix3 & operator -=( const Matrix3 & mat ); + // Perform compound assignment and subtraction by a 3x3 matrix + // + inline Matrix3 &operator-=(const Matrix3 &mat); - // Perform compound assignment and multiplication by a scalar - // - inline Matrix3 & operator *=( float scalar ); + // Perform compound assignment and multiplication by a scalar + // + inline Matrix3 &operator*=(float scalar); - // Perform compound assignment and multiplication by a 3x3 matrix - // - inline Matrix3 & operator *=( const Matrix3 & mat ); + // Perform compound assignment and multiplication by a 3x3 matrix + // + inline Matrix3 &operator*=(const Matrix3 &mat); - // Construct an identity 3x3 matrix - // - static inline const Matrix3 identity( ); + // Construct an identity 3x3 matrix + // + static inline const Matrix3 identity(); - // Construct a 3x3 matrix to rotate around the x axis - // - static inline const Matrix3 rotationX( float radians ); + // Construct a 3x3 matrix to rotate around the x axis + // + static inline const Matrix3 rotationX(float radians); - // Construct a 3x3 matrix to rotate around the y axis - // - static inline const Matrix3 rotationY( float radians ); + // Construct a 3x3 matrix to rotate around the y axis + // + static inline const Matrix3 rotationY(float radians); - // Construct a 3x3 matrix to rotate around the z axis - // - static inline const Matrix3 rotationZ( float radians ); + // Construct a 3x3 matrix to rotate around the z axis + // + static inline const Matrix3 rotationZ(float radians); - // Construct a 3x3 matrix to rotate around the x, y, and z axes - // - static inline const Matrix3 rotationZYX( const Vector3 & radiansXYZ ); + // Construct a 3x3 matrix to rotate around the x, y, and z axes + // + static inline const Matrix3 rotationZYX(const Vector3 &radiansXYZ); - // Construct a 3x3 matrix to rotate around a unit-length 3-D vector - // - static inline const Matrix3 rotation( float radians, const Vector3 & unitVec ); + // Construct a 3x3 matrix to rotate around a unit-length 3-D vector + // + static inline const Matrix3 rotation(float radians, const Vector3 &unitVec); - // Construct a rotation matrix from a unit-length quaternion - // - static inline const Matrix3 rotation( const Quat & unitQuat ); - - // Construct a 3x3 matrix to perform scaling - // - static inline const Matrix3 scale( const Vector3 & scaleVec ); + // Construct a rotation matrix from a unit-length quaternion + // + static inline const Matrix3 rotation(const Quat &unitQuat); + // Construct a 3x3 matrix to perform scaling + // + static inline const Matrix3 scale(const Vector3 &scaleVec); }; // Multiply a 3x3 matrix by a scalar -// -inline const Matrix3 operator *( float scalar, const Matrix3 & mat ); +// +inline const Matrix3 operator*(float scalar, const Matrix3 &mat); // Append (post-multiply) a scale transformation to a 3x3 matrix -// NOTE: +// NOTE: // Faster than creating and multiplying a scale transformation matrix. -// -inline const Matrix3 appendScale( const Matrix3 & mat, const Vector3 & scaleVec ); +// +inline const Matrix3 appendScale(const Matrix3 &mat, const Vector3 &scaleVec); // Prepend (pre-multiply) a scale transformation to a 3x3 matrix -// NOTE: +// NOTE: // Faster than creating and multiplying a scale transformation matrix. -// -inline const Matrix3 prependScale( const Vector3 & scaleVec, const Matrix3 & mat ); +// +inline const Matrix3 prependScale(const Vector3 &scaleVec, const Matrix3 &mat); // Multiply two 3x3 matrices per element -// -inline const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ); +// +inline const Matrix3 mulPerElem(const Matrix3 &mat0, const Matrix3 &mat1); // Compute the absolute value of a 3x3 matrix per element -// -inline const Matrix3 absPerElem( const Matrix3 & mat ); +// +inline const Matrix3 absPerElem(const Matrix3 &mat); // Transpose of a 3x3 matrix -// -inline const Matrix3 transpose( const Matrix3 & mat ); +// +inline const Matrix3 transpose(const Matrix3 &mat); // Compute the inverse of a 3x3 matrix -// NOTE: +// NOTE: // Result is unpredictable when the determinant of mat is equal to or near 0. -// -inline const Matrix3 inverse( const Matrix3 & mat ); +// +inline const Matrix3 inverse(const Matrix3 &mat); // Determinant of a 3x3 matrix -// -inline float determinant( const Matrix3 & mat ); +// +inline float determinant(const Matrix3 &mat); // Conditionally select between two 3x3 matrices -// -inline const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ); +// +inline const Matrix3 select(const Matrix3 &mat0, const Matrix3 &mat1, bool select1); #ifdef _VECTORMATH_DEBUG // Print a 3x3 matrix -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Matrix3 & mat ); +// +inline void print(const Matrix3 &mat); // Print a 3x3 matrix and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Matrix3 & mat, const char * name ); +// +inline void print(const Matrix3 &mat, const char *name); #endif @@ -1338,304 +1337,303 @@ inline void print( const Matrix3 & mat, const char * name ); // class Matrix4 { - Vector4 mCol0; - Vector4 mCol1; - Vector4 mCol2; - Vector4 mCol3; + Vector4 mCol0; + Vector4 mCol1; + Vector4 mCol2; + Vector4 mCol3; public: - // Default constructor; does no initialization - // - inline Matrix4( ) { }; + // Default constructor; does no initialization + // + inline Matrix4(){}; - // Copy a 4x4 matrix - // - inline Matrix4( const Matrix4 & mat ); + // Copy a 4x4 matrix + // + inline Matrix4(const Matrix4 &mat); - // Construct a 4x4 matrix containing the specified columns - // - inline Matrix4( const Vector4 & col0, const Vector4 & col1, const Vector4 & col2, const Vector4 & col3 ); + // Construct a 4x4 matrix containing the specified columns + // + inline Matrix4(const Vector4 &col0, const Vector4 &col1, const Vector4 &col2, const Vector4 &col3); - // Construct a 4x4 matrix from a 3x4 transformation matrix - // - explicit inline Matrix4( const Transform3 & mat ); + // Construct a 4x4 matrix from a 3x4 transformation matrix + // + explicit inline Matrix4(const Transform3 &mat); - // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector - // - inline Matrix4( const Matrix3 & mat, const Vector3 & translateVec ); + // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector + // + inline Matrix4(const Matrix3 &mat, const Vector3 &translateVec); - // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector - // - inline Matrix4( const Quat & unitQuat, const Vector3 & translateVec ); + // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector + // + inline Matrix4(const Quat &unitQuat, const Vector3 &translateVec); - // Set all elements of a 4x4 matrix to the same scalar value - // - explicit inline Matrix4( float scalar ); + // Set all elements of a 4x4 matrix to the same scalar value + // + explicit inline Matrix4(float scalar); - // Assign one 4x4 matrix to another - // - inline Matrix4 & operator =( const Matrix4 & mat ); + // Assign one 4x4 matrix to another + // + inline Matrix4 &operator=(const Matrix4 &mat); - // Set the upper-left 3x3 submatrix - // NOTE: - // This function does not change the bottom row elements. - // - inline Matrix4 & setUpper3x3( const Matrix3 & mat3 ); + // Set the upper-left 3x3 submatrix + // NOTE: + // This function does not change the bottom row elements. + // + inline Matrix4 &setUpper3x3(const Matrix3 &mat3); - // Get the upper-left 3x3 submatrix of a 4x4 matrix - // - inline const Matrix3 getUpper3x3( ) const; + // Get the upper-left 3x3 submatrix of a 4x4 matrix + // + inline const Matrix3 getUpper3x3() const; - // Set translation component - // NOTE: - // This function does not change the bottom row elements. - // - inline Matrix4 & setTranslation( const Vector3 & translateVec ); + // Set translation component + // NOTE: + // This function does not change the bottom row elements. + // + inline Matrix4 &setTranslation(const Vector3 &translateVec); - // Get the translation component of a 4x4 matrix - // - inline const Vector3 getTranslation( ) const; + // Get the translation component of a 4x4 matrix + // + inline const Vector3 getTranslation() const; - // Set column 0 of a 4x4 matrix - // - inline Matrix4 & setCol0( const Vector4 & col0 ); + // Set column 0 of a 4x4 matrix + // + inline Matrix4 &setCol0(const Vector4 &col0); - // Set column 1 of a 4x4 matrix - // - inline Matrix4 & setCol1( const Vector4 & col1 ); + // Set column 1 of a 4x4 matrix + // + inline Matrix4 &setCol1(const Vector4 &col1); - // Set column 2 of a 4x4 matrix - // - inline Matrix4 & setCol2( const Vector4 & col2 ); + // Set column 2 of a 4x4 matrix + // + inline Matrix4 &setCol2(const Vector4 &col2); - // Set column 3 of a 4x4 matrix - // - inline Matrix4 & setCol3( const Vector4 & col3 ); + // Set column 3 of a 4x4 matrix + // + inline Matrix4 &setCol3(const Vector4 &col3); - // Get column 0 of a 4x4 matrix - // - inline const Vector4 getCol0( ) const; + // Get column 0 of a 4x4 matrix + // + inline const Vector4 getCol0() const; - // Get column 1 of a 4x4 matrix - // - inline const Vector4 getCol1( ) const; + // Get column 1 of a 4x4 matrix + // + inline const Vector4 getCol1() const; - // Get column 2 of a 4x4 matrix - // - inline const Vector4 getCol2( ) const; + // Get column 2 of a 4x4 matrix + // + inline const Vector4 getCol2() const; - // Get column 3 of a 4x4 matrix - // - inline const Vector4 getCol3( ) const; + // Get column 3 of a 4x4 matrix + // + inline const Vector4 getCol3() const; - // Set the column of a 4x4 matrix referred to by the specified index - // - inline Matrix4 & setCol( int col, const Vector4 & vec ); + // Set the column of a 4x4 matrix referred to by the specified index + // + inline Matrix4 &setCol(int col, const Vector4 &vec); - // Set the row of a 4x4 matrix referred to by the specified index - // - inline Matrix4 & setRow( int row, const Vector4 & vec ); + // Set the row of a 4x4 matrix referred to by the specified index + // + inline Matrix4 &setRow(int row, const Vector4 &vec); - // Get the column of a 4x4 matrix referred to by the specified index - // - inline const Vector4 getCol( int col ) const; + // Get the column of a 4x4 matrix referred to by the specified index + // + inline const Vector4 getCol(int col) const; - // Get the row of a 4x4 matrix referred to by the specified index - // - inline const Vector4 getRow( int row ) const; + // Get the row of a 4x4 matrix referred to by the specified index + // + inline const Vector4 getRow(int row) const; - // Subscripting operator to set or get a column - // - inline Vector4 & operator []( int col ); + // Subscripting operator to set or get a column + // + inline Vector4 &operator[](int col); - // Subscripting operator to get a column - // - inline const Vector4 operator []( int col ) const; + // Subscripting operator to get a column + // + inline const Vector4 operator[](int col) const; - // Set the element of a 4x4 matrix referred to by column and row indices - // - inline Matrix4 & setElem( int col, int row, float val ); + // Set the element of a 4x4 matrix referred to by column and row indices + // + inline Matrix4 &setElem(int col, int row, float val); - // Get the element of a 4x4 matrix referred to by column and row indices - // - inline float getElem( int col, int row ) const; + // Get the element of a 4x4 matrix referred to by column and row indices + // + inline float getElem(int col, int row) const; - // Add two 4x4 matrices - // - inline const Matrix4 operator +( const Matrix4 & mat ) const; + // Add two 4x4 matrices + // + inline const Matrix4 operator+(const Matrix4 &mat) const; - // Subtract a 4x4 matrix from another 4x4 matrix - // - inline const Matrix4 operator -( const Matrix4 & mat ) const; + // Subtract a 4x4 matrix from another 4x4 matrix + // + inline const Matrix4 operator-(const Matrix4 &mat) const; - // Negate all elements of a 4x4 matrix - // - inline const Matrix4 operator -( ) const; + // Negate all elements of a 4x4 matrix + // + inline const Matrix4 operator-() const; - // Multiply a 4x4 matrix by a scalar - // - inline const Matrix4 operator *( float scalar ) const; + // Multiply a 4x4 matrix by a scalar + // + inline const Matrix4 operator*(float scalar) const; - // Multiply a 4x4 matrix by a 4-D vector - // - inline const Vector4 operator *( const Vector4 & vec ) const; + // Multiply a 4x4 matrix by a 4-D vector + // + inline const Vector4 operator*(const Vector4 &vec) const; - // Multiply a 4x4 matrix by a 3-D vector - // - inline const Vector4 operator *( const Vector3 & vec ) const; + // Multiply a 4x4 matrix by a 3-D vector + // + inline const Vector4 operator*(const Vector3 &vec) const; - // Multiply a 4x4 matrix by a 3-D point - // - inline const Vector4 operator *( const Point3 & pnt ) const; + // Multiply a 4x4 matrix by a 3-D point + // + inline const Vector4 operator*(const Point3 &pnt) const; - // Multiply two 4x4 matrices - // - inline const Matrix4 operator *( const Matrix4 & mat ) const; + // Multiply two 4x4 matrices + // + inline const Matrix4 operator*(const Matrix4 &mat) const; - // Multiply a 4x4 matrix by a 3x4 transformation matrix - // - inline const Matrix4 operator *( const Transform3 & tfrm ) const; + // Multiply a 4x4 matrix by a 3x4 transformation matrix + // + inline const Matrix4 operator*(const Transform3 &tfrm) const; - // Perform compound assignment and addition with a 4x4 matrix - // - inline Matrix4 & operator +=( const Matrix4 & mat ); + // Perform compound assignment and addition with a 4x4 matrix + // + inline Matrix4 &operator+=(const Matrix4 &mat); - // Perform compound assignment and subtraction by a 4x4 matrix - // - inline Matrix4 & operator -=( const Matrix4 & mat ); + // Perform compound assignment and subtraction by a 4x4 matrix + // + inline Matrix4 &operator-=(const Matrix4 &mat); - // Perform compound assignment and multiplication by a scalar - // - inline Matrix4 & operator *=( float scalar ); + // Perform compound assignment and multiplication by a scalar + // + inline Matrix4 &operator*=(float scalar); - // Perform compound assignment and multiplication by a 4x4 matrix - // - inline Matrix4 & operator *=( const Matrix4 & mat ); + // Perform compound assignment and multiplication by a 4x4 matrix + // + inline Matrix4 &operator*=(const Matrix4 &mat); - // Perform compound assignment and multiplication by a 3x4 transformation matrix - // - inline Matrix4 & operator *=( const Transform3 & tfrm ); + // Perform compound assignment and multiplication by a 3x4 transformation matrix + // + inline Matrix4 &operator*=(const Transform3 &tfrm); - // Construct an identity 4x4 matrix - // - static inline const Matrix4 identity( ); + // Construct an identity 4x4 matrix + // + static inline const Matrix4 identity(); - // Construct a 4x4 matrix to rotate around the x axis - // - static inline const Matrix4 rotationX( float radians ); + // Construct a 4x4 matrix to rotate around the x axis + // + static inline const Matrix4 rotationX(float radians); - // Construct a 4x4 matrix to rotate around the y axis - // - static inline const Matrix4 rotationY( float radians ); + // Construct a 4x4 matrix to rotate around the y axis + // + static inline const Matrix4 rotationY(float radians); - // Construct a 4x4 matrix to rotate around the z axis - // - static inline const Matrix4 rotationZ( float radians ); + // Construct a 4x4 matrix to rotate around the z axis + // + static inline const Matrix4 rotationZ(float radians); - // Construct a 4x4 matrix to rotate around the x, y, and z axes - // - static inline const Matrix4 rotationZYX( const Vector3 & radiansXYZ ); + // Construct a 4x4 matrix to rotate around the x, y, and z axes + // + static inline const Matrix4 rotationZYX(const Vector3 &radiansXYZ); - // Construct a 4x4 matrix to rotate around a unit-length 3-D vector - // - static inline const Matrix4 rotation( float radians, const Vector3 & unitVec ); + // Construct a 4x4 matrix to rotate around a unit-length 3-D vector + // + static inline const Matrix4 rotation(float radians, const Vector3 &unitVec); - // Construct a rotation matrix from a unit-length quaternion - // - static inline const Matrix4 rotation( const Quat & unitQuat ); + // Construct a rotation matrix from a unit-length quaternion + // + static inline const Matrix4 rotation(const Quat &unitQuat); - // Construct a 4x4 matrix to perform scaling - // - static inline const Matrix4 scale( const Vector3 & scaleVec ); + // Construct a 4x4 matrix to perform scaling + // + static inline const Matrix4 scale(const Vector3 &scaleVec); - // Construct a 4x4 matrix to perform translation - // - static inline const Matrix4 translation( const Vector3 & translateVec ); + // Construct a 4x4 matrix to perform translation + // + static inline const Matrix4 translation(const Vector3 &translateVec); - // Construct viewing matrix based on eye position, position looked at, and up direction - // - static inline const Matrix4 lookAt( const Point3 & eyePos, const Point3 & lookAtPos, const Vector3 & upVec ); + // Construct viewing matrix based on eye position, position looked at, and up direction + // + static inline const Matrix4 lookAt(const Point3 &eyePos, const Point3 &lookAtPos, const Vector3 &upVec); - // Construct a perspective projection matrix - // - static inline const Matrix4 perspective( float fovyRadians, float aspect, float zNear, float zFar ); + // Construct a perspective projection matrix + // + static inline const Matrix4 perspective(float fovyRadians, float aspect, float zNear, float zFar); - // Construct a perspective projection matrix based on frustum - // - static inline const Matrix4 frustum( float left, float right, float bottom, float top, float zNear, float zFar ); - - // Construct an orthographic projection matrix - // - static inline const Matrix4 orthographic( float left, float right, float bottom, float top, float zNear, float zFar ); + // Construct a perspective projection matrix based on frustum + // + static inline const Matrix4 frustum(float left, float right, float bottom, float top, float zNear, float zFar); + // Construct an orthographic projection matrix + // + static inline const Matrix4 orthographic(float left, float right, float bottom, float top, float zNear, float zFar); }; // Multiply a 4x4 matrix by a scalar -// -inline const Matrix4 operator *( float scalar, const Matrix4 & mat ); +// +inline const Matrix4 operator*(float scalar, const Matrix4 &mat); // Append (post-multiply) a scale transformation to a 4x4 matrix -// NOTE: +// NOTE: // Faster than creating and multiplying a scale transformation matrix. -// -inline const Matrix4 appendScale( const Matrix4 & mat, const Vector3 & scaleVec ); +// +inline const Matrix4 appendScale(const Matrix4 &mat, const Vector3 &scaleVec); // Prepend (pre-multiply) a scale transformation to a 4x4 matrix -// NOTE: +// NOTE: // Faster than creating and multiplying a scale transformation matrix. -// -inline const Matrix4 prependScale( const Vector3 & scaleVec, const Matrix4 & mat ); +// +inline const Matrix4 prependScale(const Vector3 &scaleVec, const Matrix4 &mat); // Multiply two 4x4 matrices per element -// -inline const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ); +// +inline const Matrix4 mulPerElem(const Matrix4 &mat0, const Matrix4 &mat1); // Compute the absolute value of a 4x4 matrix per element -// -inline const Matrix4 absPerElem( const Matrix4 & mat ); +// +inline const Matrix4 absPerElem(const Matrix4 &mat); // Transpose of a 4x4 matrix -// -inline const Matrix4 transpose( const Matrix4 & mat ); +// +inline const Matrix4 transpose(const Matrix4 &mat); // Compute the inverse of a 4x4 matrix -// NOTE: +// NOTE: // Result is unpredictable when the determinant of mat is equal to or near 0. -// -inline const Matrix4 inverse( const Matrix4 & mat ); +// +inline const Matrix4 inverse(const Matrix4 &mat); // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix -// NOTE: +// NOTE: // This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. The result is unpredictable when the determinant of mat is equal to or near 0. -// -inline const Matrix4 affineInverse( const Matrix4 & mat ); +// +inline const Matrix4 affineInverse(const Matrix4 &mat); // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix -// NOTE: +// NOTE: // This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. -// -inline const Matrix4 orthoInverse( const Matrix4 & mat ); +// +inline const Matrix4 orthoInverse(const Matrix4 &mat); // Determinant of a 4x4 matrix -// -inline float determinant( const Matrix4 & mat ); +// +inline float determinant(const Matrix4 &mat); // Conditionally select between two 4x4 matrices -// -inline const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ); +// +inline const Matrix4 select(const Matrix4 &mat0, const Matrix4 &mat1, bool select1); #ifdef _VECTORMATH_DEBUG // Print a 4x4 matrix -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Matrix4 & mat ); +// +inline void print(const Matrix4 &mat); // Print a 4x4 matrix and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Matrix4 & mat, const char * name ); +// +inline void print(const Matrix4 &mat, const char *name); #endif @@ -1643,227 +1641,226 @@ inline void print( const Matrix4 & mat, const char * name ); // class Transform3 { - Vector3 mCol0; - Vector3 mCol1; - Vector3 mCol2; - Vector3 mCol3; + Vector3 mCol0; + Vector3 mCol1; + Vector3 mCol2; + Vector3 mCol3; public: - // Default constructor; does no initialization - // - inline Transform3( ) { }; + // Default constructor; does no initialization + // + inline Transform3(){}; - // Copy a 3x4 transformation matrix - // - inline Transform3( const Transform3 & tfrm ); + // Copy a 3x4 transformation matrix + // + inline Transform3(const Transform3 &tfrm); - // Construct a 3x4 transformation matrix containing the specified columns - // - inline Transform3( const Vector3 & col0, const Vector3 & col1, const Vector3 & col2, const Vector3 & col3 ); + // Construct a 3x4 transformation matrix containing the specified columns + // + inline Transform3(const Vector3 &col0, const Vector3 &col1, const Vector3 &col2, const Vector3 &col3); - // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector - // - inline Transform3( const Matrix3 & tfrm, const Vector3 & translateVec ); + // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector + // + inline Transform3(const Matrix3 &tfrm, const Vector3 &translateVec); - // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector - // - inline Transform3( const Quat & unitQuat, const Vector3 & translateVec ); + // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector + // + inline Transform3(const Quat &unitQuat, const Vector3 &translateVec); - // Set all elements of a 3x4 transformation matrix to the same scalar value - // - explicit inline Transform3( float scalar ); + // Set all elements of a 3x4 transformation matrix to the same scalar value + // + explicit inline Transform3(float scalar); - // Assign one 3x4 transformation matrix to another - // - inline Transform3 & operator =( const Transform3 & tfrm ); + // Assign one 3x4 transformation matrix to another + // + inline Transform3 &operator=(const Transform3 &tfrm); - // Set the upper-left 3x3 submatrix - // - inline Transform3 & setUpper3x3( const Matrix3 & mat3 ); + // Set the upper-left 3x3 submatrix + // + inline Transform3 &setUpper3x3(const Matrix3 &mat3); - // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix - // - inline const Matrix3 getUpper3x3( ) const; + // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix + // + inline const Matrix3 getUpper3x3() const; - // Set translation component - // - inline Transform3 & setTranslation( const Vector3 & translateVec ); + // Set translation component + // + inline Transform3 &setTranslation(const Vector3 &translateVec); - // Get the translation component of a 3x4 transformation matrix - // - inline const Vector3 getTranslation( ) const; + // Get the translation component of a 3x4 transformation matrix + // + inline const Vector3 getTranslation() const; - // Set column 0 of a 3x4 transformation matrix - // - inline Transform3 & setCol0( const Vector3 & col0 ); + // Set column 0 of a 3x4 transformation matrix + // + inline Transform3 &setCol0(const Vector3 &col0); - // Set column 1 of a 3x4 transformation matrix - // - inline Transform3 & setCol1( const Vector3 & col1 ); + // Set column 1 of a 3x4 transformation matrix + // + inline Transform3 &setCol1(const Vector3 &col1); - // Set column 2 of a 3x4 transformation matrix - // - inline Transform3 & setCol2( const Vector3 & col2 ); + // Set column 2 of a 3x4 transformation matrix + // + inline Transform3 &setCol2(const Vector3 &col2); - // Set column 3 of a 3x4 transformation matrix - // - inline Transform3 & setCol3( const Vector3 & col3 ); + // Set column 3 of a 3x4 transformation matrix + // + inline Transform3 &setCol3(const Vector3 &col3); - // Get column 0 of a 3x4 transformation matrix - // - inline const Vector3 getCol0( ) const; + // Get column 0 of a 3x4 transformation matrix + // + inline const Vector3 getCol0() const; - // Get column 1 of a 3x4 transformation matrix - // - inline const Vector3 getCol1( ) const; + // Get column 1 of a 3x4 transformation matrix + // + inline const Vector3 getCol1() const; - // Get column 2 of a 3x4 transformation matrix - // - inline const Vector3 getCol2( ) const; + // Get column 2 of a 3x4 transformation matrix + // + inline const Vector3 getCol2() const; - // Get column 3 of a 3x4 transformation matrix - // - inline const Vector3 getCol3( ) const; + // Get column 3 of a 3x4 transformation matrix + // + inline const Vector3 getCol3() const; - // Set the column of a 3x4 transformation matrix referred to by the specified index - // - inline Transform3 & setCol( int col, const Vector3 & vec ); + // Set the column of a 3x4 transformation matrix referred to by the specified index + // + inline Transform3 &setCol(int col, const Vector3 &vec); - // Set the row of a 3x4 transformation matrix referred to by the specified index - // - inline Transform3 & setRow( int row, const Vector4 & vec ); + // Set the row of a 3x4 transformation matrix referred to by the specified index + // + inline Transform3 &setRow(int row, const Vector4 &vec); - // Get the column of a 3x4 transformation matrix referred to by the specified index - // - inline const Vector3 getCol( int col ) const; + // Get the column of a 3x4 transformation matrix referred to by the specified index + // + inline const Vector3 getCol(int col) const; - // Get the row of a 3x4 transformation matrix referred to by the specified index - // - inline const Vector4 getRow( int row ) const; + // Get the row of a 3x4 transformation matrix referred to by the specified index + // + inline const Vector4 getRow(int row) const; - // Subscripting operator to set or get a column - // - inline Vector3 & operator []( int col ); + // Subscripting operator to set or get a column + // + inline Vector3 &operator[](int col); - // Subscripting operator to get a column - // - inline const Vector3 operator []( int col ) const; + // Subscripting operator to get a column + // + inline const Vector3 operator[](int col) const; - // Set the element of a 3x4 transformation matrix referred to by column and row indices - // - inline Transform3 & setElem( int col, int row, float val ); + // Set the element of a 3x4 transformation matrix referred to by column and row indices + // + inline Transform3 &setElem(int col, int row, float val); - // Get the element of a 3x4 transformation matrix referred to by column and row indices - // - inline float getElem( int col, int row ) const; + // Get the element of a 3x4 transformation matrix referred to by column and row indices + // + inline float getElem(int col, int row) const; - // Multiply a 3x4 transformation matrix by a 3-D vector - // - inline const Vector3 operator *( const Vector3 & vec ) const; + // Multiply a 3x4 transformation matrix by a 3-D vector + // + inline const Vector3 operator*(const Vector3 &vec) const; - // Multiply a 3x4 transformation matrix by a 3-D point - // - inline const Point3 operator *( const Point3 & pnt ) const; + // Multiply a 3x4 transformation matrix by a 3-D point + // + inline const Point3 operator*(const Point3 &pnt) const; - // Multiply two 3x4 transformation matrices - // - inline const Transform3 operator *( const Transform3 & tfrm ) const; + // Multiply two 3x4 transformation matrices + // + inline const Transform3 operator*(const Transform3 &tfrm) const; - // Perform compound assignment and multiplication by a 3x4 transformation matrix - // - inline Transform3 & operator *=( const Transform3 & tfrm ); + // Perform compound assignment and multiplication by a 3x4 transformation matrix + // + inline Transform3 &operator*=(const Transform3 &tfrm); - // Construct an identity 3x4 transformation matrix - // - static inline const Transform3 identity( ); + // Construct an identity 3x4 transformation matrix + // + static inline const Transform3 identity(); - // Construct a 3x4 transformation matrix to rotate around the x axis - // - static inline const Transform3 rotationX( float radians ); + // Construct a 3x4 transformation matrix to rotate around the x axis + // + static inline const Transform3 rotationX(float radians); - // Construct a 3x4 transformation matrix to rotate around the y axis - // - static inline const Transform3 rotationY( float radians ); + // Construct a 3x4 transformation matrix to rotate around the y axis + // + static inline const Transform3 rotationY(float radians); - // Construct a 3x4 transformation matrix to rotate around the z axis - // - static inline const Transform3 rotationZ( float radians ); + // Construct a 3x4 transformation matrix to rotate around the z axis + // + static inline const Transform3 rotationZ(float radians); - // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes - // - static inline const Transform3 rotationZYX( const Vector3 & radiansXYZ ); + // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes + // + static inline const Transform3 rotationZYX(const Vector3 &radiansXYZ); - // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector - // - static inline const Transform3 rotation( float radians, const Vector3 & unitVec ); + // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector + // + static inline const Transform3 rotation(float radians, const Vector3 &unitVec); - // Construct a rotation matrix from a unit-length quaternion - // - static inline const Transform3 rotation( const Quat & unitQuat ); + // Construct a rotation matrix from a unit-length quaternion + // + static inline const Transform3 rotation(const Quat &unitQuat); - // Construct a 3x4 transformation matrix to perform scaling - // - static inline const Transform3 scale( const Vector3 & scaleVec ); - - // Construct a 3x4 transformation matrix to perform translation - // - static inline const Transform3 translation( const Vector3 & translateVec ); + // Construct a 3x4 transformation matrix to perform scaling + // + static inline const Transform3 scale(const Vector3 &scaleVec); + // Construct a 3x4 transformation matrix to perform translation + // + static inline const Transform3 translation(const Vector3 &translateVec); }; // Append (post-multiply) a scale transformation to a 3x4 transformation matrix -// NOTE: +// NOTE: // Faster than creating and multiplying a scale transformation matrix. -// -inline const Transform3 appendScale( const Transform3 & tfrm, const Vector3 & scaleVec ); +// +inline const Transform3 appendScale(const Transform3 &tfrm, const Vector3 &scaleVec); // Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix -// NOTE: +// NOTE: // Faster than creating and multiplying a scale transformation matrix. -// -inline const Transform3 prependScale( const Vector3 & scaleVec, const Transform3 & tfrm ); +// +inline const Transform3 prependScale(const Vector3 &scaleVec, const Transform3 &tfrm); // Multiply two 3x4 transformation matrices per element -// -inline const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ); +// +inline const Transform3 mulPerElem(const Transform3 &tfrm0, const Transform3 &tfrm1); // Compute the absolute value of a 3x4 transformation matrix per element -// -inline const Transform3 absPerElem( const Transform3 & tfrm ); +// +inline const Transform3 absPerElem(const Transform3 &tfrm); // Inverse of a 3x4 transformation matrix -// NOTE: +// NOTE: // Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. -// -inline const Transform3 inverse( const Transform3 & tfrm ); +// +inline const Transform3 inverse(const Transform3 &tfrm); // Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix -// NOTE: +// NOTE: // This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. -// -inline const Transform3 orthoInverse( const Transform3 & tfrm ); +// +inline const Transform3 orthoInverse(const Transform3 &tfrm); // Conditionally select between two 3x4 transformation matrices -// -inline const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ); +// +inline const Transform3 select(const Transform3 &tfrm0, const Transform3 &tfrm1, bool select1); #ifdef _VECTORMATH_DEBUG // Print a 3x4 transformation matrix -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Transform3 & tfrm ); +// +inline void print(const Transform3 &tfrm); // Print a 3x4 transformation matrix and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -inline void print( const Transform3 & tfrm, const char * name ); +// +inline void print(const Transform3 &tfrm, const char *name); #endif -} // namespace Aos -} // namespace Vectormath +} // namespace Aos +} // namespace Vectormath #include "vec_aos.h" #include "quat_aos.h" diff --git a/test/Bullet2/vectormath/sse/boolInVec.h b/test/Bullet2/vectormath/sse/boolInVec.h index d21d25cbb..bdbc75cd2 100644 --- a/test/Bullet2/vectormath/sse/boolInVec.h +++ b/test/Bullet2/vectormath/sse/boolInVec.h @@ -32,8 +32,8 @@ #include -namespace Vectormath { - +namespace Vectormath +{ class floatInVec; //-------------------------------------------------------------------------------------------------- @@ -42,58 +42,59 @@ class floatInVec; class boolInVec { - private: - __m128 mData; +private: + __m128 mData; - inline boolInVec(__m128 vec); - public: - inline boolInVec() {} + inline boolInVec(__m128 vec); - // matches standard type conversions - // - inline boolInVec(const floatInVec &vec); +public: + inline boolInVec() {} - // explicit cast from bool - // - explicit inline boolInVec(bool scalar); + // matches standard type conversions + // + inline boolInVec(const floatInVec &vec); + + // explicit cast from bool + // + explicit inline boolInVec(bool scalar); #ifdef _VECTORMATH_NO_SCALAR_CAST - // explicit cast to bool - // - inline bool getAsBool() const; + // explicit cast to bool + // + inline bool getAsBool() const; #else - // implicit cast to bool - // - inline operator bool() const; + // implicit cast to bool + // + inline operator bool() const; #endif - - // get vector data - // bool value is splatted across all word slots of vector as 0 (false) or -1 (true) - // - inline __m128 get128() const; - // operators - // - inline const boolInVec operator ! () const; - inline boolInVec& operator = (const boolInVec &vec); - inline boolInVec& operator &= (const boolInVec &vec); - inline boolInVec& operator ^= (const boolInVec &vec); - inline boolInVec& operator |= (const boolInVec &vec); + // get vector data + // bool value is splatted across all word slots of vector as 0 (false) or -1 (true) + // + inline __m128 get128() const; - // friend functions - // - friend inline const boolInVec operator == (const boolInVec &vec0, const boolInVec &vec1); - friend inline const boolInVec operator != (const boolInVec &vec0, const boolInVec &vec1); - friend inline const boolInVec operator < (const floatInVec &vec0, const floatInVec &vec1); - friend inline const boolInVec operator <= (const floatInVec &vec0, const floatInVec &vec1); - friend inline const boolInVec operator > (const floatInVec &vec0, const floatInVec &vec1); - friend inline const boolInVec operator >= (const floatInVec &vec0, const floatInVec &vec1); - friend inline const boolInVec operator == (const floatInVec &vec0, const floatInVec &vec1); - friend inline const boolInVec operator != (const floatInVec &vec0, const floatInVec &vec1); - friend inline const boolInVec operator & (const boolInVec &vec0, const boolInVec &vec1); - friend inline const boolInVec operator ^ (const boolInVec &vec0, const boolInVec &vec1); - friend inline const boolInVec operator | (const boolInVec &vec0, const boolInVec &vec1); - friend inline const boolInVec select(const boolInVec &vec0, const boolInVec &vec1, const boolInVec &select_vec1); + // operators + // + inline const boolInVec operator!() const; + inline boolInVec &operator=(const boolInVec &vec); + inline boolInVec &operator&=(const boolInVec &vec); + inline boolInVec &operator^=(const boolInVec &vec); + inline boolInVec &operator|=(const boolInVec &vec); + + // friend functions + // + friend inline const boolInVec operator==(const boolInVec &vec0, const boolInVec &vec1); + friend inline const boolInVec operator!=(const boolInVec &vec0, const boolInVec &vec1); + friend inline const boolInVec operator<(const floatInVec &vec0, const floatInVec &vec1); + friend inline const boolInVec operator<=(const floatInVec &vec0, const floatInVec &vec1); + friend inline const boolInVec operator>(const floatInVec &vec0, const floatInVec &vec1); + friend inline const boolInVec operator>=(const floatInVec &vec0, const floatInVec &vec1); + friend inline const boolInVec operator==(const floatInVec &vec0, const floatInVec &vec1); + friend inline const boolInVec operator!=(const floatInVec &vec0, const floatInVec &vec1); + friend inline const boolInVec operator&(const boolInVec &vec0, const boolInVec &vec1); + friend inline const boolInVec operator^(const boolInVec &vec0, const boolInVec &vec1); + friend inline const boolInVec operator|(const boolInVec &vec0, const boolInVec &vec1); + friend inline const boolInVec select(const boolInVec &vec0, const boolInVec &vec1, const boolInVec &select_vec1); }; //-------------------------------------------------------------------------------------------------- @@ -102,18 +103,18 @@ class boolInVec // operators // -inline const boolInVec operator == (const boolInVec &vec0, const boolInVec &vec1); -inline const boolInVec operator != (const boolInVec &vec0, const boolInVec &vec1); -inline const boolInVec operator & (const boolInVec &vec0, const boolInVec &vec1); -inline const boolInVec operator ^ (const boolInVec &vec0, const boolInVec &vec1); -inline const boolInVec operator | (const boolInVec &vec0, const boolInVec &vec1); +inline const boolInVec operator==(const boolInVec &vec0, const boolInVec &vec1); +inline const boolInVec operator!=(const boolInVec &vec0, const boolInVec &vec1); +inline const boolInVec operator&(const boolInVec &vec0, const boolInVec &vec1); +inline const boolInVec operator^(const boolInVec &vec0, const boolInVec &vec1); +inline const boolInVec operator|(const boolInVec &vec0, const boolInVec &vec1); // select between vec0 and vec1 using boolInVec. // false selects vec0, true selects vec1 // inline const boolInVec select(const boolInVec &vec0, const boolInVec &vec1, const boolInVec &select_vec1); -} // namespace Vectormath +} // namespace Vectormath //-------------------------------------------------------------------------------------------------- // boolInVec implementation @@ -121,127 +122,110 @@ inline const boolInVec select(const boolInVec &vec0, const boolInVec &vec1, cons #include "floatInVec.h" -namespace Vectormath { - -inline -boolInVec::boolInVec(__m128 vec) +namespace Vectormath { - mData = vec; +inline boolInVec::boolInVec(__m128 vec) +{ + mData = vec; } -inline -boolInVec::boolInVec(const floatInVec &vec) +inline boolInVec::boolInVec(const floatInVec &vec) { - *this = (vec != floatInVec(0.0f)); + *this = (vec != floatInVec(0.0f)); } -inline -boolInVec::boolInVec(bool scalar) +inline boolInVec::boolInVec(bool scalar) { - unsigned int mask = -(int)scalar; - mData = _mm_set1_ps(*(float *)&mask); // TODO: Union + unsigned int mask = -(int)scalar; + mData = _mm_set1_ps(*(float *)&mask); // TODO: Union } #ifdef _VECTORMATH_NO_SCALAR_CAST -inline -bool +inline bool boolInVec::getAsBool() const #else -inline -boolInVec::operator bool() const +inline boolInVec::operator bool() const #endif { return *(bool *)&mData; } -inline -__m128 +inline __m128 boolInVec::get128() const { - return mData; + return mData; } -inline -const boolInVec -boolInVec::operator ! () const +inline const boolInVec +boolInVec::operator!() const { - return boolInVec(_mm_andnot_ps(mData, _mm_cmpneq_ps(_mm_setzero_ps(),_mm_setzero_ps()))); + return boolInVec(_mm_andnot_ps(mData, _mm_cmpneq_ps(_mm_setzero_ps(), _mm_setzero_ps()))); } -inline -boolInVec& -boolInVec::operator = (const boolInVec &vec) +inline boolInVec & +boolInVec::operator=(const boolInVec &vec) { - mData = vec.mData; - return *this; + mData = vec.mData; + return *this; } -inline -boolInVec& -boolInVec::operator &= (const boolInVec &vec) +inline boolInVec & +boolInVec::operator&=(const boolInVec &vec) { - *this = *this & vec; - return *this; + *this = *this & vec; + return *this; } -inline -boolInVec& -boolInVec::operator ^= (const boolInVec &vec) +inline boolInVec & +boolInVec::operator^=(const boolInVec &vec) { - *this = *this ^ vec; - return *this; + *this = *this ^ vec; + return *this; } -inline -boolInVec& -boolInVec::operator |= (const boolInVec &vec) +inline boolInVec & +boolInVec::operator|=(const boolInVec &vec) { - *this = *this | vec; - return *this; + *this = *this | vec; + return *this; } -inline -const boolInVec -operator == (const boolInVec &vec0, const boolInVec &vec1) +inline const boolInVec +operator==(const boolInVec &vec0, const boolInVec &vec1) { return boolInVec(_mm_cmpeq_ps(vec0.get128(), vec1.get128())); } -inline -const boolInVec -operator != (const boolInVec &vec0, const boolInVec &vec1) +inline const boolInVec +operator!=(const boolInVec &vec0, const boolInVec &vec1) { return boolInVec(_mm_cmpneq_ps(vec0.get128(), vec1.get128())); } - -inline -const boolInVec -operator & (const boolInVec &vec0, const boolInVec &vec1) + +inline const boolInVec +operator&(const boolInVec &vec0, const boolInVec &vec1) { return boolInVec(_mm_and_ps(vec0.get128(), vec1.get128())); } -inline -const boolInVec -operator | (const boolInVec &vec0, const boolInVec &vec1) +inline const boolInVec +operator|(const boolInVec &vec0, const boolInVec &vec1) { return boolInVec(_mm_or_ps(vec0.get128(), vec1.get128())); } -inline -const boolInVec -operator ^ (const boolInVec &vec0, const boolInVec &vec1) +inline const boolInVec +operator^(const boolInVec &vec0, const boolInVec &vec1) { return boolInVec(_mm_xor_ps(vec0.get128(), vec1.get128())); } -inline -const boolInVec +inline const boolInVec select(const boolInVec &vec0, const boolInVec &vec1, const boolInVec &select_vec1) { return boolInVec(vec_sel(vec0.get128(), vec1.get128(), select_vec1.get128())); } - -} // namespace Vectormath -#endif // boolInVec_h +} // namespace Vectormath + +#endif // boolInVec_h diff --git a/test/Bullet2/vectormath/sse/floatInVec.h b/test/Bullet2/vectormath/sse/floatInVec.h index e8ac5959e..eabd48a8a 100644 --- a/test/Bullet2/vectormath/sse/floatInVec.h +++ b/test/Bullet2/vectormath/sse/floatInVec.h @@ -33,8 +33,8 @@ #include #include -namespace Vectormath { - +namespace Vectormath +{ class boolInVec; //-------------------------------------------------------------------------------------------------- @@ -43,61 +43,61 @@ class boolInVec; class floatInVec { - private: - __m128 mData; +private: + __m128 mData; - public: - inline floatInVec(__m128 vec); +public: + inline floatInVec(__m128 vec); - inline floatInVec() {} + inline floatInVec() {} - // matches standard type conversions - // - inline floatInVec(const boolInVec &vec); + // matches standard type conversions + // + inline floatInVec(const boolInVec &vec); - // construct from a slot of __m128 - // - inline floatInVec(__m128 vec, int slot); - - // explicit cast from float - // - explicit inline floatInVec(float scalar); + // construct from a slot of __m128 + // + inline floatInVec(__m128 vec, int slot); + + // explicit cast from float + // + explicit inline floatInVec(float scalar); #ifdef _VECTORMATH_NO_SCALAR_CAST - // explicit cast to float - // - inline float getAsFloat() const; + // explicit cast to float + // + inline float getAsFloat() const; #else - // implicit cast to float - // - inline operator float() const; + // implicit cast to float + // + inline operator float() const; #endif - // get vector data - // float value is splatted across all word slots of vector - // - inline __m128 get128() const; + // get vector data + // float value is splatted across all word slots of vector + // + inline __m128 get128() const; - // operators - // - inline const floatInVec operator ++ (int); - inline const floatInVec operator -- (int); - inline floatInVec& operator ++ (); - inline floatInVec& operator -- (); - inline const floatInVec operator - () const; - inline floatInVec& operator = (const floatInVec &vec); - inline floatInVec& operator *= (const floatInVec &vec); - inline floatInVec& operator /= (const floatInVec &vec); - inline floatInVec& operator += (const floatInVec &vec); - inline floatInVec& operator -= (const floatInVec &vec); + // operators + // + inline const floatInVec operator++(int); + inline const floatInVec operator--(int); + inline floatInVec &operator++(); + inline floatInVec &operator--(); + inline const floatInVec operator-() const; + inline floatInVec &operator=(const floatInVec &vec); + inline floatInVec &operator*=(const floatInVec &vec); + inline floatInVec &operator/=(const floatInVec &vec); + inline floatInVec &operator+=(const floatInVec &vec); + inline floatInVec &operator-=(const floatInVec &vec); - // friend functions - // - friend inline const floatInVec operator * (const floatInVec &vec0, const floatInVec &vec1); - friend inline const floatInVec operator / (const floatInVec &vec0, const floatInVec &vec1); - friend inline const floatInVec operator + (const floatInVec &vec0, const floatInVec &vec1); - friend inline const floatInVec operator - (const floatInVec &vec0, const floatInVec &vec1); - friend inline const floatInVec select(const floatInVec &vec0, const floatInVec &vec1, boolInVec select_vec1); + // friend functions + // + friend inline const floatInVec operator*(const floatInVec &vec0, const floatInVec &vec1); + friend inline const floatInVec operator/(const floatInVec &vec0, const floatInVec &vec1); + friend inline const floatInVec operator+(const floatInVec &vec0, const floatInVec &vec1); + friend inline const floatInVec operator-(const floatInVec &vec0, const floatInVec &vec1); + friend inline const floatInVec select(const floatInVec &vec0, const floatInVec &vec1, boolInVec select_vec1); }; //-------------------------------------------------------------------------------------------------- @@ -105,24 +105,24 @@ class floatInVec // // operators -// -inline const floatInVec operator * (const floatInVec &vec0, const floatInVec &vec1); -inline const floatInVec operator / (const floatInVec &vec0, const floatInVec &vec1); -inline const floatInVec operator + (const floatInVec &vec0, const floatInVec &vec1); -inline const floatInVec operator - (const floatInVec &vec0, const floatInVec &vec1); -inline const boolInVec operator < (const floatInVec &vec0, const floatInVec &vec1); -inline const boolInVec operator <= (const floatInVec &vec0, const floatInVec &vec1); -inline const boolInVec operator > (const floatInVec &vec0, const floatInVec &vec1); -inline const boolInVec operator >= (const floatInVec &vec0, const floatInVec &vec1); -inline const boolInVec operator == (const floatInVec &vec0, const floatInVec &vec1); -inline const boolInVec operator != (const floatInVec &vec0, const floatInVec &vec1); +// +inline const floatInVec operator*(const floatInVec &vec0, const floatInVec &vec1); +inline const floatInVec operator/(const floatInVec &vec0, const floatInVec &vec1); +inline const floatInVec operator+(const floatInVec &vec0, const floatInVec &vec1); +inline const floatInVec operator-(const floatInVec &vec0, const floatInVec &vec1); +inline const boolInVec operator<(const floatInVec &vec0, const floatInVec &vec1); +inline const boolInVec operator<=(const floatInVec &vec0, const floatInVec &vec1); +inline const boolInVec operator>(const floatInVec &vec0, const floatInVec &vec1); +inline const boolInVec operator>=(const floatInVec &vec0, const floatInVec &vec1); +inline const boolInVec operator==(const floatInVec &vec0, const floatInVec &vec1); +inline const boolInVec operator!=(const floatInVec &vec0, const floatInVec &vec1); // select between vec0 and vec1 using boolInVec. // false selects vec0, true selects vec1 // inline const floatInVec select(const floatInVec &vec0, const floatInVec &vec1, const boolInVec &select_vec1); -} // namespace Vectormath +} // namespace Vectormath //-------------------------------------------------------------------------------------------------- // floatInVec implementation @@ -130,211 +130,183 @@ inline const floatInVec select(const floatInVec &vec0, const floatInVec &vec1, c #include "boolInVec.h" -namespace Vectormath { - -inline -floatInVec::floatInVec(__m128 vec) +namespace Vectormath { - mData = vec; +inline floatInVec::floatInVec(__m128 vec) +{ + mData = vec; } -inline -floatInVec::floatInVec(const boolInVec &vec) +inline floatInVec::floatInVec(const boolInVec &vec) { mData = vec_sel(_mm_setzero_ps(), _mm_set1_ps(1.0f), vec.get128()); } -inline -floatInVec::floatInVec(__m128 vec, int slot) +inline floatInVec::floatInVec(__m128 vec, int slot) { SSEFloat v; v.m128 = vec; mData = _mm_set1_ps(v.f[slot]); } -inline -floatInVec::floatInVec(float scalar) +inline floatInVec::floatInVec(float scalar) { mData = _mm_set1_ps(scalar); } #ifdef _VECTORMATH_NO_SCALAR_CAST -inline -float +inline float floatInVec::getAsFloat() const #else -inline -floatInVec::operator float() const +inline floatInVec::operator float() const #endif { - return *((float *)&mData); + return *((float *)&mData); } -inline -__m128 +inline __m128 floatInVec::get128() const { - return mData; + return mData; } -inline -const floatInVec -floatInVec::operator ++ (int) +inline const floatInVec +floatInVec::operator++(int) { - __m128 olddata = mData; - operator ++(); - return floatInVec(olddata); + __m128 olddata = mData; + operator++(); + return floatInVec(olddata); } -inline -const floatInVec -floatInVec::operator -- (int) +inline const floatInVec +floatInVec::operator--(int) { - __m128 olddata = mData; - operator --(); - return floatInVec(olddata); + __m128 olddata = mData; + operator--(); + return floatInVec(olddata); } -inline -floatInVec& -floatInVec::operator ++ () +inline floatInVec & +floatInVec::operator++() { - *this += floatInVec(_mm_set1_ps(1.0f)); - return *this; + *this += floatInVec(_mm_set1_ps(1.0f)); + return *this; } -inline -floatInVec& -floatInVec::operator -- () +inline floatInVec & +floatInVec::operator--() { - *this -= floatInVec(_mm_set1_ps(1.0f)); - return *this; + *this -= floatInVec(_mm_set1_ps(1.0f)); + return *this; } -inline -const floatInVec -floatInVec::operator - () const +inline const floatInVec +floatInVec::operator-() const { - return floatInVec(_mm_sub_ps(_mm_setzero_ps(), mData)); + return floatInVec(_mm_sub_ps(_mm_setzero_ps(), mData)); } -inline -floatInVec& -floatInVec::operator = (const floatInVec &vec) +inline floatInVec & +floatInVec::operator=(const floatInVec &vec) { - mData = vec.mData; - return *this; + mData = vec.mData; + return *this; } -inline -floatInVec& -floatInVec::operator *= (const floatInVec &vec) +inline floatInVec & +floatInVec::operator*=(const floatInVec &vec) { - *this = *this * vec; - return *this; + *this = *this * vec; + return *this; } -inline -floatInVec& -floatInVec::operator /= (const floatInVec &vec) +inline floatInVec & +floatInVec::operator/=(const floatInVec &vec) { - *this = *this / vec; - return *this; + *this = *this / vec; + return *this; } -inline -floatInVec& -floatInVec::operator += (const floatInVec &vec) +inline floatInVec & +floatInVec::operator+=(const floatInVec &vec) { - *this = *this + vec; - return *this; + *this = *this + vec; + return *this; } -inline -floatInVec& -floatInVec::operator -= (const floatInVec &vec) +inline floatInVec & +floatInVec::operator-=(const floatInVec &vec) { - *this = *this - vec; - return *this; + *this = *this - vec; + return *this; } -inline -const floatInVec -operator * (const floatInVec &vec0, const floatInVec &vec1) +inline const floatInVec +operator*(const floatInVec &vec0, const floatInVec &vec1) { - return floatInVec(_mm_mul_ps(vec0.get128(), vec1.get128())); + return floatInVec(_mm_mul_ps(vec0.get128(), vec1.get128())); } -inline -const floatInVec -operator / (const floatInVec &num, const floatInVec &den) +inline const floatInVec +operator/(const floatInVec &num, const floatInVec &den) { - return floatInVec(_mm_div_ps(num.get128(), den.get128())); + return floatInVec(_mm_div_ps(num.get128(), den.get128())); } -inline -const floatInVec -operator + (const floatInVec &vec0, const floatInVec &vec1) +inline const floatInVec +operator+(const floatInVec &vec0, const floatInVec &vec1) { - return floatInVec(_mm_add_ps(vec0.get128(), vec1.get128())); + return floatInVec(_mm_add_ps(vec0.get128(), vec1.get128())); } -inline -const floatInVec -operator - (const floatInVec &vec0, const floatInVec &vec1) +inline const floatInVec +operator-(const floatInVec &vec0, const floatInVec &vec1) { - return floatInVec(_mm_sub_ps(vec0.get128(), vec1.get128())); + return floatInVec(_mm_sub_ps(vec0.get128(), vec1.get128())); } -inline -const boolInVec -operator < (const floatInVec &vec0, const floatInVec &vec1) +inline const boolInVec +operator<(const floatInVec &vec0, const floatInVec &vec1) { - return boolInVec(_mm_cmpgt_ps(vec1.get128(), vec0.get128())); + return boolInVec(_mm_cmpgt_ps(vec1.get128(), vec0.get128())); } -inline -const boolInVec -operator <= (const floatInVec &vec0, const floatInVec &vec1) +inline const boolInVec +operator<=(const floatInVec &vec0, const floatInVec &vec1) { - return boolInVec(_mm_cmpge_ps(vec1.get128(), vec0.get128())); + return boolInVec(_mm_cmpge_ps(vec1.get128(), vec0.get128())); } -inline -const boolInVec -operator > (const floatInVec &vec0, const floatInVec &vec1) +inline const boolInVec +operator>(const floatInVec &vec0, const floatInVec &vec1) { - return boolInVec(_mm_cmpgt_ps(vec0.get128(), vec1.get128())); + return boolInVec(_mm_cmpgt_ps(vec0.get128(), vec1.get128())); } -inline -const boolInVec -operator >= (const floatInVec &vec0, const floatInVec &vec1) +inline const boolInVec +operator>=(const floatInVec &vec0, const floatInVec &vec1) { - return boolInVec(_mm_cmpge_ps(vec0.get128(), vec1.get128())); + return boolInVec(_mm_cmpge_ps(vec0.get128(), vec1.get128())); } -inline -const boolInVec -operator == (const floatInVec &vec0, const floatInVec &vec1) +inline const boolInVec +operator==(const floatInVec &vec0, const floatInVec &vec1) { - return boolInVec(_mm_cmpeq_ps(vec0.get128(), vec1.get128())); + return boolInVec(_mm_cmpeq_ps(vec0.get128(), vec1.get128())); } -inline -const boolInVec -operator != (const floatInVec &vec0, const floatInVec &vec1) +inline const boolInVec +operator!=(const floatInVec &vec0, const floatInVec &vec1) { - return boolInVec(_mm_cmpneq_ps(vec0.get128(), vec1.get128())); + return boolInVec(_mm_cmpneq_ps(vec0.get128(), vec1.get128())); } - -inline -const floatInVec + +inline const floatInVec select(const floatInVec &vec0, const floatInVec &vec1, const boolInVec &select_vec1) { - return floatInVec(vec_sel(vec0.get128(), vec1.get128(), select_vec1.get128())); + return floatInVec(vec_sel(vec0.get128(), vec1.get128(), select_vec1.get128())); } -} // namespace Vectormath +} // namespace Vectormath -#endif // floatInVec_h +#endif // floatInVec_h diff --git a/test/Bullet2/vectormath/sse/mat_aos.h b/test/Bullet2/vectormath/sse/mat_aos.h index a2c66cc5f..ea1658559 100644 --- a/test/Bullet2/vectormath/sse/mat_aos.h +++ b/test/Bullet2/vectormath/sse/mat_aos.h @@ -27,763 +27,742 @@ POSSIBILITY OF SUCH DAMAGE. */ - #ifndef _VECTORMATH_MAT_AOS_CPP_H #define _VECTORMATH_MAT_AOS_CPP_H -namespace Vectormath { -namespace Aos { - +namespace Vectormath +{ +namespace Aos +{ //----------------------------------------------------------------------------- // Constants // for shuffles, words are labeled [x,y,z,w] [a,b,c,d] -#define _VECTORMATH_PERM_ZBWX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X }) -#define _VECTORMATH_PERM_XCYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) -#define _VECTORMATH_PERM_XYAB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B }) -#define _VECTORMATH_PERM_ZWCD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W, _VECTORMATH_PERM_C, _VECTORMATH_PERM_D }) -#define _VECTORMATH_PERM_XZBX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_X }) -#define _VECTORMATH_PERM_CXXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) -#define _VECTORMATH_PERM_YAXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) -#define _VECTORMATH_PERM_XAZC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_C }) -#define _VECTORMATH_PERM_YXWZ ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W, _VECTORMATH_PERM_Z }) -#define _VECTORMATH_PERM_YBWD ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_D }) -#define _VECTORMATH_PERM_XYCX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X }) -#define _VECTORMATH_PERM_YCXY ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y }) -#define _VECTORMATH_PERM_CXYC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C }) -#define _VECTORMATH_PERM_ZAYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) -#define _VECTORMATH_PERM_BZXX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X }) -#define _VECTORMATH_PERM_XZYA ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A }) -#define _VECTORMATH_PERM_ZXXB ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_B }) -#define _VECTORMATH_PERM_YXXC ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_C }) -#define _VECTORMATH_PERM_BBYX ((vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_B, _VECTORMATH_PERM_B, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X }) +#define _VECTORMATH_PERM_ZBWX ((vec_uchar16)(vec_uint4){_VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_X}) +#define _VECTORMATH_PERM_XCYX ((vec_uchar16)(vec_uint4){_VECTORMATH_PERM_X, _VECTORMATH_PERM_C, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X}) +#define _VECTORMATH_PERM_XYAB ((vec_uchar16)(vec_uint4){_VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B}) +#define _VECTORMATH_PERM_ZWCD ((vec_uchar16)(vec_uint4){_VECTORMATH_PERM_Z, _VECTORMATH_PERM_W, _VECTORMATH_PERM_C, _VECTORMATH_PERM_D}) +#define _VECTORMATH_PERM_XZBX ((vec_uchar16)(vec_uint4){_VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_B, _VECTORMATH_PERM_X}) +#define _VECTORMATH_PERM_CXXX ((vec_uchar16)(vec_uint4){_VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X}) +#define _VECTORMATH_PERM_YAXX ((vec_uchar16)(vec_uint4){_VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X}) +#define _VECTORMATH_PERM_XAZC ((vec_uchar16)(vec_uint4){_VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_C}) +#define _VECTORMATH_PERM_YXWZ ((vec_uchar16)(vec_uint4){_VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W, _VECTORMATH_PERM_Z}) +#define _VECTORMATH_PERM_YBWD ((vec_uchar16)(vec_uint4){_VECTORMATH_PERM_Y, _VECTORMATH_PERM_B, _VECTORMATH_PERM_W, _VECTORMATH_PERM_D}) +#define _VECTORMATH_PERM_XYCX ((vec_uchar16)(vec_uint4){_VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X}) +#define _VECTORMATH_PERM_YCXY ((vec_uchar16)(vec_uint4){_VECTORMATH_PERM_Y, _VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y}) +#define _VECTORMATH_PERM_CXYC ((vec_uchar16)(vec_uint4){_VECTORMATH_PERM_C, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_C}) +#define _VECTORMATH_PERM_ZAYX ((vec_uchar16)(vec_uint4){_VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X}) +#define _VECTORMATH_PERM_BZXX ((vec_uchar16)(vec_uint4){_VECTORMATH_PERM_B, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X}) +#define _VECTORMATH_PERM_XZYA ((vec_uchar16)(vec_uint4){_VECTORMATH_PERM_X, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A}) +#define _VECTORMATH_PERM_ZXXB ((vec_uchar16)(vec_uint4){_VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_B}) +#define _VECTORMATH_PERM_YXXC ((vec_uchar16)(vec_uint4){_VECTORMATH_PERM_Y, _VECTORMATH_PERM_X, _VECTORMATH_PERM_X, _VECTORMATH_PERM_C}) +#define _VECTORMATH_PERM_BBYX ((vec_uchar16)(vec_uint4){_VECTORMATH_PERM_B, _VECTORMATH_PERM_B, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_X}) #define _VECTORMATH_PI_OVER_2 1.570796327f //----------------------------------------------------------------------------- // Definitions -VECTORMATH_FORCE_INLINE Matrix3::Matrix3( const Matrix3 & mat ) +VECTORMATH_FORCE_INLINE Matrix3::Matrix3(const Matrix3 &mat) { - mCol0 = mat.mCol0; - mCol1 = mat.mCol1; - mCol2 = mat.mCol2; + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; } -VECTORMATH_FORCE_INLINE Matrix3::Matrix3( float scalar ) +VECTORMATH_FORCE_INLINE Matrix3::Matrix3(float scalar) { - mCol0 = Vector3( scalar ); - mCol1 = Vector3( scalar ); - mCol2 = Vector3( scalar ); + mCol0 = Vector3(scalar); + mCol1 = Vector3(scalar); + mCol2 = Vector3(scalar); } -VECTORMATH_FORCE_INLINE Matrix3::Matrix3( const floatInVec &scalar ) +VECTORMATH_FORCE_INLINE Matrix3::Matrix3(const floatInVec &scalar) { - mCol0 = Vector3( scalar ); - mCol1 = Vector3( scalar ); - mCol2 = Vector3( scalar ); + mCol0 = Vector3(scalar); + mCol1 = Vector3(scalar); + mCol2 = Vector3(scalar); } -VECTORMATH_FORCE_INLINE Matrix3::Matrix3( const Quat &unitQuat ) +VECTORMATH_FORCE_INLINE Matrix3::Matrix3(const Quat &unitQuat) { - __m128 xyzw_2, wwww, yzxw, zxyw, yzxw_2, zxyw_2; - __m128 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; + __m128 xyzw_2, wwww, yzxw, zxyw, yzxw_2, zxyw_2; + __m128 tmp0, tmp1, tmp2, tmp3, tmp4, tmp5; VM_ATTRIBUTE_ALIGN16 unsigned int sx[4] = {0xffffffff, 0, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int sz[4] = {0, 0, 0xffffffff, 0}; __m128 select_x = _mm_load_ps((float *)sx); __m128 select_z = _mm_load_ps((float *)sz); - xyzw_2 = _mm_add_ps( unitQuat.get128(), unitQuat.get128() ); - wwww = _mm_shuffle_ps( unitQuat.get128(), unitQuat.get128(), _MM_SHUFFLE(3,3,3,3) ); - yzxw = _mm_shuffle_ps( unitQuat.get128(), unitQuat.get128(), _MM_SHUFFLE(3,0,2,1) ); - zxyw = _mm_shuffle_ps( unitQuat.get128(), unitQuat.get128(), _MM_SHUFFLE(3,1,0,2) ); - yzxw_2 = _mm_shuffle_ps( xyzw_2, xyzw_2, _MM_SHUFFLE(3,0,2,1) ); - zxyw_2 = _mm_shuffle_ps( xyzw_2, xyzw_2, _MM_SHUFFLE(3,1,0,2) ); + xyzw_2 = _mm_add_ps(unitQuat.get128(), unitQuat.get128()); + wwww = _mm_shuffle_ps(unitQuat.get128(), unitQuat.get128(), _MM_SHUFFLE(3, 3, 3, 3)); + yzxw = _mm_shuffle_ps(unitQuat.get128(), unitQuat.get128(), _MM_SHUFFLE(3, 0, 2, 1)); + zxyw = _mm_shuffle_ps(unitQuat.get128(), unitQuat.get128(), _MM_SHUFFLE(3, 1, 0, 2)); + yzxw_2 = _mm_shuffle_ps(xyzw_2, xyzw_2, _MM_SHUFFLE(3, 0, 2, 1)); + zxyw_2 = _mm_shuffle_ps(xyzw_2, xyzw_2, _MM_SHUFFLE(3, 1, 0, 2)); - tmp0 = _mm_mul_ps( yzxw_2, wwww ); // tmp0 = 2yw, 2zw, 2xw, 2w2 - tmp1 = _mm_sub_ps( _mm_set1_ps(1.0f), _mm_mul_ps(yzxw, yzxw_2) ); // tmp1 = 1 - 2y2, 1 - 2z2, 1 - 2x2, 1 - 2w2 - tmp2 = _mm_mul_ps( yzxw, xyzw_2 ); // tmp2 = 2xy, 2yz, 2xz, 2w2 - tmp0 = _mm_add_ps( _mm_mul_ps(zxyw, xyzw_2), tmp0 ); // tmp0 = 2yw + 2zx, 2zw + 2xy, 2xw + 2yz, 2w2 + 2w2 - tmp1 = _mm_sub_ps( tmp1, _mm_mul_ps(zxyw, zxyw_2) ); // tmp1 = 1 - 2y2 - 2z2, 1 - 2z2 - 2x2, 1 - 2x2 - 2y2, 1 - 2w2 - 2w2 - tmp2 = _mm_sub_ps( tmp2, _mm_mul_ps(zxyw_2, wwww) ); // tmp2 = 2xy - 2zw, 2yz - 2xw, 2xz - 2yw, 2w2 -2w2 + tmp0 = _mm_mul_ps(yzxw_2, wwww); // tmp0 = 2yw, 2zw, 2xw, 2w2 + tmp1 = _mm_sub_ps(_mm_set1_ps(1.0f), _mm_mul_ps(yzxw, yzxw_2)); // tmp1 = 1 - 2y2, 1 - 2z2, 1 - 2x2, 1 - 2w2 + tmp2 = _mm_mul_ps(yzxw, xyzw_2); // tmp2 = 2xy, 2yz, 2xz, 2w2 + tmp0 = _mm_add_ps(_mm_mul_ps(zxyw, xyzw_2), tmp0); // tmp0 = 2yw + 2zx, 2zw + 2xy, 2xw + 2yz, 2w2 + 2w2 + tmp1 = _mm_sub_ps(tmp1, _mm_mul_ps(zxyw, zxyw_2)); // tmp1 = 1 - 2y2 - 2z2, 1 - 2z2 - 2x2, 1 - 2x2 - 2y2, 1 - 2w2 - 2w2 + tmp2 = _mm_sub_ps(tmp2, _mm_mul_ps(zxyw_2, wwww)); // tmp2 = 2xy - 2zw, 2yz - 2xw, 2xz - 2yw, 2w2 -2w2 - tmp3 = vec_sel( tmp0, tmp1, select_x ); - tmp4 = vec_sel( tmp1, tmp2, select_x ); - tmp5 = vec_sel( tmp2, tmp0, select_x ); - mCol0 = Vector3( vec_sel( tmp3, tmp2, select_z ) ); - mCol1 = Vector3( vec_sel( tmp4, tmp0, select_z ) ); - mCol2 = Vector3( vec_sel( tmp5, tmp1, select_z ) ); + tmp3 = vec_sel(tmp0, tmp1, select_x); + tmp4 = vec_sel(tmp1, tmp2, select_x); + tmp5 = vec_sel(tmp2, tmp0, select_x); + mCol0 = Vector3(vec_sel(tmp3, tmp2, select_z)); + mCol1 = Vector3(vec_sel(tmp4, tmp0, select_z)); + mCol2 = Vector3(vec_sel(tmp5, tmp1, select_z)); } -VECTORMATH_FORCE_INLINE Matrix3::Matrix3( const Vector3 &_col0, const Vector3 &_col1, const Vector3 &_col2 ) +VECTORMATH_FORCE_INLINE Matrix3::Matrix3(const Vector3 &_col0, const Vector3 &_col1, const Vector3 &_col2) { - mCol0 = _col0; - mCol1 = _col1; - mCol2 = _col2; + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; } -VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setCol0( const Vector3 &_col0 ) +VECTORMATH_FORCE_INLINE Matrix3 &Matrix3::setCol0(const Vector3 &_col0) { - mCol0 = _col0; - return *this; + mCol0 = _col0; + return *this; } -VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setCol1( const Vector3 &_col1 ) +VECTORMATH_FORCE_INLINE Matrix3 &Matrix3::setCol1(const Vector3 &_col1) { - mCol1 = _col1; - return *this; + mCol1 = _col1; + return *this; } -VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setCol2( const Vector3 &_col2 ) +VECTORMATH_FORCE_INLINE Matrix3 &Matrix3::setCol2(const Vector3 &_col2) { - mCol2 = _col2; - return *this; + mCol2 = _col2; + return *this; } -VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setCol( int col, const Vector3 &vec ) +VECTORMATH_FORCE_INLINE Matrix3 &Matrix3::setCol(int col, const Vector3 &vec) { - *(&mCol0 + col) = vec; - return *this; + *(&mCol0 + col) = vec; + return *this; } -VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setRow( int row, const Vector3 &vec ) +VECTORMATH_FORCE_INLINE Matrix3 &Matrix3::setRow(int row, const Vector3 &vec) { - mCol0.setElem( row, vec.getElem( 0 ) ); - mCol1.setElem( row, vec.getElem( 1 ) ); - mCol2.setElem( row, vec.getElem( 2 ) ); - return *this; + mCol0.setElem(row, vec.getElem(0)); + mCol1.setElem(row, vec.getElem(1)); + mCol2.setElem(row, vec.getElem(2)); + return *this; } -VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setElem( int col, int row, float val ) +VECTORMATH_FORCE_INLINE Matrix3 &Matrix3::setElem(int col, int row, float val) { - (*this)[col].setElem(row, val); - return *this; + (*this)[col].setElem(row, val); + return *this; } -VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::setElem( int col, int row, const floatInVec &val ) +VECTORMATH_FORCE_INLINE Matrix3 &Matrix3::setElem(int col, int row, const floatInVec &val) { - Vector3 tmpV3_0; - tmpV3_0 = this->getCol( col ); - tmpV3_0.setElem( row, val ); - this->setCol( col, tmpV3_0 ); - return *this; + Vector3 tmpV3_0; + tmpV3_0 = this->getCol(col); + tmpV3_0.setElem(row, val); + this->setCol(col, tmpV3_0); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Matrix3::getElem( int col, int row ) const +VECTORMATH_FORCE_INLINE const floatInVec Matrix3::getElem(int col, int row) const { - return this->getCol( col ).getElem( row ); + return this->getCol(col).getElem(row); } -VECTORMATH_FORCE_INLINE const Vector3 Matrix3::getCol0( ) const +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::getCol0() const { - return mCol0; + return mCol0; } -VECTORMATH_FORCE_INLINE const Vector3 Matrix3::getCol1( ) const +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::getCol1() const { - return mCol1; + return mCol1; } -VECTORMATH_FORCE_INLINE const Vector3 Matrix3::getCol2( ) const +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::getCol2() const { - return mCol2; + return mCol2; } -VECTORMATH_FORCE_INLINE const Vector3 Matrix3::getCol( int col ) const +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::getCol(int col) const { - return *(&mCol0 + col); + return *(&mCol0 + col); } -VECTORMATH_FORCE_INLINE const Vector3 Matrix3::getRow( int row ) const +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::getRow(int row) const { - return Vector3( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ) ); + return Vector3(mCol0.getElem(row), mCol1.getElem(row), mCol2.getElem(row)); } -VECTORMATH_FORCE_INLINE Vector3 & Matrix3::operator []( int col ) +VECTORMATH_FORCE_INLINE Vector3 &Matrix3::operator[](int col) { - return *(&mCol0 + col); + return *(&mCol0 + col); } -VECTORMATH_FORCE_INLINE const Vector3 Matrix3::operator []( int col ) const +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::operator[](int col) const { - return *(&mCol0 + col); + return *(&mCol0 + col); } -VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::operator =( const Matrix3 & mat ) +VECTORMATH_FORCE_INLINE Matrix3 &Matrix3::operator=(const Matrix3 &mat) { - mCol0 = mat.mCol0; - mCol1 = mat.mCol1; - mCol2 = mat.mCol2; - return *this; + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + return *this; } -VECTORMATH_FORCE_INLINE const Matrix3 transpose( const Matrix3 & mat ) +VECTORMATH_FORCE_INLINE const Matrix3 transpose(const Matrix3 &mat) { - __m128 tmp0, tmp1, res0, res1, res2; - tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() ); - tmp1 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() ); - res0 = vec_mergeh( tmp0, mat.getCol1().get128() ); - //res1 = vec_perm( tmp0, mat.getCol1().get128(), _VECTORMATH_PERM_ZBWX ); + __m128 tmp0, tmp1, res0, res1, res2; + tmp0 = vec_mergeh(mat.getCol0().get128(), mat.getCol2().get128()); + tmp1 = vec_mergel(mat.getCol0().get128(), mat.getCol2().get128()); + res0 = vec_mergeh(tmp0, mat.getCol1().get128()); + //res1 = vec_perm( tmp0, mat.getCol1().get128(), _VECTORMATH_PERM_ZBWX ); VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; - res1 = _mm_shuffle_ps( tmp0, tmp0, _MM_SHUFFLE(0,3,2,2)); + res1 = _mm_shuffle_ps(tmp0, tmp0, _MM_SHUFFLE(0, 3, 2, 2)); res1 = vec_sel(res1, mat.getCol1().get128(), select_y); - //res2 = vec_perm( tmp1, mat.getCol1().get128(), _VECTORMATH_PERM_XCYX ); - res2 = _mm_shuffle_ps( tmp1, tmp1, _MM_SHUFFLE(0,1,1,0)); + //res2 = vec_perm( tmp1, mat.getCol1().get128(), _VECTORMATH_PERM_XCYX ); + res2 = _mm_shuffle_ps(tmp1, tmp1, _MM_SHUFFLE(0, 1, 1, 0)); res2 = vec_sel(res2, vec_splat(mat.getCol1().get128(), 2), select_y); - return Matrix3( - Vector3( res0 ), - Vector3( res1 ), - Vector3( res2 ) - ); + return Matrix3( + Vector3(res0), + Vector3(res1), + Vector3(res2)); } -VECTORMATH_FORCE_INLINE const Matrix3 inverse( const Matrix3 & mat ) +VECTORMATH_FORCE_INLINE const Matrix3 inverse(const Matrix3 &mat) { - __m128 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet, inv0, inv1, inv2; - tmp2 = _vmathVfCross( mat.getCol0().get128(), mat.getCol1().get128() ); - tmp0 = _vmathVfCross( mat.getCol1().get128(), mat.getCol2().get128() ); - tmp1 = _vmathVfCross( mat.getCol2().get128(), mat.getCol0().get128() ); - dot = _vmathVfDot3( tmp2, mat.getCol2().get128() ); - dot = vec_splat( dot, 0 ); - invdet = recipf4( dot ); - tmp3 = vec_mergeh( tmp0, tmp2 ); - tmp4 = vec_mergel( tmp0, tmp2 ); - inv0 = vec_mergeh( tmp3, tmp1 ); - //inv1 = vec_perm( tmp3, tmp1, _VECTORMATH_PERM_ZBWX ); + __m128 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet, inv0, inv1, inv2; + tmp2 = _vmathVfCross(mat.getCol0().get128(), mat.getCol1().get128()); + tmp0 = _vmathVfCross(mat.getCol1().get128(), mat.getCol2().get128()); + tmp1 = _vmathVfCross(mat.getCol2().get128(), mat.getCol0().get128()); + dot = _vmathVfDot3(tmp2, mat.getCol2().get128()); + dot = vec_splat(dot, 0); + invdet = recipf4(dot); + tmp3 = vec_mergeh(tmp0, tmp2); + tmp4 = vec_mergel(tmp0, tmp2); + inv0 = vec_mergeh(tmp3, tmp1); + //inv1 = vec_perm( tmp3, tmp1, _VECTORMATH_PERM_ZBWX ); VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; - inv1 = _mm_shuffle_ps( tmp3, tmp3, _MM_SHUFFLE(0,3,2,2)); + inv1 = _mm_shuffle_ps(tmp3, tmp3, _MM_SHUFFLE(0, 3, 2, 2)); inv1 = vec_sel(inv1, tmp1, select_y); - //inv2 = vec_perm( tmp4, tmp1, _VECTORMATH_PERM_XCYX ); - inv2 = _mm_shuffle_ps( tmp4, tmp4, _MM_SHUFFLE(0,1,1,0)); + //inv2 = vec_perm( tmp4, tmp1, _VECTORMATH_PERM_XCYX ); + inv2 = _mm_shuffle_ps(tmp4, tmp4, _MM_SHUFFLE(0, 1, 1, 0)); inv2 = vec_sel(inv2, vec_splat(tmp1, 2), select_y); - inv0 = vec_mul( inv0, invdet ); - inv1 = vec_mul( inv1, invdet ); - inv2 = vec_mul( inv2, invdet ); - return Matrix3( - Vector3( inv0 ), - Vector3( inv1 ), - Vector3( inv2 ) - ); + inv0 = vec_mul(inv0, invdet); + inv1 = vec_mul(inv1, invdet); + inv2 = vec_mul(inv2, invdet); + return Matrix3( + Vector3(inv0), + Vector3(inv1), + Vector3(inv2)); } -VECTORMATH_FORCE_INLINE const floatInVec determinant( const Matrix3 & mat ) +VECTORMATH_FORCE_INLINE const floatInVec determinant(const Matrix3 &mat) { - return dot( mat.getCol2(), cross( mat.getCol0(), mat.getCol1() ) ); + return dot(mat.getCol2(), cross(mat.getCol0(), mat.getCol1())); } -VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator +( const Matrix3 & mat ) const +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator+(const Matrix3 &mat) const { - return Matrix3( - ( mCol0 + mat.mCol0 ), - ( mCol1 + mat.mCol1 ), - ( mCol2 + mat.mCol2 ) - ); + return Matrix3( + (mCol0 + mat.mCol0), + (mCol1 + mat.mCol1), + (mCol2 + mat.mCol2)); } -VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator -( const Matrix3 & mat ) const +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator-(const Matrix3 &mat) const { - return Matrix3( - ( mCol0 - mat.mCol0 ), - ( mCol1 - mat.mCol1 ), - ( mCol2 - mat.mCol2 ) - ); + return Matrix3( + (mCol0 - mat.mCol0), + (mCol1 - mat.mCol1), + (mCol2 - mat.mCol2)); } -VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::operator +=( const Matrix3 & mat ) +VECTORMATH_FORCE_INLINE Matrix3 &Matrix3::operator+=(const Matrix3 &mat) { - *this = *this + mat; - return *this; + *this = *this + mat; + return *this; } -VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::operator -=( const Matrix3 & mat ) +VECTORMATH_FORCE_INLINE Matrix3 &Matrix3::operator-=(const Matrix3 &mat) { - *this = *this - mat; - return *this; + *this = *this - mat; + return *this; } -VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator -( ) const +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator-() const { - return Matrix3( - ( -mCol0 ), - ( -mCol1 ), - ( -mCol2 ) - ); + return Matrix3( + (-mCol0), + (-mCol1), + (-mCol2)); } -VECTORMATH_FORCE_INLINE const Matrix3 absPerElem( const Matrix3 & mat ) +VECTORMATH_FORCE_INLINE const Matrix3 absPerElem(const Matrix3 &mat) { - return Matrix3( - absPerElem( mat.getCol0() ), - absPerElem( mat.getCol1() ), - absPerElem( mat.getCol2() ) - ); + return Matrix3( + absPerElem(mat.getCol0()), + absPerElem(mat.getCol1()), + absPerElem(mat.getCol2())); } -VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator *( float scalar ) const +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator*(float scalar) const { - return *this * floatInVec(scalar); + return *this * floatInVec(scalar); } -VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator *( const floatInVec &scalar ) const +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator*(const floatInVec &scalar) const { - return Matrix3( - ( mCol0 * scalar ), - ( mCol1 * scalar ), - ( mCol2 * scalar ) - ); + return Matrix3( + (mCol0 * scalar), + (mCol1 * scalar), + (mCol2 * scalar)); } -VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::operator *=( float scalar ) +VECTORMATH_FORCE_INLINE Matrix3 &Matrix3::operator*=(float scalar) { - return *this *= floatInVec(scalar); + return *this *= floatInVec(scalar); } -VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::operator *=( const floatInVec &scalar ) +VECTORMATH_FORCE_INLINE Matrix3 &Matrix3::operator*=(const floatInVec &scalar) { - *this = *this * scalar; - return *this; + *this = *this * scalar; + return *this; } -VECTORMATH_FORCE_INLINE const Matrix3 operator *( float scalar, const Matrix3 & mat ) +VECTORMATH_FORCE_INLINE const Matrix3 operator*(float scalar, const Matrix3 &mat) { - return floatInVec(scalar) * mat; + return floatInVec(scalar) * mat; } -VECTORMATH_FORCE_INLINE const Matrix3 operator *( const floatInVec &scalar, const Matrix3 & mat ) +VECTORMATH_FORCE_INLINE const Matrix3 operator*(const floatInVec &scalar, const Matrix3 &mat) { - return mat * scalar; + return mat * scalar; } -VECTORMATH_FORCE_INLINE const Vector3 Matrix3::operator *( const Vector3 &vec ) const +VECTORMATH_FORCE_INLINE const Vector3 Matrix3::operator*(const Vector3 &vec) const { - __m128 res; - __m128 xxxx, yyyy, zzzz; - xxxx = vec_splat( vec.get128(), 0 ); - yyyy = vec_splat( vec.get128(), 1 ); - zzzz = vec_splat( vec.get128(), 2 ); - res = vec_mul( mCol0.get128(), xxxx ); - res = vec_madd( mCol1.get128(), yyyy, res ); - res = vec_madd( mCol2.get128(), zzzz, res ); - return Vector3( res ); + __m128 res; + __m128 xxxx, yyyy, zzzz; + xxxx = vec_splat(vec.get128(), 0); + yyyy = vec_splat(vec.get128(), 1); + zzzz = vec_splat(vec.get128(), 2); + res = vec_mul(mCol0.get128(), xxxx); + res = vec_madd(mCol1.get128(), yyyy, res); + res = vec_madd(mCol2.get128(), zzzz, res); + return Vector3(res); } -VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator *( const Matrix3 & mat ) const +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::operator*(const Matrix3 &mat) const { - return Matrix3( - ( *this * mat.mCol0 ), - ( *this * mat.mCol1 ), - ( *this * mat.mCol2 ) - ); + return Matrix3( + (*this * mat.mCol0), + (*this * mat.mCol1), + (*this * mat.mCol2)); } -VECTORMATH_FORCE_INLINE Matrix3 & Matrix3::operator *=( const Matrix3 & mat ) +VECTORMATH_FORCE_INLINE Matrix3 &Matrix3::operator*=(const Matrix3 &mat) { - *this = *this * mat; - return *this; + *this = *this * mat; + return *this; } -VECTORMATH_FORCE_INLINE const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ) +VECTORMATH_FORCE_INLINE const Matrix3 mulPerElem(const Matrix3 &mat0, const Matrix3 &mat1) { - return Matrix3( - mulPerElem( mat0.getCol0(), mat1.getCol0() ), - mulPerElem( mat0.getCol1(), mat1.getCol1() ), - mulPerElem( mat0.getCol2(), mat1.getCol2() ) - ); + return Matrix3( + mulPerElem(mat0.getCol0(), mat1.getCol0()), + mulPerElem(mat0.getCol1(), mat1.getCol1()), + mulPerElem(mat0.getCol2(), mat1.getCol2())); } -VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::identity( ) +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::identity() { - return Matrix3( - Vector3::xAxis( ), - Vector3::yAxis( ), - Vector3::zAxis( ) - ); + return Matrix3( + Vector3::xAxis(), + Vector3::yAxis(), + Vector3::zAxis()); } -VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationX( float radians ) +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationX(float radians) { - return rotationX( floatInVec(radians) ); + return rotationX(floatInVec(radians)); } -VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationX( const floatInVec &radians ) +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationX(const floatInVec &radians) { - __m128 s, c, res1, res2; - __m128 zero; + __m128 s, c, res1, res2; + __m128 zero; VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; - zero = _mm_setzero_ps(); - sincosf4( radians.get128(), &s, &c ); - res1 = vec_sel( zero, c, select_y ); - res1 = vec_sel( res1, s, select_z ); - res2 = vec_sel( zero, negatef4(s), select_y ); - res2 = vec_sel( res2, c, select_z ); - return Matrix3( - Vector3::xAxis( ), - Vector3( res1 ), - Vector3( res2 ) - ); + zero = _mm_setzero_ps(); + sincosf4(radians.get128(), &s, &c); + res1 = vec_sel(zero, c, select_y); + res1 = vec_sel(res1, s, select_z); + res2 = vec_sel(zero, negatef4(s), select_y); + res2 = vec_sel(res2, c, select_z); + return Matrix3( + Vector3::xAxis(), + Vector3(res1), + Vector3(res2)); } -VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationY( float radians ) +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationY(float radians) { - return rotationY( floatInVec(radians) ); + return rotationY(floatInVec(radians)); } -VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationY( const floatInVec &radians ) +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationY(const floatInVec &radians) { - __m128 s, c, res0, res2; - __m128 zero; + __m128 s, c, res0, res2; + __m128 zero; VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; - zero = _mm_setzero_ps(); - sincosf4( radians.get128(), &s, &c ); - res0 = vec_sel( zero, c, select_x ); - res0 = vec_sel( res0, negatef4(s), select_z ); - res2 = vec_sel( zero, s, select_x ); - res2 = vec_sel( res2, c, select_z ); - return Matrix3( - Vector3( res0 ), - Vector3::yAxis( ), - Vector3( res2 ) - ); + zero = _mm_setzero_ps(); + sincosf4(radians.get128(), &s, &c); + res0 = vec_sel(zero, c, select_x); + res0 = vec_sel(res0, negatef4(s), select_z); + res2 = vec_sel(zero, s, select_x); + res2 = vec_sel(res2, c, select_z); + return Matrix3( + Vector3(res0), + Vector3::yAxis(), + Vector3(res2)); } -VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationZ( float radians ) +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationZ(float radians) { - return rotationZ( floatInVec(radians) ); + return rotationZ(floatInVec(radians)); } -VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationZ( const floatInVec &radians ) +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationZ(const floatInVec &radians) { - __m128 s, c, res0, res1; - __m128 zero; + __m128 s, c, res0, res1; + __m128 zero; VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; - zero = _mm_setzero_ps(); - sincosf4( radians.get128(), &s, &c ); - res0 = vec_sel( zero, c, select_x ); - res0 = vec_sel( res0, s, select_y ); - res1 = vec_sel( zero, negatef4(s), select_x ); - res1 = vec_sel( res1, c, select_y ); - return Matrix3( - Vector3( res0 ), - Vector3( res1 ), - Vector3::zAxis( ) - ); + zero = _mm_setzero_ps(); + sincosf4(radians.get128(), &s, &c); + res0 = vec_sel(zero, c, select_x); + res0 = vec_sel(res0, s, select_y); + res1 = vec_sel(zero, negatef4(s), select_x); + res1 = vec_sel(res1, c, select_y); + return Matrix3( + Vector3(res0), + Vector3(res1), + Vector3::zAxis()); } -VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationZYX( const Vector3 &radiansXYZ ) +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotationZYX(const Vector3 &radiansXYZ) { - __m128 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; - angles = Vector4( radiansXYZ, 0.0f ).get128(); - sincosf4( angles, &s, &c ); - negS = negatef4( s ); - Z0 = vec_mergel( c, s ); - Z1 = vec_mergel( negS, c ); + __m128 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; + angles = Vector4(radiansXYZ, 0.0f).get128(); + sincosf4(angles, &s, &c); + negS = negatef4(s); + Z0 = vec_mergel(c, s); + Z1 = vec_mergel(negS, c); VM_ATTRIBUTE_ALIGN16 unsigned int select_xyz[4] = {0xffffffff, 0xffffffff, 0xffffffff, 0}; - Z1 = vec_and( Z1, _mm_load_ps( (float *)select_xyz ) ); - Y0 = _mm_shuffle_ps( c, negS, _MM_SHUFFLE(0,1,1,1) ); - Y1 = _mm_shuffle_ps( s, c, _MM_SHUFFLE(0,1,1,1) ); - X0 = vec_splat( s, 0 ); - X1 = vec_splat( c, 0 ); - tmp = vec_mul( Z0, Y1 ); - return Matrix3( - Vector3( vec_mul( Z0, Y0 ) ), - Vector3( vec_madd( Z1, X1, vec_mul( tmp, X0 ) ) ), - Vector3( vec_nmsub( Z1, X0, vec_mul( tmp, X1 ) ) ) - ); + Z1 = vec_and(Z1, _mm_load_ps((float *)select_xyz)); + Y0 = _mm_shuffle_ps(c, negS, _MM_SHUFFLE(0, 1, 1, 1)); + Y1 = _mm_shuffle_ps(s, c, _MM_SHUFFLE(0, 1, 1, 1)); + X0 = vec_splat(s, 0); + X1 = vec_splat(c, 0); + tmp = vec_mul(Z0, Y1); + return Matrix3( + Vector3(vec_mul(Z0, Y0)), + Vector3(vec_madd(Z1, X1, vec_mul(tmp, X0))), + Vector3(vec_nmsub(Z1, X0, vec_mul(tmp, X1)))); } -VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotation( float radians, const Vector3 &unitVec ) +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotation(float radians, const Vector3 &unitVec) { - return rotation( floatInVec(radians), unitVec ); + return rotation(floatInVec(radians), unitVec); } -VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotation( const floatInVec &radians, const Vector3 &unitVec ) +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotation(const floatInVec &radians, const Vector3 &unitVec) { - __m128 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2; - axis = unitVec.get128(); - sincosf4( radians.get128(), &s, &c ); - xxxx = vec_splat( axis, 0 ); - yyyy = vec_splat( axis, 1 ); - zzzz = vec_splat( axis, 2 ); - oneMinusC = vec_sub( _mm_set1_ps(1.0f), c ); - axisS = vec_mul( axis, s ); - negAxisS = negatef4( axisS ); + __m128 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2; + axis = unitVec.get128(); + sincosf4(radians.get128(), &s, &c); + xxxx = vec_splat(axis, 0); + yyyy = vec_splat(axis, 1); + zzzz = vec_splat(axis, 2); + oneMinusC = vec_sub(_mm_set1_ps(1.0f), c); + axisS = vec_mul(axis, s); + negAxisS = negatef4(axisS); VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; - //tmp0 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_XZBX ); - tmp0 = _mm_shuffle_ps( axisS, axisS, _MM_SHUFFLE(0,0,2,0) ); + //tmp0 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_XZBX ); + tmp0 = _mm_shuffle_ps(axisS, axisS, _MM_SHUFFLE(0, 0, 2, 0)); tmp0 = vec_sel(tmp0, vec_splat(negAxisS, 1), select_z); - //tmp1 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_CXXX ); - tmp1 = vec_sel( vec_splat(axisS, 0), vec_splat(negAxisS, 2), select_x ); - //tmp2 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_YAXX ); - tmp2 = _mm_shuffle_ps( axisS, axisS, _MM_SHUFFLE(0,0,0,1) ); + //tmp1 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_CXXX ); + tmp1 = vec_sel(vec_splat(axisS, 0), vec_splat(negAxisS, 2), select_x); + //tmp2 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_YAXX ); + tmp2 = _mm_shuffle_ps(axisS, axisS, _MM_SHUFFLE(0, 0, 0, 1)); tmp2 = vec_sel(tmp2, vec_splat(negAxisS, 0), select_y); - tmp0 = vec_sel( tmp0, c, select_x ); - tmp1 = vec_sel( tmp1, c, select_y ); - tmp2 = vec_sel( tmp2, c, select_z ); - return Matrix3( - Vector3( vec_madd( vec_mul( axis, xxxx ), oneMinusC, tmp0 ) ), - Vector3( vec_madd( vec_mul( axis, yyyy ), oneMinusC, tmp1 ) ), - Vector3( vec_madd( vec_mul( axis, zzzz ), oneMinusC, tmp2 ) ) - ); + tmp0 = vec_sel(tmp0, c, select_x); + tmp1 = vec_sel(tmp1, c, select_y); + tmp2 = vec_sel(tmp2, c, select_z); + return Matrix3( + Vector3(vec_madd(vec_mul(axis, xxxx), oneMinusC, tmp0)), + Vector3(vec_madd(vec_mul(axis, yyyy), oneMinusC, tmp1)), + Vector3(vec_madd(vec_mul(axis, zzzz), oneMinusC, tmp2))); } -VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotation( const Quat &unitQuat ) +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::rotation(const Quat &unitQuat) { - return Matrix3( unitQuat ); + return Matrix3(unitQuat); } -VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::scale( const Vector3 &scaleVec ) +VECTORMATH_FORCE_INLINE const Matrix3 Matrix3::scale(const Vector3 &scaleVec) { - __m128 zero = _mm_setzero_ps(); + __m128 zero = _mm_setzero_ps(); VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; - return Matrix3( - Vector3( vec_sel( zero, scaleVec.get128(), select_x ) ), - Vector3( vec_sel( zero, scaleVec.get128(), select_y ) ), - Vector3( vec_sel( zero, scaleVec.get128(), select_z ) ) - ); + return Matrix3( + Vector3(vec_sel(zero, scaleVec.get128(), select_x)), + Vector3(vec_sel(zero, scaleVec.get128(), select_y)), + Vector3(vec_sel(zero, scaleVec.get128(), select_z))); } -VECTORMATH_FORCE_INLINE const Matrix3 appendScale( const Matrix3 & mat, const Vector3 &scaleVec ) +VECTORMATH_FORCE_INLINE const Matrix3 appendScale(const Matrix3 &mat, const Vector3 &scaleVec) { - return Matrix3( - ( mat.getCol0() * scaleVec.getX( ) ), - ( mat.getCol1() * scaleVec.getY( ) ), - ( mat.getCol2() * scaleVec.getZ( ) ) - ); + return Matrix3( + (mat.getCol0() * scaleVec.getX()), + (mat.getCol1() * scaleVec.getY()), + (mat.getCol2() * scaleVec.getZ())); } -VECTORMATH_FORCE_INLINE const Matrix3 prependScale( const Vector3 &scaleVec, const Matrix3 & mat ) +VECTORMATH_FORCE_INLINE const Matrix3 prependScale(const Vector3 &scaleVec, const Matrix3 &mat) { - return Matrix3( - mulPerElem( mat.getCol0(), scaleVec ), - mulPerElem( mat.getCol1(), scaleVec ), - mulPerElem( mat.getCol2(), scaleVec ) - ); + return Matrix3( + mulPerElem(mat.getCol0(), scaleVec), + mulPerElem(mat.getCol1(), scaleVec), + mulPerElem(mat.getCol2(), scaleVec)); } -VECTORMATH_FORCE_INLINE const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ) +VECTORMATH_FORCE_INLINE const Matrix3 select(const Matrix3 &mat0, const Matrix3 &mat1, bool select1) { - return Matrix3( - select( mat0.getCol0(), mat1.getCol0(), select1 ), - select( mat0.getCol1(), mat1.getCol1(), select1 ), - select( mat0.getCol2(), mat1.getCol2(), select1 ) - ); + return Matrix3( + select(mat0.getCol0(), mat1.getCol0(), select1), + select(mat0.getCol1(), mat1.getCol1(), select1), + select(mat0.getCol2(), mat1.getCol2(), select1)); } -VECTORMATH_FORCE_INLINE const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, const boolInVec &select1 ) +VECTORMATH_FORCE_INLINE const Matrix3 select(const Matrix3 &mat0, const Matrix3 &mat1, const boolInVec &select1) { - return Matrix3( - select( mat0.getCol0(), mat1.getCol0(), select1 ), - select( mat0.getCol1(), mat1.getCol1(), select1 ), - select( mat0.getCol2(), mat1.getCol2(), select1 ) - ); + return Matrix3( + select(mat0.getCol0(), mat1.getCol0(), select1), + select(mat0.getCol1(), mat1.getCol1(), select1), + select(mat0.getCol2(), mat1.getCol2(), select1)); } #ifdef _VECTORMATH_DEBUG -VECTORMATH_FORCE_INLINE void print( const Matrix3 & mat ) +VECTORMATH_FORCE_INLINE void print(const Matrix3 &mat) { - print( mat.getRow( 0 ) ); - print( mat.getRow( 1 ) ); - print( mat.getRow( 2 ) ); + print(mat.getRow(0)); + print(mat.getRow(1)); + print(mat.getRow(2)); } -VECTORMATH_FORCE_INLINE void print( const Matrix3 & mat, const char * name ) +VECTORMATH_FORCE_INLINE void print(const Matrix3 &mat, const char *name) { - printf("%s:\n", name); - print( mat ); + printf("%s:\n", name); + print(mat); } #endif -VECTORMATH_FORCE_INLINE Matrix4::Matrix4( const Matrix4 & mat ) +VECTORMATH_FORCE_INLINE Matrix4::Matrix4(const Matrix4 &mat) { - mCol0 = mat.mCol0; - mCol1 = mat.mCol1; - mCol2 = mat.mCol2; - mCol3 = mat.mCol3; + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + mCol3 = mat.mCol3; } -VECTORMATH_FORCE_INLINE Matrix4::Matrix4( float scalar ) +VECTORMATH_FORCE_INLINE Matrix4::Matrix4(float scalar) { - mCol0 = Vector4( scalar ); - mCol1 = Vector4( scalar ); - mCol2 = Vector4( scalar ); - mCol3 = Vector4( scalar ); + mCol0 = Vector4(scalar); + mCol1 = Vector4(scalar); + mCol2 = Vector4(scalar); + mCol3 = Vector4(scalar); } -VECTORMATH_FORCE_INLINE Matrix4::Matrix4( const floatInVec &scalar ) +VECTORMATH_FORCE_INLINE Matrix4::Matrix4(const floatInVec &scalar) { - mCol0 = Vector4( scalar ); - mCol1 = Vector4( scalar ); - mCol2 = Vector4( scalar ); - mCol3 = Vector4( scalar ); + mCol0 = Vector4(scalar); + mCol1 = Vector4(scalar); + mCol2 = Vector4(scalar); + mCol3 = Vector4(scalar); } -VECTORMATH_FORCE_INLINE Matrix4::Matrix4( const Transform3 & mat ) +VECTORMATH_FORCE_INLINE Matrix4::Matrix4(const Transform3 &mat) { - mCol0 = Vector4( mat.getCol0(), 0.0f ); - mCol1 = Vector4( mat.getCol1(), 0.0f ); - mCol2 = Vector4( mat.getCol2(), 0.0f ); - mCol3 = Vector4( mat.getCol3(), 1.0f ); + mCol0 = Vector4(mat.getCol0(), 0.0f); + mCol1 = Vector4(mat.getCol1(), 0.0f); + mCol2 = Vector4(mat.getCol2(), 0.0f); + mCol3 = Vector4(mat.getCol3(), 1.0f); } -VECTORMATH_FORCE_INLINE Matrix4::Matrix4( const Vector4 &_col0, const Vector4 &_col1, const Vector4 &_col2, const Vector4 &_col3 ) +VECTORMATH_FORCE_INLINE Matrix4::Matrix4(const Vector4 &_col0, const Vector4 &_col1, const Vector4 &_col2, const Vector4 &_col3) { - mCol0 = _col0; - mCol1 = _col1; - mCol2 = _col2; - mCol3 = _col3; + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; + mCol3 = _col3; } -VECTORMATH_FORCE_INLINE Matrix4::Matrix4( const Matrix3 & mat, const Vector3 &translateVec ) +VECTORMATH_FORCE_INLINE Matrix4::Matrix4(const Matrix3 &mat, const Vector3 &translateVec) { - mCol0 = Vector4( mat.getCol0(), 0.0f ); - mCol1 = Vector4( mat.getCol1(), 0.0f ); - mCol2 = Vector4( mat.getCol2(), 0.0f ); - mCol3 = Vector4( translateVec, 1.0f ); + mCol0 = Vector4(mat.getCol0(), 0.0f); + mCol1 = Vector4(mat.getCol1(), 0.0f); + mCol2 = Vector4(mat.getCol2(), 0.0f); + mCol3 = Vector4(translateVec, 1.0f); } -VECTORMATH_FORCE_INLINE Matrix4::Matrix4( const Quat &unitQuat, const Vector3 &translateVec ) +VECTORMATH_FORCE_INLINE Matrix4::Matrix4(const Quat &unitQuat, const Vector3 &translateVec) { - Matrix3 mat; - mat = Matrix3( unitQuat ); - mCol0 = Vector4( mat.getCol0(), 0.0f ); - mCol1 = Vector4( mat.getCol1(), 0.0f ); - mCol2 = Vector4( mat.getCol2(), 0.0f ); - mCol3 = Vector4( translateVec, 1.0f ); + Matrix3 mat; + mat = Matrix3(unitQuat); + mCol0 = Vector4(mat.getCol0(), 0.0f); + mCol1 = Vector4(mat.getCol1(), 0.0f); + mCol2 = Vector4(mat.getCol2(), 0.0f); + mCol3 = Vector4(translateVec, 1.0f); } -VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setCol0( const Vector4 &_col0 ) +VECTORMATH_FORCE_INLINE Matrix4 &Matrix4::setCol0(const Vector4 &_col0) { - mCol0 = _col0; - return *this; + mCol0 = _col0; + return *this; } -VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setCol1( const Vector4 &_col1 ) +VECTORMATH_FORCE_INLINE Matrix4 &Matrix4::setCol1(const Vector4 &_col1) { - mCol1 = _col1; - return *this; + mCol1 = _col1; + return *this; } -VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setCol2( const Vector4 &_col2 ) +VECTORMATH_FORCE_INLINE Matrix4 &Matrix4::setCol2(const Vector4 &_col2) { - mCol2 = _col2; - return *this; + mCol2 = _col2; + return *this; } -VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setCol3( const Vector4 &_col3 ) +VECTORMATH_FORCE_INLINE Matrix4 &Matrix4::setCol3(const Vector4 &_col3) { - mCol3 = _col3; - return *this; + mCol3 = _col3; + return *this; } -VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setCol( int col, const Vector4 &vec ) +VECTORMATH_FORCE_INLINE Matrix4 &Matrix4::setCol(int col, const Vector4 &vec) { - *(&mCol0 + col) = vec; - return *this; + *(&mCol0 + col) = vec; + return *this; } -VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setRow( int row, const Vector4 &vec ) +VECTORMATH_FORCE_INLINE Matrix4 &Matrix4::setRow(int row, const Vector4 &vec) { - mCol0.setElem( row, vec.getElem( 0 ) ); - mCol1.setElem( row, vec.getElem( 1 ) ); - mCol2.setElem( row, vec.getElem( 2 ) ); - mCol3.setElem( row, vec.getElem( 3 ) ); - return *this; + mCol0.setElem(row, vec.getElem(0)); + mCol1.setElem(row, vec.getElem(1)); + mCol2.setElem(row, vec.getElem(2)); + mCol3.setElem(row, vec.getElem(3)); + return *this; } -VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setElem( int col, int row, float val ) +VECTORMATH_FORCE_INLINE Matrix4 &Matrix4::setElem(int col, int row, float val) { - (*this)[col].setElem(row, val); - return *this; + (*this)[col].setElem(row, val); + return *this; } -VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setElem( int col, int row, const floatInVec &val ) +VECTORMATH_FORCE_INLINE Matrix4 &Matrix4::setElem(int col, int row, const floatInVec &val) { - Vector4 tmpV3_0; - tmpV3_0 = this->getCol( col ); - tmpV3_0.setElem( row, val ); - this->setCol( col, tmpV3_0 ); - return *this; + Vector4 tmpV3_0; + tmpV3_0 = this->getCol(col); + tmpV3_0.setElem(row, val); + this->setCol(col, tmpV3_0); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Matrix4::getElem( int col, int row ) const +VECTORMATH_FORCE_INLINE const floatInVec Matrix4::getElem(int col, int row) const { - return this->getCol( col ).getElem( row ); + return this->getCol(col).getElem(row); } -VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getCol0( ) const +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getCol0() const { - return mCol0; + return mCol0; } -VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getCol1( ) const +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getCol1() const { - return mCol1; + return mCol1; } -VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getCol2( ) const +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getCol2() const { - return mCol2; + return mCol2; } -VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getCol3( ) const +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getCol3() const { - return mCol3; + return mCol3; } -VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getCol( int col ) const +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getCol(int col) const { - return *(&mCol0 + col); + return *(&mCol0 + col); } -VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getRow( int row ) const +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::getRow(int row) const { - return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); + return Vector4(mCol0.getElem(row), mCol1.getElem(row), mCol2.getElem(row), mCol3.getElem(row)); } -VECTORMATH_FORCE_INLINE Vector4 & Matrix4::operator []( int col ) +VECTORMATH_FORCE_INLINE Vector4 &Matrix4::operator[](int col) { - return *(&mCol0 + col); + return *(&mCol0 + col); } -VECTORMATH_FORCE_INLINE const Vector4 Matrix4::operator []( int col ) const +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::operator[](int col) const { - return *(&mCol0 + col); + return *(&mCol0 + col); } -VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator =( const Matrix4 & mat ) +VECTORMATH_FORCE_INLINE Matrix4 &Matrix4::operator=(const Matrix4 &mat) { - mCol0 = mat.mCol0; - mCol1 = mat.mCol1; - mCol2 = mat.mCol2; - mCol3 = mat.mCol3; - return *this; + mCol0 = mat.mCol0; + mCol1 = mat.mCol1; + mCol2 = mat.mCol2; + mCol3 = mat.mCol3; + return *this; } -VECTORMATH_FORCE_INLINE const Matrix4 transpose( const Matrix4 & mat ) +VECTORMATH_FORCE_INLINE const Matrix4 transpose(const Matrix4 &mat) { - __m128 tmp0, tmp1, tmp2, tmp3, res0, res1, res2, res3; - tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() ); - tmp1 = vec_mergeh( mat.getCol1().get128(), mat.getCol3().get128() ); - tmp2 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() ); - tmp3 = vec_mergel( mat.getCol1().get128(), mat.getCol3().get128() ); - res0 = vec_mergeh( tmp0, tmp1 ); - res1 = vec_mergel( tmp0, tmp1 ); - res2 = vec_mergeh( tmp2, tmp3 ); - res3 = vec_mergel( tmp2, tmp3 ); - return Matrix4( - Vector4( res0 ), - Vector4( res1 ), - Vector4( res2 ), - Vector4( res3 ) - ); + __m128 tmp0, tmp1, tmp2, tmp3, res0, res1, res2, res3; + tmp0 = vec_mergeh(mat.getCol0().get128(), mat.getCol2().get128()); + tmp1 = vec_mergeh(mat.getCol1().get128(), mat.getCol3().get128()); + tmp2 = vec_mergel(mat.getCol0().get128(), mat.getCol2().get128()); + tmp3 = vec_mergel(mat.getCol1().get128(), mat.getCol3().get128()); + res0 = vec_mergeh(tmp0, tmp1); + res1 = vec_mergel(tmp0, tmp1); + res2 = vec_mergeh(tmp2, tmp3); + res3 = vec_mergel(tmp2, tmp3); + return Matrix4( + Vector4(res0), + Vector4(res1), + Vector4(res2), + Vector4(res3)); } // TODO: Tidy @@ -791,12 +770,12 @@ static VM_ATTRIBUTE_ALIGN16 const unsigned int _vmathPNPN[4] = {0x00000000, 0x80 static VM_ATTRIBUTE_ALIGN16 const unsigned int _vmathNPNP[4] = {0x80000000, 0x00000000, 0x80000000, 0x00000000}; static VM_ATTRIBUTE_ALIGN16 const float _vmathZERONE[4] = {1.0f, 0.0f, 0.0f, 1.0f}; -VECTORMATH_FORCE_INLINE const Matrix4 inverse( const Matrix4 & mat ) +VECTORMATH_FORCE_INLINE const Matrix4 inverse(const Matrix4 &mat) { - __m128 Va,Vb,Vc; - __m128 r1,r2,r3,tt,tt2; - __m128 sum,Det,RDet; - __m128 trns0,trns1,trns2,trns3; + __m128 Va, Vb, Vc; + __m128 r1, r2, r3, tt, tt2; + __m128 sum, Det, RDet; + __m128 trns0, trns1, trns2, trns3; __m128 _L1 = mat.getCol0().get128(); __m128 _L2 = mat.getCol1().get128(); @@ -805,56 +784,66 @@ VECTORMATH_FORCE_INLINE const Matrix4 inverse( const Matrix4 & mat ) // Calculating the minterms for the first line. // _mm_ror_ps is just a macro using _mm_shuffle_ps(). - tt = _L4; tt2 = _mm_ror_ps(_L3,1); - Vc = _mm_mul_ps(tt2,_mm_ror_ps(tt,0)); // V3'dot V4 - Va = _mm_mul_ps(tt2,_mm_ror_ps(tt,2)); // V3'dot V4" - Vb = _mm_mul_ps(tt2,_mm_ror_ps(tt,3)); // V3' dot V4^ + tt = _L4; + tt2 = _mm_ror_ps(_L3, 1); + Vc = _mm_mul_ps(tt2, _mm_ror_ps(tt, 0)); // V3'dot V4 + Va = _mm_mul_ps(tt2, _mm_ror_ps(tt, 2)); // V3'dot V4" + Vb = _mm_mul_ps(tt2, _mm_ror_ps(tt, 3)); // V3' dot V4^ - r1 = _mm_sub_ps(_mm_ror_ps(Va,1),_mm_ror_ps(Vc,2)); // V3" dot V4^ - V3^ dot V4" - r2 = _mm_sub_ps(_mm_ror_ps(Vb,2),_mm_ror_ps(Vb,0)); // V3^ dot V4' - V3' dot V4^ - r3 = _mm_sub_ps(_mm_ror_ps(Va,0),_mm_ror_ps(Vc,1)); // V3' dot V4" - V3" dot V4' + r1 = _mm_sub_ps(_mm_ror_ps(Va, 1), _mm_ror_ps(Vc, 2)); // V3" dot V4^ - V3^ dot V4" + r2 = _mm_sub_ps(_mm_ror_ps(Vb, 2), _mm_ror_ps(Vb, 0)); // V3^ dot V4' - V3' dot V4^ + r3 = _mm_sub_ps(_mm_ror_ps(Va, 0), _mm_ror_ps(Vc, 1)); // V3' dot V4" - V3" dot V4' tt = _L2; - Va = _mm_ror_ps(tt,1); sum = _mm_mul_ps(Va,r1); - Vb = _mm_ror_ps(tt,2); sum = _mm_add_ps(sum,_mm_mul_ps(Vb,r2)); - Vc = _mm_ror_ps(tt,3); sum = _mm_add_ps(sum,_mm_mul_ps(Vc,r3)); + Va = _mm_ror_ps(tt, 1); + sum = _mm_mul_ps(Va, r1); + Vb = _mm_ror_ps(tt, 2); + sum = _mm_add_ps(sum, _mm_mul_ps(Vb, r2)); + Vc = _mm_ror_ps(tt, 3); + sum = _mm_add_ps(sum, _mm_mul_ps(Vc, r3)); // Calculating the determinant. - Det = _mm_mul_ps(sum,_L1); - Det = _mm_add_ps(Det,_mm_movehl_ps(Det,Det)); + Det = _mm_mul_ps(sum, _L1); + Det = _mm_add_ps(Det, _mm_movehl_ps(Det, Det)); const __m128 Sign_PNPN = _mm_load_ps((float *)_vmathPNPN); const __m128 Sign_NPNP = _mm_load_ps((float *)_vmathNPNP); - __m128 mtL1 = _mm_xor_ps(sum,Sign_PNPN); + __m128 mtL1 = _mm_xor_ps(sum, Sign_PNPN); // Calculating the minterms of the second line (using previous results). - tt = _mm_ror_ps(_L1,1); sum = _mm_mul_ps(tt,r1); - tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2)); - tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3)); - __m128 mtL2 = _mm_xor_ps(sum,Sign_NPNP); + tt = _mm_ror_ps(_L1, 1); + sum = _mm_mul_ps(tt, r1); + tt = _mm_ror_ps(tt, 1); + sum = _mm_add_ps(sum, _mm_mul_ps(tt, r2)); + tt = _mm_ror_ps(tt, 1); + sum = _mm_add_ps(sum, _mm_mul_ps(tt, r3)); + __m128 mtL2 = _mm_xor_ps(sum, Sign_NPNP); // Testing the determinant. - Det = _mm_sub_ss(Det,_mm_shuffle_ps(Det,Det,1)); + Det = _mm_sub_ss(Det, _mm_shuffle_ps(Det, Det, 1)); // Calculating the minterms of the third line. - tt = _mm_ror_ps(_L1,1); - Va = _mm_mul_ps(tt,Vb); // V1' dot V2" - Vb = _mm_mul_ps(tt,Vc); // V1' dot V2^ - Vc = _mm_mul_ps(tt,_L2); // V1' dot V2 + tt = _mm_ror_ps(_L1, 1); + Va = _mm_mul_ps(tt, Vb); // V1' dot V2" + Vb = _mm_mul_ps(tt, Vc); // V1' dot V2^ + Vc = _mm_mul_ps(tt, _L2); // V1' dot V2 - r1 = _mm_sub_ps(_mm_ror_ps(Va,1),_mm_ror_ps(Vc,2)); // V1" dot V2^ - V1^ dot V2" - r2 = _mm_sub_ps(_mm_ror_ps(Vb,2),_mm_ror_ps(Vb,0)); // V1^ dot V2' - V1' dot V2^ - r3 = _mm_sub_ps(_mm_ror_ps(Va,0),_mm_ror_ps(Vc,1)); // V1' dot V2" - V1" dot V2' + r1 = _mm_sub_ps(_mm_ror_ps(Va, 1), _mm_ror_ps(Vc, 2)); // V1" dot V2^ - V1^ dot V2" + r2 = _mm_sub_ps(_mm_ror_ps(Vb, 2), _mm_ror_ps(Vb, 0)); // V1^ dot V2' - V1' dot V2^ + r3 = _mm_sub_ps(_mm_ror_ps(Va, 0), _mm_ror_ps(Vc, 1)); // V1' dot V2" - V1" dot V2' - tt = _mm_ror_ps(_L4,1); sum = _mm_mul_ps(tt,r1); - tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2)); - tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3)); - __m128 mtL3 = _mm_xor_ps(sum,Sign_PNPN); + tt = _mm_ror_ps(_L4, 1); + sum = _mm_mul_ps(tt, r1); + tt = _mm_ror_ps(tt, 1); + sum = _mm_add_ps(sum, _mm_mul_ps(tt, r2)); + tt = _mm_ror_ps(tt, 1); + sum = _mm_add_ps(sum, _mm_mul_ps(tt, r3)); + __m128 mtL3 = _mm_xor_ps(sum, Sign_PNPN); // Dividing is FASTER than rcp_nr! (Because rcp_nr causes many register-memory RWs). - RDet = _mm_div_ss(_mm_load_ss((float *)&_vmathZERONE), Det); // TODO: just 1.0f? - RDet = _mm_shuffle_ps(RDet,RDet,0x00); + RDet = _mm_div_ss(_mm_load_ss((float *)&_vmathZERONE), Det); // TODO: just 1.0f? + RDet = _mm_shuffle_ps(RDet, RDet, 0x00); // Devide the first 12 minterms with the determinant. mtL1 = _mm_mul_ps(mtL1, RDet); @@ -862,55 +851,57 @@ VECTORMATH_FORCE_INLINE const Matrix4 inverse( const Matrix4 & mat ) mtL3 = _mm_mul_ps(mtL3, RDet); // Calculate the minterms of the forth line and devide by the determinant. - tt = _mm_ror_ps(_L3,1); sum = _mm_mul_ps(tt,r1); - tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2)); - tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3)); - __m128 mtL4 = _mm_xor_ps(sum,Sign_NPNP); + tt = _mm_ror_ps(_L3, 1); + sum = _mm_mul_ps(tt, r1); + tt = _mm_ror_ps(tt, 1); + sum = _mm_add_ps(sum, _mm_mul_ps(tt, r2)); + tt = _mm_ror_ps(tt, 1); + sum = _mm_add_ps(sum, _mm_mul_ps(tt, r3)); + __m128 mtL4 = _mm_xor_ps(sum, Sign_NPNP); mtL4 = _mm_mul_ps(mtL4, RDet); // Now we just have to transpose the minterms matrix. - trns0 = _mm_unpacklo_ps(mtL1,mtL2); - trns1 = _mm_unpacklo_ps(mtL3,mtL4); - trns2 = _mm_unpackhi_ps(mtL1,mtL2); - trns3 = _mm_unpackhi_ps(mtL3,mtL4); - _L1 = _mm_movelh_ps(trns0,trns1); - _L2 = _mm_movehl_ps(trns1,trns0); - _L3 = _mm_movelh_ps(trns2,trns3); - _L4 = _mm_movehl_ps(trns3,trns2); + trns0 = _mm_unpacklo_ps(mtL1, mtL2); + trns1 = _mm_unpacklo_ps(mtL3, mtL4); + trns2 = _mm_unpackhi_ps(mtL1, mtL2); + trns3 = _mm_unpackhi_ps(mtL3, mtL4); + _L1 = _mm_movelh_ps(trns0, trns1); + _L2 = _mm_movehl_ps(trns1, trns0); + _L3 = _mm_movelh_ps(trns2, trns3); + _L4 = _mm_movehl_ps(trns3, trns2); - return Matrix4( - Vector4( _L1 ), - Vector4( _L2 ), - Vector4( _L3 ), - Vector4( _L4 ) - ); + return Matrix4( + Vector4(_L1), + Vector4(_L2), + Vector4(_L3), + Vector4(_L4)); } -VECTORMATH_FORCE_INLINE const Matrix4 affineInverse( const Matrix4 & mat ) +VECTORMATH_FORCE_INLINE const Matrix4 affineInverse(const Matrix4 &mat) { - Transform3 affineMat; - affineMat.setCol0( mat.getCol0().getXYZ( ) ); - affineMat.setCol1( mat.getCol1().getXYZ( ) ); - affineMat.setCol2( mat.getCol2().getXYZ( ) ); - affineMat.setCol3( mat.getCol3().getXYZ( ) ); - return Matrix4( inverse( affineMat ) ); + Transform3 affineMat; + affineMat.setCol0(mat.getCol0().getXYZ()); + affineMat.setCol1(mat.getCol1().getXYZ()); + affineMat.setCol2(mat.getCol2().getXYZ()); + affineMat.setCol3(mat.getCol3().getXYZ()); + return Matrix4(inverse(affineMat)); } -VECTORMATH_FORCE_INLINE const Matrix4 orthoInverse( const Matrix4 & mat ) +VECTORMATH_FORCE_INLINE const Matrix4 orthoInverse(const Matrix4 &mat) { - Transform3 affineMat; - affineMat.setCol0( mat.getCol0().getXYZ( ) ); - affineMat.setCol1( mat.getCol1().getXYZ( ) ); - affineMat.setCol2( mat.getCol2().getXYZ( ) ); - affineMat.setCol3( mat.getCol3().getXYZ( ) ); - return Matrix4( orthoInverse( affineMat ) ); + Transform3 affineMat; + affineMat.setCol0(mat.getCol0().getXYZ()); + affineMat.setCol1(mat.getCol1().getXYZ()); + affineMat.setCol2(mat.getCol2().getXYZ()); + affineMat.setCol3(mat.getCol3().getXYZ()); + return Matrix4(orthoInverse(affineMat)); } -VECTORMATH_FORCE_INLINE const floatInVec determinant( const Matrix4 & mat ) +VECTORMATH_FORCE_INLINE const floatInVec determinant(const Matrix4 &mat) { - __m128 Va,Vb,Vc; - __m128 r1,r2,r3,tt,tt2; - __m128 sum,Det; + __m128 Va, Vb, Vc; + __m128 r1, r2, r3, tt, tt2; + __m128 sum, Det; __m128 _L1 = mat.getCol0().get128(); __m128 _L2 = mat.getCol1().get128(); @@ -919,1272 +910,1240 @@ VECTORMATH_FORCE_INLINE const floatInVec determinant( const Matrix4 & mat ) // Calculating the minterms for the first line. // _mm_ror_ps is just a macro using _mm_shuffle_ps(). - tt = _L4; tt2 = _mm_ror_ps(_L3,1); - Vc = _mm_mul_ps(tt2,_mm_ror_ps(tt,0)); // V3' dot V4 - Va = _mm_mul_ps(tt2,_mm_ror_ps(tt,2)); // V3' dot V4" - Vb = _mm_mul_ps(tt2,_mm_ror_ps(tt,3)); // V3' dot V4^ + tt = _L4; + tt2 = _mm_ror_ps(_L3, 1); + Vc = _mm_mul_ps(tt2, _mm_ror_ps(tt, 0)); // V3' dot V4 + Va = _mm_mul_ps(tt2, _mm_ror_ps(tt, 2)); // V3' dot V4" + Vb = _mm_mul_ps(tt2, _mm_ror_ps(tt, 3)); // V3' dot V4^ - r1 = _mm_sub_ps(_mm_ror_ps(Va,1),_mm_ror_ps(Vc,2)); // V3" dot V4^ - V3^ dot V4" - r2 = _mm_sub_ps(_mm_ror_ps(Vb,2),_mm_ror_ps(Vb,0)); // V3^ dot V4' - V3' dot V4^ - r3 = _mm_sub_ps(_mm_ror_ps(Va,0),_mm_ror_ps(Vc,1)); // V3' dot V4" - V3" dot V4' + r1 = _mm_sub_ps(_mm_ror_ps(Va, 1), _mm_ror_ps(Vc, 2)); // V3" dot V4^ - V3^ dot V4" + r2 = _mm_sub_ps(_mm_ror_ps(Vb, 2), _mm_ror_ps(Vb, 0)); // V3^ dot V4' - V3' dot V4^ + r3 = _mm_sub_ps(_mm_ror_ps(Va, 0), _mm_ror_ps(Vc, 1)); // V3' dot V4" - V3" dot V4' tt = _L2; - Va = _mm_ror_ps(tt,1); sum = _mm_mul_ps(Va,r1); - Vb = _mm_ror_ps(tt,2); sum = _mm_add_ps(sum,_mm_mul_ps(Vb,r2)); - Vc = _mm_ror_ps(tt,3); sum = _mm_add_ps(sum,_mm_mul_ps(Vc,r3)); + Va = _mm_ror_ps(tt, 1); + sum = _mm_mul_ps(Va, r1); + Vb = _mm_ror_ps(tt, 2); + sum = _mm_add_ps(sum, _mm_mul_ps(Vb, r2)); + Vc = _mm_ror_ps(tt, 3); + sum = _mm_add_ps(sum, _mm_mul_ps(Vc, r3)); // Calculating the determinant. - Det = _mm_mul_ps(sum,_L1); - Det = _mm_add_ps(Det,_mm_movehl_ps(Det,Det)); + Det = _mm_mul_ps(sum, _L1); + Det = _mm_add_ps(Det, _mm_movehl_ps(Det, Det)); // Calculating the minterms of the second line (using previous results). - tt = _mm_ror_ps(_L1,1); sum = _mm_mul_ps(tt,r1); - tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r2)); - tt = _mm_ror_ps(tt,1); sum = _mm_add_ps(sum,_mm_mul_ps(tt,r3)); + tt = _mm_ror_ps(_L1, 1); + sum = _mm_mul_ps(tt, r1); + tt = _mm_ror_ps(tt, 1); + sum = _mm_add_ps(sum, _mm_mul_ps(tt, r2)); + tt = _mm_ror_ps(tt, 1); + sum = _mm_add_ps(sum, _mm_mul_ps(tt, r3)); // Testing the determinant. - Det = _mm_sub_ss(Det,_mm_shuffle_ps(Det,Det,1)); + Det = _mm_sub_ss(Det, _mm_shuffle_ps(Det, Det, 1)); return floatInVec(Det, 0); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator +( const Matrix4 & mat ) const +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator+(const Matrix4 &mat) const { - return Matrix4( - ( mCol0 + mat.mCol0 ), - ( mCol1 + mat.mCol1 ), - ( mCol2 + mat.mCol2 ), - ( mCol3 + mat.mCol3 ) - ); + return Matrix4( + (mCol0 + mat.mCol0), + (mCol1 + mat.mCol1), + (mCol2 + mat.mCol2), + (mCol3 + mat.mCol3)); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator -( const Matrix4 & mat ) const +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator-(const Matrix4 &mat) const { - return Matrix4( - ( mCol0 - mat.mCol0 ), - ( mCol1 - mat.mCol1 ), - ( mCol2 - mat.mCol2 ), - ( mCol3 - mat.mCol3 ) - ); + return Matrix4( + (mCol0 - mat.mCol0), + (mCol1 - mat.mCol1), + (mCol2 - mat.mCol2), + (mCol3 - mat.mCol3)); } -VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator +=( const Matrix4 & mat ) +VECTORMATH_FORCE_INLINE Matrix4 &Matrix4::operator+=(const Matrix4 &mat) { - *this = *this + mat; - return *this; + *this = *this + mat; + return *this; } -VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator -=( const Matrix4 & mat ) +VECTORMATH_FORCE_INLINE Matrix4 &Matrix4::operator-=(const Matrix4 &mat) { - *this = *this - mat; - return *this; + *this = *this - mat; + return *this; } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator -( ) const +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator-() const { - return Matrix4( - ( -mCol0 ), - ( -mCol1 ), - ( -mCol2 ), - ( -mCol3 ) - ); + return Matrix4( + (-mCol0), + (-mCol1), + (-mCol2), + (-mCol3)); } -VECTORMATH_FORCE_INLINE const Matrix4 absPerElem( const Matrix4 & mat ) +VECTORMATH_FORCE_INLINE const Matrix4 absPerElem(const Matrix4 &mat) { - return Matrix4( - absPerElem( mat.getCol0() ), - absPerElem( mat.getCol1() ), - absPerElem( mat.getCol2() ), - absPerElem( mat.getCol3() ) - ); + return Matrix4( + absPerElem(mat.getCol0()), + absPerElem(mat.getCol1()), + absPerElem(mat.getCol2()), + absPerElem(mat.getCol3())); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator *( float scalar ) const +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator*(float scalar) const { - return *this * floatInVec(scalar); + return *this * floatInVec(scalar); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator *( const floatInVec &scalar ) const +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator*(const floatInVec &scalar) const { - return Matrix4( - ( mCol0 * scalar ), - ( mCol1 * scalar ), - ( mCol2 * scalar ), - ( mCol3 * scalar ) - ); + return Matrix4( + (mCol0 * scalar), + (mCol1 * scalar), + (mCol2 * scalar), + (mCol3 * scalar)); } -VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator *=( float scalar ) +VECTORMATH_FORCE_INLINE Matrix4 &Matrix4::operator*=(float scalar) { - return *this *= floatInVec(scalar); + return *this *= floatInVec(scalar); } -VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator *=( const floatInVec &scalar ) +VECTORMATH_FORCE_INLINE Matrix4 &Matrix4::operator*=(const floatInVec &scalar) { - *this = *this * scalar; - return *this; + *this = *this * scalar; + return *this; } -VECTORMATH_FORCE_INLINE const Matrix4 operator *( float scalar, const Matrix4 & mat ) +VECTORMATH_FORCE_INLINE const Matrix4 operator*(float scalar, const Matrix4 &mat) { - return floatInVec(scalar) * mat; + return floatInVec(scalar) * mat; } -VECTORMATH_FORCE_INLINE const Matrix4 operator *( const floatInVec &scalar, const Matrix4 & mat ) +VECTORMATH_FORCE_INLINE const Matrix4 operator*(const floatInVec &scalar, const Matrix4 &mat) { - return mat * scalar; + return mat * scalar; } -VECTORMATH_FORCE_INLINE const Vector4 Matrix4::operator *( const Vector4 &vec ) const +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::operator*(const Vector4 &vec) const { - return Vector4( + return Vector4( _mm_add_ps( - _mm_add_ps(_mm_mul_ps(mCol0.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(0,0,0,0))), _mm_mul_ps(mCol1.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(1,1,1,1)))), - _mm_add_ps(_mm_mul_ps(mCol2.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(2,2,2,2))), _mm_mul_ps(mCol3.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(3,3,3,3))))) - ); + _mm_add_ps(_mm_mul_ps(mCol0.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(0, 0, 0, 0))), _mm_mul_ps(mCol1.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(1, 1, 1, 1)))), + _mm_add_ps(_mm_mul_ps(mCol2.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(2, 2, 2, 2))), _mm_mul_ps(mCol3.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(3, 3, 3, 3)))))); } -VECTORMATH_FORCE_INLINE const Vector4 Matrix4::operator *( const Vector3 &vec ) const +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::operator*(const Vector3 &vec) const { - return Vector4( + return Vector4( _mm_add_ps( - _mm_add_ps(_mm_mul_ps(mCol0.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(0,0,0,0))), _mm_mul_ps(mCol1.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(1,1,1,1)))), - _mm_mul_ps(mCol2.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(2,2,2,2)))) - ); + _mm_add_ps(_mm_mul_ps(mCol0.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(0, 0, 0, 0))), _mm_mul_ps(mCol1.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(1, 1, 1, 1)))), + _mm_mul_ps(mCol2.get128(), _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(2, 2, 2, 2))))); } -VECTORMATH_FORCE_INLINE const Vector4 Matrix4::operator *( const Point3 &pnt ) const +VECTORMATH_FORCE_INLINE const Vector4 Matrix4::operator*(const Point3 &pnt) const { - return Vector4( + return Vector4( _mm_add_ps( - _mm_add_ps(_mm_mul_ps(mCol0.get128(), _mm_shuffle_ps(pnt.get128(), pnt.get128(), _MM_SHUFFLE(0,0,0,0))), _mm_mul_ps(mCol1.get128(), _mm_shuffle_ps(pnt.get128(), pnt.get128(), _MM_SHUFFLE(1,1,1,1)))), - _mm_add_ps(_mm_mul_ps(mCol2.get128(), _mm_shuffle_ps(pnt.get128(), pnt.get128(), _MM_SHUFFLE(2,2,2,2))), mCol3.get128())) - ); + _mm_add_ps(_mm_mul_ps(mCol0.get128(), _mm_shuffle_ps(pnt.get128(), pnt.get128(), _MM_SHUFFLE(0, 0, 0, 0))), _mm_mul_ps(mCol1.get128(), _mm_shuffle_ps(pnt.get128(), pnt.get128(), _MM_SHUFFLE(1, 1, 1, 1)))), + _mm_add_ps(_mm_mul_ps(mCol2.get128(), _mm_shuffle_ps(pnt.get128(), pnt.get128(), _MM_SHUFFLE(2, 2, 2, 2))), mCol3.get128()))); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator *( const Matrix4 & mat ) const +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator*(const Matrix4 &mat) const { - return Matrix4( - ( *this * mat.mCol0 ), - ( *this * mat.mCol1 ), - ( *this * mat.mCol2 ), - ( *this * mat.mCol3 ) - ); + return Matrix4( + (*this * mat.mCol0), + (*this * mat.mCol1), + (*this * mat.mCol2), + (*this * mat.mCol3)); } -VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator *=( const Matrix4 & mat ) +VECTORMATH_FORCE_INLINE Matrix4 &Matrix4::operator*=(const Matrix4 &mat) { - *this = *this * mat; - return *this; + *this = *this * mat; + return *this; } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator *( const Transform3 & tfrm ) const +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::operator*(const Transform3 &tfrm) const { - return Matrix4( - ( *this * tfrm.getCol0() ), - ( *this * tfrm.getCol1() ), - ( *this * tfrm.getCol2() ), - ( *this * Point3( tfrm.getCol3() ) ) - ); + return Matrix4( + (*this * tfrm.getCol0()), + (*this * tfrm.getCol1()), + (*this * tfrm.getCol2()), + (*this * Point3(tfrm.getCol3()))); } -VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::operator *=( const Transform3 & tfrm ) +VECTORMATH_FORCE_INLINE Matrix4 &Matrix4::operator*=(const Transform3 &tfrm) { - *this = *this * tfrm; - return *this; + *this = *this * tfrm; + return *this; } -VECTORMATH_FORCE_INLINE const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ) +VECTORMATH_FORCE_INLINE const Matrix4 mulPerElem(const Matrix4 &mat0, const Matrix4 &mat1) { - return Matrix4( - mulPerElem( mat0.getCol0(), mat1.getCol0() ), - mulPerElem( mat0.getCol1(), mat1.getCol1() ), - mulPerElem( mat0.getCol2(), mat1.getCol2() ), - mulPerElem( mat0.getCol3(), mat1.getCol3() ) - ); + return Matrix4( + mulPerElem(mat0.getCol0(), mat1.getCol0()), + mulPerElem(mat0.getCol1(), mat1.getCol1()), + mulPerElem(mat0.getCol2(), mat1.getCol2()), + mulPerElem(mat0.getCol3(), mat1.getCol3())); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::identity( ) +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::identity() { - return Matrix4( - Vector4::xAxis( ), - Vector4::yAxis( ), - Vector4::zAxis( ), - Vector4::wAxis( ) - ); + return Matrix4( + Vector4::xAxis(), + Vector4::yAxis(), + Vector4::zAxis(), + Vector4::wAxis()); } -VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setUpper3x3( const Matrix3 & mat3 ) +VECTORMATH_FORCE_INLINE Matrix4 &Matrix4::setUpper3x3(const Matrix3 &mat3) { - mCol0.setXYZ( mat3.getCol0() ); - mCol1.setXYZ( mat3.getCol1() ); - mCol2.setXYZ( mat3.getCol2() ); - return *this; + mCol0.setXYZ(mat3.getCol0()); + mCol1.setXYZ(mat3.getCol1()); + mCol2.setXYZ(mat3.getCol2()); + return *this; } -VECTORMATH_FORCE_INLINE const Matrix3 Matrix4::getUpper3x3( ) const +VECTORMATH_FORCE_INLINE const Matrix3 Matrix4::getUpper3x3() const { - return Matrix3( - mCol0.getXYZ( ), - mCol1.getXYZ( ), - mCol2.getXYZ( ) - ); + return Matrix3( + mCol0.getXYZ(), + mCol1.getXYZ(), + mCol2.getXYZ()); } -VECTORMATH_FORCE_INLINE Matrix4 & Matrix4::setTranslation( const Vector3 &translateVec ) +VECTORMATH_FORCE_INLINE Matrix4 &Matrix4::setTranslation(const Vector3 &translateVec) { - mCol3.setXYZ( translateVec ); - return *this; + mCol3.setXYZ(translateVec); + return *this; } -VECTORMATH_FORCE_INLINE const Vector3 Matrix4::getTranslation( ) const +VECTORMATH_FORCE_INLINE const Vector3 Matrix4::getTranslation() const { - return mCol3.getXYZ( ); + return mCol3.getXYZ(); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationX( float radians ) +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationX(float radians) { - return rotationX( floatInVec(radians) ); + return rotationX(floatInVec(radians)); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationX( const floatInVec &radians ) +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationX(const floatInVec &radians) { - __m128 s, c, res1, res2; - __m128 zero; + __m128 s, c, res1, res2; + __m128 zero; VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; - zero = _mm_setzero_ps(); - sincosf4( radians.get128(), &s, &c ); - res1 = vec_sel( zero, c, select_y ); - res1 = vec_sel( res1, s, select_z ); - res2 = vec_sel( zero, negatef4(s), select_y ); - res2 = vec_sel( res2, c, select_z ); - return Matrix4( - Vector4::xAxis( ), - Vector4( res1 ), - Vector4( res2 ), - Vector4::wAxis( ) - ); + zero = _mm_setzero_ps(); + sincosf4(radians.get128(), &s, &c); + res1 = vec_sel(zero, c, select_y); + res1 = vec_sel(res1, s, select_z); + res2 = vec_sel(zero, negatef4(s), select_y); + res2 = vec_sel(res2, c, select_z); + return Matrix4( + Vector4::xAxis(), + Vector4(res1), + Vector4(res2), + Vector4::wAxis()); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationY( float radians ) +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationY(float radians) { - return rotationY( floatInVec(radians) ); + return rotationY(floatInVec(radians)); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationY( const floatInVec &radians ) +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationY(const floatInVec &radians) { - __m128 s, c, res0, res2; - __m128 zero; + __m128 s, c, res0, res2; + __m128 zero; VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; - zero = _mm_setzero_ps(); - sincosf4( radians.get128(), &s, &c ); - res0 = vec_sel( zero, c, select_x ); - res0 = vec_sel( res0, negatef4(s), select_z ); - res2 = vec_sel( zero, s, select_x ); - res2 = vec_sel( res2, c, select_z ); - return Matrix4( - Vector4( res0 ), - Vector4::yAxis( ), - Vector4( res2 ), - Vector4::wAxis( ) - ); + zero = _mm_setzero_ps(); + sincosf4(radians.get128(), &s, &c); + res0 = vec_sel(zero, c, select_x); + res0 = vec_sel(res0, negatef4(s), select_z); + res2 = vec_sel(zero, s, select_x); + res2 = vec_sel(res2, c, select_z); + return Matrix4( + Vector4(res0), + Vector4::yAxis(), + Vector4(res2), + Vector4::wAxis()); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationZ( float radians ) +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationZ(float radians) { - return rotationZ( floatInVec(radians) ); + return rotationZ(floatInVec(radians)); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationZ( const floatInVec &radians ) +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationZ(const floatInVec &radians) { - __m128 s, c, res0, res1; - __m128 zero; + __m128 s, c, res0, res1; + __m128 zero; VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; - zero = _mm_setzero_ps(); - sincosf4( radians.get128(), &s, &c ); - res0 = vec_sel( zero, c, select_x ); - res0 = vec_sel( res0, s, select_y ); - res1 = vec_sel( zero, negatef4(s), select_x ); - res1 = vec_sel( res1, c, select_y ); - return Matrix4( - Vector4( res0 ), - Vector4( res1 ), - Vector4::zAxis( ), - Vector4::wAxis( ) - ); + zero = _mm_setzero_ps(); + sincosf4(radians.get128(), &s, &c); + res0 = vec_sel(zero, c, select_x); + res0 = vec_sel(res0, s, select_y); + res1 = vec_sel(zero, negatef4(s), select_x); + res1 = vec_sel(res1, c, select_y); + return Matrix4( + Vector4(res0), + Vector4(res1), + Vector4::zAxis(), + Vector4::wAxis()); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationZYX( const Vector3 &radiansXYZ ) +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotationZYX(const Vector3 &radiansXYZ) { - __m128 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; - angles = Vector4( radiansXYZ, 0.0f ).get128(); - sincosf4( angles, &s, &c ); - negS = negatef4( s ); - Z0 = vec_mergel( c, s ); - Z1 = vec_mergel( negS, c ); + __m128 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; + angles = Vector4(radiansXYZ, 0.0f).get128(); + sincosf4(angles, &s, &c); + negS = negatef4(s); + Z0 = vec_mergel(c, s); + Z1 = vec_mergel(negS, c); VM_ATTRIBUTE_ALIGN16 unsigned int select_xyz[4] = {0xffffffff, 0xffffffff, 0xffffffff, 0}; - Z1 = vec_and( Z1, _mm_load_ps( (float *)select_xyz ) ); - Y0 = _mm_shuffle_ps( c, negS, _MM_SHUFFLE(0,1,1,1) ); - Y1 = _mm_shuffle_ps( s, c, _MM_SHUFFLE(0,1,1,1) ); - X0 = vec_splat( s, 0 ); - X1 = vec_splat( c, 0 ); - tmp = vec_mul( Z0, Y1 ); - return Matrix4( - Vector4( vec_mul( Z0, Y0 ) ), - Vector4( vec_madd( Z1, X1, vec_mul( tmp, X0 ) ) ), - Vector4( vec_nmsub( Z1, X0, vec_mul( tmp, X1 ) ) ), - Vector4::wAxis( ) - ); + Z1 = vec_and(Z1, _mm_load_ps((float *)select_xyz)); + Y0 = _mm_shuffle_ps(c, negS, _MM_SHUFFLE(0, 1, 1, 1)); + Y1 = _mm_shuffle_ps(s, c, _MM_SHUFFLE(0, 1, 1, 1)); + X0 = vec_splat(s, 0); + X1 = vec_splat(c, 0); + tmp = vec_mul(Z0, Y1); + return Matrix4( + Vector4(vec_mul(Z0, Y0)), + Vector4(vec_madd(Z1, X1, vec_mul(tmp, X0))), + Vector4(vec_nmsub(Z1, X0, vec_mul(tmp, X1))), + Vector4::wAxis()); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotation( float radians, const Vector3 &unitVec ) +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotation(float radians, const Vector3 &unitVec) { - return rotation( floatInVec(radians), unitVec ); + return rotation(floatInVec(radians), unitVec); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotation( const floatInVec &radians, const Vector3 &unitVec ) +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotation(const floatInVec &radians, const Vector3 &unitVec) { - __m128 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2; - axis = unitVec.get128(); - sincosf4( radians.get128(), &s, &c ); - xxxx = vec_splat( axis, 0 ); - yyyy = vec_splat( axis, 1 ); - zzzz = vec_splat( axis, 2 ); - oneMinusC = vec_sub( _mm_set1_ps(1.0f), c ); - axisS = vec_mul( axis, s ); - negAxisS = negatef4( axisS ); + __m128 axis, s, c, oneMinusC, axisS, negAxisS, xxxx, yyyy, zzzz, tmp0, tmp1, tmp2; + axis = unitVec.get128(); + sincosf4(radians.get128(), &s, &c); + xxxx = vec_splat(axis, 0); + yyyy = vec_splat(axis, 1); + zzzz = vec_splat(axis, 2); + oneMinusC = vec_sub(_mm_set1_ps(1.0f), c); + axisS = vec_mul(axis, s); + negAxisS = negatef4(axisS); VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; - //tmp0 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_XZBX ); - tmp0 = _mm_shuffle_ps( axisS, axisS, _MM_SHUFFLE(0,0,2,0) ); + //tmp0 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_XZBX ); + tmp0 = _mm_shuffle_ps(axisS, axisS, _MM_SHUFFLE(0, 0, 2, 0)); tmp0 = vec_sel(tmp0, vec_splat(negAxisS, 1), select_z); - //tmp1 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_CXXX ); - tmp1 = vec_sel( vec_splat(axisS, 0), vec_splat(negAxisS, 2), select_x ); - //tmp2 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_YAXX ); - tmp2 = _mm_shuffle_ps( axisS, axisS, _MM_SHUFFLE(0,0,0,1) ); + //tmp1 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_CXXX ); + tmp1 = vec_sel(vec_splat(axisS, 0), vec_splat(negAxisS, 2), select_x); + //tmp2 = vec_perm( axisS, negAxisS, _VECTORMATH_PERM_YAXX ); + tmp2 = _mm_shuffle_ps(axisS, axisS, _MM_SHUFFLE(0, 0, 0, 1)); tmp2 = vec_sel(tmp2, vec_splat(negAxisS, 0), select_y); - tmp0 = vec_sel( tmp0, c, select_x ); - tmp1 = vec_sel( tmp1, c, select_y ); - tmp2 = vec_sel( tmp2, c, select_z ); + tmp0 = vec_sel(tmp0, c, select_x); + tmp1 = vec_sel(tmp1, c, select_y); + tmp2 = vec_sel(tmp2, c, select_z); VM_ATTRIBUTE_ALIGN16 unsigned int select_xyz[4] = {0xffffffff, 0xffffffff, 0xffffffff, 0}; - axis = vec_and( axis, _mm_load_ps( (float *)select_xyz ) ); - tmp0 = vec_and( tmp0, _mm_load_ps( (float *)select_xyz ) ); - tmp1 = vec_and( tmp1, _mm_load_ps( (float *)select_xyz ) ); - tmp2 = vec_and( tmp2, _mm_load_ps( (float *)select_xyz ) ); - return Matrix4( - Vector4( vec_madd( vec_mul( axis, xxxx ), oneMinusC, tmp0 ) ), - Vector4( vec_madd( vec_mul( axis, yyyy ), oneMinusC, tmp1 ) ), - Vector4( vec_madd( vec_mul( axis, zzzz ), oneMinusC, tmp2 ) ), - Vector4::wAxis( ) - ); + axis = vec_and(axis, _mm_load_ps((float *)select_xyz)); + tmp0 = vec_and(tmp0, _mm_load_ps((float *)select_xyz)); + tmp1 = vec_and(tmp1, _mm_load_ps((float *)select_xyz)); + tmp2 = vec_and(tmp2, _mm_load_ps((float *)select_xyz)); + return Matrix4( + Vector4(vec_madd(vec_mul(axis, xxxx), oneMinusC, tmp0)), + Vector4(vec_madd(vec_mul(axis, yyyy), oneMinusC, tmp1)), + Vector4(vec_madd(vec_mul(axis, zzzz), oneMinusC, tmp2)), + Vector4::wAxis()); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotation( const Quat &unitQuat ) +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::rotation(const Quat &unitQuat) { - return Matrix4( Transform3::rotation( unitQuat ) ); + return Matrix4(Transform3::rotation(unitQuat)); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::scale( const Vector3 &scaleVec ) +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::scale(const Vector3 &scaleVec) { - __m128 zero = _mm_setzero_ps(); + __m128 zero = _mm_setzero_ps(); VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; - return Matrix4( - Vector4( vec_sel( zero, scaleVec.get128(), select_x ) ), - Vector4( vec_sel( zero, scaleVec.get128(), select_y ) ), - Vector4( vec_sel( zero, scaleVec.get128(), select_z ) ), - Vector4::wAxis( ) - ); + return Matrix4( + Vector4(vec_sel(zero, scaleVec.get128(), select_x)), + Vector4(vec_sel(zero, scaleVec.get128(), select_y)), + Vector4(vec_sel(zero, scaleVec.get128(), select_z)), + Vector4::wAxis()); } -VECTORMATH_FORCE_INLINE const Matrix4 appendScale( const Matrix4 & mat, const Vector3 &scaleVec ) +VECTORMATH_FORCE_INLINE const Matrix4 appendScale(const Matrix4 &mat, const Vector3 &scaleVec) { - return Matrix4( - ( mat.getCol0() * scaleVec.getX( ) ), - ( mat.getCol1() * scaleVec.getY( ) ), - ( mat.getCol2() * scaleVec.getZ( ) ), - mat.getCol3() - ); + return Matrix4( + (mat.getCol0() * scaleVec.getX()), + (mat.getCol1() * scaleVec.getY()), + (mat.getCol2() * scaleVec.getZ()), + mat.getCol3()); } -VECTORMATH_FORCE_INLINE const Matrix4 prependScale( const Vector3 &scaleVec, const Matrix4 & mat ) +VECTORMATH_FORCE_INLINE const Matrix4 prependScale(const Vector3 &scaleVec, const Matrix4 &mat) { - Vector4 scale4; - scale4 = Vector4( scaleVec, 1.0f ); - return Matrix4( - mulPerElem( mat.getCol0(), scale4 ), - mulPerElem( mat.getCol1(), scale4 ), - mulPerElem( mat.getCol2(), scale4 ), - mulPerElem( mat.getCol3(), scale4 ) - ); + Vector4 scale4; + scale4 = Vector4(scaleVec, 1.0f); + return Matrix4( + mulPerElem(mat.getCol0(), scale4), + mulPerElem(mat.getCol1(), scale4), + mulPerElem(mat.getCol2(), scale4), + mulPerElem(mat.getCol3(), scale4)); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::translation( const Vector3 &translateVec ) +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::translation(const Vector3 &translateVec) { - return Matrix4( - Vector4::xAxis( ), - Vector4::yAxis( ), - Vector4::zAxis( ), - Vector4( translateVec, 1.0f ) - ); + return Matrix4( + Vector4::xAxis(), + Vector4::yAxis(), + Vector4::zAxis(), + Vector4(translateVec, 1.0f)); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::lookAt( const Point3 &eyePos, const Point3 &lookAtPos, const Vector3 &upVec ) +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::lookAt(const Point3 &eyePos, const Point3 &lookAtPos, const Vector3 &upVec) { - Matrix4 m4EyeFrame; - Vector3 v3X, v3Y, v3Z; - v3Y = normalize( upVec ); - v3Z = normalize( ( eyePos - lookAtPos ) ); - v3X = normalize( cross( v3Y, v3Z ) ); - v3Y = cross( v3Z, v3X ); - m4EyeFrame = Matrix4( Vector4( v3X ), Vector4( v3Y ), Vector4( v3Z ), Vector4( eyePos ) ); - return orthoInverse( m4EyeFrame ); + Matrix4 m4EyeFrame; + Vector3 v3X, v3Y, v3Z; + v3Y = normalize(upVec); + v3Z = normalize((eyePos - lookAtPos)); + v3X = normalize(cross(v3Y, v3Z)); + v3Y = cross(v3Z, v3X); + m4EyeFrame = Matrix4(Vector4(v3X), Vector4(v3Y), Vector4(v3Z), Vector4(eyePos)); + return orthoInverse(m4EyeFrame); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::perspective( float fovyRadians, float aspect, float zNear, float zFar ) +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::perspective(float fovyRadians, float aspect, float zNear, float zFar) { - float f, rangeInv; - __m128 zero, col0, col1, col2, col3; - union { __m128 v; float s[4]; } tmp; - f = tanf( _VECTORMATH_PI_OVER_2 - fovyRadians * 0.5f ); - rangeInv = 1.0f / ( zNear - zFar ); - zero = _mm_setzero_ps(); - tmp.v = zero; - tmp.s[0] = f / aspect; - col0 = tmp.v; - tmp.v = zero; - tmp.s[1] = f; - col1 = tmp.v; - tmp.v = zero; - tmp.s[2] = ( zNear + zFar ) * rangeInv; - tmp.s[3] = -1.0f; - col2 = tmp.v; - tmp.v = zero; - tmp.s[2] = zNear * zFar * rangeInv * 2.0f; - col3 = tmp.v; - return Matrix4( - Vector4( col0 ), - Vector4( col1 ), - Vector4( col2 ), - Vector4( col3 ) - ); + float f, rangeInv; + __m128 zero, col0, col1, col2, col3; + union { + __m128 v; + float s[4]; + } tmp; + f = tanf(_VECTORMATH_PI_OVER_2 - fovyRadians * 0.5f); + rangeInv = 1.0f / (zNear - zFar); + zero = _mm_setzero_ps(); + tmp.v = zero; + tmp.s[0] = f / aspect; + col0 = tmp.v; + tmp.v = zero; + tmp.s[1] = f; + col1 = tmp.v; + tmp.v = zero; + tmp.s[2] = (zNear + zFar) * rangeInv; + tmp.s[3] = -1.0f; + col2 = tmp.v; + tmp.v = zero; + tmp.s[2] = zNear * zFar * rangeInv * 2.0f; + col3 = tmp.v; + return Matrix4( + Vector4(col0), + Vector4(col1), + Vector4(col2), + Vector4(col3)); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::frustum( float left, float right, float bottom, float top, float zNear, float zFar ) +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::frustum(float left, float right, float bottom, float top, float zNear, float zFar) { - /* function implementation based on code from STIDC SDK: */ - /* -------------------------------------------------------------- */ - /* PLEASE DO NOT MODIFY THIS SECTION */ - /* This prolog section is automatically generated. */ - /* */ - /* (C)Copyright */ - /* Sony Computer Entertainment, Inc., */ - /* Toshiba Corporation, */ - /* International Business Machines Corporation, */ - /* 2001,2002. */ - /* S/T/I Confidential Information */ - /* -------------------------------------------------------------- */ - __m128 lbf, rtn; - __m128 diff, sum, inv_diff; - __m128 diagonal, column, near2; - __m128 zero = _mm_setzero_ps(); - union { __m128 v; float s[4]; } l, f, r, n, b, t; // TODO: Union? - l.s[0] = left; - f.s[0] = zFar; - r.s[0] = right; - n.s[0] = zNear; - b.s[0] = bottom; - t.s[0] = top; - lbf = vec_mergeh( l.v, f.v ); - rtn = vec_mergeh( r.v, n.v ); - lbf = vec_mergeh( lbf, b.v ); - rtn = vec_mergeh( rtn, t.v ); - diff = vec_sub( rtn, lbf ); - sum = vec_add( rtn, lbf ); - inv_diff = recipf4( diff ); - near2 = vec_splat( n.v, 0 ); - near2 = vec_add( near2, near2 ); - diagonal = vec_mul( near2, inv_diff ); - column = vec_mul( sum, inv_diff ); + /* function implementation based on code from STIDC SDK: */ + /* -------------------------------------------------------------- */ + /* PLEASE DO NOT MODIFY THIS SECTION */ + /* This prolog section is automatically generated. */ + /* */ + /* (C)Copyright */ + /* Sony Computer Entertainment, Inc., */ + /* Toshiba Corporation, */ + /* International Business Machines Corporation, */ + /* 2001,2002. */ + /* S/T/I Confidential Information */ + /* -------------------------------------------------------------- */ + __m128 lbf, rtn; + __m128 diff, sum, inv_diff; + __m128 diagonal, column, near2; + __m128 zero = _mm_setzero_ps(); + union { + __m128 v; + float s[4]; + } l, f, r, n, b, t; // TODO: Union? + l.s[0] = left; + f.s[0] = zFar; + r.s[0] = right; + n.s[0] = zNear; + b.s[0] = bottom; + t.s[0] = top; + lbf = vec_mergeh(l.v, f.v); + rtn = vec_mergeh(r.v, n.v); + lbf = vec_mergeh(lbf, b.v); + rtn = vec_mergeh(rtn, t.v); + diff = vec_sub(rtn, lbf); + sum = vec_add(rtn, lbf); + inv_diff = recipf4(diff); + near2 = vec_splat(n.v, 0); + near2 = vec_add(near2, near2); + diagonal = vec_mul(near2, inv_diff); + column = vec_mul(sum, inv_diff); VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_w[4] = {0, 0, 0, 0xffffffff}; - return Matrix4( - Vector4( vec_sel( zero, diagonal, select_x ) ), - Vector4( vec_sel( zero, diagonal, select_y ) ), - Vector4( vec_sel( column, _mm_set1_ps(-1.0f), select_w ) ), - Vector4( vec_sel( zero, vec_mul( diagonal, vec_splat( f.v, 0 ) ), select_z ) ) - ); + return Matrix4( + Vector4(vec_sel(zero, diagonal, select_x)), + Vector4(vec_sel(zero, diagonal, select_y)), + Vector4(vec_sel(column, _mm_set1_ps(-1.0f), select_w)), + Vector4(vec_sel(zero, vec_mul(diagonal, vec_splat(f.v, 0)), select_z))); } -VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::orthographic( float left, float right, float bottom, float top, float zNear, float zFar ) +VECTORMATH_FORCE_INLINE const Matrix4 Matrix4::orthographic(float left, float right, float bottom, float top, float zNear, float zFar) { - /* function implementation based on code from STIDC SDK: */ - /* -------------------------------------------------------------- */ - /* PLEASE DO NOT MODIFY THIS SECTION */ - /* This prolog section is automatically generated. */ - /* */ - /* (C)Copyright */ - /* Sony Computer Entertainment, Inc., */ - /* Toshiba Corporation, */ - /* International Business Machines Corporation, */ - /* 2001,2002. */ - /* S/T/I Confidential Information */ - /* -------------------------------------------------------------- */ - __m128 lbf, rtn; - __m128 diff, sum, inv_diff, neg_inv_diff; - __m128 diagonal, column; - __m128 zero = _mm_setzero_ps(); - union { __m128 v; float s[4]; } l, f, r, n, b, t; - l.s[0] = left; - f.s[0] = zFar; - r.s[0] = right; - n.s[0] = zNear; - b.s[0] = bottom; - t.s[0] = top; - lbf = vec_mergeh( l.v, f.v ); - rtn = vec_mergeh( r.v, n.v ); - lbf = vec_mergeh( lbf, b.v ); - rtn = vec_mergeh( rtn, t.v ); - diff = vec_sub( rtn, lbf ); - sum = vec_add( rtn, lbf ); - inv_diff = recipf4( diff ); - neg_inv_diff = negatef4( inv_diff ); - diagonal = vec_add( inv_diff, inv_diff ); + /* function implementation based on code from STIDC SDK: */ + /* -------------------------------------------------------------- */ + /* PLEASE DO NOT MODIFY THIS SECTION */ + /* This prolog section is automatically generated. */ + /* */ + /* (C)Copyright */ + /* Sony Computer Entertainment, Inc., */ + /* Toshiba Corporation, */ + /* International Business Machines Corporation, */ + /* 2001,2002. */ + /* S/T/I Confidential Information */ + /* -------------------------------------------------------------- */ + __m128 lbf, rtn; + __m128 diff, sum, inv_diff, neg_inv_diff; + __m128 diagonal, column; + __m128 zero = _mm_setzero_ps(); + union { + __m128 v; + float s[4]; + } l, f, r, n, b, t; + l.s[0] = left; + f.s[0] = zFar; + r.s[0] = right; + n.s[0] = zNear; + b.s[0] = bottom; + t.s[0] = top; + lbf = vec_mergeh(l.v, f.v); + rtn = vec_mergeh(r.v, n.v); + lbf = vec_mergeh(lbf, b.v); + rtn = vec_mergeh(rtn, t.v); + diff = vec_sub(rtn, lbf); + sum = vec_add(rtn, lbf); + inv_diff = recipf4(diff); + neg_inv_diff = negatef4(inv_diff); + diagonal = vec_add(inv_diff, inv_diff); VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_w[4] = {0, 0, 0, 0xffffffff}; - column = vec_mul( sum, vec_sel( neg_inv_diff, inv_diff, select_z ) ); // TODO: no madds with zero - return Matrix4( - Vector4( vec_sel( zero, diagonal, select_x ) ), - Vector4( vec_sel( zero, diagonal, select_y ) ), - Vector4( vec_sel( zero, diagonal, select_z ) ), - Vector4( vec_sel( column, _mm_set1_ps(1.0f), select_w ) ) - ); + column = vec_mul(sum, vec_sel(neg_inv_diff, inv_diff, select_z)); // TODO: no madds with zero + return Matrix4( + Vector4(vec_sel(zero, diagonal, select_x)), + Vector4(vec_sel(zero, diagonal, select_y)), + Vector4(vec_sel(zero, diagonal, select_z)), + Vector4(vec_sel(column, _mm_set1_ps(1.0f), select_w))); } -VECTORMATH_FORCE_INLINE const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ) +VECTORMATH_FORCE_INLINE const Matrix4 select(const Matrix4 &mat0, const Matrix4 &mat1, bool select1) { - return Matrix4( - select( mat0.getCol0(), mat1.getCol0(), select1 ), - select( mat0.getCol1(), mat1.getCol1(), select1 ), - select( mat0.getCol2(), mat1.getCol2(), select1 ), - select( mat0.getCol3(), mat1.getCol3(), select1 ) - ); + return Matrix4( + select(mat0.getCol0(), mat1.getCol0(), select1), + select(mat0.getCol1(), mat1.getCol1(), select1), + select(mat0.getCol2(), mat1.getCol2(), select1), + select(mat0.getCol3(), mat1.getCol3(), select1)); } -VECTORMATH_FORCE_INLINE const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, const boolInVec &select1 ) +VECTORMATH_FORCE_INLINE const Matrix4 select(const Matrix4 &mat0, const Matrix4 &mat1, const boolInVec &select1) { - return Matrix4( - select( mat0.getCol0(), mat1.getCol0(), select1 ), - select( mat0.getCol1(), mat1.getCol1(), select1 ), - select( mat0.getCol2(), mat1.getCol2(), select1 ), - select( mat0.getCol3(), mat1.getCol3(), select1 ) - ); + return Matrix4( + select(mat0.getCol0(), mat1.getCol0(), select1), + select(mat0.getCol1(), mat1.getCol1(), select1), + select(mat0.getCol2(), mat1.getCol2(), select1), + select(mat0.getCol3(), mat1.getCol3(), select1)); } #ifdef _VECTORMATH_DEBUG -VECTORMATH_FORCE_INLINE void print( const Matrix4 & mat ) +VECTORMATH_FORCE_INLINE void print(const Matrix4 &mat) { - print( mat.getRow( 0 ) ); - print( mat.getRow( 1 ) ); - print( mat.getRow( 2 ) ); - print( mat.getRow( 3 ) ); + print(mat.getRow(0)); + print(mat.getRow(1)); + print(mat.getRow(2)); + print(mat.getRow(3)); } -VECTORMATH_FORCE_INLINE void print( const Matrix4 & mat, const char * name ) +VECTORMATH_FORCE_INLINE void print(const Matrix4 &mat, const char *name) { - printf("%s:\n", name); - print( mat ); + printf("%s:\n", name); + print(mat); } #endif -VECTORMATH_FORCE_INLINE Transform3::Transform3( const Transform3 & tfrm ) +VECTORMATH_FORCE_INLINE Transform3::Transform3(const Transform3 &tfrm) { - mCol0 = tfrm.mCol0; - mCol1 = tfrm.mCol1; - mCol2 = tfrm.mCol2; - mCol3 = tfrm.mCol3; + mCol0 = tfrm.mCol0; + mCol1 = tfrm.mCol1; + mCol2 = tfrm.mCol2; + mCol3 = tfrm.mCol3; } -VECTORMATH_FORCE_INLINE Transform3::Transform3( float scalar ) +VECTORMATH_FORCE_INLINE Transform3::Transform3(float scalar) { - mCol0 = Vector3( scalar ); - mCol1 = Vector3( scalar ); - mCol2 = Vector3( scalar ); - mCol3 = Vector3( scalar ); + mCol0 = Vector3(scalar); + mCol1 = Vector3(scalar); + mCol2 = Vector3(scalar); + mCol3 = Vector3(scalar); } -VECTORMATH_FORCE_INLINE Transform3::Transform3( const floatInVec &scalar ) +VECTORMATH_FORCE_INLINE Transform3::Transform3(const floatInVec &scalar) { - mCol0 = Vector3( scalar ); - mCol1 = Vector3( scalar ); - mCol2 = Vector3( scalar ); - mCol3 = Vector3( scalar ); + mCol0 = Vector3(scalar); + mCol1 = Vector3(scalar); + mCol2 = Vector3(scalar); + mCol3 = Vector3(scalar); } -VECTORMATH_FORCE_INLINE Transform3::Transform3( const Vector3 &_col0, const Vector3 &_col1, const Vector3 &_col2, const Vector3 &_col3 ) +VECTORMATH_FORCE_INLINE Transform3::Transform3(const Vector3 &_col0, const Vector3 &_col1, const Vector3 &_col2, const Vector3 &_col3) { - mCol0 = _col0; - mCol1 = _col1; - mCol2 = _col2; - mCol3 = _col3; + mCol0 = _col0; + mCol1 = _col1; + mCol2 = _col2; + mCol3 = _col3; } -VECTORMATH_FORCE_INLINE Transform3::Transform3( const Matrix3 & tfrm, const Vector3 &translateVec ) +VECTORMATH_FORCE_INLINE Transform3::Transform3(const Matrix3 &tfrm, const Vector3 &translateVec) { - this->setUpper3x3( tfrm ); - this->setTranslation( translateVec ); + this->setUpper3x3(tfrm); + this->setTranslation(translateVec); } -VECTORMATH_FORCE_INLINE Transform3::Transform3( const Quat &unitQuat, const Vector3 &translateVec ) +VECTORMATH_FORCE_INLINE Transform3::Transform3(const Quat &unitQuat, const Vector3 &translateVec) { - this->setUpper3x3( Matrix3( unitQuat ) ); - this->setTranslation( translateVec ); + this->setUpper3x3(Matrix3(unitQuat)); + this->setTranslation(translateVec); } -VECTORMATH_FORCE_INLINE Transform3 & Transform3::setCol0( const Vector3 &_col0 ) +VECTORMATH_FORCE_INLINE Transform3 &Transform3::setCol0(const Vector3 &_col0) { - mCol0 = _col0; - return *this; + mCol0 = _col0; + return *this; } -VECTORMATH_FORCE_INLINE Transform3 & Transform3::setCol1( const Vector3 &_col1 ) +VECTORMATH_FORCE_INLINE Transform3 &Transform3::setCol1(const Vector3 &_col1) { - mCol1 = _col1; - return *this; + mCol1 = _col1; + return *this; } -VECTORMATH_FORCE_INLINE Transform3 & Transform3::setCol2( const Vector3 &_col2 ) +VECTORMATH_FORCE_INLINE Transform3 &Transform3::setCol2(const Vector3 &_col2) { - mCol2 = _col2; - return *this; + mCol2 = _col2; + return *this; } -VECTORMATH_FORCE_INLINE Transform3 & Transform3::setCol3( const Vector3 &_col3 ) +VECTORMATH_FORCE_INLINE Transform3 &Transform3::setCol3(const Vector3 &_col3) { - mCol3 = _col3; - return *this; + mCol3 = _col3; + return *this; } -VECTORMATH_FORCE_INLINE Transform3 & Transform3::setCol( int col, const Vector3 &vec ) +VECTORMATH_FORCE_INLINE Transform3 &Transform3::setCol(int col, const Vector3 &vec) { - *(&mCol0 + col) = vec; - return *this; + *(&mCol0 + col) = vec; + return *this; } -VECTORMATH_FORCE_INLINE Transform3 & Transform3::setRow( int row, const Vector4 &vec ) +VECTORMATH_FORCE_INLINE Transform3 &Transform3::setRow(int row, const Vector4 &vec) { - mCol0.setElem( row, vec.getElem( 0 ) ); - mCol1.setElem( row, vec.getElem( 1 ) ); - mCol2.setElem( row, vec.getElem( 2 ) ); - mCol3.setElem( row, vec.getElem( 3 ) ); - return *this; + mCol0.setElem(row, vec.getElem(0)); + mCol1.setElem(row, vec.getElem(1)); + mCol2.setElem(row, vec.getElem(2)); + mCol3.setElem(row, vec.getElem(3)); + return *this; } -VECTORMATH_FORCE_INLINE Transform3 & Transform3::setElem( int col, int row, float val ) +VECTORMATH_FORCE_INLINE Transform3 &Transform3::setElem(int col, int row, float val) { - (*this)[col].setElem(row, val); - return *this; + (*this)[col].setElem(row, val); + return *this; } -VECTORMATH_FORCE_INLINE Transform3 & Transform3::setElem( int col, int row, const floatInVec &val ) +VECTORMATH_FORCE_INLINE Transform3 &Transform3::setElem(int col, int row, const floatInVec &val) { - Vector3 tmpV3_0; - tmpV3_0 = this->getCol( col ); - tmpV3_0.setElem( row, val ); - this->setCol( col, tmpV3_0 ); - return *this; + Vector3 tmpV3_0; + tmpV3_0 = this->getCol(col); + tmpV3_0.setElem(row, val); + this->setCol(col, tmpV3_0); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Transform3::getElem( int col, int row ) const +VECTORMATH_FORCE_INLINE const floatInVec Transform3::getElem(int col, int row) const { - return this->getCol( col ).getElem( row ); + return this->getCol(col).getElem(row); } -VECTORMATH_FORCE_INLINE const Vector3 Transform3::getCol0( ) const +VECTORMATH_FORCE_INLINE const Vector3 Transform3::getCol0() const { - return mCol0; + return mCol0; } -VECTORMATH_FORCE_INLINE const Vector3 Transform3::getCol1( ) const +VECTORMATH_FORCE_INLINE const Vector3 Transform3::getCol1() const { - return mCol1; + return mCol1; } -VECTORMATH_FORCE_INLINE const Vector3 Transform3::getCol2( ) const +VECTORMATH_FORCE_INLINE const Vector3 Transform3::getCol2() const { - return mCol2; + return mCol2; } -VECTORMATH_FORCE_INLINE const Vector3 Transform3::getCol3( ) const +VECTORMATH_FORCE_INLINE const Vector3 Transform3::getCol3() const { - return mCol3; + return mCol3; } -VECTORMATH_FORCE_INLINE const Vector3 Transform3::getCol( int col ) const +VECTORMATH_FORCE_INLINE const Vector3 Transform3::getCol(int col) const { - return *(&mCol0 + col); + return *(&mCol0 + col); } -VECTORMATH_FORCE_INLINE const Vector4 Transform3::getRow( int row ) const +VECTORMATH_FORCE_INLINE const Vector4 Transform3::getRow(int row) const { - return Vector4( mCol0.getElem( row ), mCol1.getElem( row ), mCol2.getElem( row ), mCol3.getElem( row ) ); + return Vector4(mCol0.getElem(row), mCol1.getElem(row), mCol2.getElem(row), mCol3.getElem(row)); } -VECTORMATH_FORCE_INLINE Vector3 & Transform3::operator []( int col ) +VECTORMATH_FORCE_INLINE Vector3 &Transform3::operator[](int col) { - return *(&mCol0 + col); + return *(&mCol0 + col); } -VECTORMATH_FORCE_INLINE const Vector3 Transform3::operator []( int col ) const +VECTORMATH_FORCE_INLINE const Vector3 Transform3::operator[](int col) const { - return *(&mCol0 + col); + return *(&mCol0 + col); } -VECTORMATH_FORCE_INLINE Transform3 & Transform3::operator =( const Transform3 & tfrm ) +VECTORMATH_FORCE_INLINE Transform3 &Transform3::operator=(const Transform3 &tfrm) { - mCol0 = tfrm.mCol0; - mCol1 = tfrm.mCol1; - mCol2 = tfrm.mCol2; - mCol3 = tfrm.mCol3; - return *this; + mCol0 = tfrm.mCol0; + mCol1 = tfrm.mCol1; + mCol2 = tfrm.mCol2; + mCol3 = tfrm.mCol3; + return *this; } -VECTORMATH_FORCE_INLINE const Transform3 inverse( const Transform3 & tfrm ) +VECTORMATH_FORCE_INLINE const Transform3 inverse(const Transform3 &tfrm) { - __m128 inv0, inv1, inv2, inv3; - __m128 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet; - __m128 xxxx, yyyy, zzzz; - tmp2 = _vmathVfCross( tfrm.getCol0().get128(), tfrm.getCol1().get128() ); - tmp0 = _vmathVfCross( tfrm.getCol1().get128(), tfrm.getCol2().get128() ); - tmp1 = _vmathVfCross( tfrm.getCol2().get128(), tfrm.getCol0().get128() ); - inv3 = negatef4( tfrm.getCol3().get128() ); - dot = _vmathVfDot3( tmp2, tfrm.getCol2().get128() ); - dot = vec_splat( dot, 0 ); - invdet = recipf4( dot ); - tmp3 = vec_mergeh( tmp0, tmp2 ); - tmp4 = vec_mergel( tmp0, tmp2 ); - inv0 = vec_mergeh( tmp3, tmp1 ); - xxxx = vec_splat( inv3, 0 ); - //inv1 = vec_perm( tmp3, tmp1, _VECTORMATH_PERM_ZBWX ); + __m128 inv0, inv1, inv2, inv3; + __m128 tmp0, tmp1, tmp2, tmp3, tmp4, dot, invdet; + __m128 xxxx, yyyy, zzzz; + tmp2 = _vmathVfCross(tfrm.getCol0().get128(), tfrm.getCol1().get128()); + tmp0 = _vmathVfCross(tfrm.getCol1().get128(), tfrm.getCol2().get128()); + tmp1 = _vmathVfCross(tfrm.getCol2().get128(), tfrm.getCol0().get128()); + inv3 = negatef4(tfrm.getCol3().get128()); + dot = _vmathVfDot3(tmp2, tfrm.getCol2().get128()); + dot = vec_splat(dot, 0); + invdet = recipf4(dot); + tmp3 = vec_mergeh(tmp0, tmp2); + tmp4 = vec_mergel(tmp0, tmp2); + inv0 = vec_mergeh(tmp3, tmp1); + xxxx = vec_splat(inv3, 0); + //inv1 = vec_perm( tmp3, tmp1, _VECTORMATH_PERM_ZBWX ); VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; - inv1 = _mm_shuffle_ps( tmp3, tmp3, _MM_SHUFFLE(0,3,2,2)); + inv1 = _mm_shuffle_ps(tmp3, tmp3, _MM_SHUFFLE(0, 3, 2, 2)); inv1 = vec_sel(inv1, tmp1, select_y); - //inv2 = vec_perm( tmp4, tmp1, _VECTORMATH_PERM_XCYX ); - inv2 = _mm_shuffle_ps( tmp4, tmp4, _MM_SHUFFLE(0,1,1,0)); + //inv2 = vec_perm( tmp4, tmp1, _VECTORMATH_PERM_XCYX ); + inv2 = _mm_shuffle_ps(tmp4, tmp4, _MM_SHUFFLE(0, 1, 1, 0)); inv2 = vec_sel(inv2, vec_splat(tmp1, 2), select_y); - yyyy = vec_splat( inv3, 1 ); - zzzz = vec_splat( inv3, 2 ); - inv3 = vec_mul( inv0, xxxx ); - inv3 = vec_madd( inv1, yyyy, inv3 ); - inv3 = vec_madd( inv2, zzzz, inv3 ); - inv0 = vec_mul( inv0, invdet ); - inv1 = vec_mul( inv1, invdet ); - inv2 = vec_mul( inv2, invdet ); - inv3 = vec_mul( inv3, invdet ); - return Transform3( - Vector3( inv0 ), - Vector3( inv1 ), - Vector3( inv2 ), - Vector3( inv3 ) - ); + yyyy = vec_splat(inv3, 1); + zzzz = vec_splat(inv3, 2); + inv3 = vec_mul(inv0, xxxx); + inv3 = vec_madd(inv1, yyyy, inv3); + inv3 = vec_madd(inv2, zzzz, inv3); + inv0 = vec_mul(inv0, invdet); + inv1 = vec_mul(inv1, invdet); + inv2 = vec_mul(inv2, invdet); + inv3 = vec_mul(inv3, invdet); + return Transform3( + Vector3(inv0), + Vector3(inv1), + Vector3(inv2), + Vector3(inv3)); } -VECTORMATH_FORCE_INLINE const Transform3 orthoInverse( const Transform3 & tfrm ) +VECTORMATH_FORCE_INLINE const Transform3 orthoInverse(const Transform3 &tfrm) { - __m128 inv0, inv1, inv2, inv3; - __m128 tmp0, tmp1; - __m128 xxxx, yyyy, zzzz; - tmp0 = vec_mergeh( tfrm.getCol0().get128(), tfrm.getCol2().get128() ); - tmp1 = vec_mergel( tfrm.getCol0().get128(), tfrm.getCol2().get128() ); - inv3 = negatef4( tfrm.getCol3().get128() ); - inv0 = vec_mergeh( tmp0, tfrm.getCol1().get128() ); - xxxx = vec_splat( inv3, 0 ); - //inv1 = vec_perm( tmp0, tfrm.getCol1().get128(), _VECTORMATH_PERM_ZBWX ); + __m128 inv0, inv1, inv2, inv3; + __m128 tmp0, tmp1; + __m128 xxxx, yyyy, zzzz; + tmp0 = vec_mergeh(tfrm.getCol0().get128(), tfrm.getCol2().get128()); + tmp1 = vec_mergel(tfrm.getCol0().get128(), tfrm.getCol2().get128()); + inv3 = negatef4(tfrm.getCol3().get128()); + inv0 = vec_mergeh(tmp0, tfrm.getCol1().get128()); + xxxx = vec_splat(inv3, 0); + //inv1 = vec_perm( tmp0, tfrm.getCol1().get128(), _VECTORMATH_PERM_ZBWX ); VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; - inv1 = _mm_shuffle_ps( tmp0, tmp0, _MM_SHUFFLE(0,3,2,2)); + inv1 = _mm_shuffle_ps(tmp0, tmp0, _MM_SHUFFLE(0, 3, 2, 2)); inv1 = vec_sel(inv1, tfrm.getCol1().get128(), select_y); - //inv2 = vec_perm( tmp1, tfrm.getCol1().get128(), _VECTORMATH_PERM_XCYX ); - inv2 = _mm_shuffle_ps( tmp1, tmp1, _MM_SHUFFLE(0,1,1,0)); + //inv2 = vec_perm( tmp1, tfrm.getCol1().get128(), _VECTORMATH_PERM_XCYX ); + inv2 = _mm_shuffle_ps(tmp1, tmp1, _MM_SHUFFLE(0, 1, 1, 0)); inv2 = vec_sel(inv2, vec_splat(tfrm.getCol1().get128(), 2), select_y); - yyyy = vec_splat( inv3, 1 ); - zzzz = vec_splat( inv3, 2 ); - inv3 = vec_mul( inv0, xxxx ); - inv3 = vec_madd( inv1, yyyy, inv3 ); - inv3 = vec_madd( inv2, zzzz, inv3 ); - return Transform3( - Vector3( inv0 ), - Vector3( inv1 ), - Vector3( inv2 ), - Vector3( inv3 ) - ); + yyyy = vec_splat(inv3, 1); + zzzz = vec_splat(inv3, 2); + inv3 = vec_mul(inv0, xxxx); + inv3 = vec_madd(inv1, yyyy, inv3); + inv3 = vec_madd(inv2, zzzz, inv3); + return Transform3( + Vector3(inv0), + Vector3(inv1), + Vector3(inv2), + Vector3(inv3)); } -VECTORMATH_FORCE_INLINE const Transform3 absPerElem( const Transform3 & tfrm ) +VECTORMATH_FORCE_INLINE const Transform3 absPerElem(const Transform3 &tfrm) { - return Transform3( - absPerElem( tfrm.getCol0() ), - absPerElem( tfrm.getCol1() ), - absPerElem( tfrm.getCol2() ), - absPerElem( tfrm.getCol3() ) - ); + return Transform3( + absPerElem(tfrm.getCol0()), + absPerElem(tfrm.getCol1()), + absPerElem(tfrm.getCol2()), + absPerElem(tfrm.getCol3())); } -VECTORMATH_FORCE_INLINE const Vector3 Transform3::operator *( const Vector3 &vec ) const +VECTORMATH_FORCE_INLINE const Vector3 Transform3::operator*(const Vector3 &vec) const { - __m128 res; - __m128 xxxx, yyyy, zzzz; - xxxx = vec_splat( vec.get128(), 0 ); - yyyy = vec_splat( vec.get128(), 1 ); - zzzz = vec_splat( vec.get128(), 2 ); - res = vec_mul( mCol0.get128(), xxxx ); - res = vec_madd( mCol1.get128(), yyyy, res ); - res = vec_madd( mCol2.get128(), zzzz, res ); - return Vector3( res ); + __m128 res; + __m128 xxxx, yyyy, zzzz; + xxxx = vec_splat(vec.get128(), 0); + yyyy = vec_splat(vec.get128(), 1); + zzzz = vec_splat(vec.get128(), 2); + res = vec_mul(mCol0.get128(), xxxx); + res = vec_madd(mCol1.get128(), yyyy, res); + res = vec_madd(mCol2.get128(), zzzz, res); + return Vector3(res); } -VECTORMATH_FORCE_INLINE const Point3 Transform3::operator *( const Point3 &pnt ) const +VECTORMATH_FORCE_INLINE const Point3 Transform3::operator*(const Point3 &pnt) const { - __m128 tmp0, tmp1, res; - __m128 xxxx, yyyy, zzzz; - xxxx = vec_splat( pnt.get128(), 0 ); - yyyy = vec_splat( pnt.get128(), 1 ); - zzzz = vec_splat( pnt.get128(), 2 ); - tmp0 = vec_mul( mCol0.get128(), xxxx ); - tmp1 = vec_mul( mCol1.get128(), yyyy ); - tmp0 = vec_madd( mCol2.get128(), zzzz, tmp0 ); - tmp1 = vec_add( mCol3.get128(), tmp1 ); - res = vec_add( tmp0, tmp1 ); - return Point3( res ); + __m128 tmp0, tmp1, res; + __m128 xxxx, yyyy, zzzz; + xxxx = vec_splat(pnt.get128(), 0); + yyyy = vec_splat(pnt.get128(), 1); + zzzz = vec_splat(pnt.get128(), 2); + tmp0 = vec_mul(mCol0.get128(), xxxx); + tmp1 = vec_mul(mCol1.get128(), yyyy); + tmp0 = vec_madd(mCol2.get128(), zzzz, tmp0); + tmp1 = vec_add(mCol3.get128(), tmp1); + res = vec_add(tmp0, tmp1); + return Point3(res); } -VECTORMATH_FORCE_INLINE const Transform3 Transform3::operator *( const Transform3 & tfrm ) const +VECTORMATH_FORCE_INLINE const Transform3 Transform3::operator*(const Transform3 &tfrm) const { - return Transform3( - ( *this * tfrm.mCol0 ), - ( *this * tfrm.mCol1 ), - ( *this * tfrm.mCol2 ), - Vector3( ( *this * Point3( tfrm.mCol3 ) ) ) - ); + return Transform3( + (*this * tfrm.mCol0), + (*this * tfrm.mCol1), + (*this * tfrm.mCol2), + Vector3((*this * Point3(tfrm.mCol3)))); } -VECTORMATH_FORCE_INLINE Transform3 & Transform3::operator *=( const Transform3 & tfrm ) +VECTORMATH_FORCE_INLINE Transform3 &Transform3::operator*=(const Transform3 &tfrm) { - *this = *this * tfrm; - return *this; + *this = *this * tfrm; + return *this; } -VECTORMATH_FORCE_INLINE const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ) +VECTORMATH_FORCE_INLINE const Transform3 mulPerElem(const Transform3 &tfrm0, const Transform3 &tfrm1) { - return Transform3( - mulPerElem( tfrm0.getCol0(), tfrm1.getCol0() ), - mulPerElem( tfrm0.getCol1(), tfrm1.getCol1() ), - mulPerElem( tfrm0.getCol2(), tfrm1.getCol2() ), - mulPerElem( tfrm0.getCol3(), tfrm1.getCol3() ) - ); + return Transform3( + mulPerElem(tfrm0.getCol0(), tfrm1.getCol0()), + mulPerElem(tfrm0.getCol1(), tfrm1.getCol1()), + mulPerElem(tfrm0.getCol2(), tfrm1.getCol2()), + mulPerElem(tfrm0.getCol3(), tfrm1.getCol3())); } -VECTORMATH_FORCE_INLINE const Transform3 Transform3::identity( ) +VECTORMATH_FORCE_INLINE const Transform3 Transform3::identity() { - return Transform3( - Vector3::xAxis( ), - Vector3::yAxis( ), - Vector3::zAxis( ), - Vector3( 0.0f ) - ); + return Transform3( + Vector3::xAxis(), + Vector3::yAxis(), + Vector3::zAxis(), + Vector3(0.0f)); } -VECTORMATH_FORCE_INLINE Transform3 & Transform3::setUpper3x3( const Matrix3 & tfrm ) +VECTORMATH_FORCE_INLINE Transform3 &Transform3::setUpper3x3(const Matrix3 &tfrm) { - mCol0 = tfrm.getCol0(); - mCol1 = tfrm.getCol1(); - mCol2 = tfrm.getCol2(); - return *this; + mCol0 = tfrm.getCol0(); + mCol1 = tfrm.getCol1(); + mCol2 = tfrm.getCol2(); + return *this; } -VECTORMATH_FORCE_INLINE const Matrix3 Transform3::getUpper3x3( ) const +VECTORMATH_FORCE_INLINE const Matrix3 Transform3::getUpper3x3() const { - return Matrix3( mCol0, mCol1, mCol2 ); + return Matrix3(mCol0, mCol1, mCol2); } -VECTORMATH_FORCE_INLINE Transform3 & Transform3::setTranslation( const Vector3 &translateVec ) +VECTORMATH_FORCE_INLINE Transform3 &Transform3::setTranslation(const Vector3 &translateVec) { - mCol3 = translateVec; - return *this; + mCol3 = translateVec; + return *this; } -VECTORMATH_FORCE_INLINE const Vector3 Transform3::getTranslation( ) const +VECTORMATH_FORCE_INLINE const Vector3 Transform3::getTranslation() const { - return mCol3; + return mCol3; } -VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationX( float radians ) +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationX(float radians) { - return rotationX( floatInVec(radians) ); + return rotationX(floatInVec(radians)); } -VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationX( const floatInVec &radians ) +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationX(const floatInVec &radians) { - __m128 s, c, res1, res2; - __m128 zero; + __m128 s, c, res1, res2; + __m128 zero; VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; - zero = _mm_setzero_ps(); - sincosf4( radians.get128(), &s, &c ); - res1 = vec_sel( zero, c, select_y ); - res1 = vec_sel( res1, s, select_z ); - res2 = vec_sel( zero, negatef4(s), select_y ); - res2 = vec_sel( res2, c, select_z ); - return Transform3( - Vector3::xAxis( ), - Vector3( res1 ), - Vector3( res2 ), - Vector3( _mm_setzero_ps() ) - ); + zero = _mm_setzero_ps(); + sincosf4(radians.get128(), &s, &c); + res1 = vec_sel(zero, c, select_y); + res1 = vec_sel(res1, s, select_z); + res2 = vec_sel(zero, negatef4(s), select_y); + res2 = vec_sel(res2, c, select_z); + return Transform3( + Vector3::xAxis(), + Vector3(res1), + Vector3(res2), + Vector3(_mm_setzero_ps())); } -VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationY( float radians ) +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationY(float radians) { - return rotationY( floatInVec(radians) ); + return rotationY(floatInVec(radians)); } -VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationY( const floatInVec &radians ) +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationY(const floatInVec &radians) { - __m128 s, c, res0, res2; - __m128 zero; + __m128 s, c, res0, res2; + __m128 zero; VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; - zero = _mm_setzero_ps(); - sincosf4( radians.get128(), &s, &c ); - res0 = vec_sel( zero, c, select_x ); - res0 = vec_sel( res0, negatef4(s), select_z ); - res2 = vec_sel( zero, s, select_x ); - res2 = vec_sel( res2, c, select_z ); - return Transform3( - Vector3( res0 ), - Vector3::yAxis( ), - Vector3( res2 ), - Vector3( 0.0f ) - ); + zero = _mm_setzero_ps(); + sincosf4(radians.get128(), &s, &c); + res0 = vec_sel(zero, c, select_x); + res0 = vec_sel(res0, negatef4(s), select_z); + res2 = vec_sel(zero, s, select_x); + res2 = vec_sel(res2, c, select_z); + return Transform3( + Vector3(res0), + Vector3::yAxis(), + Vector3(res2), + Vector3(0.0f)); } -VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationZ( float radians ) +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationZ(float radians) { - return rotationZ( floatInVec(radians) ); + return rotationZ(floatInVec(radians)); } -VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationZ( const floatInVec &radians ) +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationZ(const floatInVec &radians) { - __m128 s, c, res0, res1; + __m128 s, c, res0, res1; VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; - __m128 zero = _mm_setzero_ps(); - sincosf4( radians.get128(), &s, &c ); - res0 = vec_sel( zero, c, select_x ); - res0 = vec_sel( res0, s, select_y ); - res1 = vec_sel( zero, negatef4(s), select_x ); - res1 = vec_sel( res1, c, select_y ); - return Transform3( - Vector3( res0 ), - Vector3( res1 ), - Vector3::zAxis( ), - Vector3( 0.0f ) - ); + __m128 zero = _mm_setzero_ps(); + sincosf4(radians.get128(), &s, &c); + res0 = vec_sel(zero, c, select_x); + res0 = vec_sel(res0, s, select_y); + res1 = vec_sel(zero, negatef4(s), select_x); + res1 = vec_sel(res1, c, select_y); + return Transform3( + Vector3(res0), + Vector3(res1), + Vector3::zAxis(), + Vector3(0.0f)); } -VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationZYX( const Vector3 &radiansXYZ ) +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotationZYX(const Vector3 &radiansXYZ) { - __m128 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; - angles = Vector4( radiansXYZ, 0.0f ).get128(); - sincosf4( angles, &s, &c ); - negS = negatef4( s ); - Z0 = vec_mergel( c, s ); - Z1 = vec_mergel( negS, c ); + __m128 angles, s, negS, c, X0, X1, Y0, Y1, Z0, Z1, tmp; + angles = Vector4(radiansXYZ, 0.0f).get128(); + sincosf4(angles, &s, &c); + negS = negatef4(s); + Z0 = vec_mergel(c, s); + Z1 = vec_mergel(negS, c); VM_ATTRIBUTE_ALIGN16 unsigned int select_xyz[4] = {0xffffffff, 0xffffffff, 0xffffffff, 0}; - Z1 = vec_and( Z1, _mm_load_ps( (float *)select_xyz ) ); - Y0 = _mm_shuffle_ps( c, negS, _MM_SHUFFLE(0,1,1,1) ); - Y1 = _mm_shuffle_ps( s, c, _MM_SHUFFLE(0,1,1,1) ); - X0 = vec_splat( s, 0 ); - X1 = vec_splat( c, 0 ); - tmp = vec_mul( Z0, Y1 ); - return Transform3( - Vector3( vec_mul( Z0, Y0 ) ), - Vector3( vec_madd( Z1, X1, vec_mul( tmp, X0 ) ) ), - Vector3( vec_nmsub( Z1, X0, vec_mul( tmp, X1 ) ) ), - Vector3( 0.0f ) - ); + Z1 = vec_and(Z1, _mm_load_ps((float *)select_xyz)); + Y0 = _mm_shuffle_ps(c, negS, _MM_SHUFFLE(0, 1, 1, 1)); + Y1 = _mm_shuffle_ps(s, c, _MM_SHUFFLE(0, 1, 1, 1)); + X0 = vec_splat(s, 0); + X1 = vec_splat(c, 0); + tmp = vec_mul(Z0, Y1); + return Transform3( + Vector3(vec_mul(Z0, Y0)), + Vector3(vec_madd(Z1, X1, vec_mul(tmp, X0))), + Vector3(vec_nmsub(Z1, X0, vec_mul(tmp, X1))), + Vector3(0.0f)); } -VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotation( float radians, const Vector3 &unitVec ) +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotation(float radians, const Vector3 &unitVec) { - return rotation( floatInVec(radians), unitVec ); + return rotation(floatInVec(radians), unitVec); } -VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotation( const floatInVec &radians, const Vector3 &unitVec ) +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotation(const floatInVec &radians, const Vector3 &unitVec) { - return Transform3( Matrix3::rotation( radians, unitVec ), Vector3( 0.0f ) ); + return Transform3(Matrix3::rotation(radians, unitVec), Vector3(0.0f)); } -VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotation( const Quat &unitQuat ) +VECTORMATH_FORCE_INLINE const Transform3 Transform3::rotation(const Quat &unitQuat) { - return Transform3( Matrix3( unitQuat ), Vector3( 0.0f ) ); + return Transform3(Matrix3(unitQuat), Vector3(0.0f)); } -VECTORMATH_FORCE_INLINE const Transform3 Transform3::scale( const Vector3 &scaleVec ) +VECTORMATH_FORCE_INLINE const Transform3 Transform3::scale(const Vector3 &scaleVec) { - __m128 zero = _mm_setzero_ps(); + __m128 zero = _mm_setzero_ps(); VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; - return Transform3( - Vector3( vec_sel( zero, scaleVec.get128(), select_x ) ), - Vector3( vec_sel( zero, scaleVec.get128(), select_y ) ), - Vector3( vec_sel( zero, scaleVec.get128(), select_z ) ), - Vector3( 0.0f ) - ); + return Transform3( + Vector3(vec_sel(zero, scaleVec.get128(), select_x)), + Vector3(vec_sel(zero, scaleVec.get128(), select_y)), + Vector3(vec_sel(zero, scaleVec.get128(), select_z)), + Vector3(0.0f)); } -VECTORMATH_FORCE_INLINE const Transform3 appendScale( const Transform3 & tfrm, const Vector3 &scaleVec ) +VECTORMATH_FORCE_INLINE const Transform3 appendScale(const Transform3 &tfrm, const Vector3 &scaleVec) { - return Transform3( - ( tfrm.getCol0() * scaleVec.getX( ) ), - ( tfrm.getCol1() * scaleVec.getY( ) ), - ( tfrm.getCol2() * scaleVec.getZ( ) ), - tfrm.getCol3() - ); + return Transform3( + (tfrm.getCol0() * scaleVec.getX()), + (tfrm.getCol1() * scaleVec.getY()), + (tfrm.getCol2() * scaleVec.getZ()), + tfrm.getCol3()); } -VECTORMATH_FORCE_INLINE const Transform3 prependScale( const Vector3 &scaleVec, const Transform3 & tfrm ) +VECTORMATH_FORCE_INLINE const Transform3 prependScale(const Vector3 &scaleVec, const Transform3 &tfrm) { - return Transform3( - mulPerElem( tfrm.getCol0(), scaleVec ), - mulPerElem( tfrm.getCol1(), scaleVec ), - mulPerElem( tfrm.getCol2(), scaleVec ), - mulPerElem( tfrm.getCol3(), scaleVec ) - ); + return Transform3( + mulPerElem(tfrm.getCol0(), scaleVec), + mulPerElem(tfrm.getCol1(), scaleVec), + mulPerElem(tfrm.getCol2(), scaleVec), + mulPerElem(tfrm.getCol3(), scaleVec)); } -VECTORMATH_FORCE_INLINE const Transform3 Transform3::translation( const Vector3 &translateVec ) +VECTORMATH_FORCE_INLINE const Transform3 Transform3::translation(const Vector3 &translateVec) { - return Transform3( - Vector3::xAxis( ), - Vector3::yAxis( ), - Vector3::zAxis( ), - translateVec - ); + return Transform3( + Vector3::xAxis(), + Vector3::yAxis(), + Vector3::zAxis(), + translateVec); } -VECTORMATH_FORCE_INLINE const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ) +VECTORMATH_FORCE_INLINE const Transform3 select(const Transform3 &tfrm0, const Transform3 &tfrm1, bool select1) { - return Transform3( - select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ), - select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ), - select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ), - select( tfrm0.getCol3(), tfrm1.getCol3(), select1 ) - ); + return Transform3( + select(tfrm0.getCol0(), tfrm1.getCol0(), select1), + select(tfrm0.getCol1(), tfrm1.getCol1(), select1), + select(tfrm0.getCol2(), tfrm1.getCol2(), select1), + select(tfrm0.getCol3(), tfrm1.getCol3(), select1)); } -VECTORMATH_FORCE_INLINE const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, const boolInVec &select1 ) +VECTORMATH_FORCE_INLINE const Transform3 select(const Transform3 &tfrm0, const Transform3 &tfrm1, const boolInVec &select1) { - return Transform3( - select( tfrm0.getCol0(), tfrm1.getCol0(), select1 ), - select( tfrm0.getCol1(), tfrm1.getCol1(), select1 ), - select( tfrm0.getCol2(), tfrm1.getCol2(), select1 ), - select( tfrm0.getCol3(), tfrm1.getCol3(), select1 ) - ); + return Transform3( + select(tfrm0.getCol0(), tfrm1.getCol0(), select1), + select(tfrm0.getCol1(), tfrm1.getCol1(), select1), + select(tfrm0.getCol2(), tfrm1.getCol2(), select1), + select(tfrm0.getCol3(), tfrm1.getCol3(), select1)); } #ifdef _VECTORMATH_DEBUG -VECTORMATH_FORCE_INLINE void print( const Transform3 & tfrm ) +VECTORMATH_FORCE_INLINE void print(const Transform3 &tfrm) { - print( tfrm.getRow( 0 ) ); - print( tfrm.getRow( 1 ) ); - print( tfrm.getRow( 2 ) ); + print(tfrm.getRow(0)); + print(tfrm.getRow(1)); + print(tfrm.getRow(2)); } -VECTORMATH_FORCE_INLINE void print( const Transform3 & tfrm, const char * name ) +VECTORMATH_FORCE_INLINE void print(const Transform3 &tfrm, const char *name) { - printf("%s:\n", name); - print( tfrm ); + printf("%s:\n", name); + print(tfrm); } #endif -VECTORMATH_FORCE_INLINE Quat::Quat( const Matrix3 & tfrm ) +VECTORMATH_FORCE_INLINE Quat::Quat(const Matrix3 &tfrm) { - __m128 res; - __m128 col0, col1, col2; - __m128 xx_yy, xx_yy_zz_xx, yy_zz_xx_yy, zz_xx_yy_zz, diagSum, diagDiff; - __m128 zy_xz_yx, yz_zx_xy, sum, diff; - __m128 radicand, invSqrt, scale; - __m128 res0, res1, res2, res3; - __m128 xx, yy, zz; + __m128 res; + __m128 col0, col1, col2; + __m128 xx_yy, xx_yy_zz_xx, yy_zz_xx_yy, zz_xx_yy_zz, diagSum, diagDiff; + __m128 zy_xz_yx, yz_zx_xy, sum, diff; + __m128 radicand, invSqrt, scale; + __m128 res0, res1, res2, res3; + __m128 xx, yy, zz; VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_w[4] = {0, 0, 0, 0xffffffff}; - col0 = tfrm.getCol0().get128(); - col1 = tfrm.getCol1().get128(); - col2 = tfrm.getCol2().get128(); + col0 = tfrm.getCol0().get128(); + col1 = tfrm.getCol1().get128(); + col2 = tfrm.getCol2().get128(); - /* four cases: */ - /* trace > 0 */ - /* else */ - /* xx largest diagonal element */ - /* yy largest diagonal element */ - /* zz largest diagonal element */ + /* four cases: */ + /* trace > 0 */ + /* else */ + /* xx largest diagonal element */ + /* yy largest diagonal element */ + /* zz largest diagonal element */ - /* compute quaternion for each case */ + /* compute quaternion for each case */ - xx_yy = vec_sel( col0, col1, select_y ); - //xx_yy_zz_xx = vec_perm( xx_yy, col2, _VECTORMATH_PERM_XYCX ); - //yy_zz_xx_yy = vec_perm( xx_yy, col2, _VECTORMATH_PERM_YCXY ); - //zz_xx_yy_zz = vec_perm( xx_yy, col2, _VECTORMATH_PERM_CXYC ); - xx_yy_zz_xx = _mm_shuffle_ps( xx_yy, xx_yy, _MM_SHUFFLE(0,0,1,0) ); - xx_yy_zz_xx = vec_sel( xx_yy_zz_xx, col2, select_z ); // TODO: Ck - yy_zz_xx_yy = _mm_shuffle_ps( xx_yy_zz_xx, xx_yy_zz_xx, _MM_SHUFFLE(1,0,2,1) ); - zz_xx_yy_zz = _mm_shuffle_ps( xx_yy_zz_xx, xx_yy_zz_xx, _MM_SHUFFLE(2,1,0,2) ); + xx_yy = vec_sel(col0, col1, select_y); + //xx_yy_zz_xx = vec_perm( xx_yy, col2, _VECTORMATH_PERM_XYCX ); + //yy_zz_xx_yy = vec_perm( xx_yy, col2, _VECTORMATH_PERM_YCXY ); + //zz_xx_yy_zz = vec_perm( xx_yy, col2, _VECTORMATH_PERM_CXYC ); + xx_yy_zz_xx = _mm_shuffle_ps(xx_yy, xx_yy, _MM_SHUFFLE(0, 0, 1, 0)); + xx_yy_zz_xx = vec_sel(xx_yy_zz_xx, col2, select_z); // TODO: Ck + yy_zz_xx_yy = _mm_shuffle_ps(xx_yy_zz_xx, xx_yy_zz_xx, _MM_SHUFFLE(1, 0, 2, 1)); + zz_xx_yy_zz = _mm_shuffle_ps(xx_yy_zz_xx, xx_yy_zz_xx, _MM_SHUFFLE(2, 1, 0, 2)); - diagSum = vec_add( vec_add( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz ); - diagDiff = vec_sub( vec_sub( xx_yy_zz_xx, yy_zz_xx_yy ), zz_xx_yy_zz ); - radicand = vec_add( vec_sel( diagDiff, diagSum, select_w ), _mm_set1_ps(1.0f) ); - // invSqrt = rsqrtf4( radicand ); - invSqrt = newtonrapson_rsqrt4( radicand ); + diagSum = vec_add(vec_add(xx_yy_zz_xx, yy_zz_xx_yy), zz_xx_yy_zz); + diagDiff = vec_sub(vec_sub(xx_yy_zz_xx, yy_zz_xx_yy), zz_xx_yy_zz); + radicand = vec_add(vec_sel(diagDiff, diagSum, select_w), _mm_set1_ps(1.0f)); + // invSqrt = rsqrtf4( radicand ); + invSqrt = newtonrapson_rsqrt4(radicand); - + zy_xz_yx = vec_sel(col0, col1, select_z); // zy_xz_yx = 00 01 12 03 + //zy_xz_yx = vec_perm( zy_xz_yx, col2, _VECTORMATH_PERM_ZAYX ); + zy_xz_yx = _mm_shuffle_ps(zy_xz_yx, zy_xz_yx, _MM_SHUFFLE(0, 1, 2, 2)); // zy_xz_yx = 12 12 01 00 + zy_xz_yx = vec_sel(zy_xz_yx, vec_splat(col2, 0), select_y); // zy_xz_yx = 12 20 01 00 + yz_zx_xy = vec_sel(col0, col1, select_x); // yz_zx_xy = 10 01 02 03 + //yz_zx_xy = vec_perm( yz_zx_xy, col2, _VECTORMATH_PERM_BZXX ); + yz_zx_xy = _mm_shuffle_ps(yz_zx_xy, yz_zx_xy, _MM_SHUFFLE(0, 0, 2, 0)); // yz_zx_xy = 10 02 10 10 + yz_zx_xy = vec_sel(yz_zx_xy, vec_splat(col2, 1), select_x); // yz_zx_xy = 21 02 10 10 - zy_xz_yx = vec_sel( col0, col1, select_z ); // zy_xz_yx = 00 01 12 03 - //zy_xz_yx = vec_perm( zy_xz_yx, col2, _VECTORMATH_PERM_ZAYX ); - zy_xz_yx = _mm_shuffle_ps( zy_xz_yx, zy_xz_yx, _MM_SHUFFLE(0,1,2,2) ); // zy_xz_yx = 12 12 01 00 - zy_xz_yx = vec_sel( zy_xz_yx, vec_splat(col2, 0), select_y ); // zy_xz_yx = 12 20 01 00 - yz_zx_xy = vec_sel( col0, col1, select_x ); // yz_zx_xy = 10 01 02 03 - //yz_zx_xy = vec_perm( yz_zx_xy, col2, _VECTORMATH_PERM_BZXX ); - yz_zx_xy = _mm_shuffle_ps( yz_zx_xy, yz_zx_xy, _MM_SHUFFLE(0,0,2,0) ); // yz_zx_xy = 10 02 10 10 - yz_zx_xy = vec_sel( yz_zx_xy, vec_splat(col2, 1), select_x ); // yz_zx_xy = 21 02 10 10 + sum = vec_add(zy_xz_yx, yz_zx_xy); + diff = vec_sub(zy_xz_yx, yz_zx_xy); - sum = vec_add( zy_xz_yx, yz_zx_xy ); - diff = vec_sub( zy_xz_yx, yz_zx_xy ); + scale = vec_mul(invSqrt, _mm_set1_ps(0.5f)); - scale = vec_mul( invSqrt, _mm_set1_ps(0.5f) ); + //res0 = vec_perm( sum, diff, _VECTORMATH_PERM_XZYA ); + res0 = _mm_shuffle_ps(sum, sum, _MM_SHUFFLE(0, 1, 2, 0)); + res0 = vec_sel(res0, vec_splat(diff, 0), select_w); // TODO: Ck + //res1 = vec_perm( sum, diff, _VECTORMATH_PERM_ZXXB ); + res1 = _mm_shuffle_ps(sum, sum, _MM_SHUFFLE(0, 0, 0, 2)); + res1 = vec_sel(res1, vec_splat(diff, 1), select_w); // TODO: Ck + //res2 = vec_perm( sum, diff, _VECTORMATH_PERM_YXXC ); + res2 = _mm_shuffle_ps(sum, sum, _MM_SHUFFLE(0, 0, 0, 1)); + res2 = vec_sel(res2, vec_splat(diff, 2), select_w); // TODO: Ck + res3 = diff; + res0 = vec_sel(res0, radicand, select_x); + res1 = vec_sel(res1, radicand, select_y); + res2 = vec_sel(res2, radicand, select_z); + res3 = vec_sel(res3, radicand, select_w); + res0 = vec_mul(res0, vec_splat(scale, 0)); + res1 = vec_mul(res1, vec_splat(scale, 1)); + res2 = vec_mul(res2, vec_splat(scale, 2)); + res3 = vec_mul(res3, vec_splat(scale, 3)); - //res0 = vec_perm( sum, diff, _VECTORMATH_PERM_XZYA ); - res0 = _mm_shuffle_ps( sum, sum, _MM_SHUFFLE(0,1,2,0) ); - res0 = vec_sel( res0, vec_splat(diff, 0), select_w ); // TODO: Ck - //res1 = vec_perm( sum, diff, _VECTORMATH_PERM_ZXXB ); - res1 = _mm_shuffle_ps( sum, sum, _MM_SHUFFLE(0,0,0,2) ); - res1 = vec_sel( res1, vec_splat(diff, 1), select_w ); // TODO: Ck - //res2 = vec_perm( sum, diff, _VECTORMATH_PERM_YXXC ); - res2 = _mm_shuffle_ps( sum, sum, _MM_SHUFFLE(0,0,0,1) ); - res2 = vec_sel( res2, vec_splat(diff, 2), select_w ); // TODO: Ck - res3 = diff; - res0 = vec_sel( res0, radicand, select_x ); - res1 = vec_sel( res1, radicand, select_y ); - res2 = vec_sel( res2, radicand, select_z ); - res3 = vec_sel( res3, radicand, select_w ); - res0 = vec_mul( res0, vec_splat( scale, 0 ) ); - res1 = vec_mul( res1, vec_splat( scale, 1 ) ); - res2 = vec_mul( res2, vec_splat( scale, 2 ) ); - res3 = vec_mul( res3, vec_splat( scale, 3 ) ); + /* determine case and select answer */ - /* determine case and select answer */ - - xx = vec_splat( col0, 0 ); - yy = vec_splat( col1, 1 ); - zz = vec_splat( col2, 2 ); - res = vec_sel( res0, res1, vec_cmpgt( yy, xx ) ); - res = vec_sel( res, res2, vec_and( vec_cmpgt( zz, xx ), vec_cmpgt( zz, yy ) ) ); - res = vec_sel( res, res3, vec_cmpgt( vec_splat( diagSum, 0 ), _mm_setzero_ps() ) ); - mVec128 = res; + xx = vec_splat(col0, 0); + yy = vec_splat(col1, 1); + zz = vec_splat(col2, 2); + res = vec_sel(res0, res1, vec_cmpgt(yy, xx)); + res = vec_sel(res, res2, vec_and(vec_cmpgt(zz, xx), vec_cmpgt(zz, yy))); + res = vec_sel(res, res3, vec_cmpgt(vec_splat(diagSum, 0), _mm_setzero_ps())); + mVec128 = res; } -VECTORMATH_FORCE_INLINE const Matrix3 outer( const Vector3 &tfrm0, const Vector3 &tfrm1 ) +VECTORMATH_FORCE_INLINE const Matrix3 outer(const Vector3 &tfrm0, const Vector3 &tfrm1) { - return Matrix3( - ( tfrm0 * tfrm1.getX( ) ), - ( tfrm0 * tfrm1.getY( ) ), - ( tfrm0 * tfrm1.getZ( ) ) - ); + return Matrix3( + (tfrm0 * tfrm1.getX()), + (tfrm0 * tfrm1.getY()), + (tfrm0 * tfrm1.getZ())); } -VECTORMATH_FORCE_INLINE const Matrix4 outer( const Vector4 &tfrm0, const Vector4 &tfrm1 ) +VECTORMATH_FORCE_INLINE const Matrix4 outer(const Vector4 &tfrm0, const Vector4 &tfrm1) { - return Matrix4( - ( tfrm0 * tfrm1.getX( ) ), - ( tfrm0 * tfrm1.getY( ) ), - ( tfrm0 * tfrm1.getZ( ) ), - ( tfrm0 * tfrm1.getW( ) ) - ); + return Matrix4( + (tfrm0 * tfrm1.getX()), + (tfrm0 * tfrm1.getY()), + (tfrm0 * tfrm1.getZ()), + (tfrm0 * tfrm1.getW())); } -VECTORMATH_FORCE_INLINE const Vector3 rowMul( const Vector3 &vec, const Matrix3 & mat ) +VECTORMATH_FORCE_INLINE const Vector3 rowMul(const Vector3 &vec, const Matrix3 &mat) { - __m128 tmp0, tmp1, mcol0, mcol1, mcol2, res; - __m128 xxxx, yyyy, zzzz; - tmp0 = vec_mergeh( mat.getCol0().get128(), mat.getCol2().get128() ); - tmp1 = vec_mergel( mat.getCol0().get128(), mat.getCol2().get128() ); - xxxx = vec_splat( vec.get128(), 0 ); - mcol0 = vec_mergeh( tmp0, mat.getCol1().get128() ); - //mcol1 = vec_perm( tmp0, mat.getCol1().get128(), _VECTORMATH_PERM_ZBWX ); + __m128 tmp0, tmp1, mcol0, mcol1, mcol2, res; + __m128 xxxx, yyyy, zzzz; + tmp0 = vec_mergeh(mat.getCol0().get128(), mat.getCol2().get128()); + tmp1 = vec_mergel(mat.getCol0().get128(), mat.getCol2().get128()); + xxxx = vec_splat(vec.get128(), 0); + mcol0 = vec_mergeh(tmp0, mat.getCol1().get128()); + //mcol1 = vec_perm( tmp0, mat.getCol1().get128(), _VECTORMATH_PERM_ZBWX ); VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; - mcol1 = _mm_shuffle_ps( tmp0, tmp0, _MM_SHUFFLE(0,3,2,2)); + mcol1 = _mm_shuffle_ps(tmp0, tmp0, _MM_SHUFFLE(0, 3, 2, 2)); mcol1 = vec_sel(mcol1, mat.getCol1().get128(), select_y); - //mcol2 = vec_perm( tmp1, mat.getCol1().get128(), _VECTORMATH_PERM_XCYX ); - mcol2 = _mm_shuffle_ps( tmp1, tmp1, _MM_SHUFFLE(0,1,1,0)); + //mcol2 = vec_perm( tmp1, mat.getCol1().get128(), _VECTORMATH_PERM_XCYX ); + mcol2 = _mm_shuffle_ps(tmp1, tmp1, _MM_SHUFFLE(0, 1, 1, 0)); mcol2 = vec_sel(mcol2, vec_splat(mat.getCol1().get128(), 2), select_y); - yyyy = vec_splat( vec.get128(), 1 ); - res = vec_mul( mcol0, xxxx ); - zzzz = vec_splat( vec.get128(), 2 ); - res = vec_madd( mcol1, yyyy, res ); - res = vec_madd( mcol2, zzzz, res ); - return Vector3( res ); + yyyy = vec_splat(vec.get128(), 1); + res = vec_mul(mcol0, xxxx); + zzzz = vec_splat(vec.get128(), 2); + res = vec_madd(mcol1, yyyy, res); + res = vec_madd(mcol2, zzzz, res); + return Vector3(res); } -VECTORMATH_FORCE_INLINE const Matrix3 crossMatrix( const Vector3 &vec ) +VECTORMATH_FORCE_INLINE const Matrix3 crossMatrix(const Vector3 &vec) { - __m128 neg, res0, res1, res2; - neg = negatef4( vec.get128() ); + __m128 neg, res0, res1, res2; + neg = negatef4(vec.get128()); VM_ATTRIBUTE_ALIGN16 unsigned int select_x[4] = {0xffffffff, 0, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_y[4] = {0, 0xffffffff, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int select_z[4] = {0, 0, 0xffffffff, 0}; - //res0 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_XZBX ); - res0 = _mm_shuffle_ps( vec.get128(), vec.get128(), _MM_SHUFFLE(0,2,2,0) ); + //res0 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_XZBX ); + res0 = _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(0, 2, 2, 0)); res0 = vec_sel(res0, vec_splat(neg, 1), select_z); - //res1 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_CXXX ); + //res1 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_CXXX ); res1 = vec_sel(vec_splat(vec.get128(), 0), vec_splat(neg, 2), select_x); - //res2 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_YAXX ); - res2 = _mm_shuffle_ps( vec.get128(), vec.get128(), _MM_SHUFFLE(0,0,1,1) ); + //res2 = vec_perm( vec.get128(), neg, _VECTORMATH_PERM_YAXX ); + res2 = _mm_shuffle_ps(vec.get128(), vec.get128(), _MM_SHUFFLE(0, 0, 1, 1)); res2 = vec_sel(res2, vec_splat(neg, 0), select_y); VM_ATTRIBUTE_ALIGN16 unsigned int filter_x[4] = {0, 0xffffffff, 0xffffffff, 0xffffffff}; VM_ATTRIBUTE_ALIGN16 unsigned int filter_y[4] = {0xffffffff, 0, 0xffffffff, 0xffffffff}; VM_ATTRIBUTE_ALIGN16 unsigned int filter_z[4] = {0xffffffff, 0xffffffff, 0, 0xffffffff}; - res0 = vec_and( res0, _mm_load_ps((float *)filter_x ) ); - res1 = vec_and( res1, _mm_load_ps((float *)filter_y ) ); - res2 = vec_and( res2, _mm_load_ps((float *)filter_z ) ); // TODO: Use selects? - return Matrix3( - Vector3( res0 ), - Vector3( res1 ), - Vector3( res2 ) - ); + res0 = vec_and(res0, _mm_load_ps((float *)filter_x)); + res1 = vec_and(res1, _mm_load_ps((float *)filter_y)); + res2 = vec_and(res2, _mm_load_ps((float *)filter_z)); // TODO: Use selects? + return Matrix3( + Vector3(res0), + Vector3(res1), + Vector3(res2)); } -VECTORMATH_FORCE_INLINE const Matrix3 crossMatrixMul( const Vector3 &vec, const Matrix3 & mat ) +VECTORMATH_FORCE_INLINE const Matrix3 crossMatrixMul(const Vector3 &vec, const Matrix3 &mat) { - return Matrix3( cross( vec, mat.getCol0() ), cross( vec, mat.getCol1() ), cross( vec, mat.getCol2() ) ); + return Matrix3(cross(vec, mat.getCol0()), cross(vec, mat.getCol1()), cross(vec, mat.getCol2())); } -} // namespace Aos -} // namespace Vectormath +} // namespace Aos +} // namespace Vectormath #endif diff --git a/test/Bullet2/vectormath/sse/quat_aos.h b/test/Bullet2/vectormath/sse/quat_aos.h index 7eac59fe5..20e3933a1 100644 --- a/test/Bullet2/vectormath/sse/quat_aos.h +++ b/test/Bullet2/vectormath/sse/quat_aos.h @@ -27,7 +27,6 @@ POSSIBILITY OF SUCH DAMAGE. */ - #ifndef _VECTORMATH_QUAT_AOS_CPP_H #define _VECTORMATH_QUAT_AOS_CPP_H @@ -39,488 +38,482 @@ #endif -namespace Vectormath { -namespace Aos { - +namespace Vectormath +{ +namespace Aos +{ VECTORMATH_FORCE_INLINE void Quat::set128(vec_float4 vec) { - mVec128 = vec; + mVec128 = vec; } -VECTORMATH_FORCE_INLINE Quat::Quat( const floatInVec &_x, const floatInVec &_y, const floatInVec &_z, const floatInVec &_w ) +VECTORMATH_FORCE_INLINE Quat::Quat(const floatInVec &_x, const floatInVec &_y, const floatInVec &_z, const floatInVec &_w) { mVec128 = _mm_unpacklo_ps( - _mm_unpacklo_ps( _x.get128(), _z.get128() ), - _mm_unpacklo_ps( _y.get128(), _w.get128() ) ); + _mm_unpacklo_ps(_x.get128(), _z.get128()), + _mm_unpacklo_ps(_y.get128(), _w.get128())); } -VECTORMATH_FORCE_INLINE Quat::Quat( const Vector3 &xyz, float _w ) +VECTORMATH_FORCE_INLINE Quat::Quat(const Vector3 &xyz, float _w) { - mVec128 = xyz.get128(); - _vmathVfSetElement(mVec128, _w, 3); + mVec128 = xyz.get128(); + _vmathVfSetElement(mVec128, _w, 3); } - - -VECTORMATH_FORCE_INLINE Quat::Quat(const Quat& quat) +VECTORMATH_FORCE_INLINE Quat::Quat(const Quat &quat) { mVec128 = quat.get128(); } -VECTORMATH_FORCE_INLINE Quat::Quat( float _x, float _y, float _z, float _w ) +VECTORMATH_FORCE_INLINE Quat::Quat(float _x, float _y, float _z, float _w) { mVec128 = _mm_setr_ps(_x, _y, _z, _w); } - - - - -VECTORMATH_FORCE_INLINE Quat::Quat( const Vector3 &xyz, const floatInVec &_w ) +VECTORMATH_FORCE_INLINE Quat::Quat(const Vector3 &xyz, const floatInVec &_w) { - mVec128 = xyz.get128(); - mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); + mVec128 = xyz.get128(); + mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); } -VECTORMATH_FORCE_INLINE Quat::Quat( const Vector4 &vec ) +VECTORMATH_FORCE_INLINE Quat::Quat(const Vector4 &vec) { - mVec128 = vec.get128(); + mVec128 = vec.get128(); } -VECTORMATH_FORCE_INLINE Quat::Quat( float scalar ) +VECTORMATH_FORCE_INLINE Quat::Quat(float scalar) { - mVec128 = floatInVec(scalar).get128(); + mVec128 = floatInVec(scalar).get128(); } -VECTORMATH_FORCE_INLINE Quat::Quat( const floatInVec &scalar ) +VECTORMATH_FORCE_INLINE Quat::Quat(const floatInVec &scalar) { - mVec128 = scalar.get128(); + mVec128 = scalar.get128(); } -VECTORMATH_FORCE_INLINE Quat::Quat( __m128 vf4 ) +VECTORMATH_FORCE_INLINE Quat::Quat(__m128 vf4) { - mVec128 = vf4; + mVec128 = vf4; } -VECTORMATH_FORCE_INLINE const Quat Quat::identity( ) +VECTORMATH_FORCE_INLINE const Quat Quat::identity() { - return Quat( _VECTORMATH_UNIT_0001 ); + return Quat(_VECTORMATH_UNIT_0001); } -VECTORMATH_FORCE_INLINE const Quat lerp( float t, const Quat &quat0, const Quat &quat1 ) +VECTORMATH_FORCE_INLINE const Quat lerp(float t, const Quat &quat0, const Quat &quat1) { - return lerp( floatInVec(t), quat0, quat1 ); + return lerp(floatInVec(t), quat0, quat1); } -VECTORMATH_FORCE_INLINE const Quat lerp( const floatInVec &t, const Quat &quat0, const Quat &quat1 ) +VECTORMATH_FORCE_INLINE const Quat lerp(const floatInVec &t, const Quat &quat0, const Quat &quat1) { - return ( quat0 + ( ( quat1 - quat0 ) * t ) ); + return (quat0 + ((quat1 - quat0) * t)); } -VECTORMATH_FORCE_INLINE const Quat slerp( float t, const Quat &unitQuat0, const Quat &unitQuat1 ) +VECTORMATH_FORCE_INLINE const Quat slerp(float t, const Quat &unitQuat0, const Quat &unitQuat1) { - return slerp( floatInVec(t), unitQuat0, unitQuat1 ); + return slerp(floatInVec(t), unitQuat0, unitQuat1); } -VECTORMATH_FORCE_INLINE const Quat slerp( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1 ) +VECTORMATH_FORCE_INLINE const Quat slerp(const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1) { - Quat start; - vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; - __m128 selectMask; - cosAngle = _vmathVfDot4( unitQuat0.get128(), unitQuat1.get128() ); - selectMask = (__m128)vec_cmpgt( _mm_setzero_ps(), cosAngle ); - cosAngle = vec_sel( cosAngle, negatef4( cosAngle ), selectMask ); - start = Quat( vec_sel( unitQuat0.get128(), negatef4( unitQuat0.get128() ), selectMask ) ); - selectMask = (__m128)vec_cmpgt( _mm_set1_ps(_VECTORMATH_SLERP_TOL), cosAngle ); - angle = acosf4( cosAngle ); - tttt = t.get128(); - oneMinusT = vec_sub( _mm_set1_ps(1.0f), tttt ); - angles = vec_mergeh( _mm_set1_ps(1.0f), tttt ); - angles = vec_mergeh( angles, oneMinusT ); - angles = vec_madd( angles, angle, _mm_setzero_ps() ); - sines = sinf4( angles ); - scales = _mm_div_ps( sines, vec_splat( sines, 0 ) ); - scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask ); - scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask ); - return Quat( vec_madd( start.get128(), scale0, vec_mul( unitQuat1.get128(), scale1 ) ) ); + Quat start; + vec_float4 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; + __m128 selectMask; + cosAngle = _vmathVfDot4(unitQuat0.get128(), unitQuat1.get128()); + selectMask = (__m128)vec_cmpgt(_mm_setzero_ps(), cosAngle); + cosAngle = vec_sel(cosAngle, negatef4(cosAngle), selectMask); + start = Quat(vec_sel(unitQuat0.get128(), negatef4(unitQuat0.get128()), selectMask)); + selectMask = (__m128)vec_cmpgt(_mm_set1_ps(_VECTORMATH_SLERP_TOL), cosAngle); + angle = acosf4(cosAngle); + tttt = t.get128(); + oneMinusT = vec_sub(_mm_set1_ps(1.0f), tttt); + angles = vec_mergeh(_mm_set1_ps(1.0f), tttt); + angles = vec_mergeh(angles, oneMinusT); + angles = vec_madd(angles, angle, _mm_setzero_ps()); + sines = sinf4(angles); + scales = _mm_div_ps(sines, vec_splat(sines, 0)); + scale0 = vec_sel(oneMinusT, vec_splat(scales, 1), selectMask); + scale1 = vec_sel(tttt, vec_splat(scales, 2), selectMask); + return Quat(vec_madd(start.get128(), scale0, vec_mul(unitQuat1.get128(), scale1))); } -VECTORMATH_FORCE_INLINE const Quat squad( float t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 ) +VECTORMATH_FORCE_INLINE const Quat squad(float t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3) { - return squad( floatInVec(t), unitQuat0, unitQuat1, unitQuat2, unitQuat3 ); + return squad(floatInVec(t), unitQuat0, unitQuat1, unitQuat2, unitQuat3); } -VECTORMATH_FORCE_INLINE const Quat squad( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 ) +VECTORMATH_FORCE_INLINE const Quat squad(const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3) { - return slerp( ( ( floatInVec(2.0f) * t ) * ( floatInVec(1.0f) - t ) ), slerp( t, unitQuat0, unitQuat3 ), slerp( t, unitQuat1, unitQuat2 ) ); + return slerp(((floatInVec(2.0f) * t) * (floatInVec(1.0f) - t)), slerp(t, unitQuat0, unitQuat3), slerp(t, unitQuat1, unitQuat2)); } -VECTORMATH_FORCE_INLINE __m128 Quat::get128( ) const +VECTORMATH_FORCE_INLINE __m128 Quat::get128() const { - return mVec128; + return mVec128; } -VECTORMATH_FORCE_INLINE Quat & Quat::operator =( const Quat &quat ) +VECTORMATH_FORCE_INLINE Quat &Quat::operator=(const Quat &quat) { - mVec128 = quat.mVec128; - return *this; + mVec128 = quat.mVec128; + return *this; } -VECTORMATH_FORCE_INLINE Quat & Quat::setXYZ( const Vector3 &vec ) +VECTORMATH_FORCE_INLINE Quat &Quat::setXYZ(const Vector3 &vec) { VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; - mVec128 = vec_sel( vec.get128(), mVec128, sw ); - return *this; + mVec128 = vec_sel(vec.get128(), mVec128, sw); + return *this; } -VECTORMATH_FORCE_INLINE const Vector3 Quat::getXYZ( ) const +VECTORMATH_FORCE_INLINE const Vector3 Quat::getXYZ() const { - return Vector3( mVec128 ); + return Vector3(mVec128); } -VECTORMATH_FORCE_INLINE Quat & Quat::setX( float _x ) +VECTORMATH_FORCE_INLINE Quat &Quat::setX(float _x) { - _vmathVfSetElement(mVec128, _x, 0); - return *this; + _vmathVfSetElement(mVec128, _x, 0); + return *this; } -VECTORMATH_FORCE_INLINE Quat & Quat::setX( const floatInVec &_x ) +VECTORMATH_FORCE_INLINE Quat &Quat::setX(const floatInVec &_x) { - mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); - return *this; + mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Quat::getX( ) const +VECTORMATH_FORCE_INLINE const floatInVec Quat::getX() const { - return floatInVec( mVec128, 0 ); + return floatInVec(mVec128, 0); } -VECTORMATH_FORCE_INLINE Quat & Quat::setY( float _y ) +VECTORMATH_FORCE_INLINE Quat &Quat::setY(float _y) { - _vmathVfSetElement(mVec128, _y, 1); - return *this; + _vmathVfSetElement(mVec128, _y, 1); + return *this; } -VECTORMATH_FORCE_INLINE Quat & Quat::setY( const floatInVec &_y ) +VECTORMATH_FORCE_INLINE Quat &Quat::setY(const floatInVec &_y) { - mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); - return *this; + mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Quat::getY( ) const +VECTORMATH_FORCE_INLINE const floatInVec Quat::getY() const { - return floatInVec( mVec128, 1 ); + return floatInVec(mVec128, 1); } -VECTORMATH_FORCE_INLINE Quat & Quat::setZ( float _z ) +VECTORMATH_FORCE_INLINE Quat &Quat::setZ(float _z) { - _vmathVfSetElement(mVec128, _z, 2); - return *this; + _vmathVfSetElement(mVec128, _z, 2); + return *this; } -VECTORMATH_FORCE_INLINE Quat & Quat::setZ( const floatInVec &_z ) +VECTORMATH_FORCE_INLINE Quat &Quat::setZ(const floatInVec &_z) { - mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); - return *this; + mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Quat::getZ( ) const +VECTORMATH_FORCE_INLINE const floatInVec Quat::getZ() const { - return floatInVec( mVec128, 2 ); + return floatInVec(mVec128, 2); } -VECTORMATH_FORCE_INLINE Quat & Quat::setW( float _w ) +VECTORMATH_FORCE_INLINE Quat &Quat::setW(float _w) { - _vmathVfSetElement(mVec128, _w, 3); - return *this; + _vmathVfSetElement(mVec128, _w, 3); + return *this; } -VECTORMATH_FORCE_INLINE Quat & Quat::setW( const floatInVec &_w ) +VECTORMATH_FORCE_INLINE Quat &Quat::setW(const floatInVec &_w) { - mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); - return *this; + mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Quat::getW( ) const +VECTORMATH_FORCE_INLINE const floatInVec Quat::getW() const { - return floatInVec( mVec128, 3 ); + return floatInVec(mVec128, 3); } -VECTORMATH_FORCE_INLINE Quat & Quat::setElem( int idx, float value ) +VECTORMATH_FORCE_INLINE Quat &Quat::setElem(int idx, float value) { - _vmathVfSetElement(mVec128, value, idx); - return *this; + _vmathVfSetElement(mVec128, value, idx); + return *this; } -VECTORMATH_FORCE_INLINE Quat & Quat::setElem( int idx, const floatInVec &value ) +VECTORMATH_FORCE_INLINE Quat &Quat::setElem(int idx, const floatInVec &value) { - mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); - return *this; + mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Quat::getElem( int idx ) const +VECTORMATH_FORCE_INLINE const floatInVec Quat::getElem(int idx) const { - return floatInVec( mVec128, idx ); + return floatInVec(mVec128, idx); } -VECTORMATH_FORCE_INLINE VecIdx Quat::operator []( int idx ) +VECTORMATH_FORCE_INLINE VecIdx Quat::operator[](int idx) { - return VecIdx( mVec128, idx ); + return VecIdx(mVec128, idx); } -VECTORMATH_FORCE_INLINE const floatInVec Quat::operator []( int idx ) const +VECTORMATH_FORCE_INLINE const floatInVec Quat::operator[](int idx) const { - return floatInVec( mVec128, idx ); + return floatInVec(mVec128, idx); } -VECTORMATH_FORCE_INLINE const Quat Quat::operator +( const Quat &quat ) const +VECTORMATH_FORCE_INLINE const Quat Quat::operator+(const Quat &quat) const { - return Quat( _mm_add_ps( mVec128, quat.mVec128 ) ); + return Quat(_mm_add_ps(mVec128, quat.mVec128)); } - -VECTORMATH_FORCE_INLINE const Quat Quat::operator -( const Quat &quat ) const +VECTORMATH_FORCE_INLINE const Quat Quat::operator-(const Quat &quat) const { - return Quat( _mm_sub_ps( mVec128, quat.mVec128 ) ); + return Quat(_mm_sub_ps(mVec128, quat.mVec128)); } -VECTORMATH_FORCE_INLINE const Quat Quat::operator *( float scalar ) const +VECTORMATH_FORCE_INLINE const Quat Quat::operator*(float scalar) const { - return *this * floatInVec(scalar); + return *this * floatInVec(scalar); } -VECTORMATH_FORCE_INLINE const Quat Quat::operator *( const floatInVec &scalar ) const +VECTORMATH_FORCE_INLINE const Quat Quat::operator*(const floatInVec &scalar) const { - return Quat( _mm_mul_ps( mVec128, scalar.get128() ) ); + return Quat(_mm_mul_ps(mVec128, scalar.get128())); } -VECTORMATH_FORCE_INLINE Quat & Quat::operator +=( const Quat &quat ) +VECTORMATH_FORCE_INLINE Quat &Quat::operator+=(const Quat &quat) { - *this = *this + quat; - return *this; + *this = *this + quat; + return *this; } -VECTORMATH_FORCE_INLINE Quat & Quat::operator -=( const Quat &quat ) +VECTORMATH_FORCE_INLINE Quat &Quat::operator-=(const Quat &quat) { - *this = *this - quat; - return *this; + *this = *this - quat; + return *this; } -VECTORMATH_FORCE_INLINE Quat & Quat::operator *=( float scalar ) +VECTORMATH_FORCE_INLINE Quat &Quat::operator*=(float scalar) { - *this = *this * scalar; - return *this; + *this = *this * scalar; + return *this; } -VECTORMATH_FORCE_INLINE Quat & Quat::operator *=( const floatInVec &scalar ) +VECTORMATH_FORCE_INLINE Quat &Quat::operator*=(const floatInVec &scalar) { - *this = *this * scalar; - return *this; + *this = *this * scalar; + return *this; } -VECTORMATH_FORCE_INLINE const Quat Quat::operator /( float scalar ) const +VECTORMATH_FORCE_INLINE const Quat Quat::operator/(float scalar) const { - return *this / floatInVec(scalar); + return *this / floatInVec(scalar); } -VECTORMATH_FORCE_INLINE const Quat Quat::operator /( const floatInVec &scalar ) const +VECTORMATH_FORCE_INLINE const Quat Quat::operator/(const floatInVec &scalar) const { - return Quat( _mm_div_ps( mVec128, scalar.get128() ) ); + return Quat(_mm_div_ps(mVec128, scalar.get128())); } -VECTORMATH_FORCE_INLINE Quat & Quat::operator /=( float scalar ) +VECTORMATH_FORCE_INLINE Quat &Quat::operator/=(float scalar) { - *this = *this / scalar; - return *this; + *this = *this / scalar; + return *this; } -VECTORMATH_FORCE_INLINE Quat & Quat::operator /=( const floatInVec &scalar ) +VECTORMATH_FORCE_INLINE Quat &Quat::operator/=(const floatInVec &scalar) { - *this = *this / scalar; - return *this; + *this = *this / scalar; + return *this; } -VECTORMATH_FORCE_INLINE const Quat Quat::operator -( ) const +VECTORMATH_FORCE_INLINE const Quat Quat::operator-() const { - return Quat(_mm_sub_ps( _mm_setzero_ps(), mVec128 ) ); + return Quat(_mm_sub_ps(_mm_setzero_ps(), mVec128)); } -VECTORMATH_FORCE_INLINE const Quat operator *( float scalar, const Quat &quat ) +VECTORMATH_FORCE_INLINE const Quat operator*(float scalar, const Quat &quat) { - return floatInVec(scalar) * quat; + return floatInVec(scalar) * quat; } -VECTORMATH_FORCE_INLINE const Quat operator *( const floatInVec &scalar, const Quat &quat ) +VECTORMATH_FORCE_INLINE const Quat operator*(const floatInVec &scalar, const Quat &quat) { - return quat * scalar; + return quat * scalar; } -VECTORMATH_FORCE_INLINE const floatInVec dot( const Quat &quat0, const Quat &quat1 ) +VECTORMATH_FORCE_INLINE const floatInVec dot(const Quat &quat0, const Quat &quat1) { - return floatInVec( _vmathVfDot4( quat0.get128(), quat1.get128() ), 0 ); + return floatInVec(_vmathVfDot4(quat0.get128(), quat1.get128()), 0); } -VECTORMATH_FORCE_INLINE const floatInVec norm( const Quat &quat ) +VECTORMATH_FORCE_INLINE const floatInVec norm(const Quat &quat) { - return floatInVec( _vmathVfDot4( quat.get128(), quat.get128() ), 0 ); + return floatInVec(_vmathVfDot4(quat.get128(), quat.get128()), 0); } -VECTORMATH_FORCE_INLINE const floatInVec length( const Quat &quat ) +VECTORMATH_FORCE_INLINE const floatInVec length(const Quat &quat) { - return floatInVec( _mm_sqrt_ps(_vmathVfDot4( quat.get128(), quat.get128() )), 0 ); + return floatInVec(_mm_sqrt_ps(_vmathVfDot4(quat.get128(), quat.get128())), 0); } -VECTORMATH_FORCE_INLINE const Quat normalize( const Quat &quat ) +VECTORMATH_FORCE_INLINE const Quat normalize(const Quat &quat) { - vec_float4 dot =_vmathVfDot4( quat.get128(), quat.get128()); - return Quat( _mm_mul_ps( quat.get128(), newtonrapson_rsqrt4( dot ) ) ); + vec_float4 dot = _vmathVfDot4(quat.get128(), quat.get128()); + return Quat(_mm_mul_ps(quat.get128(), newtonrapson_rsqrt4(dot))); } - -VECTORMATH_FORCE_INLINE const Quat Quat::rotation( const Vector3 &unitVec0, const Vector3 &unitVec1 ) +VECTORMATH_FORCE_INLINE const Quat Quat::rotation(const Vector3 &unitVec0, const Vector3 &unitVec1) { - Vector3 crossVec; - __m128 cosAngle, cosAngleX2Plus2, recipCosHalfAngleX2, cosHalfAngleX2, res; - cosAngle = _vmathVfDot3( unitVec0.get128(), unitVec1.get128() ); - cosAngleX2Plus2 = vec_madd( cosAngle, _mm_set1_ps(2.0f), _mm_set1_ps(2.0f) ); - recipCosHalfAngleX2 = _mm_rsqrt_ps( cosAngleX2Plus2 ); - cosHalfAngleX2 = vec_mul( recipCosHalfAngleX2, cosAngleX2Plus2 ); - crossVec = cross( unitVec0, unitVec1 ); - res = vec_mul( crossVec.get128(), recipCosHalfAngleX2 ); + Vector3 crossVec; + __m128 cosAngle, cosAngleX2Plus2, recipCosHalfAngleX2, cosHalfAngleX2, res; + cosAngle = _vmathVfDot3(unitVec0.get128(), unitVec1.get128()); + cosAngleX2Plus2 = vec_madd(cosAngle, _mm_set1_ps(2.0f), _mm_set1_ps(2.0f)); + recipCosHalfAngleX2 = _mm_rsqrt_ps(cosAngleX2Plus2); + cosHalfAngleX2 = vec_mul(recipCosHalfAngleX2, cosAngleX2Plus2); + crossVec = cross(unitVec0, unitVec1); + res = vec_mul(crossVec.get128(), recipCosHalfAngleX2); VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; - res = vec_sel( res, vec_mul( cosHalfAngleX2, _mm_set1_ps(0.5f) ), sw ); - return Quat( res ); + res = vec_sel(res, vec_mul(cosHalfAngleX2, _mm_set1_ps(0.5f)), sw); + return Quat(res); } -VECTORMATH_FORCE_INLINE const Quat Quat::rotation( float radians, const Vector3 &unitVec ) +VECTORMATH_FORCE_INLINE const Quat Quat::rotation(float radians, const Vector3 &unitVec) { - return rotation( floatInVec(radians), unitVec ); + return rotation(floatInVec(radians), unitVec); } -VECTORMATH_FORCE_INLINE const Quat Quat::rotation( const floatInVec &radians, const Vector3 &unitVec ) +VECTORMATH_FORCE_INLINE const Quat Quat::rotation(const floatInVec &radians, const Vector3 &unitVec) { - __m128 s, c, angle, res; - angle = vec_mul( radians.get128(), _mm_set1_ps(0.5f) ); - sincosf4( angle, &s, &c ); + __m128 s, c, angle, res; + angle = vec_mul(radians.get128(), _mm_set1_ps(0.5f)); + sincosf4(angle, &s, &c); VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; - res = vec_sel( vec_mul( unitVec.get128(), s ), c, sw ); - return Quat( res ); + res = vec_sel(vec_mul(unitVec.get128(), s), c, sw); + return Quat(res); } -VECTORMATH_FORCE_INLINE const Quat Quat::rotationX( float radians ) +VECTORMATH_FORCE_INLINE const Quat Quat::rotationX(float radians) { - return rotationX( floatInVec(radians) ); + return rotationX(floatInVec(radians)); } -VECTORMATH_FORCE_INLINE const Quat Quat::rotationX( const floatInVec &radians ) +VECTORMATH_FORCE_INLINE const Quat Quat::rotationX(const floatInVec &radians) { - __m128 s, c, angle, res; - angle = vec_mul( radians.get128(), _mm_set1_ps(0.5f) ); - sincosf4( angle, &s, &c ); + __m128 s, c, angle, res; + angle = vec_mul(radians.get128(), _mm_set1_ps(0.5f)); + sincosf4(angle, &s, &c); VM_ATTRIBUTE_ALIGN16 unsigned int xsw[4] = {0xffffffff, 0, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int wsw[4] = {0, 0, 0, 0xffffffff}; - res = vec_sel( _mm_setzero_ps(), s, xsw ); - res = vec_sel( res, c, wsw ); - return Quat( res ); + res = vec_sel(_mm_setzero_ps(), s, xsw); + res = vec_sel(res, c, wsw); + return Quat(res); } -VECTORMATH_FORCE_INLINE const Quat Quat::rotationY( float radians ) +VECTORMATH_FORCE_INLINE const Quat Quat::rotationY(float radians) { - return rotationY( floatInVec(radians) ); + return rotationY(floatInVec(radians)); } -VECTORMATH_FORCE_INLINE const Quat Quat::rotationY( const floatInVec &radians ) +VECTORMATH_FORCE_INLINE const Quat Quat::rotationY(const floatInVec &radians) { - __m128 s, c, angle, res; - angle = vec_mul( radians.get128(), _mm_set1_ps(0.5f) ); - sincosf4( angle, &s, &c ); + __m128 s, c, angle, res; + angle = vec_mul(radians.get128(), _mm_set1_ps(0.5f)); + sincosf4(angle, &s, &c); VM_ATTRIBUTE_ALIGN16 unsigned int ysw[4] = {0, 0xffffffff, 0, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int wsw[4] = {0, 0, 0, 0xffffffff}; - res = vec_sel( _mm_setzero_ps(), s, ysw ); - res = vec_sel( res, c, wsw ); - return Quat( res ); + res = vec_sel(_mm_setzero_ps(), s, ysw); + res = vec_sel(res, c, wsw); + return Quat(res); } -VECTORMATH_FORCE_INLINE const Quat Quat::rotationZ( float radians ) +VECTORMATH_FORCE_INLINE const Quat Quat::rotationZ(float radians) { - return rotationZ( floatInVec(radians) ); + return rotationZ(floatInVec(radians)); } -VECTORMATH_FORCE_INLINE const Quat Quat::rotationZ( const floatInVec &radians ) +VECTORMATH_FORCE_INLINE const Quat Quat::rotationZ(const floatInVec &radians) { - __m128 s, c, angle, res; - angle = vec_mul( radians.get128(), _mm_set1_ps(0.5f) ); - sincosf4( angle, &s, &c ); + __m128 s, c, angle, res; + angle = vec_mul(radians.get128(), _mm_set1_ps(0.5f)); + sincosf4(angle, &s, &c); VM_ATTRIBUTE_ALIGN16 unsigned int zsw[4] = {0, 0, 0xffffffff, 0}; VM_ATTRIBUTE_ALIGN16 unsigned int wsw[4] = {0, 0, 0, 0xffffffff}; - res = vec_sel( _mm_setzero_ps(), s, zsw ); - res = vec_sel( res, c, wsw ); - return Quat( res ); + res = vec_sel(_mm_setzero_ps(), s, zsw); + res = vec_sel(res, c, wsw); + return Quat(res); } -VECTORMATH_FORCE_INLINE const Quat Quat::operator *( const Quat &quat ) const +VECTORMATH_FORCE_INLINE const Quat Quat::operator*(const Quat &quat) const { - __m128 ldata, rdata, qv, tmp0, tmp1, tmp2, tmp3; - __m128 product, l_wxyz, r_wxyz, xy, qw; - ldata = mVec128; - rdata = quat.mVec128; - tmp0 = _mm_shuffle_ps( ldata, ldata, _MM_SHUFFLE(3,0,2,1) ); - tmp1 = _mm_shuffle_ps( rdata, rdata, _MM_SHUFFLE(3,1,0,2) ); - tmp2 = _mm_shuffle_ps( ldata, ldata, _MM_SHUFFLE(3,1,0,2) ); - tmp3 = _mm_shuffle_ps( rdata, rdata, _MM_SHUFFLE(3,0,2,1) ); - qv = vec_mul( vec_splat( ldata, 3 ), rdata ); - qv = vec_madd( vec_splat( rdata, 3 ), ldata, qv ); - qv = vec_madd( tmp0, tmp1, qv ); - qv = vec_nmsub( tmp2, tmp3, qv ); - product = vec_mul( ldata, rdata ); - l_wxyz = vec_sld( ldata, ldata, 12 ); - r_wxyz = vec_sld( rdata, rdata, 12 ); - qw = vec_nmsub( l_wxyz, r_wxyz, product ); - xy = vec_madd( l_wxyz, r_wxyz, product ); - qw = vec_sub( qw, vec_sld( xy, xy, 8 ) ); + __m128 ldata, rdata, qv, tmp0, tmp1, tmp2, tmp3; + __m128 product, l_wxyz, r_wxyz, xy, qw; + ldata = mVec128; + rdata = quat.mVec128; + tmp0 = _mm_shuffle_ps(ldata, ldata, _MM_SHUFFLE(3, 0, 2, 1)); + tmp1 = _mm_shuffle_ps(rdata, rdata, _MM_SHUFFLE(3, 1, 0, 2)); + tmp2 = _mm_shuffle_ps(ldata, ldata, _MM_SHUFFLE(3, 1, 0, 2)); + tmp3 = _mm_shuffle_ps(rdata, rdata, _MM_SHUFFLE(3, 0, 2, 1)); + qv = vec_mul(vec_splat(ldata, 3), rdata); + qv = vec_madd(vec_splat(rdata, 3), ldata, qv); + qv = vec_madd(tmp0, tmp1, qv); + qv = vec_nmsub(tmp2, tmp3, qv); + product = vec_mul(ldata, rdata); + l_wxyz = vec_sld(ldata, ldata, 12); + r_wxyz = vec_sld(rdata, rdata, 12); + qw = vec_nmsub(l_wxyz, r_wxyz, product); + xy = vec_madd(l_wxyz, r_wxyz, product); + qw = vec_sub(qw, vec_sld(xy, xy, 8)); VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; - return Quat( vec_sel( qv, qw, sw ) ); + return Quat(vec_sel(qv, qw, sw)); } -VECTORMATH_FORCE_INLINE Quat & Quat::operator *=( const Quat &quat ) +VECTORMATH_FORCE_INLINE Quat &Quat::operator*=(const Quat &quat) { - *this = *this * quat; - return *this; + *this = *this * quat; + return *this; } -VECTORMATH_FORCE_INLINE const Vector3 rotate( const Quat &quat, const Vector3 &vec ) -{ __m128 qdata, vdata, product, tmp0, tmp1, tmp2, tmp3, wwww, qv, qw, res; - qdata = quat.get128(); - vdata = vec.get128(); - tmp0 = _mm_shuffle_ps( qdata, qdata, _MM_SHUFFLE(3,0,2,1) ); - tmp1 = _mm_shuffle_ps( vdata, vdata, _MM_SHUFFLE(3,1,0,2) ); - tmp2 = _mm_shuffle_ps( qdata, qdata, _MM_SHUFFLE(3,1,0,2) ); - tmp3 = _mm_shuffle_ps( vdata, vdata, _MM_SHUFFLE(3,0,2,1) ); - wwww = vec_splat( qdata, 3 ); - qv = vec_mul( wwww, vdata ); - qv = vec_madd( tmp0, tmp1, qv ); - qv = vec_nmsub( tmp2, tmp3, qv ); - product = vec_mul( qdata, vdata ); - qw = vec_madd( vec_sld( qdata, qdata, 4 ), vec_sld( vdata, vdata, 4 ), product ); - qw = vec_add( vec_sld( product, product, 8 ), qw ); - tmp1 = _mm_shuffle_ps( qv, qv, _MM_SHUFFLE(3,1,0,2) ); - tmp3 = _mm_shuffle_ps( qv, qv, _MM_SHUFFLE(3,0,2,1) ); - res = vec_mul( vec_splat( qw, 0 ), qdata ); - res = vec_madd( wwww, qv, res ); - res = vec_madd( tmp0, tmp1, res ); - res = vec_nmsub( tmp2, tmp3, res ); - return Vector3( res ); -} - -VECTORMATH_FORCE_INLINE const Quat conj( const Quat &quat ) +VECTORMATH_FORCE_INLINE const Vector3 rotate(const Quat &quat, const Vector3 &vec) { - VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0x80000000,0x80000000,0x80000000,0}; - return Quat( vec_xor( quat.get128(), _mm_load_ps((float *)sw) ) ); + __m128 qdata, vdata, product, tmp0, tmp1, tmp2, tmp3, wwww, qv, qw, res; + qdata = quat.get128(); + vdata = vec.get128(); + tmp0 = _mm_shuffle_ps(qdata, qdata, _MM_SHUFFLE(3, 0, 2, 1)); + tmp1 = _mm_shuffle_ps(vdata, vdata, _MM_SHUFFLE(3, 1, 0, 2)); + tmp2 = _mm_shuffle_ps(qdata, qdata, _MM_SHUFFLE(3, 1, 0, 2)); + tmp3 = _mm_shuffle_ps(vdata, vdata, _MM_SHUFFLE(3, 0, 2, 1)); + wwww = vec_splat(qdata, 3); + qv = vec_mul(wwww, vdata); + qv = vec_madd(tmp0, tmp1, qv); + qv = vec_nmsub(tmp2, tmp3, qv); + product = vec_mul(qdata, vdata); + qw = vec_madd(vec_sld(qdata, qdata, 4), vec_sld(vdata, vdata, 4), product); + qw = vec_add(vec_sld(product, product, 8), qw); + tmp1 = _mm_shuffle_ps(qv, qv, _MM_SHUFFLE(3, 1, 0, 2)); + tmp3 = _mm_shuffle_ps(qv, qv, _MM_SHUFFLE(3, 0, 2, 1)); + res = vec_mul(vec_splat(qw, 0), qdata); + res = vec_madd(wwww, qv, res); + res = vec_madd(tmp0, tmp1, res); + res = vec_nmsub(tmp2, tmp3, res); + return Vector3(res); } -VECTORMATH_FORCE_INLINE const Quat select( const Quat &quat0, const Quat &quat1, bool select1 ) +VECTORMATH_FORCE_INLINE const Quat conj(const Quat &quat) { - return select( quat0, quat1, boolInVec(select1) ); + VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0x80000000, 0x80000000, 0x80000000, 0}; + return Quat(vec_xor(quat.get128(), _mm_load_ps((float *)sw))); +} + +VECTORMATH_FORCE_INLINE const Quat select(const Quat &quat0, const Quat &quat1, bool select1) +{ + return select(quat0, quat1, boolInVec(select1)); } //VECTORMATH_FORCE_INLINE const Quat select( const Quat &quat0, const Quat &quat1, const boolInVec &select1 ) @@ -528,52 +521,54 @@ VECTORMATH_FORCE_INLINE const Quat select( const Quat &quat0, const Quat &quat1, // return Quat( vec_sel( quat0.get128(), quat1.get128(), select1.get128() ) ); //} -VECTORMATH_FORCE_INLINE void loadXYZW(Quat& quat, const float* fptr) +VECTORMATH_FORCE_INLINE void loadXYZW(Quat &quat, const float *fptr) { #ifdef USE_SSE3_LDDQU - quat = Quat( SSEFloat(_mm_lddqu_si128((const __m128i*)((float*)(fptr)))).m128 ); + quat = Quat(SSEFloat(_mm_lddqu_si128((const __m128i *)((float *)(fptr)))).m128); #else SSEFloat fl; fl.f[0] = fptr[0]; fl.f[1] = fptr[1]; fl.f[2] = fptr[2]; fl.f[3] = fptr[3]; - quat = Quat( fl.m128); + quat = Quat(fl.m128); #endif - - } -VECTORMATH_FORCE_INLINE void storeXYZW(const Quat& quat, float* fptr) +VECTORMATH_FORCE_INLINE void storeXYZW(const Quat &quat, float *fptr) { fptr[0] = quat.getX(); fptr[1] = quat.getY(); fptr[2] = quat.getZ(); fptr[3] = quat.getW(); -// _mm_storeu_ps((float*)quat.get128(),fptr); + // _mm_storeu_ps((float*)quat.get128(),fptr); } - - #ifdef _VECTORMATH_DEBUG -VECTORMATH_FORCE_INLINE void print( const Quat &quat ) +VECTORMATH_FORCE_INLINE void print(const Quat &quat) { - union { __m128 v; float s[4]; } tmp; - tmp.v = quat.get128(); - printf( "( %f %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); + union { + __m128 v; + float s[4]; + } tmp; + tmp.v = quat.get128(); + printf("( %f %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3]); } -VECTORMATH_FORCE_INLINE void print( const Quat &quat, const char * name ) +VECTORMATH_FORCE_INLINE void print(const Quat &quat, const char *name) { - union { __m128 v; float s[4]; } tmp; - tmp.v = quat.get128(); - printf( "%s: ( %f %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); + union { + __m128 v; + float s[4]; + } tmp; + tmp.v = quat.get128(); + printf("%s: ( %f %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3]); } #endif -} // namespace Aos -} // namespace Vectormath +} // namespace Aos +} // namespace Vectormath #endif diff --git a/test/Bullet2/vectormath/sse/vec_aos.h b/test/Bullet2/vectormath/sse/vec_aos.h index 35aeeaf16..2e3cc6dbc 100644 --- a/test/Bullet2/vectormath/sse/vec_aos.h +++ b/test/Bullet2/vectormath/sse/vec_aos.h @@ -42,21 +42,32 @@ #define _VECTORMATH_PERM_B 0x14151617 #define _VECTORMATH_PERM_C 0x18191a1b #define _VECTORMATH_PERM_D 0x1c1d1e1f -#define _VECTORMATH_PERM_XYZA (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A } -#define _VECTORMATH_PERM_ZXYW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_W } -#define _VECTORMATH_PERM_YZXW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W } -#define _VECTORMATH_PERM_YZAB (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B } -#define _VECTORMATH_PERM_ZABC (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B, _VECTORMATH_PERM_C } -#define _VECTORMATH_PERM_XYAW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_W } -#define _VECTORMATH_PERM_XAZW (vec_uchar16)(vec_uint4){ _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W } -#define _VECTORMATH_MASK_0xF000 (vec_uint4){ 0xffffffff, 0, 0, 0 } -#define _VECTORMATH_MASK_0x0F00 (vec_uint4){ 0, 0xffffffff, 0, 0 } -#define _VECTORMATH_MASK_0x00F0 (vec_uint4){ 0, 0, 0xffffffff, 0 } -#define _VECTORMATH_MASK_0x000F (vec_uint4){ 0, 0, 0, 0xffffffff } -#define _VECTORMATH_UNIT_1000 _mm_setr_ps(1.0f,0.0f,0.0f,0.0f) // (__m128){ 1.0f, 0.0f, 0.0f, 0.0f } -#define _VECTORMATH_UNIT_0100 _mm_setr_ps(0.0f,1.0f,0.0f,0.0f) // (__m128){ 0.0f, 1.0f, 0.0f, 0.0f } -#define _VECTORMATH_UNIT_0010 _mm_setr_ps(0.0f,0.0f,1.0f,0.0f) // (__m128){ 0.0f, 0.0f, 1.0f, 0.0f } -#define _VECTORMATH_UNIT_0001 _mm_setr_ps(0.0f,0.0f,0.0f,1.0f) // (__m128){ 0.0f, 0.0f, 0.0f, 1.0f } +#define _VECTORMATH_PERM_XYZA \ + (vec_uchar16)(vec_uint4) { _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A } +#define _VECTORMATH_PERM_ZXYW \ + (vec_uchar16)(vec_uint4) { _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_W } +#define _VECTORMATH_PERM_YZXW \ + (vec_uchar16)(vec_uint4) { _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_X, _VECTORMATH_PERM_W } +#define _VECTORMATH_PERM_YZAB \ + (vec_uchar16)(vec_uint4) { _VECTORMATH_PERM_Y, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B } +#define _VECTORMATH_PERM_ZABC \ + (vec_uchar16)(vec_uint4) { _VECTORMATH_PERM_Z, _VECTORMATH_PERM_A, _VECTORMATH_PERM_B, _VECTORMATH_PERM_C } +#define _VECTORMATH_PERM_XYAW \ + (vec_uchar16)(vec_uint4) { _VECTORMATH_PERM_X, _VECTORMATH_PERM_Y, _VECTORMATH_PERM_A, _VECTORMATH_PERM_W } +#define _VECTORMATH_PERM_XAZW \ + (vec_uchar16)(vec_uint4) { _VECTORMATH_PERM_X, _VECTORMATH_PERM_A, _VECTORMATH_PERM_Z, _VECTORMATH_PERM_W } +#define _VECTORMATH_MASK_0xF000 \ + (vec_uint4) { 0xffffffff, 0, 0, 0 } +#define _VECTORMATH_MASK_0x0F00 \ + (vec_uint4) { 0, 0xffffffff, 0, 0 } +#define _VECTORMATH_MASK_0x00F0 \ + (vec_uint4) { 0, 0, 0xffffffff, 0 } +#define _VECTORMATH_MASK_0x000F \ + (vec_uint4) { 0, 0, 0, 0xffffffff } +#define _VECTORMATH_UNIT_1000 _mm_setr_ps(1.0f, 0.0f, 0.0f, 0.0f) // (__m128){ 1.0f, 0.0f, 0.0f, 0.0f } +#define _VECTORMATH_UNIT_0100 _mm_setr_ps(0.0f, 1.0f, 0.0f, 0.0f) // (__m128){ 0.0f, 1.0f, 0.0f, 0.0f } +#define _VECTORMATH_UNIT_0010 _mm_setr_ps(0.0f, 0.0f, 1.0f, 0.0f) // (__m128){ 0.0f, 0.0f, 1.0f, 0.0f } +#define _VECTORMATH_UNIT_0001 _mm_setr_ps(0.0f, 0.0f, 0.0f, 1.0f) // (__m128){ 0.0f, 0.0f, 0.0f, 1.0f } #define _VECTORMATH_SLERP_TOL 0.999f //_VECTORMATH_SLERP_TOLF @@ -66,31 +77,31 @@ #ifndef _VECTORMATH_INTERNAL_FUNCTIONS #define _VECTORMATH_INTERNAL_FUNCTIONS -#define _vmath_shufps(a, b, immx, immy, immz, immw) _mm_shuffle_ps(a, b, _MM_SHUFFLE(immw, immz, immy, immx)) -static VECTORMATH_FORCE_INLINE __m128 _vmathVfDot3( __m128 vec0, __m128 vec1 ) +#define _vmath_shufps(a, b, immx, immy, immz, immw) _mm_shuffle_ps(a, b, _MM_SHUFFLE(immw, immz, immy, immx)) +static VECTORMATH_FORCE_INLINE __m128 _vmathVfDot3(__m128 vec0, __m128 vec1) { - __m128 result = _mm_mul_ps( vec0, vec1); - return _mm_add_ps( vec_splat( result, 0 ), _mm_add_ps( vec_splat( result, 1 ), vec_splat( result, 2 ) ) ); + __m128 result = _mm_mul_ps(vec0, vec1); + return _mm_add_ps(vec_splat(result, 0), _mm_add_ps(vec_splat(result, 1), vec_splat(result, 2))); } -static VECTORMATH_FORCE_INLINE __m128 _vmathVfDot4( __m128 vec0, __m128 vec1 ) +static VECTORMATH_FORCE_INLINE __m128 _vmathVfDot4(__m128 vec0, __m128 vec1) { - __m128 result = _mm_mul_ps(vec0, vec1); - return _mm_add_ps(_mm_shuffle_ps(result, result, _MM_SHUFFLE(0,0,0,0)), - _mm_add_ps(_mm_shuffle_ps(result, result, _MM_SHUFFLE(1,1,1,1)), - _mm_add_ps(_mm_shuffle_ps(result, result, _MM_SHUFFLE(2,2,2,2)), _mm_shuffle_ps(result, result, _MM_SHUFFLE(3,3,3,3))))); + __m128 result = _mm_mul_ps(vec0, vec1); + return _mm_add_ps(_mm_shuffle_ps(result, result, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_add_ps(_mm_shuffle_ps(result, result, _MM_SHUFFLE(1, 1, 1, 1)), + _mm_add_ps(_mm_shuffle_ps(result, result, _MM_SHUFFLE(2, 2, 2, 2)), _mm_shuffle_ps(result, result, _MM_SHUFFLE(3, 3, 3, 3))))); } -static VECTORMATH_FORCE_INLINE __m128 _vmathVfCross( __m128 vec0, __m128 vec1 ) +static VECTORMATH_FORCE_INLINE __m128 _vmathVfCross(__m128 vec0, __m128 vec1) { - __m128 tmp0, tmp1, tmp2, tmp3, result; - tmp0 = _mm_shuffle_ps( vec0, vec0, _MM_SHUFFLE(3,0,2,1) ); - tmp1 = _mm_shuffle_ps( vec1, vec1, _MM_SHUFFLE(3,1,0,2) ); - tmp2 = _mm_shuffle_ps( vec0, vec0, _MM_SHUFFLE(3,1,0,2) ); - tmp3 = _mm_shuffle_ps( vec1, vec1, _MM_SHUFFLE(3,0,2,1) ); - result = vec_mul( tmp0, tmp1 ); - result = vec_nmsub( tmp2, tmp3, result ); - return result; + __m128 tmp0, tmp1, tmp2, tmp3, result; + tmp0 = _mm_shuffle_ps(vec0, vec0, _MM_SHUFFLE(3, 0, 2, 1)); + tmp1 = _mm_shuffle_ps(vec1, vec1, _MM_SHUFFLE(3, 1, 0, 2)); + tmp2 = _mm_shuffle_ps(vec0, vec0, _MM_SHUFFLE(3, 1, 0, 2)); + tmp3 = _mm_shuffle_ps(vec1, vec1, _MM_SHUFFLE(3, 0, 2, 1)); + result = vec_mul(tmp0, tmp1); + result = vec_nmsub(tmp2, tmp3, result); + return result; } /* static VECTORMATH_FORCE_INLINE vec_uint4 _vmathVfToHalfFloatsUnpacked(__m128 v) @@ -159,14 +170,14 @@ static VECTORMATH_FORCE_INLINE __m128 _vmathVfSplatScalar(float scalar) #endif -namespace Vectormath { -namespace Aos { - - +namespace Vectormath +{ +namespace Aos +{ #ifdef _VECTORMATH_NO_SCALAR_CAST VECTORMATH_FORCE_INLINE VecIdx::operator floatInVec() const { - return floatInVec(ref, i); + return floatInVec(ref, i); } VECTORMATH_FORCE_INLINE float VecIdx::getAsFloat() const @@ -174,234 +185,228 @@ VECTORMATH_FORCE_INLINE float VecIdx::getAsFloat() const VECTORMATH_FORCE_INLINE VecIdx::operator float() const #endif { - return ((float *)&ref)[i]; + return ((float *)&ref)[i]; } -VECTORMATH_FORCE_INLINE float VecIdx::operator =( float scalar ) +VECTORMATH_FORCE_INLINE float VecIdx::operator=(float scalar) { - _vmathVfSetElement(ref, scalar, i); - return scalar; + _vmathVfSetElement(ref, scalar, i); + return scalar; } -VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator =( const floatInVec &scalar ) +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator=(const floatInVec &scalar) { - ref = _vmathVfInsert(ref, scalar.get128(), i); - return scalar; + ref = _vmathVfInsert(ref, scalar.get128(), i); + return scalar; } -VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator =( const VecIdx& scalar ) +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator=(const VecIdx &scalar) { - return *this = floatInVec(scalar.ref, scalar.i); + return *this = floatInVec(scalar.ref, scalar.i); } -VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator *=( float scalar ) +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator*=(float scalar) { - return *this *= floatInVec(scalar); + return *this *= floatInVec(scalar); } -VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator *=( const floatInVec &scalar ) +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator*=(const floatInVec &scalar) { - return *this = floatInVec(ref, i) * scalar; + return *this = floatInVec(ref, i) * scalar; } -VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator /=( float scalar ) +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator/=(float scalar) { - return *this /= floatInVec(scalar); + return *this /= floatInVec(scalar); } -inline floatInVec VecIdx::operator /=( const floatInVec &scalar ) +inline floatInVec VecIdx::operator/=(const floatInVec &scalar) { - return *this = floatInVec(ref, i) / scalar; + return *this = floatInVec(ref, i) / scalar; } -VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator +=( float scalar ) +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator+=(float scalar) { - return *this += floatInVec(scalar); + return *this += floatInVec(scalar); } -VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator +=( const floatInVec &scalar ) +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator+=(const floatInVec &scalar) { - return *this = floatInVec(ref, i) + scalar; + return *this = floatInVec(ref, i) + scalar; } -VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator -=( float scalar ) +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator-=(float scalar) { - return *this -= floatInVec(scalar); + return *this -= floatInVec(scalar); } -VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator -=( const floatInVec &scalar ) +VECTORMATH_FORCE_INLINE floatInVec VecIdx::operator-=(const floatInVec &scalar) { - return *this = floatInVec(ref, i) - scalar; + return *this = floatInVec(ref, i) - scalar; } -VECTORMATH_FORCE_INLINE Vector3::Vector3(const Vector3& vec) +VECTORMATH_FORCE_INLINE Vector3::Vector3(const Vector3 &vec) { - set128(vec.get128()); + set128(vec.get128()); } VECTORMATH_FORCE_INLINE void Vector3::set128(vec_float4 vec) { - mVec128 = vec; + mVec128 = vec; } - -VECTORMATH_FORCE_INLINE Vector3::Vector3( float _x, float _y, float _z ) +VECTORMATH_FORCE_INLINE Vector3::Vector3(float _x, float _y, float _z) { - mVec128 = _mm_setr_ps(_x, _y, _z, 0.0f); + mVec128 = _mm_setr_ps(_x, _y, _z, 0.0f); } -VECTORMATH_FORCE_INLINE Vector3::Vector3( const floatInVec &_x, const floatInVec &_y, const floatInVec &_z ) +VECTORMATH_FORCE_INLINE Vector3::Vector3(const floatInVec &_x, const floatInVec &_y, const floatInVec &_z) { - __m128 xz = _mm_unpacklo_ps( _x.get128(), _z.get128() ); - mVec128 = _mm_unpacklo_ps( xz, _y.get128() ); + __m128 xz = _mm_unpacklo_ps(_x.get128(), _z.get128()); + mVec128 = _mm_unpacklo_ps(xz, _y.get128()); } -VECTORMATH_FORCE_INLINE Vector3::Vector3( const Point3 &pnt ) +VECTORMATH_FORCE_INLINE Vector3::Vector3(const Point3 &pnt) { - mVec128 = pnt.get128(); + mVec128 = pnt.get128(); } -VECTORMATH_FORCE_INLINE Vector3::Vector3( float scalar ) +VECTORMATH_FORCE_INLINE Vector3::Vector3(float scalar) { - mVec128 = floatInVec(scalar).get128(); + mVec128 = floatInVec(scalar).get128(); } -VECTORMATH_FORCE_INLINE Vector3::Vector3( const floatInVec &scalar ) +VECTORMATH_FORCE_INLINE Vector3::Vector3(const floatInVec &scalar) { - mVec128 = scalar.get128(); + mVec128 = scalar.get128(); } -VECTORMATH_FORCE_INLINE Vector3::Vector3( __m128 vf4 ) +VECTORMATH_FORCE_INLINE Vector3::Vector3(__m128 vf4) { - mVec128 = vf4; + mVec128 = vf4; } -VECTORMATH_FORCE_INLINE const Vector3 Vector3::xAxis( ) +VECTORMATH_FORCE_INLINE const Vector3 Vector3::xAxis() { - return Vector3( _VECTORMATH_UNIT_1000 ); + return Vector3(_VECTORMATH_UNIT_1000); } -VECTORMATH_FORCE_INLINE const Vector3 Vector3::yAxis( ) +VECTORMATH_FORCE_INLINE const Vector3 Vector3::yAxis() { - return Vector3( _VECTORMATH_UNIT_0100 ); + return Vector3(_VECTORMATH_UNIT_0100); } -VECTORMATH_FORCE_INLINE const Vector3 Vector3::zAxis( ) +VECTORMATH_FORCE_INLINE const Vector3 Vector3::zAxis() { - return Vector3( _VECTORMATH_UNIT_0010 ); + return Vector3(_VECTORMATH_UNIT_0010); } -VECTORMATH_FORCE_INLINE const Vector3 lerp( float t, const Vector3 &vec0, const Vector3 &vec1 ) +VECTORMATH_FORCE_INLINE const Vector3 lerp(float t, const Vector3 &vec0, const Vector3 &vec1) { - return lerp( floatInVec(t), vec0, vec1 ); + return lerp(floatInVec(t), vec0, vec1); } -VECTORMATH_FORCE_INLINE const Vector3 lerp( const floatInVec &t, const Vector3 &vec0, const Vector3 &vec1 ) +VECTORMATH_FORCE_INLINE const Vector3 lerp(const floatInVec &t, const Vector3 &vec0, const Vector3 &vec1) { - return ( vec0 + ( ( vec1 - vec0 ) * t ) ); + return (vec0 + ((vec1 - vec0) * t)); } -VECTORMATH_FORCE_INLINE const Vector3 slerp( float t, const Vector3 &unitVec0, const Vector3 &unitVec1 ) +VECTORMATH_FORCE_INLINE const Vector3 slerp(float t, const Vector3 &unitVec0, const Vector3 &unitVec1) { - return slerp( floatInVec(t), unitVec0, unitVec1 ); + return slerp(floatInVec(t), unitVec0, unitVec1); } -VECTORMATH_FORCE_INLINE const Vector3 slerp( const floatInVec &t, const Vector3 &unitVec0, const Vector3 &unitVec1 ) +VECTORMATH_FORCE_INLINE const Vector3 slerp(const floatInVec &t, const Vector3 &unitVec0, const Vector3 &unitVec1) { - __m128 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; - cosAngle = _vmathVfDot3( unitVec0.get128(), unitVec1.get128() ); - __m128 selectMask = _mm_cmpgt_ps( _mm_set1_ps(_VECTORMATH_SLERP_TOL), cosAngle ); - angle = acosf4( cosAngle ); - tttt = t.get128(); - oneMinusT = _mm_sub_ps( _mm_set1_ps(1.0f), tttt ); - angles = _mm_unpacklo_ps( _mm_set1_ps(1.0f), tttt ); // angles = 1, t, 1, t - angles = _mm_unpacklo_ps( angles, oneMinusT ); // angles = 1, 1-t, t, 1-t - angles = _mm_mul_ps( angles, angle ); - sines = sinf4( angles ); - scales = _mm_div_ps( sines, vec_splat( sines, 0 ) ); - scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask ); - scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask ); - return Vector3( vec_madd( unitVec0.get128(), scale0, _mm_mul_ps( unitVec1.get128(), scale1 ) ) ); + __m128 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; + cosAngle = _vmathVfDot3(unitVec0.get128(), unitVec1.get128()); + __m128 selectMask = _mm_cmpgt_ps(_mm_set1_ps(_VECTORMATH_SLERP_TOL), cosAngle); + angle = acosf4(cosAngle); + tttt = t.get128(); + oneMinusT = _mm_sub_ps(_mm_set1_ps(1.0f), tttt); + angles = _mm_unpacklo_ps(_mm_set1_ps(1.0f), tttt); // angles = 1, t, 1, t + angles = _mm_unpacklo_ps(angles, oneMinusT); // angles = 1, 1-t, t, 1-t + angles = _mm_mul_ps(angles, angle); + sines = sinf4(angles); + scales = _mm_div_ps(sines, vec_splat(sines, 0)); + scale0 = vec_sel(oneMinusT, vec_splat(scales, 1), selectMask); + scale1 = vec_sel(tttt, vec_splat(scales, 2), selectMask); + return Vector3(vec_madd(unitVec0.get128(), scale0, _mm_mul_ps(unitVec1.get128(), scale1))); } -VECTORMATH_FORCE_INLINE __m128 Vector3::get128( ) const +VECTORMATH_FORCE_INLINE __m128 Vector3::get128() const { - return mVec128; + return mVec128; } -VECTORMATH_FORCE_INLINE void loadXYZ(Point3& vec, const float* fptr) +VECTORMATH_FORCE_INLINE void loadXYZ(Point3 &vec, const float *fptr) { #ifdef USE_SSE3_LDDQU - vec = Point3( SSEFloat(_mm_lddqu_si128((const __m128i*)((float*)(fptr)))).m128 ); + vec = Point3(SSEFloat(_mm_lddqu_si128((const __m128i *)((float *)(fptr)))).m128); #else SSEFloat fl; fl.f[0] = fptr[0]; fl.f[1] = fptr[1]; fl.f[2] = fptr[2]; fl.f[3] = fptr[3]; - vec = Point3( fl.m128); -#endif //USE_SSE3_LDDQU - + vec = Point3(fl.m128); +#endif //USE_SSE3_LDDQU } - - -VECTORMATH_FORCE_INLINE void loadXYZ(Vector3& vec, const float* fptr) +VECTORMATH_FORCE_INLINE void loadXYZ(Vector3 &vec, const float *fptr) { #ifdef USE_SSE3_LDDQU - vec = Vector3( SSEFloat(_mm_lddqu_si128((const __m128i*)((float*)(fptr)))).m128 ); + vec = Vector3(SSEFloat(_mm_lddqu_si128((const __m128i *)((float *)(fptr)))).m128); #else SSEFloat fl; fl.f[0] = fptr[0]; fl.f[1] = fptr[1]; fl.f[2] = fptr[2]; fl.f[3] = fptr[3]; - vec = Vector3( fl.m128); -#endif //USE_SSE3_LDDQU - + vec = Vector3(fl.m128); +#endif //USE_SSE3_LDDQU } -VECTORMATH_FORCE_INLINE void storeXYZ( const Vector3 &vec, __m128 * quad ) +VECTORMATH_FORCE_INLINE void storeXYZ(const Vector3 &vec, __m128 *quad) { __m128 dstVec = *quad; - VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; // TODO: Centralize + VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; // TODO: Centralize dstVec = vec_sel(vec.get128(), dstVec, sw); *quad = dstVec; } -VECTORMATH_FORCE_INLINE void storeXYZ(const Point3& vec, float* fptr) +VECTORMATH_FORCE_INLINE void storeXYZ(const Point3 &vec, float *fptr) { fptr[0] = vec.getX(); fptr[1] = vec.getY(); fptr[2] = vec.getZ(); } -VECTORMATH_FORCE_INLINE void storeXYZ(const Vector3& vec, float* fptr) +VECTORMATH_FORCE_INLINE void storeXYZ(const Vector3 &vec, float *fptr) { fptr[0] = vec.getX(); fptr[1] = vec.getY(); fptr[2] = vec.getZ(); } - -VECTORMATH_FORCE_INLINE void loadXYZArray( Vector3 & vec0, Vector3 & vec1, Vector3 & vec2, Vector3 & vec3, const __m128 * threeQuads ) +VECTORMATH_FORCE_INLINE void loadXYZArray(Vector3 &vec0, Vector3 &vec1, Vector3 &vec2, Vector3 &vec3, const __m128 *threeQuads) { const float *quads = (float *)threeQuads; - vec0 = Vector3( _mm_load_ps(quads) ); - vec1 = Vector3( _mm_loadu_ps(quads + 3) ); - vec2 = Vector3( _mm_loadu_ps(quads + 6) ); - vec3 = Vector3( _mm_loadu_ps(quads + 9) ); + vec0 = Vector3(_mm_load_ps(quads)); + vec1 = Vector3(_mm_loadu_ps(quads + 3)); + vec2 = Vector3(_mm_loadu_ps(quads + 6)); + vec3 = Vector3(_mm_loadu_ps(quads + 9)); } -VECTORMATH_FORCE_INLINE void storeXYZArray( const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, __m128 * threeQuads ) +VECTORMATH_FORCE_INLINE void storeXYZArray(const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, __m128 *threeQuads) { - __m128 xxxx = _mm_shuffle_ps( vec1.get128(), vec1.get128(), _MM_SHUFFLE(0, 0, 0, 0) ); - __m128 zzzz = _mm_shuffle_ps( vec2.get128(), vec2.get128(), _MM_SHUFFLE(2, 2, 2, 2) ); + __m128 xxxx = _mm_shuffle_ps(vec1.get128(), vec1.get128(), _MM_SHUFFLE(0, 0, 0, 0)); + __m128 zzzz = _mm_shuffle_ps(vec2.get128(), vec2.get128(), _MM_SHUFFLE(2, 2, 2, 2)); VM_ATTRIBUTE_ALIGN16 unsigned int xsw[4] = {0, 0, 0, 0xffffffff}; VM_ATTRIBUTE_ALIGN16 unsigned int zsw[4] = {0xffffffff, 0, 0, 0}; - threeQuads[0] = vec_sel( vec0.get128(), xxxx, xsw ); - threeQuads[1] = _mm_shuffle_ps( vec1.get128(), vec2.get128(), _MM_SHUFFLE(1, 0, 2, 1) ); - threeQuads[2] = vec_sel( _mm_shuffle_ps( vec3.get128(), vec3.get128(), _MM_SHUFFLE(2, 1, 0, 3) ), zzzz, zsw ); + threeQuads[0] = vec_sel(vec0.get128(), xxxx, xsw); + threeQuads[1] = _mm_shuffle_ps(vec1.get128(), vec2.get128(), _MM_SHUFFLE(1, 0, 2, 1)); + threeQuads[2] = vec_sel(_mm_shuffle_ps(vec3.get128(), vec3.get128(), _MM_SHUFFLE(2, 1, 0, 3)), zzzz, zsw); } /* VECTORMATH_FORCE_INLINE void storeHalfFloats( const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, const Vector3 &vec4, const Vector3 &vec5, const Vector3 &vec6, const Vector3 &vec7, vec_ushort8 * threeQuads ) @@ -418,405 +423,409 @@ VECTORMATH_FORCE_INLINE void storeHalfFloats( const Vector3 &vec0, const Vector3 #endif } */ -VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator =( const Vector3 &vec ) +VECTORMATH_FORCE_INLINE Vector3 &Vector3::operator=(const Vector3 &vec) { - mVec128 = vec.mVec128; - return *this; + mVec128 = vec.mVec128; + return *this; } -VECTORMATH_FORCE_INLINE Vector3 & Vector3::setX( float _x ) +VECTORMATH_FORCE_INLINE Vector3 &Vector3::setX(float _x) { - _vmathVfSetElement(mVec128, _x, 0); - return *this; + _vmathVfSetElement(mVec128, _x, 0); + return *this; } -VECTORMATH_FORCE_INLINE Vector3 & Vector3::setX( const floatInVec &_x ) +VECTORMATH_FORCE_INLINE Vector3 &Vector3::setX(const floatInVec &_x) { - mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); - return *this; + mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Vector3::getX( ) const +VECTORMATH_FORCE_INLINE const floatInVec Vector3::getX() const { - return floatInVec( mVec128, 0 ); + return floatInVec(mVec128, 0); } -VECTORMATH_FORCE_INLINE Vector3 & Vector3::setY( float _y ) +VECTORMATH_FORCE_INLINE Vector3 &Vector3::setY(float _y) { - _vmathVfSetElement(mVec128, _y, 1); - return *this; + _vmathVfSetElement(mVec128, _y, 1); + return *this; } -VECTORMATH_FORCE_INLINE Vector3 & Vector3::setY( const floatInVec &_y ) +VECTORMATH_FORCE_INLINE Vector3 &Vector3::setY(const floatInVec &_y) { - mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); - return *this; + mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Vector3::getY( ) const +VECTORMATH_FORCE_INLINE const floatInVec Vector3::getY() const { - return floatInVec( mVec128, 1 ); + return floatInVec(mVec128, 1); } -VECTORMATH_FORCE_INLINE Vector3 & Vector3::setZ( float _z ) +VECTORMATH_FORCE_INLINE Vector3 &Vector3::setZ(float _z) { - _vmathVfSetElement(mVec128, _z, 2); - return *this; + _vmathVfSetElement(mVec128, _z, 2); + return *this; } -VECTORMATH_FORCE_INLINE Vector3 & Vector3::setZ( const floatInVec &_z ) +VECTORMATH_FORCE_INLINE Vector3 &Vector3::setZ(const floatInVec &_z) { - mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); - return *this; + mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Vector3::getZ( ) const +VECTORMATH_FORCE_INLINE const floatInVec Vector3::getZ() const { - return floatInVec( mVec128, 2 ); + return floatInVec(mVec128, 2); } -VECTORMATH_FORCE_INLINE Vector3 & Vector3::setElem( int idx, float value ) +VECTORMATH_FORCE_INLINE Vector3 &Vector3::setElem(int idx, float value) { - _vmathVfSetElement(mVec128, value, idx); - return *this; + _vmathVfSetElement(mVec128, value, idx); + return *this; } -VECTORMATH_FORCE_INLINE Vector3 & Vector3::setElem( int idx, const floatInVec &value ) +VECTORMATH_FORCE_INLINE Vector3 &Vector3::setElem(int idx, const floatInVec &value) { - mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); - return *this; + mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Vector3::getElem( int idx ) const +VECTORMATH_FORCE_INLINE const floatInVec Vector3::getElem(int idx) const { - return floatInVec( mVec128, idx ); + return floatInVec(mVec128, idx); } -VECTORMATH_FORCE_INLINE VecIdx Vector3::operator []( int idx ) +VECTORMATH_FORCE_INLINE VecIdx Vector3::operator[](int idx) { - return VecIdx( mVec128, idx ); + return VecIdx(mVec128, idx); } -VECTORMATH_FORCE_INLINE const floatInVec Vector3::operator []( int idx ) const +VECTORMATH_FORCE_INLINE const floatInVec Vector3::operator[](int idx) const { - return floatInVec( mVec128, idx ); + return floatInVec(mVec128, idx); } -VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator +( const Vector3 &vec ) const +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator+(const Vector3 &vec) const { - return Vector3( _mm_add_ps( mVec128, vec.mVec128 ) ); + return Vector3(_mm_add_ps(mVec128, vec.mVec128)); } -VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator -( const Vector3 &vec ) const +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator-(const Vector3 &vec) const { - return Vector3( _mm_sub_ps( mVec128, vec.mVec128 ) ); + return Vector3(_mm_sub_ps(mVec128, vec.mVec128)); } -VECTORMATH_FORCE_INLINE const Point3 Vector3::operator +( const Point3 &pnt ) const +VECTORMATH_FORCE_INLINE const Point3 Vector3::operator+(const Point3 &pnt) const { - return Point3( _mm_add_ps( mVec128, pnt.get128() ) ); + return Point3(_mm_add_ps(mVec128, pnt.get128())); } -VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator *( float scalar ) const +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator*(float scalar) const { - return *this * floatInVec(scalar); + return *this * floatInVec(scalar); } -VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator *( const floatInVec &scalar ) const +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator*(const floatInVec &scalar) const { - return Vector3( _mm_mul_ps( mVec128, scalar.get128() ) ); + return Vector3(_mm_mul_ps(mVec128, scalar.get128())); } -VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator +=( const Vector3 &vec ) +VECTORMATH_FORCE_INLINE Vector3 &Vector3::operator+=(const Vector3 &vec) { - *this = *this + vec; - return *this; + *this = *this + vec; + return *this; } -VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator -=( const Vector3 &vec ) +VECTORMATH_FORCE_INLINE Vector3 &Vector3::operator-=(const Vector3 &vec) { - *this = *this - vec; - return *this; + *this = *this - vec; + return *this; } -VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator *=( float scalar ) +VECTORMATH_FORCE_INLINE Vector3 &Vector3::operator*=(float scalar) { - *this = *this * scalar; - return *this; + *this = *this * scalar; + return *this; } -VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator *=( const floatInVec &scalar ) +VECTORMATH_FORCE_INLINE Vector3 &Vector3::operator*=(const floatInVec &scalar) { - *this = *this * scalar; - return *this; + *this = *this * scalar; + return *this; } -VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator /( float scalar ) const +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator/(float scalar) const { - return *this / floatInVec(scalar); + return *this / floatInVec(scalar); } -VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator /( const floatInVec &scalar ) const +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator/(const floatInVec &scalar) const { - return Vector3( _mm_div_ps( mVec128, scalar.get128() ) ); + return Vector3(_mm_div_ps(mVec128, scalar.get128())); } -VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator /=( float scalar ) +VECTORMATH_FORCE_INLINE Vector3 &Vector3::operator/=(float scalar) { - *this = *this / scalar; - return *this; + *this = *this / scalar; + return *this; } -VECTORMATH_FORCE_INLINE Vector3 & Vector3::operator /=( const floatInVec &scalar ) +VECTORMATH_FORCE_INLINE Vector3 &Vector3::operator/=(const floatInVec &scalar) { - *this = *this / scalar; - return *this; + *this = *this / scalar; + return *this; } -VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator -( ) const +VECTORMATH_FORCE_INLINE const Vector3 Vector3::operator-() const { //return Vector3(_mm_sub_ps( _mm_setzero_ps(), mVec128 ) ); VM_ATTRIBUTE_ALIGN16 static const int array[] = {0x80000000, 0x80000000, 0x80000000, 0x80000000}; - __m128 NEG_MASK = SSEFloat(*(const vec_float4*)array).vf; - return Vector3(_mm_xor_ps(get128(),NEG_MASK)); + __m128 NEG_MASK = SSEFloat(*(const vec_float4 *)array).vf; + return Vector3(_mm_xor_ps(get128(), NEG_MASK)); } -VECTORMATH_FORCE_INLINE const Vector3 operator *( float scalar, const Vector3 &vec ) +VECTORMATH_FORCE_INLINE const Vector3 operator*(float scalar, const Vector3 &vec) { - return floatInVec(scalar) * vec; + return floatInVec(scalar) * vec; } -VECTORMATH_FORCE_INLINE const Vector3 operator *( const floatInVec &scalar, const Vector3 &vec ) +VECTORMATH_FORCE_INLINE const Vector3 operator*(const floatInVec &scalar, const Vector3 &vec) { - return vec * scalar; + return vec * scalar; } -VECTORMATH_FORCE_INLINE const Vector3 mulPerElem( const Vector3 &vec0, const Vector3 &vec1 ) +VECTORMATH_FORCE_INLINE const Vector3 mulPerElem(const Vector3 &vec0, const Vector3 &vec1) { - return Vector3( _mm_mul_ps( vec0.get128(), vec1.get128() ) ); + return Vector3(_mm_mul_ps(vec0.get128(), vec1.get128())); } -VECTORMATH_FORCE_INLINE const Vector3 divPerElem( const Vector3 &vec0, const Vector3 &vec1 ) +VECTORMATH_FORCE_INLINE const Vector3 divPerElem(const Vector3 &vec0, const Vector3 &vec1) { - return Vector3( _mm_div_ps( vec0.get128(), vec1.get128() ) ); + return Vector3(_mm_div_ps(vec0.get128(), vec1.get128())); } -VECTORMATH_FORCE_INLINE const Vector3 recipPerElem( const Vector3 &vec ) +VECTORMATH_FORCE_INLINE const Vector3 recipPerElem(const Vector3 &vec) { - return Vector3( _mm_rcp_ps( vec.get128() ) ); + return Vector3(_mm_rcp_ps(vec.get128())); } -VECTORMATH_FORCE_INLINE const Vector3 absPerElem( const Vector3 &vec ) +VECTORMATH_FORCE_INLINE const Vector3 absPerElem(const Vector3 &vec) { - return Vector3( fabsf4( vec.get128() ) ); + return Vector3(fabsf4(vec.get128())); } -VECTORMATH_FORCE_INLINE const Vector3 copySignPerElem( const Vector3 &vec0, const Vector3 &vec1 ) +VECTORMATH_FORCE_INLINE const Vector3 copySignPerElem(const Vector3 &vec0, const Vector3 &vec1) { __m128 vmask = toM128(0x7fffffff); - return Vector3( _mm_or_ps( - _mm_and_ps ( vmask, vec0.get128() ), // Value - _mm_andnot_ps( vmask, vec1.get128() ) ) ); // Signs + return Vector3(_mm_or_ps( + _mm_and_ps(vmask, vec0.get128()), // Value + _mm_andnot_ps(vmask, vec1.get128()))); // Signs } -VECTORMATH_FORCE_INLINE const Vector3 maxPerElem( const Vector3 &vec0, const Vector3 &vec1 ) +VECTORMATH_FORCE_INLINE const Vector3 maxPerElem(const Vector3 &vec0, const Vector3 &vec1) { - return Vector3( _mm_max_ps( vec0.get128(), vec1.get128() ) ); + return Vector3(_mm_max_ps(vec0.get128(), vec1.get128())); } -VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Vector3 &vec ) +VECTORMATH_FORCE_INLINE const floatInVec maxElem(const Vector3 &vec) { - return floatInVec( _mm_max_ps( _mm_max_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), vec_splat( vec.get128(), 2 ) ) ); + return floatInVec(_mm_max_ps(_mm_max_ps(vec_splat(vec.get128(), 0), vec_splat(vec.get128(), 1)), vec_splat(vec.get128(), 2))); } -VECTORMATH_FORCE_INLINE const Vector3 minPerElem( const Vector3 &vec0, const Vector3 &vec1 ) +VECTORMATH_FORCE_INLINE const Vector3 minPerElem(const Vector3 &vec0, const Vector3 &vec1) { - return Vector3( _mm_min_ps( vec0.get128(), vec1.get128() ) ); + return Vector3(_mm_min_ps(vec0.get128(), vec1.get128())); } -VECTORMATH_FORCE_INLINE const floatInVec minElem( const Vector3 &vec ) +VECTORMATH_FORCE_INLINE const floatInVec minElem(const Vector3 &vec) { - return floatInVec( _mm_min_ps( _mm_min_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), vec_splat( vec.get128(), 2 ) ) ); + return floatInVec(_mm_min_ps(_mm_min_ps(vec_splat(vec.get128(), 0), vec_splat(vec.get128(), 1)), vec_splat(vec.get128(), 2))); } -VECTORMATH_FORCE_INLINE const floatInVec sum( const Vector3 &vec ) +VECTORMATH_FORCE_INLINE const floatInVec sum(const Vector3 &vec) { - return floatInVec( _mm_add_ps( _mm_add_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), vec_splat( vec.get128(), 2 ) ) ); + return floatInVec(_mm_add_ps(_mm_add_ps(vec_splat(vec.get128(), 0), vec_splat(vec.get128(), 1)), vec_splat(vec.get128(), 2))); } -VECTORMATH_FORCE_INLINE const floatInVec dot( const Vector3 &vec0, const Vector3 &vec1 ) +VECTORMATH_FORCE_INLINE const floatInVec dot(const Vector3 &vec0, const Vector3 &vec1) { - return floatInVec( _vmathVfDot3( vec0.get128(), vec1.get128() ), 0 ); + return floatInVec(_vmathVfDot3(vec0.get128(), vec1.get128()), 0); } -VECTORMATH_FORCE_INLINE const floatInVec lengthSqr( const Vector3 &vec ) +VECTORMATH_FORCE_INLINE const floatInVec lengthSqr(const Vector3 &vec) { - return floatInVec( _vmathVfDot3( vec.get128(), vec.get128() ), 0 ); + return floatInVec(_vmathVfDot3(vec.get128(), vec.get128()), 0); } -VECTORMATH_FORCE_INLINE const floatInVec length( const Vector3 &vec ) +VECTORMATH_FORCE_INLINE const floatInVec length(const Vector3 &vec) { - return floatInVec( _mm_sqrt_ps(_vmathVfDot3( vec.get128(), vec.get128() )), 0 ); + return floatInVec(_mm_sqrt_ps(_vmathVfDot3(vec.get128(), vec.get128())), 0); } - -VECTORMATH_FORCE_INLINE const Vector3 normalizeApprox( const Vector3 &vec ) +VECTORMATH_FORCE_INLINE const Vector3 normalizeApprox(const Vector3 &vec) { - return Vector3( _mm_mul_ps( vec.get128(), _mm_rsqrt_ps( _vmathVfDot3( vec.get128(), vec.get128() ) ) ) ); + return Vector3(_mm_mul_ps(vec.get128(), _mm_rsqrt_ps(_vmathVfDot3(vec.get128(), vec.get128())))); } -VECTORMATH_FORCE_INLINE const Vector3 normalize( const Vector3 &vec ) +VECTORMATH_FORCE_INLINE const Vector3 normalize(const Vector3 &vec) { - return Vector3( _mm_mul_ps( vec.get128(), newtonrapson_rsqrt4( _vmathVfDot3( vec.get128(), vec.get128() ) ) ) ); + return Vector3(_mm_mul_ps(vec.get128(), newtonrapson_rsqrt4(_vmathVfDot3(vec.get128(), vec.get128())))); } -VECTORMATH_FORCE_INLINE const Vector3 cross( const Vector3 &vec0, const Vector3 &vec1 ) +VECTORMATH_FORCE_INLINE const Vector3 cross(const Vector3 &vec0, const Vector3 &vec1) { - return Vector3( _vmathVfCross( vec0.get128(), vec1.get128() ) ); + return Vector3(_vmathVfCross(vec0.get128(), vec1.get128())); } -VECTORMATH_FORCE_INLINE const Vector3 select( const Vector3 &vec0, const Vector3 &vec1, bool select1 ) +VECTORMATH_FORCE_INLINE const Vector3 select(const Vector3 &vec0, const Vector3 &vec1, bool select1) { - return select( vec0, vec1, boolInVec(select1) ); + return select(vec0, vec1, boolInVec(select1)); } - -VECTORMATH_FORCE_INLINE const Vector4 select(const Vector4& vec0, const Vector4& vec1, const boolInVec& select1) +VECTORMATH_FORCE_INLINE const Vector4 select(const Vector4 &vec0, const Vector4 &vec1, const boolInVec &select1) { - return Vector4(vec_sel(vec0.get128(), vec1.get128(), select1.get128())); + return Vector4(vec_sel(vec0.get128(), vec1.get128(), select1.get128())); } #ifdef _VECTORMATH_DEBUG -VECTORMATH_FORCE_INLINE void print( const Vector3 &vec ) +VECTORMATH_FORCE_INLINE void print(const Vector3 &vec) { - union { __m128 v; float s[4]; } tmp; - tmp.v = vec.get128(); - printf( "( %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2] ); + union { + __m128 v; + float s[4]; + } tmp; + tmp.v = vec.get128(); + printf("( %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2]); } -VECTORMATH_FORCE_INLINE void print( const Vector3 &vec, const char * name ) +VECTORMATH_FORCE_INLINE void print(const Vector3 &vec, const char *name) { - union { __m128 v; float s[4]; } tmp; - tmp.v = vec.get128(); - printf( "%s: ( %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2] ); + union { + __m128 v; + float s[4]; + } tmp; + tmp.v = vec.get128(); + printf("%s: ( %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2]); } #endif -VECTORMATH_FORCE_INLINE Vector4::Vector4( float _x, float _y, float _z, float _w ) +VECTORMATH_FORCE_INLINE Vector4::Vector4(float _x, float _y, float _z, float _w) { - mVec128 = _mm_setr_ps(_x, _y, _z, _w); - } + mVec128 = _mm_setr_ps(_x, _y, _z, _w); +} -VECTORMATH_FORCE_INLINE Vector4::Vector4( const floatInVec &_x, const floatInVec &_y, const floatInVec &_z, const floatInVec &_w ) +VECTORMATH_FORCE_INLINE Vector4::Vector4(const floatInVec &_x, const floatInVec &_y, const floatInVec &_z, const floatInVec &_w) { mVec128 = _mm_unpacklo_ps( - _mm_unpacklo_ps( _x.get128(), _z.get128() ), - _mm_unpacklo_ps( _y.get128(), _w.get128() ) ); + _mm_unpacklo_ps(_x.get128(), _z.get128()), + _mm_unpacklo_ps(_y.get128(), _w.get128())); } -VECTORMATH_FORCE_INLINE Vector4::Vector4( const Vector3 &xyz, float _w ) +VECTORMATH_FORCE_INLINE Vector4::Vector4(const Vector3 &xyz, float _w) { - mVec128 = xyz.get128(); - _vmathVfSetElement(mVec128, _w, 3); + mVec128 = xyz.get128(); + _vmathVfSetElement(mVec128, _w, 3); } -VECTORMATH_FORCE_INLINE Vector4::Vector4( const Vector3 &xyz, const floatInVec &_w ) +VECTORMATH_FORCE_INLINE Vector4::Vector4(const Vector3 &xyz, const floatInVec &_w) { - mVec128 = xyz.get128(); - mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); + mVec128 = xyz.get128(); + mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); } -VECTORMATH_FORCE_INLINE Vector4::Vector4( const Vector3 &vec ) +VECTORMATH_FORCE_INLINE Vector4::Vector4(const Vector3 &vec) { - mVec128 = vec.get128(); - mVec128 = _vmathVfInsert(mVec128, _mm_setzero_ps(), 3); + mVec128 = vec.get128(); + mVec128 = _vmathVfInsert(mVec128, _mm_setzero_ps(), 3); } -VECTORMATH_FORCE_INLINE Vector4::Vector4( const Point3 &pnt ) +VECTORMATH_FORCE_INLINE Vector4::Vector4(const Point3 &pnt) { - mVec128 = pnt.get128(); - mVec128 = _vmathVfInsert(mVec128, _mm_set1_ps(1.0f), 3); + mVec128 = pnt.get128(); + mVec128 = _vmathVfInsert(mVec128, _mm_set1_ps(1.0f), 3); } -VECTORMATH_FORCE_INLINE Vector4::Vector4( const Quat &quat ) +VECTORMATH_FORCE_INLINE Vector4::Vector4(const Quat &quat) { - mVec128 = quat.get128(); + mVec128 = quat.get128(); } -VECTORMATH_FORCE_INLINE Vector4::Vector4( float scalar ) +VECTORMATH_FORCE_INLINE Vector4::Vector4(float scalar) { - mVec128 = floatInVec(scalar).get128(); + mVec128 = floatInVec(scalar).get128(); } -VECTORMATH_FORCE_INLINE Vector4::Vector4( const floatInVec &scalar ) +VECTORMATH_FORCE_INLINE Vector4::Vector4(const floatInVec &scalar) { - mVec128 = scalar.get128(); + mVec128 = scalar.get128(); } -VECTORMATH_FORCE_INLINE Vector4::Vector4( __m128 vf4 ) +VECTORMATH_FORCE_INLINE Vector4::Vector4(__m128 vf4) { - mVec128 = vf4; + mVec128 = vf4; } -VECTORMATH_FORCE_INLINE const Vector4 Vector4::xAxis( ) +VECTORMATH_FORCE_INLINE const Vector4 Vector4::xAxis() { - return Vector4( _VECTORMATH_UNIT_1000 ); + return Vector4(_VECTORMATH_UNIT_1000); } -VECTORMATH_FORCE_INLINE const Vector4 Vector4::yAxis( ) +VECTORMATH_FORCE_INLINE const Vector4 Vector4::yAxis() { - return Vector4( _VECTORMATH_UNIT_0100 ); + return Vector4(_VECTORMATH_UNIT_0100); } -VECTORMATH_FORCE_INLINE const Vector4 Vector4::zAxis( ) +VECTORMATH_FORCE_INLINE const Vector4 Vector4::zAxis() { - return Vector4( _VECTORMATH_UNIT_0010 ); + return Vector4(_VECTORMATH_UNIT_0010); } -VECTORMATH_FORCE_INLINE const Vector4 Vector4::wAxis( ) +VECTORMATH_FORCE_INLINE const Vector4 Vector4::wAxis() { - return Vector4( _VECTORMATH_UNIT_0001 ); + return Vector4(_VECTORMATH_UNIT_0001); } -VECTORMATH_FORCE_INLINE const Vector4 lerp( float t, const Vector4 &vec0, const Vector4 &vec1 ) +VECTORMATH_FORCE_INLINE const Vector4 lerp(float t, const Vector4 &vec0, const Vector4 &vec1) { - return lerp( floatInVec(t), vec0, vec1 ); + return lerp(floatInVec(t), vec0, vec1); } -VECTORMATH_FORCE_INLINE const Vector4 lerp( const floatInVec &t, const Vector4 &vec0, const Vector4 &vec1 ) +VECTORMATH_FORCE_INLINE const Vector4 lerp(const floatInVec &t, const Vector4 &vec0, const Vector4 &vec1) { - return ( vec0 + ( ( vec1 - vec0 ) * t ) ); + return (vec0 + ((vec1 - vec0) * t)); } -VECTORMATH_FORCE_INLINE const Vector4 slerp( float t, const Vector4 &unitVec0, const Vector4 &unitVec1 ) +VECTORMATH_FORCE_INLINE const Vector4 slerp(float t, const Vector4 &unitVec0, const Vector4 &unitVec1) { - return slerp( floatInVec(t), unitVec0, unitVec1 ); + return slerp(floatInVec(t), unitVec0, unitVec1); } -VECTORMATH_FORCE_INLINE const Vector4 slerp( const floatInVec &t, const Vector4 &unitVec0, const Vector4 &unitVec1 ) +VECTORMATH_FORCE_INLINE const Vector4 slerp(const floatInVec &t, const Vector4 &unitVec0, const Vector4 &unitVec1) { - __m128 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; - cosAngle = _vmathVfDot4( unitVec0.get128(), unitVec1.get128() ); - __m128 selectMask = _mm_cmpgt_ps( _mm_set1_ps(_VECTORMATH_SLERP_TOL), cosAngle ); - angle = acosf4( cosAngle ); - tttt = t.get128(); - oneMinusT = _mm_sub_ps( _mm_set1_ps(1.0f), tttt ); - angles = _mm_unpacklo_ps( _mm_set1_ps(1.0f), tttt ); // angles = 1, t, 1, t - angles = _mm_unpacklo_ps( angles, oneMinusT ); // angles = 1, 1-t, t, 1-t - angles = _mm_mul_ps( angles, angle ); - sines = sinf4( angles ); - scales = _mm_div_ps( sines, vec_splat( sines, 0 ) ); - scale0 = vec_sel( oneMinusT, vec_splat( scales, 1 ), selectMask ); - scale1 = vec_sel( tttt, vec_splat( scales, 2 ), selectMask ); - return Vector4( vec_madd( unitVec0.get128(), scale0, _mm_mul_ps( unitVec1.get128(), scale1 ) ) ); + __m128 scales, scale0, scale1, cosAngle, angle, tttt, oneMinusT, angles, sines; + cosAngle = _vmathVfDot4(unitVec0.get128(), unitVec1.get128()); + __m128 selectMask = _mm_cmpgt_ps(_mm_set1_ps(_VECTORMATH_SLERP_TOL), cosAngle); + angle = acosf4(cosAngle); + tttt = t.get128(); + oneMinusT = _mm_sub_ps(_mm_set1_ps(1.0f), tttt); + angles = _mm_unpacklo_ps(_mm_set1_ps(1.0f), tttt); // angles = 1, t, 1, t + angles = _mm_unpacklo_ps(angles, oneMinusT); // angles = 1, 1-t, t, 1-t + angles = _mm_mul_ps(angles, angle); + sines = sinf4(angles); + scales = _mm_div_ps(sines, vec_splat(sines, 0)); + scale0 = vec_sel(oneMinusT, vec_splat(scales, 1), selectMask); + scale1 = vec_sel(tttt, vec_splat(scales, 2), selectMask); + return Vector4(vec_madd(unitVec0.get128(), scale0, _mm_mul_ps(unitVec1.get128(), scale1))); } -VECTORMATH_FORCE_INLINE __m128 Vector4::get128( ) const +VECTORMATH_FORCE_INLINE __m128 Vector4::get128() const { - return mVec128; + return mVec128; } /* VECTORMATH_FORCE_INLINE void storeHalfFloats( const Vector4 &vec0, const Vector4 &vec1, const Vector4 &vec2, const Vector4 &vec3, vec_ushort8 * twoQuads ) @@ -825,379 +834,384 @@ VECTORMATH_FORCE_INLINE void storeHalfFloats( const Vector4 &vec0, const Vector4 twoQuads[1] = _vmath2VfToHalfFloats(vec2.get128(), vec3.get128()); } */ -VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator =( const Vector4 &vec ) +VECTORMATH_FORCE_INLINE Vector4 &Vector4::operator=(const Vector4 &vec) { - mVec128 = vec.mVec128; - return *this; + mVec128 = vec.mVec128; + return *this; } -VECTORMATH_FORCE_INLINE Vector4 & Vector4::setXYZ( const Vector3 &vec ) +VECTORMATH_FORCE_INLINE Vector4 &Vector4::setXYZ(const Vector3 &vec) { VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; - mVec128 = vec_sel( vec.get128(), mVec128, sw ); - return *this; + mVec128 = vec_sel(vec.get128(), mVec128, sw); + return *this; } -VECTORMATH_FORCE_INLINE const Vector3 Vector4::getXYZ( ) const +VECTORMATH_FORCE_INLINE const Vector3 Vector4::getXYZ() const { - return Vector3( mVec128 ); + return Vector3(mVec128); } -VECTORMATH_FORCE_INLINE Vector4 & Vector4::setX( float _x ) +VECTORMATH_FORCE_INLINE Vector4 &Vector4::setX(float _x) { - _vmathVfSetElement(mVec128, _x, 0); - return *this; + _vmathVfSetElement(mVec128, _x, 0); + return *this; } -VECTORMATH_FORCE_INLINE Vector4 & Vector4::setX( const floatInVec &_x ) +VECTORMATH_FORCE_INLINE Vector4 &Vector4::setX(const floatInVec &_x) { - mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); - return *this; + mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Vector4::getX( ) const +VECTORMATH_FORCE_INLINE const floatInVec Vector4::getX() const { - return floatInVec( mVec128, 0 ); + return floatInVec(mVec128, 0); } -VECTORMATH_FORCE_INLINE Vector4 & Vector4::setY( float _y ) +VECTORMATH_FORCE_INLINE Vector4 &Vector4::setY(float _y) { - _vmathVfSetElement(mVec128, _y, 1); - return *this; + _vmathVfSetElement(mVec128, _y, 1); + return *this; } -VECTORMATH_FORCE_INLINE Vector4 & Vector4::setY( const floatInVec &_y ) +VECTORMATH_FORCE_INLINE Vector4 &Vector4::setY(const floatInVec &_y) { - mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); - return *this; + mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Vector4::getY( ) const +VECTORMATH_FORCE_INLINE const floatInVec Vector4::getY() const { - return floatInVec( mVec128, 1 ); + return floatInVec(mVec128, 1); } -VECTORMATH_FORCE_INLINE Vector4 & Vector4::setZ( float _z ) +VECTORMATH_FORCE_INLINE Vector4 &Vector4::setZ(float _z) { - _vmathVfSetElement(mVec128, _z, 2); - return *this; + _vmathVfSetElement(mVec128, _z, 2); + return *this; } -VECTORMATH_FORCE_INLINE Vector4 & Vector4::setZ( const floatInVec &_z ) +VECTORMATH_FORCE_INLINE Vector4 &Vector4::setZ(const floatInVec &_z) { - mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); - return *this; + mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Vector4::getZ( ) const +VECTORMATH_FORCE_INLINE const floatInVec Vector4::getZ() const { - return floatInVec( mVec128, 2 ); + return floatInVec(mVec128, 2); } -VECTORMATH_FORCE_INLINE Vector4 & Vector4::setW( float _w ) +VECTORMATH_FORCE_INLINE Vector4 &Vector4::setW(float _w) { - _vmathVfSetElement(mVec128, _w, 3); - return *this; + _vmathVfSetElement(mVec128, _w, 3); + return *this; } -VECTORMATH_FORCE_INLINE Vector4 & Vector4::setW( const floatInVec &_w ) +VECTORMATH_FORCE_INLINE Vector4 &Vector4::setW(const floatInVec &_w) { - mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); - return *this; + mVec128 = _vmathVfInsert(mVec128, _w.get128(), 3); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Vector4::getW( ) const +VECTORMATH_FORCE_INLINE const floatInVec Vector4::getW() const { - return floatInVec( mVec128, 3 ); + return floatInVec(mVec128, 3); } -VECTORMATH_FORCE_INLINE Vector4 & Vector4::setElem( int idx, float value ) +VECTORMATH_FORCE_INLINE Vector4 &Vector4::setElem(int idx, float value) { - _vmathVfSetElement(mVec128, value, idx); - return *this; + _vmathVfSetElement(mVec128, value, idx); + return *this; } -VECTORMATH_FORCE_INLINE Vector4 & Vector4::setElem( int idx, const floatInVec &value ) +VECTORMATH_FORCE_INLINE Vector4 &Vector4::setElem(int idx, const floatInVec &value) { - mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); - return *this; + mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Vector4::getElem( int idx ) const +VECTORMATH_FORCE_INLINE const floatInVec Vector4::getElem(int idx) const { - return floatInVec( mVec128, idx ); + return floatInVec(mVec128, idx); } -VECTORMATH_FORCE_INLINE VecIdx Vector4::operator []( int idx ) +VECTORMATH_FORCE_INLINE VecIdx Vector4::operator[](int idx) { - return VecIdx( mVec128, idx ); + return VecIdx(mVec128, idx); } -VECTORMATH_FORCE_INLINE const floatInVec Vector4::operator []( int idx ) const +VECTORMATH_FORCE_INLINE const floatInVec Vector4::operator[](int idx) const { - return floatInVec( mVec128, idx ); + return floatInVec(mVec128, idx); } -VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator +( const Vector4 &vec ) const +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator+(const Vector4 &vec) const { - return Vector4( _mm_add_ps( mVec128, vec.mVec128 ) ); + return Vector4(_mm_add_ps(mVec128, vec.mVec128)); } -VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator -( const Vector4 &vec ) const +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator-(const Vector4 &vec) const { - return Vector4( _mm_sub_ps( mVec128, vec.mVec128 ) ); + return Vector4(_mm_sub_ps(mVec128, vec.mVec128)); } -VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator *( float scalar ) const +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator*(float scalar) const { - return *this * floatInVec(scalar); + return *this * floatInVec(scalar); } -VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator *( const floatInVec &scalar ) const +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator*(const floatInVec &scalar) const { - return Vector4( _mm_mul_ps( mVec128, scalar.get128() ) ); + return Vector4(_mm_mul_ps(mVec128, scalar.get128())); } -VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator +=( const Vector4 &vec ) +VECTORMATH_FORCE_INLINE Vector4 &Vector4::operator+=(const Vector4 &vec) { - *this = *this + vec; - return *this; + *this = *this + vec; + return *this; } -VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator -=( const Vector4 &vec ) +VECTORMATH_FORCE_INLINE Vector4 &Vector4::operator-=(const Vector4 &vec) { - *this = *this - vec; - return *this; + *this = *this - vec; + return *this; } -VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator *=( float scalar ) +VECTORMATH_FORCE_INLINE Vector4 &Vector4::operator*=(float scalar) { - *this = *this * scalar; - return *this; + *this = *this * scalar; + return *this; } -VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator *=( const floatInVec &scalar ) +VECTORMATH_FORCE_INLINE Vector4 &Vector4::operator*=(const floatInVec &scalar) { - *this = *this * scalar; - return *this; + *this = *this * scalar; + return *this; } -VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator /( float scalar ) const +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator/(float scalar) const { - return *this / floatInVec(scalar); + return *this / floatInVec(scalar); } -VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator /( const floatInVec &scalar ) const +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator/(const floatInVec &scalar) const { - return Vector4( _mm_div_ps( mVec128, scalar.get128() ) ); + return Vector4(_mm_div_ps(mVec128, scalar.get128())); } -VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator /=( float scalar ) +VECTORMATH_FORCE_INLINE Vector4 &Vector4::operator/=(float scalar) { - *this = *this / scalar; - return *this; + *this = *this / scalar; + return *this; } -VECTORMATH_FORCE_INLINE Vector4 & Vector4::operator /=( const floatInVec &scalar ) +VECTORMATH_FORCE_INLINE Vector4 &Vector4::operator/=(const floatInVec &scalar) { - *this = *this / scalar; - return *this; + *this = *this / scalar; + return *this; } -VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator -( ) const +VECTORMATH_FORCE_INLINE const Vector4 Vector4::operator-() const { - return Vector4(_mm_sub_ps( _mm_setzero_ps(), mVec128 ) ); + return Vector4(_mm_sub_ps(_mm_setzero_ps(), mVec128)); } -VECTORMATH_FORCE_INLINE const Vector4 operator *( float scalar, const Vector4 &vec ) +VECTORMATH_FORCE_INLINE const Vector4 operator*(float scalar, const Vector4 &vec) { - return floatInVec(scalar) * vec; + return floatInVec(scalar) * vec; } -VECTORMATH_FORCE_INLINE const Vector4 operator *( const floatInVec &scalar, const Vector4 &vec ) +VECTORMATH_FORCE_INLINE const Vector4 operator*(const floatInVec &scalar, const Vector4 &vec) { - return vec * scalar; + return vec * scalar; } -VECTORMATH_FORCE_INLINE const Vector4 mulPerElem( const Vector4 &vec0, const Vector4 &vec1 ) +VECTORMATH_FORCE_INLINE const Vector4 mulPerElem(const Vector4 &vec0, const Vector4 &vec1) { - return Vector4( _mm_mul_ps( vec0.get128(), vec1.get128() ) ); + return Vector4(_mm_mul_ps(vec0.get128(), vec1.get128())); } -VECTORMATH_FORCE_INLINE const Vector4 divPerElem( const Vector4 &vec0, const Vector4 &vec1 ) +VECTORMATH_FORCE_INLINE const Vector4 divPerElem(const Vector4 &vec0, const Vector4 &vec1) { - return Vector4( _mm_div_ps( vec0.get128(), vec1.get128() ) ); + return Vector4(_mm_div_ps(vec0.get128(), vec1.get128())); } -VECTORMATH_FORCE_INLINE const Vector4 recipPerElem( const Vector4 &vec ) +VECTORMATH_FORCE_INLINE const Vector4 recipPerElem(const Vector4 &vec) { - return Vector4( _mm_rcp_ps( vec.get128() ) ); + return Vector4(_mm_rcp_ps(vec.get128())); } -VECTORMATH_FORCE_INLINE const Vector4 absPerElem( const Vector4 &vec ) +VECTORMATH_FORCE_INLINE const Vector4 absPerElem(const Vector4 &vec) { - return Vector4( fabsf4( vec.get128() ) ); + return Vector4(fabsf4(vec.get128())); } -VECTORMATH_FORCE_INLINE const Vector4 copySignPerElem( const Vector4 &vec0, const Vector4 &vec1 ) +VECTORMATH_FORCE_INLINE const Vector4 copySignPerElem(const Vector4 &vec0, const Vector4 &vec1) { __m128 vmask = toM128(0x7fffffff); - return Vector4( _mm_or_ps( - _mm_and_ps ( vmask, vec0.get128() ), // Value - _mm_andnot_ps( vmask, vec1.get128() ) ) ); // Signs + return Vector4(_mm_or_ps( + _mm_and_ps(vmask, vec0.get128()), // Value + _mm_andnot_ps(vmask, vec1.get128()))); // Signs } -VECTORMATH_FORCE_INLINE const Vector4 maxPerElem( const Vector4 &vec0, const Vector4 &vec1 ) +VECTORMATH_FORCE_INLINE const Vector4 maxPerElem(const Vector4 &vec0, const Vector4 &vec1) { - return Vector4( _mm_max_ps( vec0.get128(), vec1.get128() ) ); + return Vector4(_mm_max_ps(vec0.get128(), vec1.get128())); } -VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Vector4 &vec ) +VECTORMATH_FORCE_INLINE const floatInVec maxElem(const Vector4 &vec) { - return floatInVec( _mm_max_ps( - _mm_max_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), - _mm_max_ps( vec_splat( vec.get128(), 2 ), vec_splat( vec.get128(), 3 ) ) ) ); + return floatInVec(_mm_max_ps( + _mm_max_ps(vec_splat(vec.get128(), 0), vec_splat(vec.get128(), 1)), + _mm_max_ps(vec_splat(vec.get128(), 2), vec_splat(vec.get128(), 3)))); } -VECTORMATH_FORCE_INLINE const Vector4 minPerElem( const Vector4 &vec0, const Vector4 &vec1 ) +VECTORMATH_FORCE_INLINE const Vector4 minPerElem(const Vector4 &vec0, const Vector4 &vec1) { - return Vector4( _mm_min_ps( vec0.get128(), vec1.get128() ) ); + return Vector4(_mm_min_ps(vec0.get128(), vec1.get128())); } -VECTORMATH_FORCE_INLINE const floatInVec minElem( const Vector4 &vec ) +VECTORMATH_FORCE_INLINE const floatInVec minElem(const Vector4 &vec) { - return floatInVec( _mm_min_ps( - _mm_min_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), - _mm_min_ps( vec_splat( vec.get128(), 2 ), vec_splat( vec.get128(), 3 ) ) ) ); + return floatInVec(_mm_min_ps( + _mm_min_ps(vec_splat(vec.get128(), 0), vec_splat(vec.get128(), 1)), + _mm_min_ps(vec_splat(vec.get128(), 2), vec_splat(vec.get128(), 3)))); } -VECTORMATH_FORCE_INLINE const floatInVec sum( const Vector4 &vec ) +VECTORMATH_FORCE_INLINE const floatInVec sum(const Vector4 &vec) { - return floatInVec( _mm_add_ps( - _mm_add_ps( vec_splat( vec.get128(), 0 ), vec_splat( vec.get128(), 1 ) ), - _mm_add_ps( vec_splat( vec.get128(), 2 ), vec_splat( vec.get128(), 3 ) ) ) ); + return floatInVec(_mm_add_ps( + _mm_add_ps(vec_splat(vec.get128(), 0), vec_splat(vec.get128(), 1)), + _mm_add_ps(vec_splat(vec.get128(), 2), vec_splat(vec.get128(), 3)))); } -VECTORMATH_FORCE_INLINE const floatInVec dot( const Vector4 &vec0, const Vector4 &vec1 ) +VECTORMATH_FORCE_INLINE const floatInVec dot(const Vector4 &vec0, const Vector4 &vec1) { - return floatInVec( _vmathVfDot4( vec0.get128(), vec1.get128() ), 0 ); + return floatInVec(_vmathVfDot4(vec0.get128(), vec1.get128()), 0); } -VECTORMATH_FORCE_INLINE const floatInVec lengthSqr( const Vector4 &vec ) +VECTORMATH_FORCE_INLINE const floatInVec lengthSqr(const Vector4 &vec) { - return floatInVec( _vmathVfDot4( vec.get128(), vec.get128() ), 0 ); + return floatInVec(_vmathVfDot4(vec.get128(), vec.get128()), 0); } -VECTORMATH_FORCE_INLINE const floatInVec length( const Vector4 &vec ) +VECTORMATH_FORCE_INLINE const floatInVec length(const Vector4 &vec) { - return floatInVec( _mm_sqrt_ps(_vmathVfDot4( vec.get128(), vec.get128() )), 0 ); + return floatInVec(_mm_sqrt_ps(_vmathVfDot4(vec.get128(), vec.get128())), 0); } -VECTORMATH_FORCE_INLINE const Vector4 normalizeApprox( const Vector4 &vec ) +VECTORMATH_FORCE_INLINE const Vector4 normalizeApprox(const Vector4 &vec) { - return Vector4( _mm_mul_ps( vec.get128(), _mm_rsqrt_ps( _vmathVfDot4( vec.get128(), vec.get128() ) ) ) ); + return Vector4(_mm_mul_ps(vec.get128(), _mm_rsqrt_ps(_vmathVfDot4(vec.get128(), vec.get128())))); } -VECTORMATH_FORCE_INLINE const Vector4 normalize( const Vector4 &vec ) +VECTORMATH_FORCE_INLINE const Vector4 normalize(const Vector4 &vec) { - return Vector4( _mm_mul_ps( vec.get128(), newtonrapson_rsqrt4( _vmathVfDot4( vec.get128(), vec.get128() ) ) ) ); + return Vector4(_mm_mul_ps(vec.get128(), newtonrapson_rsqrt4(_vmathVfDot4(vec.get128(), vec.get128())))); } -VECTORMATH_FORCE_INLINE const Vector4 select( const Vector4 &vec0, const Vector4 &vec1, bool select1 ) +VECTORMATH_FORCE_INLINE const Vector4 select(const Vector4 &vec0, const Vector4 &vec1, bool select1) { - return select( vec0, vec1, boolInVec(select1) ); + return select(vec0, vec1, boolInVec(select1)); } - #ifdef _VECTORMATH_DEBUG -VECTORMATH_FORCE_INLINE void print( const Vector4 &vec ) +VECTORMATH_FORCE_INLINE void print(const Vector4 &vec) { - union { __m128 v; float s[4]; } tmp; - tmp.v = vec.get128(); - printf( "( %f %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); + union { + __m128 v; + float s[4]; + } tmp; + tmp.v = vec.get128(); + printf("( %f %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3]); } -VECTORMATH_FORCE_INLINE void print( const Vector4 &vec, const char * name ) +VECTORMATH_FORCE_INLINE void print(const Vector4 &vec, const char *name) { - union { __m128 v; float s[4]; } tmp; - tmp.v = vec.get128(); - printf( "%s: ( %f %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3] ); + union { + __m128 v; + float s[4]; + } tmp; + tmp.v = vec.get128(); + printf("%s: ( %f %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2], tmp.s[3]); } #endif -VECTORMATH_FORCE_INLINE Point3::Point3( float _x, float _y, float _z ) +VECTORMATH_FORCE_INLINE Point3::Point3(float _x, float _y, float _z) { - mVec128 = _mm_setr_ps(_x, _y, _z, 0.0f); + mVec128 = _mm_setr_ps(_x, _y, _z, 0.0f); } -VECTORMATH_FORCE_INLINE Point3::Point3( const floatInVec &_x, const floatInVec &_y, const floatInVec &_z ) +VECTORMATH_FORCE_INLINE Point3::Point3(const floatInVec &_x, const floatInVec &_y, const floatInVec &_z) { - mVec128 = _mm_unpacklo_ps( _mm_unpacklo_ps( _x.get128(), _z.get128() ), _y.get128() ); + mVec128 = _mm_unpacklo_ps(_mm_unpacklo_ps(_x.get128(), _z.get128()), _y.get128()); } -VECTORMATH_FORCE_INLINE Point3::Point3( const Vector3 &vec ) +VECTORMATH_FORCE_INLINE Point3::Point3(const Vector3 &vec) { - mVec128 = vec.get128(); + mVec128 = vec.get128(); } -VECTORMATH_FORCE_INLINE Point3::Point3( float scalar ) +VECTORMATH_FORCE_INLINE Point3::Point3(float scalar) { - mVec128 = floatInVec(scalar).get128(); + mVec128 = floatInVec(scalar).get128(); } -VECTORMATH_FORCE_INLINE Point3::Point3( const floatInVec &scalar ) +VECTORMATH_FORCE_INLINE Point3::Point3(const floatInVec &scalar) { - mVec128 = scalar.get128(); + mVec128 = scalar.get128(); } -VECTORMATH_FORCE_INLINE Point3::Point3( __m128 vf4 ) +VECTORMATH_FORCE_INLINE Point3::Point3(__m128 vf4) { - mVec128 = vf4; + mVec128 = vf4; } -VECTORMATH_FORCE_INLINE const Point3 lerp( float t, const Point3 &pnt0, const Point3 &pnt1 ) +VECTORMATH_FORCE_INLINE const Point3 lerp(float t, const Point3 &pnt0, const Point3 &pnt1) { - return lerp( floatInVec(t), pnt0, pnt1 ); + return lerp(floatInVec(t), pnt0, pnt1); } -VECTORMATH_FORCE_INLINE const Point3 lerp( const floatInVec &t, const Point3 &pnt0, const Point3 &pnt1 ) +VECTORMATH_FORCE_INLINE const Point3 lerp(const floatInVec &t, const Point3 &pnt0, const Point3 &pnt1) { - return ( pnt0 + ( ( pnt1 - pnt0 ) * t ) ); + return (pnt0 + ((pnt1 - pnt0) * t)); } -VECTORMATH_FORCE_INLINE __m128 Point3::get128( ) const +VECTORMATH_FORCE_INLINE __m128 Point3::get128() const { - return mVec128; + return mVec128; } -VECTORMATH_FORCE_INLINE void storeXYZ( const Point3 &pnt, __m128 * quad ) +VECTORMATH_FORCE_INLINE void storeXYZ(const Point3 &pnt, __m128 *quad) { - __m128 dstVec = *quad; - VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; // TODO: Centralize - dstVec = vec_sel(pnt.get128(), dstVec, sw); - *quad = dstVec; + __m128 dstVec = *quad; + VM_ATTRIBUTE_ALIGN16 unsigned int sw[4] = {0, 0, 0, 0xffffffff}; // TODO: Centralize + dstVec = vec_sel(pnt.get128(), dstVec, sw); + *quad = dstVec; } -VECTORMATH_FORCE_INLINE void loadXYZArray( Point3 & pnt0, Point3 & pnt1, Point3 & pnt2, Point3 & pnt3, const __m128 * threeQuads ) +VECTORMATH_FORCE_INLINE void loadXYZArray(Point3 &pnt0, Point3 &pnt1, Point3 &pnt2, Point3 &pnt3, const __m128 *threeQuads) { const float *quads = (float *)threeQuads; - pnt0 = Point3( _mm_load_ps(quads) ); - pnt1 = Point3( _mm_loadu_ps(quads + 3) ); - pnt2 = Point3( _mm_loadu_ps(quads + 6) ); - pnt3 = Point3( _mm_loadu_ps(quads + 9) ); + pnt0 = Point3(_mm_load_ps(quads)); + pnt1 = Point3(_mm_loadu_ps(quads + 3)); + pnt2 = Point3(_mm_loadu_ps(quads + 6)); + pnt3 = Point3(_mm_loadu_ps(quads + 9)); } -VECTORMATH_FORCE_INLINE void storeXYZArray( const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, __m128 * threeQuads ) +VECTORMATH_FORCE_INLINE void storeXYZArray(const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, __m128 *threeQuads) { - __m128 xxxx = _mm_shuffle_ps( pnt1.get128(), pnt1.get128(), _MM_SHUFFLE(0, 0, 0, 0) ); - __m128 zzzz = _mm_shuffle_ps( pnt2.get128(), pnt2.get128(), _MM_SHUFFLE(2, 2, 2, 2) ); + __m128 xxxx = _mm_shuffle_ps(pnt1.get128(), pnt1.get128(), _MM_SHUFFLE(0, 0, 0, 0)); + __m128 zzzz = _mm_shuffle_ps(pnt2.get128(), pnt2.get128(), _MM_SHUFFLE(2, 2, 2, 2)); VM_ATTRIBUTE_ALIGN16 unsigned int xsw[4] = {0, 0, 0, 0xffffffff}; VM_ATTRIBUTE_ALIGN16 unsigned int zsw[4] = {0xffffffff, 0, 0, 0}; - threeQuads[0] = vec_sel( pnt0.get128(), xxxx, xsw ); - threeQuads[1] = _mm_shuffle_ps( pnt1.get128(), pnt2.get128(), _MM_SHUFFLE(1, 0, 2, 1) ); - threeQuads[2] = vec_sel( _mm_shuffle_ps( pnt3.get128(), pnt3.get128(), _MM_SHUFFLE(2, 1, 0, 3) ), zzzz, zsw ); + threeQuads[0] = vec_sel(pnt0.get128(), xxxx, xsw); + threeQuads[1] = _mm_shuffle_ps(pnt1.get128(), pnt2.get128(), _MM_SHUFFLE(1, 0, 2, 1)); + threeQuads[2] = vec_sel(_mm_shuffle_ps(pnt3.get128(), pnt3.get128(), _MM_SHUFFLE(2, 1, 0, 3)), zzzz, zsw); } /* VECTORMATH_FORCE_INLINE void storeHalfFloats( const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, const Point3 &pnt4, const Point3 &pnt5, const Point3 &pnt6, const Point3 &pnt7, vec_ushort8 * threeQuads ) @@ -1215,241 +1229,245 @@ VECTORMATH_FORCE_INLINE void storeHalfFloats( const Point3 &pnt0, const Point3 & #endif } */ -VECTORMATH_FORCE_INLINE Point3 & Point3::operator =( const Point3 &pnt ) +VECTORMATH_FORCE_INLINE Point3 &Point3::operator=(const Point3 &pnt) { - mVec128 = pnt.mVec128; - return *this; + mVec128 = pnt.mVec128; + return *this; } -VECTORMATH_FORCE_INLINE Point3 & Point3::setX( float _x ) +VECTORMATH_FORCE_INLINE Point3 &Point3::setX(float _x) { - _vmathVfSetElement(mVec128, _x, 0); - return *this; + _vmathVfSetElement(mVec128, _x, 0); + return *this; } -VECTORMATH_FORCE_INLINE Point3 & Point3::setX( const floatInVec &_x ) +VECTORMATH_FORCE_INLINE Point3 &Point3::setX(const floatInVec &_x) { - mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); - return *this; + mVec128 = _vmathVfInsert(mVec128, _x.get128(), 0); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Point3::getX( ) const +VECTORMATH_FORCE_INLINE const floatInVec Point3::getX() const { - return floatInVec( mVec128, 0 ); + return floatInVec(mVec128, 0); } -VECTORMATH_FORCE_INLINE Point3 & Point3::setY( float _y ) +VECTORMATH_FORCE_INLINE Point3 &Point3::setY(float _y) { - _vmathVfSetElement(mVec128, _y, 1); - return *this; + _vmathVfSetElement(mVec128, _y, 1); + return *this; } -VECTORMATH_FORCE_INLINE Point3 & Point3::setY( const floatInVec &_y ) +VECTORMATH_FORCE_INLINE Point3 &Point3::setY(const floatInVec &_y) { - mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); - return *this; + mVec128 = _vmathVfInsert(mVec128, _y.get128(), 1); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Point3::getY( ) const +VECTORMATH_FORCE_INLINE const floatInVec Point3::getY() const { - return floatInVec( mVec128, 1 ); + return floatInVec(mVec128, 1); } -VECTORMATH_FORCE_INLINE Point3 & Point3::setZ( float _z ) +VECTORMATH_FORCE_INLINE Point3 &Point3::setZ(float _z) { - _vmathVfSetElement(mVec128, _z, 2); - return *this; + _vmathVfSetElement(mVec128, _z, 2); + return *this; } -VECTORMATH_FORCE_INLINE Point3 & Point3::setZ( const floatInVec &_z ) +VECTORMATH_FORCE_INLINE Point3 &Point3::setZ(const floatInVec &_z) { - mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); - return *this; + mVec128 = _vmathVfInsert(mVec128, _z.get128(), 2); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Point3::getZ( ) const +VECTORMATH_FORCE_INLINE const floatInVec Point3::getZ() const { - return floatInVec( mVec128, 2 ); + return floatInVec(mVec128, 2); } -VECTORMATH_FORCE_INLINE Point3 & Point3::setElem( int idx, float value ) +VECTORMATH_FORCE_INLINE Point3 &Point3::setElem(int idx, float value) { - _vmathVfSetElement(mVec128, value, idx); - return *this; + _vmathVfSetElement(mVec128, value, idx); + return *this; } -VECTORMATH_FORCE_INLINE Point3 & Point3::setElem( int idx, const floatInVec &value ) +VECTORMATH_FORCE_INLINE Point3 &Point3::setElem(int idx, const floatInVec &value) { - mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); - return *this; + mVec128 = _vmathVfInsert(mVec128, value.get128(), idx); + return *this; } -VECTORMATH_FORCE_INLINE const floatInVec Point3::getElem( int idx ) const +VECTORMATH_FORCE_INLINE const floatInVec Point3::getElem(int idx) const { - return floatInVec( mVec128, idx ); + return floatInVec(mVec128, idx); } -VECTORMATH_FORCE_INLINE VecIdx Point3::operator []( int idx ) +VECTORMATH_FORCE_INLINE VecIdx Point3::operator[](int idx) { - return VecIdx( mVec128, idx ); + return VecIdx(mVec128, idx); } -VECTORMATH_FORCE_INLINE const floatInVec Point3::operator []( int idx ) const +VECTORMATH_FORCE_INLINE const floatInVec Point3::operator[](int idx) const { - return floatInVec( mVec128, idx ); + return floatInVec(mVec128, idx); } -VECTORMATH_FORCE_INLINE const Vector3 Point3::operator -( const Point3 &pnt ) const +VECTORMATH_FORCE_INLINE const Vector3 Point3::operator-(const Point3 &pnt) const { - return Vector3( _mm_sub_ps( mVec128, pnt.mVec128 ) ); + return Vector3(_mm_sub_ps(mVec128, pnt.mVec128)); } -VECTORMATH_FORCE_INLINE const Point3 Point3::operator +( const Vector3 &vec ) const +VECTORMATH_FORCE_INLINE const Point3 Point3::operator+(const Vector3 &vec) const { - return Point3( _mm_add_ps( mVec128, vec.get128() ) ); + return Point3(_mm_add_ps(mVec128, vec.get128())); } -VECTORMATH_FORCE_INLINE const Point3 Point3::operator -( const Vector3 &vec ) const +VECTORMATH_FORCE_INLINE const Point3 Point3::operator-(const Vector3 &vec) const { - return Point3( _mm_sub_ps( mVec128, vec.get128() ) ); + return Point3(_mm_sub_ps(mVec128, vec.get128())); } -VECTORMATH_FORCE_INLINE Point3 & Point3::operator +=( const Vector3 &vec ) +VECTORMATH_FORCE_INLINE Point3 &Point3::operator+=(const Vector3 &vec) { - *this = *this + vec; - return *this; + *this = *this + vec; + return *this; } -VECTORMATH_FORCE_INLINE Point3 & Point3::operator -=( const Vector3 &vec ) +VECTORMATH_FORCE_INLINE Point3 &Point3::operator-=(const Vector3 &vec) { - *this = *this - vec; - return *this; + *this = *this - vec; + return *this; } -VECTORMATH_FORCE_INLINE const Point3 mulPerElem( const Point3 &pnt0, const Point3 &pnt1 ) +VECTORMATH_FORCE_INLINE const Point3 mulPerElem(const Point3 &pnt0, const Point3 &pnt1) { - return Point3( _mm_mul_ps( pnt0.get128(), pnt1.get128() ) ); + return Point3(_mm_mul_ps(pnt0.get128(), pnt1.get128())); } -VECTORMATH_FORCE_INLINE const Point3 divPerElem( const Point3 &pnt0, const Point3 &pnt1 ) +VECTORMATH_FORCE_INLINE const Point3 divPerElem(const Point3 &pnt0, const Point3 &pnt1) { - return Point3( _mm_div_ps( pnt0.get128(), pnt1.get128() ) ); + return Point3(_mm_div_ps(pnt0.get128(), pnt1.get128())); } -VECTORMATH_FORCE_INLINE const Point3 recipPerElem( const Point3 &pnt ) +VECTORMATH_FORCE_INLINE const Point3 recipPerElem(const Point3 &pnt) { - return Point3( _mm_rcp_ps( pnt.get128() ) ); + return Point3(_mm_rcp_ps(pnt.get128())); } -VECTORMATH_FORCE_INLINE const Point3 absPerElem( const Point3 &pnt ) +VECTORMATH_FORCE_INLINE const Point3 absPerElem(const Point3 &pnt) { - return Point3( fabsf4( pnt.get128() ) ); + return Point3(fabsf4(pnt.get128())); } -VECTORMATH_FORCE_INLINE const Point3 copySignPerElem( const Point3 &pnt0, const Point3 &pnt1 ) +VECTORMATH_FORCE_INLINE const Point3 copySignPerElem(const Point3 &pnt0, const Point3 &pnt1) { __m128 vmask = toM128(0x7fffffff); - return Point3( _mm_or_ps( - _mm_and_ps ( vmask, pnt0.get128() ), // Value - _mm_andnot_ps( vmask, pnt1.get128() ) ) ); // Signs + return Point3(_mm_or_ps( + _mm_and_ps(vmask, pnt0.get128()), // Value + _mm_andnot_ps(vmask, pnt1.get128()))); // Signs } -VECTORMATH_FORCE_INLINE const Point3 maxPerElem( const Point3 &pnt0, const Point3 &pnt1 ) +VECTORMATH_FORCE_INLINE const Point3 maxPerElem(const Point3 &pnt0, const Point3 &pnt1) { - return Point3( _mm_max_ps( pnt0.get128(), pnt1.get128() ) ); + return Point3(_mm_max_ps(pnt0.get128(), pnt1.get128())); } -VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Point3 &pnt ) +VECTORMATH_FORCE_INLINE const floatInVec maxElem(const Point3 &pnt) { - return floatInVec( _mm_max_ps( _mm_max_ps( vec_splat( pnt.get128(), 0 ), vec_splat( pnt.get128(), 1 ) ), vec_splat( pnt.get128(), 2 ) ) ); + return floatInVec(_mm_max_ps(_mm_max_ps(vec_splat(pnt.get128(), 0), vec_splat(pnt.get128(), 1)), vec_splat(pnt.get128(), 2))); } -VECTORMATH_FORCE_INLINE const Point3 minPerElem( const Point3 &pnt0, const Point3 &pnt1 ) +VECTORMATH_FORCE_INLINE const Point3 minPerElem(const Point3 &pnt0, const Point3 &pnt1) { - return Point3( _mm_min_ps( pnt0.get128(), pnt1.get128() ) ); + return Point3(_mm_min_ps(pnt0.get128(), pnt1.get128())); } -VECTORMATH_FORCE_INLINE const floatInVec minElem( const Point3 &pnt ) +VECTORMATH_FORCE_INLINE const floatInVec minElem(const Point3 &pnt) { - return floatInVec( _mm_min_ps( _mm_min_ps( vec_splat( pnt.get128(), 0 ), vec_splat( pnt.get128(), 1 ) ), vec_splat( pnt.get128(), 2 ) ) ); + return floatInVec(_mm_min_ps(_mm_min_ps(vec_splat(pnt.get128(), 0), vec_splat(pnt.get128(), 1)), vec_splat(pnt.get128(), 2))); } -VECTORMATH_FORCE_INLINE const floatInVec sum( const Point3 &pnt ) +VECTORMATH_FORCE_INLINE const floatInVec sum(const Point3 &pnt) { - return floatInVec( _mm_add_ps( _mm_add_ps( vec_splat( pnt.get128(), 0 ), vec_splat( pnt.get128(), 1 ) ), vec_splat( pnt.get128(), 2 ) ) ); + return floatInVec(_mm_add_ps(_mm_add_ps(vec_splat(pnt.get128(), 0), vec_splat(pnt.get128(), 1)), vec_splat(pnt.get128(), 2))); } -VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, float scaleVal ) +VECTORMATH_FORCE_INLINE const Point3 scale(const Point3 &pnt, float scaleVal) { - return scale( pnt, floatInVec( scaleVal ) ); + return scale(pnt, floatInVec(scaleVal)); } -VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, const floatInVec &scaleVal ) +VECTORMATH_FORCE_INLINE const Point3 scale(const Point3 &pnt, const floatInVec &scaleVal) { - return mulPerElem( pnt, Point3( scaleVal ) ); + return mulPerElem(pnt, Point3(scaleVal)); } -VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, const Vector3 &scaleVec ) +VECTORMATH_FORCE_INLINE const Point3 scale(const Point3 &pnt, const Vector3 &scaleVec) { - return mulPerElem( pnt, Point3( scaleVec ) ); + return mulPerElem(pnt, Point3(scaleVec)); } -VECTORMATH_FORCE_INLINE const floatInVec projection( const Point3 &pnt, const Vector3 &unitVec ) +VECTORMATH_FORCE_INLINE const floatInVec projection(const Point3 &pnt, const Vector3 &unitVec) { - return floatInVec( _vmathVfDot3( pnt.get128(), unitVec.get128() ), 0 ); + return floatInVec(_vmathVfDot3(pnt.get128(), unitVec.get128()), 0); } -VECTORMATH_FORCE_INLINE const floatInVec distSqrFromOrigin( const Point3 &pnt ) +VECTORMATH_FORCE_INLINE const floatInVec distSqrFromOrigin(const Point3 &pnt) { - return lengthSqr( Vector3( pnt ) ); + return lengthSqr(Vector3(pnt)); } -VECTORMATH_FORCE_INLINE const floatInVec distFromOrigin( const Point3 &pnt ) +VECTORMATH_FORCE_INLINE const floatInVec distFromOrigin(const Point3 &pnt) { - return length( Vector3( pnt ) ); + return length(Vector3(pnt)); } -VECTORMATH_FORCE_INLINE const floatInVec distSqr( const Point3 &pnt0, const Point3 &pnt1 ) +VECTORMATH_FORCE_INLINE const floatInVec distSqr(const Point3 &pnt0, const Point3 &pnt1) { - return lengthSqr( ( pnt1 - pnt0 ) ); + return lengthSqr((pnt1 - pnt0)); } -VECTORMATH_FORCE_INLINE const floatInVec dist( const Point3 &pnt0, const Point3 &pnt1 ) +VECTORMATH_FORCE_INLINE const floatInVec dist(const Point3 &pnt0, const Point3 &pnt1) { - return length( ( pnt1 - pnt0 ) ); + return length((pnt1 - pnt0)); } -VECTORMATH_FORCE_INLINE const Point3 select( const Point3 &pnt0, const Point3 &pnt1, bool select1 ) +VECTORMATH_FORCE_INLINE const Point3 select(const Point3 &pnt0, const Point3 &pnt1, bool select1) { - return select( pnt0, pnt1, boolInVec(select1) ); + return select(pnt0, pnt1, boolInVec(select1)); } -VECTORMATH_FORCE_INLINE const Point3 select( const Point3 &pnt0, const Point3 &pnt1, const boolInVec &select1 ) +VECTORMATH_FORCE_INLINE const Point3 select(const Point3 &pnt0, const Point3 &pnt1, const boolInVec &select1) { - return Point3( vec_sel( pnt0.get128(), pnt1.get128(), select1.get128() ) ); + return Point3(vec_sel(pnt0.get128(), pnt1.get128(), select1.get128())); } - - #ifdef _VECTORMATH_DEBUG -VECTORMATH_FORCE_INLINE void print( const Point3 &pnt ) +VECTORMATH_FORCE_INLINE void print(const Point3 &pnt) { - union { __m128 v; float s[4]; } tmp; - tmp.v = pnt.get128(); - printf( "( %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2] ); + union { + __m128 v; + float s[4]; + } tmp; + tmp.v = pnt.get128(); + printf("( %f %f %f )\n", tmp.s[0], tmp.s[1], tmp.s[2]); } -VECTORMATH_FORCE_INLINE void print( const Point3 &pnt, const char * name ) +VECTORMATH_FORCE_INLINE void print(const Point3 &pnt, const char *name) { - union { __m128 v; float s[4]; } tmp; - tmp.v = pnt.get128(); - printf( "%s: ( %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2] ); + union { + __m128 v; + float s[4]; + } tmp; + tmp.v = pnt.get128(); + printf("%s: ( %f %f %f )\n", name, tmp.s[0], tmp.s[1], tmp.s[2]); } #endif -} // namespace Aos -} // namespace Vectormath +} // namespace Aos +} // namespace Vectormath #endif diff --git a/test/Bullet2/vectormath/sse/vecidx_aos.h b/test/Bullet2/vectormath/sse/vecidx_aos.h index 8ba4b1d75..7b63c65e1 100644 --- a/test/Bullet2/vectormath/sse/vecidx_aos.h +++ b/test/Bullet2/vectormath/sse/vecidx_aos.h @@ -30,51 +30,53 @@ #ifndef _VECTORMATH_VECIDX_AOS_H #define _VECTORMATH_VECIDX_AOS_H - #include "floatInVec.h" -namespace Vectormath { -namespace Aos { - +namespace Vectormath +{ +namespace Aos +{ //----------------------------------------------------------------------------- -// VecIdx -// Used in setting elements of Vector3, Vector4, Point3, or Quat with the +// VecIdx +// Used in setting elements of Vector3, Vector4, Point3, or Quat with the // subscripting operator. // -VM_ATTRIBUTE_ALIGNED_CLASS16 (class) VecIdx +VM_ATTRIBUTE_ALIGNED_CLASS16(class) +VecIdx { private: - __m128 &ref; - int i; -public: - inline VecIdx( __m128& vec, int idx ): ref(vec) { i = idx; } + __m128 &ref; + int i; - // implicitly casts to float unless _VECTORMATH_NO_SCALAR_CAST defined - // in which case, implicitly casts to floatInVec, and one must call - // getAsFloat to convert to float. - // +public: + inline VecIdx(__m128 & vec, int idx) : ref(vec) { i = idx; } + + // implicitly casts to float unless _VECTORMATH_NO_SCALAR_CAST defined + // in which case, implicitly casts to floatInVec, and one must call + // getAsFloat to convert to float. + // #ifdef _VECTORMATH_NO_SCALAR_CAST - inline operator floatInVec() const; - inline float getAsFloat() const; + inline operator floatInVec() const; + inline float getAsFloat() const; #else - inline operator float() const; + inline operator float() const; #endif - inline float operator =( float scalar ); - inline floatInVec operator =( const floatInVec &scalar ); - inline floatInVec operator =( const VecIdx& scalar ); - inline floatInVec operator *=( float scalar ); - inline floatInVec operator *=( const floatInVec &scalar ); - inline floatInVec operator /=( float scalar ); - inline floatInVec operator /=( const floatInVec &scalar ); - inline floatInVec operator +=( float scalar ); - inline floatInVec operator +=( const floatInVec &scalar ); - inline floatInVec operator -=( float scalar ); - inline floatInVec operator -=( const floatInVec &scalar ); + inline float operator=(float scalar); + inline floatInVec operator=(const floatInVec &scalar); + inline floatInVec operator=(const VecIdx &scalar); + inline floatInVec operator*=(float scalar); + inline floatInVec operator*=(const floatInVec &scalar); + inline floatInVec operator/=(float scalar); + inline floatInVec operator/=(const floatInVec &scalar); + inline floatInVec operator+=(float scalar); + inline floatInVec operator+=(const floatInVec &scalar); + inline floatInVec operator-=(float scalar); + inline floatInVec operator-=(const floatInVec &scalar); }; -} // namespace Aos -} // namespace Vectormath +} // namespace Aos +} // namespace Vectormath #endif diff --git a/test/Bullet2/vectormath/sse/vectormath_aos.h b/test/Bullet2/vectormath/sse/vectormath_aos.h index be5ae8c6e..c12049485 100644 --- a/test/Bullet2/vectormath/sse/vectormath_aos.h +++ b/test/Bullet2/vectormath/sse/vectormath_aos.h @@ -27,7 +27,6 @@ POSSIBILITY OF SUCH DAMAGE. */ - #ifndef _VECTORMATH_AOS_CPP_SSE_H #define _VECTORMATH_AOS_CPP_SSE_H @@ -36,30 +35,28 @@ #include #include -#define Vector3Ref Vector3& -#define QuatRef Quat& -#define Matrix3Ref Matrix3& +#define Vector3Ref Vector3 & +#define QuatRef Quat & +#define Matrix3Ref Matrix3 & -#if (defined (_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) - #define USE_SSE3_LDDQU +#if (defined(_WIN32) && (_MSC_VER) && _MSC_VER >= 1400) +#define USE_SSE3_LDDQU - #define VM_ATTRIBUTE_ALIGNED_CLASS16(a) __declspec(align(16)) a - #define VM_ATTRIBUTE_ALIGN16 __declspec(align(16)) - #define VECTORMATH_FORCE_INLINE __forceinline +#define VM_ATTRIBUTE_ALIGNED_CLASS16(a) __declspec(align(16)) a +#define VM_ATTRIBUTE_ALIGN16 __declspec(align(16)) +#define VECTORMATH_FORCE_INLINE __forceinline #else - #define VM_ATTRIBUTE_ALIGNED_CLASS16(a) a __attribute__ ((aligned (16))) - #define VM_ATTRIBUTE_ALIGN16 __attribute__ ((aligned (16))) - #define VECTORMATH_FORCE_INLINE inline __attribute__ ((always_inline)) - #ifdef __SSE3__ - #define USE_SSE3_LDDQU - #endif //__SSE3__ -#endif//_WIN32 - +#define VM_ATTRIBUTE_ALIGNED_CLASS16(a) a __attribute__((aligned(16))) +#define VM_ATTRIBUTE_ALIGN16 __attribute__((aligned(16))) +#define VECTORMATH_FORCE_INLINE inline __attribute__((always_inline)) +#ifdef __SSE3__ +#define USE_SSE3_LDDQU +#endif //__SSE3__ +#endif //_WIN32 #ifdef USE_SSE3_LDDQU -#include //_mm_lddqu_si128 -#endif //USE_SSE3_LDDQU - +#include //_mm_lddqu_si128 +#endif //USE_SSE3_LDDQU // TODO: Tidy typedef __m128 vec_float4; @@ -68,31 +65,30 @@ typedef __m128 vec_int4; typedef __m128i vec_uchar16; typedef __m128i vec_ushort8; -#define vec_splat(x, e) _mm_shuffle_ps(x, x, _MM_SHUFFLE(e,e,e,e)) +#define vec_splat(x, e) _mm_shuffle_ps(x, x, _MM_SHUFFLE(e, e, e, e)) -#define _mm_ror_ps(vec,i) \ - (((i)%4) ? (_mm_shuffle_ps(vec,vec, _MM_SHUFFLE((unsigned char)(i+3)%4,(unsigned char)(i+2)%4,(unsigned char)(i+1)%4,(unsigned char)(i+0)%4))) : (vec)) -#define _mm_rol_ps(vec,i) \ - (((i)%4) ? (_mm_shuffle_ps(vec,vec, _MM_SHUFFLE((unsigned char)(7-i)%4,(unsigned char)(6-i)%4,(unsigned char)(5-i)%4,(unsigned char)(4-i)%4))) : (vec)) +#define _mm_ror_ps(vec, i) \ + (((i) % 4) ? (_mm_shuffle_ps(vec, vec, _MM_SHUFFLE((unsigned char)(i + 3) % 4, (unsigned char)(i + 2) % 4, (unsigned char)(i + 1) % 4, (unsigned char)(i + 0) % 4))) : (vec)) +#define _mm_rol_ps(vec, i) \ + (((i) % 4) ? (_mm_shuffle_ps(vec, vec, _MM_SHUFFLE((unsigned char)(7 - i) % 4, (unsigned char)(6 - i) % 4, (unsigned char)(5 - i) % 4, (unsigned char)(4 - i) % 4))) : (vec)) -#define vec_sld(vec,vec2,x) _mm_ror_ps(vec, ((x)/4)) +#define vec_sld(vec, vec2, x) _mm_ror_ps(vec, ((x) / 4)) -#define _mm_abs_ps(vec) _mm_andnot_ps(_MASKSIGN_,vec) -#define _mm_neg_ps(vec) _mm_xor_ps(_MASKSIGN_,vec) +#define _mm_abs_ps(vec) _mm_andnot_ps(_MASKSIGN_, vec) +#define _mm_neg_ps(vec) _mm_xor_ps(_MASKSIGN_, vec) -#define vec_madd(a, b, c) _mm_add_ps(c, _mm_mul_ps(a, b) ) +#define vec_madd(a, b, c) _mm_add_ps(c, _mm_mul_ps(a, b)) -union SSEFloat -{ +union SSEFloat { __m128i vi; __m128 m128; __m128 vf; - unsigned int ui[4]; + unsigned int ui[4]; unsigned short s[8]; float f[4]; SSEFloat(__m128 v) : m128(v) {} - SSEFloat(__m128i v) : vi(v) {} - SSEFloat() {}//uninitialized + SSEFloat(__m128i v) : vi(v) {} + SSEFloat() {} //uninitialized }; static VECTORMATH_FORCE_INLINE __m128 vec_sel(__m128 a, __m128 b, __m128 mask) @@ -110,12 +106,12 @@ static VECTORMATH_FORCE_INLINE __m128 vec_sel(__m128 a, __m128 b, unsigned int _ static VECTORMATH_FORCE_INLINE __m128 toM128(unsigned int x) { - return _mm_set1_ps( *(float *)&x ); + return _mm_set1_ps(*(float *)&x); } static VECTORMATH_FORCE_INLINE __m128 fabsf4(__m128 x) { - return _mm_and_ps( x, toM128( 0x7fffffff ) ); + return _mm_and_ps(x, toM128(0x7fffffff)); } /* union SSE64 @@ -154,210 +150,211 @@ static VECTORMATH_FORCE_INLINE __m128 vec_ctf(__m128 x, int a) */ static VECTORMATH_FORCE_INLINE __m128 vec_cts(__m128 x, int a) { - assert(a == 0); // Only 2^0 supported + assert(a == 0); // Only 2^0 supported (void)a; __m128i result = _mm_cvtps_epi32(x); - return (__m128 &)result; + return (__m128 &)result; } static VECTORMATH_FORCE_INLINE __m128 vec_ctf(__m128 x, int a) { - assert(a == 0); // Only 2^0 supported + assert(a == 0); // Only 2^0 supported (void)a; return _mm_cvtepi32_ps((__m128i &)x); } -#define vec_nmsub(a,b,c) _mm_sub_ps( c, _mm_mul_ps( a, b ) ) -#define vec_sub(a,b) _mm_sub_ps( a, b ) -#define vec_add(a,b) _mm_add_ps( a, b ) -#define vec_mul(a,b) _mm_mul_ps( a, b ) -#define vec_xor(a,b) _mm_xor_ps( a, b ) -#define vec_and(a,b) _mm_and_ps( a, b ) -#define vec_cmpeq(a,b) _mm_cmpeq_ps( a, b ) -#define vec_cmpgt(a,b) _mm_cmpgt_ps( a, b ) +#define vec_nmsub(a, b, c) _mm_sub_ps(c, _mm_mul_ps(a, b)) +#define vec_sub(a, b) _mm_sub_ps(a, b) +#define vec_add(a, b) _mm_add_ps(a, b) +#define vec_mul(a, b) _mm_mul_ps(a, b) +#define vec_xor(a, b) _mm_xor_ps(a, b) +#define vec_and(a, b) _mm_and_ps(a, b) +#define vec_cmpeq(a, b) _mm_cmpeq_ps(a, b) +#define vec_cmpgt(a, b) _mm_cmpgt_ps(a, b) -#define vec_mergeh(a,b) _mm_unpacklo_ps( a, b ) -#define vec_mergel(a,b) _mm_unpackhi_ps( a, b ) +#define vec_mergeh(a, b) _mm_unpacklo_ps(a, b) +#define vec_mergel(a, b) _mm_unpackhi_ps(a, b) -#define vec_andc(a,b) _mm_andnot_ps( b, a ) +#define vec_andc(a, b) _mm_andnot_ps(b, a) -#define sqrtf4(x) _mm_sqrt_ps( x ) -#define rsqrtf4(x) _mm_rsqrt_ps( x ) -#define recipf4(x) _mm_rcp_ps( x ) -#define negatef4(x) _mm_sub_ps( _mm_setzero_ps(), x ) +#define sqrtf4(x) _mm_sqrt_ps(x) +#define rsqrtf4(x) _mm_rsqrt_ps(x) +#define recipf4(x) _mm_rcp_ps(x) +#define negatef4(x) _mm_sub_ps(_mm_setzero_ps(), x) -static VECTORMATH_FORCE_INLINE __m128 newtonrapson_rsqrt4( const __m128 v ) -{ -#define _half4 _mm_setr_ps(.5f,.5f,.5f,.5f) -#define _three _mm_setr_ps(3.f,3.f,3.f,3.f) -const __m128 approx = _mm_rsqrt_ps( v ); -const __m128 muls = _mm_mul_ps(_mm_mul_ps(v, approx), approx); -return _mm_mul_ps(_mm_mul_ps(_half4, approx), _mm_sub_ps(_three, muls) ); +static VECTORMATH_FORCE_INLINE __m128 newtonrapson_rsqrt4(const __m128 v) +{ +#define _half4 _mm_setr_ps(.5f, .5f, .5f, .5f) +#define _three _mm_setr_ps(3.f, 3.f, 3.f, 3.f) + const __m128 approx = _mm_rsqrt_ps(v); + const __m128 muls = _mm_mul_ps(_mm_mul_ps(v, approx), approx); + return _mm_mul_ps(_mm_mul_ps(_half4, approx), _mm_sub_ps(_three, muls)); } static VECTORMATH_FORCE_INLINE __m128 acosf4(__m128 x) { - __m128 xabs = fabsf4(x); - __m128 select = _mm_cmplt_ps( x, _mm_setzero_ps() ); - __m128 t1 = sqrtf4(vec_sub(_mm_set1_ps(1.0f), xabs)); - - /* Instruction counts can be reduced if the polynomial was + __m128 xabs = fabsf4(x); + __m128 select = _mm_cmplt_ps(x, _mm_setzero_ps()); + __m128 t1 = sqrtf4(vec_sub(_mm_set1_ps(1.0f), xabs)); + + /* Instruction counts can be reduced if the polynomial was * computed entirely from nested (dependent) fma's. However, * to reduce the number of pipeline stalls, the polygon is evaluated * in two halves (hi amd lo). */ - __m128 xabs2 = _mm_mul_ps(xabs, xabs); - __m128 xabs4 = _mm_mul_ps(xabs2, xabs2); - __m128 hi = vec_madd(vec_madd(vec_madd(_mm_set1_ps(-0.0012624911f), - xabs, _mm_set1_ps(0.0066700901f)), - xabs, _mm_set1_ps(-0.0170881256f)), - xabs, _mm_set1_ps( 0.0308918810f)); - __m128 lo = vec_madd(vec_madd(vec_madd(_mm_set1_ps(-0.0501743046f), - xabs, _mm_set1_ps(0.0889789874f)), - xabs, _mm_set1_ps(-0.2145988016f)), - xabs, _mm_set1_ps( 1.5707963050f)); - - __m128 result = vec_madd(hi, xabs4, lo); - - // Adjust the result if x is negactive. - return vec_sel( - vec_mul(t1, result), // Positive - vec_nmsub(t1, result, _mm_set1_ps(3.1415926535898f)), // Negative + __m128 xabs2 = _mm_mul_ps(xabs, xabs); + __m128 xabs4 = _mm_mul_ps(xabs2, xabs2); + __m128 hi = vec_madd(vec_madd(vec_madd(_mm_set1_ps(-0.0012624911f), + xabs, _mm_set1_ps(0.0066700901f)), + xabs, _mm_set1_ps(-0.0170881256f)), + xabs, _mm_set1_ps(0.0308918810f)); + __m128 lo = vec_madd(vec_madd(vec_madd(_mm_set1_ps(-0.0501743046f), + xabs, _mm_set1_ps(0.0889789874f)), + xabs, _mm_set1_ps(-0.2145988016f)), + xabs, _mm_set1_ps(1.5707963050f)); + + __m128 result = vec_madd(hi, xabs4, lo); + + // Adjust the result if x is negactive. + return vec_sel( + vec_mul(t1, result), // Positive + vec_nmsub(t1, result, _mm_set1_ps(3.1415926535898f)), // Negative select); } static VECTORMATH_FORCE_INLINE __m128 sinf4(vec_float4 x) { - // // Common constants used to evaluate sinf4/cosf4/tanf4 // -#define _SINCOS_CC0 -0.0013602249f -#define _SINCOS_CC1 0.0416566950f -#define _SINCOS_CC2 -0.4999990225f -#define _SINCOS_SC0 -0.0001950727f -#define _SINCOS_SC1 0.0083320758f -#define _SINCOS_SC2 -0.1666665247f +#define _SINCOS_CC0 -0.0013602249f +#define _SINCOS_CC1 0.0416566950f +#define _SINCOS_CC2 -0.4999990225f +#define _SINCOS_SC0 -0.0001950727f +#define _SINCOS_SC1 0.0083320758f +#define _SINCOS_SC2 -0.1666665247f -#define _SINCOS_KC1 1.57079625129f -#define _SINCOS_KC2 7.54978995489e-8f +#define _SINCOS_KC1 1.57079625129f +#define _SINCOS_KC2 7.54978995489e-8f - vec_float4 xl,xl2,xl3,res; + vec_float4 xl, xl2, xl3, res; - // Range reduction using : xl = angle * TwoOverPi; - // - xl = vec_mul(x, _mm_set1_ps(0.63661977236f)); + // Range reduction using : xl = angle * TwoOverPi; + // + xl = vec_mul(x, _mm_set1_ps(0.63661977236f)); - // Find the quadrant the angle falls in - // using: q = (int) (ceil(abs(xl))*sign(xl)) - // - vec_int4 q = vec_cts(xl,0); + // Find the quadrant the angle falls in + // using: q = (int) (ceil(abs(xl))*sign(xl)) + // + vec_int4 q = vec_cts(xl, 0); - // Compute an offset based on the quadrant that the angle falls in - // - vec_int4 offset = _mm_and_ps(q,toM128(0x3)); + // Compute an offset based on the quadrant that the angle falls in + // + vec_int4 offset = _mm_and_ps(q, toM128(0x3)); - // Remainder in range [-pi/4..pi/4] - // - vec_float4 qf = vec_ctf(q,0); - xl = vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC2),vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC1),x)); - - // Compute x^2 and x^3 - // - xl2 = vec_mul(xl,xl); - xl3 = vec_mul(xl2,xl); - - // Compute both the sin and cos of the angles - // using a polynomial expression: - // cx = 1.0f + xl2 * ((C0 * xl2 + C1) * xl2 + C2), and - // sx = xl + xl3 * ((S0 * xl2 + S1) * xl2 + S2) - // - - vec_float4 cx = + // Remainder in range [-pi/4..pi/4] + // + vec_float4 qf = vec_ctf(q, 0); + xl = vec_nmsub(qf, _mm_set1_ps(_SINCOS_KC2), vec_nmsub(qf, _mm_set1_ps(_SINCOS_KC1), x)); + + // Compute x^2 and x^3 + // + xl2 = vec_mul(xl, xl); + xl3 = vec_mul(xl2, xl); + + // Compute both the sin and cos of the angles + // using a polynomial expression: + // cx = 1.0f + xl2 * ((C0 * xl2 + C1) * xl2 + C2), and + // sx = xl + xl3 * ((S0 * xl2 + S1) * xl2 + S2) + // + + vec_float4 cx = vec_madd( vec_madd( - vec_madd(_mm_set1_ps(_SINCOS_CC0),xl2,_mm_set1_ps(_SINCOS_CC1)),xl2,_mm_set1_ps(_SINCOS_CC2)),xl2,_mm_set1_ps(1.0f)); - vec_float4 sx = + vec_madd(_mm_set1_ps(_SINCOS_CC0), xl2, _mm_set1_ps(_SINCOS_CC1)), xl2, _mm_set1_ps(_SINCOS_CC2)), + xl2, _mm_set1_ps(1.0f)); + vec_float4 sx = vec_madd( vec_madd( - vec_madd(_mm_set1_ps(_SINCOS_SC0),xl2,_mm_set1_ps(_SINCOS_SC1)),xl2,_mm_set1_ps(_SINCOS_SC2)),xl3,xl); + vec_madd(_mm_set1_ps(_SINCOS_SC0), xl2, _mm_set1_ps(_SINCOS_SC1)), xl2, _mm_set1_ps(_SINCOS_SC2)), + xl3, xl); - // Use the cosine when the offset is odd and the sin - // when the offset is even - // - res = vec_sel(cx,sx,vec_cmpeq(vec_and(offset, - toM128(0x1)), - _mm_setzero_ps())); + // Use the cosine when the offset is odd and the sin + // when the offset is even + // + res = vec_sel(cx, sx, vec_cmpeq(vec_and(offset, toM128(0x1)), _mm_setzero_ps())); - // Flip the sign of the result when (offset mod 4) = 1 or 2 - // - return vec_sel( - vec_xor(toM128(0x80000000U), res), // Negative - res, // Positive - vec_cmpeq(vec_and(offset,toM128(0x2)),_mm_setzero_ps())); + // Flip the sign of the result when (offset mod 4) = 1 or 2 + // + return vec_sel( + vec_xor(toM128(0x80000000U), res), // Negative + res, // Positive + vec_cmpeq(vec_and(offset, toM128(0x2)), _mm_setzero_ps())); } -static VECTORMATH_FORCE_INLINE void sincosf4(vec_float4 x, vec_float4* s, vec_float4* c) +static VECTORMATH_FORCE_INLINE void sincosf4(vec_float4 x, vec_float4 *s, vec_float4 *c) { - vec_float4 xl,xl2,xl3; - vec_int4 offsetSin, offsetCos; + vec_float4 xl, xl2, xl3; + vec_int4 offsetSin, offsetCos; - // Range reduction using : xl = angle * TwoOverPi; - // - xl = vec_mul(x, _mm_set1_ps(0.63661977236f)); + // Range reduction using : xl = angle * TwoOverPi; + // + xl = vec_mul(x, _mm_set1_ps(0.63661977236f)); - // Find the quadrant the angle falls in - // using: q = (int) (ceil(abs(xl))*sign(xl)) - // - //vec_int4 q = vec_cts(vec_add(xl,vec_sel(_mm_set1_ps(0.5f),xl,(0x80000000))),0); - vec_int4 q = vec_cts(xl,0); - - // Compute the offset based on the quadrant that the angle falls in. - // Add 1 to the offset for the cosine. - // - offsetSin = vec_and(q,toM128((int)0x3)); - __m128i temp = _mm_add_epi32(_mm_set1_epi32(1),(__m128i &)offsetSin); + // Find the quadrant the angle falls in + // using: q = (int) (ceil(abs(xl))*sign(xl)) + // + //vec_int4 q = vec_cts(vec_add(xl,vec_sel(_mm_set1_ps(0.5f),xl,(0x80000000))),0); + vec_int4 q = vec_cts(xl, 0); + + // Compute the offset based on the quadrant that the angle falls in. + // Add 1 to the offset for the cosine. + // + offsetSin = vec_and(q, toM128((int)0x3)); + __m128i temp = _mm_add_epi32(_mm_set1_epi32(1), (__m128i &)offsetSin); offsetCos = (__m128 &)temp; - // Remainder in range [-pi/4..pi/4] - // - vec_float4 qf = vec_ctf(q,0); - xl = vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC2),vec_nmsub(qf,_mm_set1_ps(_SINCOS_KC1),x)); - - // Compute x^2 and x^3 - // - xl2 = vec_mul(xl,xl); - xl3 = vec_mul(xl2,xl); - - // Compute both the sin and cos of the angles - // using a polynomial expression: - // cx = 1.0f + xl2 * ((C0 * xl2 + C1) * xl2 + C2), and - // sx = xl + xl3 * ((S0 * xl2 + S1) * xl2 + S2) - // - vec_float4 cx = + // Remainder in range [-pi/4..pi/4] + // + vec_float4 qf = vec_ctf(q, 0); + xl = vec_nmsub(qf, _mm_set1_ps(_SINCOS_KC2), vec_nmsub(qf, _mm_set1_ps(_SINCOS_KC1), x)); + + // Compute x^2 and x^3 + // + xl2 = vec_mul(xl, xl); + xl3 = vec_mul(xl2, xl); + + // Compute both the sin and cos of the angles + // using a polynomial expression: + // cx = 1.0f + xl2 * ((C0 * xl2 + C1) * xl2 + C2), and + // sx = xl + xl3 * ((S0 * xl2 + S1) * xl2 + S2) + // + vec_float4 cx = vec_madd( vec_madd( - vec_madd(_mm_set1_ps(_SINCOS_CC0),xl2,_mm_set1_ps(_SINCOS_CC1)),xl2,_mm_set1_ps(_SINCOS_CC2)),xl2,_mm_set1_ps(1.0f)); - vec_float4 sx = + vec_madd(_mm_set1_ps(_SINCOS_CC0), xl2, _mm_set1_ps(_SINCOS_CC1)), xl2, _mm_set1_ps(_SINCOS_CC2)), + xl2, _mm_set1_ps(1.0f)); + vec_float4 sx = vec_madd( vec_madd( - vec_madd(_mm_set1_ps(_SINCOS_SC0),xl2,_mm_set1_ps(_SINCOS_SC1)),xl2,_mm_set1_ps(_SINCOS_SC2)),xl3,xl); + vec_madd(_mm_set1_ps(_SINCOS_SC0), xl2, _mm_set1_ps(_SINCOS_SC1)), xl2, _mm_set1_ps(_SINCOS_SC2)), + xl3, xl); - // Use the cosine when the offset is odd and the sin - // when the offset is even - // - vec_uint4 sinMask = (vec_uint4)vec_cmpeq(vec_and(offsetSin,toM128(0x1)),_mm_setzero_ps()); - vec_uint4 cosMask = (vec_uint4)vec_cmpeq(vec_and(offsetCos,toM128(0x1)),_mm_setzero_ps()); - *s = vec_sel(cx,sx,sinMask); - *c = vec_sel(cx,sx,cosMask); + // Use the cosine when the offset is odd and the sin + // when the offset is even + // + vec_uint4 sinMask = (vec_uint4)vec_cmpeq(vec_and(offsetSin, toM128(0x1)), _mm_setzero_ps()); + vec_uint4 cosMask = (vec_uint4)vec_cmpeq(vec_and(offsetCos, toM128(0x1)), _mm_setzero_ps()); + *s = vec_sel(cx, sx, sinMask); + *c = vec_sel(cx, sx, cosMask); - // Flip the sign of the result when (offset mod 4) = 1 or 2 - // - sinMask = vec_cmpeq(vec_and(offsetSin,toM128(0x2)),_mm_setzero_ps()); - cosMask = vec_cmpeq(vec_and(offsetCos,toM128(0x2)),_mm_setzero_ps()); - - *s = vec_sel((vec_float4)vec_xor(toM128(0x80000000),(vec_uint4)*s),*s,sinMask); - *c = vec_sel((vec_float4)vec_xor(toM128(0x80000000),(vec_uint4)*c),*c,cosMask); + // Flip the sign of the result when (offset mod 4) = 1 or 2 + // + sinMask = vec_cmpeq(vec_and(offsetSin, toM128(0x2)), _mm_setzero_ps()); + cosMask = vec_cmpeq(vec_and(offsetCos, toM128(0x2)), _mm_setzero_ps()); + + *s = vec_sel((vec_float4)vec_xor(toM128(0x80000000), (vec_uint4)*s), *s, sinMask); + *c = vec_sel((vec_float4)vec_xor(toM128(0x80000000), (vec_uint4)*c), *c, cosMask); } #include "vecidx_aos.h" @@ -367,10 +364,10 @@ static VECTORMATH_FORCE_INLINE void sincosf4(vec_float4 x, vec_float4* s, vec_fl #ifdef _VECTORMATH_DEBUG #include #endif -namespace Vectormath { - -namespace Aos { - +namespace Vectormath +{ +namespace Aos +{ //----------------------------------------------------------------------------- // Forward Declarations // @@ -387,342 +384,341 @@ class Transform3; // class Vector3 { - __m128 mVec128; + __m128 mVec128; VECTORMATH_FORCE_INLINE void set128(vec_float4 vec); - - VECTORMATH_FORCE_INLINE vec_float4& get128Ref(); + + VECTORMATH_FORCE_INLINE vec_float4 &get128Ref(); public: - // Default constructor; does no initialization - // - VECTORMATH_FORCE_INLINE Vector3( ) { }; + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Vector3(){}; // Default copy constructor - // - VECTORMATH_FORCE_INLINE Vector3(const Vector3& vec); + // + VECTORMATH_FORCE_INLINE Vector3(const Vector3 &vec); - // Construct a 3-D vector from x, y, and z elements - // - VECTORMATH_FORCE_INLINE Vector3( float x, float y, float z ); + // Construct a 3-D vector from x, y, and z elements + // + VECTORMATH_FORCE_INLINE Vector3(float x, float y, float z); - // Construct a 3-D vector from x, y, and z elements (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Vector3( const floatInVec &x, const floatInVec &y, const floatInVec &z ); + // Construct a 3-D vector from x, y, and z elements (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3(const floatInVec &x, const floatInVec &y, const floatInVec &z); - // Copy elements from a 3-D point into a 3-D vector - // - explicit VECTORMATH_FORCE_INLINE Vector3( const Point3 &pnt ); + // Copy elements from a 3-D point into a 3-D vector + // + explicit VECTORMATH_FORCE_INLINE Vector3(const Point3 &pnt); - // Set all elements of a 3-D vector to the same scalar value - // - explicit VECTORMATH_FORCE_INLINE Vector3( float scalar ); + // Set all elements of a 3-D vector to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Vector3(float scalar); - // Set all elements of a 3-D vector to the same scalar value (scalar data contained in vector data type) - // - explicit VECTORMATH_FORCE_INLINE Vector3( const floatInVec &scalar ); + // Set all elements of a 3-D vector to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Vector3(const floatInVec &scalar); - // Set vector float data in a 3-D vector - // - explicit VECTORMATH_FORCE_INLINE Vector3( __m128 vf4 ); + // Set vector float data in a 3-D vector + // + explicit VECTORMATH_FORCE_INLINE Vector3(__m128 vf4); - // Get vector float data from a 3-D vector - // - VECTORMATH_FORCE_INLINE __m128 get128( ) const; + // Get vector float data from a 3-D vector + // + VECTORMATH_FORCE_INLINE __m128 get128() const; - // Assign one 3-D vector to another - // - VECTORMATH_FORCE_INLINE Vector3 & operator =( const Vector3 &vec ); + // Assign one 3-D vector to another + // + VECTORMATH_FORCE_INLINE Vector3 &operator=(const Vector3 &vec); - // Set the x element of a 3-D vector - // - VECTORMATH_FORCE_INLINE Vector3 & setX( float x ); + // Set the x element of a 3-D vector + // + VECTORMATH_FORCE_INLINE Vector3 &setX(float x); - // Set the y element of a 3-D vector - // - VECTORMATH_FORCE_INLINE Vector3 & setY( float y ); + // Set the y element of a 3-D vector + // + VECTORMATH_FORCE_INLINE Vector3 &setY(float y); - // Set the z element of a 3-D vector - // - VECTORMATH_FORCE_INLINE Vector3 & setZ( float z ); + // Set the z element of a 3-D vector + // + VECTORMATH_FORCE_INLINE Vector3 &setZ(float z); - // Set the x element of a 3-D vector (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Vector3 & setX( const floatInVec &x ); + // Set the x element of a 3-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3 &setX(const floatInVec &x); - // Set the y element of a 3-D vector (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Vector3 & setY( const floatInVec &y ); + // Set the y element of a 3-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3 &setY(const floatInVec &y); - // Set the z element of a 3-D vector (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Vector3 & setZ( const floatInVec &z ); + // Set the z element of a 3-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3 &setZ(const floatInVec &z); - // Get the x element of a 3-D vector - // - VECTORMATH_FORCE_INLINE const floatInVec getX( ) const; + // Get the x element of a 3-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getX() const; - // Get the y element of a 3-D vector - // - VECTORMATH_FORCE_INLINE const floatInVec getY( ) const; + // Get the y element of a 3-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getY() const; - // Get the z element of a 3-D vector - // - VECTORMATH_FORCE_INLINE const floatInVec getZ( ) const; + // Get the z element of a 3-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getZ() const; - // Set an x, y, or z element of a 3-D vector by index - // - VECTORMATH_FORCE_INLINE Vector3 & setElem( int idx, float value ); + // Set an x, y, or z element of a 3-D vector by index + // + VECTORMATH_FORCE_INLINE Vector3 &setElem(int idx, float value); - // Set an x, y, or z element of a 3-D vector by index (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Vector3 & setElem( int idx, const floatInVec &value ); + // Set an x, y, or z element of a 3-D vector by index (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3 &setElem(int idx, const floatInVec &value); - // Get an x, y, or z element of a 3-D vector by index - // - VECTORMATH_FORCE_INLINE const floatInVec getElem( int idx ) const; + // Get an x, y, or z element of a 3-D vector by index + // + VECTORMATH_FORCE_INLINE const floatInVec getElem(int idx) const; - // Subscripting operator to set or get an element - // - VECTORMATH_FORCE_INLINE VecIdx operator []( int idx ); + // Subscripting operator to set or get an element + // + VECTORMATH_FORCE_INLINE VecIdx operator[](int idx); - // Subscripting operator to get an element - // - VECTORMATH_FORCE_INLINE const floatInVec operator []( int idx ) const; + // Subscripting operator to get an element + // + VECTORMATH_FORCE_INLINE const floatInVec operator[](int idx) const; - // Add two 3-D vectors - // - VECTORMATH_FORCE_INLINE const Vector3 operator +( const Vector3 &vec ) const; + // Add two 3-D vectors + // + VECTORMATH_FORCE_INLINE const Vector3 operator+(const Vector3 &vec) const; - // Subtract a 3-D vector from another 3-D vector - // - VECTORMATH_FORCE_INLINE const Vector3 operator -( const Vector3 &vec ) const; + // Subtract a 3-D vector from another 3-D vector + // + VECTORMATH_FORCE_INLINE const Vector3 operator-(const Vector3 &vec) const; - // Add a 3-D vector to a 3-D point - // - VECTORMATH_FORCE_INLINE const Point3 operator +( const Point3 &pnt ) const; + // Add a 3-D vector to a 3-D point + // + VECTORMATH_FORCE_INLINE const Point3 operator+(const Point3 &pnt) const; - // Multiply a 3-D vector by a scalar - // - VECTORMATH_FORCE_INLINE const Vector3 operator *( float scalar ) const; + // Multiply a 3-D vector by a scalar + // + VECTORMATH_FORCE_INLINE const Vector3 operator*(float scalar) const; - // Divide a 3-D vector by a scalar - // - VECTORMATH_FORCE_INLINE const Vector3 operator /( float scalar ) const; + // Divide a 3-D vector by a scalar + // + VECTORMATH_FORCE_INLINE const Vector3 operator/(float scalar) const; - // Multiply a 3-D vector by a scalar (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE const Vector3 operator *( const floatInVec &scalar ) const; + // Multiply a 3-D vector by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Vector3 operator*(const floatInVec &scalar) const; - // Divide a 3-D vector by a scalar (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE const Vector3 operator /( const floatInVec &scalar ) const; + // Divide a 3-D vector by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Vector3 operator/(const floatInVec &scalar) const; - // Perform compound assignment and addition with a 3-D vector - // - VECTORMATH_FORCE_INLINE Vector3 & operator +=( const Vector3 &vec ); + // Perform compound assignment and addition with a 3-D vector + // + VECTORMATH_FORCE_INLINE Vector3 &operator+=(const Vector3 &vec); - // Perform compound assignment and subtraction by a 3-D vector - // - VECTORMATH_FORCE_INLINE Vector3 & operator -=( const Vector3 &vec ); + // Perform compound assignment and subtraction by a 3-D vector + // + VECTORMATH_FORCE_INLINE Vector3 &operator-=(const Vector3 &vec); - // Perform compound assignment and multiplication by a scalar - // - VECTORMATH_FORCE_INLINE Vector3 & operator *=( float scalar ); + // Perform compound assignment and multiplication by a scalar + // + VECTORMATH_FORCE_INLINE Vector3 &operator*=(float scalar); - // Perform compound assignment and division by a scalar - // - VECTORMATH_FORCE_INLINE Vector3 & operator /=( float scalar ); + // Perform compound assignment and division by a scalar + // + VECTORMATH_FORCE_INLINE Vector3 &operator/=(float scalar); - // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Vector3 & operator *=( const floatInVec &scalar ); + // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3 &operator*=(const floatInVec &scalar); - // Perform compound assignment and division by a scalar (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Vector3 & operator /=( const floatInVec &scalar ); + // Perform compound assignment and division by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector3 &operator/=(const floatInVec &scalar); - // Negate all elements of a 3-D vector - // - VECTORMATH_FORCE_INLINE const Vector3 operator -( ) const; + // Negate all elements of a 3-D vector + // + VECTORMATH_FORCE_INLINE const Vector3 operator-() const; - // Construct x axis - // - static VECTORMATH_FORCE_INLINE const Vector3 xAxis( ); + // Construct x axis + // + static VECTORMATH_FORCE_INLINE const Vector3 xAxis(); - // Construct y axis - // - static VECTORMATH_FORCE_INLINE const Vector3 yAxis( ); - - // Construct z axis - // - static VECTORMATH_FORCE_INLINE const Vector3 zAxis( ); + // Construct y axis + // + static VECTORMATH_FORCE_INLINE const Vector3 yAxis(); + // Construct z axis + // + static VECTORMATH_FORCE_INLINE const Vector3 zAxis(); }; // Multiply a 3-D vector by a scalar -// -VECTORMATH_FORCE_INLINE const Vector3 operator *( float scalar, const Vector3 &vec ); +// +VECTORMATH_FORCE_INLINE const Vector3 operator*(float scalar, const Vector3 &vec); // Multiply a 3-D vector by a scalar (scalar data contained in vector data type) -// -VECTORMATH_FORCE_INLINE const Vector3 operator *( const floatInVec &scalar, const Vector3 &vec ); +// +VECTORMATH_FORCE_INLINE const Vector3 operator*(const floatInVec &scalar, const Vector3 &vec); // Multiply two 3-D vectors per element -// -VECTORMATH_FORCE_INLINE const Vector3 mulPerElem( const Vector3 &vec0, const Vector3 &vec1 ); +// +VECTORMATH_FORCE_INLINE const Vector3 mulPerElem(const Vector3 &vec0, const Vector3 &vec1); // Divide two 3-D vectors per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function divf4. -// -VECTORMATH_FORCE_INLINE const Vector3 divPerElem( const Vector3 &vec0, const Vector3 &vec1 ); +// +VECTORMATH_FORCE_INLINE const Vector3 divPerElem(const Vector3 &vec0, const Vector3 &vec1); // Compute the reciprocal of a 3-D vector per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function recipf4. -// -VECTORMATH_FORCE_INLINE const Vector3 recipPerElem( const Vector3 &vec ); +// +VECTORMATH_FORCE_INLINE const Vector3 recipPerElem(const Vector3 &vec); // Compute the absolute value of a 3-D vector per element -// -VECTORMATH_FORCE_INLINE const Vector3 absPerElem( const Vector3 &vec ); +// +VECTORMATH_FORCE_INLINE const Vector3 absPerElem(const Vector3 &vec); // Copy sign from one 3-D vector to another, per element -// -VECTORMATH_FORCE_INLINE const Vector3 copySignPerElem( const Vector3 &vec0, const Vector3 &vec1 ); +// +VECTORMATH_FORCE_INLINE const Vector3 copySignPerElem(const Vector3 &vec0, const Vector3 &vec1); // Maximum of two 3-D vectors per element -// -VECTORMATH_FORCE_INLINE const Vector3 maxPerElem( const Vector3 &vec0, const Vector3 &vec1 ); +// +VECTORMATH_FORCE_INLINE const Vector3 maxPerElem(const Vector3 &vec0, const Vector3 &vec1); // Minimum of two 3-D vectors per element -// -VECTORMATH_FORCE_INLINE const Vector3 minPerElem( const Vector3 &vec0, const Vector3 &vec1 ); +// +VECTORMATH_FORCE_INLINE const Vector3 minPerElem(const Vector3 &vec0, const Vector3 &vec1); // Maximum element of a 3-D vector -// -VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Vector3 &vec ); +// +VECTORMATH_FORCE_INLINE const floatInVec maxElem(const Vector3 &vec); // Minimum element of a 3-D vector -// -VECTORMATH_FORCE_INLINE const floatInVec minElem( const Vector3 &vec ); +// +VECTORMATH_FORCE_INLINE const floatInVec minElem(const Vector3 &vec); // Compute the sum of all elements of a 3-D vector -// -VECTORMATH_FORCE_INLINE const floatInVec sum( const Vector3 &vec ); +// +VECTORMATH_FORCE_INLINE const floatInVec sum(const Vector3 &vec); // Compute the dot product of two 3-D vectors -// -VECTORMATH_FORCE_INLINE const floatInVec dot( const Vector3 &vec0, const Vector3 &vec1 ); +// +VECTORMATH_FORCE_INLINE const floatInVec dot(const Vector3 &vec0, const Vector3 &vec1); // Compute the square of the length of a 3-D vector -// -VECTORMATH_FORCE_INLINE const floatInVec lengthSqr( const Vector3 &vec ); +// +VECTORMATH_FORCE_INLINE const floatInVec lengthSqr(const Vector3 &vec); // Compute the length of a 3-D vector -// -VECTORMATH_FORCE_INLINE const floatInVec length( const Vector3 &vec ); +// +VECTORMATH_FORCE_INLINE const floatInVec length(const Vector3 &vec); // Normalize a 3-D vector -// NOTE: +// NOTE: // The result is unpredictable when all elements of vec are at or near zero. -// -VECTORMATH_FORCE_INLINE const Vector3 normalize( const Vector3 &vec ); +// +VECTORMATH_FORCE_INLINE const Vector3 normalize(const Vector3 &vec); // Compute cross product of two 3-D vectors -// -VECTORMATH_FORCE_INLINE const Vector3 cross( const Vector3 &vec0, const Vector3 &vec1 ); +// +VECTORMATH_FORCE_INLINE const Vector3 cross(const Vector3 &vec0, const Vector3 &vec1); // Outer product of two 3-D vectors -// -VECTORMATH_FORCE_INLINE const Matrix3 outer( const Vector3 &vec0, const Vector3 &vec1 ); +// +VECTORMATH_FORCE_INLINE const Matrix3 outer(const Vector3 &vec0, const Vector3 &vec1); // Pre-multiply a row vector by a 3x3 matrix -// NOTE: +// NOTE: // Slower than column post-multiply. -// -VECTORMATH_FORCE_INLINE const Vector3 rowMul( const Vector3 &vec, const Matrix3 & mat ); +// +VECTORMATH_FORCE_INLINE const Vector3 rowMul(const Vector3 &vec, const Matrix3 &mat); // Cross-product matrix of a 3-D vector -// -VECTORMATH_FORCE_INLINE const Matrix3 crossMatrix( const Vector3 &vec ); +// +VECTORMATH_FORCE_INLINE const Matrix3 crossMatrix(const Vector3 &vec); // Create cross-product matrix and multiply -// NOTE: +// NOTE: // Faster than separately creating a cross-product matrix and multiplying. -// -VECTORMATH_FORCE_INLINE const Matrix3 crossMatrixMul( const Vector3 &vec, const Matrix3 & mat ); +// +VECTORMATH_FORCE_INLINE const Matrix3 crossMatrixMul(const Vector3 &vec, const Matrix3 &mat); // Linear interpolation between two 3-D vectors -// NOTE: +// NOTE: // Does not clamp t between 0 and 1. -// -VECTORMATH_FORCE_INLINE const Vector3 lerp( float t, const Vector3 &vec0, const Vector3 &vec1 ); +// +VECTORMATH_FORCE_INLINE const Vector3 lerp(float t, const Vector3 &vec0, const Vector3 &vec1); // Linear interpolation between two 3-D vectors (scalar data contained in vector data type) -// NOTE: +// NOTE: // Does not clamp t between 0 and 1. -// -VECTORMATH_FORCE_INLINE const Vector3 lerp( const floatInVec &t, const Vector3 &vec0, const Vector3 &vec1 ); +// +VECTORMATH_FORCE_INLINE const Vector3 lerp(const floatInVec &t, const Vector3 &vec0, const Vector3 &vec1); // Spherical linear interpolation between two 3-D vectors -// NOTE: +// NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. -// -VECTORMATH_FORCE_INLINE const Vector3 slerp( float t, const Vector3 &unitVec0, const Vector3 &unitVec1 ); +// +VECTORMATH_FORCE_INLINE const Vector3 slerp(float t, const Vector3 &unitVec0, const Vector3 &unitVec1); // Spherical linear interpolation between two 3-D vectors (scalar data contained in vector data type) -// NOTE: +// NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. -// -VECTORMATH_FORCE_INLINE const Vector3 slerp( const floatInVec &t, const Vector3 &unitVec0, const Vector3 &unitVec1 ); +// +VECTORMATH_FORCE_INLINE const Vector3 slerp(const floatInVec &t, const Vector3 &unitVec0, const Vector3 &unitVec1); // Conditionally select between two 3-D vectors -// NOTE: +// NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. -// -VECTORMATH_FORCE_INLINE const Vector3 select( const Vector3 &vec0, const Vector3 &vec1, bool select1 ); +// +VECTORMATH_FORCE_INLINE const Vector3 select(const Vector3 &vec0, const Vector3 &vec1, bool select1); // Conditionally select between two 3-D vectors (scalar data contained in vector data type) -// NOTE: +// NOTE: // This function uses a conditional select instruction to avoid a branch. -// -VECTORMATH_FORCE_INLINE const Vector3 select( const Vector3 &vec0, const Vector3 &vec1, const boolInVec &select1 ); +// +VECTORMATH_FORCE_INLINE const Vector3 select(const Vector3 &vec0, const Vector3 &vec1, const boolInVec &select1); // Store x, y, and z elements of 3-D vector in first three words of a quadword, preserving fourth word -// -VECTORMATH_FORCE_INLINE void storeXYZ( const Vector3 &vec, __m128 * quad ); +// +VECTORMATH_FORCE_INLINE void storeXYZ(const Vector3 &vec, __m128 *quad); // Load four three-float 3-D vectors, stored in three quadwords -// -VECTORMATH_FORCE_INLINE void loadXYZArray( Vector3 & vec0, Vector3 & vec1, Vector3 & vec2, Vector3 & vec3, const __m128 * threeQuads ); +// +VECTORMATH_FORCE_INLINE void loadXYZArray(Vector3 &vec0, Vector3 &vec1, Vector3 &vec2, Vector3 &vec3, const __m128 *threeQuads); // Store four 3-D vectors in three quadwords -// -VECTORMATH_FORCE_INLINE void storeXYZArray( const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, __m128 * threeQuads ); +// +VECTORMATH_FORCE_INLINE void storeXYZArray(const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, __m128 *threeQuads); // Store eight 3-D vectors as half-floats -// -VECTORMATH_FORCE_INLINE void storeHalfFloats( const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, const Vector3 &vec4, const Vector3 &vec5, const Vector3 &vec6, const Vector3 &vec7, vec_ushort8 * threeQuads ); +// +VECTORMATH_FORCE_INLINE void storeHalfFloats(const Vector3 &vec0, const Vector3 &vec1, const Vector3 &vec2, const Vector3 &vec3, const Vector3 &vec4, const Vector3 &vec5, const Vector3 &vec6, const Vector3 &vec7, vec_ushort8 *threeQuads); #ifdef _VECTORMATH_DEBUG // Print a 3-D vector -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -VECTORMATH_FORCE_INLINE void print( const Vector3 &vec ); +// +VECTORMATH_FORCE_INLINE void print(const Vector3 &vec); // Print a 3-D vector and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -VECTORMATH_FORCE_INLINE void print( const Vector3 &vec, const char * name ); +// +VECTORMATH_FORCE_INLINE void print(const Vector3 &vec, const char *name); #endif @@ -730,340 +726,339 @@ VECTORMATH_FORCE_INLINE void print( const Vector3 &vec, const char * name ); // class Vector4 { - __m128 mVec128; + __m128 mVec128; public: - // Default constructor; does no initialization - // - VECTORMATH_FORCE_INLINE Vector4( ) { }; + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Vector4(){}; - // Construct a 4-D vector from x, y, z, and w elements - // - VECTORMATH_FORCE_INLINE Vector4( float x, float y, float z, float w ); + // Construct a 4-D vector from x, y, z, and w elements + // + VECTORMATH_FORCE_INLINE Vector4(float x, float y, float z, float w); - // Construct a 4-D vector from x, y, z, and w elements (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Vector4( const floatInVec &x, const floatInVec &y, const floatInVec &z, const floatInVec &w ); + // Construct a 4-D vector from x, y, z, and w elements (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4(const floatInVec &x, const floatInVec &y, const floatInVec &z, const floatInVec &w); - // Construct a 4-D vector from a 3-D vector and a scalar - // - VECTORMATH_FORCE_INLINE Vector4( const Vector3 &xyz, float w ); + // Construct a 4-D vector from a 3-D vector and a scalar + // + VECTORMATH_FORCE_INLINE Vector4(const Vector3 &xyz, float w); - // Construct a 4-D vector from a 3-D vector and a scalar (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Vector4( const Vector3 &xyz, const floatInVec &w ); + // Construct a 4-D vector from a 3-D vector and a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4(const Vector3 &xyz, const floatInVec &w); - // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 - // - explicit VECTORMATH_FORCE_INLINE Vector4( const Vector3 &vec ); + // Copy x, y, and z from a 3-D vector into a 4-D vector, and set w to 0 + // + explicit VECTORMATH_FORCE_INLINE Vector4(const Vector3 &vec); - // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 - // - explicit VECTORMATH_FORCE_INLINE Vector4( const Point3 &pnt ); + // Copy x, y, and z from a 3-D point into a 4-D vector, and set w to 1 + // + explicit VECTORMATH_FORCE_INLINE Vector4(const Point3 &pnt); - // Copy elements from a quaternion into a 4-D vector - // - explicit VECTORMATH_FORCE_INLINE Vector4( const Quat &quat ); + // Copy elements from a quaternion into a 4-D vector + // + explicit VECTORMATH_FORCE_INLINE Vector4(const Quat &quat); - // Set all elements of a 4-D vector to the same scalar value - // - explicit VECTORMATH_FORCE_INLINE Vector4( float scalar ); + // Set all elements of a 4-D vector to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Vector4(float scalar); - // Set all elements of a 4-D vector to the same scalar value (scalar data contained in vector data type) - // - explicit VECTORMATH_FORCE_INLINE Vector4( const floatInVec &scalar ); + // Set all elements of a 4-D vector to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Vector4(const floatInVec &scalar); - // Set vector float data in a 4-D vector - // - explicit VECTORMATH_FORCE_INLINE Vector4( __m128 vf4 ); + // Set vector float data in a 4-D vector + // + explicit VECTORMATH_FORCE_INLINE Vector4(__m128 vf4); - // Get vector float data from a 4-D vector - // - VECTORMATH_FORCE_INLINE __m128 get128( ) const; + // Get vector float data from a 4-D vector + // + VECTORMATH_FORCE_INLINE __m128 get128() const; - // Assign one 4-D vector to another - // - VECTORMATH_FORCE_INLINE Vector4 & operator =( const Vector4 &vec ); + // Assign one 4-D vector to another + // + VECTORMATH_FORCE_INLINE Vector4 &operator=(const Vector4 &vec); - // Set the x, y, and z elements of a 4-D vector - // NOTE: - // This function does not change the w element. - // - VECTORMATH_FORCE_INLINE Vector4 & setXYZ( const Vector3 &vec ); + // Set the x, y, and z elements of a 4-D vector + // NOTE: + // This function does not change the w element. + // + VECTORMATH_FORCE_INLINE Vector4 &setXYZ(const Vector3 &vec); - // Get the x, y, and z elements of a 4-D vector - // - VECTORMATH_FORCE_INLINE const Vector3 getXYZ( ) const; + // Get the x, y, and z elements of a 4-D vector + // + VECTORMATH_FORCE_INLINE const Vector3 getXYZ() const; - // Set the x element of a 4-D vector - // - VECTORMATH_FORCE_INLINE Vector4 & setX( float x ); + // Set the x element of a 4-D vector + // + VECTORMATH_FORCE_INLINE Vector4 &setX(float x); - // Set the y element of a 4-D vector - // - VECTORMATH_FORCE_INLINE Vector4 & setY( float y ); + // Set the y element of a 4-D vector + // + VECTORMATH_FORCE_INLINE Vector4 &setY(float y); - // Set the z element of a 4-D vector - // - VECTORMATH_FORCE_INLINE Vector4 & setZ( float z ); + // Set the z element of a 4-D vector + // + VECTORMATH_FORCE_INLINE Vector4 &setZ(float z); - // Set the w element of a 4-D vector - // - VECTORMATH_FORCE_INLINE Vector4 & setW( float w ); + // Set the w element of a 4-D vector + // + VECTORMATH_FORCE_INLINE Vector4 &setW(float w); - // Set the x element of a 4-D vector (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Vector4 & setX( const floatInVec &x ); + // Set the x element of a 4-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 &setX(const floatInVec &x); - // Set the y element of a 4-D vector (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Vector4 & setY( const floatInVec &y ); + // Set the y element of a 4-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 &setY(const floatInVec &y); - // Set the z element of a 4-D vector (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Vector4 & setZ( const floatInVec &z ); + // Set the z element of a 4-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 &setZ(const floatInVec &z); - // Set the w element of a 4-D vector (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Vector4 & setW( const floatInVec &w ); + // Set the w element of a 4-D vector (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 &setW(const floatInVec &w); - // Get the x element of a 4-D vector - // - VECTORMATH_FORCE_INLINE const floatInVec getX( ) const; + // Get the x element of a 4-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getX() const; - // Get the y element of a 4-D vector - // - VECTORMATH_FORCE_INLINE const floatInVec getY( ) const; + // Get the y element of a 4-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getY() const; - // Get the z element of a 4-D vector - // - VECTORMATH_FORCE_INLINE const floatInVec getZ( ) const; + // Get the z element of a 4-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getZ() const; - // Get the w element of a 4-D vector - // - VECTORMATH_FORCE_INLINE const floatInVec getW( ) const; + // Get the w element of a 4-D vector + // + VECTORMATH_FORCE_INLINE const floatInVec getW() const; - // Set an x, y, z, or w element of a 4-D vector by index - // - VECTORMATH_FORCE_INLINE Vector4 & setElem( int idx, float value ); + // Set an x, y, z, or w element of a 4-D vector by index + // + VECTORMATH_FORCE_INLINE Vector4 &setElem(int idx, float value); - // Set an x, y, z, or w element of a 4-D vector by index (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Vector4 & setElem( int idx, const floatInVec &value ); + // Set an x, y, z, or w element of a 4-D vector by index (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 &setElem(int idx, const floatInVec &value); - // Get an x, y, z, or w element of a 4-D vector by index - // - VECTORMATH_FORCE_INLINE const floatInVec getElem( int idx ) const; + // Get an x, y, z, or w element of a 4-D vector by index + // + VECTORMATH_FORCE_INLINE const floatInVec getElem(int idx) const; - // Subscripting operator to set or get an element - // - VECTORMATH_FORCE_INLINE VecIdx operator []( int idx ); + // Subscripting operator to set or get an element + // + VECTORMATH_FORCE_INLINE VecIdx operator[](int idx); - // Subscripting operator to get an element - // - VECTORMATH_FORCE_INLINE const floatInVec operator []( int idx ) const; + // Subscripting operator to get an element + // + VECTORMATH_FORCE_INLINE const floatInVec operator[](int idx) const; - // Add two 4-D vectors - // - VECTORMATH_FORCE_INLINE const Vector4 operator +( const Vector4 &vec ) const; + // Add two 4-D vectors + // + VECTORMATH_FORCE_INLINE const Vector4 operator+(const Vector4 &vec) const; - // Subtract a 4-D vector from another 4-D vector - // - VECTORMATH_FORCE_INLINE const Vector4 operator -( const Vector4 &vec ) const; + // Subtract a 4-D vector from another 4-D vector + // + VECTORMATH_FORCE_INLINE const Vector4 operator-(const Vector4 &vec) const; - // Multiply a 4-D vector by a scalar - // - VECTORMATH_FORCE_INLINE const Vector4 operator *( float scalar ) const; + // Multiply a 4-D vector by a scalar + // + VECTORMATH_FORCE_INLINE const Vector4 operator*(float scalar) const; - // Divide a 4-D vector by a scalar - // - VECTORMATH_FORCE_INLINE const Vector4 operator /( float scalar ) const; + // Divide a 4-D vector by a scalar + // + VECTORMATH_FORCE_INLINE const Vector4 operator/(float scalar) const; - // Multiply a 4-D vector by a scalar (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE const Vector4 operator *( const floatInVec &scalar ) const; + // Multiply a 4-D vector by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Vector4 operator*(const floatInVec &scalar) const; - // Divide a 4-D vector by a scalar (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE const Vector4 operator /( const floatInVec &scalar ) const; + // Divide a 4-D vector by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Vector4 operator/(const floatInVec &scalar) const; - // Perform compound assignment and addition with a 4-D vector - // - VECTORMATH_FORCE_INLINE Vector4 & operator +=( const Vector4 &vec ); + // Perform compound assignment and addition with a 4-D vector + // + VECTORMATH_FORCE_INLINE Vector4 &operator+=(const Vector4 &vec); - // Perform compound assignment and subtraction by a 4-D vector - // - VECTORMATH_FORCE_INLINE Vector4 & operator -=( const Vector4 &vec ); + // Perform compound assignment and subtraction by a 4-D vector + // + VECTORMATH_FORCE_INLINE Vector4 &operator-=(const Vector4 &vec); - // Perform compound assignment and multiplication by a scalar - // - VECTORMATH_FORCE_INLINE Vector4 & operator *=( float scalar ); + // Perform compound assignment and multiplication by a scalar + // + VECTORMATH_FORCE_INLINE Vector4 &operator*=(float scalar); - // Perform compound assignment and division by a scalar - // - VECTORMATH_FORCE_INLINE Vector4 & operator /=( float scalar ); + // Perform compound assignment and division by a scalar + // + VECTORMATH_FORCE_INLINE Vector4 &operator/=(float scalar); - // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Vector4 & operator *=( const floatInVec &scalar ); + // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 &operator*=(const floatInVec &scalar); - // Perform compound assignment and division by a scalar (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Vector4 & operator /=( const floatInVec &scalar ); + // Perform compound assignment and division by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Vector4 &operator/=(const floatInVec &scalar); - // Negate all elements of a 4-D vector - // - VECTORMATH_FORCE_INLINE const Vector4 operator -( ) const; + // Negate all elements of a 4-D vector + // + VECTORMATH_FORCE_INLINE const Vector4 operator-() const; - // Construct x axis - // - static VECTORMATH_FORCE_INLINE const Vector4 xAxis( ); + // Construct x axis + // + static VECTORMATH_FORCE_INLINE const Vector4 xAxis(); - // Construct y axis - // - static VECTORMATH_FORCE_INLINE const Vector4 yAxis( ); + // Construct y axis + // + static VECTORMATH_FORCE_INLINE const Vector4 yAxis(); - // Construct z axis - // - static VECTORMATH_FORCE_INLINE const Vector4 zAxis( ); - - // Construct w axis - // - static VECTORMATH_FORCE_INLINE const Vector4 wAxis( ); + // Construct z axis + // + static VECTORMATH_FORCE_INLINE const Vector4 zAxis(); + // Construct w axis + // + static VECTORMATH_FORCE_INLINE const Vector4 wAxis(); }; // Multiply a 4-D vector by a scalar -// -VECTORMATH_FORCE_INLINE const Vector4 operator *( float scalar, const Vector4 &vec ); +// +VECTORMATH_FORCE_INLINE const Vector4 operator*(float scalar, const Vector4 &vec); // Multiply a 4-D vector by a scalar (scalar data contained in vector data type) -// -VECTORMATH_FORCE_INLINE const Vector4 operator *( const floatInVec &scalar, const Vector4 &vec ); +// +VECTORMATH_FORCE_INLINE const Vector4 operator*(const floatInVec &scalar, const Vector4 &vec); // Multiply two 4-D vectors per element -// -VECTORMATH_FORCE_INLINE const Vector4 mulPerElem( const Vector4 &vec0, const Vector4 &vec1 ); +// +VECTORMATH_FORCE_INLINE const Vector4 mulPerElem(const Vector4 &vec0, const Vector4 &vec1); // Divide two 4-D vectors per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function divf4. -// -VECTORMATH_FORCE_INLINE const Vector4 divPerElem( const Vector4 &vec0, const Vector4 &vec1 ); +// +VECTORMATH_FORCE_INLINE const Vector4 divPerElem(const Vector4 &vec0, const Vector4 &vec1); // Compute the reciprocal of a 4-D vector per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function recipf4. -// -VECTORMATH_FORCE_INLINE const Vector4 recipPerElem( const Vector4 &vec ); +// +VECTORMATH_FORCE_INLINE const Vector4 recipPerElem(const Vector4 &vec); // Compute the absolute value of a 4-D vector per element -// -VECTORMATH_FORCE_INLINE const Vector4 absPerElem( const Vector4 &vec ); +// +VECTORMATH_FORCE_INLINE const Vector4 absPerElem(const Vector4 &vec); // Copy sign from one 4-D vector to another, per element -// -VECTORMATH_FORCE_INLINE const Vector4 copySignPerElem( const Vector4 &vec0, const Vector4 &vec1 ); +// +VECTORMATH_FORCE_INLINE const Vector4 copySignPerElem(const Vector4 &vec0, const Vector4 &vec1); // Maximum of two 4-D vectors per element -// -VECTORMATH_FORCE_INLINE const Vector4 maxPerElem( const Vector4 &vec0, const Vector4 &vec1 ); +// +VECTORMATH_FORCE_INLINE const Vector4 maxPerElem(const Vector4 &vec0, const Vector4 &vec1); // Minimum of two 4-D vectors per element -// -VECTORMATH_FORCE_INLINE const Vector4 minPerElem( const Vector4 &vec0, const Vector4 &vec1 ); +// +VECTORMATH_FORCE_INLINE const Vector4 minPerElem(const Vector4 &vec0, const Vector4 &vec1); // Maximum element of a 4-D vector -// -VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Vector4 &vec ); +// +VECTORMATH_FORCE_INLINE const floatInVec maxElem(const Vector4 &vec); // Minimum element of a 4-D vector -// -VECTORMATH_FORCE_INLINE const floatInVec minElem( const Vector4 &vec ); +// +VECTORMATH_FORCE_INLINE const floatInVec minElem(const Vector4 &vec); // Compute the sum of all elements of a 4-D vector -// -VECTORMATH_FORCE_INLINE const floatInVec sum( const Vector4 &vec ); +// +VECTORMATH_FORCE_INLINE const floatInVec sum(const Vector4 &vec); // Compute the dot product of two 4-D vectors -// -VECTORMATH_FORCE_INLINE const floatInVec dot( const Vector4 &vec0, const Vector4 &vec1 ); +// +VECTORMATH_FORCE_INLINE const floatInVec dot(const Vector4 &vec0, const Vector4 &vec1); // Compute the square of the length of a 4-D vector -// -VECTORMATH_FORCE_INLINE const floatInVec lengthSqr( const Vector4 &vec ); +// +VECTORMATH_FORCE_INLINE const floatInVec lengthSqr(const Vector4 &vec); // Compute the length of a 4-D vector -// -VECTORMATH_FORCE_INLINE const floatInVec length( const Vector4 &vec ); +// +VECTORMATH_FORCE_INLINE const floatInVec length(const Vector4 &vec); // Normalize a 4-D vector -// NOTE: +// NOTE: // The result is unpredictable when all elements of vec are at or near zero. -// -VECTORMATH_FORCE_INLINE const Vector4 normalize( const Vector4 &vec ); +// +VECTORMATH_FORCE_INLINE const Vector4 normalize(const Vector4 &vec); // Outer product of two 4-D vectors -// -VECTORMATH_FORCE_INLINE const Matrix4 outer( const Vector4 &vec0, const Vector4 &vec1 ); +// +VECTORMATH_FORCE_INLINE const Matrix4 outer(const Vector4 &vec0, const Vector4 &vec1); // Linear interpolation between two 4-D vectors -// NOTE: +// NOTE: // Does not clamp t between 0 and 1. -// -VECTORMATH_FORCE_INLINE const Vector4 lerp( float t, const Vector4 &vec0, const Vector4 &vec1 ); +// +VECTORMATH_FORCE_INLINE const Vector4 lerp(float t, const Vector4 &vec0, const Vector4 &vec1); // Linear interpolation between two 4-D vectors (scalar data contained in vector data type) -// NOTE: +// NOTE: // Does not clamp t between 0 and 1. -// -VECTORMATH_FORCE_INLINE const Vector4 lerp( const floatInVec &t, const Vector4 &vec0, const Vector4 &vec1 ); +// +VECTORMATH_FORCE_INLINE const Vector4 lerp(const floatInVec &t, const Vector4 &vec0, const Vector4 &vec1); // Spherical linear interpolation between two 4-D vectors -// NOTE: +// NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. -// -VECTORMATH_FORCE_INLINE const Vector4 slerp( float t, const Vector4 &unitVec0, const Vector4 &unitVec1 ); +// +VECTORMATH_FORCE_INLINE const Vector4 slerp(float t, const Vector4 &unitVec0, const Vector4 &unitVec1); // Spherical linear interpolation between two 4-D vectors (scalar data contained in vector data type) -// NOTE: +// NOTE: // The result is unpredictable if the vectors point in opposite directions. // Does not clamp t between 0 and 1. -// -VECTORMATH_FORCE_INLINE const Vector4 slerp( const floatInVec &t, const Vector4 &unitVec0, const Vector4 &unitVec1 ); +// +VECTORMATH_FORCE_INLINE const Vector4 slerp(const floatInVec &t, const Vector4 &unitVec0, const Vector4 &unitVec1); // Conditionally select between two 4-D vectors -// NOTE: +// NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. -// -VECTORMATH_FORCE_INLINE const Vector4 select( const Vector4 &vec0, const Vector4 &vec1, bool select1 ); +// +VECTORMATH_FORCE_INLINE const Vector4 select(const Vector4 &vec0, const Vector4 &vec1, bool select1); // Conditionally select between two 4-D vectors (scalar data contained in vector data type) -// NOTE: +// NOTE: // This function uses a conditional select instruction to avoid a branch. -// -VECTORMATH_FORCE_INLINE const Vector4 select( const Vector4 &vec0, const Vector4 &vec1, const boolInVec &select1 ); +// +VECTORMATH_FORCE_INLINE const Vector4 select(const Vector4 &vec0, const Vector4 &vec1, const boolInVec &select1); // Store four 4-D vectors as half-floats -// -VECTORMATH_FORCE_INLINE void storeHalfFloats( const Vector4 &vec0, const Vector4 &vec1, const Vector4 &vec2, const Vector4 &vec3, vec_ushort8 * twoQuads ); +// +VECTORMATH_FORCE_INLINE void storeHalfFloats(const Vector4 &vec0, const Vector4 &vec1, const Vector4 &vec2, const Vector4 &vec3, vec_ushort8 *twoQuads); #ifdef _VECTORMATH_DEBUG // Print a 4-D vector -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -VECTORMATH_FORCE_INLINE void print( const Vector4 &vec ); +// +VECTORMATH_FORCE_INLINE void print(const Vector4 &vec); // Print a 4-D vector and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -VECTORMATH_FORCE_INLINE void print( const Vector4 &vec, const char * name ); +// +VECTORMATH_FORCE_INLINE void print(const Vector4 &vec, const char *name); #endif @@ -1071,254 +1066,253 @@ VECTORMATH_FORCE_INLINE void print( const Vector4 &vec, const char * name ); // class Point3 { - __m128 mVec128; + __m128 mVec128; public: - // Default constructor; does no initialization - // - VECTORMATH_FORCE_INLINE Point3( ) { }; + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Point3(){}; - // Construct a 3-D point from x, y, and z elements - // - VECTORMATH_FORCE_INLINE Point3( float x, float y, float z ); + // Construct a 3-D point from x, y, and z elements + // + VECTORMATH_FORCE_INLINE Point3(float x, float y, float z); - // Construct a 3-D point from x, y, and z elements (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Point3( const floatInVec &x, const floatInVec &y, const floatInVec &z ); + // Construct a 3-D point from x, y, and z elements (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Point3(const floatInVec &x, const floatInVec &y, const floatInVec &z); - // Copy elements from a 3-D vector into a 3-D point - // - explicit VECTORMATH_FORCE_INLINE Point3( const Vector3 &vec ); + // Copy elements from a 3-D vector into a 3-D point + // + explicit VECTORMATH_FORCE_INLINE Point3(const Vector3 &vec); - // Set all elements of a 3-D point to the same scalar value - // - explicit VECTORMATH_FORCE_INLINE Point3( float scalar ); + // Set all elements of a 3-D point to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Point3(float scalar); - // Set all elements of a 3-D point to the same scalar value (scalar data contained in vector data type) - // - explicit VECTORMATH_FORCE_INLINE Point3( const floatInVec &scalar ); + // Set all elements of a 3-D point to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Point3(const floatInVec &scalar); - // Set vector float data in a 3-D point - // - explicit VECTORMATH_FORCE_INLINE Point3( __m128 vf4 ); + // Set vector float data in a 3-D point + // + explicit VECTORMATH_FORCE_INLINE Point3(__m128 vf4); - // Get vector float data from a 3-D point - // - VECTORMATH_FORCE_INLINE __m128 get128( ) const; + // Get vector float data from a 3-D point + // + VECTORMATH_FORCE_INLINE __m128 get128() const; - // Assign one 3-D point to another - // - VECTORMATH_FORCE_INLINE Point3 & operator =( const Point3 &pnt ); + // Assign one 3-D point to another + // + VECTORMATH_FORCE_INLINE Point3 &operator=(const Point3 &pnt); - // Set the x element of a 3-D point - // - VECTORMATH_FORCE_INLINE Point3 & setX( float x ); + // Set the x element of a 3-D point + // + VECTORMATH_FORCE_INLINE Point3 &setX(float x); - // Set the y element of a 3-D point - // - VECTORMATH_FORCE_INLINE Point3 & setY( float y ); + // Set the y element of a 3-D point + // + VECTORMATH_FORCE_INLINE Point3 &setY(float y); - // Set the z element of a 3-D point - // - VECTORMATH_FORCE_INLINE Point3 & setZ( float z ); + // Set the z element of a 3-D point + // + VECTORMATH_FORCE_INLINE Point3 &setZ(float z); - // Set the x element of a 3-D point (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Point3 & setX( const floatInVec &x ); + // Set the x element of a 3-D point (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Point3 &setX(const floatInVec &x); - // Set the y element of a 3-D point (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Point3 & setY( const floatInVec &y ); + // Set the y element of a 3-D point (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Point3 &setY(const floatInVec &y); - // Set the z element of a 3-D point (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Point3 & setZ( const floatInVec &z ); + // Set the z element of a 3-D point (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Point3 &setZ(const floatInVec &z); - // Get the x element of a 3-D point - // - VECTORMATH_FORCE_INLINE const floatInVec getX( ) const; + // Get the x element of a 3-D point + // + VECTORMATH_FORCE_INLINE const floatInVec getX() const; - // Get the y element of a 3-D point - // - VECTORMATH_FORCE_INLINE const floatInVec getY( ) const; + // Get the y element of a 3-D point + // + VECTORMATH_FORCE_INLINE const floatInVec getY() const; - // Get the z element of a 3-D point - // - VECTORMATH_FORCE_INLINE const floatInVec getZ( ) const; + // Get the z element of a 3-D point + // + VECTORMATH_FORCE_INLINE const floatInVec getZ() const; - // Set an x, y, or z element of a 3-D point by index - // - VECTORMATH_FORCE_INLINE Point3 & setElem( int idx, float value ); + // Set an x, y, or z element of a 3-D point by index + // + VECTORMATH_FORCE_INLINE Point3 &setElem(int idx, float value); - // Set an x, y, or z element of a 3-D point by index (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Point3 & setElem( int idx, const floatInVec &value ); + // Set an x, y, or z element of a 3-D point by index (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Point3 &setElem(int idx, const floatInVec &value); - // Get an x, y, or z element of a 3-D point by index - // - VECTORMATH_FORCE_INLINE const floatInVec getElem( int idx ) const; + // Get an x, y, or z element of a 3-D point by index + // + VECTORMATH_FORCE_INLINE const floatInVec getElem(int idx) const; - // Subscripting operator to set or get an element - // - VECTORMATH_FORCE_INLINE VecIdx operator []( int idx ); + // Subscripting operator to set or get an element + // + VECTORMATH_FORCE_INLINE VecIdx operator[](int idx); - // Subscripting operator to get an element - // - VECTORMATH_FORCE_INLINE const floatInVec operator []( int idx ) const; + // Subscripting operator to get an element + // + VECTORMATH_FORCE_INLINE const floatInVec operator[](int idx) const; - // Subtract a 3-D point from another 3-D point - // - VECTORMATH_FORCE_INLINE const Vector3 operator -( const Point3 &pnt ) const; + // Subtract a 3-D point from another 3-D point + // + VECTORMATH_FORCE_INLINE const Vector3 operator-(const Point3 &pnt) const; - // Add a 3-D point to a 3-D vector - // - VECTORMATH_FORCE_INLINE const Point3 operator +( const Vector3 &vec ) const; + // Add a 3-D point to a 3-D vector + // + VECTORMATH_FORCE_INLINE const Point3 operator+(const Vector3 &vec) const; - // Subtract a 3-D vector from a 3-D point - // - VECTORMATH_FORCE_INLINE const Point3 operator -( const Vector3 &vec ) const; + // Subtract a 3-D vector from a 3-D point + // + VECTORMATH_FORCE_INLINE const Point3 operator-(const Vector3 &vec) const; - // Perform compound assignment and addition with a 3-D vector - // - VECTORMATH_FORCE_INLINE Point3 & operator +=( const Vector3 &vec ); - - // Perform compound assignment and subtraction by a 3-D vector - // - VECTORMATH_FORCE_INLINE Point3 & operator -=( const Vector3 &vec ); + // Perform compound assignment and addition with a 3-D vector + // + VECTORMATH_FORCE_INLINE Point3 &operator+=(const Vector3 &vec); + // Perform compound assignment and subtraction by a 3-D vector + // + VECTORMATH_FORCE_INLINE Point3 &operator-=(const Vector3 &vec); }; // Multiply two 3-D points per element -// -VECTORMATH_FORCE_INLINE const Point3 mulPerElem( const Point3 &pnt0, const Point3 &pnt1 ); +// +VECTORMATH_FORCE_INLINE const Point3 mulPerElem(const Point3 &pnt0, const Point3 &pnt1); // Divide two 3-D points per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function divf4. -// -VECTORMATH_FORCE_INLINE const Point3 divPerElem( const Point3 &pnt0, const Point3 &pnt1 ); +// +VECTORMATH_FORCE_INLINE const Point3 divPerElem(const Point3 &pnt0, const Point3 &pnt1); // Compute the reciprocal of a 3-D point per element -// NOTE: +// NOTE: // Floating-point behavior matches standard library function recipf4. -// -VECTORMATH_FORCE_INLINE const Point3 recipPerElem( const Point3 &pnt ); +// +VECTORMATH_FORCE_INLINE const Point3 recipPerElem(const Point3 &pnt); // Compute the absolute value of a 3-D point per element -// -VECTORMATH_FORCE_INLINE const Point3 absPerElem( const Point3 &pnt ); +// +VECTORMATH_FORCE_INLINE const Point3 absPerElem(const Point3 &pnt); // Copy sign from one 3-D point to another, per element -// -VECTORMATH_FORCE_INLINE const Point3 copySignPerElem( const Point3 &pnt0, const Point3 &pnt1 ); +// +VECTORMATH_FORCE_INLINE const Point3 copySignPerElem(const Point3 &pnt0, const Point3 &pnt1); // Maximum of two 3-D points per element -// -VECTORMATH_FORCE_INLINE const Point3 maxPerElem( const Point3 &pnt0, const Point3 &pnt1 ); +// +VECTORMATH_FORCE_INLINE const Point3 maxPerElem(const Point3 &pnt0, const Point3 &pnt1); // Minimum of two 3-D points per element -// -VECTORMATH_FORCE_INLINE const Point3 minPerElem( const Point3 &pnt0, const Point3 &pnt1 ); +// +VECTORMATH_FORCE_INLINE const Point3 minPerElem(const Point3 &pnt0, const Point3 &pnt1); // Maximum element of a 3-D point -// -VECTORMATH_FORCE_INLINE const floatInVec maxElem( const Point3 &pnt ); +// +VECTORMATH_FORCE_INLINE const floatInVec maxElem(const Point3 &pnt); // Minimum element of a 3-D point -// -VECTORMATH_FORCE_INLINE const floatInVec minElem( const Point3 &pnt ); +// +VECTORMATH_FORCE_INLINE const floatInVec minElem(const Point3 &pnt); // Compute the sum of all elements of a 3-D point -// -VECTORMATH_FORCE_INLINE const floatInVec sum( const Point3 &pnt ); +// +VECTORMATH_FORCE_INLINE const floatInVec sum(const Point3 &pnt); // Apply uniform scale to a 3-D point -// -VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, float scaleVal ); +// +VECTORMATH_FORCE_INLINE const Point3 scale(const Point3 &pnt, float scaleVal); // Apply uniform scale to a 3-D point (scalar data contained in vector data type) -// -VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, const floatInVec &scaleVal ); +// +VECTORMATH_FORCE_INLINE const Point3 scale(const Point3 &pnt, const floatInVec &scaleVal); // Apply non-uniform scale to a 3-D point -// -VECTORMATH_FORCE_INLINE const Point3 scale( const Point3 &pnt, const Vector3 &scaleVec ); +// +VECTORMATH_FORCE_INLINE const Point3 scale(const Point3 &pnt, const Vector3 &scaleVec); // Scalar projection of a 3-D point on a unit-length 3-D vector -// -VECTORMATH_FORCE_INLINE const floatInVec projection( const Point3 &pnt, const Vector3 &unitVec ); +// +VECTORMATH_FORCE_INLINE const floatInVec projection(const Point3 &pnt, const Vector3 &unitVec); // Compute the square of the distance of a 3-D point from the coordinate-system origin -// -VECTORMATH_FORCE_INLINE const floatInVec distSqrFromOrigin( const Point3 &pnt ); +// +VECTORMATH_FORCE_INLINE const floatInVec distSqrFromOrigin(const Point3 &pnt); // Compute the distance of a 3-D point from the coordinate-system origin -// -VECTORMATH_FORCE_INLINE const floatInVec distFromOrigin( const Point3 &pnt ); +// +VECTORMATH_FORCE_INLINE const floatInVec distFromOrigin(const Point3 &pnt); // Compute the square of the distance between two 3-D points -// -VECTORMATH_FORCE_INLINE const floatInVec distSqr( const Point3 &pnt0, const Point3 &pnt1 ); +// +VECTORMATH_FORCE_INLINE const floatInVec distSqr(const Point3 &pnt0, const Point3 &pnt1); // Compute the distance between two 3-D points -// -VECTORMATH_FORCE_INLINE const floatInVec dist( const Point3 &pnt0, const Point3 &pnt1 ); +// +VECTORMATH_FORCE_INLINE const floatInVec dist(const Point3 &pnt0, const Point3 &pnt1); // Linear interpolation between two 3-D points -// NOTE: +// NOTE: // Does not clamp t between 0 and 1. -// -VECTORMATH_FORCE_INLINE const Point3 lerp( float t, const Point3 &pnt0, const Point3 &pnt1 ); +// +VECTORMATH_FORCE_INLINE const Point3 lerp(float t, const Point3 &pnt0, const Point3 &pnt1); // Linear interpolation between two 3-D points (scalar data contained in vector data type) -// NOTE: +// NOTE: // Does not clamp t between 0 and 1. -// -VECTORMATH_FORCE_INLINE const Point3 lerp( const floatInVec &t, const Point3 &pnt0, const Point3 &pnt1 ); +// +VECTORMATH_FORCE_INLINE const Point3 lerp(const floatInVec &t, const Point3 &pnt0, const Point3 &pnt1); // Conditionally select between two 3-D points -// NOTE: +// NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. -// -VECTORMATH_FORCE_INLINE const Point3 select( const Point3 &pnt0, const Point3 &pnt1, bool select1 ); +// +VECTORMATH_FORCE_INLINE const Point3 select(const Point3 &pnt0, const Point3 &pnt1, bool select1); // Conditionally select between two 3-D points (scalar data contained in vector data type) -// NOTE: +// NOTE: // This function uses a conditional select instruction to avoid a branch. -// -VECTORMATH_FORCE_INLINE const Point3 select( const Point3 &pnt0, const Point3 &pnt1, const boolInVec &select1 ); +// +VECTORMATH_FORCE_INLINE const Point3 select(const Point3 &pnt0, const Point3 &pnt1, const boolInVec &select1); // Store x, y, and z elements of 3-D point in first three words of a quadword, preserving fourth word -// -VECTORMATH_FORCE_INLINE void storeXYZ( const Point3 &pnt, __m128 * quad ); +// +VECTORMATH_FORCE_INLINE void storeXYZ(const Point3 &pnt, __m128 *quad); // Load four three-float 3-D points, stored in three quadwords -// -VECTORMATH_FORCE_INLINE void loadXYZArray( Point3 & pnt0, Point3 & pnt1, Point3 & pnt2, Point3 & pnt3, const __m128 * threeQuads ); +// +VECTORMATH_FORCE_INLINE void loadXYZArray(Point3 &pnt0, Point3 &pnt1, Point3 &pnt2, Point3 &pnt3, const __m128 *threeQuads); // Store four 3-D points in three quadwords -// -VECTORMATH_FORCE_INLINE void storeXYZArray( const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, __m128 * threeQuads ); +// +VECTORMATH_FORCE_INLINE void storeXYZArray(const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, __m128 *threeQuads); // Store eight 3-D points as half-floats -// -VECTORMATH_FORCE_INLINE void storeHalfFloats( const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, const Point3 &pnt4, const Point3 &pnt5, const Point3 &pnt6, const Point3 &pnt7, vec_ushort8 * threeQuads ); +// +VECTORMATH_FORCE_INLINE void storeHalfFloats(const Point3 &pnt0, const Point3 &pnt1, const Point3 &pnt2, const Point3 &pnt3, const Point3 &pnt4, const Point3 &pnt5, const Point3 &pnt6, const Point3 &pnt7, vec_ushort8 *threeQuads); #ifdef _VECTORMATH_DEBUG // Print a 3-D point -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -VECTORMATH_FORCE_INLINE void print( const Point3 &pnt ); +// +VECTORMATH_FORCE_INLINE void print(const Point3 &pnt); // Print a 3-D point and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -VECTORMATH_FORCE_INLINE void print( const Point3 &pnt, const char * name ); +// +VECTORMATH_FORCE_INLINE void print(const Point3 &pnt, const char *name); #endif @@ -1326,340 +1320,339 @@ VECTORMATH_FORCE_INLINE void print( const Point3 &pnt, const char * name ); // class Quat { - __m128 mVec128; + __m128 mVec128; public: - // Default constructor; does no initialization - // - VECTORMATH_FORCE_INLINE Quat( ) { }; + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Quat(){}; - VECTORMATH_FORCE_INLINE Quat(const Quat& quat); + VECTORMATH_FORCE_INLINE Quat(const Quat &quat); - // Construct a quaternion from x, y, z, and w elements - // - VECTORMATH_FORCE_INLINE Quat( float x, float y, float z, float w ); + // Construct a quaternion from x, y, z, and w elements + // + VECTORMATH_FORCE_INLINE Quat(float x, float y, float z, float w); - // Construct a quaternion from x, y, z, and w elements (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Quat( const floatInVec &x, const floatInVec &y, const floatInVec &z, const floatInVec &w ); + // Construct a quaternion from x, y, z, and w elements (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat(const floatInVec &x, const floatInVec &y, const floatInVec &z, const floatInVec &w); - // Construct a quaternion from a 3-D vector and a scalar - // - VECTORMATH_FORCE_INLINE Quat( const Vector3 &xyz, float w ); + // Construct a quaternion from a 3-D vector and a scalar + // + VECTORMATH_FORCE_INLINE Quat(const Vector3 &xyz, float w); - // Construct a quaternion from a 3-D vector and a scalar (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Quat( const Vector3 &xyz, const floatInVec &w ); + // Construct a quaternion from a 3-D vector and a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat(const Vector3 &xyz, const floatInVec &w); - // Copy elements from a 4-D vector into a quaternion - // - explicit VECTORMATH_FORCE_INLINE Quat( const Vector4 &vec ); + // Copy elements from a 4-D vector into a quaternion + // + explicit VECTORMATH_FORCE_INLINE Quat(const Vector4 &vec); - // Convert a rotation matrix to a unit-length quaternion - // - explicit VECTORMATH_FORCE_INLINE Quat( const Matrix3 & rotMat ); + // Convert a rotation matrix to a unit-length quaternion + // + explicit VECTORMATH_FORCE_INLINE Quat(const Matrix3 &rotMat); - // Set all elements of a quaternion to the same scalar value - // - explicit VECTORMATH_FORCE_INLINE Quat( float scalar ); + // Set all elements of a quaternion to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Quat(float scalar); - // Set all elements of a quaternion to the same scalar value (scalar data contained in vector data type) - // - explicit VECTORMATH_FORCE_INLINE Quat( const floatInVec &scalar ); + // Set all elements of a quaternion to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Quat(const floatInVec &scalar); - // Set vector float data in a quaternion - // - explicit VECTORMATH_FORCE_INLINE Quat( __m128 vf4 ); + // Set vector float data in a quaternion + // + explicit VECTORMATH_FORCE_INLINE Quat(__m128 vf4); - // Get vector float data from a quaternion - // - VECTORMATH_FORCE_INLINE __m128 get128( ) const; + // Get vector float data from a quaternion + // + VECTORMATH_FORCE_INLINE __m128 get128() const; // Set a quaterion from vector float data - // + // VECTORMATH_FORCE_INLINE void set128(vec_float4 vec); - // Assign one quaternion to another - // - VECTORMATH_FORCE_INLINE Quat & operator =( const Quat &quat ); + // Assign one quaternion to another + // + VECTORMATH_FORCE_INLINE Quat &operator=(const Quat &quat); - // Set the x, y, and z elements of a quaternion - // NOTE: - // This function does not change the w element. - // - VECTORMATH_FORCE_INLINE Quat & setXYZ( const Vector3 &vec ); + // Set the x, y, and z elements of a quaternion + // NOTE: + // This function does not change the w element. + // + VECTORMATH_FORCE_INLINE Quat &setXYZ(const Vector3 &vec); - // Get the x, y, and z elements of a quaternion - // - VECTORMATH_FORCE_INLINE const Vector3 getXYZ( ) const; + // Get the x, y, and z elements of a quaternion + // + VECTORMATH_FORCE_INLINE const Vector3 getXYZ() const; - // Set the x element of a quaternion - // - VECTORMATH_FORCE_INLINE Quat & setX( float x ); + // Set the x element of a quaternion + // + VECTORMATH_FORCE_INLINE Quat &setX(float x); - // Set the y element of a quaternion - // - VECTORMATH_FORCE_INLINE Quat & setY( float y ); + // Set the y element of a quaternion + // + VECTORMATH_FORCE_INLINE Quat &setY(float y); - // Set the z element of a quaternion - // - VECTORMATH_FORCE_INLINE Quat & setZ( float z ); + // Set the z element of a quaternion + // + VECTORMATH_FORCE_INLINE Quat &setZ(float z); - // Set the w element of a quaternion - // - VECTORMATH_FORCE_INLINE Quat & setW( float w ); + // Set the w element of a quaternion + // + VECTORMATH_FORCE_INLINE Quat &setW(float w); - // Set the x element of a quaternion (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Quat & setX( const floatInVec &x ); + // Set the x element of a quaternion (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat &setX(const floatInVec &x); - // Set the y element of a quaternion (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Quat & setY( const floatInVec &y ); + // Set the y element of a quaternion (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat &setY(const floatInVec &y); - // Set the z element of a quaternion (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Quat & setZ( const floatInVec &z ); + // Set the z element of a quaternion (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat &setZ(const floatInVec &z); - // Set the w element of a quaternion (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Quat & setW( const floatInVec &w ); + // Set the w element of a quaternion (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat &setW(const floatInVec &w); - // Get the x element of a quaternion - // - VECTORMATH_FORCE_INLINE const floatInVec getX( ) const; + // Get the x element of a quaternion + // + VECTORMATH_FORCE_INLINE const floatInVec getX() const; - // Get the y element of a quaternion - // - VECTORMATH_FORCE_INLINE const floatInVec getY( ) const; + // Get the y element of a quaternion + // + VECTORMATH_FORCE_INLINE const floatInVec getY() const; - // Get the z element of a quaternion - // - VECTORMATH_FORCE_INLINE const floatInVec getZ( ) const; + // Get the z element of a quaternion + // + VECTORMATH_FORCE_INLINE const floatInVec getZ() const; - // Get the w element of a quaternion - // - VECTORMATH_FORCE_INLINE const floatInVec getW( ) const; + // Get the w element of a quaternion + // + VECTORMATH_FORCE_INLINE const floatInVec getW() const; - // Set an x, y, z, or w element of a quaternion by index - // - VECTORMATH_FORCE_INLINE Quat & setElem( int idx, float value ); + // Set an x, y, z, or w element of a quaternion by index + // + VECTORMATH_FORCE_INLINE Quat &setElem(int idx, float value); - // Set an x, y, z, or w element of a quaternion by index (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Quat & setElem( int idx, const floatInVec &value ); + // Set an x, y, z, or w element of a quaternion by index (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat &setElem(int idx, const floatInVec &value); - // Get an x, y, z, or w element of a quaternion by index - // - VECTORMATH_FORCE_INLINE const floatInVec getElem( int idx ) const; + // Get an x, y, z, or w element of a quaternion by index + // + VECTORMATH_FORCE_INLINE const floatInVec getElem(int idx) const; - // Subscripting operator to set or get an element - // - VECTORMATH_FORCE_INLINE VecIdx operator []( int idx ); + // Subscripting operator to set or get an element + // + VECTORMATH_FORCE_INLINE VecIdx operator[](int idx); - // Subscripting operator to get an element - // - VECTORMATH_FORCE_INLINE const floatInVec operator []( int idx ) const; + // Subscripting operator to get an element + // + VECTORMATH_FORCE_INLINE const floatInVec operator[](int idx) const; - // Add two quaternions - // - VECTORMATH_FORCE_INLINE const Quat operator +( const Quat &quat ) const; + // Add two quaternions + // + VECTORMATH_FORCE_INLINE const Quat operator+(const Quat &quat) const; - // Subtract a quaternion from another quaternion - // - VECTORMATH_FORCE_INLINE const Quat operator -( const Quat &quat ) const; + // Subtract a quaternion from another quaternion + // + VECTORMATH_FORCE_INLINE const Quat operator-(const Quat &quat) const; - // Multiply two quaternions - // - VECTORMATH_FORCE_INLINE const Quat operator *( const Quat &quat ) const; + // Multiply two quaternions + // + VECTORMATH_FORCE_INLINE const Quat operator*(const Quat &quat) const; - // Multiply a quaternion by a scalar - // - VECTORMATH_FORCE_INLINE const Quat operator *( float scalar ) const; + // Multiply a quaternion by a scalar + // + VECTORMATH_FORCE_INLINE const Quat operator*(float scalar) const; - // Divide a quaternion by a scalar - // - VECTORMATH_FORCE_INLINE const Quat operator /( float scalar ) const; + // Divide a quaternion by a scalar + // + VECTORMATH_FORCE_INLINE const Quat operator/(float scalar) const; - // Multiply a quaternion by a scalar (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE const Quat operator *( const floatInVec &scalar ) const; + // Multiply a quaternion by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Quat operator*(const floatInVec &scalar) const; - // Divide a quaternion by a scalar (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE const Quat operator /( const floatInVec &scalar ) const; + // Divide a quaternion by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Quat operator/(const floatInVec &scalar) const; - // Perform compound assignment and addition with a quaternion - // - VECTORMATH_FORCE_INLINE Quat & operator +=( const Quat &quat ); + // Perform compound assignment and addition with a quaternion + // + VECTORMATH_FORCE_INLINE Quat &operator+=(const Quat &quat); - // Perform compound assignment and subtraction by a quaternion - // - VECTORMATH_FORCE_INLINE Quat & operator -=( const Quat &quat ); + // Perform compound assignment and subtraction by a quaternion + // + VECTORMATH_FORCE_INLINE Quat &operator-=(const Quat &quat); - // Perform compound assignment and multiplication by a quaternion - // - VECTORMATH_FORCE_INLINE Quat & operator *=( const Quat &quat ); + // Perform compound assignment and multiplication by a quaternion + // + VECTORMATH_FORCE_INLINE Quat &operator*=(const Quat &quat); - // Perform compound assignment and multiplication by a scalar - // - VECTORMATH_FORCE_INLINE Quat & operator *=( float scalar ); + // Perform compound assignment and multiplication by a scalar + // + VECTORMATH_FORCE_INLINE Quat &operator*=(float scalar); - // Perform compound assignment and division by a scalar - // - VECTORMATH_FORCE_INLINE Quat & operator /=( float scalar ); + // Perform compound assignment and division by a scalar + // + VECTORMATH_FORCE_INLINE Quat &operator/=(float scalar); - // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Quat & operator *=( const floatInVec &scalar ); + // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat &operator*=(const floatInVec &scalar); - // Perform compound assignment and division by a scalar (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Quat & operator /=( const floatInVec &scalar ); + // Perform compound assignment and division by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Quat &operator/=(const floatInVec &scalar); - // Negate all elements of a quaternion - // - VECTORMATH_FORCE_INLINE const Quat operator -( ) const; + // Negate all elements of a quaternion + // + VECTORMATH_FORCE_INLINE const Quat operator-() const; - // Construct an identity quaternion - // - static VECTORMATH_FORCE_INLINE const Quat identity( ); + // Construct an identity quaternion + // + static VECTORMATH_FORCE_INLINE const Quat identity(); - // Construct a quaternion to rotate between two unit-length 3-D vectors - // NOTE: - // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. - // - static VECTORMATH_FORCE_INLINE const Quat rotation( const Vector3 &unitVec0, const Vector3 &unitVec1 ); + // Construct a quaternion to rotate between two unit-length 3-D vectors + // NOTE: + // The result is unpredictable if unitVec0 and unitVec1 point in opposite directions. + // + static VECTORMATH_FORCE_INLINE const Quat rotation(const Vector3 &unitVec0, const Vector3 &unitVec1); - // Construct a quaternion to rotate around a unit-length 3-D vector - // - static VECTORMATH_FORCE_INLINE const Quat rotation( float radians, const Vector3 &unitVec ); + // Construct a quaternion to rotate around a unit-length 3-D vector + // + static VECTORMATH_FORCE_INLINE const Quat rotation(float radians, const Vector3 &unitVec); - // Construct a quaternion to rotate around a unit-length 3-D vector (scalar data contained in vector data type) - // - static VECTORMATH_FORCE_INLINE const Quat rotation( const floatInVec &radians, const Vector3 &unitVec ); + // Construct a quaternion to rotate around a unit-length 3-D vector (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Quat rotation(const floatInVec &radians, const Vector3 &unitVec); - // Construct a quaternion to rotate around the x axis - // - static VECTORMATH_FORCE_INLINE const Quat rotationX( float radians ); + // Construct a quaternion to rotate around the x axis + // + static VECTORMATH_FORCE_INLINE const Quat rotationX(float radians); - // Construct a quaternion to rotate around the y axis - // - static VECTORMATH_FORCE_INLINE const Quat rotationY( float radians ); + // Construct a quaternion to rotate around the y axis + // + static VECTORMATH_FORCE_INLINE const Quat rotationY(float radians); - // Construct a quaternion to rotate around the z axis - // - static VECTORMATH_FORCE_INLINE const Quat rotationZ( float radians ); + // Construct a quaternion to rotate around the z axis + // + static VECTORMATH_FORCE_INLINE const Quat rotationZ(float radians); - // Construct a quaternion to rotate around the x axis (scalar data contained in vector data type) - // - static VECTORMATH_FORCE_INLINE const Quat rotationX( const floatInVec &radians ); + // Construct a quaternion to rotate around the x axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Quat rotationX(const floatInVec &radians); - // Construct a quaternion to rotate around the y axis (scalar data contained in vector data type) - // - static VECTORMATH_FORCE_INLINE const Quat rotationY( const floatInVec &radians ); - - // Construct a quaternion to rotate around the z axis (scalar data contained in vector data type) - // - static VECTORMATH_FORCE_INLINE const Quat rotationZ( const floatInVec &radians ); + // Construct a quaternion to rotate around the y axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Quat rotationY(const floatInVec &radians); + // Construct a quaternion to rotate around the z axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Quat rotationZ(const floatInVec &radians); }; // Multiply a quaternion by a scalar -// -VECTORMATH_FORCE_INLINE const Quat operator *( float scalar, const Quat &quat ); +// +VECTORMATH_FORCE_INLINE const Quat operator*(float scalar, const Quat &quat); // Multiply a quaternion by a scalar (scalar data contained in vector data type) -// -VECTORMATH_FORCE_INLINE const Quat operator *( const floatInVec &scalar, const Quat &quat ); +// +VECTORMATH_FORCE_INLINE const Quat operator*(const floatInVec &scalar, const Quat &quat); // Compute the conjugate of a quaternion -// -VECTORMATH_FORCE_INLINE const Quat conj( const Quat &quat ); +// +VECTORMATH_FORCE_INLINE const Quat conj(const Quat &quat); // Use a unit-length quaternion to rotate a 3-D vector -// -VECTORMATH_FORCE_INLINE const Vector3 rotate( const Quat &unitQuat, const Vector3 &vec ); +// +VECTORMATH_FORCE_INLINE const Vector3 rotate(const Quat &unitQuat, const Vector3 &vec); // Compute the dot product of two quaternions -// -VECTORMATH_FORCE_INLINE const floatInVec dot( const Quat &quat0, const Quat &quat1 ); +// +VECTORMATH_FORCE_INLINE const floatInVec dot(const Quat &quat0, const Quat &quat1); // Compute the norm of a quaternion -// -VECTORMATH_FORCE_INLINE const floatInVec norm( const Quat &quat ); +// +VECTORMATH_FORCE_INLINE const floatInVec norm(const Quat &quat); // Compute the length of a quaternion -// -VECTORMATH_FORCE_INLINE const floatInVec length( const Quat &quat ); +// +VECTORMATH_FORCE_INLINE const floatInVec length(const Quat &quat); // Normalize a quaternion -// NOTE: +// NOTE: // The result is unpredictable when all elements of quat are at or near zero. -// -VECTORMATH_FORCE_INLINE const Quat normalize( const Quat &quat ); +// +VECTORMATH_FORCE_INLINE const Quat normalize(const Quat &quat); // Linear interpolation between two quaternions -// NOTE: +// NOTE: // Does not clamp t between 0 and 1. -// -VECTORMATH_FORCE_INLINE const Quat lerp( float t, const Quat &quat0, const Quat &quat1 ); +// +VECTORMATH_FORCE_INLINE const Quat lerp(float t, const Quat &quat0, const Quat &quat1); // Linear interpolation between two quaternions (scalar data contained in vector data type) -// NOTE: +// NOTE: // Does not clamp t between 0 and 1. -// -VECTORMATH_FORCE_INLINE const Quat lerp( const floatInVec &t, const Quat &quat0, const Quat &quat1 ); +// +VECTORMATH_FORCE_INLINE const Quat lerp(const floatInVec &t, const Quat &quat0, const Quat &quat1); // Spherical linear interpolation between two quaternions -// NOTE: +// NOTE: // Interpolates along the shortest path between orientations. // Does not clamp t between 0 and 1. -// -VECTORMATH_FORCE_INLINE const Quat slerp( float t, const Quat &unitQuat0, const Quat &unitQuat1 ); +// +VECTORMATH_FORCE_INLINE const Quat slerp(float t, const Quat &unitQuat0, const Quat &unitQuat1); // Spherical linear interpolation between two quaternions (scalar data contained in vector data type) -// NOTE: +// NOTE: // Interpolates along the shortest path between orientations. // Does not clamp t between 0 and 1. -// -VECTORMATH_FORCE_INLINE const Quat slerp( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1 ); +// +VECTORMATH_FORCE_INLINE const Quat slerp(const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1); // Spherical quadrangle interpolation -// -VECTORMATH_FORCE_INLINE const Quat squad( float t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 ); +// +VECTORMATH_FORCE_INLINE const Quat squad(float t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3); // Spherical quadrangle interpolation (scalar data contained in vector data type) -// -VECTORMATH_FORCE_INLINE const Quat squad( const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3 ); +// +VECTORMATH_FORCE_INLINE const Quat squad(const floatInVec &t, const Quat &unitQuat0, const Quat &unitQuat1, const Quat &unitQuat2, const Quat &unitQuat3); // Conditionally select between two quaternions -// NOTE: +// NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. -// -VECTORMATH_FORCE_INLINE const Quat select( const Quat &quat0, const Quat &quat1, bool select1 ); +// +VECTORMATH_FORCE_INLINE const Quat select(const Quat &quat0, const Quat &quat1, bool select1); // Conditionally select between two quaternions (scalar data contained in vector data type) -// NOTE: +// NOTE: // This function uses a conditional select instruction to avoid a branch. -// -VECTORMATH_FORCE_INLINE const Quat select( const Quat &quat0, const Quat &quat1, const boolInVec &select1 ); +// +VECTORMATH_FORCE_INLINE const Quat select(const Quat &quat0, const Quat &quat1, const boolInVec &select1); #ifdef _VECTORMATH_DEBUG // Print a quaternion -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -VECTORMATH_FORCE_INLINE void print( const Quat &quat ); +// +VECTORMATH_FORCE_INLINE void print(const Quat &quat); // Print a quaternion and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -VECTORMATH_FORCE_INLINE void print( const Quat &quat, const char * name ); +// +VECTORMATH_FORCE_INLINE void print(const Quat &quat, const char *name); #endif @@ -1667,265 +1660,264 @@ VECTORMATH_FORCE_INLINE void print( const Quat &quat, const char * name ); // class Matrix3 { - Vector3 mCol0; - Vector3 mCol1; - Vector3 mCol2; + Vector3 mCol0; + Vector3 mCol1; + Vector3 mCol2; public: - // Default constructor; does no initialization - // - VECTORMATH_FORCE_INLINE Matrix3( ) { }; + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Matrix3(){}; - // Copy a 3x3 matrix - // - VECTORMATH_FORCE_INLINE Matrix3( const Matrix3 & mat ); + // Copy a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3(const Matrix3 &mat); - // Construct a 3x3 matrix containing the specified columns - // - VECTORMATH_FORCE_INLINE Matrix3( const Vector3 &col0, const Vector3 &col1, const Vector3 &col2 ); + // Construct a 3x3 matrix containing the specified columns + // + VECTORMATH_FORCE_INLINE Matrix3(const Vector3 &col0, const Vector3 &col1, const Vector3 &col2); - // Construct a 3x3 rotation matrix from a unit-length quaternion - // - explicit VECTORMATH_FORCE_INLINE Matrix3( const Quat &unitQuat ); + // Construct a 3x3 rotation matrix from a unit-length quaternion + // + explicit VECTORMATH_FORCE_INLINE Matrix3(const Quat &unitQuat); - // Set all elements of a 3x3 matrix to the same scalar value - // - explicit VECTORMATH_FORCE_INLINE Matrix3( float scalar ); + // Set all elements of a 3x3 matrix to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Matrix3(float scalar); - // Set all elements of a 3x3 matrix to the same scalar value (scalar data contained in vector data type) - // - explicit VECTORMATH_FORCE_INLINE Matrix3( const floatInVec &scalar ); + // Set all elements of a 3x3 matrix to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Matrix3(const floatInVec &scalar); - // Assign one 3x3 matrix to another - // - VECTORMATH_FORCE_INLINE Matrix3 & operator =( const Matrix3 & mat ); + // Assign one 3x3 matrix to another + // + VECTORMATH_FORCE_INLINE Matrix3 &operator=(const Matrix3 &mat); - // Set column 0 of a 3x3 matrix - // - VECTORMATH_FORCE_INLINE Matrix3 & setCol0( const Vector3 &col0 ); + // Set column 0 of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3 &setCol0(const Vector3 &col0); - // Set column 1 of a 3x3 matrix - // - VECTORMATH_FORCE_INLINE Matrix3 & setCol1( const Vector3 &col1 ); + // Set column 1 of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3 &setCol1(const Vector3 &col1); - // Set column 2 of a 3x3 matrix - // - VECTORMATH_FORCE_INLINE Matrix3 & setCol2( const Vector3 &col2 ); + // Set column 2 of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3 &setCol2(const Vector3 &col2); - // Get column 0 of a 3x3 matrix - // - VECTORMATH_FORCE_INLINE const Vector3 getCol0( ) const; + // Get column 0 of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol0() const; - // Get column 1 of a 3x3 matrix - // - VECTORMATH_FORCE_INLINE const Vector3 getCol1( ) const; + // Get column 1 of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol1() const; - // Get column 2 of a 3x3 matrix - // - VECTORMATH_FORCE_INLINE const Vector3 getCol2( ) const; + // Get column 2 of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol2() const; - // Set the column of a 3x3 matrix referred to by the specified index - // - VECTORMATH_FORCE_INLINE Matrix3 & setCol( int col, const Vector3 &vec ); + // Set the column of a 3x3 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE Matrix3 &setCol(int col, const Vector3 &vec); - // Set the row of a 3x3 matrix referred to by the specified index - // - VECTORMATH_FORCE_INLINE Matrix3 & setRow( int row, const Vector3 &vec ); + // Set the row of a 3x3 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE Matrix3 &setRow(int row, const Vector3 &vec); - // Get the column of a 3x3 matrix referred to by the specified index - // - VECTORMATH_FORCE_INLINE const Vector3 getCol( int col ) const; + // Get the column of a 3x3 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE const Vector3 getCol(int col) const; - // Get the row of a 3x3 matrix referred to by the specified index - // - VECTORMATH_FORCE_INLINE const Vector3 getRow( int row ) const; + // Get the row of a 3x3 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE const Vector3 getRow(int row) const; - // Subscripting operator to set or get a column - // - VECTORMATH_FORCE_INLINE Vector3 & operator []( int col ); + // Subscripting operator to set or get a column + // + VECTORMATH_FORCE_INLINE Vector3 &operator[](int col); - // Subscripting operator to get a column - // - VECTORMATH_FORCE_INLINE const Vector3 operator []( int col ) const; + // Subscripting operator to get a column + // + VECTORMATH_FORCE_INLINE const Vector3 operator[](int col) const; - // Set the element of a 3x3 matrix referred to by column and row indices - // - VECTORMATH_FORCE_INLINE Matrix3 & setElem( int col, int row, float val ); + // Set the element of a 3x3 matrix referred to by column and row indices + // + VECTORMATH_FORCE_INLINE Matrix3 &setElem(int col, int row, float val); - // Set the element of a 3x3 matrix referred to by column and row indices (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Matrix3 & setElem( int col, int row, const floatInVec &val ); + // Set the element of a 3x3 matrix referred to by column and row indices (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Matrix3 &setElem(int col, int row, const floatInVec &val); - // Get the element of a 3x3 matrix referred to by column and row indices - // - VECTORMATH_FORCE_INLINE const floatInVec getElem( int col, int row ) const; + // Get the element of a 3x3 matrix referred to by column and row indices + // + VECTORMATH_FORCE_INLINE const floatInVec getElem(int col, int row) const; - // Add two 3x3 matrices - // - VECTORMATH_FORCE_INLINE const Matrix3 operator +( const Matrix3 & mat ) const; + // Add two 3x3 matrices + // + VECTORMATH_FORCE_INLINE const Matrix3 operator+(const Matrix3 &mat) const; - // Subtract a 3x3 matrix from another 3x3 matrix - // - VECTORMATH_FORCE_INLINE const Matrix3 operator -( const Matrix3 & mat ) const; + // Subtract a 3x3 matrix from another 3x3 matrix + // + VECTORMATH_FORCE_INLINE const Matrix3 operator-(const Matrix3 &mat) const; - // Negate all elements of a 3x3 matrix - // - VECTORMATH_FORCE_INLINE const Matrix3 operator -( ) const; + // Negate all elements of a 3x3 matrix + // + VECTORMATH_FORCE_INLINE const Matrix3 operator-() const; - // Multiply a 3x3 matrix by a scalar - // - VECTORMATH_FORCE_INLINE const Matrix3 operator *( float scalar ) const; + // Multiply a 3x3 matrix by a scalar + // + VECTORMATH_FORCE_INLINE const Matrix3 operator*(float scalar) const; - // Multiply a 3x3 matrix by a scalar (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE const Matrix3 operator *( const floatInVec &scalar ) const; + // Multiply a 3x3 matrix by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Matrix3 operator*(const floatInVec &scalar) const; - // Multiply a 3x3 matrix by a 3-D vector - // - VECTORMATH_FORCE_INLINE const Vector3 operator *( const Vector3 &vec ) const; + // Multiply a 3x3 matrix by a 3-D vector + // + VECTORMATH_FORCE_INLINE const Vector3 operator*(const Vector3 &vec) const; - // Multiply two 3x3 matrices - // - VECTORMATH_FORCE_INLINE const Matrix3 operator *( const Matrix3 & mat ) const; + // Multiply two 3x3 matrices + // + VECTORMATH_FORCE_INLINE const Matrix3 operator*(const Matrix3 &mat) const; - // Perform compound assignment and addition with a 3x3 matrix - // - VECTORMATH_FORCE_INLINE Matrix3 & operator +=( const Matrix3 & mat ); + // Perform compound assignment and addition with a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3 &operator+=(const Matrix3 &mat); - // Perform compound assignment and subtraction by a 3x3 matrix - // - VECTORMATH_FORCE_INLINE Matrix3 & operator -=( const Matrix3 & mat ); + // Perform compound assignment and subtraction by a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3 &operator-=(const Matrix3 &mat); - // Perform compound assignment and multiplication by a scalar - // - VECTORMATH_FORCE_INLINE Matrix3 & operator *=( float scalar ); + // Perform compound assignment and multiplication by a scalar + // + VECTORMATH_FORCE_INLINE Matrix3 &operator*=(float scalar); - // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Matrix3 & operator *=( const floatInVec &scalar ); + // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Matrix3 &operator*=(const floatInVec &scalar); - // Perform compound assignment and multiplication by a 3x3 matrix - // - VECTORMATH_FORCE_INLINE Matrix3 & operator *=( const Matrix3 & mat ); + // Perform compound assignment and multiplication by a 3x3 matrix + // + VECTORMATH_FORCE_INLINE Matrix3 &operator*=(const Matrix3 &mat); - // Construct an identity 3x3 matrix - // - static VECTORMATH_FORCE_INLINE const Matrix3 identity( ); + // Construct an identity 3x3 matrix + // + static VECTORMATH_FORCE_INLINE const Matrix3 identity(); - // Construct a 3x3 matrix to rotate around the x axis - // - static VECTORMATH_FORCE_INLINE const Matrix3 rotationX( float radians ); + // Construct a 3x3 matrix to rotate around the x axis + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationX(float radians); - // Construct a 3x3 matrix to rotate around the y axis - // - static VECTORMATH_FORCE_INLINE const Matrix3 rotationY( float radians ); + // Construct a 3x3 matrix to rotate around the y axis + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationY(float radians); - // Construct a 3x3 matrix to rotate around the z axis - // - static VECTORMATH_FORCE_INLINE const Matrix3 rotationZ( float radians ); + // Construct a 3x3 matrix to rotate around the z axis + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationZ(float radians); - // Construct a 3x3 matrix to rotate around the x axis (scalar data contained in vector data type) - // - static VECTORMATH_FORCE_INLINE const Matrix3 rotationX( const floatInVec &radians ); + // Construct a 3x3 matrix to rotate around the x axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationX(const floatInVec &radians); - // Construct a 3x3 matrix to rotate around the y axis (scalar data contained in vector data type) - // - static VECTORMATH_FORCE_INLINE const Matrix3 rotationY( const floatInVec &radians ); + // Construct a 3x3 matrix to rotate around the y axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationY(const floatInVec &radians); - // Construct a 3x3 matrix to rotate around the z axis (scalar data contained in vector data type) - // - static VECTORMATH_FORCE_INLINE const Matrix3 rotationZ( const floatInVec &radians ); + // Construct a 3x3 matrix to rotate around the z axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationZ(const floatInVec &radians); - // Construct a 3x3 matrix to rotate around the x, y, and z axes - // - static VECTORMATH_FORCE_INLINE const Matrix3 rotationZYX( const Vector3 &radiansXYZ ); + // Construct a 3x3 matrix to rotate around the x, y, and z axes + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotationZYX(const Vector3 &radiansXYZ); - // Construct a 3x3 matrix to rotate around a unit-length 3-D vector - // - static VECTORMATH_FORCE_INLINE const Matrix3 rotation( float radians, const Vector3 &unitVec ); + // Construct a 3x3 matrix to rotate around a unit-length 3-D vector + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotation(float radians, const Vector3 &unitVec); - // Construct a 3x3 matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type) - // - static VECTORMATH_FORCE_INLINE const Matrix3 rotation( const floatInVec &radians, const Vector3 &unitVec ); + // Construct a 3x3 matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotation(const floatInVec &radians, const Vector3 &unitVec); - // Construct a rotation matrix from a unit-length quaternion - // - static VECTORMATH_FORCE_INLINE const Matrix3 rotation( const Quat &unitQuat ); - - // Construct a 3x3 matrix to perform scaling - // - static VECTORMATH_FORCE_INLINE const Matrix3 scale( const Vector3 &scaleVec ); + // Construct a rotation matrix from a unit-length quaternion + // + static VECTORMATH_FORCE_INLINE const Matrix3 rotation(const Quat &unitQuat); + // Construct a 3x3 matrix to perform scaling + // + static VECTORMATH_FORCE_INLINE const Matrix3 scale(const Vector3 &scaleVec); }; // Multiply a 3x3 matrix by a scalar -// -VECTORMATH_FORCE_INLINE const Matrix3 operator *( float scalar, const Matrix3 & mat ); +// +VECTORMATH_FORCE_INLINE const Matrix3 operator*(float scalar, const Matrix3 &mat); // Multiply a 3x3 matrix by a scalar (scalar data contained in vector data type) -// -VECTORMATH_FORCE_INLINE const Matrix3 operator *( const floatInVec &scalar, const Matrix3 & mat ); +// +VECTORMATH_FORCE_INLINE const Matrix3 operator*(const floatInVec &scalar, const Matrix3 &mat); // Append (post-multiply) a scale transformation to a 3x3 matrix -// NOTE: +// NOTE: // Faster than creating and multiplying a scale transformation matrix. -// -VECTORMATH_FORCE_INLINE const Matrix3 appendScale( const Matrix3 & mat, const Vector3 &scaleVec ); +// +VECTORMATH_FORCE_INLINE const Matrix3 appendScale(const Matrix3 &mat, const Vector3 &scaleVec); // Prepend (pre-multiply) a scale transformation to a 3x3 matrix -// NOTE: +// NOTE: // Faster than creating and multiplying a scale transformation matrix. -// -VECTORMATH_FORCE_INLINE const Matrix3 prependScale( const Vector3 &scaleVec, const Matrix3 & mat ); +// +VECTORMATH_FORCE_INLINE const Matrix3 prependScale(const Vector3 &scaleVec, const Matrix3 &mat); // Multiply two 3x3 matrices per element -// -VECTORMATH_FORCE_INLINE const Matrix3 mulPerElem( const Matrix3 & mat0, const Matrix3 & mat1 ); +// +VECTORMATH_FORCE_INLINE const Matrix3 mulPerElem(const Matrix3 &mat0, const Matrix3 &mat1); // Compute the absolute value of a 3x3 matrix per element -// -VECTORMATH_FORCE_INLINE const Matrix3 absPerElem( const Matrix3 & mat ); +// +VECTORMATH_FORCE_INLINE const Matrix3 absPerElem(const Matrix3 &mat); // Transpose of a 3x3 matrix -// -VECTORMATH_FORCE_INLINE const Matrix3 transpose( const Matrix3 & mat ); +// +VECTORMATH_FORCE_INLINE const Matrix3 transpose(const Matrix3 &mat); // Compute the inverse of a 3x3 matrix -// NOTE: +// NOTE: // Result is unpredictable when the determinant of mat is equal to or near 0. -// -VECTORMATH_FORCE_INLINE const Matrix3 inverse( const Matrix3 & mat ); +// +VECTORMATH_FORCE_INLINE const Matrix3 inverse(const Matrix3 &mat); // Determinant of a 3x3 matrix -// -VECTORMATH_FORCE_INLINE const floatInVec determinant( const Matrix3 & mat ); +// +VECTORMATH_FORCE_INLINE const floatInVec determinant(const Matrix3 &mat); // Conditionally select between two 3x3 matrices -// NOTE: +// NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. -// -VECTORMATH_FORCE_INLINE const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, bool select1 ); +// +VECTORMATH_FORCE_INLINE const Matrix3 select(const Matrix3 &mat0, const Matrix3 &mat1, bool select1); // Conditionally select between two 3x3 matrices (scalar data contained in vector data type) -// NOTE: +// NOTE: // This function uses a conditional select instruction to avoid a branch. -// -VECTORMATH_FORCE_INLINE const Matrix3 select( const Matrix3 & mat0, const Matrix3 & mat1, const boolInVec &select1 ); +// +VECTORMATH_FORCE_INLINE const Matrix3 select(const Matrix3 &mat0, const Matrix3 &mat1, const boolInVec &select1); #ifdef _VECTORMATH_DEBUG // Print a 3x3 matrix -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -VECTORMATH_FORCE_INLINE void print( const Matrix3 & mat ); +// +VECTORMATH_FORCE_INLINE void print(const Matrix3 &mat); // Print a 3x3 matrix and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -VECTORMATH_FORCE_INLINE void print( const Matrix3 & mat, const char * name ); +// +VECTORMATH_FORCE_INLINE void print(const Matrix3 &mat, const char *name); #endif @@ -1933,350 +1925,349 @@ VECTORMATH_FORCE_INLINE void print( const Matrix3 & mat, const char * name ); // class Matrix4 { - Vector4 mCol0; - Vector4 mCol1; - Vector4 mCol2; - Vector4 mCol3; + Vector4 mCol0; + Vector4 mCol1; + Vector4 mCol2; + Vector4 mCol3; public: - // Default constructor; does no initialization - // - VECTORMATH_FORCE_INLINE Matrix4( ) { }; + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Matrix4(){}; - // Copy a 4x4 matrix - // - VECTORMATH_FORCE_INLINE Matrix4( const Matrix4 & mat ); + // Copy a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4(const Matrix4 &mat); - // Construct a 4x4 matrix containing the specified columns - // - VECTORMATH_FORCE_INLINE Matrix4( const Vector4 &col0, const Vector4 &col1, const Vector4 &col2, const Vector4 &col3 ); + // Construct a 4x4 matrix containing the specified columns + // + VECTORMATH_FORCE_INLINE Matrix4(const Vector4 &col0, const Vector4 &col1, const Vector4 &col2, const Vector4 &col3); - // Construct a 4x4 matrix from a 3x4 transformation matrix - // - explicit VECTORMATH_FORCE_INLINE Matrix4( const Transform3 & mat ); + // Construct a 4x4 matrix from a 3x4 transformation matrix + // + explicit VECTORMATH_FORCE_INLINE Matrix4(const Transform3 &mat); - // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector - // - VECTORMATH_FORCE_INLINE Matrix4( const Matrix3 & mat, const Vector3 &translateVec ); + // Construct a 4x4 matrix from a 3x3 matrix and a 3-D vector + // + VECTORMATH_FORCE_INLINE Matrix4(const Matrix3 &mat, const Vector3 &translateVec); - // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector - // - VECTORMATH_FORCE_INLINE Matrix4( const Quat &unitQuat, const Vector3 &translateVec ); + // Construct a 4x4 matrix from a unit-length quaternion and a 3-D vector + // + VECTORMATH_FORCE_INLINE Matrix4(const Quat &unitQuat, const Vector3 &translateVec); - // Set all elements of a 4x4 matrix to the same scalar value - // - explicit VECTORMATH_FORCE_INLINE Matrix4( float scalar ); + // Set all elements of a 4x4 matrix to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Matrix4(float scalar); - // Set all elements of a 4x4 matrix to the same scalar value (scalar data contained in vector data type) - // - explicit VECTORMATH_FORCE_INLINE Matrix4( const floatInVec &scalar ); + // Set all elements of a 4x4 matrix to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Matrix4(const floatInVec &scalar); - // Assign one 4x4 matrix to another - // - VECTORMATH_FORCE_INLINE Matrix4 & operator =( const Matrix4 & mat ); + // Assign one 4x4 matrix to another + // + VECTORMATH_FORCE_INLINE Matrix4 &operator=(const Matrix4 &mat); - // Set the upper-left 3x3 submatrix - // NOTE: - // This function does not change the bottom row elements. - // - VECTORMATH_FORCE_INLINE Matrix4 & setUpper3x3( const Matrix3 & mat3 ); + // Set the upper-left 3x3 submatrix + // NOTE: + // This function does not change the bottom row elements. + // + VECTORMATH_FORCE_INLINE Matrix4 &setUpper3x3(const Matrix3 &mat3); - // Get the upper-left 3x3 submatrix of a 4x4 matrix - // - VECTORMATH_FORCE_INLINE const Matrix3 getUpper3x3( ) const; + // Get the upper-left 3x3 submatrix of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Matrix3 getUpper3x3() const; - // Set translation component - // NOTE: - // This function does not change the bottom row elements. - // - VECTORMATH_FORCE_INLINE Matrix4 & setTranslation( const Vector3 &translateVec ); + // Set translation component + // NOTE: + // This function does not change the bottom row elements. + // + VECTORMATH_FORCE_INLINE Matrix4 &setTranslation(const Vector3 &translateVec); - // Get the translation component of a 4x4 matrix - // - VECTORMATH_FORCE_INLINE const Vector3 getTranslation( ) const; + // Get the translation component of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getTranslation() const; - // Set column 0 of a 4x4 matrix - // - VECTORMATH_FORCE_INLINE Matrix4 & setCol0( const Vector4 &col0 ); + // Set column 0 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 &setCol0(const Vector4 &col0); - // Set column 1 of a 4x4 matrix - // - VECTORMATH_FORCE_INLINE Matrix4 & setCol1( const Vector4 &col1 ); + // Set column 1 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 &setCol1(const Vector4 &col1); - // Set column 2 of a 4x4 matrix - // - VECTORMATH_FORCE_INLINE Matrix4 & setCol2( const Vector4 &col2 ); + // Set column 2 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 &setCol2(const Vector4 &col2); - // Set column 3 of a 4x4 matrix - // - VECTORMATH_FORCE_INLINE Matrix4 & setCol3( const Vector4 &col3 ); + // Set column 3 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 &setCol3(const Vector4 &col3); - // Get column 0 of a 4x4 matrix - // - VECTORMATH_FORCE_INLINE const Vector4 getCol0( ) const; + // Get column 0 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Vector4 getCol0() const; - // Get column 1 of a 4x4 matrix - // - VECTORMATH_FORCE_INLINE const Vector4 getCol1( ) const; + // Get column 1 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Vector4 getCol1() const; - // Get column 2 of a 4x4 matrix - // - VECTORMATH_FORCE_INLINE const Vector4 getCol2( ) const; + // Get column 2 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Vector4 getCol2() const; - // Get column 3 of a 4x4 matrix - // - VECTORMATH_FORCE_INLINE const Vector4 getCol3( ) const; + // Get column 3 of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Vector4 getCol3() const; - // Set the column of a 4x4 matrix referred to by the specified index - // - VECTORMATH_FORCE_INLINE Matrix4 & setCol( int col, const Vector4 &vec ); + // Set the column of a 4x4 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE Matrix4 &setCol(int col, const Vector4 &vec); - // Set the row of a 4x4 matrix referred to by the specified index - // - VECTORMATH_FORCE_INLINE Matrix4 & setRow( int row, const Vector4 &vec ); + // Set the row of a 4x4 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE Matrix4 &setRow(int row, const Vector4 &vec); - // Get the column of a 4x4 matrix referred to by the specified index - // - VECTORMATH_FORCE_INLINE const Vector4 getCol( int col ) const; + // Get the column of a 4x4 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE const Vector4 getCol(int col) const; - // Get the row of a 4x4 matrix referred to by the specified index - // - VECTORMATH_FORCE_INLINE const Vector4 getRow( int row ) const; + // Get the row of a 4x4 matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE const Vector4 getRow(int row) const; - // Subscripting operator to set or get a column - // - VECTORMATH_FORCE_INLINE Vector4 & operator []( int col ); + // Subscripting operator to set or get a column + // + VECTORMATH_FORCE_INLINE Vector4 &operator[](int col); - // Subscripting operator to get a column - // - VECTORMATH_FORCE_INLINE const Vector4 operator []( int col ) const; + // Subscripting operator to get a column + // + VECTORMATH_FORCE_INLINE const Vector4 operator[](int col) const; - // Set the element of a 4x4 matrix referred to by column and row indices - // - VECTORMATH_FORCE_INLINE Matrix4 & setElem( int col, int row, float val ); + // Set the element of a 4x4 matrix referred to by column and row indices + // + VECTORMATH_FORCE_INLINE Matrix4 &setElem(int col, int row, float val); - // Set the element of a 4x4 matrix referred to by column and row indices (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Matrix4 & setElem( int col, int row, const floatInVec &val ); + // Set the element of a 4x4 matrix referred to by column and row indices (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Matrix4 &setElem(int col, int row, const floatInVec &val); - // Get the element of a 4x4 matrix referred to by column and row indices - // - VECTORMATH_FORCE_INLINE const floatInVec getElem( int col, int row ) const; + // Get the element of a 4x4 matrix referred to by column and row indices + // + VECTORMATH_FORCE_INLINE const floatInVec getElem(int col, int row) const; - // Add two 4x4 matrices - // - VECTORMATH_FORCE_INLINE const Matrix4 operator +( const Matrix4 & mat ) const; + // Add two 4x4 matrices + // + VECTORMATH_FORCE_INLINE const Matrix4 operator+(const Matrix4 &mat) const; - // Subtract a 4x4 matrix from another 4x4 matrix - // - VECTORMATH_FORCE_INLINE const Matrix4 operator -( const Matrix4 & mat ) const; + // Subtract a 4x4 matrix from another 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Matrix4 operator-(const Matrix4 &mat) const; - // Negate all elements of a 4x4 matrix - // - VECTORMATH_FORCE_INLINE const Matrix4 operator -( ) const; + // Negate all elements of a 4x4 matrix + // + VECTORMATH_FORCE_INLINE const Matrix4 operator-() const; - // Multiply a 4x4 matrix by a scalar - // - VECTORMATH_FORCE_INLINE const Matrix4 operator *( float scalar ) const; + // Multiply a 4x4 matrix by a scalar + // + VECTORMATH_FORCE_INLINE const Matrix4 operator*(float scalar) const; - // Multiply a 4x4 matrix by a scalar (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE const Matrix4 operator *( const floatInVec &scalar ) const; + // Multiply a 4x4 matrix by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE const Matrix4 operator*(const floatInVec &scalar) const; - // Multiply a 4x4 matrix by a 4-D vector - // - VECTORMATH_FORCE_INLINE const Vector4 operator *( const Vector4 &vec ) const; + // Multiply a 4x4 matrix by a 4-D vector + // + VECTORMATH_FORCE_INLINE const Vector4 operator*(const Vector4 &vec) const; - // Multiply a 4x4 matrix by a 3-D vector - // - VECTORMATH_FORCE_INLINE const Vector4 operator *( const Vector3 &vec ) const; + // Multiply a 4x4 matrix by a 3-D vector + // + VECTORMATH_FORCE_INLINE const Vector4 operator*(const Vector3 &vec) const; - // Multiply a 4x4 matrix by a 3-D point - // - VECTORMATH_FORCE_INLINE const Vector4 operator *( const Point3 &pnt ) const; + // Multiply a 4x4 matrix by a 3-D point + // + VECTORMATH_FORCE_INLINE const Vector4 operator*(const Point3 &pnt) const; - // Multiply two 4x4 matrices - // - VECTORMATH_FORCE_INLINE const Matrix4 operator *( const Matrix4 & mat ) const; + // Multiply two 4x4 matrices + // + VECTORMATH_FORCE_INLINE const Matrix4 operator*(const Matrix4 &mat) const; - // Multiply a 4x4 matrix by a 3x4 transformation matrix - // - VECTORMATH_FORCE_INLINE const Matrix4 operator *( const Transform3 & tfrm ) const; + // Multiply a 4x4 matrix by a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Matrix4 operator*(const Transform3 &tfrm) const; - // Perform compound assignment and addition with a 4x4 matrix - // - VECTORMATH_FORCE_INLINE Matrix4 & operator +=( const Matrix4 & mat ); + // Perform compound assignment and addition with a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 &operator+=(const Matrix4 &mat); - // Perform compound assignment and subtraction by a 4x4 matrix - // - VECTORMATH_FORCE_INLINE Matrix4 & operator -=( const Matrix4 & mat ); + // Perform compound assignment and subtraction by a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 &operator-=(const Matrix4 &mat); - // Perform compound assignment and multiplication by a scalar - // - VECTORMATH_FORCE_INLINE Matrix4 & operator *=( float scalar ); + // Perform compound assignment and multiplication by a scalar + // + VECTORMATH_FORCE_INLINE Matrix4 &operator*=(float scalar); - // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Matrix4 & operator *=( const floatInVec &scalar ); + // Perform compound assignment and multiplication by a scalar (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Matrix4 &operator*=(const floatInVec &scalar); - // Perform compound assignment and multiplication by a 4x4 matrix - // - VECTORMATH_FORCE_INLINE Matrix4 & operator *=( const Matrix4 & mat ); + // Perform compound assignment and multiplication by a 4x4 matrix + // + VECTORMATH_FORCE_INLINE Matrix4 &operator*=(const Matrix4 &mat); - // Perform compound assignment and multiplication by a 3x4 transformation matrix - // - VECTORMATH_FORCE_INLINE Matrix4 & operator *=( const Transform3 & tfrm ); + // Perform compound assignment and multiplication by a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Matrix4 &operator*=(const Transform3 &tfrm); - // Construct an identity 4x4 matrix - // - static VECTORMATH_FORCE_INLINE const Matrix4 identity( ); + // Construct an identity 4x4 matrix + // + static VECTORMATH_FORCE_INLINE const Matrix4 identity(); - // Construct a 4x4 matrix to rotate around the x axis - // - static VECTORMATH_FORCE_INLINE const Matrix4 rotationX( float radians ); + // Construct a 4x4 matrix to rotate around the x axis + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationX(float radians); - // Construct a 4x4 matrix to rotate around the y axis - // - static VECTORMATH_FORCE_INLINE const Matrix4 rotationY( float radians ); + // Construct a 4x4 matrix to rotate around the y axis + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationY(float radians); - // Construct a 4x4 matrix to rotate around the z axis - // - static VECTORMATH_FORCE_INLINE const Matrix4 rotationZ( float radians ); + // Construct a 4x4 matrix to rotate around the z axis + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationZ(float radians); - // Construct a 4x4 matrix to rotate around the x axis (scalar data contained in vector data type) - // - static VECTORMATH_FORCE_INLINE const Matrix4 rotationX( const floatInVec &radians ); + // Construct a 4x4 matrix to rotate around the x axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationX(const floatInVec &radians); - // Construct a 4x4 matrix to rotate around the y axis (scalar data contained in vector data type) - // - static VECTORMATH_FORCE_INLINE const Matrix4 rotationY( const floatInVec &radians ); + // Construct a 4x4 matrix to rotate around the y axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationY(const floatInVec &radians); - // Construct a 4x4 matrix to rotate around the z axis (scalar data contained in vector data type) - // - static VECTORMATH_FORCE_INLINE const Matrix4 rotationZ( const floatInVec &radians ); + // Construct a 4x4 matrix to rotate around the z axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationZ(const floatInVec &radians); - // Construct a 4x4 matrix to rotate around the x, y, and z axes - // - static VECTORMATH_FORCE_INLINE const Matrix4 rotationZYX( const Vector3 &radiansXYZ ); + // Construct a 4x4 matrix to rotate around the x, y, and z axes + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotationZYX(const Vector3 &radiansXYZ); - // Construct a 4x4 matrix to rotate around a unit-length 3-D vector - // - static VECTORMATH_FORCE_INLINE const Matrix4 rotation( float radians, const Vector3 &unitVec ); + // Construct a 4x4 matrix to rotate around a unit-length 3-D vector + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotation(float radians, const Vector3 &unitVec); - // Construct a 4x4 matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type) - // - static VECTORMATH_FORCE_INLINE const Matrix4 rotation( const floatInVec &radians, const Vector3 &unitVec ); + // Construct a 4x4 matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotation(const floatInVec &radians, const Vector3 &unitVec); - // Construct a rotation matrix from a unit-length quaternion - // - static VECTORMATH_FORCE_INLINE const Matrix4 rotation( const Quat &unitQuat ); + // Construct a rotation matrix from a unit-length quaternion + // + static VECTORMATH_FORCE_INLINE const Matrix4 rotation(const Quat &unitQuat); - // Construct a 4x4 matrix to perform scaling - // - static VECTORMATH_FORCE_INLINE const Matrix4 scale( const Vector3 &scaleVec ); + // Construct a 4x4 matrix to perform scaling + // + static VECTORMATH_FORCE_INLINE const Matrix4 scale(const Vector3 &scaleVec); - // Construct a 4x4 matrix to perform translation - // - static VECTORMATH_FORCE_INLINE const Matrix4 translation( const Vector3 &translateVec ); + // Construct a 4x4 matrix to perform translation + // + static VECTORMATH_FORCE_INLINE const Matrix4 translation(const Vector3 &translateVec); - // Construct viewing matrix based on eye, position looked at, and up direction - // - static VECTORMATH_FORCE_INLINE const Matrix4 lookAt( const Point3 &eyePos, const Point3 &lookAtPos, const Vector3 &upVec ); + // Construct viewing matrix based on eye, position looked at, and up direction + // + static VECTORMATH_FORCE_INLINE const Matrix4 lookAt(const Point3 &eyePos, const Point3 &lookAtPos, const Vector3 &upVec); - // Construct a perspective projection matrix - // - static VECTORMATH_FORCE_INLINE const Matrix4 perspective( float fovyRadians, float aspect, float zNear, float zFar ); + // Construct a perspective projection matrix + // + static VECTORMATH_FORCE_INLINE const Matrix4 perspective(float fovyRadians, float aspect, float zNear, float zFar); - // Construct a perspective projection matrix based on frustum - // - static VECTORMATH_FORCE_INLINE const Matrix4 frustum( float left, float right, float bottom, float top, float zNear, float zFar ); - - // Construct an orthographic projection matrix - // - static VECTORMATH_FORCE_INLINE const Matrix4 orthographic( float left, float right, float bottom, float top, float zNear, float zFar ); + // Construct a perspective projection matrix based on frustum + // + static VECTORMATH_FORCE_INLINE const Matrix4 frustum(float left, float right, float bottom, float top, float zNear, float zFar); + // Construct an orthographic projection matrix + // + static VECTORMATH_FORCE_INLINE const Matrix4 orthographic(float left, float right, float bottom, float top, float zNear, float zFar); }; // Multiply a 4x4 matrix by a scalar -// -VECTORMATH_FORCE_INLINE const Matrix4 operator *( float scalar, const Matrix4 & mat ); +// +VECTORMATH_FORCE_INLINE const Matrix4 operator*(float scalar, const Matrix4 &mat); // Multiply a 4x4 matrix by a scalar (scalar data contained in vector data type) -// -VECTORMATH_FORCE_INLINE const Matrix4 operator *( const floatInVec &scalar, const Matrix4 & mat ); +// +VECTORMATH_FORCE_INLINE const Matrix4 operator*(const floatInVec &scalar, const Matrix4 &mat); // Append (post-multiply) a scale transformation to a 4x4 matrix -// NOTE: +// NOTE: // Faster than creating and multiplying a scale transformation matrix. -// -VECTORMATH_FORCE_INLINE const Matrix4 appendScale( const Matrix4 & mat, const Vector3 &scaleVec ); +// +VECTORMATH_FORCE_INLINE const Matrix4 appendScale(const Matrix4 &mat, const Vector3 &scaleVec); // Prepend (pre-multiply) a scale transformation to a 4x4 matrix -// NOTE: +// NOTE: // Faster than creating and multiplying a scale transformation matrix. -// -VECTORMATH_FORCE_INLINE const Matrix4 prependScale( const Vector3 &scaleVec, const Matrix4 & mat ); +// +VECTORMATH_FORCE_INLINE const Matrix4 prependScale(const Vector3 &scaleVec, const Matrix4 &mat); // Multiply two 4x4 matrices per element -// -VECTORMATH_FORCE_INLINE const Matrix4 mulPerElem( const Matrix4 & mat0, const Matrix4 & mat1 ); +// +VECTORMATH_FORCE_INLINE const Matrix4 mulPerElem(const Matrix4 &mat0, const Matrix4 &mat1); // Compute the absolute value of a 4x4 matrix per element -// -VECTORMATH_FORCE_INLINE const Matrix4 absPerElem( const Matrix4 & mat ); +// +VECTORMATH_FORCE_INLINE const Matrix4 absPerElem(const Matrix4 &mat); // Transpose of a 4x4 matrix -// -VECTORMATH_FORCE_INLINE const Matrix4 transpose( const Matrix4 & mat ); +// +VECTORMATH_FORCE_INLINE const Matrix4 transpose(const Matrix4 &mat); // Compute the inverse of a 4x4 matrix -// NOTE: +// NOTE: // Result is unpredictable when the determinant of mat is equal to or near 0. -// -VECTORMATH_FORCE_INLINE const Matrix4 inverse( const Matrix4 & mat ); +// +VECTORMATH_FORCE_INLINE const Matrix4 inverse(const Matrix4 &mat); // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix -// NOTE: +// NOTE: // This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. The result is unpredictable when the determinant of mat is equal to or near 0. -// -VECTORMATH_FORCE_INLINE const Matrix4 affineInverse( const Matrix4 & mat ); +// +VECTORMATH_FORCE_INLINE const Matrix4 affineInverse(const Matrix4 &mat); // Compute the inverse of a 4x4 matrix, which is expected to be an affine matrix with an orthogonal upper-left 3x3 submatrix -// NOTE: +// NOTE: // This can be used to achieve better performance than a general inverse when the specified 4x4 matrix meets the given restrictions. -// -VECTORMATH_FORCE_INLINE const Matrix4 orthoInverse( const Matrix4 & mat ); +// +VECTORMATH_FORCE_INLINE const Matrix4 orthoInverse(const Matrix4 &mat); // Determinant of a 4x4 matrix -// -VECTORMATH_FORCE_INLINE const floatInVec determinant( const Matrix4 & mat ); +// +VECTORMATH_FORCE_INLINE const floatInVec determinant(const Matrix4 &mat); // Conditionally select between two 4x4 matrices -// NOTE: +// NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. -// -VECTORMATH_FORCE_INLINE const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, bool select1 ); +// +VECTORMATH_FORCE_INLINE const Matrix4 select(const Matrix4 &mat0, const Matrix4 &mat1, bool select1); // Conditionally select between two 4x4 matrices (scalar data contained in vector data type) -// NOTE: +// NOTE: // This function uses a conditional select instruction to avoid a branch. -// -VECTORMATH_FORCE_INLINE const Matrix4 select( const Matrix4 & mat0, const Matrix4 & mat1, const boolInVec &select1 ); +// +VECTORMATH_FORCE_INLINE const Matrix4 select(const Matrix4 &mat0, const Matrix4 &mat1, const boolInVec &select1); #ifdef _VECTORMATH_DEBUG // Print a 4x4 matrix -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -VECTORMATH_FORCE_INLINE void print( const Matrix4 & mat ); +// +VECTORMATH_FORCE_INLINE void print(const Matrix4 &mat); // Print a 4x4 matrix and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -VECTORMATH_FORCE_INLINE void print( const Matrix4 & mat, const char * name ); +// +VECTORMATH_FORCE_INLINE void print(const Matrix4 &mat, const char *name); #endif @@ -2284,261 +2275,260 @@ VECTORMATH_FORCE_INLINE void print( const Matrix4 & mat, const char * name ); // class Transform3 { - Vector3 mCol0; - Vector3 mCol1; - Vector3 mCol2; - Vector3 mCol3; + Vector3 mCol0; + Vector3 mCol1; + Vector3 mCol2; + Vector3 mCol3; public: - // Default constructor; does no initialization - // - VECTORMATH_FORCE_INLINE Transform3( ) { }; + // Default constructor; does no initialization + // + VECTORMATH_FORCE_INLINE Transform3(){}; - // Copy a 3x4 transformation matrix - // - VECTORMATH_FORCE_INLINE Transform3( const Transform3 & tfrm ); + // Copy a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Transform3(const Transform3 &tfrm); - // Construct a 3x4 transformation matrix containing the specified columns - // - VECTORMATH_FORCE_INLINE Transform3( const Vector3 &col0, const Vector3 &col1, const Vector3 &col2, const Vector3 &col3 ); + // Construct a 3x4 transformation matrix containing the specified columns + // + VECTORMATH_FORCE_INLINE Transform3(const Vector3 &col0, const Vector3 &col1, const Vector3 &col2, const Vector3 &col3); - // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector - // - VECTORMATH_FORCE_INLINE Transform3( const Matrix3 & tfrm, const Vector3 &translateVec ); + // Construct a 3x4 transformation matrix from a 3x3 matrix and a 3-D vector + // + VECTORMATH_FORCE_INLINE Transform3(const Matrix3 &tfrm, const Vector3 &translateVec); - // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector - // - VECTORMATH_FORCE_INLINE Transform3( const Quat &unitQuat, const Vector3 &translateVec ); + // Construct a 3x4 transformation matrix from a unit-length quaternion and a 3-D vector + // + VECTORMATH_FORCE_INLINE Transform3(const Quat &unitQuat, const Vector3 &translateVec); - // Set all elements of a 3x4 transformation matrix to the same scalar value - // - explicit VECTORMATH_FORCE_INLINE Transform3( float scalar ); + // Set all elements of a 3x4 transformation matrix to the same scalar value + // + explicit VECTORMATH_FORCE_INLINE Transform3(float scalar); - // Set all elements of a 3x4 transformation matrix to the same scalar value (scalar data contained in vector data type) - // - explicit VECTORMATH_FORCE_INLINE Transform3( const floatInVec &scalar ); + // Set all elements of a 3x4 transformation matrix to the same scalar value (scalar data contained in vector data type) + // + explicit VECTORMATH_FORCE_INLINE Transform3(const floatInVec &scalar); - // Assign one 3x4 transformation matrix to another - // - VECTORMATH_FORCE_INLINE Transform3 & operator =( const Transform3 & tfrm ); + // Assign one 3x4 transformation matrix to another + // + VECTORMATH_FORCE_INLINE Transform3 &operator=(const Transform3 &tfrm); - // Set the upper-left 3x3 submatrix - // - VECTORMATH_FORCE_INLINE Transform3 & setUpper3x3( const Matrix3 & mat3 ); + // Set the upper-left 3x3 submatrix + // + VECTORMATH_FORCE_INLINE Transform3 &setUpper3x3(const Matrix3 &mat3); - // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix - // - VECTORMATH_FORCE_INLINE const Matrix3 getUpper3x3( ) const; + // Get the upper-left 3x3 submatrix of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Matrix3 getUpper3x3() const; - // Set translation component - // - VECTORMATH_FORCE_INLINE Transform3 & setTranslation( const Vector3 &translateVec ); + // Set translation component + // + VECTORMATH_FORCE_INLINE Transform3 &setTranslation(const Vector3 &translateVec); - // Get the translation component of a 3x4 transformation matrix - // - VECTORMATH_FORCE_INLINE const Vector3 getTranslation( ) const; + // Get the translation component of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getTranslation() const; - // Set column 0 of a 3x4 transformation matrix - // - VECTORMATH_FORCE_INLINE Transform3 & setCol0( const Vector3 &col0 ); + // Set column 0 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Transform3 &setCol0(const Vector3 &col0); - // Set column 1 of a 3x4 transformation matrix - // - VECTORMATH_FORCE_INLINE Transform3 & setCol1( const Vector3 &col1 ); + // Set column 1 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Transform3 &setCol1(const Vector3 &col1); - // Set column 2 of a 3x4 transformation matrix - // - VECTORMATH_FORCE_INLINE Transform3 & setCol2( const Vector3 &col2 ); + // Set column 2 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Transform3 &setCol2(const Vector3 &col2); - // Set column 3 of a 3x4 transformation matrix - // - VECTORMATH_FORCE_INLINE Transform3 & setCol3( const Vector3 &col3 ); + // Set column 3 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Transform3 &setCol3(const Vector3 &col3); - // Get column 0 of a 3x4 transformation matrix - // - VECTORMATH_FORCE_INLINE const Vector3 getCol0( ) const; + // Get column 0 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol0() const; - // Get column 1 of a 3x4 transformation matrix - // - VECTORMATH_FORCE_INLINE const Vector3 getCol1( ) const; + // Get column 1 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol1() const; - // Get column 2 of a 3x4 transformation matrix - // - VECTORMATH_FORCE_INLINE const Vector3 getCol2( ) const; + // Get column 2 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol2() const; - // Get column 3 of a 3x4 transformation matrix - // - VECTORMATH_FORCE_INLINE const Vector3 getCol3( ) const; + // Get column 3 of a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE const Vector3 getCol3() const; - // Set the column of a 3x4 transformation matrix referred to by the specified index - // - VECTORMATH_FORCE_INLINE Transform3 & setCol( int col, const Vector3 &vec ); + // Set the column of a 3x4 transformation matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE Transform3 &setCol(int col, const Vector3 &vec); - // Set the row of a 3x4 transformation matrix referred to by the specified index - // - VECTORMATH_FORCE_INLINE Transform3 & setRow( int row, const Vector4 &vec ); + // Set the row of a 3x4 transformation matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE Transform3 &setRow(int row, const Vector4 &vec); - // Get the column of a 3x4 transformation matrix referred to by the specified index - // - VECTORMATH_FORCE_INLINE const Vector3 getCol( int col ) const; + // Get the column of a 3x4 transformation matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE const Vector3 getCol(int col) const; - // Get the row of a 3x4 transformation matrix referred to by the specified index - // - VECTORMATH_FORCE_INLINE const Vector4 getRow( int row ) const; + // Get the row of a 3x4 transformation matrix referred to by the specified index + // + VECTORMATH_FORCE_INLINE const Vector4 getRow(int row) const; - // Subscripting operator to set or get a column - // - VECTORMATH_FORCE_INLINE Vector3 & operator []( int col ); + // Subscripting operator to set or get a column + // + VECTORMATH_FORCE_INLINE Vector3 &operator[](int col); - // Subscripting operator to get a column - // - VECTORMATH_FORCE_INLINE const Vector3 operator []( int col ) const; + // Subscripting operator to get a column + // + VECTORMATH_FORCE_INLINE const Vector3 operator[](int col) const; - // Set the element of a 3x4 transformation matrix referred to by column and row indices - // - VECTORMATH_FORCE_INLINE Transform3 & setElem( int col, int row, float val ); + // Set the element of a 3x4 transformation matrix referred to by column and row indices + // + VECTORMATH_FORCE_INLINE Transform3 &setElem(int col, int row, float val); - // Set the element of a 3x4 transformation matrix referred to by column and row indices (scalar data contained in vector data type) - // - VECTORMATH_FORCE_INLINE Transform3 & setElem( int col, int row, const floatInVec &val ); + // Set the element of a 3x4 transformation matrix referred to by column and row indices (scalar data contained in vector data type) + // + VECTORMATH_FORCE_INLINE Transform3 &setElem(int col, int row, const floatInVec &val); - // Get the element of a 3x4 transformation matrix referred to by column and row indices - // - VECTORMATH_FORCE_INLINE const floatInVec getElem( int col, int row ) const; + // Get the element of a 3x4 transformation matrix referred to by column and row indices + // + VECTORMATH_FORCE_INLINE const floatInVec getElem(int col, int row) const; - // Multiply a 3x4 transformation matrix by a 3-D vector - // - VECTORMATH_FORCE_INLINE const Vector3 operator *( const Vector3 &vec ) const; + // Multiply a 3x4 transformation matrix by a 3-D vector + // + VECTORMATH_FORCE_INLINE const Vector3 operator*(const Vector3 &vec) const; - // Multiply a 3x4 transformation matrix by a 3-D point - // - VECTORMATH_FORCE_INLINE const Point3 operator *( const Point3 &pnt ) const; + // Multiply a 3x4 transformation matrix by a 3-D point + // + VECTORMATH_FORCE_INLINE const Point3 operator*(const Point3 &pnt) const; - // Multiply two 3x4 transformation matrices - // - VECTORMATH_FORCE_INLINE const Transform3 operator *( const Transform3 & tfrm ) const; + // Multiply two 3x4 transformation matrices + // + VECTORMATH_FORCE_INLINE const Transform3 operator*(const Transform3 &tfrm) const; - // Perform compound assignment and multiplication by a 3x4 transformation matrix - // - VECTORMATH_FORCE_INLINE Transform3 & operator *=( const Transform3 & tfrm ); + // Perform compound assignment and multiplication by a 3x4 transformation matrix + // + VECTORMATH_FORCE_INLINE Transform3 &operator*=(const Transform3 &tfrm); - // Construct an identity 3x4 transformation matrix - // - static VECTORMATH_FORCE_INLINE const Transform3 identity( ); + // Construct an identity 3x4 transformation matrix + // + static VECTORMATH_FORCE_INLINE const Transform3 identity(); - // Construct a 3x4 transformation matrix to rotate around the x axis - // - static VECTORMATH_FORCE_INLINE const Transform3 rotationX( float radians ); + // Construct a 3x4 transformation matrix to rotate around the x axis + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationX(float radians); - // Construct a 3x4 transformation matrix to rotate around the y axis - // - static VECTORMATH_FORCE_INLINE const Transform3 rotationY( float radians ); + // Construct a 3x4 transformation matrix to rotate around the y axis + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationY(float radians); - // Construct a 3x4 transformation matrix to rotate around the z axis - // - static VECTORMATH_FORCE_INLINE const Transform3 rotationZ( float radians ); + // Construct a 3x4 transformation matrix to rotate around the z axis + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationZ(float radians); - // Construct a 3x4 transformation matrix to rotate around the x axis (scalar data contained in vector data type) - // - static VECTORMATH_FORCE_INLINE const Transform3 rotationX( const floatInVec &radians ); + // Construct a 3x4 transformation matrix to rotate around the x axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationX(const floatInVec &radians); - // Construct a 3x4 transformation matrix to rotate around the y axis (scalar data contained in vector data type) - // - static VECTORMATH_FORCE_INLINE const Transform3 rotationY( const floatInVec &radians ); + // Construct a 3x4 transformation matrix to rotate around the y axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationY(const floatInVec &radians); - // Construct a 3x4 transformation matrix to rotate around the z axis (scalar data contained in vector data type) - // - static VECTORMATH_FORCE_INLINE const Transform3 rotationZ( const floatInVec &radians ); + // Construct a 3x4 transformation matrix to rotate around the z axis (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationZ(const floatInVec &radians); - // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes - // - static VECTORMATH_FORCE_INLINE const Transform3 rotationZYX( const Vector3 &radiansXYZ ); + // Construct a 3x4 transformation matrix to rotate around the x, y, and z axes + // + static VECTORMATH_FORCE_INLINE const Transform3 rotationZYX(const Vector3 &radiansXYZ); - // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector - // - static VECTORMATH_FORCE_INLINE const Transform3 rotation( float radians, const Vector3 &unitVec ); + // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector + // + static VECTORMATH_FORCE_INLINE const Transform3 rotation(float radians, const Vector3 &unitVec); - // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type) - // - static VECTORMATH_FORCE_INLINE const Transform3 rotation( const floatInVec &radians, const Vector3 &unitVec ); + // Construct a 3x4 transformation matrix to rotate around a unit-length 3-D vector (scalar data contained in vector data type) + // + static VECTORMATH_FORCE_INLINE const Transform3 rotation(const floatInVec &radians, const Vector3 &unitVec); - // Construct a rotation matrix from a unit-length quaternion - // - static VECTORMATH_FORCE_INLINE const Transform3 rotation( const Quat &unitQuat ); + // Construct a rotation matrix from a unit-length quaternion + // + static VECTORMATH_FORCE_INLINE const Transform3 rotation(const Quat &unitQuat); - // Construct a 3x4 transformation matrix to perform scaling - // - static VECTORMATH_FORCE_INLINE const Transform3 scale( const Vector3 &scaleVec ); - - // Construct a 3x4 transformation matrix to perform translation - // - static VECTORMATH_FORCE_INLINE const Transform3 translation( const Vector3 &translateVec ); + // Construct a 3x4 transformation matrix to perform scaling + // + static VECTORMATH_FORCE_INLINE const Transform3 scale(const Vector3 &scaleVec); + // Construct a 3x4 transformation matrix to perform translation + // + static VECTORMATH_FORCE_INLINE const Transform3 translation(const Vector3 &translateVec); }; // Append (post-multiply) a scale transformation to a 3x4 transformation matrix -// NOTE: +// NOTE: // Faster than creating and multiplying a scale transformation matrix. -// -VECTORMATH_FORCE_INLINE const Transform3 appendScale( const Transform3 & tfrm, const Vector3 &scaleVec ); +// +VECTORMATH_FORCE_INLINE const Transform3 appendScale(const Transform3 &tfrm, const Vector3 &scaleVec); // Prepend (pre-multiply) a scale transformation to a 3x4 transformation matrix -// NOTE: +// NOTE: // Faster than creating and multiplying a scale transformation matrix. -// -VECTORMATH_FORCE_INLINE const Transform3 prependScale( const Vector3 &scaleVec, const Transform3 & tfrm ); +// +VECTORMATH_FORCE_INLINE const Transform3 prependScale(const Vector3 &scaleVec, const Transform3 &tfrm); // Multiply two 3x4 transformation matrices per element -// -VECTORMATH_FORCE_INLINE const Transform3 mulPerElem( const Transform3 & tfrm0, const Transform3 & tfrm1 ); +// +VECTORMATH_FORCE_INLINE const Transform3 mulPerElem(const Transform3 &tfrm0, const Transform3 &tfrm1); // Compute the absolute value of a 3x4 transformation matrix per element -// -VECTORMATH_FORCE_INLINE const Transform3 absPerElem( const Transform3 & tfrm ); +// +VECTORMATH_FORCE_INLINE const Transform3 absPerElem(const Transform3 &tfrm); // Inverse of a 3x4 transformation matrix -// NOTE: +// NOTE: // Result is unpredictable when the determinant of the left 3x3 submatrix is equal to or near 0. -// -VECTORMATH_FORCE_INLINE const Transform3 inverse( const Transform3 & tfrm ); +// +VECTORMATH_FORCE_INLINE const Transform3 inverse(const Transform3 &tfrm); // Compute the inverse of a 3x4 transformation matrix, expected to have an orthogonal upper-left 3x3 submatrix -// NOTE: +// NOTE: // This can be used to achieve better performance than a general inverse when the specified 3x4 transformation matrix meets the given restrictions. -// -VECTORMATH_FORCE_INLINE const Transform3 orthoInverse( const Transform3 & tfrm ); +// +VECTORMATH_FORCE_INLINE const Transform3 orthoInverse(const Transform3 &tfrm); // Conditionally select between two 3x4 transformation matrices -// NOTE: +// NOTE: // This function uses a conditional select instruction to avoid a branch. // However, the transfer of select1 to a VMX register may use more processing time than a branch. // Use the boolInVec version for better performance. -// -VECTORMATH_FORCE_INLINE const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, bool select1 ); +// +VECTORMATH_FORCE_INLINE const Transform3 select(const Transform3 &tfrm0, const Transform3 &tfrm1, bool select1); // Conditionally select between two 3x4 transformation matrices (scalar data contained in vector data type) -// NOTE: +// NOTE: // This function uses a conditional select instruction to avoid a branch. -// -VECTORMATH_FORCE_INLINE const Transform3 select( const Transform3 & tfrm0, const Transform3 & tfrm1, const boolInVec &select1 ); +// +VECTORMATH_FORCE_INLINE const Transform3 select(const Transform3 &tfrm0, const Transform3 &tfrm1, const boolInVec &select1); #ifdef _VECTORMATH_DEBUG // Print a 3x4 transformation matrix -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -VECTORMATH_FORCE_INLINE void print( const Transform3 & tfrm ); +// +VECTORMATH_FORCE_INLINE void print(const Transform3 &tfrm); // Print a 3x4 transformation matrix and an associated string identifier -// NOTE: +// NOTE: // Function is only defined when _VECTORMATH_DEBUG is defined. -// -VECTORMATH_FORCE_INLINE void print( const Transform3 & tfrm, const char * name ); +// +VECTORMATH_FORCE_INLINE void print(const Transform3 &tfrm, const char *name); #endif -} // namespace Aos -} // namespace Vectormath +} // namespace Aos +} // namespace Vectormath #include "vec_aos.h" #include "quat_aos.h" diff --git a/test/Bullet2/vectormath/vmInclude.h b/test/Bullet2/vectormath/vmInclude.h index 656514e42..4f858e473 100644 --- a/test/Bullet2/vectormath/vmInclude.h +++ b/test/Bullet2/vectormath/vmInclude.h @@ -4,28 +4,24 @@ #include "LinearMath/btScalar.h" -#if defined (USE_SYSTEM_VECTORMATH) || defined (__CELLOS_LV2__) - #include -#else //(USE_SYSTEM_VECTORMATH) - #if defined (BT_USE_SSE) - #include "sse/vectormath_aos.h" - #else //all other platforms - #if defined (BT_USE_NEON) - #include "neon/vectormath_aos.h" - #else - #include "scalar/vectormath_aos.h" - #endif - #endif //(BT_USE_SSE) && defined (_WIN32) -#endif //(USE_SYSTEM_VECTORMATH) +#if defined(USE_SYSTEM_VECTORMATH) || defined(__CELLOS_LV2__) +#include +#else //(USE_SYSTEM_VECTORMATH) +#if defined(BT_USE_SSE) +#include "sse/vectormath_aos.h" +#else //all other platforms +#if defined(BT_USE_NEON) +#include "neon/vectormath_aos.h" +#else +#include "scalar/vectormath_aos.h" +#endif +#endif //(BT_USE_SSE) && defined (_WIN32) +#endif //(USE_SYSTEM_VECTORMATH) - - -typedef Vectormath::Aos::Vector3 vmVector3; -typedef Vectormath::Aos::Quat vmQuat; -typedef Vectormath::Aos::Matrix3 vmMatrix3; +typedef Vectormath::Aos::Vector3 vmVector3; +typedef Vectormath::Aos::Quat vmQuat; +typedef Vectormath::Aos::Matrix3 vmMatrix3; typedef Vectormath::Aos::Transform3 vmTransform3; -typedef Vectormath::Aos::Point3 vmPoint3; - -#endif //__VM_INCLUDE_H - +typedef Vectormath::Aos::Point3 vmPoint3; +#endif //__VM_INCLUDE_H diff --git a/test/BulletDynamics/test_btKinematicCharacterController.cpp b/test/BulletDynamics/test_btKinematicCharacterController.cpp index 4b0a567c0..e06dbf321 100644 --- a/test/BulletDynamics/test_btKinematicCharacterController.cpp +++ b/test/BulletDynamics/test_btKinematicCharacterController.cpp @@ -5,23 +5,22 @@ #include #include +GTEST_TEST(BulletDynamics, KinematicCharacterController) +{ + btPairCachingGhostObject* ghostObject = new btPairCachingGhostObject(); + btBoxShape* convexShape = new btBoxShape(btVector3(1, 1, 1)); -GTEST_TEST(BulletDynamics, KinematicCharacterController) { + //For now only a simple test that it initializes correctly. + btKinematicCharacterController* tested = new btKinematicCharacterController(ghostObject, convexShape, 1); + EXPECT_TRUE(tested); - btPairCachingGhostObject* ghostObject = new btPairCachingGhostObject(); - btBoxShape* convexShape = new btBoxShape(btVector3(1, 1, 1)); - - //For now only a simple test that it initializes correctly. - btKinematicCharacterController* tested = new btKinematicCharacterController(ghostObject, convexShape, 1); - EXPECT_TRUE(tested); - - EXPECT_FLOAT_EQ(-9.8 * 3.0, tested->getGravity().x()); - EXPECT_FLOAT_EQ(0, tested->getGravity().y()); - EXPECT_FLOAT_EQ(0, tested->getGravity().z()); + EXPECT_FLOAT_EQ(-9.8 * 3.0, tested->getGravity().x()); + EXPECT_FLOAT_EQ(0, tested->getGravity().y()); + EXPECT_FLOAT_EQ(0, tested->getGravity().z()); } - -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); } \ No newline at end of file diff --git a/test/GwenOpenGLTest/Button.cpp b/test/GwenOpenGLTest/Button.cpp index 727670ed2..139d995a4 100644 --- a/test/GwenOpenGLTest/Button.cpp +++ b/test/GwenOpenGLTest/Button.cpp @@ -4,72 +4,68 @@ using namespace Gwen; class Button : public GUnit { - public: - - GWEN_CONTROL_INLINE( Button, GUnit ) +public: + GWEN_CONTROL_INLINE(Button, GUnit) { - // Normal button - Controls::Button* pButtonA = new Controls::Button( this ); - pButtonA->SetText( L"Event Tester" ); - pButtonA->onPress.Add( this, &Button::onButtonA ); + // Normal button + Controls::Button* pButtonA = new Controls::Button(this); + pButtonA->SetText(L"Event Tester"); + pButtonA->onPress.Add(this, &Button::onButtonA); - { - Controls::Button* pButtonA = new Controls::Button( this ); - pButtonA->SetBounds( 200, 30, 300, 200 ); - pButtonA->SetText( L"Event Tester" ); - pButtonA->onPress.Add( this, &Button::onButtonA ); - } + { + Controls::Button* pButtonA = new Controls::Button(this); + pButtonA->SetBounds(200, 30, 300, 200); + pButtonA->SetText(L"Event Tester"); + pButtonA->onPress.Add(this, &Button::onButtonA); + } - // Unicode test - Controls::Button* pButtonB = new Controls::Button( this ); - pButtonB->SetText( L"\u0417\u0430\u043C\u0435\u0436\u043D\u0430\u044F \u043C\u043E\u0432\u0430" ); - Gwen::Align::PlaceBelow( pButtonB, pButtonA, 10 ); + // Unicode test + Controls::Button* pButtonB = new Controls::Button(this); + pButtonB->SetText(L"\u0417\u0430\u043C\u0435\u0436\u043D\u0430\u044F \u043C\u043E\u0432\u0430"); + Gwen::Align::PlaceBelow(pButtonB, pButtonA, 10); - // Image with text - Controls::Button* pButtonC = new Controls::Button( this ); - pButtonC->SetText( L"Image Button" ); - pButtonC->SetImage( L"test16.png" ); - Gwen::Align::PlaceBelow( pButtonC, pButtonB, 10 ); + // Image with text + Controls::Button* pButtonC = new Controls::Button(this); + pButtonC->SetText(L"Image Button"); + pButtonC->SetImage(L"test16.png"); + Gwen::Align::PlaceBelow(pButtonC, pButtonB, 10); - // Just image - Controls::Button* pButtonD = new Controls::Button( this ); - pButtonD->SetText( L"" ); - pButtonD->SetImage( L"test16.png" ); - pButtonD->SetSize( 20, 20 ); - Gwen::Align::PlaceBelow( pButtonD, pButtonC, 10 ); + // Just image + Controls::Button* pButtonD = new Controls::Button(this); + pButtonD->SetText(L""); + pButtonD->SetImage(L"test16.png"); + pButtonD->SetSize(20, 20); + Gwen::Align::PlaceBelow(pButtonD, pButtonC, 10); - // Toggle button - Controls::Button* pButtonE = new Controls::Button( this ); - pButtonE->SetText( L"Toggle Me" ); - pButtonE->SetIsToggle( true ); - pButtonE->onToggle.Add( this, &Button::OnToggle ); - pButtonE->onToggleOn.Add( this, &Button::OnToggleOn ); - pButtonE->onToggleOff.Add( this, &Button::OnToggleOff ); - Gwen::Align::PlaceBelow( pButtonE, pButtonD, 10 ); + // Toggle button + Controls::Button* pButtonE = new Controls::Button(this); + pButtonE->SetText(L"Toggle Me"); + pButtonE->SetIsToggle(true); + pButtonE->onToggle.Add(this, &Button::OnToggle); + pButtonE->onToggleOn.Add(this, &Button::OnToggleOn); + pButtonE->onToggleOff.Add(this, &Button::OnToggleOff); + Gwen::Align::PlaceBelow(pButtonE, pButtonD, 10); } - void onButtonA( Controls::Base* pControl ) + void onButtonA(Controls::Base* pControl) { - UnitPrint( L"Button Pressed (using 'OnPress' event)" ); + UnitPrint(L"Button Pressed (using 'OnPress' event)"); } - void OnToggle( Controls::Base* pControl ) + void OnToggle(Controls::Base* pControl) { - UnitPrint( L"Button Toggled (using 'OnToggle' event)" ); + UnitPrint(L"Button Toggled (using 'OnToggle' event)"); } - void OnToggleOn( Controls::Base* pControl ) + void OnToggleOn(Controls::Base* pControl) { - UnitPrint( L"Button Toggled ON (using 'OnToggleOn' event)" ); + UnitPrint(L"Button Toggled ON (using 'OnToggleOn' event)"); } - void OnToggleOff( Controls::Base* pControl ) + void OnToggleOff(Controls::Base* pControl) { - UnitPrint( L"Button Toggled Off (using 'OnToggleOff' event)" ); + UnitPrint(L"Button Toggled Off (using 'OnToggleOff' event)"); } - }; - - -DEFINE_UNIT_TEST( Button, L"Button" ); \ No newline at end of file +DEFINE_UNIT_TEST(Button, L"Button"); \ No newline at end of file diff --git a/test/GwenOpenGLTest/Checkbox.cpp b/test/GwenOpenGLTest/Checkbox.cpp index b46a84b37..fb107ebc4 100644 --- a/test/GwenOpenGLTest/Checkbox.cpp +++ b/test/GwenOpenGLTest/Checkbox.cpp @@ -5,44 +5,38 @@ using namespace Gwen; class Checkbox : public GUnit { - public: - - GWEN_CONTROL_INLINE( Checkbox, GUnit ) +public: + GWEN_CONTROL_INLINE(Checkbox, GUnit) { - Gwen::Controls::CheckBox* check = new Gwen::Controls::CheckBox( this ); - check->SetPos( 10, 10 ); - check->onChecked.Add( this, &Checkbox::OnChecked ); - check->onUnChecked.Add( this, &Checkbox::OnUnchecked ); - check->onCheckChanged.Add( this, &Checkbox::OnCheckChanged ); - - - Gwen::Controls::CheckBoxWithLabel* labeled = new Gwen::Controls::CheckBoxWithLabel( this ); - labeled->SetPos( 10, 10 ); - labeled->Label()->SetText( "Labeled CheckBox" ); - labeled->Checkbox()->onChecked.Add( this, &Checkbox::OnChecked ); - labeled->Checkbox()->onUnChecked.Add( this, &Checkbox::OnUnchecked ); - labeled->Checkbox()->onCheckChanged.Add( this, &Checkbox::OnCheckChanged ); - Gwen::Align::PlaceBelow( labeled, check, 10 ); + Gwen::Controls::CheckBox* check = new Gwen::Controls::CheckBox(this); + check->SetPos(10, 10); + check->onChecked.Add(this, &Checkbox::OnChecked); + check->onUnChecked.Add(this, &Checkbox::OnUnchecked); + check->onCheckChanged.Add(this, &Checkbox::OnCheckChanged); + Gwen::Controls::CheckBoxWithLabel* labeled = new Gwen::Controls::CheckBoxWithLabel(this); + labeled->SetPos(10, 10); + labeled->Label()->SetText("Labeled CheckBox"); + labeled->Checkbox()->onChecked.Add(this, &Checkbox::OnChecked); + labeled->Checkbox()->onUnChecked.Add(this, &Checkbox::OnUnchecked); + labeled->Checkbox()->onCheckChanged.Add(this, &Checkbox::OnCheckChanged); + Gwen::Align::PlaceBelow(labeled, check, 10); } - void OnChecked( Controls::Base* pControl ) + void OnChecked(Controls::Base* pControl) { - UnitPrint( L"Checkbox Checked (using 'OnChecked' event)" ); + UnitPrint(L"Checkbox Checked (using 'OnChecked' event)"); } - void OnUnchecked( Controls::Base* pControl ) + void OnUnchecked(Controls::Base* pControl) { - UnitPrint( L"Checkbox Unchecked (using 'OnUnchecked' event)" ); + UnitPrint(L"Checkbox Unchecked (using 'OnUnchecked' event)"); } - void OnCheckChanged( Controls::Base* pControl ) + void OnCheckChanged(Controls::Base* pControl) { - UnitPrint( L"Checkbox CheckChanged (using 'OnCheckChanged' event)" ); + UnitPrint(L"Checkbox CheckChanged (using 'OnCheckChanged' event)"); } - }; - - -DEFINE_UNIT_TEST( Checkbox, L"Checkbox" ); \ No newline at end of file +DEFINE_UNIT_TEST(Checkbox, L"Checkbox"); \ No newline at end of file diff --git a/test/GwenOpenGLTest/ComboBox.cpp b/test/GwenOpenGLTest/ComboBox.cpp index 3ae13cb09..b7d6023d2 100644 --- a/test/GwenOpenGLTest/ComboBox.cpp +++ b/test/GwenOpenGLTest/ComboBox.cpp @@ -5,54 +5,48 @@ using namespace Gwen; class ComboBox : public GUnit { - public: - - GWEN_CONTROL_INLINE( ComboBox, GUnit ) +public: + GWEN_CONTROL_INLINE(ComboBox, GUnit) { - { - Gwen::Controls::ComboBox* combo = new Gwen::Controls::ComboBox( this ); + Gwen::Controls::ComboBox* combo = new Gwen::Controls::ComboBox(this); combo->SetKeyboardInputEnabled(true); - combo->SetPos( 50, 50 ); - combo->SetWidth( 200 ); + combo->SetPos(50, 50); + combo->SetWidth(200); + combo->AddItem(L"Option One", "one"); + combo->AddItem(L"Number Two", "two"); + combo->AddItem(L"Door Three", "three"); + combo->AddItem(L"Four Legs", "four"); + combo->AddItem(L"Five Birds", "five"); - combo->AddItem( L"Option One", "one" ); - combo->AddItem( L"Number Two", "two" ); - combo->AddItem( L"Door Three", "three" ); - combo->AddItem( L"Four Legs", "four" ); - combo->AddItem( L"Five Birds", "five" ); - - combo->onSelection.Add( this, &ComboBox::OnComboSelect ); + combo->onSelection.Add(this, &ComboBox::OnComboSelect); } { // Empty.. - Gwen::Controls::ComboBox* combo = new Gwen::Controls::ComboBox( this ); - combo->SetPos( 50, 80 ); - combo->SetWidth( 200 ); + Gwen::Controls::ComboBox* combo = new Gwen::Controls::ComboBox(this); + combo->SetPos(50, 80); + combo->SetWidth(200); } { // Empty.. - Gwen::Controls::ComboBox* combo = new Gwen::Controls::ComboBox( this ); - combo->SetPos( 50, 110 ); - combo->SetWidth( 200 ); + Gwen::Controls::ComboBox* combo = new Gwen::Controls::ComboBox(this); + combo->SetPos(50, 110); + combo->SetWidth(200); - for (int i=0; i<500; i++ ) - combo->AddItem( L"Lots Of Options" ); + for (int i = 0; i < 500; i++) + combo->AddItem(L"Lots Of Options"); } - } - void OnComboSelect( Gwen::Controls::Base* pControl ) + void OnComboSelect(Gwen::Controls::Base* pControl) { Gwen::Controls::ComboBox* combo = (Gwen::Controls::ComboBox*)pControl; - UnitPrint( Utility::Format( L"Combo Changed: %s", combo->GetSelectedItem()->GetText().c_str() ) ); + UnitPrint(Utility::Format(L"Combo Changed: %s", combo->GetSelectedItem()->GetText().c_str())); } }; - - -DEFINE_UNIT_TEST( ComboBox, L"ComboBox" ); \ No newline at end of file +DEFINE_UNIT_TEST(ComboBox, L"ComboBox"); \ No newline at end of file diff --git a/test/GwenOpenGLTest/CrossSplitter.cpp b/test/GwenOpenGLTest/CrossSplitter.cpp index dea72d466..1c1c7336d 100644 --- a/test/GwenOpenGLTest/CrossSplitter.cpp +++ b/test/GwenOpenGLTest/CrossSplitter.cpp @@ -7,78 +7,74 @@ using namespace Gwen; class CrossSplitter : public GUnit { - public: - - GWEN_CONTROL_INLINE( CrossSplitter, GUnit ) +public: + GWEN_CONTROL_INLINE(CrossSplitter, GUnit) { - m_bSplittersVisible = false; m_iCurZoom = 0; - m_Splitter = new Gwen::Controls::CrossSplitter( this ); + m_Splitter = new Gwen::Controls::CrossSplitter(this); m_Splitter->SetPos(0, 0); - m_Splitter->Dock( Pos::Fill ); + m_Splitter->Dock(Pos::Fill); { - Gwen::Controls::Button* testButton = new Gwen::Controls::Button( m_Splitter ); - testButton->SetText( "TOPLEFT"); - m_Splitter->SetPanel( 0, testButton ); + Gwen::Controls::Button* testButton = new Gwen::Controls::Button(m_Splitter); + testButton->SetText("TOPLEFT"); + m_Splitter->SetPanel(0, testButton); } { - Gwen::Controls::Button* testButton = new Gwen::Controls::Button( m_Splitter ); - testButton->SetText( "TOPRIGHT"); - m_Splitter->SetPanel( 1, testButton ); + Gwen::Controls::Button* testButton = new Gwen::Controls::Button(m_Splitter); + testButton->SetText("TOPRIGHT"); + m_Splitter->SetPanel(1, testButton); } { - Gwen::Controls::Button* testButton = new Gwen::Controls::Button( m_Splitter ); - testButton->SetText( "BOTTOMRIGHT"); - m_Splitter->SetPanel( 2, testButton ); + Gwen::Controls::Button* testButton = new Gwen::Controls::Button(m_Splitter); + testButton->SetText("BOTTOMRIGHT"); + m_Splitter->SetPanel(2, testButton); } { - Gwen::Controls::Button* testButton = new Gwen::Controls::Button( m_Splitter ); - testButton->SetText( "BOTTOMLEFT"); - m_Splitter->SetPanel( 3, testButton ); + Gwen::Controls::Button* testButton = new Gwen::Controls::Button(m_Splitter); + testButton->SetText("BOTTOMLEFT"); + m_Splitter->SetPanel(3, testButton); } - //Status bar to hold unit testing buttons - Gwen::Controls::StatusBar* pStatus = new Gwen::Controls::StatusBar( this ); - pStatus->Dock( Pos::Bottom ); - + Gwen::Controls::StatusBar* pStatus = new Gwen::Controls::StatusBar(this); + pStatus->Dock(Pos::Bottom); { - Gwen::Controls::Button* pButton = new Gwen::Controls::Button( pStatus ); - pButton->SetText( "Zoom" ); - pButton->onPress.Add( this, &CrossSplitter::ZoomTest ); - pStatus->AddControl( pButton, false ); + Gwen::Controls::Button* pButton = new Gwen::Controls::Button(pStatus); + pButton->SetText("Zoom"); + pButton->onPress.Add(this, &CrossSplitter::ZoomTest); + pStatus->AddControl(pButton, false); } { - Gwen::Controls::Button* pButton = new Gwen::Controls::Button( pStatus ); - pButton->SetText( "UnZoom" ); - pButton->onPress.Add( this, &CrossSplitter::UnZoomTest ); - pStatus->AddControl( pButton, false ); + Gwen::Controls::Button* pButton = new Gwen::Controls::Button(pStatus); + pButton->SetText("UnZoom"); + pButton->onPress.Add(this, &CrossSplitter::UnZoomTest); + pStatus->AddControl(pButton, false); } { - Gwen::Controls::Button* pButton = new Gwen::Controls::Button( pStatus ); - pButton->SetText( "CenterPanels" ); - pButton->onPress.Add( this, &CrossSplitter::CenterPanels ); - pStatus->AddControl( pButton, true ); + Gwen::Controls::Button* pButton = new Gwen::Controls::Button(pStatus); + pButton->SetText("CenterPanels"); + pButton->onPress.Add(this, &CrossSplitter::CenterPanels); + pStatus->AddControl(pButton, true); } { - Gwen::Controls::Button* pButton = new Gwen::Controls::Button( pStatus ); - pButton->SetText( "Splitters" ); - pButton->onPress.Add( this, &CrossSplitter::ToggleSplitters ); - pStatus->AddControl( pButton, true ); + Gwen::Controls::Button* pButton = new Gwen::Controls::Button(pStatus); + pButton->SetText("Splitters"); + pButton->onPress.Add(this, &CrossSplitter::ToggleSplitters); + pStatus->AddControl(pButton, true); } } - void ZoomTest( Gwen::Controls::Base* pFromPanel ) + void ZoomTest(Gwen::Controls::Base* pFromPanel) { m_Splitter->Zoom(m_iCurZoom); m_iCurZoom++; @@ -86,30 +82,26 @@ class CrossSplitter : public GUnit m_iCurZoom = 0; } - void UnZoomTest( Gwen::Controls::Base* pFromPanel ) + void UnZoomTest(Gwen::Controls::Base* pFromPanel) { m_Splitter->UnZoom(); } - void CenterPanels( Gwen::Controls::Base* pFromPanel ) + void CenterPanels(Gwen::Controls::Base* pFromPanel) { m_Splitter->CenterPanels(); m_Splitter->UnZoom(); } - void ToggleSplitters( Gwen::Controls::Base* pFromPanel ) + void ToggleSplitters(Gwen::Controls::Base* pFromPanel) { - m_Splitter->SetSplittersVisible( !m_bSplittersVisible ); + m_Splitter->SetSplittersVisible(!m_bSplittersVisible); m_bSplittersVisible = !m_bSplittersVisible; } - bool m_bSplittersVisible; - int m_iCurZoom; + int m_iCurZoom; Controls::CrossSplitter* m_Splitter; - }; - - -DEFINE_UNIT_TEST( CrossSplitter, L"CrossSplitter" ); \ No newline at end of file +DEFINE_UNIT_TEST(CrossSplitter, L"CrossSplitter"); \ No newline at end of file diff --git a/test/GwenOpenGLTest/GroupBox.cpp b/test/GwenOpenGLTest/GroupBox.cpp index f0a490162..586895f29 100644 --- a/test/GwenOpenGLTest/GroupBox.cpp +++ b/test/GwenOpenGLTest/GroupBox.cpp @@ -5,17 +5,13 @@ using namespace Gwen; class GroupBox2 : public GUnit { - public: - - GWEN_CONTROL_INLINE( GroupBox2, GUnit ) +public: + GWEN_CONTROL_INLINE(GroupBox2, GUnit) { - Gwen::Controls::GroupBox* pGroup = new Gwen::Controls::GroupBox( this ); - pGroup->Dock( Pos::Fill ); - pGroup->SetText( "Group Box" ); + Gwen::Controls::GroupBox* pGroup = new Gwen::Controls::GroupBox(this); + pGroup->Dock(Pos::Fill); + pGroup->SetText("Group Box"); } }; - - - -DEFINE_UNIT_TEST( GroupBox2, L"GroupBox" ); \ No newline at end of file +DEFINE_UNIT_TEST(GroupBox2, L"GroupBox"); \ No newline at end of file diff --git a/test/GwenOpenGLTest/ImagePanel.cpp b/test/GwenOpenGLTest/ImagePanel.cpp index 015cfb307..271145fb9 100644 --- a/test/GwenOpenGLTest/ImagePanel.cpp +++ b/test/GwenOpenGLTest/ImagePanel.cpp @@ -5,28 +5,23 @@ using namespace Gwen; class ImagePanel : public GUnit { - public: - - GWEN_CONTROL_INLINE( ImagePanel, GUnit ) +public: + GWEN_CONTROL_INLINE(ImagePanel, GUnit) { // Normal { - Controls::ImagePanel* img = new Controls::ImagePanel( this ); - img->SetImage( L"gwen.png" ); - img->SetBounds( 10, 10, 100, 100 ); + Controls::ImagePanel* img = new Controls::ImagePanel(this); + img->SetImage(L"gwen.png"); + img->SetBounds(10, 10, 100, 100); } // Missing { - Controls::ImagePanel* img = new Controls::ImagePanel( this ); - img->SetImage( L"missingimage.png" ); - img->SetBounds( 120, 10, 100, 100 ); + Controls::ImagePanel* img = new Controls::ImagePanel(this); + img->SetImage(L"missingimage.png"); + img->SetBounds(120, 10, 100, 100); } - } - }; - - -DEFINE_UNIT_TEST( ImagePanel, L"ImagePanel" ); \ No newline at end of file +DEFINE_UNIT_TEST(ImagePanel, L"ImagePanel"); \ No newline at end of file diff --git a/test/GwenOpenGLTest/Label.cpp b/test/GwenOpenGLTest/Label.cpp index a2301f1f2..5ca41b50a 100644 --- a/test/GwenOpenGLTest/Label.cpp +++ b/test/GwenOpenGLTest/Label.cpp @@ -5,66 +5,65 @@ using namespace Gwen; class Label : public GUnit { - public: - - GWEN_CONTROL_INLINE( Label, GUnit ) +public: + GWEN_CONTROL_INLINE(Label, GUnit) { { - Gwen::Controls::Label* label = new Gwen::Controls::Label( this ); - label->SetText( "Garry's Normal Label" ); + Gwen::Controls::Label* label = new Gwen::Controls::Label(this); + label->SetText("Garry's Normal Label"); label->SizeToContents(); - label->SetPos( 10, 10 ); + label->SetPos(10, 10); } { - Gwen::Controls::Label* label = new Gwen::Controls::Label( this ); - label->SetText( L"Chinese: \u4E45\u6709\u5F52\u5929\u613F \u7EC8\u8FC7\u9B3C\u95E8\u5173" ); + Gwen::Controls::Label* label = new Gwen::Controls::Label(this); + label->SetText(L"Chinese: \u4E45\u6709\u5F52\u5929\u613F \u7EC8\u8FC7\u9B3C\u95E8\u5173"); label->SizeToContents(); - label->SetPos( 10, 30 ); + label->SetPos(10, 30); } { - Gwen::Controls::Label* label = new Gwen::Controls::Label( this ); - label->SetText( L"Japanese: \u751F\u3080\u304E\u3000\u751F\u3054\u3081\u3000\u751F\u305F\u307E\u3054" ); + Gwen::Controls::Label* label = new Gwen::Controls::Label(this); + label->SetText(L"Japanese: \u751F\u3080\u304E\u3000\u751F\u3054\u3081\u3000\u751F\u305F\u307E\u3054"); label->SizeToContents(); - label->SetPos( 10, 50 ); + label->SetPos(10, 50); } { - Gwen::Controls::Label* label = new Gwen::Controls::Label( this ); - label->SetText( L"Korean: \uADF9\uC9C0\uD0D0\uD5D8\u3000\uD611\uD68C\uACB0\uC131\u3000\uCCB4\uACC4\uC801\u3000\uC5F0\uAD6C" ); + Gwen::Controls::Label* label = new Gwen::Controls::Label(this); + label->SetText(L"Korean: \uADF9\uC9C0\uD0D0\uD5D8\u3000\uD611\uD68C\uACB0\uC131\u3000\uCCB4\uACC4\uC801\u3000\uC5F0\uAD6C"); label->SizeToContents(); - label->SetPos( 10, 70 ); + label->SetPos(10, 70); } { - Gwen::Controls::Label* label = new Gwen::Controls::Label( this ); - label->SetText( L"Hindi: \u092F\u0947 \u0905\u0928\u0941\u091A\u094D\u091B\u0947\u0926 \u0939\u093F\u0928\u094D\u0926\u0940 \u092E\u0947\u0902 \u0939\u0948\u0964" ); + Gwen::Controls::Label* label = new Gwen::Controls::Label(this); + label->SetText(L"Hindi: \u092F\u0947 \u0905\u0928\u0941\u091A\u094D\u091B\u0947\u0926 \u0939\u093F\u0928\u094D\u0926\u0940 \u092E\u0947\u0902 \u0939\u0948\u0964"); label->SizeToContents(); - label->SetPos( 10, 90 ); + label->SetPos(10, 90); } { - Gwen::Controls::Label* label = new Gwen::Controls::Label( this ); - label->SetText( L"Arabic: \u0627\u0644\u0622\u0646 \u0644\u062D\u0636\u0648\u0631 \u0627\u0644\u0645\u0624\u062A\u0645\u0631 \u0627\u0644\u062F\u0648\u0644\u064A" ); + Gwen::Controls::Label* label = new Gwen::Controls::Label(this); + label->SetText(L"Arabic: \u0627\u0644\u0622\u0646 \u0644\u062D\u0636\u0648\u0631 \u0627\u0644\u0645\u0624\u062A\u0645\u0631 \u0627\u0644\u062F\u0648\u0644\u064A"); label->SizeToContents(); - label->SetPos( 10, 110 ); + label->SetPos(10, 110); } { - Gwen::Controls::Label* label = new Gwen::Controls::Label( this ); - label->SetText( L"Wow, Coloured Text" ); - label->SetTextColor( Gwen::Color( 0, 0, 255, 255 ) ); + Gwen::Controls::Label* label = new Gwen::Controls::Label(this); + label->SetText(L"Wow, Coloured Text"); + label->SetTextColor(Gwen::Color(0, 0, 255, 255)); label->SizeToContents(); - label->SetPos( 10, 130 ); + label->SetPos(10, 130); } { - Gwen::Controls::Label* label = new Gwen::Controls::Label( this ); - label->SetText( L"Coloured Text With Alpha" ); - label->SetTextColor( Gwen::Color( 0, 0, 255, 100 ) ); + Gwen::Controls::Label* label = new Gwen::Controls::Label(this); + label->SetText(L"Coloured Text With Alpha"); + label->SetTextColor(Gwen::Color(0, 0, 255, 100)); label->SizeToContents(); - label->SetPos( 10, 150 ); + label->SetPos(10, 150); } { @@ -75,25 +74,22 @@ class Label : public GUnit m_Font.facename = L"Comic Sans MS"; m_Font.size = 25; - Gwen::Controls::Label* label = new Gwen::Controls::Label( this ); - label->SetText( L"Custom Font (Comic Sans 25)" ); - label->SetFont( &m_Font ); + Gwen::Controls::Label* label = new Gwen::Controls::Label(this); + label->SetText(L"Custom Font (Comic Sans 25)"); + label->SetFont(&m_Font); label->SizeToContents(); - label->SetPos( 10, 170 ); + label->SetPos(10, 170); } { - Gwen::Controls::Label* label = new Gwen::Controls::Label( this ); - label->SetText( L"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." ); + Gwen::Controls::Label* label = new Gwen::Controls::Label(this); + label->SetText(L"Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\n\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); label->SizeToContents(); - label->SetBounds( 300, 10, 150, 500 ); + label->SetBounds(300, 10, 150, 500); } - } - Gwen::Font m_Font; + Gwen::Font m_Font; }; - - -DEFINE_UNIT_TEST( Label, L"Label" ); \ No newline at end of file +DEFINE_UNIT_TEST(Label, L"Label"); \ No newline at end of file diff --git a/test/GwenOpenGLTest/ListBox.cpp b/test/GwenOpenGLTest/ListBox.cpp index 7072f89b2..537d8c6f4 100644 --- a/test/GwenOpenGLTest/ListBox.cpp +++ b/test/GwenOpenGLTest/ListBox.cpp @@ -5,67 +5,63 @@ using namespace Gwen; class ListBox : public GUnit { - public: - - GWEN_CONTROL_INLINE( ListBox, GUnit ) +public: + GWEN_CONTROL_INLINE(ListBox, GUnit) { { - Gwen::Controls::ListBox* ctrl = new Gwen::Controls::ListBox( this ); - ctrl->SetBounds( 10, 10, 100, 200 ); + Gwen::Controls::ListBox* ctrl = new Gwen::Controls::ListBox(this); + ctrl->SetBounds(10, 10, 100, 200); - ctrl->AddItem( L"First" ); - ctrl->AddItem( L"Blue" ); - ctrl->AddItem( L"Yellow" ); - ctrl->AddItem( L"Orange" ); - ctrl->AddItem( L"Brown" ); - ctrl->AddItem( L"Green" ); - ctrl->AddItem( L"Dog" ); - ctrl->AddItem( L"Cat" ); - ctrl->AddItem( L"Shoes" ); - ctrl->AddItem( L"Chair" ); - ctrl->AddItem( L"Last" ); + ctrl->AddItem(L"First"); + ctrl->AddItem(L"Blue"); + ctrl->AddItem(L"Yellow"); + ctrl->AddItem(L"Orange"); + ctrl->AddItem(L"Brown"); + ctrl->AddItem(L"Green"); + ctrl->AddItem(L"Dog"); + ctrl->AddItem(L"Cat"); + ctrl->AddItem(L"Shoes"); + ctrl->AddItem(L"Chair"); + ctrl->AddItem(L"Last"); - ctrl->onRowSelected.Add( this, &ThisClass::RowSelected ); + ctrl->onRowSelected.Add(this, &ThisClass::RowSelected); } { - Gwen::Controls::ListBox* ctrl = new Gwen::Controls::ListBox( this ); - ctrl->SetBounds( 120, 10, 200, 200 ); - ctrl->SetColumnCount( 3 ); - ctrl->SetAllowMultiSelect( true ); - ctrl->onRowSelected.Add( this, &ThisClass::RowSelected ); - + Gwen::Controls::ListBox* ctrl = new Gwen::Controls::ListBox(this); + ctrl->SetBounds(120, 10, 200, 200); + ctrl->SetColumnCount(3); + ctrl->SetAllowMultiSelect(true); + ctrl->onRowSelected.Add(this, &ThisClass::RowSelected); { - Gwen::Controls::Layout::TableRow* pRow = ctrl->AddItem( L"Baked Beans" ); - pRow->SetCellText( 1, L"Heinz" ); - pRow->SetCellText( 2, L"£3.50" ); + Gwen::Controls::Layout::TableRow* pRow = ctrl->AddItem(L"Baked Beans"); + pRow->SetCellText(1, L"Heinz"); + pRow->SetCellText(2, L"£3.50"); } { - Gwen::Controls::Layout::TableRow* pRow = ctrl->AddItem( L"Bananas" ); - pRow->SetCellText( 1, L"Trees" ); - pRow->SetCellText( 2, L"£1.27" ); + Gwen::Controls::Layout::TableRow* pRow = ctrl->AddItem(L"Bananas"); + pRow->SetCellText(1, L"Trees"); + pRow->SetCellText(2, L"£1.27"); } { - Gwen::Controls::Layout::TableRow* pRow = ctrl->AddItem( L"Chicken" ); - pRow->SetCellText( 1, L"\u5355\u5143\u6D4B\u8BD5" ); - pRow->SetCellText( 2, L"£8.95" ); + Gwen::Controls::Layout::TableRow* pRow = ctrl->AddItem(L"Chicken"); + pRow->SetCellText(1, L"\u5355\u5143\u6D4B\u8BD5"); + pRow->SetCellText(2, L"£8.95"); } } } - void RowSelected( Gwen::Controls::Base* pControl ) + void RowSelected(Gwen::Controls::Base* pControl) { Gwen::Controls::ListBox* ctrl = (Gwen::Controls::ListBox*)pControl; - UnitPrint( Utility::Format( L"Listbox Item Selected: %s", ctrl->GetSelectedRow()->GetText( 0 ).c_str() ) ); + UnitPrint(Utility::Format(L"Listbox Item Selected: %s", ctrl->GetSelectedRow()->GetText(0).c_str())); } - Gwen::Font m_Font; + Gwen::Font m_Font; }; - - -DEFINE_UNIT_TEST( ListBox, L"ListBox" ); \ No newline at end of file +DEFINE_UNIT_TEST(ListBox, L"ListBox"); \ No newline at end of file diff --git a/test/GwenOpenGLTest/MenuStrip.cpp b/test/GwenOpenGLTest/MenuStrip.cpp index 14a8a1457..b1d29ab53 100644 --- a/test/GwenOpenGLTest/MenuStrip.cpp +++ b/test/GwenOpenGLTest/MenuStrip.cpp @@ -5,101 +5,96 @@ using namespace Gwen; class MenuStrip : public GUnit { - public: - - GWEN_CONTROL_INLINE( MenuStrip, GUnit ) +public: + GWEN_CONTROL_INLINE(MenuStrip, GUnit) { - Gwen::Controls::MenuStrip* menu = new Gwen::Controls::MenuStrip( this ); + Gwen::Controls::MenuStrip* menu = new Gwen::Controls::MenuStrip(this); { - Gwen::Controls::MenuItem* pRoot = menu->AddItem( L"File" ); - pRoot->GetMenu()->AddItem( L"New", L"test16.png", GWEN_MCALL( ThisClass::MenuItemSelect ) ); - pRoot->GetMenu()->AddItem( L"Load", L"test16.png", GWEN_MCALL( ThisClass::MenuItemSelect ) ); - pRoot->GetMenu()->AddItem( L"Save", GWEN_MCALL( ThisClass::MenuItemSelect ) ); - pRoot->GetMenu()->AddItem( L"Save As..", GWEN_MCALL( ThisClass::MenuItemSelect ) ); - pRoot->GetMenu()->AddItem( L"Quit", GWEN_MCALL( ThisClass::MenuItemSelect ) ); + Gwen::Controls::MenuItem* pRoot = menu->AddItem(L"File"); + pRoot->GetMenu()->AddItem(L"New", L"test16.png", GWEN_MCALL(ThisClass::MenuItemSelect)); + pRoot->GetMenu()->AddItem(L"Load", L"test16.png", GWEN_MCALL(ThisClass::MenuItemSelect)); + pRoot->GetMenu()->AddItem(L"Save", GWEN_MCALL(ThisClass::MenuItemSelect)); + pRoot->GetMenu()->AddItem(L"Save As..", GWEN_MCALL(ThisClass::MenuItemSelect)); + pRoot->GetMenu()->AddItem(L"Quit", GWEN_MCALL(ThisClass::MenuItemSelect)); } { - Gwen::Controls::MenuItem* pRoot = menu->AddItem( L"\u043F\u0438\u0440\u0430\u0442\u0441\u0442\u0432\u043E" ); - pRoot->GetMenu()->AddItem( L"\u5355\u5143\u6D4B\u8BD5", GWEN_MCALL( ThisClass::MenuItemSelect ) ); - pRoot->GetMenu()->AddItem( L"\u0111\u01A1n v\u1ECB th\u1EED nghi\u1EC7m", L"test16.png", GWEN_MCALL( ThisClass::MenuItemSelect ) ); + Gwen::Controls::MenuItem* pRoot = menu->AddItem(L"\u043F\u0438\u0440\u0430\u0442\u0441\u0442\u0432\u043E"); + pRoot->GetMenu()->AddItem(L"\u5355\u5143\u6D4B\u8BD5", GWEN_MCALL(ThisClass::MenuItemSelect)); + pRoot->GetMenu()->AddItem(L"\u0111\u01A1n v\u1ECB th\u1EED nghi\u1EC7m", L"test16.png", GWEN_MCALL(ThisClass::MenuItemSelect)); } { - Gwen::Controls::MenuItem* pRoot = menu->AddItem( L"Submenu" ); + Gwen::Controls::MenuItem* pRoot = menu->AddItem(L"Submenu"); - pRoot->GetMenu()->AddItem( "One" )->SetCheckable( true ); + pRoot->GetMenu()->AddItem("One")->SetCheckable(true); { - Gwen::Controls::MenuItem* pRootB = pRoot->GetMenu()->AddItem( "Two" ); - pRootB->GetMenu()->AddItem( "Two.One" ); - pRootB->GetMenu()->AddItem( "Two.Two" ); - pRootB->GetMenu()->AddItem( "Two.Three" ); - pRootB->GetMenu()->AddItem( "Two.Four" ); - pRootB->GetMenu()->AddItem( "Two.Five" ); - pRootB->GetMenu()->AddItem( "Two.Six" ); - pRootB->GetMenu()->AddItem( "Two.Seven" ); - pRootB->GetMenu()->AddItem( "Two.Eight" ); - pRootB->GetMenu()->AddItem( "Two.Nine", "test16.png" ); + Gwen::Controls::MenuItem* pRootB = pRoot->GetMenu()->AddItem("Two"); + pRootB->GetMenu()->AddItem("Two.One"); + pRootB->GetMenu()->AddItem("Two.Two"); + pRootB->GetMenu()->AddItem("Two.Three"); + pRootB->GetMenu()->AddItem("Two.Four"); + pRootB->GetMenu()->AddItem("Two.Five"); + pRootB->GetMenu()->AddItem("Two.Six"); + pRootB->GetMenu()->AddItem("Two.Seven"); + pRootB->GetMenu()->AddItem("Two.Eight"); + pRootB->GetMenu()->AddItem("Two.Nine", "test16.png"); } - pRoot->GetMenu()->AddItem( "Three" ); - pRoot->GetMenu()->AddItem( "Four" ); - pRoot->GetMenu()->AddItem( "Five" ); + pRoot->GetMenu()->AddItem("Three"); + pRoot->GetMenu()->AddItem("Four"); + pRoot->GetMenu()->AddItem("Five"); { - Gwen::Controls::MenuItem* pRootB = pRoot->GetMenu()->AddItem( "Six" ); - pRootB->GetMenu()->AddItem( "Six.One" ); - pRootB->GetMenu()->AddItem( "Six.Two" ); - pRootB->GetMenu()->AddItem( "Six.Three" ); - pRootB->GetMenu()->AddItem( "Six.Four" ); - pRootB->GetMenu()->AddItem( "Six.Five", "test16.png" ); + Gwen::Controls::MenuItem* pRootB = pRoot->GetMenu()->AddItem("Six"); + pRootB->GetMenu()->AddItem("Six.One"); + pRootB->GetMenu()->AddItem("Six.Two"); + pRootB->GetMenu()->AddItem("Six.Three"); + pRootB->GetMenu()->AddItem("Six.Four"); + pRootB->GetMenu()->AddItem("Six.Five", "test16.png"); { - Gwen::Controls::MenuItem* pRootC = pRootB->GetMenu()->AddItem( "Six.Six" ); - pRootC->GetMenu()->AddItem( "Sheep" ); - pRootC->GetMenu()->AddItem( "Goose" ); + Gwen::Controls::MenuItem* pRootC = pRootB->GetMenu()->AddItem("Six.Six"); + pRootC->GetMenu()->AddItem("Sheep"); + pRootC->GetMenu()->AddItem("Goose"); { - Gwen::Controls::MenuItem* pRootD = pRootC->GetMenu()->AddItem( "Camel" ); - pRootD->GetMenu()->AddItem( "Eyes" ); - pRootD->GetMenu()->AddItem( "Nose" ); + Gwen::Controls::MenuItem* pRootD = pRootC->GetMenu()->AddItem("Camel"); + pRootD->GetMenu()->AddItem("Eyes"); + pRootD->GetMenu()->AddItem("Nose"); { - Gwen::Controls::MenuItem* pRootE = pRootD->GetMenu()->AddItem( "Hair" ); - pRootE->GetMenu()->AddItem( "Blonde" ); - pRootE->GetMenu()->AddItem( "Black" ); + Gwen::Controls::MenuItem* pRootE = pRootD->GetMenu()->AddItem("Hair"); + pRootE->GetMenu()->AddItem("Blonde"); + pRootE->GetMenu()->AddItem("Black"); { - Gwen::Controls::MenuItem* pRootF = pRootE->GetMenu()->AddItem( "Red" ); - pRootF->GetMenu()->AddItem( "Light" ); - pRootF->GetMenu()->AddItem( "Medium" ); - pRootF->GetMenu()->AddItem( "Dark" ); + Gwen::Controls::MenuItem* pRootF = pRootE->GetMenu()->AddItem("Red"); + pRootF->GetMenu()->AddItem("Light"); + pRootF->GetMenu()->AddItem("Medium"); + pRootF->GetMenu()->AddItem("Dark"); } - pRootE->GetMenu()->AddItem( "Brown" ); + pRootE->GetMenu()->AddItem("Brown"); } - pRootD->GetMenu()->AddItem( "Ears" ); + pRootD->GetMenu()->AddItem("Ears"); } - pRootC->GetMenu()->AddItem( "Duck" ); + pRootC->GetMenu()->AddItem("Duck"); } - pRootB->GetMenu()->AddItem( "Six.Seven" ); - pRootB->GetMenu()->AddItem( "Six.Eight" ); - pRootB->GetMenu()->AddItem( "Six.Nine" ); + pRootB->GetMenu()->AddItem("Six.Seven"); + pRootB->GetMenu()->AddItem("Six.Eight"); + pRootB->GetMenu()->AddItem("Six.Nine"); } - pRoot->GetMenu()->AddItem( "Seven" ); - + pRoot->GetMenu()->AddItem("Seven"); } } - void MenuItemSelect( Base* pControl ) + void MenuItemSelect(Base* pControl) { Gwen::Controls::MenuItem* pMenuItem = (Gwen::Controls::MenuItem*)pControl; - UnitPrint( Utility::Format( L"Menu Selected: %s", pMenuItem->GetText().c_str() ) ); + UnitPrint(Utility::Format(L"Menu Selected: %s", pMenuItem->GetText().c_str())); } - }; - - -DEFINE_UNIT_TEST( MenuStrip, L"MenuStrip" ); \ No newline at end of file +DEFINE_UNIT_TEST(MenuStrip, L"MenuStrip"); \ No newline at end of file diff --git a/test/GwenOpenGLTest/Numeric.cpp b/test/GwenOpenGLTest/Numeric.cpp index f7a1c85eb..36ca9693f 100644 --- a/test/GwenOpenGLTest/Numeric.cpp +++ b/test/GwenOpenGLTest/Numeric.cpp @@ -5,27 +5,22 @@ using namespace Gwen; class Numeric : public GUnit { - public: - - GWEN_CONTROL_INLINE( Numeric, GUnit ) +public: + GWEN_CONTROL_INLINE(Numeric, GUnit) { - - Controls::NumericUpDown* pCtrl = new Controls::NumericUpDown( this ); - pCtrl->SetBounds( 10, 10, 50, 20 ); - pCtrl->SetValue( 50 ); - pCtrl->SetMax( 1000 ); - pCtrl->SetMin( -1000 ); + Controls::NumericUpDown* pCtrl = new Controls::NumericUpDown(this); + pCtrl->SetBounds(10, 10, 50, 20); + pCtrl->SetValue(50); + pCtrl->SetMax(1000); + pCtrl->SetMin(-1000); // pCtrl->onPress.Add( this, &ThisClass::onButtonA ); } - void onButtonA( Controls::Base* pControl ) + void onButtonA(Controls::Base* pControl) { - // UnitPrint( L"Button Pressed (using 'OnPress' event)" ); + // UnitPrint( L"Button Pressed (using 'OnPress' event)" ); } - }; - - -DEFINE_UNIT_TEST( Numeric, L"Numeric" ); \ No newline at end of file +DEFINE_UNIT_TEST(Numeric, L"Numeric"); \ No newline at end of file diff --git a/test/GwenOpenGLTest/OpenGLSample.cpp b/test/GwenOpenGLTest/OpenGLSample.cpp index 1a609a584..50048e0f8 100644 --- a/test/GwenOpenGLTest/OpenGLSample.cpp +++ b/test/GwenOpenGLTest/OpenGLSample.cpp @@ -23,9 +23,9 @@ extern unsigned char OpenSansData[]; #else //let's cross the fingers it is Linux/X11 #include "OpenGLWindow/X11OpenGLWindow.h" -#endif //_WIN32 -#endif//__APPLE__ -#endif //B3_USE_GLFW +#endif //_WIN32 +#endif //__APPLE__ +#endif //B3_USE_GLFW #include "OpenGLWindow/opengl_fontstashcallbacks.h" #ifndef NO_OPENGL3 #include "OpenGLWindow/GwenOpenGL3CoreRenderer.h" @@ -33,24 +33,24 @@ extern unsigned char OpenSansData[]; #endif #include -Gwen::Controls::Canvas* pCanvas = NULL; +Gwen::Controls::Canvas* pCanvas = NULL; Gwen::Skin::Simple skin; -void MyMouseMoveCallback( float x, float y) +void MyMouseMoveCallback(float x, float y) { //b3DefaultMouseCallback(button,state,x,y); - static int m_lastmousepos[2] = {0,0}; + static int m_lastmousepos[2] = {0, 0}; static bool isInitialized = false; if (pCanvas) { if (!isInitialized) { isInitialized = true; - m_lastmousepos[0] = x+1; - m_lastmousepos[1] = y+1; + m_lastmousepos[0] = x + 1; + m_lastmousepos[1] = y + 1; } - bool handled = pCanvas->InputMouseMoved(x,y,m_lastmousepos[0],m_lastmousepos[1]); + bool handled = pCanvas->InputMouseMoved(x, y, m_lastmousepos[0], m_lastmousepos[1]); } } @@ -60,11 +60,11 @@ void MyMouseButtonCallback(int button, int state, float x, float y) if (pCanvas) { - bool handled = pCanvas->InputMouseMoved(x,y,x, y); + bool handled = pCanvas->InputMouseMoved(x, y, x, y); - if (button>=0) + if (button >= 0) { - handled = pCanvas->InputMouseButton(button,state); + handled = pCanvas->InputMouseButton(button, state); if (handled) { if (!state) @@ -74,13 +74,13 @@ void MyMouseButtonCallback(int button, int state, float x, float y) } } -int sWidth = 800;//1050; -int sHeight = 600;//768; -GLPrimitiveRenderer* primRenderer=0; +int sWidth = 800; //1050; +int sHeight = 600; //768; +GLPrimitiveRenderer* primRenderer = 0; //GwenOpenGL3CoreRenderer* gwenRenderer=0; -Gwen::Renderer::Base* gwenRenderer =0; +Gwen::Renderer::Base* gwenRenderer = 0; -static void MyResizeCallback( float width, float height) +static void MyResizeCallback(float width, float height) { sWidth = width; sHeight = height; @@ -88,33 +88,31 @@ static void MyResizeCallback( float width, float height) #ifndef NO_OPENGL3 if (primRenderer) { - primRenderer->setScreenSize(width,height); + primRenderer->setScreenSize(width, height); } #endif if (gwenRenderer) { - gwenRenderer->Resize(width,height); + gwenRenderer->Resize(width, height); } if (pCanvas) { - pCanvas->SetSize( sWidth, sHeight); + pCanvas->SetSize(sWidth, sHeight); } - } - - int droidRegular;//, droidItalic, droidBold, droidJapanese, dejavu; +int droidRegular; //, droidItalic, droidBold, droidJapanese, dejavu; #ifndef NO_OPENGL3 sth_stash* initFont(GLPrimitiveRenderer* primRenderer) { GLint err; - struct sth_stash* stash = 0; - OpenGL2RenderCallbacks* renderCallbacks = new OpenGL2RenderCallbacks(primRenderer); + struct sth_stash* stash = 0; + OpenGL2RenderCallbacks* renderCallbacks = new OpenGL2RenderCallbacks(primRenderer); - stash = sth_create(512,512,renderCallbacks);//256,256);//,1024);//512,512); - err = glGetError(); - assert(err==GL_NO_ERROR); + stash = sth_create(512, 512, renderCallbacks); //256,256);//,1024);//512,512); + err = glGetError(); + assert(err == GL_NO_ERROR); if (!stash) { @@ -122,97 +120,92 @@ sth_stash* initFont(GLPrimitiveRenderer* primRenderer) return 0; } - #ifdef LOAD_FONTS_FROM_FILE - int datasize; + int datasize; unsigned char* data; - float sx,sy,dx,dy,lh; + float sx, sy, dx, dy, lh; GLuint texture; + const char* fontPaths[] = { + "./", + "../../bin/", + "../bin/", + "bin/"}; - - const char* fontPaths[]={ - "./", - "../../bin/", - "../bin/", - "bin/" - }; - - int numPaths=sizeof(fontPaths)/sizeof(char*); + int numPaths = sizeof(fontPaths) / sizeof(char*); // Load the first truetype font from memory (just because we can). FILE* fp = 0; - const char* fontPath ="./"; + const char* fontPath = "./"; char fullFontFileName[1024]; - for (int i=0;iInputKey(key,value==1); - int gwenKey = -1; switch (key) { - case B3G_LEFT_ARROW: + case B3G_LEFT_ARROW: { gwenKey = Gwen::Key::Left; break; } - case B3G_RIGHT_ARROW: + case B3G_RIGHT_ARROW: { gwenKey = Gwen::Key::Right; break; } - case B3G_UP_ARROW: + case B3G_UP_ARROW: { gwenKey = Gwen::Key::Up; break; } - case B3G_DOWN_ARROW: + case B3G_DOWN_ARROW: { gwenKey = Gwen::Key::Down; break; } - case B3G_BACKSPACE: + case B3G_BACKSPACE: { gwenKey = Gwen::Key::Backspace; break; } - case B3G_DELETE: + case B3G_DELETE: { gwenKey = Gwen::Key::Delete; break; } - case B3G_HOME: + case B3G_HOME: { gwenKey = Gwen::Key::Home; break; } - case B3G_END: + case B3G_END: { gwenKey = Gwen::Key::End; break; } - case B3G_SHIFT: + case B3G_SHIFT: { gwenKey = Gwen::Key::Shift; break; } - case B3G_CONTROL: + case B3G_CONTROL: { gwenKey = Gwen::Key::Control; break; } - - - default: + default: { - } }; - if (gwenKey>=0) + if (gwenKey >= 0) { - pCanvas->InputKey(gwenKey,value==1); - } else + pCanvas->InputKey(gwenKey, value == 1); + } + else { - if (key<256 && value) + if (key < 256 && value) { - Gwen::UnicodeChar c = ( Gwen::UnicodeChar ) key; + Gwen::UnicodeChar c = (Gwen::UnicodeChar)key; pCanvas->InputCharacter(c); } } @@ -312,14 +302,13 @@ extern int avoidUpdate; int main() { - b3gDefaultOpenGLWindow* window = new b3gDefaultOpenGLWindow(); window->setKeyboardCallback(keyCallback); b3gWindowConstructionInfo wci; #ifndef NO_OPENGL3 wci.m_openglVersion = 3; #else - wci.m_openglVersion = 2; + wci.m_openglVersion = 2; #endif wci.m_width = sWidth; wci.m_height = sHeight; @@ -327,105 +316,94 @@ int main() window->createWindow(wci); window->setResizeCallback(MyResizeCallback); - - int majorGlVersion, minorGlVersion; + int majorGlVersion, minorGlVersion; - if (!(sscanf((const char*)glGetString(GL_VERSION), "%d.%d", &majorGlVersion, &minorGlVersion)==2)) - { - printf("Exit: Error cannot extract OpenGL version from GL_VERSION string\n"); - exit(0); - } + if (!(sscanf((const char*)glGetString(GL_VERSION), "%d.%d", &majorGlVersion, &minorGlVersion) == 2)) + { + printf("Exit: Error cannot extract OpenGL version from GL_VERSION string\n"); + exit(0); + } char title[1024]; - if (wci.m_openglVersion>2) + if (wci.m_openglVersion > 2) { - sprintf(title,"Gwen with OpenGL %d.%d\n",majorGlVersion,minorGlVersion); - } else + sprintf(title, "Gwen with OpenGL %d.%d\n", majorGlVersion, minorGlVersion); + } + else { - sprintf(title,"Gwen with OpenGL %d\n",wci.m_openglVersion); + sprintf(title, "Gwen with OpenGL %d\n", wci.m_openglVersion); } window->setWindowTitle(title); float retinaScale = window->getRetinaScale(); #ifndef NO_OPENGL3 - if (majorGlVersion>=3 && wci.m_openglVersion>=3) - { -#ifndef B3_USE_GLFW + if (majorGlVersion >= 3 && wci.m_openglVersion >= 3) + { +#ifndef B3_USE_GLFW #ifndef __APPLE__ #ifndef _WIN32 - //we need glewExperimental on Linux -#endif // _WIN32 + //we need glewExperimental on Linux +#endif // _WIN32 gladLoaderLoadGL(); #endif -#endif //B3_USE_GLFW - //we ned to call glGetError twice, because of some Ubuntu/Intel/OpenGL issue +#endif //B3_USE_GLFW \ + //we ned to call glGetError twice, because of some Ubuntu/Intel/OpenGL issue - GLuint err = glGetError(); - err = glGetError(); - assert(err==GL_NO_ERROR); + GLuint err = glGetError(); + err = glGetError(); + assert(err == GL_NO_ERROR); + primRenderer = new GLPrimitiveRenderer(sWidth, sHeight); - primRenderer = new GLPrimitiveRenderer(sWidth,sHeight); + sth_stash* font = initFont(primRenderer); - sth_stash* font = initFont(primRenderer ); - - - gwenRenderer = new GwenOpenGL3CoreRenderer(primRenderer,font,sWidth,sHeight,retinaScale); - - } else + gwenRenderer = new GwenOpenGL3CoreRenderer(primRenderer, font, sWidth, sHeight, retinaScale); + } + else #endif - { - //OpenGL 2.x - gwenRenderer = new Gwen::Renderer::OpenGL_DebugFont(retinaScale); - - - skin.SetRender( gwenRenderer ); - - - - glClearColor(1,0,0,1); - - } + { + //OpenGL 2.x + gwenRenderer = new Gwen::Renderer::OpenGL_DebugFont(retinaScale); + skin.SetRender(gwenRenderer); + glClearColor(1, 0, 0, 1); + } // // Create a GWEN OpenGL Renderer // -// Gwen::Renderer::OpenGL_DebugFont * pRenderer = new Gwen::Renderer::OpenGL_DebugFont(); + // Gwen::Renderer::OpenGL_DebugFont * pRenderer = new Gwen::Renderer::OpenGL_DebugFont(); // // Create a GWEN skin // - #ifdef USE_TEXTURED_SKIN Gwen::Skin::TexturedBase skin; - skin.SetRender( pRenderer ); + skin.SetRender(pRenderer); skin.Init("DefaultSkin.png"); #else - skin.SetRender( gwenRenderer ); + skin.SetRender(gwenRenderer); #endif - // // Create a Canvas (it's root, on which all other GWEN panels are created) // - pCanvas = new Gwen::Controls::Canvas( &skin ); - pCanvas->SetSize( sWidth, sHeight); - pCanvas->SetDrawBackground( true ); - pCanvas->SetBackgroundColor( Gwen::Color( 150, 170, 170, 255 ) ); + pCanvas = new Gwen::Controls::Canvas(&skin); + pCanvas->SetSize(sWidth, sHeight); + pCanvas->SetDrawBackground(true); + pCanvas->SetBackgroundColor(Gwen::Color(150, 170, 170, 255)); window->setMouseButtonCallback(MyMouseButtonCallback); window->setMouseMoveCallback(MyMouseMoveCallback); - // // Create our unittest control (which is a Window with controls in it) // - UnitTest* pUnit = new UnitTest( pCanvas ); - pUnit->SetPos( 10, 10 ); + UnitTest* pUnit = new UnitTest(pCanvas); + pUnit->SetPos(10, 10); // // Create a Windows Control helper @@ -437,110 +415,101 @@ int main() // // Begin the main game loop // -// MSG msg; - while( !window->requestedExit() ) + // MSG msg; + while (!window->requestedExit()) { - if (majorGlVersion<3 || wci.m_openglVersion<3) - { - saveOpenGLState(sWidth,sHeight); - } + if (majorGlVersion < 3 || wci.m_openglVersion < 3) + { + saveOpenGLState(sWidth, sHeight); + } // Skip out if the window is closed //if ( !IsWindowVisible( g_pHWND ) ) - //break; + //break; // If we have a message from windows.. - // if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) + // if ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) { - // .. give it to the input handler to process - // GwenInput.ProcessMessage( msg ); + // GwenInput.ProcessMessage( msg ); // if it's QUIT then quit.. - // if ( msg.message == WM_QUIT ) + // if ( msg.message == WM_QUIT ) // break; // Handle the regular window stuff.. - // TranslateMessage(&msg); - // DispatchMessage(&msg); - + // TranslateMessage(&msg); + // DispatchMessage(&msg); } window->startRendering(); // Main OpenGL Render Loop { - glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glEnable(GL_BLEND); - GLint err = glGetError(); - assert(err==GL_NO_ERROR); + glEnable(GL_BLEND); + GLint err = glGetError(); + assert(err == GL_NO_ERROR); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - err = glGetError(); - assert(err==GL_NO_ERROR); + err = glGetError(); + assert(err == GL_NO_ERROR); - err = glGetError(); - assert(err==GL_NO_ERROR); + err = glGetError(); + assert(err == GL_NO_ERROR); - glDisable(GL_DEPTH_TEST); - err = glGetError(); - assert(err==GL_NO_ERROR); + glDisable(GL_DEPTH_TEST); + err = glGetError(); + assert(err == GL_NO_ERROR); - //glColor4ub(255,0,0,255); + //glColor4ub(255,0,0,255); - err = glGetError(); - assert(err==GL_NO_ERROR); + err = glGetError(); + assert(err == GL_NO_ERROR); - - err = glGetError(); - assert(err==GL_NO_ERROR); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); + err = glGetError(); + assert(err == GL_NO_ERROR); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // saveOpenGLState(width,height);//m_glutScreenWidth,m_glutScreenHeight); - err = glGetError(); - assert(err==GL_NO_ERROR); + err = glGetError(); + assert(err == GL_NO_ERROR); + err = glGetError(); + assert(err == GL_NO_ERROR); - err = glGetError(); - assert(err==GL_NO_ERROR); + glDisable(GL_CULL_FACE); - glDisable(GL_CULL_FACE); + glDisable(GL_DEPTH_TEST); + err = glGetError(); + assert(err == GL_NO_ERROR); - glDisable(GL_DEPTH_TEST); - err = glGetError(); - assert(err==GL_NO_ERROR); - - err = glGetError(); - assert(err==GL_NO_ERROR); - - glEnable(GL_BLEND); - - - err = glGetError(); - assert(err==GL_NO_ERROR); + err = glGetError(); + assert(err == GL_NO_ERROR); + glEnable(GL_BLEND); + err = glGetError(); + assert(err == GL_NO_ERROR); pCanvas->RenderCanvas(); - if (avoidUpdate<=0) + if (avoidUpdate <= 0) avoidUpdate++; - // SwapBuffers( GetDC( g_pHWND ) ); + // SwapBuffers( GetDC( g_pHWND ) ); } window->endRendering(); - if (majorGlVersion<3 || wci.m_openglVersion<3) - { - restoreOpenGLState(); - } + if (majorGlVersion < 3 || wci.m_openglVersion < 3) + { + restoreOpenGLState(); + } } window->closeWindow(); delete window; - - } diff --git a/test/GwenOpenGLTest/PanelListPanel.cpp b/test/GwenOpenGLTest/PanelListPanel.cpp index fcf1ae316..8955ff089 100644 --- a/test/GwenOpenGLTest/PanelListPanel.cpp +++ b/test/GwenOpenGLTest/PanelListPanel.cpp @@ -7,48 +7,46 @@ using namespace Gwen; class PanelListPanel : public GUnit { - public: - - GWEN_CONTROL_INLINE( PanelListPanel, GUnit ) +public: + GWEN_CONTROL_INLINE(PanelListPanel, GUnit) { - m_PLP = new Gwen::Controls::PanelListPanel( this ); - m_PLP->Dock( Pos::Fill ); - m_PLP->SetPadding( Gwen::Padding( 10, 10 )); + m_PLP = new Gwen::Controls::PanelListPanel(this); + m_PLP->Dock(Pos::Fill); + m_PLP->SetPadding(Gwen::Padding(10, 10)); m_PLP->SetVertical(); - m_PLP->SetSizeToChildren( false ); + m_PLP->SetSizeToChildren(false); - for ( int i = 0; i < 16; i++) + for (int i = 0; i < 16; i++) { - Gwen::String testName = "TEST" + Utility::ToString( i ); - Gwen::Controls::Button* testButton = new Gwen::Controls::Button( m_PLP ); - testButton->SetText( testName ); + Gwen::String testName = "TEST" + Utility::ToString(i); + Gwen::Controls::Button* testButton = new Gwen::Controls::Button(m_PLP); + testButton->SetText(testName); } - Gwen::Controls::StatusBar* pStatus = new Gwen::Controls::StatusBar( this ); - pStatus->Dock( Pos::Bottom ); + Gwen::Controls::StatusBar* pStatus = new Gwen::Controls::StatusBar(this); + pStatus->Dock(Pos::Bottom); { - Gwen::Controls::Button* pButton = new Gwen::Controls::Button( pStatus ); - pButton->SetText( "Horizontal" ); - pButton->onPress.Add( this, &PanelListPanel::GoHorizontal ); - pStatus->AddControl( pButton, false ); + Gwen::Controls::Button* pButton = new Gwen::Controls::Button(pStatus); + pButton->SetText("Horizontal"); + pButton->onPress.Add(this, &PanelListPanel::GoHorizontal); + pStatus->AddControl(pButton, false); } { - Gwen::Controls::Button* pButton = new Gwen::Controls::Button( pStatus ); - pButton->SetText( "Vertical" ); - pButton->onPress.Add( this, &PanelListPanel::GoVertical ); - pStatus->AddControl( pButton, true ); + Gwen::Controls::Button* pButton = new Gwen::Controls::Button(pStatus); + pButton->SetText("Vertical"); + pButton->onPress.Add(this, &PanelListPanel::GoVertical); + pStatus->AddControl(pButton, true); } } - - void GoVertical( Gwen::Controls::Base* pFromPanel ) + void GoVertical(Gwen::Controls::Base* pFromPanel) { m_PLP->SetVertical(); } - void GoHorizontal( Gwen::Controls::Base* pFromPanel ) + void GoHorizontal(Gwen::Controls::Base* pFromPanel) { m_PLP->SetHorizontal(); } @@ -56,6 +54,4 @@ class PanelListPanel : public GUnit Gwen::Controls::PanelListPanel* m_PLP; }; - - -DEFINE_UNIT_TEST( PanelListPanel, L"PanelListPanel" ); \ No newline at end of file +DEFINE_UNIT_TEST(PanelListPanel, L"PanelListPanel"); \ No newline at end of file diff --git a/test/GwenOpenGLTest/ProgressBar.cpp b/test/GwenOpenGLTest/ProgressBar.cpp index ed72c3e19..b7f016293 100644 --- a/test/GwenOpenGLTest/ProgressBar.cpp +++ b/test/GwenOpenGLTest/ProgressBar.cpp @@ -6,88 +6,82 @@ using namespace Gwen; class ProgressBar : public GUnit { - public: - - GWEN_CONTROL_INLINE( ProgressBar, GUnit ) +public: + GWEN_CONTROL_INLINE(ProgressBar, GUnit) { - { - Gwen::Controls::ProgressBar* pb = new Gwen::Controls::ProgressBar( this ); - pb->SetBounds( Gwen::Rect( 110, 20, 200, 20 ) ); - pb->SetValue( 0.27f ); + Gwen::Controls::ProgressBar* pb = new Gwen::Controls::ProgressBar(this); + pb->SetBounds(Gwen::Rect(110, 20, 200, 20)); + pb->SetValue(0.27f); } { - Gwen::Controls::ProgressBar* pb = new Gwen::Controls::ProgressBar( this ); - pb->SetBounds( Gwen::Rect( 110, 50, 200, 20 ) ); - pb->SetValue( 0.66f ); - pb->SetAlignment( Pos::Right | Pos::CenterV ); + Gwen::Controls::ProgressBar* pb = new Gwen::Controls::ProgressBar(this); + pb->SetBounds(Gwen::Rect(110, 50, 200, 20)); + pb->SetValue(0.66f); + pb->SetAlignment(Pos::Right | Pos::CenterV); } { - Gwen::Controls::ProgressBar* pb = new Gwen::Controls::ProgressBar( this ); - pb->SetBounds( Gwen::Rect( 110, 80, 200, 20 ) ); - pb->SetValue( 0.88f ); - pb->SetAlignment( Pos::Left | Pos::CenterV ); + Gwen::Controls::ProgressBar* pb = new Gwen::Controls::ProgressBar(this); + pb->SetBounds(Gwen::Rect(110, 80, 200, 20)); + pb->SetValue(0.88f); + pb->SetAlignment(Pos::Left | Pos::CenterV); } { - Gwen::Controls::ProgressBar* pb = new Gwen::Controls::ProgressBar( this ); - pb->SetBounds( Gwen::Rect( 110, 110, 200, 20 ) ); - pb->SetAutoLabel( false ); - pb->SetValue( 0.20f ); - pb->SetAlignment( Pos::Right | Pos::CenterV ); - pb->SetText( L"40,245 MB" ); + Gwen::Controls::ProgressBar* pb = new Gwen::Controls::ProgressBar(this); + pb->SetBounds(Gwen::Rect(110, 110, 200, 20)); + pb->SetAutoLabel(false); + pb->SetValue(0.20f); + pb->SetAlignment(Pos::Right | Pos::CenterV); + pb->SetText(L"40,245 MB"); } { - Gwen::Controls::ProgressBar* pb = new Gwen::Controls::ProgressBar( this ); - pb->SetBounds( Gwen::Rect( 110, 140, 200, 20 ) ); - pb->SetAutoLabel( false ); - pb->SetValue( 1.00f ); + Gwen::Controls::ProgressBar* pb = new Gwen::Controls::ProgressBar(this); + pb->SetBounds(Gwen::Rect(110, 140, 200, 20)); + pb->SetAutoLabel(false); + pb->SetValue(1.00f); } { - Gwen::Controls::ProgressBar* pb = new Gwen::Controls::ProgressBar( this ); - pb->SetBounds( Gwen::Rect( 110, 170, 200, 20 ) ); - pb->SetAutoLabel( false ); - pb->SetValue( 0.00f ); + Gwen::Controls::ProgressBar* pb = new Gwen::Controls::ProgressBar(this); + pb->SetBounds(Gwen::Rect(110, 170, 200, 20)); + pb->SetAutoLabel(false); + pb->SetValue(0.00f); } { - Gwen::Controls::ProgressBar* pb = new Gwen::Controls::ProgressBar( this ); - pb->SetBounds( Gwen::Rect( 110, 200, 200, 20 ) ); - pb->SetAutoLabel( false ); - pb->SetValue( 0.50f ); + Gwen::Controls::ProgressBar* pb = new Gwen::Controls::ProgressBar(this); + pb->SetBounds(Gwen::Rect(110, 200, 200, 20)); + pb->SetAutoLabel(false); + pb->SetValue(0.50f); } { - Gwen::Controls::ProgressBar* pb = new Gwen::Controls::ProgressBar( this ); - pb->SetBounds( Gwen::Rect( 20, 20, 25, 200 ) ); + Gwen::Controls::ProgressBar* pb = new Gwen::Controls::ProgressBar(this); + pb->SetBounds(Gwen::Rect(20, 20, 25, 200)); pb->SetVertical(); - pb->SetValue( 0.25f ); - pb->SetAlignment( Pos::Top | Pos::CenterH ); + pb->SetValue(0.25f); + pb->SetAlignment(Pos::Top | Pos::CenterH); } { - Gwen::Controls::ProgressBar* pb = new Gwen::Controls::ProgressBar( this ); - pb->SetBounds( Gwen::Rect( 50, 20, 25, 200 ) ); + Gwen::Controls::ProgressBar* pb = new Gwen::Controls::ProgressBar(this); + pb->SetBounds(Gwen::Rect(50, 20, 25, 200)); pb->SetVertical(); - pb->SetValue( 0.40f ); + pb->SetValue(0.40f); } { - Gwen::Controls::ProgressBar* pb = new Gwen::Controls::ProgressBar( this ); - pb->SetBounds( Gwen::Rect( 80, 20, 25, 200 ) ); + Gwen::Controls::ProgressBar* pb = new Gwen::Controls::ProgressBar(this); + pb->SetBounds(Gwen::Rect(80, 20, 25, 200)); pb->SetVertical(); - pb->SetAlignment( Pos::Bottom | Pos::CenterH ); - pb->SetValue( 0.65f ); + pb->SetAlignment(Pos::Bottom | Pos::CenterH); + pb->SetValue(0.65f); } - } - }; - - -DEFINE_UNIT_TEST( ProgressBar, L"ProgressBar" ); \ No newline at end of file +DEFINE_UNIT_TEST(ProgressBar, L"ProgressBar"); \ No newline at end of file diff --git a/test/GwenOpenGLTest/Properties.cpp b/test/GwenOpenGLTest/Properties.cpp index c909db388..45e0ca300 100644 --- a/test/GwenOpenGLTest/Properties.cpp +++ b/test/GwenOpenGLTest/Properties.cpp @@ -6,58 +6,52 @@ using namespace Gwen; class Properties2 : public GUnit { - public: - - GWEN_CONTROL_INLINE( Properties2, GUnit ) +public: + GWEN_CONTROL_INLINE(Properties2, GUnit) { { - Gwen::Controls::Properties* props = new Gwen::Controls::Properties( this ); + Gwen::Controls::Properties* props = new Gwen::Controls::Properties(this); - props->SetBounds( 10, 10, 150, 300 ); + props->SetBounds(10, 10, 150, 300); { { - Gwen::Controls::PropertyRow* pRow = props->Add( L"First Name" ); - pRow->onChange.Add( this, &Properties2::OnFirstNameChanged ); + Gwen::Controls::PropertyRow* pRow = props->Add(L"First Name"); + pRow->onChange.Add(this, &Properties2::OnFirstNameChanged); } - props->Add( L"Middle Name" ); - props->Add( L"Last Name" ); + props->Add(L"Middle Name"); + props->Add(L"Last Name"); } - } { - Gwen::Controls::PropertyTree* ptree = new Gwen::Controls::PropertyTree( this ); - ptree->SetBounds( 200, 10, 200, 200 ); + Gwen::Controls::PropertyTree* ptree = new Gwen::Controls::PropertyTree(this); + ptree->SetBounds(200, 10, 200, 200); { - Gwen::Controls::Properties* props = ptree->Add( L"Item One" ); - props->Add( L"Middle Name" ); - props->Add( L"Last Name" ); - props->Add( L"Four" ); + Gwen::Controls::Properties* props = ptree->Add(L"Item One"); + props->Add(L"Middle Name"); + props->Add(L"Last Name"); + props->Add(L"Four"); } { - Gwen::Controls::Properties* props = ptree->Add( L"Item Two" ); - props->Add( L"More Items" ); - props->Add( L"To Fill" ); - props->Add( L"Out Here" ); + Gwen::Controls::Properties* props = ptree->Add(L"Item Two"); + props->Add(L"More Items"); + props->Add(L"To Fill"); + props->Add(L"Out Here"); } ptree->ExpandAll(); - } } - void OnFirstNameChanged( Controls::Base* pControl ) + void OnFirstNameChanged(Controls::Base* pControl) { - Gwen::Controls::PropertyRow* pRow = (Gwen::Controls::PropertyRow*) pControl; - UnitPrint( Utility::Format( L"First Name Changed: %s", pRow->GetProperty()->GetPropertyValue().c_str() ) ); + Gwen::Controls::PropertyRow* pRow = (Gwen::Controls::PropertyRow*)pControl; + UnitPrint(Utility::Format(L"First Name Changed: %s", pRow->GetProperty()->GetPropertyValue().c_str())); } - }; - - -DEFINE_UNIT_TEST( Properties2, L"Properties" ); \ No newline at end of file +DEFINE_UNIT_TEST(Properties2, L"Properties"); \ No newline at end of file diff --git a/test/GwenOpenGLTest/RadioButton.cpp b/test/GwenOpenGLTest/RadioButton.cpp index 5d4948dd0..5f515c8a6 100644 --- a/test/GwenOpenGLTest/RadioButton.cpp +++ b/test/GwenOpenGLTest/RadioButton.cpp @@ -5,34 +5,28 @@ using namespace Gwen; class RadioButton2 : public GUnit { - public: - - GWEN_CONTROL_INLINE( RadioButton2, GUnit ) +public: + GWEN_CONTROL_INLINE(RadioButton2, GUnit) { + Gwen::Controls::RadioButtonController* rc = new Gwen::Controls::RadioButtonController(this); - Gwen::Controls::RadioButtonController* rc = new Gwen::Controls::RadioButtonController( this ); - - rc->AddOption( "Option 1" ); - rc->AddOption( "Option 2" ); - rc->AddOption( "Option 3" ); - rc->AddOption( L"\u0627\u0644\u0622\u0646 \u0644\u062D\u0636\u0648\u0631" ); - - rc->SetBounds( 30, 30, 200, 200 ); - - rc->onSelectionChange.Add( this, &RadioButton2::OnChange ); + rc->AddOption("Option 1"); + rc->AddOption("Option 2"); + rc->AddOption("Option 3"); + rc->AddOption(L"\u0627\u0644\u0622\u0646 \u0644\u062D\u0636\u0648\u0631"); + rc->SetBounds(30, 30, 200, 200); + rc->onSelectionChange.Add(this, &RadioButton2::OnChange); } - void OnChange( Controls::Base* pControl ) + void OnChange(Controls::Base* pControl) { - Gwen::Controls::RadioButtonController* rc = (Gwen::Controls::RadioButtonController*) pControl; + Gwen::Controls::RadioButtonController* rc = (Gwen::Controls::RadioButtonController*)pControl; Gwen::Controls::LabeledRadioButton* pSelected = rc->GetSelected(); - UnitPrint( Utility::Format( L"RadioButton changed (using 'OnChange' event)\n Chosen Item: '%s'", pSelected->GetLabel()->GetText().c_str() ) ); + UnitPrint(Utility::Format(L"RadioButton changed (using 'OnChange' event)\n Chosen Item: '%s'", pSelected->GetLabel()->GetText().c_str())); } }; - - -DEFINE_UNIT_TEST( RadioButton2, L"RadioButton" ); \ No newline at end of file +DEFINE_UNIT_TEST(RadioButton2, L"RadioButton"); \ No newline at end of file diff --git a/test/GwenOpenGLTest/ScrollControl.cpp b/test/GwenOpenGLTest/ScrollControl.cpp index c21a2080a..db2accae3 100644 --- a/test/GwenOpenGLTest/ScrollControl.cpp +++ b/test/GwenOpenGLTest/ScrollControl.cpp @@ -5,134 +5,129 @@ using namespace Gwen; class ScrollControl : public GUnit { - public: - - GWEN_CONTROL_INLINE( ScrollControl, GUnit ) +public: + GWEN_CONTROL_INLINE(ScrollControl, GUnit) { - { - Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl( this ); - pCtrl->SetBounds( 10, 10, 100, 100 ); + Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl(this); + pCtrl->SetBounds(10, 10, 100, 100); - Controls::Button* pTestButton = new Controls::Button( pCtrl ); - pTestButton->SetText( L"Twice As Big" ); - pTestButton->SetBounds( 0, 0, 200, 200 ); + Controls::Button* pTestButton = new Controls::Button(pCtrl); + pTestButton->SetText(L"Twice As Big"); + pTestButton->SetBounds(0, 0, 200, 200); } { - Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl( this ); - pCtrl->SetBounds( 110, 10, 100, 100 ); + Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl(this); + pCtrl->SetBounds(110, 10, 100, 100); - Controls::Button* pTestButton = new Controls::Button( pCtrl ); - pTestButton->SetText( L"Same Size" ); - pTestButton->SetBounds( 0, 0, 100, 100 ); + Controls::Button* pTestButton = new Controls::Button(pCtrl); + pTestButton->SetText(L"Same Size"); + pTestButton->SetBounds(0, 0, 100, 100); } { - Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl( this ); - pCtrl->SetBounds( 210, 10, 100, 100 ); + Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl(this); + pCtrl->SetBounds(210, 10, 100, 100); - Controls::Button* pTestButton = new Controls::Button( pCtrl ); - pTestButton->SetText( L"Wide" ); - pTestButton->SetBounds( 0, 0, 200, 50 ); + Controls::Button* pTestButton = new Controls::Button(pCtrl); + pTestButton->SetText(L"Wide"); + pTestButton->SetBounds(0, 0, 200, 50); } { - Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl( this ); - pCtrl->SetBounds( 310, 10, 100, 100 ); + Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl(this); + pCtrl->SetBounds(310, 10, 100, 100); - Controls::Button* pTestButton = new Controls::Button( pCtrl ); - pTestButton->SetText( L"Tall" ); - pTestButton->SetBounds( 0, 0, 50, 200 ); + Controls::Button* pTestButton = new Controls::Button(pCtrl); + pTestButton->SetText(L"Tall"); + pTestButton->SetBounds(0, 0, 50, 200); } { - Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl( this ); - pCtrl->SetBounds( 410, 10, 100, 100 ); - pCtrl->SetScroll( false, true ); + Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl(this); + pCtrl->SetBounds(410, 10, 100, 100); + pCtrl->SetScroll(false, true); - Controls::Button* pTestButton = new Controls::Button( pCtrl ); - pTestButton->SetText( L"Vertical" ); - pTestButton->SetBounds( 0, 0, 200, 200 ); + Controls::Button* pTestButton = new Controls::Button(pCtrl); + pTestButton->SetText(L"Vertical"); + pTestButton->SetBounds(0, 0, 200, 200); } { - Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl( this ); - pCtrl->SetBounds( 510, 10, 100, 100 ); - pCtrl->SetScroll( true, false ); + Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl(this); + pCtrl->SetBounds(510, 10, 100, 100); + pCtrl->SetScroll(true, false); - Controls::Button* pTestButton = new Controls::Button( pCtrl ); - pTestButton->SetText( L"Horinzontal" ); - pTestButton->SetBounds( 0, 0, 200, 200 ); + Controls::Button* pTestButton = new Controls::Button(pCtrl); + pTestButton->SetText(L"Horinzontal"); + pTestButton->SetBounds(0, 0, 200, 200); } // Bottom Row { - Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl( this ); - pCtrl->SetBounds( 10, 110, 100, 100 ); - pCtrl->SetAutoHideBars( true ); + Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl(this); + pCtrl->SetBounds(10, 110, 100, 100); + pCtrl->SetAutoHideBars(true); - Controls::Button* pTestButton = new Controls::Button( pCtrl ); - pTestButton->SetText( L"Twice As Big" ); - pTestButton->SetBounds( 0, 0, 200, 200 ); + Controls::Button* pTestButton = new Controls::Button(pCtrl); + pTestButton->SetText(L"Twice As Big"); + pTestButton->SetBounds(0, 0, 200, 200); } { - Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl( this ); - pCtrl->SetBounds( 110, 110, 100, 100 ); - pCtrl->SetAutoHideBars( true ); + Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl(this); + pCtrl->SetBounds(110, 110, 100, 100); + pCtrl->SetAutoHideBars(true); - Controls::Button* pTestButton = new Controls::Button( pCtrl ); - pTestButton->SetText( L"Same Size" ); - pTestButton->SetBounds( 0, 0, 100, 100 ); + Controls::Button* pTestButton = new Controls::Button(pCtrl); + pTestButton->SetText(L"Same Size"); + pTestButton->SetBounds(0, 0, 100, 100); } { - Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl( this ); - pCtrl->SetBounds( 210, 110, 100, 100 ); - pCtrl->SetAutoHideBars( true ); + Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl(this); + pCtrl->SetBounds(210, 110, 100, 100); + pCtrl->SetAutoHideBars(true); - Controls::Button* pTestButton = new Controls::Button( pCtrl ); - pTestButton->SetText( L"Wide" ); - pTestButton->SetBounds( 0, 0, 200, 50 ); + Controls::Button* pTestButton = new Controls::Button(pCtrl); + pTestButton->SetText(L"Wide"); + pTestButton->SetBounds(0, 0, 200, 50); } { - Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl( this ); - pCtrl->SetBounds( 310, 110, 100, 100 ); - pCtrl->SetAutoHideBars( true ); + Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl(this); + pCtrl->SetBounds(310, 110, 100, 100); + pCtrl->SetAutoHideBars(true); - Controls::Button* pTestButton = new Controls::Button( pCtrl ); - pTestButton->SetText( L"Tall" ); - pTestButton->SetBounds( 0, 0, 50, 200 ); + Controls::Button* pTestButton = new Controls::Button(pCtrl); + pTestButton->SetText(L"Tall"); + pTestButton->SetBounds(0, 0, 50, 200); } { - Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl( this ); - pCtrl->SetBounds( 410, 110, 100, 100 ); - pCtrl->SetAutoHideBars( true ); - pCtrl->SetScroll( false, true ); + Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl(this); + pCtrl->SetBounds(410, 110, 100, 100); + pCtrl->SetAutoHideBars(true); + pCtrl->SetScroll(false, true); - Controls::Button* pTestButton = new Controls::Button( pCtrl ); - pTestButton->SetText( L"Vertical" ); - pTestButton->SetBounds( 0, 0, 200, 200 ); + Controls::Button* pTestButton = new Controls::Button(pCtrl); + pTestButton->SetText(L"Vertical"); + pTestButton->SetBounds(0, 0, 200, 200); } { - Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl( this ); - pCtrl->SetBounds( 510, 110, 100, 100 ); - pCtrl->SetAutoHideBars( true ); - pCtrl->SetScroll( true, false ); + Gwen::Controls::ScrollControl* pCtrl = new Gwen::Controls::ScrollControl(this); + pCtrl->SetBounds(510, 110, 100, 100); + pCtrl->SetAutoHideBars(true); + pCtrl->SetScroll(true, false); - Controls::Button* pTestButton = new Controls::Button( pCtrl ); - pTestButton->SetText( L"Horinzontal" ); - pTestButton->SetBounds( 0, 0, 200, 200 ); + Controls::Button* pTestButton = new Controls::Button(pCtrl); + pTestButton->SetText(L"Horinzontal"); + pTestButton->SetBounds(0, 0, 200, 200); } } - }; - - -DEFINE_UNIT_TEST( ScrollControl, L"Scroll" ); \ No newline at end of file +DEFINE_UNIT_TEST(ScrollControl, L"Scroll"); \ No newline at end of file diff --git a/test/GwenOpenGLTest/Slider.cpp b/test/GwenOpenGLTest/Slider.cpp index cf002fa86..6f46771d8 100644 --- a/test/GwenOpenGLTest/Slider.cpp +++ b/test/GwenOpenGLTest/Slider.cpp @@ -7,60 +7,56 @@ using namespace Gwen; class Slider : public GUnit { - public: - - GWEN_CONTROL_INLINE( Slider, GUnit ) +public: + GWEN_CONTROL_INLINE(Slider, GUnit) { { - Gwen::Controls::HorizontalSlider* pSlider = new Gwen::Controls::HorizontalSlider( this ); - pSlider->SetPos( 10, 10 ); - pSlider->SetSize( 150, 20 ); - pSlider->SetRange( 0, 100 ); - pSlider->SetValue( 25 ); - pSlider->onValueChanged.Add( this, &Slider::SliderMoved ); + Gwen::Controls::HorizontalSlider* pSlider = new Gwen::Controls::HorizontalSlider(this); + pSlider->SetPos(10, 10); + pSlider->SetSize(150, 20); + pSlider->SetRange(0, 100); + pSlider->SetValue(25); + pSlider->onValueChanged.Add(this, &Slider::SliderMoved); } { - Gwen::Controls::HorizontalSlider* pSlider = new Gwen::Controls::HorizontalSlider( this ); - pSlider->SetPos( 10, 40 ); - pSlider->SetSize( 150, 20 ); - pSlider->SetRange( 0, 100 ); - pSlider->SetValue( 25 ); - pSlider->SetNotchCount( 10 ); - pSlider->SetClampToNotches( true ); - pSlider->onValueChanged.Add( this, &Slider::SliderMoved ); + Gwen::Controls::HorizontalSlider* pSlider = new Gwen::Controls::HorizontalSlider(this); + pSlider->SetPos(10, 40); + pSlider->SetSize(150, 20); + pSlider->SetRange(0, 100); + pSlider->SetValue(25); + pSlider->SetNotchCount(10); + pSlider->SetClampToNotches(true); + pSlider->onValueChanged.Add(this, &Slider::SliderMoved); } { - Gwen::Controls::VerticalSlider* pSlider = new Gwen::Controls::VerticalSlider( this ); - pSlider->SetPos( 160, 10 ); - pSlider->SetSize( 20, 200 ); - pSlider->SetRange( 0, 100 ); - pSlider->SetValue( 25 ); - pSlider->onValueChanged.Add( this, &Slider::SliderMoved ); + Gwen::Controls::VerticalSlider* pSlider = new Gwen::Controls::VerticalSlider(this); + pSlider->SetPos(160, 10); + pSlider->SetSize(20, 200); + pSlider->SetRange(0, 100); + pSlider->SetValue(25); + pSlider->onValueChanged.Add(this, &Slider::SliderMoved); } { - Gwen::Controls::VerticalSlider* pSlider = new Gwen::Controls::VerticalSlider( this ); - pSlider->SetPos( 190, 10 ); - pSlider->SetSize( 20, 200 ); - pSlider->SetRange( 0, 100 ); - pSlider->SetValue( 25 ); - pSlider->SetNotchCount( 10 ); - pSlider->SetClampToNotches( true ); - pSlider->onValueChanged.Add( this, &Slider::SliderMoved ); + Gwen::Controls::VerticalSlider* pSlider = new Gwen::Controls::VerticalSlider(this); + pSlider->SetPos(190, 10); + pSlider->SetSize(20, 200); + pSlider->SetRange(0, 100); + pSlider->SetValue(25); + pSlider->SetNotchCount(10); + pSlider->SetClampToNotches(true); + pSlider->onValueChanged.Add(this, &Slider::SliderMoved); } } - void SliderMoved( Base* pControl ) + void SliderMoved(Base* pControl) { Gwen::Controls::Slider* pSlider = (Gwen::Controls::Slider*)pControl; - UnitPrint( Utility::Format( L"Slider Value: %.2f", pSlider->GetValue() ) ); + UnitPrint(Utility::Format(L"Slider Value: %.2f", pSlider->GetValue())); } - }; - - -DEFINE_UNIT_TEST( Slider, L"Slider" ); \ No newline at end of file +DEFINE_UNIT_TEST(Slider, L"Slider"); \ No newline at end of file diff --git a/test/GwenOpenGLTest/StatusBar.cpp b/test/GwenOpenGLTest/StatusBar.cpp index 902553739..07584c7ff 100644 --- a/test/GwenOpenGLTest/StatusBar.cpp +++ b/test/GwenOpenGLTest/StatusBar.cpp @@ -6,23 +6,20 @@ using namespace Gwen; class StatusBar : public GUnit { - public: - - GWEN_CONTROL_INLINE( StatusBar, GUnit ) +public: + GWEN_CONTROL_INLINE(StatusBar, GUnit) { - Gwen::Controls::StatusBar* pStatus = new Gwen::Controls::StatusBar( this ); - pStatus->Dock( Pos::Bottom ); + Gwen::Controls::StatusBar* pStatus = new Gwen::Controls::StatusBar(this); + pStatus->Dock(Pos::Bottom); - Gwen::Controls::Label* pLeft = new Gwen::Controls::Label( pStatus ); + Gwen::Controls::Label* pLeft = new Gwen::Controls::Label(pStatus); pLeft->SetText(L"Label Added to left"); - pStatus->AddControl( pLeft, false ); + pStatus->AddControl(pLeft, false); - Gwen::Controls::Label* pRight = new Gwen::Controls::Label( pStatus ); + Gwen::Controls::Label* pRight = new Gwen::Controls::Label(pStatus); pRight->SetText(L"Label Added to Right"); - pStatus->AddControl( pRight, true ); + pStatus->AddControl(pRight, true); } }; - - -DEFINE_UNIT_TEST( StatusBar, L"StatusBar" ); \ No newline at end of file +DEFINE_UNIT_TEST(StatusBar, L"StatusBar"); \ No newline at end of file diff --git a/test/GwenOpenGLTest/TabControl.cpp b/test/GwenOpenGLTest/TabControl.cpp index 8ed2b2ba6..c587b92fb 100644 --- a/test/GwenOpenGLTest/TabControl.cpp +++ b/test/GwenOpenGLTest/TabControl.cpp @@ -6,66 +6,62 @@ using namespace Gwen; class TabControl2 : public GUnit { - public: - +public: Controls::TabControl* m_pDockControlLeft; - GWEN_CONTROL_INLINE( TabControl2, GUnit ) + GWEN_CONTROL_INLINE(TabControl2, GUnit) { { - m_pDockControlLeft = new Controls::TabControl( this ); - m_pDockControlLeft->SetBounds( 10, 10, 200, 200 ); + m_pDockControlLeft = new Controls::TabControl(this); + m_pDockControlLeft->SetBounds(10, 10, 200, 200); { - Controls::TabButton* pButton = m_pDockControlLeft->AddPage( L"Controls" ); + Controls::TabButton* pButton = m_pDockControlLeft->AddPage(L"Controls"); Base* pPage = pButton->GetPage(); { - Controls::RadioButtonController* pRadio = new Controls::RadioButtonController( pPage ); - pRadio->SetBounds( 10, 10, 100, 100 ); + Controls::RadioButtonController* pRadio = new Controls::RadioButtonController(pPage); + pRadio->SetBounds(10, 10, 100, 100); - pRadio->AddOption( "Top" )->Select(); - pRadio->AddOption( "Bottom" ); - pRadio->AddOption( "Left" ); - pRadio->AddOption( "Right" ); - - pRadio->onSelectionChange.Add( this, &ThisClass::OnDockChange ); + pRadio->AddOption("Top")->Select(); + pRadio->AddOption("Bottom"); + pRadio->AddOption("Left"); + pRadio->AddOption("Right"); + pRadio->onSelectionChange.Add(this, &ThisClass::OnDockChange); } } - m_pDockControlLeft->AddPage( L"Red" ); - m_pDockControlLeft->AddPage( L"Green" ); - m_pDockControlLeft->AddPage( L"Blue" ); + m_pDockControlLeft->AddPage(L"Red"); + m_pDockControlLeft->AddPage(L"Green"); + m_pDockControlLeft->AddPage(L"Blue"); } { - Controls::TabControl* pDragMe = new Controls::TabControl( this ); - pDragMe->SetBounds( 220, 10, 200, 200 ); + Controls::TabControl* pDragMe = new Controls::TabControl(this); + pDragMe->SetBounds(220, 10, 200, 200); - pDragMe->AddPage( L"You" ); - pDragMe->AddPage( L"Can" ); - pDragMe->AddPage( L"Reorder" )->SetImage( L"test16.png" ); - pDragMe->AddPage( L"These" ); - pDragMe->AddPage( L"Tabs" ); + pDragMe->AddPage(L"You"); + pDragMe->AddPage(L"Can"); + pDragMe->AddPage(L"Reorder")->SetImage(L"test16.png"); + pDragMe->AddPage(L"These"); + pDragMe->AddPage(L"Tabs"); - pDragMe->SetAllowReorder( true ); + pDragMe->SetAllowReorder(true); } } - void OnDockChange( Gwen::Controls::Base* pControl ) + void OnDockChange(Gwen::Controls::Base* pControl) { - Gwen::Controls::RadioButtonController* rc = (Gwen::Controls::RadioButtonController*) pControl; + Gwen::Controls::RadioButtonController* rc = (Gwen::Controls::RadioButtonController*)pControl; - if ( rc->GetSelectedLabel() == L"Top" ) m_pDockControlLeft->SetTabStripPosition( Pos::Top ); - if ( rc->GetSelectedLabel() == L"Bottom" ) m_pDockControlLeft->SetTabStripPosition( Pos::Bottom ); - if ( rc->GetSelectedLabel() == L"Left" ) m_pDockControlLeft->SetTabStripPosition( Pos::Left ); - if ( rc->GetSelectedLabel() == L"Right" ) m_pDockControlLeft->SetTabStripPosition( Pos::Right ); + if (rc->GetSelectedLabel() == L"Top") m_pDockControlLeft->SetTabStripPosition(Pos::Top); + if (rc->GetSelectedLabel() == L"Bottom") m_pDockControlLeft->SetTabStripPosition(Pos::Bottom); + if (rc->GetSelectedLabel() == L"Left") m_pDockControlLeft->SetTabStripPosition(Pos::Left); + if (rc->GetSelectedLabel() == L"Right") m_pDockControlLeft->SetTabStripPosition(Pos::Right); } - Gwen::Font m_Font; + Gwen::Font m_Font; }; - - -DEFINE_UNIT_TEST( TabControl2, L"TabControl" ); \ No newline at end of file +DEFINE_UNIT_TEST(TabControl2, L"TabControl"); \ No newline at end of file diff --git a/test/GwenOpenGLTest/TextBox.cpp b/test/GwenOpenGLTest/TextBox.cpp index 72b49adc9..615b2bd3d 100644 --- a/test/GwenOpenGLTest/TextBox.cpp +++ b/test/GwenOpenGLTest/TextBox.cpp @@ -5,75 +5,69 @@ using namespace Gwen; class TextBox : public GUnit { - public: - - GWEN_CONTROL_INLINE( TextBox, GUnit ) +public: + GWEN_CONTROL_INLINE(TextBox, GUnit) { { - Gwen::Controls::TextBox* label = new Gwen::Controls::TextBox( this ); - label->SetText( "" ); - label->SetPos( 10, 10 ); - label->onTextChanged.Add( this, &ThisClass::OnEdit ); - label->onReturnPressed.Add( this, &ThisClass::OnSubmit ); - + Gwen::Controls::TextBox* label = new Gwen::Controls::TextBox(this); + label->SetText(""); + label->SetPos(10, 10); + label->onTextChanged.Add(this, &ThisClass::OnEdit); + label->onReturnPressed.Add(this, &ThisClass::OnSubmit); } { - Gwen::Controls::TextBox* label = new Gwen::Controls::TextBox( this ); - label->SetText( "Normal Everyday Label" ); - label->SetPos( 10, 10 + 25 ); + Gwen::Controls::TextBox* label = new Gwen::Controls::TextBox(this); + label->SetText("Normal Everyday Label"); + label->SetPos(10, 10 + 25); } { - Gwen::Controls::TextBox* label = new Gwen::Controls::TextBox( this ); - label->SetText( "Select All Text On Focus" ); - label->SetPos( 10, 10 + 25 * 2 ); - label->SetSelectAllOnFocus( true ); + Gwen::Controls::TextBox* label = new Gwen::Controls::TextBox(this); + label->SetText("Select All Text On Focus"); + label->SetPos(10, 10 + 25 * 2); + label->SetSelectAllOnFocus(true); } { - Gwen::Controls::TextBox* label = new Gwen::Controls::TextBox( this ); - label->SetText( L"Different Coloured Text, for some reason" ); - label->SetTextColor( Gwen::Color( 255, 0, 255, 255 ) ); - label->SetPos( 10, 10 + 25 * 3 ); + Gwen::Controls::TextBox* label = new Gwen::Controls::TextBox(this); + label->SetText(L"Different Coloured Text, for some reason"); + label->SetTextColor(Gwen::Color(255, 0, 255, 255)); + label->SetPos(10, 10 + 25 * 3); } { - Gwen::Controls::TextBoxNumeric* label = new Gwen::Controls::TextBoxNumeric( this ); - label->SetText( L"2004" ); - label->SetTextColor( Gwen::Color( 255, 0, 255, 255 ) ); - label->SetPos( 10, 10 + 25 * 4 ); + Gwen::Controls::TextBoxNumeric* label = new Gwen::Controls::TextBoxNumeric(this); + label->SetText(L"2004"); + label->SetTextColor(Gwen::Color(255, 0, 255, 255)); + label->SetPos(10, 10 + 25 * 4); } { m_Font.facename = L"Impact"; m_Font.size = 50; - Gwen::Controls::TextBox* label = new Gwen::Controls::TextBox( this ); - label->SetText( L"Different Font" ); - label->SetPos( 10, 10 + 25 * 5 ); - label->SetFont( &m_Font ); - label->SetSize( 200, 55 ); + Gwen::Controls::TextBox* label = new Gwen::Controls::TextBox(this); + label->SetText(L"Different Font"); + label->SetPos(10, 10 + 25 * 5); + label->SetFont(&m_Font); + label->SetSize(200, 55); } - - } - void OnEdit( Gwen::Controls::Base* pControl ) + void OnEdit(Gwen::Controls::Base* pControl) { - Gwen::Controls::TextBox* textbox = (Gwen::Controls::TextBox*) (pControl); - UnitPrint( Utility::Format( L"Textbox Edit: [%s]\n", textbox->GetText().c_str() ) ); + Gwen::Controls::TextBox* textbox = (Gwen::Controls::TextBox*)(pControl); + UnitPrint(Utility::Format(L"Textbox Edit: [%s]\n", textbox->GetText().c_str())); } - void OnSubmit( Gwen::Controls::Base* pControl ) + void OnSubmit(Gwen::Controls::Base* pControl) { - Gwen::Controls::TextBox* textbox = (Gwen::Controls::TextBox*) (pControl); - UnitPrint( Utility::Format( L"Textbox Submit: [%s]\n", textbox->GetText().c_str() ) ); + Gwen::Controls::TextBox* textbox = (Gwen::Controls::TextBox*)(pControl); + UnitPrint(Utility::Format(L"Textbox Submit: [%s]\n", textbox->GetText().c_str())); } - Gwen::Font m_Font; + Gwen::Font m_Font; }; - - -DEFINE_UNIT_TEST( TextBox, L"TextBox" ); \ No newline at end of file +DEFINE_UNIT_TEST(TextBox, L"TextBox"); \ No newline at end of file diff --git a/test/GwenOpenGLTest/TreeControl.cpp b/test/GwenOpenGLTest/TreeControl.cpp index 87924ce7e..f0e22d14b 100644 --- a/test/GwenOpenGLTest/TreeControl.cpp +++ b/test/GwenOpenGLTest/TreeControl.cpp @@ -5,57 +5,52 @@ using namespace Gwen; using namespace Gwen::Controls; - class TreeControl2 : public GUnit { - public: - - GWEN_CONTROL_INLINE( TreeControl2, GUnit ) +public: + GWEN_CONTROL_INLINE(TreeControl2, GUnit) { { - Gwen::Controls::TreeControl* ctrl = new Gwen::Controls::TreeControl( this ); + Gwen::Controls::TreeControl* ctrl = new Gwen::Controls::TreeControl(this); ctrl->SetKeyboardInputEnabled(true); - ctrl->AddNode( L"Node One" ); - Gwen::Controls::TreeNode* pNode = ctrl->AddNode( L"Node Two" ); - pNode->AddNode( L"Node Two Inside" ); - pNode->AddNode( L"Eyes" ); + ctrl->AddNode(L"Node One"); + Gwen::Controls::TreeNode* pNode = ctrl->AddNode(L"Node Two"); + pNode->AddNode(L"Node Two Inside"); + pNode->AddNode(L"Eyes"); pNode->SetSelected(true); - pNode->AddNode( L"Brown" )->AddNode( L"Node Two Inside" )->AddNode( L"Eyes" )->AddNode( L"Brown" ); - ctrl->AddNode( L"Node Three" ); + pNode->AddNode(L"Brown")->AddNode(L"Node Two Inside")->AddNode(L"Eyes")->AddNode(L"Brown"); + ctrl->AddNode(L"Node Three"); ctrl->Focus(); ctrl->SetKeyboardInputEnabled(true); - ctrl->SetBounds( 30, 30, 200, 200 ); + ctrl->SetBounds(30, 30, 200, 200); ctrl->ExpandAll(); } { - Gwen::Controls::TreeControl* ctrl = new Gwen::Controls::TreeControl( this ); + Gwen::Controls::TreeControl* ctrl = new Gwen::Controls::TreeControl(this); - ctrl->AllowMultiSelect( true ); + ctrl->AllowMultiSelect(true); - ctrl->AddNode( L"Node One" ); - Gwen::Controls::TreeNode* pNode = ctrl->AddNode( L"Node Two" ); - pNode->AddNode( L"Node Two Inside" ); - pNode->AddNode( L"Eyes" ); - Gwen::Controls::TreeNode* pNodeTwo = pNode->AddNode( L"Brown" )->AddNode( L"Node Two Inside" )->AddNode( L"Eyes" ); - pNodeTwo->AddNode( L"Brown" ); - pNodeTwo->AddNode( L"Green" ); - pNodeTwo->AddNode( L"Slime" ); - pNodeTwo->AddNode( L"Grass" ); - pNodeTwo->AddNode( L"Pipe" ); + ctrl->AddNode(L"Node One"); + Gwen::Controls::TreeNode* pNode = ctrl->AddNode(L"Node Two"); + pNode->AddNode(L"Node Two Inside"); + pNode->AddNode(L"Eyes"); + Gwen::Controls::TreeNode* pNodeTwo = pNode->AddNode(L"Brown")->AddNode(L"Node Two Inside")->AddNode(L"Eyes"); + pNodeTwo->AddNode(L"Brown"); + pNodeTwo->AddNode(L"Green"); + pNodeTwo->AddNode(L"Slime"); + pNodeTwo->AddNode(L"Grass"); + pNodeTwo->AddNode(L"Pipe"); - ctrl->AddNode( L"Node Three" ); + ctrl->AddNode(L"Node Three"); - ctrl->SetBounds( 240, 30, 200, 200 ); + ctrl->SetBounds(240, 30, 200, 200); ctrl->ExpandAll(); } } - }; - - -DEFINE_UNIT_TEST( TreeControl2, L"TreeControl" ); \ No newline at end of file +DEFINE_UNIT_TEST(TreeControl2, L"TreeControl"); \ No newline at end of file diff --git a/test/GwenOpenGLTest/UnitTest.cpp b/test/GwenOpenGLTest/UnitTest.cpp index 9886c6eb3..c378bbd67 100644 --- a/test/GwenOpenGLTest/UnitTest.cpp +++ b/test/GwenOpenGLTest/UnitTest.cpp @@ -10,170 +10,153 @@ using namespace Gwen; -#define ADD_UNIT_TEST( name )\ - GUnit* RegisterUnitTest_##name( Gwen::Controls::TabControl* tab );\ - RegisterUnitTest_##name( m_TabControl )->SetUnitTest( this ); +#define ADD_UNIT_TEST(name) \ + GUnit* RegisterUnitTest_##name(Gwen::Controls::TabControl* tab); \ + RegisterUnitTest_##name(m_TabControl)->SetUnitTest(this); -GWEN_CONTROL_CONSTRUCTOR( UnitTest ) +GWEN_CONTROL_CONSTRUCTOR(UnitTest) { - SetTitle( L"GWEN Unit Test" ); + SetTitle(L"GWEN Unit Test"); - SetSize( 600, 450 ); + SetSize(600, 450); + m_TabControl = new Controls::TabControl(this); + m_TabControl->Dock(Pos::Fill); + m_TabControl->SetMargin(Margin(2, 2, 2, 2)); - m_TabControl = new Controls::TabControl( this ); - m_TabControl->Dock( Pos::Fill ); - m_TabControl->SetMargin( Margin( 2, 2, 2, 2 ) ); + m_TextOutput = new Controls::ListBox(this); + m_TextOutput->Dock(Pos::Bottom); + m_TextOutput->SetHeight(100); - m_TextOutput = new Controls::ListBox( this ); - m_TextOutput->Dock( Pos::Bottom ); - m_TextOutput->SetHeight( 100 ); - - - ADD_UNIT_TEST( ImagePanel ); + ADD_UNIT_TEST(ImagePanel); //ADD_UNIT_TEST( MenuStrip ); Gwen::UnicodeString str1(L"testje"); Gwen::Controls::TabButton* tab = m_TabControl->AddPage(str1); - Gwen::Controls::TreeControl* ctrl=0; - + Gwen::Controls::TreeControl* ctrl = 0; + { - ctrl = new Gwen::Controls::TreeControl(tab->GetPage()); + ctrl = new Gwen::Controls::TreeControl(tab->GetPage()); - ctrl->SetKeyboardInputEnabled(true); - ctrl->AddNode( L"Node One" ); - { - Gwen::Controls::TreeNode* pNode = ctrl->AddNode( L"Node Two" ); - pNode->AddNode( L"Node Two Inside" ); - pNode->AddNode( L"Eyes" ); - - } - { - Gwen::Controls::TreeNode* pNode = ctrl->AddNode( L"Node Two" ); - pNode->AddNode( L"Node Two Inside" ); - pNode->AddNode( L"Eyes" ); - - } - { - Gwen::Controls::TreeNode* pNode = ctrl->AddNode( L"Node Two" ); - pNode->AddNode( L"Node Two Inside" ); - pNode->AddNode( L"Eyes" ); - - } - { - Gwen::Controls::TreeNode* pNode = ctrl->AddNode( L"Node Two" ); - pNode->AddNode( L"Node Two Inside" ); - pNode->AddNode( L"Eyes" ); - - } - { - Gwen::Controls::TreeNode* pNode = ctrl->AddNode( L"Node Two" ); - pNode->AddNode( L"Node Two Inside" ); - pNode->AddNode( L"Eyes" ); - - } - { - Gwen::Controls::TreeNode* pNode = ctrl->AddNode( L"Node Two" ); - pNode->AddNode( L"Node Two Inside" ); - pNode->AddNode( L"Eyes" ); - pNode->SetSelected(true); - - - pNode->AddNode( L"Brown" )->AddNode( L"Node Two Inside" )->AddNode( L"Eyes" )->AddNode( L"Brown" ); - } - ctrl->AddNode( L"Node Three" ); - ctrl->Focus(); - ctrl->SetKeyboardInputEnabled(true); - - ctrl->SetBounds( 30, 30, 200, 30+16*10 ); - //ctrl->ExpandAll(); - ctrl->ForceUpdateScrollBars(); - ctrl->OnKeyDown(true); - - + ctrl->SetKeyboardInputEnabled(true); + ctrl->AddNode(L"Node One"); + { + Gwen::Controls::TreeNode* pNode = ctrl->AddNode(L"Node Two"); + pNode->AddNode(L"Node Two Inside"); + pNode->AddNode(L"Eyes"); } - - - //GUnit* u = new TreeControl2(m_TabControl);..Gwen::Controls::TreeControl2( m_TabControl ); + { + Gwen::Controls::TreeNode* pNode = ctrl->AddNode(L"Node Two"); + pNode->AddNode(L"Node Two Inside"); + pNode->AddNode(L"Eyes"); + } + { + Gwen::Controls::TreeNode* pNode = ctrl->AddNode(L"Node Two"); + pNode->AddNode(L"Node Two Inside"); + pNode->AddNode(L"Eyes"); + } + { + Gwen::Controls::TreeNode* pNode = ctrl->AddNode(L"Node Two"); + pNode->AddNode(L"Node Two Inside"); + pNode->AddNode(L"Eyes"); + } + { + Gwen::Controls::TreeNode* pNode = ctrl->AddNode(L"Node Two"); + pNode->AddNode(L"Node Two Inside"); + pNode->AddNode(L"Eyes"); + } + { + Gwen::Controls::TreeNode* pNode = ctrl->AddNode(L"Node Two"); + pNode->AddNode(L"Node Two Inside"); + pNode->AddNode(L"Eyes"); + pNode->SetSelected(true); + + pNode->AddNode(L"Brown")->AddNode(L"Node Two Inside")->AddNode(L"Eyes")->AddNode(L"Brown"); + } + ctrl->AddNode(L"Node Three"); + ctrl->Focus(); + ctrl->SetKeyboardInputEnabled(true); + + ctrl->SetBounds(30, 30, 200, 30 + 16 * 10); + //ctrl->ExpandAll(); + ctrl->ForceUpdateScrollBars(); + ctrl->OnKeyDown(true); + } + + //GUnit* u = new TreeControl2(m_TabControl);..Gwen::Controls::TreeControl2( m_TabControl ); //GUnit* RegisterUnitTest_TreeControl2( Gwen::Controls::TabControl* tab );\ //RegisterUnitTest_TreeControl2( m_TabControl )->SetUnitTest( this ); - - //#define DEFINE_UNIT_TEST( name, displayname ) + //#define DEFINE_UNIT_TEST( name, displayname ) //GUnit* RegisterUnitTest_TreeControl2( Gwen::Controls::TabControl* tab ) //{ - // GUnit* u = new TreeControl2( tab ); - // tab->AddPage( displayname, u ); - // return u; + // GUnit* u = new TreeControl2( tab ); + // tab->AddPage( displayname, u ); + // return u; //} //ADD_UNIT_TEST( TreeControl2 ); - - ADD_UNIT_TEST( Properties2 ); - - - ADD_UNIT_TEST( TabControl2 ); - ADD_UNIT_TEST( ScrollControl ); - ADD_UNIT_TEST( MenuStrip ); - ADD_UNIT_TEST( Numeric ); - ADD_UNIT_TEST( ComboBox ); - ADD_UNIT_TEST( TextBox ); - ADD_UNIT_TEST( ListBox ); - ADD_UNIT_TEST( Slider ); - ADD_UNIT_TEST( ProgressBar ); - ADD_UNIT_TEST( RadioButton2 ); - - ADD_UNIT_TEST( Label ); - ADD_UNIT_TEST( Checkbox ); - ADD_UNIT_TEST( Button ); - ADD_UNIT_TEST( CrossSplitter ); + ADD_UNIT_TEST(Properties2); - ADD_UNIT_TEST( PanelListPanel ); - ADD_UNIT_TEST( GroupBox2 ); + ADD_UNIT_TEST(TabControl2); + ADD_UNIT_TEST(ScrollControl); + ADD_UNIT_TEST(MenuStrip); + ADD_UNIT_TEST(Numeric); + ADD_UNIT_TEST(ComboBox); + ADD_UNIT_TEST(TextBox); + ADD_UNIT_TEST(ListBox); + ADD_UNIT_TEST(Slider); + ADD_UNIT_TEST(ProgressBar); + ADD_UNIT_TEST(RadioButton2); - ADD_UNIT_TEST( StatusBar ); - + ADD_UNIT_TEST(Label); + ADD_UNIT_TEST(Checkbox); + ADD_UNIT_TEST(Button); + + ADD_UNIT_TEST(CrossSplitter); + + ADD_UNIT_TEST(PanelListPanel); + ADD_UNIT_TEST(GroupBox2); + + ADD_UNIT_TEST(StatusBar); ctrl->Focus(); - PrintText( L"Unit Test Started.\n" ); + PrintText(L"Unit Test Started.\n"); m_fLastSecond = Gwen::Platform::GetTimeInSeconds(); m_iFrames = 0; } - -void UnitTest::PrintText( const Gwen::UnicodeString& str ) +void UnitTest::PrintText(const Gwen::UnicodeString& str) { - m_TextOutput->AddItem( str ); + m_TextOutput->AddItem(str); m_TextOutput->Scroller()->ScrollToBottom(); } -void UnitTest::Render( Gwen::Skin::Base* skin ) +void UnitTest::Render(Gwen::Skin::Base* skin) { m_iFrames++; - if ( m_fLastSecond < Gwen::Platform::GetTimeInSeconds() ) + if (m_fLastSecond < Gwen::Platform::GetTimeInSeconds()) { - SetTitle( Gwen::Utility::Format( L"GWEN Unit Test - %i fps", m_iFrames ) ); + SetTitle(Gwen::Utility::Format(L"GWEN Unit Test - %i fps", m_iFrames)); m_fLastSecond = Gwen::Platform::GetTimeInSeconds() + 1.0f; m_iFrames = 0; } - BaseClass::Render( skin ); - + BaseClass::Render(skin); } -void GUnit::UnitPrint( const Gwen::UnicodeString& str ) +void GUnit::UnitPrint(const Gwen::UnicodeString& str) { - m_pUnitTest->PrintText( str ); + m_pUnitTest->PrintText(str); } -void GUnit::UnitPrint( const Gwen::String& str ) +void GUnit::UnitPrint(const Gwen::String& str) { - UnitPrint( Utility::StringToUnicode( str ) ); + UnitPrint(Utility::StringToUnicode(str)); } - diff --git a/test/GwenOpenGLTest/UnitTest.h b/test/GwenOpenGLTest/UnitTest.h index 7d8f76f7f..13b03d8aa 100644 --- a/test/GwenOpenGLTest/UnitTest.h +++ b/test/GwenOpenGLTest/UnitTest.h @@ -4,7 +4,6 @@ See license in Gwen.h */ - #pragma once #ifndef GWEN_UNITTEST_UNITTEST_H #define GWEN_UNITTEST_UNITTEST_H @@ -18,47 +17,43 @@ class UnitTest; - - class GUnit : public Gwen::Controls::Base { - public: +public: + GWEN_CONTROL_INLINE(GUnit, Gwen::Controls::Base) + { + m_pUnitTest = NULL; + } - GWEN_CONTROL_INLINE( GUnit, Gwen::Controls::Base ) - { - m_pUnitTest = NULL; - } + void SetUnitTest(UnitTest* u) { m_pUnitTest = u; } - void SetUnitTest( UnitTest* u ){ m_pUnitTest = u; } + void UnitPrint(const Gwen::UnicodeString& str); + void UnitPrint(const Gwen::String& str); - void UnitPrint( const Gwen::UnicodeString& str ); - void UnitPrint( const Gwen::String& str ); - - - - - UnitTest* m_pUnitTest; + UnitTest* m_pUnitTest; }; class UnitTest : public Gwen::Controls::WindowControl { - public: +public: + GWEN_CONTROL(UnitTest, Gwen::Controls::WindowControl); - GWEN_CONTROL( UnitTest, Gwen::Controls::WindowControl ); + void PrintText(const Gwen::UnicodeString& str); - void PrintText( const Gwen::UnicodeString& str ); - - void Render( Gwen::Skin::Base* skin ); - - - private: - - Gwen::Controls::TabControl* m_TabControl; - Gwen::Controls::ListBox* m_TextOutput; - unsigned int m_iFrames; - float m_fLastSecond; + void Render(Gwen::Skin::Base* skin); +private: + Gwen::Controls::TabControl* m_TabControl; + Gwen::Controls::ListBox* m_TextOutput; + unsigned int m_iFrames; + float m_fLastSecond; }; -#define DEFINE_UNIT_TEST( name, displayname ) GUnit* RegisterUnitTest_##name( Gwen::Controls::TabControl* tab ){ GUnit* u = new name( tab ); tab->AddPage( displayname, u ); return u; } +#define DEFINE_UNIT_TEST(name, displayname) \ + GUnit* RegisterUnitTest_##name(Gwen::Controls::TabControl* tab) \ + { \ + GUnit* u = new name(tab); \ + tab->AddPage(displayname, u); \ + return u; \ + } #endif diff --git a/test/InverseDynamics/test_invdyn_bullet.cpp b/test/InverseDynamics/test_invdyn_bullet.cpp index 63597a562..3cec06f4f 100644 --- a/test/InverseDynamics/test_invdyn_bullet.cpp +++ b/test/InverseDynamics/test_invdyn_bullet.cpp @@ -32,7 +32,7 @@ using namespace btInverseDynamics; -bool FLAGS_verbose=false; +bool FLAGS_verbose = false; static btVector3 gravity(0, 0, -10); static const bool kBaseFixed = false; @@ -41,73 +41,80 @@ static const char kUrdfFile[] = "r2d2.urdf"; /// this test loads the a urdf model with fixed, floating, prismatic and rotational joints, /// converts in to an inverse dynamics model and compares forward to inverse dynamics for /// random input -TEST(InvDynCompare, bulletUrdfR2D2) { - MyBtMultiBodyFromURDF mb_load(gravity, kBaseFixed); +TEST(InvDynCompare, bulletUrdfR2D2) +{ + MyBtMultiBodyFromURDF mb_load(gravity, kBaseFixed); - char relativeFileName[1024]; + char relativeFileName[1024]; - ASSERT_TRUE(b3ResourcePath::findResourcePath(kUrdfFile, relativeFileName, 1024)); + ASSERT_TRUE(b3ResourcePath::findResourcePath(kUrdfFile, relativeFileName, 1024)); - mb_load.setFileName(relativeFileName); - mb_load.init(); + mb_load.setFileName(relativeFileName); + mb_load.init(); - btMultiBodyTreeCreator id_creator; - btMultiBody *btmb = mb_load.getBtMultiBody(); - ASSERT_EQ(id_creator.createFromBtMultiBody(btmb), 0); + btMultiBodyTreeCreator id_creator; + btMultiBody *btmb = mb_load.getBtMultiBody(); + ASSERT_EQ(id_creator.createFromBtMultiBody(btmb), 0); - MultiBodyTree *id_tree = CreateMultiBodyTree(id_creator); - ASSERT_EQ(0x0 != id_tree, true); + MultiBodyTree *id_tree = CreateMultiBodyTree(id_creator); + ASSERT_EQ(0x0 != id_tree, true); - vecx q(id_tree->numDoFs()); - vecx u(id_tree->numDoFs()); - vecx dot_u(id_tree->numDoFs()); - vecx joint_forces(id_tree->numDoFs()); + vecx q(id_tree->numDoFs()); + vecx u(id_tree->numDoFs()); + vecx dot_u(id_tree->numDoFs()); + vecx joint_forces(id_tree->numDoFs()); - const int kNLoops = 10; - double max_pos_error = 0; - double max_acc_error = 0; + const int kNLoops = 10; + double max_pos_error = 0; + double max_acc_error = 0; - b3Srand(0); + b3Srand(0); - for (int loop = 0; loop < kNLoops; loop++) { - for (int i = 0; i < q.size(); i++) { - q(i) = b3RandRange(-B3_PI, B3_PI); - u(i) = b3RandRange(-B3_PI, B3_PI); - dot_u(i) = b3RandRange(-B3_PI, B3_PI); - } + for (int loop = 0; loop < kNLoops; loop++) + { + for (int i = 0; i < q.size(); i++) + { + q(i) = b3RandRange(-B3_PI, B3_PI); + u(i) = b3RandRange(-B3_PI, B3_PI); + dot_u(i) = b3RandRange(-B3_PI, B3_PI); + } - double pos_error; - double acc_error; - btmb->clearForcesAndTorques(); - id_tree->clearAllUserForcesAndMoments(); - // call inverse dynamics once, to get global position & velocity of root body - // (fixed, so q, u, dot_u arbitrary) - EXPECT_EQ(id_tree->calculateInverseDynamics(q, u, dot_u, &joint_forces), 0); + double pos_error; + double acc_error; + btmb->clearForcesAndTorques(); + id_tree->clearAllUserForcesAndMoments(); + // call inverse dynamics once, to get global position & velocity of root body + // (fixed, so q, u, dot_u arbitrary) + EXPECT_EQ(id_tree->calculateInverseDynamics(q, u, dot_u, &joint_forces), 0); - EXPECT_EQ(compareInverseAndForwardDynamics(q, u, dot_u, gravity, FLAGS_verbose, btmb, id_tree, - &pos_error, &acc_error), - 0); + EXPECT_EQ(compareInverseAndForwardDynamics(q, u, dot_u, gravity, FLAGS_verbose, btmb, id_tree, + &pos_error, &acc_error), + 0); - if (pos_error > max_pos_error) { - max_pos_error = pos_error; - } - if (acc_error > max_acc_error) { - max_acc_error = acc_error; - } - } + if (pos_error > max_pos_error) + { + max_pos_error = pos_error; + } + if (acc_error > max_acc_error) + { + max_acc_error = acc_error; + } + } - if (FLAGS_verbose) { - printf("max_pos_error= %e\n", max_pos_error); - printf("max_acc_error= %e\n", max_acc_error); - } + if (FLAGS_verbose) + { + printf("max_pos_error= %e\n", max_pos_error); + printf("max_acc_error= %e\n", max_acc_error); + } - EXPECT_LT(max_pos_error, std::numeric_limits::epsilon()*1e4); - EXPECT_LT(max_acc_error, std::numeric_limits::epsilon()*1e5); + EXPECT_LT(max_pos_error, std::numeric_limits::epsilon() * 1e4); + EXPECT_LT(max_acc_error, std::numeric_limits::epsilon() * 1e5); } -int main(int argc, char **argv) { - b3CommandLineArgs myArgs(argc,argv); - FLAGS_verbose = myArgs.CheckCmdLineFlag("verbose"); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); +int main(int argc, char **argv) +{ + b3CommandLineArgs myArgs(argc, argv); + FLAGS_verbose = myArgs.CheckCmdLineFlag("verbose"); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); } diff --git a/test/InverseDynamics/test_invdyn_jacobian.cpp b/test/InverseDynamics/test_invdyn_jacobian.cpp index dccc40e40..c752c0a37 100644 --- a/test/InverseDynamics/test_invdyn_jacobian.cpp +++ b/test/InverseDynamics/test_invdyn_jacobian.cpp @@ -22,305 +22,340 @@ using namespace btInverseDynamics; #if (defined BT_ID_HAVE_MAT3X) && (defined BT_ID_WITH_JACOBIANS) // minimal smart pointer to make this work for c++2003 template -class ptr { - ptr(); - ptr(const ptr&); +class ptr +{ + ptr(); + ptr(const ptr&); + public: - ptr(T* p) : m_p(p) {}; - ~ptr() { delete m_p; } - T& operator*() { return *m_p; } - T* operator->() { return m_p; } - T*get() {return m_p;} - const T*get() const {return m_p;} - friend bool operator==(const ptr& lhs, const ptr& rhs) { return rhs.m_p == lhs.m_p; } - friend bool operator!=(const ptr& lhs, const ptr& rhs) { return !(rhs.m_p == lhs.m_p); -} + ptr(T* p) : m_p(p){}; + ~ptr() { delete m_p; } + T& operator*() { return *m_p; } + T* operator->() { return m_p; } + T* get() { return m_p; } + const T* get() const { return m_p; } + friend bool operator==(const ptr& lhs, const ptr& rhs) { return rhs.m_p == lhs.m_p; } + friend bool operator!=(const ptr& lhs, const ptr& rhs) + { + return !(rhs.m_p == lhs.m_p); + } private: - T* m_p; + T* m_p; }; void calculateDotJacUError(const MultiBodyTreeCreator& creator, const int nloops, - double* max_error) { - // tree1 is used as reference to compute dot(Jacobian)*u from acceleration(dot(u)=0) - ptr tree1(CreateMultiBodyTree(creator)); - ASSERT_TRUE(0x0 != tree1); - CloneTreeCreator clone(tree1.get()); - // tree2 is used to compute dot(Jacobian)*u using the calculateJacobian function - ptr tree2(CreateMultiBodyTree(clone)); - ASSERT_TRUE(0x0 != tree2); + double* max_error) +{ + // tree1 is used as reference to compute dot(Jacobian)*u from acceleration(dot(u)=0) + ptr tree1(CreateMultiBodyTree(creator)); + ASSERT_TRUE(0x0 != tree1); + CloneTreeCreator clone(tree1.get()); + // tree2 is used to compute dot(Jacobian)*u using the calculateJacobian function + ptr tree2(CreateMultiBodyTree(clone)); + ASSERT_TRUE(0x0 != tree2); - const int ndofs = tree1->numDoFs(); - const int nbodies = tree1->numBodies(); - if (ndofs <= 0) { - *max_error = 0; - return; - } + const int ndofs = tree1->numDoFs(); + const int nbodies = tree1->numBodies(); + if (ndofs <= 0) + { + *max_error = 0; + return; + } - vecx q(ndofs); - vecx u(ndofs); - vecx dot_u(ndofs); - vecx zero(ndofs); - setZero(zero); + vecx q(ndofs); + vecx u(ndofs); + vecx dot_u(ndofs); + vecx zero(ndofs); + setZero(zero); - double max_lin_error = 0; - double max_ang_error = 0; + double max_lin_error = 0; + double max_ang_error = 0; - for (int loop = 0; loop < nloops; loop++) { - for (int i = 0; i < q.size(); i++) { - q(i) = b3RandRange(-B3_PI, B3_PI); - u(i) = b3RandRange(-B3_PI, B3_PI); - } + for (int loop = 0; loop < nloops; loop++) + { + for (int i = 0; i < q.size(); i++) + { + q(i) = b3RandRange(-B3_PI, B3_PI); + u(i) = b3RandRange(-B3_PI, B3_PI); + } - EXPECT_EQ(0, tree1->calculateKinematics(q, u, zero)); - EXPECT_EQ(0, tree2->calculatePositionAndVelocityKinematics(q, u)); - EXPECT_EQ(0, tree2->calculateJacobians(q, u)); + EXPECT_EQ(0, tree1->calculateKinematics(q, u, zero)); + EXPECT_EQ(0, tree2->calculatePositionAndVelocityKinematics(q, u)); + EXPECT_EQ(0, tree2->calculateJacobians(q, u)); - for (int idx = 0; idx < nbodies; idx++) { - vec3 tmp1, tmp2; - vec3 diff; - EXPECT_EQ(0, tree1->getBodyLinearAcceleration(idx, &tmp1)); - EXPECT_EQ(0, tree2->getBodyDotJacobianTransU(idx, &tmp2)); - diff = tmp1 - tmp2; - double lin_error = maxAbs(diff); + for (int idx = 0; idx < nbodies; idx++) + { + vec3 tmp1, tmp2; + vec3 diff; + EXPECT_EQ(0, tree1->getBodyLinearAcceleration(idx, &tmp1)); + EXPECT_EQ(0, tree2->getBodyDotJacobianTransU(idx, &tmp2)); + diff = tmp1 - tmp2; + double lin_error = maxAbs(diff); - if (lin_error > max_lin_error) { - max_lin_error = lin_error; - } + if (lin_error > max_lin_error) + { + max_lin_error = lin_error; + } - EXPECT_EQ(0, tree1->getBodyAngularAcceleration(idx, &tmp1)); - EXPECT_EQ(0, tree2->getBodyDotJacobianRotU(idx, &tmp2)); - diff = tmp1 - tmp2; - double ang_error = maxAbs(diff); - if (ang_error > max_ang_error) { - max_ang_error = ang_error; - } - } - } - *max_error = max_ang_error > max_lin_error ? max_ang_error : max_lin_error; + EXPECT_EQ(0, tree1->getBodyAngularAcceleration(idx, &tmp1)); + EXPECT_EQ(0, tree2->getBodyDotJacobianRotU(idx, &tmp2)); + diff = tmp1 - tmp2; + double ang_error = maxAbs(diff); + if (ang_error > max_ang_error) + { + max_ang_error = ang_error; + } + } + } + *max_error = max_ang_error > max_lin_error ? max_ang_error : max_lin_error; } void calculateJacobianError(const MultiBodyTreeCreator& creator, const int nloops, - double* max_error) { - // tree1 is used as reference to compute the Jacobian from velocities with unit u vectors. - ptr tree1(CreateMultiBodyTree(creator)); - ASSERT_TRUE(0x0 != tree1); - // tree2 is used to compute the Jacobians using the calculateJacobian function - CloneTreeCreator clone(tree1.get()); - ptr tree2(CreateMultiBodyTree(clone)); - ASSERT_TRUE(0x0 != tree2); + double* max_error) +{ + // tree1 is used as reference to compute the Jacobian from velocities with unit u vectors. + ptr tree1(CreateMultiBodyTree(creator)); + ASSERT_TRUE(0x0 != tree1); + // tree2 is used to compute the Jacobians using the calculateJacobian function + CloneTreeCreator clone(tree1.get()); + ptr tree2(CreateMultiBodyTree(clone)); + ASSERT_TRUE(0x0 != tree2); - const int ndofs = tree1->numDoFs(); - const int nbodies = tree1->numBodies(); + const int ndofs = tree1->numDoFs(); + const int nbodies = tree1->numBodies(); - if (ndofs <= 0) { - *max_error = 0; - return; - } + if (ndofs <= 0) + { + *max_error = 0; + return; + } - vecx q(ndofs); - vecx zero(ndofs); - setZero(zero); - vecx one(ndofs); + vecx q(ndofs); + vecx zero(ndofs); + setZero(zero); + vecx one(ndofs); - double max_lin_error = 0; - double max_ang_error = 0; + double max_lin_error = 0; + double max_ang_error = 0; - for (int loop = 0; loop < nloops; loop++) { - for (int i = 0; i < q.size(); i++) { - q(i) = b3RandRange(-B3_PI, B3_PI); - } + for (int loop = 0; loop < nloops; loop++) + { + for (int i = 0; i < q.size(); i++) + { + q(i) = b3RandRange(-B3_PI, B3_PI); + } - EXPECT_EQ(0, tree2->calculatePositionKinematics(q)); - EXPECT_EQ(0, tree2->calculateJacobians(q)); + EXPECT_EQ(0, tree2->calculatePositionKinematics(q)); + EXPECT_EQ(0, tree2->calculateJacobians(q)); - for (int idx = 0; idx < nbodies; idx++) { - mat3x ref_jac_r(3, ndofs); - mat3x ref_jac_t(3, ndofs); - ref_jac_r.setZero(); - ref_jac_t.setZero(); - // this re-computes all jacobians for every body ... - // but avoids std::vector issues - for (int col = 0; col < ndofs; col++) { - setZero(one); - one(col) = 1.0; - EXPECT_EQ(0, tree1->calculatePositionAndVelocityKinematics(q, one)); - vec3 vel, omg; - EXPECT_EQ(0, tree1->getBodyLinearVelocity(idx, &vel)); - EXPECT_EQ(0, tree1->getBodyAngularVelocity(idx, &omg)); - setMat3xElem(0, col, omg(0), &ref_jac_r); - setMat3xElem(1, col, omg(1), &ref_jac_r); - setMat3xElem(2, col, omg(2), &ref_jac_r); - setMat3xElem(0, col, vel(0), &ref_jac_t); - setMat3xElem(1, col, vel(1), &ref_jac_t); - setMat3xElem(2, col, vel(2), &ref_jac_t); - } + for (int idx = 0; idx < nbodies; idx++) + { + mat3x ref_jac_r(3, ndofs); + mat3x ref_jac_t(3, ndofs); + ref_jac_r.setZero(); + ref_jac_t.setZero(); + // this re-computes all jacobians for every body ... + // but avoids std::vector issues + for (int col = 0; col < ndofs; col++) + { + setZero(one); + one(col) = 1.0; + EXPECT_EQ(0, tree1->calculatePositionAndVelocityKinematics(q, one)); + vec3 vel, omg; + EXPECT_EQ(0, tree1->getBodyLinearVelocity(idx, &vel)); + EXPECT_EQ(0, tree1->getBodyAngularVelocity(idx, &omg)); + setMat3xElem(0, col, omg(0), &ref_jac_r); + setMat3xElem(1, col, omg(1), &ref_jac_r); + setMat3xElem(2, col, omg(2), &ref_jac_r); + setMat3xElem(0, col, vel(0), &ref_jac_t); + setMat3xElem(1, col, vel(1), &ref_jac_t); + setMat3xElem(2, col, vel(2), &ref_jac_t); + } - mat3x jac_r(3, ndofs); - mat3x jac_t(3, ndofs); - mat3x diff(3, ndofs); + mat3x jac_r(3, ndofs); + mat3x jac_t(3, ndofs); + mat3x diff(3, ndofs); - EXPECT_EQ(0, tree2->getBodyJacobianTrans(idx, &jac_t)); - EXPECT_EQ(0, tree2->getBodyJacobianRot(idx, &jac_r)); - sub(ref_jac_t,jac_t,&diff); - double lin_error = maxAbsMat3x(diff); - if (lin_error > max_lin_error) { - max_lin_error = lin_error; - } - sub(ref_jac_r, jac_r,&diff); - double ang_error = maxAbsMat3x(diff); - if (ang_error > max_ang_error) { - max_ang_error = ang_error; - } - } - } - *max_error = max_ang_error > max_lin_error ? max_ang_error : max_lin_error; + EXPECT_EQ(0, tree2->getBodyJacobianTrans(idx, &jac_t)); + EXPECT_EQ(0, tree2->getBodyJacobianRot(idx, &jac_r)); + sub(ref_jac_t, jac_t, &diff); + double lin_error = maxAbsMat3x(diff); + if (lin_error > max_lin_error) + { + max_lin_error = lin_error; + } + sub(ref_jac_r, jac_r, &diff); + double ang_error = maxAbsMat3x(diff); + if (ang_error > max_ang_error) + { + max_ang_error = ang_error; + } + } + } + *max_error = max_ang_error > max_lin_error ? max_ang_error : max_lin_error; } void calculateVelocityJacobianError(const MultiBodyTreeCreator& creator, const int nloops, - double* max_error) { - // tree1 is used as reference to compute the velocities directly - ptr tree1(CreateMultiBodyTree(creator)); - ASSERT_TRUE(0x0 != tree1); - // tree2 is used to compute the velocities via jacobians - CloneTreeCreator clone(tree1.get()); - ptr tree2(CreateMultiBodyTree(clone)); - ASSERT_TRUE(0x0 != tree2); + double* max_error) +{ + // tree1 is used as reference to compute the velocities directly + ptr tree1(CreateMultiBodyTree(creator)); + ASSERT_TRUE(0x0 != tree1); + // tree2 is used to compute the velocities via jacobians + CloneTreeCreator clone(tree1.get()); + ptr tree2(CreateMultiBodyTree(clone)); + ASSERT_TRUE(0x0 != tree2); - const int ndofs = tree1->numDoFs(); - const int nbodies = tree1->numBodies(); + const int ndofs = tree1->numDoFs(); + const int nbodies = tree1->numBodies(); - if (ndofs <= 0) { - *max_error = 0; - return; - } + if (ndofs <= 0) + { + *max_error = 0; + return; + } - vecx q(ndofs); - vecx u(ndofs); + vecx q(ndofs); + vecx u(ndofs); - double max_lin_error = 0; - double max_ang_error = 0; + double max_lin_error = 0; + double max_ang_error = 0; - for (int loop = 0; loop < nloops; loop++) { - for (int i = 0; i < q.size(); i++) { - q(i) = b3RandRange(-B3_PI, B3_PI); - u(i) = b3RandRange(-B3_PI, B3_PI); - } + for (int loop = 0; loop < nloops; loop++) + { + for (int i = 0; i < q.size(); i++) + { + q(i) = b3RandRange(-B3_PI, B3_PI); + u(i) = b3RandRange(-B3_PI, B3_PI); + } - EXPECT_EQ(0, tree1->calculatePositionAndVelocityKinematics(q, u)); - EXPECT_EQ(0, tree2->calculatePositionKinematics(q)); - EXPECT_EQ(0, tree2->calculateJacobians(q)); + EXPECT_EQ(0, tree1->calculatePositionAndVelocityKinematics(q, u)); + EXPECT_EQ(0, tree2->calculatePositionKinematics(q)); + EXPECT_EQ(0, tree2->calculateJacobians(q)); - for (int idx = 0; idx < nbodies; idx++) { - vec3 vel1; - vec3 omg1; - vec3 vel2; - vec3 omg2; - mat3x jac_r2(3, ndofs); - mat3x jac_t2(3, ndofs); + for (int idx = 0; idx < nbodies; idx++) + { + vec3 vel1; + vec3 omg1; + vec3 vel2; + vec3 omg2; + mat3x jac_r2(3, ndofs); + mat3x jac_t2(3, ndofs); - EXPECT_EQ(0, tree1->getBodyLinearVelocity(idx, &vel1)); - EXPECT_EQ(0, tree1->getBodyAngularVelocity(idx, &omg1)); - EXPECT_EQ(0, tree2->getBodyJacobianTrans(idx, &jac_t2)); - EXPECT_EQ(0, tree2->getBodyJacobianRot(idx, &jac_r2)); - omg2 = jac_r2 * u; - vel2 = jac_t2 * u; + EXPECT_EQ(0, tree1->getBodyLinearVelocity(idx, &vel1)); + EXPECT_EQ(0, tree1->getBodyAngularVelocity(idx, &omg1)); + EXPECT_EQ(0, tree2->getBodyJacobianTrans(idx, &jac_t2)); + EXPECT_EQ(0, tree2->getBodyJacobianRot(idx, &jac_r2)); + omg2 = jac_r2 * u; + vel2 = jac_t2 * u; - double lin_error = maxAbs(vel1 - vel2); - if (lin_error > max_lin_error) { - max_lin_error = lin_error; - } - double ang_error = maxAbs(omg1 - omg2); - if (ang_error > max_ang_error) { - max_ang_error = ang_error; - } - } - } - *max_error = max_ang_error > max_lin_error ? max_ang_error : max_lin_error; + double lin_error = maxAbs(vel1 - vel2); + if (lin_error > max_lin_error) + { + max_lin_error = lin_error; + } + double ang_error = maxAbs(omg1 - omg2); + if (ang_error > max_ang_error) + { + max_ang_error = ang_error; + } + } + } + *max_error = max_ang_error > max_lin_error ? max_ang_error : max_lin_error; } // test nonlinear terms: dot(Jacobian)*u (linear and angular acceleration for dot_u ==0) // from Jacobian calculation method and pseudo-numerically using via the kinematics method. -TEST(InvDynJacobians, JacDotJacU) { - const int kNumLevels = 5; -#ifdef B3_USE_DOUBLE_PRECISION - const double kMaxError = 1e-12; -#else - const double kMaxError = 5e-5; -#endif - const int kNumLoops = 20; - for (int level = 0; level < kNumLevels; level++) { - const int nbodies = BT_ID_POW(2, level); - CoilCreator coil(nbodies); - double error; - calculateDotJacUError(coil, kNumLoops, &error); - EXPECT_GT(kMaxError, error); - DillCreator dill(level); - calculateDotJacUError(dill, kNumLoops, &error); - EXPECT_GT(kMaxError, error); - } - - const int kRandomLoops = 100; - const int kMaxRandomBodies = 128; - for (int loop = 0; loop < kRandomLoops; loop++) { - RandomTreeCreator random(kMaxRandomBodies); - double error; - calculateDotJacUError(random, kNumLoops, &error); - EXPECT_GT(kMaxError, error); - } -} - -// Jacobians: linear and angular acceleration for dot_u ==0 -// from Jacobian calculation method and pseudo-numerically using via the kinematics method. -TEST(InvDynJacobians, Jacobians) { - const int kNumLevels = 5; +TEST(InvDynJacobians, JacDotJacU) +{ + const int kNumLevels = 5; #ifdef B3_USE_DOUBLE_PRECISION const double kMaxError = 1e-12; #else const double kMaxError = 5e-5; #endif const int kNumLoops = 20; - for (int level = 0; level < kNumLevels; level++) { - const int nbodies = BT_ID_POW(2, level); - CoilCreator coil(nbodies); - double error; - calculateJacobianError(coil, kNumLoops, &error); - EXPECT_GT(kMaxError, error); - DillCreator dill(level); - calculateDotJacUError(dill, kNumLoops, &error); - EXPECT_GT(kMaxError, error); - } - const int kRandomLoops = 20; - const int kMaxRandomBodies = 16; - for (int loop = 0; loop < kRandomLoops; loop++) { - RandomTreeCreator random(kMaxRandomBodies); - double error; - calculateJacobianError(random, kNumLoops, &error); - EXPECT_GT(kMaxError, error); - } + for (int level = 0; level < kNumLevels; level++) + { + const int nbodies = BT_ID_POW(2, level); + CoilCreator coil(nbodies); + double error; + calculateDotJacUError(coil, kNumLoops, &error); + EXPECT_GT(kMaxError, error); + DillCreator dill(level); + calculateDotJacUError(dill, kNumLoops, &error); + EXPECT_GT(kMaxError, error); + } + + const int kRandomLoops = 100; + const int kMaxRandomBodies = 128; + for (int loop = 0; loop < kRandomLoops; loop++) + { + RandomTreeCreator random(kMaxRandomBodies); + double error; + calculateDotJacUError(random, kNumLoops, &error); + EXPECT_GT(kMaxError, error); + } } -// test for jacobian*u == velocity -TEST(InvDynJacobians, VelocitiesFromJacobians) { - const int kRandomLoops = 20; - const int kMaxRandomBodies = 16; - const int kNumLoops = 20; +// Jacobians: linear and angular acceleration for dot_u ==0 +// from Jacobian calculation method and pseudo-numerically using via the kinematics method. +TEST(InvDynJacobians, Jacobians) +{ + const int kNumLevels = 5; #ifdef B3_USE_DOUBLE_PRECISION const double kMaxError = 1e-12; #else const double kMaxError = 5e-5; #endif - for (int loop = 0; loop < kRandomLoops; loop++) { - RandomTreeCreator random(kMaxRandomBodies); - double error; - calculateVelocityJacobianError(random, kNumLoops, &error); - EXPECT_GT(kMaxError, error); - } + const int kNumLoops = 20; + for (int level = 0; level < kNumLevels; level++) + { + const int nbodies = BT_ID_POW(2, level); + CoilCreator coil(nbodies); + double error; + calculateJacobianError(coil, kNumLoops, &error); + EXPECT_GT(kMaxError, error); + DillCreator dill(level); + calculateDotJacUError(dill, kNumLoops, &error); + EXPECT_GT(kMaxError, error); + } + const int kRandomLoops = 20; + const int kMaxRandomBodies = 16; + for (int loop = 0; loop < kRandomLoops; loop++) + { + RandomTreeCreator random(kMaxRandomBodies); + double error; + calculateJacobianError(random, kNumLoops, &error); + EXPECT_GT(kMaxError, error); + } +} + +// test for jacobian*u == velocity +TEST(InvDynJacobians, VelocitiesFromJacobians) +{ + const int kRandomLoops = 20; + const int kMaxRandomBodies = 16; + const int kNumLoops = 20; +#ifdef B3_USE_DOUBLE_PRECISION + const double kMaxError = 1e-12; +#else + const double kMaxError = 5e-5; +#endif + for (int loop = 0; loop < kRandomLoops; loop++) + { + RandomTreeCreator random(kMaxRandomBodies); + double error; + calculateVelocityJacobianError(random, kNumLoops, &error); + EXPECT_GT(kMaxError, error); + } } #endif -int main(int argc, char** argv) { +int main(int argc, char** argv) +{ b3Srand(1234); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); } diff --git a/test/InverseDynamics/test_invdyn_kinematics.cpp b/test/InverseDynamics/test_invdyn_kinematics.cpp index 697691360..2fab4d048 100644 --- a/test/InverseDynamics/test_invdyn_kinematics.cpp +++ b/test/InverseDynamics/test_invdyn_kinematics.cpp @@ -23,8 +23,9 @@ template idScalar calculateNorm(T&); // only implemented for vec3 template <> -idScalar calculateNorm(vec3& v) { - return BT_ID_SQRT(BT_ID_POW(v(0), 2) + BT_ID_POW(v(1), 2) + BT_ID_POW(v(2), 2)); +idScalar calculateNorm(vec3& v) +{ + return BT_ID_SQRT(BT_ID_POW(v(0), 2) + BT_ID_POW(v(1), 2) + BT_ID_POW(v(2), 2)); } // template function to convert a DiffType (finite differences) @@ -35,21 +36,23 @@ DiffType toDiffType(ValueType& fd, ValueType& val); // vector case: just return finite difference approximation template <> -vec3 toDiffType(vec3& fd, vec3& val) { - return fd; +vec3 toDiffType(vec3& fd, vec3& val) +{ + return fd; } // orientation case: calculate spin tensor and extract angular velocity template <> -vec3 toDiffType(mat33& fd, mat33& val) { - // spin tensor - mat33 omega_tilde = fd * val.transpose(); - // extract vector from spin tensor - vec3 omega; - omega(0) = 0.5 * (omega_tilde(2, 1) - omega_tilde(1, 2)); - omega(1) = 0.5 * (omega_tilde(0, 2) - omega_tilde(2, 0)); - omega(2) = 0.5 * (omega_tilde(1, 0) - omega_tilde(0, 1)); - return omega; +vec3 toDiffType(mat33& fd, mat33& val) +{ + // spin tensor + mat33 omega_tilde = fd * val.transpose(); + // extract vector from spin tensor + vec3 omega; + omega(0) = 0.5 * (omega_tilde(2, 1) - omega_tilde(1, 2)); + omega(1) = 0.5 * (omega_tilde(0, 2) - omega_tilde(2, 0)); + omega(2) = 0.5 * (omega_tilde(1, 0) - omega_tilde(0, 1)); + return omega; } /// Class for calculating finite difference approximation @@ -57,290 +60,317 @@ vec3 toDiffType(mat33& fd, mat33& val) { /// DiffType and ValueType can be different, to allow comparison /// of angular velocity vectors and orientations given as transform matrices. template -class DiffFD { +class DiffFD +{ public: - DiffFD() : m_dt(0.0), m_num_updates(0), m_max_error(0.0), m_max_value(0.0), m_valid_fd(false) {} + DiffFD() : m_dt(0.0), m_num_updates(0), m_max_error(0.0), m_max_value(0.0), m_valid_fd(false) {} - void init(std::string name, idScalar dt) { - m_name = name; - m_dt = dt; - m_num_updates = 0; - m_max_error = 0.0; - m_max_value = 0.0; - m_valid_fd = false; - } + void init(std::string name, idScalar dt) + { + m_name = name; + m_dt = dt; + m_num_updates = 0; + m_max_error = 0.0; + m_max_value = 0.0; + m_valid_fd = false; + } - void update(const ValueType& val, const DiffType& true_diff) { - m_val = val; - if (m_num_updates > 2) { - // 2nd order finite difference approximation for d(value)/dt - ValueType diff_value_fd = (val - m_older_val) / (2.0 * m_dt); - // convert to analytical diff type. This is for angular velocities - m_diff_fd = toDiffType(diff_value_fd, m_old_val); - // now, calculate the error - DiffType error_value_type = m_diff_fd - m_old_true_diff; - idScalar error = calculateNorm(error_value_type); - if (error > m_max_error) { - m_max_error = error; - } + void update(const ValueType& val, const DiffType& true_diff) + { + m_val = val; + if (m_num_updates > 2) + { + // 2nd order finite difference approximation for d(value)/dt + ValueType diff_value_fd = (val - m_older_val) / (2.0 * m_dt); + // convert to analytical diff type. This is for angular velocities + m_diff_fd = toDiffType(diff_value_fd, m_old_val); + // now, calculate the error + DiffType error_value_type = m_diff_fd - m_old_true_diff; + idScalar error = calculateNorm(error_value_type); + if (error > m_max_error) + { + m_max_error = error; + } - idScalar value = calculateNorm(m_old_true_diff); - if (value > m_max_value) { - m_max_value = value; - } + idScalar value = calculateNorm(m_old_true_diff); + if (value > m_max_value) + { + m_max_value = value; + } - m_valid_fd = true; - } - m_older_val = m_old_val; - m_old_val = m_val; - m_old_true_diff = true_diff; - m_num_updates++; - m_time += m_dt; - } + m_valid_fd = true; + } + m_older_val = m_old_val; + m_old_val = m_val; + m_old_true_diff = true_diff; + m_num_updates++; + m_time += m_dt; + } - void printMaxError() { - printf("max_error: %e dt= %e max_value= %e fraction= %e\n", m_max_error, m_dt, m_max_value, - m_max_value > 0.0 ? m_max_error / m_max_value : 0.0); - } - void printCurrent() { - if (m_valid_fd) { - // note: m_old_true_diff already equals m_true_diff here, so values are not aligned. - // (but error calculation takes this into account) - printf("%s time: %e fd: %e %e %e true: %e %e %e\n", m_name.c_str(), m_time, - m_diff_fd(0), m_diff_fd(1), m_diff_fd(2), m_old_true_diff(0), m_old_true_diff(1), - m_old_true_diff(2)); - } - } + void printMaxError() + { + printf("max_error: %e dt= %e max_value= %e fraction= %e\n", m_max_error, m_dt, m_max_value, + m_max_value > 0.0 ? m_max_error / m_max_value : 0.0); + } + void printCurrent() + { + if (m_valid_fd) + { + // note: m_old_true_diff already equals m_true_diff here, so values are not aligned. + // (but error calculation takes this into account) + printf("%s time: %e fd: %e %e %e true: %e %e %e\n", m_name.c_str(), m_time, + m_diff_fd(0), m_diff_fd(1), m_diff_fd(2), m_old_true_diff(0), m_old_true_diff(1), + m_old_true_diff(2)); + } + } - idScalar getMaxError() const { return m_max_error; } - idScalar getMaxValue() const { return m_max_value; } + idScalar getMaxError() const { return m_max_error; } + idScalar getMaxValue() const { return m_max_value; } private: - idScalar m_dt; - ValueType m_val; - ValueType m_old_val; - ValueType m_older_val; - DiffType m_old_true_diff; - DiffType m_diff_fd; - int m_num_updates; - idScalar m_max_error; - idScalar m_max_value; - idScalar m_time; - std::string m_name; - bool m_valid_fd; + idScalar m_dt; + ValueType m_val; + ValueType m_old_val; + ValueType m_older_val; + DiffType m_old_true_diff; + DiffType m_diff_fd; + int m_num_updates; + idScalar m_max_error; + idScalar m_max_value; + idScalar m_time; + std::string m_name; + bool m_valid_fd; }; template -class VecDiffFD { +class VecDiffFD +{ public: - VecDiffFD(std::string name, int dim, idScalar dt) : m_name(name), m_fd(dim), m_dt(dt) { - for (int i = 0; i < m_fd.size(); i++) { - char buf[256]; - BT_ID_SNPRINTF(buf, 256, "%s-%.2d", name.c_str(), i); - m_fd[i].init(buf, dt); - } - } - void update(int i, ValueType& val, DiffType& true_diff) { m_fd[i].update(val, true_diff); } - idScalar getMaxError() const { - idScalar max_error = 0; - for (int i = 0; i < m_fd.size(); i++) { - const idScalar error = m_fd[i].getMaxError(); - if (error > max_error) { - max_error = error; - } - } - return max_error; - } - idScalar getMaxValue() const { - idScalar max_value = 0; - for (int i = 0; i < m_fd.size(); i++) { - const idScalar value = m_fd[i].getMaxValue(); - if (value > max_value) { - max_value= value; - } - } - return max_value; - } - void printMaxError() { - printf("%s: total dt= %e max_error= %e\n", m_name.c_str(), m_dt, getMaxError()); - } + VecDiffFD(std::string name, int dim, idScalar dt) : m_name(name), m_fd(dim), m_dt(dt) + { + for (int i = 0; i < m_fd.size(); i++) + { + char buf[256]; + BT_ID_SNPRINTF(buf, 256, "%s-%.2d", name.c_str(), i); + m_fd[i].init(buf, dt); + } + } + void update(int i, ValueType& val, DiffType& true_diff) { m_fd[i].update(val, true_diff); } + idScalar getMaxError() const + { + idScalar max_error = 0; + for (int i = 0; i < m_fd.size(); i++) + { + const idScalar error = m_fd[i].getMaxError(); + if (error > max_error) + { + max_error = error; + } + } + return max_error; + } + idScalar getMaxValue() const + { + idScalar max_value = 0; + for (int i = 0; i < m_fd.size(); i++) + { + const idScalar value = m_fd[i].getMaxValue(); + if (value > max_value) + { + max_value = value; + } + } + return max_value; + } + void printMaxError() + { + printf("%s: total dt= %e max_error= %e\n", m_name.c_str(), m_dt, getMaxError()); + } - void printCurrent() { - for (int i = 0; i < m_fd.size(); i++) { - m_fd[i].printCurrent(); - } - } + void printCurrent() + { + for (int i = 0; i < m_fd.size(); i++) + { + m_fd[i].printCurrent(); + } + } private: - std::string m_name; - std::vector > m_fd; - const idScalar m_dt; - idScalar m_max_error; + std::string m_name; + std::vector > m_fd; + const idScalar m_dt; + idScalar m_max_error; }; // calculate maximum difference between finite difference and analytical differentiation int calculateDifferentiationError(const MultiBodyTreeCreator& creator, idScalar deltaT, - idScalar endTime, idScalar* max_linear_velocity_error, - idScalar* max_angular_velocity_error, - idScalar* max_linear_acceleration_error, - idScalar* max_angular_acceleration_error) { - // setup system - MultiBodyTree* tree = CreateMultiBodyTree(creator); - if (0x0 == tree) { - return -1; - } - // set gravity to zero, so nothing is added to accelerations in forward kinematics - vec3 gravity_zero; - gravity_zero(0) = 0; - gravity_zero(1) = 0; - gravity_zero(2) = 0; - tree->setGravityInWorldFrame(gravity_zero); - // - const idScalar kAmplitude = 1.0; - const idScalar kFrequency = 1.0; + idScalar endTime, idScalar* max_linear_velocity_error, + idScalar* max_angular_velocity_error, + idScalar* max_linear_acceleration_error, + idScalar* max_angular_acceleration_error) +{ + // setup system + MultiBodyTree* tree = CreateMultiBodyTree(creator); + if (0x0 == tree) + { + return -1; + } + // set gravity to zero, so nothing is added to accelerations in forward kinematics + vec3 gravity_zero; + gravity_zero(0) = 0; + gravity_zero(1) = 0; + gravity_zero(2) = 0; + tree->setGravityInWorldFrame(gravity_zero); + // + const idScalar kAmplitude = 1.0; + const idScalar kFrequency = 1.0; - vecx q(tree->numDoFs()); - vecx dot_q(tree->numDoFs()); - vecx ddot_q(tree->numDoFs()); - vecx joint_forces(tree->numDoFs()); + vecx q(tree->numDoFs()); + vecx dot_q(tree->numDoFs()); + vecx ddot_q(tree->numDoFs()); + vecx joint_forces(tree->numDoFs()); - VecDiffFD fd_vel("linear-velocity", tree->numBodies(), deltaT); - VecDiffFD fd_acc("linear-acceleration", tree->numBodies(), deltaT); - VecDiffFD fd_omg("angular-velocity", tree->numBodies(), deltaT); - VecDiffFD fd_omgd("angular-acceleration", tree->numBodies(), deltaT); + VecDiffFD fd_vel("linear-velocity", tree->numBodies(), deltaT); + VecDiffFD fd_acc("linear-acceleration", tree->numBodies(), deltaT); + VecDiffFD fd_omg("angular-velocity", tree->numBodies(), deltaT); + VecDiffFD fd_omgd("angular-acceleration", tree->numBodies(), deltaT); - for (idScalar t = 0.0; t < endTime; t += deltaT) { - for (int body = 0; body < tree->numBodies(); body++) { - q(body) = kAmplitude * sin(t * 2.0 * BT_ID_PI * kFrequency); - dot_q(body) = kAmplitude * 2.0 * BT_ID_PI * kFrequency * cos(t * 2.0 * BT_ID_PI * kFrequency); - ddot_q(body) = - -kAmplitude * pow(2.0 * BT_ID_PI * kFrequency, 2) * sin(t * 2.0 * BT_ID_PI * kFrequency); - } + for (idScalar t = 0.0; t < endTime; t += deltaT) + { + for (int body = 0; body < tree->numBodies(); body++) + { + q(body) = kAmplitude * sin(t * 2.0 * BT_ID_PI * kFrequency); + dot_q(body) = kAmplitude * 2.0 * BT_ID_PI * kFrequency * cos(t * 2.0 * BT_ID_PI * kFrequency); + ddot_q(body) = + -kAmplitude * pow(2.0 * BT_ID_PI * kFrequency, 2) * sin(t * 2.0 * BT_ID_PI * kFrequency); + } - if (-1 == tree->calculateInverseDynamics(q, dot_q, ddot_q, &joint_forces)) { - delete tree; - return -1; - } + if (-1 == tree->calculateInverseDynamics(q, dot_q, ddot_q, &joint_forces)) + { + delete tree; + return -1; + } - // position/velocity - for (int body = 0; body < tree->numBodies(); body++) { - vec3 pos; - vec3 vel; - mat33 world_T_body; - vec3 omega; - vec3 dot_omega; - vec3 acc; + // position/velocity + for (int body = 0; body < tree->numBodies(); body++) + { + vec3 pos; + vec3 vel; + mat33 world_T_body; + vec3 omega; + vec3 dot_omega; + vec3 acc; - tree->getBodyOrigin(body, &pos); - tree->getBodyTransform(body, &world_T_body); - tree->getBodyLinearVelocity(body, &vel); - tree->getBodyAngularVelocity(body, &omega); - tree->getBodyLinearAcceleration(body, &acc); - tree->getBodyAngularAcceleration(body, &dot_omega); + tree->getBodyOrigin(body, &pos); + tree->getBodyTransform(body, &world_T_body); + tree->getBodyLinearVelocity(body, &vel); + tree->getBodyAngularVelocity(body, &omega); + tree->getBodyLinearAcceleration(body, &acc); + tree->getBodyAngularAcceleration(body, &dot_omega); - fd_vel.update(body, pos, vel); - fd_omg.update(body, world_T_body, omega); - fd_acc.update(body, vel, acc); - fd_omgd.update(body, omega, dot_omega); + fd_vel.update(body, pos, vel); + fd_omg.update(body, world_T_body, omega); + fd_acc.update(body, vel, acc); + fd_omgd.update(body, omega, dot_omega); + // fd_vel.printCurrent(); + //fd_acc.printCurrent(); + //fd_omg.printCurrent(); + //fd_omgd.printCurrent(); + } + } -// fd_vel.printCurrent(); -//fd_acc.printCurrent(); -//fd_omg.printCurrent(); -//fd_omgd.printCurrent(); - } - } + *max_linear_velocity_error = fd_vel.getMaxError() / fd_vel.getMaxValue(); + *max_angular_velocity_error = fd_omg.getMaxError() / fd_omg.getMaxValue(); + *max_linear_acceleration_error = fd_acc.getMaxError() / fd_acc.getMaxValue(); + *max_angular_acceleration_error = fd_omgd.getMaxError() / fd_omgd.getMaxValue(); - *max_linear_velocity_error = fd_vel.getMaxError()/fd_vel.getMaxValue(); - *max_angular_velocity_error = fd_omg.getMaxError()/fd_omg.getMaxValue(); - *max_linear_acceleration_error = fd_acc.getMaxError()/fd_acc.getMaxValue(); - *max_angular_acceleration_error = fd_omgd.getMaxError()/fd_omgd.getMaxValue(); - - delete tree; - return 0; + delete tree; + return 0; } // first test: absolute difference between numerical and numerial // differentiation should be small -TEST(InvDynKinematicsDifferentiation, errorAbsolute) { - //CAVEAT:these values are hand-tuned to work for the specific trajectory defined above. +TEST(InvDynKinematicsDifferentiation, errorAbsolute) +{ + //CAVEAT:these values are hand-tuned to work for the specific trajectory defined above. #ifdef BT_ID_USE_DOUBLE_PRECISION - const idScalar kDeltaT = 1e-7; + const idScalar kDeltaT = 1e-7; const idScalar kAcceptableError = 1e-4; #else - const idScalar kDeltaT = 1e-4; + const idScalar kDeltaT = 1e-4; const idScalar kAcceptableError = 5e-3; #endif - const idScalar kDuration = 0.01; - + const idScalar kDuration = 0.01; - CoilCreator coil_creator(kNumBodies); - DillCreator dill_creator(kLevel); - SimpleTreeCreator simple_creator(kNumBodies); + CoilCreator coil_creator(kNumBodies); + DillCreator dill_creator(kLevel); + SimpleTreeCreator simple_creator(kNumBodies); - idScalar max_linear_velocity_error; - idScalar max_angular_velocity_error; - idScalar max_linear_acceleration_error; - idScalar max_angular_acceleration_error; + idScalar max_linear_velocity_error; + idScalar max_angular_velocity_error; + idScalar max_linear_acceleration_error; + idScalar max_angular_acceleration_error; - // test serial chain - calculateDifferentiationError(coil_creator, kDeltaT, kDuration, &max_linear_velocity_error, - &max_angular_velocity_error, &max_linear_acceleration_error, - &max_angular_acceleration_error); + // test serial chain + calculateDifferentiationError(coil_creator, kDeltaT, kDuration, &max_linear_velocity_error, + &max_angular_velocity_error, &max_linear_acceleration_error, + &max_angular_acceleration_error); - EXPECT_LT(max_linear_velocity_error, kAcceptableError); - EXPECT_LT(max_angular_velocity_error, kAcceptableError); - EXPECT_LT(max_linear_acceleration_error, kAcceptableError); - EXPECT_LT(max_angular_acceleration_error, kAcceptableError); + EXPECT_LT(max_linear_velocity_error, kAcceptableError); + EXPECT_LT(max_angular_velocity_error, kAcceptableError); + EXPECT_LT(max_linear_acceleration_error, kAcceptableError); + EXPECT_LT(max_angular_acceleration_error, kAcceptableError); - // test branched tree - calculateDifferentiationError(dill_creator, kDeltaT, kDuration, &max_linear_velocity_error, - &max_angular_velocity_error, &max_linear_acceleration_error, - &max_angular_acceleration_error); + // test branched tree + calculateDifferentiationError(dill_creator, kDeltaT, kDuration, &max_linear_velocity_error, + &max_angular_velocity_error, &max_linear_acceleration_error, + &max_angular_acceleration_error); - EXPECT_LT(max_linear_velocity_error, kAcceptableError); - EXPECT_LT(max_angular_velocity_error, kAcceptableError); - EXPECT_LT(max_linear_acceleration_error, kAcceptableError); - EXPECT_LT(max_angular_acceleration_error, kAcceptableError); + EXPECT_LT(max_linear_velocity_error, kAcceptableError); + EXPECT_LT(max_angular_velocity_error, kAcceptableError); + EXPECT_LT(max_linear_acceleration_error, kAcceptableError); + EXPECT_LT(max_angular_acceleration_error, kAcceptableError); - // test system with different joint types - calculateDifferentiationError(simple_creator, kDeltaT, kDuration, &max_linear_velocity_error, - &max_angular_velocity_error, &max_linear_acceleration_error, - &max_angular_acceleration_error); + // test system with different joint types + calculateDifferentiationError(simple_creator, kDeltaT, kDuration, &max_linear_velocity_error, + &max_angular_velocity_error, &max_linear_acceleration_error, + &max_angular_acceleration_error); - EXPECT_LT(max_linear_velocity_error, kAcceptableError); - EXPECT_LT(max_angular_velocity_error, kAcceptableError); - EXPECT_LT(max_linear_acceleration_error, kAcceptableError); - EXPECT_LT(max_angular_acceleration_error, kAcceptableError); + EXPECT_LT(max_linear_velocity_error, kAcceptableError); + EXPECT_LT(max_angular_velocity_error, kAcceptableError); + EXPECT_LT(max_linear_acceleration_error, kAcceptableError); + EXPECT_LT(max_angular_acceleration_error, kAcceptableError); } // second test: check if the change in the differentiation error // is consitent with the second order approximation, ie, error ~ O(dt^2) -TEST(InvDynKinematicsDifferentiation, errorOrder) { - const idScalar kDeltaTs[2] = {1e-4, 1e-5}; - const idScalar kDuration = 1e-2; +TEST(InvDynKinematicsDifferentiation, errorOrder) +{ + const idScalar kDeltaTs[2] = {1e-4, 1e-5}; + const idScalar kDuration = 1e-2; - CoilCreator coil_creator(kNumBodies); - // DillCreator dill_creator(kLevel); - // SimpleTreeCreator simple_creator(kNumBodies); + CoilCreator coil_creator(kNumBodies); + // DillCreator dill_creator(kLevel); + // SimpleTreeCreator simple_creator(kNumBodies); - idScalar max_linear_velocity_error[2]; - idScalar max_angular_velocity_error[2]; - idScalar max_linear_acceleration_error[2]; - idScalar max_angular_acceleration_error[2]; + idScalar max_linear_velocity_error[2]; + idScalar max_angular_velocity_error[2]; + idScalar max_linear_acceleration_error[2]; + idScalar max_angular_acceleration_error[2]; - // test serial chain - calculateDifferentiationError(coil_creator, kDeltaTs[0], kDuration, - &max_linear_velocity_error[0], &max_angular_velocity_error[0], - &max_linear_acceleration_error[0], - &max_angular_acceleration_error[0]); + // test serial chain + calculateDifferentiationError(coil_creator, kDeltaTs[0], kDuration, + &max_linear_velocity_error[0], &max_angular_velocity_error[0], + &max_linear_acceleration_error[0], + &max_angular_acceleration_error[0]); - calculateDifferentiationError(coil_creator, kDeltaTs[1], kDuration, - &max_linear_velocity_error[1], &max_angular_velocity_error[1], - &max_linear_acceleration_error[1], - &max_angular_acceleration_error[1]); + calculateDifferentiationError(coil_creator, kDeltaTs[1], kDuration, + &max_linear_velocity_error[1], &max_angular_velocity_error[1], + &max_linear_acceleration_error[1], + &max_angular_acceleration_error[1]); -/* + /* const idScalar expected_linear_velocity_error_1 = max_linear_velocity_error[0] * pow(kDeltaTs[1] / kDeltaTs[0], 2); const idScalar expected_angular_velocity_error_1 = @@ -365,10 +395,10 @@ TEST(InvDynKinematicsDifferentiation, errorOrder) { */ } -int main(int argc, char** argv) { +int main(int argc, char** argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); - - return EXIT_SUCCESS; + return EXIT_SUCCESS; } diff --git a/test/OpenCL/AllBullet3Kernels/initCL.h b/test/OpenCL/AllBullet3Kernels/initCL.h index 4d05971ff..208127ce4 100644 --- a/test/OpenCL/AllBullet3Kernels/initCL.h +++ b/test/OpenCL/AllBullet3Kernels/initCL.h @@ -2,78 +2,67 @@ #ifndef INIT_CL_H #define INIT_CL_H - - - void initCL() - { +{ + int preferredDeviceIndex = -1; + int preferredPlatformIndex = -1; + bool allowCpuOpenCL = false; - int preferredDeviceIndex=-1; - int preferredPlatformIndex=-1; - bool allowCpuOpenCL=false; + b3CommandLineArgs args(gArgc, gArgv); + args.GetCmdLineArgument("cl_device", preferredDeviceIndex); + args.GetCmdLineArgument("cl_platform", preferredPlatformIndex); + allowCpuOpenCL = args.CheckCmdLineFlag("allow_opencl_cpu"); - b3CommandLineArgs args(gArgc,gArgv); - args.GetCmdLineArgument("cl_device", preferredDeviceIndex); - args.GetCmdLineArgument("cl_platform", preferredPlatformIndex); - allowCpuOpenCL = args.CheckCmdLineFlag("allow_opencl_cpu"); - - void* glCtx=0; - void* glDC = 0; - - - - int ciErrNum = 0; + void* glCtx = 0; + void* glDC = 0; - cl_device_type deviceType = CL_DEVICE_TYPE_GPU; - if (allowCpuOpenCL) - deviceType = CL_DEVICE_TYPE_ALL; + int ciErrNum = 0; - - - // if (useInterop) - // { - // m_data->m_clContext = b3OpenCLUtils::createContextFromType(deviceType, &ciErrNum, glCtx, glDC); - // } else - { - m_clContext = b3OpenCLUtils::createContextFromType(deviceType, &ciErrNum, 0,0,preferredDeviceIndex, preferredPlatformIndex,&m_platformId); - ASSERT_FALSE(m_clContext==0); - } - - b3OpenCLPlatformInfo platformInfo; - b3OpenCLUtils::getPlatformInfo(m_platformId,&platformInfo); - b3Printf("OpenCL Platform Name %s\n", platformInfo.m_platformName); - b3Printf("OpenCL Platform Vendor %s\n", platformInfo.m_platformVendor); - b3Printf("OpenCL Platform Version %s\n", platformInfo.m_platformVersion); - - - ASSERT_EQ(ciErrNum, CL_SUCCESS); - - int numDev = b3OpenCLUtils::getNumDevices(m_clContext); - EXPECT_GT(numDev,0); + cl_device_type deviceType = CL_DEVICE_TYPE_GPU; + if (allowCpuOpenCL) + deviceType = CL_DEVICE_TYPE_ALL; - if (numDev>0) - { - m_clDevice= b3OpenCLUtils::getDevice(m_clContext,0); - ASSERT_FALSE(m_clDevice==0); + // if (useInterop) + // { + // m_data->m_clContext = b3OpenCLUtils::createContextFromType(deviceType, &ciErrNum, glCtx, glDC); + // } else + { + m_clContext = b3OpenCLUtils::createContextFromType(deviceType, &ciErrNum, 0, 0, preferredDeviceIndex, preferredPlatformIndex, &m_platformId); + ASSERT_FALSE(m_clContext == 0); + } - m_clQueue = clCreateCommandQueue(m_clContext, m_clDevice, 0, &ciErrNum); - ASSERT_FALSE(m_clQueue==0); - - ASSERT_EQ(ciErrNum, CL_SUCCESS); - - - b3OpenCLDeviceInfo info; - b3OpenCLUtils::getDeviceInfo(m_clDevice,&info); - b3OpenCLUtils::printDeviceInfo(m_clDevice); - m_clDeviceName = info.m_deviceName; - } - } + b3OpenCLPlatformInfo platformInfo; + b3OpenCLUtils::getPlatformInfo(m_platformId, &platformInfo); + b3Printf("OpenCL Platform Name %s\n", platformInfo.m_platformName); + b3Printf("OpenCL Platform Vendor %s\n", platformInfo.m_platformVendor); + b3Printf("OpenCL Platform Version %s\n", platformInfo.m_platformVersion); - void exitCL() - { - clReleaseCommandQueue(m_clQueue); - clReleaseContext(m_clContext); - } + ASSERT_EQ(ciErrNum, CL_SUCCESS); -#endif //INIT_CL_H + int numDev = b3OpenCLUtils::getNumDevices(m_clContext); + EXPECT_GT(numDev, 0); + if (numDev > 0) + { + m_clDevice = b3OpenCLUtils::getDevice(m_clContext, 0); + ASSERT_FALSE(m_clDevice == 0); + + m_clQueue = clCreateCommandQueue(m_clContext, m_clDevice, 0, &ciErrNum); + ASSERT_FALSE(m_clQueue == 0); + + ASSERT_EQ(ciErrNum, CL_SUCCESS); + + b3OpenCLDeviceInfo info; + b3OpenCLUtils::getDeviceInfo(m_clDevice, &info); + b3OpenCLUtils::printDeviceInfo(m_clDevice); + m_clDeviceName = info.m_deviceName; + } +} + +void exitCL() +{ + clReleaseCommandQueue(m_clQueue); + clReleaseContext(m_clContext); +} + +#endif //INIT_CL_H diff --git a/test/OpenCL/AllBullet3Kernels/testCompileBullet3BroadphaseKernels.cpp b/test/OpenCL/AllBullet3Kernels/testCompileBullet3BroadphaseKernels.cpp index ff8ac0096..40ea6aabd 100644 --- a/test/OpenCL/AllBullet3Kernels/testCompileBullet3BroadphaseKernels.cpp +++ b/test/OpenCL/AllBullet3Kernels/testCompileBullet3BroadphaseKernels.cpp @@ -11,157 +11,147 @@ extern char** gArgv; namespace { - struct CompileBullet3BroadphaseKernels : public ::testing::Test +struct CompileBullet3BroadphaseKernels : public ::testing::Test +{ + cl_context m_clContext; + cl_device_id m_clDevice; + cl_command_queue m_clQueue; + char* m_clDeviceName; + cl_platform_id m_platformId; + + CompileBullet3BroadphaseKernels() + : m_clDeviceName(0), + m_clContext(0), + m_clDevice(0), + m_clQueue(0), + m_platformId(0) { - cl_context m_clContext; - cl_device_id m_clDevice; - cl_command_queue m_clQueue; - char* m_clDeviceName; - cl_platform_id m_platformId; + // You can do set-up work for each test here. + b3CommandLineArgs args(gArgc, gArgv); + int preferredDeviceIndex = -1; + int preferredPlatformIndex = -1; + bool allowCpuOpenCL = false; - CompileBullet3BroadphaseKernels() - :m_clDeviceName(0), - m_clContext(0), - m_clDevice(0), - m_clQueue(0), - m_platformId(0) - { - // You can do set-up work for each test here. - b3CommandLineArgs args(gArgc,gArgv); - int preferredDeviceIndex=-1; - int preferredPlatformIndex = -1; - bool allowCpuOpenCL = false; + initCL(); + } - - initCL(); - } - - virtual ~CompileBullet3BroadphaseKernels() - { - // You can do clean-up work that doesn't throw exceptions here. - exitCL(); - } - - // If the constructor and destructor are not enough for setting up - // and cleaning up each test, you can define the following methods: - - #include "initCL.h" - - - - virtual void SetUp() - { - - - // Code here will be called immediately after the constructor (right - // before each test). - } - - virtual void TearDown() - { - // Code here will be called immediately after each test (right - // before the destructor). - } - }; - - - - TEST_F(CompileBullet3BroadphaseKernels,sapKernels) + virtual ~CompileBullet3BroadphaseKernels() { - cl_int errNum=0; - cl_program sapProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext,m_clDevice,sapCL,&errNum,"",0,true); - { - ASSERT_EQ(CL_SUCCESS,errNum ); - cl_kernel copyAabbsKernel= b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,sapCL, "copyAabbsKernel",&errNum,sapProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(copyAabbsKernel==0); - clReleaseKernel(copyAabbsKernel); - } - { - cl_kernel sap2Kernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,sapCL, "computePairsKernelTwoArrays",&errNum,sapProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(sap2Kernel==0); - clReleaseKernel(sap2Kernel); - } - { - cl_kernel sapKernelBruteForce = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,sapCL, "computePairsKernelBruteForce",&errNum,sapProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(sapKernelBruteForce==0); - clReleaseKernel(sapKernelBruteForce); - } - { - cl_kernel sapKernelOriginal = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,sapCL, "computePairsKernelOriginal",&errNum,sapProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(sapKernelOriginal==0); - clReleaseKernel(sapKernelOriginal); - } + // You can do clean-up work that doesn't throw exceptions here. + exitCL(); + } - { - cl_kernel sapKernelBarrier = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,sapCL, "computePairsKernelBarrier",&errNum,sapProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(sapKernelBarrier==0); - clReleaseKernel(sapKernelBarrier); - } - { - cl_kernel sapKernelLocalShared = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,sapCL, "computePairsKernelLocalSharedMemory",&errNum,sapProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(sapKernelLocalShared==0); - clReleaseKernel(sapKernelLocalShared); - } - { - cl_kernel prepareSumVarianceKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,sapCL, "prepareSumVarianceKernel",&errNum,sapProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(prepareSumVarianceKernel==0); - clReleaseKernel(prepareSumVarianceKernel); - } - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,sapCL, "flipFloatKernel",&errNum,sapProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,sapCL, "scatterKernel",&errNum,sapProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - - clReleaseProgram(sapProg); + // If the constructor and destructor are not enough for setting up + // and cleaning up each test, you can define the following methods: - }; - - - - TEST_F(CompileBullet3BroadphaseKernels,gridBroadphaseKernels) +#include "initCL.h" + + virtual void SetUp() { - cl_int errNum=0; - cl_program gridProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext,m_clDevice,gridBroadphaseCL,&errNum,"",0,true); - ASSERT_EQ(CL_SUCCESS,errNum); + // Code here will be called immediately after the constructor (right + // before each test). + } - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,gridBroadphaseCL, "kCalcHashAABB",&errNum,gridProg); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(k); - } - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,gridBroadphaseCL, "kClearCellStart",&errNum,gridProg); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(k); - } - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,gridBroadphaseCL, "kFindCellStart",&errNum,gridProg); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(k); - } - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,gridBroadphaseCL, "kFindOverlappingPairs",&errNum,gridProg); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(k); - } - - clReleaseProgram(gridProg); + virtual void TearDown() + { + // Code here will be called immediately after each test (right + // before the destructor). } }; + +TEST_F(CompileBullet3BroadphaseKernels, sapKernels) +{ + cl_int errNum = 0; + cl_program sapProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext, m_clDevice, sapCL, &errNum, "", 0, true); + { + ASSERT_EQ(CL_SUCCESS, errNum); + cl_kernel copyAabbsKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, sapCL, "copyAabbsKernel", &errNum, sapProg); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(copyAabbsKernel == 0); + clReleaseKernel(copyAabbsKernel); + } + { + cl_kernel sap2Kernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, sapCL, "computePairsKernelTwoArrays", &errNum, sapProg); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(sap2Kernel == 0); + clReleaseKernel(sap2Kernel); + } + { + cl_kernel sapKernelBruteForce = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, sapCL, "computePairsKernelBruteForce", &errNum, sapProg); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(sapKernelBruteForce == 0); + clReleaseKernel(sapKernelBruteForce); + } + { + cl_kernel sapKernelOriginal = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, sapCL, "computePairsKernelOriginal", &errNum, sapProg); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(sapKernelOriginal == 0); + clReleaseKernel(sapKernelOriginal); + } + + { + cl_kernel sapKernelBarrier = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, sapCL, "computePairsKernelBarrier", &errNum, sapProg); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(sapKernelBarrier == 0); + clReleaseKernel(sapKernelBarrier); + } + { + cl_kernel sapKernelLocalShared = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, sapCL, "computePairsKernelLocalSharedMemory", &errNum, sapProg); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(sapKernelLocalShared == 0); + clReleaseKernel(sapKernelLocalShared); + } + { + cl_kernel prepareSumVarianceKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, sapCL, "prepareSumVarianceKernel", &errNum, sapProg); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(prepareSumVarianceKernel == 0); + clReleaseKernel(prepareSumVarianceKernel); + } + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, sapCL, "flipFloatKernel", &errNum, sapProg); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, sapCL, "scatterKernel", &errNum, sapProg); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + clReleaseProgram(sapProg); +}; + +TEST_F(CompileBullet3BroadphaseKernels, gridBroadphaseKernels) +{ + cl_int errNum = 0; + cl_program gridProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext, m_clDevice, gridBroadphaseCL, &errNum, "", 0, true); + ASSERT_EQ(CL_SUCCESS, errNum); + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, gridBroadphaseCL, "kCalcHashAABB", &errNum, gridProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(k); + } + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, gridBroadphaseCL, "kClearCellStart", &errNum, gridProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, gridBroadphaseCL, "kFindCellStart", &errNum, gridProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, gridBroadphaseCL, "kFindOverlappingPairs", &errNum, gridProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(k); + } + + clReleaseProgram(gridProg); +} +}; // namespace diff --git a/test/OpenCL/AllBullet3Kernels/testCompileBullet3IntegrateUpdateAabbKernels.cpp b/test/OpenCL/AllBullet3Kernels/testCompileBullet3IntegrateUpdateAabbKernels.cpp index 286832290..0d1910caf 100644 --- a/test/OpenCL/AllBullet3Kernels/testCompileBullet3IntegrateUpdateAabbKernels.cpp +++ b/test/OpenCL/AllBullet3Kernels/testCompileBullet3IntegrateUpdateAabbKernels.cpp @@ -7,103 +7,96 @@ #include "Bullet3OpenCL/RigidBody/kernels/integrateKernel.h" #include "Bullet3OpenCL/RigidBody/kernels/updateAabbsKernel.h" - extern int gArgc; extern char** gArgv; namespace { - struct testCompileBullet3IntegrateUpdateAabbKernels : public ::testing::Test +struct testCompileBullet3IntegrateUpdateAabbKernels : public ::testing::Test +{ + cl_context m_clContext; + cl_device_id m_clDevice; + cl_command_queue m_clQueue; + char* m_clDeviceName; + cl_platform_id m_platformId; + + testCompileBullet3IntegrateUpdateAabbKernels() + : m_clDeviceName(0), + m_clContext(0), + m_clDevice(0), + m_clQueue(0), + m_platformId(0) { - cl_context m_clContext; - cl_device_id m_clDevice; - cl_command_queue m_clQueue; - char* m_clDeviceName; - cl_platform_id m_platformId; + // You can do set-up work for each test here. + b3CommandLineArgs args(gArgc, gArgv); + int preferredDeviceIndex = -1; + int preferredPlatformIndex = -1; + bool allowCpuOpenCL = false; - testCompileBullet3IntegrateUpdateAabbKernels() - :m_clDeviceName(0), - m_clContext(0), - m_clDevice(0), - m_clQueue(0), - m_platformId(0) - { - // You can do set-up work for each test here. - b3CommandLineArgs args(gArgc,gArgv); - int preferredDeviceIndex=-1; - int preferredPlatformIndex = -1; - bool allowCpuOpenCL = false; - - - initCL(); - } - - virtual ~testCompileBullet3IntegrateUpdateAabbKernels() - { - // You can do clean-up work that doesn't throw exceptions here. - exitCL(); - } - - // If the constructor and destructor are not enough for setting up - // and cleaning up each test, you can define the following methods: - - - #include "initCL.h" - - virtual void SetUp() - { - - - // Code here will be called immediately after the constructor (right - // before each test). - } - - virtual void TearDown() - { - // Code here will be called immediately after each test (right - // before the destructor). - } - }; - - TEST_F(testCompileBullet3IntegrateUpdateAabbKernels,integrateKernelCL) - { - cl_int errNum=0; - - cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_clContext,m_clDevice,integrateKernelCL,&errNum,"",0,true); - ASSERT_EQ(CL_SUCCESS,errNum); - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,integrateKernelCL, "integrateTransformsKernel",&errNum,prog); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - clReleaseProgram(prog); - - } - - TEST_F(testCompileBullet3IntegrateUpdateAabbKernels,updateAabbsKernelCL) - { - cl_int errNum=0; - cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_clContext,m_clDevice,updateAabbsKernelCL,&errNum,"",0,true); - ASSERT_EQ(CL_SUCCESS,errNum); - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,updateAabbsKernelCL, "initializeGpuAabbsFull",&errNum,prog); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,updateAabbsKernelCL, "clearOverlappingPairsKernel",&errNum,prog); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - - clReleaseProgram(prog); + initCL(); } + virtual ~testCompileBullet3IntegrateUpdateAabbKernels() + { + // You can do clean-up work that doesn't throw exceptions here. + exitCL(); + } + + // If the constructor and destructor are not enough for setting up + // and cleaning up each test, you can define the following methods: + +#include "initCL.h" + + virtual void SetUp() + { + // Code here will be called immediately after the constructor (right + // before each test). + } + + virtual void TearDown() + { + // Code here will be called immediately after each test (right + // before the destructor). + } }; + +TEST_F(testCompileBullet3IntegrateUpdateAabbKernels, integrateKernelCL) +{ + cl_int errNum = 0; + + cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_clContext, m_clDevice, integrateKernelCL, &errNum, "", 0, true); + ASSERT_EQ(CL_SUCCESS, errNum); + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, integrateKernelCL, "integrateTransformsKernel", &errNum, prog); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + clReleaseProgram(prog); +} + +TEST_F(testCompileBullet3IntegrateUpdateAabbKernels, updateAabbsKernelCL) +{ + cl_int errNum = 0; + cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_clContext, m_clDevice, updateAabbsKernelCL, &errNum, "", 0, true); + ASSERT_EQ(CL_SUCCESS, errNum); + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, updateAabbsKernelCL, "initializeGpuAabbsFull", &errNum, prog); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, updateAabbsKernelCL, "clearOverlappingPairsKernel", &errNum, prog); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + clReleaseProgram(prog); +} + +}; // namespace diff --git a/test/OpenCL/AllBullet3Kernels/testCompileBullet3JacobiContactSolverKernels.cpp b/test/OpenCL/AllBullet3Kernels/testCompileBullet3JacobiContactSolverKernels.cpp index aa2414b84..05b373b48 100644 --- a/test/OpenCL/AllBullet3Kernels/testCompileBullet3JacobiContactSolverKernels.cpp +++ b/test/OpenCL/AllBullet3Kernels/testCompileBullet3JacobiContactSolverKernels.cpp @@ -11,118 +11,110 @@ extern char** gArgv; namespace { - struct CompileBullet3JacobiContactSolverKernels : public ::testing::Test +struct CompileBullet3JacobiContactSolverKernels : public ::testing::Test +{ + cl_context m_clContext; + cl_device_id m_clDevice; + cl_command_queue m_clQueue; + char* m_clDeviceName; + cl_platform_id m_platformId; + + CompileBullet3JacobiContactSolverKernels() + : m_clDeviceName(0), + m_clContext(0), + m_clDevice(0), + m_clQueue(0), + m_platformId(0) { - cl_context m_clContext; - cl_device_id m_clDevice; - cl_command_queue m_clQueue; - char* m_clDeviceName; - cl_platform_id m_platformId; + // You can do set-up work for each test here. + b3CommandLineArgs args(gArgc, gArgv); + int preferredDeviceIndex = -1; + int preferredPlatformIndex = -1; + bool allowCpuOpenCL = false; - CompileBullet3JacobiContactSolverKernels() - :m_clDeviceName(0), - m_clContext(0), - m_clDevice(0), - m_clQueue(0), - m_platformId(0) - { - // You can do set-up work for each test here. - b3CommandLineArgs args(gArgc,gArgv); - int preferredDeviceIndex=-1; - int preferredPlatformIndex = -1; - bool allowCpuOpenCL = false; + initCL(); + } - - initCL(); - } - - virtual ~CompileBullet3JacobiContactSolverKernels() - { - // You can do clean-up work that doesn't throw exceptions here. - exitCL(); - } - - // If the constructor and destructor are not enough for setting up - // and cleaning up each test, you can define the following methods: - - #include "initCL.h" - - - virtual void SetUp() - { - - - // Code here will be called immediately after the constructor (right - // before each test). - } - - virtual void TearDown() - { - // Code here will be called immediately after each test (right - // before the destructor). - } - }; - - TEST_F(CompileBullet3JacobiContactSolverKernels,jacobiContactKernels) + virtual ~CompileBullet3JacobiContactSolverKernels() { + // You can do clean-up work that doesn't throw exceptions here. + exitCL(); + } - cl_int errNum=0; - const char* additionalMacros=""; - - cl_program solverUtilsProg= b3OpenCLUtils::compileCLProgramFromString( m_clContext, m_clDevice, solverUtilsCL, &errNum,additionalMacros, 0,true); - ASSERT_EQ(CL_SUCCESS,errNum); + // If the constructor and destructor are not enough for setting up + // and cleaning up each test, you can define the following methods: +#include "initCL.h" - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, solverUtilsCL, "CountBodiesKernel", &errNum, solverUtilsProg,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } + virtual void SetUp() + { + // Code here will be called immediately after the constructor (right + // before each test). + } - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, solverUtilsCL, "ContactToConstraintSplitKernel", &errNum, solverUtilsProg,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, solverUtilsCL, "ClearVelocitiesKernel", &errNum, solverUtilsProg,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, solverUtilsCL, "AverageVelocitiesKernel", &errNum, solverUtilsProg,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, solverUtilsCL, "UpdateBodyVelocitiesKernel", &errNum, solverUtilsProg,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, solverUtilsCL, "SolveContactJacobiKernel", &errNum, solverUtilsProg,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, solverUtilsCL, "SolveFrictionJacobiKernel", &errNum, solverUtilsProg,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - clReleaseProgram(solverUtilsProg); - - } + virtual void TearDown() + { + // Code here will be called immediately after each test (right + // before the destructor). + } }; + +TEST_F(CompileBullet3JacobiContactSolverKernels, jacobiContactKernels) +{ + cl_int errNum = 0; + const char* additionalMacros = ""; + + cl_program solverUtilsProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext, m_clDevice, solverUtilsCL, &errNum, additionalMacros, 0, true); + ASSERT_EQ(CL_SUCCESS, errNum); + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solverUtilsCL, "CountBodiesKernel", &errNum, solverUtilsProg, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solverUtilsCL, "ContactToConstraintSplitKernel", &errNum, solverUtilsProg, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solverUtilsCL, "ClearVelocitiesKernel", &errNum, solverUtilsProg, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solverUtilsCL, "AverageVelocitiesKernel", &errNum, solverUtilsProg, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solverUtilsCL, "UpdateBodyVelocitiesKernel", &errNum, solverUtilsProg, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solverUtilsCL, "SolveContactJacobiKernel", &errNum, solverUtilsProg, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solverUtilsCL, "SolveFrictionJacobiKernel", &errNum, solverUtilsProg, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + clReleaseProgram(solverUtilsProg); +} +}; // namespace diff --git a/test/OpenCL/AllBullet3Kernels/testCompileBullet3NarrowphaseKernels.cpp b/test/OpenCL/AllBullet3Kernels/testCompileBullet3NarrowphaseKernels.cpp index 491b58d79..55427c9e5 100644 --- a/test/OpenCL/AllBullet3Kernels/testCompileBullet3NarrowphaseKernels.cpp +++ b/test/OpenCL/AllBullet3Kernels/testCompileBullet3NarrowphaseKernels.cpp @@ -11,262 +11,244 @@ #include "Bullet3OpenCL/NarrowphaseCollision/kernels/bvhTraversal.h" #include "Bullet3OpenCL/NarrowphaseCollision/kernels/primitiveContacts.h" - extern int gArgc; extern char** gArgv; namespace { - struct CompileBullet3NarrowphaseKernels : public ::testing::Test +struct CompileBullet3NarrowphaseKernels : public ::testing::Test +{ + cl_context m_clContext; + cl_device_id m_clDevice; + cl_command_queue m_clQueue; + char* m_clDeviceName; + cl_platform_id m_platformId; + + CompileBullet3NarrowphaseKernels() + : m_clDeviceName(0), + m_clContext(0), + m_clDevice(0), + m_clQueue(0), + m_platformId(0) { - cl_context m_clContext; - cl_device_id m_clDevice; - cl_command_queue m_clQueue; - char* m_clDeviceName; - cl_platform_id m_platformId; - - CompileBullet3NarrowphaseKernels() - :m_clDeviceName(0), - m_clContext(0), - m_clDevice(0), - m_clQueue(0), - m_platformId(0) - { - // You can do set-up work for each test here. - b3CommandLineArgs args(gArgc,gArgv); - int preferredDeviceIndex=-1; - int preferredPlatformIndex = -1; - bool allowCpuOpenCL = false; - - - initCL(); - } - - virtual ~CompileBullet3NarrowphaseKernels() - { - // You can do clean-up work that doesn't throw exceptions here. - exitCL(); - } - - // If the constructor and destructor are not enough for setting up - // and cleaning up each test, you can define the following methods: - - #include "initCL.h" - - virtual void SetUp() - { - - - // Code here will be called immediately after the constructor (right - // before each test). - } - - virtual void TearDown() - { - // Code here will be called immediately after each test (right - // before the destructor). - } - }; - - TEST_F(CompileBullet3NarrowphaseKernels,satKernelsCL) - { - cl_int errNum=0; - - char flags[1024]={0}; - - cl_program satProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext,m_clDevice,satKernelsCL,&errNum,flags,0,true); - ASSERT_EQ(CL_SUCCESS,errNum); - - - { - cl_kernel m_findSeparatingAxisKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satKernelsCL, "findSeparatingAxisKernel",&errNum,satProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(m_findSeparatingAxisKernel ); - } - - { - cl_kernel m_findSeparatingAxisVertexFaceKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satKernelsCL, "findSeparatingAxisVertexFaceKernel",&errNum,satProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(m_findSeparatingAxisVertexFaceKernel); - } - - { - cl_kernel m_findSeparatingAxisEdgeEdgeKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satKernelsCL, "findSeparatingAxisEdgeEdgeKernel",&errNum,satProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(m_findSeparatingAxisEdgeEdgeKernel); - } - - { - cl_kernel m_findConcaveSeparatingAxisKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satKernelsCL, "findConcaveSeparatingAxisKernel",&errNum,satProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(m_findConcaveSeparatingAxisKernel ); - } - - - { - cl_kernel m_findCompoundPairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satKernelsCL, "findCompoundPairsKernel",&errNum,satProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(m_findCompoundPairsKernel); - } - - { - cl_kernel m_processCompoundPairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satKernelsCL, "processCompoundPairsKernel",&errNum,satProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(m_processCompoundPairsKernel); - } - - clReleaseProgram(satProg); + // You can do set-up work for each test here. + b3CommandLineArgs args(gArgc, gArgv); + int preferredDeviceIndex = -1; + int preferredPlatformIndex = -1; + bool allowCpuOpenCL = false; + initCL(); } - TEST_F(CompileBullet3NarrowphaseKernels,satConcaveKernelsCL) + virtual ~CompileBullet3NarrowphaseKernels() { - cl_int errNum=0; - - char flags[1024]={0}; - - cl_program satConcaveProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext,m_clDevice,satConcaveKernelsCL,&errNum,flags,0,true); - ASSERT_EQ(CL_SUCCESS,errNum); - - { - cl_kernel m_findConcaveSeparatingAxisVertexFaceKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satConcaveKernelsCL, "findConcaveSeparatingAxisVertexFaceKernel",&errNum,satConcaveProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(m_findConcaveSeparatingAxisVertexFaceKernel); - } - - { - cl_kernel m_findConcaveSeparatingAxisEdgeEdgeKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satConcaveKernelsCL, "findConcaveSeparatingAxisEdgeEdgeKernel",&errNum,satConcaveProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(m_findConcaveSeparatingAxisEdgeEdgeKernel); - } - - clReleaseProgram(satConcaveProg); + // You can do clean-up work that doesn't throw exceptions here. + exitCL(); } + // If the constructor and destructor are not enough for setting up + // and cleaning up each test, you can define the following methods: - TEST_F(CompileBullet3NarrowphaseKernels,satClipKernelsCL) +#include "initCL.h" + + virtual void SetUp() { - - char flags[1024]={0}; - cl_int errNum=0; -//#ifdef CL_PLATFORM_INTEL -// sprintf(flags,"-g -s \"%s\"","C:/develop/bullet3_experiments2/opencl/gpu_narrowphase/kernels/satClipHullContacts.cl"); -//#endif - - cl_program satClipContactsProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext,m_clDevice,satClipKernelsCL,&errNum,flags,0,true); - ASSERT_EQ(CL_SUCCESS,errNum); - - { - cl_kernel m_clipHullHullKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satClipKernelsCL, "clipHullHullKernel",&errNum,satClipContactsProg); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(m_clipHullHullKernel); - } - - { - cl_kernel m_clipCompoundsHullHullKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satClipKernelsCL, "clipCompoundsHullHullKernel",&errNum,satClipContactsProg); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(m_clipCompoundsHullHullKernel); - } - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satClipKernelsCL, "findClippingFacesKernel",&errNum,satClipContactsProg); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(k); - } - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satClipKernelsCL, "clipFacesAndFindContactsKernel",&errNum,satClipContactsProg); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(k); - } - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satClipKernelsCL, "clipHullHullConcaveConvexKernel",&errNum,satClipContactsProg); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(k); - } - - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,satClipKernelsCL, - "newContactReductionKernel",&errNum,satClipContactsProg); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(k); - } - - clReleaseProgram(satClipContactsProg); + // Code here will be called immediately after the constructor (right + // before each test). } - - TEST_F(CompileBullet3NarrowphaseKernels,bvhTraversalKernels) + virtual void TearDown() { - - - cl_int errNum=0; - cl_program bvhTraversalProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext,m_clDevice,bvhTraversalKernelCL,&errNum,"",0,true); - ASSERT_EQ(CL_SUCCESS,errNum); - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,bvhTraversalKernelCL, "bvhTraversalKernel",&errNum,bvhTraversalProg,""); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(k); - } - clReleaseProgram(bvhTraversalProg); + // Code here will be called immediately after each test (right + // before the destructor). } - - TEST_F(CompileBullet3NarrowphaseKernels,primitiveContactsKernelsCL) - { - cl_int errNum=0; - cl_program primitiveContactsProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext,m_clDevice,primitiveContactsKernelsCL,&errNum,"",0,true); - ASSERT_EQ(CL_SUCCESS,errNum); - - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,primitiveContactsKernelsCL, "primitiveContactsKernel",&errNum,primitiveContactsProg,""); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(k); - } - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,primitiveContactsKernelsCL, "findConcaveSphereContactsKernel",&errNum,primitiveContactsProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(k); - } - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,primitiveContactsKernelsCL, "processCompoundPairsPrimitivesKernel",&errNum,primitiveContactsProg,""); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(k); - } - - clReleaseProgram(primitiveContactsProg); - } - - - TEST_F(CompileBullet3NarrowphaseKernels,mprKernelsCL) - { - - cl_int errNum=0; - const char* srcConcave = satConcaveKernelsCL; - char flags[1024]={0}; - cl_program mprProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext,m_clDevice,mprKernelsCL,&errNum,flags,0,true); - ASSERT_EQ(CL_SUCCESS,errNum); - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,mprKernelsCL, "mprPenetrationKernel",&errNum,mprProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(k); - } - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,mprKernelsCL, "findSeparatingAxisUnitSphereKernel",&errNum,mprProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(k); - } - - - clReleaseProgram(mprProg); - } - - }; + +TEST_F(CompileBullet3NarrowphaseKernels, satKernelsCL) +{ + cl_int errNum = 0; + + char flags[1024] = {0}; + + cl_program satProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext, m_clDevice, satKernelsCL, &errNum, flags, 0, true); + ASSERT_EQ(CL_SUCCESS, errNum); + + { + cl_kernel m_findSeparatingAxisKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, satKernelsCL, "findSeparatingAxisKernel", &errNum, satProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(m_findSeparatingAxisKernel); + } + + { + cl_kernel m_findSeparatingAxisVertexFaceKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, satKernelsCL, "findSeparatingAxisVertexFaceKernel", &errNum, satProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(m_findSeparatingAxisVertexFaceKernel); + } + + { + cl_kernel m_findSeparatingAxisEdgeEdgeKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, satKernelsCL, "findSeparatingAxisEdgeEdgeKernel", &errNum, satProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(m_findSeparatingAxisEdgeEdgeKernel); + } + + { + cl_kernel m_findConcaveSeparatingAxisKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, satKernelsCL, "findConcaveSeparatingAxisKernel", &errNum, satProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(m_findConcaveSeparatingAxisKernel); + } + + { + cl_kernel m_findCompoundPairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, satKernelsCL, "findCompoundPairsKernel", &errNum, satProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(m_findCompoundPairsKernel); + } + + { + cl_kernel m_processCompoundPairsKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, satKernelsCL, "processCompoundPairsKernel", &errNum, satProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(m_processCompoundPairsKernel); + } + + clReleaseProgram(satProg); +} + +TEST_F(CompileBullet3NarrowphaseKernels, satConcaveKernelsCL) +{ + cl_int errNum = 0; + + char flags[1024] = {0}; + + cl_program satConcaveProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext, m_clDevice, satConcaveKernelsCL, &errNum, flags, 0, true); + ASSERT_EQ(CL_SUCCESS, errNum); + + { + cl_kernel m_findConcaveSeparatingAxisVertexFaceKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, satConcaveKernelsCL, "findConcaveSeparatingAxisVertexFaceKernel", &errNum, satConcaveProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(m_findConcaveSeparatingAxisVertexFaceKernel); + } + + { + cl_kernel m_findConcaveSeparatingAxisEdgeEdgeKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, satConcaveKernelsCL, "findConcaveSeparatingAxisEdgeEdgeKernel", &errNum, satConcaveProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(m_findConcaveSeparatingAxisEdgeEdgeKernel); + } + + clReleaseProgram(satConcaveProg); +} + +TEST_F(CompileBullet3NarrowphaseKernels, satClipKernelsCL) +{ + char flags[1024] = {0}; + cl_int errNum = 0; + //#ifdef CL_PLATFORM_INTEL + // sprintf(flags,"-g -s \"%s\"","C:/develop/bullet3_experiments2/opencl/gpu_narrowphase/kernels/satClipHullContacts.cl"); + //#endif + + cl_program satClipContactsProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext, m_clDevice, satClipKernelsCL, &errNum, flags, 0, true); + ASSERT_EQ(CL_SUCCESS, errNum); + + { + cl_kernel m_clipHullHullKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, satClipKernelsCL, "clipHullHullKernel", &errNum, satClipContactsProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(m_clipHullHullKernel); + } + + { + cl_kernel m_clipCompoundsHullHullKernel = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, satClipKernelsCL, "clipCompoundsHullHullKernel", &errNum, satClipContactsProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(m_clipCompoundsHullHullKernel); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, satClipKernelsCL, "findClippingFacesKernel", &errNum, satClipContactsProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, satClipKernelsCL, "clipFacesAndFindContactsKernel", &errNum, satClipContactsProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, satClipKernelsCL, "clipHullHullConcaveConvexKernel", &errNum, satClipContactsProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, satClipKernelsCL, + "newContactReductionKernel", &errNum, satClipContactsProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(k); + } + + clReleaseProgram(satClipContactsProg); +} + +TEST_F(CompileBullet3NarrowphaseKernels, bvhTraversalKernels) +{ + cl_int errNum = 0; + cl_program bvhTraversalProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext, m_clDevice, bvhTraversalKernelCL, &errNum, "", 0, true); + ASSERT_EQ(CL_SUCCESS, errNum); + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, bvhTraversalKernelCL, "bvhTraversalKernel", &errNum, bvhTraversalProg, ""); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(k); + } + clReleaseProgram(bvhTraversalProg); +} + +TEST_F(CompileBullet3NarrowphaseKernels, primitiveContactsKernelsCL) +{ + cl_int errNum = 0; + cl_program primitiveContactsProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext, m_clDevice, primitiveContactsKernelsCL, &errNum, "", 0, true); + ASSERT_EQ(CL_SUCCESS, errNum); + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, primitiveContactsKernelsCL, "primitiveContactsKernel", &errNum, primitiveContactsProg, ""); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, primitiveContactsKernelsCL, "findConcaveSphereContactsKernel", &errNum, primitiveContactsProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, primitiveContactsKernelsCL, "processCompoundPairsPrimitivesKernel", &errNum, primitiveContactsProg, ""); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(k); + } + + clReleaseProgram(primitiveContactsProg); +} + +TEST_F(CompileBullet3NarrowphaseKernels, mprKernelsCL) +{ + cl_int errNum = 0; + const char* srcConcave = satConcaveKernelsCL; + char flags[1024] = {0}; + cl_program mprProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext, m_clDevice, mprKernelsCL, &errNum, flags, 0, true); + ASSERT_EQ(CL_SUCCESS, errNum); + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, mprKernelsCL, "mprPenetrationKernel", &errNum, mprProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, mprKernelsCL, "findSeparatingAxisUnitSphereKernel", &errNum, mprProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(k); + } + + clReleaseProgram(mprProg); +} + +}; // namespace diff --git a/test/OpenCL/AllBullet3Kernels/testCompileBullet3PgsContactSolverKernels.cpp b/test/OpenCL/AllBullet3Kernels/testCompileBullet3PgsContactSolverKernels.cpp index 4fd381a06..cec1b3cf7 100644 --- a/test/OpenCL/AllBullet3Kernels/testCompileBullet3PgsContactSolverKernels.cpp +++ b/test/OpenCL/AllBullet3Kernels/testCompileBullet3PgsContactSolverKernels.cpp @@ -11,228 +11,217 @@ #include "Bullet3OpenCL/RigidBody/kernels/batchingKernels.h" #include "Bullet3OpenCL/RigidBody/kernels/batchingKernelsNew.h" - extern int gArgc; extern char** gArgv; namespace { - struct CompileBullet3PgsContactSolverKernels : public ::testing::Test +struct CompileBullet3PgsContactSolverKernels : public ::testing::Test +{ + cl_context m_clContext; + cl_device_id m_clDevice; + cl_command_queue m_clQueue; + char* m_clDeviceName; + cl_platform_id m_platformId; + + CompileBullet3PgsContactSolverKernels() + : m_clDeviceName(0), + m_clContext(0), + m_clDevice(0), + m_clQueue(0), + m_platformId(0) { - cl_context m_clContext; - cl_device_id m_clDevice; - cl_command_queue m_clQueue; - char* m_clDeviceName; - cl_platform_id m_platformId; + // You can do set-up work for each test here. + b3CommandLineArgs args(gArgc, gArgv); + int preferredDeviceIndex = -1; + int preferredPlatformIndex = -1; + bool allowCpuOpenCL = false; - CompileBullet3PgsContactSolverKernels() - :m_clDeviceName(0), - m_clContext(0), - m_clDevice(0), - m_clQueue(0), - m_platformId(0) - { - // You can do set-up work for each test here. - b3CommandLineArgs args(gArgc,gArgv); - int preferredDeviceIndex=-1; - int preferredPlatformIndex = -1; - bool allowCpuOpenCL = false; - - - initCL(); - } - - virtual ~CompileBullet3PgsContactSolverKernels() - { - // You can do clean-up work that doesn't throw exceptions here. - exitCL(); - } - - // If the constructor and destructor are not enough for setting up - // and cleaning up each test, you can define the following methods: - - #include "initCL.h" - - virtual void SetUp() - { - - - // Code here will be called immediately after the constructor (right - // before each test). - } - - virtual void TearDown() - { - // Code here will be called immediately after each test (right - // before the destructor). - } - }; - - TEST_F(CompileBullet3PgsContactSolverKernels,solveFrictionCL) - { - const char* additionalMacros=""; - cl_int errNum=0; - cl_program solveFrictionProg= b3OpenCLUtils::compileCLProgramFromString( m_clContext, m_clDevice, solveFrictionCL, &errNum,additionalMacros, 0,true); - ASSERT_EQ(CL_SUCCESS,errNum); - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, solveFrictionCL, "BatchSolveKernelFriction", &errNum, solveFrictionProg,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - - { - cl_kernel k =b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, solveFrictionCL, "solveSingleFrictionKernel", &errNum, solveFrictionProg,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - clReleaseProgram(solveFrictionProg); + initCL(); } - TEST_F(CompileBullet3PgsContactSolverKernels,solverSetupCL) + virtual ~CompileBullet3PgsContactSolverKernels() { - const char* additionalMacros=""; - cl_int errNum=0; - cl_program solverSetupProg= b3OpenCLUtils::compileCLProgramFromString( m_clContext, m_clDevice, solverSetupCL, &errNum,additionalMacros, 0,true); - ASSERT_EQ(CL_SUCCESS,errNum); - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, solverSetupCL, "ContactToConstraintKernel", &errNum, solverSetupProg,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - - clReleaseProgram(solverSetupProg); + // You can do clean-up work that doesn't throw exceptions here. + exitCL(); } - TEST_F(CompileBullet3PgsContactSolverKernels,solverSetup2CL) + // If the constructor and destructor are not enough for setting up + // and cleaning up each test, you can define the following methods: + +#include "initCL.h" + + virtual void SetUp() { - const char* additionalMacros=""; - cl_int errNum=0; - - cl_program solverSetup2Prog= b3OpenCLUtils::compileCLProgramFromString( m_clContext, m_clDevice, solverSetup2CL, &errNum,additionalMacros, 0,true); - ASSERT_EQ(CL_SUCCESS,errNum); - - - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, solverSetup2CL, "SetSortDataKernel", &errNum, solverSetup2Prog,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, solverSetup2CL, "SetDeterminismSortDataBodyA", &errNum, solverSetup2Prog,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, solverSetup2CL, "SetDeterminismSortDataBodyB", &errNum, solverSetup2Prog,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, solverSetup2CL, "SetDeterminismSortDataChildShapeA", &errNum, solverSetup2Prog,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, solverSetup2CL, "SetDeterminismSortDataChildShapeB", &errNum, solverSetup2Prog,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, solverSetup2CL, "ReorderContactKernel", &errNum, solverSetup2Prog,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, solverSetup2CL, "CopyConstraintKernel", &errNum, solverSetup2Prog,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - - clReleaseProgram(solverSetup2Prog); + // Code here will be called immediately after the constructor (right + // before each test). } - TEST_F(CompileBullet3PgsContactSolverKernels,solveContactCL) + virtual void TearDown() { - const char* additionalMacros=""; - cl_int errNum=0; - - cl_program solveContactProg= b3OpenCLUtils::compileCLProgramFromString( m_clContext, m_clDevice, solveContactCL, &errNum,additionalMacros, 0,true); - ASSERT_EQ(CL_SUCCESS,errNum); - - - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, solveContactCL, "BatchSolveKernelContact", &errNum, solveContactProg,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, solveContactCL, "solveSingleContactKernel", &errNum, solveContactProg,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - - clReleaseProgram(solveContactProg); + // Code here will be called immediately after each test (right + // before the destructor). } - - - TEST_F(CompileBullet3PgsContactSolverKernels,batchingKernelsCL) - { - const char* additionalMacros=""; - cl_int errNum=0; - - cl_program batchingProg = b3OpenCLUtils::compileCLProgramFromString( m_clContext, m_clDevice, batchingKernelsCL, &errNum,additionalMacros, 0,true); - ASSERT_EQ(CL_SUCCESS,errNum); - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, batchingKernelsCL, "CreateBatches", &errNum, batchingProg,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - - clReleaseProgram(batchingProg); - } - - TEST_F(CompileBullet3PgsContactSolverKernels,batchingKernelsNewCL) - { - const char* additionalMacros=""; - cl_int errNum=0; - - cl_program batchingNewProg = b3OpenCLUtils::compileCLProgramFromString( m_clContext, m_clDevice, batchingKernelsNewCL, &errNum,additionalMacros, 0,true); - ASSERT_EQ(CL_SUCCESS,errNum); - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString( m_clContext, m_clDevice, batchingKernelsNewCL, "CreateBatchesNew", &errNum, batchingNewProg,additionalMacros ); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - clReleaseProgram(batchingNewProg); - } - }; + +TEST_F(CompileBullet3PgsContactSolverKernels, solveFrictionCL) +{ + const char* additionalMacros = ""; + cl_int errNum = 0; + cl_program solveFrictionProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext, m_clDevice, solveFrictionCL, &errNum, additionalMacros, 0, true); + ASSERT_EQ(CL_SUCCESS, errNum); + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solveFrictionCL, "BatchSolveKernelFriction", &errNum, solveFrictionProg, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solveFrictionCL, "solveSingleFrictionKernel", &errNum, solveFrictionProg, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + clReleaseProgram(solveFrictionProg); +} + +TEST_F(CompileBullet3PgsContactSolverKernels, solverSetupCL) +{ + const char* additionalMacros = ""; + cl_int errNum = 0; + cl_program solverSetupProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext, m_clDevice, solverSetupCL, &errNum, additionalMacros, 0, true); + ASSERT_EQ(CL_SUCCESS, errNum); + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solverSetupCL, "ContactToConstraintKernel", &errNum, solverSetupProg, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + clReleaseProgram(solverSetupProg); +} + +TEST_F(CompileBullet3PgsContactSolverKernels, solverSetup2CL) +{ + const char* additionalMacros = ""; + cl_int errNum = 0; + + cl_program solverSetup2Prog = b3OpenCLUtils::compileCLProgramFromString(m_clContext, m_clDevice, solverSetup2CL, &errNum, additionalMacros, 0, true); + ASSERT_EQ(CL_SUCCESS, errNum); + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solverSetup2CL, "SetSortDataKernel", &errNum, solverSetup2Prog, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solverSetup2CL, "SetDeterminismSortDataBodyA", &errNum, solverSetup2Prog, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solverSetup2CL, "SetDeterminismSortDataBodyB", &errNum, solverSetup2Prog, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solverSetup2CL, "SetDeterminismSortDataChildShapeA", &errNum, solverSetup2Prog, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solverSetup2CL, "SetDeterminismSortDataChildShapeB", &errNum, solverSetup2Prog, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solverSetup2CL, "ReorderContactKernel", &errNum, solverSetup2Prog, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solverSetup2CL, "CopyConstraintKernel", &errNum, solverSetup2Prog, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + clReleaseProgram(solverSetup2Prog); +} + +TEST_F(CompileBullet3PgsContactSolverKernels, solveContactCL) +{ + const char* additionalMacros = ""; + cl_int errNum = 0; + + cl_program solveContactProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext, m_clDevice, solveContactCL, &errNum, additionalMacros, 0, true); + ASSERT_EQ(CL_SUCCESS, errNum); + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solveContactCL, "BatchSolveKernelContact", &errNum, solveContactProg, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solveContactCL, "solveSingleContactKernel", &errNum, solveContactProg, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + clReleaseProgram(solveContactProg); +} + +TEST_F(CompileBullet3PgsContactSolverKernels, batchingKernelsCL) +{ + const char* additionalMacros = ""; + cl_int errNum = 0; + + cl_program batchingProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext, m_clDevice, batchingKernelsCL, &errNum, additionalMacros, 0, true); + ASSERT_EQ(CL_SUCCESS, errNum); + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, batchingKernelsCL, "CreateBatches", &errNum, batchingProg, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + clReleaseProgram(batchingProg); +} + +TEST_F(CompileBullet3PgsContactSolverKernels, batchingKernelsNewCL) +{ + const char* additionalMacros = ""; + cl_int errNum = 0; + + cl_program batchingNewProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext, m_clDevice, batchingKernelsNewCL, &errNum, additionalMacros, 0, true); + ASSERT_EQ(CL_SUCCESS, errNum); + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, batchingKernelsNewCL, "CreateBatchesNew", &errNum, batchingNewProg, additionalMacros); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + clReleaseProgram(batchingNewProg); +} + +}; // namespace diff --git a/test/OpenCL/AllBullet3Kernels/testCompileBullet3PgsJointSolverKernels.cpp b/test/OpenCL/AllBullet3Kernels/testCompileBullet3PgsJointSolverKernels.cpp index b128962ba..b7227a7d2 100644 --- a/test/OpenCL/AllBullet3Kernels/testCompileBullet3PgsJointSolverKernels.cpp +++ b/test/OpenCL/AllBullet3Kernels/testCompileBullet3PgsJointSolverKernels.cpp @@ -11,112 +11,105 @@ extern char** gArgv; namespace { - struct testCompileBullet3PgsJointSolverKernels : public ::testing::Test +struct testCompileBullet3PgsJointSolverKernels : public ::testing::Test +{ + cl_context m_clContext; + cl_device_id m_clDevice; + cl_command_queue m_clQueue; + char* m_clDeviceName; + cl_platform_id m_platformId; + + testCompileBullet3PgsJointSolverKernels() + : m_clDeviceName(0), + m_clContext(0), + m_clDevice(0), + m_clQueue(0), + m_platformId(0) { - cl_context m_clContext; - cl_device_id m_clDevice; - cl_command_queue m_clQueue; - char* m_clDeviceName; - cl_platform_id m_platformId; + // You can do set-up work for each test here. + b3CommandLineArgs args(gArgc, gArgv); + int preferredDeviceIndex = -1; + int preferredPlatformIndex = -1; + bool allowCpuOpenCL = false; - testCompileBullet3PgsJointSolverKernels() - :m_clDeviceName(0), - m_clContext(0), - m_clDevice(0), - m_clQueue(0), - m_platformId(0) - { - // You can do set-up work for each test here. - b3CommandLineArgs args(gArgc,gArgv); - int preferredDeviceIndex=-1; - int preferredPlatformIndex = -1; - bool allowCpuOpenCL = false; + initCL(); + } - - initCL(); - } - - virtual ~testCompileBullet3PgsJointSolverKernels() - { - // You can do clean-up work that doesn't throw exceptions here. - exitCL(); - } - - // If the constructor and destructor are not enough for setting up - // and cleaning up each test, you can define the following methods: - - #include "initCL.h" - - virtual void SetUp() - { - - - // Code here will be called immediately after the constructor (right - // before each test). - } - - virtual void TearDown() - { - // Code here will be called immediately after each test (right - // before the destructor). - } - }; - - TEST_F(testCompileBullet3PgsJointSolverKernels,solveConstraintRowsCL) + virtual ~testCompileBullet3PgsJointSolverKernels() { - cl_int errNum=0; + // You can do clean-up work that doesn't throw exceptions here. + exitCL(); + } - cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_clContext,m_clDevice,solveConstraintRowsCL,&errNum,"",0,true); - ASSERT_EQ(CL_SUCCESS,errNum); - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,solveConstraintRowsCL, "solveJointConstraintRows",&errNum,prog); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } + // If the constructor and destructor are not enough for setting up + // and cleaning up each test, you can define the following methods: - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext,m_clDevice,solveConstraintRowsCL,"initSolverBodies",&errNum,prog); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext,m_clDevice,solveConstraintRowsCL,"getInfo1Kernel",&errNum,prog); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext,m_clDevice,solveConstraintRowsCL,"initBatchConstraintsKernel",&errNum,prog); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - { - cl_kernel k= b3OpenCLUtils::compileCLKernelFromString(m_clContext,m_clDevice,solveConstraintRowsCL,"getInfo2Kernel",&errNum,prog); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext,m_clDevice,solveConstraintRowsCL,"writeBackVelocitiesKernel",&errNum,prog); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext,m_clDevice,solveConstraintRowsCL,"breakViolatedConstraintsKernel",&errNum,prog); - ASSERT_EQ(CL_SUCCESS,errNum); - ASSERT_FALSE(k==0); - clReleaseKernel(k); - } +#include "initCL.h" - - + virtual void SetUp() + { + // Code here will be called immediately after the constructor (right + // before each test). + } - clReleaseProgram(prog); - - } + virtual void TearDown() + { + // Code here will be called immediately after each test (right + // before the destructor). + } }; + +TEST_F(testCompileBullet3PgsJointSolverKernels, solveConstraintRowsCL) +{ + cl_int errNum = 0; + + cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_clContext, m_clDevice, solveConstraintRowsCL, &errNum, "", 0, true); + ASSERT_EQ(CL_SUCCESS, errNum); + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solveConstraintRowsCL, "solveJointConstraintRows", &errNum, prog); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solveConstraintRowsCL, "initSolverBodies", &errNum, prog); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solveConstraintRowsCL, "getInfo1Kernel", &errNum, prog); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solveConstraintRowsCL, "initBatchConstraintsKernel", &errNum, prog); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solveConstraintRowsCL, "getInfo2Kernel", &errNum, prog); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solveConstraintRowsCL, "writeBackVelocitiesKernel", &errNum, prog); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, solveConstraintRowsCL, "breakViolatedConstraintsKernel", &errNum, prog); + ASSERT_EQ(CL_SUCCESS, errNum); + ASSERT_FALSE(k == 0); + clReleaseKernel(k); + } + + clReleaseProgram(prog); +} +}; // namespace diff --git a/test/OpenCL/AllBullet3Kernels/testCompileBullet3RaycastKernels.cpp b/test/OpenCL/AllBullet3Kernels/testCompileBullet3RaycastKernels.cpp index b30726611..9e99051a6 100644 --- a/test/OpenCL/AllBullet3Kernels/testCompileBullet3RaycastKernels.cpp +++ b/test/OpenCL/AllBullet3Kernels/testCompileBullet3RaycastKernels.cpp @@ -11,71 +11,66 @@ extern char** gArgv; namespace { - struct CompileBullet3RaycastKernels : public ::testing::Test +struct CompileBullet3RaycastKernels : public ::testing::Test +{ + cl_context m_clContext; + cl_device_id m_clDevice; + cl_command_queue m_clQueue; + char* m_clDeviceName; + cl_platform_id m_platformId; + + CompileBullet3RaycastKernels() + : m_clDeviceName(0), + m_clContext(0), + m_clDevice(0), + m_clQueue(0), + m_platformId(0) { - cl_context m_clContext; - cl_device_id m_clDevice; - cl_command_queue m_clQueue; - char* m_clDeviceName; - cl_platform_id m_platformId; + // You can do set-up work for each test here. + b3CommandLineArgs args(gArgc, gArgv); + int preferredDeviceIndex = -1; + int preferredPlatformIndex = -1; + bool allowCpuOpenCL = false; - CompileBullet3RaycastKernels() - :m_clDeviceName(0), - m_clContext(0), - m_clDevice(0), - m_clQueue(0), - m_platformId(0) - { - // You can do set-up work for each test here. - b3CommandLineArgs args(gArgc,gArgv); - int preferredDeviceIndex=-1; - int preferredPlatformIndex = -1; - bool allowCpuOpenCL = false; + initCL(); + } - - initCL(); - } - - virtual ~CompileBullet3RaycastKernels() - { - // You can do clean-up work that doesn't throw exceptions here. - exitCL(); - } - - // If the constructor and destructor are not enough for setting up - // and cleaning up each test, you can define the following methods: - - - #include "initCL.h" - - virtual void SetUp() - { - - - // Code here will be called immediately after the constructor (right - // before each test). - } - - virtual void TearDown() - { - // Code here will be called immediately after each test (right - // before the destructor). - } - }; - - TEST_F(CompileBullet3RaycastKernels,sapFastKernels) + virtual ~CompileBullet3RaycastKernels() { - - cl_int errNum=0; - cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_clContext,m_clDevice,rayCastKernelCL,&errNum,"",0,true); - ASSERT_EQ(CL_SUCCESS,errNum); + // You can do clean-up work that doesn't throw exceptions here. + exitCL(); + } - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,rayCastKernelCL, "rayCastKernel",&errNum,prog); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(k); - } - - clReleaseProgram(prog); - } + // If the constructor and destructor are not enough for setting up + // and cleaning up each test, you can define the following methods: + +#include "initCL.h" + + virtual void SetUp() + { + // Code here will be called immediately after the constructor (right + // before each test). + } + + virtual void TearDown() + { + // Code here will be called immediately after each test (right + // before the destructor). + } }; + +TEST_F(CompileBullet3RaycastKernels, sapFastKernels) +{ + cl_int errNum = 0; + cl_program prog = b3OpenCLUtils::compileCLProgramFromString(m_clContext, m_clDevice, rayCastKernelCL, &errNum, "", 0, true); + ASSERT_EQ(CL_SUCCESS, errNum); + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, rayCastKernelCL, "rayCastKernel", &errNum, prog); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(k); + } + + clReleaseProgram(prog); +} +}; // namespace diff --git a/test/OpenCL/AllBullet3Kernels/testExecuteBullet3NarrowphaseKernels.cpp b/test/OpenCL/AllBullet3Kernels/testExecuteBullet3NarrowphaseKernels.cpp index 06f32b43a..28f3ba4b2 100644 --- a/test/OpenCL/AllBullet3Kernels/testExecuteBullet3NarrowphaseKernels.cpp +++ b/test/OpenCL/AllBullet3Kernels/testExecuteBullet3NarrowphaseKernels.cpp @@ -21,51 +21,49 @@ extern char** gArgv; namespace { - struct ExecuteBullet3NarrowphaseKernels : public ::testing::Test +struct ExecuteBullet3NarrowphaseKernels : public ::testing::Test +{ + cl_context m_clContext; + cl_device_id m_clDevice; + cl_command_queue m_clQueue; + char* m_clDeviceName; + cl_platform_id m_platformId; + + ExecuteBullet3NarrowphaseKernels() + : m_clDeviceName(0), + m_clContext(0), + m_clDevice(0), + m_clQueue(0), + m_platformId(0) { - cl_context m_clContext; - cl_device_id m_clDevice; - cl_command_queue m_clQueue; - char* m_clDeviceName; - cl_platform_id m_platformId; + // You can do set-up work for each test here. - ExecuteBullet3NarrowphaseKernels() - :m_clDeviceName(0), - m_clContext(0), - m_clDevice(0), - m_clQueue(0), - m_platformId(0) - { - // You can do set-up work for each test here. + initCL(); + } - initCL(); - } + virtual ~ExecuteBullet3NarrowphaseKernels() + { + // You can do clean-up work that doesn't throw exceptions here. + exitCL(); + } - virtual ~ExecuteBullet3NarrowphaseKernels() - { - // You can do clean-up work that doesn't throw exceptions here. - exitCL(); - } + // If the constructor and destructor are not enough for setting up + // and cleaning up each test, you can define the following methods: - // If the constructor and destructor are not enough for setting up - // and cleaning up each test, you can define the following methods: +#include "initCL.h" - #include "initCL.h" + virtual void SetUp() + { + // Code here will be called immediately after the constructor (right + // before each test). + } - virtual void SetUp() - { - - - // Code here will be called immediately after the constructor (right - // before each test). - } - - virtual void TearDown() - { - // Code here will be called immediately after each test (right - // before the destructor). - } - }; + virtual void TearDown() + { + // Code here will be called immediately after each test (right + // before the destructor). + } +}; #if 0 TEST_F(ExecuteBullet3NarrowphaseKernels,satKernelsCL) @@ -244,196 +242,191 @@ namespace #endif - unsigned char* openFile(const char* fileName, int* sizeInBytesPtr) - { - *sizeInBytesPtr=0; - - unsigned char* buffer = 0; - const char* prefix[]={"./","./data/","../data/","../../data/","../../../data/","../../../../data/"}; - int numPrefixes = sizeof(prefix)/sizeof(const char*); - char relativeFileName[1024]; +unsigned char* openFile(const char* fileName, int* sizeInBytesPtr) +{ + *sizeInBytesPtr = 0; + unsigned char* buffer = 0; + const char* prefix[] = {"./", "./data/", "../data/", "../../data/", "../../../data/", "../../../../data/"}; + int numPrefixes = sizeof(prefix) / sizeof(const char*); + char relativeFileName[1024]; #ifdef B3_USE_ZLIB + { + FILE* f = 0; + int result = 0; + + for (int i = 0; !f && i < numPrefixes; i++) { - FILE* f=0; - int result = 0; + sprintf(relativeFileName, "%s%s", prefix[i], "unittest_data.zip"); + f = fopen(relativeFileName, "rb"); + } + if (f) + { + fclose(f); - for (int i=0;!f && i totalContactsOut(this->m_clContext,this->m_clQueue); - totalContactsOut.setFromOpenCLBuffer(data.m_clBuffer,1); - int numContacts = totalContactsOut.at(0); - ASSERT_EQ(results[i],numContacts); - } - //printf("numContacts = %d\n",numContacts); - - //nContacts = m_totalContactsOut.at(0); + b3Printf("error, cannot get file size\n"); } - - - - - clReleaseKernel(k); + buffer = (unsigned char*)malloc(sizeInBytes); + int actualRead = fread(buffer, sizeInBytes, 1, f); + if (actualRead != 1) + { + free(buffer); + buffer = 0; + } + else + { + *sizeInBytesPtr = sizeInBytes; + } + fclose(f); } - - { - cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice,mprKernelsCL, "findSeparatingAxisUnitSphereKernel",&errNum,mprProg ); - ASSERT_EQ(CL_SUCCESS,errNum); - clReleaseKernel(k); - } - - - clReleaseProgram(mprProg); } + return buffer; +} -}; +void testLauncher(const char* fileName2, b3LauncherCL& launcher, cl_context ctx) +{ + int sizeInBytes = 0; + + unsigned char* buf = openFile(fileName2, &sizeInBytes); + ASSERT_FALSE(buf == NULL); + if (buf) + { + int serializedBytes = launcher.deserializeArgs(buf, sizeInBytes, ctx); + int num = *(int*)&buf[serializedBytes]; + + launcher.launch1D(num); + + free(buf); + //this clFinish is for testing on errors + } +} + +TEST_F(ExecuteBullet3NarrowphaseKernels, mprKernelsCL) +{ + cl_int errNum = 0; + const char* srcConcave = satConcaveKernelsCL; + char flags[1024] = {0}; + cl_program mprProg = b3OpenCLUtils::compileCLProgramFromString(m_clContext, m_clDevice, mprKernelsCL, &errNum, flags, 0, true); + ASSERT_EQ(CL_SUCCESS, errNum); + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, mprKernelsCL, "mprPenetrationKernel", &errNum, mprProg); + ASSERT_EQ(CL_SUCCESS, errNum); + + if (1) + { + const char* fileNames[] = {"mprPenetrationKernel60.bin", "mprPenetrationKernel61.bin", "mprPenetrationKernel70.bin", "mprPenetrationKernel128.bin"}; + int results[] = {0, 1, 46, 98}; + + int numTests = sizeof(fileNames) / sizeof(const char*); + for (int i = 0; i < numTests; i++) + { + b3LauncherCL launcher(m_clQueue, k, fileNames[i]); + testLauncher(fileNames[i], launcher, m_clContext); + clFinish(m_clQueue); + ASSERT_EQ(launcher.getNumArguments(), 11); + + b3KernelArgData data = launcher.getArgument(8); + ASSERT_TRUE(data.m_isBuffer); + b3OpenCLArray totalContactsOut(this->m_clContext, this->m_clQueue); + totalContactsOut.setFromOpenCLBuffer(data.m_clBuffer, 1); + int numContacts = totalContactsOut.at(0); + ASSERT_EQ(results[i], numContacts); + } + //printf("numContacts = %d\n",numContacts); + + //nContacts = m_totalContactsOut.at(0); + } + + clReleaseKernel(k); + } + + { + cl_kernel k = b3OpenCLUtils::compileCLKernelFromString(m_clContext, m_clDevice, mprKernelsCL, "findSeparatingAxisUnitSphereKernel", &errNum, mprProg); + ASSERT_EQ(CL_SUCCESS, errNum); + clReleaseKernel(k); + } + + clReleaseProgram(mprProg); +} + +}; // namespace diff --git a/test/OpenCL/BasicInitialize/main.cpp b/test/OpenCL/BasicInitialize/main.cpp index 1b4312bd5..4c5402d03 100644 --- a/test/OpenCL/BasicInitialize/main.cpp +++ b/test/OpenCL/BasicInitialize/main.cpp @@ -20,13 +20,11 @@ subject to the following restrictions: #include -cl_context g_cxMainContext; -cl_command_queue g_cqCommandQue; - +cl_context g_cxMainContext; +cl_command_queue g_cqCommandQue; #include "Bullet3Common/b3Logging.h" - void myerrorwarningprintf(const char* msg) { //OutputDebugStringA(msg); @@ -54,64 +52,63 @@ int main(int argc, char* argv[]) cl_device_type deviceType = CL_DEVICE_TYPE_ALL; const char* vendorSDK = b3OpenCLUtils::getSdkVendorName(); - b3Printf("This program was compiled using the %s OpenCL SDK\n",vendorSDK); + b3Printf("This program was compiled using the %s OpenCL SDK\n", vendorSDK); int numPlatforms = b3OpenCLUtils::getNumPlatforms(); b3Printf("Num Platforms = %d\n", numPlatforms); - for (int i=0;i memTester(g_cxMainContext,g_cqCommandQue,0,true); + b3OpenCLArray memTester(g_cxMainContext, g_cqCommandQue, 0, true); int maxMem = 0; - bool result=true; - for (size_t i=1;result;i++) + bool result = true; + for (size_t i = 1; result; i++) { - size_t numBytes = i*1024*1024; - result = memTester.resize(numBytes,false); + size_t numBytes = i * 1024 * 1024; + result = memTester.resize(numBytes, false); if (result) { maxMem = numBytes; - - } else + } + else { break; } } - printf("allocated %d MB successfully\n",maxMem/(1024*1024)); + printf("allocated %d MB successfully\n", maxMem / (1024 * 1024)); clReleaseCommandQueue(g_cqCommandQue); - g_cqCommandQue=0; - + g_cqCommandQue = 0; } clReleaseContext(g_cxMainContext); - g_cxMainContext=0; + g_cxMainContext = 0; } ///Easier method to initialize OpenCL using createContextFromType for a GPU deviceType = CL_DEVICE_TYPE_GPU; - void* glCtx=0; + void* glCtx = 0; void* glDC = 0; b3Printf("Initialize OpenCL using b3OpenCLUtils::createContextFromType for CL_DEVICE_TYPE_GPU\n"); g_cxMainContext = b3OpenCLUtils::createContextFromType(deviceType, &ciErrNum, glCtx, glDC); @@ -121,48 +118,47 @@ int main(int argc, char* argv[]) { int numDev = b3OpenCLUtils::getNumDevices(g_cxMainContext); - for (int i=0;i memTester(g_cxMainContext,g_cqCommandQue,0,true); - - bool result=true; - for (size_t i=1;result;i++) - { - size_t numBytes = i*1024*1024; - result = memTester.resize(numBytes,false); + b3OpenCLArray memTester(g_cxMainContext, g_cqCommandQue, 0, true); - if (result) - { - maxMem=numBytes; - - } else - { + bool result = true; + for (size_t i = 1; result; i++) + { + size_t numBytes = i * 1024 * 1024; + result = memTester.resize(numBytes, false); + + if (result) + { + maxMem = numBytes; + } + else + { break; - } - } - printf("allocated %d MB successfully\n",maxMem/(1024*1024)); + } + } + printf("allocated %d MB successfully\n", maxMem / (1024 * 1024)); } - clReleaseCommandQueue(g_cqCommandQue); } clReleaseContext(g_cxMainContext); - } - else { + else + { b3Printf("No OpenCL capable GPU found!"); } b3Printf("press \n"); diff --git a/test/OpenCL/BasicInitialize/testInitOpenCL.cpp b/test/OpenCL/BasicInitialize/testInitOpenCL.cpp index 32b43b10a..7163d3705 100644 --- a/test/OpenCL/BasicInitialize/testInitOpenCL.cpp +++ b/test/OpenCL/BasicInitialize/testInitOpenCL.cpp @@ -2,43 +2,40 @@ #include #include "Bullet3Common/b3Logging.h" - #include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h" -TEST(b3OpenCLUtils, getNumPlatforms) +TEST(b3OpenCLUtils, getNumPlatforms) { int numPlatforms = b3OpenCLUtils::getNumPlatforms(); - ASSERT_GT(numPlatforms,0); + ASSERT_GT(numPlatforms, 0); } - -TEST(b3OpenCLUtils, getSdkVendorName) +TEST(b3OpenCLUtils, getSdkVendorName) { const char* vendorSDK = b3OpenCLUtils::getSdkVendorName(); - b3Printf("getSdkVendorName=%s\n",vendorSDK); - ASSERT_FALSE(vendorSDK==NULL); + b3Printf("getSdkVendorName=%s\n", vendorSDK); + ASSERT_FALSE(vendorSDK == NULL); } - -TEST(b3OpenCLUtils, getPlatformInfo) +TEST(b3OpenCLUtils, getPlatformInfo) { int numPlatforms = b3OpenCLUtils::getNumPlatforms(); - ASSERT_GT(numPlatforms,0); + ASSERT_GT(numPlatforms, 0); b3Printf("Num Platforms = %d\n", numPlatforms); - for (int i=0;im_worldNormal.w; + }; + inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints) { + contact->m_worldNormal.w = (float)numPoints; + }; -}; -inline int b3Contact4Data_getNumPoints(const struct b3Contact4Data* contact) -{ - return (int)contact->m_worldNormal.w; -}; -inline void b3Contact4Data_setNumPoints(struct b3Contact4Data* contact, int numPoints) -{ - contact->m_worldNormal.w = (float)numPoints; -}; + typedef volatile __global int* my_counter32_t; -typedef volatile __global int* my_counter32_t; + __kernel void testKernel(__global int* testData, __global b3Contact4Data_t* contactData, my_counter32_t numElements) { + int id = get_local_id(0); + int sz = sizeof(b3Contact4Data_t); + testData[id] = sz; - -__kernel void testKernel( __global int* testData, __global b3Contact4Data_t* contactData, my_counter32_t numElements) -{ - int id = get_local_id(0); - int sz = sizeof(b3Contact4Data_t); - testData[id]=sz; - - __private b3Contact4Data_t tmp; - if (id==0) - { - tmp = contactData[1]; - contactData[1] = contactData[0]; - contactData[0] = tmp; + __private b3Contact4Data_t tmp; + if (id == 0) + { + tmp = contactData[1]; + contactData[1] = contactData[0]; + contactData[0] = tmp; + } } -} - - ); - - #include "Bullet3Common/b3Logging.h" - void myprintf(const char* msg) { //OutputDebugStringA(msg); - printf("%s",msg); + printf("%s", msg); } int main(int argc, char* argv[]) @@ -129,64 +115,62 @@ int main(int argc, char* argv[]) cl_device_type deviceType = CL_DEVICE_TYPE_GPU; const char* vendorSDK = b3OpenCLUtils::getSdkVendorName(); - b3Printf("This program was compiled using the %s OpenCL SDK\n",vendorSDK); + b3Printf("This program was compiled using the %s OpenCL SDK\n", vendorSDK); int numPlatforms = b3OpenCLUtils::getNumPlatforms(); b3Printf("Num Platforms = %d\n", numPlatforms); - for (int i=0;i deviceElements(context,queue); - b3OpenCLArray atomicCounter(context,queue); - b3OpenCLArray deviceContacts(context,queue); + b3OpenCLArray deviceElements(context, queue); + b3OpenCLArray atomicCounter(context, queue); + b3OpenCLArray deviceContacts(context, queue); b3AlignedObjectArray hostContacts; b3Contact4Data tmp; int sz = sizeof(b3Contact4Data); - memset(&tmp,1,sz); + memset(&tmp, 1, sz); deviceContacts.push_back(tmp); b3Contact4Data tmp2 = tmp; - memset(&tmp,2,sz); + memset(&tmp, 2, sz); deviceContacts.push_back(tmp); b3Contact4Data tmp3 = tmp; - atomicCounter.push_back(0); deviceElements.resize(numWorkItems); - b3LauncherCL run(queue,testKernel,"testKernel"); + b3LauncherCL run(queue, testKernel, "testKernel"); run.setBuffer(deviceElements.getBufferCL()); run.setBuffer(deviceContacts.getBufferCL()); run.setBuffer(atomicCounter.getBufferCL()); @@ -199,16 +183,12 @@ int main(int argc, char* argv[]) tmp2 = hostContacts[0]; tmp3 = hostContacts[1]; - printf("...\n"); - - } else + } + else { printf("kernel failed to compile\n"); } - - - } } diff --git a/test/OpenCL/ParallelPrimitives/main.cpp b/test/OpenCL/ParallelPrimitives/main.cpp index d7ebbc788..ee48bc11a 100644 --- a/test/OpenCL/ParallelPrimitives/main.cpp +++ b/test/OpenCL/ParallelPrimitives/main.cpp @@ -12,7 +12,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include #include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h" #include "Bullet3OpenCL/ParallelPrimitives/b3FillCL.h" @@ -27,13 +26,22 @@ int g_nFailed = 0; bool g_testFailed = 0; #define TEST_INIT g_testFailed = 0; -#define TEST_ASSERT(x) if( !(x) ){g_testFailed = 1;} -#define TEST_REPORT(testName) printf("[%s] %s\n",(g_testFailed)?"X":"O", testName); if(g_testFailed) g_nFailed++; else g_nPassed++; -#define NEXTMULTIPLEOF(num, alignment) (((num)/(alignment) + (((num)%(alignment)==0)?0:1))*(alignment)) +#define TEST_ASSERT(x) \ + if (!(x)) \ + { \ + g_testFailed = 1; \ + } +#define TEST_REPORT(testName) \ + printf("[%s] %s\n", (g_testFailed) ? "X" : "O", testName); \ + if (g_testFailed) \ + g_nFailed++; \ + else \ + g_nPassed++; +#define NEXTMULTIPLEOF(num, alignment) (((num) / (alignment) + (((num) % (alignment) == 0) ? 0 : 1)) * (alignment)) -cl_context g_context=0; -cl_device_id g_device=0; -cl_command_queue g_queue =0; +cl_context g_context = 0; +cl_device_id g_device = 0; +cl_command_queue g_queue = 0; const char* g_deviceName = 0; void initCL(int preferredDeviceIndex, int preferredPlatformIndex) @@ -45,17 +53,17 @@ void initCL(int preferredDeviceIndex, int preferredPlatformIndex) cl_device_type deviceType = CL_DEVICE_TYPE_ALL; - g_context = b3OpenCLUtils::createContextFromType(deviceType, &ciErrNum, 0,0,preferredDeviceIndex, preferredPlatformIndex); + g_context = b3OpenCLUtils::createContextFromType(deviceType, &ciErrNum, 0, 0, preferredDeviceIndex, preferredPlatformIndex); oclCHECKERROR(ciErrNum, CL_SUCCESS); int numDev = b3OpenCLUtils::getNumDevices(g_context); - if (numDev>0) + if (numDev > 0) { b3OpenCLDeviceInfo info; - g_device= b3OpenCLUtils::getDevice(g_context,0); + g_device = b3OpenCLUtils::getDevice(g_context, 0); g_queue = clCreateCommandQueue(g_context, g_device, 0, &ciErrNum); oclCHECKERROR(ciErrNum, CL_SUCCESS); - b3OpenCLUtils::printDeviceInfo(g_device); - b3OpenCLUtils::getDeviceInfo(g_device,&info); + b3OpenCLUtils::printDeviceInfo(g_device); + b3OpenCLUtils::getDeviceInfo(g_device, &info); g_deviceName = info.m_deviceName; } } @@ -66,100 +74,90 @@ void exitCL() clReleaseContext(g_context); } - inline void fillIntTest() { TEST_INIT; - b3FillCL* fillCL = new b3FillCL(g_context,g_device,g_queue); - int maxSize=1024*256; - b3OpenCLArray intBuffer(g_context,g_queue,maxSize); + b3FillCL* fillCL = new b3FillCL(g_context, g_device, g_queue); + int maxSize = 1024 * 256; + b3OpenCLArray intBuffer(g_context, g_queue, maxSize); intBuffer.resize(maxSize); - + #define NUM_TESTS 7 - int dx = maxSize/NUM_TESTS; - for (int iter=0;iterexecute(intBuffer,value,size,offset); + int offset = 0; + fillCL->execute(intBuffer, value, size, offset); b3AlignedObjectArray hostBuf2; hostBuf2.resize(size); - fillCL->executeHost(hostBuf2,value,size,offset); + fillCL->executeHost(hostBuf2, value, size, offset); b3AlignedObjectArray hostBuf; intBuffer.copyToHost(hostBuf); - for(int i=0; i -__inline -T getRandom(const T& minV, const T& maxV) +template +__inline T getRandom(const T& minV, const T& maxV) { - float r = (rand()%10000)/10000.f; + float r = (rand() % 10000) / 10000.f; T range = maxV - minV; - return (T)(minV + r*range); + return (T)(minV + r * range); } struct b3SortDataCompare { inline bool operator()(const b3SortData& first, const b3SortData& second) const { - return (first.m_key < second.m_key) || (first.m_key==second.m_key && first.m_value < second.m_value); + return (first.m_key < second.m_key) || (first.m_key == second.m_key && first.m_value < second.m_value); } }; - -void boundSearchTest( ) +void boundSearchTest() { TEST_INIT; - int maxSize = 1024*256; + int maxSize = 1024 * 256; int bucketSize = 256; - b3OpenCLArray srcCL(g_context,g_queue,maxSize); - b3OpenCLArray upperCL(g_context,g_queue,maxSize); - b3OpenCLArray lowerCL(g_context,g_queue,maxSize); - + b3OpenCLArray srcCL(g_context, g_queue, maxSize); + b3OpenCLArray upperCL(g_context, g_queue, maxSize); + b3OpenCLArray lowerCL(g_context, g_queue, maxSize); + b3AlignedObjectArray srcHost; b3AlignedObjectArray upperHost; b3AlignedObjectArray lowerHost; b3AlignedObjectArray upperHostCompare; b3AlignedObjectArray lowerHostCompare; - - b3BoundSearchCL* search = new b3BoundSearchCL(g_context,g_device,g_queue, maxSize); + b3BoundSearchCL* search = new b3BoundSearchCL(g_context, g_device, g_queue, maxSize); - int dx = maxSize/NUM_TESTS; - for(int iter=0; iterexecute(srcCL,size,upperCL,bucketSize,b3BoundSearchCL::BOUND_UPPER); - search->execute(srcCL,size,lowerCL,bucketSize,b3BoundSearchCL::BOUND_LOWER); + search->execute(srcCL, size, upperCL, bucketSize, b3BoundSearchCL::BOUND_UPPER); + search->execute(srcCL, size, lowerCL, bucketSize, b3BoundSearchCL::BOUND_LOWER); - search->executeHost(srcHost,size,upperHostCompare,bucketSize,b3BoundSearchCL::BOUND_UPPER); - search->executeHost(srcHost,size,lowerHostCompare,bucketSize,b3BoundSearchCL::BOUND_LOWER); + search->executeHost(srcHost, size, upperHostCompare, bucketSize, b3BoundSearchCL::BOUND_UPPER); + search->executeHost(srcHost, size, lowerHostCompare, bucketSize, b3BoundSearchCL::BOUND_LOWER); lowerCL.copyToHost(lowerHost); upperCL.copyToHost(upperHost); - for(int i=0; i buf0Host; b3AlignedObjectArray buf1Host; - b3OpenCLArray buf2CL(g_context,g_queue,maxSize); - b3OpenCLArray buf3CL(g_context,g_queue,maxSize); - - - b3PrefixScanCL* scan = new b3PrefixScanCL(g_context,g_device,g_queue,maxSize); - - int dx = maxSize/NUM_TESTS; - for(int iter=0; iter buf2CL(g_context, g_queue, maxSize); + b3OpenCLArray buf3CL(g_context, g_queue, maxSize); + + b3PrefixScanCL* scan = new b3PrefixScanCL(g_context, g_device, g_queue, maxSize); + + int dx = maxSize / NUM_TESTS; + for (int iter = 0; iter < NUM_TESTS; iter++) { - int size = b3Min( 128+dx*iter, maxSize ); + int size = b3Min(128 + dx * iter, maxSize); buf0Host.resize(size); buf1Host.resize(size); - for(int i=0; iexecuteHost(buf0Host, buf1Host, size, &sumHost ); - scan->execute( buf2CL, buf3CL, size, &sumGPU ); + scan->executeHost(buf0Host, buf1Host, size, &sumHost); + scan->execute(buf2CL, buf3CL, size, &sumGPU); buf3CL.copyToHost(buf0Host); - - TEST_ASSERT( sumHost == sumGPU ); - for(int i=0; i buf0Host; buf0Host.resize(maxSize); b3AlignedObjectArray buf1Host; - buf1Host.resize(maxSize ); - b3OpenCLArray buf2CL(g_context,g_queue,maxSize); + buf1Host.resize(maxSize); + b3OpenCLArray buf2CL(g_context, g_queue, maxSize); - b3RadixSort32CL* sort = new b3RadixSort32CL(g_context,g_device,g_queue,maxSize); + b3RadixSort32CL* sort = new b3RadixSort32CL(g_context, g_device, g_queue, maxSize); - int dx = maxSize/NUM_TESTS; - for(int iter=0; iterexecuteHost( buf0Host); + sort->executeHost(buf0Host); sort->execute(buf2CL); buf2CL.copyToHost(buf1Host); - - for(int i=0; i\n"); getchar(); } diff --git a/test/OpenCL/RadixSortBenchmark/main.cpp b/test/OpenCL/RadixSortBenchmark/main.cpp index 37bf63275..14ed3b15f 100644 --- a/test/OpenCL/RadixSortBenchmark/main.cpp +++ b/test/OpenCL/RadixSortBenchmark/main.cpp @@ -47,17 +47,16 @@ * Converted from CUDA to OpenCL/DirectCompute by Erwin Coumans ******************************************************************************/ #ifdef _WIN32 -#pragma warning (disable:4996) +#pragma warning(disable : 4996) #endif -#include -#include -#include -#include +#include +#include +#include +#include #include #include #include - //#include #include /********************** @@ -77,19 +76,16 @@ cl_command_queue g_cqCommandQueue; */ bool g_verbose; -///Preferred OpenCL device/platform. When < 0 then no preference is used. +///Preferred OpenCL device/platform. When < 0 then no preference is used. ///Note that b3OpenCLUtils might still use the preference of using a platform vendor that matches the SDK vendor used to build the application. ///Preferred device/platform take priority over this platform-vendor match int gPreferredDeviceId = -1; int gPreferredPlatformId = -1; - - /****************************************************************************** * Routines ******************************************************************************/ - /** * Keys-only sorting. Uses the GPU to sort the specified vector of elements for the given * number of iterations, displaying runtime information. @@ -105,7 +101,7 @@ int gPreferredPlatformId = -1; */ template void TimedSort( - unsigned int num_elements, + unsigned int num_elements, K *h_keys, unsigned int iterations) { @@ -114,21 +110,21 @@ void TimedSort( int max_elements = num_elements; b3AlignedObjectArray hostData; hostData.resize(num_elements); - for (int i=0;i gpuData(g_cxMainContext,g_cqCommandQueue); + b3OpenCLArray gpuData(g_cxMainContext, g_cqCommandQueue); gpuData.copyFromHost(hostData); //sorter.executeHost(gpuData); - sorter.execute(gpuData); - + sorter.execute(gpuData); + b3AlignedObjectArray hostDataSorted; gpuData.copyToHost(hostDataSorted); - + clFinish(g_cqCommandQueue); { @@ -148,44 +144,38 @@ void TimedSort( watch.reset(); - - for (int i = 0; i < iterations; i++) + for (int i = 0; i < iterations; i++) { - - - // Move a fresh copy of the problem into device storage gpuData.copyFromHost(hostData); clFinish(g_cqCommandQueue); // Start GPU timing record - double startMs = watch.getTimeMicroseconds()/1e3; - + double startMs = watch.getTimeMicroseconds() / 1e3; + // Call the sorting API routine sorter.execute(gpuData); - - clFinish(g_cqCommandQueue); - - double stopMs = watch.getTimeMicroseconds()/1e3; + + double stopMs = watch.getTimeMicroseconds() / 1e3; duration = stopMs - startMs; - + // End GPU timing record - elapsed += (double) duration; + elapsed += (double)duration; printf("duration = %f\n", duration); } // Display timing information double avg_runtime = elapsed / iterations; - // double throughput = ((double) num_elements) / avg_runtime / 1000.0 / 1000.0; - // printf(", %f GPU ms, %f x10^9 elts/sec\n", avg_runtime, throughput); - double throughput = ((double) num_elements) / avg_runtime / 1000.0 ; - printf(", %f GPU ms, %f x10^6 elts/sec\n", avg_runtime, throughput); + // double throughput = ((double) num_elements) / avg_runtime / 1000.0 / 1000.0; + // printf(", %f GPU ms, %f x10^9 elts/sec\n", avg_runtime, throughput); + double throughput = ((double)num_elements) / avg_runtime / 1000.0; + printf(", %f GPU ms, %f x10^6 elts/sec\n", avg_runtime, throughput); gpuData.copyToHost(hostData); - for (int i=0;i void TimedSort( - unsigned int num_elements, + unsigned int num_elements, K *h_keys, - V *h_values, - unsigned int iterations) + V *h_values, + unsigned int iterations) { - printf("Key-values, %d iterations, %d elements\n", iterations, num_elements); int max_elements = num_elements; b3AlignedObjectArray hostData; hostData.resize(num_elements); - for (int i=0;i gpuData(g_cxMainContext,g_cqCommandQueue); + b3OpenCLArray gpuData(g_cxMainContext, g_cqCommandQueue); gpuData.copyFromHost(hostData); //sorter.executeHost(gpuData); - sorter.execute(gpuData); - + sorter.execute(gpuData); + b3AlignedObjectArray hostDataSorted; gpuData.copyToHost(hostDataSorted); #if 0 @@ -242,8 +231,8 @@ void TimedSort( printf("hostData[%d].m_value = %d\n",i,hostDataSorted[i].m_value); } #endif - -clFinish(g_cqCommandQueue); + + clFinish(g_cqCommandQueue); { //printf("Key-values, %d iterations, %d elements", iterations, num_elements); @@ -254,7 +243,7 @@ clFinish(g_cqCommandQueue); double elapsed = 0; float duration = 0; b3Clock watch; - + //warm-start gpuData.copyFromHost(hostData); sorter.execute(gpuData); @@ -262,41 +251,37 @@ clFinish(g_cqCommandQueue); watch.reset(); - - for (int i = 0; i < iterations; i++) + for (int i = 0; i < iterations; i++) { - - - // Move a fresh copy of the problem into device storage gpuData.copyFromHost(hostData); clFinish(g_cqCommandQueue); // Start GPU timing record - double startMs = watch.getTimeMicroseconds()/1e3; - + double startMs = watch.getTimeMicroseconds() / 1e3; + // Call the sorting API routine sorter.execute(gpuData); clFinish(g_cqCommandQueue); - - double stopMs = watch.getTimeMicroseconds()/1e3; + + double stopMs = watch.getTimeMicroseconds() / 1e3; duration = stopMs - startMs; - + // End GPU timing record - elapsed += (double) duration; + elapsed += (double)duration; printf("duration = %f\n", duration); } // Display timing information double avg_runtime = elapsed / iterations; - // double throughput = ((double) num_elements) / avg_runtime / 1000.0 / 1000.0; - // printf(", %f GPU ms, %f x10^9 elts/sec\n", avg_runtime, throughput); - double throughput = ((double) num_elements) / avg_runtime / 1000.0 ; - printf(", %f GPU ms, %f x10^6 elts/sec\n", avg_runtime, throughput); + // double throughput = ((double) num_elements) / avg_runtime / 1000.0 / 1000.0; + // printf(", %f GPU ms, %f x10^9 elts/sec\n", avg_runtime, throughput); + double throughput = ((double)num_elements) / avg_runtime / 1000.0; + printf(", %f GPU ms, %f x10^6 elts/sec\n", avg_runtime, throughput); gpuData.copyToHost(hostData); - for (int i=0;i> 7); } key_bits[j] = quarterword; } - - if (lower_key_bits < sizeof(K) * 8) { + + if (lower_key_bits < sizeof(K) * 8) + { unsigned long long base = 0; memcpy(&base, key_bits, sizeof(K)); base &= (1 << lower_key_bits) - 1; memcpy(key_bits, &base, sizeof(K)); } - - memcpy(&key, key_bits, sizeof(K)); - - } while (key != key); // avoids NaNs when generating random floating point numbers -} + memcpy(&key, key_bits, sizeof(K)); + + } while (key != key); // avoids NaNs when generating random floating point numbers +} /****************************************************************************** * Templated routines for printing keys/values to the console ******************************************************************************/ -template -void PrintValue(T val) { +template +void PrintValue(T val) +{ printf("%d", val); } -template<> -void PrintValue(float val) { +template <> +void PrintValue(float val) +{ printf("%f", val); } -template<> -void PrintValue(double val) { +template <> +void PrintValue(double val) +{ printf("%f", val); } -template<> -void PrintValue(unsigned char val) { +template <> +void PrintValue(unsigned char val) +{ printf("%u", val); } -template<> -void PrintValue(unsigned short val) { +template <> +void PrintValue(unsigned short val) +{ printf("%u", val); } -template<> -void PrintValue(unsigned int val) { +template <> +void PrintValue(unsigned int val) +{ printf("%u", val); } -template<> -void PrintValue(long val) { +template <> +void PrintValue(long val) +{ printf("%ld", val); } -template<> -void PrintValue(unsigned long val) { +template <> +void PrintValue(unsigned long val) +{ printf("%lu", val); } -template<> -void PrintValue(long long val) { +template <> +void PrintValue(long long val) +{ printf("%lld", val); } -template<> -void PrintValue(unsigned long long val) { +template <> +void PrintValue(unsigned long long val) +{ printf("%llu", val); } - - /** * Compares the equivalence of two arrays */ template -int CompareResults(T* computed, T* reference, SizeT len, bool verbose = true) +int CompareResults(T *computed, T *reference, SizeT len, bool verbose = true) { printf("\n"); - for (SizeT i = 0; i < len; i++) { - - if (computed[i] != reference[i]) { - printf("INCORRECT: [%lu]: ", (unsigned long) i); + for (SizeT i = 0; i < len; i++) + { + if (computed[i] != reference[i]) + { + printf("INCORRECT: [%lu]: ", (unsigned long)i); PrintValue(computed[i]); printf(" != "); PrintValue(reference[i]); - if (verbose) { + if (verbose) + { printf("\nresult[..."); - for (size_t j = (i >= 5) ? i - 5 : 0; (j < i + 5) && (j < len); j++) { + for (size_t j = (i >= 5) ? i - 5 : 0; (j < i + 5) && (j < len); j++) + { PrintValue(computed[j]); printf(", "); } printf("...]"); printf("\nreference[..."); - for (size_t j = (i >= 5) ? i - 5 : 0; (j < i + 5) && (j < len); j++) { + for (size_t j = (i >= 5) ? i - 5 : 0; (j < i + 5) && (j < len); j++) + { PrintValue(reference[j]); printf(", "); } @@ -463,71 +460,74 @@ int CompareResults(T* computed, T* reference, SizeT len, bool verbose = true) * @param[in] cfg * Config */ -template +template void TestSort( unsigned int iterations, int num_elements, bool keys_only) { - // Allocate the sorting problem on the host and fill the keys with random bytes + // Allocate the sorting problem on the host and fill the keys with random bytes K *h_keys = NULL; K *h_reference_keys = NULL; V *h_values = NULL; - h_keys = (K*) malloc(num_elements * sizeof(K)); - h_reference_keys = (K*) malloc(num_elements * sizeof(K)); - if (!keys_only) h_values = (V*) malloc(num_elements * sizeof(V)); - + h_keys = (K *)malloc(num_elements * sizeof(K)); + h_reference_keys = (K *)malloc(num_elements * sizeof(K)); + if (!keys_only) h_values = (V *)malloc(num_elements * sizeof(V)); // Use random bits - for (unsigned int i = 0; i < num_elements; ++i) { + for (unsigned int i = 0; i < num_elements; ++i) + { RandomBits(h_keys[i], 0); //h_keys[i] = num_elements-i; - //h_keys[i] = 0xffffffffu-i; + //h_keys[i] = 0xffffffffu-i; if (!keys_only) - h_values[i] = h_keys[i];//0xffffffffu-i; + h_values[i] = h_keys[i]; //0xffffffffu-i; h_reference_keys[i] = h_keys[i]; } - // Run the timing test - if (keys_only) { + // Run the timing test + if (keys_only) + { TimedSort(num_elements, h_keys, iterations); - } else { + } + else + { TimedSort(num_elements, h_keys, h_values, iterations); } -// cudaThreadSynchronize(); - + // cudaThreadSynchronize(); + // Display sorted key data - if (g_verbose) { + if (g_verbose) + { printf("\n\nKeys:\n"); - for (int i = 0; i < num_elements; i++) { + for (int i = 0; i < num_elements; i++) + { PrintValue(h_keys[i]); printf(", "); } printf("\n\n"); - } - - // Verify solution - std::sort(h_reference_keys, h_reference_keys + num_elements); + } + + // Verify solution + std::sort(h_reference_keys, h_reference_keys + num_elements); CompareResults(h_keys, h_reference_keys, num_elements, true); printf("\n"); fflush(stdout); - // Free our allocated host memory + // Free our allocated host memory if (h_keys != NULL) free(h_keys); - if (h_values != NULL) free(h_values); + if (h_values != NULL) free(h_values); } - - /** * Displays the commandline usage for this tool */ -void Usage() +void Usage() { - printf("\ntest_large_problem_sorting [--device=] [--v] [--i=] [--n=] [--key-values] [--deviceId=] [--platformId=]\n"); + printf("\ntest_large_problem_sorting [--device=] [--v] [--i=] [--n=] [--key-values] [--deviceId=] [--platformId=]\n"); printf("\n"); printf("\t--v\tDisplays sorted results to the console.\n"); printf("\n"); @@ -541,7 +541,6 @@ void Usage() printf("\n"); } - /****************************************************************************** * Command-line parsing ******************************************************************************/ @@ -552,44 +551,47 @@ void Usage() class b3CommandLineArgs { protected: - std::map pairs; public: - // Constructor b3CommandLineArgs(int argc, char **argv) { using namespace std; - for (int i = 1; i < argc; i++) - { - string arg = argv[i]; + for (int i = 1; i < argc; i++) + { + string arg = argv[i]; - if ((arg[0] != '-') || (arg[1] != '-')) { - continue; - } + if ((arg[0] != '-') || (arg[1] != '-')) + { + continue; + } - string::size_type pos; - string key, val; - if ((pos = arg.find( '=')) == string::npos) { - key = string(arg, 2, arg.length() - 2); - val = ""; - } else { - key = string(arg, 2, pos - 2); - val = string(arg, pos + 1, arg.length() - 1); - } - pairs[key] = val; - } + string::size_type pos; + string key, val; + if ((pos = arg.find('=')) == string::npos) + { + key = string(arg, 2, arg.length() - 2); + val = ""; + } + else + { + key = string(arg, 2, pos - 2); + val = string(arg, pos + 1, arg.length() - 1); + } + pairs[key] = val; + } } - bool CheckCmdLineFlag(const char* arg_name) + bool CheckCmdLineFlag(const char *arg_name) { using namespace std; map::iterator itr; - if ((itr = pairs.find(arg_name)) != pairs.end()) { + if ((itr = pairs.find(arg_name)) != pairs.end()) + { return true; - } + } return false; } @@ -607,31 +609,29 @@ void b3CommandLineArgs::GetCmdLineArgument(const char *arg_name, T &val) { using namespace std; map::iterator itr; - if ((itr = pairs.find(arg_name)) != pairs.end()) { + if ((itr = pairs.find(arg_name)) != pairs.end()) + { istringstream strstream(itr->second); strstream >> val; - } -} - -template <> -void b3CommandLineArgs::GetCmdLineArgument(const char* arg_name, char* &val) -{ - using namespace std; - map::iterator itr; - if ((itr = pairs.find(arg_name)) != pairs.end()) { - - string s = itr->second; - val = (char*) malloc(sizeof(char) * (s.length() + 1)); - strcpy(val, s.c_str()); - - } else { - val = NULL; } } - - - +template <> +void b3CommandLineArgs::GetCmdLineArgument(const char *arg_name, char *&val) +{ + using namespace std; + map::iterator itr; + if ((itr = pairs.find(arg_name)) != pairs.end()) + { + string s = itr->second; + val = (char *)malloc(sizeof(char) * (s.length() + 1)); + strcpy(val, s.c_str()); + } + else + { + val = NULL; + } +} /****************************************************************************** * Main @@ -639,28 +639,28 @@ void b3CommandLineArgs::GetCmdLineArgument(const char* arg_name, char* &v extern bool gDebugSkipLoadingBinary; -void myprintf(const char* msg) +void myprintf(const char *msg) { - (void*) msg; + (void *)msg; } -int main( int argc, char** argv) +int main(int argc, char **argv) { //gDebugSkipLoadingBinary = true; -// b3SetCustomPrintfFunc(myprintf); + // b3SetCustomPrintfFunc(myprintf); cl_int ciErrNum; - b3CommandLineArgs args(argc,argv); + b3CommandLineArgs args(argc, argv); args.GetCmdLineArgument("deviceId", gPreferredDeviceId); args.GetCmdLineArgument("platformId", gPreferredPlatformId); b3Printf("Initialize OpenCL using b3OpenCLUtils_createContextFromType\n"); cl_platform_id platformId; -// g_cxMainContext = b3OpenCLUtils_createContextFromType(CL_DEVICE_TYPE_ALL, &ciErrNum, 0, 0,gPreferredDeviceId,gPreferredPlatformId,&platformId); - g_cxMainContext = b3OpenCLUtils_createContextFromType(CL_DEVICE_TYPE_GPU, &ciErrNum, 0, 0,gPreferredDeviceId,gPreferredPlatformId,&platformId); + // g_cxMainContext = b3OpenCLUtils_createContextFromType(CL_DEVICE_TYPE_ALL, &ciErrNum, 0, 0,gPreferredDeviceId,gPreferredPlatformId,&platformId); + g_cxMainContext = b3OpenCLUtils_createContextFromType(CL_DEVICE_TYPE_GPU, &ciErrNum, 0, 0, gPreferredDeviceId, gPreferredPlatformId, &platformId); //g_cxMainContext = b3OpenCLUtils_createContextFromType(CL_DEVICE_TYPE_CPU, &ciErrNum, 0, 0,gPreferredDeviceId,gPreferredPlatformId,&platformId); - + oclCHECKERROR(ciErrNum, CL_SUCCESS); int numDev = b3OpenCLUtils_getNumDevices(g_cxMainContext); @@ -671,47 +671,37 @@ int main( int argc, char** argv) exit(0); } int devId = 0; - g_device = b3OpenCLUtils_getDevice(g_cxMainContext,devId); + g_device = b3OpenCLUtils_getDevice(g_cxMainContext, devId); b3OpenCLUtils_printDeviceInfo(g_device); // create a command-queue g_cqCommandQueue = clCreateCommandQueue(g_cxMainContext, g_device, 0, &ciErrNum); oclCHECKERROR(ciErrNum, CL_SUCCESS); + //srand(time(NULL)); + srand(0); // presently deterministic + unsigned int num_elements = 8 * 1024 * 1024; //4*1024*1024;//4*1024*1024;//257;//8*524288;//2048;//512;//524288; + unsigned int iterations = 10; + bool keys_only = true; - //srand(time(NULL)); - srand(0); // presently deterministic - - unsigned int num_elements = 8*1024*1024;//4*1024*1024;//4*1024*1024;//257;//8*524288;//2048;//512;//524288; - unsigned int iterations = 10; - bool keys_only = true; - - // + // // Check command line arguments - // - - + // if (args.CheckCmdLineFlag("help")) { Usage(); return 0; } - + args.GetCmdLineArgument("i", iterations); args.GetCmdLineArgument("n", num_elements); - - keys_only = !args.CheckCmdLineFlag("key-values"); g_verbose = args.CheckCmdLineFlag("v"); - - TestSort( - iterations, - num_elements, - keys_only); - - + iterations, + num_elements, + keys_only); } diff --git a/test/OpenGLTrueTypeFont/main.cpp b/test/OpenGLTrueTypeFont/main.cpp index c33303903..20264af3d 100644 --- a/test/OpenGLTrueTypeFont/main.cpp +++ b/test/OpenGLTrueTypeFont/main.cpp @@ -18,14 +18,14 @@ subject to the following restrictions: #ifndef __APPLE__ #include #endif -#include //memset +#include //memset #ifdef __APPLE__ - #include "OpenGLWindow/MacOpenGLWindow.h" -#elif defined (_WIN32) - #include "OpenGLWindow/Win32OpenGLWindow.h" -#elif defined (__linux) - #include "OpenGLWindow/X11OpenGLWindow.h" +#include "OpenGLWindow/MacOpenGLWindow.h" +#elif defined(_WIN32) +#include "OpenGLWindow/Win32OpenGLWindow.h" +#elif defined(__linux) +#include "OpenGLWindow/X11OpenGLWindow.h" #endif #include "fontstash.h" @@ -46,7 +46,6 @@ int m_glutScreenHeight; bool useInterop = false; - #include "../OpenGLWindow/GLPrimInternalData.h" static PrimInternalData sData; @@ -59,243 +58,230 @@ GLuint m_vertexArrayObject,m_vertexBuffer; GLuint m_indexBuffer; */ - - void loadShader(); -unsigned int indexData[6] = {0,1,2,0,2,3}; +unsigned int indexData[6] = {0, 1, 2, 0, 2, 3}; -void loadBufferData(){ - Vertex vertexDataOrg[4] = { - { vec4(-0.5, -0.5, 0.0, 1.0 ), vec4( 1.0, 0.0, 0.0, 1.0 ) ,vec2(0,0)}, - { vec4(-0.5, 0.5, 0.0, 1.0 ), vec4( 1.0, 1.0, 1.0, 1.0 ) ,vec2(0,1)}, - { vec4( 0.5, 0.5, 0.0, 1.0 ), vec4( 1.0, 1.0, 1.0, 1.0 ) ,vec2(1,1)}, - { vec4( 0.5, -0.5, 0.0, 1.0 ), vec4( 1.0, 1.0, 1.0, 1.0 ) ,vec2(1,0)} - }; +void loadBufferData() +{ + Vertex vertexDataOrg[4] = { + {vec4(-0.5, -0.5, 0.0, 1.0), vec4(1.0, 0.0, 0.0, 1.0), vec2(0, 0)}, + {vec4(-0.5, 0.5, 0.0, 1.0), vec4(1.0, 1.0, 1.0, 1.0), vec2(0, 1)}, + {vec4(0.5, 0.5, 0.0, 1.0), vec4(1.0, 1.0, 1.0, 1.0), vec2(1, 1)}, + {vec4(0.5, -0.5, 0.0, 1.0), vec4(1.0, 1.0, 1.0, 1.0), vec2(1, 0)}}; - Vertex vertexData[4] = { - { vec4(-0.5, -0.5, 0.0, 1.0 ), vec4( 1.0, 1.0, 1.0, 1.0 ) ,vec2(0.0078125,0.015625)}, - { vec4(-0.5, 0.5, 0.0, 1.0 ), vec4( 1.0, 1.0, 1.0, 1.0 ) ,vec2(0.101562,0.015625)}, - { vec4( 0.5, 0.5, 0.0, 1.0 ), vec4( 1.0, 1.0, 1.0, 1.0 ) ,vec2(0.101562,0.105469)}, - { vec4( 0.5, -0.5, 0.0, 1.0 ), vec4( 1.0, 1.0, 1.0, 1.0 ) ,vec2(0.0078125,0.105469)} - }; - - Vertex vertexData2[4] = { - { vec4(0, 0.901042, 0.0, 1.0 ), vec4( 1.0, 1.0, 1.0, 1.0 ) ,vec2(0.0078125,0.015625)}, - { vec4(0.0234375, 0.901042, 0.0, 1.0 ), vec4( 1.0, 1.0, 1.0, 1.0 ) ,vec2(0.101562,0.015625)}, - { vec4( 0.0234375, 0.871094, 0.0, 1.0 ), vec4( 1.0, 1.0, 1.0, 1.0 ) ,vec2(0.101562,0.105469)}, - { vec4( 0., 0.871094, 0.0, 1.0 ), vec4( 1.0, 1.0, 1.0, 1.0 ) ,vec2(0.0078125,0.105469)} - }; + Vertex vertexData[4] = { + {vec4(-0.5, -0.5, 0.0, 1.0), vec4(1.0, 1.0, 1.0, 1.0), vec2(0.0078125, 0.015625)}, + {vec4(-0.5, 0.5, 0.0, 1.0), vec4(1.0, 1.0, 1.0, 1.0), vec2(0.101562, 0.015625)}, + {vec4(0.5, 0.5, 0.0, 1.0), vec4(1.0, 1.0, 1.0, 1.0), vec2(0.101562, 0.105469)}, + {vec4(0.5, -0.5, 0.0, 1.0), vec4(1.0, 1.0, 1.0, 1.0), vec2(0.0078125, 0.105469)}}; + + Vertex vertexData2[4] = { + {vec4(0, 0.901042, 0.0, 1.0), vec4(1.0, 1.0, 1.0, 1.0), vec2(0.0078125, 0.015625)}, + {vec4(0.0234375, 0.901042, 0.0, 1.0), vec4(1.0, 1.0, 1.0, 1.0), vec2(0.101562, 0.015625)}, + {vec4(0.0234375, 0.871094, 0.0, 1.0), vec4(1.0, 1.0, 1.0, 1.0), vec2(0.101562, 0.105469)}, + {vec4(0., 0.871094, 0.0, 1.0), vec4(1.0, 1.0, 1.0, 1.0), vec2(0.0078125, 0.105469)}}; - glGenVertexArrays(1, &sData.m_vertexArrayObject); - glBindVertexArray(sData.m_vertexArrayObject); - - glGenBuffers(1, &sData.m_vertexBuffer); - glBindBuffer(GL_ARRAY_BUFFER, sData.m_vertexBuffer); - glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(Vertex), vertexData, GL_STATIC_DRAW); - GLuint err = glGetError(); - b3Assert(err==GL_NO_ERROR); + glBindVertexArray(sData.m_vertexArrayObject); - - - glGenBuffers(1, &sData.m_indexBuffer); - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sData.m_indexBuffer); - glBufferData(GL_ELEMENT_ARRAY_BUFFER,6*sizeof(int), indexData,GL_STATIC_DRAW); - - glEnableVertexAttribArray(sData.m_positionAttribute); - glEnableVertexAttribArray(sData.m_colourAttribute); + glGenBuffers(1, &sData.m_vertexBuffer); + glBindBuffer(GL_ARRAY_BUFFER, sData.m_vertexBuffer); + glBufferData(GL_ARRAY_BUFFER, 4 * sizeof(Vertex), vertexData, GL_STATIC_DRAW); + GLuint err = glGetError(); + b3Assert(err == GL_NO_ERROR); + + glGenBuffers(1, &sData.m_indexBuffer); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, sData.m_indexBuffer); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, 6 * sizeof(int), indexData, GL_STATIC_DRAW); + + glEnableVertexAttribArray(sData.m_positionAttribute); + glEnableVertexAttribArray(sData.m_colourAttribute); err = glGetError(); - b3Assert(err==GL_NO_ERROR); - + b3Assert(err == GL_NO_ERROR); + glEnableVertexAttribArray(sData.m_textureAttribute); - - glVertexAttribPointer(sData.m_positionAttribute, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)0); - glVertexAttribPointer(sData.m_colourAttribute , 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)sizeof(vec4)); - glVertexAttribPointer(sData.m_textureAttribute , 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid *)(sizeof(vec4)+sizeof(vec4))); + + glVertexAttribPointer(sData.m_positionAttribute, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)0); + glVertexAttribPointer(sData.m_colourAttribute, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)sizeof(vec4)); + glVertexAttribPointer(sData.m_textureAttribute, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (const GLvoid*)(sizeof(vec4) + sizeof(vec4))); err = glGetError(); - b3Assert(err==GL_NO_ERROR); - + b3Assert(err == GL_NO_ERROR); } void initTestTexture() { - // glEnable(GL_TEXTURE_2D); - glGenTextures(1,(GLuint*)&sData.m_texturehandle); - - GLint err = glGetError(); - b3Assert(err==GL_NO_ERROR); - - glBindTexture(GL_TEXTURE_2D,sData.m_texturehandle); - - err = glGetError(); - b3Assert(err==GL_NO_ERROR); - - err = glGetError(); - b3Assert(err==GL_NO_ERROR); - - int width=256; - int height=256; - unsigned char* image = (unsigned char*)malloc(width*height); - memset(image,0,width*height); - for (int i=0;i] [--load_bulletfile=test.bullet] [--enable_interop=<0 or 1>] [--enable_gpusap=<0 or 1>] [--enable_convexheightfield=<0 or 1>] [--enable_static=<0 or 1>] [--x_dim=] [--y_dim=] [--z_dim=] [--x_gap=] [--y_gap=] [--z_gap=]\n"); + printf("\nprogram.exe [--pause_simulation=<0 or 1>] [--load_bulletfile=test.bullet] [--enable_interop=<0 or 1>] [--enable_gpusap=<0 or 1>] [--enable_convexheightfield=<0 or 1>] [--enable_static=<0 or 1>] [--x_dim=] [--y_dim=] [--z_dim=] [--x_gap=] [--y_gap=] [--z_gap=]\n"); }; int main(int argc, char* argv[]) { GLint err; - b3CommandLineArgs args(argc,argv); + b3CommandLineArgs args(argc, argv); if (args.CheckCmdLineFlag("help")) { @@ -304,85 +290,74 @@ int main(int argc, char* argv[]) } args.GetCmdLineArgument("enable_interop", useInterop); - printf("useInterop=%d\n",useInterop); - - + printf("useInterop=%d\n", useInterop); args.GetCmdLineArgument("pause_simulation", pauseSimulation); - printf("pause_simulation=%d\n",pauseSimulation); - + printf("pause_simulation=%d\n", pauseSimulation); - char* tmpfile = 0; - args.GetCmdLineArgument("load_bulletfile", tmpfile ); + args.GetCmdLineArgument("load_bulletfile", tmpfile); if (tmpfile) fileName = tmpfile; - printf("load_bulletfile=%s\n",fileName); + printf("load_bulletfile=%s\n", fileName); int width = 700; - int height= 512; + int height = 512; printf("\n"); - - + b3gDefaultOpenGLWindow* window = new b3gDefaultOpenGLWindow(); - window->createWindow(b3gWindowConstructionInfo(width,height)); + window->createWindow(b3gWindowConstructionInfo(width, height)); window->setWindowTitle("font test"); - - #ifndef __APPLE__ err = glewInit(); #endif - window->runMainLoop(); - - loadShader(); - - loadBufferData(); - - initTestTexture(); - + window->runMainLoop(); + + loadShader(); + + loadBufferData(); + + initTestTexture(); + window->startRendering(); window->endRendering(); - - err = glGetError(); - b3Assert(err==GL_NO_ERROR); - - -// render.InitShaders(); - -// render.writeTransforms(); + err = glGetError(); + b3Assert(err == GL_NO_ERROR); - window->runMainLoop(); + // render.InitShaders(); -// window->setMouseCallback(b3DefaultMouseCallback); -// window->setKeyboardCallback(b3DefaultKeyboardCallback); - // window->setWheelCallback(b3DefaultWheelCallback); + // render.writeTransforms(); - err = glGetError(); - b3Assert(err==GL_NO_ERROR); + window->runMainLoop(); + // window->setMouseCallback(b3DefaultMouseCallback); + // window->setKeyboardCallback(b3DefaultKeyboardCallback); + // window->setWheelCallback(b3DefaultWheelCallback); - int done; + err = glGetError(); + b3Assert(err == GL_NO_ERROR); + + int done; struct sth_stash* stash = 0; FILE* fp = 0; int datasize; - float sx,sy,dx,dy,lh; - int droidRegular;//, droidItalic, droidBold, droidJapanese, dejavu; + float sx, sy, dx, dy, lh; + int droidRegular; //, droidItalic, droidBold, droidJapanese, dejavu; GLuint texture; - int fontTextureWidth = 512; int fontTextureHeight = 512; SimpleOpenGL2RenderCallbacks* renderCallbacks = new SimpleOpenGL2RenderCallbacks(&sData); - stash = sth_create(fontTextureWidth,fontTextureHeight,renderCallbacks); - - err = glGetError(); - b3Assert(err==GL_NO_ERROR); - + stash = sth_create(fontTextureWidth, fontTextureHeight, renderCallbacks); + + err = glGetError(); + b3Assert(err == GL_NO_ERROR); + if (!stash) { fprintf(stderr, "Could not create stash.\n"); @@ -391,287 +366,274 @@ int main(int argc, char* argv[]) // Load the first truetype font from memory (just because we can). #ifdef _WIN32 - const char* fontPath = "../../bin/"; + const char* fontPath = "../../bin/"; #else - const char* fontPath = "./"; + const char* fontPath = "./"; #endif - - char fullFontFileName[1024]; - sprintf(fullFontFileName,"%s%s",fontPath,"DroidSerif-Regular.ttf");//cour.ttf");//times.ttf");//DroidSerif-Regular.ttf"); + + char fullFontFileName[1024]; + sprintf(fullFontFileName, "%s%s", fontPath, "DroidSerif-Regular.ttf"); //cour.ttf");//times.ttf");//DroidSerif-Regular.ttf"); //sprintf(fullFontFileName,"%s%s",fontPath,"arial.ttf");//cour.ttf");//times.ttf");//DroidSerif-Regular.ttf"); - + fp = fopen(fullFontFileName, "rb"); #ifdef LOAD_FONT_FROM_FILE - unsigned char* data; - err = glGetError(); - b3Assert(err==GL_NO_ERROR); - - b3Assert(fp); - if (fp) - { - fseek(fp, 0, SEEK_END); - datasize = (int)ftell(fp); - fseek(fp, 0, SEEK_SET); - data = (unsigned char*)malloc(datasize); - if (data == NULL) - { - b3Assert(0); - return -1; - } - else - fread(data, 1, datasize, fp); - fclose(fp); - fp = 0; - } + unsigned char* data; + err = glGetError(); + b3Assert(err == GL_NO_ERROR); + + b3Assert(fp); + if (fp) + { + fseek(fp, 0, SEEK_END); + datasize = (int)ftell(fp); + fseek(fp, 0, SEEK_SET); + data = (unsigned char*)malloc(datasize); + if (data == NULL) + { + b3Assert(0); + return -1; + } + else + fread(data, 1, datasize, fp); + fclose(fp); + fp = 0; + } if (!(droidRegular = sth_add_font_from_memory(stash, data))) - { - b3Assert(0); - return -1; - } - err = glGetError(); - b3Assert(err==GL_NO_ERROR); + { + b3Assert(0); + return -1; + } + err = glGetError(); + b3Assert(err == GL_NO_ERROR); // Load the remaining truetype fonts directly. - sprintf(fullFontFileName,"%s%s",fontPath,"DroidSerif-Italic.ttf"); + sprintf(fullFontFileName, "%s%s", fontPath, "DroidSerif-Italic.ttf"); - if (!(droidItalic = sth_add_font(stash,fullFontFileName))) + if (!(droidItalic = sth_add_font(stash, fullFontFileName))) { - b3Assert(0); - return -1; - } - sprintf(fullFontFileName,"%s%s",fontPath,"DroidSerif-Bold.ttf"); + b3Assert(0); + return -1; + } + sprintf(fullFontFileName, "%s%s", fontPath, "DroidSerif-Bold.ttf"); - - if (!(droidBold = sth_add_font(stash,fullFontFileName))) + if (!(droidBold = sth_add_font(stash, fullFontFileName))) { - b3Assert(0); - return -1; - } - err = glGetError(); - b3Assert(err==GL_NO_ERROR); - - sprintf(fullFontFileName,"%s%s",fontPath,"DroidSansJapanese.ttf"); - if (!(droidJapanese = sth_add_font(stash,fullFontFileName))) + b3Assert(0); + return -1; + } + err = glGetError(); + b3Assert(err == GL_NO_ERROR); + + sprintf(fullFontFileName, "%s%s", fontPath, "DroidSansJapanese.ttf"); + if (!(droidJapanese = sth_add_font(stash, fullFontFileName))) { - b3Assert(0); - return -1; - } - err = glGetError(); - b3Assert(err==GL_NO_ERROR); -#else//LOAD_FONT_FROM_FILE + b3Assert(0); + return -1; + } + err = glGetError(); + b3Assert(err == GL_NO_ERROR); +#else //LOAD_FONT_FROM_FILE char* data2 = OpenSansData; - unsigned char* data = (unsigned char*) data2; + unsigned char* data = (unsigned char*)data2; if (!(droidRegular = sth_add_font_from_memory(stash, data))) { printf("error!\n"); } -#endif//LOAD_FONT_FROM_FILE - - +#endif //LOAD_FONT_FROM_FILE while (!window->requestedExit()) { - GLint err = glGetError(); - b3Assert(err==GL_NO_ERROR); - - // glClearColor(0.5f,0.5f,0.5f,1.f); - - err = glGetError(); - b3Assert(err==GL_NO_ERROR); - - window->startRendering(); - - err = glGetError(); - b3Assert(err==GL_NO_ERROR); - - glClearColor(1,1,1,1);//.4, .4, 0.4, 1.0); - glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); + GLint err = glGetError(); + b3Assert(err == GL_NO_ERROR); - //display(); - - err = glGetError(); - b3Assert(err==GL_NO_ERROR); - - if (1) - { - B3_PROFILE("font stash rendering"); - // Update and render - glEnable(GL_BLEND); - err = glGetError(); - b3Assert(err==GL_NO_ERROR); + // glClearColor(0.5f,0.5f,0.5f,1.f); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - err = glGetError(); - b3Assert(err==GL_NO_ERROR); + err = glGetError(); + b3Assert(err == GL_NO_ERROR); - err = glGetError(); - b3Assert(err==GL_NO_ERROR); - - glDisable(GL_DEPTH_TEST); - err = glGetError(); - b3Assert(err==GL_NO_ERROR); - - //glColor4ub(255,0,0,255); - - err = glGetError(); - b3Assert(err==GL_NO_ERROR); - - glEnable(GL_BLEND); - - err = glGetError(); - b3Assert(err==GL_NO_ERROR); - glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); - err = glGetError(); - b3Assert(err==GL_NO_ERROR); - - sx = 0; sy = height; - - sth_begin_draw(stash); - - display(); + window->startRendering(); - dx = sx; dy = sy; - static int once=0; + err = glGetError(); + b3Assert(err == GL_NO_ERROR); + glClearColor(1, 1, 1, 1); //.4, .4, 0.4, 1.0); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + //display(); + + err = glGetError(); + b3Assert(err == GL_NO_ERROR); - //sth_draw_text(stash, droidRegular,12.f, dx, dy-50, "How does this OpenGL True Type font look? ", &dx,width,height); - int spacing = 512; if (1) - for (int i=20;i<=110;i+=12) { - char txt[512]; - sprintf(txt,"%d. The quick brown fox jumped over the lazy dog. 1234567890",i); - sth_draw_text(stash, droidRegular,i, 10, dy-spacing, txt, &dx,width,height); - spacing-=i; - } - - err = glGetError(); - b3Assert(err==GL_NO_ERROR); + B3_PROFILE("font stash rendering"); + // Update and render + glEnable(GL_BLEND); + err = glGetError(); + b3Assert(err == GL_NO_ERROR); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + err = glGetError(); + b3Assert(err == GL_NO_ERROR); + + err = glGetError(); + b3Assert(err == GL_NO_ERROR); + + glDisable(GL_DEPTH_TEST); + err = glGetError(); + b3Assert(err == GL_NO_ERROR); + + //glColor4ub(255,0,0,255); + + err = glGetError(); + b3Assert(err == GL_NO_ERROR); + + glEnable(GL_BLEND); + + err = glGetError(); + b3Assert(err == GL_NO_ERROR); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + err = glGetError(); + b3Assert(err == GL_NO_ERROR); + + sx = 0; + sy = height; + + sth_begin_draw(stash); + + display(); - if (0) - for (int i=0;i<1;i++) - { dx = sx; - if (once!=1) - { - //need to save this file as UTF-8 without signature, codepage 650001 in Visual Studio - err = glGetError(); - b3Assert(err==GL_NO_ERROR); + dy = sy; + static int once = 0; - //sth_draw_text(stash, droidJapanese,16.f, dx, dy-36, (const char*) "\xE7\xA7\x81\xE3\x81\xAF\xE3\x82\xAC\xE3\x83\xA9\xE3\x82\xB9\xE3\x82\x92\xE9\xA3\x9F\xE3\x81\xB9\xE3\x82\x89\xE3\x82\x8C\xE3\x81\xBE\xE3\x81\x99\xE3\x80\x82",&dx, - // width,height);//ã¯abcdefghijlkmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_-+=?/\][{}.,<>`~@#$%^", &dx); -// sth_draw_text(stash, droidJapanese,32.f, dx, dy, (const char*) "ç§ã¯ã‚¬ãƒ©ã‚¹ã‚’食ã¹ã‚‰ã‚Œã¾ã™ã€‚ãれã¯ç§ã‚’å‚·ã¤ã‘ã¾ã›ã‚“。",&dx);//ã¯abcdefghijlkmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_-+=?/\][{}.,<>`~@#$%^", &dx); - - dx = sx; + //sth_draw_text(stash, droidRegular,12.f, dx, dy-50, "How does this OpenGL True Type font look? ", &dx,width,height); + int spacing = 512; + if (1) + for (int i = 20; i <= 110; i += 12) + { + char txt[512]; + sprintf(txt, "%d. The quick brown fox jumped over the lazy dog. 1234567890", i); + sth_draw_text(stash, droidRegular, i, 10, dy - spacing, txt, &dx, width, height); + spacing -= i; + } - err = glGetError(); - b3Assert(err==GL_NO_ERROR); - sth_flush_draw(stash); - dx=0; - sth_draw_text(stash, droidRegular,14.f, dx, dy-80, "How does this OpenGL True Type font look? ", &dx,width,height); - dx=0; - dy-=30; + err = glGetError(); + b3Assert(err == GL_NO_ERROR); - //sth_draw_text(stash, droidRegular,16.f, dx, dy-80, "Profile How does this OpenGL True Type font look? ", &dx,width,height); - dx=0; - dy-=30; + if (0) + for (int i = 0; i < 1; i++) + { + dx = sx; + if (once != 1) + { + //need to save this file as UTF-8 without signature, codepage 650001 in Visual Studio + err = glGetError(); + b3Assert(err == GL_NO_ERROR); - - sth_draw_text(stash, droidRegular,16.f, dx, dy-80, "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", &dx,width,height); - dx=0; - dy-=30; - sth_draw_text(stash, droidRegular,16.f, dx, dy-80, "!@#$%^abcdefghijklmnopqrstuvwxyz", &dx,width,height); + //sth_draw_text(stash, droidJapanese,16.f, dx, dy-36, (const char*) "\xE7\xA7\x81\xE3\x81\xAF\xE3\x82\xAC\xE3\x83\xA9\xE3\x82\xB9\xE3\x82\x92\xE9\xA3\x9F\xE3\x81\xB9\xE3\x82\x89\xE3\x82\x8C\xE3\x81\xBE\xE3\x81\x99\xE3\x80\x82",&dx, + // width,height);//ã¯abcdefghijlkmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_-+=?/\][{}.,<>`~@#$%^", &dx); + // sth_draw_text(stash, droidJapanese,32.f, dx, dy, (const char*) "ç§ã¯ã‚¬ãƒ©ã‚¹ã‚’食ã¹ã‚‰ã‚Œã¾ã™ã€‚ãれã¯ç§ã‚’å‚·ã¤ã‘ã¾ã›ã‚“。",&dx);//ã¯abcdefghijlkmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()_-+=?/\][{}.,<>`~@#$%^", &dx); - dx=0; - // sth_draw_text(stash, droidRegular,16.f, dx, dy-42, "aph OpenGL Profile aCABCabdabcdefghijlkmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^", &dx,width,height); - //sth_draw_text(stash, droidRegular,16.f, dx, dy-42, "aph OpenGL Profile aCABCabdabcdefghijlkmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^", &dx,width,height); + dx = sx; - sth_flush_draw(stash); - err = glGetError(); - b3Assert(err==GL_NO_ERROR); + err = glGetError(); + b3Assert(err == GL_NO_ERROR); + sth_flush_draw(stash); + dx = 0; + sth_draw_text(stash, droidRegular, 14.f, dx, dy - 80, "How does this OpenGL True Type font look? ", &dx, width, height); + dx = 0; + dy -= 30; + //sth_draw_text(stash, droidRegular,16.f, dx, dy-80, "Profile How does this OpenGL True Type font look? ", &dx,width,height); + dx = 0; + dy -= 30; - } else - { - dx = sx; - dy = height; - - err = glGetError(); - b3Assert(err==GL_NO_ERROR); + sth_draw_text(stash, droidRegular, 16.f, dx, dy - 80, "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", &dx, width, height); + dx = 0; + dy -= 30; + sth_draw_text(stash, droidRegular, 16.f, dx, dy - 80, "!@#$%^abcdefghijklmnopqrstuvwxyz", &dx, width, height); - - sth_draw_texture(stash, droidRegular, 16.f, 0, 0,width,height, "a", &dx); - err = glGetError(); - b3Assert(err==GL_NO_ERROR); + dx = 0; + // sth_draw_text(stash, droidRegular,16.f, dx, dy-42, "aph OpenGL Profile aCABCabdabcdefghijlkmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^", &dx,width,height); + //sth_draw_text(stash, droidRegular,16.f, dx, dy-42, "aph OpenGL Profile aCABCabdabcdefghijlkmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^", &dx,width,height); - dumpTextureToPng(fontTextureWidth, fontTextureHeight,"newPic.png"); + sth_flush_draw(stash); + err = glGetError(); + b3Assert(err == GL_NO_ERROR); + } + else + { + dx = sx; + dy = height; + err = glGetError(); + b3Assert(err == GL_NO_ERROR); - } - once++; + sth_draw_texture(stash, droidRegular, 16.f, 0, 0, width, height, "a", &dx); + err = glGetError(); + b3Assert(err == GL_NO_ERROR); + + dumpTextureToPng(fontTextureWidth, fontTextureHeight, "newPic.png"); + } + once++; + } + err = glGetError(); + b3Assert(err == GL_NO_ERROR); + + sth_end_draw(stash); + + glEnable(GL_DEPTH_TEST); + err = glGetError(); + b3Assert(err == GL_NO_ERROR); + + //glFinish(); } - err = glGetError(); - b3Assert(err==GL_NO_ERROR); - - sth_end_draw(stash); - - glEnable(GL_DEPTH_TEST); - err = glGetError(); - b3Assert(err==GL_NO_ERROR); - - //glFinish(); - } - err = glGetError(); - b3Assert(err==GL_NO_ERROR); - + err = glGetError(); + b3Assert(err == GL_NO_ERROR); window->endRendering(); - err = glGetError(); - b3Assert(err==GL_NO_ERROR); - + err = glGetError(); + b3Assert(err == GL_NO_ERROR); + { glFinish(); } + static bool printStats = true; - static bool printStats = true; - - - - if (printStats && !pauseSimulation) - { + if (printStats && !pauseSimulation) + { static int count = 0; count--; - if (count<0) + if (count < 0) { count = 100; -// b3ProfileManager::dumpAll(); + // b3ProfileManager::dumpAll(); //printStats = false; - } else - { -// printf("."); } - } - - err = glGetError(); - b3Assert(err==GL_NO_ERROR); - + else + { + // printf("."); + } + } + err = glGetError(); + b3Assert(err == GL_NO_ERROR); } #ifdef _WIN32 sth_delete(stash); #ifdef LOAD_FONT_FROM_FILE free(data); -#endif //LOAD_FONT_FROM_FILE +#endif //LOAD_FONT_FROM_FILE #endif -// render.CleanupShaders(); + // render.CleanupShaders(); window->closeWindow(); delete window; - - return 0; + return 0; } diff --git a/test/RobotClientAPI/SlopeFrictionMain.cpp b/test/RobotClientAPI/SlopeFrictionMain.cpp index f0d802667..af28dadf8 100644 --- a/test/RobotClientAPI/SlopeFrictionMain.cpp +++ b/test/RobotClientAPI/SlopeFrictionMain.cpp @@ -6,64 +6,61 @@ #include #include #include -#define ASSERT_EQ(a,b) assert((a)==(b)); +#define ASSERT_EQ(a, b) assert((a) == (b)); #include "MinitaurSetup.h" #define NUM_SIM 1 int main(int argc, char* argv[]) { b3RobotSimulatorClientAPI* sims[2]; - b3Scalar fixedTimeStep = 1./240.; - for (int i=0;iconnect(eCONNECT_GUI);//eCONNECT_GUI);//DIRECT); + sim->connect(eCONNECT_GUI); //eCONNECT_GUI);//DIRECT); //Can also use eCONNECT_DIRECT,eCONNECT_SHARED_MEMORY,eCONNECT_UDP,eCONNECT_TCP, for example: //sim->connect(eCONNECT_UDP, "localhost", 1234); - sim->configureDebugVisualizer( COV_ENABLE_GUI, 0); - // sim->configureDebugVisualizer( COV_ENABLE_SHADOWS, 0);//COV_ENABLE_WIREFRAME + sim->configureDebugVisualizer(COV_ENABLE_GUI, 0); + // sim->configureDebugVisualizer( COV_ENABLE_SHADOWS, 0);//COV_ENABLE_WIREFRAME //sim->setTimeOut(3); //syncBodies is only needed when connecting to an existing physics server that has already some bodies sim->syncBodies(); - sim->setTimeStep(fixedTimeStep); - b3Quaternion q = sim->getQuaternionFromEuler(b3MakeVector3(0.1,0.2,0.3)); + b3Quaternion q = sim->getQuaternionFromEuler(b3MakeVector3(0.1, 0.2, 0.3)); b3Vector3 rpy; rpy = sim->getEulerFromQuaternion(q); - sim->setGravity(b3MakeVector3(0,0,-9.8)); + sim->setGravity(b3MakeVector3(0, 0, -9.8)); //int blockId = sim->loadURDF("cube.urdf"); //b3BodyInfo bodyInfo; //sim->getBodyInfo(blockId,&bodyInfo); b3Quaternion orn; - orn.setEulerZYX(0,B3_PI*0.23,0); - + orn.setEulerZYX(0, B3_PI * 0.23, 0); + b3RobotSimulatorLoadUrdfFileArgs args; - args.m_startPosition.setValue(0,0,0); + args.m_startPosition.setValue(0, 0, 0); args.m_startOrientation = orn; - args.m_useMultiBody = i==0? false : true;//true : false;//false : true; - - sim->loadURDF("plane.urdf",args); + args.m_useMultiBody = i == 0 ? false : true; //true : false;//false : true; - args.m_startPosition.setValue(0,0,0.66); - args.m_startOrientation.setEulerZYX(0,B3_PI*0.23,0); - sim->loadURDF("cube_soft.urdf",args); + sim->loadURDF("plane.urdf", args); + + args.m_startPosition.setValue(0, 0, 0.66); + args.m_startOrientation.setEulerZYX(0, B3_PI * 0.23, 0); + sim->loadURDF("cube_soft.urdf", args); - double distance = 1.5; double yaw = 50; - sim->resetDebugVisualizerCamera(distance,yaw,20,b3MakeVector3(0,0,0.1)); + sim->resetDebugVisualizerCamera(distance, yaw, 20, b3MakeVector3(0, 0, 0.1)); sim->setRealTimeSimulation(false); - } int enableSim = 1; - while (sims[0]->canSubmitCommand()) + while (sims[0]->canSubmitCommand()) { - #if 0 +#if 0 b3KeyboardEventsData keyEvents; sim->getKeyboardEvents(&keyEvents); if (keyEvents.m_numKeyboardEvents) @@ -79,33 +76,27 @@ int main(int argc, char* argv[]) } } } - #endif - for (int i=0;isetGravity(b3MakeVector3(0,0,-10)); + sims[i]->setGravity(b3MakeVector3(0, 0, -10)); //printf("."); if (enableSim) { - sims[i]->stepSimulation(); + sims[i]->stepSimulation(); } } - b3Clock::usleep(1000.*1000.*fixedTimeStep); + b3Clock::usleep(1000. * 1000. * fixedTimeStep); } printf("sim->disconnect\n"); - for (int i=0;idisconnect(); printf("delete sim\n"); delete sims[i]; - } - printf("exit\n"); - } - - diff --git a/test/RobotLogging/main.cpp b/test/RobotLogging/main.cpp index a2e1b3992..3bdf6452c 100644 --- a/test/RobotLogging/main.cpp +++ b/test/RobotLogging/main.cpp @@ -3,13 +3,12 @@ #ifndef ENABLE_GTEST #include -#define ASSERT_EQ(a,b) assert((a)==(b)); +#define ASSERT_EQ(a, b) assert((a) == (b)); #else #include #define printf #endif - void testMinitaurLogging() { const char* fileName = "d:/logTest.txt"; @@ -20,29 +19,28 @@ void testMinitaurLogging() int status = readMinitaurLogFile(fileName, structNames, structTypes, logRecords, verbose); - for (int i=0;i - #include #ifndef ENABLE_GTEST #include -#define ASSERT_EQ(a,b) assert((a)==(b)); +#define ASSERT_EQ(a, b) assert((a) == (b)); #else #define printf #endif void testSharedMemory(b3PhysicsClientHandle sm) { - int i, dofCount , posVarCount, ret ,numJoints ; - int sensorJointIndexLeft=-1; - int sensorJointIndexRight=-1; + int i, dofCount, posVarCount, ret, numJoints; + int sensorJointIndexLeft = -1; + int sensorJointIndexRight = -1; const char* urdfFileName = "r2d2.urdf"; const char* sdfFileName = "kuka_iiwa/model.sdf"; - double gravx=0, gravy=0, gravz=-9.8; - double timeStep = 1./60.; - double startPosX, startPosY,startPosZ; + double gravx = 0, gravy = 0, gravz = -9.8; + double timeStep = 1. / 60.; + double startPosX, startPosY, startPosZ; int imuLinkIndex = -1; int bodyIndex = -1; if (b3CanSubmitCommand(sm)) { - { - b3SharedMemoryCommandHandle command = b3InitPhysicsParamCommand(sm); - b3SharedMemoryStatusHandle statusHandle; - ret = b3PhysicsParamSetGravity(command, gravx,gravy, gravz); - ret = b3PhysicsParamSetTimeStep(command, timeStep); - statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command); - ASSERT_EQ(b3GetStatusType(statusHandle), CMD_CLIENT_COMMAND_COMPLETED); - } + { + b3SharedMemoryCommandHandle command = b3InitPhysicsParamCommand(sm); + b3SharedMemoryStatusHandle statusHandle; + ret = b3PhysicsParamSetGravity(command, gravx, gravy, gravz); + ret = b3PhysicsParamSetTimeStep(command, timeStep); + statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command); + ASSERT_EQ(b3GetStatusType(statusHandle), CMD_CLIENT_COMMAND_COMPLETED); + } - { - b3SharedMemoryStatusHandle statusHandle; - int statusType; - int bodyIndicesOut[10];//MAX_SDF_BODIES = 10 - int numJoints, numBodies; + { + b3SharedMemoryStatusHandle statusHandle; + int statusType; + int bodyIndicesOut[10]; //MAX_SDF_BODIES = 10 + int numJoints, numBodies; int bodyUniqueId; - b3SharedMemoryCommandHandle command = b3LoadSdfCommandInit(sm, sdfFileName); - statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command); + b3SharedMemoryCommandHandle command = b3LoadSdfCommandInit(sm, sdfFileName); + statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command); statusType = b3GetStatusType(statusHandle); ASSERT_EQ(statusType, CMD_SDF_LOADING_COMPLETED); - + numBodies = b3GetStatusBodyIndices(statusHandle, bodyIndicesOut, 10); - ASSERT_EQ(numBodies,1); - bodyUniqueId = bodyIndicesOut[0]; + ASSERT_EQ(numBodies, 1); + bodyUniqueId = bodyIndicesOut[0]; { { b3SharedMemoryStatusHandle statusHandle; @@ -90,9 +89,9 @@ void testSharedMemory(b3PhysicsClientHandle sm) } } } - - numJoints = b3GetNumJoints(sm,bodyUniqueId); - ASSERT_EQ(numJoints,7); + + numJoints = b3GetNumJoints(sm, bodyUniqueId); + ASSERT_EQ(numJoints, 7); #if 0 b3Printf("numJoints: %d\n", numJoints); @@ -105,122 +104,116 @@ void testSharedMemory(b3PhysicsClientHandle sm) } } #endif - { - b3SharedMemoryStatusHandle statusHandle; - b3SharedMemoryCommandHandle commandHandle; - double jointAngle = 0.f; - int jointIndex; - commandHandle = b3CreatePoseCommandInit(sm, bodyUniqueId); - for (jointIndex=0;jointIndex=0) - { - + } - numJoints = b3GetNumJoints(sm,bodyIndex); - for (i=0;i= 0) + { + numJoints = b3GetNumJoints(sm, bodyIndex); + for (i = 0; i < numJoints; i++) { struct b3JointInfo jointInfo; - b3GetJointInfo(sm,bodyIndex, i,&jointInfo); - - // printf("jointInfo[%d].m_jointName=%s\n",i,jointInfo.m_jointName); + b3GetJointInfo(sm, bodyIndex, i, &jointInfo); + + // printf("jointInfo[%d].m_jointName=%s\n",i,jointInfo.m_jointName); //pick the IMU link index based on torso name - if (strstr(jointInfo.m_linkName,"base_link")) + if (strstr(jointInfo.m_linkName, "base_link")) { imuLinkIndex = i; } - + //pick the joint index based on joint name - if (strstr(jointInfo.m_jointName,"base_to_left_leg")) + if (strstr(jointInfo.m_jointName, "base_to_left_leg")) { sensorJointIndexLeft = i; } - if (strstr(jointInfo.m_jointName,"base_to_right_leg")) + if (strstr(jointInfo.m_jointName, "base_to_right_leg")) { sensorJointIndexRight = i; } - } - - if ((sensorJointIndexLeft>=0) || (sensorJointIndexRight>=0)) + + if ((sensorJointIndexLeft >= 0) || (sensorJointIndexRight >= 0)) { b3SharedMemoryCommandHandle command = b3CreateSensorCommandInit(sm, bodyIndex); b3SharedMemoryStatusHandle statusHandle; - if (imuLinkIndex>=0) + if (imuLinkIndex >= 0) { - ret = b3CreateSensorEnableIMUForLink(command, imuLinkIndex, 1); + ret = b3CreateSensorEnableIMUForLink(command, imuLinkIndex, 1); } - - if (sensorJointIndexLeft>=0) + + if (sensorJointIndexLeft >= 0) { - ret = b3CreateSensorEnable6DofJointForceTorqueSensor(command, sensorJointIndexLeft, 1); + ret = b3CreateSensorEnable6DofJointForceTorqueSensor(command, sensorJointIndexLeft, 1); } - if(sensorJointIndexRight>=0) + if (sensorJointIndexRight >= 0) { ret = b3CreateSensorEnable6DofJointForceTorqueSensor(command, sensorJointIndexRight, 1); } statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command); - ASSERT_EQ(b3GetStatusType(statusHandle), CMD_CLIENT_COMMAND_COMPLETED); + ASSERT_EQ(b3GetStatusType(statusHandle), CMD_CLIENT_COMMAND_COMPLETED); } } - - { - b3SharedMemoryStatusHandle statusHandle; - b3SharedMemoryCommandHandle command = b3CreateBoxShapeCommandInit(sm); - ret = b3CreateBoxCommandSetStartPosition(command, 0,0,-1); - ret = b3CreateBoxCommandSetStartOrientation(command,0,0,0,1); - ret = b3CreateBoxCommandSetHalfExtents(command, 10,10,1); - statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command); - ASSERT_EQ(b3GetStatusType(statusHandle), CMD_RIGID_BODY_CREATION_COMPLETED); - } + { + b3SharedMemoryStatusHandle statusHandle; + b3SharedMemoryCommandHandle command = b3CreateBoxShapeCommandInit(sm); + ret = b3CreateBoxCommandSetStartPosition(command, 0, 0, -1); + ret = b3CreateBoxCommandSetStartOrientation(command, 0, 0, 0, 1); + ret = b3CreateBoxCommandSetHalfExtents(command, 10, 10, 1); + statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command); + ASSERT_EQ(b3GetStatusType(statusHandle), CMD_RIGID_BODY_CREATION_COMPLETED); + } - { - int statusType; - b3SharedMemoryCommandHandle command = b3RequestActualStateCommandInit(sm,bodyIndex); - b3SharedMemoryStatusHandle statusHandle; - statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command); - statusType = b3GetStatusType(statusHandle); - ASSERT_EQ(statusType, CMD_ACTUAL_STATE_UPDATE_COMPLETED); - - if (statusType == CMD_ACTUAL_STATE_UPDATE_COMPLETED) - { - b3GetStatusActualState(statusHandle, - 0, &posVarCount, &dofCount, - 0, 0, 0, 0); - ASSERT_EQ(posVarCount,15); - ASSERT_EQ(dofCount,14); - } - } - - { + { + int statusType; + b3SharedMemoryCommandHandle command = b3RequestActualStateCommandInit(sm, bodyIndex); + b3SharedMemoryStatusHandle statusHandle; + statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command); + statusType = b3GetStatusType(statusHandle); + ASSERT_EQ(statusType, CMD_ACTUAL_STATE_UPDATE_COMPLETED); + + if (statusType == CMD_ACTUAL_STATE_UPDATE_COMPLETED) + { + b3GetStatusActualState(statusHandle, + 0, &posVarCount, &dofCount, + 0, 0, 0, 0); + ASSERT_EQ(posVarCount, 15); + ASSERT_EQ(dofCount, 14); + } + } + + { #if 0 b3SharedMemoryStatusHandle statusHandle; b3SharedMemoryCommandHandle command = b3JointControlCommandInit( sm, CONTROL_MODE_VELOCITY); @@ -231,134 +224,126 @@ void testSharedMemory(b3PhysicsClientHandle sm) } statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command); #endif - } - ///perform some simulation steps for testing - for ( i=0;i<1000;i++) - { + } + ///perform some simulation steps for testing + for (i = 0; i < 1000; i++) + { b3SharedMemoryStatusHandle statusHandle; int statusType; - if (b3CanSubmitCommand(sm)) - { - statusHandle = b3SubmitClientCommandAndWaitStatus(sm, b3InitStepSimulationCommand(sm)); - statusType = b3GetStatusType(statusHandle); - ASSERT_EQ(statusType, CMD_STEP_FORWARD_SIMULATION_COMPLETED); - } else - { - break; - } - } - + if (b3CanSubmitCommand(sm)) + { + statusHandle = b3SubmitClientCommandAndWaitStatus(sm, b3InitStepSimulationCommand(sm)); + statusType = b3GetStatusType(statusHandle); + ASSERT_EQ(statusType, CMD_STEP_FORWARD_SIMULATION_COMPLETED); + } + else + { + break; + } + } + { b3SharedMemoryCommandHandle command; b3SharedMemoryStatusHandle statusHandle; - int width = 1024; + int width = 1024; int height = 1024; command = b3InitRequestCameraImage(sm); - + b3RequestCameraImageSetPixelResolution(command, width, height); - b3RequestCameraImageSelectRenderer(command,ER_BULLET_HARDWARE_OPENGL); + b3RequestCameraImageSelectRenderer(command, ER_BULLET_HARDWARE_OPENGL); statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command); } - - if (b3CanSubmitCommand(sm)) - { - b3SharedMemoryStatusHandle state = b3SubmitClientCommandAndWaitStatus(sm, b3RequestActualStateCommandInit(sm,bodyIndex)); - - if (sensorJointIndexLeft>=0) - { - struct b3JointSensorState sensorState; - b3GetJointState(sm,state,sensorJointIndexLeft,&sensorState); - + if (b3CanSubmitCommand(sm)) + { + b3SharedMemoryStatusHandle state = b3SubmitClientCommandAndWaitStatus(sm, b3RequestActualStateCommandInit(sm, bodyIndex)); + + if (sensorJointIndexLeft >= 0) + { + struct b3JointSensorState sensorState; + b3GetJointState(sm, state, sensorJointIndexLeft, &sensorState); + b3Printf("Sensor for joint [%d] = %f,%f,%f\n", sensorJointIndexLeft, - sensorState.m_jointForceTorque[0], - sensorState.m_jointForceTorque[1], - sensorState.m_jointForceTorque[2]); - + sensorState.m_jointForceTorque[0], + sensorState.m_jointForceTorque[1], + sensorState.m_jointForceTorque[2]); } - - if (sensorJointIndexRight>=0) + + if (sensorJointIndexRight >= 0) { - struct b3JointSensorState sensorState; - b3GetJointState(sm,state,sensorJointIndexRight,&sensorState); - + struct b3JointSensorState sensorState; + b3GetJointState(sm, state, sensorJointIndexRight, &sensorState); + b3Printf("Sensor for joint [%d] = %f,%f,%f\n", sensorJointIndexRight, sensorState.m_jointForceTorque[0], sensorState.m_jointForceTorque[1], sensorState.m_jointForceTorque[2]); - } - - - { - b3SharedMemoryStatusHandle statusHandle; - statusHandle = b3SubmitClientCommandAndWaitStatus(sm, b3InitResetSimulationCommand(sm)); - ASSERT_EQ(b3GetStatusType(statusHandle), CMD_RESET_SIMULATION_COMPLETED); - } - } - - } else - { - b3Warning("Cannot submit commands.\n"); - } + { + b3SharedMemoryStatusHandle statusHandle; + statusHandle = b3SubmitClientCommandAndWaitStatus(sm, b3InitResetSimulationCommand(sm)); + ASSERT_EQ(b3GetStatusType(statusHandle), CMD_RESET_SIMULATION_COMPLETED); + } + } + } + else + { + b3Warning("Cannot submit commands.\n"); + } b3DisconnectSharedMemory(sm); } - - #ifdef ENABLE_GTEST - -TEST(BulletPhysicsClientServerTest, DirectConnection) { - b3PhysicsClientHandle sm = b3ConnectPhysicsDirect(); - testSharedMemory(sm); +TEST(BulletPhysicsClientServerTest, DirectConnection) +{ + b3PhysicsClientHandle sm = b3ConnectPhysicsDirect(); + testSharedMemory(sm); } -TEST(BulletPhysicsClientServerTest, LoopBackSharedMemory) { - b3PhysicsClientHandle sm = b3ConnectPhysicsLoopback(SHARED_MEMORY_KEY); - testSharedMemory(sm); +TEST(BulletPhysicsClientServerTest, LoopBackSharedMemory) +{ + b3PhysicsClientHandle sm = b3ConnectPhysicsLoopback(SHARED_MEMORY_KEY); + testSharedMemory(sm); } - #else int main(int argc, char* argv[]) { #ifdef PHYSICS_LOOP_BACK - b3PhysicsClientHandle sm = b3ConnectPhysicsLoopback(SHARED_MEMORY_KEY); + b3PhysicsClientHandle sm = b3ConnectPhysicsLoopback(SHARED_MEMORY_KEY); #endif #ifdef PHYSICS_SERVER_DIRECT - b3PhysicsClientHandle sm = b3ConnectPhysicsDirect(); + b3PhysicsClientHandle sm = b3ConnectPhysicsDirect(); #endif #ifdef PHYSICS_IN_PROCESS_EXAMPLE_BROWSER #ifdef __APPLE__ - b3PhysicsClientHandle sm = b3CreateInProcessPhysicsServerAndConnectMainThread(argc,argv); + b3PhysicsClientHandle sm = b3CreateInProcessPhysicsServerAndConnectMainThread(argc, argv); #else - b3PhysicsClientHandle sm = b3CreateInProcessPhysicsServerAndConnect(argc,argv); -#endif //__APPLE__ + b3PhysicsClientHandle sm = b3CreateInProcessPhysicsServerAndConnect(argc, argv); +#endif //__APPLE__ #endif #ifdef PHYSICS_SHARED_MEMORY - b3PhysicsClientHandle sm = b3ConnectSharedMemory(SHARED_MEMORY_KEY); -#endif //PHYSICS_SHARED_MEMORY + b3PhysicsClientHandle sm = b3ConnectSharedMemory(SHARED_MEMORY_KEY); +#endif //PHYSICS_SHARED_MEMORY #ifdef PHYSICS_UDP - b3PhysicsClientHandle sm = b3ConnectPhysicsUDP("localhost",1234); -#endif //PHYSICS_UDP + b3PhysicsClientHandle sm = b3ConnectPhysicsUDP("localhost", 1234); +#endif //PHYSICS_UDP #ifdef PHYSICS_TCP - b3PhysicsClientHandle sm = b3ConnectPhysicsTCP("localhost",6667); -#endif //PHYSICS_UDP + b3PhysicsClientHandle sm = b3ConnectPhysicsTCP("localhost", 6667); +#endif //PHYSICS_UDP testSharedMemory(sm); } #endif - - diff --git a/test/TestBullet3OpenCL/main.cpp b/test/TestBullet3OpenCL/main.cpp index aee2434c2..570d70c2e 100644 --- a/test/TestBullet3OpenCL/main.cpp +++ b/test/TestBullet3OpenCL/main.cpp @@ -3,12 +3,11 @@ #include "Bullet3Common/b3Logging.h" - void myerrorprintf(const char* msg) { - printf("%s",msg); + printf("%s", msg); } - + static bool sVerboseWarning = true; void mywarningprintf(const char* msg) @@ -16,38 +15,38 @@ void mywarningprintf(const char* msg) if (sVerboseWarning) { //OutputDebugStringA(msg); - printf("%s",msg); + printf("%s", msg); } } -static bool sVerbosePrintf=true;//false; +static bool sVerbosePrintf = true; //false; void myprintf(const char* msg) { if (sVerbosePrintf) { //OutputDebugStringA(msg); - printf("%s",msg); + printf("%s", msg); } } -int gArgc=0; -char** gArgv=0; +int gArgc = 0; +char** gArgv = 0; - -int main(int argc, char **argv) { +int main(int argc, char** argv) +{ #if _MSC_VER - _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); - //void *testWhetherMemoryLeakDetectionWorks = malloc(1); + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); + //void *testWhetherMemoryLeakDetectionWorks = malloc(1); #endif - ::testing::InitGoogleTest(&argc, argv); + ::testing::InitGoogleTest(&argc, argv); - gArgc = argc; - gArgv = argv; + gArgc = argc; + gArgv = argv; - b3SetCustomPrintfFunc(myprintf); - b3SetCustomWarningMessageFunc(mywarningprintf); - b3SetCustomErrorMessageFunc(myerrorprintf); + b3SetCustomPrintfFunc(myprintf); + b3SetCustomWarningMessageFunc(mywarningprintf); + b3SetCustomErrorMessageFunc(myerrorprintf); - return RUN_ALL_TESTS(); + return RUN_ALL_TESTS(); } diff --git a/test/b3DynamicBvhBroadphase/main.cpp b/test/b3DynamicBvhBroadphase/main.cpp index b071dda1f..0979e0ed3 100644 --- a/test/b3DynamicBvhBroadphase/main.cpp +++ b/test/b3DynamicBvhBroadphase/main.cpp @@ -12,7 +12,6 @@ subject to the following restrictions: 3. This notice may not be removed or altered from any source distribution. */ - #include #include "Bullet3Common/b3Vector3.h" @@ -26,57 +25,57 @@ int g_nFailed = 0; bool g_testFailed = 0; #define TEST_INIT g_testFailed = 0; -#define TEST_ASSERT(x) if( !(x) ){g_testFailed = 1;} -#define TEST_REPORT(testName) printf("[%s] %s\n",(g_testFailed)?"X":"O", testName); if(g_testFailed) g_nFailed++; else g_nPassed++; - - +#define TEST_ASSERT(x) \ + if (!(x)) \ + { \ + g_testFailed = 1; \ + } +#define TEST_REPORT(testName) \ + printf("[%s] %s\n", (g_testFailed) ? "X" : "O", testName); \ + if (g_testFailed) \ + g_nFailed++; \ + else \ + g_nPassed++; inline void broadphaseTest() { TEST_INIT; b3DynamicBvhBroadphase* bp = new b3DynamicBvhBroadphase(2); - - int group=1; - int mask=1; - b3Vector3 aabbMin(0,0,0); - b3Vector3 aabbMax(1,1,1); + + int group = 1; + int mask = 1; + b3Vector3 aabbMin(0, 0, 0); + b3Vector3 aabbMax(1, 1, 1); int userId = 0; - bp->createProxy(aabbMin,aabbMax,userId++,0,group,mask); + bp->createProxy(aabbMin, aabbMax, userId++, 0, group, mask); - aabbMin.setValue(1,1,1); - aabbMax.setValue(2,2,2); + aabbMin.setValue(1, 1, 1); + aabbMax.setValue(2, 2, 2); - - bp->createProxy(aabbMin,aabbMax,userId++,0,group,mask); - + bp->createProxy(aabbMin, aabbMax, userId++, 0, group, mask); bp->calculateOverlappingPairs(); - + int numOverlap = bp->getOverlappingPairCache()->getNumOverlappingPairs(); - - - TEST_ASSERT(numOverlap==1); + + TEST_ASSERT(numOverlap == 1); delete bp; - TEST_REPORT( "broadphaseTest" ); + TEST_REPORT("broadphaseTest"); } int main(int argc, char** argv) { - - broadphaseTest(); - printf("%d tests passed\n",g_nPassed, g_nFailed); + printf("%d tests passed\n", g_nPassed, g_nFailed); if (g_nFailed) { - printf("%d tests failed\n",g_nFailed); + printf("%d tests failed\n", g_nFailed); } printf("End, press \n"); getchar(); - } - diff --git a/test/clew/clewTest.cpp b/test/clew/clewTest.cpp index 5a6187272..c496c412f 100644 --- a/test/clew/clewTest.cpp +++ b/test/clew/clewTest.cpp @@ -12,30 +12,29 @@ int main(int argc, char* argv[]) const char* cl = "OpenCL.dll"; #elif defined __APPLE__ const char* cl = "/System/Library/Frameworks/OpenCL.framework/Versions/Current/OpenCL"; -#else//presumable Linux? +#else //presumable Linux? //linux (tested on Ubuntu 12.10 with Catalyst 13.4 beta drivers, not that there is no symbolic link from libOpenCL.so const char* cl = "libOpenCL.so.1"; result = clewInit(cl); if (result != CLEW_SUCCESS) { cl = "libOpenCL.so"; - } else + } + else { clewExit(); } #endif result = clewInit(cl); - if (result!=CLEW_SUCCESS) - printf("clewInit failed with error code %d\n",result); + if (result != CLEW_SUCCESS) + printf("clewInit failed with error code %d\n", result); else { - printf("clewInit succesfull using %s\n",cl); + printf("clewInit succesfull using %s\n", cl); //some test and then clewExit(); } - return 0; } - diff --git a/test/clsocket/EchoServer.cpp b/test/clsocket/EchoServer.cpp index 4388fc2f2..35a0b007f 100644 --- a/test/clsocket/EchoServer.cpp +++ b/test/clsocket/EchoServer.cpp @@ -1,30 +1,30 @@ -#include "PassiveSocket.h" // Include header for active socket object definition +#include "PassiveSocket.h" // Include header for active socket object definition -#define MAX_PACKET 4096 +#define MAX_PACKET 4096 int main(int argc, char **argv) { - CPassiveSocket socket; - CActiveSocket *pClient = NULL; + CPassiveSocket socket; + CActiveSocket *pClient = NULL; - //-------------------------------------------------------------------------- - // Initialize our socket object - //-------------------------------------------------------------------------- - socket.Initialize(); + //-------------------------------------------------------------------------- + // Initialize our socket object + //-------------------------------------------------------------------------- + socket.Initialize(); - socket.Listen("localhost", 6667); + socket.Listen("localhost", 6667); - while (true) - { - if ((pClient = socket.Accept()) != NULL) - { + while (true) + { + if ((pClient = socket.Accept()) != NULL) + { int clientPort = socket.GetClientPort(); - printf("connected from %s:%d\n", socket.GetClientAddr(),clientPort); - //---------------------------------------------------------------------- - // Receive request from the client. - //---------------------------------------------------------------------- - while (1) + printf("connected from %s:%d\n", socket.GetClientAddr(), clientPort); + //---------------------------------------------------------------------- + // Receive request from the client. + //---------------------------------------------------------------------- + while (1) { //printf("try receive\n"); bool receivedData = false; @@ -32,15 +32,15 @@ int main(int argc, char **argv) recBytes = pClient->Receive(MAX_PACKET); if (recBytes) { - char* msg = (char*) pClient->GetData(); - msg[recBytes]=0; - printf("received message [%s]\n",msg); + char *msg = (char *)pClient->GetData(); + msg[recBytes] = 0; + printf("received message [%s]\n", msg); //------------------------------------------------------------------ // Send response to client and close connection to the client. //------------------------------------------------------------------ - pClient->Send( pClient->GetData(), pClient->GetBytesReceived() ); + pClient->Send(pClient->GetData(), pClient->GetBytesReceived()); receivedData = true; - if (strncmp(msg,"stop",4)==0) + if (strncmp(msg, "stop", 4) == 0) { printf("Stop request received\n"); break; @@ -50,18 +50,18 @@ int main(int argc, char **argv) { printf("Didn't receive data.\n"); break; - } + } } printf("Disconnecting client.\n"); pClient->Close(); - delete pClient; - } - } + delete pClient; + } + } - //----------------------------------------------------------------------------- - // Receive request from the client. - //----------------------------------------------------------------------------- - socket.Close(); + //----------------------------------------------------------------------------- + // Receive request from the client. + //----------------------------------------------------------------------------- + socket.Close(); - return 1; + return 1; } diff --git a/test/clsocket/QueryDayTime.cpp b/test/clsocket/QueryDayTime.cpp index 2211f37ce..f86b82200 100644 --- a/test/clsocket/QueryDayTime.cpp +++ b/test/clsocket/QueryDayTime.cpp @@ -1,58 +1,57 @@ #include -#include "ActiveSocket.h" // Include header for active socket object definition +#include "ActiveSocket.h" // Include header for active socket object definition int main(int argc, char **argv) { - CActiveSocket socket; // Instantiate active socket object (defaults to TCP). - char time[50]; + CActiveSocket socket; // Instantiate active socket object (defaults to TCP). + char time[50]; - memset(&time, 0, 50); + memset(&time, 0, 50); - //-------------------------------------------------------------------------- - // Initialize our socket object - //-------------------------------------------------------------------------- - socket.Initialize(); + //-------------------------------------------------------------------------- + // Initialize our socket object + //-------------------------------------------------------------------------- + socket.Initialize(); - //-------------------------------------------------------------------------- - // Create a connection to the time server so that data can be sent - // and received. - //-------------------------------------------------------------------------- -// if (socket.Open("time-C.timefreq.bldrdoc.gov", 13)) - if (socket.Open("192.168.86.196", 6667)) - { - for (int i=0;i<100;i++) - { - //---------------------------------------------------------------------- - // Send a requtest the server requesting the current time. - //---------------------------------------------------------------------- - char data[1024]; - sprintf(data,"%s %d","Hello",i); - int len = strlen(data); - data[len]=0; - printf("Sending [%s]\n",data); - len++; - if (socket.Send((const uint8 *)data, len)) - { - //---------------------------------------------------------------------- - // Receive response from the server. - //---------------------------------------------------------------------- - int rec = socket.Receive(len); - if (rec) - { - uint8* data = socket.GetData(); - memcpy(&time, data, len); - printf("Received: [%s]\n", time); - } - } - } + //-------------------------------------------------------------------------- + // Create a connection to the time server so that data can be sent + // and received. + //-------------------------------------------------------------------------- + // if (socket.Open("time-C.timefreq.bldrdoc.gov", 13)) + if (socket.Open("192.168.86.196", 6667)) + { + for (int i = 0; i < 100; i++) + { + //---------------------------------------------------------------------- + // Send a requtest the server requesting the current time. + //---------------------------------------------------------------------- + char data[1024]; + sprintf(data, "%s %d", "Hello", i); + int len = strlen(data); + data[len] = 0; + printf("Sending [%s]\n", data); + len++; + if (socket.Send((const uint8 *)data, len)) + { + //---------------------------------------------------------------------- + // Receive response from the server. + //---------------------------------------------------------------------- + int rec = socket.Receive(len); + if (rec) + { + uint8 *data = socket.GetData(); + memcpy(&time, data, len); + printf("Received: [%s]\n", time); + } + } + } - //---------------------------------------------------------------------- - // Close the connection. - //---------------------------------------------------------------------- - socket.Close(); - } + //---------------------------------------------------------------------- + // Close the connection. + //---------------------------------------------------------------------- + socket.Close(); + } - - return 1; + return 1; } diff --git a/test/clsocket/RecvAsync.cpp b/test/clsocket/RecvAsync.cpp index d4e415fd0..790ca807d 100644 --- a/test/clsocket/RecvAsync.cpp +++ b/test/clsocket/RecvAsync.cpp @@ -4,98 +4,97 @@ #ifdef WIN32 #include - // usually defined with #include - static void sleep( unsigned int seconds ) - { - Sleep( seconds * 1000 ); - } +// usually defined with #include +static void sleep(unsigned int seconds) +{ + Sleep(seconds * 1000); +} #endif -#define MAX_PACKET 4096 +#define MAX_PACKET 4096 #define TEST_PACKET "Test Packet" struct thread_data { - const char *pszServerAddr; - short int nPort; - int nNumBytesToReceive; - int nTotalPayloadSize; + const char *pszServerAddr; + short int nPort; + int nNumBytesToReceive; + int nTotalPayloadSize; }; - void *CreateTCPEchoServer(void *param) { - CPassiveSocket socket; - CActiveSocket *pClient = NULL; - struct thread_data *pData = (struct thread_data *)param; - int nBytesReceived = 0; + CPassiveSocket socket; + CActiveSocket *pClient = NULL; + struct thread_data *pData = (struct thread_data *)param; + int nBytesReceived = 0; - socket.Initialize(); - socket.Listen(pData->pszServerAddr, pData->nPort); + socket.Initialize(); + socket.Listen(pData->pszServerAddr, pData->nPort); - if ((pClient = socket.Accept()) != NULL) - { - while (nBytesReceived != pData->nTotalPayloadSize) - { - if (nBytesReceived += pClient->Receive(pData->nNumBytesToReceive)) - { - pClient->Send((const uint8 *)pClient->GetData(), pClient->GetBytesReceived()); - } - } + if ((pClient = socket.Accept()) != NULL) + { + while (nBytesReceived != pData->nTotalPayloadSize) + { + if (nBytesReceived += pClient->Receive(pData->nNumBytesToReceive)) + { + pClient->Send((const uint8 *)pClient->GetData(), pClient->GetBytesReceived()); + } + } - sleep(100); + sleep(100); - delete pClient; - } + delete pClient; + } - socket.Close(); + socket.Close(); - return NULL; + return NULL; } int main(int argc, char **argv) { - pthread_t threadId; - struct thread_data thData; - CActiveSocket client; - char result[1024]; + pthread_t threadId; + struct thread_data thData; + CActiveSocket client; + char result[1024]; - thData.pszServerAddr = "127.0.0.1"; - thData.nPort = 6789; - thData.nNumBytesToReceive = 1; - thData.nTotalPayloadSize = (int)strlen(TEST_PACKET); + thData.pszServerAddr = "127.0.0.1"; + thData.nPort = 6789; + thData.nNumBytesToReceive = 1; + thData.nTotalPayloadSize = (int)strlen(TEST_PACKET); - pthread_create(&threadId, 0, CreateTCPEchoServer, &thData); - sleep(1); // allow a second for the thread to create and listen + pthread_create(&threadId, 0, CreateTCPEchoServer, &thData); + sleep(1); // allow a second for the thread to create and listen - client.Initialize(); - client.SetNonblocking(); + client.Initialize(); + client.SetNonblocking(); - if (client.Open("127.0.0.1", 6789)) - { - if (client.Send((uint8 *)TEST_PACKET, strlen(TEST_PACKET))) - { - int numBytes = -1; - int bytesReceived = 0; + if (client.Open("127.0.0.1", 6789)) + { + if (client.Send((uint8 *)TEST_PACKET, strlen(TEST_PACKET))) + { + int numBytes = -1; + int bytesReceived = 0; - client.Select(); + client.Select(); - while (bytesReceived != strlen(TEST_PACKET)) - { - numBytes = client.Receive(MAX_PACKET); + while (bytesReceived != strlen(TEST_PACKET)) + { + numBytes = client.Receive(MAX_PACKET); - if (numBytes > 0) - { - bytesReceived += numBytes; - memset(result, 0, 1024); - memcpy(result, client.GetData(), numBytes); - printf("received %d bytes: '%s'\n", numBytes, result); - } - else - { - printf("Received %d bytes\n", numBytes); - } - } - } - } + if (numBytes > 0) + { + bytesReceived += numBytes; + memset(result, 0, 1024); + memcpy(result, client.GetData(), numBytes); + printf("received %d bytes: '%s'\n", numBytes, result); + } + else + { + printf("Received %d bytes\n", numBytes); + } + } + } + } } diff --git a/test/collision/SphereSphereCollision.h b/test/collision/SphereSphereCollision.h index 2588fc5ba..bd93e778d 100644 --- a/test/collision/SphereSphereCollision.h +++ b/test/collision/SphereSphereCollision.h @@ -16,15 +16,15 @@ subject to the following restrictions: #ifndef SPHERE_SPHERE_COLLISION_H #define SPHERE_SPHERE_COLLISION_H -#include "LinearMath/btTransform.h" // Note that btVector3 might be double precision... +#include "LinearMath/btTransform.h" // Note that btVector3 might be double precision... #include "btDistanceInfo.h" struct btSphereSphereCollisionDescription { - btTransform m_sphereTransformA; - btTransform m_sphereTransformB; - btScalar m_radiusA; - btScalar m_radiusB; + btTransform m_sphereTransformA; + btTransform m_sphereTransformB; + btScalar m_radiusA; + btScalar m_radiusB; }; ///compute the distance between two spheres, where the distance is zero when the spheres are touching @@ -32,26 +32,23 @@ struct btSphereSphereCollisionDescription ///point A and pointB are witness points, and normalOnB points from sphere B to sphere A inline int btComputeSphereSphereCollision(const btSphereSphereCollisionDescription& input, btDistanceInfo* distInfo) { + btVector3 diff = input.m_sphereTransformA.getOrigin() - input.m_sphereTransformB.getOrigin(); + btScalar len = diff.length(); + btScalar radiusA = input.m_radiusA; + btScalar radiusB = input.m_radiusB; - btVector3 diff = input.m_sphereTransformA.getOrigin()- input.m_sphereTransformB.getOrigin(); - btScalar len = diff.length(); - btScalar radiusA = input.m_radiusA; - btScalar radiusB = input.m_radiusB; - - ///distance (negative means penetration) - btScalar dist = len - (radiusA+radiusB); - btVector3 normalOnSurfaceB(1,0,0); - if (len > SIMD_EPSILON) - { - normalOnSurfaceB = diff / len; - } - distInfo->m_distance = dist; - distInfo->m_normalBtoA = normalOnSurfaceB; - distInfo->m_pointOnA = input.m_sphereTransformA.getOrigin()-input.m_radiusA*normalOnSurfaceB; - distInfo->m_pointOnB = input.m_sphereTransformB.getOrigin()+input.m_radiusB*normalOnSurfaceB; - return 0;//sphere-sphere cannot fail + ///distance (negative means penetration) + btScalar dist = len - (radiusA + radiusB); + btVector3 normalOnSurfaceB(1, 0, 0); + if (len > SIMD_EPSILON) + { + normalOnSurfaceB = diff / len; + } + distInfo->m_distance = dist; + distInfo->m_normalBtoA = normalOnSurfaceB; + distInfo->m_pointOnA = input.m_sphereTransformA.getOrigin() - input.m_radiusA * normalOnSurfaceB; + distInfo->m_pointOnB = input.m_sphereTransformB.getOrigin() + input.m_radiusB * normalOnSurfaceB; + return 0; //sphere-sphere cannot fail } -#endif //SPHERE_SPHERE_COLLISION_H - - +#endif //SPHERE_SPHERE_COLLISION_H diff --git a/test/collision/btDistanceInfo.h b/test/collision/btDistanceInfo.h index 1aa39ba69..b3c9c3305 100644 --- a/test/collision/btDistanceInfo.h +++ b/test/collision/btDistanceInfo.h @@ -20,11 +20,10 @@ subject to the following restrictions: struct btDistanceInfo { - btVector3 m_pointOnA; - btVector3 m_pointOnB; - btVector3 m_normalBtoA; - btScalar m_distance; + btVector3 m_pointOnA; + btVector3 m_pointOnB; + btVector3 m_normalBtoA; + btScalar m_distance; }; -#endif //BT_DISTANCE_INFO_H - +#endif //BT_DISTANCE_INFO_H diff --git a/test/collision/main.cpp b/test/collision/main.cpp index 86fb36c59..8f85873ff 100644 --- a/test/collision/main.cpp +++ b/test/collision/main.cpp @@ -20,205 +20,195 @@ subject to the following restrictions: ///Todo: the test needs proper coverage and using a convex hull point cloud ///Also the GJK, EPA and MPR should be improved, both quality and performance - #include - #include "SphereSphereCollision.h" #include "BulletCollision/CollisionShapes/btSphereShape.h" #include "BulletCollision/CollisionShapes/btMultiSphereShape.h" - - #include "BulletCollision/NarrowPhaseCollision/btComputeGjkEpaPenetration.h" #include "BulletCollision/NarrowPhaseCollision/btGjkEpa3.h" #include "BulletCollision/NarrowPhaseCollision/btMprPenetration.h" - - btVector3 MyBulletShapeSupportFunc(const void* shapeAptr, const btVector3& dir, bool includeMargin) { - btConvexShape* shape = (btConvexShape*) shapeAptr; - if (includeMargin) - { - return shape->localGetSupportingVertex(dir); - } - - return shape->localGetSupportingVertexWithoutMargin(dir); + btConvexShape* shape = (btConvexShape*)shapeAptr; + if (includeMargin) + { + return shape->localGetSupportingVertex(dir); + } + + return shape->localGetSupportingVertexWithoutMargin(dir); } btVector3 MyBulletShapeCenterFunc(const void* shapeAptr) { - return btVector3(0,0,0); + return btVector3(0, 0, 0); } enum SphereSphereTestMethod { - SSTM_ANALYTIC, - SSTM_GJKEPA, - SSTM_GJKEPA_RADIUS_NOT_FULL_MARGIN, - SSTM_GJKMPR + SSTM_ANALYTIC, + SSTM_GJKEPA, + SSTM_GJKEPA_RADIUS_NOT_FULL_MARGIN, + SSTM_GJKMPR }; - - struct ConvexWrap { - btConvexShape* m_convex; - btTransform m_worldTrans; - inline btScalar getMargin() const - { - return m_convex->getMargin(); - } - inline btVector3 getObjectCenterInWorld() const - { - return m_worldTrans.getOrigin(); - } - inline const btTransform& getWorldTransform() const - { - return m_worldTrans; - } - inline btVector3 getLocalSupportWithMargin(const btVector3& dir) const - { - return m_convex->localGetSupportingVertex(dir); - } - inline btVector3 getLocalSupportWithoutMargin(const btVector3& dir) const - { - return m_convex->localGetSupportingVertexWithoutMargin(dir); - } + btConvexShape* m_convex; + btTransform m_worldTrans; + inline btScalar getMargin() const + { + return m_convex->getMargin(); + } + inline btVector3 getObjectCenterInWorld() const + { + return m_worldTrans.getOrigin(); + } + inline const btTransform& getWorldTransform() const + { + return m_worldTrans; + } + inline btVector3 getLocalSupportWithMargin(const btVector3& dir) const + { + return m_convex->localGetSupportingVertex(dir); + } + inline btVector3 getLocalSupportWithoutMargin(const btVector3& dir) const + { + return m_convex->localGetSupportingVertexWithoutMargin(dir); + } }; -inline int btComputeGjkEpaSphereSphereCollision(const btSphereSphereCollisionDescription& input, btDistanceInfo* distInfo,SphereSphereTestMethod method) +inline int btComputeGjkEpaSphereSphereCollision(const btSphereSphereCollisionDescription& input, btDistanceInfo* distInfo, SphereSphereTestMethod method) { - ///for spheres it is best to use a 'point' and set the margin to the radius (which is what btSphereShape does) - btSphereShape singleSphereA(input.m_radiusA); - btSphereShape singleSphereB(input.m_radiusB); - btVector3 org(0,0,0); - btScalar radA =input.m_radiusA; - btScalar radB =input.m_radiusB; + ///for spheres it is best to use a 'point' and set the margin to the radius (which is what btSphereShape does) + btSphereShape singleSphereA(input.m_radiusA); + btSphereShape singleSphereB(input.m_radiusB); + btVector3 org(0, 0, 0); + btScalar radA = input.m_radiusA; + btScalar radB = input.m_radiusB; - ConvexWrap a,b; - a.m_worldTrans = input.m_sphereTransformA; - b.m_worldTrans = input.m_sphereTransformB;; - - btMultiSphereShape multiSphereA(&org,&radA,1); - btMultiSphereShape multiSphereB(&org,&radB,1); - - btGjkCollisionDescription colDesc; - switch (method) - { - case SSTM_GJKEPA_RADIUS_NOT_FULL_MARGIN: - { - - a.m_convex = &multiSphereA; - b.m_convex = &multiSphereB; - break; - } - default: - { - a.m_convex = &singleSphereA; - b.m_convex = &singleSphereB; - } - }; - - btVoronoiSimplexSolver simplexSolver; - simplexSolver.reset(); - - int res=-1; - ///todo(erwincoumans): improve convex-convex quality and performance - ///also compare with https://code.google.com/p/bullet/source/browse/branches/PhysicsEffects/src/base_level/collision/pfx_gjk_solver.cpp - switch (method) - { - case SSTM_GJKEPA_RADIUS_NOT_FULL_MARGIN: - case SSTM_GJKEPA: - { - res = btComputeGjkEpaPenetration(a,b,colDesc,simplexSolver, distInfo); - break; - } - case SSTM_GJKMPR: - { - res = btComputeGjkDistance(a,b,colDesc,distInfo); - if (res==0) - { - // printf("use GJK results in distance %f\n",distInfo->m_distance); - return res; - } else - { - btMprCollisionDescription mprDesc; - res = btComputeMprPenetration(a,b,mprDesc, distInfo); + ConvexWrap a, b; + a.m_worldTrans = input.m_sphereTransformA; + b.m_worldTrans = input.m_sphereTransformB; + ; -// if (res==0) -// { -// printf("use MPR results in distance %f\n",distInfo->m_distance); -// } - } - break; - } - default: - { - - btAssert(0); - } - } - return res; + btMultiSphereShape multiSphereA(&org, &radA, 1); + btMultiSphereShape multiSphereB(&org, &radB, 1); + + btGjkCollisionDescription colDesc; + switch (method) + { + case SSTM_GJKEPA_RADIUS_NOT_FULL_MARGIN: + { + a.m_convex = &multiSphereA; + b.m_convex = &multiSphereB; + break; + } + default: + { + a.m_convex = &singleSphereA; + b.m_convex = &singleSphereB; + } + }; + + btVoronoiSimplexSolver simplexSolver; + simplexSolver.reset(); + + int res = -1; + ///todo(erwincoumans): improve convex-convex quality and performance + ///also compare with https://code.google.com/p/bullet/source/browse/branches/PhysicsEffects/src/base_level/collision/pfx_gjk_solver.cpp + switch (method) + { + case SSTM_GJKEPA_RADIUS_NOT_FULL_MARGIN: + case SSTM_GJKEPA: + { + res = btComputeGjkEpaPenetration(a, b, colDesc, simplexSolver, distInfo); + break; + } + case SSTM_GJKMPR: + { + res = btComputeGjkDistance(a, b, colDesc, distInfo); + if (res == 0) + { + // printf("use GJK results in distance %f\n",distInfo->m_distance); + return res; + } + else + { + btMprCollisionDescription mprDesc; + res = btComputeMprPenetration(a, b, mprDesc, distInfo); + + // if (res==0) + // { + // printf("use MPR results in distance %f\n",distInfo->m_distance); + // } + } + break; + } + default: + { + btAssert(0); + } + } + return res; } - - void testSphereSphereDistance(SphereSphereTestMethod method, btScalar abs_error) { - { - btSphereSphereCollisionDescription ssd; - ssd.m_sphereTransformA.setIdentity(); - ssd.m_sphereTransformB.setIdentity(); - ssd.m_radiusA = 0.f; - ssd.m_radiusB = 0.f; - btDistanceInfo distInfo; - int result = btComputeSphereSphereCollision(ssd,&distInfo); - ASSERT_EQ(0,result); - ASSERT_EQ(btScalar(0), distInfo.m_distance); - } - - for (int rb=1;rb<5;rb++) - for (int z=-5;z<5;z++) - { - for (int j=1;j<5;j++) - { - for (int i=-5;i<5;i++) - { - if (i!=z)//skip co-centric spheres for now (todo(erwincoumans) fix this) - { - btSphereSphereCollisionDescription ssd; - ssd.m_sphereTransformA.setIdentity(); - ssd.m_sphereTransformA.setOrigin(btVector3(0,btScalar(i),0)); - ssd.m_sphereTransformB.setIdentity(); - ssd.m_sphereTransformB.setOrigin(btVector3(0,btScalar(z),0)); - ssd.m_radiusA = btScalar(j); - ssd.m_radiusB = btScalar(rb)*btScalar(0.1); - btDistanceInfo distInfo; - int result=-1; - switch (method) - { - case SSTM_ANALYTIC: - { - result = btComputeSphereSphereCollision(ssd,&distInfo); - break; - } - case SSTM_GJKMPR: - case SSTM_GJKEPA: - case SSTM_GJKEPA_RADIUS_NOT_FULL_MARGIN: - { - result = btComputeGjkEpaSphereSphereCollision(ssd,&distInfo, method); - break; - } - default: - { - ASSERT_EQ(0,1); - btAssert(0); - break; - } - } - // int result = btComputeSphereSphereCollision(ssd,&distInfo); + { + btSphereSphereCollisionDescription ssd; + ssd.m_sphereTransformA.setIdentity(); + ssd.m_sphereTransformB.setIdentity(); + ssd.m_radiusA = 0.f; + ssd.m_radiusB = 0.f; + btDistanceInfo distInfo; + int result = btComputeSphereSphereCollision(ssd, &distInfo); + ASSERT_EQ(0, result); + ASSERT_EQ(btScalar(0), distInfo.m_distance); + } + + for (int rb = 1; rb < 5; rb++) + for (int z = -5; z < 5; z++) + { + for (int j = 1; j < 5; j++) + { + for (int i = -5; i < 5; i++) + { + if (i != z) //skip co-centric spheres for now (todo(erwincoumans) fix this) + { + btSphereSphereCollisionDescription ssd; + ssd.m_sphereTransformA.setIdentity(); + ssd.m_sphereTransformA.setOrigin(btVector3(0, btScalar(i), 0)); + ssd.m_sphereTransformB.setIdentity(); + ssd.m_sphereTransformB.setOrigin(btVector3(0, btScalar(z), 0)); + ssd.m_radiusA = btScalar(j); + ssd.m_radiusB = btScalar(rb) * btScalar(0.1); + btDistanceInfo distInfo; + int result = -1; + switch (method) + { + case SSTM_ANALYTIC: + { + result = btComputeSphereSphereCollision(ssd, &distInfo); + break; + } + case SSTM_GJKMPR: + case SSTM_GJKEPA: + case SSTM_GJKEPA_RADIUS_NOT_FULL_MARGIN: + { + result = btComputeGjkEpaSphereSphereCollision(ssd, &distInfo, method); + break; + } + default: + { + ASSERT_EQ(0, 1); + btAssert(0); + break; + } + } + // int result = btComputeSphereSphereCollision(ssd,&distInfo); #if 0 printf("sphereA(pos=[%f,%f,%f],r=%f)-sphereB(pos=[%f,%f,%f],r=%f) Dist=%f,normalOnB[%f,%f,%f],pA=[%f,%f,%f],pB[%f,%f,%f]\n", ssd.m_sphereTransformA.getOrigin()[0],ssd.m_sphereTransformA.getOrigin()[1],ssd.m_sphereTransformA.getOrigin()[2],ssd.m_radiusA, @@ -227,45 +217,44 @@ void testSphereSphereDistance(SphereSphereTestMethod method, btScalar abs_error) distInfo.m_pointOnA[0],distInfo.m_pointOnA[1],distInfo.m_pointOnA[2], distInfo.m_pointOnB[0],distInfo.m_pointOnB[1],distInfo.m_pointOnB[2]); #endif - ASSERT_EQ(0,result); - ASSERT_NEAR(btFabs(btScalar(i-z))-btScalar(j)-ssd.m_radiusB, distInfo.m_distance, abs_error); - btVector3 computedA = distInfo.m_pointOnB+distInfo.m_distance*distInfo.m_normalBtoA; - ASSERT_NEAR(computedA.x(),distInfo.m_pointOnA.x(),abs_error); - ASSERT_NEAR(computedA.y(),distInfo.m_pointOnA.y(),abs_error); - ASSERT_NEAR(computedA.z(),distInfo.m_pointOnA.z(),abs_error); - } - } - } - } - + ASSERT_EQ(0, result); + ASSERT_NEAR(btFabs(btScalar(i - z)) - btScalar(j) - ssd.m_radiusB, distInfo.m_distance, abs_error); + btVector3 computedA = distInfo.m_pointOnB + distInfo.m_distance * distInfo.m_normalBtoA; + ASSERT_NEAR(computedA.x(), distInfo.m_pointOnA.x(), abs_error); + ASSERT_NEAR(computedA.y(), distInfo.m_pointOnA.y(), abs_error); + ASSERT_NEAR(computedA.z(), distInfo.m_pointOnA.z(), abs_error); + } + } + } + } } -TEST(BulletCollisionTest, GjkMPRSphereSphereDistance) { - testSphereSphereDistance(SSTM_GJKMPR, 0.0001); +TEST(BulletCollisionTest, GjkMPRSphereSphereDistance) +{ + testSphereSphereDistance(SSTM_GJKMPR, 0.0001); } - -TEST(BulletCollisionTest, GjkEpaSphereSphereDistance) { - testSphereSphereDistance(SSTM_GJKEPA, 0.00001); +TEST(BulletCollisionTest, GjkEpaSphereSphereDistance) +{ + testSphereSphereDistance(SSTM_GJKEPA, 0.00001); } -TEST(BulletCollisionTest, GjkEpaSphereSphereRadiusNotFullMarginDistance) { - testSphereSphereDistance(SSTM_GJKEPA_RADIUS_NOT_FULL_MARGIN, 0.1); +TEST(BulletCollisionTest, GjkEpaSphereSphereRadiusNotFullMarginDistance) +{ + testSphereSphereDistance(SSTM_GJKEPA_RADIUS_NOT_FULL_MARGIN, 0.1); } -TEST(BulletCollisionTest, AnalyticSphereSphereDistance) { - testSphereSphereDistance(SSTM_ANALYTIC, 0.00001); +TEST(BulletCollisionTest, AnalyticSphereSphereDistance) +{ + testSphereSphereDistance(SSTM_ANALYTIC, 0.00001); } - - - - -int main(int argc, char **argv) { +int main(int argc, char** argv) +{ #if _MSC_VER - _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); - //void *testWhetherMemoryLeakDetectionWorks = malloc(1); + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); + //void *testWhetherMemoryLeakDetectionWorks = malloc(1); #endif - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); } diff --git a/test/enet/chat/client/main.cpp b/test/enet/chat/client/main.cpp index 8aff0f699..de2b13f72 100644 --- a/test/enet/chat/client/main.cpp +++ b/test/enet/chat/client/main.cpp @@ -4,8 +4,8 @@ #include #include - -int main(int argc, char* argv[]) { +int main(int argc, char *argv[]) +{ ENetHost *client; ENetAddress address; ENetPeer *peer; @@ -15,42 +15,41 @@ int main(int argc, char* argv[]) { puts("Starting client"); - if (enet_initialize() != 0) { + if (enet_initialize() != 0) + { fprintf(stderr, "Error initialising enet"); exit(EXIT_FAILURE); - } - client = enet_host_create(NULL, /* create a client host */ - 1, /* number of clients */ - 2, /* number of channels */ - 57600 / 8, /* incoming bandwith */ - 14400 / 8); /* outgoing bandwith */ + client = enet_host_create(NULL, /* create a client host */ + 1, /* number of clients */ + 2, /* number of channels */ + 57600 / 8, /* incoming bandwith */ + 14400 / 8); /* outgoing bandwith */ - if (client == NULL) { + if (client == NULL) + { fprintf(stderr, "Could not create client host"); exit(EXIT_FAILURE); - } - enet_address_set_host(&address, "localhost"); address.port = 1234; peer = enet_host_connect(client, - &address, /* address to connect to */ - 2, /* number of channels */ - 0); /* user data supplied to + &address, /* address to connect to */ + 2, /* number of channels */ + 0); /* user data supplied to the receiving host */ - if (peer == NULL) { - fprintf(stderr, "No available peers for initiating an ENet " - "connection.\n"); + if (peer == NULL) + { + fprintf(stderr, + "No available peers for initiating an ENet " + "connection.\n"); exit(EXIT_FAILURE); - } - /* Try to connect to server within 5 seconds */ if (enet_host_service(client, &event, 5000) > 0 && event.type == ENET_EVENT_TYPE_CONNECT) @@ -81,32 +80,33 @@ int main(int argc, char* argv[]) { { switch (event.type) { - case ENET_EVENT_TYPE_CONNECT: - printf("A new client connected from %x:%u.\n", - event.peer->address.host, - event.peer->address.port); + case ENET_EVENT_TYPE_CONNECT: + printf("A new client connected from %x:%u.\n", + event.peer->address.host, + event.peer->address.port); - event.peer->data = (void*)"New User"; - break; + event.peer->data = (void *)"New User"; + break; - case ENET_EVENT_TYPE_RECEIVE: - printf("A packet of length %u containing '%s' was " - "received from %s on channel %u.\n", - event.packet->dataLength, - event.packet->data, - event.peer->data, - event.channelID); + case ENET_EVENT_TYPE_RECEIVE: + printf( + "A packet of length %u containing '%s' was " + "received from %s on channel %u.\n", + event.packet->dataLength, + event.packet->data, + event.peer->data, + event.channelID); - /* Clean up the packet now that we're done using it. + /* Clean up the packet now that we're done using it. > */ - enet_packet_destroy(event.packet); + enet_packet_destroy(event.packet); - break; + break; - case ENET_EVENT_TYPE_DISCONNECT: - printf("%s disconnected.\n", event.peer->data); + case ENET_EVENT_TYPE_DISCONNECT: + printf("%s disconnected.\n", event.peer->data); - break; + break; } } else if (serviceResult > 0) @@ -114,29 +114,25 @@ int main(int argc, char* argv[]) { puts("Error with servicing the client"); exit(EXIT_FAILURE); } - } - printf("Say> "); #ifdef _WIN32 gets_s(message, 1024); #else - fgets(message,1024,stdin); + fgets(message, 1024, stdin); #endif if (strcmp(message, "exit") == 0 || - strcmp(message, "quit") == 0) { + strcmp(message, "quit") == 0) + { break; - } - if (strlen(message) > 0) { - ENetPacket *packet = enet_packet_create(message, strlen - (message) + 1, ENET_PACKET_FLAG_RELIABLE); + if (strlen(message) > 0) + { + ENetPacket *packet = enet_packet_create(message, strlen(message) + 1, ENET_PACKET_FLAG_RELIABLE); enet_peer_send(peer, 0, packet); - } - } enet_peer_disconnect(peer, 0); @@ -145,24 +141,20 @@ int main(int argc, char* argv[]) { /* and drop any packets received packets */ while (enet_host_service(client, &event, 3000) > 0) { - switch (event.type) { - case ENET_EVENT_TYPE_RECEIVE: - enet_packet_destroy(event.packet); - break; + case ENET_EVENT_TYPE_RECEIVE: + enet_packet_destroy(event.packet); + break; - case ENET_EVENT_TYPE_DISCONNECT: - puts("Disconnection succeeded."); - break; + case ENET_EVENT_TYPE_DISCONNECT: + puts("Disconnection succeeded."); + break; } } - enet_host_destroy(client); enet_deinitialize(); return 0; - - } diff --git a/test/enet/chat/server/main.cpp b/test/enet/chat/server/main.cpp index d1f85bd99..1c3a0dff2 100644 --- a/test/enet/chat/server/main.cpp +++ b/test/enet/chat/server/main.cpp @@ -17,7 +17,6 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - /* Bind the server to the default localhost. */ /* A specific host address can be specified by */ /* enet_address_set_host (& address, "x.x.x.x"); */ @@ -26,10 +25,10 @@ int main(int argc, char *argv[]) address.port = 1234; server = enet_host_create(&address, - 32, /* number of clients */ - 2, /* number of channels */ - 0, /* Any incoming bandwith */ - 0); /* Any outgoing bandwith */ + 32, /* number of clients */ + 2, /* number of channels */ + 0, /* Any incoming bandwith */ + 0); /* Any outgoing bandwith */ if (server == NULL) { @@ -37,7 +36,6 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } - while (true) { serviceResult = 1; @@ -50,42 +48,42 @@ int main(int argc, char *argv[]) if (serviceResult > 0) { - switch (event.type) { - case ENET_EVENT_TYPE_CONNECT: - printf("A new client connected from %x:%u.\n", - event.peer->address.host, - event.peer->address.port); + case ENET_EVENT_TYPE_CONNECT: + printf("A new client connected from %x:%u.\n", + event.peer->address.host, + event.peer->address.port); - /* Store any relevant client information here. */ - event.peer->data = (void*)"Client information"; + /* Store any relevant client information here. */ + event.peer->data = (void *)"Client information"; - break; + break; - case ENET_EVENT_TYPE_RECEIVE: - printf("A packet of length %lu containing '%s' was " - "received from %s on channel %u.\n", - event.packet->dataLength, - event.packet->data, - event.peer->data, - event.channelID); + case ENET_EVENT_TYPE_RECEIVE: + printf( + "A packet of length %lu containing '%s' was " + "received from %s on channel %u.\n", + event.packet->dataLength, + event.packet->data, + event.peer->data, + event.channelID); - /* Tell all clients about this message */ - enet_host_broadcast(server, 0, event.packet); + /* Tell all clients about this message */ + enet_host_broadcast(server, 0, event.packet); - break; + break; - case ENET_EVENT_TYPE_DISCONNECT: - printf("%s disconnected.\n", event.peer->data); + case ENET_EVENT_TYPE_DISCONNECT: + printf("%s disconnected.\n", event.peer->data); - /* Reset the peer's client information. */ + /* Reset the peer's client information. */ - event.peer->data = NULL; + event.peer->data = NULL; - break; - case ENET_EVENT_TYPE_NONE: - break; + break; + case ENET_EVENT_TYPE_NONE: + break; } } else if (serviceResult > 0) @@ -94,12 +92,10 @@ int main(int argc, char *argv[]) exit(EXIT_FAILURE); } } - } enet_host_destroy(server); enet_deinitialize(); return 0; - } diff --git a/test/enet/nat_punchthrough/client/main.cpp b/test/enet/nat_punchthrough/client/main.cpp index ceb6fe1ff..f10182c5f 100644 --- a/test/enet/nat_punchthrough/client/main.cpp +++ b/test/enet/nat_punchthrough/client/main.cpp @@ -1,38 +1,33 @@ - - - - #include #include #include - int main(int argc, char* argv[]) { printf("starting client (and server)\n"); - if (enet_initialize () != 0) - { - fprintf (stderr, "An error occurred while initializing ENet.\n"); - return EXIT_FAILURE; - } - atexit (enet_deinitialize); + if (enet_initialize() != 0) + { + fprintf(stderr, "An error occurred while initializing ENet.\n"); + return EXIT_FAILURE; + } + atexit(enet_deinitialize); ENetAddress selfaddress; selfaddress.host = ENET_HOST_ANY; /* Bind the server to port 1111. */ selfaddress.port = 1111; - ENetHost * client=0; + ENetHost* client = 0; while (!client) { - client = enet_host_create (&selfaddress/* create a client host */, - 32 /* only 32 connections */, - 2 /* allow up 2 channels to be used, 0 and 1 */, - 0/*57600 / 8 56K modem with 56 Kbps downstream bandwidth */, - 0 /* 14400 / 8 56K modem with 14 Kbps upstream bandwidth */); + client = enet_host_create(&selfaddress /* create a client host */, + 32 /* only 32 connections */, + 2 /* allow up 2 channels to be used, 0 and 1 */, + 0 /*57600 / 8 56K modem with 56 Kbps downstream bandwidth */, + 0 /* 14400 / 8 56K modem with 14 Kbps upstream bandwidth */); if (client == NULL) { selfaddress.port++; @@ -40,140 +35,121 @@ int main(int argc, char* argv[]) } if (client == NULL) { - fprintf (stderr, - "An error occurred while trying to create an ENet client host.\n"); - exit (EXIT_FAILURE); + fprintf(stderr, + "An error occurred while trying to create an ENet client host.\n"); + exit(EXIT_FAILURE); } - - ENetAddress dedicatedserveraddress; ENetEvent event; - ENetPeer* dedicatedpeer=0; - ENetPeer* natpeer=0; + ENetPeer* dedicatedpeer = 0; + ENetPeer* natpeer = 0; /* Connect to some.server.net:1234. */ - enet_address_set_host (& dedicatedserveraddress, "localhost"); + enet_address_set_host(&dedicatedserveraddress, "localhost"); dedicatedserveraddress.port = 1234; /* Initiate the connection, allocating the two channels 0 and 1. */ - dedicatedpeer = enet_host_connect (client, & dedicatedserveraddress, 2, 0); + dedicatedpeer = enet_host_connect(client, &dedicatedserveraddress, 2, 0); if (dedicatedpeer == NULL) { - fprintf (stderr, "No available peers for initiating an ENet connection.\n"); - exit (EXIT_FAILURE); + fprintf(stderr, "No available peers for initiating an ENet connection.\n"); + exit(EXIT_FAILURE); } /* Wait up to 5 seconds for the connection attempt to succeed. */ - if (enet_host_service (client, & event, 5000) > 0 && + if (enet_host_service(client, &event, 5000) > 0 && event.type == ENET_EVENT_TYPE_CONNECT) { char servername[1024]; - enet_address_get_host(&dedicatedserveraddress,servername, 1024); + enet_address_get_host(&dedicatedserveraddress, servername, 1024); char serverinfo[1024]; - sprintf(serverinfo,"Connection to %s:%d succeeded", servername,dedicatedserveraddress.port); - puts (serverinfo); + sprintf(serverinfo, "Connection to %s:%d succeeded", servername, dedicatedserveraddress.port); + puts(serverinfo); /////.... /* Wait up to 1000 milliseconds for an event. */ - while (enet_host_service (client, & event, 1000000000) > 0) + while (enet_host_service(client, &event, 1000000000) > 0) { if (natpeer) { - /* Create a reliable packet of size 7 containing "packet\0" */ - ENetPacket * packet = enet_packet_create ("packet", - strlen ("packet") + 1, - ENET_PACKET_FLAG_RELIABLE); - /* Extend the packet so and append the string "foo", so it now */ - /* contains "packetfoo\0" */ - enet_packet_resize (packet, strlen ("packetfoo") + 1); - strcpy ((char*)& packet -> data [strlen ("packet")], "foo"); - /* Send the packet to the peer over channel id 0. */ - /* One could also broadcast the packet by */ - /* enet_host_broadcast (host, 0, packet); */ - enet_peer_send (natpeer, 0, packet); + /* Create a reliable packet of size 7 containing "packet\0" */ + ENetPacket* packet = enet_packet_create("packet", + strlen("packet") + 1, + ENET_PACKET_FLAG_RELIABLE); + /* Extend the packet so and append the string "foo", so it now */ + /* contains "packetfoo\0" */ + enet_packet_resize(packet, strlen("packetfoo") + 1); + strcpy((char*)&packet->data[strlen("packet")], "foo"); + /* Send the packet to the peer over channel id 0. */ + /* One could also broadcast the packet by */ + /* enet_host_broadcast (host, 0, packet); */ + enet_peer_send(natpeer, 0, packet); } switch (event.type) { - case ENET_EVENT_TYPE_CONNECT: - printf ("A new client connected from %x:%u.\n", - event.peer -> address.host, - event.peer -> address.port); - /* Store any relevant client information here. */ - event.peer -> data = (char*)"Client information"; - break; - case ENET_EVENT_TYPE_RECEIVE: - printf ("A packet of length %u containing %s was received from %s on channel %u.\n", - event.packet -> dataLength, - event.packet -> data, - event.peer -> data, - event.channelID); - /* Clean up the packet now that we're done using it. */ + case ENET_EVENT_TYPE_CONNECT: + printf("A new client connected from %x:%u.\n", + event.peer->address.host, + event.peer->address.port); + /* Store any relevant client information here. */ + event.peer->data = (char*)"Client information"; + break; + case ENET_EVENT_TYPE_RECEIVE: + printf("A packet of length %u containing %s was received from %s on channel %u.\n", + event.packet->dataLength, + event.packet->data, + event.peer->data, + event.channelID); + /* Clean up the packet now that we're done using it. */ - if (event.packet->dataLength==sizeof(ENetAddress)) - { - ENetAddress* address = (ENetAddress*)event.packet->data; - printf("received other client's address from server, connecting...\n"); - natpeer = enet_host_connect (client, address, 2, 0); - if (natpeer== NULL) + if (event.packet->dataLength == sizeof(ENetAddress)) { - fprintf (stderr, "No available peers for initiating an ENet connection.\n"); - exit (EXIT_FAILURE); - } - /* Wait up to 5 seconds for the connection attempt to succeed. */ - if (enet_host_service (client, & event, 5000) > 0 && - event.type == ENET_EVENT_TYPE_CONNECT) - { - puts ("Connection to natpeer succeeded."); - } else - { - enet_peer_reset (natpeer); - puts ("Connection to natpeer failed."); - natpeer=0; - exit(0); + ENetAddress* address = (ENetAddress*)event.packet->data; + printf("received other client's address from server, connecting...\n"); + natpeer = enet_host_connect(client, address, 2, 0); + if (natpeer == NULL) + { + fprintf(stderr, "No available peers for initiating an ENet connection.\n"); + exit(EXIT_FAILURE); + } + /* Wait up to 5 seconds for the connection attempt to succeed. */ + if (enet_host_service(client, &event, 5000) > 0 && + event.type == ENET_EVENT_TYPE_CONNECT) + { + puts("Connection to natpeer succeeded."); + } + else + { + enet_peer_reset(natpeer); + puts("Connection to natpeer failed."); + natpeer = 0; + exit(0); + } } - } + enet_packet_destroy(event.packet); + break; - enet_packet_destroy (event.packet); - break; - - case ENET_EVENT_TYPE_DISCONNECT: - printf ("%s disconnected.\n", event.peer -> data); - /* Reset the peer's client information. */ - event.peer -> data = NULL; + case ENET_EVENT_TYPE_DISCONNECT: + printf("%s disconnected.\n", event.peer->data); + /* Reset the peer's client information. */ + event.peer->data = NULL; } } /* One could just use enet_host_service() instead. */ - enet_host_flush (client);//host); + enet_host_flush(client); //host); } else { /* Either the 5 seconds are up or a disconnect event was */ /* received. Reset the peer in the event the 5 seconds */ /* had run out without any significant event. */ - enet_peer_reset (dedicatedpeer); - puts ("Connection to some.server.net:1234 failed."); + enet_peer_reset(dedicatedpeer); + puts("Connection to some.server.net:1234 failed."); } - - - - - enet_host_destroy(client); - + return 0; } - - - - - - - - - - - - diff --git a/test/enet/nat_punchthrough/server/main.cpp b/test/enet/nat_punchthrough/server/main.cpp index c06adeeaa..e05f0f397 100644 --- a/test/enet/nat_punchthrough/server/main.cpp +++ b/test/enet/nat_punchthrough/server/main.cpp @@ -3,107 +3,98 @@ #include #include - -ENetPeer* mypeers[2]={0,0}; +ENetPeer* mypeers[2] = {0, 0}; ENetAddress clientAddresses[2]; -int numpeers=0; +int numpeers = 0; int main(int argc, char* argv[]) { - fprintf(stderr,"starting enet dedicated server\n"); + fprintf(stderr, "starting enet dedicated server\n"); - if (enet_initialize () != 0) - { - fprintf (stderr, "An error occurred while initializing ENet.\n"); - return EXIT_FAILURE; - } - atexit (enet_deinitialize); + if (enet_initialize() != 0) + { + fprintf(stderr, "An error occurred while initializing ENet.\n"); + return EXIT_FAILURE; + } + atexit(enet_deinitialize); ENetAddress address; - ENetHost * server; + ENetHost* server; /* Bind the server to the default localhost. */ /* A specific host address can be specified by */ /* enet_address_set_host (& address, "x.x.x.x"); */ address.host = ENET_HOST_ANY; /* Bind the server to port 1234. */ address.port = 1234; - server = enet_host_create (& address /* the address to bind the server host to */, - 32 /* allow up to 32 clients and/or outgoing connections */, - 2 /* allow up to 2 channels to be used, 0 and 1 */, - 0 /* assume any amount of incoming bandwidth */, - 0 /* assume any amount of outgoing bandwidth */); + server = enet_host_create(&address /* the address to bind the server host to */, + 32 /* allow up to 32 clients and/or outgoing connections */, + 2 /* allow up to 2 channels to be used, 0 and 1 */, + 0 /* assume any amount of incoming bandwidth */, + 0 /* assume any amount of outgoing bandwidth */); if (server == NULL) { - fprintf (stderr, - "An error occurred while trying to create an ENet server host.\n"); - exit (EXIT_FAILURE); + fprintf(stderr, + "An error occurred while trying to create an ENet server host.\n"); + exit(EXIT_FAILURE); } - - + ENetEvent event; - /* Wait up to 10000000 milliseconds for an event. */ - while (enet_host_service (server, & event, 10000000) > 0) + /* Wait up to 10000000 milliseconds for an event. */ + while (enet_host_service(server, &event, 10000000) > 0) { switch (event.type) { - case ENET_EVENT_TYPE_CONNECT: - char clientname[1024]; - enet_address_get_host(&event.peer -> address,clientname, 1024); - printf ("A new client connected from %s:%u.\n", - clientname, - event.peer -> address.port); - /* Store any relevant client information here. */ - event.peer -> data = (char*)"Client information"; - if (numpeers<2) - { - clientAddresses[numpeers] = event.peer->address; - mypeers[numpeers] = event.peer; - } - numpeers++; - if (numpeers==2) - { - printf("exchanging addresses for NAT punchthrough\n"); - //exchange the address info - for (int i=0;i<2;i++) + case ENET_EVENT_TYPE_CONNECT: + char clientname[1024]; + enet_address_get_host(&event.peer->address, clientname, 1024); + printf("A new client connected from %s:%u.\n", + clientname, + event.peer->address.port); + /* Store any relevant client information here. */ + event.peer->data = (char*)"Client information"; + if (numpeers < 2) { - int sz = sizeof(ENetAddress); - /* Create a reliable packet of size 7 containing "packet\0" */ - ENetPacket * packet = enet_packet_create (&clientAddresses[i], - sz, - ENET_PACKET_FLAG_RELIABLE); - enet_peer_send (mypeers[1-i], 0, packet); - - + clientAddresses[numpeers] = event.peer->address; + mypeers[numpeers] = event.peer; + } + numpeers++; + if (numpeers == 2) + { + printf("exchanging addresses for NAT punchthrough\n"); + //exchange the address info + for (int i = 0; i < 2; i++) + { + int sz = sizeof(ENetAddress); + /* Create a reliable packet of size 7 containing "packet\0" */ + ENetPacket* packet = enet_packet_create(&clientAddresses[i], + sz, + ENET_PACKET_FLAG_RELIABLE); + enet_peer_send(mypeers[1 - i], 0, packet); + } + //prepare for the next pair of clients to connect/NAT punchthrough + numpeers = 0; } - //prepare for the next pair of clients to connect/NAT punchthrough - numpeers=0; - } - break; - case ENET_EVENT_TYPE_RECEIVE: - printf ("A packet of length %u containing %s was received from %s on channel %u.\n", - event.packet -> dataLength, - event.packet -> data, - event.peer -> data, - event.channelID); - /* Clean up the packet now that we're done using it. */ - enet_packet_destroy (event.packet); + break; + case ENET_EVENT_TYPE_RECEIVE: + printf("A packet of length %u containing %s was received from %s on channel %u.\n", + event.packet->dataLength, + event.packet->data, + event.peer->data, + event.channelID); + /* Clean up the packet now that we're done using it. */ + enet_packet_destroy(event.packet); - break; - - case ENET_EVENT_TYPE_DISCONNECT: - printf ("%s disconnected.\n", event.peer -> data); - /* Reset the peer's client information. */ - event.peer -> data = NULL; + break; + + case ENET_EVENT_TYPE_DISCONNECT: + printf("%s disconnected.\n", event.peer->data); + /* Reset the peer's client information. */ + event.peer->data = NULL; } } - - - - - enet_host_destroy(server); printf("server exited, press key\n"); getchar(); diff --git a/test/gtest-1.7.0/include/gtest/gtest-death-test.h b/test/gtest-1.7.0/include/gtest/gtest-death-test.h index 957a69c6a..1b22bae6e 100644 --- a/test/gtest-1.7.0/include/gtest/gtest-death-test.h +++ b/test/gtest-1.7.0/include/gtest/gtest-death-test.h @@ -40,8 +40,8 @@ #include "gtest/internal/gtest-death-test-internal.h" -namespace testing { - +namespace testing +{ // This flag controls the style of death tests. Valid values are "threadsafe", // meaning that the death test child process will re-execute the test binary // from the start, running only a single death test, or "fast", @@ -51,8 +51,8 @@ GTEST_DECLARE_string_(death_test_style); #if GTEST_HAS_DEATH_TEST -namespace internal { - +namespace internal +{ // Returns a Boolean value indicating whether the caller is currently // executing in the context of the death test child process. Tools such as // Valgrind heap checkers may need this to modify their behavior in death @@ -165,50 +165,54 @@ GTEST_API_ bool InDeathTestChild(); // Asserts that a given statement causes the program to exit, with an // integer exit status that satisfies predicate, and emitting error output // that matches regex. -# define ASSERT_EXIT(statement, predicate, regex) \ - GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) +#define ASSERT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_FATAL_FAILURE_) // Like ASSERT_EXIT, but continues on to successive tests in the // test case, if any: -# define EXPECT_EXIT(statement, predicate, regex) \ - GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) +#define EXPECT_EXIT(statement, predicate, regex) \ + GTEST_DEATH_TEST_(statement, predicate, regex, GTEST_NONFATAL_FAILURE_) // Asserts that a given statement causes the program to exit, either by // explicitly exiting with a nonzero exit code or being killed by a // signal, and emitting error output that matches regex. -# define ASSERT_DEATH(statement, regex) \ - ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) +#define ASSERT_DEATH(statement, regex) \ + ASSERT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) // Like ASSERT_DEATH, but continues on to successive tests in the // test case, if any: -# define EXPECT_DEATH(statement, regex) \ - EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) +#define EXPECT_DEATH(statement, regex) \ + EXPECT_EXIT(statement, ::testing::internal::ExitedUnsuccessfully, regex) // Two predicate classes that can be used in {ASSERT,EXPECT}_EXIT*: // Tests that an exit code describes a normal exit with a given exit code. -class GTEST_API_ ExitedWithCode { - public: - explicit ExitedWithCode(int exit_code); - bool operator()(int exit_status) const; - private: - // No implementation - assignment is unsupported. - void operator=(const ExitedWithCode& other); +class GTEST_API_ ExitedWithCode +{ +public: + explicit ExitedWithCode(int exit_code); + bool operator()(int exit_status) const; - const int exit_code_; +private: + // No implementation - assignment is unsupported. + void operator=(const ExitedWithCode& other); + + const int exit_code_; }; -# if !GTEST_OS_WINDOWS +#if !GTEST_OS_WINDOWS // Tests that an exit code describes an exit due to termination by a // given signal. -class GTEST_API_ KilledBySignal { - public: - explicit KilledBySignal(int signum); - bool operator()(int exit_status) const; - private: - const int signum_; +class GTEST_API_ KilledBySignal +{ +public: + explicit KilledBySignal(int signum); + bool operator()(int exit_status) const; + +private: + const int signum_; }; -# endif // !GTEST_OS_WINDOWS +#endif // !GTEST_OS_WINDOWS // EXPECT_DEBUG_DEATH asserts that the given statements die in debug mode. // The death testing framework causes this to have interesting semantics, @@ -253,23 +257,23 @@ class GTEST_API_ KilledBySignal { // EXPECT_EQ(12, DieInDebugOr12(&sideeffect)); // }, "death"); // -# ifdef NDEBUG +#ifdef NDEBUG -# define EXPECT_DEBUG_DEATH(statement, regex) \ - GTEST_EXECUTE_STATEMENT_(statement, regex) +#define EXPECT_DEBUG_DEATH(statement, regex) \ + GTEST_EXECUTE_STATEMENT_(statement, regex) -# define ASSERT_DEBUG_DEATH(statement, regex) \ - GTEST_EXECUTE_STATEMENT_(statement, regex) +#define ASSERT_DEBUG_DEATH(statement, regex) \ + GTEST_EXECUTE_STATEMENT_(statement, regex) -# else +#else -# define EXPECT_DEBUG_DEATH(statement, regex) \ - EXPECT_DEATH(statement, regex) +#define EXPECT_DEBUG_DEATH(statement, regex) \ + EXPECT_DEATH(statement, regex) -# define ASSERT_DEBUG_DEATH(statement, regex) \ - ASSERT_DEATH(statement, regex) +#define ASSERT_DEBUG_DEATH(statement, regex) \ + ASSERT_DEATH(statement, regex) -# endif // NDEBUG for EXPECT_DEBUG_DEATH +#endif // NDEBUG for EXPECT_DEBUG_DEATH #endif // GTEST_HAS_DEATH_TEST // EXPECT_DEATH_IF_SUPPORTED(statement, regex) and @@ -278,15 +282,15 @@ class GTEST_API_ KilledBySignal { // useful when you are combining death test assertions with normal test // assertions in one test. #if GTEST_HAS_DEATH_TEST -# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ - EXPECT_DEATH(statement, regex) -# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ - ASSERT_DEATH(statement, regex) +#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + EXPECT_DEATH(statement, regex) +#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + ASSERT_DEATH(statement, regex) #else -# define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ - GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) -# define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ - GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return) +#define EXPECT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, ) +#define ASSERT_DEATH_IF_SUPPORTED(statement, regex) \ + GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, return ) #endif } // namespace testing diff --git a/test/gtest-1.7.0/include/gtest/gtest-message.h b/test/gtest-1.7.0/include/gtest/gtest-message.h index fe879bca7..600d3a536 100644 --- a/test/gtest-1.7.0/include/gtest/gtest-message.h +++ b/test/gtest-1.7.0/include/gtest/gtest-message.h @@ -54,8 +54,8 @@ // See Message& operator<<(...) below for why. void operator<<(const testing::internal::Secret&, int); -namespace testing { - +namespace testing +{ // The Message class works like an ostream repeater. // // Typical usage: @@ -82,166 +82,183 @@ namespace testing { // latter (it causes an access violation if you do). The Message // class hides this difference by treating a NULL char pointer as // "(null)". -class GTEST_API_ Message { - private: - // The type of basic IO manipulators (endl, ends, and flush) for - // narrow streams. - typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); +class GTEST_API_ Message +{ +private: + // The type of basic IO manipulators (endl, ends, and flush) for + // narrow streams. + typedef std::ostream& (*BasicNarrowIoManip)(std::ostream&); - public: - // Constructs an empty Message. - Message(); +public: + // Constructs an empty Message. + Message(); - // Copy constructor. - Message(const Message& msg) : ss_(new ::std::stringstream) { // NOLINT - *ss_ << msg.GetString(); - } + // Copy constructor. + Message(const Message& msg) : ss_(new ::std::stringstream) + { // NOLINT + *ss_ << msg.GetString(); + } - // Constructs a Message from a C-string. - explicit Message(const char* str) : ss_(new ::std::stringstream) { - *ss_ << str; - } + // Constructs a Message from a C-string. + explicit Message(const char* str) : ss_(new ::std::stringstream) + { + *ss_ << str; + } #if GTEST_OS_SYMBIAN - // Streams a value (either a pointer or not) to this object. - template - inline Message& operator <<(const T& value) { - StreamHelper(typename internal::is_pointer::type(), value); - return *this; - } + // Streams a value (either a pointer or not) to this object. + template + inline Message& operator<<(const T& value) + { + StreamHelper(typename internal::is_pointer::type(), value); + return *this; + } #else - // Streams a non-pointer value to this object. - template - inline Message& operator <<(const T& val) { - // Some libraries overload << for STL containers. These - // overloads are defined in the global namespace instead of ::std. - // - // C++'s symbol lookup rule (i.e. Koenig lookup) says that these - // overloads are visible in either the std namespace or the global - // namespace, but not other namespaces, including the testing - // namespace which Google Test's Message class is in. - // - // To allow STL containers (and other types that has a << operator - // defined in the global namespace) to be used in Google Test - // assertions, testing::Message must access the custom << operator - // from the global namespace. With this using declaration, - // overloads of << defined in the global namespace and those - // visible via Koenig lookup are both exposed in this function. - using ::operator <<; - *ss_ << val; - return *this; - } + // Streams a non-pointer value to this object. + template + inline Message& operator<<(const T& val) + { + // Some libraries overload << for STL containers. These + // overloads are defined in the global namespace instead of ::std. + // + // C++'s symbol lookup rule (i.e. Koenig lookup) says that these + // overloads are visible in either the std namespace or the global + // namespace, but not other namespaces, including the testing + // namespace which Google Test's Message class is in. + // + // To allow STL containers (and other types that has a << operator + // defined in the global namespace) to be used in Google Test + // assertions, testing::Message must access the custom << operator + // from the global namespace. With this using declaration, + // overloads of << defined in the global namespace and those + // visible via Koenig lookup are both exposed in this function. + using ::operator<<; + *ss_ << val; + return *this; + } - // Streams a pointer value to this object. - // - // This function is an overload of the previous one. When you - // stream a pointer to a Message, this definition will be used as it - // is more specialized. (The C++ Standard, section - // [temp.func.order].) If you stream a non-pointer, then the - // previous definition will be used. - // - // The reason for this overload is that streaming a NULL pointer to - // ostream is undefined behavior. Depending on the compiler, you - // may get "0", "(nil)", "(null)", or an access violation. To - // ensure consistent result across compilers, we always treat NULL - // as "(null)". - template - inline Message& operator <<(T* const& pointer) { // NOLINT - if (pointer == NULL) { - *ss_ << "(null)"; - } else { - *ss_ << pointer; - } - return *this; - } + // Streams a pointer value to this object. + // + // This function is an overload of the previous one. When you + // stream a pointer to a Message, this definition will be used as it + // is more specialized. (The C++ Standard, section + // [temp.func.order].) If you stream a non-pointer, then the + // previous definition will be used. + // + // The reason for this overload is that streaming a NULL pointer to + // ostream is undefined behavior. Depending on the compiler, you + // may get "0", "(nil)", "(null)", or an access violation. To + // ensure consistent result across compilers, we always treat NULL + // as "(null)". + template + inline Message& operator<<(T* const& pointer) + { // NOLINT + if (pointer == NULL) + { + *ss_ << "(null)"; + } + else + { + *ss_ << pointer; + } + return *this; + } #endif // GTEST_OS_SYMBIAN - // Since the basic IO manipulators are overloaded for both narrow - // and wide streams, we have to provide this specialized definition - // of operator <<, even though its body is the same as the - // templatized version above. Without this definition, streaming - // endl or other basic IO manipulators to Message will confuse the - // compiler. - Message& operator <<(BasicNarrowIoManip val) { - *ss_ << val; - return *this; - } + // Since the basic IO manipulators are overloaded for both narrow + // and wide streams, we have to provide this specialized definition + // of operator <<, even though its body is the same as the + // templatized version above. Without this definition, streaming + // endl or other basic IO manipulators to Message will confuse the + // compiler. + Message& operator<<(BasicNarrowIoManip val) + { + *ss_ << val; + return *this; + } - // Instead of 1/0, we want to see true/false for bool values. - Message& operator <<(bool b) { - return *this << (b ? "true" : "false"); - } + // Instead of 1/0, we want to see true/false for bool values. + Message& operator<<(bool b) + { + return *this << (b ? "true" : "false"); + } - // These two overloads allow streaming a wide C string to a Message - // using the UTF-8 encoding. - Message& operator <<(const wchar_t* wide_c_str); - Message& operator <<(wchar_t* wide_c_str); + // These two overloads allow streaming a wide C string to a Message + // using the UTF-8 encoding. + Message& operator<<(const wchar_t* wide_c_str); + Message& operator<<(wchar_t* wide_c_str); #if GTEST_HAS_STD_WSTRING - // Converts the given wide string to a narrow string using the UTF-8 - // encoding, and streams the result to this Message object. - Message& operator <<(const ::std::wstring& wstr); + // Converts the given wide string to a narrow string using the UTF-8 + // encoding, and streams the result to this Message object. + Message& operator<<(const ::std::wstring& wstr); #endif // GTEST_HAS_STD_WSTRING #if GTEST_HAS_GLOBAL_WSTRING - // Converts the given wide string to a narrow string using the UTF-8 - // encoding, and streams the result to this Message object. - Message& operator <<(const ::wstring& wstr); + // Converts the given wide string to a narrow string using the UTF-8 + // encoding, and streams the result to this Message object. + Message& operator<<(const ::wstring& wstr); #endif // GTEST_HAS_GLOBAL_WSTRING - // Gets the text streamed to this object so far as an std::string. - // Each '\0' character in the buffer is replaced with "\\0". - // - // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - std::string GetString() const; - - private: + // Gets the text streamed to this object so far as an std::string. + // Each '\0' character in the buffer is replaced with "\\0". + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + std::string GetString() const; +private: #if GTEST_OS_SYMBIAN - // These are needed as the Nokia Symbian Compiler cannot decide between - // const T& and const T* in a function template. The Nokia compiler _can_ - // decide between class template specializations for T and T*, so a - // tr1::type_traits-like is_pointer works, and we can overload on that. - template - inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) { - if (pointer == NULL) { - *ss_ << "(null)"; - } else { - *ss_ << pointer; - } - } - template - inline void StreamHelper(internal::false_type /*is_pointer*/, - const T& value) { - // See the comments in Message& operator <<(const T&) above for why - // we need this using statement. - using ::operator <<; - *ss_ << value; - } + // These are needed as the Nokia Symbian Compiler cannot decide between + // const T& and const T* in a function template. The Nokia compiler _can_ + // decide between class template specializations for T and T*, so a + // tr1::type_traits-like is_pointer works, and we can overload on that. + template + inline void StreamHelper(internal::true_type /*is_pointer*/, T* pointer) + { + if (pointer == NULL) + { + *ss_ << "(null)"; + } + else + { + *ss_ << pointer; + } + } + template + inline void StreamHelper(internal::false_type /*is_pointer*/, + const T& value) + { + // See the comments in Message& operator <<(const T&) above for why + // we need this using statement. + using ::operator<<; + *ss_ << value; + } #endif // GTEST_OS_SYMBIAN - // We'll hold the text streamed to this object here. - const internal::scoped_ptr< ::std::stringstream> ss_; + // We'll hold the text streamed to this object here. + const internal::scoped_ptr< ::std::stringstream> ss_; - // We declare (but don't implement) this to prevent the compiler - // from implementing the assignment operator. - void operator=(const Message&); + // We declare (but don't implement) this to prevent the compiler + // from implementing the assignment operator. + void operator=(const Message&); }; // Streams a Message to an ostream. -inline std::ostream& operator <<(std::ostream& os, const Message& sb) { - return os << sb.GetString(); +inline std::ostream& operator<<(std::ostream& os, const Message& sb) +{ + return os << sb.GetString(); } -namespace internal { - +namespace internal +{ // Converts a streamable value to an std::string. A NULL pointer is // converted to "(null)". When the input value is a ::string, // ::std::string, ::wstring, or ::std::wstring object, each NUL // character in it is replaced with "\\0". template -std::string StreamableToString(const T& streamable) { - return (Message() << streamable).GetString(); +std::string StreamableToString(const T& streamable) +{ + return (Message() << streamable).GetString(); } } // namespace internal diff --git a/test/gtest-1.7.0/include/gtest/gtest-param-test.h b/test/gtest-1.7.0/include/gtest/gtest-param-test.h index d6702c8f1..2ff255a5e 100644 --- a/test/gtest-1.7.0/include/gtest/gtest-param-test.h +++ b/test/gtest-1.7.0/include/gtest/gtest-param-test.h @@ -41,7 +41,6 @@ #ifndef GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ #define GTEST_INCLUDE_GTEST_GTEST_PARAM_TEST_H_ - // Value-parameterized tests allow you to test your code with different // parameters without writing multiple copies of the same test. // @@ -182,7 +181,7 @@ TEST_P(DerivedTest, DoesBlah) { #include "gtest/internal/gtest-port.h" #if !GTEST_OS_SYMBIAN -# include +#include #endif // scripts/fuse_gtest.py depends on gtest's own header being #included @@ -194,8 +193,8 @@ TEST_P(DerivedTest, DoesBlah) { #if GTEST_HAS_PARAM_TEST -namespace testing { - +namespace testing +{ // Functions producing parameter generators. // // Google Test uses these generators to produce parameters for value- @@ -239,14 +238,16 @@ namespace testing { // to contain any elements. // template -internal::ParamGenerator Range(T start, T end, IncrementT step) { - return internal::ParamGenerator( - new internal::RangeGenerator(start, end, step)); +internal::ParamGenerator Range(T start, T end, IncrementT step) +{ + return internal::ParamGenerator( + new internal::RangeGenerator(start, end, step)); } template -internal::ParamGenerator Range(T start, T end) { - return Range(start, end, 1); +internal::ParamGenerator Range(T start, T end) +{ + return Range(start, end, 1); } // ValuesIn() function allows generation of tests with parameters coming from @@ -306,23 +307,25 @@ internal::ParamGenerator Range(T start, T end) { // template internal::ParamGenerator< - typename ::testing::internal::IteratorTraits::value_type> -ValuesIn(ForwardIterator begin, ForwardIterator end) { - typedef typename ::testing::internal::IteratorTraits - ::value_type ParamType; - return internal::ParamGenerator( - new internal::ValuesInIteratorRangeGenerator(begin, end)); + typename ::testing::internal::IteratorTraits::value_type> +ValuesIn(ForwardIterator begin, ForwardIterator end) +{ + typedef typename ::testing::internal::IteratorTraits::value_type ParamType; + return internal::ParamGenerator( + new internal::ValuesInIteratorRangeGenerator(begin, end)); } template -internal::ParamGenerator ValuesIn(const T (&array)[N]) { - return ValuesIn(array, array + N); +internal::ParamGenerator ValuesIn(const T (&array)[N]) +{ + return ValuesIn(array, array + N); } template internal::ParamGenerator ValuesIn( - const Container& container) { - return ValuesIn(container.begin(), container.end()); + const Container& container) +{ + return ValuesIn(container.begin(), container.end()); } // Values() allows generating tests from explicitly specified list of @@ -345,856 +348,946 @@ internal::ParamGenerator ValuesIn( // Currently, Values() supports from 1 to 50 parameters. // template -internal::ValueArray1 Values(T1 v1) { - return internal::ValueArray1(v1); +internal::ValueArray1 Values(T1 v1) +{ + return internal::ValueArray1(v1); } template -internal::ValueArray2 Values(T1 v1, T2 v2) { - return internal::ValueArray2(v1, v2); +internal::ValueArray2 Values(T1 v1, T2 v2) +{ + return internal::ValueArray2(v1, v2); } template -internal::ValueArray3 Values(T1 v1, T2 v2, T3 v3) { - return internal::ValueArray3(v1, v2, v3); +internal::ValueArray3 Values(T1 v1, T2 v2, T3 v3) +{ + return internal::ValueArray3(v1, v2, v3); } template -internal::ValueArray4 Values(T1 v1, T2 v2, T3 v3, T4 v4) { - return internal::ValueArray4(v1, v2, v3, v4); +internal::ValueArray4 Values(T1 v1, T2 v2, T3 v3, T4 v4) +{ + return internal::ValueArray4(v1, v2, v3, v4); } template internal::ValueArray5 Values(T1 v1, T2 v2, T3 v3, T4 v4, - T5 v5) { - return internal::ValueArray5(v1, v2, v3, v4, v5); + T5 v5) +{ + return internal::ValueArray5(v1, v2, v3, v4, v5); } template + typename T6> internal::ValueArray6 Values(T1 v1, T2 v2, T3 v3, - T4 v4, T5 v5, T6 v6) { - return internal::ValueArray6(v1, v2, v3, v4, v5, v6); + T4 v4, T5 v5, T6 v6) +{ + return internal::ValueArray6(v1, v2, v3, v4, v5, v6); } template + typename T6, typename T7> internal::ValueArray7 Values(T1 v1, T2 v2, T3 v3, - T4 v4, T5 v5, T6 v6, T7 v7) { - return internal::ValueArray7(v1, v2, v3, v4, v5, - v6, v7); + T4 v4, T5 v5, T6 v6, T7 v7) +{ + return internal::ValueArray7(v1, v2, v3, v4, v5, + v6, v7); } template + typename T6, typename T7, typename T8> internal::ValueArray8 Values(T1 v1, T2 v2, - T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) { - return internal::ValueArray8(v1, v2, v3, v4, - v5, v6, v7, v8); + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8) +{ + return internal::ValueArray8(v1, v2, v3, v4, + v5, v6, v7, v8); } template + typename T6, typename T7, typename T8, typename T9> internal::ValueArray9 Values(T1 v1, T2 v2, - T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) { - return internal::ValueArray9(v1, v2, v3, - v4, v5, v6, v7, v8, v9); + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9) +{ + return internal::ValueArray9(v1, v2, v3, + v4, v5, v6, v7, v8, v9); } template + typename T6, typename T7, typename T8, typename T9, typename T10> internal::ValueArray10 Values(T1 v1, - T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) { - return internal::ValueArray10(v1, - v2, v3, v4, v5, v6, v7, v8, v9, v10); + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10) +{ + return internal::ValueArray10(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11> internal::ValueArray11 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11) { - return internal::ValueArray11(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11); + T11> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11) +{ + return internal::ValueArray11(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12> internal::ValueArray12 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12) { - return internal::ValueArray12(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12); + T12> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12) +{ + return internal::ValueArray12(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13> internal::ValueArray13 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13) { - return internal::ValueArray13(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13); + T13> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13) +{ + return internal::ValueArray13(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14> internal::ValueArray14 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) { - return internal::ValueArray14(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, - v14); + T14> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) +{ + return internal::ValueArray14(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15> internal::ValueArray15 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, - T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) { - return internal::ValueArray15(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, - v13, v14, v15); + T14, T15> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) +{ + return internal::ValueArray15(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16> internal::ValueArray16 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, - T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, - T16 v16) { - return internal::ValueArray16(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, - v12, v13, v14, v15, v16); + T14, T15, T16> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16) +{ + return internal::ValueArray16(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17> internal::ValueArray17 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, - T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, - T16 v16, T17 v17) { - return internal::ValueArray17(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, - v11, v12, v13, v14, v15, v16, v17); + T14, T15, T16, T17> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17) +{ + return internal::ValueArray17(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18> internal::ValueArray18 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, - T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, - T16 v16, T17 v17, T18 v18) { - return internal::ValueArray18(v1, v2, v3, v4, v5, v6, v7, v8, v9, - v10, v11, v12, v13, v14, v15, v16, v17, v18); + T14, T15, T16, T17, T18> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18) +{ + return internal::ValueArray18(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19> internal::ValueArray19 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, - T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, - T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) { - return internal::ValueArray19(v1, v2, v3, v4, v5, v6, v7, v8, - v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19); + T14, T15, T16, T17, T18, T19> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19) +{ + return internal::ValueArray19(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20> internal::ValueArray20 Values(T1 v1, T2 v2, T3 v3, T4 v4, - T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, - T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) { - return internal::ValueArray20(v1, v2, v3, v4, v5, v6, v7, - v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20); + T14, T15, T16, T17, T18, T19, T20> +Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20) +{ + return internal::ValueArray20(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21> internal::ValueArray21 Values(T1 v1, T2 v2, T3 v3, T4 v4, - T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, - T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) { - return internal::ValueArray21(v1, v2, v3, v4, v5, v6, - v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21); + T14, T15, T16, T17, T18, T19, T20, T21> +Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21) +{ + return internal::ValueArray21(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22> internal::ValueArray22 Values(T1 v1, T2 v2, T3 v3, - T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, - T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, - T21 v21, T22 v22) { - return internal::ValueArray22(v1, v2, v3, v4, - v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, - v20, v21, v22); + T14, T15, T16, T17, T18, T19, T20, T21, T22> +Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22) +{ + return internal::ValueArray22(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23> internal::ValueArray23 Values(T1 v1, T2 v2, - T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, - T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, - T21 v21, T22 v22, T23 v23) { - return internal::ValueArray23(v1, v2, v3, - v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, - v20, v21, v22, v23); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23> +Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23) +{ + return internal::ValueArray23(v1, v2, v3, + v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24> internal::ValueArray24 Values(T1 v1, T2 v2, - T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, - T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, - T21 v21, T22 v22, T23 v23, T24 v24) { - return internal::ValueArray24(v1, v2, - v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, - v19, v20, v21, v22, v23, v24); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24> +Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24) +{ + return internal::ValueArray24(v1, v2, + v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, v20, v21, v22, v23, v24); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25> internal::ValueArray25 Values(T1 v1, - T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, - T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, - T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) { - return internal::ValueArray25(v1, - v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, - v18, v19, v20, v21, v22, v23, v24, v25); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25> +Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, + T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, + T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25) +{ + return internal::ValueArray25(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, + v18, v19, v20, v21, v22, v23, v24, v25); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26> internal::ValueArray26 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26) { - return internal::ValueArray26(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, - v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, + T26> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26) +{ + return internal::ValueArray26(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27> internal::ValueArray27 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27) { - return internal::ValueArray27(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, - v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, + T27> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27) +{ + return internal::ValueArray27(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, + v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28> internal::ValueArray28 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28) { - return internal::ValueArray28(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, - v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, - v28); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, + T28> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28) +{ + return internal::ValueArray28(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, + v28); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29> internal::ValueArray29 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29) { - return internal::ValueArray29(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, - v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, - v27, v28, v29); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29) +{ + return internal::ValueArray29(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, + v27, v28, v29); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30> internal::ValueArray30 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, - T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, - T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, - T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) { - return internal::ValueArray30(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, - v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, - v26, v27, v28, v29, v30); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) +{ + return internal::ValueArray30(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, + v26, v27, v28, v29, v30); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31> internal::ValueArray31 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, - T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, - T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, - T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) { - return internal::ValueArray31(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, - v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, - v25, v26, v27, v28, v29, v30, v31); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) +{ + return internal::ValueArray31(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, + v25, v26, v27, v28, v29, v30, v31); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32> internal::ValueArray32 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, - T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, - T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, - T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, - T32 v32) { - return internal::ValueArray32(v1, v2, v3, v4, v5, v6, v7, v8, v9, - v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, - v24, v25, v26, v27, v28, v29, v30, v31, v32); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32) +{ + return internal::ValueArray32(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33> internal::ValueArray33 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, - T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, - T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, - T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, - T32 v32, T33 v33) { - return internal::ValueArray33(v1, v2, v3, v4, v5, v6, v7, v8, - v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, - v24, v25, v26, v27, v28, v29, v30, v31, v32, v33); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33) +{ + return internal::ValueArray33(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34> internal::ValueArray34 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, - T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, - T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, - T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, - T31 v31, T32 v32, T33 v33, T34 v34) { - return internal::ValueArray34(v1, v2, v3, v4, v5, v6, v7, - v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, - v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, + T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, + T31 v31, T32 v32, T33 v33, T34 v34) +{ + return internal::ValueArray34(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, + v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35> internal::ValueArray35 Values(T1 v1, T2 v2, T3 v3, T4 v4, - T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, - T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, - T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, - T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) { - return internal::ValueArray35(v1, v2, v3, v4, v5, v6, - v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, - v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35> +Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35) +{ + return internal::ValueArray35(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, + v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36> internal::ValueArray36 Values(T1 v1, T2 v2, T3 v3, T4 v4, - T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, - T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, - T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, - T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) { - return internal::ValueArray36(v1, v2, v3, v4, - v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, - v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, - v34, v35, v36); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36> +Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36) +{ + return internal::ValueArray36(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37> internal::ValueArray37 Values(T1 v1, T2 v2, T3 v3, - T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, - T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, - T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, - T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, - T37 v37) { - return internal::ValueArray37(v1, v2, v3, - v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, - v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, - v34, v35, v36, v37); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37> +Values(T1 v1, T2 v2, T3 v3, + T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37) +{ + return internal::ValueArray37(v1, v2, v3, + v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36, v37); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38> internal::ValueArray38 Values(T1 v1, T2 v2, - T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, - T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, - T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, - T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, - T37 v37, T38 v38) { - return internal::ValueArray38(v1, v2, - v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, - v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, - v33, v34, v35, v36, v37, v38); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38> +Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37, T38 v38) +{ + return internal::ValueArray38(v1, v2, + v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, + v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, + v33, v34, v35, v36, v37, v38); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39> internal::ValueArray39 Values(T1 v1, T2 v2, - T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, - T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, - T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, - T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, - T37 v37, T38 v38, T39 v39) { - return internal::ValueArray39(v1, - v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, - v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, - v32, v33, v34, v35, v36, v37, v38, v39); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39> +Values(T1 v1, T2 v2, + T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, + T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, + T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, + T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, + T37 v37, T38 v38, T39 v39) +{ + return internal::ValueArray39(v1, + v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, + v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, + v32, v33, v34, v35, v36, v37, v38, v39); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40> internal::ValueArray40 Values(T1 v1, - T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, - T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, - T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, - T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, - T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) { - return internal::ValueArray40(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, - v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, - v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40> +Values(T1 v1, + T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, + T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, + T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, + T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, + T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) +{ + return internal::ValueArray40(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, + v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, + v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41> internal::ValueArray41 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) { - return internal::ValueArray41(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, - v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, - v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, + T41> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41) +{ + return internal::ValueArray41(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, + v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, + v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42> internal::ValueArray42 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42) { - return internal::ValueArray42(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, - v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, - v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, - v42); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, + T42> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42) +{ + return internal::ValueArray42(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, + v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, + v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, + v42); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43> internal::ValueArray43 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42, T43 v43) { - return internal::ValueArray43(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, - v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, - v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, - v41, v42, v43); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, + T43> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43) +{ + return internal::ValueArray43(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, + v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, + v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, + v41, v42, v43); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44> internal::ValueArray44 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42, T43 v43, T44 v44) { - return internal::ValueArray44(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, - v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, - v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, - v40, v41, v42, v43, v44); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44) +{ + return internal::ValueArray44(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, + v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, + v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, + v40, v41, v42, v43, v44); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45> internal::ValueArray45 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, - T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, - T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, - T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, - T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, - T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) { - return internal::ValueArray45(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, - v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, - v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, - v39, v40, v41, v42, v43, v44, v45); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, + T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, + T41 v41, T42 v42, T43 v43, T44 v44, T45 v45) +{ + return internal::ValueArray45(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, + v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, + v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, + v39, v40, v41, v42, v43, v44, v45); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46> internal::ValueArray46 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, - T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, - T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, - T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, - T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, - T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) { - return internal::ValueArray46(v1, v2, v3, v4, v5, v6, v7, v8, v9, - v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, - v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, - v38, v39, v40, v41, v42, v43, v44, v45, v46); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) +{ + return internal::ValueArray46(v1, v2, v3, v4, v5, v6, v7, v8, v9, + v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, + v38, v39, v40, v41, v42, v43, v44, v45, v46); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47> internal::ValueArray47 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, - T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, - T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, - T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, - T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, - T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) { - return internal::ValueArray47(v1, v2, v3, v4, v5, v6, v7, v8, - v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, - v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, - v38, v39, v40, v41, v42, v43, v44, v45, v46, v47); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) +{ + return internal::ValueArray47(v1, v2, v3, v4, v5, v6, v7, v8, + v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, + v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, + v38, v39, v40, v41, v42, v43, v44, v45, v46, v47); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48> internal::ValueArray48 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, - T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, - T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, - T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, - T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, - T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, - T48 v48) { - return internal::ValueArray48(v1, v2, v3, v4, v5, v6, v7, - v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, - v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, - v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47, T48> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, + T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, + T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, + T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, + T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, + T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, + T48 v48) +{ + return internal::ValueArray48(v1, v2, v3, v4, v5, v6, v7, + v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, + v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, + v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49> internal::ValueArray49 Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, - T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, - T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, - T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, - T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, - T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, - T47 v47, T48 v48, T49 v49) { - return internal::ValueArray49(v1, v2, v3, v4, v5, v6, - v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, - v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, - v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47, T48, T49> +Values(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, + T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, + T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, + T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, + T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, + T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, + T47 v47, T48 v48, T49 v49) +{ + return internal::ValueArray49(v1, v2, v3, v4, v5, v6, + v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, + v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, + v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49); } template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49, typename T50> internal::ValueArray50 Values(T1 v1, T2 v2, T3 v3, T4 v4, - T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, - T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, - T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, - T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, - T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, - T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) { - return internal::ValueArray50(v1, v2, v3, v4, - v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, - v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, - v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, - v48, v49, v50); + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47, T48, T49, T50> +Values(T1 v1, T2 v2, T3 v3, T4 v4, + T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, T10 v10, T11 v11, T12 v12, T13 v13, + T14 v14, T15 v15, T16 v16, T17 v17, T18 v18, T19 v19, T20 v20, T21 v21, + T22 v22, T23 v23, T24 v24, T25 v25, T26 v26, T27 v27, T28 v28, T29 v29, + T30 v30, T31 v31, T32 v32, T33 v33, T34 v34, T35 v35, T36 v36, T37 v37, + T38 v38, T39 v39, T40 v40, T41 v41, T42 v42, T43 v43, T44 v44, T45 v45, + T46 v46, T47 v47, T48 v48, T49 v49, T50 v50) +{ + return internal::ValueArray50(v1, v2, v3, v4, + v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, + v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, + v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, + v48, v49, v50); } // Bool() allows generating tests with parameters in a set of (false, true). @@ -1217,11 +1310,12 @@ internal::ValueArray50 Bool() { - return Values(false, true); +inline internal::ParamGenerator Bool() +{ + return Values(false, true); } -# if GTEST_HAS_COMBINE +#if GTEST_HAS_COMBINE // Combine() allows the user to combine two or more sequences to produce // values of a Cartesian product of those sequences' elements. // @@ -1272,147 +1366,165 @@ inline internal::ParamGenerator Bool() { // template internal::CartesianProductHolder2 Combine( - const Generator1& g1, const Generator2& g2) { - return internal::CartesianProductHolder2( - g1, g2); + const Generator1& g1, const Generator2& g2) +{ + return internal::CartesianProductHolder2( + g1, g2); } template internal::CartesianProductHolder3 Combine( - const Generator1& g1, const Generator2& g2, const Generator3& g3) { - return internal::CartesianProductHolder3( - g1, g2, g3); + const Generator1& g1, const Generator2& g2, const Generator3& g3) +{ + return internal::CartesianProductHolder3( + g1, g2, g3); } template + typename Generator4> internal::CartesianProductHolder4 Combine( - const Generator1& g1, const Generator2& g2, const Generator3& g3, - const Generator4& g4) { - return internal::CartesianProductHolder4( - g1, g2, g3, g4); + Generator4> +Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4) +{ + return internal::CartesianProductHolder4( + g1, g2, g3, g4); } template + typename Generator4, typename Generator5> internal::CartesianProductHolder5 Combine( - const Generator1& g1, const Generator2& g2, const Generator3& g3, - const Generator4& g4, const Generator5& g5) { - return internal::CartesianProductHolder5( - g1, g2, g3, g4, g5); + Generator4, Generator5> +Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5) +{ + return internal::CartesianProductHolder5( + g1, g2, g3, g4, g5); } template + typename Generator4, typename Generator5, typename Generator6> internal::CartesianProductHolder6 Combine( - const Generator1& g1, const Generator2& g2, const Generator3& g3, - const Generator4& g4, const Generator5& g5, const Generator6& g6) { - return internal::CartesianProductHolder6( - g1, g2, g3, g4, g5, g6); + Generator4, Generator5, Generator6> +Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6) +{ + return internal::CartesianProductHolder6( + g1, g2, g3, g4, g5, g6); } template + typename Generator4, typename Generator5, typename Generator6, + typename Generator7> internal::CartesianProductHolder7 Combine( - const Generator1& g1, const Generator2& g2, const Generator3& g3, - const Generator4& g4, const Generator5& g5, const Generator6& g6, - const Generator7& g7) { - return internal::CartesianProductHolder7( - g1, g2, g3, g4, g5, g6, g7); + Generator4, Generator5, Generator6, Generator7> +Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7) +{ + return internal::CartesianProductHolder7( + g1, g2, g3, g4, g5, g6, g7); } template + typename Generator4, typename Generator5, typename Generator6, + typename Generator7, typename Generator8> internal::CartesianProductHolder8 Combine( - const Generator1& g1, const Generator2& g2, const Generator3& g3, - const Generator4& g4, const Generator5& g5, const Generator6& g6, - const Generator7& g7, const Generator8& g8) { - return internal::CartesianProductHolder8( - g1, g2, g3, g4, g5, g6, g7, g8); + Generator4, Generator5, Generator6, Generator7, Generator8> +Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8) +{ + return internal::CartesianProductHolder8( + g1, g2, g3, g4, g5, g6, g7, g8); } template + typename Generator4, typename Generator5, typename Generator6, + typename Generator7, typename Generator8, typename Generator9> internal::CartesianProductHolder9 Combine( - const Generator1& g1, const Generator2& g2, const Generator3& g3, - const Generator4& g4, const Generator5& g5, const Generator6& g6, - const Generator7& g7, const Generator8& g8, const Generator9& g9) { - return internal::CartesianProductHolder9( - g1, g2, g3, g4, g5, g6, g7, g8, g9); + Generator4, Generator5, Generator6, Generator7, Generator8, + Generator9> +Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8, const Generator9& g9) +{ + return internal::CartesianProductHolder9( + g1, g2, g3, g4, g5, g6, g7, g8, g9); } template + typename Generator4, typename Generator5, typename Generator6, + typename Generator7, typename Generator8, typename Generator9, + typename Generator10> internal::CartesianProductHolder10 Combine( - const Generator1& g1, const Generator2& g2, const Generator3& g3, - const Generator4& g4, const Generator5& g5, const Generator6& g6, - const Generator7& g7, const Generator8& g8, const Generator9& g9, - const Generator10& g10) { - return internal::CartesianProductHolder10( - g1, g2, g3, g4, g5, g6, g7, g8, g9, g10); + Generator4, Generator5, Generator6, Generator7, Generator8, Generator9, + Generator10> +Combine( + const Generator1& g1, const Generator2& g2, const Generator3& g3, + const Generator4& g4, const Generator5& g5, const Generator6& g6, + const Generator7& g7, const Generator8& g8, const Generator9& g9, + const Generator10& g10) +{ + return internal::CartesianProductHolder10( + g1, g2, g3, g4, g5, g6, g7, g8, g9, g10); } -# endif // GTEST_HAS_COMBINE +#endif // GTEST_HAS_COMBINE +#define TEST_P(test_case_name, test_name) \ + class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + : public test_case_name \ + { \ + public: \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + () {} \ + virtual void TestBody(); \ + \ + private: \ + static int AddToRegistry() \ + { \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry().GetTestCasePatternHolder( \ + #test_case_name, __FILE__, __LINE__) \ + ->AddTestPattern( \ + #test_case_name, \ + #test_name, \ + new ::testing::internal::TestMetaFactory< \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ + return 0; \ + } \ + static int gtest_registering_dummy_; \ + GTEST_DISALLOW_COPY_AND_ASSIGN_( \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ + }; \ + int GTEST_TEST_CLASS_NAME_(test_case_name, \ + test_name)::gtest_registering_dummy_ = \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ + void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() - -# define TEST_P(test_case_name, test_name) \ - class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ - : public test_case_name { \ - public: \ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {} \ - virtual void TestBody(); \ - private: \ - static int AddToRegistry() { \ - ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ - GetTestCasePatternHolder(\ - #test_case_name, __FILE__, __LINE__)->AddTestPattern(\ - #test_case_name, \ - #test_name, \ - new ::testing::internal::TestMetaFactory< \ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>()); \ - return 0; \ - } \ - static int gtest_registering_dummy_; \ - GTEST_DISALLOW_COPY_AND_ASSIGN_(\ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ - }; \ - int GTEST_TEST_CLASS_NAME_(test_case_name, \ - test_name)::gtest_registering_dummy_ = \ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::AddToRegistry(); \ - void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() - -# define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ - ::testing::internal::ParamGenerator \ - gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ - int gtest_##prefix##test_case_name##_dummy_ = \ - ::testing::UnitTest::GetInstance()->parameterized_test_registry(). \ - GetTestCasePatternHolder(\ - #test_case_name, __FILE__, __LINE__)->AddTestCaseInstantiation(\ - #prefix, \ - >est_##prefix##test_case_name##_EvalGenerator_, \ - __FILE__, __LINE__) +#define INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \ + ::testing::internal::ParamGenerator \ + gtest_##prefix##test_case_name##_EvalGenerator_() { return generator; } \ + int gtest_##prefix##test_case_name##_dummy_ = \ + ::testing::UnitTest::GetInstance()->parameterized_test_registry().GetTestCasePatternHolder( \ + #test_case_name, __FILE__, __LINE__) \ + ->AddTestCaseInstantiation( \ + #prefix, \ + >est_##prefix##test_case_name##_EvalGenerator_, \ + __FILE__, __LINE__) } // namespace testing diff --git a/test/gtest-1.7.0/include/gtest/gtest-printers.h b/test/gtest-1.7.0/include/gtest/gtest-printers.h index 0639d9f58..008921f36 100644 --- a/test/gtest-1.7.0/include/gtest/gtest-printers.h +++ b/test/gtest-1.7.0/include/gtest/gtest-printers.h @@ -103,25 +103,26 @@ #include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-internal.h" -namespace testing { - +namespace testing +{ // Definitions in the 'internal' and 'internal2' name spaces are // subject to change without notice. DO NOT USE THEM IN USER CODE! -namespace internal2 { - +namespace internal2 +{ // Prints the given number of bytes in the given object to the given // ostream. GTEST_API_ void PrintBytesInObjectTo(const unsigned char* obj_bytes, - size_t count, - ::std::ostream* os); + size_t count, + ::std::ostream* os); // For selecting which printer to use when a given type has neither << // nor PrintTo(). -enum TypeKind { - kProtobuf, // a protobuf type - kConvertibleToInteger, // a type implicitly convertible to BiggestInt - // (e.g. a named or unnamed enum type) - kOtherType // anything else +enum TypeKind +{ + kProtobuf, // a protobuf type + kConvertibleToInteger, // a type implicitly convertible to BiggestInt + // (e.g. a named or unnamed enum type) + kOtherType // anything else }; // TypeWithoutFormatter::PrintValue(value, os) is called @@ -129,13 +130,15 @@ enum TypeKind { // operator<< nor PrintTo() is defined for T, where kTypeKind is the // "kind" of T as defined by enum TypeKind. template -class TypeWithoutFormatter { - public: - // This default version is called when kTypeKind is kOtherType. - static void PrintValue(const T& value, ::std::ostream* os) { - PrintBytesInObjectTo(reinterpret_cast(&value), - sizeof(value), os); - } +class TypeWithoutFormatter +{ +public: + // This default version is called when kTypeKind is kOtherType. + static void PrintValue(const T& value, ::std::ostream* os) + { + PrintBytesInObjectTo(reinterpret_cast(&value), + sizeof(value), os); + } }; // We print a protobuf using its ShortDebugString() when the string @@ -144,31 +147,34 @@ class TypeWithoutFormatter { const size_t kProtobufOneLinerMaxLength = 50; template -class TypeWithoutFormatter { - public: - static void PrintValue(const T& value, ::std::ostream* os) { - const ::testing::internal::string short_str = value.ShortDebugString(); - const ::testing::internal::string pretty_str = - short_str.length() <= kProtobufOneLinerMaxLength ? - short_str : ("\n" + value.DebugString()); - *os << ("<" + pretty_str + ">"); - } +class TypeWithoutFormatter +{ +public: + static void PrintValue(const T& value, ::std::ostream* os) + { + const ::testing::internal::string short_str = value.ShortDebugString(); + const ::testing::internal::string pretty_str = + short_str.length() <= kProtobufOneLinerMaxLength ? short_str : ("\n" + value.DebugString()); + *os << ("<" + pretty_str + ">"); + } }; template -class TypeWithoutFormatter { - public: - // Since T has no << operator or PrintTo() but can be implicitly - // converted to BiggestInt, we print it as a BiggestInt. - // - // Most likely T is an enum type (either named or unnamed), in which - // case printing it as an integer is the desired behavior. In case - // T is not an enum, printing it as an integer is the best we can do - // given that it has no user-defined printer. - static void PrintValue(const T& value, ::std::ostream* os) { - const internal::BiggestInt kBigInt = value; - *os << kBigInt; - } +class TypeWithoutFormatter +{ +public: + // Since T has no << operator or PrintTo() but can be implicitly + // converted to BiggestInt, we print it as a BiggestInt. + // + // Most likely T is an enum type (either named or unnamed), in which + // case printing it as an integer is the desired behavior. In case + // T is not an enum, printing it as an integer is the best we can do + // given that it has no user-defined printer. + static void PrintValue(const T& value, ::std::ostream* os) + { + const internal::BiggestInt kBigInt = value; + *os << kBigInt; + } }; // Prints the given value to the given ostream. If the value is a @@ -197,12 +203,11 @@ class TypeWithoutFormatter { // specific. template ::std::basic_ostream& operator<<( - ::std::basic_ostream& os, const T& x) { - TypeWithoutFormatter::value ? kProtobuf : - internal::ImplicitlyConvertible::value ? - kConvertibleToInteger : kOtherType)>::PrintValue(x, &os); - return os; + ::std::basic_ostream& os, const T& x) +{ + TypeWithoutFormatter::value ? kProtobuf : internal::ImplicitlyConvertible::value ? kConvertibleToInteger : kOtherType)>::PrintValue(x, &os); + return os; } } // namespace internal2 @@ -210,46 +215,48 @@ template // This namespace MUST NOT BE NESTED IN ::testing, or the name look-up // magic needed for implementing UniversalPrinter won't work. -namespace testing_internal { - +namespace testing_internal +{ // Used to print a value that is not an STL-style container when the // user doesn't define PrintTo() for it. template -void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) { - // With the following statement, during unqualified name lookup, - // testing::internal2::operator<< appears as if it was declared in - // the nearest enclosing namespace that contains both - // ::testing_internal and ::testing::internal2, i.e. the global - // namespace. For more details, refer to the C++ Standard section - // 7.3.4-1 [namespace.udir]. This allows us to fall back onto - // testing::internal2::operator<< in case T doesn't come with a << - // operator. - // - // We cannot write 'using ::testing::internal2::operator<<;', which - // gcc 3.3 fails to compile due to a compiler bug. - using namespace ::testing::internal2; // NOLINT +void DefaultPrintNonContainerTo(const T& value, ::std::ostream* os) +{ + // With the following statement, during unqualified name lookup, + // testing::internal2::operator<< appears as if it was declared in + // the nearest enclosing namespace that contains both + // ::testing_internal and ::testing::internal2, i.e. the global + // namespace. For more details, refer to the C++ Standard section + // 7.3.4-1 [namespace.udir]. This allows us to fall back onto + // testing::internal2::operator<< in case T doesn't come with a << + // operator. + // + // We cannot write 'using ::testing::internal2::operator<<;', which + // gcc 3.3 fails to compile due to a compiler bug. + using namespace ::testing::internal2; // NOLINT - // Assuming T is defined in namespace foo, in the next statement, - // the compiler will consider all of: - // - // 1. foo::operator<< (thanks to Koenig look-up), - // 2. ::operator<< (as the current namespace is enclosed in ::), - // 3. testing::internal2::operator<< (thanks to the using statement above). - // - // The operator<< whose type matches T best will be picked. - // - // We deliberately allow #2 to be a candidate, as sometimes it's - // impossible to define #1 (e.g. when foo is ::std, defining - // anything in it is undefined behavior unless you are a compiler - // vendor.). - *os << value; + // Assuming T is defined in namespace foo, in the next statement, + // the compiler will consider all of: + // + // 1. foo::operator<< (thanks to Koenig look-up), + // 2. ::operator<< (as the current namespace is enclosed in ::), + // 3. testing::internal2::operator<< (thanks to the using statement above). + // + // The operator<< whose type matches T best will be picked. + // + // We deliberately allow #2 to be a candidate, as sometimes it's + // impossible to define #1 (e.g. when foo is ::std, defining + // anything in it is undefined behavior unless you are a compiler + // vendor.). + *os << value; } } // namespace testing_internal -namespace testing { -namespace internal { - +namespace testing +{ +namespace internal +{ // UniversalPrinter::Print(value, ostream_ptr) prints the given // value to the given ostream. The caller must ensure that // 'ostream_ptr' is not NULL, or the behavior is undefined. @@ -267,30 +274,35 @@ void UniversalPrint(const T& value, ::std::ostream* os); // a PrintTo() for it. template void DefaultPrintTo(IsContainer /* dummy */, - false_type /* is not a pointer */, - const C& container, ::std::ostream* os) { - const size_t kMaxCount = 32; // The maximum number of elements to print. - *os << '{'; - size_t count = 0; - for (typename C::const_iterator it = container.begin(); - it != container.end(); ++it, ++count) { - if (count > 0) { - *os << ','; - if (count == kMaxCount) { // Enough has been printed. - *os << " ..."; - break; - } - } - *os << ' '; - // We cannot call PrintTo(*it, os) here as PrintTo() doesn't - // handle *it being a native array. - internal::UniversalPrint(*it, os); - } + false_type /* is not a pointer */, + const C& container, ::std::ostream* os) +{ + const size_t kMaxCount = 32; // The maximum number of elements to print. + *os << '{'; + size_t count = 0; + for (typename C::const_iterator it = container.begin(); + it != container.end(); ++it, ++count) + { + if (count > 0) + { + *os << ','; + if (count == kMaxCount) + { // Enough has been printed. + *os << " ..."; + break; + } + } + *os << ' '; + // We cannot call PrintTo(*it, os) here as PrintTo() doesn't + // handle *it being a native array. + internal::UniversalPrint(*it, os); + } - if (count > 0) { - *os << ' '; - } - *os << '}'; + if (count > 0) + { + *os << ' '; + } + *os << '}'; } // Used to print a pointer that is neither a char pointer nor a member @@ -301,41 +313,49 @@ void DefaultPrintTo(IsContainer /* dummy */, // bytes.) template void DefaultPrintTo(IsNotContainer /* dummy */, - true_type /* is a pointer */, - T* p, ::std::ostream* os) { - if (p == NULL) { - *os << "NULL"; - } else { - // C++ doesn't allow casting from a function pointer to any object - // pointer. - // - // IsTrue() silences warnings: "Condition is always true", - // "unreachable code". - if (IsTrue(ImplicitlyConvertible::value)) { - // T is not a function type. We just call << to print p, - // relying on ADL to pick up user-defined << for their pointer - // types, if any. - *os << p; - } else { - // T is a function type, so '*os << p' doesn't do what we want - // (it just prints p as bool). We want to print p as a const - // void*. However, we cannot cast it to const void* directly, - // even using reinterpret_cast, as earlier versions of gcc - // (e.g. 3.4.5) cannot compile the cast when p is a function - // pointer. Casting to UInt64 first solves the problem. - *os << reinterpret_cast( - reinterpret_cast(p)); - } - } + true_type /* is a pointer */, + T* p, ::std::ostream* os) +{ + if (p == NULL) + { + *os << "NULL"; + } + else + { + // C++ doesn't allow casting from a function pointer to any object + // pointer. + // + // IsTrue() silences warnings: "Condition is always true", + // "unreachable code". + if (IsTrue(ImplicitlyConvertible::value)) + { + // T is not a function type. We just call << to print p, + // relying on ADL to pick up user-defined << for their pointer + // types, if any. + *os << p; + } + else + { + // T is a function type, so '*os << p' doesn't do what we want + // (it just prints p as bool). We want to print p as a const + // void*. However, we cannot cast it to const void* directly, + // even using reinterpret_cast, as earlier versions of gcc + // (e.g. 3.4.5) cannot compile the cast when p is a function + // pointer. Casting to UInt64 first solves the problem. + *os << reinterpret_cast( + reinterpret_cast(p)); + } + } } // Used to print a non-container, non-pointer value when the user // doesn't define PrintTo() for it. template void DefaultPrintTo(IsNotContainer /* dummy */, - false_type /* is not a pointer */, - const T& value, ::std::ostream* os) { - ::testing_internal::DefaultPrintNonContainerTo(value, os); + false_type /* is not a pointer */, + const T& value, ::std::ostream* os) +{ + ::testing_internal::DefaultPrintNonContainerTo(value, os); } // Prints the given value using the << operator if it has one; @@ -350,30 +370,31 @@ void DefaultPrintTo(IsNotContainer /* dummy */, // or there is already a << operator but it doesn't do what the user // wants). template -void PrintTo(const T& value, ::std::ostream* os) { - // DefaultPrintTo() is overloaded. The type of its first two - // arguments determine which version will be picked. If T is an - // STL-style container, the version for container will be called; if - // T is a pointer, the pointer version will be called; otherwise the - // generic version will be called. - // - // Note that we check for container types here, prior to we check - // for protocol message types in our operator<<. The rationale is: - // - // For protocol messages, we want to give people a chance to - // override Google Mock's format by defining a PrintTo() or - // operator<<. For STL containers, other formats can be - // incompatible with Google Mock's format for the container - // elements; therefore we check for container types here to ensure - // that our format is used. - // - // The second argument of DefaultPrintTo() is needed to bypass a bug - // in Symbian's C++ compiler that prevents it from picking the right - // overload between: - // - // PrintTo(const T& x, ...); - // PrintTo(T* x, ...); - DefaultPrintTo(IsContainerTest(0), is_pointer(), value, os); +void PrintTo(const T& value, ::std::ostream* os) +{ + // DefaultPrintTo() is overloaded. The type of its first two + // arguments determine which version will be picked. If T is an + // STL-style container, the version for container will be called; if + // T is a pointer, the pointer version will be called; otherwise the + // generic version will be called. + // + // Note that we check for container types here, prior to we check + // for protocol message types in our operator<<. The rationale is: + // + // For protocol messages, we want to give people a chance to + // override Google Mock's format by defining a PrintTo() or + // operator<<. For STL containers, other formats can be + // incompatible with Google Mock's format for the container + // elements; therefore we check for container types here to ensure + // that our format is used. + // + // The second argument of DefaultPrintTo() is needed to bypass a bug + // in Symbian's C++ compiler that prevents it from picking the right + // overload between: + // + // PrintTo(const T& x, ...); + // PrintTo(T* x, ...); + DefaultPrintTo(IsContainerTest(0), is_pointer(), value, os); } // The following list of PrintTo() overloads tells @@ -383,16 +404,18 @@ void PrintTo(const T& value, ::std::ostream* os) { // Overloads for various char types. GTEST_API_ void PrintTo(unsigned char c, ::std::ostream* os); GTEST_API_ void PrintTo(signed char c, ::std::ostream* os); -inline void PrintTo(char c, ::std::ostream* os) { - // When printing a plain char, we always treat it as unsigned. This - // way, the output won't be affected by whether the compiler thinks - // char is signed or not. - PrintTo(static_cast(c), os); +inline void PrintTo(char c, ::std::ostream* os) +{ + // When printing a plain char, we always treat it as unsigned. This + // way, the output won't be affected by whether the compiler thinks + // char is signed or not. + PrintTo(static_cast(c), os); } // Overloads for other simple built-in types. -inline void PrintTo(bool x, ::std::ostream* os) { - *os << (x ? "true" : "false"); +inline void PrintTo(bool x, ::std::ostream* os) +{ + *os << (x ? "true" : "false"); } // Overload for wchar_t type. @@ -406,23 +429,28 @@ GTEST_API_ void PrintTo(wchar_t wc, ::std::ostream* os); // Overloads for C strings. GTEST_API_ void PrintTo(const char* s, ::std::ostream* os); -inline void PrintTo(char* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); +inline void PrintTo(char* s, ::std::ostream* os) +{ + PrintTo(ImplicitCast_(s), os); } // signed/unsigned char is often used for representing binary data, so // we print pointers to it as void* to be safe. -inline void PrintTo(const signed char* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); +inline void PrintTo(const signed char* s, ::std::ostream* os) +{ + PrintTo(ImplicitCast_(s), os); } -inline void PrintTo(signed char* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); +inline void PrintTo(signed char* s, ::std::ostream* os) +{ + PrintTo(ImplicitCast_(s), os); } -inline void PrintTo(const unsigned char* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); +inline void PrintTo(const unsigned char* s, ::std::ostream* os) +{ + PrintTo(ImplicitCast_(s), os); } -inline void PrintTo(unsigned char* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); +inline void PrintTo(unsigned char* s, ::std::ostream* os) +{ + PrintTo(ImplicitCast_(s), os); } // MSVC can be configured to define wchar_t as a typedef of unsigned @@ -433,8 +461,9 @@ inline void PrintTo(unsigned char* s, ::std::ostream* os) { #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) // Overloads for wide C strings GTEST_API_ void PrintTo(const wchar_t* s, ::std::ostream* os); -inline void PrintTo(wchar_t* s, ::std::ostream* os) { - PrintTo(ImplicitCast_(s), os); +inline void PrintTo(wchar_t* s, ::std::ostream* os) +{ + PrintTo(ImplicitCast_(s), os); } #endif @@ -444,39 +473,45 @@ inline void PrintTo(wchar_t* s, ::std::ostream* os) { // Prints the given number of elements in an array, without printing // the curly braces. template -void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) { - UniversalPrint(a[0], os); - for (size_t i = 1; i != count; i++) { - *os << ", "; - UniversalPrint(a[i], os); - } +void PrintRawArrayTo(const T a[], size_t count, ::std::ostream* os) +{ + UniversalPrint(a[0], os); + for (size_t i = 1; i != count; i++) + { + *os << ", "; + UniversalPrint(a[i], os); + } } // Overloads for ::string and ::std::string. #if GTEST_HAS_GLOBAL_STRING -GTEST_API_ void PrintStringTo(const ::string&s, ::std::ostream* os); -inline void PrintTo(const ::string& s, ::std::ostream* os) { - PrintStringTo(s, os); +GTEST_API_ void PrintStringTo(const ::string& s, ::std::ostream* os); +inline void PrintTo(const ::string& s, ::std::ostream* os) +{ + PrintStringTo(s, os); } #endif // GTEST_HAS_GLOBAL_STRING -GTEST_API_ void PrintStringTo(const ::std::string&s, ::std::ostream* os); -inline void PrintTo(const ::std::string& s, ::std::ostream* os) { - PrintStringTo(s, os); +GTEST_API_ void PrintStringTo(const ::std::string& s, ::std::ostream* os); +inline void PrintTo(const ::std::string& s, ::std::ostream* os) +{ + PrintStringTo(s, os); } // Overloads for ::wstring and ::std::wstring. #if GTEST_HAS_GLOBAL_WSTRING -GTEST_API_ void PrintWideStringTo(const ::wstring&s, ::std::ostream* os); -inline void PrintTo(const ::wstring& s, ::std::ostream* os) { - PrintWideStringTo(s, os); +GTEST_API_ void PrintWideStringTo(const ::wstring& s, ::std::ostream* os); +inline void PrintTo(const ::wstring& s, ::std::ostream* os) +{ + PrintWideStringTo(s, os); } #endif // GTEST_HAS_GLOBAL_WSTRING #if GTEST_HAS_STD_WSTRING -GTEST_API_ void PrintWideStringTo(const ::std::wstring&s, ::std::ostream* os); -inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) { - PrintWideStringTo(s, os); +GTEST_API_ void PrintWideStringTo(const ::std::wstring& s, ::std::ostream* os); +inline void PrintTo(const ::std::wstring& s, ::std::ostream* os) +{ + PrintWideStringTo(s, os); } #endif // GTEST_HAS_STD_WSTRING @@ -494,183 +529,208 @@ void PrintTupleTo(const T& t, ::std::ostream* os); // regardless of whether tr1::tuple is implemented using the // non-standard variadic template feature or not. -inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) { - PrintTupleTo(t, os); +inline void PrintTo(const ::std::tr1::tuple<>& t, ::std::ostream* os) +{ + PrintTupleTo(t, os); } template -void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { - PrintTupleTo(t, os); +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) +{ + PrintTupleTo(t, os); } template -void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { - PrintTupleTo(t, os); +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) +{ + PrintTupleTo(t, os); } template -void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { - PrintTupleTo(t, os); +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) +{ + PrintTupleTo(t, os); } template -void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) { - PrintTupleTo(t, os); +void PrintTo(const ::std::tr1::tuple& t, ::std::ostream* os) +{ + PrintTupleTo(t, os); } template void PrintTo(const ::std::tr1::tuple& t, - ::std::ostream* os) { - PrintTupleTo(t, os); + ::std::ostream* os) +{ + PrintTupleTo(t, os); } template + typename T6> void PrintTo(const ::std::tr1::tuple& t, - ::std::ostream* os) { - PrintTupleTo(t, os); + ::std::ostream* os) +{ + PrintTupleTo(t, os); } template + typename T6, typename T7> void PrintTo(const ::std::tr1::tuple& t, - ::std::ostream* os) { - PrintTupleTo(t, os); + ::std::ostream* os) +{ + PrintTupleTo(t, os); } template + typename T6, typename T7, typename T8> void PrintTo(const ::std::tr1::tuple& t, - ::std::ostream* os) { - PrintTupleTo(t, os); + ::std::ostream* os) +{ + PrintTupleTo(t, os); } template + typename T6, typename T7, typename T8, typename T9> void PrintTo(const ::std::tr1::tuple& t, - ::std::ostream* os) { - PrintTupleTo(t, os); + ::std::ostream* os) +{ + PrintTupleTo(t, os); } template + typename T6, typename T7, typename T8, typename T9, typename T10> void PrintTo( - const ::std::tr1::tuple& t, - ::std::ostream* os) { - PrintTupleTo(t, os); + const ::std::tr1::tuple& t, + ::std::ostream* os) +{ + PrintTupleTo(t, os); } #endif // GTEST_HAS_TR1_TUPLE // Overload for std::pair. template -void PrintTo(const ::std::pair& value, ::std::ostream* os) { - *os << '('; - // We cannot use UniversalPrint(value.first, os) here, as T1 may be - // a reference type. The same for printing value.second. - UniversalPrinter::Print(value.first, os); - *os << ", "; - UniversalPrinter::Print(value.second, os); - *os << ')'; +void PrintTo(const ::std::pair& value, ::std::ostream* os) +{ + *os << '('; + // We cannot use UniversalPrint(value.first, os) here, as T1 may be + // a reference type. The same for printing value.second. + UniversalPrinter::Print(value.first, os); + *os << ", "; + UniversalPrinter::Print(value.second, os); + *os << ')'; } // Implements printing a non-reference type T by letting the compiler // pick the right overload of PrintTo() for T. template -class UniversalPrinter { - public: - // MSVC warns about adding const to a function type, so we want to - // disable the warning. +class UniversalPrinter +{ +public: + // MSVC warns about adding const to a function type, so we want to + // disable the warning. #ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4180) // Temporarily disables warning 4180. -#endif // _MSC_VER +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable : 4180) // Temporarily disables warning 4180. +#endif // _MSC_VER - // Note: we deliberately don't call this PrintTo(), as that name - // conflicts with ::testing::internal::PrintTo in the body of the - // function. - static void Print(const T& value, ::std::ostream* os) { - // By default, ::testing::internal::PrintTo() is used for printing - // the value. - // - // Thanks to Koenig look-up, if T is a class and has its own - // PrintTo() function defined in its namespace, that function will - // be visible here. Since it is more specific than the generic ones - // in ::testing::internal, it will be picked by the compiler in the - // following statement - exactly what we want. - PrintTo(value, os); - } + // Note: we deliberately don't call this PrintTo(), as that name + // conflicts with ::testing::internal::PrintTo in the body of the + // function. + static void Print(const T& value, ::std::ostream* os) + { + // By default, ::testing::internal::PrintTo() is used for printing + // the value. + // + // Thanks to Koenig look-up, if T is a class and has its own + // PrintTo() function defined in its namespace, that function will + // be visible here. Since it is more specific than the generic ones + // in ::testing::internal, it will be picked by the compiler in the + // following statement - exactly what we want. + PrintTo(value, os); + } #ifdef _MSC_VER -# pragma warning(pop) // Restores the warning state. -#endif // _MSC_VER +#pragma warning(pop) // Restores the warning state. +#endif // _MSC_VER }; // UniversalPrintArray(begin, len, os) prints an array of 'len' // elements, starting at address 'begin'. template -void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) { - if (len == 0) { - *os << "{}"; - } else { - *os << "{ "; - const size_t kThreshold = 18; - const size_t kChunkSize = 8; - // If the array has more than kThreshold elements, we'll have to - // omit some details by printing only the first and the last - // kChunkSize elements. - // TODO(wan@google.com): let the user control the threshold using a flag. - if (len <= kThreshold) { - PrintRawArrayTo(begin, len, os); - } else { - PrintRawArrayTo(begin, kChunkSize, os); - *os << ", ..., "; - PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os); - } - *os << " }"; - } +void UniversalPrintArray(const T* begin, size_t len, ::std::ostream* os) +{ + if (len == 0) + { + *os << "{}"; + } + else + { + *os << "{ "; + const size_t kThreshold = 18; + const size_t kChunkSize = 8; + // If the array has more than kThreshold elements, we'll have to + // omit some details by printing only the first and the last + // kChunkSize elements. + // TODO(wan@google.com): let the user control the threshold using a flag. + if (len <= kThreshold) + { + PrintRawArrayTo(begin, len, os); + } + else + { + PrintRawArrayTo(begin, kChunkSize, os); + *os << ", ..., "; + PrintRawArrayTo(begin + len - kChunkSize, kChunkSize, os); + } + *os << " }"; + } } // This overload prints a (const) char array compactly. GTEST_API_ void UniversalPrintArray( - const char* begin, size_t len, ::std::ostream* os); + const char* begin, size_t len, ::std::ostream* os); // This overload prints a (const) wchar_t array compactly. GTEST_API_ void UniversalPrintArray( - const wchar_t* begin, size_t len, ::std::ostream* os); + const wchar_t* begin, size_t len, ::std::ostream* os); // Implements printing an array type T[N]. template -class UniversalPrinter { - public: - // Prints the given array, omitting some elements when there are too - // many. - static void Print(const T (&a)[N], ::std::ostream* os) { - UniversalPrintArray(a, N, os); - } +class UniversalPrinter +{ +public: + // Prints the given array, omitting some elements when there are too + // many. + static void Print(const T (&a)[N], ::std::ostream* os) + { + UniversalPrintArray(a, N, os); + } }; // Implements printing a reference type T&. template -class UniversalPrinter { - public: - // MSVC warns about adding const to a function type, so we want to - // disable the warning. +class UniversalPrinter +{ +public: + // MSVC warns about adding const to a function type, so we want to + // disable the warning. #ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4180) // Temporarily disables warning 4180. -#endif // _MSC_VER +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable : 4180) // Temporarily disables warning 4180. +#endif // _MSC_VER - static void Print(const T& value, ::std::ostream* os) { - // Prints the address of the value. We use reinterpret_cast here - // as static_cast doesn't compile when T is a function type. - *os << "@" << reinterpret_cast(&value) << " "; + static void Print(const T& value, ::std::ostream* os) + { + // Prints the address of the value. We use reinterpret_cast here + // as static_cast doesn't compile when T is a function type. + *os << "@" << reinterpret_cast(&value) << " "; - // Then prints the value itself. - UniversalPrint(value, os); - } + // Then prints the value itself. + UniversalPrint(value, os); + } #ifdef _MSC_VER -# pragma warning(pop) // Restores the warning state. -#endif // _MSC_VER +#pragma warning(pop) // Restores the warning state. +#endif // _MSC_VER }; // Prints a value tersely: for a reference type, the referenced value @@ -678,70 +738,91 @@ class UniversalPrinter { // NUL-terminated string (but not the pointer) is printed. template -class UniversalTersePrinter { - public: - static void Print(const T& value, ::std::ostream* os) { - UniversalPrint(value, os); - } +class UniversalTersePrinter +{ +public: + static void Print(const T& value, ::std::ostream* os) + { + UniversalPrint(value, os); + } }; template -class UniversalTersePrinter { - public: - static void Print(const T& value, ::std::ostream* os) { - UniversalPrint(value, os); - } +class UniversalTersePrinter +{ +public: + static void Print(const T& value, ::std::ostream* os) + { + UniversalPrint(value, os); + } }; template -class UniversalTersePrinter { - public: - static void Print(const T (&value)[N], ::std::ostream* os) { - UniversalPrinter::Print(value, os); - } +class UniversalTersePrinter +{ +public: + static void Print(const T (&value)[N], ::std::ostream* os) + { + UniversalPrinter::Print(value, os); + } }; template <> -class UniversalTersePrinter { - public: - static void Print(const char* str, ::std::ostream* os) { - if (str == NULL) { - *os << "NULL"; - } else { - UniversalPrint(string(str), os); - } - } +class UniversalTersePrinter +{ +public: + static void Print(const char* str, ::std::ostream* os) + { + if (str == NULL) + { + *os << "NULL"; + } + else + { + UniversalPrint(string(str), os); + } + } }; template <> -class UniversalTersePrinter { - public: - static void Print(char* str, ::std::ostream* os) { - UniversalTersePrinter::Print(str, os); - } +class UniversalTersePrinter +{ +public: + static void Print(char* str, ::std::ostream* os) + { + UniversalTersePrinter::Print(str, os); + } }; #if GTEST_HAS_STD_WSTRING template <> -class UniversalTersePrinter { - public: - static void Print(const wchar_t* str, ::std::ostream* os) { - if (str == NULL) { - *os << "NULL"; - } else { - UniversalPrint(::std::wstring(str), os); - } - } +class UniversalTersePrinter +{ +public: + static void Print(const wchar_t* str, ::std::ostream* os) + { + if (str == NULL) + { + *os << "NULL"; + } + else + { + UniversalPrint(::std::wstring(str), os); + } + } }; #endif template <> -class UniversalTersePrinter { - public: - static void Print(wchar_t* str, ::std::ostream* os) { - UniversalTersePrinter::Print(str, os); - } +class UniversalTersePrinter +{ +public: + static void Print(wchar_t* str, ::std::ostream* os) + { + UniversalTersePrinter::Print(str, os); + } }; template -void UniversalTersePrint(const T& value, ::std::ostream* os) { - UniversalTersePrinter::Print(value, os); +void UniversalTersePrint(const T& value, ::std::ostream* os) +{ + UniversalTersePrinter::Print(value, os); } // Prints a value using the type inferred by the compiler. The @@ -749,11 +830,12 @@ void UniversalTersePrint(const T& value, ::std::ostream* os) { // (const) char pointer, this prints both the pointer and the // NUL-terminated string. template -void UniversalPrint(const T& value, ::std::ostream* os) { - // A workarond for the bug in VC++ 7.1 that prevents us from instantiating - // UniversalPrinter with T directly. - typedef T T1; - UniversalPrinter::Print(value, os); +void UniversalPrint(const T& value, ::std::ostream* os) +{ + // A workarond for the bug in VC++ 7.1 that prevents us from instantiating + // UniversalPrinter with T directly. + typedef T T1; + UniversalPrinter::Print(value, os); } #if GTEST_HAS_TR1_TUPLE @@ -768,35 +850,42 @@ typedef ::std::vector Strings; // The inductive case. template -struct TuplePrefixPrinter { - // Prints the first N fields of a tuple. - template - static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { - TuplePrefixPrinter::PrintPrefixTo(t, os); - *os << ", "; - UniversalPrinter::type> - ::Print(::std::tr1::get(t), os); - } +struct TuplePrefixPrinter +{ + // Prints the first N fields of a tuple. + template + static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) + { + TuplePrefixPrinter::PrintPrefixTo(t, os); + *os << ", "; + UniversalPrinter::type>::Print(::std::tr1::get(t), os); + } - // Tersely prints the first N fields of a tuple to a string vector, - // one element for each field. - template - static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { - TuplePrefixPrinter::TersePrintPrefixToStrings(t, strings); - ::std::stringstream ss; - UniversalTersePrint(::std::tr1::get(t), &ss); - strings->push_back(ss.str()); - } + // Tersely prints the first N fields of a tuple to a string vector, + // one element for each field. + template + static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) + { + TuplePrefixPrinter::TersePrintPrefixToStrings(t, strings); + ::std::stringstream ss; + UniversalTersePrint(::std::tr1::get(t), &ss); + strings->push_back(ss.str()); + } }; // Base cases. template <> -struct TuplePrefixPrinter<0> { - template - static void PrintPrefixTo(const Tuple&, ::std::ostream*) {} +struct TuplePrefixPrinter<0> +{ + template + static void PrintPrefixTo(const Tuple&, ::std::ostream*) + { + } - template - static void TersePrintPrefixToStrings(const Tuple&, Strings*) {} + template + static void TersePrintPrefixToStrings(const Tuple&, Strings*) + { + } }; // We have to specialize the entire TuplePrefixPrinter<> class // template here, even though the definition of @@ -804,50 +893,56 @@ struct TuplePrefixPrinter<0> { // Embarcadero (formerly CodeGear, formerly Borland) C++ doesn't // support specializing a method template of a class template. template <> -struct TuplePrefixPrinter<1> { - template - static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) { - UniversalPrinter::type>:: - Print(::std::tr1::get<0>(t), os); - } +struct TuplePrefixPrinter<1> +{ + template + static void PrintPrefixTo(const Tuple& t, ::std::ostream* os) + { + UniversalPrinter::type>:: + Print(::std::tr1::get<0>(t), os); + } - template - static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) { - ::std::stringstream ss; - UniversalTersePrint(::std::tr1::get<0>(t), &ss); - strings->push_back(ss.str()); - } + template + static void TersePrintPrefixToStrings(const Tuple& t, Strings* strings) + { + ::std::stringstream ss; + UniversalTersePrint(::std::tr1::get<0>(t), &ss); + strings->push_back(ss.str()); + } }; // Helper function for printing a tuple. T must be instantiated with // a tuple type. template -void PrintTupleTo(const T& t, ::std::ostream* os) { - *os << "("; - TuplePrefixPrinter< ::std::tr1::tuple_size::value>:: - PrintPrefixTo(t, os); - *os << ")"; +void PrintTupleTo(const T& t, ::std::ostream* os) +{ + *os << "("; + TuplePrefixPrinter< ::std::tr1::tuple_size::value>:: + PrintPrefixTo(t, os); + *os << ")"; } // Prints the fields of a tuple tersely to a string vector, one // element for each field. See the comment before // UniversalTersePrint() for how we define "tersely". template -Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) { - Strings result; - TuplePrefixPrinter< ::std::tr1::tuple_size::value>:: - TersePrintPrefixToStrings(value, &result); - return result; +Strings UniversalTersePrintTupleFieldsToStrings(const Tuple& value) +{ + Strings result; + TuplePrefixPrinter< ::std::tr1::tuple_size::value>:: + TersePrintPrefixToStrings(value, &result); + return result; } #endif // GTEST_HAS_TR1_TUPLE } // namespace internal template -::std::string PrintToString(const T& value) { - ::std::stringstream ss; - internal::UniversalTersePrinter::Print(value, &ss); - return ss.str(); +::std::string PrintToString(const T& value) +{ + ::std::stringstream ss; + internal::UniversalTersePrinter::Print(value, &ss); + return ss.str(); } } // namespace testing diff --git a/test/gtest-1.7.0/include/gtest/gtest-spi.h b/test/gtest-1.7.0/include/gtest/gtest-spi.h index f63fa9a1b..d0ca19e0b 100644 --- a/test/gtest-1.7.0/include/gtest/gtest-spi.h +++ b/test/gtest-1.7.0/include/gtest/gtest-spi.h @@ -37,8 +37,8 @@ #include "gtest/gtest.h" -namespace testing { - +namespace testing +{ // This helper class can be used to mock out Google Test failure reporting // so that we can test Google Test or code that builds on Google Test. // @@ -49,63 +49,68 @@ namespace testing { // all generated failures. The scope of this mock object can be controlled with // the second argument to the two arguments constructor. class GTEST_API_ ScopedFakeTestPartResultReporter - : public TestPartResultReporterInterface { - public: - // The two possible mocking modes of this object. - enum InterceptMode { - INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. - INTERCEPT_ALL_THREADS // Intercepts all failures. - }; + : public TestPartResultReporterInterface +{ +public: + // The two possible mocking modes of this object. + enum InterceptMode + { + INTERCEPT_ONLY_CURRENT_THREAD, // Intercepts only thread local failures. + INTERCEPT_ALL_THREADS // Intercepts all failures. + }; - // The c'tor sets this object as the test part result reporter used - // by Google Test. The 'result' parameter specifies where to report the - // results. This reporter will only catch failures generated in the current - // thread. DEPRECATED - explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); + // The c'tor sets this object as the test part result reporter used + // by Google Test. The 'result' parameter specifies where to report the + // results. This reporter will only catch failures generated in the current + // thread. DEPRECATED + explicit ScopedFakeTestPartResultReporter(TestPartResultArray* result); - // Same as above, but you can choose the interception scope of this object. - ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, - TestPartResultArray* result); + // Same as above, but you can choose the interception scope of this object. + ScopedFakeTestPartResultReporter(InterceptMode intercept_mode, + TestPartResultArray* result); - // The d'tor restores the previous test part result reporter. - virtual ~ScopedFakeTestPartResultReporter(); + // The d'tor restores the previous test part result reporter. + virtual ~ScopedFakeTestPartResultReporter(); - // Appends the TestPartResult object to the TestPartResultArray - // received in the constructor. - // - // This method is from the TestPartResultReporterInterface - // interface. - virtual void ReportTestPartResult(const TestPartResult& result); - private: - void Init(); + // Appends the TestPartResult object to the TestPartResultArray + // received in the constructor. + // + // This method is from the TestPartResultReporterInterface + // interface. + virtual void ReportTestPartResult(const TestPartResult& result); - const InterceptMode intercept_mode_; - TestPartResultReporterInterface* old_reporter_; - TestPartResultArray* const result_; +private: + void Init(); - GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); + const InterceptMode intercept_mode_; + TestPartResultReporterInterface* old_reporter_; + TestPartResultArray* const result_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedFakeTestPartResultReporter); }; -namespace internal { - +namespace internal +{ // A helper class for implementing EXPECT_FATAL_FAILURE() and // EXPECT_NONFATAL_FAILURE(). Its destructor verifies that the given // TestPartResultArray contains exactly one failure that has the given // type and contains the given substring. If that's not the case, a // non-fatal failure will be generated. -class GTEST_API_ SingleFailureChecker { - public: - // The constructor remembers the arguments. - SingleFailureChecker(const TestPartResultArray* results, - TestPartResult::Type type, - const string& substr); - ~SingleFailureChecker(); - private: - const TestPartResultArray* const results_; - const TestPartResult::Type type_; - const string substr_; +class GTEST_API_ SingleFailureChecker +{ +public: + // The constructor remembers the arguments. + SingleFailureChecker(const TestPartResultArray* results, + TestPartResult::Type type, + const string& substr); + ~SingleFailureChecker(); - GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); +private: + const TestPartResultArray* const results_; + const TestPartResult::Type type_; + const string substr_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(SingleFailureChecker); }; } // namespace internal @@ -135,39 +140,45 @@ class GTEST_API_ SingleFailureChecker { // helper macro, due to some peculiarity in how the preprocessor // works. The AcceptsMacroThatExpandsToUnprotectedComma test in // gtest_unittest.cc will fail to compile if we do that. -#define EXPECT_FATAL_FAILURE(statement, substr) \ - do { \ - class GTestExpectFatalFailureHelper {\ - public:\ - static void Execute() { statement; }\ - };\ - ::testing::TestPartResultArray gtest_failures;\ - ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ - {\ - ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ - ::testing::ScopedFakeTestPartResultReporter:: \ - INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ - GTestExpectFatalFailureHelper::Execute();\ - }\ - } while (::testing::internal::AlwaysFalse()) +#define EXPECT_FATAL_FAILURE(statement, substr) \ + do \ + { \ + class GTestExpectFatalFailureHelper \ + { \ + public: \ + static void Execute() { statement; } \ + }; \ + ::testing::TestPartResultArray gtest_failures; \ + ::testing::internal::SingleFailureChecker gtest_checker( \ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \ + { \ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, \ + >est_failures); \ + GTestExpectFatalFailureHelper::Execute(); \ + } \ + } while (::testing::internal::AlwaysFalse()) -#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ - do { \ - class GTestExpectFatalFailureHelper {\ - public:\ - static void Execute() { statement; }\ - };\ - ::testing::TestPartResultArray gtest_failures;\ - ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TestPartResult::kFatalFailure, (substr));\ - {\ - ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ - ::testing::ScopedFakeTestPartResultReporter:: \ - INTERCEPT_ALL_THREADS, >est_failures);\ - GTestExpectFatalFailureHelper::Execute();\ - }\ - } while (::testing::internal::AlwaysFalse()) +#define EXPECT_FATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do \ + { \ + class GTestExpectFatalFailureHelper \ + { \ + public: \ + static void Execute() { statement; } \ + }; \ + ::testing::TestPartResultArray gtest_failures; \ + ::testing::internal::SingleFailureChecker gtest_checker( \ + >est_failures, ::testing::TestPartResult::kFatalFailure, (substr)); \ + { \ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ALL_THREADS, \ + >est_failures); \ + GTestExpectFatalFailureHelper::Execute(); \ + } \ + } while (::testing::internal::AlwaysFalse()) // A macro for testing Google Test assertions or code that's expected to // generate Google Test non-fatal failures. It asserts that the given @@ -201,32 +212,41 @@ class GTEST_API_ SingleFailureChecker { // instead of // GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) // to avoid an MSVC warning on unreachable code. -#define EXPECT_NONFATAL_FAILURE(statement, substr) \ - do {\ - ::testing::TestPartResultArray gtest_failures;\ - ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ - (substr));\ - {\ - ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ - ::testing::ScopedFakeTestPartResultReporter:: \ - INTERCEPT_ONLY_CURRENT_THREAD, >est_failures);\ - if (::testing::internal::AlwaysTrue()) { statement; }\ - }\ - } while (::testing::internal::AlwaysFalse()) +#define EXPECT_NONFATAL_FAILURE(statement, substr) \ + do \ + { \ + ::testing::TestPartResultArray gtest_failures; \ + ::testing::internal::SingleFailureChecker gtest_checker( \ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr)); \ + { \ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \ + ::testing::ScopedFakeTestPartResultReporter:: \ + INTERCEPT_ONLY_CURRENT_THREAD, \ + >est_failures); \ + if (::testing::internal::AlwaysTrue()) \ + { \ + statement; \ + } \ + } \ + } while (::testing::internal::AlwaysFalse()) -#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ - do {\ - ::testing::TestPartResultArray gtest_failures;\ - ::testing::internal::SingleFailureChecker gtest_checker(\ - >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ - (substr));\ - {\ - ::testing::ScopedFakeTestPartResultReporter gtest_reporter(\ - ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ - >est_failures);\ - if (::testing::internal::AlwaysTrue()) { statement; }\ - }\ - } while (::testing::internal::AlwaysFalse()) +#define EXPECT_NONFATAL_FAILURE_ON_ALL_THREADS(statement, substr) \ + do \ + { \ + ::testing::TestPartResultArray gtest_failures; \ + ::testing::internal::SingleFailureChecker gtest_checker( \ + >est_failures, ::testing::TestPartResult::kNonFatalFailure, \ + (substr)); \ + { \ + ::testing::ScopedFakeTestPartResultReporter gtest_reporter( \ + ::testing::ScopedFakeTestPartResultReporter::INTERCEPT_ALL_THREADS, \ + >est_failures); \ + if (::testing::internal::AlwaysTrue()) \ + { \ + statement; \ + } \ + } \ + } while (::testing::internal::AlwaysFalse()) #endif // GTEST_INCLUDE_GTEST_GTEST_SPI_H_ diff --git a/test/gtest-1.7.0/include/gtest/gtest-test-part.h b/test/gtest-1.7.0/include/gtest/gtest-test-part.h index 77eb84483..afa95211b 100644 --- a/test/gtest-1.7.0/include/gtest/gtest-test-part.h +++ b/test/gtest-1.7.0/include/gtest/gtest-test-part.h @@ -38,82 +38,86 @@ #include "gtest/internal/gtest-internal.h" #include "gtest/internal/gtest-string.h" -namespace testing { - +namespace testing +{ // A copyable object representing the result of a test part (i.e. an // assertion or an explicit FAIL(), ADD_FAILURE(), or SUCCESS()). // // Don't inherit from TestPartResult as its destructor is not virtual. -class GTEST_API_ TestPartResult { - public: - // The possible outcomes of a test part (i.e. an assertion or an - // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). - enum Type { - kSuccess, // Succeeded. - kNonFatalFailure, // Failed but the test can continue. - kFatalFailure // Failed and the test should be terminated. - }; +class GTEST_API_ TestPartResult +{ +public: + // The possible outcomes of a test part (i.e. an assertion or an + // explicit SUCCEED(), FAIL(), or ADD_FAILURE()). + enum Type + { + kSuccess, // Succeeded. + kNonFatalFailure, // Failed but the test can continue. + kFatalFailure // Failed and the test should be terminated. + }; - // C'tor. TestPartResult does NOT have a default constructor. - // Always use this constructor (with parameters) to create a - // TestPartResult object. - TestPartResult(Type a_type, - const char* a_file_name, - int a_line_number, - const char* a_message) - : type_(a_type), - file_name_(a_file_name == NULL ? "" : a_file_name), - line_number_(a_line_number), - summary_(ExtractSummary(a_message)), - message_(a_message) { - } + // C'tor. TestPartResult does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestPartResult object. + TestPartResult(Type a_type, + const char* a_file_name, + int a_line_number, + const char* a_message) + : type_(a_type), + file_name_(a_file_name == NULL ? "" : a_file_name), + line_number_(a_line_number), + summary_(ExtractSummary(a_message)), + message_(a_message) + { + } - // Gets the outcome of the test part. - Type type() const { return type_; } + // Gets the outcome of the test part. + Type type() const { return type_; } - // Gets the name of the source file where the test part took place, or - // NULL if it's unknown. - const char* file_name() const { - return file_name_.empty() ? NULL : file_name_.c_str(); - } + // Gets the name of the source file where the test part took place, or + // NULL if it's unknown. + const char* file_name() const + { + return file_name_.empty() ? NULL : file_name_.c_str(); + } - // Gets the line in the source file where the test part took place, - // or -1 if it's unknown. - int line_number() const { return line_number_; } + // Gets the line in the source file where the test part took place, + // or -1 if it's unknown. + int line_number() const { return line_number_; } - // Gets the summary of the failure message. - const char* summary() const { return summary_.c_str(); } + // Gets the summary of the failure message. + const char* summary() const { return summary_.c_str(); } - // Gets the message associated with the test part. - const char* message() const { return message_.c_str(); } + // Gets the message associated with the test part. + const char* message() const { return message_.c_str(); } - // Returns true iff the test part passed. - bool passed() const { return type_ == kSuccess; } + // Returns true iff the test part passed. + bool passed() const { return type_ == kSuccess; } - // Returns true iff the test part failed. - bool failed() const { return type_ != kSuccess; } + // Returns true iff the test part failed. + bool failed() const { return type_ != kSuccess; } - // Returns true iff the test part non-fatally failed. - bool nonfatally_failed() const { return type_ == kNonFatalFailure; } + // Returns true iff the test part non-fatally failed. + bool nonfatally_failed() const { return type_ == kNonFatalFailure; } - // Returns true iff the test part fatally failed. - bool fatally_failed() const { return type_ == kFatalFailure; } + // Returns true iff the test part fatally failed. + bool fatally_failed() const { return type_ == kFatalFailure; } - private: - Type type_; +private: + Type type_; - // Gets the summary of the failure message by omitting the stack - // trace in it. - static std::string ExtractSummary(const char* message); + // Gets the summary of the failure message by omitting the stack + // trace in it. + static std::string ExtractSummary(const char* message); - // The name of the source file where the test part took place, or - // "" if the source file is unknown. - std::string file_name_; - // The line in the source file where the test part took place, or -1 - // if the line number is unknown. - int line_number_; - std::string summary_; // The test failure summary. - std::string message_; // The test failure message. + // The name of the source file where the test part took place, or + // "" if the source file is unknown. + std::string file_name_; + // The line in the source file where the test part took place, or -1 + // if the line number is unknown. + int line_number_; + std::string summary_; // The test failure summary. + std::string message_; // The test failure message. }; // Prints a TestPartResult object. @@ -123,35 +127,37 @@ std::ostream& operator<<(std::ostream& os, const TestPartResult& result); // // Don't inherit from TestPartResultArray as its destructor is not // virtual. -class GTEST_API_ TestPartResultArray { - public: - TestPartResultArray() {} +class GTEST_API_ TestPartResultArray +{ +public: + TestPartResultArray() {} - // Appends the given TestPartResult to the array. - void Append(const TestPartResult& result); + // Appends the given TestPartResult to the array. + void Append(const TestPartResult& result); - // Returns the TestPartResult at the given index (0-based). - const TestPartResult& GetTestPartResult(int index) const; + // Returns the TestPartResult at the given index (0-based). + const TestPartResult& GetTestPartResult(int index) const; - // Returns the number of TestPartResult objects in the array. - int size() const; + // Returns the number of TestPartResult objects in the array. + int size() const; - private: - std::vector array_; +private: + std::vector array_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestPartResultArray); }; // This interface knows how to report a test part result. -class TestPartResultReporterInterface { - public: - virtual ~TestPartResultReporterInterface() {} +class TestPartResultReporterInterface +{ +public: + virtual ~TestPartResultReporterInterface() {} - virtual void ReportTestPartResult(const TestPartResult& result) = 0; + virtual void ReportTestPartResult(const TestPartResult& result) = 0; }; -namespace internal { - +namespace internal +{ // This helper class is used by {ASSERT|EXPECT}_NO_FATAL_FAILURE to check if a // statement generates new fatal failures. To do so it registers itself as the // current test part result reporter. Besides checking if fatal failures were @@ -159,17 +165,19 @@ namespace internal { // The original result reporter is restored in the destructor. // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. class GTEST_API_ HasNewFatalFailureHelper - : public TestPartResultReporterInterface { - public: - HasNewFatalFailureHelper(); - virtual ~HasNewFatalFailureHelper(); - virtual void ReportTestPartResult(const TestPartResult& result); - bool has_new_fatal_failure() const { return has_new_fatal_failure_; } - private: - bool has_new_fatal_failure_; - TestPartResultReporterInterface* original_reporter_; + : public TestPartResultReporterInterface +{ +public: + HasNewFatalFailureHelper(); + virtual ~HasNewFatalFailureHelper(); + virtual void ReportTestPartResult(const TestPartResult& result); + bool has_new_fatal_failure() const { return has_new_fatal_failure_; } - GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); +private: + bool has_new_fatal_failure_; + TestPartResultReporterInterface* original_reporter_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(HasNewFatalFailureHelper); }; } // namespace internal diff --git a/test/gtest-1.7.0/include/gtest/gtest-typed-test.h b/test/gtest-1.7.0/include/gtest/gtest-typed-test.h index fe1e83b27..c371adf6c 100644 --- a/test/gtest-1.7.0/include/gtest/gtest-typed-test.h +++ b/test/gtest-1.7.0/include/gtest/gtest-typed-test.h @@ -157,33 +157,33 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); // // Expands to the name of the typedef for the type parameters of the // given test case. -# define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ +#define GTEST_TYPE_PARAMS_(TestCaseName) gtest_type_params_##TestCaseName##_ // The 'Types' template argument below must have spaces around it // since some compilers may choke on '>>' when passing a template // instance (e.g. Types) -# define TYPED_TEST_CASE(CaseName, Types) \ - typedef ::testing::internal::TypeList< Types >::type \ - GTEST_TYPE_PARAMS_(CaseName) +#define TYPED_TEST_CASE(CaseName, Types) \ + typedef ::testing::internal::TypeList::type \ + GTEST_TYPE_PARAMS_(CaseName) -# define TYPED_TEST(CaseName, TestName) \ - template \ - class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ - : public CaseName { \ - private: \ - typedef CaseName TestFixture; \ - typedef gtest_TypeParam_ TypeParam; \ - virtual void TestBody(); \ - }; \ - bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \ - ::testing::internal::TypeParameterizedTest< \ - CaseName, \ - ::testing::internal::TemplateSel< \ - GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ - GTEST_TYPE_PARAMS_(CaseName)>::Register(\ - "", #CaseName, #TestName, 0); \ - template \ - void GTEST_TEST_CLASS_NAME_(CaseName, TestName)::TestBody() +#define TYPED_TEST(CaseName, TestName) \ + template \ + class GTEST_TEST_CLASS_NAME_(CaseName, TestName) \ + : public CaseName \ + { \ + private: \ + typedef CaseName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + virtual void TestBody(); \ + }; \ + bool gtest_##CaseName##_##TestName##_registered_ GTEST_ATTRIBUTE_UNUSED_ = \ + ::testing::internal::TypeParameterizedTest< \ + CaseName, \ + ::testing::internal::TemplateSel< \ + GTEST_TEST_CLASS_NAME_(CaseName, TestName)>, \ + GTEST_TYPE_PARAMS_(CaseName)>::Register("", #CaseName, #TestName, 0); \ + template \ + void GTEST_TEST_CLASS_NAME_(CaseName, TestName)::TestBody() #endif // GTEST_HAS_TYPED_TEST @@ -196,63 +196,65 @@ INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes); // Expands to the namespace name that the type-parameterized tests for // the given type-parameterized test case are defined in. The exact // name of the namespace is subject to change without notice. -# define GTEST_CASE_NAMESPACE_(TestCaseName) \ - gtest_case_##TestCaseName##_ +#define GTEST_CASE_NAMESPACE_(TestCaseName) \ + gtest_case_##TestCaseName##_ // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Expands to the name of the variable used to remember the names of // the defined tests in the given test case. -# define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ - gtest_typed_test_case_p_state_##TestCaseName##_ +#define GTEST_TYPED_TEST_CASE_P_STATE_(TestCaseName) \ + gtest_typed_test_case_p_state_##TestCaseName##_ // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE DIRECTLY. // // Expands to the name of the variable used to remember the names of // the registered tests in the given test case. -# define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ - gtest_registered_test_names_##TestCaseName##_ +#define GTEST_REGISTERED_TEST_NAMES_(TestCaseName) \ + gtest_registered_test_names_##TestCaseName##_ // The variables defined in the type-parameterized test macros are // static as typically these macros are used in a .h file that can be // #included in multiple translation units linked together. -# define TYPED_TEST_CASE_P(CaseName) \ - static ::testing::internal::TypedTestCasePState \ - GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) +#define TYPED_TEST_CASE_P(CaseName) \ + static ::testing::internal::TypedTestCasePState \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName) -# define TYPED_TEST_P(CaseName, TestName) \ - namespace GTEST_CASE_NAMESPACE_(CaseName) { \ - template \ - class TestName : public CaseName { \ - private: \ - typedef CaseName TestFixture; \ - typedef gtest_TypeParam_ TypeParam; \ - virtual void TestBody(); \ - }; \ - static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ - GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName(\ - __FILE__, __LINE__, #CaseName, #TestName); \ - } \ - template \ - void GTEST_CASE_NAMESPACE_(CaseName)::TestName::TestBody() +#define TYPED_TEST_P(CaseName, TestName) \ + namespace GTEST_CASE_NAMESPACE_(CaseName) \ + { \ + template \ + class TestName : public CaseName \ + { \ + private: \ + typedef CaseName TestFixture; \ + typedef gtest_TypeParam_ TypeParam; \ + virtual void TestBody(); \ + }; \ + static bool gtest_##TestName##_defined_ GTEST_ATTRIBUTE_UNUSED_ = \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).AddTestName( \ + __FILE__, __LINE__, #CaseName, #TestName); \ + } \ + template \ + void GTEST_CASE_NAMESPACE_(CaseName)::TestName::TestBody() -# define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ - namespace GTEST_CASE_NAMESPACE_(CaseName) { \ - typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ - } \ - static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \ - GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames(\ - __FILE__, __LINE__, #__VA_ARGS__) +#define REGISTER_TYPED_TEST_CASE_P(CaseName, ...) \ + namespace GTEST_CASE_NAMESPACE_(CaseName) \ + { \ + typedef ::testing::internal::Templates<__VA_ARGS__>::type gtest_AllTests_; \ + } \ + static const char* const GTEST_REGISTERED_TEST_NAMES_(CaseName) = \ + GTEST_TYPED_TEST_CASE_P_STATE_(CaseName).VerifyRegisteredTestNames( \ + __FILE__, __LINE__, #__VA_ARGS__) // The 'Types' template argument below must have spaces around it // since some compilers may choke on '>>' when passing a template // instance (e.g. Types) -# define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ - bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \ - ::testing::internal::TypeParameterizedTestCase::type>::Register(\ - #Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) +#define INSTANTIATE_TYPED_TEST_CASE_P(Prefix, CaseName, Types) \ + bool gtest_##Prefix##_##CaseName GTEST_ATTRIBUTE_UNUSED_ = \ + ::testing::internal::TypeParameterizedTestCase::type>::Register(#Prefix, #CaseName, GTEST_REGISTERED_TEST_NAMES_(CaseName)) #endif // GTEST_HAS_TYPED_TEST_P diff --git a/test/gtest-1.7.0/include/gtest/gtest.h b/test/gtest-1.7.0/include/gtest/gtest.h index 6fa0a3925..ef30ce95f 100644 --- a/test/gtest-1.7.0/include/gtest/gtest.h +++ b/test/gtest-1.7.0/include/gtest/gtest.h @@ -80,8 +80,8 @@ // If the user doesn't define GTEST_HAS_GLOBAL_STRING, it is defined // heuristically. -namespace testing { - +namespace testing +{ // Declares the flags. // This flag temporary enables the disabled tests. @@ -146,8 +146,8 @@ GTEST_DECLARE_string_(stream_result_to); // The upper limit for valid stack trace depths. const int kMaxStackTraceDepth = 100; -namespace internal { - +namespace internal +{ class AssertHelper; class DefaultGlobalTestPartResultReporter; class ExecDeathTest; @@ -162,7 +162,7 @@ class UnitTestRecordPropertyTestHelper; class WindowsDeathTest; class UnitTestImpl* GetUnitTestImpl(); void ReportFailureInUnknownLocation(TestPartResult::Type result_type, - const std::string& message); + const std::string& message); } // namespace internal @@ -253,62 +253,68 @@ class UnitTest; // Expected: Foo() is even // Actual: it's 5 // -class GTEST_API_ AssertionResult { - public: - // Copy constructor. - // Used in EXPECT_TRUE/FALSE(assertion_result). - AssertionResult(const AssertionResult& other); - // Used in the EXPECT_TRUE/FALSE(bool_expression). - explicit AssertionResult(bool success) : success_(success) {} +class GTEST_API_ AssertionResult +{ +public: + // Copy constructor. + // Used in EXPECT_TRUE/FALSE(assertion_result). + AssertionResult(const AssertionResult& other); + // Used in the EXPECT_TRUE/FALSE(bool_expression). + explicit AssertionResult(bool success) : success_(success) {} - // Returns true iff the assertion succeeded. - operator bool() const { return success_; } // NOLINT + // Returns true iff the assertion succeeded. + operator bool() const { return success_; } // NOLINT - // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. - AssertionResult operator!() const; + // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. + AssertionResult operator!() const; - // Returns the text streamed into this AssertionResult. Test assertions - // use it when they fail (i.e., the predicate's outcome doesn't match the - // assertion's expectation). When nothing has been streamed into the - // object, returns an empty string. - const char* message() const { - return message_.get() != NULL ? message_->c_str() : ""; - } - // TODO(vladl@google.com): Remove this after making sure no clients use it. - // Deprecated; please use message() instead. - const char* failure_message() const { return message(); } + // Returns the text streamed into this AssertionResult. Test assertions + // use it when they fail (i.e., the predicate's outcome doesn't match the + // assertion's expectation). When nothing has been streamed into the + // object, returns an empty string. + const char* message() const + { + return message_.get() != NULL ? message_->c_str() : ""; + } + // TODO(vladl@google.com): Remove this after making sure no clients use it. + // Deprecated; please use message() instead. + const char* failure_message() const { return message(); } - // Streams a custom failure message into this object. - template AssertionResult& operator<<(const T& value) { - AppendMessage(Message() << value); - return *this; - } + // Streams a custom failure message into this object. + template + AssertionResult& operator<<(const T& value) + { + AppendMessage(Message() << value); + return *this; + } - // Allows streaming basic output manipulators such as endl or flush into - // this object. - AssertionResult& operator<<( - ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) { - AppendMessage(Message() << basic_manipulator); - return *this; - } + // Allows streaming basic output manipulators such as endl or flush into + // this object. + AssertionResult& operator<<( + ::std::ostream& (*basic_manipulator)(::std::ostream& stream)) + { + AppendMessage(Message() << basic_manipulator); + return *this; + } - private: - // Appends the contents of message to message_. - void AppendMessage(const Message& a_message) { - if (message_.get() == NULL) - message_.reset(new ::std::string); - message_->append(a_message.GetString().c_str()); - } +private: + // Appends the contents of message to message_. + void AppendMessage(const Message& a_message) + { + if (message_.get() == NULL) + message_.reset(new ::std::string); + message_->append(a_message.GetString().c_str()); + } - // Stores result of the assertion predicate. - bool success_; - // Stores the message describing the condition in case the expectation - // construct is not satisfied with the predicate's outcome. - // Referenced via a pointer to avoid taking too much stack frame space - // with test assertions. - internal::scoped_ptr< ::std::string> message_; + // Stores result of the assertion predicate. + bool success_; + // Stores the message describing the condition in case the expectation + // construct is not satisfied with the predicate's outcome. + // Referenced via a pointer to avoid taking too much stack frame space + // with test assertions. + internal::scoped_ptr< ::std::string> message_; - GTEST_DISALLOW_ASSIGN_(AssertionResult); + GTEST_DISALLOW_ASSIGN_(AssertionResult); }; // Makes a successful assertion result. @@ -344,114 +350,117 @@ GTEST_API_ AssertionResult AssertionFailure(const Message& msg); // TEST_F(FooTest, Baz) { ... } // // Test is not copyable. -class GTEST_API_ Test { - public: - friend class TestInfo; +class GTEST_API_ Test +{ +public: + friend class TestInfo; - // Defines types for pointers to functions that set up and tear down - // a test case. - typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc; - typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc; + // Defines types for pointers to functions that set up and tear down + // a test case. + typedef internal::SetUpTestCaseFunc SetUpTestCaseFunc; + typedef internal::TearDownTestCaseFunc TearDownTestCaseFunc; - // The d'tor is virtual as we intend to inherit from Test. - virtual ~Test(); + // The d'tor is virtual as we intend to inherit from Test. + virtual ~Test(); - // Sets up the stuff shared by all tests in this test case. - // - // Google Test will call Foo::SetUpTestCase() before running the first - // test in test case Foo. Hence a sub-class can define its own - // SetUpTestCase() method to shadow the one defined in the super - // class. - static void SetUpTestCase() {} + // Sets up the stuff shared by all tests in this test case. + // + // Google Test will call Foo::SetUpTestCase() before running the first + // test in test case Foo. Hence a sub-class can define its own + // SetUpTestCase() method to shadow the one defined in the super + // class. + static void SetUpTestCase() {} - // Tears down the stuff shared by all tests in this test case. - // - // Google Test will call Foo::TearDownTestCase() after running the last - // test in test case Foo. Hence a sub-class can define its own - // TearDownTestCase() method to shadow the one defined in the super - // class. - static void TearDownTestCase() {} + // Tears down the stuff shared by all tests in this test case. + // + // Google Test will call Foo::TearDownTestCase() after running the last + // test in test case Foo. Hence a sub-class can define its own + // TearDownTestCase() method to shadow the one defined in the super + // class. + static void TearDownTestCase() {} - // Returns true iff the current test has a fatal failure. - static bool HasFatalFailure(); + // Returns true iff the current test has a fatal failure. + static bool HasFatalFailure(); - // Returns true iff the current test has a non-fatal failure. - static bool HasNonfatalFailure(); + // Returns true iff the current test has a non-fatal failure. + static bool HasNonfatalFailure(); - // Returns true iff the current test has a (either fatal or - // non-fatal) failure. - static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); } + // Returns true iff the current test has a (either fatal or + // non-fatal) failure. + static bool HasFailure() { return HasFatalFailure() || HasNonfatalFailure(); } - // Logs a property for the current test, test case, or for the entire - // invocation of the test program when used outside of the context of a - // test case. Only the last value for a given key is remembered. These - // are public static so they can be called from utility functions that are - // not members of the test fixture. Calls to RecordProperty made during - // lifespan of the test (from the moment its constructor starts to the - // moment its destructor finishes) will be output in XML as attributes of - // the element. Properties recorded from fixture's - // SetUpTestCase or TearDownTestCase are logged as attributes of the - // corresponding element. Calls to RecordProperty made in the - // global context (before or after invocation of RUN_ALL_TESTS and from - // SetUp/TearDown method of Environment objects registered with Google - // Test) will be output as attributes of the element. - static void RecordProperty(const std::string& key, const std::string& value); - static void RecordProperty(const std::string& key, int value); + // Logs a property for the current test, test case, or for the entire + // invocation of the test program when used outside of the context of a + // test case. Only the last value for a given key is remembered. These + // are public static so they can be called from utility functions that are + // not members of the test fixture. Calls to RecordProperty made during + // lifespan of the test (from the moment its constructor starts to the + // moment its destructor finishes) will be output in XML as attributes of + // the element. Properties recorded from fixture's + // SetUpTestCase or TearDownTestCase are logged as attributes of the + // corresponding element. Calls to RecordProperty made in the + // global context (before or after invocation of RUN_ALL_TESTS and from + // SetUp/TearDown method of Environment objects registered with Google + // Test) will be output as attributes of the element. + static void RecordProperty(const std::string& key, const std::string& value); + static void RecordProperty(const std::string& key, int value); - protected: - // Creates a Test object. - Test(); +protected: + // Creates a Test object. + Test(); - // Sets up the test fixture. - virtual void SetUp(); + // Sets up the test fixture. + virtual void SetUp(); - // Tears down the test fixture. - virtual void TearDown(); + // Tears down the test fixture. + virtual void TearDown(); - private: - // Returns true iff the current test has the same fixture class as - // the first test in the current test case. - static bool HasSameFixtureClass(); +private: + // Returns true iff the current test has the same fixture class as + // the first test in the current test case. + static bool HasSameFixtureClass(); - // Runs the test after the test fixture has been set up. - // - // A sub-class must implement this to define the test logic. - // - // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM. - // Instead, use the TEST or TEST_F macro. - virtual void TestBody() = 0; + // Runs the test after the test fixture has been set up. + // + // A sub-class must implement this to define the test logic. + // + // DO NOT OVERRIDE THIS FUNCTION DIRECTLY IN A USER PROGRAM. + // Instead, use the TEST or TEST_F macro. + virtual void TestBody() = 0; - // Sets up, executes, and tears down the test. - void Run(); + // Sets up, executes, and tears down the test. + void Run(); - // Deletes self. We deliberately pick an unusual name for this - // internal method to avoid clashing with names used in user TESTs. - void DeleteSelf_() { delete this; } + // Deletes self. We deliberately pick an unusual name for this + // internal method to avoid clashing with names used in user TESTs. + void DeleteSelf_() { delete this; } - // Uses a GTestFlagSaver to save and restore all Google Test flags. - const internal::GTestFlagSaver* const gtest_flag_saver_; + // Uses a GTestFlagSaver to save and restore all Google Test flags. + const internal::GTestFlagSaver* const gtest_flag_saver_; - // Often a user mis-spells SetUp() as Setup() and spends a long time - // wondering why it is never called by Google Test. The declaration of - // the following method is solely for catching such an error at - // compile time: - // - // - The return type is deliberately chosen to be not void, so it - // will be a conflict if a user declares void Setup() in his test - // fixture. - // - // - This method is private, so it will be another compiler error - // if a user calls it from his test fixture. - // - // DO NOT OVERRIDE THIS FUNCTION. - // - // If you see an error about overriding the following function or - // about it being private, you have mis-spelled SetUp() as Setup(). - struct Setup_should_be_spelled_SetUp {}; - virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } + // Often a user mis-spells SetUp() as Setup() and spends a long time + // wondering why it is never called by Google Test. The declaration of + // the following method is solely for catching such an error at + // compile time: + // + // - The return type is deliberately chosen to be not void, so it + // will be a conflict if a user declares void Setup() in his test + // fixture. + // + // - This method is private, so it will be another compiler error + // if a user calls it from his test fixture. + // + // DO NOT OVERRIDE THIS FUNCTION. + // + // If you see an error about overriding the following function or + // about it being private, you have mis-spelled SetUp() as Setup(). + struct Setup_should_be_spelled_SetUp + { + }; + virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } - // We disallow copying Tests. - GTEST_DISALLOW_COPY_AND_ASSIGN_(Test); + // We disallow copying Tests. + GTEST_DISALLOW_COPY_AND_ASSIGN_(Test); }; typedef internal::TimeInMillis TimeInMillis; @@ -460,35 +469,39 @@ typedef internal::TimeInMillis TimeInMillis; // output as a key/value string pair. // // Don't inherit from TestProperty as its destructor is not virtual. -class TestProperty { - public: - // C'tor. TestProperty does NOT have a default constructor. - // Always use this constructor (with parameters) to create a - // TestProperty object. - TestProperty(const std::string& a_key, const std::string& a_value) : - key_(a_key), value_(a_value) { - } +class TestProperty +{ +public: + // C'tor. TestProperty does NOT have a default constructor. + // Always use this constructor (with parameters) to create a + // TestProperty object. + TestProperty(const std::string& a_key, const std::string& a_value) : key_(a_key), value_(a_value) + { + } - // Gets the user supplied key. - const char* key() const { - return key_.c_str(); - } + // Gets the user supplied key. + const char* key() const + { + return key_.c_str(); + } - // Gets the user supplied value. - const char* value() const { - return value_.c_str(); - } + // Gets the user supplied value. + const char* value() const + { + return value_.c_str(); + } - // Sets a new value, overriding the one supplied in the constructor. - void SetValue(const std::string& new_value) { - value_ = new_value; - } + // Sets a new value, overriding the one supplied in the constructor. + void SetValue(const std::string& new_value) + { + value_ = new_value; + } - private: - // The key supplied by the user. - std::string key_; - // The value supplied by the user. - std::string value_; +private: + // The key supplied by the user. + std::string key_; + // The value supplied by the user. + std::string value_; }; // The result of a single Test. This includes a list of @@ -497,114 +510,117 @@ class TestProperty { // the Test. // // TestResult is not copyable. -class GTEST_API_ TestResult { - public: - // Creates an empty TestResult. - TestResult(); +class GTEST_API_ TestResult +{ +public: + // Creates an empty TestResult. + TestResult(); - // D'tor. Do not inherit from TestResult. - ~TestResult(); + // D'tor. Do not inherit from TestResult. + ~TestResult(); - // Gets the number of all test parts. This is the sum of the number - // of successful test parts and the number of failed test parts. - int total_part_count() const; + // Gets the number of all test parts. This is the sum of the number + // of successful test parts and the number of failed test parts. + int total_part_count() const; - // Returns the number of the test properties. - int test_property_count() const; + // Returns the number of the test properties. + int test_property_count() const; - // Returns true iff the test passed (i.e. no test part failed). - bool Passed() const { return !Failed(); } + // Returns true iff the test passed (i.e. no test part failed). + bool Passed() const { return !Failed(); } - // Returns true iff the test failed. - bool Failed() const; + // Returns true iff the test failed. + bool Failed() const; - // Returns true iff the test fatally failed. - bool HasFatalFailure() const; + // Returns true iff the test fatally failed. + bool HasFatalFailure() const; - // Returns true iff the test has a non-fatal failure. - bool HasNonfatalFailure() const; + // Returns true iff the test has a non-fatal failure. + bool HasNonfatalFailure() const; - // Returns the elapsed time, in milliseconds. - TimeInMillis elapsed_time() const { return elapsed_time_; } + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } - // Returns the i-th test part result among all the results. i can range - // from 0 to test_property_count() - 1. If i is not in that range, aborts - // the program. - const TestPartResult& GetTestPartResult(int i) const; + // Returns the i-th test part result among all the results. i can range + // from 0 to test_property_count() - 1. If i is not in that range, aborts + // the program. + const TestPartResult& GetTestPartResult(int i) const; - // Returns the i-th test property. i can range from 0 to - // test_property_count() - 1. If i is not in that range, aborts the - // program. - const TestProperty& GetTestProperty(int i) const; + // Returns the i-th test property. i can range from 0 to + // test_property_count() - 1. If i is not in that range, aborts the + // program. + const TestProperty& GetTestProperty(int i) const; - private: - friend class TestInfo; - friend class TestCase; - friend class UnitTest; - friend class internal::DefaultGlobalTestPartResultReporter; - friend class internal::ExecDeathTest; - friend class internal::TestResultAccessor; - friend class internal::UnitTestImpl; - friend class internal::WindowsDeathTest; +private: + friend class TestInfo; + friend class TestCase; + friend class UnitTest; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::ExecDeathTest; + friend class internal::TestResultAccessor; + friend class internal::UnitTestImpl; + friend class internal::WindowsDeathTest; - // Gets the vector of TestPartResults. - const std::vector& test_part_results() const { - return test_part_results_; - } + // Gets the vector of TestPartResults. + const std::vector& test_part_results() const + { + return test_part_results_; + } - // Gets the vector of TestProperties. - const std::vector& test_properties() const { - return test_properties_; - } + // Gets the vector of TestProperties. + const std::vector& test_properties() const + { + return test_properties_; + } - // Sets the elapsed time. - void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } + // Sets the elapsed time. + void set_elapsed_time(TimeInMillis elapsed) { elapsed_time_ = elapsed; } - // Adds a test property to the list. The property is validated and may add - // a non-fatal failure if invalid (e.g., if it conflicts with reserved - // key names). If a property is already recorded for the same key, the - // value will be updated, rather than storing multiple values for the same - // key. xml_element specifies the element for which the property is being - // recorded and is used for validation. - void RecordProperty(const std::string& xml_element, - const TestProperty& test_property); + // Adds a test property to the list. The property is validated and may add + // a non-fatal failure if invalid (e.g., if it conflicts with reserved + // key names). If a property is already recorded for the same key, the + // value will be updated, rather than storing multiple values for the same + // key. xml_element specifies the element for which the property is being + // recorded and is used for validation. + void RecordProperty(const std::string& xml_element, + const TestProperty& test_property); - // Adds a failure if the key is a reserved attribute of Google Test - // testcase tags. Returns true if the property is valid. - // TODO(russr): Validate attribute names are legal and human readable. - static bool ValidateTestProperty(const std::string& xml_element, - const TestProperty& test_property); + // Adds a failure if the key is a reserved attribute of Google Test + // testcase tags. Returns true if the property is valid. + // TODO(russr): Validate attribute names are legal and human readable. + static bool ValidateTestProperty(const std::string& xml_element, + const TestProperty& test_property); - // Adds a test part result to the list. - void AddTestPartResult(const TestPartResult& test_part_result); + // Adds a test part result to the list. + void AddTestPartResult(const TestPartResult& test_part_result); - // Returns the death test count. - int death_test_count() const { return death_test_count_; } + // Returns the death test count. + int death_test_count() const { return death_test_count_; } - // Increments the death test count, returning the new count. - int increment_death_test_count() { return ++death_test_count_; } + // Increments the death test count, returning the new count. + int increment_death_test_count() { return ++death_test_count_; } - // Clears the test part results. - void ClearTestPartResults(); + // Clears the test part results. + void ClearTestPartResults(); - // Clears the object. - void Clear(); + // Clears the object. + void Clear(); - // Protects mutable state of the property vector and of owned - // properties, whose values may be updated. - internal::Mutex test_properites_mutex_; + // Protects mutable state of the property vector and of owned + // properties, whose values may be updated. + internal::Mutex test_properites_mutex_; - // The vector of TestPartResults - std::vector test_part_results_; - // The vector of TestProperties - std::vector test_properties_; - // Running count of death tests. - int death_test_count_; - // The elapsed time, in milliseconds. - TimeInMillis elapsed_time_; + // The vector of TestPartResults + std::vector test_part_results_; + // The vector of TestProperties + std::vector test_properties_; + // Running count of death tests. + int death_test_count_; + // The elapsed time, in milliseconds. + TimeInMillis elapsed_time_; - // We disallow copying TestResult. - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); + // We disallow copying TestResult. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestResult); }; // class TestResult // A TestInfo object stores the following information about a test: @@ -618,309 +634,325 @@ class GTEST_API_ TestResult { // The constructor of TestInfo registers itself with the UnitTest // singleton such that the RUN_ALL_TESTS() macro knows which tests to // run. -class GTEST_API_ TestInfo { - public: - // Destructs a TestInfo object. This function is not virtual, so - // don't inherit from TestInfo. - ~TestInfo(); +class GTEST_API_ TestInfo +{ +public: + // Destructs a TestInfo object. This function is not virtual, so + // don't inherit from TestInfo. + ~TestInfo(); - // Returns the test case name. - const char* test_case_name() const { return test_case_name_.c_str(); } + // Returns the test case name. + const char* test_case_name() const { return test_case_name_.c_str(); } - // Returns the test name. - const char* name() const { return name_.c_str(); } + // Returns the test name. + const char* name() const { return name_.c_str(); } - // Returns the name of the parameter type, or NULL if this is not a typed - // or a type-parameterized test. - const char* type_param() const { - if (type_param_.get() != NULL) - return type_param_->c_str(); - return NULL; - } + // Returns the name of the parameter type, or NULL if this is not a typed + // or a type-parameterized test. + const char* type_param() const + { + if (type_param_.get() != NULL) + return type_param_->c_str(); + return NULL; + } - // Returns the text representation of the value parameter, or NULL if this - // is not a value-parameterized test. - const char* value_param() const { - if (value_param_.get() != NULL) - return value_param_->c_str(); - return NULL; - } + // Returns the text representation of the value parameter, or NULL if this + // is not a value-parameterized test. + const char* value_param() const + { + if (value_param_.get() != NULL) + return value_param_->c_str(); + return NULL; + } - // Returns true if this test should run, that is if the test is not - // disabled (or it is disabled but the also_run_disabled_tests flag has - // been specified) and its full name matches the user-specified filter. - // - // Google Test allows the user to filter the tests by their full names. - // The full name of a test Bar in test case Foo is defined as - // "Foo.Bar". Only the tests that match the filter will run. - // - // A filter is a colon-separated list of glob (not regex) patterns, - // optionally followed by a '-' and a colon-separated list of - // negative patterns (tests to exclude). A test is run if it - // matches one of the positive patterns and does not match any of - // the negative patterns. - // - // For example, *A*:Foo.* is a filter that matches any string that - // contains the character 'A' or starts with "Foo.". - bool should_run() const { return should_run_; } + // Returns true if this test should run, that is if the test is not + // disabled (or it is disabled but the also_run_disabled_tests flag has + // been specified) and its full name matches the user-specified filter. + // + // Google Test allows the user to filter the tests by their full names. + // The full name of a test Bar in test case Foo is defined as + // "Foo.Bar". Only the tests that match the filter will run. + // + // A filter is a colon-separated list of glob (not regex) patterns, + // optionally followed by a '-' and a colon-separated list of + // negative patterns (tests to exclude). A test is run if it + // matches one of the positive patterns and does not match any of + // the negative patterns. + // + // For example, *A*:Foo.* is a filter that matches any string that + // contains the character 'A' or starts with "Foo.". + bool should_run() const { return should_run_; } - // Returns true iff this test will appear in the XML report. - bool is_reportable() const { - // For now, the XML report includes all tests matching the filter. - // In the future, we may trim tests that are excluded because of - // sharding. - return matches_filter_; - } + // Returns true iff this test will appear in the XML report. + bool is_reportable() const + { + // For now, the XML report includes all tests matching the filter. + // In the future, we may trim tests that are excluded because of + // sharding. + return matches_filter_; + } - // Returns the result of the test. - const TestResult* result() const { return &result_; } + // Returns the result of the test. + const TestResult* result() const { return &result_; } - private: +private: #if GTEST_HAS_DEATH_TEST - friend class internal::DefaultDeathTestFactory; + friend class internal::DefaultDeathTestFactory; #endif // GTEST_HAS_DEATH_TEST - friend class Test; - friend class TestCase; - friend class internal::UnitTestImpl; - friend class internal::StreamingListenerTest; - friend TestInfo* internal::MakeAndRegisterTestInfo( - const char* test_case_name, - const char* name, - const char* type_param, - const char* value_param, - internal::TypeId fixture_class_id, - Test::SetUpTestCaseFunc set_up_tc, - Test::TearDownTestCaseFunc tear_down_tc, - internal::TestFactoryBase* factory); + friend class Test; + friend class TestCase; + friend class internal::UnitTestImpl; + friend class internal::StreamingListenerTest; + friend TestInfo* internal::MakeAndRegisterTestInfo( + const char* test_case_name, + const char* name, + const char* type_param, + const char* value_param, + internal::TypeId fixture_class_id, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc, + internal::TestFactoryBase* factory); - // Constructs a TestInfo object. The newly constructed instance assumes - // ownership of the factory object. - TestInfo(const std::string& test_case_name, - const std::string& name, - const char* a_type_param, // NULL if not a type-parameterized test - const char* a_value_param, // NULL if not a value-parameterized test - internal::TypeId fixture_class_id, - internal::TestFactoryBase* factory); + // Constructs a TestInfo object. The newly constructed instance assumes + // ownership of the factory object. + TestInfo(const std::string& test_case_name, + const std::string& name, + const char* a_type_param, // NULL if not a type-parameterized test + const char* a_value_param, // NULL if not a value-parameterized test + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory); - // Increments the number of death tests encountered in this test so - // far. - int increment_death_test_count() { - return result_.increment_death_test_count(); - } + // Increments the number of death tests encountered in this test so + // far. + int increment_death_test_count() + { + return result_.increment_death_test_count(); + } - // Creates the test object, runs it, records its result, and then - // deletes it. - void Run(); + // Creates the test object, runs it, records its result, and then + // deletes it. + void Run(); - static void ClearTestResult(TestInfo* test_info) { - test_info->result_.Clear(); - } + static void ClearTestResult(TestInfo* test_info) + { + test_info->result_.Clear(); + } - // These fields are immutable properties of the test. - const std::string test_case_name_; // Test case name - const std::string name_; // Test name - // Name of the parameter type, or NULL if this is not a typed or a - // type-parameterized test. - const internal::scoped_ptr type_param_; - // Text representation of the value parameter, or NULL if this is not a - // value-parameterized test. - const internal::scoped_ptr value_param_; - const internal::TypeId fixture_class_id_; // ID of the test fixture class - bool should_run_; // True iff this test should run - bool is_disabled_; // True iff this test is disabled - bool matches_filter_; // True if this test matches the - // user-specified filter. - internal::TestFactoryBase* const factory_; // The factory that creates - // the test object + // These fields are immutable properties of the test. + const std::string test_case_name_; // Test case name + const std::string name_; // Test name + // Name of the parameter type, or NULL if this is not a typed or a + // type-parameterized test. + const internal::scoped_ptr type_param_; + // Text representation of the value parameter, or NULL if this is not a + // value-parameterized test. + const internal::scoped_ptr value_param_; + const internal::TypeId fixture_class_id_; // ID of the test fixture class + bool should_run_; // True iff this test should run + bool is_disabled_; // True iff this test is disabled + bool matches_filter_; // True if this test matches the + // user-specified filter. + internal::TestFactoryBase* const factory_; // The factory that creates + // the test object - // This field is mutable and needs to be reset before running the - // test for the second time. - TestResult result_; + // This field is mutable and needs to be reset before running the + // test for the second time. + TestResult result_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestInfo); }; // A test case, which consists of a vector of TestInfos. // // TestCase is not copyable. -class GTEST_API_ TestCase { - public: - // Creates a TestCase with the given name. - // - // TestCase does NOT have a default constructor. Always use this - // constructor to create a TestCase object. - // - // Arguments: - // - // name: name of the test case - // a_type_param: the name of the test's type parameter, or NULL if - // this is not a type-parameterized test. - // set_up_tc: pointer to the function that sets up the test case - // tear_down_tc: pointer to the function that tears down the test case - TestCase(const char* name, const char* a_type_param, - Test::SetUpTestCaseFunc set_up_tc, - Test::TearDownTestCaseFunc tear_down_tc); +class GTEST_API_ TestCase +{ +public: + // Creates a TestCase with the given name. + // + // TestCase does NOT have a default constructor. Always use this + // constructor to create a TestCase object. + // + // Arguments: + // + // name: name of the test case + // a_type_param: the name of the test's type parameter, or NULL if + // this is not a type-parameterized test. + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase(const char* name, const char* a_type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); - // Destructor of TestCase. - virtual ~TestCase(); + // Destructor of TestCase. + virtual ~TestCase(); - // Gets the name of the TestCase. - const char* name() const { return name_.c_str(); } + // Gets the name of the TestCase. + const char* name() const { return name_.c_str(); } - // Returns the name of the parameter type, or NULL if this is not a - // type-parameterized test case. - const char* type_param() const { - if (type_param_.get() != NULL) - return type_param_->c_str(); - return NULL; - } + // Returns the name of the parameter type, or NULL if this is not a + // type-parameterized test case. + const char* type_param() const + { + if (type_param_.get() != NULL) + return type_param_->c_str(); + return NULL; + } - // Returns true if any test in this test case should run. - bool should_run() const { return should_run_; } + // Returns true if any test in this test case should run. + bool should_run() const { return should_run_; } - // Gets the number of successful tests in this test case. - int successful_test_count() const; + // Gets the number of successful tests in this test case. + int successful_test_count() const; - // Gets the number of failed tests in this test case. - int failed_test_count() const; + // Gets the number of failed tests in this test case. + int failed_test_count() const; - // Gets the number of disabled tests that will be reported in the XML report. - int reportable_disabled_test_count() const; + // Gets the number of disabled tests that will be reported in the XML report. + int reportable_disabled_test_count() const; - // Gets the number of disabled tests in this test case. - int disabled_test_count() const; + // Gets the number of disabled tests in this test case. + int disabled_test_count() const; - // Gets the number of tests to be printed in the XML report. - int reportable_test_count() const; + // Gets the number of tests to be printed in the XML report. + int reportable_test_count() const; - // Get the number of tests in this test case that should run. - int test_to_run_count() const; + // Get the number of tests in this test case that should run. + int test_to_run_count() const; - // Gets the number of all tests in this test case. - int total_test_count() const; + // Gets the number of all tests in this test case. + int total_test_count() const; - // Returns true iff the test case passed. - bool Passed() const { return !Failed(); } + // Returns true iff the test case passed. + bool Passed() const { return !Failed(); } - // Returns true iff the test case failed. - bool Failed() const { return failed_test_count() > 0; } + // Returns true iff the test case failed. + bool Failed() const { return failed_test_count() > 0; } - // Returns the elapsed time, in milliseconds. - TimeInMillis elapsed_time() const { return elapsed_time_; } + // Returns the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } - // Returns the i-th test among all the tests. i can range from 0 to - // total_test_count() - 1. If i is not in that range, returns NULL. - const TestInfo* GetTestInfo(int i) const; + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + const TestInfo* GetTestInfo(int i) const; - // Returns the TestResult that holds test properties recorded during - // execution of SetUpTestCase and TearDownTestCase. - const TestResult& ad_hoc_test_result() const { return ad_hoc_test_result_; } + // Returns the TestResult that holds test properties recorded during + // execution of SetUpTestCase and TearDownTestCase. + const TestResult& ad_hoc_test_result() const { return ad_hoc_test_result_; } - private: - friend class Test; - friend class internal::UnitTestImpl; +private: + friend class Test; + friend class internal::UnitTestImpl; - // Gets the (mutable) vector of TestInfos in this TestCase. - std::vector& test_info_list() { return test_info_list_; } + // Gets the (mutable) vector of TestInfos in this TestCase. + std::vector& test_info_list() { return test_info_list_; } - // Gets the (immutable) vector of TestInfos in this TestCase. - const std::vector& test_info_list() const { - return test_info_list_; - } + // Gets the (immutable) vector of TestInfos in this TestCase. + const std::vector& test_info_list() const + { + return test_info_list_; + } - // Returns the i-th test among all the tests. i can range from 0 to - // total_test_count() - 1. If i is not in that range, returns NULL. - TestInfo* GetMutableTestInfo(int i); + // Returns the i-th test among all the tests. i can range from 0 to + // total_test_count() - 1. If i is not in that range, returns NULL. + TestInfo* GetMutableTestInfo(int i); - // Sets the should_run member. - void set_should_run(bool should) { should_run_ = should; } + // Sets the should_run member. + void set_should_run(bool should) { should_run_ = should; } - // Adds a TestInfo to this test case. Will delete the TestInfo upon - // destruction of the TestCase object. - void AddTestInfo(TestInfo * test_info); + // Adds a TestInfo to this test case. Will delete the TestInfo upon + // destruction of the TestCase object. + void AddTestInfo(TestInfo* test_info); - // Clears the results of all tests in this test case. - void ClearResult(); + // Clears the results of all tests in this test case. + void ClearResult(); - // Clears the results of all tests in the given test case. - static void ClearTestCaseResult(TestCase* test_case) { - test_case->ClearResult(); - } + // Clears the results of all tests in the given test case. + static void ClearTestCaseResult(TestCase* test_case) + { + test_case->ClearResult(); + } - // Runs every test in this TestCase. - void Run(); + // Runs every test in this TestCase. + void Run(); - // Runs SetUpTestCase() for this TestCase. This wrapper is needed - // for catching exceptions thrown from SetUpTestCase(). - void RunSetUpTestCase() { (*set_up_tc_)(); } + // Runs SetUpTestCase() for this TestCase. This wrapper is needed + // for catching exceptions thrown from SetUpTestCase(). + void RunSetUpTestCase() { (*set_up_tc_)(); } - // Runs TearDownTestCase() for this TestCase. This wrapper is - // needed for catching exceptions thrown from TearDownTestCase(). - void RunTearDownTestCase() { (*tear_down_tc_)(); } + // Runs TearDownTestCase() for this TestCase. This wrapper is + // needed for catching exceptions thrown from TearDownTestCase(). + void RunTearDownTestCase() { (*tear_down_tc_)(); } - // Returns true iff test passed. - static bool TestPassed(const TestInfo* test_info) { - return test_info->should_run() && test_info->result()->Passed(); - } + // Returns true iff test passed. + static bool TestPassed(const TestInfo* test_info) + { + return test_info->should_run() && test_info->result()->Passed(); + } - // Returns true iff test failed. - static bool TestFailed(const TestInfo* test_info) { - return test_info->should_run() && test_info->result()->Failed(); - } + // Returns true iff test failed. + static bool TestFailed(const TestInfo* test_info) + { + return test_info->should_run() && test_info->result()->Failed(); + } - // Returns true iff the test is disabled and will be reported in the XML - // report. - static bool TestReportableDisabled(const TestInfo* test_info) { - return test_info->is_reportable() && test_info->is_disabled_; - } + // Returns true iff the test is disabled and will be reported in the XML + // report. + static bool TestReportableDisabled(const TestInfo* test_info) + { + return test_info->is_reportable() && test_info->is_disabled_; + } - // Returns true iff test is disabled. - static bool TestDisabled(const TestInfo* test_info) { - return test_info->is_disabled_; - } + // Returns true iff test is disabled. + static bool TestDisabled(const TestInfo* test_info) + { + return test_info->is_disabled_; + } - // Returns true iff this test will appear in the XML report. - static bool TestReportable(const TestInfo* test_info) { - return test_info->is_reportable(); - } + // Returns true iff this test will appear in the XML report. + static bool TestReportable(const TestInfo* test_info) + { + return test_info->is_reportable(); + } - // Returns true if the given test should run. - static bool ShouldRunTest(const TestInfo* test_info) { - return test_info->should_run(); - } + // Returns true if the given test should run. + static bool ShouldRunTest(const TestInfo* test_info) + { + return test_info->should_run(); + } - // Shuffles the tests in this test case. - void ShuffleTests(internal::Random* random); + // Shuffles the tests in this test case. + void ShuffleTests(internal::Random* random); - // Restores the test order to before the first shuffle. - void UnshuffleTests(); + // Restores the test order to before the first shuffle. + void UnshuffleTests(); - // Name of the test case. - std::string name_; - // Name of the parameter type, or NULL if this is not a typed or a - // type-parameterized test. - const internal::scoped_ptr type_param_; - // The vector of TestInfos in their original order. It owns the - // elements in the vector. - std::vector test_info_list_; - // Provides a level of indirection for the test list to allow easy - // shuffling and restoring the test order. The i-th element in this - // vector is the index of the i-th test in the shuffled test list. - std::vector test_indices_; - // Pointer to the function that sets up the test case. - Test::SetUpTestCaseFunc set_up_tc_; - // Pointer to the function that tears down the test case. - Test::TearDownTestCaseFunc tear_down_tc_; - // True iff any test in this test case should run. - bool should_run_; - // Elapsed time, in milliseconds. - TimeInMillis elapsed_time_; - // Holds test properties recorded during execution of SetUpTestCase and - // TearDownTestCase. - TestResult ad_hoc_test_result_; + // Name of the test case. + std::string name_; + // Name of the parameter type, or NULL if this is not a typed or a + // type-parameterized test. + const internal::scoped_ptr type_param_; + // The vector of TestInfos in their original order. It owns the + // elements in the vector. + std::vector test_info_list_; + // Provides a level of indirection for the test list to allow easy + // shuffling and restoring the test order. The i-th element in this + // vector is the index of the i-th test in the shuffled test list. + std::vector test_indices_; + // Pointer to the function that sets up the test case. + Test::SetUpTestCaseFunc set_up_tc_; + // Pointer to the function that tears down the test case. + Test::TearDownTestCaseFunc tear_down_tc_; + // True iff any test in this test case should run. + bool should_run_; + // Elapsed time, in milliseconds. + TimeInMillis elapsed_time_; + // Holds test properties recorded during execution of SetUpTestCase and + // TearDownTestCase. + TestResult ad_hoc_test_result_; - // We disallow copying TestCases. - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); + // We disallow copying TestCases. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestCase); }; // An Environment object is capable of setting up and tearing down an @@ -937,71 +969,76 @@ class GTEST_API_ TestCase { // available. // 2. You cannot use ASSERT_* directly in a constructor or // destructor. -class Environment { - public: - // The d'tor is virtual as we need to subclass Environment. - virtual ~Environment() {} +class Environment +{ +public: + // The d'tor is virtual as we need to subclass Environment. + virtual ~Environment() {} - // Override this to define how to set up the environment. - virtual void SetUp() {} + // Override this to define how to set up the environment. + virtual void SetUp() {} - // Override this to define how to tear down the environment. - virtual void TearDown() {} - private: - // If you see an error about overriding the following function or - // about it being private, you have mis-spelled SetUp() as Setup(). - struct Setup_should_be_spelled_SetUp {}; - virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } + // Override this to define how to tear down the environment. + virtual void TearDown() {} + +private: + // If you see an error about overriding the following function or + // about it being private, you have mis-spelled SetUp() as Setup(). + struct Setup_should_be_spelled_SetUp + { + }; + virtual Setup_should_be_spelled_SetUp* Setup() { return NULL; } }; // The interface for tracing execution of tests. The methods are organized in // the order the corresponding events are fired. -class TestEventListener { - public: - virtual ~TestEventListener() {} +class TestEventListener +{ +public: + virtual ~TestEventListener() {} - // Fired before any test activity starts. - virtual void OnTestProgramStart(const UnitTest& unit_test) = 0; + // Fired before any test activity starts. + virtual void OnTestProgramStart(const UnitTest& unit_test) = 0; - // Fired before each iteration of tests starts. There may be more than - // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration - // index, starting from 0. - virtual void OnTestIterationStart(const UnitTest& unit_test, - int iteration) = 0; + // Fired before each iteration of tests starts. There may be more than + // one iteration if GTEST_FLAG(repeat) is set. iteration is the iteration + // index, starting from 0. + virtual void OnTestIterationStart(const UnitTest& unit_test, + int iteration) = 0; - // Fired before environment set-up for each iteration of tests starts. - virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0; + // Fired before environment set-up for each iteration of tests starts. + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test) = 0; - // Fired after environment set-up for each iteration of tests ends. - virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0; + // Fired after environment set-up for each iteration of tests ends. + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test) = 0; - // Fired before the test case starts. - virtual void OnTestCaseStart(const TestCase& test_case) = 0; + // Fired before the test case starts. + virtual void OnTestCaseStart(const TestCase& test_case) = 0; - // Fired before the test starts. - virtual void OnTestStart(const TestInfo& test_info) = 0; + // Fired before the test starts. + virtual void OnTestStart(const TestInfo& test_info) = 0; - // Fired after a failed assertion or a SUCCEED() invocation. - virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; + // Fired after a failed assertion or a SUCCEED() invocation. + virtual void OnTestPartResult(const TestPartResult& test_part_result) = 0; - // Fired after the test ends. - virtual void OnTestEnd(const TestInfo& test_info) = 0; + // Fired after the test ends. + virtual void OnTestEnd(const TestInfo& test_info) = 0; - // Fired after the test case ends. - virtual void OnTestCaseEnd(const TestCase& test_case) = 0; + // Fired after the test case ends. + virtual void OnTestCaseEnd(const TestCase& test_case) = 0; - // Fired before environment tear-down for each iteration of tests starts. - virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0; + // Fired before environment tear-down for each iteration of tests starts. + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test) = 0; - // Fired after environment tear-down for each iteration of tests ends. - virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; + // Fired after environment tear-down for each iteration of tests ends. + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test) = 0; - // Fired after each iteration of tests finishes. - virtual void OnTestIterationEnd(const UnitTest& unit_test, - int iteration) = 0; + // Fired after each iteration of tests finishes. + virtual void OnTestIterationEnd(const UnitTest& unit_test, + int iteration) = 0; - // Fired after all test activities have ended. - virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; + // Fired after all test activities have ended. + virtual void OnTestProgramEnd(const UnitTest& unit_test) = 0; }; // The convenience class for users who need to override just one or two @@ -1009,101 +1046,105 @@ class TestEventListener { // the methods they override will not be caught during the build. For // comments about each method please see the definition of TestEventListener // above. -class EmptyTestEventListener : public TestEventListener { - public: - virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} - virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, - int /*iteration*/) {} - virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {} - virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} - virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} - virtual void OnTestStart(const TestInfo& /*test_info*/) {} - virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {} - virtual void OnTestEnd(const TestInfo& /*test_info*/) {} - virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} - virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {} - virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} - virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, - int /*iteration*/) {} - virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} +class EmptyTestEventListener : public TestEventListener +{ +public: + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnEnvironmentsSetUpStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& /*test_case*/) {} + virtual void OnTestStart(const TestInfo& /*test_info*/) {} + virtual void OnTestPartResult(const TestPartResult& /*test_part_result*/) {} + virtual void OnTestEnd(const TestInfo& /*test_info*/) {} + virtual void OnTestCaseEnd(const TestCase& /*test_case*/) {} + virtual void OnEnvironmentsTearDownStart(const UnitTest& /*unit_test*/) {} + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& /*unit_test*/, + int /*iteration*/) {} + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} }; // TestEventListeners lets users add listeners to track events in Google Test. -class GTEST_API_ TestEventListeners { - public: - TestEventListeners(); - ~TestEventListeners(); +class GTEST_API_ TestEventListeners +{ +public: + TestEventListeners(); + ~TestEventListeners(); - // Appends an event listener to the end of the list. Google Test assumes - // the ownership of the listener (i.e. it will delete the listener when - // the test program finishes). - void Append(TestEventListener* listener); + // Appends an event listener to the end of the list. Google Test assumes + // the ownership of the listener (i.e. it will delete the listener when + // the test program finishes). + void Append(TestEventListener* listener); - // Removes the given event listener from the list and returns it. It then - // becomes the caller's responsibility to delete the listener. Returns - // NULL if the listener is not found in the list. - TestEventListener* Release(TestEventListener* listener); + // Removes the given event listener from the list and returns it. It then + // becomes the caller's responsibility to delete the listener. Returns + // NULL if the listener is not found in the list. + TestEventListener* Release(TestEventListener* listener); - // Returns the standard listener responsible for the default console - // output. Can be removed from the listeners list to shut down default - // console output. Note that removing this object from the listener list - // with Release transfers its ownership to the caller and makes this - // function return NULL the next time. - TestEventListener* default_result_printer() const { - return default_result_printer_; - } + // Returns the standard listener responsible for the default console + // output. Can be removed from the listeners list to shut down default + // console output. Note that removing this object from the listener list + // with Release transfers its ownership to the caller and makes this + // function return NULL the next time. + TestEventListener* default_result_printer() const + { + return default_result_printer_; + } - // Returns the standard listener responsible for the default XML output - // controlled by the --gtest_output=xml flag. Can be removed from the - // listeners list by users who want to shut down the default XML output - // controlled by this flag and substitute it with custom one. Note that - // removing this object from the listener list with Release transfers its - // ownership to the caller and makes this function return NULL the next - // time. - TestEventListener* default_xml_generator() const { - return default_xml_generator_; - } + // Returns the standard listener responsible for the default XML output + // controlled by the --gtest_output=xml flag. Can be removed from the + // listeners list by users who want to shut down the default XML output + // controlled by this flag and substitute it with custom one. Note that + // removing this object from the listener list with Release transfers its + // ownership to the caller and makes this function return NULL the next + // time. + TestEventListener* default_xml_generator() const + { + return default_xml_generator_; + } - private: - friend class TestCase; - friend class TestInfo; - friend class internal::DefaultGlobalTestPartResultReporter; - friend class internal::NoExecDeathTest; - friend class internal::TestEventListenersAccessor; - friend class internal::UnitTestImpl; +private: + friend class TestCase; + friend class TestInfo; + friend class internal::DefaultGlobalTestPartResultReporter; + friend class internal::NoExecDeathTest; + friend class internal::TestEventListenersAccessor; + friend class internal::UnitTestImpl; - // Returns repeater that broadcasts the TestEventListener events to all - // subscribers. - TestEventListener* repeater(); + // Returns repeater that broadcasts the TestEventListener events to all + // subscribers. + TestEventListener* repeater(); - // Sets the default_result_printer attribute to the provided listener. - // The listener is also added to the listener list and previous - // default_result_printer is removed from it and deleted. The listener can - // also be NULL in which case it will not be added to the list. Does - // nothing if the previous and the current listener objects are the same. - void SetDefaultResultPrinter(TestEventListener* listener); + // Sets the default_result_printer attribute to the provided listener. + // The listener is also added to the listener list and previous + // default_result_printer is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultResultPrinter(TestEventListener* listener); - // Sets the default_xml_generator attribute to the provided listener. The - // listener is also added to the listener list and previous - // default_xml_generator is removed from it and deleted. The listener can - // also be NULL in which case it will not be added to the list. Does - // nothing if the previous and the current listener objects are the same. - void SetDefaultXmlGenerator(TestEventListener* listener); + // Sets the default_xml_generator attribute to the provided listener. The + // listener is also added to the listener list and previous + // default_xml_generator is removed from it and deleted. The listener can + // also be NULL in which case it will not be added to the list. Does + // nothing if the previous and the current listener objects are the same. + void SetDefaultXmlGenerator(TestEventListener* listener); - // Controls whether events will be forwarded by the repeater to the - // listeners in the list. - bool EventForwardingEnabled() const; - void SuppressEventForwarding(); + // Controls whether events will be forwarded by the repeater to the + // listeners in the list. + bool EventForwardingEnabled() const; + void SuppressEventForwarding(); - // The actual list of listeners. - internal::TestEventRepeater* repeater_; - // Listener responsible for the standard result output. - TestEventListener* default_result_printer_; - // Listener responsible for the creation of the XML output file. - TestEventListener* default_xml_generator_; + // The actual list of listeners. + internal::TestEventRepeater* repeater_; + // Listener responsible for the standard result output. + TestEventListener* default_result_printer_; + // Listener responsible for the creation of the XML output file. + TestEventListener* default_xml_generator_; - // We disallow copying TestEventListeners. - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners); + // We disallow copying TestEventListeners. + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventListeners); }; // A UnitTest consists of a vector of TestCases. @@ -1116,185 +1157,186 @@ class GTEST_API_ TestEventListeners { // // This class is thread-safe as long as the methods are called // according to their specification. -class GTEST_API_ UnitTest { - public: - // Gets the singleton UnitTest object. The first time this method - // is called, a UnitTest object is constructed and returned. - // Consecutive calls will return the same object. - static UnitTest* GetInstance(); +class GTEST_API_ UnitTest +{ +public: + // Gets the singleton UnitTest object. The first time this method + // is called, a UnitTest object is constructed and returned. + // Consecutive calls will return the same object. + static UnitTest* GetInstance(); - // Runs all tests in this UnitTest object and prints the result. - // Returns 0 if successful, or 1 otherwise. - // - // This method can only be called from the main thread. - // - // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - int Run() GTEST_MUST_USE_RESULT_; + // Runs all tests in this UnitTest object and prints the result. + // Returns 0 if successful, or 1 otherwise. + // + // This method can only be called from the main thread. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + int Run() GTEST_MUST_USE_RESULT_; - // Returns the working directory when the first TEST() or TEST_F() - // was executed. The UnitTest object owns the string. - const char* original_working_dir() const; + // Returns the working directory when the first TEST() or TEST_F() + // was executed. The UnitTest object owns the string. + const char* original_working_dir() const; - // Returns the TestCase object for the test that's currently running, - // or NULL if no test is running. - const TestCase* current_test_case() const - GTEST_LOCK_EXCLUDED_(mutex_); + // Returns the TestCase object for the test that's currently running, + // or NULL if no test is running. + const TestCase* current_test_case() const + GTEST_LOCK_EXCLUDED_(mutex_); - // Returns the TestInfo object for the test that's currently running, - // or NULL if no test is running. - const TestInfo* current_test_info() const - GTEST_LOCK_EXCLUDED_(mutex_); + // Returns the TestInfo object for the test that's currently running, + // or NULL if no test is running. + const TestInfo* current_test_info() const + GTEST_LOCK_EXCLUDED_(mutex_); - // Returns the random seed used at the start of the current test run. - int random_seed() const; + // Returns the random seed used at the start of the current test run. + int random_seed() const; #if GTEST_HAS_PARAM_TEST - // Returns the ParameterizedTestCaseRegistry object used to keep track of - // value-parameterized tests and instantiate and register them. - // - // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. - internal::ParameterizedTestCaseRegistry& parameterized_test_registry() - GTEST_LOCK_EXCLUDED_(mutex_); + // Returns the ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + // + // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry() + GTEST_LOCK_EXCLUDED_(mutex_); #endif // GTEST_HAS_PARAM_TEST - // Gets the number of successful test cases. - int successful_test_case_count() const; + // Gets the number of successful test cases. + int successful_test_case_count() const; - // Gets the number of failed test cases. - int failed_test_case_count() const; + // Gets the number of failed test cases. + int failed_test_case_count() const; - // Gets the number of all test cases. - int total_test_case_count() const; + // Gets the number of all test cases. + int total_test_case_count() const; - // Gets the number of all test cases that contain at least one test - // that should run. - int test_case_to_run_count() const; + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; - // Gets the number of successful tests. - int successful_test_count() const; + // Gets the number of successful tests. + int successful_test_count() const; - // Gets the number of failed tests. - int failed_test_count() const; + // Gets the number of failed tests. + int failed_test_count() const; - // Gets the number of disabled tests that will be reported in the XML report. - int reportable_disabled_test_count() const; + // Gets the number of disabled tests that will be reported in the XML report. + int reportable_disabled_test_count() const; - // Gets the number of disabled tests. - int disabled_test_count() const; + // Gets the number of disabled tests. + int disabled_test_count() const; - // Gets the number of tests to be printed in the XML report. - int reportable_test_count() const; + // Gets the number of tests to be printed in the XML report. + int reportable_test_count() const; - // Gets the number of all tests. - int total_test_count() const; + // Gets the number of all tests. + int total_test_count() const; - // Gets the number of tests that should run. - int test_to_run_count() const; + // Gets the number of tests that should run. + int test_to_run_count() const; - // Gets the time of the test program start, in ms from the start of the - // UNIX epoch. - TimeInMillis start_timestamp() const; + // Gets the time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp() const; - // Gets the elapsed time, in milliseconds. - TimeInMillis elapsed_time() const; + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const; - // Returns true iff the unit test passed (i.e. all test cases passed). - bool Passed() const; + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const; - // Returns true iff the unit test failed (i.e. some test case failed - // or something outside of all tests failed). - bool Failed() const; + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const; - // Gets the i-th test case among all the test cases. i can range from 0 to - // total_test_case_count() - 1. If i is not in that range, returns NULL. - const TestCase* GetTestCase(int i) const; + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const; - // Returns the TestResult containing information on test failures and - // properties logged outside of individual test cases. - const TestResult& ad_hoc_test_result() const; + // Returns the TestResult containing information on test failures and + // properties logged outside of individual test cases. + const TestResult& ad_hoc_test_result() const; - // Returns the list of event listeners that can be used to track events - // inside Google Test. - TestEventListeners& listeners(); + // Returns the list of event listeners that can be used to track events + // inside Google Test. + TestEventListeners& listeners(); - private: - // Registers and returns a global test environment. When a test - // program is run, all global test environments will be set-up in - // the order they were registered. After all tests in the program - // have finished, all global test environments will be torn-down in - // the *reverse* order they were registered. - // - // The UnitTest object takes ownership of the given environment. - // - // This method can only be called from the main thread. - Environment* AddEnvironment(Environment* env); +private: + // Registers and returns a global test environment. When a test + // program is run, all global test environments will be set-up in + // the order they were registered. After all tests in the program + // have finished, all global test environments will be torn-down in + // the *reverse* order they were registered. + // + // The UnitTest object takes ownership of the given environment. + // + // This method can only be called from the main thread. + Environment* AddEnvironment(Environment* env); - // Adds a TestPartResult to the current TestResult object. All - // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) - // eventually call this to report their results. The user code - // should use the assertion macros instead of calling this directly. - void AddTestPartResult(TestPartResult::Type result_type, - const char* file_name, - int line_number, - const std::string& message, - const std::string& os_stack_trace) - GTEST_LOCK_EXCLUDED_(mutex_); + // Adds a TestPartResult to the current TestResult object. All + // Google Test assertion macros (e.g. ASSERT_TRUE, EXPECT_EQ, etc) + // eventually call this to report their results. The user code + // should use the assertion macros instead of calling this directly. + void AddTestPartResult(TestPartResult::Type result_type, + const char* file_name, + int line_number, + const std::string& message, + const std::string& os_stack_trace) + GTEST_LOCK_EXCLUDED_(mutex_); - // Adds a TestProperty to the current TestResult object when invoked from - // inside a test, to current TestCase's ad_hoc_test_result_ when invoked - // from SetUpTestCase or TearDownTestCase, or to the global property set - // when invoked elsewhere. If the result already contains a property with - // the same key, the value will be updated. - void RecordProperty(const std::string& key, const std::string& value); + // Adds a TestProperty to the current TestResult object when invoked from + // inside a test, to current TestCase's ad_hoc_test_result_ when invoked + // from SetUpTestCase or TearDownTestCase, or to the global property set + // when invoked elsewhere. If the result already contains a property with + // the same key, the value will be updated. + void RecordProperty(const std::string& key, const std::string& value); - // Gets the i-th test case among all the test cases. i can range from 0 to - // total_test_case_count() - 1. If i is not in that range, returns NULL. - TestCase* GetMutableTestCase(int i); + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i); - // Accessors for the implementation object. - internal::UnitTestImpl* impl() { return impl_; } - const internal::UnitTestImpl* impl() const { return impl_; } + // Accessors for the implementation object. + internal::UnitTestImpl* impl() { return impl_; } + const internal::UnitTestImpl* impl() const { return impl_; } - // These classes and funcions are friends as they need to access private - // members of UnitTest. - friend class Test; - friend class internal::AssertHelper; - friend class internal::ScopedTrace; - friend class internal::StreamingListenerTest; - friend class internal::UnitTestRecordPropertyTestHelper; - friend Environment* AddGlobalTestEnvironment(Environment* env); - friend internal::UnitTestImpl* internal::GetUnitTestImpl(); - friend void internal::ReportFailureInUnknownLocation( - TestPartResult::Type result_type, - const std::string& message); + // These classes and funcions are friends as they need to access private + // members of UnitTest. + friend class Test; + friend class internal::AssertHelper; + friend class internal::ScopedTrace; + friend class internal::StreamingListenerTest; + friend class internal::UnitTestRecordPropertyTestHelper; + friend Environment* AddGlobalTestEnvironment(Environment* env); + friend internal::UnitTestImpl* internal::GetUnitTestImpl(); + friend void internal::ReportFailureInUnknownLocation( + TestPartResult::Type result_type, + const std::string& message); - // Creates an empty UnitTest. - UnitTest(); + // Creates an empty UnitTest. + UnitTest(); - // D'tor - virtual ~UnitTest(); + // D'tor + virtual ~UnitTest(); - // Pushes a trace defined by SCOPED_TRACE() on to the per-thread - // Google Test trace stack. - void PushGTestTrace(const internal::TraceInfo& trace) - GTEST_LOCK_EXCLUDED_(mutex_); + // Pushes a trace defined by SCOPED_TRACE() on to the per-thread + // Google Test trace stack. + void PushGTestTrace(const internal::TraceInfo& trace) + GTEST_LOCK_EXCLUDED_(mutex_); - // Pops a trace from the per-thread Google Test trace stack. - void PopGTestTrace() - GTEST_LOCK_EXCLUDED_(mutex_); + // Pops a trace from the per-thread Google Test trace stack. + void PopGTestTrace() + GTEST_LOCK_EXCLUDED_(mutex_); - // Protects mutable state in *impl_. This is mutable as some const - // methods need to lock it too. - mutable internal::Mutex mutex_; + // Protects mutable state in *impl_. This is mutable as some const + // methods need to lock it too. + mutable internal::Mutex mutex_; - // Opaque implementation object. This field is never changed once - // the object is constructed. We don't mark it as const here, as - // doing so will cause a warning in the constructor of UnitTest. - // Mutable state in *impl_ is protected by mutex_. - internal::UnitTestImpl* impl_; + // Opaque implementation object. This field is never changed once + // the object is constructed. We don't mark it as const here, as + // doing so will cause a warning in the constructor of UnitTest. + // Mutable state in *impl_ is protected by mutex_. + internal::UnitTestImpl* impl_; - // We disallow copying UnitTest. - GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest); + // We disallow copying UnitTest. + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTest); }; // A convenient wrapper for adding an environment for the test @@ -1315,8 +1357,9 @@ class GTEST_API_ UnitTest { // translation units and the environments have dependencies among them // (remember that the compiler doesn't guarantee the order in which // global variables from different translation units are initialized). -inline Environment* AddGlobalTestEnvironment(Environment* env) { - return UnitTest::GetInstance()->AddEnvironment(env); +inline Environment* AddGlobalTestEnvironment(Environment* env) +{ + return UnitTest::GetInstance()->AddEnvironment(env); } // Initializes Google Test. This must be called before calling @@ -1334,8 +1377,8 @@ GTEST_API_ void InitGoogleTest(int* argc, char** argv); // UNICODE mode. GTEST_API_ void InitGoogleTest(int* argc, wchar_t** argv); -namespace internal { - +namespace internal +{ // FormatForComparison::Format(value) formats a // value of type ToPrint that is an operand of a comparison assertion // (e.g. ASSERT_EQ). OtherOperand is the type of the other operand in @@ -1352,33 +1395,39 @@ namespace internal { // The default case. template -class FormatForComparison { - public: - static ::std::string Format(const ToPrint& value) { - return ::testing::PrintToString(value); - } +class FormatForComparison +{ +public: + static ::std::string Format(const ToPrint& value) + { + return ::testing::PrintToString(value); + } }; // Array. template -class FormatForComparison { - public: - static ::std::string Format(const ToPrint* value) { - return FormatForComparison::Format(value); - } +class FormatForComparison +{ +public: + static ::std::string Format(const ToPrint* value) + { + return FormatForComparison::Format(value); + } }; // By default, print C string as pointers to be safe, as we don't know // whether they actually point to a NUL-terminated string. -#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \ - template \ - class FormatForComparison { \ - public: \ - static ::std::string Format(CharType* value) { \ - return ::testing::PrintToString(static_cast(value)); \ - } \ - } +#define GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(CharType) \ + template \ + class FormatForComparison \ + { \ + public: \ + static ::std::string Format(CharType* value) \ + { \ + return ::testing::PrintToString(static_cast(value)); \ + } \ + } GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(char); GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char); @@ -1391,13 +1440,15 @@ GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const wchar_t); // to point to a NUL-terminated string, and thus can print it as a string. #define GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(CharType, OtherStringType) \ - template <> \ - class FormatForComparison { \ - public: \ - static ::std::string Format(CharType* value) { \ - return ::testing::PrintToString(value); \ - } \ - } + template <> \ + class FormatForComparison \ + { \ + public: \ + static ::std::string Format(CharType* value) \ + { \ + return ::testing::PrintToString(value); \ + } \ + } GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string); @@ -1429,120 +1480,129 @@ GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const wchar_t, ::std::wstring); // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. template std::string FormatForComparisonFailureMessage( - const T1& value, const T2& /* other_operand */) { - return FormatForComparison::Format(value); + const T1& value, const T2& /* other_operand */) +{ + return FormatForComparison::Format(value); } // The helper function for {ASSERT|EXPECT}_EQ. template AssertionResult CmpHelperEQ(const char* expected_expression, - const char* actual_expression, - const T1& expected, - const T2& actual) { + const char* actual_expression, + const T1& expected, + const T2& actual) +{ #ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4389) // Temporarily disables warning on - // signed/unsigned mismatch. +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable : 4389) // Temporarily disables warning on \ + // signed/unsigned mismatch. #endif - if (expected == actual) { - return AssertionSuccess(); - } + if (expected == actual) + { + return AssertionSuccess(); + } #ifdef _MSC_VER -# pragma warning(pop) // Restores the warning state. +#pragma warning(pop) // Restores the warning state. #endif - return EqFailure(expected_expression, - actual_expression, - FormatForComparisonFailureMessage(expected, actual), - FormatForComparisonFailureMessage(actual, expected), - false); + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); } // With this overloaded version, we allow anonymous enums to be used // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous enums // can be implicitly cast to BiggestInt. GTEST_API_ AssertionResult CmpHelperEQ(const char* expected_expression, - const char* actual_expression, - BiggestInt expected, - BiggestInt actual); + const char* actual_expression, + BiggestInt expected, + BiggestInt actual); // The helper class for {ASSERT|EXPECT}_EQ. The template argument // lhs_is_null_literal is true iff the first argument to ASSERT_EQ() // is a null pointer literal. The following default implementation is // for lhs_is_null_literal being false. template -class EqHelper { - public: - // This templatized version is for the general case. - template - static AssertionResult Compare(const char* expected_expression, - const char* actual_expression, - const T1& expected, - const T2& actual) { - return CmpHelperEQ(expected_expression, actual_expression, expected, - actual); - } +class EqHelper +{ +public: + // This templatized version is for the general case. + template + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual) + { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } - // With this overloaded version, we allow anonymous enums to be used - // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous - // enums can be implicitly cast to BiggestInt. - // - // Even though its body looks the same as the above version, we - // cannot merge the two, as it will make anonymous enums unhappy. - static AssertionResult Compare(const char* expected_expression, - const char* actual_expression, - BiggestInt expected, - BiggestInt actual) { - return CmpHelperEQ(expected_expression, actual_expression, expected, - actual); - } + // With this overloaded version, we allow anonymous enums to be used + // in {ASSERT|EXPECT}_EQ when compiled with gcc 4, as anonymous + // enums can be implicitly cast to BiggestInt. + // + // Even though its body looks the same as the above version, we + // cannot merge the two, as it will make anonymous enums unhappy. + static AssertionResult Compare(const char* expected_expression, + const char* actual_expression, + BiggestInt expected, + BiggestInt actual) + { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } }; // This specialization is used when the first argument to ASSERT_EQ() // is a null pointer literal, like NULL, false, or 0. template <> -class EqHelper { - public: - // We define two overloaded versions of Compare(). The first - // version will be picked when the second argument to ASSERT_EQ() is - // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or - // EXPECT_EQ(false, a_bool). - template - static AssertionResult Compare( - const char* expected_expression, - const char* actual_expression, - const T1& expected, - const T2& actual, - // The following line prevents this overload from being considered if T2 - // is not a pointer type. We need this because ASSERT_EQ(NULL, my_ptr) - // expands to Compare("", "", NULL, my_ptr), which requires a conversion - // to match the Secret* in the other overload, which would otherwise make - // this template match better. - typename EnableIf::value>::type* = 0) { - return CmpHelperEQ(expected_expression, actual_expression, expected, - actual); - } +class EqHelper +{ +public: + // We define two overloaded versions of Compare(). The first + // version will be picked when the second argument to ASSERT_EQ() is + // NOT a pointer, e.g. ASSERT_EQ(0, AnIntFunction()) or + // EXPECT_EQ(false, a_bool). + template + static AssertionResult Compare( + const char* expected_expression, + const char* actual_expression, + const T1& expected, + const T2& actual, + // The following line prevents this overload from being considered if T2 + // is not a pointer type. We need this because ASSERT_EQ(NULL, my_ptr) + // expands to Compare("", "", NULL, my_ptr), which requires a conversion + // to match the Secret* in the other overload, which would otherwise make + // this template match better. + typename EnableIf::value>::type* = 0) + { + return CmpHelperEQ(expected_expression, actual_expression, expected, + actual); + } - // This version will be picked when the second argument to ASSERT_EQ() is a - // pointer, e.g. ASSERT_EQ(NULL, a_pointer). - template - static AssertionResult Compare( - const char* expected_expression, - const char* actual_expression, - // We used to have a second template parameter instead of Secret*. That - // template parameter would deduce to 'long', making this a better match - // than the first overload even without the first overload's EnableIf. - // Unfortunately, gcc with -Wconversion-null warns when "passing NULL to - // non-pointer argument" (even a deduced integral argument), so the old - // implementation caused warnings in user code. - Secret* /* expected (NULL) */, - T* actual) { - // We already know that 'expected' is a null pointer. - return CmpHelperEQ(expected_expression, actual_expression, - static_cast(NULL), actual); - } + // This version will be picked when the second argument to ASSERT_EQ() is a + // pointer, e.g. ASSERT_EQ(NULL, a_pointer). + template + static AssertionResult Compare( + const char* expected_expression, + const char* actual_expression, + // We used to have a second template parameter instead of Secret*. That + // template parameter would deduce to 'long', making this a better match + // than the first overload even without the first overload's EnableIf. + // Unfortunately, gcc with -Wconversion-null warns when "passing NULL to + // non-pointer argument" (even a deduced integral argument), so the old + // implementation caused warnings in user code. + Secret* /* expected (NULL) */, + T* actual) + { + // We already know that 'expected' is a null pointer. + return CmpHelperEQ(expected_expression, actual_expression, + static_cast(NULL), actual); + } }; // A macro for implementing the helper functions needed to implement @@ -1555,21 +1615,25 @@ class EqHelper { // with gcc 4. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. -#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ -template \ -AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ - const T1& val1, const T2& val2) {\ - if (val1 op val2) {\ - return AssertionSuccess();\ - } else {\ - return AssertionFailure() \ - << "Expected: (" << expr1 << ") " #op " (" << expr2\ - << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ - << " vs " << FormatForComparisonFailureMessage(val2, val1);\ - }\ -}\ -GTEST_API_ AssertionResult CmpHelper##op_name(\ - const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2) +#define GTEST_IMPL_CMP_HELPER_(op_name, op) \ + template \ + AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + const T1& val1, const T2& val2) \ + { \ + if (val1 op val2) \ + { \ + return AssertionSuccess(); \ + } \ + else \ + { \ + return AssertionFailure() \ + << "Expected: (" << expr1 << ") " #op " (" << expr2 \ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2) \ + << " vs " << FormatForComparisonFailureMessage(val2, val1); \ + } \ + } \ + GTEST_API_ AssertionResult CmpHelper##op_name( \ + const char* expr1, const char* expr2, BiggestInt val1, BiggestInt val2) // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. @@ -1590,50 +1654,49 @@ GTEST_IMPL_CMP_HELPER_(GT, >); // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, - const char* actual_expression, - const char* expected, - const char* actual); + const char* actual_expression, + const char* expected, + const char* actual); // The helper function for {ASSERT|EXPECT}_STRCASEEQ. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, - const char* actual_expression, - const char* expected, - const char* actual); + const char* actual_expression, + const char* expected, + const char* actual); // The helper function for {ASSERT|EXPECT}_STRNE. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, - const char* s2_expression, - const char* s1, - const char* s2); + const char* s2_expression, + const char* s1, + const char* s2); // The helper function for {ASSERT|EXPECT}_STRCASENE. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRCASENE(const char* s1_expression, - const char* s2_expression, - const char* s1, - const char* s2); - + const char* s2_expression, + const char* s1, + const char* s2); // Helper function for *_STREQ on wide strings. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTREQ(const char* expected_expression, - const char* actual_expression, - const wchar_t* expected, - const wchar_t* actual); + const char* actual_expression, + const wchar_t* expected, + const wchar_t* actual); // Helper function for *_STRNE on wide strings. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, - const char* s2_expression, - const wchar_t* s1, - const wchar_t* s2); + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2); } // namespace internal @@ -1646,35 +1709,35 @@ GTEST_API_ AssertionResult CmpHelperSTRNE(const char* s1_expression, // The {needle,haystack}_expr arguments are the stringified // expressions that generated the two real arguments. GTEST_API_ AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const char* needle, const char* haystack); + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack); GTEST_API_ AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const wchar_t* needle, const wchar_t* haystack); + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack); GTEST_API_ AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const char* needle, const char* haystack); + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack); GTEST_API_ AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const wchar_t* needle, const wchar_t* haystack); + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack); GTEST_API_ AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::string& needle, const ::std::string& haystack); + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack); GTEST_API_ AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::string& needle, const ::std::string& haystack); + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack); #if GTEST_HAS_STD_WSTRING GTEST_API_ AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::wstring& needle, const ::std::wstring& haystack); + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack); GTEST_API_ AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::wstring& needle, const ::std::wstring& haystack); + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack); #endif // GTEST_HAS_STD_WSTRING -namespace internal { - +namespace internal +{ // Helper template function for comparing floating-points. // // Template parameter: @@ -1684,79 +1747,83 @@ namespace internal { // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. template AssertionResult CmpHelperFloatingPointEQ(const char* expected_expression, - const char* actual_expression, - RawType expected, - RawType actual) { - const FloatingPoint lhs(expected), rhs(actual); + const char* actual_expression, + RawType expected, + RawType actual) +{ + const FloatingPoint lhs(expected), rhs(actual); - if (lhs.AlmostEquals(rhs)) { - return AssertionSuccess(); - } + if (lhs.AlmostEquals(rhs)) + { + return AssertionSuccess(); + } - ::std::stringstream expected_ss; - expected_ss << std::setprecision(std::numeric_limits::digits10 + 2) - << expected; + ::std::stringstream expected_ss; + expected_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << expected; - ::std::stringstream actual_ss; - actual_ss << std::setprecision(std::numeric_limits::digits10 + 2) - << actual; + ::std::stringstream actual_ss; + actual_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << actual; - return EqFailure(expected_expression, - actual_expression, - StringStreamToString(&expected_ss), - StringStreamToString(&actual_ss), - false); + return EqFailure(expected_expression, + actual_expression, + StringStreamToString(&expected_ss), + StringStreamToString(&actual_ss), + false); } // Helper function for implementing ASSERT_NEAR. // // INTERNAL IMPLEMENTATION - DO NOT USE IN A USER PROGRAM. GTEST_API_ AssertionResult DoubleNearPredFormat(const char* expr1, - const char* expr2, - const char* abs_error_expr, - double val1, - double val2, - double abs_error); + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error); // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // A class that enables one to stream messages to assertion macros -class GTEST_API_ AssertHelper { - public: - // Constructor. - AssertHelper(TestPartResult::Type type, - const char* file, - int line, - const char* message); - ~AssertHelper(); +class GTEST_API_ AssertHelper +{ +public: + // Constructor. + AssertHelper(TestPartResult::Type type, + const char* file, + int line, + const char* message); + ~AssertHelper(); - // Message assignment is a semantic trick to enable assertion - // streaming; see the GTEST_MESSAGE_ macro below. - void operator=(const Message& message) const; + // Message assignment is a semantic trick to enable assertion + // streaming; see the GTEST_MESSAGE_ macro below. + void operator=(const Message& message) const; - private: - // We put our data in a struct so that the size of the AssertHelper class can - // be as small as possible. This is important because gcc is incapable of - // re-using stack space even for temporary variables, so every EXPECT_EQ - // reserves stack space for another AssertHelper. - struct AssertHelperData { - AssertHelperData(TestPartResult::Type t, - const char* srcfile, - int line_num, - const char* msg) - : type(t), file(srcfile), line(line_num), message(msg) { } +private: + // We put our data in a struct so that the size of the AssertHelper class can + // be as small as possible. This is important because gcc is incapable of + // re-using stack space even for temporary variables, so every EXPECT_EQ + // reserves stack space for another AssertHelper. + struct AssertHelperData + { + AssertHelperData(TestPartResult::Type t, + const char* srcfile, + int line_num, + const char* msg) + : type(t), file(srcfile), line(line_num), message(msg) {} - TestPartResult::Type const type; - const char* const file; - int const line; - std::string const message; + TestPartResult::Type const type; + const char* const file; + int const line; + std::string const message; - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); - }; + private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelperData); + }; - AssertHelperData* const data_; + AssertHelperData* const data_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); + GTEST_DISALLOW_COPY_AND_ASSIGN_(AssertHelper); }; } // namespace internal @@ -1797,35 +1864,39 @@ class GTEST_API_ AssertHelper { // INSTANTIATE_TEST_CASE_P(OneToTenRange, FooTest, ::testing::Range(1, 10)); template -class WithParamInterface { - public: - typedef T ParamType; - virtual ~WithParamInterface() {} +class WithParamInterface +{ +public: + typedef T ParamType; + virtual ~WithParamInterface() {} - // The current parameter value. Is also available in the test fixture's - // constructor. This member function is non-static, even though it only - // references static data, to reduce the opportunity for incorrect uses - // like writing 'WithParamInterface::GetParam()' for a test that - // uses a fixture whose parameter type is int. - const ParamType& GetParam() const { - GTEST_CHECK_(parameter_ != NULL) - << "GetParam() can only be called inside a value-parameterized test " - << "-- did you intend to write TEST_P instead of TEST_F?"; - return *parameter_; - } + // The current parameter value. Is also available in the test fixture's + // constructor. This member function is non-static, even though it only + // references static data, to reduce the opportunity for incorrect uses + // like writing 'WithParamInterface::GetParam()' for a test that + // uses a fixture whose parameter type is int. + const ParamType& GetParam() const + { + GTEST_CHECK_(parameter_ != NULL) + << "GetParam() can only be called inside a value-parameterized test " + << "-- did you intend to write TEST_P instead of TEST_F?"; + return *parameter_; + } - private: - // Sets parameter value. The caller is responsible for making sure the value - // remains alive and unchanged throughout the current test. - static void SetParam(const ParamType* parameter) { - parameter_ = parameter; - } +private: + // Sets parameter value. The caller is responsible for making sure the value + // remains alive and unchanged throughout the current test. + static void SetParam(const ParamType* parameter) + { + parameter_ = parameter; + } - // Static value used for accessing parameter during a test lifetime. - static const ParamType* parameter_; + // Static value used for accessing parameter during a test lifetime. + static const ParamType* parameter_; - // TestClass must be a subclass of WithParamInterface and Test. - template friend class internal::ParameterizedTestFactory; + // TestClass must be a subclass of WithParamInterface and Test. + template + friend class internal::ParameterizedTestFactory; }; template @@ -1835,7 +1906,8 @@ const T* WithParamInterface::parameter_ = NULL; // WithParamInterface, and can just inherit from ::testing::TestWithParam. template -class TestWithParam : public Test, public WithParamInterface { +class TestWithParam : public Test, public WithParamInterface +{ }; #endif // GTEST_HAS_PARAM_TEST @@ -1864,9 +1936,9 @@ class TestWithParam : public Test, public WithParamInterface { // Generates a nonfatal failure at the given source file location with // a generic message. -#define ADD_FAILURE_AT(file, line) \ - GTEST_MESSAGE_AT_(file, line, "Failed", \ - ::testing::TestPartResult::kNonFatalFailure) +#define ADD_FAILURE_AT(file, line) \ + GTEST_MESSAGE_AT_(file, line, "Failed", \ + ::testing::TestPartResult::kNonFatalFailure) // Generates a fatal failure with a generic message. #define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed") @@ -1874,7 +1946,7 @@ class TestWithParam : public Test, public WithParamInterface { // Define this macro to 1 to omit the definition of FAIL(), which is a // generic name and clashes with some other libraries. #if !GTEST_DONT_DEFINE_FAIL -# define FAIL() GTEST_FAIL() +#define FAIL() GTEST_FAIL() #endif // Generates a success with a generic message. @@ -1883,7 +1955,7 @@ class TestWithParam : public Test, public WithParamInterface { // Define this macro to 1 to omit the definition of SUCCEED(), which // is a generic name and clashes with some other libraries. #if !GTEST_DONT_DEFINE_SUCCEED -# define SUCCEED() GTEST_SUCCEED() +#define SUCCEED() GTEST_SUCCEED() #endif // Macros for testing exceptions. @@ -1896,33 +1968,33 @@ class TestWithParam : public Test, public WithParamInterface { // Tests that the statement throws an exception. #define EXPECT_THROW(statement, expected_exception) \ - GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_) + GTEST_TEST_THROW_(statement, expected_exception, GTEST_NONFATAL_FAILURE_) #define EXPECT_NO_THROW(statement) \ - GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_) + GTEST_TEST_NO_THROW_(statement, GTEST_NONFATAL_FAILURE_) #define EXPECT_ANY_THROW(statement) \ - GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_) + GTEST_TEST_ANY_THROW_(statement, GTEST_NONFATAL_FAILURE_) #define ASSERT_THROW(statement, expected_exception) \ - GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_) + GTEST_TEST_THROW_(statement, expected_exception, GTEST_FATAL_FAILURE_) #define ASSERT_NO_THROW(statement) \ - GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_) + GTEST_TEST_NO_THROW_(statement, GTEST_FATAL_FAILURE_) #define ASSERT_ANY_THROW(statement) \ - GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_) + GTEST_TEST_ANY_THROW_(statement, GTEST_FATAL_FAILURE_) // Boolean assertions. Condition can be either a Boolean expression or an // AssertionResult. For more information on how to use AssertionResult with // these macros see comments on that class. -#define EXPECT_TRUE(condition) \ - GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ - GTEST_NONFATAL_FAILURE_) -#define EXPECT_FALSE(condition) \ - GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ - GTEST_NONFATAL_FAILURE_) -#define ASSERT_TRUE(condition) \ - GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ - GTEST_FATAL_FAILURE_) -#define ASSERT_FALSE(condition) \ - GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ - GTEST_FATAL_FAILURE_) +#define EXPECT_TRUE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ + GTEST_NONFATAL_FAILURE_) +#define EXPECT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ + GTEST_NONFATAL_FAILURE_) +#define ASSERT_TRUE(condition) \ + GTEST_TEST_BOOLEAN_(condition, #condition, false, true, \ + GTEST_FATAL_FAILURE_) +#define ASSERT_FALSE(condition) \ + GTEST_TEST_BOOLEAN_(!(condition), #condition, true, false, \ + GTEST_FATAL_FAILURE_) // Includes the auto-generated header that implements a family of // generic predicate assertion macros. @@ -1974,61 +2046,61 @@ class TestWithParam : public Test, public WithParamInterface { // ASSERT_LT(i, array_size); // ASSERT_GT(records.size(), 0) << "There is no record left."; -#define EXPECT_EQ(expected, actual) \ - EXPECT_PRED_FORMAT2(::testing::internal:: \ - EqHelper::Compare, \ - expected, actual) +#define EXPECT_EQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal:: \ + EqHelper::Compare, \ + expected, actual) #define EXPECT_NE(expected, actual) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual) + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperNE, expected, actual) #define EXPECT_LE(val1, val2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) #define EXPECT_LT(val1, val2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) #define EXPECT_GE(val1, val2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) #define EXPECT_GT(val1, val2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) -#define GTEST_ASSERT_EQ(expected, actual) \ - ASSERT_PRED_FORMAT2(::testing::internal:: \ - EqHelper::Compare, \ - expected, actual) +#define GTEST_ASSERT_EQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal:: \ + EqHelper::Compare, \ + expected, actual) #define GTEST_ASSERT_NE(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperNE, val1, val2) #define GTEST_ASSERT_LE(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val1, val2) #define GTEST_ASSERT_LT(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperLT, val1, val2) #define GTEST_ASSERT_GE(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val1, val2) #define GTEST_ASSERT_GT(val1, val2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperGT, val1, val2) // Define macro GTEST_DONT_DEFINE_ASSERT_XY to 1 to omit the definition of // ASSERT_XY(), which clashes with some users' own code. #if !GTEST_DONT_DEFINE_ASSERT_EQ -# define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2) +#define ASSERT_EQ(val1, val2) GTEST_ASSERT_EQ(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_NE -# define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2) +#define ASSERT_NE(val1, val2) GTEST_ASSERT_NE(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_LE -# define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2) +#define ASSERT_LE(val1, val2) GTEST_ASSERT_LE(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_LT -# define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2) +#define ASSERT_LT(val1, val2) GTEST_ASSERT_LT(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_GE -# define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2) +#define ASSERT_GE(val1, val2) GTEST_ASSERT_GE(val1, val2) #endif #if !GTEST_DONT_DEFINE_ASSERT_GT -# define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2) +#define ASSERT_GT(val1, val2) GTEST_ASSERT_GT(val1, val2) #endif // C-string Comparisons. All tests treat NULL and any non-NULL string @@ -2048,22 +2120,22 @@ class TestWithParam : public Test, public WithParamInterface { // These macros evaluate their arguments exactly once. #define EXPECT_STREQ(expected, actual) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) #define EXPECT_STRNE(s1, s2) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) #define EXPECT_STRCASEEQ(expected, actual) \ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) -#define EXPECT_STRCASENE(s1, s2)\ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) +#define EXPECT_STRCASENE(s1, s2) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) #define ASSERT_STREQ(expected, actual) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTREQ, expected, actual) #define ASSERT_STRNE(s1, s2) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRNE, s1, s2) #define ASSERT_STRCASEEQ(expected, actual) \ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) -#define ASSERT_STRCASENE(s1, s2)\ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASEEQ, expected, actual) +#define ASSERT_STRCASENE(s1, s2) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperSTRCASENE, s1, s2) // Macros for comparing floating-point numbers. // @@ -2079,29 +2151,29 @@ class TestWithParam : public Test, public WithParamInterface { // FloatingPoint template class in gtest-internal.h if you are // interested in the implementation details. -#define EXPECT_FLOAT_EQ(expected, actual)\ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ - expected, actual) +#define EXPECT_FLOAT_EQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) -#define EXPECT_DOUBLE_EQ(expected, actual)\ - EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ - expected, actual) +#define EXPECT_DOUBLE_EQ(expected, actual) \ + EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) -#define ASSERT_FLOAT_EQ(expected, actual)\ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ - expected, actual) +#define ASSERT_FLOAT_EQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) -#define ASSERT_DOUBLE_EQ(expected, actual)\ - ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ - expected, actual) +#define ASSERT_DOUBLE_EQ(expected, actual) \ + ASSERT_PRED_FORMAT2(::testing::internal::CmpHelperFloatingPointEQ, \ + expected, actual) -#define EXPECT_NEAR(val1, val2, abs_error)\ - EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ - val1, val2, abs_error) +#define EXPECT_NEAR(val1, val2, abs_error) \ + EXPECT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ + val1, val2, abs_error) -#define ASSERT_NEAR(val1, val2, abs_error)\ - ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ - val1, val2, abs_error) +#define ASSERT_NEAR(val1, val2, abs_error) \ + ASSERT_PRED_FORMAT3(::testing::internal::DoubleNearPredFormat, \ + val1, val2, abs_error) // These predicate format functions work on floating-point values, and // can be used in {ASSERT|EXPECT}_PRED_FORMAT2*(), e.g. @@ -2111,10 +2183,9 @@ class TestWithParam : public Test, public WithParamInterface { // Asserts that val1 is less than, or almost equal to, val2. Fails // otherwise. In particular, it fails if either val1 or val2 is NaN. GTEST_API_ AssertionResult FloatLE(const char* expr1, const char* expr2, - float val1, float val2); + float val1, float val2); GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, - double val1, double val2); - + double val1, double val2); #if GTEST_OS_WINDOWS @@ -2127,17 +2198,17 @@ GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, // expected result and the actual result with both a human-readable // string representation of the error, if available, as well as the // hex result code. -# define EXPECT_HRESULT_SUCCEEDED(expr) \ - EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) +#define EXPECT_HRESULT_SUCCEEDED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) -# define ASSERT_HRESULT_SUCCEEDED(expr) \ - ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) +#define ASSERT_HRESULT_SUCCEEDED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTSuccess, (expr)) -# define EXPECT_HRESULT_FAILED(expr) \ - EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) +#define EXPECT_HRESULT_FAILED(expr) \ + EXPECT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) -# define ASSERT_HRESULT_FAILED(expr) \ - ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) +#define ASSERT_HRESULT_FAILED(expr) \ + ASSERT_PRED_FORMAT1(::testing::internal::IsHRESULTFailure, (expr)) #endif // GTEST_OS_WINDOWS @@ -2152,9 +2223,9 @@ GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, // ASSERT_NO_FATAL_FAILURE(Process()) << "Process() failed"; // #define ASSERT_NO_FATAL_FAILURE(statement) \ - GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_) + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_FATAL_FAILURE_) #define EXPECT_NO_FATAL_FAILURE(statement) \ - GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_) + GTEST_TEST_NO_FATAL_FAILURE_(statement, GTEST_NONFATAL_FAILURE_) // Causes a trace (including the source file path, the current line // number, and the given message) to be included in every test failure @@ -2167,9 +2238,9 @@ GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, // of the dummy variable name, thus allowing multiple SCOPED_TRACE()s // to appear in the same block - as long as they are on different // lines. -#define SCOPED_TRACE(message) \ - ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)(\ - __FILE__, __LINE__, ::testing::Message() << (message)) +#define SCOPED_TRACE(message) \ + ::testing::internal::ScopedTrace GTEST_CONCAT_TOKEN_(gtest_trace_, __LINE__)( \ + __FILE__, __LINE__, ::testing::Message() << (message)) // Compile-time assertion for type equality. // StaticAssertTypeEq() compiles iff type1 and type2 are @@ -2202,9 +2273,10 @@ GTEST_API_ AssertionResult DoubleLE(const char* expr1, const char* expr2, // // to cause a compiler error. template -bool StaticAssertTypeEq() { - (void)internal::StaticAssertTypeEqHelper(); - return true; +bool StaticAssertTypeEq() +{ + (void)internal::StaticAssertTypeEqHelper(); + return true; } // Defines a test. @@ -2232,14 +2304,14 @@ bool StaticAssertTypeEq() { // code. GetTestTypeId() is guaranteed to always return the same // value, as it always calls GetTypeId<>() from the Google Test // framework. -#define GTEST_TEST(test_case_name, test_name)\ - GTEST_TEST_(test_case_name, test_name, \ - ::testing::Test, ::testing::internal::GetTestTypeId()) +#define GTEST_TEST(test_case_name, test_name) \ + GTEST_TEST_(test_case_name, test_name, \ + ::testing::Test, ::testing::internal::GetTestTypeId()) // Define this macro to 1 to omit the definition of TEST(), which // is a generic name and clashes with some other libraries. #if !GTEST_DONT_DEFINE_TEST -# define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name) +#define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name) #endif // Defines a test that uses a test fixture. @@ -2268,9 +2340,9 @@ bool StaticAssertTypeEq() { // EXPECT_EQ(1, b_.size()); // } -#define TEST_F(test_fixture, test_name)\ - GTEST_TEST_(test_fixture, test_name, test_fixture, \ - ::testing::internal::GetTypeId()) +#define TEST_F(test_fixture, test_name) \ + GTEST_TEST_(test_fixture, test_name, test_fixture, \ + ::testing::internal::GetTypeId()) } // namespace testing @@ -2284,8 +2356,9 @@ bool StaticAssertTypeEq() { // namespace and has an all-caps name. int RUN_ALL_TESTS() GTEST_MUST_USE_RESULT_; -inline int RUN_ALL_TESTS() { - return ::testing::UnitTest::GetInstance()->Run(); +inline int RUN_ALL_TESTS() +{ + return ::testing::UnitTest::GetInstance()->Run(); } #endif // GTEST_INCLUDE_GTEST_GTEST_H_ diff --git a/test/gtest-1.7.0/include/gtest/gtest_pred_impl.h b/test/gtest-1.7.0/include/gtest/gtest_pred_impl.h index 30ae712f5..aa4db7177 100644 --- a/test/gtest-1.7.0/include/gtest/gtest_pred_impl.h +++ b/test/gtest-1.7.0/include/gtest/gtest_pred_impl.h @@ -37,7 +37,7 @@ // Makes sure this header is not included before gtest.h. #ifndef GTEST_INCLUDE_GTEST_GTEST_H_ -# error Do not include gtest_pred_impl.h directly. Include gtest.h instead. +#error Do not include gtest_pred_impl.h directly. Include gtest.h instead. #endif // GTEST_INCLUDE_GTEST_GTEST_H_ // This header implements a family of generic predicate assertion @@ -72,287 +72,301 @@ // GTEST_ASSERT_ is the basic statement to which all of the assertions // in this file reduce. Don't use this in your code. -#define GTEST_ASSERT_(expression, on_failure) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (const ::testing::AssertionResult gtest_ar = (expression)) \ - ; \ - else \ - on_failure(gtest_ar.failure_message()) - +#define GTEST_ASSERT_(expression, on_failure) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar = (expression)) \ + ; \ + else \ + on_failure(gtest_ar.failure_message()) // Helper function for implementing {EXPECT|ASSERT}_PRED1. Don't use // this in your code. template + typename T1> AssertionResult AssertPred1Helper(const char* pred_text, - const char* e1, - Pred pred, - const T1& v1) { - if (pred(v1)) return AssertionSuccess(); + const char* e1, + Pred pred, + const T1& v1) +{ + if (pred(v1)) return AssertionSuccess(); - return AssertionFailure() << pred_text << "(" - << e1 << ") evaluates to false, where" - << "\n" << e1 << " evaluates to " << v1; + return AssertionFailure() << pred_text << "(" + << e1 << ") evaluates to false, where" + << "\n" + << e1 << " evaluates to " << v1; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT1. // Don't use this in your code. -#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure)\ - GTEST_ASSERT_(pred_format(#v1, v1), \ - on_failure) +#define GTEST_PRED_FORMAT1_(pred_format, v1, on_failure) \ + GTEST_ASSERT_(pred_format(#v1, v1), \ + on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED1. Don't use // this in your code. -#define GTEST_PRED1_(pred, v1, on_failure)\ - GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \ - #v1, \ - pred, \ - v1), on_failure) +#define GTEST_PRED1_(pred, v1, on_failure) \ + GTEST_ASSERT_(::testing::AssertPred1Helper(#pred, \ + #v1, \ + pred, \ + v1), \ + on_failure) // Unary predicate assertion macros. #define EXPECT_PRED_FORMAT1(pred_format, v1) \ - GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) + GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED1(pred, v1) \ - GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) + GTEST_PRED1_(pred, v1, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT1(pred_format, v1) \ - GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) + GTEST_PRED_FORMAT1_(pred_format, v1, GTEST_FATAL_FAILURE_) #define ASSERT_PRED1(pred, v1) \ - GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) - - + GTEST_PRED1_(pred, v1, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED2. Don't use // this in your code. template + typename T1, + typename T2> AssertionResult AssertPred2Helper(const char* pred_text, - const char* e1, - const char* e2, - Pred pred, - const T1& v1, - const T2& v2) { - if (pred(v1, v2)) return AssertionSuccess(); + const char* e1, + const char* e2, + Pred pred, + const T1& v1, + const T2& v2) +{ + if (pred(v1, v2)) return AssertionSuccess(); - return AssertionFailure() << pred_text << "(" - << e1 << ", " - << e2 << ") evaluates to false, where" - << "\n" << e1 << " evaluates to " << v1 - << "\n" << e2 << " evaluates to " << v2; + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ") evaluates to false, where" + << "\n" + << e1 << " evaluates to " << v1 + << "\n" + << e2 << " evaluates to " << v2; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT2. // Don't use this in your code. -#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure)\ - GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \ - on_failure) +#define GTEST_PRED_FORMAT2_(pred_format, v1, v2, on_failure) \ + GTEST_ASSERT_(pred_format(#v1, #v2, v1, v2), \ + on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED2. Don't use // this in your code. -#define GTEST_PRED2_(pred, v1, v2, on_failure)\ - GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \ - #v1, \ - #v2, \ - pred, \ - v1, \ - v2), on_failure) +#define GTEST_PRED2_(pred, v1, v2, on_failure) \ + GTEST_ASSERT_(::testing::AssertPred2Helper(#pred, \ + #v1, \ + #v2, \ + pred, \ + v1, \ + v2), \ + on_failure) // Binary predicate assertion macros. #define EXPECT_PRED_FORMAT2(pred_format, v1, v2) \ - GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) + GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED2(pred, v1, v2) \ - GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_) + GTEST_PRED2_(pred, v1, v2, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT2(pred_format, v1, v2) \ - GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) + GTEST_PRED_FORMAT2_(pred_format, v1, v2, GTEST_FATAL_FAILURE_) #define ASSERT_PRED2(pred, v1, v2) \ - GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) - - + GTEST_PRED2_(pred, v1, v2, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED3. Don't use // this in your code. template + typename T1, + typename T2, + typename T3> AssertionResult AssertPred3Helper(const char* pred_text, - const char* e1, - const char* e2, - const char* e3, - Pred pred, - const T1& v1, - const T2& v2, - const T3& v3) { - if (pred(v1, v2, v3)) return AssertionSuccess(); + const char* e1, + const char* e2, + const char* e3, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3) +{ + if (pred(v1, v2, v3)) return AssertionSuccess(); - return AssertionFailure() << pred_text << "(" - << e1 << ", " - << e2 << ", " - << e3 << ") evaluates to false, where" - << "\n" << e1 << " evaluates to " << v1 - << "\n" << e2 << " evaluates to " << v2 - << "\n" << e3 << " evaluates to " << v3; + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ") evaluates to false, where" + << "\n" + << e1 << " evaluates to " << v1 + << "\n" + << e2 << " evaluates to " << v2 + << "\n" + << e3 << " evaluates to " << v3; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT3. // Don't use this in your code. -#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure)\ - GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \ - on_failure) +#define GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, on_failure) \ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, v1, v2, v3), \ + on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED3. Don't use // this in your code. -#define GTEST_PRED3_(pred, v1, v2, v3, on_failure)\ - GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \ - #v1, \ - #v2, \ - #v3, \ - pred, \ - v1, \ - v2, \ - v3), on_failure) +#define GTEST_PRED3_(pred, v1, v2, v3, on_failure) \ + GTEST_ASSERT_(::testing::AssertPred3Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + pred, \ + v1, \ + v2, \ + v3), \ + on_failure) // Ternary predicate assertion macros. #define EXPECT_PRED_FORMAT3(pred_format, v1, v2, v3) \ - GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_) + GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED3(pred, v1, v2, v3) \ - GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_) + GTEST_PRED3_(pred, v1, v2, v3, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT3(pred_format, v1, v2, v3) \ - GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_) + GTEST_PRED_FORMAT3_(pred_format, v1, v2, v3, GTEST_FATAL_FAILURE_) #define ASSERT_PRED3(pred, v1, v2, v3) \ - GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) - - + GTEST_PRED3_(pred, v1, v2, v3, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED4. Don't use // this in your code. template + typename T1, + typename T2, + typename T3, + typename T4> AssertionResult AssertPred4Helper(const char* pred_text, - const char* e1, - const char* e2, - const char* e3, - const char* e4, - Pred pred, - const T1& v1, - const T2& v2, - const T3& v3, - const T4& v4) { - if (pred(v1, v2, v3, v4)) return AssertionSuccess(); + const char* e1, + const char* e2, + const char* e3, + const char* e4, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4) +{ + if (pred(v1, v2, v3, v4)) return AssertionSuccess(); - return AssertionFailure() << pred_text << "(" - << e1 << ", " - << e2 << ", " - << e3 << ", " - << e4 << ") evaluates to false, where" - << "\n" << e1 << " evaluates to " << v1 - << "\n" << e2 << " evaluates to " << v2 - << "\n" << e3 << " evaluates to " << v3 - << "\n" << e4 << " evaluates to " << v4; + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ", " + << e4 << ") evaluates to false, where" + << "\n" + << e1 << " evaluates to " << v1 + << "\n" + << e2 << " evaluates to " << v2 + << "\n" + << e3 << " evaluates to " << v3 + << "\n" + << e4 << " evaluates to " << v4; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT4. // Don't use this in your code. -#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure)\ - GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \ - on_failure) +#define GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, on_failure) \ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, v1, v2, v3, v4), \ + on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED4. Don't use // this in your code. -#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure)\ - GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \ - #v1, \ - #v2, \ - #v3, \ - #v4, \ - pred, \ - v1, \ - v2, \ - v3, \ - v4), on_failure) +#define GTEST_PRED4_(pred, v1, v2, v3, v4, on_failure) \ + GTEST_ASSERT_(::testing::AssertPred4Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + #v4, \ + pred, \ + v1, \ + v2, \ + v3, \ + v4), \ + on_failure) // 4-ary predicate assertion macros. #define EXPECT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ - GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) + GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED4(pred, v1, v2, v3, v4) \ - GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) + GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT4(pred_format, v1, v2, v3, v4) \ - GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) + GTEST_PRED_FORMAT4_(pred_format, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) #define ASSERT_PRED4(pred, v1, v2, v3, v4) \ - GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) - - + GTEST_PRED4_(pred, v1, v2, v3, v4, GTEST_FATAL_FAILURE_) // Helper function for implementing {EXPECT|ASSERT}_PRED5. Don't use // this in your code. template + typename T1, + typename T2, + typename T3, + typename T4, + typename T5> AssertionResult AssertPred5Helper(const char* pred_text, - const char* e1, - const char* e2, - const char* e3, - const char* e4, - const char* e5, - Pred pred, - const T1& v1, - const T2& v2, - const T3& v3, - const T4& v4, - const T5& v5) { - if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); + const char* e1, + const char* e2, + const char* e3, + const char* e4, + const char* e5, + Pred pred, + const T1& v1, + const T2& v2, + const T3& v3, + const T4& v4, + const T5& v5) +{ + if (pred(v1, v2, v3, v4, v5)) return AssertionSuccess(); - return AssertionFailure() << pred_text << "(" - << e1 << ", " - << e2 << ", " - << e3 << ", " - << e4 << ", " - << e5 << ") evaluates to false, where" - << "\n" << e1 << " evaluates to " << v1 - << "\n" << e2 << " evaluates to " << v2 - << "\n" << e3 << " evaluates to " << v3 - << "\n" << e4 << " evaluates to " << v4 - << "\n" << e5 << " evaluates to " << v5; + return AssertionFailure() << pred_text << "(" + << e1 << ", " + << e2 << ", " + << e3 << ", " + << e4 << ", " + << e5 << ") evaluates to false, where" + << "\n" + << e1 << " evaluates to " << v1 + << "\n" + << e2 << " evaluates to " << v2 + << "\n" + << e3 << " evaluates to " << v3 + << "\n" + << e4 << " evaluates to " << v4 + << "\n" + << e5 << " evaluates to " << v5; } // Internal macro for implementing {EXPECT|ASSERT}_PRED_FORMAT5. // Don't use this in your code. -#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure)\ - GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \ - on_failure) +#define GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, on_failure) \ + GTEST_ASSERT_(pred_format(#v1, #v2, #v3, #v4, #v5, v1, v2, v3, v4, v5), \ + on_failure) // Internal macro for implementing {EXPECT|ASSERT}_PRED5. Don't use // this in your code. -#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure)\ - GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \ - #v1, \ - #v2, \ - #v3, \ - #v4, \ - #v5, \ - pred, \ - v1, \ - v2, \ - v3, \ - v4, \ - v5), on_failure) +#define GTEST_PRED5_(pred, v1, v2, v3, v4, v5, on_failure) \ + GTEST_ASSERT_(::testing::AssertPred5Helper(#pred, \ + #v1, \ + #v2, \ + #v3, \ + #v4, \ + #v5, \ + pred, \ + v1, \ + v2, \ + v3, \ + v4, \ + v5), \ + on_failure) // 5-ary predicate assertion macros. #define EXPECT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ - GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) + GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) #define EXPECT_PRED5(pred, v1, v2, v3, v4, v5) \ - GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) + GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_NONFATAL_FAILURE_) #define ASSERT_PRED_FORMAT5(pred_format, v1, v2, v3, v4, v5) \ - GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) + GTEST_PRED_FORMAT5_(pred_format, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) #define ASSERT_PRED5(pred, v1, v2, v3, v4, v5) \ - GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) - - + GTEST_PRED5_(pred, v1, v2, v3, v4, v5, GTEST_FATAL_FAILURE_) #endif // GTEST_INCLUDE_GTEST_GTEST_PRED_IMPL_H_ diff --git a/test/gtest-1.7.0/include/gtest/gtest_prod.h b/test/gtest-1.7.0/include/gtest/gtest_prod.h index da80ddc6c..f4eec82c8 100644 --- a/test/gtest-1.7.0/include/gtest/gtest_prod.h +++ b/test/gtest-1.7.0/include/gtest/gtest_prod.h @@ -52,7 +52,7 @@ // // Can call MyClass::MyMethod() here. // } -#define FRIEND_TEST(test_case_name, test_name)\ -friend class test_case_name##_##test_name##_Test +#define FRIEND_TEST(test_case_name, test_name) \ + friend class test_case_name##_##test_name##_Test #endif // GTEST_INCLUDE_GTEST_GTEST_PROD_H_ diff --git a/test/gtest-1.7.0/include/gtest/internal/gtest-death-test-internal.h b/test/gtest-1.7.0/include/gtest/internal/gtest-death-test-internal.h index 2b3a78f5b..249201a85 100644 --- a/test/gtest-1.7.0/include/gtest/internal/gtest-death-test-internal.h +++ b/test/gtest-1.7.0/include/gtest/internal/gtest-death-test-internal.h @@ -41,9 +41,10 @@ #include -namespace testing { -namespace internal { - +namespace testing +{ +namespace internal +{ GTEST_DECLARE_string_(internal_run_death_test); // Names of the flags (needed for parsing Google Test flags). @@ -66,89 +67,99 @@ const char kInternalRunDeathTestFlag[] = "internal_run_death_test"; // by wait(2) // exit code: The integer code passed to exit(3), _exit(2), or // returned from main() -class GTEST_API_ DeathTest { - public: - // Create returns false if there was an error determining the - // appropriate action to take for the current death test; for example, - // if the gtest_death_test_style flag is set to an invalid value. - // The LastMessage method will return a more detailed message in that - // case. Otherwise, the DeathTest pointer pointed to by the "test" - // argument is set. If the death test should be skipped, the pointer - // is set to NULL; otherwise, it is set to the address of a new concrete - // DeathTest object that controls the execution of the current test. - static bool Create(const char* statement, const RE* regex, - const char* file, int line, DeathTest** test); - DeathTest(); - virtual ~DeathTest() { } +class GTEST_API_ DeathTest +{ +public: + // Create returns false if there was an error determining the + // appropriate action to take for the current death test; for example, + // if the gtest_death_test_style flag is set to an invalid value. + // The LastMessage method will return a more detailed message in that + // case. Otherwise, the DeathTest pointer pointed to by the "test" + // argument is set. If the death test should be skipped, the pointer + // is set to NULL; otherwise, it is set to the address of a new concrete + // DeathTest object that controls the execution of the current test. + static bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test); + DeathTest(); + virtual ~DeathTest() {} - // A helper class that aborts a death test when it's deleted. - class ReturnSentinel { - public: - explicit ReturnSentinel(DeathTest* test) : test_(test) { } - ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } - private: - DeathTest* const test_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); - } GTEST_ATTRIBUTE_UNUSED_; + // A helper class that aborts a death test when it's deleted. + class ReturnSentinel + { + public: + explicit ReturnSentinel(DeathTest* test) : test_(test) {} + ~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); } - // An enumeration of possible roles that may be taken when a death - // test is encountered. EXECUTE means that the death test logic should - // be executed immediately. OVERSEE means that the program should prepare - // the appropriate environment for a child process to execute the death - // test, then wait for it to complete. - enum TestRole { OVERSEE_TEST, EXECUTE_TEST }; + private: + DeathTest* const test_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel); + } GTEST_ATTRIBUTE_UNUSED_; - // An enumeration of the three reasons that a test might be aborted. - enum AbortReason { - TEST_ENCOUNTERED_RETURN_STATEMENT, - TEST_THREW_EXCEPTION, - TEST_DID_NOT_DIE - }; + // An enumeration of possible roles that may be taken when a death + // test is encountered. EXECUTE means that the death test logic should + // be executed immediately. OVERSEE means that the program should prepare + // the appropriate environment for a child process to execute the death + // test, then wait for it to complete. + enum TestRole + { + OVERSEE_TEST, + EXECUTE_TEST + }; - // Assumes one of the above roles. - virtual TestRole AssumeRole() = 0; + // An enumeration of the three reasons that a test might be aborted. + enum AbortReason + { + TEST_ENCOUNTERED_RETURN_STATEMENT, + TEST_THREW_EXCEPTION, + TEST_DID_NOT_DIE + }; - // Waits for the death test to finish and returns its status. - virtual int Wait() = 0; + // Assumes one of the above roles. + virtual TestRole AssumeRole() = 0; - // Returns true if the death test passed; that is, the test process - // exited during the test, its exit status matches a user-supplied - // predicate, and its stderr output matches a user-supplied regular - // expression. - // The user-supplied predicate may be a macro expression rather - // than a function pointer or functor, or else Wait and Passed could - // be combined. - virtual bool Passed(bool exit_status_ok) = 0; + // Waits for the death test to finish and returns its status. + virtual int Wait() = 0; - // Signals that the death test did not die as expected. - virtual void Abort(AbortReason reason) = 0; + // Returns true if the death test passed; that is, the test process + // exited during the test, its exit status matches a user-supplied + // predicate, and its stderr output matches a user-supplied regular + // expression. + // The user-supplied predicate may be a macro expression rather + // than a function pointer or functor, or else Wait and Passed could + // be combined. + virtual bool Passed(bool exit_status_ok) = 0; - // Returns a human-readable outcome message regarding the outcome of - // the last death test. - static const char* LastMessage(); + // Signals that the death test did not die as expected. + virtual void Abort(AbortReason reason) = 0; - static void set_last_death_test_message(const std::string& message); + // Returns a human-readable outcome message regarding the outcome of + // the last death test. + static const char* LastMessage(); - private: - // A string containing a description of the outcome of the last death test. - static std::string last_death_test_message_; + static void set_last_death_test_message(const std::string& message); - GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); +private: + // A string containing a description of the outcome of the last death test. + static std::string last_death_test_message_; + + GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest); }; // Factory interface for death tests. May be mocked out for testing. -class DeathTestFactory { - public: - virtual ~DeathTestFactory() { } - virtual bool Create(const char* statement, const RE* regex, - const char* file, int line, DeathTest** test) = 0; +class DeathTestFactory +{ +public: + virtual ~DeathTestFactory() {} + virtual bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test) = 0; }; // A concrete DeathTestFactory implementation for normal use. -class DefaultDeathTestFactory : public DeathTestFactory { - public: - virtual bool Create(const char* statement, const RE* regex, - const char* file, int line, DeathTest** test); +class DefaultDeathTestFactory : public DeathTestFactory +{ +public: + virtual bool Create(const char* statement, const RE* regex, + const char* file, int line, DeathTest** test); }; // Returns true if exit_status describes a process that was terminated @@ -157,63 +168,74 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status); // Traps C++ exceptions escaping statement and reports them as test // failures. Note that trapping SEH exceptions is not implemented here. -# if GTEST_HAS_EXCEPTIONS -# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } catch (const ::std::exception& gtest_exception) { \ - fprintf(\ - stderr, \ - "\n%s: Caught std::exception-derived exception escaping the " \ - "death test statement. Exception message: %s\n", \ - ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \ - gtest_exception.what()); \ - fflush(stderr); \ - death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ - } catch (...) { \ - death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ - } +#if GTEST_HAS_EXCEPTIONS +#define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ + try \ + { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (const ::std::exception& gtest_exception) \ + { \ + fprintf( \ + stderr, \ + "\n%s: Caught std::exception-derived exception escaping the " \ + "death test statement. Exception message: %s\n", \ + ::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \ + gtest_exception.what()); \ + fflush(stderr); \ + death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ + } \ + catch (...) \ + { \ + death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \ + } -# else -# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) +#else +#define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) -# endif +#endif // This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*, // ASSERT_EXIT*, and EXPECT_EXIT*. -# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::AlwaysTrue()) { \ - const ::testing::internal::RE& gtest_regex = (regex); \ - ::testing::internal::DeathTest* gtest_dt; \ - if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ - __FILE__, __LINE__, >est_dt)) { \ - goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ - } \ - if (gtest_dt != NULL) { \ - ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \ - gtest_dt_ptr(gtest_dt); \ - switch (gtest_dt->AssumeRole()) { \ - case ::testing::internal::DeathTest::OVERSEE_TEST: \ - if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \ - goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ - } \ - break; \ - case ::testing::internal::DeathTest::EXECUTE_TEST: { \ - ::testing::internal::DeathTest::ReturnSentinel \ - gtest_sentinel(gtest_dt); \ - GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \ - gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ - break; \ - } \ - default: \ - break; \ - } \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \ - fail(::testing::internal::DeathTest::LastMessage()) +#define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) \ + { \ + const ::testing::internal::RE& gtest_regex = (regex); \ + ::testing::internal::DeathTest* gtest_dt; \ + if (!::testing::internal::DeathTest::Create(#statement, >est_regex, \ + __FILE__, __LINE__, >est_dt)) \ + { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ + } \ + if (gtest_dt != NULL) \ + { \ + ::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \ + gtest_dt_ptr(gtest_dt); \ + switch (gtest_dt->AssumeRole()) \ + { \ + case ::testing::internal::DeathTest::OVERSEE_TEST: \ + if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) \ + { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \ + } \ + break; \ + case ::testing::internal::DeathTest::EXECUTE_TEST: \ + { \ + ::testing::internal::DeathTest::ReturnSentinel \ + gtest_sentinel(gtest_dt); \ + GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \ + gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \ + break; \ + } \ + default: \ + break; \ + } \ + } \ + } \ + else \ + GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__) : fail(::testing::internal::DeathTest::LastMessage()) // The symbol "fail" here expands to something into which a message // can be streamed. @@ -221,42 +243,45 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status); // NDEBUG mode. In this case we need the statements to be executed, the regex is // ignored, and the macro must accept a streamed message even though the message // is never printed. -# define GTEST_EXECUTE_STATEMENT_(statement, regex) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::AlwaysTrue()) { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } else \ - ::testing::Message() +#define GTEST_EXECUTE_STATEMENT_(statement, regex) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) \ + { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + else \ + ::testing::Message() // A class representing the parsed contents of the // --gtest_internal_run_death_test flag, as it existed when // RUN_ALL_TESTS was called. -class InternalRunDeathTestFlag { - public: - InternalRunDeathTestFlag(const std::string& a_file, - int a_line, - int an_index, - int a_write_fd) - : file_(a_file), line_(a_line), index_(an_index), - write_fd_(a_write_fd) {} +class InternalRunDeathTestFlag +{ +public: + InternalRunDeathTestFlag(const std::string& a_file, + int a_line, + int an_index, + int a_write_fd) + : file_(a_file), line_(a_line), index_(an_index), write_fd_(a_write_fd) {} - ~InternalRunDeathTestFlag() { - if (write_fd_ >= 0) - posix::Close(write_fd_); - } + ~InternalRunDeathTestFlag() + { + if (write_fd_ >= 0) + posix::Close(write_fd_); + } - const std::string& file() const { return file_; } - int line() const { return line_; } - int index() const { return index_; } - int write_fd() const { return write_fd_; } + const std::string& file() const { return file_; } + int line() const { return line_; } + int index() const { return index_; } + int write_fd() const { return write_fd_; } - private: - std::string file_; - int line_; - int index_; - int write_fd_; +private: + std::string file_; + int line_; + int index_; + int write_fd_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); + GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag); }; // Returns a newly created InternalRunDeathTestFlag object with fields @@ -298,18 +323,22 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag(); // statement unconditionally returns or throws. The Message constructor at // the end allows the syntax of streaming additional messages into the // macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH. -# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::AlwaysTrue()) { \ - GTEST_LOG_(WARNING) \ - << "Death tests are not supported on this platform.\n" \ - << "Statement '" #statement "' cannot be verified."; \ - } else if (::testing::internal::AlwaysFalse()) { \ - ::testing::internal::RE::PartialMatch(".*", (regex)); \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - terminator; \ - } else \ - ::testing::Message() +#define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) \ + { \ + GTEST_LOG_(WARNING) \ + << "Death tests are not supported on this platform.\n" \ + << "Statement '" #statement "' cannot be verified."; \ + } \ + else if (::testing::internal::AlwaysFalse()) \ + { \ + ::testing::internal::RE::PartialMatch(".*", (regex)); \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + terminator; \ + } \ + else \ + ::testing::Message() #endif // GTEST_HAS_DEATH_TEST diff --git a/test/gtest-1.7.0/include/gtest/internal/gtest-filepath.h b/test/gtest-1.7.0/include/gtest/internal/gtest-filepath.h index 7a13b4b0d..89c4dc3d8 100644 --- a/test/gtest-1.7.0/include/gtest/internal/gtest-filepath.h +++ b/test/gtest-1.7.0/include/gtest/internal/gtest-filepath.h @@ -42,9 +42,10 @@ #include "gtest/internal/gtest-string.h" -namespace testing { -namespace internal { - +namespace testing +{ +namespace internal +{ // FilePath - a class for file and directory pathname manipulation which // handles platform-specific conventions (like the pathname separator). // Used for helper functions for naming files in a directory for xml output. @@ -56,148 +57,152 @@ namespace internal { // Names are NOT checked for syntax correctness -- no checking for illegal // characters, malformed paths, etc. -class GTEST_API_ FilePath { - public: - FilePath() : pathname_("") { } - FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { } +class GTEST_API_ FilePath +{ +public: + FilePath() : pathname_("") {} + FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {} - explicit FilePath(const std::string& pathname) : pathname_(pathname) { - Normalize(); - } + explicit FilePath(const std::string& pathname) : pathname_(pathname) + { + Normalize(); + } - FilePath& operator=(const FilePath& rhs) { - Set(rhs); - return *this; - } + FilePath& operator=(const FilePath& rhs) + { + Set(rhs); + return *this; + } - void Set(const FilePath& rhs) { - pathname_ = rhs.pathname_; - } + void Set(const FilePath& rhs) + { + pathname_ = rhs.pathname_; + } - const std::string& string() const { return pathname_; } - const char* c_str() const { return pathname_.c_str(); } + const std::string& string() const { return pathname_; } + const char* c_str() const { return pathname_.c_str(); } - // Returns the current working directory, or "" if unsuccessful. - static FilePath GetCurrentDir(); + // Returns the current working directory, or "" if unsuccessful. + static FilePath GetCurrentDir(); - // Given directory = "dir", base_name = "test", number = 0, - // extension = "xml", returns "dir/test.xml". If number is greater - // than zero (e.g., 12), returns "dir/test_12.xml". - // On Windows platform, uses \ as the separator rather than /. - static FilePath MakeFileName(const FilePath& directory, - const FilePath& base_name, - int number, - const char* extension); + // Given directory = "dir", base_name = "test", number = 0, + // extension = "xml", returns "dir/test.xml". If number is greater + // than zero (e.g., 12), returns "dir/test_12.xml". + // On Windows platform, uses \ as the separator rather than /. + static FilePath MakeFileName(const FilePath& directory, + const FilePath& base_name, + int number, + const char* extension); - // Given directory = "dir", relative_path = "test.xml", - // returns "dir/test.xml". - // On Windows, uses \ as the separator rather than /. - static FilePath ConcatPaths(const FilePath& directory, - const FilePath& relative_path); + // Given directory = "dir", relative_path = "test.xml", + // returns "dir/test.xml". + // On Windows, uses \ as the separator rather than /. + static FilePath ConcatPaths(const FilePath& directory, + const FilePath& relative_path); - // Returns a pathname for a file that does not currently exist. The pathname - // will be directory/base_name.extension or - // directory/base_name_.extension if directory/base_name.extension - // already exists. The number will be incremented until a pathname is found - // that does not already exist. - // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. - // There could be a race condition if two or more processes are calling this - // function at the same time -- they could both pick the same filename. - static FilePath GenerateUniqueFileName(const FilePath& directory, - const FilePath& base_name, - const char* extension); + // Returns a pathname for a file that does not currently exist. The pathname + // will be directory/base_name.extension or + // directory/base_name_.extension if directory/base_name.extension + // already exists. The number will be incremented until a pathname is found + // that does not already exist. + // Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'. + // There could be a race condition if two or more processes are calling this + // function at the same time -- they could both pick the same filename. + static FilePath GenerateUniqueFileName(const FilePath& directory, + const FilePath& base_name, + const char* extension); - // Returns true iff the path is "". - bool IsEmpty() const { return pathname_.empty(); } + // Returns true iff the path is "". + bool IsEmpty() const { return pathname_.empty(); } - // If input name has a trailing separator character, removes it and returns - // the name, otherwise return the name string unmodified. - // On Windows platform, uses \ as the separator, other platforms use /. - FilePath RemoveTrailingPathSeparator() const; + // If input name has a trailing separator character, removes it and returns + // the name, otherwise return the name string unmodified. + // On Windows platform, uses \ as the separator, other platforms use /. + FilePath RemoveTrailingPathSeparator() const; - // Returns a copy of the FilePath with the directory part removed. - // Example: FilePath("path/to/file").RemoveDirectoryName() returns - // FilePath("file"). If there is no directory part ("just_a_file"), it returns - // the FilePath unmodified. If there is no file part ("just_a_dir/") it - // returns an empty FilePath (""). - // On Windows platform, '\' is the path separator, otherwise it is '/'. - FilePath RemoveDirectoryName() const; + // Returns a copy of the FilePath with the directory part removed. + // Example: FilePath("path/to/file").RemoveDirectoryName() returns + // FilePath("file"). If there is no directory part ("just_a_file"), it returns + // the FilePath unmodified. If there is no file part ("just_a_dir/") it + // returns an empty FilePath (""). + // On Windows platform, '\' is the path separator, otherwise it is '/'. + FilePath RemoveDirectoryName() const; - // RemoveFileName returns the directory path with the filename removed. - // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". - // If the FilePath is "a_file" or "/a_file", RemoveFileName returns - // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does - // not have a file, like "just/a/dir/", it returns the FilePath unmodified. - // On Windows platform, '\' is the path separator, otherwise it is '/'. - FilePath RemoveFileName() const; + // RemoveFileName returns the directory path with the filename removed. + // Example: FilePath("path/to/file").RemoveFileName() returns "path/to/". + // If the FilePath is "a_file" or "/a_file", RemoveFileName returns + // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does + // not have a file, like "just/a/dir/", it returns the FilePath unmodified. + // On Windows platform, '\' is the path separator, otherwise it is '/'. + FilePath RemoveFileName() const; - // Returns a copy of the FilePath with the case-insensitive extension removed. - // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns - // FilePath("dir/file"). If a case-insensitive extension is not - // found, returns a copy of the original FilePath. - FilePath RemoveExtension(const char* extension) const; + // Returns a copy of the FilePath with the case-insensitive extension removed. + // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns + // FilePath("dir/file"). If a case-insensitive extension is not + // found, returns a copy of the original FilePath. + FilePath RemoveExtension(const char* extension) const; - // Creates directories so that path exists. Returns true if successful or if - // the directories already exist; returns false if unable to create - // directories for any reason. Will also return false if the FilePath does - // not represent a directory (that is, it doesn't end with a path separator). - bool CreateDirectoriesRecursively() const; + // Creates directories so that path exists. Returns true if successful or if + // the directories already exist; returns false if unable to create + // directories for any reason. Will also return false if the FilePath does + // not represent a directory (that is, it doesn't end with a path separator). + bool CreateDirectoriesRecursively() const; - // Create the directory so that path exists. Returns true if successful or - // if the directory already exists; returns false if unable to create the - // directory for any reason, including if the parent directory does not - // exist. Not named "CreateDirectory" because that's a macro on Windows. - bool CreateFolder() const; + // Create the directory so that path exists. Returns true if successful or + // if the directory already exists; returns false if unable to create the + // directory for any reason, including if the parent directory does not + // exist. Not named "CreateDirectory" because that's a macro on Windows. + bool CreateFolder() const; - // Returns true if FilePath describes something in the file-system, - // either a file, directory, or whatever, and that something exists. - bool FileOrDirectoryExists() const; + // Returns true if FilePath describes something in the file-system, + // either a file, directory, or whatever, and that something exists. + bool FileOrDirectoryExists() const; - // Returns true if pathname describes a directory in the file-system - // that exists. - bool DirectoryExists() const; + // Returns true if pathname describes a directory in the file-system + // that exists. + bool DirectoryExists() const; - // Returns true if FilePath ends with a path separator, which indicates that - // it is intended to represent a directory. Returns false otherwise. - // This does NOT check that a directory (or file) actually exists. - bool IsDirectory() const; + // Returns true if FilePath ends with a path separator, which indicates that + // it is intended to represent a directory. Returns false otherwise. + // This does NOT check that a directory (or file) actually exists. + bool IsDirectory() const; - // Returns true if pathname describes a root directory. (Windows has one - // root directory per disk drive.) - bool IsRootDirectory() const; + // Returns true if pathname describes a root directory. (Windows has one + // root directory per disk drive.) + bool IsRootDirectory() const; - // Returns true if pathname describes an absolute path. - bool IsAbsolutePath() const; + // Returns true if pathname describes an absolute path. + bool IsAbsolutePath() const; - private: - // Replaces multiple consecutive separators with a single separator. - // For example, "bar///foo" becomes "bar/foo". Does not eliminate other - // redundancies that might be in a pathname involving "." or "..". - // - // A pathname with multiple consecutive separators may occur either through - // user error or as a result of some scripts or APIs that generate a pathname - // with a trailing separator. On other platforms the same API or script - // may NOT generate a pathname with a trailing "/". Then elsewhere that - // pathname may have another "/" and pathname components added to it, - // without checking for the separator already being there. - // The script language and operating system may allow paths like "foo//bar" - // but some of the functions in FilePath will not handle that correctly. In - // particular, RemoveTrailingPathSeparator() only removes one separator, and - // it is called in CreateDirectoriesRecursively() assuming that it will change - // a pathname from directory syntax (trailing separator) to filename syntax. - // - // On Windows this method also replaces the alternate path separator '/' with - // the primary path separator '\\', so that for example "bar\\/\\foo" becomes - // "bar\\foo". +private: + // Replaces multiple consecutive separators with a single separator. + // For example, "bar///foo" becomes "bar/foo". Does not eliminate other + // redundancies that might be in a pathname involving "." or "..". + // + // A pathname with multiple consecutive separators may occur either through + // user error or as a result of some scripts or APIs that generate a pathname + // with a trailing separator. On other platforms the same API or script + // may NOT generate a pathname with a trailing "/". Then elsewhere that + // pathname may have another "/" and pathname components added to it, + // without checking for the separator already being there. + // The script language and operating system may allow paths like "foo//bar" + // but some of the functions in FilePath will not handle that correctly. In + // particular, RemoveTrailingPathSeparator() only removes one separator, and + // it is called in CreateDirectoriesRecursively() assuming that it will change + // a pathname from directory syntax (trailing separator) to filename syntax. + // + // On Windows this method also replaces the alternate path separator '/' with + // the primary path separator '\\', so that for example "bar\\/\\foo" becomes + // "bar\\foo". - void Normalize(); + void Normalize(); - // Returns a pointer to the last occurence of a valid path separator in - // the FilePath. On Windows, for example, both '/' and '\' are valid path - // separators. Returns NULL if no path separator was found. - const char* FindLastPathSeparator() const; + // Returns a pointer to the last occurence of a valid path separator in + // the FilePath. On Windows, for example, both '/' and '\' are valid path + // separators. Returns NULL if no path separator was found. + const char* FindLastPathSeparator() const; - std::string pathname_; + std::string pathname_; }; // class FilePath } // namespace internal diff --git a/test/gtest-1.7.0/include/gtest/internal/gtest-internal.h b/test/gtest-1.7.0/include/gtest/internal/gtest-internal.h index 0dcc3a319..6c35e03e7 100644 --- a/test/gtest-1.7.0/include/gtest/internal/gtest-internal.h +++ b/test/gtest-1.7.0/include/gtest/internal/gtest-internal.h @@ -40,14 +40,14 @@ #include "gtest/internal/gtest-port.h" #if GTEST_OS_LINUX -# include -# include -# include -# include +#include +#include +#include +#include #endif // GTEST_OS_LINUX #if GTEST_HAS_EXCEPTIONS -# include +#include #endif #include @@ -71,31 +71,34 @@ // the current line number. For more details, see // http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.6 #define GTEST_CONCAT_TOKEN_(foo, bar) GTEST_CONCAT_TOKEN_IMPL_(foo, bar) -#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo ## bar +#define GTEST_CONCAT_TOKEN_IMPL_(foo, bar) foo##bar class ProtocolMessage; -namespace proto2 { class Message; } - -namespace testing { +namespace proto2 +{ +class Message; +} +namespace testing +{ // Forward declarations. -class AssertionResult; // Result of an assertion. -class Message; // Represents a failure message. -class Test; // Represents a test. -class TestInfo; // Information about a test. -class TestPartResult; // Result of a test part. -class UnitTest; // A collection of test cases. +class AssertionResult; // Result of an assertion. +class Message; // Represents a failure message. +class Test; // Represents a test. +class TestInfo; // Information about a test. +class TestPartResult; // Result of a test part. +class UnitTest; // A collection of test cases. template ::std::string PrintToString(const T& value); -namespace internal { - -struct TraceInfo; // Information about a trace point. -class ScopedTrace; // Implements scoped trace. -class TestInfoImpl; // Opaque implementation of TestInfo -class UnitTestImpl; // Opaque implementation of UnitTest +namespace internal +{ +struct TraceInfo; // Information about a trace point. +class ScopedTrace; // Implements scoped trace. +class TestInfoImpl; // Opaque implementation of TestInfo +class UnitTestImpl; // Opaque implementation of UnitTest // How many times InitGoogleTest() has been called. GTEST_API_ extern int g_init_gtest_count; @@ -127,15 +130,15 @@ char (&IsNullLiteralHelper(...))[2]; // NOLINT #ifdef GTEST_ELLIPSIS_NEEDS_POD_ // We lose support for NULL detection where the compiler doesn't like // passing non-POD classes through ellipsis (...). -# define GTEST_IS_NULL_LITERAL_(x) false +#define GTEST_IS_NULL_LITERAL_(x) false #else -# define GTEST_IS_NULL_LITERAL_(x) \ - (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1) +#define GTEST_IS_NULL_LITERAL_(x) \ + (sizeof(::testing::internal::IsNullLiteralHelper(x)) == 1) #endif // GTEST_ELLIPSIS_NEEDS_POD_ // Appends the user-supplied message to the Google-Test-generated message. GTEST_API_ std::string AppendUserMessage( - const std::string& gtest_msg, const Message& user_msg); + const std::string& gtest_msg, const Message& user_msg); #if GTEST_HAS_EXCEPTIONS @@ -145,31 +148,33 @@ GTEST_API_ std::string AppendUserMessage( // errors presumably detectable only at run time. Since // std::runtime_error inherits from std::exception, many testing // frameworks know how to extract and print the message inside it. -class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error { - public: - explicit GoogleTestFailureException(const TestPartResult& failure); +class GTEST_API_ GoogleTestFailureException : public ::std::runtime_error +{ +public: + explicit GoogleTestFailureException(const TestPartResult& failure); }; #endif // GTEST_HAS_EXCEPTIONS // A helper class for creating scoped traces in user programs. -class GTEST_API_ ScopedTrace { - public: - // The c'tor pushes the given source file location and message onto - // a trace stack maintained by Google Test. - ScopedTrace(const char* file, int line, const Message& message); +class GTEST_API_ ScopedTrace +{ +public: + // The c'tor pushes the given source file location and message onto + // a trace stack maintained by Google Test. + ScopedTrace(const char* file, int line, const Message& message); - // The d'tor pops the info pushed by the c'tor. - // - // Note that the d'tor is not virtual in order to be efficient. - // Don't inherit from ScopedTrace! - ~ScopedTrace(); + // The d'tor pops the info pushed by the c'tor. + // + // Note that the d'tor is not virtual in order to be efficient. + // Don't inherit from ScopedTrace! + ~ScopedTrace(); - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace); +private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedTrace); } GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its - // c'tor and d'tor. Therefore it doesn't - // need to be used otherwise. + // c'tor and d'tor. Therefore it doesn't + // need to be used otherwise. // Constructs and returns the message for an equality assertion // (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. @@ -187,17 +192,17 @@ class GTEST_API_ ScopedTrace { // *_STRCASEEQ*. When it's true, the string " (ignoring case)" will // be inserted into the message. GTEST_API_ AssertionResult EqFailure(const char* expected_expression, - const char* actual_expression, - const std::string& expected_value, - const std::string& actual_value, - bool ignoring_case); + const char* actual_expression, + const std::string& expected_value, + const std::string& actual_value, + bool ignoring_case); // Constructs a failure message for Boolean assertions such as EXPECT_TRUE. GTEST_API_ std::string GetBoolAssertionFailureMessage( - const AssertionResult& assertion_result, - const char* expression_text, - const char* actual_predicate_value, - const char* expected_predicate_value); + const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value); // This template class represents an IEEE floating-point number // (either single-precision or double-precision, depending on the @@ -229,161 +234,176 @@ GTEST_API_ std::string GetBoolAssertionFailureMessage( // // RawType: the raw floating-point type (either float or double) template -class FloatingPoint { - public: - // Defines the unsigned integer type that has the same size as the - // floating point number. - typedef typename TypeWithSize::UInt Bits; +class FloatingPoint +{ +public: + // Defines the unsigned integer type that has the same size as the + // floating point number. + typedef typename TypeWithSize::UInt Bits; - // Constants. + // Constants. - // # of bits in a number. - static const size_t kBitCount = 8*sizeof(RawType); + // # of bits in a number. + static const size_t kBitCount = 8 * sizeof(RawType); - // # of fraction bits in a number. - static const size_t kFractionBitCount = - std::numeric_limits::digits - 1; + // # of fraction bits in a number. + static const size_t kFractionBitCount = + std::numeric_limits::digits - 1; - // # of exponent bits in a number. - static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; + // # of exponent bits in a number. + static const size_t kExponentBitCount = kBitCount - 1 - kFractionBitCount; - // The mask for the sign bit. - static const Bits kSignBitMask = static_cast(1) << (kBitCount - 1); + // The mask for the sign bit. + static const Bits kSignBitMask = static_cast(1) << (kBitCount - 1); - // The mask for the fraction bits. - static const Bits kFractionBitMask = - ~static_cast(0) >> (kExponentBitCount + 1); + // The mask for the fraction bits. + static const Bits kFractionBitMask = + ~static_cast(0) >> (kExponentBitCount + 1); - // The mask for the exponent bits. - static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); + // The mask for the exponent bits. + static const Bits kExponentBitMask = ~(kSignBitMask | kFractionBitMask); - // How many ULP's (Units in the Last Place) we want to tolerate when - // comparing two numbers. The larger the value, the more error we - // allow. A 0 value means that two numbers must be exactly the same - // to be considered equal. - // - // The maximum error of a single floating-point operation is 0.5 - // units in the last place. On Intel CPU's, all floating-point - // calculations are done with 80-bit precision, while double has 64 - // bits. Therefore, 4 should be enough for ordinary use. - // - // See the following article for more details on ULP: - // http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ - static const size_t kMaxUlps = 4; + // How many ULP's (Units in the Last Place) we want to tolerate when + // comparing two numbers. The larger the value, the more error we + // allow. A 0 value means that two numbers must be exactly the same + // to be considered equal. + // + // The maximum error of a single floating-point operation is 0.5 + // units in the last place. On Intel CPU's, all floating-point + // calculations are done with 80-bit precision, while double has 64 + // bits. Therefore, 4 should be enough for ordinary use. + // + // See the following article for more details on ULP: + // http://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ + static const size_t kMaxUlps = 4; - // Constructs a FloatingPoint from a raw floating-point number. - // - // On an Intel CPU, passing a non-normalized NAN (Not a Number) - // around may change its bits, although the new value is guaranteed - // to be also a NAN. Therefore, don't expect this constructor to - // preserve the bits in x when x is a NAN. - explicit FloatingPoint(const RawType& x) { u_.value_ = x; } + // Constructs a FloatingPoint from a raw floating-point number. + // + // On an Intel CPU, passing a non-normalized NAN (Not a Number) + // around may change its bits, although the new value is guaranteed + // to be also a NAN. Therefore, don't expect this constructor to + // preserve the bits in x when x is a NAN. + explicit FloatingPoint(const RawType& x) { u_.value_ = x; } - // Static methods + // Static methods - // Reinterprets a bit pattern as a floating-point number. - // - // This function is needed to test the AlmostEquals() method. - static RawType ReinterpretBits(const Bits bits) { - FloatingPoint fp(0); - fp.u_.bits_ = bits; - return fp.u_.value_; - } + // Reinterprets a bit pattern as a floating-point number. + // + // This function is needed to test the AlmostEquals() method. + static RawType ReinterpretBits(const Bits bits) + { + FloatingPoint fp(0); + fp.u_.bits_ = bits; + return fp.u_.value_; + } - // Returns the floating-point number that represent positive infinity. - static RawType Infinity() { - return ReinterpretBits(kExponentBitMask); - } + // Returns the floating-point number that represent positive infinity. + static RawType Infinity() + { + return ReinterpretBits(kExponentBitMask); + } - // Returns the maximum representable finite floating-point number. - static RawType Max(); + // Returns the maximum representable finite floating-point number. + static RawType Max(); - // Non-static methods + // Non-static methods - // Returns the bits that represents this number. - const Bits &bits() const { return u_.bits_; } + // Returns the bits that represents this number. + const Bits& bits() const { return u_.bits_; } - // Returns the exponent bits of this number. - Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } + // Returns the exponent bits of this number. + Bits exponent_bits() const { return kExponentBitMask & u_.bits_; } - // Returns the fraction bits of this number. - Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } + // Returns the fraction bits of this number. + Bits fraction_bits() const { return kFractionBitMask & u_.bits_; } - // Returns the sign bit of this number. - Bits sign_bit() const { return kSignBitMask & u_.bits_; } + // Returns the sign bit of this number. + Bits sign_bit() const { return kSignBitMask & u_.bits_; } - // Returns true iff this is NAN (not a number). - bool is_nan() const { - // It's a NAN if the exponent bits are all ones and the fraction - // bits are not entirely zeros. - return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0); - } + // Returns true iff this is NAN (not a number). + bool is_nan() const + { + // It's a NAN if the exponent bits are all ones and the fraction + // bits are not entirely zeros. + return (exponent_bits() == kExponentBitMask) && (fraction_bits() != 0); + } - // Returns true iff this number is at most kMaxUlps ULP's away from - // rhs. In particular, this function: - // - // - returns false if either number is (or both are) NAN. - // - treats really large numbers as almost equal to infinity. - // - thinks +0.0 and -0.0 are 0 DLP's apart. - bool AlmostEquals(const FloatingPoint& rhs) const { - // The IEEE standard says that any comparison operation involving - // a NAN must return false. - if (is_nan() || rhs.is_nan()) return false; + // Returns true iff this number is at most kMaxUlps ULP's away from + // rhs. In particular, this function: + // + // - returns false if either number is (or both are) NAN. + // - treats really large numbers as almost equal to infinity. + // - thinks +0.0 and -0.0 are 0 DLP's apart. + bool AlmostEquals(const FloatingPoint& rhs) const + { + // The IEEE standard says that any comparison operation involving + // a NAN must return false. + if (is_nan() || rhs.is_nan()) return false; - return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) - <= kMaxUlps; - } + return DistanceBetweenSignAndMagnitudeNumbers(u_.bits_, rhs.u_.bits_) <= kMaxUlps; + } - private: - // The data type used to store the actual floating-point number. - union FloatingPointUnion { - RawType value_; // The raw floating-point number. - Bits bits_; // The bits that represent the number. - }; +private: + // The data type used to store the actual floating-point number. + union FloatingPointUnion { + RawType value_; // The raw floating-point number. + Bits bits_; // The bits that represent the number. + }; - // Converts an integer from the sign-and-magnitude representation to - // the biased representation. More precisely, let N be 2 to the - // power of (kBitCount - 1), an integer x is represented by the - // unsigned number x + N. - // - // For instance, - // - // -N + 1 (the most negative number representable using - // sign-and-magnitude) is represented by 1; - // 0 is represented by N; and - // N - 1 (the biggest number representable using - // sign-and-magnitude) is represented by 2N - 1. - // - // Read http://en.wikipedia.org/wiki/Signed_number_representations - // for more details on signed number representations. - static Bits SignAndMagnitudeToBiased(const Bits &sam) { - if (kSignBitMask & sam) { - // sam represents a negative number. - return ~sam + 1; - } else { - // sam represents a positive number. - return kSignBitMask | sam; - } - } + // Converts an integer from the sign-and-magnitude representation to + // the biased representation. More precisely, let N be 2 to the + // power of (kBitCount - 1), an integer x is represented by the + // unsigned number x + N. + // + // For instance, + // + // -N + 1 (the most negative number representable using + // sign-and-magnitude) is represented by 1; + // 0 is represented by N; and + // N - 1 (the biggest number representable using + // sign-and-magnitude) is represented by 2N - 1. + // + // Read http://en.wikipedia.org/wiki/Signed_number_representations + // for more details on signed number representations. + static Bits SignAndMagnitudeToBiased(const Bits& sam) + { + if (kSignBitMask & sam) + { + // sam represents a negative number. + return ~sam + 1; + } + else + { + // sam represents a positive number. + return kSignBitMask | sam; + } + } - // Given two numbers in the sign-and-magnitude representation, - // returns the distance between them as an unsigned number. - static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits &sam1, - const Bits &sam2) { - const Bits biased1 = SignAndMagnitudeToBiased(sam1); - const Bits biased2 = SignAndMagnitudeToBiased(sam2); - return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); - } + // Given two numbers in the sign-and-magnitude representation, + // returns the distance between them as an unsigned number. + static Bits DistanceBetweenSignAndMagnitudeNumbers(const Bits& sam1, + const Bits& sam2) + { + const Bits biased1 = SignAndMagnitudeToBiased(sam1); + const Bits biased2 = SignAndMagnitudeToBiased(sam2); + return (biased1 >= biased2) ? (biased1 - biased2) : (biased2 - biased1); + } - FloatingPointUnion u_; + FloatingPointUnion u_; }; // We cannot use std::numeric_limits::max() as it clashes with the max() // macro defined by . template <> -inline float FloatingPoint::Max() { return FLT_MAX; } +inline float FloatingPoint::Max() +{ + return FLT_MAX; +} template <> -inline double FloatingPoint::Max() { return DBL_MAX; } +inline double FloatingPoint::Max() +{ + return DBL_MAX; +} // Typedefs the instances of the FloatingPoint template class that we // care to use. @@ -399,12 +419,13 @@ typedef FloatingPoint Double; typedef const void* TypeId; template -class TypeIdHelper { - public: - // dummy_ must not have a const type. Otherwise an overly eager - // compiler (e.g. MSVC 7.1 & 8.0) may try to merge - // TypeIdHelper::dummy_ for different Ts as an "optimization". - static bool dummy_; +class TypeIdHelper +{ +public: + // dummy_ must not have a const type. Otherwise an overly eager + // compiler (e.g. MSVC 7.1 & 8.0) may try to merge + // TypeIdHelper::dummy_ for different Ts as an "optimization". + static bool dummy_; }; template @@ -414,12 +435,13 @@ bool TypeIdHelper::dummy_ = false; // returned for different types. Calling the function twice with the // same type argument is guaranteed to return the same ID. template -TypeId GetTypeId() { - // The compiler is required to allocate a different - // TypeIdHelper::dummy_ variable for each T used to instantiate - // the template. Therefore, the address of dummy_ is guaranteed to - // be unique. - return &(TypeIdHelper::dummy_); +TypeId GetTypeId() +{ + // The compiler is required to allocate a different + // TypeIdHelper::dummy_ variable for each T used to instantiate + // the template. Therefore, the address of dummy_ is guaranteed to + // be unique. + return &(TypeIdHelper::dummy_); } // Returns the type ID of ::testing::Test. Always call this instead @@ -431,27 +453,29 @@ GTEST_API_ TypeId GetTestTypeId(); // Defines the abstract factory interface that creates instances // of a Test object. -class TestFactoryBase { - public: - virtual ~TestFactoryBase() {} +class TestFactoryBase +{ +public: + virtual ~TestFactoryBase() {} - // Creates a test instance to run. The instance is both created and destroyed - // within TestInfoImpl::Run() - virtual Test* CreateTest() = 0; + // Creates a test instance to run. The instance is both created and destroyed + // within TestInfoImpl::Run() + virtual Test* CreateTest() = 0; - protected: - TestFactoryBase() {} +protected: + TestFactoryBase() {} - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase); +private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestFactoryBase); }; // This class provides implementation of TeastFactoryBase interface. // It is used in TEST and TEST_F macros. template -class TestFactoryImpl : public TestFactoryBase { - public: - virtual Test* CreateTest() { return new TestClass; } +class TestFactoryImpl : public TestFactoryBase +{ +public: + virtual Test* CreateTest() { return new TestClass; } }; #if GTEST_OS_WINDOWS @@ -461,9 +485,9 @@ class TestFactoryImpl : public TestFactoryBase { // We pass a long instead of HRESULT to avoid causing an // include dependency for the HRESULT type. GTEST_API_ AssertionResult IsHRESULTSuccess(const char* expr, - long hr); // NOLINT + long hr); // NOLINT GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr, - long hr); // NOLINT + long hr); // NOLINT #endif // GTEST_OS_WINDOWS @@ -489,14 +513,14 @@ typedef void (*TearDownTestCaseFunc)(); // The newly created TestInfo instance will assume // ownership of the factory object. GTEST_API_ TestInfo* MakeAndRegisterTestInfo( - const char* test_case_name, - const char* name, - const char* type_param, - const char* value_param, - TypeId fixture_class_id, - SetUpTestCaseFunc set_up_tc, - TearDownTestCaseFunc tear_down_tc, - TestFactoryBase* factory); + const char* test_case_name, + const char* name, + const char* type_param, + const char* value_param, + TypeId fixture_class_id, + SetUpTestCaseFunc set_up_tc, + TearDownTestCaseFunc tear_down_tc, + TestFactoryBase* factory); // If *pstr starts with the given prefix, modifies *pstr to be right // past the prefix and returns true; otherwise leaves *pstr unchanged @@ -506,53 +530,62 @@ GTEST_API_ bool SkipPrefix(const char* prefix, const char** pstr); #if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P // State of the definition of a type-parameterized test case. -class GTEST_API_ TypedTestCasePState { - public: - TypedTestCasePState() : registered_(false) {} +class GTEST_API_ TypedTestCasePState +{ +public: + TypedTestCasePState() : registered_(false) {} - // Adds the given test name to defined_test_names_ and return true - // if the test case hasn't been registered; otherwise aborts the - // program. - bool AddTestName(const char* file, int line, const char* case_name, - const char* test_name) { - if (registered_) { - fprintf(stderr, "%s Test %s must be defined before " - "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n", - FormatFileLocation(file, line).c_str(), test_name, case_name); - fflush(stderr); - posix::Abort(); - } - defined_test_names_.insert(test_name); - return true; - } + // Adds the given test name to defined_test_names_ and return true + // if the test case hasn't been registered; otherwise aborts the + // program. + bool AddTestName(const char* file, int line, const char* case_name, + const char* test_name) + { + if (registered_) + { + fprintf(stderr, + "%s Test %s must be defined before " + "REGISTER_TYPED_TEST_CASE_P(%s, ...).\n", + FormatFileLocation(file, line).c_str(), test_name, case_name); + fflush(stderr); + posix::Abort(); + } + defined_test_names_.insert(test_name); + return true; + } - // Verifies that registered_tests match the test names in - // defined_test_names_; returns registered_tests if successful, or - // aborts the program otherwise. - const char* VerifyRegisteredTestNames( - const char* file, int line, const char* registered_tests); + // Verifies that registered_tests match the test names in + // defined_test_names_; returns registered_tests if successful, or + // aborts the program otherwise. + const char* VerifyRegisteredTestNames( + const char* file, int line, const char* registered_tests); - private: - bool registered_; - ::std::set defined_test_names_; +private: + bool registered_; + ::std::set defined_test_names_; }; // Skips to the first non-space char after the first comma in 'str'; // returns NULL if no comma is found in 'str'. -inline const char* SkipComma(const char* str) { - const char* comma = strchr(str, ','); - if (comma == NULL) { - return NULL; - } - while (IsSpace(*(++comma))) {} - return comma; +inline const char* SkipComma(const char* str) +{ + const char* comma = strchr(str, ','); + if (comma == NULL) + { + return NULL; + } + while (IsSpace(*(++comma))) + { + } + return comma; } // Returns the prefix of 'str' before the first comma in it; returns // the entire string if it contains no comma. -inline std::string GetPrefixUntilComma(const char* str) { - const char* comma = strchr(str, ','); - return comma == NULL ? str : std::string(str, comma); +inline std::string GetPrefixUntilComma(const char* str) +{ + const char* comma = strchr(str, ','); + return comma == NULL ? str : std::string(str, comma); } // TypeParameterizedTest::Register() @@ -563,45 +596,47 @@ inline std::string GetPrefixUntilComma(const char* str) { // Implementation note: The GTEST_TEMPLATE_ macro declares a template // template parameter. It's defined in gtest-type-util.h. template -class TypeParameterizedTest { - public: - // 'index' is the index of the test in the type list 'Types' - // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase, - // Types). Valid values for 'index' are [0, N - 1] where N is the - // length of Types. - static bool Register(const char* prefix, const char* case_name, - const char* test_names, int index) { - typedef typename Types::Head Type; - typedef Fixture FixtureClass; - typedef typename GTEST_BIND_(TestSel, Type) TestClass; +class TypeParameterizedTest +{ +public: + // 'index' is the index of the test in the type list 'Types' + // specified in INSTANTIATE_TYPED_TEST_CASE_P(Prefix, TestCase, + // Types). Valid values for 'index' are [0, N - 1] where N is the + // length of Types. + static bool Register(const char* prefix, const char* case_name, + const char* test_names, int index) + { + typedef typename Types::Head Type; + typedef Fixture FixtureClass; + typedef typename GTEST_BIND_(TestSel, Type) TestClass; - // First, registers the first type-parameterized test in the type - // list. - MakeAndRegisterTestInfo( - (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + "/" - + StreamableToString(index)).c_str(), - GetPrefixUntilComma(test_names).c_str(), - GetTypeName().c_str(), - NULL, // No value parameter. - GetTypeId(), - TestClass::SetUpTestCase, - TestClass::TearDownTestCase, - new TestFactoryImpl); + // First, registers the first type-parameterized test in the type + // list. + MakeAndRegisterTestInfo( + (std::string(prefix) + (prefix[0] == '\0' ? "" : "/") + case_name + "/" + StreamableToString(index)).c_str(), + GetPrefixUntilComma(test_names).c_str(), + GetTypeName().c_str(), + NULL, // No value parameter. + GetTypeId(), + TestClass::SetUpTestCase, + TestClass::TearDownTestCase, + new TestFactoryImpl); - // Next, recurses (at compile time) with the tail of the type list. - return TypeParameterizedTest - ::Register(prefix, case_name, test_names, index + 1); - } + // Next, recurses (at compile time) with the tail of the type list. + return TypeParameterizedTest::Register(prefix, case_name, test_names, index + 1); + } }; // The base case for the compile time recursion. template -class TypeParameterizedTest { - public: - static bool Register(const char* /*prefix*/, const char* /*case_name*/, - const char* /*test_names*/, int /*index*/) { - return true; - } +class TypeParameterizedTest +{ +public: + static bool Register(const char* /*prefix*/, const char* /*case_name*/, + const char* /*test_names*/, int /*index*/) + { + return true; + } }; // TypeParameterizedTestCase::Register() @@ -609,30 +644,33 @@ class TypeParameterizedTest { // Test. The return value is insignificant - we just need to return // something such that we can call this function in a namespace scope. template -class TypeParameterizedTestCase { - public: - static bool Register(const char* prefix, const char* case_name, - const char* test_names) { - typedef typename Tests::Head Head; +class TypeParameterizedTestCase +{ +public: + static bool Register(const char* prefix, const char* case_name, + const char* test_names) + { + typedef typename Tests::Head Head; - // First, register the first test in 'Test' for each type in 'Types'. - TypeParameterizedTest::Register( - prefix, case_name, test_names, 0); + // First, register the first test in 'Test' for each type in 'Types'. + TypeParameterizedTest::Register( + prefix, case_name, test_names, 0); - // Next, recurses (at compile time) with the tail of the test list. - return TypeParameterizedTestCase - ::Register(prefix, case_name, SkipComma(test_names)); - } + // Next, recurses (at compile time) with the tail of the test list. + return TypeParameterizedTestCase::Register(prefix, case_name, SkipComma(test_names)); + } }; // The base case for the compile time recursion. template -class TypeParameterizedTestCase { - public: - static bool Register(const char* /*prefix*/, const char* /*case_name*/, - const char* /*test_names*/) { - return true; - } +class TypeParameterizedTestCase +{ +public: + static bool Register(const char* /*prefix*/, const char* /*case_name*/, + const char* /*test_names*/) + { + return true; + } }; #endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P @@ -648,7 +686,7 @@ class TypeParameterizedTestCase { // GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. GTEST_API_ std::string GetCurrentOsStackTraceExceptTop( - UnitTest* unit_test, int skip_count); + UnitTest* unit_test, int skip_count); // Helpers for suppressing warnings on unreachable code or constant // condition. @@ -662,10 +700,11 @@ inline bool AlwaysFalse() { return !AlwaysTrue(); } // Helper for suppressing false warning from Clang on a const char* // variable declared in a conditional expression always being NULL in // the else branch. -struct GTEST_API_ ConstCharPtr { - ConstCharPtr(const char* str) : value(str) {} - operator bool() const { return true; } - const char* value; +struct GTEST_API_ ConstCharPtr +{ + ConstCharPtr(const char* str) : value(str) {} + operator bool() const { return true; } + const char* value; }; // A simple Linear Congruential Generator for generating random @@ -673,21 +712,22 @@ struct GTEST_API_ ConstCharPtr { // doesn't use global state (and therefore can't interfere with user // code). Unlike rand_r(), it's portable. An LCG isn't very random, // but it's good enough for our purposes. -class GTEST_API_ Random { - public: - static const UInt32 kMaxRange = 1u << 31; +class GTEST_API_ Random +{ +public: + static const UInt32 kMaxRange = 1u << 31; - explicit Random(UInt32 seed) : state_(seed) {} + explicit Random(UInt32 seed) : state_(seed) {} - void Reseed(UInt32 seed) { state_ = seed; } + void Reseed(UInt32 seed) { state_ = seed; } - // Generates a random number from [0, range). Crashes if 'range' is - // 0 or greater than kMaxRange. - UInt32 Generate(UInt32 range); + // Generates a random number from [0, range). Crashes if 'range' is + // 0 or greater than kMaxRange. + UInt32 Generate(UInt32 range); - private: - UInt32 state_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); +private: + UInt32 state_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(Random); }; // Defining a variable of type CompileAssertTypesEqual will cause a @@ -696,36 +736,50 @@ template struct CompileAssertTypesEqual; template -struct CompileAssertTypesEqual { +struct CompileAssertTypesEqual +{ }; // Removes the reference from a type if it is a reference type, // otherwise leaves it unchanged. This is the same as // tr1::remove_reference, which is not widely available yet. template -struct RemoveReference { typedef T type; }; // NOLINT +struct RemoveReference +{ + typedef T type; +}; // NOLINT template -struct RemoveReference { typedef T type; }; // NOLINT +struct RemoveReference +{ + typedef T type; +}; // NOLINT // A handy wrapper around RemoveReference that works when the argument // T depends on template parameters. #define GTEST_REMOVE_REFERENCE_(T) \ - typename ::testing::internal::RemoveReference::type + typename ::testing::internal::RemoveReference::type // Removes const from a type if it is a const type, otherwise leaves // it unchanged. This is the same as tr1::remove_const, which is not // widely available yet. template -struct RemoveConst { typedef T type; }; // NOLINT +struct RemoveConst +{ + typedef T type; +}; // NOLINT template -struct RemoveConst { typedef T type; }; // NOLINT +struct RemoveConst +{ + typedef T type; +}; // NOLINT // MSVC 8.0, Sun C++, and IBM XL C++ have a bug which causes the above // definition to fail to remove the const in 'const int[3]' and 'const // char[3][4]'. The following specialization works around the bug. template -struct RemoveConst { - typedef typename RemoveConst::type type[N]; +struct RemoveConst +{ + typedef typename RemoveConst::type type[N]; }; #if defined(_MSC_VER) && _MSC_VER < 1400 @@ -733,32 +787,39 @@ struct RemoveConst { // 'const int[3] and 'const int[3][4]'. However, it causes trouble with GCC // and thus needs to be conditionally compiled. template -struct RemoveConst { - typedef typename RemoveConst::type type[N]; +struct RemoveConst +{ + typedef typename RemoveConst::type type[N]; }; #endif // A handy wrapper around RemoveConst that works when the argument // T depends on template parameters. #define GTEST_REMOVE_CONST_(T) \ - typename ::testing::internal::RemoveConst::type + typename ::testing::internal::RemoveConst::type // Turns const U&, U&, const U, and U all into U. #define GTEST_REMOVE_REFERENCE_AND_CONST_(T) \ - GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T)) + GTEST_REMOVE_CONST_(GTEST_REMOVE_REFERENCE_(T)) // Adds reference to a type if it is not a reference type, // otherwise leaves it unchanged. This is the same as // tr1::add_reference, which is not widely available yet. template -struct AddReference { typedef T& type; }; // NOLINT +struct AddReference +{ + typedef T& type; +}; // NOLINT template -struct AddReference { typedef T& type; }; // NOLINT +struct AddReference +{ + typedef T& type; +}; // NOLINT // A handy wrapper around AddReference that works when the argument T // depends on template parameters. #define GTEST_ADD_REFERENCE_(T) \ - typename ::testing::internal::AddReference::type + typename ::testing::internal::AddReference::type // Adds a reference to const on top of T as necessary. For example, // it transforms @@ -770,56 +831,57 @@ struct AddReference { typedef T& type; }; // NOLINT // // The argument T must depend on some template parameters. #define GTEST_REFERENCE_TO_CONST_(T) \ - GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T)) + GTEST_ADD_REFERENCE_(const GTEST_REMOVE_REFERENCE_(T)) // ImplicitlyConvertible::value is a compile-time bool // constant that's true iff type From can be implicitly converted to // type To. template -class ImplicitlyConvertible { - private: - // We need the following helper functions only for their types. - // They have no implementations. +class ImplicitlyConvertible +{ +private: + // We need the following helper functions only for their types. + // They have no implementations. - // MakeFrom() is an expression whose type is From. We cannot simply - // use From(), as the type From may not have a public default - // constructor. - static From MakeFrom(); + // MakeFrom() is an expression whose type is From. We cannot simply + // use From(), as the type From may not have a public default + // constructor. + static From MakeFrom(); - // These two functions are overloaded. Given an expression - // Helper(x), the compiler will pick the first version if x can be - // implicitly converted to type To; otherwise it will pick the - // second version. - // - // The first version returns a value of size 1, and the second - // version returns a value of size 2. Therefore, by checking the - // size of Helper(x), which can be done at compile time, we can tell - // which version of Helper() is used, and hence whether x can be - // implicitly converted to type To. - static char Helper(To); - static char (&Helper(...))[2]; // NOLINT + // These two functions are overloaded. Given an expression + // Helper(x), the compiler will pick the first version if x can be + // implicitly converted to type To; otherwise it will pick the + // second version. + // + // The first version returns a value of size 1, and the second + // version returns a value of size 2. Therefore, by checking the + // size of Helper(x), which can be done at compile time, we can tell + // which version of Helper() is used, and hence whether x can be + // implicitly converted to type To. + static char Helper(To); + static char (&Helper(...))[2]; // NOLINT - // We have to put the 'public' section after the 'private' section, - // or MSVC refuses to compile the code. - public: - // MSVC warns about implicitly converting from double to int for - // possible loss of data, so we need to temporarily disable the - // warning. + // We have to put the 'public' section after the 'private' section, + // or MSVC refuses to compile the code. +public: + // MSVC warns about implicitly converting from double to int for + // possible loss of data, so we need to temporarily disable the + // warning. #ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4244) // Temporarily disables warning 4244. +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable : 4244) // Temporarily disables warning 4244. - static const bool value = - sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; -# pragma warning(pop) // Restores the warning state. + static const bool value = + sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; +#pragma warning(pop) // Restores the warning state. #elif defined(__BORLANDC__) - // C++Builder cannot use member overload resolution during template - // instantiation. The simplest workaround is to use its C++0x type traits - // functions (C++Builder 2009 and above only). - static const bool value = __is_convertible(From, To); + // C++Builder cannot use member overload resolution during template + // instantiation. The simplest workaround is to use its C++0x type traits + // functions (C++Builder 2009 and above only). + static const bool value = __is_convertible(From, To); #else - static const bool value = - sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; + static const bool value = + sizeof(Helper(ImplicitlyConvertible::MakeFrom())) == 1; #endif // _MSV_VER }; template @@ -830,9 +892,10 @@ const bool ImplicitlyConvertible::value; // of those. template struct IsAProtocolMessage - : public bool_constant< - ImplicitlyConvertible::value || - ImplicitlyConvertible::value> { + : public bool_constant< + ImplicitlyConvertible::value || + ImplicitlyConvertible::value> +{ }; // When the compiler sees expression IsContainerTest(0), if C is an @@ -859,21 +922,30 @@ struct IsAProtocolMessage typedef int IsContainer; template IsContainer IsContainerTest(int /* dummy */, - typename C::iterator* /* it */ = NULL, - typename C::const_iterator* /* const_it */ = NULL) { - return 0; + typename C::iterator* /* it */ = NULL, + typename C::const_iterator* /* const_it */ = NULL) +{ + return 0; } typedef char IsNotContainer; template -IsNotContainer IsContainerTest(long /* dummy */) { return '\0'; } +IsNotContainer IsContainerTest(long /* dummy */) +{ + return '\0'; +} // EnableIf::type is void when 'Cond' is true, and // undefined when 'Cond' is false. To use SFINAE to make a function // overload only apply when a particular expression is true, add // "typename EnableIf::type* = 0" as the last parameter. -template struct EnableIf; -template<> struct EnableIf { typedef void type; }; // NOLINT +template +struct EnableIf; +template <> +struct EnableIf +{ + typedef void type; +}; // NOLINT // Utilities for native arrays. @@ -886,35 +958,43 @@ bool ArrayEq(const T* lhs, size_t size, const U* rhs); // This generic version is used when k is 0. template -inline bool ArrayEq(const T& lhs, const U& rhs) { return lhs == rhs; } +inline bool ArrayEq(const T& lhs, const U& rhs) +{ + return lhs == rhs; +} // This overload is used when k >= 1. template -inline bool ArrayEq(const T(&lhs)[N], const U(&rhs)[N]) { - return internal::ArrayEq(lhs, N, rhs); +inline bool ArrayEq(const T (&lhs)[N], const U (&rhs)[N]) +{ + return internal::ArrayEq(lhs, N, rhs); } // This helper reduces code bloat. If we instead put its logic inside // the previous ArrayEq() function, arrays with different sizes would // lead to different copies of the template code. template -bool ArrayEq(const T* lhs, size_t size, const U* rhs) { - for (size_t i = 0; i != size; i++) { - if (!internal::ArrayEq(lhs[i], rhs[i])) - return false; - } - return true; +bool ArrayEq(const T* lhs, size_t size, const U* rhs) +{ + for (size_t i = 0; i != size; i++) + { + if (!internal::ArrayEq(lhs[i], rhs[i])) + return false; + } + return true; } // Finds the first element in the iterator range [begin, end) that // equals elem. Element may be a native array type itself. template -Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) { - for (Iter it = begin; it != end; ++it) { - if (internal::ArrayEq(*it, elem)) - return it; - } - return end; +Iter ArrayAwareFind(Iter begin, Iter end, const Element& elem) +{ + for (Iter it = begin; it != end; ++it) + { + if (internal::ArrayEq(*it, elem)) + return it; + } + return end; } // CopyArray() copies a k-dimensional native array using the elements' @@ -926,30 +1006,37 @@ void CopyArray(const T* from, size_t size, U* to); // This generic version is used when k is 0. template -inline void CopyArray(const T& from, U* to) { *to = from; } +inline void CopyArray(const T& from, U* to) +{ + *to = from; +} // This overload is used when k >= 1. template -inline void CopyArray(const T(&from)[N], U(*to)[N]) { - internal::CopyArray(from, N, *to); +inline void CopyArray(const T (&from)[N], U (*to)[N]) +{ + internal::CopyArray(from, N, *to); } // This helper reduces code bloat. If we instead put its logic inside // the previous CopyArray() function, arrays with different sizes // would lead to different copies of the template code. template -void CopyArray(const T* from, size_t size, U* to) { - for (size_t i = 0; i != size; i++) { - internal::CopyArray(from[i], to + i); - } +void CopyArray(const T* from, size_t size, U* to) +{ + for (size_t i = 0; i != size; i++) + { + internal::CopyArray(from[i], to + i); + } } // The relation between an NativeArray object (see below) and the // native array it represents. -enum RelationToSource { - kReference, // The NativeArray references the native array. - kCopy // The NativeArray makes a copy of the native array and - // owns the copy. +enum RelationToSource +{ + kReference, // The NativeArray references the native array. + kCopy // The NativeArray makes a copy of the native array and + // owns the copy. }; // Adapts a native array to a read-only STL-style container. Instead @@ -961,198 +1048,226 @@ enum RelationToSource { // this requirement. Element can be an array type itself (hence // multi-dimensional arrays are supported). template -class NativeArray { - public: - // STL-style container typedefs. - typedef Element value_type; - typedef Element* iterator; - typedef const Element* const_iterator; +class NativeArray +{ +public: + // STL-style container typedefs. + typedef Element value_type; + typedef Element* iterator; + typedef const Element* const_iterator; - // Constructs from a native array. - NativeArray(const Element* array, size_t count, RelationToSource relation) { - Init(array, count, relation); - } + // Constructs from a native array. + NativeArray(const Element* array, size_t count, RelationToSource relation) + { + Init(array, count, relation); + } - // Copy constructor. - NativeArray(const NativeArray& rhs) { - Init(rhs.array_, rhs.size_, rhs.relation_to_source_); - } + // Copy constructor. + NativeArray(const NativeArray& rhs) + { + Init(rhs.array_, rhs.size_, rhs.relation_to_source_); + } - ~NativeArray() { - // Ensures that the user doesn't instantiate NativeArray with a - // const or reference type. - static_cast(StaticAssertTypeEqHelper()); - if (relation_to_source_ == kCopy) - delete[] array_; - } + ~NativeArray() + { + // Ensures that the user doesn't instantiate NativeArray with a + // const or reference type. + static_cast(StaticAssertTypeEqHelper()); + if (relation_to_source_ == kCopy) + delete[] array_; + } - // STL-style container methods. - size_t size() const { return size_; } - const_iterator begin() const { return array_; } - const_iterator end() const { return array_ + size_; } - bool operator==(const NativeArray& rhs) const { - return size() == rhs.size() && - ArrayEq(begin(), size(), rhs.begin()); - } + // STL-style container methods. + size_t size() const { return size_; } + const_iterator begin() const { return array_; } + const_iterator end() const { return array_ + size_; } + bool operator==(const NativeArray& rhs) const + { + return size() == rhs.size() && + ArrayEq(begin(), size(), rhs.begin()); + } - private: - // Initializes this object; makes a copy of the input array if - // 'relation' is kCopy. - void Init(const Element* array, size_t a_size, RelationToSource relation) { - if (relation == kReference) { - array_ = array; - } else { - Element* const copy = new Element[a_size]; - CopyArray(array, a_size, copy); - array_ = copy; - } - size_ = a_size; - relation_to_source_ = relation; - } +private: + // Initializes this object; makes a copy of the input array if + // 'relation' is kCopy. + void Init(const Element* array, size_t a_size, RelationToSource relation) + { + if (relation == kReference) + { + array_ = array; + } + else + { + Element* const copy = new Element[a_size]; + CopyArray(array, a_size, copy); + array_ = copy; + } + size_ = a_size; + relation_to_source_ = relation; + } - const Element* array_; - size_t size_; - RelationToSource relation_to_source_; + const Element* array_; + size_t size_; + RelationToSource relation_to_source_; - GTEST_DISALLOW_ASSIGN_(NativeArray); + GTEST_DISALLOW_ASSIGN_(NativeArray); }; } // namespace internal } // namespace testing #define GTEST_MESSAGE_AT_(file, line, message, result_type) \ - ::testing::internal::AssertHelper(result_type, file, line, message) \ - = ::testing::Message() + ::testing::internal::AssertHelper(result_type, file, line, message) = ::testing::Message() #define GTEST_MESSAGE_(message, result_type) \ - GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type) + GTEST_MESSAGE_AT_(__FILE__, __LINE__, message, result_type) #define GTEST_FATAL_FAILURE_(message) \ - return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) + return GTEST_MESSAGE_(message, ::testing::TestPartResult::kFatalFailure) #define GTEST_NONFATAL_FAILURE_(message) \ - GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) + GTEST_MESSAGE_(message, ::testing::TestPartResult::kNonFatalFailure) #define GTEST_SUCCESS_(message) \ - GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess) + GTEST_MESSAGE_(message, ::testing::TestPartResult::kSuccess) // Suppresses MSVC warnings 4072 (unreachable code) for the code following // statement if it returns or throws (or doesn't return or throw in some // situations). #define GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement) \ - if (::testing::internal::AlwaysTrue()) { statement; } + if (::testing::internal::AlwaysTrue()) \ + { \ + statement; \ + } -#define GTEST_TEST_THROW_(statement, expected_exception, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::ConstCharPtr gtest_msg = "") { \ - bool gtest_caught_expected = false; \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } \ - catch (expected_exception const&) { \ - gtest_caught_expected = true; \ - } \ - catch (...) { \ - gtest_msg.value = \ - "Expected: " #statement " throws an exception of type " \ - #expected_exception ".\n Actual: it throws a different type."; \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ - } \ - if (!gtest_caught_expected) { \ - gtest_msg.value = \ - "Expected: " #statement " throws an exception of type " \ - #expected_exception ".\n Actual: it throws nothing."; \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__): \ - fail(gtest_msg.value) +#define GTEST_TEST_THROW_(statement, expected_exception, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::ConstCharPtr gtest_msg = "") \ + { \ + bool gtest_caught_expected = false; \ + try \ + { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (expected_exception const&) \ + { \ + gtest_caught_expected = true; \ + } \ + catch (...) \ + { \ + gtest_msg.value = \ + "Expected: " #statement " throws an exception of type " #expected_exception ".\n Actual: it throws a different type."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + if (!gtest_caught_expected) \ + { \ + gtest_msg.value = \ + "Expected: " #statement " throws an exception of type " #expected_exception ".\n Actual: it throws nothing."; \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__); \ + } \ + } \ + else \ + GTEST_CONCAT_TOKEN_(gtest_label_testthrow_, __LINE__) : fail(gtest_msg.value) -#define GTEST_TEST_NO_THROW_(statement, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::AlwaysTrue()) { \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } \ - catch (...) { \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__): \ - fail("Expected: " #statement " doesn't throw an exception.\n" \ - " Actual: it throws.") - -#define GTEST_TEST_ANY_THROW_(statement, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::AlwaysTrue()) { \ - bool gtest_caught_any = false; \ - try { \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - } \ - catch (...) { \ - gtest_caught_any = true; \ - } \ - if (!gtest_caught_any) { \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__): \ - fail("Expected: " #statement " throws an exception.\n" \ - " Actual: it doesn't.") +#define GTEST_TEST_NO_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) \ + { \ + try \ + { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (...) \ + { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__); \ + } \ + } \ + else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnothrow_, __LINE__) : fail("Expected: " #statement \ + " doesn't throw an exception.\n" \ + " Actual: it throws.") +#define GTEST_TEST_ANY_THROW_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) \ + { \ + bool gtest_caught_any = false; \ + try \ + { \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + } \ + catch (...) \ + { \ + gtest_caught_any = true; \ + } \ + if (!gtest_caught_any) \ + { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__); \ + } \ + } \ + else \ + GTEST_CONCAT_TOKEN_(gtest_label_testanythrow_, __LINE__) : fail("Expected: " #statement \ + " throws an exception.\n" \ + " Actual: it doesn't.") // Implements Boolean test assertions such as EXPECT_TRUE. expression can be // either a boolean expression or an AssertionResult. text is a textual // represenation of expression as it was passed into the EXPECT_TRUE. #define GTEST_TEST_BOOLEAN_(expression, text, actual, expected, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (const ::testing::AssertionResult gtest_ar_ = \ - ::testing::AssertionResult(expression)) \ - ; \ - else \ - fail(::testing::internal::GetBoolAssertionFailureMessage(\ - gtest_ar_, text, #actual, #expected).c_str()) + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (const ::testing::AssertionResult gtest_ar_ = \ + ::testing::AssertionResult(expression)) \ + ; \ + else \ + fail(::testing::internal::GetBoolAssertionFailureMessage( \ + gtest_ar_, text, #actual, #expected) \ + .c_str()) -#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::AlwaysTrue()) { \ - ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ - GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ - if (gtest_fatal_failure_checker.has_new_fatal_failure()) { \ - goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ - } \ - } else \ - GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__): \ - fail("Expected: " #statement " doesn't generate new fatal " \ - "failures in the current thread.\n" \ - " Actual: it does.") +#define GTEST_TEST_NO_FATAL_FAILURE_(statement, fail) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::AlwaysTrue()) \ + { \ + ::testing::internal::HasNewFatalFailureHelper gtest_fatal_failure_checker; \ + GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \ + if (gtest_fatal_failure_checker.has_new_fatal_failure()) \ + { \ + goto GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__); \ + } \ + } \ + else \ + GTEST_CONCAT_TOKEN_(gtest_label_testnofatal_, __LINE__) : fail("Expected: " #statement \ + " doesn't generate new fatal " \ + "failures in the current thread.\n" \ + " Actual: it does.") // Expands to the name of the class that implements the given test. #define GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ - test_case_name##_##test_name##_Test + test_case_name##_##test_name##_Test // Helper macro for defining tests. -#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\ -class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\ - public:\ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\ - private:\ - virtual void TestBody();\ - static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_;\ - GTEST_DISALLOW_COPY_AND_ASSIGN_(\ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\ -};\ -\ -::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)\ - ::test_info_ =\ - ::testing::internal::MakeAndRegisterTestInfo(\ - #test_case_name, #test_name, NULL, NULL, \ - (parent_id), \ - parent_class::SetUpTestCase, \ - parent_class::TearDownTestCase, \ - new ::testing::internal::TestFactoryImpl<\ - GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>);\ -void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() +#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id) \ + class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class \ + { \ + public: \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name) \ + () {} \ + \ + private: \ + virtual void TestBody(); \ + static ::testing::TestInfo* const test_info_ GTEST_ATTRIBUTE_UNUSED_; \ + GTEST_DISALLOW_COPY_AND_ASSIGN_( \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)); \ + }; \ + \ + ::testing::TestInfo* const GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::test_info_ = \ + ::testing::internal::MakeAndRegisterTestInfo( \ + #test_case_name, #test_name, NULL, NULL, \ + (parent_id), \ + parent_class::SetUpTestCase, \ + parent_class::TearDownTestCase, \ + new ::testing::internal::TestFactoryImpl< \ + GTEST_TEST_CLASS_NAME_(test_case_name, test_name)>); \ + void GTEST_TEST_CLASS_NAME_(test_case_name, test_name)::TestBody() #endif // GTEST_INCLUDE_GTEST_INTERNAL_GTEST_INTERNAL_H_ diff --git a/test/gtest-1.7.0/include/gtest/internal/gtest-linked_ptr.h b/test/gtest-1.7.0/include/gtest/internal/gtest-linked_ptr.h index b1362cd00..7d579c9f0 100644 --- a/test/gtest-1.7.0/include/gtest/internal/gtest-linked_ptr.h +++ b/test/gtest-1.7.0/include/gtest/internal/gtest-linked_ptr.h @@ -73,9 +73,10 @@ #include "gtest/internal/gtest-port.h" -namespace testing { -namespace internal { - +namespace testing +{ +namespace internal +{ // Protects copying of all linked_ptr objects. GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex); @@ -86,145 +87,169 @@ GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex); // in the same circular linked list, so we need a single class type here. // // DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr. -class linked_ptr_internal { - public: - // Create a new circle that includes only this instance. - void join_new() { - next_ = this; - } +class linked_ptr_internal +{ +public: + // Create a new circle that includes only this instance. + void join_new() + { + next_ = this; + } - // Many linked_ptr operations may change p.link_ for some linked_ptr - // variable p in the same circle as this object. Therefore we need - // to prevent two such operations from occurring concurrently. - // - // Note that different types of linked_ptr objects can coexist in a - // circle (e.g. linked_ptr, linked_ptr, and - // linked_ptr). Therefore we must use a single mutex to - // protect all linked_ptr objects. This can create serious - // contention in production code, but is acceptable in a testing - // framework. + // Many linked_ptr operations may change p.link_ for some linked_ptr + // variable p in the same circle as this object. Therefore we need + // to prevent two such operations from occurring concurrently. + // + // Note that different types of linked_ptr objects can coexist in a + // circle (e.g. linked_ptr, linked_ptr, and + // linked_ptr). Therefore we must use a single mutex to + // protect all linked_ptr objects. This can create serious + // contention in production code, but is acceptable in a testing + // framework. - // Join an existing circle. - void join(linked_ptr_internal const* ptr) - GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { - MutexLock lock(&g_linked_ptr_mutex); + // Join an existing circle. + void join(linked_ptr_internal const* ptr) + GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) + { + MutexLock lock(&g_linked_ptr_mutex); - linked_ptr_internal const* p = ptr; - while (p->next_ != ptr) p = p->next_; - p->next_ = this; - next_ = ptr; - } + linked_ptr_internal const* p = ptr; + while (p->next_ != ptr) p = p->next_; + p->next_ = this; + next_ = ptr; + } - // Leave whatever circle we're part of. Returns true if we were the - // last member of the circle. Once this is done, you can join() another. - bool depart() - GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) { - MutexLock lock(&g_linked_ptr_mutex); + // Leave whatever circle we're part of. Returns true if we were the + // last member of the circle. Once this is done, you can join() another. + bool depart() + GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) + { + MutexLock lock(&g_linked_ptr_mutex); - if (next_ == this) return true; - linked_ptr_internal const* p = next_; - while (p->next_ != this) p = p->next_; - p->next_ = next_; - return false; - } + if (next_ == this) return true; + linked_ptr_internal const* p = next_; + while (p->next_ != this) p = p->next_; + p->next_ = next_; + return false; + } - private: - mutable linked_ptr_internal const* next_; +private: + mutable linked_ptr_internal const* next_; }; template -class linked_ptr { - public: - typedef T element_type; +class linked_ptr +{ +public: + typedef T element_type; - // Take over ownership of a raw pointer. This should happen as soon as - // possible after the object is created. - explicit linked_ptr(T* ptr = NULL) { capture(ptr); } - ~linked_ptr() { depart(); } + // Take over ownership of a raw pointer. This should happen as soon as + // possible after the object is created. + explicit linked_ptr(T* ptr = NULL) { capture(ptr); } + ~linked_ptr() { depart(); } - // Copy an existing linked_ptr<>, adding ourselves to the list of references. - template linked_ptr(linked_ptr const& ptr) { copy(&ptr); } - linked_ptr(linked_ptr const& ptr) { // NOLINT - assert(&ptr != this); - copy(&ptr); - } + // Copy an existing linked_ptr<>, adding ourselves to the list of references. + template + linked_ptr(linked_ptr const& ptr) + { + copy(&ptr); + } + linked_ptr(linked_ptr const& ptr) + { // NOLINT + assert(&ptr != this); + copy(&ptr); + } - // Assignment releases the old value and acquires the new. - template linked_ptr& operator=(linked_ptr const& ptr) { - depart(); - copy(&ptr); - return *this; - } + // Assignment releases the old value and acquires the new. + template + linked_ptr& operator=(linked_ptr const& ptr) + { + depart(); + copy(&ptr); + return *this; + } - linked_ptr& operator=(linked_ptr const& ptr) { - if (&ptr != this) { - depart(); - copy(&ptr); - } - return *this; - } + linked_ptr& operator=(linked_ptr const& ptr) + { + if (&ptr != this) + { + depart(); + copy(&ptr); + } + return *this; + } - // Smart pointer members. - void reset(T* ptr = NULL) { - depart(); - capture(ptr); - } - T* get() const { return value_; } - T* operator->() const { return value_; } - T& operator*() const { return *value_; } + // Smart pointer members. + void reset(T* ptr = NULL) + { + depart(); + capture(ptr); + } + T* get() const { return value_; } + T* operator->() const { return value_; } + T& operator*() const { return *value_; } - bool operator==(T* p) const { return value_ == p; } - bool operator!=(T* p) const { return value_ != p; } - template - bool operator==(linked_ptr const& ptr) const { - return value_ == ptr.get(); - } - template - bool operator!=(linked_ptr const& ptr) const { - return value_ != ptr.get(); - } + bool operator==(T* p) const { return value_ == p; } + bool operator!=(T* p) const { return value_ != p; } + template + bool operator==(linked_ptr const& ptr) const + { + return value_ == ptr.get(); + } + template + bool operator!=(linked_ptr const& ptr) const + { + return value_ != ptr.get(); + } - private: - template - friend class linked_ptr; +private: + template + friend class linked_ptr; - T* value_; - linked_ptr_internal link_; + T* value_; + linked_ptr_internal link_; - void depart() { - if (link_.depart()) delete value_; - } + void depart() + { + if (link_.depart()) delete value_; + } - void capture(T* ptr) { - value_ = ptr; - link_.join_new(); - } + void capture(T* ptr) + { + value_ = ptr; + link_.join_new(); + } - template void copy(linked_ptr const* ptr) { - value_ = ptr->get(); - if (value_) - link_.join(&ptr->link_); - else - link_.join_new(); - } + template + void copy(linked_ptr const* ptr) + { + value_ = ptr->get(); + if (value_) + link_.join(&ptr->link_); + else + link_.join_new(); + } }; -template inline -bool operator==(T* ptr, const linked_ptr& x) { - return ptr == x.get(); +template +inline bool operator==(T* ptr, const linked_ptr& x) +{ + return ptr == x.get(); } -template inline -bool operator!=(T* ptr, const linked_ptr& x) { - return ptr != x.get(); +template +inline bool operator!=(T* ptr, const linked_ptr& x) +{ + return ptr != x.get(); } // A function to convert T* into linked_ptr // Doing e.g. make_linked_ptr(new FooBarBaz(arg)) is a shorter notation // for linked_ptr >(new FooBarBaz(arg)) template -linked_ptr make_linked_ptr(T* ptr) { - return linked_ptr(ptr); +linked_ptr make_linked_ptr(T* ptr) +{ + return linked_ptr(ptr); } } // namespace internal diff --git a/test/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h b/test/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h index e80548592..3bc49a918 100644 --- a/test/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h +++ b/test/gtest-1.7.0/include/gtest/internal/gtest-param-util-generated.h @@ -54,13 +54,13 @@ #if GTEST_HAS_PARAM_TEST -namespace testing { - +namespace testing +{ // Forward declarations of ValuesIn(), which is implemented in // include/gtest/gtest-param-test.h. template internal::ParamGenerator< - typename ::testing::internal::IteratorTraits::value_type> + typename ::testing::internal::IteratorTraits::value_type> ValuesIn(ForwardIterator begin, ForwardIterator end); template @@ -68,3088 +68,3163 @@ internal::ParamGenerator ValuesIn(const T (&array)[N]); template internal::ParamGenerator ValuesIn( - const Container& container); - -namespace internal { + const Container& container); +namespace internal +{ // Used in the Values() function to provide polymorphic capabilities. template -class ValueArray1 { - public: - explicit ValueArray1(T1 v1) : v1_(v1) {} +class ValueArray1 +{ +public: + explicit ValueArray1(T1 v1) : v1_(v1) {} - template - operator ParamGenerator() const { return ValuesIn(&v1_, &v1_ + 1); } + template + operator ParamGenerator() const + { + return ValuesIn(&v1_, &v1_ + 1); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray1& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray1& other); - const T1 v1_; + const T1 v1_; }; template -class ValueArray2 { - public: - ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {} +class ValueArray2 +{ +public: + ValueArray2(T1 v1, T2 v2) : v1_(v1), v2_(v2) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray2& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray2& other); - const T1 v1_; - const T2 v2_; + const T1 v1_; + const T2 v2_; }; template -class ValueArray3 { - public: - ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {} +class ValueArray3 +{ +public: + ValueArray3(T1 v1, T2 v2, T3 v3) : v1_(v1), v2_(v2), v3_(v3) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray3& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray3& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; + const T1 v1_; + const T2 v2_; + const T3 v3_; }; template -class ValueArray4 { - public: - ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3), - v4_(v4) {} +class ValueArray4 +{ +public: + ValueArray4(T1 v1, T2 v2, T3 v3, T4 v4) : v1_(v1), v2_(v2), v3_(v3), v4_(v4) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray4& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray4& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; }; template -class ValueArray5 { - public: - ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3), - v4_(v4), v5_(v5) {} +class ValueArray5 +{ +public: + ValueArray5(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray5& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray5& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; }; template -class ValueArray6 { - public: - ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2), - v3_(v3), v4_(v4), v5_(v5), v6_(v6) {} + typename T6> +class ValueArray6 +{ +public: + ValueArray6(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray6& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray6& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; }; template -class ValueArray7 { - public: - ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1), - v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7) {} + typename T6, typename T7> +class ValueArray7 +{ +public: + ValueArray7(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7) : v1_(v1), + v2_(v2), + v3_(v3), + v4_(v4), + v5_(v5), + v6_(v6), + v7_(v7) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray7& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray7& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; }; template -class ValueArray8 { - public: - ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, - T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8) {} + typename T6, typename T7, typename T8> +class ValueArray8 +{ +public: + ValueArray8(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, + T8 v8) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray8& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray8& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; }; template -class ValueArray9 { - public: - ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, - T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9) {} + typename T6, typename T7, typename T8, typename T9> +class ValueArray9 +{ +public: + ValueArray9(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, + T9 v9) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray9& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray9& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; }; template -class ValueArray10 { - public: - ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10) {} + typename T6, typename T7, typename T8, typename T9, typename T10> +class ValueArray10 +{ +public: + ValueArray10(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray10& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray10& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; }; template -class ValueArray11 { - public: - ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), - v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11> +class ValueArray11 +{ +public: + ValueArray11(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray11& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray11& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; }; template -class ValueArray12 { - public: - ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), - v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12> +class ValueArray12 +{ +public: + ValueArray12(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray12& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray12& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; }; template -class ValueArray13 { - public: - ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), - v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), - v12_(v12), v13_(v13) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13> +class ValueArray13 +{ +public: + ValueArray13(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray13& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray13& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; }; template -class ValueArray14 { - public: - ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3), - v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), - v11_(v11), v12_(v12), v13_(v13), v14_(v14) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14> +class ValueArray14 +{ +public: + ValueArray14(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray14& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray14& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; }; template -class ValueArray15 { - public: - ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2), - v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), - v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15> +class ValueArray15 +{ +public: + ValueArray15(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray15& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray15& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; }; template -class ValueArray16 { - public: - ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1), - v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), - v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), - v16_(v16) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16> +class ValueArray16 +{ +public: + ValueArray16(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16) : v1_(v1), + v2_(v2), + v3_(v3), + v4_(v4), + v5_(v5), + v6_(v6), + v7_(v7), + v8_(v8), + v9_(v9), + v10_(v10), + v11_(v11), + v12_(v12), + v13_(v13), + v14_(v14), + v15_(v15), + v16_(v16) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray16& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray16& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; }; template -class ValueArray17 { - public: - ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, - T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), - v15_(v15), v16_(v16), v17_(v17) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17> +class ValueArray17 +{ +public: + ValueArray17(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, + T17 v17) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray17& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray17& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; }; template -class ValueArray18 { - public: - ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), - v15_(v15), v16_(v16), v17_(v17), v18_(v18) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18> +class ValueArray18 +{ +public: + ValueArray18(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray18& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray18& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; }; template -class ValueArray19 { - public: - ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), - v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), - v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19> +class ValueArray19 +{ +public: + ValueArray19(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray19& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray19& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; }; template -class ValueArray20 { - public: - ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), - v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), - v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), - v19_(v19), v20_(v20) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20> +class ValueArray20 +{ +public: + ValueArray20(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray20& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray20& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; }; template -class ValueArray21 { - public: - ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), - v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), - v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), - v18_(v18), v19_(v19), v20_(v20), v21_(v21) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21> +class ValueArray21 +{ +public: + ValueArray21(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray21& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray21& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; }; template -class ValueArray22 { - public: - ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3), - v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), - v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), - v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22> +class ValueArray22 +{ +public: + ValueArray22(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray22& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray22& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; }; template -class ValueArray23 { - public: - ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2), - v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), - v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), - v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), - v23_(v23) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23> +class ValueArray23 +{ +public: + ValueArray23(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray23& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray23& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; }; template -class ValueArray24 { - public: - ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1), - v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), - v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), - v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), - v22_(v22), v23_(v23), v24_(v24) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24> +class ValueArray24 +{ +public: + ValueArray24(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24) : v1_(v1), + v2_(v2), + v3_(v3), + v4_(v4), + v5_(v5), + v6_(v6), + v7_(v7), + v8_(v8), + v9_(v9), + v10_(v10), + v11_(v11), + v12_(v12), + v13_(v13), + v14_(v14), + v15_(v15), + v16_(v16), + v17_(v17), + v18_(v18), + v19_(v19), + v20_(v20), + v21_(v21), + v22_(v22), + v23_(v23), + v24_(v24) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray24& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray24& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; }; template -class ValueArray25 { - public: - ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, - T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), - v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), - v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25> +class ValueArray25 +{ +public: + ValueArray25(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, + T25 v25) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray25& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray25& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; }; template -class ValueArray26 { - public: - ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), - v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), - v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26> +class ValueArray26 +{ +public: + ValueArray26(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray26& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray26& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; }; template -class ValueArray27 { - public: - ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), - v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), - v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), - v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), - v26_(v26), v27_(v27) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27> +class ValueArray27 +{ +public: + ValueArray27(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray27& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray27& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; }; template -class ValueArray28 { - public: - ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), - v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), - v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), - v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), - v25_(v25), v26_(v26), v27_(v27), v28_(v28) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28> +class ValueArray28 +{ +public: + ValueArray28(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray28& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray28& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; }; template -class ValueArray29 { - public: - ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), - v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), - v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), - v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), - v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29> +class ValueArray29 +{ +public: + ValueArray29(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray29& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray29& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; }; template -class ValueArray30 { - public: - ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3), - v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), - v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), - v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), - v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), - v29_(v29), v30_(v30) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30> +class ValueArray30 +{ +public: + ValueArray30(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray30& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray30& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; }; template -class ValueArray31 { - public: - ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2), - v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), - v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), - v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), - v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), - v29_(v29), v30_(v30), v31_(v31) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31> +class ValueArray31 +{ +public: + ValueArray31(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray31& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray31& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; }; template -class ValueArray32 { - public: - ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1), - v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), - v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), - v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), - v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), - v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32> +class ValueArray32 +{ +public: + ValueArray32(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32) : v1_(v1), + v2_(v2), + v3_(v3), + v4_(v4), + v5_(v5), + v6_(v6), + v7_(v7), + v8_(v8), + v9_(v9), + v10_(v10), + v11_(v11), + v12_(v12), + v13_(v13), + v14_(v14), + v15_(v15), + v16_(v16), + v17_(v17), + v18_(v18), + v19_(v19), + v20_(v20), + v21_(v21), + v22_(v22), + v23_(v23), + v24_(v24), + v25_(v25), + v26_(v26), + v27_(v27), + v28_(v28), + v29_(v29), + v30_(v30), + v31_(v31), + v32_(v32) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray32& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray32& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; }; template -class ValueArray33 { - public: - ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, - T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), - v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), - v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), - v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), - v33_(v33) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33> +class ValueArray33 +{ +public: + ValueArray33(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, + T33 v33) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray33& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray33& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; }; template -class ValueArray34 { - public: - ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), - v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), - v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), - v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), - v33_(v33), v34_(v34) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34> +class ValueArray34 +{ +public: + ValueArray34(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray34& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray34& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; }; template -class ValueArray35 { - public: - ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), - v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), - v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), - v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), - v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), - v32_(v32), v33_(v33), v34_(v34), v35_(v35) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35> +class ValueArray35 +{ +public: + ValueArray35(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray35& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray35& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; }; template -class ValueArray36 { - public: - ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), - v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), - v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), - v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), - v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), - v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36> +class ValueArray36 +{ +public: + ValueArray36(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray36& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray36& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; }; template -class ValueArray37 { - public: - ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), - v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), - v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), - v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), - v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), - v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), - v36_(v36), v37_(v37) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37> +class ValueArray37 +{ +public: + ValueArray37(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray37& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray37& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; }; template -class ValueArray38 { - public: - ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3), - v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), - v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), - v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), - v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), - v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), - v35_(v35), v36_(v36), v37_(v37), v38_(v38) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38> +class ValueArray38 +{ +public: + ValueArray38(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray38& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray38& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; }; template -class ValueArray39 { - public: - ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2), - v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), - v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), - v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), - v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), - v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), - v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39> +class ValueArray39 +{ +public: + ValueArray39(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray39& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray39& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; }; template -class ValueArray40 { - public: - ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1), - v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), - v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), - v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), - v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), - v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), - v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), - v40_(v40) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40> +class ValueArray40 +{ +public: + ValueArray40(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40) : v1_(v1), + v2_(v2), + v3_(v3), + v4_(v4), + v5_(v5), + v6_(v6), + v7_(v7), + v8_(v8), + v9_(v9), + v10_(v10), + v11_(v11), + v12_(v12), + v13_(v13), + v14_(v14), + v15_(v15), + v16_(v16), + v17_(v17), + v18_(v18), + v19_(v19), + v20_(v20), + v21_(v21), + v22_(v22), + v23_(v23), + v24_(v24), + v25_(v25), + v26_(v26), + v27_(v27), + v28_(v28), + v29_(v29), + v30_(v30), + v31_(v31), + v32_(v32), + v33_(v33), + v34_(v34), + v35_(v35), + v36_(v36), + v37_(v37), + v38_(v38), + v39_(v39), + v40_(v40) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray40& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray40& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; }; template -class ValueArray41 { - public: - ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, - T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), - v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), - v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), - v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), - v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), - v39_(v39), v40_(v40), v41_(v41) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41> +class ValueArray41 +{ +public: + ValueArray41(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, + T41 v41) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_), static_cast(v41_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray41& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray41& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; - const T41 v41_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; }; template -class ValueArray42 { - public: - ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), - v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), - v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), - v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), - v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), - v39_(v39), v40_(v40), v41_(v41), v42_(v42) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42> +class ValueArray42 +{ +public: + ValueArray42(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_), static_cast(v41_), - static_cast(v42_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray42& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray42& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; - const T41 v41_; - const T42 v42_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; }; template -class ValueArray43 { - public: - ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), - v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), - v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), - v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), - v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), - v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), - v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43> +class ValueArray43 +{ +public: + ValueArray43(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_), static_cast(v41_), - static_cast(v42_), static_cast(v43_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray43& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray43& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; - const T41 v41_; - const T42 v42_; - const T43 v43_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; }; template -class ValueArray44 { - public: - ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), - v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), - v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), - v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), - v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), - v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), - v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), - v43_(v43), v44_(v44) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44> +class ValueArray44 +{ +public: + ValueArray44(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_), static_cast(v41_), - static_cast(v42_), static_cast(v43_), static_cast(v44_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray44& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray44& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; - const T41 v41_; - const T42 v42_; - const T43 v43_; - const T44 v44_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; }; template -class ValueArray45 { - public: - ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), - v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), - v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), - v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), - v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), - v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), - v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), - v42_(v42), v43_(v43), v44_(v44), v45_(v45) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45> +class ValueArray45 +{ +public: + ValueArray45(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_), static_cast(v41_), - static_cast(v42_), static_cast(v43_), static_cast(v44_), - static_cast(v45_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray45& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray45& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; - const T41 v41_; - const T42 v42_; - const T43 v43_; - const T44 v44_; - const T45 v45_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; }; template -class ValueArray46 { - public: - ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3), - v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), - v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), - v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), - v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), - v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), - v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), - v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46> +class ValueArray46 +{ +public: + ValueArray46(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_), static_cast(v41_), - static_cast(v42_), static_cast(v43_), static_cast(v44_), - static_cast(v45_), static_cast(v46_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray46& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray46& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; - const T41 v41_; - const T42 v42_; - const T43 v43_; - const T44 v44_; - const T45 v45_; - const T46 v46_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; }; template -class ValueArray47 { - public: - ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2), - v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), - v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), - v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), - v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), - v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), - v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), - v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), - v47_(v47) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47> +class ValueArray47 +{ +public: + ValueArray47(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), v47_(v47) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_), static_cast(v41_), - static_cast(v42_), static_cast(v43_), static_cast(v44_), - static_cast(v45_), static_cast(v46_), static_cast(v47_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_), static_cast(v47_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray47& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray47& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; - const T41 v41_; - const T42 v42_; - const T43 v43_; - const T44 v44_; - const T45 v45_; - const T46 v46_; - const T47 v47_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; }; template -class ValueArray48 { - public: - ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1), - v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), - v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), - v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), - v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), - v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), - v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), - v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), - v46_(v46), v47_(v47), v48_(v48) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48> +class ValueArray48 +{ +public: + ValueArray48(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48) : v1_(v1), + v2_(v2), + v3_(v3), + v4_(v4), + v5_(v5), + v6_(v6), + v7_(v7), + v8_(v8), + v9_(v9), + v10_(v10), + v11_(v11), + v12_(v12), + v13_(v13), + v14_(v14), + v15_(v15), + v16_(v16), + v17_(v17), + v18_(v18), + v19_(v19), + v20_(v20), + v21_(v21), + v22_(v22), + v23_(v23), + v24_(v24), + v25_(v25), + v26_(v26), + v27_(v27), + v28_(v28), + v29_(v29), + v30_(v30), + v31_(v31), + v32_(v32), + v33_(v33), + v34_(v34), + v35_(v35), + v36_(v36), + v37_(v37), + v38_(v38), + v39_(v39), + v40_(v40), + v41_(v41), + v42_(v42), + v43_(v43), + v44_(v44), + v45_(v45), + v46_(v46), + v47_(v47), + v48_(v48) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_), static_cast(v41_), - static_cast(v42_), static_cast(v43_), static_cast(v44_), - static_cast(v45_), static_cast(v46_), static_cast(v47_), - static_cast(v48_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_), static_cast(v47_), + static_cast(v48_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray48& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray48& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; - const T41 v41_; - const T42 v42_; - const T43 v43_; - const T44 v44_; - const T45 v45_; - const T46 v46_; - const T47 v47_; - const T48 v48_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; }; template -class ValueArray49 { - public: - ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, - T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), - v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), - v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), - v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), - v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), - v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), - v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49> +class ValueArray49 +{ +public: + ValueArray49(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, + T49 v49) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_), static_cast(v41_), - static_cast(v42_), static_cast(v43_), static_cast(v44_), - static_cast(v45_), static_cast(v46_), static_cast(v47_), - static_cast(v48_), static_cast(v49_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_), static_cast(v47_), + static_cast(v48_), static_cast(v49_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray49& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray49& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; - const T41 v41_; - const T42 v42_; - const T43 v43_; - const T44 v44_; - const T45 v45_; - const T46 v46_; - const T47 v47_; - const T48 v48_; - const T49 v49_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; + const T49 v49_; }; template -class ValueArray50 { - public: - ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, - T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, - T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, - T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, - T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, - T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49, - T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), - v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), - v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), - v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), - v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), - v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), - v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), - v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {} + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49, typename T50> +class ValueArray50 +{ +public: + ValueArray50(T1 v1, T2 v2, T3 v3, T4 v4, T5 v5, T6 v6, T7 v7, T8 v8, T9 v9, + T10 v10, T11 v11, T12 v12, T13 v13, T14 v14, T15 v15, T16 v16, T17 v17, + T18 v18, T19 v19, T20 v20, T21 v21, T22 v22, T23 v23, T24 v24, T25 v25, + T26 v26, T27 v27, T28 v28, T29 v29, T30 v30, T31 v31, T32 v32, T33 v33, + T34 v34, T35 v35, T36 v36, T37 v37, T38 v38, T39 v39, T40 v40, T41 v41, + T42 v42, T43 v43, T44 v44, T45 v45, T46 v46, T47 v47, T48 v48, T49 v49, + T50 v50) : v1_(v1), v2_(v2), v3_(v3), v4_(v4), v5_(v5), v6_(v6), v7_(v7), v8_(v8), v9_(v9), v10_(v10), v11_(v11), v12_(v12), v13_(v13), v14_(v14), v15_(v15), v16_(v16), v17_(v17), v18_(v18), v19_(v19), v20_(v20), v21_(v21), v22_(v22), v23_(v23), v24_(v24), v25_(v25), v26_(v26), v27_(v27), v28_(v28), v29_(v29), v30_(v30), v31_(v31), v32_(v32), v33_(v33), v34_(v34), v35_(v35), v36_(v36), v37_(v37), v38_(v38), v39_(v39), v40_(v40), v41_(v41), v42_(v42), v43_(v43), v44_(v44), v45_(v45), v46_(v46), v47_(v47), v48_(v48), v49_(v49), v50_(v50) {} - template - operator ParamGenerator() const { - const T array[] = {static_cast(v1_), static_cast(v2_), - static_cast(v3_), static_cast(v4_), static_cast(v5_), - static_cast(v6_), static_cast(v7_), static_cast(v8_), - static_cast(v9_), static_cast(v10_), static_cast(v11_), - static_cast(v12_), static_cast(v13_), static_cast(v14_), - static_cast(v15_), static_cast(v16_), static_cast(v17_), - static_cast(v18_), static_cast(v19_), static_cast(v20_), - static_cast(v21_), static_cast(v22_), static_cast(v23_), - static_cast(v24_), static_cast(v25_), static_cast(v26_), - static_cast(v27_), static_cast(v28_), static_cast(v29_), - static_cast(v30_), static_cast(v31_), static_cast(v32_), - static_cast(v33_), static_cast(v34_), static_cast(v35_), - static_cast(v36_), static_cast(v37_), static_cast(v38_), - static_cast(v39_), static_cast(v40_), static_cast(v41_), - static_cast(v42_), static_cast(v43_), static_cast(v44_), - static_cast(v45_), static_cast(v46_), static_cast(v47_), - static_cast(v48_), static_cast(v49_), static_cast(v50_)}; - return ValuesIn(array); - } + template + operator ParamGenerator() const + { + const T array[] = {static_cast(v1_), static_cast(v2_), + static_cast(v3_), static_cast(v4_), static_cast(v5_), + static_cast(v6_), static_cast(v7_), static_cast(v8_), + static_cast(v9_), static_cast(v10_), static_cast(v11_), + static_cast(v12_), static_cast(v13_), static_cast(v14_), + static_cast(v15_), static_cast(v16_), static_cast(v17_), + static_cast(v18_), static_cast(v19_), static_cast(v20_), + static_cast(v21_), static_cast(v22_), static_cast(v23_), + static_cast(v24_), static_cast(v25_), static_cast(v26_), + static_cast(v27_), static_cast(v28_), static_cast(v29_), + static_cast(v30_), static_cast(v31_), static_cast(v32_), + static_cast(v33_), static_cast(v34_), static_cast(v35_), + static_cast(v36_), static_cast(v37_), static_cast(v38_), + static_cast(v39_), static_cast(v40_), static_cast(v41_), + static_cast(v42_), static_cast(v43_), static_cast(v44_), + static_cast(v45_), static_cast(v46_), static_cast(v47_), + static_cast(v48_), static_cast(v49_), static_cast(v50_)}; + return ValuesIn(array); + } - private: - // No implementation - assignment is unsupported. - void operator=(const ValueArray50& other); +private: + // No implementation - assignment is unsupported. + void operator=(const ValueArray50& other); - const T1 v1_; - const T2 v2_; - const T3 v3_; - const T4 v4_; - const T5 v5_; - const T6 v6_; - const T7 v7_; - const T8 v8_; - const T9 v9_; - const T10 v10_; - const T11 v11_; - const T12 v12_; - const T13 v13_; - const T14 v14_; - const T15 v15_; - const T16 v16_; - const T17 v17_; - const T18 v18_; - const T19 v19_; - const T20 v20_; - const T21 v21_; - const T22 v22_; - const T23 v23_; - const T24 v24_; - const T25 v25_; - const T26 v26_; - const T27 v27_; - const T28 v28_; - const T29 v29_; - const T30 v30_; - const T31 v31_; - const T32 v32_; - const T33 v33_; - const T34 v34_; - const T35 v35_; - const T36 v36_; - const T37 v37_; - const T38 v38_; - const T39 v39_; - const T40 v40_; - const T41 v41_; - const T42 v42_; - const T43 v43_; - const T44 v44_; - const T45 v45_; - const T46 v46_; - const T47 v47_; - const T48 v48_; - const T49 v49_; - const T50 v50_; + const T1 v1_; + const T2 v2_; + const T3 v3_; + const T4 v4_; + const T5 v5_; + const T6 v6_; + const T7 v7_; + const T8 v8_; + const T9 v9_; + const T10 v10_; + const T11 v11_; + const T12 v12_; + const T13 v13_; + const T14 v14_; + const T15 v15_; + const T16 v16_; + const T17 v17_; + const T18 v18_; + const T19 v19_; + const T20 v20_; + const T21 v21_; + const T22 v22_; + const T23 v23_; + const T24 v24_; + const T25 v25_; + const T26 v26_; + const T27 v27_; + const T28 v28_; + const T29 v29_; + const T30 v30_; + const T31 v31_; + const T32 v32_; + const T33 v33_; + const T34 v34_; + const T35 v35_; + const T36 v36_; + const T37 v37_; + const T38 v38_; + const T39 v39_; + const T40 v40_; + const T41 v41_; + const T42 v42_; + const T43 v43_; + const T44 v44_; + const T45 v45_; + const T46 v46_; + const T47 v47_; + const T48 v48_; + const T49 v49_; + const T50 v50_; }; -# if GTEST_HAS_COMBINE +#if GTEST_HAS_COMBINE // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Generates values from the Cartesian product of values produced @@ -3157,1675 +3232,1906 @@ class ValueArray50 { // template class CartesianProductGenerator2 - : public ParamGeneratorInterface< ::std::tr1::tuple > { - public: - typedef ::std::tr1::tuple ParamType; + : public ParamGeneratorInterface< ::std::tr1::tuple > +{ +public: + typedef ::std::tr1::tuple ParamType; - CartesianProductGenerator2(const ParamGenerator& g1, - const ParamGenerator& g2) - : g1_(g1), g2_(g2) {} - virtual ~CartesianProductGenerator2() {} + CartesianProductGenerator2(const ParamGenerator& g1, + const ParamGenerator& g2) + : g1_(g1), g2_(g2) {} + virtual ~CartesianProductGenerator2() {} - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin()); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, g1_, g1_.end(), g2_, g2_.end()); - } + virtual ParamIteratorInterface* Begin() const + { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin()); + } + virtual ParamIteratorInterface* End() const + { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end()); + } - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - const ParamGenerator& g1, - const typename ParamGenerator::iterator& current1, - const ParamGenerator& g2, - const typename ParamGenerator::iterator& current2) - : base_(base), - begin1_(g1.begin()), end1_(g1.end()), current1_(current1), - begin2_(g2.begin()), end2_(g2.end()), current2_(current2) { - ComputeCurrentValue(); - } - virtual ~Iterator() {} +private: + class Iterator : public ParamIteratorInterface + { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2) + : base_(base), + begin1_(g1.begin()), + end1_(g1.end()), + current1_(current1), + begin2_(g2.begin()), + end2_(g2.end()), + current2_(current2) + { + ComputeCurrentValue(); + } + virtual ~Iterator() {} - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - // Advance should not be called on beyond-of-range iterators - // so no component iterators must be beyond end of range, either. - virtual void Advance() { - assert(!AtEnd()); - ++current2_; - if (current2_ == end2_) { - current2_ = begin2_; - ++current1_; - } - ComputeCurrentValue(); - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - virtual const ParamType* Current() const { return ¤t_value_; } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const Iterator* typed_other = - CheckedDowncastToActualType(&other); - // We must report iterators equal if they both point beyond their - // respective ranges. That can happen in a variety of fashions, - // so we have to consult AtEnd(). - return (AtEnd() && typed_other->AtEnd()) || - ( - current1_ == typed_other->current1_ && - current2_ == typed_other->current2_); - } + virtual const ParamGeneratorInterface* BaseGenerator() const + { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() + { + assert(!AtEnd()); + ++current2_; + if (current2_ == end2_) + { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const + { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const + { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + (current1_ == typed_other->current1_ && + current2_ == typed_other->current2_); + } - private: - Iterator(const Iterator& other) - : base_(other.base_), - begin1_(other.begin1_), - end1_(other.end1_), - current1_(other.current1_), - begin2_(other.begin2_), - end2_(other.end2_), - current2_(other.current2_) { - ComputeCurrentValue(); - } + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_) + { + ComputeCurrentValue(); + } - void ComputeCurrentValue() { - if (!AtEnd()) - current_value_ = ParamType(*current1_, *current2_); - } - bool AtEnd() const { - // We must report iterator past the end of the range when either of the - // component iterators has reached the end of its range. - return - current1_ == end1_ || - current2_ == end2_; - } + void ComputeCurrentValue() + { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_); + } + bool AtEnd() const + { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return current1_ == end1_ || + current2_ == end2_; + } - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); - const ParamGeneratorInterface* const base_; - // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. - // current[i]_ is the actual traversing iterator. - const typename ParamGenerator::iterator begin1_; - const typename ParamGenerator::iterator end1_; - typename ParamGenerator::iterator current1_; - const typename ParamGenerator::iterator begin2_; - const typename ParamGenerator::iterator end2_; - typename ParamGenerator::iterator current2_; - ParamType current_value_; - }; // class CartesianProductGenerator2::Iterator + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + ParamType current_value_; + }; // class CartesianProductGenerator2::Iterator - // No implementation - assignment is unsupported. - void operator=(const CartesianProductGenerator2& other); + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator2& other); - const ParamGenerator g1_; - const ParamGenerator g2_; + const ParamGenerator g1_; + const ParamGenerator g2_; }; // class CartesianProductGenerator2 - template class CartesianProductGenerator3 - : public ParamGeneratorInterface< ::std::tr1::tuple > { - public: - typedef ::std::tr1::tuple ParamType; + : public ParamGeneratorInterface< ::std::tr1::tuple > +{ +public: + typedef ::std::tr1::tuple ParamType; - CartesianProductGenerator3(const ParamGenerator& g1, - const ParamGenerator& g2, const ParamGenerator& g3) - : g1_(g1), g2_(g2), g3_(g3) {} - virtual ~CartesianProductGenerator3() {} + CartesianProductGenerator3(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3) + : g1_(g1), g2_(g2), g3_(g3) {} + virtual ~CartesianProductGenerator3() {} - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, - g3_.begin()); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end()); - } + virtual ParamIteratorInterface* Begin() const + { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin()); + } + virtual ParamIteratorInterface* End() const + { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end()); + } - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - const ParamGenerator& g1, - const typename ParamGenerator::iterator& current1, - const ParamGenerator& g2, - const typename ParamGenerator::iterator& current2, - const ParamGenerator& g3, - const typename ParamGenerator::iterator& current3) - : base_(base), - begin1_(g1.begin()), end1_(g1.end()), current1_(current1), - begin2_(g2.begin()), end2_(g2.end()), current2_(current2), - begin3_(g3.begin()), end3_(g3.end()), current3_(current3) { - ComputeCurrentValue(); - } - virtual ~Iterator() {} +private: + class Iterator : public ParamIteratorInterface + { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3) + : base_(base), + begin1_(g1.begin()), + end1_(g1.end()), + current1_(current1), + begin2_(g2.begin()), + end2_(g2.end()), + current2_(current2), + begin3_(g3.begin()), + end3_(g3.end()), + current3_(current3) + { + ComputeCurrentValue(); + } + virtual ~Iterator() {} - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - // Advance should not be called on beyond-of-range iterators - // so no component iterators must be beyond end of range, either. - virtual void Advance() { - assert(!AtEnd()); - ++current3_; - if (current3_ == end3_) { - current3_ = begin3_; - ++current2_; - } - if (current2_ == end2_) { - current2_ = begin2_; - ++current1_; - } - ComputeCurrentValue(); - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - virtual const ParamType* Current() const { return ¤t_value_; } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const Iterator* typed_other = - CheckedDowncastToActualType(&other); - // We must report iterators equal if they both point beyond their - // respective ranges. That can happen in a variety of fashions, - // so we have to consult AtEnd(). - return (AtEnd() && typed_other->AtEnd()) || - ( - current1_ == typed_other->current1_ && - current2_ == typed_other->current2_ && - current3_ == typed_other->current3_); - } + virtual const ParamGeneratorInterface* BaseGenerator() const + { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() + { + assert(!AtEnd()); + ++current3_; + if (current3_ == end3_) + { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) + { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const + { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const + { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + (current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_); + } - private: - Iterator(const Iterator& other) - : base_(other.base_), - begin1_(other.begin1_), - end1_(other.end1_), - current1_(other.current1_), - begin2_(other.begin2_), - end2_(other.end2_), - current2_(other.current2_), - begin3_(other.begin3_), - end3_(other.end3_), - current3_(other.current3_) { - ComputeCurrentValue(); - } + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_) + { + ComputeCurrentValue(); + } - void ComputeCurrentValue() { - if (!AtEnd()) - current_value_ = ParamType(*current1_, *current2_, *current3_); - } - bool AtEnd() const { - // We must report iterator past the end of the range when either of the - // component iterators has reached the end of its range. - return - current1_ == end1_ || - current2_ == end2_ || - current3_ == end3_; - } + void ComputeCurrentValue() + { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_); + } + bool AtEnd() const + { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_; + } - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); - const ParamGeneratorInterface* const base_; - // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. - // current[i]_ is the actual traversing iterator. - const typename ParamGenerator::iterator begin1_; - const typename ParamGenerator::iterator end1_; - typename ParamGenerator::iterator current1_; - const typename ParamGenerator::iterator begin2_; - const typename ParamGenerator::iterator end2_; - typename ParamGenerator::iterator current2_; - const typename ParamGenerator::iterator begin3_; - const typename ParamGenerator::iterator end3_; - typename ParamGenerator::iterator current3_; - ParamType current_value_; - }; // class CartesianProductGenerator3::Iterator + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + ParamType current_value_; + }; // class CartesianProductGenerator3::Iterator - // No implementation - assignment is unsupported. - void operator=(const CartesianProductGenerator3& other); + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator3& other); - const ParamGenerator g1_; - const ParamGenerator g2_; - const ParamGenerator g3_; + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; }; // class CartesianProductGenerator3 - template class CartesianProductGenerator4 - : public ParamGeneratorInterface< ::std::tr1::tuple > { - public: - typedef ::std::tr1::tuple ParamType; + : public ParamGeneratorInterface< ::std::tr1::tuple > +{ +public: + typedef ::std::tr1::tuple ParamType; - CartesianProductGenerator4(const ParamGenerator& g1, - const ParamGenerator& g2, const ParamGenerator& g3, - const ParamGenerator& g4) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} - virtual ~CartesianProductGenerator4() {} + CartesianProductGenerator4(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} + virtual ~CartesianProductGenerator4() {} - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, - g3_.begin(), g4_, g4_.begin()); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), - g4_, g4_.end()); - } + virtual ParamIteratorInterface* Begin() const + { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin()); + } + virtual ParamIteratorInterface* End() const + { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end()); + } - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - const ParamGenerator& g1, - const typename ParamGenerator::iterator& current1, - const ParamGenerator& g2, - const typename ParamGenerator::iterator& current2, - const ParamGenerator& g3, - const typename ParamGenerator::iterator& current3, - const ParamGenerator& g4, - const typename ParamGenerator::iterator& current4) - : base_(base), - begin1_(g1.begin()), end1_(g1.end()), current1_(current1), - begin2_(g2.begin()), end2_(g2.end()), current2_(current2), - begin3_(g3.begin()), end3_(g3.end()), current3_(current3), - begin4_(g4.begin()), end4_(g4.end()), current4_(current4) { - ComputeCurrentValue(); - } - virtual ~Iterator() {} +private: + class Iterator : public ParamIteratorInterface + { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4) + : base_(base), + begin1_(g1.begin()), + end1_(g1.end()), + current1_(current1), + begin2_(g2.begin()), + end2_(g2.end()), + current2_(current2), + begin3_(g3.begin()), + end3_(g3.end()), + current3_(current3), + begin4_(g4.begin()), + end4_(g4.end()), + current4_(current4) + { + ComputeCurrentValue(); + } + virtual ~Iterator() {} - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - // Advance should not be called on beyond-of-range iterators - // so no component iterators must be beyond end of range, either. - virtual void Advance() { - assert(!AtEnd()); - ++current4_; - if (current4_ == end4_) { - current4_ = begin4_; - ++current3_; - } - if (current3_ == end3_) { - current3_ = begin3_; - ++current2_; - } - if (current2_ == end2_) { - current2_ = begin2_; - ++current1_; - } - ComputeCurrentValue(); - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - virtual const ParamType* Current() const { return ¤t_value_; } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const Iterator* typed_other = - CheckedDowncastToActualType(&other); - // We must report iterators equal if they both point beyond their - // respective ranges. That can happen in a variety of fashions, - // so we have to consult AtEnd(). - return (AtEnd() && typed_other->AtEnd()) || - ( - current1_ == typed_other->current1_ && - current2_ == typed_other->current2_ && - current3_ == typed_other->current3_ && - current4_ == typed_other->current4_); - } + virtual const ParamGeneratorInterface* BaseGenerator() const + { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() + { + assert(!AtEnd()); + ++current4_; + if (current4_ == end4_) + { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) + { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) + { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const + { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const + { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + (current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_); + } - private: - Iterator(const Iterator& other) - : base_(other.base_), - begin1_(other.begin1_), - end1_(other.end1_), - current1_(other.current1_), - begin2_(other.begin2_), - end2_(other.end2_), - current2_(other.current2_), - begin3_(other.begin3_), - end3_(other.end3_), - current3_(other.current3_), - begin4_(other.begin4_), - end4_(other.end4_), - current4_(other.current4_) { - ComputeCurrentValue(); - } + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_) + { + ComputeCurrentValue(); + } - void ComputeCurrentValue() { - if (!AtEnd()) - current_value_ = ParamType(*current1_, *current2_, *current3_, - *current4_); - } - bool AtEnd() const { - // We must report iterator past the end of the range when either of the - // component iterators has reached the end of its range. - return - current1_ == end1_ || - current2_ == end2_ || - current3_ == end3_ || - current4_ == end4_; - } + void ComputeCurrentValue() + { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_); + } + bool AtEnd() const + { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_; + } - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); - const ParamGeneratorInterface* const base_; - // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. - // current[i]_ is the actual traversing iterator. - const typename ParamGenerator::iterator begin1_; - const typename ParamGenerator::iterator end1_; - typename ParamGenerator::iterator current1_; - const typename ParamGenerator::iterator begin2_; - const typename ParamGenerator::iterator end2_; - typename ParamGenerator::iterator current2_; - const typename ParamGenerator::iterator begin3_; - const typename ParamGenerator::iterator end3_; - typename ParamGenerator::iterator current3_; - const typename ParamGenerator::iterator begin4_; - const typename ParamGenerator::iterator end4_; - typename ParamGenerator::iterator current4_; - ParamType current_value_; - }; // class CartesianProductGenerator4::Iterator + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + ParamType current_value_; + }; // class CartesianProductGenerator4::Iterator - // No implementation - assignment is unsupported. - void operator=(const CartesianProductGenerator4& other); + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator4& other); - const ParamGenerator g1_; - const ParamGenerator g2_; - const ParamGenerator g3_; - const ParamGenerator g4_; + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; }; // class CartesianProductGenerator4 - template class CartesianProductGenerator5 - : public ParamGeneratorInterface< ::std::tr1::tuple > { - public: - typedef ::std::tr1::tuple ParamType; + : public ParamGeneratorInterface< ::std::tr1::tuple > +{ +public: + typedef ::std::tr1::tuple ParamType; - CartesianProductGenerator5(const ParamGenerator& g1, - const ParamGenerator& g2, const ParamGenerator& g3, - const ParamGenerator& g4, const ParamGenerator& g5) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} - virtual ~CartesianProductGenerator5() {} + CartesianProductGenerator5(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} + virtual ~CartesianProductGenerator5() {} - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, - g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin()); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), - g4_, g4_.end(), g5_, g5_.end()); - } + virtual ParamIteratorInterface* Begin() const + { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin()); + } + virtual ParamIteratorInterface* End() const + { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end()); + } - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - const ParamGenerator& g1, - const typename ParamGenerator::iterator& current1, - const ParamGenerator& g2, - const typename ParamGenerator::iterator& current2, - const ParamGenerator& g3, - const typename ParamGenerator::iterator& current3, - const ParamGenerator& g4, - const typename ParamGenerator::iterator& current4, - const ParamGenerator& g5, - const typename ParamGenerator::iterator& current5) - : base_(base), - begin1_(g1.begin()), end1_(g1.end()), current1_(current1), - begin2_(g2.begin()), end2_(g2.end()), current2_(current2), - begin3_(g3.begin()), end3_(g3.end()), current3_(current3), - begin4_(g4.begin()), end4_(g4.end()), current4_(current4), - begin5_(g5.begin()), end5_(g5.end()), current5_(current5) { - ComputeCurrentValue(); - } - virtual ~Iterator() {} +private: + class Iterator : public ParamIteratorInterface + { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5) + : base_(base), + begin1_(g1.begin()), + end1_(g1.end()), + current1_(current1), + begin2_(g2.begin()), + end2_(g2.end()), + current2_(current2), + begin3_(g3.begin()), + end3_(g3.end()), + current3_(current3), + begin4_(g4.begin()), + end4_(g4.end()), + current4_(current4), + begin5_(g5.begin()), + end5_(g5.end()), + current5_(current5) + { + ComputeCurrentValue(); + } + virtual ~Iterator() {} - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - // Advance should not be called on beyond-of-range iterators - // so no component iterators must be beyond end of range, either. - virtual void Advance() { - assert(!AtEnd()); - ++current5_; - if (current5_ == end5_) { - current5_ = begin5_; - ++current4_; - } - if (current4_ == end4_) { - current4_ = begin4_; - ++current3_; - } - if (current3_ == end3_) { - current3_ = begin3_; - ++current2_; - } - if (current2_ == end2_) { - current2_ = begin2_; - ++current1_; - } - ComputeCurrentValue(); - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - virtual const ParamType* Current() const { return ¤t_value_; } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const Iterator* typed_other = - CheckedDowncastToActualType(&other); - // We must report iterators equal if they both point beyond their - // respective ranges. That can happen in a variety of fashions, - // so we have to consult AtEnd(). - return (AtEnd() && typed_other->AtEnd()) || - ( - current1_ == typed_other->current1_ && - current2_ == typed_other->current2_ && - current3_ == typed_other->current3_ && - current4_ == typed_other->current4_ && - current5_ == typed_other->current5_); - } + virtual const ParamGeneratorInterface* BaseGenerator() const + { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() + { + assert(!AtEnd()); + ++current5_; + if (current5_ == end5_) + { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) + { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) + { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) + { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const + { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const + { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + (current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_); + } - private: - Iterator(const Iterator& other) - : base_(other.base_), - begin1_(other.begin1_), - end1_(other.end1_), - current1_(other.current1_), - begin2_(other.begin2_), - end2_(other.end2_), - current2_(other.current2_), - begin3_(other.begin3_), - end3_(other.end3_), - current3_(other.current3_), - begin4_(other.begin4_), - end4_(other.end4_), - current4_(other.current4_), - begin5_(other.begin5_), - end5_(other.end5_), - current5_(other.current5_) { - ComputeCurrentValue(); - } + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_) + { + ComputeCurrentValue(); + } - void ComputeCurrentValue() { - if (!AtEnd()) - current_value_ = ParamType(*current1_, *current2_, *current3_, - *current4_, *current5_); - } - bool AtEnd() const { - // We must report iterator past the end of the range when either of the - // component iterators has reached the end of its range. - return - current1_ == end1_ || - current2_ == end2_ || - current3_ == end3_ || - current4_ == end4_ || - current5_ == end5_; - } + void ComputeCurrentValue() + { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_); + } + bool AtEnd() const + { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_; + } - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); - const ParamGeneratorInterface* const base_; - // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. - // current[i]_ is the actual traversing iterator. - const typename ParamGenerator::iterator begin1_; - const typename ParamGenerator::iterator end1_; - typename ParamGenerator::iterator current1_; - const typename ParamGenerator::iterator begin2_; - const typename ParamGenerator::iterator end2_; - typename ParamGenerator::iterator current2_; - const typename ParamGenerator::iterator begin3_; - const typename ParamGenerator::iterator end3_; - typename ParamGenerator::iterator current3_; - const typename ParamGenerator::iterator begin4_; - const typename ParamGenerator::iterator end4_; - typename ParamGenerator::iterator current4_; - const typename ParamGenerator::iterator begin5_; - const typename ParamGenerator::iterator end5_; - typename ParamGenerator::iterator current5_; - ParamType current_value_; - }; // class CartesianProductGenerator5::Iterator + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + ParamType current_value_; + }; // class CartesianProductGenerator5::Iterator - // No implementation - assignment is unsupported. - void operator=(const CartesianProductGenerator5& other); + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator5& other); - const ParamGenerator g1_; - const ParamGenerator g2_; - const ParamGenerator g3_; - const ParamGenerator g4_; - const ParamGenerator g5_; + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; }; // class CartesianProductGenerator5 - template + typename T6> class CartesianProductGenerator6 - : public ParamGeneratorInterface< ::std::tr1::tuple > { - public: - typedef ::std::tr1::tuple ParamType; + : public ParamGeneratorInterface< ::std::tr1::tuple > +{ +public: + typedef ::std::tr1::tuple ParamType; - CartesianProductGenerator6(const ParamGenerator& g1, - const ParamGenerator& g2, const ParamGenerator& g3, - const ParamGenerator& g4, const ParamGenerator& g5, - const ParamGenerator& g6) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} - virtual ~CartesianProductGenerator6() {} + CartesianProductGenerator6(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} + virtual ~CartesianProductGenerator6() {} - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, - g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin()); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), - g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end()); - } + virtual ParamIteratorInterface* Begin() const + { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin()); + } + virtual ParamIteratorInterface* End() const + { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end()); + } - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - const ParamGenerator& g1, - const typename ParamGenerator::iterator& current1, - const ParamGenerator& g2, - const typename ParamGenerator::iterator& current2, - const ParamGenerator& g3, - const typename ParamGenerator::iterator& current3, - const ParamGenerator& g4, - const typename ParamGenerator::iterator& current4, - const ParamGenerator& g5, - const typename ParamGenerator::iterator& current5, - const ParamGenerator& g6, - const typename ParamGenerator::iterator& current6) - : base_(base), - begin1_(g1.begin()), end1_(g1.end()), current1_(current1), - begin2_(g2.begin()), end2_(g2.end()), current2_(current2), - begin3_(g3.begin()), end3_(g3.end()), current3_(current3), - begin4_(g4.begin()), end4_(g4.end()), current4_(current4), - begin5_(g5.begin()), end5_(g5.end()), current5_(current5), - begin6_(g6.begin()), end6_(g6.end()), current6_(current6) { - ComputeCurrentValue(); - } - virtual ~Iterator() {} +private: + class Iterator : public ParamIteratorInterface + { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6) + : base_(base), + begin1_(g1.begin()), + end1_(g1.end()), + current1_(current1), + begin2_(g2.begin()), + end2_(g2.end()), + current2_(current2), + begin3_(g3.begin()), + end3_(g3.end()), + current3_(current3), + begin4_(g4.begin()), + end4_(g4.end()), + current4_(current4), + begin5_(g5.begin()), + end5_(g5.end()), + current5_(current5), + begin6_(g6.begin()), + end6_(g6.end()), + current6_(current6) + { + ComputeCurrentValue(); + } + virtual ~Iterator() {} - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - // Advance should not be called on beyond-of-range iterators - // so no component iterators must be beyond end of range, either. - virtual void Advance() { - assert(!AtEnd()); - ++current6_; - if (current6_ == end6_) { - current6_ = begin6_; - ++current5_; - } - if (current5_ == end5_) { - current5_ = begin5_; - ++current4_; - } - if (current4_ == end4_) { - current4_ = begin4_; - ++current3_; - } - if (current3_ == end3_) { - current3_ = begin3_; - ++current2_; - } - if (current2_ == end2_) { - current2_ = begin2_; - ++current1_; - } - ComputeCurrentValue(); - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - virtual const ParamType* Current() const { return ¤t_value_; } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const Iterator* typed_other = - CheckedDowncastToActualType(&other); - // We must report iterators equal if they both point beyond their - // respective ranges. That can happen in a variety of fashions, - // so we have to consult AtEnd(). - return (AtEnd() && typed_other->AtEnd()) || - ( - current1_ == typed_other->current1_ && - current2_ == typed_other->current2_ && - current3_ == typed_other->current3_ && - current4_ == typed_other->current4_ && - current5_ == typed_other->current5_ && - current6_ == typed_other->current6_); - } + virtual const ParamGeneratorInterface* BaseGenerator() const + { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() + { + assert(!AtEnd()); + ++current6_; + if (current6_ == end6_) + { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) + { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) + { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) + { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) + { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const + { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const + { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + (current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_); + } - private: - Iterator(const Iterator& other) - : base_(other.base_), - begin1_(other.begin1_), - end1_(other.end1_), - current1_(other.current1_), - begin2_(other.begin2_), - end2_(other.end2_), - current2_(other.current2_), - begin3_(other.begin3_), - end3_(other.end3_), - current3_(other.current3_), - begin4_(other.begin4_), - end4_(other.end4_), - current4_(other.current4_), - begin5_(other.begin5_), - end5_(other.end5_), - current5_(other.current5_), - begin6_(other.begin6_), - end6_(other.end6_), - current6_(other.current6_) { - ComputeCurrentValue(); - } + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_) + { + ComputeCurrentValue(); + } - void ComputeCurrentValue() { - if (!AtEnd()) - current_value_ = ParamType(*current1_, *current2_, *current3_, - *current4_, *current5_, *current6_); - } - bool AtEnd() const { - // We must report iterator past the end of the range when either of the - // component iterators has reached the end of its range. - return - current1_ == end1_ || - current2_ == end2_ || - current3_ == end3_ || - current4_ == end4_ || - current5_ == end5_ || - current6_ == end6_; - } + void ComputeCurrentValue() + { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_); + } + bool AtEnd() const + { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_; + } - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); - const ParamGeneratorInterface* const base_; - // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. - // current[i]_ is the actual traversing iterator. - const typename ParamGenerator::iterator begin1_; - const typename ParamGenerator::iterator end1_; - typename ParamGenerator::iterator current1_; - const typename ParamGenerator::iterator begin2_; - const typename ParamGenerator::iterator end2_; - typename ParamGenerator::iterator current2_; - const typename ParamGenerator::iterator begin3_; - const typename ParamGenerator::iterator end3_; - typename ParamGenerator::iterator current3_; - const typename ParamGenerator::iterator begin4_; - const typename ParamGenerator::iterator end4_; - typename ParamGenerator::iterator current4_; - const typename ParamGenerator::iterator begin5_; - const typename ParamGenerator::iterator end5_; - typename ParamGenerator::iterator current5_; - const typename ParamGenerator::iterator begin6_; - const typename ParamGenerator::iterator end6_; - typename ParamGenerator::iterator current6_; - ParamType current_value_; - }; // class CartesianProductGenerator6::Iterator + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + ParamType current_value_; + }; // class CartesianProductGenerator6::Iterator - // No implementation - assignment is unsupported. - void operator=(const CartesianProductGenerator6& other); + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator6& other); - const ParamGenerator g1_; - const ParamGenerator g2_; - const ParamGenerator g3_; - const ParamGenerator g4_; - const ParamGenerator g5_; - const ParamGenerator g6_; + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; }; // class CartesianProductGenerator6 - template + typename T6, typename T7> class CartesianProductGenerator7 - : public ParamGeneratorInterface< ::std::tr1::tuple > { - public: - typedef ::std::tr1::tuple ParamType; + : public ParamGeneratorInterface< ::std::tr1::tuple > +{ +public: + typedef ::std::tr1::tuple ParamType; - CartesianProductGenerator7(const ParamGenerator& g1, - const ParamGenerator& g2, const ParamGenerator& g3, - const ParamGenerator& g4, const ParamGenerator& g5, - const ParamGenerator& g6, const ParamGenerator& g7) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} - virtual ~CartesianProductGenerator7() {} + CartesianProductGenerator7(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} + virtual ~CartesianProductGenerator7() {} - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, - g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, - g7_.begin()); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), - g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end()); - } + virtual ParamIteratorInterface* Begin() const + { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin()); + } + virtual ParamIteratorInterface* End() const + { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end()); + } - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - const ParamGenerator& g1, - const typename ParamGenerator::iterator& current1, - const ParamGenerator& g2, - const typename ParamGenerator::iterator& current2, - const ParamGenerator& g3, - const typename ParamGenerator::iterator& current3, - const ParamGenerator& g4, - const typename ParamGenerator::iterator& current4, - const ParamGenerator& g5, - const typename ParamGenerator::iterator& current5, - const ParamGenerator& g6, - const typename ParamGenerator::iterator& current6, - const ParamGenerator& g7, - const typename ParamGenerator::iterator& current7) - : base_(base), - begin1_(g1.begin()), end1_(g1.end()), current1_(current1), - begin2_(g2.begin()), end2_(g2.end()), current2_(current2), - begin3_(g3.begin()), end3_(g3.end()), current3_(current3), - begin4_(g4.begin()), end4_(g4.end()), current4_(current4), - begin5_(g5.begin()), end5_(g5.end()), current5_(current5), - begin6_(g6.begin()), end6_(g6.end()), current6_(current6), - begin7_(g7.begin()), end7_(g7.end()), current7_(current7) { - ComputeCurrentValue(); - } - virtual ~Iterator() {} +private: + class Iterator : public ParamIteratorInterface + { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7) + : base_(base), + begin1_(g1.begin()), + end1_(g1.end()), + current1_(current1), + begin2_(g2.begin()), + end2_(g2.end()), + current2_(current2), + begin3_(g3.begin()), + end3_(g3.end()), + current3_(current3), + begin4_(g4.begin()), + end4_(g4.end()), + current4_(current4), + begin5_(g5.begin()), + end5_(g5.end()), + current5_(current5), + begin6_(g6.begin()), + end6_(g6.end()), + current6_(current6), + begin7_(g7.begin()), + end7_(g7.end()), + current7_(current7) + { + ComputeCurrentValue(); + } + virtual ~Iterator() {} - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - // Advance should not be called on beyond-of-range iterators - // so no component iterators must be beyond end of range, either. - virtual void Advance() { - assert(!AtEnd()); - ++current7_; - if (current7_ == end7_) { - current7_ = begin7_; - ++current6_; - } - if (current6_ == end6_) { - current6_ = begin6_; - ++current5_; - } - if (current5_ == end5_) { - current5_ = begin5_; - ++current4_; - } - if (current4_ == end4_) { - current4_ = begin4_; - ++current3_; - } - if (current3_ == end3_) { - current3_ = begin3_; - ++current2_; - } - if (current2_ == end2_) { - current2_ = begin2_; - ++current1_; - } - ComputeCurrentValue(); - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - virtual const ParamType* Current() const { return ¤t_value_; } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const Iterator* typed_other = - CheckedDowncastToActualType(&other); - // We must report iterators equal if they both point beyond their - // respective ranges. That can happen in a variety of fashions, - // so we have to consult AtEnd(). - return (AtEnd() && typed_other->AtEnd()) || - ( - current1_ == typed_other->current1_ && - current2_ == typed_other->current2_ && - current3_ == typed_other->current3_ && - current4_ == typed_other->current4_ && - current5_ == typed_other->current5_ && - current6_ == typed_other->current6_ && - current7_ == typed_other->current7_); - } + virtual const ParamGeneratorInterface* BaseGenerator() const + { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() + { + assert(!AtEnd()); + ++current7_; + if (current7_ == end7_) + { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) + { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) + { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) + { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) + { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) + { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const + { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const + { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + (current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_); + } - private: - Iterator(const Iterator& other) - : base_(other.base_), - begin1_(other.begin1_), - end1_(other.end1_), - current1_(other.current1_), - begin2_(other.begin2_), - end2_(other.end2_), - current2_(other.current2_), - begin3_(other.begin3_), - end3_(other.end3_), - current3_(other.current3_), - begin4_(other.begin4_), - end4_(other.end4_), - current4_(other.current4_), - begin5_(other.begin5_), - end5_(other.end5_), - current5_(other.current5_), - begin6_(other.begin6_), - end6_(other.end6_), - current6_(other.current6_), - begin7_(other.begin7_), - end7_(other.end7_), - current7_(other.current7_) { - ComputeCurrentValue(); - } + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_) + { + ComputeCurrentValue(); + } - void ComputeCurrentValue() { - if (!AtEnd()) - current_value_ = ParamType(*current1_, *current2_, *current3_, - *current4_, *current5_, *current6_, *current7_); - } - bool AtEnd() const { - // We must report iterator past the end of the range when either of the - // component iterators has reached the end of its range. - return - current1_ == end1_ || - current2_ == end2_ || - current3_ == end3_ || - current4_ == end4_ || - current5_ == end5_ || - current6_ == end6_ || - current7_ == end7_; - } + void ComputeCurrentValue() + { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_); + } + bool AtEnd() const + { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_; + } - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); - const ParamGeneratorInterface* const base_; - // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. - // current[i]_ is the actual traversing iterator. - const typename ParamGenerator::iterator begin1_; - const typename ParamGenerator::iterator end1_; - typename ParamGenerator::iterator current1_; - const typename ParamGenerator::iterator begin2_; - const typename ParamGenerator::iterator end2_; - typename ParamGenerator::iterator current2_; - const typename ParamGenerator::iterator begin3_; - const typename ParamGenerator::iterator end3_; - typename ParamGenerator::iterator current3_; - const typename ParamGenerator::iterator begin4_; - const typename ParamGenerator::iterator end4_; - typename ParamGenerator::iterator current4_; - const typename ParamGenerator::iterator begin5_; - const typename ParamGenerator::iterator end5_; - typename ParamGenerator::iterator current5_; - const typename ParamGenerator::iterator begin6_; - const typename ParamGenerator::iterator end6_; - typename ParamGenerator::iterator current6_; - const typename ParamGenerator::iterator begin7_; - const typename ParamGenerator::iterator end7_; - typename ParamGenerator::iterator current7_; - ParamType current_value_; - }; // class CartesianProductGenerator7::Iterator + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + ParamType current_value_; + }; // class CartesianProductGenerator7::Iterator - // No implementation - assignment is unsupported. - void operator=(const CartesianProductGenerator7& other); + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator7& other); - const ParamGenerator g1_; - const ParamGenerator g2_; - const ParamGenerator g3_; - const ParamGenerator g4_; - const ParamGenerator g5_; - const ParamGenerator g6_; - const ParamGenerator g7_; + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; }; // class CartesianProductGenerator7 - template + typename T6, typename T7, typename T8> class CartesianProductGenerator8 - : public ParamGeneratorInterface< ::std::tr1::tuple > { - public: - typedef ::std::tr1::tuple ParamType; + : public ParamGeneratorInterface< ::std::tr1::tuple > +{ +public: + typedef ::std::tr1::tuple ParamType; - CartesianProductGenerator8(const ParamGenerator& g1, - const ParamGenerator& g2, const ParamGenerator& g3, - const ParamGenerator& g4, const ParamGenerator& g5, - const ParamGenerator& g6, const ParamGenerator& g7, - const ParamGenerator& g8) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), - g8_(g8) {} - virtual ~CartesianProductGenerator8() {} + CartesianProductGenerator8(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8) {} + virtual ~CartesianProductGenerator8() {} - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, - g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, - g7_.begin(), g8_, g8_.begin()); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), - g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, - g8_.end()); - } + virtual ParamIteratorInterface* Begin() const + { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin()); + } + virtual ParamIteratorInterface* End() const + { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end()); + } - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - const ParamGenerator& g1, - const typename ParamGenerator::iterator& current1, - const ParamGenerator& g2, - const typename ParamGenerator::iterator& current2, - const ParamGenerator& g3, - const typename ParamGenerator::iterator& current3, - const ParamGenerator& g4, - const typename ParamGenerator::iterator& current4, - const ParamGenerator& g5, - const typename ParamGenerator::iterator& current5, - const ParamGenerator& g6, - const typename ParamGenerator::iterator& current6, - const ParamGenerator& g7, - const typename ParamGenerator::iterator& current7, - const ParamGenerator& g8, - const typename ParamGenerator::iterator& current8) - : base_(base), - begin1_(g1.begin()), end1_(g1.end()), current1_(current1), - begin2_(g2.begin()), end2_(g2.end()), current2_(current2), - begin3_(g3.begin()), end3_(g3.end()), current3_(current3), - begin4_(g4.begin()), end4_(g4.end()), current4_(current4), - begin5_(g5.begin()), end5_(g5.end()), current5_(current5), - begin6_(g6.begin()), end6_(g6.end()), current6_(current6), - begin7_(g7.begin()), end7_(g7.end()), current7_(current7), - begin8_(g8.begin()), end8_(g8.end()), current8_(current8) { - ComputeCurrentValue(); - } - virtual ~Iterator() {} +private: + class Iterator : public ParamIteratorInterface + { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8) + : base_(base), + begin1_(g1.begin()), + end1_(g1.end()), + current1_(current1), + begin2_(g2.begin()), + end2_(g2.end()), + current2_(current2), + begin3_(g3.begin()), + end3_(g3.end()), + current3_(current3), + begin4_(g4.begin()), + end4_(g4.end()), + current4_(current4), + begin5_(g5.begin()), + end5_(g5.end()), + current5_(current5), + begin6_(g6.begin()), + end6_(g6.end()), + current6_(current6), + begin7_(g7.begin()), + end7_(g7.end()), + current7_(current7), + begin8_(g8.begin()), + end8_(g8.end()), + current8_(current8) + { + ComputeCurrentValue(); + } + virtual ~Iterator() {} - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - // Advance should not be called on beyond-of-range iterators - // so no component iterators must be beyond end of range, either. - virtual void Advance() { - assert(!AtEnd()); - ++current8_; - if (current8_ == end8_) { - current8_ = begin8_; - ++current7_; - } - if (current7_ == end7_) { - current7_ = begin7_; - ++current6_; - } - if (current6_ == end6_) { - current6_ = begin6_; - ++current5_; - } - if (current5_ == end5_) { - current5_ = begin5_; - ++current4_; - } - if (current4_ == end4_) { - current4_ = begin4_; - ++current3_; - } - if (current3_ == end3_) { - current3_ = begin3_; - ++current2_; - } - if (current2_ == end2_) { - current2_ = begin2_; - ++current1_; - } - ComputeCurrentValue(); - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - virtual const ParamType* Current() const { return ¤t_value_; } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const Iterator* typed_other = - CheckedDowncastToActualType(&other); - // We must report iterators equal if they both point beyond their - // respective ranges. That can happen in a variety of fashions, - // so we have to consult AtEnd(). - return (AtEnd() && typed_other->AtEnd()) || - ( - current1_ == typed_other->current1_ && - current2_ == typed_other->current2_ && - current3_ == typed_other->current3_ && - current4_ == typed_other->current4_ && - current5_ == typed_other->current5_ && - current6_ == typed_other->current6_ && - current7_ == typed_other->current7_ && - current8_ == typed_other->current8_); - } + virtual const ParamGeneratorInterface* BaseGenerator() const + { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() + { + assert(!AtEnd()); + ++current8_; + if (current8_ == end8_) + { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) + { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) + { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) + { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) + { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) + { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) + { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const + { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const + { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + (current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_); + } - private: - Iterator(const Iterator& other) - : base_(other.base_), - begin1_(other.begin1_), - end1_(other.end1_), - current1_(other.current1_), - begin2_(other.begin2_), - end2_(other.end2_), - current2_(other.current2_), - begin3_(other.begin3_), - end3_(other.end3_), - current3_(other.current3_), - begin4_(other.begin4_), - end4_(other.end4_), - current4_(other.current4_), - begin5_(other.begin5_), - end5_(other.end5_), - current5_(other.current5_), - begin6_(other.begin6_), - end6_(other.end6_), - current6_(other.current6_), - begin7_(other.begin7_), - end7_(other.end7_), - current7_(other.current7_), - begin8_(other.begin8_), - end8_(other.end8_), - current8_(other.current8_) { - ComputeCurrentValue(); - } + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_) + { + ComputeCurrentValue(); + } - void ComputeCurrentValue() { - if (!AtEnd()) - current_value_ = ParamType(*current1_, *current2_, *current3_, - *current4_, *current5_, *current6_, *current7_, *current8_); - } - bool AtEnd() const { - // We must report iterator past the end of the range when either of the - // component iterators has reached the end of its range. - return - current1_ == end1_ || - current2_ == end2_ || - current3_ == end3_ || - current4_ == end4_ || - current5_ == end5_ || - current6_ == end6_ || - current7_ == end7_ || - current8_ == end8_; - } + void ComputeCurrentValue() + { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_); + } + bool AtEnd() const + { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_; + } - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); - const ParamGeneratorInterface* const base_; - // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. - // current[i]_ is the actual traversing iterator. - const typename ParamGenerator::iterator begin1_; - const typename ParamGenerator::iterator end1_; - typename ParamGenerator::iterator current1_; - const typename ParamGenerator::iterator begin2_; - const typename ParamGenerator::iterator end2_; - typename ParamGenerator::iterator current2_; - const typename ParamGenerator::iterator begin3_; - const typename ParamGenerator::iterator end3_; - typename ParamGenerator::iterator current3_; - const typename ParamGenerator::iterator begin4_; - const typename ParamGenerator::iterator end4_; - typename ParamGenerator::iterator current4_; - const typename ParamGenerator::iterator begin5_; - const typename ParamGenerator::iterator end5_; - typename ParamGenerator::iterator current5_; - const typename ParamGenerator::iterator begin6_; - const typename ParamGenerator::iterator end6_; - typename ParamGenerator::iterator current6_; - const typename ParamGenerator::iterator begin7_; - const typename ParamGenerator::iterator end7_; - typename ParamGenerator::iterator current7_; - const typename ParamGenerator::iterator begin8_; - const typename ParamGenerator::iterator end8_; - typename ParamGenerator::iterator current8_; - ParamType current_value_; - }; // class CartesianProductGenerator8::Iterator + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + ParamType current_value_; + }; // class CartesianProductGenerator8::Iterator - // No implementation - assignment is unsupported. - void operator=(const CartesianProductGenerator8& other); + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator8& other); - const ParamGenerator g1_; - const ParamGenerator g2_; - const ParamGenerator g3_; - const ParamGenerator g4_; - const ParamGenerator g5_; - const ParamGenerator g6_; - const ParamGenerator g7_; - const ParamGenerator g8_; + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; }; // class CartesianProductGenerator8 - template + typename T6, typename T7, typename T8, typename T9> class CartesianProductGenerator9 - : public ParamGeneratorInterface< ::std::tr1::tuple > { - public: - typedef ::std::tr1::tuple ParamType; + : public ParamGeneratorInterface< ::std::tr1::tuple > +{ +public: + typedef ::std::tr1::tuple ParamType; - CartesianProductGenerator9(const ParamGenerator& g1, - const ParamGenerator& g2, const ParamGenerator& g3, - const ParamGenerator& g4, const ParamGenerator& g5, - const ParamGenerator& g6, const ParamGenerator& g7, - const ParamGenerator& g8, const ParamGenerator& g9) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), - g9_(g9) {} - virtual ~CartesianProductGenerator9() {} + CartesianProductGenerator9(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8, const ParamGenerator& g9) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), g9_(g9) {} + virtual ~CartesianProductGenerator9() {} - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, - g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, - g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin()); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), - g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, - g8_.end(), g9_, g9_.end()); - } + virtual ParamIteratorInterface* Begin() const + { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin()); + } + virtual ParamIteratorInterface* End() const + { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end(), g9_, g9_.end()); + } - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - const ParamGenerator& g1, - const typename ParamGenerator::iterator& current1, - const ParamGenerator& g2, - const typename ParamGenerator::iterator& current2, - const ParamGenerator& g3, - const typename ParamGenerator::iterator& current3, - const ParamGenerator& g4, - const typename ParamGenerator::iterator& current4, - const ParamGenerator& g5, - const typename ParamGenerator::iterator& current5, - const ParamGenerator& g6, - const typename ParamGenerator::iterator& current6, - const ParamGenerator& g7, - const typename ParamGenerator::iterator& current7, - const ParamGenerator& g8, - const typename ParamGenerator::iterator& current8, - const ParamGenerator& g9, - const typename ParamGenerator::iterator& current9) - : base_(base), - begin1_(g1.begin()), end1_(g1.end()), current1_(current1), - begin2_(g2.begin()), end2_(g2.end()), current2_(current2), - begin3_(g3.begin()), end3_(g3.end()), current3_(current3), - begin4_(g4.begin()), end4_(g4.end()), current4_(current4), - begin5_(g5.begin()), end5_(g5.end()), current5_(current5), - begin6_(g6.begin()), end6_(g6.end()), current6_(current6), - begin7_(g7.begin()), end7_(g7.end()), current7_(current7), - begin8_(g8.begin()), end8_(g8.end()), current8_(current8), - begin9_(g9.begin()), end9_(g9.end()), current9_(current9) { - ComputeCurrentValue(); - } - virtual ~Iterator() {} +private: + class Iterator : public ParamIteratorInterface + { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8, + const ParamGenerator& g9, + const typename ParamGenerator::iterator& current9) + : base_(base), + begin1_(g1.begin()), + end1_(g1.end()), + current1_(current1), + begin2_(g2.begin()), + end2_(g2.end()), + current2_(current2), + begin3_(g3.begin()), + end3_(g3.end()), + current3_(current3), + begin4_(g4.begin()), + end4_(g4.end()), + current4_(current4), + begin5_(g5.begin()), + end5_(g5.end()), + current5_(current5), + begin6_(g6.begin()), + end6_(g6.end()), + current6_(current6), + begin7_(g7.begin()), + end7_(g7.end()), + current7_(current7), + begin8_(g8.begin()), + end8_(g8.end()), + current8_(current8), + begin9_(g9.begin()), + end9_(g9.end()), + current9_(current9) + { + ComputeCurrentValue(); + } + virtual ~Iterator() {} - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - // Advance should not be called on beyond-of-range iterators - // so no component iterators must be beyond end of range, either. - virtual void Advance() { - assert(!AtEnd()); - ++current9_; - if (current9_ == end9_) { - current9_ = begin9_; - ++current8_; - } - if (current8_ == end8_) { - current8_ = begin8_; - ++current7_; - } - if (current7_ == end7_) { - current7_ = begin7_; - ++current6_; - } - if (current6_ == end6_) { - current6_ = begin6_; - ++current5_; - } - if (current5_ == end5_) { - current5_ = begin5_; - ++current4_; - } - if (current4_ == end4_) { - current4_ = begin4_; - ++current3_; - } - if (current3_ == end3_) { - current3_ = begin3_; - ++current2_; - } - if (current2_ == end2_) { - current2_ = begin2_; - ++current1_; - } - ComputeCurrentValue(); - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - virtual const ParamType* Current() const { return ¤t_value_; } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const Iterator* typed_other = - CheckedDowncastToActualType(&other); - // We must report iterators equal if they both point beyond their - // respective ranges. That can happen in a variety of fashions, - // so we have to consult AtEnd(). - return (AtEnd() && typed_other->AtEnd()) || - ( - current1_ == typed_other->current1_ && - current2_ == typed_other->current2_ && - current3_ == typed_other->current3_ && - current4_ == typed_other->current4_ && - current5_ == typed_other->current5_ && - current6_ == typed_other->current6_ && - current7_ == typed_other->current7_ && - current8_ == typed_other->current8_ && - current9_ == typed_other->current9_); - } + virtual const ParamGeneratorInterface* BaseGenerator() const + { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() + { + assert(!AtEnd()); + ++current9_; + if (current9_ == end9_) + { + current9_ = begin9_; + ++current8_; + } + if (current8_ == end8_) + { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) + { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) + { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) + { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) + { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) + { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) + { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const + { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const + { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + (current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_ && + current9_ == typed_other->current9_); + } - private: - Iterator(const Iterator& other) - : base_(other.base_), - begin1_(other.begin1_), - end1_(other.end1_), - current1_(other.current1_), - begin2_(other.begin2_), - end2_(other.end2_), - current2_(other.current2_), - begin3_(other.begin3_), - end3_(other.end3_), - current3_(other.current3_), - begin4_(other.begin4_), - end4_(other.end4_), - current4_(other.current4_), - begin5_(other.begin5_), - end5_(other.end5_), - current5_(other.current5_), - begin6_(other.begin6_), - end6_(other.end6_), - current6_(other.current6_), - begin7_(other.begin7_), - end7_(other.end7_), - current7_(other.current7_), - begin8_(other.begin8_), - end8_(other.end8_), - current8_(other.current8_), - begin9_(other.begin9_), - end9_(other.end9_), - current9_(other.current9_) { - ComputeCurrentValue(); - } + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_), + begin9_(other.begin9_), + end9_(other.end9_), + current9_(other.current9_) + { + ComputeCurrentValue(); + } - void ComputeCurrentValue() { - if (!AtEnd()) - current_value_ = ParamType(*current1_, *current2_, *current3_, - *current4_, *current5_, *current6_, *current7_, *current8_, - *current9_); - } - bool AtEnd() const { - // We must report iterator past the end of the range when either of the - // component iterators has reached the end of its range. - return - current1_ == end1_ || - current2_ == end2_ || - current3_ == end3_ || - current4_ == end4_ || - current5_ == end5_ || - current6_ == end6_ || - current7_ == end7_ || - current8_ == end8_ || - current9_ == end9_; - } + void ComputeCurrentValue() + { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_, + *current9_); + } + bool AtEnd() const + { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_ || + current9_ == end9_; + } - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); - const ParamGeneratorInterface* const base_; - // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. - // current[i]_ is the actual traversing iterator. - const typename ParamGenerator::iterator begin1_; - const typename ParamGenerator::iterator end1_; - typename ParamGenerator::iterator current1_; - const typename ParamGenerator::iterator begin2_; - const typename ParamGenerator::iterator end2_; - typename ParamGenerator::iterator current2_; - const typename ParamGenerator::iterator begin3_; - const typename ParamGenerator::iterator end3_; - typename ParamGenerator::iterator current3_; - const typename ParamGenerator::iterator begin4_; - const typename ParamGenerator::iterator end4_; - typename ParamGenerator::iterator current4_; - const typename ParamGenerator::iterator begin5_; - const typename ParamGenerator::iterator end5_; - typename ParamGenerator::iterator current5_; - const typename ParamGenerator::iterator begin6_; - const typename ParamGenerator::iterator end6_; - typename ParamGenerator::iterator current6_; - const typename ParamGenerator::iterator begin7_; - const typename ParamGenerator::iterator end7_; - typename ParamGenerator::iterator current7_; - const typename ParamGenerator::iterator begin8_; - const typename ParamGenerator::iterator end8_; - typename ParamGenerator::iterator current8_; - const typename ParamGenerator::iterator begin9_; - const typename ParamGenerator::iterator end9_; - typename ParamGenerator::iterator current9_; - ParamType current_value_; - }; // class CartesianProductGenerator9::Iterator + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + const typename ParamGenerator::iterator begin9_; + const typename ParamGenerator::iterator end9_; + typename ParamGenerator::iterator current9_; + ParamType current_value_; + }; // class CartesianProductGenerator9::Iterator - // No implementation - assignment is unsupported. - void operator=(const CartesianProductGenerator9& other); + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator9& other); - const ParamGenerator g1_; - const ParamGenerator g2_; - const ParamGenerator g3_; - const ParamGenerator g4_; - const ParamGenerator g5_; - const ParamGenerator g6_; - const ParamGenerator g7_; - const ParamGenerator g8_; - const ParamGenerator g9_; + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; + const ParamGenerator g9_; }; // class CartesianProductGenerator9 - template + typename T6, typename T7, typename T8, typename T9, typename T10> class CartesianProductGenerator10 - : public ParamGeneratorInterface< ::std::tr1::tuple > { - public: - typedef ::std::tr1::tuple ParamType; + : public ParamGeneratorInterface< ::std::tr1::tuple > +{ +public: + typedef ::std::tr1::tuple ParamType; - CartesianProductGenerator10(const ParamGenerator& g1, - const ParamGenerator& g2, const ParamGenerator& g3, - const ParamGenerator& g4, const ParamGenerator& g5, - const ParamGenerator& g6, const ParamGenerator& g7, - const ParamGenerator& g8, const ParamGenerator& g9, - const ParamGenerator& g10) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), - g9_(g9), g10_(g10) {} - virtual ~CartesianProductGenerator10() {} + CartesianProductGenerator10(const ParamGenerator& g1, + const ParamGenerator& g2, const ParamGenerator& g3, + const ParamGenerator& g4, const ParamGenerator& g5, + const ParamGenerator& g6, const ParamGenerator& g7, + const ParamGenerator& g8, const ParamGenerator& g9, + const ParamGenerator& g10) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), g9_(g9), g10_(g10) {} + virtual ~CartesianProductGenerator10() {} - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, - g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, - g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin()); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), - g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, - g8_.end(), g9_, g9_.end(), g10_, g10_.end()); - } + virtual ParamIteratorInterface* Begin() const + { + return new Iterator(this, g1_, g1_.begin(), g2_, g2_.begin(), g3_, + g3_.begin(), g4_, g4_.begin(), g5_, g5_.begin(), g6_, g6_.begin(), g7_, + g7_.begin(), g8_, g8_.begin(), g9_, g9_.begin(), g10_, g10_.begin()); + } + virtual ParamIteratorInterface* End() const + { + return new Iterator(this, g1_, g1_.end(), g2_, g2_.end(), g3_, g3_.end(), + g4_, g4_.end(), g5_, g5_.end(), g6_, g6_.end(), g7_, g7_.end(), g8_, + g8_.end(), g9_, g9_.end(), g10_, g10_.end()); + } - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - const ParamGenerator& g1, - const typename ParamGenerator::iterator& current1, - const ParamGenerator& g2, - const typename ParamGenerator::iterator& current2, - const ParamGenerator& g3, - const typename ParamGenerator::iterator& current3, - const ParamGenerator& g4, - const typename ParamGenerator::iterator& current4, - const ParamGenerator& g5, - const typename ParamGenerator::iterator& current5, - const ParamGenerator& g6, - const typename ParamGenerator::iterator& current6, - const ParamGenerator& g7, - const typename ParamGenerator::iterator& current7, - const ParamGenerator& g8, - const typename ParamGenerator::iterator& current8, - const ParamGenerator& g9, - const typename ParamGenerator::iterator& current9, - const ParamGenerator& g10, - const typename ParamGenerator::iterator& current10) - : base_(base), - begin1_(g1.begin()), end1_(g1.end()), current1_(current1), - begin2_(g2.begin()), end2_(g2.end()), current2_(current2), - begin3_(g3.begin()), end3_(g3.end()), current3_(current3), - begin4_(g4.begin()), end4_(g4.end()), current4_(current4), - begin5_(g5.begin()), end5_(g5.end()), current5_(current5), - begin6_(g6.begin()), end6_(g6.end()), current6_(current6), - begin7_(g7.begin()), end7_(g7.end()), current7_(current7), - begin8_(g8.begin()), end8_(g8.end()), current8_(current8), - begin9_(g9.begin()), end9_(g9.end()), current9_(current9), - begin10_(g10.begin()), end10_(g10.end()), current10_(current10) { - ComputeCurrentValue(); - } - virtual ~Iterator() {} +private: + class Iterator : public ParamIteratorInterface + { + public: + Iterator(const ParamGeneratorInterface* base, + const ParamGenerator& g1, + const typename ParamGenerator::iterator& current1, + const ParamGenerator& g2, + const typename ParamGenerator::iterator& current2, + const ParamGenerator& g3, + const typename ParamGenerator::iterator& current3, + const ParamGenerator& g4, + const typename ParamGenerator::iterator& current4, + const ParamGenerator& g5, + const typename ParamGenerator::iterator& current5, + const ParamGenerator& g6, + const typename ParamGenerator::iterator& current6, + const ParamGenerator& g7, + const typename ParamGenerator::iterator& current7, + const ParamGenerator& g8, + const typename ParamGenerator::iterator& current8, + const ParamGenerator& g9, + const typename ParamGenerator::iterator& current9, + const ParamGenerator& g10, + const typename ParamGenerator::iterator& current10) + : base_(base), + begin1_(g1.begin()), + end1_(g1.end()), + current1_(current1), + begin2_(g2.begin()), + end2_(g2.end()), + current2_(current2), + begin3_(g3.begin()), + end3_(g3.end()), + current3_(current3), + begin4_(g4.begin()), + end4_(g4.end()), + current4_(current4), + begin5_(g5.begin()), + end5_(g5.end()), + current5_(current5), + begin6_(g6.begin()), + end6_(g6.end()), + current6_(current6), + begin7_(g7.begin()), + end7_(g7.end()), + current7_(current7), + begin8_(g8.begin()), + end8_(g8.end()), + current8_(current8), + begin9_(g9.begin()), + end9_(g9.end()), + current9_(current9), + begin10_(g10.begin()), + end10_(g10.end()), + current10_(current10) + { + ComputeCurrentValue(); + } + virtual ~Iterator() {} - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - // Advance should not be called on beyond-of-range iterators - // so no component iterators must be beyond end of range, either. - virtual void Advance() { - assert(!AtEnd()); - ++current10_; - if (current10_ == end10_) { - current10_ = begin10_; - ++current9_; - } - if (current9_ == end9_) { - current9_ = begin9_; - ++current8_; - } - if (current8_ == end8_) { - current8_ = begin8_; - ++current7_; - } - if (current7_ == end7_) { - current7_ = begin7_; - ++current6_; - } - if (current6_ == end6_) { - current6_ = begin6_; - ++current5_; - } - if (current5_ == end5_) { - current5_ = begin5_; - ++current4_; - } - if (current4_ == end4_) { - current4_ = begin4_; - ++current3_; - } - if (current3_ == end3_) { - current3_ = begin3_; - ++current2_; - } - if (current2_ == end2_) { - current2_ = begin2_; - ++current1_; - } - ComputeCurrentValue(); - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - virtual const ParamType* Current() const { return ¤t_value_; } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const Iterator* typed_other = - CheckedDowncastToActualType(&other); - // We must report iterators equal if they both point beyond their - // respective ranges. That can happen in a variety of fashions, - // so we have to consult AtEnd(). - return (AtEnd() && typed_other->AtEnd()) || - ( - current1_ == typed_other->current1_ && - current2_ == typed_other->current2_ && - current3_ == typed_other->current3_ && - current4_ == typed_other->current4_ && - current5_ == typed_other->current5_ && - current6_ == typed_other->current6_ && - current7_ == typed_other->current7_ && - current8_ == typed_other->current8_ && - current9_ == typed_other->current9_ && - current10_ == typed_other->current10_); - } + virtual const ParamGeneratorInterface* BaseGenerator() const + { + return base_; + } + // Advance should not be called on beyond-of-range iterators + // so no component iterators must be beyond end of range, either. + virtual void Advance() + { + assert(!AtEnd()); + ++current10_; + if (current10_ == end10_) + { + current10_ = begin10_; + ++current9_; + } + if (current9_ == end9_) + { + current9_ = begin9_; + ++current8_; + } + if (current8_ == end8_) + { + current8_ = begin8_; + ++current7_; + } + if (current7_ == end7_) + { + current7_ = begin7_; + ++current6_; + } + if (current6_ == end6_) + { + current6_ = begin6_; + ++current5_; + } + if (current5_ == end5_) + { + current5_ = begin5_; + ++current4_; + } + if (current4_ == end4_) + { + current4_ = begin4_; + ++current3_; + } + if (current3_ == end3_) + { + current3_ = begin3_; + ++current2_; + } + if (current2_ == end2_) + { + current2_ = begin2_; + ++current1_; + } + ComputeCurrentValue(); + } + virtual ParamIteratorInterface* Clone() const + { + return new Iterator(*this); + } + virtual const ParamType* Current() const { return ¤t_value_; } + virtual bool Equals(const ParamIteratorInterface& other) const + { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const Iterator* typed_other = + CheckedDowncastToActualType(&other); + // We must report iterators equal if they both point beyond their + // respective ranges. That can happen in a variety of fashions, + // so we have to consult AtEnd(). + return (AtEnd() && typed_other->AtEnd()) || + (current1_ == typed_other->current1_ && + current2_ == typed_other->current2_ && + current3_ == typed_other->current3_ && + current4_ == typed_other->current4_ && + current5_ == typed_other->current5_ && + current6_ == typed_other->current6_ && + current7_ == typed_other->current7_ && + current8_ == typed_other->current8_ && + current9_ == typed_other->current9_ && + current10_ == typed_other->current10_); + } - private: - Iterator(const Iterator& other) - : base_(other.base_), - begin1_(other.begin1_), - end1_(other.end1_), - current1_(other.current1_), - begin2_(other.begin2_), - end2_(other.end2_), - current2_(other.current2_), - begin3_(other.begin3_), - end3_(other.end3_), - current3_(other.current3_), - begin4_(other.begin4_), - end4_(other.end4_), - current4_(other.current4_), - begin5_(other.begin5_), - end5_(other.end5_), - current5_(other.current5_), - begin6_(other.begin6_), - end6_(other.end6_), - current6_(other.current6_), - begin7_(other.begin7_), - end7_(other.end7_), - current7_(other.current7_), - begin8_(other.begin8_), - end8_(other.end8_), - current8_(other.current8_), - begin9_(other.begin9_), - end9_(other.end9_), - current9_(other.current9_), - begin10_(other.begin10_), - end10_(other.end10_), - current10_(other.current10_) { - ComputeCurrentValue(); - } + private: + Iterator(const Iterator& other) + : base_(other.base_), + begin1_(other.begin1_), + end1_(other.end1_), + current1_(other.current1_), + begin2_(other.begin2_), + end2_(other.end2_), + current2_(other.current2_), + begin3_(other.begin3_), + end3_(other.end3_), + current3_(other.current3_), + begin4_(other.begin4_), + end4_(other.end4_), + current4_(other.current4_), + begin5_(other.begin5_), + end5_(other.end5_), + current5_(other.current5_), + begin6_(other.begin6_), + end6_(other.end6_), + current6_(other.current6_), + begin7_(other.begin7_), + end7_(other.end7_), + current7_(other.current7_), + begin8_(other.begin8_), + end8_(other.end8_), + current8_(other.current8_), + begin9_(other.begin9_), + end9_(other.end9_), + current9_(other.current9_), + begin10_(other.begin10_), + end10_(other.end10_), + current10_(other.current10_) + { + ComputeCurrentValue(); + } - void ComputeCurrentValue() { - if (!AtEnd()) - current_value_ = ParamType(*current1_, *current2_, *current3_, - *current4_, *current5_, *current6_, *current7_, *current8_, - *current9_, *current10_); - } - bool AtEnd() const { - // We must report iterator past the end of the range when either of the - // component iterators has reached the end of its range. - return - current1_ == end1_ || - current2_ == end2_ || - current3_ == end3_ || - current4_ == end4_ || - current5_ == end5_ || - current6_ == end6_ || - current7_ == end7_ || - current8_ == end8_ || - current9_ == end9_ || - current10_ == end10_; - } + void ComputeCurrentValue() + { + if (!AtEnd()) + current_value_ = ParamType(*current1_, *current2_, *current3_, + *current4_, *current5_, *current6_, *current7_, *current8_, + *current9_, *current10_); + } + bool AtEnd() const + { + // We must report iterator past the end of the range when either of the + // component iterators has reached the end of its range. + return current1_ == end1_ || + current2_ == end2_ || + current3_ == end3_ || + current4_ == end4_ || + current5_ == end5_ || + current6_ == end6_ || + current7_ == end7_ || + current8_ == end8_ || + current9_ == end9_ || + current10_ == end10_; + } - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); - const ParamGeneratorInterface* const base_; - // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. - // current[i]_ is the actual traversing iterator. - const typename ParamGenerator::iterator begin1_; - const typename ParamGenerator::iterator end1_; - typename ParamGenerator::iterator current1_; - const typename ParamGenerator::iterator begin2_; - const typename ParamGenerator::iterator end2_; - typename ParamGenerator::iterator current2_; - const typename ParamGenerator::iterator begin3_; - const typename ParamGenerator::iterator end3_; - typename ParamGenerator::iterator current3_; - const typename ParamGenerator::iterator begin4_; - const typename ParamGenerator::iterator end4_; - typename ParamGenerator::iterator current4_; - const typename ParamGenerator::iterator begin5_; - const typename ParamGenerator::iterator end5_; - typename ParamGenerator::iterator current5_; - const typename ParamGenerator::iterator begin6_; - const typename ParamGenerator::iterator end6_; - typename ParamGenerator::iterator current6_; - const typename ParamGenerator::iterator begin7_; - const typename ParamGenerator::iterator end7_; - typename ParamGenerator::iterator current7_; - const typename ParamGenerator::iterator begin8_; - const typename ParamGenerator::iterator end8_; - typename ParamGenerator::iterator current8_; - const typename ParamGenerator::iterator begin9_; - const typename ParamGenerator::iterator end9_; - typename ParamGenerator::iterator current9_; - const typename ParamGenerator::iterator begin10_; - const typename ParamGenerator::iterator end10_; - typename ParamGenerator::iterator current10_; - ParamType current_value_; - }; // class CartesianProductGenerator10::Iterator + const ParamGeneratorInterface* const base_; + // begin[i]_ and end[i]_ define the i-th range that Iterator traverses. + // current[i]_ is the actual traversing iterator. + const typename ParamGenerator::iterator begin1_; + const typename ParamGenerator::iterator end1_; + typename ParamGenerator::iterator current1_; + const typename ParamGenerator::iterator begin2_; + const typename ParamGenerator::iterator end2_; + typename ParamGenerator::iterator current2_; + const typename ParamGenerator::iterator begin3_; + const typename ParamGenerator::iterator end3_; + typename ParamGenerator::iterator current3_; + const typename ParamGenerator::iterator begin4_; + const typename ParamGenerator::iterator end4_; + typename ParamGenerator::iterator current4_; + const typename ParamGenerator::iterator begin5_; + const typename ParamGenerator::iterator end5_; + typename ParamGenerator::iterator current5_; + const typename ParamGenerator::iterator begin6_; + const typename ParamGenerator::iterator end6_; + typename ParamGenerator::iterator current6_; + const typename ParamGenerator::iterator begin7_; + const typename ParamGenerator::iterator end7_; + typename ParamGenerator::iterator current7_; + const typename ParamGenerator::iterator begin8_; + const typename ParamGenerator::iterator end8_; + typename ParamGenerator::iterator current8_; + const typename ParamGenerator::iterator begin9_; + const typename ParamGenerator::iterator end9_; + typename ParamGenerator::iterator current9_; + const typename ParamGenerator::iterator begin10_; + const typename ParamGenerator::iterator end10_; + typename ParamGenerator::iterator current10_; + ParamType current_value_; + }; // class CartesianProductGenerator10::Iterator - // No implementation - assignment is unsupported. - void operator=(const CartesianProductGenerator10& other); + // No implementation - assignment is unsupported. + void operator=(const CartesianProductGenerator10& other); - const ParamGenerator g1_; - const ParamGenerator g2_; - const ParamGenerator g3_; - const ParamGenerator g4_; - const ParamGenerator g5_; - const ParamGenerator g6_; - const ParamGenerator g7_; - const ParamGenerator g8_; - const ParamGenerator g9_; - const ParamGenerator g10_; + const ParamGenerator g1_; + const ParamGenerator g2_; + const ParamGenerator g3_; + const ParamGenerator g4_; + const ParamGenerator g5_; + const ParamGenerator g6_; + const ParamGenerator g7_; + const ParamGenerator g8_; + const ParamGenerator g9_; + const ParamGenerator g10_; }; // class CartesianProductGenerator10 - // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Helper classes providing Combine() with polymorphic features. They allow @@ -4833,307 +5139,322 @@ class CartesianProductGenerator10 // convertible to U. // template -class CartesianProductHolder2 { - public: -CartesianProductHolder2(const Generator1& g1, const Generator2& g2) - : g1_(g1), g2_(g2) {} - template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( - new CartesianProductGenerator2( - static_cast >(g1_), - static_cast >(g2_))); - } +class CartesianProductHolder2 +{ +public: + CartesianProductHolder2(const Generator1& g1, const Generator2& g2) + : g1_(g1), g2_(g2) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const + { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator2( + static_cast >(g1_), + static_cast >(g2_))); + } - private: - // No implementation - assignment is unsupported. - void operator=(const CartesianProductHolder2& other); +private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder2& other); - const Generator1 g1_; - const Generator2 g2_; + const Generator1 g1_; + const Generator2 g2_; }; // class CartesianProductHolder2 template -class CartesianProductHolder3 { - public: -CartesianProductHolder3(const Generator1& g1, const Generator2& g2, - const Generator3& g3) - : g1_(g1), g2_(g2), g3_(g3) {} - template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( - new CartesianProductGenerator3( - static_cast >(g1_), - static_cast >(g2_), - static_cast >(g3_))); - } +class CartesianProductHolder3 +{ +public: + CartesianProductHolder3(const Generator1& g1, const Generator2& g2, + const Generator3& g3) + : g1_(g1), g2_(g2), g3_(g3) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const + { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator3( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_))); + } - private: - // No implementation - assignment is unsupported. - void operator=(const CartesianProductHolder3& other); +private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder3& other); - const Generator1 g1_; - const Generator2 g2_; - const Generator3 g3_; + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; }; // class CartesianProductHolder3 template -class CartesianProductHolder4 { - public: -CartesianProductHolder4(const Generator1& g1, const Generator2& g2, - const Generator3& g3, const Generator4& g4) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} - template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( - new CartesianProductGenerator4( - static_cast >(g1_), - static_cast >(g2_), - static_cast >(g3_), - static_cast >(g4_))); - } + class Generator4> +class CartesianProductHolder4 +{ +public: + CartesianProductHolder4(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const + { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator4( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_))); + } - private: - // No implementation - assignment is unsupported. - void operator=(const CartesianProductHolder4& other); +private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder4& other); - const Generator1 g1_; - const Generator2 g2_; - const Generator3 g3_; - const Generator4 g4_; + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; }; // class CartesianProductHolder4 template -class CartesianProductHolder5 { - public: -CartesianProductHolder5(const Generator1& g1, const Generator2& g2, - const Generator3& g3, const Generator4& g4, const Generator5& g5) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} - template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( - new CartesianProductGenerator5( - static_cast >(g1_), - static_cast >(g2_), - static_cast >(g3_), - static_cast >(g4_), - static_cast >(g5_))); - } + class Generator4, class Generator5> +class CartesianProductHolder5 +{ +public: + CartesianProductHolder5(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const + { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator5( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_))); + } - private: - // No implementation - assignment is unsupported. - void operator=(const CartesianProductHolder5& other); +private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder5& other); - const Generator1 g1_; - const Generator2 g2_; - const Generator3 g3_; - const Generator4 g4_; - const Generator5 g5_; + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; }; // class CartesianProductHolder5 template -class CartesianProductHolder6 { - public: -CartesianProductHolder6(const Generator1& g1, const Generator2& g2, - const Generator3& g3, const Generator4& g4, const Generator5& g5, - const Generator6& g6) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} - template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( - new CartesianProductGenerator6( - static_cast >(g1_), - static_cast >(g2_), - static_cast >(g3_), - static_cast >(g4_), - static_cast >(g5_), - static_cast >(g6_))); - } + class Generator4, class Generator5, class Generator6> +class CartesianProductHolder6 +{ +public: + CartesianProductHolder6(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const + { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator6( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_))); + } - private: - // No implementation - assignment is unsupported. - void operator=(const CartesianProductHolder6& other); +private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder6& other); - const Generator1 g1_; - const Generator2 g2_; - const Generator3 g3_; - const Generator4 g4_; - const Generator5 g5_; - const Generator6 g6_; + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; }; // class CartesianProductHolder6 template -class CartesianProductHolder7 { - public: -CartesianProductHolder7(const Generator1& g1, const Generator2& g2, - const Generator3& g3, const Generator4& g4, const Generator5& g5, - const Generator6& g6, const Generator7& g7) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} - template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( - new CartesianProductGenerator7( - static_cast >(g1_), - static_cast >(g2_), - static_cast >(g3_), - static_cast >(g4_), - static_cast >(g5_), - static_cast >(g6_), - static_cast >(g7_))); - } + class Generator4, class Generator5, class Generator6, class Generator7> +class CartesianProductHolder7 +{ +public: + CartesianProductHolder7(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const + { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator7( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_))); + } - private: - // No implementation - assignment is unsupported. - void operator=(const CartesianProductHolder7& other); +private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder7& other); - const Generator1 g1_; - const Generator2 g2_; - const Generator3 g3_; - const Generator4 g4_; - const Generator5 g5_; - const Generator6 g6_; - const Generator7 g7_; + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; }; // class CartesianProductHolder7 template -class CartesianProductHolder8 { - public: -CartesianProductHolder8(const Generator1& g1, const Generator2& g2, - const Generator3& g3, const Generator4& g4, const Generator5& g5, - const Generator6& g6, const Generator7& g7, const Generator8& g8) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), - g8_(g8) {} - template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( - new CartesianProductGenerator8( - static_cast >(g1_), - static_cast >(g2_), - static_cast >(g3_), - static_cast >(g4_), - static_cast >(g5_), - static_cast >(g6_), - static_cast >(g7_), - static_cast >(g8_))); - } + class Generator4, class Generator5, class Generator6, class Generator7, + class Generator8> +class CartesianProductHolder8 +{ +public: + CartesianProductHolder8(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const + { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator8( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_))); + } - private: - // No implementation - assignment is unsupported. - void operator=(const CartesianProductHolder8& other); +private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder8& other); - const Generator1 g1_; - const Generator2 g2_; - const Generator3 g3_; - const Generator4 g4_; - const Generator5 g5_; - const Generator6 g6_; - const Generator7 g7_; - const Generator8 g8_; + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; }; // class CartesianProductHolder8 template -class CartesianProductHolder9 { - public: -CartesianProductHolder9(const Generator1& g1, const Generator2& g2, - const Generator3& g3, const Generator4& g4, const Generator5& g5, - const Generator6& g6, const Generator7& g7, const Generator8& g8, - const Generator9& g9) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), - g9_(g9) {} - template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( - new CartesianProductGenerator9( - static_cast >(g1_), - static_cast >(g2_), - static_cast >(g3_), - static_cast >(g4_), - static_cast >(g5_), - static_cast >(g6_), - static_cast >(g7_), - static_cast >(g8_), - static_cast >(g9_))); - } + class Generator4, class Generator5, class Generator6, class Generator7, + class Generator8, class Generator9> +class CartesianProductHolder9 +{ +public: + CartesianProductHolder9(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8, + const Generator9& g9) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), g9_(g9) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const + { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator9( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_), + static_cast >(g9_))); + } - private: - // No implementation - assignment is unsupported. - void operator=(const CartesianProductHolder9& other); +private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder9& other); - const Generator1 g1_; - const Generator2 g2_; - const Generator3 g3_; - const Generator4 g4_; - const Generator5 g5_; - const Generator6 g6_; - const Generator7 g7_; - const Generator8 g8_; - const Generator9 g9_; + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; + const Generator9 g9_; }; // class CartesianProductHolder9 template -class CartesianProductHolder10 { - public: -CartesianProductHolder10(const Generator1& g1, const Generator2& g2, - const Generator3& g3, const Generator4& g4, const Generator5& g5, - const Generator6& g6, const Generator7& g7, const Generator8& g8, - const Generator9& g9, const Generator10& g10) - : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), - g9_(g9), g10_(g10) {} - template - operator ParamGenerator< ::std::tr1::tuple >() const { - return ParamGenerator< ::std::tr1::tuple >( - new CartesianProductGenerator10( - static_cast >(g1_), - static_cast >(g2_), - static_cast >(g3_), - static_cast >(g4_), - static_cast >(g5_), - static_cast >(g6_), - static_cast >(g7_), - static_cast >(g8_), - static_cast >(g9_), - static_cast >(g10_))); - } + class Generator4, class Generator5, class Generator6, class Generator7, + class Generator8, class Generator9, class Generator10> +class CartesianProductHolder10 +{ +public: + CartesianProductHolder10(const Generator1& g1, const Generator2& g2, + const Generator3& g3, const Generator4& g4, const Generator5& g5, + const Generator6& g6, const Generator7& g7, const Generator8& g8, + const Generator9& g9, const Generator10& g10) + : g1_(g1), g2_(g2), g3_(g3), g4_(g4), g5_(g5), g6_(g6), g7_(g7), g8_(g8), g9_(g9), g10_(g10) {} + template + operator ParamGenerator< ::std::tr1::tuple >() const + { + return ParamGenerator< ::std::tr1::tuple >( + new CartesianProductGenerator10( + static_cast >(g1_), + static_cast >(g2_), + static_cast >(g3_), + static_cast >(g4_), + static_cast >(g5_), + static_cast >(g6_), + static_cast >(g7_), + static_cast >(g8_), + static_cast >(g9_), + static_cast >(g10_))); + } - private: - // No implementation - assignment is unsupported. - void operator=(const CartesianProductHolder10& other); +private: + // No implementation - assignment is unsupported. + void operator=(const CartesianProductHolder10& other); - const Generator1 g1_; - const Generator2 g2_; - const Generator3 g3_; - const Generator4 g4_; - const Generator5 g5_; - const Generator6 g6_; - const Generator7 g7_; - const Generator8 g8_; - const Generator9 g9_; - const Generator10 g10_; + const Generator1 g1_; + const Generator2 g2_; + const Generator3 g3_; + const Generator4 g4_; + const Generator5 g5_; + const Generator6 g6_; + const Generator7 g7_; + const Generator8 g8_; + const Generator9 g9_; + const Generator10 g10_; }; // class CartesianProductHolder10 -# endif // GTEST_HAS_COMBINE +#endif // GTEST_HAS_COMBINE } // namespace internal } // namespace testing diff --git a/test/gtest-1.7.0/include/gtest/internal/gtest-param-util.h b/test/gtest-1.7.0/include/gtest/internal/gtest-param-util.h index d5e1028b0..c6958f26f 100644 --- a/test/gtest-1.7.0/include/gtest/internal/gtest-param-util.h +++ b/test/gtest-1.7.0/include/gtest/internal/gtest-param-util.h @@ -48,9 +48,10 @@ #if GTEST_HAS_PARAM_TEST -namespace testing { -namespace internal { - +namespace testing +{ +namespace internal +{ // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // // Outputs a message explaining invalid registration of different @@ -58,96 +59,106 @@ namespace internal { // TEST_P macro is used to define two tests with the same name // but in different namespaces. GTEST_API_ void ReportInvalidTestCaseType(const char* test_case_name, - const char* file, int line); + const char* file, int line); -template class ParamGeneratorInterface; -template class ParamGenerator; +template +class ParamGeneratorInterface; +template +class ParamGenerator; // Interface for iterating over elements provided by an implementation // of ParamGeneratorInterface. template -class ParamIteratorInterface { - public: - virtual ~ParamIteratorInterface() {} - // A pointer to the base generator instance. - // Used only for the purposes of iterator comparison - // to make sure that two iterators belong to the same generator. - virtual const ParamGeneratorInterface* BaseGenerator() const = 0; - // Advances iterator to point to the next element - // provided by the generator. The caller is responsible - // for not calling Advance() on an iterator equal to - // BaseGenerator()->End(). - virtual void Advance() = 0; - // Clones the iterator object. Used for implementing copy semantics - // of ParamIterator. - virtual ParamIteratorInterface* Clone() const = 0; - // Dereferences the current iterator and provides (read-only) access - // to the pointed value. It is the caller's responsibility not to call - // Current() on an iterator equal to BaseGenerator()->End(). - // Used for implementing ParamGenerator::operator*(). - virtual const T* Current() const = 0; - // Determines whether the given iterator and other point to the same - // element in the sequence generated by the generator. - // Used for implementing ParamGenerator::operator==(). - virtual bool Equals(const ParamIteratorInterface& other) const = 0; +class ParamIteratorInterface +{ +public: + virtual ~ParamIteratorInterface() {} + // A pointer to the base generator instance. + // Used only for the purposes of iterator comparison + // to make sure that two iterators belong to the same generator. + virtual const ParamGeneratorInterface* BaseGenerator() const = 0; + // Advances iterator to point to the next element + // provided by the generator. The caller is responsible + // for not calling Advance() on an iterator equal to + // BaseGenerator()->End(). + virtual void Advance() = 0; + // Clones the iterator object. Used for implementing copy semantics + // of ParamIterator. + virtual ParamIteratorInterface* Clone() const = 0; + // Dereferences the current iterator and provides (read-only) access + // to the pointed value. It is the caller's responsibility not to call + // Current() on an iterator equal to BaseGenerator()->End(). + // Used for implementing ParamGenerator::operator*(). + virtual const T* Current() const = 0; + // Determines whether the given iterator and other point to the same + // element in the sequence generated by the generator. + // Used for implementing ParamGenerator::operator==(). + virtual bool Equals(const ParamIteratorInterface& other) const = 0; }; // Class iterating over elements provided by an implementation of // ParamGeneratorInterface. It wraps ParamIteratorInterface // and implements the const forward iterator concept. template -class ParamIterator { - public: - typedef T value_type; - typedef const T& reference; - typedef ptrdiff_t difference_type; +class ParamIterator +{ +public: + typedef T value_type; + typedef const T& reference; + typedef ptrdiff_t difference_type; - // ParamIterator assumes ownership of the impl_ pointer. - ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} - ParamIterator& operator=(const ParamIterator& other) { - if (this != &other) - impl_.reset(other.impl_->Clone()); - return *this; - } + // ParamIterator assumes ownership of the impl_ pointer. + ParamIterator(const ParamIterator& other) : impl_(other.impl_->Clone()) {} + ParamIterator& operator=(const ParamIterator& other) + { + if (this != &other) + impl_.reset(other.impl_->Clone()); + return *this; + } - const T& operator*() const { return *impl_->Current(); } - const T* operator->() const { return impl_->Current(); } - // Prefix version of operator++. - ParamIterator& operator++() { - impl_->Advance(); - return *this; - } - // Postfix version of operator++. - ParamIterator operator++(int /*unused*/) { - ParamIteratorInterface* clone = impl_->Clone(); - impl_->Advance(); - return ParamIterator(clone); - } - bool operator==(const ParamIterator& other) const { - return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); - } - bool operator!=(const ParamIterator& other) const { - return !(*this == other); - } + const T& operator*() const { return *impl_->Current(); } + const T* operator->() const { return impl_->Current(); } + // Prefix version of operator++. + ParamIterator& operator++() + { + impl_->Advance(); + return *this; + } + // Postfix version of operator++. + ParamIterator operator++(int /*unused*/) + { + ParamIteratorInterface* clone = impl_->Clone(); + impl_->Advance(); + return ParamIterator(clone); + } + bool operator==(const ParamIterator& other) const + { + return impl_.get() == other.impl_.get() || impl_->Equals(*other.impl_); + } + bool operator!=(const ParamIterator& other) const + { + return !(*this == other); + } - private: - friend class ParamGenerator; - explicit ParamIterator(ParamIteratorInterface* impl) : impl_(impl) {} - scoped_ptr > impl_; +private: + friend class ParamGenerator; + explicit ParamIterator(ParamIteratorInterface* impl) : impl_(impl) {} + scoped_ptr > impl_; }; // ParamGeneratorInterface is the binary interface to access generators // defined in other translation units. template -class ParamGeneratorInterface { - public: - typedef T ParamType; +class ParamGeneratorInterface +{ +public: + typedef T ParamType; - virtual ~ParamGeneratorInterface() {} + virtual ~ParamGeneratorInterface() {} - // Generator interface definition - virtual ParamIteratorInterface* Begin() const = 0; - virtual ParamIteratorInterface* End() const = 0; + // Generator interface definition + virtual ParamIteratorInterface* Begin() const = 0; + virtual ParamIteratorInterface* End() const = 0; }; // Wraps ParamGeneratorInterface and provides general generator syntax @@ -155,24 +166,26 @@ class ParamGeneratorInterface { // This class implements copy initialization semantics and the contained // ParamGeneratorInterface instance is shared among all copies // of the original object. This is possible because that instance is immutable. -template -class ParamGenerator { - public: - typedef ParamIterator iterator; +template +class ParamGenerator +{ +public: + typedef ParamIterator iterator; - explicit ParamGenerator(ParamGeneratorInterface* impl) : impl_(impl) {} - ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} + explicit ParamGenerator(ParamGeneratorInterface* impl) : impl_(impl) {} + ParamGenerator(const ParamGenerator& other) : impl_(other.impl_) {} - ParamGenerator& operator=(const ParamGenerator& other) { - impl_ = other.impl_; - return *this; - } + ParamGenerator& operator=(const ParamGenerator& other) + { + impl_ = other.impl_; + return *this; + } - iterator begin() const { return iterator(impl_->Begin()); } - iterator end() const { return iterator(impl_->End()); } + iterator begin() const { return iterator(impl_->Begin()); } + iterator end() const { return iterator(impl_->End()); } - private: - linked_ptr > impl_; +private: + linked_ptr > impl_; }; // Generates values from a range of two comparable values. Can be used to @@ -180,169 +193,191 @@ class ParamGenerator { // operator<(). // This class is used in the Range() function. template -class RangeGenerator : public ParamGeneratorInterface { - public: - RangeGenerator(T begin, T end, IncrementT step) - : begin_(begin), end_(end), - step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} - virtual ~RangeGenerator() {} +class RangeGenerator : public ParamGeneratorInterface +{ +public: + RangeGenerator(T begin, T end, IncrementT step) + : begin_(begin), end_(end), step_(step), end_index_(CalculateEndIndex(begin, end, step)) {} + virtual ~RangeGenerator() {} - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, begin_, 0, step_); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, end_, end_index_, step_); - } + virtual ParamIteratorInterface* Begin() const + { + return new Iterator(this, begin_, 0, step_); + } + virtual ParamIteratorInterface* End() const + { + return new Iterator(this, end_, end_index_, step_); + } - private: - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, T value, int index, - IncrementT step) - : base_(base), value_(value), index_(index), step_(step) {} - virtual ~Iterator() {} +private: + class Iterator : public ParamIteratorInterface + { + public: + Iterator(const ParamGeneratorInterface* base, T value, int index, + IncrementT step) + : base_(base), value_(value), index_(index), step_(step) {} + virtual ~Iterator() {} - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - virtual void Advance() { - value_ = value_ + step_; - index_++; - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - virtual const T* Current() const { return &value_; } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - const int other_index = - CheckedDowncastToActualType(&other)->index_; - return index_ == other_index; - } + virtual const ParamGeneratorInterface* BaseGenerator() const + { + return base_; + } + virtual void Advance() + { + value_ = value_ + step_; + index_++; + } + virtual ParamIteratorInterface* Clone() const + { + return new Iterator(*this); + } + virtual const T* Current() const { return &value_; } + virtual bool Equals(const ParamIteratorInterface& other) const + { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const int other_index = + CheckedDowncastToActualType(&other)->index_; + return index_ == other_index; + } - private: - Iterator(const Iterator& other) - : ParamIteratorInterface(), - base_(other.base_), value_(other.value_), index_(other.index_), - step_(other.step_) {} + private: + Iterator(const Iterator& other) + : ParamIteratorInterface(), + base_(other.base_), + value_(other.value_), + index_(other.index_), + step_(other.step_) {} - // No implementation - assignment is unsupported. - void operator=(const Iterator& other); + // No implementation - assignment is unsupported. + void operator=(const Iterator& other); - const ParamGeneratorInterface* const base_; - T value_; - int index_; - const IncrementT step_; - }; // class RangeGenerator::Iterator + const ParamGeneratorInterface* const base_; + T value_; + int index_; + const IncrementT step_; + }; // class RangeGenerator::Iterator - static int CalculateEndIndex(const T& begin, - const T& end, - const IncrementT& step) { - int end_index = 0; - for (T i = begin; i < end; i = i + step) - end_index++; - return end_index; - } + static int CalculateEndIndex(const T& begin, + const T& end, + const IncrementT& step) + { + int end_index = 0; + for (T i = begin; i < end; i = i + step) + end_index++; + return end_index; + } - // No implementation - assignment is unsupported. - void operator=(const RangeGenerator& other); + // No implementation - assignment is unsupported. + void operator=(const RangeGenerator& other); - const T begin_; - const T end_; - const IncrementT step_; - // The index for the end() iterator. All the elements in the generated - // sequence are indexed (0-based) to aid iterator comparison. - const int end_index_; + const T begin_; + const T end_; + const IncrementT step_; + // The index for the end() iterator. All the elements in the generated + // sequence are indexed (0-based) to aid iterator comparison. + const int end_index_; }; // class RangeGenerator - // Generates values from a pair of STL-style iterators. Used in the // ValuesIn() function. The elements are copied from the source range // since the source can be located on the stack, and the generator // is likely to persist beyond that stack frame. template -class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface { - public: - template - ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) - : container_(begin, end) {} - virtual ~ValuesInIteratorRangeGenerator() {} +class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface +{ +public: + template + ValuesInIteratorRangeGenerator(ForwardIterator begin, ForwardIterator end) + : container_(begin, end) + { + } + virtual ~ValuesInIteratorRangeGenerator() {} - virtual ParamIteratorInterface* Begin() const { - return new Iterator(this, container_.begin()); - } - virtual ParamIteratorInterface* End() const { - return new Iterator(this, container_.end()); - } + virtual ParamIteratorInterface* Begin() const + { + return new Iterator(this, container_.begin()); + } + virtual ParamIteratorInterface* End() const + { + return new Iterator(this, container_.end()); + } - private: - typedef typename ::std::vector ContainerType; +private: + typedef typename ::std::vector ContainerType; - class Iterator : public ParamIteratorInterface { - public: - Iterator(const ParamGeneratorInterface* base, - typename ContainerType::const_iterator iterator) - : base_(base), iterator_(iterator) {} - virtual ~Iterator() {} + class Iterator : public ParamIteratorInterface + { + public: + Iterator(const ParamGeneratorInterface* base, + typename ContainerType::const_iterator iterator) + : base_(base), iterator_(iterator) {} + virtual ~Iterator() {} - virtual const ParamGeneratorInterface* BaseGenerator() const { - return base_; - } - virtual void Advance() { - ++iterator_; - value_.reset(); - } - virtual ParamIteratorInterface* Clone() const { - return new Iterator(*this); - } - // We need to use cached value referenced by iterator_ because *iterator_ - // can return a temporary object (and of type other then T), so just - // having "return &*iterator_;" doesn't work. - // value_ is updated here and not in Advance() because Advance() - // can advance iterator_ beyond the end of the range, and we cannot - // detect that fact. The client code, on the other hand, is - // responsible for not calling Current() on an out-of-range iterator. - virtual const T* Current() const { - if (value_.get() == NULL) - value_.reset(new T(*iterator_)); - return value_.get(); - } - virtual bool Equals(const ParamIteratorInterface& other) const { - // Having the same base generator guarantees that the other - // iterator is of the same type and we can downcast. - GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) - << "The program attempted to compare iterators " - << "from different generators." << std::endl; - return iterator_ == - CheckedDowncastToActualType(&other)->iterator_; - } + virtual const ParamGeneratorInterface* BaseGenerator() const + { + return base_; + } + virtual void Advance() + { + ++iterator_; + value_.reset(); + } + virtual ParamIteratorInterface* Clone() const + { + return new Iterator(*this); + } + // We need to use cached value referenced by iterator_ because *iterator_ + // can return a temporary object (and of type other then T), so just + // having "return &*iterator_;" doesn't work. + // value_ is updated here and not in Advance() because Advance() + // can advance iterator_ beyond the end of the range, and we cannot + // detect that fact. The client code, on the other hand, is + // responsible for not calling Current() on an out-of-range iterator. + virtual const T* Current() const + { + if (value_.get() == NULL) + value_.reset(new T(*iterator_)); + return value_.get(); + } + virtual bool Equals(const ParamIteratorInterface& other) const + { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + return iterator_ == + CheckedDowncastToActualType(&other)->iterator_; + } - private: - Iterator(const Iterator& other) - // The explicit constructor call suppresses a false warning - // emitted by gcc when supplied with the -Wextra option. - : ParamIteratorInterface(), - base_(other.base_), - iterator_(other.iterator_) {} + private: + Iterator(const Iterator& other) + // The explicit constructor call suppresses a false warning + // emitted by gcc when supplied with the -Wextra option. + : ParamIteratorInterface(), + base_(other.base_), + iterator_(other.iterator_) + { + } - const ParamGeneratorInterface* const base_; - typename ContainerType::const_iterator iterator_; - // A cached value of *iterator_. We keep it here to allow access by - // pointer in the wrapping iterator's operator->(). - // value_ needs to be mutable to be accessed in Current(). - // Use of scoped_ptr helps manage cached value's lifetime, - // which is bound by the lifespan of the iterator itself. - mutable scoped_ptr value_; - }; // class ValuesInIteratorRangeGenerator::Iterator + const ParamGeneratorInterface* const base_; + typename ContainerType::const_iterator iterator_; + // A cached value of *iterator_. We keep it here to allow access by + // pointer in the wrapping iterator's operator->(). + // value_ needs to be mutable to be accessed in Current(). + // Use of scoped_ptr helps manage cached value's lifetime, + // which is bound by the lifespan of the iterator itself. + mutable scoped_ptr value_; + }; // class ValuesInIteratorRangeGenerator::Iterator - // No implementation - assignment is unsupported. - void operator=(const ValuesInIteratorRangeGenerator& other); + // No implementation - assignment is unsupported. + void operator=(const ValuesInIteratorRangeGenerator& other); - const ContainerType container_; + const ContainerType container_; }; // class ValuesInIteratorRangeGenerator // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. @@ -350,20 +385,21 @@ class ValuesInIteratorRangeGenerator : public ParamGeneratorInterface { // Stores a parameter value and later creates tests parameterized with that // value. template -class ParameterizedTestFactory : public TestFactoryBase { - public: - typedef typename TestClass::ParamType ParamType; - explicit ParameterizedTestFactory(ParamType parameter) : - parameter_(parameter) {} - virtual Test* CreateTest() { - TestClass::SetParam(¶meter_); - return new TestClass(); - } +class ParameterizedTestFactory : public TestFactoryBase +{ +public: + typedef typename TestClass::ParamType ParamType; + explicit ParameterizedTestFactory(ParamType parameter) : parameter_(parameter) {} + virtual Test* CreateTest() + { + TestClass::SetParam(¶meter_); + return new TestClass(); + } - private: - const ParamType parameter_; +private: + const ParamType parameter_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestFactory); }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. @@ -371,11 +407,12 @@ class ParameterizedTestFactory : public TestFactoryBase { // TestMetaFactoryBase is a base class for meta-factories that create // test factories for passing into MakeAndRegisterTestInfo function. template -class TestMetaFactoryBase { - public: - virtual ~TestMetaFactoryBase() {} +class TestMetaFactoryBase +{ +public: + virtual ~TestMetaFactoryBase() {} - virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; + virtual TestFactoryBase* CreateTestFactory(ParamType parameter) = 0; }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. @@ -388,18 +425,20 @@ class TestMetaFactoryBase { // creator class. template class TestMetaFactory - : public TestMetaFactoryBase { - public: - typedef typename TestCase::ParamType ParamType; + : public TestMetaFactoryBase +{ +public: + typedef typename TestCase::ParamType ParamType; - TestMetaFactory() {} + TestMetaFactory() {} - virtual TestFactoryBase* CreateTestFactory(ParamType parameter) { - return new ParameterizedTestFactory(parameter); - } + virtual TestFactoryBase* CreateTestFactory(ParamType parameter) + { + return new ParameterizedTestFactory(parameter); + } - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); +private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestMetaFactory); }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. @@ -412,25 +451,26 @@ class TestMetaFactory // in RegisterTests method. The ParameterizeTestCaseRegistry class holds // a collection of pointers to the ParameterizedTestCaseInfo objects // and calls RegisterTests() on each of them when asked. -class ParameterizedTestCaseInfoBase { - public: - virtual ~ParameterizedTestCaseInfoBase() {} +class ParameterizedTestCaseInfoBase +{ +public: + virtual ~ParameterizedTestCaseInfoBase() {} - // Base part of test case name for display purposes. - virtual const string& GetTestCaseName() const = 0; - // Test case id to verify identity. - virtual TypeId GetTestCaseTypeId() const = 0; - // UnitTest class invokes this method to register tests in this - // test case right before running them in RUN_ALL_TESTS macro. - // This method should not be called more then once on any single - // instance of a ParameterizedTestCaseInfoBase derived class. - virtual void RegisterTests() = 0; + // Base part of test case name for display purposes. + virtual const string& GetTestCaseName() const = 0; + // Test case id to verify identity. + virtual TypeId GetTestCaseTypeId() const = 0; + // UnitTest class invokes this method to register tests in this + // test case right before running them in RUN_ALL_TESTS macro. + // This method should not be called more then once on any single + // instance of a ParameterizedTestCaseInfoBase derived class. + virtual void RegisterTests() = 0; - protected: - ParameterizedTestCaseInfoBase() {} +protected: + ParameterizedTestCaseInfoBase() {} - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase); +private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfoBase); }; // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. @@ -441,110 +481,118 @@ class ParameterizedTestCaseInfoBase { // test case. It registers tests with all values generated by all // generators when asked. template -class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { - public: - // ParamType and GeneratorCreationFunc are private types but are required - // for declarations of public methods AddTestPattern() and - // AddTestCaseInstantiation(). - typedef typename TestCase::ParamType ParamType; - // A function that returns an instance of appropriate generator type. - typedef ParamGenerator(GeneratorCreationFunc)(); +class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase +{ +public: + // ParamType and GeneratorCreationFunc are private types but are required + // for declarations of public methods AddTestPattern() and + // AddTestCaseInstantiation(). + typedef typename TestCase::ParamType ParamType; + // A function that returns an instance of appropriate generator type. + typedef ParamGenerator(GeneratorCreationFunc)(); - explicit ParameterizedTestCaseInfo(const char* name) - : test_case_name_(name) {} + explicit ParameterizedTestCaseInfo(const char* name) + : test_case_name_(name) {} - // Test case base name for display purposes. - virtual const string& GetTestCaseName() const { return test_case_name_; } - // Test case id to verify identity. - virtual TypeId GetTestCaseTypeId() const { return GetTypeId(); } - // TEST_P macro uses AddTestPattern() to record information - // about a single test in a LocalTestInfo structure. - // test_case_name is the base name of the test case (without invocation - // prefix). test_base_name is the name of an individual test without - // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is - // test case base name and DoBar is test base name. - void AddTestPattern(const char* test_case_name, - const char* test_base_name, - TestMetaFactoryBase* meta_factory) { - tests_.push_back(linked_ptr(new TestInfo(test_case_name, - test_base_name, - meta_factory))); - } - // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information - // about a generator. - int AddTestCaseInstantiation(const string& instantiation_name, - GeneratorCreationFunc* func, - const char* /* file */, - int /* line */) { - instantiations_.push_back(::std::make_pair(instantiation_name, func)); - return 0; // Return value used only to run this method in namespace scope. - } - // UnitTest class invokes this method to register tests in this test case - // test cases right before running tests in RUN_ALL_TESTS macro. - // This method should not be called more then once on any single - // instance of a ParameterizedTestCaseInfoBase derived class. - // UnitTest has a guard to prevent from calling this method more then once. - virtual void RegisterTests() { - for (typename TestInfoContainer::iterator test_it = tests_.begin(); - test_it != tests_.end(); ++test_it) { - linked_ptr test_info = *test_it; - for (typename InstantiationContainer::iterator gen_it = - instantiations_.begin(); gen_it != instantiations_.end(); - ++gen_it) { - const string& instantiation_name = gen_it->first; - ParamGenerator generator((*gen_it->second)()); + // Test case base name for display purposes. + virtual const string& GetTestCaseName() const { return test_case_name_; } + // Test case id to verify identity. + virtual TypeId GetTestCaseTypeId() const { return GetTypeId(); } + // TEST_P macro uses AddTestPattern() to record information + // about a single test in a LocalTestInfo structure. + // test_case_name is the base name of the test case (without invocation + // prefix). test_base_name is the name of an individual test without + // parameter index. For the test SequenceA/FooTest.DoBar/1 FooTest is + // test case base name and DoBar is test base name. + void AddTestPattern(const char* test_case_name, + const char* test_base_name, + TestMetaFactoryBase* meta_factory) + { + tests_.push_back(linked_ptr(new TestInfo(test_case_name, + test_base_name, + meta_factory))); + } + // INSTANTIATE_TEST_CASE_P macro uses AddGenerator() to record information + // about a generator. + int AddTestCaseInstantiation(const string& instantiation_name, + GeneratorCreationFunc* func, + const char* /* file */, + int /* line */) + { + instantiations_.push_back(::std::make_pair(instantiation_name, func)); + return 0; // Return value used only to run this method in namespace scope. + } + // UnitTest class invokes this method to register tests in this test case + // test cases right before running tests in RUN_ALL_TESTS macro. + // This method should not be called more then once on any single + // instance of a ParameterizedTestCaseInfoBase derived class. + // UnitTest has a guard to prevent from calling this method more then once. + virtual void RegisterTests() + { + for (typename TestInfoContainer::iterator test_it = tests_.begin(); + test_it != tests_.end(); ++test_it) + { + linked_ptr test_info = *test_it; + for (typename InstantiationContainer::iterator gen_it = + instantiations_.begin(); + gen_it != instantiations_.end(); + ++gen_it) + { + const string& instantiation_name = gen_it->first; + ParamGenerator generator((*gen_it->second)()); - string test_case_name; - if ( !instantiation_name.empty() ) - test_case_name = instantiation_name + "/"; - test_case_name += test_info->test_case_base_name; + string test_case_name; + if (!instantiation_name.empty()) + test_case_name = instantiation_name + "/"; + test_case_name += test_info->test_case_base_name; - int i = 0; - for (typename ParamGenerator::iterator param_it = - generator.begin(); - param_it != generator.end(); ++param_it, ++i) { - Message test_name_stream; - test_name_stream << test_info->test_base_name << "/" << i; - MakeAndRegisterTestInfo( - test_case_name.c_str(), - test_name_stream.GetString().c_str(), - NULL, // No type parameter. - PrintToString(*param_it).c_str(), - GetTestCaseTypeId(), - TestCase::SetUpTestCase, - TestCase::TearDownTestCase, - test_info->test_meta_factory->CreateTestFactory(*param_it)); - } // for param_it - } // for gen_it - } // for test_it - } // RegisterTests + int i = 0; + for (typename ParamGenerator::iterator param_it = + generator.begin(); + param_it != generator.end(); ++param_it, ++i) + { + Message test_name_stream; + test_name_stream << test_info->test_base_name << "/" << i; + MakeAndRegisterTestInfo( + test_case_name.c_str(), + test_name_stream.GetString().c_str(), + NULL, // No type parameter. + PrintToString(*param_it).c_str(), + GetTestCaseTypeId(), + TestCase::SetUpTestCase, + TestCase::TearDownTestCase, + test_info->test_meta_factory->CreateTestFactory(*param_it)); + } // for param_it + } // for gen_it + } // for test_it + } // RegisterTests - private: - // LocalTestInfo structure keeps information about a single test registered - // with TEST_P macro. - struct TestInfo { - TestInfo(const char* a_test_case_base_name, - const char* a_test_base_name, - TestMetaFactoryBase* a_test_meta_factory) : - test_case_base_name(a_test_case_base_name), - test_base_name(a_test_base_name), - test_meta_factory(a_test_meta_factory) {} +private: + // LocalTestInfo structure keeps information about a single test registered + // with TEST_P macro. + struct TestInfo + { + TestInfo(const char* a_test_case_base_name, + const char* a_test_base_name, + TestMetaFactoryBase* a_test_meta_factory) : test_case_base_name(a_test_case_base_name), + test_base_name(a_test_base_name), + test_meta_factory(a_test_meta_factory) {} - const string test_case_base_name; - const string test_base_name; - const scoped_ptr > test_meta_factory; - }; - typedef ::std::vector > TestInfoContainer; - // Keeps pairs of - // received from INSTANTIATE_TEST_CASE_P macros. - typedef ::std::vector > - InstantiationContainer; + const string test_case_base_name; + const string test_base_name; + const scoped_ptr > test_meta_factory; + }; + typedef ::std::vector > TestInfoContainer; + // Keeps pairs of + // received from INSTANTIATE_TEST_CASE_P macros. + typedef ::std::vector > + InstantiationContainer; - const string test_case_name_; - TestInfoContainer tests_; - InstantiationContainer instantiations_; + const string test_case_name_; + TestInfoContainer tests_; + InstantiationContainer instantiations_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo); + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseInfo); }; // class ParameterizedTestCaseInfo // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. @@ -553,62 +601,74 @@ class ParameterizedTestCaseInfo : public ParameterizedTestCaseInfoBase { // classes accessed by test case names. TEST_P and INSTANTIATE_TEST_CASE_P // macros use it to locate their corresponding ParameterizedTestCaseInfo // descriptors. -class ParameterizedTestCaseRegistry { - public: - ParameterizedTestCaseRegistry() {} - ~ParameterizedTestCaseRegistry() { - for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); - it != test_case_infos_.end(); ++it) { - delete *it; - } - } +class ParameterizedTestCaseRegistry +{ +public: + ParameterizedTestCaseRegistry() {} + ~ParameterizedTestCaseRegistry() + { + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) + { + delete *it; + } + } - // Looks up or creates and returns a structure containing information about - // tests and instantiations of a particular test case. - template - ParameterizedTestCaseInfo* GetTestCasePatternHolder( - const char* test_case_name, - const char* file, - int line) { - ParameterizedTestCaseInfo* typed_test_info = NULL; - for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); - it != test_case_infos_.end(); ++it) { - if ((*it)->GetTestCaseName() == test_case_name) { - if ((*it)->GetTestCaseTypeId() != GetTypeId()) { - // Complain about incorrect usage of Google Test facilities - // and terminate the program since we cannot guaranty correct - // test case setup and tear-down in this case. - ReportInvalidTestCaseType(test_case_name, file, line); - posix::Abort(); - } else { - // At this point we are sure that the object we found is of the same - // type we are looking for, so we downcast it to that type - // without further checks. - typed_test_info = CheckedDowncastToActualType< - ParameterizedTestCaseInfo >(*it); - } - break; - } - } - if (typed_test_info == NULL) { - typed_test_info = new ParameterizedTestCaseInfo(test_case_name); - test_case_infos_.push_back(typed_test_info); - } - return typed_test_info; - } - void RegisterTests() { - for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); - it != test_case_infos_.end(); ++it) { - (*it)->RegisterTests(); - } - } + // Looks up or creates and returns a structure containing information about + // tests and instantiations of a particular test case. + template + ParameterizedTestCaseInfo* GetTestCasePatternHolder( + const char* test_case_name, + const char* file, + int line) + { + ParameterizedTestCaseInfo* typed_test_info = NULL; + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) + { + if ((*it)->GetTestCaseName() == test_case_name) + { + if ((*it)->GetTestCaseTypeId() != GetTypeId()) + { + // Complain about incorrect usage of Google Test facilities + // and terminate the program since we cannot guaranty correct + // test case setup and tear-down in this case. + ReportInvalidTestCaseType(test_case_name, file, line); + posix::Abort(); + } + else + { + // At this point we are sure that the object we found is of the same + // type we are looking for, so we downcast it to that type + // without further checks. + typed_test_info = CheckedDowncastToActualType< + ParameterizedTestCaseInfo >(*it); + } + break; + } + } + if (typed_test_info == NULL) + { + typed_test_info = new ParameterizedTestCaseInfo(test_case_name); + test_case_infos_.push_back(typed_test_info); + } + return typed_test_info; + } + void RegisterTests() + { + for (TestCaseInfoContainer::iterator it = test_case_infos_.begin(); + it != test_case_infos_.end(); ++it) + { + (*it)->RegisterTests(); + } + } - private: - typedef ::std::vector TestCaseInfoContainer; +private: + typedef ::std::vector TestCaseInfoContainer; - TestCaseInfoContainer test_case_infos_; + TestCaseInfoContainer test_case_infos_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry); + GTEST_DISALLOW_COPY_AND_ASSIGN_(ParameterizedTestCaseRegistry); }; } // namespace internal diff --git a/test/gtest-1.7.0/include/gtest/internal/gtest-port.h b/test/gtest-1.7.0/include/gtest/internal/gtest-port.h index dc4fe0cb6..3f5cab780 100644 --- a/test/gtest-1.7.0/include/gtest/internal/gtest-port.h +++ b/test/gtest-1.7.0/include/gtest/internal/gtest-port.h @@ -199,18 +199,18 @@ #include #include #ifndef _WIN32_WCE -# include -# include +#include +#include #endif // !_WIN32_WCE #if defined __APPLE__ -# include -# include +#include +#include #endif #include // NOLINT -#include // NOLINT -#include // NOLINT +#include // NOLINT +#include // NOLINT #define GTEST_DEV_EMAIL_ "googletestframework@@googlegroups.com" #define GTEST_FLAG_PREFIX_ "gtest_" @@ -222,51 +222,51 @@ // Determines the version of gcc that is used to compile this. #ifdef __GNUC__ // 40302 means version 4.3.2. -# define GTEST_GCC_VER_ \ - (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) +#define GTEST_GCC_VER_ \ + (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #endif // __GNUC__ // Determines the platform on which Google Test is compiled. #ifdef __CYGWIN__ -# define GTEST_OS_CYGWIN 1 +#define GTEST_OS_CYGWIN 1 #elif defined __SYMBIAN32__ -# define GTEST_OS_SYMBIAN 1 +#define GTEST_OS_SYMBIAN 1 #elif defined _WIN32 -# define GTEST_OS_WINDOWS 1 -# ifdef _WIN32_WCE -# define GTEST_OS_WINDOWS_MOBILE 1 -# elif defined(__MINGW__) || defined(__MINGW32__) -# define GTEST_OS_WINDOWS_MINGW 1 -# else -# define GTEST_OS_WINDOWS_DESKTOP 1 -# endif // _WIN32_WCE +#define GTEST_OS_WINDOWS 1 +#ifdef _WIN32_WCE +#define GTEST_OS_WINDOWS_MOBILE 1 +#elif defined(__MINGW__) || defined(__MINGW32__) +#define GTEST_OS_WINDOWS_MINGW 1 +#else +#define GTEST_OS_WINDOWS_DESKTOP 1 +#endif // _WIN32_WCE #elif defined __APPLE__ -# define GTEST_OS_MAC 1 -# if TARGET_OS_IPHONE -# define GTEST_OS_IOS 1 -# if TARGET_IPHONE_SIMULATOR -# define GTEST_OS_IOS_SIMULATOR 1 -# endif -# endif +#define GTEST_OS_MAC 1 +#if TARGET_OS_IPHONE +#define GTEST_OS_IOS 1 +#if TARGET_IPHONE_SIMULATOR +#define GTEST_OS_IOS_SIMULATOR 1 +#endif +#endif #elif defined __linux__ -# define GTEST_OS_LINUX 1 -# if defined __ANDROID__ -# define GTEST_OS_LINUX_ANDROID 1 -# endif +#define GTEST_OS_LINUX 1 +#if defined __ANDROID__ +#define GTEST_OS_LINUX_ANDROID 1 +#endif #elif defined __MVS__ -# define GTEST_OS_ZOS 1 +#define GTEST_OS_ZOS 1 #elif defined(__sun) && defined(__SVR4) -# define GTEST_OS_SOLARIS 1 +#define GTEST_OS_SOLARIS 1 #elif defined(_AIX) -# define GTEST_OS_AIX 1 +#define GTEST_OS_AIX 1 #elif defined(__hpux) -# define GTEST_OS_HPUX 1 +#define GTEST_OS_HPUX 1 #elif defined __native_client__ -# define GTEST_OS_NACL 1 +#define GTEST_OS_NACL 1 #elif defined __OpenBSD__ -# define GTEST_OS_OPENBSD 1 +#define GTEST_OS_OPENBSD 1 #elif defined __QNX__ -# define GTEST_OS_QNX 1 +#define GTEST_OS_QNX 1 #endif // __CYGWIN__ #ifndef GTEST_LANG_CXX11 @@ -274,12 +274,12 @@ // -std={c,gnu}++{0x,11} is passed. The C++11 standard specifies a // value for __cplusplus, and recent versions of clang, gcc, and // probably other compilers set that too in C++11 mode. -# if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L +#if __GXX_EXPERIMENTAL_CXX0X__ || __cplusplus >= 201103L // Compiling in at least C++11 mode. -# define GTEST_LANG_CXX11 1 -# else -# define GTEST_LANG_CXX11 0 -# endif +#define GTEST_LANG_CXX11 1 +#else +#define GTEST_LANG_CXX11 0 +#endif #endif // Brings in definitions for functions used in the testing::internal::posix @@ -289,26 +289,26 @@ // This assumes that non-Windows OSes provide unistd.h. For OSes where this // is not the case, we need to include headers that provide the functions // mentioned above. -# include -# include +#include +#include #elif !GTEST_OS_WINDOWS_MOBILE -# include -# include +#include +#include #endif #if GTEST_OS_LINUX_ANDROID // Used to define __ANDROID_API__ matching the target NDK API level. -# include // NOLINT +#include // NOLINT #endif // Defines this to true iff Google Test can use POSIX regular expressions. #ifndef GTEST_HAS_POSIX_RE -# if GTEST_OS_LINUX_ANDROID +#if GTEST_OS_LINUX_ANDROID // On Android, is only available starting with Gingerbread. -# define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9) -# else -# define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS) -# endif +#define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9) +#else +#define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS) +#endif #endif #if GTEST_HAS_POSIX_RE @@ -317,71 +317,71 @@ // won't compile otherwise. We can #include it here as we already // included , which is guaranteed to define size_t through // . -# include // NOLINT +#include // NOLINT -# define GTEST_USES_POSIX_RE 1 +#define GTEST_USES_POSIX_RE 1 #elif GTEST_OS_WINDOWS // is not available on Windows. Use our own simple regex // implementation instead. -# define GTEST_USES_SIMPLE_RE 1 +#define GTEST_USES_SIMPLE_RE 1 #else // may not be available on this platform. Use our own // simple regex implementation instead. -# define GTEST_USES_SIMPLE_RE 1 +#define GTEST_USES_SIMPLE_RE 1 #endif // GTEST_HAS_POSIX_RE #ifndef GTEST_HAS_EXCEPTIONS // The user didn't tell us whether exceptions are enabled, so we need // to figure it out. -# if defined(_MSC_VER) || defined(__BORLANDC__) +#if defined(_MSC_VER) || defined(__BORLANDC__) // MSVC's and C++Builder's implementations of the STL use the _HAS_EXCEPTIONS // macro to enable exceptions, so we'll do the same. // Assumes that exceptions are enabled by default. -# ifndef _HAS_EXCEPTIONS -# define _HAS_EXCEPTIONS 1 -# endif // _HAS_EXCEPTIONS -# define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS -# elif defined(__GNUC__) && __EXCEPTIONS +#ifndef _HAS_EXCEPTIONS +#define _HAS_EXCEPTIONS 1 +#endif // _HAS_EXCEPTIONS +#define GTEST_HAS_EXCEPTIONS _HAS_EXCEPTIONS +#elif defined(__GNUC__) && __EXCEPTIONS // gcc defines __EXCEPTIONS to 1 iff exceptions are enabled. -# define GTEST_HAS_EXCEPTIONS 1 -# elif defined(__SUNPRO_CC) +#define GTEST_HAS_EXCEPTIONS 1 +#elif defined(__SUNPRO_CC) // Sun Pro CC supports exceptions. However, there is no compile-time way of // detecting whether they are enabled or not. Therefore, we assume that // they are enabled unless the user tells us otherwise. -# define GTEST_HAS_EXCEPTIONS 1 -# elif defined(__IBMCPP__) && __EXCEPTIONS +#define GTEST_HAS_EXCEPTIONS 1 +#elif defined(__IBMCPP__) && __EXCEPTIONS // xlC defines __EXCEPTIONS to 1 iff exceptions are enabled. -# define GTEST_HAS_EXCEPTIONS 1 -# elif defined(__HP_aCC) +#define GTEST_HAS_EXCEPTIONS 1 +#elif defined(__HP_aCC) // Exception handling is in effect by default in HP aCC compiler. It has to // be turned of by +noeh compiler option if desired. -# define GTEST_HAS_EXCEPTIONS 1 -# else +#define GTEST_HAS_EXCEPTIONS 1 +#else // For other compilers, we assume exceptions are disabled to be // conservative. -# define GTEST_HAS_EXCEPTIONS 0 -# endif // defined(_MSC_VER) || defined(__BORLANDC__) +#define GTEST_HAS_EXCEPTIONS 0 +#endif // defined(_MSC_VER) || defined(__BORLANDC__) #endif // GTEST_HAS_EXCEPTIONS #if !defined(GTEST_HAS_STD_STRING) // Even though we don't use this macro any longer, we keep it in case // some clients still depend on it. -# define GTEST_HAS_STD_STRING 1 +#define GTEST_HAS_STD_STRING 1 #elif !GTEST_HAS_STD_STRING // The user told us that ::std::string isn't available. -# error "Google Test cannot be used where ::std::string isn't available." +#error "Google Test cannot be used where ::std::string isn't available." #endif // !defined(GTEST_HAS_STD_STRING) #ifndef GTEST_HAS_GLOBAL_STRING // The user didn't tell us whether ::string is available, so we need // to figure it out. -# define GTEST_HAS_GLOBAL_STRING 0 +#define GTEST_HAS_GLOBAL_STRING 0 #endif // GTEST_HAS_GLOBAL_STRING @@ -394,16 +394,16 @@ // Cygwin 1.7 and below doesn't support ::std::wstring. // Solaris' libc++ doesn't support it either. Android has // no support for it at least as recent as Froyo (2.2). -# define GTEST_HAS_STD_WSTRING \ - (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS)) +#define GTEST_HAS_STD_WSTRING \ + (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS)) #endif // GTEST_HAS_STD_WSTRING #ifndef GTEST_HAS_GLOBAL_WSTRING // The user didn't tell us whether ::wstring is available, so we need // to figure it out. -# define GTEST_HAS_GLOBAL_WSTRING \ - (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING) +#define GTEST_HAS_GLOBAL_WSTRING \ + (GTEST_HAS_STD_WSTRING && GTEST_HAS_GLOBAL_STRING) #endif // GTEST_HAS_GLOBAL_WSTRING // Determines whether RTTI is available. @@ -411,62 +411,62 @@ // The user didn't tell us whether RTTI is enabled, so we need to // figure it out. -# ifdef _MSC_VER +#ifdef _MSC_VER -# ifdef _CPPRTTI // MSVC defines this macro iff RTTI is enabled. -# define GTEST_HAS_RTTI 1 -# else -# define GTEST_HAS_RTTI 0 -# endif +#ifdef _CPPRTTI // MSVC defines this macro iff RTTI is enabled. +#define GTEST_HAS_RTTI 1 +#else +#define GTEST_HAS_RTTI 0 +#endif // Starting with version 4.3.2, gcc defines __GXX_RTTI iff RTTI is enabled. -# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302) +#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40302) -# ifdef __GXX_RTTI +#ifdef __GXX_RTTI // When building against STLport with the Android NDK and with // -frtti -fno-exceptions, the build fails at link time with undefined // references to __cxa_bad_typeid. Note sure if STL or toolchain bug, // so disable RTTI when detected. -# if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) && \ - !defined(__EXCEPTIONS) -# define GTEST_HAS_RTTI 0 -# else -# define GTEST_HAS_RTTI 1 -# endif // GTEST_OS_LINUX_ANDROID && __STLPORT_MAJOR && !__EXCEPTIONS -# else -# define GTEST_HAS_RTTI 0 -# endif // __GXX_RTTI +#if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) && \ + !defined(__EXCEPTIONS) +#define GTEST_HAS_RTTI 0 +#else +#define GTEST_HAS_RTTI 1 +#endif // GTEST_OS_LINUX_ANDROID && __STLPORT_MAJOR && !__EXCEPTIONS +#else +#define GTEST_HAS_RTTI 0 +#endif // __GXX_RTTI // Clang defines __GXX_RTTI starting with version 3.0, but its manual recommends // using has_feature instead. has_feature(cxx_rtti) is supported since 2.7, the // first version with C++ support. -# elif defined(__clang__) +#elif defined(__clang__) -# define GTEST_HAS_RTTI __has_feature(cxx_rtti) +#define GTEST_HAS_RTTI __has_feature(cxx_rtti) // Starting with version 9.0 IBM Visual Age defines __RTTI_ALL__ to 1 if // both the typeid and dynamic_cast features are present. -# elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) +#elif defined(__IBMCPP__) && (__IBMCPP__ >= 900) -# ifdef __RTTI_ALL__ -# define GTEST_HAS_RTTI 1 -# else -# define GTEST_HAS_RTTI 0 -# endif +#ifdef __RTTI_ALL__ +#define GTEST_HAS_RTTI 1 +#else +#define GTEST_HAS_RTTI 0 +#endif -# else +#else // For all other compilers, we assume RTTI is enabled. -# define GTEST_HAS_RTTI 1 +#define GTEST_HAS_RTTI 1 -# endif // _MSC_VER +#endif // _MSC_VER #endif // GTEST_HAS_RTTI // It's this header's responsibility to #include when RTTI // is enabled. #if GTEST_HAS_RTTI -# include +#include #endif // Determines whether Google Test can use the pthreads library. @@ -476,30 +476,29 @@ // // To disable threading support in Google Test, add -DGTEST_HAS_PTHREAD=0 // to your compiler flags. -# define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX \ - || GTEST_OS_QNX) +#define GTEST_HAS_PTHREAD (GTEST_OS_LINUX || GTEST_OS_MAC || GTEST_OS_HPUX || GTEST_OS_QNX) #endif // GTEST_HAS_PTHREAD #if GTEST_HAS_PTHREAD // gtest-port.h guarantees to #include when GTEST_HAS_PTHREAD is // true. -# include // NOLINT +#include // NOLINT // For timespec and nanosleep, used below. -# include // NOLINT +#include // NOLINT #endif // Determines whether Google Test can use tr1/tuple. You can define // this macro to 0 to prevent Google Test from using tuple (any // feature depending on tuple with be disabled in this mode). #ifndef GTEST_HAS_TR1_TUPLE -# if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) +#if GTEST_OS_LINUX_ANDROID && defined(_STLPORT_MAJOR) // STLport, provided with the Android NDK, has neither or . -# define GTEST_HAS_TR1_TUPLE 0 -# else +#define GTEST_HAS_TR1_TUPLE 0 +#else // The user didn't tell us not to do it, so we assume it's OK. -# define GTEST_HAS_TR1_TUPLE 1 -# endif +#define GTEST_HAS_TR1_TUPLE 1 +#endif #endif // GTEST_HAS_TR1_TUPLE // Determines whether Google Test's own tr1 tuple implementation @@ -517,23 +516,22 @@ // user has. QNX's QCC compiler is a modified GCC but it doesn't // support TR1 tuple. libc++ only provides std::tuple, in C++11 mode, // and it can be used with some compilers that define __GNUC__. -# if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000) \ - && !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) || _MSC_VER >= 1600 -# define GTEST_ENV_HAS_TR1_TUPLE_ 1 -# endif +#if (defined(__GNUC__) && !defined(__CUDACC__) && (GTEST_GCC_VER_ >= 40000) && !GTEST_OS_QNX && !defined(_LIBCPP_VERSION)) || _MSC_VER >= 1600 +#define GTEST_ENV_HAS_TR1_TUPLE_ 1 +#endif // C++11 specifies that provides std::tuple. Use that if gtest is used // in C++11 mode and libstdc++ isn't very old (binaries targeting OS X 10.6 // can build with clang but need to use gcc4.2's libstdc++). -# if GTEST_LANG_CXX11 && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20110325) -# define GTEST_ENV_HAS_STD_TUPLE_ 1 -# endif +#if GTEST_LANG_CXX11 && (!defined(__GLIBCXX__) || __GLIBCXX__ > 20110325) +#define GTEST_ENV_HAS_STD_TUPLE_ 1 +#endif -# if GTEST_ENV_HAS_TR1_TUPLE_ || GTEST_ENV_HAS_STD_TUPLE_ -# define GTEST_USE_OWN_TR1_TUPLE 0 -# else -# define GTEST_USE_OWN_TR1_TUPLE 1 -# endif +#if GTEST_ENV_HAS_TR1_TUPLE_ || GTEST_ENV_HAS_STD_TUPLE_ +#define GTEST_USE_OWN_TR1_TUPLE 0 +#else +#define GTEST_USE_OWN_TR1_TUPLE 1 +#endif #endif // GTEST_USE_OWN_TR1_TUPLE @@ -542,63 +540,65 @@ // tr1/tuple. #if GTEST_HAS_TR1_TUPLE -# if GTEST_USE_OWN_TR1_TUPLE -# include "gtest/internal/gtest-tuple.h" -# elif GTEST_ENV_HAS_STD_TUPLE_ -# include +#if GTEST_USE_OWN_TR1_TUPLE +#include "gtest/internal/gtest-tuple.h" +#elif GTEST_ENV_HAS_STD_TUPLE_ +#include // C++11 puts its tuple into the ::std namespace rather than // ::std::tr1. gtest expects tuple to live in ::std::tr1, so put it there. // This causes undefined behavior, but supported compilers react in // the way we intend. -namespace std { -namespace tr1 { +namespace std +{ +namespace tr1 +{ using ::std::get; using ::std::make_tuple; using ::std::tuple; using ::std::tuple_element; using ::std::tuple_size; -} -} +} // namespace tr1 +} // namespace std -# elif GTEST_OS_SYMBIAN +#elif GTEST_OS_SYMBIAN // On Symbian, BOOST_HAS_TR1_TUPLE causes Boost's TR1 tuple library to // use STLport's tuple implementation, which unfortunately doesn't // work as the copy of STLport distributed with Symbian is incomplete. // By making sure BOOST_HAS_TR1_TUPLE is undefined, we force Boost to // use its own tuple implementation. -# ifdef BOOST_HAS_TR1_TUPLE -# undef BOOST_HAS_TR1_TUPLE -# endif // BOOST_HAS_TR1_TUPLE +#ifdef BOOST_HAS_TR1_TUPLE +#undef BOOST_HAS_TR1_TUPLE +#endif // BOOST_HAS_TR1_TUPLE // This prevents , which defines // BOOST_HAS_TR1_TUPLE, from being #included by Boost's . -# define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED -# include +#define BOOST_TR1_DETAIL_CONFIG_HPP_INCLUDED +#include -# elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) +#elif defined(__GNUC__) && (GTEST_GCC_VER_ >= 40000) // GCC 4.0+ implements tr1/tuple in the header. This does // not conform to the TR1 spec, which requires the header to be . -# if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 +#if !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 // Until version 4.3.2, gcc has a bug that causes , // which is #included by , to not compile when RTTI is // disabled. _TR1_FUNCTIONAL is the header guard for // . Hence the following #define is a hack to prevent // from being included. -# define _TR1_FUNCTIONAL 1 -# include -# undef _TR1_FUNCTIONAL // Allows the user to #include - // if he chooses to. -# else -# include // NOLINT -# endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 +#define _TR1_FUNCTIONAL 1 +#include +#undef _TR1_FUNCTIONAL // Allows the user to #include +// if he chooses to. +#else +#include // NOLINT +#endif // !GTEST_HAS_RTTI && GTEST_GCC_VER_ < 40302 -# else +#else // If the compiler is not GCC 4.0+, we assume the user is using a // spec-conforming TR1 implementation. -# include // NOLINT -# endif // GTEST_USE_OWN_TR1_TUPLE +#include // NOLINT +#endif // GTEST_USE_OWN_TR1_TUPLE #endif // GTEST_HAS_TR1_TUPLE @@ -609,20 +609,20 @@ using ::std::tuple_size; #ifndef GTEST_HAS_CLONE // The user didn't tell us, so we need to figure it out. -# if GTEST_OS_LINUX && !defined(__ia64__) -# if GTEST_OS_LINUX_ANDROID +#if GTEST_OS_LINUX && !defined(__ia64__) +#if GTEST_OS_LINUX_ANDROID // On Android, clone() is only available on ARM starting with Gingerbread. -# if defined(__arm__) && __ANDROID_API__ >= 9 -# define GTEST_HAS_CLONE 1 -# else -# define GTEST_HAS_CLONE 0 -# endif -# else -# define GTEST_HAS_CLONE 1 -# endif -# else -# define GTEST_HAS_CLONE 0 -# endif // GTEST_OS_LINUX && !defined(__ia64__) +#if defined(__arm__) && __ANDROID_API__ >= 9 +#define GTEST_HAS_CLONE 1 +#else +#define GTEST_HAS_CLONE 0 +#endif +#else +#define GTEST_HAS_CLONE 1 +#endif +#else +#define GTEST_HAS_CLONE 0 +#endif // GTEST_OS_LINUX && !defined(__ia64__) #endif // GTEST_HAS_CLONE @@ -631,24 +631,24 @@ using ::std::tuple_size; #ifndef GTEST_HAS_STREAM_REDIRECTION // By default, we assume that stream redirection is supported on all // platforms except known mobile ones. -# if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN -# define GTEST_HAS_STREAM_REDIRECTION 0 -# else -# define GTEST_HAS_STREAM_REDIRECTION 1 -# endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN +#define GTEST_HAS_STREAM_REDIRECTION 0 +#else +#define GTEST_HAS_STREAM_REDIRECTION 1 +#endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_SYMBIAN #endif // GTEST_HAS_STREAM_REDIRECTION // Determines whether to support death tests. // Google Test does not support death tests for VC 7.1 and earlier as // abort() in a VC 7.1 application compiled as GUI in debug config // pops up a dialog window that cannot be suppressed programmatically. -#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ - (GTEST_OS_MAC && !GTEST_OS_IOS) || GTEST_OS_IOS_SIMULATOR || \ - (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ - GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \ - GTEST_OS_OPENBSD || GTEST_OS_QNX) -# define GTEST_HAS_DEATH_TEST 1 -# include // NOLINT +#if (GTEST_OS_LINUX || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ + (GTEST_OS_MAC && !GTEST_OS_IOS) || GTEST_OS_IOS_SIMULATOR || \ + (GTEST_OS_WINDOWS_DESKTOP && _MSC_VER >= 1400) || \ + GTEST_OS_WINDOWS_MINGW || GTEST_OS_AIX || GTEST_OS_HPUX || \ + GTEST_OS_OPENBSD || GTEST_OS_QNX) +#define GTEST_HAS_DEATH_TEST 1 +#include // NOLINT #endif // We don't support MSVC 7.1 with exceptions disabled now. Therefore @@ -661,9 +661,9 @@ using ::std::tuple_size; // Typed tests need and variadic macros, which GCC, VC++ 8.0, // Sun Pro CC, IBM Visual Age, and HP aCC support. #if defined(__GNUC__) || (_MSC_VER >= 1400) || defined(__SUNPRO_CC) || \ - defined(__IBMCPP__) || defined(__HP_aCC) -# define GTEST_HAS_TYPED_TEST 1 -# define GTEST_HAS_TYPED_TEST_P 1 + defined(__IBMCPP__) || defined(__HP_aCC) +#define GTEST_HAS_TYPED_TEST 1 +#define GTEST_HAS_TYPED_TEST_P 1 #endif // Determines whether to support Combine(). This only makes sense when @@ -671,16 +671,16 @@ using ::std::tuple_size; // work on Sun Studio since it doesn't understand templated conversion // operators. #if GTEST_HAS_PARAM_TEST && GTEST_HAS_TR1_TUPLE && !defined(__SUNPRO_CC) -# define GTEST_HAS_COMBINE 1 +#define GTEST_HAS_COMBINE 1 #endif // Determines whether the system compiler uses UTF-16 for encoding wide strings. #define GTEST_WIDE_STRING_USES_UTF16_ \ - (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX) + (GTEST_OS_WINDOWS || GTEST_OS_CYGWIN || GTEST_OS_SYMBIAN || GTEST_OS_AIX) // Determines whether test results can be streamed to a socket. #if GTEST_OS_LINUX -# define GTEST_CAN_STREAM_RESULTS_ 1 +#define GTEST_CAN_STREAM_RESULTS_ 1 #endif // Defines some utility macros. @@ -694,9 +694,12 @@ using ::std::tuple_size; // // The "switch (0) case 0:" idiom is used to suppress this. #ifdef __INTEL_COMPILER -# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ +#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ #else -# define GTEST_AMBIGUOUS_ELSE_BLOCKER_ switch (0) case 0: default: // NOLINT +#define GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + switch (0) \ + case 0: \ + default: // NOLINT #endif // Use this annotation at the end of a struct/class definition to @@ -711,21 +714,21 @@ using ::std::tuple_size; // Also use it after a variable or parameter declaration to tell the // compiler the variable/parameter does not have to be used. #if defined(__GNUC__) && !defined(COMPILER_ICC) -# define GTEST_ATTRIBUTE_UNUSED_ __attribute__ ((unused)) +#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused)) #else -# define GTEST_ATTRIBUTE_UNUSED_ +#define GTEST_ATTRIBUTE_UNUSED_ #endif // A macro to disallow operator= // This should be used in the private: declarations for a class. -#define GTEST_DISALLOW_ASSIGN_(type)\ - void operator=(type const &) +#define GTEST_DISALLOW_ASSIGN_(type) \ + void operator=(type const&) // A macro to disallow copy constructor and operator= // This should be used in the private: declarations for a class. -#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type)\ - type(type const &);\ - GTEST_DISALLOW_ASSIGN_(type) +#define GTEST_DISALLOW_COPY_AND_ASSIGN_(type) \ + type(type const&); \ + GTEST_DISALLOW_ASSIGN_(type) // Tell the compiler to warn about unused return values for functions declared // with this macro. The macro should be used on function declarations @@ -733,9 +736,9 @@ using ::std::tuple_size; // // Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; #if defined(__GNUC__) && (GTEST_GCC_VER_ >= 30400) && !defined(COMPILER_ICC) -# define GTEST_MUST_USE_RESULT_ __attribute__ ((warn_unused_result)) +#define GTEST_MUST_USE_RESULT_ __attribute__((warn_unused_result)) #else -# define GTEST_MUST_USE_RESULT_ +#define GTEST_MUST_USE_RESULT_ #endif // __GNUC__ && (GTEST_GCC_VER_ >= 30400) && !COMPILER_ICC // Determine whether the compiler supports Microsoft's Structured Exception @@ -744,50 +747,50 @@ using ::std::tuple_size; #ifndef GTEST_HAS_SEH // The user didn't tell us, so we need to figure it out. -# if defined(_MSC_VER) || defined(__BORLANDC__) +#if defined(_MSC_VER) || defined(__BORLANDC__) // These two compilers are known to support SEH. -# define GTEST_HAS_SEH 1 -# else +#define GTEST_HAS_SEH 1 +#else // Assume no SEH. -# define GTEST_HAS_SEH 0 -# endif +#define GTEST_HAS_SEH 0 +#endif #endif // GTEST_HAS_SEH #ifdef _MSC_VER -# if GTEST_LINKED_AS_SHARED_LIBRARY -# define GTEST_API_ __declspec(dllimport) -# elif GTEST_CREATE_SHARED_LIBRARY -# define GTEST_API_ __declspec(dllexport) -# endif +#if GTEST_LINKED_AS_SHARED_LIBRARY +#define GTEST_API_ __declspec(dllimport) +#elif GTEST_CREATE_SHARED_LIBRARY +#define GTEST_API_ __declspec(dllexport) +#endif #endif // _MSC_VER #ifndef GTEST_API_ -# define GTEST_API_ +#define GTEST_API_ #endif #ifdef __GNUC__ // Ask the compiler to never inline a given function. -# define GTEST_NO_INLINE_ __attribute__((noinline)) +#define GTEST_NO_INLINE_ __attribute__((noinline)) #else -# define GTEST_NO_INLINE_ +#define GTEST_NO_INLINE_ #endif // _LIBCPP_VERSION is defined by the libc++ library from the LLVM project. #if defined(__GLIBCXX__) || defined(_LIBCPP_VERSION) -# define GTEST_HAS_CXXABI_H_ 1 +#define GTEST_HAS_CXXABI_H_ 1 #else -# define GTEST_HAS_CXXABI_H_ 0 +#define GTEST_HAS_CXXABI_H_ 0 #endif -namespace testing { - +namespace testing +{ class Message; -namespace internal { - +namespace internal +{ // A secret type that Google Test users don't know about. It has no // definition on purpose. Therefore it's impossible to create a // Secret object, which is what we want. @@ -809,12 +812,13 @@ class Secret; // containing the name of the variable. template -struct CompileAssert { +struct CompileAssert +{ }; -#define GTEST_COMPILE_ASSERT_(expr, msg) \ - typedef ::testing::internal::CompileAssert<(static_cast(expr))> \ - msg[static_cast(expr) ? 1 : -1] GTEST_ATTRIBUTE_UNUSED_ +#define GTEST_COMPILE_ASSERT_(expr, msg) \ + typedef ::testing::internal::CompileAssert<(static_cast(expr))> \ + msg[static_cast(expr) ? 1 : -1] GTEST_ATTRIBUTE_UNUSED_ // Implementation details of GTEST_COMPILE_ASSERT_: // @@ -864,7 +868,9 @@ template struct StaticAssertTypeEqHelper; template -struct StaticAssertTypeEqHelper {}; +struct StaticAssertTypeEqHelper +{ +}; #if GTEST_HAS_GLOBAL_STRING typedef ::string string; @@ -887,112 +893,128 @@ GTEST_API_ bool IsTrue(bool condition); // This implementation of scoped_ptr is PARTIAL - it only contains // enough stuff to satisfy Google Test's need. template -class scoped_ptr { - public: - typedef T element_type; +class scoped_ptr +{ +public: + typedef T element_type; - explicit scoped_ptr(T* p = NULL) : ptr_(p) {} - ~scoped_ptr() { reset(); } + explicit scoped_ptr(T* p = NULL) : ptr_(p) {} + ~scoped_ptr() { reset(); } - T& operator*() const { return *ptr_; } - T* operator->() const { return ptr_; } - T* get() const { return ptr_; } + T& operator*() const { return *ptr_; } + T* operator->() const { return ptr_; } + T* get() const { return ptr_; } - T* release() { - T* const ptr = ptr_; - ptr_ = NULL; - return ptr; - } + T* release() + { + T* const ptr = ptr_; + ptr_ = NULL; + return ptr; + } - void reset(T* p = NULL) { - if (p != ptr_) { - if (IsTrue(sizeof(T) > 0)) { // Makes sure T is a complete type. - delete ptr_; - } - ptr_ = p; - } - } + void reset(T* p = NULL) + { + if (p != ptr_) + { + if (IsTrue(sizeof(T) > 0)) + { // Makes sure T is a complete type. + delete ptr_; + } + ptr_ = p; + } + } - private: - T* ptr_; +private: + T* ptr_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr); + GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr); }; // Defines RE. // A simple C++ wrapper for . It uses the POSIX Extended // Regular Expression syntax. -class GTEST_API_ RE { - public: - // A copy constructor is required by the Standard to initialize object - // references from r-values. - RE(const RE& other) { Init(other.pattern()); } +class GTEST_API_ RE +{ +public: + // A copy constructor is required by the Standard to initialize object + // references from r-values. + RE(const RE& other) { Init(other.pattern()); } - // Constructs an RE from a string. - RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT + // Constructs an RE from a string. + RE(const ::std::string& regex) { Init(regex.c_str()); } // NOLINT #if GTEST_HAS_GLOBAL_STRING - RE(const ::string& regex) { Init(regex.c_str()); } // NOLINT + RE(const ::string& regex) + { + Init(regex.c_str()); + } // NOLINT #endif // GTEST_HAS_GLOBAL_STRING - RE(const char* regex) { Init(regex); } // NOLINT - ~RE(); + RE(const char* regex) + { + Init(regex); + } // NOLINT + ~RE(); - // Returns the string representation of the regex. - const char* pattern() const { return pattern_; } + // Returns the string representation of the regex. + const char* pattern() const { return pattern_; } - // FullMatch(str, re) returns true iff regular expression re matches - // the entire str. - // PartialMatch(str, re) returns true iff regular expression re - // matches a substring of str (including str itself). - // - // TODO(wan@google.com): make FullMatch() and PartialMatch() work - // when str contains NUL characters. - static bool FullMatch(const ::std::string& str, const RE& re) { - return FullMatch(str.c_str(), re); - } - static bool PartialMatch(const ::std::string& str, const RE& re) { - return PartialMatch(str.c_str(), re); - } + // FullMatch(str, re) returns true iff regular expression re matches + // the entire str. + // PartialMatch(str, re) returns true iff regular expression re + // matches a substring of str (including str itself). + // + // TODO(wan@google.com): make FullMatch() and PartialMatch() work + // when str contains NUL characters. + static bool FullMatch(const ::std::string& str, const RE& re) + { + return FullMatch(str.c_str(), re); + } + static bool PartialMatch(const ::std::string& str, const RE& re) + { + return PartialMatch(str.c_str(), re); + } #if GTEST_HAS_GLOBAL_STRING - static bool FullMatch(const ::string& str, const RE& re) { - return FullMatch(str.c_str(), re); - } - static bool PartialMatch(const ::string& str, const RE& re) { - return PartialMatch(str.c_str(), re); - } + static bool FullMatch(const ::string& str, const RE& re) + { + return FullMatch(str.c_str(), re); + } + static bool PartialMatch(const ::string& str, const RE& re) + { + return PartialMatch(str.c_str(), re); + } #endif // GTEST_HAS_GLOBAL_STRING - static bool FullMatch(const char* str, const RE& re); - static bool PartialMatch(const char* str, const RE& re); + static bool FullMatch(const char* str, const RE& re); + static bool PartialMatch(const char* str, const RE& re); - private: - void Init(const char* regex); +private: + void Init(const char* regex); - // We use a const char* instead of an std::string, as Google Test used to be - // used where std::string is not available. TODO(wan@google.com): change to - // std::string. - const char* pattern_; - bool is_valid_; + // We use a const char* instead of an std::string, as Google Test used to be + // used where std::string is not available. TODO(wan@google.com): change to + // std::string. + const char* pattern_; + bool is_valid_; #if GTEST_USES_POSIX_RE - regex_t full_regex_; // For FullMatch(). - regex_t partial_regex_; // For PartialMatch(). + regex_t full_regex_; // For FullMatch(). + regex_t partial_regex_; // For PartialMatch(). #else // GTEST_USES_SIMPLE_RE - const char* full_pattern_; // For FullMatch(); + const char* full_pattern_; // For FullMatch(); #endif - GTEST_DISALLOW_ASSIGN_(RE); + GTEST_DISALLOW_ASSIGN_(RE); }; // Formats a source file path and a line number as they would appear @@ -1003,7 +1025,7 @@ GTEST_API_ ::std::string FormatFileLocation(const char* file, int line); // Although this function is not platform dependent, we put it next to // FormatFileLocation in order to contrast the two functions. GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file, - int line); + int line); // Defines logging utilities: // GTEST_LOG_(severity) - logs messages at the specified severity level. The @@ -1011,36 +1033,41 @@ GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file, // LogToStderr() - directs all log messages to stderr. // FlushInfoLog() - flushes informational log messages. -enum GTestLogSeverity { - GTEST_INFO, - GTEST_WARNING, - GTEST_ERROR, - GTEST_FATAL +enum GTestLogSeverity +{ + GTEST_INFO, + GTEST_WARNING, + GTEST_ERROR, + GTEST_FATAL }; // Formats log entry severity, provides a stream object for streaming the // log message, and terminates the message with a newline when going out of // scope. -class GTEST_API_ GTestLog { - public: - GTestLog(GTestLogSeverity severity, const char* file, int line); +class GTEST_API_ GTestLog +{ +public: + GTestLog(GTestLogSeverity severity, const char* file, int line); - // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. - ~GTestLog(); + // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. + ~GTestLog(); - ::std::ostream& GetStream() { return ::std::cerr; } + ::std::ostream& GetStream() { return ::std::cerr; } - private: - const GTestLogSeverity severity_; +private: + const GTestLogSeverity severity_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestLog); }; -#define GTEST_LOG_(severity) \ - ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ - __FILE__, __LINE__).GetStream() +#define GTEST_LOG_(severity) \ + ::testing::internal::GTestLog(::testing::internal::GTEST_##severity, \ + __FILE__, __LINE__) \ + .GetStream() -inline void LogToStderr() {} +inline void LogToStderr() +{ +} inline void FlushInfoLog() { fflush(NULL); } // INTERNAL IMPLEMENTATION - DO NOT USE. @@ -1057,22 +1084,22 @@ inline void FlushInfoLog() { fflush(NULL); } // condition itself, plus additional message streamed into it, if any, // and then it aborts the program. It aborts the program irrespective of // whether it is built in the debug mode or not. -#define GTEST_CHECK_(condition) \ - GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ - if (::testing::internal::IsTrue(condition)) \ - ; \ - else \ - GTEST_LOG_(FATAL) << "Condition " #condition " failed. " +#define GTEST_CHECK_(condition) \ + GTEST_AMBIGUOUS_ELSE_BLOCKER_ \ + if (::testing::internal::IsTrue(condition)) \ + ; \ + else \ + GTEST_LOG_(FATAL) << "Condition " #condition " failed. " // An all-mode assert to verify that the given POSIX-style function // call returns 0 (indicating success). Known limitation: this // doesn't expand to a balanced 'if' statement, so enclose the macro // in {} if you need to use it as the only statement in an 'if' // branch. -#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \ - if (const int gtest_error = (posix_call)) \ - GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ - << gtest_error +#define GTEST_CHECK_POSIX_SUCCESS_(posix_call) \ + if (const int gtest_error = (posix_call)) \ + GTEST_LOG_(FATAL) << #posix_call << "failed with error " \ + << gtest_error // INTERNAL IMPLEMENTATION - DO NOT USE IN USER CODE. // @@ -1094,8 +1121,11 @@ inline void FlushInfoLog() { fflush(NULL); } // This relatively ugly name is intentional. It prevents clashes with // similar functions users may have (e.g., implicit_cast). The internal // namespace alone is not enough because the function can be found by ADL. -template -inline To ImplicitCast_(To x) { return x; } +template +inline To ImplicitCast_(To x) +{ + return x; +} // When you upcast (that is, cast a pointer from type Foo to type // SuperclassOfFoo), it's fine to use ImplicitCast_<>, since upcasts @@ -1118,22 +1148,24 @@ inline To ImplicitCast_(To x) { return x; } // This relatively ugly name is intentional. It prevents clashes with // similar functions users may have (e.g., down_cast). The internal // namespace alone is not enough because the function can be found by ADL. -template // use like this: DownCast_(foo); -inline To DownCast_(From* f) { // so we only accept pointers - // Ensures that To is a sub-type of From *. This test is here only - // for compile-time type checking, and has no overhead in an - // optimized build at run-time, as it will be optimized away - // completely. - if (false) { - const To to = NULL; - ::testing::internal::ImplicitCast_(to); - } +template // use like this: DownCast_(foo); +inline To DownCast_(From* f) +{ // so we only accept pointers + // Ensures that To is a sub-type of From *. This test is here only + // for compile-time type checking, and has no overhead in an + // optimized build at run-time, as it will be optimized away + // completely. + if (false) + { + const To to = NULL; + ::testing::internal::ImplicitCast_(to); + } #if GTEST_HAS_RTTI - // RTTI: debug mode only! - GTEST_CHECK_(f == NULL || dynamic_cast(f) != NULL); + // RTTI: debug mode only! + GTEST_CHECK_(f == NULL || dynamic_cast(f) != NULL); #endif - return static_cast(f); + return static_cast(f); } // Downcasts the pointer of type Base to Derived. @@ -1142,12 +1174,13 @@ inline To DownCast_(From* f) { // so we only accept pointers // When RTTI is available, the function performs a runtime // check to enforce this. template -Derived* CheckedDowncastToActualType(Base* base) { +Derived* CheckedDowncastToActualType(Base* base) +{ #if GTEST_HAS_RTTI - GTEST_CHECK_(typeid(*base) == typeid(Derived)); - return dynamic_cast(base); // NOLINT + GTEST_CHECK_(typeid(*base) == typeid(Derived)); + return dynamic_cast(base); // NOLINT #else - return static_cast(base); // Poor man's downcast. + return static_cast(base); // Poor man's downcast. #endif } @@ -1166,12 +1199,11 @@ GTEST_API_ std::string GetCapturedStderr(); #endif // GTEST_HAS_STREAM_REDIRECTION - #if GTEST_HAS_DEATH_TEST const ::std::vector& GetInjectableArgvs(); void SetInjectableArgvs(const ::std::vector* - new_argvs); + new_argvs); // A copy of all command line arguments. Set by InitGoogleTest(). extern ::std::vector g_argvs; @@ -1185,12 +1217,13 @@ extern ::std::vector g_argvs; // Sleeps for (roughly) n milli-seconds. This function is only for // testing Google Test's own constructs. Don't use it in user tests, // either directly or indirectly. -inline void SleepMilliseconds(int n) { - const timespec time = { - 0, // 0 seconds. - n * 1000L * 1000L, // And n ms. - }; - nanosleep(&time, NULL); +inline void SleepMilliseconds(int n) +{ + const timespec time = { + 0, // 0 seconds. + n * 1000L * 1000L, // And n ms. + }; + nanosleep(&time, NULL); } // Allows a controller thread to pause execution of newly created @@ -1199,41 +1232,47 @@ inline void SleepMilliseconds(int n) { // // This class is only for testing Google Test's own constructs. Do not // use it in user tests, either directly or indirectly. -class Notification { - public: - Notification() : notified_(false) { - GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); - } - ~Notification() { - pthread_mutex_destroy(&mutex_); - } +class Notification +{ +public: + Notification() : notified_(false) + { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); + } + ~Notification() + { + pthread_mutex_destroy(&mutex_); + } - // Notifies all threads created with this notification to start. Must - // be called from the controller thread. - void Notify() { - pthread_mutex_lock(&mutex_); - notified_ = true; - pthread_mutex_unlock(&mutex_); - } + // Notifies all threads created with this notification to start. Must + // be called from the controller thread. + void Notify() + { + pthread_mutex_lock(&mutex_); + notified_ = true; + pthread_mutex_unlock(&mutex_); + } - // Blocks until the controller thread notifies. Must be called from a test - // thread. - void WaitForNotification() { - for (;;) { - pthread_mutex_lock(&mutex_); - const bool notified = notified_; - pthread_mutex_unlock(&mutex_); - if (notified) - break; - SleepMilliseconds(10); - } - } + // Blocks until the controller thread notifies. Must be called from a test + // thread. + void WaitForNotification() + { + for (;;) + { + pthread_mutex_lock(&mutex_); + const bool notified = notified_; + pthread_mutex_unlock(&mutex_); + if (notified) + break; + SleepMilliseconds(10); + } + } - private: - pthread_mutex_t mutex_; - bool notified_; +private: + pthread_mutex_t mutex_; + bool notified_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); + GTEST_DISALLOW_COPY_AND_ASSIGN_(Notification); }; // As a C-function, ThreadFuncWithCLinkage cannot be templated itself. @@ -1241,10 +1280,11 @@ class Notification { // in order to call its Run(). Introducing ThreadWithParamBase as a // non-templated base class for ThreadWithParam allows us to bypass this // problem. -class ThreadWithParamBase { - public: - virtual ~ThreadWithParamBase() {} - virtual void Run() = 0; +class ThreadWithParamBase +{ +public: + virtual ~ThreadWithParamBase() {} + virtual void Run() = 0; }; // pthread_create() accepts a pointer to a function type with the C linkage. @@ -1253,9 +1293,10 @@ class ThreadWithParamBase { // example, SunStudio) treat them as different types. Since class methods // cannot be defined with C-linkage we need to define a free C-function to // pass into pthread_create(). -extern "C" inline void* ThreadFuncWithCLinkage(void* thread) { - static_cast(thread)->Run(); - return NULL; +extern "C" inline void* ThreadFuncWithCLinkage(void* thread) +{ + static_cast(thread)->Run(); + return NULL; } // Helper class for testing Google Test's multi-threading constructs. @@ -1271,47 +1312,52 @@ extern "C" inline void* ThreadFuncWithCLinkage(void* thread) { // These classes are only for testing Google Test's own constructs. Do // not use them in user tests, either directly or indirectly. template -class ThreadWithParam : public ThreadWithParamBase { - public: - typedef void (*UserThreadFunc)(T); +class ThreadWithParam : public ThreadWithParamBase +{ +public: + typedef void (*UserThreadFunc)(T); - ThreadWithParam( - UserThreadFunc func, T param, Notification* thread_can_start) - : func_(func), - param_(param), - thread_can_start_(thread_can_start), - finished_(false) { - ThreadWithParamBase* const base = this; - // The thread can be created only after all fields except thread_ - // have been initialized. - GTEST_CHECK_POSIX_SUCCESS_( - pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base)); - } - ~ThreadWithParam() { Join(); } + ThreadWithParam( + UserThreadFunc func, T param, Notification* thread_can_start) + : func_(func), + param_(param), + thread_can_start_(thread_can_start), + finished_(false) + { + ThreadWithParamBase* const base = this; + // The thread can be created only after all fields except thread_ + // have been initialized. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_create(&thread_, 0, &ThreadFuncWithCLinkage, base)); + } + ~ThreadWithParam() { Join(); } - void Join() { - if (!finished_) { - GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0)); - finished_ = true; - } - } + void Join() + { + if (!finished_) + { + GTEST_CHECK_POSIX_SUCCESS_(pthread_join(thread_, 0)); + finished_ = true; + } + } - virtual void Run() { - if (thread_can_start_ != NULL) - thread_can_start_->WaitForNotification(); - func_(param_); - } + virtual void Run() + { + if (thread_can_start_ != NULL) + thread_can_start_->WaitForNotification(); + func_(param_); + } - private: - const UserThreadFunc func_; // User-supplied thread function. - const T param_; // User-supplied parameter to the thread function. - // When non-NULL, used to block execution until the controller thread - // notifies. - Notification* const thread_can_start_; - bool finished_; // true iff we know that the thread function has finished. - pthread_t thread_; // The native thread object. +private: + const UserThreadFunc func_; // User-supplied thread function. + const T param_; // User-supplied parameter to the thread function. + // When non-NULL, used to block execution until the controller thread + // notifies. + Notification* const thread_can_start_; + bool finished_; // true iff we know that the thread function has finished. + pthread_t thread_; // The native thread object. - GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadWithParam); }; // MutexBase and Mutex implement mutex on pthreads-based platforms. They @@ -1333,52 +1379,56 @@ class ThreadWithParam : public ThreadWithParamBase { // GTEST_DECLARE_STATIC_MUTEX_(g_some_mutex); // // To create a dynamic mutex, just define an object of type Mutex. -class MutexBase { - public: - // Acquires this mutex. - void Lock() { - GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); - owner_ = pthread_self(); - has_owner_ = true; - } +class MutexBase +{ +public: + // Acquires this mutex. + void Lock() + { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_lock(&mutex_)); + owner_ = pthread_self(); + has_owner_ = true; + } - // Releases this mutex. - void Unlock() { - // Since the lock is being released the owner_ field should no longer be - // considered valid. We don't protect writing to has_owner_ here, as it's - // the caller's responsibility to ensure that the current thread holds the - // mutex when this is called. - has_owner_ = false; - GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); - } + // Releases this mutex. + void Unlock() + { + // Since the lock is being released the owner_ field should no longer be + // considered valid. We don't protect writing to has_owner_ here, as it's + // the caller's responsibility to ensure that the current thread holds the + // mutex when this is called. + has_owner_ = false; + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_unlock(&mutex_)); + } - // Does nothing if the current thread holds the mutex. Otherwise, crashes - // with high probability. - void AssertHeld() const { - GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self())) - << "The current thread is not holding the mutex @" << this; - } + // Does nothing if the current thread holds the mutex. Otherwise, crashes + // with high probability. + void AssertHeld() const + { + GTEST_CHECK_(has_owner_ && pthread_equal(owner_, pthread_self())) + << "The current thread is not holding the mutex @" << this; + } - // A static mutex may be used before main() is entered. It may even - // be used before the dynamic initialization stage. Therefore we - // must be able to initialize a static mutex object at link time. - // This means MutexBase has to be a POD and its member variables - // have to be public. - public: - pthread_mutex_t mutex_; // The underlying pthread mutex. - // has_owner_ indicates whether the owner_ field below contains a valid thread - // ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All - // accesses to the owner_ field should be protected by a check of this field. - // An alternative might be to memset() owner_ to all zeros, but there's no - // guarantee that a zero'd pthread_t is necessarily invalid or even different - // from pthread_self(). - bool has_owner_; - pthread_t owner_; // The thread holding the mutex. + // A static mutex may be used before main() is entered. It may even + // be used before the dynamic initialization stage. Therefore we + // must be able to initialize a static mutex object at link time. + // This means MutexBase has to be a POD and its member variables + // have to be public. +public: + pthread_mutex_t mutex_; // The underlying pthread mutex. + // has_owner_ indicates whether the owner_ field below contains a valid thread + // ID and is therefore safe to inspect (e.g., to use in pthread_equal()). All + // accesses to the owner_ field should be protected by a check of this field. + // An alternative might be to memset() owner_ to all zeros, but there's no + // guarantee that a zero'd pthread_t is necessarily invalid or even different + // from pthread_self(). + bool has_owner_; + pthread_t owner_; // The thread holding the mutex. }; // Forward-declares a static mutex. -# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ - extern ::testing::internal::MutexBase mutex +#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::MutexBase mutex // Defines and statically (i.e. at link time) initializes a static mutex. // The initialization list here does not explicitly initialize each field, @@ -1386,39 +1436,43 @@ class MutexBase { // particular, the owner_ field (a pthread_t) is not explicitly initialized. // This allows initialization to work whether pthread_t is a scalar or struct. // The flag -Wmissing-field-initializers must not be specified for this to work. -# define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ - ::testing::internal::MutexBase mutex = { PTHREAD_MUTEX_INITIALIZER, false } +#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \ + ::testing::internal::MutexBase mutex = {PTHREAD_MUTEX_INITIALIZER, false} // The Mutex class can only be used for mutexes created at runtime. It // shares its API with MutexBase otherwise. -class Mutex : public MutexBase { - public: - Mutex() { - GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); - has_owner_ = false; - } - ~Mutex() { - GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); - } +class Mutex : public MutexBase +{ +public: + Mutex() + { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_init(&mutex_, NULL)); + has_owner_ = false; + } + ~Mutex() + { + GTEST_CHECK_POSIX_SUCCESS_(pthread_mutex_destroy(&mutex_)); + } - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); +private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(Mutex); }; // We cannot name this class MutexLock as the ctor declaration would // conflict with a macro named MutexLock, which is defined on some // platforms. Hence the typedef trick below. -class GTestMutexLock { - public: - explicit GTestMutexLock(MutexBase* mutex) - : mutex_(mutex) { mutex_->Lock(); } +class GTestMutexLock +{ +public: + explicit GTestMutexLock(MutexBase* mutex) + : mutex_(mutex) { mutex_->Lock(); } - ~GTestMutexLock() { mutex_->Unlock(); } + ~GTestMutexLock() { mutex_->Unlock(); } - private: - MutexBase* const mutex_; +private: + MutexBase* const mutex_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); + GTEST_DISALLOW_COPY_AND_ASSIGN_(GTestMutexLock); }; typedef GTestMutexLock MutexLock; @@ -1429,15 +1483,17 @@ typedef GTestMutexLock MutexLock; // C-linkage. Therefore it cannot be templatized to access // ThreadLocal. Hence the need for class // ThreadLocalValueHolderBase. -class ThreadLocalValueHolderBase { - public: - virtual ~ThreadLocalValueHolderBase() {} +class ThreadLocalValueHolderBase +{ +public: + virtual ~ThreadLocalValueHolderBase() {} }; // Called by pthread to delete thread-local data stored by // pthread_setspecific(). -extern "C" inline void DeleteThreadLocalValue(void* value_holder) { - delete static_cast(value_holder); +extern "C" inline void DeleteThreadLocalValue(void* value_holder) +{ + delete static_cast(value_holder); } // Implements thread-local storage on pthreads-based systems. @@ -1470,70 +1526,76 @@ extern "C" inline void DeleteThreadLocalValue(void* value_holder) { // object managed by Google Test will be leaked as long as all threads // using Google Test have exited when main() returns. template -class ThreadLocal { - public: - ThreadLocal() : key_(CreateKey()), - default_() {} - explicit ThreadLocal(const T& value) : key_(CreateKey()), - default_(value) {} +class ThreadLocal +{ +public: + ThreadLocal() : key_(CreateKey()), + default_() {} + explicit ThreadLocal(const T& value) : key_(CreateKey()), + default_(value) {} - ~ThreadLocal() { - // Destroys the managed object for the current thread, if any. - DeleteThreadLocalValue(pthread_getspecific(key_)); + ~ThreadLocal() + { + // Destroys the managed object for the current thread, if any. + DeleteThreadLocalValue(pthread_getspecific(key_)); - // Releases resources associated with the key. This will *not* - // delete managed objects for other threads. - GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_)); - } + // Releases resources associated with the key. This will *not* + // delete managed objects for other threads. + GTEST_CHECK_POSIX_SUCCESS_(pthread_key_delete(key_)); + } - T* pointer() { return GetOrCreateValue(); } - const T* pointer() const { return GetOrCreateValue(); } - const T& get() const { return *pointer(); } - void set(const T& value) { *pointer() = value; } + T* pointer() { return GetOrCreateValue(); } + const T* pointer() const { return GetOrCreateValue(); } + const T& get() const { return *pointer(); } + void set(const T& value) { *pointer() = value; } - private: - // Holds a value of type T. - class ValueHolder : public ThreadLocalValueHolderBase { - public: - explicit ValueHolder(const T& value) : value_(value) {} +private: + // Holds a value of type T. + class ValueHolder : public ThreadLocalValueHolderBase + { + public: + explicit ValueHolder(const T& value) : value_(value) {} - T* pointer() { return &value_; } + T* pointer() { return &value_; } - private: - T value_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); - }; + private: + T value_; + GTEST_DISALLOW_COPY_AND_ASSIGN_(ValueHolder); + }; - static pthread_key_t CreateKey() { - pthread_key_t key; - // When a thread exits, DeleteThreadLocalValue() will be called on - // the object managed for that thread. - GTEST_CHECK_POSIX_SUCCESS_( - pthread_key_create(&key, &DeleteThreadLocalValue)); - return key; - } + static pthread_key_t CreateKey() + { + pthread_key_t key; + // When a thread exits, DeleteThreadLocalValue() will be called on + // the object managed for that thread. + GTEST_CHECK_POSIX_SUCCESS_( + pthread_key_create(&key, &DeleteThreadLocalValue)); + return key; + } - T* GetOrCreateValue() const { - ThreadLocalValueHolderBase* const holder = - static_cast(pthread_getspecific(key_)); - if (holder != NULL) { - return CheckedDowncastToActualType(holder)->pointer(); - } + T* GetOrCreateValue() const + { + ThreadLocalValueHolderBase* const holder = + static_cast(pthread_getspecific(key_)); + if (holder != NULL) + { + return CheckedDowncastToActualType(holder)->pointer(); + } - ValueHolder* const new_holder = new ValueHolder(default_); - ThreadLocalValueHolderBase* const holder_base = new_holder; - GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); - return new_holder->pointer(); - } + ValueHolder* const new_holder = new ValueHolder(default_); + ThreadLocalValueHolderBase* const holder_base = new_holder; + GTEST_CHECK_POSIX_SUCCESS_(pthread_setspecific(key_, holder_base)); + return new_holder->pointer(); + } - // A key pthreads uses for looking up per-thread values. - const pthread_key_t key_; - const T default_; // The default value for each thread. + // A key pthreads uses for looking up per-thread values. + const pthread_key_t key_; + const T default_; // The default value for each thread. - GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); + GTEST_DISALLOW_COPY_AND_ASSIGN_(ThreadLocal); }; -# define GTEST_IS_THREADSAFE 1 +#define GTEST_IS_THREADSAFE 1 #else // GTEST_HAS_PTHREAD @@ -1542,42 +1604,46 @@ class ThreadLocal { // mutex is not supported - using Google Test in multiple threads is not // supported on such platforms. -class Mutex { - public: - Mutex() {} - void Lock() {} - void Unlock() {} - void AssertHeld() const {} +class Mutex +{ +public: + Mutex() {} + void Lock() {} + void Unlock() {} + void AssertHeld() const {} }; -# define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ - extern ::testing::internal::Mutex mutex +#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \ + extern ::testing::internal::Mutex mutex -# define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex +#define GTEST_DEFINE_STATIC_MUTEX_(mutex) ::testing::internal::Mutex mutex -class GTestMutexLock { - public: - explicit GTestMutexLock(Mutex*) {} // NOLINT +class GTestMutexLock +{ +public: + explicit GTestMutexLock(Mutex*) {} // NOLINT }; typedef GTestMutexLock MutexLock; template -class ThreadLocal { - public: - ThreadLocal() : value_() {} - explicit ThreadLocal(const T& value) : value_(value) {} - T* pointer() { return &value_; } - const T* pointer() const { return &value_; } - const T& get() const { return value_; } - void set(const T& value) { value_ = value; } - private: - T value_; +class ThreadLocal +{ +public: + ThreadLocal() : value_() {} + explicit ThreadLocal(const T& value) : value_(value) {} + T* pointer() { return &value_; } + const T* pointer() const { return &value_; } + const T& get() const { return value_; } + void set(const T& value) { value_ = value; } + +private: + T value_; }; // The above synchronization primitives have dummy implementations. // Therefore Google Test is not thread-safe. -# define GTEST_IS_THREADSAFE 0 +#define GTEST_IS_THREADSAFE 0 #endif // GTEST_HAS_PTHREAD @@ -1594,9 +1660,9 @@ GTEST_API_ size_t GetThreadCount(); #if defined(__SYMBIAN32__) || defined(__IBMCPP__) || defined(__SUNPRO_CC) // We lose support for NULL detection where the compiler doesn't like // passing non-POD classes through ellipsis (...). -# define GTEST_ELLIPSIS_NEEDS_POD_ 1 +#define GTEST_ELLIPSIS_NEEDS_POD_ 1 #else -# define GTEST_CAN_COMPARE_NULL 1 +#define GTEST_CAN_COMPARE_NULL 1 #endif // The Nokia Symbian and IBM XL C/C++ compilers cannot decide between @@ -1604,48 +1670,57 @@ GTEST_API_ size_t GetThreadCount(); // _can_ decide between class template specializations for T and T*, // so a tr1::type_traits-like is_pointer works. #if defined(__SYMBIAN32__) || defined(__IBMCPP__) -# define GTEST_NEEDS_IS_POINTER_ 1 +#define GTEST_NEEDS_IS_POINTER_ 1 #endif template -struct bool_constant { - typedef bool_constant type; - static const bool value = bool_value; +struct bool_constant +{ + typedef bool_constant type; + static const bool value = bool_value; }; -template const bool bool_constant::value; +template +const bool bool_constant::value; typedef bool_constant false_type; typedef bool_constant true_type; template -struct is_pointer : public false_type {}; +struct is_pointer : public false_type +{ +}; template -struct is_pointer : public true_type {}; +struct is_pointer : public true_type +{ +}; template -struct IteratorTraits { - typedef typename Iterator::value_type value_type; +struct IteratorTraits +{ + typedef typename Iterator::value_type value_type; }; template -struct IteratorTraits { - typedef T value_type; +struct IteratorTraits +{ + typedef T value_type; }; template -struct IteratorTraits { - typedef T value_type; +struct IteratorTraits +{ + typedef T value_type; }; #if GTEST_OS_WINDOWS -# define GTEST_PATH_SEP_ "\\" -# define GTEST_HAS_ALT_PATH_SEP_ 1 +#define GTEST_PATH_SEP_ "\\" +#define GTEST_HAS_ALT_PATH_SEP_ 1 // The biggest signed integer type the compiler supports. typedef __int64 BiggestInt; #else -# define GTEST_PATH_SEP_ "/" -# define GTEST_HAS_ALT_PATH_SEP_ 0 +#define GTEST_PATH_SEP_ "/" +#define GTEST_HAS_ALT_PATH_SEP_ 0 typedef long long BiggestInt; // NOLINT #endif // GTEST_OS_WINDOWS @@ -1656,37 +1731,47 @@ typedef long long BiggestInt; // NOLINT // Therefore we need to cast a char to unsigned char before calling // isspace(), etc. -inline bool IsAlpha(char ch) { - return isalpha(static_cast(ch)) != 0; +inline bool IsAlpha(char ch) +{ + return isalpha(static_cast(ch)) != 0; } -inline bool IsAlNum(char ch) { - return isalnum(static_cast(ch)) != 0; +inline bool IsAlNum(char ch) +{ + return isalnum(static_cast(ch)) != 0; } -inline bool IsDigit(char ch) { - return isdigit(static_cast(ch)) != 0; +inline bool IsDigit(char ch) +{ + return isdigit(static_cast(ch)) != 0; } -inline bool IsLower(char ch) { - return islower(static_cast(ch)) != 0; +inline bool IsLower(char ch) +{ + return islower(static_cast(ch)) != 0; } -inline bool IsSpace(char ch) { - return isspace(static_cast(ch)) != 0; +inline bool IsSpace(char ch) +{ + return isspace(static_cast(ch)) != 0; } -inline bool IsUpper(char ch) { - return isupper(static_cast(ch)) != 0; +inline bool IsUpper(char ch) +{ + return isupper(static_cast(ch)) != 0; } -inline bool IsXDigit(char ch) { - return isxdigit(static_cast(ch)) != 0; +inline bool IsXDigit(char ch) +{ + return isxdigit(static_cast(ch)) != 0; } -inline bool IsXDigit(wchar_t ch) { - const unsigned char low_byte = static_cast(ch); - return ch == low_byte && isxdigit(low_byte) != 0; +inline bool IsXDigit(wchar_t ch) +{ + const unsigned char low_byte = static_cast(ch); + return ch == low_byte && isxdigit(low_byte) != 0; } -inline char ToLower(char ch) { - return static_cast(tolower(static_cast(ch))); +inline char ToLower(char ch) +{ + return static_cast(tolower(static_cast(ch))); } -inline char ToUpper(char ch) { - return static_cast(toupper(static_cast(ch))); +inline char ToUpper(char ch) +{ + return static_cast(toupper(static_cast(ch))); } // The testing::internal::posix namespace holds wrappers for common @@ -1695,44 +1780,62 @@ inline char ToUpper(char ch) { // standard functions as macros, the wrapper cannot have the same name // as the wrapped function. -namespace posix { - +namespace posix +{ // Functions with a different name on Windows. #if GTEST_OS_WINDOWS typedef struct _stat StatStruct; -# ifdef __BORLANDC__ -inline int IsATTY(int fd) { return isatty(fd); } -inline int StrCaseCmp(const char* s1, const char* s2) { - return stricmp(s1, s2); +#ifdef __BORLANDC__ +inline int IsATTY(int fd) +{ + return isatty(fd); +} +inline int StrCaseCmp(const char* s1, const char* s2) +{ + return stricmp(s1, s2); } inline char* StrDup(const char* src) { return strdup(src); } -# else // !__BORLANDC__ -# if GTEST_OS_WINDOWS_MOBILE -inline int IsATTY(int /* fd */) { return 0; } -# else -inline int IsATTY(int fd) { return _isatty(fd); } -# endif // GTEST_OS_WINDOWS_MOBILE -inline int StrCaseCmp(const char* s1, const char* s2) { - return _stricmp(s1, s2); +#else // !__BORLANDC__ +#if GTEST_OS_WINDOWS_MOBILE +inline int IsATTY(int /* fd */) +{ + return 0; +} +#else +inline int IsATTY(int fd) +{ + return _isatty(fd); +} +#endif // GTEST_OS_WINDOWS_MOBILE +inline int StrCaseCmp(const char* s1, const char* s2) +{ + return _stricmp(s1, s2); } inline char* StrDup(const char* src) { return _strdup(src); } -# endif // __BORLANDC__ +#endif // __BORLANDC__ -# if GTEST_OS_WINDOWS_MOBILE -inline int FileNo(FILE* file) { return reinterpret_cast(_fileno(file)); } +#if GTEST_OS_WINDOWS_MOBILE +inline int FileNo(FILE* file) +{ + return reinterpret_cast(_fileno(file)); +} // Stat(), RmDir(), and IsDir() are not needed on Windows CE at this // time and thus not defined there. -# else -inline int FileNo(FILE* file) { return _fileno(file); } +#else +inline int FileNo(FILE* file) +{ + return _fileno(file); +} inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } inline int RmDir(const char* dir) { return _rmdir(dir); } -inline bool IsDir(const StatStruct& st) { - return (_S_IFDIR & st.st_mode) != 0; +inline bool IsDir(const StatStruct& st) +{ + return (_S_IFDIR & st.st_mode) != 0; } -# endif // GTEST_OS_WINDOWS_MOBILE +#endif // GTEST_OS_WINDOWS_MOBILE #else @@ -1741,8 +1844,9 @@ typedef struct stat StatStruct; inline int FileNo(FILE* file) { return fileno(file); } inline int IsATTY(int fd) { return isatty(fd); } inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } -inline int StrCaseCmp(const char* s1, const char* s2) { - return strcasecmp(s1, s2); +inline int StrCaseCmp(const char* s1, const char* s2) +{ + return strcasecmp(s1, s2); } inline char* StrDup(const char* src) { return strdup(src); } inline int RmDir(const char* dir) { return rmdir(dir); } @@ -1754,12 +1858,13 @@ inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } #ifdef _MSC_VER // Temporarily disable warning 4996 (deprecated function). -# pragma warning(push) -# pragma warning(disable:4996) +#pragma warning(push) +#pragma warning(disable : 4996) #endif -inline const char* StrNCpy(char* dest, const char* src, size_t n) { - return strncpy(dest, src, n); +inline const char* StrNCpy(char* dest, const char* src, size_t n) +{ + return strncpy(dest, src, n); } // ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and @@ -1767,44 +1872,55 @@ inline const char* StrNCpy(char* dest, const char* src, size_t n) { // defined there. #if !GTEST_OS_WINDOWS_MOBILE -inline int ChDir(const char* dir) { return chdir(dir); } +inline int ChDir(const char* dir) +{ + return chdir(dir); +} #endif -inline FILE* FOpen(const char* path, const char* mode) { - return fopen(path, mode); +inline FILE* FOpen(const char* path, const char* mode) +{ + return fopen(path, mode); } #if !GTEST_OS_WINDOWS_MOBILE -inline FILE *FReopen(const char* path, const char* mode, FILE* stream) { - return freopen(path, mode, stream); +inline FILE* FReopen(const char* path, const char* mode, FILE* stream) +{ + return freopen(path, mode, stream); } inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } #endif -inline int FClose(FILE* fp) { return fclose(fp); } -#if !GTEST_OS_WINDOWS_MOBILE -inline int Read(int fd, void* buf, unsigned int count) { - return static_cast(read(fd, buf, count)); +inline int FClose(FILE* fp) +{ + return fclose(fp); } -inline int Write(int fd, const void* buf, unsigned int count) { - return static_cast(write(fd, buf, count)); +#if !GTEST_OS_WINDOWS_MOBILE +inline int Read(int fd, void* buf, unsigned int count) +{ + return static_cast(read(fd, buf, count)); +} +inline int Write(int fd, const void* buf, unsigned int count) +{ + return static_cast(write(fd, buf, count)); } inline int Close(int fd) { return close(fd); } inline const char* StrError(int errnum) { return strerror(errnum); } #endif -inline const char* GetEnv(const char* name) { +inline const char* GetEnv(const char* name) +{ #if GTEST_OS_WINDOWS_MOBILE - // We are on Windows CE, which has no environment variables. - return NULL; + // We are on Windows CE, which has no environment variables. + return NULL; #elif defined(__BORLANDC__) || defined(__SunOS_5_8) || defined(__SunOS_5_9) - // Environment variables which we programmatically clear will be set to the - // empty string rather than unset (NULL). Handle that case. - const char* const env = getenv(name); - return (env != NULL && env[0] != '\0') ? env : NULL; + // Environment variables which we programmatically clear will be set to the + // empty string rather than unset (NULL). Handle that case. + const char* const env = getenv(name); + return (env != NULL && env[0] != '\0') ? env : NULL; #else - return getenv(name); + return getenv(name); #endif } #ifdef _MSC_VER -# pragma warning(pop) // Restores the warning state. +#pragma warning(pop) // Restores the warning state. #endif #if GTEST_OS_WINDOWS_MOBILE @@ -1813,7 +1929,10 @@ inline const char* GetEnv(const char* name) { // imitation of standard behaviour. void Abort(); #else -inline void Abort() { abort(); } +inline void Abort() +{ + abort(); +} #endif // GTEST_OS_WINDOWS_MOBILE } // namespace posix @@ -1825,14 +1944,14 @@ inline void Abort() { abort(); } // snprintf is a variadic function. #if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE // MSVC 2005 and above support variadic macros. -# define GTEST_SNPRINTF_(buffer, size, format, ...) \ - _snprintf_s(buffer, size, size, format, __VA_ARGS__) +#define GTEST_SNPRINTF_(buffer, size, format, ...) \ + _snprintf_s(buffer, size, size, format, __VA_ARGS__) #elif defined(_MSC_VER) // Windows CE does not define _snprintf_s and MSVC prior to 2005 doesn't // complain about _snprintf. -# define GTEST_SNPRINTF_ _snprintf +#define GTEST_SNPRINTF_ _snprintf #else -# define GTEST_SNPRINTF_ snprintf +#define GTEST_SNPRINTF_ snprintf #endif // The maximum number a BiggestInt can represent. This definition @@ -1843,7 +1962,7 @@ inline void Abort() { abort(); } // are not part of standard C++ and numeric_limits doesn't need to be // defined for them. const BiggestInt kMaxBiggestInt = - ~(static_cast(1) << (8*sizeof(BiggestInt) - 1)); + ~(static_cast(1) << (8 * sizeof(BiggestInt) - 1)); // This template class serves as a compile-time function from size to // type. It maps a size in bytes to a primitive type with that @@ -1864,35 +1983,38 @@ const BiggestInt kMaxBiggestInt = // needs. Other types can be easily added in the future if need // arises. template -class TypeWithSize { - public: - // This prevents the user from using TypeWithSize with incorrect - // values of N. - typedef void UInt; +class TypeWithSize +{ +public: + // This prevents the user from using TypeWithSize with incorrect + // values of N. + typedef void UInt; }; // The specialization for size 4. template <> -class TypeWithSize<4> { - public: - // unsigned int has size 4 in both gcc and MSVC. - // - // As base/basictypes.h doesn't compile on Windows, we cannot use - // uint32, uint64, and etc here. - typedef int Int; - typedef unsigned int UInt; +class TypeWithSize<4> +{ +public: + // unsigned int has size 4 in both gcc and MSVC. + // + // As base/basictypes.h doesn't compile on Windows, we cannot use + // uint32, uint64, and etc here. + typedef int Int; + typedef unsigned int UInt; }; // The specialization for size 8. template <> -class TypeWithSize<8> { - public: +class TypeWithSize<8> +{ +public: #if GTEST_OS_WINDOWS - typedef __int64 Int; - typedef unsigned __int64 UInt; + typedef __int64 Int; + typedef unsigned __int64 UInt; #else - typedef long long Int; // NOLINT - typedef unsigned long long UInt; // NOLINT + typedef long long Int; // NOLINT + typedef unsigned long long UInt; // NOLINT #endif // GTEST_OS_WINDOWS }; @@ -1911,17 +2033,17 @@ typedef TypeWithSize<8>::Int TimeInMillis; // Represents time in milliseconds. // Macros for declaring flags. #define GTEST_DECLARE_bool_(name) GTEST_API_ extern bool GTEST_FLAG(name) #define GTEST_DECLARE_int32_(name) \ - GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) + GTEST_API_ extern ::testing::internal::Int32 GTEST_FLAG(name) #define GTEST_DECLARE_string_(name) \ - GTEST_API_ extern ::std::string GTEST_FLAG(name) + GTEST_API_ extern ::std::string GTEST_FLAG(name) // Macros for defining flags. #define GTEST_DEFINE_bool_(name, default_val, doc) \ - GTEST_API_ bool GTEST_FLAG(name) = (default_val) + GTEST_API_ bool GTEST_FLAG(name) = (default_val) #define GTEST_DEFINE_int32_(name, default_val, doc) \ - GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) + GTEST_API_ ::testing::internal::Int32 GTEST_FLAG(name) = (default_val) #define GTEST_DEFINE_string_(name, default_val, doc) \ - GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) + GTEST_API_ ::std::string GTEST_FLAG(name) = (default_val) // Thread annotations #define GTEST_EXCLUSIVE_LOCK_REQUIRED_(locks) diff --git a/test/gtest-1.7.0/include/gtest/internal/gtest-string.h b/test/gtest-1.7.0/include/gtest/internal/gtest-string.h index 97f1a7fdd..447a99b0a 100644 --- a/test/gtest-1.7.0/include/gtest/internal/gtest-string.h +++ b/test/gtest-1.7.0/include/gtest/internal/gtest-string.h @@ -43,7 +43,7 @@ #ifdef __BORLANDC__ // string.h is not guaranteed to provide strcpy on C++ Builder. -# include +#include #endif #include @@ -51,111 +51,113 @@ #include "gtest/internal/gtest-port.h" -namespace testing { -namespace internal { - +namespace testing +{ +namespace internal +{ // String - an abstract class holding static string utilities. -class GTEST_API_ String { - public: - // Static utility methods +class GTEST_API_ String +{ +public: + // Static utility methods - // Clones a 0-terminated C string, allocating memory using new. The - // caller is responsible for deleting the return value using - // delete[]. Returns the cloned string, or NULL if the input is - // NULL. - // - // This is different from strdup() in string.h, which allocates - // memory using malloc(). - static const char* CloneCString(const char* c_str); + // Clones a 0-terminated C string, allocating memory using new. The + // caller is responsible for deleting the return value using + // delete[]. Returns the cloned string, or NULL if the input is + // NULL. + // + // This is different from strdup() in string.h, which allocates + // memory using malloc(). + static const char* CloneCString(const char* c_str); #if GTEST_OS_WINDOWS_MOBILE - // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be - // able to pass strings to Win32 APIs on CE we need to convert them - // to 'Unicode', UTF-16. + // Windows CE does not have the 'ANSI' versions of Win32 APIs. To be + // able to pass strings to Win32 APIs on CE we need to convert them + // to 'Unicode', UTF-16. - // Creates a UTF-16 wide string from the given ANSI string, allocating - // memory using new. The caller is responsible for deleting the return - // value using delete[]. Returns the wide string, or NULL if the - // input is NULL. - // - // The wide string is created using the ANSI codepage (CP_ACP) to - // match the behaviour of the ANSI versions of Win32 calls and the - // C runtime. - static LPCWSTR AnsiToUtf16(const char* c_str); + // Creates a UTF-16 wide string from the given ANSI string, allocating + // memory using new. The caller is responsible for deleting the return + // value using delete[]. Returns the wide string, or NULL if the + // input is NULL. + // + // The wide string is created using the ANSI codepage (CP_ACP) to + // match the behaviour of the ANSI versions of Win32 calls and the + // C runtime. + static LPCWSTR AnsiToUtf16(const char* c_str); - // Creates an ANSI string from the given wide string, allocating - // memory using new. The caller is responsible for deleting the return - // value using delete[]. Returns the ANSI string, or NULL if the - // input is NULL. - // - // The returned string is created using the ANSI codepage (CP_ACP) to - // match the behaviour of the ANSI versions of Win32 calls and the - // C runtime. - static const char* Utf16ToAnsi(LPCWSTR utf16_str); + // Creates an ANSI string from the given wide string, allocating + // memory using new. The caller is responsible for deleting the return + // value using delete[]. Returns the ANSI string, or NULL if the + // input is NULL. + // + // The returned string is created using the ANSI codepage (CP_ACP) to + // match the behaviour of the ANSI versions of Win32 calls and the + // C runtime. + static const char* Utf16ToAnsi(LPCWSTR utf16_str); #endif - // Compares two C strings. Returns true iff they have the same content. - // - // Unlike strcmp(), this function can handle NULL argument(s). A - // NULL C string is considered different to any non-NULL C string, - // including the empty string. - static bool CStringEquals(const char* lhs, const char* rhs); + // Compares two C strings. Returns true iff they have the same content. + // + // Unlike strcmp(), this function can handle NULL argument(s). A + // NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool CStringEquals(const char* lhs, const char* rhs); - // Converts a wide C string to a String using the UTF-8 encoding. - // NULL will be converted to "(null)". If an error occurred during - // the conversion, "(failed to convert from wide string)" is - // returned. - static std::string ShowWideCString(const wchar_t* wide_c_str); + // Converts a wide C string to a String using the UTF-8 encoding. + // NULL will be converted to "(null)". If an error occurred during + // the conversion, "(failed to convert from wide string)" is + // returned. + static std::string ShowWideCString(const wchar_t* wide_c_str); - // Compares two wide C strings. Returns true iff they have the same - // content. - // - // Unlike wcscmp(), this function can handle NULL argument(s). A - // NULL C string is considered different to any non-NULL C string, - // including the empty string. - static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); + // Compares two wide C strings. Returns true iff they have the same + // content. + // + // Unlike wcscmp(), this function can handle NULL argument(s). A + // NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs); - // Compares two C strings, ignoring case. Returns true iff they - // have the same content. - // - // Unlike strcasecmp(), this function can handle NULL argument(s). - // A NULL C string is considered different to any non-NULL C string, - // including the empty string. - static bool CaseInsensitiveCStringEquals(const char* lhs, - const char* rhs); + // Compares two C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike strcasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL C string, + // including the empty string. + static bool CaseInsensitiveCStringEquals(const char* lhs, + const char* rhs); - // Compares two wide C strings, ignoring case. Returns true iff they - // have the same content. - // - // Unlike wcscasecmp(), this function can handle NULL argument(s). - // A NULL C string is considered different to any non-NULL wide C string, - // including the empty string. - // NB: The implementations on different platforms slightly differ. - // On windows, this method uses _wcsicmp which compares according to LC_CTYPE - // environment variable. On GNU platform this method uses wcscasecmp - // which compares according to LC_CTYPE category of the current locale. - // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the - // current locale. - static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, - const wchar_t* rhs); + // Compares two wide C strings, ignoring case. Returns true iff they + // have the same content. + // + // Unlike wcscasecmp(), this function can handle NULL argument(s). + // A NULL C string is considered different to any non-NULL wide C string, + // including the empty string. + // NB: The implementations on different platforms slightly differ. + // On windows, this method uses _wcsicmp which compares according to LC_CTYPE + // environment variable. On GNU platform this method uses wcscasecmp + // which compares according to LC_CTYPE category of the current locale. + // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the + // current locale. + static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs, + const wchar_t* rhs); - // Returns true iff the given string ends with the given suffix, ignoring - // case. Any string is considered to end with an empty suffix. - static bool EndsWithCaseInsensitive( - const std::string& str, const std::string& suffix); + // Returns true iff the given string ends with the given suffix, ignoring + // case. Any string is considered to end with an empty suffix. + static bool EndsWithCaseInsensitive( + const std::string& str, const std::string& suffix); - // Formats an int value as "%02d". - static std::string FormatIntWidth2(int value); // "%02d" for width == 2 + // Formats an int value as "%02d". + static std::string FormatIntWidth2(int value); // "%02d" for width == 2 - // Formats an int value as "%X". - static std::string FormatHexInt(int value); + // Formats an int value as "%X". + static std::string FormatHexInt(int value); - // Formats a byte as "%02X". - static std::string FormatByte(unsigned char value); + // Formats a byte as "%02X". + static std::string FormatByte(unsigned char value); - private: - String(); // Not meant to be instantiated. -}; // class String +private: + String(); // Not meant to be instantiated. +}; // class String // Gets the content of the stringstream's buffer as an std::string. Each '\0' // character in the buffer is replaced with "\\0". diff --git a/test/gtest-1.7.0/include/gtest/internal/gtest-tuple.h b/test/gtest-1.7.0/include/gtest/internal/gtest-tuple.h index 7b3dfc312..899b60eb5 100644 --- a/test/gtest-1.7.0/include/gtest/internal/gtest-tuple.h +++ b/test/gtest-1.7.0/include/gtest/internal/gtest-tuple.h @@ -46,35 +46,37 @@ // private as public. // Sun Studio versions < 12 also have the above bug. #if defined(__SYMBIAN32__) || (defined(__SUNPRO_CC) && __SUNPRO_CC < 0x590) -# define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: +#define GTEST_DECLARE_TUPLE_AS_FRIEND_ public: #else -# define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ - template friend class tuple; \ - private: +#define GTEST_DECLARE_TUPLE_AS_FRIEND_ \ + template \ + friend class tuple; \ + \ +private: #endif // GTEST_n_TUPLE_(T) is the type of an n-tuple. #define GTEST_0_TUPLE_(T) tuple<> #define GTEST_1_TUPLE_(T) tuple + void, void, void> #define GTEST_2_TUPLE_(T) tuple + void, void, void> #define GTEST_3_TUPLE_(T) tuple + void, void, void> #define GTEST_4_TUPLE_(T) tuple + void, void, void> #define GTEST_5_TUPLE_(T) tuple + void, void, void> #define GTEST_6_TUPLE_(T) tuple + void, void, void> #define GTEST_7_TUPLE_(T) tuple + void, void, void> #define GTEST_8_TUPLE_(T) tuple + T##7, void, void> #define GTEST_9_TUPLE_(T) tuple + T##7, T##8, void> #define GTEST_10_TUPLE_(T) tuple + T##7, T##8, T##9> // GTEST_n_TYPENAMES_(T) declares a list of n typenames. #define GTEST_0_TYPENAMES_(T) @@ -82,43 +84,50 @@ #define GTEST_2_TYPENAMES_(T) typename T##0, typename T##1 #define GTEST_3_TYPENAMES_(T) typename T##0, typename T##1, typename T##2 #define GTEST_4_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ - typename T##3 + typename T##3 #define GTEST_5_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ - typename T##3, typename T##4 + typename T##3, typename T##4 #define GTEST_6_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ - typename T##3, typename T##4, typename T##5 + typename T##3, typename T##4, typename T##5 #define GTEST_7_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ - typename T##3, typename T##4, typename T##5, typename T##6 + typename T##3, typename T##4, typename T##5, typename T##6 #define GTEST_8_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ - typename T##3, typename T##4, typename T##5, typename T##6, typename T##7 -#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ - typename T##3, typename T##4, typename T##5, typename T##6, \ - typename T##7, typename T##8 -#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ - typename T##3, typename T##4, typename T##5, typename T##6, \ - typename T##7, typename T##8, typename T##9 + typename T##3, typename T##4, typename T##5, typename T##6, typename T##7 +#define GTEST_9_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, \ + typename T##7, typename T##8 +#define GTEST_10_TYPENAMES_(T) typename T##0, typename T##1, typename T##2, \ + typename T##3, typename T##4, typename T##5, typename T##6, \ + typename T##7, typename T##8, typename T##9 // In theory, defining stuff in the ::std namespace is undefined // behavior. We can do this as we are playing the role of a standard // library vendor. -namespace std { -namespace tr1 { - +namespace std +{ +namespace tr1 +{ template + typename T3 = void, typename T4 = void, typename T5 = void, + typename T6 = void, typename T7 = void, typename T8 = void, + typename T9 = void> class tuple; // Anything in namespace gtest_internal is Google Test's INTERNAL // IMPLEMENTATION DETAIL and MUST NOT BE USED DIRECTLY in user code. -namespace gtest_internal { - +namespace gtest_internal +{ // ByRef::type is T if T is a reference; otherwise it's const T&. template -struct ByRef { typedef const T& type; }; // NOLINT +struct ByRef +{ + typedef const T& type; +}; // NOLINT template -struct ByRef { typedef T& type; }; // NOLINT +struct ByRef +{ + typedef T& type; +}; // NOLINT // A handy wrapper for ByRef. #define GTEST_BY_REF_(T) typename ::std::tr1::gtest_internal::ByRef::type @@ -126,15 +135,22 @@ struct ByRef { typedef T& type; }; // NOLINT // AddRef::type is T if T is a reference; otherwise it's T&. This // is the same as tr1::add_reference::type. template -struct AddRef { typedef T& type; }; // NOLINT +struct AddRef +{ + typedef T& type; +}; // NOLINT template -struct AddRef { typedef T& type; }; // NOLINT +struct AddRef +{ + typedef T& type; +}; // NOLINT // A handy wrapper for AddRef. #define GTEST_ADD_REF_(T) typename ::std::tr1::gtest_internal::AddRef::type // A helper for implementing get(). -template class Get; +template +class Get; // A helper for implementing tuple_element. kIndexValid is true // iff k < the number of fields in tuple type T. @@ -142,520 +158,573 @@ template struct TupleElement; template -struct TupleElement { - typedef T0 type; +struct TupleElement +{ + typedef T0 type; }; template -struct TupleElement { - typedef T1 type; +struct TupleElement +{ + typedef T1 type; }; template -struct TupleElement { - typedef T2 type; +struct TupleElement +{ + typedef T2 type; }; template -struct TupleElement { - typedef T3 type; +struct TupleElement +{ + typedef T3 type; }; template -struct TupleElement { - typedef T4 type; +struct TupleElement +{ + typedef T4 type; }; template -struct TupleElement { - typedef T5 type; +struct TupleElement +{ + typedef T5 type; }; template -struct TupleElement { - typedef T6 type; +struct TupleElement +{ + typedef T6 type; }; template -struct TupleElement { - typedef T7 type; +struct TupleElement +{ + typedef T7 type; }; template -struct TupleElement { - typedef T8 type; +struct TupleElement +{ + typedef T8 type; }; template -struct TupleElement { - typedef T9 type; +struct TupleElement +{ + typedef T9 type; }; } // namespace gtest_internal template <> -class tuple<> { - public: - tuple() {} - tuple(const tuple& /* t */) {} - tuple& operator=(const tuple& /* t */) { return *this; } +class tuple<> +{ +public: + tuple() {} + tuple(const tuple& /* t */) {} + tuple& operator=(const tuple& /* t */) { return *this; } }; template -class GTEST_1_TUPLE_(T) { - public: - template friend class gtest_internal::Get; +class GTEST_1_TUPLE_(T) +{ +public: + template + friend class gtest_internal::Get; - tuple() : f0_() {} + tuple() : f0_() {} - explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {} + explicit tuple(GTEST_BY_REF_(T0) f0) : f0_(f0) {} - tuple(const tuple& t) : f0_(t.f0_) {} + tuple(const tuple& t) : f0_(t.f0_) {} - template - tuple(const GTEST_1_TUPLE_(U)& t) : f0_(t.f0_) {} + template + tuple(const GTEST_1_TUPLE_(U) & t) : f0_(t.f0_) + { + } - tuple& operator=(const tuple& t) { return CopyFrom(t); } + tuple& operator=(const tuple& t) { return CopyFrom(t); } - template - tuple& operator=(const GTEST_1_TUPLE_(U)& t) { - return CopyFrom(t); - } + template + tuple& operator=(const GTEST_1_TUPLE_(U) & t) + { + return CopyFrom(t); + } - GTEST_DECLARE_TUPLE_AS_FRIEND_ + GTEST_DECLARE_TUPLE_AS_FRIEND_ - template - tuple& CopyFrom(const GTEST_1_TUPLE_(U)& t) { - f0_ = t.f0_; - return *this; - } + template + tuple& CopyFrom(const GTEST_1_TUPLE_(U) & t) + { + f0_ = t.f0_; + return *this; + } - T0 f0_; + T0 f0_; }; template -class GTEST_2_TUPLE_(T) { - public: - template friend class gtest_internal::Get; +class GTEST_2_TUPLE_(T) +{ +public: + template + friend class gtest_internal::Get; - tuple() : f0_(), f1_() {} + tuple() : f0_(), f1_() {} - explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0), - f1_(f1) {} + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1) : f0_(f0), + f1_(f1) {} - tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {} + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_) {} - template - tuple(const GTEST_2_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_) {} - template - tuple(const ::std::pair& p) : f0_(p.first), f1_(p.second) {} + template + tuple(const GTEST_2_TUPLE_(U) & t) : f0_(t.f0_), f1_(t.f1_) + { + } + template + tuple(const ::std::pair& p) : f0_(p.first), f1_(p.second) + { + } - tuple& operator=(const tuple& t) { return CopyFrom(t); } + tuple& operator=(const tuple& t) { return CopyFrom(t); } - template - tuple& operator=(const GTEST_2_TUPLE_(U)& t) { - return CopyFrom(t); - } - template - tuple& operator=(const ::std::pair& p) { - f0_ = p.first; - f1_ = p.second; - return *this; - } + template + tuple& operator=(const GTEST_2_TUPLE_(U) & t) + { + return CopyFrom(t); + } + template + tuple& operator=(const ::std::pair& p) + { + f0_ = p.first; + f1_ = p.second; + return *this; + } - GTEST_DECLARE_TUPLE_AS_FRIEND_ + GTEST_DECLARE_TUPLE_AS_FRIEND_ - template - tuple& CopyFrom(const GTEST_2_TUPLE_(U)& t) { - f0_ = t.f0_; - f1_ = t.f1_; - return *this; - } + template + tuple& CopyFrom(const GTEST_2_TUPLE_(U) & t) + { + f0_ = t.f0_; + f1_ = t.f1_; + return *this; + } - T0 f0_; - T1 f1_; + T0 f0_; + T1 f1_; }; template -class GTEST_3_TUPLE_(T) { - public: - template friend class gtest_internal::Get; +class GTEST_3_TUPLE_(T) +{ +public: + template + friend class gtest_internal::Get; - tuple() : f0_(), f1_(), f2_() {} + tuple() : f0_(), f1_(), f2_() {} - explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, - GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {} + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2) : f0_(f0), f1_(f1), f2_(f2) {} - tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} - template - tuple(const GTEST_3_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) {} + template + tuple(const GTEST_3_TUPLE_(U) & t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_) + { + } - tuple& operator=(const tuple& t) { return CopyFrom(t); } + tuple& operator=(const tuple& t) { return CopyFrom(t); } - template - tuple& operator=(const GTEST_3_TUPLE_(U)& t) { - return CopyFrom(t); - } + template + tuple& operator=(const GTEST_3_TUPLE_(U) & t) + { + return CopyFrom(t); + } - GTEST_DECLARE_TUPLE_AS_FRIEND_ + GTEST_DECLARE_TUPLE_AS_FRIEND_ - template - tuple& CopyFrom(const GTEST_3_TUPLE_(U)& t) { - f0_ = t.f0_; - f1_ = t.f1_; - f2_ = t.f2_; - return *this; - } + template + tuple& CopyFrom(const GTEST_3_TUPLE_(U) & t) + { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + return *this; + } - T0 f0_; - T1 f1_; - T2 f2_; + T0 f0_; + T1 f1_; + T2 f2_; }; template -class GTEST_4_TUPLE_(T) { - public: - template friend class gtest_internal::Get; +class GTEST_4_TUPLE_(T) +{ +public: + template + friend class gtest_internal::Get; - tuple() : f0_(), f1_(), f2_(), f3_() {} + tuple() : f0_(), f1_(), f2_(), f3_() {} - explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, - GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2), - f3_(f3) {} + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3) : f0_(f0), f1_(f1), f2_(f2), f3_(f3) {} - tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {} + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) {} - template - tuple(const GTEST_4_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), - f3_(t.f3_) {} + template + tuple(const GTEST_4_TUPLE_(U) & t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_) + { + } - tuple& operator=(const tuple& t) { return CopyFrom(t); } + tuple& operator=(const tuple& t) { return CopyFrom(t); } - template - tuple& operator=(const GTEST_4_TUPLE_(U)& t) { - return CopyFrom(t); - } + template + tuple& operator=(const GTEST_4_TUPLE_(U) & t) + { + return CopyFrom(t); + } - GTEST_DECLARE_TUPLE_AS_FRIEND_ + GTEST_DECLARE_TUPLE_AS_FRIEND_ - template - tuple& CopyFrom(const GTEST_4_TUPLE_(U)& t) { - f0_ = t.f0_; - f1_ = t.f1_; - f2_ = t.f2_; - f3_ = t.f3_; - return *this; - } + template + tuple& CopyFrom(const GTEST_4_TUPLE_(U) & t) + { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + return *this; + } - T0 f0_; - T1 f1_; - T2 f2_; - T3 f3_; + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; }; template -class GTEST_5_TUPLE_(T) { - public: - template friend class gtest_internal::Get; +class GTEST_5_TUPLE_(T) +{ +public: + template + friend class gtest_internal::Get; - tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {} + tuple() : f0_(), f1_(), f2_(), f3_(), f4_() {} - explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, - GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, - GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {} + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, + GTEST_BY_REF_(T4) f4) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4) {} - tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), - f4_(t.f4_) {} + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_) {} - template - tuple(const GTEST_5_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), - f3_(t.f3_), f4_(t.f4_) {} + template + tuple(const GTEST_5_TUPLE_(U) & t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_) + { + } - tuple& operator=(const tuple& t) { return CopyFrom(t); } + tuple& operator=(const tuple& t) { return CopyFrom(t); } - template - tuple& operator=(const GTEST_5_TUPLE_(U)& t) { - return CopyFrom(t); - } + template + tuple& operator=(const GTEST_5_TUPLE_(U) & t) + { + return CopyFrom(t); + } - GTEST_DECLARE_TUPLE_AS_FRIEND_ + GTEST_DECLARE_TUPLE_AS_FRIEND_ - template - tuple& CopyFrom(const GTEST_5_TUPLE_(U)& t) { - f0_ = t.f0_; - f1_ = t.f1_; - f2_ = t.f2_; - f3_ = t.f3_; - f4_ = t.f4_; - return *this; - } + template + tuple& CopyFrom(const GTEST_5_TUPLE_(U) & t) + { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + return *this; + } - T0 f0_; - T1 f1_; - T2 f2_; - T3 f3_; - T4 f4_; + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; }; template -class GTEST_6_TUPLE_(T) { - public: - template friend class gtest_internal::Get; +class GTEST_6_TUPLE_(T) +{ +public: + template + friend class gtest_internal::Get; - tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {} + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_() {} - explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, - GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, - GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), - f5_(f5) {} + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5) {} - tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), - f4_(t.f4_), f5_(t.f5_) {} + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {} - template - tuple(const GTEST_6_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), - f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) {} + template + tuple(const GTEST_6_TUPLE_(U) & t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_) + { + } - tuple& operator=(const tuple& t) { return CopyFrom(t); } + tuple& operator=(const tuple& t) { return CopyFrom(t); } - template - tuple& operator=(const GTEST_6_TUPLE_(U)& t) { - return CopyFrom(t); - } + template + tuple& operator=(const GTEST_6_TUPLE_(U) & t) + { + return CopyFrom(t); + } - GTEST_DECLARE_TUPLE_AS_FRIEND_ + GTEST_DECLARE_TUPLE_AS_FRIEND_ - template - tuple& CopyFrom(const GTEST_6_TUPLE_(U)& t) { - f0_ = t.f0_; - f1_ = t.f1_; - f2_ = t.f2_; - f3_ = t.f3_; - f4_ = t.f4_; - f5_ = t.f5_; - return *this; - } + template + tuple& CopyFrom(const GTEST_6_TUPLE_(U) & t) + { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + return *this; + } - T0 f0_; - T1 f1_; - T2 f2_; - T3 f3_; - T4 f4_; - T5 f5_; + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; }; template -class GTEST_7_TUPLE_(T) { - public: - template friend class gtest_internal::Get; +class GTEST_7_TUPLE_(T) +{ +public: + template + friend class gtest_internal::Get; - tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {} + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_() {} - explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, - GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, - GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2), - f3_(f3), f4_(f4), f5_(f5), f6_(f6) {} + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5), f6_(f6) {} - tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), - f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} - template - tuple(const GTEST_7_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), - f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) {} + template + tuple(const GTEST_7_TUPLE_(U) & t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_) + { + } - tuple& operator=(const tuple& t) { return CopyFrom(t); } + tuple& operator=(const tuple& t) { return CopyFrom(t); } - template - tuple& operator=(const GTEST_7_TUPLE_(U)& t) { - return CopyFrom(t); - } + template + tuple& operator=(const GTEST_7_TUPLE_(U) & t) + { + return CopyFrom(t); + } - GTEST_DECLARE_TUPLE_AS_FRIEND_ + GTEST_DECLARE_TUPLE_AS_FRIEND_ - template - tuple& CopyFrom(const GTEST_7_TUPLE_(U)& t) { - f0_ = t.f0_; - f1_ = t.f1_; - f2_ = t.f2_; - f3_ = t.f3_; - f4_ = t.f4_; - f5_ = t.f5_; - f6_ = t.f6_; - return *this; - } + template + tuple& CopyFrom(const GTEST_7_TUPLE_(U) & t) + { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + return *this; + } - T0 f0_; - T1 f1_; - T2 f2_; - T3 f3_; - T4 f4_; - T5 f5_; - T6 f6_; + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; }; template -class GTEST_8_TUPLE_(T) { - public: - template friend class gtest_internal::Get; +class GTEST_8_TUPLE_(T) +{ +public: + template + friend class gtest_internal::Get; - tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {} + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_() {} - explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, - GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, - GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, - GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), - f5_(f5), f6_(f6), f7_(f7) {} + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, + GTEST_BY_REF_(T7) f7) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7) {} - tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), - f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} - template - tuple(const GTEST_8_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), - f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) {} + template + tuple(const GTEST_8_TUPLE_(U) & t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_) + { + } - tuple& operator=(const tuple& t) { return CopyFrom(t); } + tuple& operator=(const tuple& t) { return CopyFrom(t); } - template - tuple& operator=(const GTEST_8_TUPLE_(U)& t) { - return CopyFrom(t); - } + template + tuple& operator=(const GTEST_8_TUPLE_(U) & t) + { + return CopyFrom(t); + } - GTEST_DECLARE_TUPLE_AS_FRIEND_ + GTEST_DECLARE_TUPLE_AS_FRIEND_ - template - tuple& CopyFrom(const GTEST_8_TUPLE_(U)& t) { - f0_ = t.f0_; - f1_ = t.f1_; - f2_ = t.f2_; - f3_ = t.f3_; - f4_ = t.f4_; - f5_ = t.f5_; - f6_ = t.f6_; - f7_ = t.f7_; - return *this; - } + template + tuple& CopyFrom(const GTEST_8_TUPLE_(U) & t) + { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + return *this; + } - T0 f0_; - T1 f1_; - T2 f2_; - T3 f3_; - T4 f4_; - T5 f5_; - T6 f6_; - T7 f7_; + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; }; template -class GTEST_9_TUPLE_(T) { - public: - template friend class gtest_internal::Get; +class GTEST_9_TUPLE_(T) +{ +public: + template + friend class gtest_internal::Get; - tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {} + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_() {} - explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, - GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, - GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, - GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), - f5_(f5), f6_(f6), f7_(f7), f8_(f8) {} + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, + GTEST_BY_REF_(T8) f8) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8) {} - tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), - f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} - template - tuple(const GTEST_9_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), - f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) {} + template + tuple(const GTEST_9_TUPLE_(U) & t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_) + { + } - tuple& operator=(const tuple& t) { return CopyFrom(t); } + tuple& operator=(const tuple& t) { return CopyFrom(t); } - template - tuple& operator=(const GTEST_9_TUPLE_(U)& t) { - return CopyFrom(t); - } + template + tuple& operator=(const GTEST_9_TUPLE_(U) & t) + { + return CopyFrom(t); + } - GTEST_DECLARE_TUPLE_AS_FRIEND_ + GTEST_DECLARE_TUPLE_AS_FRIEND_ - template - tuple& CopyFrom(const GTEST_9_TUPLE_(U)& t) { - f0_ = t.f0_; - f1_ = t.f1_; - f2_ = t.f2_; - f3_ = t.f3_; - f4_ = t.f4_; - f5_ = t.f5_; - f6_ = t.f6_; - f7_ = t.f7_; - f8_ = t.f8_; - return *this; - } + template + tuple& CopyFrom(const GTEST_9_TUPLE_(U) & t) + { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + f8_ = t.f8_; + return *this; + } - T0 f0_; - T1 f1_; - T2 f2_; - T3 f3_; - T4 f4_; - T5 f5_; - T6 f6_; - T7 f7_; - T8 f8_; + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; + T8 f8_; }; template -class tuple { - public: - template friend class gtest_internal::Get; +class tuple +{ +public: + template + friend class gtest_internal::Get; - tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(), - f9_() {} + tuple() : f0_(), f1_(), f2_(), f3_(), f4_(), f5_(), f6_(), f7_(), f8_(), f9_() {} - explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, - GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, - GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, - GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2), - f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {} + explicit tuple(GTEST_BY_REF_(T0) f0, GTEST_BY_REF_(T1) f1, + GTEST_BY_REF_(T2) f2, GTEST_BY_REF_(T3) f3, GTEST_BY_REF_(T4) f4, + GTEST_BY_REF_(T5) f5, GTEST_BY_REF_(T6) f6, GTEST_BY_REF_(T7) f7, + GTEST_BY_REF_(T8) f8, GTEST_BY_REF_(T9) f9) : f0_(f0), f1_(f1), f2_(f2), f3_(f3), f4_(f4), f5_(f5), f6_(f6), f7_(f7), f8_(f8), f9_(f9) {} - tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), - f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {} + tuple(const tuple& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) {} - template - tuple(const GTEST_10_TUPLE_(U)& t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), - f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), - f9_(t.f9_) {} + template + tuple(const GTEST_10_TUPLE_(U) & t) : f0_(t.f0_), f1_(t.f1_), f2_(t.f2_), f3_(t.f3_), f4_(t.f4_), f5_(t.f5_), f6_(t.f6_), f7_(t.f7_), f8_(t.f8_), f9_(t.f9_) + { + } - tuple& operator=(const tuple& t) { return CopyFrom(t); } + tuple& operator=(const tuple& t) { return CopyFrom(t); } - template - tuple& operator=(const GTEST_10_TUPLE_(U)& t) { - return CopyFrom(t); - } + template + tuple& operator=(const GTEST_10_TUPLE_(U) & t) + { + return CopyFrom(t); + } - GTEST_DECLARE_TUPLE_AS_FRIEND_ + GTEST_DECLARE_TUPLE_AS_FRIEND_ - template - tuple& CopyFrom(const GTEST_10_TUPLE_(U)& t) { - f0_ = t.f0_; - f1_ = t.f1_; - f2_ = t.f2_; - f3_ = t.f3_; - f4_ = t.f4_; - f5_ = t.f5_; - f6_ = t.f6_; - f7_ = t.f7_; - f8_ = t.f8_; - f9_ = t.f9_; - return *this; - } + template + tuple& CopyFrom(const GTEST_10_TUPLE_(U) & t) + { + f0_ = t.f0_; + f1_ = t.f1_; + f2_ = t.f2_; + f3_ = t.f3_; + f4_ = t.f4_; + f5_ = t.f5_; + f6_ = t.f6_; + f7_ = t.f7_; + f8_ = t.f8_; + f9_ = t.f9_; + return *this; + } - T0 f0_; - T1 f1_; - T2 f2_; - T3 f3_; - T4 f4_; - T5 f5_; - T6 f6_; - T7 f7_; - T8 f8_; - T9 f9_; + T0 f0_; + T1 f1_; + T2 f2_; + T3 f3_; + T4 f4_; + T5 f5_; + T6 f6_; + T7 f7_; + T8 f8_; + T9 f9_; }; // 6.1.3.2 Tuple creation functions. @@ -667,275 +736,370 @@ class tuple { inline tuple<> make_tuple() { return tuple<>(); } template -inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) { - return GTEST_1_TUPLE_(T)(f0); +inline GTEST_1_TUPLE_(T) make_tuple(const T0& f0) +{ + return GTEST_1_TUPLE_(T)(f0); } template -inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) { - return GTEST_2_TUPLE_(T)(f0, f1); +inline GTEST_2_TUPLE_(T) make_tuple(const T0& f0, const T1& f1) +{ + return GTEST_2_TUPLE_(T)(f0, f1); } template -inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) { - return GTEST_3_TUPLE_(T)(f0, f1, f2); +inline GTEST_3_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2) +{ + return GTEST_3_TUPLE_(T)(f0, f1, f2); } template inline GTEST_4_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, - const T3& f3) { - return GTEST_4_TUPLE_(T)(f0, f1, f2, f3); + const T3& f3) +{ + return GTEST_4_TUPLE_(T)(f0, f1, f2, f3); } template inline GTEST_5_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, - const T3& f3, const T4& f4) { - return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4); + const T3& f3, const T4& f4) +{ + return GTEST_5_TUPLE_(T)(f0, f1, f2, f3, f4); } template inline GTEST_6_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, - const T3& f3, const T4& f4, const T5& f5) { - return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5); + const T3& f3, const T4& f4, const T5& f5) +{ + return GTEST_6_TUPLE_(T)(f0, f1, f2, f3, f4, f5); } template inline GTEST_7_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, - const T3& f3, const T4& f4, const T5& f5, const T6& f6) { - return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6); + const T3& f3, const T4& f4, const T5& f5, const T6& f6) +{ + return GTEST_7_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6); } template inline GTEST_8_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, - const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) { - return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7); + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7) +{ + return GTEST_8_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7); } template inline GTEST_9_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, - const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, - const T8& f8) { - return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8); + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, + const T8& f8) +{ + return GTEST_9_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8); } template inline GTEST_10_TUPLE_(T) make_tuple(const T0& f0, const T1& f1, const T2& f2, - const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, - const T8& f8, const T9& f9) { - return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9); + const T3& f3, const T4& f4, const T5& f5, const T6& f6, const T7& f7, + const T8& f8, const T9& f9) +{ + return GTEST_10_TUPLE_(T)(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9); } // 6.1.3.3 Tuple helper classes. -template struct tuple_size; +template +struct tuple_size; template -struct tuple_size { - static const int value = 0; +struct tuple_size +{ + static const int value = 0; }; template -struct tuple_size { - static const int value = 1; +struct tuple_size +{ + static const int value = 1; }; template -struct tuple_size { - static const int value = 2; +struct tuple_size +{ + static const int value = 2; }; template -struct tuple_size { - static const int value = 3; +struct tuple_size +{ + static const int value = 3; }; template -struct tuple_size { - static const int value = 4; +struct tuple_size +{ + static const int value = 4; }; template -struct tuple_size { - static const int value = 5; +struct tuple_size +{ + static const int value = 5; }; template -struct tuple_size { - static const int value = 6; +struct tuple_size +{ + static const int value = 6; }; template -struct tuple_size { - static const int value = 7; +struct tuple_size +{ + static const int value = 7; }; template -struct tuple_size { - static const int value = 8; +struct tuple_size +{ + static const int value = 8; }; template -struct tuple_size { - static const int value = 9; +struct tuple_size +{ + static const int value = 9; }; template -struct tuple_size { - static const int value = 10; +struct tuple_size +{ + static const int value = 10; }; template -struct tuple_element { - typedef typename gtest_internal::TupleElement< - k < (tuple_size::value), k, Tuple>::type type; +struct tuple_element +{ + typedef typename gtest_internal::TupleElement < + k<(tuple_size::value), k, Tuple>::type type; }; -#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element::type +#define GTEST_TUPLE_ELEMENT_(k, Tuple) typename tuple_element::type // 6.1.3.4 Element access. -namespace gtest_internal { - +namespace gtest_internal +{ template <> -class Get<0> { - public: - template - static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) - Field(Tuple& t) { return t.f0_; } // NOLINT +class Get<0> +{ +public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) + Field(Tuple& t) + { + return t.f0_; + } // NOLINT - template - static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) - ConstField(const Tuple& t) { return t.f0_; } + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(0, Tuple)) + ConstField(const Tuple& t) + { + return t.f0_; + } }; template <> -class Get<1> { - public: - template - static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) - Field(Tuple& t) { return t.f1_; } // NOLINT +class Get<1> +{ +public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) + Field(Tuple& t) + { + return t.f1_; + } // NOLINT - template - static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) - ConstField(const Tuple& t) { return t.f1_; } + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(1, Tuple)) + ConstField(const Tuple& t) + { + return t.f1_; + } }; template <> -class Get<2> { - public: - template - static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) - Field(Tuple& t) { return t.f2_; } // NOLINT +class Get<2> +{ +public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) + Field(Tuple& t) + { + return t.f2_; + } // NOLINT - template - static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) - ConstField(const Tuple& t) { return t.f2_; } + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(2, Tuple)) + ConstField(const Tuple& t) + { + return t.f2_; + } }; template <> -class Get<3> { - public: - template - static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) - Field(Tuple& t) { return t.f3_; } // NOLINT +class Get<3> +{ +public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) + Field(Tuple& t) + { + return t.f3_; + } // NOLINT - template - static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) - ConstField(const Tuple& t) { return t.f3_; } + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(3, Tuple)) + ConstField(const Tuple& t) + { + return t.f3_; + } }; template <> -class Get<4> { - public: - template - static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) - Field(Tuple& t) { return t.f4_; } // NOLINT +class Get<4> +{ +public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) + Field(Tuple& t) + { + return t.f4_; + } // NOLINT - template - static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) - ConstField(const Tuple& t) { return t.f4_; } + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(4, Tuple)) + ConstField(const Tuple& t) + { + return t.f4_; + } }; template <> -class Get<5> { - public: - template - static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) - Field(Tuple& t) { return t.f5_; } // NOLINT +class Get<5> +{ +public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) + Field(Tuple& t) + { + return t.f5_; + } // NOLINT - template - static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) - ConstField(const Tuple& t) { return t.f5_; } + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(5, Tuple)) + ConstField(const Tuple& t) + { + return t.f5_; + } }; template <> -class Get<6> { - public: - template - static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) - Field(Tuple& t) { return t.f6_; } // NOLINT +class Get<6> +{ +public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) + Field(Tuple& t) + { + return t.f6_; + } // NOLINT - template - static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) - ConstField(const Tuple& t) { return t.f6_; } + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(6, Tuple)) + ConstField(const Tuple& t) + { + return t.f6_; + } }; template <> -class Get<7> { - public: - template - static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) - Field(Tuple& t) { return t.f7_; } // NOLINT +class Get<7> +{ +public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) + Field(Tuple& t) + { + return t.f7_; + } // NOLINT - template - static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) - ConstField(const Tuple& t) { return t.f7_; } + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(7, Tuple)) + ConstField(const Tuple& t) + { + return t.f7_; + } }; template <> -class Get<8> { - public: - template - static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) - Field(Tuple& t) { return t.f8_; } // NOLINT +class Get<8> +{ +public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) + Field(Tuple& t) + { + return t.f8_; + } // NOLINT - template - static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) - ConstField(const Tuple& t) { return t.f8_; } + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(8, Tuple)) + ConstField(const Tuple& t) + { + return t.f8_; + } }; template <> -class Get<9> { - public: - template - static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) - Field(Tuple& t) { return t.f9_; } // NOLINT +class Get<9> +{ +public: + template + static GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) + Field(Tuple& t) + { + return t.f9_; + } // NOLINT - template - static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) - ConstField(const Tuple& t) { return t.f9_; } + template + static GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(9, Tuple)) + ConstField(const Tuple& t) + { + return t.f9_; + } }; } // namespace gtest_internal template GTEST_ADD_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) -get(GTEST_10_TUPLE_(T)& t) { - return gtest_internal::Get::Field(t); +get(GTEST_10_TUPLE_(T) & t) +{ + return gtest_internal::Get::Field(t); } template -GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) -get(const GTEST_10_TUPLE_(T)& t) { - return gtest_internal::Get::ConstField(t); +GTEST_BY_REF_(GTEST_TUPLE_ELEMENT_(k, GTEST_10_TUPLE_(T))) +get(const GTEST_10_TUPLE_(T) & t) +{ + return gtest_internal::Get::ConstField(t); } // 6.1.3.5 Relational operators // We only implement == and !=, as we don't have a need for the rest yet. -namespace gtest_internal { - +namespace gtest_internal +{ // SameSizeTuplePrefixComparator::Eq(t1, t2) returns true if the // first k fields of t1 equals the first k fields of t2. // SameSizeTuplePrefixComparator(k1, k2) would be a compiler error if @@ -944,35 +1108,43 @@ template struct SameSizeTuplePrefixComparator; template <> -struct SameSizeTuplePrefixComparator<0, 0> { - template - static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) { - return true; - } +struct SameSizeTuplePrefixComparator<0, 0> +{ + template + static bool Eq(const Tuple1& /* t1 */, const Tuple2& /* t2 */) + { + return true; + } }; template -struct SameSizeTuplePrefixComparator { - template - static bool Eq(const Tuple1& t1, const Tuple2& t2) { - return SameSizeTuplePrefixComparator::Eq(t1, t2) && - ::std::tr1::get(t1) == ::std::tr1::get(t2); - } +struct SameSizeTuplePrefixComparator +{ + template + static bool Eq(const Tuple1& t1, const Tuple2& t2) + { + return SameSizeTuplePrefixComparator::Eq(t1, t2) && + ::std::tr1::get(t1) == ::std::tr1::get(t2); + } }; } // namespace gtest_internal template -inline bool operator==(const GTEST_10_TUPLE_(T)& t, - const GTEST_10_TUPLE_(U)& u) { - return gtest_internal::SameSizeTuplePrefixComparator< - tuple_size::value, - tuple_size::value>::Eq(t, u); +inline bool operator==(const GTEST_10_TUPLE_(T) & t, + const GTEST_10_TUPLE_(U) & u) +{ + return gtest_internal::SameSizeTuplePrefixComparator< + tuple_size::value, + tuple_size::value>::Eq(t, u); } template -inline bool operator!=(const GTEST_10_TUPLE_(T)& t, - const GTEST_10_TUPLE_(U)& u) { return !(t == u); } +inline bool operator!=(const GTEST_10_TUPLE_(T) & t, + const GTEST_10_TUPLE_(U) & u) +{ + return !(t == u); +} // 6.1.4 Pairs. // Unimplemented. diff --git a/test/gtest-1.7.0/include/gtest/internal/gtest-type-util.h b/test/gtest-1.7.0/include/gtest/internal/gtest-type-util.h index e46f7cfcb..aa4adb5e8 100644 --- a/test/gtest-1.7.0/include/gtest/internal/gtest-type-util.h +++ b/test/gtest-1.7.0/include/gtest/internal/gtest-type-util.h @@ -48,43 +48,45 @@ // #ifdef __GNUC__ is too general here. It is possible to use gcc without using // libstdc++ (which is where cxxabi.h comes from). -# if GTEST_HAS_CXXABI_H_ -# include -# elif defined(__HP_aCC) -# include -# endif // GTEST_HASH_CXXABI_H_ - -namespace testing { -namespace internal { +#if GTEST_HAS_CXXABI_H_ +#include +#elif defined(__HP_aCC) +#include +#endif // GTEST_HASH_CXXABI_H_ +namespace testing +{ +namespace internal +{ // GetTypeName() returns a human-readable name of type T. // NB: This function is also used in Google Mock, so don't move it inside of // the typed-test-only section below. template -std::string GetTypeName() { -# if GTEST_HAS_RTTI +std::string GetTypeName() +{ +#if GTEST_HAS_RTTI - const char* const name = typeid(T).name(); -# if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) - int status = 0; - // gcc's implementation of typeid(T).name() mangles the type name, - // so we have to demangle it. -# if GTEST_HAS_CXXABI_H_ - using abi::__cxa_demangle; -# endif // GTEST_HAS_CXXABI_H_ - char* const readable_name = __cxa_demangle(name, 0, 0, &status); - const std::string name_str(status == 0 ? readable_name : name); - free(readable_name); - return name_str; -# else - return name; -# endif // GTEST_HAS_CXXABI_H_ || __HP_aCC + const char* const name = typeid(T).name(); +#if GTEST_HAS_CXXABI_H_ || defined(__HP_aCC) + int status = 0; + // gcc's implementation of typeid(T).name() mangles the type name, + // so we have to demangle it. +#if GTEST_HAS_CXXABI_H_ + using abi::__cxa_demangle; +#endif // GTEST_HAS_CXXABI_H_ + char* const readable_name = __cxa_demangle(name, 0, 0, &status); + const std::string name_str(status == 0 ? readable_name : name); + free(readable_name); + return name_str; +#else + return name; +#endif // GTEST_HAS_CXXABI_H_ || __HP_aCC -# else +#else - return ""; + return ""; -# endif // GTEST_HAS_RTTI +#endif // GTEST_HAS_RTTI } #if GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P @@ -97,15 +99,18 @@ template struct AssertTypeEq; template -struct AssertTypeEq { - typedef bool type; +struct AssertTypeEq +{ + typedef bool type; }; // A unique type used as the default value for the arguments of class // template Types. This allows us to simulate variadic templates // (e.g. Types, Type, and etc), which C++ doesn't // support directly. -struct None {}; +struct None +{ +}; // The following family of struct and struct templates are used to // represent type lists. In particular, TypesN @@ -115,601 +120,688 @@ struct None {}; // list. // The empty type list. -struct Types0 {}; +struct Types0 +{ +}; // Type lists of length 1, 2, 3, and so on. template -struct Types1 { - typedef T1 Head; - typedef Types0 Tail; +struct Types1 +{ + typedef T1 Head; + typedef Types0 Tail; }; template -struct Types2 { - typedef T1 Head; - typedef Types1 Tail; +struct Types2 +{ + typedef T1 Head; + typedef Types1 Tail; }; template -struct Types3 { - typedef T1 Head; - typedef Types2 Tail; +struct Types3 +{ + typedef T1 Head; + typedef Types2 Tail; }; template -struct Types4 { - typedef T1 Head; - typedef Types3 Tail; +struct Types4 +{ + typedef T1 Head; + typedef Types3 Tail; }; template -struct Types5 { - typedef T1 Head; - typedef Types4 Tail; +struct Types5 +{ + typedef T1 Head; + typedef Types4 Tail; }; template -struct Types6 { - typedef T1 Head; - typedef Types5 Tail; + typename T6> +struct Types6 +{ + typedef T1 Head; + typedef Types5 Tail; }; template -struct Types7 { - typedef T1 Head; - typedef Types6 Tail; + typename T6, typename T7> +struct Types7 +{ + typedef T1 Head; + typedef Types6 Tail; }; template -struct Types8 { - typedef T1 Head; - typedef Types7 Tail; + typename T6, typename T7, typename T8> +struct Types8 +{ + typedef T1 Head; + typedef Types7 Tail; }; template -struct Types9 { - typedef T1 Head; - typedef Types8 Tail; + typename T6, typename T7, typename T8, typename T9> +struct Types9 +{ + typedef T1 Head; + typedef Types8 Tail; }; template -struct Types10 { - typedef T1 Head; - typedef Types9 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10> +struct Types10 +{ + typedef T1 Head; + typedef Types9 Tail; }; template -struct Types11 { - typedef T1 Head; - typedef Types10 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11> +struct Types11 +{ + typedef T1 Head; + typedef Types10 Tail; }; template -struct Types12 { - typedef T1 Head; - typedef Types11 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12> +struct Types12 +{ + typedef T1 Head; + typedef Types11 Tail; }; template -struct Types13 { - typedef T1 Head; - typedef Types12 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13> +struct Types13 +{ + typedef T1 Head; + typedef Types12 Tail; }; template -struct Types14 { - typedef T1 Head; - typedef Types13 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14> +struct Types14 +{ + typedef T1 Head; + typedef Types13 Tail; }; template -struct Types15 { - typedef T1 Head; - typedef Types14 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15> +struct Types15 +{ + typedef T1 Head; + typedef Types14 + Tail; }; template -struct Types16 { - typedef T1 Head; - typedef Types15 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16> +struct Types16 +{ + typedef T1 Head; + typedef Types15 + Tail; }; template -struct Types17 { - typedef T1 Head; - typedef Types16 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17> +struct Types17 +{ + typedef T1 Head; + typedef Types16 + Tail; }; template -struct Types18 { - typedef T1 Head; - typedef Types17 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18> +struct Types18 +{ + typedef T1 Head; + typedef Types17 + Tail; }; template -struct Types19 { - typedef T1 Head; - typedef Types18 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19> +struct Types19 +{ + typedef T1 Head; + typedef Types18 + Tail; }; template -struct Types20 { - typedef T1 Head; - typedef Types19 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20> +struct Types20 +{ + typedef T1 Head; + typedef Types19 + Tail; }; template -struct Types21 { - typedef T1 Head; - typedef Types20 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21> +struct Types21 +{ + typedef T1 Head; + typedef Types20 + Tail; }; template -struct Types22 { - typedef T1 Head; - typedef Types21 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22> +struct Types22 +{ + typedef T1 Head; + typedef Types21 + Tail; }; template -struct Types23 { - typedef T1 Head; - typedef Types22 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23> +struct Types23 +{ + typedef T1 Head; + typedef Types22 + Tail; }; template -struct Types24 { - typedef T1 Head; - typedef Types23 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24> +struct Types24 +{ + typedef T1 Head; + typedef Types23 + Tail; }; template -struct Types25 { - typedef T1 Head; - typedef Types24 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25> +struct Types25 +{ + typedef T1 Head; + typedef Types24 + Tail; }; template -struct Types26 { - typedef T1 Head; - typedef Types25 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26> +struct Types26 +{ + typedef T1 Head; + typedef Types25 + Tail; }; template -struct Types27 { - typedef T1 Head; - typedef Types26 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27> +struct Types27 +{ + typedef T1 Head; + typedef Types26 + Tail; }; template -struct Types28 { - typedef T1 Head; - typedef Types27 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28> +struct Types28 +{ + typedef T1 Head; + typedef Types27 + Tail; }; template -struct Types29 { - typedef T1 Head; - typedef Types28 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29> +struct Types29 +{ + typedef T1 Head; + typedef Types28 + Tail; }; template -struct Types30 { - typedef T1 Head; - typedef Types29 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30> +struct Types30 +{ + typedef T1 Head; + typedef Types29 + Tail; }; template -struct Types31 { - typedef T1 Head; - typedef Types30 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31> +struct Types31 +{ + typedef T1 Head; + typedef Types30 + Tail; }; template -struct Types32 { - typedef T1 Head; - typedef Types31 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32> +struct Types32 +{ + typedef T1 Head; + typedef Types31 + Tail; }; template -struct Types33 { - typedef T1 Head; - typedef Types32 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33> +struct Types33 +{ + typedef T1 Head; + typedef Types32 + Tail; }; template -struct Types34 { - typedef T1 Head; - typedef Types33 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34> +struct Types34 +{ + typedef T1 Head; + typedef Types33 + Tail; }; template -struct Types35 { - typedef T1 Head; - typedef Types34 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35> +struct Types35 +{ + typedef T1 Head; + typedef Types34 + Tail; }; template -struct Types36 { - typedef T1 Head; - typedef Types35 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36> +struct Types36 +{ + typedef T1 Head; + typedef Types35 + Tail; }; template -struct Types37 { - typedef T1 Head; - typedef Types36 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37> +struct Types37 +{ + typedef T1 Head; + typedef Types36 + Tail; }; template -struct Types38 { - typedef T1 Head; - typedef Types37 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38> +struct Types38 +{ + typedef T1 Head; + typedef Types37 + Tail; }; template -struct Types39 { - typedef T1 Head; - typedef Types38 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39> +struct Types39 +{ + typedef T1 Head; + typedef Types38 + Tail; }; template -struct Types40 { - typedef T1 Head; - typedef Types39 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40> +struct Types40 +{ + typedef T1 Head; + typedef Types39 + Tail; }; template -struct Types41 { - typedef T1 Head; - typedef Types40 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41> +struct Types41 +{ + typedef T1 Head; + typedef Types40 + Tail; }; template -struct Types42 { - typedef T1 Head; - typedef Types41 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42> +struct Types42 +{ + typedef T1 Head; + typedef Types41 + Tail; }; template -struct Types43 { - typedef T1 Head; - typedef Types42 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43> +struct Types43 +{ + typedef T1 Head; + typedef Types42 + Tail; }; template -struct Types44 { - typedef T1 Head; - typedef Types43 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44> +struct Types44 +{ + typedef T1 Head; + typedef Types43 + Tail; }; template -struct Types45 { - typedef T1 Head; - typedef Types44 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45> +struct Types45 +{ + typedef T1 Head; + typedef Types44 + Tail; }; template -struct Types46 { - typedef T1 Head; - typedef Types45 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46> +struct Types46 +{ + typedef T1 Head; + typedef Types45 + Tail; }; template -struct Types47 { - typedef T1 Head; - typedef Types46 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47> +struct Types47 +{ + typedef T1 Head; + typedef Types46 + Tail; }; template -struct Types48 { - typedef T1 Head; - typedef Types47 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48> +struct Types48 +{ + typedef T1 Head; + typedef Types47 + Tail; }; template -struct Types49 { - typedef T1 Head; - typedef Types48 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49> +struct Types49 +{ + typedef T1 Head; + typedef Types48 + Tail; }; template -struct Types50 { - typedef T1 Head; - typedef Types49 Tail; + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49, typename T50> +struct Types50 +{ + typedef T1 Head; + typedef Types49 + Tail; }; - } // namespace internal // We don't want to require the users to write TypesN<...> directly, @@ -726,900 +818,991 @@ struct Types50 { // readable. The translation is done by the 'type' member of the // Types template. template -struct Types { - typedef internal::Types50 type; + typename T3 = internal::None, typename T4 = internal::None, + typename T5 = internal::None, typename T6 = internal::None, + typename T7 = internal::None, typename T8 = internal::None, + typename T9 = internal::None, typename T10 = internal::None, + typename T11 = internal::None, typename T12 = internal::None, + typename T13 = internal::None, typename T14 = internal::None, + typename T15 = internal::None, typename T16 = internal::None, + typename T17 = internal::None, typename T18 = internal::None, + typename T19 = internal::None, typename T20 = internal::None, + typename T21 = internal::None, typename T22 = internal::None, + typename T23 = internal::None, typename T24 = internal::None, + typename T25 = internal::None, typename T26 = internal::None, + typename T27 = internal::None, typename T28 = internal::None, + typename T29 = internal::None, typename T30 = internal::None, + typename T31 = internal::None, typename T32 = internal::None, + typename T33 = internal::None, typename T34 = internal::None, + typename T35 = internal::None, typename T36 = internal::None, + typename T37 = internal::None, typename T38 = internal::None, + typename T39 = internal::None, typename T40 = internal::None, + typename T41 = internal::None, typename T42 = internal::None, + typename T43 = internal::None, typename T44 = internal::None, + typename T45 = internal::None, typename T46 = internal::None, + typename T47 = internal::None, typename T48 = internal::None, + typename T49 = internal::None, typename T50 = internal::None> +struct Types +{ + typedef internal::Types50 + type; }; template <> struct Types { - typedef internal::Types0 type; + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> +{ + typedef internal::Types0 type; }; template struct Types { - typedef internal::Types1 type; + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> +{ + typedef internal::Types1 type; }; template struct Types { - typedef internal::Types2 type; + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> +{ + typedef internal::Types2 type; }; template struct Types { - typedef internal::Types3 type; + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> +{ + typedef internal::Types3 type; }; template struct Types { - typedef internal::Types4 type; + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> +{ + typedef internal::Types4 type; }; template struct Types { - typedef internal::Types5 type; + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> +{ + typedef internal::Types5 type; }; template + typename T6> struct Types { - typedef internal::Types6 type; + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> +{ + typedef internal::Types6 type; }; template + typename T6, typename T7> struct Types { - typedef internal::Types7 type; + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> +{ + typedef internal::Types7 type; }; template + typename T6, typename T7, typename T8> struct Types { - typedef internal::Types8 type; + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> +{ + typedef internal::Types8 type; }; template + typename T6, typename T7, typename T8, typename T9> struct Types { - typedef internal::Types9 type; + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> +{ + typedef internal::Types9 type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10> struct Types { - typedef internal::Types10 type; + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> +{ + typedef internal::Types10 type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11> struct Types { - typedef internal::Types11 type; + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> +{ + typedef internal::Types11 type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12> struct Types { - typedef internal::Types12 type; + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> +{ + typedef internal::Types12 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13> struct Types { - typedef internal::Types13 type; + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> +{ + typedef internal::Types13 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14> struct Types { - typedef internal::Types14 type; + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> +{ + typedef internal::Types14 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15> struct Types { - typedef internal::Types15 type; + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> +{ + typedef internal::Types15 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16> struct Types { - typedef internal::Types16 type; + T16, internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> +{ + typedef internal::Types16 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17> struct Types { - typedef internal::Types17 type; + T16, T17, internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> +{ + typedef internal::Types17 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18> struct Types { - typedef internal::Types18 type; + T16, T17, T18, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> +{ + typedef internal::Types18 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19> struct Types { - typedef internal::Types19 type; + T16, T17, T18, T19, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> +{ + typedef internal::Types19 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20> struct Types { - typedef internal::Types20 type; + T16, T17, T18, T19, T20, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> +{ + typedef internal::Types20 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21> struct Types { - typedef internal::Types21 type; + T16, T17, T18, T19, T20, T21, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> +{ + typedef internal::Types21 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22> struct Types { - typedef internal::Types22 type; + T16, T17, T18, T19, T20, T21, T22, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> +{ + typedef internal::Types22 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23> struct Types { - typedef internal::Types23 type; + T16, T17, T18, T19, T20, T21, T22, T23, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> +{ + typedef internal::Types23 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24> struct Types { - typedef internal::Types24 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> +{ + typedef internal::Types24 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25> struct Types { - typedef internal::Types25 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> +{ + typedef internal::Types25 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26> struct Types { - typedef internal::Types26 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> +{ + typedef internal::Types26 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27> struct Types { - typedef internal::Types27 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> +{ + typedef internal::Types27 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28> struct Types { - typedef internal::Types28 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> +{ + typedef internal::Types28 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29> struct Types { - typedef internal::Types29 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> +{ + typedef internal::Types29 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30> struct Types { - typedef internal::Types30 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> +{ + typedef internal::Types30 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31> struct Types { - typedef internal::Types31 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> +{ + typedef internal::Types31 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32> struct Types { - typedef internal::Types32 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> +{ + typedef internal::Types32 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33> struct Types { - typedef internal::Types33 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> +{ + typedef internal::Types33 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34> struct Types { - typedef internal::Types34 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> +{ + typedef internal::Types34 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35> struct Types { - typedef internal::Types35 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> +{ + typedef internal::Types35 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36> struct Types { - typedef internal::Types36 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> +{ + typedef internal::Types36 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37> struct Types { - typedef internal::Types37 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> +{ + typedef internal::Types37 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38> struct Types { - typedef internal::Types38 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> +{ + typedef internal::Types38 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39> struct Types { - typedef internal::Types39 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> +{ + typedef internal::Types39 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40> struct Types { - typedef internal::Types40 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None> +{ + typedef internal::Types40 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41> struct Types { - typedef internal::Types41 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None, internal::None> +{ + typedef internal::Types41 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42> struct Types { - typedef internal::Types42 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, internal::None, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> +{ + typedef internal::Types42 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43> struct Types { - typedef internal::Types43 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None, internal::None> +{ + typedef internal::Types43 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44> struct Types { - typedef internal::Types44 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + internal::None, internal::None, internal::None, internal::None, + internal::None, internal::None> +{ + typedef internal::Types44 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45> struct Types { - typedef internal::Types45 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, + internal::None, internal::None, internal::None, internal::None, + internal::None> +{ + typedef internal::Types45 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46> struct Types { - typedef internal::Types46 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, + T46, internal::None, internal::None, internal::None, internal::None> +{ + typedef internal::Types46 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47> struct Types { - typedef internal::Types47 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, + T46, T47, internal::None, internal::None, internal::None> +{ + typedef internal::Types47 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48> struct Types { - typedef internal::Types48 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, + T46, T47, T48, internal::None, internal::None> +{ + typedef internal::Types48 + type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49> struct Types { - typedef internal::Types49 type; + T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, T30, + T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, T45, + T46, T47, T48, T49, internal::None> +{ + typedef internal::Types49 + type; }; -namespace internal { - -# define GTEST_TEMPLATE_ template class +namespace internal +{ +#define GTEST_TEMPLATE_ template \ +class // The template "selector" struct TemplateSel is used to // represent Tmpl, which must be a class template with one type @@ -1630,22 +1813,26 @@ namespace internal { // This trick is necessary for simulating typedef for class templates, // which C++ doesn't support directly. template -struct TemplateSel { - template - struct Bind { - typedef Tmpl type; - }; +struct TemplateSel +{ + template + struct Bind + { + typedef Tmpl type; + }; }; -# define GTEST_BIND_(TmplSel, T) \ - TmplSel::template Bind::type +#define GTEST_BIND_(TmplSel, T) \ + TmplSel::template Bind::type // A unique struct template used as the default value for the // arguments of class template Templates. This allows us to simulate // variadic templates (e.g. Templates, Templates, // and etc), which C++ doesn't support directly. template -struct NoneT {}; +struct NoneT +{ +}; // The following family of struct and struct templates are used to // represent template lists. In particular, TemplatesN -struct Templates1 { - typedef TemplateSel Head; - typedef Templates0 Tail; +struct Templates1 +{ + typedef TemplateSel Head; + typedef Templates0 Tail; }; template -struct Templates2 { - typedef TemplateSel Head; - typedef Templates1 Tail; +struct Templates2 +{ + typedef TemplateSel Head; + typedef Templates1 Tail; }; template -struct Templates3 { - typedef TemplateSel Head; - typedef Templates2 Tail; +struct Templates3 +{ + typedef TemplateSel Head; + typedef Templates2 Tail; }; template -struct Templates4 { - typedef TemplateSel Head; - typedef Templates3 Tail; + GTEST_TEMPLATE_ T4> +struct Templates4 +{ + typedef TemplateSel Head; + typedef Templates3 Tail; }; template -struct Templates5 { - typedef TemplateSel Head; - typedef Templates4 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5> +struct Templates5 +{ + typedef TemplateSel Head; + typedef Templates4 Tail; }; template -struct Templates6 { - typedef TemplateSel Head; - typedef Templates5 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6> +struct Templates6 +{ + typedef TemplateSel Head; + typedef Templates5 Tail; }; template -struct Templates7 { - typedef TemplateSel Head; - typedef Templates6 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7> +struct Templates7 +{ + typedef TemplateSel Head; + typedef Templates6 Tail; }; template -struct Templates8 { - typedef TemplateSel Head; - typedef Templates7 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8> +struct Templates8 +{ + typedef TemplateSel Head; + typedef Templates7 Tail; }; template -struct Templates9 { - typedef TemplateSel Head; - typedef Templates8 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9> +struct Templates9 +{ + typedef TemplateSel Head; + typedef Templates8 Tail; }; template -struct Templates10 { - typedef TemplateSel Head; - typedef Templates9 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10> +struct Templates10 +{ + typedef TemplateSel Head; + typedef Templates9 Tail; }; template -struct Templates11 { - typedef TemplateSel Head; - typedef Templates10 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11> +struct Templates11 +{ + typedef TemplateSel Head; + typedef Templates10 Tail; }; template -struct Templates12 { - typedef TemplateSel Head; - typedef Templates11 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12> +struct Templates12 +{ + typedef TemplateSel Head; + typedef Templates11 Tail; }; template -struct Templates13 { - typedef TemplateSel Head; - typedef Templates12 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13> +struct Templates13 +{ + typedef TemplateSel Head; + typedef Templates12 Tail; }; template -struct Templates14 { - typedef TemplateSel Head; - typedef Templates13 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14> +struct Templates14 +{ + typedef TemplateSel Head; + typedef Templates13 + Tail; }; template -struct Templates15 { - typedef TemplateSel Head; - typedef Templates14 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15> +struct Templates15 +{ + typedef TemplateSel Head; + typedef Templates14 + Tail; }; template -struct Templates16 { - typedef TemplateSel Head; - typedef Templates15 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16> +struct Templates16 +{ + typedef TemplateSel Head; + typedef Templates15 + Tail; }; template -struct Templates17 { - typedef TemplateSel Head; - typedef Templates16 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17> +struct Templates17 +{ + typedef TemplateSel Head; + typedef Templates16 + Tail; }; template -struct Templates18 { - typedef TemplateSel Head; - typedef Templates17 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18> +struct Templates18 +{ + typedef TemplateSel Head; + typedef Templates17 + Tail; }; template -struct Templates19 { - typedef TemplateSel Head; - typedef Templates18 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19> +struct Templates19 +{ + typedef TemplateSel Head; + typedef Templates18 + Tail; }; template -struct Templates20 { - typedef TemplateSel Head; - typedef Templates19 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20> +struct Templates20 +{ + typedef TemplateSel Head; + typedef Templates19 + Tail; }; template -struct Templates21 { - typedef TemplateSel Head; - typedef Templates20 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21> +struct Templates21 +{ + typedef TemplateSel Head; + typedef Templates20 + Tail; }; template -struct Templates22 { - typedef TemplateSel Head; - typedef Templates21 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22> +struct Templates22 +{ + typedef TemplateSel Head; + typedef Templates21 + Tail; }; template -struct Templates23 { - typedef TemplateSel Head; - typedef Templates22 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23> +struct Templates23 +{ + typedef TemplateSel Head; + typedef Templates22 + Tail; }; template -struct Templates24 { - typedef TemplateSel Head; - typedef Templates23 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24> +struct Templates24 +{ + typedef TemplateSel Head; + typedef Templates23 + Tail; }; template -struct Templates25 { - typedef TemplateSel Head; - typedef Templates24 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25> +struct Templates25 +{ + typedef TemplateSel Head; + typedef Templates24 + Tail; }; template -struct Templates26 { - typedef TemplateSel Head; - typedef Templates25 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26> +struct Templates26 +{ + typedef TemplateSel Head; + typedef Templates25 + Tail; }; template -struct Templates27 { - typedef TemplateSel Head; - typedef Templates26 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27> +struct Templates27 +{ + typedef TemplateSel Head; + typedef Templates26 + Tail; }; template -struct Templates28 { - typedef TemplateSel Head; - typedef Templates27 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28> +struct Templates28 +{ + typedef TemplateSel Head; + typedef Templates27 + Tail; }; template -struct Templates29 { - typedef TemplateSel Head; - typedef Templates28 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29> +struct Templates29 +{ + typedef TemplateSel Head; + typedef Templates28 + Tail; }; template -struct Templates30 { - typedef TemplateSel Head; - typedef Templates29 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30> +struct Templates30 +{ + typedef TemplateSel Head; + typedef Templates29 + Tail; }; template -struct Templates31 { - typedef TemplateSel Head; - typedef Templates30 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31> +struct Templates31 +{ + typedef TemplateSel Head; + typedef Templates30 + Tail; }; template -struct Templates32 { - typedef TemplateSel Head; - typedef Templates31 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32> +struct Templates32 +{ + typedef TemplateSel Head; + typedef Templates31 + Tail; }; template -struct Templates33 { - typedef TemplateSel Head; - typedef Templates32 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33> +struct Templates33 +{ + typedef TemplateSel Head; + typedef Templates32 + Tail; }; template -struct Templates34 { - typedef TemplateSel Head; - typedef Templates33 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34> +struct Templates34 +{ + typedef TemplateSel Head; + typedef Templates33 + Tail; }; template -struct Templates35 { - typedef TemplateSel Head; - typedef Templates34 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35> +struct Templates35 +{ + typedef TemplateSel Head; + typedef Templates34 + Tail; }; template -struct Templates36 { - typedef TemplateSel Head; - typedef Templates35 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36> +struct Templates36 +{ + typedef TemplateSel Head; + typedef Templates35 + Tail; }; template -struct Templates37 { - typedef TemplateSel Head; - typedef Templates36 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37> +struct Templates37 +{ + typedef TemplateSel Head; + typedef Templates36 + Tail; }; template -struct Templates38 { - typedef TemplateSel Head; - typedef Templates37 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38> +struct Templates38 +{ + typedef TemplateSel Head; + typedef Templates37 + Tail; }; template -struct Templates39 { - typedef TemplateSel Head; - typedef Templates38 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39> +struct Templates39 +{ + typedef TemplateSel Head; + typedef Templates38 + Tail; }; template -struct Templates40 { - typedef TemplateSel Head; - typedef Templates39 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40> +struct Templates40 +{ + typedef TemplateSel Head; + typedef Templates39 + Tail; }; template -struct Templates41 { - typedef TemplateSel Head; - typedef Templates40 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41> +struct Templates41 +{ + typedef TemplateSel Head; + typedef Templates40 + Tail; }; template -struct Templates42 { - typedef TemplateSel Head; - typedef Templates41 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42> +struct Templates42 +{ + typedef TemplateSel Head; + typedef Templates41 + Tail; }; template -struct Templates43 { - typedef TemplateSel Head; - typedef Templates42 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43> +struct Templates43 +{ + typedef TemplateSel Head; + typedef Templates42 + Tail; }; template -struct Templates44 { - typedef TemplateSel Head; - typedef Templates43 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44> +struct Templates44 +{ + typedef TemplateSel Head; + typedef Templates43 + Tail; }; template -struct Templates45 { - typedef TemplateSel Head; - typedef Templates44 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45> +struct Templates45 +{ + typedef TemplateSel Head; + typedef Templates44 + Tail; }; template -struct Templates46 { - typedef TemplateSel Head; - typedef Templates45 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46> +struct Templates46 +{ + typedef TemplateSel Head; + typedef Templates45 + Tail; }; template -struct Templates47 { - typedef TemplateSel Head; - typedef Templates46 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47> +struct Templates47 +{ + typedef TemplateSel Head; + typedef Templates46 + Tail; }; template -struct Templates48 { - typedef TemplateSel Head; - typedef Templates47 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48> +struct Templates48 +{ + typedef TemplateSel Head; + typedef Templates47 + Tail; }; template -struct Templates49 { - typedef TemplateSel Head; - typedef Templates48 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48, + GTEST_TEMPLATE_ T49> +struct Templates49 +{ + typedef TemplateSel Head; + typedef Templates48 + Tail; }; template -struct Templates50 { - typedef TemplateSel Head; - typedef Templates49 Tail; + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48, + GTEST_TEMPLATE_ T49, GTEST_TEMPLATE_ T50> +struct Templates50 +{ + typedef TemplateSel Head; + typedef Templates49 + Tail; }; - // We don't want to require the users to write TemplatesN<...> directly, // as that would require them to count the length. Templates<...> is much // easier to write, but generates horrible messages when there is a @@ -2434,864 +2709,953 @@ struct Templates50 { // readable. The translation is done by the 'type' member of the // Templates template. template -struct Templates { - typedef Templates50 type; + GTEST_TEMPLATE_ T3 = NoneT, GTEST_TEMPLATE_ T4 = NoneT, + GTEST_TEMPLATE_ T5 = NoneT, GTEST_TEMPLATE_ T6 = NoneT, + GTEST_TEMPLATE_ T7 = NoneT, GTEST_TEMPLATE_ T8 = NoneT, + GTEST_TEMPLATE_ T9 = NoneT, GTEST_TEMPLATE_ T10 = NoneT, + GTEST_TEMPLATE_ T11 = NoneT, GTEST_TEMPLATE_ T12 = NoneT, + GTEST_TEMPLATE_ T13 = NoneT, GTEST_TEMPLATE_ T14 = NoneT, + GTEST_TEMPLATE_ T15 = NoneT, GTEST_TEMPLATE_ T16 = NoneT, + GTEST_TEMPLATE_ T17 = NoneT, GTEST_TEMPLATE_ T18 = NoneT, + GTEST_TEMPLATE_ T19 = NoneT, GTEST_TEMPLATE_ T20 = NoneT, + GTEST_TEMPLATE_ T21 = NoneT, GTEST_TEMPLATE_ T22 = NoneT, + GTEST_TEMPLATE_ T23 = NoneT, GTEST_TEMPLATE_ T24 = NoneT, + GTEST_TEMPLATE_ T25 = NoneT, GTEST_TEMPLATE_ T26 = NoneT, + GTEST_TEMPLATE_ T27 = NoneT, GTEST_TEMPLATE_ T28 = NoneT, + GTEST_TEMPLATE_ T29 = NoneT, GTEST_TEMPLATE_ T30 = NoneT, + GTEST_TEMPLATE_ T31 = NoneT, GTEST_TEMPLATE_ T32 = NoneT, + GTEST_TEMPLATE_ T33 = NoneT, GTEST_TEMPLATE_ T34 = NoneT, + GTEST_TEMPLATE_ T35 = NoneT, GTEST_TEMPLATE_ T36 = NoneT, + GTEST_TEMPLATE_ T37 = NoneT, GTEST_TEMPLATE_ T38 = NoneT, + GTEST_TEMPLATE_ T39 = NoneT, GTEST_TEMPLATE_ T40 = NoneT, + GTEST_TEMPLATE_ T41 = NoneT, GTEST_TEMPLATE_ T42 = NoneT, + GTEST_TEMPLATE_ T43 = NoneT, GTEST_TEMPLATE_ T44 = NoneT, + GTEST_TEMPLATE_ T45 = NoneT, GTEST_TEMPLATE_ T46 = NoneT, + GTEST_TEMPLATE_ T47 = NoneT, GTEST_TEMPLATE_ T48 = NoneT, + GTEST_TEMPLATE_ T49 = NoneT, GTEST_TEMPLATE_ T50 = NoneT> +struct Templates +{ + typedef Templates50 + type; }; template <> struct Templates { - typedef Templates0 type; + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT> +{ + typedef Templates0 type; }; template struct Templates { - typedef Templates1 type; + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT> +{ + typedef Templates1 type; }; template struct Templates { - typedef Templates2 type; + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT> +{ + typedef Templates2 type; }; template struct Templates { - typedef Templates3 type; + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates3 type; }; template + GTEST_TEMPLATE_ T4> struct Templates { - typedef Templates4 type; + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates4 type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5> struct Templates { - typedef Templates5 type; + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates5 type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6> struct Templates { - typedef Templates6 type; + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates6 type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7> struct Templates { - typedef Templates7 type; + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates7 type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8> struct Templates { - typedef Templates8 type; + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates8 type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9> struct Templates { - typedef Templates9 type; + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates9 type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10> struct Templates { - typedef Templates10 type; + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates10 type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11> struct Templates { - typedef Templates11 type; + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates11 type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12> struct Templates { - typedef Templates12 type; + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates12 type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13> struct Templates { - typedef Templates13 type; + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates13 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14> struct Templates { - typedef Templates14 type; + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates14 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15> struct Templates { - typedef Templates15 type; + T15, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates15 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16> struct Templates { - typedef Templates16 type; + T15, T16, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates16 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17> struct Templates { - typedef Templates17 type; + T15, T16, T17, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates17 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18> struct Templates { - typedef Templates18 type; + T15, T16, T17, T18, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates18 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19> struct Templates { - typedef Templates19 type; + T15, T16, T17, T18, T19, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates19 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20> struct Templates { - typedef Templates20 type; + T15, T16, T17, T18, T19, T20, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates20 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21> struct Templates { - typedef Templates21 type; + T15, T16, T17, T18, T19, T20, T21, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates21 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22> struct Templates { - typedef Templates22 type; + T15, T16, T17, T18, T19, T20, T21, T22, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT> +{ + typedef Templates22 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23> struct Templates { - typedef Templates23 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT> +{ + typedef Templates23 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24> struct Templates { - typedef Templates24 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT> +{ + typedef Templates24 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25> struct Templates { - typedef Templates25 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT> +{ + typedef Templates25 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26> struct Templates { - typedef Templates26 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT> +{ + typedef Templates26 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27> struct Templates { - typedef Templates27 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT> +{ + typedef Templates27 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28> struct Templates { - typedef Templates28 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT> +{ + typedef Templates28 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29> struct Templates { - typedef Templates29 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT> +{ + typedef Templates29 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30> struct Templates { - typedef Templates30 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates30 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31> struct Templates { - typedef Templates31 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates31 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32> struct Templates { - typedef Templates32 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates32 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33> struct Templates { - typedef Templates33 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates33 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34> struct Templates { - typedef Templates34 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates34 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35> struct Templates { - typedef Templates35 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates35 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36> struct Templates { - typedef Templates36 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates36 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37> struct Templates { - typedef Templates37 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, NoneT, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates37 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38> struct Templates { - typedef Templates38 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, NoneT, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates38 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39> struct Templates { - typedef Templates39 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates39 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40> struct Templates { - typedef Templates40 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, NoneT, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates40 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41> struct Templates { - typedef Templates41 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, NoneT, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates41 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42> struct Templates { - typedef Templates42 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, NoneT, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates42 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43> struct Templates { - typedef Templates43 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates43 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44> struct Templates { - typedef Templates44 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + NoneT, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates44 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45> struct Templates { - typedef Templates45 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + T45, NoneT, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates45 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46> struct Templates { - typedef Templates46 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + T45, T46, NoneT, NoneT, NoneT, NoneT> +{ + typedef Templates46 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47> struct Templates { - typedef Templates47 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + T45, T46, T47, NoneT, NoneT, NoneT> +{ + typedef Templates47 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48> struct Templates { - typedef Templates48 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + T45, T46, T47, T48, NoneT, NoneT> +{ + typedef Templates48 + type; }; template + GTEST_TEMPLATE_ T4, GTEST_TEMPLATE_ T5, GTEST_TEMPLATE_ T6, + GTEST_TEMPLATE_ T7, GTEST_TEMPLATE_ T8, GTEST_TEMPLATE_ T9, + GTEST_TEMPLATE_ T10, GTEST_TEMPLATE_ T11, GTEST_TEMPLATE_ T12, + GTEST_TEMPLATE_ T13, GTEST_TEMPLATE_ T14, GTEST_TEMPLATE_ T15, + GTEST_TEMPLATE_ T16, GTEST_TEMPLATE_ T17, GTEST_TEMPLATE_ T18, + GTEST_TEMPLATE_ T19, GTEST_TEMPLATE_ T20, GTEST_TEMPLATE_ T21, + GTEST_TEMPLATE_ T22, GTEST_TEMPLATE_ T23, GTEST_TEMPLATE_ T24, + GTEST_TEMPLATE_ T25, GTEST_TEMPLATE_ T26, GTEST_TEMPLATE_ T27, + GTEST_TEMPLATE_ T28, GTEST_TEMPLATE_ T29, GTEST_TEMPLATE_ T30, + GTEST_TEMPLATE_ T31, GTEST_TEMPLATE_ T32, GTEST_TEMPLATE_ T33, + GTEST_TEMPLATE_ T34, GTEST_TEMPLATE_ T35, GTEST_TEMPLATE_ T36, + GTEST_TEMPLATE_ T37, GTEST_TEMPLATE_ T38, GTEST_TEMPLATE_ T39, + GTEST_TEMPLATE_ T40, GTEST_TEMPLATE_ T41, GTEST_TEMPLATE_ T42, + GTEST_TEMPLATE_ T43, GTEST_TEMPLATE_ T44, GTEST_TEMPLATE_ T45, + GTEST_TEMPLATE_ T46, GTEST_TEMPLATE_ T47, GTEST_TEMPLATE_ T48, + GTEST_TEMPLATE_ T49> struct Templates { - typedef Templates49 type; + T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, T29, + T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, T44, + T45, T46, T47, T48, T49, NoneT> +{ + typedef Templates49 + type; }; // The TypeList template makes it possible to use either a single type @@ -3299,28 +3663,30 @@ struct Templates -struct TypeList { - typedef Types1 type; +struct TypeList +{ + typedef Types1 type; }; template + typename T6, typename T7, typename T8, typename T9, typename T10, + typename T11, typename T12, typename T13, typename T14, typename T15, + typename T16, typename T17, typename T18, typename T19, typename T20, + typename T21, typename T22, typename T23, typename T24, typename T25, + typename T26, typename T27, typename T28, typename T29, typename T30, + typename T31, typename T32, typename T33, typename T34, typename T35, + typename T36, typename T37, typename T38, typename T39, typename T40, + typename T41, typename T42, typename T43, typename T44, typename T45, + typename T46, typename T47, typename T48, typename T49, typename T50> struct TypeList > { - typedef typename Types::type type; + T14, T15, T16, T17, T18, T19, T20, T21, T22, T23, T24, T25, T26, T27, T28, + T29, T30, T31, T32, T33, T34, T35, T36, T37, T38, T39, T40, T41, T42, T43, + T44, T45, T46, T47, T48, T49, T50> > +{ + typedef typename Types::type type; }; #endif // GTEST_HAS_TYPED_TEST || GTEST_HAS_TYPED_TEST_P diff --git a/test/gtest-1.7.0/src/gtest-death-test.cc b/test/gtest-1.7.0/src/gtest-death-test.cc index a6023fce4..5abdb10ae 100644 --- a/test/gtest-1.7.0/src/gtest-death-test.cc +++ b/test/gtest-1.7.0/src/gtest-death-test.cc @@ -36,30 +36,30 @@ #if GTEST_HAS_DEATH_TEST -# if GTEST_OS_MAC -# include -# endif // GTEST_OS_MAC +#if GTEST_OS_MAC +#include +#endif // GTEST_OS_MAC -# include -# include -# include +#include +#include +#include -# if GTEST_OS_LINUX -# include -# endif // GTEST_OS_LINUX +#if GTEST_OS_LINUX +#include +#endif // GTEST_OS_LINUX -# include +#include -# if GTEST_OS_WINDOWS -# include -# else -# include -# include -# endif // GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS +#include +#else +#include +#include +#endif // GTEST_OS_WINDOWS -# if GTEST_OS_QNX -# include -# endif // GTEST_OS_QNX +#if GTEST_OS_QNX +#include +#endif // GTEST_OS_QNX #endif // GTEST_HAS_DEATH_TEST @@ -75,49 +75,50 @@ #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ -namespace testing { - +namespace testing +{ // Constants. // The default death test style. static const char kDefaultDeathTestStyle[] = "fast"; GTEST_DEFINE_string_( - death_test_style, - internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), - "Indicates how to run a death test in a forked child process: " - "\"threadsafe\" (child process re-executes the test binary " - "from the beginning, running only the specific death test) or " - "\"fast\" (child process runs the death test immediately " - "after forking)."); + death_test_style, + internal::StringFromGTestEnv("death_test_style", kDefaultDeathTestStyle), + "Indicates how to run a death test in a forked child process: " + "\"threadsafe\" (child process re-executes the test binary " + "from the beginning, running only the specific death test) or " + "\"fast\" (child process runs the death test immediately " + "after forking)."); GTEST_DEFINE_bool_( - death_test_use_fork, - internal::BoolFromGTestEnv("death_test_use_fork", false), - "Instructs to use fork()/_exit() instead of clone() in death tests. " - "Ignored and always uses fork() on POSIX systems where clone() is not " - "implemented. Useful when running under valgrind or similar tools if " - "those do not support clone(). Valgrind 3.3.1 will just fail if " - "it sees an unsupported combination of clone() flags. " - "It is not recommended to use this flag w/o valgrind though it will " - "work in 99% of the cases. Once valgrind is fixed, this flag will " - "most likely be removed."); + death_test_use_fork, + internal::BoolFromGTestEnv("death_test_use_fork", false), + "Instructs to use fork()/_exit() instead of clone() in death tests. " + "Ignored and always uses fork() on POSIX systems where clone() is not " + "implemented. Useful when running under valgrind or similar tools if " + "those do not support clone(). Valgrind 3.3.1 will just fail if " + "it sees an unsupported combination of clone() flags. " + "It is not recommended to use this flag w/o valgrind though it will " + "work in 99% of the cases. Once valgrind is fixed, this flag will " + "most likely be removed."); -namespace internal { +namespace internal +{ GTEST_DEFINE_string_( - internal_run_death_test, "", - "Indicates the file, line number, temporal index of " - "the single death test to run, and a file descriptor to " - "which a success code may be sent, all separated by " - "the '|' characters. This flag is specified if and only if the current " - "process is a sub-process launched for running a thread-safe " - "death test. FOR INTERNAL USE ONLY."); + internal_run_death_test, "", + "Indicates the file, line number, temporal index of " + "the single death test to run, and a file descriptor to " + "which a success code may be sent, all separated by " + "the '|' characters. This flag is specified if and only if the current " + "process is a sub-process launched for running a thread-safe " + "death test. FOR INTERNAL USE ONLY."); } // namespace internal #if GTEST_HAS_DEATH_TEST -namespace internal { - +namespace internal +{ // Valid only for fast death tests. Indicates the code is running in the // child process of a fast style death test. static bool g_in_fast_death_test_child = false; @@ -127,104 +128,116 @@ static bool g_in_fast_death_test_child = false; // Valgrind heap checkers may need this to modify their behavior in death // tests. IMPORTANT: This is an internal utility. Using it may break the // implementation of death tests. User code MUST NOT use it. -bool InDeathTestChild() { -# if GTEST_OS_WINDOWS +bool InDeathTestChild() +{ +#if GTEST_OS_WINDOWS - // On Windows, death tests are thread-safe regardless of the value of the - // death_test_style flag. - return !GTEST_FLAG(internal_run_death_test).empty(); + // On Windows, death tests are thread-safe regardless of the value of the + // death_test_style flag. + return !GTEST_FLAG(internal_run_death_test).empty(); -# else +#else - if (GTEST_FLAG(death_test_style) == "threadsafe") - return !GTEST_FLAG(internal_run_death_test).empty(); - else - return g_in_fast_death_test_child; + if (GTEST_FLAG(death_test_style) == "threadsafe") + return !GTEST_FLAG(internal_run_death_test).empty(); + else + return g_in_fast_death_test_child; #endif } } // namespace internal // ExitedWithCode constructor. -ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) { +ExitedWithCode::ExitedWithCode(int exit_code) : exit_code_(exit_code) +{ } // ExitedWithCode function-call operator. -bool ExitedWithCode::operator()(int exit_status) const { -# if GTEST_OS_WINDOWS +bool ExitedWithCode::operator()(int exit_status) const +{ +#if GTEST_OS_WINDOWS - return exit_status == exit_code_; + return exit_status == exit_code_; -# else +#else - return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; + return WIFEXITED(exit_status) && WEXITSTATUS(exit_status) == exit_code_; -# endif // GTEST_OS_WINDOWS +#endif // GTEST_OS_WINDOWS } -# if !GTEST_OS_WINDOWS +#if !GTEST_OS_WINDOWS // KilledBySignal constructor. -KilledBySignal::KilledBySignal(int signum) : signum_(signum) { +KilledBySignal::KilledBySignal(int signum) : signum_(signum) +{ } // KilledBySignal function-call operator. -bool KilledBySignal::operator()(int exit_status) const { - return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; +bool KilledBySignal::operator()(int exit_status) const +{ + return WIFSIGNALED(exit_status) && WTERMSIG(exit_status) == signum_; } -# endif // !GTEST_OS_WINDOWS - -namespace internal { +#endif // !GTEST_OS_WINDOWS +namespace internal +{ // Utilities needed for death tests. // Generates a textual description of a given exit code, in the format // specified by wait(2). -static std::string ExitSummary(int exit_code) { - Message m; +static std::string ExitSummary(int exit_code) +{ + Message m; -# if GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS - m << "Exited with exit status " << exit_code; + m << "Exited with exit status " << exit_code; -# else +#else - if (WIFEXITED(exit_code)) { - m << "Exited with exit status " << WEXITSTATUS(exit_code); - } else if (WIFSIGNALED(exit_code)) { - m << "Terminated by signal " << WTERMSIG(exit_code); - } -# ifdef WCOREDUMP - if (WCOREDUMP(exit_code)) { - m << " (core dumped)"; - } -# endif -# endif // GTEST_OS_WINDOWS + if (WIFEXITED(exit_code)) + { + m << "Exited with exit status " << WEXITSTATUS(exit_code); + } + else if (WIFSIGNALED(exit_code)) + { + m << "Terminated by signal " << WTERMSIG(exit_code); + } +#ifdef WCOREDUMP + if (WCOREDUMP(exit_code)) + { + m << " (core dumped)"; + } +#endif +#endif // GTEST_OS_WINDOWS - return m.GetString(); + return m.GetString(); } // Returns true if exit_status describes a process that was terminated // by a signal, or exited normally with a nonzero exit code. -bool ExitedUnsuccessfully(int exit_status) { - return !ExitedWithCode(0)(exit_status); +bool ExitedUnsuccessfully(int exit_status) +{ + return !ExitedWithCode(0)(exit_status); } -# if !GTEST_OS_WINDOWS +#if !GTEST_OS_WINDOWS // Generates a textual failure message when a death test finds more than // one thread running, or cannot determine the number of threads, prior // to executing the given statement. It is the responsibility of the // caller not to pass a thread_count of 1. -static std::string DeathTestThreadWarning(size_t thread_count) { - Message msg; - msg << "Death tests use fork(), which is unsafe particularly" - << " in a threaded context. For this test, " << GTEST_NAME_ << " "; - if (thread_count == 0) - msg << "couldn't detect the number of threads."; - else - msg << "detected " << thread_count << " threads."; - return msg.GetString(); +static std::string DeathTestThreadWarning(size_t thread_count) +{ + Message msg; + msg << "Death tests use fork(), which is unsafe particularly" + << " in a threaded context. For this test, " << GTEST_NAME_ << " "; + if (thread_count == 0) + msg << "couldn't detect the number of threads."; + else + msg << "detected " << thread_count << " threads."; + return msg.GetString(); } -# endif // !GTEST_OS_WINDOWS +#endif // !GTEST_OS_WINDOWS // Flag characters for reporting a death test that did not die. static const char kDeathTestLived = 'L'; @@ -241,43 +254,54 @@ static const char kDeathTestInternalError = 'I'; // has not yet concluded. // TODO(vladl@google.com): Unify names and possibly values for // AbortReason, DeathTestOutcome, and flag characters above. -enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; +enum DeathTestOutcome +{ + IN_PROGRESS, + DIED, + LIVED, + RETURNED, + THREW +}; // Routine for aborting the program which is safe to call from an // exec-style death test child process, in which case the error // message is propagated back to the parent process. Otherwise, the // message is simply printed to stderr. In either case, the program // then exits with status 1. -void DeathTestAbort(const std::string& message) { - // On a POSIX system, this function may be called from a threadsafe-style - // death test child process, which operates on a very small stack. Use - // the heap for any additional non-minuscule memory requirements. - const InternalRunDeathTestFlag* const flag = - GetUnitTestImpl()->internal_run_death_test_flag(); - if (flag != NULL) { - FILE* parent = posix::FDOpen(flag->write_fd(), "w"); - fputc(kDeathTestInternalError, parent); - fprintf(parent, "%s", message.c_str()); - fflush(parent); - _exit(1); - } else { - fprintf(stderr, "%s", message.c_str()); - fflush(stderr); - posix::Abort(); - } +void DeathTestAbort(const std::string& message) +{ + // On a POSIX system, this function may be called from a threadsafe-style + // death test child process, which operates on a very small stack. Use + // the heap for any additional non-minuscule memory requirements. + const InternalRunDeathTestFlag* const flag = + GetUnitTestImpl()->internal_run_death_test_flag(); + if (flag != NULL) + { + FILE* parent = posix::FDOpen(flag->write_fd(), "w"); + fputc(kDeathTestInternalError, parent); + fprintf(parent, "%s", message.c_str()); + fflush(parent); + _exit(1); + } + else + { + fprintf(stderr, "%s", message.c_str()); + fflush(stderr); + posix::Abort(); + } } // A replacement for CHECK that calls DeathTestAbort if the assertion // fails. -# define GTEST_DEATH_TEST_CHECK_(expression) \ - do { \ - if (!::testing::internal::IsTrue(expression)) { \ - DeathTestAbort( \ - ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ - + ::testing::internal::StreamableToString(__LINE__) + ": " \ - + #expression); \ - } \ - } while (::testing::internal::AlwaysFalse()) +#define GTEST_DEATH_TEST_CHECK_(expression) \ + do \ + { \ + if (!::testing::internal::IsTrue(expression)) \ + { \ + DeathTestAbort( \ + ::std::string("CHECK failed: File ") + __FILE__ + ", line " + ::testing::internal::StreamableToString(__LINE__) + ": " + #expression); \ + } \ + } while (::testing::internal::AlwaysFalse()) // This macro is similar to GTEST_DEATH_TEST_CHECK_, but it is meant for // evaluating any system call that fulfills two conditions: it must return @@ -286,223 +310,249 @@ void DeathTestAbort(const std::string& message) { // evaluates the expression as long as it evaluates to -1 and sets // errno to EINTR. If the expression evaluates to -1 but errno is // something other than EINTR, DeathTestAbort is called. -# define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ - do { \ - int gtest_retval; \ - do { \ - gtest_retval = (expression); \ - } while (gtest_retval == -1 && errno == EINTR); \ - if (gtest_retval == -1) { \ - DeathTestAbort( \ - ::std::string("CHECK failed: File ") + __FILE__ + ", line " \ - + ::testing::internal::StreamableToString(__LINE__) + ": " \ - + #expression + " != -1"); \ - } \ - } while (::testing::internal::AlwaysFalse()) +#define GTEST_DEATH_TEST_CHECK_SYSCALL_(expression) \ + do \ + { \ + int gtest_retval; \ + do \ + { \ + gtest_retval = (expression); \ + } while (gtest_retval == -1 && errno == EINTR); \ + if (gtest_retval == -1) \ + { \ + DeathTestAbort( \ + ::std::string("CHECK failed: File ") + __FILE__ + ", line " + ::testing::internal::StreamableToString(__LINE__) + ": " + #expression + " != -1"); \ + } \ + } while (::testing::internal::AlwaysFalse()) // Returns the message describing the last system error in errno. -std::string GetLastErrnoDescription() { - return errno == 0 ? "" : posix::StrError(errno); +std::string GetLastErrnoDescription() +{ + return errno == 0 ? "" : posix::StrError(errno); } // This is called from a death test parent process to read a failure // message from the death test child process and log it with the FATAL // severity. On Windows, the message is read from a pipe handle. On other // platforms, it is read from a file descriptor. -static void FailFromInternalError(int fd) { - Message error; - char buffer[256]; - int num_read; +static void FailFromInternalError(int fd) +{ + Message error; + char buffer[256]; + int num_read; - do { - while ((num_read = posix::Read(fd, buffer, 255)) > 0) { - buffer[num_read] = '\0'; - error << buffer; - } - } while (num_read == -1 && errno == EINTR); + do + { + while ((num_read = posix::Read(fd, buffer, 255)) > 0) + { + buffer[num_read] = '\0'; + error << buffer; + } + } while (num_read == -1 && errno == EINTR); - if (num_read == 0) { - GTEST_LOG_(FATAL) << error.GetString(); - } else { - const int last_error = errno; - GTEST_LOG_(FATAL) << "Error while reading death test internal: " - << GetLastErrnoDescription() << " [" << last_error << "]"; - } + if (num_read == 0) + { + GTEST_LOG_(FATAL) << error.GetString(); + } + else + { + const int last_error = errno; + GTEST_LOG_(FATAL) << "Error while reading death test internal: " + << GetLastErrnoDescription() << " [" << last_error << "]"; + } } // Death test constructor. Increments the running death test count // for the current test. -DeathTest::DeathTest() { - TestInfo* const info = GetUnitTestImpl()->current_test_info(); - if (info == NULL) { - DeathTestAbort("Cannot run a death test outside of a TEST or " - "TEST_F construct"); - } +DeathTest::DeathTest() +{ + TestInfo* const info = GetUnitTestImpl()->current_test_info(); + if (info == NULL) + { + DeathTestAbort( + "Cannot run a death test outside of a TEST or " + "TEST_F construct"); + } } // Creates and returns a death test by dispatching to the current // death test factory. bool DeathTest::Create(const char* statement, const RE* regex, - const char* file, int line, DeathTest** test) { - return GetUnitTestImpl()->death_test_factory()->Create( - statement, regex, file, line, test); + const char* file, int line, DeathTest** test) +{ + return GetUnitTestImpl()->death_test_factory()->Create( + statement, regex, file, line, test); } -const char* DeathTest::LastMessage() { - return last_death_test_message_.c_str(); +const char* DeathTest::LastMessage() +{ + return last_death_test_message_.c_str(); } -void DeathTest::set_last_death_test_message(const std::string& message) { - last_death_test_message_ = message; +void DeathTest::set_last_death_test_message(const std::string& message) +{ + last_death_test_message_ = message; } std::string DeathTest::last_death_test_message_; // Provides cross platform implementation for some death functionality. -class DeathTestImpl : public DeathTest { - protected: - DeathTestImpl(const char* a_statement, const RE* a_regex) - : statement_(a_statement), - regex_(a_regex), - spawned_(false), - status_(-1), - outcome_(IN_PROGRESS), - read_fd_(-1), - write_fd_(-1) {} +class DeathTestImpl : public DeathTest +{ +protected: + DeathTestImpl(const char* a_statement, const RE* a_regex) + : statement_(a_statement), + regex_(a_regex), + spawned_(false), + status_(-1), + outcome_(IN_PROGRESS), + read_fd_(-1), + write_fd_(-1) {} - // read_fd_ is expected to be closed and cleared by a derived class. - ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } + // read_fd_ is expected to be closed and cleared by a derived class. + ~DeathTestImpl() { GTEST_DEATH_TEST_CHECK_(read_fd_ == -1); } - void Abort(AbortReason reason); - virtual bool Passed(bool status_ok); + void Abort(AbortReason reason); + virtual bool Passed(bool status_ok); - const char* statement() const { return statement_; } - const RE* regex() const { return regex_; } - bool spawned() const { return spawned_; } - void set_spawned(bool is_spawned) { spawned_ = is_spawned; } - int status() const { return status_; } - void set_status(int a_status) { status_ = a_status; } - DeathTestOutcome outcome() const { return outcome_; } - void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } - int read_fd() const { return read_fd_; } - void set_read_fd(int fd) { read_fd_ = fd; } - int write_fd() const { return write_fd_; } - void set_write_fd(int fd) { write_fd_ = fd; } + const char* statement() const { return statement_; } + const RE* regex() const { return regex_; } + bool spawned() const { return spawned_; } + void set_spawned(bool is_spawned) { spawned_ = is_spawned; } + int status() const { return status_; } + void set_status(int a_status) { status_ = a_status; } + DeathTestOutcome outcome() const { return outcome_; } + void set_outcome(DeathTestOutcome an_outcome) { outcome_ = an_outcome; } + int read_fd() const { return read_fd_; } + void set_read_fd(int fd) { read_fd_ = fd; } + int write_fd() const { return write_fd_; } + void set_write_fd(int fd) { write_fd_ = fd; } - // Called in the parent process only. Reads the result code of the death - // test child process via a pipe, interprets it to set the outcome_ - // member, and closes read_fd_. Outputs diagnostics and terminates in - // case of unexpected codes. - void ReadAndInterpretStatusByte(); + // Called in the parent process only. Reads the result code of the death + // test child process via a pipe, interprets it to set the outcome_ + // member, and closes read_fd_. Outputs diagnostics and terminates in + // case of unexpected codes. + void ReadAndInterpretStatusByte(); - private: - // The textual content of the code this object is testing. This class - // doesn't own this string and should not attempt to delete it. - const char* const statement_; - // The regular expression which test output must match. DeathTestImpl - // doesn't own this object and should not attempt to delete it. - const RE* const regex_; - // True if the death test child process has been successfully spawned. - bool spawned_; - // The exit status of the child process. - int status_; - // How the death test concluded. - DeathTestOutcome outcome_; - // Descriptor to the read end of the pipe to the child process. It is - // always -1 in the child process. The child keeps its write end of the - // pipe in write_fd_. - int read_fd_; - // Descriptor to the child's write end of the pipe to the parent process. - // It is always -1 in the parent process. The parent keeps its end of the - // pipe in read_fd_. - int write_fd_; +private: + // The textual content of the code this object is testing. This class + // doesn't own this string and should not attempt to delete it. + const char* const statement_; + // The regular expression which test output must match. DeathTestImpl + // doesn't own this object and should not attempt to delete it. + const RE* const regex_; + // True if the death test child process has been successfully spawned. + bool spawned_; + // The exit status of the child process. + int status_; + // How the death test concluded. + DeathTestOutcome outcome_; + // Descriptor to the read end of the pipe to the child process. It is + // always -1 in the child process. The child keeps its write end of the + // pipe in write_fd_. + int read_fd_; + // Descriptor to the child's write end of the pipe to the parent process. + // It is always -1 in the parent process. The parent keeps its end of the + // pipe in read_fd_. + int write_fd_; }; // Called in the parent process only. Reads the result code of the death // test child process via a pipe, interprets it to set the outcome_ // member, and closes read_fd_. Outputs diagnostics and terminates in // case of unexpected codes. -void DeathTestImpl::ReadAndInterpretStatusByte() { - char flag; - int bytes_read; +void DeathTestImpl::ReadAndInterpretStatusByte() +{ + char flag; + int bytes_read; - // The read() here blocks until data is available (signifying the - // failure of the death test) or until the pipe is closed (signifying - // its success), so it's okay to call this in the parent before - // the child process has exited. - do { - bytes_read = posix::Read(read_fd(), &flag, 1); - } while (bytes_read == -1 && errno == EINTR); + // The read() here blocks until data is available (signifying the + // failure of the death test) or until the pipe is closed (signifying + // its success), so it's okay to call this in the parent before + // the child process has exited. + do + { + bytes_read = posix::Read(read_fd(), &flag, 1); + } while (bytes_read == -1 && errno == EINTR); - if (bytes_read == 0) { - set_outcome(DIED); - } else if (bytes_read == 1) { - switch (flag) { - case kDeathTestReturned: - set_outcome(RETURNED); - break; - case kDeathTestThrew: - set_outcome(THREW); - break; - case kDeathTestLived: - set_outcome(LIVED); - break; - case kDeathTestInternalError: - FailFromInternalError(read_fd()); // Does not return. - break; - default: - GTEST_LOG_(FATAL) << "Death test child process reported " - << "unexpected status byte (" - << static_cast(flag) << ")"; - } - } else { - GTEST_LOG_(FATAL) << "Read from death test child process failed: " - << GetLastErrnoDescription(); - } - GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); - set_read_fd(-1); + if (bytes_read == 0) + { + set_outcome(DIED); + } + else if (bytes_read == 1) + { + switch (flag) + { + case kDeathTestReturned: + set_outcome(RETURNED); + break; + case kDeathTestThrew: + set_outcome(THREW); + break; + case kDeathTestLived: + set_outcome(LIVED); + break; + case kDeathTestInternalError: + FailFromInternalError(read_fd()); // Does not return. + break; + default: + GTEST_LOG_(FATAL) << "Death test child process reported " + << "unexpected status byte (" + << static_cast(flag) << ")"; + } + } + else + { + GTEST_LOG_(FATAL) << "Read from death test child process failed: " + << GetLastErrnoDescription(); + } + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Close(read_fd())); + set_read_fd(-1); } // Signals that the death test code which should have exited, didn't. // Should be called only in a death test child process. // Writes a status byte to the child's status file descriptor, then // calls _exit(1). -void DeathTestImpl::Abort(AbortReason reason) { - // The parent process considers the death test to be a failure if - // it finds any data in our pipe. So, here we write a single flag byte - // to the pipe, then exit. - const char status_ch = - reason == TEST_DID_NOT_DIE ? kDeathTestLived : - reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; +void DeathTestImpl::Abort(AbortReason reason) +{ + // The parent process considers the death test to be a failure if + // it finds any data in our pipe. So, here we write a single flag byte + // to the pipe, then exit. + const char status_ch = + reason == TEST_DID_NOT_DIE ? kDeathTestLived : reason == TEST_THREW_EXCEPTION ? kDeathTestThrew : kDeathTestReturned; - GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); - // We are leaking the descriptor here because on some platforms (i.e., - // when built as Windows DLL), destructors of global objects will still - // run after calling _exit(). On such systems, write_fd_ will be - // indirectly closed from the destructor of UnitTestImpl, causing double - // close if it is also closed here. On debug configurations, double close - // may assert. As there are no in-process buffers to flush here, we are - // relying on the OS to close the descriptor after the process terminates - // when the destructors are not run. - _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) + GTEST_DEATH_TEST_CHECK_SYSCALL_(posix::Write(write_fd(), &status_ch, 1)); + // We are leaking the descriptor here because on some platforms (i.e., + // when built as Windows DLL), destructors of global objects will still + // run after calling _exit(). On such systems, write_fd_ will be + // indirectly closed from the destructor of UnitTestImpl, causing double + // close if it is also closed here. On debug configurations, double close + // may assert. As there are no in-process buffers to flush here, we are + // relying on the OS to close the descriptor after the process terminates + // when the destructors are not run. + _exit(1); // Exits w/o any normal exit hooks (we were supposed to crash) } // Returns an indented copy of stderr output for a death test. // This makes distinguishing death test output lines from regular log lines // much easier. -static ::std::string FormatDeathTestOutput(const ::std::string& output) { - ::std::string ret; - for (size_t at = 0; ; ) { - const size_t line_end = output.find('\n', at); - ret += "[ DEATH ] "; - if (line_end == ::std::string::npos) { - ret += output.substr(at); - break; - } - ret += output.substr(at, line_end + 1 - at); - at = line_end + 1; - } - return ret; +static ::std::string FormatDeathTestOutput(const ::std::string& output) +{ + ::std::string ret; + for (size_t at = 0;;) + { + const size_t line_end = output.find('\n', at); + ret += "[ DEATH ] "; + if (line_end == ::std::string::npos) + { + ret += output.substr(at); + break; + } + ret += output.substr(at, line_end + 1 - at); + at = line_end + 1; + } + return ret; } // Assesses the success or failure of a death test, using both private @@ -527,56 +577,69 @@ static ::std::string FormatDeathTestOutput(const ::std::string& output) { // Returns true iff all of the above conditions are met. Otherwise, the // first failing condition, in the order given above, is the one that is // reported. Also sets the last death test message string. -bool DeathTestImpl::Passed(bool status_ok) { - if (!spawned()) - return false; +bool DeathTestImpl::Passed(bool status_ok) +{ + if (!spawned()) + return false; - const std::string error_message = GetCapturedStderr(); + const std::string error_message = GetCapturedStderr(); - bool success = false; - Message buffer; + bool success = false; + Message buffer; - buffer << "Death test: " << statement() << "\n"; - switch (outcome()) { - case LIVED: - buffer << " Result: failed to die.\n" - << " Error msg:\n" << FormatDeathTestOutput(error_message); - break; - case THREW: - buffer << " Result: threw an exception.\n" - << " Error msg:\n" << FormatDeathTestOutput(error_message); - break; - case RETURNED: - buffer << " Result: illegal return in test statement.\n" - << " Error msg:\n" << FormatDeathTestOutput(error_message); - break; - case DIED: - if (status_ok) { - const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); - if (matched) { - success = true; - } else { - buffer << " Result: died but not with expected error.\n" - << " Expected: " << regex()->pattern() << "\n" - << "Actual msg:\n" << FormatDeathTestOutput(error_message); - } - } else { - buffer << " Result: died but not with expected exit code:\n" - << " " << ExitSummary(status()) << "\n" - << "Actual msg:\n" << FormatDeathTestOutput(error_message); - } - break; - case IN_PROGRESS: - default: - GTEST_LOG_(FATAL) - << "DeathTest::Passed somehow called before conclusion of test"; - } + buffer << "Death test: " << statement() << "\n"; + switch (outcome()) + { + case LIVED: + buffer << " Result: failed to die.\n" + << " Error msg:\n" + << FormatDeathTestOutput(error_message); + break; + case THREW: + buffer << " Result: threw an exception.\n" + << " Error msg:\n" + << FormatDeathTestOutput(error_message); + break; + case RETURNED: + buffer << " Result: illegal return in test statement.\n" + << " Error msg:\n" + << FormatDeathTestOutput(error_message); + break; + case DIED: + if (status_ok) + { + const bool matched = RE::PartialMatch(error_message.c_str(), *regex()); + if (matched) + { + success = true; + } + else + { + buffer << " Result: died but not with expected error.\n" + << " Expected: " << regex()->pattern() << "\n" + << "Actual msg:\n" + << FormatDeathTestOutput(error_message); + } + } + else + { + buffer << " Result: died but not with expected exit code:\n" + << " " << ExitSummary(status()) << "\n" + << "Actual msg:\n" + << FormatDeathTestOutput(error_message); + } + break; + case IN_PROGRESS: + default: + GTEST_LOG_(FATAL) + << "DeathTest::Passed somehow called before conclusion of test"; + } - DeathTest::set_last_death_test_message(buffer.GetString()); - return success; + DeathTest::set_last_death_test_message(buffer.GetString()); + return success; } -# if GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // WindowsDeathTest implements death tests on Windows. Due to the // specifics of starting new processes on Windows, death tests there are // always threadsafe, and Google Test considers the @@ -605,75 +668,78 @@ bool DeathTestImpl::Passed(bool status_ok) { // Note: to distinguish Win32 API calls from the local method and function // calls, the former are explicitly resolved in the global namespace. // -class WindowsDeathTest : public DeathTestImpl { - public: - WindowsDeathTest(const char* a_statement, - const RE* a_regex, - const char* file, - int line) - : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} +class WindowsDeathTest : public DeathTestImpl +{ +public: + WindowsDeathTest(const char* a_statement, + const RE* a_regex, + const char* file, + int line) + : DeathTestImpl(a_statement, a_regex), file_(file), line_(line) {} - // All of these virtual functions are inherited from DeathTest. - virtual int Wait(); - virtual TestRole AssumeRole(); + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); + virtual TestRole AssumeRole(); - private: - // The name of the file in which the death test is located. - const char* const file_; - // The line number on which the death test is located. - const int line_; - // Handle to the write end of the pipe to the child process. - AutoHandle write_handle_; - // Child process handle. - AutoHandle child_handle_; - // Event the child process uses to signal the parent that it has - // acquired the handle to the write end of the pipe. After seeing this - // event the parent can release its own handles to make sure its - // ReadFile() calls return when the child terminates. - AutoHandle event_handle_; +private: + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; + // Handle to the write end of the pipe to the child process. + AutoHandle write_handle_; + // Child process handle. + AutoHandle child_handle_; + // Event the child process uses to signal the parent that it has + // acquired the handle to the write end of the pipe. After seeing this + // event the parent can release its own handles to make sure its + // ReadFile() calls return when the child terminates. + AutoHandle event_handle_; }; // Waits for the child in a death test to exit, returning its exit // status, or 0 if no child process exists. As a side effect, sets the // outcome data member. -int WindowsDeathTest::Wait() { - if (!spawned()) - return 0; +int WindowsDeathTest::Wait() +{ + if (!spawned()) + return 0; - // Wait until the child either signals that it has acquired the write end - // of the pipe or it dies. - const HANDLE wait_handles[2] = { child_handle_.Get(), event_handle_.Get() }; - switch (::WaitForMultipleObjects(2, - wait_handles, - FALSE, // Waits for any of the handles. - INFINITE)) { - case WAIT_OBJECT_0: - case WAIT_OBJECT_0 + 1: - break; - default: - GTEST_DEATH_TEST_CHECK_(false); // Should not get here. - } + // Wait until the child either signals that it has acquired the write end + // of the pipe or it dies. + const HANDLE wait_handles[2] = {child_handle_.Get(), event_handle_.Get()}; + switch (::WaitForMultipleObjects(2, + wait_handles, + FALSE, // Waits for any of the handles. + INFINITE)) + { + case WAIT_OBJECT_0: + case WAIT_OBJECT_0 + 1: + break; + default: + GTEST_DEATH_TEST_CHECK_(false); // Should not get here. + } - // The child has acquired the write end of the pipe or exited. - // We release the handle on our side and continue. - write_handle_.Reset(); - event_handle_.Reset(); + // The child has acquired the write end of the pipe or exited. + // We release the handle on our side and continue. + write_handle_.Reset(); + event_handle_.Reset(); - ReadAndInterpretStatusByte(); + ReadAndInterpretStatusByte(); - // Waits for the child process to exit if it haven't already. This - // returns immediately if the child has already exited, regardless of - // whether previous calls to WaitForMultipleObjects synchronized on this - // handle or not. - GTEST_DEATH_TEST_CHECK_( - WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), - INFINITE)); - DWORD status_code; - GTEST_DEATH_TEST_CHECK_( - ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); - child_handle_.Reset(); - set_status(static_cast(status_code)); - return status(); + // Waits for the child process to exit if it haven't already. This + // returns immediately if the child has already exited, regardless of + // whether previous calls to WaitForMultipleObjects synchronized on this + // handle or not. + GTEST_DEATH_TEST_CHECK_( + WAIT_OBJECT_0 == ::WaitForSingleObject(child_handle_.Get(), + INFINITE)); + DWORD status_code; + GTEST_DEATH_TEST_CHECK_( + ::GetExitCodeProcess(child_handle_.Get(), &status_code) != FALSE); + child_handle_.Reset(); + set_status(static_cast(status_code)); + return status(); } // The AssumeRole process for a Windows death test. It creates a child @@ -681,294 +747,317 @@ int WindowsDeathTest::Wait() { // death test. The child process is given the --gtest_filter and // --gtest_internal_run_death_test flags such that it knows to run the // current death test only. -DeathTest::TestRole WindowsDeathTest::AssumeRole() { - const UnitTestImpl* const impl = GetUnitTestImpl(); - const InternalRunDeathTestFlag* const flag = - impl->internal_run_death_test_flag(); - const TestInfo* const info = impl->current_test_info(); - const int death_test_index = info->result()->death_test_count(); +DeathTest::TestRole WindowsDeathTest::AssumeRole() +{ + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); - if (flag != NULL) { - // ParseInternalRunDeathTestFlag() has performed all the necessary - // processing. - set_write_fd(flag->write_fd()); - return EXECUTE_TEST; - } + if (flag != NULL) + { + // ParseInternalRunDeathTestFlag() has performed all the necessary + // processing. + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } - // WindowsDeathTest uses an anonymous pipe to communicate results of - // a death test. - SECURITY_ATTRIBUTES handles_are_inheritable = { - sizeof(SECURITY_ATTRIBUTES), NULL, TRUE }; - HANDLE read_handle, write_handle; - GTEST_DEATH_TEST_CHECK_( - ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, - 0) // Default buffer size. - != FALSE); - set_read_fd(::_open_osfhandle(reinterpret_cast(read_handle), - O_RDONLY)); - write_handle_.Reset(write_handle); - event_handle_.Reset(::CreateEvent( - &handles_are_inheritable, - TRUE, // The event will automatically reset to non-signaled state. - FALSE, // The initial state is non-signalled. - NULL)); // The even is unnamed. - GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); - const std::string filter_flag = - std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + - info->test_case_name() + "." + info->name(); - const std::string internal_flag = - std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + - "=" + file_ + "|" + StreamableToString(line_) + "|" + - StreamableToString(death_test_index) + "|" + - StreamableToString(static_cast(::GetCurrentProcessId())) + - // size_t has the same width as pointers on both 32-bit and 64-bit - // Windows platforms. - // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. - "|" + StreamableToString(reinterpret_cast(write_handle)) + - "|" + StreamableToString(reinterpret_cast(event_handle_.Get())); + // WindowsDeathTest uses an anonymous pipe to communicate results of + // a death test. + SECURITY_ATTRIBUTES handles_are_inheritable = { + sizeof(SECURITY_ATTRIBUTES), NULL, TRUE}; + HANDLE read_handle, write_handle; + GTEST_DEATH_TEST_CHECK_( + ::CreatePipe(&read_handle, &write_handle, &handles_are_inheritable, + 0) // Default buffer size. + != FALSE); + set_read_fd(::_open_osfhandle(reinterpret_cast(read_handle), + O_RDONLY)); + write_handle_.Reset(write_handle); + event_handle_.Reset(::CreateEvent( + &handles_are_inheritable, + TRUE, // The event will automatically reset to non-signaled state. + FALSE, // The initial state is non-signalled. + NULL)); // The even is unnamed. + GTEST_DEATH_TEST_CHECK_(event_handle_.Get() != NULL); + const std::string filter_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + + info->test_case_name() + "." + info->name(); + const std::string internal_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + + "=" + file_ + "|" + StreamableToString(line_) + "|" + + StreamableToString(death_test_index) + "|" + + StreamableToString(static_cast(::GetCurrentProcessId())) + + // size_t has the same width as pointers on both 32-bit and 64-bit + // Windows platforms. + // See http://msdn.microsoft.com/en-us/library/tcxf1dw6.aspx. + "|" + StreamableToString(reinterpret_cast(write_handle)) + + "|" + StreamableToString(reinterpret_cast(event_handle_.Get())); - char executable_path[_MAX_PATH + 1]; // NOLINT - GTEST_DEATH_TEST_CHECK_( - _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, - executable_path, - _MAX_PATH)); + char executable_path[_MAX_PATH + 1]; // NOLINT + GTEST_DEATH_TEST_CHECK_( + _MAX_PATH + 1 != ::GetModuleFileNameA(NULL, + executable_path, + _MAX_PATH)); - std::string command_line = - std::string(::GetCommandLineA()) + " " + filter_flag + " \"" + - internal_flag + "\""; + std::string command_line = + std::string(::GetCommandLineA()) + " " + filter_flag + " \"" + + internal_flag + "\""; - DeathTest::set_last_death_test_message(""); + DeathTest::set_last_death_test_message(""); - CaptureStderr(); - // Flush the log buffers since the log streams are shared with the child. - FlushInfoLog(); + CaptureStderr(); + // Flush the log buffers since the log streams are shared with the child. + FlushInfoLog(); - // The child process will share the standard handles with the parent. - STARTUPINFOA startup_info; - memset(&startup_info, 0, sizeof(STARTUPINFO)); - startup_info.dwFlags = STARTF_USESTDHANDLES; - startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); - startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); - startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); + // The child process will share the standard handles with the parent. + STARTUPINFOA startup_info; + memset(&startup_info, 0, sizeof(STARTUPINFO)); + startup_info.dwFlags = STARTF_USESTDHANDLES; + startup_info.hStdInput = ::GetStdHandle(STD_INPUT_HANDLE); + startup_info.hStdOutput = ::GetStdHandle(STD_OUTPUT_HANDLE); + startup_info.hStdError = ::GetStdHandle(STD_ERROR_HANDLE); - PROCESS_INFORMATION process_info; - GTEST_DEATH_TEST_CHECK_(::CreateProcessA( - executable_path, - const_cast(command_line.c_str()), - NULL, // Retuned process handle is not inheritable. - NULL, // Retuned thread handle is not inheritable. - TRUE, // Child inherits all inheritable handles (for write_handle_). - 0x0, // Default creation flags. - NULL, // Inherit the parent's environment. - UnitTest::GetInstance()->original_working_dir(), - &startup_info, - &process_info) != FALSE); - child_handle_.Reset(process_info.hProcess); - ::CloseHandle(process_info.hThread); - set_spawned(true); - return OVERSEE_TEST; + PROCESS_INFORMATION process_info; + GTEST_DEATH_TEST_CHECK_(::CreateProcessA( + executable_path, + const_cast(command_line.c_str()), + NULL, // Retuned process handle is not inheritable. + NULL, // Retuned thread handle is not inheritable. + TRUE, // Child inherits all inheritable handles (for write_handle_). + 0x0, // Default creation flags. + NULL, // Inherit the parent's environment. + UnitTest::GetInstance()->original_working_dir(), + &startup_info, + &process_info) != FALSE); + child_handle_.Reset(process_info.hProcess); + ::CloseHandle(process_info.hThread); + set_spawned(true); + return OVERSEE_TEST; } -# else // We are not on Windows. +#else // We are not on Windows. // ForkingDeathTest provides implementations for most of the abstract // methods of the DeathTest interface. Only the AssumeRole method is // left undefined. -class ForkingDeathTest : public DeathTestImpl { - public: - ForkingDeathTest(const char* statement, const RE* regex); +class ForkingDeathTest : public DeathTestImpl +{ +public: + ForkingDeathTest(const char* statement, const RE* regex); - // All of these virtual functions are inherited from DeathTest. - virtual int Wait(); + // All of these virtual functions are inherited from DeathTest. + virtual int Wait(); - protected: - void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } +protected: + void set_child_pid(pid_t child_pid) { child_pid_ = child_pid; } - private: - // PID of child process during death test; 0 in the child process itself. - pid_t child_pid_; +private: + // PID of child process during death test; 0 in the child process itself. + pid_t child_pid_; }; // Constructs a ForkingDeathTest. ForkingDeathTest::ForkingDeathTest(const char* a_statement, const RE* a_regex) - : DeathTestImpl(a_statement, a_regex), - child_pid_(-1) {} + : DeathTestImpl(a_statement, a_regex), + child_pid_(-1) {} // Waits for the child in a death test to exit, returning its exit // status, or 0 if no child process exists. As a side effect, sets the // outcome data member. -int ForkingDeathTest::Wait() { - if (!spawned()) - return 0; +int ForkingDeathTest::Wait() +{ + if (!spawned()) + return 0; - ReadAndInterpretStatusByte(); + ReadAndInterpretStatusByte(); - int status_value; - GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); - set_status(status_value); - return status_value; + int status_value; + GTEST_DEATH_TEST_CHECK_SYSCALL_(waitpid(child_pid_, &status_value, 0)); + set_status(status_value); + return status_value; } // A concrete death test class that forks, then immediately runs the test // in the child process. -class NoExecDeathTest : public ForkingDeathTest { - public: - NoExecDeathTest(const char* a_statement, const RE* a_regex) : - ForkingDeathTest(a_statement, a_regex) { } - virtual TestRole AssumeRole(); +class NoExecDeathTest : public ForkingDeathTest +{ +public: + NoExecDeathTest(const char* a_statement, const RE* a_regex) : ForkingDeathTest(a_statement, a_regex) {} + virtual TestRole AssumeRole(); }; // The AssumeRole process for a fork-and-run death test. It implements a // straightforward fork, with a simple pipe to transmit the status byte. -DeathTest::TestRole NoExecDeathTest::AssumeRole() { - const size_t thread_count = GetThreadCount(); - if (thread_count != 1) { - GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); - } +DeathTest::TestRole NoExecDeathTest::AssumeRole() +{ + const size_t thread_count = GetThreadCount(); + if (thread_count != 1) + { + GTEST_LOG_(WARNING) << DeathTestThreadWarning(thread_count); + } - int pipe_fd[2]; - GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); - DeathTest::set_last_death_test_message(""); - CaptureStderr(); - // When we fork the process below, the log file buffers are copied, but the - // file descriptors are shared. We flush all log files here so that closing - // the file descriptors in the child process doesn't throw off the - // synchronization between descriptors and buffers in the parent process. - // This is as close to the fork as possible to avoid a race condition in case - // there are multiple threads running before the death test, and another - // thread writes to the log file. - FlushInfoLog(); + DeathTest::set_last_death_test_message(""); + CaptureStderr(); + // When we fork the process below, the log file buffers are copied, but the + // file descriptors are shared. We flush all log files here so that closing + // the file descriptors in the child process doesn't throw off the + // synchronization between descriptors and buffers in the parent process. + // This is as close to the fork as possible to avoid a race condition in case + // there are multiple threads running before the death test, and another + // thread writes to the log file. + FlushInfoLog(); - const pid_t child_pid = fork(); - GTEST_DEATH_TEST_CHECK_(child_pid != -1); - set_child_pid(child_pid); - if (child_pid == 0) { - GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); - set_write_fd(pipe_fd[1]); - // Redirects all logging to stderr in the child process to prevent - // concurrent writes to the log files. We capture stderr in the parent - // process and append the child process' output to a log. - LogToStderr(); - // Event forwarding to the listeners of event listener API mush be shut - // down in death test subprocesses. - GetUnitTestImpl()->listeners()->SuppressEventForwarding(); - g_in_fast_death_test_child = true; - return EXECUTE_TEST; - } else { - GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); - set_read_fd(pipe_fd[0]); - set_spawned(true); - return OVERSEE_TEST; - } + const pid_t child_pid = fork(); + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + set_child_pid(child_pid); + if (child_pid == 0) + { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[0])); + set_write_fd(pipe_fd[1]); + // Redirects all logging to stderr in the child process to prevent + // concurrent writes to the log files. We capture stderr in the parent + // process and append the child process' output to a log. + LogToStderr(); + // Event forwarding to the listeners of event listener API mush be shut + // down in death test subprocesses. + GetUnitTestImpl()->listeners()->SuppressEventForwarding(); + g_in_fast_death_test_child = true; + return EXECUTE_TEST; + } + else + { + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; + } } // A concrete death test class that forks and re-executes the main // program from the beginning, with command-line flags set that cause // only this specific death test to be run. -class ExecDeathTest : public ForkingDeathTest { - public: - ExecDeathTest(const char* a_statement, const RE* a_regex, - const char* file, int line) : - ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) { } - virtual TestRole AssumeRole(); - private: - static ::std::vector - GetArgvsForDeathTestChildProcess() { - ::std::vector args = GetInjectableArgvs(); - return args; - } - // The name of the file in which the death test is located. - const char* const file_; - // The line number on which the death test is located. - const int line_; +class ExecDeathTest : public ForkingDeathTest +{ +public: + ExecDeathTest(const char* a_statement, const RE* a_regex, + const char* file, int line) : ForkingDeathTest(a_statement, a_regex), file_(file), line_(line) {} + virtual TestRole AssumeRole(); + +private: + static ::std::vector + GetArgvsForDeathTestChildProcess() + { + ::std::vector args = GetInjectableArgvs(); + return args; + } + // The name of the file in which the death test is located. + const char* const file_; + // The line number on which the death test is located. + const int line_; }; // Utility class for accumulating command-line arguments. -class Arguments { - public: - Arguments() { - args_.push_back(NULL); - } +class Arguments +{ +public: + Arguments() + { + args_.push_back(NULL); + } - ~Arguments() { - for (std::vector::iterator i = args_.begin(); i != args_.end(); - ++i) { - free(*i); - } - } - void AddArgument(const char* argument) { - args_.insert(args_.end() - 1, posix::StrDup(argument)); - } + ~Arguments() + { + for (std::vector::iterator i = args_.begin(); i != args_.end(); + ++i) + { + free(*i); + } + } + void AddArgument(const char* argument) + { + args_.insert(args_.end() - 1, posix::StrDup(argument)); + } - template - void AddArguments(const ::std::vector& arguments) { - for (typename ::std::vector::const_iterator i = arguments.begin(); - i != arguments.end(); - ++i) { - args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); - } - } - char* const* Argv() { - return &args_[0]; - } + template + void AddArguments(const ::std::vector& arguments) + { + for (typename ::std::vector::const_iterator i = arguments.begin(); + i != arguments.end(); + ++i) + { + args_.insert(args_.end() - 1, posix::StrDup(i->c_str())); + } + } + char* const* Argv() + { + return &args_[0]; + } - private: - std::vector args_; +private: + std::vector args_; }; // A struct that encompasses the arguments to the child process of a // threadsafe-style death test process. -struct ExecDeathTestArgs { - char* const* argv; // Command-line arguments for the child's call to exec - int close_fd; // File descriptor to close; the read end of a pipe +struct ExecDeathTestArgs +{ + char* const* argv; // Command-line arguments for the child's call to exec + int close_fd; // File descriptor to close; the read end of a pipe }; -# if GTEST_OS_MAC -inline char** GetEnviron() { - // When Google Test is built as a framework on MacOS X, the environ variable - // is unavailable. Apple's documentation (man environ) recommends using - // _NSGetEnviron() instead. - return *_NSGetEnviron(); +#if GTEST_OS_MAC +inline char** GetEnviron() +{ + // When Google Test is built as a framework on MacOS X, the environ variable + // is unavailable. Apple's documentation (man environ) recommends using + // _NSGetEnviron() instead. + return *_NSGetEnviron(); } -# else +#else // Some POSIX platforms expect you to declare environ. extern "C" makes // it reside in the global namespace. extern "C" char** environ; inline char** GetEnviron() { return environ; } -# endif // GTEST_OS_MAC +#endif // GTEST_OS_MAC -# if !GTEST_OS_QNX +#if !GTEST_OS_QNX // The main function for a threadsafe-style death test child process. // This function is called in a clone()-ed process and thus must avoid // any potentially unsafe operations like malloc or libc functions. -static int ExecDeathTestChildMain(void* child_arg) { - ExecDeathTestArgs* const args = static_cast(child_arg); - GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); +static int ExecDeathTestChildMain(void* child_arg) +{ + ExecDeathTestArgs* const args = static_cast(child_arg); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(args->close_fd)); - // We need to execute the test program in the same environment where - // it was originally invoked. Therefore we change to the original - // working directory first. - const char* const original_dir = - UnitTest::GetInstance()->original_working_dir(); - // We can safely call chdir() as it's a direct system call. - if (chdir(original_dir) != 0) { - DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + - GetLastErrnoDescription()); - return EXIT_FAILURE; - } + // We need to execute the test program in the same environment where + // it was originally invoked. Therefore we change to the original + // working directory first. + const char* const original_dir = + UnitTest::GetInstance()->original_working_dir(); + // We can safely call chdir() as it's a direct system call. + if (chdir(original_dir) != 0) + { + DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; + } - // We can safely call execve() as it's a direct system call. We - // cannot use execvp() as it's a libc function and thus potentially - // unsafe. Since execve() doesn't search the PATH, the user must - // invoke the test program via a valid path that contains at least - // one path separator. - execve(args->argv[0], args->argv, GetEnviron()); - DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " + - original_dir + " failed: " + - GetLastErrnoDescription()); - return EXIT_FAILURE; + // We can safely call execve() as it's a direct system call. We + // cannot use execvp() as it's a libc function and thus potentially + // unsafe. Since execve() doesn't search the PATH, the user must + // invoke the test program via a valid path that contains at least + // one path separator. + execve(args->argv[0], args->argv, GetEnviron()); + DeathTestAbort(std::string("execve(") + args->argv[0] + ", ...) in " + + original_dir + " failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; } -# endif // !GTEST_OS_QNX +#endif // !GTEST_OS_QNX // Two utility routines that together determine the direction the stack // grows. @@ -980,16 +1069,18 @@ static int ExecDeathTestChildMain(void* child_arg) { // StackLowerThanAddress into StackGrowsDown, which then doesn't give // correct answer. void StackLowerThanAddress(const void* ptr, bool* result) GTEST_NO_INLINE_; -void StackLowerThanAddress(const void* ptr, bool* result) { - int dummy; - *result = (&dummy < ptr); +void StackLowerThanAddress(const void* ptr, bool* result) +{ + int dummy; + *result = (&dummy < ptr); } -bool StackGrowsDown() { - int dummy; - bool result; - StackLowerThanAddress(&dummy, &result); - return result; +bool StackGrowsDown() +{ + int dummy; + bool result; + StackLowerThanAddress(&dummy, &result); + return result; } // Spawns a child process with the same executable as the current process in @@ -999,151 +1090,153 @@ bool StackGrowsDown() { // fork supports only single-threaded environments, so this function uses // spawn(2) there instead. The function dies with an error message if // anything goes wrong. -static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) { - ExecDeathTestArgs args = { argv, close_fd }; - pid_t child_pid = -1; +static pid_t ExecDeathTestSpawnChild(char* const* argv, int close_fd) +{ + ExecDeathTestArgs args = {argv, close_fd}; + pid_t child_pid = -1; -# if GTEST_OS_QNX - // Obtains the current directory and sets it to be closed in the child - // process. - const int cwd_fd = open(".", O_RDONLY); - GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); - GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); - // We need to execute the test program in the same environment where - // it was originally invoked. Therefore we change to the original - // working directory first. - const char* const original_dir = - UnitTest::GetInstance()->original_working_dir(); - // We can safely call chdir() as it's a direct system call. - if (chdir(original_dir) != 0) { - DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + - GetLastErrnoDescription()); - return EXIT_FAILURE; - } +#if GTEST_OS_QNX + // Obtains the current directory and sets it to be closed in the child + // process. + const int cwd_fd = open(".", O_RDONLY); + GTEST_DEATH_TEST_CHECK_(cwd_fd != -1); + GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(cwd_fd, F_SETFD, FD_CLOEXEC)); + // We need to execute the test program in the same environment where + // it was originally invoked. Therefore we change to the original + // working directory first. + const char* const original_dir = + UnitTest::GetInstance()->original_working_dir(); + // We can safely call chdir() as it's a direct system call. + if (chdir(original_dir) != 0) + { + DeathTestAbort(std::string("chdir(\"") + original_dir + "\") failed: " + + GetLastErrnoDescription()); + return EXIT_FAILURE; + } - int fd_flags; - // Set close_fd to be closed after spawn. - GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); - GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, - fd_flags | FD_CLOEXEC)); - struct inheritance inherit = {0}; - // spawn is a system call. - child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron()); - // Restores the current working directory. - GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); - GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); + int fd_flags; + // Set close_fd to be closed after spawn. + GTEST_DEATH_TEST_CHECK_SYSCALL_(fd_flags = fcntl(close_fd, F_GETFD)); + GTEST_DEATH_TEST_CHECK_SYSCALL_(fcntl(close_fd, F_SETFD, + fd_flags | FD_CLOEXEC)); + struct inheritance inherit = {0}; + // spawn is a system call. + child_pid = spawn(args.argv[0], 0, NULL, &inherit, args.argv, GetEnviron()); + // Restores the current working directory. + GTEST_DEATH_TEST_CHECK_(fchdir(cwd_fd) != -1); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(cwd_fd)); -# else // GTEST_OS_QNX -# if GTEST_OS_LINUX - // When a SIGPROF signal is received while fork() or clone() are executing, - // the process may hang. To avoid this, we ignore SIGPROF here and re-enable - // it after the call to fork()/clone() is complete. - struct sigaction saved_sigprof_action; - struct sigaction ignore_sigprof_action; - memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); - sigemptyset(&ignore_sigprof_action.sa_mask); - ignore_sigprof_action.sa_handler = SIG_IGN; - GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( - SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); -# endif // GTEST_OS_LINUX +#else // GTEST_OS_QNX +#if GTEST_OS_LINUX + // When a SIGPROF signal is received while fork() or clone() are executing, + // the process may hang. To avoid this, we ignore SIGPROF here and re-enable + // it after the call to fork()/clone() is complete. + struct sigaction saved_sigprof_action; + struct sigaction ignore_sigprof_action; + memset(&ignore_sigprof_action, 0, sizeof(ignore_sigprof_action)); + sigemptyset(&ignore_sigprof_action.sa_mask); + ignore_sigprof_action.sa_handler = SIG_IGN; + GTEST_DEATH_TEST_CHECK_SYSCALL_(sigaction( + SIGPROF, &ignore_sigprof_action, &saved_sigprof_action)); +#endif // GTEST_OS_LINUX -# if GTEST_HAS_CLONE - const bool use_fork = GTEST_FLAG(death_test_use_fork); +#if GTEST_HAS_CLONE + const bool use_fork = GTEST_FLAG(death_test_use_fork); - if (!use_fork) { - static const bool stack_grows_down = StackGrowsDown(); - const size_t stack_size = getpagesize(); - // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. - void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, - MAP_ANON | MAP_PRIVATE, -1, 0); - GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); + if (!use_fork) + { + static const bool stack_grows_down = StackGrowsDown(); + const size_t stack_size = getpagesize(); + // MMAP_ANONYMOUS is not defined on Mac, so we use MAP_ANON instead. + void* const stack = mmap(NULL, stack_size, PROT_READ | PROT_WRITE, + MAP_ANON | MAP_PRIVATE, -1, 0); + GTEST_DEATH_TEST_CHECK_(stack != MAP_FAILED); - // Maximum stack alignment in bytes: For a downward-growing stack, this - // amount is subtracted from size of the stack space to get an address - // that is within the stack space and is aligned on all systems we care - // about. As far as I know there is no ABI with stack alignment greater - // than 64. We assume stack and stack_size already have alignment of - // kMaxStackAlignment. - const size_t kMaxStackAlignment = 64; - void* const stack_top = - static_cast(stack) + - (stack_grows_down ? stack_size - kMaxStackAlignment : 0); - GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment && - reinterpret_cast(stack_top) % kMaxStackAlignment == 0); + // Maximum stack alignment in bytes: For a downward-growing stack, this + // amount is subtracted from size of the stack space to get an address + // that is within the stack space and is aligned on all systems we care + // about. As far as I know there is no ABI with stack alignment greater + // than 64. We assume stack and stack_size already have alignment of + // kMaxStackAlignment. + const size_t kMaxStackAlignment = 64; + void* const stack_top = + static_cast(stack) + + (stack_grows_down ? stack_size - kMaxStackAlignment : 0); + GTEST_DEATH_TEST_CHECK_(stack_size > kMaxStackAlignment && + reinterpret_cast(stack_top) % kMaxStackAlignment == 0); - child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); + child_pid = clone(&ExecDeathTestChildMain, stack_top, SIGCHLD, &args); - GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); - } -# else - const bool use_fork = true; -# endif // GTEST_HAS_CLONE + GTEST_DEATH_TEST_CHECK_(munmap(stack, stack_size) != -1); + } +#else + const bool use_fork = true; +#endif // GTEST_HAS_CLONE - if (use_fork && (child_pid = fork()) == 0) { - ExecDeathTestChildMain(&args); - _exit(0); - } -# endif // GTEST_OS_QNX -# if GTEST_OS_LINUX - GTEST_DEATH_TEST_CHECK_SYSCALL_( - sigaction(SIGPROF, &saved_sigprof_action, NULL)); -# endif // GTEST_OS_LINUX + if (use_fork && (child_pid = fork()) == 0) + { + ExecDeathTestChildMain(&args); + _exit(0); + } +#endif // GTEST_OS_QNX +#if GTEST_OS_LINUX + GTEST_DEATH_TEST_CHECK_SYSCALL_( + sigaction(SIGPROF, &saved_sigprof_action, NULL)); +#endif // GTEST_OS_LINUX - GTEST_DEATH_TEST_CHECK_(child_pid != -1); - return child_pid; + GTEST_DEATH_TEST_CHECK_(child_pid != -1); + return child_pid; } // The AssumeRole process for a fork-and-exec death test. It re-executes the // main program from the beginning, setting the --gtest_filter // and --gtest_internal_run_death_test flags to cause only the current // death test to be re-run. -DeathTest::TestRole ExecDeathTest::AssumeRole() { - const UnitTestImpl* const impl = GetUnitTestImpl(); - const InternalRunDeathTestFlag* const flag = - impl->internal_run_death_test_flag(); - const TestInfo* const info = impl->current_test_info(); - const int death_test_index = info->result()->death_test_count(); +DeathTest::TestRole ExecDeathTest::AssumeRole() +{ + const UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const TestInfo* const info = impl->current_test_info(); + const int death_test_index = info->result()->death_test_count(); - if (flag != NULL) { - set_write_fd(flag->write_fd()); - return EXECUTE_TEST; - } + if (flag != NULL) + { + set_write_fd(flag->write_fd()); + return EXECUTE_TEST; + } - int pipe_fd[2]; - GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); - // Clear the close-on-exec flag on the write end of the pipe, lest - // it be closed when the child process does an exec: - GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); + int pipe_fd[2]; + GTEST_DEATH_TEST_CHECK_(pipe(pipe_fd) != -1); + // Clear the close-on-exec flag on the write end of the pipe, lest + // it be closed when the child process does an exec: + GTEST_DEATH_TEST_CHECK_(fcntl(pipe_fd[1], F_SETFD, 0) != -1); - const std::string filter_flag = - std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" - + info->test_case_name() + "." + info->name(); - const std::string internal_flag = - std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" - + file_ + "|" + StreamableToString(line_) + "|" - + StreamableToString(death_test_index) + "|" - + StreamableToString(pipe_fd[1]); - Arguments args; - args.AddArguments(GetArgvsForDeathTestChildProcess()); - args.AddArgument(filter_flag.c_str()); - args.AddArgument(internal_flag.c_str()); + const std::string filter_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kFilterFlag + "=" + info->test_case_name() + "." + info->name(); + const std::string internal_flag = + std::string("--") + GTEST_FLAG_PREFIX_ + kInternalRunDeathTestFlag + "=" + file_ + "|" + StreamableToString(line_) + "|" + StreamableToString(death_test_index) + "|" + StreamableToString(pipe_fd[1]); + Arguments args; + args.AddArguments(GetArgvsForDeathTestChildProcess()); + args.AddArgument(filter_flag.c_str()); + args.AddArgument(internal_flag.c_str()); - DeathTest::set_last_death_test_message(""); + DeathTest::set_last_death_test_message(""); - CaptureStderr(); - // See the comment in NoExecDeathTest::AssumeRole for why the next line - // is necessary. - FlushInfoLog(); + CaptureStderr(); + // See the comment in NoExecDeathTest::AssumeRole for why the next line + // is necessary. + FlushInfoLog(); - const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); - GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); - set_child_pid(child_pid); - set_read_fd(pipe_fd[0]); - set_spawned(true); - return OVERSEE_TEST; + const pid_t child_pid = ExecDeathTestSpawnChild(args.Argv(), pipe_fd[0]); + GTEST_DEATH_TEST_CHECK_SYSCALL_(close(pipe_fd[1])); + set_child_pid(child_pid); + set_read_fd(pipe_fd[0]); + set_spawned(true); + return OVERSEE_TEST; } -# endif // !GTEST_OS_WINDOWS +#endif // !GTEST_OS_WINDOWS // Creates a concrete DeathTest-derived class that depends on the // --gtest_death_test_style flag, and sets the pointer pointed to @@ -1151,190 +1244,200 @@ DeathTest::TestRole ExecDeathTest::AssumeRole() { // skipped, sets that pointer to NULL. Returns true, unless the // flag is set to an invalid value. bool DefaultDeathTestFactory::Create(const char* statement, const RE* regex, - const char* file, int line, - DeathTest** test) { - UnitTestImpl* const impl = GetUnitTestImpl(); - const InternalRunDeathTestFlag* const flag = - impl->internal_run_death_test_flag(); - const int death_test_index = impl->current_test_info() - ->increment_death_test_count(); + const char* file, int line, + DeathTest** test) +{ + UnitTestImpl* const impl = GetUnitTestImpl(); + const InternalRunDeathTestFlag* const flag = + impl->internal_run_death_test_flag(); + const int death_test_index = impl->current_test_info() + ->increment_death_test_count(); - if (flag != NULL) { - if (death_test_index > flag->index()) { - DeathTest::set_last_death_test_message( - "Death test count (" + StreamableToString(death_test_index) - + ") somehow exceeded expected maximum (" - + StreamableToString(flag->index()) + ")"); - return false; - } + if (flag != NULL) + { + if (death_test_index > flag->index()) + { + DeathTest::set_last_death_test_message( + "Death test count (" + StreamableToString(death_test_index) + ") somehow exceeded expected maximum (" + StreamableToString(flag->index()) + ")"); + return false; + } - if (!(flag->file() == file && flag->line() == line && - flag->index() == death_test_index)) { - *test = NULL; - return true; - } - } + if (!(flag->file() == file && flag->line() == line && + flag->index() == death_test_index)) + { + *test = NULL; + return true; + } + } -# if GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS - if (GTEST_FLAG(death_test_style) == "threadsafe" || - GTEST_FLAG(death_test_style) == "fast") { - *test = new WindowsDeathTest(statement, regex, file, line); - } + if (GTEST_FLAG(death_test_style) == "threadsafe" || + GTEST_FLAG(death_test_style) == "fast") + { + *test = new WindowsDeathTest(statement, regex, file, line); + } -# else +#else - if (GTEST_FLAG(death_test_style) == "threadsafe") { - *test = new ExecDeathTest(statement, regex, file, line); - } else if (GTEST_FLAG(death_test_style) == "fast") { - *test = new NoExecDeathTest(statement, regex); - } + if (GTEST_FLAG(death_test_style) == "threadsafe") + { + *test = new ExecDeathTest(statement, regex, file, line); + } + else if (GTEST_FLAG(death_test_style) == "fast") + { + *test = new NoExecDeathTest(statement, regex); + } -# endif // GTEST_OS_WINDOWS +#endif // GTEST_OS_WINDOWS - else { // NOLINT - this is more readable than unbalanced brackets inside #if. - DeathTest::set_last_death_test_message( - "Unknown death test style \"" + GTEST_FLAG(death_test_style) - + "\" encountered"); - return false; - } + else + { // NOLINT - this is more readable than unbalanced brackets inside #if. + DeathTest::set_last_death_test_message( + "Unknown death test style \"" + GTEST_FLAG(death_test_style) + "\" encountered"); + return false; + } - return true; + return true; } // Splits a given string on a given delimiter, populating a given // vector with the fields. GTEST_HAS_DEATH_TEST implies that we have // ::std::string, so we can use it here. static void SplitString(const ::std::string& str, char delimiter, - ::std::vector< ::std::string>* dest) { - ::std::vector< ::std::string> parsed; - ::std::string::size_type pos = 0; - while (::testing::internal::AlwaysTrue()) { - const ::std::string::size_type colon = str.find(delimiter, pos); - if (colon == ::std::string::npos) { - parsed.push_back(str.substr(pos)); - break; - } else { - parsed.push_back(str.substr(pos, colon - pos)); - pos = colon + 1; - } - } - dest->swap(parsed); + ::std::vector< ::std::string>* dest) +{ + ::std::vector< ::std::string> parsed; + ::std::string::size_type pos = 0; + while (::testing::internal::AlwaysTrue()) + { + const ::std::string::size_type colon = str.find(delimiter, pos); + if (colon == ::std::string::npos) + { + parsed.push_back(str.substr(pos)); + break; + } + else + { + parsed.push_back(str.substr(pos, colon - pos)); + pos = colon + 1; + } + } + dest->swap(parsed); } -# if GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // Recreates the pipe and event handles from the provided parameters, // signals the event, and returns a file descriptor wrapped around the pipe // handle. This function is called in the child process only. int GetStatusFileDescriptor(unsigned int parent_process_id, - size_t write_handle_as_size_t, - size_t event_handle_as_size_t) { - AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, - FALSE, // Non-inheritable. - parent_process_id)); - if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) { - DeathTestAbort("Unable to open parent process " + - StreamableToString(parent_process_id)); - } + size_t write_handle_as_size_t, + size_t event_handle_as_size_t) +{ + AutoHandle parent_process_handle(::OpenProcess(PROCESS_DUP_HANDLE, + FALSE, // Non-inheritable. + parent_process_id)); + if (parent_process_handle.Get() == INVALID_HANDLE_VALUE) + { + DeathTestAbort("Unable to open parent process " + + StreamableToString(parent_process_id)); + } - // TODO(vladl@google.com): Replace the following check with a - // compile-time assertion when available. - GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); + // TODO(vladl@google.com): Replace the following check with a + // compile-time assertion when available. + GTEST_CHECK_(sizeof(HANDLE) <= sizeof(size_t)); - const HANDLE write_handle = - reinterpret_cast(write_handle_as_size_t); - HANDLE dup_write_handle; + const HANDLE write_handle = + reinterpret_cast(write_handle_as_size_t); + HANDLE dup_write_handle; - // The newly initialized handle is accessible only in in the parent - // process. To obtain one accessible within the child, we need to use - // DuplicateHandle. - if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, - ::GetCurrentProcess(), &dup_write_handle, - 0x0, // Requested privileges ignored since - // DUPLICATE_SAME_ACCESS is used. - FALSE, // Request non-inheritable handler. - DUPLICATE_SAME_ACCESS)) { - DeathTestAbort("Unable to duplicate the pipe handle " + - StreamableToString(write_handle_as_size_t) + - " from the parent process " + - StreamableToString(parent_process_id)); - } + // The newly initialized handle is accessible only in in the parent + // process. To obtain one accessible within the child, we need to use + // DuplicateHandle. + if (!::DuplicateHandle(parent_process_handle.Get(), write_handle, + ::GetCurrentProcess(), &dup_write_handle, + 0x0, // Requested privileges ignored since + // DUPLICATE_SAME_ACCESS is used. + FALSE, // Request non-inheritable handler. + DUPLICATE_SAME_ACCESS)) + { + DeathTestAbort("Unable to duplicate the pipe handle " + + StreamableToString(write_handle_as_size_t) + + " from the parent process " + + StreamableToString(parent_process_id)); + } - const HANDLE event_handle = reinterpret_cast(event_handle_as_size_t); - HANDLE dup_event_handle; + const HANDLE event_handle = reinterpret_cast(event_handle_as_size_t); + HANDLE dup_event_handle; - if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, - ::GetCurrentProcess(), &dup_event_handle, - 0x0, - FALSE, - DUPLICATE_SAME_ACCESS)) { - DeathTestAbort("Unable to duplicate the event handle " + - StreamableToString(event_handle_as_size_t) + - " from the parent process " + - StreamableToString(parent_process_id)); - } + if (!::DuplicateHandle(parent_process_handle.Get(), event_handle, + ::GetCurrentProcess(), &dup_event_handle, + 0x0, + FALSE, + DUPLICATE_SAME_ACCESS)) + { + DeathTestAbort("Unable to duplicate the event handle " + + StreamableToString(event_handle_as_size_t) + + " from the parent process " + + StreamableToString(parent_process_id)); + } - const int write_fd = - ::_open_osfhandle(reinterpret_cast(dup_write_handle), O_APPEND); - if (write_fd == -1) { - DeathTestAbort("Unable to convert pipe handle " + - StreamableToString(write_handle_as_size_t) + - " to a file descriptor"); - } + const int write_fd = + ::_open_osfhandle(reinterpret_cast(dup_write_handle), O_APPEND); + if (write_fd == -1) + { + DeathTestAbort("Unable to convert pipe handle " + + StreamableToString(write_handle_as_size_t) + + " to a file descriptor"); + } - // Signals the parent that the write end of the pipe has been acquired - // so the parent can release its own write end. - ::SetEvent(dup_event_handle); + // Signals the parent that the write end of the pipe has been acquired + // so the parent can release its own write end. + ::SetEvent(dup_event_handle); - return write_fd; + return write_fd; } -# endif // GTEST_OS_WINDOWS +#endif // GTEST_OS_WINDOWS // Returns a newly created InternalRunDeathTestFlag object with fields // initialized from the GTEST_FLAG(internal_run_death_test) flag if // the flag is specified; otherwise returns NULL. -InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() { - if (GTEST_FLAG(internal_run_death_test) == "") return NULL; +InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag() +{ + if (GTEST_FLAG(internal_run_death_test) == "") return NULL; - // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we - // can use it here. - int line = -1; - int index = -1; - ::std::vector< ::std::string> fields; - SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); - int write_fd = -1; + // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we + // can use it here. + int line = -1; + int index = -1; + ::std::vector< ::std::string> fields; + SplitString(GTEST_FLAG(internal_run_death_test).c_str(), '|', &fields); + int write_fd = -1; -# if GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS - unsigned int parent_process_id = 0; - size_t write_handle_as_size_t = 0; - size_t event_handle_as_size_t = 0; + unsigned int parent_process_id = 0; + size_t write_handle_as_size_t = 0; + size_t event_handle_as_size_t = 0; - if (fields.size() != 6 - || !ParseNaturalNumber(fields[1], &line) - || !ParseNaturalNumber(fields[2], &index) - || !ParseNaturalNumber(fields[3], &parent_process_id) - || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) - || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) { - DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + - GTEST_FLAG(internal_run_death_test)); - } - write_fd = GetStatusFileDescriptor(parent_process_id, - write_handle_as_size_t, - event_handle_as_size_t); -# else + if (fields.size() != 6 || !ParseNaturalNumber(fields[1], &line) || !ParseNaturalNumber(fields[2], &index) || !ParseNaturalNumber(fields[3], &parent_process_id) || !ParseNaturalNumber(fields[4], &write_handle_as_size_t) || !ParseNaturalNumber(fields[5], &event_handle_as_size_t)) + { + DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + + GTEST_FLAG(internal_run_death_test)); + } + write_fd = GetStatusFileDescriptor(parent_process_id, + write_handle_as_size_t, + event_handle_as_size_t); +#else - if (fields.size() != 4 - || !ParseNaturalNumber(fields[1], &line) - || !ParseNaturalNumber(fields[2], &index) - || !ParseNaturalNumber(fields[3], &write_fd)) { - DeathTestAbort("Bad --gtest_internal_run_death_test flag: " - + GTEST_FLAG(internal_run_death_test)); - } + if (fields.size() != 4 || !ParseNaturalNumber(fields[1], &line) || !ParseNaturalNumber(fields[2], &index) || !ParseNaturalNumber(fields[3], &write_fd)) + { + DeathTestAbort("Bad --gtest_internal_run_death_test flag: " + GTEST_FLAG(internal_run_death_test)); + } -# endif // GTEST_OS_WINDOWS +#endif // GTEST_OS_WINDOWS - return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); + return new InternalRunDeathTestFlag(fields[0], line, index, write_fd); } } // namespace internal diff --git a/test/gtest-1.7.0/src/gtest-filepath.cc b/test/gtest-1.7.0/src/gtest-filepath.cc index 6be58b6fc..8afcba723 100644 --- a/test/gtest-1.7.0/src/gtest-filepath.cc +++ b/test/gtest-1.7.0/src/gtest-filepath.cc @@ -36,33 +36,34 @@ #include #if GTEST_OS_WINDOWS_MOBILE -# include +#include #elif GTEST_OS_WINDOWS -# include -# include +#include +#include #elif GTEST_OS_SYMBIAN // Symbian OpenC has PATH_MAX in sys/syslimits.h -# include +#include #else -# include -# include // Some Linux distributions define PATH_MAX here. -#endif // GTEST_OS_WINDOWS_MOBILE +#include +#include // Some Linux distributions define PATH_MAX here. +#endif // GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_WINDOWS -# define GTEST_PATH_MAX_ _MAX_PATH +#define GTEST_PATH_MAX_ _MAX_PATH #elif defined(PATH_MAX) -# define GTEST_PATH_MAX_ PATH_MAX +#define GTEST_PATH_MAX_ PATH_MAX #elif defined(_XOPEN_PATH_MAX) -# define GTEST_PATH_MAX_ _XOPEN_PATH_MAX +#define GTEST_PATH_MAX_ _XOPEN_PATH_MAX #else -# define GTEST_PATH_MAX_ _POSIX_PATH_MAX +#define GTEST_PATH_MAX_ _POSIX_PATH_MAX #endif // GTEST_OS_WINDOWS #include "gtest/internal/gtest-string.h" -namespace testing { -namespace internal { - +namespace testing +{ +namespace internal +{ #if GTEST_OS_WINDOWS // On Windows, '\\' is the standard path separator, but many tools and the // Windows API also accept '/' as an alternate path separator. Unless otherwise @@ -72,16 +73,16 @@ const char kPathSeparator = '\\'; const char kAlternatePathSeparator = '/'; const char kPathSeparatorString[] = "\\"; const char kAlternatePathSeparatorString[] = "/"; -# if GTEST_OS_WINDOWS_MOBILE +#if GTEST_OS_WINDOWS_MOBILE // Windows CE doesn't have a current directory. You should not use // the current directory in tests on Windows CE, but this at least // provides a reasonable fallback. const char kCurrentDirectoryString[] = "\\"; // Windows CE doesn't define INVALID_FILE_ATTRIBUTES const DWORD kInvalidFileAttributes = 0xffffffff; -# else +#else const char kCurrentDirectoryString[] = ".\\"; -# endif // GTEST_OS_WINDOWS_MOBILE +#endif // GTEST_OS_WINDOWS_MOBILE #else const char kPathSeparator = '/'; const char kPathSeparatorString[] = "/"; @@ -89,26 +90,28 @@ const char kCurrentDirectoryString[] = "./"; #endif // GTEST_OS_WINDOWS // Returns whether the given character is a valid path separator. -static bool IsPathSeparator(char c) { +static bool IsPathSeparator(char c) +{ #if GTEST_HAS_ALT_PATH_SEP_ - return (c == kPathSeparator) || (c == kAlternatePathSeparator); + return (c == kPathSeparator) || (c == kAlternatePathSeparator); #else - return c == kPathSeparator; + return c == kPathSeparator; #endif } // Returns the current working directory, or "" if unsuccessful. -FilePath FilePath::GetCurrentDir() { +FilePath FilePath::GetCurrentDir() +{ #if GTEST_OS_WINDOWS_MOBILE - // Windows CE doesn't have a current directory, so we just return - // something reasonable. - return FilePath(kCurrentDirectoryString); + // Windows CE doesn't have a current directory, so we just return + // something reasonable. + return FilePath(kCurrentDirectoryString); #elif GTEST_OS_WINDOWS - char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; - return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); + char cwd[GTEST_PATH_MAX_ + 1] = {'\0'}; + return FilePath(_getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); #else - char cwd[GTEST_PATH_MAX_ + 1] = { '\0' }; - return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); + char cwd[GTEST_PATH_MAX_ + 1] = {'\0'}; + return FilePath(getcwd(cwd, sizeof(cwd)) == NULL ? "" : cwd); #endif // GTEST_OS_WINDOWS_MOBILE } @@ -116,29 +119,33 @@ FilePath FilePath::GetCurrentDir() { // Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns // FilePath("dir/file"). If a case-insensitive extension is not // found, returns a copy of the original FilePath. -FilePath FilePath::RemoveExtension(const char* extension) const { - const std::string dot_extension = std::string(".") + extension; - if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) { - return FilePath(pathname_.substr( - 0, pathname_.length() - dot_extension.length())); - } - return *this; +FilePath FilePath::RemoveExtension(const char* extension) const +{ + const std::string dot_extension = std::string(".") + extension; + if (String::EndsWithCaseInsensitive(pathname_, dot_extension)) + { + return FilePath(pathname_.substr( + 0, pathname_.length() - dot_extension.length())); + } + return *this; } // Returns a pointer to the last occurence of a valid path separator in // the FilePath. On Windows, for example, both '/' and '\' are valid path // separators. Returns NULL if no path separator was found. -const char* FilePath::FindLastPathSeparator() const { - const char* const last_sep = strrchr(c_str(), kPathSeparator); +const char* FilePath::FindLastPathSeparator() const +{ + const char* const last_sep = strrchr(c_str(), kPathSeparator); #if GTEST_HAS_ALT_PATH_SEP_ - const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); - // Comparing two pointers of which only one is NULL is undefined. - if (last_alt_sep != NULL && - (last_sep == NULL || last_alt_sep > last_sep)) { - return last_alt_sep; - } + const char* const last_alt_sep = strrchr(c_str(), kAlternatePathSeparator); + // Comparing two pointers of which only one is NULL is undefined. + if (last_alt_sep != NULL && + (last_sep == NULL || last_alt_sep > last_sep)) + { + return last_alt_sep; + } #endif - return last_sep; + return last_sep; } // Returns a copy of the FilePath with the directory part removed. @@ -147,9 +154,10 @@ const char* FilePath::FindLastPathSeparator() const { // the FilePath unmodified. If there is no file part ("just_a_dir/") it // returns an empty FilePath (""). // On Windows platform, '\' is the path separator, otherwise it is '/'. -FilePath FilePath::RemoveDirectoryName() const { - const char* const last_sep = FindLastPathSeparator(); - return last_sep ? FilePath(last_sep + 1) : *this; +FilePath FilePath::RemoveDirectoryName() const +{ + const char* const last_sep = FindLastPathSeparator(); + return last_sep ? FilePath(last_sep + 1) : *this; } // RemoveFileName returns the directory path with the filename removed. @@ -158,15 +166,19 @@ FilePath FilePath::RemoveDirectoryName() const { // FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does // not have a file, like "just/a/dir/", it returns the FilePath unmodified. // On Windows platform, '\' is the path separator, otherwise it is '/'. -FilePath FilePath::RemoveFileName() const { - const char* const last_sep = FindLastPathSeparator(); - std::string dir; - if (last_sep) { - dir = std::string(c_str(), last_sep + 1 - c_str()); - } else { - dir = kCurrentDirectoryString; - } - return FilePath(dir); +FilePath FilePath::RemoveFileName() const +{ + const char* const last_sep = FindLastPathSeparator(); + std::string dir; + if (last_sep) + { + dir = std::string(c_str(), last_sep + 1 - c_str()); + } + else + { + dir = kCurrentDirectoryString; + } + return FilePath(dir); } // Helper functions for naming files in a directory for xml output. @@ -176,97 +188,105 @@ FilePath FilePath::RemoveFileName() const { // than zero (e.g., 12), returns "dir/test_12.xml". // On Windows platform, uses \ as the separator rather than /. FilePath FilePath::MakeFileName(const FilePath& directory, - const FilePath& base_name, - int number, - const char* extension) { - std::string file; - if (number == 0) { - file = base_name.string() + "." + extension; - } else { - file = base_name.string() + "_" + StreamableToString(number) - + "." + extension; - } - return ConcatPaths(directory, FilePath(file)); + const FilePath& base_name, + int number, + const char* extension) +{ + std::string file; + if (number == 0) + { + file = base_name.string() + "." + extension; + } + else + { + file = base_name.string() + "_" + StreamableToString(number) + "." + extension; + } + return ConcatPaths(directory, FilePath(file)); } // Given directory = "dir", relative_path = "test.xml", returns "dir/test.xml". // On Windows, uses \ as the separator rather than /. FilePath FilePath::ConcatPaths(const FilePath& directory, - const FilePath& relative_path) { - if (directory.IsEmpty()) - return relative_path; - const FilePath dir(directory.RemoveTrailingPathSeparator()); - return FilePath(dir.string() + kPathSeparator + relative_path.string()); + const FilePath& relative_path) +{ + if (directory.IsEmpty()) + return relative_path; + const FilePath dir(directory.RemoveTrailingPathSeparator()); + return FilePath(dir.string() + kPathSeparator + relative_path.string()); } // Returns true if pathname describes something findable in the file-system, // either a file, directory, or whatever. -bool FilePath::FileOrDirectoryExists() const { +bool FilePath::FileOrDirectoryExists() const +{ #if GTEST_OS_WINDOWS_MOBILE - LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); - const DWORD attributes = GetFileAttributes(unicode); - delete [] unicode; - return attributes != kInvalidFileAttributes; + LPCWSTR unicode = String::AnsiToUtf16(pathname_.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete[] unicode; + return attributes != kInvalidFileAttributes; #else - posix::StatStruct file_stat; - return posix::Stat(pathname_.c_str(), &file_stat) == 0; + posix::StatStruct file_stat; + return posix::Stat(pathname_.c_str(), &file_stat) == 0; #endif // GTEST_OS_WINDOWS_MOBILE } // Returns true if pathname describes a directory in the file-system // that exists. -bool FilePath::DirectoryExists() const { - bool result = false; +bool FilePath::DirectoryExists() const +{ + bool result = false; #if GTEST_OS_WINDOWS - // Don't strip off trailing separator if path is a root directory on - // Windows (like "C:\\"). - const FilePath& path(IsRootDirectory() ? *this : - RemoveTrailingPathSeparator()); + // Don't strip off trailing separator if path is a root directory on + // Windows (like "C:\\"). + const FilePath& path(IsRootDirectory() ? *this : RemoveTrailingPathSeparator()); #else - const FilePath& path(*this); + const FilePath& path(*this); #endif #if GTEST_OS_WINDOWS_MOBILE - LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); - const DWORD attributes = GetFileAttributes(unicode); - delete [] unicode; - if ((attributes != kInvalidFileAttributes) && - (attributes & FILE_ATTRIBUTE_DIRECTORY)) { - result = true; - } + LPCWSTR unicode = String::AnsiToUtf16(path.c_str()); + const DWORD attributes = GetFileAttributes(unicode); + delete[] unicode; + if ((attributes != kInvalidFileAttributes) && + (attributes & FILE_ATTRIBUTE_DIRECTORY)) + { + result = true; + } #else - posix::StatStruct file_stat; - result = posix::Stat(path.c_str(), &file_stat) == 0 && - posix::IsDir(file_stat); + posix::StatStruct file_stat; + result = posix::Stat(path.c_str(), &file_stat) == 0 && + posix::IsDir(file_stat); #endif // GTEST_OS_WINDOWS_MOBILE - return result; + return result; } // Returns true if pathname describes a root directory. (Windows has one // root directory per disk drive.) -bool FilePath::IsRootDirectory() const { +bool FilePath::IsRootDirectory() const +{ #if GTEST_OS_WINDOWS - // TODO(wan@google.com): on Windows a network share like - // \\server\share can be a root directory, although it cannot be the - // current directory. Handle this properly. - return pathname_.length() == 3 && IsAbsolutePath(); + // TODO(wan@google.com): on Windows a network share like + // \\server\share can be a root directory, although it cannot be the + // current directory. Handle this properly. + return pathname_.length() == 3 && IsAbsolutePath(); #else - return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); + return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); #endif } // Returns true if pathname describes an absolute path. -bool FilePath::IsAbsolutePath() const { - const char* const name = pathname_.c_str(); +bool FilePath::IsAbsolutePath() const +{ + const char* const name = pathname_.c_str(); #if GTEST_OS_WINDOWS - return pathname_.length() >= 3 && - ((name[0] >= 'a' && name[0] <= 'z') || - (name[0] >= 'A' && name[0] <= 'Z')) && - name[1] == ':' && - IsPathSeparator(name[2]); + return pathname_.length() >= 3 && + ((name[0] >= 'a' && name[0] <= 'z') || + (name[0] >= 'A' && name[0] <= 'Z')) && + name[1] == ':' && + IsPathSeparator(name[2]); #else - return IsPathSeparator(name[0]); + return IsPathSeparator(name[0]); #endif } @@ -279,103 +299,119 @@ bool FilePath::IsAbsolutePath() const { // There could be a race condition if two or more processes are calling this // function at the same time -- they could both pick the same filename. FilePath FilePath::GenerateUniqueFileName(const FilePath& directory, - const FilePath& base_name, - const char* extension) { - FilePath full_pathname; - int number = 0; - do { - full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); - } while (full_pathname.FileOrDirectoryExists()); - return full_pathname; + const FilePath& base_name, + const char* extension) +{ + FilePath full_pathname; + int number = 0; + do + { + full_pathname.Set(MakeFileName(directory, base_name, number++, extension)); + } while (full_pathname.FileOrDirectoryExists()); + return full_pathname; } // Returns true if FilePath ends with a path separator, which indicates that // it is intended to represent a directory. Returns false otherwise. // This does NOT check that a directory (or file) actually exists. -bool FilePath::IsDirectory() const { - return !pathname_.empty() && - IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); +bool FilePath::IsDirectory() const +{ + return !pathname_.empty() && + IsPathSeparator(pathname_.c_str()[pathname_.length() - 1]); } // Create directories so that path exists. Returns true if successful or if // the directories already exist; returns false if unable to create directories // for any reason. -bool FilePath::CreateDirectoriesRecursively() const { - if (!this->IsDirectory()) { - return false; - } +bool FilePath::CreateDirectoriesRecursively() const +{ + if (!this->IsDirectory()) + { + return false; + } - if (pathname_.length() == 0 || this->DirectoryExists()) { - return true; - } + if (pathname_.length() == 0 || this->DirectoryExists()) + { + return true; + } - const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); - return parent.CreateDirectoriesRecursively() && this->CreateFolder(); + const FilePath parent(this->RemoveTrailingPathSeparator().RemoveFileName()); + return parent.CreateDirectoriesRecursively() && this->CreateFolder(); } // Create the directory so that path exists. Returns true if successful or // if the directory already exists; returns false if unable to create the // directory for any reason, including if the parent directory does not // exist. Not named "CreateDirectory" because that's a macro on Windows. -bool FilePath::CreateFolder() const { +bool FilePath::CreateFolder() const +{ #if GTEST_OS_WINDOWS_MOBILE - FilePath removed_sep(this->RemoveTrailingPathSeparator()); - LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); - int result = CreateDirectory(unicode, NULL) ? 0 : -1; - delete [] unicode; + FilePath removed_sep(this->RemoveTrailingPathSeparator()); + LPCWSTR unicode = String::AnsiToUtf16(removed_sep.c_str()); + int result = CreateDirectory(unicode, NULL) ? 0 : -1; + delete[] unicode; #elif GTEST_OS_WINDOWS - int result = _mkdir(pathname_.c_str()); + int result = _mkdir(pathname_.c_str()); #else - int result = mkdir(pathname_.c_str(), 0777); + int result = mkdir(pathname_.c_str(), 0777); #endif // GTEST_OS_WINDOWS_MOBILE - if (result == -1) { - return this->DirectoryExists(); // An error is OK if the directory exists. - } - return true; // No error. + if (result == -1) + { + return this->DirectoryExists(); // An error is OK if the directory exists. + } + return true; // No error. } // If input name has a trailing separator character, remove it and return the // name, otherwise return the name string unmodified. // On Windows platform, uses \ as the separator, other platforms use /. -FilePath FilePath::RemoveTrailingPathSeparator() const { - return IsDirectory() - ? FilePath(pathname_.substr(0, pathname_.length() - 1)) - : *this; +FilePath FilePath::RemoveTrailingPathSeparator() const +{ + return IsDirectory() + ? FilePath(pathname_.substr(0, pathname_.length() - 1)) + : *this; } // Removes any redundant separators that might be in the pathname. // For example, "bar///foo" becomes "bar/foo". Does not eliminate other // redundancies that might be in a pathname involving "." or "..". // TODO(wan@google.com): handle Windows network shares (e.g. \\server\share). -void FilePath::Normalize() { - if (pathname_.c_str() == NULL) { - pathname_ = ""; - return; - } - const char* src = pathname_.c_str(); - char* const dest = new char[pathname_.length() + 1]; - char* dest_ptr = dest; - memset(dest_ptr, 0, pathname_.length() + 1); +void FilePath::Normalize() +{ + if (pathname_.c_str() == NULL) + { + pathname_ = ""; + return; + } + const char* src = pathname_.c_str(); + char* const dest = new char[pathname_.length() + 1]; + char* dest_ptr = dest; + memset(dest_ptr, 0, pathname_.length() + 1); - while (*src != '\0') { - *dest_ptr = *src; - if (!IsPathSeparator(*src)) { - src++; - } else { + while (*src != '\0') + { + *dest_ptr = *src; + if (!IsPathSeparator(*src)) + { + src++; + } + else + { #if GTEST_HAS_ALT_PATH_SEP_ - if (*dest_ptr == kAlternatePathSeparator) { - *dest_ptr = kPathSeparator; - } + if (*dest_ptr == kAlternatePathSeparator) + { + *dest_ptr = kPathSeparator; + } #endif - while (IsPathSeparator(*src)) - src++; - } - dest_ptr++; - } - *dest_ptr = '\0'; - pathname_ = dest; - delete[] dest; + while (IsPathSeparator(*src)) + src++; + } + dest_ptr++; + } + *dest_ptr = '\0'; + pathname_ = dest; + delete[] dest; } } // namespace internal diff --git a/test/gtest-1.7.0/src/gtest-internal-inl.h b/test/gtest-1.7.0/src/gtest-internal-inl.h index 35df303cc..ec2a6717d 100644 --- a/test/gtest-1.7.0/src/gtest-internal-inl.h +++ b/test/gtest-1.7.0/src/gtest-internal-inl.h @@ -41,12 +41,12 @@ // part of Google Test's implementation; otherwise it's undefined. #if !GTEST_IMPLEMENTATION_ // A user is trying to include this from his code - just say no. -# error "gtest-internal-inl.h is part of Google Test's internal implementation." -# error "It must not be included except by Google Test itself." +#error "gtest-internal-inl.h is part of Google Test's internal implementation." +#error "It must not be included except by Google Test itself." #endif // GTEST_IMPLEMENTATION_ #ifndef _WIN32_WCE -# include +#include #endif // !_WIN32_WCE #include #include // For strtoll/_strtoul64/malloc/free. @@ -59,19 +59,19 @@ #include "gtest/internal/gtest-port.h" #if GTEST_CAN_STREAM_RESULTS_ -# include // NOLINT -# include // NOLINT +#include // NOLINT +#include // NOLINT #endif #if GTEST_OS_WINDOWS -# include // NOLINT -#endif // GTEST_OS_WINDOWS +#include // NOLINT +#endif // GTEST_OS_WINDOWS #include "gtest/gtest.h" // NOLINT #include "gtest/gtest-spi.h" -namespace testing { - +namespace testing +{ // Declares the flags. // // We don't want the users to modify this flag in the code, but want @@ -79,8 +79,8 @@ namespace testing { // declare it here as opposed to in gtest.h. GTEST_DECLARE_bool_(death_test_use_fork); -namespace internal { - +namespace internal +{ // The value of GetTestTypeId() as seen from within the Google Test // library. This is solely for testing GetTestTypeId(). GTEST_API_ extern const TypeId kTestTypeIdInGoogleTest; @@ -128,99 +128,103 @@ GTEST_API_ std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms); // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. GTEST_API_ bool ParseInt32Flag( - const char* str, const char* flag, Int32* value); + const char* str, const char* flag, Int32* value); // Returns a random seed in range [1, kMaxRandomSeed] based on the // given --gtest_random_seed flag value. -inline int GetRandomSeedFromFlag(Int32 random_seed_flag) { - const unsigned int raw_seed = (random_seed_flag == 0) ? - static_cast(GetTimeInMillis()) : - static_cast(random_seed_flag); +inline int GetRandomSeedFromFlag(Int32 random_seed_flag) +{ + const unsigned int raw_seed = (random_seed_flag == 0) ? static_cast(GetTimeInMillis()) : static_cast(random_seed_flag); - // Normalizes the actual seed to range [1, kMaxRandomSeed] such that - // it's easy to type. - const int normalized_seed = - static_cast((raw_seed - 1U) % - static_cast(kMaxRandomSeed)) + 1; - return normalized_seed; + // Normalizes the actual seed to range [1, kMaxRandomSeed] such that + // it's easy to type. + const int normalized_seed = + static_cast((raw_seed - 1U) % + static_cast(kMaxRandomSeed)) + + 1; + return normalized_seed; } // Returns the first valid random seed after 'seed'. The behavior is // undefined if 'seed' is invalid. The seed after kMaxRandomSeed is // considered to be 1. -inline int GetNextRandomSeed(int seed) { - GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) - << "Invalid random seed " << seed << " - must be in [1, " - << kMaxRandomSeed << "]."; - const int next_seed = seed + 1; - return (next_seed > kMaxRandomSeed) ? 1 : next_seed; +inline int GetNextRandomSeed(int seed) +{ + GTEST_CHECK_(1 <= seed && seed <= kMaxRandomSeed) + << "Invalid random seed " << seed << " - must be in [1, " + << kMaxRandomSeed << "]."; + const int next_seed = seed + 1; + return (next_seed > kMaxRandomSeed) ? 1 : next_seed; } // This class saves the values of all Google Test flags in its c'tor, and // restores them in its d'tor. -class GTestFlagSaver { - public: - // The c'tor. - GTestFlagSaver() { - also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); - break_on_failure_ = GTEST_FLAG(break_on_failure); - catch_exceptions_ = GTEST_FLAG(catch_exceptions); - color_ = GTEST_FLAG(color); - death_test_style_ = GTEST_FLAG(death_test_style); - death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); - filter_ = GTEST_FLAG(filter); - internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); - list_tests_ = GTEST_FLAG(list_tests); - output_ = GTEST_FLAG(output); - print_time_ = GTEST_FLAG(print_time); - random_seed_ = GTEST_FLAG(random_seed); - repeat_ = GTEST_FLAG(repeat); - shuffle_ = GTEST_FLAG(shuffle); - stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); - stream_result_to_ = GTEST_FLAG(stream_result_to); - throw_on_failure_ = GTEST_FLAG(throw_on_failure); - } +class GTestFlagSaver +{ +public: + // The c'tor. + GTestFlagSaver() + { + also_run_disabled_tests_ = GTEST_FLAG(also_run_disabled_tests); + break_on_failure_ = GTEST_FLAG(break_on_failure); + catch_exceptions_ = GTEST_FLAG(catch_exceptions); + color_ = GTEST_FLAG(color); + death_test_style_ = GTEST_FLAG(death_test_style); + death_test_use_fork_ = GTEST_FLAG(death_test_use_fork); + filter_ = GTEST_FLAG(filter); + internal_run_death_test_ = GTEST_FLAG(internal_run_death_test); + list_tests_ = GTEST_FLAG(list_tests); + output_ = GTEST_FLAG(output); + print_time_ = GTEST_FLAG(print_time); + random_seed_ = GTEST_FLAG(random_seed); + repeat_ = GTEST_FLAG(repeat); + shuffle_ = GTEST_FLAG(shuffle); + stack_trace_depth_ = GTEST_FLAG(stack_trace_depth); + stream_result_to_ = GTEST_FLAG(stream_result_to); + throw_on_failure_ = GTEST_FLAG(throw_on_failure); + } - // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. - ~GTestFlagSaver() { - GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; - GTEST_FLAG(break_on_failure) = break_on_failure_; - GTEST_FLAG(catch_exceptions) = catch_exceptions_; - GTEST_FLAG(color) = color_; - GTEST_FLAG(death_test_style) = death_test_style_; - GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; - GTEST_FLAG(filter) = filter_; - GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; - GTEST_FLAG(list_tests) = list_tests_; - GTEST_FLAG(output) = output_; - GTEST_FLAG(print_time) = print_time_; - GTEST_FLAG(random_seed) = random_seed_; - GTEST_FLAG(repeat) = repeat_; - GTEST_FLAG(shuffle) = shuffle_; - GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; - GTEST_FLAG(stream_result_to) = stream_result_to_; - GTEST_FLAG(throw_on_failure) = throw_on_failure_; - } + // The d'tor is not virtual. DO NOT INHERIT FROM THIS CLASS. + ~GTestFlagSaver() + { + GTEST_FLAG(also_run_disabled_tests) = also_run_disabled_tests_; + GTEST_FLAG(break_on_failure) = break_on_failure_; + GTEST_FLAG(catch_exceptions) = catch_exceptions_; + GTEST_FLAG(color) = color_; + GTEST_FLAG(death_test_style) = death_test_style_; + GTEST_FLAG(death_test_use_fork) = death_test_use_fork_; + GTEST_FLAG(filter) = filter_; + GTEST_FLAG(internal_run_death_test) = internal_run_death_test_; + GTEST_FLAG(list_tests) = list_tests_; + GTEST_FLAG(output) = output_; + GTEST_FLAG(print_time) = print_time_; + GTEST_FLAG(random_seed) = random_seed_; + GTEST_FLAG(repeat) = repeat_; + GTEST_FLAG(shuffle) = shuffle_; + GTEST_FLAG(stack_trace_depth) = stack_trace_depth_; + GTEST_FLAG(stream_result_to) = stream_result_to_; + GTEST_FLAG(throw_on_failure) = throw_on_failure_; + } - private: - // Fields for saving the original values of flags. - bool also_run_disabled_tests_; - bool break_on_failure_; - bool catch_exceptions_; - std::string color_; - std::string death_test_style_; - bool death_test_use_fork_; - std::string filter_; - std::string internal_run_death_test_; - bool list_tests_; - std::string output_; - bool print_time_; - internal::Int32 random_seed_; - internal::Int32 repeat_; - bool shuffle_; - internal::Int32 stack_trace_depth_; - std::string stream_result_to_; - bool throw_on_failure_; +private: + // Fields for saving the original values of flags. + bool also_run_disabled_tests_; + bool break_on_failure_; + bool catch_exceptions_; + std::string color_; + std::string death_test_style_; + bool death_test_use_fork_; + std::string filter_; + std::string internal_run_death_test_; + bool list_tests_; + std::string output_; + bool print_time_; + internal::Int32 random_seed_; + internal::Int32 repeat_; + bool shuffle_; + internal::Int32 stack_trace_depth_; + std::string stream_result_to_; + bool throw_on_failure_; } GTEST_ATTRIBUTE_UNUSED_; // Converts a Unicode code point to a narrow string in UTF-8 encoding. @@ -259,8 +263,8 @@ void WriteToShardStatusFileIfNeeded(); // disabled because it must only be applied to the original test // process. Otherwise, we could filter out death tests we intended to execute. GTEST_API_ bool ShouldShard(const char* total_shards_str, - const char* shard_index_str, - bool in_subprocess_for_death_test); + const char* shard_index_str, + bool in_subprocess_for_death_test); // Parses the environment variable var as an Int32. If it is unset, // returns default_val. If it is not an Int32, prints an error and @@ -272,35 +276,39 @@ GTEST_API_ Int32 Int32FromEnvOrDie(const char* env_var, Int32 default_val); // some arbitrary but unique non-negative integer assigned to each test // method. Assumes that 0 <= shard_index < total_shards. GTEST_API_ bool ShouldRunTestOnShard( - int total_shards, int shard_index, int test_id); + int total_shards, int shard_index, int test_id); // STL container utilities. // Returns the number of elements in the given container that satisfy // the given predicate. template -inline int CountIf(const Container& c, Predicate predicate) { - // Implemented as an explicit loop since std::count_if() in libCstd on - // Solaris has a non-standard signature. - int count = 0; - for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) { - if (predicate(*it)) - ++count; - } - return count; +inline int CountIf(const Container& c, Predicate predicate) +{ + // Implemented as an explicit loop since std::count_if() in libCstd on + // Solaris has a non-standard signature. + int count = 0; + for (typename Container::const_iterator it = c.begin(); it != c.end(); ++it) + { + if (predicate(*it)) + ++count; + } + return count; } // Applies a function/functor to each element in the container. template -void ForEach(const Container& c, Functor functor) { - std::for_each(c.begin(), c.end(), functor); +void ForEach(const Container& c, Functor functor) +{ + std::for_each(c.begin(), c.end(), functor); } // Returns the i-th element of the vector, or default_value if i is not // in range [0, v.size()). template -inline E GetElementOr(const std::vector& v, int i, E default_value) { - return (i < 0 || i >= static_cast(v.size())) ? default_value : v[i]; +inline E GetElementOr(const std::vector& v, int i, E default_value) +{ + return (i < 0 || i >= static_cast(v.size())) ? default_value : v[i]; } // Performs an in-place shuffle of a range of the vector's elements. @@ -309,54 +317,60 @@ inline E GetElementOr(const std::vector& v, int i, E default_value) { // shuffle to the end of the vector. template void ShuffleRange(internal::Random* random, int begin, int end, - std::vector* v) { - const int size = static_cast(v->size()); - GTEST_CHECK_(0 <= begin && begin <= size) - << "Invalid shuffle range start " << begin << ": must be in range [0, " - << size << "]."; - GTEST_CHECK_(begin <= end && end <= size) - << "Invalid shuffle range finish " << end << ": must be in range [" - << begin << ", " << size << "]."; + std::vector* v) +{ + const int size = static_cast(v->size()); + GTEST_CHECK_(0 <= begin && begin <= size) + << "Invalid shuffle range start " << begin << ": must be in range [0, " + << size << "]."; + GTEST_CHECK_(begin <= end && end <= size) + << "Invalid shuffle range finish " << end << ": must be in range [" + << begin << ", " << size << "]."; - // Fisher-Yates shuffle, from - // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle - for (int range_width = end - begin; range_width >= 2; range_width--) { - const int last_in_range = begin + range_width - 1; - const int selected = begin + random->Generate(range_width); - std::swap((*v)[selected], (*v)[last_in_range]); - } + // Fisher-Yates shuffle, from + // http://en.wikipedia.org/wiki/Fisher-Yates_shuffle + for (int range_width = end - begin; range_width >= 2; range_width--) + { + const int last_in_range = begin + range_width - 1; + const int selected = begin + random->Generate(range_width); + std::swap((*v)[selected], (*v)[last_in_range]); + } } // Performs an in-place shuffle of the vector's elements. template -inline void Shuffle(internal::Random* random, std::vector* v) { - ShuffleRange(random, 0, static_cast(v->size()), v); +inline void Shuffle(internal::Random* random, std::vector* v) +{ + ShuffleRange(random, 0, static_cast(v->size()), v); } // A function for deleting an object. Handy for being used as a // functor. template -static void Delete(T* x) { - delete x; +static void Delete(T* x) +{ + delete x; } // A predicate that checks the key of a TestProperty against a known key. // // TestPropertyKeyIs is copyable. -class TestPropertyKeyIs { - public: - // Constructor. - // - // TestPropertyKeyIs has NO default constructor. - explicit TestPropertyKeyIs(const std::string& key) : key_(key) {} +class TestPropertyKeyIs +{ +public: + // Constructor. + // + // TestPropertyKeyIs has NO default constructor. + explicit TestPropertyKeyIs(const std::string& key) : key_(key) {} - // Returns true iff the test name of test property matches on key_. - bool operator()(const TestProperty& test_property) const { - return test_property.key() == key_; - } + // Returns true iff the test name of test property matches on key_. + bool operator()(const TestProperty& test_property) const + { + return test_property.key() == key_; + } - private: - std::string key_; +private: + std::string key_; }; // Class UnitTestOptions. @@ -369,44 +383,45 @@ class TestPropertyKeyIs { // test filter using either GTEST_FILTER or --gtest_filter. If both // the variable and the flag are present, the latter overrides the // former. -class GTEST_API_ UnitTestOptions { - public: - // Functions for processing the gtest_output flag. +class GTEST_API_ UnitTestOptions +{ +public: + // Functions for processing the gtest_output flag. - // Returns the output format, or "" for normal printed output. - static std::string GetOutputFormat(); + // Returns the output format, or "" for normal printed output. + static std::string GetOutputFormat(); - // Returns the absolute path of the requested output file, or the - // default (test_detail.xml in the original working directory) if - // none was explicitly specified. - static std::string GetAbsolutePathToOutputFile(); + // Returns the absolute path of the requested output file, or the + // default (test_detail.xml in the original working directory) if + // none was explicitly specified. + static std::string GetAbsolutePathToOutputFile(); - // Functions for processing the gtest_filter flag. + // Functions for processing the gtest_filter flag. - // Returns true iff the wildcard pattern matches the string. The - // first ':' or '\0' character in pattern marks the end of it. - // - // This recursive algorithm isn't very efficient, but is clear and - // works well enough for matching test names, which are short. - static bool PatternMatchesString(const char *pattern, const char *str); + // Returns true iff the wildcard pattern matches the string. The + // first ':' or '\0' character in pattern marks the end of it. + // + // This recursive algorithm isn't very efficient, but is clear and + // works well enough for matching test names, which are short. + static bool PatternMatchesString(const char* pattern, const char* str); - // Returns true iff the user-specified filter matches the test case - // name and the test name. - static bool FilterMatchesTest(const std::string &test_case_name, - const std::string &test_name); + // Returns true iff the user-specified filter matches the test case + // name and the test name. + static bool FilterMatchesTest(const std::string& test_case_name, + const std::string& test_name); #if GTEST_OS_WINDOWS - // Function for supporting the gtest_catch_exception flag. + // Function for supporting the gtest_catch_exception flag. - // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the - // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. - // This function is useful as an __except condition. - static int GTestShouldProcessSEH(DWORD exception_code); + // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the + // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. + // This function is useful as an __except condition. + static int GTestShouldProcessSEH(DWORD exception_code); #endif // GTEST_OS_WINDOWS - // Returns true if "name" matches the ':' separated list of glob-style - // filters in "filter". - static bool MatchesFilter(const std::string& name, const char* filter); + // Returns true if "name" matches the ':' separated list of glob-style + // filters in "filter". + static bool MatchesFilter(const std::string& name, const char* filter); }; // Returns the current application's name, removing directory path if that @@ -414,527 +429,551 @@ class GTEST_API_ UnitTestOptions { GTEST_API_ FilePath GetCurrentExecutableName(); // The role interface for getting the OS stack trace as a string. -class OsStackTraceGetterInterface { - public: - OsStackTraceGetterInterface() {} - virtual ~OsStackTraceGetterInterface() {} +class OsStackTraceGetterInterface +{ +public: + OsStackTraceGetterInterface() {} + virtual ~OsStackTraceGetterInterface() {} - // Returns the current OS stack trace as an std::string. Parameters: - // - // max_depth - the maximum number of stack frames to be included - // in the trace. - // skip_count - the number of top frames to be skipped; doesn't count - // against max_depth. - virtual string CurrentStackTrace(int max_depth, int skip_count) = 0; + // Returns the current OS stack trace as an std::string. Parameters: + // + // max_depth - the maximum number of stack frames to be included + // in the trace. + // skip_count - the number of top frames to be skipped; doesn't count + // against max_depth. + virtual string CurrentStackTrace(int max_depth, int skip_count) = 0; - // UponLeavingGTest() should be called immediately before Google Test calls - // user code. It saves some information about the current stack that - // CurrentStackTrace() will use to find and hide Google Test stack frames. - virtual void UponLeavingGTest() = 0; + // UponLeavingGTest() should be called immediately before Google Test calls + // user code. It saves some information about the current stack that + // CurrentStackTrace() will use to find and hide Google Test stack frames. + virtual void UponLeavingGTest() = 0; - private: - GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); +private: + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetterInterface); }; // A working implementation of the OsStackTraceGetterInterface interface. -class OsStackTraceGetter : public OsStackTraceGetterInterface { - public: - OsStackTraceGetter() : caller_frame_(NULL) {} +class OsStackTraceGetter : public OsStackTraceGetterInterface +{ +public: + OsStackTraceGetter() : caller_frame_(NULL) {} - virtual string CurrentStackTrace(int max_depth, int skip_count) - GTEST_LOCK_EXCLUDED_(mutex_); + virtual string CurrentStackTrace(int max_depth, int skip_count) + GTEST_LOCK_EXCLUDED_(mutex_); - virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_); + virtual void UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_); - // This string is inserted in place of stack frames that are part of - // Google Test's implementation. - static const char* const kElidedFramesMarker; + // This string is inserted in place of stack frames that are part of + // Google Test's implementation. + static const char* const kElidedFramesMarker; - private: - Mutex mutex_; // protects all internal state +private: + Mutex mutex_; // protects all internal state - // We save the stack frame below the frame that calls user code. - // We do this because the address of the frame immediately below - // the user code changes between the call to UponLeavingGTest() - // and any calls to CurrentStackTrace() from within the user code. - void* caller_frame_; + // We save the stack frame below the frame that calls user code. + // We do this because the address of the frame immediately below + // the user code changes between the call to UponLeavingGTest() + // and any calls to CurrentStackTrace() from within the user code. + void* caller_frame_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); + GTEST_DISALLOW_COPY_AND_ASSIGN_(OsStackTraceGetter); }; // Information about a Google Test trace point. -struct TraceInfo { - const char* file; - int line; - std::string message; +struct TraceInfo +{ + const char* file; + int line; + std::string message; }; // This is the default global test part result reporter used in UnitTestImpl. // This class should only be used by UnitTestImpl. class DefaultGlobalTestPartResultReporter - : public TestPartResultReporterInterface { - public: - explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); - // Implements the TestPartResultReporterInterface. Reports the test part - // result in the current test. - virtual void ReportTestPartResult(const TestPartResult& result); + : public TestPartResultReporterInterface +{ +public: + explicit DefaultGlobalTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. Reports the test part + // result in the current test. + virtual void ReportTestPartResult(const TestPartResult& result); - private: - UnitTestImpl* const unit_test_; +private: + UnitTestImpl* const unit_test_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultGlobalTestPartResultReporter); }; // This is the default per thread test part result reporter used in // UnitTestImpl. This class should only be used by UnitTestImpl. class DefaultPerThreadTestPartResultReporter - : public TestPartResultReporterInterface { - public: - explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); - // Implements the TestPartResultReporterInterface. The implementation just - // delegates to the current global test part result reporter of *unit_test_. - virtual void ReportTestPartResult(const TestPartResult& result); + : public TestPartResultReporterInterface +{ +public: + explicit DefaultPerThreadTestPartResultReporter(UnitTestImpl* unit_test); + // Implements the TestPartResultReporterInterface. The implementation just + // delegates to the current global test part result reporter of *unit_test_. + virtual void ReportTestPartResult(const TestPartResult& result); - private: - UnitTestImpl* const unit_test_; +private: + UnitTestImpl* const unit_test_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); + GTEST_DISALLOW_COPY_AND_ASSIGN_(DefaultPerThreadTestPartResultReporter); }; // The private implementation of the UnitTest class. We don't protect // the methods under a mutex, as this class is not accessible by a // user and the UnitTest class that delegates work to this class does // proper locking. -class GTEST_API_ UnitTestImpl { - public: - explicit UnitTestImpl(UnitTest* parent); - virtual ~UnitTestImpl(); +class GTEST_API_ UnitTestImpl +{ +public: + explicit UnitTestImpl(UnitTest* parent); + virtual ~UnitTestImpl(); - // There are two different ways to register your own TestPartResultReporter. - // You can register your own repoter to listen either only for test results - // from the current thread or for results from all threads. - // By default, each per-thread test result repoter just passes a new - // TestPartResult to the global test result reporter, which registers the - // test part result for the currently running test. + // There are two different ways to register your own TestPartResultReporter. + // You can register your own repoter to listen either only for test results + // from the current thread or for results from all threads. + // By default, each per-thread test result repoter just passes a new + // TestPartResult to the global test result reporter, which registers the + // test part result for the currently running test. - // Returns the global test part result reporter. - TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); + // Returns the global test part result reporter. + TestPartResultReporterInterface* GetGlobalTestPartResultReporter(); - // Sets the global test part result reporter. - void SetGlobalTestPartResultReporter( - TestPartResultReporterInterface* reporter); + // Sets the global test part result reporter. + void SetGlobalTestPartResultReporter( + TestPartResultReporterInterface* reporter); - // Returns the test part result reporter for the current thread. - TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); + // Returns the test part result reporter for the current thread. + TestPartResultReporterInterface* GetTestPartResultReporterForCurrentThread(); - // Sets the test part result reporter for the current thread. - void SetTestPartResultReporterForCurrentThread( - TestPartResultReporterInterface* reporter); + // Sets the test part result reporter for the current thread. + void SetTestPartResultReporterForCurrentThread( + TestPartResultReporterInterface* reporter); - // Gets the number of successful test cases. - int successful_test_case_count() const; + // Gets the number of successful test cases. + int successful_test_case_count() const; - // Gets the number of failed test cases. - int failed_test_case_count() const; + // Gets the number of failed test cases. + int failed_test_case_count() const; - // Gets the number of all test cases. - int total_test_case_count() const; + // Gets the number of all test cases. + int total_test_case_count() const; - // Gets the number of all test cases that contain at least one test - // that should run. - int test_case_to_run_count() const; + // Gets the number of all test cases that contain at least one test + // that should run. + int test_case_to_run_count() const; - // Gets the number of successful tests. - int successful_test_count() const; + // Gets the number of successful tests. + int successful_test_count() const; - // Gets the number of failed tests. - int failed_test_count() const; + // Gets the number of failed tests. + int failed_test_count() const; - // Gets the number of disabled tests that will be reported in the XML report. - int reportable_disabled_test_count() const; + // Gets the number of disabled tests that will be reported in the XML report. + int reportable_disabled_test_count() const; - // Gets the number of disabled tests. - int disabled_test_count() const; + // Gets the number of disabled tests. + int disabled_test_count() const; - // Gets the number of tests to be printed in the XML report. - int reportable_test_count() const; + // Gets the number of tests to be printed in the XML report. + int reportable_test_count() const; - // Gets the number of all tests. - int total_test_count() const; + // Gets the number of all tests. + int total_test_count() const; - // Gets the number of tests that should run. - int test_to_run_count() const; + // Gets the number of tests that should run. + int test_to_run_count() const; - // Gets the time of the test program start, in ms from the start of the - // UNIX epoch. - TimeInMillis start_timestamp() const { return start_timestamp_; } + // Gets the time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp() const { return start_timestamp_; } - // Gets the elapsed time, in milliseconds. - TimeInMillis elapsed_time() const { return elapsed_time_; } + // Gets the elapsed time, in milliseconds. + TimeInMillis elapsed_time() const { return elapsed_time_; } - // Returns true iff the unit test passed (i.e. all test cases passed). - bool Passed() const { return !Failed(); } + // Returns true iff the unit test passed (i.e. all test cases passed). + bool Passed() const { return !Failed(); } - // Returns true iff the unit test failed (i.e. some test case failed - // or something outside of all tests failed). - bool Failed() const { - return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); - } + // Returns true iff the unit test failed (i.e. some test case failed + // or something outside of all tests failed). + bool Failed() const + { + return failed_test_case_count() > 0 || ad_hoc_test_result()->Failed(); + } - // Gets the i-th test case among all the test cases. i can range from 0 to - // total_test_case_count() - 1. If i is not in that range, returns NULL. - const TestCase* GetTestCase(int i) const { - const int index = GetElementOr(test_case_indices_, i, -1); - return index < 0 ? NULL : test_cases_[i]; - } + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + const TestCase* GetTestCase(int i) const + { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[i]; + } - // Gets the i-th test case among all the test cases. i can range from 0 to - // total_test_case_count() - 1. If i is not in that range, returns NULL. - TestCase* GetMutableTestCase(int i) { - const int index = GetElementOr(test_case_indices_, i, -1); - return index < 0 ? NULL : test_cases_[index]; - } + // Gets the i-th test case among all the test cases. i can range from 0 to + // total_test_case_count() - 1. If i is not in that range, returns NULL. + TestCase* GetMutableTestCase(int i) + { + const int index = GetElementOr(test_case_indices_, i, -1); + return index < 0 ? NULL : test_cases_[index]; + } - // Provides access to the event listener list. - TestEventListeners* listeners() { return &listeners_; } + // Provides access to the event listener list. + TestEventListeners* listeners() { return &listeners_; } - // Returns the TestResult for the test that's currently running, or - // the TestResult for the ad hoc test if no test is running. - TestResult* current_test_result(); + // Returns the TestResult for the test that's currently running, or + // the TestResult for the ad hoc test if no test is running. + TestResult* current_test_result(); - // Returns the TestResult for the ad hoc test. - const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } + // Returns the TestResult for the ad hoc test. + const TestResult* ad_hoc_test_result() const { return &ad_hoc_test_result_; } - // Sets the OS stack trace getter. - // - // Does nothing if the input and the current OS stack trace getter - // are the same; otherwise, deletes the old getter and makes the - // input the current getter. - void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); + // Sets the OS stack trace getter. + // + // Does nothing if the input and the current OS stack trace getter + // are the same; otherwise, deletes the old getter and makes the + // input the current getter. + void set_os_stack_trace_getter(OsStackTraceGetterInterface* getter); - // Returns the current OS stack trace getter if it is not NULL; - // otherwise, creates an OsStackTraceGetter, makes it the current - // getter, and returns it. - OsStackTraceGetterInterface* os_stack_trace_getter(); + // Returns the current OS stack trace getter if it is not NULL; + // otherwise, creates an OsStackTraceGetter, makes it the current + // getter, and returns it. + OsStackTraceGetterInterface* os_stack_trace_getter(); - // Returns the current OS stack trace as an std::string. - // - // The maximum number of stack frames to be included is specified by - // the gtest_stack_trace_depth flag. The skip_count parameter - // specifies the number of top frames to be skipped, which doesn't - // count against the number of frames to be included. - // - // For example, if Foo() calls Bar(), which in turn calls - // CurrentOsStackTraceExceptTop(1), Foo() will be included in the - // trace but Bar() and CurrentOsStackTraceExceptTop() won't. - std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; + // Returns the current OS stack trace as an std::string. + // + // The maximum number of stack frames to be included is specified by + // the gtest_stack_trace_depth flag. The skip_count parameter + // specifies the number of top frames to be skipped, which doesn't + // count against the number of frames to be included. + // + // For example, if Foo() calls Bar(), which in turn calls + // CurrentOsStackTraceExceptTop(1), Foo() will be included in the + // trace but Bar() and CurrentOsStackTraceExceptTop() won't. + std::string CurrentOsStackTraceExceptTop(int skip_count) GTEST_NO_INLINE_; - // Finds and returns a TestCase with the given name. If one doesn't - // exist, creates one and returns it. - // - // Arguments: - // - // test_case_name: name of the test case - // type_param: the name of the test's type parameter, or NULL if - // this is not a typed or a type-parameterized test. - // set_up_tc: pointer to the function that sets up the test case - // tear_down_tc: pointer to the function that tears down the test case - TestCase* GetTestCase(const char* test_case_name, - const char* type_param, - Test::SetUpTestCaseFunc set_up_tc, - Test::TearDownTestCaseFunc tear_down_tc); + // Finds and returns a TestCase with the given name. If one doesn't + // exist, creates one and returns it. + // + // Arguments: + // + // test_case_name: name of the test case + // type_param: the name of the test's type parameter, or NULL if + // this is not a typed or a type-parameterized test. + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + TestCase* GetTestCase(const char* test_case_name, + const char* type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc); - // Adds a TestInfo to the unit test. - // - // Arguments: - // - // set_up_tc: pointer to the function that sets up the test case - // tear_down_tc: pointer to the function that tears down the test case - // test_info: the TestInfo object - void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, - Test::TearDownTestCaseFunc tear_down_tc, - TestInfo* test_info) { - // In order to support thread-safe death tests, we need to - // remember the original working directory when the test program - // was first invoked. We cannot do this in RUN_ALL_TESTS(), as - // the user may have changed the current directory before calling - // RUN_ALL_TESTS(). Therefore we capture the current directory in - // AddTestInfo(), which is called to register a TEST or TEST_F - // before main() is reached. - if (original_working_dir_.IsEmpty()) { - original_working_dir_.Set(FilePath::GetCurrentDir()); - GTEST_CHECK_(!original_working_dir_.IsEmpty()) - << "Failed to get the current working directory."; - } + // Adds a TestInfo to the unit test. + // + // Arguments: + // + // set_up_tc: pointer to the function that sets up the test case + // tear_down_tc: pointer to the function that tears down the test case + // test_info: the TestInfo object + void AddTestInfo(Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc, + TestInfo* test_info) + { + // In order to support thread-safe death tests, we need to + // remember the original working directory when the test program + // was first invoked. We cannot do this in RUN_ALL_TESTS(), as + // the user may have changed the current directory before calling + // RUN_ALL_TESTS(). Therefore we capture the current directory in + // AddTestInfo(), which is called to register a TEST or TEST_F + // before main() is reached. + if (original_working_dir_.IsEmpty()) + { + original_working_dir_.Set(FilePath::GetCurrentDir()); + GTEST_CHECK_(!original_working_dir_.IsEmpty()) + << "Failed to get the current working directory."; + } - GetTestCase(test_info->test_case_name(), - test_info->type_param(), - set_up_tc, - tear_down_tc)->AddTestInfo(test_info); - } + GetTestCase(test_info->test_case_name(), + test_info->type_param(), + set_up_tc, + tear_down_tc) + ->AddTestInfo(test_info); + } #if GTEST_HAS_PARAM_TEST - // Returns ParameterizedTestCaseRegistry object used to keep track of - // value-parameterized tests and instantiate and register them. - internal::ParameterizedTestCaseRegistry& parameterized_test_registry() { - return parameterized_test_registry_; - } + // Returns ParameterizedTestCaseRegistry object used to keep track of + // value-parameterized tests and instantiate and register them. + internal::ParameterizedTestCaseRegistry& parameterized_test_registry() + { + return parameterized_test_registry_; + } #endif // GTEST_HAS_PARAM_TEST - // Sets the TestCase object for the test that's currently running. - void set_current_test_case(TestCase* a_current_test_case) { - current_test_case_ = a_current_test_case; - } + // Sets the TestCase object for the test that's currently running. + void set_current_test_case(TestCase* a_current_test_case) + { + current_test_case_ = a_current_test_case; + } - // Sets the TestInfo object for the test that's currently running. If - // current_test_info is NULL, the assertion results will be stored in - // ad_hoc_test_result_. - void set_current_test_info(TestInfo* a_current_test_info) { - current_test_info_ = a_current_test_info; - } + // Sets the TestInfo object for the test that's currently running. If + // current_test_info is NULL, the assertion results will be stored in + // ad_hoc_test_result_. + void set_current_test_info(TestInfo* a_current_test_info) + { + current_test_info_ = a_current_test_info; + } - // Registers all parameterized tests defined using TEST_P and - // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter - // combination. This method can be called more then once; it has guards - // protecting from registering the tests more then once. If - // value-parameterized tests are disabled, RegisterParameterizedTests is - // present but does nothing. - void RegisterParameterizedTests(); + // Registers all parameterized tests defined using TEST_P and + // INSTANTIATE_TEST_CASE_P, creating regular tests for each test/parameter + // combination. This method can be called more then once; it has guards + // protecting from registering the tests more then once. If + // value-parameterized tests are disabled, RegisterParameterizedTests is + // present but does nothing. + void RegisterParameterizedTests(); - // Runs all tests in this UnitTest object, prints the result, and - // returns true if all tests are successful. If any exception is - // thrown during a test, this test is considered to be failed, but - // the rest of the tests will still be run. - bool RunAllTests(); + // Runs all tests in this UnitTest object, prints the result, and + // returns true if all tests are successful. If any exception is + // thrown during a test, this test is considered to be failed, but + // the rest of the tests will still be run. + bool RunAllTests(); - // Clears the results of all tests, except the ad hoc tests. - void ClearNonAdHocTestResult() { - ForEach(test_cases_, TestCase::ClearTestCaseResult); - } + // Clears the results of all tests, except the ad hoc tests. + void ClearNonAdHocTestResult() + { + ForEach(test_cases_, TestCase::ClearTestCaseResult); + } - // Clears the results of ad-hoc test assertions. - void ClearAdHocTestResult() { - ad_hoc_test_result_.Clear(); - } + // Clears the results of ad-hoc test assertions. + void ClearAdHocTestResult() + { + ad_hoc_test_result_.Clear(); + } - // Adds a TestProperty to the current TestResult object when invoked in a - // context of a test or a test case, or to the global property set. If the - // result already contains a property with the same key, the value will be - // updated. - void RecordProperty(const TestProperty& test_property); + // Adds a TestProperty to the current TestResult object when invoked in a + // context of a test or a test case, or to the global property set. If the + // result already contains a property with the same key, the value will be + // updated. + void RecordProperty(const TestProperty& test_property); - enum ReactionToSharding { - HONOR_SHARDING_PROTOCOL, - IGNORE_SHARDING_PROTOCOL - }; + enum ReactionToSharding + { + HONOR_SHARDING_PROTOCOL, + IGNORE_SHARDING_PROTOCOL + }; - // Matches the full name of each test against the user-specified - // filter to decide whether the test should run, then records the - // result in each TestCase and TestInfo object. - // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests - // based on sharding variables in the environment. - // Returns the number of tests that should run. - int FilterTests(ReactionToSharding shard_tests); + // Matches the full name of each test against the user-specified + // filter to decide whether the test should run, then records the + // result in each TestCase and TestInfo object. + // If shard_tests == HONOR_SHARDING_PROTOCOL, further filters tests + // based on sharding variables in the environment. + // Returns the number of tests that should run. + int FilterTests(ReactionToSharding shard_tests); - // Prints the names of the tests matching the user-specified filter flag. - void ListTestsMatchingFilter(); + // Prints the names of the tests matching the user-specified filter flag. + void ListTestsMatchingFilter(); - const TestCase* current_test_case() const { return current_test_case_; } - TestInfo* current_test_info() { return current_test_info_; } - const TestInfo* current_test_info() const { return current_test_info_; } + const TestCase* current_test_case() const { return current_test_case_; } + TestInfo* current_test_info() { return current_test_info_; } + const TestInfo* current_test_info() const { return current_test_info_; } - // Returns the vector of environments that need to be set-up/torn-down - // before/after the tests are run. - std::vector& environments() { return environments_; } + // Returns the vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector& environments() { return environments_; } - // Getters for the per-thread Google Test trace stack. - std::vector& gtest_trace_stack() { - return *(gtest_trace_stack_.pointer()); - } - const std::vector& gtest_trace_stack() const { - return gtest_trace_stack_.get(); - } + // Getters for the per-thread Google Test trace stack. + std::vector& gtest_trace_stack() + { + return *(gtest_trace_stack_.pointer()); + } + const std::vector& gtest_trace_stack() const + { + return gtest_trace_stack_.get(); + } #if GTEST_HAS_DEATH_TEST - void InitDeathTestSubprocessControlInfo() { - internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); - } - // Returns a pointer to the parsed --gtest_internal_run_death_test - // flag, or NULL if that flag was not specified. - // This information is useful only in a death test child process. - // Must not be called before a call to InitGoogleTest. - const InternalRunDeathTestFlag* internal_run_death_test_flag() const { - return internal_run_death_test_flag_.get(); - } + void InitDeathTestSubprocessControlInfo() + { + internal_run_death_test_flag_.reset(ParseInternalRunDeathTestFlag()); + } + // Returns a pointer to the parsed --gtest_internal_run_death_test + // flag, or NULL if that flag was not specified. + // This information is useful only in a death test child process. + // Must not be called before a call to InitGoogleTest. + const InternalRunDeathTestFlag* internal_run_death_test_flag() const + { + return internal_run_death_test_flag_.get(); + } - // Returns a pointer to the current death test factory. - internal::DeathTestFactory* death_test_factory() { - return death_test_factory_.get(); - } + // Returns a pointer to the current death test factory. + internal::DeathTestFactory* death_test_factory() + { + return death_test_factory_.get(); + } - void SuppressTestEventsIfInSubprocess(); + void SuppressTestEventsIfInSubprocess(); - friend class ReplaceDeathTestFactory; + friend class ReplaceDeathTestFactory; #endif // GTEST_HAS_DEATH_TEST - // Initializes the event listener performing XML output as specified by - // UnitTestOptions. Must not be called before InitGoogleTest. - void ConfigureXmlOutput(); + // Initializes the event listener performing XML output as specified by + // UnitTestOptions. Must not be called before InitGoogleTest. + void ConfigureXmlOutput(); #if GTEST_CAN_STREAM_RESULTS_ - // Initializes the event listener for streaming test results to a socket. - // Must not be called before InitGoogleTest. - void ConfigureStreamingOutput(); + // Initializes the event listener for streaming test results to a socket. + // Must not be called before InitGoogleTest. + void ConfigureStreamingOutput(); #endif - // Performs initialization dependent upon flag values obtained in - // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to - // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest - // this function is also called from RunAllTests. Since this function can be - // called more than once, it has to be idempotent. - void PostFlagParsingInit(); + // Performs initialization dependent upon flag values obtained in + // ParseGoogleTestFlagsOnly. Is called from InitGoogleTest after the call to + // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest + // this function is also called from RunAllTests. Since this function can be + // called more than once, it has to be idempotent. + void PostFlagParsingInit(); - // Gets the random seed used at the start of the current test iteration. - int random_seed() const { return random_seed_; } + // Gets the random seed used at the start of the current test iteration. + int random_seed() const { return random_seed_; } - // Gets the random number generator. - internal::Random* random() { return &random_; } + // Gets the random number generator. + internal::Random* random() { return &random_; } - // Shuffles all test cases, and the tests within each test case, - // making sure that death tests are still run first. - void ShuffleTests(); + // Shuffles all test cases, and the tests within each test case, + // making sure that death tests are still run first. + void ShuffleTests(); - // Restores the test cases and tests to their order before the first shuffle. - void UnshuffleTests(); + // Restores the test cases and tests to their order before the first shuffle. + void UnshuffleTests(); - // Returns the value of GTEST_FLAG(catch_exceptions) at the moment - // UnitTest::Run() starts. - bool catch_exceptions() const { return catch_exceptions_; } + // Returns the value of GTEST_FLAG(catch_exceptions) at the moment + // UnitTest::Run() starts. + bool catch_exceptions() const { return catch_exceptions_; } - private: - friend class ::testing::UnitTest; +private: + friend class ::testing::UnitTest; - // Used by UnitTest::Run() to capture the state of - // GTEST_FLAG(catch_exceptions) at the moment it starts. - void set_catch_exceptions(bool value) { catch_exceptions_ = value; } + // Used by UnitTest::Run() to capture the state of + // GTEST_FLAG(catch_exceptions) at the moment it starts. + void set_catch_exceptions(bool value) { catch_exceptions_ = value; } - // The UnitTest object that owns this implementation object. - UnitTest* const parent_; + // The UnitTest object that owns this implementation object. + UnitTest* const parent_; - // The working directory when the first TEST() or TEST_F() was - // executed. - internal::FilePath original_working_dir_; + // The working directory when the first TEST() or TEST_F() was + // executed. + internal::FilePath original_working_dir_; - // The default test part result reporters. - DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; - DefaultPerThreadTestPartResultReporter - default_per_thread_test_part_result_reporter_; + // The default test part result reporters. + DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; + DefaultPerThreadTestPartResultReporter + default_per_thread_test_part_result_reporter_; - // Points to (but doesn't own) the global test part result reporter. - TestPartResultReporterInterface* global_test_part_result_repoter_; + // Points to (but doesn't own) the global test part result reporter. + TestPartResultReporterInterface* global_test_part_result_repoter_; - // Protects read and write access to global_test_part_result_reporter_. - internal::Mutex global_test_part_result_reporter_mutex_; + // Protects read and write access to global_test_part_result_reporter_. + internal::Mutex global_test_part_result_reporter_mutex_; - // Points to (but doesn't own) the per-thread test part result reporter. - internal::ThreadLocal - per_thread_test_part_result_reporter_; + // Points to (but doesn't own) the per-thread test part result reporter. + internal::ThreadLocal + per_thread_test_part_result_reporter_; - // The vector of environments that need to be set-up/torn-down - // before/after the tests are run. - std::vector environments_; + // The vector of environments that need to be set-up/torn-down + // before/after the tests are run. + std::vector environments_; - // The vector of TestCases in their original order. It owns the - // elements in the vector. - std::vector test_cases_; + // The vector of TestCases in their original order. It owns the + // elements in the vector. + std::vector test_cases_; - // Provides a level of indirection for the test case list to allow - // easy shuffling and restoring the test case order. The i-th - // element of this vector is the index of the i-th test case in the - // shuffled order. - std::vector test_case_indices_; + // Provides a level of indirection for the test case list to allow + // easy shuffling and restoring the test case order. The i-th + // element of this vector is the index of the i-th test case in the + // shuffled order. + std::vector test_case_indices_; #if GTEST_HAS_PARAM_TEST - // ParameterizedTestRegistry object used to register value-parameterized - // tests. - internal::ParameterizedTestCaseRegistry parameterized_test_registry_; + // ParameterizedTestRegistry object used to register value-parameterized + // tests. + internal::ParameterizedTestCaseRegistry parameterized_test_registry_; - // Indicates whether RegisterParameterizedTests() has been called already. - bool parameterized_tests_registered_; + // Indicates whether RegisterParameterizedTests() has been called already. + bool parameterized_tests_registered_; #endif // GTEST_HAS_PARAM_TEST - // Index of the last death test case registered. Initially -1. - int last_death_test_case_; + // Index of the last death test case registered. Initially -1. + int last_death_test_case_; - // This points to the TestCase for the currently running test. It - // changes as Google Test goes through one test case after another. - // When no test is running, this is set to NULL and Google Test - // stores assertion results in ad_hoc_test_result_. Initially NULL. - TestCase* current_test_case_; + // This points to the TestCase for the currently running test. It + // changes as Google Test goes through one test case after another. + // When no test is running, this is set to NULL and Google Test + // stores assertion results in ad_hoc_test_result_. Initially NULL. + TestCase* current_test_case_; - // This points to the TestInfo for the currently running test. It - // changes as Google Test goes through one test after another. When - // no test is running, this is set to NULL and Google Test stores - // assertion results in ad_hoc_test_result_. Initially NULL. - TestInfo* current_test_info_; + // This points to the TestInfo for the currently running test. It + // changes as Google Test goes through one test after another. When + // no test is running, this is set to NULL and Google Test stores + // assertion results in ad_hoc_test_result_. Initially NULL. + TestInfo* current_test_info_; - // Normally, a user only writes assertions inside a TEST or TEST_F, - // or inside a function called by a TEST or TEST_F. Since Google - // Test keeps track of which test is current running, it can - // associate such an assertion with the test it belongs to. - // - // If an assertion is encountered when no TEST or TEST_F is running, - // Google Test attributes the assertion result to an imaginary "ad hoc" - // test, and records the result in ad_hoc_test_result_. - TestResult ad_hoc_test_result_; + // Normally, a user only writes assertions inside a TEST or TEST_F, + // or inside a function called by a TEST or TEST_F. Since Google + // Test keeps track of which test is current running, it can + // associate such an assertion with the test it belongs to. + // + // If an assertion is encountered when no TEST or TEST_F is running, + // Google Test attributes the assertion result to an imaginary "ad hoc" + // test, and records the result in ad_hoc_test_result_. + TestResult ad_hoc_test_result_; - // The list of event listeners that can be used to track events inside - // Google Test. - TestEventListeners listeners_; + // The list of event listeners that can be used to track events inside + // Google Test. + TestEventListeners listeners_; - // The OS stack trace getter. Will be deleted when the UnitTest - // object is destructed. By default, an OsStackTraceGetter is used, - // but the user can set this field to use a custom getter if that is - // desired. - OsStackTraceGetterInterface* os_stack_trace_getter_; + // The OS stack trace getter. Will be deleted when the UnitTest + // object is destructed. By default, an OsStackTraceGetter is used, + // but the user can set this field to use a custom getter if that is + // desired. + OsStackTraceGetterInterface* os_stack_trace_getter_; - // True iff PostFlagParsingInit() has been called. - bool post_flag_parse_init_performed_; + // True iff PostFlagParsingInit() has been called. + bool post_flag_parse_init_performed_; - // The random number seed used at the beginning of the test run. - int random_seed_; + // The random number seed used at the beginning of the test run. + int random_seed_; - // Our random number generator. - internal::Random random_; + // Our random number generator. + internal::Random random_; - // The time of the test program start, in ms from the start of the - // UNIX epoch. - TimeInMillis start_timestamp_; + // The time of the test program start, in ms from the start of the + // UNIX epoch. + TimeInMillis start_timestamp_; - // How long the test took to run, in milliseconds. - TimeInMillis elapsed_time_; + // How long the test took to run, in milliseconds. + TimeInMillis elapsed_time_; #if GTEST_HAS_DEATH_TEST - // The decomposed components of the gtest_internal_run_death_test flag, - // parsed when RUN_ALL_TESTS is called. - internal::scoped_ptr internal_run_death_test_flag_; - internal::scoped_ptr death_test_factory_; + // The decomposed components of the gtest_internal_run_death_test flag, + // parsed when RUN_ALL_TESTS is called. + internal::scoped_ptr internal_run_death_test_flag_; + internal::scoped_ptr death_test_factory_; #endif // GTEST_HAS_DEATH_TEST - // A per-thread stack of traces created by the SCOPED_TRACE() macro. - internal::ThreadLocal > gtest_trace_stack_; + // A per-thread stack of traces created by the SCOPED_TRACE() macro. + internal::ThreadLocal > gtest_trace_stack_; - // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests() - // starts. - bool catch_exceptions_; + // The value of GTEST_FLAG(catch_exceptions) at the moment RunAllTests() + // starts. + bool catch_exceptions_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); + GTEST_DISALLOW_COPY_AND_ASSIGN_(UnitTestImpl); }; // class UnitTestImpl // Convenience function for accessing the global UnitTest // implementation object. -inline UnitTestImpl* GetUnitTestImpl() { - return UnitTest::GetInstance()->impl(); +inline UnitTestImpl* GetUnitTestImpl() +{ + return UnitTest::GetInstance()->impl(); } #if GTEST_USES_SIMPLE_RE @@ -952,7 +991,7 @@ GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch); GTEST_API_ bool ValidateRegex(const char* regex); GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str); GTEST_API_ bool MatchRepetitionAndRegexAtHead( - bool escaped, char ch, char repeat, const char* regex, const char* str); + bool escaped, char ch, char repeat, const char* regex, const char* str); GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str); #endif // GTEST_USES_SIMPLE_RE @@ -968,75 +1007,81 @@ GTEST_API_ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv); // platform. GTEST_API_ std::string GetLastErrnoDescription(); -# if GTEST_OS_WINDOWS +#if GTEST_OS_WINDOWS // Provides leak-safe Windows kernel handle ownership. -class AutoHandle { - public: - AutoHandle() : handle_(INVALID_HANDLE_VALUE) {} - explicit AutoHandle(HANDLE handle) : handle_(handle) {} +class AutoHandle +{ +public: + AutoHandle() : handle_(INVALID_HANDLE_VALUE) {} + explicit AutoHandle(HANDLE handle) : handle_(handle) {} - ~AutoHandle() { Reset(); } + ~AutoHandle() { Reset(); } - HANDLE Get() const { return handle_; } - void Reset() { Reset(INVALID_HANDLE_VALUE); } - void Reset(HANDLE handle) { - if (handle != handle_) { - if (handle_ != INVALID_HANDLE_VALUE) - ::CloseHandle(handle_); - handle_ = handle; - } - } + HANDLE Get() const { return handle_; } + void Reset() { Reset(INVALID_HANDLE_VALUE); } + void Reset(HANDLE handle) + { + if (handle != handle_) + { + if (handle_ != INVALID_HANDLE_VALUE) + ::CloseHandle(handle_); + handle_ = handle; + } + } - private: - HANDLE handle_; +private: + HANDLE handle_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); + GTEST_DISALLOW_COPY_AND_ASSIGN_(AutoHandle); }; -# endif // GTEST_OS_WINDOWS +#endif // GTEST_OS_WINDOWS // Attempts to parse a string into a positive integer pointed to by the // number parameter. Returns true if that is possible. // GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can use // it here. template -bool ParseNaturalNumber(const ::std::string& str, Integer* number) { - // Fail fast if the given string does not begin with a digit; - // this bypasses strtoXXX's "optional leading whitespace and plus - // or minus sign" semantics, which are undesirable here. - if (str.empty() || !IsDigit(str[0])) { - return false; - } - errno = 0; +bool ParseNaturalNumber(const ::std::string& str, Integer* number) +{ + // Fail fast if the given string does not begin with a digit; + // this bypasses strtoXXX's "optional leading whitespace and plus + // or minus sign" semantics, which are undesirable here. + if (str.empty() || !IsDigit(str[0])) + { + return false; + } + errno = 0; - char* end; - // BiggestConvertible is the largest integer type that system-provided - // string-to-number conversion routines can return. + char* end; + // BiggestConvertible is the largest integer type that system-provided + // string-to-number conversion routines can return. -# if GTEST_OS_WINDOWS && !defined(__GNUC__) +#if GTEST_OS_WINDOWS && !defined(__GNUC__) - // MSVC and C++ Builder define __int64 instead of the standard long long. - typedef unsigned __int64 BiggestConvertible; - const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); + // MSVC and C++ Builder define __int64 instead of the standard long long. + typedef unsigned __int64 BiggestConvertible; + const BiggestConvertible parsed = _strtoui64(str.c_str(), &end, 10); -# else +#else - typedef unsigned long long BiggestConvertible; // NOLINT - const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); + typedef unsigned long long BiggestConvertible; // NOLINT + const BiggestConvertible parsed = strtoull(str.c_str(), &end, 10); -# endif // GTEST_OS_WINDOWS && !defined(__GNUC__) +#endif // GTEST_OS_WINDOWS && !defined(__GNUC__) - const bool parse_success = *end == '\0' && errno == 0; + const bool parse_success = *end == '\0' && errno == 0; - // TODO(vladl@google.com): Convert this to compile time assertion when it is - // available. - GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); + // TODO(vladl@google.com): Convert this to compile time assertion when it is + // available. + GTEST_CHECK_(sizeof(Integer) <= sizeof(parsed)); - const Integer result = static_cast(parsed); - if (parse_success && static_cast(result) == parsed) { - *number = result; - return true; - } - return false; + const Integer result = static_cast(parsed); + if (parse_success && static_cast(result) == parsed) + { + *number = result; + return true; + } + return false; } #endif // GTEST_HAS_DEATH_TEST @@ -1046,168 +1091,188 @@ bool ParseNaturalNumber(const ::std::string& str, Integer* number) { // // This class is supplied only for the purpose of testing Google Test's own // constructs. Do not use it in user tests, either directly or indirectly. -class TestResultAccessor { - public: - static void RecordProperty(TestResult* test_result, - const std::string& xml_element, - const TestProperty& property) { - test_result->RecordProperty(xml_element, property); - } +class TestResultAccessor +{ +public: + static void RecordProperty(TestResult* test_result, + const std::string& xml_element, + const TestProperty& property) + { + test_result->RecordProperty(xml_element, property); + } - static void ClearTestPartResults(TestResult* test_result) { - test_result->ClearTestPartResults(); - } + static void ClearTestPartResults(TestResult* test_result) + { + test_result->ClearTestPartResults(); + } - static const std::vector& test_part_results( - const TestResult& test_result) { - return test_result.test_part_results(); - } + static const std::vector& test_part_results( + const TestResult& test_result) + { + return test_result.test_part_results(); + } }; #if GTEST_CAN_STREAM_RESULTS_ // Streams test results to the given port on the given host machine. -class StreamingListener : public EmptyTestEventListener { - public: - // Abstract base class for writing strings to a socket. - class AbstractSocketWriter { - public: - virtual ~AbstractSocketWriter() {} +class StreamingListener : public EmptyTestEventListener +{ +public: + // Abstract base class for writing strings to a socket. + class AbstractSocketWriter + { + public: + virtual ~AbstractSocketWriter() {} - // Sends a string to the socket. - virtual void Send(const string& message) = 0; + // Sends a string to the socket. + virtual void Send(const string& message) = 0; - // Closes the socket. - virtual void CloseConnection() {} + // Closes the socket. + virtual void CloseConnection() {} - // Sends a string and a newline to the socket. - void SendLn(const string& message) { - Send(message + "\n"); - } - }; + // Sends a string and a newline to the socket. + void SendLn(const string& message) + { + Send(message + "\n"); + } + }; - // Concrete class for actually writing strings to a socket. - class SocketWriter : public AbstractSocketWriter { - public: - SocketWriter(const string& host, const string& port) - : sockfd_(-1), host_name_(host), port_num_(port) { - MakeConnection(); - } + // Concrete class for actually writing strings to a socket. + class SocketWriter : public AbstractSocketWriter + { + public: + SocketWriter(const string& host, const string& port) + : sockfd_(-1), host_name_(host), port_num_(port) + { + MakeConnection(); + } - virtual ~SocketWriter() { - if (sockfd_ != -1) - CloseConnection(); - } + virtual ~SocketWriter() + { + if (sockfd_ != -1) + CloseConnection(); + } - // Sends a string to the socket. - virtual void Send(const string& message) { - GTEST_CHECK_(sockfd_ != -1) - << "Send() can be called only when there is a connection."; + // Sends a string to the socket. + virtual void Send(const string& message) + { + GTEST_CHECK_(sockfd_ != -1) + << "Send() can be called only when there is a connection."; - const int len = static_cast(message.length()); - if (write(sockfd_, message.c_str(), len) != len) { - GTEST_LOG_(WARNING) - << "stream_result_to: failed to stream to " - << host_name_ << ":" << port_num_; - } - } + const int len = static_cast(message.length()); + if (write(sockfd_, message.c_str(), len) != len) + { + GTEST_LOG_(WARNING) + << "stream_result_to: failed to stream to " + << host_name_ << ":" << port_num_; + } + } - private: - // Creates a client socket and connects to the server. - void MakeConnection(); + private: + // Creates a client socket and connects to the server. + void MakeConnection(); - // Closes the socket. - void CloseConnection() { - GTEST_CHECK_(sockfd_ != -1) - << "CloseConnection() can be called only when there is a connection."; + // Closes the socket. + void CloseConnection() + { + GTEST_CHECK_(sockfd_ != -1) + << "CloseConnection() can be called only when there is a connection."; - close(sockfd_); - sockfd_ = -1; - } + close(sockfd_); + sockfd_ = -1; + } - int sockfd_; // socket file descriptor - const string host_name_; - const string port_num_; + int sockfd_; // socket file descriptor + const string host_name_; + const string port_num_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter); - }; // class SocketWriter + GTEST_DISALLOW_COPY_AND_ASSIGN_(SocketWriter); + }; // class SocketWriter - // Escapes '=', '&', '%', and '\n' characters in str as "%xx". - static string UrlEncode(const char* str); + // Escapes '=', '&', '%', and '\n' characters in str as "%xx". + static string UrlEncode(const char* str); - StreamingListener(const string& host, const string& port) - : socket_writer_(new SocketWriter(host, port)) { Start(); } + StreamingListener(const string& host, const string& port) + : socket_writer_(new SocketWriter(host, port)) { Start(); } - explicit StreamingListener(AbstractSocketWriter* socket_writer) - : socket_writer_(socket_writer) { Start(); } + explicit StreamingListener(AbstractSocketWriter* socket_writer) + : socket_writer_(socket_writer) { Start(); } - void OnTestProgramStart(const UnitTest& /* unit_test */) { - SendLn("event=TestProgramStart"); - } + void OnTestProgramStart(const UnitTest& /* unit_test */) + { + SendLn("event=TestProgramStart"); + } - void OnTestProgramEnd(const UnitTest& unit_test) { - // Note that Google Test current only report elapsed time for each - // test iteration, not for the entire test program. - SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed())); + void OnTestProgramEnd(const UnitTest& unit_test) + { + // Note that Google Test current only report elapsed time for each + // test iteration, not for the entire test program. + SendLn("event=TestProgramEnd&passed=" + FormatBool(unit_test.Passed())); - // Notify the streaming server to stop. - socket_writer_->CloseConnection(); - } + // Notify the streaming server to stop. + socket_writer_->CloseConnection(); + } - void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) { - SendLn("event=TestIterationStart&iteration=" + - StreamableToString(iteration)); - } + void OnTestIterationStart(const UnitTest& /* unit_test */, int iteration) + { + SendLn("event=TestIterationStart&iteration=" + + StreamableToString(iteration)); + } - void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) { - SendLn("event=TestIterationEnd&passed=" + - FormatBool(unit_test.Passed()) + "&elapsed_time=" + - StreamableToString(unit_test.elapsed_time()) + "ms"); - } + void OnTestIterationEnd(const UnitTest& unit_test, int /* iteration */) + { + SendLn("event=TestIterationEnd&passed=" + + FormatBool(unit_test.Passed()) + "&elapsed_time=" + + StreamableToString(unit_test.elapsed_time()) + "ms"); + } - void OnTestCaseStart(const TestCase& test_case) { - SendLn(std::string("event=TestCaseStart&name=") + test_case.name()); - } + void OnTestCaseStart(const TestCase& test_case) + { + SendLn(std::string("event=TestCaseStart&name=") + test_case.name()); + } - void OnTestCaseEnd(const TestCase& test_case) { - SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) - + "&elapsed_time=" + StreamableToString(test_case.elapsed_time()) - + "ms"); - } + void OnTestCaseEnd(const TestCase& test_case) + { + SendLn("event=TestCaseEnd&passed=" + FormatBool(test_case.Passed()) + "&elapsed_time=" + StreamableToString(test_case.elapsed_time()) + "ms"); + } - void OnTestStart(const TestInfo& test_info) { - SendLn(std::string("event=TestStart&name=") + test_info.name()); - } + void OnTestStart(const TestInfo& test_info) + { + SendLn(std::string("event=TestStart&name=") + test_info.name()); + } - void OnTestEnd(const TestInfo& test_info) { - SendLn("event=TestEnd&passed=" + - FormatBool((test_info.result())->Passed()) + - "&elapsed_time=" + - StreamableToString((test_info.result())->elapsed_time()) + "ms"); - } + void OnTestEnd(const TestInfo& test_info) + { + SendLn("event=TestEnd&passed=" + + FormatBool((test_info.result())->Passed()) + + "&elapsed_time=" + + StreamableToString((test_info.result())->elapsed_time()) + "ms"); + } - void OnTestPartResult(const TestPartResult& test_part_result) { - const char* file_name = test_part_result.file_name(); - if (file_name == NULL) - file_name = ""; - SendLn("event=TestPartResult&file=" + UrlEncode(file_name) + - "&line=" + StreamableToString(test_part_result.line_number()) + - "&message=" + UrlEncode(test_part_result.message())); - } + void OnTestPartResult(const TestPartResult& test_part_result) + { + const char* file_name = test_part_result.file_name(); + if (file_name == NULL) + file_name = ""; + SendLn("event=TestPartResult&file=" + UrlEncode(file_name) + + "&line=" + StreamableToString(test_part_result.line_number()) + + "&message=" + UrlEncode(test_part_result.message())); + } - private: - // Sends the given message and a newline to the socket. - void SendLn(const string& message) { socket_writer_->SendLn(message); } +private: + // Sends the given message and a newline to the socket. + void SendLn(const string& message) { socket_writer_->SendLn(message); } - // Called at the start of streaming to notify the receiver what - // protocol we are using. - void Start() { SendLn("gtest_streaming_protocol_version=1.0"); } + // Called at the start of streaming to notify the receiver what + // protocol we are using. + void Start() { SendLn("gtest_streaming_protocol_version=1.0"); } - string FormatBool(bool value) { return value ? "1" : "0"; } + string FormatBool(bool value) { return value ? "1" : "0"; } - const scoped_ptr socket_writer_; + const scoped_ptr socket_writer_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); + GTEST_DISALLOW_COPY_AND_ASSIGN_(StreamingListener); }; // class StreamingListener #endif // GTEST_CAN_STREAM_RESULTS_ diff --git a/test/gtest-1.7.0/src/gtest-port.cc b/test/gtest-1.7.0/src/gtest-port.cc index 0c4df5f29..0601ebe25 100644 --- a/test/gtest-1.7.0/src/gtest-port.cc +++ b/test/gtest-1.7.0/src/gtest-port.cc @@ -37,23 +37,23 @@ #include #if GTEST_OS_WINDOWS_MOBILE -# include // For TerminateProcess() +#include // For TerminateProcess() #elif GTEST_OS_WINDOWS -# include -# include +#include +#include #else -# include +#include #endif // GTEST_OS_WINDOWS_MOBILE #if GTEST_OS_MAC -# include -# include -# include +#include +#include +#include #endif // GTEST_OS_MAC #if GTEST_OS_QNX -# include -# include +#include +#include #endif // GTEST_OS_QNX #include "gtest/gtest-spi.h" @@ -70,9 +70,10 @@ #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ -namespace testing { -namespace internal { - +namespace testing +{ +namespace internal +{ #if defined(_MSC_VER) || defined(__BORLANDC__) // MSVC and C++Builder do not provide a definition of STDERR_FILENO. const int kStdOutFileno = 1; @@ -86,49 +87,59 @@ const int kStdErrFileno = STDERR_FILENO; // Returns the number of threads running in the process, or 0 to indicate that // we cannot detect it. -size_t GetThreadCount() { - const task_t task = mach_task_self(); - mach_msg_type_number_t thread_count; - thread_act_array_t thread_list; - const kern_return_t status = task_threads(task, &thread_list, &thread_count); - if (status == KERN_SUCCESS) { - // task_threads allocates resources in thread_list and we need to free them - // to avoid leaks. - vm_deallocate(task, - reinterpret_cast(thread_list), - sizeof(thread_t) * thread_count); - return static_cast(thread_count); - } else { - return 0; - } +size_t GetThreadCount() +{ + const task_t task = mach_task_self(); + mach_msg_type_number_t thread_count; + thread_act_array_t thread_list; + const kern_return_t status = task_threads(task, &thread_list, &thread_count); + if (status == KERN_SUCCESS) + { + // task_threads allocates resources in thread_list and we need to free them + // to avoid leaks. + vm_deallocate(task, + reinterpret_cast(thread_list), + sizeof(thread_t) * thread_count); + return static_cast(thread_count); + } + else + { + return 0; + } } #elif GTEST_OS_QNX // Returns the number of threads running in the process, or 0 to indicate that // we cannot detect it. -size_t GetThreadCount() { - const int fd = open("/proc/self/as", O_RDONLY); - if (fd < 0) { - return 0; - } - procfs_info process_info; - const int status = - devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL); - close(fd); - if (status == EOK) { - return static_cast(process_info.num_threads); - } else { - return 0; - } +size_t GetThreadCount() +{ + const int fd = open("/proc/self/as", O_RDONLY); + if (fd < 0) + { + return 0; + } + procfs_info process_info; + const int status = + devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL); + close(fd); + if (status == EOK) + { + return static_cast(process_info.num_threads); + } + else + { + return 0; + } } #else -size_t GetThreadCount() { - // There's no portable way to detect the number of threads, so we just - // return 0 to indicate that we cannot detect it. - return 0; +size_t GetThreadCount() +{ + // There's no portable way to detect the number of threads, so we just + // return 0 to indicate that we cannot detect it. + return 0; } #endif // GTEST_OS_MAC @@ -137,177 +148,218 @@ size_t GetThreadCount() { // Implements RE. Currently only needed for death tests. -RE::~RE() { - if (is_valid_) { - // regfree'ing an invalid regex might crash because the content - // of the regex is undefined. Since the regex's are essentially - // the same, one cannot be valid (or invalid) without the other - // being so too. - regfree(&partial_regex_); - regfree(&full_regex_); - } - free(const_cast(pattern_)); +RE::~RE() +{ + if (is_valid_) + { + // regfree'ing an invalid regex might crash because the content + // of the regex is undefined. Since the regex's are essentially + // the same, one cannot be valid (or invalid) without the other + // being so too. + regfree(&partial_regex_); + regfree(&full_regex_); + } + free(const_cast(pattern_)); } // Returns true iff regular expression re matches the entire str. -bool RE::FullMatch(const char* str, const RE& re) { - if (!re.is_valid_) return false; +bool RE::FullMatch(const char* str, const RE& re) +{ + if (!re.is_valid_) return false; - regmatch_t match; - return regexec(&re.full_regex_, str, 1, &match, 0) == 0; + regmatch_t match; + return regexec(&re.full_regex_, str, 1, &match, 0) == 0; } // Returns true iff regular expression re matches a substring of str // (including str itself). -bool RE::PartialMatch(const char* str, const RE& re) { - if (!re.is_valid_) return false; +bool RE::PartialMatch(const char* str, const RE& re) +{ + if (!re.is_valid_) return false; - regmatch_t match; - return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; + regmatch_t match; + return regexec(&re.partial_regex_, str, 1, &match, 0) == 0; } // Initializes an RE from its string representation. -void RE::Init(const char* regex) { - pattern_ = posix::StrDup(regex); +void RE::Init(const char* regex) +{ + pattern_ = posix::StrDup(regex); - // Reserves enough bytes to hold the regular expression used for a - // full match. - const size_t full_regex_len = strlen(regex) + 10; - char* const full_pattern = new char[full_regex_len]; + // Reserves enough bytes to hold the regular expression used for a + // full match. + const size_t full_regex_len = strlen(regex) + 10; + char* const full_pattern = new char[full_regex_len]; - snprintf(full_pattern, full_regex_len, "^(%s)$", regex); - is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; - // We want to call regcomp(&partial_regex_, ...) even if the - // previous expression returns false. Otherwise partial_regex_ may - // not be properly initialized can may cause trouble when it's - // freed. - // - // Some implementation of POSIX regex (e.g. on at least some - // versions of Cygwin) doesn't accept the empty string as a valid - // regex. We change it to an equivalent form "()" to be safe. - if (is_valid_) { - const char* const partial_regex = (*regex == '\0') ? "()" : regex; - is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; - } - EXPECT_TRUE(is_valid_) - << "Regular expression \"" << regex - << "\" is not a valid POSIX Extended regular expression."; + snprintf(full_pattern, full_regex_len, "^(%s)$", regex); + is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0; + // We want to call regcomp(&partial_regex_, ...) even if the + // previous expression returns false. Otherwise partial_regex_ may + // not be properly initialized can may cause trouble when it's + // freed. + // + // Some implementation of POSIX regex (e.g. on at least some + // versions of Cygwin) doesn't accept the empty string as a valid + // regex. We change it to an equivalent form "()" to be safe. + if (is_valid_) + { + const char* const partial_regex = (*regex == '\0') ? "()" : regex; + is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0; + } + EXPECT_TRUE(is_valid_) + << "Regular expression \"" << regex + << "\" is not a valid POSIX Extended regular expression."; - delete[] full_pattern; + delete[] full_pattern; } #elif GTEST_USES_SIMPLE_RE // Returns true iff ch appears anywhere in str (excluding the // terminating '\0' character). -bool IsInSet(char ch, const char* str) { - return ch != '\0' && strchr(str, ch) != NULL; +bool IsInSet(char ch, const char* str) +{ + return ch != '\0' && strchr(str, ch) != NULL; } // Returns true iff ch belongs to the given classification. Unlike // similar functions in , these aren't affected by the // current locale. bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; } -bool IsAsciiPunct(char ch) { - return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); +bool IsAsciiPunct(char ch) +{ + return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~"); } bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); } bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); } -bool IsAsciiWordChar(char ch) { - return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || - ('0' <= ch && ch <= '9') || ch == '_'; +bool IsAsciiWordChar(char ch) +{ + return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') || + ('0' <= ch && ch <= '9') || ch == '_'; } // Returns true iff "\\c" is a supported escape sequence. -bool IsValidEscape(char c) { - return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW")); +bool IsValidEscape(char c) +{ + return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW")); } // Returns true iff the given atom (specified by escaped and pattern) // matches ch. The result is undefined if the atom is invalid. -bool AtomMatchesChar(bool escaped, char pattern_char, char ch) { - if (escaped) { // "\\p" where p is pattern_char. - switch (pattern_char) { - case 'd': return IsAsciiDigit(ch); - case 'D': return !IsAsciiDigit(ch); - case 'f': return ch == '\f'; - case 'n': return ch == '\n'; - case 'r': return ch == '\r'; - case 's': return IsAsciiWhiteSpace(ch); - case 'S': return !IsAsciiWhiteSpace(ch); - case 't': return ch == '\t'; - case 'v': return ch == '\v'; - case 'w': return IsAsciiWordChar(ch); - case 'W': return !IsAsciiWordChar(ch); - } - return IsAsciiPunct(pattern_char) && pattern_char == ch; - } +bool AtomMatchesChar(bool escaped, char pattern_char, char ch) +{ + if (escaped) + { // "\\p" where p is pattern_char. + switch (pattern_char) + { + case 'd': + return IsAsciiDigit(ch); + case 'D': + return !IsAsciiDigit(ch); + case 'f': + return ch == '\f'; + case 'n': + return ch == '\n'; + case 'r': + return ch == '\r'; + case 's': + return IsAsciiWhiteSpace(ch); + case 'S': + return !IsAsciiWhiteSpace(ch); + case 't': + return ch == '\t'; + case 'v': + return ch == '\v'; + case 'w': + return IsAsciiWordChar(ch); + case 'W': + return !IsAsciiWordChar(ch); + } + return IsAsciiPunct(pattern_char) && pattern_char == ch; + } - return (pattern_char == '.' && ch != '\n') || pattern_char == ch; + return (pattern_char == '.' && ch != '\n') || pattern_char == ch; } // Helper function used by ValidateRegex() to format error messages. -std::string FormatRegexSyntaxError(const char* regex, int index) { - return (Message() << "Syntax error at index " << index - << " in simple regular expression \"" << regex << "\": ").GetString(); +std::string FormatRegexSyntaxError(const char* regex, int index) +{ + return (Message() << "Syntax error at index " << index + << " in simple regular expression \"" << regex << "\": ") + .GetString(); } // Generates non-fatal failures and returns false if regex is invalid; // otherwise returns true. -bool ValidateRegex(const char* regex) { - if (regex == NULL) { - // TODO(wan@google.com): fix the source file location in the - // assertion failures to match where the regex is used in user - // code. - ADD_FAILURE() << "NULL is not a valid simple regular expression."; - return false; - } +bool ValidateRegex(const char* regex) +{ + if (regex == NULL) + { + // TODO(wan@google.com): fix the source file location in the + // assertion failures to match where the regex is used in user + // code. + ADD_FAILURE() << "NULL is not a valid simple regular expression."; + return false; + } - bool is_valid = true; + bool is_valid = true; - // True iff ?, *, or + can follow the previous atom. - bool prev_repeatable = false; - for (int i = 0; regex[i]; i++) { - if (regex[i] == '\\') { // An escape sequence - i++; - if (regex[i] == '\0') { - ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) - << "'\\' cannot appear at the end."; - return false; - } + // True iff ?, *, or + can follow the previous atom. + bool prev_repeatable = false; + for (int i = 0; regex[i]; i++) + { + if (regex[i] == '\\') + { // An escape sequence + i++; + if (regex[i] == '\0') + { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "'\\' cannot appear at the end."; + return false; + } - if (!IsValidEscape(regex[i])) { - ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) - << "invalid escape sequence \"\\" << regex[i] << "\"."; - is_valid = false; - } - prev_repeatable = true; - } else { // Not an escape sequence. - const char ch = regex[i]; + if (!IsValidEscape(regex[i])) + { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1) + << "invalid escape sequence \"\\" << regex[i] << "\"."; + is_valid = false; + } + prev_repeatable = true; + } + else + { // Not an escape sequence. + const char ch = regex[i]; - if (ch == '^' && i > 0) { - ADD_FAILURE() << FormatRegexSyntaxError(regex, i) - << "'^' can only appear at the beginning."; - is_valid = false; - } else if (ch == '$' && regex[i + 1] != '\0') { - ADD_FAILURE() << FormatRegexSyntaxError(regex, i) - << "'$' can only appear at the end."; - is_valid = false; - } else if (IsInSet(ch, "()[]{}|")) { - ADD_FAILURE() << FormatRegexSyntaxError(regex, i) - << "'" << ch << "' is unsupported."; - is_valid = false; - } else if (IsRepeat(ch) && !prev_repeatable) { - ADD_FAILURE() << FormatRegexSyntaxError(regex, i) - << "'" << ch << "' can only follow a repeatable token."; - is_valid = false; - } + if (ch == '^' && i > 0) + { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'^' can only appear at the beginning."; + is_valid = false; + } + else if (ch == '$' && regex[i + 1] != '\0') + { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'$' can only appear at the end."; + is_valid = false; + } + else if (IsInSet(ch, "()[]{}|")) + { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' is unsupported."; + is_valid = false; + } + else if (IsRepeat(ch) && !prev_repeatable) + { + ADD_FAILURE() << FormatRegexSyntaxError(regex, i) + << "'" << ch << "' can only follow a repeatable token."; + is_valid = false; + } - prev_repeatable = !IsInSet(ch, "^$?*+"); - } - } + prev_repeatable = !IsInSet(ch, "^$?*+"); + } + } - return is_valid; + return is_valid; } // Matches a repeated regex atom followed by a valid simple regular @@ -318,58 +370,64 @@ bool ValidateRegex(const char* regex) { // probably time out anyway. We are fine with this limitation as // std::string has it too. bool MatchRepetitionAndRegexAtHead( - bool escaped, char c, char repeat, const char* regex, - const char* str) { - const size_t min_count = (repeat == '+') ? 1 : 0; - const size_t max_count = (repeat == '?') ? 1 : - static_cast(-1) - 1; - // We cannot call numeric_limits::max() as it conflicts with the - // max() macro on Windows. + bool escaped, char c, char repeat, const char* regex, + const char* str) +{ + const size_t min_count = (repeat == '+') ? 1 : 0; + const size_t max_count = (repeat == '?') ? 1 : static_cast(-1) - 1; + // We cannot call numeric_limits::max() as it conflicts with the + // max() macro on Windows. - for (size_t i = 0; i <= max_count; ++i) { - // We know that the atom matches each of the first i characters in str. - if (i >= min_count && MatchRegexAtHead(regex, str + i)) { - // We have enough matches at the head, and the tail matches too. - // Since we only care about *whether* the pattern matches str - // (as opposed to *how* it matches), there is no need to find a - // greedy match. - return true; - } - if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) - return false; - } - return false; + for (size_t i = 0; i <= max_count; ++i) + { + // We know that the atom matches each of the first i characters in str. + if (i >= min_count && MatchRegexAtHead(regex, str + i)) + { + // We have enough matches at the head, and the tail matches too. + // Since we only care about *whether* the pattern matches str + // (as opposed to *how* it matches), there is no need to find a + // greedy match. + return true; + } + if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) + return false; + } + return false; } // Returns true iff regex matches a prefix of str. regex must be a // valid simple regular expression and not start with "^", or the // result is undefined. -bool MatchRegexAtHead(const char* regex, const char* str) { - if (*regex == '\0') // An empty regex matches a prefix of anything. - return true; +bool MatchRegexAtHead(const char* regex, const char* str) +{ + if (*regex == '\0') // An empty regex matches a prefix of anything. + return true; - // "$" only matches the end of a string. Note that regex being - // valid guarantees that there's nothing after "$" in it. - if (*regex == '$') - return *str == '\0'; + // "$" only matches the end of a string. Note that regex being + // valid guarantees that there's nothing after "$" in it. + if (*regex == '$') + return *str == '\0'; - // Is the first thing in regex an escape sequence? - const bool escaped = *regex == '\\'; - if (escaped) - ++regex; - if (IsRepeat(regex[1])) { - // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so - // here's an indirect recursion. It terminates as the regex gets - // shorter in each recursion. - return MatchRepetitionAndRegexAtHead( - escaped, regex[0], regex[1], regex + 2, str); - } else { - // regex isn't empty, isn't "$", and doesn't start with a - // repetition. We match the first atom of regex with the first - // character of str and recurse. - return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && - MatchRegexAtHead(regex + 1, str + 1); - } + // Is the first thing in regex an escape sequence? + const bool escaped = *regex == '\\'; + if (escaped) + ++regex; + if (IsRepeat(regex[1])) + { + // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so + // here's an indirect recursion. It terminates as the regex gets + // shorter in each recursion. + return MatchRepetitionAndRegexAtHead( + escaped, regex[0], regex[1], regex + 2, str); + } + else + { + // regex isn't empty, isn't "$", and doesn't start with a + // repetition. We match the first atom of regex with the first + // character of str and recurse. + return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) && + MatchRegexAtHead(regex + 1, str + 1); + } } // Returns true iff regex matches any substring of str. regex must be @@ -380,71 +438,79 @@ bool MatchRegexAtHead(const char* regex, const char* str) { // stack space normally. In rare cases the time complexity can be // exponential with respect to the regex length + the string length, // but usually it's must faster (often close to linear). -bool MatchRegexAnywhere(const char* regex, const char* str) { - if (regex == NULL || str == NULL) - return false; +bool MatchRegexAnywhere(const char* regex, const char* str) +{ + if (regex == NULL || str == NULL) + return false; - if (*regex == '^') - return MatchRegexAtHead(regex + 1, str); + if (*regex == '^') + return MatchRegexAtHead(regex + 1, str); - // A successful match can be anywhere in str. - do { - if (MatchRegexAtHead(regex, str)) - return true; - } while (*str++ != '\0'); - return false; + // A successful match can be anywhere in str. + do + { + if (MatchRegexAtHead(regex, str)) + return true; + } while (*str++ != '\0'); + return false; } // Implements the RE class. -RE::~RE() { - free(const_cast(pattern_)); - free(const_cast(full_pattern_)); +RE::~RE() +{ + free(const_cast(pattern_)); + free(const_cast(full_pattern_)); } // Returns true iff regular expression re matches the entire str. -bool RE::FullMatch(const char* str, const RE& re) { - return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); +bool RE::FullMatch(const char* str, const RE& re) +{ + return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str); } // Returns true iff regular expression re matches a substring of str // (including str itself). -bool RE::PartialMatch(const char* str, const RE& re) { - return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); +bool RE::PartialMatch(const char* str, const RE& re) +{ + return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str); } // Initializes an RE from its string representation. -void RE::Init(const char* regex) { - pattern_ = full_pattern_ = NULL; - if (regex != NULL) { - pattern_ = posix::StrDup(regex); - } +void RE::Init(const char* regex) +{ + pattern_ = full_pattern_ = NULL; + if (regex != NULL) + { + pattern_ = posix::StrDup(regex); + } - is_valid_ = ValidateRegex(regex); - if (!is_valid_) { - // No need to calculate the full pattern when the regex is invalid. - return; - } + is_valid_ = ValidateRegex(regex); + if (!is_valid_) + { + // No need to calculate the full pattern when the regex is invalid. + return; + } - const size_t len = strlen(regex); - // Reserves enough bytes to hold the regular expression used for a - // full match: we need space to prepend a '^', append a '$', and - // terminate the string with '\0'. - char* buffer = static_cast(malloc(len + 3)); - full_pattern_ = buffer; + const size_t len = strlen(regex); + // Reserves enough bytes to hold the regular expression used for a + // full match: we need space to prepend a '^', append a '$', and + // terminate the string with '\0'. + char* buffer = static_cast(malloc(len + 3)); + full_pattern_ = buffer; - if (*regex != '^') - *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. + if (*regex != '^') + *buffer++ = '^'; // Makes sure full_pattern_ starts with '^'. - // We don't use snprintf or strncpy, as they trigger a warning when - // compiled with VC++ 8.0. - memcpy(buffer, regex, len); - buffer += len; + // We don't use snprintf or strncpy, as they trigger a warning when + // compiled with VC++ 8.0. + memcpy(buffer, regex, len); + buffer += len; - if (len == 0 || regex[len - 1] != '$') - *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. + if (len == 0 || regex[len - 1] != '$') + *buffer++ = '$'; // Makes sure full_pattern_ ends with '$'. - *buffer = '\0'; + *buffer = '\0'; } #endif // GTEST_USES_POSIX_RE @@ -453,16 +519,18 @@ const char kUnknownFile[] = "unknown file"; // Formats a source file path and a line number as they would appear // in an error message from the compiler used to compile this code. -GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { - const std::string file_name(file == NULL ? kUnknownFile : file); +GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) +{ + const std::string file_name(file == NULL ? kUnknownFile : file); - if (line < 0) { - return file_name + ":"; - } + if (line < 0) + { + return file_name + ":"; + } #ifdef _MSC_VER - return file_name + "(" + StreamableToString(line) + "):"; + return file_name + "(" + StreamableToString(line) + "):"; #else - return file_name + ":" + StreamableToString(line) + ":"; + return file_name + ":" + StreamableToString(line) + ":"; #endif // _MSC_VER } @@ -472,202 +540,219 @@ GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { // Note that FormatCompilerIndependentFileLocation() does NOT append colon // to the file location it produces, unlike FormatFileLocation(). GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( - const char* file, int line) { - const std::string file_name(file == NULL ? kUnknownFile : file); + const char* file, int line) +{ + const std::string file_name(file == NULL ? kUnknownFile : file); - if (line < 0) - return file_name; - else - return file_name + ":" + StreamableToString(line); + if (line < 0) + return file_name; + else + return file_name + ":" + StreamableToString(line); } - GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) - : severity_(severity) { - const char* const marker = - severity == GTEST_INFO ? "[ INFO ]" : - severity == GTEST_WARNING ? "[WARNING]" : - severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; - GetStream() << ::std::endl << marker << " " - << FormatFileLocation(file, line).c_str() << ": "; + : severity_(severity) +{ + const char* const marker = + severity == GTEST_INFO ? "[ INFO ]" : severity == GTEST_WARNING ? "[WARNING]" : severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]"; + GetStream() << ::std::endl + << marker << " " + << FormatFileLocation(file, line).c_str() << ": "; } // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program. -GTestLog::~GTestLog() { - GetStream() << ::std::endl; - if (severity_ == GTEST_FATAL) { - fflush(stderr); - posix::Abort(); - } +GTestLog::~GTestLog() +{ + GetStream() << ::std::endl; + if (severity_ == GTEST_FATAL) + { + fflush(stderr); + posix::Abort(); + } } // Disable Microsoft deprecation warnings for POSIX functions called from // this class (creat, dup, dup2, and close) #ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable: 4996) +#pragma warning(push) +#pragma warning(disable : 4996) #endif // _MSC_VER #if GTEST_HAS_STREAM_REDIRECTION // Object that captures an output stream (stdout/stderr). -class CapturedStream { - public: - // The ctor redirects the stream to a temporary file. - explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) { -# if GTEST_OS_WINDOWS - char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT - char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT +class CapturedStream +{ +public: + // The ctor redirects the stream to a temporary file. + explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) + { +#if GTEST_OS_WINDOWS + char temp_dir_path[MAX_PATH + 1] = {'\0'}; // NOLINT + char temp_file_path[MAX_PATH + 1] = {'\0'}; // NOLINT - ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); - const UINT success = ::GetTempFileNameA(temp_dir_path, - "gtest_redir", - 0, // Generate unique file name. - temp_file_path); - GTEST_CHECK_(success != 0) - << "Unable to create a temporary file in " << temp_dir_path; - const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); - GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " - << temp_file_path; - filename_ = temp_file_path; -# else - // There's no guarantee that a test has write access to the current - // directory, so we create the temporary file in the /tmp directory - // instead. We use /tmp on most systems, and /sdcard on Android. - // That's because Android doesn't have /tmp. -# if GTEST_OS_LINUX_ANDROID - // Note: Android applications are expected to call the framework's - // Context.getExternalStorageDirectory() method through JNI to get - // the location of the world-writable SD Card directory. However, - // this requires a Context handle, which cannot be retrieved - // globally from native code. Doing so also precludes running the - // code as part of a regular standalone executable, which doesn't - // run in a Dalvik process (e.g. when running it through 'adb shell'). - // - // The location /sdcard is directly accessible from native code - // and is the only location (unofficially) supported by the Android - // team. It's generally a symlink to the real SD Card mount point - // which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or - // other OEM-customized locations. Never rely on these, and always - // use /sdcard. - char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX"; -# else - char name_template[] = "/tmp/captured_stream.XXXXXX"; -# endif // GTEST_OS_LINUX_ANDROID - const int captured_fd = mkstemp(name_template); - filename_ = name_template; -# endif // GTEST_OS_WINDOWS - fflush(NULL); - dup2(captured_fd, fd_); - close(captured_fd); - } + ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path); + const UINT success = ::GetTempFileNameA(temp_dir_path, + "gtest_redir", + 0, // Generate unique file name. + temp_file_path); + GTEST_CHECK_(success != 0) + << "Unable to create a temporary file in " << temp_dir_path; + const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE); + GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file " + << temp_file_path; + filename_ = temp_file_path; +#else + // There's no guarantee that a test has write access to the current + // directory, so we create the temporary file in the /tmp directory + // instead. We use /tmp on most systems, and /sdcard on Android. + // That's because Android doesn't have /tmp. +#if GTEST_OS_LINUX_ANDROID + // Note: Android applications are expected to call the framework's + // Context.getExternalStorageDirectory() method through JNI to get + // the location of the world-writable SD Card directory. However, + // this requires a Context handle, which cannot be retrieved + // globally from native code. Doing so also precludes running the + // code as part of a regular standalone executable, which doesn't + // run in a Dalvik process (e.g. when running it through 'adb shell'). + // + // The location /sdcard is directly accessible from native code + // and is the only location (unofficially) supported by the Android + // team. It's generally a symlink to the real SD Card mount point + // which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or + // other OEM-customized locations. Never rely on these, and always + // use /sdcard. + char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX"; +#else + char name_template[] = "/tmp/captured_stream.XXXXXX"; +#endif // GTEST_OS_LINUX_ANDROID + const int captured_fd = mkstemp(name_template); + filename_ = name_template; +#endif // GTEST_OS_WINDOWS + fflush(NULL); + dup2(captured_fd, fd_); + close(captured_fd); + } - ~CapturedStream() { - remove(filename_.c_str()); - } + ~CapturedStream() + { + remove(filename_.c_str()); + } - std::string GetCapturedString() { - if (uncaptured_fd_ != -1) { - // Restores the original stream. - fflush(NULL); - dup2(uncaptured_fd_, fd_); - close(uncaptured_fd_); - uncaptured_fd_ = -1; - } + std::string GetCapturedString() + { + if (uncaptured_fd_ != -1) + { + // Restores the original stream. + fflush(NULL); + dup2(uncaptured_fd_, fd_); + close(uncaptured_fd_); + uncaptured_fd_ = -1; + } - FILE* const file = posix::FOpen(filename_.c_str(), "r"); - const std::string content = ReadEntireFile(file); - posix::FClose(file); - return content; - } + FILE* const file = posix::FOpen(filename_.c_str(), "r"); + const std::string content = ReadEntireFile(file); + posix::FClose(file); + return content; + } - private: - // Reads the entire content of a file as an std::string. - static std::string ReadEntireFile(FILE* file); +private: + // Reads the entire content of a file as an std::string. + static std::string ReadEntireFile(FILE* file); - // Returns the size (in bytes) of a file. - static size_t GetFileSize(FILE* file); + // Returns the size (in bytes) of a file. + static size_t GetFileSize(FILE* file); - const int fd_; // A stream to capture. - int uncaptured_fd_; - // Name of the temporary file holding the stderr output. - ::std::string filename_; + const int fd_; // A stream to capture. + int uncaptured_fd_; + // Name of the temporary file holding the stderr output. + ::std::string filename_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); + GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream); }; // Returns the size (in bytes) of a file. -size_t CapturedStream::GetFileSize(FILE* file) { - fseek(file, 0, SEEK_END); - return static_cast(ftell(file)); +size_t CapturedStream::GetFileSize(FILE* file) +{ + fseek(file, 0, SEEK_END); + return static_cast(ftell(file)); } // Reads the entire content of a file as a string. -std::string CapturedStream::ReadEntireFile(FILE* file) { - const size_t file_size = GetFileSize(file); - char* const buffer = new char[file_size]; +std::string CapturedStream::ReadEntireFile(FILE* file) +{ + const size_t file_size = GetFileSize(file); + char* const buffer = new char[file_size]; - size_t bytes_last_read = 0; // # of bytes read in the last fread() - size_t bytes_read = 0; // # of bytes read so far + size_t bytes_last_read = 0; // # of bytes read in the last fread() + size_t bytes_read = 0; // # of bytes read so far - fseek(file, 0, SEEK_SET); + fseek(file, 0, SEEK_SET); - // Keeps reading the file until we cannot read further or the - // pre-determined file size is reached. - do { - bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file); - bytes_read += bytes_last_read; - } while (bytes_last_read > 0 && bytes_read < file_size); + // Keeps reading the file until we cannot read further or the + // pre-determined file size is reached. + do + { + bytes_last_read = fread(buffer + bytes_read, 1, file_size - bytes_read, file); + bytes_read += bytes_last_read; + } while (bytes_last_read > 0 && bytes_read < file_size); - const std::string content(buffer, bytes_read); - delete[] buffer; + const std::string content(buffer, bytes_read); + delete[] buffer; - return content; + return content; } -# ifdef _MSC_VER -# pragma warning(pop) -# endif // _MSC_VER +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER static CapturedStream* g_captured_stderr = NULL; static CapturedStream* g_captured_stdout = NULL; // Starts capturing an output stream (stdout/stderr). -void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) { - if (*stream != NULL) { - GTEST_LOG_(FATAL) << "Only one " << stream_name - << " capturer can exist at a time."; - } - *stream = new CapturedStream(fd); +void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) +{ + if (*stream != NULL) + { + GTEST_LOG_(FATAL) << "Only one " << stream_name + << " capturer can exist at a time."; + } + *stream = new CapturedStream(fd); } // Stops capturing the output stream and returns the captured string. -std::string GetCapturedStream(CapturedStream** captured_stream) { - const std::string content = (*captured_stream)->GetCapturedString(); +std::string GetCapturedStream(CapturedStream** captured_stream) +{ + const std::string content = (*captured_stream)->GetCapturedString(); - delete *captured_stream; - *captured_stream = NULL; + delete *captured_stream; + *captured_stream = NULL; - return content; + return content; } // Starts capturing stdout. -void CaptureStdout() { - CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); +void CaptureStdout() +{ + CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout); } // Starts capturing stderr. -void CaptureStderr() { - CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); +void CaptureStderr() +{ + CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr); } // Stops capturing stdout and returns the captured string. -std::string GetCapturedStdout() { - return GetCapturedStream(&g_captured_stdout); +std::string GetCapturedStdout() +{ + return GetCapturedStream(&g_captured_stdout); } // Stops capturing stderr and returns the captured string. -std::string GetCapturedStderr() { - return GetCapturedStream(&g_captured_stderr); +std::string GetCapturedStderr() +{ + return GetCapturedStream(&g_captured_stderr); } #endif // GTEST_HAS_STREAM_REDIRECTION @@ -678,27 +763,32 @@ std::string GetCapturedStderr() { ::std::vector g_argvs; static const ::std::vector* g_injected_test_argvs = - NULL; // Owned. + NULL; // Owned. -void SetInjectableArgvs(const ::std::vector* argvs) { - if (g_injected_test_argvs != argvs) - delete g_injected_test_argvs; - g_injected_test_argvs = argvs; +void SetInjectableArgvs(const ::std::vector* argvs) +{ + if (g_injected_test_argvs != argvs) + delete g_injected_test_argvs; + g_injected_test_argvs = argvs; } -const ::std::vector& GetInjectableArgvs() { - if (g_injected_test_argvs != NULL) { - return *g_injected_test_argvs; - } - return g_argvs; +const ::std::vector& GetInjectableArgvs() +{ + if (g_injected_test_argvs != NULL) + { + return *g_injected_test_argvs; + } + return g_argvs; } #endif // GTEST_HAS_DEATH_TEST #if GTEST_OS_WINDOWS_MOBILE -namespace posix { -void Abort() { - DebugBreak(); - TerminateProcess(GetCurrentProcess(), 1); +namespace posix +{ +void Abort() +{ + DebugBreak(); + TerminateProcess(GetCurrentProcess(), 1); } } // namespace posix #endif // GTEST_OS_WINDOWS_MOBILE @@ -706,99 +796,108 @@ void Abort() { // Returns the name of the environment variable corresponding to the // given flag. For example, FlagToEnvVar("foo") will return // "GTEST_FOO" in the open-source version. -static std::string FlagToEnvVar(const char* flag) { - const std::string full_flag = - (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); +static std::string FlagToEnvVar(const char* flag) +{ + const std::string full_flag = + (Message() << GTEST_FLAG_PREFIX_ << flag).GetString(); - Message env_var; - for (size_t i = 0; i != full_flag.length(); i++) { - env_var << ToUpper(full_flag.c_str()[i]); - } + Message env_var; + for (size_t i = 0; i != full_flag.length(); i++) + { + env_var << ToUpper(full_flag.c_str()[i]); + } - return env_var.GetString(); + return env_var.GetString(); } // Parses 'str' for a 32-bit signed integer. If successful, writes // the result to *value and returns true; otherwise leaves *value // unchanged and returns false. -bool ParseInt32(const Message& src_text, const char* str, Int32* value) { - // Parses the environment variable as a decimal integer. - char* end = NULL; - const long long_value = strtol(str, &end, 10); // NOLINT +bool ParseInt32(const Message& src_text, const char* str, Int32* value) +{ + // Parses the environment variable as a decimal integer. + char* end = NULL; + const long long_value = strtol(str, &end, 10); // NOLINT - // Has strtol() consumed all characters in the string? - if (*end != '\0') { - // No - an invalid character was encountered. - Message msg; - msg << "WARNING: " << src_text - << " is expected to be a 32-bit integer, but actually" - << " has value \"" << str << "\".\n"; - printf("%s", msg.GetString().c_str()); - fflush(stdout); - return false; - } + // Has strtol() consumed all characters in the string? + if (*end != '\0') + { + // No - an invalid character was encountered. + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value \"" << str << "\".\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } - // Is the parsed value in the range of an Int32? - const Int32 result = static_cast(long_value); - if (long_value == LONG_MAX || long_value == LONG_MIN || - // The parsed value overflows as a long. (strtol() returns - // LONG_MAX or LONG_MIN when the input overflows.) - result != long_value - // The parsed value overflows as an Int32. - ) { - Message msg; - msg << "WARNING: " << src_text - << " is expected to be a 32-bit integer, but actually" - << " has value " << str << ", which overflows.\n"; - printf("%s", msg.GetString().c_str()); - fflush(stdout); - return false; - } + // Is the parsed value in the range of an Int32? + const Int32 result = static_cast(long_value); + if (long_value == LONG_MAX || long_value == LONG_MIN || + // The parsed value overflows as a long. (strtol() returns + // LONG_MAX or LONG_MIN when the input overflows.) + result != long_value + // The parsed value overflows as an Int32. + ) + { + Message msg; + msg << "WARNING: " << src_text + << " is expected to be a 32-bit integer, but actually" + << " has value " << str << ", which overflows.\n"; + printf("%s", msg.GetString().c_str()); + fflush(stdout); + return false; + } - *value = result; - return true; + *value = result; + return true; } // Reads and returns the Boolean environment variable corresponding to // the given flag; if it's not set, returns default_value. // // The value is considered true iff it's not "0". -bool BoolFromGTestEnv(const char* flag, bool default_value) { - const std::string env_var = FlagToEnvVar(flag); - const char* const string_value = posix::GetEnv(env_var.c_str()); - return string_value == NULL ? - default_value : strcmp(string_value, "0") != 0; +bool BoolFromGTestEnv(const char* flag, bool default_value) +{ + const std::string env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + return string_value == NULL ? default_value : strcmp(string_value, "0") != 0; } // Reads and returns a 32-bit integer stored in the environment // variable corresponding to the given flag; if it isn't set or // doesn't represent a valid 32-bit integer, returns default_value. -Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) { - const std::string env_var = FlagToEnvVar(flag); - const char* const string_value = posix::GetEnv(env_var.c_str()); - if (string_value == NULL) { - // The environment variable is not set. - return default_value; - } +Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) +{ + const std::string env_var = FlagToEnvVar(flag); + const char* const string_value = posix::GetEnv(env_var.c_str()); + if (string_value == NULL) + { + // The environment variable is not set. + return default_value; + } - Int32 result = default_value; - if (!ParseInt32(Message() << "Environment variable " << env_var, - string_value, &result)) { - printf("The default value %s is used.\n", - (Message() << default_value).GetString().c_str()); - fflush(stdout); - return default_value; - } + Int32 result = default_value; + if (!ParseInt32(Message() << "Environment variable " << env_var, + string_value, &result)) + { + printf("The default value %s is used.\n", + (Message() << default_value).GetString().c_str()); + fflush(stdout); + return default_value; + } - return result; + return result; } // Reads and returns the string environment variable corresponding to // the given flag; if it's not set, returns default_value. -const char* StringFromGTestEnv(const char* flag, const char* default_value) { - const std::string env_var = FlagToEnvVar(flag); - const char* const value = posix::GetEnv(env_var.c_str()); - return value == NULL ? default_value : value; +const char* StringFromGTestEnv(const char* flag, const char* default_value) +{ + const std::string env_var = FlagToEnvVar(flag); + const char* const value = posix::GetEnv(env_var.c_str()); + return value == NULL ? default_value : value; } } // namespace internal diff --git a/test/gtest-1.7.0/src/gtest-printers.cc b/test/gtest-1.7.0/src/gtest-printers.cc index 75fa40810..57c58944a 100644 --- a/test/gtest-1.7.0/src/gtest-printers.cc +++ b/test/gtest-1.7.0/src/gtest-printers.cc @@ -49,89 +49,99 @@ #include #include "gtest/internal/gtest-port.h" -namespace testing { - -namespace { - +namespace testing +{ +namespace +{ using ::std::ostream; // Prints a segment of bytes in the given object. void PrintByteSegmentInObjectTo(const unsigned char* obj_bytes, size_t start, - size_t count, ostream* os) { - char text[5] = ""; - for (size_t i = 0; i != count; i++) { - const size_t j = start + i; - if (i != 0) { - // Organizes the bytes into groups of 2 for easy parsing by - // human. - if ((j % 2) == 0) - *os << ' '; - else - *os << '-'; - } - GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]); - *os << text; - } + size_t count, ostream* os) +{ + char text[5] = ""; + for (size_t i = 0; i != count; i++) + { + const size_t j = start + i; + if (i != 0) + { + // Organizes the bytes into groups of 2 for easy parsing by + // human. + if ((j % 2) == 0) + *os << ' '; + else + *os << '-'; + } + GTEST_SNPRINTF_(text, sizeof(text), "%02X", obj_bytes[j]); + *os << text; + } } // Prints the bytes in the given value to the given ostream. void PrintBytesInObjectToImpl(const unsigned char* obj_bytes, size_t count, - ostream* os) { - // Tells the user how big the object is. - *os << count << "-byte object <"; + ostream* os) +{ + // Tells the user how big the object is. + *os << count << "-byte object <"; - const size_t kThreshold = 132; - const size_t kChunkSize = 64; - // If the object size is bigger than kThreshold, we'll have to omit - // some details by printing only the first and the last kChunkSize - // bytes. - // TODO(wan): let the user control the threshold using a flag. - if (count < kThreshold) { - PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); - } else { - PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); - *os << " ... "; - // Rounds up to 2-byte boundary. - const size_t resume_pos = (count - kChunkSize + 1)/2*2; - PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); - } - *os << ">"; + const size_t kThreshold = 132; + const size_t kChunkSize = 64; + // If the object size is bigger than kThreshold, we'll have to omit + // some details by printing only the first and the last kChunkSize + // bytes. + // TODO(wan): let the user control the threshold using a flag. + if (count < kThreshold) + { + PrintByteSegmentInObjectTo(obj_bytes, 0, count, os); + } + else + { + PrintByteSegmentInObjectTo(obj_bytes, 0, kChunkSize, os); + *os << " ... "; + // Rounds up to 2-byte boundary. + const size_t resume_pos = (count - kChunkSize + 1) / 2 * 2; + PrintByteSegmentInObjectTo(obj_bytes, resume_pos, count - resume_pos, os); + } + *os << ">"; } } // namespace -namespace internal2 { - +namespace internal2 +{ // Delegates to PrintBytesInObjectToImpl() to print the bytes in the // given object. The delegation simplifies the implementation, which // uses the << operator and thus is easier done outside of the // ::testing::internal namespace, which contains a << operator that // sometimes conflicts with the one in STL. void PrintBytesInObjectTo(const unsigned char* obj_bytes, size_t count, - ostream* os) { - PrintBytesInObjectToImpl(obj_bytes, count, os); + ostream* os) +{ + PrintBytesInObjectToImpl(obj_bytes, count, os); } } // namespace internal2 -namespace internal { - +namespace internal +{ // Depending on the value of a char (or wchar_t), we print it in one // of three formats: // - as is if it's a printable ASCII (e.g. 'a', '2', ' '), // - as a hexidecimal escape sequence (e.g. '\x7F'), or // - as a special escape sequence (e.g. '\r', '\n'). -enum CharFormat { - kAsIs, - kHexEscape, - kSpecialEscape +enum CharFormat +{ + kAsIs, + kHexEscape, + kSpecialEscape }; // Returns true if c is a printable ASCII character. We test the // value of c directly instead of calling isprint(), which is buggy on // Windows Mobile. -inline bool IsPrintableAscii(wchar_t c) { - return 0x20 <= c && c <= 0x7E; +inline bool IsPrintableAscii(wchar_t c) +{ + return 0x20 <= c && c <= 0x7E; } // Prints a wide or narrow char c as a character literal without the @@ -139,70 +149,78 @@ inline bool IsPrintableAscii(wchar_t c) { // The template argument UnsignedChar is the unsigned version of Char, // which is the type of c. template -static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) { - switch (static_cast(c)) { - case L'\0': - *os << "\\0"; - break; - case L'\'': - *os << "\\'"; - break; - case L'\\': - *os << "\\\\"; - break; - case L'\a': - *os << "\\a"; - break; - case L'\b': - *os << "\\b"; - break; - case L'\f': - *os << "\\f"; - break; - case L'\n': - *os << "\\n"; - break; - case L'\r': - *os << "\\r"; - break; - case L'\t': - *os << "\\t"; - break; - case L'\v': - *os << "\\v"; - break; - default: - if (IsPrintableAscii(c)) { - *os << static_cast(c); - return kAsIs; - } else { - *os << "\\x" + String::FormatHexInt(static_cast(c)); - return kHexEscape; - } - } - return kSpecialEscape; +static CharFormat PrintAsCharLiteralTo(Char c, ostream* os) +{ + switch (static_cast(c)) + { + case L'\0': + *os << "\\0"; + break; + case L'\'': + *os << "\\'"; + break; + case L'\\': + *os << "\\\\"; + break; + case L'\a': + *os << "\\a"; + break; + case L'\b': + *os << "\\b"; + break; + case L'\f': + *os << "\\f"; + break; + case L'\n': + *os << "\\n"; + break; + case L'\r': + *os << "\\r"; + break; + case L'\t': + *os << "\\t"; + break; + case L'\v': + *os << "\\v"; + break; + default: + if (IsPrintableAscii(c)) + { + *os << static_cast(c); + return kAsIs; + } + else + { + *os << "\\x" + String::FormatHexInt(static_cast(c)); + return kHexEscape; + } + } + return kSpecialEscape; } // Prints a wchar_t c as if it's part of a string literal, escaping it when // necessary; returns how c was formatted. -static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) { - switch (c) { - case L'\'': - *os << "'"; - return kAsIs; - case L'"': - *os << "\\\""; - return kSpecialEscape; - default: - return PrintAsCharLiteralTo(c, os); - } +static CharFormat PrintAsStringLiteralTo(wchar_t c, ostream* os) +{ + switch (c) + { + case L'\'': + *os << "'"; + return kAsIs; + case L'"': + *os << "\\\""; + return kSpecialEscape; + default: + return PrintAsCharLiteralTo(c, os); + } } // Prints a char c as if it's part of a string literal, escaping it when // necessary; returns how c was formatted. -static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { - return PrintAsStringLiteralTo( - static_cast(static_cast(c)), os); +static CharFormat PrintAsStringLiteralTo(char c, ostream* os) +{ + return PrintAsStringLiteralTo( + static_cast(static_cast(c)), os); } // Prints a wide or narrow character c and its code. '\0' is printed @@ -210,41 +228,48 @@ static CharFormat PrintAsStringLiteralTo(char c, ostream* os) { // using the standard C++ escape sequence. The template argument // UnsignedChar is the unsigned version of Char, which is the type of c. template -void PrintCharAndCodeTo(Char c, ostream* os) { - // First, print c as a literal in the most readable form we can find. - *os << ((sizeof(c) > 1) ? "L'" : "'"); - const CharFormat format = PrintAsCharLiteralTo(c, os); - *os << "'"; +void PrintCharAndCodeTo(Char c, ostream* os) +{ + // First, print c as a literal in the most readable form we can find. + *os << ((sizeof(c) > 1) ? "L'" : "'"); + const CharFormat format = PrintAsCharLiteralTo(c, os); + *os << "'"; - // To aid user debugging, we also print c's code in decimal, unless - // it's 0 (in which case c was printed as '\\0', making the code - // obvious). - if (c == 0) - return; - *os << " (" << static_cast(c); + // To aid user debugging, we also print c's code in decimal, unless + // it's 0 (in which case c was printed as '\\0', making the code + // obvious). + if (c == 0) + return; + *os << " (" << static_cast(c); - // For more convenience, we print c's code again in hexidecimal, - // unless c was already printed in the form '\x##' or the code is in - // [1, 9]. - if (format == kHexEscape || (1 <= c && c <= 9)) { - // Do nothing. - } else { - *os << ", 0x" << String::FormatHexInt(static_cast(c)); - } - *os << ")"; + // For more convenience, we print c's code again in hexidecimal, + // unless c was already printed in the form '\x##' or the code is in + // [1, 9]. + if (format == kHexEscape || (1 <= c && c <= 9)) + { + // Do nothing. + } + else + { + *os << ", 0x" << String::FormatHexInt(static_cast(c)); + } + *os << ")"; } -void PrintTo(unsigned char c, ::std::ostream* os) { - PrintCharAndCodeTo(c, os); +void PrintTo(unsigned char c, ::std::ostream* os) +{ + PrintCharAndCodeTo(c, os); } -void PrintTo(signed char c, ::std::ostream* os) { - PrintCharAndCodeTo(c, os); +void PrintTo(signed char c, ::std::ostream* os) +{ + PrintCharAndCodeTo(c, os); } // Prints a wchar_t as a symbol if it is printable or as its internal // code otherwise and also as its code. L'\0' is printed as "L'\\0'". -void PrintTo(wchar_t wc, ostream* os) { - PrintCharAndCodeTo(wc, os); +void PrintTo(wchar_t wc, ostream* os) +{ + PrintCharAndCodeTo(wc, os); } // Prints the given array of characters to the ostream. CharType must be either @@ -253,67 +278,78 @@ void PrintTo(wchar_t wc, ostream* os) { // and may not be NUL-terminated. template static void PrintCharsAsStringTo( - const CharType* begin, size_t len, ostream* os) { - const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; - *os << kQuoteBegin; - bool is_previous_hex = false; - for (size_t index = 0; index < len; ++index) { - const CharType cur = begin[index]; - if (is_previous_hex && IsXDigit(cur)) { - // Previous character is of '\x..' form and this character can be - // interpreted as another hexadecimal digit in its number. Break string to - // disambiguate. - *os << "\" " << kQuoteBegin; - } - is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; - } - *os << "\""; + const CharType* begin, size_t len, ostream* os) +{ + const char* const kQuoteBegin = sizeof(CharType) == 1 ? "\"" : "L\""; + *os << kQuoteBegin; + bool is_previous_hex = false; + for (size_t index = 0; index < len; ++index) + { + const CharType cur = begin[index]; + if (is_previous_hex && IsXDigit(cur)) + { + // Previous character is of '\x..' form and this character can be + // interpreted as another hexadecimal digit in its number. Break string to + // disambiguate. + *os << "\" " << kQuoteBegin; + } + is_previous_hex = PrintAsStringLiteralTo(cur, os) == kHexEscape; + } + *os << "\""; } // Prints a (const) char/wchar_t array of 'len' elements, starting at address // 'begin'. CharType must be either char or wchar_t. template static void UniversalPrintCharArray( - const CharType* begin, size_t len, ostream* os) { - // The code - // const char kFoo[] = "foo"; - // generates an array of 4, not 3, elements, with the last one being '\0'. - // - // Therefore when printing a char array, we don't print the last element if - // it's '\0', such that the output matches the string literal as it's - // written in the source code. - if (len > 0 && begin[len - 1] == '\0') { - PrintCharsAsStringTo(begin, len - 1, os); - return; - } + const CharType* begin, size_t len, ostream* os) +{ + // The code + // const char kFoo[] = "foo"; + // generates an array of 4, not 3, elements, with the last one being '\0'. + // + // Therefore when printing a char array, we don't print the last element if + // it's '\0', such that the output matches the string literal as it's + // written in the source code. + if (len > 0 && begin[len - 1] == '\0') + { + PrintCharsAsStringTo(begin, len - 1, os); + return; + } - // If, however, the last element in the array is not '\0', e.g. - // const char kFoo[] = { 'f', 'o', 'o' }; - // we must print the entire array. We also print a message to indicate - // that the array is not NUL-terminated. - PrintCharsAsStringTo(begin, len, os); - *os << " (no terminating NUL)"; + // If, however, the last element in the array is not '\0', e.g. + // const char kFoo[] = { 'f', 'o', 'o' }; + // we must print the entire array. We also print a message to indicate + // that the array is not NUL-terminated. + PrintCharsAsStringTo(begin, len, os); + *os << " (no terminating NUL)"; } // Prints a (const) char array of 'len' elements, starting at address 'begin'. -void UniversalPrintArray(const char* begin, size_t len, ostream* os) { - UniversalPrintCharArray(begin, len, os); +void UniversalPrintArray(const char* begin, size_t len, ostream* os) +{ + UniversalPrintCharArray(begin, len, os); } // Prints a (const) wchar_t array of 'len' elements, starting at address // 'begin'. -void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) { - UniversalPrintCharArray(begin, len, os); +void UniversalPrintArray(const wchar_t* begin, size_t len, ostream* os) +{ + UniversalPrintCharArray(begin, len, os); } // Prints the given C string to the ostream. -void PrintTo(const char* s, ostream* os) { - if (s == NULL) { - *os << "NULL"; - } else { - *os << ImplicitCast_(s) << " pointing to "; - PrintCharsAsStringTo(s, strlen(s), os); - } +void PrintTo(const char* s, ostream* os) +{ + if (s == NULL) + { + *os << "NULL"; + } + else + { + *os << ImplicitCast_(s) << " pointing to "; + PrintCharsAsStringTo(s, strlen(s), os); + } } // MSVC compiler can be configured to define whar_t as a typedef @@ -324,37 +360,45 @@ void PrintTo(const char* s, ostream* os) { // wchar_t is implemented as a native type. #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) // Prints the given wide C string to the ostream. -void PrintTo(const wchar_t* s, ostream* os) { - if (s == NULL) { - *os << "NULL"; - } else { - *os << ImplicitCast_(s) << " pointing to "; - PrintCharsAsStringTo(s, wcslen(s), os); - } +void PrintTo(const wchar_t* s, ostream* os) +{ + if (s == NULL) + { + *os << "NULL"; + } + else + { + *os << ImplicitCast_(s) << " pointing to "; + PrintCharsAsStringTo(s, wcslen(s), os); + } } #endif // wchar_t is native // Prints a ::string object. #if GTEST_HAS_GLOBAL_STRING -void PrintStringTo(const ::string& s, ostream* os) { - PrintCharsAsStringTo(s.data(), s.size(), os); +void PrintStringTo(const ::string& s, ostream* os) +{ + PrintCharsAsStringTo(s.data(), s.size(), os); } #endif // GTEST_HAS_GLOBAL_STRING -void PrintStringTo(const ::std::string& s, ostream* os) { - PrintCharsAsStringTo(s.data(), s.size(), os); +void PrintStringTo(const ::std::string& s, ostream* os) +{ + PrintCharsAsStringTo(s.data(), s.size(), os); } // Prints a ::wstring object. #if GTEST_HAS_GLOBAL_WSTRING -void PrintWideStringTo(const ::wstring& s, ostream* os) { - PrintCharsAsStringTo(s.data(), s.size(), os); +void PrintWideStringTo(const ::wstring& s, ostream* os) +{ + PrintCharsAsStringTo(s.data(), s.size(), os); } #endif // GTEST_HAS_GLOBAL_WSTRING #if GTEST_HAS_STD_WSTRING -void PrintWideStringTo(const ::std::wstring& s, ostream* os) { - PrintCharsAsStringTo(s.data(), s.size(), os); +void PrintWideStringTo(const ::std::wstring& s, ostream* os) +{ + PrintCharsAsStringTo(s.data(), s.size(), os); } #endif // GTEST_HAS_STD_WSTRING diff --git a/test/gtest-1.7.0/src/gtest-test-part.cc b/test/gtest-1.7.0/src/gtest-test-part.cc index c60eef3ab..ff35f67e1 100644 --- a/test/gtest-1.7.0/src/gtest-test-part.cc +++ b/test/gtest-1.7.0/src/gtest-test-part.cc @@ -42,67 +42,72 @@ #include "src/gtest-internal-inl.h" #undef GTEST_IMPLEMENTATION_ -namespace testing { - +namespace testing +{ using internal::GetUnitTestImpl; // Gets the summary of the failure message by omitting the stack trace // in it. -std::string TestPartResult::ExtractSummary(const char* message) { - const char* const stack_trace = strstr(message, internal::kStackTraceMarker); - return stack_trace == NULL ? message : - std::string(message, stack_trace); +std::string TestPartResult::ExtractSummary(const char* message) +{ + const char* const stack_trace = strstr(message, internal::kStackTraceMarker); + return stack_trace == NULL ? message : std::string(message, stack_trace); } // Prints a TestPartResult object. -std::ostream& operator<<(std::ostream& os, const TestPartResult& result) { - return os - << result.file_name() << ":" << result.line_number() << ": " - << (result.type() == TestPartResult::kSuccess ? "Success" : - result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : - "Non-fatal failure") << ":\n" - << result.message() << std::endl; +std::ostream& operator<<(std::ostream& os, const TestPartResult& result) +{ + return os + << result.file_name() << ":" << result.line_number() << ": " + << (result.type() == TestPartResult::kSuccess ? "Success" : result.type() == TestPartResult::kFatalFailure ? "Fatal failure" : "Non-fatal failure") << ":\n" + << result.message() << std::endl; } // Appends a TestPartResult to the array. -void TestPartResultArray::Append(const TestPartResult& result) { - array_.push_back(result); +void TestPartResultArray::Append(const TestPartResult& result) +{ + array_.push_back(result); } // Returns the TestPartResult at the given index (0-based). -const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const { - if (index < 0 || index >= size()) { - printf("\nInvalid index (%d) into TestPartResultArray.\n", index); - internal::posix::Abort(); - } +const TestPartResult& TestPartResultArray::GetTestPartResult(int index) const +{ + if (index < 0 || index >= size()) + { + printf("\nInvalid index (%d) into TestPartResultArray.\n", index); + internal::posix::Abort(); + } - return array_[index]; + return array_[index]; } // Returns the number of TestPartResult objects in the array. -int TestPartResultArray::size() const { - return static_cast(array_.size()); +int TestPartResultArray::size() const +{ + return static_cast(array_.size()); } -namespace internal { - +namespace internal +{ HasNewFatalFailureHelper::HasNewFatalFailureHelper() - : has_new_fatal_failure_(false), - original_reporter_(GetUnitTestImpl()-> - GetTestPartResultReporterForCurrentThread()) { - GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); + : has_new_fatal_failure_(false), + original_reporter_(GetUnitTestImpl()->GetTestPartResultReporterForCurrentThread()) +{ + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread(this); } -HasNewFatalFailureHelper::~HasNewFatalFailureHelper() { - GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( - original_reporter_); +HasNewFatalFailureHelper::~HasNewFatalFailureHelper() +{ + GetUnitTestImpl()->SetTestPartResultReporterForCurrentThread( + original_reporter_); } void HasNewFatalFailureHelper::ReportTestPartResult( - const TestPartResult& result) { - if (result.fatally_failed()) - has_new_fatal_failure_ = true; - original_reporter_->ReportTestPartResult(result); + const TestPartResult& result) +{ + if (result.fatally_failed()) + has_new_fatal_failure_ = true; + original_reporter_->ReportTestPartResult(result); } } // namespace internal diff --git a/test/gtest-1.7.0/src/gtest-typed-test.cc b/test/gtest-1.7.0/src/gtest-typed-test.cc index f0079f407..51071c469 100644 --- a/test/gtest-1.7.0/src/gtest-typed-test.cc +++ b/test/gtest-1.7.0/src/gtest-typed-test.cc @@ -32,76 +32,89 @@ #include "gtest/gtest-typed-test.h" #include "gtest/gtest.h" -namespace testing { -namespace internal { - +namespace testing +{ +namespace internal +{ #if GTEST_HAS_TYPED_TEST_P // Skips to the first non-space char in str. Returns an empty string if str // contains only whitespace characters. -static const char* SkipSpaces(const char* str) { - while (IsSpace(*str)) - str++; - return str; +static const char* SkipSpaces(const char* str) +{ + while (IsSpace(*str)) + str++; + return str; } // Verifies that registered_tests match the test names in // defined_test_names_; returns registered_tests if successful, or // aborts the program otherwise. const char* TypedTestCasePState::VerifyRegisteredTestNames( - const char* file, int line, const char* registered_tests) { - typedef ::std::set::const_iterator DefinedTestIter; - registered_ = true; + const char* file, int line, const char* registered_tests) +{ + typedef ::std::set::const_iterator DefinedTestIter; + registered_ = true; - // Skip initial whitespace in registered_tests since some - // preprocessors prefix stringizied literals with whitespace. - registered_tests = SkipSpaces(registered_tests); + // Skip initial whitespace in registered_tests since some + // preprocessors prefix stringizied literals with whitespace. + registered_tests = SkipSpaces(registered_tests); - Message errors; - ::std::set tests; - for (const char* names = registered_tests; names != NULL; - names = SkipComma(names)) { - const std::string name = GetPrefixUntilComma(names); - if (tests.count(name) != 0) { - errors << "Test " << name << " is listed more than once.\n"; - continue; - } + Message errors; + ::std::set tests; + for (const char* names = registered_tests; names != NULL; + names = SkipComma(names)) + { + const std::string name = GetPrefixUntilComma(names); + if (tests.count(name) != 0) + { + errors << "Test " << name << " is listed more than once.\n"; + continue; + } - bool found = false; - for (DefinedTestIter it = defined_test_names_.begin(); - it != defined_test_names_.end(); - ++it) { - if (name == *it) { - found = true; - break; - } - } + bool found = false; + for (DefinedTestIter it = defined_test_names_.begin(); + it != defined_test_names_.end(); + ++it) + { + if (name == *it) + { + found = true; + break; + } + } - if (found) { - tests.insert(name); - } else { - errors << "No test named " << name - << " can be found in this test case.\n"; - } - } + if (found) + { + tests.insert(name); + } + else + { + errors << "No test named " << name + << " can be found in this test case.\n"; + } + } - for (DefinedTestIter it = defined_test_names_.begin(); - it != defined_test_names_.end(); - ++it) { - if (tests.count(*it) == 0) { - errors << "You forgot to list test " << *it << ".\n"; - } - } + for (DefinedTestIter it = defined_test_names_.begin(); + it != defined_test_names_.end(); + ++it) + { + if (tests.count(*it) == 0) + { + errors << "You forgot to list test " << *it << ".\n"; + } + } - const std::string& errors_str = errors.GetString(); - if (errors_str != "") { - fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), - errors_str.c_str()); - fflush(stderr); - posix::Abort(); - } + const std::string& errors_str = errors.GetString(); + if (errors_str != "") + { + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors_str.c_str()); + fflush(stderr); + posix::Abort(); + } - return registered_tests; + return registered_tests; } #endif // GTEST_HAS_TYPED_TEST_P diff --git a/test/gtest-1.7.0/src/gtest.cc b/test/gtest-1.7.0/src/gtest.cc index 6de53dd01..e5f294f72 100644 --- a/test/gtest-1.7.0/src/gtest.cc +++ b/test/gtest-1.7.0/src/gtest.cc @@ -54,76 +54,76 @@ // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). -# define GTEST_HAS_GETTIMEOFDAY_ 1 +#define GTEST_HAS_GETTIMEOFDAY_ 1 -# include // NOLINT -# include // NOLINT -# include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT // Declares vsnprintf(). This header is not available on Windows. -# include // NOLINT -# include // NOLINT -# include // NOLINT -# include // NOLINT -# include +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include #elif GTEST_OS_SYMBIAN -# define GTEST_HAS_GETTIMEOFDAY_ 1 -# include // NOLINT +#define GTEST_HAS_GETTIMEOFDAY_ 1 +#include // NOLINT #elif GTEST_OS_ZOS -# define GTEST_HAS_GETTIMEOFDAY_ 1 -# include // NOLINT +#define GTEST_HAS_GETTIMEOFDAY_ 1 +#include // NOLINT // On z/OS we additionally need strings.h for strcasecmp. -# include // NOLINT +#include // NOLINT #elif GTEST_OS_WINDOWS_MOBILE // We are on Windows CE. -# include // NOLINT +#include // NOLINT #elif GTEST_OS_WINDOWS // We are on Windows proper. -# include // NOLINT -# include // NOLINT -# include // NOLINT -# include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT +#include // NOLINT -# if GTEST_OS_WINDOWS_MINGW +#if GTEST_OS_WINDOWS_MINGW // MinGW has gettimeofday() but not _ftime64(). // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). // TODO(kenton@google.com): There are other ways to get the time on // Windows, like GetTickCount() or GetSystemTimeAsFileTime(). MinGW // supports these. consider using them instead. -# define GTEST_HAS_GETTIMEOFDAY_ 1 -# include // NOLINT -# endif // GTEST_OS_WINDOWS_MINGW +#define GTEST_HAS_GETTIMEOFDAY_ 1 +#include // NOLINT +#endif // GTEST_OS_WINDOWS_MINGW // cpplint thinks that the header is already included, so we want to // silence it. -# include // NOLINT +#include // NOLINT #else // Assume other platforms have gettimeofday(). // TODO(kenton@google.com): Use autoconf to detect availability of // gettimeofday(). -# define GTEST_HAS_GETTIMEOFDAY_ 1 +#define GTEST_HAS_GETTIMEOFDAY_ 1 // cpplint thinks that the header is already included, so we want to // silence it. -# include // NOLINT -# include // NOLINT +#include // NOLINT +#include // NOLINT #endif // GTEST_OS_LINUX #if GTEST_HAS_EXCEPTIONS -# include +#include #endif #if GTEST_CAN_STREAM_RESULTS_ -# include // NOLINT -# include // NOLINT +#include // NOLINT +#include // NOLINT #endif // Indicates that this translation unit is part of Google Test's @@ -136,11 +136,11 @@ #undef GTEST_IMPLEMENTATION_ #if GTEST_OS_WINDOWS -# define vsnprintf _vsnprintf +#define vsnprintf _vsnprintf #endif // GTEST_OS_WINDOWS -namespace testing { - +namespace testing +{ using internal::CountIf; using internal::ForEach; using internal::GetElementOr; @@ -170,8 +170,8 @@ static const char kTestTotalShards[] = "GTEST_TOTAL_SHARDS"; // The environment variable name for the test shard status file. static const char kTestShardStatusFile[] = "GTEST_SHARD_STATUS_FILE"; -namespace internal { - +namespace internal +{ // The text used in failure messages to indicate the start of the // stack trace. const char kStackTraceMarker[] = "\nStack trace:\n"; @@ -182,126 +182,129 @@ bool g_help_flag = false; } // namespace internal -static const char* GetDefaultFilter() { - return kUniversalFilter; +static const char* GetDefaultFilter() +{ + return kUniversalFilter; } GTEST_DEFINE_bool_( - also_run_disabled_tests, - internal::BoolFromGTestEnv("also_run_disabled_tests", false), - "Run disabled tests too, in addition to the tests normally being run."); + also_run_disabled_tests, + internal::BoolFromGTestEnv("also_run_disabled_tests", false), + "Run disabled tests too, in addition to the tests normally being run."); GTEST_DEFINE_bool_( - break_on_failure, - internal::BoolFromGTestEnv("break_on_failure", false), - "True iff a failed assertion should be a debugger break-point."); + break_on_failure, + internal::BoolFromGTestEnv("break_on_failure", false), + "True iff a failed assertion should be a debugger break-point."); GTEST_DEFINE_bool_( - catch_exceptions, - internal::BoolFromGTestEnv("catch_exceptions", true), - "True iff " GTEST_NAME_ - " should catch exceptions and treat them as test failures."); + catch_exceptions, + internal::BoolFromGTestEnv("catch_exceptions", true), + "True iff " GTEST_NAME_ + " should catch exceptions and treat them as test failures."); GTEST_DEFINE_string_( - color, - internal::StringFromGTestEnv("color", "auto"), - "Whether to use colors in the output. Valid values: yes, no, " - "and auto. 'auto' means to use colors if the output is " - "being sent to a terminal and the TERM environment variable " - "is set to a terminal type that supports colors."); + color, + internal::StringFromGTestEnv("color", "auto"), + "Whether to use colors in the output. Valid values: yes, no, " + "and auto. 'auto' means to use colors if the output is " + "being sent to a terminal and the TERM environment variable " + "is set to a terminal type that supports colors."); GTEST_DEFINE_string_( - filter, - internal::StringFromGTestEnv("filter", GetDefaultFilter()), - "A colon-separated list of glob (not regex) patterns " - "for filtering the tests to run, optionally followed by a " - "'-' and a : separated list of negative patterns (tests to " - "exclude). A test is run if it matches one of the positive " - "patterns and does not match any of the negative patterns."); + filter, + internal::StringFromGTestEnv("filter", GetDefaultFilter()), + "A colon-separated list of glob (not regex) patterns " + "for filtering the tests to run, optionally followed by a " + "'-' and a : separated list of negative patterns (tests to " + "exclude). A test is run if it matches one of the positive " + "patterns and does not match any of the negative patterns."); GTEST_DEFINE_bool_(list_tests, false, - "List all tests without running them."); + "List all tests without running them."); GTEST_DEFINE_string_( - output, - internal::StringFromGTestEnv("output", ""), - "A format (currently must be \"xml\"), optionally followed " - "by a colon and an output file name or directory. A directory " - "is indicated by a trailing pathname separator. " - "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " - "If a directory is specified, output files will be created " - "within that directory, with file-names based on the test " - "executable's name and, if necessary, made unique by adding " - "digits."); + output, + internal::StringFromGTestEnv("output", ""), + "A format (currently must be \"xml\"), optionally followed " + "by a colon and an output file name or directory. A directory " + "is indicated by a trailing pathname separator. " + "Examples: \"xml:filename.xml\", \"xml::directoryname/\". " + "If a directory is specified, output files will be created " + "within that directory, with file-names based on the test " + "executable's name and, if necessary, made unique by adding " + "digits."); GTEST_DEFINE_bool_( - print_time, - internal::BoolFromGTestEnv("print_time", true), - "True iff " GTEST_NAME_ - " should display elapsed time in text output."); + print_time, + internal::BoolFromGTestEnv("print_time", true), + "True iff " GTEST_NAME_ + " should display elapsed time in text output."); GTEST_DEFINE_int32_( - random_seed, - internal::Int32FromGTestEnv("random_seed", 0), - "Random number seed to use when shuffling test orders. Must be in range " - "[1, 99999], or 0 to use a seed based on the current time."); + random_seed, + internal::Int32FromGTestEnv("random_seed", 0), + "Random number seed to use when shuffling test orders. Must be in range " + "[1, 99999], or 0 to use a seed based on the current time."); GTEST_DEFINE_int32_( - repeat, - internal::Int32FromGTestEnv("repeat", 1), - "How many times to repeat each test. Specify a negative number " - "for repeating forever. Useful for shaking out flaky tests."); + repeat, + internal::Int32FromGTestEnv("repeat", 1), + "How many times to repeat each test. Specify a negative number " + "for repeating forever. Useful for shaking out flaky tests."); GTEST_DEFINE_bool_( - show_internal_stack_frames, false, - "True iff " GTEST_NAME_ " should include internal stack frames when " - "printing test failure stack traces."); + show_internal_stack_frames, false, + "True iff " GTEST_NAME_ + " should include internal stack frames when " + "printing test failure stack traces."); GTEST_DEFINE_bool_( - shuffle, - internal::BoolFromGTestEnv("shuffle", false), - "True iff " GTEST_NAME_ - " should randomize tests' order on every run."); + shuffle, + internal::BoolFromGTestEnv("shuffle", false), + "True iff " GTEST_NAME_ + " should randomize tests' order on every run."); GTEST_DEFINE_int32_( - stack_trace_depth, - internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), - "The maximum number of stack frames to print when an " - "assertion fails. The valid range is 0 through 100, inclusive."); + stack_trace_depth, + internal::Int32FromGTestEnv("stack_trace_depth", kMaxStackTraceDepth), + "The maximum number of stack frames to print when an " + "assertion fails. The valid range is 0 through 100, inclusive."); GTEST_DEFINE_string_( - stream_result_to, - internal::StringFromGTestEnv("stream_result_to", ""), - "This flag specifies the host name and the port number on which to stream " - "test results. Example: \"localhost:555\". The flag is effective only on " - "Linux."); + stream_result_to, + internal::StringFromGTestEnv("stream_result_to", ""), + "This flag specifies the host name and the port number on which to stream " + "test results. Example: \"localhost:555\". The flag is effective only on " + "Linux."); GTEST_DEFINE_bool_( - throw_on_failure, - internal::BoolFromGTestEnv("throw_on_failure", false), - "When this flag is specified, a failed assertion will throw an exception " - "if exceptions are enabled or exit the program with a non-zero code " - "otherwise."); - -namespace internal { + throw_on_failure, + internal::BoolFromGTestEnv("throw_on_failure", false), + "When this flag is specified, a failed assertion will throw an exception " + "if exceptions are enabled or exit the program with a non-zero code " + "otherwise."); +namespace internal +{ // Generates a random number from [0, range), using a Linear // Congruential Generator (LCG). Crashes if 'range' is 0 or greater // than kMaxRange. -UInt32 Random::Generate(UInt32 range) { - // These constants are the same as are used in glibc's rand(3). - state_ = (1103515245U*state_ + 12345U) % kMaxRange; +UInt32 Random::Generate(UInt32 range) +{ + // These constants are the same as are used in glibc's rand(3). + state_ = (1103515245U * state_ + 12345U) % kMaxRange; - GTEST_CHECK_(range > 0) - << "Cannot generate a number in the range [0, 0)."; - GTEST_CHECK_(range <= kMaxRange) - << "Generation of a number in [0, " << range << ") was requested, " - << "but this can only generate numbers in [0, " << kMaxRange << ")."; + GTEST_CHECK_(range > 0) + << "Cannot generate a number in the range [0, 0)."; + GTEST_CHECK_(range <= kMaxRange) + << "Generation of a number in [0, " << range << ") was requested, " + << "but this can only generate numbers in [0, " << kMaxRange << ")."; - // Converting via modulus introduces a bit of downward bias, but - // it's simple, and a linear congruential generator isn't too good - // to begin with. - return state_ % range; + // Converting via modulus introduces a bit of downward bias, but + // it's simple, and a linear congruential generator isn't too good + // to begin with. + return state_ % range; } // GTestIsInitialized() returns true iff the user has initialized @@ -319,51 +322,57 @@ static bool GTestIsInitialized() { return g_init_gtest_count != 0; } // results of calling a given int-returning method on each. // Returns the sum. static int SumOverTestCaseList(const std::vector& case_list, - int (TestCase::*method)() const) { - int sum = 0; - for (size_t i = 0; i < case_list.size(); i++) { - sum += (case_list[i]->*method)(); - } - return sum; + int (TestCase::*method)() const) +{ + int sum = 0; + for (size_t i = 0; i < case_list.size(); i++) + { + sum += (case_list[i]->*method)(); + } + return sum; } // Returns true iff the test case passed. -static bool TestCasePassed(const TestCase* test_case) { - return test_case->should_run() && test_case->Passed(); +static bool TestCasePassed(const TestCase* test_case) +{ + return test_case->should_run() && test_case->Passed(); } // Returns true iff the test case failed. -static bool TestCaseFailed(const TestCase* test_case) { - return test_case->should_run() && test_case->Failed(); +static bool TestCaseFailed(const TestCase* test_case) +{ + return test_case->should_run() && test_case->Failed(); } // Returns true iff test_case contains at least one test that should // run. -static bool ShouldRunTestCase(const TestCase* test_case) { - return test_case->should_run(); +static bool ShouldRunTestCase(const TestCase* test_case) +{ + return test_case->should_run(); } // AssertHelper constructor. AssertHelper::AssertHelper(TestPartResult::Type type, - const char* file, - int line, - const char* message) - : data_(new AssertHelperData(type, file, line, message)) { + const char* file, + int line, + const char* message) + : data_(new AssertHelperData(type, file, line, message)) +{ } -AssertHelper::~AssertHelper() { - delete data_; +AssertHelper::~AssertHelper() +{ + delete data_; } // Message assignment, for assertion streaming support. -void AssertHelper::operator=(const Message& message) const { - UnitTest::GetInstance()-> - AddTestPartResult(data_->type, data_->file, data_->line, - AppendUserMessage(data_->message, message), - UnitTest::GetInstance()->impl() - ->CurrentOsStackTraceExceptTop(1) - // Skips the stack frame for this function itself. - ); // NOLINT +void AssertHelper::operator=(const Message& message) const +{ + UnitTest::GetInstance()->AddTestPartResult(data_->type, data_->file, data_->line, + AppendUserMessage(data_->message, message), + UnitTest::GetInstance()->impl()->CurrentOsStackTraceExceptTop(1) + // Skips the stack frame for this function itself. + ); // NOLINT } // Mutex for linked pointers. @@ -374,62 +383,64 @@ std::string g_executable_path; // Returns the current application's name, removing directory path if that // is present. -FilePath GetCurrentExecutableName() { - FilePath result; +FilePath GetCurrentExecutableName() +{ + FilePath result; #if GTEST_OS_WINDOWS - result.Set(FilePath(g_executable_path).RemoveExtension("exe")); + result.Set(FilePath(g_executable_path).RemoveExtension("exe")); #else - result.Set(FilePath(g_executable_path)); + result.Set(FilePath(g_executable_path)); #endif // GTEST_OS_WINDOWS - return result.RemoveDirectoryName(); + return result.RemoveDirectoryName(); } // Functions for processing the gtest_output flag. // Returns the output format, or "" for normal printed output. -std::string UnitTestOptions::GetOutputFormat() { - const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); - if (gtest_output_flag == NULL) return std::string(""); +std::string UnitTestOptions::GetOutputFormat() +{ + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) return std::string(""); - const char* const colon = strchr(gtest_output_flag, ':'); - return (colon == NULL) ? - std::string(gtest_output_flag) : - std::string(gtest_output_flag, colon - gtest_output_flag); + const char* const colon = strchr(gtest_output_flag, ':'); + return (colon == NULL) ? std::string(gtest_output_flag) : std::string(gtest_output_flag, colon - gtest_output_flag); } // Returns the name of the requested output file, or the default if none // was explicitly specified. -std::string UnitTestOptions::GetAbsolutePathToOutputFile() { - const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); - if (gtest_output_flag == NULL) - return ""; +std::string UnitTestOptions::GetAbsolutePathToOutputFile() +{ + const char* const gtest_output_flag = GTEST_FLAG(output).c_str(); + if (gtest_output_flag == NULL) + return ""; - const char* const colon = strchr(gtest_output_flag, ':'); - if (colon == NULL) - return internal::FilePath::ConcatPaths( - internal::FilePath( - UnitTest::GetInstance()->original_working_dir()), - internal::FilePath(kDefaultOutputFile)).string(); + const char* const colon = strchr(gtest_output_flag, ':'); + if (colon == NULL) + return internal::FilePath::ConcatPaths( + internal::FilePath( + UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(kDefaultOutputFile)) + .string(); - internal::FilePath output_name(colon + 1); - if (!output_name.IsAbsolutePath()) - // TODO(wan@google.com): on Windows \some\path is not an absolute - // path (as its meaning depends on the current drive), yet the - // following logic for turning it into an absolute path is wrong. - // Fix it. - output_name = internal::FilePath::ConcatPaths( - internal::FilePath(UnitTest::GetInstance()->original_working_dir()), - internal::FilePath(colon + 1)); + internal::FilePath output_name(colon + 1); + if (!output_name.IsAbsolutePath()) + // TODO(wan@google.com): on Windows \some\path is not an absolute + // path (as its meaning depends on the current drive), yet the + // following logic for turning it into an absolute path is wrong. + // Fix it. + output_name = internal::FilePath::ConcatPaths( + internal::FilePath(UnitTest::GetInstance()->original_working_dir()), + internal::FilePath(colon + 1)); - if (!output_name.IsDirectory()) - return output_name.string(); + if (!output_name.IsDirectory()) + return output_name.string(); - internal::FilePath result(internal::FilePath::GenerateUniqueFileName( - output_name, internal::GetCurrentExecutableName(), - GetOutputFormat().c_str())); - return result.string(); + internal::FilePath result(internal::FilePath::GenerateUniqueFileName( + output_name, internal::GetCurrentExecutableName(), + GetOutputFormat().c_str())); + return result.string(); } // Returns true iff the wildcard pattern matches the string. The @@ -437,99 +448,111 @@ std::string UnitTestOptions::GetAbsolutePathToOutputFile() { // // This recursive algorithm isn't very efficient, but is clear and // works well enough for matching test names, which are short. -bool UnitTestOptions::PatternMatchesString(const char *pattern, - const char *str) { - switch (*pattern) { - case '\0': - case ':': // Either ':' or '\0' marks the end of the pattern. - return *str == '\0'; - case '?': // Matches any single character. - return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); - case '*': // Matches any string (possibly empty) of characters. - return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || - PatternMatchesString(pattern + 1, str); - default: // Non-special character. Matches itself. - return *pattern == *str && - PatternMatchesString(pattern + 1, str + 1); - } +bool UnitTestOptions::PatternMatchesString(const char* pattern, + const char* str) +{ + switch (*pattern) + { + case '\0': + case ':': // Either ':' or '\0' marks the end of the pattern. + return *str == '\0'; + case '?': // Matches any single character. + return *str != '\0' && PatternMatchesString(pattern + 1, str + 1); + case '*': // Matches any string (possibly empty) of characters. + return (*str != '\0' && PatternMatchesString(pattern, str + 1)) || + PatternMatchesString(pattern + 1, str); + default: // Non-special character. Matches itself. + return *pattern == *str && + PatternMatchesString(pattern + 1, str + 1); + } } bool UnitTestOptions::MatchesFilter( - const std::string& name, const char* filter) { - const char *cur_pattern = filter; - for (;;) { - if (PatternMatchesString(cur_pattern, name.c_str())) { - return true; - } + const std::string& name, const char* filter) +{ + const char* cur_pattern = filter; + for (;;) + { + if (PatternMatchesString(cur_pattern, name.c_str())) + { + return true; + } - // Finds the next pattern in the filter. - cur_pattern = strchr(cur_pattern, ':'); + // Finds the next pattern in the filter. + cur_pattern = strchr(cur_pattern, ':'); - // Returns if no more pattern can be found. - if (cur_pattern == NULL) { - return false; - } + // Returns if no more pattern can be found. + if (cur_pattern == NULL) + { + return false; + } - // Skips the pattern separater (the ':' character). - cur_pattern++; - } + // Skips the pattern separater (the ':' character). + cur_pattern++; + } } // Returns true iff the user-specified filter matches the test case // name and the test name. -bool UnitTestOptions::FilterMatchesTest(const std::string &test_case_name, - const std::string &test_name) { - const std::string& full_name = test_case_name + "." + test_name.c_str(); +bool UnitTestOptions::FilterMatchesTest(const std::string& test_case_name, + const std::string& test_name) +{ + const std::string& full_name = test_case_name + "." + test_name.c_str(); - // Split --gtest_filter at '-', if there is one, to separate into - // positive filter and negative filter portions - const char* const p = GTEST_FLAG(filter).c_str(); - const char* const dash = strchr(p, '-'); - std::string positive; - std::string negative; - if (dash == NULL) { - positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter - negative = ""; - } else { - positive = std::string(p, dash); // Everything up to the dash - negative = std::string(dash + 1); // Everything after the dash - if (positive.empty()) { - // Treat '-test1' as the same as '*-test1' - positive = kUniversalFilter; - } - } + // Split --gtest_filter at '-', if there is one, to separate into + // positive filter and negative filter portions + const char* const p = GTEST_FLAG(filter).c_str(); + const char* const dash = strchr(p, '-'); + std::string positive; + std::string negative; + if (dash == NULL) + { + positive = GTEST_FLAG(filter).c_str(); // Whole string is a positive filter + negative = ""; + } + else + { + positive = std::string(p, dash); // Everything up to the dash + negative = std::string(dash + 1); // Everything after the dash + if (positive.empty()) + { + // Treat '-test1' as the same as '*-test1' + positive = kUniversalFilter; + } + } - // A filter is a colon-separated list of patterns. It matches a - // test if any pattern in it matches the test. - return (MatchesFilter(full_name, positive.c_str()) && - !MatchesFilter(full_name, negative.c_str())); + // A filter is a colon-separated list of patterns. It matches a + // test if any pattern in it matches the test. + return (MatchesFilter(full_name, positive.c_str()) && + !MatchesFilter(full_name, negative.c_str())); } #if GTEST_HAS_SEH // Returns EXCEPTION_EXECUTE_HANDLER if Google Test should handle the // given SEH exception, or EXCEPTION_CONTINUE_SEARCH otherwise. // This function is useful as an __except condition. -int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { - // Google Test should handle a SEH exception if: - // 1. the user wants it to, AND - // 2. this is not a breakpoint exception, AND - // 3. this is not a C++ exception (VC++ implements them via SEH, - // apparently). - // - // SEH exception code for C++ exceptions. - // (see http://support.microsoft.com/kb/185294 for more information). - const DWORD kCxxExceptionCode = 0xe06d7363; +int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) +{ + // Google Test should handle a SEH exception if: + // 1. the user wants it to, AND + // 2. this is not a breakpoint exception, AND + // 3. this is not a C++ exception (VC++ implements them via SEH, + // apparently). + // + // SEH exception code for C++ exceptions. + // (see http://support.microsoft.com/kb/185294 for more information). + const DWORD kCxxExceptionCode = 0xe06d7363; - bool should_handle = true; + bool should_handle = true; - if (!GTEST_FLAG(catch_exceptions)) - should_handle = false; - else if (exception_code == EXCEPTION_BREAKPOINT) - should_handle = false; - else if (exception_code == kCxxExceptionCode) - should_handle = false; + if (!GTEST_FLAG(catch_exceptions)) + should_handle = false; + else if (exception_code == EXCEPTION_BREAKPOINT) + should_handle = false; + else if (exception_code == kCxxExceptionCode) + should_handle = false; - return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; + return should_handle ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH; } #endif // GTEST_HAS_SEH @@ -539,53 +562,64 @@ int UnitTestOptions::GTestShouldProcessSEH(DWORD exception_code) { // Google Test. The 'result' parameter specifies where to report the // results. Intercepts only failures from the current thread. ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( - TestPartResultArray* result) - : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), - result_(result) { - Init(); + TestPartResultArray* result) + : intercept_mode_(INTERCEPT_ONLY_CURRENT_THREAD), + result_(result) +{ + Init(); } // The c'tor sets this object as the test part result reporter used by // Google Test. The 'result' parameter specifies where to report the // results. ScopedFakeTestPartResultReporter::ScopedFakeTestPartResultReporter( - InterceptMode intercept_mode, TestPartResultArray* result) - : intercept_mode_(intercept_mode), - result_(result) { - Init(); + InterceptMode intercept_mode, TestPartResultArray* result) + : intercept_mode_(intercept_mode), + result_(result) +{ + Init(); } -void ScopedFakeTestPartResultReporter::Init() { - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - if (intercept_mode_ == INTERCEPT_ALL_THREADS) { - old_reporter_ = impl->GetGlobalTestPartResultReporter(); - impl->SetGlobalTestPartResultReporter(this); - } else { - old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); - impl->SetTestPartResultReporterForCurrentThread(this); - } +void ScopedFakeTestPartResultReporter::Init() +{ + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) + { + old_reporter_ = impl->GetGlobalTestPartResultReporter(); + impl->SetGlobalTestPartResultReporter(this); + } + else + { + old_reporter_ = impl->GetTestPartResultReporterForCurrentThread(); + impl->SetTestPartResultReporterForCurrentThread(this); + } } // The d'tor restores the test part result reporter used by Google Test // before. -ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() { - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - if (intercept_mode_ == INTERCEPT_ALL_THREADS) { - impl->SetGlobalTestPartResultReporter(old_reporter_); - } else { - impl->SetTestPartResultReporterForCurrentThread(old_reporter_); - } +ScopedFakeTestPartResultReporter::~ScopedFakeTestPartResultReporter() +{ + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + if (intercept_mode_ == INTERCEPT_ALL_THREADS) + { + impl->SetGlobalTestPartResultReporter(old_reporter_); + } + else + { + impl->SetTestPartResultReporterForCurrentThread(old_reporter_); + } } // Increments the test part result count and remembers the result. // This method is from the TestPartResultReporterInterface interface. void ScopedFakeTestPartResultReporter::ReportTestPartResult( - const TestPartResult& result) { - result_->Append(result); + const TestPartResult& result) +{ + result_->Append(result); } -namespace internal { - +namespace internal +{ // Returns the type ID of ::testing::Test. We should always call this // instead of GetTypeId< ::testing::Test>() to get the type ID of // testing::Test. This is to work around a suspected linker bug when @@ -595,8 +629,9 @@ namespace internal { // from user test code. GetTestTypeId() is guaranteed to always // return the same value, as it always calls GetTypeId<>() from the // gtest.cc, which is within the Google Test framework. -TypeId GetTestTypeId() { - return GetTypeId(); +TypeId GetTestTypeId() +{ + return GetTypeId(); } // The value of GetTestTypeId() as seen from within the Google Test @@ -607,158 +642,180 @@ extern const TypeId kTestTypeIdInGoogleTest = GetTestTypeId(); // failure of the given type and that the failure message contains the // given substring. AssertionResult HasOneFailure(const char* /* results_expr */, - const char* /* type_expr */, - const char* /* substr_expr */, - const TestPartResultArray& results, - TestPartResult::Type type, - const string& substr) { - const std::string expected(type == TestPartResult::kFatalFailure ? - "1 fatal failure" : - "1 non-fatal failure"); - Message msg; - if (results.size() != 1) { - msg << "Expected: " << expected << "\n" - << " Actual: " << results.size() << " failures"; - for (int i = 0; i < results.size(); i++) { - msg << "\n" << results.GetTestPartResult(i); - } - return AssertionFailure() << msg; - } + const char* /* type_expr */, + const char* /* substr_expr */, + const TestPartResultArray& results, + TestPartResult::Type type, + const string& substr) +{ + const std::string expected(type == TestPartResult::kFatalFailure ? "1 fatal failure" : "1 non-fatal failure"); + Message msg; + if (results.size() != 1) + { + msg << "Expected: " << expected << "\n" + << " Actual: " << results.size() << " failures"; + for (int i = 0; i < results.size(); i++) + { + msg << "\n" + << results.GetTestPartResult(i); + } + return AssertionFailure() << msg; + } - const TestPartResult& r = results.GetTestPartResult(0); - if (r.type() != type) { - return AssertionFailure() << "Expected: " << expected << "\n" - << " Actual:\n" - << r; - } + const TestPartResult& r = results.GetTestPartResult(0); + if (r.type() != type) + { + return AssertionFailure() << "Expected: " << expected << "\n" + << " Actual:\n" + << r; + } - if (strstr(r.message(), substr.c_str()) == NULL) { - return AssertionFailure() << "Expected: " << expected << " containing \"" - << substr << "\"\n" - << " Actual:\n" - << r; - } + if (strstr(r.message(), substr.c_str()) == NULL) + { + return AssertionFailure() << "Expected: " << expected << " containing \"" + << substr << "\"\n" + << " Actual:\n" + << r; + } - return AssertionSuccess(); + return AssertionSuccess(); } // The constructor of SingleFailureChecker remembers where to look up // test part results, what type of failure we expect, and what // substring the failure message should contain. -SingleFailureChecker:: SingleFailureChecker( - const TestPartResultArray* results, - TestPartResult::Type type, - const string& substr) - : results_(results), - type_(type), - substr_(substr) {} +SingleFailureChecker::SingleFailureChecker( + const TestPartResultArray* results, + TestPartResult::Type type, + const string& substr) + : results_(results), + type_(type), + substr_(substr) {} // The destructor of SingleFailureChecker verifies that the given // TestPartResultArray contains exactly one failure that has the given // type and contains the given substring. If that's not the case, a // non-fatal failure will be generated. -SingleFailureChecker::~SingleFailureChecker() { - EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_); +SingleFailureChecker::~SingleFailureChecker() +{ + EXPECT_PRED_FORMAT3(HasOneFailure, *results_, type_, substr_); } DefaultGlobalTestPartResultReporter::DefaultGlobalTestPartResultReporter( - UnitTestImpl* unit_test) : unit_test_(unit_test) {} + UnitTestImpl* unit_test) : unit_test_(unit_test) {} void DefaultGlobalTestPartResultReporter::ReportTestPartResult( - const TestPartResult& result) { - unit_test_->current_test_result()->AddTestPartResult(result); - unit_test_->listeners()->repeater()->OnTestPartResult(result); + const TestPartResult& result) +{ + unit_test_->current_test_result()->AddTestPartResult(result); + unit_test_->listeners()->repeater()->OnTestPartResult(result); } DefaultPerThreadTestPartResultReporter::DefaultPerThreadTestPartResultReporter( - UnitTestImpl* unit_test) : unit_test_(unit_test) {} + UnitTestImpl* unit_test) : unit_test_(unit_test) {} void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( - const TestPartResult& result) { - unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); + const TestPartResult& result) +{ + unit_test_->GetGlobalTestPartResultReporter()->ReportTestPartResult(result); } // Returns the global test part result reporter. TestPartResultReporterInterface* -UnitTestImpl::GetGlobalTestPartResultReporter() { - internal::MutexLock lock(&global_test_part_result_reporter_mutex_); - return global_test_part_result_repoter_; +UnitTestImpl::GetGlobalTestPartResultReporter() +{ + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + return global_test_part_result_repoter_; } // Sets the global test part result reporter. void UnitTestImpl::SetGlobalTestPartResultReporter( - TestPartResultReporterInterface* reporter) { - internal::MutexLock lock(&global_test_part_result_reporter_mutex_); - global_test_part_result_repoter_ = reporter; + TestPartResultReporterInterface* reporter) +{ + internal::MutexLock lock(&global_test_part_result_reporter_mutex_); + global_test_part_result_repoter_ = reporter; } // Returns the test part result reporter for the current thread. TestPartResultReporterInterface* -UnitTestImpl::GetTestPartResultReporterForCurrentThread() { - return per_thread_test_part_result_reporter_.get(); +UnitTestImpl::GetTestPartResultReporterForCurrentThread() +{ + return per_thread_test_part_result_reporter_.get(); } // Sets the test part result reporter for the current thread. void UnitTestImpl::SetTestPartResultReporterForCurrentThread( - TestPartResultReporterInterface* reporter) { - per_thread_test_part_result_reporter_.set(reporter); + TestPartResultReporterInterface* reporter) +{ + per_thread_test_part_result_reporter_.set(reporter); } // Gets the number of successful test cases. -int UnitTestImpl::successful_test_case_count() const { - return CountIf(test_cases_, TestCasePassed); +int UnitTestImpl::successful_test_case_count() const +{ + return CountIf(test_cases_, TestCasePassed); } // Gets the number of failed test cases. -int UnitTestImpl::failed_test_case_count() const { - return CountIf(test_cases_, TestCaseFailed); +int UnitTestImpl::failed_test_case_count() const +{ + return CountIf(test_cases_, TestCaseFailed); } // Gets the number of all test cases. -int UnitTestImpl::total_test_case_count() const { - return static_cast(test_cases_.size()); +int UnitTestImpl::total_test_case_count() const +{ + return static_cast(test_cases_.size()); } // Gets the number of all test cases that contain at least one test // that should run. -int UnitTestImpl::test_case_to_run_count() const { - return CountIf(test_cases_, ShouldRunTestCase); +int UnitTestImpl::test_case_to_run_count() const +{ + return CountIf(test_cases_, ShouldRunTestCase); } // Gets the number of successful tests. -int UnitTestImpl::successful_test_count() const { - return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count); +int UnitTestImpl::successful_test_count() const +{ + return SumOverTestCaseList(test_cases_, &TestCase::successful_test_count); } // Gets the number of failed tests. -int UnitTestImpl::failed_test_count() const { - return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count); +int UnitTestImpl::failed_test_count() const +{ + return SumOverTestCaseList(test_cases_, &TestCase::failed_test_count); } // Gets the number of disabled tests that will be reported in the XML report. -int UnitTestImpl::reportable_disabled_test_count() const { - return SumOverTestCaseList(test_cases_, - &TestCase::reportable_disabled_test_count); +int UnitTestImpl::reportable_disabled_test_count() const +{ + return SumOverTestCaseList(test_cases_, + &TestCase::reportable_disabled_test_count); } // Gets the number of disabled tests. -int UnitTestImpl::disabled_test_count() const { - return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count); +int UnitTestImpl::disabled_test_count() const +{ + return SumOverTestCaseList(test_cases_, &TestCase::disabled_test_count); } // Gets the number of tests to be printed in the XML report. -int UnitTestImpl::reportable_test_count() const { - return SumOverTestCaseList(test_cases_, &TestCase::reportable_test_count); +int UnitTestImpl::reportable_test_count() const +{ + return SumOverTestCaseList(test_cases_, &TestCase::reportable_test_count); } // Gets the number of all tests. -int UnitTestImpl::total_test_count() const { - return SumOverTestCaseList(test_cases_, &TestCase::total_test_count); +int UnitTestImpl::total_test_count() const +{ + return SumOverTestCaseList(test_cases_, &TestCase::total_test_count); } // Gets the number of tests that should run. -int UnitTestImpl::test_to_run_count() const { - return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count); +int UnitTestImpl::test_to_run_count() const +{ + return SumOverTestCaseList(test_cases_, &TestCase::test_to_run_count); } // Returns the current OS stack trace as an std::string. @@ -771,60 +828,63 @@ int UnitTestImpl::test_to_run_count() const { // For example, if Foo() calls Bar(), which in turn calls // CurrentOsStackTraceExceptTop(1), Foo() will be included in the // trace but Bar() and CurrentOsStackTraceExceptTop() won't. -std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { - (void)skip_count; - return ""; +std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) +{ + (void)skip_count; + return ""; } // Returns the current time in milliseconds. -TimeInMillis GetTimeInMillis() { +TimeInMillis GetTimeInMillis() +{ #if GTEST_OS_WINDOWS_MOBILE || defined(__BORLANDC__) - // Difference between 1970-01-01 and 1601-01-01 in milliseconds. - // http://analogous.blogspot.com/2005/04/epoch.html - const TimeInMillis kJavaEpochToWinFileTimeDelta = - static_cast(116444736UL) * 100000UL; - const DWORD kTenthMicrosInMilliSecond = 10000; + // Difference between 1970-01-01 and 1601-01-01 in milliseconds. + // http://analogous.blogspot.com/2005/04/epoch.html + const TimeInMillis kJavaEpochToWinFileTimeDelta = + static_cast(116444736UL) * 100000UL; + const DWORD kTenthMicrosInMilliSecond = 10000; - SYSTEMTIME now_systime; - FILETIME now_filetime; - ULARGE_INTEGER now_int64; - // TODO(kenton@google.com): Shouldn't this just use - // GetSystemTimeAsFileTime()? - GetSystemTime(&now_systime); - if (SystemTimeToFileTime(&now_systime, &now_filetime)) { - now_int64.LowPart = now_filetime.dwLowDateTime; - now_int64.HighPart = now_filetime.dwHighDateTime; - now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) - - kJavaEpochToWinFileTimeDelta; - return now_int64.QuadPart; - } - return 0; + SYSTEMTIME now_systime; + FILETIME now_filetime; + ULARGE_INTEGER now_int64; + // TODO(kenton@google.com): Shouldn't this just use + // GetSystemTimeAsFileTime()? + GetSystemTime(&now_systime); + if (SystemTimeToFileTime(&now_systime, &now_filetime)) + { + now_int64.LowPart = now_filetime.dwLowDateTime; + now_int64.HighPart = now_filetime.dwHighDateTime; + now_int64.QuadPart = (now_int64.QuadPart / kTenthMicrosInMilliSecond) - + kJavaEpochToWinFileTimeDelta; + return now_int64.QuadPart; + } + return 0; #elif GTEST_OS_WINDOWS && !GTEST_HAS_GETTIMEOFDAY_ - __timeb64 now; + __timeb64 now; -# ifdef _MSC_VER +#ifdef _MSC_VER - // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 - // (deprecated function) there. - // TODO(kenton@google.com): Use GetTickCount()? Or use - // SystemTimeToFileTime() -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4996) // Temporarily disables warning 4996. - _ftime64(&now); -# pragma warning(pop) // Restores the warning state. -# else - - _ftime64(&now); - -# endif // _MSC_VER - - return static_cast(now.time) * 1000 + now.millitm; -#elif GTEST_HAS_GETTIMEOFDAY_ - struct timeval now; - gettimeofday(&now, NULL); - return static_cast(now.tv_sec) * 1000 + now.tv_usec / 1000; + // MSVC 8 deprecates _ftime64(), so we want to suppress warning 4996 + // (deprecated function) there. + // TODO(kenton@google.com): Use GetTickCount()? Or use + // SystemTimeToFileTime() +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable : 4996) // Temporarily disables warning 4996. + _ftime64(&now); +#pragma warning(pop) // Restores the warning state. #else -# error "Don't know how to get the current time on your system." + + _ftime64(&now); + +#endif // _MSC_VER + + return static_cast(now.time) * 1000 + now.millitm; +#elif GTEST_HAS_GETTIMEOFDAY_ + struct timeval now; + gettimeofday(&now, NULL); + return static_cast(now.tv_sec) * 1000 + now.tv_usec / 1000; +#else +#error "Don't know how to get the current time on your system." #endif } @@ -837,33 +897,35 @@ TimeInMillis GetTimeInMillis() { // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the wide string, or NULL if the // input is NULL. -LPCWSTR String::AnsiToUtf16(const char* ansi) { - if (!ansi) return NULL; - const int length = strlen(ansi); - const int unicode_length = - MultiByteToWideChar(CP_ACP, 0, ansi, length, - NULL, 0); - WCHAR* unicode = new WCHAR[unicode_length + 1]; - MultiByteToWideChar(CP_ACP, 0, ansi, length, - unicode, unicode_length); - unicode[unicode_length] = 0; - return unicode; +LPCWSTR String::AnsiToUtf16(const char* ansi) +{ + if (!ansi) return NULL; + const int length = strlen(ansi); + const int unicode_length = + MultiByteToWideChar(CP_ACP, 0, ansi, length, + NULL, 0); + WCHAR* unicode = new WCHAR[unicode_length + 1]; + MultiByteToWideChar(CP_ACP, 0, ansi, length, + unicode, unicode_length); + unicode[unicode_length] = 0; + return unicode; } // Creates an ANSI string from the given wide string, allocating // memory using new. The caller is responsible for deleting the return // value using delete[]. Returns the ANSI string, or NULL if the // input is NULL. -const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { - if (!utf16_str) return NULL; - const int ansi_length = - WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, - NULL, 0, NULL, NULL); - char* ansi = new char[ansi_length + 1]; - WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, - ansi, ansi_length, NULL, NULL); - ansi[ansi_length] = 0; - return ansi; +const char* String::Utf16ToAnsi(LPCWSTR utf16_str) +{ + if (!utf16_str) return NULL; + const int ansi_length = + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + NULL, 0, NULL, NULL); + char* ansi = new char[ansi_length + 1]; + WideCharToMultiByte(CP_ACP, 0, utf16_str, -1, + ansi, ansi_length, NULL, NULL); + ansi[ansi_length] = 0; + return ansi; } #endif // GTEST_OS_WINDOWS_MOBILE @@ -873,12 +935,13 @@ const char* String::Utf16ToAnsi(LPCWSTR utf16_str) { // Unlike strcmp(), this function can handle NULL argument(s). A NULL // C string is considered different to any non-NULL C string, // including the empty string. -bool String::CStringEquals(const char * lhs, const char * rhs) { - if ( lhs == NULL ) return rhs == NULL; +bool String::CStringEquals(const char* lhs, const char* rhs) +{ + if (lhs == NULL) return rhs == NULL; - if ( rhs == NULL ) return false; + if (rhs == NULL) return false; - return strcmp(lhs, rhs) == 0; + return strcmp(lhs, rhs) == 0; } #if GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING @@ -886,17 +949,22 @@ bool String::CStringEquals(const char * lhs, const char * rhs) { // Converts an array of wide chars to a narrow string using the UTF-8 // encoding, and streams the result to the given Message object. static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, - Message* msg) { - for (size_t i = 0; i != length; ) { // NOLINT - if (wstr[i] != L'\0') { - *msg << WideStringToUtf8(wstr + i, static_cast(length - i)); - while (i != length && wstr[i] != L'\0') - i++; - } else { - *msg << '\0'; - i++; - } - } + Message* msg) +{ + for (size_t i = 0; i != length;) + { // NOLINT + if (wstr[i] != L'\0') + { + *msg << WideStringToUtf8(wstr + i, static_cast(length - i)); + while (i != length && wstr[i] != L'\0') + i++; + } + else + { + *msg << '\0'; + i++; + } + } } #endif // GTEST_HAS_STD_WSTRING || GTEST_HAS_GLOBAL_WSTRING @@ -908,80 +976,89 @@ static void StreamWideCharsToMessage(const wchar_t* wstr, size_t length, // ASSERT/EXPECT in a procedure adds over 200 bytes to the procedure's // stack frame leading to huge stack frames in some cases; gcc does not reuse // the stack space. -Message::Message() : ss_(new ::std::stringstream) { - // By default, we want there to be enough precision when printing - // a double to a Message. - *ss_ << std::setprecision(std::numeric_limits::digits10 + 2); +Message::Message() : ss_(new ::std::stringstream) +{ + // By default, we want there to be enough precision when printing + // a double to a Message. + *ss_ << std::setprecision(std::numeric_limits::digits10 + 2); } // These two overloads allow streaming a wide C string to a Message // using the UTF-8 encoding. -Message& Message::operator <<(const wchar_t* wide_c_str) { - return *this << internal::String::ShowWideCString(wide_c_str); +Message& Message::operator<<(const wchar_t* wide_c_str) +{ + return *this << internal::String::ShowWideCString(wide_c_str); } -Message& Message::operator <<(wchar_t* wide_c_str) { - return *this << internal::String::ShowWideCString(wide_c_str); +Message& Message::operator<<(wchar_t* wide_c_str) +{ + return *this << internal::String::ShowWideCString(wide_c_str); } #if GTEST_HAS_STD_WSTRING // Converts the given wide string to a narrow string using the UTF-8 // encoding, and streams the result to this Message object. -Message& Message::operator <<(const ::std::wstring& wstr) { - internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); - return *this; +Message& Message::operator<<(const ::std::wstring& wstr) +{ + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; } #endif // GTEST_HAS_STD_WSTRING #if GTEST_HAS_GLOBAL_WSTRING // Converts the given wide string to a narrow string using the UTF-8 // encoding, and streams the result to this Message object. -Message& Message::operator <<(const ::wstring& wstr) { - internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); - return *this; +Message& Message::operator<<(const ::wstring& wstr) +{ + internal::StreamWideCharsToMessage(wstr.c_str(), wstr.length(), this); + return *this; } #endif // GTEST_HAS_GLOBAL_WSTRING // Gets the text streamed to this object so far as an std::string. // Each '\0' character in the buffer is replaced with "\\0". -std::string Message::GetString() const { - return internal::StringStreamToString(ss_.get()); +std::string Message::GetString() const +{ + return internal::StringStreamToString(ss_.get()); } // AssertionResult constructors. // Used in EXPECT_TRUE/FALSE(assertion_result). AssertionResult::AssertionResult(const AssertionResult& other) - : success_(other.success_), - message_(other.message_.get() != NULL ? - new ::std::string(*other.message_) : - static_cast< ::std::string*>(NULL)) { + : success_(other.success_), + message_(other.message_.get() != NULL ? new ::std::string(*other.message_) : static_cast< ::std::string*>(NULL)) +{ } // Returns the assertion's negation. Used with EXPECT/ASSERT_FALSE. -AssertionResult AssertionResult::operator!() const { - AssertionResult negation(!success_); - if (message_.get() != NULL) - negation << *message_; - return negation; +AssertionResult AssertionResult::operator!() const +{ + AssertionResult negation(!success_); + if (message_.get() != NULL) + negation << *message_; + return negation; } // Makes a successful assertion result. -AssertionResult AssertionSuccess() { - return AssertionResult(true); +AssertionResult AssertionSuccess() +{ + return AssertionResult(true); } // Makes a failed assertion result. -AssertionResult AssertionFailure() { - return AssertionResult(false); +AssertionResult AssertionFailure() +{ + return AssertionResult(false); } // Makes a failed assertion result with the given failure message. // Deprecated; use AssertionFailure() << message. -AssertionResult AssertionFailure(const Message& message) { - return AssertionFailure() << message; +AssertionResult AssertionFailure(const Message& message) +{ + return AssertionFailure() << message; } -namespace internal { - +namespace internal +{ // Constructs and returns the message for an equality assertion // (e.g. ASSERT_EQ, EXPECT_STREQ, etc) failure. // @@ -998,97 +1075,105 @@ namespace internal { // *_STRCASEEQ*. When it's true, the string " (ignoring case)" will // be inserted into the message. AssertionResult EqFailure(const char* expected_expression, - const char* actual_expression, - const std::string& expected_value, - const std::string& actual_value, - bool ignoring_case) { - Message msg; - msg << "Value of: " << actual_expression; - if (actual_value != actual_expression) { - msg << "\n Actual: " << actual_value; - } + const char* actual_expression, + const std::string& expected_value, + const std::string& actual_value, + bool ignoring_case) +{ + Message msg; + msg << "Value of: " << actual_expression; + if (actual_value != actual_expression) + { + msg << "\n Actual: " << actual_value; + } - msg << "\nExpected: " << expected_expression; - if (ignoring_case) { - msg << " (ignoring case)"; - } - if (expected_value != expected_expression) { - msg << "\nWhich is: " << expected_value; - } + msg << "\nExpected: " << expected_expression; + if (ignoring_case) + { + msg << " (ignoring case)"; + } + if (expected_value != expected_expression) + { + msg << "\nWhich is: " << expected_value; + } - return AssertionFailure() << msg; + return AssertionFailure() << msg; } // Constructs a failure message for Boolean assertions such as EXPECT_TRUE. std::string GetBoolAssertionFailureMessage( - const AssertionResult& assertion_result, - const char* expression_text, - const char* actual_predicate_value, - const char* expected_predicate_value) { - const char* actual_message = assertion_result.message(); - Message msg; - msg << "Value of: " << expression_text - << "\n Actual: " << actual_predicate_value; - if (actual_message[0] != '\0') - msg << " (" << actual_message << ")"; - msg << "\nExpected: " << expected_predicate_value; - return msg.GetString(); + const AssertionResult& assertion_result, + const char* expression_text, + const char* actual_predicate_value, + const char* expected_predicate_value) +{ + const char* actual_message = assertion_result.message(); + Message msg; + msg << "Value of: " << expression_text + << "\n Actual: " << actual_predicate_value; + if (actual_message[0] != '\0') + msg << " (" << actual_message << ")"; + msg << "\nExpected: " << expected_predicate_value; + return msg.GetString(); } // Helper function for implementing ASSERT_NEAR. AssertionResult DoubleNearPredFormat(const char* expr1, - const char* expr2, - const char* abs_error_expr, - double val1, - double val2, - double abs_error) { - const double diff = fabs(val1 - val2); - if (diff <= abs_error) return AssertionSuccess(); + const char* expr2, + const char* abs_error_expr, + double val1, + double val2, + double abs_error) +{ + const double diff = fabs(val1 - val2); + if (diff <= abs_error) return AssertionSuccess(); - // TODO(wan): do not print the value of an expression if it's - // already a literal. - return AssertionFailure() - << "The difference between " << expr1 << " and " << expr2 - << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" - << expr1 << " evaluates to " << val1 << ",\n" - << expr2 << " evaluates to " << val2 << ", and\n" - << abs_error_expr << " evaluates to " << abs_error << "."; + // TODO(wan): do not print the value of an expression if it's + // already a literal. + return AssertionFailure() + << "The difference between " << expr1 << " and " << expr2 + << " is " << diff << ", which exceeds " << abs_error_expr << ", where\n" + << expr1 << " evaluates to " << val1 << ",\n" + << expr2 << " evaluates to " << val2 << ", and\n" + << abs_error_expr << " evaluates to " << abs_error << "."; } - // Helper template for implementing FloatLE() and DoubleLE(). template AssertionResult FloatingPointLE(const char* expr1, - const char* expr2, - RawType val1, - RawType val2) { - // Returns success if val1 is less than val2, - if (val1 < val2) { - return AssertionSuccess(); - } + const char* expr2, + RawType val1, + RawType val2) +{ + // Returns success if val1 is less than val2, + if (val1 < val2) + { + return AssertionSuccess(); + } - // or if val1 is almost equal to val2. - const FloatingPoint lhs(val1), rhs(val2); - if (lhs.AlmostEquals(rhs)) { - return AssertionSuccess(); - } + // or if val1 is almost equal to val2. + const FloatingPoint lhs(val1), rhs(val2); + if (lhs.AlmostEquals(rhs)) + { + return AssertionSuccess(); + } - // Note that the above two checks will both fail if either val1 or - // val2 is NaN, as the IEEE floating-point standard requires that - // any predicate involving a NaN must return false. + // Note that the above two checks will both fail if either val1 or + // val2 is NaN, as the IEEE floating-point standard requires that + // any predicate involving a NaN must return false. - ::std::stringstream val1_ss; - val1_ss << std::setprecision(std::numeric_limits::digits10 + 2) - << val1; + ::std::stringstream val1_ss; + val1_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << val1; - ::std::stringstream val2_ss; - val2_ss << std::setprecision(std::numeric_limits::digits10 + 2) - << val2; + ::std::stringstream val2_ss; + val2_ss << std::setprecision(std::numeric_limits::digits10 + 2) + << val2; - return AssertionFailure() - << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" - << " Actual: " << StringStreamToString(&val1_ss) << " vs " - << StringStreamToString(&val2_ss); + return AssertionFailure() + << "Expected: (" << expr1 << ") <= (" << expr2 << ")\n" + << " Actual: " << StringStreamToString(&val1_ss) << " vs " + << StringStreamToString(&val2_ss); } } // namespace internal @@ -1096,51 +1181,59 @@ AssertionResult FloatingPointLE(const char* expr1, // Asserts that val1 is less than, or almost equal to, val2. Fails // otherwise. In particular, it fails if either val1 or val2 is NaN. AssertionResult FloatLE(const char* expr1, const char* expr2, - float val1, float val2) { - return internal::FloatingPointLE(expr1, expr2, val1, val2); + float val1, float val2) +{ + return internal::FloatingPointLE(expr1, expr2, val1, val2); } // Asserts that val1 is less than, or almost equal to, val2. Fails // otherwise. In particular, it fails if either val1 or val2 is NaN. AssertionResult DoubleLE(const char* expr1, const char* expr2, - double val1, double val2) { - return internal::FloatingPointLE(expr1, expr2, val1, val2); + double val1, double val2) +{ + return internal::FloatingPointLE(expr1, expr2, val1, val2); } -namespace internal { - +namespace internal +{ // The helper function for {ASSERT|EXPECT}_EQ with int or enum // arguments. AssertionResult CmpHelperEQ(const char* expected_expression, - const char* actual_expression, - BiggestInt expected, - BiggestInt actual) { - if (expected == actual) { - return AssertionSuccess(); - } + const char* actual_expression, + BiggestInt expected, + BiggestInt actual) +{ + if (expected == actual) + { + return AssertionSuccess(); + } - return EqFailure(expected_expression, - actual_expression, - FormatForComparisonFailureMessage(expected, actual), - FormatForComparisonFailureMessage(actual, expected), - false); + return EqFailure(expected_expression, + actual_expression, + FormatForComparisonFailureMessage(expected, actual), + FormatForComparisonFailureMessage(actual, expected), + false); } // A macro for implementing the helper functions needed to implement // ASSERT_?? and EXPECT_?? with integer or enum arguments. It is here // just to avoid copy-and-paste of similar code. -#define GTEST_IMPL_CMP_HELPER_(op_name, op)\ -AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ - BiggestInt val1, BiggestInt val2) {\ - if (val1 op val2) {\ - return AssertionSuccess();\ - } else {\ - return AssertionFailure() \ - << "Expected: (" << expr1 << ") " #op " (" << expr2\ - << "), actual: " << FormatForComparisonFailureMessage(val1, val2)\ - << " vs " << FormatForComparisonFailureMessage(val2, val1);\ - }\ -} +#define GTEST_IMPL_CMP_HELPER_(op_name, op) \ + AssertionResult CmpHelper##op_name(const char* expr1, const char* expr2, \ + BiggestInt val1, BiggestInt val2) \ + { \ + if (val1 op val2) \ + { \ + return AssertionSuccess(); \ + } \ + else \ + { \ + return AssertionFailure() \ + << "Expected: (" << expr1 << ") " #op " (" << expr2 \ + << "), actual: " << FormatForComparisonFailureMessage(val1, val2) \ + << " vs " << FormatForComparisonFailureMessage(val2, val1); \ + } \ + } // Implements the helper function for {ASSERT|EXPECT}_NE with int or // enum arguments. @@ -1150,106 +1243,121 @@ GTEST_IMPL_CMP_HELPER_(NE, !=) GTEST_IMPL_CMP_HELPER_(LE, <=) // Implements the helper function for {ASSERT|EXPECT}_LT with int or // enum arguments. -GTEST_IMPL_CMP_HELPER_(LT, < ) +GTEST_IMPL_CMP_HELPER_(LT, <) // Implements the helper function for {ASSERT|EXPECT}_GE with int or // enum arguments. GTEST_IMPL_CMP_HELPER_(GE, >=) // Implements the helper function for {ASSERT|EXPECT}_GT with int or // enum arguments. -GTEST_IMPL_CMP_HELPER_(GT, > ) +GTEST_IMPL_CMP_HELPER_(GT, >) #undef GTEST_IMPL_CMP_HELPER_ // The helper function for {ASSERT|EXPECT}_STREQ. AssertionResult CmpHelperSTREQ(const char* expected_expression, - const char* actual_expression, - const char* expected, - const char* actual) { - if (String::CStringEquals(expected, actual)) { - return AssertionSuccess(); - } + const char* actual_expression, + const char* expected, + const char* actual) +{ + if (String::CStringEquals(expected, actual)) + { + return AssertionSuccess(); + } - return EqFailure(expected_expression, - actual_expression, - PrintToString(expected), - PrintToString(actual), - false); + return EqFailure(expected_expression, + actual_expression, + PrintToString(expected), + PrintToString(actual), + false); } // The helper function for {ASSERT|EXPECT}_STRCASEEQ. AssertionResult CmpHelperSTRCASEEQ(const char* expected_expression, - const char* actual_expression, - const char* expected, - const char* actual) { - if (String::CaseInsensitiveCStringEquals(expected, actual)) { - return AssertionSuccess(); - } + const char* actual_expression, + const char* expected, + const char* actual) +{ + if (String::CaseInsensitiveCStringEquals(expected, actual)) + { + return AssertionSuccess(); + } - return EqFailure(expected_expression, - actual_expression, - PrintToString(expected), - PrintToString(actual), - true); + return EqFailure(expected_expression, + actual_expression, + PrintToString(expected), + PrintToString(actual), + true); } // The helper function for {ASSERT|EXPECT}_STRNE. AssertionResult CmpHelperSTRNE(const char* s1_expression, - const char* s2_expression, - const char* s1, - const char* s2) { - if (!String::CStringEquals(s1, s2)) { - return AssertionSuccess(); - } else { - return AssertionFailure() << "Expected: (" << s1_expression << ") != (" - << s2_expression << "), actual: \"" - << s1 << "\" vs \"" << s2 << "\""; - } + const char* s2_expression, + const char* s1, + const char* s2) +{ + if (!String::CStringEquals(s1, s2)) + { + return AssertionSuccess(); + } + else + { + return AssertionFailure() << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + } } // The helper function for {ASSERT|EXPECT}_STRCASENE. AssertionResult CmpHelperSTRCASENE(const char* s1_expression, - const char* s2_expression, - const char* s1, - const char* s2) { - if (!String::CaseInsensitiveCStringEquals(s1, s2)) { - return AssertionSuccess(); - } else { - return AssertionFailure() - << "Expected: (" << s1_expression << ") != (" - << s2_expression << ") (ignoring case), actual: \"" - << s1 << "\" vs \"" << s2 << "\""; - } + const char* s2_expression, + const char* s1, + const char* s2) +{ + if (!String::CaseInsensitiveCStringEquals(s1, s2)) + { + return AssertionSuccess(); + } + else + { + return AssertionFailure() + << "Expected: (" << s1_expression << ") != (" + << s2_expression << ") (ignoring case), actual: \"" + << s1 << "\" vs \"" << s2 << "\""; + } } } // namespace internal -namespace { - +namespace +{ // Helper functions for implementing IsSubString() and IsNotSubstring(). // This group of overloaded functions return true iff needle is a // substring of haystack. NULL is considered a substring of itself // only. -bool IsSubstringPred(const char* needle, const char* haystack) { - if (needle == NULL || haystack == NULL) - return needle == haystack; +bool IsSubstringPred(const char* needle, const char* haystack) +{ + if (needle == NULL || haystack == NULL) + return needle == haystack; - return strstr(haystack, needle) != NULL; + return strstr(haystack, needle) != NULL; } -bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) { - if (needle == NULL || haystack == NULL) - return needle == haystack; +bool IsSubstringPred(const wchar_t* needle, const wchar_t* haystack) +{ + if (needle == NULL || haystack == NULL) + return needle == haystack; - return wcsstr(haystack, needle) != NULL; + return wcsstr(haystack, needle) != NULL; } // StringType here can be either ::std::string or ::std::wstring. template bool IsSubstringPred(const StringType& needle, - const StringType& haystack) { - return haystack.find(needle) != StringType::npos; + const StringType& haystack) +{ + return haystack.find(needle) != StringType::npos; } // This function implements either IsSubstring() or IsNotSubstring(), @@ -1258,20 +1366,21 @@ bool IsSubstringPred(const StringType& needle, // or ::std::wstring. template AssertionResult IsSubstringImpl( - bool expected_to_be_substring, - const char* needle_expr, const char* haystack_expr, - const StringType& needle, const StringType& haystack) { - if (IsSubstringPred(needle, haystack) == expected_to_be_substring) - return AssertionSuccess(); + bool expected_to_be_substring, + const char* needle_expr, const char* haystack_expr, + const StringType& needle, const StringType& haystack) +{ + if (IsSubstringPred(needle, haystack) == expected_to_be_substring) + return AssertionSuccess(); - const bool is_wide_string = sizeof(needle[0]) > 1; - const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; - return AssertionFailure() - << "Value of: " << needle_expr << "\n" - << " Actual: " << begin_string_quote << needle << "\"\n" - << "Expected: " << (expected_to_be_substring ? "" : "not ") - << "a substring of " << haystack_expr << "\n" - << "Which is: " << begin_string_quote << haystack << "\""; + const bool is_wide_string = sizeof(needle[0]) > 1; + const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; + return AssertionFailure() + << "Value of: " << needle_expr << "\n" + << " Actual: " << begin_string_quote << needle << "\"\n" + << "Expected: " << (expected_to_be_substring ? "" : "not ") + << "a substring of " << haystack_expr << "\n" + << "Which is: " << begin_string_quote << haystack << "\""; } } // namespace @@ -1281,115 +1390,129 @@ AssertionResult IsSubstringImpl( // only), and return an appropriate error message when they fail. AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const char* needle, const char* haystack) { - return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) +{ + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const wchar_t* needle, const wchar_t* haystack) { - return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) +{ + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const char* needle, const char* haystack) { - return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); + const char* needle_expr, const char* haystack_expr, + const char* needle, const char* haystack) +{ + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const wchar_t* needle, const wchar_t* haystack) { - return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); + const char* needle_expr, const char* haystack_expr, + const wchar_t* needle, const wchar_t* haystack) +{ + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::string& needle, const ::std::string& haystack) { - return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) +{ + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::string& needle, const ::std::string& haystack) { - return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); + const char* needle_expr, const char* haystack_expr, + const ::std::string& needle, const ::std::string& haystack) +{ + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } #if GTEST_HAS_STD_WSTRING AssertionResult IsSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::wstring& needle, const ::std::wstring& haystack) { - return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) +{ + return IsSubstringImpl(true, needle_expr, haystack_expr, needle, haystack); } AssertionResult IsNotSubstring( - const char* needle_expr, const char* haystack_expr, - const ::std::wstring& needle, const ::std::wstring& haystack) { - return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); + const char* needle_expr, const char* haystack_expr, + const ::std::wstring& needle, const ::std::wstring& haystack) +{ + return IsSubstringImpl(false, needle_expr, haystack_expr, needle, haystack); } #endif // GTEST_HAS_STD_WSTRING -namespace internal { - +namespace internal +{ #if GTEST_OS_WINDOWS -namespace { - +namespace +{ // Helper function for IsHRESULT{SuccessFailure} predicates AssertionResult HRESULTFailureHelper(const char* expr, - const char* expected, - long hr) { // NOLINT -# if GTEST_OS_WINDOWS_MOBILE + const char* expected, + long hr) +{ // NOLINT +#if GTEST_OS_WINDOWS_MOBILE - // Windows CE doesn't support FormatMessage. - const char error_text[] = ""; + // Windows CE doesn't support FormatMessage. + const char error_text[] = ""; -# else +#else - // Looks up the human-readable system message for the HRESULT code - // and since we're not passing any params to FormatMessage, we don't - // want inserts expanded. - const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS; - const DWORD kBufSize = 4096; - // Gets the system's human readable message string for this HRESULT. - char error_text[kBufSize] = { '\0' }; - DWORD message_length = ::FormatMessageA(kFlags, - 0, // no source, we're asking system - hr, // the error - 0, // no line width restrictions - error_text, // output buffer - kBufSize, // buf size - NULL); // no arguments for inserts - // Trims tailing white space (FormatMessage leaves a trailing CR-LF) - for (; message_length && IsSpace(error_text[message_length - 1]); - --message_length) { - error_text[message_length - 1] = '\0'; - } + // Looks up the human-readable system message for the HRESULT code + // and since we're not passing any params to FormatMessage, we don't + // want inserts expanded. + const DWORD kFlags = FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS; + const DWORD kBufSize = 4096; + // Gets the system's human readable message string for this HRESULT. + char error_text[kBufSize] = {'\0'}; + DWORD message_length = ::FormatMessageA(kFlags, + 0, // no source, we're asking system + hr, // the error + 0, // no line width restrictions + error_text, // output buffer + kBufSize, // buf size + NULL); // no arguments for inserts + // Trims tailing white space (FormatMessage leaves a trailing CR-LF) + for (; message_length && IsSpace(error_text[message_length - 1]); + --message_length) + { + error_text[message_length - 1] = '\0'; + } -# endif // GTEST_OS_WINDOWS_MOBILE +#endif // GTEST_OS_WINDOWS_MOBILE - const std::string error_hex("0x" + String::FormatHexInt(hr)); - return ::testing::AssertionFailure() - << "Expected: " << expr << " " << expected << ".\n" - << " Actual: " << error_hex << " " << error_text << "\n"; + const std::string error_hex("0x" + String::FormatHexInt(hr)); + return ::testing::AssertionFailure() + << "Expected: " << expr << " " << expected << ".\n" + << " Actual: " << error_hex << " " << error_text << "\n"; } } // namespace -AssertionResult IsHRESULTSuccess(const char* expr, long hr) { // NOLINT - if (SUCCEEDED(hr)) { - return AssertionSuccess(); - } - return HRESULTFailureHelper(expr, "succeeds", hr); +AssertionResult IsHRESULTSuccess(const char* expr, long hr) +{ // NOLINT + if (SUCCEEDED(hr)) + { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "succeeds", hr); } -AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT - if (FAILED(hr)) { - return AssertionSuccess(); - } - return HRESULTFailureHelper(expr, "fails", hr); +AssertionResult IsHRESULTFailure(const char* expr, long hr) +{ // NOLINT + if (FAILED(hr)) + { + return AssertionSuccess(); + } + return HRESULTFailureHelper(expr, "fails", hr); } #endif // GTEST_OS_WINDOWS @@ -1407,24 +1530,25 @@ AssertionResult IsHRESULTFailure(const char* expr, long hr) { // NOLINT // 17 - 21 bits 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx // The maximum code-point a one-byte UTF-8 sequence can represent. -const UInt32 kMaxCodePoint1 = (static_cast(1) << 7) - 1; +const UInt32 kMaxCodePoint1 = (static_cast(1) << 7) - 1; // The maximum code-point a two-byte UTF-8 sequence can represent. const UInt32 kMaxCodePoint2 = (static_cast(1) << (5 + 6)) - 1; // The maximum code-point a three-byte UTF-8 sequence can represent. -const UInt32 kMaxCodePoint3 = (static_cast(1) << (4 + 2*6)) - 1; +const UInt32 kMaxCodePoint3 = (static_cast(1) << (4 + 2 * 6)) - 1; // The maximum code-point a four-byte UTF-8 sequence can represent. -const UInt32 kMaxCodePoint4 = (static_cast(1) << (3 + 3*6)) - 1; +const UInt32 kMaxCodePoint4 = (static_cast(1) << (3 + 3 * 6)) - 1; // Chops off the n lowest bits from a bit pattern. Returns the n // lowest bits. As a side effect, the original bit pattern will be // shifted to the right by n bits. -inline UInt32 ChopLowBits(UInt32* bits, int n) { - const UInt32 low_bits = *bits & ((static_cast(1) << n) - 1); - *bits >>= n; - return low_bits; +inline UInt32 ChopLowBits(UInt32* bits, int n) +{ + const UInt32 low_bits = *bits & ((static_cast(1) << n) - 1); + *bits >>= n; + return low_bits; } // Converts a Unicode code point to a narrow string in UTF-8 encoding. @@ -1433,32 +1557,41 @@ inline UInt32 ChopLowBits(UInt32* bits, int n) { // If the code_point is not a valid Unicode code point // (i.e. outside of Unicode range U+0 to U+10FFFF) it will be converted // to "(Invalid Unicode 0xXXXXXXXX)". -std::string CodePointToUtf8(UInt32 code_point) { - if (code_point > kMaxCodePoint4) { - return "(Invalid Unicode 0x" + String::FormatHexInt(code_point) + ")"; - } +std::string CodePointToUtf8(UInt32 code_point) +{ + if (code_point > kMaxCodePoint4) + { + return "(Invalid Unicode 0x" + String::FormatHexInt(code_point) + ")"; + } - char str[5]; // Big enough for the largest valid code point. - if (code_point <= kMaxCodePoint1) { - str[1] = '\0'; - str[0] = static_cast(code_point); // 0xxxxxxx - } else if (code_point <= kMaxCodePoint2) { - str[2] = '\0'; - str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx - str[0] = static_cast(0xC0 | code_point); // 110xxxxx - } else if (code_point <= kMaxCodePoint3) { - str[3] = '\0'; - str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx - str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx - str[0] = static_cast(0xE0 | code_point); // 1110xxxx - } else { // code_point <= kMaxCodePoint4 - str[4] = '\0'; - str[3] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx - str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx - str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx - str[0] = static_cast(0xF0 | code_point); // 11110xxx - } - return str; + char str[5]; // Big enough for the largest valid code point. + if (code_point <= kMaxCodePoint1) + { + str[1] = '\0'; + str[0] = static_cast(code_point); // 0xxxxxxx + } + else if (code_point <= kMaxCodePoint2) + { + str[2] = '\0'; + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xC0 | code_point); // 110xxxxx + } + else if (code_point <= kMaxCodePoint3) + { + str[3] = '\0'; + str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xE0 | code_point); // 1110xxxx + } + else + { // code_point <= kMaxCodePoint4 + str[4] = '\0'; + str[3] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[2] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[1] = static_cast(0x80 | ChopLowBits(&code_point, 6)); // 10xxxxxx + str[0] = static_cast(0xF0 | code_point); // 11110xxx + } + return str; } // The following two functions only make sense if the the system @@ -1468,20 +1601,21 @@ std::string CodePointToUtf8(UInt32 code_point) { // Determines if the arguments constitute UTF-16 surrogate pair // and thus should be combined into a single Unicode code point // using CreateCodePointFromUtf16SurrogatePair. -inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) { - return sizeof(wchar_t) == 2 && - (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; +inline bool IsUtf16SurrogatePair(wchar_t first, wchar_t second) +{ + return sizeof(wchar_t) == 2 && + (first & 0xFC00) == 0xD800 && (second & 0xFC00) == 0xDC00; } // Creates a Unicode code point from UTF16 surrogate pair. inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, - wchar_t second) { - const UInt32 mask = (1 << 10) - 1; - return (sizeof(wchar_t) == 2) ? - (((first & mask) << 10) | (second & mask)) + 0x10000 : - // This function should not be called when the condition is - // false, but we provide a sensible default in case it is. - static_cast(first); + wchar_t second) +{ + const UInt32 mask = (1 << 10) - 1; + return (sizeof(wchar_t) == 2) ? (((first & mask) << 10) | (second & mask)) + 0x10000 : + // This function should not be called when the condition is + // false, but we provide a sensible default in case it is. + static_cast(first); } // Converts a wide string to a narrow string in UTF-8 encoding. @@ -1497,35 +1631,43 @@ inline UInt32 CreateCodePointFromUtf16SurrogatePair(wchar_t first, // as '(Invalid Unicode 0xXXXXXXXX)'. If the string is in UTF16 encoding // and contains invalid UTF-16 surrogate pairs, values in those pairs // will be encoded as individual Unicode characters from Basic Normal Plane. -std::string WideStringToUtf8(const wchar_t* str, int num_chars) { - if (num_chars == -1) - num_chars = static_cast(wcslen(str)); +std::string WideStringToUtf8(const wchar_t* str, int num_chars) +{ + if (num_chars == -1) + num_chars = static_cast(wcslen(str)); - ::std::stringstream stream; - for (int i = 0; i < num_chars; ++i) { - UInt32 unicode_code_point; + ::std::stringstream stream; + for (int i = 0; i < num_chars; ++i) + { + UInt32 unicode_code_point; - if (str[i] == L'\0') { - break; - } else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) { - unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], - str[i + 1]); - i++; - } else { - unicode_code_point = static_cast(str[i]); - } + if (str[i] == L'\0') + { + break; + } + else if (i + 1 < num_chars && IsUtf16SurrogatePair(str[i], str[i + 1])) + { + unicode_code_point = CreateCodePointFromUtf16SurrogatePair(str[i], + str[i + 1]); + i++; + } + else + { + unicode_code_point = static_cast(str[i]); + } - stream << CodePointToUtf8(unicode_code_point); - } - return StringStreamToString(&stream); + stream << CodePointToUtf8(unicode_code_point); + } + return StringStreamToString(&stream); } // Converts a wide C string to an std::string using the UTF-8 encoding. // NULL will be converted to "(null)". -std::string String::ShowWideCString(const wchar_t * wide_c_str) { - if (wide_c_str == NULL) return "(null)"; +std::string String::ShowWideCString(const wchar_t* wide_c_str) +{ + if (wide_c_str == NULL) return "(null)"; - return internal::WideStringToUtf8(wide_c_str, -1); + return internal::WideStringToUtf8(wide_c_str, -1); } // Compares two wide C strings. Returns true iff they have the same @@ -1534,43 +1676,48 @@ std::string String::ShowWideCString(const wchar_t * wide_c_str) { // Unlike wcscmp(), this function can handle NULL argument(s). A NULL // C string is considered different to any non-NULL C string, // including the empty string. -bool String::WideCStringEquals(const wchar_t * lhs, const wchar_t * rhs) { - if (lhs == NULL) return rhs == NULL; +bool String::WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs) +{ + if (lhs == NULL) return rhs == NULL; - if (rhs == NULL) return false; + if (rhs == NULL) return false; - return wcscmp(lhs, rhs) == 0; + return wcscmp(lhs, rhs) == 0; } // Helper function for *_STREQ on wide strings. AssertionResult CmpHelperSTREQ(const char* expected_expression, - const char* actual_expression, - const wchar_t* expected, - const wchar_t* actual) { - if (String::WideCStringEquals(expected, actual)) { - return AssertionSuccess(); - } + const char* actual_expression, + const wchar_t* expected, + const wchar_t* actual) +{ + if (String::WideCStringEquals(expected, actual)) + { + return AssertionSuccess(); + } - return EqFailure(expected_expression, - actual_expression, - PrintToString(expected), - PrintToString(actual), - false); + return EqFailure(expected_expression, + actual_expression, + PrintToString(expected), + PrintToString(actual), + false); } // Helper function for *_STRNE on wide strings. AssertionResult CmpHelperSTRNE(const char* s1_expression, - const char* s2_expression, - const wchar_t* s1, - const wchar_t* s2) { - if (!String::WideCStringEquals(s1, s2)) { - return AssertionSuccess(); - } + const char* s2_expression, + const wchar_t* s1, + const wchar_t* s2) +{ + if (!String::WideCStringEquals(s1, s2)) + { + return AssertionSuccess(); + } - return AssertionFailure() << "Expected: (" << s1_expression << ") != (" - << s2_expression << "), actual: " - << PrintToString(s1) - << " vs " << PrintToString(s2); + return AssertionFailure() << "Expected: (" << s1_expression << ") != (" + << s2_expression << "), actual: " + << PrintToString(s1) + << " vs " << PrintToString(s2); } // Compares two C strings, ignoring case. Returns true iff they have @@ -1579,111 +1726,125 @@ AssertionResult CmpHelperSTRNE(const char* s1_expression, // Unlike strcasecmp(), this function can handle NULL argument(s). A // NULL C string is considered different to any non-NULL C string, // including the empty string. -bool String::CaseInsensitiveCStringEquals(const char * lhs, const char * rhs) { - if (lhs == NULL) - return rhs == NULL; - if (rhs == NULL) - return false; - return posix::StrCaseCmp(lhs, rhs) == 0; +bool String::CaseInsensitiveCStringEquals(const char* lhs, const char* rhs) +{ + if (lhs == NULL) + return rhs == NULL; + if (rhs == NULL) + return false; + return posix::StrCaseCmp(lhs, rhs) == 0; } - // Compares two wide C strings, ignoring case. Returns true iff they - // have the same content. - // - // Unlike wcscasecmp(), this function can handle NULL argument(s). - // A NULL C string is considered different to any non-NULL wide C string, - // including the empty string. - // NB: The implementations on different platforms slightly differ. - // On windows, this method uses _wcsicmp which compares according to LC_CTYPE - // environment variable. On GNU platform this method uses wcscasecmp - // which compares according to LC_CTYPE category of the current locale. - // On MacOS X, it uses towlower, which also uses LC_CTYPE category of the - // current locale. +// Compares two wide C strings, ignoring case. Returns true iff they +// have the same content. +// +// Unlike wcscasecmp(), this function can handle NULL argument(s). +// A NULL C string is considered different to any non-NULL wide C string, +// including the empty string. +// NB: The implementations on different platforms slightly differ. +// On windows, this method uses _wcsicmp which compares according to LC_CTYPE +// environment variable. On GNU platform this method uses wcscasecmp +// which compares according to LC_CTYPE category of the current locale. +// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the +// current locale. bool String::CaseInsensitiveWideCStringEquals(const wchar_t* lhs, - const wchar_t* rhs) { - if (lhs == NULL) return rhs == NULL; + const wchar_t* rhs) +{ + if (lhs == NULL) return rhs == NULL; - if (rhs == NULL) return false; + if (rhs == NULL) return false; #if GTEST_OS_WINDOWS - return _wcsicmp(lhs, rhs) == 0; + return _wcsicmp(lhs, rhs) == 0; #elif GTEST_OS_LINUX && !GTEST_OS_LINUX_ANDROID - return wcscasecmp(lhs, rhs) == 0; + return wcscasecmp(lhs, rhs) == 0; #else - // Android, Mac OS X and Cygwin don't define wcscasecmp. - // Other unknown OSes may not define it either. - wint_t left, right; - do { - left = towlower(*lhs++); - right = towlower(*rhs++); - } while (left && left == right); - return left == right; + // Android, Mac OS X and Cygwin don't define wcscasecmp. + // Other unknown OSes may not define it either. + wint_t left, right; + do + { + left = towlower(*lhs++); + right = towlower(*rhs++); + } while (left && left == right); + return left == right; #endif // OS selector } // Returns true iff str ends with the given suffix, ignoring case. // Any string is considered to end with an empty suffix. bool String::EndsWithCaseInsensitive( - const std::string& str, const std::string& suffix) { - const size_t str_len = str.length(); - const size_t suffix_len = suffix.length(); - return (str_len >= suffix_len) && - CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len, - suffix.c_str()); + const std::string& str, const std::string& suffix) +{ + const size_t str_len = str.length(); + const size_t suffix_len = suffix.length(); + return (str_len >= suffix_len) && + CaseInsensitiveCStringEquals(str.c_str() + str_len - suffix_len, + suffix.c_str()); } // Formats an int value as "%02d". -std::string String::FormatIntWidth2(int value) { - std::stringstream ss; - ss << std::setfill('0') << std::setw(2) << value; - return ss.str(); +std::string String::FormatIntWidth2(int value) +{ + std::stringstream ss; + ss << std::setfill('0') << std::setw(2) << value; + return ss.str(); } // Formats an int value as "%X". -std::string String::FormatHexInt(int value) { - std::stringstream ss; - ss << std::hex << std::uppercase << value; - return ss.str(); +std::string String::FormatHexInt(int value) +{ + std::stringstream ss; + ss << std::hex << std::uppercase << value; + return ss.str(); } // Formats a byte as "%02X". -std::string String::FormatByte(unsigned char value) { - std::stringstream ss; - ss << std::setfill('0') << std::setw(2) << std::hex << std::uppercase - << static_cast(value); - return ss.str(); +std::string String::FormatByte(unsigned char value) +{ + std::stringstream ss; + ss << std::setfill('0') << std::setw(2) << std::hex << std::uppercase + << static_cast(value); + return ss.str(); } // Converts the buffer in a stringstream to an std::string, converting NUL // bytes to "\\0" along the way. -std::string StringStreamToString(::std::stringstream* ss) { - const ::std::string& str = ss->str(); - const char* const start = str.c_str(); - const char* const end = start + str.length(); +std::string StringStreamToString(::std::stringstream* ss) +{ + const ::std::string& str = ss->str(); + const char* const start = str.c_str(); + const char* const end = start + str.length(); - std::string result; - result.reserve(2 * (end - start)); - for (const char* ch = start; ch != end; ++ch) { - if (*ch == '\0') { - result += "\\0"; // Replaces NUL with "\\0"; - } else { - result += *ch; - } - } + std::string result; + result.reserve(2 * (end - start)); + for (const char* ch = start; ch != end; ++ch) + { + if (*ch == '\0') + { + result += "\\0"; // Replaces NUL with "\\0"; + } + else + { + result += *ch; + } + } - return result; + return result; } // Appends the user-supplied message to the Google-Test-generated message. std::string AppendUserMessage(const std::string& gtest_msg, - const Message& user_msg) { - // Appends the user message if it's non-empty. - const std::string user_msg_string = user_msg.GetString(); - if (user_msg_string.empty()) { - return gtest_msg; - } + const Message& user_msg) +{ + // Appends the user message if it's non-empty. + const std::string user_msg_string = user_msg.GetString(); + if (user_msg_string.empty()) + { + return gtest_msg; + } - return gtest_msg + "\n" + user_msg_string; + return gtest_msg + "\n" + user_msg_string; } } // namespace internal @@ -1692,195 +1853,226 @@ std::string AppendUserMessage(const std::string& gtest_msg, // Creates an empty TestResult. TestResult::TestResult() - : death_test_count_(0), - elapsed_time_(0) { + : death_test_count_(0), + elapsed_time_(0) +{ } // D'tor. -TestResult::~TestResult() { +TestResult::~TestResult() +{ } // Returns the i-th test part result among all the results. i can // range from 0 to total_part_count() - 1. If i is not in that range, // aborts the program. -const TestPartResult& TestResult::GetTestPartResult(int i) const { - if (i < 0 || i >= total_part_count()) - internal::posix::Abort(); - return test_part_results_.at(i); +const TestPartResult& TestResult::GetTestPartResult(int i) const +{ + if (i < 0 || i >= total_part_count()) + internal::posix::Abort(); + return test_part_results_.at(i); } // Returns the i-th test property. i can range from 0 to // test_property_count() - 1. If i is not in that range, aborts the // program. -const TestProperty& TestResult::GetTestProperty(int i) const { - if (i < 0 || i >= test_property_count()) - internal::posix::Abort(); - return test_properties_.at(i); +const TestProperty& TestResult::GetTestProperty(int i) const +{ + if (i < 0 || i >= test_property_count()) + internal::posix::Abort(); + return test_properties_.at(i); } // Clears the test part results. -void TestResult::ClearTestPartResults() { - test_part_results_.clear(); +void TestResult::ClearTestPartResults() +{ + test_part_results_.clear(); } // Adds a test part result to the list. -void TestResult::AddTestPartResult(const TestPartResult& test_part_result) { - test_part_results_.push_back(test_part_result); +void TestResult::AddTestPartResult(const TestPartResult& test_part_result) +{ + test_part_results_.push_back(test_part_result); } // Adds a test property to the list. If a property with the same key as the // supplied property is already represented, the value of this test_property // replaces the old value for that key. void TestResult::RecordProperty(const std::string& xml_element, - const TestProperty& test_property) { - if (!ValidateTestProperty(xml_element, test_property)) { - return; - } - internal::MutexLock lock(&test_properites_mutex_); - const std::vector::iterator property_with_matching_key = - std::find_if(test_properties_.begin(), test_properties_.end(), - internal::TestPropertyKeyIs(test_property.key())); - if (property_with_matching_key == test_properties_.end()) { - test_properties_.push_back(test_property); - return; - } - property_with_matching_key->SetValue(test_property.value()); + const TestProperty& test_property) +{ + if (!ValidateTestProperty(xml_element, test_property)) + { + return; + } + internal::MutexLock lock(&test_properites_mutex_); + const std::vector::iterator property_with_matching_key = + std::find_if(test_properties_.begin(), test_properties_.end(), + internal::TestPropertyKeyIs(test_property.key())); + if (property_with_matching_key == test_properties_.end()) + { + test_properties_.push_back(test_property); + return; + } + property_with_matching_key->SetValue(test_property.value()); } // The list of reserved attributes used in the element of XML // output. static const char* const kReservedTestSuitesAttributes[] = { - "disabled", - "errors", - "failures", - "name", - "random_seed", - "tests", - "time", - "timestamp" -}; + "disabled", + "errors", + "failures", + "name", + "random_seed", + "tests", + "time", + "timestamp"}; // The list of reserved attributes used in the element of XML // output. static const char* const kReservedTestSuiteAttributes[] = { - "disabled", - "errors", - "failures", - "name", - "tests", - "time" -}; + "disabled", + "errors", + "failures", + "name", + "tests", + "time"}; // The list of reserved attributes used in the element of XML output. static const char* const kReservedTestCaseAttributes[] = { - "classname", - "name", - "status", - "time", - "type_param", - "value_param" -}; + "classname", + "name", + "status", + "time", + "type_param", + "value_param"}; template -std::vector ArrayAsVector(const char* const (&array)[kSize]) { - return std::vector(array, array + kSize); +std::vector ArrayAsVector(const char* const (&array)[kSize]) +{ + return std::vector(array, array + kSize); } static std::vector GetReservedAttributesForElement( - const std::string& xml_element) { - if (xml_element == "testsuites") { - return ArrayAsVector(kReservedTestSuitesAttributes); - } else if (xml_element == "testsuite") { - return ArrayAsVector(kReservedTestSuiteAttributes); - } else if (xml_element == "testcase") { - return ArrayAsVector(kReservedTestCaseAttributes); - } else { - GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element; - } - // This code is unreachable but some compilers may not realizes that. - return std::vector(); + const std::string& xml_element) +{ + if (xml_element == "testsuites") + { + return ArrayAsVector(kReservedTestSuitesAttributes); + } + else if (xml_element == "testsuite") + { + return ArrayAsVector(kReservedTestSuiteAttributes); + } + else if (xml_element == "testcase") + { + return ArrayAsVector(kReservedTestCaseAttributes); + } + else + { + GTEST_CHECK_(false) << "Unrecognized xml_element provided: " << xml_element; + } + // This code is unreachable but some compilers may not realizes that. + return std::vector(); } -static std::string FormatWordList(const std::vector& words) { - Message word_list; - for (size_t i = 0; i < words.size(); ++i) { - if (i > 0 && words.size() > 2) { - word_list << ", "; - } - if (i == words.size() - 1) { - word_list << "and "; - } - word_list << "'" << words[i] << "'"; - } - return word_list.GetString(); +static std::string FormatWordList(const std::vector& words) +{ + Message word_list; + for (size_t i = 0; i < words.size(); ++i) + { + if (i > 0 && words.size() > 2) + { + word_list << ", "; + } + if (i == words.size() - 1) + { + word_list << "and "; + } + word_list << "'" << words[i] << "'"; + } + return word_list.GetString(); } bool ValidateTestPropertyName(const std::string& property_name, - const std::vector& reserved_names) { - if (std::find(reserved_names.begin(), reserved_names.end(), property_name) != - reserved_names.end()) { - ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name - << " (" << FormatWordList(reserved_names) - << " are reserved by " << GTEST_NAME_ << ")"; - return false; - } - return true; + const std::vector& reserved_names) +{ + if (std::find(reserved_names.begin(), reserved_names.end(), property_name) != + reserved_names.end()) + { + ADD_FAILURE() << "Reserved key used in RecordProperty(): " << property_name + << " (" << FormatWordList(reserved_names) + << " are reserved by " << GTEST_NAME_ << ")"; + return false; + } + return true; } // Adds a failure if the key is a reserved attribute of the element named // xml_element. Returns true if the property is valid. bool TestResult::ValidateTestProperty(const std::string& xml_element, - const TestProperty& test_property) { - return ValidateTestPropertyName(test_property.key(), - GetReservedAttributesForElement(xml_element)); + const TestProperty& test_property) +{ + return ValidateTestPropertyName(test_property.key(), + GetReservedAttributesForElement(xml_element)); } // Clears the object. -void TestResult::Clear() { - test_part_results_.clear(); - test_properties_.clear(); - death_test_count_ = 0; - elapsed_time_ = 0; +void TestResult::Clear() +{ + test_part_results_.clear(); + test_properties_.clear(); + death_test_count_ = 0; + elapsed_time_ = 0; } // Returns true iff the test failed. -bool TestResult::Failed() const { - for (int i = 0; i < total_part_count(); ++i) { - if (GetTestPartResult(i).failed()) - return true; - } - return false; +bool TestResult::Failed() const +{ + for (int i = 0; i < total_part_count(); ++i) + { + if (GetTestPartResult(i).failed()) + return true; + } + return false; } // Returns true iff the test part fatally failed. -static bool TestPartFatallyFailed(const TestPartResult& result) { - return result.fatally_failed(); +static bool TestPartFatallyFailed(const TestPartResult& result) +{ + return result.fatally_failed(); } // Returns true iff the test fatally failed. -bool TestResult::HasFatalFailure() const { - return CountIf(test_part_results_, TestPartFatallyFailed) > 0; +bool TestResult::HasFatalFailure() const +{ + return CountIf(test_part_results_, TestPartFatallyFailed) > 0; } // Returns true iff the test part non-fatally failed. -static bool TestPartNonfatallyFailed(const TestPartResult& result) { - return result.nonfatally_failed(); +static bool TestPartNonfatallyFailed(const TestPartResult& result) +{ + return result.nonfatally_failed(); } // Returns true iff the test has a non-fatal failure. -bool TestResult::HasNonfatalFailure() const { - return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; +bool TestResult::HasNonfatalFailure() const +{ + return CountIf(test_part_results_, TestPartNonfatallyFailed) > 0; } // Gets the number of all test parts. This is the sum of the number // of successful test parts and the number of failed test parts. -int TestResult::total_part_count() const { - return static_cast(test_part_results_.size()); +int TestResult::total_part_count() const +{ + return static_cast(test_part_results_.size()); } // Returns the number of the test properties. -int TestResult::test_property_count() const { - return static_cast(test_properties_.size()); +int TestResult::test_property_count() const +{ + return static_cast(test_properties_.size()); } // class Test @@ -1889,50 +2081,57 @@ int TestResult::test_property_count() const { // The c'tor saves the values of all Google Test flags. Test::Test() - : gtest_flag_saver_(new internal::GTestFlagSaver) { + : gtest_flag_saver_(new internal::GTestFlagSaver) +{ } // The d'tor restores the values of all Google Test flags. -Test::~Test() { - delete gtest_flag_saver_; +Test::~Test() +{ + delete gtest_flag_saver_; } // Sets up the test fixture. // // A sub-class may override this. -void Test::SetUp() { +void Test::SetUp() +{ } // Tears down the test fixture. // // A sub-class may override this. -void Test::TearDown() { +void Test::TearDown() +{ } // Allows user supplied key value pairs to be recorded for later output. -void Test::RecordProperty(const std::string& key, const std::string& value) { - UnitTest::GetInstance()->RecordProperty(key, value); +void Test::RecordProperty(const std::string& key, const std::string& value) +{ + UnitTest::GetInstance()->RecordProperty(key, value); } // Allows user supplied key value pairs to be recorded for later output. -void Test::RecordProperty(const std::string& key, int value) { - Message value_message; - value_message << value; - RecordProperty(key, value_message.GetString().c_str()); +void Test::RecordProperty(const std::string& key, int value) +{ + Message value_message; + value_message << value; + RecordProperty(key, value_message.GetString().c_str()); } -namespace internal { - +namespace internal +{ void ReportFailureInUnknownLocation(TestPartResult::Type result_type, - const std::string& message) { - // This function is a friend of UnitTest and as such has access to - // AddTestPartResult. - UnitTest::GetInstance()->AddTestPartResult( - result_type, - NULL, // No info about the source file where the exception occurred. - -1, // We have no info on which line caused the exception. - message, - ""); // No stack trace, either. + const std::string& message) +{ + // This function is a friend of UnitTest and as such has access to + // AddTestPartResult. + UnitTest::GetInstance()->AddTestPartResult( + result_type, + NULL, // No info about the source file where the exception occurred. + -1, // We have no info on which line caused the exception. + message, + ""); // No stack trace, either. } } // namespace internal @@ -1942,65 +2141,70 @@ void ReportFailureInUnknownLocation(TestPartResult::Type result_type, // same fixture class as the first test in the current test case. If // yes, it returns true; otherwise it generates a Google Test failure and // returns false. -bool Test::HasSameFixtureClass() { - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - const TestCase* const test_case = impl->current_test_case(); +bool Test::HasSameFixtureClass() +{ + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + const TestCase* const test_case = impl->current_test_case(); - // Info about the first test in the current test case. - const TestInfo* const first_test_info = test_case->test_info_list()[0]; - const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_; - const char* const first_test_name = first_test_info->name(); + // Info about the first test in the current test case. + const TestInfo* const first_test_info = test_case->test_info_list()[0]; + const internal::TypeId first_fixture_id = first_test_info->fixture_class_id_; + const char* const first_test_name = first_test_info->name(); - // Info about the current test. - const TestInfo* const this_test_info = impl->current_test_info(); - const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_; - const char* const this_test_name = this_test_info->name(); + // Info about the current test. + const TestInfo* const this_test_info = impl->current_test_info(); + const internal::TypeId this_fixture_id = this_test_info->fixture_class_id_; + const char* const this_test_name = this_test_info->name(); - if (this_fixture_id != first_fixture_id) { - // Is the first test defined using TEST? - const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); - // Is this test defined using TEST? - const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); + if (this_fixture_id != first_fixture_id) + { + // Is the first test defined using TEST? + const bool first_is_TEST = first_fixture_id == internal::GetTestTypeId(); + // Is this test defined using TEST? + const bool this_is_TEST = this_fixture_id == internal::GetTestTypeId(); - if (first_is_TEST || this_is_TEST) { - // The user mixed TEST and TEST_F in this test case - we'll tell - // him/her how to fix it. + if (first_is_TEST || this_is_TEST) + { + // The user mixed TEST and TEST_F in this test case - we'll tell + // him/her how to fix it. - // Gets the name of the TEST and the name of the TEST_F. Note - // that first_is_TEST and this_is_TEST cannot both be true, as - // the fixture IDs are different for the two tests. - const char* const TEST_name = - first_is_TEST ? first_test_name : this_test_name; - const char* const TEST_F_name = - first_is_TEST ? this_test_name : first_test_name; + // Gets the name of the TEST and the name of the TEST_F. Note + // that first_is_TEST and this_is_TEST cannot both be true, as + // the fixture IDs are different for the two tests. + const char* const TEST_name = + first_is_TEST ? first_test_name : this_test_name; + const char* const TEST_F_name = + first_is_TEST ? this_test_name : first_test_name; - ADD_FAILURE() - << "All tests in the same test case must use the same test fixture\n" - << "class, so mixing TEST_F and TEST in the same test case is\n" - << "illegal. In test case " << this_test_info->test_case_name() - << ",\n" - << "test " << TEST_F_name << " is defined using TEST_F but\n" - << "test " << TEST_name << " is defined using TEST. You probably\n" - << "want to change the TEST to TEST_F or move it to another test\n" - << "case."; - } else { - // The user defined two fixture classes with the same name in - // two namespaces - we'll tell him/her how to fix it. - ADD_FAILURE() - << "All tests in the same test case must use the same test fixture\n" - << "class. However, in test case " - << this_test_info->test_case_name() << ",\n" - << "you defined test " << first_test_name - << " and test " << this_test_name << "\n" - << "using two different test fixture classes. This can happen if\n" - << "the two classes are from different namespaces or translation\n" - << "units and have the same name. You should probably rename one\n" - << "of the classes to put the tests into different test cases."; - } - return false; - } + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class, so mixing TEST_F and TEST in the same test case is\n" + << "illegal. In test case " << this_test_info->test_case_name() + << ",\n" + << "test " << TEST_F_name << " is defined using TEST_F but\n" + << "test " << TEST_name << " is defined using TEST. You probably\n" + << "want to change the TEST to TEST_F or move it to another test\n" + << "case."; + } + else + { + // The user defined two fixture classes with the same name in + // two namespaces - we'll tell him/her how to fix it. + ADD_FAILURE() + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " + << this_test_info->test_case_name() << ",\n" + << "you defined test " << first_test_name + << " and test " << this_test_name << "\n" + << "using two different test fixture classes. This can happen if\n" + << "the two classes are from different namespaces or translation\n" + << "units and have the same name. You should probably rename one\n" + << "of the classes to put the tests into different test cases."; + } + return false; + } - return true; + return true; } #if GTEST_HAS_SEH @@ -2010,40 +2214,44 @@ bool Test::HasSameFixtureClass() { // prohibits creation of objects with destructors on stack in functions // using __try (see error C2712). static std::string* FormatSehExceptionMessage(DWORD exception_code, - const char* location) { - Message message; - message << "SEH exception with code 0x" << std::setbase(16) << - exception_code << std::setbase(10) << " thrown in " << location << "."; + const char* location) +{ + Message message; + message << "SEH exception with code 0x" << std::setbase(16) << exception_code << std::setbase(10) << " thrown in " << location << "."; - return new std::string(message.GetString()); + return new std::string(message.GetString()); } #endif // GTEST_HAS_SEH -namespace internal { - +namespace internal +{ #if GTEST_HAS_EXCEPTIONS // Adds an "exception thrown" fatal failure to the current test. static std::string FormatCxxExceptionMessage(const char* description, - const char* location) { - Message message; - if (description != NULL) { - message << "C++ exception with description \"" << description << "\""; - } else { - message << "Unknown C++ exception"; - } - message << " thrown in " << location << "."; + const char* location) +{ + Message message; + if (description != NULL) + { + message << "C++ exception with description \"" << description << "\""; + } + else + { + message << "Unknown C++ exception"; + } + message << " thrown in " << location << "."; - return message.GetString(); + return message.GetString(); } static std::string PrintTestPartResultToString( - const TestPartResult& test_part_result); + const TestPartResult& test_part_result); GoogleTestFailureException::GoogleTestFailureException( - const TestPartResult& failure) - : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} + const TestPartResult& failure) + : ::std::runtime_error(PrintTestPartResultToString(failure).c_str()) {} #endif // GTEST_HAS_EXCEPTIONS @@ -2057,25 +2265,29 @@ GoogleTestFailureException::GoogleTestFailureException( // wrapper function for handling SEH exceptions.) template Result HandleSehExceptionsInMethodIfSupported( - T* object, Result (T::*method)(), const char* location) { + T* object, Result (T::*method)(), const char* location) +{ #if GTEST_HAS_SEH - __try { - return (object->*method)(); - } __except (internal::UnitTestOptions::GTestShouldProcessSEH( // NOLINT - GetExceptionCode())) { - // We create the exception message on the heap because VC++ prohibits - // creation of objects with destructors on stack in functions using __try - // (see error C2712). - std::string* exception_message = FormatSehExceptionMessage( - GetExceptionCode(), location); - internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, - *exception_message); - delete exception_message; - return static_cast(0); - } + __try + { + return (object->*method)(); + } + __except (internal::UnitTestOptions::GTestShouldProcessSEH( // NOLINT + GetExceptionCode())) + { + // We create the exception message on the heap because VC++ prohibits + // creation of objects with destructors on stack in functions using __try + // (see error C2712). + std::string* exception_message = FormatSehExceptionMessage( + GetExceptionCode(), location); + internal::ReportFailureInUnknownLocation(TestPartResult::kFatalFailure, + *exception_message); + delete exception_message; + return static_cast(0); + } #else - (void)location; - return (object->*method)(); + (void)location; + return (object->*method)(); #endif // GTEST_HAS_SEH } @@ -2084,90 +2296,104 @@ Result HandleSehExceptionsInMethodIfSupported( // Result in case of an SEH exception. template Result HandleExceptionsInMethodIfSupported( - T* object, Result (T::*method)(), const char* location) { - // NOTE: The user code can affect the way in which Google Test handles - // exceptions by setting GTEST_FLAG(catch_exceptions), but only before - // RUN_ALL_TESTS() starts. It is technically possible to check the flag - // after the exception is caught and either report or re-throw the - // exception based on the flag's value: - // - // try { - // // Perform the test method. - // } catch (...) { - // if (GTEST_FLAG(catch_exceptions)) - // // Report the exception as failure. - // else - // throw; // Re-throws the original exception. - // } - // - // However, the purpose of this flag is to allow the program to drop into - // the debugger when the exception is thrown. On most platforms, once the - // control enters the catch block, the exception origin information is - // lost and the debugger will stop the program at the point of the - // re-throw in this function -- instead of at the point of the original - // throw statement in the code under test. For this reason, we perform - // the check early, sacrificing the ability to affect Google Test's - // exception handling in the method where the exception is thrown. - if (internal::GetUnitTestImpl()->catch_exceptions()) { + T* object, Result (T::*method)(), const char* location) +{ + // NOTE: The user code can affect the way in which Google Test handles + // exceptions by setting GTEST_FLAG(catch_exceptions), but only before + // RUN_ALL_TESTS() starts. It is technically possible to check the flag + // after the exception is caught and either report or re-throw the + // exception based on the flag's value: + // + // try { + // // Perform the test method. + // } catch (...) { + // if (GTEST_FLAG(catch_exceptions)) + // // Report the exception as failure. + // else + // throw; // Re-throws the original exception. + // } + // + // However, the purpose of this flag is to allow the program to drop into + // the debugger when the exception is thrown. On most platforms, once the + // control enters the catch block, the exception origin information is + // lost and the debugger will stop the program at the point of the + // re-throw in this function -- instead of at the point of the original + // throw statement in the code under test. For this reason, we perform + // the check early, sacrificing the ability to affect Google Test's + // exception handling in the method where the exception is thrown. + if (internal::GetUnitTestImpl()->catch_exceptions()) + { #if GTEST_HAS_EXCEPTIONS - try { - return HandleSehExceptionsInMethodIfSupported(object, method, location); - } catch (const internal::GoogleTestFailureException&) { // NOLINT - // This exception type can only be thrown by a failed Google - // Test assertion with the intention of letting another testing - // framework catch it. Therefore we just re-throw it. - throw; - } catch (const std::exception& e) { // NOLINT - internal::ReportFailureInUnknownLocation( - TestPartResult::kFatalFailure, - FormatCxxExceptionMessage(e.what(), location)); - } catch (...) { // NOLINT - internal::ReportFailureInUnknownLocation( - TestPartResult::kFatalFailure, - FormatCxxExceptionMessage(NULL, location)); - } - return static_cast(0); + try + { + return HandleSehExceptionsInMethodIfSupported(object, method, location); + } + catch (const internal::GoogleTestFailureException&) + { // NOLINT + // This exception type can only be thrown by a failed Google + // Test assertion with the intention of letting another testing + // framework catch it. Therefore we just re-throw it. + throw; + } + catch (const std::exception& e) + { // NOLINT + internal::ReportFailureInUnknownLocation( + TestPartResult::kFatalFailure, + FormatCxxExceptionMessage(e.what(), location)); + } + catch (...) + { // NOLINT + internal::ReportFailureInUnknownLocation( + TestPartResult::kFatalFailure, + FormatCxxExceptionMessage(NULL, location)); + } + return static_cast(0); #else - return HandleSehExceptionsInMethodIfSupported(object, method, location); + return HandleSehExceptionsInMethodIfSupported(object, method, location); #endif // GTEST_HAS_EXCEPTIONS - } else { - return (object->*method)(); - } + } + else + { + return (object->*method)(); + } } } // namespace internal // Runs the test and updates the test result. -void Test::Run() { - if (!HasSameFixtureClass()) return; +void Test::Run() +{ + if (!HasSameFixtureClass()) return; - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - impl->os_stack_trace_getter()->UponLeavingGTest(); - internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()"); - // We will run the test only if SetUp() was successful. - if (!HasFatalFailure()) { - impl->os_stack_trace_getter()->UponLeavingGTest(); - internal::HandleExceptionsInMethodIfSupported( - this, &Test::TestBody, "the test body"); - } + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported(this, &Test::SetUp, "SetUp()"); + // We will run the test only if SetUp() was successful. + if (!HasFatalFailure()) + { + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &Test::TestBody, "the test body"); + } - // However, we want to clean up as much as possible. Hence we will - // always call TearDown(), even if SetUp() or the test body has - // failed. - impl->os_stack_trace_getter()->UponLeavingGTest(); - internal::HandleExceptionsInMethodIfSupported( - this, &Test::TearDown, "TearDown()"); + // However, we want to clean up as much as possible. Hence we will + // always call TearDown(), even if SetUp() or the test body has + // failed. + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &Test::TearDown, "TearDown()"); } // Returns true iff the current test has a fatal failure. -bool Test::HasFatalFailure() { - return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); +bool Test::HasFatalFailure() +{ + return internal::GetUnitTestImpl()->current_test_result()->HasFatalFailure(); } // Returns true iff the current test has a non-fatal failure. -bool Test::HasNonfatalFailure() { - return internal::GetUnitTestImpl()->current_test_result()-> - HasNonfatalFailure(); +bool Test::HasNonfatalFailure() +{ + return internal::GetUnitTestImpl()->current_test_result()->HasNonfatalFailure(); } // class TestInfo @@ -2175,27 +2401,27 @@ bool Test::HasNonfatalFailure() { // Constructs a TestInfo object. It assumes ownership of the test factory // object. TestInfo::TestInfo(const std::string& a_test_case_name, - const std::string& a_name, - const char* a_type_param, - const char* a_value_param, - internal::TypeId fixture_class_id, - internal::TestFactoryBase* factory) - : test_case_name_(a_test_case_name), - name_(a_name), - type_param_(a_type_param ? new std::string(a_type_param) : NULL), - value_param_(a_value_param ? new std::string(a_value_param) : NULL), - fixture_class_id_(fixture_class_id), - should_run_(false), - is_disabled_(false), - matches_filter_(false), - factory_(factory), - result_() {} + const std::string& a_name, + const char* a_type_param, + const char* a_value_param, + internal::TypeId fixture_class_id, + internal::TestFactoryBase* factory) + : test_case_name_(a_test_case_name), + name_(a_name), + type_param_(a_type_param ? new std::string(a_type_param) : NULL), + value_param_(a_value_param ? new std::string(a_value_param) : NULL), + fixture_class_id_(fixture_class_id), + should_run_(false), + is_disabled_(false), + matches_filter_(false), + factory_(factory), + result_() {} // Destructs a TestInfo object. TestInfo::~TestInfo() { delete factory_; } -namespace internal { - +namespace internal +{ // Creates a new TestInfo object and registers it with Google Test; // returns the created object. // @@ -2214,44 +2440,46 @@ namespace internal { // The newly created TestInfo instance will assume // ownership of the factory object. TestInfo* MakeAndRegisterTestInfo( - const char* test_case_name, - const char* name, - const char* type_param, - const char* value_param, - TypeId fixture_class_id, - SetUpTestCaseFunc set_up_tc, - TearDownTestCaseFunc tear_down_tc, - TestFactoryBase* factory) { - TestInfo* const test_info = - new TestInfo(test_case_name, name, type_param, value_param, - fixture_class_id, factory); - GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); - return test_info; + const char* test_case_name, + const char* name, + const char* type_param, + const char* value_param, + TypeId fixture_class_id, + SetUpTestCaseFunc set_up_tc, + TearDownTestCaseFunc tear_down_tc, + TestFactoryBase* factory) +{ + TestInfo* const test_info = + new TestInfo(test_case_name, name, type_param, value_param, + fixture_class_id, factory); + GetUnitTestImpl()->AddTestInfo(set_up_tc, tear_down_tc, test_info); + return test_info; } #if GTEST_HAS_PARAM_TEST void ReportInvalidTestCaseType(const char* test_case_name, - const char* file, int line) { - Message errors; - errors - << "Attempted redefinition of test case " << test_case_name << ".\n" - << "All tests in the same test case must use the same test fixture\n" - << "class. However, in test case " << test_case_name << ", you tried\n" - << "to define a test using a fixture class different from the one\n" - << "used earlier. This can happen if the two fixture classes are\n" - << "from different namespaces and have the same name. You should\n" - << "probably rename one of the classes to put the tests into different\n" - << "test cases."; + const char* file, int line) +{ + Message errors; + errors + << "Attempted redefinition of test case " << test_case_name << ".\n" + << "All tests in the same test case must use the same test fixture\n" + << "class. However, in test case " << test_case_name << ", you tried\n" + << "to define a test using a fixture class different from the one\n" + << "used earlier. This can happen if the two fixture classes are\n" + << "from different namespaces and have the same name. You should\n" + << "probably rename one of the classes to put the tests into different\n" + << "test cases."; - fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), - errors.GetString().c_str()); + fprintf(stderr, "%s %s", FormatFileLocation(file, line).c_str(), + errors.GetString().c_str()); } #endif // GTEST_HAS_PARAM_TEST } // namespace internal -namespace { - +namespace +{ // A predicate that checks the test name of a TestInfo against a known // value. // @@ -2260,36 +2488,40 @@ namespace { // namespace. // // TestNameIs is copyable. -class TestNameIs { - public: - // Constructor. - // - // TestNameIs has NO default constructor. - explicit TestNameIs(const char* name) - : name_(name) {} +class TestNameIs +{ +public: + // Constructor. + // + // TestNameIs has NO default constructor. + explicit TestNameIs(const char* name) + : name_(name) {} - // Returns true iff the test name of test_info matches name_. - bool operator()(const TestInfo * test_info) const { - return test_info && test_info->name() == name_; - } + // Returns true iff the test name of test_info matches name_. + bool operator()(const TestInfo* test_info) const + { + return test_info && test_info->name() == name_; + } - private: - std::string name_; +private: + std::string name_; }; } // namespace -namespace internal { - +namespace internal +{ // This method expands all parameterized tests registered with macros TEST_P // and INSTANTIATE_TEST_CASE_P into regular tests and registers those. // This will be done just once during the program runtime. -void UnitTestImpl::RegisterParameterizedTests() { +void UnitTestImpl::RegisterParameterizedTests() +{ #if GTEST_HAS_PARAM_TEST - if (!parameterized_tests_registered_) { - parameterized_test_registry_.RegisterTests(); - parameterized_tests_registered_ = true; - } + if (!parameterized_tests_registered_) + { + parameterized_test_registry_.RegisterTests(); + parameterized_tests_registered_ = true; + } #endif } @@ -2297,85 +2529,94 @@ void UnitTestImpl::RegisterParameterizedTests() { // Creates the test object, runs it, records its result, and then // deletes it. -void TestInfo::Run() { - if (!should_run_) return; +void TestInfo::Run() +{ + if (!should_run_) return; - // Tells UnitTest where to store test result. - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - impl->set_current_test_info(this); + // Tells UnitTest where to store test result. + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_info(this); - TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); - // Notifies the unit test event listeners that a test is about to start. - repeater->OnTestStart(*this); + // Notifies the unit test event listeners that a test is about to start. + repeater->OnTestStart(*this); - const TimeInMillis start = internal::GetTimeInMillis(); + const TimeInMillis start = internal::GetTimeInMillis(); - impl->os_stack_trace_getter()->UponLeavingGTest(); + impl->os_stack_trace_getter()->UponLeavingGTest(); - // Creates the test object. - Test* const test = internal::HandleExceptionsInMethodIfSupported( - factory_, &internal::TestFactoryBase::CreateTest, - "the test fixture's constructor"); + // Creates the test object. + Test* const test = internal::HandleExceptionsInMethodIfSupported( + factory_, &internal::TestFactoryBase::CreateTest, + "the test fixture's constructor"); - // Runs the test only if the test object was created and its - // constructor didn't generate a fatal failure. - if ((test != NULL) && !Test::HasFatalFailure()) { - // This doesn't throw as all user code that can throw are wrapped into - // exception handling code. - test->Run(); - } + // Runs the test only if the test object was created and its + // constructor didn't generate a fatal failure. + if ((test != NULL) && !Test::HasFatalFailure()) + { + // This doesn't throw as all user code that can throw are wrapped into + // exception handling code. + test->Run(); + } - // Deletes the test object. - impl->os_stack_trace_getter()->UponLeavingGTest(); - internal::HandleExceptionsInMethodIfSupported( - test, &Test::DeleteSelf_, "the test fixture's destructor"); + // Deletes the test object. + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + test, &Test::DeleteSelf_, "the test fixture's destructor"); - result_.set_elapsed_time(internal::GetTimeInMillis() - start); + result_.set_elapsed_time(internal::GetTimeInMillis() - start); - // Notifies the unit test event listener that a test has just finished. - repeater->OnTestEnd(*this); + // Notifies the unit test event listener that a test has just finished. + repeater->OnTestEnd(*this); - // Tells UnitTest to stop associating assertion results to this - // test. - impl->set_current_test_info(NULL); + // Tells UnitTest to stop associating assertion results to this + // test. + impl->set_current_test_info(NULL); } // class TestCase // Gets the number of successful tests in this test case. -int TestCase::successful_test_count() const { - return CountIf(test_info_list_, TestPassed); +int TestCase::successful_test_count() const +{ + return CountIf(test_info_list_, TestPassed); } // Gets the number of failed tests in this test case. -int TestCase::failed_test_count() const { - return CountIf(test_info_list_, TestFailed); +int TestCase::failed_test_count() const +{ + return CountIf(test_info_list_, TestFailed); } // Gets the number of disabled tests that will be reported in the XML report. -int TestCase::reportable_disabled_test_count() const { - return CountIf(test_info_list_, TestReportableDisabled); +int TestCase::reportable_disabled_test_count() const +{ + return CountIf(test_info_list_, TestReportableDisabled); } // Gets the number of disabled tests in this test case. -int TestCase::disabled_test_count() const { - return CountIf(test_info_list_, TestDisabled); +int TestCase::disabled_test_count() const +{ + return CountIf(test_info_list_, TestDisabled); } // Gets the number of tests to be printed in the XML report. -int TestCase::reportable_test_count() const { - return CountIf(test_info_list_, TestReportable); +int TestCase::reportable_test_count() const +{ + return CountIf(test_info_list_, TestReportable); } // Get the number of tests in this test case that should run. -int TestCase::test_to_run_count() const { - return CountIf(test_info_list_, ShouldRunTest); +int TestCase::test_to_run_count() const +{ + return CountIf(test_info_list_, ShouldRunTest); } // Gets the number of all tests. -int TestCase::total_test_count() const { - return static_cast(test_info_list_.size()); +int TestCase::total_test_count() const +{ + return static_cast(test_info_list_.size()); } // Creates a TestCase with the given name. @@ -2388,87 +2629,98 @@ int TestCase::total_test_count() const { // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case TestCase::TestCase(const char* a_name, const char* a_type_param, - Test::SetUpTestCaseFunc set_up_tc, - Test::TearDownTestCaseFunc tear_down_tc) - : name_(a_name), - type_param_(a_type_param ? new std::string(a_type_param) : NULL), - set_up_tc_(set_up_tc), - tear_down_tc_(tear_down_tc), - should_run_(false), - elapsed_time_(0) { + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) + : name_(a_name), + type_param_(a_type_param ? new std::string(a_type_param) : NULL), + set_up_tc_(set_up_tc), + tear_down_tc_(tear_down_tc), + should_run_(false), + elapsed_time_(0) +{ } // Destructor of TestCase. -TestCase::~TestCase() { - // Deletes every Test in the collection. - ForEach(test_info_list_, internal::Delete); +TestCase::~TestCase() +{ + // Deletes every Test in the collection. + ForEach(test_info_list_, internal::Delete); } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. -const TestInfo* TestCase::GetTestInfo(int i) const { - const int index = GetElementOr(test_indices_, i, -1); - return index < 0 ? NULL : test_info_list_[index]; +const TestInfo* TestCase::GetTestInfo(int i) const +{ + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; } // Returns the i-th test among all the tests. i can range from 0 to // total_test_count() - 1. If i is not in that range, returns NULL. -TestInfo* TestCase::GetMutableTestInfo(int i) { - const int index = GetElementOr(test_indices_, i, -1); - return index < 0 ? NULL : test_info_list_[index]; +TestInfo* TestCase::GetMutableTestInfo(int i) +{ + const int index = GetElementOr(test_indices_, i, -1); + return index < 0 ? NULL : test_info_list_[index]; } // Adds a test to this test case. Will delete the test upon // destruction of the TestCase object. -void TestCase::AddTestInfo(TestInfo * test_info) { - test_info_list_.push_back(test_info); - test_indices_.push_back(static_cast(test_indices_.size())); +void TestCase::AddTestInfo(TestInfo* test_info) +{ + test_info_list_.push_back(test_info); + test_indices_.push_back(static_cast(test_indices_.size())); } // Runs every test in this TestCase. -void TestCase::Run() { - if (!should_run_) return; +void TestCase::Run() +{ + if (!should_run_) return; - internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); - impl->set_current_test_case(this); + internal::UnitTestImpl* const impl = internal::GetUnitTestImpl(); + impl->set_current_test_case(this); - TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); + TestEventListener* repeater = UnitTest::GetInstance()->listeners().repeater(); - repeater->OnTestCaseStart(*this); - impl->os_stack_trace_getter()->UponLeavingGTest(); - internal::HandleExceptionsInMethodIfSupported( - this, &TestCase::RunSetUpTestCase, "SetUpTestCase()"); + repeater->OnTestCaseStart(*this); + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &TestCase::RunSetUpTestCase, "SetUpTestCase()"); - const internal::TimeInMillis start = internal::GetTimeInMillis(); - for (int i = 0; i < total_test_count(); i++) { - GetMutableTestInfo(i)->Run(); - } - elapsed_time_ = internal::GetTimeInMillis() - start; + const internal::TimeInMillis start = internal::GetTimeInMillis(); + for (int i = 0; i < total_test_count(); i++) + { + GetMutableTestInfo(i)->Run(); + } + elapsed_time_ = internal::GetTimeInMillis() - start; - impl->os_stack_trace_getter()->UponLeavingGTest(); - internal::HandleExceptionsInMethodIfSupported( - this, &TestCase::RunTearDownTestCase, "TearDownTestCase()"); + impl->os_stack_trace_getter()->UponLeavingGTest(); + internal::HandleExceptionsInMethodIfSupported( + this, &TestCase::RunTearDownTestCase, "TearDownTestCase()"); - repeater->OnTestCaseEnd(*this); - impl->set_current_test_case(NULL); + repeater->OnTestCaseEnd(*this); + impl->set_current_test_case(NULL); } // Clears the results of all tests in this test case. -void TestCase::ClearResult() { - ad_hoc_test_result_.Clear(); - ForEach(test_info_list_, TestInfo::ClearTestResult); +void TestCase::ClearResult() +{ + ad_hoc_test_result_.Clear(); + ForEach(test_info_list_, TestInfo::ClearTestResult); } // Shuffles the tests in this test case. -void TestCase::ShuffleTests(internal::Random* random) { - Shuffle(random, &test_indices_); +void TestCase::ShuffleTests(internal::Random* random) +{ + Shuffle(random, &test_indices_); } // Restores the test order to before the first shuffle. -void TestCase::UnshuffleTests() { - for (size_t i = 0; i < test_indices_.size(); i++) { - test_indices_[i] = static_cast(i); - } +void TestCase::UnshuffleTests() +{ + for (size_t i = 0; i < test_indices_.size(); i++) + { + test_indices_[i] = static_cast(i); + } } // Formats a countable noun. Depending on its quantity, either the @@ -2477,191 +2729,216 @@ void TestCase::UnshuffleTests() { // FormatCountableNoun(1, "formula", "formuli") returns "1 formula". // FormatCountableNoun(5, "book", "books") returns "5 books". static std::string FormatCountableNoun(int count, - const char * singular_form, - const char * plural_form) { - return internal::StreamableToString(count) + " " + - (count == 1 ? singular_form : plural_form); + const char* singular_form, + const char* plural_form) +{ + return internal::StreamableToString(count) + " " + + (count == 1 ? singular_form : plural_form); } // Formats the count of tests. -static std::string FormatTestCount(int test_count) { - return FormatCountableNoun(test_count, "test", "tests"); +static std::string FormatTestCount(int test_count) +{ + return FormatCountableNoun(test_count, "test", "tests"); } // Formats the count of test cases. -static std::string FormatTestCaseCount(int test_case_count) { - return FormatCountableNoun(test_case_count, "test case", "test cases"); +static std::string FormatTestCaseCount(int test_case_count) +{ + return FormatCountableNoun(test_case_count, "test case", "test cases"); } // Converts a TestPartResult::Type enum to human-friendly string // representation. Both kNonFatalFailure and kFatalFailure are translated // to "Failure", as the user usually doesn't care about the difference // between the two when viewing the test result. -static const char * TestPartResultTypeToString(TestPartResult::Type type) { - switch (type) { - case TestPartResult::kSuccess: - return "Success"; +static const char* TestPartResultTypeToString(TestPartResult::Type type) +{ + switch (type) + { + case TestPartResult::kSuccess: + return "Success"; - case TestPartResult::kNonFatalFailure: - case TestPartResult::kFatalFailure: + case TestPartResult::kNonFatalFailure: + case TestPartResult::kFatalFailure: #ifdef _MSC_VER - return "error: "; + return "error: "; #else - return "Failure\n"; + return "Failure\n"; #endif - default: - return "Unknown result type"; - } + default: + return "Unknown result type"; + } } -namespace internal { - +namespace internal +{ // Prints a TestPartResult to an std::string. static std::string PrintTestPartResultToString( - const TestPartResult& test_part_result) { - return (Message() - << internal::FormatFileLocation(test_part_result.file_name(), - test_part_result.line_number()) - << " " << TestPartResultTypeToString(test_part_result.type()) - << test_part_result.message()).GetString(); + const TestPartResult& test_part_result) +{ + return (Message() + << internal::FormatFileLocation(test_part_result.file_name(), + test_part_result.line_number()) + << " " << TestPartResultTypeToString(test_part_result.type()) + << test_part_result.message()) + .GetString(); } // Prints a TestPartResult. -static void PrintTestPartResult(const TestPartResult& test_part_result) { - const std::string& result = - PrintTestPartResultToString(test_part_result); - printf("%s\n", result.c_str()); - fflush(stdout); - // If the test program runs in Visual Studio or a debugger, the - // following statements add the test part result message to the Output - // window such that the user can double-click on it to jump to the - // corresponding source code location; otherwise they do nothing. +static void PrintTestPartResult(const TestPartResult& test_part_result) +{ + const std::string& result = + PrintTestPartResultToString(test_part_result); + printf("%s\n", result.c_str()); + fflush(stdout); + // If the test program runs in Visual Studio or a debugger, the + // following statements add the test part result message to the Output + // window such that the user can double-click on it to jump to the + // corresponding source code location; otherwise they do nothing. #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE - // We don't call OutputDebugString*() on Windows Mobile, as printing - // to stdout is done by OutputDebugString() there already - we don't - // want the same message printed twice. - ::OutputDebugStringA(result.c_str()); - ::OutputDebugStringA("\n"); + // We don't call OutputDebugString*() on Windows Mobile, as printing + // to stdout is done by OutputDebugString() there already - we don't + // want the same message printed twice. + ::OutputDebugStringA(result.c_str()); + ::OutputDebugStringA("\n"); #endif } // class PrettyUnitTestResultPrinter -enum GTestColor { - COLOR_DEFAULT, - COLOR_RED, - COLOR_GREEN, - COLOR_YELLOW +enum GTestColor +{ + COLOR_DEFAULT, + COLOR_RED, + COLOR_GREEN, + COLOR_YELLOW }; #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE // Returns the character attribute for the given color. -WORD GetColorAttribute(GTestColor color) { - switch (color) { - case COLOR_RED: return FOREGROUND_RED; - case COLOR_GREEN: return FOREGROUND_GREEN; - case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; - default: return 0; - } +WORD GetColorAttribute(GTestColor color) +{ + switch (color) + { + case COLOR_RED: + return FOREGROUND_RED; + case COLOR_GREEN: + return FOREGROUND_GREEN; + case COLOR_YELLOW: + return FOREGROUND_RED | FOREGROUND_GREEN; + default: + return 0; + } } #else // Returns the ANSI color code for the given color. COLOR_DEFAULT is // an invalid input. -const char* GetAnsiColorCode(GTestColor color) { - switch (color) { - case COLOR_RED: return "1"; - case COLOR_GREEN: return "2"; - case COLOR_YELLOW: return "3"; - default: return NULL; - }; +const char* GetAnsiColorCode(GTestColor color) +{ + switch (color) + { + case COLOR_RED: + return "1"; + case COLOR_GREEN: + return "2"; + case COLOR_YELLOW: + return "3"; + default: + return NULL; + }; } #endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE // Returns true iff Google Test should use colors in the output. -bool ShouldUseColor(bool stdout_is_tty) { - const char* const gtest_color = GTEST_FLAG(color).c_str(); +bool ShouldUseColor(bool stdout_is_tty) +{ + const char* const gtest_color = GTEST_FLAG(color).c_str(); - if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) { + if (String::CaseInsensitiveCStringEquals(gtest_color, "auto")) + { #if GTEST_OS_WINDOWS - // On Windows the TERM variable is usually not set, but the - // console there does support colors. - return stdout_is_tty; + // On Windows the TERM variable is usually not set, but the + // console there does support colors. + return stdout_is_tty; #else - // On non-Windows platforms, we rely on the TERM variable. - const char* const term = posix::GetEnv("TERM"); - const bool term_supports_color = - String::CStringEquals(term, "xterm") || - String::CStringEquals(term, "xterm-color") || - String::CStringEquals(term, "xterm-256color") || - String::CStringEquals(term, "screen") || - String::CStringEquals(term, "screen-256color") || - String::CStringEquals(term, "linux") || - String::CStringEquals(term, "cygwin"); - return stdout_is_tty && term_supports_color; + // On non-Windows platforms, we rely on the TERM variable. + const char* const term = posix::GetEnv("TERM"); + const bool term_supports_color = + String::CStringEquals(term, "xterm") || + String::CStringEquals(term, "xterm-color") || + String::CStringEquals(term, "xterm-256color") || + String::CStringEquals(term, "screen") || + String::CStringEquals(term, "screen-256color") || + String::CStringEquals(term, "linux") || + String::CStringEquals(term, "cygwin"); + return stdout_is_tty && term_supports_color; #endif // GTEST_OS_WINDOWS - } + } - return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || - String::CaseInsensitiveCStringEquals(gtest_color, "true") || - String::CaseInsensitiveCStringEquals(gtest_color, "t") || - String::CStringEquals(gtest_color, "1"); - // We take "yes", "true", "t", and "1" as meaning "yes". If the - // value is neither one of these nor "auto", we treat it as "no" to - // be conservative. + return String::CaseInsensitiveCStringEquals(gtest_color, "yes") || + String::CaseInsensitiveCStringEquals(gtest_color, "true") || + String::CaseInsensitiveCStringEquals(gtest_color, "t") || + String::CStringEquals(gtest_color, "1"); + // We take "yes", "true", "t", and "1" as meaning "yes". If the + // value is neither one of these nor "auto", we treat it as "no" to + // be conservative. } // Helpers for printing colored strings to stdout. Note that on Windows, we // cannot simply emit special characters and have the terminal change colors. // This routine must actually emit the characters rather than return a string // that would be colored when printed, as can be done on Linux. -void ColoredPrintf(GTestColor color, const char* fmt, ...) { - va_list args; - va_start(args, fmt); +void ColoredPrintf(GTestColor color, const char* fmt, ...) +{ + va_list args; + va_start(args, fmt); #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS || GTEST_OS_IOS - const bool use_color = false; + const bool use_color = false; #else - static const bool in_color_mode = - ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); - const bool use_color = in_color_mode && (color != COLOR_DEFAULT); + static const bool in_color_mode = + ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); + const bool use_color = in_color_mode && (color != COLOR_DEFAULT); #endif // GTEST_OS_WINDOWS_MOBILE || GTEST_OS_SYMBIAN || GTEST_OS_ZOS - // The '!= 0' comparison is necessary to satisfy MSVC 7.1. + // The '!= 0' comparison is necessary to satisfy MSVC 7.1. - if (!use_color) { - vprintf(fmt, args); - va_end(args); - return; - } + if (!use_color) + { + vprintf(fmt, args); + va_end(args); + return; + } #if GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE - const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); + const HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE); - // Gets the current text color. - CONSOLE_SCREEN_BUFFER_INFO buffer_info; - GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); - const WORD old_color_attrs = buffer_info.wAttributes; + // Gets the current text color. + CONSOLE_SCREEN_BUFFER_INFO buffer_info; + GetConsoleScreenBufferInfo(stdout_handle, &buffer_info); + const WORD old_color_attrs = buffer_info.wAttributes; - // We need to flush the stream buffers into the console before each - // SetConsoleTextAttribute call lest it affect the text that is already - // printed but has not yet reached the console. - fflush(stdout); - SetConsoleTextAttribute(stdout_handle, - GetColorAttribute(color) | FOREGROUND_INTENSITY); - vprintf(fmt, args); + // We need to flush the stream buffers into the console before each + // SetConsoleTextAttribute call lest it affect the text that is already + // printed but has not yet reached the console. + fflush(stdout); + SetConsoleTextAttribute(stdout_handle, + GetColorAttribute(color) | FOREGROUND_INTENSITY); + vprintf(fmt, args); - fflush(stdout); - // Restores the text color. - SetConsoleTextAttribute(stdout_handle, old_color_attrs); + fflush(stdout); + // Restores the text color. + SetConsoleTextAttribute(stdout_handle, old_color_attrs); #else - printf("\033[0;3%sm", GetAnsiColorCode(color)); - vprintf(fmt, args); - printf("\033[m"); // Resets the terminal to default. + printf("\033[0;3%sm", GetAnsiColorCode(color)); + vprintf(fmt, args); + printf("\033[m"); // Resets the terminal to default. #endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MOBILE - va_end(args); + va_end(args); } // Text printed in Google Test's text output and --gunit_list_tests @@ -2669,226 +2946,264 @@ void ColoredPrintf(GTestColor color, const char* fmt, ...) { static const char kTypeParamLabel[] = "TypeParam"; static const char kValueParamLabel[] = "GetParam()"; -void PrintFullTestCommentIfPresent(const TestInfo& test_info) { - const char* const type_param = test_info.type_param(); - const char* const value_param = test_info.value_param(); +void PrintFullTestCommentIfPresent(const TestInfo& test_info) +{ + const char* const type_param = test_info.type_param(); + const char* const value_param = test_info.value_param(); - if (type_param != NULL || value_param != NULL) { - printf(", where "); - if (type_param != NULL) { - printf("%s = %s", kTypeParamLabel, type_param); - if (value_param != NULL) - printf(" and "); - } - if (value_param != NULL) { - printf("%s = %s", kValueParamLabel, value_param); - } - } + if (type_param != NULL || value_param != NULL) + { + printf(", where "); + if (type_param != NULL) + { + printf("%s = %s", kTypeParamLabel, type_param); + if (value_param != NULL) + printf(" and "); + } + if (value_param != NULL) + { + printf("%s = %s", kValueParamLabel, value_param); + } + } } // This class implements the TestEventListener interface. // // Class PrettyUnitTestResultPrinter is copyable. -class PrettyUnitTestResultPrinter : public TestEventListener { - public: - PrettyUnitTestResultPrinter() {} - static void PrintTestName(const char * test_case, const char * test) { - printf("%s.%s", test_case, test); - } +class PrettyUnitTestResultPrinter : public TestEventListener +{ +public: + PrettyUnitTestResultPrinter() {} + static void PrintTestName(const char* test_case, const char* test) + { + printf("%s.%s", test_case, test); + } - // The following methods override what's in the TestEventListener class. - virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} - virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); - virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); - virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} - virtual void OnTestCaseStart(const TestCase& test_case); - virtual void OnTestStart(const TestInfo& test_info); - virtual void OnTestPartResult(const TestPartResult& result); - virtual void OnTestEnd(const TestInfo& test_info); - virtual void OnTestCaseEnd(const TestCase& test_case); - virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); - virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} - virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); - virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} + // The following methods override what's in the TestEventListener class. + virtual void OnTestProgramStart(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& /*unit_test*/) {} + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& /*unit_test*/) {} - private: - static void PrintFailedTests(const UnitTest& unit_test); +private: + static void PrintFailedTests(const UnitTest& unit_test); }; - // Fired before each iteration of tests starts. +// Fired before each iteration of tests starts. void PrettyUnitTestResultPrinter::OnTestIterationStart( - const UnitTest& unit_test, int iteration) { - if (GTEST_FLAG(repeat) != 1) - printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); + const UnitTest& unit_test, int iteration) +{ + if (GTEST_FLAG(repeat) != 1) + printf("\nRepeating all tests (iteration %d) . . .\n\n", iteration + 1); - const char* const filter = GTEST_FLAG(filter).c_str(); + const char* const filter = GTEST_FLAG(filter).c_str(); - // Prints the filter if it's not *. This reminds the user that some - // tests may be skipped. - if (!String::CStringEquals(filter, kUniversalFilter)) { - ColoredPrintf(COLOR_YELLOW, - "Note: %s filter = %s\n", GTEST_NAME_, filter); - } + // Prints the filter if it's not *. This reminds the user that some + // tests may be skipped. + if (!String::CStringEquals(filter, kUniversalFilter)) + { + ColoredPrintf(COLOR_YELLOW, + "Note: %s filter = %s\n", GTEST_NAME_, filter); + } - if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) { - const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); - ColoredPrintf(COLOR_YELLOW, - "Note: This is test shard %d of %s.\n", - static_cast(shard_index) + 1, - internal::posix::GetEnv(kTestTotalShards)); - } + if (internal::ShouldShard(kTestTotalShards, kTestShardIndex, false)) + { + const Int32 shard_index = Int32FromEnvOrDie(kTestShardIndex, -1); + ColoredPrintf(COLOR_YELLOW, + "Note: This is test shard %d of %s.\n", + static_cast(shard_index) + 1, + internal::posix::GetEnv(kTestTotalShards)); + } - if (GTEST_FLAG(shuffle)) { - ColoredPrintf(COLOR_YELLOW, - "Note: Randomizing tests' orders with a seed of %d .\n", - unit_test.random_seed()); - } + if (GTEST_FLAG(shuffle)) + { + ColoredPrintf(COLOR_YELLOW, + "Note: Randomizing tests' orders with a seed of %d .\n", + unit_test.random_seed()); + } - ColoredPrintf(COLOR_GREEN, "[==========] "); - printf("Running %s from %s.\n", - FormatTestCount(unit_test.test_to_run_count()).c_str(), - FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); - fflush(stdout); + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("Running %s from %s.\n", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + fflush(stdout); } void PrettyUnitTestResultPrinter::OnEnvironmentsSetUpStart( - const UnitTest& /*unit_test*/) { - ColoredPrintf(COLOR_GREEN, "[----------] "); - printf("Global test environment set-up.\n"); - fflush(stdout); + const UnitTest& /*unit_test*/) +{ + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment set-up.\n"); + fflush(stdout); } -void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) { - const std::string counts = - FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); - ColoredPrintf(COLOR_GREEN, "[----------] "); - printf("%s from %s", counts.c_str(), test_case.name()); - if (test_case.type_param() == NULL) { - printf("\n"); - } else { - printf(", where %s = %s\n", kTypeParamLabel, test_case.type_param()); - } - fflush(stdout); +void PrettyUnitTestResultPrinter::OnTestCaseStart(const TestCase& test_case) +{ + const std::string counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s", counts.c_str(), test_case.name()); + if (test_case.type_param() == NULL) + { + printf("\n"); + } + else + { + printf(", where %s = %s\n", kTypeParamLabel, test_case.type_param()); + } + fflush(stdout); } -void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) { - ColoredPrintf(COLOR_GREEN, "[ RUN ] "); - PrintTestName(test_info.test_case_name(), test_info.name()); - printf("\n"); - fflush(stdout); +void PrettyUnitTestResultPrinter::OnTestStart(const TestInfo& test_info) +{ + ColoredPrintf(COLOR_GREEN, "[ RUN ] "); + PrintTestName(test_info.test_case_name(), test_info.name()); + printf("\n"); + fflush(stdout); } // Called after an assertion failure. void PrettyUnitTestResultPrinter::OnTestPartResult( - const TestPartResult& result) { - // If the test part succeeded, we don't need to do anything. - if (result.type() == TestPartResult::kSuccess) - return; + const TestPartResult& result) +{ + // If the test part succeeded, we don't need to do anything. + if (result.type() == TestPartResult::kSuccess) + return; - // Print failure message from the assertion (e.g. expected this and got that). - PrintTestPartResult(result); - fflush(stdout); + // Print failure message from the assertion (e.g. expected this and got that). + PrintTestPartResult(result); + fflush(stdout); } -void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) { - if (test_info.result()->Passed()) { - ColoredPrintf(COLOR_GREEN, "[ OK ] "); - } else { - ColoredPrintf(COLOR_RED, "[ FAILED ] "); - } - PrintTestName(test_info.test_case_name(), test_info.name()); - if (test_info.result()->Failed()) - PrintFullTestCommentIfPresent(test_info); +void PrettyUnitTestResultPrinter::OnTestEnd(const TestInfo& test_info) +{ + if (test_info.result()->Passed()) + { + ColoredPrintf(COLOR_GREEN, "[ OK ] "); + } + else + { + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + } + PrintTestName(test_info.test_case_name(), test_info.name()); + if (test_info.result()->Failed()) + PrintFullTestCommentIfPresent(test_info); - if (GTEST_FLAG(print_time)) { - printf(" (%s ms)\n", internal::StreamableToString( - test_info.result()->elapsed_time()).c_str()); - } else { - printf("\n"); - } - fflush(stdout); + if (GTEST_FLAG(print_time)) + { + printf(" (%s ms)\n", internal::StreamableToString( + test_info.result()->elapsed_time()) + .c_str()); + } + else + { + printf("\n"); + } + fflush(stdout); } -void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) { - if (!GTEST_FLAG(print_time)) return; +void PrettyUnitTestResultPrinter::OnTestCaseEnd(const TestCase& test_case) +{ + if (!GTEST_FLAG(print_time)) return; - const std::string counts = - FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); - ColoredPrintf(COLOR_GREEN, "[----------] "); - printf("%s from %s (%s ms total)\n\n", - counts.c_str(), test_case.name(), - internal::StreamableToString(test_case.elapsed_time()).c_str()); - fflush(stdout); + const std::string counts = + FormatCountableNoun(test_case.test_to_run_count(), "test", "tests"); + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("%s from %s (%s ms total)\n\n", + counts.c_str(), test_case.name(), + internal::StreamableToString(test_case.elapsed_time()).c_str()); + fflush(stdout); } void PrettyUnitTestResultPrinter::OnEnvironmentsTearDownStart( - const UnitTest& /*unit_test*/) { - ColoredPrintf(COLOR_GREEN, "[----------] "); - printf("Global test environment tear-down\n"); - fflush(stdout); + const UnitTest& /*unit_test*/) +{ + ColoredPrintf(COLOR_GREEN, "[----------] "); + printf("Global test environment tear-down\n"); + fflush(stdout); } // Internal helper for printing the list of failed tests. -void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) { - const int failed_test_count = unit_test.failed_test_count(); - if (failed_test_count == 0) { - return; - } +void PrettyUnitTestResultPrinter::PrintFailedTests(const UnitTest& unit_test) +{ + const int failed_test_count = unit_test.failed_test_count(); + if (failed_test_count == 0) + { + return; + } - for (int i = 0; i < unit_test.total_test_case_count(); ++i) { - const TestCase& test_case = *unit_test.GetTestCase(i); - if (!test_case.should_run() || (test_case.failed_test_count() == 0)) { - continue; - } - for (int j = 0; j < test_case.total_test_count(); ++j) { - const TestInfo& test_info = *test_case.GetTestInfo(j); - if (!test_info.should_run() || test_info.result()->Passed()) { - continue; - } - ColoredPrintf(COLOR_RED, "[ FAILED ] "); - printf("%s.%s", test_case.name(), test_info.name()); - PrintFullTestCommentIfPresent(test_info); - printf("\n"); - } - } + for (int i = 0; i < unit_test.total_test_case_count(); ++i) + { + const TestCase& test_case = *unit_test.GetTestCase(i); + if (!test_case.should_run() || (test_case.failed_test_count() == 0)) + { + continue; + } + for (int j = 0; j < test_case.total_test_count(); ++j) + { + const TestInfo& test_info = *test_case.GetTestInfo(j); + if (!test_info.should_run() || test_info.result()->Passed()) + { + continue; + } + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s.%s", test_case.name(), test_info.name()); + PrintFullTestCommentIfPresent(test_info); + printf("\n"); + } + } } void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, - int /*iteration*/) { - ColoredPrintf(COLOR_GREEN, "[==========] "); - printf("%s from %s ran.", - FormatTestCount(unit_test.test_to_run_count()).c_str(), - FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); - if (GTEST_FLAG(print_time)) { - printf(" (%s ms total)", - internal::StreamableToString(unit_test.elapsed_time()).c_str()); - } - printf("\n"); - ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); - printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); + int /*iteration*/) +{ + ColoredPrintf(COLOR_GREEN, "[==========] "); + printf("%s from %s ran.", + FormatTestCount(unit_test.test_to_run_count()).c_str(), + FormatTestCaseCount(unit_test.test_case_to_run_count()).c_str()); + if (GTEST_FLAG(print_time)) + { + printf(" (%s ms total)", + internal::StreamableToString(unit_test.elapsed_time()).c_str()); + } + printf("\n"); + ColoredPrintf(COLOR_GREEN, "[ PASSED ] "); + printf("%s.\n", FormatTestCount(unit_test.successful_test_count()).c_str()); - int num_failures = unit_test.failed_test_count(); - if (!unit_test.Passed()) { - const int failed_test_count = unit_test.failed_test_count(); - ColoredPrintf(COLOR_RED, "[ FAILED ] "); - printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); - PrintFailedTests(unit_test); - printf("\n%2d FAILED %s\n", num_failures, - num_failures == 1 ? "TEST" : "TESTS"); - } + int num_failures = unit_test.failed_test_count(); + if (!unit_test.Passed()) + { + const int failed_test_count = unit_test.failed_test_count(); + ColoredPrintf(COLOR_RED, "[ FAILED ] "); + printf("%s, listed below:\n", FormatTestCount(failed_test_count).c_str()); + PrintFailedTests(unit_test); + printf("\n%2d FAILED %s\n", num_failures, + num_failures == 1 ? "TEST" : "TESTS"); + } - int num_disabled = unit_test.reportable_disabled_test_count(); - if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) { - if (!num_failures) { - printf("\n"); // Add a spacer if no FAILURE banner is displayed. - } - ColoredPrintf(COLOR_YELLOW, - " YOU HAVE %d DISABLED %s\n\n", - num_disabled, - num_disabled == 1 ? "TEST" : "TESTS"); - } - // Ensure that Google Test output is printed before, e.g., heapchecker output. - fflush(stdout); + int num_disabled = unit_test.reportable_disabled_test_count(); + if (num_disabled && !GTEST_FLAG(also_run_disabled_tests)) + { + if (!num_failures) + { + printf("\n"); // Add a spacer if no FAILURE banner is displayed. + } + ColoredPrintf(COLOR_YELLOW, + " YOU HAVE %d DISABLED %s\n\n", + num_disabled, + num_disabled == 1 ? "TEST" : "TESTS"); + } + // Ensure that Google Test output is printed before, e.g., heapchecker output. + fflush(stdout); } // End PrettyUnitTestResultPrinter @@ -2896,82 +3211,94 @@ void PrettyUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, // class TestEventRepeater // // This class forwards events to other event listeners. -class TestEventRepeater : public TestEventListener { - public: - TestEventRepeater() : forwarding_enabled_(true) {} - virtual ~TestEventRepeater(); - void Append(TestEventListener *listener); - TestEventListener* Release(TestEventListener* listener); +class TestEventRepeater : public TestEventListener +{ +public: + TestEventRepeater() : forwarding_enabled_(true) {} + virtual ~TestEventRepeater(); + void Append(TestEventListener* listener); + TestEventListener* Release(TestEventListener* listener); - // Controls whether events will be forwarded to listeners_. Set to false - // in death test child processes. - bool forwarding_enabled() const { return forwarding_enabled_; } - void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled() const { return forwarding_enabled_; } + void set_forwarding_enabled(bool enable) { forwarding_enabled_ = enable; } - virtual void OnTestProgramStart(const UnitTest& unit_test); - virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); - virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); - virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test); - virtual void OnTestCaseStart(const TestCase& test_case); - virtual void OnTestStart(const TestInfo& test_info); - virtual void OnTestPartResult(const TestPartResult& result); - virtual void OnTestEnd(const TestInfo& test_info); - virtual void OnTestCaseEnd(const TestCase& test_case); - virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); - virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test); - virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); - virtual void OnTestProgramEnd(const UnitTest& unit_test); + virtual void OnTestProgramStart(const UnitTest& unit_test); + virtual void OnTestIterationStart(const UnitTest& unit_test, int iteration); + virtual void OnEnvironmentsSetUpStart(const UnitTest& unit_test); + virtual void OnEnvironmentsSetUpEnd(const UnitTest& unit_test); + virtual void OnTestCaseStart(const TestCase& test_case); + virtual void OnTestStart(const TestInfo& test_info); + virtual void OnTestPartResult(const TestPartResult& result); + virtual void OnTestEnd(const TestInfo& test_info); + virtual void OnTestCaseEnd(const TestCase& test_case); + virtual void OnEnvironmentsTearDownStart(const UnitTest& unit_test); + virtual void OnEnvironmentsTearDownEnd(const UnitTest& unit_test); + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestProgramEnd(const UnitTest& unit_test); - private: - // Controls whether events will be forwarded to listeners_. Set to false - // in death test child processes. - bool forwarding_enabled_; - // The list of listeners that receive events. - std::vector listeners_; +private: + // Controls whether events will be forwarded to listeners_. Set to false + // in death test child processes. + bool forwarding_enabled_; + // The list of listeners that receive events. + std::vector listeners_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); + GTEST_DISALLOW_COPY_AND_ASSIGN_(TestEventRepeater); }; -TestEventRepeater::~TestEventRepeater() { - ForEach(listeners_, Delete); +TestEventRepeater::~TestEventRepeater() +{ + ForEach(listeners_, Delete); } -void TestEventRepeater::Append(TestEventListener *listener) { - listeners_.push_back(listener); +void TestEventRepeater::Append(TestEventListener* listener) +{ + listeners_.push_back(listener); } // TODO(vladl@google.com): Factor the search functionality into Vector::Find. -TestEventListener* TestEventRepeater::Release(TestEventListener *listener) { - for (size_t i = 0; i < listeners_.size(); ++i) { - if (listeners_[i] == listener) { - listeners_.erase(listeners_.begin() + i); - return listener; - } - } +TestEventListener* TestEventRepeater::Release(TestEventListener* listener) +{ + for (size_t i = 0; i < listeners_.size(); ++i) + { + if (listeners_[i] == listener) + { + listeners_.erase(listeners_.begin() + i); + return listener; + } + } - return NULL; + return NULL; } // Since most methods are very similar, use macros to reduce boilerplate. // This defines a member that forwards the call to all listeners. -#define GTEST_REPEATER_METHOD_(Name, Type) \ -void TestEventRepeater::Name(const Type& parameter) { \ - if (forwarding_enabled_) { \ - for (size_t i = 0; i < listeners_.size(); i++) { \ - listeners_[i]->Name(parameter); \ - } \ - } \ -} +#define GTEST_REPEATER_METHOD_(Name, Type) \ + void TestEventRepeater::Name(const Type& parameter) \ + { \ + if (forwarding_enabled_) \ + { \ + for (size_t i = 0; i < listeners_.size(); i++) \ + { \ + listeners_[i]->Name(parameter); \ + } \ + } \ + } // This defines a member that forwards the call to all listeners in reverse // order. -#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ -void TestEventRepeater::Name(const Type& parameter) { \ - if (forwarding_enabled_) { \ - for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { \ - listeners_[i]->Name(parameter); \ - } \ - } \ -} +#define GTEST_REVERSE_REPEATER_METHOD_(Name, Type) \ + void TestEventRepeater::Name(const Type& parameter) \ + { \ + if (forwarding_enabled_) \ + { \ + for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) \ + { \ + listeners_[i]->Name(parameter); \ + } \ + } \ + } GTEST_REPEATER_METHOD_(OnTestProgramStart, UnitTest) GTEST_REPEATER_METHOD_(OnEnvironmentsSetUpStart, UnitTest) @@ -2989,139 +3316,155 @@ GTEST_REVERSE_REPEATER_METHOD_(OnTestProgramEnd, UnitTest) #undef GTEST_REVERSE_REPEATER_METHOD_ void TestEventRepeater::OnTestIterationStart(const UnitTest& unit_test, - int iteration) { - if (forwarding_enabled_) { - for (size_t i = 0; i < listeners_.size(); i++) { - listeners_[i]->OnTestIterationStart(unit_test, iteration); - } - } + int iteration) +{ + if (forwarding_enabled_) + { + for (size_t i = 0; i < listeners_.size(); i++) + { + listeners_[i]->OnTestIterationStart(unit_test, iteration); + } + } } void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, - int iteration) { - if (forwarding_enabled_) { - for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) { - listeners_[i]->OnTestIterationEnd(unit_test, iteration); - } - } + int iteration) +{ + if (forwarding_enabled_) + { + for (int i = static_cast(listeners_.size()) - 1; i >= 0; i--) + { + listeners_[i]->OnTestIterationEnd(unit_test, iteration); + } + } } // End TestEventRepeater // This class generates an XML output file. -class XmlUnitTestResultPrinter : public EmptyTestEventListener { - public: - explicit XmlUnitTestResultPrinter(const char* output_file); +class XmlUnitTestResultPrinter : public EmptyTestEventListener +{ +public: + explicit XmlUnitTestResultPrinter(const char* output_file); - virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); + virtual void OnTestIterationEnd(const UnitTest& unit_test, int iteration); - private: - // Is c a whitespace character that is normalized to a space character - // when it appears in an XML attribute value? - static bool IsNormalizableWhitespace(char c) { - return c == 0x9 || c == 0xA || c == 0xD; - } +private: + // Is c a whitespace character that is normalized to a space character + // when it appears in an XML attribute value? + static bool IsNormalizableWhitespace(char c) + { + return c == 0x9 || c == 0xA || c == 0xD; + } - // May c appear in a well-formed XML document? - static bool IsValidXmlCharacter(char c) { - return IsNormalizableWhitespace(c) || c >= 0x20; - } + // May c appear in a well-formed XML document? + static bool IsValidXmlCharacter(char c) + { + return IsNormalizableWhitespace(c) || c >= 0x20; + } - // Returns an XML-escaped copy of the input string str. If - // is_attribute is true, the text is meant to appear as an attribute - // value, and normalizable whitespace is preserved by replacing it - // with character references. - static std::string EscapeXml(const std::string& str, bool is_attribute); + // Returns an XML-escaped copy of the input string str. If + // is_attribute is true, the text is meant to appear as an attribute + // value, and normalizable whitespace is preserved by replacing it + // with character references. + static std::string EscapeXml(const std::string& str, bool is_attribute); - // Returns the given string with all characters invalid in XML removed. - static std::string RemoveInvalidXmlCharacters(const std::string& str); + // Returns the given string with all characters invalid in XML removed. + static std::string RemoveInvalidXmlCharacters(const std::string& str); - // Convenience wrapper around EscapeXml when str is an attribute value. - static std::string EscapeXmlAttribute(const std::string& str) { - return EscapeXml(str, true); - } + // Convenience wrapper around EscapeXml when str is an attribute value. + static std::string EscapeXmlAttribute(const std::string& str) + { + return EscapeXml(str, true); + } - // Convenience wrapper around EscapeXml when str is not an attribute value. - static std::string EscapeXmlText(const char* str) { - return EscapeXml(str, false); - } + // Convenience wrapper around EscapeXml when str is not an attribute value. + static std::string EscapeXmlText(const char* str) + { + return EscapeXml(str, false); + } - // Verifies that the given attribute belongs to the given element and - // streams the attribute as XML. - static void OutputXmlAttribute(std::ostream* stream, - const std::string& element_name, - const std::string& name, - const std::string& value); + // Verifies that the given attribute belongs to the given element and + // streams the attribute as XML. + static void OutputXmlAttribute(std::ostream* stream, + const std::string& element_name, + const std::string& name, + const std::string& value); - // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. - static void OutputXmlCDataSection(::std::ostream* stream, const char* data); + // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. + static void OutputXmlCDataSection(::std::ostream* stream, const char* data); - // Streams an XML representation of a TestInfo object. - static void OutputXmlTestInfo(::std::ostream* stream, - const char* test_case_name, - const TestInfo& test_info); + // Streams an XML representation of a TestInfo object. + static void OutputXmlTestInfo(::std::ostream* stream, + const char* test_case_name, + const TestInfo& test_info); - // Prints an XML representation of a TestCase object - static void PrintXmlTestCase(::std::ostream* stream, - const TestCase& test_case); + // Prints an XML representation of a TestCase object + static void PrintXmlTestCase(::std::ostream* stream, + const TestCase& test_case); - // Prints an XML summary of unit_test to output stream out. - static void PrintXmlUnitTest(::std::ostream* stream, - const UnitTest& unit_test); + // Prints an XML summary of unit_test to output stream out. + static void PrintXmlUnitTest(::std::ostream* stream, + const UnitTest& unit_test); - // Produces a string representing the test properties in a result as space - // delimited XML attributes based on the property key="value" pairs. - // When the std::string is not empty, it includes a space at the beginning, - // to delimit this attribute from prior attributes. - static std::string TestPropertiesAsXmlAttributes(const TestResult& result); + // Produces a string representing the test properties in a result as space + // delimited XML attributes based on the property key="value" pairs. + // When the std::string is not empty, it includes a space at the beginning, + // to delimit this attribute from prior attributes. + static std::string TestPropertiesAsXmlAttributes(const TestResult& result); - // The output file. - const std::string output_file_; + // The output file. + const std::string output_file_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); + GTEST_DISALLOW_COPY_AND_ASSIGN_(XmlUnitTestResultPrinter); }; // Creates a new XmlUnitTestResultPrinter. XmlUnitTestResultPrinter::XmlUnitTestResultPrinter(const char* output_file) - : output_file_(output_file) { - if (output_file_.c_str() == NULL || output_file_.empty()) { - fprintf(stderr, "XML output file may not be null\n"); - fflush(stderr); - exit(EXIT_FAILURE); - } + : output_file_(output_file) +{ + if (output_file_.c_str() == NULL || output_file_.empty()) + { + fprintf(stderr, "XML output file may not be null\n"); + fflush(stderr); + exit(EXIT_FAILURE); + } } // Called after the unit test ends. void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, - int /*iteration*/) { - FILE* xmlout = NULL; - FilePath output_file(output_file_); - FilePath output_dir(output_file.RemoveFileName()); + int /*iteration*/) +{ + FILE* xmlout = NULL; + FilePath output_file(output_file_); + FilePath output_dir(output_file.RemoveFileName()); - if (output_dir.CreateDirectoriesRecursively()) { - xmlout = posix::FOpen(output_file_.c_str(), "w"); - } - if (xmlout == NULL) { - // TODO(wan): report the reason of the failure. - // - // We don't do it for now as: - // - // 1. There is no urgent need for it. - // 2. It's a bit involved to make the errno variable thread-safe on - // all three operating systems (Linux, Windows, and Mac OS). - // 3. To interpret the meaning of errno in a thread-safe way, - // we need the strerror_r() function, which is not available on - // Windows. - fprintf(stderr, - "Unable to open file \"%s\"\n", - output_file_.c_str()); - fflush(stderr); - exit(EXIT_FAILURE); - } - std::stringstream stream; - PrintXmlUnitTest(&stream, unit_test); - fprintf(xmlout, "%s", StringStreamToString(&stream).c_str()); - fclose(xmlout); + if (output_dir.CreateDirectoriesRecursively()) + { + xmlout = posix::FOpen(output_file_.c_str(), "w"); + } + if (xmlout == NULL) + { + // TODO(wan): report the reason of the failure. + // + // We don't do it for now as: + // + // 1. There is no urgent need for it. + // 2. It's a bit involved to make the errno variable thread-safe on + // all three operating systems (Linux, Windows, and Mac OS). + // 3. To interpret the meaning of errno in a thread-safe way, + // we need the strerror_r() function, which is not available on + // Windows. + fprintf(stderr, + "Unable to open file \"%s\"\n", + output_file_.c_str()); + fflush(stderr); + exit(EXIT_FAILURE); + } + std::stringstream stream; + PrintXmlUnitTest(&stream, unit_test); + fprintf(xmlout, "%s", StringStreamToString(&stream).c_str()); + fclose(xmlout); } // Returns an XML-escaped copy of the input string str. If is_attribute @@ -3137,60 +3480,65 @@ void XmlUnitTestResultPrinter::OnTestIterationEnd(const UnitTest& unit_test, // TODO(wan): It might be nice to have a minimally invasive, human-readable // escaping scheme for invalid characters, rather than dropping them. std::string XmlUnitTestResultPrinter::EscapeXml( - const std::string& str, bool is_attribute) { - Message m; + const std::string& str, bool is_attribute) +{ + Message m; - for (size_t i = 0; i < str.size(); ++i) { - const char ch = str[i]; - switch (ch) { - case '<': - m << "<"; - break; - case '>': - m << ">"; - break; - case '&': - m << "&"; - break; - case '\'': - if (is_attribute) - m << "'"; - else - m << '\''; - break; - case '"': - if (is_attribute) - m << """; - else - m << '"'; - break; - default: - if (IsValidXmlCharacter(ch)) { - if (is_attribute && IsNormalizableWhitespace(ch)) - m << "&#x" << String::FormatByte(static_cast(ch)) - << ";"; - else - m << ch; - } - break; - } - } + for (size_t i = 0; i < str.size(); ++i) + { + const char ch = str[i]; + switch (ch) + { + case '<': + m << "<"; + break; + case '>': + m << ">"; + break; + case '&': + m << "&"; + break; + case '\'': + if (is_attribute) + m << "'"; + else + m << '\''; + break; + case '"': + if (is_attribute) + m << """; + else + m << '"'; + break; + default: + if (IsValidXmlCharacter(ch)) + { + if (is_attribute && IsNormalizableWhitespace(ch)) + m << "&#x" << String::FormatByte(static_cast(ch)) + << ";"; + else + m << ch; + } + break; + } + } - return m.GetString(); + return m.GetString(); } // Returns the given string with all characters invalid in XML removed. // Currently invalid characters are dropped from the string. An // alternative is to replace them with certain characters such as . or ?. std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters( - const std::string& str) { - std::string output; - output.reserve(str.size()); - for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) - if (IsValidXmlCharacter(*it)) - output.push_back(*it); + const std::string& str) +{ + std::string output; + output.reserve(str.size()); + for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) + if (IsValidXmlCharacter(*it)) + output.push_back(*it); - return output; + return output; } // The following routines generate an XML representation of a UnitTest @@ -3210,201 +3558,222 @@ std::string XmlUnitTestResultPrinter::RemoveInvalidXmlCharacters( // // Formats the given time in milliseconds as seconds. -std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) { - ::std::stringstream ss; - ss << ms/1000.0; - return ss.str(); +std::string FormatTimeInMillisAsSeconds(TimeInMillis ms) +{ + ::std::stringstream ss; + ss << ms / 1000.0; + return ss.str(); } // Converts the given epoch time in milliseconds to a date string in the ISO // 8601 format, without the timezone information. -std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) { - // Using non-reentrant version as localtime_r is not portable. - time_t seconds = static_cast(ms / 1000); +std::string FormatEpochTimeInMillisAsIso8601(TimeInMillis ms) +{ + // Using non-reentrant version as localtime_r is not portable. + time_t seconds = static_cast(ms / 1000); #ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4996) // Temporarily disables warning 4996 - // (function or variable may be unsafe). - const struct tm* const time_struct = localtime(&seconds); // NOLINT -# pragma warning(pop) // Restores the warning state again. +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable : 4996) // Temporarily disables warning 4996 \ + // (function or variable may be unsafe). + const struct tm* const time_struct = localtime(&seconds); // NOLINT +#pragma warning(pop) // Restores the warning state again. #else - const struct tm* const time_struct = localtime(&seconds); // NOLINT + const struct tm* const time_struct = localtime(&seconds); // NOLINT #endif - if (time_struct == NULL) - return ""; // Invalid ms value + if (time_struct == NULL) + return ""; // Invalid ms value - // YYYY-MM-DDThh:mm:ss - return StreamableToString(time_struct->tm_year + 1900) + "-" + - String::FormatIntWidth2(time_struct->tm_mon + 1) + "-" + - String::FormatIntWidth2(time_struct->tm_mday) + "T" + - String::FormatIntWidth2(time_struct->tm_hour) + ":" + - String::FormatIntWidth2(time_struct->tm_min) + ":" + - String::FormatIntWidth2(time_struct->tm_sec); + // YYYY-MM-DDThh:mm:ss + return StreamableToString(time_struct->tm_year + 1900) + "-" + + String::FormatIntWidth2(time_struct->tm_mon + 1) + "-" + + String::FormatIntWidth2(time_struct->tm_mday) + "T" + + String::FormatIntWidth2(time_struct->tm_hour) + ":" + + String::FormatIntWidth2(time_struct->tm_min) + ":" + + String::FormatIntWidth2(time_struct->tm_sec); } // Streams an XML CDATA section, escaping invalid CDATA sequences as needed. void XmlUnitTestResultPrinter::OutputXmlCDataSection(::std::ostream* stream, - const char* data) { - const char* segment = data; - *stream << ""); - if (next_segment != NULL) { - stream->write( - segment, static_cast(next_segment - segment)); - *stream << "]]>]]>"); - } else { - *stream << segment; - break; - } - } - *stream << "]]>"; + const char* data) +{ + const char* segment = data; + *stream << ""); + if (next_segment != NULL) + { + stream->write( + segment, static_cast(next_segment - segment)); + *stream << "]]>]]>"); + } + else + { + *stream << segment; + break; + } + } + *stream << "]]>"; } void XmlUnitTestResultPrinter::OutputXmlAttribute( - std::ostream* stream, - const std::string& element_name, - const std::string& name, - const std::string& value) { - const std::vector& allowed_names = - GetReservedAttributesForElement(element_name); + std::ostream* stream, + const std::string& element_name, + const std::string& name, + const std::string& value) +{ + const std::vector& allowed_names = + GetReservedAttributesForElement(element_name); - GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != - allowed_names.end()) - << "Attribute " << name << " is not allowed for element <" << element_name - << ">."; + GTEST_CHECK_(std::find(allowed_names.begin(), allowed_names.end(), name) != + allowed_names.end()) + << "Attribute " << name << " is not allowed for element <" << element_name + << ">."; - *stream << " " << name << "=\"" << EscapeXmlAttribute(value) << "\""; + *stream << " " << name << "=\"" << EscapeXmlAttribute(value) << "\""; } // Prints an XML representation of a TestInfo object. // TODO(wan): There is also value in printing properties with the plain printer. void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, - const char* test_case_name, - const TestInfo& test_info) { - const TestResult& result = *test_info.result(); - const std::string kTestcase = "testcase"; + const char* test_case_name, + const TestInfo& test_info) +{ + const TestResult& result = *test_info.result(); + const std::string kTestcase = "testcase"; - *stream << " \n"; - } - const string location = internal::FormatCompilerIndependentFileLocation( - part.file_name(), part.line_number()); - const string summary = location + "\n" + part.summary(); - *stream << " "; - const string detail = location + "\n" + part.message(); - OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str()); - *stream << "\n"; - } - } + int failures = 0; + for (int i = 0; i < result.total_part_count(); ++i) + { + const TestPartResult& part = result.GetTestPartResult(i); + if (part.failed()) + { + if (++failures == 1) + { + *stream << ">\n"; + } + const string location = internal::FormatCompilerIndependentFileLocation( + part.file_name(), part.line_number()); + const string summary = location + "\n" + part.summary(); + *stream << " "; + const string detail = location + "\n" + part.message(); + OutputXmlCDataSection(stream, RemoveInvalidXmlCharacters(detail).c_str()); + *stream << "\n"; + } + } - if (failures == 0) - *stream << " />\n"; - else - *stream << " \n"; + if (failures == 0) + *stream << " />\n"; + else + *stream << " \n"; } // Prints an XML representation of a TestCase object void XmlUnitTestResultPrinter::PrintXmlTestCase(std::ostream* stream, - const TestCase& test_case) { - const std::string kTestsuite = "testsuite"; - *stream << " <" << kTestsuite; - OutputXmlAttribute(stream, kTestsuite, "name", test_case.name()); - OutputXmlAttribute(stream, kTestsuite, "tests", - StreamableToString(test_case.reportable_test_count())); - OutputXmlAttribute(stream, kTestsuite, "failures", - StreamableToString(test_case.failed_test_count())); - OutputXmlAttribute( - stream, kTestsuite, "disabled", - StreamableToString(test_case.reportable_disabled_test_count())); - OutputXmlAttribute(stream, kTestsuite, "errors", "0"); - OutputXmlAttribute(stream, kTestsuite, "time", - FormatTimeInMillisAsSeconds(test_case.elapsed_time())); - *stream << TestPropertiesAsXmlAttributes(test_case.ad_hoc_test_result()) - << ">\n"; + const TestCase& test_case) +{ + const std::string kTestsuite = "testsuite"; + *stream << " <" << kTestsuite; + OutputXmlAttribute(stream, kTestsuite, "name", test_case.name()); + OutputXmlAttribute(stream, kTestsuite, "tests", + StreamableToString(test_case.reportable_test_count())); + OutputXmlAttribute(stream, kTestsuite, "failures", + StreamableToString(test_case.failed_test_count())); + OutputXmlAttribute( + stream, kTestsuite, "disabled", + StreamableToString(test_case.reportable_disabled_test_count())); + OutputXmlAttribute(stream, kTestsuite, "errors", "0"); + OutputXmlAttribute(stream, kTestsuite, "time", + FormatTimeInMillisAsSeconds(test_case.elapsed_time())); + *stream << TestPropertiesAsXmlAttributes(test_case.ad_hoc_test_result()) + << ">\n"; - for (int i = 0; i < test_case.total_test_count(); ++i) { - if (test_case.GetTestInfo(i)->is_reportable()) - OutputXmlTestInfo(stream, test_case.name(), *test_case.GetTestInfo(i)); - } - *stream << " \n"; + for (int i = 0; i < test_case.total_test_count(); ++i) + { + if (test_case.GetTestInfo(i)->is_reportable()) + OutputXmlTestInfo(stream, test_case.name(), *test_case.GetTestInfo(i)); + } + *stream << " \n"; } // Prints an XML summary of unit_test to output stream out. void XmlUnitTestResultPrinter::PrintXmlUnitTest(std::ostream* stream, - const UnitTest& unit_test) { - const std::string kTestsuites = "testsuites"; + const UnitTest& unit_test) +{ + const std::string kTestsuites = "testsuites"; - *stream << "\n"; - *stream << "<" << kTestsuites; + *stream << "\n"; + *stream << "<" << kTestsuites; - OutputXmlAttribute(stream, kTestsuites, "tests", - StreamableToString(unit_test.reportable_test_count())); - OutputXmlAttribute(stream, kTestsuites, "failures", - StreamableToString(unit_test.failed_test_count())); - OutputXmlAttribute( - stream, kTestsuites, "disabled", - StreamableToString(unit_test.reportable_disabled_test_count())); - OutputXmlAttribute(stream, kTestsuites, "errors", "0"); - OutputXmlAttribute( - stream, kTestsuites, "timestamp", - FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp())); - OutputXmlAttribute(stream, kTestsuites, "time", - FormatTimeInMillisAsSeconds(unit_test.elapsed_time())); + OutputXmlAttribute(stream, kTestsuites, "tests", + StreamableToString(unit_test.reportable_test_count())); + OutputXmlAttribute(stream, kTestsuites, "failures", + StreamableToString(unit_test.failed_test_count())); + OutputXmlAttribute( + stream, kTestsuites, "disabled", + StreamableToString(unit_test.reportable_disabled_test_count())); + OutputXmlAttribute(stream, kTestsuites, "errors", "0"); + OutputXmlAttribute( + stream, kTestsuites, "timestamp", + FormatEpochTimeInMillisAsIso8601(unit_test.start_timestamp())); + OutputXmlAttribute(stream, kTestsuites, "time", + FormatTimeInMillisAsSeconds(unit_test.elapsed_time())); - if (GTEST_FLAG(shuffle)) { - OutputXmlAttribute(stream, kTestsuites, "random_seed", - StreamableToString(unit_test.random_seed())); - } + if (GTEST_FLAG(shuffle)) + { + OutputXmlAttribute(stream, kTestsuites, "random_seed", + StreamableToString(unit_test.random_seed())); + } - *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result()); + *stream << TestPropertiesAsXmlAttributes(unit_test.ad_hoc_test_result()); - OutputXmlAttribute(stream, kTestsuites, "name", "AllTests"); - *stream << ">\n"; + OutputXmlAttribute(stream, kTestsuites, "name", "AllTests"); + *stream << ">\n"; - for (int i = 0; i < unit_test.total_test_case_count(); ++i) { - if (unit_test.GetTestCase(i)->reportable_test_count() > 0) - PrintXmlTestCase(stream, *unit_test.GetTestCase(i)); - } - *stream << "\n"; + for (int i = 0; i < unit_test.total_test_case_count(); ++i) + { + if (unit_test.GetTestCase(i)->reportable_test_count() > 0) + PrintXmlTestCase(stream, *unit_test.GetTestCase(i)); + } + *stream << "\n"; } // Produces a string representing the test properties in a result as space // delimited XML attributes based on the property key="value" pairs. std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( - const TestResult& result) { - Message attributes; - for (int i = 0; i < result.test_property_count(); ++i) { - const TestProperty& property = result.GetTestProperty(i); - attributes << " " << property.key() << "=" - << "\"" << EscapeXmlAttribute(property.value()) << "\""; - } - return attributes.GetString(); + const TestResult& result) +{ + Message attributes; + for (int i = 0; i < result.test_property_count(); ++i) + { + const TestProperty& property = result.GetTestProperty(i); + attributes << " " << property.key() << "=" + << "\"" << EscapeXmlAttribute(property.value()) << "\""; + } + return attributes.GetString(); } // End XmlUnitTestResultPrinter @@ -3416,64 +3785,73 @@ std::string XmlUnitTestResultPrinter::TestPropertiesAsXmlAttributes( // example, replaces "=" with "%3D". This algorithm is O(strlen(str)) // in both time and space -- important as the input str may contain an // arbitrarily long test failure message and stack trace. -string StreamingListener::UrlEncode(const char* str) { - string result; - result.reserve(strlen(str) + 1); - for (char ch = *str; ch != '\0'; ch = *++str) { - switch (ch) { - case '%': - case '=': - case '&': - case '\n': - result.append("%" + String::FormatByte(static_cast(ch))); - break; - default: - result.push_back(ch); - break; - } - } - return result; +string StreamingListener::UrlEncode(const char* str) +{ + string result; + result.reserve(strlen(str) + 1); + for (char ch = *str; ch != '\0'; ch = *++str) + { + switch (ch) + { + case '%': + case '=': + case '&': + case '\n': + result.append("%" + String::FormatByte(static_cast(ch))); + break; + default: + result.push_back(ch); + break; + } + } + return result; } -void StreamingListener::SocketWriter::MakeConnection() { - GTEST_CHECK_(sockfd_ == -1) - << "MakeConnection() can't be called when there is already a connection."; +void StreamingListener::SocketWriter::MakeConnection() +{ + GTEST_CHECK_(sockfd_ == -1) + << "MakeConnection() can't be called when there is already a connection."; - addrinfo hints; - memset(&hints, 0, sizeof(hints)); - hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses. - hints.ai_socktype = SOCK_STREAM; - addrinfo* servinfo = NULL; + addrinfo hints; + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; // To allow both IPv4 and IPv6 addresses. + hints.ai_socktype = SOCK_STREAM; + addrinfo* servinfo = NULL; - // Use the getaddrinfo() to get a linked list of IP addresses for - // the given host name. - const int error_num = getaddrinfo( - host_name_.c_str(), port_num_.c_str(), &hints, &servinfo); - if (error_num != 0) { - GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: " - << gai_strerror(error_num); - } + // Use the getaddrinfo() to get a linked list of IP addresses for + // the given host name. + const int error_num = getaddrinfo( + host_name_.c_str(), port_num_.c_str(), &hints, &servinfo); + if (error_num != 0) + { + GTEST_LOG_(WARNING) << "stream_result_to: getaddrinfo() failed: " + << gai_strerror(error_num); + } - // Loop through all the results and connect to the first we can. - for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL; - cur_addr = cur_addr->ai_next) { - sockfd_ = socket( - cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol); - if (sockfd_ != -1) { - // Connect the client socket to the server socket. - if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) { - close(sockfd_); - sockfd_ = -1; - } - } - } + // Loop through all the results and connect to the first we can. + for (addrinfo* cur_addr = servinfo; sockfd_ == -1 && cur_addr != NULL; + cur_addr = cur_addr->ai_next) + { + sockfd_ = socket( + cur_addr->ai_family, cur_addr->ai_socktype, cur_addr->ai_protocol); + if (sockfd_ != -1) + { + // Connect the client socket to the server socket. + if (connect(sockfd_, cur_addr->ai_addr, cur_addr->ai_addrlen) == -1) + { + close(sockfd_); + sockfd_ = -1; + } + } + } - freeaddrinfo(servinfo); // all done with this structure + freeaddrinfo(servinfo); // all done with this structure - if (sockfd_ == -1) { - GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to " - << host_name_ << ":" << port_num_; - } + if (sockfd_ == -1) + { + GTEST_LOG_(WARNING) << "stream_result_to: failed to connect to " + << host_name_ << ":" << port_num_; + } } // End of class Streaming Listener @@ -3484,22 +3862,23 @@ void StreamingListener::SocketWriter::MakeConnection() { // Pushes the given source file location and message onto a per-thread // trace stack maintained by Google Test. ScopedTrace::ScopedTrace(const char* file, int line, const Message& message) - GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { - TraceInfo trace; - trace.file = file; - trace.line = line; - trace.message = message.GetString(); + GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) +{ + TraceInfo trace; + trace.file = file; + trace.line = line; + trace.message = message.GetString(); - UnitTest::GetInstance()->PushGTestTrace(trace); + UnitTest::GetInstance()->PushGTestTrace(trace); } // Pops the info pushed by the c'tor. ScopedTrace::~ScopedTrace() - GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) { - UnitTest::GetInstance()->PopGTestTrace(); + GTEST_LOCK_EXCLUDED_(&UnitTest::mutex_) +{ + UnitTest::GetInstance()->PopGTestTrace(); } - // class OsStackTraceGetter // Returns the current OS stack trace as an std::string. Parameters: @@ -3510,46 +3889,53 @@ ScopedTrace::~ScopedTrace() // against max_depth. // string OsStackTraceGetter::CurrentStackTrace(int /* max_depth */, - int /* skip_count */) - GTEST_LOCK_EXCLUDED_(mutex_) { - return ""; + int /* skip_count */) + GTEST_LOCK_EXCLUDED_(mutex_) +{ + return ""; } void OsStackTraceGetter::UponLeavingGTest() - GTEST_LOCK_EXCLUDED_(mutex_) { + GTEST_LOCK_EXCLUDED_(mutex_) +{ } const char* const -OsStackTraceGetter::kElidedFramesMarker = - "... " GTEST_NAME_ " internal frames ..."; + OsStackTraceGetter::kElidedFramesMarker = + "... " GTEST_NAME_ " internal frames ..."; // A helper class that creates the premature-exit file in its // constructor and deletes the file in its destructor. -class ScopedPrematureExitFile { - public: - explicit ScopedPrematureExitFile(const char* premature_exit_filepath) - : premature_exit_filepath_(premature_exit_filepath) { - // If a path to the premature-exit file is specified... - if (premature_exit_filepath != NULL && *premature_exit_filepath != '\0') { - // create the file with a single "0" character in it. I/O - // errors are ignored as there's nothing better we can do and we - // don't want to fail the test because of this. - FILE* pfile = posix::FOpen(premature_exit_filepath, "w"); - fwrite("0", 1, 1, pfile); - fclose(pfile); - } - } +class ScopedPrematureExitFile +{ +public: + explicit ScopedPrematureExitFile(const char* premature_exit_filepath) + : premature_exit_filepath_(premature_exit_filepath) + { + // If a path to the premature-exit file is specified... + if (premature_exit_filepath != NULL && *premature_exit_filepath != '\0') + { + // create the file with a single "0" character in it. I/O + // errors are ignored as there's nothing better we can do and we + // don't want to fail the test because of this. + FILE* pfile = posix::FOpen(premature_exit_filepath, "w"); + fwrite("0", 1, 1, pfile); + fclose(pfile); + } + } - ~ScopedPrematureExitFile() { - if (premature_exit_filepath_ != NULL && *premature_exit_filepath_ != '\0') { - remove(premature_exit_filepath_); - } - } + ~ScopedPrematureExitFile() + { + if (premature_exit_filepath_ != NULL && *premature_exit_filepath_ != '\0') + { + remove(premature_exit_filepath_); + } + } - private: - const char* const premature_exit_filepath_; +private: + const char* const premature_exit_filepath_; - GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile); + GTEST_DISALLOW_COPY_AND_ASSIGN_(ScopedPrematureExitFile); }; } // namespace internal @@ -3557,9 +3943,10 @@ class ScopedPrematureExitFile { // class TestEventListeners TestEventListeners::TestEventListeners() - : repeater_(new internal::TestEventRepeater()), - default_result_printer_(NULL), - default_xml_generator_(NULL) { + : repeater_(new internal::TestEventRepeater()), + default_result_printer_(NULL), + default_xml_generator_(NULL) +{ } TestEventListeners::~TestEventListeners() { delete repeater_; } @@ -3568,19 +3955,21 @@ TestEventListeners::~TestEventListeners() { delete repeater_; } // output. Can be removed from the listeners list to shut down default // console output. Note that removing this object from the listener list // with Release transfers its ownership to the user. -void TestEventListeners::Append(TestEventListener* listener) { - repeater_->Append(listener); +void TestEventListeners::Append(TestEventListener* listener) +{ + repeater_->Append(listener); } // Removes the given event listener from the list and returns it. It then // becomes the caller's responsibility to delete the listener. Returns // NULL if the listener is not found in the list. -TestEventListener* TestEventListeners::Release(TestEventListener* listener) { - if (listener == default_result_printer_) - default_result_printer_ = NULL; - else if (listener == default_xml_generator_) - default_xml_generator_ = NULL; - return repeater_->Release(listener); +TestEventListener* TestEventListeners::Release(TestEventListener* listener) +{ + if (listener == default_result_printer_) + default_result_printer_ = NULL; + else if (listener == default_xml_generator_) + default_xml_generator_ = NULL; + return repeater_->Release(listener); } // Returns repeater that broadcasts the TestEventListener events to all @@ -3592,15 +3981,17 @@ TestEventListener* TestEventListeners::repeater() { return repeater_; } // default_result_printer is removed from it and deleted. The listener can // also be NULL in which case it will not be added to the list. Does // nothing if the previous and the current listener objects are the same. -void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { - if (default_result_printer_ != listener) { - // It is an error to pass this method a listener that is already in the - // list. - delete Release(default_result_printer_); - default_result_printer_ = listener; - if (listener != NULL) - Append(listener); - } +void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) +{ + if (default_result_printer_ != listener) + { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_result_printer_); + default_result_printer_ = listener; + if (listener != NULL) + Append(listener); + } } // Sets the default_xml_generator attribute to the provided listener. The @@ -3608,25 +3999,29 @@ void TestEventListeners::SetDefaultResultPrinter(TestEventListener* listener) { // default_xml_generator is removed from it and deleted. The listener can // also be NULL in which case it will not be added to the list. Does // nothing if the previous and the current listener objects are the same. -void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) { - if (default_xml_generator_ != listener) { - // It is an error to pass this method a listener that is already in the - // list. - delete Release(default_xml_generator_); - default_xml_generator_ = listener; - if (listener != NULL) - Append(listener); - } +void TestEventListeners::SetDefaultXmlGenerator(TestEventListener* listener) +{ + if (default_xml_generator_ != listener) + { + // It is an error to pass this method a listener that is already in the + // list. + delete Release(default_xml_generator_); + default_xml_generator_ = listener; + if (listener != NULL) + Append(listener); + } } // Controls whether events will be forwarded by the repeater to the // listeners in the list. -bool TestEventListeners::EventForwardingEnabled() const { - return repeater_->forwarding_enabled(); +bool TestEventListeners::EventForwardingEnabled() const +{ + return repeater_->forwarding_enabled(); } -void TestEventListeners::SuppressEventForwarding() { - repeater_->set_forwarding_enabled(false); +void TestEventListeners::SuppressEventForwarding() +{ + repeater_->set_forwarding_enabled(false); } // class UnitTest @@ -3638,69 +4033,78 @@ void TestEventListeners::SuppressEventForwarding() { // We don't protect this under mutex_ as a user is not supposed to // call this before main() starts, from which point on the return // value will never change. -UnitTest* UnitTest::GetInstance() { - // When compiled with MSVC 7.1 in optimized mode, destroying the - // UnitTest object upon exiting the program messes up the exit code, - // causing successful tests to appear failed. We have to use a - // different implementation in this case to bypass the compiler bug. - // This implementation makes the compiler happy, at the cost of - // leaking the UnitTest object. +UnitTest* UnitTest::GetInstance() +{ + // When compiled with MSVC 7.1 in optimized mode, destroying the + // UnitTest object upon exiting the program messes up the exit code, + // causing successful tests to appear failed. We have to use a + // different implementation in this case to bypass the compiler bug. + // This implementation makes the compiler happy, at the cost of + // leaking the UnitTest object. - // CodeGear C++Builder insists on a public destructor for the - // default implementation. Use this implementation to keep good OO - // design with private destructor. + // CodeGear C++Builder insists on a public destructor for the + // default implementation. Use this implementation to keep good OO + // design with private destructor. #if (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) - static UnitTest* const instance = new UnitTest; - return instance; + static UnitTest* const instance = new UnitTest; + return instance; #else - static UnitTest instance; - return &instance; + static UnitTest instance; + return &instance; #endif // (_MSC_VER == 1310 && !defined(_DEBUG)) || defined(__BORLANDC__) } // Gets the number of successful test cases. -int UnitTest::successful_test_case_count() const { - return impl()->successful_test_case_count(); +int UnitTest::successful_test_case_count() const +{ + return impl()->successful_test_case_count(); } // Gets the number of failed test cases. -int UnitTest::failed_test_case_count() const { - return impl()->failed_test_case_count(); +int UnitTest::failed_test_case_count() const +{ + return impl()->failed_test_case_count(); } // Gets the number of all test cases. -int UnitTest::total_test_case_count() const { - return impl()->total_test_case_count(); +int UnitTest::total_test_case_count() const +{ + return impl()->total_test_case_count(); } // Gets the number of all test cases that contain at least one test // that should run. -int UnitTest::test_case_to_run_count() const { - return impl()->test_case_to_run_count(); +int UnitTest::test_case_to_run_count() const +{ + return impl()->test_case_to_run_count(); } // Gets the number of successful tests. -int UnitTest::successful_test_count() const { - return impl()->successful_test_count(); +int UnitTest::successful_test_count() const +{ + return impl()->successful_test_count(); } // Gets the number of failed tests. int UnitTest::failed_test_count() const { return impl()->failed_test_count(); } // Gets the number of disabled tests that will be reported in the XML report. -int UnitTest::reportable_disabled_test_count() const { - return impl()->reportable_disabled_test_count(); +int UnitTest::reportable_disabled_test_count() const +{ + return impl()->reportable_disabled_test_count(); } // Gets the number of disabled tests. -int UnitTest::disabled_test_count() const { - return impl()->disabled_test_count(); +int UnitTest::disabled_test_count() const +{ + return impl()->disabled_test_count(); } // Gets the number of tests to be printed in the XML report. -int UnitTest::reportable_test_count() const { - return impl()->reportable_test_count(); +int UnitTest::reportable_test_count() const +{ + return impl()->reportable_test_count(); } // Gets the number of all tests. @@ -3711,13 +4115,15 @@ int UnitTest::test_to_run_count() const { return impl()->test_to_run_count(); } // Gets the time of the test program start, in ms from the start of the // UNIX epoch. -internal::TimeInMillis UnitTest::start_timestamp() const { - return impl()->start_timestamp(); +internal::TimeInMillis UnitTest::start_timestamp() const +{ + return impl()->start_timestamp(); } // Gets the elapsed time, in milliseconds. -internal::TimeInMillis UnitTest::elapsed_time() const { - return impl()->elapsed_time(); +internal::TimeInMillis UnitTest::elapsed_time() const +{ + return impl()->elapsed_time(); } // Returns true iff the unit test passed (i.e. all test cases passed). @@ -3729,26 +4135,30 @@ bool UnitTest::Failed() const { return impl()->Failed(); } // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. -const TestCase* UnitTest::GetTestCase(int i) const { - return impl()->GetTestCase(i); +const TestCase* UnitTest::GetTestCase(int i) const +{ + return impl()->GetTestCase(i); } // Returns the TestResult containing information on test failures and // properties logged outside of individual test cases. -const TestResult& UnitTest::ad_hoc_test_result() const { - return *impl()->ad_hoc_test_result(); +const TestResult& UnitTest::ad_hoc_test_result() const +{ + return *impl()->ad_hoc_test_result(); } // Gets the i-th test case among all the test cases. i can range from 0 to // total_test_case_count() - 1. If i is not in that range, returns NULL. -TestCase* UnitTest::GetMutableTestCase(int i) { - return impl()->GetMutableTestCase(i); +TestCase* UnitTest::GetMutableTestCase(int i) +{ + return impl()->GetMutableTestCase(i); } // Returns the list of event listeners that can be used to track events // inside Google Test. -TestEventListeners& UnitTest::listeners() { - return *impl()->listeners(); +TestEventListeners& UnitTest::listeners() +{ + return *impl()->listeners(); } // Registers and returns a global test environment. When a test @@ -3761,13 +4171,15 @@ TestEventListeners& UnitTest::listeners() { // // We don't protect this under mutex_, as we only support calling it // from the main thread. -Environment* UnitTest::AddEnvironment(Environment* env) { - if (env == NULL) { - return NULL; - } +Environment* UnitTest::AddEnvironment(Environment* env) +{ + if (env == NULL) + { + return NULL; + } - impl_->environments().push_back(env); - return env; + impl_->environments().push_back(env); + return env; } // Adds a TestPartResult to the current TestResult object. All Google Test @@ -3775,65 +4187,74 @@ Environment* UnitTest::AddEnvironment(Environment* env) { // this to report their results. The user code should use the // assertion macros instead of calling this directly. void UnitTest::AddTestPartResult( - TestPartResult::Type result_type, - const char* file_name, - int line_number, - const std::string& message, - const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_) { - Message msg; - msg << message; + TestPartResult::Type result_type, + const char* file_name, + int line_number, + const std::string& message, + const std::string& os_stack_trace) GTEST_LOCK_EXCLUDED_(mutex_) +{ + Message msg; + msg << message; - internal::MutexLock lock(&mutex_); - if (impl_->gtest_trace_stack().size() > 0) { - msg << "\n" << GTEST_NAME_ << " trace:"; + internal::MutexLock lock(&mutex_); + if (impl_->gtest_trace_stack().size() > 0) + { + msg << "\n" + << GTEST_NAME_ << " trace:"; - for (int i = static_cast(impl_->gtest_trace_stack().size()); - i > 0; --i) { - const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; - msg << "\n" << internal::FormatFileLocation(trace.file, trace.line) - << " " << trace.message; - } - } + for (int i = static_cast(impl_->gtest_trace_stack().size()); + i > 0; --i) + { + const internal::TraceInfo& trace = impl_->gtest_trace_stack()[i - 1]; + msg << "\n" + << internal::FormatFileLocation(trace.file, trace.line) + << " " << trace.message; + } + } - if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) { - msg << internal::kStackTraceMarker << os_stack_trace; - } + if (os_stack_trace.c_str() != NULL && !os_stack_trace.empty()) + { + msg << internal::kStackTraceMarker << os_stack_trace; + } - const TestPartResult result = - TestPartResult(result_type, file_name, line_number, - msg.GetString().c_str()); - impl_->GetTestPartResultReporterForCurrentThread()-> - ReportTestPartResult(result); + const TestPartResult result = + TestPartResult(result_type, file_name, line_number, + msg.GetString().c_str()); + impl_->GetTestPartResultReporterForCurrentThread()->ReportTestPartResult(result); - if (result_type != TestPartResult::kSuccess) { - // gtest_break_on_failure takes precedence over - // gtest_throw_on_failure. This allows a user to set the latter - // in the code (perhaps in order to use Google Test assertions - // with another testing framework) and specify the former on the - // command line for debugging. - if (GTEST_FLAG(break_on_failure)) { + if (result_type != TestPartResult::kSuccess) + { + // gtest_break_on_failure takes precedence over + // gtest_throw_on_failure. This allows a user to set the latter + // in the code (perhaps in order to use Google Test assertions + // with another testing framework) and specify the former on the + // command line for debugging. + if (GTEST_FLAG(break_on_failure)) + { #if GTEST_OS_WINDOWS - // Using DebugBreak on Windows allows gtest to still break into a debugger - // when a failure happens and both the --gtest_break_on_failure and - // the --gtest_catch_exceptions flags are specified. - DebugBreak(); + // Using DebugBreak on Windows allows gtest to still break into a debugger + // when a failure happens and both the --gtest_break_on_failure and + // the --gtest_catch_exceptions flags are specified. + DebugBreak(); #else - // Dereference NULL through a volatile pointer to prevent the compiler - // from removing. We use this rather than abort() or __builtin_trap() for - // portability: Symbian doesn't implement abort() well, and some debuggers - // don't correctly trap abort(). - *static_cast(NULL) = 1; + // Dereference NULL through a volatile pointer to prevent the compiler + // from removing. We use this rather than abort() or __builtin_trap() for + // portability: Symbian doesn't implement abort() well, and some debuggers + // don't correctly trap abort(). + *static_cast(NULL) = 1; #endif // GTEST_OS_WINDOWS - } else if (GTEST_FLAG(throw_on_failure)) { + } + else if (GTEST_FLAG(throw_on_failure)) + { #if GTEST_HAS_EXCEPTIONS - throw internal::GoogleTestFailureException(result); + throw internal::GoogleTestFailureException(result); #else - // We cannot call abort() as it generates a pop-up in debug mode - // that cannot be suppressed in VC 7.1 or below. - exit(1); + // We cannot call abort() as it generates a pop-up in debug mode + // that cannot be suppressed in VC 7.1 or below. + exit(1); #endif - } - } + } + } } // Adds a TestProperty to the current TestResult object when invoked from @@ -3842,8 +4263,9 @@ void UnitTest::AddTestPartResult( // when invoked elsewhere. If the result already contains a property with // the same key, the value will be updated. void UnitTest::RecordProperty(const std::string& key, - const std::string& value) { - impl_->RecordProperty(TestProperty(key, value)); + const std::string& value) +{ + impl_->RecordProperty(TestProperty(key, value)); } // Runs all tests in this UnitTest object and prints the result. @@ -3851,104 +4273,110 @@ void UnitTest::RecordProperty(const std::string& key, // // We don't protect this under mutex_, as we only support calling it // from the main thread. -int UnitTest::Run() { - const bool in_death_test_child_process = - internal::GTEST_FLAG(internal_run_death_test).length() > 0; +int UnitTest::Run() +{ + const bool in_death_test_child_process = + internal::GTEST_FLAG(internal_run_death_test).length() > 0; - // Google Test implements this protocol for catching that a test - // program exits before returning control to Google Test: - // - // 1. Upon start, Google Test creates a file whose absolute path - // is specified by the environment variable - // TEST_PREMATURE_EXIT_FILE. - // 2. When Google Test has finished its work, it deletes the file. - // - // This allows a test runner to set TEST_PREMATURE_EXIT_FILE before - // running a Google-Test-based test program and check the existence - // of the file at the end of the test execution to see if it has - // exited prematurely. + // Google Test implements this protocol for catching that a test + // program exits before returning control to Google Test: + // + // 1. Upon start, Google Test creates a file whose absolute path + // is specified by the environment variable + // TEST_PREMATURE_EXIT_FILE. + // 2. When Google Test has finished its work, it deletes the file. + // + // This allows a test runner to set TEST_PREMATURE_EXIT_FILE before + // running a Google-Test-based test program and check the existence + // of the file at the end of the test execution to see if it has + // exited prematurely. - // If we are in the child process of a death test, don't - // create/delete the premature exit file, as doing so is unnecessary - // and will confuse the parent process. Otherwise, create/delete - // the file upon entering/leaving this function. If the program - // somehow exits before this function has a chance to return, the - // premature-exit file will be left undeleted, causing a test runner - // that understands the premature-exit-file protocol to report the - // test as having failed. - const internal::ScopedPrematureExitFile premature_exit_file( - in_death_test_child_process ? - NULL : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE")); + // If we are in the child process of a death test, don't + // create/delete the premature exit file, as doing so is unnecessary + // and will confuse the parent process. Otherwise, create/delete + // the file upon entering/leaving this function. If the program + // somehow exits before this function has a chance to return, the + // premature-exit file will be left undeleted, causing a test runner + // that understands the premature-exit-file protocol to report the + // test as having failed. + const internal::ScopedPrematureExitFile premature_exit_file( + in_death_test_child_process ? NULL : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE")); - // Captures the value of GTEST_FLAG(catch_exceptions). This value will be - // used for the duration of the program. - impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions)); + // Captures the value of GTEST_FLAG(catch_exceptions). This value will be + // used for the duration of the program. + impl()->set_catch_exceptions(GTEST_FLAG(catch_exceptions)); #if GTEST_HAS_SEH - // Either the user wants Google Test to catch exceptions thrown by the - // tests or this is executing in the context of death test child - // process. In either case the user does not want to see pop-up dialogs - // about crashes - they are expected. - if (impl()->catch_exceptions() || in_death_test_child_process) { -# if !GTEST_OS_WINDOWS_MOBILE - // SetErrorMode doesn't exist on CE. - SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | - SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); -# endif // !GTEST_OS_WINDOWS_MOBILE + // Either the user wants Google Test to catch exceptions thrown by the + // tests or this is executing in the context of death test child + // process. In either case the user does not want to see pop-up dialogs + // about crashes - they are expected. + if (impl()->catch_exceptions() || in_death_test_child_process) + { +#if !GTEST_OS_WINDOWS_MOBILE + // SetErrorMode doesn't exist on CE. + SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT | + SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX); +#endif // !GTEST_OS_WINDOWS_MOBILE -# if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE - // Death test children can be terminated with _abort(). On Windows, - // _abort() can show a dialog with a warning message. This forces the - // abort message to go to stderr instead. - _set_error_mode(_OUT_TO_STDERR); -# endif +#if (defined(_MSC_VER) || GTEST_OS_WINDOWS_MINGW) && !GTEST_OS_WINDOWS_MOBILE + // Death test children can be terminated with _abort(). On Windows, + // _abort() can show a dialog with a warning message. This forces the + // abort message to go to stderr instead. + _set_error_mode(_OUT_TO_STDERR); +#endif -# if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE - // In the debug version, Visual Studio pops up a separate dialog - // offering a choice to debug the aborted program. We need to suppress - // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement - // executed. Google Test will notify the user of any unexpected - // failure via stderr. - // - // VC++ doesn't define _set_abort_behavior() prior to the version 8.0. - // Users of prior VC versions shall suffer the agony and pain of - // clicking through the countless debug dialogs. - // TODO(vladl@google.com): find a way to suppress the abort dialog() in the - // debug mode when compiled with VC 7.1 or lower. - if (!GTEST_FLAG(break_on_failure)) - _set_abort_behavior( - 0x0, // Clear the following flags: - _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. -# endif - } +#if _MSC_VER >= 1400 && !GTEST_OS_WINDOWS_MOBILE + // In the debug version, Visual Studio pops up a separate dialog + // offering a choice to debug the aborted program. We need to suppress + // this dialog or it will pop up for every EXPECT/ASSERT_DEATH statement + // executed. Google Test will notify the user of any unexpected + // failure via stderr. + // + // VC++ doesn't define _set_abort_behavior() prior to the version 8.0. + // Users of prior VC versions shall suffer the agony and pain of + // clicking through the countless debug dialogs. + // TODO(vladl@google.com): find a way to suppress the abort dialog() in the + // debug mode when compiled with VC 7.1 or lower. + if (!GTEST_FLAG(break_on_failure)) + _set_abort_behavior( + 0x0, // Clear the following flags: + _WRITE_ABORT_MSG | _CALL_REPORTFAULT); // pop-up window, core dump. +#endif + } #endif // GTEST_HAS_SEH - return internal::HandleExceptionsInMethodIfSupported( - impl(), - &internal::UnitTestImpl::RunAllTests, - "auxiliary test code (environments or event listeners)") ? 0 : 1; + return internal::HandleExceptionsInMethodIfSupported( + impl(), + &internal::UnitTestImpl::RunAllTests, + "auxiliary test code (environments or event listeners)") + ? 0 + : 1; } // Returns the working directory when the first TEST() or TEST_F() was // executed. -const char* UnitTest::original_working_dir() const { - return impl_->original_working_dir_.c_str(); +const char* UnitTest::original_working_dir() const +{ + return impl_->original_working_dir_.c_str(); } // Returns the TestCase object for the test that's currently running, // or NULL if no test is running. const TestCase* UnitTest::current_test_case() const - GTEST_LOCK_EXCLUDED_(mutex_) { - internal::MutexLock lock(&mutex_); - return impl_->current_test_case(); + GTEST_LOCK_EXCLUDED_(mutex_) +{ + internal::MutexLock lock(&mutex_); + return impl_->current_test_case(); } // Returns the TestInfo object for the test that's currently running, // or NULL if no test is running. const TestInfo* UnitTest::current_test_info() const - GTEST_LOCK_EXCLUDED_(mutex_) { - internal::MutexLock lock(&mutex_); - return impl_->current_test_info(); + GTEST_LOCK_EXCLUDED_(mutex_) +{ + internal::MutexLock lock(&mutex_); + return impl_->current_test_info(); } // Returns the random seed used at the start of the current test run. @@ -3958,86 +4386,93 @@ int UnitTest::random_seed() const { return impl_->random_seed(); } // Returns ParameterizedTestCaseRegistry object used to keep track of // value-parameterized tests and instantiate and register them. internal::ParameterizedTestCaseRegistry& - UnitTest::parameterized_test_registry() - GTEST_LOCK_EXCLUDED_(mutex_) { - return impl_->parameterized_test_registry(); +UnitTest::parameterized_test_registry() + GTEST_LOCK_EXCLUDED_(mutex_) +{ + return impl_->parameterized_test_registry(); } #endif // GTEST_HAS_PARAM_TEST // Creates an empty UnitTest. -UnitTest::UnitTest() { - impl_ = new internal::UnitTestImpl(this); +UnitTest::UnitTest() +{ + impl_ = new internal::UnitTestImpl(this); } // Destructor of UnitTest. -UnitTest::~UnitTest() { - delete impl_; +UnitTest::~UnitTest() +{ + delete impl_; } // Pushes a trace defined by SCOPED_TRACE() on to the per-thread // Google Test trace stack. void UnitTest::PushGTestTrace(const internal::TraceInfo& trace) - GTEST_LOCK_EXCLUDED_(mutex_) { - internal::MutexLock lock(&mutex_); - impl_->gtest_trace_stack().push_back(trace); + GTEST_LOCK_EXCLUDED_(mutex_) +{ + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().push_back(trace); } // Pops a trace from the per-thread Google Test trace stack. void UnitTest::PopGTestTrace() - GTEST_LOCK_EXCLUDED_(mutex_) { - internal::MutexLock lock(&mutex_); - impl_->gtest_trace_stack().pop_back(); + GTEST_LOCK_EXCLUDED_(mutex_) +{ + internal::MutexLock lock(&mutex_); + impl_->gtest_trace_stack().pop_back(); } -namespace internal { - +namespace internal +{ UnitTestImpl::UnitTestImpl(UnitTest* parent) - : parent_(parent), + : parent_(parent), #ifdef _MSC_VER -# pragma warning(push) // Saves the current warning state. -# pragma warning(disable:4355) // Temporarily disables warning 4355 - // (using this in initializer). - default_global_test_part_result_reporter_(this), - default_per_thread_test_part_result_reporter_(this), -# pragma warning(pop) // Restores the warning state again. +#pragma warning(push) // Saves the current warning state. +#pragma warning(disable : 4355) // Temporarily disables warning 4355 \ + // (using this in initializer). + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), +#pragma warning(pop) // Restores the warning state again. #else - default_global_test_part_result_reporter_(this), - default_per_thread_test_part_result_reporter_(this), + default_global_test_part_result_reporter_(this), + default_per_thread_test_part_result_reporter_(this), #endif // _MSC_VER - global_test_part_result_repoter_( - &default_global_test_part_result_reporter_), - per_thread_test_part_result_reporter_( - &default_per_thread_test_part_result_reporter_), + global_test_part_result_repoter_( + &default_global_test_part_result_reporter_), + per_thread_test_part_result_reporter_( + &default_per_thread_test_part_result_reporter_), #if GTEST_HAS_PARAM_TEST - parameterized_test_registry_(), - parameterized_tests_registered_(false), + parameterized_test_registry_(), + parameterized_tests_registered_(false), #endif // GTEST_HAS_PARAM_TEST - last_death_test_case_(-1), - current_test_case_(NULL), - current_test_info_(NULL), - ad_hoc_test_result_(), - os_stack_trace_getter_(NULL), - post_flag_parse_init_performed_(false), - random_seed_(0), // Will be overridden by the flag before first use. - random_(0), // Will be reseeded before first use. - start_timestamp_(0), - elapsed_time_(0), + last_death_test_case_(-1), + current_test_case_(NULL), + current_test_info_(NULL), + ad_hoc_test_result_(), + os_stack_trace_getter_(NULL), + post_flag_parse_init_performed_(false), + random_seed_(0), // Will be overridden by the flag before first use. + random_(0), // Will be reseeded before first use. + start_timestamp_(0), + elapsed_time_(0), #if GTEST_HAS_DEATH_TEST - death_test_factory_(new DefaultDeathTestFactory), + death_test_factory_(new DefaultDeathTestFactory), #endif - // Will be overridden by the flag before first use. - catch_exceptions_(false) { - listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); + // Will be overridden by the flag before first use. + catch_exceptions_(false) +{ + listeners()->SetDefaultResultPrinter(new PrettyUnitTestResultPrinter); } -UnitTestImpl::~UnitTestImpl() { - // Deletes every TestCase. - ForEach(test_cases_, internal::Delete); +UnitTestImpl::~UnitTestImpl() +{ + // Deletes every TestCase. + ForEach(test_cases_, internal::Delete); - // Deletes every Environment. - ForEach(environments_, internal::Delete); + // Deletes every Environment. + ForEach(environments_, internal::Delete); - delete os_stack_trace_getter_; + delete os_stack_trace_getter_; } // Adds a TestProperty to the current TestResult object when invoked in a @@ -4045,62 +4480,78 @@ UnitTestImpl::~UnitTestImpl() { // from SetUpTestCase/TearDownTestCase, or to the global property set // otherwise. If the result already contains a property with the same key, // the value will be updated. -void UnitTestImpl::RecordProperty(const TestProperty& test_property) { - std::string xml_element; - TestResult* test_result; // TestResult appropriate for property recording. +void UnitTestImpl::RecordProperty(const TestProperty& test_property) +{ + std::string xml_element; + TestResult* test_result; // TestResult appropriate for property recording. - if (current_test_info_ != NULL) { - xml_element = "testcase"; - test_result = &(current_test_info_->result_); - } else if (current_test_case_ != NULL) { - xml_element = "testsuite"; - test_result = &(current_test_case_->ad_hoc_test_result_); - } else { - xml_element = "testsuites"; - test_result = &ad_hoc_test_result_; - } - test_result->RecordProperty(xml_element, test_property); + if (current_test_info_ != NULL) + { + xml_element = "testcase"; + test_result = &(current_test_info_->result_); + } + else if (current_test_case_ != NULL) + { + xml_element = "testsuite"; + test_result = &(current_test_case_->ad_hoc_test_result_); + } + else + { + xml_element = "testsuites"; + test_result = &ad_hoc_test_result_; + } + test_result->RecordProperty(xml_element, test_property); } #if GTEST_HAS_DEATH_TEST // Disables event forwarding if the control is currently in a death test // subprocess. Must not be called before InitGoogleTest. -void UnitTestImpl::SuppressTestEventsIfInSubprocess() { - if (internal_run_death_test_flag_.get() != NULL) - listeners()->SuppressEventForwarding(); +void UnitTestImpl::SuppressTestEventsIfInSubprocess() +{ + if (internal_run_death_test_flag_.get() != NULL) + listeners()->SuppressEventForwarding(); } #endif // GTEST_HAS_DEATH_TEST // Initializes event listeners performing XML output as specified by // UnitTestOptions. Must not be called before InitGoogleTest. -void UnitTestImpl::ConfigureXmlOutput() { - const std::string& output_format = UnitTestOptions::GetOutputFormat(); - if (output_format == "xml") { - listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( - UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); - } else if (output_format != "") { - printf("WARNING: unrecognized output format \"%s\" ignored.\n", - output_format.c_str()); - fflush(stdout); - } +void UnitTestImpl::ConfigureXmlOutput() +{ + const std::string& output_format = UnitTestOptions::GetOutputFormat(); + if (output_format == "xml") + { + listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( + UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); + } + else if (output_format != "") + { + printf("WARNING: unrecognized output format \"%s\" ignored.\n", + output_format.c_str()); + fflush(stdout); + } } #if GTEST_CAN_STREAM_RESULTS_ // Initializes event listeners for streaming test results in string form. // Must not be called before InitGoogleTest. -void UnitTestImpl::ConfigureStreamingOutput() { - const std::string& target = GTEST_FLAG(stream_result_to); - if (!target.empty()) { - const size_t pos = target.find(':'); - if (pos != std::string::npos) { - listeners()->Append(new StreamingListener(target.substr(0, pos), - target.substr(pos+1))); - } else { - printf("WARNING: unrecognized streaming target \"%s\" ignored.\n", - target.c_str()); - fflush(stdout); - } - } +void UnitTestImpl::ConfigureStreamingOutput() +{ + const std::string& target = GTEST_FLAG(stream_result_to); + if (!target.empty()) + { + const size_t pos = target.find(':'); + if (pos != std::string::npos) + { + listeners()->Append(new StreamingListener(target.substr(0, pos), + target.substr(pos + 1))); + } + else + { + printf("WARNING: unrecognized streaming target \"%s\" ignored.\n", + target.c_str()); + fflush(stdout); + } + } } #endif // GTEST_CAN_STREAM_RESULTS_ @@ -4109,30 +4560,32 @@ void UnitTestImpl::ConfigureStreamingOutput() { // ParseGoogleTestFlagsOnly. In case a user neglects to call InitGoogleTest // this function is also called from RunAllTests. Since this function can be // called more than once, it has to be idempotent. -void UnitTestImpl::PostFlagParsingInit() { - // Ensures that this function does not execute more than once. - if (!post_flag_parse_init_performed_) { - post_flag_parse_init_performed_ = true; +void UnitTestImpl::PostFlagParsingInit() +{ + // Ensures that this function does not execute more than once. + if (!post_flag_parse_init_performed_) + { + post_flag_parse_init_performed_ = true; #if GTEST_HAS_DEATH_TEST - InitDeathTestSubprocessControlInfo(); - SuppressTestEventsIfInSubprocess(); + InitDeathTestSubprocessControlInfo(); + SuppressTestEventsIfInSubprocess(); #endif // GTEST_HAS_DEATH_TEST - // Registers parameterized tests. This makes parameterized tests - // available to the UnitTest reflection API without running - // RUN_ALL_TESTS. - RegisterParameterizedTests(); + // Registers parameterized tests. This makes parameterized tests + // available to the UnitTest reflection API without running + // RUN_ALL_TESTS. + RegisterParameterizedTests(); - // Configures listeners for XML output. This makes it possible for users - // to shut down the default XML output before invoking RUN_ALL_TESTS. - ConfigureXmlOutput(); + // Configures listeners for XML output. This makes it possible for users + // to shut down the default XML output before invoking RUN_ALL_TESTS. + ConfigureXmlOutput(); #if GTEST_CAN_STREAM_RESULTS_ - // Configures listeners for streaming test results to the specified server. - ConfigureStreamingOutput(); + // Configures listeners for streaming test results to the specified server. + ConfigureStreamingOutput(); #endif // GTEST_CAN_STREAM_RESULTS_ - } + } } // A predicate that checks the name of a TestCase against a known @@ -4143,19 +4596,21 @@ void UnitTestImpl::PostFlagParsingInit() { // namespace. // // TestCaseNameIs is copyable. -class TestCaseNameIs { - public: - // Constructor. - explicit TestCaseNameIs(const std::string& name) - : name_(name) {} +class TestCaseNameIs +{ +public: + // Constructor. + explicit TestCaseNameIs(const std::string& name) + : name_(name) {} - // Returns true iff the name of test_case matches name_. - bool operator()(const TestCase* test_case) const { - return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0; - } + // Returns true iff the name of test_case matches name_. + bool operator()(const TestCase* test_case) const + { + return test_case != NULL && strcmp(test_case->name(), name_.c_str()) == 0; + } - private: - std::string name_; +private: + std::string name_; }; // Finds and returns a TestCase with the given name. If one doesn't @@ -4171,38 +4626,42 @@ class TestCaseNameIs { // set_up_tc: pointer to the function that sets up the test case // tear_down_tc: pointer to the function that tears down the test case TestCase* UnitTestImpl::GetTestCase(const char* test_case_name, - const char* type_param, - Test::SetUpTestCaseFunc set_up_tc, - Test::TearDownTestCaseFunc tear_down_tc) { - // Can we find a TestCase with the given name? - const std::vector::const_iterator test_case = - std::find_if(test_cases_.begin(), test_cases_.end(), - TestCaseNameIs(test_case_name)); + const char* type_param, + Test::SetUpTestCaseFunc set_up_tc, + Test::TearDownTestCaseFunc tear_down_tc) +{ + // Can we find a TestCase with the given name? + const std::vector::const_iterator test_case = + std::find_if(test_cases_.begin(), test_cases_.end(), + TestCaseNameIs(test_case_name)); - if (test_case != test_cases_.end()) - return *test_case; + if (test_case != test_cases_.end()) + return *test_case; - // No. Let's create one. - TestCase* const new_test_case = - new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc); + // No. Let's create one. + TestCase* const new_test_case = + new TestCase(test_case_name, type_param, set_up_tc, tear_down_tc); - // Is this a death test case? - if (internal::UnitTestOptions::MatchesFilter(test_case_name, - kDeathTestCaseFilter)) { - // Yes. Inserts the test case after the last death test case - // defined so far. This only works when the test cases haven't - // been shuffled. Otherwise we may end up running a death test - // after a non-death test. - ++last_death_test_case_; - test_cases_.insert(test_cases_.begin() + last_death_test_case_, - new_test_case); - } else { - // No. Appends to the end of the list. - test_cases_.push_back(new_test_case); - } + // Is this a death test case? + if (internal::UnitTestOptions::MatchesFilter(test_case_name, + kDeathTestCaseFilter)) + { + // Yes. Inserts the test case after the last death test case + // defined so far. This only works when the test cases haven't + // been shuffled. Otherwise we may end up running a death test + // after a non-death test. + ++last_death_test_case_; + test_cases_.insert(test_cases_.begin() + last_death_test_case_, + new_test_case); + } + else + { + // No. Appends to the end of the list. + test_cases_.push_back(new_test_case); + } - test_case_indices_.push_back(static_cast(test_case_indices_.size())); - return new_test_case; + test_case_indices_.push_back(static_cast(test_case_indices_.size())); + return new_test_case; } // Helpers for setting up / tearing down the given environment. They @@ -4219,157 +4678,169 @@ static void TearDownEnvironment(Environment* env) { env->TearDown(); } // parameterized tests first in RegisterParameterizedTests(). // All other functions called from RunAllTests() may safely assume that // parameterized tests are ready to be counted and run. -bool UnitTestImpl::RunAllTests() { - // Makes sure InitGoogleTest() was called. - if (!GTestIsInitialized()) { - printf("%s", - "\nThis test program did NOT call ::testing::InitGoogleTest " - "before calling RUN_ALL_TESTS(). Please fix it.\n"); - return false; - } +bool UnitTestImpl::RunAllTests() +{ + // Makes sure InitGoogleTest() was called. + if (!GTestIsInitialized()) + { + printf("%s", + "\nThis test program did NOT call ::testing::InitGoogleTest " + "before calling RUN_ALL_TESTS(). Please fix it.\n"); + return false; + } - // Do not run any test if the --help flag was specified. - if (g_help_flag) - return true; + // Do not run any test if the --help flag was specified. + if (g_help_flag) + return true; - // Repeats the call to the post-flag parsing initialization in case the - // user didn't call InitGoogleTest. - PostFlagParsingInit(); + // Repeats the call to the post-flag parsing initialization in case the + // user didn't call InitGoogleTest. + PostFlagParsingInit(); - // Even if sharding is not on, test runners may want to use the - // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding - // protocol. - internal::WriteToShardStatusFileIfNeeded(); + // Even if sharding is not on, test runners may want to use the + // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding + // protocol. + internal::WriteToShardStatusFileIfNeeded(); - // True iff we are in a subprocess for running a thread-safe-style - // death test. - bool in_subprocess_for_death_test = false; + // True iff we are in a subprocess for running a thread-safe-style + // death test. + bool in_subprocess_for_death_test = false; #if GTEST_HAS_DEATH_TEST - in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); + in_subprocess_for_death_test = (internal_run_death_test_flag_.get() != NULL); #endif // GTEST_HAS_DEATH_TEST - const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, - in_subprocess_for_death_test); + const bool should_shard = ShouldShard(kTestTotalShards, kTestShardIndex, + in_subprocess_for_death_test); - // Compares the full test names with the filter to decide which - // tests to run. - const bool has_tests_to_run = FilterTests(should_shard - ? HONOR_SHARDING_PROTOCOL - : IGNORE_SHARDING_PROTOCOL) > 0; + // Compares the full test names with the filter to decide which + // tests to run. + const bool has_tests_to_run = FilterTests(should_shard + ? HONOR_SHARDING_PROTOCOL + : IGNORE_SHARDING_PROTOCOL) > 0; - // Lists the tests and exits if the --gtest_list_tests flag was specified. - if (GTEST_FLAG(list_tests)) { - // This must be called *after* FilterTests() has been called. - ListTestsMatchingFilter(); - return true; - } + // Lists the tests and exits if the --gtest_list_tests flag was specified. + if (GTEST_FLAG(list_tests)) + { + // This must be called *after* FilterTests() has been called. + ListTestsMatchingFilter(); + return true; + } - random_seed_ = GTEST_FLAG(shuffle) ? - GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; + random_seed_ = GTEST_FLAG(shuffle) ? GetRandomSeedFromFlag(GTEST_FLAG(random_seed)) : 0; - // True iff at least one test has failed. - bool failed = false; + // True iff at least one test has failed. + bool failed = false; - TestEventListener* repeater = listeners()->repeater(); + TestEventListener* repeater = listeners()->repeater(); - start_timestamp_ = GetTimeInMillis(); - repeater->OnTestProgramStart(*parent_); + start_timestamp_ = GetTimeInMillis(); + repeater->OnTestProgramStart(*parent_); - // How many times to repeat the tests? We don't want to repeat them - // when we are inside the subprocess of a death test. - const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); - // Repeats forever if the repeat count is negative. - const bool forever = repeat < 0; - for (int i = 0; forever || i != repeat; i++) { - // We want to preserve failures generated by ad-hoc test - // assertions executed before RUN_ALL_TESTS(). - ClearNonAdHocTestResult(); + // How many times to repeat the tests? We don't want to repeat them + // when we are inside the subprocess of a death test. + const int repeat = in_subprocess_for_death_test ? 1 : GTEST_FLAG(repeat); + // Repeats forever if the repeat count is negative. + const bool forever = repeat < 0; + for (int i = 0; forever || i != repeat; i++) + { + // We want to preserve failures generated by ad-hoc test + // assertions executed before RUN_ALL_TESTS(). + ClearNonAdHocTestResult(); - const TimeInMillis start = GetTimeInMillis(); + const TimeInMillis start = GetTimeInMillis(); - // Shuffles test cases and tests if requested. - if (has_tests_to_run && GTEST_FLAG(shuffle)) { - random()->Reseed(random_seed_); - // This should be done before calling OnTestIterationStart(), - // such that a test event listener can see the actual test order - // in the event. - ShuffleTests(); - } + // Shuffles test cases and tests if requested. + if (has_tests_to_run && GTEST_FLAG(shuffle)) + { + random()->Reseed(random_seed_); + // This should be done before calling OnTestIterationStart(), + // such that a test event listener can see the actual test order + // in the event. + ShuffleTests(); + } - // Tells the unit test event listeners that the tests are about to start. - repeater->OnTestIterationStart(*parent_, i); + // Tells the unit test event listeners that the tests are about to start. + repeater->OnTestIterationStart(*parent_, i); - // Runs each test case if there is at least one test to run. - if (has_tests_to_run) { - // Sets up all environments beforehand. - repeater->OnEnvironmentsSetUpStart(*parent_); - ForEach(environments_, SetUpEnvironment); - repeater->OnEnvironmentsSetUpEnd(*parent_); + // Runs each test case if there is at least one test to run. + if (has_tests_to_run) + { + // Sets up all environments beforehand. + repeater->OnEnvironmentsSetUpStart(*parent_); + ForEach(environments_, SetUpEnvironment); + repeater->OnEnvironmentsSetUpEnd(*parent_); - // Runs the tests only if there was no fatal failure during global - // set-up. - if (!Test::HasFatalFailure()) { - for (int test_index = 0; test_index < total_test_case_count(); - test_index++) { - GetMutableTestCase(test_index)->Run(); - } - } + // Runs the tests only if there was no fatal failure during global + // set-up. + if (!Test::HasFatalFailure()) + { + for (int test_index = 0; test_index < total_test_case_count(); + test_index++) + { + GetMutableTestCase(test_index)->Run(); + } + } - // Tears down all environments in reverse order afterwards. - repeater->OnEnvironmentsTearDownStart(*parent_); - std::for_each(environments_.rbegin(), environments_.rend(), - TearDownEnvironment); - repeater->OnEnvironmentsTearDownEnd(*parent_); - } + // Tears down all environments in reverse order afterwards. + repeater->OnEnvironmentsTearDownStart(*parent_); + std::for_each(environments_.rbegin(), environments_.rend(), + TearDownEnvironment); + repeater->OnEnvironmentsTearDownEnd(*parent_); + } - elapsed_time_ = GetTimeInMillis() - start; + elapsed_time_ = GetTimeInMillis() - start; - // Tells the unit test event listener that the tests have just finished. - repeater->OnTestIterationEnd(*parent_, i); + // Tells the unit test event listener that the tests have just finished. + repeater->OnTestIterationEnd(*parent_, i); - // Gets the result and clears it. - if (!Passed()) { - failed = true; - } + // Gets the result and clears it. + if (!Passed()) + { + failed = true; + } - // Restores the original test order after the iteration. This - // allows the user to quickly repro a failure that happens in the - // N-th iteration without repeating the first (N - 1) iterations. - // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in - // case the user somehow changes the value of the flag somewhere - // (it's always safe to unshuffle the tests). - UnshuffleTests(); + // Restores the original test order after the iteration. This + // allows the user to quickly repro a failure that happens in the + // N-th iteration without repeating the first (N - 1) iterations. + // This is not enclosed in "if (GTEST_FLAG(shuffle)) { ... }", in + // case the user somehow changes the value of the flag somewhere + // (it's always safe to unshuffle the tests). + UnshuffleTests(); - if (GTEST_FLAG(shuffle)) { - // Picks a new random seed for each iteration. - random_seed_ = GetNextRandomSeed(random_seed_); - } - } + if (GTEST_FLAG(shuffle)) + { + // Picks a new random seed for each iteration. + random_seed_ = GetNextRandomSeed(random_seed_); + } + } - repeater->OnTestProgramEnd(*parent_); + repeater->OnTestProgramEnd(*parent_); - return !failed; + return !failed; } // Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file // if the variable is present. If a file already exists at this location, this // function will write over it. If the variable is present, but the file cannot // be created, prints an error and exits. -void WriteToShardStatusFileIfNeeded() { - const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); - if (test_shard_file != NULL) { - FILE* const file = posix::FOpen(test_shard_file, "w"); - if (file == NULL) { - ColoredPrintf(COLOR_RED, - "Could not write to the test shard status file \"%s\" " - "specified by the %s environment variable.\n", - test_shard_file, kTestShardStatusFile); - fflush(stdout); - exit(EXIT_FAILURE); - } - fclose(file); - } +void WriteToShardStatusFileIfNeeded() +{ + const char* const test_shard_file = posix::GetEnv(kTestShardStatusFile); + if (test_shard_file != NULL) + { + FILE* const file = posix::FOpen(test_shard_file, "w"); + if (file == NULL) + { + ColoredPrintf(COLOR_RED, + "Could not write to the test shard status file \"%s\" " + "specified by the %s environment variable.\n", + test_shard_file, kTestShardStatusFile); + fflush(stdout); + exit(EXIT_FAILURE); + } + fclose(file); + } } // Checks whether sharding is enabled by examining the relevant @@ -4379,70 +4850,83 @@ void WriteToShardStatusFileIfNeeded() { // disabled because it must only be applied to the original test // process. Otherwise, we could filter out death tests we intended to execute. bool ShouldShard(const char* total_shards_env, - const char* shard_index_env, - bool in_subprocess_for_death_test) { - if (in_subprocess_for_death_test) { - return false; - } + const char* shard_index_env, + bool in_subprocess_for_death_test) +{ + if (in_subprocess_for_death_test) + { + return false; + } - const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); - const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); + const Int32 total_shards = Int32FromEnvOrDie(total_shards_env, -1); + const Int32 shard_index = Int32FromEnvOrDie(shard_index_env, -1); - if (total_shards == -1 && shard_index == -1) { - return false; - } else if (total_shards == -1 && shard_index != -1) { - const Message msg = Message() - << "Invalid environment variables: you have " - << kTestShardIndex << " = " << shard_index - << ", but have left " << kTestTotalShards << " unset.\n"; - ColoredPrintf(COLOR_RED, msg.GetString().c_str()); - fflush(stdout); - exit(EXIT_FAILURE); - } else if (total_shards != -1 && shard_index == -1) { - const Message msg = Message() - << "Invalid environment variables: you have " - << kTestTotalShards << " = " << total_shards - << ", but have left " << kTestShardIndex << " unset.\n"; - ColoredPrintf(COLOR_RED, msg.GetString().c_str()); - fflush(stdout); - exit(EXIT_FAILURE); - } else if (shard_index < 0 || shard_index >= total_shards) { - const Message msg = Message() - << "Invalid environment variables: we require 0 <= " - << kTestShardIndex << " < " << kTestTotalShards - << ", but you have " << kTestShardIndex << "=" << shard_index - << ", " << kTestTotalShards << "=" << total_shards << ".\n"; - ColoredPrintf(COLOR_RED, msg.GetString().c_str()); - fflush(stdout); - exit(EXIT_FAILURE); - } + if (total_shards == -1 && shard_index == -1) + { + return false; + } + else if (total_shards == -1 && shard_index != -1) + { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestShardIndex << " = " << shard_index + << ", but have left " << kTestTotalShards << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } + else if (total_shards != -1 && shard_index == -1) + { + const Message msg = Message() + << "Invalid environment variables: you have " + << kTestTotalShards << " = " << total_shards + << ", but have left " << kTestShardIndex << " unset.\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } + else if (shard_index < 0 || shard_index >= total_shards) + { + const Message msg = Message() + << "Invalid environment variables: we require 0 <= " + << kTestShardIndex << " < " << kTestTotalShards + << ", but you have " << kTestShardIndex << "=" << shard_index + << ", " << kTestTotalShards << "=" << total_shards << ".\n"; + ColoredPrintf(COLOR_RED, msg.GetString().c_str()); + fflush(stdout); + exit(EXIT_FAILURE); + } - return total_shards > 1; + return total_shards > 1; } // Parses the environment variable var as an Int32. If it is unset, // returns default_val. If it is not an Int32, prints an error // and aborts. -Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) { - const char* str_val = posix::GetEnv(var); - if (str_val == NULL) { - return default_val; - } +Int32 Int32FromEnvOrDie(const char* var, Int32 default_val) +{ + const char* str_val = posix::GetEnv(var); + if (str_val == NULL) + { + return default_val; + } - Int32 result; - if (!ParseInt32(Message() << "The value of environment variable " << var, - str_val, &result)) { - exit(EXIT_FAILURE); - } - return result; + Int32 result; + if (!ParseInt32(Message() << "The value of environment variable " << var, + str_val, &result)) + { + exit(EXIT_FAILURE); + } + return result; } // Given the total number of shards, the shard index, and the test id, // returns true iff the test should be run on this shard. The test id is // some arbitrary but unique non-negative integer assigned to each test // method. Assumes that 0 <= shard_index < total_shards. -bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { - return (test_id % total_shards) == shard_index; +bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) +{ + return (test_id % total_shards) == shard_index; } // Compares the name of each test with the user-specified filter to @@ -4452,117 +4936,132 @@ bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { // variables in the environment - see // http://code.google.com/p/googletest/wiki/GoogleTestAdvancedGuide. // Returns the number of tests that should run. -int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { - const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? - Int32FromEnvOrDie(kTestTotalShards, -1) : -1; - const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? - Int32FromEnvOrDie(kTestShardIndex, -1) : -1; +int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) +{ + const Int32 total_shards = shard_tests == HONOR_SHARDING_PROTOCOL ? Int32FromEnvOrDie(kTestTotalShards, -1) : -1; + const Int32 shard_index = shard_tests == HONOR_SHARDING_PROTOCOL ? Int32FromEnvOrDie(kTestShardIndex, -1) : -1; - // num_runnable_tests are the number of tests that will - // run across all shards (i.e., match filter and are not disabled). - // num_selected_tests are the number of tests to be run on - // this shard. - int num_runnable_tests = 0; - int num_selected_tests = 0; - for (size_t i = 0; i < test_cases_.size(); i++) { - TestCase* const test_case = test_cases_[i]; - const std::string &test_case_name = test_case->name(); - test_case->set_should_run(false); + // num_runnable_tests are the number of tests that will + // run across all shards (i.e., match filter and are not disabled). + // num_selected_tests are the number of tests to be run on + // this shard. + int num_runnable_tests = 0; + int num_selected_tests = 0; + for (size_t i = 0; i < test_cases_.size(); i++) + { + TestCase* const test_case = test_cases_[i]; + const std::string& test_case_name = test_case->name(); + test_case->set_should_run(false); - for (size_t j = 0; j < test_case->test_info_list().size(); j++) { - TestInfo* const test_info = test_case->test_info_list()[j]; - const std::string test_name(test_info->name()); - // A test is disabled if test case name or test name matches - // kDisableTestFilter. - const bool is_disabled = - internal::UnitTestOptions::MatchesFilter(test_case_name, - kDisableTestFilter) || - internal::UnitTestOptions::MatchesFilter(test_name, - kDisableTestFilter); - test_info->is_disabled_ = is_disabled; + for (size_t j = 0; j < test_case->test_info_list().size(); j++) + { + TestInfo* const test_info = test_case->test_info_list()[j]; + const std::string test_name(test_info->name()); + // A test is disabled if test case name or test name matches + // kDisableTestFilter. + const bool is_disabled = + internal::UnitTestOptions::MatchesFilter(test_case_name, + kDisableTestFilter) || + internal::UnitTestOptions::MatchesFilter(test_name, + kDisableTestFilter); + test_info->is_disabled_ = is_disabled; - const bool matches_filter = - internal::UnitTestOptions::FilterMatchesTest(test_case_name, - test_name); - test_info->matches_filter_ = matches_filter; + const bool matches_filter = + internal::UnitTestOptions::FilterMatchesTest(test_case_name, + test_name); + test_info->matches_filter_ = matches_filter; - const bool is_runnable = - (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && - matches_filter; + const bool is_runnable = + (GTEST_FLAG(also_run_disabled_tests) || !is_disabled) && + matches_filter; - const bool is_selected = is_runnable && - (shard_tests == IGNORE_SHARDING_PROTOCOL || - ShouldRunTestOnShard(total_shards, shard_index, - num_runnable_tests)); + const bool is_selected = is_runnable && + (shard_tests == IGNORE_SHARDING_PROTOCOL || + ShouldRunTestOnShard(total_shards, shard_index, + num_runnable_tests)); - num_runnable_tests += is_runnable; - num_selected_tests += is_selected; + num_runnable_tests += is_runnable; + num_selected_tests += is_selected; - test_info->should_run_ = is_selected; - test_case->set_should_run(test_case->should_run() || is_selected); - } - } - return num_selected_tests; + test_info->should_run_ = is_selected; + test_case->set_should_run(test_case->should_run() || is_selected); + } + } + return num_selected_tests; } // Prints the given C-string on a single line by replacing all '\n' // characters with string "\\n". If the output takes more than // max_length characters, only prints the first max_length characters // and "...". -static void PrintOnOneLine(const char* str, int max_length) { - if (str != NULL) { - for (int i = 0; *str != '\0'; ++str) { - if (i >= max_length) { - printf("..."); - break; - } - if (*str == '\n') { - printf("\\n"); - i += 2; - } else { - printf("%c", *str); - ++i; - } - } - } +static void PrintOnOneLine(const char* str, int max_length) +{ + if (str != NULL) + { + for (int i = 0; *str != '\0'; ++str) + { + if (i >= max_length) + { + printf("..."); + break; + } + if (*str == '\n') + { + printf("\\n"); + i += 2; + } + else + { + printf("%c", *str); + ++i; + } + } + } } // Prints the names of the tests matching the user-specified filter flag. -void UnitTestImpl::ListTestsMatchingFilter() { - // Print at most this many characters for each type/value parameter. - const int kMaxParamLength = 250; +void UnitTestImpl::ListTestsMatchingFilter() +{ + // Print at most this many characters for each type/value parameter. + const int kMaxParamLength = 250; - for (size_t i = 0; i < test_cases_.size(); i++) { - const TestCase* const test_case = test_cases_[i]; - bool printed_test_case_name = false; + for (size_t i = 0; i < test_cases_.size(); i++) + { + const TestCase* const test_case = test_cases_[i]; + bool printed_test_case_name = false; - for (size_t j = 0; j < test_case->test_info_list().size(); j++) { - const TestInfo* const test_info = - test_case->test_info_list()[j]; - if (test_info->matches_filter_) { - if (!printed_test_case_name) { - printed_test_case_name = true; - printf("%s.", test_case->name()); - if (test_case->type_param() != NULL) { - printf(" # %s = ", kTypeParamLabel); - // We print the type parameter on a single line to make - // the output easy to parse by a program. - PrintOnOneLine(test_case->type_param(), kMaxParamLength); - } - printf("\n"); - } - printf(" %s", test_info->name()); - if (test_info->value_param() != NULL) { - printf(" # %s = ", kValueParamLabel); - // We print the value parameter on a single line to make the - // output easy to parse by a program. - PrintOnOneLine(test_info->value_param(), kMaxParamLength); - } - printf("\n"); - } - } - } - fflush(stdout); + for (size_t j = 0; j < test_case->test_info_list().size(); j++) + { + const TestInfo* const test_info = + test_case->test_info_list()[j]; + if (test_info->matches_filter_) + { + if (!printed_test_case_name) + { + printed_test_case_name = true; + printf("%s.", test_case->name()); + if (test_case->type_param() != NULL) + { + printf(" # %s = ", kTypeParamLabel); + // We print the type parameter on a single line to make + // the output easy to parse by a program. + PrintOnOneLine(test_case->type_param(), kMaxParamLength); + } + printf("\n"); + } + printf(" %s", test_info->name()); + if (test_info->value_param() != NULL) + { + printf(" # %s = ", kValueParamLabel); + // We print the value parameter on a single line to make the + // output easy to parse by a program. + PrintOnOneLine(test_info->value_param(), kMaxParamLength); + } + printf("\n"); + } + } + } + fflush(stdout); } // Sets the OS stack trace getter. @@ -4571,55 +5070,63 @@ void UnitTestImpl::ListTestsMatchingFilter() { // the same; otherwise, deletes the old getter and makes the input the // current getter. void UnitTestImpl::set_os_stack_trace_getter( - OsStackTraceGetterInterface* getter) { - if (os_stack_trace_getter_ != getter) { - delete os_stack_trace_getter_; - os_stack_trace_getter_ = getter; - } + OsStackTraceGetterInterface* getter) +{ + if (os_stack_trace_getter_ != getter) + { + delete os_stack_trace_getter_; + os_stack_trace_getter_ = getter; + } } // Returns the current OS stack trace getter if it is not NULL; // otherwise, creates an OsStackTraceGetter, makes it the current // getter, and returns it. -OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() { - if (os_stack_trace_getter_ == NULL) { - os_stack_trace_getter_ = new OsStackTraceGetter; - } +OsStackTraceGetterInterface* UnitTestImpl::os_stack_trace_getter() +{ + if (os_stack_trace_getter_ == NULL) + { + os_stack_trace_getter_ = new OsStackTraceGetter; + } - return os_stack_trace_getter_; + return os_stack_trace_getter_; } // Returns the TestResult for the test that's currently running, or // the TestResult for the ad hoc test if no test is running. -TestResult* UnitTestImpl::current_test_result() { - return current_test_info_ ? - &(current_test_info_->result_) : &ad_hoc_test_result_; +TestResult* UnitTestImpl::current_test_result() +{ + return current_test_info_ ? &(current_test_info_->result_) : &ad_hoc_test_result_; } // Shuffles all test cases, and the tests within each test case, // making sure that death tests are still run first. -void UnitTestImpl::ShuffleTests() { - // Shuffles the death test cases. - ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_); +void UnitTestImpl::ShuffleTests() +{ + // Shuffles the death test cases. + ShuffleRange(random(), 0, last_death_test_case_ + 1, &test_case_indices_); - // Shuffles the non-death test cases. - ShuffleRange(random(), last_death_test_case_ + 1, - static_cast(test_cases_.size()), &test_case_indices_); + // Shuffles the non-death test cases. + ShuffleRange(random(), last_death_test_case_ + 1, + static_cast(test_cases_.size()), &test_case_indices_); - // Shuffles the tests inside each test case. - for (size_t i = 0; i < test_cases_.size(); i++) { - test_cases_[i]->ShuffleTests(random()); - } + // Shuffles the tests inside each test case. + for (size_t i = 0; i < test_cases_.size(); i++) + { + test_cases_[i]->ShuffleTests(random()); + } } // Restores the test cases and tests to their order before the first shuffle. -void UnitTestImpl::UnshuffleTests() { - for (size_t i = 0; i < test_cases_.size(); i++) { - // Unshuffles the tests in each test case. - test_cases_[i]->UnshuffleTests(); - // Resets the index of each test case. - test_case_indices_[i] = static_cast(i); - } +void UnitTestImpl::UnshuffleTests() +{ + for (size_t i = 0; i < test_cases_.size(); i++) + { + // Unshuffles the tests in each test case. + test_cases_[i]->UnshuffleTests(); + // Resets the index of each test case. + test_case_indices_[i] = static_cast(i); + } } // Returns the current OS stack trace as an std::string. @@ -4633,40 +5140,47 @@ void UnitTestImpl::UnshuffleTests() { // GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. std::string GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, - int skip_count) { - // We pass skip_count + 1 to skip this wrapper function in addition - // to what the user really wants to skip. - return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); + int skip_count) +{ + // We pass skip_count + 1 to skip this wrapper function in addition + // to what the user really wants to skip. + return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); } // Used by the GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_ macro to // suppress unreachable code warnings. -namespace { -class ClassUniqueToAlwaysTrue {}; -} +namespace +{ +class ClassUniqueToAlwaysTrue +{ +}; +} // namespace bool IsTrue(bool condition) { return condition; } -bool AlwaysTrue() { +bool AlwaysTrue() +{ #if GTEST_HAS_EXCEPTIONS - // This condition is always false so AlwaysTrue() never actually throws, - // but it makes the compiler think that it may throw. - if (IsTrue(false)) - throw ClassUniqueToAlwaysTrue(); + // This condition is always false so AlwaysTrue() never actually throws, + // but it makes the compiler think that it may throw. + if (IsTrue(false)) + throw ClassUniqueToAlwaysTrue(); #endif // GTEST_HAS_EXCEPTIONS - return true; + return true; } // If *pstr starts with the given prefix, modifies *pstr to be right // past the prefix and returns true; otherwise leaves *pstr unchanged // and returns false. None of pstr, *pstr, and prefix can be NULL. -bool SkipPrefix(const char* prefix, const char** pstr) { - const size_t prefix_len = strlen(prefix); - if (strncmp(*pstr, prefix, prefix_len) == 0) { - *pstr += prefix_len; - return true; - } - return false; +bool SkipPrefix(const char* prefix, const char** pstr) +{ + const size_t prefix_len = strlen(prefix); + if (strncmp(*pstr, prefix, prefix_len) == 0) + { + *pstr += prefix_len; + return true; + } + return false; } // Parses a string as a command line flag. The string should have @@ -4675,31 +5189,33 @@ bool SkipPrefix(const char* prefix, const char** pstr) { // // Returns the value of the flag, or NULL if the parsing failed. const char* ParseFlagValue(const char* str, - const char* flag, - bool def_optional) { - // str and flag must not be NULL. - if (str == NULL || flag == NULL) return NULL; + const char* flag, + bool def_optional) +{ + // str and flag must not be NULL. + if (str == NULL || flag == NULL) return NULL; - // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. - const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag; - const size_t flag_len = flag_str.length(); - if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; + // The flag must start with "--" followed by GTEST_FLAG_PREFIX_. + const std::string flag_str = std::string("--") + GTEST_FLAG_PREFIX_ + flag; + const size_t flag_len = flag_str.length(); + if (strncmp(str, flag_str.c_str(), flag_len) != 0) return NULL; - // Skips the flag name. - const char* flag_end = str + flag_len; + // Skips the flag name. + const char* flag_end = str + flag_len; - // When def_optional is true, it's OK to not have a "=value" part. - if (def_optional && (flag_end[0] == '\0')) { - return flag_end; - } + // When def_optional is true, it's OK to not have a "=value" part. + if (def_optional && (flag_end[0] == '\0')) + { + return flag_end; + } - // If def_optional is true and there are more characters after the - // flag name, or if def_optional is false, there must be a '=' after - // the flag name. - if (flag_end[0] != '=') return NULL; + // If def_optional is true and there are more characters after the + // flag name, or if def_optional is false, there must be a '=' after + // the flag name. + if (flag_end[0] != '=') return NULL; - // Returns the string after "=". - return flag_end + 1; + // Returns the string after "=". + return flag_end + 1; } // Parses a string for a bool flag, in the form of either @@ -4712,16 +5228,17 @@ const char* ParseFlagValue(const char* str, // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. -bool ParseBoolFlag(const char* str, const char* flag, bool* value) { - // Gets the value of the flag as a string. - const char* const value_str = ParseFlagValue(str, flag, true); +bool ParseBoolFlag(const char* str, const char* flag, bool* value) +{ + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, true); - // Aborts if the parsing failed. - if (value_str == NULL) return false; + // Aborts if the parsing failed. + if (value_str == NULL) return false; - // Converts the string value to a bool. - *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); - return true; + // Converts the string value to a bool. + *value = !(*value_str == '0' || *value_str == 'f' || *value_str == 'F'); + return true; } // Parses a string for an Int32 flag, in the form of @@ -4729,16 +5246,17 @@ bool ParseBoolFlag(const char* str, const char* flag, bool* value) { // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. -bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { - // Gets the value of the flag as a string. - const char* const value_str = ParseFlagValue(str, flag, false); +bool ParseInt32Flag(const char* str, const char* flag, Int32* value) +{ + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); - // Aborts if the parsing failed. - if (value_str == NULL) return false; + // Aborts if the parsing failed. + if (value_str == NULL) return false; - // Sets *value to the value of the flag. - return ParseInt32(Message() << "The value of flag --" << flag, - value_str, value); + // Sets *value to the value of the flag. + return ParseInt32(Message() << "The value of flag --" << flag, + value_str, value); } // Parses a string for a string flag, in the form of @@ -4746,16 +5264,17 @@ bool ParseInt32Flag(const char* str, const char* flag, Int32* value) { // // On success, stores the value of the flag in *value, and returns // true. On failure, returns false without changing *value. -bool ParseStringFlag(const char* str, const char* flag, std::string* value) { - // Gets the value of the flag as a string. - const char* const value_str = ParseFlagValue(str, flag, false); +bool ParseStringFlag(const char* str, const char* flag, std::string* value) +{ + // Gets the value of the flag as a string. + const char* const value_str = ParseFlagValue(str, flag, false); - // Aborts if the parsing failed. - if (value_str == NULL) return false; + // Aborts if the parsing failed. + if (value_str == NULL) return false; - // Sets *value to the value of the flag. - *value = value_str; - return true; + // Sets *value to the value of the flag. + *value = value_str; + return true; } // Determines whether a string has a prefix that Google Test uses for its @@ -4764,13 +5283,14 @@ bool ParseStringFlag(const char* str, const char* flag, std::string* value) { // recognized, it will print its help message. Flags starting with // GTEST_INTERNAL_PREFIX_ followed by "internal_" are considered Google Test // internal flags and do not trigger the help message. -static bool HasGoogleTestFlagPrefix(const char* str) { - return (SkipPrefix("--", &str) || - SkipPrefix("-", &str) || - SkipPrefix("/", &str)) && - !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && - (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || - SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); +static bool HasGoogleTestFlagPrefix(const char* str) +{ + return (SkipPrefix("--", &str) || + SkipPrefix("-", &str) || + SkipPrefix("/", &str)) && + !SkipPrefix(GTEST_FLAG_PREFIX_ "internal_", &str) && + (SkipPrefix(GTEST_FLAG_PREFIX_, &str) || + SkipPrefix(GTEST_FLAG_PREFIX_DASH_, &str)); } // Prints a string containing code-encoded text. The following escape @@ -4784,183 +5304,223 @@ static bool HasGoogleTestFlagPrefix(const char* str) { // // TODO(wan@google.com): Write tests for this once we add stdout // capturing to Google Test. -static void PrintColorEncoded(const char* str) { - GTestColor color = COLOR_DEFAULT; // The current color. +static void PrintColorEncoded(const char* str) +{ + GTestColor color = COLOR_DEFAULT; // The current color. - // Conceptually, we split the string into segments divided by escape - // sequences. Then we print one segment at a time. At the end of - // each iteration, the str pointer advances to the beginning of the - // next segment. - for (;;) { - const char* p = strchr(str, '@'); - if (p == NULL) { - ColoredPrintf(color, "%s", str); - return; - } + // Conceptually, we split the string into segments divided by escape + // sequences. Then we print one segment at a time. At the end of + // each iteration, the str pointer advances to the beginning of the + // next segment. + for (;;) + { + const char* p = strchr(str, '@'); + if (p == NULL) + { + ColoredPrintf(color, "%s", str); + return; + } - ColoredPrintf(color, "%s", std::string(str, p).c_str()); + ColoredPrintf(color, "%s", std::string(str, p).c_str()); - const char ch = p[1]; - str = p + 2; - if (ch == '@') { - ColoredPrintf(color, "@"); - } else if (ch == 'D') { - color = COLOR_DEFAULT; - } else if (ch == 'R') { - color = COLOR_RED; - } else if (ch == 'G') { - color = COLOR_GREEN; - } else if (ch == 'Y') { - color = COLOR_YELLOW; - } else { - --str; - } - } + const char ch = p[1]; + str = p + 2; + if (ch == '@') + { + ColoredPrintf(color, "@"); + } + else if (ch == 'D') + { + color = COLOR_DEFAULT; + } + else if (ch == 'R') + { + color = COLOR_RED; + } + else if (ch == 'G') + { + color = COLOR_GREEN; + } + else if (ch == 'Y') + { + color = COLOR_YELLOW; + } + else + { + --str; + } + } } static const char kColorEncodedHelpMessage[] = -"This program contains tests written using " GTEST_NAME_ ". You can use the\n" -"following command line flags to control its behavior:\n" -"\n" -"Test Selection:\n" -" @G--" GTEST_FLAG_PREFIX_ "list_tests@D\n" -" List the names of all tests instead of running them. The name of\n" -" TEST(Foo, Bar) is \"Foo.Bar\".\n" -" @G--" GTEST_FLAG_PREFIX_ "filter=@YPOSTIVE_PATTERNS" - "[@G-@YNEGATIVE_PATTERNS]@D\n" -" Run only the tests whose name matches one of the positive patterns but\n" -" none of the negative patterns. '?' matches any single character; '*'\n" -" matches any substring; ':' separates two patterns.\n" -" @G--" GTEST_FLAG_PREFIX_ "also_run_disabled_tests@D\n" -" Run all disabled tests too.\n" -"\n" -"Test Execution:\n" -" @G--" GTEST_FLAG_PREFIX_ "repeat=@Y[COUNT]@D\n" -" Run the tests repeatedly; use a negative count to repeat forever.\n" -" @G--" GTEST_FLAG_PREFIX_ "shuffle@D\n" -" Randomize tests' orders on every iteration.\n" -" @G--" GTEST_FLAG_PREFIX_ "random_seed=@Y[NUMBER]@D\n" -" Random number seed to use for shuffling test orders (between 1 and\n" -" 99999, or 0 to use a seed based on the current time).\n" -"\n" -"Test Output:\n" -" @G--" GTEST_FLAG_PREFIX_ "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" -" Enable/disable colored output. The default is @Gauto@D.\n" -" -@G-" GTEST_FLAG_PREFIX_ "print_time=0@D\n" -" Don't print the elapsed time of each test.\n" -" @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G" - GTEST_PATH_SEP_ "@Y|@G:@YFILE_PATH]@D\n" -" Generate an XML report in the given directory or with the given file\n" -" name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" + "This program contains tests written using " GTEST_NAME_ + ". You can use the\n" + "following command line flags to control its behavior:\n" + "\n" + "Test Selection:\n" + " @G--" GTEST_FLAG_PREFIX_ + "list_tests@D\n" + " List the names of all tests instead of running them. The name of\n" + " TEST(Foo, Bar) is \"Foo.Bar\".\n" + " @G--" GTEST_FLAG_PREFIX_ + "filter=@YPOSTIVE_PATTERNS" + "[@G-@YNEGATIVE_PATTERNS]@D\n" + " Run only the tests whose name matches one of the positive patterns but\n" + " none of the negative patterns. '?' matches any single character; '*'\n" + " matches any substring; ':' separates two patterns.\n" + " @G--" GTEST_FLAG_PREFIX_ + "also_run_disabled_tests@D\n" + " Run all disabled tests too.\n" + "\n" + "Test Execution:\n" + " @G--" GTEST_FLAG_PREFIX_ + "repeat=@Y[COUNT]@D\n" + " Run the tests repeatedly; use a negative count to repeat forever.\n" + " @G--" GTEST_FLAG_PREFIX_ + "shuffle@D\n" + " Randomize tests' orders on every iteration.\n" + " @G--" GTEST_FLAG_PREFIX_ + "random_seed=@Y[NUMBER]@D\n" + " Random number seed to use for shuffling test orders (between 1 and\n" + " 99999, or 0 to use a seed based on the current time).\n" + "\n" + "Test Output:\n" + " @G--" GTEST_FLAG_PREFIX_ + "color=@Y(@Gyes@Y|@Gno@Y|@Gauto@Y)@D\n" + " Enable/disable colored output. The default is @Gauto@D.\n" + " -@G-" GTEST_FLAG_PREFIX_ + "print_time=0@D\n" + " Don't print the elapsed time of each test.\n" + " @G--" GTEST_FLAG_PREFIX_ "output=xml@Y[@G:@YDIRECTORY_PATH@G" GTEST_PATH_SEP_ + "@Y|@G:@YFILE_PATH]@D\n" + " Generate an XML report in the given directory or with the given file\n" + " name. @YFILE_PATH@D defaults to @Gtest_details.xml@D.\n" #if GTEST_CAN_STREAM_RESULTS_ -" @G--" GTEST_FLAG_PREFIX_ "stream_result_to=@YHOST@G:@YPORT@D\n" -" Stream test results to the given server.\n" + " @G--" GTEST_FLAG_PREFIX_ + "stream_result_to=@YHOST@G:@YPORT@D\n" + " Stream test results to the given server.\n" #endif // GTEST_CAN_STREAM_RESULTS_ -"\n" -"Assertion Behavior:\n" + "\n" + "Assertion Behavior:\n" #if GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS -" @G--" GTEST_FLAG_PREFIX_ "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" -" Set the default death test style.\n" + " @G--" GTEST_FLAG_PREFIX_ + "death_test_style=@Y(@Gfast@Y|@Gthreadsafe@Y)@D\n" + " Set the default death test style.\n" #endif // GTEST_HAS_DEATH_TEST && !GTEST_OS_WINDOWS -" @G--" GTEST_FLAG_PREFIX_ "break_on_failure@D\n" -" Turn assertion failures into debugger break-points.\n" -" @G--" GTEST_FLAG_PREFIX_ "throw_on_failure@D\n" -" Turn assertion failures into C++ exceptions.\n" -" @G--" GTEST_FLAG_PREFIX_ "catch_exceptions=0@D\n" -" Do not report exceptions as test failures. Instead, allow them\n" -" to crash the program or throw a pop-up (on Windows).\n" -"\n" -"Except for @G--" GTEST_FLAG_PREFIX_ "list_tests@D, you can alternatively set " - "the corresponding\n" -"environment variable of a flag (all letters in upper-case). For example, to\n" -"disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_ - "color=no@D or set\n" -"the @G" GTEST_FLAG_PREFIX_UPPER_ "COLOR@D environment variable to @Gno@D.\n" -"\n" -"For more information, please read the " GTEST_NAME_ " documentation at\n" -"@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ "\n" -"(not one in your own code or tests), please report it to\n" -"@G<" GTEST_DEV_EMAIL_ ">@D.\n"; + " @G--" GTEST_FLAG_PREFIX_ + "break_on_failure@D\n" + " Turn assertion failures into debugger break-points.\n" + " @G--" GTEST_FLAG_PREFIX_ + "throw_on_failure@D\n" + " Turn assertion failures into C++ exceptions.\n" + " @G--" GTEST_FLAG_PREFIX_ + "catch_exceptions=0@D\n" + " Do not report exceptions as test failures. Instead, allow them\n" + " to crash the program or throw a pop-up (on Windows).\n" + "\n" + "Except for @G--" GTEST_FLAG_PREFIX_ + "list_tests@D, you can alternatively set " + "the corresponding\n" + "environment variable of a flag (all letters in upper-case). For example, to\n" + "disable colored text output, you can either specify @G--" GTEST_FLAG_PREFIX_ + "color=no@D or set\n" + "the @G" GTEST_FLAG_PREFIX_UPPER_ + "COLOR@D environment variable to @Gno@D.\n" + "\n" + "For more information, please read the " GTEST_NAME_ + " documentation at\n" + "@G" GTEST_PROJECT_URL_ "@D. If you find a bug in " GTEST_NAME_ + "\n" + "(not one in your own code or tests), please report it to\n" + "@G<" GTEST_DEV_EMAIL_ ">@D.\n"; // Parses the command line for Google Test flags, without initializing // other parts of Google Test. The type parameter CharType can be // instantiated to either char or wchar_t. template -void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { - for (int i = 1; i < *argc; i++) { - const std::string arg_string = StreamableToString(argv[i]); - const char* const arg = arg_string.c_str(); +void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) +{ + for (int i = 1; i < *argc; i++) + { + const std::string arg_string = StreamableToString(argv[i]); + const char* const arg = arg_string.c_str(); - using internal::ParseBoolFlag; - using internal::ParseInt32Flag; - using internal::ParseStringFlag; + using internal::ParseBoolFlag; + using internal::ParseInt32Flag; + using internal::ParseStringFlag; - // Do we see a Google Test flag? - if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, - >EST_FLAG(also_run_disabled_tests)) || - ParseBoolFlag(arg, kBreakOnFailureFlag, - >EST_FLAG(break_on_failure)) || - ParseBoolFlag(arg, kCatchExceptionsFlag, - >EST_FLAG(catch_exceptions)) || - ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || - ParseStringFlag(arg, kDeathTestStyleFlag, - >EST_FLAG(death_test_style)) || - ParseBoolFlag(arg, kDeathTestUseFork, - >EST_FLAG(death_test_use_fork)) || - ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || - ParseStringFlag(arg, kInternalRunDeathTestFlag, - >EST_FLAG(internal_run_death_test)) || - ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || - ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || - ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || - ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || - ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || - ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || - ParseInt32Flag(arg, kStackTraceDepthFlag, - >EST_FLAG(stack_trace_depth)) || - ParseStringFlag(arg, kStreamResultToFlag, - >EST_FLAG(stream_result_to)) || - ParseBoolFlag(arg, kThrowOnFailureFlag, - >EST_FLAG(throw_on_failure)) - ) { - // Yes. Shift the remainder of the argv list left by one. Note - // that argv has (*argc + 1) elements, the last one always being - // NULL. The following loop moves the trailing NULL element as - // well. - for (int j = i; j != *argc; j++) { - argv[j] = argv[j + 1]; - } + // Do we see a Google Test flag? + if (ParseBoolFlag(arg, kAlsoRunDisabledTestsFlag, + >EST_FLAG(also_run_disabled_tests)) || + ParseBoolFlag(arg, kBreakOnFailureFlag, + >EST_FLAG(break_on_failure)) || + ParseBoolFlag(arg, kCatchExceptionsFlag, + >EST_FLAG(catch_exceptions)) || + ParseStringFlag(arg, kColorFlag, >EST_FLAG(color)) || + ParseStringFlag(arg, kDeathTestStyleFlag, + >EST_FLAG(death_test_style)) || + ParseBoolFlag(arg, kDeathTestUseFork, + >EST_FLAG(death_test_use_fork)) || + ParseStringFlag(arg, kFilterFlag, >EST_FLAG(filter)) || + ParseStringFlag(arg, kInternalRunDeathTestFlag, + >EST_FLAG(internal_run_death_test)) || + ParseBoolFlag(arg, kListTestsFlag, >EST_FLAG(list_tests)) || + ParseStringFlag(arg, kOutputFlag, >EST_FLAG(output)) || + ParseBoolFlag(arg, kPrintTimeFlag, >EST_FLAG(print_time)) || + ParseInt32Flag(arg, kRandomSeedFlag, >EST_FLAG(random_seed)) || + ParseInt32Flag(arg, kRepeatFlag, >EST_FLAG(repeat)) || + ParseBoolFlag(arg, kShuffleFlag, >EST_FLAG(shuffle)) || + ParseInt32Flag(arg, kStackTraceDepthFlag, + >EST_FLAG(stack_trace_depth)) || + ParseStringFlag(arg, kStreamResultToFlag, + >EST_FLAG(stream_result_to)) || + ParseBoolFlag(arg, kThrowOnFailureFlag, + >EST_FLAG(throw_on_failure))) + { + // Yes. Shift the remainder of the argv list left by one. Note + // that argv has (*argc + 1) elements, the last one always being + // NULL. The following loop moves the trailing NULL element as + // well. + for (int j = i; j != *argc; j++) + { + argv[j] = argv[j + 1]; + } - // Decrements the argument count. - (*argc)--; + // Decrements the argument count. + (*argc)--; - // We also need to decrement the iterator as we just removed - // an element. - i--; - } else if (arg_string == "--help" || arg_string == "-h" || - arg_string == "-?" || arg_string == "/?" || - HasGoogleTestFlagPrefix(arg)) { - // Both help flag and unrecognized Google Test flags (excluding - // internal ones) trigger help display. - g_help_flag = true; - } - } + // We also need to decrement the iterator as we just removed + // an element. + i--; + } + else if (arg_string == "--help" || arg_string == "-h" || + arg_string == "-?" || arg_string == "/?" || + HasGoogleTestFlagPrefix(arg)) + { + // Both help flag and unrecognized Google Test flags (excluding + // internal ones) trigger help display. + g_help_flag = true; + } + } - if (g_help_flag) { - // We print the help here instead of in RUN_ALL_TESTS(), as the - // latter may not be called at all if the user is using Google - // Test with another testing framework. - PrintColorEncoded(kColorEncodedHelpMessage); - } + if (g_help_flag) + { + // We print the help here instead of in RUN_ALL_TESTS(), as the + // latter may not be called at all if the user is using Google + // Test with another testing framework. + PrintColorEncoded(kColorEncodedHelpMessage); + } } // Parses the command line for Google Test flags, without initializing // other parts of Google Test. -void ParseGoogleTestFlagsOnly(int* argc, char** argv) { - ParseGoogleTestFlagsOnlyImpl(argc, argv); +void ParseGoogleTestFlagsOnly(int* argc, char** argv) +{ + ParseGoogleTestFlagsOnlyImpl(argc, argv); } -void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { - ParseGoogleTestFlagsOnlyImpl(argc, argv); +void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) +{ + ParseGoogleTestFlagsOnlyImpl(argc, argv); } // The internal implementation of InitGoogleTest(). @@ -4968,27 +5528,29 @@ void ParseGoogleTestFlagsOnly(int* argc, wchar_t** argv) { // The type parameter CharType can be instantiated to either char or // wchar_t. template -void InitGoogleTestImpl(int* argc, CharType** argv) { - g_init_gtest_count++; +void InitGoogleTestImpl(int* argc, CharType** argv) +{ + g_init_gtest_count++; - // We don't want to run the initialization code twice. - if (g_init_gtest_count != 1) return; + // We don't want to run the initialization code twice. + if (g_init_gtest_count != 1) return; - if (*argc <= 0) return; + if (*argc <= 0) return; - internal::g_executable_path = internal::StreamableToString(argv[0]); + internal::g_executable_path = internal::StreamableToString(argv[0]); #if GTEST_HAS_DEATH_TEST - g_argvs.clear(); - for (int i = 0; i != *argc; i++) { - g_argvs.push_back(StreamableToString(argv[i])); - } + g_argvs.clear(); + for (int i = 0; i != *argc; i++) + { + g_argvs.push_back(StreamableToString(argv[i])); + } #endif // GTEST_HAS_DEATH_TEST - ParseGoogleTestFlagsOnly(argc, argv); - GetUnitTestImpl()->PostFlagParsingInit(); + ParseGoogleTestFlagsOnly(argc, argv); + GetUnitTestImpl()->PostFlagParsingInit(); } } // namespace internal @@ -5002,14 +5564,16 @@ void InitGoogleTestImpl(int* argc, CharType** argv) { // updated. // // Calling the function for the second time has no user-visible effect. -void InitGoogleTest(int* argc, char** argv) { - internal::InitGoogleTestImpl(argc, argv); +void InitGoogleTest(int* argc, char** argv) +{ + internal::InitGoogleTestImpl(argc, argv); } // This overloaded version can be used in Windows programs compiled in // UNICODE mode. -void InitGoogleTest(int* argc, wchar_t** argv) { - internal::InitGoogleTestImpl(argc, argv); +void InitGoogleTest(int* argc, wchar_t** argv) +{ + internal::InitGoogleTestImpl(argc, argv); } } // namespace testing diff --git a/test/gtest-1.7.0/src/gtest_main.cc b/test/gtest-1.7.0/src/gtest_main.cc index f30282255..9705c0305 100644 --- a/test/gtest-1.7.0/src/gtest_main.cc +++ b/test/gtest-1.7.0/src/gtest_main.cc @@ -31,8 +31,9 @@ #include "gtest/gtest.h" -GTEST_API_ int main(int argc, char **argv) { - printf("Running main() from gtest_main.cc\n"); - testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); +GTEST_API_ int main(int argc, char **argv) +{ + printf("Running main() from gtest_main.cc\n"); + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); } diff --git a/test/hello_gtest/main.cpp b/test/hello_gtest/main.cpp index 537ec225b..e31777992 100644 --- a/test/hello_gtest/main.cpp +++ b/test/hello_gtest/main.cpp @@ -1,38 +1,40 @@ ///////////////////////////// // In the header file - #include using namespace std; class Salutation { public: - static string greet(const string& name); + static string greet(const string& name); }; /////////////////////////////////////// // In the class implementation file -string Salutation::greet(const string& name) { - ostringstream s; - s << "Hello " << name << "!"; - return s.str(); +string Salutation::greet(const string& name) +{ + ostringstream s; + s << "Hello " << name << "!"; + return s.str(); } /////////////////////////////////////////// // In the test file #include -TEST(SalutationTest, Static) { - EXPECT_EQ(string("Hello World!"), Salutation::greet("World")); +TEST(SalutationTest, Static) +{ + EXPECT_EQ(string("Hello World!"), Salutation::greet("World")); } -int main(int argc, char **argv) { +int main(int argc, char** argv) +{ #if _MSC_VER - _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); - //void *testWhetherMemoryLeakDetectionWorks = malloc(1); + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); + //void *testWhetherMemoryLeakDetectionWorks = malloc(1); #endif - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); }